Update linux-x86 Go prebuilts from ab/9878432

https://ci.android.com/builds/branches/aosp-build-tools-release/grid?head=9878432&tail=9878432

Update script: toolchain/go/update-prebuilts.sh

Test: Treehugger presubmit
Change-Id: I07818c960e04b2ef4373ab22161590b088582d39
diff --git a/src/README.vendor b/src/README.vendor
index e74fc2f..4b6bdb8 100644
--- a/src/README.vendor
+++ b/src/README.vendor
@@ -4,12 +4,8 @@
 The Go command maintains copies of external packages needed by the
 standard library in the src/vendor and src/cmd/vendor directories.
 
-In GOPATH mode, imports of vendored packages are resolved to these
-directories following normal vendor directory logic
-(see golang.org/s/go15vendor).
-
-In module mode, std and cmd are modules (defined in src/go.mod and
-src/cmd/go.mod). When a package outside std or cmd is imported
+There are two modules, std and cmd, defined in src/go.mod and
+src/cmd/go.mod. When a package outside std or cmd is imported
 by a package inside std or cmd, the import path is interpreted
 as if it had a "vendor/" prefix. For example, within "crypto/tls",
 an import of "golang.org/x/crypto/cryptobyte" resolves to
@@ -34,14 +30,15 @@
 ==============================
 
 Before updating vendor directories, ensure that module mode is enabled.
-Make sure GO111MODULE=off is not set ('on' or 'auto' should work).
+Make sure that GO111MODULE is not set in the environment, or that it is
+set to 'on' or 'auto'.
 
 Requirements may be added, updated, and removed with 'go get'.
 The vendor directory may be updated with 'go mod vendor'.
 A typical sequence might be:
 
     cd src
-    go get -d golang.org/x/net@latest
+    go get golang.org/x/net@latest
     go mod tidy
     go mod vendor
 
diff --git a/src/archive/tar/common.go b/src/archive/tar/common.go
index f6d701d..38216ac 100644
--- a/src/archive/tar/common.go
+++ b/src/archive/tar/common.go
@@ -13,6 +13,7 @@
 import (
 	"errors"
 	"fmt"
+	"internal/godebug"
 	"io/fs"
 	"math"
 	"path"
@@ -26,11 +27,14 @@
 // architectures. If a large value is encountered when decoding, the result
 // stored in Header will be the truncated version.
 
+var tarinsecurepath = godebug.New("tarinsecurepath")
+
 var (
 	ErrHeader          = errors.New("archive/tar: invalid tar header")
 	ErrWriteTooLong    = errors.New("archive/tar: write too long")
 	ErrFieldTooLong    = errors.New("archive/tar: header field too long")
 	ErrWriteAfterClose = errors.New("archive/tar: write after close")
+	ErrInsecurePath    = errors.New("archive/tar: insecure file path")
 	errMissData        = errors.New("archive/tar: sparse file references non-existent data")
 	errUnrefData       = errors.New("archive/tar: sparse file contains unreferenced data")
 	errWriteHole       = errors.New("archive/tar: write non-NUL byte in sparse hole")
@@ -55,8 +59,10 @@
 // Type flags for Header.Typeflag.
 const (
 	// Type '0' indicates a regular file.
-	TypeReg  = '0'
-	TypeRegA = '\x00' // Deprecated: Use TypeReg instead.
+	TypeReg = '0'
+
+	// Deprecated: Use TypeReg instead.
+	TypeRegA = '\x00'
 
 	// Type '1' to '6' are header-only flags and may not have a data body.
 	TypeLink    = '1' // Hard link
diff --git a/src/archive/tar/format.go b/src/archive/tar/format.go
index 21b9d9d..e50124d 100644
--- a/src/archive/tar/format.go
+++ b/src/archive/tar/format.go
@@ -143,6 +143,10 @@
 	blockSize  = 512 // Size of each block in a tar stream
 	nameSize   = 100 // Max length of the name field in USTAR format
 	prefixSize = 155 // Max length of the prefix field in USTAR format
+
+	// Max length of a special file (PAX header, GNU long name or link).
+	// This matches the limit used by libarchive.
+	maxSpecialFileSize = 1 << 20
 )
 
 // blockPadding computes the number of bytes needed to pad offset up to the
@@ -162,7 +166,7 @@
 func (b *block) toUSTAR() *headerUSTAR { return (*headerUSTAR)(b) }
 func (b *block) toSparse() sparseArray { return sparseArray(b[:]) }
 
-// GetFormat checks that the block is a valid tar header based on the checksum.
+// getFormat checks that the block is a valid tar header based on the checksum.
 // It then attempts to guess the specific format based on magic values.
 // If the checksum fails, then FormatUnknown is returned.
 func (b *block) getFormat() Format {
@@ -235,7 +239,7 @@
 	return unsigned, signed
 }
 
-// Reset clears the block with all zeros.
+// reset clears the block with all zeros.
 func (b *block) reset() {
 	*b = block{}
 }
diff --git a/src/archive/tar/reader.go b/src/archive/tar/reader.go
index f1b35c3..768ca19 100644
--- a/src/archive/tar/reader.go
+++ b/src/archive/tar/reader.go
@@ -7,6 +7,7 @@
 import (
 	"bytes"
 	"io"
+	"path/filepath"
 	"strconv"
 	"strings"
 	"time"
@@ -42,14 +43,23 @@
 // Next advances to the next entry in the tar archive.
 // The Header.Size determines how many bytes can be read for the next file.
 // Any remaining data in the current file is automatically discarded.
+// At the end of the archive, Next returns the error io.EOF.
 //
-// io.EOF is returned at the end of the input.
+// If Next encounters a non-local name (as defined by [filepath.IsLocal])
+// and the GODEBUG environment variable contains `tarinsecurepath=0`,
+// Next returns the header with an ErrInsecurePath error.
+// A future version of Go may introduce this behavior by default.
+// Programs that want to accept non-local names can ignore
+// the ErrInsecurePath error and use the returned header.
 func (tr *Reader) Next() (*Header, error) {
 	if tr.err != nil {
 		return nil, tr.err
 	}
 	hdr, err := tr.next()
 	tr.err = err
+	if err == nil && tarinsecurepath.Value() == "0" && !filepath.IsLocal(hdr.Name) {
+		err = ErrInsecurePath
+	}
 	return hdr, err
 }
 
@@ -103,7 +113,7 @@
 			continue // This is a meta header affecting the next header
 		case TypeGNULongName, TypeGNULongLink:
 			format.mayOnlyBe(FormatGNU)
-			realname, err := io.ReadAll(tr)
+			realname, err := readSpecialFile(tr)
 			if err != nil {
 				return nil, err
 			}
@@ -291,9 +301,9 @@
 }
 
 // parsePAX parses PAX headers.
-// If an extended header (type 'x') is invalid, ErrHeader is returned
+// If an extended header (type 'x') is invalid, ErrHeader is returned.
 func parsePAX(r io.Reader) (map[string]string, error) {
-	buf, err := io.ReadAll(r)
+	buf, err := readSpecialFile(r)
 	if err != nil {
 		return nil, err
 	}
@@ -683,7 +693,7 @@
 	return fr.nb
 }
 
-// logicalRemaining implements fileState.physicalRemaining.
+// physicalRemaining implements fileState.physicalRemaining.
 func (fr regFileReader) physicalRemaining() int64 {
 	return fr.nb
 }
@@ -828,6 +838,16 @@
 	return n, err
 }
 
+// readSpecialFile is like io.ReadAll except it returns
+// ErrFieldTooLong if more than maxSpecialFileSize is read.
+func readSpecialFile(r io.Reader) ([]byte, error) {
+	buf, err := io.ReadAll(io.LimitReader(r, maxSpecialFileSize+1))
+	if len(buf) > maxSpecialFileSize {
+		return nil, ErrFieldTooLong
+	}
+	return buf, err
+}
+
 // discard skips n bytes in r, reporting an error if unable to do so.
 func discard(r io.Reader, n int64) error {
 	// If possible, Seek to the last byte before the end of the data section.
diff --git a/src/archive/tar/reader_test.go b/src/archive/tar/reader_test.go
index f21a606..7e0462c 100644
--- a/src/archive/tar/reader_test.go
+++ b/src/archive/tar/reader_test.go
@@ -6,6 +6,7 @@
 
 import (
 	"bytes"
+	"compress/bzip2"
 	"crypto/md5"
 	"errors"
 	"fmt"
@@ -244,6 +245,9 @@
 		file: "testdata/pax-bad-hdr-file.tar",
 		err:  ErrHeader,
 	}, {
+		file: "testdata/pax-bad-hdr-large.tar.bz2",
+		err:  ErrFieldTooLong,
+	}, {
 		file: "testdata/pax-bad-mtime-file.tar",
 		err:  ErrHeader,
 	}, {
@@ -625,9 +629,14 @@
 			}
 			defer f.Close()
 
+			var fr io.Reader = f
+			if strings.HasSuffix(v.file, ".bz2") {
+				fr = bzip2.NewReader(fr)
+			}
+
 			// Capture all headers and checksums.
 			var (
-				tr      = NewReader(f)
+				tr      = NewReader(fr)
 				hdrs    []*Header
 				chksums []string
 				rdbuf   = make([]byte, 8)
@@ -657,7 +666,6 @@
 			for i, hdr := range hdrs {
 				if i >= len(v.headers) {
 					t.Fatalf("entry %d: unexpected header:\ngot %+v", i, *hdr)
-					continue
 				}
 				if !reflect.DeepEqual(*hdr, *v.headers[i]) {
 					t.Fatalf("entry %d: incorrect header:\ngot  %+v\nwant %+v", i, *hdr, *v.headers[i])
@@ -670,7 +678,6 @@
 			for i, sum := range chksums {
 				if i >= len(v.chksums) {
 					t.Fatalf("entry %d: unexpected sum: got %s", i, sum)
-					continue
 				}
 				if sum != v.chksums[i] {
 					t.Fatalf("entry %d: incorrect checksum: got %s, want %s", i, sum, v.chksums[i])
@@ -1608,3 +1615,60 @@
 		}
 	}
 }
+
+func TestInsecurePaths(t *testing.T) {
+	t.Setenv("GODEBUG", "tarinsecurepath=0")
+	for _, path := range []string{
+		"../foo",
+		"/foo",
+		"a/b/../../../c",
+	} {
+		var buf bytes.Buffer
+		tw := NewWriter(&buf)
+		tw.WriteHeader(&Header{
+			Name: path,
+		})
+		const securePath = "secure"
+		tw.WriteHeader(&Header{
+			Name: securePath,
+		})
+		tw.Close()
+
+		tr := NewReader(&buf)
+		h, err := tr.Next()
+		if err != ErrInsecurePath {
+			t.Errorf("tr.Next for file %q: got err %v, want ErrInsecurePath", path, err)
+			continue
+		}
+		if h.Name != path {
+			t.Errorf("tr.Next for file %q: got name %q, want %q", path, h.Name, path)
+		}
+		// Error should not be sticky.
+		h, err = tr.Next()
+		if err != nil {
+			t.Errorf("tr.Next for file %q: got err %v, want nil", securePath, err)
+		}
+		if h.Name != securePath {
+			t.Errorf("tr.Next for file %q: got name %q, want %q", securePath, h.Name, securePath)
+		}
+	}
+}
+
+func TestDisableInsecurePathCheck(t *testing.T) {
+	t.Setenv("GODEBUG", "tarinsecurepath=1")
+	var buf bytes.Buffer
+	tw := NewWriter(&buf)
+	const name = "/foo"
+	tw.WriteHeader(&Header{
+		Name: name,
+	})
+	tw.Close()
+	tr := NewReader(&buf)
+	h, err := tr.Next()
+	if err != nil {
+		t.Fatalf("tr.Next with tarinsecurepath=1: got err %v, want nil", err)
+	}
+	if h.Name != name {
+		t.Fatalf("tr.Next with tarinsecurepath=1: got name %q, want %q", h.Name, name)
+	}
+}
diff --git a/src/archive/tar/testdata/pax-bad-hdr-large.tar.bz2 b/src/archive/tar/testdata/pax-bad-hdr-large.tar.bz2
new file mode 100644
index 0000000..06bf710
--- /dev/null
+++ b/src/archive/tar/testdata/pax-bad-hdr-large.tar.bz2
Binary files differ
diff --git a/src/archive/tar/writer.go b/src/archive/tar/writer.go
index 3729f7e..1c95f07 100644
--- a/src/archive/tar/writer.go
+++ b/src/archive/tar/writer.go
@@ -199,6 +199,9 @@
 			flag = TypeXHeader
 		}
 		data := buf.String()
+		if len(data) > maxSpecialFileSize {
+			return ErrFieldTooLong
+		}
 		if err := tw.writeRawFile(name, data, flag, FormatPAX); err != nil || isGlobal {
 			return err // Global headers return here
 		}
@@ -516,7 +519,7 @@
 	return fw.nb
 }
 
-// logicalRemaining implements fileState.physicalRemaining.
+// physicalRemaining implements fileState.physicalRemaining.
 func (fw regFileWriter) physicalRemaining() int64 {
 	return fw.nb
 }
diff --git a/src/archive/tar/writer_test.go b/src/archive/tar/writer_test.go
index da3fb89..f6d75c5 100644
--- a/src/archive/tar/writer_test.go
+++ b/src/archive/tar/writer_test.go
@@ -780,7 +780,7 @@
 	// Test that we can get a long name back out of the archive.
 	reader := NewReader(&buf)
 	hdr, err = reader.Next()
-	if err != nil {
+	if err != nil && err != ErrInsecurePath {
 		t.Fatal(err)
 	}
 	if hdr.Name != longName {
@@ -995,7 +995,7 @@
 
 		tr := NewReader(&b)
 		hdr, err := tr.Next()
-		if err != nil {
+		if err != nil && err != ErrInsecurePath {
 			t.Errorf("test %d, unexpected Next error: %v", i, err)
 		}
 		if hdr.Name != name {
@@ -1004,6 +1004,33 @@
 	}
 }
 
+func TestWriteLongHeader(t *testing.T) {
+	for _, test := range []struct {
+		name string
+		h    *Header
+	}{{
+		name: "name too long",
+		h:    &Header{Name: strings.Repeat("a", maxSpecialFileSize)},
+	}, {
+		name: "linkname too long",
+		h:    &Header{Linkname: strings.Repeat("a", maxSpecialFileSize)},
+	}, {
+		name: "uname too long",
+		h:    &Header{Uname: strings.Repeat("a", maxSpecialFileSize)},
+	}, {
+		name: "gname too long",
+		h:    &Header{Gname: strings.Repeat("a", maxSpecialFileSize)},
+	}, {
+		name: "PAX header too long",
+		h:    &Header{PAXRecords: map[string]string{"GOLANG.x": strings.Repeat("a", maxSpecialFileSize)}},
+	}} {
+		w := NewWriter(io.Discard)
+		if err := w.WriteHeader(test.h); err != ErrFieldTooLong {
+			t.Errorf("%v: w.WriteHeader() = %v, want ErrFieldTooLong", test.name, err)
+		}
+	}
+}
+
 // testNonEmptyWriter wraps an io.Writer and ensures that
 // Write is never called with an empty buffer.
 type testNonEmptyWriter struct{ io.Writer }
@@ -1252,7 +1279,7 @@
 
 	for i, v := range vectors {
 		var wantStr string
-		bb := new(bytes.Buffer)
+		bb := new(strings.Builder)
 		w := testNonEmptyWriter{bb}
 		var fw fileWriter
 		switch maker := v.maker.(type) {
diff --git a/src/archive/zip/reader.go b/src/archive/zip/reader.go
index d7fcff2..a1554d2 100644
--- a/src/archive/zip/reader.go
+++ b/src/archive/zip/reader.go
@@ -10,20 +10,25 @@
 	"errors"
 	"hash"
 	"hash/crc32"
+	"internal/godebug"
 	"io"
 	"io/fs"
 	"os"
 	"path"
+	"path/filepath"
 	"sort"
 	"strings"
 	"sync"
 	"time"
 )
 
+var zipinsecurepath = godebug.New("zipinsecurepath")
+
 var (
-	ErrFormat    = errors.New("zip: not a valid zip file")
-	ErrAlgorithm = errors.New("zip: unsupported compression algorithm")
-	ErrChecksum  = errors.New("zip: checksum error")
+	ErrFormat       = errors.New("zip: not a valid zip file")
+	ErrAlgorithm    = errors.New("zip: unsupported compression algorithm")
+	ErrChecksum     = errors.New("zip: checksum error")
+	ErrInsecurePath = errors.New("zip: insecure file path")
 )
 
 // A Reader serves content from a ZIP archive.
@@ -82,6 +87,14 @@
 
 // NewReader returns a new Reader reading from r, which is assumed to
 // have the given size in bytes.
+//
+// If any file inside the archive uses a non-local name
+// (as defined by [filepath.IsLocal]) or a name containing backslashes
+// and the GODEBUG environment variable contains `zipinsecurepath=0`,
+// NewReader returns the reader with an ErrInsecurePath error.
+// A future version of Go may introduce this behavior by default.
+// Programs that want to accept non-local names can ignore
+// the ErrInsecurePath error and use the returned reader.
 func NewReader(r io.ReaderAt, size int64) (*Reader, error) {
 	if size < 0 {
 		return nil, errors.New("zip: size cannot be negative")
@@ -90,6 +103,20 @@
 	if err := zr.init(r, size); err != nil {
 		return nil, err
 	}
+	for _, f := range zr.File {
+		if f.Name == "" {
+			// Zip permits an empty file name field.
+			continue
+		}
+		if zipinsecurepath.Value() != "0" {
+			continue
+		}
+		// The zip specification states that names must use forward slashes,
+		// so consider any backslashes in the name insecure.
+		if !filepath.IsLocal(f.Name) || strings.Contains(f.Name, `\`) {
+			return zr, ErrInsecurePath
+		}
+	}
 	return zr, nil
 }
 
@@ -197,6 +224,22 @@
 	if err != nil {
 		return nil, err
 	}
+	if strings.HasSuffix(f.Name, "/") {
+		// The ZIP specification (APPNOTE.TXT) specifies that directories, which
+		// are technically zero-byte files, must not have any associated file
+		// data. We previously tried failing here if f.CompressedSize64 != 0,
+		// but it turns out that a number of implementations (namely, the Java
+		// jar tool) don't properly set the storage method on directories
+		// resulting in a file with compressed size > 0 but uncompressed size ==
+		// 0. We still want to fail when a directory has associated uncompressed
+		// data, but we are tolerant of cases where the uncompressed size is
+		// zero but compressed size is not.
+		if f.UncompressedSize64 != 0 {
+			return &dirReader{ErrFormat}, nil
+		} else {
+			return &dirReader{io.EOF}, nil
+		}
+	}
 	size := int64(f.CompressedSize64)
 	r := io.NewSectionReader(f.zipr, f.headerOffset+bodyOffset, size)
 	dcomp := f.zip.decompressor(f.Method)
@@ -228,6 +271,18 @@
 	return r, nil
 }
 
+type dirReader struct {
+	err error
+}
+
+func (r *dirReader) Read([]byte) (int, error) {
+	return 0, r.err
+}
+
+func (r *dirReader) Close() error {
+	return nil
+}
+
 type checksumReader struct {
 	rc    io.ReadCloser
 	hash  hash.Hash32
@@ -715,12 +770,13 @@
 func toValidName(name string) string {
 	name = strings.ReplaceAll(name, `\`, `/`)
 	p := path.Clean(name)
-	if strings.HasPrefix(p, "/") {
-		p = p[len("/"):]
-	}
+
+	p = strings.TrimPrefix(p, "/")
+
 	for strings.HasPrefix(p, "../") {
 		p = p[len("../"):]
 	}
+
 	return p
 }
 
diff --git a/src/archive/zip/reader_test.go b/src/archive/zip/reader_test.go
index 84742c7..1594b26 100644
--- a/src/archive/zip/reader_test.go
+++ b/src/archive/zip/reader_test.go
@@ -1290,6 +1290,7 @@
 }
 
 func TestCVE202127919(t *testing.T) {
+	t.Setenv("GODEBUG", "zipinsecurepath=0")
 	// Archive containing only the file "../test.txt"
 	data := []byte{
 		0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x08, 0x00,
@@ -1315,7 +1316,7 @@
 		0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00,
 	}
 	r, err := NewReader(bytes.NewReader([]byte(data)), int64(len(data)))
-	if err != nil {
+	if err != ErrInsecurePath {
 		t.Fatalf("Error reading the archive: %v", err)
 	}
 	_, err = r.Open("test.txt")
@@ -1411,6 +1412,7 @@
 }
 
 func TestCVE202141772(t *testing.T) {
+	t.Setenv("GODEBUG", "zipinsecurepath=0")
 	// Archive contains a file whose name is exclusively made up of '/', '\'
 	// characters, or "../", "..\" paths, which would previously cause a panic.
 	//
@@ -1484,7 +1486,7 @@
 		0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00,
 	}
 	r, err := NewReader(bytes.NewReader([]byte(data)), int64(len(data)))
-	if err != nil {
+	if err != ErrInsecurePath {
 		t.Fatalf("Error reading the archive: %v", err)
 	}
 	entryNames := []string{`/`, `//`, `\`, `/test.txt`}
@@ -1554,3 +1556,158 @@
 		})
 	}
 }
+
+func TestIssue54801(t *testing.T) {
+	for _, input := range []string{"testdata/readme.zip", "testdata/dd.zip"} {
+		z, err := OpenReader(input)
+		if err != nil {
+			t.Fatal(err)
+		}
+		defer z.Close()
+
+		for _, f := range z.File {
+			// Make file a directory
+			f.Name += "/"
+
+			t.Run(f.Name, func(t *testing.T) {
+				t.Logf("CompressedSize64: %d, Flags: %#x", f.CompressedSize64, f.Flags)
+
+				rd, err := f.Open()
+				if err != nil {
+					t.Fatal(err)
+				}
+				defer rd.Close()
+
+				n, got := io.Copy(io.Discard, rd)
+				if n != 0 || got != ErrFormat {
+					t.Fatalf("Error mismatch, got: %d, %v, want: %v", n, got, ErrFormat)
+				}
+			})
+		}
+	}
+}
+
+func TestInsecurePaths(t *testing.T) {
+	t.Setenv("GODEBUG", "zipinsecurepath=0")
+	for _, path := range []string{
+		"../foo",
+		"/foo",
+		"a/b/../../../c",
+		`a\b`,
+	} {
+		var buf bytes.Buffer
+		zw := NewWriter(&buf)
+		_, err := zw.Create(path)
+		if err != nil {
+			t.Errorf("zw.Create(%q) = %v", path, err)
+			continue
+		}
+		zw.Close()
+
+		zr, err := NewReader(bytes.NewReader(buf.Bytes()), int64(buf.Len()))
+		if err != ErrInsecurePath {
+			t.Errorf("NewReader for archive with file %q: got err %v, want ErrInsecurePath", path, err)
+			continue
+		}
+		var gotPaths []string
+		for _, f := range zr.File {
+			gotPaths = append(gotPaths, f.Name)
+		}
+		if !reflect.DeepEqual(gotPaths, []string{path}) {
+			t.Errorf("NewReader for archive with file %q: got files %q", path, gotPaths)
+			continue
+		}
+	}
+}
+
+func TestDisableInsecurePathCheck(t *testing.T) {
+	t.Setenv("GODEBUG", "zipinsecurepath=1")
+	var buf bytes.Buffer
+	zw := NewWriter(&buf)
+	const name = "/foo"
+	_, err := zw.Create(name)
+	if err != nil {
+		t.Fatalf("zw.Create(%q) = %v", name, err)
+	}
+	zw.Close()
+	zr, err := NewReader(bytes.NewReader(buf.Bytes()), int64(buf.Len()))
+	if err != nil {
+		t.Fatalf("NewReader with zipinsecurepath=1: got err %v, want nil", err)
+	}
+	var gotPaths []string
+	for _, f := range zr.File {
+		gotPaths = append(gotPaths, f.Name)
+	}
+	if want := []string{name}; !reflect.DeepEqual(gotPaths, want) {
+		t.Errorf("NewReader with zipinsecurepath=1: got files %q, want %q", gotPaths, want)
+	}
+}
+
+func TestCompressedDirectory(t *testing.T) {
+	// Empty Java JAR, with a compressed directory with uncompressed size 0
+	// which should not fail.
+	//
+	// Length   Method    Size  Cmpr    Date    Time   CRC-32   Name
+	// --------  ------  ------- ---- ---------- ----- --------  ----
+	//        0  Defl:N        2   0% 12-01-2022 16:50 00000000  META-INF/
+	//       60  Defl:N       59   2% 12-01-2022 16:50 af937e93  META-INF/MANIFEST.MF
+	// --------          -------  ---                            -------
+	//       60               61  -2%                            2 files
+	data := []byte{
+		0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x08, 0x08,
+		0x08, 0x00, 0x49, 0x86, 0x81, 0x55, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x09, 0x00, 0x04, 0x00, 0x4d, 0x45,
+		0x54, 0x41, 0x2d, 0x49, 0x4e, 0x46, 0x2f, 0xfe,
+		0xca, 0x00, 0x00, 0x03, 0x00, 0x50, 0x4b, 0x07,
+		0x08, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x4b, 0x03,
+		0x04, 0x14, 0x00, 0x08, 0x08, 0x08, 0x00, 0x49,
+		0x86, 0x81, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
+		0x00, 0x00, 0x00, 0x4d, 0x45, 0x54, 0x41, 0x2d,
+		0x49, 0x4e, 0x46, 0x2f, 0x4d, 0x41, 0x4e, 0x49,
+		0x46, 0x45, 0x53, 0x54, 0x2e, 0x4d, 0x46, 0xf3,
+		0x4d, 0xcc, 0xcb, 0x4c, 0x4b, 0x2d, 0x2e, 0xd1,
+		0x0d, 0x4b, 0x2d, 0x2a, 0xce, 0xcc, 0xcf, 0xb3,
+		0x52, 0x30, 0xd4, 0x33, 0xe0, 0xe5, 0x72, 0x2e,
+		0x4a, 0x4d, 0x2c, 0x49, 0x4d, 0xd1, 0x75, 0xaa,
+		0x04, 0x0a, 0x00, 0x45, 0xf4, 0x0c, 0x8d, 0x15,
+		0x34, 0xdc, 0xf3, 0xf3, 0xd3, 0x73, 0x52, 0x15,
+		0x3c, 0xf3, 0x92, 0xf5, 0x34, 0x79, 0xb9, 0x78,
+		0xb9, 0x00, 0x50, 0x4b, 0x07, 0x08, 0x93, 0x7e,
+		0x93, 0xaf, 0x3b, 0x00, 0x00, 0x00, 0x3c, 0x00,
+		0x00, 0x00, 0x50, 0x4b, 0x01, 0x02, 0x14, 0x00,
+		0x14, 0x00, 0x08, 0x08, 0x08, 0x00, 0x49, 0x86,
+		0x81, 0x55, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00,
+		0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x4d, 0x45, 0x54, 0x41, 0x2d, 0x49, 0x4e, 0x46,
+		0x2f, 0xfe, 0xca, 0x00, 0x00, 0x50, 0x4b, 0x01,
+		0x02, 0x14, 0x00, 0x14, 0x00, 0x08, 0x08, 0x08,
+		0x00, 0x49, 0x86, 0x81, 0x55, 0x93, 0x7e, 0x93,
+		0xaf, 0x3b, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00,
+		0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d,
+		0x00, 0x00, 0x00, 0x4d, 0x45, 0x54, 0x41, 0x2d,
+		0x49, 0x4e, 0x46, 0x2f, 0x4d, 0x41, 0x4e, 0x49,
+		0x46, 0x45, 0x53, 0x54, 0x2e, 0x4d, 0x46, 0x50,
+		0x4b, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x02,
+		0x00, 0x02, 0x00, 0x7d, 0x00, 0x00, 0x00, 0xba,
+		0x00, 0x00, 0x00, 0x00, 0x00,
+	}
+	r, err := NewReader(bytes.NewReader(data), int64(len(data)))
+	if err != nil {
+		t.Fatalf("unexpected error: %v", err)
+	}
+	for _, f := range r.File {
+		r, err := f.Open()
+		if err != nil {
+			t.Fatalf("unexpected error: %v", err)
+		}
+		if _, err := io.Copy(io.Discard, r); err != nil {
+			t.Fatalf("unexpected error: %v", err)
+		}
+	}
+}
diff --git a/src/archive/zip/struct.go b/src/archive/zip/struct.go
index 6f73fb8..9c37084 100644
--- a/src/archive/zip/struct.go
+++ b/src/archive/zip/struct.go
@@ -5,7 +5,7 @@
 /*
 Package zip provides support for reading and writing ZIP archives.
 
-See: https://www.pkware.com/appnote
+See the [ZIP specification] for details.
 
 This package does not support disk spanning.
 
@@ -16,6 +16,8 @@
 for normal archives both fields will be the same. For files requiring
 the ZIP64 format the 32 bit fields will be 0xffffffff and the 64 bit
 fields must be used instead.
+
+[ZIP specification]: https://www.pkware.com/appnote
 */
 package zip
 
@@ -77,21 +79,16 @@
 	infoZipUnixExtraID = 0x5855 // Info-ZIP Unix extension
 )
 
-// FileHeader describes a file within a zip file.
-// See the zip spec for details.
+// FileHeader describes a file within a ZIP file.
+// See the [ZIP specification] for details.
+//
+// [ZIP specification]: https://www.pkware.com/appnote
 type FileHeader struct {
 	// Name is the name of the file.
 	//
 	// It must be a relative path, not start with a drive letter (such as "C:"),
 	// and must use forward slashes instead of back slashes. A trailing slash
 	// indicates that this file is a directory and should have no data.
-	//
-	// When reading zip files, the Name field is populated from
-	// the zip file directly and is not validated for correctness.
-	// It is the caller's responsibility to sanitize it as
-	// appropriate, including canonicalizing slash directions,
-	// validating that paths are relative, and preventing path
-	// traversal through filenames ("../../../").
 	Name string
 
 	// Comment is any arbitrary user-defined string shorter than 64KiB.
@@ -124,17 +121,43 @@
 	// When writing, an extended timestamp (which is timezone-agnostic) is
 	// always emitted. The legacy MS-DOS date field is encoded according to the
 	// location of the Modified time.
-	Modified     time.Time
-	ModifiedTime uint16 // Deprecated: Legacy MS-DOS date; use Modified instead.
-	ModifiedDate uint16 // Deprecated: Legacy MS-DOS time; use Modified instead.
+	Modified time.Time
 
-	CRC32              uint32
-	CompressedSize     uint32 // Deprecated: Use CompressedSize64 instead.
-	UncompressedSize   uint32 // Deprecated: Use UncompressedSize64 instead.
-	CompressedSize64   uint64
+	// ModifiedTime is an MS-DOS-encoded time.
+	//
+	// Deprecated: Use Modified instead.
+	ModifiedTime uint16
+
+	// ModifiedDate is an MS-DOS-encoded date.
+	//
+	// Deprecated: Use Modified instead.
+	ModifiedDate uint16
+
+	// CRC32 is the CRC32 checksum of the file content.
+	CRC32 uint32
+
+	// CompressedSize is the compressed size of the file in bytes.
+	// If either the uncompressed or compressed size of the file
+	// does not fit in 32 bits, CompressedSize is set to ^uint32(0).
+	//
+	// Deprecated: Use CompressedSize64 instead.
+	CompressedSize uint32
+
+	// UncompressedSize is the compressed size of the file in bytes.
+	// If either the uncompressed or compressed size of the file
+	// does not fit in 32 bits, CompressedSize is set to ^uint32(0).
+	//
+	// Deprecated: Use UncompressedSize64 instead.
+	UncompressedSize uint32
+
+	// CompressedSize64 is the compressed size of the file in bytes.
+	CompressedSize64 uint64
+
+	// UncompressedSize64 is the uncompressed size of the file in bytes.
 	UncompressedSize64 uint64
-	Extra              []byte
-	ExternalAttrs      uint32 // Meaning depends on CreatorVersion
+
+	Extra         []byte
+	ExternalAttrs uint32 // Meaning depends on CreatorVersion
 }
 
 // FileInfo returns an fs.FileInfo for the FileHeader.
diff --git a/src/archive/zip/zip_test.go b/src/archive/zip/zip_test.go
index ead9cd3..a4b952e 100644
--- a/src/archive/zip/zip_test.go
+++ b/src/archive/zip/zip_test.go
@@ -24,7 +24,7 @@
 	if testing.Short() && testenv.Builder() == "" {
 		t.Skip("skipping in short mode")
 	}
-	buf := new(bytes.Buffer)
+	buf := new(strings.Builder)
 	w := NewWriter(buf)
 	const nFiles = (1 << 16) + 42
 	for i := 0; i < nFiles; i++ {
diff --git a/src/arena/arena.go b/src/arena/arena.go
new file mode 100644
index 0000000..35b2fbd
--- /dev/null
+++ b/src/arena/arena.go
@@ -0,0 +1,108 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build goexperiment.arenas
+
+/*
+The arena package provides the ability to allocate memory for a collection
+of Go values and free that space manually all at once, safely. The purpose
+of this functionality is to improve efficiency: manually freeing memory
+before a garbage collection delays that cycle. Less frequent cycles means
+the CPU cost of the garbage collector is incurred less frequently.
+
+This functionality in this package is mostly captured in the Arena type.
+Arenas allocate large chunks of memory for Go values, so they're likely to
+be inefficient for allocating only small amounts of small Go values. They're
+best used in bulk, on the order of MiB of memory allocated on each use.
+
+Note that by allowing for this limited form of manual memory allocation
+that use-after-free bugs are possible with regular Go values. This package
+limits the impact of these use-after-free bugs by preventing reuse of freed
+memory regions until the garbage collector is able to determine that it is
+safe. Typically, a use-after-free bug will result in a fault and a helpful
+error message, but this package reserves the right to not force a fault on
+freed memory. That means a valid implementation of this package is to just
+allocate all memory the way the runtime normally would, and in fact, it
+reserves the right to occasionally do so for some Go values.
+*/
+package arena
+
+import (
+	"internal/reflectlite"
+	"unsafe"
+)
+
+// Arena represents a collection of Go values allocated and freed together.
+// Arenas are useful for improving efficiency as they may be freed back to
+// the runtime manually, though any memory obtained from freed arenas must
+// not be accessed once that happens. An Arena is automatically freed once
+// it is no longer referenced, so it must be kept alive (see runtime.KeepAlive)
+// until any memory allocated from it is no longer needed.
+//
+// An Arena must never be used concurrently by multiple goroutines.
+type Arena struct {
+	a unsafe.Pointer
+}
+
+// NewArena allocates a new arena.
+func NewArena() *Arena {
+	return &Arena{a: runtime_arena_newArena()}
+}
+
+// Free frees the arena (and all objects allocated from the arena) so that
+// memory backing the arena can be reused fairly quickly without garbage
+// collection overhead. Applications must not call any method on this
+// arena after it has been freed.
+func (a *Arena) Free() {
+	runtime_arena_arena_Free(a.a)
+	a.a = nil
+}
+
+// New creates a new *T in the provided arena. The *T must not be used after
+// the arena is freed. Accessing the value after free may result in a fault,
+// but this fault is also not guaranteed.
+func New[T any](a *Arena) *T {
+	return runtime_arena_arena_New(a.a, reflectlite.TypeOf((*T)(nil))).(*T)
+}
+
+// MakeSlice creates a new []T with the provided capacity and length. The []T must
+// not be used after the arena is freed. Accessing the underlying storage of the
+// slice after free may result in a fault, but this fault is also not guaranteed.
+func MakeSlice[T any](a *Arena, len, cap int) []T {
+	var sl []T
+	runtime_arena_arena_Slice(a.a, &sl, cap)
+	return sl[:len]
+}
+
+// Clone makes a shallow copy of the input value that is no longer bound to any
+// arena it may have been allocated from, returning the copy. If it was not
+// allocated from an arena, it is returned untouched. This function is useful
+// to more easily let an arena-allocated value out-live its arena.
+// T must be a pointer, a slice, or a string, otherwise this function will panic.
+func Clone[T any](s T) T {
+	return runtime_arena_heapify(s).(T)
+}
+
+//go:linkname reflect_arena_New reflect.arena_New
+func reflect_arena_New(a *Arena, typ any) any {
+	return runtime_arena_arena_New(a.a, typ)
+}
+
+//go:linkname runtime_arena_newArena
+func runtime_arena_newArena() unsafe.Pointer
+
+//go:linkname runtime_arena_arena_New
+func runtime_arena_arena_New(arena unsafe.Pointer, typ any) any
+
+// Mark as noescape to avoid escaping the slice header.
+//
+//go:noescape
+//go:linkname runtime_arena_arena_Slice
+func runtime_arena_arena_Slice(arena unsafe.Pointer, slice any, cap int)
+
+//go:linkname runtime_arena_arena_Free
+func runtime_arena_arena_Free(arena unsafe.Pointer)
+
+//go:linkname runtime_arena_heapify
+func runtime_arena_heapify(any) any
diff --git a/src/arena/arena_test.go b/src/arena/arena_test.go
new file mode 100644
index 0000000..017c33c
--- /dev/null
+++ b/src/arena/arena_test.go
@@ -0,0 +1,42 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build goexperiment.arenas
+
+package arena_test
+
+import (
+	"arena"
+	"testing"
+)
+
+type T1 struct {
+	n int
+}
+type T2 [1 << 20]byte // 1MiB
+
+func TestSmoke(t *testing.T) {
+	a := arena.NewArena()
+	defer a.Free()
+
+	tt := arena.New[T1](a)
+	tt.n = 1
+
+	ts := arena.MakeSlice[T1](a, 99, 100)
+	if len(ts) != 99 {
+		t.Errorf("Slice() len = %d, want 99", len(ts))
+	}
+	if cap(ts) != 100 {
+		t.Errorf("Slice() cap = %d, want 100", cap(ts))
+	}
+	ts[1].n = 42
+}
+
+func TestSmokeLarge(t *testing.T) {
+	a := arena.NewArena()
+	defer a.Free()
+	for i := 0; i < 10*64; i++ {
+		_ = arena.New[T2](a)
+	}
+}
diff --git a/src/bootstrap.bash b/src/bootstrap.bash
index 4038eaf..1e4f1c5 100755
--- a/src/bootstrap.bash
+++ b/src/bootstrap.bash
@@ -15,14 +15,8 @@
 # Only changes that have been committed to Git (at least locally,
 # not necessary reviewed and submitted to master) are included in the tree.
 #
-# As a special case for Go's internal use only, if the
-# BOOTSTRAP_FORMAT environment variable is set to "mintgz", the
-# resulting archive is intended for use by the Go build system and
-# differs in that the mintgz file:
-#   * is a tar.gz file instead of bz2
-#   * has many unnecessary files deleted to reduce its size
-#   * does not have a shared directory component for each tar entry
-# Do not depend on the mintgz format.
+# See also golang.org/x/build/cmd/genbootstrap, which is used
+# to generate bootstrap tgz files for builders.
 
 set -e
 
@@ -37,11 +31,6 @@
 	exit 2
 fi
 
-if [ "$BOOTSTRAP_FORMAT" != "mintgz" -a "$BOOTSTRAP_FORMAT" != "" ]; then
-	echo "unknown BOOTSTRAP_FORMAT format"
-	exit 2
-fi
-
 unset GOROOT
 src=$(cd .. && pwd)
 echo "#### Copying to $targ"
@@ -79,39 +68,8 @@
 	rm -rf "pkg/${gohostos}_${gohostarch}" "pkg/tool/${gohostos}_${gohostarch}"
 fi
 
-if [ "$BOOTSTRAP_FORMAT" = "mintgz" ]; then
-	# Fetch git revision before rm -rf .git.
-	GITREV=$(git rev-parse --short HEAD)
-fi
-
 rm -rf pkg/bootstrap pkg/obj .git
 
-# Support for building minimal tar.gz for the builders.
-# The build system doesn't support bzip2, and by deleting more stuff,
-# they start faster, especially on machines without fast filesystems
-# and things like tmpfs configures.
-# Do not depend on this format. It's for internal use only.
-if [ "$BOOTSTRAP_FORMAT" = "mintgz" ]; then
-	OUTGZ="gobootstrap-${GOOS}-${GOARCH}-${GITREV}.tar.gz"
-	echo "Preparing to generate build system's ${OUTGZ}; cleaning ..."
-	rm -rf bin/gofmt
-	rm -rf src/runtime/race/race_*.syso
-	rm -rf api test doc misc/cgo/test
-	rm -rf pkg/tool/*_*/{addr2line,api,cgo,cover,doc,fix,nm,objdump,pack,pprof,test2json,trace,vet}
-	rm -rf pkg/*_*/{image,database,cmd}
-	rm -rf $(find . -type d -name testdata)
-	find . -type f -name '*_test.go' -exec rm {} \;
-	# git clean doesn't clean symlinks apparently, and the buildlet
-	# rejects them, so:
-	find . -type l -exec rm {} \;
-
-	echo "Writing ${OUTGZ} ..."
-	tar cf - . | gzip -9 > ../$OUTGZ
-	cd ..
-	ls -l "$(pwd)/$OUTGZ"
-	exit 0
-fi
-
 echo ----
 echo Bootstrap toolchain for "$GOOS/$GOARCH" installed in "$(pwd)".
 echo Building tbz.
diff --git a/src/bufio/bufio.go b/src/bufio/bufio.go
index 1da8ffa..5a88def 100644
--- a/src/bufio/bufio.go
+++ b/src/bufio/bufio.go
@@ -454,8 +454,7 @@
 		}
 
 		// Make a copy of the buffer.
-		buf := make([]byte, len(frag))
-		copy(buf, frag)
+		buf := bytes.Clone(frag)
 		fullBuffers = append(fullBuffers, buf)
 		totalLen += len(buf)
 	}
diff --git a/src/bufio/bufio_test.go b/src/bufio/bufio_test.go
index b3456d2..64ccd02 100644
--- a/src/bufio/bufio_test.go
+++ b/src/bufio/bufio_test.go
@@ -574,7 +574,7 @@
 	// Invalid runes, including negative ones, should be written as the
 	// replacement character.
 	for _, r := range []rune{-1, utf8.MaxRune + 1} {
-		var buf bytes.Buffer
+		var buf strings.Builder
 		w := NewWriter(&buf)
 		w.WriteRune(r)
 		w.Flush()
@@ -746,7 +746,7 @@
 
 func TestWriteString(t *testing.T) {
 	const BufSize = 8
-	buf := new(bytes.Buffer)
+	buf := new(strings.Builder)
 	b := NewWriterSize(buf, BufSize)
 	b.WriteString("0")                         // easy
 	b.WriteString("123456")                    // still easy
@@ -757,8 +757,8 @@
 		t.Error("WriteString", err)
 	}
 	s := "01234567890abcdefghijklmnopqrstuvwxyz"
-	if string(buf.Bytes()) != s {
-		t.Errorf("WriteString wants %q gets %q", s, string(buf.Bytes()))
+	if buf.String() != s {
+		t.Errorf("WriteString wants %q gets %q", s, buf.String())
 	}
 }
 
@@ -1001,7 +1001,7 @@
 	line1 := "this is line1"
 	restData := "this is line2\nthis is line 3\n"
 	inbuf := bytes.NewReader([]byte(line1 + "\n" + restData))
-	outbuf := new(bytes.Buffer)
+	outbuf := new(strings.Builder)
 	maxLineLength := len(line1) + len(restData)/2
 	l := NewReaderSize(inbuf, maxLineLength)
 	line, isPrefix, err := l.ReadLine()
@@ -1173,7 +1173,7 @@
 	for ri, rfunc := range rs {
 		for wi, wfunc := range ws {
 			input := createTestInput(8192)
-			b := new(bytes.Buffer)
+			b := new(strings.Builder)
 			w := NewWriter(wfunc(b))
 			r := rfunc(bytes.NewReader(input))
 			if n, err := w.ReadFrom(r); err != nil || n != int64(len(input)) {
@@ -1389,7 +1389,7 @@
 		t.Fatalf("ReadFrom returned (%v, %v), want (4, nil)", n2, err)
 	}
 	w.Flush()
-	if got, want := string(buf.Bytes()), "0123abcd"; got != want {
+	if got, want := buf.String(), "0123abcd"; got != want {
 		t.Fatalf("buf.Bytes() returned %q, want %q", got, want)
 	}
 }
@@ -1510,7 +1510,7 @@
 }
 
 func TestWriterReset(t *testing.T) {
-	var buf1, buf2, buf3 bytes.Buffer
+	var buf1, buf2, buf3 strings.Builder
 	w := NewWriter(&buf1)
 	w.WriteString("foo")
 
diff --git a/src/buildall.bash b/src/buildall.bash
index 7b3751f..e4e3ec3 100755
--- a/src/buildall.bash
+++ b/src/buildall.bash
@@ -41,7 +41,7 @@
 }
 
 selectedtargets() {
-	gettargets | egrep "$pattern"
+	gettargets | grep -E "$pattern"
 }
 
 # put linux first in the target list to get all the architectures up front.
diff --git a/src/bytes/buffer.go b/src/bytes/buffer.go
index 0bacbda..ee83fd8 100644
--- a/src/bytes/buffer.go
+++ b/src/bytes/buffer.go
@@ -298,9 +298,8 @@
 	if !ok {
 		m = b.grow(utf8.UTFMax)
 	}
-	n = utf8.EncodeRune(b.buf[m:m+utf8.UTFMax], r)
-	b.buf = b.buf[:m+n]
-	return n, nil
+	b.buf = utf8.AppendRune(b.buf[:m], r)
+	return len(b.buf) - m, nil
 }
 
 // Read reads the next len(p) bytes from the buffer or until the buffer
diff --git a/src/bytes/bytes.go b/src/bytes/bytes.go
index 659a82b..e2e5d5f 100644
--- a/src/bytes/bytes.go
+++ b/src/bytes/bytes.go
@@ -560,9 +560,7 @@
 	// In the worst case, the slice can grow when mapped, making
 	// things unpleasant. But it's so rare we barge in assuming it's
 	// fine. It could also shrink but that falls out naturally.
-	maxbytes := len(s) // length of b
-	nbytes := 0        // number of bytes encoded in b
-	b := make([]byte, maxbytes)
+	b := make([]byte, 0, len(s))
 	for i := 0; i < len(s); {
 		wid := 1
 		r := rune(s[i])
@@ -571,28 +569,17 @@
 		}
 		r = mapping(r)
 		if r >= 0 {
-			rl := utf8.RuneLen(r)
-			if rl < 0 {
-				rl = len(string(utf8.RuneError))
-			}
-			if nbytes+rl > maxbytes {
-				// Grow the buffer.
-				maxbytes = maxbytes*2 + utf8.UTFMax
-				nb := make([]byte, maxbytes)
-				copy(nb, b[0:nbytes])
-				b = nb
-			}
-			nbytes += utf8.EncodeRune(b[nbytes:maxbytes], r)
+			b = utf8.AppendRune(b, r)
 		}
 		i += wid
 	}
-	return b[0:nbytes]
+	return b
 }
 
 // Repeat returns a new byte slice consisting of count copies of b.
 //
-// It panics if count is negative or if
-// the result of (len(b) * count) overflows.
+// It panics if count is negative or if the result of (len(b) * count)
+// overflows.
 func Repeat(b []byte, count int) []byte {
 	if count == 0 {
 		return []byte{}
@@ -600,18 +587,45 @@
 	// Since we cannot return an error on overflow,
 	// we should panic if the repeat will generate
 	// an overflow.
-	// See Issue golang.org/issue/16237.
+	// See golang.org/issue/16237.
 	if count < 0 {
 		panic("bytes: negative Repeat count")
 	} else if len(b)*count/count != len(b) {
 		panic("bytes: Repeat count causes overflow")
 	}
 
-	nb := make([]byte, len(b)*count)
+	if len(b) == 0 {
+		return []byte{}
+	}
+
+	n := len(b) * count
+
+	// Past a certain chunk size it is counterproductive to use
+	// larger chunks as the source of the write, as when the source
+	// is too large we are basically just thrashing the CPU D-cache.
+	// So if the result length is larger than an empirically-found
+	// limit (8KB), we stop growing the source string once the limit
+	// is reached and keep reusing the same source string - that
+	// should therefore be always resident in the L1 cache - until we
+	// have completed the construction of the result.
+	// This yields significant speedups (up to +100%) in cases where
+	// the result length is large (roughly, over L2 cache size).
+	const chunkLimit = 8 * 1024
+	chunkMax := n
+	if chunkMax > chunkLimit {
+		chunkMax = chunkLimit / len(b) * len(b)
+		if chunkMax == 0 {
+			chunkMax = len(b)
+		}
+	}
+	nb := make([]byte, n)
 	bp := copy(nb, b)
 	for bp < len(nb) {
-		copy(nb[bp:], nb[:bp])
-		bp *= 2
+		chunk := bp
+		if chunk > chunkMax {
+			chunk = chunkMax
+		}
+		bp += copy(nb[bp:], nb[:chunk])
 	}
 	return nb
 }
@@ -1147,6 +1161,36 @@
 // are equal under simple Unicode case-folding, which is a more general
 // form of case-insensitivity.
 func EqualFold(s, t []byte) bool {
+	// ASCII fast path
+	i := 0
+	for ; i < len(s) && i < len(t); i++ {
+		sr := s[i]
+		tr := t[i]
+		if sr|tr >= utf8.RuneSelf {
+			goto hasUnicode
+		}
+
+		// Easy case.
+		if tr == sr {
+			continue
+		}
+
+		// Make sr < tr to simplify what follows.
+		if tr < sr {
+			tr, sr = sr, tr
+		}
+		// ASCII only, sr/tr must be upper/lower case
+		if 'A' <= sr && sr <= 'Z' && tr == sr+'a'-'A' {
+			continue
+		}
+		return false
+	}
+	// Check if we've exhausted both strings.
+	return len(s) == len(t)
+
+hasUnicode:
+	s = s[i:]
+	t = t[i:]
 	for len(s) != 0 && len(t) != 0 {
 		// Extract first rune from each.
 		var sr, tr rune
@@ -1299,3 +1343,39 @@
 	}
 	return s, nil, false
 }
+
+// Clone returns a copy of b[:len(b)].
+// The result may have additional unused capacity.
+// Clone(nil) returns nil.
+func Clone(b []byte) []byte {
+	if b == nil {
+		return nil
+	}
+	return append([]byte{}, b...)
+}
+
+// CutPrefix returns s without the provided leading prefix byte slice
+// and reports whether it found the prefix.
+// If s doesn't start with prefix, CutPrefix returns s, false.
+// If prefix is the empty byte slice, CutPrefix returns s, true.
+//
+// CutPrefix returns slices of the original slice s, not copies.
+func CutPrefix(s, prefix []byte) (after []byte, found bool) {
+	if !HasPrefix(s, prefix) {
+		return s, false
+	}
+	return s[len(prefix):], true
+}
+
+// CutSuffix returns s without the provided ending suffix byte slice
+// and reports whether it found the suffix.
+// If s doesn't end with suffix, CutSuffix returns s, false.
+// If suffix is the empty byte slice, CutSuffix returns s, true.
+//
+// CutSuffix returns slices of the original slice s, not copies.
+func CutSuffix(s, suffix []byte) (before []byte, found bool) {
+	if !HasSuffix(s, suffix) {
+		return s, false
+	}
+	return s[:len(s)-len(suffix)], true
+}
diff --git a/src/bytes/bytes_test.go b/src/bytes/bytes_test.go
index 985aa0b..f58f18c 100644
--- a/src/bytes/bytes_test.go
+++ b/src/bytes/bytes_test.go
@@ -15,6 +15,7 @@
 	"testing"
 	"unicode"
 	"unicode/utf8"
+	"unsafe"
 )
 
 func eq(a, b []string) bool {
@@ -755,6 +756,8 @@
 	{"123", "", 2, []string{"1", "23"}},
 	{"123", "", 17, []string{"1", "2", "3"}},
 	{"bT", "T", math.MaxInt / 4, []string{"b", ""}},
+	{"\xff-\xff", "", -1, []string{"\xff", "-", "\xff"}},
+	{"\xff-\xff", "-", -1, []string{"\xff", "\xff"}},
 }
 
 func TestSplit(t *testing.T) {
@@ -1156,6 +1159,8 @@
 	count   int
 }
 
+var longString = "a" + string(make([]byte, 1<<16)) + "z"
+
 var RepeatTests = []RepeatTest{
 	{"", "", 0},
 	{"", "", 1},
@@ -1164,6 +1169,9 @@
 	{"-", "-", 1},
 	{"-", "----------", 10},
 	{"abc ", "abc abc abc ", 3},
+	// Tests for results over the chunkLimit
+	{string(rune(0)), string(make([]byte, 1<<16)), 1 << 16},
+	{longString, longString + longString, 2},
 }
 
 func TestRepeat(t *testing.T) {
@@ -1697,6 +1705,48 @@
 	}
 }
 
+var cutPrefixTests = []struct {
+	s, sep string
+	after  string
+	found  bool
+}{
+	{"abc", "a", "bc", true},
+	{"abc", "abc", "", true},
+	{"abc", "", "abc", true},
+	{"abc", "d", "abc", false},
+	{"", "d", "", false},
+	{"", "", "", true},
+}
+
+func TestCutPrefix(t *testing.T) {
+	for _, tt := range cutPrefixTests {
+		if after, found := CutPrefix([]byte(tt.s), []byte(tt.sep)); string(after) != tt.after || found != tt.found {
+			t.Errorf("CutPrefix(%q, %q) = %q, %v, want %q, %v", tt.s, tt.sep, after, found, tt.after, tt.found)
+		}
+	}
+}
+
+var cutSuffixTests = []struct {
+	s, sep string
+	after  string
+	found  bool
+}{
+	{"abc", "bc", "a", true},
+	{"abc", "abc", "", true},
+	{"abc", "", "abc", true},
+	{"abc", "d", "abc", false},
+	{"", "d", "", false},
+	{"", "", "", true},
+}
+
+func TestCutSuffix(t *testing.T) {
+	for _, tt := range cutSuffixTests {
+		if after, found := CutSuffix([]byte(tt.s), []byte(tt.sep)); string(after) != tt.after || found != tt.found {
+			t.Errorf("CutSuffix(%q, %q) = %q, %v, want %q, %v", tt.s, tt.sep, after, found, tt.after, tt.found)
+		}
+	}
+}
+
 func TestBufferGrowNegative(t *testing.T) {
 	defer func() {
 		if err := recover(); err == nil {
@@ -2003,6 +2053,25 @@
 	}
 }
 
+func BenchmarkRepeatLarge(b *testing.B) {
+	s := Repeat([]byte("@"), 8*1024)
+	for j := 8; j <= 30; j++ {
+		for _, k := range []int{1, 16, 4097} {
+			s := s[:k]
+			n := (1 << j) / k
+			if n == 0 {
+				continue
+			}
+			b.Run(fmt.Sprintf("%d/%d", 1<<j, k), func(b *testing.B) {
+				for i := 0; i < b.N; i++ {
+					Repeat(s, n)
+				}
+				b.SetBytes(int64(n * len(s)))
+			})
+		}
+	}
+}
+
 func BenchmarkBytesCompare(b *testing.B) {
 	for n := 1; n <= 2048; n <<= 1 {
 		b.Run(fmt.Sprint(n), func(b *testing.B) {
@@ -2116,3 +2185,33 @@
 		})
 	}
 }
+
+func TestClone(t *testing.T) {
+	var cloneTests = [][]byte{
+		[]byte(nil),
+		[]byte{},
+		Clone([]byte{}),
+		[]byte(strings.Repeat("a", 42))[:0],
+		[]byte(strings.Repeat("a", 42))[:0:0],
+		[]byte("short"),
+		[]byte(strings.Repeat("a", 42)),
+	}
+	for _, input := range cloneTests {
+		clone := Clone(input)
+		if !Equal(clone, input) {
+			t.Errorf("Clone(%q) = %q; want %q", input, clone, input)
+		}
+
+		if input == nil && clone != nil {
+			t.Errorf("Clone(%#v) return value should be equal to nil slice.", input)
+		}
+
+		if input != nil && clone == nil {
+			t.Errorf("Clone(%#v) return value should not be equal to nil slice.", input)
+		}
+
+		if cap(input) != 0 && unsafe.SliceData(input) == unsafe.SliceData(clone) {
+			t.Errorf("Clone(%q) return value should not reference inputs backing memory.", input)
+		}
+	}
+}
diff --git a/src/bytes/compare_test.go b/src/bytes/compare_test.go
index a595d57..a0150ab 100644
--- a/src/bytes/compare_test.go
+++ b/src/bytes/compare_test.go
@@ -6,6 +6,7 @@
 
 import (
 	. "bytes"
+	"fmt"
 	"internal/testenv"
 	"testing"
 )
@@ -213,22 +214,30 @@
 	}
 }
 
-func BenchmarkCompareBytesBigUnaligned(b *testing.B) {
+func benchmarkCompareBytesBigUnaligned(b *testing.B, offset int) {
 	b.StopTimer()
 	b1 := make([]byte, 0, 1<<20)
 	for len(b1) < 1<<20 {
 		b1 = append(b1, "Hello Gophers!"...)
 	}
-	b2 := append([]byte("hello"), b1...)
+	b2 := append([]byte("12345678")[:offset], b1...)
 	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		if Compare(b1, b2[len("hello"):]) != 0 {
+	for j := 0; j < b.N; j++ {
+		if Compare(b1, b2[offset:]) != 0 {
 			b.Fatal("b1 != b2")
 		}
 	}
 	b.SetBytes(int64(len(b1)))
 }
 
+func BenchmarkCompareBytesBigUnaligned(b *testing.B) {
+	for i := 1; i < 8; i++ {
+		b.Run(fmt.Sprintf("offset=%d", i), func(b *testing.B) {
+			benchmarkCompareBytesBigUnaligned(b, i)
+		})
+	}
+}
+
 func BenchmarkCompareBytesBig(b *testing.B) {
 	b.StopTimer()
 	b1 := make([]byte, 0, 1<<20)
diff --git a/src/cmd/addr2line/addr2line_test.go b/src/cmd/addr2line/addr2line_test.go
index 992d7ac..0ea8994 100644
--- a/src/cmd/addr2line/addr2line_test.go
+++ b/src/cmd/addr2line/addr2line_test.go
@@ -9,18 +9,50 @@
 	"bytes"
 	"internal/testenv"
 	"os"
-	"os/exec"
 	"path/filepath"
 	"runtime"
 	"strings"
+	"sync"
 	"testing"
 )
 
-func loadSyms(t *testing.T) map[string]string {
-	cmd := exec.Command(testenv.GoToolPath(t), "tool", "nm", os.Args[0])
+// TestMain executes the test binary as the addr2line command if
+// GO_ADDR2LINETEST_IS_ADDR2LINE is set, and runs the tests otherwise.
+func TestMain(m *testing.M) {
+	if os.Getenv("GO_ADDR2LINETEST_IS_ADDR2LINE") != "" {
+		main()
+		os.Exit(0)
+	}
+
+	os.Setenv("GO_ADDR2LINETEST_IS_ADDR2LINE", "1") // Set for subprocesses to inherit.
+	os.Exit(m.Run())
+}
+
+// addr2linePath returns the path to the "addr2line" binary to run.
+func addr2linePath(t testing.TB) string {
+	t.Helper()
+	testenv.MustHaveExec(t)
+
+	addr2linePathOnce.Do(func() {
+		addr2lineExePath, addr2linePathErr = os.Executable()
+	})
+	if addr2linePathErr != nil {
+		t.Fatal(addr2linePathErr)
+	}
+	return addr2lineExePath
+}
+
+var (
+	addr2linePathOnce sync.Once
+	addr2lineExePath  string
+	addr2linePathErr  error
+)
+
+func loadSyms(t *testing.T, dbgExePath string) map[string]string {
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "tool", "nm", dbgExePath)
 	out, err := cmd.CombinedOutput()
 	if err != nil {
-		t.Fatalf("go tool nm %v: %v\n%s", os.Args[0], err, string(out))
+		t.Fatalf("%v: %v\n%s", cmd, err, string(out))
 	}
 	syms := make(map[string]string)
 	scanner := bufio.NewScanner(bytes.NewReader(out))
@@ -37,8 +69,8 @@
 	return syms
 }
 
-func runAddr2Line(t *testing.T, exepath, addr string) (funcname, path, lineno string) {
-	cmd := exec.Command(exepath, os.Args[0])
+func runAddr2Line(t *testing.T, dbgExePath, addr string) (funcname, path, lineno string) {
+	cmd := testenv.Command(t, addr2linePath(t), dbgExePath)
 	cmd.Stdin = strings.NewReader(addr)
 	out, err := cmd.CombinedOutput()
 	if err != nil {
@@ -63,8 +95,8 @@
 
 const symName = "cmd/addr2line.TestAddr2Line"
 
-func testAddr2Line(t *testing.T, exepath, addr string) {
-	funcName, srcPath, srcLineNo := runAddr2Line(t, exepath, addr)
+func testAddr2Line(t *testing.T, dbgExePath, addr string) {
+	funcName, srcPath, srcLineNo := runAddr2Line(t, dbgExePath, addr)
 	if symName != funcName {
 		t.Fatalf("expected function name %v; got %v", symName, funcName)
 	}
@@ -97,12 +129,12 @@
 	if !os.SameFile(fi1, fi2) {
 		t.Fatalf("addr2line_test.go and %s are not same file", srcPath)
 	}
-	if srcLineNo != "106" {
-		t.Fatalf("line number = %v; want 106", srcLineNo)
+	if srcLineNo != "138" {
+		t.Fatalf("line number = %v; want 138", srcLineNo)
 	}
 }
 
-// This is line 106. The test depends on that.
+// This is line 137. The test depends on that.
 func TestAddr2Line(t *testing.T) {
 	testenv.MustHaveGoBuild(t)
 
@@ -115,19 +147,12 @@
 	// Build copy of test binary with debug symbols,
 	// since the one running now may not have them.
 	exepath := filepath.Join(tmpDir, "testaddr2line_test.exe")
-	out, err := exec.Command(testenv.GoToolPath(t), "test", "-c", "-o", exepath, "cmd/addr2line").CombinedOutput()
+	out, err := testenv.Command(t, testenv.GoToolPath(t), "test", "-c", "-o", exepath, "cmd/addr2line").CombinedOutput()
 	if err != nil {
 		t.Fatalf("go test -c -o %v cmd/addr2line: %v\n%s", exepath, err, string(out))
 	}
-	os.Args[0] = exepath
 
-	syms := loadSyms(t)
-
-	exepath = filepath.Join(tmpDir, "testaddr2line.exe")
-	out, err = exec.Command(testenv.GoToolPath(t), "build", "-o", exepath, "cmd/addr2line").CombinedOutput()
-	if err != nil {
-		t.Fatalf("go build -o %v cmd/addr2line: %v\n%s", exepath, err, string(out))
-	}
+	syms := loadSyms(t, exepath)
 
 	testAddr2Line(t, exepath, syms[symName])
 	testAddr2Line(t, exepath, "0x"+syms[symName])
diff --git a/src/cmd/api/api.go b/src/cmd/api/api.go
new file mode 100644
index 0000000..399da1c
--- /dev/null
+++ b/src/cmd/api/api.go
@@ -0,0 +1,1264 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package api computes the exported API of a set of Go packages.
+// It is only a test, not a command, nor a usefully importable package.
+package api
+
+import (
+	"bufio"
+	"bytes"
+	"encoding/json"
+	"flag"
+	"fmt"
+	"go/ast"
+	"go/build"
+	"go/parser"
+	"go/token"
+	"go/types"
+	"internal/testenv"
+	"io"
+	"log"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"regexp"
+	"runtime"
+	"sort"
+	"strconv"
+	"strings"
+	"sync"
+	"testing"
+)
+
+const verbose = false
+
+func goCmd() string {
+	var exeSuffix string
+	if runtime.GOOS == "windows" {
+		exeSuffix = ".exe"
+	}
+	path := filepath.Join(testenv.GOROOT(nil), "bin", "go"+exeSuffix)
+	if _, err := os.Stat(path); err == nil {
+		return path
+	}
+	return "go"
+}
+
+// contexts are the default contexts which are scanned, unless
+// overridden by the -contexts flag.
+var contexts = []*build.Context{
+	{GOOS: "linux", GOARCH: "386", CgoEnabled: true},
+	{GOOS: "linux", GOARCH: "386"},
+	{GOOS: "linux", GOARCH: "amd64", CgoEnabled: true},
+	{GOOS: "linux", GOARCH: "amd64"},
+	{GOOS: "linux", GOARCH: "arm", CgoEnabled: true},
+	{GOOS: "linux", GOARCH: "arm"},
+	{GOOS: "darwin", GOARCH: "amd64", CgoEnabled: true},
+	{GOOS: "darwin", GOARCH: "amd64"},
+	{GOOS: "darwin", GOARCH: "arm64", CgoEnabled: true},
+	{GOOS: "darwin", GOARCH: "arm64"},
+	{GOOS: "windows", GOARCH: "amd64"},
+	{GOOS: "windows", GOARCH: "386"},
+	{GOOS: "freebsd", GOARCH: "386", CgoEnabled: true},
+	{GOOS: "freebsd", GOARCH: "386"},
+	{GOOS: "freebsd", GOARCH: "amd64", CgoEnabled: true},
+	{GOOS: "freebsd", GOARCH: "amd64"},
+	{GOOS: "freebsd", GOARCH: "arm", CgoEnabled: true},
+	{GOOS: "freebsd", GOARCH: "arm"},
+	{GOOS: "netbsd", GOARCH: "386", CgoEnabled: true},
+	{GOOS: "netbsd", GOARCH: "386"},
+	{GOOS: "netbsd", GOARCH: "amd64", CgoEnabled: true},
+	{GOOS: "netbsd", GOARCH: "amd64"},
+	{GOOS: "netbsd", GOARCH: "arm", CgoEnabled: true},
+	{GOOS: "netbsd", GOARCH: "arm"},
+	{GOOS: "netbsd", GOARCH: "arm64", CgoEnabled: true},
+	{GOOS: "netbsd", GOARCH: "arm64"},
+	{GOOS: "openbsd", GOARCH: "386", CgoEnabled: true},
+	{GOOS: "openbsd", GOARCH: "386"},
+	{GOOS: "openbsd", GOARCH: "amd64", CgoEnabled: true},
+	{GOOS: "openbsd", GOARCH: "amd64"},
+}
+
+func contextName(c *build.Context) string {
+	s := c.GOOS + "-" + c.GOARCH
+	if c.CgoEnabled {
+		s += "-cgo"
+	}
+	if c.Dir != "" {
+		s += fmt.Sprintf(" [%s]", c.Dir)
+	}
+	return s
+}
+
+func parseContext(c string) *build.Context {
+	parts := strings.Split(c, "-")
+	if len(parts) < 2 {
+		log.Fatalf("bad context: %q", c)
+	}
+	bc := &build.Context{
+		GOOS:   parts[0],
+		GOARCH: parts[1],
+	}
+	if len(parts) == 3 {
+		if parts[2] == "cgo" {
+			bc.CgoEnabled = true
+		} else {
+			log.Fatalf("bad context: %q", c)
+		}
+	}
+	return bc
+}
+
+var internalPkg = regexp.MustCompile(`(^|/)internal($|/)`)
+
+var exitCode = 0
+
+func Check(t *testing.T) {
+	checkFiles, err := filepath.Glob(filepath.Join(testenv.GOROOT(t), "api/go1*.txt"))
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	var nextFiles []string
+	if strings.Contains(runtime.Version(), "devel") {
+		next, err := filepath.Glob(filepath.Join(testenv.GOROOT(t), "api/next/*.txt"))
+		if err != nil {
+			t.Fatal(err)
+		}
+		nextFiles = next
+	}
+
+	for _, c := range contexts {
+		c.Compiler = build.Default.Compiler
+	}
+
+	walkers := make([]*Walker, len(contexts))
+	var wg sync.WaitGroup
+	for i, context := range contexts {
+		i, context := i, context
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+			walkers[i] = NewWalker(context, filepath.Join(testenv.GOROOT(t), "src"))
+		}()
+	}
+	wg.Wait()
+
+	var featureCtx = make(map[string]map[string]bool) // feature -> context name -> true
+	for _, w := range walkers {
+		pkgNames := w.stdPackages
+		if flag.NArg() > 0 {
+			pkgNames = flag.Args()
+		}
+
+		for _, name := range pkgNames {
+			pkg, err := w.import_(name)
+			if _, nogo := err.(*build.NoGoError); nogo {
+				continue
+			}
+			if err != nil {
+				log.Fatalf("Import(%q): %v", name, err)
+			}
+			w.export(pkg)
+		}
+
+		ctxName := contextName(w.context)
+		for _, f := range w.Features() {
+			if featureCtx[f] == nil {
+				featureCtx[f] = make(map[string]bool)
+			}
+			featureCtx[f][ctxName] = true
+		}
+	}
+
+	var features []string
+	for f, cmap := range featureCtx {
+		if len(cmap) == len(contexts) {
+			features = append(features, f)
+			continue
+		}
+		comma := strings.Index(f, ",")
+		for cname := range cmap {
+			f2 := fmt.Sprintf("%s (%s)%s", f[:comma], cname, f[comma:])
+			features = append(features, f2)
+		}
+	}
+
+	bw := bufio.NewWriter(os.Stdout)
+	defer bw.Flush()
+
+	var required []string
+	for _, file := range checkFiles {
+		required = append(required, fileFeatures(file, needApproval(file))...)
+	}
+	var optional []string
+	for _, file := range nextFiles {
+		optional = append(optional, fileFeatures(file, true)...)
+	}
+	exception := fileFeatures(filepath.Join(testenv.GOROOT(t), "api/except.txt"), false)
+
+	if exitCode == 1 {
+		t.Errorf("API database problems found")
+	}
+	if !compareAPI(bw, features, required, optional, exception, false) {
+		t.Errorf("API differences found")
+	}
+}
+
+// export emits the exported package features.
+func (w *Walker) export(pkg *apiPackage) {
+	if verbose {
+		log.Println(pkg)
+	}
+	pop := w.pushScope("pkg " + pkg.Path())
+	w.current = pkg
+	w.collectDeprecated()
+	scope := pkg.Scope()
+	for _, name := range scope.Names() {
+		if token.IsExported(name) {
+			w.emitObj(scope.Lookup(name))
+		}
+	}
+	pop()
+}
+
+func set(items []string) map[string]bool {
+	s := make(map[string]bool)
+	for _, v := range items {
+		s[v] = true
+	}
+	return s
+}
+
+var spaceParensRx = regexp.MustCompile(` \(\S+?\)`)
+
+func featureWithoutContext(f string) string {
+	if !strings.Contains(f, "(") {
+		return f
+	}
+	return spaceParensRx.ReplaceAllString(f, "")
+}
+
+// portRemoved reports whether the given port-specific API feature is
+// okay to no longer exist because its port was removed.
+func portRemoved(feature string) bool {
+	return strings.Contains(feature, "(darwin-386)") ||
+		strings.Contains(feature, "(darwin-386-cgo)")
+}
+
+func compareAPI(w io.Writer, features, required, optional, exception []string, allowAdd bool) (ok bool) {
+	ok = true
+
+	optionalSet := set(optional)
+	exceptionSet := set(exception)
+	featureSet := set(features)
+
+	sort.Strings(features)
+	sort.Strings(required)
+
+	take := func(sl *[]string) string {
+		s := (*sl)[0]
+		*sl = (*sl)[1:]
+		return s
+	}
+
+	for len(required) > 0 || len(features) > 0 {
+		switch {
+		case len(features) == 0 || (len(required) > 0 && required[0] < features[0]):
+			feature := take(&required)
+			if exceptionSet[feature] {
+				// An "unfortunate" case: the feature was once
+				// included in the API (e.g. go1.txt), but was
+				// subsequently removed. These are already
+				// acknowledged by being in the file
+				// "api/except.txt". No need to print them out
+				// here.
+			} else if portRemoved(feature) {
+				// okay.
+			} else if featureSet[featureWithoutContext(feature)] {
+				// okay.
+			} else {
+				fmt.Fprintf(w, "-%s\n", feature)
+				ok = false // broke compatibility
+			}
+		case len(required) == 0 || (len(features) > 0 && required[0] > features[0]):
+			newFeature := take(&features)
+			if optionalSet[newFeature] {
+				// Known added feature to the upcoming release.
+				// Delete it from the map so we can detect any upcoming features
+				// which were never seen.  (so we can clean up the nextFile)
+				delete(optionalSet, newFeature)
+			} else {
+				fmt.Fprintf(w, "+%s\n", newFeature)
+				if !allowAdd {
+					ok = false // we're in lock-down mode for next release
+				}
+			}
+		default:
+			take(&required)
+			take(&features)
+		}
+	}
+
+	// In next file, but not in API.
+	var missing []string
+	for feature := range optionalSet {
+		missing = append(missing, feature)
+	}
+	sort.Strings(missing)
+	for _, feature := range missing {
+		fmt.Fprintf(w, "±%s\n", feature)
+	}
+	return
+}
+
+// aliasReplacer applies type aliases to earlier API files,
+// to avoid misleading negative results.
+// This makes all the references to os.FileInfo in go1.txt
+// be read as if they said fs.FileInfo, since os.FileInfo is now an alias.
+// If there are many of these, we could do a more general solution,
+// but for now the replacer is fine.
+var aliasReplacer = strings.NewReplacer(
+	"os.FileInfo", "fs.FileInfo",
+	"os.FileMode", "fs.FileMode",
+	"os.PathError", "fs.PathError",
+)
+
+func fileFeatures(filename string, needApproval bool) []string {
+	bs, err := os.ReadFile(filename)
+	if err != nil {
+		log.Fatal(err)
+	}
+	s := string(bs)
+
+	// Diagnose common mistakes people make,
+	// since there is no apifmt to format these files.
+	// The missing final newline is important for the
+	// final release step of cat next/*.txt >go1.X.txt.
+	// If the files don't end in full lines, the concatenation goes awry.
+	if strings.Contains(s, "\r") {
+		log.Printf("%s: contains CRLFs", filename)
+		exitCode = 1
+	}
+	if s == "" {
+		log.Printf("%s: empty file", filename)
+		exitCode = 1
+	} else if s[len(s)-1] != '\n' {
+		log.Printf("%s: missing final newline", filename)
+		exitCode = 1
+	}
+	s = aliasReplacer.Replace(s)
+	lines := strings.Split(s, "\n")
+	var nonblank []string
+	for i, line := range lines {
+		line = strings.TrimSpace(line)
+		if line == "" || strings.HasPrefix(line, "#") {
+			continue
+		}
+		if needApproval {
+			feature, approval, ok := strings.Cut(line, "#")
+			if !ok {
+				log.Printf("%s:%d: missing proposal approval\n", filename, i+1)
+				exitCode = 1
+			} else {
+				_, err := strconv.Atoi(approval)
+				if err != nil {
+					log.Printf("%s:%d: malformed proposal approval #%s\n", filename, i+1, approval)
+					exitCode = 1
+				}
+			}
+			line = strings.TrimSpace(feature)
+		} else {
+			if strings.Contains(line, " #") {
+				log.Printf("%s:%d: unexpected approval\n", filename, i+1)
+				exitCode = 1
+			}
+		}
+		nonblank = append(nonblank, line)
+	}
+	return nonblank
+}
+
+var fset = token.NewFileSet()
+
+type Walker struct {
+	context     *build.Context
+	root        string
+	scope       []string
+	current     *apiPackage
+	deprecated  map[token.Pos]bool
+	features    map[string]bool              // set
+	imported    map[string]*apiPackage       // packages already imported
+	stdPackages []string                     // names, omitting "unsafe", internal, and vendored packages
+	importMap   map[string]map[string]string // importer dir -> import path -> canonical path
+	importDir   map[string]string            // canonical import path -> dir
+
+}
+
+func NewWalker(context *build.Context, root string) *Walker {
+	w := &Walker{
+		context:  context,
+		root:     root,
+		features: map[string]bool{},
+		imported: map[string]*apiPackage{"unsafe": &apiPackage{Package: types.Unsafe}},
+	}
+	w.loadImports()
+	return w
+}
+
+func (w *Walker) Features() (fs []string) {
+	for f := range w.features {
+		fs = append(fs, f)
+	}
+	sort.Strings(fs)
+	return
+}
+
+var parsedFileCache = make(map[string]*ast.File)
+
+func (w *Walker) parseFile(dir, file string) (*ast.File, error) {
+	filename := filepath.Join(dir, file)
+	if f := parsedFileCache[filename]; f != nil {
+		return f, nil
+	}
+
+	f, err := parser.ParseFile(fset, filename, nil, parser.ParseComments)
+	if err != nil {
+		return nil, err
+	}
+	parsedFileCache[filename] = f
+
+	return f, nil
+}
+
+// Disable before debugging non-obvious errors from the type-checker.
+const usePkgCache = true
+
+var (
+	pkgCache = map[string]*apiPackage{} // map tagKey to package
+	pkgTags  = map[string][]string{}    // map import dir to list of relevant tags
+)
+
+// tagKey returns the tag-based key to use in the pkgCache.
+// It is a comma-separated string; the first part is dir, the rest tags.
+// The satisfied tags are derived from context but only those that
+// matter (the ones listed in the tags argument plus GOOS and GOARCH) are used.
+// The tags list, which came from go/build's Package.AllTags,
+// is known to be sorted.
+func tagKey(dir string, context *build.Context, tags []string) string {
+	ctags := map[string]bool{
+		context.GOOS:   true,
+		context.GOARCH: true,
+	}
+	if context.CgoEnabled {
+		ctags["cgo"] = true
+	}
+	for _, tag := range context.BuildTags {
+		ctags[tag] = true
+	}
+	// TODO: ReleaseTags (need to load default)
+	key := dir
+
+	// explicit on GOOS and GOARCH as global cache will use "all" cached packages for
+	// an indirect imported package. See https://github.com/golang/go/issues/21181
+	// for more detail.
+	tags = append(tags, context.GOOS, context.GOARCH)
+	sort.Strings(tags)
+
+	for _, tag := range tags {
+		if ctags[tag] {
+			key += "," + tag
+			ctags[tag] = false
+		}
+	}
+	return key
+}
+
+type listImports struct {
+	stdPackages []string                     // names, omitting "unsafe", internal, and vendored packages
+	importDir   map[string]string            // canonical import path → directory
+	importMap   map[string]map[string]string // import path → canonical import path
+}
+
+var listCache sync.Map // map[string]listImports, keyed by contextName
+
+// listSem is a semaphore restricting concurrent invocations of 'go list'. 'go
+// list' has its own internal concurrency, so we use a hard-coded constant (to
+// allow the I/O-intensive phases of 'go list' to overlap) instead of scaling
+// all the way up to GOMAXPROCS.
+var listSem = make(chan semToken, 2)
+
+type semToken struct{}
+
+// loadImports populates w with information about the packages in the standard
+// library and the packages they themselves import in w's build context.
+//
+// The source import path and expanded import path are identical except for vendored packages.
+// For example, on return:
+//
+//	w.importMap["math"] = "math"
+//	w.importDir["math"] = "<goroot>/src/math"
+//
+//	w.importMap["golang.org/x/net/route"] = "vendor/golang.org/x/net/route"
+//	w.importDir["vendor/golang.org/x/net/route"] = "<goroot>/src/vendor/golang.org/x/net/route"
+//
+// Since the set of packages that exist depends on context, the result of
+// loadImports also depends on context. However, to improve test running time
+// the configuration for each environment is cached across runs.
+func (w *Walker) loadImports() {
+	if w.context == nil {
+		return // test-only Walker; does not use the import map
+	}
+
+	name := contextName(w.context)
+
+	imports, ok := listCache.Load(name)
+	if !ok {
+		listSem <- semToken{}
+		defer func() { <-listSem }()
+
+		cmd := exec.Command(goCmd(), "list", "-e", "-deps", "-json", "std")
+		cmd.Env = listEnv(w.context)
+		if w.context.Dir != "" {
+			cmd.Dir = w.context.Dir
+		}
+		out, err := cmd.CombinedOutput()
+		if err != nil {
+			log.Fatalf("loading imports: %v\n%s", err, out)
+		}
+
+		var stdPackages []string
+		importMap := make(map[string]map[string]string)
+		importDir := make(map[string]string)
+		dec := json.NewDecoder(bytes.NewReader(out))
+		for {
+			var pkg struct {
+				ImportPath, Dir string
+				ImportMap       map[string]string
+				Standard        bool
+			}
+			err := dec.Decode(&pkg)
+			if err == io.EOF {
+				break
+			}
+			if err != nil {
+				log.Fatalf("go list: invalid output: %v", err)
+			}
+
+			// - Package "unsafe" contains special signatures requiring
+			//   extra care when printing them - ignore since it is not
+			//   going to change w/o a language change.
+			// - Internal and vendored packages do not contribute to our
+			//   API surface. (If we are running within the "std" module,
+			//   vendored dependencies appear as themselves instead of
+			//   their "vendor/" standard-library copies.)
+			// - 'go list std' does not include commands, which cannot be
+			//   imported anyway.
+			if ip := pkg.ImportPath; pkg.Standard && ip != "unsafe" && !strings.HasPrefix(ip, "vendor/") && !internalPkg.MatchString(ip) {
+				stdPackages = append(stdPackages, ip)
+			}
+			importDir[pkg.ImportPath] = pkg.Dir
+			if len(pkg.ImportMap) > 0 {
+				importMap[pkg.Dir] = make(map[string]string, len(pkg.ImportMap))
+			}
+			for k, v := range pkg.ImportMap {
+				importMap[pkg.Dir][k] = v
+			}
+		}
+
+		sort.Strings(stdPackages)
+		imports = listImports{
+			stdPackages: stdPackages,
+			importMap:   importMap,
+			importDir:   importDir,
+		}
+		imports, _ = listCache.LoadOrStore(name, imports)
+	}
+
+	li := imports.(listImports)
+	w.stdPackages = li.stdPackages
+	w.importDir = li.importDir
+	w.importMap = li.importMap
+}
+
+// listEnv returns the process environment to use when invoking 'go list' for
+// the given context.
+func listEnv(c *build.Context) []string {
+	if c == nil {
+		return os.Environ()
+	}
+
+	environ := append(os.Environ(),
+		"GOOS="+c.GOOS,
+		"GOARCH="+c.GOARCH)
+	if c.CgoEnabled {
+		environ = append(environ, "CGO_ENABLED=1")
+	} else {
+		environ = append(environ, "CGO_ENABLED=0")
+	}
+	return environ
+}
+
+type apiPackage struct {
+	*types.Package
+	Files []*ast.File
+}
+
+// Importing is a sentinel taking the place in Walker.imported
+// for a package that is in the process of being imported.
+var importing apiPackage
+
+// Import implements types.Importer.
+func (w *Walker) Import(name string) (*types.Package, error) {
+	return w.ImportFrom(name, "", 0)
+}
+
+// ImportFrom implements types.ImporterFrom.
+func (w *Walker) ImportFrom(fromPath, fromDir string, mode types.ImportMode) (*types.Package, error) {
+	pkg, err := w.importFrom(fromPath, fromDir, mode)
+	if err != nil {
+		return nil, err
+	}
+	return pkg.Package, nil
+}
+
+func (w *Walker) import_(name string) (*apiPackage, error) {
+	return w.importFrom(name, "", 0)
+}
+
+func (w *Walker) importFrom(fromPath, fromDir string, mode types.ImportMode) (*apiPackage, error) {
+	name := fromPath
+	if canonical, ok := w.importMap[fromDir][fromPath]; ok {
+		name = canonical
+	}
+
+	pkg := w.imported[name]
+	if pkg != nil {
+		if pkg == &importing {
+			log.Fatalf("cycle importing package %q", name)
+		}
+		return pkg, nil
+	}
+	w.imported[name] = &importing
+
+	// Determine package files.
+	dir := w.importDir[name]
+	if dir == "" {
+		dir = filepath.Join(w.root, filepath.FromSlash(name))
+	}
+	if fi, err := os.Stat(dir); err != nil || !fi.IsDir() {
+		log.Panicf("no source in tree for import %q (from import %s in %s): %v", name, fromPath, fromDir, err)
+	}
+
+	context := w.context
+	if context == nil {
+		context = &build.Default
+	}
+
+	// Look in cache.
+	// If we've already done an import with the same set
+	// of relevant tags, reuse the result.
+	var key string
+	if usePkgCache {
+		if tags, ok := pkgTags[dir]; ok {
+			key = tagKey(dir, context, tags)
+			if pkg := pkgCache[key]; pkg != nil {
+				w.imported[name] = pkg
+				return pkg, nil
+			}
+		}
+	}
+
+	info, err := context.ImportDir(dir, 0)
+	if err != nil {
+		if _, nogo := err.(*build.NoGoError); nogo {
+			return nil, err
+		}
+		log.Fatalf("pkg %q, dir %q: ScanDir: %v", name, dir, err)
+	}
+
+	// Save tags list first time we see a directory.
+	if usePkgCache {
+		if _, ok := pkgTags[dir]; !ok {
+			pkgTags[dir] = info.AllTags
+			key = tagKey(dir, context, info.AllTags)
+		}
+	}
+
+	filenames := append(append([]string{}, info.GoFiles...), info.CgoFiles...)
+
+	// Parse package files.
+	var files []*ast.File
+	for _, file := range filenames {
+		f, err := w.parseFile(dir, file)
+		if err != nil {
+			log.Fatalf("error parsing package %s: %s", name, err)
+		}
+		files = append(files, f)
+	}
+
+	// Type-check package files.
+	var sizes types.Sizes
+	if w.context != nil {
+		sizes = types.SizesFor(w.context.Compiler, w.context.GOARCH)
+	}
+	conf := types.Config{
+		IgnoreFuncBodies: true,
+		FakeImportC:      true,
+		Importer:         w,
+		Sizes:            sizes,
+	}
+	tpkg, err := conf.Check(name, fset, files, nil)
+	if err != nil {
+		ctxt := "<no context>"
+		if w.context != nil {
+			ctxt = fmt.Sprintf("%s-%s", w.context.GOOS, w.context.GOARCH)
+		}
+		log.Fatalf("error typechecking package %s: %s (%s)", name, err, ctxt)
+	}
+	pkg = &apiPackage{tpkg, files}
+
+	if usePkgCache {
+		pkgCache[key] = pkg
+	}
+
+	w.imported[name] = pkg
+	return pkg, nil
+}
+
+// pushScope enters a new scope (walking a package, type, node, etc)
+// and returns a function that will leave the scope (with sanity checking
+// for mismatched pushes & pops)
+func (w *Walker) pushScope(name string) (popFunc func()) {
+	w.scope = append(w.scope, name)
+	return func() {
+		if len(w.scope) == 0 {
+			log.Fatalf("attempt to leave scope %q with empty scope list", name)
+		}
+		if w.scope[len(w.scope)-1] != name {
+			log.Fatalf("attempt to leave scope %q, but scope is currently %#v", name, w.scope)
+		}
+		w.scope = w.scope[:len(w.scope)-1]
+	}
+}
+
+func sortedMethodNames(typ *types.Interface) []string {
+	n := typ.NumMethods()
+	list := make([]string, n)
+	for i := range list {
+		list[i] = typ.Method(i).Name()
+	}
+	sort.Strings(list)
+	return list
+}
+
+// sortedEmbeddeds returns constraint types embedded in an
+// interface. It does not include embedded interface types or methods.
+func (w *Walker) sortedEmbeddeds(typ *types.Interface) []string {
+	n := typ.NumEmbeddeds()
+	list := make([]string, 0, n)
+	for i := 0; i < n; i++ {
+		emb := typ.EmbeddedType(i)
+		switch emb := emb.(type) {
+		case *types.Interface:
+			list = append(list, w.sortedEmbeddeds(emb)...)
+		case *types.Union:
+			var buf bytes.Buffer
+			nu := emb.Len()
+			for i := 0; i < nu; i++ {
+				if i > 0 {
+					buf.WriteString(" | ")
+				}
+				term := emb.Term(i)
+				if term.Tilde() {
+					buf.WriteByte('~')
+				}
+				w.writeType(&buf, term.Type())
+			}
+			list = append(list, buf.String())
+		}
+	}
+	sort.Strings(list)
+	return list
+}
+
+func (w *Walker) writeType(buf *bytes.Buffer, typ types.Type) {
+	switch typ := typ.(type) {
+	case *types.Basic:
+		s := typ.Name()
+		switch typ.Kind() {
+		case types.UnsafePointer:
+			s = "unsafe.Pointer"
+		case types.UntypedBool:
+			s = "ideal-bool"
+		case types.UntypedInt:
+			s = "ideal-int"
+		case types.UntypedRune:
+			// "ideal-char" for compatibility with old tool
+			// TODO(gri) change to "ideal-rune"
+			s = "ideal-char"
+		case types.UntypedFloat:
+			s = "ideal-float"
+		case types.UntypedComplex:
+			s = "ideal-complex"
+		case types.UntypedString:
+			s = "ideal-string"
+		case types.UntypedNil:
+			panic("should never see untyped nil type")
+		default:
+			switch s {
+			case "byte":
+				s = "uint8"
+			case "rune":
+				s = "int32"
+			}
+		}
+		buf.WriteString(s)
+
+	case *types.Array:
+		fmt.Fprintf(buf, "[%d]", typ.Len())
+		w.writeType(buf, typ.Elem())
+
+	case *types.Slice:
+		buf.WriteString("[]")
+		w.writeType(buf, typ.Elem())
+
+	case *types.Struct:
+		buf.WriteString("struct")
+
+	case *types.Pointer:
+		buf.WriteByte('*')
+		w.writeType(buf, typ.Elem())
+
+	case *types.Tuple:
+		panic("should never see a tuple type")
+
+	case *types.Signature:
+		buf.WriteString("func")
+		w.writeSignature(buf, typ)
+
+	case *types.Interface:
+		buf.WriteString("interface{")
+		if typ.NumMethods() > 0 || typ.NumEmbeddeds() > 0 {
+			buf.WriteByte(' ')
+		}
+		if typ.NumMethods() > 0 {
+			buf.WriteString(strings.Join(sortedMethodNames(typ), ", "))
+		}
+		if typ.NumEmbeddeds() > 0 {
+			buf.WriteString(strings.Join(w.sortedEmbeddeds(typ), ", "))
+		}
+		if typ.NumMethods() > 0 || typ.NumEmbeddeds() > 0 {
+			buf.WriteByte(' ')
+		}
+		buf.WriteString("}")
+
+	case *types.Map:
+		buf.WriteString("map[")
+		w.writeType(buf, typ.Key())
+		buf.WriteByte(']')
+		w.writeType(buf, typ.Elem())
+
+	case *types.Chan:
+		var s string
+		switch typ.Dir() {
+		case types.SendOnly:
+			s = "chan<- "
+		case types.RecvOnly:
+			s = "<-chan "
+		case types.SendRecv:
+			s = "chan "
+		default:
+			panic("unreachable")
+		}
+		buf.WriteString(s)
+		w.writeType(buf, typ.Elem())
+
+	case *types.Named:
+		obj := typ.Obj()
+		pkg := obj.Pkg()
+		if pkg != nil && pkg != w.current.Package {
+			buf.WriteString(pkg.Name())
+			buf.WriteByte('.')
+		}
+		buf.WriteString(typ.Obj().Name())
+
+	case *types.TypeParam:
+		// Type parameter names may change, so use a placeholder instead.
+		fmt.Fprintf(buf, "$%d", typ.Index())
+
+	default:
+		panic(fmt.Sprintf("unknown type %T", typ))
+	}
+}
+
+func (w *Walker) writeSignature(buf *bytes.Buffer, sig *types.Signature) {
+	if tparams := sig.TypeParams(); tparams != nil {
+		w.writeTypeParams(buf, tparams, true)
+	}
+	w.writeParams(buf, sig.Params(), sig.Variadic())
+	switch res := sig.Results(); res.Len() {
+	case 0:
+		// nothing to do
+	case 1:
+		buf.WriteByte(' ')
+		w.writeType(buf, res.At(0).Type())
+	default:
+		buf.WriteByte(' ')
+		w.writeParams(buf, res, false)
+	}
+}
+
+func (w *Walker) writeTypeParams(buf *bytes.Buffer, tparams *types.TypeParamList, withConstraints bool) {
+	buf.WriteByte('[')
+	c := tparams.Len()
+	for i := 0; i < c; i++ {
+		if i > 0 {
+			buf.WriteString(", ")
+		}
+		tp := tparams.At(i)
+		w.writeType(buf, tp)
+		if withConstraints {
+			buf.WriteByte(' ')
+			w.writeType(buf, tp.Constraint())
+		}
+	}
+	buf.WriteByte(']')
+}
+
+func (w *Walker) writeParams(buf *bytes.Buffer, t *types.Tuple, variadic bool) {
+	buf.WriteByte('(')
+	for i, n := 0, t.Len(); i < n; i++ {
+		if i > 0 {
+			buf.WriteString(", ")
+		}
+		typ := t.At(i).Type()
+		if variadic && i+1 == n {
+			buf.WriteString("...")
+			typ = typ.(*types.Slice).Elem()
+		}
+		w.writeType(buf, typ)
+	}
+	buf.WriteByte(')')
+}
+
+func (w *Walker) typeString(typ types.Type) string {
+	var buf bytes.Buffer
+	w.writeType(&buf, typ)
+	return buf.String()
+}
+
+func (w *Walker) signatureString(sig *types.Signature) string {
+	var buf bytes.Buffer
+	w.writeSignature(&buf, sig)
+	return buf.String()
+}
+
+func (w *Walker) emitObj(obj types.Object) {
+	switch obj := obj.(type) {
+	case *types.Const:
+		if w.isDeprecated(obj) {
+			w.emitf("const %s //deprecated", obj.Name())
+		}
+		w.emitf("const %s %s", obj.Name(), w.typeString(obj.Type()))
+		x := obj.Val()
+		short := x.String()
+		exact := x.ExactString()
+		if short == exact {
+			w.emitf("const %s = %s", obj.Name(), short)
+		} else {
+			w.emitf("const %s = %s  // %s", obj.Name(), short, exact)
+		}
+	case *types.Var:
+		if w.isDeprecated(obj) {
+			w.emitf("var %s //deprecated", obj.Name())
+		}
+		w.emitf("var %s %s", obj.Name(), w.typeString(obj.Type()))
+	case *types.TypeName:
+		w.emitType(obj)
+	case *types.Func:
+		w.emitFunc(obj)
+	default:
+		panic("unknown object: " + obj.String())
+	}
+}
+
+func (w *Walker) emitType(obj *types.TypeName) {
+	name := obj.Name()
+	if w.isDeprecated(obj) {
+		w.emitf("type %s //deprecated", name)
+	}
+	if tparams := obj.Type().(*types.Named).TypeParams(); tparams != nil {
+		var buf bytes.Buffer
+		buf.WriteString(name)
+		w.writeTypeParams(&buf, tparams, true)
+		name = buf.String()
+	}
+	typ := obj.Type()
+	if obj.IsAlias() {
+		w.emitf("type %s = %s", name, w.typeString(typ))
+		return
+	}
+	switch typ := typ.Underlying().(type) {
+	case *types.Struct:
+		w.emitStructType(name, typ)
+	case *types.Interface:
+		w.emitIfaceType(name, typ)
+		return // methods are handled by emitIfaceType
+	default:
+		w.emitf("type %s %s", name, w.typeString(typ.Underlying()))
+	}
+
+	// emit methods with value receiver
+	var methodNames map[string]bool
+	vset := types.NewMethodSet(typ)
+	for i, n := 0, vset.Len(); i < n; i++ {
+		m := vset.At(i)
+		if m.Obj().Exported() {
+			w.emitMethod(m)
+			if methodNames == nil {
+				methodNames = make(map[string]bool)
+			}
+			methodNames[m.Obj().Name()] = true
+		}
+	}
+
+	// emit methods with pointer receiver; exclude
+	// methods that we have emitted already
+	// (the method set of *T includes the methods of T)
+	pset := types.NewMethodSet(types.NewPointer(typ))
+	for i, n := 0, pset.Len(); i < n; i++ {
+		m := pset.At(i)
+		if m.Obj().Exported() && !methodNames[m.Obj().Name()] {
+			w.emitMethod(m)
+		}
+	}
+}
+
+func (w *Walker) emitStructType(name string, typ *types.Struct) {
+	typeStruct := fmt.Sprintf("type %s struct", name)
+	w.emitf(typeStruct)
+	defer w.pushScope(typeStruct)()
+
+	for i := 0; i < typ.NumFields(); i++ {
+		f := typ.Field(i)
+		if !f.Exported() {
+			continue
+		}
+		typ := f.Type()
+		if f.Anonymous() {
+			if w.isDeprecated(f) {
+				w.emitf("embedded %s //deprecated", w.typeString(typ))
+			}
+			w.emitf("embedded %s", w.typeString(typ))
+			continue
+		}
+		if w.isDeprecated(f) {
+			w.emitf("%s //deprecated", f.Name())
+		}
+		w.emitf("%s %s", f.Name(), w.typeString(typ))
+	}
+}
+
+func (w *Walker) emitIfaceType(name string, typ *types.Interface) {
+	pop := w.pushScope("type " + name + " interface")
+
+	var methodNames []string
+	complete := true
+	mset := types.NewMethodSet(typ)
+	for i, n := 0, mset.Len(); i < n; i++ {
+		m := mset.At(i).Obj().(*types.Func)
+		if !m.Exported() {
+			complete = false
+			continue
+		}
+		methodNames = append(methodNames, m.Name())
+		if w.isDeprecated(m) {
+			w.emitf("%s //deprecated", m.Name())
+		}
+		w.emitf("%s%s", m.Name(), w.signatureString(m.Type().(*types.Signature)))
+	}
+
+	if !complete {
+		// The method set has unexported methods, so all the
+		// implementations are provided by the same package,
+		// so the method set can be extended. Instead of recording
+		// the full set of names (below), record only that there were
+		// unexported methods. (If the interface shrinks, we will notice
+		// because a method signature emitted during the last loop
+		// will disappear.)
+		w.emitf("unexported methods")
+	}
+
+	pop()
+
+	if !complete {
+		return
+	}
+
+	if len(methodNames) == 0 {
+		w.emitf("type %s interface {}", name)
+		return
+	}
+
+	sort.Strings(methodNames)
+	w.emitf("type %s interface { %s }", name, strings.Join(methodNames, ", "))
+}
+
+func (w *Walker) emitFunc(f *types.Func) {
+	sig := f.Type().(*types.Signature)
+	if sig.Recv() != nil {
+		panic("method considered a regular function: " + f.String())
+	}
+	if w.isDeprecated(f) {
+		w.emitf("func %s //deprecated", f.Name())
+	}
+	w.emitf("func %s%s", f.Name(), w.signatureString(sig))
+}
+
+func (w *Walker) emitMethod(m *types.Selection) {
+	sig := m.Type().(*types.Signature)
+	recv := sig.Recv().Type()
+	// report exported methods with unexported receiver base type
+	if true {
+		base := recv
+		if p, _ := recv.(*types.Pointer); p != nil {
+			base = p.Elem()
+		}
+		if obj := base.(*types.Named).Obj(); !obj.Exported() {
+			log.Fatalf("exported method with unexported receiver base type: %s", m)
+		}
+	}
+	tps := ""
+	if rtp := sig.RecvTypeParams(); rtp != nil {
+		var buf bytes.Buffer
+		w.writeTypeParams(&buf, rtp, false)
+		tps = buf.String()
+	}
+	if w.isDeprecated(m.Obj()) {
+		w.emitf("method (%s%s) %s //deprecated", w.typeString(recv), tps, m.Obj().Name())
+	}
+	w.emitf("method (%s%s) %s%s", w.typeString(recv), tps, m.Obj().Name(), w.signatureString(sig))
+}
+
+func (w *Walker) emitf(format string, args ...any) {
+	f := strings.Join(w.scope, ", ") + ", " + fmt.Sprintf(format, args...)
+	if strings.Contains(f, "\n") {
+		panic("feature contains newlines: " + f)
+	}
+
+	if _, dup := w.features[f]; dup {
+		panic("duplicate feature inserted: " + f)
+	}
+	w.features[f] = true
+
+	if verbose {
+		log.Printf("feature: %s", f)
+	}
+}
+
+func needApproval(filename string) bool {
+	name := filepath.Base(filename)
+	if name == "go1.txt" {
+		return false
+	}
+	minor := strings.TrimSuffix(strings.TrimPrefix(name, "go1."), ".txt")
+	n, err := strconv.Atoi(minor)
+	if err != nil {
+		log.Fatalf("unexpected api file: %v", name)
+	}
+	return n >= 19 // started tracking approvals in Go 1.19
+}
+
+func (w *Walker) collectDeprecated() {
+	isDeprecated := func(doc *ast.CommentGroup) bool {
+		if doc != nil {
+			for _, c := range doc.List {
+				if strings.HasPrefix(c.Text, "// Deprecated:") {
+					return true
+				}
+			}
+		}
+		return false
+	}
+
+	w.deprecated = make(map[token.Pos]bool)
+	mark := func(id *ast.Ident) {
+		if id != nil {
+			w.deprecated[id.Pos()] = true
+		}
+	}
+	for _, file := range w.current.Files {
+		ast.Inspect(file, func(n ast.Node) bool {
+			switch n := n.(type) {
+			case *ast.File:
+				if isDeprecated(n.Doc) {
+					mark(n.Name)
+				}
+				return true
+			case *ast.GenDecl:
+				if isDeprecated(n.Doc) {
+					for _, spec := range n.Specs {
+						switch spec := spec.(type) {
+						case *ast.ValueSpec:
+							for _, id := range spec.Names {
+								mark(id)
+							}
+						case *ast.TypeSpec:
+							mark(spec.Name)
+						}
+					}
+				}
+				return true // look at specs
+			case *ast.FuncDecl:
+				if isDeprecated(n.Doc) {
+					mark(n.Name)
+				}
+				return false
+			case *ast.TypeSpec:
+				if isDeprecated(n.Doc) {
+					mark(n.Name)
+				}
+				return true // recurse into struct or interface type
+			case *ast.StructType:
+				return true // recurse into fields
+			case *ast.InterfaceType:
+				return true // recurse into methods
+			case *ast.FieldList:
+				return true // recurse into fields
+			case *ast.ValueSpec:
+				if isDeprecated(n.Doc) {
+					for _, id := range n.Names {
+						mark(id)
+					}
+				}
+				return false
+			case *ast.Field:
+				if isDeprecated(n.Doc) {
+					for _, id := range n.Names {
+						mark(id)
+					}
+					if len(n.Names) == 0 {
+						// embedded field T or *T?
+						typ := n.Type
+						if ptr, ok := typ.(*ast.StarExpr); ok {
+							typ = ptr.X
+						}
+						if id, ok := typ.(*ast.Ident); ok {
+							mark(id)
+						}
+					}
+				}
+				return false
+			default:
+				return false
+			}
+		})
+	}
+}
+
+func (w *Walker) isDeprecated(obj types.Object) bool {
+	return w.deprecated[obj.Pos()]
+}
diff --git a/src/cmd/api/api_test.go b/src/cmd/api/api_test.go
new file mode 100644
index 0000000..5f9aa6d
--- /dev/null
+++ b/src/cmd/api/api_test.go
@@ -0,0 +1,265 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package api
+
+import (
+	"flag"
+	"fmt"
+	"go/build"
+	"internal/testenv"
+	"os"
+	"path/filepath"
+	"sort"
+	"strings"
+	"sync"
+	"testing"
+)
+
+var flagCheck = flag.Bool("check", false, "run API checks")
+
+func TestMain(m *testing.M) {
+	if !testenv.HasExec() {
+		os.Stdout.WriteString("skipping test: platform cannot exec")
+		os.Exit(0)
+	}
+	if !testenv.HasGoBuild() {
+		os.Stdout.WriteString("skipping test: platform cannot 'go build' to import std packages")
+		os.Exit(0)
+	}
+
+	flag.Parse()
+	for _, c := range contexts {
+		c.Compiler = build.Default.Compiler
+	}
+	build.Default.GOROOT = testenv.GOROOT(nil)
+
+	// Warm up the import cache in parallel.
+	var wg sync.WaitGroup
+	for _, context := range contexts {
+		context := context
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+			_ = NewWalker(context, filepath.Join(testenv.GOROOT(nil), "src"))
+		}()
+	}
+	wg.Wait()
+
+	os.Exit(m.Run())
+}
+
+var (
+	updateGolden = flag.Bool("updategolden", false, "update golden files")
+)
+
+func TestGolden(t *testing.T) {
+	if *flagCheck {
+		// slow, not worth repeating in -check
+		t.Skip("skipping with -check set")
+	}
+	td, err := os.Open("testdata/src/pkg")
+	if err != nil {
+		t.Fatal(err)
+	}
+	fis, err := td.Readdir(0)
+	if err != nil {
+		t.Fatal(err)
+	}
+	for _, fi := range fis {
+		if !fi.IsDir() {
+			continue
+		}
+
+		// TODO(gri) remove extra pkg directory eventually
+		goldenFile := filepath.Join("testdata", "src", "pkg", fi.Name(), "golden.txt")
+		w := NewWalker(nil, "testdata/src/pkg")
+		pkg, _ := w.import_(fi.Name())
+		w.export(pkg)
+
+		if *updateGolden {
+			os.Remove(goldenFile)
+			f, err := os.Create(goldenFile)
+			if err != nil {
+				t.Fatal(err)
+			}
+			for _, feat := range w.Features() {
+				fmt.Fprintf(f, "%s\n", feat)
+			}
+			f.Close()
+		}
+
+		bs, err := os.ReadFile(goldenFile)
+		if err != nil {
+			t.Fatalf("opening golden.txt for package %q: %v", fi.Name(), err)
+		}
+		wanted := strings.Split(string(bs), "\n")
+		sort.Strings(wanted)
+		for _, feature := range wanted {
+			if feature == "" {
+				continue
+			}
+			_, ok := w.features[feature]
+			if !ok {
+				t.Errorf("package %s: missing feature %q", fi.Name(), feature)
+			}
+			delete(w.features, feature)
+		}
+
+		for _, feature := range w.Features() {
+			t.Errorf("package %s: extra feature not in golden file: %q", fi.Name(), feature)
+		}
+	}
+}
+
+func TestCompareAPI(t *testing.T) {
+	tests := []struct {
+		name                                    string
+		features, required, optional, exception []string
+		ok                                      bool   // want
+		out                                     string // want
+	}{
+		{
+			name:     "feature added",
+			features: []string{"A", "B", "C", "D", "E", "F"},
+			required: []string{"B", "D"},
+			ok:       true,
+			out:      "+A\n+C\n+E\n+F\n",
+		},
+		{
+			name:     "feature removed",
+			features: []string{"C", "A"},
+			required: []string{"A", "B", "C"},
+			ok:       false,
+			out:      "-B\n",
+		},
+		{
+			name:     "feature added then removed",
+			features: []string{"A", "C"},
+			optional: []string{"B"},
+			required: []string{"A", "C"},
+			ok:       true,
+			out:      "±B\n",
+		},
+		{
+			name:      "exception removal",
+			required:  []string{"A", "B", "C"},
+			features:  []string{"A", "C"},
+			exception: []string{"B"},
+			ok:        true,
+			out:       "",
+		},
+		{
+			// https://golang.org/issue/4303
+			name: "contexts reconverging",
+			required: []string{
+				"A",
+				"pkg syscall (darwin-amd64), type RawSockaddrInet6 struct",
+			},
+			features: []string{
+				"A",
+				"pkg syscall, type RawSockaddrInet6 struct",
+			},
+			ok:  true,
+			out: "+pkg syscall, type RawSockaddrInet6 struct\n",
+		},
+	}
+	for _, tt := range tests {
+		buf := new(strings.Builder)
+		gotok := compareAPI(buf, tt.features, tt.required, tt.optional, tt.exception, true)
+		if gotok != tt.ok {
+			t.Errorf("%s: ok = %v; want %v", tt.name, gotok, tt.ok)
+		}
+		if got := buf.String(); got != tt.out {
+			t.Errorf("%s: output differs\nGOT:\n%s\nWANT:\n%s", tt.name, got, tt.out)
+		}
+	}
+}
+
+func TestSkipInternal(t *testing.T) {
+	tests := []struct {
+		pkg  string
+		want bool
+	}{
+		{"net/http", true},
+		{"net/http/internal-foo", true},
+		{"net/http/internal", false},
+		{"net/http/internal/bar", false},
+		{"internal/foo", false},
+		{"internal", false},
+	}
+	for _, tt := range tests {
+		got := !internalPkg.MatchString(tt.pkg)
+		if got != tt.want {
+			t.Errorf("%s is internal = %v; want %v", tt.pkg, got, tt.want)
+		}
+	}
+}
+
+func BenchmarkAll(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		for _, context := range contexts {
+			w := NewWalker(context, filepath.Join(testenv.GOROOT(b), "src"))
+			for _, name := range w.stdPackages {
+				pkg, _ := w.import_(name)
+				w.export(pkg)
+			}
+			w.Features()
+		}
+	}
+}
+
+func TestIssue21181(t *testing.T) {
+	if *flagCheck {
+		// slow, not worth repeating in -check
+		t.Skip("skipping with -check set")
+	}
+	for _, context := range contexts {
+		w := NewWalker(context, "testdata/src/issue21181")
+		pkg, err := w.import_("p")
+		if err != nil {
+			t.Fatalf("%s: (%s-%s) %s %v", err, context.GOOS, context.GOARCH,
+				pkg.Name(), w.imported)
+		}
+		w.export(pkg)
+	}
+}
+
+func TestIssue29837(t *testing.T) {
+	if *flagCheck {
+		// slow, not worth repeating in -check
+		t.Skip("skipping with -check set")
+	}
+	for _, context := range contexts {
+		w := NewWalker(context, "testdata/src/issue29837")
+		_, err := w.ImportFrom("p", "", 0)
+		if _, nogo := err.(*build.NoGoError); !nogo {
+			t.Errorf("expected *build.NoGoError, got %T", err)
+		}
+	}
+}
+
+func TestIssue41358(t *testing.T) {
+	if *flagCheck {
+		// slow, not worth repeating in -check
+		t.Skip("skipping with -check set")
+	}
+	context := new(build.Context)
+	*context = build.Default
+	context.Dir = filepath.Join(testenv.GOROOT(t), "src")
+
+	w := NewWalker(context, context.Dir)
+	for _, pkg := range w.stdPackages {
+		if strings.HasPrefix(pkg, "vendor/") || strings.HasPrefix(pkg, "golang.org/x/") {
+			t.Fatalf("stdPackages contains unexpected package %s", pkg)
+		}
+	}
+}
+
+func TestCheck(t *testing.T) {
+	if !*flagCheck {
+		t.Skip("-check not specified")
+	}
+	Check(t)
+}
diff --git a/src/cmd/api/boring_test.go b/src/cmd/api/boring_test.go
new file mode 100644
index 0000000..a9ec6e6
--- /dev/null
+++ b/src/cmd/api/boring_test.go
@@ -0,0 +1,17 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build boringcrypto
+
+package api
+
+import (
+	"fmt"
+	"os"
+)
+
+func init() {
+	fmt.Printf("SKIP with boringcrypto enabled\n")
+	os.Exit(0)
+}
diff --git a/src/cmd/api/goapi.go b/src/cmd/api/goapi.go
deleted file mode 100644
index e6bf62d..0000000
--- a/src/cmd/api/goapi.go
+++ /dev/null
@@ -1,1123 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Api computes the exported API of a set of Go packages.
-package main
-
-import (
-	"bufio"
-	"bytes"
-	"encoding/json"
-	"flag"
-	"fmt"
-	"go/ast"
-	"go/build"
-	"go/parser"
-	"go/token"
-	"go/types"
-	"io"
-	"log"
-	"os"
-	"os/exec"
-	"path/filepath"
-	"regexp"
-	"runtime"
-	"sort"
-	"strconv"
-	"strings"
-	"sync"
-)
-
-func goCmd() string {
-	var exeSuffix string
-	if runtime.GOOS == "windows" {
-		exeSuffix = ".exe"
-	}
-	if goroot := build.Default.GOROOT; goroot != "" {
-		path := filepath.Join(goroot, "bin", "go"+exeSuffix)
-		if _, err := os.Stat(path); err == nil {
-			return path
-		}
-	}
-	return "go"
-}
-
-// Flags
-var (
-	checkFiles      = flag.String("c", "", "optional comma-separated filename(s) to check API against")
-	requireApproval = flag.String("approval", "", "require approvals in comma-separated list of `files`")
-	allowNew        = flag.Bool("allow_new", true, "allow API additions")
-	exceptFile      = flag.String("except", "", "optional filename of packages that are allowed to change without triggering a failure in the tool")
-	nextFiles       = flag.String("next", "", "comma-separated list of `files` for upcoming API features for the next release. These files can be lazily maintained. They only affects the delta warnings from the -c file printed on success.")
-	verbose         = flag.Bool("v", false, "verbose debugging")
-	forceCtx        = flag.String("contexts", "", "optional comma-separated list of <goos>-<goarch>[-cgo] to override default contexts.")
-)
-
-// contexts are the default contexts which are scanned, unless
-// overridden by the -contexts flag.
-var contexts = []*build.Context{
-	{GOOS: "linux", GOARCH: "386", CgoEnabled: true},
-	{GOOS: "linux", GOARCH: "386"},
-	{GOOS: "linux", GOARCH: "amd64", CgoEnabled: true},
-	{GOOS: "linux", GOARCH: "amd64"},
-	{GOOS: "linux", GOARCH: "arm", CgoEnabled: true},
-	{GOOS: "linux", GOARCH: "arm"},
-	{GOOS: "darwin", GOARCH: "amd64", CgoEnabled: true},
-	{GOOS: "darwin", GOARCH: "amd64"},
-	{GOOS: "windows", GOARCH: "amd64"},
-	{GOOS: "windows", GOARCH: "386"},
-	{GOOS: "freebsd", GOARCH: "386", CgoEnabled: true},
-	{GOOS: "freebsd", GOARCH: "386"},
-	{GOOS: "freebsd", GOARCH: "amd64", CgoEnabled: true},
-	{GOOS: "freebsd", GOARCH: "amd64"},
-	{GOOS: "freebsd", GOARCH: "arm", CgoEnabled: true},
-	{GOOS: "freebsd", GOARCH: "arm"},
-	{GOOS: "netbsd", GOARCH: "386", CgoEnabled: true},
-	{GOOS: "netbsd", GOARCH: "386"},
-	{GOOS: "netbsd", GOARCH: "amd64", CgoEnabled: true},
-	{GOOS: "netbsd", GOARCH: "amd64"},
-	{GOOS: "netbsd", GOARCH: "arm", CgoEnabled: true},
-	{GOOS: "netbsd", GOARCH: "arm"},
-	{GOOS: "netbsd", GOARCH: "arm64", CgoEnabled: true},
-	{GOOS: "netbsd", GOARCH: "arm64"},
-	{GOOS: "openbsd", GOARCH: "386", CgoEnabled: true},
-	{GOOS: "openbsd", GOARCH: "386"},
-	{GOOS: "openbsd", GOARCH: "amd64", CgoEnabled: true},
-	{GOOS: "openbsd", GOARCH: "amd64"},
-}
-
-func contextName(c *build.Context) string {
-	s := c.GOOS + "-" + c.GOARCH
-	if c.CgoEnabled {
-		s += "-cgo"
-	}
-	if c.Dir != "" {
-		s += fmt.Sprintf(" [%s]", c.Dir)
-	}
-	return s
-}
-
-func parseContext(c string) *build.Context {
-	parts := strings.Split(c, "-")
-	if len(parts) < 2 {
-		log.Fatalf("bad context: %q", c)
-	}
-	bc := &build.Context{
-		GOOS:   parts[0],
-		GOARCH: parts[1],
-	}
-	if len(parts) == 3 {
-		if parts[2] == "cgo" {
-			bc.CgoEnabled = true
-		} else {
-			log.Fatalf("bad context: %q", c)
-		}
-	}
-	return bc
-}
-
-func setContexts() {
-	contexts = []*build.Context{}
-	for _, c := range strings.Split(*forceCtx, ",") {
-		contexts = append(contexts, parseContext(c))
-	}
-}
-
-var internalPkg = regexp.MustCompile(`(^|/)internal($|/)`)
-
-func main() {
-	flag.Parse()
-
-	if build.Default.GOROOT == "" {
-		log.Fatalf("GOROOT not found. (If binary was built with -trimpath, $GOROOT must be set.)")
-	}
-
-	if !strings.Contains(runtime.Version(), "weekly") && !strings.Contains(runtime.Version(), "devel") {
-		if *nextFiles != "" {
-			fmt.Printf("Go version is %q, ignoring -next %s\n", runtime.Version(), *nextFiles)
-			*nextFiles = ""
-		}
-	}
-
-	if *forceCtx != "" {
-		setContexts()
-	}
-	for _, c := range contexts {
-		c.Compiler = build.Default.Compiler
-	}
-
-	walkers := make([]*Walker, len(contexts))
-	var wg sync.WaitGroup
-	for i, context := range contexts {
-		i, context := i, context
-		wg.Add(1)
-		go func() {
-			defer wg.Done()
-			walkers[i] = NewWalker(context, filepath.Join(build.Default.GOROOT, "src"))
-		}()
-	}
-	wg.Wait()
-
-	var featureCtx = make(map[string]map[string]bool) // feature -> context name -> true
-	for _, w := range walkers {
-		pkgNames := w.stdPackages
-		if flag.NArg() > 0 {
-			pkgNames = flag.Args()
-		}
-
-		for _, name := range pkgNames {
-			pkg, err := w.Import(name)
-			if _, nogo := err.(*build.NoGoError); nogo {
-				continue
-			}
-			if err != nil {
-				log.Fatalf("Import(%q): %v", name, err)
-			}
-			w.export(pkg)
-		}
-
-		ctxName := contextName(w.context)
-		for _, f := range w.Features() {
-			if featureCtx[f] == nil {
-				featureCtx[f] = make(map[string]bool)
-			}
-			featureCtx[f][ctxName] = true
-		}
-	}
-
-	var features []string
-	for f, cmap := range featureCtx {
-		if len(cmap) == len(contexts) {
-			features = append(features, f)
-			continue
-		}
-		comma := strings.Index(f, ",")
-		for cname := range cmap {
-			f2 := fmt.Sprintf("%s (%s)%s", f[:comma], cname, f[comma:])
-			features = append(features, f2)
-		}
-	}
-
-	fail := false
-	defer func() {
-		if fail {
-			os.Exit(1)
-		}
-	}()
-
-	bw := bufio.NewWriter(os.Stdout)
-	defer bw.Flush()
-
-	if *checkFiles == "" {
-		sort.Strings(features)
-		for _, f := range features {
-			fmt.Fprintln(bw, f)
-		}
-		return
-	}
-
-	var required []string
-	for _, file := range strings.Split(*checkFiles, ",") {
-		required = append(required, fileFeatures(file)...)
-	}
-	var optional []string
-	if *nextFiles != "" {
-		for _, file := range strings.Split(*nextFiles, ",") {
-			optional = append(optional, fileFeatures(file)...)
-		}
-	}
-	exception := fileFeatures(*exceptFile)
-	fail = !compareAPI(bw, features, required, optional, exception, *allowNew)
-}
-
-// export emits the exported package features.
-func (w *Walker) export(pkg *types.Package) {
-	if *verbose {
-		log.Println(pkg)
-	}
-	pop := w.pushScope("pkg " + pkg.Path())
-	w.current = pkg
-	scope := pkg.Scope()
-	for _, name := range scope.Names() {
-		if token.IsExported(name) {
-			w.emitObj(scope.Lookup(name))
-		}
-	}
-	pop()
-}
-
-func set(items []string) map[string]bool {
-	s := make(map[string]bool)
-	for _, v := range items {
-		s[v] = true
-	}
-	return s
-}
-
-var spaceParensRx = regexp.MustCompile(` \(\S+?\)`)
-
-func featureWithoutContext(f string) string {
-	if !strings.Contains(f, "(") {
-		return f
-	}
-	return spaceParensRx.ReplaceAllString(f, "")
-}
-
-// portRemoved reports whether the given port-specific API feature is
-// okay to no longer exist because its port was removed.
-func portRemoved(feature string) bool {
-	return strings.Contains(feature, "(darwin-386)") ||
-		strings.Contains(feature, "(darwin-386-cgo)")
-}
-
-func compareAPI(w io.Writer, features, required, optional, exception []string, allowAdd bool) (ok bool) {
-	ok = true
-
-	optionalSet := set(optional)
-	exceptionSet := set(exception)
-	featureSet := set(features)
-
-	sort.Strings(features)
-	sort.Strings(required)
-
-	take := func(sl *[]string) string {
-		s := (*sl)[0]
-		*sl = (*sl)[1:]
-		return s
-	}
-
-	for len(required) > 0 || len(features) > 0 {
-		switch {
-		case len(features) == 0 || (len(required) > 0 && required[0] < features[0]):
-			feature := take(&required)
-			if exceptionSet[feature] {
-				// An "unfortunate" case: the feature was once
-				// included in the API (e.g. go1.txt), but was
-				// subsequently removed. These are already
-				// acknowledged by being in the file
-				// "api/except.txt". No need to print them out
-				// here.
-			} else if portRemoved(feature) {
-				// okay.
-			} else if featureSet[featureWithoutContext(feature)] {
-				// okay.
-			} else {
-				fmt.Fprintf(w, "-%s\n", feature)
-				ok = false // broke compatibility
-			}
-		case len(required) == 0 || (len(features) > 0 && required[0] > features[0]):
-			newFeature := take(&features)
-			if optionalSet[newFeature] {
-				// Known added feature to the upcoming release.
-				// Delete it from the map so we can detect any upcoming features
-				// which were never seen.  (so we can clean up the nextFile)
-				delete(optionalSet, newFeature)
-			} else {
-				fmt.Fprintf(w, "+%s\n", newFeature)
-				if !allowAdd {
-					ok = false // we're in lock-down mode for next release
-				}
-			}
-		default:
-			take(&required)
-			take(&features)
-		}
-	}
-
-	// In next file, but not in API.
-	var missing []string
-	for feature := range optionalSet {
-		missing = append(missing, feature)
-	}
-	sort.Strings(missing)
-	for _, feature := range missing {
-		fmt.Fprintf(w, "±%s\n", feature)
-	}
-	return
-}
-
-// aliasReplacer applies type aliases to earlier API files,
-// to avoid misleading negative results.
-// This makes all the references to os.FileInfo in go1.txt
-// be read as if they said fs.FileInfo, since os.FileInfo is now an alias.
-// If there are many of these, we could do a more general solution,
-// but for now the replacer is fine.
-var aliasReplacer = strings.NewReplacer(
-	"os.FileInfo", "fs.FileInfo",
-	"os.FileMode", "fs.FileMode",
-	"os.PathError", "fs.PathError",
-)
-
-func fileFeatures(filename string) []string {
-	if filename == "" {
-		return nil
-	}
-	needApproval := false
-	for _, name := range strings.Split(*requireApproval, ",") {
-		if filename == name {
-			needApproval = true
-			break
-		}
-	}
-	bs, err := os.ReadFile(filename)
-	if err != nil {
-		log.Fatalf("Error reading file %s: %v", filename, err)
-	}
-	s := string(bs)
-	s = aliasReplacer.Replace(s)
-	lines := strings.Split(s, "\n")
-	var nonblank []string
-	for i, line := range lines {
-		line = strings.TrimSpace(line)
-		if line == "" || strings.HasPrefix(line, "#") {
-			continue
-		}
-		if needApproval {
-			feature, approval, ok := strings.Cut(line, "#")
-			if !ok {
-				log.Fatalf("%s:%d: missing proposal approval\n", filename, i+1)
-			}
-			_, err := strconv.Atoi(approval)
-			if err != nil {
-				log.Fatalf("%s:%d: malformed proposal approval #%s\n", filename, i+1, approval)
-			}
-			line = strings.TrimSpace(feature)
-		}
-		nonblank = append(nonblank, line)
-	}
-	return nonblank
-}
-
-var fset = token.NewFileSet()
-
-type Walker struct {
-	context     *build.Context
-	root        string
-	scope       []string
-	current     *types.Package
-	features    map[string]bool              // set
-	imported    map[string]*types.Package    // packages already imported
-	stdPackages []string                     // names, omitting "unsafe", internal, and vendored packages
-	importMap   map[string]map[string]string // importer dir -> import path -> canonical path
-	importDir   map[string]string            // canonical import path -> dir
-
-}
-
-func NewWalker(context *build.Context, root string) *Walker {
-	w := &Walker{
-		context:  context,
-		root:     root,
-		features: map[string]bool{},
-		imported: map[string]*types.Package{"unsafe": types.Unsafe},
-	}
-	w.loadImports()
-	return w
-}
-
-func (w *Walker) Features() (fs []string) {
-	for f := range w.features {
-		fs = append(fs, f)
-	}
-	sort.Strings(fs)
-	return
-}
-
-var parsedFileCache = make(map[string]*ast.File)
-
-func (w *Walker) parseFile(dir, file string) (*ast.File, error) {
-	filename := filepath.Join(dir, file)
-	if f := parsedFileCache[filename]; f != nil {
-		return f, nil
-	}
-
-	f, err := parser.ParseFile(fset, filename, nil, 0)
-	if err != nil {
-		return nil, err
-	}
-	parsedFileCache[filename] = f
-
-	return f, nil
-}
-
-// Disable before debugging non-obvious errors from the type-checker.
-const usePkgCache = true
-
-var (
-	pkgCache = map[string]*types.Package{} // map tagKey to package
-	pkgTags  = map[string][]string{}       // map import dir to list of relevant tags
-)
-
-// tagKey returns the tag-based key to use in the pkgCache.
-// It is a comma-separated string; the first part is dir, the rest tags.
-// The satisfied tags are derived from context but only those that
-// matter (the ones listed in the tags argument plus GOOS and GOARCH) are used.
-// The tags list, which came from go/build's Package.AllTags,
-// is known to be sorted.
-func tagKey(dir string, context *build.Context, tags []string) string {
-	ctags := map[string]bool{
-		context.GOOS:   true,
-		context.GOARCH: true,
-	}
-	if context.CgoEnabled {
-		ctags["cgo"] = true
-	}
-	for _, tag := range context.BuildTags {
-		ctags[tag] = true
-	}
-	// TODO: ReleaseTags (need to load default)
-	key := dir
-
-	// explicit on GOOS and GOARCH as global cache will use "all" cached packages for
-	// an indirect imported package. See https://github.com/golang/go/issues/21181
-	// for more detail.
-	tags = append(tags, context.GOOS, context.GOARCH)
-	sort.Strings(tags)
-
-	for _, tag := range tags {
-		if ctags[tag] {
-			key += "," + tag
-			ctags[tag] = false
-		}
-	}
-	return key
-}
-
-type listImports struct {
-	stdPackages []string                     // names, omitting "unsafe", internal, and vendored packages
-	importDir   map[string]string            // canonical import path → directory
-	importMap   map[string]map[string]string // import path → canonical import path
-}
-
-var listCache sync.Map // map[string]listImports, keyed by contextName
-
-// listSem is a semaphore restricting concurrent invocations of 'go list'. 'go
-// list' has its own internal concurrency, so we use a hard-coded constant (to
-// allow the I/O-intensive phases of 'go list' to overlap) instead of scaling
-// all the way up to GOMAXPROCS.
-var listSem = make(chan semToken, 2)
-
-type semToken struct{}
-
-// loadImports populates w with information about the packages in the standard
-// library and the packages they themselves import in w's build context.
-//
-// The source import path and expanded import path are identical except for vendored packages.
-// For example, on return:
-//
-//	w.importMap["math"] = "math"
-//	w.importDir["math"] = "<goroot>/src/math"
-//
-//	w.importMap["golang.org/x/net/route"] = "vendor/golang.org/x/net/route"
-//	w.importDir["vendor/golang.org/x/net/route"] = "<goroot>/src/vendor/golang.org/x/net/route"
-//
-// Since the set of packages that exist depends on context, the result of
-// loadImports also depends on context. However, to improve test running time
-// the configuration for each environment is cached across runs.
-func (w *Walker) loadImports() {
-	if w.context == nil {
-		return // test-only Walker; does not use the import map
-	}
-
-	name := contextName(w.context)
-
-	imports, ok := listCache.Load(name)
-	if !ok {
-		listSem <- semToken{}
-		defer func() { <-listSem }()
-
-		cmd := exec.Command(goCmd(), "list", "-e", "-deps", "-json", "std")
-		cmd.Env = listEnv(w.context)
-		if w.context.Dir != "" {
-			cmd.Dir = w.context.Dir
-		}
-		out, err := cmd.CombinedOutput()
-		if err != nil {
-			log.Fatalf("loading imports: %v\n%s", err, out)
-		}
-
-		var stdPackages []string
-		importMap := make(map[string]map[string]string)
-		importDir := make(map[string]string)
-		dec := json.NewDecoder(bytes.NewReader(out))
-		for {
-			var pkg struct {
-				ImportPath, Dir string
-				ImportMap       map[string]string
-				Standard        bool
-			}
-			err := dec.Decode(&pkg)
-			if err == io.EOF {
-				break
-			}
-			if err != nil {
-				log.Fatalf("go list: invalid output: %v", err)
-			}
-
-			// - Package "unsafe" contains special signatures requiring
-			//   extra care when printing them - ignore since it is not
-			//   going to change w/o a language change.
-			// - Internal and vendored packages do not contribute to our
-			//   API surface. (If we are running within the "std" module,
-			//   vendored dependencies appear as themselves instead of
-			//   their "vendor/" standard-library copies.)
-			// - 'go list std' does not include commands, which cannot be
-			//   imported anyway.
-			if ip := pkg.ImportPath; pkg.Standard && ip != "unsafe" && !strings.HasPrefix(ip, "vendor/") && !internalPkg.MatchString(ip) {
-				stdPackages = append(stdPackages, ip)
-			}
-			importDir[pkg.ImportPath] = pkg.Dir
-			if len(pkg.ImportMap) > 0 {
-				importMap[pkg.Dir] = make(map[string]string, len(pkg.ImportMap))
-			}
-			for k, v := range pkg.ImportMap {
-				importMap[pkg.Dir][k] = v
-			}
-		}
-
-		sort.Strings(stdPackages)
-		imports = listImports{
-			stdPackages: stdPackages,
-			importMap:   importMap,
-			importDir:   importDir,
-		}
-		imports, _ = listCache.LoadOrStore(name, imports)
-	}
-
-	li := imports.(listImports)
-	w.stdPackages = li.stdPackages
-	w.importDir = li.importDir
-	w.importMap = li.importMap
-}
-
-// listEnv returns the process environment to use when invoking 'go list' for
-// the given context.
-func listEnv(c *build.Context) []string {
-	if c == nil {
-		return os.Environ()
-	}
-
-	environ := append(os.Environ(),
-		"GOOS="+c.GOOS,
-		"GOARCH="+c.GOARCH)
-	if c.CgoEnabled {
-		environ = append(environ, "CGO_ENABLED=1")
-	} else {
-		environ = append(environ, "CGO_ENABLED=0")
-	}
-	return environ
-}
-
-// Importing is a sentinel taking the place in Walker.imported
-// for a package that is in the process of being imported.
-var importing types.Package
-
-func (w *Walker) Import(name string) (*types.Package, error) {
-	return w.ImportFrom(name, "", 0)
-}
-
-func (w *Walker) ImportFrom(fromPath, fromDir string, mode types.ImportMode) (*types.Package, error) {
-	name := fromPath
-	if canonical, ok := w.importMap[fromDir][fromPath]; ok {
-		name = canonical
-	}
-
-	pkg := w.imported[name]
-	if pkg != nil {
-		if pkg == &importing {
-			log.Fatalf("cycle importing package %q", name)
-		}
-		return pkg, nil
-	}
-	w.imported[name] = &importing
-
-	// Determine package files.
-	dir := w.importDir[name]
-	if dir == "" {
-		dir = filepath.Join(w.root, filepath.FromSlash(name))
-	}
-	if fi, err := os.Stat(dir); err != nil || !fi.IsDir() {
-		log.Panicf("no source in tree for import %q (from import %s in %s): %v", name, fromPath, fromDir, err)
-	}
-
-	context := w.context
-	if context == nil {
-		context = &build.Default
-	}
-
-	// Look in cache.
-	// If we've already done an import with the same set
-	// of relevant tags, reuse the result.
-	var key string
-	if usePkgCache {
-		if tags, ok := pkgTags[dir]; ok {
-			key = tagKey(dir, context, tags)
-			if pkg := pkgCache[key]; pkg != nil {
-				w.imported[name] = pkg
-				return pkg, nil
-			}
-		}
-	}
-
-	info, err := context.ImportDir(dir, 0)
-	if err != nil {
-		if _, nogo := err.(*build.NoGoError); nogo {
-			return nil, err
-		}
-		log.Fatalf("pkg %q, dir %q: ScanDir: %v", name, dir, err)
-	}
-
-	// Save tags list first time we see a directory.
-	if usePkgCache {
-		if _, ok := pkgTags[dir]; !ok {
-			pkgTags[dir] = info.AllTags
-			key = tagKey(dir, context, info.AllTags)
-		}
-	}
-
-	filenames := append(append([]string{}, info.GoFiles...), info.CgoFiles...)
-
-	// Parse package files.
-	var files []*ast.File
-	for _, file := range filenames {
-		f, err := w.parseFile(dir, file)
-		if err != nil {
-			log.Fatalf("error parsing package %s: %s", name, err)
-		}
-		files = append(files, f)
-	}
-
-	// Type-check package files.
-	var sizes types.Sizes
-	if w.context != nil {
-		sizes = types.SizesFor(w.context.Compiler, w.context.GOARCH)
-	}
-	conf := types.Config{
-		IgnoreFuncBodies: true,
-		FakeImportC:      true,
-		Importer:         w,
-		Sizes:            sizes,
-	}
-	pkg, err = conf.Check(name, fset, files, nil)
-	if err != nil {
-		ctxt := "<no context>"
-		if w.context != nil {
-			ctxt = fmt.Sprintf("%s-%s", w.context.GOOS, w.context.GOARCH)
-		}
-		log.Fatalf("error typechecking package %s: %s (%s)", name, err, ctxt)
-	}
-
-	if usePkgCache {
-		pkgCache[key] = pkg
-	}
-
-	w.imported[name] = pkg
-	return pkg, nil
-}
-
-// pushScope enters a new scope (walking a package, type, node, etc)
-// and returns a function that will leave the scope (with sanity checking
-// for mismatched pushes & pops)
-func (w *Walker) pushScope(name string) (popFunc func()) {
-	w.scope = append(w.scope, name)
-	return func() {
-		if len(w.scope) == 0 {
-			log.Fatalf("attempt to leave scope %q with empty scope list", name)
-		}
-		if w.scope[len(w.scope)-1] != name {
-			log.Fatalf("attempt to leave scope %q, but scope is currently %#v", name, w.scope)
-		}
-		w.scope = w.scope[:len(w.scope)-1]
-	}
-}
-
-func sortedMethodNames(typ *types.Interface) []string {
-	n := typ.NumMethods()
-	list := make([]string, n)
-	for i := range list {
-		list[i] = typ.Method(i).Name()
-	}
-	sort.Strings(list)
-	return list
-}
-
-// sortedEmbeddeds returns constraint types embedded in an
-// interface. It does not include embedded interface types or methods.
-func (w *Walker) sortedEmbeddeds(typ *types.Interface) []string {
-	n := typ.NumEmbeddeds()
-	list := make([]string, 0, n)
-	for i := 0; i < n; i++ {
-		emb := typ.EmbeddedType(i)
-		switch emb := emb.(type) {
-		case *types.Interface:
-			list = append(list, w.sortedEmbeddeds(emb)...)
-		case *types.Union:
-			var buf bytes.Buffer
-			nu := emb.Len()
-			for i := 0; i < nu; i++ {
-				if i > 0 {
-					buf.WriteString(" | ")
-				}
-				term := emb.Term(i)
-				if term.Tilde() {
-					buf.WriteByte('~')
-				}
-				w.writeType(&buf, term.Type())
-			}
-			list = append(list, buf.String())
-		}
-	}
-	sort.Strings(list)
-	return list
-}
-
-func (w *Walker) writeType(buf *bytes.Buffer, typ types.Type) {
-	switch typ := typ.(type) {
-	case *types.Basic:
-		s := typ.Name()
-		switch typ.Kind() {
-		case types.UnsafePointer:
-			s = "unsafe.Pointer"
-		case types.UntypedBool:
-			s = "ideal-bool"
-		case types.UntypedInt:
-			s = "ideal-int"
-		case types.UntypedRune:
-			// "ideal-char" for compatibility with old tool
-			// TODO(gri) change to "ideal-rune"
-			s = "ideal-char"
-		case types.UntypedFloat:
-			s = "ideal-float"
-		case types.UntypedComplex:
-			s = "ideal-complex"
-		case types.UntypedString:
-			s = "ideal-string"
-		case types.UntypedNil:
-			panic("should never see untyped nil type")
-		default:
-			switch s {
-			case "byte":
-				s = "uint8"
-			case "rune":
-				s = "int32"
-			}
-		}
-		buf.WriteString(s)
-
-	case *types.Array:
-		fmt.Fprintf(buf, "[%d]", typ.Len())
-		w.writeType(buf, typ.Elem())
-
-	case *types.Slice:
-		buf.WriteString("[]")
-		w.writeType(buf, typ.Elem())
-
-	case *types.Struct:
-		buf.WriteString("struct")
-
-	case *types.Pointer:
-		buf.WriteByte('*')
-		w.writeType(buf, typ.Elem())
-
-	case *types.Tuple:
-		panic("should never see a tuple type")
-
-	case *types.Signature:
-		buf.WriteString("func")
-		w.writeSignature(buf, typ)
-
-	case *types.Interface:
-		buf.WriteString("interface{")
-		if typ.NumMethods() > 0 || typ.NumEmbeddeds() > 0 {
-			buf.WriteByte(' ')
-		}
-		if typ.NumMethods() > 0 {
-			buf.WriteString(strings.Join(sortedMethodNames(typ), ", "))
-		}
-		if typ.NumEmbeddeds() > 0 {
-			buf.WriteString(strings.Join(w.sortedEmbeddeds(typ), ", "))
-		}
-		if typ.NumMethods() > 0 || typ.NumEmbeddeds() > 0 {
-			buf.WriteByte(' ')
-		}
-		buf.WriteString("}")
-
-	case *types.Map:
-		buf.WriteString("map[")
-		w.writeType(buf, typ.Key())
-		buf.WriteByte(']')
-		w.writeType(buf, typ.Elem())
-
-	case *types.Chan:
-		var s string
-		switch typ.Dir() {
-		case types.SendOnly:
-			s = "chan<- "
-		case types.RecvOnly:
-			s = "<-chan "
-		case types.SendRecv:
-			s = "chan "
-		default:
-			panic("unreachable")
-		}
-		buf.WriteString(s)
-		w.writeType(buf, typ.Elem())
-
-	case *types.Named:
-		obj := typ.Obj()
-		pkg := obj.Pkg()
-		if pkg != nil && pkg != w.current {
-			buf.WriteString(pkg.Name())
-			buf.WriteByte('.')
-		}
-		buf.WriteString(typ.Obj().Name())
-
-	case *types.TypeParam:
-		// Type parameter names may change, so use a placeholder instead.
-		fmt.Fprintf(buf, "$%d", typ.Index())
-
-	default:
-		panic(fmt.Sprintf("unknown type %T", typ))
-	}
-}
-
-func (w *Walker) writeSignature(buf *bytes.Buffer, sig *types.Signature) {
-	if tparams := sig.TypeParams(); tparams != nil {
-		w.writeTypeParams(buf, tparams, true)
-	}
-	w.writeParams(buf, sig.Params(), sig.Variadic())
-	switch res := sig.Results(); res.Len() {
-	case 0:
-		// nothing to do
-	case 1:
-		buf.WriteByte(' ')
-		w.writeType(buf, res.At(0).Type())
-	default:
-		buf.WriteByte(' ')
-		w.writeParams(buf, res, false)
-	}
-}
-
-func (w *Walker) writeTypeParams(buf *bytes.Buffer, tparams *types.TypeParamList, withConstraints bool) {
-	buf.WriteByte('[')
-	c := tparams.Len()
-	for i := 0; i < c; i++ {
-		if i > 0 {
-			buf.WriteString(", ")
-		}
-		tp := tparams.At(i)
-		w.writeType(buf, tp)
-		if withConstraints {
-			buf.WriteByte(' ')
-			w.writeType(buf, tp.Constraint())
-		}
-	}
-	buf.WriteByte(']')
-}
-
-func (w *Walker) writeParams(buf *bytes.Buffer, t *types.Tuple, variadic bool) {
-	buf.WriteByte('(')
-	for i, n := 0, t.Len(); i < n; i++ {
-		if i > 0 {
-			buf.WriteString(", ")
-		}
-		typ := t.At(i).Type()
-		if variadic && i+1 == n {
-			buf.WriteString("...")
-			typ = typ.(*types.Slice).Elem()
-		}
-		w.writeType(buf, typ)
-	}
-	buf.WriteByte(')')
-}
-
-func (w *Walker) typeString(typ types.Type) string {
-	var buf bytes.Buffer
-	w.writeType(&buf, typ)
-	return buf.String()
-}
-
-func (w *Walker) signatureString(sig *types.Signature) string {
-	var buf bytes.Buffer
-	w.writeSignature(&buf, sig)
-	return buf.String()
-}
-
-func (w *Walker) emitObj(obj types.Object) {
-	switch obj := obj.(type) {
-	case *types.Const:
-		w.emitf("const %s %s", obj.Name(), w.typeString(obj.Type()))
-		x := obj.Val()
-		short := x.String()
-		exact := x.ExactString()
-		if short == exact {
-			w.emitf("const %s = %s", obj.Name(), short)
-		} else {
-			w.emitf("const %s = %s  // %s", obj.Name(), short, exact)
-		}
-	case *types.Var:
-		w.emitf("var %s %s", obj.Name(), w.typeString(obj.Type()))
-	case *types.TypeName:
-		w.emitType(obj)
-	case *types.Func:
-		w.emitFunc(obj)
-	default:
-		panic("unknown object: " + obj.String())
-	}
-}
-
-func (w *Walker) emitType(obj *types.TypeName) {
-	name := obj.Name()
-	if tparams := obj.Type().(*types.Named).TypeParams(); tparams != nil {
-		var buf bytes.Buffer
-		buf.WriteString(name)
-		w.writeTypeParams(&buf, tparams, true)
-		name = buf.String()
-	}
-	typ := obj.Type()
-	if obj.IsAlias() {
-		w.emitf("type %s = %s", name, w.typeString(typ))
-		return
-	}
-	switch typ := typ.Underlying().(type) {
-	case *types.Struct:
-		w.emitStructType(name, typ)
-	case *types.Interface:
-		w.emitIfaceType(name, typ)
-		return // methods are handled by emitIfaceType
-	default:
-		w.emitf("type %s %s", name, w.typeString(typ.Underlying()))
-	}
-
-	// emit methods with value receiver
-	var methodNames map[string]bool
-	vset := types.NewMethodSet(typ)
-	for i, n := 0, vset.Len(); i < n; i++ {
-		m := vset.At(i)
-		if m.Obj().Exported() {
-			w.emitMethod(m)
-			if methodNames == nil {
-				methodNames = make(map[string]bool)
-			}
-			methodNames[m.Obj().Name()] = true
-		}
-	}
-
-	// emit methods with pointer receiver; exclude
-	// methods that we have emitted already
-	// (the method set of *T includes the methods of T)
-	pset := types.NewMethodSet(types.NewPointer(typ))
-	for i, n := 0, pset.Len(); i < n; i++ {
-		m := pset.At(i)
-		if m.Obj().Exported() && !methodNames[m.Obj().Name()] {
-			w.emitMethod(m)
-		}
-	}
-}
-
-func (w *Walker) emitStructType(name string, typ *types.Struct) {
-	typeStruct := fmt.Sprintf("type %s struct", name)
-	w.emitf(typeStruct)
-	defer w.pushScope(typeStruct)()
-
-	for i := 0; i < typ.NumFields(); i++ {
-		f := typ.Field(i)
-		if !f.Exported() {
-			continue
-		}
-		typ := f.Type()
-		if f.Anonymous() {
-			w.emitf("embedded %s", w.typeString(typ))
-			continue
-		}
-		w.emitf("%s %s", f.Name(), w.typeString(typ))
-	}
-}
-
-func (w *Walker) emitIfaceType(name string, typ *types.Interface) {
-	pop := w.pushScope("type " + name + " interface")
-
-	var methodNames []string
-	complete := true
-	mset := types.NewMethodSet(typ)
-	for i, n := 0, mset.Len(); i < n; i++ {
-		m := mset.At(i).Obj().(*types.Func)
-		if !m.Exported() {
-			complete = false
-			continue
-		}
-		methodNames = append(methodNames, m.Name())
-		w.emitf("%s%s", m.Name(), w.signatureString(m.Type().(*types.Signature)))
-	}
-
-	if !complete {
-		// The method set has unexported methods, so all the
-		// implementations are provided by the same package,
-		// so the method set can be extended. Instead of recording
-		// the full set of names (below), record only that there were
-		// unexported methods. (If the interface shrinks, we will notice
-		// because a method signature emitted during the last loop
-		// will disappear.)
-		w.emitf("unexported methods")
-	}
-
-	pop()
-
-	if !complete {
-		return
-	}
-
-	if len(methodNames) == 0 {
-		w.emitf("type %s interface {}", name)
-		return
-	}
-
-	sort.Strings(methodNames)
-	w.emitf("type %s interface { %s }", name, strings.Join(methodNames, ", "))
-}
-
-func (w *Walker) emitFunc(f *types.Func) {
-	sig := f.Type().(*types.Signature)
-	if sig.Recv() != nil {
-		panic("method considered a regular function: " + f.String())
-	}
-	w.emitf("func %s%s", f.Name(), w.signatureString(sig))
-}
-
-func (w *Walker) emitMethod(m *types.Selection) {
-	sig := m.Type().(*types.Signature)
-	recv := sig.Recv().Type()
-	// report exported methods with unexported receiver base type
-	if true {
-		base := recv
-		if p, _ := recv.(*types.Pointer); p != nil {
-			base = p.Elem()
-		}
-		if obj := base.(*types.Named).Obj(); !obj.Exported() {
-			log.Fatalf("exported method with unexported receiver base type: %s", m)
-		}
-	}
-	tps := ""
-	if rtp := sig.RecvTypeParams(); rtp != nil {
-		var buf bytes.Buffer
-		w.writeTypeParams(&buf, rtp, false)
-		tps = buf.String()
-	}
-	w.emitf("method (%s%s) %s%s", w.typeString(recv), tps, m.Obj().Name(), w.signatureString(sig))
-}
-
-func (w *Walker) emitf(format string, args ...any) {
-	f := strings.Join(w.scope, ", ") + ", " + fmt.Sprintf(format, args...)
-	if strings.Contains(f, "\n") {
-		panic("feature contains newlines: " + f)
-	}
-
-	if _, dup := w.features[f]; dup {
-		panic("duplicate feature inserted: " + f)
-	}
-	w.features[f] = true
-
-	if *verbose {
-		log.Printf("feature: %s", f)
-	}
-}
diff --git a/src/cmd/api/goapi_boring_test.go b/src/cmd/api/goapi_boring_test.go
deleted file mode 100644
index f0e3575..0000000
--- a/src/cmd/api/goapi_boring_test.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build boringcrypto
-
-package main
-
-import (
-	"fmt"
-	"os"
-)
-
-func init() {
-	fmt.Printf("SKIP with boringcrypto enabled\n")
-	os.Exit(0)
-}
diff --git a/src/cmd/api/goapi_test.go b/src/cmd/api/goapi_test.go
deleted file mode 100644
index 862ab18..0000000
--- a/src/cmd/api/goapi_test.go
+++ /dev/null
@@ -1,232 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import (
-	"bytes"
-	"flag"
-	"fmt"
-	"go/build"
-	"internal/testenv"
-	"os"
-	"path/filepath"
-	"sort"
-	"strings"
-	"sync"
-	"testing"
-)
-
-func TestMain(m *testing.M) {
-	flag.Parse()
-	for _, c := range contexts {
-		c.Compiler = build.Default.Compiler
-	}
-	build.Default.GOROOT = testenv.GOROOT(nil)
-
-	// Warm up the import cache in parallel.
-	var wg sync.WaitGroup
-	for _, context := range contexts {
-		context := context
-		wg.Add(1)
-		go func() {
-			defer wg.Done()
-			_ = NewWalker(context, filepath.Join(build.Default.GOROOT, "src"))
-		}()
-	}
-	wg.Wait()
-
-	os.Exit(m.Run())
-}
-
-var (
-	updateGolden = flag.Bool("updategolden", false, "update golden files")
-)
-
-func TestGolden(t *testing.T) {
-	td, err := os.Open("testdata/src/pkg")
-	if err != nil {
-		t.Fatal(err)
-	}
-	fis, err := td.Readdir(0)
-	if err != nil {
-		t.Fatal(err)
-	}
-	for _, fi := range fis {
-		if !fi.IsDir() {
-			continue
-		}
-
-		// TODO(gri) remove extra pkg directory eventually
-		goldenFile := filepath.Join("testdata", "src", "pkg", fi.Name(), "golden.txt")
-		w := NewWalker(nil, "testdata/src/pkg")
-		pkg, _ := w.Import(fi.Name())
-		w.export(pkg)
-
-		if *updateGolden {
-			os.Remove(goldenFile)
-			f, err := os.Create(goldenFile)
-			if err != nil {
-				t.Fatal(err)
-			}
-			for _, feat := range w.Features() {
-				fmt.Fprintf(f, "%s\n", feat)
-			}
-			f.Close()
-		}
-
-		bs, err := os.ReadFile(goldenFile)
-		if err != nil {
-			t.Fatalf("opening golden.txt for package %q: %v", fi.Name(), err)
-		}
-		wanted := strings.Split(string(bs), "\n")
-		sort.Strings(wanted)
-		for _, feature := range wanted {
-			if feature == "" {
-				continue
-			}
-			_, ok := w.features[feature]
-			if !ok {
-				t.Errorf("package %s: missing feature %q", fi.Name(), feature)
-			}
-			delete(w.features, feature)
-		}
-
-		for _, feature := range w.Features() {
-			t.Errorf("package %s: extra feature not in golden file: %q", fi.Name(), feature)
-		}
-	}
-}
-
-func TestCompareAPI(t *testing.T) {
-	tests := []struct {
-		name                                    string
-		features, required, optional, exception []string
-		ok                                      bool   // want
-		out                                     string // want
-	}{
-		{
-			name:     "feature added",
-			features: []string{"A", "B", "C", "D", "E", "F"},
-			required: []string{"B", "D"},
-			ok:       true,
-			out:      "+A\n+C\n+E\n+F\n",
-		},
-		{
-			name:     "feature removed",
-			features: []string{"C", "A"},
-			required: []string{"A", "B", "C"},
-			ok:       false,
-			out:      "-B\n",
-		},
-		{
-			name:     "feature added then removed",
-			features: []string{"A", "C"},
-			optional: []string{"B"},
-			required: []string{"A", "C"},
-			ok:       true,
-			out:      "±B\n",
-		},
-		{
-			name:      "exception removal",
-			required:  []string{"A", "B", "C"},
-			features:  []string{"A", "C"},
-			exception: []string{"B"},
-			ok:        true,
-			out:       "",
-		},
-		{
-			// https://golang.org/issue/4303
-			name: "contexts reconverging",
-			required: []string{
-				"A",
-				"pkg syscall (darwin-amd64), type RawSockaddrInet6 struct",
-			},
-			features: []string{
-				"A",
-				"pkg syscall, type RawSockaddrInet6 struct",
-			},
-			ok:  true,
-			out: "+pkg syscall, type RawSockaddrInet6 struct\n",
-		},
-	}
-	for _, tt := range tests {
-		buf := new(bytes.Buffer)
-		gotok := compareAPI(buf, tt.features, tt.required, tt.optional, tt.exception, true)
-		if gotok != tt.ok {
-			t.Errorf("%s: ok = %v; want %v", tt.name, gotok, tt.ok)
-		}
-		if got := buf.String(); got != tt.out {
-			t.Errorf("%s: output differs\nGOT:\n%s\nWANT:\n%s", tt.name, got, tt.out)
-		}
-	}
-}
-
-func TestSkipInternal(t *testing.T) {
-	tests := []struct {
-		pkg  string
-		want bool
-	}{
-		{"net/http", true},
-		{"net/http/internal-foo", true},
-		{"net/http/internal", false},
-		{"net/http/internal/bar", false},
-		{"internal/foo", false},
-		{"internal", false},
-	}
-	for _, tt := range tests {
-		got := !internalPkg.MatchString(tt.pkg)
-		if got != tt.want {
-			t.Errorf("%s is internal = %v; want %v", tt.pkg, got, tt.want)
-		}
-	}
-}
-
-func BenchmarkAll(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		for _, context := range contexts {
-			w := NewWalker(context, filepath.Join(build.Default.GOROOT, "src"))
-			for _, name := range w.stdPackages {
-				pkg, _ := w.Import(name)
-				w.export(pkg)
-			}
-			w.Features()
-		}
-	}
-}
-
-func TestIssue21181(t *testing.T) {
-	for _, context := range contexts {
-		w := NewWalker(context, "testdata/src/issue21181")
-		pkg, err := w.Import("p")
-		if err != nil {
-			t.Fatalf("%s: (%s-%s) %s %v", err, context.GOOS, context.GOARCH,
-				pkg.Name(), w.imported)
-		}
-		w.export(pkg)
-	}
-}
-
-func TestIssue29837(t *testing.T) {
-	for _, context := range contexts {
-		w := NewWalker(context, "testdata/src/issue29837")
-		_, err := w.Import("p")
-		if _, nogo := err.(*build.NoGoError); !nogo {
-			t.Errorf("expected *build.NoGoError, got %T", err)
-		}
-	}
-}
-
-func TestIssue41358(t *testing.T) {
-	context := new(build.Context)
-	*context = build.Default
-	context.Dir = filepath.Join(context.GOROOT, "src")
-
-	w := NewWalker(context, context.Dir)
-	for _, pkg := range w.stdPackages {
-		if strings.HasPrefix(pkg, "vendor/") || strings.HasPrefix(pkg, "golang.org/x/") {
-			t.Fatalf("stdPackages contains unexpected package %s", pkg)
-		}
-	}
-}
diff --git a/src/cmd/api/run.go b/src/cmd/api/run.go
deleted file mode 100644
index 1ae629a..0000000
--- a/src/cmd/api/run.go
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build ignore
-
-// The run program is invoked via the dist tool.
-// To invoke manually: go tool dist test -run api --no-rebuild
-package main
-
-import (
-	"errors"
-	"fmt"
-	"internal/goversion"
-	"io/fs"
-	"log"
-	"os"
-	"os/exec"
-	"path/filepath"
-	"runtime"
-	"strconv"
-	"strings"
-)
-
-func goCmd() string {
-	var exeSuffix string
-	if runtime.GOOS == "windows" {
-		exeSuffix = ".exe"
-	}
-	path := filepath.Join(runtime.GOROOT(), "bin", "go"+exeSuffix)
-	if _, err := os.Stat(path); err == nil {
-		return path
-	}
-	return "go"
-}
-
-var goroot string
-
-func main() {
-	log.SetFlags(0)
-	goroot = os.Getenv("GOROOT") // should be set by run.{bash,bat}
-	if goroot == "" {
-		log.Fatal("No $GOROOT set.")
-	}
-	if err := os.Chdir(filepath.Join(goroot, "api")); err != nil {
-		log.Fatal(err)
-	}
-
-	files, err := filepath.Glob("go1*.txt")
-	if err != nil {
-		log.Fatal(err)
-	}
-	next, err := filepath.Glob(filepath.Join("next", "*.txt"))
-	if err != nil {
-		log.Fatal(err)
-	}
-	cmd := exec.Command(goCmd(), "tool", "api",
-		"-c", strings.Join(files, ","),
-		"-approval", strings.Join(append(approvalNeeded(files), next...), ","),
-		allowNew(),
-		"-next", strings.Join(next, ","),
-		"-except", "except.txt",
-	)
-	out, err := cmd.CombinedOutput()
-	if err != nil {
-		log.Fatalf("Error running API checker: %v\n%s", err, out)
-	}
-	fmt.Print(string(out))
-}
-
-func approvalNeeded(files []string) []string {
-	var out []string
-	for _, f := range files {
-		name := filepath.Base(f)
-		if name == "go1.txt" {
-			continue
-		}
-		minor := strings.TrimSuffix(strings.TrimPrefix(name, "go1."), ".txt")
-		n, err := strconv.Atoi(minor)
-		if err != nil {
-			log.Fatalf("unexpected api file: %v", f)
-		}
-		if n >= 19 { // approvals started being tracked in Go 1.19
-			out = append(out, f)
-		}
-	}
-	return out
-}
-
-// allowNew returns the -allow_new flag to use for the 'go tool api' invocation.
-func allowNew() string {
-	// Experiment for Go 1.19: always require api file updates.
-	return "-allow_new=false"
-
-	// Verify that the api/go1.n.txt for previous Go version exists.
-	// It definitely should, otherwise it's a signal that the logic below may be outdated.
-	if _, err := os.Stat(fmt.Sprintf("go1.%d.txt", goversion.Version-1)); err != nil {
-		log.Fatalln("Problem with api file for previous release:", err)
-	}
-
-	// See whether the api/go1.n.txt for this Go version has been created.
-	// (As of April 2021, it gets created during the release of the first Beta.)
-	_, err := os.Stat(fmt.Sprintf("go1.%d.txt", goversion.Version))
-	if errors.Is(err, fs.ErrNotExist) {
-		// It doesn't exist, so we're in development or before Beta 1.
-		// At this stage, unmentioned API additions are deemed okay.
-		// (They will be quietly shown in API check output, but the test won't fail).
-		return "-allow_new=true"
-	} else if err == nil {
-		// The api/go1.n.txt for this Go version has been created,
-		// so we're definitely past Beta 1 in the release cycle.
-		//
-		// From this point, enforce that api/go1.n.txt is an accurate and complete
-		// representation of what's going into the release by failing API check if
-		// there are API additions (a month into the freeze, there shouldn't be many).
-		//
-		// See golang.org/issue/43956.
-		return "-allow_new=false"
-	} else {
-		log.Fatal(err)
-	}
-	panic("unreachable")
-}
diff --git a/src/cmd/api/testdata/src/pkg/p1/golden.txt b/src/cmd/api/testdata/src/pkg/p1/golden.txt
index 0378a56..65c4f35 100644
--- a/src/cmd/api/testdata/src/pkg/p1/golden.txt
+++ b/src/cmd/api/testdata/src/pkg/p1/golden.txt
@@ -1,5 +1,6 @@
 pkg p1, const A = 1
 pkg p1, const A ideal-int
+pkg p1, const A //deprecated
 pkg p1, const A64 = 1
 pkg p1, const A64 int64
 pkg p1, const AIsLowerA = 11
@@ -25,6 +26,7 @@
 pkg p1, method (*B) OnBothTandBPtr()
 pkg p1, method (*Embedded) OnEmbedded()
 pkg p1, method (*S2) SMethod(int8, int16, int64)
+pkg p1, method (*S2) SMethod //deprecated
 pkg p1, method (*T) JustOnT()
 pkg p1, method (*T) OnBothTandBPtr()
 pkg p1, method (B) OnBothTandBVal()
@@ -52,6 +54,7 @@
 pkg p1, type Error interface, Temporary() bool
 pkg p1, type FuncType func(int, int, string) (*B, error)
 pkg p1, type I interface, Get(string) int64
+pkg p1, type I interface, Get //deprecated
 pkg p1, type I interface, GetNamed(string) int64
 pkg p1, type I interface, Name() string
 pkg p1, type I interface, PackageTwoMeth()
@@ -62,15 +65,18 @@
 pkg p1, type Namer interface, Name() string
 pkg p1, type Private interface, X()
 pkg p1, type Private interface, unexported methods
+pkg p1, type Private //deprecated
 pkg p1, type Public interface { X, Y }
 pkg p1, type Public interface, X()
 pkg p1, type Public interface, Y()
 pkg p1, type S struct
 pkg p1, type S struct, Public *int
+pkg p1, type S struct, Public //deprecated
 pkg p1, type S struct, PublicTime Time
 pkg p1, type S2 struct
 pkg p1, type S2 struct, Extra bool
 pkg p1, type S2 struct, embedded S
+pkg p1, type S2 struct, embedded S //deprecated
 pkg p1, type SI struct
 pkg p1, type SI struct, I int
 pkg p1, type T struct
@@ -79,6 +85,7 @@
 pkg p1, type TPtrUnexported struct
 pkg p1, type Time struct
 pkg p1, type URL struct
+pkg p1, type URL //deprecated
 pkg p1, var Byte uint8
 pkg p1, var ByteConv []uint8
 pkg p1, var ByteFunc func(uint8) int32
@@ -91,6 +98,7 @@
 pkg p1, var V1 uint64
 pkg p1, var V2 p2.Twoer
 pkg p1, var VError Error
+pkg p1, var VError //deprecated
 pkg p1, var X I
 pkg p1, var X0 int64
 pkg p1, var Y int
diff --git a/src/cmd/api/testdata/src/pkg/p1/p1.go b/src/cmd/api/testdata/src/pkg/p1/p1.go
index 81826d7..025563d 100644
--- a/src/cmd/api/testdata/src/pkg/p1/p1.go
+++ b/src/cmd/api/testdata/src/pkg/p1/p1.go
@@ -1,3 +1,7 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
 package p1
 
 import (
@@ -8,6 +12,7 @@
 	ConstChase2 = constChase // forward declaration to unexported ident
 	constChase  = AIsLowerA  // forward declaration to exported ident
 
+	// Deprecated: use B.
 	A         = 1
 	a         = 11
 	A64 int64 = 1
@@ -21,7 +26,8 @@
 
 // Variables from function calls.
 var (
-	V      = ptwo.F()
+	V = ptwo.F()
+	// Deprecated: use WError.
 	VError = BarE()
 	V1     = Bar1(1, 2, 3)
 	V2     = ptwo.G()
@@ -46,11 +52,13 @@
 type Time struct{}
 
 type S struct {
+	// Deprecated: use PublicTime.
 	Public     *int
 	private    *int
 	PublicTime Time
 }
 
+// Deprecated: use URI.
 type URL struct{}
 
 type EmbedURLPtr struct {
@@ -58,6 +66,7 @@
 }
 
 type S2 struct {
+	// Deprecated: use T.
 	S
 	Extra bool
 }
@@ -77,6 +86,7 @@
 	Namer
 	ptwo.Twoer
 	Set(name string, balance int64)
+	// Deprecated: use GetNamed.
 	Get(string) int64
 	GetNamed(string) (balance int64)
 	private()
@@ -87,6 +97,7 @@
 	Y()
 }
 
+// Deprecated: Use Unexported.
 type Private interface {
 	X()
 	y()
@@ -100,6 +111,7 @@
 func (myInt) privateTypeMethod()           {}
 func (myInt) CapitalMethodUnexportedType() {}
 
+// Deprecated: use TMethod.
 func (s *S2) SMethod(x int8, y int16, z int64) {}
 
 type s struct{}
diff --git a/src/cmd/api/testdata/src/pkg/p2/golden.txt b/src/cmd/api/testdata/src/pkg/p2/golden.txt
index 4271620..735d668 100644
--- a/src/cmd/api/testdata/src/pkg/p2/golden.txt
+++ b/src/cmd/api/testdata/src/pkg/p2/golden.txt
@@ -1,5 +1,8 @@
 pkg p2, func F() string
+pkg p2, func F //deprecated
 pkg p2, func G() Twoer
 pkg p2, func NewError(string) error
 pkg p2, type Twoer interface { PackageTwoMeth }
 pkg p2, type Twoer interface, PackageTwoMeth()
+pkg p2, type Twoer interface, PackageTwoMeth //deprecated
+
diff --git a/src/cmd/api/testdata/src/pkg/p2/p2.go b/src/cmd/api/testdata/src/pkg/p2/p2.go
index 6b107b5..2ce4e75 100644
--- a/src/cmd/api/testdata/src/pkg/p2/p2.go
+++ b/src/cmd/api/testdata/src/pkg/p2/p2.go
@@ -1,9 +1,17 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
 package p2
 
 type Twoer interface {
+	// Deprecated: No good.
 	PackageTwoMeth()
 }
 
-func F() string               {}
-func G() Twoer                {}
+// Deprecated: No good.
+func F() string {}
+
+func G() Twoer {}
+
 func NewError(s string) error {}
diff --git a/src/cmd/api/testdata/src/pkg/p3/p3.go b/src/cmd/api/testdata/src/pkg/p3/p3.go
index 1b2b1a4..3a0686a 100644
--- a/src/cmd/api/testdata/src/pkg/p3/p3.go
+++ b/src/cmd/api/testdata/src/pkg/p3/p3.go
@@ -1,3 +1,7 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
 package p3
 
 type ThirdBase struct{}
diff --git a/src/cmd/api/testdata/src/pkg/p4/golden.txt b/src/cmd/api/testdata/src/pkg/p4/golden.txt
index 7997ab4..eec0598 100644
--- a/src/cmd/api/testdata/src/pkg/p4/golden.txt
+++ b/src/cmd/api/testdata/src/pkg/p4/golden.txt
@@ -3,3 +3,4 @@
 pkg p4, method (Pair[$0, $1]) First() $0
 pkg p4, type Pair[$0 interface{ M }, $1 interface{ ~int }] struct
 pkg p4, func Clone[$0 interface{ ~[]$1 }, $1 interface{}]($0) $0
+pkg p4, func Clone //deprecated
diff --git a/src/cmd/api/testdata/src/pkg/p4/p4.go b/src/cmd/api/testdata/src/pkg/p4/p4.go
index 1f90e77..6c93e3e 100644
--- a/src/cmd/api/testdata/src/pkg/p4/p4.go
+++ b/src/cmd/api/testdata/src/pkg/p4/p4.go
@@ -21,6 +21,7 @@
 	return p.f2
 }
 
+// Deprecated: Use something else.
 func Clone[S ~[]T, T any](s S) S {
 	return append(S(nil), s...)
 }
diff --git a/src/cmd/asm/doc.go b/src/cmd/asm/doc.go
index 098f063..bb9166b 100644
--- a/src/cmd/asm/doc.go
+++ b/src/cmd/asm/doc.go
@@ -37,6 +37,8 @@
 		Write symbol ABI information to output file. Don't assemble.
 	-o file
 		Write output to file. The default is foo.o for /a/b/c/foo.s.
+	-p pkgpath
+		Set expected package import to pkgpath.
 	-shared
 		Generate code that can be linked into a shared library.
 	-spectre list
diff --git a/src/cmd/asm/internal/arch/arch.go b/src/cmd/asm/internal/arch/arch.go
index a724a3b..740711c 100644
--- a/src/cmd/asm/internal/arch/arch.go
+++ b/src/cmd/asm/internal/arch/arch.go
@@ -336,6 +336,9 @@
 	for i := ppc64.REG_VS0; i <= ppc64.REG_VS63; i++ {
 		register[obj.Rconv(i)] = int16(i)
 	}
+	for i := ppc64.REG_A0; i <= ppc64.REG_A7; i++ {
+		register[obj.Rconv(i)] = int16(i)
+	}
 	for i := ppc64.REG_CR0; i <= ppc64.REG_CR7; i++ {
 		register[obj.Rconv(i)] = int16(i)
 	}
@@ -374,6 +377,11 @@
 			instructions[s] = obj.As(i) + obj.ABasePPC64
 		}
 	}
+	// The opcodes generated by x/arch's ppc64map are listed in
+	// a separate slice, add them too.
+	for i, s := range ppc64.GenAnames {
+		instructions[s] = obj.As(i) + ppc64.AFIRSTGEN
+	}
 	// Annoying aliases.
 	instructions["BR"] = ppc64.ABR
 	instructions["BL"] = ppc64.ABL
diff --git a/src/cmd/asm/internal/arch/arm.go b/src/cmd/asm/internal/arch/arm.go
index b0e985f..22ac483 100644
--- a/src/cmd/asm/internal/arch/arm.go
+++ b/src/cmd/asm/internal/arch/arm.go
@@ -113,7 +113,7 @@
 const aMCR = arm.ALAST + 1
 
 // IsARMMRC reports whether the op (as defined by an arm.A* constant) is
-// MRC or MCR
+// MRC or MCR.
 func IsARMMRC(op obj.As) bool {
 	switch op {
 	case arm.AMRC, aMCR: // Note: aMCR is defined in this package.
diff --git a/src/cmd/asm/internal/arch/arm64.go b/src/cmd/asm/internal/arch/arm64.go
index 936b894..e63601d 100644
--- a/src/cmd/asm/internal/arch/arm64.go
+++ b/src/cmd/asm/internal/arch/arm64.go
@@ -12,7 +12,6 @@
 	"cmd/internal/obj"
 	"cmd/internal/obj/arm64"
 	"errors"
-	"fmt"
 )
 
 var arm64LS = map[string]uint8{
@@ -66,8 +65,7 @@
 		// Generate the mapping automatically when the first time the function is called.
 		arm64SpecialOperand = map[string]arm64.SpecialOperand{}
 		for opd := arm64.SPOP_BEGIN; opd < arm64.SPOP_END; opd++ {
-			s := fmt.Sprintf("%s", opd)
-			arm64SpecialOperand[s] = opd
+			arm64SpecialOperand[opd.String()] = opd
 		}
 
 		// Handle some special cases.
@@ -120,10 +118,7 @@
 		return true
 	}
 	// LDADDx/SWPx/CASx atomic instructions
-	if arm64.IsAtomicInstruction(op) {
-		return true
-	}
-	return false
+	return arm64.IsAtomicInstruction(op)
 }
 
 // IsARM64TBL reports whether the op (as defined by an arm64.A*
@@ -131,7 +126,7 @@
 // inputs does not fit into prog.Reg, so require special handling.
 func IsARM64TBL(op obj.As) bool {
 	switch op {
-	case arm64.AVTBL, arm64.AVMOVQ:
+	case arm64.AVTBL, arm64.AVTBX, arm64.AVMOVQ:
 		return true
 	}
 	return false
diff --git a/src/cmd/asm/internal/arch/ppc64.go b/src/cmd/asm/internal/arch/ppc64.go
index 616e189..98a2bfe 100644
--- a/src/cmd/asm/internal/arch/ppc64.go
+++ b/src/cmd/asm/internal/arch/ppc64.go
@@ -21,28 +21,6 @@
 	return false
 }
 
-// IsPPC64RLD reports whether the op (as defined by an ppc64.A* constant) is
-// one of the RLD-like instructions that require special handling.
-// The FMADD-like instructions behave similarly.
-func IsPPC64RLD(op obj.As) bool {
-	switch op {
-	case ppc64.ARLDC, ppc64.ARLDCCC, ppc64.ARLDCL, ppc64.ARLDCLCC,
-		ppc64.ARLDCR, ppc64.ARLDCRCC, ppc64.ARLDMI, ppc64.ARLDMICC,
-		ppc64.ARLWMI, ppc64.ARLWMICC, ppc64.ARLWNM, ppc64.ARLWNMCC:
-		return true
-	case ppc64.AFMADD, ppc64.AFMADDCC, ppc64.AFMADDS, ppc64.AFMADDSCC,
-		ppc64.AFMSUB, ppc64.AFMSUBCC, ppc64.AFMSUBS, ppc64.AFMSUBSCC,
-		ppc64.AFNMADD, ppc64.AFNMADDCC, ppc64.AFNMADDS, ppc64.AFNMADDSCC,
-		ppc64.AFNMSUB, ppc64.AFNMSUBCC, ppc64.AFNMSUBS, ppc64.AFNMSUBSCC:
-		return true
-	}
-	return false
-}
-
-func IsPPC64ISEL(op obj.As) bool {
-	return op == ppc64.AISEL
-}
-
 // IsPPC64CMP reports whether the op (as defined by an ppc64.A* constant) is
 // one of the CMP instructions that require special handling.
 func IsPPC64CMP(op obj.As) bool {
@@ -77,6 +55,10 @@
 		if 0 <= n && n <= 7 {
 			return ppc64.REG_CR0 + n, true
 		}
+	case "A":
+		if 0 <= n && n <= 8 {
+			return ppc64.REG_A0 + n, true
+		}
 	case "VS":
 		if 0 <= n && n <= 63 {
 			return ppc64.REG_VS0 + n, true
diff --git a/src/cmd/asm/internal/asm/asm.go b/src/cmd/asm/internal/asm/asm.go
index cfd1f4c..00fb7f4 100644
--- a/src/cmd/asm/internal/asm/asm.go
+++ b/src/cmd/asm/internal/asm/asm.go
@@ -5,9 +5,9 @@
 package asm
 
 import (
-	"bytes"
 	"fmt"
 	"strconv"
+	"strings"
 	"text/scanner"
 
 	"cmd/asm/internal/arch"
@@ -22,7 +22,7 @@
 
 // TODO: configure the architecture
 
-var testOut *bytes.Buffer // Gathers output when testing.
+var testOut *strings.Builder // Gathers output when testing.
 
 // append adds the Prog to the end of the program-thus-far.
 // If doLabel is set, it also defines the labels collect for this Prog.
@@ -178,7 +178,7 @@
 		}
 		argSize = p.positiveAtoi(op[1].String())
 	}
-	p.ctxt.InitTextSym(nameAddr.Sym, int(flag))
+	p.ctxt.InitTextSym(nameAddr.Sym, int(flag), p.pos())
 	prog := &obj.Prog{
 		Ctxt: p.ctxt,
 		As:   obj.ATEXT,
@@ -297,7 +297,7 @@
 	}
 
 	// log.Printf("GLOBL %s %d, $%d", name, flag, size)
-	p.ctxt.Globl(nameAddr.Sym, addr.Offset, int(flag))
+	p.ctxt.GloblPos(nameAddr.Sym, addr.Offset, int(flag), p.pos())
 }
 
 // asmPCData assembles a PCDATA pseudo-op.
@@ -727,23 +727,17 @@
 				prog.To = a[1]
 				break
 			}
-			// Arithmetic. Choices are:
-			// reg reg reg
-			// imm reg reg
-			// reg imm reg
-			// If the immediate is the middle argument, use From3.
+
+			prog.From = a[0]
+			prog.To = a[2]
+
+			// If the second argument is not a register argument, it must be
+			// passed RestArgs/SetFrom3
 			switch a[1].Type {
 			case obj.TYPE_REG:
-				prog.From = a[0]
 				prog.Reg = p.getRegister(prog, op, &a[1])
-				prog.To = a[2]
-			case obj.TYPE_CONST:
-				prog.From = a[0]
-				prog.SetFrom3(a[1])
-				prog.To = a[2]
 			default:
-				p.errorf("invalid addressing modes for %s instruction", op)
-				return
+				prog.SetFrom3(a[1])
 			}
 		case sys.RISCV64:
 			// RISCV64 instructions with one input and two outputs.
@@ -810,41 +804,18 @@
 			break
 		}
 		if p.arch.Family == sys.PPC64 {
-			if arch.IsPPC64RLD(op) {
-				prog.From = a[0]
-				prog.Reg = p.getRegister(prog, op, &a[1])
-				prog.SetFrom3(a[2])
-				prog.To = a[3]
-				break
-			} else if arch.IsPPC64ISEL(op) {
-				// ISEL BC,RB,RA,RT becomes isel rt,ra,rb,bc
-				prog.SetFrom3(a[2])                       // ra
-				prog.From = a[0]                          // bc
-				prog.Reg = p.getRegister(prog, op, &a[1]) // rb
-				prog.To = a[3]                            // rt
-				break
-			}
-			// Else, it is a VA-form instruction
-			// reg reg reg reg
-			// imm reg reg reg
-			// Or a VX-form instruction
-			// imm imm reg reg
+			prog.From = a[0]
+			prog.To = a[3]
+			// If the second argument is not a register argument, it must be
+			// passed RestArgs/SetFrom3
 			if a[1].Type == obj.TYPE_REG {
-				prog.From = a[0]
 				prog.Reg = p.getRegister(prog, op, &a[1])
-				prog.SetFrom3(a[2])
-				prog.To = a[3]
-				break
-			} else if a[1].Type == obj.TYPE_CONST {
-				prog.From = a[0]
-				prog.Reg = p.getRegister(prog, op, &a[2])
-				prog.SetFrom3(a[1])
-				prog.To = a[3]
-				break
+				prog.SetRestArgs([]obj.Addr{a[2]})
 			} else {
-				p.errorf("invalid addressing modes for %s instruction", op)
-				return
+				// Don't set prog.Reg if a1 isn't a reg arg.
+				prog.SetRestArgs([]obj.Addr{a[1], a[2]})
 			}
+			break
 		}
 		if p.arch.Family == sys.RISCV64 {
 			prog.From = a[0]
@@ -909,6 +880,14 @@
 			prog.As = MRC // Both instructions are coded as MRC.
 			break
 		}
+		if p.arch.Family == sys.PPC64 {
+			prog.From = a[0]
+			// Second arg is always a register type on ppc64.
+			prog.Reg = p.getRegister(prog, op, &a[1])
+			prog.SetRestArgs([]obj.Addr{a[2], a[3], a[4]})
+			prog.To = a[5]
+			break
+		}
 		fallthrough
 	default:
 		p.errorf("can't handle %s instruction with %d operands", op, len(a))
@@ -918,13 +897,6 @@
 	p.append(prog, cond, true)
 }
 
-// newAddr returns a new(Addr) initialized to x.
-func newAddr(x obj.Addr) *obj.Addr {
-	p := new(obj.Addr)
-	*p = x
-	return p
-}
-
 // symbolName returns the symbol name, or an error string if none if available.
 func symbolName(addr *obj.Addr) string {
 	if addr.Sym != nil {
diff --git a/src/cmd/asm/internal/asm/endtoend_test.go b/src/cmd/asm/internal/asm/endtoend_test.go
index 33a4465..3928e36 100644
--- a/src/cmd/asm/internal/asm/endtoend_test.go
+++ b/src/cmd/asm/internal/asm/endtoend_test.go
@@ -9,7 +9,6 @@
 	"bytes"
 	"fmt"
 	"internal/buildcfg"
-	"io/ioutil"
 	"os"
 	"path/filepath"
 	"regexp"
@@ -34,7 +33,7 @@
 	parser := NewParser(ctxt, architecture, lexer, false)
 	pList := new(obj.Plist)
 	var ok bool
-	testOut = new(bytes.Buffer) // The assembler writes test output to this buffer.
+	testOut = new(strings.Builder) // The assembler writes test output to this buffer.
 	ctxt.Bso = bufio.NewWriter(os.Stdout)
 	ctxt.IsAsm = true
 	defer ctxt.Bso.Flush()
@@ -51,7 +50,7 @@
 	output := strings.Split(testOut.String(), "\n")
 
 	// Reconstruct expected output by independently "parsing" the input.
-	data, err := ioutil.ReadFile(input)
+	data, err := os.ReadFile(input)
 	if err != nil {
 		t.Error(err)
 		return
@@ -262,7 +261,7 @@
 // the standard file:line: prefix,
 // but that's not where we are today.
 // It might be at the beginning but it might be in the middle of the printed instruction.
-var fileLineRE = regexp.MustCompile(`(?:^|\()(testdata[/\\][0-9a-z]+\.s:[0-9]+)(?:$|\)|:)`)
+var fileLineRE = regexp.MustCompile(`(?:^|\()(testdata[/\\][\da-z]+\.s:\d+)(?:$|\)|:)`)
 
 // Same as in test/run.go
 var (
@@ -277,7 +276,6 @@
 	parser := NewParser(ctxt, architecture, lexer, false)
 	pList := new(obj.Plist)
 	var ok bool
-	testOut = new(bytes.Buffer) // The assembler writes test output to this buffer.
 	ctxt.Bso = bufio.NewWriter(os.Stdout)
 	ctxt.IsAsm = true
 	defer ctxt.Bso.Flush()
@@ -325,7 +323,7 @@
 	}
 
 	// Reconstruct expected errors by independently "parsing" the input.
-	data, err := ioutil.ReadFile(input)
+	data, err := os.ReadFile(input)
 	if err != nil {
 		t.Error(err)
 		return
@@ -383,6 +381,10 @@
 	testErrors(t, "amd64", "buildtagerror")
 }
 
+func TestGenericErrors(t *testing.T) {
+	testErrors(t, "amd64", "duperror")
+}
+
 func TestARMErrors(t *testing.T) {
 	testErrors(t, "arm", "armerror")
 }
@@ -456,6 +458,9 @@
 
 func TestPPC64EndToEnd(t *testing.T) {
 	testEndToEnd(t, "ppc64", "ppc64")
+
+	// The assembler accepts all instructions irrespective of the GOPPC64 value.
+	testEndToEnd(t, "ppc64", "ppc64_p10")
 }
 
 func TestRISCVEndToEnd(t *testing.T) {
diff --git a/src/cmd/asm/internal/asm/operand_test.go b/src/cmd/asm/internal/asm/operand_test.go
index b47c7e1..29371d6 100644
--- a/src/cmd/asm/internal/asm/operand_test.go
+++ b/src/cmd/asm/internal/asm/operand_test.go
@@ -473,7 +473,7 @@
 	{"(R4)", "(R4)"},
 	{"(R5)", "(R5)"},
 	{"(R5)(R6*1)", "(R5)(R6*1)"},
-	{"(R5+R6)", "(R5)(R6*1)"}, // Old syntax.
+	{"(R5+R6)", "(R5)(R6)"},
 	{"-1(R4)", "-1(R4)"},
 	{"-1(R5)", "-1(R5)"},
 	{"6(PC)", "6(PC)"},
diff --git a/src/cmd/asm/internal/asm/parse.go b/src/cmd/asm/internal/asm/parse.go
index 6445e01..e26c945 100644
--- a/src/cmd/asm/internal/asm/parse.go
+++ b/src/cmd/asm/internal/asm/parse.go
@@ -567,10 +567,7 @@
 		return false
 	}
 	// R1.xxx
-	if p.peek() == '.' {
-		return true
-	}
-	return false
+	return p.peek() == '.'
 }
 
 // registerReference parses a register given either the name, R10, or a parenthesized form, SPR(10).
@@ -975,13 +972,13 @@
 			return
 		}
 		if p.arch.Family == sys.PPC64 {
-			// Special form for PPC64: (R1+R2); alias for (R1)(R2*1).
+			// Special form for PPC64: (R1+R2); alias for (R1)(R2).
 			if prefix != 0 || scale != 0 {
 				p.errorf("illegal address mode for register+register")
 				return
 			}
 			a.Type = obj.TYPE_MEM
-			a.Scale = 1
+			a.Scale = 0
 			a.Index = r2
 			// Nothing may follow.
 			return
@@ -1014,9 +1011,10 @@
 				p.errorf("unimplemented two-register form")
 			}
 			a.Index = r1
-			if scale != 0 && scale != 1 && p.arch.Family == sys.ARM64 {
+			if scale != 0 && scale != 1 && (p.arch.Family == sys.ARM64 ||
+				p.arch.Family == sys.PPC64) {
 				// Support (R1)(R2) (no scaling) and (R1)(R2*1).
-				p.errorf("arm64 doesn't support scaled register format")
+				p.errorf("%s doesn't support scaled register format", p.arch.Name)
 			} else {
 				a.Scale = int16(scale)
 			}
diff --git a/src/cmd/asm/internal/asm/pseudo_test.go b/src/cmd/asm/internal/asm/pseudo_test.go
index fe6ffa6..5e6fcf8 100644
--- a/src/cmd/asm/internal/asm/pseudo_test.go
+++ b/src/cmd/asm/internal/asm/pseudo_test.go
@@ -5,7 +5,6 @@
 package asm
 
 import (
-	"bytes"
 	"strings"
 	"testing"
 
@@ -81,7 +80,7 @@
 	// Note these errors should be independent of the architecture.
 	// Just run the test with amd64.
 	parser := newParser("amd64")
-	var buf bytes.Buffer
+	var buf strings.Builder
 	parser.errorWriter = &buf
 
 	for _, cat := range testcats {
diff --git a/src/cmd/asm/internal/asm/testdata/arm64.s b/src/cmd/asm/internal/asm/testdata/arm64.s
index 4451338..a1493a7 100644
--- a/src/cmd/asm/internal/asm/testdata/arm64.s
+++ b/src/cmd/asm/internal/asm/testdata/arm64.s
@@ -95,6 +95,14 @@
 	// CLS
 	CLSW	R1, R2
 	CLS	R1, R2
+	SBC	$0, R1                           // 21001fda
+	SBCW	$0, R1                           // 21001f5a
+	SBCS	$0, R1                           // 21001ffa
+	SBCSW	$0, R1                           // 21001f7a
+	ADC	$0, R1                           // 21001f9a
+	ADCW	$0, R1                           // 21001f1a
+	ADCS	$0, R1                           // 21001fba
+	ADCSW	$0, R1                           // 21001f3a
 
 // fp/simd instructions.
 	VADDP	V1.B16, V2.B16, V3.B16          // 43bc214e
@@ -167,6 +175,22 @@
 	VTBL	V14.B16, [V3.B16, V4.B16, V5.B16], V17.B16                              // 71400e4e
 	VTBL	V13.B16, [V29.B16, V30.B16, V31.B16, V0.B16], V28.B16                   // bc630d4e
 	VTBL	V3.B8, [V27.B16], V8.B8                                                 // 6803030e
+	VTBX	V22.B16, [V28.B16, V29.B16], V11.B16                                    // 8b33164e
+	VTBX	V18.B8, [V17.B16, V18.B16, V19.B16], V22.B8                             // 3652120e
+	VTBX	V31.B8, [V14.B16, V15.B16, V16.B16, V17.B16], V15.B8                    // cf711f0e
+	VTBX	V14.B16, [V16.B16], V11.B16                                             // 0b120e4e
+	VTBX	V28.B16, [V25.B16, V26.B16], V5.B16                                     // 25331c4e
+	VTBX	V16.B8, [V4.B16, V5.B16, V6.B16], V12.B8                                // 8c50100e
+	VTBX	V4.B8, [V16.B16, V17.B16, V18.B16, V19.B16], V4.B8                      // 0472040e
+	VTBX	V15.B8, [V1.B16], V20.B8                                                // 34100f0e
+	VTBX	V26.B16, [V2.B16, V3.B16], V26.B16                                      // 5a301a4e
+	VTBX	V15.B8, [V6.B16, V7.B16, V8.B16], V2.B8                                 // c2500f0e
+	VTBX	V2.B16, [V27.B16, V28.B16, V29.B16, V30.B16], V18.B16                   // 7273024e
+	VTBX	V11.B16, [V13.B16], V27.B16                                             // bb110b4e
+	VTBX	V3.B8, [V7.B16, V8.B16], V25.B8                                         // f930030e
+	VTBX	V14.B16, [V3.B16, V4.B16, V5.B16], V17.B16                              // 71500e4e
+	VTBX	V13.B16, [V29.B16, V30.B16, V31.B16, V0.B16], V28.B16                   // bc730d4e
+	VTBX	V3.B8, [V27.B16], V8.B8                                                 // 6813030e
 	VZIP1	V16.H8, V3.H8, V19.H8           // 7338504e
 	VZIP2	V22.D2, V25.D2, V21.D2          // 357bd64e
 	VZIP1	V6.D2, V9.D2, V11.D2            // 2b39c64e
@@ -210,6 +234,10 @@
 	FMOVD	$(0.1796875), F2                // 02f0681e
 	FMOVS	$(0.96875), F3                  // 03f02d1e
 	FMOVD	$(28.0), F4                     // 0490671e
+	FMOVD	$0, F0                          // e003679e
+	FMOVS	$0, F0                          // e003271e
+	FMOVD	ZR, F0                          // e003679e
+	FMOVS	ZR, F0                          // e003271e
 	VUADDW	V9.B8, V12.H8, V14.H8           // 8e11292e
 	VUADDW	V13.H4, V10.S4, V11.S4          // 4b116d2e
 	VUADDW	V21.S2, V24.D2, V29.D2          // 1d13b52e
@@ -370,7 +398,7 @@
 	MOVD	$0x11110000, R1               // MOVD	$286326784, R1              // 2122a2d2
 	MOVD	$0xaaaa0000aaaa1111, R1       // MOVD	$-6149102338357718767, R1   // 212282d24155b5f24155f5f2
 	MOVD	$0x1111ffff1111aaaa, R1       // MOVD	$1230045644216969898, R1    // a1aa8a922122a2f22122e2f2
-	MOVD	$0, R1                        // 010080d2
+	MOVD	$0, R1                        // e1031faa
 	MOVD	$-1, R1                       // 01008092
 	MOVD	$0x210000, R0                 // MOVD	$2162688, R0                // 2004a0d2
 	MOVD	$0xffffffffffffaaaa, R1       // MOVD	$-21846, R1                 // a1aa8a92
@@ -480,6 +508,15 @@
 	FMOVQ.P	11(R10), F13                                    // 4db5c03c
 	FMOVQ.W	11(R20), F15                                    // 8fbec03c
 
+// storing $0 to memory, $0 will be replaced with ZR.
+	MOVD	$0, (R1)  // 3f0000f9
+	MOVW	$0, (R1)  // 3f0000b9
+	MOVWU	$0, (R1)  // 3f0000b9
+	MOVH	$0, (R1)  // 3f000079
+	MOVHU	$0, (R1)  // 3f000079
+	MOVB	$0, (R1)  // 3f000039
+	MOVBU	$0, (R1)  // 3f000039
+
 // small offset fits into instructions
 	MOVB	R1, 1(R2) // 41040039
 	MOVH	R1, 1(R2) // 41100078
@@ -1076,6 +1113,7 @@
 	MSR	$1, SPSel                          // bf4100d5
 	MSR	$9, DAIFSet                        // df4903d5
 	MSR	$6, DAIFClr                        // ff4603d5
+	MSR	$0, CPACR_EL1                      // 5f1018d5
 	MRS	ELR_EL1, R8                        // 284038d5
 	MSR	R16, ELR_EL1                       // 304018d5
 	MSR	R2, ACTLR_EL1                      // 221018d5
diff --git a/src/cmd/asm/internal/asm/testdata/arm64enc.s b/src/cmd/asm/internal/asm/testdata/arm64enc.s
index eff48ae..0ae00d2 100644
--- a/src/cmd/asm/internal/asm/testdata/arm64enc.s
+++ b/src/cmd/asm/internal/asm/testdata/arm64enc.s
@@ -263,7 +263,7 @@
    MOVKW $(3905<<0), R21                      // MOVKW $3905, R21              // 35e88172
    MOVKW $(3905<<16), R21                     // MOVKW $255918080, R21         // 35e8a172
    MOVK $(3905<<32), R21                      // MOVK $16771847290880, R21     // 35e8c1f2
-   MOVD $0, R5                                // 050080d2
+   MOVD $0, R5                                // e5031faa
    MSR $1, SPSel                              // bf4100d5
    MSR $9, DAIFSet                            // df4903d5
    MSR $6, DAIFClr                            // ff4603d5
diff --git a/src/cmd/asm/internal/asm/testdata/duperror.s b/src/cmd/asm/internal/asm/testdata/duperror.s
new file mode 100644
index 0000000..cd5934b
--- /dev/null
+++ b/src/cmd/asm/internal/asm/testdata/duperror.s
@@ -0,0 +1,14 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+TEXT foo(SB), 0, $0
+	RET
+TEXT foo(SB), 0, $0 // ERROR "symbol foo redeclared"
+	RET
+
+GLOBL bar(SB), 0, $8
+GLOBL bar(SB), 0, $8 // ERROR "symbol bar redeclared"
+
+DATA bar+0(SB)/8, $0
+DATA bar+0(SB)/8, $0 // ERROR "overlapping DATA entry for bar"
diff --git a/src/cmd/asm/internal/asm/testdata/loong64enc1.s b/src/cmd/asm/internal/asm/testdata/loong64enc1.s
index 56eb244..83bb6ec 100644
--- a/src/cmd/asm/internal/asm/testdata/loong64enc1.s
+++ b/src/cmd/asm/internal/asm/testdata/loong64enc1.s
@@ -41,8 +41,12 @@
 	SRL	R4, R5, R6	 	// a6901700
 	SRA	R4, R5			// a5101800
 	SRA	R4, R5, R6	 	// a6101800
+	ROTR	R4, R5			// a5101b00
+	ROTR	R4, R5, R6		// a6101b00
 	SLLV	R4, R5			// a5901800
 	SLLV	R4, R5, R6		// a6901800
+	ROTRV	R4, R5			// a5901b00
+	ROTRV	R4, R5, R6		// a6901b00
 	CLO	R4, R5			// 85100000
 	CLZ	R4, R5			// 85140000
 	ADDF	F4, F5			// a5900001
@@ -102,8 +106,12 @@
 	SRL	$4, R4			// 84904400
 	SRA	$4, R4, R5		// 85904800
 	SRA	$4, R4			// 84904800
+	ROTR	$4, R4, R5		// 85904c00
+	ROTR	$4, R4			// 84904c00
 	SLLV	$4, R4, R5		// 85104100
 	SLLV	$4, R4			// 84104100
+	ROTRV	$4, R4, R5		// 85104d00
+	ROTRV	$4, R4			// 84104d00
 	SYSCALL				// 00002b00
 	BEQ	R4, R5, 1(PC)		// 85040058
 	BEQ	R4, 1(PC)		// 80040058
@@ -180,6 +188,9 @@
 	SRLV	$32, R4, R5 		// 85804500
 	SRLV	$32, R4			// 84804500
 
+	MASKEQZ	R4, R5, R6		// a6101300
+	MASKNEZ	R4, R5, R6		// a6901300
+
 	MOVFD	F4, F5			// 85241901
 	MOVDF	F4, F5			// 85181901
 	MOVWF	F4, F5			// 85101d01
diff --git a/src/cmd/asm/internal/asm/testdata/ppc64.s b/src/cmd/asm/internal/asm/testdata/ppc64.s
index f307db3..367d7b7 100644
--- a/src/cmd/asm/internal/asm/testdata/ppc64.s
+++ b/src/cmd/asm/internal/asm/testdata/ppc64.s
@@ -8,6 +8,10 @@
 
 #include "../../../../../runtime/textflag.h"
 
+// In case of index mode instructions, usage of
+// (Rx)(R0) is equivalent to (Rx+R0)
+// In case of base+displacement mode instructions if
+// the offset is 0, usage of (Rx) is equivalent to 0(Rx)
 TEXT asmtest(SB),DUPOK|NOSPLIT,$0
 	// move constants
 	MOVD $1, R3                     // 38600001
@@ -24,60 +28,120 @@
 	MOVW $-32767, R5                // 38a08001
 	MOVW $-32768, R6                // 38c08000
 	MOVW $1234567, R5               // 6405001260a5d687
+	// Hex constant 0x80000001
+	MOVW $2147483649, R5            // 6405800060a50001
+	MOVD $2147483649, R5            // 6405800060a50001
+	// Hex constant 0xFFFFFFFF80000001
+	MOVD $-2147483647, R5    	// 3ca0800060a50001
 	MOVD 8(R3), R4                  // e8830008
 	MOVD (R3)(R4), R5               // 7ca4182a
+	MOVD (R3)(R0), R5               // 7ca0182a
+	MOVD (R3), R5                   // e8a30000
 	MOVW 4(R3), R4                  // e8830006
 	MOVW (R3)(R4), R5               // 7ca41aaa
+	MOVW (R3)(R0), R5               // 7ca01aaa
+	MOVW (R3), R5                   // e8a30002
 	MOVWZ 4(R3), R4                 // 80830004
 	MOVWZ (R3)(R4), R5              // 7ca4182e
+	MOVWZ (R3)(R0), R5              // 7ca0182e
+	MOVWZ (R3), R5                  // 80a30000
 	MOVH 4(R3), R4                  // a8830004
 	MOVH (R3)(R4), R5               // 7ca41aae
+	MOVH (R3)(R0), R5               // 7ca01aae
+	MOVH (R3), R5                   // a8a30000
+
 	MOVHZ 2(R3), R4                 // a0830002
 	MOVHZ (R3)(R4), R5              // 7ca41a2e
+	MOVHZ (R3)(R0), R5              // 7ca01a2e
+	MOVHZ (R3), R5                  // a0a30000
 	MOVB 1(R3), R4                  // 888300017c840774
 	MOVB (R3)(R4), R5               // 7ca418ae7ca50774
+	MOVB (R3)(R0), R5               // 7ca018ae7ca50774
+	MOVB (R3), R5                   // 88a300007ca50774
 	MOVBZ 1(R3), R4                 // 88830001
 	MOVBZ (R3)(R4), R5              // 7ca418ae
+	MOVBZ (R3)(R0), R5              // 7ca018ae
+	MOVBZ (R3), R5                  // 88a30000
 	MOVDBR (R3)(R4), R5             // 7ca41c28
+	MOVDBR (R3)(R0), R5             // 7ca01c28
+	MOVDBR (R3), R5                 // 7ca01c28
 	MOVWBR (R3)(R4), R5             // 7ca41c2c
+	MOVWBR (R3)(R0), R5             // 7ca01c2c
+	MOVWBR (R3), R5                 // 7ca01c2c
 	MOVHBR (R3)(R4), R5             // 7ca41e2c
+	MOVHBR (R3)(R0), R5             // 7ca01e2c
+	MOVHBR (R3), R5                 // 7ca01e2c
 	MOVD $foo+4009806848(FP), R5    // 3ca1ef0138a5cc40
 	MOVD $foo(SB), R5               // 3ca0000038a50000
 
 	MOVDU 8(R3), R4                 // e8830009
 	MOVDU (R3)(R4), R5              // 7ca4186a
+	MOVDU (R3)(R0), R5              // 7ca0186a
+	MOVDU (R3), R5                  // e8a30001
 	MOVWU (R3)(R4), R5              // 7ca41aea
+	MOVWU (R3)(R0), R5              // 7ca01aea
 	MOVWZU 4(R3), R4                // 84830004
 	MOVWZU (R3)(R4), R5             // 7ca4186e
+	MOVWZU (R3)(R0), R5             // 7ca0186e
+	MOVWZU (R3), R5                 // 84a30000
 	MOVHU 2(R3), R4                 // ac830002
 	MOVHU (R3)(R4), R5              // 7ca41aee
+	MOVHU (R3)(R0), R5              // 7ca01aee
+	MOVHU (R3), R5                  // aca30000
 	MOVHZU 2(R3), R4                // a4830002
 	MOVHZU (R3)(R4), R5             // 7ca41a6e
+	MOVHZU (R3)(R0), R5             // 7ca01a6e
+	MOVHZU (R3), R5                 // a4a30000
 	MOVBU 1(R3), R4                 // 8c8300017c840774
 	MOVBU (R3)(R4), R5              // 7ca418ee7ca50774
+	MOVBU (R3)(R0), R5              // 7ca018ee7ca50774
+	MOVBU (R3), R5                  // 8ca300007ca50774
 	MOVBZU 1(R3), R4                // 8c830001
 	MOVBZU (R3)(R4), R5             // 7ca418ee
+	MOVBZU (R3)(R0), R5             // 7ca018ee
+	MOVBZU (R3), R5                 // 8ca30000
 
 	MOVD R4, 8(R3)                  // f8830008
 	MOVD R5, (R3)(R4)               // 7ca4192a
+	MOVD R5, (R3)(R0)               // 7ca0192a
+	MOVD R5, (R3)                   // f8a30000
 	MOVW R4, 4(R3)                  // 90830004
 	MOVW R5, (R3)(R4)               // 7ca4192e
+	MOVW R5, (R3)(R0)               // 7ca0192e
+	MOVW R5, (R3)                   // 90a30000
 	MOVH R4, 2(R3)                  // b0830002
 	MOVH R5, (R3)(R4)               // 7ca41b2e
+	MOVH R5, (R3)(R0)               // 7ca01b2e
+	MOVH R5, (R3)                   // b0a30000
 	MOVB R4, 1(R3)                  // 98830001
 	MOVB R5, (R3)(R4)               // 7ca419ae
+	MOVB R5, (R3)(R0)               // 7ca019ae
+	MOVB R5, (R3)                   // 98a30000
 	MOVDBR R5, (R3)(R4)             // 7ca41d28
+	MOVDBR R5, (R3)(R0)             // 7ca01d28
+	MOVDBR R5, (R3)                 // 7ca01d28
 	MOVWBR R5, (R3)(R4)             // 7ca41d2c
+	MOVWBR R5, (R3)(R0)             // 7ca01d2c
+	MOVWBR R5, (R3)                 // 7ca01d2c
 	MOVHBR R5, (R3)(R4)             // 7ca41f2c
+	MOVHBR R5, (R3)(R0)             // 7ca01f2c
+	MOVHBR R5, (R3)                 // 7ca01f2c
 
 	MOVDU R4, 8(R3)                 // f8830009
 	MOVDU R5, (R3)(R4)              // 7ca4196a
+	MOVDU R5, (R3)(R0)              // 7ca0196a
+	MOVDU R5, (R3)                  // f8a30001
 	MOVWU R4, 4(R3)                 // 94830004
 	MOVWU R5, (R3)(R4)              // 7ca4196e
+	MOVWU R5, (R3)(R0)              // 7ca0196e
 	MOVHU R4, 2(R3)                 // b4830002
 	MOVHU R5, (R3)(R4)              // 7ca41b6e
+	MOVHU R5, (R3)(R0)              // 7ca01b6e
+	MOVHU R5, (R3)                  // b4a30000
 	MOVBU R4, 1(R3)                 // 9c830001
 	MOVBU R5, (R3)(R4)              // 7ca419ee
+	MOVBU R5, (R3)(R0)              // 7ca019ee
+	MOVBU R5, (R3)                  // 9ca30000
 
 	MOVB $0, R4                     // 38800000
 	MOVBZ $0, R4                    // 38800000
@@ -103,6 +167,7 @@
 	ADD $1234567, R5                // 641f001263ffd6877cbf2a14
 	ADD $1234567, R5, R6            // 641f001263ffd6877cdf2a14
 	ADDEX R3, R5, $3, R6            // 7cc32f54
+	ADDEX R3, $3, R5, R6            // 7cc32f54
 	ADDIS $8, R3                    // 3c630008
 	ADDIS $1000, R3, R4             // 3c8303e8
 
@@ -168,6 +233,7 @@
 	ADD R3, R4, R5                  // 7ca41a14
 	ADDC R3, R4                     // 7c841814
 	ADDC R3, R4, R5                 // 7ca41814
+	ADDCC R3, R4, R5                // 7ca41a15
 	ADDE R3, R4                     // 7c841914
 	ADDECC R3, R4                   // 7c841915
 	ADDEV R3, R4                    // 7c841d14
@@ -197,10 +263,12 @@
 	AND R3, R4, R5                  // 7c851838
 	ANDN R3, R4, R5                 // 7c851878
 	ANDCC R3, R4, R5                // 7c851839
+	ANDNCC R3, R4, R5               // 7c851879
 	OR R3, R4                       // 7c841b78
 	OR R3, R4, R5                   // 7c851b78
 	ORN R3, R4, R5                  // 7c851b38
 	ORCC R3, R4, R5                 // 7c851b79
+	ORNCC R3, R4, R5                // 7c851b39
 	XOR R3, R4                      // 7c841a78
 	XOR R3, R4, R5                  // 7c851a78
 	XORCC R3, R4, R5                // 7c851a79
@@ -215,6 +283,17 @@
 	SUB R3, R4, R5                  // 7ca32050
 	SUBC R3, R4                     // 7c832010
 	SUBC R3, R4, R5                 // 7ca32010
+	SUBCC R3, R4, R5                // 7ca32051
+	SUBVCC R3, R4, R5               // 7ca32451
+	SUBCCC R3, R4, R5               // 7ca32011
+	SUBCV R3, R4, R5                // 7ca32410
+	SUBCVCC R3, R4, R5              // 7ca32411
+	SUBMEVCC R3, R4                 // 7c8305d1
+	SUBV R3, R4, R5                 // 7ca32450
+	SUBE R3, R4, R5                 // 7ca32110
+	SUBECC R3, R4, R5               // 7ca32111
+	SUBEV R3, R4, R5                // 7ca32510
+	SUBEVCC R3, R4, R5              // 7ca32511
 
 	MULLW R3, R4                    // 7c8419d6
 	MULLW R3, R4, R5                // 7ca419d6
@@ -233,6 +312,8 @@
 	MULLDCC R3, R4, R5              // 7ca419d3
 	MULHD R3, R4, R5                // 7ca41892
 	MULHDCC R3, R4, R5              // 7ca41893
+	MULHDU R3, R4, R5               // 7ca41812
+	MULHDUCC R3, R4, R5             // 7ca41813
 
 	MULLWV R3, R4                   // 7c841dd6
 	MULLWV R3, R4, R5               // 7ca41dd6
@@ -243,13 +324,22 @@
 
 	DIVD R3,R4                      // 7c841bd2
 	DIVD R3, R4, R5                 // 7ca41bd2
+	DIVW R3, R4                     // 7c841bd6
+	DIVW R3, R4, R5                 // 7ca41bd6
 	DIVDCC R3,R4, R5                // 7ca41bd3
+	DIVWCC R3,R4, R5                // 7ca41bd7
 	DIVDU R3, R4, R5                // 7ca41b92
+	DIVWU R3, R4, R5                // 7ca41b96
 	DIVDV R3, R4, R5                // 7ca41fd2
+	DIVWV R3, R4, R5                // 7ca41fd6
 	DIVDUCC R3, R4, R5              // 7ca41b93
+	DIVWUCC R3, R4, R5              // 7ca41b97
 	DIVDVCC R3, R4, R5              // 7ca41fd3
+	DIVWVCC R3, R4, R5              // 7ca41fd7
 	DIVDUV R3, R4, R5               // 7ca41f92
 	DIVDUVCC R3, R4, R5             // 7ca41f93
+	DIVWUVCC R3, R4, R5             // 7ca41f97
+	DIVWUV   R3, R4, R5             // 7ca41f96
 	DIVDE R3, R4, R5                // 7ca41b52
 	DIVDECC R3, R4, R5              // 7ca41b53
 	DIVDEU R3, R4, R5               // 7ca41b12
@@ -289,7 +379,15 @@
 	SRDCC R3, R4                    // 7c841c37
 	ROTLW $16, R3, R4               // 5464803e
 	ROTLW R3, R4, R5                // 5c85183e
+	ROTL $16, R3, R4                // 78648000
 	EXTSWSLI $3, R4, R5             // 7c851ef4
+	EXTSWSLICC $16, R3, R4          // 7c6486f5
+	EXTSB R3, R4                    // 7c640774
+	EXTSBCC R3, R4                  // 7c640775
+	EXTSH R3, R4                    // 7c640734
+	EXTSHCC R3, R4                  // 7c640735
+	EXTSW R3, R4                    // 7c6407b4
+	EXTSWCC R3, R4                  // 7c6407b5
 	RLWMI $7, R3, $65535, R6        // 50663c3e
 	RLWMI $7, R3, $16, $31, R6      // 50663c3e
 	RLWMICC $7, R3, $65535, R6      // 50663c3f
@@ -322,6 +420,18 @@
 	CLRLSLDI $24, R4, $2, R3        // 78831588
 	RLDCR	$1, R1, $-16, R1        // 78210ee4
 	RLDCRCC	$1, R1, $-16, R1        // 78210ee5
+	CNTLZW R3,R4                    // 7c640034
+	CNTLZWCC R3,R4                  // 7c640035
+	CNTLZD R3, R4                   // 7c640074
+	CNTLZDCC R3, R4                 // 7c640075
+	CNTTZW R3,R4                    // 7c640434
+	CNTTZWCC R3,R4                  // 7c640435
+	CNTTZD R3,R4                    // 7c640474
+	CNTTZDCC R3,R4                  // 7c640475
+	NEG R3, R4                      // 7c8300d0
+	NEGCC R3, R4                    // 7c8300d1
+	NEGV R3, R4                     // 7c8304d0
+	NEGVCC R3, R4                   // 7c8304d1
 
 	BEQ 0(PC)                       // 41820000
 	BEQ CR1,0(PC)                   // 41860000
@@ -335,6 +445,8 @@
 	BLT CR5,0(PC)                   // 41940000
 	BNE 0(PC)                       // 40820000
 	BLT CR6,0(PC)                   // 41980000
+	BVC 0(PC)                       // 40830000
+	BVS 0(PC)                       // 41830000
 	JMP 8(PC)                       // 48000010
 
 	NOP
@@ -372,36 +484,77 @@
 
 	// load-and-reserve
 	LBAR (R4)(R3*1),$1,R5           // 7ca32069
+	LBAR (R4)(R0),$1,R5             // 7ca02069
 	LBAR (R4),$0,R5                 // 7ca02068
 	LBAR (R3),R5                    // 7ca01868
 	LHAR (R4)(R3*1),$1,R5           // 7ca320e9
+	LHAR (R4)(R0),$1,R5             // 7ca020e9
 	LHAR (R4),$0,R5                 // 7ca020e8
 	LHAR (R3),R5                    // 7ca018e8
 	LWAR (R4)(R3*1),$1,R5           // 7ca32029
+	LWAR (R4)(R0),$1,R5             // 7ca02029
 	LWAR (R4),$0,R5                 // 7ca02028
 	LWAR (R3),R5                    // 7ca01828
 	LDAR (R4)(R3*1),$1,R5           // 7ca320a9
+	LDAR (R4)(R0),$1,R5             // 7ca020a9
 	LDAR (R4),$0,R5                 // 7ca020a8
 	LDAR (R3),R5                    // 7ca018a8
 
+	LSW (R3)(R4), R5                // 7ca41c2a
+	LSW (R3)(R0), R5                // 7ca01c2a
+	LSW (R3), R5                    // 7ca01c2a
+
 	STBCCC R3, (R4)(R5)             // 7c65256d
+	STBCCC R3, (R4)(R0)             // 7c60256d
+	STBCCC R3, (R4)                 // 7c60256d
 	STWCCC R3, (R4)(R5)             // 7c65212d
+	STWCCC R3, (R4)(R0)             // 7c60212d
+	STWCCC R3, (R4)                 // 7c60212d
 	STDCCC R3, (R4)(R5)             // 7c6521ad
-	STHCCC R3, (R4)(R5)
-	STSW R3, (R4)(R5)
+	STDCCC R3, (R4)(R0)             // 7c6021ad
+	STDCCC R3, (R4)                 // 7c6021ad
+	STHCCC R3, (R4)(R5)             // 7c6525ad
+	STHCCC R3, (R4)(R0)             // 7c6025ad
+	STHCCC R3, (R4)                 // 7c6025ad
+	STSW R3, (R4)(R5)               // 7c65252a
+	STSW R3, (R4)(R0)               // 7c60252a
+	STSW R3, (R4)                   // 7c60252a
 
 	SYNC                            // 7c0004ac
 	ISYNC                           // 4c00012c
 	LWSYNC                          // 7c2004ac
+	EIEIO                           // 7c0006ac
+	PTESYNC                         // 7c4004ac
+	TLBIE R3                        // 7c001a64
+	TLBIEL R3                       // 7c001a24
+	TLBSYNC                         // 7c00046c
+	HRFID                           // 4c000224
+	SLBIA                           // 7c0003e4
+	SLBIE R3                        // 7c001b64
+	SLBMFEE R3, R4                  // 7c801f26
+	SLBMFEV R3, R4                  // 7c801ea6
+	SLBMTE R3, R4                   // 7c801b24
 
+	TW $31, R0, R0                  // 7fe00008
+	TD $31, R0, R0                  // 7fe00088
 	DARN $1, R5                     // 7ca105e6
 
 	DCBF (R3)(R4)                   // 7c0418ac
-	DCBI (R3)(R4)                   // 7c041bac
+	DCBF (R3)(R0)                   // 7c0018ac
+	DCBF (R3)                       // 7c0018ac
+
 	DCBST (R3)(R4)                  // 7c04186c
+	DCBST (R3)(R0)                  // 7c00186c
+	DCBST (R3)                      // 7c00186c
 	DCBZ (R3)(R4)                   // 7c041fec
+	DCBZ (R3)(R0)                   // 7c001fec
+	DCBZ (R3)                       // 7c001fec
 	DCBT (R3)(R4)                   // 7c041a2c
+	DCBT (R3)(R0)                   // 7c001a2c
+	DCBT (R3)                       // 7c001a2c
 	ICBI (R3)(R4)                   // 7c041fac
+	ICBI (R3)(R0)                   // 7c001fac
+	ICBI (R3)                       // 7c001fac
 
 	// float constants
 	FMOVD $(0.0), F1                // f0210cd0
@@ -409,24 +562,50 @@
 
 	FMOVD 8(R3), F1                 // c8230008
 	FMOVD (R3)(R4), F1              // 7c241cae
+	FMOVD (R3)(R0), F1              // 7c201cae
+	FMOVD (R3), F1                  // c8230000
 	FMOVDU 8(R3), F1                // cc230008
 	FMOVDU (R3)(R4), F1             // 7c241cee
+	FMOVDU (R3)(R0), F1             // 7c201cee
+	FMOVDU (R3), F1                 // cc230000
 	FMOVS 4(R3), F1                 // c0230004
 	FMOVS (R3)(R4), F1              // 7c241c2e
+	FMOVS (R3)(R0), F1              // 7c201c2e
+	FMOVS (R3), F1                  // c0230000
 	FMOVSU 4(R3), F1                // c4230004
 	FMOVSU (R3)(R4), F1             // 7c241c6e
+	FMOVSU (R3)(R0), F1             // 7c201c6e
+	FMOVSU (R3), F1                 // c4230000
+	FMOVSX (R3)(R4), F1             // 7c241eae
+	FMOVSX (R3)(R0), F1             // 7c201eae
+	FMOVSX (R3), F1                 // 7c201eae
+	FMOVSZ (R3)(R4), F1             // 7c241eee
+	FMOVSZ (R3)(R0), F1             // 7c201eee
+	FMOVSZ (R3), F1                 // 7c201eee
 
 	FMOVD F1, 8(R3)                 // d8230008
 	FMOVD F1, (R3)(R4)              // 7c241dae
+	FMOVD F1, (R3)(R0)              // 7c201dae
+	FMOVD F1, (R3)                  // d8230000
 	FMOVDU F1, 8(R3)                // dc230008
 	FMOVDU F1, (R3)(R4)             // 7c241dee
+	FMOVDU F1, (R3)(R0)             // 7c201dee
+	FMOVDU F1, (R3)                 // dc230000
 	FMOVS F1, 4(R3)                 // d0230004
 	FMOVS F1, (R3)(R4)              // 7c241d2e
+	FMOVS F1, (R3)(R0)              // 7c201d2e
+	FMOVS F1, (R3)                  // d0230000
 	FMOVSU F1, 4(R3)                // d4230004
 	FMOVSU F1, (R3)(R4)             // 7c241d6e
+	FMOVSU F1, (R3)(R0)             // 7c201d6e
+	FMOVSU F1, (R3)                 // d4230000
+	FMOVSX F1, (R3)(R4)             // 7c241fae
+	FMOVSX F1, (R3)(R0)             // 7c201fae
+	FMOVSX F1, (R3)                 // 7c201fae
 	FADD F1, F2                     // fc42082a
 	FADD F1, F2, F3                 // fc62082a
 	FADDCC F1, F2, F3               // fc62082b
+	FMOVDCC F1, F2                  // fc400891
 	FADDS F1, F2                    // ec42082a
 	FADDS F1, F2, F3                // ec62082a
 	FADDSCC F1, F2, F3              // ec62082b
@@ -436,6 +615,7 @@
 	FSUBS F1, F2                    // ec420828
 	FSUBS F1, F2, F3                // ec620828
 	FSUBCC F1, F2, F3               // fc620829
+	FSUBSCC F1, F2, F3              // ec620829
 	FMUL F1, F2                     // fc420072
 	FMUL F1, F2, F3                 // fc620072
 	FMULCC F1, F2, F3               // fc620073
@@ -448,6 +628,8 @@
 	FDIVS F1, F2                    // ec420824
 	FDIVS F1, F2, F3                // ec620824
 	FDIVSCC F1, F2, F3              // ec620825
+	FTDIV F1, F2, $2                // fd011100
+	FTSQRT F1, $2	                // fd000940
 	FMADD F1, F2, F3, F4            // fc8110fa
 	FMADDCC F1, F2, F3, F4          // fc8110fb
 	FMADDS F1, F2, F3, F4           // ec8110fa
@@ -467,8 +649,11 @@
 	FSEL F1, F2, F3, F4             // fc8110ee
 	FSELCC F1, F2, F3, F4           // fc8110ef
 	FABS F1, F2                     // fc400a10
+	FNABS F1, F2                    // fc400910
 	FABSCC F1, F2                   // fc400a11
+	FNABSCC F1, F2                  // fc400911
 	FNEG F1, F2                     // fc400850
+	FNEGCC F1, F2                   // fc400851
 	FABSCC F1, F2                   // fc400a11
 	FRSP F1, F2                     // fc400818
 	FRSPCC F1, F2                   // fc400819
@@ -507,17 +692,41 @@
 	FCMPO F1, F2                    // fc011040
 	FCMPU F1, F2                    // fc011000
 	LVX (R3)(R4), V1                // 7c2418ce
+	LVX (R3)(R0), V1                // 7c2018ce
+	LVX (R3), V1                    // 7c2018ce
 	LVXL (R3)(R4), V1               // 7c241ace
+	LVXL (R3)(R0), V1               // 7c201ace
+	LVXL (R3), V1                   // 7c201ace
 	LVSL (R3)(R4), V1               // 7c24180c
+	LVSL (R3)(R0), V1               // 7c20180c
+	LVSL (R3), V1                   // 7c20180c
 	LVSR (R3)(R4), V1               // 7c24184c
+	LVSR (R3)(R0), V1               // 7c20184c
+	LVSR (R3), V1                   // 7c20184c
 	LVEBX (R3)(R4), V1              // 7c24180e
+	LVEBX (R3)(R0), V1              // 7c20180e
+	LVEBX (R3), V1                  // 7c20180e
 	LVEHX (R3)(R4), V1              // 7c24184e
+	LVEHX (R3)(R0), V1              // 7c20184e
+	LVEHX (R3), V1                  // 7c20184e
 	LVEWX (R3)(R4), V1              // 7c24188e
+	LVEWX (R3)(R0), V1              // 7c20188e
+	LVEWX (R3), V1                  // 7c20188e
 	STVX V1, (R3)(R4)               // 7c2419ce
+	STVX V1, (R3)(R0)               // 7c2019ce
+	STVX V1, (R3)                   // 7c2019ce
 	STVXL V1, (R3)(R4)              // 7c241bce
+	STVXL V1, (R3)(R0)              // 7c201bce
+	STVXL V1, (R3)                  // 7c201bce
 	STVEBX V1, (R3)(R4)             // 7c24190e
+	STVEBX V1, (R3)(R0)             // 7c20190e
+	STVEBX V1, (R3)                 // 7c20190e
 	STVEHX V1, (R3)(R4)             // 7c24194e
+	STVEHX V1, (R3)(R0)             // 7c20194e
+	STVEHX V1, (R3)                 // 7c20194e
 	STVEWX V1, (R3)(R4)             // 7c24198e
+	STVEWX V1, (R3)(R0)             // 7c20198e
+	STVEWX V1, (R3)                 // 7c20198e
 
 	VAND V1, V2, V3                 // 10611404
 	VANDC V1, V2, V3                // 10611444
@@ -537,6 +746,11 @@
 	VADDUBS V1, V2, V3              // 10611200
 	VADDUHS V1, V2, V3              // 10611240
 	VADDUWS V1, V2, V3              // 10611280
+	VADDSBS V1, V2, V3              // 10611300
+	VADDSHS V1, V2, V3              // 10611340
+	VADDSWS V1, V2, V3              // 10611380
+	VADDEUQM V1, V2, V3, V4         // 108110fc
+	VADDECUQ V1, V2, V3, V4         // 108110fd
 	VSUBUBM V1, V2, V3              // 10611400
 	VSUBUHM V1, V2, V3              // 10611440
 	VSUBUWM V1, V2, V3              // 10611480
@@ -553,6 +767,7 @@
 	VSUBEUQM V1, V2, V3, V4         // 108110fe
 	VSUBECUQ V1, V2, V3, V4         // 108110ff
 	VMULESB V1, V2, V3              // 10611308
+	VMULESW V1, V2, V3              // 10611388
 	VMULOSB V1, V2, V3              // 10611108
 	VMULEUB V1, V2, V3              // 10611208
 	VMULOUB V1, V2, V3              // 10611008
@@ -582,6 +797,7 @@
 	VSRB V1, V2, V3                 // 10611204
 	VSRH V1, V2, V3                 // 10611244
 	VSRW V1, V2, V3                 // 10611284
+	VSRD V1, V2, V3                 // 106116c4
 	VSR V1, V2, V3                  // 106112c4
 	VSRO V1, V2, V3                 // 1061144c
 	VSLD V1, V2, V3                 // 106115c4
@@ -648,31 +864,66 @@
 	VNCIPHERLAST V1, V2, V3         // 10611549
 	VSBOX V1, V2                    // 104105c8
 	VSHASIGMAW $1, V1, $15, V2      // 10418e82
+	VSHASIGMAW $1, $15, V1, V2      // 10418e82
 	VSHASIGMAD $2, V1, $15, V2      // 104196c2
+	VSHASIGMAD $2, $15, V1, V2      // 104196c2
 
 	LXVD2X (R3)(R4), VS1            // 7c241e98
+	LXVD2X (R3)(R0), VS1            // 7c201e98
+	LXVD2X (R3), VS1                // 7c201e98
 	LXVDSX (R3)(R4), VS1            // 7c241a98
+	LXVDSX (R3)(R0), VS1            // 7c201a98
+	LXVDSX (R3), VS1                // 7c201a98
 	LXVH8X (R3)(R4), VS1            // 7c241e58
+	LXVH8X (R3)(R0), VS1            // 7c201e58
+	LXVH8X (R3), VS1                // 7c201e58
 	LXVB16X (R3)(R4), VS1           // 7c241ed8
+	LXVB16X (R3)(R0), VS1           // 7c201ed8
+	LXVB16X (R3), VS1               // 7c201ed8
 	LXVW4X (R3)(R4), VS1            // 7c241e18
+	LXVW4X (R3)(R0), VS1            // 7c201e18
+	LXVW4X (R3), VS1                // 7c201e18
 	LXV 16(R3), VS1                 // f4230011
+	LXV (R3), VS1                   // f4230001
 	LXV 16(R3), VS33                // f4230019
+	LXV (R3), VS33                  // f4230009
 	LXV 16(R3), V1                  // f4230019
+	LXV (R3), V1                    // f4230009
 	LXVL R3, R4, VS1                // 7c23221a
 	LXVLL R3, R4, VS1               // 7c23225a
 	LXVX R3, R4, VS1                // 7c232218
 	LXSDX (R3)(R4), VS1             // 7c241c98
+	LXSDX (R3)(R0), VS1             // 7c201c98
+	LXSDX (R3), VS1                 // 7c201c98
 	STXVD2X VS1, (R3)(R4)           // 7c241f98
+	STXVD2X VS1, (R3)(R0)           // 7c201f98
+	STXVD2X VS1, (R3)               // 7c201f98
+	STXVW4X VS1, (R3)(R4)           // 7c241f18
+	STXVW4X VS1, (R3)(R0)           // 7c201f18
+	STXVW4X VS1, (R3)               // 7c201f18
 	STXV VS1,16(R3)                 // f4230015
+	STXV VS1,(R3)                   // f4230005
 	STXVL VS1, R3, R4               // 7c23231a
 	STXVLL VS1, R3, R4              // 7c23235a
 	STXVX VS1, R3, R4               // 7c232318
 	STXVB16X VS1, (R4)(R5)          // 7c2527d8
+	STXVB16X VS1, (R4)(R0)          // 7c2027d8
+	STXVB16X VS1, (R4)              // 7c2027d8
 	STXVH8X VS1, (R4)(R5)           // 7c252758
-
+	STXVH8X VS1, (R4)(R0)           // 7c202758
+	STXVH8X VS1, (R4)               // 7c202758
 	STXSDX VS1, (R3)(R4)            // 7c241d98
+	STXSDX VS1, (R4)(R0)            // 7c202598
+	STXSDX VS1, (R4)                // 7c202598
 	LXSIWAX (R3)(R4), VS1           // 7c241898
+	LXSIWAX (R3)(R0), VS1           // 7c201898
+	LXSIWAX (R3), VS1               // 7c201898
+	LXSIWZX (R3)(R4), VS1           // 7c241818
+	LXSIWZX (R3)(R0), VS1           // 7c201818
+	LXSIWZX (R3), VS1               // 7c201818
 	STXSIWX VS1, (R3)(R4)           // 7c241918
+	STXSIWX VS1, (R3)(R0)           // 7c201918
+	STXSIWX VS1, (R3)               // 7c201918
 	MFVSRD VS1, R3                  // 7c230066
 	MTFPRD R3, F0                   // 7c030166
 	MFVRD V0, R3                    // 7c030067
@@ -688,6 +939,11 @@
 	MTVSRWA R4, VS31                // 7fe401a6
 	MTVSRWS R4, VS32                // 7c040327
 	MTVSRWZ R4, VS63                // 7fe401e7
+	MTFSB0 $2                       // fc40008c
+	MTFSB0CC $2                     // fc40008d
+	MTFSB1 $2                       // fc40004c
+	MTFSB1CC $2                     // fc40004d
+	XXBRQ VS0, VS1                  // f03f076c
 	XXBRD VS0, VS1                  // f037076c
 	XXBRW VS1, VS2                  // f04f0f6c
 	XXBRH VS2, VS3                  // f067176c
@@ -713,7 +969,11 @@
 	XXPERM VS1, VS2, VS3            // f06110d0
 	XXSLDWI VS1, VS2, $1, VS3       // f0611110
 	XXSLDWI V1, V2, $1, V3          // f0611117
+	XXSLDWI V1, $1, V2, V3          // f0611117
 	XXSLDWI VS33, VS34, $1, VS35    // f0611117
+	XXSLDWI VS33, $1, VS34, VS35    // f0611117
+	XXPERMDI VS33, VS34, $1, VS35   // f0611157
+	XXPERMDI VS33, $1, VS34, VS35   // f0611157
 	XSCVDPSP VS1, VS2               // f0400c24
 	XVCVDPSP VS1, VS2               // f0400e24
 	XSCVSXDDP VS1, VS2              // f0400de0
@@ -770,6 +1030,8 @@
 	MOVFL R1, $1                    // 7c301120
 	MOVFL R1, $128                  // 7c380120
 	MOVFL R1, $3                    // 7c203120
+	MOVMW 4(R3), R4                 // b8830004
+
 
 	// Verify supported bdnz/bdz encodings.
 	BC 16,0,0(PC)                   // BC $16, CR0LT, 0(PC) // 42000000
@@ -818,5 +1080,6 @@
 	MOVD XER, 4(R1)                 // 7fe102a6fbe10004
 	MOVD 4(R1), SPR(3)              // ebe100047fe303a6
 	MOVD 4(R1), XER                 // ebe100047fe103a6
+	PNOP                            // 0700000000000000
 
 	RET
diff --git a/src/cmd/asm/internal/asm/testdata/ppc64_p10.s b/src/cmd/asm/internal/asm/testdata/ppc64_p10.s
new file mode 100644
index 0000000..c0a22aa
--- /dev/null
+++ b/src/cmd/asm/internal/asm/testdata/ppc64_p10.s
@@ -0,0 +1,273 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This contains the valid opcode combinations available
+// in cmd/internal/obj/ppc64/asm9.go which exist for
+// POWER10/ISA 3.1.
+
+#include "../../../../../runtime/textflag.h"
+
+TEXT asmtest(SB), DUPOK|NOSPLIT, $0
+	BRD R1, R2                              // 7c220176
+	BRH R1, R2                              // 7c2201b6
+	BRW R1, R2                              // 7c220136
+	CFUGED R1, R2, R3                       // 7c2311b8
+	CNTLZDM R2, R3, R1                      // 7c411876
+	CNTTZDM R2, R3, R1                      // 7c411c76
+	DCFFIXQQ V1, F2                         // fc400fc4
+	DCTFIXQQ F2, V3                         // fc6117c4
+	LXVKQ $0, VS33                          // f03f02d1
+	LXVP 12352(R5), VS6                     // 18c53040
+	LXVPX (R1)(R2), VS4                     // 7c820a9a
+	LXVRBX (R1)(R2), VS4                    // 7c82081a
+	LXVRDX (R1)(R2), VS4                    // 7c8208da
+	LXVRHX (R1)(R2), VS4                    // 7c82085a
+	LXVRWX (R1)(R2), VS4                    // 7c82089a
+	MTVSRBM R1, V1                          // 10300e42
+	MTVSRBMI $5, V1                         // 10220015
+	MTVSRDM R1, V1                          // 10330e42
+	MTVSRHM R1, V1                          // 10310e42
+	MTVSRQM R1, V1                          // 10340e42
+	MTVSRWM R1, V1                          // 10320e42
+	PADDI R3, $1234567890, $1, R4           // 06104996388302d2
+	PADDI R0, $1234567890, $0, R4           // 06004996388002d2
+	PADDI R0, $1234567890, $1, R4           // 06104996388002d2
+	PDEPD R1, R2, R3                        // 7c231138
+	PEXTD R1, R2, R3                        // 7c231178
+	PLBZ 1234(R1), $0, R3                   // 06000000886104d260000000
+	// Note, PLD crosses a 64B boundary, and a nop is inserted between PLBZ and PLD
+	PLD 1234(R1), $0, R3                    // 04000000e46104d2
+	PLFD 1234(R1), $0, F3                   // 06000000c86104d2
+	PLFS 1234567890(R4), $0, F3             // 06004996c06402d2
+	PLFS 1234567890(R0), $1, F3             // 06104996c06002d2
+	PLHA 1234(R1), $0, R3                   // 06000000a86104d2
+	PLHZ 1234(R1), $0, R3                   // 06000000a06104d2
+	PLQ 1234(R1), $0, R4                    // 04000000e08104d2
+	PLWA 1234(R1), $0, R3                   // 04000000a46104d2
+	PLWZ 1234567890(R4), $0, R3             // 06004996806402d2
+	PLWZ 1234567890(R0), $1, R3             // 06104996806002d2
+	PLXSD 1234(R1), $0, V1                  // 04000000a82104d2
+	PLXSSP 5(R1), $0, V2                    // 04000000ac410005
+	PLXSSP 5(R0), $1, V2                    // 04100000ac400005
+	PLXV 12346891(R6), $1, VS44             // 041000bccd86660b
+	PLXVP 12345678(R4), $1, VS4             // 041000bce884614e
+	PMXVBF16GER2 VS1, VS2, $1, $2, $3, A1   // 0790c012ec811198
+	PMXVBF16GER2NN VS1, VS2, $1, $2, $3, A1 // 0790c012ec811790
+	PMXVBF16GER2NP VS1, VS2, $1, $2, $3, A1 // 0790c012ec811390
+	PMXVBF16GER2PN VS1, VS2, $1, $2, $3, A1 // 0790c012ec811590
+	PMXVBF16GER2PP VS1, VS2, $1, $2, $3, A1 // 0790c012ec811190
+	PMXVF16GER2 VS1, VS2, $1, $2, $3, A1    // 0790c012ec811098
+	PMXVF16GER2NN VS1, VS2, $1, $2, $3, A1  // 0790c012ec811690
+	PMXVF16GER2NP VS1, VS2, $1, $2, $3, A1  // 0790c012ec811290
+	PMXVF16GER2PN VS1, VS2, $1, $2, $3, A1  // 0790c012ec811490
+	PMXVF16GER2PP VS1, VS2, $1, $2, $3, A1  // 0790c012ec811090
+	PMXVF32GER VS1, VS2, $1, $2, A1         // 07900012ec8110d8
+	PMXVF32GERNN VS1, VS2, $1, $2, A1       // 07900012ec8116d0
+	PMXVF32GERNP VS1, VS2, $1, $2, A1       // 07900012ec8112d0
+	PMXVF32GERPN VS1, VS2, $1, $2, A1       // 07900012ec8114d0
+	PMXVF32GERPP VS1, VS2, $1, $2, A1       // 07900012ec8110d0
+	PMXVF64GER VS4, VS2, $1, $2, A1         // 07900018ec8411d8
+	PMXVF64GERNN VS4, VS2, $1, $2, A1       // 07900018ec8417d0
+	PMXVF64GERNP VS4, VS2, $1, $2, A1       // 07900018ec8413d0
+	PMXVF64GERPN VS4, VS2, $1, $2, A1       // 07900018ec8415d0
+	PMXVF64GERPP VS4, VS2, $1, $2, A1       // 07900018ec8411d0
+	PMXVI16GER2 VS1, VS2, $1, $2, $3, A1    // 0790c012ec811258
+	PMXVI16GER2PP VS1, VS2, $1, $2, $3, A1  // 0790c012ec811358
+	PMXVI16GER2S VS1, VS2, $1, $2, $3, A1   // 0790c012ec811158
+	PMXVI16GER2SPP VS1, VS2, $1, $2, $3, A1 // 0790c012ec811150
+	PMXVI4GER8 VS1, VS2, $1, $2, $3, A1     // 07900312ec811118
+	PMXVI4GER8PP VS1, VS2, $1, $2, $3, A1   // 07900312ec811110
+	PMXVI8GER4 VS1, VS2, $1, $2, $3, A1     // 07903012ec811018
+	PMXVI8GER4PP VS1, VS2, $1, $2, $3, A1   // 07903012ec811010
+	PMXVI8GER4SPP VS1, VS2, $1, $2, $3, A1  // 07903012ec811318
+	PNOP                                    // 0700000000000000
+	PSTB R1, $1, 12345678(R2)               // 061000bc9822614e
+	PSTD R1, $1, 12345678(R2)               // 041000bcf422614e
+	PSTFD F1, $1, 12345678(R2)              // 061000bcd822614e
+	PSTFS F1, $1, 123456789(R7)             // 0610075bd027cd15
+	PSTH R1, $1, 12345678(R2)               // 061000bcb022614e
+	PSTQ R2, $1, 12345678(R2)               // 041000bcf042614e
+	PSTW R1, $1, 12345678(R2)               // 061000bc9022614e
+	PSTW R24, $0, 45(R13)                   // 06000000930d002d
+	PSTXSD V1, $1, 12345678(R2)             // 041000bcb822614e
+	PSTXSSP V1, $1, 1234567890(R0)          // 04104996bc2002d2
+	PSTXSSP V1, $1, 1234567890(R1)          // 04104996bc2102d2
+	PSTXSSP V1, $0, 1234567890(R3)          // 04004996bc2302d2
+	PSTXV VS6, $1, 1234567890(R5)           // 04104996d8c502d2
+	PSTXVP VS2, $1, 12345678(R2)            // 041000bcf842614e
+	PSTXVP VS62, $0, 5555555(R3)            // 04000054fbe3c563
+	SETBC CR2EQ, R2                         // 7c4a0300
+	SETBCR CR2LT, R2                        // 7c480340
+	SETNBC CR2GT, R2                        // 7c490380
+	SETNBCR CR6SO, R2                       // 7c5b03c0
+	STXVP VS6, 12352(R5)                    // 18c53041
+	STXVPX VS22, (R1)(R2)                   // 7ec20b9a
+	STXVRBX VS2, (R1)(R2)                   // 7c42091a
+	STXVRDX VS2, (R1)(R2)                   // 7c4209da
+	STXVRHX VS2, (R1)(R2)                   // 7c42095a
+	STXVRWX VS2, (R1)(R2)                   // 7c42099a
+	VCFUGED V1, V2, V3                      // 1061154d
+	VCLRLB V1, R2, V3                       // 1061118d
+	VCLRRB V1, R2, V3                       // 106111cd
+	VCLZDM V1, V2, V3                       // 10611784
+	VCMPEQUQ V1, V2, V3                     // 106111c7
+	VCMPEQUQCC V1, V2, V3                   // 106115c7
+	VCMPGTSQ V1, V2, V3                     // 10611387
+	VCMPGTSQCC V1, V2, V3                   // 10611787
+	VCMPGTUQ V1, V2, V3                     // 10611287
+	VCMPGTUQCC V1, V2, V3                   // 10611687
+	VCMPSQ V1, V2, CR2                      // 11011141
+	VCMPUQ V1, V2, CR3                      // 11811101
+	VCNTMBB V1, $1, R3                      // 10790e42
+	VCNTMBD V1, $1, R3                      // 107f0e42
+	VCNTMBH V1, $1, R3                      // 107b0e42
+	VCNTMBW V1, $1, R3                      // 107d0e42
+	VCTZDM V1, V2, V3                       // 106117c4
+	VDIVESD V1, V2, V3                      // 106113cb
+	VDIVESQ V1, V2, V3                      // 1061130b
+	VDIVESW V1, V2, V3                      // 1061138b
+	VDIVEUD V1, V2, V3                      // 106112cb
+	VDIVEUQ V1, V2, V3                      // 1061120b
+	VDIVEUW V1, V2, V3                      // 1061128b
+	VDIVSD V1, V2, V3                       // 106111cb
+	VDIVSQ V1, V2, V3                       // 1061110b
+	VDIVSW V1, V2, V3                       // 1061118b
+	VDIVUD V1, V2, V3                       // 106110cb
+	VDIVUQ V1, V2, V3                       // 1061100b
+	VDIVUW V1, V2, V3                       // 1061108b
+	VEXPANDBM V1, V2                        // 10400e42
+	VEXPANDDM V1, V2                        // 10430e42
+	VEXPANDHM V1, V2                        // 10410e42
+	VEXPANDQM V1, V2                        // 10440e42
+	VEXPANDWM V1, V2                        // 10420e42
+	VEXTDDVLX V1, V2, R3, V4                // 108110de
+	VEXTDDVRX V1, V2, R3, V4                // 108110df
+	VEXTDUBVLX V1, V2, R3, V4               // 108110d8
+	VEXTDUBVRX V1, V2, R3, V4               // 108110d9
+	VEXTDUHVLX V1, V2, R3, V4               // 108110da
+	VEXTDUHVRX V1, V2, R3, V4               // 108110db
+	VEXTDUWVLX V1, V2, R3, V4               // 108110dc
+	VEXTDUWVRX V1, V2, R5, V3               // 1061115d
+	VEXTRACTBM V1, R2                       // 10480e42
+	VEXTRACTDM V1, R2                       // 104b0e42
+	VEXTRACTHM V1, R2                       // 10490e42
+	VEXTRACTQM V1, R2                       // 104c0e42
+	VEXTRACTWM V1, R6                       // 10ca0e42
+	VEXTSD2Q V1, V2                         // 105b0e02
+	VGNB V1, $1, R31                        // 13e10ccc
+	VINSBLX R1, R2, V3                      // 1061120f
+	VINSBRX R1, R2, V3                      // 1061130f
+	VINSBVLX R1, V1, V2                     // 1041080f
+	VINSBVRX R1, V1, V2                     // 1041090f
+	VINSD R1, $2, V2                        // 104209cf
+	VINSDLX R1, R2, V3                      // 106112cf
+	VINSDRX R1, R2, V3                      // 106113cf
+	VINSHLX R1, R2, V3                      // 1061124f
+	VINSHRX R1, R2, V3                      // 1061134f
+	VINSHVLX R1, V2, V3                     // 1061104f
+	VINSHVRX R1, V2, V3                     // 1061114f
+	VINSW R1, $4, V3                        // 106408cf
+	VINSWLX R1, R2, V3                      // 1061128f
+	VINSWRX R1, R2, V3                      // 1061138f
+	VINSWVLX R1, V2, V3                     // 1061108f
+	VINSWVRX R1, V2, V3                     // 1061118f
+	VMODSD V1, V2, V3                       // 106117cb
+	VMODSQ V1, V2, V3                       // 1061170b
+	VMODSW V1, V2, V3                       // 1061178b
+	VMODUD V1, V2, V3                       // 106116cb
+	VMODUQ V1, V2, V3                       // 1061160b
+	VMODUW V1, V2, V3                       // 1061168b
+	VMSUMCUD V1, V2, V3, V4                 // 108110d7
+	VMULESD V1, V2, V3                      // 106113c8
+	VMULEUD V1, V2, V3                      // 106112c8
+	VMULHSD V1, V2, V3                      // 106113c9
+	VMULHSW V1, V2, V3                      // 10611389
+	VMULHUD V1, V2, V3                      // 106112c9
+	VMULHUW V1, V2, V3                      // 10611289
+	VMULLD V1, V2, V3                       // 106111c9
+	VMULOSD V1, V2, V3                      // 106111c8
+	VMULOUD V1, V2, V3                      // 106110c8
+	VPDEPD V1, V2, V3                       // 106115cd
+	VPEXTD V1, V2, V3                       // 1061158d
+	VRLQ V1, V2, V3                         // 10611005
+	VRLQMI V1, V2, V3                       // 10611045
+	VRLQNM V1, V2, V3                       // 10611145
+	VSLDBI V1, V2, $3, V3                   // 106110d6
+	VSLQ V1, V2, V3                         // 10611105
+	VSRAQ V1, V2, V3                        // 10611305
+	VSRDBI V1, V2, $3, V4                   // 108112d6
+	VSRQ V1, V2, V3                         // 10611205
+	VSTRIBL V1, V2                          // 1040080d
+	VSTRIBLCC V1, V2                        // 10400c0d
+	VSTRIBR V1, V2                          // 1041080d
+	VSTRIBRCC V1, V2                        // 10410c0d
+	VSTRIHL V1, V2                          // 1042080d
+	VSTRIHLCC V1, V2                        // 10420c0d
+	VSTRIHR V1, V2                          // 1043080d
+	VSTRIHRCC V1, V2                        // 10430c0d
+	XSCMPEQQP V1, V2, V3                    // fc611088
+	XSCMPGEQP V1, V2, V3                    // fc611188
+	XSCMPGTQP V1, V2, V3                    // fc6111c8
+	XSCVQPSQZ V1, V2                        // fc480e88
+	XSCVQPUQZ V1, V2                        // fc400e88
+	XSCVSQQP V1, V2                         // fc4b0e88
+	XSCVUQQP V2, V3                         // fc631688
+	XSMAXCQP V1, V2, V3                     // fc611548
+	XSMINCQP V1, V2, V4                     // fc8115c8
+	XVBF16GER2 VS1, VS2, A1                 // ec811198
+	XVBF16GER2NN VS1, VS2, A1               // ec811790
+	XVBF16GER2NP VS1, VS2, A1               // ec811390
+	XVBF16GER2PN VS1, VS2, A1               // ec811590
+	XVBF16GER2PP VS1, VS2, A1               // ec811190
+	XVCVBF16SPN VS2, VS3                    // f070176c
+	XVCVSPBF16 VS1, VS4                     // f0910f6c
+	XVF16GER2 VS1, VS2, A1                  // ec811098
+	XVF16GER2NN VS1, VS2, A1                // ec811690
+	XVF16GER2NP VS1, VS2, A1                // ec811290
+	XVF16GER2PN VS1, VS2, A1                // ec811490
+	XVF16GER2PP VS1, VS2, A1                // ec811090
+	XVF32GER VS1, VS2, A1                   // ec8110d8
+	XVF32GERNN VS1, VS2, A1                 // ec8116d0
+	XVF32GERNP VS1, VS2, A1                 // ec8112d0
+	XVF32GERPN VS1, VS2, A1                 // ec8114d0
+	XVF32GERPP VS1, VS2, A1                 // ec8110d0
+	XVF64GER VS2, VS1, A1                   // ec8209d8
+	XVF64GERNN VS2, VS1, A1                 // ec820fd0
+	XVF64GERNP VS2, VS1, A1                 // ec820bd0
+	XVF64GERPN VS2, VS1, A1                 // ec820dd0
+	XVF64GERPP VS2, VS1, A1                 // ec8209d0
+	XVI16GER2 VS1, VS2, A1                  // ec811258
+	XVI16GER2PP VS1, VS2, A1                // ec811358
+	XVI16GER2S VS1, VS2, A1                 // ec811158
+	XVI16GER2SPP VS1, VS2, A1               // ec811150
+	XVI4GER8 VS1, VS2, A1                   // ec811118
+	XVI4GER8PP VS1, VS2, A1                 // ec811110
+	XVI8GER4 VS1, VS2, A1                   // ec811018
+	XVI8GER4PP VS1, VS2, A1                 // ec811010
+	XVI8GER4SPP VS4, VS6, A1                // ec843318
+	XVTLSBB VS1, CR2                        // f1020f6c
+	XXBLENDVB VS1, VS3, VS7, VS11           // 05000000856119c0
+	XXBLENDVD VS1, VS3, VS7, VS11           // 05000000856119f0
+	XXBLENDVH VS1, VS3, VS7, VS11           // 05000000856119d0
+	XXBLENDVW VS1, VS3, VS7, VS11           // 05000000856119e0
+	XXEVAL VS1, VS2, VS3, $2, VS4           // 05000002888110d0
+	XXGENPCVBM V2, $2, VS3                  // f0621728
+	XXGENPCVDM V2, $2, VS3                  // f062176a
+	XXGENPCVHM V2, $2, VS3                  // f062172a
+	XXGENPCVWM V2, $2, VS3                  // f0621768
+	XXMFACC A1                              // 7c800162
+	XXMTACC A1                              // 7c810162
+	XXPERMX VS1, VS34, VS2, $2, VS3         // 0500000288611082
+	XXSETACCZ A1                            // 7c830162
+	XXSPLTI32DX $1, $1234, VS3              // 05000000806204d2
+	XXSPLTIDP $12345678, VS4                // 050000bc8084614e
+	XXSPLTIW $123456, VS3                   // 050000018066e240
+
+	// ISA 3.1B
+	HASHST R2, -8(R1)                       // 7fe115a5
+	HASHSTP R2, -8(R1)                      // 7fe11525
+	HASHCHK -8(R1), R2                      // 7fe115e5
+	HASHCHKP -8(R1), R2                     // 7fe11565
+
+        RET
diff --git a/src/cmd/asm/internal/flags/flags.go b/src/cmd/asm/internal/flags/flags.go
index 1c8b908..b9a94a0 100644
--- a/src/cmd/asm/internal/flags/flags.go
+++ b/src/cmd/asm/internal/flags/flags.go
@@ -73,8 +73,7 @@
 }
 
 func Parse() {
-	flag.Usage = Usage
-	flag.Parse()
+	objabi.Flagparse(Usage)
 	if flag.NArg() == 0 {
 		flag.Usage()
 	}
@@ -85,9 +84,7 @@
 			flag.Usage()
 		}
 		input := filepath.Base(flag.Arg(0))
-		if strings.HasSuffix(input, ".s") {
-			input = input[:len(input)-2]
-		}
+		input = strings.TrimSuffix(input, ".s")
 		*OutputFile = fmt.Sprintf("%s.o", input)
 	}
 }
diff --git a/src/cmd/asm/internal/lex/lex_test.go b/src/cmd/asm/internal/lex/lex_test.go
index 51679d2..e8dcf4b 100644
--- a/src/cmd/asm/internal/lex/lex_test.go
+++ b/src/cmd/asm/internal/lex/lex_test.go
@@ -5,7 +5,6 @@
 package lex
 
 import (
-	"bytes"
 	"strings"
 	"testing"
 	"text/scanner"
@@ -275,7 +274,7 @@
 
 // drain returns a single string representing the processed input tokens.
 func drain(input *Input) string {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	for {
 		tok := input.Next()
 		if tok == scanner.EOF {
diff --git a/src/cmd/asm/internal/lex/tokenizer.go b/src/cmd/asm/internal/lex/tokenizer.go
index 4db88e2..f60f7a1 100644
--- a/src/cmd/asm/internal/lex/tokenizer.go
+++ b/src/cmd/asm/internal/lex/tokenizer.go
@@ -5,6 +5,7 @@
 package lex
 
 import (
+	"go/build/constraint"
 	"io"
 	"os"
 	"strings"
@@ -109,8 +110,7 @@
 		}
 		text := s.TokenText()
 		t.line += strings.Count(text, "\n")
-		// TODO: Use constraint.IsGoBuild once #44505 fixed.
-		if strings.HasPrefix(text, "//go:build") {
+		if constraint.IsGoBuild(text) {
 			t.tok = BuildComment
 			break
 		}
diff --git a/src/cmd/cgo/ast.go b/src/cmd/cgo/ast.go
index 28879e3..81060c6 100644
--- a/src/cmd/cgo/ast.go
+++ b/src/cmd/cgo/ast.go
@@ -52,8 +52,8 @@
 	// and reprinting.
 	// In cgo mode, we ignore ast2 and just apply edits directly
 	// the text behind ast1. In godefs mode we modify and print ast2.
-	ast1 := parse(abspath, src, parser.ParseComments)
-	ast2 := parse(abspath, src, 0)
+	ast1 := parse(abspath, src, parser.SkipObjectResolution|parser.ParseComments)
+	ast2 := parse(abspath, src, parser.SkipObjectResolution)
 
 	f.Package = ast1.Name.Name
 	f.Name = make(map[string]*Name)
@@ -409,6 +409,9 @@
 	case *ast.StructType:
 		f.walk(n.Fields, ctxField, visit)
 	case *ast.FuncType:
+		if tparams := funcTypeTypeParams(n); tparams != nil {
+			f.walk(tparams, ctxParam, visit)
+		}
 		f.walk(n.Params, ctxParam, visit)
 		if n.Results != nil {
 			f.walk(n.Results, ctxParam, visit)
@@ -496,6 +499,9 @@
 			f.walk(n.Values, ctxExpr, visit)
 		}
 	case *ast.TypeSpec:
+		if tparams := typeSpecTypeParams(n); tparams != nil {
+			f.walk(tparams, ctxParam, visit)
+		}
 		f.walk(&n.Type, ctxType, visit)
 
 	case *ast.BadDecl:
diff --git a/src/cmd/cgo/ast_go1.go b/src/cmd/cgo/ast_go1.go
index f52bf00..2f65f0f 100644
--- a/src/cmd/cgo/ast_go1.go
+++ b/src/cmd/cgo/ast_go1.go
@@ -3,11 +3,11 @@
 // license that can be found in the LICENSE file.
 
 //go:build compiler_bootstrap
-// +build compiler_bootstrap
 
 package main
 
 import (
+	"go/ast"
 	"go/token"
 )
 
@@ -15,3 +15,11 @@
 	error_(token.NoPos, "unexpected type %T in walk", x)
 	panic("unexpected type")
 }
+
+func funcTypeTypeParams(n *ast.FuncType) *ast.FieldList {
+	return nil
+}
+
+func typeSpecTypeParams(n *ast.TypeSpec) *ast.FieldList {
+	return nil
+}
diff --git a/src/cmd/cgo/ast_go118.go b/src/cmd/cgo/ast_go118.go
index db0108e..ced3072 100644
--- a/src/cmd/cgo/ast_go118.go
+++ b/src/cmd/cgo/ast_go118.go
@@ -3,7 +3,6 @@
 // license that can be found in the LICENSE file.
 
 //go:build !compiler_bootstrap
-// +build !compiler_bootstrap
 
 package main
 
@@ -23,3 +22,11 @@
 		f.walk(n.Indices, ctxExpr, visit)
 	}
 }
+
+func funcTypeTypeParams(n *ast.FuncType) *ast.FieldList {
+	return n.TypeParams
+}
+
+func typeSpecTypeParams(n *ast.TypeSpec) *ast.FieldList {
+	return n.TypeParams
+}
diff --git a/src/cmd/cgo/doc.go b/src/cmd/cgo/doc.go
index 7fb6179..70685c7 100644
--- a/src/cmd/cgo/doc.go
+++ b/src/cmd/cgo/doc.go
@@ -119,13 +119,15 @@
 local version in preference to any other version.
 
 The cgo tool is enabled by default for native builds on systems where
-it is expected to work. It is disabled by default when
-cross-compiling. You can control this by setting the CGO_ENABLED
+it is expected to work. It is disabled by default when cross-compiling
+as well as when the CC environment variable is unset and the default
+C compiler (typically gcc or clang) cannot be found on the system PATH.
+You can override the default by setting the CGO_ENABLED
 environment variable when running the go tool: set it to 1 to enable
 the use of cgo, and to 0 to disable it. The go tool will set the
 build constraint "cgo" if cgo is enabled. The special import "C"
 implies the "cgo" build constraint, as though the file also said
-"// +build cgo".  Therefore, if cgo is disabled, files that import
+"//go:build cgo".  Therefore, if cgo is disabled, files that import
 "C" will not be built by the go tool. (For more about build constraints
 see https://golang.org/pkg/go/build/#hdr-Build_Constraints).
 
@@ -498,6 +500,9 @@
 		The -fgo-prefix option to be used with gccgo.
 	-gccgopkgpath path
 		The -fgo-pkgpath option to be used with gccgo.
+	-gccgo_define_cgoincomplete
+		Define cgo.Incomplete locally rather than importing it from
+		the "runtime/cgo" package. Used for old gccgo versions.
 	-godefs
 		Write out input file in Go syntax replacing C package
 		names with real values. Used to generate files in the
diff --git a/src/cmd/cgo/gcc.go b/src/cmd/cgo/gcc.go
index d89bff2..5df4a8c 100644
--- a/src/cmd/cgo/gcc.go
+++ b/src/cmd/cgo/gcc.go
@@ -47,6 +47,8 @@
 	"complexdouble": "double _Complex",
 }
 
+var incomplete = "_cgopackage.Incomplete"
+
 // cname returns the C name to use for C.s.
 // The expansions are listed in nameToC and also
 // struct_foo becomes "struct foo", and similarly for
@@ -2154,8 +2156,8 @@
 	// Type names X for which there exists an XGetTypeID function with type func() CFTypeID.
 	getTypeIDs map[string]bool
 
-	// badStructs contains C structs that should be marked NotInHeap.
-	notInHeapStructs map[string]bool
+	// incompleteStructs contains C structs that should be marked Incomplete.
+	incompleteStructs map[string]bool
 
 	// Predeclared types.
 	bool                                   ast.Expr
@@ -2168,7 +2170,6 @@
 	string                                 ast.Expr
 	goVoid                                 ast.Expr // _Ctype_void, denotes C's void
 	goVoidPtr                              ast.Expr // unsafe.Pointer or *byte
-	goVoidPtrNoHeap                        ast.Expr // *_Ctype_void_notinheap, like goVoidPtr but marked NotInHeap
 
 	ptrSize int64
 	intSize int64
@@ -2192,7 +2193,7 @@
 	c.m = make(map[string]*Type)
 	c.ptrs = make(map[string][]*Type)
 	c.getTypeIDs = make(map[string]bool)
-	c.notInHeapStructs = make(map[string]bool)
+	c.incompleteStructs = make(map[string]bool)
 	c.bool = c.Ident("bool")
 	c.byte = c.Ident("byte")
 	c.int8 = c.Ident("int8")
@@ -2211,7 +2212,6 @@
 	c.void = c.Ident("void")
 	c.string = c.Ident("string")
 	c.goVoid = c.Ident("_Ctype_void")
-	c.goVoidPtrNoHeap = c.Ident("*_Ctype_void_notinheap")
 
 	// Normally cgo translates void* to unsafe.Pointer,
 	// but for historical reasons -godefs uses *byte instead.
@@ -2222,7 +2222,7 @@
 	}
 }
 
-// base strips away qualifiers and typedefs to get the underlying type
+// base strips away qualifiers and typedefs to get the underlying type.
 func base(dt dwarf.Type) dwarf.Type {
 	for {
 		if d, ok := dt.(*dwarf.QualType); ok {
@@ -2561,19 +2561,13 @@
 			// other than try to determine a Go representation.
 			tt := *t
 			tt.C = &TypeRepr{"%s %s", []interface{}{dt.Kind, tag}}
-			tt.Go = c.Ident("struct{}")
-			if dt.Kind == "struct" {
-				// We don't know what the representation of this struct is, so don't let
-				// anyone allocate one on the Go side. As a side effect of this annotation,
-				// pointers to this type will not be considered pointers in Go. They won't
-				// get writebarrier-ed or adjusted during a stack copy. This should handle
-				// all the cases badPointerTypedef used to handle, but hopefully will
-				// continue to work going forward without any more need for cgo changes.
-				tt.NotInHeap = true
-				// TODO: we should probably do the same for unions. Unions can't live
-				// on the Go heap, right? It currently doesn't work for unions because
-				// they are defined as a type alias for struct{}, not a defined type.
-			}
+			// We don't know what the representation of this struct is, so don't let
+			// anyone allocate one on the Go side. As a side effect of this annotation,
+			// pointers to this type will not be considered pointers in Go. They won't
+			// get writebarrier-ed or adjusted during a stack copy. This should handle
+			// all the cases badPointerTypedef used to handle, but hopefully will
+			// continue to work going forward without any more need for cgo changes.
+			tt.Go = c.Ident(incomplete)
 			typedef[name.Name] = &tt
 			break
 		}
@@ -2599,7 +2593,9 @@
 				tt.C = &TypeRepr{"struct %s", []interface{}{tag}}
 			}
 			tt.Go = g
-			tt.NotInHeap = c.notInHeapStructs[tag]
+			if c.incompleteStructs[tag] {
+				tt.Go = c.Ident(incomplete)
+			}
 			typedef[name.Name] = &tt
 		}
 
@@ -2644,9 +2640,9 @@
 			}
 		}
 		if c.badVoidPointerTypedef(dt) {
-			// Treat this typedef as a pointer to a NotInHeap void.
+			// Treat this typedef as a pointer to a _cgopackage.Incomplete.
 			s := *sub
-			s.Go = c.goVoidPtrNoHeap
+			s.Go = c.Ident("*" + incomplete)
 			sub = &s
 			// Make sure we update any previously computed type.
 			if oldType := typedef[name.Name]; oldType != nil {
@@ -2654,22 +2650,21 @@
 			}
 		}
 		// Check for non-pointer "struct <tag>{...}; typedef struct <tag> *<name>"
-		// typedefs that should be marked NotInHeap.
+		// typedefs that should be marked Incomplete.
 		if ptr, ok := dt.Type.(*dwarf.PtrType); ok {
 			if strct, ok := ptr.Type.(*dwarf.StructType); ok {
 				if c.badStructPointerTypedef(dt.Name, strct) {
-					c.notInHeapStructs[strct.StructName] = true
+					c.incompleteStructs[strct.StructName] = true
 					// Make sure we update any previously computed type.
 					name := "_Ctype_struct_" + strct.StructName
 					if oldType := typedef[name]; oldType != nil {
-						oldType.NotInHeap = true
+						oldType.Go = c.Ident(incomplete)
 					}
 				}
 			}
 		}
 		t.Go = name
 		t.BadPointer = sub.BadPointer
-		t.NotInHeap = sub.NotInHeap
 		if unionWithPointer[sub.Go] {
 			unionWithPointer[t.Go] = true
 		}
@@ -2680,7 +2675,6 @@
 			tt := *t
 			tt.Go = sub.Go
 			tt.BadPointer = sub.BadPointer
-			tt.NotInHeap = sub.NotInHeap
 			typedef[name.Name] = &tt
 		}
 
@@ -2923,7 +2917,7 @@
 	// Minimum alignment for a struct is 1 byte.
 	align = 1
 
-	var buf bytes.Buffer
+	var buf strings.Builder
 	buf.WriteString("struct {")
 	fld := make([]*ast.Field, 0, 2*len(dt.Field)+1) // enough for padding around every field
 	sizes := make([]int64, 0, 2*len(dt.Field)+1)
@@ -3204,7 +3198,7 @@
 // non-pointers in this type.
 // TODO: Currently our best solution is to find these manually and list them as
 // they come up. A better solution is desired.
-// Note: DEPRECATED. There is now a better solution. Search for NotInHeap in this file.
+// Note: DEPRECATED. There is now a better solution. Search for incomplete in this file.
 func (c *typeConv) badPointerTypedef(dt *dwarf.TypedefType) bool {
 	if c.badCFType(dt) {
 		return true
@@ -3218,7 +3212,7 @@
 	return false
 }
 
-// badVoidPointerTypedef is like badPointerTypeDef, but for "void *" typedefs that should be NotInHeap.
+// badVoidPointerTypedef is like badPointerTypeDef, but for "void *" typedefs that should be _cgopackage.Incomplete.
 func (c *typeConv) badVoidPointerTypedef(dt *dwarf.TypedefType) bool {
 	// Match the Windows HANDLE type (#42018).
 	if goos != "windows" || dt.Name != "HANDLE" {
diff --git a/src/cmd/cgo/godefs.go b/src/cmd/cgo/godefs.go
index 3a27b31..f628670 100644
--- a/src/cmd/cgo/godefs.go
+++ b/src/cmd/cgo/godefs.go
@@ -5,7 +5,6 @@
 package main
 
 import (
-	"bytes"
 	"fmt"
 	"go/ast"
 	"go/printer"
@@ -17,7 +16,7 @@
 
 // godefs returns the output for -godefs mode.
 func (p *Package) godefs(f *File, args []string) string {
-	var buf bytes.Buffer
+	var buf strings.Builder
 
 	fmt.Fprintf(&buf, "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n")
 	fmt.Fprintf(&buf, "// %s %s\n", filepath.Base(args[0]), strings.Join(args[1:], " "))
@@ -115,7 +114,7 @@
 	return buf.String()
 }
 
-var gofmtBuf bytes.Buffer
+var gofmtBuf strings.Builder
 
 // gofmt returns the gofmt-formatted string for an AST node.
 func gofmt(n interface{}) string {
diff --git a/src/cmd/cgo/main.go b/src/cmd/cgo/main.go
index e343459..f78969e 100644
--- a/src/cmd/cgo/main.go
+++ b/src/cmd/cgo/main.go
@@ -18,7 +18,6 @@
 	"go/token"
 	"internal/buildcfg"
 	"io"
-	"io/ioutil"
 	"os"
 	"path/filepath"
 	"reflect"
@@ -153,7 +152,6 @@
 	EnumValues map[string]int64
 	Typedef    string
 	BadPointer bool // this pointer type should be represented as a uintptr (deprecated)
-	NotInHeap  bool // this type should have a go:notinheap annotation
 }
 
 // A FuncType collects information about a function type in both the C and Go worlds.
@@ -244,6 +242,7 @@
 var gccgoprefix = flag.String("gccgoprefix", "", "-fgo-prefix option used with gccgo")
 var gccgopkgpath = flag.String("gccgopkgpath", "", "-fgo-pkgpath option used with gccgo")
 var gccgoMangler func(string) string
+var gccgoDefineCgoIncomplete = flag.Bool("gccgo_define_cgoincomplete", false, "define cgo.Incomplete for older gccgo/GoLLVM")
 var importRuntimeCgo = flag.Bool("import_runtime_cgo", true, "import runtime/cgo in generated code")
 var importSyscall = flag.Bool("import_syscall", true, "import syscall in generated code")
 var trimpath = flag.String("trimpath", "", "applies supplied rewrites or trims prefixes to recorded source file paths")
@@ -253,8 +252,15 @@
 
 func main() {
 	objabi.AddVersionFlag() // -V
-	flag.Usage = usage
-	flag.Parse()
+	objabi.Flagparse(usage)
+
+	if *gccgoDefineCgoIncomplete {
+		if !*gccgo {
+			fmt.Fprintf(os.Stderr, "cgo: -gccgo_define_cgoincomplete without -gccgo\n")
+			os.Exit(2)
+		}
+		incomplete = "_cgopackage_Incomplete"
+	}
 
 	if *dynobj != "" {
 		// cgo -dynimport is essentially a separate helper command
@@ -347,7 +353,7 @@
 			input = aname
 		}
 
-		b, err := ioutil.ReadFile(input)
+		b, err := os.ReadFile(input)
 		if err != nil {
 			fatalf("%s", err)
 		}
diff --git a/src/cmd/cgo/out.go b/src/cmd/cgo/out.go
index 119eca2..d26f9e7 100644
--- a/src/cmd/cgo/out.go
+++ b/src/cmd/cgo/out.go
@@ -43,7 +43,7 @@
 	}
 	fm := creat(*objDir + "_cgo_main.c")
 
-	var gccgoInit bytes.Buffer
+	var gccgoInit strings.Builder
 
 	fflg := creat(*objDir + "_cgo_flags")
 	for k, v := range p.CgoFlags {
@@ -81,11 +81,19 @@
 	fmt.Fprintf(fgo2, "// Code generated by cmd/cgo; DO NOT EDIT.\n\n")
 	fmt.Fprintf(fgo2, "package %s\n\n", p.PackageName)
 	fmt.Fprintf(fgo2, "import \"unsafe\"\n\n")
-	if !*gccgo && *importRuntimeCgo {
-		fmt.Fprintf(fgo2, "import _ \"runtime/cgo\"\n\n")
-	}
 	if *importSyscall {
 		fmt.Fprintf(fgo2, "import \"syscall\"\n\n")
+	}
+	if *importRuntimeCgo {
+		if !*gccgoDefineCgoIncomplete {
+			fmt.Fprintf(fgo2, "import _cgopackage \"runtime/cgo\"\n\n")
+			fmt.Fprintf(fgo2, "type _ _cgopackage.Incomplete\n") // prevent import-not-used error
+		} else {
+			fmt.Fprintf(fgo2, "//go:notinheap\n")
+			fmt.Fprintf(fgo2, "type _cgopackage_Incomplete struct{ _ struct{ _ struct{} } }\n")
+		}
+	}
+	if *importSyscall {
 		fmt.Fprintf(fgo2, "var _ syscall.Errno\n")
 	}
 	fmt.Fprintf(fgo2, "func _Cgo_ptr(ptr unsafe.Pointer) unsafe.Pointer { return ptr }\n\n")
@@ -109,9 +117,6 @@
 	sort.Strings(typedefNames)
 	for _, name := range typedefNames {
 		def := typedef[name]
-		if def.NotInHeap {
-			fmt.Fprintf(fgo2, "//go:notinheap\n")
-		}
 		fmt.Fprintf(fgo2, "type %s ", name)
 		// We don't have source info for these types, so write them out without source info.
 		// Otherwise types would look like:
@@ -136,7 +141,6 @@
 		fmt.Fprintf(fgo2, "%s", buf.Bytes())
 		fmt.Fprintf(fgo2, "\n\n")
 	}
-	fmt.Fprintf(fgo2, "//go:notinheap\ntype _Ctype_void_notinheap struct{}\n\n")
 	if *gccgo {
 		fmt.Fprintf(fgo2, "type _Ctype_void byte\n")
 	} else {
@@ -428,7 +432,7 @@
 			fatalf("dynamic symbol %q contains unsupported character", s)
 		}
 	}
-	if strings.Index(s, "//") >= 0 || strings.Index(s, "/*") >= 0 {
+	if strings.Contains(s, "//") || strings.Contains(s, "/*") {
 		fatalf("dynamic symbol %q contains Go comment")
 	}
 }
@@ -439,7 +443,7 @@
 // Also assumes that gc convention is to word-align the
 // input and output parameters.
 func (p *Package) structType(n *Name) (string, int64) {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	fmt.Fprint(&buf, "struct {\n")
 	off := int64(0)
 	for i, t := range n.FuncType.Params {
@@ -628,9 +632,7 @@
 // writeOutput creates stubs for a specific source file to be compiled by gc
 func (p *Package) writeOutput(f *File, srcfile string) {
 	base := srcfile
-	if strings.HasSuffix(base, ".go") {
-		base = base[0 : len(base)-3]
-	}
+	base = strings.TrimSuffix(base, ".go")
 	base = filepath.Base(base)
 	fgo1 := creat(*objDir + base + ".cgo1.go")
 	fgcc := creat(*objDir + base + ".cgo2.c")
@@ -1115,7 +1117,7 @@
 		fn := exp.Func
 		fntype := fn.Type
 
-		cdeclBuf := new(bytes.Buffer)
+		cdeclBuf := new(strings.Builder)
 		resultCount := 0
 		forFieldList(fntype.Results,
 			func(i int, aname string, atype ast.Expr) { resultCount++ })
@@ -1147,7 +1149,7 @@
 
 		cRet := cdeclBuf.String()
 
-		cdeclBuf = new(bytes.Buffer)
+		cdeclBuf = new(strings.Builder)
 		fmt.Fprintf(cdeclBuf, "(")
 		if fn.Recv != nil {
 			fmt.Fprintf(cdeclBuf, "%s recv", p.cgoType(fn.Recv.List[0].Type).C.String())
@@ -1283,7 +1285,7 @@
 	// They aren't useful for people using the header file,
 	// and they mean that the header files change based on the
 	// exact location of GOPATH.
-	re := regexp.MustCompile(`(?m)^(#line\s+[0-9]+\s+")[^"]*[/\\]([^"]*")`)
+	re := regexp.MustCompile(`(?m)^(#line\s+\d+\s+")[^"]*[/\\]([^"]*")`)
 	preamble := re.ReplaceAllString(p.Preamble, "$1$2")
 
 	fmt.Fprintf(fgcch, "/* Start of preamble from import \"C\" comments.  */\n\n")
diff --git a/src/cmd/cgo/util.go b/src/cmd/cgo/util.go
index 779f7be..054cd6c 100644
--- a/src/cmd/cgo/util.go
+++ b/src/cmd/cgo/util.go
@@ -8,7 +8,6 @@
 	"bytes"
 	"fmt"
 	"go/token"
-	"io/ioutil"
 	"os"
 	"os/exec"
 )
@@ -21,13 +20,13 @@
 		// Some compilers have trouble with standard input.
 		// Others have trouble with -xc.
 		// Avoid both problems by writing a file with a .c extension.
-		f, err := ioutil.TempFile("", "cgo-gcc-input-")
+		f, err := os.CreateTemp("", "cgo-gcc-input-")
 		if err != nil {
 			fatalf("%s", err)
 		}
 		name := f.Name()
 		f.Close()
-		if err := ioutil.WriteFile(name+".c", stdin, 0666); err != nil {
+		if err := os.WriteFile(name+".c", stdin, 0666); err != nil {
 			os.Remove(name)
 			fatalf("%s", err)
 		}
@@ -106,19 +105,6 @@
 	fmt.Fprintf(os.Stderr, "\n")
 }
 
-// isName reports whether s is a valid C identifier
-func isName(s string) bool {
-	for i, v := range s {
-		if v != '_' && (v < 'A' || v > 'Z') && (v < 'a' || v > 'z') && (v < '0' || v > '9') {
-			return false
-		}
-		if i == 0 && '0' <= v && v <= '9' {
-			return false
-		}
-	}
-	return s != ""
-}
-
 func creat(name string) *os.File {
 	f, err := os.Create(name)
 	if err != nil {
@@ -126,10 +112,3 @@
 	}
 	return f
 }
-
-func slashToUnderscore(c rune) rune {
-	if c == '/' || c == '\\' || c == ':' {
-		c = '_'
-	}
-	return c
-}
diff --git a/src/cmd/compile/internal/abi/abiutils.go b/src/cmd/compile/internal/abi/abiutils.go
index aa5063f..a88f8c4 100644
--- a/src/cmd/compile/internal/abi/abiutils.go
+++ b/src/cmd/compile/internal/abi/abiutils.go
@@ -359,7 +359,7 @@
 		result.inparams = append(result.inparams,
 			s.assignParamOrReturn(t, nil, false))
 	}
-	s.stackOffset = types.Rnd(s.stackOffset, int64(types.RegSize))
+	s.stackOffset = types.RoundUp(s.stackOffset, int64(types.RegSize))
 	result.inRegistersUsed = s.rUsed.intRegs + s.rUsed.floatRegs
 
 	// Outputs
@@ -403,7 +403,7 @@
 		result.inparams = append(result.inparams,
 			s.assignParamOrReturn(f.Type, f.Nname, false))
 	}
-	s.stackOffset = types.Rnd(s.stackOffset, int64(types.RegSize))
+	s.stackOffset = types.RoundUp(s.stackOffset, int64(types.RegSize))
 	result.inRegistersUsed = s.rUsed.intRegs + s.rUsed.floatRegs
 
 	// Outputs
@@ -529,7 +529,7 @@
 	spillOffset int64      // current spill offset
 }
 
-// align returns a rounded up to t's alignment
+// align returns a rounded up to t's alignment.
 func align(a int64, t *types.Type) int64 {
 	return alignTo(a, int(uint8(t.Alignment())))
 }
@@ -539,7 +539,7 @@
 	if t == 0 {
 		return a
 	}
-	return types.Rnd(a, int64(t))
+	return types.RoundUp(a, int64(t))
 }
 
 // stackSlot returns a stack offset for a param or result of the
@@ -647,7 +647,7 @@
 // can register allocate, FALSE otherwise (and updates state
 // accordingly).
 func (state *assignState) regassignIntegral(t *types.Type) bool {
-	regsNeeded := int(types.Rnd(t.Size(), int64(types.PtrSize)) / int64(types.PtrSize))
+	regsNeeded := int(types.RoundUp(t.Size(), int64(types.PtrSize)) / int64(types.PtrSize))
 	if t.IsComplex() {
 		regsNeeded = 2
 	}
diff --git a/src/cmd/compile/internal/abt/avlint32.go b/src/cmd/compile/internal/abt/avlint32.go
index 00bbccf..9800e03 100644
--- a/src/cmd/compile/internal/abt/avlint32.go
+++ b/src/cmd/compile/internal/abt/avlint32.go
@@ -7,6 +7,7 @@
 import (
 	"fmt"
 	"strconv"
+	"strings"
 )
 
 const (
@@ -36,7 +37,7 @@
 	return &node32{key: key, height_: LEAF_HEIGHT}
 }
 
-// IsSingle returns true iff t is empty.
+// IsEmpty returns true iff t is empty.
 func (t *T) IsEmpty() bool {
 	return t.root == nil
 }
@@ -326,39 +327,21 @@
 	return t.root.equals(u.root)
 }
 
-// This doesn't build with go1.4, sigh
-// func (t *T) String() string {
-// 	var b strings.Builder
-// 	first := true
-// 	for it := t.Iterator(); !it.IsEmpty(); {
-// 		k, v := it.Next()
-// 		if first {
-// 			first = false
-// 		} else {
-// 			b.WriteString("; ")
-// 		}
-// 		b.WriteString(strconv.FormatInt(int64(k), 10))
-// 		b.WriteString(":")
-// 		b.WriteString(v.String())
-// 	}
-// 	return b.String()
-// }
-
 func (t *T) String() string {
-	var b string
+	var b strings.Builder
 	first := true
 	for it := t.Iterator(); !it.Done(); {
 		k, v := it.Next()
 		if first {
 			first = false
 		} else {
-			b += ("; ")
+			b.WriteString("; ")
 		}
-		b += (strconv.FormatInt(int64(k), 10))
-		b += (":")
-		b += fmt.Sprint(v)
+		b.WriteString(strconv.FormatInt(int64(k), 10))
+		b.WriteString(":")
+		fmt.Fprint(&b, v)
 	}
-	return b
+	return b.String()
 }
 
 func (t *node32) equals(u *node32) bool {
diff --git a/src/cmd/compile/internal/amd64/ssa.go b/src/cmd/compile/internal/amd64/ssa.go
index 0a95aaa..6139d5e 100644
--- a/src/cmd/compile/internal/amd64/ssa.go
+++ b/src/cmd/compile/internal/amd64/ssa.go
@@ -20,7 +20,7 @@
 	"cmd/internal/obj/x86"
 )
 
-// markMoves marks any MOVXconst ops that need to avoid clobbering flags.
+// ssaMarkMoves marks any MOVXconst ops that need to avoid clobbering flags.
 func ssaMarkMoves(s *ssagen.State, b *ssa.Block) {
 	flive := b.FlagsLiveAtEnd
 	for _, c := range b.ControlValues() {
@@ -600,23 +600,23 @@
 	case ssa.OpAMD64CMOVQEQF, ssa.OpAMD64CMOVLEQF, ssa.OpAMD64CMOVWEQF:
 		// Flag condition: ZERO && !PARITY
 		// Generate:
-		//   MOV      SRC,AX
-		//   CMOV*NE  DST,AX
-		//   CMOV*PC  AX,DST
+		//   MOV      SRC,TMP
+		//   CMOV*NE  DST,TMP
+		//   CMOV*PC  TMP,DST
 		//
 		// TODO(rasky): we could generate:
 		//   CMOV*NE  DST,SRC
 		//   CMOV*PC  SRC,DST
 		// But this requires a way for regalloc to know that SRC might be
 		// clobbered by this instruction.
-		if v.Args[1].Reg() != x86.REG_AX {
-			opregreg(s, moveByType(v.Type), x86.REG_AX, v.Args[1].Reg())
-		}
+		t := v.RegTmp()
+		opregreg(s, moveByType(v.Type), t, v.Args[1].Reg())
+
 		p := s.Prog(v.Op.Asm())
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = v.Reg()
 		p.To.Type = obj.TYPE_REG
-		p.To.Reg = x86.REG_AX
+		p.To.Reg = t
 		var q *obj.Prog
 		if v.Op == ssa.OpAMD64CMOVQEQF {
 			q = s.Prog(x86.ACMOVQPC)
@@ -626,7 +626,7 @@
 			q = s.Prog(x86.ACMOVWPC)
 		}
 		q.From.Type = obj.TYPE_REG
-		q.From.Reg = x86.REG_AX
+		q.From.Reg = t
 		q.To.Type = obj.TYPE_REG
 		q.To.Reg = v.Reg()
 
@@ -1194,24 +1194,26 @@
 		ssagen.AddAux(&p.To, v)
 
 	case ssa.OpAMD64SETNEF:
+		t := v.RegTmp()
 		p := s.Prog(v.Op.Asm())
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
 		q := s.Prog(x86.ASETPS)
 		q.To.Type = obj.TYPE_REG
-		q.To.Reg = x86.REG_AX
+		q.To.Reg = t
 		// ORL avoids partial register write and is smaller than ORQ, used by old compiler
-		opregreg(s, x86.AORL, v.Reg(), x86.REG_AX)
+		opregreg(s, x86.AORL, v.Reg(), t)
 
 	case ssa.OpAMD64SETEQF:
+		t := v.RegTmp()
 		p := s.Prog(v.Op.Asm())
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
 		q := s.Prog(x86.ASETPC)
 		q.To.Type = obj.TYPE_REG
-		q.To.Reg = x86.REG_AX
+		q.To.Reg = t
 		// ANDL avoids partial register write and is smaller than ANDQ, used by old compiler
-		opregreg(s, x86.AANDL, v.Reg(), x86.REG_AX)
+		opregreg(s, x86.AANDL, v.Reg(), t)
 
 	case ssa.OpAMD64InvertFlags:
 		v.Fatalf("InvertFlags should never make it to codegen %v", v.LongString())
diff --git a/src/cmd/compile/internal/amd64/versions_test.go b/src/cmd/compile/internal/amd64/versions_test.go
index b6411a1..fc0046a 100644
--- a/src/cmd/compile/internal/amd64/versions_test.go
+++ b/src/cmd/compile/internal/amd64/versions_test.go
@@ -14,6 +14,7 @@
 	"debug/macho"
 	"errors"
 	"fmt"
+	"go/build"
 	"internal/testenv"
 	"io"
 	"math"
@@ -36,10 +37,10 @@
 	if runtime.GOOS != "linux" && runtime.GOOS != "darwin" {
 		t.Skip("test only works on elf or macho platforms")
 	}
-	if v := os.Getenv("GOAMD64"); v != "" && v != "v1" {
-		// Test runs only on v1 (which is the default).
-		// TODO: use build tags from #45454 instead.
-		t.Skip("GOAMD64 already set")
+	for _, tag := range build.Default.ToolTags {
+		if tag == "amd64.v2" {
+			t.Skip("compiling for GOAMD64=v2 or higher")
+		}
 	}
 	if os.Getenv("TESTGOAMD64V1") != "" {
 		t.Skip("recursive call")
@@ -71,7 +72,7 @@
 	}
 
 	// Run the resulting binary.
-	cmd := exec.Command(dst.Name())
+	cmd := testenv.Command(t, dst.Name())
 	testenv.CleanCmdEnv(cmd)
 	cmd.Env = append(cmd.Env, "TESTGOAMD64V1=yes")
 	cmd.Env = append(cmd.Env, fmt.Sprintf("GODEBUG=%s", strings.Join(features, ",")))
@@ -103,7 +104,7 @@
 	if false {
 		// TODO: go tool objdump doesn't disassemble the bmi1 instructions
 		// in question correctly. See issue 48584.
-		cmd := exec.Command("go", "tool", "objdump", src)
+		cmd := testenv.Command(t, "go", "tool", "objdump", src)
 		var err error
 		disasm, err = cmd.StdoutPipe()
 		if err != nil {
@@ -112,11 +113,16 @@
 		if err := cmd.Start(); err != nil {
 			t.Fatal(err)
 		}
-		re = regexp.MustCompile(`^[^:]*:[-0-9]+\s+0x([0-9a-f]+)\s+([0-9a-f]+)\s+([A-Z]+)`)
+		t.Cleanup(func() {
+			if err := cmd.Wait(); err != nil {
+				t.Error(err)
+			}
+		})
+		re = regexp.MustCompile(`^[^:]*:[-\d]+\s+0x([\da-f]+)\s+([\da-f]+)\s+([A-Z]+)`)
 	} else {
 		// TODO: we're depending on platform-native objdump here. Hence the Skipf
 		// below if it doesn't run for some reason.
-		cmd := exec.Command("objdump", "-d", src)
+		cmd := testenv.Command(t, "objdump", "-d", src)
 		var err error
 		disasm, err = cmd.StdoutPipe()
 		if err != nil {
@@ -128,7 +134,12 @@
 			}
 			t.Fatal(err)
 		}
-		re = regexp.MustCompile(`^\s*([0-9a-f]+):\s*((?:[0-9a-f][0-9a-f] )+)\s*([a-z0-9]+)`)
+		t.Cleanup(func() {
+			if err := cmd.Wait(); err != nil {
+				t.Error(err)
+			}
+		})
+		re = regexp.MustCompile(`^\s*([\da-f]+):\s*((?:[\da-f][\da-f] )+)\s*([a-z\d]+)`)
 	}
 
 	// Find all the instruction addresses we need to edit.
diff --git a/src/cmd/compile/internal/arm/ssa.go b/src/cmd/compile/internal/arm/ssa.go
index a53f51b..fd0da34 100644
--- a/src/cmd/compile/internal/arm/ssa.go
+++ b/src/cmd/compile/internal/arm/ssa.go
@@ -72,7 +72,7 @@
 	panic("bad store type")
 }
 
-// shift type is used as Offset in obj.TYPE_SHIFT operands to encode shifted register operands
+// shift type is used as Offset in obj.TYPE_SHIFT operands to encode shifted register operands.
 type shift int64
 
 // copied from ../../../internal/obj/util.go:/TYPE_SHIFT
@@ -87,7 +87,7 @@
 	}
 }
 
-// makeshift encodes a register shifted by a constant
+// makeshift encodes a register shifted by a constant.
 func makeshift(v *ssa.Value, reg int16, typ int64, s int64) shift {
 	if s < 0 || s >= 32 {
 		v.Fatalf("shift out of range: %d", s)
@@ -95,7 +95,7 @@
 	return shift(int64(reg&0xf) | typ | (s&31)<<7)
 }
 
-// genshift generates a Prog for r = r0 op (r1 shifted by n)
+// genshift generates a Prog for r = r0 op (r1 shifted by n).
 func genshift(s *ssagen.State, v *ssa.Value, as obj.As, r0, r1, r int16, typ int64, n int64) *obj.Prog {
 	p := s.Prog(as)
 	p.From.Type = obj.TYPE_SHIFT
@@ -108,12 +108,12 @@
 	return p
 }
 
-// makeregshift encodes a register shifted by a register
+// makeregshift encodes a register shifted by a register.
 func makeregshift(r1 int16, typ int64, r2 int16) shift {
 	return shift(int64(r1&0xf) | typ | int64(r2&0xf)<<8 | 1<<4)
 }
 
-// genregshift generates a Prog for r = r0 op (r1 shifted by r2)
+// genregshift generates a Prog for r = r0 op (r1 shifted by r2).
 func genregshift(s *ssagen.State, as obj.As, r0, r1, r2, r int16, typ int64) *obj.Prog {
 	p := s.Prog(as)
 	p.From.Type = obj.TYPE_SHIFT
@@ -903,13 +903,13 @@
 	ssa.BlockARMGEnoov: {arm.ABPL, arm.ABMI},
 }
 
-// To model a 'LEnoov' ('<=' without overflow checking) branching
+// To model a 'LEnoov' ('<=' without overflow checking) branching.
 var leJumps = [2][2]ssagen.IndexJump{
 	{{Jump: arm.ABEQ, Index: 0}, {Jump: arm.ABPL, Index: 1}}, // next == b.Succs[0]
 	{{Jump: arm.ABMI, Index: 0}, {Jump: arm.ABEQ, Index: 0}}, // next == b.Succs[1]
 }
 
-// To model a 'GTnoov' ('>' without overflow checking) branching
+// To model a 'GTnoov' ('>' without overflow checking) branching.
 var gtJumps = [2][2]ssagen.IndexJump{
 	{{Jump: arm.ABMI, Index: 1}, {Jump: arm.ABEQ, Index: 1}}, // next == b.Succs[0]
 	{{Jump: arm.ABEQ, Index: 1}, {Jump: arm.ABPL, Index: 0}}, // next == b.Succs[1]
diff --git a/src/cmd/compile/internal/arm64/ggen.go b/src/cmd/compile/internal/arm64/ggen.go
index 89be496..a681adc 100644
--- a/src/cmd/compile/internal/arm64/ggen.go
+++ b/src/cmd/compile/internal/arm64/ggen.go
@@ -10,11 +10,8 @@
 	"cmd/compile/internal/types"
 	"cmd/internal/obj"
 	"cmd/internal/obj/arm64"
-	"internal/buildcfg"
 )
 
-var darwin = buildcfg.GOOS == "darwin" || buildcfg.GOOS == "ios"
-
 func padframe(frame int64) int64 {
 	// arm64 requires that the frame size (not counting saved FP&LR)
 	// be 16 bytes aligned. If not, pad it.
@@ -32,7 +29,7 @@
 		for i := int64(0); i < cnt; i += int64(types.PtrSize) {
 			p = pp.Append(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGZERO, 0, obj.TYPE_MEM, arm64.REGSP, 8+off+i)
 		}
-	} else if cnt <= int64(128*types.PtrSize) && !darwin { // darwin ld64 cannot handle BR26 reloc with non-zero addend
+	} else if cnt <= int64(128*types.PtrSize) {
 		if cnt%(2*int64(types.PtrSize)) != 0 {
 			p = pp.Append(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGZERO, 0, obj.TYPE_MEM, arm64.REGSP, 8+off)
 			off += int64(types.PtrSize)
diff --git a/src/cmd/compile/internal/arm64/ssa.go b/src/cmd/compile/internal/arm64/ssa.go
index c93e6e6..8885655 100644
--- a/src/cmd/compile/internal/arm64/ssa.go
+++ b/src/cmd/compile/internal/arm64/ssa.go
@@ -78,7 +78,7 @@
 	panic("bad store type")
 }
 
-// makeshift encodes a register shifted by a constant, used as an Offset in Prog
+// makeshift encodes a register shifted by a constant, used as an Offset in Prog.
 func makeshift(v *ssa.Value, reg int16, typ int64, s int64) int64 {
 	if s < 0 || s >= 64 {
 		v.Fatalf("shift out of range: %d", s)
@@ -86,7 +86,7 @@
 	return int64(reg&31)<<16 | typ | (s&63)<<10
 }
 
-// genshift generates a Prog for r = r0 op (r1 shifted by n)
+// genshift generates a Prog for r = r0 op (r1 shifted by n).
 func genshift(s *ssagen.State, v *ssa.Value, as obj.As, r0, r1, r int16, typ int64, n int64) *obj.Prog {
 	p := s.Prog(as)
 	p.From.Type = obj.TYPE_SHIFT
@@ -449,6 +449,14 @@
 		ssagen.AddAux(&p.From, v)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
+	case ssa.OpARM64LDP:
+		p := s.Prog(v.Op.Asm())
+		p.From.Type = obj.TYPE_MEM
+		p.From.Reg = v.Args[0].Reg()
+		ssagen.AddAux(&p.From, v)
+		p.To.Type = obj.TYPE_REGREG
+		p.To.Reg = v.Reg0()
+		p.To.Offset = int64(v.Reg1())
 	case ssa.OpARM64MOVBloadidx,
 		ssa.OpARM64MOVBUloadidx,
 		ssa.OpARM64MOVHloadidx,
@@ -565,21 +573,6 @@
 		p.Reg = v.Args[0].Reg()
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
-	case ssa.OpARM64LoweredMuluhilo:
-		r0 := v.Args[0].Reg()
-		r1 := v.Args[1].Reg()
-		p := s.Prog(arm64.AUMULH)
-		p.From.Type = obj.TYPE_REG
-		p.From.Reg = r1
-		p.Reg = r0
-		p.To.Type = obj.TYPE_REG
-		p.To.Reg = v.Reg0()
-		p1 := s.Prog(arm64.AMUL)
-		p1.From.Type = obj.TYPE_REG
-		p1.From.Reg = r1
-		p1.Reg = r0
-		p1.To.Type = obj.TYPE_REG
-		p1.To.Reg = v.Reg1()
 	case ssa.OpARM64LoweredAtomicExchange64,
 		ssa.OpARM64LoweredAtomicExchange32:
 		// LDAXR	(Rarg0), Rout
@@ -1036,25 +1029,27 @@
 		p.To.Sym = ir.Syms.Duffcopy
 		p.To.Offset = v.AuxInt
 	case ssa.OpARM64LoweredMove:
-		// MOVD.P	8(R16), Rtmp
-		// MOVD.P	Rtmp, 8(R17)
+		// LDP.P	16(R16), (R25, Rtmp)
+		// STP.P	(R25, Rtmp), 16(R17)
 		// CMP	Rarg2, R16
 		// BLE	-3(PC)
 		// arg2 is the address of the last element of src
-		p := s.Prog(arm64.AMOVD)
+		p := s.Prog(arm64.ALDP)
 		p.Scond = arm64.C_XPOST
 		p.From.Type = obj.TYPE_MEM
 		p.From.Reg = arm64.REG_R16
-		p.From.Offset = 8
-		p.To.Type = obj.TYPE_REG
-		p.To.Reg = arm64.REGTMP
-		p2 := s.Prog(arm64.AMOVD)
+		p.From.Offset = 16
+		p.To.Type = obj.TYPE_REGREG
+		p.To.Reg = arm64.REG_R25
+		p.To.Offset = int64(arm64.REGTMP)
+		p2 := s.Prog(arm64.ASTP)
 		p2.Scond = arm64.C_XPOST
-		p2.From.Type = obj.TYPE_REG
-		p2.From.Reg = arm64.REGTMP
+		p2.From.Type = obj.TYPE_REGREG
+		p2.From.Reg = arm64.REG_R25
+		p2.From.Offset = int64(arm64.REGTMP)
 		p2.To.Type = obj.TYPE_MEM
 		p2.To.Reg = arm64.REG_R17
-		p2.To.Offset = 8
+		p2.To.Offset = 16
 		p3 := s.Prog(arm64.ACMP)
 		p3.From.Type = obj.TYPE_REG
 		p3.From.Reg = v.Args[2].Reg()
@@ -1228,13 +1223,13 @@
 	ssa.BlockARM64GEnoov: {arm64.ABPL, arm64.ABMI},
 }
 
-// To model a 'LEnoov' ('<=' without overflow checking) branching
+// To model a 'LEnoov' ('<=' without overflow checking) branching.
 var leJumps = [2][2]ssagen.IndexJump{
 	{{Jump: arm64.ABEQ, Index: 0}, {Jump: arm64.ABPL, Index: 1}}, // next == b.Succs[0]
 	{{Jump: arm64.ABMI, Index: 0}, {Jump: arm64.ABEQ, Index: 0}}, // next == b.Succs[1]
 }
 
-// To model a 'GTnoov' ('>' without overflow checking) branching
+// To model a 'GTnoov' ('>' without overflow checking) branching.
 var gtJumps = [2][2]ssagen.IndexJump{
 	{{Jump: arm64.ABMI, Index: 1}, {Jump: arm64.ABEQ, Index: 1}}, // next == b.Succs[0]
 	{{Jump: arm64.ABEQ, Index: 1}, {Jump: arm64.ABPL, Index: 0}}, // next == b.Succs[1]
diff --git a/src/cmd/compile/internal/base/base.go b/src/cmd/compile/internal/base/base.go
index 39ce8e6..521600b 100644
--- a/src/cmd/compile/internal/base/base.go
+++ b/src/cmd/compile/internal/base/base.go
@@ -5,7 +5,11 @@
 package base
 
 import (
+	"fmt"
 	"os"
+	"runtime"
+	"runtime/debug"
+	"runtime/metrics"
 )
 
 var atExitFuncs []func()
@@ -26,6 +30,196 @@
 // To enable tracing support (-t flag), set EnableTrace to true.
 const EnableTrace = false
 
+// forEachGC calls fn each GC cycle until it returns false.
+func forEachGC(fn func() bool) {
+	type T [32]byte // large enough to avoid runtime's tiny object allocator
+
+	var finalizer func(*T)
+	finalizer = func(p *T) {
+		if fn() {
+			runtime.SetFinalizer(p, finalizer)
+		}
+	}
+
+	finalizer(new(T))
+}
+
+// AdjustStartingHeap modifies GOGC so that GC should not occur until the heap
+// grows to the requested size.  This is intended but not promised, though it
+// is true-mostly, depending on when the adjustment occurs and on the
+// compiler's input and behavior.  Once this size is approximately reached
+// GOGC is reset to 100; subsequent GCs may reduce the heap below the requested
+// size, but this function does not affect that.
+//
+// -d=gcadjust=1 enables logging of GOGC adjustment events.
+//
+// NOTE: If you think this code would help startup time in your own
+// application and you decide to use it, please benchmark first to see if it
+// actually works for you (it may not: the Go compiler is not typical), and
+// whatever the outcome, please leave a comment on bug #56546.  This code
+// uses supported interfaces, but depends more than we like on
+// current+observed behavior of the garbage collector, so if many people need
+// this feature, we should consider/propose a better way to accomplish it.
+func AdjustStartingHeap(requestedHeapGoal uint64) {
+	logHeapTweaks := Debug.GCAdjust == 1
+	mp := runtime.GOMAXPROCS(0)
+	gcConcurrency := Flag.LowerC
+
+	const (
+		goal   = "/gc/heap/goal:bytes"
+		count  = "/gc/cycles/total:gc-cycles"
+		allocs = "/gc/heap/allocs:bytes"
+		frees  = "/gc/heap/frees:bytes"
+	)
+
+	sample := []metrics.Sample{{Name: goal}, {Name: count}, {Name: allocs}, {Name: frees}}
+	const (
+		GOAL   = 0
+		COUNT  = 1
+		ALLOCS = 2
+		FREES  = 3
+	)
+
+	// Assumptions and observations of Go's garbage collector, as of Go 1.17-1.20:
+
+	// - the initial heap goal is 4M, by fiat.  It is possible for Go to start
+	//   with a heap as small as 512k, so this may change in the future.
+
+	// - except for the first heap goal, heap goal is a function of
+	//   observed-live at the previous GC and current GOGC.  After the first
+	//   GC, adjusting GOGC immediately updates GOGC; before the first GC,
+	//   adjusting GOGC does not modify goal (but the change takes effect after
+	//   the first GC).
+
+	// - the before/after first GC behavior is not guaranteed anywhere, it's
+	//   just behavior, and it's a bad idea to rely on it.
+
+	// - we don't know exactly when GC will run, even after we adjust GOGC; the
+	//   first GC may not have happened yet, may have already happened, or may
+	//   be currently in progress, and GCs can start for several reasons.
+
+	// - forEachGC above will run the provided function at some delay after each
+	//   GC's mark phase terminates; finalizers are run after marking as the
+	//   spans containing finalizable objects are swept, driven by GC
+	//   background activity and allocation demand.
+
+	// - "live at last GC" is not available through the current metrics
+	//    interface. Instead, live is estimated by knowing the adjusted value of
+	//    GOGC and the new heap goal following a GC (this requires knowing that
+	//    at least one GC has occurred):
+	//		  estLive = 100 * newGoal / (100 + currentGogc)]
+	//    this new value of GOGC
+	//		  newGogc = 100*requestedHeapGoal/estLive - 100
+	//    will result in the desired goal. The logging code checks that the
+	//    resulting goal is correct.
+
+	// There's a small risk that the finalizer will be slow to run after a GC
+	// that expands the goal to a huge value, and that this will lead to
+	// out-of-memory.  This doesn't seem to happen; in experiments on a variety
+	// of machines with a variety of extra loads to disrupt scheduling, the
+	// worst overshoot observed was 50% past requestedHeapGoal.
+
+	metrics.Read(sample)
+	for _, s := range sample {
+		if s.Value.Kind() == metrics.KindBad {
+			// Just return, a slightly slower compilation is a tolerable outcome.
+			if logHeapTweaks {
+				fmt.Fprintf(os.Stderr, "GCAdjust: Regret unexpected KindBad for metric %s\n", s.Name)
+			}
+			return
+		}
+	}
+
+	// Tinker with GOGC to make the heap grow rapidly at first.
+	currentGoal := sample[GOAL].Value.Uint64() // Believe this will be 4MByte or less, perhaps 512k
+	myGogc := 100 * requestedHeapGoal / currentGoal
+	if myGogc <= 150 {
+		return
+	}
+
+	if logHeapTweaks {
+		sample := append([]metrics.Sample(nil), sample...) // avoid races with GC callback
+		AtExit(func() {
+			metrics.Read(sample)
+			goal := sample[GOAL].Value.Uint64()
+			count := sample[COUNT].Value.Uint64()
+			oldGogc := debug.SetGCPercent(100)
+			if oldGogc == 100 {
+				fmt.Fprintf(os.Stderr, "GCAdjust: AtExit goal %d gogc %d count %d maxprocs %d gcConcurrency %d\n",
+					goal, oldGogc, count, mp, gcConcurrency)
+			} else {
+				inUse := sample[ALLOCS].Value.Uint64() - sample[FREES].Value.Uint64()
+				overPct := 100 * (int(inUse) - int(requestedHeapGoal)) / int(requestedHeapGoal)
+				fmt.Fprintf(os.Stderr, "GCAdjust: AtExit goal %d gogc %d count %d maxprocs %d gcConcurrency %d overPct %d\n",
+					goal, oldGogc, count, mp, gcConcurrency, overPct)
+
+			}
+		})
+	}
+
+	debug.SetGCPercent(int(myGogc))
+
+	adjustFunc := func() bool {
+
+		metrics.Read(sample)
+		goal := sample[GOAL].Value.Uint64()
+		count := sample[COUNT].Value.Uint64()
+
+		if goal <= requestedHeapGoal { // Stay the course
+			if logHeapTweaks {
+				fmt.Fprintf(os.Stderr, "GCAdjust: Reuse GOGC adjust, current goal %d, count is %d, current gogc %d\n",
+					goal, count, myGogc)
+			}
+			return true
+		}
+
+		// Believe goal has been adjusted upwards, else it would be less-than-or-equal than requestedHeapGoal
+		calcLive := 100 * goal / (100 + myGogc)
+
+		if 2*calcLive < requestedHeapGoal { // calcLive can exceed requestedHeapGoal!
+			myGogc = 100*requestedHeapGoal/calcLive - 100
+
+			if myGogc > 125 {
+				// Not done growing the heap.
+				oldGogc := debug.SetGCPercent(int(myGogc))
+
+				if logHeapTweaks {
+					// Check that the new goal looks right
+					inUse := sample[ALLOCS].Value.Uint64() - sample[FREES].Value.Uint64()
+					metrics.Read(sample)
+					newGoal := sample[GOAL].Value.Uint64()
+					pctOff := 100 * (int64(newGoal) - int64(requestedHeapGoal)) / int64(requestedHeapGoal)
+					// Check that the new goal is close to requested.  3% of make.bash fails this test.  Why, TBD.
+					if pctOff < 2 {
+						fmt.Fprintf(os.Stderr, "GCAdjust: Retry GOGC adjust, current goal %d, count is %d, gogc was %d, is now %d, calcLive %d pctOff %d\n",
+							goal, count, oldGogc, myGogc, calcLive, pctOff)
+					} else {
+						// The GC is being annoying and not giving us the goal that we requested, say more to help understand when/why.
+						fmt.Fprintf(os.Stderr, "GCAdjust: Retry GOGC adjust, current goal %d, count is %d, gogc was %d, is now %d, calcLive %d pctOff %d inUse %d\n",
+							goal, count, oldGogc, myGogc, calcLive, pctOff, inUse)
+					}
+				}
+				return true
+			}
+		}
+
+		// In this case we're done boosting GOGC, set it to 100 and don't set a new finalizer.
+		oldGogc := debug.SetGCPercent(100)
+		// inUse helps estimate how late the finalizer ran; at the instant the previous GC ended,
+		// it was (in theory) equal to the previous GC's heap goal.  In a growing heap it is
+		// expected to grow to the new heap goal.
+		inUse := sample[ALLOCS].Value.Uint64() - sample[FREES].Value.Uint64()
+		overPct := 100 * (int(inUse) - int(requestedHeapGoal)) / int(requestedHeapGoal)
+		if logHeapTweaks {
+			fmt.Fprintf(os.Stderr, "GCAdjust: Reset GOGC adjust, old goal %d, count is %d, gogc was %d, calcLive %d inUse %d overPct %d\n",
+				goal, count, oldGogc, calcLive, inUse, overPct)
+		}
+		return false
+	}
+
+	forEachGC(adjustFunc)
+}
+
 func Compiling(pkgs []string) bool {
 	if Ctxt.Pkgpath != "" {
 		for _, p := range pkgs {
diff --git a/src/cmd/compile/internal/base/bootstrap_false.go b/src/cmd/compile/internal/base/bootstrap_false.go
index c77fcd7..ea6da43 100644
--- a/src/cmd/compile/internal/base/bootstrap_false.go
+++ b/src/cmd/compile/internal/base/bootstrap_false.go
@@ -3,7 +3,6 @@
 // license that can be found in the LICENSE file.
 
 //go:build !compiler_bootstrap
-// +build !compiler_bootstrap
 
 package base
 
diff --git a/src/cmd/compile/internal/base/bootstrap_true.go b/src/cmd/compile/internal/base/bootstrap_true.go
index 1eb58b2..d0c6c88 100644
--- a/src/cmd/compile/internal/base/bootstrap_true.go
+++ b/src/cmd/compile/internal/base/bootstrap_true.go
@@ -3,7 +3,6 @@
 // license that can be found in the LICENSE file.
 
 //go:build compiler_bootstrap
-// +build compiler_bootstrap
 
 package base
 
diff --git a/src/cmd/compile/internal/base/debug.go b/src/cmd/compile/internal/base/debug.go
index f1d020f..ee42696 100644
--- a/src/cmd/compile/internal/base/debug.go
+++ b/src/cmd/compile/internal/base/debug.go
@@ -16,35 +16,46 @@
 // The -d option takes a comma-separated list of settings.
 // Each setting is name=value; for ints, name is short for name=1.
 type DebugFlags struct {
-	Append               int    `help:"print information about append compilation"`
-	Checkptr             int    `help:"instrument unsafe pointer conversions\n0: instrumentation disabled\n1: conversions involving unsafe.Pointer are instrumented\n2: conversions to unsafe.Pointer force heap allocation"`
-	Closure              int    `help:"print information about closure compilation"`
-	DclStack             int    `help:"run internal dclstack check"`
-	Defer                int    `help:"print information about defer compilation"`
-	DisableNil           int    `help:"disable nil checks"`
-	DumpPtrs             int    `help:"show Node pointers values in dump output"`
-	DwarfInl             int    `help:"print information about DWARF inlined function creation"`
-	Export               int    `help:"print export data"`
-	GCProg               int    `help:"print dump of GC programs"`
-	InlFuncsWithClosures int    `help:"allow functions with closures to be inlined"`
-	Libfuzzer            int    `help:"enable coverage instrumentation for libfuzzer"`
-	LocationLists        int    `help:"print information about DWARF location list creation"`
-	Nil                  int    `help:"print information about nil checks"`
-	NoOpenDefer          int    `help:"disable open-coded defers"`
-	NoRefName            int    `help:"do not include referenced symbol names in object file"`
-	PCTab                string `help:"print named pc-value table\nOne of: pctospadj, pctofile, pctoline, pctoinline, pctopcdata"`
-	Panic                int    `help:"show all compiler panics"`
-	Slice                int    `help:"print information about slice compilation"`
-	SoftFloat            int    `help:"force compiler to emit soft-float code"`
-	SyncFrames           int    `help:"how many writer stack frames to include at sync points in unified export data"`
-	TypeAssert           int    `help:"print information about type assertion inlining"`
-	TypecheckInl         int    `help:"eager typechecking of inline function bodies"`
-	Unified              int    `help:"enable unified IR construction"`
-	WB                   int    `help:"print information about write barriers"`
-	ABIWrap              int    `help:"print information about ABI wrapper generation"`
-	MayMoreStack         string `help:"call named function before all stack growth checks"`
+	Append                int    `help:"print information about append compilation"`
+	Checkptr              int    `help:"instrument unsafe pointer conversions\n0: instrumentation disabled\n1: conversions involving unsafe.Pointer are instrumented\n2: conversions to unsafe.Pointer force heap allocation" concurrent:"ok"`
+	Closure               int    `help:"print information about closure compilation"`
+	DclStack              int    `help:"run internal dclstack check"`
+	Defer                 int    `help:"print information about defer compilation"`
+	DisableNil            int    `help:"disable nil checks" concurrent:"ok"`
+	DumpPtrs              int    `help:"show Node pointers values in dump output"`
+	DwarfInl              int    `help:"print information about DWARF inlined function creation"`
+	Export                int    `help:"print export data"`
+	Fmahash               string `help:"hash value for use in debugging platform-dependent multiply-add use" concurrent:"ok"`
+	GCAdjust              int    `help:"log adjustments to GOGC" concurrent:"ok"`
+	GCCheck               int    `help:"check heap/gc use by compiler" concurrent:"ok"`
+	GCProg                int    `help:"print dump of GC programs"`
+	Gossahash             string `help:"hash value for use in debugging the compiler"`
+	InlFuncsWithClosures  int    `help:"allow functions with closures to be inlined" concurrent:"ok"`
+	InlStaticInit         int    `help:"allow static initialization of inlined calls" concurrent:"ok"`
+	InterfaceCycles       int    `help:"allow anonymous interface cycles"`
+	Libfuzzer             int    `help:"enable coverage instrumentation for libfuzzer"`
+	LocationLists         int    `help:"print information about DWARF location list creation"`
+	Nil                   int    `help:"print information about nil checks"`
+	NoOpenDefer           int    `help:"disable open-coded defers" concurrent:"ok"`
+	NoRefName             int    `help:"do not include referenced symbol names in object file" concurrent:"ok"`
+	PCTab                 string `help:"print named pc-value table\nOne of: pctospadj, pctofile, pctoline, pctoinline, pctopcdata"`
+	Panic                 int    `help:"show all compiler panics"`
+	Reshape               int    `help:"print information about expression reshaping"`
+	Shapify               int    `help:"print information about shaping recursive types"`
+	Slice                 int    `help:"print information about slice compilation"`
+	SoftFloat             int    `help:"force compiler to emit soft-float code" concurrent:"ok"`
+	SyncFrames            int    `help:"how many writer stack frames to include at sync points in unified export data"`
+	TypeAssert            int    `help:"print information about type assertion inlining"`
+	TypecheckInl          int    `help:"eager typechecking of inline function bodies" concurrent:"ok"`
+	Unified               int    `help:"enable unified IR construction"`
+	WB                    int    `help:"print information about write barriers"`
+	ABIWrap               int    `help:"print information about ABI wrapper generation"`
+	MayMoreStack          string `help:"call named function before all stack growth checks" concurrent:"ok"`
+	PGOInlineCDFThreshold string `help:"cummulative threshold percentage for determining call sites as hot candidates for inlining" concurrent:"ok"`
+	PGOInlineBudget       int    `help:"inline budget for hot functions" concurrent:"ok"`
+	PGOInline             int    `help:"debug profile-guided inlining"`
 
-	Any bool // set when any of the debug flags have been set
+	ConcurrentOk bool // true if only concurrentOk flags seen
 }
 
 // DebugSSA is called to set a -d ssa/... option.
diff --git a/src/cmd/compile/internal/base/flag.go b/src/cmd/compile/internal/base/flag.go
index a363b83..be555c3 100644
--- a/src/cmd/compile/internal/base/flag.go
+++ b/src/cmd/compile/internal/base/flag.go
@@ -9,7 +9,8 @@
 	"flag"
 	"fmt"
 	"internal/buildcfg"
-	"io/ioutil"
+	"internal/coverage"
+	"internal/platform"
 	"log"
 	"os"
 	"reflect"
@@ -79,8 +80,8 @@
 	LowerV *bool      "help:\"increase debug verbosity\""
 
 	// Special characters
-	Percent          int  "flag:\"%\" help:\"debug non-static initializers\""
-	CompilingRuntime bool "flag:\"+\" help:\"compiling runtime\""
+	Percent          CountFlag "flag:\"%\" help:\"debug non-static initializers\""
+	CompilingRuntime bool      "flag:\"+\" help:\"compiling runtime\""
 
 	// Longer names
 	AsmHdr             string       "help:\"write assembly header to `file`\""
@@ -111,6 +112,7 @@
 	MemProfileRate     int          "help:\"set runtime.MemProfileRate to `rate`\""
 	MutexProfile       string       "help:\"write mutex profile to `file`\""
 	NoLocalImports     bool         "help:\"reject local (relative) imports\""
+	CoverageCfg        func(string) "help:\"read coverage configuration from `file`\""
 	Pack               bool         "help:\"write to file.a instead of file.o\""
 	Race               bool         "help:\"enable race detector\""
 	Shared             *bool        "help:\"generate code that can be linked into a shared library\"" // &Ctxt.Flag_shared, set below
@@ -120,7 +122,9 @@
 	SymABIs            string       "help:\"read symbol ABIs from `file`\""
 	TraceProfile       string       "help:\"write an execution trace to `file`\""
 	TrimPath           string       "help:\"remove `prefix` from recorded source file paths\""
-	WB                 bool         "help:\"enable write barrier\"" // TODO: remove
+	WB                 bool         "help:\"enable write barrier\""            // TODO: remove
+	OldComparable      bool         "help:\"enable old comparable semantics\"" // TODO: remove for Go 1.21
+	PgoProfile         string       "help:\"read profile from `file`\""
 
 	// Configuration derived from flags; not a flag itself.
 	Cfg struct {
@@ -128,10 +132,11 @@
 			Patterns map[string][]string
 			Files    map[string]string
 		}
-		ImportDirs   []string          // appended to by -I
-		ImportMap    map[string]string // set by -importcfg
-		PackageFile  map[string]string // set by -importcfg; nil means not in use
-		SpectreIndex bool              // set by -spectre=index or -spectre=all
+		ImportDirs   []string                   // appended to by -I
+		ImportMap    map[string]string          // set by -importcfg
+		PackageFile  map[string]string          // set by -importcfg; nil means not in use
+		CoverageInfo *coverage.CoverFixupConfig // set by -coveragecfg
+		SpectreIndex bool                       // set by -spectre=index or -spectre=all
 		// Whether we are adding any sort of code instrumentation, such as
 		// when the race detector is enabled.
 		Instrumenting bool
@@ -142,7 +147,7 @@
 func ParseFlags() {
 	Flag.I = addImportDir
 
-	Flag.LowerC = 1
+	Flag.LowerC = runtime.GOMAXPROCS(0)
 	Flag.LowerD = objabi.NewDebugFlag(&Debug, DebugSSA)
 	Flag.LowerP = &Ctxt.Pkgpath
 	Flag.LowerV = &Ctxt.Debugvlog
@@ -155,14 +160,18 @@
 	Flag.EmbedCfg = readEmbedCfg
 	Flag.GenDwarfInl = 2
 	Flag.ImportCfg = readImportCfg
+	Flag.CoverageCfg = readCoverageCfg
 	Flag.LinkShared = &Ctxt.Flag_linkshared
 	Flag.Shared = &Ctxt.Flag_shared
 	Flag.WB = true
 
+	Debug.ConcurrentOk = true
 	Debug.InlFuncsWithClosures = 1
+	Debug.InlStaticInit = 0
 	if buildcfg.Experiment.Unified {
 		Debug.Unified = 1
 	}
+	Debug.SyncFrames = -1 // disable sync markers by default
 
 	Debug.Checkptr = -1 // so we can tell whether it is set explicitly
 
@@ -172,13 +181,27 @@
 	registerFlags()
 	objabi.Flagparse(usage)
 
-	if Flag.MSan && !sys.MSanSupported(buildcfg.GOOS, buildcfg.GOARCH) {
+	if gcd := os.Getenv("GOCOMPILEDEBUG"); gcd != "" {
+		// This will only override the flags set in gcd;
+		// any others set on the command line remain set.
+		Flag.LowerD.Set(gcd)
+	}
+
+	if Debug.Gossahash != "" {
+		hashDebug = NewHashDebug("gosshash", Debug.Gossahash, nil)
+	}
+
+	if Debug.Fmahash != "" {
+		FmaHash = NewHashDebug("fmahash", Debug.Fmahash, nil)
+	}
+
+	if Flag.MSan && !platform.MSanSupported(buildcfg.GOOS, buildcfg.GOARCH) {
 		log.Fatalf("%s/%s does not support -msan", buildcfg.GOOS, buildcfg.GOARCH)
 	}
-	if Flag.ASan && !sys.ASanSupported(buildcfg.GOOS, buildcfg.GOARCH) {
+	if Flag.ASan && !platform.ASanSupported(buildcfg.GOOS, buildcfg.GOARCH) {
 		log.Fatalf("%s/%s does not support -asan", buildcfg.GOOS, buildcfg.GOARCH)
 	}
-	if Flag.Race && !sys.RaceDetectorSupported(buildcfg.GOOS, buildcfg.GOARCH) {
+	if Flag.Race && !platform.RaceDetectorSupported(buildcfg.GOOS, buildcfg.GOARCH) {
 		log.Fatalf("%s/%s does not support -race", buildcfg.GOOS, buildcfg.GOARCH)
 	}
 	if (*Flag.Shared || *Flag.Dynlink || *Flag.LinkShared) && !Ctxt.Arch.InFamily(sys.AMD64, sys.ARM, sys.ARM64, sys.I386, sys.PPC64, sys.RISCV64, sys.S390X) {
@@ -245,8 +268,8 @@
 	if Flag.LowerC < 1 {
 		log.Fatalf("-c must be at least 1, got %d", Flag.LowerC)
 	}
-	if Flag.LowerC > 1 && !concurrentBackendAllowed() {
-		log.Fatalf("cannot use concurrent backend compilation with provided flags; invoked as %v", os.Args)
+	if !concurrentBackendAllowed() {
+		Flag.LowerC = 1
 	}
 
 	if Flag.CompilingRuntime {
@@ -366,7 +389,7 @@
 	// while writing the object file, and that is non-concurrent.
 	// Adding Debug_vlog, however, causes Debug.S to also print
 	// while flushing the plist, which happens concurrently.
-	if Ctxt.Debugvlog || Debug.Any || Flag.Live > 0 {
+	if Ctxt.Debugvlog || !Debug.ConcurrentOk || Flag.Live > 0 {
 		return false
 	}
 	// TODO: Test and delete this condition.
@@ -391,7 +414,7 @@
 		Flag.Cfg.ImportMap = make(map[string]string)
 	}
 	Flag.Cfg.PackageFile = map[string]string{}
-	data, err := ioutil.ReadFile(file)
+	data, err := os.ReadFile(file)
 	if err != nil {
 		log.Fatalf("-importcfg: %v", err)
 	}
@@ -430,8 +453,20 @@
 	}
 }
 
+func readCoverageCfg(file string) {
+	var cfg coverage.CoverFixupConfig
+	data, err := os.ReadFile(file)
+	if err != nil {
+		log.Fatalf("-coveragecfg: %v", err)
+	}
+	if err := json.Unmarshal(data, &cfg); err != nil {
+		log.Fatalf("error reading -coveragecfg file %q: %v", file, err)
+	}
+	Flag.Cfg.CoverageInfo = &cfg
+}
+
 func readEmbedCfg(file string) {
-	data, err := ioutil.ReadFile(file)
+	data, err := os.ReadFile(file)
 	if err != nil {
 		log.Fatalf("-embedcfg: %v", err)
 	}
diff --git a/src/cmd/compile/internal/base/hashdebug.go b/src/cmd/compile/internal/base/hashdebug.go
new file mode 100644
index 0000000..6c4821b
--- /dev/null
+++ b/src/cmd/compile/internal/base/hashdebug.go
@@ -0,0 +1,323 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package base
+
+import (
+	"bytes"
+	"cmd/internal/notsha256"
+	"cmd/internal/obj"
+	"cmd/internal/src"
+	"fmt"
+	"io"
+	"os"
+	"strconv"
+	"strings"
+	"sync"
+)
+
+type writeSyncer interface {
+	io.Writer
+	Sync() error
+}
+
+type hashAndMask struct {
+	// a hash h matches if (h^hash)&mask == 0
+	hash uint64
+	mask uint64
+	name string // base name, or base name + "0", "1", etc.
+}
+
+type HashDebug struct {
+	mu   sync.Mutex // for logfile, posTmp, bytesTmp
+	name string     // base name of the flag/variable.
+	// what file (if any) receives the yes/no logging?
+	// default is os.Stdout
+	logfile  writeSyncer
+	posTmp   []src.Pos
+	bytesTmp bytes.Buffer
+	matches  []hashAndMask // A hash matches if one of these matches.
+	yes, no  bool
+}
+
+// The default compiler-debugging HashDebug, for "-d=gossahash=..."
+var hashDebug *HashDebug
+var FmaHash *HashDebug
+
+// DebugHashMatch reports whether debug variable Gossahash
+//
+//  1. is empty (returns true; this is a special more-quickly implemented case of 4 below)
+//
+//  2. is "y" or "Y" (returns true)
+//
+//  3. is "n" or "N" (returns false)
+//
+//  4. is a suffix of the sha1 hash of pkgAndName (returns true)
+//
+//  5. OR
+//     if the value is in the regular language "[01]+(;[01]+)+"
+//     test the [01]+ substrings after in order returning true
+//     for the first one that suffix-matches. The substrings AFTER
+//     the first semicolon are numbered 0,1, etc and are named
+//     fmt.Sprintf("%s%d", varname, number)
+//     Clause 5 is not really intended for human use and only
+//     matters for failures that require multiple triggers.
+//
+// Otherwise it returns false.
+//
+// Unless Flags.Gossahash is empty, when DebugHashMatch returns true the message
+//
+//	"%s triggered %s\n", varname, pkgAndName
+//
+// is printed on the file named in environment variable GSHS_LOGFILE,
+// or standard out if that is empty.  "Varname" is either the name of
+// the variable or the name of the substring, depending on which matched.
+//
+// Typical use:
+//
+//  1. you make a change to the compiler, say, adding a new phase
+//
+//  2. it is broken in some mystifying way, for example, make.bash builds a broken
+//     compiler that almost works, but crashes compiling a test in run.bash.
+//
+//  3. add this guard to the code, which by default leaves it broken, but does not
+//     run the broken new code if Flags.Gossahash is non-empty and non-matching:
+//
+//     if !base.DebugHashMatch(ir.PkgFuncName(fn)) {
+//     return nil // early exit, do nothing
+//     }
+//
+//  4. rebuild w/o the bad code,
+//     GOCOMPILEDEBUG=gossahash=n ./all.bash
+//     to verify that you put the guard in the right place with the right sense of the test.
+//
+//  5. use github.com/dr2chase/gossahash to search for the error:
+//
+//     go install github.com/dr2chase/gossahash@latest
+//
+//     gossahash -- <the thing that fails>
+//
+//     for example: GOMAXPROCS=1 gossahash -- ./all.bash
+//
+//  6. gossahash should return a single function whose miscompilation
+//     causes the problem, and you can focus on that.
+func DebugHashMatch(pkgAndName string) bool {
+	return hashDebug.DebugHashMatch(pkgAndName)
+}
+
+// HasDebugHash returns true if Flags.Gossahash is non-empty, which
+// results in hashDebug being not-nil.  I.e., if !HasDebugHash(),
+// there is no need to create the string for hashing and testing.
+func HasDebugHash() bool {
+	return hashDebug != nil
+}
+
+func toHashAndMask(s, varname string) hashAndMask {
+	l := len(s)
+	if l > 64 {
+		s = s[l-64:]
+		l = 64
+	}
+	m := ^(^uint64(0) << l)
+	h, err := strconv.ParseUint(s, 2, 64)
+	if err != nil {
+		Fatalf("Could not parse %s (=%s) as a binary number", varname, s)
+	}
+
+	return hashAndMask{name: varname, hash: h, mask: m}
+}
+
+// NewHashDebug returns a new hash-debug tester for the
+// environment variable ev.  If ev is not set, it returns
+// nil, allowing a lightweight check for normal-case behavior.
+func NewHashDebug(ev, s string, file writeSyncer) *HashDebug {
+	if s == "" {
+		return nil
+	}
+
+	hd := &HashDebug{name: ev, logfile: file}
+	switch s[0] {
+	case 'y', 'Y':
+		hd.yes = true
+		return hd
+	case 'n', 'N':
+		hd.no = true
+		return hd
+	}
+	ss := strings.Split(s, "/")
+	hd.matches = append(hd.matches, toHashAndMask(ss[0], ev))
+	// hash searches may use additional EVs with 0, 1, 2, ... suffixes.
+	for i := 1; i < len(ss); i++ {
+		evi := fmt.Sprintf("%s%d", ev, i-1) // convention is extras begin indexing at zero
+		hd.matches = append(hd.matches, toHashAndMask(ss[i], evi))
+	}
+	return hd
+
+}
+
+func hashOf(pkgAndName string, param uint64) uint64 {
+	return hashOfBytes([]byte(pkgAndName), param)
+}
+
+func hashOfBytes(sbytes []byte, param uint64) uint64 {
+	hbytes := notsha256.Sum256(sbytes)
+	hash := uint64(hbytes[7])<<56 + uint64(hbytes[6])<<48 +
+		uint64(hbytes[5])<<40 + uint64(hbytes[4])<<32 +
+		uint64(hbytes[3])<<24 + uint64(hbytes[2])<<16 +
+		uint64(hbytes[1])<<8 + uint64(hbytes[0])
+
+	if param != 0 {
+		// Because param is probably a line number, probably near zero,
+		// hash it up a little bit, but even so only the lower-order bits
+		// likely matter because search focuses on those.
+		p0 := param + uint64(hbytes[9]) + uint64(hbytes[10])<<8 +
+			uint64(hbytes[11])<<16 + uint64(hbytes[12])<<24
+
+		p1 := param + uint64(hbytes[13]) + uint64(hbytes[14])<<8 +
+			uint64(hbytes[15])<<16 + uint64(hbytes[16])<<24
+
+		param += p0 * p1
+		param ^= param>>17 ^ param<<47
+	}
+
+	return hash ^ param
+}
+
+// DebugHashMatch returns true if either the variable used to create d is
+// unset, or if its value is y, or if it is a suffix of the base-two
+// representation of the hash of pkgAndName.  If the variable is not nil,
+// then a true result is accompanied by stylized output to d.logfile, which
+// is used for automated bug search.
+func (d *HashDebug) DebugHashMatch(pkgAndName string) bool {
+	return d.DebugHashMatchParam(pkgAndName, 0)
+}
+
+// DebugHashMatchParam returns true if either the variable used to create d is
+// unset, or if its value is y, or if it is a suffix of the base-two
+// representation of the hash of pkgAndName and param. If the variable is not
+// nil, then a true result is accompanied by stylized output to d.logfile,
+// which is used for automated bug search.
+func (d *HashDebug) DebugHashMatchParam(pkgAndName string, param uint64) bool {
+	if d == nil {
+		return true
+	}
+	if d.no {
+		return false
+	}
+
+	if d.yes {
+		d.logDebugHashMatch(d.name, pkgAndName, "y", param)
+		return true
+	}
+
+	hash := hashOf(pkgAndName, param)
+
+	for _, m := range d.matches {
+		if (m.hash^hash)&m.mask == 0 {
+			hstr := ""
+			if hash == 0 {
+				hstr = "0"
+			} else {
+				for ; hash != 0; hash = hash >> 1 {
+					hstr = string('0'+byte(hash&1)) + hstr
+				}
+			}
+			d.logDebugHashMatch(m.name, pkgAndName, hstr, param)
+			return true
+		}
+	}
+	return false
+}
+
+// DebugHashMatchPos is similar to DebugHashMatchParam, but for hash computation
+// it uses the source position including all inlining information instead of
+// package name and path. The output trigger string is prefixed with "POS=" so
+// that tools processing the output can reliably tell the difference. The mutex
+// locking is also more frequent and more granular.
+func (d *HashDebug) DebugHashMatchPos(ctxt *obj.Link, pos src.XPos) bool {
+	if d == nil {
+		return true
+	}
+	if d.no {
+		return false
+	}
+	d.mu.Lock()
+	defer d.mu.Unlock()
+
+	b := d.bytesForPos(ctxt, pos)
+
+	if d.yes {
+		d.logDebugHashMatchLocked(d.name, string(b), "y", 0)
+		return true
+	}
+
+	hash := hashOfBytes(b, 0)
+
+	for _, m := range d.matches {
+		if (m.hash^hash)&m.mask == 0 {
+			hstr := ""
+			if hash == 0 {
+				hstr = "0"
+			} else {
+				for ; hash != 0; hash = hash >> 1 {
+					hstr = string('0'+byte(hash&1)) + hstr
+				}
+			}
+			d.logDebugHashMatchLocked(m.name, "POS="+string(b), hstr, 0)
+			return true
+		}
+	}
+	return false
+}
+
+// bytesForPos renders a position, including inlining, into d.bytesTmp
+// and returns the byte array.  d.mu must be locked.
+func (d *HashDebug) bytesForPos(ctxt *obj.Link, pos src.XPos) []byte {
+	d.posTmp = ctxt.AllPos(pos, d.posTmp)
+	// Reverse posTmp to put outermost first.
+	b := &d.bytesTmp
+	b.Reset()
+	for i := len(d.posTmp) - 1; i >= 0; i-- {
+		p := &d.posTmp[i]
+		fmt.Fprintf(b, "%s:%d:%d", p.Filename(), p.Line(), p.Col())
+		if i != 0 {
+			b.WriteByte(';')
+		}
+	}
+	return b.Bytes()
+}
+
+func (d *HashDebug) logDebugHashMatch(varname, name, hstr string, param uint64) {
+	d.mu.Lock()
+	defer d.mu.Unlock()
+	d.logDebugHashMatchLocked(varname, name, hstr, param)
+}
+
+func (d *HashDebug) logDebugHashMatchLocked(varname, name, hstr string, param uint64) {
+	file := d.logfile
+	if file == nil {
+		if tmpfile := os.Getenv("GSHS_LOGFILE"); tmpfile != "" {
+			var err error
+			file, err = os.OpenFile(tmpfile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
+			if err != nil {
+				Fatalf("could not open hash-testing logfile %s", tmpfile)
+				return
+			}
+		}
+		if file == nil {
+			file = os.Stdout
+		}
+		d.logfile = file
+	}
+	if len(hstr) > 24 {
+		hstr = hstr[len(hstr)-24:]
+	}
+	// External tools depend on this string
+	if param == 0 {
+		fmt.Fprintf(file, "%s triggered %s %s\n", varname, name, hstr)
+	} else {
+		fmt.Fprintf(file, "%s triggered %s:%d %s\n", varname, name, param, hstr)
+	}
+	file.Sync()
+}
diff --git a/src/cmd/compile/internal/base/hashdebug_test.go b/src/cmd/compile/internal/base/hashdebug_test.go
new file mode 100644
index 0000000..b74169f
--- /dev/null
+++ b/src/cmd/compile/internal/base/hashdebug_test.go
@@ -0,0 +1,164 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package base
+
+import (
+	"bytes"
+	"strings"
+	"testing"
+)
+
+func TestHashDebugGossahashY(t *testing.T) {
+	hd := NewHashDebug("GOSSAHASH", "y", nil)
+	if hd == nil {
+		t.Errorf("NewHashDebug should not return nil for GOSSASHASH=y")
+	}
+	if !hd.yes {
+		t.Errorf("NewHashDebug should return hd.yes==true for GOSSASHASH=y")
+	}
+	if hd.no {
+		t.Errorf("NewHashDebug should not return hd.no==true for GOSSASHASH=y")
+	}
+}
+
+func TestHashDebugGossahashN(t *testing.T) {
+	hd := NewHashDebug("GOSSAHASH", "n", nil)
+	if hd == nil {
+		t.Errorf("NewHashDebug should not return nil for GOSSASHASH=n")
+	}
+	if !hd.no {
+		t.Errorf("NewHashDebug should return hd.no==true GOSSASHASH=n")
+	}
+	if hd.yes {
+		t.Errorf("NewHashDebug should not return hd.yes==true for GOSSASHASH=n")
+	}
+}
+
+func TestHashDebugGossahashEmpty(t *testing.T) {
+	hd := NewHashDebug("GOSSAHASH", "", nil)
+	if hd != nil {
+		t.Errorf("NewHashDebug should return nil for GOSSASHASH=\"\"")
+	}
+}
+
+func TestHashDebugMagic(t *testing.T) {
+	hd := NewHashDebug("FOOXYZZY", "y", nil)
+	hd0 := NewHashDebug("FOOXYZZY0", "n", nil)
+	if hd == nil {
+		t.Errorf("NewHashDebug should have succeeded for FOOXYZZY")
+	}
+	if hd0 == nil {
+		t.Errorf("NewHashDebug should have succeeded for FOOXYZZY0")
+	}
+}
+
+func TestHash(t *testing.T) {
+	h0 := hashOf("bar", 0)
+	h1 := hashOf("bar", 1)
+	t.Logf(`These values are used in other tests: hashOf("bar,0)"=0x%x, hashOf("bar,1)"=0x%x`, h0, h1)
+	if h0 == h1 {
+		t.Errorf("Hashes 0x%x and 0x%x should differ", h0, h1)
+	}
+}
+
+func TestHashMatch(t *testing.T) {
+	ws := new(bufferWithSync)
+	hd := NewHashDebug("GOSSAHASH", "0011", ws)
+	check := hd.DebugHashMatch("bar")
+	msg := ws.String()
+	t.Logf("message was '%s'", msg)
+	if !check {
+		t.Errorf("GOSSAHASH=0011 should have matched for 'bar'")
+	}
+	wantPrefix(t, msg, "GOSSAHASH triggered bar ")
+}
+
+func TestHashMatchParam(t *testing.T) {
+	ws := new(bufferWithSync)
+	hd := NewHashDebug("GOSSAHASH", "1010", ws)
+	check := hd.DebugHashMatchParam("bar", 1)
+	msg := ws.String()
+	t.Logf("message was '%s'", msg)
+	if !check {
+		t.Errorf("GOSSAHASH=1010 should have matched for 'bar', 1")
+	}
+	wantPrefix(t, msg, "GOSSAHASH triggered bar:1 ")
+}
+
+func TestYMatch(t *testing.T) {
+	ws := new(bufferWithSync)
+	hd := NewHashDebug("GOSSAHASH", "y", ws)
+	check := hd.DebugHashMatch("bar")
+	msg := ws.String()
+	t.Logf("message was '%s'", msg)
+	if !check {
+		t.Errorf("GOSSAHASH=y should have matched for 'bar'")
+	}
+	wantPrefix(t, msg, "GOSSAHASH triggered bar y")
+}
+
+func TestNMatch(t *testing.T) {
+	ws := new(bufferWithSync)
+	hd := NewHashDebug("GOSSAHASH", "n", ws)
+	check := hd.DebugHashMatch("bar")
+	msg := ws.String()
+	t.Logf("message was '%s'", msg)
+	if check {
+		t.Errorf("GOSSAHASH=n should NOT have matched for 'bar'")
+	}
+	if msg != "" {
+		t.Errorf("Message should have been empty, instead %s", msg)
+	}
+}
+
+func TestHashNoMatch(t *testing.T) {
+	ws := new(bufferWithSync)
+	hd := NewHashDebug("GOSSAHASH", "001100", ws)
+	check := hd.DebugHashMatch("bar")
+	msg := ws.String()
+	t.Logf("message was '%s'", msg)
+	if check {
+		t.Errorf("GOSSAHASH=001100 should NOT have matched for 'bar'")
+	}
+	if msg != "" {
+		t.Errorf("Message should have been empty, instead %s", msg)
+	}
+
+}
+
+func TestHashSecondMatch(t *testing.T) {
+	ws := new(bufferWithSync)
+	hd := NewHashDebug("GOSSAHASH", "001100/0011", ws)
+
+	check := hd.DebugHashMatch("bar")
+	msg := ws.String()
+	t.Logf("message was '%s'", msg)
+	if !check {
+		t.Errorf("GOSSAHASH=001100, GOSSAHASH0=0011 should have matched for 'bar'")
+	}
+	wantPrefix(t, msg, "GOSSAHASH0 triggered bar")
+}
+
+type bufferWithSync struct {
+	b bytes.Buffer
+}
+
+func (ws *bufferWithSync) Sync() error {
+	return nil
+}
+
+func (ws *bufferWithSync) Write(p []byte) (n int, err error) {
+	return (&ws.b).Write(p)
+}
+
+func (ws *bufferWithSync) String() string {
+	return strings.TrimSpace((&ws.b).String())
+}
+
+func wantPrefix(t *testing.T, got, want string) {
+	if !strings.HasPrefix(got, want) {
+		t.Errorf("Want %s, got %s", want, got)
+	}
+}
diff --git a/src/cmd/compile/internal/base/link.go b/src/cmd/compile/internal/base/link.go
index 49fe435..d8aa5a7 100644
--- a/src/cmd/compile/internal/base/link.go
+++ b/src/cmd/compile/internal/base/link.go
@@ -8,6 +8,19 @@
 	"cmd/internal/obj"
 )
 
+// ReservedImports are import paths used internally for generated
+// symbols by the compiler.
+//
+// The linker uses the magic symbol prefixes "go:" and "type:".
+// Avoid potential confusion between import paths and symbols
+// by rejecting these reserved imports for now. Also, people
+// "can do weird things in GOPATH and we'd prefer they didn't
+// do _that_ weird thing" (per rsc). See also #4257.
+var ReservedImports = map[string]bool{
+	"go":   true,
+	"type": true,
+}
+
 var Ctxt *obj.Link
 
 // TODO(mdempsky): These should probably be obj.Link methods.
@@ -20,7 +33,11 @@
 		// TODO(mdempsky): Cleanup callers and Fatalf instead.
 		return linksym(prefix, "_", abi)
 	}
-	return linksym(prefix, prefix+"."+name, abi)
+	sep := "."
+	if ReservedImports[prefix] {
+		sep = ":"
+	}
+	return linksym(prefix, prefix+sep+name, abi)
 }
 
 // Linkname returns the linker symbol for the given name as it might
diff --git a/src/cmd/compile/internal/base/mapfile_mmap.go b/src/cmd/compile/internal/base/mapfile_mmap.go
index c1616db..bbcfda2 100644
--- a/src/cmd/compile/internal/base/mapfile_mmap.go
+++ b/src/cmd/compile/internal/base/mapfile_mmap.go
@@ -2,14 +2,14 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd
-// +build darwin dragonfly freebsd linux netbsd openbsd
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || (solaris && go1.20)
 
 package base
 
 import (
+	"internal/unsafeheader"
 	"os"
-	"reflect"
+	"runtime"
 	"syscall"
 	"unsafe"
 )
@@ -17,7 +17,7 @@
 // TODO(mdempsky): Is there a higher-level abstraction that still
 // works well for iimport?
 
-// mapFile returns length bytes from the file starting at the
+// MapFile returns length bytes from the file starting at the
 // specified offset as a string.
 func MapFile(f *os.File, offset, length int64) (string, error) {
 	// POSIX mmap: "The implementation may require that off is a
@@ -27,23 +27,19 @@
 	length += x
 
 	buf, err := syscall.Mmap(int(f.Fd()), offset, int(length), syscall.PROT_READ, syscall.MAP_SHARED)
-	keepAlive(f)
+	runtime.KeepAlive(f)
 	if err != nil {
 		return "", err
 	}
 
 	buf = buf[x:]
-	pSlice := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
+	pSlice := (*unsafeheader.Slice)(unsafe.Pointer(&buf))
 
 	var res string
-	pString := (*reflect.StringHeader)(unsafe.Pointer(&res))
+	pString := (*unsafeheader.String)(unsafe.Pointer(&res))
 
 	pString.Data = pSlice.Data
 	pString.Len = pSlice.Len
 
 	return res, nil
 }
-
-// keepAlive is a reimplementation of runtime.KeepAlive, which wasn't
-// added until Go 1.7, whereas we need to compile with Go 1.4.
-var keepAlive = func(interface{}) {}
diff --git a/src/cmd/compile/internal/base/mapfile_read.go b/src/cmd/compile/internal/base/mapfile_read.go
index 01796a9..c1b84db 100644
--- a/src/cmd/compile/internal/base/mapfile_read.go
+++ b/src/cmd/compile/internal/base/mapfile_read.go
@@ -2,8 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd
-// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !(solaris && go1.20)
 
 package base
 
diff --git a/src/cmd/compile/internal/base/print.go b/src/cmd/compile/internal/base/print.go
index 955f9d2..21fa001 100644
--- a/src/cmd/compile/internal/base/print.go
+++ b/src/cmd/compile/internal/base/print.go
@@ -36,7 +36,7 @@
 	return numErrors
 }
 
-// SyntaxErrors returns the number of syntax errors reported
+// SyntaxErrors returns the number of syntax errors reported.
 func SyntaxErrors() int {
 	return numSyntaxErrors
 }
@@ -161,7 +161,7 @@
 	}
 }
 
-// Warnf reports a formatted warning at the current line.
+// Warn reports a formatted warning at the current line.
 // In general the Go compiler does NOT generate warnings,
 // so this should be used only when the user has opted in
 // to additional output by setting a particular flag.
diff --git a/src/cmd/compile/internal/compare/compare.go b/src/cmd/compile/internal/compare/compare.go
index c0017b1..512ad25 100644
--- a/src/cmd/compile/internal/compare/compare.go
+++ b/src/cmd/compile/internal/compare/compare.go
@@ -79,10 +79,93 @@
 	}
 }
 
+// EqStructCost returns the cost of an equality comparison of two structs.
+//
+// The cost is determined using an algorithm which takes into consideration
+// the size of the registers in the current architecture and the size of the
+// memory-only fields in the struct.
+func EqStructCost(t *types.Type) int64 {
+	cost := int64(0)
+
+	for i, fields := 0, t.FieldSlice(); i < len(fields); {
+		f := fields[i]
+
+		// Skip blank-named fields.
+		if f.Sym.IsBlank() {
+			i++
+			continue
+		}
+
+		n, _, next := eqStructFieldCost(t, i)
+
+		cost += n
+		i = next
+	}
+
+	return cost
+}
+
+// eqStructFieldCost returns the cost of an equality comparison of two struct fields.
+// t is the parent struct type, and i is the index of the field in the parent struct type.
+// eqStructFieldCost may compute the cost of several adjacent fields at once. It returns
+// the cost, the size of the set of fields it computed the cost for (in bytes), and the
+// index of the first field not part of the set of fields for which the cost
+// has already been calculated.
+func eqStructFieldCost(t *types.Type, i int) (int64, int64, int) {
+	var (
+		cost    = int64(0)
+		regSize = int64(types.RegSize)
+
+		size int64
+		next int
+	)
+
+	if base.Ctxt.Arch.CanMergeLoads {
+		// If we can merge adjacent loads then we can calculate the cost of the
+		// comparison using the size of the memory run and the size of the registers.
+		size, next = Memrun(t, i)
+		cost = size / regSize
+		if size%regSize != 0 {
+			cost++
+		}
+		return cost, size, next
+	}
+
+	// If we cannot merge adjacent loads then we have to use the size of the
+	// field and take into account the type to determine how many loads and compares
+	// are needed.
+	ft := t.Field(i).Type
+	size = ft.Size()
+	next = i + 1
+
+	return calculateCostForType(ft), size, next
+}
+
+func calculateCostForType(t *types.Type) int64 {
+	var cost int64
+	switch t.Kind() {
+	case types.TSTRUCT:
+		return EqStructCost(t)
+	case types.TSLICE:
+		// Slices are not comparable.
+		base.Fatalf("eqStructFieldCost: unexpected slice type")
+	case types.TARRAY:
+		elemCost := calculateCostForType(t.Elem())
+		cost = t.NumElem() * elemCost
+	case types.TSTRING, types.TINTER, types.TCOMPLEX64, types.TCOMPLEX128:
+		cost = 2
+	case types.TINT64, types.TUINT64:
+		cost = 8 / int64(types.RegSize)
+	default:
+		cost = 1
+	}
+	return cost
+}
+
 // EqStruct compares two structs np and nq for equality.
 // It works by building a list of boolean conditions to satisfy.
 // Conditions must be evaluated in the returned order and
-// properly short circuited by the caller.
+// properly short-circuited by the caller.
 func EqStruct(t *types.Type, np, nq ir.Node) []ir.Node {
 	// The conditions are a list-of-lists. Conditions are reorderable
 	// within each inner list. The outer lists must be evaluated in order.
@@ -128,18 +211,15 @@
 			continue
 		}
 
-		// Find maximal length run of memory-only fields.
-		size, next := Memrun(t, i)
-
-		// TODO(rsc): All the calls to newname are wrong for
-		// cross-package unexported fields.
-		if s := fields[i:next]; len(s) <= 2 {
-			// Two or fewer fields: use plain field equality.
+		cost, size, next := eqStructFieldCost(t, i)
+		if cost <= 4 {
+			// Cost of 4 or less: use plain field equality.
+			s := fields[i:next]
 			for _, f := range s {
 				and(eqfield(np, nq, ir.OEQ, f.Sym))
 			}
 		} else {
-			// More than two fields: use memequal.
+			// Higher cost: use memequal.
 			cc := eqmem(np, nq, f.Sym, size)
 			and(cc)
 		}
diff --git a/src/cmd/compile/internal/compare/compare_test.go b/src/cmd/compile/internal/compare/compare_test.go
new file mode 100644
index 0000000..db34657
--- /dev/null
+++ b/src/cmd/compile/internal/compare/compare_test.go
@@ -0,0 +1,182 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package compare
+
+import (
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"cmd/internal/obj"
+	"cmd/internal/src"
+	"cmd/internal/sys"
+	"testing"
+)
+
+type typefn func() *types.Type
+
+func init() {
+	// These are the few constants that need to be initialized in order to use
+	// the types package without using the typecheck package by calling
+	// typecheck.InitUniverse() (the normal way to initialize the types package).
+	types.PtrSize = 8
+	types.RegSize = 8
+	types.MaxWidth = 1 << 50
+	typecheck.InitUniverse()
+	base.Ctxt = &obj.Link{Arch: &obj.LinkArch{Arch: &sys.Arch{Alignment: 1, CanMergeLoads: true}}}
+}
+
+func TestEqStructCost(t *testing.T) {
+	newByteField := func(parent *types.Type, offset int64) *types.Field {
+		f := types.NewField(src.XPos{}, parent.Sym(), types.ByteType)
+		f.Offset = offset
+		return f
+	}
+	newArrayField := func(parent *types.Type, offset int64, len int64, kind types.Kind) *types.Field {
+		f := types.NewField(src.XPos{}, parent.Sym(), types.NewArray(types.Types[kind], len))
+		// Call Type.Size here to force the size calculation to be done. If not done here the size returned later is incorrect.
+		f.Type.Size()
+		f.Offset = offset
+		return f
+	}
+	newField := func(parent *types.Type, offset int64, kind types.Kind) *types.Field {
+		f := types.NewField(src.XPos{}, parent.Sym(), types.Types[kind])
+		f.Offset = offset
+		return f
+	}
+	tt := []struct {
+		name             string
+		cost             int64
+		nonMergeLoadCost int64
+		tfn              typefn
+	}{
+		{"struct without fields", 0, 0,
+			func() *types.Type {
+				return types.NewStruct(types.NewPkg("main", ""), []*types.Field{})
+			}},
+		{"struct with 1 byte field", 1, 1,
+			func() *types.Type {
+				parent := types.NewStruct(types.NewPkg("main", ""), []*types.Field{})
+				fields := []*types.Field{
+					newByteField(parent, 0),
+				}
+				parent.SetFields(fields)
+				return parent
+			},
+		},
+		{"struct with 8 byte fields", 1, 8,
+			func() *types.Type {
+				parent := types.NewStruct(types.NewPkg("main", ""), []*types.Field{})
+				fields := make([]*types.Field, 8)
+				for i := range fields {
+					fields[i] = newByteField(parent, int64(i))
+				}
+				parent.SetFields(fields)
+				return parent
+			},
+		},
+		{"struct with 16 byte fields", 2, 16,
+			func() *types.Type {
+				parent := types.NewStruct(types.NewPkg("main", ""), []*types.Field{})
+				fields := make([]*types.Field, 16)
+				for i := range fields {
+					fields[i] = newByteField(parent, int64(i))
+				}
+				parent.SetFields(fields)
+				return parent
+			},
+		},
+		{"struct with 32 byte fields", 4, 32,
+			func() *types.Type {
+				parent := types.NewStruct(types.NewPkg("main", ""), []*types.Field{})
+				fields := make([]*types.Field, 32)
+				for i := range fields {
+					fields[i] = newByteField(parent, int64(i))
+				}
+				parent.SetFields(fields)
+				return parent
+			},
+		},
+		{"struct with 2 int32 fields", 1, 2,
+			func() *types.Type {
+				parent := types.NewStruct(types.NewPkg("main", ""), []*types.Field{})
+				fields := make([]*types.Field, 2)
+				for i := range fields {
+					fields[i] = newField(parent, int64(i*4), types.TINT32)
+				}
+				parent.SetFields(fields)
+				return parent
+			},
+		},
+		{"struct with 2 int32 fields and 1 int64", 2, 3,
+			func() *types.Type {
+				parent := types.NewStruct(types.NewPkg("main", ""), []*types.Field{})
+				fields := make([]*types.Field, 3)
+				fields[0] = newField(parent, int64(0), types.TINT32)
+				fields[1] = newField(parent, int64(4), types.TINT32)
+				fields[2] = newField(parent, int64(8), types.TINT64)
+				parent.SetFields(fields)
+				return parent
+			},
+		},
+		{"struct with 1 int field and 1 string", 3, 3,
+			func() *types.Type {
+				parent := types.NewStruct(types.NewPkg("main", ""), []*types.Field{})
+				fields := make([]*types.Field, 2)
+				fields[0] = newField(parent, int64(0), types.TINT64)
+				fields[1] = newField(parent, int64(8), types.TSTRING)
+				parent.SetFields(fields)
+				return parent
+			},
+		},
+		{"struct with 2 strings", 4, 4,
+			func() *types.Type {
+				parent := types.NewStruct(types.NewPkg("main", ""), []*types.Field{})
+				fields := make([]*types.Field, 2)
+				fields[0] = newField(parent, int64(0), types.TSTRING)
+				fields[1] = newField(parent, int64(8), types.TSTRING)
+				parent.SetFields(fields)
+				return parent
+			},
+		},
+		{"struct with 1 large byte array field", 26, 101,
+			func() *types.Type {
+				parent := types.NewStruct(types.NewPkg("main", ""), []*types.Field{})
+				fields := []*types.Field{
+					newArrayField(parent, 0, 101, types.TUINT16),
+				}
+				parent.SetFields(fields)
+				return parent
+			},
+		},
+		{"struct with string array field", 4, 4,
+			func() *types.Type {
+				parent := types.NewStruct(types.NewPkg("main", ""), []*types.Field{})
+				fields := []*types.Field{
+					newArrayField(parent, 0, 2, types.TSTRING),
+				}
+				parent.SetFields(fields)
+				return parent
+			},
+		},
+	}
+
+	for _, tc := range tt {
+		t.Run(tc.name, func(t *testing.T) {
+			want := tc.cost
+			base.Ctxt.Arch.CanMergeLoads = true
+			actual := EqStructCost(tc.tfn())
+			if actual != want {
+				t.Errorf("CanMergeLoads=true EqStructCost(%v) = %d, want %d", tc.tfn, actual, want)
+			}
+
+			base.Ctxt.Arch.CanMergeLoads = false
+			want = tc.nonMergeLoadCost
+			actual = EqStructCost(tc.tfn())
+			if actual != want {
+				t.Errorf("CanMergeLoads=false EqStructCost(%v) = %d, want %d", tc.tfn, actual, want)
+			}
+		})
+	}
+}
diff --git a/src/cmd/compile/internal/coverage/cover.go b/src/cmd/compile/internal/coverage/cover.go
new file mode 100644
index 0000000..688728d
--- /dev/null
+++ b/src/cmd/compile/internal/coverage/cover.go
@@ -0,0 +1,209 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package coverage
+
+// This package contains support routines for coverage "fixup" in the
+// compiler, which happens when compiling a package whose source code
+// has been run through "cmd/cover" to add instrumentation. The two
+// important entry points are FixupVars (called prior to package init
+// generation) and FixupInit (called following package init
+// generation).
+
+import (
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"cmd/internal/objabi"
+	"internal/coverage"
+	"strconv"
+	"strings"
+)
+
+// Names records state information collected in the first fixup
+// phase so that it can be passed to the second fixup phase.
+type Names struct {
+	MetaVar     *ir.Name
+	PkgIdVar    *ir.Name
+	InitFn      *ir.Func
+	CounterMode coverage.CounterMode
+	CounterGran coverage.CounterGranularity
+}
+
+// FixupVars is the first of two entry points for coverage compiler
+// fixup. It collects and returns the package ID and meta-data
+// variables being used for this "-cover" build, along with the
+// coverage counter mode and granularity. It also reclassifies selected
+// variables (for example, tagging coverage counter variables with
+// flags so that they can be handled properly downstream).
+func FixupVars() Names {
+	metaVarName := base.Flag.Cfg.CoverageInfo.MetaVar
+	pkgIdVarName := base.Flag.Cfg.CoverageInfo.PkgIdVar
+	counterMode := base.Flag.Cfg.CoverageInfo.CounterMode
+	counterGran := base.Flag.Cfg.CoverageInfo.CounterGranularity
+	counterPrefix := base.Flag.Cfg.CoverageInfo.CounterPrefix
+	var metavar *ir.Name
+	var pkgidvar *ir.Name
+
+	ckTypSanity := func(nm *ir.Name, tag string) {
+		if nm.Type() == nil || nm.Type().HasPointers() {
+			base.Fatalf("unsuitable %s %q mentioned in coveragecfg, improper type '%v'", tag, nm.Sym().Name, nm.Type())
+		}
+	}
+
+	for _, n := range typecheck.Target.Decls {
+		as, ok := n.(*ir.AssignStmt)
+		if !ok {
+			continue
+		}
+		nm, ok := as.X.(*ir.Name)
+		if !ok {
+			continue
+		}
+		s := nm.Sym()
+		switch s.Name {
+		case metaVarName:
+			metavar = nm
+			ckTypSanity(nm, "metavar")
+			nm.MarkReadonly()
+			continue
+		case pkgIdVarName:
+			pkgidvar = nm
+			ckTypSanity(nm, "pkgidvar")
+			nm.SetCoverageAuxVar(true)
+			s := nm.Linksym()
+			s.Type = objabi.SCOVERAGE_AUXVAR
+			continue
+		}
+		if strings.HasPrefix(s.Name, counterPrefix) {
+			ckTypSanity(nm, "countervar")
+			nm.SetCoverageCounter(true)
+			s := nm.Linksym()
+			s.Type = objabi.SCOVERAGE_COUNTER
+		}
+	}
+	cm := coverage.ParseCounterMode(counterMode)
+	if cm == coverage.CtrModeInvalid {
+		base.Fatalf("bad setting %q for covermode in coveragecfg:",
+			counterMode)
+	}
+	var cg coverage.CounterGranularity
+	switch counterGran {
+	case "perblock":
+		cg = coverage.CtrGranularityPerBlock
+	case "perfunc":
+		cg = coverage.CtrGranularityPerFunc
+	default:
+		base.Fatalf("bad setting %q for covergranularity in coveragecfg:",
+			counterGran)
+	}
+
+	return Names{
+		MetaVar:     metavar,
+		PkgIdVar:    pkgidvar,
+		CounterMode: cm,
+		CounterGran: cg,
+	}
+}
+
+// FixupInit is the second main entry point for coverage compiler
+// fixup. It adds calls to the pkg init function as appropriate to
+// register coverage-related variables with the runtime.
+func FixupInit(cnames Names) {
+	for _, n := range typecheck.Target.Decls {
+		if fn, ok := n.(*ir.Func); ok && ir.FuncName(fn) == "init" {
+			cnames.InitFn = fn
+			break
+		}
+	}
+	if cnames.InitFn == nil {
+		panic("unexpected (no init func for -cover build)")
+	}
+
+	hashv, len := metaHashAndLen()
+	if cnames.CounterMode != coverage.CtrModeTestMain {
+		registerMeta(cnames, hashv, len)
+	}
+	if base.Ctxt.Pkgpath == "main" {
+		addInitHookCall(cnames.InitFn, cnames.CounterMode)
+	}
+}
+
+func metaHashAndLen() ([16]byte, int) {
+
+	// Read meta-data hash from config entry.
+	mhash := base.Flag.Cfg.CoverageInfo.MetaHash
+	if len(mhash) != 32 {
+		base.Fatalf("unexpected: got metahash length %d want 32", len(mhash))
+	}
+	var hv [16]byte
+	for i := 0; i < 16; i++ {
+		nib := string(mhash[i*2 : i*2+2])
+		x, err := strconv.ParseInt(nib, 16, 32)
+		if err != nil {
+			base.Fatalf("metahash bad byte %q", nib)
+		}
+		hv[i] = byte(x)
+	}
+
+	// Return hash and meta-data len
+	return hv, base.Flag.Cfg.CoverageInfo.MetaLen
+}
+
+func registerMeta(cnames Names, hashv [16]byte, mdlen int) {
+	// Materialize expression for hash (an array literal)
+	pos := cnames.InitFn.Pos()
+	elist := make([]ir.Node, 0, 16)
+	for i := 0; i < 16; i++ {
+		elem := ir.NewInt(int64(hashv[i]))
+		elist = append(elist, elem)
+	}
+	ht := types.NewArray(types.Types[types.TUINT8], 16)
+	hashx := ir.NewCompLitExpr(pos, ir.OCOMPLIT, ht, elist)
+
+	// Materalize expression corresponding to address of the meta-data symbol.
+	mdax := typecheck.NodAddr(cnames.MetaVar)
+	mdauspx := typecheck.ConvNop(mdax, types.Types[types.TUNSAFEPTR])
+
+	// Materialize expression for length.
+	lenx := ir.NewInt(int64(mdlen)) // untyped
+
+	// Generate a call to runtime.addCovMeta, e.g.
+	//
+	//   pkgIdVar = runtime.addCovMeta(&sym, len, hash, pkgpath, pkid, cmode, cgran)
+	//
+	fn := typecheck.LookupRuntime("addCovMeta")
+	pkid := coverage.HardCodedPkgID(base.Ctxt.Pkgpath)
+	pkIdNode := ir.NewInt(int64(pkid))
+	cmodeNode := ir.NewInt(int64(cnames.CounterMode))
+	cgranNode := ir.NewInt(int64(cnames.CounterGran))
+	pkPathNode := ir.NewString(base.Ctxt.Pkgpath)
+	callx := typecheck.Call(pos, fn, []ir.Node{mdauspx, lenx, hashx,
+		pkPathNode, pkIdNode, cmodeNode, cgranNode}, false)
+	assign := callx
+	if pkid == coverage.NotHardCoded {
+		assign = typecheck.Stmt(ir.NewAssignStmt(pos, cnames.PkgIdVar, callx))
+	}
+
+	// Tack the call onto the start of our init function. We do this
+	// early in the init since it's possible that instrumented function
+	// bodies (with counter updates) might be inlined into init.
+	cnames.InitFn.Body.Prepend(assign)
+}
+
+// addInitHookCall generates a call to runtime/coverage.initHook() and
+// inserts it into the package main init function, which will kick off
+// the process for coverage data writing (emit meta data, and register
+// an exit hook to emit counter data).
+func addInitHookCall(initfn *ir.Func, cmode coverage.CounterMode) {
+	typecheck.InitCoverage()
+	pos := initfn.Pos()
+	istest := cmode == coverage.CtrModeTestMain
+	initf := typecheck.LookupCoverage("initHook")
+	istestNode := ir.NewBool(istest)
+	args := []ir.Node{istestNode}
+	callx := typecheck.Call(pos, initf, args, false)
+	initfn.Body.Append(callx)
+}
diff --git a/src/cmd/compile/internal/devirtualize/devirtualize.go b/src/cmd/compile/internal/devirtualize/devirtualize.go
index 60ba208..554e935 100644
--- a/src/cmd/compile/internal/devirtualize/devirtualize.go
+++ b/src/cmd/compile/internal/devirtualize/devirtualize.go
@@ -17,9 +17,25 @@
 // Func devirtualizes calls within fn where possible.
 func Func(fn *ir.Func) {
 	ir.CurFunc = fn
+
+	// For promoted methods (including value-receiver methods promoted to pointer-receivers),
+	// the interface method wrapper may contain expressions that can panic (e.g., ODEREF, ODOTPTR, ODOTINTER).
+	// Devirtualization involves inlining these expressions (and possible panics) to the call site.
+	// This normally isn't a problem, but for go/defer statements it can move the panic from when/where
+	// the call executes to the go/defer statement itself, which is a visible change in semantics (e.g., #52072).
+	// To prevent this, we skip devirtualizing calls within go/defer statements altogether.
+	goDeferCall := make(map[*ir.CallExpr]bool)
 	ir.VisitList(fn.Body, func(n ir.Node) {
-		if call, ok := n.(*ir.CallExpr); ok {
-			Call(call)
+		switch n := n.(type) {
+		case *ir.GoDeferStmt:
+			if call, ok := n.Call.(*ir.CallExpr); ok {
+				goDeferCall[call] = true
+			}
+			return
+		case *ir.CallExpr:
+			if !goDeferCall[n] {
+				Call(n)
+			}
 		}
 	})
 }
@@ -41,6 +57,60 @@
 		return
 	}
 
+	if base.Debug.Unified != 0 {
+		// N.B., stencil.go converts shape-typed values to interface type
+		// using OEFACE instead of OCONVIFACE, so devirtualization fails
+		// above instead. That's why this code is specific to unified IR.
+
+		// If typ is a shape type, then it was a type argument originally
+		// and we'd need an indirect call through the dictionary anyway.
+		// We're unable to devirtualize this call.
+		if typ.IsShape() {
+			return
+		}
+
+		// If typ *has* a shape type, then it's an shaped, instantiated
+		// type like T[go.shape.int], and its methods (may) have an extra
+		// dictionary parameter. We could devirtualize this call if we
+		// could derive an appropriate dictionary argument.
+		//
+		// TODO(mdempsky): If typ has has a promoted non-generic method,
+		// then that method won't require a dictionary argument. We could
+		// still devirtualize those calls.
+		//
+		// TODO(mdempsky): We have the *runtime.itab in recv.TypeWord. It
+		// should be possible to compute the represented type's runtime
+		// dictionary from this (e.g., by adding a pointer from T[int]'s
+		// *runtime._type to .dict.T[int]; or by recognizing static
+		// references to go:itab.T[int],iface and constructing a direct
+		// reference to .dict.T[int]).
+		if typ.HasShape() {
+			if base.Flag.LowerM != 0 {
+				base.WarnfAt(call.Pos(), "cannot devirtualize %v: shaped receiver %v", call, typ)
+			}
+			return
+		}
+
+		// Further, if sel.X's type has a shape type, then it's a shaped
+		// interface type. In this case, the (non-dynamic) TypeAssertExpr
+		// we construct below would attempt to create an itab
+		// corresponding to this shaped interface type; but the actual
+		// itab pointer in the interface value will correspond to the
+		// original (non-shaped) interface type instead. These are
+		// functionally equivalent, but they have distinct pointer
+		// identities, which leads to the type assertion failing.
+		//
+		// TODO(mdempsky): We know the type assertion here is safe, so we
+		// could instead set a flag so that walk skips the itab check. For
+		// now, punting is easy and safe.
+		if sel.X.Type().HasShape() {
+			if base.Flag.LowerM != 0 {
+				base.WarnfAt(call.Pos(), "cannot devirtualize %v: shaped interface %v", call, sel.X.Type())
+			}
+			return
+		}
+	}
+
 	dt := ir.NewTypeAssertExpr(sel.Pos(), sel.X, nil)
 	dt.SetType(typ)
 	x := typecheck.Callee(ir.NewSelectorExpr(sel.Pos(), ir.OXDOT, dt, sel.Sel))
@@ -82,4 +152,7 @@
 	default:
 		call.SetType(ft.Results())
 	}
+
+	// Desugar OCALLMETH, if we created one (#57309).
+	typecheck.FixMethodCall(call)
 }
diff --git a/src/cmd/compile/internal/dwarfgen/dwarf.go b/src/cmd/compile/internal/dwarfgen/dwarf.go
index 4bbc048..90c331f 100644
--- a/src/cmd/compile/internal/dwarfgen/dwarf.go
+++ b/src/cmd/compile/internal/dwarfgen/dwarf.go
@@ -107,7 +107,7 @@
 	// the function symbol to insure that the type included in DWARF
 	// processing during linking.
 	typesyms := []*obj.LSym{}
-	for t, _ := range fnsym.Func().Autot {
+	for t := range fnsym.Func().Autot {
 		typesyms = append(typesyms, t)
 	}
 	sort.Sort(obj.BySymName(typesyms))
@@ -151,6 +151,21 @@
 	} else {
 		decls, vars, selected = createSimpleVars(fnsym, apDecls)
 	}
+	if fn.DebugInfo != nil {
+		// Recover zero sized variables eliminated by the stackframe pass
+		for _, n := range fn.DebugInfo.(*ssa.FuncDebug).OptDcl {
+			if n.Class != ir.PAUTO {
+				continue
+			}
+			types.CalcSize(n.Type())
+			if n.Type().Size() == 0 {
+				decls = append(decls, n)
+				vars = append(vars, createSimpleVar(fnsym, n))
+				vars[len(vars)-1].StackOffset = 0
+				fnsym.Func().RecordAutoType(reflectdata.TypeLinksym(n.Type()))
+			}
+		}
+	}
 
 	dcl := apDecls
 	if fnsym.WasInlined() {
@@ -471,7 +486,7 @@
 
 	gotype := reflectdata.TypeLinksym(n.Type())
 	delete(fnsym.Func().Autot, gotype)
-	typename := dwarf.InfoPrefix + gotype.Name[len("type."):]
+	typename := dwarf.InfoPrefix + gotype.Name[len("type:"):]
 	inlIndex := 0
 	if base.Flag.GenDwarfInl > 1 {
 		if n.InlFormal() || n.InlLocal() {
diff --git a/src/cmd/compile/internal/dwarfgen/scope_test.go b/src/cmd/compile/internal/dwarfgen/scope_test.go
index 3df4c34..502b66f 100644
--- a/src/cmd/compile/internal/dwarfgen/scope_test.go
+++ b/src/cmd/compile/internal/dwarfgen/scope_test.go
@@ -8,9 +8,7 @@
 	"debug/dwarf"
 	"fmt"
 	"internal/testenv"
-	"io/ioutil"
 	"os"
-	"os/exec"
 	"path/filepath"
 	"runtime"
 	"sort"
@@ -221,7 +219,7 @@
 		t.Skip("skipping on plan9; no DWARF symbol table in executables")
 	}
 
-	dir, err := ioutil.TempDir("", "TestScopeRanges")
+	dir, err := os.MkdirTemp("", "TestScopeRanges")
 	if err != nil {
 		t.Fatalf("could not create directory: %v", err)
 	}
@@ -475,7 +473,7 @@
 	}
 	args = append(args, "-o", dst, src)
 
-	cmd := exec.Command(testenv.GoToolPath(t), args...)
+	cmd := testenv.Command(t, testenv.GoToolPath(t), args...)
 	if b, err := cmd.CombinedOutput(); err != nil {
 		t.Logf("build: %s\n", string(b))
 		t.Fatal(err)
@@ -498,7 +496,7 @@
 		t.Skip("skipping on plan9; no DWARF symbol table in executables")
 	}
 
-	dir, err := ioutil.TempDir("", "TestEmptyDwarfRanges")
+	dir, err := os.MkdirTemp("", "TestEmptyDwarfRanges")
 	if err != nil {
 		t.Fatalf("could not create directory: %v", err)
 	}
diff --git a/src/cmd/compile/internal/escape/call.go b/src/cmd/compile/internal/escape/call.go
index ee76adb..448702e 100644
--- a/src/cmd/compile/internal/escape/call.go
+++ b/src/cmd/compile/internal/escape/call.go
@@ -19,7 +19,7 @@
 	var init ir.Nodes
 	e.callCommon(ks, call, &init, nil)
 	if len(init) != 0 {
-		call.(*ir.CallExpr).PtrInit().Append(init...)
+		call.(ir.InitNode).PtrInit().Append(init...)
 	}
 }
 
@@ -38,6 +38,18 @@
 		argumentFunc(nil, k, argp)
 	}
 
+	argumentRType := func(rtypep *ir.Node) {
+		rtype := *rtypep
+		if rtype == nil {
+			return
+		}
+		// common case: static rtype/itab argument, which can be evaluated within the wrapper instead.
+		if addr, ok := rtype.(*ir.AddrExpr); ok && addr.Op() == ir.OADDR && addr.X.Op() == ir.OLINKSYMOFFSET {
+			return
+		}
+		e.wrapExpr(rtype.Pos(), rtypep, init, call, wrapper)
+	}
+
 	switch call.Op() {
 	default:
 		ir.Dump("esc", call)
@@ -153,6 +165,7 @@
 				argument(e.heapHole(), &args[i])
 			}
 		}
+		argumentRType(&call.RType)
 
 	case ir.OCOPY:
 		call := call.(*ir.BinaryExpr)
@@ -163,6 +176,7 @@
 			copiedK = e.heapHole().deref(call, "copied slice")
 		}
 		argument(copiedK, &call.Y)
+		argumentRType(&call.RType)
 
 	case ir.OPANIC:
 		call := call.(*ir.UnaryExpr)
@@ -179,15 +193,21 @@
 		for i := range call.Args {
 			argument(e.discardHole(), &call.Args[i])
 		}
+		argumentRType(&call.RType)
 
 	case ir.OLEN, ir.OCAP, ir.OREAL, ir.OIMAG, ir.OCLOSE:
 		call := call.(*ir.UnaryExpr)
 		argument(e.discardHole(), &call.X)
 
-	case ir.OUNSAFEADD, ir.OUNSAFESLICE:
+	case ir.OUNSAFESTRINGDATA, ir.OUNSAFESLICEDATA:
+		call := call.(*ir.UnaryExpr)
+		argument(ks[0], &call.X)
+
+	case ir.OUNSAFEADD, ir.OUNSAFESLICE, ir.OUNSAFESTRING:
 		call := call.(*ir.BinaryExpr)
 		argument(ks[0], &call.X)
 		argument(e.discardHole(), &call.Y)
+		argumentRType(&call.RType)
 	}
 }
 
@@ -223,6 +243,10 @@
 
 	// If the function is already a zero argument/result function call,
 	// just escape analyze it normally.
+	//
+	// Note that the runtime is aware of this optimization for
+	// "go" statements that start in reflect.makeFuncStub or
+	// reflect.methodValueCall.
 	if call, ok := call.(*ir.CallExpr); ok && call.Op() == ir.OCALLFUNC {
 		if sig := call.X.Type(); sig.NumParams()+sig.NumResults() == 0 {
 			if clo, ok := call.X.(*ir.ClosureExpr); ok && n.Op() == ir.OGO {
diff --git a/src/cmd/compile/internal/escape/expr.go b/src/cmd/compile/internal/escape/expr.go
index 9c3e09d..fc56530 100644
--- a/src/cmd/compile/internal/escape/expr.go
+++ b/src/cmd/compile/internal/escape/expr.go
@@ -123,9 +123,13 @@
 		n := n.(*ir.BinaryExpr)
 		// Note: n.X is not needed because it can never point to memory that might escape.
 		e.expr(k, n.Y)
-	case ir.OIDATA, ir.OSPTR:
+	case ir.OITAB, ir.OIDATA, ir.OSPTR:
 		n := n.(*ir.UnaryExpr)
 		e.expr(k, n.X)
+	case ir.OSLICE2ARR:
+		// Converting a slice to array is effectively a deref.
+		n := n.(*ir.ConvExpr)
+		e.expr(k.deref(n, "slice-to-array"), n.X)
 	case ir.OSLICE2ARRPTR:
 		// the slice pointer flows directly to the result
 		n := n.(*ir.ConvExpr)
@@ -134,7 +138,9 @@
 		n := n.(*ir.UnaryExpr)
 		e.discard(n.X)
 
-	case ir.OCALLMETH, ir.OCALLFUNC, ir.OCALLINTER, ir.OINLCALL, ir.OLEN, ir.OCAP, ir.OCOMPLEX, ir.OREAL, ir.OIMAG, ir.OAPPEND, ir.OCOPY, ir.ORECOVER, ir.OUNSAFEADD, ir.OUNSAFESLICE:
+	case ir.OCALLMETH, ir.OCALLFUNC, ir.OCALLINTER, ir.OINLCALL,
+		ir.OLEN, ir.OCAP, ir.OCOMPLEX, ir.OREAL, ir.OIMAG, ir.OAPPEND, ir.OCOPY, ir.ORECOVER,
+		ir.OUNSAFEADD, ir.OUNSAFESLICE, ir.OUNSAFESTRING, ir.OUNSAFESTRINGDATA, ir.OUNSAFESLICEDATA:
 		e.call([]hole{k}, n)
 
 	case ir.ONEW:
diff --git a/src/cmd/compile/internal/escape/leaks.go b/src/cmd/compile/internal/escape/leaks.go
index 4c848a5..1432607 100644
--- a/src/cmd/compile/internal/escape/leaks.go
+++ b/src/cmd/compile/internal/escape/leaks.go
@@ -94,7 +94,7 @@
 	return s
 }
 
-// parseLeaks parses a binary string representing a leaks
+// parseLeaks parses a binary string representing a leaks.
 func parseLeaks(s string) leaks {
 	var l leaks
 	if !strings.HasPrefix(s, "esc:") {
diff --git a/src/cmd/compile/internal/escape/stmt.go b/src/cmd/compile/internal/escape/stmt.go
index 4e8dd90..90d4f2d 100644
--- a/src/cmd/compile/internal/escape/stmt.go
+++ b/src/cmd/compile/internal/escape/stmt.go
@@ -74,7 +74,11 @@
 		e.block(n.Body)
 		e.block(n.Else)
 
-	case ir.OFOR, ir.OFORUNTIL:
+	case ir.OCHECKNIL:
+		n := n.(*ir.UnaryExpr)
+		e.discard(n.X)
+
+	case ir.OFOR:
 		n := n.(*ir.ForStmt)
 		e.loopDepth++
 		e.discard(n.Cond)
diff --git a/src/cmd/compile/internal/gc/bootstrap.go b/src/cmd/compile/internal/gc/bootstrap.go
deleted file mode 100644
index 37b0d59..0000000
--- a/src/cmd/compile/internal/gc/bootstrap.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build !go1.8
-// +build !go1.8
-
-package gc
-
-import (
-	"cmd/compile/internal/base"
-	"runtime"
-)
-
-func startMutexProfiling() {
-	base.Fatalf("mutex profiling unavailable in version %v", runtime.Version())
-}
diff --git a/src/cmd/compile/internal/gc/compile.go b/src/cmd/compile/internal/gc/compile.go
index 0050445..6951d7e 100644
--- a/src/cmd/compile/internal/gc/compile.go
+++ b/src/cmd/compile/internal/gc/compile.go
@@ -44,7 +44,7 @@
 
 	if len(fn.Body) == 0 {
 		// Initialize ABI wrappers if necessary.
-		ssagen.InitLSym(fn, false)
+		ir.InitLSym(fn, false)
 		types.CalcSize(fn.Type())
 		a := ssagen.AbiForBodylessFuncStackMap(fn)
 		abiInfo := a.ABIAnalyzeFuncType(fn.Type().FuncType()) // abiInfo has spill/home locations for wrapper
@@ -82,7 +82,7 @@
 	// Set up the function's LSym early to avoid data races with the assemblers.
 	// Do this before walk, as walk needs the LSym to set attributes/relocations
 	// (e.g. in MarkTypeUsedInInterface).
-	ssagen.InitLSym(fn, true)
+	ir.InitLSym(fn, true)
 
 	// Calculate parameter offsets.
 	types.CalcSize(fn.Type())
@@ -126,20 +126,38 @@
 	}
 
 	if nWorkers := base.Flag.LowerC; nWorkers > 1 {
-		// For concurrent builds, we create a goroutine per task, but
-		// require them to hold a unique worker ID while performing work
-		// to limit parallelism.
-		workerIDs := make(chan int, nWorkers)
-		for i := 0; i < nWorkers; i++ {
-			workerIDs <- i
-		}
-
+		// For concurrent builds, we allow the work queue
+		// to grow arbitrarily large, but only nWorkers work items
+		// can be running concurrently.
+		workq := make(chan func(int))
+		done := make(chan int)
+		go func() {
+			ids := make([]int, nWorkers)
+			for i := range ids {
+				ids[i] = i
+			}
+			var pending []func(int)
+			for {
+				select {
+				case work := <-workq:
+					pending = append(pending, work)
+				case id := <-done:
+					ids = append(ids, id)
+				}
+				for len(pending) > 0 && len(ids) > 0 {
+					work := pending[len(pending)-1]
+					id := ids[len(ids)-1]
+					pending = pending[:len(pending)-1]
+					ids = ids[:len(ids)-1]
+					go func() {
+						work(id)
+						done <- id
+					}()
+				}
+			}
+		}()
 		queue = func(work func(int)) {
-			go func() {
-				worker := <-workerIDs
-				work(worker)
-				workerIDs <- worker
-			}()
+			workq <- work
 		}
 	}
 
diff --git a/src/cmd/compile/internal/gc/main.go b/src/cmd/compile/internal/gc/main.go
index 70f1a2f..4a37548 100644
--- a/src/cmd/compile/internal/gc/main.go
+++ b/src/cmd/compile/internal/gc/main.go
@@ -8,6 +8,7 @@
 	"bufio"
 	"bytes"
 	"cmd/compile/internal/base"
+	"cmd/compile/internal/coverage"
 	"cmd/compile/internal/deadcode"
 	"cmd/compile/internal/devirtualize"
 	"cmd/compile/internal/dwarfgen"
@@ -16,6 +17,7 @@
 	"cmd/compile/internal/ir"
 	"cmd/compile/internal/logopt"
 	"cmd/compile/internal/noder"
+	"cmd/compile/internal/pgo"
 	"cmd/compile/internal/pkginit"
 	"cmd/compile/internal/reflectdata"
 	"cmd/compile/internal/ssa"
@@ -73,16 +75,17 @@
 	base.DebugSSA = ssa.PhaseOption
 	base.ParseFlags()
 
-	types.LocalPkg = types.NewPkg(base.Ctxt.Pkgpath, "")
+	if os.Getenv("GOGC") == "" { // GOGC set disables starting heap adjustment
+		// More processors will use more heap, but assume that more memory is available.
+		// So 1 processor -> 40MB, 4 -> 64MB, 12 -> 128MB
+		base.AdjustStartingHeap(uint64(32+8*base.Flag.LowerC) << 20)
+	}
 
-	// We won't know localpkg's height until after import
-	// processing. In the mean time, set to MaxPkgHeight to ensure
-	// height comparisons at least work until then.
-	types.LocalPkg.Height = types.MaxPkgHeight
+	types.LocalPkg = types.NewPkg(base.Ctxt.Pkgpath, "")
 
 	// pseudo-package, for scoping
 	types.BuiltinPkg = types.NewPkg("go.builtin", "") // TODO(gri) name this package go.builtin?
-	types.BuiltinPkg.Prefix = "go.builtin"            // not go%2ebuiltin
+	types.BuiltinPkg.Prefix = "go:builtin"
 
 	// pseudo-package, accessed by import "unsafe"
 	types.UnsafePkg = types.NewPkg("unsafe", "unsafe")
@@ -97,11 +100,15 @@
 
 	// pseudo-packages used in symbol tables
 	ir.Pkgs.Itab = types.NewPkg("go.itab", "go.itab")
-	ir.Pkgs.Itab.Prefix = "go.itab" // not go%2eitab
+	ir.Pkgs.Itab.Prefix = "go:itab"
 
 	// pseudo-package used for methods with anonymous receivers
 	ir.Pkgs.Go = types.NewPkg("go", "")
 
+	// pseudo-package for use with code coverage instrumentation.
+	ir.Pkgs.Coverage = types.NewPkg("go.coverage", "runtime/coverage")
+	ir.Pkgs.Coverage.Prefix = "runtime/coverage"
+
 	// Record flags that affect the build result. (And don't
 	// record flags that don't, since that would cause spurious
 	// changes in the binary.)
@@ -203,6 +210,12 @@
 	// because it generates itabs for initializing global variables.
 	ssagen.InitConfig()
 
+	// First part of coverage fixup (if applicable).
+	var cnames coverage.Names
+	if base.Flag.Cfg.CoverageInfo != nil {
+		cnames = coverage.FixupVars()
+	}
+
 	// Create "init" function for package-scope variable initialization
 	// statements, if any.
 	//
@@ -212,6 +225,12 @@
 	// removal can skew the results (e.g., #43444).
 	pkginit.MakeInit()
 
+	// Second part of code coverage fixup (init func modification),
+	// if applicable.
+	if base.Flag.Cfg.CoverageInfo != nil {
+		coverage.FixupInit(cnames)
+	}
+
 	// Eliminate some obviously dead code.
 	// Must happen after typechecking.
 	for _, n := range typecheck.Target.Decls {
@@ -237,10 +256,17 @@
 		typecheck.AllImportedBodies()
 	}
 
+	// Read profile file and build profile-graph and weighted-call-graph.
+	base.Timer.Start("fe", "pgoprofile")
+	var profile *pgo.Profile
+	if base.Flag.PgoProfile != "" {
+		profile = pgo.New(base.Flag.PgoProfile)
+	}
+
 	// Inlining
 	base.Timer.Start("fe", "inlining")
 	if base.Flag.LowerL != 0 {
-		inline.InlinePackage()
+		inline.InlinePackage(profile)
 	}
 	noder.MakeWrappers(typecheck.Target) // must happen after inlining
 
diff --git a/src/cmd/compile/internal/gc/obj.go b/src/cmd/compile/internal/gc/obj.go
index 5008aa2..504072b 100644
--- a/src/cmd/compile/internal/gc/obj.go
+++ b/src/cmd/compile/internal/gc/obj.go
@@ -148,7 +148,7 @@
 	dumpglobls(typecheck.Target.Externs[numExterns:])
 
 	if reflectdata.ZeroSize > 0 {
-		zero := base.PkgLinksym("go.map", "zero", obj.ABI0)
+		zero := base.PkgLinksym("go:map", "zero", obj.ABI0)
 		objw.Global(zero, int32(reflectdata.ZeroSize), obj.DUPOK|obj.RODATA)
 		zero.Set(obj.AttrStatic, true)
 	}
@@ -195,6 +195,9 @@
 	}
 	types.CalcSize(n.Type())
 	ggloblnod(n)
+	if n.CoverageCounter() || n.CoverageAuxVar() {
+		return
+	}
 	base.Ctxt.DwarfGlobal(base.Ctxt.Pkgpath, types.TypeSymName(n.Type()), n.Linksym())
 }
 
@@ -316,6 +319,9 @@
 	if nam.Libfuzzer8BitCounter() {
 		s.Type = objabi.SLIBFUZZER_8BIT_COUNTER
 	}
+	if nam.CoverageCounter() {
+		s.Type = objabi.SCOVERAGE_COUNTER
+	}
 	if nam.Sym().Linkname != "" {
 		// Make sure linkname'd symbol is non-package. When a symbol is
 		// both imported and linkname'd, s.Pkg may not set to "_" in
diff --git a/src/cmd/compile/internal/gc/pprof.go b/src/cmd/compile/internal/gc/pprof.go
deleted file mode 100644
index 5f9b030..0000000
--- a/src/cmd/compile/internal/gc/pprof.go
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build go1.8
-// +build go1.8
-
-package gc
-
-import "runtime"
-
-func startMutexProfiling() {
-	runtime.SetMutexProfileFraction(1)
-}
diff --git a/src/cmd/compile/internal/gc/trace.go b/src/cmd/compile/internal/gc/trace.go
deleted file mode 100644
index 8cdbd4b..0000000
--- a/src/cmd/compile/internal/gc/trace.go
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build go1.7
-// +build go1.7
-
-package gc
-
-import (
-	"os"
-	tracepkg "runtime/trace"
-
-	"cmd/compile/internal/base"
-)
-
-func init() {
-	traceHandler = traceHandlerGo17
-}
-
-func traceHandlerGo17(traceprofile string) {
-	f, err := os.Create(traceprofile)
-	if err != nil {
-		base.Fatalf("%v", err)
-	}
-	if err := tracepkg.Start(f); err != nil {
-		base.Fatalf("%v", err)
-	}
-	base.AtExit(tracepkg.Stop)
-}
diff --git a/src/cmd/compile/internal/gc/util.go b/src/cmd/compile/internal/gc/util.go
index 56fd137..dcac0ce 100644
--- a/src/cmd/compile/internal/gc/util.go
+++ b/src/cmd/compile/internal/gc/util.go
@@ -8,12 +8,11 @@
 	"os"
 	"runtime"
 	"runtime/pprof"
+	tracepkg "runtime/trace"
 
 	"cmd/compile/internal/base"
 )
 
-var traceHandler func(string)
-
 func startProfile() {
 	if base.Flag.CPUProfile != "" {
 		f, err := os.Create(base.Flag.CPUProfile)
@@ -64,13 +63,20 @@
 		if err != nil {
 			base.Fatalf("%v", err)
 		}
-		startMutexProfiling()
+		runtime.SetMutexProfileFraction(1)
 		base.AtExit(func() {
 			pprof.Lookup("mutex").WriteTo(f, 0)
 			f.Close()
 		})
 	}
-	if base.Flag.TraceProfile != "" && traceHandler != nil {
-		traceHandler(base.Flag.TraceProfile)
+	if base.Flag.TraceProfile != "" {
+		f, err := os.Create(base.Flag.TraceProfile)
+		if err != nil {
+			base.Fatalf("%v", err)
+		}
+		if err := tracepkg.Start(f); err != nil {
+			base.Fatalf("%v", err)
+		}
+		base.AtExit(tracepkg.Stop)
 	}
 }
diff --git a/src/cmd/compile/internal/importer/gcimporter.go b/src/cmd/compile/internal/importer/gcimporter.go
index bcf0480..5d948f0 100644
--- a/src/cmd/compile/internal/importer/gcimporter.go
+++ b/src/cmd/compile/internal/importer/gcimporter.go
@@ -7,21 +7,62 @@
 
 import (
 	"bufio"
-	"cmd/compile/internal/types2"
+	"bytes"
 	"fmt"
 	"go/build"
 	"internal/pkgbits"
 	"io"
-	"io/ioutil"
 	"os"
+	"os/exec"
 	"path/filepath"
 	"strings"
+	"sync"
+
+	"cmd/compile/internal/types2"
 )
 
-// debugging/development support
-const debug = false
+var exportMap sync.Map // package dir → func() (string, bool)
 
-var pkgExts = [...]string{".a", ".o"}
+// lookupGorootExport returns the location of the export data
+// (normally found in the build cache, but located in GOROOT/pkg
+// in prior Go releases) for the package located in pkgDir.
+//
+// (We use the package's directory instead of its import path
+// mainly to simplify handling of the packages in src/vendor
+// and cmd/vendor.)
+func lookupGorootExport(pkgDir string) (string, bool) {
+	f, ok := exportMap.Load(pkgDir)
+	if !ok {
+		var (
+			listOnce   sync.Once
+			exportPath string
+		)
+		f, _ = exportMap.LoadOrStore(pkgDir, func() (string, bool) {
+			listOnce.Do(func() {
+				cmd := exec.Command("go", "list", "-export", "-f", "{{.Export}}", pkgDir)
+				cmd.Dir = build.Default.GOROOT
+				var output []byte
+				output, err := cmd.Output()
+				if err != nil {
+					return
+				}
+
+				exports := strings.Split(string(bytes.TrimSpace(output)), "\n")
+				if len(exports) != 1 {
+					return
+				}
+
+				exportPath = exports[0]
+			})
+
+			return exportPath, exportPath != ""
+		})
+	}
+
+	return f.(func() (string, bool))()
+}
+
+var pkgExts = [...]string{".a", ".o"} // a file from the build cache will have no extension
 
 // FindPkg returns the filename and unique package id for an import
 // path based on package information provided by build.Import (using
@@ -43,10 +84,17 @@
 		}
 		bp, _ := build.Import(path, srcDir, build.FindOnly|build.AllowBinary)
 		if bp.PkgObj == "" {
-			id = path // make sure we have an id to print in error message
-			return
+			var ok bool
+			if bp.Goroot && bp.Dir != "" {
+				filename, ok = lookupGorootExport(bp.Dir)
+			}
+			if !ok {
+				id = path // make sure we have an id to print in error message
+				return
+			}
+		} else {
+			noext = strings.TrimSuffix(bp.PkgObj, ".a")
 		}
-		noext = strings.TrimSuffix(bp.PkgObj, ".a")
 		id = bp.ImportPath
 
 	case build.IsLocalImport(path):
@@ -68,6 +116,11 @@
 		}
 	}
 
+	if filename != "" {
+		if f, err := os.Stat(filename); err == nil && !f.IsDir() {
+			return
+		}
+	}
 	// try extensions
 	for _, ext := range pkgExts {
 		filename = noext + ext
@@ -149,7 +202,7 @@
 		if size >= 0 {
 			r = io.LimitReader(r, int64(size))
 		}
-		data, err = ioutil.ReadAll(r)
+		data, err = io.ReadAll(r)
 		if err != nil {
 			break
 		}
diff --git a/src/cmd/compile/internal/importer/gcimporter_test.go b/src/cmd/compile/internal/importer/gcimporter_test.go
index 2fbd3f0..387c7c0 100644
--- a/src/cmd/compile/internal/importer/gcimporter_test.go
+++ b/src/cmd/compile/internal/importer/gcimporter_test.go
@@ -13,6 +13,7 @@
 	"internal/testenv"
 	"os"
 	"os/exec"
+	"path"
 	"path/filepath"
 	"runtime"
 	"strings"
@@ -25,29 +26,37 @@
 	os.Exit(m.Run())
 }
 
-// skipSpecialPlatforms causes the test to be skipped for platforms where
-// builders (build.golang.org) don't have access to compiled packages for
-// import.
-func skipSpecialPlatforms(t *testing.T) {
-	switch platform := runtime.GOOS + "-" + runtime.GOARCH; platform {
-	case "darwin-arm64":
-		t.Skipf("no compiled packages available for import on %s", platform)
-	}
-}
-
 // compile runs the compiler on filename, with dirname as the working directory,
 // and writes the output file to outdirname.
-func compile(t *testing.T, dirname, filename, outdirname string) string {
+// compile gives the resulting package a packagepath of testdata/<filebasename>.
+func compile(t *testing.T, dirname, filename, outdirname string, packagefiles map[string]string) string {
 	// filename must end with ".go"
-	if !strings.HasSuffix(filename, ".go") {
+	basename, ok := strings.CutSuffix(filepath.Base(filename), ".go")
+	if !ok {
+		t.Helper()
 		t.Fatalf("filename doesn't end in .go: %s", filename)
 	}
-	basename := filepath.Base(filename)
-	outname := filepath.Join(outdirname, basename[:len(basename)-2]+"o")
-	cmd := exec.Command(testenv.GoToolPath(t), "tool", "compile", "-p", strings.TrimSuffix(outname, ".o"), "-o", outname, filename)
+	objname := basename + ".o"
+	outname := filepath.Join(outdirname, objname)
+	pkgpath := path.Join("testdata", basename)
+
+	importcfgfile := os.DevNull
+	if len(packagefiles) > 0 {
+		importcfgfile = filepath.Join(outdirname, basename) + ".importcfg"
+		importcfg := new(bytes.Buffer)
+		for k, v := range packagefiles {
+			fmt.Fprintf(importcfg, "packagefile %s=%s\n", k, v)
+		}
+		if err := os.WriteFile(importcfgfile, importcfg.Bytes(), 0655); err != nil {
+			t.Fatal(err)
+		}
+	}
+
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "tool", "compile", "-p", pkgpath, "-D", "testdata", "-importcfg", importcfgfile, "-o", outname, filename)
 	cmd.Dir = dirname
 	out, err := cmd.CombinedOutput()
 	if err != nil {
+		t.Helper()
 		t.Logf("%s", out)
 		t.Fatalf("go tool compile %s failed: %s", filename, err)
 	}
@@ -65,37 +74,6 @@
 	return pkg
 }
 
-const maxTime = 30 * time.Second
-
-func testDir(t *testing.T, dir string, endTime time.Time) (nimports int) {
-	dirname := filepath.Join(testenv.GOROOT(t), "pkg", runtime.GOOS+"_"+runtime.GOARCH, dir)
-	list, err := os.ReadDir(dirname)
-	if err != nil {
-		t.Fatalf("testDir(%s): %s", dirname, err)
-	}
-	for _, f := range list {
-		if time.Now().After(endTime) {
-			t.Log("testing time used up")
-			return
-		}
-		switch {
-		case !f.IsDir():
-			// try extensions
-			for _, ext := range pkgExts {
-				if strings.HasSuffix(f.Name(), ext) {
-					name := f.Name()[0 : len(f.Name())-len(ext)] // remove extension
-					if testPath(t, filepath.Join(dir, name), dir) != nil {
-						nimports++
-					}
-				}
-			}
-		case f.IsDir():
-			nimports += testDir(t, filepath.Join(dir, f.Name()), endTime)
-		}
-	}
-	return
-}
-
 func mktmpdir(t *testing.T) string {
 	tmpdir, err := os.MkdirTemp("", "gcimporter_test")
 	if err != nil {
@@ -114,6 +92,8 @@
 		t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
 	}
 
+	testenv.MustHaveGoBuild(t)
+
 	testfiles := map[string][]string{
 		"exports.go":  {"go/ast", "go/token"},
 		"generics.go": nil,
@@ -129,7 +109,16 @@
 		tmpdir := mktmpdir(t)
 		defer os.RemoveAll(tmpdir)
 
-		compile(t, "testdata", testfile, filepath.Join(tmpdir, "testdata"))
+		importMap := map[string]string{}
+		for _, pkg := range wantImports {
+			export, _ := FindPkg(pkg, "testdata")
+			if export == "" {
+				t.Fatalf("no export data found for %s", pkg)
+			}
+			importMap[pkg] = export
+		}
+
+		compile(t, "testdata", testfile, filepath.Join(tmpdir, "testdata"), importMap)
 		path := "./testdata/" + strings.TrimSuffix(testfile, ".go")
 
 		if pkg := testPath(t, path, tmpdir); pkg != nil {
@@ -147,7 +136,7 @@
 }
 
 func TestVersionHandling(t *testing.T) {
-	skipSpecialPlatforms(t)
+	testenv.MustHaveGoBuild(t)
 
 	// This package only handles gc export data.
 	if runtime.Compiler != "gc" {
@@ -238,18 +227,39 @@
 }
 
 func TestImportStdLib(t *testing.T) {
-	skipSpecialPlatforms(t)
+	if testing.Short() {
+		t.Skip("the imports can be expensive, and this test is especially slow when the build cache is empty")
+	}
+	testenv.MustHaveGoBuild(t)
 
 	// This package only handles gc export data.
 	if runtime.Compiler != "gc" {
 		t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
 	}
 
-	dt := maxTime
-	if testing.Short() && testenv.Builder() == "" {
-		dt = 10 * time.Millisecond
+	// Get list of packages in stdlib. Filter out test-only packages with {{if .GoFiles}} check.
+	var stderr bytes.Buffer
+	cmd := exec.Command("go", "list", "-f", "{{if .GoFiles}}{{.ImportPath}}{{end}}", "std")
+	cmd.Stderr = &stderr
+	out, err := cmd.Output()
+	if err != nil {
+		t.Fatalf("failed to run go list to determine stdlib packages: %v\nstderr:\n%v", err, stderr.String())
 	}
-	nimports := testDir(t, "", time.Now().Add(dt)) // installed packages
+	pkgs := strings.Fields(string(out))
+
+	var nimports int
+	for _, pkg := range pkgs {
+		t.Run(pkg, func(t *testing.T) {
+			if testPath(t, pkg, filepath.Join(testenv.GOROOT(t), "src", path.Dir(pkg))) != nil {
+				nimports++
+			}
+		})
+	}
+	const minPkgs = 225 // 'GOOS=plan9 go1.18 list std | wc -l' reports 228; most other platforms have more.
+	if len(pkgs) < minPkgs {
+		t.Fatalf("too few packages (%d) were imported", nimports)
+	}
+
 	t.Logf("tested %d imports", nimports)
 }
 
@@ -278,7 +288,7 @@
 }
 
 func TestImportedTypes(t *testing.T) {
-	skipSpecialPlatforms(t)
+	testenv.MustHaveGoBuild(t)
 
 	// This package only handles gc export data.
 	if runtime.Compiler != "gc" {
@@ -361,7 +371,7 @@
 }
 
 func TestIssue5815(t *testing.T) {
-	skipSpecialPlatforms(t)
+	testenv.MustHaveGoBuild(t)
 
 	// This package only handles gc export data.
 	if runtime.Compiler != "gc" {
@@ -390,7 +400,7 @@
 
 // Smoke test to ensure that imported methods get the correct package.
 func TestCorrectMethodPackage(t *testing.T) {
-	skipSpecialPlatforms(t)
+	testenv.MustHaveGoBuild(t)
 
 	// This package only handles gc export data.
 	if runtime.Compiler != "gc" {
@@ -412,7 +422,7 @@
 }
 
 func TestIssue13566(t *testing.T) {
-	skipSpecialPlatforms(t)
+	testenv.MustHaveGoBuild(t)
 
 	// This package only handles gc export data.
 	if runtime.Compiler != "gc" {
@@ -436,8 +446,14 @@
 	if err != nil {
 		t.Fatal(err)
 	}
-	compile(t, "testdata", "a.go", testoutdir)
-	compile(t, testoutdir, bpath, testoutdir)
+
+	jsonExport, _ := FindPkg("encoding/json", "testdata")
+	if jsonExport == "" {
+		t.Fatalf("no export data found for encoding/json")
+	}
+
+	compile(t, "testdata", "a.go", testoutdir, map[string]string{"encoding/json": jsonExport})
+	compile(t, testoutdir, bpath, testoutdir, map[string]string{"testdata/a": filepath.Join(testoutdir, "a.o")})
 
 	// import must succeed (test for issue at hand)
 	pkg := importPkg(t, "./testdata/b", tmpdir)
@@ -451,7 +467,7 @@
 }
 
 func TestIssue13898(t *testing.T) {
-	skipSpecialPlatforms(t)
+	testenv.MustHaveGoBuild(t)
 
 	// This package only handles gc export data.
 	if runtime.Compiler != "gc" {
@@ -497,7 +513,7 @@
 }
 
 func TestIssue15517(t *testing.T) {
-	skipSpecialPlatforms(t)
+	testenv.MustHaveGoBuild(t)
 
 	// This package only handles gc export data.
 	if runtime.Compiler != "gc" {
@@ -513,7 +529,7 @@
 	tmpdir := mktmpdir(t)
 	defer os.RemoveAll(tmpdir)
 
-	compile(t, "testdata", "p.go", filepath.Join(tmpdir, "testdata"))
+	compile(t, "testdata", "p.go", filepath.Join(tmpdir, "testdata"), nil)
 
 	// Multiple imports of p must succeed without redeclaration errors.
 	// We use an import path that's not cleaned up so that the eventual
@@ -536,7 +552,7 @@
 }
 
 func TestIssue15920(t *testing.T) {
-	skipSpecialPlatforms(t)
+	testenv.MustHaveGoBuild(t)
 
 	// This package only handles gc export data.
 	if runtime.Compiler != "gc" {
@@ -553,7 +569,7 @@
 }
 
 func TestIssue20046(t *testing.T) {
-	skipSpecialPlatforms(t)
+	testenv.MustHaveGoBuild(t)
 
 	// This package only handles gc export data.
 	if runtime.Compiler != "gc" {
@@ -574,7 +590,7 @@
 	}
 }
 func TestIssue25301(t *testing.T) {
-	skipSpecialPlatforms(t)
+	testenv.MustHaveGoBuild(t)
 
 	// This package only handles gc export data.
 	if runtime.Compiler != "gc" {
@@ -591,7 +607,7 @@
 }
 
 func TestIssue25596(t *testing.T) {
-	skipSpecialPlatforms(t)
+	testenv.MustHaveGoBuild(t)
 
 	// This package only handles gc export data.
 	if runtime.Compiler != "gc" {
@@ -610,15 +626,17 @@
 func importPkg(t *testing.T, path, srcDir string) *types2.Package {
 	pkg, err := Import(make(map[string]*types2.Package), path, srcDir, nil)
 	if err != nil {
+		t.Helper()
 		t.Fatal(err)
 	}
 	return pkg
 }
 
 func compileAndImportPkg(t *testing.T, name string) *types2.Package {
+	t.Helper()
 	tmpdir := mktmpdir(t)
 	defer os.RemoveAll(tmpdir)
-	compile(t, "testdata", name+".go", filepath.Join(tmpdir, "testdata"))
+	compile(t, "testdata", name+".go", filepath.Join(tmpdir, "testdata"), nil)
 	return importPkg(t, "./testdata/"+name, tmpdir)
 }
 
@@ -626,6 +644,7 @@
 	if obj := scope.Lookup(name); obj != nil {
 		return obj
 	}
+	t.Helper()
 	t.Fatalf("%s not found", name)
 	return nil
 }
diff --git a/src/cmd/compile/internal/importer/iimport.go b/src/cmd/compile/internal/importer/iimport.go
index 576036b..24d3d4b 100644
--- a/src/cmd/compile/internal/importer/iimport.go
+++ b/src/cmd/compile/internal/importer/iimport.go
@@ -79,7 +79,7 @@
 
 const io_SeekCurrent = 1 // io.SeekCurrent (not defined in Go 1.4)
 
-// iImportData imports a package from the serialized package data
+// ImportData imports a package from the serialized package data
 // and returns the number of bytes consumed and a reference to the package.
 // If the export data version is not recognized or the format is otherwise
 // compromised, an error is returned.
@@ -139,22 +139,19 @@
 		pkgPathOff := r.uint64()
 		pkgPath := p.stringAt(pkgPathOff)
 		pkgName := p.stringAt(r.uint64())
-		pkgHeight := int(r.uint64())
+		_ = int(r.uint64()) // was package height, but not necessary anymore.
 
 		if pkgPath == "" {
 			pkgPath = path
 		}
 		pkg := imports[pkgPath]
 		if pkg == nil {
-			pkg = types2.NewPackageHeight(pkgPath, pkgName, pkgHeight)
+			pkg = types2.NewPackage(pkgPath, pkgName)
 			imports[pkgPath] = pkg
 		} else {
 			if pkg.Name() != pkgName {
 				errorf("conflicting names %s and %s for package %q", pkg.Name(), pkgName, path)
 			}
-			if pkg.Height() != pkgHeight {
-				errorf("conflicting heights %v and %v for package %q", pkg.Height(), pkgHeight, path)
-			}
 		}
 
 		p.pkgCache[pkgPathOff] = pkg
@@ -236,10 +233,7 @@
 	}
 
 	r := &importReader{p: p, currPkg: pkg}
-	// Reader.Reset is not available in Go 1.4.
-	// Use bytes.NewReader for now.
-	// r.declReader.Reset(p.declData[off:])
-	r.declReader = *strings.NewReader(p.declData[off:])
+	r.declReader.Reset(p.declData[off:])
 
 	r.obj(name)
 }
@@ -285,10 +279,7 @@
 	}
 
 	r := &importReader{p: p}
-	// Reader.Reset is not available in Go 1.4.
-	// Use bytes.NewReader for now.
-	// r.declReader.Reset(p.declData[off-predeclReserved:])
-	r.declReader = *strings.NewReader(p.declData[off-predeclReserved:])
+	r.declReader.Reset(p.declData[off-predeclReserved:])
 	t := r.doType(base)
 
 	if canReuse(base, t) {
diff --git a/src/cmd/compile/internal/importer/ureader.go b/src/cmd/compile/internal/importer/ureader.go
index e5547b6..f5c2f41 100644
--- a/src/cmd/compile/internal/importer/ureader.go
+++ b/src/cmd/compile/internal/importer/ureader.go
@@ -1,5 +1,3 @@
-// UNREVIEWED
-
 // Copyright 2021 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
@@ -39,7 +37,7 @@
 
 	r := pr.newReader(pkgbits.RelocMeta, pkgbits.PublicRootIdx, pkgbits.SyncPublic)
 	pkg := r.pkg()
-	r.Bool() // has init
+	r.Bool() // TODO(mdempsky): Remove; was "has init"
 
 	for i, n := 0, r.Len(); i < n; i++ {
 		// As if r.obj(), but avoiding the Scope.Lookup call,
@@ -85,6 +83,17 @@
 	}
 }
 
+func (pr *pkgReader) tempReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader {
+	return &reader{
+		Decoder: pr.TempDecoder(k, idx, marker),
+		p:       pr,
+	}
+}
+
+func (pr *pkgReader) retireReader(r *reader) {
+	pr.RetireDecoder(&r.Decoder)
+}
+
 // @@@ Positions
 
 func (r *reader) pos() syntax.Pos {
@@ -108,19 +117,21 @@
 	if b := pr.posBases[idx]; b != nil {
 		return b
 	}
-
-	r := pr.newReader(pkgbits.RelocPosBase, idx, pkgbits.SyncPosBase)
 	var b *syntax.PosBase
+	{
+		r := pr.tempReader(pkgbits.RelocPosBase, idx, pkgbits.SyncPosBase)
 
-	filename := r.String()
+		filename := r.String()
 
-	if r.Bool() {
-		b = syntax.NewTrimmedFileBase(filename, true)
-	} else {
-		pos := r.pos()
-		line := r.Uint()
-		col := r.Uint()
-		b = syntax.NewLineBase(pos, filename, true, line, col)
+		if r.Bool() {
+			b = syntax.NewTrimmedFileBase(filename, true)
+		} else {
+			pos := r.pos()
+			line := r.Uint()
+			col := r.Uint()
+			b = syntax.NewLineBase(pos, filename, true, line, col)
+		}
+		pr.retireReader(r)
 	}
 
 	pr.posBases[idx] = b
@@ -162,9 +173,7 @@
 	}
 
 	name := r.String()
-	height := r.Len()
-
-	pkg := types2.NewPackageHeight(path, name, height)
+	pkg := types2.NewPackage(path, name)
 	r.p.imports[path] = pkg
 
 	// TODO(mdempsky): The list of imported packages is important for
@@ -206,11 +215,15 @@
 		return typ
 	}
 
-	r := pr.newReader(pkgbits.RelocType, idx, pkgbits.SyncTypeIdx)
-	r.dict = dict
+	var typ types2.Type
+	{
+		r := pr.tempReader(pkgbits.RelocType, idx, pkgbits.SyncTypeIdx)
+		r.dict = dict
 
-	typ := r.doTyp()
-	assert(typ != nil)
+		typ = r.doTyp()
+		assert(typ != nil)
+		pr.retireReader(r)
+	}
 
 	// See comment in pkgReader.typIdx explaining how this happens.
 	if prev := *where; prev != nil {
@@ -365,12 +378,18 @@
 }
 
 func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types2.Package, string) {
-	rname := pr.newReader(pkgbits.RelocName, idx, pkgbits.SyncObject1)
+	var objPkg *types2.Package
+	var objName string
+	var tag pkgbits.CodeObj
+	{
+		rname := pr.tempReader(pkgbits.RelocName, idx, pkgbits.SyncObject1)
 
-	objPkg, objName := rname.qualifiedIdent()
-	assert(objName != "")
+		objPkg, objName = rname.qualifiedIdent()
+		assert(objName != "")
 
-	tag := pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj))
+		tag = pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj))
+		pr.retireReader(rname)
+	}
 
 	if tag == pkgbits.ObjStub {
 		base.Assertf(objPkg == nil || objPkg == types2.Unsafe, "unexpected stub package: %v", objPkg)
@@ -435,25 +454,27 @@
 }
 
 func (pr *pkgReader) objDictIdx(idx pkgbits.Index) *readerDict {
-	r := pr.newReader(pkgbits.RelocObjDict, idx, pkgbits.SyncObject1)
-
 	var dict readerDict
+	{
+		r := pr.tempReader(pkgbits.RelocObjDict, idx, pkgbits.SyncObject1)
 
-	if implicits := r.Len(); implicits != 0 {
-		base.Fatalf("unexpected object with %v implicit type parameter(s)", implicits)
+		if implicits := r.Len(); implicits != 0 {
+			base.Fatalf("unexpected object with %v implicit type parameter(s)", implicits)
+		}
+
+		dict.bounds = make([]typeInfo, r.Len())
+		for i := range dict.bounds {
+			dict.bounds[i] = r.typInfo()
+		}
+
+		dict.derived = make([]derivedInfo, r.Len())
+		dict.derivedTypes = make([]types2.Type, len(dict.derived))
+		for i := range dict.derived {
+			dict.derived[i] = derivedInfo{r.Reloc(pkgbits.RelocType), r.Bool()}
+		}
+
+		pr.retireReader(r)
 	}
-
-	dict.bounds = make([]typeInfo, r.Len())
-	for i := range dict.bounds {
-		dict.bounds[i] = r.typInfo()
-	}
-
-	dict.derived = make([]derivedInfo, r.Len())
-	dict.derivedTypes = make([]types2.Type, len(dict.derived))
-	for i := range dict.derived {
-		dict.derived[i] = derivedInfo{r.Reloc(pkgbits.RelocType), r.Bool()}
-	}
-
 	// function references follow, but reader doesn't need those
 
 	return &dict
diff --git a/src/cmd/compile/internal/inline/inl.go b/src/cmd/compile/internal/inline/inl.go
index 9ef016a..84e61f3 100644
--- a/src/cmd/compile/internal/inline/inl.go
+++ b/src/cmd/compile/internal/inline/inl.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 //
-// The inlining facility makes 2 passes: first caninl determines which
+// The inlining facility makes 2 passes: first CanInline determines which
 // functions are suitable for inlining, and for those that are it
 // saves a copy of the body. Then InlineCalls walks each function body to
 // expand calls to inlinable functions.
@@ -29,11 +29,14 @@
 import (
 	"fmt"
 	"go/constant"
+	"sort"
+	"strconv"
 	"strings"
 
 	"cmd/compile/internal/base"
 	"cmd/compile/internal/ir"
 	"cmd/compile/internal/logopt"
+	"cmd/compile/internal/pgo"
 	"cmd/compile/internal/typecheck"
 	"cmd/compile/internal/types"
 	"cmd/internal/obj"
@@ -53,30 +56,166 @@
 	inlineBigFunctionMaxCost = 20   // Max cost of inlinee when inlining into a "big" function.
 )
 
+var (
+	// List of all hot callee nodes.
+	// TODO(prattmic): Make this non-global.
+	candHotCalleeMap = make(map[*pgo.IRNode]struct{})
+
+	// List of all hot call sites. CallSiteInfo.Callee is always nil.
+	// TODO(prattmic): Make this non-global.
+	candHotEdgeMap = make(map[pgo.CallSiteInfo]struct{})
+
+	// List of inlined call sites. CallSiteInfo.Callee is always nil.
+	// TODO(prattmic): Make this non-global.
+	inlinedCallSites = make(map[pgo.CallSiteInfo]struct{})
+
+	// Threshold in percentage for hot callsite inlining.
+	inlineHotCallSiteThresholdPercent float64
+
+	// Threshold in CDF percentage for hot callsite inlining,
+	// that is, for a threshold of X the hottest callsites that
+	// make up the top X% of total edge weight will be
+	// considered hot for inlining candidates.
+	inlineCDFHotCallSiteThresholdPercent = float64(99)
+
+	// Budget increased due to hotness.
+	inlineHotMaxBudget int32 = 2000
+)
+
+// pgoInlinePrologue records the hot callsites from ir-graph.
+func pgoInlinePrologue(p *pgo.Profile, decls []ir.Node) {
+	if base.Debug.PGOInlineCDFThreshold != "" {
+		if s, err := strconv.ParseFloat(base.Debug.PGOInlineCDFThreshold, 64); err == nil && s >= 0 && s <= 100 {
+			inlineCDFHotCallSiteThresholdPercent = s
+		} else {
+			base.Fatalf("invalid PGOInlineCDFThreshold, must be between 0 and 100")
+		}
+	}
+	var hotCallsites []pgo.NodeMapKey
+	inlineHotCallSiteThresholdPercent, hotCallsites = hotNodesFromCDF(p)
+	if base.Debug.PGOInline > 0 {
+		fmt.Printf("hot-callsite-thres-from-CDF=%v\n", inlineHotCallSiteThresholdPercent)
+	}
+
+	if x := base.Debug.PGOInlineBudget; x != 0 {
+		inlineHotMaxBudget = int32(x)
+	}
+
+	for _, n := range hotCallsites {
+		// mark inlineable callees from hot edges
+		if callee := p.WeightedCG.IRNodes[n.CalleeName]; callee != nil {
+			candHotCalleeMap[callee] = struct{}{}
+		}
+		// mark hot call sites
+		if caller := p.WeightedCG.IRNodes[n.CallerName]; caller != nil {
+			csi := pgo.CallSiteInfo{LineOffset: n.CallSiteOffset, Caller: caller.AST}
+			candHotEdgeMap[csi] = struct{}{}
+		}
+	}
+
+	if base.Debug.PGOInline >= 2 {
+		fmt.Printf("hot-cg before inline in dot format:")
+		p.PrintWeightedCallGraphDOT(inlineHotCallSiteThresholdPercent)
+	}
+}
+
+// hotNodesFromCDF computes an edge weight threshold and the list of hot
+// nodes that make up the given percentage of the CDF. The threshold, as
+// a percent, is the lower bound of weight for nodes to be considered hot
+// (currently only used in debug prints) (in case of equal weights,
+// comparing with the threshold may not accurately reflect which nodes are
+// considiered hot).
+func hotNodesFromCDF(p *pgo.Profile) (float64, []pgo.NodeMapKey) {
+	nodes := make([]pgo.NodeMapKey, len(p.NodeMap))
+	i := 0
+	for n := range p.NodeMap {
+		nodes[i] = n
+		i++
+	}
+	sort.Slice(nodes, func(i, j int) bool {
+		ni, nj := nodes[i], nodes[j]
+		if wi, wj := p.NodeMap[ni].EWeight, p.NodeMap[nj].EWeight; wi != wj {
+			return wi > wj // want larger weight first
+		}
+		// same weight, order by name/line number
+		if ni.CallerName != nj.CallerName {
+			return ni.CallerName < nj.CallerName
+		}
+		if ni.CalleeName != nj.CalleeName {
+			return ni.CalleeName < nj.CalleeName
+		}
+		return ni.CallSiteOffset < nj.CallSiteOffset
+	})
+	cum := int64(0)
+	for i, n := range nodes {
+		w := p.NodeMap[n].EWeight
+		cum += w
+		if pgo.WeightInPercentage(cum, p.TotalEdgeWeight) > inlineCDFHotCallSiteThresholdPercent {
+			// nodes[:i+1] to include the very last node that makes it to go over the threshold.
+			// (Say, if the CDF threshold is 50% and one hot node takes 60% of weight, we want to
+			// include that node instead of excluding it.)
+			return pgo.WeightInPercentage(w, p.TotalEdgeWeight), nodes[:i+1]
+		}
+	}
+	return 0, nodes
+}
+
+// pgoInlineEpilogue updates IRGraph after inlining.
+func pgoInlineEpilogue(p *pgo.Profile, decls []ir.Node) {
+	if base.Debug.PGOInline >= 2 {
+		ir.VisitFuncsBottomUp(decls, func(list []*ir.Func, recursive bool) {
+			for _, f := range list {
+				name := ir.PkgFuncName(f)
+				if n, ok := p.WeightedCG.IRNodes[name]; ok {
+					p.RedirectEdges(n, inlinedCallSites)
+				}
+			}
+		})
+		// Print the call-graph after inlining. This is a debugging feature.
+		fmt.Printf("hot-cg after inline in dot:")
+		p.PrintWeightedCallGraphDOT(inlineHotCallSiteThresholdPercent)
+	}
+}
+
 // InlinePackage finds functions that can be inlined and clones them before walk expands them.
-func InlinePackage() {
-	ir.VisitFuncsBottomUp(typecheck.Target.Decls, func(list []*ir.Func, recursive bool) {
+func InlinePackage(p *pgo.Profile) {
+	InlineDecls(p, typecheck.Target.Decls, true)
+}
+
+// InlineDecls applies inlining to the given batch of declarations.
+func InlineDecls(p *pgo.Profile, decls []ir.Node, doInline bool) {
+	if p != nil {
+		pgoInlinePrologue(p, decls)
+	}
+
+	ir.VisitFuncsBottomUp(decls, func(list []*ir.Func, recursive bool) {
 		numfns := numNonClosures(list)
 		for _, n := range list {
 			if !recursive || numfns > 1 {
 				// We allow inlining if there is no
 				// recursion, or the recursion cycle is
 				// across more than one function.
-				CanInline(n)
+				CanInline(n, p)
 			} else {
 				if base.Flag.LowerM > 1 {
 					fmt.Printf("%v: cannot inline %v: recursive\n", ir.Line(n), n.Nname)
 				}
 			}
-			InlineCalls(n)
+			if doInline {
+				InlineCalls(n, p)
+			}
 		}
 	})
+
+	if p != nil {
+		pgoInlineEpilogue(p, decls)
+	}
 }
 
 // CanInline determines whether fn is inlineable.
 // If so, CanInline saves copies of fn.Body and fn.Dcl in fn.Inl.
 // fn and fn.Body will already have been typechecked.
-func CanInline(fn *ir.Func) {
+func CanInline(fn *ir.Func, profile *pgo.Profile) {
 	if fn.Nname == nil {
 		base.Fatalf("CanInline no nname %+v", fn)
 	}
@@ -168,6 +307,19 @@
 		cc = 1 // this appears to yield better performance than 0.
 	}
 
+	// Update the budget for profile-guided inlining.
+	budget := int32(inlineMaxBudget)
+	if profile != nil {
+		if n, ok := profile.WeightedCG.IRNodes[ir.PkgFuncName(fn)]; ok {
+			if _, ok := candHotCalleeMap[n]; ok {
+				budget = int32(inlineHotMaxBudget)
+				if base.Debug.PGOInline > 0 {
+					fmt.Printf("hot-node enabled increased budget=%v for func=%v\n", budget, ir.PkgFuncName(fn))
+				}
+			}
+		}
+	}
+
 	// At this point in the game the function we're looking at may
 	// have "stale" autos, vars that still appear in the Dcl list, but
 	// which no longer have any uses in the function body (due to
@@ -178,8 +330,11 @@
 	// list. See issue 25249 for more context.
 
 	visitor := hairyVisitor{
-		budget:        inlineMaxBudget,
+		curFunc:       fn,
+		budget:        budget,
+		maxBudget:     budget,
 		extraCallCost: cc,
+		profile:       profile,
 	}
 	if visitor.tooHairy(fn) {
 		reason = visitor.reason
@@ -187,7 +342,7 @@
 	}
 
 	n.Func.Inl = &ir.Inline{
-		Cost: inlineMaxBudget - visitor.budget,
+		Cost: budget - visitor.budget,
 		Dcl:  pruneUnusedAutos(n.Defn.(*ir.Func).Dcl, &visitor),
 		Body: inlcopylist(fn.Body),
 
@@ -195,12 +350,12 @@
 	}
 
 	if base.Flag.LowerM > 1 {
-		fmt.Printf("%v: can inline %v with cost %d as: %v { %v }\n", ir.Line(fn), n, inlineMaxBudget-visitor.budget, fn.Type(), ir.Nodes(n.Func.Inl.Body))
+		fmt.Printf("%v: can inline %v with cost %d as: %v { %v }\n", ir.Line(fn), n, budget-visitor.budget, fn.Type(), ir.Nodes(n.Func.Inl.Body))
 	} else if base.Flag.LowerM != 0 {
 		fmt.Printf("%v: can inline %v\n", ir.Line(fn), n)
 	}
 	if logopt.Enabled() {
-		logopt.LogOpt(fn.Pos(), "canInlineFunction", "inline", ir.FuncName(fn), fmt.Sprintf("cost: %d", inlineMaxBudget-visitor.budget))
+		logopt.LogOpt(fn.Pos(), "canInlineFunction", "inline", ir.FuncName(fn), fmt.Sprintf("cost: %d", budget-visitor.budget))
 	}
 }
 
@@ -239,11 +394,15 @@
 // hairyVisitor visits a function body to determine its inlining
 // hairiness and whether or not it can be inlined.
 type hairyVisitor struct {
+	// This is needed to access the current caller in the doNode function.
+	curFunc       *ir.Func
 	budget        int32
+	maxBudget     int32
 	reason        string
 	extraCallCost int32
 	usedLocals    ir.NameSet
 	do            func(ir.Node) bool
+	profile       *pgo.Profile
 }
 
 func (v *hairyVisitor) tooHairy(fn *ir.Func) bool {
@@ -252,7 +411,7 @@
 		return true
 	}
 	if v.budget < 0 {
-		v.reason = fmt.Sprintf("function too complex: cost %d exceeds budget %d", inlineMaxBudget-v.budget, inlineMaxBudget)
+		v.reason = fmt.Sprintf("function too complex: cost %d exceeds budget %d", v.maxBudget-v.budget, v.maxBudget)
 		return true
 	}
 	return false
@@ -283,6 +442,19 @@
 					break
 				}
 			}
+			// Special case for coverage counter updates; although
+			// these correspond to real operations, we treat them as
+			// zero cost for the moment. This is due to the existence
+			// of tests that are sensitive to inlining-- if the
+			// insertion of coverage instrumentation happens to tip a
+			// given function over the threshold and move it from
+			// "inlinable" to "not-inlinable", this can cause changes
+			// in allocation behavior, which can then result in test
+			// failures (a good example is the TestAllocations in
+			// crypto/ed25519).
+			if isAtomicCoverageCounterUpdate(n) {
+				return false
+			}
 		}
 		if n.X.Op() == ir.OMETHEXPR {
 			if meth := ir.MethodExprName(n.X); meth != nil {
@@ -304,7 +476,9 @@
 						case "littleEndian.Uint64", "littleEndian.Uint32", "littleEndian.Uint16",
 							"bigEndian.Uint64", "bigEndian.Uint32", "bigEndian.Uint16",
 							"littleEndian.PutUint64", "littleEndian.PutUint32", "littleEndian.PutUint16",
-							"bigEndian.PutUint64", "bigEndian.PutUint32", "bigEndian.PutUint16":
+							"bigEndian.PutUint64", "bigEndian.PutUint32", "bigEndian.PutUint16",
+							"littleEndian.AppendUint64", "littleEndian.AppendUint32", "littleEndian.AppendUint16",
+							"bigEndian.AppendUint64", "bigEndian.AppendUint32", "bigEndian.AppendUint16":
 							cheap = true
 						}
 					}
@@ -315,12 +489,25 @@
 			}
 		}
 
+		// Determine if the callee edge is for an inlinable hot callee or not.
+		if v.profile != nil && v.curFunc != nil {
+			if fn := inlCallee(n.X, v.profile); fn != nil && typecheck.HaveInlineBody(fn) {
+				lineOffset := pgo.NodeLineOffset(n, fn)
+				csi := pgo.CallSiteInfo{LineOffset: lineOffset, Caller: v.curFunc}
+				if _, o := candHotEdgeMap[csi]; o {
+					if base.Debug.PGOInline > 0 {
+						fmt.Printf("hot-callsite identified at line=%v for func=%v\n", ir.Line(n), ir.PkgFuncName(v.curFunc))
+					}
+				}
+			}
+		}
+
 		if ir.IsIntrinsicCall(n) {
 			// Treat like any other node.
 			break
 		}
 
-		if fn := inlCallee(n.X); fn != nil && typecheck.HaveInlineBody(fn) {
+		if fn := inlCallee(n.X, v.profile); fn != nil && typecheck.HaveInlineBody(fn) {
 			v.budget -= fn.Inl.Cost
 			break
 		}
@@ -379,6 +566,15 @@
 	case ir.OAPPEND:
 		v.budget -= inlineExtraAppendCost
 
+	case ir.OADDR:
+		n := n.(*ir.AddrExpr)
+		// Make "&s.f" cost 0 when f's offset is zero.
+		if dot, ok := n.X.(*ir.SelectorExpr); ok && (dot.Op() == ir.ODOT || dot.Op() == ir.ODOTPTR) {
+			if _, ok := dot.X.(*ir.Name); ok && dot.Selection.Offset == 0 {
+				v.budget += 2 // undo ir.OADDR+ir.ODOT/ir.ODOTPTR
+			}
+		}
+
 	case ir.ODEREF:
 		// *(*X)(unsafe.Pointer(&x)) is low-cost
 		n := n.(*ir.StarExpr)
@@ -430,6 +626,52 @@
 
 	case ir.OMETHEXPR:
 		v.budget++ // Hack for toolstash -cmp.
+
+	case ir.OAS2:
+		n := n.(*ir.AssignListStmt)
+
+		// Unified IR unconditionally rewrites:
+		//
+		//	a, b = f()
+		//
+		// into:
+		//
+		//	DCL tmp1
+		//	DCL tmp2
+		//	tmp1, tmp2 = f()
+		//	a, b = tmp1, tmp2
+		//
+		// so that it can insert implicit conversions as necessary. To
+		// minimize impact to the existing inlining heuristics (in
+		// particular, to avoid breaking the existing inlinability regress
+		// tests), we need to compensate for this here.
+		if base.Debug.Unified != 0 {
+			if init := n.Rhs[0].Init(); len(init) == 1 {
+				if _, ok := init[0].(*ir.AssignListStmt); ok {
+					// 4 for each value, because each temporary variable now
+					// appears 3 times (DCL, LHS, RHS), plus an extra DCL node.
+					//
+					// 1 for the extra "tmp1, tmp2 = f()" assignment statement.
+					v.budget += 4*int32(len(n.Lhs)) + 1
+				}
+			}
+		}
+
+	case ir.OAS:
+		// Special case for coverage counter updates and coverage
+		// function registrations. Although these correspond to real
+		// operations, we treat them as zero cost for the moment. This
+		// is primarily due to the existence of tests that are
+		// sensitive to inlining-- if the insertion of coverage
+		// instrumentation happens to tip a given function over the
+		// threshold and move it from "inlinable" to "not-inlinable",
+		// this can cause changes in allocation behavior, which can
+		// then result in test failures (a good example is the
+		// TestAllocations in crypto/ed25519).
+		n := n.(*ir.AssignStmt)
+		if n.X.Op() == ir.OINDEX && isIndexingCoverageCounter(n.X) {
+			return false
+		}
 	}
 
 	v.budget--
@@ -495,25 +737,30 @@
 
 // InlineCalls/inlnode walks fn's statements and expressions and substitutes any
 // calls made to inlineable functions. This is the external entry point.
-func InlineCalls(fn *ir.Func) {
+func InlineCalls(fn *ir.Func, profile *pgo.Profile) {
 	savefn := ir.CurFunc
 	ir.CurFunc = fn
 	maxCost := int32(inlineMaxBudget)
 	if isBigFunc(fn) {
 		maxCost = inlineBigFunctionMaxCost
 	}
-	// Map to keep track of functions that have been inlined at a particular
-	// call site, in order to stop inlining when we reach the beginning of a
-	// recursion cycle again. We don't inline immediately recursive functions,
-	// but allow inlining if there is a recursion cycle of many functions.
-	// Most likely, the inlining will stop before we even hit the beginning of
-	// the cycle again, but the map catches the unusual case.
-	inlMap := make(map[*ir.Func]bool)
+	var inlCalls []*ir.InlinedCallExpr
 	var edit func(ir.Node) ir.Node
 	edit = func(n ir.Node) ir.Node {
-		return inlnode(n, maxCost, inlMap, edit)
+		return inlnode(n, maxCost, &inlCalls, edit, profile)
 	}
 	ir.EditChildren(fn, edit)
+
+	// If we inlined any calls, we want to recursively visit their
+	// bodies for further inlining. However, we need to wait until
+	// *after* the original function body has been expanded, or else
+	// inlCallee can have false positives (e.g., #54632).
+	for len(inlCalls) > 0 {
+		call := inlCalls[0]
+		inlCalls = inlCalls[1:]
+		ir.EditChildren(call, edit)
+	}
+
 	ir.CurFunc = savefn
 }
 
@@ -531,7 +778,7 @@
 // The result of inlnode MUST be assigned back to n, e.g.
 //
 //	n.Left = inlnode(n.Left)
-func inlnode(n ir.Node, maxCost int32, inlMap map[*ir.Func]bool, edit func(ir.Node) ir.Node) ir.Node {
+func inlnode(n ir.Node, maxCost int32, inlCalls *[]*ir.InlinedCallExpr, edit func(ir.Node) ir.Node, profile *pgo.Profile) ir.Node {
 	if n == nil {
 		return n
 	}
@@ -592,8 +839,8 @@
 		if ir.IsIntrinsicCall(call) {
 			break
 		}
-		if fn := inlCallee(call.X); fn != nil && typecheck.HaveInlineBody(fn) {
-			n = mkinlcall(call, fn, maxCost, inlMap, edit)
+		if fn := inlCallee(call.X, profile); fn != nil && typecheck.HaveInlineBody(fn) {
+			n = mkinlcall(call, fn, maxCost, inlCalls, edit)
 		}
 	}
 
@@ -604,7 +851,7 @@
 
 // inlCallee takes a function-typed expression and returns the underlying function ONAME
 // that it refers to if statically known. Otherwise, it returns nil.
-func inlCallee(fn ir.Node) *ir.Func {
+func inlCallee(fn ir.Node, profile *pgo.Profile) *ir.Func {
 	fn = ir.StaticValue(fn)
 	switch fn.Op() {
 	case ir.OMETHEXPR:
@@ -625,7 +872,7 @@
 	case ir.OCLOSURE:
 		fn := fn.(*ir.ClosureExpr)
 		c := fn.Func
-		CanInline(c)
+		CanInline(c, profile)
 		return c
 	}
 	return nil
@@ -654,10 +901,9 @@
 // when producing output for debugging the compiler itself.
 var SSADumpInline = func(*ir.Func) {}
 
-// NewInline allows the inliner implementation to be overridden.
-// If it returns nil, the legacy inliner will handle this call
-// instead.
-var NewInline = func(call *ir.CallExpr, fn *ir.Func, inlIndex int) *ir.InlinedCallExpr { return nil }
+// InlineCall allows the inliner implementation to be overridden.
+// If it returns nil, the function will not be inlined.
+var InlineCall = oldInlineCall
 
 // If n is a OCALLFUNC node, and fn is an ONAME node for a
 // function with an inlinable body, return an OINLCALL node that can replace n.
@@ -667,7 +913,7 @@
 // The result of mkinlcall MUST be assigned back to n, e.g.
 //
 //	n.Left = mkinlcall(n.Left, fn, isddd)
-func mkinlcall(n *ir.CallExpr, fn *ir.Func, maxCost int32, inlMap map[*ir.Func]bool, edit func(ir.Node) ir.Node) ir.Node {
+func mkinlcall(n *ir.CallExpr, fn *ir.Func, maxCost int32, inlCalls *[]*ir.InlinedCallExpr, edit func(ir.Node) ir.Node) ir.Node {
 	if fn.Inl == nil {
 		if logopt.Enabled() {
 			logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", ir.FuncName(ir.CurFunc),
@@ -676,13 +922,29 @@
 		return n
 	}
 	if fn.Inl.Cost > maxCost {
-		// The inlined function body is too big. Typically we use this check to restrict
-		// inlining into very big functions.  See issue 26546 and 17566.
-		if logopt.Enabled() {
-			logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", ir.FuncName(ir.CurFunc),
-				fmt.Sprintf("cost %d of %s exceeds max large caller cost %d", fn.Inl.Cost, ir.PkgFuncName(fn), maxCost))
+		// If the callsite is hot and it is under the inlineHotMaxBudget budget, then try to inline it, or else bail.
+		lineOffset := pgo.NodeLineOffset(n, ir.CurFunc)
+		csi := pgo.CallSiteInfo{LineOffset: lineOffset, Caller: ir.CurFunc}
+		if _, ok := candHotEdgeMap[csi]; ok {
+			if fn.Inl.Cost > inlineHotMaxBudget {
+				if logopt.Enabled() {
+					logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", ir.FuncName(ir.CurFunc),
+						fmt.Sprintf("cost %d of %s exceeds max large caller cost %d", fn.Inl.Cost, ir.PkgFuncName(fn), inlineHotMaxBudget))
+				}
+				return n
+			}
+			if base.Debug.PGOInline > 0 {
+				fmt.Printf("hot-budget check allows inlining for call %s at %v\n", ir.PkgFuncName(fn), ir.Line(n))
+			}
+		} else {
+			// The inlined function body is too big. Typically we use this check to restrict
+			// inlining into very big functions.  See issue 26546 and 17566.
+			if logopt.Enabled() {
+				logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", ir.FuncName(ir.CurFunc),
+					fmt.Sprintf("cost %d of %s exceeds max large caller cost %d", fn.Inl.Cost, ir.PkgFuncName(fn), maxCost))
+			}
+			return n
 		}
-		return n
 	}
 
 	if fn == ir.CurFunc {
@@ -693,44 +955,47 @@
 		return n
 	}
 
-	// Don't inline a function fn that has no shape parameters, but is passed at
-	// least one shape arg. This means we must be inlining a non-generic function
-	// fn that was passed into a generic function, and can be called with a shape
-	// arg because it matches an appropriate type parameters. But fn may include
-	// an interface conversion (that may be applied to a shape arg) that was not
-	// apparent when we first created the instantiation of the generic function.
-	// We can't handle this if we actually do the inlining, since we want to know
-	// all interface conversions immediately after stenciling. So, we avoid
-	// inlining in this case, see issue #49309. (1)
-	//
-	// See discussion on go.dev/cl/406475 for more background.
-	if !fn.Type().Params().HasShape() {
-		for _, arg := range n.Args {
-			if arg.Type().HasShape() {
+	// The non-unified frontend has issues with inlining and shape parameters.
+	if base.Debug.Unified == 0 {
+		// Don't inline a function fn that has no shape parameters, but is passed at
+		// least one shape arg. This means we must be inlining a non-generic function
+		// fn that was passed into a generic function, and can be called with a shape
+		// arg because it matches an appropriate type parameters. But fn may include
+		// an interface conversion (that may be applied to a shape arg) that was not
+		// apparent when we first created the instantiation of the generic function.
+		// We can't handle this if we actually do the inlining, since we want to know
+		// all interface conversions immediately after stenciling. So, we avoid
+		// inlining in this case, see issue #49309. (1)
+		//
+		// See discussion on go.dev/cl/406475 for more background.
+		if !fn.Type().Params().HasShape() {
+			for _, arg := range n.Args {
+				if arg.Type().HasShape() {
+					if logopt.Enabled() {
+						logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", ir.FuncName(ir.CurFunc),
+							fmt.Sprintf("inlining function %v has no-shape params with shape args", ir.FuncName(fn)))
+					}
+					return n
+				}
+			}
+		} else {
+			// Don't inline a function fn that has shape parameters, but is passed no shape arg.
+			// See comments (1) above, and issue #51909.
+			inlineable := len(n.Args) == 0 // Function has shape in type, with no arguments can always be inlined.
+			for _, arg := range n.Args {
+				if arg.Type().HasShape() {
+					inlineable = true
+					break
+				}
+			}
+			if !inlineable {
 				if logopt.Enabled() {
 					logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", ir.FuncName(ir.CurFunc),
-						fmt.Sprintf("inlining function %v has no-shape params with shape args", ir.FuncName(fn)))
+						fmt.Sprintf("inlining function %v has shape params with no-shape args", ir.FuncName(fn)))
 				}
 				return n
 			}
 		}
-	} else {
-		// Don't inline a function fn that has shape parameters, but is passed no shape arg.
-		// See comments (1) above, and issue #51909.
-		inlineable := len(n.Args) == 0 // Function has shape in type, with no arguments can always be inlined.
-		for _, arg := range n.Args {
-			if arg.Type().HasShape() {
-				inlineable = true
-				break
-			}
-		}
-		if !inlineable {
-			if logopt.Enabled() {
-				logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", ir.FuncName(ir.CurFunc),
-					fmt.Sprintf("inlining function %v has shape params with no-shape args", ir.FuncName(fn)))
-			}
-			return n
-		}
 	}
 
 	if base.Flag.Cfg.Instrumenting && types.IsRuntimePkg(fn.Sym().Pkg) {
@@ -743,24 +1008,71 @@
 		return n
 	}
 
-	if inlMap[fn] {
-		if base.Flag.LowerM > 1 {
-			fmt.Printf("%v: cannot inline %v into %v: repeated recursive cycle\n", ir.Line(n), fn, ir.FuncName(ir.CurFunc))
+	parent := base.Ctxt.PosTable.Pos(n.Pos()).Base().InliningIndex()
+	sym := fn.Linksym()
+
+	// Check if we've already inlined this function at this particular
+	// call site, in order to stop inlining when we reach the beginning
+	// of a recursion cycle again. We don't inline immediately recursive
+	// functions, but allow inlining if there is a recursion cycle of
+	// many functions. Most likely, the inlining will stop before we
+	// even hit the beginning of the cycle again, but this catches the
+	// unusual case.
+	for inlIndex := parent; inlIndex >= 0; inlIndex = base.Ctxt.InlTree.Parent(inlIndex) {
+		if base.Ctxt.InlTree.InlinedFunction(inlIndex) == sym {
+			if base.Flag.LowerM > 1 {
+				fmt.Printf("%v: cannot inline %v into %v: repeated recursive cycle\n", ir.Line(n), fn, ir.FuncName(ir.CurFunc))
+			}
+			return n
 		}
-		return n
 	}
-	inlMap[fn] = true
-	defer func() {
-		inlMap[fn] = false
-	}()
 
 	typecheck.FixVariadicCall(n)
 
-	parent := base.Ctxt.PosTable.Pos(n.Pos()).Base().InliningIndex()
-
-	sym := fn.Linksym()
 	inlIndex := base.Ctxt.InlTree.Add(parent, n.Pos(), sym)
 
+	closureInitLSym := func(n *ir.CallExpr, fn *ir.Func) {
+		// The linker needs FuncInfo metadata for all inlined
+		// functions. This is typically handled by gc.enqueueFunc
+		// calling ir.InitLSym for all function declarations in
+		// typecheck.Target.Decls (ir.UseClosure adds all closures to
+		// Decls).
+		//
+		// However, non-trivial closures in Decls are ignored, and are
+		// insteaded enqueued when walk of the calling function
+		// discovers them.
+		//
+		// This presents a problem for direct calls to closures.
+		// Inlining will replace the entire closure definition with its
+		// body, which hides the closure from walk and thus suppresses
+		// symbol creation.
+		//
+		// Explicitly create a symbol early in this edge case to ensure
+		// we keep this metadata.
+		//
+		// TODO: Refactor to keep a reference so this can all be done
+		// by enqueueFunc.
+
+		if n.Op() != ir.OCALLFUNC {
+			// Not a standard call.
+			return
+		}
+		if n.X.Op() != ir.OCLOSURE {
+			// Not a direct closure call.
+			return
+		}
+
+		clo := n.X.(*ir.ClosureExpr)
+		if ir.IsTrivialClosure(clo) {
+			// enqueueFunc will handle trivial closures anyways.
+			return
+		}
+
+		ir.InitLSym(fn, true)
+	}
+
+	closureInitLSym(n, fn)
+
 	if base.Flag.GenDwarfInl > 0 {
 		if !sym.WasInlined() {
 			base.Ctxt.DwFixups.SetPrecursorFunc(sym, fn)
@@ -775,41 +1087,43 @@
 		fmt.Printf("%v: Before inlining: %+v\n", ir.Line(n), n)
 	}
 
-	res := NewInline(n, fn, inlIndex)
-	if res == nil {
-		res = oldInline(n, fn, inlIndex)
+	if base.Debug.PGOInline > 0 {
+		csi := pgo.CallSiteInfo{LineOffset: pgo.NodeLineOffset(n, fn), Caller: ir.CurFunc}
+		if _, ok := inlinedCallSites[csi]; !ok {
+			inlinedCallSites[csi] = struct{}{}
+		}
 	}
 
-	// transitive inlining
-	// might be nice to do this before exporting the body,
-	// but can't emit the body with inlining expanded.
-	// instead we emit the things that the body needs
-	// and each use must redo the inlining.
-	// luckily these are small.
-	ir.EditChildren(res, edit)
+	res := InlineCall(n, fn, inlIndex)
+
+	if res == nil {
+		base.FatalfAt(n.Pos(), "inlining call to %v failed", fn)
+	}
 
 	if base.Flag.LowerM > 2 {
 		fmt.Printf("%v: After inlining %+v\n\n", ir.Line(res), res)
 	}
 
+	*inlCalls = append(*inlCalls, res)
+
 	return res
 }
 
 // CalleeEffects appends any side effects from evaluating callee to init.
 func CalleeEffects(init *ir.Nodes, callee ir.Node) {
 	for {
+		init.Append(ir.TakeInit(callee)...)
+
 		switch callee.Op() {
 		case ir.ONAME, ir.OCLOSURE, ir.OMETHEXPR:
 			return // done
 
 		case ir.OCONVNOP:
 			conv := callee.(*ir.ConvExpr)
-			init.Append(ir.TakeInit(conv)...)
 			callee = conv.X
 
 		case ir.OINLCALL:
 			ic := callee.(*ir.InlinedCallExpr)
-			init.Append(ir.TakeInit(ic)...)
 			init.Append(ic.Body.Take()...)
 			callee = ic.SingleResult()
 
@@ -819,11 +1133,11 @@
 	}
 }
 
-// oldInline creates an InlinedCallExpr to replace the given call
+// oldInlineCall creates an InlinedCallExpr to replace the given call
 // expression. fn is the callee function to be inlined. inlIndex is
 // the inlining tree position index, for use with src.NewInliningBase
 // when rewriting positions.
-func oldInline(call *ir.CallExpr, fn *ir.Func, inlIndex int) *ir.InlinedCallExpr {
+func oldInlineCall(call *ir.CallExpr, fn *ir.Func, inlIndex int) *ir.InlinedCallExpr {
 	if base.Debug.TypecheckInl == 0 {
 		typecheck.ImportedBody(fn)
 	}
@@ -1427,3 +1741,41 @@
 	}
 	return false
 }
+
+// isIndexingCoverageCounter returns true if the specified node 'n' is indexing
+// into a coverage counter array.
+func isIndexingCoverageCounter(n ir.Node) bool {
+	if n.Op() != ir.OINDEX {
+		return false
+	}
+	ixn := n.(*ir.IndexExpr)
+	if ixn.X.Op() != ir.ONAME || !ixn.X.Type().IsArray() {
+		return false
+	}
+	nn := ixn.X.(*ir.Name)
+	return nn.CoverageCounter()
+}
+
+// isAtomicCoverageCounterUpdate examines the specified node to
+// determine whether it represents a call to sync/atomic.AddUint32 to
+// increment a coverage counter.
+func isAtomicCoverageCounterUpdate(cn *ir.CallExpr) bool {
+	if cn.X.Op() != ir.ONAME {
+		return false
+	}
+	name := cn.X.(*ir.Name)
+	if name.Class != ir.PFUNC {
+		return false
+	}
+	fn := name.Sym().Name
+	if name.Sym().Pkg.Path != "sync/atomic" ||
+		(fn != "AddUint32" && fn != "StoreUint32") {
+		return false
+	}
+	if len(cn.Args) != 2 || cn.Args[0].Op() != ir.OADDR {
+		return false
+	}
+	adn := cn.Args[0].(*ir.AddrExpr)
+	v := isIndexingCoverageCounter(adn.X)
+	return v
+}
diff --git a/src/cmd/compile/internal/ir/abi.go b/src/cmd/compile/internal/ir/abi.go
new file mode 100644
index 0000000..8cd1606
--- /dev/null
+++ b/src/cmd/compile/internal/ir/abi.go
@@ -0,0 +1,78 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ir
+
+import (
+	"cmd/compile/internal/base"
+	"cmd/internal/obj"
+)
+
+// InitLSym defines f's obj.LSym and initializes it based on the
+// properties of f. This includes setting the symbol flags and ABI and
+// creating and initializing related DWARF symbols.
+//
+// InitLSym must be called exactly once per function and must be
+// called for both functions with bodies and functions without bodies.
+// For body-less functions, we only create the LSym; for functions
+// with bodies call a helper to setup up / populate the LSym.
+func InitLSym(f *Func, hasBody bool) {
+	if f.LSym != nil {
+		base.FatalfAt(f.Pos(), "InitLSym called twice on %v", f)
+	}
+
+	if nam := f.Nname; !IsBlank(nam) {
+		f.LSym = nam.LinksymABI(f.ABI)
+		if f.Pragma&Systemstack != 0 {
+			f.LSym.Set(obj.AttrCFunc, true)
+		}
+	}
+	if hasBody {
+		setupTextLSym(f, 0)
+	}
+}
+
+// setupTextLSym initializes the LSym for a with-body text symbol.
+func setupTextLSym(f *Func, flag int) {
+	if f.Dupok() {
+		flag |= obj.DUPOK
+	}
+	if f.Wrapper() {
+		flag |= obj.WRAPPER
+	}
+	if f.ABIWrapper() {
+		flag |= obj.ABIWRAPPER
+	}
+	if f.Needctxt() {
+		flag |= obj.NEEDCTXT
+	}
+	if f.Pragma&Nosplit != 0 {
+		flag |= obj.NOSPLIT
+	}
+	if f.ReflectMethod() {
+		flag |= obj.REFLECTMETHOD
+	}
+
+	// Clumsy but important.
+	// For functions that could be on the path of invoking a deferred
+	// function that can recover (runtime.reflectcall, reflect.callReflect,
+	// and reflect.callMethod), we want the panic+recover special handling.
+	// See test/recover.go for test cases and src/reflect/value.go
+	// for the actual functions being considered.
+	//
+	// runtime.reflectcall is an assembly function which tailcalls
+	// WRAPPER functions (runtime.callNN). Its ABI wrapper needs WRAPPER
+	// flag as well.
+	fnname := f.Sym().Name
+	if base.Ctxt.Pkgpath == "runtime" && fnname == "reflectcall" {
+		flag |= obj.WRAPPER
+	} else if base.Ctxt.Pkgpath == "reflect" {
+		switch fnname {
+		case "callReflect", "callMethod":
+			flag |= obj.WRAPPER
+		}
+	}
+
+	base.Ctxt.InitTextSym(f.LSym, flag, f.Pos())
+}
diff --git a/src/cmd/compile/internal/ir/bitset.go b/src/cmd/compile/internal/ir/bitset.go
index 0c7bd54..bae4005 100644
--- a/src/cmd/compile/internal/ir/bitset.go
+++ b/src/cmd/compile/internal/ir/bitset.go
@@ -35,37 +35,3 @@
 		*(*uint16)(f) &^= mask
 	}
 }
-
-type bitset32 uint32
-
-func (f *bitset32) set(mask uint32, b bool) {
-	if b {
-		*(*uint32)(f) |= mask
-	} else {
-		*(*uint32)(f) &^= mask
-	}
-}
-
-func (f bitset32) get2(shift uint8) uint8 {
-	return uint8(f>>shift) & 3
-}
-
-// set2 sets two bits in f using the bottom two bits of b.
-func (f *bitset32) set2(shift uint8, b uint8) {
-	// Clear old bits.
-	*(*uint32)(f) &^= 3 << shift
-	// Set new bits.
-	*(*uint32)(f) |= uint32(b&3) << shift
-}
-
-func (f bitset32) get3(shift uint8) uint8 {
-	return uint8(f>>shift) & 7
-}
-
-// set3 sets three bits in f using the bottom three bits of b.
-func (f *bitset32) set3(shift uint8, b uint8) {
-	// Clear old bits.
-	*(*uint32)(f) &^= 7 << shift
-	// Set new bits.
-	*(*uint32)(f) |= uint32(b&7) << shift
-}
diff --git a/src/cmd/compile/internal/ir/cfg.go b/src/cmd/compile/internal/ir/cfg.go
index d986ac3..49e1ed3 100644
--- a/src/cmd/compile/internal/ir/cfg.go
+++ b/src/cmd/compile/internal/ir/cfg.go
@@ -5,12 +5,12 @@
 package ir
 
 var (
-	// maximum size variable which we will allocate on the stack.
+	// MaxStackVarSize is the maximum size variable which we will allocate on the stack.
 	// This limit is for explicit variable declarations like "var x T" or "x := ...".
 	// Note: the flag smallframes can update this value.
 	MaxStackVarSize = int64(10 * 1024 * 1024)
 
-	// maximum size of implicit variables that we will allocate on the stack.
+	// MaxImplicitStackVarSize is the maximum size of implicit variables that we will allocate on the stack.
 	//   p := new(T)          allocating T on the stack
 	//   p := &T{}            allocating T on the stack
 	//   s := make([]T, n)    allocating [n]T on the stack
diff --git a/src/cmd/compile/internal/ir/expr.go b/src/cmd/compile/internal/ir/expr.go
index 8ac7e7f..a481b14 100644
--- a/src/cmd/compile/internal/ir/expr.go
+++ b/src/cmd/compile/internal/ir/expr.go
@@ -119,8 +119,9 @@
 // or Op(X, Y) for builtin functions that do not become calls.
 type BinaryExpr struct {
 	miniExpr
-	X Node
-	Y Node
+	X     Node
+	Y     Node
+	RType Node `mknode:"-"` // see reflectdata/helpers.go
 }
 
 func NewBinaryExpr(pos src.XPos, op Op, x, y Node) *BinaryExpr {
@@ -136,7 +137,7 @@
 		panic(n.no("SetOp " + op.String()))
 	case OADD, OADDSTR, OAND, OANDNOT, ODIV, OEQ, OGE, OGT, OLE,
 		OLSH, OLT, OMOD, OMUL, ONE, OOR, ORSH, OSUB, OXOR,
-		OCOPY, OCOMPLEX, OUNSAFEADD, OUNSAFESLICE,
+		OCOPY, OCOMPLEX, OUNSAFEADD, OUNSAFESLICE, OUNSAFESTRING,
 		OEFACE:
 		n.op = op
 	}
@@ -148,6 +149,7 @@
 	origNode
 	X         Node
 	Args      Nodes
+	RType     Node    `mknode:"-"` // see reflectdata/helpers.go
 	KeepAlive []*Name // vars to be kept alive until call returns
 	IsDDD     bool
 	NoInline  bool
@@ -192,6 +194,7 @@
 	miniExpr
 	origNode
 	List     Nodes // initialized values
+	RType    Node  `mknode:"-"` // *runtime._type for OMAPLIT map types
 	Prealloc *Name
 	// For OSLICELIT, Len is the backing array length.
 	// For OMAPLIT, Len is the number of entries that we've removed from List and
@@ -246,6 +249,27 @@
 type ConvExpr struct {
 	miniExpr
 	X Node
+
+	// For implementing OCONVIFACE expressions.
+	//
+	// TypeWord is an expression yielding a *runtime._type or
+	// *runtime.itab value to go in the type word of the iface/eface
+	// result. See reflectdata.ConvIfaceTypeWord for further details.
+	//
+	// SrcRType is an expression yielding a *runtime._type value for X,
+	// if it's not pointer-shaped and needs to be heap allocated.
+	TypeWord Node `mknode:"-"`
+	SrcRType Node `mknode:"-"`
+
+	// For -d=checkptr instrumentation of conversions from
+	// unsafe.Pointer to *Elem or *[Len]Elem.
+	//
+	// TODO(mdempsky): We only ever need one of these, but currently we
+	// don't decide which one until walk. Longer term, it probably makes
+	// sense to have a dedicated IR op for `(*[Len]Elem)(ptr)[:n:m]`
+	// expressions.
+	ElemRType     Node `mknode:"-"`
+	ElemElemRType Node `mknode:"-"`
 }
 
 func NewConvExpr(pos src.XPos, op Op, typ *types.Type, x Node) *ConvExpr {
@@ -265,7 +289,7 @@
 	switch op {
 	default:
 		panic(n.no("SetOp " + op.String()))
-	case OCONV, OCONVIFACE, OCONVIDATA, OCONVNOP, OBYTES2STR, OBYTES2STRTMP, ORUNES2STR, OSTR2BYTES, OSTR2BYTESTMP, OSTR2RUNES, ORUNESTR, OSLICE2ARRPTR:
+	case OCONV, OCONVIFACE, OCONVIDATA, OCONVNOP, OBYTES2STR, OBYTES2STRTMP, ORUNES2STR, OSTR2BYTES, OSTR2BYTESTMP, OSTR2RUNES, ORUNESTR, OSLICE2ARR, OSLICE2ARRPTR:
 		n.op = op
 	}
 }
@@ -275,6 +299,7 @@
 	miniExpr
 	X        Node
 	Index    Node
+	RType    Node `mknode:"-"` // see reflectdata/helpers.go
 	Assigned bool
 }
 
@@ -385,8 +410,9 @@
 // but *not* OMAKE (that's a pre-typechecking CallExpr).
 type MakeExpr struct {
 	miniExpr
-	Len Node
-	Cap Node
+	RType Node `mknode:"-"` // see reflectdata/helpers.go
+	Len   Node
+	Cap   Node
 }
 
 func NewMakeExpr(pos src.XPos, op Op, len, cap Node) *MakeExpr {
@@ -598,6 +624,21 @@
 	return n
 }
 
+// A StringHeaderExpr expression constructs a string header from its parts.
+type StringHeaderExpr struct {
+	miniExpr
+	Ptr Node
+	Len Node
+}
+
+func NewStringHeaderExpr(pos src.XPos, ptr, len Node) *StringHeaderExpr {
+	n := &StringHeaderExpr{Ptr: ptr, Len: len}
+	n.pos = pos
+	n.op = OSTRINGHEADER
+	n.typ = types.Types[types.TSTRING]
+	return n
+}
+
 // A StarExpr is a dereference expression *X.
 // It may end up being a value or a type.
 type StarExpr struct {
@@ -623,7 +664,7 @@
 
 	// Runtime type information provided by walkDotType for
 	// assertions from non-empty interface to concrete type.
-	ITab *AddrExpr `mknode:"-"` // *runtime.itab for Type implementing X's type
+	ITab Node `mknode:"-"` // *runtime.itab for Type implementing X's type
 }
 
 func NewTypeAssertExpr(pos src.XPos, x Node, typ *types.Type) *TypeAssertExpr {
@@ -650,6 +691,11 @@
 	miniExpr
 	X Node
 
+	// SrcRType is an expression that yields a *runtime._type value
+	// representing X's type. It's used in failed assertion panic
+	// messages.
+	SrcRType Node
+
 	// RType is an expression that yields a *runtime._type value
 	// representing the asserted type.
 	//
@@ -703,7 +749,8 @@
 	case OBITNOT, ONEG, ONOT, OPLUS, ORECV,
 		OALIGNOF, OCAP, OCLOSE, OIMAG, OLEN, ONEW,
 		OOFFSETOF, OPANIC, OREAL, OSIZEOF,
-		OCHECKNIL, OCFUNC, OIDATA, OITAB, OSPTR, OVARDEF, OVARKILL, OVARLIVE:
+		OCHECKNIL, OCFUNC, OIDATA, OITAB, OSPTR,
+		OUNSAFESTRINGDATA, OUNSAFESLICEDATA:
 		n.op = op
 	}
 }
@@ -1103,7 +1150,6 @@
 	b.WriteString(".")
 	b.WriteString(msym.Name)
 	b.WriteString(suffix)
-
 	return rpkg.LookupBytes(b.Bytes())
 }
 
diff --git a/src/cmd/compile/internal/ir/fmt.go b/src/cmd/compile/internal/ir/fmt.go
index 760ae7d..bac172d 100644
--- a/src/cmd/compile/internal/ir/fmt.go
+++ b/src/cmd/compile/internal/ir/fmt.go
@@ -25,71 +25,73 @@
 // Op
 
 var OpNames = []string{
-	OADDR:        "&",
-	OADD:         "+",
-	OADDSTR:      "+",
-	OALIGNOF:     "unsafe.Alignof",
-	OANDAND:      "&&",
-	OANDNOT:      "&^",
-	OAND:         "&",
-	OAPPEND:      "append",
-	OAS:          "=",
-	OAS2:         "=",
-	OBREAK:       "break",
-	OCALL:        "function call", // not actual syntax
-	OCAP:         "cap",
-	OCASE:        "case",
-	OCLOSE:       "close",
-	OCOMPLEX:     "complex",
-	OBITNOT:      "^",
-	OCONTINUE:    "continue",
-	OCOPY:        "copy",
-	ODELETE:      "delete",
-	ODEFER:       "defer",
-	ODIV:         "/",
-	OEQ:          "==",
-	OFALL:        "fallthrough",
-	OFOR:         "for",
-	OFORUNTIL:    "foruntil", // not actual syntax; used to avoid off-end pointer live on backedge.892
-	OGE:          ">=",
-	OGOTO:        "goto",
-	OGT:          ">",
-	OIF:          "if",
-	OIMAG:        "imag",
-	OINLMARK:     "inlmark",
-	ODEREF:       "*",
-	OLEN:         "len",
-	OLE:          "<=",
-	OLSH:         "<<",
-	OLT:          "<",
-	OMAKE:        "make",
-	ONEG:         "-",
-	OMOD:         "%",
-	OMUL:         "*",
-	ONEW:         "new",
-	ONE:          "!=",
-	ONOT:         "!",
-	OOFFSETOF:    "unsafe.Offsetof",
-	OOROR:        "||",
-	OOR:          "|",
-	OPANIC:       "panic",
-	OPLUS:        "+",
-	OPRINTN:      "println",
-	OPRINT:       "print",
-	ORANGE:       "range",
-	OREAL:        "real",
-	ORECV:        "<-",
-	ORECOVER:     "recover",
-	ORETURN:      "return",
-	ORSH:         ">>",
-	OSELECT:      "select",
-	OSEND:        "<-",
-	OSIZEOF:      "unsafe.Sizeof",
-	OSUB:         "-",
-	OSWITCH:      "switch",
-	OUNSAFEADD:   "unsafe.Add",
-	OUNSAFESLICE: "unsafe.Slice",
-	OXOR:         "^",
+	OADDR:             "&",
+	OADD:              "+",
+	OADDSTR:           "+",
+	OALIGNOF:          "unsafe.Alignof",
+	OANDAND:           "&&",
+	OANDNOT:           "&^",
+	OAND:              "&",
+	OAPPEND:           "append",
+	OAS:               "=",
+	OAS2:              "=",
+	OBREAK:            "break",
+	OCALL:             "function call", // not actual syntax
+	OCAP:              "cap",
+	OCASE:             "case",
+	OCLOSE:            "close",
+	OCOMPLEX:          "complex",
+	OBITNOT:           "^",
+	OCONTINUE:         "continue",
+	OCOPY:             "copy",
+	ODELETE:           "delete",
+	ODEFER:            "defer",
+	ODIV:              "/",
+	OEQ:               "==",
+	OFALL:             "fallthrough",
+	OFOR:              "for",
+	OGE:               ">=",
+	OGOTO:             "goto",
+	OGT:               ">",
+	OIF:               "if",
+	OIMAG:             "imag",
+	OINLMARK:          "inlmark",
+	ODEREF:            "*",
+	OLEN:              "len",
+	OLE:               "<=",
+	OLSH:              "<<",
+	OLT:               "<",
+	OMAKE:             "make",
+	ONEG:              "-",
+	OMOD:              "%",
+	OMUL:              "*",
+	ONEW:              "new",
+	ONE:               "!=",
+	ONOT:              "!",
+	OOFFSETOF:         "unsafe.Offsetof",
+	OOROR:             "||",
+	OOR:               "|",
+	OPANIC:            "panic",
+	OPLUS:             "+",
+	OPRINTN:           "println",
+	OPRINT:            "print",
+	ORANGE:            "range",
+	OREAL:             "real",
+	ORECV:             "<-",
+	ORECOVER:          "recover",
+	ORETURN:           "return",
+	ORSH:              ">>",
+	OSELECT:           "select",
+	OSEND:             "<-",
+	OSIZEOF:           "unsafe.Sizeof",
+	OSUB:              "-",
+	OSWITCH:           "switch",
+	OUNSAFEADD:        "unsafe.Add",
+	OUNSAFESLICE:      "unsafe.Slice",
+	OUNSAFESLICEDATA:  "unsafe.SliceData",
+	OUNSAFESTRING:     "unsafe.String",
+	OUNSAFESTRINGDATA: "unsafe.StringData",
+	OXOR:              "^",
 }
 
 // GoString returns the Go syntax for the Op, or else its name.
@@ -121,8 +123,8 @@
 
 // Node
 
-// FmtNode implements formatting for a Node n.
-// Every Node implementation must define a Format method that calls FmtNode.
+// fmtNode implements formatting for a Node n.
+// Every Node implementation must define a Format method that calls fmtNode.
 // The valid formats are:
 //
 //	%v	Go syntax
@@ -169,94 +171,99 @@
 }
 
 var OpPrec = []int{
-	OALIGNOF:       8,
-	OAPPEND:        8,
-	OBYTES2STR:     8,
-	OARRAYLIT:      8,
-	OSLICELIT:      8,
-	ORUNES2STR:     8,
-	OCALLFUNC:      8,
-	OCALLINTER:     8,
-	OCALLMETH:      8,
-	OCALL:          8,
-	OCAP:           8,
-	OCLOSE:         8,
-	OCOMPLIT:       8,
-	OCONVIFACE:     8,
-	OCONVIDATA:     8,
-	OCONVNOP:       8,
-	OCONV:          8,
-	OCOPY:          8,
-	ODELETE:        8,
-	OGETG:          8,
-	OLEN:           8,
-	OLITERAL:       8,
-	OMAKESLICE:     8,
-	OMAKESLICECOPY: 8,
-	OMAKE:          8,
-	OMAPLIT:        8,
-	ONAME:          8,
-	ONEW:           8,
-	ONIL:           8,
-	ONONAME:        8,
-	OOFFSETOF:      8,
-	OPANIC:         8,
-	OPAREN:         8,
-	OPRINTN:        8,
-	OPRINT:         8,
-	ORUNESTR:       8,
-	OSIZEOF:        8,
-	OSLICE2ARRPTR:  8,
-	OSTR2BYTES:     8,
-	OSTR2RUNES:     8,
-	OSTRUCTLIT:     8,
-	OTYPE:          8,
-	OUNSAFEADD:     8,
-	OUNSAFESLICE:   8,
-	OINDEXMAP:      8,
-	OINDEX:         8,
-	OSLICE:         8,
-	OSLICESTR:      8,
-	OSLICEARR:      8,
-	OSLICE3:        8,
-	OSLICE3ARR:     8,
-	OSLICEHEADER:   8,
-	ODOTINTER:      8,
-	ODOTMETH:       8,
-	ODOTPTR:        8,
-	ODOTTYPE2:      8,
-	ODOTTYPE:       8,
-	ODOT:           8,
-	OXDOT:          8,
-	OMETHVALUE:     8,
-	OMETHEXPR:      8,
-	OPLUS:          7,
-	ONOT:           7,
-	OBITNOT:        7,
-	ONEG:           7,
-	OADDR:          7,
-	ODEREF:         7,
-	ORECV:          7,
-	OMUL:           6,
-	ODIV:           6,
-	OMOD:           6,
-	OLSH:           6,
-	ORSH:           6,
-	OAND:           6,
-	OANDNOT:        6,
-	OADD:           5,
-	OSUB:           5,
-	OOR:            5,
-	OXOR:           5,
-	OEQ:            4,
-	OLT:            4,
-	OLE:            4,
-	OGE:            4,
-	OGT:            4,
-	ONE:            4,
-	OSEND:          3,
-	OANDAND:        2,
-	OOROR:          1,
+	OALIGNOF:          8,
+	OAPPEND:           8,
+	OBYTES2STR:        8,
+	OARRAYLIT:         8,
+	OSLICELIT:         8,
+	ORUNES2STR:        8,
+	OCALLFUNC:         8,
+	OCALLINTER:        8,
+	OCALLMETH:         8,
+	OCALL:             8,
+	OCAP:              8,
+	OCLOSE:            8,
+	OCOMPLIT:          8,
+	OCONVIFACE:        8,
+	OCONVIDATA:        8,
+	OCONVNOP:          8,
+	OCONV:             8,
+	OCOPY:             8,
+	ODELETE:           8,
+	OGETG:             8,
+	OLEN:              8,
+	OLITERAL:          8,
+	OMAKESLICE:        8,
+	OMAKESLICECOPY:    8,
+	OMAKE:             8,
+	OMAPLIT:           8,
+	ONAME:             8,
+	ONEW:              8,
+	ONIL:              8,
+	ONONAME:           8,
+	OOFFSETOF:         8,
+	OPANIC:            8,
+	OPAREN:            8,
+	OPRINTN:           8,
+	OPRINT:            8,
+	ORUNESTR:          8,
+	OSIZEOF:           8,
+	OSLICE2ARR:        8,
+	OSLICE2ARRPTR:     8,
+	OSTR2BYTES:        8,
+	OSTR2RUNES:        8,
+	OSTRUCTLIT:        8,
+	OTYPE:             8,
+	OUNSAFEADD:        8,
+	OUNSAFESLICE:      8,
+	OUNSAFESLICEDATA:  8,
+	OUNSAFESTRING:     8,
+	OUNSAFESTRINGDATA: 8,
+	OINDEXMAP:         8,
+	OINDEX:            8,
+	OSLICE:            8,
+	OSLICESTR:         8,
+	OSLICEARR:         8,
+	OSLICE3:           8,
+	OSLICE3ARR:        8,
+	OSLICEHEADER:      8,
+	OSTRINGHEADER:     8,
+	ODOTINTER:         8,
+	ODOTMETH:          8,
+	ODOTPTR:           8,
+	ODOTTYPE2:         8,
+	ODOTTYPE:          8,
+	ODOT:              8,
+	OXDOT:             8,
+	OMETHVALUE:        8,
+	OMETHEXPR:         8,
+	OPLUS:             7,
+	ONOT:              7,
+	OBITNOT:           7,
+	ONEG:              7,
+	OADDR:             7,
+	ODEREF:            7,
+	ORECV:             7,
+	OMUL:              6,
+	ODIV:              6,
+	OMOD:              6,
+	OLSH:              6,
+	ORSH:              6,
+	OAND:              6,
+	OANDNOT:           6,
+	OADD:              5,
+	OSUB:              5,
+	OOR:               5,
+	OXOR:              5,
+	OEQ:               4,
+	OLT:               4,
+	OLE:               4,
+	OGE:               4,
+	OGT:               4,
+	ONE:               4,
+	OSEND:             3,
+	OANDAND:           2,
+	OOROR:             1,
 
 	// Statements handled by stmtfmt
 	OAS:         -1,
@@ -274,7 +281,6 @@
 	ODEFER:      -1,
 	OFALL:       -1,
 	OFOR:        -1,
-	OFORUNTIL:   -1,
 	OGOTO:       -1,
 	OIF:         -1,
 	OLABEL:      -1,
@@ -290,7 +296,7 @@
 // StmtWithInit reports whether op is a statement with an explicit init list.
 func StmtWithInit(op Op) bool {
 	switch op {
-	case OIF, OFOR, OFORUNTIL, OSWITCH:
+	case OIF, OFOR, OSWITCH:
 		return true
 	}
 	return false
@@ -401,18 +407,14 @@
 			fmt.Fprintf(s, " else { %v }", n.Else)
 		}
 
-	case OFOR, OFORUNTIL:
+	case OFOR:
 		n := n.(*ForStmt)
-		opname := "for"
-		if n.Op() == OFORUNTIL {
-			opname = "foruntil"
-		}
 		if !exportFormat { // TODO maybe only if FmtShort, same below
-			fmt.Fprintf(s, "%s loop", opname)
+			fmt.Fprintf(s, "for loop")
 			break
 		}
 
-		fmt.Fprint(s, opname)
+		fmt.Fprint(s, "for")
 		if simpleinit {
 			fmt.Fprintf(s, " %v;", n.Init()[0])
 		} else if n.Post != nil {
@@ -429,10 +431,6 @@
 			fmt.Fprint(s, ";")
 		}
 
-		if n.Op() == OFORUNTIL && len(n.Late) != 0 {
-			fmt.Fprintf(s, "; %v", n.Late)
-		}
-
 		fmt.Fprintf(s, " { %v }", n.Body)
 
 	case ORANGE:
@@ -756,6 +754,7 @@
 		OSTR2BYTES,
 		OSTR2RUNES,
 		ORUNESTR,
+		OSLICE2ARR,
 		OSLICE2ARRPTR:
 		n := n.(*ConvExpr)
 		if n.Type() == nil || n.Type().Sym() == nil {
@@ -1127,6 +1126,15 @@
 		dumpNodeHeader(w, n)
 		return
 
+	case OLINKSYMOFFSET:
+		n := n.(*LinksymOffsetExpr)
+		fmt.Fprintf(w, "%+v-%v", n.Op(), n.Linksym)
+		// Offset is almost always 0, so only print when it's interesting.
+		if n.Offset_ != 0 {
+			fmt.Fprintf(w, "%+v", n.Offset_)
+		}
+		dumpNodeHeader(w, n)
+
 	case OASOP:
 		n := n.(*AssignOpStmt)
 		fmt.Fprintf(w, "%+v-%+v", n.Op(), n.AsOp)
diff --git a/src/cmd/compile/internal/ir/func.go b/src/cmd/compile/internal/ir/func.go
index f90c871..b0b8da5 100644
--- a/src/cmd/compile/internal/ir/func.go
+++ b/src/cmd/compile/internal/ir/func.go
@@ -147,9 +147,10 @@
 
 func (f *Func) isStmt() {}
 
-func (n *Func) copy() Node                         { panic(n.no("copy")) }
-func (n *Func) doChildren(do func(Node) bool) bool { return doNodes(n.Body, do) }
-func (n *Func) editChildren(edit func(Node) Node)  { editNodes(n.Body, edit) }
+func (n *Func) copy() Node                                  { panic(n.no("copy")) }
+func (n *Func) doChildren(do func(Node) bool) bool          { return doNodes(n.Body, do) }
+func (n *Func) editChildren(edit func(Node) Node)           { editNodes(n.Body, edit) }
+func (n *Func) editChildrenWithHidden(edit func(Node) Node) { editNodes(n.Body, edit) }
 
 func (f *Func) Type() *types.Type                { return f.Nname.Type() }
 func (f *Func) Sym() *types.Sym                  { return f.Nname.Sym() }
@@ -268,13 +269,6 @@
 	s := f.Sym()
 	pkg := s.Pkg
 
-	// TODO(mdempsky): Remove after submitting CL 393715? This matches
-	// how PkgFuncName has historically handled local functions, but
-	// drchase points out it contradicts the documentation.
-	if pkg == types.LocalPkg {
-		return s.Name
-	}
-
 	return pkg.Path + "." + s.Name
 }
 
@@ -306,7 +300,7 @@
 }
 
 // ClosureDebugRuntimeCheck applies boilerplate checks for debug flags
-// and compiling runtime
+// and compiling runtime.
 func ClosureDebugRuntimeCheck(clo *ClosureExpr) {
 	if base.Debug.Closure > 0 {
 		if clo.Esc() == EscHeap {
diff --git a/src/cmd/compile/internal/ir/mini.go b/src/cmd/compile/internal/ir/mini.go
index 48f5ecc..52c622d 100644
--- a/src/cmd/compile/internal/ir/mini.go
+++ b/src/cmd/compile/internal/ir/mini.go
@@ -2,8 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:generate go run -mod=mod mknode.go
-// Note: see comment at top of mknode.go
+//go:generate go run mknode.go
 
 package ir
 
diff --git a/src/cmd/compile/internal/ir/mknode.go b/src/cmd/compile/internal/ir/mknode.go
index af8869d..716e843 100644
--- a/src/cmd/compile/internal/ir/mknode.go
+++ b/src/cmd/compile/internal/ir/mknode.go
@@ -1,238 +1,366 @@
-// Copyright 2020 The Go Authors. All rights reserved.
+// Copyright 2022 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
 //go:build ignore
-// +build ignore
 
-// Note: this program must be run with the GOROOT
-// environment variable set to the root of this tree.
-//   GOROOT=...
-//   cd $GOROOT/src/cmd/compile/internal/ir
-//   ../../../../../bin/go run -mod=mod mknode.go
+// Note: this program must be run in this directory.
+//   go run mknode.go
 
 package main
 
 import (
 	"bytes"
 	"fmt"
+	"go/ast"
 	"go/format"
-	"go/types"
-	"io/ioutil"
+	"go/parser"
+	"go/token"
+	"io/fs"
 	"log"
-	"reflect"
+	"os"
 	"sort"
 	"strings"
-
-	"golang.org/x/tools/go/packages"
 )
 
-var irPkg *types.Package
+var fset = token.NewFileSet()
+
 var buf bytes.Buffer
 
-func main() {
-	cfg := &packages.Config{
-		Mode: packages.NeedSyntax | packages.NeedTypes,
-	}
-	pkgs, err := packages.Load(cfg, "cmd/compile/internal/ir")
-	if err != nil {
-		log.Fatal(err)
-	}
-	irPkg = pkgs[0].Types
+// concreteNodes contains all concrete types in the package that implement Node
+// (except for the mini* types).
+var concreteNodes []*ast.TypeSpec
 
+// interfaceNodes contains all interface types in the package that implement Node.
+var interfaceNodes []*ast.TypeSpec
+
+// mini contains the embeddable mini types (miniNode, miniExpr, and miniStmt).
+var mini = map[string]*ast.TypeSpec{}
+
+// implementsNode reports whether the type t is one which represents a Node
+// in the AST.
+func implementsNode(t ast.Expr) bool {
+	id, ok := t.(*ast.Ident)
+	if !ok {
+		return false // only named types
+	}
+	for _, ts := range interfaceNodes {
+		if ts.Name.Name == id.Name {
+			return true
+		}
+	}
+	for _, ts := range concreteNodes {
+		if ts.Name.Name == id.Name {
+			return true
+		}
+	}
+	return false
+}
+
+func isMini(t ast.Expr) bool {
+	id, ok := t.(*ast.Ident)
+	return ok && mini[id.Name] != nil
+}
+
+func isNamedType(t ast.Expr, name string) bool {
+	if id, ok := t.(*ast.Ident); ok {
+		if id.Name == name {
+			return true
+		}
+	}
+	return false
+}
+
+func main() {
 	fmt.Fprintln(&buf, "// Code generated by mknode.go. DO NOT EDIT.")
 	fmt.Fprintln(&buf)
 	fmt.Fprintln(&buf, "package ir")
 	fmt.Fprintln(&buf)
 	fmt.Fprintln(&buf, `import "fmt"`)
 
-	scope := irPkg.Scope()
-	for _, name := range scope.Names() {
-		if strings.HasPrefix(name, "mini") {
-			continue
+	filter := func(file fs.FileInfo) bool {
+		return !strings.HasPrefix(file.Name(), "mknode")
+	}
+	pkgs, err := parser.ParseDir(fset, ".", filter, 0)
+	if err != nil {
+		panic(err)
+	}
+	pkg := pkgs["ir"]
+
+	// Find all the mini types. These let us determine which
+	// concrete types implement Node, so we need to find them first.
+	for _, f := range pkg.Files {
+		for _, d := range f.Decls {
+			g, ok := d.(*ast.GenDecl)
+			if !ok {
+				continue
+			}
+			for _, s := range g.Specs {
+				t, ok := s.(*ast.TypeSpec)
+				if !ok {
+					continue
+				}
+				if strings.HasPrefix(t.Name.Name, "mini") {
+					mini[t.Name.Name] = t
+					// Double-check that it is or embeds miniNode.
+					if t.Name.Name != "miniNode" {
+						s := t.Type.(*ast.StructType)
+						if !isNamedType(s.Fields.List[0].Type, "miniNode") {
+							panic(fmt.Sprintf("can't find miniNode in %s", t.Name.Name))
+						}
+					}
+				}
+			}
 		}
-
-		obj, ok := scope.Lookup(name).(*types.TypeName)
-		if !ok {
-			continue
-		}
-		typ := obj.Type().(*types.Named)
-		if !implementsNode(types.NewPointer(typ)) {
-			continue
-		}
-
-		fmt.Fprintf(&buf, "\n")
-		fmt.Fprintf(&buf, "func (n *%s) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }\n", name)
-
-		switch name {
-		case "Name", "Func":
-			// Too specialized to automate.
-			continue
-		}
-
-		forNodeFields(typ,
-			"func (n *%[1]s) copy() Node { c := *n\n",
-			"",
-			"c.%[1]s = copy%[2]s(c.%[1]s)",
-			"return &c }\n")
-
-		forNodeFields(typ,
-			"func (n *%[1]s) doChildren(do func(Node) bool) bool {\n",
-			"if n.%[1]s != nil && do(n.%[1]s) { return true }",
-			"if do%[2]s(n.%[1]s, do) { return true }",
-			"return false }\n")
-
-		forNodeFields(typ,
-			"func (n *%[1]s) editChildren(edit func(Node) Node) {\n",
-			"if n.%[1]s != nil { n.%[1]s = edit(n.%[1]s).(%[2]s) }",
-			"edit%[2]s(n.%[1]s, edit)",
-			"}\n")
 	}
 
-	makeHelpers()
+	// Find all the declarations of concrete types that implement Node.
+	for _, f := range pkg.Files {
+		for _, d := range f.Decls {
+			g, ok := d.(*ast.GenDecl)
+			if !ok {
+				continue
+			}
+			for _, s := range g.Specs {
+				t, ok := s.(*ast.TypeSpec)
+				if !ok {
+					continue
+				}
+				if strings.HasPrefix(t.Name.Name, "mini") {
+					// We don't treat the mini types as
+					// concrete implementations of Node
+					// (even though they are) because
+					// we only use them by embedding them.
+					continue
+				}
+				if isConcreteNode(t) {
+					concreteNodes = append(concreteNodes, t)
+				}
+				if isInterfaceNode(t) {
+					interfaceNodes = append(interfaceNodes, t)
+				}
+			}
+		}
+	}
+	// Sort for deterministic output.
+	sort.Slice(concreteNodes, func(i, j int) bool {
+		return concreteNodes[i].Name.Name < concreteNodes[j].Name.Name
+	})
+	// Generate code for each concrete type.
+	for _, t := range concreteNodes {
+		processType(t)
+	}
+	// Add some helpers.
+	generateHelpers()
 
+	// Format and write output.
 	out, err := format.Source(buf.Bytes())
 	if err != nil {
 		// write out mangled source so we can see the bug.
 		out = buf.Bytes()
 	}
-
-	err = ioutil.WriteFile("node_gen.go", out, 0666)
+	err = os.WriteFile("node_gen.go", out, 0666)
 	if err != nil {
 		log.Fatal(err)
 	}
 }
 
-// needHelper maps needed slice helpers from their base name to their
-// respective slice-element type.
-var needHelper = map[string]string{}
-
-func makeHelpers() {
-	var names []string
-	for name := range needHelper {
-		names = append(names, name)
+// isConcreteNode reports whether the type t is a concrete type
+// implementing Node.
+func isConcreteNode(t *ast.TypeSpec) bool {
+	s, ok := t.Type.(*ast.StructType)
+	if !ok {
+		return false
 	}
-	sort.Strings(names)
-
-	for _, name := range names {
-		fmt.Fprintf(&buf, sliceHelperTmpl, name, needHelper[name])
-	}
-}
-
-const sliceHelperTmpl = `
-func copy%[1]s(list []%[2]s) []%[2]s {
-	if list == nil {
-		return nil
-	}
-	c := make([]%[2]s, len(list))
-	copy(c, list)
-	return c
-}
-func do%[1]s(list []%[2]s, do func(Node) bool) bool {
-	for _, x := range list {
-		if x != nil && do(x) {
+	for _, f := range s.Fields.List {
+		if isMini(f.Type) {
 			return true
 		}
 	}
 	return false
 }
-func edit%[1]s(list []%[2]s, edit func(Node) Node) {
-	for i, x := range list {
-		if x != nil {
-			list[i] = edit(x).(%[2]s)
-		}
-	}
-}
-`
 
-func forNodeFields(named *types.Named, prologue, singleTmpl, sliceTmpl, epilogue string) {
-	fmt.Fprintf(&buf, prologue, named.Obj().Name())
-
-	anyField(named.Underlying().(*types.Struct), func(f *types.Var) bool {
-		if f.Embedded() {
-			return false
-		}
-		name, typ := f.Name(), f.Type()
-
-		slice, _ := typ.Underlying().(*types.Slice)
-		if slice != nil {
-			typ = slice.Elem()
-		}
-
-		tmpl, what := singleTmpl, types.TypeString(typ, types.RelativeTo(irPkg))
-		if what == "go/constant.Value" {
-			return false
-		}
-		if implementsNode(typ) {
-			if slice != nil {
-				helper := strings.TrimPrefix(what, "*") + "s"
-				needHelper[helper] = what
-				tmpl, what = sliceTmpl, helper
-			}
-		} else if what == "*Field" {
-			// Special case for *Field.
-			tmpl = sliceTmpl
-			if slice != nil {
-				what = "Fields"
-			} else {
-				what = "Field"
-			}
-		} else {
-			return false
-		}
-
-		if tmpl == "" {
-			return false
-		}
-
-		// Allow template to not use all arguments without
-		// upsetting fmt.Printf.
-		s := fmt.Sprintf(tmpl+"\x00 %[1]s %[2]s", name, what)
-		fmt.Fprintln(&buf, s[:strings.LastIndex(s, "\x00")])
+// isInterfaceNode reports whether the type t is an interface type
+// implementing Node (including Node itself).
+func isInterfaceNode(t *ast.TypeSpec) bool {
+	s, ok := t.Type.(*ast.InterfaceType)
+	if !ok {
 		return false
-	})
-
-	fmt.Fprintf(&buf, epilogue)
-}
-
-func implementsNode(typ types.Type) bool {
-	if _, ok := typ.Underlying().(*types.Interface); ok {
-		// TODO(mdempsky): Check the interface implements Node.
-		// Worst case, node_gen.go will fail to compile if we're wrong.
+	}
+	if t.Name.Name == "Node" {
 		return true
 	}
-
-	if ptr, ok := typ.(*types.Pointer); ok {
-		if str, ok := ptr.Elem().Underlying().(*types.Struct); ok {
-			return anyField(str, func(f *types.Var) bool {
-				return f.Embedded() && f.Name() == "miniNode"
-			})
-		}
+	if t.Name.Name == "OrigNode" || t.Name.Name == "InitNode" {
+		// These we exempt from consideration (fields of
+		// this type don't need to be walked or copied).
+		return false
 	}
 
+	// Look for embedded Node type.
+	// Note that this doesn't handle multi-level embedding, but
+	// we have none of that at the moment.
+	for _, f := range s.Methods.List {
+		if len(f.Names) != 0 {
+			continue
+		}
+		if isNamedType(f.Type, "Node") {
+			return true
+		}
+	}
 	return false
 }
 
-func anyField(typ *types.Struct, pred func(f *types.Var) bool) bool {
-	for i, n := 0, typ.NumFields(); i < n; i++ {
-		if value, ok := reflect.StructTag(typ.Tag(i)).Lookup("mknode"); ok {
-			if value != "-" {
-				panic(fmt.Sprintf("unexpected tag value: %q", value))
-			}
-			continue
-		}
+func processType(t *ast.TypeSpec) {
+	name := t.Name.Name
+	fmt.Fprintf(&buf, "\n")
+	fmt.Fprintf(&buf, "func (n *%s) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }\n", name)
 
-		f := typ.Field(i)
-		if pred(f) {
-			return true
+	switch name {
+	case "Name", "Func":
+		// Too specialized to automate.
+		return
+	}
+
+	s := t.Type.(*ast.StructType)
+	fields := s.Fields.List
+
+	// Expand any embedded fields.
+	for i := 0; i < len(fields); i++ {
+		f := fields[i]
+		if len(f.Names) != 0 {
+			continue // not embedded
 		}
-		if f.Embedded() {
-			if typ, ok := f.Type().Underlying().(*types.Struct); ok {
-				if anyField(typ, pred) {
-					return true
+		if isMini(f.Type) {
+			// Insert the fields of the embedded type into the main type.
+			// (It would be easier just to append, but inserting in place
+			// matches the old mknode behavior.)
+			ss := mini[f.Type.(*ast.Ident).Name].Type.(*ast.StructType)
+			var f2 []*ast.Field
+			f2 = append(f2, fields[:i]...)
+			f2 = append(f2, ss.Fields.List...)
+			f2 = append(f2, fields[i+1:]...)
+			fields = f2
+			i--
+			continue
+		} else if isNamedType(f.Type, "origNode") {
+			// Ignore this field
+			copy(fields[i:], fields[i+1:])
+			fields = fields[:len(fields)-1]
+			i--
+			continue
+		} else {
+			panic("unknown embedded field " + fmt.Sprintf("%v", f.Type))
+		}
+	}
+	// Process fields.
+	var copyBody strings.Builder
+	var doChildrenBody strings.Builder
+	var editChildrenBody strings.Builder
+	var editChildrenWithHiddenBody strings.Builder
+	for _, f := range fields {
+		names := f.Names
+		ft := f.Type
+		hidden := false
+		if f.Tag != nil {
+			tag := f.Tag.Value[1 : len(f.Tag.Value)-1]
+			if strings.HasPrefix(tag, "mknode:") {
+				if tag[7:] == "\"-\"" {
+					if !isNamedType(ft, "Node") {
+						continue
+					}
+					hidden = true
+				} else {
+					panic(fmt.Sprintf("unexpected tag value: %s", tag))
 				}
 			}
 		}
+		if isNamedType(ft, "Nodes") {
+			// Nodes == []Node
+			ft = &ast.ArrayType{Elt: &ast.Ident{Name: "Node"}}
+		}
+		isSlice := false
+		if a, ok := ft.(*ast.ArrayType); ok && a.Len == nil {
+			isSlice = true
+			ft = a.Elt
+		}
+		isPtr := false
+		if p, ok := ft.(*ast.StarExpr); ok {
+			isPtr = true
+			ft = p.X
+		}
+		if !implementsNode(ft) {
+			continue
+		}
+		for _, name := range names {
+			ptr := ""
+			if isPtr {
+				ptr = "*"
+			}
+			if isSlice {
+				fmt.Fprintf(&editChildrenWithHiddenBody,
+					"edit%ss(n.%s, edit)\n", ft, name)
+			} else {
+				fmt.Fprintf(&editChildrenWithHiddenBody,
+					"if n.%s != nil {\nn.%s = edit(n.%s).(%s%s)\n}\n", name, name, name, ptr, ft)
+			}
+			if hidden {
+				continue
+			}
+			if isSlice {
+				fmt.Fprintf(&copyBody, "c.%s = copy%ss(c.%s)\n", name, ft, name)
+				fmt.Fprintf(&doChildrenBody,
+					"if do%ss(n.%s, do) {\nreturn true\n}\n", ft, name)
+				fmt.Fprintf(&editChildrenBody,
+					"edit%ss(n.%s, edit)\n", ft, name)
+			} else {
+				fmt.Fprintf(&doChildrenBody,
+					"if n.%s != nil && do(n.%s) {\nreturn true\n}\n", name, name)
+				fmt.Fprintf(&editChildrenBody,
+					"if n.%s != nil {\nn.%s = edit(n.%s).(%s%s)\n}\n", name, name, name, ptr, ft)
+			}
+		}
 	}
-	return false
+	fmt.Fprintf(&buf, "func (n *%s) copy() Node {\nc := *n\n", name)
+	buf.WriteString(copyBody.String())
+	fmt.Fprintf(&buf, "return &c\n}\n")
+	fmt.Fprintf(&buf, "func (n *%s) doChildren(do func(Node) bool) bool {\n", name)
+	buf.WriteString(doChildrenBody.String())
+	fmt.Fprintf(&buf, "return false\n}\n")
+	fmt.Fprintf(&buf, "func (n *%s) editChildren(edit func(Node) Node) {\n", name)
+	buf.WriteString(editChildrenBody.String())
+	fmt.Fprintf(&buf, "}\n")
+	fmt.Fprintf(&buf, "func (n *%s) editChildrenWithHidden(edit func(Node) Node) {\n", name)
+	buf.WriteString(editChildrenWithHiddenBody.String())
+	fmt.Fprintf(&buf, "}\n")
+}
+
+func generateHelpers() {
+	for _, typ := range []string{"CaseClause", "CommClause", "Name", "Node", "Ntype"} {
+		ptr := "*"
+		if typ == "Node" || typ == "Ntype" {
+			ptr = "" // interfaces don't need *
+		}
+		fmt.Fprintf(&buf, "\n")
+		fmt.Fprintf(&buf, "func copy%ss(list []%s%s) []%s%s {\n", typ, ptr, typ, ptr, typ)
+		fmt.Fprintf(&buf, "if list == nil { return nil }\n")
+		fmt.Fprintf(&buf, "c := make([]%s%s, len(list))\n", ptr, typ)
+		fmt.Fprintf(&buf, "copy(c, list)\n")
+		fmt.Fprintf(&buf, "return c\n")
+		fmt.Fprintf(&buf, "}\n")
+		fmt.Fprintf(&buf, "func do%ss(list []%s%s, do func(Node) bool) bool {\n", typ, ptr, typ)
+		fmt.Fprintf(&buf, "for _, x := range list {\n")
+		fmt.Fprintf(&buf, "if x != nil && do(x) {\n")
+		fmt.Fprintf(&buf, "return true\n")
+		fmt.Fprintf(&buf, "}\n")
+		fmt.Fprintf(&buf, "}\n")
+		fmt.Fprintf(&buf, "return false\n")
+		fmt.Fprintf(&buf, "}\n")
+		fmt.Fprintf(&buf, "func edit%ss(list []%s%s, edit func(Node) Node) {\n", typ, ptr, typ)
+		fmt.Fprintf(&buf, "for i, x := range list {\n")
+		fmt.Fprintf(&buf, "if x != nil {\n")
+		fmt.Fprintf(&buf, "list[i] = edit(x).(%s%s)\n", ptr, typ)
+		fmt.Fprintf(&buf, "}\n")
+		fmt.Fprintf(&buf, "}\n")
+		fmt.Fprintf(&buf, "}\n")
+	}
 }
diff --git a/src/cmd/compile/internal/ir/name.go b/src/cmd/compile/internal/ir/name.go
index 711d1de..43aa582 100644
--- a/src/cmd/compile/internal/ir/name.go
+++ b/src/cmd/compile/internal/ir/name.go
@@ -134,9 +134,10 @@
 
 func (n *Name) isExpr() {}
 
-func (n *Name) copy() Node                         { panic(n.no("copy")) }
-func (n *Name) doChildren(do func(Node) bool) bool { return false }
-func (n *Name) editChildren(edit func(Node) Node)  {}
+func (n *Name) copy() Node                                  { panic(n.no("copy")) }
+func (n *Name) doChildren(do func(Node) bool) bool          { return false }
+func (n *Name) editChildren(edit func(Node) Node)           {}
+func (n *Name) editChildrenWithHidden(edit func(Node) Node) {}
 
 // RecordFrameOffset records the frame offset for the name.
 // It is used by package types when laying out function arguments.
@@ -236,6 +237,8 @@
 	nameInlLocal                 // PAUTO created by inliner, derived from callee local
 	nameOpenDeferSlot            // if temporary var storing info for open-coded defers
 	nameLibfuzzer8BitCounter     // if PEXTERN should be assigned to __sancov_cntrs section
+	nameCoverageCounter          // instrumentation counter var for cmd/cover
+	nameCoverageAuxVar           // instrumentation pkg ID variable cmd/cover
 	nameAlias                    // is type name an alias
 )
 
@@ -251,6 +254,8 @@
 func (n *Name) InlLocal() bool                 { return n.flags&nameInlLocal != 0 }
 func (n *Name) OpenDeferSlot() bool            { return n.flags&nameOpenDeferSlot != 0 }
 func (n *Name) Libfuzzer8BitCounter() bool     { return n.flags&nameLibfuzzer8BitCounter != 0 }
+func (n *Name) CoverageCounter() bool          { return n.flags&nameCoverageCounter != 0 }
+func (n *Name) CoverageAuxVar() bool           { return n.flags&nameCoverageAuxVar != 0 }
 
 func (n *Name) setReadonly(b bool)                 { n.flags.set(nameReadonly, b) }
 func (n *Name) SetNeedzero(b bool)                 { n.flags.set(nameNeedzero, b) }
@@ -264,6 +269,8 @@
 func (n *Name) SetInlLocal(b bool)                 { n.flags.set(nameInlLocal, b) }
 func (n *Name) SetOpenDeferSlot(b bool)            { n.flags.set(nameOpenDeferSlot, b) }
 func (n *Name) SetLibfuzzer8BitCounter(b bool)     { n.flags.set(nameLibfuzzer8BitCounter, b) }
+func (n *Name) SetCoverageCounter(b bool)          { n.flags.set(nameCoverageCounter, b) }
+func (n *Name) SetCoverageAuxVar(b bool)           { n.flags.set(nameCoverageAuxVar, b) }
 
 // OnStack reports whether variable n may reside on the stack.
 func (n *Name) OnStack() bool {
@@ -336,6 +343,14 @@
 // NewClosureVar returns a new closure variable for fn to refer to
 // outer variable n.
 func NewClosureVar(pos src.XPos, fn *Func, n *Name) *Name {
+	switch n.Class {
+	case PAUTO, PPARAM, PPARAMOUT, PAUTOHEAP:
+		// ok
+	default:
+		// Prevent mistaken capture of global variables.
+		base.Fatalf("NewClosureVar: %+v", n)
+	}
+
 	c := NewNameAt(pos, n.Sym())
 	c.Curfn = fn
 	c.Class = PAUTOHEAP
diff --git a/src/cmd/compile/internal/ir/node.go b/src/cmd/compile/internal/ir/node.go
index 3b69f98..b42f914 100644
--- a/src/cmd/compile/internal/ir/node.go
+++ b/src/cmd/compile/internal/ir/node.go
@@ -30,6 +30,7 @@
 
 	doChildren(func(Node) bool) bool
 	editChildren(func(Node) Node)
+	editChildrenWithHidden(func(Node) Node)
 
 	// Abstract graph structure, for generic traversals.
 	Op() Op
@@ -134,6 +135,7 @@
 	OSTR2BYTES    // Type(X) (Type is []byte, X is a string)
 	OSTR2BYTESTMP // Type(X) (Type is []byte, X is a string, ephemeral)
 	OSTR2RUNES    // Type(X) (Type is []rune, X is a string)
+	OSLICE2ARR    // Type(X) (Type is [N]T, X is a []T)
 	OSLICE2ARRPTR // Type(X) (Type is *[N]T, X is a []T)
 	// X = Y or (if Def=true) X := Y
 	// If Def, then Init includes a DCL node for X.
@@ -152,7 +154,7 @@
 	// Prior to walk, they are: X(Args), where Args is all regular arguments.
 	// After walk, if any argument whose evaluation might requires temporary variable,
 	// that temporary variable will be pushed to Init, Args will contains an updated
-	// set of arguments. KeepAlive is all OVARLIVE nodes that are attached to OCALLxxx.
+	// set of arguments.
 	OCALLFUNC  // X(Args) (function call f(args))
 	OCALLMETH  // X(Args) (direct method call x.Method(args))
 	OCALLINTER // X(Args) (interface method call x.Method(args))
@@ -209,45 +211,49 @@
 	//
 	// This node is created so the walk pass can optimize this pattern which would
 	// otherwise be hard to detect after the order pass.
-	OMUL         // X * Y
-	ODIV         // X / Y
-	OMOD         // X % Y
-	OLSH         // X << Y
-	ORSH         // X >> Y
-	OAND         // X & Y
-	OANDNOT      // X &^ Y
-	ONEW         // new(X); corresponds to calls to new in source code
-	ONOT         // !X
-	OBITNOT      // ^X
-	OPLUS        // +X
-	ONEG         // -X
-	OOROR        // X || Y
-	OPANIC       // panic(X)
-	OPRINT       // print(List)
-	OPRINTN      // println(List)
-	OPAREN       // (X)
-	OSEND        // Chan <- Value
-	OSLICE       // X[Low : High] (X is untypechecked or slice)
-	OSLICEARR    // X[Low : High] (X is pointer to array)
-	OSLICESTR    // X[Low : High] (X is string)
-	OSLICE3      // X[Low : High : Max] (X is untypedchecked or slice)
-	OSLICE3ARR   // X[Low : High : Max] (X is pointer to array)
-	OSLICEHEADER // sliceheader{Ptr, Len, Cap} (Ptr is unsafe.Pointer, Len is length, Cap is capacity)
-	ORECOVER     // recover()
-	ORECOVERFP   // recover(Args) w/ explicit FP argument
-	ORECV        // <-X
-	ORUNESTR     // Type(X) (Type is string, X is rune)
-	OSELRECV2    // like OAS2: Lhs = Rhs where len(Lhs)=2, len(Rhs)=1, Rhs[0].Op = ORECV (appears as .Var of OCASE)
-	OREAL        // real(X)
-	OIMAG        // imag(X)
-	OCOMPLEX     // complex(X, Y)
-	OALIGNOF     // unsafe.Alignof(X)
-	OOFFSETOF    // unsafe.Offsetof(X)
-	OSIZEOF      // unsafe.Sizeof(X)
-	OUNSAFEADD   // unsafe.Add(X, Y)
-	OUNSAFESLICE // unsafe.Slice(X, Y)
-	OMETHEXPR    // X(Args) (method expression T.Method(args), first argument is the method receiver)
-	OMETHVALUE   // X.Sel   (method expression t.Method, not called)
+	OMUL              // X * Y
+	ODIV              // X / Y
+	OMOD              // X % Y
+	OLSH              // X << Y
+	ORSH              // X >> Y
+	OAND              // X & Y
+	OANDNOT           // X &^ Y
+	ONEW              // new(X); corresponds to calls to new in source code
+	ONOT              // !X
+	OBITNOT           // ^X
+	OPLUS             // +X
+	ONEG              // -X
+	OOROR             // X || Y
+	OPANIC            // panic(X)
+	OPRINT            // print(List)
+	OPRINTN           // println(List)
+	OPAREN            // (X)
+	OSEND             // Chan <- Value
+	OSLICE            // X[Low : High] (X is untypechecked or slice)
+	OSLICEARR         // X[Low : High] (X is pointer to array)
+	OSLICESTR         // X[Low : High] (X is string)
+	OSLICE3           // X[Low : High : Max] (X is untypedchecked or slice)
+	OSLICE3ARR        // X[Low : High : Max] (X is pointer to array)
+	OSLICEHEADER      // sliceheader{Ptr, Len, Cap} (Ptr is unsafe.Pointer, Len is length, Cap is capacity)
+	OSTRINGHEADER     // stringheader{Ptr, Len} (Ptr is unsafe.Pointer, Len is length)
+	ORECOVER          // recover()
+	ORECOVERFP        // recover(Args) w/ explicit FP argument
+	ORECV             // <-X
+	ORUNESTR          // Type(X) (Type is string, X is rune)
+	OSELRECV2         // like OAS2: Lhs = Rhs where len(Lhs)=2, len(Rhs)=1, Rhs[0].Op = ORECV (appears as .Var of OCASE)
+	OREAL             // real(X)
+	OIMAG             // imag(X)
+	OCOMPLEX          // complex(X, Y)
+	OALIGNOF          // unsafe.Alignof(X)
+	OOFFSETOF         // unsafe.Offsetof(X)
+	OSIZEOF           // unsafe.Sizeof(X)
+	OUNSAFEADD        // unsafe.Add(X, Y)
+	OUNSAFESLICE      // unsafe.Slice(X, Y)
+	OUNSAFESLICEDATA  // unsafe.SliceData(X)
+	OUNSAFESTRING     // unsafe.String(X, Y)
+	OUNSAFESTRINGDATA // unsafe.StringData(X)
+	OMETHEXPR         // X(Args) (method expression T.Method(args), first argument is the method receiver)
+	OMETHVALUE        // X.Sel   (method expression t.Method, not called)
 
 	// statements
 	OBLOCK // { List } (block of code)
@@ -263,24 +269,14 @@
 	ODEFER    // defer Call
 	OFALL     // fallthrough
 	OFOR      // for Init; Cond; Post { Body }
-	// OFORUNTIL is like OFOR, but the test (Cond) is applied after the body:
-	// 	Init
-	// 	top: { Body }   // Execute the body at least once
-	// 	cont: Post
-	// 	if Cond {        // And then test the loop condition
-	// 		List     // Before looping to top, execute List
-	// 		goto top
-	// 	}
-	// OFORUNTIL is created by walk. There's no way to write this in Go code.
-	OFORUNTIL
-	OGOTO   // goto Label
-	OIF     // if Init; Cond { Then } else { Else }
-	OLABEL  // Label:
-	OGO     // go Call
-	ORANGE  // for Key, Value = range X { Body }
-	ORETURN // return Results
-	OSELECT // select { Cases }
-	OSWITCH // switch Init; Expr { Cases }
+	OGOTO     // goto Label
+	OIF       // if Init; Cond { Then } else { Else }
+	OLABEL    // Label:
+	OGO       // go Call
+	ORANGE    // for Key, Value = range X { Body }
+	ORETURN   // return Results
+	OSELECT   // select { Cases }
+	OSWITCH   // switch Init; Expr { Cases }
 	// OTYPESW:  X := Y.(type) (appears as .Tag of OSWITCH)
 	//   X is nil if there is no type-switch variable
 	OTYPESW
@@ -298,9 +294,6 @@
 	OSPTR          // base pointer of a slice or string.
 	OCFUNC         // reference to c function pointer (not go func value)
 	OCHECKNIL      // emit code to ensure pointer/interface not nil
-	OVARDEF        // variable is about to be fully initialized
-	OVARKILL       // variable is dead
-	OVARLIVE       // variable is alive
 	ORESULT        // result of a function call; Xoffset is stack offset
 	OINLMARK       // start of an inlined body, with file/line of caller. Xoffset is an index into the inline tree.
 	OLINKSYMOFFSET // offset within a name
@@ -463,9 +456,6 @@
 	Nowritebarrierrec  // error on write barrier in this or recursive callees
 	Yeswritebarrierrec // cancels Nowritebarrierrec in this function and callees
 
-	// Runtime and cgo type pragmas
-	NotInHeap // values of this type must not be heap allocated
-
 	// Go command pragmas
 	GoBuildPragma
 
diff --git a/src/cmd/compile/internal/ir/node_gen.go b/src/cmd/compile/internal/ir/node_gen.go
index 6e14bea..2dda76b 100644
--- a/src/cmd/compile/internal/ir/node_gen.go
+++ b/src/cmd/compile/internal/ir/node_gen.go
@@ -30,6 +30,13 @@
 		n.Prealloc = edit(n.Prealloc).(*Name)
 	}
 }
+func (n *AddStringExpr) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	editNodes(n.List, edit)
+	if n.Prealloc != nil {
+		n.Prealloc = edit(n.Prealloc).(*Name)
+	}
+}
 
 func (n *AddrExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *AddrExpr) copy() Node {
@@ -58,6 +65,15 @@
 		n.Prealloc = edit(n.Prealloc).(*Name)
 	}
 }
+func (n *AddrExpr) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.X != nil {
+		n.X = edit(n.X).(Node)
+	}
+	if n.Prealloc != nil {
+		n.Prealloc = edit(n.Prealloc).(*Name)
+	}
+}
 
 func (n *AssignListStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *AssignListStmt) copy() Node {
@@ -84,6 +100,11 @@
 	editNodes(n.Lhs, edit)
 	editNodes(n.Rhs, edit)
 }
+func (n *AssignListStmt) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	editNodes(n.Lhs, edit)
+	editNodes(n.Rhs, edit)
+}
 
 func (n *AssignOpStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *AssignOpStmt) copy() Node {
@@ -112,6 +133,15 @@
 		n.Y = edit(n.Y).(Node)
 	}
 }
+func (n *AssignOpStmt) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.X != nil {
+		n.X = edit(n.X).(Node)
+	}
+	if n.Y != nil {
+		n.Y = edit(n.Y).(Node)
+	}
+}
 
 func (n *AssignStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *AssignStmt) copy() Node {
@@ -140,6 +170,15 @@
 		n.Y = edit(n.Y).(Node)
 	}
 }
+func (n *AssignStmt) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.X != nil {
+		n.X = edit(n.X).(Node)
+	}
+	if n.Y != nil {
+		n.Y = edit(n.Y).(Node)
+	}
+}
 
 func (n *BasicLit) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *BasicLit) copy() Node {
@@ -156,6 +195,9 @@
 func (n *BasicLit) editChildren(edit func(Node) Node) {
 	editNodes(n.init, edit)
 }
+func (n *BasicLit) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+}
 
 func (n *BinaryExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *BinaryExpr) copy() Node {
@@ -184,6 +226,18 @@
 		n.Y = edit(n.Y).(Node)
 	}
 }
+func (n *BinaryExpr) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.X != nil {
+		n.X = edit(n.X).(Node)
+	}
+	if n.Y != nil {
+		n.Y = edit(n.Y).(Node)
+	}
+	if n.RType != nil {
+		n.RType = edit(n.RType).(Node)
+	}
+}
 
 func (n *BlockStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *BlockStmt) copy() Node {
@@ -205,6 +259,10 @@
 	editNodes(n.init, edit)
 	editNodes(n.List, edit)
 }
+func (n *BlockStmt) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	editNodes(n.List, edit)
+}
 
 func (n *BranchStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *BranchStmt) copy() Node {
@@ -221,6 +279,9 @@
 func (n *BranchStmt) editChildren(edit func(Node) Node) {
 	editNodes(n.init, edit)
 }
+func (n *BranchStmt) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+}
 
 func (n *CallExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *CallExpr) copy() Node {
@@ -253,12 +314,24 @@
 	editNodes(n.Args, edit)
 	editNames(n.KeepAlive, edit)
 }
+func (n *CallExpr) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.X != nil {
+		n.X = edit(n.X).(Node)
+	}
+	editNodes(n.Args, edit)
+	if n.RType != nil {
+		n.RType = edit(n.RType).(Node)
+	}
+	editNames(n.KeepAlive, edit)
+}
 
 func (n *CaseClause) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *CaseClause) copy() Node {
 	c := *n
 	c.init = copyNodes(c.init)
 	c.List = copyNodes(c.List)
+	c.RTypes = copyNodes(c.RTypes)
 	c.Body = copyNodes(c.Body)
 	return &c
 }
@@ -272,6 +345,9 @@
 	if doNodes(n.List, do) {
 		return true
 	}
+	if doNodes(n.RTypes, do) {
+		return true
+	}
 	if doNodes(n.Body, do) {
 		return true
 	}
@@ -283,6 +359,16 @@
 		n.Var = edit(n.Var).(*Name)
 	}
 	editNodes(n.List, edit)
+	editNodes(n.RTypes, edit)
+	editNodes(n.Body, edit)
+}
+func (n *CaseClause) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.Var != nil {
+		n.Var = edit(n.Var).(*Name)
+	}
+	editNodes(n.List, edit)
+	editNodes(n.RTypes, edit)
 	editNodes(n.Body, edit)
 }
 
@@ -307,6 +393,12 @@
 		n.Prealloc = edit(n.Prealloc).(*Name)
 	}
 }
+func (n *ClosureExpr) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.Prealloc != nil {
+		n.Prealloc = edit(n.Prealloc).(*Name)
+	}
+}
 
 func (n *CommClause) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *CommClause) copy() Node {
@@ -334,6 +426,13 @@
 	}
 	editNodes(n.Body, edit)
 }
+func (n *CommClause) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.Comm != nil {
+		n.Comm = edit(n.Comm).(Node)
+	}
+	editNodes(n.Body, edit)
+}
 
 func (n *CompLitExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *CompLitExpr) copy() Node {
@@ -361,6 +460,16 @@
 		n.Prealloc = edit(n.Prealloc).(*Name)
 	}
 }
+func (n *CompLitExpr) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	editNodes(n.List, edit)
+	if n.RType != nil {
+		n.RType = edit(n.RType).(Node)
+	}
+	if n.Prealloc != nil {
+		n.Prealloc = edit(n.Prealloc).(*Name)
+	}
+}
 
 func (n *ConstExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *ConstExpr) copy() Node {
@@ -377,6 +486,9 @@
 func (n *ConstExpr) editChildren(edit func(Node) Node) {
 	editNodes(n.init, edit)
 }
+func (n *ConstExpr) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+}
 
 func (n *ConvExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *ConvExpr) copy() Node {
@@ -399,6 +511,24 @@
 		n.X = edit(n.X).(Node)
 	}
 }
+func (n *ConvExpr) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.X != nil {
+		n.X = edit(n.X).(Node)
+	}
+	if n.TypeWord != nil {
+		n.TypeWord = edit(n.TypeWord).(Node)
+	}
+	if n.SrcRType != nil {
+		n.SrcRType = edit(n.SrcRType).(Node)
+	}
+	if n.ElemRType != nil {
+		n.ElemRType = edit(n.ElemRType).(Node)
+	}
+	if n.ElemElemRType != nil {
+		n.ElemElemRType = edit(n.ElemElemRType).(Node)
+	}
+}
 
 func (n *Decl) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *Decl) copy() Node {
@@ -416,6 +546,11 @@
 		n.X = edit(n.X).(*Name)
 	}
 }
+func (n *Decl) editChildrenWithHidden(edit func(Node) Node) {
+	if n.X != nil {
+		n.X = edit(n.X).(*Name)
+	}
+}
 
 func (n *DynamicType) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *DynamicType) copy() Node {
@@ -444,6 +579,15 @@
 		n.ITab = edit(n.ITab).(Node)
 	}
 }
+func (n *DynamicType) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.RType != nil {
+		n.RType = edit(n.RType).(Node)
+	}
+	if n.ITab != nil {
+		n.ITab = edit(n.ITab).(Node)
+	}
+}
 
 func (n *DynamicTypeAssertExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *DynamicTypeAssertExpr) copy() Node {
@@ -458,6 +602,9 @@
 	if n.X != nil && do(n.X) {
 		return true
 	}
+	if n.SrcRType != nil && do(n.SrcRType) {
+		return true
+	}
 	if n.RType != nil && do(n.RType) {
 		return true
 	}
@@ -471,6 +618,24 @@
 	if n.X != nil {
 		n.X = edit(n.X).(Node)
 	}
+	if n.SrcRType != nil {
+		n.SrcRType = edit(n.SrcRType).(Node)
+	}
+	if n.RType != nil {
+		n.RType = edit(n.RType).(Node)
+	}
+	if n.ITab != nil {
+		n.ITab = edit(n.ITab).(Node)
+	}
+}
+func (n *DynamicTypeAssertExpr) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.X != nil {
+		n.X = edit(n.X).(Node)
+	}
+	if n.SrcRType != nil {
+		n.SrcRType = edit(n.SrcRType).(Node)
+	}
 	if n.RType != nil {
 		n.RType = edit(n.RType).(Node)
 	}
@@ -483,7 +648,6 @@
 func (n *ForStmt) copy() Node {
 	c := *n
 	c.init = copyNodes(c.init)
-	c.Late = copyNodes(c.Late)
 	c.Body = copyNodes(c.Body)
 	return &c
 }
@@ -494,9 +658,6 @@
 	if n.Cond != nil && do(n.Cond) {
 		return true
 	}
-	if doNodes(n.Late, do) {
-		return true
-	}
 	if n.Post != nil && do(n.Post) {
 		return true
 	}
@@ -510,7 +671,16 @@
 	if n.Cond != nil {
 		n.Cond = edit(n.Cond).(Node)
 	}
-	editNodes(n.Late, edit)
+	if n.Post != nil {
+		n.Post = edit(n.Post).(Node)
+	}
+	editNodes(n.Body, edit)
+}
+func (n *ForStmt) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.Cond != nil {
+		n.Cond = edit(n.Cond).(Node)
+	}
 	if n.Post != nil {
 		n.Post = edit(n.Post).(Node)
 	}
@@ -540,6 +710,12 @@
 		n.Call = edit(n.Call).(Node)
 	}
 }
+func (n *GoDeferStmt) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.Call != nil {
+		n.Call = edit(n.Call).(Node)
+	}
+}
 
 func (n *Ident) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *Ident) copy() Node {
@@ -556,6 +732,9 @@
 func (n *Ident) editChildren(edit func(Node) Node) {
 	editNodes(n.init, edit)
 }
+func (n *Ident) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+}
 
 func (n *IfStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *IfStmt) copy() Node {
@@ -588,6 +767,14 @@
 	editNodes(n.Body, edit)
 	editNodes(n.Else, edit)
 }
+func (n *IfStmt) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.Cond != nil {
+		n.Cond = edit(n.Cond).(Node)
+	}
+	editNodes(n.Body, edit)
+	editNodes(n.Else, edit)
+}
 
 func (n *IndexExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *IndexExpr) copy() Node {
@@ -616,6 +803,18 @@
 		n.Index = edit(n.Index).(Node)
 	}
 }
+func (n *IndexExpr) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.X != nil {
+		n.X = edit(n.X).(Node)
+	}
+	if n.Index != nil {
+		n.Index = edit(n.Index).(Node)
+	}
+	if n.RType != nil {
+		n.RType = edit(n.RType).(Node)
+	}
+}
 
 func (n *InlineMarkStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *InlineMarkStmt) copy() Node {
@@ -632,6 +831,9 @@
 func (n *InlineMarkStmt) editChildren(edit func(Node) Node) {
 	editNodes(n.init, edit)
 }
+func (n *InlineMarkStmt) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+}
 
 func (n *InlinedCallExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *InlinedCallExpr) copy() Node {
@@ -658,6 +860,11 @@
 	editNodes(n.Body, edit)
 	editNodes(n.ReturnVars, edit)
 }
+func (n *InlinedCallExpr) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	editNodes(n.Body, edit)
+	editNodes(n.ReturnVars, edit)
+}
 
 func (n *InstExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *InstExpr) copy() Node {
@@ -685,6 +892,13 @@
 	}
 	editNtypes(n.Targs, edit)
 }
+func (n *InstExpr) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.X != nil {
+		n.X = edit(n.X).(Node)
+	}
+	editNtypes(n.Targs, edit)
+}
 
 func (n *JumpTableStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *JumpTableStmt) copy() Node {
@@ -707,6 +921,12 @@
 		n.Idx = edit(n.Idx).(Node)
 	}
 }
+func (n *JumpTableStmt) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.Idx != nil {
+		n.Idx = edit(n.Idx).(Node)
+	}
+}
 
 func (n *KeyExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *KeyExpr) copy() Node {
@@ -735,6 +955,15 @@
 		n.Value = edit(n.Value).(Node)
 	}
 }
+func (n *KeyExpr) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.Key != nil {
+		n.Key = edit(n.Key).(Node)
+	}
+	if n.Value != nil {
+		n.Value = edit(n.Value).(Node)
+	}
+}
 
 func (n *LabelStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *LabelStmt) copy() Node {
@@ -751,6 +980,9 @@
 func (n *LabelStmt) editChildren(edit func(Node) Node) {
 	editNodes(n.init, edit)
 }
+func (n *LabelStmt) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+}
 
 func (n *LinksymOffsetExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *LinksymOffsetExpr) copy() Node {
@@ -767,6 +999,9 @@
 func (n *LinksymOffsetExpr) editChildren(edit func(Node) Node) {
 	editNodes(n.init, edit)
 }
+func (n *LinksymOffsetExpr) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+}
 
 func (n *LogicalExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *LogicalExpr) copy() Node {
@@ -795,6 +1030,15 @@
 		n.Y = edit(n.Y).(Node)
 	}
 }
+func (n *LogicalExpr) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.X != nil {
+		n.X = edit(n.X).(Node)
+	}
+	if n.Y != nil {
+		n.Y = edit(n.Y).(Node)
+	}
+}
 
 func (n *MakeExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *MakeExpr) copy() Node {
@@ -823,6 +1067,18 @@
 		n.Cap = edit(n.Cap).(Node)
 	}
 }
+func (n *MakeExpr) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.RType != nil {
+		n.RType = edit(n.RType).(Node)
+	}
+	if n.Len != nil {
+		n.Len = edit(n.Len).(Node)
+	}
+	if n.Cap != nil {
+		n.Cap = edit(n.Cap).(Node)
+	}
+}
 
 func (n *Name) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 
@@ -841,6 +1097,9 @@
 func (n *NilExpr) editChildren(edit func(Node) Node) {
 	editNodes(n.init, edit)
 }
+func (n *NilExpr) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+}
 
 func (n *ParenExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *ParenExpr) copy() Node {
@@ -863,6 +1122,12 @@
 		n.X = edit(n.X).(Node)
 	}
 }
+func (n *ParenExpr) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.X != nil {
+		n.X = edit(n.X).(Node)
+	}
+}
 
 func (n *RangeStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *RangeStmt) copy() Node {
@@ -908,6 +1173,37 @@
 		n.Prealloc = edit(n.Prealloc).(*Name)
 	}
 }
+func (n *RangeStmt) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.X != nil {
+		n.X = edit(n.X).(Node)
+	}
+	if n.RType != nil {
+		n.RType = edit(n.RType).(Node)
+	}
+	if n.Key != nil {
+		n.Key = edit(n.Key).(Node)
+	}
+	if n.Value != nil {
+		n.Value = edit(n.Value).(Node)
+	}
+	editNodes(n.Body, edit)
+	if n.Prealloc != nil {
+		n.Prealloc = edit(n.Prealloc).(*Name)
+	}
+	if n.KeyTypeWord != nil {
+		n.KeyTypeWord = edit(n.KeyTypeWord).(Node)
+	}
+	if n.KeySrcRType != nil {
+		n.KeySrcRType = edit(n.KeySrcRType).(Node)
+	}
+	if n.ValueTypeWord != nil {
+		n.ValueTypeWord = edit(n.ValueTypeWord).(Node)
+	}
+	if n.ValueSrcRType != nil {
+		n.ValueSrcRType = edit(n.ValueSrcRType).(Node)
+	}
+}
 
 func (n *RawOrigExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *RawOrigExpr) copy() Node {
@@ -924,6 +1220,9 @@
 func (n *RawOrigExpr) editChildren(edit func(Node) Node) {
 	editNodes(n.init, edit)
 }
+func (n *RawOrigExpr) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+}
 
 func (n *ResultExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *ResultExpr) copy() Node {
@@ -940,6 +1239,9 @@
 func (n *ResultExpr) editChildren(edit func(Node) Node) {
 	editNodes(n.init, edit)
 }
+func (n *ResultExpr) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+}
 
 func (n *ReturnStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *ReturnStmt) copy() Node {
@@ -961,6 +1263,10 @@
 	editNodes(n.init, edit)
 	editNodes(n.Results, edit)
 }
+func (n *ReturnStmt) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	editNodes(n.Results, edit)
+}
 
 func (n *SelectStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *SelectStmt) copy() Node {
@@ -987,6 +1293,11 @@
 	editCommClauses(n.Cases, edit)
 	editNodes(n.Compiled, edit)
 }
+func (n *SelectStmt) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	editCommClauses(n.Cases, edit)
+	editNodes(n.Compiled, edit)
+}
 
 func (n *SelectorExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *SelectorExpr) copy() Node {
@@ -1015,6 +1326,15 @@
 		n.Prealloc = edit(n.Prealloc).(*Name)
 	}
 }
+func (n *SelectorExpr) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.X != nil {
+		n.X = edit(n.X).(Node)
+	}
+	if n.Prealloc != nil {
+		n.Prealloc = edit(n.Prealloc).(*Name)
+	}
+}
 
 func (n *SendStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *SendStmt) copy() Node {
@@ -1043,6 +1363,15 @@
 		n.Value = edit(n.Value).(Node)
 	}
 }
+func (n *SendStmt) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.Chan != nil {
+		n.Chan = edit(n.Chan).(Node)
+	}
+	if n.Value != nil {
+		n.Value = edit(n.Value).(Node)
+	}
+}
 
 func (n *SliceExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *SliceExpr) copy() Node {
@@ -1083,6 +1412,21 @@
 		n.Max = edit(n.Max).(Node)
 	}
 }
+func (n *SliceExpr) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.X != nil {
+		n.X = edit(n.X).(Node)
+	}
+	if n.Low != nil {
+		n.Low = edit(n.Low).(Node)
+	}
+	if n.High != nil {
+		n.High = edit(n.High).(Node)
+	}
+	if n.Max != nil {
+		n.Max = edit(n.Max).(Node)
+	}
+}
 
 func (n *SliceHeaderExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *SliceHeaderExpr) copy() Node {
@@ -1117,6 +1461,18 @@
 		n.Cap = edit(n.Cap).(Node)
 	}
 }
+func (n *SliceHeaderExpr) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.Ptr != nil {
+		n.Ptr = edit(n.Ptr).(Node)
+	}
+	if n.Len != nil {
+		n.Len = edit(n.Len).(Node)
+	}
+	if n.Cap != nil {
+		n.Cap = edit(n.Cap).(Node)
+	}
+}
 
 func (n *StarExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *StarExpr) copy() Node {
@@ -1139,6 +1495,49 @@
 		n.X = edit(n.X).(Node)
 	}
 }
+func (n *StarExpr) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.X != nil {
+		n.X = edit(n.X).(Node)
+	}
+}
+
+func (n *StringHeaderExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
+func (n *StringHeaderExpr) copy() Node {
+	c := *n
+	c.init = copyNodes(c.init)
+	return &c
+}
+func (n *StringHeaderExpr) doChildren(do func(Node) bool) bool {
+	if doNodes(n.init, do) {
+		return true
+	}
+	if n.Ptr != nil && do(n.Ptr) {
+		return true
+	}
+	if n.Len != nil && do(n.Len) {
+		return true
+	}
+	return false
+}
+func (n *StringHeaderExpr) editChildren(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.Ptr != nil {
+		n.Ptr = edit(n.Ptr).(Node)
+	}
+	if n.Len != nil {
+		n.Len = edit(n.Len).(Node)
+	}
+}
+func (n *StringHeaderExpr) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.Ptr != nil {
+		n.Ptr = edit(n.Ptr).(Node)
+	}
+	if n.Len != nil {
+		n.Len = edit(n.Len).(Node)
+	}
+}
 
 func (n *StructKeyExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *StructKeyExpr) copy() Node {
@@ -1161,6 +1560,12 @@
 		n.Value = edit(n.Value).(Node)
 	}
 }
+func (n *StructKeyExpr) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.Value != nil {
+		n.Value = edit(n.Value).(Node)
+	}
+}
 
 func (n *SwitchStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *SwitchStmt) copy() Node {
@@ -1193,6 +1598,14 @@
 	editCaseClauses(n.Cases, edit)
 	editNodes(n.Compiled, edit)
 }
+func (n *SwitchStmt) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.Tag != nil {
+		n.Tag = edit(n.Tag).(Node)
+	}
+	editCaseClauses(n.Cases, edit)
+	editNodes(n.Compiled, edit)
+}
 
 func (n *TailCallStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *TailCallStmt) copy() Node {
@@ -1215,6 +1628,12 @@
 		n.Call = edit(n.Call).(*CallExpr)
 	}
 }
+func (n *TailCallStmt) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.Call != nil {
+		n.Call = edit(n.Call).(*CallExpr)
+	}
+}
 
 func (n *TypeAssertExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *TypeAssertExpr) copy() Node {
@@ -1237,6 +1656,15 @@
 		n.X = edit(n.X).(Node)
 	}
 }
+func (n *TypeAssertExpr) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.X != nil {
+		n.X = edit(n.X).(Node)
+	}
+	if n.ITab != nil {
+		n.ITab = edit(n.ITab).(Node)
+	}
+}
 
 func (n *TypeSwitchGuard) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *TypeSwitchGuard) copy() Node {
@@ -1260,6 +1688,14 @@
 		n.X = edit(n.X).(Node)
 	}
 }
+func (n *TypeSwitchGuard) editChildrenWithHidden(edit func(Node) Node) {
+	if n.Tag != nil {
+		n.Tag = edit(n.Tag).(*Ident)
+	}
+	if n.X != nil {
+		n.X = edit(n.X).(Node)
+	}
+}
 
 func (n *UnaryExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *UnaryExpr) copy() Node {
@@ -1282,6 +1718,12 @@
 		n.X = edit(n.X).(Node)
 	}
 }
+func (n *UnaryExpr) editChildrenWithHidden(edit func(Node) Node) {
+	editNodes(n.init, edit)
+	if n.X != nil {
+		n.X = edit(n.X).(Node)
+	}
+}
 
 func (n *typeNode) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }
 func (n *typeNode) copy() Node {
@@ -1293,6 +1735,8 @@
 }
 func (n *typeNode) editChildren(edit func(Node) Node) {
 }
+func (n *typeNode) editChildrenWithHidden(edit func(Node) Node) {
+}
 
 func copyCaseClauses(list []*CaseClause) []*CaseClause {
 	if list == nil {
diff --git a/src/cmd/compile/internal/ir/op_string.go b/src/cmd/compile/internal/ir/op_string.go
index 5d475a7..d84a08e 100644
--- a/src/cmd/compile/internal/ir/op_string.go
+++ b/src/cmd/compile/internal/ir/op_string.go
@@ -28,145 +28,146 @@
 	_ = x[OSTR2BYTES-17]
 	_ = x[OSTR2BYTESTMP-18]
 	_ = x[OSTR2RUNES-19]
-	_ = x[OSLICE2ARRPTR-20]
-	_ = x[OAS-21]
-	_ = x[OAS2-22]
-	_ = x[OAS2DOTTYPE-23]
-	_ = x[OAS2FUNC-24]
-	_ = x[OAS2MAPR-25]
-	_ = x[OAS2RECV-26]
-	_ = x[OASOP-27]
-	_ = x[OCALL-28]
-	_ = x[OCALLFUNC-29]
-	_ = x[OCALLMETH-30]
-	_ = x[OCALLINTER-31]
-	_ = x[OCAP-32]
-	_ = x[OCLOSE-33]
-	_ = x[OCLOSURE-34]
-	_ = x[OCOMPLIT-35]
-	_ = x[OMAPLIT-36]
-	_ = x[OSTRUCTLIT-37]
-	_ = x[OARRAYLIT-38]
-	_ = x[OSLICELIT-39]
-	_ = x[OPTRLIT-40]
-	_ = x[OCONV-41]
-	_ = x[OCONVIFACE-42]
-	_ = x[OCONVIDATA-43]
-	_ = x[OCONVNOP-44]
-	_ = x[OCOPY-45]
-	_ = x[ODCL-46]
-	_ = x[ODCLFUNC-47]
-	_ = x[ODCLCONST-48]
-	_ = x[ODCLTYPE-49]
-	_ = x[ODELETE-50]
-	_ = x[ODOT-51]
-	_ = x[ODOTPTR-52]
-	_ = x[ODOTMETH-53]
-	_ = x[ODOTINTER-54]
-	_ = x[OXDOT-55]
-	_ = x[ODOTTYPE-56]
-	_ = x[ODOTTYPE2-57]
-	_ = x[OEQ-58]
-	_ = x[ONE-59]
-	_ = x[OLT-60]
-	_ = x[OLE-61]
-	_ = x[OGE-62]
-	_ = x[OGT-63]
-	_ = x[ODEREF-64]
-	_ = x[OINDEX-65]
-	_ = x[OINDEXMAP-66]
-	_ = x[OKEY-67]
-	_ = x[OSTRUCTKEY-68]
-	_ = x[OLEN-69]
-	_ = x[OMAKE-70]
-	_ = x[OMAKECHAN-71]
-	_ = x[OMAKEMAP-72]
-	_ = x[OMAKESLICE-73]
-	_ = x[OMAKESLICECOPY-74]
-	_ = x[OMUL-75]
-	_ = x[ODIV-76]
-	_ = x[OMOD-77]
-	_ = x[OLSH-78]
-	_ = x[ORSH-79]
-	_ = x[OAND-80]
-	_ = x[OANDNOT-81]
-	_ = x[ONEW-82]
-	_ = x[ONOT-83]
-	_ = x[OBITNOT-84]
-	_ = x[OPLUS-85]
-	_ = x[ONEG-86]
-	_ = x[OOROR-87]
-	_ = x[OPANIC-88]
-	_ = x[OPRINT-89]
-	_ = x[OPRINTN-90]
-	_ = x[OPAREN-91]
-	_ = x[OSEND-92]
-	_ = x[OSLICE-93]
-	_ = x[OSLICEARR-94]
-	_ = x[OSLICESTR-95]
-	_ = x[OSLICE3-96]
-	_ = x[OSLICE3ARR-97]
-	_ = x[OSLICEHEADER-98]
-	_ = x[ORECOVER-99]
-	_ = x[ORECOVERFP-100]
-	_ = x[ORECV-101]
-	_ = x[ORUNESTR-102]
-	_ = x[OSELRECV2-103]
-	_ = x[OREAL-104]
-	_ = x[OIMAG-105]
-	_ = x[OCOMPLEX-106]
-	_ = x[OALIGNOF-107]
-	_ = x[OOFFSETOF-108]
-	_ = x[OSIZEOF-109]
-	_ = x[OUNSAFEADD-110]
-	_ = x[OUNSAFESLICE-111]
-	_ = x[OMETHEXPR-112]
-	_ = x[OMETHVALUE-113]
-	_ = x[OBLOCK-114]
-	_ = x[OBREAK-115]
-	_ = x[OCASE-116]
-	_ = x[OCONTINUE-117]
-	_ = x[ODEFER-118]
-	_ = x[OFALL-119]
-	_ = x[OFOR-120]
-	_ = x[OFORUNTIL-121]
-	_ = x[OGOTO-122]
-	_ = x[OIF-123]
-	_ = x[OLABEL-124]
-	_ = x[OGO-125]
-	_ = x[ORANGE-126]
-	_ = x[ORETURN-127]
-	_ = x[OSELECT-128]
-	_ = x[OSWITCH-129]
-	_ = x[OTYPESW-130]
-	_ = x[OFUNCINST-131]
-	_ = x[OINLCALL-132]
-	_ = x[OEFACE-133]
-	_ = x[OITAB-134]
-	_ = x[OIDATA-135]
-	_ = x[OSPTR-136]
-	_ = x[OCFUNC-137]
-	_ = x[OCHECKNIL-138]
-	_ = x[OVARDEF-139]
-	_ = x[OVARKILL-140]
-	_ = x[OVARLIVE-141]
-	_ = x[ORESULT-142]
-	_ = x[OINLMARK-143]
-	_ = x[OLINKSYMOFFSET-144]
-	_ = x[OJUMPTABLE-145]
-	_ = x[ODYNAMICDOTTYPE-146]
-	_ = x[ODYNAMICDOTTYPE2-147]
-	_ = x[ODYNAMICTYPE-148]
-	_ = x[OTAILCALL-149]
-	_ = x[OGETG-150]
-	_ = x[OGETCALLERPC-151]
-	_ = x[OGETCALLERSP-152]
-	_ = x[OEND-153]
+	_ = x[OSLICE2ARR-20]
+	_ = x[OSLICE2ARRPTR-21]
+	_ = x[OAS-22]
+	_ = x[OAS2-23]
+	_ = x[OAS2DOTTYPE-24]
+	_ = x[OAS2FUNC-25]
+	_ = x[OAS2MAPR-26]
+	_ = x[OAS2RECV-27]
+	_ = x[OASOP-28]
+	_ = x[OCALL-29]
+	_ = x[OCALLFUNC-30]
+	_ = x[OCALLMETH-31]
+	_ = x[OCALLINTER-32]
+	_ = x[OCAP-33]
+	_ = x[OCLOSE-34]
+	_ = x[OCLOSURE-35]
+	_ = x[OCOMPLIT-36]
+	_ = x[OMAPLIT-37]
+	_ = x[OSTRUCTLIT-38]
+	_ = x[OARRAYLIT-39]
+	_ = x[OSLICELIT-40]
+	_ = x[OPTRLIT-41]
+	_ = x[OCONV-42]
+	_ = x[OCONVIFACE-43]
+	_ = x[OCONVIDATA-44]
+	_ = x[OCONVNOP-45]
+	_ = x[OCOPY-46]
+	_ = x[ODCL-47]
+	_ = x[ODCLFUNC-48]
+	_ = x[ODCLCONST-49]
+	_ = x[ODCLTYPE-50]
+	_ = x[ODELETE-51]
+	_ = x[ODOT-52]
+	_ = x[ODOTPTR-53]
+	_ = x[ODOTMETH-54]
+	_ = x[ODOTINTER-55]
+	_ = x[OXDOT-56]
+	_ = x[ODOTTYPE-57]
+	_ = x[ODOTTYPE2-58]
+	_ = x[OEQ-59]
+	_ = x[ONE-60]
+	_ = x[OLT-61]
+	_ = x[OLE-62]
+	_ = x[OGE-63]
+	_ = x[OGT-64]
+	_ = x[ODEREF-65]
+	_ = x[OINDEX-66]
+	_ = x[OINDEXMAP-67]
+	_ = x[OKEY-68]
+	_ = x[OSTRUCTKEY-69]
+	_ = x[OLEN-70]
+	_ = x[OMAKE-71]
+	_ = x[OMAKECHAN-72]
+	_ = x[OMAKEMAP-73]
+	_ = x[OMAKESLICE-74]
+	_ = x[OMAKESLICECOPY-75]
+	_ = x[OMUL-76]
+	_ = x[ODIV-77]
+	_ = x[OMOD-78]
+	_ = x[OLSH-79]
+	_ = x[ORSH-80]
+	_ = x[OAND-81]
+	_ = x[OANDNOT-82]
+	_ = x[ONEW-83]
+	_ = x[ONOT-84]
+	_ = x[OBITNOT-85]
+	_ = x[OPLUS-86]
+	_ = x[ONEG-87]
+	_ = x[OOROR-88]
+	_ = x[OPANIC-89]
+	_ = x[OPRINT-90]
+	_ = x[OPRINTN-91]
+	_ = x[OPAREN-92]
+	_ = x[OSEND-93]
+	_ = x[OSLICE-94]
+	_ = x[OSLICEARR-95]
+	_ = x[OSLICESTR-96]
+	_ = x[OSLICE3-97]
+	_ = x[OSLICE3ARR-98]
+	_ = x[OSLICEHEADER-99]
+	_ = x[OSTRINGHEADER-100]
+	_ = x[ORECOVER-101]
+	_ = x[ORECOVERFP-102]
+	_ = x[ORECV-103]
+	_ = x[ORUNESTR-104]
+	_ = x[OSELRECV2-105]
+	_ = x[OREAL-106]
+	_ = x[OIMAG-107]
+	_ = x[OCOMPLEX-108]
+	_ = x[OALIGNOF-109]
+	_ = x[OOFFSETOF-110]
+	_ = x[OSIZEOF-111]
+	_ = x[OUNSAFEADD-112]
+	_ = x[OUNSAFESLICE-113]
+	_ = x[OUNSAFESLICEDATA-114]
+	_ = x[OUNSAFESTRING-115]
+	_ = x[OUNSAFESTRINGDATA-116]
+	_ = x[OMETHEXPR-117]
+	_ = x[OMETHVALUE-118]
+	_ = x[OBLOCK-119]
+	_ = x[OBREAK-120]
+	_ = x[OCASE-121]
+	_ = x[OCONTINUE-122]
+	_ = x[ODEFER-123]
+	_ = x[OFALL-124]
+	_ = x[OFOR-125]
+	_ = x[OGOTO-126]
+	_ = x[OIF-127]
+	_ = x[OLABEL-128]
+	_ = x[OGO-129]
+	_ = x[ORANGE-130]
+	_ = x[ORETURN-131]
+	_ = x[OSELECT-132]
+	_ = x[OSWITCH-133]
+	_ = x[OTYPESW-134]
+	_ = x[OFUNCINST-135]
+	_ = x[OINLCALL-136]
+	_ = x[OEFACE-137]
+	_ = x[OITAB-138]
+	_ = x[OIDATA-139]
+	_ = x[OSPTR-140]
+	_ = x[OCFUNC-141]
+	_ = x[OCHECKNIL-142]
+	_ = x[ORESULT-143]
+	_ = x[OINLMARK-144]
+	_ = x[OLINKSYMOFFSET-145]
+	_ = x[OJUMPTABLE-146]
+	_ = x[ODYNAMICDOTTYPE-147]
+	_ = x[ODYNAMICDOTTYPE2-148]
+	_ = x[ODYNAMICTYPE-149]
+	_ = x[OTAILCALL-150]
+	_ = x[OGETG-151]
+	_ = x[OGETCALLERPC-152]
+	_ = x[OGETCALLERSP-153]
+	_ = x[OEND-154]
 }
 
-const _Op_name = "XXXNAMENONAMETYPELITERALNILADDSUBORXORADDSTRADDRANDANDAPPENDBYTES2STRBYTES2STRTMPRUNES2STRSTR2BYTESSTR2BYTESTMPSTR2RUNESSLICE2ARRPTRASAS2AS2DOTTYPEAS2FUNCAS2MAPRAS2RECVASOPCALLCALLFUNCCALLMETHCALLINTERCAPCLOSECLOSURECOMPLITMAPLITSTRUCTLITARRAYLITSLICELITPTRLITCONVCONVIFACECONVIDATACONVNOPCOPYDCLDCLFUNCDCLCONSTDCLTYPEDELETEDOTDOTPTRDOTMETHDOTINTERXDOTDOTTYPEDOTTYPE2EQNELTLEGEGTDEREFINDEXINDEXMAPKEYSTRUCTKEYLENMAKEMAKECHANMAKEMAPMAKESLICEMAKESLICECOPYMULDIVMODLSHRSHANDANDNOTNEWNOTBITNOTPLUSNEGORORPANICPRINTPRINTNPARENSENDSLICESLICEARRSLICESTRSLICE3SLICE3ARRSLICEHEADERRECOVERRECOVERFPRECVRUNESTRSELRECV2REALIMAGCOMPLEXALIGNOFOFFSETOFSIZEOFUNSAFEADDUNSAFESLICEMETHEXPRMETHVALUEBLOCKBREAKCASECONTINUEDEFERFALLFORFORUNTILGOTOIFLABELGORANGERETURNSELECTSWITCHTYPESWFUNCINSTINLCALLEFACEITABIDATASPTRCFUNCCHECKNILVARDEFVARKILLVARLIVERESULTINLMARKLINKSYMOFFSETJUMPTABLEDYNAMICDOTTYPEDYNAMICDOTTYPE2DYNAMICTYPETAILCALLGETGGETCALLERPCGETCALLERSPEND"
+const _Op_name = "XXXNAMENONAMETYPELITERALNILADDSUBORXORADDSTRADDRANDANDAPPENDBYTES2STRBYTES2STRTMPRUNES2STRSTR2BYTESSTR2BYTESTMPSTR2RUNESSLICE2ARRSLICE2ARRPTRASAS2AS2DOTTYPEAS2FUNCAS2MAPRAS2RECVASOPCALLCALLFUNCCALLMETHCALLINTERCAPCLOSECLOSURECOMPLITMAPLITSTRUCTLITARRAYLITSLICELITPTRLITCONVCONVIFACECONVIDATACONVNOPCOPYDCLDCLFUNCDCLCONSTDCLTYPEDELETEDOTDOTPTRDOTMETHDOTINTERXDOTDOTTYPEDOTTYPE2EQNELTLEGEGTDEREFINDEXINDEXMAPKEYSTRUCTKEYLENMAKEMAKECHANMAKEMAPMAKESLICEMAKESLICECOPYMULDIVMODLSHRSHANDANDNOTNEWNOTBITNOTPLUSNEGORORPANICPRINTPRINTNPARENSENDSLICESLICEARRSLICESTRSLICE3SLICE3ARRSLICEHEADERSTRINGHEADERRECOVERRECOVERFPRECVRUNESTRSELRECV2REALIMAGCOMPLEXALIGNOFOFFSETOFSIZEOFUNSAFEADDUNSAFESLICEUNSAFESLICEDATAUNSAFESTRINGUNSAFESTRINGDATAMETHEXPRMETHVALUEBLOCKBREAKCASECONTINUEDEFERFALLFORGOTOIFLABELGORANGERETURNSELECTSWITCHTYPESWFUNCINSTINLCALLEFACEITABIDATASPTRCFUNCCHECKNILRESULTINLMARKLINKSYMOFFSETJUMPTABLEDYNAMICDOTTYPEDYNAMICDOTTYPE2DYNAMICTYPETAILCALLGETGGETCALLERPCGETCALLERSPEND"
 
-var _Op_index = [...]uint16{0, 3, 7, 13, 17, 24, 27, 30, 33, 35, 38, 44, 48, 54, 60, 69, 81, 90, 99, 111, 120, 132, 134, 137, 147, 154, 161, 168, 172, 176, 184, 192, 201, 204, 209, 216, 223, 229, 238, 246, 254, 260, 264, 273, 282, 289, 293, 296, 303, 311, 318, 324, 327, 333, 340, 348, 352, 359, 367, 369, 371, 373, 375, 377, 379, 384, 389, 397, 400, 409, 412, 416, 424, 431, 440, 453, 456, 459, 462, 465, 468, 471, 477, 480, 483, 489, 493, 496, 500, 505, 510, 516, 521, 525, 530, 538, 546, 552, 561, 572, 579, 588, 592, 599, 607, 611, 615, 622, 629, 637, 643, 652, 663, 671, 680, 685, 690, 694, 702, 707, 711, 714, 722, 726, 728, 733, 735, 740, 746, 752, 758, 764, 772, 779, 784, 788, 793, 797, 802, 810, 816, 823, 830, 836, 843, 856, 865, 879, 894, 905, 913, 917, 928, 939, 942}
+var _Op_index = [...]uint16{0, 3, 7, 13, 17, 24, 27, 30, 33, 35, 38, 44, 48, 54, 60, 69, 81, 90, 99, 111, 120, 129, 141, 143, 146, 156, 163, 170, 177, 181, 185, 193, 201, 210, 213, 218, 225, 232, 238, 247, 255, 263, 269, 273, 282, 291, 298, 302, 305, 312, 320, 327, 333, 336, 342, 349, 357, 361, 368, 376, 378, 380, 382, 384, 386, 388, 393, 398, 406, 409, 418, 421, 425, 433, 440, 449, 462, 465, 468, 471, 474, 477, 480, 486, 489, 492, 498, 502, 505, 509, 514, 519, 525, 530, 534, 539, 547, 555, 561, 570, 581, 593, 600, 609, 613, 620, 628, 632, 636, 643, 650, 658, 664, 673, 684, 699, 711, 727, 735, 744, 749, 754, 758, 766, 771, 775, 778, 782, 784, 789, 791, 796, 802, 808, 814, 820, 828, 835, 840, 844, 849, 853, 858, 866, 872, 879, 892, 901, 915, 930, 941, 949, 953, 964, 975, 978}
 
 func (i Op) String() string {
 	if i >= Op(len(_Op_index)-1) {
diff --git a/src/cmd/compile/internal/ir/scc.go b/src/cmd/compile/internal/ir/scc.go
index a42951c..b222939 100644
--- a/src/cmd/compile/internal/ir/scc.go
+++ b/src/cmd/compile/internal/ir/scc.go
@@ -103,16 +103,13 @@
 	if (min == id || min == id+1) && !n.IsHiddenClosure() {
 		// This node is the root of a strongly connected component.
 
-		// The original min passed to visitcodelist was v.nodeID[n]+1.
-		// If visitcodelist found its way back to v.nodeID[n], then this
-		// block is a set of mutually recursive functions.
-		// Otherwise it's just a lone function that does not recurse.
+		// The original min was id+1. If the bottomUpVisitor found its way
+		// back to id, then this block is a set of mutually recursive functions.
+		// Otherwise, it's just a lone function that does not recurse.
 		recursive := min == id
 
-		// Remove connected component from stack.
-		// Mark walkgen so that future visits return a large number
-		// so as not to affect the caller's min.
-
+		// Remove connected component from stack and mark v.nodeID so that future
+		// visits return a large number, which will not affect the caller's min.
 		var i int
 		for i = len(v.stack) - 1; i >= 0; i-- {
 			x := v.stack[i]
@@ -122,7 +119,7 @@
 			}
 		}
 		block := v.stack[i:]
-		// Run escape analysis on this set of functions.
+		// Call analyze on this set of functions.
 		v.stack = v.stack[:i]
 		v.analyze(block, recursive)
 	}
diff --git a/src/cmd/compile/internal/ir/stmt.go b/src/cmd/compile/internal/ir/stmt.go
index c46debc..9f2d04f 100644
--- a/src/cmd/compile/internal/ir/stmt.go
+++ b/src/cmd/compile/internal/ir/stmt.go
@@ -170,6 +170,17 @@
 	miniStmt
 	Var  *Name // declared variable for this case in type switch
 	List Nodes // list of expressions for switch, early select
+
+	// RTypes is a list of RType expressions, which are copied to the
+	// corresponding OEQ nodes that are emitted when switch statements
+	// are desugared. RTypes[i] must be non-nil if the emitted
+	// comparison for List[i] will be a mixed interface/concrete
+	// comparison; see reflectdata.CompareRType for details.
+	//
+	// Because mixed interface/concrete switch cases are rare, we allow
+	// len(RTypes) < len(List). Missing entries are implicitly nil.
+	RTypes Nodes
+
 	Body Nodes
 }
 
@@ -194,12 +205,10 @@
 }
 
 // A ForStmt is a non-range for loop: for Init; Cond; Post { Body }
-// Op can be OFOR or OFORUNTIL (!Cond).
 type ForStmt struct {
 	miniStmt
 	Label    *types.Sym
 	Cond     Node
-	Late     Nodes
 	Post     Node
 	Body     Nodes
 	HasBreak bool
@@ -216,13 +225,6 @@
 	return n
 }
 
-func (n *ForStmt) SetOp(op Op) {
-	if op != OFOR && op != OFORUNTIL {
-		panic(n.no("SetOp " + op.String()))
-	}
-	n.op = op
-}
-
 // A GoDeferStmt is a go or defer statement: go Call / defer Call.
 //
 // The two opcodes use a single syntax because the implementations
@@ -333,11 +335,20 @@
 	Label    *types.Sym
 	Def      bool
 	X        Node
+	RType    Node `mknode:"-"` // see reflectdata/helpers.go
 	Key      Node
 	Value    Node
 	Body     Nodes
 	HasBreak bool
 	Prealloc *Name
+
+	// When desugaring the RangeStmt during walk, the assignments to Key
+	// and Value may require OCONVIFACE operations. If so, these fields
+	// will be copied to their respective ConvExpr fields.
+	KeyTypeWord   Node `mknode:"-"`
+	KeySrcRType   Node `mknode:"-"`
+	ValueTypeWord Node `mknode:"-"`
+	ValueSrcRType Node `mknode:"-"`
 }
 
 func NewRangeStmt(pos src.XPos, key, value, x Node, body []Node) *RangeStmt {
diff --git a/src/cmd/compile/internal/ir/symtab.go b/src/cmd/compile/internal/ir/symtab.go
index b204a1d..bde7a4c 100644
--- a/src/cmd/compile/internal/ir/symtab.go
+++ b/src/cmd/compile/internal/ir/symtab.go
@@ -26,6 +26,7 @@
 	GCWriteBarrier    *obj.LSym
 	Goschedguarded    *obj.LSym
 	Growslice         *obj.LSym
+	Memmove           *obj.LSym
 	Msanread          *obj.LSym
 	Msanwrite         *obj.LSym
 	Msanmove          *obj.LSym
@@ -57,10 +58,6 @@
 	// Wasm
 	WasmDiv *obj.LSym
 	// Wasm
-	WasmMove *obj.LSym
-	// Wasm
-	WasmZero *obj.LSym
-	// Wasm
 	WasmTruncS *obj.LSym
 	// Wasm
 	WasmTruncU *obj.LSym
@@ -68,7 +65,8 @@
 
 // Pkgs holds known packages.
 var Pkgs struct {
-	Go      *types.Pkg
-	Itab    *types.Pkg
-	Runtime *types.Pkg
+	Go       *types.Pkg
+	Itab     *types.Pkg
+	Runtime  *types.Pkg
+	Coverage *types.Pkg
 }
diff --git a/src/cmd/compile/internal/ir/visit.go b/src/cmd/compile/internal/ir/visit.go
index e4aeae3..0164670 100644
--- a/src/cmd/compile/internal/ir/visit.go
+++ b/src/cmd/compile/internal/ir/visit.go
@@ -184,3 +184,15 @@
 	}
 	n.editChildren(edit)
 }
+
+// EditChildrenWithHidden is like EditChildren, but also edits
+// Node-typed fields tagged with `mknode:"-"`.
+//
+// TODO(mdempsky): Remove the `mknode:"-"` tags so this function can
+// go away.
+func EditChildrenWithHidden(n Node, edit func(Node) Node) {
+	if n == nil {
+		return
+	}
+	n.editChildrenWithHidden(edit)
+}
diff --git a/src/cmd/compile/internal/liveness/arg.go b/src/cmd/compile/internal/liveness/arg.go
index 2ca5d09..abbc8c9 100644
--- a/src/cmd/compile/internal/liveness/arg.go
+++ b/src/cmd/compile/internal/liveness/arg.go
@@ -249,7 +249,7 @@
 func mayFault(v *ssa.Value) bool {
 	switch v.Op {
 	case ssa.OpLoadReg, ssa.OpStoreReg, ssa.OpCopy, ssa.OpPhi,
-		ssa.OpVarDef, ssa.OpVarKill, ssa.OpVarLive, ssa.OpKeepAlive,
+		ssa.OpVarDef, ssa.OpVarLive, ssa.OpKeepAlive,
 		ssa.OpSelect0, ssa.OpSelect1, ssa.OpSelectN, ssa.OpMakeResult,
 		ssa.OpConvert, ssa.OpInlMark, ssa.OpGetG:
 		return false
diff --git a/src/cmd/compile/internal/liveness/plive.go b/src/cmd/compile/internal/liveness/plive.go
index 93f49fa..689b528 100644
--- a/src/cmd/compile/internal/liveness/plive.go
+++ b/src/cmd/compile/internal/liveness/plive.go
@@ -80,15 +80,6 @@
 // the liveness analysis work on single-word values as well, although
 // there are complications around interface values, slices, and strings,
 // all of which cannot be treated as individual words.
-//
-// OpVarKill is the opposite of OpVarDef: it marks a value as no longer needed,
-// even if its address has been taken. That is, an OpVarKill annotation asserts
-// that its argument is certainly dead, for use when the liveness analysis
-// would not otherwise be able to deduce that fact.
-
-// TODO: get rid of OpVarKill here. It's useful for stack frame allocation
-// so the compiler can allocate two temps to the same location. Here it's now
-// useless, since the implementation of stack objects.
 
 // blockEffects summarizes the liveness effects on an SSA block.
 type blockEffects struct {
@@ -269,7 +260,7 @@
 	// OpVarFoo pseudo-ops. Ignore them to prevent "lost track of
 	// variable" ICEs (issue 19632).
 	switch v.Op {
-	case ssa.OpVarDef, ssa.OpVarKill, ssa.OpVarLive, ssa.OpKeepAlive:
+	case ssa.OpVarDef, ssa.OpVarLive, ssa.OpKeepAlive:
 		if !n.Used() {
 			return -1, 0
 		}
@@ -305,7 +296,7 @@
 	return -1, 0
 }
 
-// affectedVar returns the *ir.Name node affected by v
+// affectedVar returns the *ir.Name node affected by v.
 func affectedVar(v *ssa.Value) (*ir.Name, ssa.SymEffect) {
 	// Special cases.
 	switch v.Op {
@@ -334,7 +325,7 @@
 
 	case ssa.OpVarLive:
 		return v.Aux.(*ir.Name), ssa.SymRead
-	case ssa.OpVarDef, ssa.OpVarKill:
+	case ssa.OpVarDef:
 		return v.Aux.(*ir.Name), ssa.SymWrite
 	case ssa.OpKeepAlive:
 		n, _ := ssa.AutoVar(v.Args[0])
@@ -434,7 +425,7 @@
 				if node.FrameOffset() < 0 {
 					lv.f.Fatalf("Node %v has frameoffset %d\n", node.Sym().Name, node.FrameOffset())
 				}
-				typebits.Set(node.Type(), node.FrameOffset(), args)
+				typebits.SetNoCheck(node.Type(), node.FrameOffset(), args)
 				break
 			}
 			fallthrough // PPARAMOUT in registers acts memory-allocates like an AUTO
@@ -1507,7 +1498,7 @@
 	bv := bitvec.New(int32(nptr) * 2)
 
 	for _, p := range abiInfo.InParams() {
-		typebits.Set(p.Type, p.FrameOffset(abiInfo), bv)
+		typebits.SetNoCheck(p.Type, p.FrameOffset(abiInfo), bv)
 	}
 
 	nbitmap := 1
@@ -1522,7 +1513,7 @@
 	if fn.Type().NumResults() > 0 {
 		for _, p := range abiInfo.OutParams() {
 			if len(p.Registers) == 0 {
-				typebits.Set(p.Type, p.FrameOffset(abiInfo), bv)
+				typebits.SetNoCheck(p.Type, p.FrameOffset(abiInfo), bv)
 			}
 		}
 		off = objw.BitVec(lsym, off, bv)
diff --git a/src/cmd/compile/internal/logopt/escape.go b/src/cmd/compile/internal/logopt/escape.go
deleted file mode 100644
index 9660e93..0000000
--- a/src/cmd/compile/internal/logopt/escape.go
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build go1.8
-// +build go1.8
-
-package logopt
-
-import "net/url"
-
-func pathEscape(s string) string {
-	return url.PathEscape(s)
-}
diff --git a/src/cmd/compile/internal/logopt/escape_bootstrap.go b/src/cmd/compile/internal/logopt/escape_bootstrap.go
deleted file mode 100644
index cc04eaa..0000000
--- a/src/cmd/compile/internal/logopt/escape_bootstrap.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build !go1.8
-// +build !go1.8
-
-package logopt
-
-// For bootstrapping with an early version of Go
-func pathEscape(s string) string {
-	panic("This should never be called; the compiler is not fully bootstrapped if it is.")
-}
diff --git a/src/cmd/compile/internal/logopt/log_opts.go b/src/cmd/compile/internal/logopt/log_opts.go
index 9fee834..d0be4d8 100644
--- a/src/cmd/compile/internal/logopt/log_opts.go
+++ b/src/cmd/compile/internal/logopt/log_opts.go
@@ -270,7 +270,7 @@
 	return
 }
 
-// isWindowsDriveURI returns true if the file URI is of the format used by
+// isWindowsDriveURIPath returns true if the file URI is of the format used by
 // Windows URIs. The url.Parse package does not specially handle Windows paths
 // (see golang/go#6027), so we check if the URI path has a drive prefix (e.g. "/C:").
 // (copied from tools/internal/span/uri.go)
@@ -304,7 +304,7 @@
 
 // checkLogPath does superficial early checking of the string specifying
 // the directory to which optimizer logging is directed, and if
-// it passes the test, stores the string in LO_dir
+// it passes the test, stores the string in LO_dir.
 func checkLogPath(destination string) string {
 	path, complaint := parseLogPath(destination)
 	if complaint != "" {
@@ -329,9 +329,9 @@
 	return &LoggedOpt{pos, pass, funcName, what, args}
 }
 
-// Logopt logs information about a (usually missed) optimization performed by the compiler.
+// LogOpt logs information about a (usually missed) optimization performed by the compiler.
 // Pos is the source position (including inlining), what is the message, pass is which pass created the message,
-// funcName is the name of the function
+// funcName is the name of the function.
 func LogOpt(pos src.XPos, what, pass, funcName string, args ...interface{}) {
 	if Format == None {
 		return
@@ -376,7 +376,7 @@
 	if lastdot != -1 {
 		basename = basename[:lastdot]
 	}
-	basename = pathEscape(basename)
+	basename = url.PathEscape(basename)
 
 	// Assume a directory, make a file
 	p := filepath.Join(subdirpath, basename+".json")
@@ -405,6 +405,9 @@
 // Return filename, replacing a first occurrence of $GOROOT with the
 // actual value of the GOROOT (because LSP does not speak "$GOROOT").
 func uprootedPath(filename string) string {
+	if filename == "" {
+		return "__unnamed__"
+	}
 	if buildcfg.GOROOT == "" || !strings.HasPrefix(filename, "$GOROOT/") {
 		return filename
 	}
@@ -428,7 +431,7 @@
 		if slashPkgPath == "" {
 			slashPkgPath = "\000"
 		}
-		subdirpath := filepath.Join(dest, pathEscape(slashPkgPath))
+		subdirpath := filepath.Join(dest, url.PathEscape(slashPkgPath))
 		err := os.MkdirAll(subdirpath, 0755)
 		if err != nil {
 			log.Fatalf("Could not create directory %s for logging optimizer actions, %v", subdirpath, err)
@@ -496,13 +499,13 @@
 		End: Position{p.Line(), p.Col()}}
 }
 
-// newLocation returns the Location for the compiler source location p
+// newLocation returns the Location for the compiler source location p.
 func newLocation(p src.Pos) Location {
 	loc := Location{URI: uriIfy(uprootedPath(p.Filename())), Range: newPointRange(p)}
 	return loc
 }
 
-// appendInlinedPos extracts inlining information from posTmp and append it to diagnostic
+// appendInlinedPos extracts inlining information from posTmp and append it to diagnostic.
 func appendInlinedPos(posTmp []src.Pos, diagnostic *Diagnostic) {
 	for i := 1; i < len(posTmp); i++ {
 		p := posTmp[i]
diff --git a/src/cmd/compile/internal/logopt/logopt_test.go b/src/cmd/compile/internal/logopt/logopt_test.go
index 411319f..eb5c313 100644
--- a/src/cmd/compile/internal/logopt/logopt_test.go
+++ b/src/cmd/compile/internal/logopt/logopt_test.go
@@ -6,9 +6,7 @@
 
 import (
 	"internal/testenv"
-	"io/ioutil"
 	"os"
-	"os/exec"
 	"path/filepath"
 	"runtime"
 	"strings"
@@ -88,7 +86,7 @@
 
 	testenv.MustHaveGoBuild(t)
 
-	dir, err := ioutil.TempDir("", "TestLogOpt")
+	dir, err := os.MkdirTemp("", "TestLogOpt")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -96,7 +94,7 @@
 
 	dir = fixSlash(dir) // Normalize the directory name as much as possible, for Windows testing
 	src := filepath.Join(dir, "file.go")
-	if err := ioutil.WriteFile(src, []byte(srcCode), 0644); err != nil {
+	if err := os.WriteFile(src, []byte(srcCode), 0644); err != nil {
 		t.Fatal(err)
 	}
 
@@ -146,7 +144,7 @@
 }
 `
 		copy := filepath.Join(dir, "copy.go")
-		if err := ioutil.WriteFile(copy, []byte(copyCode), 0644); err != nil {
+		if err := os.WriteFile(copy, []byte(copyCode), 0644); err != nil {
 			t.Fatal(err)
 		}
 		outcopy := filepath.Join(dir, "copy.o")
@@ -169,7 +167,7 @@
 				if err != nil {
 					t.Error("-json=0,file://log/opt should have succeeded")
 				}
-				logged, err := ioutil.ReadFile(filepath.Join(dir, "log", "opt", "x", "copy.json"))
+				logged, err := os.ReadFile(filepath.Join(dir, "log", "opt", "x", "copy.json"))
 				if err != nil {
 					t.Error("-json=0,file://log/opt missing expected log file")
 				}
@@ -196,7 +194,7 @@
 		if err != nil {
 			t.Error("-json=0,file://log/opt should have succeeded")
 		}
-		logged, err := ioutil.ReadFile(filepath.Join(dir, "log", "opt", "x", "file.json"))
+		logged, err := os.ReadFile(filepath.Join(dir, "log", "opt", "x", "file.json"))
 		if err != nil {
 			t.Error("-json=0,file://log/opt missing expected log file")
 		}
@@ -228,7 +226,7 @@
 func testLogOpt(t *testing.T, flag, src, outfile string) (string, error) {
 	run := []string{testenv.GoToolPath(t), "tool", "compile", "-p=p", flag, "-o", outfile, src}
 	t.Log(run)
-	cmd := exec.Command(run[0], run[1:]...)
+	cmd := testenv.Command(t, run[0], run[1:]...)
 	out, err := cmd.CombinedOutput()
 	t.Logf("%s", out)
 	return string(out), err
@@ -238,7 +236,7 @@
 	// Notice the specified import path "x"
 	run := []string{testenv.GoToolPath(t), "tool", "compile", "-p=x", flag, "-o", outfile, src}
 	t.Log(run)
-	cmd := exec.Command(run[0], run[1:]...)
+	cmd := testenv.Command(t, run[0], run[1:]...)
 	cmd.Dir = dir
 	out, err := cmd.CombinedOutput()
 	t.Logf("%s", out)
@@ -249,7 +247,7 @@
 	// Notice the specified import path "x"
 	run := []string{testenv.GoToolPath(t), "tool", "compile", "-p=x", "-json=0,file://log/opt", "-o", outfile, src}
 	t.Log(run)
-	cmd := exec.Command(run[0], run[1:]...)
+	cmd := testenv.Command(t, run[0], run[1:]...)
 	cmd.Dir = dir
 	cmd.Env = append(os.Environ(), "GOARCH="+goarch, "GOOS="+goos)
 	out, err := cmd.CombinedOutput()
diff --git a/src/cmd/compile/internal/loong64/ssa.go b/src/cmd/compile/internal/loong64/ssa.go
index ed1fcb3..59f9e18 100644
--- a/src/cmd/compile/internal/loong64/ssa.go
+++ b/src/cmd/compile/internal/loong64/ssa.go
@@ -17,7 +17,7 @@
 	"cmd/internal/obj/loong64"
 )
 
-// isFPreg reports whether r is an FP register
+// isFPreg reports whether r is an FP register.
 func isFPreg(r int16) bool {
 	return loong64.REG_F0 <= r && r <= loong64.REG_F31
 }
@@ -101,9 +101,6 @@
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = y
 	case ssa.OpLOONG64MOVVnop:
-		if v.Reg() != v.Args[0].Reg() {
-			v.Fatalf("input[0] and output not in same register %s", v.LongString())
-		}
 		// nothing to do
 	case ssa.OpLoadReg:
 		if v.Type.IsFlags() {
@@ -134,6 +131,8 @@
 		ssa.OpLOONG64SLLV,
 		ssa.OpLOONG64SRLV,
 		ssa.OpLOONG64SRAV,
+		ssa.OpLOONG64ROTR,
+		ssa.OpLOONG64ROTRV,
 		ssa.OpLOONG64ADDF,
 		ssa.OpLOONG64ADDD,
 		ssa.OpLOONG64SUBF,
@@ -165,6 +164,8 @@
 		ssa.OpLOONG64SLLVconst,
 		ssa.OpLOONG64SRLVconst,
 		ssa.OpLOONG64SRAVconst,
+		ssa.OpLOONG64ROTRconst,
+		ssa.OpLOONG64ROTRVconst,
 		ssa.OpLOONG64SGTconst,
 		ssa.OpLOONG64SGTUconst:
 		p := s.Prog(v.Op.Asm())
@@ -785,6 +786,13 @@
 		p := s.Prog(obj.AGETCALLERPC)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
+	case ssa.OpLOONG64MASKEQZ, ssa.OpLOONG64MASKNEZ:
+		p := s.Prog(v.Op.Asm())
+		p.From.Type = obj.TYPE_REG
+		p.From.Reg = v.Args[1].Reg()
+		p.Reg = v.Args[0].Reg()
+		p.To.Type = obj.TYPE_REG
+		p.To.Reg = v.Reg()
 	case ssa.OpClobber, ssa.OpClobberReg:
 		// TODO: implement for clobberdead experiment. Nop is ok for now.
 	default:
diff --git a/src/cmd/compile/internal/mips/ssa.go b/src/cmd/compile/internal/mips/ssa.go
index 0411756..2ad7520 100644
--- a/src/cmd/compile/internal/mips/ssa.go
+++ b/src/cmd/compile/internal/mips/ssa.go
@@ -17,12 +17,12 @@
 	"cmd/internal/obj/mips"
 )
 
-// isFPreg reports whether r is an FP register
+// isFPreg reports whether r is an FP register.
 func isFPreg(r int16) bool {
 	return mips.REG_F0 <= r && r <= mips.REG_F31
 }
 
-// isHILO reports whether r is HI or LO register
+// isHILO reports whether r is HI or LO register.
 func isHILO(r int16) bool {
 	return r == mips.REG_HI || r == mips.REG_LO
 }
diff --git a/src/cmd/compile/internal/mips64/ssa.go b/src/cmd/compile/internal/mips64/ssa.go
index f3e372c..8612763 100644
--- a/src/cmd/compile/internal/mips64/ssa.go
+++ b/src/cmd/compile/internal/mips64/ssa.go
@@ -17,12 +17,12 @@
 	"cmd/internal/obj/mips"
 )
 
-// isFPreg reports whether r is an FP register
+// isFPreg reports whether r is an FP register.
 func isFPreg(r int16) bool {
 	return mips.REG_F0 <= r && r <= mips.REG_F31
 }
 
-// isHILO reports whether r is HI or LO register
+// isHILO reports whether r is HI or LO register.
 func isHILO(r int16) bool {
 	return r == mips.REG_HI || r == mips.REG_LO
 }
diff --git a/src/cmd/compile/internal/noder/codes.go b/src/cmd/compile/internal/noder/codes.go
index 8f54a07..c1ee8d1 100644
--- a/src/cmd/compile/internal/noder/codes.go
+++ b/src/cmd/compile/internal/noder/codes.go
@@ -1,5 +1,3 @@
-// UNREVIEWED
-
 // Copyright 2021 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
@@ -8,6 +6,7 @@
 
 import "internal/pkgbits"
 
+// A codeStmt distinguishes among statement encodings.
 type codeStmt int
 
 func (c codeStmt) Marker() pkgbits.SyncMarker { return pkgbits.SyncStmt1 }
@@ -31,6 +30,7 @@
 	stmtSelect
 )
 
+// A codeExpr distinguishes among expression encodings.
 type codeExpr int
 
 func (c codeExpr) Marker() pkgbits.SyncMarker { return pkgbits.SyncExpr }
@@ -38,15 +38,14 @@
 
 // TODO(mdempsky): Split expr into addr, for lvalues.
 const (
-	exprNone codeExpr = iota
-	exprConst
-	exprType  // type expression
-	exprLocal // local variable
-	exprName  // global variable or function
-	exprBlank
+	exprConst  codeExpr = iota
+	exprLocal           // local variable
+	exprGlobal          // global variable or function
 	exprCompLit
 	exprFuncLit
-	exprSelector
+	exprFieldVal
+	exprMethodVal
+	exprMethodExpr
 	exprIndex
 	exprSlice
 	exprAssert
@@ -54,8 +53,26 @@
 	exprBinaryOp
 	exprCall
 	exprConvert
+	exprNew
+	exprMake
+	exprNil
+	exprFuncInst
+	exprRecv
+	exprReshape
 )
 
+type codeAssign int
+
+func (c codeAssign) Marker() pkgbits.SyncMarker { return pkgbits.SyncAssign }
+func (c codeAssign) Value() int                 { return int(c) }
+
+const (
+	assignBlank codeAssign = iota
+	assignDef
+	assignExpr
+)
+
+// A codeDecl distinguishes among declaration encodings.
 type codeDecl int
 
 func (c codeDecl) Marker() pkgbits.SyncMarker { return pkgbits.SyncDecl }
diff --git a/src/cmd/compile/internal/noder/decl.go b/src/cmd/compile/internal/noder/decl.go
index 91a90d9..07353cc 100644
--- a/src/cmd/compile/internal/noder/decl.go
+++ b/src/cmd/compile/internal/noder/decl.go
@@ -212,33 +212,9 @@
 		ntyp.SetVargen()
 	}
 
-	pragmas := g.pragmaFlags(decl.Pragma, typePragmas)
+	pragmas := g.pragmaFlags(decl.Pragma, 0)
 	name.SetPragma(pragmas) // TODO(mdempsky): Is this still needed?
 
-	if pragmas&ir.NotInHeap != 0 {
-		ntyp.SetNotInHeap(true)
-	}
-
-	// We need to use g.typeExpr(decl.Type) here to ensure that for
-	// chained, defined-type declarations like:
-	//
-	//	type T U
-	//
-	//	//go:notinheap
-	//	type U struct { … }
-	//
-	// we mark both T and U as NotInHeap. If we instead used just
-	// g.typ(otyp.Underlying()), then we'd instead set T's underlying
-	// type directly to the struct type (which is not marked NotInHeap)
-	// and fail to mark T as NotInHeap.
-	//
-	// Also, we rely here on Type.SetUnderlying allowing passing a
-	// defined type and handling forward references like from T to U
-	// above. Contrast with go/types's Named.SetUnderlying, which
-	// disallows this.
-	//
-	// [mdempsky: Subtleties like these are why I always vehemently
-	// object to new type pragmas.]
 	ntyp.SetUnderlying(g.typeExpr(decl.Type))
 
 	tparams := otyp.(*types2.Named).TypeParams()
diff --git a/src/cmd/compile/internal/noder/expr.go b/src/cmd/compile/internal/noder/expr.go
index a1160d4..f391339 100644
--- a/src/cmd/compile/internal/noder/expr.go
+++ b/src/cmd/compile/internal/noder/expr.go
@@ -6,7 +6,6 @@
 
 import (
 	"fmt"
-	"go/constant"
 
 	"cmd/compile/internal/base"
 	"cmd/compile/internal/ir"
@@ -28,10 +27,7 @@
 		return ir.BlankNode
 	}
 
-	tv, ok := g.info.Types[expr]
-	if !ok {
-		base.FatalfAt(g.pos(expr), "missing type for %v (%T)", expr, expr)
-	}
+	tv := g.typeAndValue(expr)
 	switch {
 	case tv.IsBuiltin():
 		// Qualified builtins, such as unsafe.Add and unsafe.Slice.
@@ -53,31 +49,9 @@
 
 	base.Assert(g.exprStmtOK)
 
-	// The gc backend expects all expressions to have a concrete type, and
-	// types2 mostly satisfies this expectation already. But there are a few
-	// cases where the Go spec doesn't require converting to concrete type,
-	// and so types2 leaves them untyped. So we need to fix those up here.
-	typ := tv.Type
-	if basic, ok := typ.(*types2.Basic); ok && basic.Info()&types2.IsUntyped != 0 {
-		switch basic.Kind() {
-		case types2.UntypedNil:
-			// ok; can appear in type switch case clauses
-			// TODO(mdempsky): Handle as part of type switches instead?
-		case types2.UntypedInt, types2.UntypedFloat, types2.UntypedComplex:
-			// Untyped rhs of non-constant shift, e.g. x << 1.0.
-			// If we have a constant value, it must be an int >= 0.
-			if tv.Value != nil {
-				s := constant.ToInt(tv.Value)
-				assert(s.Kind() == constant.Int && constant.Sign(s) >= 0)
-			}
-			typ = types2.Typ[types2.Uint]
-		case types2.UntypedBool:
-			typ = types2.Typ[types2.Bool] // expression in "if" or "for" condition
-		case types2.UntypedString:
-			typ = types2.Typ[types2.String] // argument to "append" or "copy" calls
-		default:
-			base.FatalfAt(g.pos(expr), "unexpected untyped type: %v", basic)
-		}
+	typ := idealType(tv)
+	if typ == nil {
+		base.FatalfAt(g.pos(expr), "unexpected untyped type: %v", tv.Type)
 	}
 
 	// Constant expression.
@@ -128,8 +102,7 @@
 	case *syntax.IndexExpr:
 		args := unpackListExpr(expr.Index)
 		if len(args) == 1 {
-			tv, ok := g.info.Types[args[0]]
-			assert(ok)
+			tv := g.typeAndValue(args[0])
 			if tv.IsValue() {
 				// This is just a normal index expression
 				n := Index(pos, g.typ(typ), g.expr(expr.X), g.expr(args[0]))
diff --git a/src/cmd/compile/internal/noder/helpers.go b/src/cmd/compile/internal/noder/helpers.go
index 33acd60..4ef46a4 100644
--- a/src/cmd/compile/internal/noder/helpers.go
+++ b/src/cmd/compile/internal/noder/helpers.go
@@ -9,8 +9,10 @@
 
 	"cmd/compile/internal/base"
 	"cmd/compile/internal/ir"
+	"cmd/compile/internal/syntax"
 	"cmd/compile/internal/typecheck"
 	"cmd/compile/internal/types"
+	"cmd/compile/internal/types2"
 	"cmd/internal/src"
 )
 
@@ -39,10 +41,6 @@
 
 // Values
 
-func Const(pos src.XPos, typ *types.Type, val constant.Value) ir.Node {
-	return typed(typ, ir.NewBasicLit(pos, val))
-}
-
 func OrigConst(pos src.XPos, typ *types.Type, val constant.Value, op ir.Op, raw string) ir.Node {
 	orig := ir.NewRawOrigExpr(pos, op, raw)
 	return ir.NewConstExpr(val, typed(typ, orig))
@@ -224,3 +222,63 @@
 	}
 	return ir.NewAssignOpStmt(pos, op, x, bl)
 }
+
+func idealType(tv syntax.TypeAndValue) types2.Type {
+	// The gc backend expects all expressions to have a concrete type, and
+	// types2 mostly satisfies this expectation already. But there are a few
+	// cases where the Go spec doesn't require converting to concrete type,
+	// and so types2 leaves them untyped. So we need to fix those up here.
+	typ := tv.Type
+	if basic, ok := typ.(*types2.Basic); ok && basic.Info()&types2.IsUntyped != 0 {
+		switch basic.Kind() {
+		case types2.UntypedNil:
+			// ok; can appear in type switch case clauses
+			// TODO(mdempsky): Handle as part of type switches instead?
+		case types2.UntypedInt, types2.UntypedFloat, types2.UntypedComplex:
+			// Untyped rhs of non-constant shift, e.g. x << 1.0.
+			// If we have a constant value, it must be an int >= 0.
+			if tv.Value != nil {
+				s := constant.ToInt(tv.Value)
+				assert(s.Kind() == constant.Int && constant.Sign(s) >= 0)
+			}
+			typ = types2.Typ[types2.Uint]
+		case types2.UntypedBool:
+			typ = types2.Typ[types2.Bool] // expression in "if" or "for" condition
+		case types2.UntypedString:
+			typ = types2.Typ[types2.String] // argument to "append" or "copy" calls
+		default:
+			return nil
+		}
+	}
+	return typ
+}
+
+func isTypeParam(t types2.Type) bool {
+	_, ok := t.(*types2.TypeParam)
+	return ok
+}
+
+// isNotInHeap reports whether typ is or contains an element of type
+// runtime/internal/sys.NotInHeap.
+func isNotInHeap(typ types2.Type) bool {
+	if named, ok := typ.(*types2.Named); ok {
+		if obj := named.Obj(); obj.Name() == "nih" && obj.Pkg().Path() == "runtime/internal/sys" {
+			return true
+		}
+		typ = named.Underlying()
+	}
+
+	switch typ := typ.(type) {
+	case *types2.Array:
+		return isNotInHeap(typ.Elem())
+	case *types2.Struct:
+		for i := 0; i < typ.NumFields(); i++ {
+			if isNotInHeap(typ.Field(i).Type()) {
+				return true
+			}
+		}
+		return false
+	default:
+		return false
+	}
+}
diff --git a/src/cmd/compile/internal/noder/import.go b/src/cmd/compile/internal/noder/import.go
index 2cef9f7..8b017ec 100644
--- a/src/cmd/compile/internal/noder/import.go
+++ b/src/cmd/compile/internal/noder/import.go
@@ -241,7 +241,7 @@
 		pr := pkgbits.NewPkgDecoder(pkg1.Path, data)
 
 		// Read package descriptors for both types2 and compiler backend.
-		readPackage(newPkgReader(pr), pkg1)
+		readPackage(newPkgReader(pr), pkg1, false)
 		pkg2 = importer.ReadPackage(env, packages, pr)
 
 	case 'i':
@@ -355,16 +355,6 @@
 	return nil
 }
 
-// The linker uses the magic symbol prefixes "go." and "type."
-// Avoid potential confusion between import paths and symbols
-// by rejecting these reserved imports for now. Also, people
-// "can do weird things in GOPATH and we'd prefer they didn't
-// do _that_ weird thing" (per rsc). See also #4257.
-var reservedimports = []string{
-	"go",
-	"type",
-}
-
 func checkImportPath(path string, allowSpace bool) error {
 	if path == "" {
 		return errors.New("import path is empty")
@@ -374,7 +364,7 @@
 		return errors.New("import path contains NUL")
 	}
 
-	for _, ri := range reservedimports {
+	for ri := range base.ReservedImports {
 		if path == ri {
 			return fmt.Errorf("import path %q is reserved and cannot be used", path)
 		}
diff --git a/src/cmd/compile/internal/noder/irgen.go b/src/cmd/compile/internal/noder/irgen.go
index e45a204..d034926 100644
--- a/src/cmd/compile/internal/noder/irgen.go
+++ b/src/cmd/compile/internal/noder/irgen.go
@@ -6,6 +6,8 @@
 
 import (
 	"fmt"
+	"regexp"
+	"sort"
 
 	"cmd/compile/internal/base"
 	"cmd/compile/internal/dwarfgen"
@@ -17,6 +19,8 @@
 	"cmd/internal/src"
 )
 
+var versionErrorRx = regexp.MustCompile(`requires go[0-9]+\.[0-9]+ or later`)
+
 // checkFiles configures and runs the types2 checker on the given
 // parsed source files and then returns the result.
 func checkFiles(noders []*noder) (posMap, *types2.Package, *types2.Info) {
@@ -39,30 +43,80 @@
 		packages: make(map[string]*types2.Package),
 	}
 	conf := types2.Config{
-		Context:               ctxt,
-		GoVersion:             base.Flag.Lang,
-		IgnoreBranchErrors:    true, // parser already checked via syntax.CheckBranches mode
-		CompilerErrorMessages: true, // use error strings matching existing compiler errors
+		Context:            ctxt,
+		GoVersion:          base.Flag.Lang,
+		IgnoreBranchErrors: true, // parser already checked via syntax.CheckBranches mode
 		Error: func(err error) {
 			terr := err.(types2.Error)
-			base.ErrorfAt(m.makeXPos(terr.Pos), "%s", terr.Msg)
+			msg := terr.Msg
+			// if we have a version error, hint at the -lang setting
+			if versionErrorRx.MatchString(msg) {
+				msg = fmt.Sprintf("%s (-lang was set to %s; check go.mod)", msg, base.Flag.Lang)
+			}
+			base.ErrorfAt(m.makeXPos(terr.Pos), "%s", msg)
 		},
-		Importer: &importer,
-		Sizes:    &gcSizes{},
+		Importer:               &importer,
+		Sizes:                  &gcSizes{},
+		OldComparableSemantics: base.Flag.OldComparable, // default is new comparable semantics
 	}
 	info := &types2.Info{
-		Types:      make(map[syntax.Expr]types2.TypeAndValue),
-		Defs:       make(map[*syntax.Name]types2.Object),
-		Uses:       make(map[*syntax.Name]types2.Object),
-		Selections: make(map[*syntax.SelectorExpr]*types2.Selection),
-		Implicits:  make(map[syntax.Node]types2.Object),
-		Scopes:     make(map[syntax.Node]*types2.Scope),
-		Instances:  make(map[*syntax.Name]types2.Instance),
+		StoreTypesInSyntax: true,
+		Defs:               make(map[*syntax.Name]types2.Object),
+		Uses:               make(map[*syntax.Name]types2.Object),
+		Selections:         make(map[*syntax.SelectorExpr]*types2.Selection),
+		Implicits:          make(map[syntax.Node]types2.Object),
+		Scopes:             make(map[syntax.Node]*types2.Scope),
+		Instances:          make(map[*syntax.Name]types2.Instance),
 		// expand as needed
 	}
 
 	pkg, err := conf.Check(base.Ctxt.Pkgpath, files, info)
 
+	// Check for anonymous interface cycles (#56103).
+	if base.Debug.InterfaceCycles == 0 {
+		var f cycleFinder
+		for _, file := range files {
+			syntax.Inspect(file, func(n syntax.Node) bool {
+				if n, ok := n.(*syntax.InterfaceType); ok {
+					if f.hasCycle(n.GetTypeInfo().Type.(*types2.Interface)) {
+						base.ErrorfAt(m.makeXPos(n.Pos()), "invalid recursive type: anonymous interface refers to itself (see https://go.dev/issue/56103)")
+
+						for typ := range f.cyclic {
+							f.cyclic[typ] = false // suppress duplicate errors
+						}
+					}
+					return false
+				}
+				return true
+			})
+		}
+	}
+
+	// Implementation restriction: we don't allow not-in-heap types to
+	// be used as type arguments (#54765).
+	{
+		type nihTarg struct {
+			pos src.XPos
+			typ types2.Type
+		}
+		var nihTargs []nihTarg
+
+		for name, inst := range info.Instances {
+			for i := 0; i < inst.TypeArgs.Len(); i++ {
+				if targ := inst.TypeArgs.At(i); isNotInHeap(targ) {
+					nihTargs = append(nihTargs, nihTarg{m.makeXPos(name.Pos()), targ})
+				}
+			}
+		}
+		sort.Slice(nihTargs, func(i, j int) bool {
+			ti, tj := nihTargs[i], nihTargs[j]
+			return ti.pos.Before(tj.pos)
+		})
+		for _, targ := range nihTargs {
+			base.ErrorfAt(targ.pos, "cannot use incomplete (or unallocatable) type as a type argument: %v", targ.typ)
+		}
+	}
+
 	base.ExitIfErrors()
 	if err != nil {
 		base.FatalfAt(src.NoXPos, "conf.Check error: %v", err)
@@ -219,7 +273,6 @@
 
 func (g *irgen) generate(noders []*noder) {
 	types.LocalPkg.Name = g.self.Name()
-	types.LocalPkg.Height = g.self.Height()
 	typecheck.TypecheckAllowed = true
 
 	// Prevent size calculations until we set the underlying type
@@ -357,3 +410,107 @@
 func (g *irgen) delayTransform() bool {
 	return g.topFuncIsGeneric
 }
+
+func (g *irgen) typeAndValue(x syntax.Expr) syntax.TypeAndValue {
+	tv := x.GetTypeInfo()
+	if tv.Type == nil {
+		base.FatalfAt(g.pos(x), "missing type for %v (%T)", x, x)
+	}
+	return tv
+}
+
+func (g *irgen) type2(x syntax.Expr) syntax.Type {
+	tv := x.GetTypeInfo()
+	if tv.Type == nil {
+		base.FatalfAt(g.pos(x), "missing type for %v (%T)", x, x)
+	}
+	return tv.Type
+}
+
+// A cycleFinder detects anonymous interface cycles (go.dev/issue/56103).
+type cycleFinder struct {
+	cyclic map[*types2.Interface]bool
+}
+
+// hasCycle reports whether typ is part of an anonymous interface cycle.
+func (f *cycleFinder) hasCycle(typ *types2.Interface) bool {
+	// We use Method instead of ExplicitMethod to implicitly expand any
+	// embedded interfaces. Then we just need to walk any anonymous
+	// types, keeping track of *types2.Interface types we visit along
+	// the way.
+	for i := 0; i < typ.NumMethods(); i++ {
+		if f.visit(typ.Method(i).Type()) {
+			return true
+		}
+	}
+	return false
+}
+
+// visit recursively walks typ0 to check any referenced interface types.
+func (f *cycleFinder) visit(typ0 types2.Type) bool {
+	for { // loop for tail recursion
+		switch typ := typ0.(type) {
+		default:
+			base.Fatalf("unexpected type: %T", typ)
+
+		case *types2.Basic, *types2.Named, *types2.TypeParam:
+			return false // named types cannot be part of an anonymous cycle
+		case *types2.Pointer:
+			typ0 = typ.Elem()
+		case *types2.Array:
+			typ0 = typ.Elem()
+		case *types2.Chan:
+			typ0 = typ.Elem()
+		case *types2.Map:
+			if f.visit(typ.Key()) {
+				return true
+			}
+			typ0 = typ.Elem()
+		case *types2.Slice:
+			typ0 = typ.Elem()
+
+		case *types2.Struct:
+			for i := 0; i < typ.NumFields(); i++ {
+				if f.visit(typ.Field(i).Type()) {
+					return true
+				}
+			}
+			return false
+
+		case *types2.Interface:
+			// The empty interface (e.g., "any") cannot be part of a cycle.
+			if typ.NumExplicitMethods() == 0 && typ.NumEmbeddeds() == 0 {
+				return false
+			}
+
+			// As an optimization, we wait to allocate cyclic here, after
+			// we've found at least one other (non-empty) anonymous
+			// interface. This means when a cycle is present, we need to
+			// make an extra recursive call to actually detect it. But for
+			// most packages, it allows skipping the map allocation
+			// entirely.
+			if x, ok := f.cyclic[typ]; ok {
+				return x
+			}
+			if f.cyclic == nil {
+				f.cyclic = make(map[*types2.Interface]bool)
+			}
+			f.cyclic[typ] = true
+			if f.hasCycle(typ) {
+				return true
+			}
+			f.cyclic[typ] = false
+			return false
+
+		case *types2.Signature:
+			return f.visit(typ.Params()) || f.visit(typ.Results())
+		case *types2.Tuple:
+			for i := 0; i < typ.Len(); i++ {
+				if f.visit(typ.At(i).Type()) {
+					return true
+				}
+			}
+			return false
+		}
+	}
+}
diff --git a/src/cmd/compile/internal/noder/lex.go b/src/cmd/compile/internal/noder/lex.go
index cef0f08..c964eca 100644
--- a/src/cmd/compile/internal/noder/lex.go
+++ b/src/cmd/compile/internal/noder/lex.go
@@ -36,8 +36,6 @@
 		ir.Nowritebarrier |
 		ir.Nowritebarrierrec |
 		ir.Yeswritebarrierrec
-
-	typePragmas = ir.NotInHeap
 )
 
 func pragmaFlag(verb string) ir.PragmaFlag {
@@ -77,8 +75,6 @@
 		return ir.UintptrEscapes | ir.UintptrKeepAlive // implies UintptrKeepAlive
 	case "go:registerparams": // TODO(register args) remove after register abi is working
 		return ir.RegisterParams
-	case "go:notinheap":
-		return ir.NotInHeap
 	}
 	return 0
 }
diff --git a/src/cmd/compile/internal/noder/linker.go b/src/cmd/compile/internal/noder/linker.go
index a58b9b9..0f39fde 100644
--- a/src/cmd/compile/internal/noder/linker.go
+++ b/src/cmd/compile/internal/noder/linker.go
@@ -1,5 +1,3 @@
-// UNREVIEWED
-
 // Copyright 2021 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
@@ -34,13 +32,20 @@
 // low-level linking details can be moved there, but the logic for
 // handling extension data needs to stay in the compiler.
 
+// A linker combines a package's stub export data with any referenced
+// elements from imported packages into a single, self-contained
+// export data file.
 type linker struct {
 	pw pkgbits.PkgEncoder
 
-	pkgs  map[string]pkgbits.Index
-	decls map[*types.Sym]pkgbits.Index
+	pkgs   map[string]pkgbits.Index
+	decls  map[*types.Sym]pkgbits.Index
+	bodies map[*types.Sym]pkgbits.Index
 }
 
+// relocAll ensures that all elements specified by pr and relocs are
+// copied into the output export data file, and returns the
+// corresponding indices in the output.
 func (l *linker) relocAll(pr *pkgReader, relocs []pkgbits.RelocEnt) []pkgbits.RelocEnt {
 	res := make([]pkgbits.RelocEnt, len(relocs))
 	for i, rent := range relocs {
@@ -50,6 +55,8 @@
 	return res
 }
 
+// relocIdx ensures a single element is copied into the output export
+// data file, and returns the corresponding index in the output.
 func (l *linker) relocIdx(pr *pkgReader, k pkgbits.RelocKind, idx pkgbits.Index) pkgbits.Index {
 	assert(pr != nil)
 
@@ -85,10 +92,19 @@
 	return newidx
 }
 
+// relocString copies the specified string from pr into the output
+// export data file, deduplicating it against other strings.
 func (l *linker) relocString(pr *pkgReader, idx pkgbits.Index) pkgbits.Index {
 	return l.pw.StringIdx(pr.StringIdx(idx))
 }
 
+// relocPkg copies the specified package from pr into the output
+// export data file, rewriting its import path to match how it was
+// imported.
+//
+// TODO(mdempsky): Since CL 391014, we already have the compilation
+// unit's import path, so there should be no need to rewrite packages
+// anymore.
 func (l *linker) relocPkg(pr *pkgReader, idx pkgbits.Index) pkgbits.Index {
 	path := pr.PeekPkgPath(idx)
 
@@ -114,6 +130,9 @@
 	return w.Flush()
 }
 
+// relocObj copies the specified object from pr into the output export
+// data file, rewriting its compiler-private extension data (e.g.,
+// adding inlining cost and escape analysis results for functions).
 func (l *linker) relocObj(pr *pkgReader, idx pkgbits.Index) pkgbits.Index {
 	path, name, tag := pr.PeekObj(idx)
 	sym := types.NewPkg(path, "").Lookup(name)
@@ -152,21 +171,12 @@
 	l.relocCommon(pr, &wname, pkgbits.RelocName, idx)
 	l.relocCommon(pr, &wdict, pkgbits.RelocObjDict, idx)
 
-	var obj *ir.Name
-	if sym.Pkg == types.LocalPkg {
-		var ok bool
-		obj, ok = sym.Def.(*ir.Name)
+	// Generic types and functions won't have definitions, and imported
+	// objects may not either.
+	obj, _ := sym.Def.(*ir.Name)
+	local := sym.Pkg == types.LocalPkg
 
-		// Generic types and functions and declared constraint types won't
-		// have definitions.
-		// For now, just generically copy their extension data.
-		// TODO(mdempsky): Restore assertion.
-		if !ok && false {
-			base.Fatalf("missing definition for %v", sym)
-		}
-	}
-
-	if obj != nil {
+	if local && obj != nil {
 		wext.Sync(pkgbits.SyncObject1)
 		switch tag {
 		case pkgbits.ObjFunc:
@@ -181,9 +191,66 @@
 		l.relocCommon(pr, &wext, pkgbits.RelocObjExt, idx)
 	}
 
+	// Check if we need to export the inline bodies for functions and
+	// methods.
+	if obj != nil {
+		if obj.Op() == ir.ONAME && obj.Class == ir.PFUNC {
+			l.exportBody(obj, local)
+		}
+
+		if obj.Op() == ir.OTYPE {
+			if typ := obj.Type(); !typ.IsInterface() {
+				for _, method := range typ.Methods().Slice() {
+					l.exportBody(method.Nname.(*ir.Name), local)
+				}
+			}
+		}
+	}
+
 	return w.Idx
 }
 
+// exportBody exports the given function or method's body, if
+// appropriate. local indicates whether it's a local function or
+// method available on a locally declared type. (Due to cross-package
+// type aliases, a method may be imported, but still available on a
+// locally declared type.)
+func (l *linker) exportBody(obj *ir.Name, local bool) {
+	assert(obj.Op() == ir.ONAME && obj.Class == ir.PFUNC)
+
+	fn := obj.Func
+	if fn.Inl == nil {
+		return // not inlinable anyway
+	}
+
+	// As a simple heuristic, if the function was declared in this
+	// package or we inlined it somewhere in this package, then we'll
+	// (re)export the function body. This isn't perfect, but seems
+	// reasonable in practice. In particular, it has the nice property
+	// that in the worst case, adding a blank import ensures the
+	// function body is available for inlining.
+	//
+	// TODO(mdempsky): Reimplement the reachable method crawling logic
+	// from typecheck/crawler.go.
+	exportBody := local || fn.Inl.Body != nil
+	if !exportBody {
+		return
+	}
+
+	sym := obj.Sym()
+	if _, ok := l.bodies[sym]; ok {
+		// Due to type aliases, we might visit methods multiple times.
+		base.AssertfAt(obj.Type().Recv() != nil, obj.Pos(), "expected method: %v", obj)
+		return
+	}
+
+	pri, ok := bodyReaderFor(fn)
+	assert(ok)
+	l.bodies[sym] = l.relocIdx(pri.pr, pkgbits.RelocBody, pri.idx)
+}
+
+// relocCommon copies the specified element from pr into w,
+// recursively relocating any referenced elements as well.
 func (l *linker) relocCommon(pr *pkgReader, w *pkgbits.Encoder, k pkgbits.RelocKind, idx pkgbits.Index) {
 	r := pr.NewDecoderRaw(k, idx)
 	w.Relocs = l.relocAll(pr, r.Relocs)
@@ -220,10 +287,6 @@
 	if inl := name.Func.Inl; w.Bool(inl != nil) {
 		w.Len(int(inl.Cost))
 		w.Bool(inl.CanDelayResults)
-
-		pri, ok := bodyReader[name.Func]
-		assert(ok)
-		w.Reloc(pkgbits.RelocBody, l.relocIdx(pri.pr, pkgbits.RelocBody, pri.idx))
 	}
 
 	w.Sync(pkgbits.SyncEOF)
diff --git a/src/cmd/compile/internal/noder/noder.go b/src/cmd/compile/internal/noder/noder.go
index 15b1bf7..d0d9545 100644
--- a/src/cmd/compile/internal/noder/noder.go
+++ b/src/cmd/compile/internal/noder/noder.go
@@ -132,7 +132,9 @@
 		}
 		n := ir.AsNode(typecheck.Lookup(l.local).Def)
 		if n == nil || n.Op() != ir.ONAME {
-			p.errorAt(l.pos, "//go:linkname must refer to declared function or variable")
+			if types.AllowsGoVersion(1, 18) {
+				p.errorAt(l.pos, "//go:linkname must refer to declared function or variable")
+			}
 			continue
 		}
 		if n.Sym().Linkname != "" {
diff --git a/src/cmd/compile/internal/noder/quirks.go b/src/cmd/compile/internal/noder/quirks.go
index c4cb9b9..a22577f 100644
--- a/src/cmd/compile/internal/noder/quirks.go
+++ b/src/cmd/compile/internal/noder/quirks.go
@@ -1,5 +1,3 @@
-// UNREVIEWED
-
 // Copyright 2021 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
@@ -12,12 +10,12 @@
 	"cmd/compile/internal/syntax"
 )
 
-// This file defines helper functions useful for satisfying toolstash
-// -cmp when compared against the legacy frontend behavior, but can be
-// removed after that's no longer a concern.
-
 // typeExprEndPos returns the position that noder would leave base.Pos
 // after parsing the given type expression.
+//
+// Deprecated: This function exists to emulate position semantics from
+// Go 1.17, necessary for compatibility with the backend DWARF
+// generation logic that assigns variables to their appropriate scope.
 func typeExprEndPos(expr0 syntax.Expr) syntax.Pos {
 	for {
 		switch expr := expr0.(type) {
diff --git a/src/cmd/compile/internal/noder/reader.go b/src/cmd/compile/internal/noder/reader.go
index 296cdd7..bc2151e 100644
--- a/src/cmd/compile/internal/noder/reader.go
+++ b/src/cmd/compile/internal/noder/reader.go
@@ -1,5 +1,3 @@
-// UNREVIEWED
-
 // Copyright 2021 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
@@ -7,7 +5,6 @@
 package noder
 
 import (
-	"bytes"
 	"fmt"
 	"go/constant"
 	"internal/buildcfg"
@@ -19,22 +16,35 @@
 	"cmd/compile/internal/dwarfgen"
 	"cmd/compile/internal/inline"
 	"cmd/compile/internal/ir"
+	"cmd/compile/internal/objw"
 	"cmd/compile/internal/reflectdata"
+	"cmd/compile/internal/staticinit"
 	"cmd/compile/internal/typecheck"
 	"cmd/compile/internal/types"
 	"cmd/internal/obj"
+	"cmd/internal/objabi"
 	"cmd/internal/src"
 )
 
+// This file implements cmd/compile backend's reader for the Unified
+// IR export data.
+
+// A pkgReader reads Unified IR export data.
 type pkgReader struct {
 	pkgbits.PkgDecoder
 
+	// Indices for encoded things; lazily populated as needed.
+	//
+	// Note: Objects (i.e., ir.Names) are lazily instantiated by
+	// populating their types.Sym.Def; see objReader below.
+
 	posBases []*src.PosBase
 	pkgs     []*types.Pkg
 	typs     []*types.Type
 
-	// offset for rewriting the given index into the output,
-	// but bitwise inverted so we can detect if we're missing the entry or not.
+	// offset for rewriting the given (absolute!) index into the output,
+	// but bitwise inverted so we can detect if we're missing the entry
+	// or not.
 	newindex []pkgbits.Index
 }
 
@@ -50,15 +60,25 @@
 	}
 }
 
+// A pkgReaderIndex compactly identifies an index (and its
+// corresponding dictionary) within a package's export data.
 type pkgReaderIndex struct {
-	pr   *pkgReader
-	idx  pkgbits.Index
-	dict *readerDict
+	pr        *pkgReader
+	idx       pkgbits.Index
+	dict      *readerDict
+	methodSym *types.Sym
+
+	synthetic func(pos src.XPos, r *reader)
 }
 
 func (pri pkgReaderIndex) asReader(k pkgbits.RelocKind, marker pkgbits.SyncMarker) *reader {
+	if pri.synthetic != nil {
+		return &reader{synthetic: pri.synthetic}
+	}
+
 	r := pri.pr.newReader(k, pri.idx, marker)
 	r.dict = pri.dict
+	r.methodSym = pri.methodSym
 	return r
 }
 
@@ -69,6 +89,7 @@
 	}
 }
 
+// A reader provides APIs for reading an individual element.
 type reader struct {
 	pkgbits.Decoder
 
@@ -87,6 +108,18 @@
 
 	funarghack bool
 
+	// methodSym is the name of method's name, if reading a method.
+	// It's nil if reading a normal function or closure body.
+	methodSym *types.Sym
+
+	// dictParam is the .dict param, if any.
+	dictParam *ir.Name
+
+	// synthetic is a callback function to construct a synthetic
+	// function body. It's used for creating the bodies of function
+	// literals used to curry arguments to shaped functions.
+	synthetic func(pos src.XPos, r *reader)
+
 	// scopeVars is a stack tracking the number of variables declared in
 	// the current function at the moment each open scope was opened.
 	scopeVars         []int
@@ -103,15 +136,45 @@
 	inlTreeIndex int
 	inlPosBases  map[*src.PosBase]*src.PosBase
 
+	// suppressInlPos tracks whether position base rewriting for
+	// inlining should be suppressed. See funcLit.
+	suppressInlPos int
+
 	delayResults bool
 
 	// Label to return to.
 	retlabel *types.Sym
 
-	inlvars, retvars ir.Nodes
+	// inlvars is the list of variables that the inlinee's arguments are
+	// assigned to, one for each receiver and normal parameter, in order.
+	inlvars ir.Nodes
+
+	// retvars is the list of variables that the inlinee's results are
+	// assigned to, one for each result parameter, in order.
+	retvars ir.Nodes
 }
 
+// A readerDict represents an instantiated "compile-time dictionary,"
+// used for resolving any derived types needed for instantiating a
+// generic object.
+//
+// A compile-time dictionary can either be "shaped" or "non-shaped."
+// Shaped compile-time dictionaries are only used for instantiating
+// shaped type definitions and function bodies, while non-shaped
+// compile-time dictionaries are used for instantiating runtime
+// dictionaries.
 type readerDict struct {
+	shaped bool // whether this is a shaped dictionary
+
+	// baseSym is the symbol for the object this dictionary belongs to.
+	// If the object is an instantiated function or defined type, then
+	// baseSym is the mangled symbol, including any type arguments.
+	baseSym *types.Sym
+
+	// For non-shaped dictionaries, shapedObj is a reference to the
+	// corresponding shaped object (always a function or defined type).
+	shapedObj *ir.Name
+
 	// targs holds the implicit and explicit type arguments in use for
 	// reading the current object. For example:
 	//
@@ -139,15 +202,16 @@
 	derived      []derivedInfo // reloc index of the derived type's descriptor
 	derivedTypes []*types.Type // slice of previously computed derived types
 
-	funcs    []objInfo
-	funcsObj []ir.Node
-
-	itabs []itabInfo2
+	// These slices correspond to entries in the runtime dictionary.
+	typeParamMethodExprs []readerMethodExprInfo
+	subdicts             []objInfo
+	rtypes               []typeInfo
+	itabs                []itabInfo
 }
 
-type itabInfo2 struct {
-	typ  *types.Type
-	lsym *obj.LSym
+type readerMethodExprInfo struct {
+	typeParamIdx int
+	method       *types.Sym
 }
 
 func setType(n ir.Node, typ *types.Type) {
@@ -162,10 +226,21 @@
 
 // @@@ Positions
 
+// pos reads a position from the bitstream.
 func (r *reader) pos() src.XPos {
 	return base.Ctxt.PosTable.XPos(r.pos0())
 }
 
+// origPos reads a position from the bitstream, and returns both the
+// original raw position and an inlining-adjusted position.
+func (r *reader) origPos() (origPos, inlPos src.XPos) {
+	r.suppressInlPos++
+	origPos = r.pos()
+	r.suppressInlPos--
+	inlPos = r.inlPos(origPos)
+	return
+}
+
 func (r *reader) pos0() src.Pos {
 	r.Sync(pkgbits.SyncPos)
 	if !r.Bool() {
@@ -178,10 +253,13 @@
 	return src.MakePos(posBase, line, col)
 }
 
+// posBase reads a position base from the bitstream.
 func (r *reader) posBase() *src.PosBase {
 	return r.inlPosBase(r.p.posBaseIdx(r.Reloc(pkgbits.RelocPosBase)))
 }
 
+// posBaseIdx returns the specified position base, reading it first if
+// needed.
 func (pr *pkgReader) posBaseIdx(idx pkgbits.Index) *src.PosBase {
 	if b := pr.posBases[idx]; b != nil {
 		return b
@@ -222,8 +300,15 @@
 	return b
 }
 
+// inlPosBase returns the inlining-adjusted src.PosBase corresponding
+// to oldBase, which must be a non-inlined position. When not
+// inlining, this is just oldBase.
 func (r *reader) inlPosBase(oldBase *src.PosBase) *src.PosBase {
-	if r.inlCall == nil {
+	if index := oldBase.InliningIndex(); index >= 0 {
+		base.Fatalf("oldBase %v already has inlining index %v", oldBase, index)
+	}
+
+	if r.inlCall == nil || r.suppressInlPos != 0 {
 		return oldBase
 	}
 
@@ -236,36 +321,25 @@
 	return newBase
 }
 
-func (r *reader) updatePos(xpos src.XPos) src.XPos {
+// inlPos returns the inlining-adjusted src.XPos corresponding to
+// xpos, which must be a non-inlined position. When not inlining, this
+// is just xpos.
+func (r *reader) inlPos(xpos src.XPos) src.XPos {
 	pos := base.Ctxt.PosTable.Pos(xpos)
 	pos.SetBase(r.inlPosBase(pos.Base()))
 	return base.Ctxt.PosTable.XPos(pos)
 }
 
-func (r *reader) origPos(xpos src.XPos) src.XPos {
-	if r.inlCall == nil {
-		return xpos
-	}
-
-	pos := base.Ctxt.PosTable.Pos(xpos)
-	for old, new := range r.inlPosBases {
-		if pos.Base() == new {
-			pos.SetBase(old)
-			return base.Ctxt.PosTable.XPos(pos)
-		}
-	}
-
-	base.FatalfAt(xpos, "pos base missing from inlPosBases")
-	panic("unreachable")
-}
-
 // @@@ Packages
 
+// pkg reads a package reference from the bitstream.
 func (r *reader) pkg() *types.Pkg {
 	r.Sync(pkgbits.SyncPkg)
 	return r.p.pkgIdx(r.Reloc(pkgbits.RelocPkg))
 }
 
+// pkgIdx returns the specified package from the export data, reading
+// it first if needed.
 func (pr *pkgReader) pkgIdx(idx pkgbits.Index) *types.Pkg {
 	if pkg := pr.pkgs[idx]; pkg != nil {
 		return pkg
@@ -276,6 +350,7 @@
 	return pkg
 }
 
+// doPkg reads a package definition from the bitstream.
 func (r *reader) doPkg() *types.Pkg {
 	path := r.String()
 	switch path {
@@ -288,7 +363,6 @@
 	}
 
 	name := r.String()
-	height := r.Len()
 
 	pkg := types.NewPkg(path, "")
 
@@ -298,12 +372,6 @@
 		base.Assertf(pkg.Name == name, "package %q has name %q, but want %q", pkg.Path, pkg.Name, name)
 	}
 
-	if pkg.Height == 0 {
-		pkg.Height = height
-	} else {
-		base.Assertf(pkg.Height == height, "package %q has height %v, but want %v", pkg.Path, pkg.Height, height)
-	}
-
 	return pkg
 }
 
@@ -327,6 +395,19 @@
 	return typeInfo{idx: r.Reloc(pkgbits.RelocType), derived: false}
 }
 
+// typListIdx returns a list of the specified types, resolving derived
+// types within the given dictionary.
+func (pr *pkgReader) typListIdx(infos []typeInfo, dict *readerDict) []*types.Type {
+	typs := make([]*types.Type, len(infos))
+	for i, info := range infos {
+		typs[i] = pr.typIdx(info, dict, true)
+	}
+	return typs
+}
+
+// typIdx returns the specified type. If info specifies a derived
+// type, it's resolved within the given dictionary. If wrapped is
+// true, then method wrappers will be generated, if appropriate.
 func (pr *pkgReader) typIdx(info typeInfo, dict *readerDict, wrapped bool) *types.Type {
 	idx := info.idx
 	var where **types.Type
@@ -446,13 +527,33 @@
 }
 
 func (r *reader) unionType() *types.Type {
-	terms := make([]*types.Type, r.Len())
-	tildes := make([]bool, len(terms))
-	for i := range terms {
-		tildes[i] = r.Bool()
-		terms[i] = r.typ()
+	// In the types1 universe, we only need to handle value types.
+	// Impure interfaces (i.e., interfaces with non-trivial type sets
+	// like "int | string") can only appear as type parameter bounds,
+	// and this is enforced by the types2 type checker.
+	//
+	// However, type unions can still appear in pure interfaces if the
+	// type union is equivalent to "any". E.g., typeparam/issue52124.go
+	// declares variables with the type "interface { any | int }".
+	//
+	// To avoid needing to represent type unions in types1 (since we
+	// don't have any uses for that today anyway), we simply fold them
+	// to "any". As a consistency check, we still read the union terms
+	// to make sure this substitution is safe.
+
+	pure := false
+	for i, n := 0, r.Len(); i < n; i++ {
+		_ = r.Bool() // tilde
+		term := r.typ()
+		if term.IsEmptyInterface() {
+			pure = true
+		}
 	}
-	return types.NewUnion(terms, tildes)
+	if !pure {
+		base.Fatalf("impure type set used in value type")
+	}
+
+	return types.Types[types.TINTER]
 }
 
 func (r *reader) interfaceType() *types.Type {
@@ -536,44 +637,48 @@
 
 // @@@ Objects
 
+// objReader maps qualified identifiers (represented as *types.Sym) to
+// a pkgReader and corresponding index that can be used for reading
+// that object's definition.
 var objReader = map[*types.Sym]pkgReaderIndex{}
 
+// obj reads an instantiated object reference from the bitstream.
 func (r *reader) obj() ir.Node {
-	r.Sync(pkgbits.SyncObject)
-
-	if r.Bool() {
-		idx := r.Len()
-		obj := r.dict.funcsObj[idx]
-		if obj == nil {
-			fn := r.dict.funcs[idx]
-			targs := make([]*types.Type, len(fn.explicits))
-			for i, targ := range fn.explicits {
-				targs[i] = r.p.typIdx(targ, r.dict, true)
-			}
-
-			obj = r.p.objIdx(fn.idx, nil, targs)
-			assert(r.dict.funcsObj[idx] == nil)
-			r.dict.funcsObj[idx] = obj
-		}
-		return obj
-	}
-
-	idx := r.Reloc(pkgbits.RelocObj)
-
-	explicits := make([]*types.Type, r.Len())
-	for i := range explicits {
-		explicits[i] = r.typ()
-	}
-
-	var implicits []*types.Type
-	if r.dict != nil {
-		implicits = r.dict.targs
-	}
-
-	return r.p.objIdx(idx, implicits, explicits)
+	return r.p.objInstIdx(r.objInfo(), r.dict, false)
 }
 
-func (pr *pkgReader) objIdx(idx pkgbits.Index, implicits, explicits []*types.Type) ir.Node {
+// objInfo reads an instantiated object reference from the bitstream
+// and returns the encoded reference to it, without instantiating it.
+func (r *reader) objInfo() objInfo {
+	r.Sync(pkgbits.SyncObject)
+	assert(!r.Bool()) // TODO(mdempsky): Remove; was derived func inst.
+	idx := r.Reloc(pkgbits.RelocObj)
+
+	explicits := make([]typeInfo, r.Len())
+	for i := range explicits {
+		explicits[i] = r.typInfo()
+	}
+
+	return objInfo{idx, explicits}
+}
+
+// objInstIdx returns the encoded, instantiated object. If shaped is
+// true, then the shaped variant of the object is returned instead.
+func (pr *pkgReader) objInstIdx(info objInfo, dict *readerDict, shaped bool) ir.Node {
+	explicits := pr.typListIdx(info.explicits, dict)
+
+	var implicits []*types.Type
+	if dict != nil {
+		implicits = dict.targs
+	}
+
+	return pr.objIdx(info.idx, implicits, explicits, shaped)
+}
+
+// objIdx returns the specified object, instantiated with the given
+// type arguments, if any. If shaped is true, then the shaped variant
+// of the object is returned instead.
+func (pr *pkgReader) objIdx(idx pkgbits.Index, implicits, explicits []*types.Type, shaped bool) ir.Node {
 	rname := pr.newReader(pkgbits.RelocName, idx, pkgbits.SyncObject1)
 	_, sym := rname.qualifiedIdent()
 	tag := pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj))
@@ -585,12 +690,17 @@
 			return sym.Def.(ir.Node)
 		}
 		if pri, ok := objReader[sym]; ok {
-			return pri.pr.objIdx(pri.idx, nil, explicits)
+			return pri.pr.objIdx(pri.idx, nil, explicits, shaped)
 		}
 		base.Fatalf("unresolved stub: %v", sym)
 	}
 
-	dict := pr.objDictIdx(sym, idx, implicits, explicits)
+	dict := pr.objDictIdx(sym, idx, implicits, explicits, shaped)
+
+	sym = dict.baseSym
+	if !sym.IsBlank() && sym.Def != nil {
+		return sym.Def.(*ir.Name)
+	}
 
 	r := pr.newReader(pkgbits.RelocObj, idx, pkgbits.SyncObject1)
 	rext := pr.newReader(pkgbits.RelocObjExt, idx, pkgbits.SyncObject1)
@@ -598,13 +708,9 @@
 	r.dict = dict
 	rext.dict = dict
 
-	sym = r.mangle(sym)
-	if !sym.IsBlank() && sym.Def != nil {
-		return sym.Def.(*ir.Name)
-	}
-
 	do := func(op ir.Op, hasTParams bool) *ir.Name {
 		pos := r.pos()
+		setBasePos(pos)
 		if hasTParams {
 			r.typeParamNames()
 		}
@@ -651,15 +757,25 @@
 
 		if r.hasTypeParams() {
 			name.Func.SetDupok(true)
+			if r.dict.shaped {
+				setType(name, shapeSig(name.Func, r.dict))
+			} else {
+				todoDicts = append(todoDicts, func() {
+					r.dict.shapedObj = pr.objIdx(idx, implicits, explicits, true).(*ir.Name)
+				})
+			}
 		}
 
-		rext.funcExt(name)
+		rext.funcExt(name, nil)
 		return name
 
 	case pkgbits.ObjType:
 		name := do(ir.OTYPE, true)
 		typ := types.NewNamed(name)
 		setType(name, typ)
+		if r.hasTypeParams() && r.dict.shaped {
+			typ.SetHasShape(true)
+		}
 
 		// Important: We need to do this before SetUnderlying.
 		rext.typeExt(name)
@@ -670,6 +786,12 @@
 		typ.SetUnderlying(r.typWrapped(false))
 		types.ResumeCheckSize()
 
+		if r.hasTypeParams() && !r.dict.shaped {
+			todoDicts = append(todoDicts, func() {
+				r.dict.shapedObj = pr.objIdx(idx, implicits, explicits, true).(*ir.Name)
+			})
+		}
+
 		methods := make([]*types.Field, r.Len())
 		for i := range methods {
 			methods[i] = r.method(rext)
@@ -678,7 +800,9 @@
 			typ.Methods().Set(methods)
 		}
 
-		r.needWrapper(typ)
+		if !r.dict.shaped {
+			r.needWrapper(typ)
+		}
 
 		return name
 
@@ -690,17 +814,22 @@
 	}
 }
 
-func (r *reader) mangle(sym *types.Sym) *types.Sym {
-	if !r.hasTypeParams() {
+func (dict *readerDict) mangle(sym *types.Sym) *types.Sym {
+	if !dict.hasTypeParams() {
 		return sym
 	}
 
-	var buf bytes.Buffer
-	buf.WriteString(sym.Name)
+	// If sym is a locally defined generic type, we need the suffix to
+	// stay at the end after mangling so that types/fmt.go can strip it
+	// out again when writing the type's runtime descriptor (#54456).
+	base, suffix := types.SplitVargenSuffix(sym.Name)
+
+	var buf strings.Builder
+	buf.WriteString(base)
 	buf.WriteByte('[')
-	for i, targ := range r.dict.targs {
+	for i, targ := range dict.targs {
 		if i > 0 {
-			if i == r.dict.implicits {
+			if i == dict.implicits {
 				buf.WriteByte(';')
 			} else {
 				buf.WriteByte(',')
@@ -709,13 +838,72 @@
 		buf.WriteString(targ.LinkString())
 	}
 	buf.WriteByte(']')
+	buf.WriteString(suffix)
 	return sym.Pkg.Lookup(buf.String())
 }
 
-func (pr *pkgReader) objDictIdx(sym *types.Sym, idx pkgbits.Index, implicits, explicits []*types.Type) *readerDict {
+// shapify returns the shape type for targ.
+//
+// If basic is true, then the type argument is used to instantiate a
+// type parameter whose constraint is a basic interface.
+func shapify(targ *types.Type, basic bool) *types.Type {
+	if targ.Kind() == types.TFORW {
+		if targ.IsFullyInstantiated() {
+			// For recursive instantiated type argument, it may  still be a TFORW
+			// when shapifying happens. If we don't have targ's underlying type,
+			// shapify won't work. The worst case is we end up not reusing code
+			// optimally in some tricky cases.
+			if base.Debug.Shapify != 0 {
+				base.Warn("skipping shaping of recursive type %v", targ)
+			}
+			if targ.HasShape() {
+				return targ
+			}
+		} else {
+			base.Fatalf("%v is missing its underlying type", targ)
+		}
+	}
+
+	// When a pointer type is used to instantiate a type parameter
+	// constrained by a basic interface, we know the pointer's element
+	// type can't matter to the generated code. In this case, we can use
+	// an arbitrary pointer type as the shape type. (To match the
+	// non-unified frontend, we use `*byte`.)
+	//
+	// Otherwise, we simply use the type's underlying type as its shape.
+	//
+	// TODO(mdempsky): It should be possible to do much more aggressive
+	// shaping still; e.g., collapsing all pointer-shaped types into a
+	// common type, collapsing scalars of the same size/alignment into a
+	// common type, recursively shaping the element types of composite
+	// types, and discarding struct field names and tags. However, we'll
+	// need to start tracking how type parameters are actually used to
+	// implement some of these optimizations.
+	under := targ.Underlying()
+	if basic && targ.IsPtr() && !targ.Elem().NotInHeap() {
+		under = types.NewPtr(types.Types[types.TUINT8])
+	}
+
+	sym := types.ShapePkg.Lookup(under.LinkString())
+	if sym.Def == nil {
+		name := ir.NewDeclNameAt(under.Pos(), ir.OTYPE, sym)
+		typ := types.NewNamed(name)
+		typ.SetUnderlying(under)
+		sym.Def = typed(typ, name)
+	}
+	res := sym.Def.Type()
+	assert(res.IsShape())
+	assert(res.HasShape())
+	return res
+}
+
+// objDictIdx reads and returns the specified object dictionary.
+func (pr *pkgReader) objDictIdx(sym *types.Sym, idx pkgbits.Index, implicits, explicits []*types.Type, shaped bool) *readerDict {
 	r := pr.newReader(pkgbits.RelocObjDict, idx, pkgbits.SyncObject1)
 
-	var dict readerDict
+	dict := readerDict{
+		shaped: shaped,
+	}
 
 	nimplicits := r.Len()
 	nexplicits := r.Len()
@@ -727,15 +915,10 @@
 	dict.targs = append(implicits[:nimplicits:nimplicits], explicits...)
 	dict.implicits = nimplicits
 
-	// For stenciling, we can just skip over the type parameters.
+	// Within the compiler, we can just skip over the type parameters.
 	for range dict.targs[dict.implicits:] {
 		// Skip past bounds without actually evaluating them.
-		r.Sync(pkgbits.SyncType)
-		if r.Bool() {
-			r.Len()
-		} else {
-			r.Reloc(pkgbits.RelocType)
-		}
+		r.typInfo()
 	}
 
 	dict.derived = make([]derivedInfo, r.Len())
@@ -744,31 +927,51 @@
 		dict.derived[i] = derivedInfo{r.Reloc(pkgbits.RelocType), r.Bool()}
 	}
 
-	dict.funcs = make([]objInfo, r.Len())
-	dict.funcsObj = make([]ir.Node, len(dict.funcs))
-	for i := range dict.funcs {
-		objIdx := r.Reloc(pkgbits.RelocObj)
-		targs := make([]typeInfo, r.Len())
-		for j := range targs {
-			targs[j] = r.typInfo()
+	// Runtime dictionary information; private to the compiler.
+
+	// If any type argument is already shaped, then we're constructing a
+	// shaped object, even if not explicitly requested (i.e., calling
+	// objIdx with shaped==true). This can happen with instantiating
+	// types that are referenced within a function body.
+	for _, targ := range dict.targs {
+		if targ.HasShape() {
+			dict.shaped = true
+			break
 		}
-		dict.funcs[i] = objInfo{idx: objIdx, explicits: targs}
 	}
 
-	dict.itabs = make([]itabInfo2, r.Len())
-	for i := range dict.itabs {
-		typ := pr.typIdx(typeInfo{idx: pkgbits.Index(r.Len()), derived: true}, &dict, true)
-		ifaceInfo := r.typInfo()
-
-		var lsym *obj.LSym
-		if typ.IsInterface() {
-			lsym = reflectdata.TypeLinksym(typ)
-		} else {
-			iface := pr.typIdx(ifaceInfo, &dict, true)
-			lsym = reflectdata.ITabLsym(typ, iface)
+	// And if we're constructing a shaped object, then shapify all type
+	// arguments.
+	for i, targ := range dict.targs {
+		basic := r.Bool()
+		if dict.shaped {
+			dict.targs[i] = shapify(targ, basic)
 		}
+	}
 
-		dict.itabs[i] = itabInfo2{typ: typ, lsym: lsym}
+	dict.baseSym = dict.mangle(sym)
+
+	dict.typeParamMethodExprs = make([]readerMethodExprInfo, r.Len())
+	for i := range dict.typeParamMethodExprs {
+		typeParamIdx := r.Len()
+		_, method := r.selector()
+
+		dict.typeParamMethodExprs[i] = readerMethodExprInfo{typeParamIdx, method}
+	}
+
+	dict.subdicts = make([]objInfo, r.Len())
+	for i := range dict.subdicts {
+		dict.subdicts[i] = r.objInfo()
+	}
+
+	dict.rtypes = make([]typeInfo, r.Len())
+	for i := range dict.rtypes {
+		dict.rtypes[i] = r.typInfo()
+	}
+
+	dict.itabs = make([]itabInfo, r.Len())
+	for i := range dict.itabs {
+		dict.itabs[i] = itabInfo{typ: r.typInfo(), iface: r.typInfo()}
 	}
 
 	return &dict
@@ -791,9 +994,7 @@
 	_, recv := r.param()
 	typ := r.signature(pkg, recv)
 
-	fnsym := sym
-	fnsym = ir.MethodSym(recv.Type, fnsym)
-	name := ir.NewNameAt(pos, fnsym)
+	name := ir.NewNameAt(pos, ir.MethodSym(recv.Type, sym))
 	setType(name, typ)
 
 	name.Func = ir.NewFunc(r.pos())
@@ -801,9 +1002,13 @@
 
 	if r.hasTypeParams() {
 		name.Func.SetDupok(true)
+		if r.dict.shaped {
+			typ = shapeSig(name.Func, r.dict)
+			setType(name, typ)
+		}
 	}
 
-	rext.funcExt(name)
+	rext.funcExt(name, sym)
 
 	meth := types.NewField(name.Func.Pos(), sym, typ)
 	meth.Nname = name
@@ -852,7 +1057,7 @@
 
 // @@@ Compiler extensions
 
-func (r *reader) funcExt(name *ir.Name) {
+func (r *reader) funcExt(name *ir.Name, method *types.Sym) {
 	r.Sync(pkgbits.SyncFuncExt)
 
 	name.Class = 0 // so MarkFunc doesn't complain
@@ -882,6 +1087,8 @@
 	typecheck.Func(fn)
 
 	if r.Bool() {
+		assert(name.Defn == nil)
+
 		fn.ABI = obj.ABI(r.Uint64())
 
 		// Escape analysis.
@@ -896,10 +1103,9 @@
 				Cost:            int32(r.Len()),
 				CanDelayResults: r.Bool(),
 			}
-			r.addBody(name.Func)
 		}
 	} else {
-		r.addBody(name.Func)
+		r.addBody(name.Func, method)
 	}
 	r.Sync(pkgbits.SyncEOF)
 }
@@ -920,9 +1126,6 @@
 	}
 
 	name.SetPragma(r.pragmaFlag())
-	if name.Pragma()&ir.NotInHeap != 0 {
-		typ.SetNotInHeap(true)
-	}
 
 	typecheck.SetBaseTypeIndex(typ, r.Int64(), r.Int64())
 }
@@ -952,23 +1155,45 @@
 
 // @@@ Function bodies
 
-// bodyReader tracks where the serialized IR for a function's body can
-// be found.
+// bodyReader tracks where the serialized IR for a local or imported,
+// generic function's body can be found.
 var bodyReader = map[*ir.Func]pkgReaderIndex{}
 
+// importBodyReader tracks where the serialized IR for an imported,
+// static (i.e., non-generic) function body can be read.
+var importBodyReader = map[*types.Sym]pkgReaderIndex{}
+
+// bodyReaderFor returns the pkgReaderIndex for reading fn's
+// serialized IR, and whether one was found.
+func bodyReaderFor(fn *ir.Func) (pri pkgReaderIndex, ok bool) {
+	if fn.Nname.Defn != nil {
+		pri, ok = bodyReader[fn]
+		base.AssertfAt(ok, base.Pos, "must have bodyReader for %v", fn) // must always be available
+	} else {
+		pri, ok = importBodyReader[fn.Sym()]
+	}
+	return
+}
+
+// todoDicts holds the list of dictionaries that still need their
+// runtime dictionary objects constructed.
+var todoDicts []func()
+
 // todoBodies holds the list of function bodies that still need to be
 // constructed.
 var todoBodies []*ir.Func
 
-func (r *reader) addBody(fn *ir.Func) {
-	pri := pkgReaderIndex{r.p, r.Reloc(pkgbits.RelocBody), r.dict}
-	bodyReader[fn] = pri
+// addBody reads a function body reference from the element bitstream,
+// and associates it with fn.
+func (r *reader) addBody(fn *ir.Func, method *types.Sym) {
+	// addBody should only be called for local functions or imported
+	// generic functions; see comment in funcExt.
+	assert(fn.Nname.Defn != nil)
 
-	if fn.Nname.Defn == nil {
-		// Don't read in function body for imported functions.
-		// See comment in funcExt.
-		return
-	}
+	idx := r.Reloc(pkgbits.RelocBody)
+
+	pri := pkgReaderIndex{r.p, idx, r.dict, method, nil}
+	bodyReader[fn] = pri
 
 	if r.curfn == nil {
 		todoBodies = append(todoBodies, fn)
@@ -983,13 +1208,22 @@
 	r.funcBody(fn)
 }
 
+// funcBody reads a function body definition from the element
+// bitstream, and populates fn with it.
 func (r *reader) funcBody(fn *ir.Func) {
 	r.curfn = fn
 	r.closureVars = fn.ClosureVars
+	if len(r.closureVars) != 0 && r.hasTypeParams() {
+		r.dictParam = r.closureVars[len(r.closureVars)-1] // dictParam is last; see reader.funcLit
+	}
 
 	ir.WithFunc(fn, func() {
 		r.funcargs(fn)
 
+		if r.syntheticBody(fn.Pos()) {
+			return
+		}
+
 		if !r.Bool() {
 			return
 		}
@@ -1005,6 +1239,248 @@
 	r.marker.WriteTo(fn)
 }
 
+// syntheticBody adds a synthetic body to r.curfn if appropriate, and
+// reports whether it did.
+func (r *reader) syntheticBody(pos src.XPos) bool {
+	if r.synthetic != nil {
+		r.synthetic(pos, r)
+		return true
+	}
+
+	// If this function has type parameters and isn't shaped, then we
+	// just tail call its corresponding shaped variant.
+	if r.hasTypeParams() && !r.dict.shaped {
+		r.callShaped(pos)
+		return true
+	}
+
+	return false
+}
+
+// callShaped emits a tail call to r.shapedFn, passing along the
+// arguments to the current function.
+func (r *reader) callShaped(pos src.XPos) {
+	shapedObj := r.dict.shapedObj
+	assert(shapedObj != nil)
+
+	var shapedFn ir.Node
+	if r.methodSym == nil {
+		// Instantiating a generic function; shapedObj is the shaped
+		// function itself.
+		assert(shapedObj.Op() == ir.ONAME && shapedObj.Class == ir.PFUNC)
+		shapedFn = shapedObj
+	} else {
+		// Instantiating a generic type's method; shapedObj is the shaped
+		// type, so we need to select it's corresponding method.
+		shapedFn = shapedMethodExpr(pos, shapedObj, r.methodSym)
+	}
+
+	recvs, params := r.syntheticArgs(pos)
+
+	// Construct the arguments list: receiver (if any), then runtime
+	// dictionary, and finally normal parameters.
+	//
+	// Note: For simplicity, shaped methods are added as normal methods
+	// on their shaped types. So existing code (e.g., packages ir and
+	// typecheck) expects the shaped type to appear as the receiver
+	// parameter (or first parameter, as a method expression). Hence
+	// putting the dictionary parameter after that is the least invasive
+	// solution at the moment.
+	var args ir.Nodes
+	args.Append(recvs...)
+	args.Append(typecheck.Expr(ir.NewAddrExpr(pos, r.p.dictNameOf(r.dict))))
+	args.Append(params...)
+
+	r.syntheticTailCall(pos, shapedFn, args)
+}
+
+// syntheticArgs returns the recvs and params arguments passed to the
+// current function.
+func (r *reader) syntheticArgs(pos src.XPos) (recvs, params ir.Nodes) {
+	sig := r.curfn.Nname.Type()
+
+	inlVarIdx := 0
+	addParams := func(out *ir.Nodes, params []*types.Field) {
+		for _, param := range params {
+			var arg ir.Node
+			if param.Nname != nil {
+				name := param.Nname.(*ir.Name)
+				if !ir.IsBlank(name) {
+					if r.inlCall != nil {
+						// During inlining, we want the respective inlvar where we
+						// assigned the callee's arguments.
+						arg = r.inlvars[inlVarIdx]
+					} else {
+						// Otherwise, we can use the parameter itself directly.
+						base.AssertfAt(name.Curfn == r.curfn, name.Pos(), "%v has curfn %v, but want %v", name, name.Curfn, r.curfn)
+						arg = name
+					}
+				}
+			}
+
+			// For anonymous and blank parameters, we don't have an *ir.Name
+			// to use as the argument. However, since we know the shaped
+			// function won't use the value either, we can just pass the
+			// zero value. (Also unfortunately, we don't have an easy
+			// zero-value IR node; so we use a default-initialized temporary
+			// variable.)
+			if arg == nil {
+				tmp := typecheck.TempAt(pos, r.curfn, param.Type)
+				r.curfn.Body.Append(
+					typecheck.Stmt(ir.NewDecl(pos, ir.ODCL, tmp)),
+					typecheck.Stmt(ir.NewAssignStmt(pos, tmp, nil)),
+				)
+				arg = tmp
+			}
+
+			out.Append(arg)
+			inlVarIdx++
+		}
+	}
+
+	addParams(&recvs, sig.Recvs().FieldSlice())
+	addParams(&params, sig.Params().FieldSlice())
+	return
+}
+
+// syntheticTailCall emits a tail call to fn, passing the given
+// arguments list.
+func (r *reader) syntheticTailCall(pos src.XPos, fn ir.Node, args ir.Nodes) {
+	// Mark the function as a wrapper so it doesn't show up in stack
+	// traces.
+	r.curfn.SetWrapper(true)
+
+	call := typecheck.Call(pos, fn, args, fn.Type().IsVariadic()).(*ir.CallExpr)
+
+	var stmt ir.Node
+	if fn.Type().NumResults() != 0 {
+		stmt = typecheck.Stmt(ir.NewReturnStmt(pos, []ir.Node{call}))
+	} else {
+		stmt = call
+	}
+	r.curfn.Body.Append(stmt)
+}
+
+// dictNameOf returns the runtime dictionary corresponding to dict.
+func (pr *pkgReader) dictNameOf(dict *readerDict) *ir.Name {
+	pos := base.AutogeneratedPos
+
+	// Check that we only instantiate runtime dictionaries with real types.
+	base.AssertfAt(!dict.shaped, pos, "runtime dictionary of shaped object %v", dict.baseSym)
+
+	sym := dict.baseSym.Pkg.Lookup(objabi.GlobalDictPrefix + "." + dict.baseSym.Name)
+	if sym.Def != nil {
+		return sym.Def.(*ir.Name)
+	}
+
+	name := ir.NewNameAt(pos, sym)
+	name.Class = ir.PEXTERN
+	sym.Def = name // break cycles with mutual subdictionaries
+
+	lsym := name.Linksym()
+	ot := 0
+
+	assertOffset := func(section string, offset int) {
+		base.AssertfAt(ot == offset*types.PtrSize, pos, "writing section %v at offset %v, but it should be at %v*%v", section, ot, offset, types.PtrSize)
+	}
+
+	assertOffset("type param method exprs", dict.typeParamMethodExprsOffset())
+	for _, info := range dict.typeParamMethodExprs {
+		typeParam := dict.targs[info.typeParamIdx]
+		method := typecheck.Expr(ir.NewSelectorExpr(pos, ir.OXDOT, ir.TypeNode(typeParam), info.method)).(*ir.SelectorExpr)
+		assert(method.Op() == ir.OMETHEXPR)
+
+		rsym := method.FuncName().Linksym()
+		assert(rsym.ABI() == obj.ABIInternal) // must be ABIInternal; see ir.OCFUNC in ssagen/ssa.go
+
+		ot = objw.SymPtr(lsym, ot, rsym, 0)
+	}
+
+	assertOffset("subdictionaries", dict.subdictsOffset())
+	for _, info := range dict.subdicts {
+		explicits := pr.typListIdx(info.explicits, dict)
+
+		// Careful: Due to subdictionary cycles, name may not be fully
+		// initialized yet.
+		name := pr.objDictName(info.idx, dict.targs, explicits)
+
+		ot = objw.SymPtr(lsym, ot, name.Linksym(), 0)
+	}
+
+	assertOffset("rtypes", dict.rtypesOffset())
+	for _, info := range dict.rtypes {
+		typ := pr.typIdx(info, dict, true)
+		ot = objw.SymPtr(lsym, ot, reflectdata.TypeLinksym(typ), 0)
+
+		// TODO(mdempsky): Double check this.
+		reflectdata.MarkTypeUsedInInterface(typ, lsym)
+	}
+
+	// For each (typ, iface) pair, we write the *runtime.itab pointer
+	// for the pair. For pairs that don't actually require an itab
+	// (i.e., typ is an interface, or iface is an empty interface), we
+	// write a nil pointer instead. This is wasteful, but rare in
+	// practice (e.g., instantiating a type parameter with an interface
+	// type).
+	assertOffset("itabs", dict.itabsOffset())
+	for _, info := range dict.itabs {
+		typ := pr.typIdx(info.typ, dict, true)
+		iface := pr.typIdx(info.iface, dict, true)
+
+		if !typ.IsInterface() && iface.IsInterface() && !iface.IsEmptyInterface() {
+			ot = objw.SymPtr(lsym, ot, reflectdata.ITabLsym(typ, iface), 0)
+		} else {
+			ot += types.PtrSize
+		}
+
+		// TODO(mdempsky): Double check this.
+		reflectdata.MarkTypeUsedInInterface(typ, lsym)
+		reflectdata.MarkTypeUsedInInterface(iface, lsym)
+	}
+
+	objw.Global(lsym, int32(ot), obj.DUPOK|obj.RODATA)
+
+	name.SetType(dict.varType())
+	name.SetTypecheck(1)
+
+	return name
+}
+
+// typeParamMethodExprsOffset returns the offset of the runtime
+// dictionary's type parameter method expressions section, in words.
+func (dict *readerDict) typeParamMethodExprsOffset() int {
+	return 0
+}
+
+// subdictsOffset returns the offset of the runtime dictionary's
+// subdictionary section, in words.
+func (dict *readerDict) subdictsOffset() int {
+	return dict.typeParamMethodExprsOffset() + len(dict.typeParamMethodExprs)
+}
+
+// rtypesOffset returns the offset of the runtime dictionary's rtypes
+// section, in words.
+func (dict *readerDict) rtypesOffset() int {
+	return dict.subdictsOffset() + len(dict.subdicts)
+}
+
+// itabsOffset returns the offset of the runtime dictionary's itabs
+// section, in words.
+func (dict *readerDict) itabsOffset() int {
+	return dict.rtypesOffset() + len(dict.rtypes)
+}
+
+// numWords returns the total number of words that comprise dict's
+// runtime dictionary variable.
+func (dict *readerDict) numWords() int64 {
+	return int64(dict.itabsOffset() + len(dict.itabs))
+}
+
+// varType returns the type of dict's runtime dictionary variable.
+func (dict *readerDict) varType() *types.Type {
+	return types.NewArray(types.Types[types.TUINTPTR], dict.numWords())
+}
+
 func (r *reader) funcargs(fn *ir.Func) {
 	sig := fn.Nname.Type()
 
@@ -1041,7 +1517,7 @@
 		return
 	}
 
-	name := ir.NewNameAt(r.updatePos(param.Pos), sym)
+	name := ir.NewNameAt(r.inlPos(param.Pos), sym)
 	setType(name, param.Type)
 	r.addLocal(name, ctxt)
 
@@ -1062,16 +1538,24 @@
 func (r *reader) addLocal(name *ir.Name, ctxt ir.Class) {
 	assert(ctxt == ir.PAUTO || ctxt == ir.PPARAM || ctxt == ir.PPARAMOUT)
 
-	r.Sync(pkgbits.SyncAddLocal)
-	if pkgbits.EnableSync {
-		want := r.Int()
-		if have := len(r.locals); have != want {
-			base.FatalfAt(name.Pos(), "locals table has desynced")
+	if name.Sym().Name == dictParamName {
+		r.dictParam = name
+	} else {
+		if r.synthetic == nil {
+			r.Sync(pkgbits.SyncAddLocal)
+			if r.p.SyncMarkers() {
+				want := r.Int()
+				if have := len(r.locals); have != want {
+					base.FatalfAt(name.Pos(), "locals table has desynced")
+				}
+			}
+			r.varDictIndex(name)
 		}
+
+		r.locals = append(r.locals, name)
 	}
 
 	name.SetUsed(true)
-	r.locals = append(r.locals, name)
 
 	// TODO(mdempsky): Move earlier.
 	if ir.IsBlank(name) {
@@ -1229,11 +1713,8 @@
 
 	case stmtAssign:
 		pos := r.pos()
-
-		// TODO(mdempsky): After quirks mode is gone, swap these
-		// statements so we visit LHS before RHS again.
-		rhs := r.exprList()
 		names, lhs := r.assignList()
+		rhs := r.multiExpr()
 
 		if len(rhs) == 0 {
 			for _, name := range names {
@@ -1301,7 +1782,7 @@
 
 	case stmtReturn:
 		pos := r.pos()
-		results := r.exprList()
+		results := r.multiExpr()
 		return ir.NewReturnStmt(pos, results)
 
 	case stmtSelect:
@@ -1323,25 +1804,42 @@
 	var names []*ir.Name
 
 	for i := range lhs {
-		if r.Bool() {
-			pos := r.pos()
-			_, sym := r.localIdent()
-			typ := r.typ()
-
-			name := ir.NewNameAt(pos, sym)
-			lhs[i] = name
-			names = append(names, name)
-			setType(name, typ)
-			r.addLocal(name, ir.PAUTO)
-			continue
+		expr, def := r.assign()
+		lhs[i] = expr
+		if def {
+			names = append(names, expr.(*ir.Name))
 		}
-
-		lhs[i] = r.expr()
 	}
 
 	return names, lhs
 }
 
+// assign returns an assignee expression. It also reports whether the
+// returned expression is a newly declared variable.
+func (r *reader) assign() (ir.Node, bool) {
+	switch tag := codeAssign(r.Code(pkgbits.SyncAssign)); tag {
+	default:
+		panic("unhandled assignee expression")
+
+	case assignBlank:
+		return typecheck.AssignExpr(ir.BlankNode), false
+
+	case assignDef:
+		pos := r.pos()
+		setBasePos(pos)
+		_, sym := r.localIdent()
+		typ := r.typ()
+
+		name := ir.NewNameAt(pos, sym)
+		setType(name, typ)
+		r.addLocal(name, ir.PAUTO)
+		return name, true
+
+	case assignExpr:
+		return r.expr(), false
+	}
+}
+
 func (r *reader) blockStmt() []ir.Node {
 	r.Sync(pkgbits.SyncBlockStmt)
 	r.openScope()
@@ -1357,16 +1855,10 @@
 
 	if r.Bool() {
 		pos := r.pos()
+		rang := ir.NewRangeStmt(pos, nil, nil, nil, nil)
+		rang.Label = label
 
-		// TODO(mdempsky): After quirks mode is gone, swap these
-		// statements so we read LHS before X again.
-		x := r.expr()
 		names, lhs := r.assignList()
-
-		body := r.blockStmt()
-		r.closeAnotherScope()
-
-		rang := ir.NewRangeStmt(pos, nil, nil, x, body)
 		if len(lhs) >= 1 {
 			rang.Key = lhs[0]
 			if len(lhs) >= 2 {
@@ -1374,13 +1866,27 @@
 			}
 		}
 		rang.Def = r.initDefn(rang, names)
-		rang.Label = label
+
+		rang.X = r.expr()
+		if rang.X.Type().IsMap() {
+			rang.RType = r.rtype(pos)
+		}
+		if rang.Key != nil && !ir.IsBlank(rang.Key) {
+			rang.KeyTypeWord, rang.KeySrcRType = r.convRTTI(pos)
+		}
+		if rang.Value != nil && !ir.IsBlank(rang.Value) {
+			rang.ValueTypeWord, rang.ValueSrcRType = r.convRTTI(pos)
+		}
+
+		rang.Body = r.blockStmt()
+		r.closeAnotherScope()
+
 		return rang
 	}
 
 	pos := r.pos()
 	init := r.stmt()
-	cond := r.expr()
+	cond := r.optExpr()
 	post := r.stmt()
 	body := r.blockStmt()
 	r.closeAnotherScope()
@@ -1419,6 +1925,44 @@
 		comm := r.stmt()
 		body := r.stmts()
 
+		// "case i = <-c: ..." may require an implicit conversion (e.g.,
+		// see fixedbugs/bug312.go). Currently, typecheck throws away the
+		// implicit conversion and relies on it being reinserted later,
+		// but that would lose any explicit RTTI operands too. To preserve
+		// RTTI, we rewrite this as "case tmp := <-c: i = tmp; ...".
+		if as, ok := comm.(*ir.AssignStmt); ok && as.Op() == ir.OAS && !as.Def {
+			if conv, ok := as.Y.(*ir.ConvExpr); ok && conv.Op() == ir.OCONVIFACE {
+				base.AssertfAt(conv.Implicit(), conv.Pos(), "expected implicit conversion: %v", conv)
+
+				recv := conv.X
+				base.AssertfAt(recv.Op() == ir.ORECV, recv.Pos(), "expected receive expression: %v", recv)
+
+				tmp := r.temp(pos, recv.Type())
+
+				// Replace comm with `tmp := <-c`.
+				tmpAs := ir.NewAssignStmt(pos, tmp, recv)
+				tmpAs.Def = true
+				tmpAs.PtrInit().Append(ir.NewDecl(pos, ir.ODCL, tmp))
+				comm = tmpAs
+
+				// Change original assignment to `i = tmp`, and prepend to body.
+				conv.X = tmp
+				body = append([]ir.Node{as}, body...)
+			}
+		}
+
+		// multiExpr will have desugared a comma-ok receive expression
+		// into a separate statement. However, the rest of the compiler
+		// expects comm to be the OAS2RECV statement itself, so we need to
+		// shuffle things around to fit that pattern.
+		if as2, ok := comm.(*ir.AssignListStmt); ok && as2.Op() == ir.OAS2 {
+			init := ir.TakeInit(as2.Rhs[0])
+			base.AssertfAt(len(init) == 1 && init[0].Op() == ir.OAS2RECV, as2.Pos(), "unexpected assignment: %+v", as2)
+
+			comm = init[0]
+			body = append([]ir.Node{as2}, body...)
+		}
+
 		clauses[i] = ir.NewCommStmt(pos, comm, body)
 	}
 	if len(clauses) > 0 {
@@ -1443,14 +1987,14 @@
 		pos := r.pos()
 		if r.Bool() {
 			pos := r.pos()
-			sym := typecheck.Lookup(r.String())
+			_, sym := r.localIdent()
 			ident = ir.NewIdent(pos, sym)
 		}
 		x := r.expr()
 		iface = x.Type()
 		tag = ir.NewTypeSwitchGuard(pos, ident, x)
 	} else {
-		tag = r.expr()
+		tag = r.optExpr()
 	}
 
 	clauses := make([]*ir.CaseClause, r.Len())
@@ -1461,20 +2005,43 @@
 		r.openScope()
 
 		pos := r.pos()
-		var cases []ir.Node
+		var cases, rtypes []ir.Node
 		if iface != nil {
 			cases = make([]ir.Node, r.Len())
 			if len(cases) == 0 {
 				cases = nil // TODO(mdempsky): Unclear if this matters.
 			}
 			for i := range cases {
-				cases[i] = r.exprType(true)
+				if r.Bool() { // case nil
+					cases[i] = typecheck.Expr(types.BuiltinPkg.Lookup("nil").Def.(*ir.NilExpr))
+				} else {
+					cases[i] = r.exprType()
+				}
 			}
 		} else {
 			cases = r.exprList()
+
+			// For `switch { case any(true): }` (e.g., issue 3980 in
+			// test/switch.go), the backend still creates a mixed bool/any
+			// comparison, and we need to explicitly supply the RTTI for the
+			// comparison.
+			//
+			// TODO(mdempsky): Change writer.go to desugar "switch {" into
+			// "switch true {", which we already handle correctly.
+			if tag == nil {
+				for i, cas := range cases {
+					if cas.Type().IsEmptyInterface() {
+						for len(rtypes) < i {
+							rtypes = append(rtypes, nil)
+						}
+						rtypes = append(rtypes, reflectdata.TypePtrAt(cas.Pos(), types.Types[types.TBOOL]))
+					}
+				}
+			}
 		}
 
 		clause := ir.NewCaseStmt(pos, cases, nil)
+		clause.RTypes = rtypes
 
 		if ident != nil {
 			pos := r.pos()
@@ -1551,24 +2118,21 @@
 	default:
 		panic("unhandled expression")
 
-	case exprNone:
-		return nil
-
-	case exprBlank:
-		// blank only allowed in LHS of assignments
-		// TODO(mdempsky): Handle directly in assignList instead?
-		return typecheck.AssignExpr(ir.BlankNode)
-
 	case exprLocal:
 		return typecheck.Expr(r.useLocal())
 
-	case exprName:
+	case exprGlobal:
 		// Callee instead of Expr allows builtins
 		// TODO(mdempsky): Handle builtins directly in exprCall, like method calls?
 		return typecheck.Callee(r.obj())
 
-	case exprType:
-		return r.exprType(false)
+	case exprFuncInst:
+		origPos, pos := r.origPos()
+		wrapperFn, baseFn, dictPtr := r.funcInst(pos)
+		if wrapperFn != nil {
+			return wrapperFn
+		}
+		return r.curry(origPos, false, baseFn, dictPtr, nil)
 
 	case exprConst:
 		pos := r.pos()
@@ -1578,51 +2142,145 @@
 		orig := r.String()
 		return typecheck.Expr(OrigConst(pos, typ, val, op, orig))
 
+	case exprNil:
+		pos := r.pos()
+		typ := r.typ()
+		return Nil(pos, typ)
+
 	case exprCompLit:
 		return r.compLit()
 
 	case exprFuncLit:
 		return r.funcLit()
 
-	case exprSelector:
+	case exprFieldVal:
 		x := r.expr()
 		pos := r.pos()
 		_, sym := r.selector()
 
-		// Method expression with derived receiver type.
-		if x.Op() == ir.ODYNAMICTYPE {
-			// TODO(mdempsky): Handle with runtime dictionary lookup.
-			n := ir.TypeNode(x.Type())
-			n.SetTypecheck(1)
-			x = n
-		}
+		return typecheck.Expr(ir.NewSelectorExpr(pos, ir.OXDOT, x, sym)).(*ir.SelectorExpr)
 
-		n := typecheck.Expr(ir.NewSelectorExpr(pos, ir.OXDOT, x, sym)).(*ir.SelectorExpr)
-		if n.Op() == ir.OMETHVALUE {
+	case exprMethodVal:
+		recv := r.expr()
+		origPos, pos := r.origPos()
+		wrapperFn, baseFn, dictPtr := r.methodExpr()
+
+		// For simple wrapperFn values, the existing machinery for creating
+		// and deduplicating wrapperFn value wrappers still works fine.
+		if wrapperFn, ok := wrapperFn.(*ir.SelectorExpr); ok && wrapperFn.Op() == ir.OMETHEXPR {
+			// The receiver expression we constructed may have a shape type.
+			// For example, in fixedbugs/issue54343.go, `New[int]()` is
+			// constructed as `New[go.shape.int](&.dict.New[int])`, which
+			// has type `*T[go.shape.int]`, not `*T[int]`.
+			//
+			// However, the method we want to select here is `(*T[int]).M`,
+			// not `(*T[go.shape.int]).M`, so we need to manually convert
+			// the type back so that the OXDOT resolves correctly.
+			//
+			// TODO(mdempsky): Logically it might make more sense for
+			// exprCall to take responsibility for setting a non-shaped
+			// result type, but this is the only place where we care
+			// currently. And only because existing ir.OMETHVALUE backend
+			// code relies on n.X.Type() instead of n.Selection.Recv().Type
+			// (because the latter is types.FakeRecvType() in the case of
+			// interface method values).
+			//
+			if recv.Type().HasShape() {
+				typ := wrapperFn.Type().Params().Field(0).Type
+				if !types.Identical(typ, recv.Type()) {
+					base.FatalfAt(wrapperFn.Pos(), "receiver %L does not match %L", recv, wrapperFn)
+				}
+				recv = typecheck.Expr(ir.NewConvExpr(recv.Pos(), ir.OCONVNOP, typ, recv))
+			}
+
+			n := typecheck.Expr(ir.NewSelectorExpr(pos, ir.OXDOT, recv, wrapperFn.Sel)).(*ir.SelectorExpr)
+
+			// As a consistency check here, we make sure "n" selected the
+			// same method (represented by a types.Field) that wrapperFn
+			// selected. However, for anonymous receiver types, there can be
+			// multiple such types.Field instances (#58563). So we may need
+			// to fallback to making sure Sym and Type (including the
+			// receiver parameter's type) match.
+			if n.Selection != wrapperFn.Selection {
+				assert(n.Selection.Sym == wrapperFn.Selection.Sym)
+				assert(types.Identical(n.Selection.Type, wrapperFn.Selection.Type))
+				assert(types.Identical(n.Selection.Type.Recv().Type, wrapperFn.Selection.Type.Recv().Type))
+			}
+
 			wrapper := methodValueWrapper{
 				rcvr:   n.X.Type(),
 				method: n.Selection,
 			}
+
 			if r.importedDef() {
 				haveMethodValueWrappers = append(haveMethodValueWrappers, wrapper)
 			} else {
 				needMethodValueWrappers = append(needMethodValueWrappers, wrapper)
 			}
+			return n
 		}
-		return n
+
+		// For more complicated method expressions, we construct a
+		// function literal wrapper.
+		return r.curry(origPos, true, baseFn, recv, dictPtr)
+
+	case exprMethodExpr:
+		recv := r.typ()
+
+		implicits := make([]int, r.Len())
+		for i := range implicits {
+			implicits[i] = r.Len()
+		}
+		var deref, addr bool
+		if r.Bool() {
+			deref = true
+		} else if r.Bool() {
+			addr = true
+		}
+
+		origPos, pos := r.origPos()
+		wrapperFn, baseFn, dictPtr := r.methodExpr()
+
+		// If we already have a wrapper and don't need to do anything with
+		// it, we can just return the wrapper directly.
+		//
+		// N.B., we use implicits/deref/addr here as the source of truth
+		// rather than types.Identical, because the latter can be confused
+		// by tricky promoted methods (e.g., typeparam/mdempsky/21.go).
+		if wrapperFn != nil && len(implicits) == 0 && !deref && !addr {
+			if !types.Identical(recv, wrapperFn.Type().Params().Field(0).Type) {
+				base.FatalfAt(pos, "want receiver type %v, but have method %L", recv, wrapperFn)
+			}
+			return wrapperFn
+		}
+
+		// Otherwise, if the wrapper function is a static method
+		// expression (OMETHEXPR) and the receiver type is unshaped, then
+		// we can rely on a statically generated wrapper being available.
+		if method, ok := wrapperFn.(*ir.SelectorExpr); ok && method.Op() == ir.OMETHEXPR && !recv.HasShape() {
+			return typecheck.Expr(ir.NewSelectorExpr(pos, ir.OXDOT, ir.TypeNode(recv), method.Sel)).(*ir.SelectorExpr)
+		}
+
+		return r.methodExprWrap(origPos, recv, implicits, deref, addr, baseFn, dictPtr)
 
 	case exprIndex:
 		x := r.expr()
 		pos := r.pos()
 		index := r.expr()
-		return typecheck.Expr(ir.NewIndexExpr(pos, x, index))
+		n := typecheck.Expr(ir.NewIndexExpr(pos, x, index))
+		switch n.Op() {
+		case ir.OINDEXMAP:
+			n := n.(*ir.IndexExpr)
+			n.RType = r.rtype(pos)
+		}
+		return n
 
 	case exprSlice:
 		x := r.expr()
 		pos := r.pos()
 		var index [3]ir.Node
 		for i := range index {
-			index[i] = r.expr()
+			index[i] = r.optExpr()
 		}
 		op := ir.OSLICE
 		if index[2] != nil {
@@ -1633,10 +2291,13 @@
 	case exprAssert:
 		x := r.expr()
 		pos := r.pos()
-		typ := r.exprType(false)
+		typ := r.exprType()
+		srcRType := r.rtype(pos)
 
+		// TODO(mdempsky): Always emit ODYNAMICDOTTYPE for uniformity?
 		if typ, ok := typ.(*ir.DynamicType); ok && typ.Op() == ir.ODYNAMICTYPE {
 			assert := ir.NewDynamicTypeAssertExpr(pos, ir.ODYNAMICDOTTYPE, x, typ.RType)
+			assert.SrcRType = srcRType
 			assert.ITab = typ.ITab
 			return typed(typ.Type(), assert)
 		}
@@ -1667,40 +2328,694 @@
 		}
 		return typecheck.Expr(ir.NewBinaryExpr(pos, op, x, y))
 
+	case exprRecv:
+		x := r.expr()
+		pos := r.pos()
+		for i, n := 0, r.Len(); i < n; i++ {
+			x = Implicit(DotField(pos, x, r.Len()))
+		}
+		if r.Bool() { // needs deref
+			x = Implicit(Deref(pos, x.Type().Elem(), x))
+		} else if r.Bool() { // needs addr
+			x = Implicit(Addr(pos, x))
+		}
+		return x
+
 	case exprCall:
-		fun := r.expr()
+		var fun ir.Node
+		var args ir.Nodes
 		if r.Bool() { // method call
+			recv := r.expr()
+			_, method, dictPtr := r.methodExpr()
+
+			if recv.Type().IsInterface() && method.Op() == ir.OMETHEXPR {
+				method := method.(*ir.SelectorExpr)
+
+				// The compiler backend (e.g., devirtualization) handle
+				// OCALLINTER/ODOTINTER better than OCALLFUNC/OMETHEXPR for
+				// interface calls, so we prefer to continue constructing
+				// calls that way where possible.
+				//
+				// There are also corner cases where semantically it's perhaps
+				// significant; e.g., fixedbugs/issue15975.go, #38634, #52025.
+
+				fun = typecheck.Callee(ir.NewSelectorExpr(method.Pos(), ir.OXDOT, recv, method.Sel))
+			} else {
+				if recv.Type().IsInterface() {
+					// N.B., this happens currently for typeparam/issue51521.go
+					// and typeparam/typeswitch3.go.
+					if base.Flag.LowerM > 0 {
+						base.WarnfAt(method.Pos(), "imprecise interface call")
+					}
+				}
+
+				fun = method
+				args.Append(recv)
+			}
+			if dictPtr != nil {
+				args.Append(dictPtr)
+			}
+		} else if r.Bool() { // call to instanced function
 			pos := r.pos()
-			_, sym := r.selector()
-			fun = typecheck.Callee(ir.NewSelectorExpr(pos, ir.OXDOT, fun, sym))
+			_, shapedFn, dictPtr := r.funcInst(pos)
+			fun = shapedFn
+			args.Append(dictPtr)
+		} else {
+			fun = r.expr()
 		}
 		pos := r.pos()
-		args := r.exprs()
+		args.Append(r.multiExpr()...)
 		dots := r.Bool()
-		return typecheck.Call(pos, fun, args, dots)
+		n := typecheck.Call(pos, fun, args, dots)
+		switch n.Op() {
+		case ir.OAPPEND:
+			n := n.(*ir.CallExpr)
+			n.RType = r.rtype(pos)
+			// For append(a, b...), we don't need the implicit conversion. The typechecker already
+			// ensured that a and b are both slices with the same base type, or []byte and string.
+			if n.IsDDD {
+				if conv, ok := n.Args[1].(*ir.ConvExpr); ok && conv.Op() == ir.OCONVNOP && conv.Implicit() {
+					n.Args[1] = conv.X
+				}
+			}
+		case ir.OCOPY:
+			n := n.(*ir.BinaryExpr)
+			n.RType = r.rtype(pos)
+		case ir.ODELETE:
+			n := n.(*ir.CallExpr)
+			n.RType = r.rtype(pos)
+		case ir.OUNSAFESLICE:
+			n := n.(*ir.BinaryExpr)
+			n.RType = r.rtype(pos)
+		}
+		return n
+
+	case exprMake:
+		pos := r.pos()
+		typ := r.exprType()
+		extra := r.exprs()
+		n := typecheck.Expr(ir.NewCallExpr(pos, ir.OMAKE, nil, append([]ir.Node{typ}, extra...))).(*ir.MakeExpr)
+		n.RType = r.rtype(pos)
+		return n
+
+	case exprNew:
+		pos := r.pos()
+		typ := r.exprType()
+		return typecheck.Expr(ir.NewUnaryExpr(pos, ir.ONEW, typ))
+
+	case exprReshape:
+		typ := r.typ()
+		x := r.expr()
+
+		if types.IdenticalStrict(x.Type(), typ) {
+			return x
+		}
+
+		// Comparison expressions are constructed as "untyped bool" still.
+		//
+		// TODO(mdempsky): It should be safe to reshape them here too, but
+		// maybe it's better to construct them with the proper type
+		// instead.
+		if x.Type() == types.UntypedBool && typ.IsBoolean() {
+			return x
+		}
+
+		base.AssertfAt(x.Type().HasShape() || typ.HasShape(), x.Pos(), "%L and %v are not shape types", x, typ)
+		base.AssertfAt(types.Identical(x.Type(), typ), x.Pos(), "%L is not shape-identical to %v", x, typ)
+
+		// We use ir.HasUniquePos here as a check that x only appears once
+		// in the AST, so it's okay for us to call SetType without
+		// breaking any other uses of it.
+		//
+		// Notably, any ONAMEs should already have the exactly right shape
+		// type and been caught by types.IdenticalStrict above.
+		base.AssertfAt(ir.HasUniquePos(x), x.Pos(), "cannot call SetType(%v) on %L", typ, x)
+
+		if base.Debug.Reshape != 0 {
+			base.WarnfAt(x.Pos(), "reshaping %L to %v", x, typ)
+		}
+
+		x.SetType(typ)
+		return x
 
 	case exprConvert:
+		implicit := r.Bool()
 		typ := r.typ()
 		pos := r.pos()
+		typeWord, srcRType := r.convRTTI(pos)
+		dstTypeParam := r.Bool()
+		identical := r.Bool()
 		x := r.expr()
 
 		// TODO(mdempsky): Stop constructing expressions of untyped type.
 		x = typecheck.DefaultLit(x, typ)
 
-		if op, why := typecheck.Convertop(x.Op() == ir.OLITERAL, x.Type(), typ); op == ir.OXXX {
-			// types2 ensured that x is convertable to typ under standard Go
-			// semantics, but cmd/compile also disallows some conversions
-			// involving //go:notinheap.
-			//
-			// TODO(mdempsky): This can be removed after #46731 is implemented.
-			base.ErrorfAt(pos, "cannot convert %L to type %v%v", x, typ, why)
-			base.ErrorExit() // harsh, but prevents constructing invalid IR
+		ce := ir.NewConvExpr(pos, ir.OCONV, typ, x)
+		ce.TypeWord, ce.SrcRType = typeWord, srcRType
+		if implicit {
+			ce.SetImplicit(true)
+		}
+		n := typecheck.Expr(ce)
+
+		// Conversions between non-identical, non-empty interfaces always
+		// requires a runtime call, even if they have identical underlying
+		// interfaces. This is because we create separate itab instances
+		// for each unique interface type, not merely each unique
+		// interface shape.
+		//
+		// However, due to shape types, typecheck.Expr might mistakenly
+		// think a conversion between two non-empty interfaces are
+		// identical and set ir.OCONVNOP, instead of ir.OCONVIFACE. To
+		// ensure we update the itab field appropriately, we force it to
+		// ir.OCONVIFACE instead when shape types are involved.
+		//
+		// TODO(mdempsky): Are there other places we might get this wrong?
+		// Should this be moved down into typecheck.{Assign,Convert}op?
+		// This would be a non-issue if itabs were unique for each
+		// *underlying* interface type instead.
+		if !identical {
+			if n, ok := n.(*ir.ConvExpr); ok && n.Op() == ir.OCONVNOP && n.Type().IsInterface() && !n.Type().IsEmptyInterface() && (n.Type().HasShape() || n.X.Type().HasShape()) {
+				n.SetOp(ir.OCONVIFACE)
+			}
 		}
 
-		return typecheck.Expr(ir.NewConvExpr(pos, ir.OCONV, typ, x))
+		// spec: "If the type is a type parameter, the constant is converted
+		// into a non-constant value of the type parameter."
+		if dstTypeParam && ir.IsConstNode(n) {
+			// Wrap in an OCONVNOP node to ensure result is non-constant.
+			n = Implicit(ir.NewConvExpr(pos, ir.OCONVNOP, n.Type(), n))
+			n.SetTypecheck(1)
+		}
+		return n
 	}
 }
 
+// funcInst reads an instantiated function reference, and returns
+// three (possibly nil) expressions related to it:
+//
+// baseFn is always non-nil: it's either a function of the appropriate
+// type already, or it has an extra dictionary parameter as the first
+// parameter.
+//
+// If dictPtr is non-nil, then it's a dictionary argument that must be
+// passed as the first argument to baseFn.
+//
+// If wrapperFn is non-nil, then it's either the same as baseFn (if
+// dictPtr is nil), or it's semantically equivalent to currying baseFn
+// to pass dictPtr. (wrapperFn is nil when dictPtr is an expression
+// that needs to be computed dynamically.)
+//
+// For callers that are creating a call to the returned function, it's
+// best to emit a call to baseFn, and include dictPtr in the arguments
+// list as appropriate.
+//
+// For callers that want to return the function without invoking it,
+// they may return wrapperFn if it's non-nil; but otherwise, they need
+// to create their own wrapper.
+func (r *reader) funcInst(pos src.XPos) (wrapperFn, baseFn, dictPtr ir.Node) {
+	// Like in methodExpr, I'm pretty sure this isn't needed.
+	var implicits []*types.Type
+	if r.dict != nil {
+		implicits = r.dict.targs
+	}
+
+	if r.Bool() { // dynamic subdictionary
+		idx := r.Len()
+		info := r.dict.subdicts[idx]
+		explicits := r.p.typListIdx(info.explicits, r.dict)
+
+		baseFn = r.p.objIdx(info.idx, implicits, explicits, true).(*ir.Name)
+
+		// TODO(mdempsky): Is there a more robust way to get the
+		// dictionary pointer type here?
+		dictPtrType := baseFn.Type().Params().Field(0).Type
+		dictPtr = typecheck.Expr(ir.NewConvExpr(pos, ir.OCONVNOP, dictPtrType, r.dictWord(pos, r.dict.subdictsOffset()+idx)))
+
+		return
+	}
+
+	info := r.objInfo()
+	explicits := r.p.typListIdx(info.explicits, r.dict)
+
+	wrapperFn = r.p.objIdx(info.idx, implicits, explicits, false).(*ir.Name)
+	baseFn = r.p.objIdx(info.idx, implicits, explicits, true).(*ir.Name)
+
+	dictName := r.p.objDictName(info.idx, implicits, explicits)
+	dictPtr = typecheck.Expr(ir.NewAddrExpr(pos, dictName))
+
+	return
+}
+
+func (pr *pkgReader) objDictName(idx pkgbits.Index, implicits, explicits []*types.Type) *ir.Name {
+	rname := pr.newReader(pkgbits.RelocName, idx, pkgbits.SyncObject1)
+	_, sym := rname.qualifiedIdent()
+	tag := pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj))
+
+	if tag == pkgbits.ObjStub {
+		assert(!sym.IsBlank())
+		if pri, ok := objReader[sym]; ok {
+			return pri.pr.objDictName(pri.idx, nil, explicits)
+		}
+		base.Fatalf("unresolved stub: %v", sym)
+	}
+
+	dict := pr.objDictIdx(sym, idx, implicits, explicits, false)
+
+	return pr.dictNameOf(dict)
+}
+
+// curry returns a function literal that calls fun with arg0 and
+// (optionally) arg1, accepting additional arguments to the function
+// literal as necessary to satisfy fun's signature.
+//
+// If nilCheck is true and arg0 is an interface value, then it's
+// checked to be non-nil as an initial step at the point of evaluating
+// the function literal itself.
+func (r *reader) curry(origPos src.XPos, ifaceHack bool, fun ir.Node, arg0, arg1 ir.Node) ir.Node {
+	var captured ir.Nodes
+	captured.Append(fun, arg0)
+	if arg1 != nil {
+		captured.Append(arg1)
+	}
+
+	params, results := syntheticSig(fun.Type())
+	params = params[len(captured)-1:] // skip curried parameters
+	typ := types.NewSignature(types.NoPkg, nil, nil, params, results)
+
+	addBody := func(pos src.XPos, r *reader, captured []ir.Node) {
+		recvs, params := r.syntheticArgs(pos)
+		assert(len(recvs) == 0)
+
+		fun := captured[0]
+
+		var args ir.Nodes
+		args.Append(captured[1:]...)
+		args.Append(params...)
+
+		r.syntheticTailCall(pos, fun, args)
+	}
+
+	return r.syntheticClosure(origPos, typ, ifaceHack, captured, addBody)
+}
+
+// methodExprWrap returns a function literal that changes method's
+// first parameter's type to recv, and uses implicits/deref/addr to
+// select the appropriate receiver parameter to pass to method.
+func (r *reader) methodExprWrap(origPos src.XPos, recv *types.Type, implicits []int, deref, addr bool, method, dictPtr ir.Node) ir.Node {
+	var captured ir.Nodes
+	captured.Append(method)
+
+	params, results := syntheticSig(method.Type())
+
+	// Change first parameter to recv.
+	params[0].Type = recv
+
+	// If we have a dictionary pointer argument to pass, then omit the
+	// underlying method expression's dictionary parameter from the
+	// returned signature too.
+	if dictPtr != nil {
+		captured.Append(dictPtr)
+		params = append(params[:1], params[2:]...)
+	}
+
+	typ := types.NewSignature(types.NoPkg, nil, nil, params, results)
+
+	addBody := func(pos src.XPos, r *reader, captured []ir.Node) {
+		recvs, args := r.syntheticArgs(pos)
+		assert(len(recvs) == 0)
+
+		fn := captured[0]
+
+		// Rewrite first argument based on implicits/deref/addr.
+		{
+			arg := args[0]
+			for _, ix := range implicits {
+				arg = Implicit(DotField(pos, arg, ix))
+			}
+			if deref {
+				arg = Implicit(Deref(pos, arg.Type().Elem(), arg))
+			} else if addr {
+				arg = Implicit(Addr(pos, arg))
+			}
+			args[0] = arg
+		}
+
+		// Insert dictionary argument, if provided.
+		if dictPtr != nil {
+			newArgs := make([]ir.Node, len(args)+1)
+			newArgs[0] = args[0]
+			newArgs[1] = captured[1]
+			copy(newArgs[2:], args[1:])
+			args = newArgs
+		}
+
+		r.syntheticTailCall(pos, fn, args)
+	}
+
+	return r.syntheticClosure(origPos, typ, false, captured, addBody)
+}
+
+// syntheticClosure constructs a synthetic function literal for
+// currying dictionary arguments. origPos is the position used for the
+// closure, which must be a non-inlined position. typ is the function
+// literal's signature type.
+//
+// captures is a list of expressions that need to be evaluated at the
+// point of function literal evaluation and captured by the function
+// literal. If ifaceHack is true and captures[1] is an interface type,
+// it's checked to be non-nil after evaluation.
+//
+// addBody is a callback function to populate the function body. The
+// list of captured values passed back has the captured variables for
+// use within the function literal, corresponding to the expressions
+// in captures.
+func (r *reader) syntheticClosure(origPos src.XPos, typ *types.Type, ifaceHack bool, captures ir.Nodes, addBody func(pos src.XPos, r *reader, captured []ir.Node)) ir.Node {
+	// isSafe reports whether n is an expression that we can safely
+	// defer to evaluating inside the closure instead, to avoid storing
+	// them into the closure.
+	//
+	// In practice this is always (and only) the wrappee function.
+	isSafe := func(n ir.Node) bool {
+		if n.Op() == ir.ONAME && n.(*ir.Name).Class == ir.PFUNC {
+			return true
+		}
+		if n.Op() == ir.OMETHEXPR {
+			return true
+		}
+
+		return false
+	}
+
+	// The ODCLFUNC and its body need to use the original position, but
+	// the OCLOSURE node and any Init statements should use the inlined
+	// position instead. See also the explanation in reader.funcLit.
+	inlPos := r.inlPos(origPos)
+
+	fn := ir.NewClosureFunc(origPos, r.curfn != nil)
+	fn.SetWrapper(true)
+	clo := fn.OClosure
+	clo.SetPos(inlPos)
+	ir.NameClosure(clo, r.curfn)
+
+	setType(fn.Nname, typ)
+	typecheck.Func(fn)
+	setType(clo, fn.Type())
+
+	var init ir.Nodes
+	for i, n := range captures {
+		if isSafe(n) {
+			continue // skip capture; can reference directly
+		}
+
+		tmp := r.tempCopy(inlPos, n, &init)
+		ir.NewClosureVar(origPos, fn, tmp)
+
+		// We need to nil check interface receivers at the point of method
+		// value evaluation, ugh.
+		if ifaceHack && i == 1 && n.Type().IsInterface() {
+			check := ir.NewUnaryExpr(inlPos, ir.OCHECKNIL, ir.NewUnaryExpr(inlPos, ir.OITAB, tmp))
+			init.Append(typecheck.Stmt(check))
+		}
+	}
+
+	pri := pkgReaderIndex{synthetic: func(pos src.XPos, r *reader) {
+		captured := make([]ir.Node, len(captures))
+		next := 0
+		for i, n := range captures {
+			if isSafe(n) {
+				captured[i] = n
+			} else {
+				captured[i] = r.closureVars[next]
+				next++
+			}
+		}
+		assert(next == len(r.closureVars))
+
+		addBody(origPos, r, captured)
+	}}
+	bodyReader[fn] = pri
+	pri.funcBody(fn)
+
+	// TODO(mdempsky): Remove hard-coding of typecheck.Target.
+	return ir.InitExpr(init, ir.UseClosure(clo, typecheck.Target))
+}
+
+// syntheticSig duplicates and returns the params and results lists
+// for sig, but renaming anonymous parameters so they can be assigned
+// ir.Names.
+func syntheticSig(sig *types.Type) (params, results []*types.Field) {
+	clone := func(params []*types.Field) []*types.Field {
+		res := make([]*types.Field, len(params))
+		for i, param := range params {
+			sym := param.Sym
+			if sym == nil || sym.Name == "_" {
+				sym = typecheck.LookupNum(".anon", i)
+			}
+			// TODO(mdempsky): It would be nice to preserve the original
+			// parameter positions here instead, but at least
+			// typecheck.NewMethodType replaces them with base.Pos, making
+			// them useless. Worse, the positions copied from base.Pos may
+			// have inlining contexts, which we definitely don't want here
+			// (e.g., #54625).
+			res[i] = types.NewField(base.AutogeneratedPos, sym, param.Type)
+			res[i].SetIsDDD(param.IsDDD())
+		}
+		return res
+	}
+
+	return clone(sig.Params().FieldSlice()), clone(sig.Results().FieldSlice())
+}
+
+func (r *reader) optExpr() ir.Node {
+	if r.Bool() {
+		return r.expr()
+	}
+	return nil
+}
+
+// methodExpr reads a method expression reference, and returns three
+// (possibly nil) expressions related to it:
+//
+// baseFn is always non-nil: it's either a function of the appropriate
+// type already, or it has an extra dictionary parameter as the second
+// parameter (i.e., immediately after the promoted receiver
+// parameter).
+//
+// If dictPtr is non-nil, then it's a dictionary argument that must be
+// passed as the second argument to baseFn.
+//
+// If wrapperFn is non-nil, then it's either the same as baseFn (if
+// dictPtr is nil), or it's semantically equivalent to currying baseFn
+// to pass dictPtr. (wrapperFn is nil when dictPtr is an expression
+// that needs to be computed dynamically.)
+//
+// For callers that are creating a call to the returned method, it's
+// best to emit a call to baseFn, and include dictPtr in the arguments
+// list as appropriate.
+//
+// For callers that want to return a method expression without
+// invoking it, they may return wrapperFn if it's non-nil; but
+// otherwise, they need to create their own wrapper.
+func (r *reader) methodExpr() (wrapperFn, baseFn, dictPtr ir.Node) {
+	recv := r.typ()
+	sig0 := r.typ()
+	pos := r.pos()
+	_, sym := r.selector()
+
+	// Signature type to return (i.e., recv prepended to the method's
+	// normal parameters list).
+	sig := typecheck.NewMethodType(sig0, recv)
+
+	if r.Bool() { // type parameter method expression
+		idx := r.Len()
+		word := r.dictWord(pos, r.dict.typeParamMethodExprsOffset()+idx)
+
+		// TODO(mdempsky): If the type parameter was instantiated with an
+		// interface type (i.e., embed.IsInterface()), then we could
+		// return the OMETHEXPR instead and save an indirection.
+
+		// We wrote the method expression's entry point PC into the
+		// dictionary, but for Go `func` values we need to return a
+		// closure (i.e., pointer to a structure with the PC as the first
+		// field). Because method expressions don't have any closure
+		// variables, we pun the dictionary entry as the closure struct.
+		fn := typecheck.Expr(ir.NewConvExpr(pos, ir.OCONVNOP, sig, ir.NewAddrExpr(pos, word)))
+		return fn, fn, nil
+	}
+
+	// TODO(mdempsky): I'm pretty sure this isn't needed: implicits is
+	// only relevant to locally defined types, but they can't have
+	// (non-promoted) methods.
+	var implicits []*types.Type
+	if r.dict != nil {
+		implicits = r.dict.targs
+	}
+
+	if r.Bool() { // dynamic subdictionary
+		idx := r.Len()
+		info := r.dict.subdicts[idx]
+		explicits := r.p.typListIdx(info.explicits, r.dict)
+
+		shapedObj := r.p.objIdx(info.idx, implicits, explicits, true).(*ir.Name)
+		shapedFn := shapedMethodExpr(pos, shapedObj, sym)
+
+		// TODO(mdempsky): Is there a more robust way to get the
+		// dictionary pointer type here?
+		dictPtrType := shapedFn.Type().Params().Field(1).Type
+		dictPtr := typecheck.Expr(ir.NewConvExpr(pos, ir.OCONVNOP, dictPtrType, r.dictWord(pos, r.dict.subdictsOffset()+idx)))
+
+		return nil, shapedFn, dictPtr
+	}
+
+	if r.Bool() { // static dictionary
+		info := r.objInfo()
+		explicits := r.p.typListIdx(info.explicits, r.dict)
+
+		shapedObj := r.p.objIdx(info.idx, implicits, explicits, true).(*ir.Name)
+		shapedFn := shapedMethodExpr(pos, shapedObj, sym)
+
+		dict := r.p.objDictName(info.idx, implicits, explicits)
+		dictPtr := typecheck.Expr(ir.NewAddrExpr(pos, dict))
+
+		// Check that dictPtr matches shapedFn's dictionary parameter.
+		if !types.Identical(dictPtr.Type(), shapedFn.Type().Params().Field(1).Type) {
+			base.FatalfAt(pos, "dict %L, but shaped method %L", dict, shapedFn)
+		}
+
+		// For statically known instantiations, we can take advantage of
+		// the stenciled wrapper.
+		base.AssertfAt(!recv.HasShape(), pos, "shaped receiver %v", recv)
+		wrapperFn := typecheck.Expr(ir.NewSelectorExpr(pos, ir.OXDOT, ir.TypeNode(recv), sym)).(*ir.SelectorExpr)
+		base.AssertfAt(types.Identical(sig, wrapperFn.Type()), pos, "wrapper %L does not have type %v", wrapperFn, sig)
+
+		return wrapperFn, shapedFn, dictPtr
+	}
+
+	// Simple method expression; no dictionary needed.
+	base.AssertfAt(!recv.HasShape() || recv.IsInterface(), pos, "shaped receiver %v", recv)
+	fn := typecheck.Expr(ir.NewSelectorExpr(pos, ir.OXDOT, ir.TypeNode(recv), sym)).(*ir.SelectorExpr)
+	return fn, fn, nil
+}
+
+// shapedMethodExpr returns the specified method on the given shaped
+// type.
+func shapedMethodExpr(pos src.XPos, obj *ir.Name, sym *types.Sym) *ir.SelectorExpr {
+	assert(obj.Op() == ir.OTYPE)
+
+	typ := obj.Type()
+	assert(typ.HasShape())
+
+	method := func() *types.Field {
+		for _, method := range typ.Methods().Slice() {
+			if method.Sym == sym {
+				return method
+			}
+		}
+
+		base.FatalfAt(pos, "failed to find method %v in shaped type %v", sym, typ)
+		panic("unreachable")
+	}()
+
+	// Construct an OMETHEXPR node.
+	recv := method.Type.Recv().Type
+	return typecheck.Expr(ir.NewSelectorExpr(pos, ir.OXDOT, ir.TypeNode(recv), sym)).(*ir.SelectorExpr)
+}
+
+func (r *reader) multiExpr() []ir.Node {
+	r.Sync(pkgbits.SyncMultiExpr)
+
+	if r.Bool() { // N:1
+		pos := r.pos()
+		expr := r.expr()
+
+		results := make([]ir.Node, r.Len())
+		as := ir.NewAssignListStmt(pos, ir.OAS2, nil, []ir.Node{expr})
+		as.Def = true
+		for i := range results {
+			tmp := r.temp(pos, r.typ())
+			as.PtrInit().Append(ir.NewDecl(pos, ir.ODCL, tmp))
+			as.Lhs.Append(tmp)
+
+			res := ir.Node(tmp)
+			if r.Bool() {
+				n := ir.NewConvExpr(pos, ir.OCONV, r.typ(), res)
+				n.TypeWord, n.SrcRType = r.convRTTI(pos)
+				n.SetImplicit(true)
+				res = typecheck.Expr(n)
+			}
+			results[i] = res
+		}
+
+		// TODO(mdempsky): Could use ir.InlinedCallExpr instead?
+		results[0] = ir.InitExpr([]ir.Node{typecheck.Stmt(as)}, results[0])
+		return results
+	}
+
+	// N:N
+	exprs := make([]ir.Node, r.Len())
+	if len(exprs) == 0 {
+		return nil
+	}
+	for i := range exprs {
+		exprs[i] = r.expr()
+	}
+	return exprs
+}
+
+// temp returns a new autotemp of the specified type.
+func (r *reader) temp(pos src.XPos, typ *types.Type) *ir.Name {
+	// See typecheck.typecheckargs.
+	curfn := r.curfn
+	if curfn == nil {
+		curfn = typecheck.InitTodoFunc
+	}
+
+	return typecheck.TempAt(pos, curfn, typ)
+}
+
+// tempCopy declares and returns a new autotemp initialized to the
+// value of expr.
+func (r *reader) tempCopy(pos src.XPos, expr ir.Node, init *ir.Nodes) *ir.Name {
+	if r.curfn == nil {
+		// Escape analysis doesn't know how to handle package-scope
+		// function literals with free variables (i.e., that capture
+		// temporary variables added to typecheck.InitTodoFunc).
+		//
+		// stencil.go works around this limitation by spilling values to
+		// global variables instead, but that causes the value to stay
+		// alive indefinitely; see go.dev/issue/54343.
+		//
+		// This code path (which implements the same workaround) isn't
+		// actually needed by unified IR, because it creates uses normal
+		// OMETHEXPR/OMETHVALUE nodes when statically-known instantiated
+		// types are used. But it's kept around for now because it's handy
+		// for testing that the generic fallback paths work correctly.
+		base.Fatalf("tempCopy called at package scope")
+
+		tmp := staticinit.StaticName(expr.Type())
+
+		assign := ir.NewAssignStmt(pos, tmp, expr)
+		assign.Def = true
+		tmp.Defn = assign
+
+		typecheck.Target.Decls = append(typecheck.Target.Decls, typecheck.Stmt(assign))
+
+		return tmp
+	}
+
+	tmp := r.temp(pos, expr.Type())
+
+	init.Append(typecheck.Stmt(ir.NewDecl(pos, ir.ODCL, tmp)))
+
+	assign := ir.NewAssignStmt(pos, tmp, expr)
+	assign.Def = true
+	init.Append(typecheck.Stmt(ir.NewAssignStmt(pos, tmp, expr)))
+
+	tmp.Defn = assign
+
+	return tmp
+}
+
 func (r *reader) compLit() ir.Node {
 	r.Sync(pkgbits.SyncCompLit)
 	pos := r.pos()
@@ -1713,6 +3028,10 @@
 	if typ.Kind() == types.TFORW {
 		base.FatalfAt(pos, "unresolved composite literal type: %v", typ)
 	}
+	var rtype ir.Node
+	if typ.IsMap() {
+		rtype = r.rtype(pos)
+	}
 	isStruct := typ.Kind() == types.TSTRUCT
 
 	elems := make([]ir.Node, r.Len())
@@ -1731,6 +3050,10 @@
 	}
 
 	lit := typecheck.Expr(ir.NewCompLitExpr(pos, ir.OCOMPLIT, typ, elems))
+	if rtype != nil {
+		lit := lit.(*ir.CompLitExpr)
+		lit.RType = rtype
+	}
 	if typ0.IsPtr() {
 		lit = typecheck.Expr(typecheck.NodAddrAt(pos, lit))
 		lit.SetType(typ0)
@@ -1758,13 +3081,30 @@
 func (r *reader) funcLit() ir.Node {
 	r.Sync(pkgbits.SyncFuncLit)
 
+	// The underlying function declaration (including its parameters'
+	// positions, if any) need to remain the original, uninlined
+	// positions. This is because we track inlining-context on nodes so
+	// we can synthesize the extra implied stack frames dynamically when
+	// generating tracebacks, whereas those stack frames don't make
+	// sense *within* the function literal. (Any necessary inlining
+	// adjustments will have been applied to the call expression
+	// instead.)
+	//
+	// This is subtle, and getting it wrong leads to cycles in the
+	// inlining tree, which lead to infinite loops during stack
+	// unwinding (#46234, #54625).
+	//
+	// Note that we *do* want the inline-adjusted position for the
+	// OCLOSURE node, because that position represents where any heap
+	// allocation of the closure is credited (#49171).
+	r.suppressInlPos++
 	pos := r.pos()
 	xtype2 := r.signature(types.LocalPkg, nil)
+	r.suppressInlPos--
 
-	opos := pos
-
-	fn := ir.NewClosureFunc(opos, r.curfn != nil)
+	fn := ir.NewClosureFunc(pos, r.curfn != nil)
 	clo := fn.OClosure
+	clo.SetPos(r.inlPos(pos)) // see comment above
 	ir.NameClosure(clo, r.curfn)
 
 	setType(fn.Nname, xtype2)
@@ -1775,8 +3115,13 @@
 	for len(fn.ClosureVars) < cap(fn.ClosureVars) {
 		ir.NewClosureVar(r.pos(), fn, r.useLocal())
 	}
+	if param := r.dictParam; param != nil {
+		// If we have a dictionary parameter, capture it too. For
+		// simplicity, we capture it last and unconditionally.
+		ir.NewClosureVar(param.Pos(), fn, param)
+	}
 
-	r.addBody(fn)
+	r.addBody(fn, nil)
 
 	// TODO(mdempsky): Remove hard-coding of typecheck.Target.
 	return ir.UseClosure(clo, typecheck.Target)
@@ -1799,44 +3144,135 @@
 	return nodes
 }
 
-func (r *reader) exprType(nilOK bool) ir.Node {
+// dictWord returns an expression to return the specified
+// uintptr-typed word from the dictionary parameter.
+func (r *reader) dictWord(pos src.XPos, idx int) ir.Node {
+	base.AssertfAt(r.dictParam != nil, pos, "expected dictParam in %v", r.curfn)
+	return typecheck.Expr(ir.NewIndexExpr(pos, r.dictParam, ir.NewBasicLit(pos, constant.MakeInt64(int64(idx)))))
+}
+
+// rttiWord is like dictWord, but converts it to *byte (the type used
+// internally to represent *runtime._type and *runtime.itab).
+func (r *reader) rttiWord(pos src.XPos, idx int) ir.Node {
+	return typecheck.Expr(ir.NewConvExpr(pos, ir.OCONVNOP, types.NewPtr(types.Types[types.TUINT8]), r.dictWord(pos, idx)))
+}
+
+// rtype reads a type reference from the element bitstream, and
+// returns an expression of type *runtime._type representing that
+// type.
+func (r *reader) rtype(pos src.XPos) ir.Node {
+	_, rtype := r.rtype0(pos)
+	return rtype
+}
+
+func (r *reader) rtype0(pos src.XPos) (typ *types.Type, rtype ir.Node) {
+	r.Sync(pkgbits.SyncRType)
+	if r.Bool() { // derived type
+		idx := r.Len()
+		info := r.dict.rtypes[idx]
+		typ = r.p.typIdx(info, r.dict, true)
+		rtype = r.rttiWord(pos, r.dict.rtypesOffset()+idx)
+		return
+	}
+
+	typ = r.typ()
+	rtype = reflectdata.TypePtrAt(pos, typ)
+	return
+}
+
+// varDictIndex populates name.DictIndex if name is a derived type.
+func (r *reader) varDictIndex(name *ir.Name) {
+	if r.Bool() {
+		idx := 1 + r.dict.rtypesOffset() + r.Len()
+		if int(uint16(idx)) != idx {
+			base.FatalfAt(name.Pos(), "DictIndex overflow for %v: %v", name, idx)
+		}
+		name.DictIndex = uint16(idx)
+	}
+}
+
+// itab returns a (typ, iface) pair of types.
+//
+// typRType and ifaceRType are expressions that evaluate to the
+// *runtime._type for typ and iface, respectively.
+//
+// If typ is a concrete type and iface is a non-empty interface type,
+// then itab is an expression that evaluates to the *runtime.itab for
+// the pair. Otherwise, itab is nil.
+func (r *reader) itab(pos src.XPos) (typ *types.Type, typRType ir.Node, iface *types.Type, ifaceRType ir.Node, itab ir.Node) {
+	typ, typRType = r.rtype0(pos)
+	iface, ifaceRType = r.rtype0(pos)
+
+	idx := -1
+	if r.Bool() {
+		idx = r.Len()
+	}
+
+	if !typ.IsInterface() && iface.IsInterface() && !iface.IsEmptyInterface() {
+		if idx >= 0 {
+			itab = r.rttiWord(pos, r.dict.itabsOffset()+idx)
+		} else {
+			base.AssertfAt(!typ.HasShape(), pos, "%v is a shape type", typ)
+			base.AssertfAt(!iface.HasShape(), pos, "%v is a shape type", iface)
+
+			lsym := reflectdata.ITabLsym(typ, iface)
+			itab = typecheck.LinksymAddr(pos, lsym, types.Types[types.TUINT8])
+		}
+	}
+
+	return
+}
+
+// convRTTI returns expressions appropriate for populating an
+// ir.ConvExpr's TypeWord and SrcRType fields, respectively.
+func (r *reader) convRTTI(pos src.XPos) (typeWord, srcRType ir.Node) {
+	r.Sync(pkgbits.SyncConvRTTI)
+	src, srcRType0, dst, dstRType, itab := r.itab(pos)
+	if !dst.IsInterface() {
+		return
+	}
+
+	// See reflectdata.ConvIfaceTypeWord.
+	switch {
+	case dst.IsEmptyInterface():
+		if !src.IsInterface() {
+			typeWord = srcRType0 // direct eface construction
+		}
+	case !src.IsInterface():
+		typeWord = itab // direct iface construction
+	default:
+		typeWord = dstRType // convI2I
+	}
+
+	// See reflectdata.ConvIfaceSrcRType.
+	if !src.IsInterface() {
+		srcRType = srcRType0
+	}
+
+	return
+}
+
+func (r *reader) exprType() ir.Node {
 	r.Sync(pkgbits.SyncExprType)
-
-	if nilOK && r.Bool() {
-		return typecheck.Expr(types.BuiltinPkg.Lookup("nil").Def.(*ir.NilExpr))
-	}
-
 	pos := r.pos()
 
-	lsymPtr := func(lsym *obj.LSym) ir.Node {
-		return typecheck.Expr(typecheck.NodAddr(ir.NewLinksymExpr(pos, lsym, types.Types[types.TUINT8])))
-	}
-
 	var typ *types.Type
 	var rtype, itab ir.Node
 
 	if r.Bool() {
-		info := r.dict.itabs[r.Len()]
-		typ = info.typ
-
-		// TODO(mdempsky): Populate rtype unconditionally?
-		if typ.IsInterface() {
-			rtype = lsymPtr(info.lsym)
-		} else {
-			itab = lsymPtr(info.lsym)
+		typ, rtype, _, _, itab = r.itab(pos)
+		if !typ.IsInterface() {
+			rtype = nil // TODO(mdempsky): Leave set?
 		}
 	} else {
-		info := r.typInfo()
-		typ = r.p.typIdx(info, r.dict, true)
+		typ, rtype = r.rtype0(pos)
 
-		if !info.derived {
+		if !r.Bool() { // not derived
 			// TODO(mdempsky): ir.TypeNode should probably return a typecheck'd node.
 			n := ir.TypeNode(typ)
 			n.SetTypecheck(1)
 			return n
 		}
-
-		rtype = lsymPtr(reflectdata.TypeLinksym(typ))
 	}
 
 	dt := ir.NewDynamicType(pos, rtype)
@@ -1972,15 +3408,28 @@
 
 // @@@ Inlining
 
+// unifiedHaveInlineBody reports whether we have the function body for
+// fn, so we can inline it.
+func unifiedHaveInlineBody(fn *ir.Func) bool {
+	if fn.Inl == nil {
+		return false
+	}
+
+	_, ok := bodyReaderFor(fn)
+	return ok
+}
+
 var inlgen = 0
 
-func InlineCall(call *ir.CallExpr, fn *ir.Func, inlIndex int) *ir.InlinedCallExpr {
+// unifiedInlineCall implements inline.NewInline by re-reading the function
+// body from its Unified IR export data.
+func unifiedInlineCall(call *ir.CallExpr, fn *ir.Func, inlIndex int) *ir.InlinedCallExpr {
 	// TODO(mdempsky): Turn callerfn into an explicit parameter.
 	callerfn := ir.CurFunc
 
-	pri, ok := bodyReader[fn]
+	pri, ok := bodyReaderFor(fn)
 	if !ok {
-		base.FatalfAt(call.Pos(), "missing function body for call to %v", fn)
+		base.FatalfAt(call.Pos(), "cannot inline call to %v: missing inline body", fn)
 	}
 
 	if fn.Inl.Body == nil {
@@ -2008,10 +3457,12 @@
 	for i, cv := range r.inlFunc.ClosureVars {
 		r.closureVars[i] = cv.Outer
 	}
+	if len(r.closureVars) != 0 && r.hasTypeParams() {
+		r.dictParam = r.closureVars[len(r.closureVars)-1] // dictParam is last; see reader.funcLit
+	}
 
 	r.funcargs(fn)
 
-	assert(r.Bool()) // have body
 	r.delayResults = fn.Inl.CanDelayResults
 
 	r.retlabel = typecheck.AutoLabel(".i")
@@ -2070,15 +3521,19 @@
 	nparams := len(r.curfn.Dcl)
 
 	ir.WithFunc(r.curfn, func() {
-		r.curfn.Body = r.stmts()
-		r.curfn.Endlineno = r.pos()
+		if !r.syntheticBody(call.Pos()) {
+			assert(r.Bool()) // have body
+
+			r.curfn.Body = r.stmts()
+			r.curfn.Endlineno = r.pos()
+		}
 
 		// TODO(mdempsky): This shouldn't be necessary. Inlining might
 		// read in new function/method declarations, which could
 		// potentially be recursively inlined themselves; but we shouldn't
 		// need to read in the non-inlined bodies for the declarations
 		// themselves. But currently it's an easy fix to #50552.
-		readBodies(typecheck.Target)
+		readBodies(typecheck.Target, true)
 
 		deadcode.Func(r.curfn)
 
@@ -2260,18 +3715,21 @@
 	}
 }
 
+// importedDef reports whether r is reading from an imported and
+// non-generic element.
+//
+// If a type was found in an imported package, then we can assume that
+// package (or one of its transitive dependencies) already generated
+// method wrappers for it.
+//
+// Exception: If we're instantiating an imported generic type or
+// function, we might be instantiating it with type arguments not
+// previously seen before.
+//
+// TODO(mdempsky): Distinguish when a generic function or type was
+// instantiated in an imported package so that we can add types to
+// haveWrapperTypes instead.
 func (r *reader) importedDef() bool {
-	// If a type was found in an imported package, then we can assume
-	// that package (or one of its transitive dependencies) already
-	// generated method wrappers for it.
-	//
-	// Exception: If we're instantiating an imported generic type or
-	// function, we might be instantiating it with type arguments not
-	// previously seen before.
-	//
-	// TODO(mdempsky): Distinguish when a generic function or type was
-	// instantiated in an imported package so that we can add types to
-	// haveWrapperTypes instead.
 	return r.p != localPkgReader && !r.hasTypeParams()
 }
 
@@ -2457,7 +3915,17 @@
 
 	// We generate wrappers after the global inlining pass,
 	// so we're responsible for applying inlining ourselves here.
-	inline.InlineCalls(fn)
+	// TODO(prattmic): plumb PGO.
+	inline.InlineCalls(fn, nil)
+
+	// The body of wrapper function after inlining may reveal new ir.OMETHVALUE node,
+	// we don't know whether wrapper function has been generated for it or not, so
+	// generate one immediately here.
+	ir.VisitList(fn.Body, func(n ir.Node) {
+		if n, ok := n.(*ir.SelectorExpr); ok && n.Op() == ir.OMETHVALUE {
+			wrapMethodValue(n.X.Type(), n.Selection, target, true)
+		}
+	})
 
 	target.Decls = append(target.Decls, fn)
 }
@@ -2516,3 +3984,46 @@
 	ret.Results = []ir.Node{call}
 	fn.Body.Append(ret)
 }
+
+func setBasePos(pos src.XPos) {
+	// Set the position for any error messages we might print (e.g. too large types).
+	base.Pos = pos
+}
+
+// dictParamName is the name of the synthetic dictionary parameter
+// added to shaped functions.
+//
+// N.B., this variable name is known to Delve:
+// https://github.com/go-delve/delve/blob/cb91509630529e6055be845688fd21eb89ae8714/pkg/proc/eval.go#L28
+const dictParamName = ".dict"
+
+// shapeSig returns a copy of fn's signature, except adding a
+// dictionary parameter and promoting the receiver parameter (if any)
+// to a normal parameter.
+//
+// The parameter types.Fields are all copied too, so their Nname
+// fields can be initialized for use by the shape function.
+func shapeSig(fn *ir.Func, dict *readerDict) *types.Type {
+	sig := fn.Nname.Type()
+	oldRecv := sig.Recv()
+
+	var recv *types.Field
+	if oldRecv != nil {
+		recv = types.NewField(oldRecv.Pos, oldRecv.Sym, oldRecv.Type)
+	}
+
+	params := make([]*types.Field, 1+sig.Params().Fields().Len())
+	params[0] = types.NewField(fn.Pos(), fn.Sym().Pkg.Lookup(dictParamName), types.NewPtr(dict.varType()))
+	for i, param := range sig.Params().Fields().Slice() {
+		d := types.NewField(param.Pos, param.Sym, param.Type)
+		d.SetIsDDD(param.IsDDD())
+		params[1+i] = d
+	}
+
+	results := make([]*types.Field, sig.Results().Fields().Len())
+	for i, result := range sig.Results().Fields().Slice() {
+		results[i] = types.NewField(result.Pos, result.Sym, result.Type)
+	}
+
+	return types.NewSignature(types.LocalPkg, recv, nil, params, results)
+}
diff --git a/src/cmd/compile/internal/noder/sizes.go b/src/cmd/compile/internal/noder/sizes.go
index 9ba0e50..107f4d0 100644
--- a/src/cmd/compile/internal/noder/sizes.go
+++ b/src/cmd/compile/internal/noder/sizes.go
@@ -25,6 +25,17 @@
 		// is the same as unsafe.Alignof(x[0]), but at least 1."
 		return s.Alignof(t.Elem())
 	case *types2.Struct:
+		if t.NumFields() == 0 && types2.IsSyncAtomicAlign64(T) {
+			// Special case: sync/atomic.align64 is an
+			// empty struct we recognize as a signal that
+			// the struct it contains must be
+			// 64-bit-aligned.
+			//
+			// This logic is equivalent to the logic in
+			// cmd/compile/internal/types/size.go:calcStructOffset
+			return 8
+		}
+
 		// spec: "For a variable x of struct type: unsafe.Alignof(x)
 		// is the largest of the values unsafe.Alignof(x.f) for each
 		// field f of x, but at least 1."
@@ -71,7 +82,7 @@
 	for i, f := range fields {
 		typ := f.Type()
 		a := s.Alignof(typ)
-		o = types.Rnd(o, a)
+		o = types.RoundUp(o, a)
 		offsets[i] = o
 		o += s.Sizeof(typ)
 	}
@@ -123,7 +134,7 @@
 		}
 
 		// gc: Size includes alignment padding.
-		return types.Rnd(offsets[n-1]+last, s.Alignof(t))
+		return types.RoundUp(offsets[n-1]+last, s.Alignof(t))
 	case *types2.Interface:
 		return int64(types.PtrSize) * 2
 	case *types2.Chan, *types2.Map, *types2.Pointer, *types2.Signature:
diff --git a/src/cmd/compile/internal/noder/stencil.go b/src/cmd/compile/internal/noder/stencil.go
index d3f51e0..26a088e 100644
--- a/src/cmd/compile/internal/noder/stencil.go
+++ b/src/cmd/compile/internal/noder/stencil.go
@@ -334,10 +334,6 @@
 	} else { // ir.OMETHEXPR or ir.METHVALUE
 		// Method expression T.M where T is a generic type.
 		se := x.(*ir.SelectorExpr)
-		targs := deref(se.X.Type()).RParams()
-		if len(targs) == 0 {
-			panic("bad")
-		}
 		if x.Op() == ir.OMETHVALUE {
 			rcvrValue = se.X
 		}
@@ -348,7 +344,8 @@
 		// of se.Selection, since that will be the type that actually has
 		// the method.
 		recv := deref(se.Selection.Type.Recv().Type)
-		if len(recv.RParams()) == 0 {
+		targs := recv.RParams()
+		if len(targs) == 0 {
 			// The embedded type that actually has the method is not
 			// actually generic, so no need to build a closure.
 			return x
@@ -550,7 +547,7 @@
 			// Lookup the method on the base generic type, since methods may
 			// not be set on imported instantiated types.
 			baseType := typ.OrigType()
-			for j, _ := range typ.Methods().Slice() {
+			for j := range typ.Methods().Slice() {
 				if baseType.Methods().Slice()[j].Nointerface() {
 					typ.Methods().Slice()[j].SetNointerface(true)
 				}
@@ -1659,9 +1656,11 @@
 				var nameNode *ir.Name
 				se := call.X.(*ir.SelectorExpr)
 				if se.X.Type().IsShape() {
-					// This is a method call enabled by a type bound.
 					tparam := se.X.Type()
-					if call.X.Op() == ir.ODOTMETH {
+					// Ensure methods on all instantiating types are computed.
+					typecheck.CalcMethods(tparam)
+					if typecheck.Lookdot1(nil, se.Sel, tparam, tparam.AllMethods(), 0) != nil {
+						// This is a method call enabled by a type bound.
 						// We need this extra check for method expressions,
 						// which don't add in the implicit XDOTs.
 						tmpse := ir.NewSelectorExpr(src.NoXPos, ir.OXDOT, se.X, se.Sel)
@@ -1790,6 +1789,7 @@
 // instantiations have been created.
 // Also handles writing method expression closures into the dictionaries.
 func (g *genInst) finalizeSyms() {
+Outer:
 	for _, d := range g.dictSymsToFinalize {
 		infoPrint("=== Finalizing dictionary %s\n", d.sym.Name)
 
@@ -1859,7 +1859,30 @@
 				}
 			}
 			if !found {
-				base.Fatalf("method %s on %v not found", bf.name, rcvr)
+				// We failed to find a method expression needed for this
+				// dictionary. This may happen because we tried to create a
+				// dictionary for an invalid instantiation.
+				//
+				// For example, in test/typeparam/issue54225.go, we attempt to
+				// construct a dictionary for "Node[struct{}].contentLen",
+				// even though "struct{}" does not implement "Value", so it
+				// cannot actually be used as a type argument to "Node".
+				//
+				// The real issue here is we shouldn't be attempting to create
+				// those dictionaries in the first place (e.g., CL 428356),
+				// but that fix is scarier for backporting to Go 1.19. Too
+				// many backport CLs to this code have fixed one issue while
+				// introducing another.
+				//
+				// So as a hack, instead of calling Fatalf, we simply skip
+				// calling objw.Global below, which prevents us from emitting
+				// the broken dictionary. The linker's dead code elimination
+				// should then naturally prune this invalid, unneeded
+				// dictionary. Worst case, if the dictionary somehow *is*
+				// needed by the final executable, we've just turned an ICE
+				// into a link-time missing symbol failure.
+				infoPrint(" ! abandoning dictionary %v; missing method expression %v.%s\n", d.sym.Name, rcvr, bf.name)
+				continue Outer
 			}
 		}
 
@@ -2242,7 +2265,7 @@
 	}
 }
 
-// startClosures starts creation of a closure that has the function type typ. It
+// startClosure starts creation of a closure that has the function type typ. It
 // creates all the formal params and results according to the type typ. On return,
 // the body and closure variables of the closure must still be filled in, and
 // ir.UseClosure() called.
diff --git a/src/cmd/compile/internal/noder/transform.go b/src/cmd/compile/internal/noder/transform.go
index ddbccf4..15adb89 100644
--- a/src/cmd/compile/internal/noder/transform.go
+++ b/src/cmd/compile/internal/noder/transform.go
@@ -730,11 +730,11 @@
 	assert(t.IsSlice())
 
 	if n.IsDDD {
-		if t.Elem().IsKind(types.TUINT8) && args[1].Type().IsString() {
-			return n
-		}
-
-		args[1] = assignconvfn(args[1], t.Underlying())
+		// assignconvfn is of args[1] not required here, as the
+		// types of args[0] and args[1] don't need to match
+		// (They will both have an underlying type which are
+		// slices of identical base types, or be []byte and string.)
+		// See issue 53888.
 		return n
 	}
 
@@ -900,7 +900,7 @@
 		transformArgs(n)
 		fallthrough
 
-	case ir.ONEW, ir.OALIGNOF, ir.OOFFSETOF, ir.OSIZEOF:
+	case ir.ONEW, ir.OALIGNOF, ir.OOFFSETOF, ir.OSIZEOF, ir.OUNSAFESLICEDATA, ir.OUNSAFESTRINGDATA:
 		u := ir.NewUnaryExpr(n.Pos(), op, n.Args[0])
 		u1 := typed(n.Type(), ir.InitExpr(n.Init(), u)) // typecheckargs can add to old.Init
 		switch op {
@@ -913,12 +913,12 @@
 		case ir.OALIGNOF, ir.OOFFSETOF, ir.OSIZEOF:
 			// This corresponds to the EvalConst() call near end of typecheck().
 			return typecheck.EvalConst(u1)
-		case ir.OCLOSE, ir.ONEW:
+		case ir.OCLOSE, ir.ONEW, ir.OUNSAFESTRINGDATA, ir.OUNSAFESLICEDATA:
 			// nothing more to do
 			return u1
 		}
 
-	case ir.OCOMPLEX, ir.OCOPY, ir.OUNSAFEADD, ir.OUNSAFESLICE:
+	case ir.OCOMPLEX, ir.OCOPY, ir.OUNSAFEADD, ir.OUNSAFESLICE, ir.OUNSAFESTRING:
 		transformArgs(n)
 		b := ir.NewBinaryExpr(n.Pos(), op, n.Args[0], n.Args[1])
 		n1 := typed(n.Type(), ir.InitExpr(n.Init(), b))
diff --git a/src/cmd/compile/internal/noder/unified.go b/src/cmd/compile/internal/noder/unified.go
index 46acdab..ed97a09 100644
--- a/src/cmd/compile/internal/noder/unified.go
+++ b/src/cmd/compile/internal/noder/unified.go
@@ -1,5 +1,3 @@
-// UNREVIEWED
-
 // Copyright 2021 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
@@ -7,13 +5,13 @@
 package noder
 
 import (
-	"bytes"
 	"fmt"
 	"internal/goversion"
 	"internal/pkgbits"
 	"io"
 	"runtime"
 	"sort"
+	"strings"
 
 	"cmd/compile/internal/base"
 	"cmd/compile/internal/inline"
@@ -71,7 +69,8 @@
 // In other words, we have all the necessary information to build the generic IR form
 // (see writer.captureVars for an example).
 func unified(noders []*noder) {
-	inline.NewInline = InlineCall
+	inline.InlineCall = unifiedInlineCall
+	typecheck.HaveInlineBody = unifiedHaveInlineBody
 
 	data := writePkgStub(noders)
 
@@ -82,13 +81,12 @@
 	base.Flag.Lang = fmt.Sprintf("go1.%d", goversion.Version)
 	types.ParseLangFlag()
 
-	types.LocalPkg.Height = 0 // reset so pkgReader.pkgIdx doesn't complain
 	target := typecheck.Target
 
 	typecheck.TypecheckAllowed = true
 
 	localPkgReader = newPkgReader(pkgbits.NewPkgDecoder(types.LocalPkg.Path, data))
-	readPackage(localPkgReader, types.LocalPkg)
+	readPackage(localPkgReader, types.LocalPkg, true)
 
 	r := localPkgReader.newReader(pkgbits.RelocMeta, pkgbits.PrivateRootIdx, pkgbits.SyncPrivate)
 	r.pkgInit(types.LocalPkg, target)
@@ -103,7 +101,7 @@
 		}
 	}
 
-	readBodies(target)
+	readBodies(target, false)
 
 	// Check that nothing snuck past typechecking.
 	for _, n := range target.Decls {
@@ -123,26 +121,82 @@
 	base.ExitIfErrors() // just in case
 }
 
-// readBodies reads in bodies for any
-func readBodies(target *ir.Package) {
+// readBodies iteratively expands all pending dictionaries and
+// function bodies.
+//
+// If duringInlining is true, then the inline.InlineDecls is called as
+// necessary on instantiations of imported generic functions, so their
+// inlining costs can be computed.
+func readBodies(target *ir.Package, duringInlining bool) {
+	var inlDecls []ir.Node
+
 	// Don't use range--bodyIdx can add closures to todoBodies.
-	for len(todoBodies) > 0 {
-		// The order we expand bodies doesn't matter, so pop from the end
-		// to reduce todoBodies reallocations if it grows further.
-		fn := todoBodies[len(todoBodies)-1]
-		todoBodies = todoBodies[:len(todoBodies)-1]
+	for {
+		// The order we expand dictionaries and bodies doesn't matter, so
+		// pop from the end to reduce todoBodies reallocations if it grows
+		// further.
+		//
+		// However, we do at least need to flush any pending dictionaries
+		// before reading bodies, because bodies might reference the
+		// dictionaries.
 
-		pri, ok := bodyReader[fn]
-		assert(ok)
-		pri.funcBody(fn)
+		if len(todoDicts) > 0 {
+			fn := todoDicts[len(todoDicts)-1]
+			todoDicts = todoDicts[:len(todoDicts)-1]
+			fn()
+			continue
+		}
 
-		// Instantiated generic function: add to Decls for typechecking
-		// and compilation.
-		if fn.OClosure == nil && len(pri.dict.targs) != 0 {
-			target.Decls = append(target.Decls, fn)
+		if len(todoBodies) > 0 {
+			fn := todoBodies[len(todoBodies)-1]
+			todoBodies = todoBodies[:len(todoBodies)-1]
+
+			pri, ok := bodyReader[fn]
+			assert(ok)
+			pri.funcBody(fn)
+
+			// Instantiated generic function: add to Decls for typechecking
+			// and compilation.
+			if fn.OClosure == nil && len(pri.dict.targs) != 0 {
+				if duringInlining {
+					inlDecls = append(inlDecls, fn)
+				} else {
+					target.Decls = append(target.Decls, fn)
+				}
+			}
+
+			continue
+		}
+
+		break
+	}
+
+	todoDicts = nil
+	todoBodies = nil
+
+	if len(inlDecls) != 0 {
+		// If we instantiated any generic functions during inlining, we need
+		// to call CanInline on them so they'll be transitively inlined
+		// correctly (#56280).
+		//
+		// We know these functions were already compiled in an imported
+		// package though, so we don't need to actually apply InlineCalls or
+		// save the function bodies any further than this.
+		//
+		// We can also lower the -m flag to 0, to suppress duplicate "can
+		// inline" diagnostics reported against the imported package. Again,
+		// we already reported those diagnostics in the original package, so
+		// it's pointless repeating them here.
+
+		oldLowerM := base.Flag.LowerM
+		base.Flag.LowerM = 0
+		inline.InlineDecls(nil, inlDecls, false)
+		base.Flag.LowerM = oldLowerM
+
+		for _, fn := range inlDecls {
+			fn.(*ir.Func).Body = nil // free memory
 		}
 	}
-	todoBodies = nil
 }
 
 // writePkgStub type checks the given parsed source files,
@@ -164,12 +218,12 @@
 	{
 		w := publicRootWriter
 		w.pkg(pkg)
-		w.Bool(false) // has init; XXX
+		w.Bool(false) // TODO(mdempsky): Remove; was "has init"
 
 		scope := pkg.Scope()
 		names := scope.Names()
 		w.Len(len(names))
-		for _, name := range scope.Names() {
+		for _, name := range names {
 			w.obj(scope.Lookup(name), nil)
 		}
 
@@ -183,7 +237,7 @@
 		w.Flush()
 	}
 
-	var sb bytes.Buffer // TODO(mdempsky): strings.Builder after #44505 is resolved
+	var sb strings.Builder
 	pw.DumpTo(&sb)
 
 	// At this point, we're done with types2. Make sure the package is
@@ -201,7 +255,8 @@
 	// not because of #22350). To avoid imposing unnecessary
 	// restrictions on the GOROOT_BOOTSTRAP toolchain, we skip the test
 	// during bootstrapping.
-	if base.CompilerBootstrap {
+	if base.CompilerBootstrap || base.Debug.GCCheck == 0 {
+		*pkg = types2.Package{}
 		return
 	}
 
@@ -227,42 +282,76 @@
 	base.Fatalf("package never finalized")
 }
 
-func readPackage(pr *pkgReader, importpkg *types.Pkg) {
-	r := pr.newReader(pkgbits.RelocMeta, pkgbits.PublicRootIdx, pkgbits.SyncPublic)
+// readPackage reads package export data from pr to populate
+// importpkg.
+//
+// localStub indicates whether pr is reading the stub export data for
+// the local package, as opposed to relocated export data for an
+// import.
+func readPackage(pr *pkgReader, importpkg *types.Pkg, localStub bool) {
+	{
+		r := pr.newReader(pkgbits.RelocMeta, pkgbits.PublicRootIdx, pkgbits.SyncPublic)
 
-	pkg := r.pkg()
-	base.Assertf(pkg == importpkg, "have package %q (%p), want package %q (%p)", pkg.Path, pkg, importpkg.Path, importpkg)
+		pkg := r.pkg()
+		base.Assertf(pkg == importpkg, "have package %q (%p), want package %q (%p)", pkg.Path, pkg, importpkg.Path, importpkg)
 
-	if r.Bool() {
-		sym := pkg.Lookup(".inittask")
-		task := ir.NewNameAt(src.NoXPos, sym)
-		task.Class = ir.PEXTERN
-		sym.Def = task
+		r.Bool() // TODO(mdempsky): Remove; was "has init"
+
+		for i, n := 0, r.Len(); i < n; i++ {
+			r.Sync(pkgbits.SyncObject)
+			assert(!r.Bool())
+			idx := r.Reloc(pkgbits.RelocObj)
+			assert(r.Len() == 0)
+
+			path, name, code := r.p.PeekObj(idx)
+			if code != pkgbits.ObjStub {
+				objReader[types.NewPkg(path, "").Lookup(name)] = pkgReaderIndex{pr, idx, nil, nil, nil}
+			}
+		}
+
+		r.Sync(pkgbits.SyncEOF)
 	}
 
-	for i, n := 0, r.Len(); i < n; i++ {
-		r.Sync(pkgbits.SyncObject)
-		assert(!r.Bool())
-		idx := r.Reloc(pkgbits.RelocObj)
-		assert(r.Len() == 0)
+	if !localStub {
+		r := pr.newReader(pkgbits.RelocMeta, pkgbits.PrivateRootIdx, pkgbits.SyncPrivate)
 
-		path, name, code := r.p.PeekObj(idx)
-		if code != pkgbits.ObjStub {
-			objReader[types.NewPkg(path, "").Lookup(name)] = pkgReaderIndex{pr, idx, nil}
+		if r.Bool() {
+			sym := importpkg.Lookup(".inittask")
+			task := ir.NewNameAt(src.NoXPos, sym)
+			task.Class = ir.PEXTERN
+			sym.Def = task
 		}
+
+		for i, n := 0, r.Len(); i < n; i++ {
+			path := r.String()
+			name := r.String()
+			idx := r.Reloc(pkgbits.RelocBody)
+
+			sym := types.NewPkg(path, "").Lookup(name)
+			if _, ok := importBodyReader[sym]; !ok {
+				importBodyReader[sym] = pkgReaderIndex{pr, idx, nil, nil, nil}
+			}
+		}
+
+		r.Sync(pkgbits.SyncEOF)
 	}
 }
 
+// writeUnifiedExport writes to `out` the finalized, self-contained
+// Unified IR export data file for the current compilation unit.
 func writeUnifiedExport(out io.Writer) {
 	l := linker{
 		pw: pkgbits.NewPkgEncoder(base.Debug.SyncFrames),
 
-		pkgs:  make(map[string]pkgbits.Index),
-		decls: make(map[*types.Sym]pkgbits.Index),
+		pkgs:   make(map[string]pkgbits.Index),
+		decls:  make(map[*types.Sym]pkgbits.Index),
+		bodies: make(map[*types.Sym]pkgbits.Index),
 	}
 
 	publicRootWriter := l.pw.NewEncoder(pkgbits.RelocMeta, pkgbits.SyncPublic)
+	privateRootWriter := l.pw.NewEncoder(pkgbits.RelocMeta, pkgbits.SyncPrivate)
 	assert(publicRootWriter.Idx == pkgbits.PublicRootIdx)
+	assert(privateRootWriter.Idx == pkgbits.PrivateRootIdx)
 
 	var selfPkgIdx pkgbits.Index
 
@@ -273,7 +362,7 @@
 		r.Sync(pkgbits.SyncPkg)
 		selfPkgIdx = l.relocIdx(pr, pkgbits.RelocPkg, r.Reloc(pkgbits.RelocPkg))
 
-		r.Bool() // has init
+		r.Bool() // TODO(mdempsky): Remove; was "has init"
 
 		for i, n := 0, r.Len(); i < n; i++ {
 			r.Sync(pkgbits.SyncObject)
@@ -304,8 +393,7 @@
 
 		w.Sync(pkgbits.SyncPkg)
 		w.Reloc(pkgbits.RelocPkg, selfPkgIdx)
-
-		w.Bool(typecheck.Lookup(".inittask").Def != nil)
+		w.Bool(false) // TODO(mdempsky): Remove; was "has init"
 
 		w.Len(len(idxs))
 		for _, idx := range idxs {
@@ -319,5 +407,31 @@
 		w.Flush()
 	}
 
+	{
+		type symIdx struct {
+			sym *types.Sym
+			idx pkgbits.Index
+		}
+		var bodies []symIdx
+		for sym, idx := range l.bodies {
+			bodies = append(bodies, symIdx{sym, idx})
+		}
+		sort.Slice(bodies, func(i, j int) bool { return bodies[i].idx < bodies[j].idx })
+
+		w := privateRootWriter
+
+		w.Bool(typecheck.Lookup(".inittask").Def != nil)
+
+		w.Len(len(bodies))
+		for _, body := range bodies {
+			w.String(body.sym.Pkg.Path)
+			w.String(body.sym.Name)
+			w.Reloc(pkgbits.RelocBody, body.idx)
+		}
+
+		w.Sync(pkgbits.SyncEOF)
+		w.Flush()
+	}
+
 	base.Ctxt.Fingerprint = l.pw.DumpTo(out)
 }
diff --git a/src/cmd/compile/internal/noder/validate.go b/src/cmd/compile/internal/noder/validate.go
index dcacae7..baf8bd3 100644
--- a/src/cmd/compile/internal/noder/validate.go
+++ b/src/cmd/compile/internal/noder/validate.go
@@ -53,7 +53,7 @@
 func (g *irgen) validate(n syntax.Node) {
 	switch n := n.(type) {
 	case *syntax.CallExpr:
-		tv := g.info.Types[n.Fun]
+		tv := g.typeAndValue(n.Fun)
 		if tv.IsBuiltin() {
 			fun := n.Fun
 			for {
@@ -81,7 +81,7 @@
 		// Check that types2+gcSizes calculates sizes the same
 		// as cmd/compile does.
 
-		tv := g.info.Types[call]
+		tv := g.typeAndValue(call)
 		if !tv.IsValue() {
 			base.FatalfAt(g.pos(call), "expected a value")
 		}
@@ -106,9 +106,9 @@
 func (g *irgen) unsafeExpr(name string, arg syntax.Expr) int64 {
 	switch name {
 	case "Alignof":
-		return g.typ(g.info.Types[arg].Type).Alignment()
+		return g.typ(g.type2(arg)).Alignment()
 	case "Sizeof":
-		return g.typ(g.info.Types[arg].Type).Size()
+		return g.typ(g.type2(arg)).Size()
 	}
 
 	// Offsetof
@@ -116,7 +116,7 @@
 	sel := arg.(*syntax.SelectorExpr)
 	selection := g.info.Selections[sel]
 
-	typ := g.typ(g.info.Types[sel.X].Type)
+	typ := g.typ(g.type2(sel.X))
 	typ = deref(typ)
 
 	var offset int64
diff --git a/src/cmd/compile/internal/noder/writer.go b/src/cmd/compile/internal/noder/writer.go
index b440ad3..da5c1e9 100644
--- a/src/cmd/compile/internal/noder/writer.go
+++ b/src/cmd/compile/internal/noder/writer.go
@@ -1,5 +1,3 @@
-// UNREVIEWED
-
 // Copyright 2021 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
@@ -13,9 +11,49 @@
 	"cmd/compile/internal/base"
 	"cmd/compile/internal/ir"
 	"cmd/compile/internal/syntax"
+	"cmd/compile/internal/types"
 	"cmd/compile/internal/types2"
 )
 
+// This file implements the Unified IR package writer and defines the
+// Unified IR export data format.
+//
+// Low-level coding details (e.g., byte-encoding of individual
+// primitive values, or handling element bitstreams and
+// cross-references) are handled by internal/pkgbits, so here we only
+// concern ourselves with higher-level worries like mapping Go
+// language constructs into elements.
+
+// There are two central types in the writing process: the "writer"
+// type handles writing out individual elements, while the "pkgWriter"
+// type keeps track of which elements have already been created.
+//
+// For each sort of "thing" (e.g., position, package, object, type)
+// that can be written into the export data, there are generally
+// several methods that work together:
+//
+// - writer.thing handles writing out a *use* of a thing, which often
+//   means writing a relocation to that thing's encoded index.
+//
+// - pkgWriter.thingIdx handles reserving an index for a thing, and
+//   writing out any elements needed for the thing.
+//
+// - writer.doThing handles writing out the *definition* of a thing,
+//   which in general is a mix of low-level coding primitives (e.g.,
+//   ints and strings) or uses of other things.
+//
+// A design goal of Unified IR is to have a single, canonical writer
+// implementation, but multiple reader implementations each tailored
+// to their respective needs. For example, within cmd/compile's own
+// backend, inlining is implemented largely by just re-running the
+// function body reading code.
+
+// TODO(mdempsky): Add an importer for Unified IR to the x/tools repo,
+// and better document the file format boundary between public and
+// private data.
+
+// A pkgWriter constructs Unified IR export data from the results of
+// running the types2 type checker on a Go compilation unit.
 type pkgWriter struct {
 	pkgbits.PkgEncoder
 
@@ -23,18 +61,29 @@
 	curpkg *types2.Package
 	info   *types2.Info
 
+	// Indices for previously written syntax and types2 things.
+
 	posBasesIdx map[*syntax.PosBase]pkgbits.Index
 	pkgsIdx     map[*types2.Package]pkgbits.Index
 	typsIdx     map[types2.Type]pkgbits.Index
-	globalsIdx  map[types2.Object]pkgbits.Index
+	objsIdx     map[types2.Object]pkgbits.Index
+
+	// Maps from types2.Objects back to their syntax.Decl.
 
 	funDecls map[*types2.Func]*syntax.FuncDecl
 	typDecls map[*types2.TypeName]typeDeclGen
 
-	linknames  map[types2.Object]string
+	// linknames maps package-scope objects to their linker symbol name,
+	// if specified by a //go:linkname directive.
+	linknames map[types2.Object]string
+
+	// cgoPragmas accumulates any //go:cgo_* pragmas that need to be
+	// passed through to cmd/link.
 	cgoPragmas [][]string
 }
 
+// newPkgWriter returns an initialized pkgWriter for the specified
+// package.
 func newPkgWriter(m posMap, pkg *types2.Package, info *types2.Info) *pkgWriter {
 	return &pkgWriter{
 		PkgEncoder: pkgbits.NewPkgEncoder(base.Debug.SyncFrames),
@@ -43,9 +92,9 @@
 		curpkg: pkg,
 		info:   info,
 
-		pkgsIdx:    make(map[*types2.Package]pkgbits.Index),
-		globalsIdx: make(map[types2.Object]pkgbits.Index),
-		typsIdx:    make(map[types2.Type]pkgbits.Index),
+		pkgsIdx: make(map[*types2.Package]pkgbits.Index),
+		objsIdx: make(map[types2.Object]pkgbits.Index),
+		typsIdx: make(map[types2.Type]pkgbits.Index),
 
 		posBasesIdx: make(map[*syntax.PosBase]pkgbits.Index),
 
@@ -56,34 +105,69 @@
 	}
 }
 
+// errorf reports a user error about thing p.
 func (pw *pkgWriter) errorf(p poser, msg string, args ...interface{}) {
 	base.ErrorfAt(pw.m.pos(p), msg, args...)
 }
 
+// fatalf reports an internal compiler error about thing p.
 func (pw *pkgWriter) fatalf(p poser, msg string, args ...interface{}) {
 	base.FatalfAt(pw.m.pos(p), msg, args...)
 }
 
+// unexpected reports a fatal error about a thing of unexpected
+// dynamic type.
 func (pw *pkgWriter) unexpected(what string, p poser) {
 	pw.fatalf(p, "unexpected %s: %v (%T)", what, p, p)
 }
 
+func (pw *pkgWriter) typeAndValue(x syntax.Expr) syntax.TypeAndValue {
+	tv := x.GetTypeInfo()
+	if tv.Type == nil {
+		pw.fatalf(x, "missing Types entry: %v", syntax.String(x))
+	}
+	return tv
+}
+func (pw *pkgWriter) maybeTypeAndValue(x syntax.Expr) (syntax.TypeAndValue, bool) {
+	tv := x.GetTypeInfo()
+	return tv, tv.Type != nil
+}
+
+// typeOf returns the Type of the given value expression.
+func (pw *pkgWriter) typeOf(expr syntax.Expr) types2.Type {
+	tv := pw.typeAndValue(expr)
+	if !tv.IsValue() {
+		pw.fatalf(expr, "expected value: %v", syntax.String(expr))
+	}
+	return tv.Type
+}
+
+// A writer provides APIs for writing out an individual element.
 type writer struct {
 	p *pkgWriter
 
 	pkgbits.Encoder
 
+	// sig holds the signature for the current function body, if any.
+	sig *types2.Signature
+
 	// TODO(mdempsky): We should be able to prune localsIdx whenever a
 	// scope closes, and then maybe we can just use the same map for
 	// storing the TypeParams too (as their TypeName instead).
 
-	// variables declared within this function
+	// localsIdx tracks any local variables declared within this
+	// function body. It's unused for writing out non-body things.
 	localsIdx map[*types2.Var]int
 
-	closureVars    []posObj
-	closureVarsIdx map[*types2.Var]int
+	// closureVars tracks any free variables that are referenced by this
+	// function body. It's unused for writing out non-body things.
+	closureVars    []posVar
+	closureVarsIdx map[*types2.Var]int // index of previously seen free variables
 
-	dict    *writerDict
+	dict *writerDict
+
+	// derived tracks whether the type being written out references any
+	// type parameters. It's unused for writing non-type things.
 	derived bool
 }
 
@@ -99,20 +183,36 @@
 	// derived slice, if present.
 	derivedIdx map[types2.Type]pkgbits.Index
 
-	// funcs lists references to generic functions that were
-	// instantiated with derived types (i.e., that require
-	// sub-dictionaries when called at run time).
-	funcs []objInfo
+	// These slices correspond to entries in the runtime dictionary.
+	typeParamMethodExprs []writerMethodExprInfo
+	subdicts             []objInfo
+	rtypes               []typeInfo
+	itabs                []itabInfo
+}
 
-	// itabs lists itabs that are needed for dynamic type assertions
-	// (including type switches).
-	itabs []itabInfo
+type itabInfo struct {
+	typ   typeInfo
+	iface typeInfo
+}
+
+// typeParamIndex returns the index of the given type parameter within
+// the dictionary. This may differ from typ.Index() when there are
+// implicit type parameters due to defined types declared within a
+// generic function or method.
+func (dict *writerDict) typeParamIndex(typ *types2.TypeParam) int {
+	for idx, implicit := range dict.implicits {
+		if implicit.Type().(*types2.TypeParam) == typ {
+			return idx
+		}
+	}
+
+	return len(dict.implicits) + typ.Index()
 }
 
 // A derivedInfo represents a reference to an encoded generic Go type.
 type derivedInfo struct {
 	idx    pkgbits.Index
-	needed bool
+	needed bool // TODO(mdempsky): Remove.
 }
 
 // A typeInfo represents a reference to an encoded Go type.
@@ -128,16 +228,23 @@
 	derived bool
 }
 
+// An objInfo represents a reference to an encoded, instantiated (if
+// applicable) Go object.
 type objInfo struct {
 	idx       pkgbits.Index // index for the generic function declaration
 	explicits []typeInfo    // info for the type arguments
 }
 
-type itabInfo struct {
-	typIdx pkgbits.Index // always a derived type index
-	iface  typeInfo      // always a non-empty interface type
+// A selectorInfo represents a reference to an encoded field or method
+// name (i.e., objects that can only be accessed using selector
+// expressions).
+type selectorInfo struct {
+	pkgIdx  pkgbits.Index
+	nameIdx pkgbits.Index
 }
 
+// anyDerived reports whether any of info's explicit type arguments
+// are derived types.
 func (info objInfo) anyDerived() bool {
 	for _, explicit := range info.explicits {
 		if explicit.derived {
@@ -147,6 +254,8 @@
 	return false
 }
 
+// equals reports whether info and other represent the same Go object
+// (i.e., same base object and identical type arguments, if any).
 func (info objInfo) equals(other objInfo) bool {
 	if info.idx != other.idx {
 		return false
@@ -160,6 +269,75 @@
 	return true
 }
 
+type writerMethodExprInfo struct {
+	typeParamIdx int
+	methodInfo   selectorInfo
+}
+
+// typeParamMethodExprIdx returns the index where the given encoded
+// method expression function pointer appears within this dictionary's
+// type parameters method expressions section, adding it if necessary.
+func (dict *writerDict) typeParamMethodExprIdx(typeParamIdx int, methodInfo selectorInfo) int {
+	newInfo := writerMethodExprInfo{typeParamIdx, methodInfo}
+
+	for idx, oldInfo := range dict.typeParamMethodExprs {
+		if oldInfo == newInfo {
+			return idx
+		}
+	}
+
+	idx := len(dict.typeParamMethodExprs)
+	dict.typeParamMethodExprs = append(dict.typeParamMethodExprs, newInfo)
+	return idx
+}
+
+// subdictIdx returns the index where the given encoded object's
+// runtime dictionary appears within this dictionary's subdictionary
+// section, adding it if necessary.
+func (dict *writerDict) subdictIdx(newInfo objInfo) int {
+	for idx, oldInfo := range dict.subdicts {
+		if oldInfo.equals(newInfo) {
+			return idx
+		}
+	}
+
+	idx := len(dict.subdicts)
+	dict.subdicts = append(dict.subdicts, newInfo)
+	return idx
+}
+
+// rtypeIdx returns the index where the given encoded type's
+// *runtime._type value appears within this dictionary's rtypes
+// section, adding it if necessary.
+func (dict *writerDict) rtypeIdx(newInfo typeInfo) int {
+	for idx, oldInfo := range dict.rtypes {
+		if oldInfo == newInfo {
+			return idx
+		}
+	}
+
+	idx := len(dict.rtypes)
+	dict.rtypes = append(dict.rtypes, newInfo)
+	return idx
+}
+
+// itabIdx returns the index where the given encoded type pair's
+// *runtime.itab value appears within this dictionary's itabs section,
+// adding it if necessary.
+func (dict *writerDict) itabIdx(typInfo, ifaceInfo typeInfo) int {
+	newInfo := itabInfo{typInfo, ifaceInfo}
+
+	for idx, oldInfo := range dict.itabs {
+		if oldInfo == newInfo {
+			return idx
+		}
+	}
+
+	idx := len(dict.itabs)
+	dict.itabs = append(dict.itabs, newInfo)
+	return idx
+}
+
 func (pw *pkgWriter) newWriter(k pkgbits.RelocKind, marker pkgbits.SyncMarker) *writer {
 	return &writer{
 		Encoder: pw.NewEncoder(k, marker),
@@ -169,6 +347,7 @@
 
 // @@@ Positions
 
+// pos writes the position of p into the element bitstream.
 func (w *writer) pos(p poser) {
 	w.Sync(pkgbits.SyncPos)
 	pos := p.Pos()
@@ -178,17 +357,19 @@
 		return
 	}
 
-	// TODO(mdempsky): Delta encoding. Also, if there's a b-side, update
-	// its position base too (but not vice versa!).
+	// TODO(mdempsky): Delta encoding.
 	w.posBase(pos.Base())
 	w.Uint(pos.Line())
 	w.Uint(pos.Col())
 }
 
+// posBase writes a reference to the given PosBase into the element
+// bitstream.
 func (w *writer) posBase(b *syntax.PosBase) {
 	w.Reloc(pkgbits.RelocPosBase, w.p.posBaseIdx(b))
 }
 
+// posBaseIdx returns the index for the given PosBase.
 func (pw *pkgWriter) posBaseIdx(b *syntax.PosBase) pkgbits.Index {
 	if idx, ok := pw.posBasesIdx[b]; ok {
 		return idx
@@ -210,11 +391,18 @@
 
 // @@@ Packages
 
+// pkg writes a use of the given Package into the element bitstream.
 func (w *writer) pkg(pkg *types2.Package) {
-	w.Sync(pkgbits.SyncPkg)
-	w.Reloc(pkgbits.RelocPkg, w.p.pkgIdx(pkg))
+	w.pkgRef(w.p.pkgIdx(pkg))
 }
 
+func (w *writer) pkgRef(idx pkgbits.Index) {
+	w.Sync(pkgbits.SyncPkg)
+	w.Reloc(pkgbits.RelocPkg, idx)
+}
+
+// pkgIdx returns the index for the given package, adding it to the
+// package export data if needed.
 func (pw *pkgWriter) pkgIdx(pkg *types2.Package) pkgbits.Index {
 	if idx, ok := pw.pkgsIdx[pkg]; ok {
 		return idx
@@ -241,7 +429,6 @@
 		base.Assertf(path != "builtin" && path != "unsafe", "unexpected path for user-defined package: %q", path)
 		w.String(path)
 		w.String(pkg.Name())
-		w.Len(pkg.Height())
 
 		w.Len(len(pkg.Imports()))
 		for _, imp := range pkg.Imports() {
@@ -254,12 +441,19 @@
 
 // @@@ Types
 
-var anyTypeName = types2.Universe.Lookup("any").(*types2.TypeName)
+var (
+	anyTypeName        = types2.Universe.Lookup("any").(*types2.TypeName)
+	comparableTypeName = types2.Universe.Lookup("comparable").(*types2.TypeName)
+	runeTypeName       = types2.Universe.Lookup("rune").(*types2.TypeName)
+)
 
+// typ writes a use of the given type into the bitstream.
 func (w *writer) typ(typ types2.Type) {
 	w.typInfo(w.p.typIdx(typ, w.dict))
 }
 
+// typInfo writes a use of the given type (specified as a typeInfo
+// instead) into the bitstream.
 func (w *writer) typInfo(info typeInfo) {
 	w.Sync(pkgbits.SyncType)
 	if w.Bool(info.derived) {
@@ -302,7 +496,7 @@
 			w.Len(int(kind))
 
 		default:
-			// Handle "byte" and "rune" as references to their TypeName.
+			// Handle "byte" and "rune" as references to their TypeNames.
 			obj := types2.Universe.Lookup(typ.Name())
 			assert(obj.Type() == typ)
 
@@ -311,31 +505,21 @@
 		}
 
 	case *types2.Named:
-		assert(typ.TypeParams().Len() == typ.TypeArgs().Len())
+		obj, targs := splitNamed(typ)
 
-		// TODO(mdempsky): Why do we need to loop here?
-		orig := typ
-		for orig.TypeArgs() != nil {
-			orig = orig.Origin()
+		// Defined types that are declared within a generic function (and
+		// thus have implicit type parameters) are always derived types.
+		if w.p.hasImplicitTypeParams(obj) {
+			w.derived = true
 		}
 
 		w.Code(pkgbits.TypeNamed)
-		w.obj(orig.Obj(), typ.TypeArgs())
+		w.obj(obj, targs)
 
 	case *types2.TypeParam:
-		index := func() int {
-			for idx, name := range w.dict.implicits {
-				if name.Type().(*types2.TypeParam) == typ {
-					return idx
-				}
-			}
-
-			return len(w.dict.implicits) + typ.Index()
-		}()
-
 		w.derived = true
 		w.Code(pkgbits.TypeTypeParam)
-		w.Len(index)
+		w.Len(w.dict.typeParamIndex(typ))
 
 	case *types2.Array:
 		w.Code(pkgbits.TypeArray)
@@ -370,6 +554,7 @@
 		w.structType(typ)
 
 	case *types2.Interface:
+		// Handle "any" as reference to its TypeName.
 		if typ == anyTypeName.Type() {
 			w.Code(pkgbits.TypeNamed)
 			w.obj(anyTypeName, nil)
@@ -417,6 +602,23 @@
 }
 
 func (w *writer) interfaceType(typ *types2.Interface) {
+	// If typ has no embedded types but it's not a basic interface, then
+	// the natural description we write out below will fail to
+	// reconstruct it.
+	if typ.NumEmbeddeds() == 0 && !typ.IsMethodSet() {
+		// Currently, this can only happen for the underlying Interface of
+		// "comparable", which is needed to handle type declarations like
+		// "type C comparable".
+		assert(typ == comparableTypeName.Type().(*types2.Named).Underlying())
+
+		// Export as "interface{ comparable }".
+		w.Len(0)                         // NumExplicitMethods
+		w.Len(1)                         // NumEmbeddeds
+		w.Bool(false)                    // IsImplicit
+		w.typ(comparableTypeName.Type()) // EmbeddedType(0)
+		return
+	}
+
 	w.Len(typ.NumExplicitMethods())
 	w.Len(typ.NumEmbeddeds())
 
@@ -468,45 +670,20 @@
 
 // @@@ Objects
 
+// obj writes a use of the given object into the bitstream.
+//
+// If obj is a generic object, then explicits are the explicit type
+// arguments used to instantiate it (i.e., used to substitute the
+// object's own declared type parameters).
 func (w *writer) obj(obj types2.Object, explicits *types2.TypeList) {
-	explicitInfos := make([]typeInfo, explicits.Len())
-	for i := range explicitInfos {
-		explicitInfos[i] = w.p.typIdx(explicits.At(i), w.dict)
-	}
-	info := objInfo{idx: w.p.objIdx(obj), explicits: explicitInfos}
+	w.objInfo(w.p.objInstIdx(obj, explicits, w.dict))
+}
 
-	if _, ok := obj.(*types2.Func); ok && info.anyDerived() {
-		idx := -1
-		for i, prev := range w.dict.funcs {
-			if prev.equals(info) {
-				idx = i
-			}
-		}
-		if idx < 0 {
-			idx = len(w.dict.funcs)
-			w.dict.funcs = append(w.dict.funcs, info)
-		}
-
-		// TODO(mdempsky): Push up into expr; this shouldn't appear
-		// outside of expression context.
-		w.Sync(pkgbits.SyncObject)
-		w.Bool(true)
-		w.Len(idx)
-		return
-	}
-
-	// TODO(mdempsky): Push up into typIdx; this shouldn't be needed
-	// except while writing out types.
-	if isDefinedType(obj) && obj.Pkg() == w.p.curpkg {
-		decl, ok := w.p.typDecls[obj.(*types2.TypeName)]
-		assert(ok)
-		if len(decl.implicits) != 0 {
-			w.derived = true
-		}
-	}
-
+// objInfo writes a use of the given encoded object into the
+// bitstream.
+func (w *writer) objInfo(info objInfo) {
 	w.Sync(pkgbits.SyncObject)
-	w.Bool(false)
+	w.Bool(false) // TODO(mdempsky): Remove; was derived func inst.
 	w.Reloc(pkgbits.RelocObj, info.idx)
 
 	w.Len(len(info.explicits))
@@ -515,8 +692,24 @@
 	}
 }
 
+// objInstIdx returns the indices for an object and a corresponding
+// list of type arguments used to instantiate it, adding them to the
+// export data as needed.
+func (pw *pkgWriter) objInstIdx(obj types2.Object, explicits *types2.TypeList, dict *writerDict) objInfo {
+	explicitInfos := make([]typeInfo, explicits.Len())
+	for i := range explicitInfos {
+		explicitInfos[i] = pw.typIdx(explicits.At(i), dict)
+	}
+	return objInfo{idx: pw.objIdx(obj), explicits: explicitInfos}
+}
+
+// objIdx returns the index for the given Object, adding it to the
+// export data as needed.
 func (pw *pkgWriter) objIdx(obj types2.Object) pkgbits.Index {
-	if idx, ok := pw.globalsIdx[obj]; ok {
+	// TODO(mdempsky): Validate that obj is a global object (or a local
+	// defined type, which we hoist to global scope anyway).
+
+	if idx, ok := pw.objsIdx[obj]; ok {
 		return idx
 	}
 
@@ -530,12 +723,35 @@
 		dict.implicits = decl.implicits
 	}
 
+	// We encode objects into 4 elements across different sections, all
+	// sharing the same index:
+	//
+	// - RelocName has just the object's qualified name (i.e.,
+	//   Object.Pkg and Object.Name) and the CodeObj indicating what
+	//   specific type of Object it is (Var, Func, etc).
+	//
+	// - RelocObj has the remaining public details about the object,
+	//   relevant to go/types importers.
+	//
+	// - RelocObjExt has additional private details about the object,
+	//   which are only relevant to cmd/compile itself. This is
+	//   separated from RelocObj so that go/types importers are
+	//   unaffected by internal compiler changes.
+	//
+	// - RelocObjDict has public details about the object's type
+	//   parameters and derived type's used by the object. This is
+	//   separated to facilitate the eventual introduction of
+	//   shape-based stenciling.
+	//
+	// TODO(mdempsky): Re-evaluate whether RelocName still makes sense
+	// to keep separate from RelocObj.
+
 	w := pw.newWriter(pkgbits.RelocObj, pkgbits.SyncObject1)
 	wext := pw.newWriter(pkgbits.RelocObjExt, pkgbits.SyncObject1)
 	wname := pw.newWriter(pkgbits.RelocName, pkgbits.SyncObject1)
 	wdict := pw.newWriter(pkgbits.RelocObjDict, pkgbits.SyncObject1)
 
-	pw.globalsIdx[obj] = w.Idx // break cycles
+	pw.objsIdx[obj] = w.Idx // break cycles
 	assert(wext.Idx == w.Idx)
 	assert(wname.Idx == w.Idx)
 	assert(wdict.Idx == w.Idx)
@@ -557,6 +773,8 @@
 	return w.Idx
 }
 
+// doObj writes the RelocObj definition for obj to w, and the
+// RelocObjExt definition to wext.
 func (w *writer) doObj(wext *writer, obj types2.Object) pkgbits.CodeObj {
 	if obj.Pkg() != w.p.curpkg {
 		return pkgbits.ObjStub
@@ -586,9 +804,6 @@
 		return pkgbits.ObjFunc
 
 	case *types2.TypeName:
-		decl, ok := w.p.typDecls[obj]
-		assert(ok)
-
 		if obj.IsAlias() {
 			w.pos(obj)
 			w.typ(obj.Type())
@@ -601,7 +816,7 @@
 		w.pos(obj)
 		w.typeParamNames(named.TypeParams())
 		wext.typeExt(obj)
-		w.typExpr(decl.Type)
+		w.typ(named.Underlying())
 
 		w.Len(named.NumMethods())
 		for i := 0; i < named.NumMethods(); i++ {
@@ -618,14 +833,6 @@
 	}
 }
 
-// typExpr writes the type represented by the given expression.
-func (w *writer) typExpr(expr syntax.Expr) {
-	tv, ok := w.p.info.Types[expr]
-	assert(ok)
-	assert(tv.IsType())
-	w.typ(tv.Type)
-}
-
 // objDict writes the dictionary needed for reading the given object.
 func (w *writer) objDict(obj types2.Object, dict *writerDict) {
 	// TODO(mdempsky): Split objDict into multiple entries? reader.go
@@ -650,25 +857,53 @@
 		w.Bool(typ.needed)
 	}
 
-	nfuncs := len(dict.funcs)
-	w.Len(nfuncs)
-	for _, fn := range dict.funcs {
-		w.Reloc(pkgbits.RelocObj, fn.idx)
-		w.Len(len(fn.explicits))
-		for _, targ := range fn.explicits {
-			w.typInfo(targ)
-		}
+	// Write runtime dictionary information.
+	//
+	// N.B., the go/types importer reads up to the section, but doesn't
+	// read any further, so it's safe to change. (See TODO above.)
+
+	// For each type parameter, write out whether the constraint is a
+	// basic interface. This is used to determine how aggressively we
+	// can shape corresponding type arguments.
+	//
+	// This is somewhat redundant with writing out the full type
+	// parameter constraints above, but the compiler currently skips
+	// over those. Also, we don't care about the *declared* constraints,
+	// but how the type parameters are actually *used*. E.g., if a type
+	// parameter is constrained to `int | uint` but then never used in
+	// arithmetic/conversions/etc, we could shape those together.
+	for _, implicit := range dict.implicits {
+		tparam := implicit.Type().(*types2.TypeParam)
+		w.Bool(tparam.Underlying().(*types2.Interface).IsMethodSet())
+	}
+	for i := 0; i < ntparams; i++ {
+		tparam := tparams.At(i)
+		w.Bool(tparam.Underlying().(*types2.Interface).IsMethodSet())
 	}
 
-	nitabs := len(dict.itabs)
-	w.Len(nitabs)
-	for _, itab := range dict.itabs {
-		w.Len(int(itab.typIdx))
-		w.typInfo(itab.iface)
+	w.Len(len(dict.typeParamMethodExprs))
+	for _, info := range dict.typeParamMethodExprs {
+		w.Len(info.typeParamIdx)
+		w.selectorInfo(info.methodInfo)
+	}
+
+	w.Len(len(dict.subdicts))
+	for _, info := range dict.subdicts {
+		w.objInfo(info)
+	}
+
+	w.Len(len(dict.rtypes))
+	for _, info := range dict.rtypes {
+		w.typInfo(info)
+	}
+
+	w.Len(len(dict.itabs))
+	for _, info := range dict.itabs {
+		w.typInfo(info.typ)
+		w.typInfo(info.iface)
 	}
 
 	assert(len(dict.derived) == nderived)
-	assert(len(dict.funcs) == nfuncs)
 }
 
 func (w *writer) typeParamNames(tparams *types2.TypeParamList) {
@@ -708,8 +943,11 @@
 		decl, ok := w.p.typDecls[obj.(*types2.TypeName)]
 		assert(ok)
 		if decl.gen != 0 {
-			// TODO(mdempsky): Find a better solution than embedding middle
-			// dot in the symbol name; this is terrible.
+			// For local defined types, we embed a scope-disambiguation
+			// number directly into their name. types.SplitVargenSuffix then
+			// knows to look for this.
+			//
+			// TODO(mdempsky): Find a better solution; this is terrible.
 			name = fmt.Sprintf("%s·%v", name, decl.gen)
 		}
 	}
@@ -724,8 +962,8 @@
 // me a little nervous to try it again.
 
 // localIdent writes the name of a locally declared object (i.e.,
-// objects that can only be accessed by name, within the context of a
-// particular function).
+// objects that can only be accessed by non-qualified name, within the
+// context of a particular function).
 func (w *writer) localIdent(obj types2.Object) {
 	assert(!isGlobal(obj))
 	w.Sync(pkgbits.SyncLocalIdent)
@@ -736,9 +974,19 @@
 // selector writes the name of a field or method (i.e., objects that
 // can only be accessed using selector expressions).
 func (w *writer) selector(obj types2.Object) {
+	w.selectorInfo(w.p.selectorIdx(obj))
+}
+
+func (w *writer) selectorInfo(info selectorInfo) {
 	w.Sync(pkgbits.SyncSelector)
-	w.pkg(obj.Pkg())
-	w.String(obj.Name())
+	w.pkgRef(info.pkgIdx)
+	w.StringRef(info.nameIdx)
+}
+
+func (pw *pkgWriter) selectorIdx(obj types2.Object) selectorInfo {
+	pkgIdx := pw.pkgIdx(obj.Pkg())
+	nameIdx := pw.StringIdx(obj.Name())
+	return selectorInfo{pkgIdx: pkgIdx, nameIdx: nameIdx}
 }
 
 // @@@ Compiler extensions
@@ -787,7 +1035,7 @@
 	}
 
 	sig, block := obj.Type().(*types2.Signature), decl.Body
-	body, closureVars := w.p.bodyIdx(w.p.curpkg, sig, block, w.dict)
+	body, closureVars := w.p.bodyIdx(sig, block, w.dict)
 	assert(len(closureVars) == 0)
 
 	w.Sync(pkgbits.SyncFuncExt)
@@ -829,8 +1077,11 @@
 
 // @@@ Function bodies
 
-func (pw *pkgWriter) bodyIdx(pkg *types2.Package, sig *types2.Signature, block *syntax.BlockStmt, dict *writerDict) (idx pkgbits.Index, closureVars []posObj) {
+// bodyIdx returns the index for the given function body (specified by
+// block), adding it to the export data
+func (pw *pkgWriter) bodyIdx(sig *types2.Signature, block *syntax.BlockStmt, dict *writerDict) (idx pkgbits.Index, closureVars []posVar) {
 	w := pw.newWriter(pkgbits.RelocBody, pkgbits.SyncFuncBody)
+	w.sig = sig
 	w.dict = dict
 
 	w.funcargs(sig)
@@ -862,18 +1113,24 @@
 	}
 }
 
+// addLocal records the declaration of a new local variable.
 func (w *writer) addLocal(obj *types2.Var) {
-	w.Sync(pkgbits.SyncAddLocal)
 	idx := len(w.localsIdx)
-	if pkgbits.EnableSync {
+
+	w.Sync(pkgbits.SyncAddLocal)
+	if w.p.SyncMarkers() {
 		w.Int(idx)
 	}
+	w.varDictIndex(obj)
+
 	if w.localsIdx == nil {
 		w.localsIdx = make(map[*types2.Var]int)
 	}
 	w.localsIdx[obj] = idx
 }
 
+// useLocal writes a reference to the given local or free variable
+// into the bitstream.
 func (w *writer) useLocal(pos syntax.Pos, obj *types2.Var) {
 	w.Sync(pkgbits.SyncUseObjLocal)
 
@@ -888,7 +1145,7 @@
 			w.closureVarsIdx = make(map[*types2.Var]int)
 		}
 		idx = len(w.closureVars)
-		w.closureVars = append(w.closureVars, posObj{pos, obj})
+		w.closureVars = append(w.closureVars, posVar{pos, obj})
 		w.closureVarsIdx[obj] = idx
 	}
 	w.Len(idx)
@@ -911,6 +1168,7 @@
 
 // @@@ Statements
 
+// stmt writes the given statement into the function body bitstream.
 func (w *writer) stmt(stmt syntax.Stmt) {
 	var stmts []syntax.Stmt
 	if stmt != nil {
@@ -949,13 +1207,15 @@
 			w.op(binOps[stmt.Op])
 			w.expr(stmt.Lhs)
 			w.pos(stmt)
-			w.expr(stmt.Rhs)
+
+			var typ types2.Type
+			if stmt.Op != syntax.Shl && stmt.Op != syntax.Shr {
+				typ = w.p.typeOf(stmt.Lhs)
+			}
+			w.implicitConvExpr(typ, stmt.Rhs)
 
 		default:
-			w.Code(stmtAssign)
-			w.pos(stmt)
-			w.exprList(stmt.Rhs)
-			w.assignList(stmt.Lhs)
+			w.assignStmt(stmt, stmt.Lhs, stmt.Rhs)
 		}
 
 	case *syntax.BlockStmt:
@@ -1000,17 +1260,24 @@
 	case *syntax.ReturnStmt:
 		w.Code(stmtReturn)
 		w.pos(stmt)
-		w.exprList(stmt.Results)
+
+		resultTypes := w.sig.Results()
+		dstType := func(i int) types2.Type {
+			return resultTypes.At(i).Type()
+		}
+		w.multiExpr(stmt, dstType, unpackListExpr(stmt.Results))
 
 	case *syntax.SelectStmt:
 		w.Code(stmtSelect)
 		w.selectStmt(stmt)
 
 	case *syntax.SendStmt:
+		chanType := types2.CoreType(w.p.typeOf(stmt.Chan)).(*types2.Chan)
+
 		w.Code(stmtSend)
 		w.pos(stmt)
 		w.expr(stmt.Chan)
-		w.expr(stmt.Value)
+		w.implicitConvExpr(chanType.Elem(), stmt.Value)
 
 	case *syntax.SwitchStmt:
 		w.Code(stmtSwitch)
@@ -1023,25 +1290,36 @@
 	w.Len(len(exprs))
 
 	for _, expr := range exprs {
-		if name, ok := expr.(*syntax.Name); ok && name.Value != "_" {
-			if obj, ok := w.p.info.Defs[name]; ok {
-				obj := obj.(*types2.Var)
+		w.assign(expr)
+	}
+}
 
-				w.Bool(true)
-				w.pos(obj)
-				w.localIdent(obj)
-				w.typ(obj.Type())
+func (w *writer) assign(expr syntax.Expr) {
+	expr = unparen(expr)
 
-				// TODO(mdempsky): Minimize locals index size by deferring
-				// this until the variables actually come into scope.
-				w.addLocal(obj)
-				continue
-			}
+	if name, ok := expr.(*syntax.Name); ok {
+		if name.Value == "_" {
+			w.Code(assignBlank)
+			return
 		}
 
-		w.Bool(false)
-		w.expr(expr)
+		if obj, ok := w.p.info.Defs[name]; ok {
+			obj := obj.(*types2.Var)
+
+			w.Code(assignDef)
+			w.pos(obj)
+			w.localIdent(obj)
+			w.typ(obj.Type())
+
+			// TODO(mdempsky): Minimize locals index size by deferring
+			// this until the variables actually come into scope.
+			w.addLocal(obj)
+			return
+		}
 	}
+
+	w.Code(assignExpr)
+	w.expr(expr)
 }
 
 func (w *writer) declStmt(decl syntax.Decl) {
@@ -1052,13 +1330,48 @@
 	case *syntax.ConstDecl, *syntax.TypeDecl:
 
 	case *syntax.VarDecl:
-		w.Code(stmtAssign)
-		w.pos(decl)
-		w.exprList(decl.Values)
-		w.assignList(namesAsExpr(decl.NameList))
+		w.assignStmt(decl, namesAsExpr(decl.NameList), decl.Values)
 	}
 }
 
+// assignStmt writes out an assignment for "lhs = rhs".
+func (w *writer) assignStmt(pos poser, lhs0, rhs0 syntax.Expr) {
+	lhs := unpackListExpr(lhs0)
+	rhs := unpackListExpr(rhs0)
+
+	w.Code(stmtAssign)
+	w.pos(pos)
+
+	// As if w.assignList(lhs0).
+	w.Len(len(lhs))
+	for _, expr := range lhs {
+		w.assign(expr)
+	}
+
+	dstType := func(i int) types2.Type {
+		dst := lhs[i]
+
+		// Finding dstType is somewhat involved, because for VarDecl
+		// statements, the Names are only added to the info.{Defs,Uses}
+		// maps, not to info.Types.
+		if name, ok := unparen(dst).(*syntax.Name); ok {
+			if name.Value == "_" {
+				return nil // ok: no implicit conversion
+			} else if def, ok := w.p.info.Defs[name].(*types2.Var); ok {
+				return def.Type()
+			} else if use, ok := w.p.info.Uses[name].(*types2.Var); ok {
+				return use.Type()
+			} else {
+				w.p.fatalf(dst, "cannot find type of destination object: %v", dst)
+			}
+		}
+
+		return w.p.typeOf(dst)
+	}
+
+	w.multiExpr(pos, dstType, rhs)
+}
+
 func (w *writer) blockStmt(stmt *syntax.BlockStmt) {
 	w.Sync(pkgbits.SyncBlockStmt)
 	w.openScope(stmt.Pos())
@@ -1072,12 +1385,45 @@
 
 	if rang, ok := stmt.Init.(*syntax.RangeClause); w.Bool(ok) {
 		w.pos(rang)
-		w.expr(rang.X)
 		w.assignList(rang.Lhs)
+		w.expr(rang.X)
+
+		xtyp := w.p.typeOf(rang.X)
+		if _, isMap := types2.CoreType(xtyp).(*types2.Map); isMap {
+			w.rtype(xtyp)
+		}
+		{
+			lhs := unpackListExpr(rang.Lhs)
+			assign := func(i int, src types2.Type) {
+				if i >= len(lhs) {
+					return
+				}
+				dst := unparen(lhs[i])
+				if name, ok := dst.(*syntax.Name); ok && name.Value == "_" {
+					return
+				}
+
+				var dstType types2.Type
+				if rang.Def {
+					// For `:=` assignments, the LHS names only appear in Defs,
+					// not Types (as used by typeOf).
+					dstType = w.p.info.Defs[dst.(*syntax.Name)].(*types2.Var).Type()
+				} else {
+					dstType = w.p.typeOf(dst)
+				}
+
+				w.convRTTI(src, dstType)
+			}
+
+			keyType, valueType := w.p.rangeTypes(rang.X)
+			assign(0, keyType)
+			assign(1, valueType)
+		}
+
 	} else {
 		w.pos(stmt)
 		w.stmt(stmt.Init)
-		w.expr(stmt.Cond)
+		w.optExpr(stmt.Cond)
 		w.stmt(stmt.Post)
 	}
 
@@ -1085,6 +1431,30 @@
 	w.closeAnotherScope()
 }
 
+// rangeTypes returns the types of values produced by ranging over
+// expr.
+func (pw *pkgWriter) rangeTypes(expr syntax.Expr) (key, value types2.Type) {
+	typ := pw.typeOf(expr)
+	switch typ := types2.CoreType(typ).(type) {
+	case *types2.Pointer: // must be pointer to array
+		return types2.Typ[types2.Int], types2.CoreType(typ.Elem()).(*types2.Array).Elem()
+	case *types2.Array:
+		return types2.Typ[types2.Int], typ.Elem()
+	case *types2.Slice:
+		return types2.Typ[types2.Int], typ.Elem()
+	case *types2.Basic:
+		if typ.Info()&types2.IsString != 0 {
+			return types2.Typ[types2.Int], runeTypeName.Type()
+		}
+	case *types2.Map:
+		return typ.Key(), typ.Elem()
+	case *types2.Chan:
+		return typ.Elem(), nil
+	}
+	pw.fatalf(expr, "unexpected range type: %v", typ)
+	panic("unreachable")
+}
+
 func (w *writer) ifStmt(stmt *syntax.IfStmt) {
 	w.Sync(pkgbits.SyncIfStmt)
 	w.openScope(stmt.Pos())
@@ -1123,20 +1493,47 @@
 	w.pos(stmt)
 	w.stmt(stmt.Init)
 
-	var iface types2.Type
+	var iface, tagType types2.Type
 	if guard, ok := stmt.Tag.(*syntax.TypeSwitchGuard); w.Bool(ok) {
-		tv, ok := w.p.info.Types[guard.X]
-		assert(ok && tv.IsValue())
-		iface = tv.Type
+		iface = w.p.typeOf(guard.X)
 
 		w.pos(guard)
 		if tag := guard.Lhs; w.Bool(tag != nil) {
 			w.pos(tag)
+
+			// Like w.localIdent, but we don't have a types2.Object.
+			w.Sync(pkgbits.SyncLocalIdent)
+			w.pkg(w.p.curpkg)
 			w.String(tag.Value)
 		}
 		w.expr(guard.X)
 	} else {
-		w.expr(stmt.Tag)
+		tag := stmt.Tag
+
+		if tag != nil {
+			tagType = w.p.typeOf(tag)
+		} else {
+			tagType = types2.Typ[types2.Bool]
+		}
+
+		// Walk is going to emit comparisons between the tag value and
+		// each case expression, and we want these comparisons to always
+		// have the same type. If there are any case values that can't be
+		// converted to the tag value's type, then convert everything to
+		// `any` instead.
+	Outer:
+		for _, clause := range stmt.Body {
+			for _, cas := range unpackListExpr(clause.Cases) {
+				if casType := w.p.typeOf(cas); !types2.AssignableTo(casType, tagType) {
+					tagType = types2.NewInterfaceType(nil, nil)
+					break Outer
+				}
+			}
+		}
+
+		if w.Bool(tag != nil) {
+			w.implicitConvExpr(tagType, tag)
+		}
 	}
 
 	w.Len(len(stmt.Body))
@@ -1148,14 +1545,25 @@
 
 		w.pos(clause)
 
+		cases := unpackListExpr(clause.Cases)
 		if iface != nil {
-			cases := unpackListExpr(clause.Cases)
 			w.Len(len(cases))
 			for _, cas := range cases {
-				w.exprType(iface, cas, true)
+				if w.Bool(isNil(w.p, cas)) {
+					continue
+				}
+				w.exprType(iface, cas)
 			}
 		} else {
-			w.exprList(clause.Cases)
+			// As if w.exprList(clause.Cases),
+			// but with implicit conversions to tagType.
+
+			w.Sync(pkgbits.SyncExprList)
+			w.Sync(pkgbits.SyncExprs)
+			w.Len(len(cases))
+			for _, cas := range cases {
+				w.implicitConvExpr(tagType, cas)
+			}
 		}
 
 		if obj, ok := w.p.info.Implicits[clause]; ok {
@@ -1200,30 +1608,26 @@
 
 // @@@ Expressions
 
+// expr writes the given expression into the function body bitstream.
 func (w *writer) expr(expr syntax.Expr) {
+	base.Assertf(expr != nil, "missing expression")
+
 	expr = unparen(expr) // skip parens; unneeded after typecheck
 
-	obj, inst := lookupObj(w.p.info, expr)
+	obj, inst := lookupObj(w.p, expr)
 	targs := inst.TypeArgs
 
-	if tv, ok := w.p.info.Types[expr]; ok {
-		// TODO(mdempsky): Be more judicious about which types are marked as "needed".
-		if inst.Type != nil {
-			w.needType(inst.Type)
-		} else {
-			w.needType(tv.Type)
-		}
-
+	if tv, ok := w.p.maybeTypeAndValue(expr); ok {
 		if tv.IsType() {
-			w.Code(exprType)
-			w.exprType(nil, expr, false)
-			return
+			w.p.fatalf(expr, "unexpected type expression %v", syntax.String(expr))
 		}
 
 		if tv.Value != nil {
 			w.Code(exprConst)
 			w.pos(expr)
-			w.typ(tv.Type)
+			typ := idealType(tv)
+			assert(typ != nil)
+			w.typ(typ)
 			w.Value(tv.Value)
 
 			// TODO(mdempsky): These details are only important for backend
@@ -1232,18 +1636,43 @@
 			w.String(syntax.String(expr))
 			return
 		}
+
+		if _, isNil := obj.(*types2.Nil); isNil {
+			w.Code(exprNil)
+			w.pos(expr)
+			w.typ(tv.Type)
+			return
+		}
+
+		// With shape types (and particular pointer shaping), we may have
+		// an expression of type "go.shape.*uint8", but need to reshape it
+		// to another shape-identical type to allow use in field
+		// selection, indexing, etc.
+		if typ := tv.Type; !tv.IsBuiltin() && !isTuple(typ) && !isUntyped(typ) {
+			w.Code(exprReshape)
+			w.typ(typ)
+			// fallthrough
+		}
 	}
 
 	if obj != nil {
+		if targs.Len() != 0 {
+			obj := obj.(*types2.Func)
+
+			w.Code(exprFuncInst)
+			w.pos(expr)
+			w.funcInst(obj, targs)
+			return
+		}
+
 		if isGlobal(obj) {
-			w.Code(exprName)
-			w.obj(obj, targs)
+			w.Code(exprGlobal)
+			w.obj(obj, nil)
 			return
 		}
 
 		obj := obj.(*types2.Var)
 		assert(!obj.IsField())
-		assert(targs.Len() == 0)
 
 		w.Code(exprLocal)
 		w.useLocal(expr.Pos(), obj)
@@ -1254,13 +1683,6 @@
 	default:
 		w.p.unexpected("expression", expr)
 
-	case nil: // absent slice index, for condition, or switch tag
-		w.Code(exprNone)
-
-	case *syntax.Name:
-		assert(expr.Value == "_")
-		w.Code(exprBlank)
-
 	case *syntax.CompositeLit:
 		w.Code(exprCompLit)
 		w.compLit(expr)
@@ -1273,36 +1695,85 @@
 		sel, ok := w.p.info.Selections[expr]
 		assert(ok)
 
-		w.Code(exprSelector)
-		w.expr(expr.X)
-		w.pos(expr)
-		w.selector(sel.Obj())
+		switch sel.Kind() {
+		default:
+			w.p.fatalf(expr, "unexpected selection kind: %v", sel.Kind())
+
+		case types2.FieldVal:
+			w.Code(exprFieldVal)
+			w.expr(expr.X)
+			w.pos(expr)
+			w.selector(sel.Obj())
+
+		case types2.MethodVal:
+			w.Code(exprMethodVal)
+			typ := w.recvExpr(expr, sel)
+			w.pos(expr)
+			w.methodExpr(expr, typ, sel)
+
+		case types2.MethodExpr:
+			w.Code(exprMethodExpr)
+
+			tv := w.p.typeAndValue(expr.X)
+			assert(tv.IsType())
+
+			index := sel.Index()
+			implicits := index[:len(index)-1]
+
+			typ := tv.Type
+			w.typ(typ)
+
+			w.Len(len(implicits))
+			for _, ix := range implicits {
+				w.Len(ix)
+				typ = deref2(typ).Underlying().(*types2.Struct).Field(ix).Type()
+			}
+
+			recv := sel.Obj().(*types2.Func).Type().(*types2.Signature).Recv().Type()
+			if w.Bool(isPtrTo(typ, recv)) { // need deref
+				typ = recv
+			} else if w.Bool(isPtrTo(recv, typ)) { // need addr
+				typ = recv
+			}
+
+			w.pos(expr)
+			w.methodExpr(expr, typ, sel)
+		}
 
 	case *syntax.IndexExpr:
-		tv, ok := w.p.info.Types[expr.Index]
-		assert(ok && tv.IsValue())
+		_ = w.p.typeOf(expr.Index) // ensure this is an index expression, not an instantiation
+
+		xtyp := w.p.typeOf(expr.X)
+
+		var keyType types2.Type
+		if mapType, ok := types2.CoreType(xtyp).(*types2.Map); ok {
+			keyType = mapType.Key()
+		}
 
 		w.Code(exprIndex)
 		w.expr(expr.X)
 		w.pos(expr)
-		w.expr(expr.Index)
+		w.implicitConvExpr(keyType, expr.Index)
+		if keyType != nil {
+			w.rtype(xtyp)
+		}
 
 	case *syntax.SliceExpr:
 		w.Code(exprSlice)
 		w.expr(expr.X)
 		w.pos(expr)
 		for _, n := range &expr.Index {
-			w.expr(n)
+			w.optExpr(n)
 		}
 
 	case *syntax.AssertExpr:
-		tv, ok := w.p.info.Types[expr.X]
-		assert(ok && tv.IsValue())
+		iface := w.p.typeOf(expr.X)
 
 		w.Code(exprAssert)
 		w.expr(expr.X)
 		w.pos(expr)
-		w.exprType(tv.Type, expr.Type, false)
+		w.exprType(iface, expr.Type)
+		w.rtype(iface)
 
 	case *syntax.Operation:
 		if expr.Y == nil {
@@ -1313,94 +1784,386 @@
 			break
 		}
 
+		var commonType types2.Type
+		switch expr.Op {
+		case syntax.Shl, syntax.Shr:
+			// ok: operands are allowed to have different types
+		default:
+			xtyp := w.p.typeOf(expr.X)
+			ytyp := w.p.typeOf(expr.Y)
+			switch {
+			case types2.AssignableTo(xtyp, ytyp):
+				commonType = ytyp
+			case types2.AssignableTo(ytyp, xtyp):
+				commonType = xtyp
+			default:
+				w.p.fatalf(expr, "failed to find common type between %v and %v", xtyp, ytyp)
+			}
+		}
+
 		w.Code(exprBinaryOp)
 		w.op(binOps[expr.Op])
-		w.expr(expr.X)
+		w.implicitConvExpr(commonType, expr.X)
 		w.pos(expr)
-		w.expr(expr.Y)
+		w.implicitConvExpr(commonType, expr.Y)
 
 	case *syntax.CallExpr:
-		tv, ok := w.p.info.Types[expr.Fun]
-		assert(ok)
+		tv := w.p.typeAndValue(expr.Fun)
 		if tv.IsType() {
 			assert(len(expr.ArgList) == 1)
 			assert(!expr.HasDots)
-
-			w.Code(exprConvert)
-			w.typ(tv.Type)
-			w.pos(expr)
-			w.expr(expr.ArgList[0])
+			w.convertExpr(tv.Type, expr.ArgList[0], false)
 			break
 		}
 
+		var rtype types2.Type
+		if tv.IsBuiltin() {
+			switch obj, _ := lookupObj(w.p, expr.Fun); obj.Name() {
+			case "make":
+				assert(len(expr.ArgList) >= 1)
+				assert(!expr.HasDots)
+
+				w.Code(exprMake)
+				w.pos(expr)
+				w.exprType(nil, expr.ArgList[0])
+				w.exprs(expr.ArgList[1:])
+
+				typ := w.p.typeOf(expr)
+				switch coreType := types2.CoreType(typ).(type) {
+				default:
+					w.p.fatalf(expr, "unexpected core type: %v", coreType)
+				case *types2.Chan:
+					w.rtype(typ)
+				case *types2.Map:
+					w.rtype(typ)
+				case *types2.Slice:
+					w.rtype(sliceElem(typ))
+				}
+
+				return
+
+			case "new":
+				assert(len(expr.ArgList) == 1)
+				assert(!expr.HasDots)
+
+				w.Code(exprNew)
+				w.pos(expr)
+				w.exprType(nil, expr.ArgList[0])
+				return
+
+			case "append":
+				rtype = sliceElem(w.p.typeOf(expr))
+			case "copy":
+				typ := w.p.typeOf(expr.ArgList[0])
+				if tuple, ok := typ.(*types2.Tuple); ok { // "copy(g())"
+					typ = tuple.At(0).Type()
+				}
+				rtype = sliceElem(typ)
+			case "delete":
+				typ := w.p.typeOf(expr.ArgList[0])
+				if tuple, ok := typ.(*types2.Tuple); ok { // "delete(g())"
+					typ = tuple.At(0).Type()
+				}
+				rtype = typ
+			case "Slice":
+				rtype = sliceElem(w.p.typeOf(expr))
+			}
+		}
+
 		writeFunExpr := func() {
-			if selector, ok := unparen(expr.Fun).(*syntax.SelectorExpr); ok {
+			fun := unparen(expr.Fun)
+
+			if selector, ok := fun.(*syntax.SelectorExpr); ok {
 				if sel, ok := w.p.info.Selections[selector]; ok && sel.Kind() == types2.MethodVal {
-					w.expr(selector.X)
 					w.Bool(true) // method call
-					w.pos(selector)
-					w.selector(sel.Obj())
+					typ := w.recvExpr(selector, sel)
+					w.methodExpr(selector, typ, sel)
 					return
 				}
 			}
 
-			w.expr(expr.Fun)
 			w.Bool(false) // not a method call (i.e., normal function call)
+
+			if obj, inst := lookupObj(w.p, fun); w.Bool(obj != nil && inst.TypeArgs.Len() != 0) {
+				obj := obj.(*types2.Func)
+
+				w.pos(fun)
+				w.funcInst(obj, inst.TypeArgs)
+				return
+			}
+
+			w.expr(fun)
 		}
 
+		sigType := types2.CoreType(tv.Type).(*types2.Signature)
+		paramTypes := sigType.Params()
+
 		w.Code(exprCall)
 		writeFunExpr()
 		w.pos(expr)
-		w.exprs(expr.ArgList)
+
+		paramType := func(i int) types2.Type {
+			if sigType.Variadic() && !expr.HasDots && i >= paramTypes.Len()-1 {
+				return paramTypes.At(paramTypes.Len() - 1).Type().(*types2.Slice).Elem()
+			}
+			return paramTypes.At(i).Type()
+		}
+
+		w.multiExpr(expr, paramType, expr.ArgList)
 		w.Bool(expr.HasDots)
+		if rtype != nil {
+			w.rtype(rtype)
+		}
 	}
 }
 
+func sliceElem(typ types2.Type) types2.Type {
+	return types2.CoreType(typ).(*types2.Slice).Elem()
+}
+
+func (w *writer) optExpr(expr syntax.Expr) {
+	if w.Bool(expr != nil) {
+		w.expr(expr)
+	}
+}
+
+// recvExpr writes out expr.X, but handles any implicit addressing,
+// dereferencing, and field selections appropriate for the method
+// selection.
+func (w *writer) recvExpr(expr *syntax.SelectorExpr, sel *types2.Selection) types2.Type {
+	index := sel.Index()
+	implicits := index[:len(index)-1]
+
+	w.Code(exprRecv)
+	w.expr(expr.X)
+	w.pos(expr)
+	w.Len(len(implicits))
+
+	typ := w.p.typeOf(expr.X)
+	for _, ix := range implicits {
+		typ = deref2(typ).Underlying().(*types2.Struct).Field(ix).Type()
+		w.Len(ix)
+	}
+
+	recv := sel.Obj().(*types2.Func).Type().(*types2.Signature).Recv().Type()
+	if w.Bool(isPtrTo(typ, recv)) { // needs deref
+		typ = recv
+	} else if w.Bool(isPtrTo(recv, typ)) { // needs addr
+		typ = recv
+	}
+
+	return typ
+}
+
+// funcInst writes a reference to an instantiated function.
+func (w *writer) funcInst(obj *types2.Func, targs *types2.TypeList) {
+	info := w.p.objInstIdx(obj, targs, w.dict)
+
+	// Type arguments list contains derived types; we can emit a static
+	// call to the shaped function, but need to dynamically compute the
+	// runtime dictionary pointer.
+	if w.Bool(info.anyDerived()) {
+		w.Len(w.dict.subdictIdx(info))
+		return
+	}
+
+	// Type arguments list is statically known; we can emit a static
+	// call with a statically reference to the respective runtime
+	// dictionary.
+	w.objInfo(info)
+}
+
+// methodExpr writes out a reference to the method selected by
+// expr. sel should be the corresponding types2.Selection, and recv
+// the type produced after any implicit addressing, dereferencing, and
+// field selection. (Note: recv might differ from sel.Obj()'s receiver
+// parameter in the case of interface types, and is needed for
+// handling type parameter methods.)
+func (w *writer) methodExpr(expr *syntax.SelectorExpr, recv types2.Type, sel *types2.Selection) {
+	fun := sel.Obj().(*types2.Func)
+	sig := fun.Type().(*types2.Signature)
+
+	w.typ(recv)
+	w.typ(sig)
+	w.pos(expr)
+	w.selector(fun)
+
+	// Method on a type parameter. These require an indirect call
+	// through the current function's runtime dictionary.
+	if typeParam, ok := recv.(*types2.TypeParam); w.Bool(ok) {
+		typeParamIdx := w.dict.typeParamIndex(typeParam)
+		methodInfo := w.p.selectorIdx(fun)
+
+		w.Len(w.dict.typeParamMethodExprIdx(typeParamIdx, methodInfo))
+		return
+	}
+
+	if isInterface(recv) != isInterface(sig.Recv().Type()) {
+		w.p.fatalf(expr, "isInterface inconsistency: %v and %v", recv, sig.Recv().Type())
+	}
+
+	if !isInterface(recv) {
+		if named, ok := deref2(recv).(*types2.Named); ok {
+			obj, targs := splitNamed(named)
+			info := w.p.objInstIdx(obj, targs, w.dict)
+
+			// Method on a derived receiver type. These can be handled by a
+			// static call to the shaped method, but require dynamically
+			// looking up the appropriate dictionary argument in the current
+			// function's runtime dictionary.
+			if w.p.hasImplicitTypeParams(obj) || info.anyDerived() {
+				w.Bool(true) // dynamic subdictionary
+				w.Len(w.dict.subdictIdx(info))
+				return
+			}
+
+			// Method on a fully known receiver type. These can be handled
+			// by a static call to the shaped method, and with a static
+			// reference to the receiver type's dictionary.
+			if targs.Len() != 0 {
+				w.Bool(false) // no dynamic subdictionary
+				w.Bool(true)  // static dictionary
+				w.objInfo(info)
+				return
+			}
+		}
+	}
+
+	w.Bool(false) // no dynamic subdictionary
+	w.Bool(false) // no static dictionary
+}
+
+// multiExpr writes a sequence of expressions, where the i'th value is
+// implicitly converted to dstType(i). It also handles when exprs is a
+// single, multi-valued expression (e.g., the multi-valued argument in
+// an f(g()) call, or the RHS operand in a comma-ok assignment).
+func (w *writer) multiExpr(pos poser, dstType func(int) types2.Type, exprs []syntax.Expr) {
+	w.Sync(pkgbits.SyncMultiExpr)
+
+	if len(exprs) == 1 {
+		expr := exprs[0]
+		if tuple, ok := w.p.typeOf(expr).(*types2.Tuple); ok {
+			assert(tuple.Len() > 1)
+			w.Bool(true) // N:1 assignment
+			w.pos(pos)
+			w.expr(expr)
+
+			w.Len(tuple.Len())
+			for i := 0; i < tuple.Len(); i++ {
+				src := tuple.At(i).Type()
+				// TODO(mdempsky): Investigate not writing src here. I think
+				// the reader should be able to infer it from expr anyway.
+				w.typ(src)
+				if dst := dstType(i); w.Bool(dst != nil && !types2.Identical(src, dst)) {
+					if src == nil || dst == nil {
+						w.p.fatalf(pos, "src is %v, dst is %v", src, dst)
+					}
+					if !types2.AssignableTo(src, dst) {
+						w.p.fatalf(pos, "%v is not assignable to %v", src, dst)
+					}
+					w.typ(dst)
+					w.convRTTI(src, dst)
+				}
+			}
+			return
+		}
+	}
+
+	w.Bool(false) // N:N assignment
+	w.Len(len(exprs))
+	for i, expr := range exprs {
+		w.implicitConvExpr(dstType(i), expr)
+	}
+}
+
+// implicitConvExpr is like expr, but if dst is non-nil and different
+// from expr's type, then an implicit conversion operation is inserted
+// at expr's position.
+func (w *writer) implicitConvExpr(dst types2.Type, expr syntax.Expr) {
+	w.convertExpr(dst, expr, true)
+}
+
+func (w *writer) convertExpr(dst types2.Type, expr syntax.Expr, implicit bool) {
+	src := w.p.typeOf(expr)
+
+	// Omit implicit no-op conversions.
+	identical := dst == nil || types2.Identical(src, dst)
+	if implicit && identical {
+		w.expr(expr)
+		return
+	}
+
+	if implicit && !types2.AssignableTo(src, dst) {
+		w.p.fatalf(expr, "%v is not assignable to %v", src, dst)
+	}
+
+	w.Code(exprConvert)
+	w.Bool(implicit)
+	w.typ(dst)
+	w.pos(expr)
+	w.convRTTI(src, dst)
+	w.Bool(isTypeParam(dst))
+	w.Bool(identical)
+	w.expr(expr)
+}
+
 func (w *writer) compLit(lit *syntax.CompositeLit) {
-	tv, ok := w.p.info.Types[lit]
-	assert(ok)
+	typ := w.p.typeOf(lit)
 
 	w.Sync(pkgbits.SyncCompLit)
 	w.pos(lit)
-	w.typ(tv.Type)
+	w.typ(typ)
 
-	typ := tv.Type
 	if ptr, ok := types2.CoreType(typ).(*types2.Pointer); ok {
 		typ = ptr.Elem()
 	}
-	str, isStruct := types2.CoreType(typ).(*types2.Struct)
+	var keyType, elemType types2.Type
+	var structType *types2.Struct
+	switch typ0 := typ; typ := types2.CoreType(typ).(type) {
+	default:
+		w.p.fatalf(lit, "unexpected composite literal type: %v", typ)
+	case *types2.Array:
+		elemType = typ.Elem()
+	case *types2.Map:
+		w.rtype(typ0)
+		keyType, elemType = typ.Key(), typ.Elem()
+	case *types2.Slice:
+		elemType = typ.Elem()
+	case *types2.Struct:
+		structType = typ
+	}
 
 	w.Len(len(lit.ElemList))
 	for i, elem := range lit.ElemList {
-		if isStruct {
+		elemType := elemType
+		if structType != nil {
 			if kv, ok := elem.(*syntax.KeyValueExpr); ok {
 				// use position of expr.Key rather than of elem (which has position of ':')
 				w.pos(kv.Key)
-				w.Len(fieldIndex(w.p.info, str, kv.Key.(*syntax.Name)))
+				i = fieldIndex(w.p.info, structType, kv.Key.(*syntax.Name))
 				elem = kv.Value
 			} else {
 				w.pos(elem)
-				w.Len(i)
 			}
+			elemType = structType.Field(i).Type()
+			w.Len(i)
 		} else {
 			if kv, ok := elem.(*syntax.KeyValueExpr); w.Bool(ok) {
 				// use position of expr.Key rather than of elem (which has position of ':')
 				w.pos(kv.Key)
-				w.expr(kv.Key)
+				w.implicitConvExpr(keyType, kv.Key)
 				elem = kv.Value
 			}
 		}
 		w.pos(elem)
-		w.expr(elem)
+		w.implicitConvExpr(elemType, elem)
 	}
 }
 
 func (w *writer) funcLit(expr *syntax.FuncLit) {
-	tv, ok := w.p.info.Types[expr]
-	assert(ok)
-	sig := tv.Type.(*types2.Signature)
+	sig := w.p.typeOf(expr).(*types2.Signature)
 
-	body, closureVars := w.p.bodyIdx(w.p.curpkg, sig, expr.Body, w.dict)
+	body, closureVars := w.p.bodyIdx(sig, expr.Body, w.dict)
 
 	w.Sync(pkgbits.SyncFuncLit)
 	w.pos(expr)
@@ -1409,15 +2172,15 @@
 	w.Len(len(closureVars))
 	for _, cv := range closureVars {
 		w.pos(cv.pos)
-		w.useLocal(cv.pos, cv.obj)
+		w.useLocal(cv.pos, cv.var_)
 	}
 
 	w.Reloc(pkgbits.RelocBody, body)
 }
 
-type posObj struct {
-	pos syntax.Pos
-	obj *types2.Var
+type posVar struct {
+	pos  syntax.Pos
+	var_ *types2.Var
 }
 
 func (w *writer) exprList(expr syntax.Expr) {
@@ -1426,10 +2189,6 @@
 }
 
 func (w *writer) exprs(exprs []syntax.Expr) {
-	if len(exprs) == 0 {
-		assert(exprs == nil)
-	}
-
 	w.Sync(pkgbits.SyncExprs)
 	w.Len(len(exprs))
 	for _, expr := range exprs {
@@ -1437,43 +2196,87 @@
 	}
 }
 
-func (w *writer) exprType(iface types2.Type, typ syntax.Expr, nilOK bool) {
-	base.Assertf(iface == nil || isInterface(iface), "%v must be nil or an interface type", iface)
+// rtype writes information so that the reader can construct an
+// expression of type *runtime._type representing typ.
+func (w *writer) rtype(typ types2.Type) {
+	typ = types2.Default(typ)
 
-	tv, ok := w.p.info.Types[typ]
-	assert(ok)
-
-	w.Sync(pkgbits.SyncExprType)
-
-	if nilOK && w.Bool(tv.IsNil()) {
-		return
-	}
-
-	assert(tv.IsType())
-	info := w.p.typIdx(tv.Type, w.dict)
-
-	w.pos(typ)
-
-	if w.Bool(info.derived && iface != nil && !iface.Underlying().(*types2.Interface).Empty()) {
-		ifaceInfo := w.p.typIdx(iface, w.dict)
-
-		idx := -1
-		for i, itab := range w.dict.itabs {
-			if itab.typIdx == info.idx && itab.iface == ifaceInfo {
-				idx = i
-			}
-		}
-		if idx < 0 {
-			idx = len(w.dict.itabs)
-			w.dict.itabs = append(w.dict.itabs, itabInfo{typIdx: info.idx, iface: ifaceInfo})
-		}
-		w.Len(idx)
-		return
-	}
-
-	w.typInfo(info)
+	info := w.p.typIdx(typ, w.dict)
+	w.rtypeInfo(info)
 }
 
+func (w *writer) rtypeInfo(info typeInfo) {
+	w.Sync(pkgbits.SyncRType)
+
+	if w.Bool(info.derived) {
+		w.Len(w.dict.rtypeIdx(info))
+	} else {
+		w.typInfo(info)
+	}
+}
+
+// varDictIndex writes out information for populating DictIndex for
+// the ir.Name that will represent obj.
+func (w *writer) varDictIndex(obj *types2.Var) {
+	info := w.p.typIdx(obj.Type(), w.dict)
+	if w.Bool(info.derived) {
+		w.Len(w.dict.rtypeIdx(info))
+	}
+}
+
+func isUntyped(typ types2.Type) bool {
+	basic, ok := typ.(*types2.Basic)
+	return ok && basic.Info()&types2.IsUntyped != 0
+}
+
+func isTuple(typ types2.Type) bool {
+	_, ok := typ.(*types2.Tuple)
+	return ok
+}
+
+func (w *writer) itab(typ, iface types2.Type) {
+	typ = types2.Default(typ)
+	iface = types2.Default(iface)
+
+	typInfo := w.p.typIdx(typ, w.dict)
+	ifaceInfo := w.p.typIdx(iface, w.dict)
+
+	w.rtypeInfo(typInfo)
+	w.rtypeInfo(ifaceInfo)
+	if w.Bool(typInfo.derived || ifaceInfo.derived) {
+		w.Len(w.dict.itabIdx(typInfo, ifaceInfo))
+	}
+}
+
+// convRTTI writes information so that the reader can construct
+// expressions for converting from src to dst.
+func (w *writer) convRTTI(src, dst types2.Type) {
+	w.Sync(pkgbits.SyncConvRTTI)
+	w.itab(src, dst)
+}
+
+func (w *writer) exprType(iface types2.Type, typ syntax.Expr) {
+	base.Assertf(iface == nil || isInterface(iface), "%v must be nil or an interface type", iface)
+
+	tv := w.p.typeAndValue(typ)
+	assert(tv.IsType())
+
+	w.Sync(pkgbits.SyncExprType)
+	w.pos(typ)
+
+	if w.Bool(iface != nil && !iface.Underlying().(*types2.Interface).Empty()) {
+		w.itab(tv.Type, iface)
+	} else {
+		w.rtype(tv.Type)
+
+		info := w.p.typIdx(tv.Type, w.dict)
+		w.Bool(info.derived)
+	}
+}
+
+// isInterface reports whether typ is known to be an interface type.
+// If typ is a type parameter, then isInterface reports an internal
+// compiler error instead.
 func isInterface(typ types2.Type) bool {
 	if _, ok := typ.(*types2.TypeParam); ok {
 		// typ is a type parameter and may be instantiated as either a
@@ -1486,6 +2289,7 @@
 	return ok
 }
 
+// op writes an Op into the bitstream.
 func (w *writer) op(op ir.Op) {
 	// TODO(mdempsky): Remove in favor of explicit codes? Would make
 	// export data more stable against internal refactorings, but low
@@ -1495,20 +2299,6 @@
 	w.Len(int(op))
 }
 
-func (w *writer) needType(typ types2.Type) {
-	// Decompose tuple into component element types.
-	if typ, ok := typ.(*types2.Tuple); ok {
-		for i := 0; i < typ.Len(); i++ {
-			w.needType(typ.At(i).Type())
-		}
-		return
-	}
-
-	if info := w.p.typIdx(typ, w.dict); info.derived {
-		w.dict.derived[info.idx].needed = true
-	}
-}
-
 // @@@ Package initialization
 
 // Caution: This code is still clumsy, because toolstash -cmp is
@@ -1526,6 +2316,12 @@
 	importedEmbed, importedUnsafe bool
 }
 
+// declCollector is a visitor type that collects compiler-needed
+// information about declarations that types2 doesn't track.
+//
+// Notably, it maps declared types and functions back to their
+// declaration statement, keeps track of implicit type parameters, and
+// assigns unique type "generation" numbers to local defined types.
 type declCollector struct {
 	pw         *pkgWriter
 	typegen    *int
@@ -1584,7 +2380,7 @@
 		if n.Alias {
 			pw.checkPragmas(n.Pragma, 0, false)
 		} else {
-			pw.checkPragmas(n.Pragma, typePragmas, false)
+			pw.checkPragmas(n.Pragma, 0, false)
 
 			// Assign a unique ID to function-scoped defined types.
 			if c.withinFunc {
@@ -1649,8 +2445,7 @@
 				}
 
 			default:
-				// TODO(mdempsky): Enable after #42938 is fixed.
-				if false {
+				if types.AllowsGoVersion(1, 18) {
 					pw.errorf(l.pos, "//go:linkname must refer to declared function or variable")
 				}
 			}
@@ -1750,6 +2545,12 @@
 		w.Code(declVar)
 		w.pos(decl)
 		w.pkgObjs(decl.NameList...)
+
+		// TODO(mdempsky): It would make sense to use multiExpr here, but
+		// that results in IR that confuses pkginit/initorder.go. So we
+		// continue using exprList, and let typecheck handle inserting any
+		// implicit conversions. That's okay though, because package-scope
+		// assignments never require dictionaries.
 		w.exprList(decl.Values)
 
 		var embeds []pragmaEmbed
@@ -1779,6 +2580,20 @@
 
 // @@@ Helpers
 
+// hasImplicitTypeParams reports whether obj is a defined type with
+// implicit type parameters (e.g., declared within a generic function
+// or method).
+func (p *pkgWriter) hasImplicitTypeParams(obj *types2.TypeName) bool {
+	if obj.Pkg() == p.curpkg {
+		decl, ok := p.typDecls[obj]
+		assert(ok)
+		if len(decl.implicits) != 0 {
+			return true
+		}
+	}
+	return false
+}
+
 // isDefinedType reports whether obj is a defined type.
 func isDefinedType(obj types2.Object) bool {
 	if obj, ok := obj.(*types2.TypeName); ok {
@@ -1797,12 +2612,11 @@
 // lookupObj returns the object that expr refers to, if any. If expr
 // is an explicit instantiation of a generic object, then the instance
 // object is returned as well.
-func lookupObj(info *types2.Info, expr syntax.Expr) (obj types2.Object, inst types2.Instance) {
+func lookupObj(p *pkgWriter, expr syntax.Expr) (obj types2.Object, inst types2.Instance) {
 	if index, ok := expr.(*syntax.IndexExpr); ok {
 		args := unpackListExpr(index.Index)
 		if len(args) == 1 {
-			tv, ok := info.Types[args[0]]
-			assert(ok)
+			tv := p.typeAndValue(args[0])
 			if tv.IsValue() {
 				return // normal index expression
 			}
@@ -1813,15 +2627,15 @@
 
 	// Strip package qualifier, if present.
 	if sel, ok := expr.(*syntax.SelectorExpr); ok {
-		if !isPkgQual(info, sel) {
+		if !isPkgQual(p.info, sel) {
 			return // normal selector expression
 		}
 		expr = sel.Sel
 	}
 
 	if name, ok := expr.(*syntax.Name); ok {
-		obj = info.Uses[name]
-		inst = info.Instances[name]
+		obj = p.info.Uses[name]
+		inst = p.info.Instances[name]
 	}
 	return
 }
@@ -1836,6 +2650,13 @@
 	return false
 }
 
+// isNil reports whether expr is a (possibly parenthesized) reference
+// to the predeclared nil value.
+func isNil(p *pkgWriter, expr syntax.Expr) bool {
+	tv := p.typeAndValue(expr)
+	return tv.IsNil()
+}
+
 // recvBase returns the base type for the given receiver parameter.
 func recvBase(recv *types2.Var) *types2.Named {
 	typ := recv.Type()
@@ -1888,9 +2709,27 @@
 	return nil
 }
 
+// splitNamed decomposes a use of a defined type into its original
+// type definition and the type arguments used to instantiate it.
+func splitNamed(typ *types2.Named) (*types2.TypeName, *types2.TypeList) {
+	base.Assertf(typ.TypeParams().Len() == typ.TypeArgs().Len(), "use of uninstantiated type: %v", typ)
+
+	orig := typ.Origin()
+	base.Assertf(orig.TypeArgs() == nil, "origin %v of %v has type arguments", orig, typ)
+	base.Assertf(typ.Obj() == orig.Obj(), "%v has object %v, but %v has object %v", typ, typ.Obj(), orig, orig.Obj())
+
+	return typ.Obj(), typ.TypeArgs()
+}
+
 func asPragmaFlag(p syntax.Pragma) ir.PragmaFlag {
 	if p == nil {
 		return 0
 	}
 	return p.(*pragmas).Flag
 }
+
+// isPtrTo reports whether from is the type *to.
+func isPtrTo(from, to types2.Type) bool {
+	ptr, ok := from.(*types2.Pointer)
+	return ok && types2.Identical(ptr.Elem(), to)
+}
diff --git a/src/cmd/compile/internal/objw/objw.go b/src/cmd/compile/internal/objw/objw.go
index ed5ad75..4189337 100644
--- a/src/cmd/compile/internal/objw/objw.go
+++ b/src/cmd/compile/internal/objw/objw.go
@@ -40,14 +40,14 @@
 }
 
 func SymPtr(s *obj.LSym, off int, x *obj.LSym, xoff int) int {
-	off = int(types.Rnd(int64(off), int64(types.PtrSize)))
+	off = int(types.RoundUp(int64(off), int64(types.PtrSize)))
 	s.WriteAddr(base.Ctxt, int64(off), types.PtrSize, x, int64(xoff))
 	off += types.PtrSize
 	return off
 }
 
 func SymPtrWeak(s *obj.LSym, off int, x *obj.LSym, xoff int) int {
-	off = int(types.Rnd(int64(off), int64(types.PtrSize)))
+	off = int(types.RoundUp(int64(off), int64(types.PtrSize)))
 	s.WriteWeakAddr(base.Ctxt, int64(off), types.PtrSize, x, int64(xoff))
 	off += types.PtrSize
 	return off
@@ -73,7 +73,7 @@
 	base.Ctxt.Globl(s, int64(width), int(flags))
 }
 
-// Bitvec writes the contents of bv into s as sequence of bytes
+// BitVec writes the contents of bv into s as sequence of bytes
 // in little-endian order, and returns the next unused offset.
 func BitVec(s *obj.LSym, off int, bv bitvec.BitVec) int {
 	// Runtime reads the bitmaps as byte arrays. Oblige.
diff --git a/src/cmd/compile/internal/pgo/graph.go b/src/cmd/compile/internal/pgo/graph.go
new file mode 100644
index 0000000..a2cf18f
--- /dev/null
+++ b/src/cmd/compile/internal/pgo/graph.go
@@ -0,0 +1,848 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package graph collects a set of samples into a directed graph.
+
+// Original file location: https://github.com/google/pprof/tree/main/internal/graph/graph.go
+package pgo
+
+import (
+	"fmt"
+	"internal/profile"
+	"math"
+	"sort"
+	"strings"
+)
+
+// Options encodes the options for constructing a graph
+type Options struct {
+	SampleValue       func(s []int64) int64 // Function to compute the value of a sample
+	SampleMeanDivisor func(s []int64) int64 // Function to compute the divisor for mean graphs, or nil
+
+	CallTree     bool // Build a tree instead of a graph
+	DropNegative bool // Drop nodes with overall negative values
+
+	KeptNodes NodeSet // If non-nil, only use nodes in this set
+}
+
+// Nodes is an ordered collection of graph nodes.
+type Nodes []*Node
+
+// Node is an entry on a profiling report. It represents a unique
+// program location.
+type Node struct {
+	// Info describes the source location associated to this node.
+	Info NodeInfo
+
+	// Function represents the function that this node belongs to. On
+	// graphs with sub-function resolution (eg line number or
+	// addresses), two nodes in a NodeMap that are part of the same
+	// function have the same value of Node.Function. If the Node
+	// represents the whole function, it points back to itself.
+	Function *Node
+
+	// Values associated to this node. Flat is exclusive to this node,
+	// Cum includes all descendents.
+	Flat, FlatDiv, Cum, CumDiv int64
+
+	// In and out Contains the nodes immediately reaching or reached by
+	// this node.
+	In, Out EdgeMap
+}
+
+// Graph summarizes a performance profile into a format that is
+// suitable for visualization.
+type Graph struct {
+	Nodes Nodes
+}
+
+// FlatValue returns the exclusive value for this node, computing the
+// mean if a divisor is available.
+func (n *Node) FlatValue() int64 {
+	if n.FlatDiv == 0 {
+		return n.Flat
+	}
+	return n.Flat / n.FlatDiv
+}
+
+// CumValue returns the inclusive value for this node, computing the
+// mean if a divisor is available.
+func (n *Node) CumValue() int64 {
+	if n.CumDiv == 0 {
+		return n.Cum
+	}
+	return n.Cum / n.CumDiv
+}
+
+// AddToEdge increases the weight of an edge between two nodes. If
+// there isn't such an edge one is created.
+func (n *Node) AddToEdge(to *Node, v int64, residual, inline bool) {
+	n.AddToEdgeDiv(to, 0, v, residual, inline)
+}
+
+// AddToEdgeDiv increases the weight of an edge between two nodes. If
+// there isn't such an edge one is created.
+func (n *Node) AddToEdgeDiv(to *Node, dv, v int64, residual, inline bool) {
+	if e := n.Out.FindTo(to); e != nil {
+		e.WeightDiv += dv
+		e.Weight += v
+		if residual {
+			e.Residual = true
+		}
+		if !inline {
+			e.Inline = false
+		}
+		return
+	}
+
+	info := &Edge{Src: n, Dest: to, WeightDiv: dv, Weight: v, Residual: residual, Inline: inline}
+	n.Out.Add(info)
+	to.In.Add(info)
+}
+
+// NodeInfo contains the attributes for a node.
+type NodeInfo struct {
+	Name              string
+	Address           uint64
+	StartLine, Lineno int
+	//File            string
+	//OrigName        string
+	//Objfile         string
+}
+
+// PrintableName calls the Node's Formatter function with a single space separator.
+func (i *NodeInfo) PrintableName() string {
+	return strings.Join(i.NameComponents(), " ")
+}
+
+// NameComponents returns the components of the printable name to be used for a node.
+func (i *NodeInfo) NameComponents() []string {
+	var name []string
+	if i.Address != 0 {
+		name = append(name, fmt.Sprintf("%016x", i.Address))
+	}
+	if fun := i.Name; fun != "" {
+		name = append(name, fun)
+	}
+
+	switch {
+	case i.Lineno != 0:
+		// User requested line numbers, provide what we have.
+		name = append(name, fmt.Sprintf(":%d", i.Lineno))
+	case i.Name != "":
+		// User requested function name. It was already included.
+	default:
+		// Do not leave it empty if there is no information at all.
+		name = append(name, "<unknown>")
+	}
+	return name
+}
+
+// NodeMap maps from a node info struct to a node. It is used to merge
+// report entries with the same info.
+type NodeMap map[NodeInfo]*Node
+
+// NodeSet is a collection of node info structs.
+type NodeSet map[NodeInfo]bool
+
+// NodePtrSet is a collection of nodes. Trimming a graph or tree requires a set
+// of objects which uniquely identify the nodes to keep. In a graph, NodeInfo
+// works as a unique identifier; however, in a tree multiple nodes may share
+// identical NodeInfos. A *Node does uniquely identify a node so we can use that
+// instead. Though a *Node also uniquely identifies a node in a graph,
+// currently, during trimming, graphs are rebuilt from scratch using only the
+// NodeSet, so there would not be the required context of the initial graph to
+// allow for the use of *Node.
+type NodePtrSet map[*Node]bool
+
+// FindOrInsertNode takes the info for a node and either returns a matching node
+// from the node map if one exists, or adds one to the map if one does not.
+// If kept is non-nil, nodes are only added if they can be located on it.
+func (nm NodeMap) FindOrInsertNode(info NodeInfo, kept NodeSet) *Node {
+	if kept != nil {
+		if _, ok := kept[info]; !ok {
+			return nil
+		}
+	}
+
+	if n, ok := nm[info]; ok {
+		return n
+	}
+
+	n := &Node{
+		Info: info,
+	}
+	nm[info] = n
+	if info.Address == 0 && info.Lineno == 0 {
+		// This node represents the whole function, so point Function
+		// back to itself.
+		n.Function = n
+		return n
+	}
+	// Find a node that represents the whole function.
+	info.Address = 0
+	info.Lineno = 0
+	n.Function = nm.FindOrInsertNode(info, nil)
+	return n
+}
+
+// EdgeMap is used to represent the incoming/outgoing edges from a node.
+type EdgeMap []*Edge
+
+func (em EdgeMap) FindTo(n *Node) *Edge {
+	for _, e := range em {
+		if e.Dest == n {
+			return e
+		}
+	}
+	return nil
+}
+
+func (em *EdgeMap) Add(e *Edge) {
+	*em = append(*em, e)
+}
+
+func (em *EdgeMap) Delete(e *Edge) {
+	for i, edge := range *em {
+		if edge == e {
+			(*em)[i] = (*em)[len(*em)-1]
+			*em = (*em)[:len(*em)-1]
+			return
+		}
+	}
+}
+
+// Edge contains any attributes to be represented about edges in a graph.
+type Edge struct {
+	Src, Dest *Node
+	// The summary weight of the edge
+	Weight, WeightDiv int64
+
+	// residual edges connect nodes that were connected through a
+	// separate node, which has been removed from the report.
+	Residual bool
+	// An inline edge represents a call that was inlined into the caller.
+	Inline bool
+}
+
+// WeightValue returns the weight value for this edge, normalizing if a
+// divisor is available.
+func (e *Edge) WeightValue() int64 {
+	if e.WeightDiv == 0 {
+		return e.Weight
+	}
+	return e.Weight / e.WeightDiv
+}
+
+// newGraph computes a graph from a profile.
+func newGraph(prof *profile.Profile, o *Options) *Graph {
+	nodes, locationMap := CreateNodes(prof, o)
+	seenNode := make(map[*Node]bool)
+	seenEdge := make(map[nodePair]bool)
+	for _, sample := range prof.Sample {
+		var w, dw int64
+		w = o.SampleValue(sample.Value)
+		if o.SampleMeanDivisor != nil {
+			dw = o.SampleMeanDivisor(sample.Value)
+		}
+		if dw == 0 && w == 0 {
+			continue
+		}
+		for k := range seenNode {
+			delete(seenNode, k)
+		}
+		for k := range seenEdge {
+			delete(seenEdge, k)
+		}
+		var parent *Node
+		// A residual edge goes over one or more nodes that were not kept.
+		residual := false
+
+		// Group the sample frames, based on a global map.
+		// Count only the last two frames as a call edge. Frames higher up
+		// the stack are unlikely to be repeated calls (e.g. runtime.main
+		// calling main.main). So adding weights to call edges higher up
+		// the stack may be not reflecting the actual call edge weights
+		// in the program. Without a branch profile this is just an
+		// approximation.
+		i := 1
+		if last := len(sample.Location) - 1; last < i {
+			i = last
+		}
+		for ; i >= 0; i-- {
+			l := sample.Location[i]
+			locNodes := locationMap.get(l.ID)
+			for ni := len(locNodes) - 1; ni >= 0; ni-- {
+				n := locNodes[ni]
+				if n == nil {
+					residual = true
+					continue
+				}
+				// Add cum weight to all nodes in stack, avoiding double counting.
+				_, sawNode := seenNode[n]
+				if !sawNode {
+					seenNode[n] = true
+					n.addSample(dw, w, false)
+				}
+				// Update edge weights for all edges in stack, avoiding double counting.
+				if (!sawNode || !seenEdge[nodePair{n, parent}]) && parent != nil && n != parent {
+					seenEdge[nodePair{n, parent}] = true
+					parent.AddToEdgeDiv(n, dw, w, residual, ni != len(locNodes)-1)
+				}
+
+				parent = n
+				residual = false
+			}
+		}
+		if parent != nil && !residual {
+			// Add flat weight to leaf node.
+			parent.addSample(dw, w, true)
+		}
+	}
+
+	return selectNodesForGraph(nodes, o.DropNegative)
+}
+
+func selectNodesForGraph(nodes Nodes, dropNegative bool) *Graph {
+	// Collect nodes into a graph.
+	gNodes := make(Nodes, 0, len(nodes))
+	for _, n := range nodes {
+		if n == nil {
+			continue
+		}
+		if n.Cum == 0 && n.Flat == 0 {
+			continue
+		}
+		if dropNegative && isNegative(n) {
+			continue
+		}
+		gNodes = append(gNodes, n)
+	}
+	return &Graph{gNodes}
+}
+
+type nodePair struct {
+	src, dest *Node
+}
+
+func newTree(prof *profile.Profile, o *Options) (g *Graph) {
+	parentNodeMap := make(map[*Node]NodeMap, len(prof.Sample))
+	for _, sample := range prof.Sample {
+		var w, dw int64
+		w = o.SampleValue(sample.Value)
+		if o.SampleMeanDivisor != nil {
+			dw = o.SampleMeanDivisor(sample.Value)
+		}
+		if dw == 0 && w == 0 {
+			continue
+		}
+		var parent *Node
+		// Group the sample frames, based on a per-node map.
+		for i := len(sample.Location) - 1; i >= 0; i-- {
+			l := sample.Location[i]
+			lines := l.Line
+			if len(lines) == 0 {
+				lines = []profile.Line{{}} // Create empty line to include location info.
+			}
+			for lidx := len(lines) - 1; lidx >= 0; lidx-- {
+				nodeMap := parentNodeMap[parent]
+				if nodeMap == nil {
+					nodeMap = make(NodeMap)
+					parentNodeMap[parent] = nodeMap
+				}
+				n := nodeMap.findOrInsertLine(l, lines[lidx], o)
+				if n == nil {
+					continue
+				}
+				n.addSample(dw, w, false)
+				if parent != nil {
+					parent.AddToEdgeDiv(n, dw, w, false, lidx != len(lines)-1)
+				}
+				parent = n
+			}
+		}
+		if parent != nil {
+			parent.addSample(dw, w, true)
+		}
+	}
+
+	nodes := make(Nodes, len(prof.Location))
+	for _, nm := range parentNodeMap {
+		nodes = append(nodes, nm.nodes()...)
+	}
+	return selectNodesForGraph(nodes, o.DropNegative)
+}
+
+// isNegative returns true if the node is considered as "negative" for the
+// purposes of drop_negative.
+func isNegative(n *Node) bool {
+	switch {
+	case n.Flat < 0:
+		return true
+	case n.Flat == 0 && n.Cum < 0:
+		return true
+	default:
+		return false
+	}
+}
+
+type locationMap struct {
+	s []Nodes          // a slice for small sequential IDs
+	m map[uint64]Nodes // fallback for large IDs (unlikely)
+}
+
+func (l *locationMap) add(id uint64, n Nodes) {
+	if id < uint64(len(l.s)) {
+		l.s[id] = n
+	} else {
+		l.m[id] = n
+	}
+}
+
+func (l locationMap) get(id uint64) Nodes {
+	if id < uint64(len(l.s)) {
+		return l.s[id]
+	} else {
+		return l.m[id]
+	}
+}
+
+// CreateNodes creates graph nodes for all locations in a profile. It
+// returns set of all nodes, plus a mapping of each location to the
+// set of corresponding nodes (one per location.Line).
+func CreateNodes(prof *profile.Profile, o *Options) (Nodes, locationMap) {
+	locations := locationMap{make([]Nodes, len(prof.Location)+1), make(map[uint64]Nodes)}
+	nm := make(NodeMap, len(prof.Location))
+	for _, l := range prof.Location {
+		lines := l.Line
+		if len(lines) == 0 {
+			lines = []profile.Line{{}} // Create empty line to include location info.
+		}
+		nodes := make(Nodes, len(lines))
+		for ln := range lines {
+			nodes[ln] = nm.findOrInsertLine(l, lines[ln], o)
+		}
+		locations.add(l.ID, nodes)
+	}
+	return nm.nodes(), locations
+}
+
+func (nm NodeMap) nodes() Nodes {
+	nodes := make(Nodes, 0, len(nm))
+	for _, n := range nm {
+		nodes = append(nodes, n)
+	}
+	return nodes
+}
+
+func (nm NodeMap) findOrInsertLine(l *profile.Location, li profile.Line, o *Options) *Node {
+	var objfile string
+	if m := l.Mapping; m != nil && m.File != "" {
+		objfile = m.File
+	}
+
+	if ni := nodeInfo(l, li, objfile, o); ni != nil {
+		return nm.FindOrInsertNode(*ni, o.KeptNodes)
+	}
+	return nil
+}
+
+func nodeInfo(l *profile.Location, line profile.Line, objfile string, o *Options) *NodeInfo {
+	if line.Function == nil {
+		return &NodeInfo{Address: l.Address}
+	}
+	ni := &NodeInfo{
+		Address: l.Address,
+		Lineno:  int(line.Line),
+		Name:    line.Function.Name,
+	}
+	ni.StartLine = int(line.Function.StartLine)
+	return ni
+}
+
+// Sum adds the flat and cum values of a set of nodes.
+func (ns Nodes) Sum() (flat int64, cum int64) {
+	for _, n := range ns {
+		flat += n.Flat
+		cum += n.Cum
+	}
+	return
+}
+
+func (n *Node) addSample(dw, w int64, flat bool) {
+	// Update sample value
+	if flat {
+		n.FlatDiv += dw
+		n.Flat += w
+	} else {
+		n.CumDiv += dw
+		n.Cum += w
+	}
+}
+
+// String returns a text representation of a graph, for debugging purposes.
+func (g *Graph) String() string {
+	var s []string
+
+	nodeIndex := make(map[*Node]int, len(g.Nodes))
+
+	for i, n := range g.Nodes {
+		nodeIndex[n] = i + 1
+	}
+
+	for i, n := range g.Nodes {
+		name := n.Info.PrintableName()
+		var in, out []int
+
+		for _, from := range n.In {
+			in = append(in, nodeIndex[from.Src])
+		}
+		for _, to := range n.Out {
+			out = append(out, nodeIndex[to.Dest])
+		}
+		s = append(s, fmt.Sprintf("%d: %s[flat=%d cum=%d] %x -> %v ", i+1, name, n.Flat, n.Cum, in, out))
+	}
+	return strings.Join(s, "\n")
+}
+
+// DiscardLowFrequencyNodes returns a set of the nodes at or over a
+// specific cum value cutoff.
+func (g *Graph) DiscardLowFrequencyNodes(nodeCutoff int64) NodeSet {
+	return makeNodeSet(g.Nodes, nodeCutoff)
+}
+
+// DiscardLowFrequencyNodePtrs returns a NodePtrSet of nodes at or over a
+// specific cum value cutoff.
+func (g *Graph) DiscardLowFrequencyNodePtrs(nodeCutoff int64) NodePtrSet {
+	cutNodes := getNodesAboveCumCutoff(g.Nodes, nodeCutoff)
+	kept := make(NodePtrSet, len(cutNodes))
+	for _, n := range cutNodes {
+		kept[n] = true
+	}
+	return kept
+}
+
+func makeNodeSet(nodes Nodes, nodeCutoff int64) NodeSet {
+	cutNodes := getNodesAboveCumCutoff(nodes, nodeCutoff)
+	kept := make(NodeSet, len(cutNodes))
+	for _, n := range cutNodes {
+		kept[n.Info] = true
+	}
+	return kept
+}
+
+// getNodesAboveCumCutoff returns all the nodes which have a Cum value greater
+// than or equal to cutoff.
+func getNodesAboveCumCutoff(nodes Nodes, nodeCutoff int64) Nodes {
+	cutoffNodes := make(Nodes, 0, len(nodes))
+	for _, n := range nodes {
+		if abs64(n.Cum) < nodeCutoff {
+			continue
+		}
+		cutoffNodes = append(cutoffNodes, n)
+	}
+	return cutoffNodes
+}
+
+// TrimLowFrequencyEdges removes edges that have less than
+// the specified weight. Returns the number of edges removed
+func (g *Graph) TrimLowFrequencyEdges(edgeCutoff int64) int {
+	var droppedEdges int
+	for _, n := range g.Nodes {
+		for _, e := range n.In {
+			if abs64(e.Weight) < edgeCutoff {
+				n.In.Delete(e)
+				e.Src.Out.Delete(e)
+				droppedEdges++
+			}
+		}
+	}
+	return droppedEdges
+}
+
+// SortNodes sorts the nodes in a graph based on a specific heuristic.
+func (g *Graph) SortNodes(cum bool, visualMode bool) {
+	// Sort nodes based on requested mode
+	switch {
+	case visualMode:
+		// Specialized sort to produce a more visually-interesting graph
+		g.Nodes.Sort(EntropyOrder)
+	case cum:
+		g.Nodes.Sort(CumNameOrder)
+	default:
+		g.Nodes.Sort(FlatNameOrder)
+	}
+}
+
+// SelectTopNodePtrs returns a set of the top maxNodes *Node in a graph.
+func (g *Graph) SelectTopNodePtrs(maxNodes int, visualMode bool) NodePtrSet {
+	set := make(NodePtrSet)
+	for _, node := range g.selectTopNodes(maxNodes, visualMode) {
+		set[node] = true
+	}
+	return set
+}
+
+// SelectTopNodes returns a set of the top maxNodes nodes in a graph.
+func (g *Graph) SelectTopNodes(maxNodes int, visualMode bool) NodeSet {
+	return makeNodeSet(g.selectTopNodes(maxNodes, visualMode), 0)
+}
+
+// selectTopNodes returns a slice of the top maxNodes nodes in a graph.
+func (g *Graph) selectTopNodes(maxNodes int, visualMode bool) Nodes {
+	if maxNodes > len(g.Nodes) {
+		maxNodes = len(g.Nodes)
+	}
+	return g.Nodes[:maxNodes]
+}
+
+// nodeSorter is a mechanism used to allow a report to be sorted
+// in different ways.
+type nodeSorter struct {
+	rs   Nodes
+	less func(l, r *Node) bool
+}
+
+func (s nodeSorter) Len() int           { return len(s.rs) }
+func (s nodeSorter) Swap(i, j int)      { s.rs[i], s.rs[j] = s.rs[j], s.rs[i] }
+func (s nodeSorter) Less(i, j int) bool { return s.less(s.rs[i], s.rs[j]) }
+
+// Sort reorders a slice of nodes based on the specified ordering
+// criteria. The result is sorted in decreasing order for (absolute)
+// numeric quantities, alphabetically for text, and increasing for
+// addresses.
+func (ns Nodes) Sort(o NodeOrder) error {
+	var s nodeSorter
+
+	switch o {
+	case FlatNameOrder:
+		s = nodeSorter{ns,
+			func(l, r *Node) bool {
+				if iv, jv := abs64(l.Flat), abs64(r.Flat); iv != jv {
+					return iv > jv
+				}
+				if iv, jv := l.Info.PrintableName(), r.Info.PrintableName(); iv != jv {
+					return iv < jv
+				}
+				if iv, jv := abs64(l.Cum), abs64(r.Cum); iv != jv {
+					return iv > jv
+				}
+				return compareNodes(l, r)
+			},
+		}
+	case FlatCumNameOrder:
+		s = nodeSorter{ns,
+			func(l, r *Node) bool {
+				if iv, jv := abs64(l.Flat), abs64(r.Flat); iv != jv {
+					return iv > jv
+				}
+				if iv, jv := abs64(l.Cum), abs64(r.Cum); iv != jv {
+					return iv > jv
+				}
+				if iv, jv := l.Info.PrintableName(), r.Info.PrintableName(); iv != jv {
+					return iv < jv
+				}
+				return compareNodes(l, r)
+			},
+		}
+	case NameOrder:
+		s = nodeSorter{ns,
+			func(l, r *Node) bool {
+				if iv, jv := l.Info.Name, r.Info.Name; iv != jv {
+					return iv < jv
+				}
+				return compareNodes(l, r)
+			},
+		}
+	case FileOrder:
+		s = nodeSorter{ns,
+			func(l, r *Node) bool {
+				if iv, jv := l.Info.StartLine, r.Info.StartLine; iv != jv {
+					return iv < jv
+				}
+				return compareNodes(l, r)
+			},
+		}
+	case AddressOrder:
+		s = nodeSorter{ns,
+			func(l, r *Node) bool {
+				if iv, jv := l.Info.Address, r.Info.Address; iv != jv {
+					return iv < jv
+				}
+				return compareNodes(l, r)
+			},
+		}
+	case CumNameOrder, EntropyOrder:
+		// Hold scoring for score-based ordering
+		var score map[*Node]int64
+		scoreOrder := func(l, r *Node) bool {
+			if iv, jv := abs64(score[l]), abs64(score[r]); iv != jv {
+				return iv > jv
+			}
+			if iv, jv := l.Info.PrintableName(), r.Info.PrintableName(); iv != jv {
+				return iv < jv
+			}
+			if iv, jv := abs64(l.Flat), abs64(r.Flat); iv != jv {
+				return iv > jv
+			}
+			return compareNodes(l, r)
+		}
+
+		switch o {
+		case CumNameOrder:
+			score = make(map[*Node]int64, len(ns))
+			for _, n := range ns {
+				score[n] = n.Cum
+			}
+			s = nodeSorter{ns, scoreOrder}
+		case EntropyOrder:
+			score = make(map[*Node]int64, len(ns))
+			for _, n := range ns {
+				score[n] = entropyScore(n)
+			}
+			s = nodeSorter{ns, scoreOrder}
+		}
+	default:
+		return fmt.Errorf("report: unrecognized sort ordering: %d", o)
+	}
+	sort.Sort(s)
+	return nil
+}
+
+// compareNodes compares two nodes to provide a deterministic ordering
+// between them. Two nodes cannot have the same Node.Info value.
+func compareNodes(l, r *Node) bool {
+	return fmt.Sprint(l.Info) < fmt.Sprint(r.Info)
+}
+
+// entropyScore computes a score for a node representing how important
+// it is to include this node on a graph visualization. It is used to
+// sort the nodes and select which ones to display if we have more
+// nodes than desired in the graph. This number is computed by looking
+// at the flat and cum weights of the node and the incoming/outgoing
+// edges. The fundamental idea is to penalize nodes that have a simple
+// fallthrough from their incoming to the outgoing edge.
+func entropyScore(n *Node) int64 {
+	score := float64(0)
+
+	if len(n.In) == 0 {
+		score++ // Favor entry nodes
+	} else {
+		score += edgeEntropyScore(n, n.In, 0)
+	}
+
+	if len(n.Out) == 0 {
+		score++ // Favor leaf nodes
+	} else {
+		score += edgeEntropyScore(n, n.Out, n.Flat)
+	}
+
+	return int64(score*float64(n.Cum)) + n.Flat
+}
+
+// edgeEntropyScore computes the entropy value for a set of edges
+// coming in or out of a node. Entropy (as defined in information
+// theory) refers to the amount of information encoded by the set of
+// edges. A set of edges that have a more interesting distribution of
+// samples gets a higher score.
+func edgeEntropyScore(n *Node, edges EdgeMap, self int64) float64 {
+	score := float64(0)
+	total := self
+	for _, e := range edges {
+		if e.Weight > 0 {
+			total += abs64(e.Weight)
+		}
+	}
+	if total != 0 {
+		for _, e := range edges {
+			frac := float64(abs64(e.Weight)) / float64(total)
+			score += -frac * math.Log2(frac)
+		}
+		if self > 0 {
+			frac := float64(abs64(self)) / float64(total)
+			score += -frac * math.Log2(frac)
+		}
+	}
+	return score
+}
+
+// NodeOrder sets the ordering for a Sort operation
+type NodeOrder int
+
+// Sorting options for node sort.
+const (
+	FlatNameOrder NodeOrder = iota
+	FlatCumNameOrder
+	CumNameOrder
+	NameOrder
+	FileOrder
+	AddressOrder
+	EntropyOrder
+)
+
+// Sort returns a slice of the edges in the map, in a consistent
+// order. The sort order is first based on the edge weight
+// (higher-to-lower) and then by the node names to avoid flakiness.
+func (e EdgeMap) Sort() []*Edge {
+	el := make(edgeList, 0, len(e))
+	for _, w := range e {
+		el = append(el, w)
+	}
+
+	sort.Sort(el)
+	return el
+}
+
+// Sum returns the total weight for a set of nodes.
+func (e EdgeMap) Sum() int64 {
+	var ret int64
+	for _, edge := range e {
+		ret += edge.Weight
+	}
+	return ret
+}
+
+type edgeList []*Edge
+
+func (el edgeList) Len() int {
+	return len(el)
+}
+
+func (el edgeList) Less(i, j int) bool {
+	if el[i].Weight != el[j].Weight {
+		return abs64(el[i].Weight) > abs64(el[j].Weight)
+	}
+
+	from1 := el[i].Src.Info.PrintableName()
+	from2 := el[j].Src.Info.PrintableName()
+	if from1 != from2 {
+		return from1 < from2
+	}
+
+	to1 := el[i].Dest.Info.PrintableName()
+	to2 := el[j].Dest.Info.PrintableName()
+
+	return to1 < to2
+}
+
+func (el edgeList) Swap(i, j int) {
+	el[i], el[j] = el[j], el[i]
+}
+
+func abs64(i int64) int64 {
+	if i < 0 {
+		return -i
+	}
+	return i
+}
diff --git a/src/cmd/compile/internal/pgo/irgraph.go b/src/cmd/compile/internal/pgo/irgraph.go
new file mode 100644
index 0000000..bb5df50
--- /dev/null
+++ b/src/cmd/compile/internal/pgo/irgraph.go
@@ -0,0 +1,547 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// WORK IN PROGRESS
+
+// A note on line numbers: when working with line numbers, we always use the
+// binary-visible relative line number. i.e., the line number as adjusted by
+// //line directives (ctxt.InnermostPos(ir.Node.Pos()).RelLine()). Use
+// NodeLineOffset to compute line offsets.
+//
+// If you are thinking, "wait, doesn't that just make things more complex than
+// using the real line number?", then you are 100% correct. Unfortunately,
+// pprof profiles generated by the runtime always contain line numbers as
+// adjusted by //line directives (because that is what we put in pclntab). Thus
+// for the best behavior when attempting to match the source with the profile
+// it makes sense to use the same line number space.
+//
+// Some of the effects of this to keep in mind:
+//
+//  - For files without //line directives there is no impact, as RelLine() ==
+//    Line().
+//  - For functions entirely covered by the same //line directive (i.e., a
+//    directive before the function definition and no directives within the
+//    function), there should also be no impact, as line offsets within the
+//    function should be the same as the real line offsets.
+//  - Functions containing //line directives may be impacted. As fake line
+//    numbers need not be monotonic, we may compute negative line offsets. We
+//    should accept these and attempt to use them for best-effort matching, as
+//    these offsets should still match if the source is unchanged, and may
+//    continue to match with changed source depending on the impact of the
+//    changes on fake line numbers.
+//  - Functions containing //line directives may also contain duplicate lines,
+//    making it ambiguous which call the profile is referencing. This is a
+//    similar problem to multiple calls on a single real line, as we don't
+//    currently track column numbers.
+//
+// Long term it would be best to extend pprof profiles to include real line
+// numbers. Until then, we have to live with these complexities. Luckily,
+// //line directives that change line numbers in strange ways should be rare,
+// and failing PGO matching on these files is not too big of a loss.
+
+package pgo
+
+import (
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/typecheck"
+	"cmd/compile/internal/types"
+	"fmt"
+	"internal/profile"
+	"log"
+	"os"
+)
+
+// IRGraph is the key datastrcture that is built from profile. It is
+// essentially a call graph with nodes pointing to IRs of functions and edges
+// carrying weights and callsite information. The graph is bidirectional that
+// helps in removing nodes efficiently.
+type IRGraph struct {
+	// Nodes of the graph
+	IRNodes  map[string]*IRNode
+	OutEdges IREdgeMap
+	InEdges  IREdgeMap
+}
+
+// IRNode represents a node in the IRGraph.
+type IRNode struct {
+	// Pointer to the IR of the Function represented by this node.
+	AST *ir.Func
+	// Flat weight of the IRNode, obtained from profile.
+	Flat int64
+	// Cumulative weight of the IRNode.
+	Cum int64
+}
+
+// IREdgeMap maps an IRNode to its successors.
+type IREdgeMap map[*IRNode][]*IREdge
+
+// IREdge represents a call edge in the IRGraph with source, destination,
+// weight, callsite, and line number information.
+type IREdge struct {
+	// Source and destination of the edge in IRNode.
+	Src, Dst       *IRNode
+	Weight         int64
+	CallSiteOffset int // Line offset from function start line.
+}
+
+// NodeMapKey represents a hash key to identify unique call-edges in profile
+// and in IR. Used for deduplication of call edges found in profile.
+type NodeMapKey struct {
+	CallerName     string
+	CalleeName     string
+	CallSiteOffset int // Line offset from function start line.
+}
+
+// Weights capture both node weight and edge weight.
+type Weights struct {
+	NFlat   int64
+	NCum    int64
+	EWeight int64
+}
+
+// CallSiteInfo captures call-site information and its caller/callee.
+type CallSiteInfo struct {
+	LineOffset int // Line offset from function start line.
+	Caller     *ir.Func
+	Callee     *ir.Func
+}
+
+// Profile contains the processed PGO profile and weighted call graph used for
+// PGO optimizations.
+type Profile struct {
+	// Aggregated NodeWeights and EdgeWeights across the profile. This
+	// helps us determine the percentage threshold for hot/cold
+	// partitioning.
+	TotalNodeWeight int64
+	TotalEdgeWeight int64
+
+	// NodeMap contains all unique call-edges in the profile and their
+	// aggregated weight.
+	NodeMap map[NodeMapKey]*Weights
+
+	// WeightedCG represents the IRGraph built from profile, which we will
+	// update as part of inlining.
+	WeightedCG *IRGraph
+}
+
+// New generates a profile-graph from the profile.
+func New(profileFile string) *Profile {
+	f, err := os.Open(profileFile)
+	if err != nil {
+		log.Fatal("failed to open file " + profileFile)
+		return nil
+	}
+	defer f.Close()
+	profile, err := profile.Parse(f)
+	if err != nil {
+		log.Fatal("failed to Parse profile file.")
+		return nil
+	}
+
+	if len(profile.Sample) == 0 {
+		// We accept empty profiles, but there is nothing to do.
+		return nil
+	}
+
+	valueIndex := -1
+	for i, s := range profile.SampleType {
+		// Samples count is the raw data collected, and CPU nanoseconds is just
+		// a scaled version of it, so either one we can find is fine.
+		if (s.Type == "samples" && s.Unit == "count") ||
+			(s.Type == "cpu" && s.Unit == "nanoseconds") {
+			valueIndex = i
+			break
+		}
+	}
+
+	if valueIndex == -1 {
+		log.Fatal("failed to find CPU samples count or CPU nanoseconds value-types in profile.")
+		return nil
+	}
+
+	g := newGraph(profile, &Options{
+		CallTree:    false,
+		SampleValue: func(v []int64) int64 { return v[valueIndex] },
+	})
+
+	p := &Profile{
+		NodeMap: make(map[NodeMapKey]*Weights),
+		WeightedCG: &IRGraph{
+			IRNodes: make(map[string]*IRNode),
+		},
+	}
+
+	// Build the node map and totals from the profile graph.
+	if !p.processprofileGraph(g) {
+		return nil
+	}
+
+	// Create package-level call graph with weights from profile and IR.
+	p.initializeIRGraph()
+
+	return p
+}
+
+// processprofileGraph builds various maps from the profile-graph.
+//
+// It initializes NodeMap and Total{Node,Edge}Weight based on the name and
+// callsite to compute node and edge weights which will be used later on to
+// create edges for WeightedCG.
+// Returns whether it successfully processed the profile.
+func (p *Profile) processprofileGraph(g *Graph) bool {
+	nFlat := make(map[string]int64)
+	nCum := make(map[string]int64)
+	seenStartLine := false
+
+	// Accummulate weights for the same node.
+	for _, n := range g.Nodes {
+		canonicalName := n.Info.Name
+		nFlat[canonicalName] += n.FlatValue()
+		nCum[canonicalName] += n.CumValue()
+	}
+
+	// Process graph and build various node and edge maps which will
+	// be consumed by AST walk.
+	for _, n := range g.Nodes {
+		seenStartLine = seenStartLine || n.Info.StartLine != 0
+
+		p.TotalNodeWeight += n.FlatValue()
+		canonicalName := n.Info.Name
+		// Create the key to the nodeMapKey.
+		nodeinfo := NodeMapKey{
+			CallerName:     canonicalName,
+			CallSiteOffset: n.Info.Lineno - n.Info.StartLine,
+		}
+
+		for _, e := range n.Out {
+			p.TotalEdgeWeight += e.WeightValue()
+			nodeinfo.CalleeName = e.Dest.Info.Name
+			if w, ok := p.NodeMap[nodeinfo]; ok {
+				w.EWeight += e.WeightValue()
+			} else {
+				weights := new(Weights)
+				weights.NFlat = nFlat[canonicalName]
+				weights.NCum = nCum[canonicalName]
+				weights.EWeight = e.WeightValue()
+				p.NodeMap[nodeinfo] = weights
+			}
+		}
+	}
+
+	if p.TotalNodeWeight == 0 || p.TotalEdgeWeight == 0 {
+		return false // accept but ignore profile with no sample
+	}
+
+	if !seenStartLine {
+		// TODO(prattic): If Function.start_line is missing we could
+		// fall back to using absolute line numbers, which is better
+		// than nothing.
+		log.Fatal("PGO profile missing Function.start_line data (Go version of profiled application too old? Go 1.20+ automatically adds this to profiles)")
+	}
+
+	return true
+}
+
+// initializeIRGraph builds the IRGraph by visting all the ir.Func in decl list
+// of a package.
+func (p *Profile) initializeIRGraph() {
+	// Bottomup walk over the function to create IRGraph.
+	ir.VisitFuncsBottomUp(typecheck.Target.Decls, func(list []*ir.Func, recursive bool) {
+		for _, n := range list {
+			p.VisitIR(n, recursive)
+		}
+	})
+}
+
+// VisitIR traverses the body of each ir.Func and use NodeMap to determine if
+// we need to add an edge from ir.Func and any node in the ir.Func body.
+func (p *Profile) VisitIR(fn *ir.Func, recursive bool) {
+	g := p.WeightedCG
+
+	if g.IRNodes == nil {
+		g.IRNodes = make(map[string]*IRNode)
+	}
+	if g.OutEdges == nil {
+		g.OutEdges = make(map[*IRNode][]*IREdge)
+	}
+	if g.InEdges == nil {
+		g.InEdges = make(map[*IRNode][]*IREdge)
+	}
+	name := ir.PkgFuncName(fn)
+	node := new(IRNode)
+	node.AST = fn
+	if g.IRNodes[name] == nil {
+		g.IRNodes[name] = node
+	}
+	// Create the key for the NodeMapKey.
+	nodeinfo := NodeMapKey{
+		CallerName:     name,
+		CalleeName:     "",
+		CallSiteOffset: 0,
+	}
+	// If the node exists, then update its node weight.
+	if weights, ok := p.NodeMap[nodeinfo]; ok {
+		g.IRNodes[name].Flat = weights.NFlat
+		g.IRNodes[name].Cum = weights.NCum
+	}
+
+	// Recursively walk over the body of the function to create IRGraph edges.
+	p.createIRGraphEdge(fn, g.IRNodes[name], name)
+}
+
+// NodeLineOffset returns the line offset of n in fn.
+func NodeLineOffset(n ir.Node, fn *ir.Func) int {
+	// See "A note on line numbers" at the top of the file.
+	line := int(base.Ctxt.InnermostPos(n.Pos()).RelLine())
+	startLine := int(base.Ctxt.InnermostPos(fn.Pos()).RelLine())
+	return line - startLine
+}
+
+// addIREdge adds an edge between caller and new node that points to `callee`
+// based on the profile-graph and NodeMap.
+func (p *Profile) addIREdge(caller *IRNode, callername string, call ir.Node, callee *ir.Func) {
+	g := p.WeightedCG
+
+	// Create an IRNode for the callee.
+	calleenode := new(IRNode)
+	calleenode.AST = callee
+	calleename := ir.PkgFuncName(callee)
+
+	// Create key for NodeMapKey.
+	nodeinfo := NodeMapKey{
+		CallerName:     callername,
+		CalleeName:     calleename,
+		CallSiteOffset: NodeLineOffset(call, caller.AST),
+	}
+
+	// Create the callee node with node weight.
+	if g.IRNodes[calleename] == nil {
+		g.IRNodes[calleename] = calleenode
+		nodeinfo2 := NodeMapKey{
+			CallerName:     calleename,
+			CalleeName:     "",
+			CallSiteOffset: 0,
+		}
+		if weights, ok := p.NodeMap[nodeinfo2]; ok {
+			g.IRNodes[calleename].Flat = weights.NFlat
+			g.IRNodes[calleename].Cum = weights.NCum
+		}
+	}
+
+	if weights, ok := p.NodeMap[nodeinfo]; ok {
+		caller.Flat = weights.NFlat
+		caller.Cum = weights.NCum
+
+		// Add edge in the IRGraph from caller to callee.
+		info := &IREdge{Src: caller, Dst: g.IRNodes[calleename], Weight: weights.EWeight, CallSiteOffset: nodeinfo.CallSiteOffset}
+		g.OutEdges[caller] = append(g.OutEdges[caller], info)
+		g.InEdges[g.IRNodes[calleename]] = append(g.InEdges[g.IRNodes[calleename]], info)
+	} else {
+		nodeinfo.CalleeName = ""
+		nodeinfo.CallSiteOffset = 0
+		if weights, ok := p.NodeMap[nodeinfo]; ok {
+			caller.Flat = weights.NFlat
+			caller.Cum = weights.NCum
+			info := &IREdge{Src: caller, Dst: g.IRNodes[calleename], Weight: 0, CallSiteOffset: nodeinfo.CallSiteOffset}
+			g.OutEdges[caller] = append(g.OutEdges[caller], info)
+			g.InEdges[g.IRNodes[calleename]] = append(g.InEdges[g.IRNodes[calleename]], info)
+		} else {
+			info := &IREdge{Src: caller, Dst: g.IRNodes[calleename], Weight: 0, CallSiteOffset: nodeinfo.CallSiteOffset}
+			g.OutEdges[caller] = append(g.OutEdges[caller], info)
+			g.InEdges[g.IRNodes[calleename]] = append(g.InEdges[g.IRNodes[calleename]], info)
+		}
+	}
+}
+
+// createIRGraphEdge traverses the nodes in the body of ir.Func and add edges between callernode which points to the ir.Func and the nodes in the body.
+func (p *Profile) createIRGraphEdge(fn *ir.Func, callernode *IRNode, name string) {
+	var doNode func(ir.Node) bool
+	doNode = func(n ir.Node) bool {
+		switch n.Op() {
+		default:
+			ir.DoChildren(n, doNode)
+		case ir.OCALLFUNC:
+			call := n.(*ir.CallExpr)
+			// Find the callee function from the call site and add the edge.
+			callee := inlCallee(call.X)
+			if callee != nil {
+				p.addIREdge(callernode, name, n, callee)
+			}
+		case ir.OCALLMETH:
+			call := n.(*ir.CallExpr)
+			// Find the callee method from the call site and add the edge.
+			callee := ir.MethodExprName(call.X).Func
+			p.addIREdge(callernode, name, n, callee)
+		}
+		return false
+	}
+	doNode(fn)
+}
+
+// WeightInPercentage converts profile weights to a percentage.
+func WeightInPercentage(value int64, total int64) float64 {
+	return (float64(value) / float64(total)) * 100
+}
+
+// PrintWeightedCallGraphDOT prints IRGraph in DOT format.
+func (p *Profile) PrintWeightedCallGraphDOT(edgeThreshold float64) {
+	fmt.Printf("\ndigraph G {\n")
+	fmt.Printf("forcelabels=true;\n")
+
+	// List of functions in this package.
+	funcs := make(map[string]struct{})
+	ir.VisitFuncsBottomUp(typecheck.Target.Decls, func(list []*ir.Func, recursive bool) {
+		for _, f := range list {
+			name := ir.PkgFuncName(f)
+			funcs[name] = struct{}{}
+		}
+	})
+
+	// Determine nodes of DOT.
+	nodes := make(map[string]*ir.Func)
+	for name, _ := range funcs {
+		if n, ok := p.WeightedCG.IRNodes[name]; ok {
+			for _, e := range p.WeightedCG.OutEdges[n] {
+				if _, ok := nodes[ir.PkgFuncName(e.Src.AST)]; !ok {
+					nodes[ir.PkgFuncName(e.Src.AST)] = e.Src.AST
+				}
+				if _, ok := nodes[ir.PkgFuncName(e.Dst.AST)]; !ok {
+					nodes[ir.PkgFuncName(e.Dst.AST)] = e.Dst.AST
+				}
+			}
+			if _, ok := nodes[ir.PkgFuncName(n.AST)]; !ok {
+				nodes[ir.PkgFuncName(n.AST)] = n.AST
+			}
+		}
+	}
+
+	// Print nodes.
+	for name, ast := range nodes {
+		if n, ok := p.WeightedCG.IRNodes[name]; ok {
+			nodeweight := WeightInPercentage(n.Flat, p.TotalNodeWeight)
+			color := "black"
+			if ast.Inl != nil {
+				fmt.Printf("\"%v\" [color=%v,label=\"%v,freq=%.2f,inl_cost=%d\"];\n", ir.PkgFuncName(ast), color, ir.PkgFuncName(ast), nodeweight, ast.Inl.Cost)
+			} else {
+				fmt.Printf("\"%v\" [color=%v, label=\"%v,freq=%.2f\"];\n", ir.PkgFuncName(ast), color, ir.PkgFuncName(ast), nodeweight)
+			}
+		}
+	}
+	// Print edges.
+	ir.VisitFuncsBottomUp(typecheck.Target.Decls, func(list []*ir.Func, recursive bool) {
+		for _, f := range list {
+			name := ir.PkgFuncName(f)
+			if n, ok := p.WeightedCG.IRNodes[name]; ok {
+				for _, e := range p.WeightedCG.OutEdges[n] {
+					edgepercent := WeightInPercentage(e.Weight, p.TotalEdgeWeight)
+					if edgepercent > edgeThreshold {
+						fmt.Printf("edge [color=red, style=solid];\n")
+					} else {
+						fmt.Printf("edge [color=black, style=solid];\n")
+					}
+
+					fmt.Printf("\"%v\" -> \"%v\" [label=\"%.2f\"];\n", ir.PkgFuncName(n.AST), ir.PkgFuncName(e.Dst.AST), edgepercent)
+				}
+			}
+		}
+	})
+	fmt.Printf("}\n")
+}
+
+// RedirectEdges deletes and redirects out-edges from node cur based on
+// inlining information via inlinedCallSites.
+//
+// CallSiteInfo.Callee must be nil.
+func (p *Profile) RedirectEdges(cur *IRNode, inlinedCallSites map[CallSiteInfo]struct{}) {
+	g := p.WeightedCG
+
+	for i, outEdge := range g.OutEdges[cur] {
+		if _, found := inlinedCallSites[CallSiteInfo{LineOffset: outEdge.CallSiteOffset, Caller: cur.AST}]; !found {
+			for _, InEdge := range g.InEdges[cur] {
+				if _, ok := inlinedCallSites[CallSiteInfo{LineOffset: InEdge.CallSiteOffset, Caller: InEdge.Src.AST}]; ok {
+					weight := g.calculateWeight(InEdge.Src, cur)
+					g.redirectEdge(InEdge.Src, cur, outEdge, weight, i)
+				}
+			}
+		} else {
+			g.remove(cur, i)
+		}
+	}
+}
+
+// redirectEdges deletes the cur node out-edges and redirect them so now these
+// edges are the parent node out-edges.
+func (g *IRGraph) redirectEdges(parent *IRNode, cur *IRNode) {
+	for _, outEdge := range g.OutEdges[cur] {
+		outEdge.Src = parent
+		g.OutEdges[parent] = append(g.OutEdges[parent], outEdge)
+	}
+	delete(g.OutEdges, cur)
+}
+
+// redirectEdge deletes the cur-node's out-edges and redirect them so now these
+// edges are the parent node out-edges.
+func (g *IRGraph) redirectEdge(parent *IRNode, cur *IRNode, outEdge *IREdge, weight int64, idx int) {
+	outEdge.Src = parent
+	outEdge.Weight = weight * outEdge.Weight
+	g.OutEdges[parent] = append(g.OutEdges[parent], outEdge)
+	g.remove(cur, idx)
+}
+
+// remove deletes the cur-node's out-edges at index idx.
+func (g *IRGraph) remove(cur *IRNode, i int) {
+	if len(g.OutEdges[cur]) >= 2 {
+		g.OutEdges[cur][i] = g.OutEdges[cur][len(g.OutEdges[cur])-1]
+		g.OutEdges[cur] = g.OutEdges[cur][:len(g.OutEdges[cur])-1]
+	} else {
+		delete(g.OutEdges, cur)
+	}
+}
+
+// calculateWeight calculates the weight of the new redirected edge.
+func (g *IRGraph) calculateWeight(parent *IRNode, cur *IRNode) int64 {
+	sum := int64(0)
+	pw := int64(0)
+	for _, InEdge := range g.InEdges[cur] {
+		sum = sum + InEdge.Weight
+		if InEdge.Src == parent {
+			pw = InEdge.Weight
+		}
+	}
+	weight := int64(0)
+	if sum != 0 {
+		weight = pw / sum
+	} else {
+		weight = pw
+	}
+	return weight
+}
+
+// inlCallee is same as the implementation for inl.go with one change. The change is that we do not invoke CanInline on a closure.
+func inlCallee(fn ir.Node) *ir.Func {
+	fn = ir.StaticValue(fn)
+	switch fn.Op() {
+	case ir.OMETHEXPR:
+		fn := fn.(*ir.SelectorExpr)
+		n := ir.MethodExprName(fn)
+		// Check that receiver type matches fn.X.
+		// TODO(mdempsky): Handle implicit dereference
+		// of pointer receiver argument?
+		if n == nil || !types.Identical(n.Type().Recv().Type, fn.X.Type()) {
+			return nil
+		}
+		return n.Func
+	case ir.ONAME:
+		fn := fn.(*ir.Name)
+		if fn.Class == ir.PFUNC {
+			return fn.Func
+		}
+	case ir.OCLOSURE:
+		fn := fn.(*ir.ClosureExpr)
+		c := fn.Func
+		return c
+	}
+	return nil
+}
diff --git a/src/cmd/compile/internal/pkginit/init.go b/src/cmd/compile/internal/pkginit/init.go
index 8c60e3b..e13a7fb 100644
--- a/src/cmd/compile/internal/pkginit/init.go
+++ b/src/cmd/compile/internal/pkginit/init.go
@@ -195,3 +195,18 @@
 	objw.Global(lsym, int32(ot), obj.NOPTR)
 	return task
 }
+
+// initRequiredForCoverage returns TRUE if we need to force creation
+// of an init function for the package so as to insert a coverage
+// runtime registration call.
+func initRequiredForCoverage(l []ir.Node) bool {
+	if base.Flag.Cfg.CoverageInfo == nil {
+		return false
+	}
+	for _, n := range l {
+		if n.Op() == ir.ODCLFUNC {
+			return true
+		}
+	}
+	return false
+}
diff --git a/src/cmd/compile/internal/pkginit/initorder.go b/src/cmd/compile/internal/pkginit/initorder.go
index a509753..426d298 100644
--- a/src/cmd/compile/internal/pkginit/initorder.go
+++ b/src/cmd/compile/internal/pkginit/initorder.go
@@ -5,9 +5,9 @@
 package pkginit
 
 import (
-	"bytes"
 	"container/heap"
 	"fmt"
+	"strings"
 
 	"cmd/compile/internal/base"
 	"cmd/compile/internal/ir"
@@ -236,7 +236,7 @@
 	// TODO(mdempsky): Method values are printed as "T.m-fm"
 	// rather than "T.m". Figure out how to avoid that.
 
-	var msg bytes.Buffer
+	var msg strings.Builder
 	fmt.Fprintf(&msg, "initialization loop:\n")
 	for _, n := range l {
 		fmt.Fprintf(&msg, "\t%v: %v refers to\n", ir.Line(n), n)
@@ -320,6 +320,15 @@
 		return
 	}
 
+	// Treat coverage counter variables effectively as invisible with
+	// respect to init order. If we don't do this, then the
+	// instrumentation vars can perturb the order of initialization
+	// away from the order of the original uninstrumented program.
+	// See issue #56293 for more details.
+	if n.CoverageCounter() || n.CoverageAuxVar() {
+		return
+	}
+
 	if d.seen.Has(n) {
 		return
 	}
diff --git a/src/cmd/compile/internal/ppc64/ssa.go b/src/cmd/compile/internal/ppc64/ssa.go
index d3a0ba1..d567a12 100644
--- a/src/cmd/compile/internal/ppc64/ssa.go
+++ b/src/cmd/compile/internal/ppc64/ssa.go
@@ -19,7 +19,7 @@
 	"strings"
 )
 
-// markMoves marks any MOVXconst ops that need to avoid clobbering flags.
+// ssaMarkMoves marks any MOVXconst ops that need to avoid clobbering flags.
 func ssaMarkMoves(s *ssagen.State, b *ssa.Block) {
 	//	flive := b.FlagsLiveAtEnd
 	//	if b.Control != nil && b.Control.Type.IsFlags() {
@@ -125,24 +125,6 @@
 			p.To.Reg = y
 		}
 
-	case ssa.OpPPC64LoweredMuluhilo:
-		// MULHDU	Rarg1, Rarg0, Reg0
-		// MULLD	Rarg1, Rarg0, Reg1
-		r0 := v.Args[0].Reg()
-		r1 := v.Args[1].Reg()
-		p := s.Prog(ppc64.AMULHDU)
-		p.From.Type = obj.TYPE_REG
-		p.From.Reg = r1
-		p.Reg = r0
-		p.To.Type = obj.TYPE_REG
-		p.To.Reg = v.Reg0()
-		p1 := s.Prog(ppc64.AMULLD)
-		p1.From.Type = obj.TYPE_REG
-		p1.From.Reg = r1
-		p1.Reg = r0
-		p1.To.Type = obj.TYPE_REG
-		p1.To.Reg = v.Reg1()
-
 	case ssa.OpPPC64LoweredAtomicAnd8,
 		ssa.OpPPC64LoweredAtomicAnd32,
 		ssa.OpPPC64LoweredAtomicOr8,
@@ -357,18 +339,16 @@
 
 	case ssa.OpPPC64LoweredAtomicCas64,
 		ssa.OpPPC64LoweredAtomicCas32:
+		// MOVD        $0, Rout
 		// LWSYNC
 		// loop:
 		// LDAR        (Rarg0), MutexHint, Rtmp
 		// CMP         Rarg1, Rtmp
-		// BNE         fail
+		// BNE         end
 		// STDCCC      Rarg2, (Rarg0)
 		// BNE         loop
 		// LWSYNC      // Only for sequential consistency; not required in CasRel.
 		// MOVD        $1, Rout
-		// BR          end
-		// fail:
-		// MOVD        $0, Rout
 		// end:
 		ld := ppc64.ALDAR
 		st := ppc64.ASTDCCC
@@ -382,20 +362,26 @@
 		r1 := v.Args[1].Reg()
 		r2 := v.Args[2].Reg()
 		out := v.Reg0()
+		// Initialize return value to false
+		p := s.Prog(ppc64.AMOVD)
+		p.From.Type = obj.TYPE_CONST
+		p.From.Offset = 0
+		p.To.Type = obj.TYPE_REG
+		p.To.Reg = out
 		// LWSYNC - Assuming shared data not write-through-required nor
 		// caching-inhibited. See Appendix B.2.2.2 in the ISA 2.07b.
 		plwsync1 := s.Prog(ppc64.ALWSYNC)
 		plwsync1.To.Type = obj.TYPE_NONE
 		// LDAR or LWAR
-		p := s.Prog(ld)
-		p.From.Type = obj.TYPE_MEM
-		p.From.Reg = r0
-		p.To.Type = obj.TYPE_REG
-		p.To.Reg = ppc64.REGTMP
+		p0 := s.Prog(ld)
+		p0.From.Type = obj.TYPE_MEM
+		p0.From.Reg = r0
+		p0.To.Type = obj.TYPE_REG
+		p0.To.Reg = ppc64.REGTMP
 		// If it is a Compare-and-Swap-Release operation, set the EH field with
 		// the release hint.
 		if v.AuxInt == 0 {
-			p.SetFrom3Const(0)
+			p0.SetFrom3Const(0)
 		}
 		// CMP reg1,reg2
 		p1 := s.Prog(cmp)
@@ -403,7 +389,7 @@
 		p1.From.Reg = r1
 		p1.To.Reg = ppc64.REGTMP
 		p1.To.Type = obj.TYPE_REG
-		// BNE cas_fail
+		// BNE done with return value = false
 		p2 := s.Prog(ppc64.ABNE)
 		p2.To.Type = obj.TYPE_BRANCH
 		// STDCCC or STWCCC
@@ -415,7 +401,7 @@
 		// BNE retry
 		p4 := s.Prog(ppc64.ABNE)
 		p4.To.Type = obj.TYPE_BRANCH
-		p4.To.SetTarget(p)
+		p4.To.SetTarget(p0)
 		// LWSYNC - Assuming shared data not write-through-required nor
 		// caching-inhibited. See Appendix B.2.1.1 in the ISA 2.07b.
 		// If the operation is a CAS-Release, then synchronization is not necessary.
@@ -423,25 +409,15 @@
 			plwsync2 := s.Prog(ppc64.ALWSYNC)
 			plwsync2.To.Type = obj.TYPE_NONE
 		}
-		// return true
+		// return value true
 		p5 := s.Prog(ppc64.AMOVD)
 		p5.From.Type = obj.TYPE_CONST
 		p5.From.Offset = 1
 		p5.To.Type = obj.TYPE_REG
 		p5.To.Reg = out
-		// BR done
-		p6 := s.Prog(obj.AJMP)
-		p6.To.Type = obj.TYPE_BRANCH
-		// return false
-		p7 := s.Prog(ppc64.AMOVD)
-		p7.From.Type = obj.TYPE_CONST
-		p7.From.Offset = 0
-		p7.To.Type = obj.TYPE_REG
-		p7.To.Reg = out
-		p2.To.SetTarget(p7)
 		// done (label)
-		p8 := s.Prog(obj.ANOP)
-		p6.To.SetTarget(p8)
+		p6 := s.Prog(obj.ANOP)
+		p2.To.SetTarget(p6)
 
 	case ssa.OpPPC64LoweredPubBarrier:
 		// LWSYNC
@@ -635,7 +611,7 @@
 		p.From.Reg = r2
 		p.Reg = r1
 		p.To.Type = obj.TYPE_REG
-		p.To.Reg = ppc64.REGTMP // result is not needed
+		p.To.Reg = v.Reg0()
 
 	case ssa.OpPPC64ROTLconst, ssa.OpPPC64ROTLWconst:
 		p := s.Prog(v.Op.Asm())
@@ -702,7 +678,7 @@
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = v.Args[0].Reg()
 
-	case ssa.OpPPC64ADDconst, ssa.OpPPC64ANDconst, ssa.OpPPC64ORconst, ssa.OpPPC64XORconst,
+	case ssa.OpPPC64ADDconst, ssa.OpPPC64ORconst, ssa.OpPPC64XORconst,
 		ssa.OpPPC64SRADconst, ssa.OpPPC64SRAWconst, ssa.OpPPC64SRDconst, ssa.OpPPC64SRWconst,
 		ssa.OpPPC64SLDconst, ssa.OpPPC64SLWconst, ssa.OpPPC64EXTSWSLconst, ssa.OpPPC64MULLWconst, ssa.OpPPC64MULLDconst:
 		p := s.Prog(v.Op.Asm())
@@ -761,7 +737,8 @@
 		p.From.Type = obj.TYPE_CONST
 		p.From.Offset = v.AuxInt
 		p.To.Type = obj.TYPE_REG
-		p.To.Reg = ppc64.REGTMP // discard result
+		//		p.To.Reg = ppc64.REGTMP // discard result
+		p.To.Reg = v.Reg0()
 
 	case ssa.OpPPC64MOVDaddr:
 		switch v.Aux.(type) {
@@ -852,7 +829,7 @@
 			// Special case for a rule combines the bytes of gostring.
 			// The v alignment might seem OK, but we don't want to load it
 			// using an offset because relocation comes later.
-			genAddr = strings.HasPrefix(fromAddr.Sym.Name, "go.string") || v.Type.Alignment()%4 != 0 || fromAddr.Offset%4 != 0
+			genAddr = strings.HasPrefix(fromAddr.Sym.Name, "go:string") || v.Type.Alignment()%4 != 0 || fromAddr.Offset%4 != 0
 		default:
 			genAddr = fromAddr.Offset%4 != 0
 		}
@@ -881,7 +858,6 @@
 		p.From = fromAddr
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
-		break
 
 	case ssa.OpPPC64MOVHload, ssa.OpPPC64MOVWZload, ssa.OpPPC64MOVBZload, ssa.OpPPC64MOVHZload, ssa.OpPPC64FMOVDload, ssa.OpPPC64FMOVSload:
 		p := s.Prog(v.Op.Asm())
@@ -987,18 +963,21 @@
 		p.To.Type = obj.TYPE_MEM
 		p.To.Reg = v.Args[0].Reg()
 
-	case ssa.OpPPC64ISEL, ssa.OpPPC64ISELB:
-		// ISEL, ISELB
-		// AuxInt value indicates condition: 0=LT 1=GT 2=EQ 4=GE 5=LE 6=NE
-		// ISEL only accepts 0, 1, 2 condition values but the others can be
-		// achieved by swapping operand order.
-		// arg0 ? arg1 : arg2 with conditions LT, GT, EQ
-		// arg0 ? arg2 : arg1 for conditions GE, LE, NE
-		// ISELB is used when a boolean result is needed, returning 0 or 1
+	case ssa.OpPPC64ISEL, ssa.OpPPC64ISELB, ssa.OpPPC64ISELZ:
+		// ISEL  AuxInt ? arg0 : arg1
+		// ISELB is a special case of ISEL where AuxInt ? $1 (arg0) : $0.
+		// ISELZ is a special case of ISEL where arg1 is implicitly $0.
+		//
+		// AuxInt value indicates conditions 0=LT 1=GT 2=EQ 3=SO 4=GE 5=LE 6=NE 7=NSO.
+		// ISEL accepts a CR bit argument, not a condition as expressed by AuxInt.
+		// Convert the condition to a CR bit argument by the following conversion:
+		//
+		// AuxInt&3 ? arg0 : arg1 for conditions LT, GT, EQ, SO
+		// AuxInt&3 ? arg1 : arg0 for conditions GE, LE, NE, NSO
 		p := s.Prog(ppc64.AISEL)
 		p.To.Type = obj.TYPE_REG
 		p.To.Reg = v.Reg()
-		// For ISELB, boolean result 0 or 1. Use R0 for 0 operand to avoid load.
+		// For ISELB/ISELZ Use R0 for 0 operand to avoid load.
 		r := obj.Addr{Type: obj.TYPE_REG, Reg: ppc64.REG_R0}
 		if v.Op == ssa.OpPPC64ISEL {
 			r.Reg = v.Args[1].Reg()
diff --git a/src/cmd/compile/internal/reflectdata/alg_test.go b/src/cmd/compile/internal/reflectdata/alg_test.go
index 1e57b91..a1fc8c5 100644
--- a/src/cmd/compile/internal/reflectdata/alg_test.go
+++ b/src/cmd/compile/internal/reflectdata/alg_test.go
@@ -74,3 +74,22 @@
 		_ = a == c
 	}
 }
+
+const size = 16
+
+type T1 struct {
+	a [size]byte
+}
+
+func BenchmarkEqStruct(b *testing.B) {
+	x, y := T1{}, T1{}
+	x.a = [size]byte{1, 2, 3, 4, 5, 6, 7, 8}
+	y.a = [size]byte{2, 3, 4, 5, 6, 7, 8, 9}
+
+	for i := 0; i < b.N; i++ {
+		f := x == y
+		if f {
+			println("hello")
+		}
+	}
+}
diff --git a/src/cmd/compile/internal/reflectdata/helpers.go b/src/cmd/compile/internal/reflectdata/helpers.go
new file mode 100644
index 0000000..99461cf
--- /dev/null
+++ b/src/cmd/compile/internal/reflectdata/helpers.go
@@ -0,0 +1,226 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package reflectdata
+
+import (
+	"cmd/compile/internal/base"
+	"cmd/compile/internal/ir"
+	"cmd/compile/internal/types"
+	"cmd/internal/src"
+)
+
+func hasRType(n, rtype ir.Node, fieldName string) bool {
+	if rtype != nil {
+		return true
+	}
+
+	// We make an exception for `init`, because we still depend on
+	// pkginit for sorting package initialization statements, and it
+	// gets confused by implicit conversions. Also, because
+	// package-scope statements can never be generic, so they'll never
+	// require dictionary lookups.
+	if base.Debug.Unified != 0 && ir.CurFunc.Nname.Sym().Name != "init" {
+		ir.Dump("CurFunc", ir.CurFunc)
+		base.FatalfAt(n.Pos(), "missing %s in %v: %+v", fieldName, ir.CurFunc, n)
+	}
+
+	return false
+}
+
+// assertOp asserts that n is an op.
+func assertOp(n ir.Node, op ir.Op) {
+	base.AssertfAt(n.Op() == op, n.Pos(), "want %v, have %v", op, n)
+}
+
+// assertOp2 asserts that n is an op1 or op2.
+func assertOp2(n ir.Node, op1, op2 ir.Op) {
+	base.AssertfAt(n.Op() == op1 || n.Op() == op2, n.Pos(), "want %v or %v, have %v", op1, op2, n)
+}
+
+// kindRType asserts that typ has the given kind, and returns an
+// expression that yields the *runtime._type value representing typ.
+func kindRType(pos src.XPos, typ *types.Type, k types.Kind) ir.Node {
+	base.AssertfAt(typ.Kind() == k, pos, "want %v type, have %v", k, typ)
+	return TypePtrAt(pos, typ)
+}
+
+// mapRType asserts that typ is a map type, and returns an expression
+// that yields the *runtime._type value representing typ.
+func mapRType(pos src.XPos, typ *types.Type) ir.Node {
+	return kindRType(pos, typ, types.TMAP)
+}
+
+// chanRType asserts that typ is a map type, and returns an expression
+// that yields the *runtime._type value representing typ.
+func chanRType(pos src.XPos, typ *types.Type) ir.Node {
+	return kindRType(pos, typ, types.TCHAN)
+}
+
+// sliceElemRType asserts that typ is a slice type, and returns an
+// expression that yields the *runtime._type value representing typ's
+// element type.
+func sliceElemRType(pos src.XPos, typ *types.Type) ir.Node {
+	base.AssertfAt(typ.IsSlice(), pos, "want slice type, have %v", typ)
+	return TypePtrAt(pos, typ.Elem())
+}
+
+// concreteRType asserts that typ is not an interface type, and
+// returns an expression that yields the *runtime._type value
+// representing typ.
+func concreteRType(pos src.XPos, typ *types.Type) ir.Node {
+	base.AssertfAt(!typ.IsInterface(), pos, "want non-interface type, have %v", typ)
+	return TypePtrAt(pos, typ)
+}
+
+// AppendElemRType asserts that n is an "append" operation, and
+// returns an expression that yields the *runtime._type value
+// representing the result slice type's element type.
+func AppendElemRType(pos src.XPos, n *ir.CallExpr) ir.Node {
+	assertOp(n, ir.OAPPEND)
+	if hasRType(n, n.RType, "RType") {
+		return n.RType
+	}
+	return sliceElemRType(pos, n.Type())
+}
+
+// CompareRType asserts that n is a comparison (== or !=) operation
+// between expressions of interface and non-interface type, and
+// returns an expression that yields the *runtime._type value
+// representing the non-interface type.
+func CompareRType(pos src.XPos, n *ir.BinaryExpr) ir.Node {
+	assertOp2(n, ir.OEQ, ir.ONE)
+	base.AssertfAt(n.X.Type().IsInterface() != n.Y.Type().IsInterface(), n.Pos(), "expect mixed interface and non-interface, have %L and %L", n.X, n.Y)
+	if hasRType(n, n.RType, "RType") {
+		return n.RType
+	}
+	typ := n.X.Type()
+	if typ.IsInterface() {
+		typ = n.Y.Type()
+	}
+	return concreteRType(pos, typ)
+}
+
+// ConvIfaceTypeWord asserts that n is conversion to interface type,
+// and returns an expression that yields the *runtime._type or
+// *runtime.itab value necessary for implementing the conversion.
+//
+//   - *runtime._type for the destination type, for I2I conversions
+//   - *runtime.itab, for T2I conversions
+//   - *runtime._type for the source type, for T2E conversions
+func ConvIfaceTypeWord(pos src.XPos, n *ir.ConvExpr) ir.Node {
+	assertOp(n, ir.OCONVIFACE)
+	src, dst := n.X.Type(), n.Type()
+	base.AssertfAt(dst.IsInterface(), n.Pos(), "want interface type, have %L", n)
+	if hasRType(n, n.TypeWord, "TypeWord") {
+		return n.TypeWord
+	}
+	if dst.IsEmptyInterface() {
+		return concreteRType(pos, src) // direct eface construction
+	}
+	if !src.IsInterface() {
+		return ITabAddrAt(pos, src, dst) // direct iface construction
+	}
+	return TypePtrAt(pos, dst) // convI2I
+}
+
+// ConvIfaceSrcRType asserts that n is a conversion from
+// non-interface type to interface type (or OCONVIDATA operation), and
+// returns an expression that yields the *runtime._type for copying
+// the convertee value to the heap.
+func ConvIfaceSrcRType(pos src.XPos, n *ir.ConvExpr) ir.Node {
+	assertOp2(n, ir.OCONVIFACE, ir.OCONVIDATA)
+	if hasRType(n, n.SrcRType, "SrcRType") {
+		return n.SrcRType
+	}
+	return concreteRType(pos, n.X.Type())
+}
+
+// CopyElemRType asserts that n is a "copy" operation, and returns an
+// expression that yields the *runtime._type value representing the
+// destination slice type's element type.
+func CopyElemRType(pos src.XPos, n *ir.BinaryExpr) ir.Node {
+	assertOp(n, ir.OCOPY)
+	if hasRType(n, n.RType, "RType") {
+		return n.RType
+	}
+	return sliceElemRType(pos, n.X.Type())
+}
+
+// DeleteMapRType asserts that n is a "delete" operation, and returns
+// an expression that yields the *runtime._type value representing the
+// map type.
+func DeleteMapRType(pos src.XPos, n *ir.CallExpr) ir.Node {
+	assertOp(n, ir.ODELETE)
+	if hasRType(n, n.RType, "RType") {
+		return n.RType
+	}
+	return mapRType(pos, n.Args[0].Type())
+}
+
+// IndexMapRType asserts that n is a map index operation, and returns
+// an expression that yields the *runtime._type value representing the
+// map type.
+func IndexMapRType(pos src.XPos, n *ir.IndexExpr) ir.Node {
+	assertOp(n, ir.OINDEXMAP)
+	if hasRType(n, n.RType, "RType") {
+		return n.RType
+	}
+	return mapRType(pos, n.X.Type())
+}
+
+// MakeChanRType asserts that n is a "make" operation for a channel
+// type, and returns an expression that yields the *runtime._type
+// value representing that channel type.
+func MakeChanRType(pos src.XPos, n *ir.MakeExpr) ir.Node {
+	assertOp(n, ir.OMAKECHAN)
+	if hasRType(n, n.RType, "RType") {
+		return n.RType
+	}
+	return chanRType(pos, n.Type())
+}
+
+// MakeMapRType asserts that n is a "make" operation for a map type,
+// and returns an expression that yields the *runtime._type value
+// representing that map type.
+func MakeMapRType(pos src.XPos, n *ir.MakeExpr) ir.Node {
+	assertOp(n, ir.OMAKEMAP)
+	if hasRType(n, n.RType, "RType") {
+		return n.RType
+	}
+	return mapRType(pos, n.Type())
+}
+
+// MakeSliceElemRType asserts that n is a "make" operation for a slice
+// type, and returns an expression that yields the *runtime._type
+// value representing that slice type's element type.
+func MakeSliceElemRType(pos src.XPos, n *ir.MakeExpr) ir.Node {
+	assertOp2(n, ir.OMAKESLICE, ir.OMAKESLICECOPY)
+	if hasRType(n, n.RType, "RType") {
+		return n.RType
+	}
+	return sliceElemRType(pos, n.Type())
+}
+
+// RangeMapRType asserts that n is a "range" loop over a map value,
+// and returns an expression that yields the *runtime._type value
+// representing that map type.
+func RangeMapRType(pos src.XPos, n *ir.RangeStmt) ir.Node {
+	assertOp(n, ir.ORANGE)
+	if hasRType(n, n.RType, "RType") {
+		return n.RType
+	}
+	return mapRType(pos, n.X.Type())
+}
+
+// UnsafeSliceElemRType asserts that n is an "unsafe.Slice" operation,
+// and returns an expression that yields the *runtime._type value
+// representing the result slice type's element type.
+func UnsafeSliceElemRType(pos src.XPos, n *ir.BinaryExpr) ir.Node {
+	assertOp(n, ir.OUNSAFESLICE)
+	if hasRType(n, n.RType, "RType") {
+		return n.RType
+	}
+	return sliceElemRType(pos, n.Type())
+}
diff --git a/src/cmd/compile/internal/reflectdata/reflect.go b/src/cmd/compile/internal/reflectdata/reflect.go
index 21301ab..9dcc0a0 100644
--- a/src/cmd/compile/internal/reflectdata/reflect.go
+++ b/src/cmd/compile/internal/reflectdata/reflect.go
@@ -19,7 +19,6 @@
 	"cmd/compile/internal/inline"
 	"cmd/compile/internal/ir"
 	"cmd/compile/internal/objw"
-	"cmd/compile/internal/staticdata"
 	"cmd/compile/internal/typebits"
 	"cmd/compile/internal/typecheck"
 	"cmd/compile/internal/types"
@@ -411,7 +410,7 @@
 		return
 	}
 
-	s := base.Ctxt.Lookup("type..importpath." + p.Prefix + ".")
+	s := base.Ctxt.Lookup("type:.importpath." + p.Prefix + ".")
 	ot := dnameData(s, 0, p.Path, "", nil, false, false)
 	objw.Global(s, int32(ot), obj.DUPOK|obj.RODATA)
 	s.Set(obj.AttrContentAddressable, true)
@@ -426,10 +425,10 @@
 	if pkg == types.LocalPkg && base.Ctxt.Pkgpath == "" {
 		// If we don't know the full import path of the package being compiled
 		// (i.e. -p was not passed on the compiler command line), emit a reference to
-		// type..importpath.""., which the linker will rewrite using the correct import path.
+		// type:.importpath.""., which the linker will rewrite using the correct import path.
 		// Every package that imports this one directly defines the symbol.
 		// See also https://groups.google.com/forum/#!topic/golang-dev/myb9s53HxGQ.
-		ns := base.Ctxt.Lookup(`type..importpath."".`)
+		ns := base.Ctxt.Lookup(`type:.importpath."".`)
 		return objw.SymPtr(s, ot, ns, 0)
 	}
 
@@ -445,10 +444,10 @@
 	if pkg == types.LocalPkg && base.Ctxt.Pkgpath == "" {
 		// If we don't know the full import path of the package being compiled
 		// (i.e. -p was not passed on the compiler command line), emit a reference to
-		// type..importpath.""., which the linker will rewrite using the correct import path.
+		// type:.importpath.""., which the linker will rewrite using the correct import path.
 		// Every package that imports this one directly defines the symbol.
 		// See also https://groups.google.com/forum/#!topic/golang-dev/myb9s53HxGQ.
-		ns := base.Ctxt.Lookup(`type..importpath."".`)
+		ns := base.Ctxt.Lookup(`type:.importpath."".`)
 		return objw.SymPtrOff(s, ot, ns)
 	}
 
@@ -517,11 +516,11 @@
 
 // dname creates a reflect.name for a struct field or method.
 func dname(name, tag string, pkg *types.Pkg, exported, embedded bool) *obj.LSym {
-	// Write out data as "type.." to signal two things to the
+	// Write out data as "type:." to signal two things to the
 	// linker, first that when dynamically linking, the symbol
 	// should be moved to a relro section, and second that the
 	// contents should not be decoded as a type.
-	sname := "type..namedata."
+	sname := "type:.namedata."
 	if pkg == nil {
 		// In the common case, share data with other packages.
 		if name == "" {
@@ -562,7 +561,7 @@
 	if t.Sym() == nil && len(m) == 0 {
 		return ot
 	}
-	noff := int(types.Rnd(int64(ot), int64(types.PtrSize)))
+	noff := int(types.RoundUp(int64(ot), int64(types.PtrSize)))
 	if noff != ot {
 		base.Fatalf("unexpected alignment in dextratype for %v", t)
 	}
@@ -798,7 +797,7 @@
 // TrackSym returns the symbol for tracking use of field/method f, assumed
 // to be a member of struct/interface type t.
 func TrackSym(t *types.Type, f *types.Field) *obj.LSym {
-	return base.PkgLinksym("go.track", t.LinkString()+"."+f.Sym.Name, obj.ABI0)
+	return base.PkgLinksym("go:track", t.LinkString()+"."+f.Sym.Name, obj.ABI0)
 }
 
 func TypeSymPrefix(prefix string, t *types.Type) *types.Sym {
@@ -842,9 +841,15 @@
 	return TypeSym(t).Linksym()
 }
 
+// Deprecated: Use TypePtrAt instead.
 func TypePtr(t *types.Type) *ir.AddrExpr {
-	n := ir.NewLinksymExpr(base.Pos, TypeLinksym(t), types.Types[types.TUINT8])
-	return typecheck.Expr(typecheck.NodAddr(n)).(*ir.AddrExpr)
+	return TypePtrAt(base.Pos, t)
+}
+
+// TypePtrAt returns an expression that evaluates to the
+// *runtime._type value for t.
+func TypePtrAt(pos src.XPos, t *types.Type) *ir.AddrExpr {
+	return typecheck.LinksymAddr(pos, TypeLinksym(t), types.Types[types.TUINT8])
 }
 
 // ITabLsym returns the LSym representing the itab for concrete type typ implementing
@@ -864,9 +869,15 @@
 	return lsym
 }
 
-// ITabAddr returns an expression representing a pointer to the itab
-// for concrete type typ implementing interface iface.
+// Deprecated: Use ITabAddrAt instead.
 func ITabAddr(typ, iface *types.Type) *ir.AddrExpr {
+	return ITabAddrAt(base.Pos, typ, iface)
+}
+
+// ITabAddrAt returns an expression that evaluates to the
+// *runtime.itab value for concrete type typ implementing interface
+// iface.
+func ITabAddrAt(pos src.XPos, typ, iface *types.Type) *ir.AddrExpr {
 	s, existed := ir.Pkgs.Itab.LookupOK(typ.LinkString() + "," + iface.LinkString())
 	lsym := s.Linksym()
 
@@ -874,8 +885,7 @@
 		writeITab(lsym, typ, iface, false)
 	}
 
-	n := ir.NewLinksymExpr(base.Pos, lsym, types.Types[types.TUINT8])
-	return typecheck.Expr(typecheck.NodAddr(n)).(*ir.AddrExpr)
+	return typecheck.LinksymAddr(pos, lsym, types.Types[types.TUINT8])
 }
 
 // needkeyupdate reports whether map updates with t as a key
@@ -1347,7 +1357,7 @@
 	// process ptabs
 	if types.LocalPkg.Name == "main" && len(ptabs) > 0 {
 		ot := 0
-		s := base.Ctxt.Lookup("go.plugin.tabs")
+		s := base.Ctxt.Lookup("go:plugin.tabs")
 		for _, p := range ptabs {
 			// Dump ptab symbol into go.pluginsym package.
 			//
@@ -1370,7 +1380,7 @@
 		objw.Global(s, int32(ot), int16(obj.RODATA))
 
 		ot = 0
-		s = base.Ctxt.Lookup("go.plugin.exports")
+		s = base.Ctxt.Lookup("go:plugin.exports")
 		for _, p := range ptabs {
 			ot = objw.SymPtr(s, ot, p.Linksym(), 0)
 		}
@@ -1385,6 +1395,35 @@
 	}
 }
 
+// writtenByWriteBasicTypes reports whether typ is written by WriteBasicTypes.
+// WriteBasicTypes always writes pointer types; any pointer has been stripped off typ already.
+func writtenByWriteBasicTypes(typ *types.Type) bool {
+	if typ.Sym() == nil && typ.Kind() == types.TFUNC {
+		f := typ.FuncType()
+		// func(error) string
+		if f.Receiver.NumFields() == 0 && f.TParams.NumFields() == 0 &&
+			f.Params.NumFields() == 1 && f.Results.NumFields() == 1 &&
+			f.Params.FieldType(0) == types.ErrorType &&
+			f.Results.FieldType(0) == types.Types[types.TSTRING] {
+			return true
+		}
+	}
+
+	// Now we have left the basic types plus any and error, plus slices of them.
+	// Strip the slice.
+	if typ.Sym() == nil && typ.IsSlice() {
+		typ = typ.Elem()
+	}
+
+	// Basic types.
+	sym := typ.Sym()
+	if sym != nil && (sym.Pkg == types.BuiltinPkg || sym.Pkg == types.UnsafePkg) {
+		return true
+	}
+	// any or error
+	return (sym == nil && typ.IsEmptyInterface()) || typ == types.ErrorType
+}
+
 func WriteBasicTypes() {
 	// do basic types if compiling package runtime.
 	// they have to be in at least one package,
@@ -1392,23 +1431,30 @@
 	// so this is as good as any.
 	// another possible choice would be package main,
 	// but using runtime means fewer copies in object files.
+	// The code here needs to be in sync with writtenByWriteBasicTypes above.
 	if base.Ctxt.Pkgpath == "runtime" {
+		// Note: always write NewPtr(t) because NeedEmit's caller strips the pointer.
+		var list []*types.Type
 		for i := types.Kind(1); i <= types.TBOOL; i++ {
-			writeType(types.NewPtr(types.Types[i]))
+			list = append(list, types.Types[i])
 		}
-		writeType(types.NewPtr(types.Types[types.TSTRING]))
-		writeType(types.NewPtr(types.Types[types.TUNSAFEPTR]))
-		writeType(types.AnyType)
+		list = append(list,
+			types.Types[types.TSTRING],
+			types.Types[types.TUNSAFEPTR],
+			types.AnyType,
+			types.ErrorType)
+		for _, t := range list {
+			writeType(types.NewPtr(t))
+			writeType(types.NewPtr(types.NewSlice(t)))
+		}
 
-		// emit type structs for error and func(error) string.
-		// The latter is the type of an auto-generated wrapper.
-		writeType(types.NewPtr(types.ErrorType))
-
-		writeType(types.NewSignature(types.NoPkg, nil, nil, []*types.Field{
+		// emit type for func(error) string,
+		// which is the type of an auto-generated wrapper.
+		writeType(types.NewPtr(types.NewSignature(types.NoPkg, nil, nil, []*types.Field{
 			types.NewField(base.Pos, nil, types.ErrorType),
 		}, []*types.Field{
 			types.NewField(base.Pos, nil, types.Types[types.TSTRING]),
-		}))
+		})))
 
 		// add paths for runtime and main, which 6l imports implicitly.
 		dimportpath(ir.Pkgs.Runtime)
@@ -1538,7 +1584,11 @@
 
 // dgcptrmask emits and returns the symbol containing a pointer mask for type t.
 func dgcptrmask(t *types.Type, write bool) *obj.LSym {
-	ptrmask := make([]byte, (types.PtrDataSize(t)/int64(types.PtrSize)+7)/8)
+	// Bytes we need for the ptrmask.
+	n := (types.PtrDataSize(t)/int64(types.PtrSize) + 7) / 8
+	// Runtime wants ptrmasks padded to a multiple of uintptr in size.
+	n = (n + int64(types.PtrSize) - 1) &^ (int64(types.PtrSize) - 1)
+	ptrmask := make([]byte, n)
 	fillptrmask(t, ptrmask)
 	p := fmt.Sprintf("runtime.gcbits.%x", ptrmask)
 
@@ -1700,7 +1750,7 @@
 	if ZeroSize < size {
 		ZeroSize = size
 	}
-	lsym := base.PkgLinksym("go.map", "zero", obj.ABI0)
+	lsym := base.PkgLinksym("go:map", "zero", obj.ABI0)
 	x := ir.NewLinksymExpr(base.Pos, lsym, types.Types[types.TUINT8])
 	return typecheck.Expr(typecheck.NodAddr(x))
 }
@@ -1745,6 +1795,9 @@
 	// instantiated generic functions too.
 
 	switch sym := typ.Sym(); {
+	case writtenByWriteBasicTypes(typ):
+		return base.Ctxt.Pkgpath == "runtime"
+
 	case sym == nil:
 		// Anonymous type; possibly never seen before or ever again.
 		// Need to emit to be safe (however, see TODO above).
@@ -1754,11 +1807,6 @@
 		// Local defined type; our responsibility.
 		return true
 
-	case base.Ctxt.Pkgpath == "runtime" && (sym.Pkg == types.BuiltinPkg || sym.Pkg == types.UnsafePkg):
-		// Package runtime is responsible for including code for builtin
-		// types (predeclared and package unsafe).
-		return true
-
 	case typ.IsFullyInstantiated():
 		// Instantiated type; possibly instantiated with unique type arguments.
 		// Need to emit to be safe (however, see TODO above).
@@ -1890,14 +1938,14 @@
 	// the TOC to the appropriate value for that module. But if it returns
 	// directly to the wrapper's caller, nothing will reset it to the correct
 	// value for that function.
+	var call *ir.CallExpr
 	if !base.Flag.Cfg.Instrumenting && rcvr.IsPtr() && methodrcvr.IsPtr() && method.Embedded != 0 && !types.IsInterfaceMethod(method.Type) && !(base.Ctxt.Arch.Name == "ppc64le" && base.Ctxt.Flag_dynlink) && !generic {
-		call := ir.NewCallExpr(base.Pos, ir.OCALL, dot, nil)
+		call = ir.NewCallExpr(base.Pos, ir.OCALL, dot, nil)
 		call.Args = ir.ParamNames(fn.Type())
 		call.IsDDD = fn.Type().IsVariadic()
 		fn.Body.Append(ir.NewTailCallStmt(base.Pos, call))
 	} else {
 		fn.SetWrapper(true) // ignore frame for panic+recover matching
-		var call *ir.CallExpr
 
 		if generic && dot.X != nthis {
 			// If there is embedding involved, then we should do the
@@ -1982,7 +2030,23 @@
 	typecheck.Stmts(fn.Body)
 
 	if AfterGlobalEscapeAnalysis {
-		inline.InlineCalls(fn)
+		// Inlining the method may reveal closures, which require walking all function bodies
+		// to decide whether to capture free variables by value or by ref. So we only do inline
+		// if the method do not contain any closures, otherwise, the escape analysis may make
+		// dead variables resurrected, and causing liveness analysis confused, see issue #53702.
+		var canInline bool
+		switch x := call.X.(type) {
+		case *ir.Name:
+			canInline = len(x.Func.Closures) == 0
+		case *ir.SelectorExpr:
+			if x.Op() == ir.OMETHEXPR {
+				canInline = x.FuncName().Func != nil && len(x.FuncName().Func.Closures) == 0
+			}
+		}
+		if canInline {
+			// TODO(prattmic): plumb PGO.
+			inline.InlineCalls(fn, nil)
+		}
 		escape.Batch([]*ir.Func{fn}, false)
 	}
 
@@ -2046,8 +2110,15 @@
 		// of the method for matching.
 		r := obj.Addrel(ir.CurFunc.LSym)
 		// We use a separate symbol just to tell the linker the method name.
-		// (The symbol itself is not needed in the final binary.)
-		r.Sym = staticdata.StringSym(src.NoXPos, dot.Sel.Name)
+		// (The symbol itself is not needed in the final binary. Do not use
+		// staticdata.StringSym, which creates a content addessable symbol,
+		// which may have trailing zero bytes. This symbol doesn't need to
+		// be deduplicated anyway.)
+		name := dot.Sel.Name
+		var nameSym obj.LSym
+		nameSym.WriteString(base.Ctxt, 0, len(name), name)
+		objw.Global(&nameSym, int32(len(name)), obj.RODATA)
+		r.Sym = &nameSym
 		r.Type = objabi.R_USEGENERICIFACEMETHOD
 		return
 	}
diff --git a/src/cmd/compile/internal/riscv64/ssa.go b/src/cmd/compile/internal/riscv64/ssa.go
index 5f74fd8..984779f 100644
--- a/src/cmd/compile/internal/riscv64/ssa.go
+++ b/src/cmd/compile/internal/riscv64/ssa.go
@@ -179,7 +179,7 @@
 	}
 }
 
-// markMoves marks any MOVXconst ops that need to avoid clobbering flags.
+// ssaMarkMoves marks any MOVXconst ops that need to avoid clobbering flags.
 // RISC-V has no flags, so this is a no-op.
 func ssaMarkMoves(s *ssagen.State, b *ssa.Block) {}
 
diff --git a/src/cmd/compile/internal/s390x/ssa.go b/src/cmd/compile/internal/s390x/ssa.go
index 7d9b31d..ba50b00 100644
--- a/src/cmd/compile/internal/s390x/ssa.go
+++ b/src/cmd/compile/internal/s390x/ssa.go
@@ -16,7 +16,7 @@
 	"cmd/internal/obj/s390x"
 )
 
-// markMoves marks any MOVXconst ops that need to avoid clobbering flags.
+// ssaMarkMoves marks any MOVXconst ops that need to avoid clobbering flags.
 func ssaMarkMoves(s *ssagen.State, b *ssa.Block) {
 	flive := b.FlagsLiveAtEnd
 	for _, c := range b.ControlValues() {
diff --git a/src/cmd/compile/internal/ssa/README.md b/src/cmd/compile/internal/ssa/README.md
index d695fda..27ac02b 100644
--- a/src/cmd/compile/internal/ssa/README.md
+++ b/src/cmd/compile/internal/ssa/README.md
@@ -34,7 +34,7 @@
 mainly consists of a unique identifier, an operator, a type, and some arguments.
 
 An operator or `Op` describes the operation that computes the value. The
-semantics of each operator can be found in `gen/*Ops.go`. For example, `OpAdd8`
+semantics of each operator can be found in `_gen/*Ops.go`. For example, `OpAdd8`
 takes two value arguments holding 8-bit integers and results in their addition.
 Here is a possible SSA representation of the addition of two `uint8` values:
 
@@ -205,16 +205,16 @@
 
 While most compiler passes are implemented directly in Go code, some others are
 code generated. This is currently done via rewrite rules, which have their own
-syntax and are maintained in `gen/*.rules`. Simpler optimizations can be written
+syntax and are maintained in `_gen/*.rules`. Simpler optimizations can be written
 easily and quickly this way, but rewrite rules are not suitable for more complex
 optimizations.
 
 To read more on rewrite rules, have a look at the top comments in
-[gen/generic.rules](gen/generic.rules) and [gen/rulegen.go](gen/rulegen.go).
+[_gen/generic.rules](_gen/generic.rules) and [_gen/rulegen.go](_gen/rulegen.go).
 
 Similarly, the code to manage operators is also code generated from
-`gen/*Ops.go`, as it is easier to maintain a few tables than a lot of code.
-After changing the rules or operators, see [gen/README](gen/README) for
+`_gen/*Ops.go`, as it is easier to maintain a few tables than a lot of code.
+After changing the rules or operators, see [_gen/README](_gen/README) for
 instructions on how to generate the Go code again.
 
 <!---
diff --git a/src/cmd/compile/internal/ssa/_gen/386.rules b/src/cmd/compile/internal/ssa/_gen/386.rules
new file mode 100644
index 0000000..5e30ca9
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/_gen/386.rules
@@ -0,0 +1,1091 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Lowering arithmetic
+(Add(Ptr|32|16|8) ...) => (ADDL ...)
+(Add(32|64)F ...) => (ADDS(S|D) ...)
+(Add32carry ...) => (ADDLcarry ...)
+(Add32withcarry ...) => (ADCL ...)
+
+(Sub(Ptr|32|16|8) ...) => (SUBL ...)
+(Sub(32|64)F ...) => (SUBS(S|D) ...)
+(Sub32carry ...) => (SUBLcarry ...)
+(Sub32withcarry ...) => (SBBL ...)
+
+(Mul(32|16|8) ...) => (MULL ...)
+(Mul(32|64)F ...) => (MULS(S|D) ...)
+(Mul32uhilo ...) => (MULLQU ...)
+
+(Select0 (Mul32uover x y)) => (Select0 <typ.UInt32> (MULLU x y))
+(Select1 (Mul32uover x y)) => (SETO (Select1 <types.TypeFlags> (MULLU x y)))
+
+(Avg32u ...) => (AVGLU ...)
+
+(Div(32|64)F ...) => (DIVS(S|D) ...)
+(Div(32|32u|16|16u) ...) => (DIV(L|LU|W|WU) ...)
+(Div8   x y) => (DIVW  (SignExt8to16 x) (SignExt8to16 y))
+(Div8u  x y) => (DIVWU (ZeroExt8to16 x) (ZeroExt8to16 y))
+
+(Hmul(32|32u) ...) => (HMUL(L|LU) ...)
+
+(Mod(32|32u|16|16u) ...) => (MOD(L|LU|W|WU) ...)
+(Mod8   x y) => (MODW  (SignExt8to16 x) (SignExt8to16 y))
+(Mod8u  x y) => (MODWU (ZeroExt8to16 x) (ZeroExt8to16 y))
+
+(And(32|16|8) ...) => (ANDL ...)
+(Or(32|16|8) ...) => (ORL ...)
+(Xor(32|16|8) ...) => (XORL ...)
+
+(Neg(32|16|8) ...) => (NEGL ...)
+(Neg32F x) => (PXOR x (MOVSSconst <typ.Float32> [float32(math.Copysign(0, -1))]))
+(Neg64F x) => (PXOR x (MOVSDconst <typ.Float64> [math.Copysign(0, -1)]))
+
+(Com(32|16|8) ...) => (NOTL ...)
+
+// Lowering boolean ops
+(AndB ...) => (ANDL ...)
+(OrB ...) => (ORL ...)
+(Not x) => (XORLconst [1] x)
+
+// Lowering pointer arithmetic
+(OffPtr [off] ptr) => (ADDLconst [int32(off)] ptr)
+
+(Bswap32 ...) => (BSWAPL ...)
+
+(Sqrt ...) => (SQRTSD ...)
+(Sqrt32 ...) => (SQRTSS ...)
+
+(Ctz16 x) => (BSFL (ORLconst <typ.UInt32> [0x10000] x))
+(Ctz16NonZero ...) => (BSFL ...)
+
+// Lowering extension
+(SignExt8to16  ...) => (MOVBLSX ...)
+(SignExt8to32  ...) => (MOVBLSX ...)
+(SignExt16to32 ...) => (MOVWLSX ...)
+
+(ZeroExt8to16  ...) => (MOVBLZX ...)
+(ZeroExt8to32  ...) => (MOVBLZX ...)
+(ZeroExt16to32 ...) => (MOVWLZX ...)
+
+(Signmask x) => (SARLconst x [31])
+(Zeromask <t> x) => (XORLconst [-1] (SBBLcarrymask <t> (CMPLconst x [1])))
+(Slicemask <t> x) => (SARLconst (NEGL <t> x) [31])
+
+// Lowering truncation
+// Because we ignore high parts of registers, truncates are just copies.
+(Trunc16to8  ...) => (Copy ...)
+(Trunc32to8  ...) => (Copy ...)
+(Trunc32to16 ...) => (Copy ...)
+
+// Lowering float-int conversions
+(Cvt32to32F ...) => (CVTSL2SS ...)
+(Cvt32to64F ...) => (CVTSL2SD ...)
+
+(Cvt32Fto32 ...) => (CVTTSS2SL ...)
+(Cvt64Fto32 ...) => (CVTTSD2SL ...)
+
+(Cvt32Fto64F ...) => (CVTSS2SD ...)
+(Cvt64Fto32F ...) => (CVTSD2SS ...)
+
+(Round32F ...) => (Copy ...)
+(Round64F ...) => (Copy ...)
+
+(CvtBoolToUint8 ...) => (Copy ...)
+
+// Lowering shifts
+// Unsigned shifts need to return 0 if shift amount is >= width of shifted value.
+//   result = (arg << shift) & (shift >= argbits ? 0 : 0xffffffffffffffff)
+(Lsh32x(32|16|8) <t> x y) && !shiftIsBounded(v) => (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMP(L|W|B)const y [32])))
+(Lsh16x(32|16|8) <t> x y) && !shiftIsBounded(v) => (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMP(L|W|B)const y [32])))
+(Lsh8x(32|16|8)  <t> x y) && !shiftIsBounded(v) => (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMP(L|W|B)const y [32])))
+
+(Lsh32x(32|16|8) <t> x y) && shiftIsBounded(v) => (SHLL <t> x y)
+(Lsh16x(32|16|8) <t> x y) && shiftIsBounded(v) => (SHLL <t> x y)
+(Lsh8x(32|16|8)  <t> x y) && shiftIsBounded(v) => (SHLL <t> x y)
+
+(Rsh32Ux(32|16|8) <t> x y) && !shiftIsBounded(v) => (ANDL (SHRL <t> x y) (SBBLcarrymask <t> (CMP(L|W|B)const y [32])))
+(Rsh16Ux(32|16|8) <t> x y) && !shiftIsBounded(v) => (ANDL (SHRW <t> x y) (SBBLcarrymask <t> (CMP(L|W|B)const y [16])))
+(Rsh8Ux(32|16|8)  <t> x y) && !shiftIsBounded(v) => (ANDL (SHRB <t> x y) (SBBLcarrymask <t> (CMP(L|W|B)const y [8])))
+
+(Rsh32Ux(32|16|8) <t> x y) && shiftIsBounded(v) => (SHRL <t> x y)
+(Rsh16Ux(32|16|8) <t> x y) && shiftIsBounded(v) => (SHRW <t> x y)
+(Rsh8Ux(32|16|8)  <t> x y) && shiftIsBounded(v) => (SHRB <t> x y)
+
+// Signed right shift needs to return 0/-1 if shift amount is >= width of shifted value.
+// We implement this by setting the shift value to -1 (all ones) if the shift value is >= width.
+
+(Rsh32x(32|16|8) <t> x y) && !shiftIsBounded(v) => (SARL <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMP(L|W|B)const y [32])))))
+(Rsh16x(32|16|8) <t> x y) && !shiftIsBounded(v) => (SARW <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMP(L|W|B)const y [16])))))
+(Rsh8x(32|16|8) <t> x y)  && !shiftIsBounded(v) => (SARB <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMP(L|W|B)const y [8])))))
+
+(Rsh32x(32|16|8) <t> x y) && shiftIsBounded(v) => (SARL x y)
+(Rsh16x(32|16|8) <t> x y) && shiftIsBounded(v) => (SARW x y)
+(Rsh8x(32|16|8) <t> x y)  && shiftIsBounded(v) => (SARB x y)
+
+// constant shifts
+// generic opt rewrites all constant shifts to shift by Const64
+(Lsh32x64 x (Const64 [c])) && uint64(c) < 32 => (SHLLconst x [int32(c)])
+(Rsh32x64 x (Const64 [c])) && uint64(c) < 32 => (SARLconst x [int32(c)])
+(Rsh32Ux64 x (Const64 [c])) && uint64(c) < 32 => (SHRLconst x [int32(c)])
+(Lsh16x64 x (Const64 [c])) && uint64(c) < 16 => (SHLLconst x [int32(c)])
+(Rsh16x64 x (Const64 [c])) && uint64(c) < 16 => (SARWconst x [int16(c)])
+(Rsh16Ux64 x (Const64 [c])) && uint64(c) < 16 => (SHRWconst x [int16(c)])
+(Lsh8x64 x (Const64 [c])) && uint64(c) < 8 => (SHLLconst x [int32(c)])
+(Rsh8x64 x (Const64 [c])) && uint64(c) < 8 => (SARBconst x [int8(c)])
+(Rsh8Ux64 x (Const64 [c])) && uint64(c) < 8 => (SHRBconst x [int8(c)])
+
+// large constant shifts
+(Lsh32x64 _ (Const64 [c])) && uint64(c) >= 32 => (Const32 [0])
+(Rsh32Ux64 _ (Const64 [c])) && uint64(c) >= 32 => (Const32 [0])
+(Lsh16x64 _ (Const64 [c])) && uint64(c) >= 16 => (Const16 [0])
+(Rsh16Ux64 _ (Const64 [c])) && uint64(c) >= 16 => (Const16 [0])
+(Lsh8x64 _ (Const64 [c])) && uint64(c) >= 8 => (Const8 [0])
+(Rsh8Ux64 _ (Const64 [c])) && uint64(c) >= 8 => (Const8 [0])
+
+// large constant signed right shift, we leave the sign bit
+(Rsh32x64 x (Const64 [c])) && uint64(c) >= 32 => (SARLconst x [31])
+(Rsh16x64 x (Const64 [c])) && uint64(c) >= 16 => (SARWconst x [15])
+(Rsh8x64 x (Const64 [c])) && uint64(c) >= 8 => (SARBconst x [7])
+
+// rotates
+(RotateLeft32 ...) => (ROLL ...)
+(RotateLeft16 ...) => (ROLW ...)
+(RotateLeft8  ...) => (ROLB ...)
+// constant rotates
+(ROLL x (MOVLconst [c])) => (ROLLconst [c&31] x)
+(ROLW x (MOVLconst [c])) => (ROLWconst [int16(c&15)] x)
+(ROLB x (MOVLconst [c])) => (ROLBconst [int8(c&7)] x)
+
+// Lowering comparisons
+(Less32  x y) => (SETL (CMPL x y))
+(Less16  x y) => (SETL (CMPW x y))
+(Less8   x y) => (SETL (CMPB x y))
+(Less32U x y) => (SETB (CMPL x y))
+(Less16U x y) => (SETB (CMPW x y))
+(Less8U  x y) => (SETB (CMPB x y))
+// Use SETGF with reversed operands to dodge NaN case
+(Less64F x y) => (SETGF (UCOMISD y x))
+(Less32F x y) => (SETGF (UCOMISS y x))
+
+(Leq32  x y) => (SETLE (CMPL x y))
+(Leq16  x y) => (SETLE (CMPW x y))
+(Leq8   x y) => (SETLE (CMPB x y))
+(Leq32U x y) => (SETBE (CMPL x y))
+(Leq16U x y) => (SETBE (CMPW x y))
+(Leq8U  x y) => (SETBE (CMPB x y))
+// Use SETGEF with reversed operands to dodge NaN case
+(Leq64F x y) => (SETGEF (UCOMISD y x))
+(Leq32F x y) => (SETGEF (UCOMISS y x))
+
+(Eq32  x y) => (SETEQ (CMPL x y))
+(Eq16  x y) => (SETEQ (CMPW x y))
+(Eq8   x y) => (SETEQ (CMPB x y))
+(EqB   x y) => (SETEQ (CMPB x y))
+(EqPtr x y) => (SETEQ (CMPL x y))
+(Eq64F x y) => (SETEQF (UCOMISD x y))
+(Eq32F x y) => (SETEQF (UCOMISS x y))
+
+(Neq32  x y) => (SETNE (CMPL x y))
+(Neq16  x y) => (SETNE (CMPW x y))
+(Neq8   x y) => (SETNE (CMPB x y))
+(NeqB   x y) => (SETNE (CMPB x y))
+(NeqPtr x y) => (SETNE (CMPL x y))
+(Neq64F x y) => (SETNEF (UCOMISD x y))
+(Neq32F x y) => (SETNEF (UCOMISS x y))
+
+// Lowering loads
+(Load <t> ptr mem) && (is32BitInt(t) || isPtr(t)) => (MOVLload ptr mem)
+(Load <t> ptr mem) && is16BitInt(t) => (MOVWload ptr mem)
+(Load <t> ptr mem) && (t.IsBoolean() || is8BitInt(t)) => (MOVBload ptr mem)
+(Load <t> ptr mem) && is32BitFloat(t) => (MOVSSload ptr mem)
+(Load <t> ptr mem) && is64BitFloat(t) => (MOVSDload ptr mem)
+
+// Lowering stores
+// These more-specific FP versions of Store pattern should come first.
+(Store {t} ptr val mem) && t.Size() == 8 && is64BitFloat(val.Type) => (MOVSDstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 4 && is32BitFloat(val.Type) => (MOVSSstore ptr val mem)
+
+(Store {t} ptr val mem) && t.Size() == 4 => (MOVLstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 2 => (MOVWstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 1 => (MOVBstore ptr val mem)
+
+// Lowering moves
+(Move [0] _ _ mem) => mem
+(Move [1] dst src mem) => (MOVBstore dst (MOVBload src mem) mem)
+(Move [2] dst src mem) => (MOVWstore dst (MOVWload src mem) mem)
+(Move [4] dst src mem) => (MOVLstore dst (MOVLload src mem) mem)
+(Move [3] dst src mem) =>
+	(MOVBstore [2] dst (MOVBload [2] src mem)
+		(MOVWstore dst (MOVWload src mem) mem))
+(Move [5] dst src mem) =>
+	(MOVBstore [4] dst (MOVBload [4] src mem)
+		(MOVLstore dst (MOVLload src mem) mem))
+(Move [6] dst src mem) =>
+	(MOVWstore [4] dst (MOVWload [4] src mem)
+		(MOVLstore dst (MOVLload src mem) mem))
+(Move [7] dst src mem) =>
+	(MOVLstore [3] dst (MOVLload [3] src mem)
+		(MOVLstore dst (MOVLload src mem) mem))
+(Move [8] dst src mem) =>
+	(MOVLstore [4] dst (MOVLload [4] src mem)
+		(MOVLstore dst (MOVLload src mem) mem))
+
+// Adjust moves to be a multiple of 4 bytes.
+(Move [s] dst src mem)
+	&& s > 8 && s%4 != 0 =>
+	(Move [s-s%4]
+		(ADDLconst <dst.Type> dst [int32(s%4)])
+		(ADDLconst <src.Type> src [int32(s%4)])
+		(MOVLstore dst (MOVLload src mem) mem))
+
+// Medium copying uses a duff device.
+(Move [s] dst src mem)
+	&& s > 8 && s <= 4*128 && s%4 == 0
+	&& !config.noDuffDevice && logLargeCopy(v, s) =>
+	(DUFFCOPY [10*(128-s/4)] dst src mem)
+// 10 and 128 are magic constants.  10 is the number of bytes to encode:
+//	MOVL	(SI), CX
+//	ADDL	$4, SI
+//	MOVL	CX, (DI)
+//	ADDL	$4, DI
+// and 128 is the number of such blocks. See src/runtime/duff_386.s:duffcopy.
+
+// Large copying uses REP MOVSL.
+(Move [s] dst src mem) && (s > 4*128 || config.noDuffDevice) && s%4 == 0 && logLargeCopy(v, s) =>
+	(REPMOVSL dst src (MOVLconst [int32(s/4)]) mem)
+
+// Lowering Zero instructions
+(Zero [0] _ mem) => mem
+(Zero [1] destptr mem) => (MOVBstoreconst [0] destptr mem)
+(Zero [2] destptr mem) => (MOVWstoreconst [0] destptr mem)
+(Zero [4] destptr mem) => (MOVLstoreconst [0] destptr mem)
+
+(Zero [3] destptr mem) =>
+	(MOVBstoreconst [makeValAndOff(0,2)] destptr
+		(MOVWstoreconst [makeValAndOff(0,0)] destptr mem))
+(Zero [5] destptr mem) =>
+	(MOVBstoreconst [makeValAndOff(0,4)] destptr
+		(MOVLstoreconst [makeValAndOff(0,0)] destptr mem))
+(Zero [6] destptr mem) =>
+	(MOVWstoreconst [makeValAndOff(0,4)] destptr
+		(MOVLstoreconst [makeValAndOff(0,0)] destptr mem))
+(Zero [7] destptr mem) =>
+	(MOVLstoreconst [makeValAndOff(0,3)] destptr
+		(MOVLstoreconst [makeValAndOff(0,0)] destptr mem))
+
+// Strip off any fractional word zeroing.
+(Zero [s] destptr mem) && s%4 != 0 && s > 4 =>
+	(Zero [s-s%4] (ADDLconst destptr [int32(s%4)])
+		(MOVLstoreconst [0] destptr mem))
+
+// Zero small numbers of words directly.
+(Zero [8] destptr mem) =>
+	(MOVLstoreconst [makeValAndOff(0,4)] destptr
+		(MOVLstoreconst [makeValAndOff(0,0)] destptr mem))
+(Zero [12] destptr mem) =>
+	(MOVLstoreconst [makeValAndOff(0,8)] destptr
+		(MOVLstoreconst [makeValAndOff(0,4)] destptr
+			(MOVLstoreconst [makeValAndOff(0,0)] destptr mem)))
+(Zero [16] destptr mem) =>
+	(MOVLstoreconst [makeValAndOff(0,12)] destptr
+		(MOVLstoreconst [makeValAndOff(0,8)] destptr
+			(MOVLstoreconst [makeValAndOff(0,4)] destptr
+				(MOVLstoreconst [makeValAndOff(0,0)] destptr mem))))
+
+// Medium zeroing uses a duff device.
+(Zero [s] destptr mem)
+  && s > 16 && s <= 4*128 && s%4 == 0
+  && !config.noDuffDevice =>
+	(DUFFZERO [1*(128-s/4)] destptr (MOVLconst [0]) mem)
+// 1 and 128 are magic constants.  1 is the number of bytes to encode STOSL.
+// 128 is the number of STOSL instructions in duffzero.
+// See src/runtime/duff_386.s:duffzero.
+
+// Large zeroing uses REP STOSQ.
+(Zero [s] destptr mem)
+  && (s > 4*128 || (config.noDuffDevice && s > 16))
+  && s%4 == 0 =>
+	(REPSTOSL destptr (MOVLconst [int32(s/4)]) (MOVLconst [0]) mem)
+
+
+// Lowering constants
+(Const8   [c]) => (MOVLconst [int32(c)])
+(Const16  [c]) => (MOVLconst [int32(c)])
+(Const32  ...) => (MOVLconst ...)
+(Const(32|64)F ...) => (MOVS(S|D)const ...)
+(ConstNil) => (MOVLconst [0])
+(ConstBool [c]) => (MOVLconst [b2i32(c)])
+
+// Lowering calls
+(StaticCall ...) => (CALLstatic ...)
+(ClosureCall ...) => (CALLclosure ...)
+(InterCall ...) => (CALLinter ...)
+(TailCall ...) => (CALLtail ...)
+
+// Miscellaneous
+(IsNonNil p) => (SETNE (TESTL p p))
+(IsInBounds idx len) => (SETB (CMPL idx len))
+(IsSliceInBounds idx len) => (SETBE (CMPL idx len))
+(NilCheck ...) => (LoweredNilCheck ...)
+(GetG ...) => (LoweredGetG ...)
+(GetClosurePtr ...) => (LoweredGetClosurePtr ...)
+(GetCallerPC ...) => (LoweredGetCallerPC ...)
+(GetCallerSP ...) => (LoweredGetCallerSP ...)
+(Addr {sym} base) => (LEAL {sym} base)
+(LocalAddr {sym} base _) => (LEAL {sym} base)
+
+// block rewrites
+(If (SETL  cmp) yes no) => (LT  cmp yes no)
+(If (SETLE cmp) yes no) => (LE  cmp yes no)
+(If (SETG  cmp) yes no) => (GT  cmp yes no)
+(If (SETGE cmp) yes no) => (GE  cmp yes no)
+(If (SETEQ cmp) yes no) => (EQ  cmp yes no)
+(If (SETNE cmp) yes no) => (NE  cmp yes no)
+(If (SETB  cmp) yes no) => (ULT cmp yes no)
+(If (SETBE cmp) yes no) => (ULE cmp yes no)
+(If (SETA  cmp) yes no) => (UGT cmp yes no)
+(If (SETAE cmp) yes no) => (UGE cmp yes no)
+(If (SETO  cmp) yes no) => (OS cmp yes no)
+
+// Special case for floating point - LF/LEF not generated
+(If (SETGF  cmp) yes no) => (UGT  cmp yes no)
+(If (SETGEF cmp) yes no) => (UGE  cmp yes no)
+(If (SETEQF cmp) yes no) => (EQF  cmp yes no)
+(If (SETNEF cmp) yes no) => (NEF  cmp yes no)
+
+(If cond yes no) => (NE (TESTB cond cond) yes no)
+
+// Write barrier.
+(WB ...) => (LoweredWB ...)
+
+(PanicBounds [kind] x y mem) && boundsABI(kind) == 0 => (LoweredPanicBoundsA [kind] x y mem)
+(PanicBounds [kind] x y mem) && boundsABI(kind) == 1 => (LoweredPanicBoundsB [kind] x y mem)
+(PanicBounds [kind] x y mem) && boundsABI(kind) == 2 => (LoweredPanicBoundsC [kind] x y mem)
+
+(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 0 => (LoweredPanicExtendA [kind] hi lo y mem)
+(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 1 => (LoweredPanicExtendB [kind] hi lo y mem)
+(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 2 => (LoweredPanicExtendC [kind] hi lo y mem)
+
+// ***************************
+// Above: lowering rules
+// Below: optimizations
+// ***************************
+// TODO: Should the optimizations be a separate pass?
+
+// Fold boolean tests into blocks
+(NE (TESTB (SETL  cmp) (SETL  cmp)) yes no) => (LT  cmp yes no)
+(NE (TESTB (SETLE cmp) (SETLE cmp)) yes no) => (LE  cmp yes no)
+(NE (TESTB (SETG  cmp) (SETG  cmp)) yes no) => (GT  cmp yes no)
+(NE (TESTB (SETGE cmp) (SETGE cmp)) yes no) => (GE  cmp yes no)
+(NE (TESTB (SETEQ cmp) (SETEQ cmp)) yes no) => (EQ  cmp yes no)
+(NE (TESTB (SETNE cmp) (SETNE cmp)) yes no) => (NE  cmp yes no)
+(NE (TESTB (SETB  cmp) (SETB  cmp)) yes no) => (ULT cmp yes no)
+(NE (TESTB (SETBE cmp) (SETBE cmp)) yes no) => (ULE cmp yes no)
+(NE (TESTB (SETA  cmp) (SETA  cmp)) yes no) => (UGT cmp yes no)
+(NE (TESTB (SETAE cmp) (SETAE cmp)) yes no) => (UGE cmp yes no)
+(NE (TESTB (SETO cmp) (SETO cmp)) yes no) => (OS cmp yes no)
+
+// Special case for floating point - LF/LEF not generated
+(NE (TESTB (SETGF  cmp) (SETGF  cmp)) yes no) => (UGT  cmp yes no)
+(NE (TESTB (SETGEF cmp) (SETGEF cmp)) yes no) => (UGE  cmp yes no)
+(NE (TESTB (SETEQF cmp) (SETEQF cmp)) yes no) => (EQF  cmp yes no)
+(NE (TESTB (SETNEF cmp) (SETNEF cmp)) yes no) => (NEF  cmp yes no)
+
+// fold constants into instructions
+(ADDL x (MOVLconst [c])) => (ADDLconst [c] x)
+(ADDLcarry x (MOVLconst [c])) => (ADDLconstcarry [c] x)
+(ADCL x (MOVLconst [c]) f) => (ADCLconst [c] x f)
+
+(SUBL x (MOVLconst [c])) => (SUBLconst x [c])
+(SUBL (MOVLconst [c]) x) => (NEGL (SUBLconst <v.Type> x [c]))
+(SUBLcarry x (MOVLconst [c])) => (SUBLconstcarry [c] x)
+(SBBL x (MOVLconst [c]) f) => (SBBLconst [c] x f)
+
+(MULL x (MOVLconst [c])) => (MULLconst [c] x)
+(ANDL x (MOVLconst [c])) => (ANDLconst [c] x)
+
+(ANDLconst [c] (ANDLconst [d] x)) => (ANDLconst [c & d] x)
+(XORLconst [c] (XORLconst [d] x)) => (XORLconst [c ^ d] x)
+(MULLconst [c] (MULLconst [d] x)) => (MULLconst [c * d] x)
+
+(ORL x (MOVLconst [c])) => (ORLconst [c] x)
+(XORL x (MOVLconst [c])) => (XORLconst [c] x)
+
+(SHLL x (MOVLconst [c])) => (SHLLconst [c&31] x)
+(SHRL x (MOVLconst [c])) => (SHRLconst [c&31] x)
+(SHRW x (MOVLconst [c])) && c&31 < 16 => (SHRWconst [int16(c&31)] x)
+(SHRW _ (MOVLconst [c])) && c&31 >= 16 => (MOVLconst [0])
+(SHRB x (MOVLconst [c])) && c&31 < 8 => (SHRBconst [int8(c&31)] x)
+(SHRB _ (MOVLconst [c])) && c&31 >= 8 => (MOVLconst [0])
+
+(SARL x (MOVLconst [c])) => (SARLconst [c&31] x)
+(SARW x (MOVLconst [c])) => (SARWconst [int16(min(int64(c&31),15))] x)
+(SARB x (MOVLconst [c])) => (SARBconst [int8(min(int64(c&31),7))] x)
+
+(SARL x (ANDLconst [31] y)) => (SARL x y)
+(SHLL x (ANDLconst [31] y)) => (SHLL x y)
+(SHRL x (ANDLconst [31] y)) => (SHRL x y)
+
+// Constant shift simplifications
+
+(SHLLconst x [0]) => x
+(SHRLconst x [0]) => x
+(SARLconst x [0]) => x
+
+(SHRWconst x [0]) => x
+(SARWconst x [0]) => x
+
+(SHRBconst x [0]) => x
+(SARBconst x [0]) => x
+
+(ROLLconst [0] x) => x
+(ROLWconst [0] x) => x
+(ROLBconst [0] x) => x
+
+// Note: the word and byte shifts keep the low 5 bits (not the low 4 or 3 bits)
+// because the x86 instructions are defined to use all 5 bits of the shift even
+// for the small shifts. I don't think we'll ever generate a weird shift (e.g.
+// (SHRW x (MOVLconst [24])), but just in case.
+
+(CMPL x (MOVLconst [c])) => (CMPLconst x [c])
+(CMPL (MOVLconst [c]) x) => (InvertFlags (CMPLconst x [c]))
+(CMPW x (MOVLconst [c])) => (CMPWconst x [int16(c)])
+(CMPW (MOVLconst [c]) x) => (InvertFlags (CMPWconst x [int16(c)]))
+(CMPB x (MOVLconst [c])) => (CMPBconst x [int8(c)])
+(CMPB (MOVLconst [c]) x) => (InvertFlags (CMPBconst x [int8(c)]))
+
+// Canonicalize the order of arguments to comparisons - helps with CSE.
+(CMP(L|W|B) x y) && canonLessThan(x,y) => (InvertFlags (CMP(L|W|B) y x))
+
+// strength reduction
+// Assumes that the following costs from https://gmplib.org/~tege/x86-timing.pdf:
+//    1 - addl, shll, leal, negl, subl
+//    3 - imull
+// This limits the rewrites to two instructions.
+// Note that negl always operates in-place,
+// which can require a register-register move
+// to preserve the original value,
+// so it must be used with care.
+(MULLconst [-9] x) => (NEGL (LEAL8 <v.Type> x x))
+(MULLconst [-5] x) => (NEGL (LEAL4 <v.Type> x x))
+(MULLconst [-3] x) => (NEGL (LEAL2 <v.Type> x x))
+(MULLconst [-1] x) => (NEGL x)
+(MULLconst [0] _) => (MOVLconst [0])
+(MULLconst [1] x) => x
+(MULLconst [3] x) => (LEAL2 x x)
+(MULLconst [5] x) => (LEAL4 x x)
+(MULLconst [7] x) => (LEAL2 x (LEAL2 <v.Type> x x))
+(MULLconst [9] x) => (LEAL8 x x)
+(MULLconst [11] x) => (LEAL2 x (LEAL4 <v.Type> x x))
+(MULLconst [13] x) => (LEAL4 x (LEAL2 <v.Type> x x))
+(MULLconst [19] x) => (LEAL2 x (LEAL8 <v.Type> x x))
+(MULLconst [21] x) => (LEAL4 x (LEAL4 <v.Type> x x))
+(MULLconst [25] x) => (LEAL8 x (LEAL2 <v.Type> x x))
+(MULLconst [27] x) => (LEAL8 (LEAL2 <v.Type> x x) (LEAL2 <v.Type> x x))
+(MULLconst [37] x) => (LEAL4 x (LEAL8 <v.Type> x x))
+(MULLconst [41] x) => (LEAL8 x (LEAL4 <v.Type> x x))
+(MULLconst [45] x) => (LEAL8 (LEAL4 <v.Type> x x) (LEAL4 <v.Type> x x))
+(MULLconst [73] x) => (LEAL8 x (LEAL8 <v.Type> x x))
+(MULLconst [81] x) => (LEAL8 (LEAL8 <v.Type> x x) (LEAL8 <v.Type> x x))
+
+(MULLconst [c] x) && isPowerOfTwo32(c+1) && c >= 15 => (SUBL (SHLLconst <v.Type> [int32(log32(c+1))] x) x)
+(MULLconst [c] x) && isPowerOfTwo32(c-1) && c >= 17 => (LEAL1 (SHLLconst <v.Type> [int32(log32(c-1))] x) x)
+(MULLconst [c] x) && isPowerOfTwo32(c-2) && c >= 34 => (LEAL2 (SHLLconst <v.Type> [int32(log32(c-2))] x) x)
+(MULLconst [c] x) && isPowerOfTwo32(c-4) && c >= 68 => (LEAL4 (SHLLconst <v.Type> [int32(log32(c-4))] x) x)
+(MULLconst [c] x) && isPowerOfTwo32(c-8) && c >= 136 => (LEAL8 (SHLLconst <v.Type> [int32(log32(c-8))] x) x)
+(MULLconst [c] x) && c%3 == 0 && isPowerOfTwo32(c/3) => (SHLLconst [int32(log32(c/3))] (LEAL2 <v.Type> x x))
+(MULLconst [c] x) && c%5 == 0 && isPowerOfTwo32(c/5) => (SHLLconst [int32(log32(c/5))] (LEAL4 <v.Type> x x))
+(MULLconst [c] x) && c%9 == 0 && isPowerOfTwo32(c/9) => (SHLLconst [int32(log32(c/9))] (LEAL8 <v.Type> x x))
+
+// combine add/shift into LEAL
+(ADDL x (SHLLconst [3] y)) => (LEAL8 x y)
+(ADDL x (SHLLconst [2] y)) => (LEAL4 x y)
+(ADDL x (SHLLconst [1] y)) => (LEAL2 x y)
+(ADDL x (ADDL y y)) => (LEAL2 x y)
+(ADDL x (ADDL x y)) => (LEAL2 y x)
+
+// combine ADDL/ADDLconst into LEAL1
+(ADDLconst [c] (ADDL x y)) => (LEAL1 [c] x y)
+(ADDL (ADDLconst [c] x) y) => (LEAL1 [c] x y)
+
+// fold ADDL into LEAL
+(ADDLconst [c] (LEAL [d] {s} x)) && is32Bit(int64(c)+int64(d)) => (LEAL [c+d] {s} x)
+(LEAL [c] {s} (ADDLconst [d] x)) && is32Bit(int64(c)+int64(d)) => (LEAL [c+d] {s} x)
+(ADDLconst [c] x:(SP)) => (LEAL [c] x) // so it is rematerializeable
+(LEAL [c] {s} (ADDL x y)) && x.Op != OpSB && y.Op != OpSB => (LEAL1 [c] {s} x y)
+(ADDL x (LEAL [c] {s} y)) && x.Op != OpSB && y.Op != OpSB => (LEAL1 [c] {s} x y)
+
+// fold ADDLconst into LEALx
+(ADDLconst [c] (LEAL1 [d] {s} x y)) && is32Bit(int64(c)+int64(d)) => (LEAL1 [c+d] {s} x y)
+(ADDLconst [c] (LEAL2 [d] {s} x y)) && is32Bit(int64(c)+int64(d)) => (LEAL2 [c+d] {s} x y)
+(ADDLconst [c] (LEAL4 [d] {s} x y)) && is32Bit(int64(c)+int64(d)) => (LEAL4 [c+d] {s} x y)
+(ADDLconst [c] (LEAL8 [d] {s} x y)) && is32Bit(int64(c)+int64(d)) => (LEAL8 [c+d] {s} x y)
+(LEAL1 [c] {s} (ADDLconst [d] x) y) && is32Bit(int64(c)+int64(d))   && x.Op != OpSB => (LEAL1 [c+d] {s} x y)
+(LEAL2 [c] {s} (ADDLconst [d] x) y) && is32Bit(int64(c)+int64(d))   && x.Op != OpSB => (LEAL2 [c+d] {s} x y)
+(LEAL2 [c] {s} x (ADDLconst [d] y)) && is32Bit(int64(c)+2*int64(d)) && y.Op != OpSB => (LEAL2 [c+2*d] {s} x y)
+(LEAL4 [c] {s} (ADDLconst [d] x) y) && is32Bit(int64(c)+int64(d))   && x.Op != OpSB => (LEAL4 [c+d] {s} x y)
+(LEAL4 [c] {s} x (ADDLconst [d] y)) && is32Bit(int64(c)+4*int64(d)) && y.Op != OpSB => (LEAL4 [c+4*d] {s} x y)
+(LEAL8 [c] {s} (ADDLconst [d] x) y) && is32Bit(int64(c)+int64(d))   && x.Op != OpSB => (LEAL8 [c+d] {s} x y)
+(LEAL8 [c] {s} x (ADDLconst [d] y)) && is32Bit(int64(c)+8*int64(d)) && y.Op != OpSB => (LEAL8 [c+8*d] {s} x y)
+
+// fold shifts into LEALx
+(LEAL1 [c] {s} x (SHLLconst [1] y)) => (LEAL2 [c] {s} x y)
+(LEAL1 [c] {s} x (SHLLconst [2] y)) => (LEAL4 [c] {s} x y)
+(LEAL1 [c] {s} x (SHLLconst [3] y)) => (LEAL8 [c] {s} x y)
+(LEAL2 [c] {s} x (SHLLconst [1] y)) => (LEAL4 [c] {s} x y)
+(LEAL2 [c] {s} x (SHLLconst [2] y)) => (LEAL8 [c] {s} x y)
+(LEAL4 [c] {s} x (SHLLconst [1] y)) => (LEAL8 [c] {s} x y)
+
+// reverse ordering of compare instruction
+(SETL (InvertFlags x)) => (SETG x)
+(SETG (InvertFlags x)) => (SETL x)
+(SETB (InvertFlags x)) => (SETA x)
+(SETA (InvertFlags x)) => (SETB x)
+(SETLE (InvertFlags x)) => (SETGE x)
+(SETGE (InvertFlags x)) => (SETLE x)
+(SETBE (InvertFlags x)) => (SETAE x)
+(SETAE (InvertFlags x)) => (SETBE x)
+(SETEQ (InvertFlags x)) => (SETEQ x)
+(SETNE (InvertFlags x)) => (SETNE x)
+
+// sign extended loads
+// Note: The combined instruction must end up in the same block
+// as the original load. If not, we end up making a value with
+// memory type live in two different blocks, which can lead to
+// multiple memory values alive simultaneously.
+// Make sure we don't combine these ops if the load has another use.
+// This prevents a single load from being split into multiple loads
+// which then might return different values.  See test/atomicload.go.
+(MOVBLSX x:(MOVBload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVBLSXload <v.Type> [off] {sym} ptr mem)
+(MOVBLZX x:(MOVBload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVBload <v.Type> [off] {sym} ptr mem)
+(MOVWLSX x:(MOVWload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVWLSXload <v.Type> [off] {sym} ptr mem)
+(MOVWLZX x:(MOVWload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVWload <v.Type> [off] {sym} ptr mem)
+
+// replace load from same location as preceding store with zero/sign extension (or copy in case of full width)
+(MOVBload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVBLZX x)
+(MOVWload [off] {sym} ptr (MOVWstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVWLZX x)
+(MOVLload [off] {sym} ptr (MOVLstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => x
+(MOVBLSXload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVBLSX x)
+(MOVWLSXload [off] {sym} ptr (MOVWstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVWLSX x)
+
+// Fold extensions and ANDs together.
+(MOVBLZX (ANDLconst [c] x)) => (ANDLconst [c & 0xff] x)
+(MOVWLZX (ANDLconst [c] x)) => (ANDLconst [c & 0xffff] x)
+(MOVBLSX (ANDLconst [c] x)) && c & 0x80 == 0 => (ANDLconst [c & 0x7f] x)
+(MOVWLSX (ANDLconst [c] x)) && c & 0x8000 == 0 => (ANDLconst [c & 0x7fff] x)
+
+// Don't extend before storing
+(MOVWstore [off] {sym} ptr (MOVWL(S|Z)X x) mem) => (MOVWstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr (MOVBL(S|Z)X x) mem) => (MOVBstore [off] {sym} ptr x mem)
+
+// fold constants into memory operations
+// Note that this is not always a good idea because if not all the uses of
+// the ADDLconst get eliminated, we still have to compute the ADDLconst and we now
+// have potentially two live values (ptr and (ADDLconst [off] ptr)) instead of one.
+// Nevertheless, let's do it!
+(MOV(L|W|B|SS|SD)load  [off1] {sym} (ADDLconst [off2] ptr) mem) && is32Bit(int64(off1)+int64(off2)) =>
+    (MOV(L|W|B|SS|SD)load  [off1+off2] {sym} ptr mem)
+(MOV(L|W|B|SS|SD)store  [off1] {sym} (ADDLconst [off2] ptr) val mem) && is32Bit(int64(off1)+int64(off2)) =>
+    (MOV(L|W|B|SS|SD)store  [off1+off2] {sym} ptr val mem)
+
+((ADD|SUB|MUL|AND|OR|XOR)Lload [off1] {sym} val (ADDLconst [off2] base) mem) && is32Bit(int64(off1)+int64(off2)) =>
+	((ADD|SUB|MUL|AND|OR|XOR)Lload [off1+off2] {sym} val base mem)
+((ADD|SUB|MUL|DIV)SSload [off1] {sym} val (ADDLconst [off2] base) mem) && is32Bit(int64(off1)+int64(off2)) =>
+	((ADD|SUB|MUL|DIV)SSload [off1+off2] {sym} val base mem)
+((ADD|SUB|MUL|DIV)SDload [off1] {sym} val (ADDLconst [off2] base) mem) && is32Bit(int64(off1)+int64(off2)) =>
+	((ADD|SUB|MUL|DIV)SDload [off1+off2] {sym} val base mem)
+((ADD|SUB|AND|OR|XOR)Lmodify [off1] {sym} (ADDLconst [off2] base) val mem) && is32Bit(int64(off1)+int64(off2)) =>
+	((ADD|SUB|AND|OR|XOR)Lmodify [off1+off2] {sym} base val mem)
+((ADD|AND|OR|XOR)Lconstmodify [valoff1] {sym} (ADDLconst [off2] base) mem) && valoff1.canAdd32(off2) =>
+	((ADD|AND|OR|XOR)Lconstmodify [valoff1.addOffset32(off2)] {sym} base mem)
+
+// Fold constants into stores.
+(MOVLstore [off] {sym} ptr (MOVLconst [c]) mem) =>
+	(MOVLstoreconst [makeValAndOff(c,off)] {sym} ptr mem)
+(MOVWstore [off] {sym} ptr (MOVLconst [c]) mem) =>
+	(MOVWstoreconst [makeValAndOff(c,off)] {sym} ptr mem)
+(MOVBstore [off] {sym} ptr (MOVLconst [c]) mem) =>
+	(MOVBstoreconst [makeValAndOff(c,off)] {sym} ptr mem)
+
+// Fold address offsets into constant stores.
+(MOV(L|W|B)storeconst [sc] {s} (ADDLconst [off] ptr) mem) && sc.canAdd32(off) =>
+	(MOV(L|W|B)storeconst [sc.addOffset32(off)] {s} ptr mem)
+
+// We need to fold LEAL into the MOVx ops so that the live variable analysis knows
+// what variables are being read/written by the ops.
+// Note: we turn off this merging for operations on globals when building
+// position-independent code (when Flag_shared is set).
+// PIC needs a spare register to load the PC into.  Having the LEAL be
+// a separate instruction gives us that register.  Having the LEAL be
+// a separate instruction also allows it to be CSEd (which is good because
+// it compiles to a thunk call).
+(MOV(L|W|B|SS|SD|BLSX|WLSX)load  [off1] {sym1} (LEAL [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)
+  && (base.Op != OpSB || !config.ctxt.Flag_shared) =>
+        (MOV(L|W|B|SS|SD|BLSX|WLSX)load  [off1+off2] {mergeSym(sym1,sym2)} base mem)
+
+(MOV(L|W|B|SS|SD)store  [off1] {sym1} (LEAL [off2] {sym2} base) val mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)
+  && (base.Op != OpSB || !config.ctxt.Flag_shared) =>
+	(MOV(L|W|B|SS|SD)store  [off1+off2] {mergeSym(sym1,sym2)} base val mem)
+
+(MOV(L|W|B)storeconst [sc] {sym1} (LEAL [off] {sym2} ptr) mem) && canMergeSym(sym1, sym2) && sc.canAdd32(off)
+  && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
+	(MOV(L|W|B)storeconst [sc.addOffset32(off)] {mergeSym(sym1, sym2)} ptr mem)
+
+((ADD|SUB|MUL|AND|OR|XOR)Lload [off1] {sym1} val (LEAL [off2] {sym2} base) mem)
+	&& is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) =>
+	((ADD|SUB|MUL|AND|OR|XOR)Lload [off1+off2] {mergeSym(sym1,sym2)} val base mem)
+((ADD|SUB|MUL|DIV)SSload [off1] {sym1} val (LEAL [off2] {sym2} base) mem)
+	&& is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) =>
+	((ADD|SUB|MUL|DIV)SSload [off1+off2] {mergeSym(sym1,sym2)} val base mem)
+((ADD|SUB|MUL|DIV)SDload [off1] {sym1} val (LEAL [off2] {sym2} base) mem)
+	&& is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) =>
+	((ADD|SUB|MUL|DIV)SDload [off1+off2] {mergeSym(sym1,sym2)} val base mem)
+((ADD|SUB|AND|OR|XOR)Lmodify [off1] {sym1} (LEAL [off2] {sym2} base) val mem)
+	&& is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) =>
+	((ADD|SUB|AND|OR|XOR)Lmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem)
+((ADD|AND|OR|XOR)Lconstmodify [valoff1] {sym1} (LEAL [off2] {sym2} base) mem)
+	&& valoff1.canAdd32(off2) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) =>
+	((ADD|AND|OR|XOR)Lconstmodify [valoff1.addOffset32(off2)] {mergeSym(sym1,sym2)} base mem)
+
+// Merge load/store to op
+((ADD|AND|OR|XOR|SUB|MUL)L x l:(MOVLload [off] {sym} ptr mem)) && canMergeLoadClobber(v, l, x) && clobber(l) => ((ADD|AND|OR|XOR|SUB|MUL)Lload x [off] {sym} ptr mem)
+((ADD|SUB|MUL|DIV)SD x l:(MOVSDload [off] {sym} ptr mem)) && canMergeLoadClobber(v, l, x) && clobber(l) => ((ADD|SUB|MUL|DIV)SDload x [off] {sym} ptr mem)
+((ADD|SUB|MUL|DIV)SS x l:(MOVSSload [off] {sym} ptr mem)) && canMergeLoadClobber(v, l, x) && clobber(l) => ((ADD|SUB|MUL|DIV)SSload x [off] {sym} ptr mem)
+(MOVLstore {sym} [off] ptr y:((ADD|AND|OR|XOR)Lload x [off] {sym} ptr mem) mem) && y.Uses==1 && clobber(y) => ((ADD|AND|OR|XOR)Lmodify [off] {sym} ptr x mem)
+(MOVLstore {sym} [off] ptr y:((ADD|SUB|AND|OR|XOR)L l:(MOVLload [off] {sym} ptr mem) x) mem) && y.Uses==1 && l.Uses==1 && clobber(y, l) =>
+	((ADD|SUB|AND|OR|XOR)Lmodify [off] {sym} ptr x mem)
+(MOVLstore {sym} [off] ptr y:((ADD|AND|OR|XOR)Lconst [c] l:(MOVLload [off] {sym} ptr mem)) mem)
+	&& y.Uses==1 && l.Uses==1 && clobber(y, l) =>
+	((ADD|AND|OR|XOR)Lconstmodify [makeValAndOff(c,off)] {sym} ptr mem)
+
+// fold LEALs together
+(LEAL [off1] {sym1} (LEAL [off2] {sym2} x)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+      (LEAL [off1+off2] {mergeSym(sym1,sym2)} x)
+
+// LEAL into LEAL1
+(LEAL1 [off1] {sym1} (LEAL [off2] {sym2} x) y) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB =>
+       (LEAL1 [off1+off2] {mergeSym(sym1,sym2)} x y)
+
+// LEAL1 into LEAL
+(LEAL [off1] {sym1} (LEAL1 [off2] {sym2} x y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+       (LEAL1 [off1+off2] {mergeSym(sym1,sym2)} x y)
+
+// LEAL into LEAL[248]
+(LEAL2 [off1] {sym1} (LEAL [off2] {sym2} x) y) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB =>
+       (LEAL2 [off1+off2] {mergeSym(sym1,sym2)} x y)
+(LEAL4 [off1] {sym1} (LEAL [off2] {sym2} x) y) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB =>
+       (LEAL4 [off1+off2] {mergeSym(sym1,sym2)} x y)
+(LEAL8 [off1] {sym1} (LEAL [off2] {sym2} x) y) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB =>
+       (LEAL8 [off1+off2] {mergeSym(sym1,sym2)} x y)
+
+// LEAL[248] into LEAL
+(LEAL [off1] {sym1} (LEAL2 [off2] {sym2} x y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+      (LEAL2 [off1+off2] {mergeSym(sym1,sym2)} x y)
+(LEAL [off1] {sym1} (LEAL4 [off2] {sym2} x y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+      (LEAL4 [off1+off2] {mergeSym(sym1,sym2)} x y)
+(LEAL [off1] {sym1} (LEAL8 [off2] {sym2} x y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+      (LEAL8 [off1+off2] {mergeSym(sym1,sym2)} x y)
+
+// LEAL[1248] into LEAL[1248]. Only some such merges are possible.
+(LEAL1 [off1] {sym1} x (LEAL1 [off2] {sym2} y y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+      (LEAL2 [off1+off2] {mergeSym(sym1, sym2)} x y)
+(LEAL1 [off1] {sym1} x (LEAL1 [off2] {sym2} x y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+      (LEAL2 [off1+off2] {mergeSym(sym1, sym2)} y x)
+(LEAL2 [off1] {sym} x (LEAL1 [off2] {nil} y y)) && is32Bit(int64(off1)+2*int64(off2)) =>
+      (LEAL4 [off1+2*off2] {sym} x y)
+(LEAL4 [off1] {sym} x (LEAL1 [off2] {nil} y y)) && is32Bit(int64(off1)+4*int64(off2)) =>
+      (LEAL8 [off1+4*off2] {sym} x y)
+
+// Absorb InvertFlags into branches.
+(LT (InvertFlags cmp) yes no) => (GT cmp yes no)
+(GT (InvertFlags cmp) yes no) => (LT cmp yes no)
+(LE (InvertFlags cmp) yes no) => (GE cmp yes no)
+(GE (InvertFlags cmp) yes no) => (LE cmp yes no)
+(ULT (InvertFlags cmp) yes no) => (UGT cmp yes no)
+(UGT (InvertFlags cmp) yes no) => (ULT cmp yes no)
+(ULE (InvertFlags cmp) yes no) => (UGE cmp yes no)
+(UGE (InvertFlags cmp) yes no) => (ULE cmp yes no)
+(EQ (InvertFlags cmp) yes no) => (EQ cmp yes no)
+(NE (InvertFlags cmp) yes no) => (NE cmp yes no)
+
+// Constant comparisons.
+(CMPLconst (MOVLconst [x]) [y]) && x==y                       => (FlagEQ)
+(CMPLconst (MOVLconst [x]) [y]) && x<y && uint32(x)<uint32(y) => (FlagLT_ULT)
+(CMPLconst (MOVLconst [x]) [y]) && x<y && uint32(x)>uint32(y) => (FlagLT_UGT)
+(CMPLconst (MOVLconst [x]) [y]) && x>y && uint32(x)<uint32(y) => (FlagGT_ULT)
+(CMPLconst (MOVLconst [x]) [y]) && x>y && uint32(x)>uint32(y) => (FlagGT_UGT)
+
+(CMPWconst (MOVLconst [x]) [y]) && int16(x)==y                       => (FlagEQ)
+(CMPWconst (MOVLconst [x]) [y]) && int16(x)<y && uint16(x)<uint16(y) => (FlagLT_ULT)
+(CMPWconst (MOVLconst [x]) [y]) && int16(x)<y && uint16(x)>uint16(y) => (FlagLT_UGT)
+(CMPWconst (MOVLconst [x]) [y]) && int16(x)>y && uint16(x)<uint16(y) => (FlagGT_ULT)
+(CMPWconst (MOVLconst [x]) [y]) && int16(x)>y && uint16(x)>uint16(y) => (FlagGT_UGT)
+
+(CMPBconst (MOVLconst [x]) [y]) && int8(x)==y                      => (FlagEQ)
+(CMPBconst (MOVLconst [x]) [y]) && int8(x)<y && uint8(x)<uint8(y) => (FlagLT_ULT)
+(CMPBconst (MOVLconst [x]) [y]) && int8(x)<y && uint8(x)>uint8(y) => (FlagLT_UGT)
+(CMPBconst (MOVLconst [x]) [y]) && int8(x)>y && uint8(x)<uint8(y) => (FlagGT_ULT)
+(CMPBconst (MOVLconst [x]) [y]) && int8(x)>y && uint8(x)>uint8(y) => (FlagGT_UGT)
+
+// Other known comparisons.
+(CMPLconst (SHRLconst _ [c]) [n]) && 0 <= n && 0 < c && c <= 32 && (1<<uint64(32-c)) <= uint64(n) => (FlagLT_ULT)
+(CMPLconst (ANDLconst _ [m]) [n]) && 0 <= m && m < n => (FlagLT_ULT)
+(CMPWconst (ANDLconst _ [m]) [n]) && 0 <= int16(m) && int16(m) < n => (FlagLT_ULT)
+(CMPBconst (ANDLconst _ [m]) [n]) && 0 <= int8(m) && int8(m) < n => (FlagLT_ULT)
+// TODO: DIVxU also.
+
+// Absorb flag constants into SBB ops.
+(SBBLcarrymask (FlagEQ)) => (MOVLconst [0])
+(SBBLcarrymask (FlagLT_ULT)) => (MOVLconst [-1])
+(SBBLcarrymask (FlagLT_UGT)) => (MOVLconst [0])
+(SBBLcarrymask (FlagGT_ULT)) => (MOVLconst [-1])
+(SBBLcarrymask (FlagGT_UGT)) => (MOVLconst [0])
+
+// Absorb flag constants into branches.
+(EQ (FlagEQ) yes no) => (First yes no)
+(EQ (FlagLT_ULT) yes no) => (First no yes)
+(EQ (FlagLT_UGT) yes no) => (First no yes)
+(EQ (FlagGT_ULT) yes no) => (First no yes)
+(EQ (FlagGT_UGT) yes no) => (First no yes)
+
+(NE (FlagEQ) yes no) => (First no yes)
+(NE (FlagLT_ULT) yes no) => (First yes no)
+(NE (FlagLT_UGT) yes no) => (First yes no)
+(NE (FlagGT_ULT) yes no) => (First yes no)
+(NE (FlagGT_UGT) yes no) => (First yes no)
+
+(LT (FlagEQ) yes no) => (First no yes)
+(LT (FlagLT_ULT) yes no) => (First yes no)
+(LT (FlagLT_UGT) yes no) => (First yes no)
+(LT (FlagGT_ULT) yes no) => (First no yes)
+(LT (FlagGT_UGT) yes no) => (First no yes)
+
+(LE (FlagEQ) yes no) => (First yes no)
+(LE (FlagLT_ULT) yes no) => (First yes no)
+(LE (FlagLT_UGT) yes no) => (First yes no)
+(LE (FlagGT_ULT) yes no) => (First no yes)
+(LE (FlagGT_UGT) yes no) => (First no yes)
+
+(GT (FlagEQ) yes no) => (First no yes)
+(GT (FlagLT_ULT) yes no) => (First no yes)
+(GT (FlagLT_UGT) yes no) => (First no yes)
+(GT (FlagGT_ULT) yes no) => (First yes no)
+(GT (FlagGT_UGT) yes no) => (First yes no)
+
+(GE (FlagEQ) yes no) => (First yes no)
+(GE (FlagLT_ULT) yes no) => (First no yes)
+(GE (FlagLT_UGT) yes no) => (First no yes)
+(GE (FlagGT_ULT) yes no) => (First yes no)
+(GE (FlagGT_UGT) yes no) => (First yes no)
+
+(ULT (FlagEQ) yes no) => (First no yes)
+(ULT (FlagLT_ULT) yes no) => (First yes no)
+(ULT (FlagLT_UGT) yes no) => (First no yes)
+(ULT (FlagGT_ULT) yes no) => (First yes no)
+(ULT (FlagGT_UGT) yes no) => (First no yes)
+
+(ULE (FlagEQ) yes no) => (First yes no)
+(ULE (FlagLT_ULT) yes no) => (First yes no)
+(ULE (FlagLT_UGT) yes no) => (First no yes)
+(ULE (FlagGT_ULT) yes no) => (First yes no)
+(ULE (FlagGT_UGT) yes no) => (First no yes)
+
+(UGT (FlagEQ) yes no) => (First no yes)
+(UGT (FlagLT_ULT) yes no) => (First no yes)
+(UGT (FlagLT_UGT) yes no) => (First yes no)
+(UGT (FlagGT_ULT) yes no) => (First no yes)
+(UGT (FlagGT_UGT) yes no) => (First yes no)
+
+(UGE (FlagEQ) yes no) => (First yes no)
+(UGE (FlagLT_ULT) yes no) => (First no yes)
+(UGE (FlagLT_UGT) yes no) => (First yes no)
+(UGE (FlagGT_ULT) yes no) => (First no yes)
+(UGE (FlagGT_UGT) yes no) => (First yes no)
+
+// Absorb flag constants into SETxx ops.
+(SETEQ (FlagEQ)) => (MOVLconst [1])
+(SETEQ (FlagLT_ULT)) => (MOVLconst [0])
+(SETEQ (FlagLT_UGT)) => (MOVLconst [0])
+(SETEQ (FlagGT_ULT)) => (MOVLconst [0])
+(SETEQ (FlagGT_UGT)) => (MOVLconst [0])
+
+(SETNE (FlagEQ)) => (MOVLconst [0])
+(SETNE (FlagLT_ULT)) => (MOVLconst [1])
+(SETNE (FlagLT_UGT)) => (MOVLconst [1])
+(SETNE (FlagGT_ULT)) => (MOVLconst [1])
+(SETNE (FlagGT_UGT)) => (MOVLconst [1])
+
+(SETL (FlagEQ)) => (MOVLconst [0])
+(SETL (FlagLT_ULT)) => (MOVLconst [1])
+(SETL (FlagLT_UGT)) => (MOVLconst [1])
+(SETL (FlagGT_ULT)) => (MOVLconst [0])
+(SETL (FlagGT_UGT)) => (MOVLconst [0])
+
+(SETLE (FlagEQ)) => (MOVLconst [1])
+(SETLE (FlagLT_ULT)) => (MOVLconst [1])
+(SETLE (FlagLT_UGT)) => (MOVLconst [1])
+(SETLE (FlagGT_ULT)) => (MOVLconst [0])
+(SETLE (FlagGT_UGT)) => (MOVLconst [0])
+
+(SETG (FlagEQ)) => (MOVLconst [0])
+(SETG (FlagLT_ULT)) => (MOVLconst [0])
+(SETG (FlagLT_UGT)) => (MOVLconst [0])
+(SETG (FlagGT_ULT)) => (MOVLconst [1])
+(SETG (FlagGT_UGT)) => (MOVLconst [1])
+
+(SETGE (FlagEQ)) => (MOVLconst [1])
+(SETGE (FlagLT_ULT)) => (MOVLconst [0])
+(SETGE (FlagLT_UGT)) => (MOVLconst [0])
+(SETGE (FlagGT_ULT)) => (MOVLconst [1])
+(SETGE (FlagGT_UGT)) => (MOVLconst [1])
+
+(SETB (FlagEQ)) => (MOVLconst [0])
+(SETB (FlagLT_ULT)) => (MOVLconst [1])
+(SETB (FlagLT_UGT)) => (MOVLconst [0])
+(SETB (FlagGT_ULT)) => (MOVLconst [1])
+(SETB (FlagGT_UGT)) => (MOVLconst [0])
+
+(SETBE (FlagEQ)) => (MOVLconst [1])
+(SETBE (FlagLT_ULT)) => (MOVLconst [1])
+(SETBE (FlagLT_UGT)) => (MOVLconst [0])
+(SETBE (FlagGT_ULT)) => (MOVLconst [1])
+(SETBE (FlagGT_UGT)) => (MOVLconst [0])
+
+(SETA (FlagEQ)) => (MOVLconst [0])
+(SETA (FlagLT_ULT)) => (MOVLconst [0])
+(SETA (FlagLT_UGT)) => (MOVLconst [1])
+(SETA (FlagGT_ULT)) => (MOVLconst [0])
+(SETA (FlagGT_UGT)) => (MOVLconst [1])
+
+(SETAE (FlagEQ)) => (MOVLconst [1])
+(SETAE (FlagLT_ULT)) => (MOVLconst [0])
+(SETAE (FlagLT_UGT)) => (MOVLconst [1])
+(SETAE (FlagGT_ULT)) => (MOVLconst [0])
+(SETAE (FlagGT_UGT)) => (MOVLconst [1])
+
+// Remove redundant *const ops
+(ADDLconst [c] x) && c==0  => x
+(SUBLconst [c] x) && c==0  => x
+(ANDLconst [c] _) && c==0  => (MOVLconst [0])
+(ANDLconst [c] x) && c==-1 => x
+(ORLconst [c] x)  && c==0  => x
+(ORLconst [c] _)  && c==-1 => (MOVLconst [-1])
+(XORLconst [c] x) && c==0  => x
+// TODO: since we got rid of the W/B versions, we might miss
+// things like (ANDLconst [0x100] x) which were formerly
+// (ANDBconst [0] x).  Probably doesn't happen very often.
+// If we cared, we might do:
+//  (ANDLconst <t> [c] x) && t.Size()==1 && int8(x)==0 => (MOVLconst [0])
+
+// Convert constant subtracts to constant adds
+(SUBLconst [c] x) => (ADDLconst [-c] x)
+
+// generic constant folding
+// TODO: more of this
+(ADDLconst [c] (MOVLconst [d])) => (MOVLconst [c+d])
+(ADDLconst [c] (ADDLconst [d] x)) => (ADDLconst [c+d] x)
+(SARLconst [c] (MOVLconst [d])) => (MOVLconst [d>>uint64(c)])
+(SARWconst [c] (MOVLconst [d])) => (MOVLconst [d>>uint64(c)])
+(SARBconst [c] (MOVLconst [d])) => (MOVLconst [d>>uint64(c)])
+(NEGL (MOVLconst [c])) => (MOVLconst [-c])
+(MULLconst [c] (MOVLconst [d])) => (MOVLconst [c*d])
+(ANDLconst [c] (MOVLconst [d])) => (MOVLconst [c&d])
+(ORLconst [c] (MOVLconst [d])) => (MOVLconst [c|d])
+(XORLconst [c] (MOVLconst [d])) => (MOVLconst [c^d])
+(NOTL (MOVLconst [c])) => (MOVLconst [^c])
+
+// generic simplifications
+// TODO: more of this
+(ADDL x (NEGL y)) => (SUBL x y)
+(SUBL x x) => (MOVLconst [0])
+(ANDL x x) => x
+(ORL x x) => x
+(XORL x x) => (MOVLconst [0])
+
+// checking AND against 0.
+(CMP(L|W|B)const l:(ANDL x y) [0]) && l.Uses==1 => (TEST(L|W|B) x y)
+(CMPLconst l:(ANDLconst [c] x) [0]) && l.Uses==1 => (TESTLconst [c] x)
+(CMPWconst l:(ANDLconst [c] x) [0]) && l.Uses==1 => (TESTWconst [int16(c)] x)
+(CMPBconst l:(ANDLconst [c] x) [0]) && l.Uses==1 => (TESTBconst [int8(c)] x)
+
+// TEST %reg,%reg is shorter than CMP
+(CMP(L|W|B)const x [0]) => (TEST(L|W|B) x x)
+
+// Convert LEAL1 back to ADDL if we can
+(LEAL1 [0] {nil} x y) => (ADDL x y)
+
+// Combining byte loads into larger (unaligned) loads.
+// There are many ways these combinations could occur.  This is
+// designed to match the way encoding/binary.LittleEndian does it.
+(ORL                  x0:(MOVBload [i0] {s} p mem)
+    s0:(SHLLconst [8] x1:(MOVBload [i1] {s} p mem)))
+  && i1 == i0+1
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && s0.Uses == 1
+  && mergePoint(b,x0,x1) != nil
+  && clobber(x0, x1, s0)
+  => @mergePoint(b,x0,x1) (MOVWload [i0] {s} p mem)
+
+(ORL                  x0:(MOVBload [i] {s} p0 mem)
+    s0:(SHLLconst [8] x1:(MOVBload [i] {s} p1 mem)))
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && s0.Uses == 1
+  && sequentialAddresses(p0, p1, 1)
+  && mergePoint(b,x0,x1) != nil
+  && clobber(x0, x1, s0)
+  => @mergePoint(b,x0,x1) (MOVWload [i] {s} p0 mem)
+
+(ORL o0:(ORL
+                       x0:(MOVWload [i0] {s} p mem)
+    s0:(SHLLconst [16] x1:(MOVBload [i2] {s} p mem)))
+    s1:(SHLLconst [24] x2:(MOVBload [i3] {s} p mem)))
+  && i2 == i0+2
+  && i3 == i0+3
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && x2.Uses == 1
+  && s0.Uses == 1
+  && s1.Uses == 1
+  && o0.Uses == 1
+  && mergePoint(b,x0,x1,x2) != nil
+  && clobber(x0, x1, x2, s0, s1, o0)
+  => @mergePoint(b,x0,x1,x2) (MOVLload [i0] {s} p mem)
+
+(ORL o0:(ORL
+                       x0:(MOVWload [i] {s} p0 mem)
+    s0:(SHLLconst [16] x1:(MOVBload [i] {s} p1 mem)))
+    s1:(SHLLconst [24] x2:(MOVBload [i] {s} p2 mem)))
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && x2.Uses == 1
+  && s0.Uses == 1
+  && s1.Uses == 1
+  && o0.Uses == 1
+  && sequentialAddresses(p0, p1, 2)
+  && sequentialAddresses(p1, p2, 1)
+  && mergePoint(b,x0,x1,x2) != nil
+  && clobber(x0, x1, x2, s0, s1, o0)
+  => @mergePoint(b,x0,x1,x2) (MOVLload [i] {s} p0 mem)
+
+// Combine constant stores into larger (unaligned) stores.
+(MOVBstoreconst [c] {s} p x:(MOVBstoreconst [a] {s} p mem))
+  && x.Uses == 1
+  && a.Off() + 1 == c.Off()
+  && clobber(x)
+  => (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p mem)
+(MOVBstoreconst [a] {s} p x:(MOVBstoreconst [c] {s} p mem))
+  && x.Uses == 1
+  && a.Off() + 1 == c.Off()
+  && clobber(x)
+  => (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p mem)
+
+(MOVBstoreconst [c] {s} p1 x:(MOVBstoreconst [a] {s} p0 mem))
+  && x.Uses == 1
+  && a.Off() == c.Off()
+  && sequentialAddresses(p0, p1, 1)
+  && clobber(x)
+  => (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p0 mem)
+(MOVBstoreconst [a] {s} p0 x:(MOVBstoreconst [c] {s} p1 mem))
+  && x.Uses == 1
+  && a.Off() == c.Off()
+  && sequentialAddresses(p0, p1, 1)
+  && clobber(x)
+  => (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p0 mem)
+
+(MOVWstoreconst [c] {s} p x:(MOVWstoreconst [a] {s} p mem))
+  && x.Uses == 1
+  && a.Off() + 2 == c.Off()
+  && clobber(x)
+  => (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p mem)
+(MOVWstoreconst [a] {s} p x:(MOVWstoreconst [c] {s} p mem))
+  && x.Uses == 1
+  && ValAndOff(a).Off() + 2 == ValAndOff(c).Off()
+  && clobber(x)
+  => (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p mem)
+
+(MOVWstoreconst [c] {s} p1 x:(MOVWstoreconst [a] {s} p0 mem))
+  && x.Uses == 1
+  && a.Off() == c.Off()
+  && sequentialAddresses(p0, p1, 2)
+  && clobber(x)
+  => (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p0 mem)
+(MOVWstoreconst [a] {s} p0 x:(MOVWstoreconst [c] {s} p1 mem))
+  && x.Uses == 1
+  && a.Off() == c.Off()
+  && sequentialAddresses(p0, p1, 2)
+  && clobber(x)
+  => (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p0 mem)
+
+// Combine stores into larger (unaligned) stores.
+(MOVBstore [i] {s} p (SHR(W|L)const [8] w) x:(MOVBstore [i-1] {s} p w mem))
+  && x.Uses == 1
+  && clobber(x)
+  => (MOVWstore [i-1] {s} p w mem)
+(MOVBstore [i] {s} p w x:(MOVBstore {s} [i+1] p (SHR(W|L)const [8] w) mem))
+  && x.Uses == 1
+  && clobber(x)
+  => (MOVWstore [i] {s} p w mem)
+(MOVBstore [i] {s} p (SHRLconst [j] w) x:(MOVBstore [i-1] {s} p w0:(SHRLconst [j-8] w) mem))
+  && x.Uses == 1
+  && clobber(x)
+  => (MOVWstore [i-1] {s} p w0 mem)
+
+(MOVBstore [i] {s} p1 (SHR(W|L)const [8] w) x:(MOVBstore [i] {s} p0 w mem))
+  && x.Uses == 1
+  && sequentialAddresses(p0, p1, 1)
+  && clobber(x)
+  => (MOVWstore [i] {s} p0 w mem)
+(MOVBstore [i] {s} p0 w x:(MOVBstore {s} [i] p1 (SHR(W|L)const [8] w) mem))
+  && x.Uses == 1
+  && sequentialAddresses(p0, p1, 1)
+  && clobber(x)
+  => (MOVWstore [i] {s} p0 w mem)
+(MOVBstore [i] {s} p1 (SHRLconst [j] w) x:(MOVBstore [i] {s} p0 w0:(SHRLconst [j-8] w) mem))
+  && x.Uses == 1
+  && sequentialAddresses(p0, p1, 1)
+  && clobber(x)
+  => (MOVWstore [i] {s} p0 w0 mem)
+
+(MOVWstore [i] {s} p (SHRLconst [16] w) x:(MOVWstore [i-2] {s} p w mem))
+  && x.Uses == 1
+  && clobber(x)
+  => (MOVLstore [i-2] {s} p w mem)
+(MOVWstore [i] {s} p (SHRLconst [j] w) x:(MOVWstore [i-2] {s} p w0:(SHRLconst [j-16] w) mem))
+  && x.Uses == 1
+  && clobber(x)
+  => (MOVLstore [i-2] {s} p w0 mem)
+
+(MOVWstore [i] {s} p1 (SHRLconst [16] w) x:(MOVWstore [i] {s} p0 w mem))
+  && x.Uses == 1
+  && sequentialAddresses(p0, p1, 2)
+  && clobber(x)
+  => (MOVLstore [i] {s} p0 w mem)
+(MOVWstore [i] {s} p1 (SHRLconst [j] w) x:(MOVWstore [i] {s} p0 w0:(SHRLconst [j-16] w) mem))
+  && x.Uses == 1
+  && sequentialAddresses(p0, p1, 2)
+  && clobber(x)
+  => (MOVLstore [i] {s} p0 w0 mem)
+
+// For PIC, break floating-point constant loading into two instructions so we have
+// a register to use for holding the address of the constant pool entry.
+(MOVSSconst [c]) && config.ctxt.Flag_shared => (MOVSSconst2 (MOVSSconst1 [c]))
+(MOVSDconst [c]) && config.ctxt.Flag_shared => (MOVSDconst2 (MOVSDconst1 [c]))
+
+(CMP(L|W|B) l:(MOV(L|W|B)load {sym} [off] ptr mem) x) && canMergeLoad(v, l) && clobber(l) => (CMP(L|W|B)load {sym} [off] ptr x mem)
+(CMP(L|W|B) x l:(MOV(L|W|B)load {sym} [off] ptr mem)) && canMergeLoad(v, l) && clobber(l) => (InvertFlags (CMP(L|W|B)load {sym} [off] ptr x mem))
+
+(CMP(L|W|B)const l:(MOV(L|W|B)load {sym} [off] ptr mem) [c])
+	&& l.Uses == 1
+	&& clobber(l) =>
+  @l.Block (CMP(L|W|B)constload {sym} [makeValAndOff(int32(c),off)] ptr mem)
+
+(CMPLload {sym} [off] ptr (MOVLconst [c]) mem) => (CMPLconstload {sym} [makeValAndOff(c,off)] ptr mem)
+(CMPWload {sym} [off] ptr (MOVLconst [c]) mem) => (CMPWconstload {sym} [makeValAndOff(int32(int16(c)),off)] ptr mem)
+(CMPBload {sym} [off] ptr (MOVLconst [c]) mem) => (CMPBconstload {sym} [makeValAndOff(int32(int8(c)),off)] ptr mem)
+
+(MOVBload [off] {sym} (SB) _) && symIsRO(sym) => (MOVLconst [int32(read8(sym, int64(off)))])
+(MOVWload [off] {sym} (SB) _) && symIsRO(sym) => (MOVLconst [int32(read16(sym, int64(off), config.ctxt.Arch.ByteOrder))])
+(MOVLload [off] {sym} (SB) _) && symIsRO(sym) => (MOVLconst [int32(read32(sym, int64(off), config.ctxt.Arch.ByteOrder))])
diff --git a/src/cmd/compile/internal/ssa/_gen/386Ops.go b/src/cmd/compile/internal/ssa/_gen/386Ops.go
new file mode 100644
index 0000000..c66650c
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/_gen/386Ops.go
@@ -0,0 +1,588 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "strings"
+
+// Notes:
+//  - Integer types live in the low portion of registers. Upper portions are junk.
+//  - Boolean types use the low-order byte of a register. 0=false, 1=true.
+//    Upper bytes are junk.
+//  - Floating-point types live in the low natural slot of an sse2 register.
+//    Unused portions are junk.
+//  - We do not use AH,BH,CH,DH registers.
+//  - When doing sub-register operations, we try to write the whole
+//    destination register to avoid a partial-register write.
+//  - Unused portions of AuxInt (or the Val portion of ValAndOff) are
+//    filled by sign-extending the used portion.  Users of AuxInt which interpret
+//    AuxInt as unsigned (e.g. shifts) must be careful.
+
+// Suffixes encode the bit width of various instructions.
+// L (long word) = 32 bit
+// W (word)      = 16 bit
+// B (byte)      = 8 bit
+
+// copied from ../../x86/reg.go
+var regNames386 = []string{
+	"AX",
+	"CX",
+	"DX",
+	"BX",
+	"SP",
+	"BP",
+	"SI",
+	"DI",
+	"X0",
+	"X1",
+	"X2",
+	"X3",
+	"X4",
+	"X5",
+	"X6",
+	"X7",
+
+	// If you add registers, update asyncPreempt in runtime
+
+	// pseudo-registers
+	"SB",
+}
+
+func init() {
+	// Make map from reg names to reg integers.
+	if len(regNames386) > 64 {
+		panic("too many registers")
+	}
+	num := map[string]int{}
+	for i, name := range regNames386 {
+		num[name] = i
+	}
+	buildReg := func(s string) regMask {
+		m := regMask(0)
+		for _, r := range strings.Split(s, " ") {
+			if n, ok := num[r]; ok {
+				m |= regMask(1) << uint(n)
+				continue
+			}
+			panic("register " + r + " not found")
+		}
+		return m
+	}
+
+	// Common individual register masks
+	var (
+		ax         = buildReg("AX")
+		cx         = buildReg("CX")
+		dx         = buildReg("DX")
+		bx         = buildReg("BX")
+		si         = buildReg("SI")
+		gp         = buildReg("AX CX DX BX BP SI DI")
+		fp         = buildReg("X0 X1 X2 X3 X4 X5 X6 X7")
+		gpsp       = gp | buildReg("SP")
+		gpspsb     = gpsp | buildReg("SB")
+		callerSave = gp | fp
+	)
+	// Common slices of register masks
+	var (
+		gponly = []regMask{gp}
+		fponly = []regMask{fp}
+	)
+
+	// Common regInfo
+	var (
+		gp01      = regInfo{inputs: nil, outputs: gponly}
+		gp11      = regInfo{inputs: []regMask{gp}, outputs: gponly}
+		gp11sp    = regInfo{inputs: []regMask{gpsp}, outputs: gponly}
+		gp11sb    = regInfo{inputs: []regMask{gpspsb}, outputs: gponly}
+		gp21      = regInfo{inputs: []regMask{gp, gp}, outputs: gponly}
+		gp11carry = regInfo{inputs: []regMask{gp}, outputs: []regMask{gp, 0}}
+		gp21carry = regInfo{inputs: []regMask{gp, gp}, outputs: []regMask{gp, 0}}
+		gp1carry1 = regInfo{inputs: []regMask{gp}, outputs: gponly}
+		gp2carry1 = regInfo{inputs: []regMask{gp, gp}, outputs: gponly}
+		gp21sp    = regInfo{inputs: []regMask{gpsp, gp}, outputs: gponly}
+		gp21sb    = regInfo{inputs: []regMask{gpspsb, gpsp}, outputs: gponly}
+		gp21shift = regInfo{inputs: []regMask{gp, cx}, outputs: []regMask{gp}}
+		gp11div   = regInfo{inputs: []regMask{ax, gpsp &^ dx}, outputs: []regMask{ax}, clobbers: dx}
+		gp21hmul  = regInfo{inputs: []regMask{ax, gpsp}, outputs: []regMask{dx}, clobbers: ax}
+		gp11mod   = regInfo{inputs: []regMask{ax, gpsp &^ dx}, outputs: []regMask{dx}, clobbers: ax}
+		gp21mul   = regInfo{inputs: []regMask{ax, gpsp}, outputs: []regMask{dx, ax}}
+
+		gp2flags     = regInfo{inputs: []regMask{gpsp, gpsp}}
+		gp1flags     = regInfo{inputs: []regMask{gpsp}}
+		gp0flagsLoad = regInfo{inputs: []regMask{gpspsb, 0}}
+		gp1flagsLoad = regInfo{inputs: []regMask{gpspsb, gpsp, 0}}
+		flagsgp      = regInfo{inputs: nil, outputs: gponly}
+
+		readflags = regInfo{inputs: nil, outputs: gponly}
+		flagsgpax = regInfo{inputs: nil, clobbers: ax, outputs: []regMask{gp &^ ax}}
+
+		gpload      = regInfo{inputs: []regMask{gpspsb, 0}, outputs: gponly}
+		gp21load    = regInfo{inputs: []regMask{gp, gpspsb, 0}, outputs: gponly}
+		gploadidx   = regInfo{inputs: []regMask{gpspsb, gpsp, 0}, outputs: gponly}
+		gp21loadidx = regInfo{inputs: []regMask{gp, gpspsb, gpsp, 0}, outputs: gponly}
+
+		gpstore         = regInfo{inputs: []regMask{gpspsb, gpsp, 0}}
+		gpstoreconst    = regInfo{inputs: []regMask{gpspsb, 0}}
+		gpstoreidx      = regInfo{inputs: []regMask{gpspsb, gpsp, gpsp, 0}}
+		gpstoreconstidx = regInfo{inputs: []regMask{gpspsb, gpsp, 0}}
+
+		fp01     = regInfo{inputs: nil, outputs: fponly}
+		fp21     = regInfo{inputs: []regMask{fp, fp}, outputs: fponly}
+		fp21load = regInfo{inputs: []regMask{fp, gpspsb, 0}, outputs: fponly}
+		fpgp     = regInfo{inputs: fponly, outputs: gponly}
+		gpfp     = regInfo{inputs: gponly, outputs: fponly}
+		fp11     = regInfo{inputs: fponly, outputs: fponly}
+		fp2flags = regInfo{inputs: []regMask{fp, fp}}
+
+		fpload    = regInfo{inputs: []regMask{gpspsb, 0}, outputs: fponly}
+		fploadidx = regInfo{inputs: []regMask{gpspsb, gpsp, 0}, outputs: fponly}
+
+		fpstore    = regInfo{inputs: []regMask{gpspsb, fp, 0}}
+		fpstoreidx = regInfo{inputs: []regMask{gpspsb, gpsp, fp, 0}}
+	)
+
+	var _386ops = []opData{
+		// fp ops
+		{name: "ADDSS", argLength: 2, reg: fp21, asm: "ADDSS", commutative: true, resultInArg0: true}, // fp32 add
+		{name: "ADDSD", argLength: 2, reg: fp21, asm: "ADDSD", commutative: true, resultInArg0: true}, // fp64 add
+		{name: "SUBSS", argLength: 2, reg: fp21, asm: "SUBSS", resultInArg0: true},                    // fp32 sub
+		{name: "SUBSD", argLength: 2, reg: fp21, asm: "SUBSD", resultInArg0: true},                    // fp64 sub
+		{name: "MULSS", argLength: 2, reg: fp21, asm: "MULSS", commutative: true, resultInArg0: true}, // fp32 mul
+		{name: "MULSD", argLength: 2, reg: fp21, asm: "MULSD", commutative: true, resultInArg0: true}, // fp64 mul
+		{name: "DIVSS", argLength: 2, reg: fp21, asm: "DIVSS", resultInArg0: true},                    // fp32 div
+		{name: "DIVSD", argLength: 2, reg: fp21, asm: "DIVSD", resultInArg0: true},                    // fp64 div
+
+		{name: "MOVSSload", argLength: 2, reg: fpload, asm: "MOVSS", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"}, // fp32 load
+		{name: "MOVSDload", argLength: 2, reg: fpload, asm: "MOVSD", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"}, // fp64 load
+		{name: "MOVSSconst", reg: fp01, asm: "MOVSS", aux: "Float32", rematerializeable: true},                               // fp32 constant
+		{name: "MOVSDconst", reg: fp01, asm: "MOVSD", aux: "Float64", rematerializeable: true},                               // fp64 constant
+		{name: "MOVSSloadidx1", argLength: 3, reg: fploadidx, asm: "MOVSS", aux: "SymOff", symEffect: "Read"},                // fp32 load indexed by i
+		{name: "MOVSSloadidx4", argLength: 3, reg: fploadidx, asm: "MOVSS", aux: "SymOff", symEffect: "Read"},                // fp32 load indexed by 4*i
+		{name: "MOVSDloadidx1", argLength: 3, reg: fploadidx, asm: "MOVSD", aux: "SymOff", symEffect: "Read"},                // fp64 load indexed by i
+		{name: "MOVSDloadidx8", argLength: 3, reg: fploadidx, asm: "MOVSD", aux: "SymOff", symEffect: "Read"},                // fp64 load indexed by 8*i
+
+		{name: "MOVSSstore", argLength: 3, reg: fpstore, asm: "MOVSS", aux: "SymOff", faultOnNilArg0: true, symEffect: "Write"}, // fp32 store
+		{name: "MOVSDstore", argLength: 3, reg: fpstore, asm: "MOVSD", aux: "SymOff", faultOnNilArg0: true, symEffect: "Write"}, // fp64 store
+		{name: "MOVSSstoreidx1", argLength: 4, reg: fpstoreidx, asm: "MOVSS", aux: "SymOff", symEffect: "Write"},                // fp32 indexed by i store
+		{name: "MOVSSstoreidx4", argLength: 4, reg: fpstoreidx, asm: "MOVSS", aux: "SymOff", symEffect: "Write"},                // fp32 indexed by 4i store
+		{name: "MOVSDstoreidx1", argLength: 4, reg: fpstoreidx, asm: "MOVSD", aux: "SymOff", symEffect: "Write"},                // fp64 indexed by i store
+		{name: "MOVSDstoreidx8", argLength: 4, reg: fpstoreidx, asm: "MOVSD", aux: "SymOff", symEffect: "Write"},                // fp64 indexed by 8i store
+
+		{name: "ADDSSload", argLength: 3, reg: fp21load, asm: "ADDSS", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"}, // fp32 arg0 + tmp, tmp loaded from arg1+auxint+aux, arg2 = mem
+		{name: "ADDSDload", argLength: 3, reg: fp21load, asm: "ADDSD", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"}, // fp64 arg0 + tmp, tmp loaded from arg1+auxint+aux, arg2 = mem
+		{name: "SUBSSload", argLength: 3, reg: fp21load, asm: "SUBSS", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"}, // fp32 arg0 - tmp, tmp loaded from arg1+auxint+aux, arg2 = mem
+		{name: "SUBSDload", argLength: 3, reg: fp21load, asm: "SUBSD", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"}, // fp64 arg0 - tmp, tmp loaded from arg1+auxint+aux, arg2 = mem
+		{name: "MULSSload", argLength: 3, reg: fp21load, asm: "MULSS", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"}, // fp32 arg0 * tmp, tmp loaded from arg1+auxint+aux, arg2 = mem
+		{name: "MULSDload", argLength: 3, reg: fp21load, asm: "MULSD", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"}, // fp64 arg0 * tmp, tmp loaded from arg1+auxint+aux, arg2 = mem
+		{name: "DIVSSload", argLength: 3, reg: fp21load, asm: "DIVSS", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"}, // fp32 arg0 / tmp, tmp loaded from arg1+auxint+aux, arg2 = mem
+		{name: "DIVSDload", argLength: 3, reg: fp21load, asm: "DIVSD", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"}, // fp64 arg0 / tmp, tmp loaded from arg1+auxint+aux, arg2 = mem
+
+		// binary ops
+		{name: "ADDL", argLength: 2, reg: gp21sp, asm: "ADDL", commutative: true, clobberFlags: true},                // arg0 + arg1
+		{name: "ADDLconst", argLength: 1, reg: gp11sp, asm: "ADDL", aux: "Int32", typ: "UInt32", clobberFlags: true}, // arg0 + auxint
+
+		{name: "ADDLcarry", argLength: 2, reg: gp21carry, asm: "ADDL", commutative: true, resultInArg0: true},                // arg0 + arg1, generates <carry,result> pair
+		{name: "ADDLconstcarry", argLength: 1, reg: gp11carry, asm: "ADDL", aux: "Int32", resultInArg0: true},                // arg0 + auxint, generates <carry,result> pair
+		{name: "ADCL", argLength: 3, reg: gp2carry1, asm: "ADCL", commutative: true, resultInArg0: true, clobberFlags: true}, // arg0+arg1+carry(arg2), where arg2 is flags
+		{name: "ADCLconst", argLength: 2, reg: gp1carry1, asm: "ADCL", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0+auxint+carry(arg1), where arg1 is flags
+
+		{name: "SUBL", argLength: 2, reg: gp21, asm: "SUBL", resultInArg0: true, clobberFlags: true},                    // arg0 - arg1
+		{name: "SUBLconst", argLength: 1, reg: gp11, asm: "SUBL", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 - auxint
+
+		{name: "SUBLcarry", argLength: 2, reg: gp21carry, asm: "SUBL", resultInArg0: true},                                   // arg0-arg1, generates <borrow,result> pair
+		{name: "SUBLconstcarry", argLength: 1, reg: gp11carry, asm: "SUBL", aux: "Int32", resultInArg0: true},                // arg0-auxint, generates <borrow,result> pair
+		{name: "SBBL", argLength: 3, reg: gp2carry1, asm: "SBBL", resultInArg0: true, clobberFlags: true},                    // arg0-arg1-borrow(arg2), where arg2 is flags
+		{name: "SBBLconst", argLength: 2, reg: gp1carry1, asm: "SBBL", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0-auxint-borrow(arg1), where arg1 is flags
+
+		{name: "MULL", argLength: 2, reg: gp21, asm: "IMULL", commutative: true, resultInArg0: true, clobberFlags: true}, // arg0 * arg1
+		{name: "MULLconst", argLength: 1, reg: gp11, asm: "IMUL3L", aux: "Int32", clobberFlags: true},                    // arg0 * auxint
+
+		{name: "MULLU", argLength: 2, reg: regInfo{inputs: []regMask{ax, gpsp}, outputs: []regMask{ax, 0}, clobbers: dx}, typ: "(UInt32,Flags)", asm: "MULL", commutative: true, clobberFlags: true}, // Let x = arg0*arg1 (full 32x32->64  unsigned multiply). Returns uint32(x), and flags set to overflow if uint32(x) != x.
+
+		{name: "HMULL", argLength: 2, reg: gp21hmul, commutative: true, asm: "IMULL", clobberFlags: true}, // (arg0 * arg1) >> width
+		{name: "HMULLU", argLength: 2, reg: gp21hmul, commutative: true, asm: "MULL", clobberFlags: true}, // (arg0 * arg1) >> width
+
+		{name: "MULLQU", argLength: 2, reg: gp21mul, commutative: true, asm: "MULL", clobberFlags: true}, // arg0 * arg1, high 32 in result[0], low 32 in result[1]
+
+		{name: "AVGLU", argLength: 2, reg: gp21, commutative: true, resultInArg0: true, clobberFlags: true}, // (arg0 + arg1) / 2 as unsigned, all 32 result bits
+
+		// For DIVL, DIVW, MODL and MODW, AuxInt non-zero means that the divisor has been proved to be not -1.
+		{name: "DIVL", argLength: 2, reg: gp11div, asm: "IDIVL", aux: "Bool", clobberFlags: true}, // arg0 / arg1
+		{name: "DIVW", argLength: 2, reg: gp11div, asm: "IDIVW", aux: "Bool", clobberFlags: true}, // arg0 / arg1
+		{name: "DIVLU", argLength: 2, reg: gp11div, asm: "DIVL", clobberFlags: true},              // arg0 / arg1
+		{name: "DIVWU", argLength: 2, reg: gp11div, asm: "DIVW", clobberFlags: true},              // arg0 / arg1
+
+		{name: "MODL", argLength: 2, reg: gp11mod, asm: "IDIVL", aux: "Bool", clobberFlags: true}, // arg0 % arg1
+		{name: "MODW", argLength: 2, reg: gp11mod, asm: "IDIVW", aux: "Bool", clobberFlags: true}, // arg0 % arg1
+		{name: "MODLU", argLength: 2, reg: gp11mod, asm: "DIVL", clobberFlags: true},              // arg0 % arg1
+		{name: "MODWU", argLength: 2, reg: gp11mod, asm: "DIVW", clobberFlags: true},              // arg0 % arg1
+
+		{name: "ANDL", argLength: 2, reg: gp21, asm: "ANDL", commutative: true, resultInArg0: true, clobberFlags: true}, // arg0 & arg1
+		{name: "ANDLconst", argLength: 1, reg: gp11, asm: "ANDL", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 & auxint
+
+		{name: "ORL", argLength: 2, reg: gp21, asm: "ORL", commutative: true, resultInArg0: true, clobberFlags: true}, // arg0 | arg1
+		{name: "ORLconst", argLength: 1, reg: gp11, asm: "ORL", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 | auxint
+
+		{name: "XORL", argLength: 2, reg: gp21, asm: "XORL", commutative: true, resultInArg0: true, clobberFlags: true}, // arg0 ^ arg1
+		{name: "XORLconst", argLength: 1, reg: gp11, asm: "XORL", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 ^ auxint
+
+		{name: "CMPL", argLength: 2, reg: gp2flags, asm: "CMPL", typ: "Flags"},                    // arg0 compare to arg1
+		{name: "CMPW", argLength: 2, reg: gp2flags, asm: "CMPW", typ: "Flags"},                    // arg0 compare to arg1
+		{name: "CMPB", argLength: 2, reg: gp2flags, asm: "CMPB", typ: "Flags"},                    // arg0 compare to arg1
+		{name: "CMPLconst", argLength: 1, reg: gp1flags, asm: "CMPL", typ: "Flags", aux: "Int32"}, // arg0 compare to auxint
+		{name: "CMPWconst", argLength: 1, reg: gp1flags, asm: "CMPW", typ: "Flags", aux: "Int16"}, // arg0 compare to auxint
+		{name: "CMPBconst", argLength: 1, reg: gp1flags, asm: "CMPB", typ: "Flags", aux: "Int8"},  // arg0 compare to auxint
+
+		// compare *(arg0+auxint+aux) to arg1 (in that order). arg2=mem.
+		{name: "CMPLload", argLength: 3, reg: gp1flagsLoad, asm: "CMPL", aux: "SymOff", typ: "Flags", symEffect: "Read", faultOnNilArg0: true},
+		{name: "CMPWload", argLength: 3, reg: gp1flagsLoad, asm: "CMPW", aux: "SymOff", typ: "Flags", symEffect: "Read", faultOnNilArg0: true},
+		{name: "CMPBload", argLength: 3, reg: gp1flagsLoad, asm: "CMPB", aux: "SymOff", typ: "Flags", symEffect: "Read", faultOnNilArg0: true},
+
+		// compare *(arg0+ValAndOff(AuxInt).Off()+aux) to ValAndOff(AuxInt).Val() (in that order). arg1=mem.
+		{name: "CMPLconstload", argLength: 2, reg: gp0flagsLoad, asm: "CMPL", aux: "SymValAndOff", typ: "Flags", symEffect: "Read", faultOnNilArg0: true},
+		{name: "CMPWconstload", argLength: 2, reg: gp0flagsLoad, asm: "CMPW", aux: "SymValAndOff", typ: "Flags", symEffect: "Read", faultOnNilArg0: true},
+		{name: "CMPBconstload", argLength: 2, reg: gp0flagsLoad, asm: "CMPB", aux: "SymValAndOff", typ: "Flags", symEffect: "Read", faultOnNilArg0: true},
+
+		{name: "UCOMISS", argLength: 2, reg: fp2flags, asm: "UCOMISS", typ: "Flags"}, // arg0 compare to arg1, f32
+		{name: "UCOMISD", argLength: 2, reg: fp2flags, asm: "UCOMISD", typ: "Flags"}, // arg0 compare to arg1, f64
+
+		{name: "TESTL", argLength: 2, reg: gp2flags, commutative: true, asm: "TESTL", typ: "Flags"}, // (arg0 & arg1) compare to 0
+		{name: "TESTW", argLength: 2, reg: gp2flags, commutative: true, asm: "TESTW", typ: "Flags"}, // (arg0 & arg1) compare to 0
+		{name: "TESTB", argLength: 2, reg: gp2flags, commutative: true, asm: "TESTB", typ: "Flags"}, // (arg0 & arg1) compare to 0
+		{name: "TESTLconst", argLength: 1, reg: gp1flags, asm: "TESTL", typ: "Flags", aux: "Int32"}, // (arg0 & auxint) compare to 0
+		{name: "TESTWconst", argLength: 1, reg: gp1flags, asm: "TESTW", typ: "Flags", aux: "Int16"}, // (arg0 & auxint) compare to 0
+		{name: "TESTBconst", argLength: 1, reg: gp1flags, asm: "TESTB", typ: "Flags", aux: "Int8"},  // (arg0 & auxint) compare to 0
+
+		{name: "SHLL", argLength: 2, reg: gp21shift, asm: "SHLL", resultInArg0: true, clobberFlags: true},               // arg0 << arg1, shift amount is mod 32
+		{name: "SHLLconst", argLength: 1, reg: gp11, asm: "SHLL", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 << auxint, shift amount 0-31
+		// Note: x86 is weird, the 16 and 8 byte shifts still use all 5 bits of shift amount!
+
+		{name: "SHRL", argLength: 2, reg: gp21shift, asm: "SHRL", resultInArg0: true, clobberFlags: true},               // unsigned arg0 >> arg1, shift amount is mod 32
+		{name: "SHRW", argLength: 2, reg: gp21shift, asm: "SHRW", resultInArg0: true, clobberFlags: true},               // unsigned arg0 >> arg1, shift amount is mod 32
+		{name: "SHRB", argLength: 2, reg: gp21shift, asm: "SHRB", resultInArg0: true, clobberFlags: true},               // unsigned arg0 >> arg1, shift amount is mod 32
+		{name: "SHRLconst", argLength: 1, reg: gp11, asm: "SHRL", aux: "Int32", resultInArg0: true, clobberFlags: true}, // unsigned arg0 >> auxint, shift amount 0-31
+		{name: "SHRWconst", argLength: 1, reg: gp11, asm: "SHRW", aux: "Int16", resultInArg0: true, clobberFlags: true}, // unsigned arg0 >> auxint, shift amount 0-15
+		{name: "SHRBconst", argLength: 1, reg: gp11, asm: "SHRB", aux: "Int8", resultInArg0: true, clobberFlags: true},  // unsigned arg0 >> auxint, shift amount 0-7
+
+		{name: "SARL", argLength: 2, reg: gp21shift, asm: "SARL", resultInArg0: true, clobberFlags: true},               // signed arg0 >> arg1, shift amount is mod 32
+		{name: "SARW", argLength: 2, reg: gp21shift, asm: "SARW", resultInArg0: true, clobberFlags: true},               // signed arg0 >> arg1, shift amount is mod 32
+		{name: "SARB", argLength: 2, reg: gp21shift, asm: "SARB", resultInArg0: true, clobberFlags: true},               // signed arg0 >> arg1, shift amount is mod 32
+		{name: "SARLconst", argLength: 1, reg: gp11, asm: "SARL", aux: "Int32", resultInArg0: true, clobberFlags: true}, // signed arg0 >> auxint, shift amount 0-31
+		{name: "SARWconst", argLength: 1, reg: gp11, asm: "SARW", aux: "Int16", resultInArg0: true, clobberFlags: true}, // signed arg0 >> auxint, shift amount 0-15
+		{name: "SARBconst", argLength: 1, reg: gp11, asm: "SARB", aux: "Int8", resultInArg0: true, clobberFlags: true},  // signed arg0 >> auxint, shift amount 0-7
+
+		{name: "ROLL", argLength: 2, reg: gp21shift, asm: "ROLL", resultInArg0: true, clobberFlags: true},               //     32 bits of arg0 rotate left by arg1
+		{name: "ROLW", argLength: 2, reg: gp21shift, asm: "ROLW", resultInArg0: true, clobberFlags: true},               // low 16 bits of arg0 rotate left by arg1
+		{name: "ROLB", argLength: 2, reg: gp21shift, asm: "ROLB", resultInArg0: true, clobberFlags: true},               // low  8 bits of arg0 rotate left by arg1
+		{name: "ROLLconst", argLength: 1, reg: gp11, asm: "ROLL", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 rotate left auxint, rotate amount 0-31
+		{name: "ROLWconst", argLength: 1, reg: gp11, asm: "ROLW", aux: "Int16", resultInArg0: true, clobberFlags: true}, // arg0 rotate left auxint, rotate amount 0-15
+		{name: "ROLBconst", argLength: 1, reg: gp11, asm: "ROLB", aux: "Int8", resultInArg0: true, clobberFlags: true},  // arg0 rotate left auxint, rotate amount 0-7
+
+		// binary-op with a memory source operand
+		{name: "ADDLload", argLength: 3, reg: gp21load, asm: "ADDL", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},  // arg0 + tmp, tmp loaded from  arg1+auxint+aux, arg2 = mem
+		{name: "SUBLload", argLength: 3, reg: gp21load, asm: "SUBL", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},  // arg0 - tmp, tmp loaded from  arg1+auxint+aux, arg2 = mem
+		{name: "MULLload", argLength: 3, reg: gp21load, asm: "IMULL", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"}, // arg0 * tmp, tmp loaded from  arg1+auxint+aux, arg2 = mem
+		{name: "ANDLload", argLength: 3, reg: gp21load, asm: "ANDL", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},  // arg0 & tmp, tmp loaded from  arg1+auxint+aux, arg2 = mem
+		{name: "ORLload", argLength: 3, reg: gp21load, asm: "ORL", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},    // arg0 | tmp, tmp loaded from  arg1+auxint+aux, arg2 = mem
+		{name: "XORLload", argLength: 3, reg: gp21load, asm: "XORL", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},  // arg0 ^ tmp, tmp loaded from  arg1+auxint+aux, arg2 = mem
+
+		// binary-op with an indexed memory source operand
+		{name: "ADDLloadidx4", argLength: 4, reg: gp21loadidx, asm: "ADDL", aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},  // arg0 + tmp, tmp loaded from  arg1+arg2*4+auxint+aux, arg3 = mem
+		{name: "SUBLloadidx4", argLength: 4, reg: gp21loadidx, asm: "SUBL", aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},  // arg0 - tmp, tmp loaded from  arg1+arg2*4+auxint+aux, arg3 = mem
+		{name: "MULLloadidx4", argLength: 4, reg: gp21loadidx, asm: "IMULL", aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"}, // arg0 * tmp, tmp loaded from  arg1+arg2*4+auxint+aux, arg3 = mem
+		{name: "ANDLloadidx4", argLength: 4, reg: gp21loadidx, asm: "ANDL", aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},  // arg0 & tmp, tmp loaded from  arg1+arg2*4+auxint+aux, arg3 = mem
+		{name: "ORLloadidx4", argLength: 4, reg: gp21loadidx, asm: "ORL", aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},    // arg0 | tmp, tmp loaded from  arg1+arg2*4+auxint+aux, arg3 = mem
+		{name: "XORLloadidx4", argLength: 4, reg: gp21loadidx, asm: "XORL", aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},  // arg0 ^ tmp, tmp loaded from  arg1+arg2*4+auxint+aux, arg3 = mem
+
+		// unary ops
+		{name: "NEGL", argLength: 1, reg: gp11, asm: "NEGL", resultInArg0: true, clobberFlags: true}, // -arg0
+
+		{name: "NOTL", argLength: 1, reg: gp11, asm: "NOTL", resultInArg0: true}, // ^arg0
+
+		{name: "BSFL", argLength: 1, reg: gp11, asm: "BSFL", clobberFlags: true}, // arg0 # of low-order zeroes ; undef if zero
+		{name: "BSFW", argLength: 1, reg: gp11, asm: "BSFW", clobberFlags: true}, // arg0 # of low-order zeroes ; undef if zero
+
+		{name: "BSRL", argLength: 1, reg: gp11, asm: "BSRL", clobberFlags: true}, // arg0 # of high-order zeroes ; undef if zero
+		{name: "BSRW", argLength: 1, reg: gp11, asm: "BSRW", clobberFlags: true}, // arg0 # of high-order zeroes ; undef if zero
+
+		{name: "BSWAPL", argLength: 1, reg: gp11, asm: "BSWAPL", resultInArg0: true}, // arg0 swap bytes
+
+		{name: "SQRTSD", argLength: 1, reg: fp11, asm: "SQRTSD"}, // sqrt(arg0)
+		{name: "SQRTSS", argLength: 1, reg: fp11, asm: "SQRTSS"}, // sqrt(arg0), float32
+
+		{name: "SBBLcarrymask", argLength: 1, reg: flagsgp, asm: "SBBL"}, // (int32)(-1) if carry is set, 0 if carry is clear.
+		// Note: SBBW and SBBB are subsumed by SBBL
+
+		{name: "SETEQ", argLength: 1, reg: readflags, asm: "SETEQ"}, // extract == condition from arg0
+		{name: "SETNE", argLength: 1, reg: readflags, asm: "SETNE"}, // extract != condition from arg0
+		{name: "SETL", argLength: 1, reg: readflags, asm: "SETLT"},  // extract signed < condition from arg0
+		{name: "SETLE", argLength: 1, reg: readflags, asm: "SETLE"}, // extract signed <= condition from arg0
+		{name: "SETG", argLength: 1, reg: readflags, asm: "SETGT"},  // extract signed > condition from arg0
+		{name: "SETGE", argLength: 1, reg: readflags, asm: "SETGE"}, // extract signed >= condition from arg0
+		{name: "SETB", argLength: 1, reg: readflags, asm: "SETCS"},  // extract unsigned < condition from arg0
+		{name: "SETBE", argLength: 1, reg: readflags, asm: "SETLS"}, // extract unsigned <= condition from arg0
+		{name: "SETA", argLength: 1, reg: readflags, asm: "SETHI"},  // extract unsigned > condition from arg0
+		{name: "SETAE", argLength: 1, reg: readflags, asm: "SETCC"}, // extract unsigned >= condition from arg0
+		{name: "SETO", argLength: 1, reg: readflags, asm: "SETOS"},  // extract if overflow flag is set from arg0
+		// Need different opcodes for floating point conditions because
+		// any comparison involving a NaN is always FALSE and thus
+		// the patterns for inverting conditions cannot be used.
+		{name: "SETEQF", argLength: 1, reg: flagsgpax, asm: "SETEQ", clobberFlags: true}, // extract == condition from arg0
+		{name: "SETNEF", argLength: 1, reg: flagsgpax, asm: "SETNE", clobberFlags: true}, // extract != condition from arg0
+		{name: "SETORD", argLength: 1, reg: flagsgp, asm: "SETPC"},                       // extract "ordered" (No Nan present) condition from arg0
+		{name: "SETNAN", argLength: 1, reg: flagsgp, asm: "SETPS"},                       // extract "unordered" (Nan present) condition from arg0
+
+		{name: "SETGF", argLength: 1, reg: flagsgp, asm: "SETHI"},  // extract floating > condition from arg0
+		{name: "SETGEF", argLength: 1, reg: flagsgp, asm: "SETCC"}, // extract floating >= condition from arg0
+
+		{name: "MOVBLSX", argLength: 1, reg: gp11, asm: "MOVBLSX"}, // sign extend arg0 from int8 to int32
+		{name: "MOVBLZX", argLength: 1, reg: gp11, asm: "MOVBLZX"}, // zero extend arg0 from int8 to int32
+		{name: "MOVWLSX", argLength: 1, reg: gp11, asm: "MOVWLSX"}, // sign extend arg0 from int16 to int32
+		{name: "MOVWLZX", argLength: 1, reg: gp11, asm: "MOVWLZX"}, // zero extend arg0 from int16 to int32
+
+		{name: "MOVLconst", reg: gp01, asm: "MOVL", typ: "UInt32", aux: "Int32", rematerializeable: true}, // 32 low bits of auxint
+
+		{name: "CVTTSD2SL", argLength: 1, reg: fpgp, asm: "CVTTSD2SL"}, // convert float64 to int32
+		{name: "CVTTSS2SL", argLength: 1, reg: fpgp, asm: "CVTTSS2SL"}, // convert float32 to int32
+		{name: "CVTSL2SS", argLength: 1, reg: gpfp, asm: "CVTSL2SS"},   // convert int32 to float32
+		{name: "CVTSL2SD", argLength: 1, reg: gpfp, asm: "CVTSL2SD"},   // convert int32 to float64
+		{name: "CVTSD2SS", argLength: 1, reg: fp11, asm: "CVTSD2SS"},   // convert float64 to float32
+		{name: "CVTSS2SD", argLength: 1, reg: fp11, asm: "CVTSS2SD"},   // convert float32 to float64
+
+		{name: "PXOR", argLength: 2, reg: fp21, asm: "PXOR", commutative: true, resultInArg0: true}, // exclusive or, applied to X regs for float negation.
+
+		{name: "LEAL", argLength: 1, reg: gp11sb, aux: "SymOff", rematerializeable: true, symEffect: "Addr"}, // arg0 + auxint + offset encoded in aux
+		{name: "LEAL1", argLength: 2, reg: gp21sb, commutative: true, aux: "SymOff", symEffect: "Addr"},      // arg0 + arg1 + auxint + aux
+		{name: "LEAL2", argLength: 2, reg: gp21sb, aux: "SymOff", symEffect: "Addr"},                         // arg0 + 2*arg1 + auxint + aux
+		{name: "LEAL4", argLength: 2, reg: gp21sb, aux: "SymOff", symEffect: "Addr"},                         // arg0 + 4*arg1 + auxint + aux
+		{name: "LEAL8", argLength: 2, reg: gp21sb, aux: "SymOff", symEffect: "Addr"},                         // arg0 + 8*arg1 + auxint + aux
+		// Note: LEAL{1,2,4,8} must not have OpSB as either argument.
+
+		// auxint+aux == add auxint and the offset of the symbol in aux (if any) to the effective address
+		{name: "MOVBload", argLength: 2, reg: gpload, asm: "MOVBLZX", aux: "SymOff", typ: "UInt8", faultOnNilArg0: true, symEffect: "Read"},  // load byte from arg0+auxint+aux. arg1=mem.  Zero extend.
+		{name: "MOVBLSXload", argLength: 2, reg: gpload, asm: "MOVBLSX", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},             // ditto, sign extend to int32
+		{name: "MOVWload", argLength: 2, reg: gpload, asm: "MOVWLZX", aux: "SymOff", typ: "UInt16", faultOnNilArg0: true, symEffect: "Read"}, // load 2 bytes from arg0+auxint+aux. arg1=mem.  Zero extend.
+		{name: "MOVWLSXload", argLength: 2, reg: gpload, asm: "MOVWLSX", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},             // ditto, sign extend to int32
+		{name: "MOVLload", argLength: 2, reg: gpload, asm: "MOVL", aux: "SymOff", typ: "UInt32", faultOnNilArg0: true, symEffect: "Read"},    // load 4 bytes from arg0+auxint+aux. arg1=mem.  Zero extend.
+		{name: "MOVBstore", argLength: 3, reg: gpstore, asm: "MOVB", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},    // store byte in arg1 to arg0+auxint+aux. arg2=mem
+		{name: "MOVWstore", argLength: 3, reg: gpstore, asm: "MOVW", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},    // store 2 bytes in arg1 to arg0+auxint+aux. arg2=mem
+		{name: "MOVLstore", argLength: 3, reg: gpstore, asm: "MOVL", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},    // store 4 bytes in arg1 to arg0+auxint+aux. arg2=mem
+
+		// direct binary-op on memory (read-modify-write)
+		{name: "ADDLmodify", argLength: 3, reg: gpstore, asm: "ADDL", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+auxint+aux) += arg1, arg2=mem
+		{name: "SUBLmodify", argLength: 3, reg: gpstore, asm: "SUBL", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+auxint+aux) -= arg1, arg2=mem
+		{name: "ANDLmodify", argLength: 3, reg: gpstore, asm: "ANDL", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+auxint+aux) &= arg1, arg2=mem
+		{name: "ORLmodify", argLength: 3, reg: gpstore, asm: "ORL", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, clobberFlags: true, symEffect: "Read,Write"},   // *(arg0+auxint+aux) |= arg1, arg2=mem
+		{name: "XORLmodify", argLength: 3, reg: gpstore, asm: "XORL", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+auxint+aux) ^= arg1, arg2=mem
+
+		// direct binary-op on indexed memory (read-modify-write)
+		{name: "ADDLmodifyidx4", argLength: 4, reg: gpstoreidx, asm: "ADDL", aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+arg1*4+auxint+aux) += arg2, arg3=mem
+		{name: "SUBLmodifyidx4", argLength: 4, reg: gpstoreidx, asm: "SUBL", aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+arg1*4+auxint+aux) -= arg2, arg3=mem
+		{name: "ANDLmodifyidx4", argLength: 4, reg: gpstoreidx, asm: "ANDL", aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+arg1*4+auxint+aux) &= arg2, arg3=mem
+		{name: "ORLmodifyidx4", argLength: 4, reg: gpstoreidx, asm: "ORL", aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},   // *(arg0+arg1*4+auxint+aux) |= arg2, arg3=mem
+		{name: "XORLmodifyidx4", argLength: 4, reg: gpstoreidx, asm: "XORL", aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+arg1*4+auxint+aux) ^= arg2, arg3=mem
+
+		// direct binary-op on memory with a constant (read-modify-write)
+		{name: "ADDLconstmodify", argLength: 2, reg: gpstoreconst, asm: "ADDL", aux: "SymValAndOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"}, // add ValAndOff(AuxInt).Val() to arg0+ValAndOff(AuxInt).Off()+aux, arg1=mem
+		{name: "ANDLconstmodify", argLength: 2, reg: gpstoreconst, asm: "ANDL", aux: "SymValAndOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"}, // and ValAndOff(AuxInt).Val() to arg0+ValAndOff(AuxInt).Off()+aux, arg1=mem
+		{name: "ORLconstmodify", argLength: 2, reg: gpstoreconst, asm: "ORL", aux: "SymValAndOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"},   // or  ValAndOff(AuxInt).Val() to arg0+ValAndOff(AuxInt).Off()+aux, arg1=mem
+		{name: "XORLconstmodify", argLength: 2, reg: gpstoreconst, asm: "XORL", aux: "SymValAndOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"}, // xor ValAndOff(AuxInt).Val() to arg0+ValAndOff(AuxInt).Off()+aux, arg1=mem
+
+		// direct binary-op on indexed memory with a constant (read-modify-write)
+		{name: "ADDLconstmodifyidx4", argLength: 3, reg: gpstoreconstidx, asm: "ADDL", aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // add ValAndOff(AuxInt).Val() to arg0+arg1*4+ValAndOff(AuxInt).Off()+aux, arg2=mem
+		{name: "ANDLconstmodifyidx4", argLength: 3, reg: gpstoreconstidx, asm: "ANDL", aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // and ValAndOff(AuxInt).Val() to arg0+arg1*4+ValAndOff(AuxInt).Off()+aux, arg2=mem
+		{name: "ORLconstmodifyidx4", argLength: 3, reg: gpstoreconstidx, asm: "ORL", aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},   // or  ValAndOff(AuxInt).Val() to arg0+arg1*4+ValAndOff(AuxInt).Off()+aux, arg2=mem
+		{name: "XORLconstmodifyidx4", argLength: 3, reg: gpstoreconstidx, asm: "XORL", aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // xor ValAndOff(AuxInt).Val() to arg0+arg1*4+ValAndOff(AuxInt).Off()+aux, arg2=mem
+
+		// indexed loads/stores
+		{name: "MOVBloadidx1", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVBLZX", aux: "SymOff", symEffect: "Read"}, // load a byte from arg0+arg1+auxint+aux. arg2=mem
+		{name: "MOVWloadidx1", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVWLZX", aux: "SymOff", symEffect: "Read"}, // load 2 bytes from arg0+arg1+auxint+aux. arg2=mem
+		{name: "MOVWloadidx2", argLength: 3, reg: gploadidx, asm: "MOVWLZX", aux: "SymOff", symEffect: "Read"},                    // load 2 bytes from arg0+2*arg1+auxint+aux. arg2=mem
+		{name: "MOVLloadidx1", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVL", aux: "SymOff", symEffect: "Read"},    // load 4 bytes from arg0+arg1+auxint+aux. arg2=mem
+		{name: "MOVLloadidx4", argLength: 3, reg: gploadidx, asm: "MOVL", aux: "SymOff", symEffect: "Read"},                       // load 4 bytes from arg0+4*arg1+auxint+aux. arg2=mem
+		// TODO: sign-extending indexed loads
+		{name: "MOVBstoreidx1", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVB", aux: "SymOff", symEffect: "Write"}, // store byte in arg2 to arg0+arg1+auxint+aux. arg3=mem
+		{name: "MOVWstoreidx1", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVW", aux: "SymOff", symEffect: "Write"}, // store 2 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem
+		{name: "MOVWstoreidx2", argLength: 4, reg: gpstoreidx, asm: "MOVW", aux: "SymOff", symEffect: "Write"},                    // store 2 bytes in arg2 to arg0+2*arg1+auxint+aux. arg3=mem
+		{name: "MOVLstoreidx1", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVL", aux: "SymOff", symEffect: "Write"}, // store 4 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem
+		{name: "MOVLstoreidx4", argLength: 4, reg: gpstoreidx, asm: "MOVL", aux: "SymOff", symEffect: "Write"},                    // store 4 bytes in arg2 to arg0+4*arg1+auxint+aux. arg3=mem
+		// TODO: add size-mismatched indexed loads, like MOVBstoreidx4.
+
+		// For storeconst ops, the AuxInt field encodes both
+		// the value to store and an address offset of the store.
+		// Cast AuxInt to a ValAndOff to extract Val and Off fields.
+		{name: "MOVBstoreconst", argLength: 2, reg: gpstoreconst, asm: "MOVB", aux: "SymValAndOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store low byte of ValAndOff(AuxInt).Val() to arg0+ValAndOff(AuxInt).Off()+aux.  arg1=mem
+		{name: "MOVWstoreconst", argLength: 2, reg: gpstoreconst, asm: "MOVW", aux: "SymValAndOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store low 2 bytes of ...
+		{name: "MOVLstoreconst", argLength: 2, reg: gpstoreconst, asm: "MOVL", aux: "SymValAndOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store low 4 bytes of ...
+
+		{name: "MOVBstoreconstidx1", argLength: 3, reg: gpstoreconstidx, asm: "MOVB", aux: "SymValAndOff", typ: "Mem", symEffect: "Write"}, // store low byte of ValAndOff(AuxInt).Val() to arg0+1*arg1+ValAndOff(AuxInt).Off()+aux.  arg2=mem
+		{name: "MOVWstoreconstidx1", argLength: 3, reg: gpstoreconstidx, asm: "MOVW", aux: "SymValAndOff", typ: "Mem", symEffect: "Write"}, // store low 2 bytes of ... arg1 ...
+		{name: "MOVWstoreconstidx2", argLength: 3, reg: gpstoreconstidx, asm: "MOVW", aux: "SymValAndOff", typ: "Mem", symEffect: "Write"}, // store low 2 bytes of ... 2*arg1 ...
+		{name: "MOVLstoreconstidx1", argLength: 3, reg: gpstoreconstidx, asm: "MOVL", aux: "SymValAndOff", typ: "Mem", symEffect: "Write"}, // store low 4 bytes of ... arg1 ...
+		{name: "MOVLstoreconstidx4", argLength: 3, reg: gpstoreconstidx, asm: "MOVL", aux: "SymValAndOff", typ: "Mem", symEffect: "Write"}, // store low 4 bytes of ... 4*arg1 ...
+
+		// arg0 = pointer to start of memory to zero
+		// arg1 = value to store (will always be zero)
+		// arg2 = mem
+		// auxint = offset into duffzero code to start executing
+		// returns mem
+		{
+			name:      "DUFFZERO",
+			aux:       "Int64",
+			argLength: 3,
+			reg: regInfo{
+				inputs:   []regMask{buildReg("DI"), buildReg("AX")},
+				clobbers: buildReg("DI CX"),
+				// Note: CX is only clobbered when dynamic linking.
+			},
+			faultOnNilArg0: true,
+		},
+
+		// arg0 = address of memory to zero
+		// arg1 = # of 4-byte words to zero
+		// arg2 = value to store (will always be zero)
+		// arg3 = mem
+		// returns mem
+		{
+			name:      "REPSTOSL",
+			argLength: 4,
+			reg: regInfo{
+				inputs:   []regMask{buildReg("DI"), buildReg("CX"), buildReg("AX")},
+				clobbers: buildReg("DI CX"),
+			},
+			faultOnNilArg0: true,
+		},
+
+		{name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                                              // call static function aux.(*obj.LSym).  arg0=mem, auxint=argsize, returns mem
+		{name: "CALLtail", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true, tailCall: true},                                // tail call static function aux.(*obj.LSym).  arg0=mem, auxint=argsize, returns mem
+		{name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{gpsp, buildReg("DX"), 0}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call function via closure.  arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem
+		{name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                        // call fn by pointer.  arg0=codeptr, arg1=mem, auxint=argsize, returns mem
+
+		// arg0 = destination pointer
+		// arg1 = source pointer
+		// arg2 = mem
+		// auxint = offset from duffcopy symbol to call
+		// returns memory
+		{
+			name:      "DUFFCOPY",
+			aux:       "Int64",
+			argLength: 3,
+			reg: regInfo{
+				inputs:   []regMask{buildReg("DI"), buildReg("SI")},
+				clobbers: buildReg("DI SI CX"), // uses CX as a temporary
+			},
+			clobberFlags:   true,
+			faultOnNilArg0: true,
+			faultOnNilArg1: true,
+		},
+
+		// arg0 = destination pointer
+		// arg1 = source pointer
+		// arg2 = # of 8-byte words to copy
+		// arg3 = mem
+		// returns memory
+		{
+			name:      "REPMOVSL",
+			argLength: 4,
+			reg: regInfo{
+				inputs:   []regMask{buildReg("DI"), buildReg("SI"), buildReg("CX")},
+				clobbers: buildReg("DI SI CX"),
+			},
+			faultOnNilArg0: true,
+			faultOnNilArg1: true,
+		},
+
+		// (InvertFlags (CMPL a b)) == (CMPL b a)
+		// So if we want (SETL (CMPL a b)) but we can't do that because a is a constant,
+		// then we do (SETL (InvertFlags (CMPL b a))) instead.
+		// Rewrites will convert this to (SETG (CMPL b a)).
+		// InvertFlags is a pseudo-op which can't appear in assembly output.
+		{name: "InvertFlags", argLength: 1}, // reverse direction of arg0
+
+		// Pseudo-ops
+		{name: "LoweredGetG", argLength: 1, reg: gp01}, // arg0=mem
+		// Scheduler ensures LoweredGetClosurePtr occurs only in entry block,
+		// and sorts it to the very beginning of the block to prevent other
+		// use of DX (the closure pointer)
+		{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("DX")}}, zeroWidth: true},
+		// LoweredGetCallerPC evaluates to the PC to which its "caller" will return.
+		// I.e., if f calls g "calls" getcallerpc,
+		// the result should be the PC within f that g will return to.
+		// See runtime/stubs.go for a more detailed discussion.
+		{name: "LoweredGetCallerPC", reg: gp01, rematerializeable: true},
+		// LoweredGetCallerSP returns the SP of the caller of the current function.
+		{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
+		//arg0=ptr,arg1=mem, returns void.  Faults if ptr is nil.
+		{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpsp}}, clobberFlags: true, nilCheck: true, faultOnNilArg0: true},
+
+		// LoweredWB invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
+		// It saves all GP registers if necessary, but may clobber others.
+		{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("DI"), ax}, clobbers: callerSave &^ gp}, clobberFlags: true, aux: "Sym", symEffect: "None"},
+
+		// There are three of these functions so that they can have three different register inputs.
+		// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the
+		// default registers to match so we don't need to copy registers around unnecessarily.
+		{name: "LoweredPanicBoundsA", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{dx, bx}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
+		{name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{cx, dx}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
+		{name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{ax, cx}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
+		// Extend ops are the same as Bounds ops except the indexes are 64-bit.
+		{name: "LoweredPanicExtendA", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{si, dx, bx}}, typ: "Mem", call: true}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
+		{name: "LoweredPanicExtendB", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{si, cx, dx}}, typ: "Mem", call: true}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
+		{name: "LoweredPanicExtendC", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{si, ax, cx}}, typ: "Mem", call: true}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
+
+		// Constant flag values. For any comparison, there are 5 possible
+		// outcomes: the three from the signed total order (<,==,>) and the
+		// three from the unsigned total order. The == cases overlap.
+		// Note: there's a sixth "unordered" outcome for floating-point
+		// comparisons, but we don't use such a beast yet.
+		// These ops are for temporary use by rewrite rules. They
+		// cannot appear in the generated assembly.
+		{name: "FlagEQ"},     // equal
+		{name: "FlagLT_ULT"}, // signed < and unsigned <
+		{name: "FlagLT_UGT"}, // signed < and unsigned >
+		{name: "FlagGT_UGT"}, // signed > and unsigned <
+		{name: "FlagGT_ULT"}, // signed > and unsigned >
+
+		// Special ops for PIC floating-point constants.
+		// MOVSXconst1 loads the address of the constant-pool entry into a register.
+		// MOVSXconst2 loads the constant from that address.
+		// MOVSXconst1 returns a pointer, but we type it as uint32 because it can never point to the Go heap.
+		{name: "MOVSSconst1", reg: gp01, typ: "UInt32", aux: "Float32"},
+		{name: "MOVSDconst1", reg: gp01, typ: "UInt32", aux: "Float64"},
+		{name: "MOVSSconst2", argLength: 1, reg: gpfp, asm: "MOVSS"},
+		{name: "MOVSDconst2", argLength: 1, reg: gpfp, asm: "MOVSD"},
+	}
+
+	var _386blocks = []blockData{
+		{name: "EQ", controls: 1},
+		{name: "NE", controls: 1},
+		{name: "LT", controls: 1},
+		{name: "LE", controls: 1},
+		{name: "GT", controls: 1},
+		{name: "GE", controls: 1},
+		{name: "OS", controls: 1},
+		{name: "OC", controls: 1},
+		{name: "ULT", controls: 1},
+		{name: "ULE", controls: 1},
+		{name: "UGT", controls: 1},
+		{name: "UGE", controls: 1},
+		{name: "EQF", controls: 1},
+		{name: "NEF", controls: 1},
+		{name: "ORD", controls: 1}, // FP, ordered comparison (parity zero)
+		{name: "NAN", controls: 1}, // FP, unordered comparison (parity one)
+	}
+
+	archs = append(archs, arch{
+		name:            "386",
+		pkg:             "cmd/internal/obj/x86",
+		genfile:         "../../x86/ssa.go",
+		ops:             _386ops,
+		blocks:          _386blocks,
+		regnames:        regNames386,
+		gpregmask:       gp,
+		fpregmask:       fp,
+		framepointerreg: int8(num["BP"]),
+		linkreg:         -1, // not used
+	})
+}
diff --git a/src/cmd/compile/internal/ssa/gen/386splitload.rules b/src/cmd/compile/internal/ssa/_gen/386splitload.rules
similarity index 100%
rename from src/cmd/compile/internal/ssa/gen/386splitload.rules
rename to src/cmd/compile/internal/ssa/_gen/386splitload.rules
diff --git a/src/cmd/compile/internal/ssa/_gen/AMD64.rules b/src/cmd/compile/internal/ssa/_gen/AMD64.rules
new file mode 100644
index 0000000..ccb5295
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/_gen/AMD64.rules
@@ -0,0 +1,2216 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Lowering arithmetic
+(Add(64|32|16|8) ...) => (ADD(Q|L|L|L) ...)
+(AddPtr ...) => (ADDQ ...)
+(Add(32|64)F ...) => (ADDS(S|D) ...)
+
+(Sub(64|32|16|8) ...) => (SUB(Q|L|L|L) ...)
+(SubPtr ...) => (SUBQ ...)
+(Sub(32|64)F ...) => (SUBS(S|D) ...)
+
+(Mul(64|32|16|8) ...) => (MUL(Q|L|L|L) ...)
+(Mul(32|64)F ...) => (MULS(S|D) ...)
+
+(Select0 (Mul64uover x y)) => (Select0 <typ.UInt64> (MULQU x y))
+(Select0 (Mul32uover x y)) => (Select0 <typ.UInt32> (MULLU x y))
+(Select1 (Mul(64|32)uover x y)) => (SETO (Select1 <types.TypeFlags> (MUL(Q|L)U x y)))
+
+(Hmul(64|32) ...) => (HMUL(Q|L) ...)
+(Hmul(64|32)u ...) => (HMUL(Q|L)U ...)
+
+(Div(64|32|16) [a] x y) => (Select0 (DIV(Q|L|W) [a] x y))
+(Div8  x y) => (Select0 (DIVW  (SignExt8to16 x) (SignExt8to16 y)))
+(Div(64|32|16)u x y) => (Select0 (DIV(Q|L|W)U x y))
+(Div8u x y) => (Select0 (DIVWU (ZeroExt8to16 x) (ZeroExt8to16 y)))
+(Div(32|64)F ...) => (DIVS(S|D) ...)
+
+(Select0 (Add64carry x y c)) =>
+	(Select0 <typ.UInt64> (ADCQ x y (Select1 <types.TypeFlags> (NEGLflags c))))
+(Select1 (Add64carry x y c)) =>
+	(NEGQ <typ.UInt64> (SBBQcarrymask <typ.UInt64> (Select1 <types.TypeFlags> (ADCQ x y (Select1 <types.TypeFlags> (NEGLflags c))))))
+(Select0 (Sub64borrow x y c)) =>
+	(Select0 <typ.UInt64> (SBBQ x y (Select1 <types.TypeFlags> (NEGLflags c))))
+(Select1 (Sub64borrow x y c)) =>
+	(NEGQ <typ.UInt64> (SBBQcarrymask <typ.UInt64> (Select1 <types.TypeFlags> (SBBQ x y (Select1 <types.TypeFlags> (NEGLflags c))))))
+
+// Optimize ADCQ and friends
+(ADCQ x (MOVQconst [c]) carry) && is32Bit(c) => (ADCQconst x [int32(c)] carry)
+(ADCQ x y (FlagEQ)) => (ADDQcarry x y)
+(ADCQconst x [c] (FlagEQ)) => (ADDQconstcarry x [c])
+(ADDQcarry x (MOVQconst [c])) && is32Bit(c) => (ADDQconstcarry x [int32(c)])
+(SBBQ x (MOVQconst [c]) borrow) && is32Bit(c) => (SBBQconst x [int32(c)] borrow)
+(SBBQ x y (FlagEQ)) => (SUBQborrow x y)
+(SBBQconst x [c] (FlagEQ)) => (SUBQconstborrow x [c])
+(SUBQborrow x (MOVQconst [c])) && is32Bit(c) => (SUBQconstborrow x [int32(c)])
+(Select1 (NEGLflags (MOVQconst [0]))) => (FlagEQ)
+(Select1 (NEGLflags (NEGQ (SBBQcarrymask x)))) => x
+
+
+(Mul64uhilo ...) => (MULQU2 ...)
+(Div128u ...) => (DIVQU2 ...)
+
+(Avg64u ...) => (AVGQU ...)
+
+(Mod(64|32|16) [a] x y) => (Select1 (DIV(Q|L|W) [a] x y))
+(Mod8  x y) => (Select1 (DIVW  (SignExt8to16 x) (SignExt8to16 y)))
+(Mod(64|32|16)u x y) => (Select1 (DIV(Q|L|W)U x y))
+(Mod8u x y) => (Select1 (DIVWU (ZeroExt8to16 x) (ZeroExt8to16 y)))
+
+(And(64|32|16|8) ...) => (AND(Q|L|L|L) ...)
+(Or(64|32|16|8) ...) => (OR(Q|L|L|L) ...)
+(Xor(64|32|16|8) ...) => (XOR(Q|L|L|L) ...)
+(Com(64|32|16|8) ...) => (NOT(Q|L|L|L) ...)
+
+(Neg(64|32|16|8) ...) => (NEG(Q|L|L|L) ...)
+(Neg32F x) => (PXOR x (MOVSSconst <typ.Float32> [float32(math.Copysign(0, -1))]))
+(Neg64F x) => (PXOR x (MOVSDconst <typ.Float64> [math.Copysign(0, -1)]))
+
+// Lowering boolean ops
+(AndB ...) => (ANDL ...)
+(OrB ...) => (ORL ...)
+(Not x) => (XORLconst [1] x)
+
+// Lowering pointer arithmetic
+(OffPtr [off] ptr) && is32Bit(off) => (ADDQconst [int32(off)] ptr)
+(OffPtr [off] ptr) => (ADDQ (MOVQconst [off]) ptr)
+
+// Lowering other arithmetic
+(Ctz64 x)     && buildcfg.GOAMD64 >= 3 => (TZCNTQ x)
+(Ctz32 x)     && buildcfg.GOAMD64 >= 3 => (TZCNTL x)
+(Ctz64 <t> x) && buildcfg.GOAMD64 <  3 => (CMOVQEQ (Select0 <t> (BSFQ x)) (MOVQconst <t> [64]) (Select1 <types.TypeFlags> (BSFQ x)))
+(Ctz32 x)     && buildcfg.GOAMD64 <  3 => (Select0 (BSFQ (BTSQconst <typ.UInt64> [32] x)))
+(Ctz16 x) => (BSFL (BTSLconst <typ.UInt32> [16] x))
+(Ctz8  x) => (BSFL (BTSLconst <typ.UInt32> [ 8] x))
+
+(Ctz64NonZero x) && buildcfg.GOAMD64 >= 3 => (TZCNTQ x)
+(Ctz32NonZero x) && buildcfg.GOAMD64 >= 3 => (TZCNTL x)
+(Ctz16NonZero x) && buildcfg.GOAMD64 >= 3 => (TZCNTL x)
+(Ctz8NonZero  x) && buildcfg.GOAMD64 >= 3 => (TZCNTL x)
+(Ctz64NonZero x) && buildcfg.GOAMD64 <  3 => (Select0 (BSFQ x))
+(Ctz32NonZero x) && buildcfg.GOAMD64 <  3 => (BSFL x)
+(Ctz16NonZero x) && buildcfg.GOAMD64 <  3 => (BSFL x)
+(Ctz8NonZero  x) && buildcfg.GOAMD64 <  3 => (BSFL x)
+
+// BitLen64 of a 64 bit value x requires checking whether x == 0, since BSRQ is undefined when x == 0.
+// However, for zero-extended values, we can cheat a bit, and calculate
+// BSR(x<<1 + 1), which is guaranteed to be non-zero, and which conveniently
+// places the index of the highest set bit where we want it.
+// For GOAMD64>=3, BitLen can be calculated by OperandSize - LZCNT(x).
+(BitLen64 <t> x) && buildcfg.GOAMD64 < 3 => (ADDQconst [1] (CMOVQEQ <t> (Select0 <t> (BSRQ x)) (MOVQconst <t> [-1]) (Select1 <types.TypeFlags> (BSRQ x))))
+(BitLen32 x) && buildcfg.GOAMD64 <  3 => (Select0 (BSRQ (LEAQ1 <typ.UInt64> [1] (MOVLQZX <typ.UInt64> x) (MOVLQZX <typ.UInt64> x))))
+(BitLen16 x) && buildcfg.GOAMD64 <  3 => (BSRL (LEAL1 <typ.UInt32> [1] (MOVWQZX <typ.UInt32> x) (MOVWQZX <typ.UInt32> x)))
+(BitLen8  x) && buildcfg.GOAMD64 <  3 => (BSRL (LEAL1 <typ.UInt32> [1] (MOVBQZX <typ.UInt32> x) (MOVBQZX <typ.UInt32> x)))
+(BitLen64 <t> x)        && buildcfg.GOAMD64 >= 3 => (NEGQ (ADDQconst <t> [-64] (LZCNTQ x)))
+// Use 64-bit version to allow const-fold remove unnecessary arithmetic.
+(BitLen32 <t> x) && buildcfg.GOAMD64 >= 3 => (NEGQ (ADDQconst <t> [-32] (LZCNTL x)))
+(BitLen16 <t> x) && buildcfg.GOAMD64 >= 3 => (NEGQ (ADDQconst <t> [-32] (LZCNTL (MOVWQZX <x.Type> x))))
+(BitLen8 <t> x) && buildcfg.GOAMD64 >= 3 => (NEGQ (ADDQconst <t> [-32] (LZCNTL (MOVBQZX <x.Type> x))))
+
+(Bswap(64|32) ...) => (BSWAP(Q|L) ...)
+
+(PopCount(64|32) ...) => (POPCNT(Q|L) ...)
+(PopCount16 x) => (POPCNTL (MOVWQZX <typ.UInt32> x))
+(PopCount8 x) => (POPCNTL (MOVBQZX <typ.UInt32> x))
+
+(Sqrt ...) => (SQRTSD ...)
+(Sqrt32 ...) => (SQRTSS ...)
+
+(RoundToEven x) => (ROUNDSD [0] x)
+(Floor x)       => (ROUNDSD [1] x)
+(Ceil x)        => (ROUNDSD [2] x)
+(Trunc x)       => (ROUNDSD [3] x)
+
+(FMA x y z) => (VFMADD231SD z x y)
+
+// Lowering extension
+// Note: we always extend to 64 bits even though some ops don't need that many result bits.
+(SignExt8to16  ...) => (MOVBQSX ...)
+(SignExt8to32  ...) => (MOVBQSX ...)
+(SignExt8to64  ...) => (MOVBQSX ...)
+(SignExt16to32 ...) => (MOVWQSX ...)
+(SignExt16to64 ...) => (MOVWQSX ...)
+(SignExt32to64 ...) => (MOVLQSX ...)
+
+(ZeroExt8to16  ...) => (MOVBQZX ...)
+(ZeroExt8to32  ...) => (MOVBQZX ...)
+(ZeroExt8to64  ...) => (MOVBQZX ...)
+(ZeroExt16to32 ...) => (MOVWQZX ...)
+(ZeroExt16to64 ...) => (MOVWQZX ...)
+(ZeroExt32to64 ...) => (MOVLQZX ...)
+
+(Slicemask <t> x) => (SARQconst (NEGQ <t> x) [63])
+
+(SpectreIndex <t> x y) => (CMOVQCC x (MOVQconst [0]) (CMPQ x y))
+(SpectreSliceIndex <t> x y) => (CMOVQHI x (MOVQconst [0]) (CMPQ x y))
+
+// Lowering truncation
+// Because we ignore high parts of registers, truncates are just copies.
+(Trunc16to8  ...) => (Copy ...)
+(Trunc32to8  ...) => (Copy ...)
+(Trunc32to16 ...) => (Copy ...)
+(Trunc64to8  ...) => (Copy ...)
+(Trunc64to16 ...) => (Copy ...)
+(Trunc64to32 ...) => (Copy ...)
+
+// Lowering float <-> int
+(Cvt32to32F ...) => (CVTSL2SS ...)
+(Cvt32to64F ...) => (CVTSL2SD ...)
+(Cvt64to32F ...) => (CVTSQ2SS ...)
+(Cvt64to64F ...) => (CVTSQ2SD ...)
+
+(Cvt32Fto32 ...) => (CVTTSS2SL ...)
+(Cvt32Fto64 ...) => (CVTTSS2SQ ...)
+(Cvt64Fto32 ...) => (CVTTSD2SL ...)
+(Cvt64Fto64 ...) => (CVTTSD2SQ ...)
+
+(Cvt32Fto64F ...) => (CVTSS2SD ...)
+(Cvt64Fto32F ...) => (CVTSD2SS ...)
+
+(Round(32|64)F ...) => (Copy ...)
+
+(CvtBoolToUint8 ...) => (Copy ...)
+
+// Lowering shifts
+// Unsigned shifts need to return 0 if shift amount is >= width of shifted value.
+//   result = (arg << shift) & (shift >= argbits ? 0 : 0xffffffffffffffff)
+(Lsh64x(64|32|16|8) <t> x y) && !shiftIsBounded(v) => (ANDQ (SHLQ <t> x y) (SBBQcarrymask <t> (CMP(Q|L|W|B)const y [64])))
+(Lsh32x(64|32|16|8) <t> x y) && !shiftIsBounded(v) => (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMP(Q|L|W|B)const y [32])))
+(Lsh16x(64|32|16|8) <t> x y) && !shiftIsBounded(v) => (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMP(Q|L|W|B)const y [32])))
+(Lsh8x(64|32|16|8)  <t> x y) && !shiftIsBounded(v) => (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMP(Q|L|W|B)const y [32])))
+
+(Lsh64x(64|32|16|8) x y) && shiftIsBounded(v) => (SHLQ x y)
+(Lsh32x(64|32|16|8) x y) && shiftIsBounded(v) => (SHLL x y)
+(Lsh16x(64|32|16|8) x y) && shiftIsBounded(v) => (SHLL x y)
+(Lsh8x(64|32|16|8)  x y) && shiftIsBounded(v) => (SHLL x y)
+
+(Rsh64Ux(64|32|16|8) <t> x y) && !shiftIsBounded(v) => (ANDQ (SHRQ <t> x y) (SBBQcarrymask <t> (CMP(Q|L|W|B)const y [64])))
+(Rsh32Ux(64|32|16|8) <t> x y) && !shiftIsBounded(v) => (ANDL (SHRL <t> x y) (SBBLcarrymask <t> (CMP(Q|L|W|B)const y [32])))
+(Rsh16Ux(64|32|16|8) <t> x y) && !shiftIsBounded(v) => (ANDL (SHRW <t> x y) (SBBLcarrymask <t> (CMP(Q|L|W|B)const y [16])))
+(Rsh8Ux(64|32|16|8)  <t> x y) && !shiftIsBounded(v) => (ANDL (SHRB <t> x y) (SBBLcarrymask <t> (CMP(Q|L|W|B)const y [8])))
+
+(Rsh64Ux(64|32|16|8) x y) && shiftIsBounded(v) => (SHRQ x y)
+(Rsh32Ux(64|32|16|8) x y) && shiftIsBounded(v) => (SHRL x y)
+(Rsh16Ux(64|32|16|8) x y) && shiftIsBounded(v) => (SHRW x y)
+(Rsh8Ux(64|32|16|8)  x y) && shiftIsBounded(v) => (SHRB x y)
+
+// Signed right shift needs to return 0/-1 if shift amount is >= width of shifted value.
+// We implement this by setting the shift value to -1 (all ones) if the shift value is >= width.
+(Rsh64x(64|32|16|8) <t> x y) && !shiftIsBounded(v) => (SARQ <t> x (OR(Q|L|L|L) <y.Type> y (NOT(Q|L|L|L) <y.Type> (SBB(Q|L|L|L)carrymask <y.Type> (CMP(Q|L|W|B)const y [64])))))
+(Rsh32x(64|32|16|8) <t> x y) && !shiftIsBounded(v) => (SARL <t> x (OR(Q|L|L|L) <y.Type> y (NOT(Q|L|L|L) <y.Type> (SBB(Q|L|L|L)carrymask <y.Type> (CMP(Q|L|W|B)const y [32])))))
+(Rsh16x(64|32|16|8) <t> x y) && !shiftIsBounded(v) => (SARW <t> x (OR(Q|L|L|L) <y.Type> y (NOT(Q|L|L|L) <y.Type> (SBB(Q|L|L|L)carrymask <y.Type> (CMP(Q|L|W|B)const y [16])))))
+(Rsh8x(64|32|16|8)  <t> x y) && !shiftIsBounded(v) => (SARB <t> x (OR(Q|L|L|L) <y.Type> y (NOT(Q|L|L|L) <y.Type> (SBB(Q|L|L|L)carrymask <y.Type> (CMP(Q|L|W|B)const y [8])))))
+
+(Rsh64x(64|32|16|8) x y) && shiftIsBounded(v) => (SARQ x y)
+(Rsh32x(64|32|16|8) x y) && shiftIsBounded(v) => (SARL x y)
+(Rsh16x(64|32|16|8) x y) && shiftIsBounded(v) => (SARW x y)
+(Rsh8x(64|32|16|8) x y)  && shiftIsBounded(v) => (SARB x y)
+
+// Lowering integer comparisons
+(Less(64|32|16|8)      x y) => (SETL  (CMP(Q|L|W|B)     x y))
+(Less(64|32|16|8)U     x y) => (SETB  (CMP(Q|L|W|B)     x y))
+(Leq(64|32|16|8)       x y) => (SETLE (CMP(Q|L|W|B)     x y))
+(Leq(64|32|16|8)U      x y) => (SETBE (CMP(Q|L|W|B)     x y))
+(Eq(Ptr|64|32|16|8|B)  x y) => (SETEQ (CMP(Q|Q|L|W|B|B) x y))
+(Neq(Ptr|64|32|16|8|B) x y) => (SETNE (CMP(Q|Q|L|W|B|B) x y))
+
+// Lowering floating point comparisons
+// Note Go assembler gets UCOMISx operand order wrong, but it is right here
+// and the operands are reversed when generating assembly language.
+(Eq(32|64)F   x y) => (SETEQF (UCOMIS(S|D) x y))
+(Neq(32|64)F  x y) => (SETNEF (UCOMIS(S|D) x y))
+// Use SETGF/SETGEF with reversed operands to dodge NaN case.
+(Less(32|64)F x y) => (SETGF  (UCOMIS(S|D) y x))
+(Leq(32|64)F  x y) => (SETGEF (UCOMIS(S|D) y x))
+
+// Lowering loads
+(Load <t> ptr mem) && (is64BitInt(t) || isPtr(t)) => (MOVQload ptr mem)
+(Load <t> ptr mem) && is32BitInt(t) => (MOVLload ptr mem)
+(Load <t> ptr mem) && is16BitInt(t) => (MOVWload ptr mem)
+(Load <t> ptr mem) && (t.IsBoolean() || is8BitInt(t)) => (MOVBload ptr mem)
+(Load <t> ptr mem) && is32BitFloat(t) => (MOVSSload ptr mem)
+(Load <t> ptr mem) && is64BitFloat(t) => (MOVSDload ptr mem)
+
+// Lowering stores
+// These more-specific FP versions of Store pattern should come first.
+(Store {t} ptr val mem) && t.Size() == 8 && is64BitFloat(val.Type) => (MOVSDstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 4 && is32BitFloat(val.Type) => (MOVSSstore ptr val mem)
+
+(Store {t} ptr val mem) && t.Size() == 8 => (MOVQstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 4 => (MOVLstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 2 => (MOVWstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 1 => (MOVBstore ptr val mem)
+
+// Lowering moves
+(Move [0] _ _ mem) => mem
+(Move [1] dst src mem) => (MOVBstore dst (MOVBload src mem) mem)
+(Move [2] dst src mem) => (MOVWstore dst (MOVWload src mem) mem)
+(Move [4] dst src mem) => (MOVLstore dst (MOVLload src mem) mem)
+(Move [8] dst src mem) => (MOVQstore dst (MOVQload src mem) mem)
+(Move [16] dst src mem) && config.useSSE => (MOVOstore dst (MOVOload src mem) mem)
+(Move [16] dst src mem) && !config.useSSE =>
+	(MOVQstore [8] dst (MOVQload [8] src mem)
+		(MOVQstore dst (MOVQload src mem) mem))
+
+(Move [32] dst src mem) =>
+	(Move [16]
+		(OffPtr <dst.Type> dst [16])
+		(OffPtr <src.Type> src [16])
+		(Move [16] dst src mem))
+
+(Move [48] dst src mem) && config.useSSE =>
+	(Move [32]
+		(OffPtr <dst.Type> dst [16])
+		(OffPtr <src.Type> src [16])
+		(Move [16] dst src mem))
+
+(Move [64] dst src mem) && config.useSSE =>
+	(Move [32]
+		(OffPtr <dst.Type> dst [32])
+		(OffPtr <src.Type> src [32])
+		(Move [32] dst src mem))
+
+(Move [3] dst src mem) =>
+	(MOVBstore [2] dst (MOVBload [2] src mem)
+		(MOVWstore dst (MOVWload src mem) mem))
+(Move [5] dst src mem) =>
+	(MOVBstore [4] dst (MOVBload [4] src mem)
+		(MOVLstore dst (MOVLload src mem) mem))
+(Move [6] dst src mem) =>
+	(MOVWstore [4] dst (MOVWload [4] src mem)
+		(MOVLstore dst (MOVLload src mem) mem))
+(Move [7] dst src mem) =>
+	(MOVLstore [3] dst (MOVLload [3] src mem)
+		(MOVLstore dst (MOVLload src mem) mem))
+(Move [9] dst src mem) =>
+	(MOVBstore [8] dst (MOVBload [8] src mem)
+		(MOVQstore dst (MOVQload src mem) mem))
+(Move [10] dst src mem) =>
+	(MOVWstore [8] dst (MOVWload [8] src mem)
+		(MOVQstore dst (MOVQload src mem) mem))
+(Move [12] dst src mem) =>
+	(MOVLstore [8] dst (MOVLload [8] src mem)
+		(MOVQstore dst (MOVQload src mem) mem))
+(Move [s] dst src mem) && s == 11 || s >= 13 && s <= 15 =>
+	(MOVQstore [int32(s-8)] dst (MOVQload [int32(s-8)] src mem)
+		(MOVQstore dst (MOVQload src mem) mem))
+
+// Adjust moves to be a multiple of 16 bytes.
+(Move [s] dst src mem)
+	&& s > 16 && s%16 != 0 && s%16 <= 8 =>
+	(Move [s-s%16]
+		(OffPtr <dst.Type> dst [s%16])
+		(OffPtr <src.Type> src [s%16])
+		(MOVQstore dst (MOVQload src mem) mem))
+(Move [s] dst src mem)
+	&& s > 16 && s%16 != 0 && s%16 > 8 && config.useSSE =>
+	(Move [s-s%16]
+		(OffPtr <dst.Type> dst [s%16])
+		(OffPtr <src.Type> src [s%16])
+		(MOVOstore dst (MOVOload src mem) mem))
+(Move [s] dst src mem)
+	&& s > 16 && s%16 != 0 && s%16 > 8 && !config.useSSE =>
+	(Move [s-s%16]
+		(OffPtr <dst.Type> dst [s%16])
+		(OffPtr <src.Type> src [s%16])
+		(MOVQstore [8] dst (MOVQload [8] src mem)
+			(MOVQstore dst (MOVQload src mem) mem)))
+
+// Medium copying uses a duff device.
+(Move [s] dst src mem)
+	&& s > 64 && s <= 16*64 && s%16 == 0
+	&& !config.noDuffDevice && logLargeCopy(v, s) =>
+	(DUFFCOPY [s] dst src mem)
+
+// Large copying uses REP MOVSQ.
+(Move [s] dst src mem) && (s > 16*64 || config.noDuffDevice) && s%8 == 0 && logLargeCopy(v, s) =>
+	(REPMOVSQ dst src (MOVQconst [s/8]) mem)
+
+// Lowering Zero instructions
+(Zero [0] _ mem) => mem
+(Zero [1] destptr mem) => (MOVBstoreconst [makeValAndOff(0,0)] destptr mem)
+(Zero [2] destptr mem) => (MOVWstoreconst [makeValAndOff(0,0)] destptr mem)
+(Zero [4] destptr mem) => (MOVLstoreconst [makeValAndOff(0,0)] destptr mem)
+(Zero [8] destptr mem) => (MOVQstoreconst [makeValAndOff(0,0)] destptr mem)
+
+(Zero [3] destptr mem) =>
+	(MOVBstoreconst [makeValAndOff(0,2)] destptr
+		(MOVWstoreconst [makeValAndOff(0,0)] destptr mem))
+(Zero [5] destptr mem) =>
+	(MOVBstoreconst [makeValAndOff(0,4)] destptr
+		(MOVLstoreconst [makeValAndOff(0,0)] destptr mem))
+(Zero [6] destptr mem) =>
+	(MOVWstoreconst [makeValAndOff(0,4)] destptr
+		(MOVLstoreconst [makeValAndOff(0,0)] destptr mem))
+(Zero [7] destptr mem) =>
+	(MOVLstoreconst [makeValAndOff(0,3)] destptr
+		(MOVLstoreconst [makeValAndOff(0,0)] destptr mem))
+
+// Strip off any fractional word zeroing.
+(Zero [s] destptr mem) && s%8 != 0 && s > 8 && !config.useSSE =>
+	(Zero [s-s%8] (OffPtr <destptr.Type> destptr [s%8])
+		(MOVQstoreconst [makeValAndOff(0,0)] destptr mem))
+
+// Zero small numbers of words directly.
+(Zero [16] destptr mem) && !config.useSSE =>
+	(MOVQstoreconst [makeValAndOff(0,8)] destptr
+		(MOVQstoreconst [makeValAndOff(0,0)] destptr mem))
+(Zero [24] destptr mem) && !config.useSSE =>
+	(MOVQstoreconst [makeValAndOff(0,16)] destptr
+		(MOVQstoreconst [makeValAndOff(0,8)] destptr
+			(MOVQstoreconst [makeValAndOff(0,0)] destptr mem)))
+(Zero [32] destptr mem) && !config.useSSE =>
+	(MOVQstoreconst [makeValAndOff(0,24)] destptr
+		(MOVQstoreconst [makeValAndOff(0,16)] destptr
+			(MOVQstoreconst [makeValAndOff(0,8)] destptr
+				(MOVQstoreconst [makeValAndOff(0,0)] destptr mem))))
+
+(Zero [s] destptr mem) && s > 8 && s < 16 && config.useSSE =>
+	(MOVQstoreconst [makeValAndOff(0,int32(s-8))] destptr
+		(MOVQstoreconst [makeValAndOff(0,0)] destptr mem))
+
+// Adjust zeros to be a multiple of 16 bytes.
+(Zero [s] destptr mem) && s%16 != 0 && s > 16 && s%16 > 8 && config.useSSE =>
+	(Zero [s-s%16] (OffPtr <destptr.Type> destptr [s%16])
+		(MOVOstoreconst [makeValAndOff(0,0)] destptr mem))
+
+(Zero [s] destptr mem) && s%16 != 0 && s > 16 && s%16 <= 8 && config.useSSE =>
+	(Zero [s-s%16] (OffPtr <destptr.Type> destptr [s%16])
+		(MOVOstoreconst [makeValAndOff(0,0)] destptr mem))
+
+(Zero [16] destptr mem) && config.useSSE =>
+	(MOVOstoreconst [makeValAndOff(0,0)] destptr mem)
+(Zero [32] destptr mem) && config.useSSE =>
+	(MOVOstoreconst [makeValAndOff(0,16)] destptr
+		(MOVOstoreconst [makeValAndOff(0,0)] destptr mem))
+(Zero [48] destptr mem) && config.useSSE =>
+	(MOVOstoreconst [makeValAndOff(0,32)] destptr
+		(MOVOstoreconst [makeValAndOff(0,16)] destptr
+			(MOVOstoreconst [makeValAndOff(0,0)] destptr mem)))
+(Zero [64] destptr mem) && config.useSSE =>
+	(MOVOstoreconst [makeValAndOff(0,48)] destptr
+		(MOVOstoreconst [makeValAndOff(0,32)] destptr
+			(MOVOstoreconst [makeValAndOff(0,16)] destptr
+				(MOVOstoreconst [makeValAndOff(0,0)] destptr mem))))
+
+// Medium zeroing uses a duff device.
+(Zero [s] destptr mem)
+	&& s > 64 && s <= 1024 && s%16 == 0 && !config.noDuffDevice =>
+	(DUFFZERO [s] destptr mem)
+
+// Large zeroing uses REP STOSQ.
+(Zero [s] destptr mem)
+	&& (s > 1024 || (config.noDuffDevice && s > 64 || !config.useSSE && s > 32))
+	&& s%8 == 0 =>
+	(REPSTOSQ destptr (MOVQconst [s/8]) (MOVQconst [0]) mem)
+
+// Lowering constants
+(Const8   [c]) => (MOVLconst [int32(c)])
+(Const16  [c]) => (MOVLconst [int32(c)])
+(Const32  ...) => (MOVLconst ...)
+(Const64  ...) => (MOVQconst ...)
+(Const32F ...) => (MOVSSconst ...)
+(Const64F ...) => (MOVSDconst ...)
+(ConstNil    ) => (MOVQconst [0])
+(ConstBool [c]) => (MOVLconst [b2i32(c)])
+
+// Lowering calls
+(StaticCall ...) => (CALLstatic ...)
+(ClosureCall ...) => (CALLclosure ...)
+(InterCall ...) => (CALLinter ...)
+(TailCall ...) => (CALLtail ...)
+
+// Lowering conditional moves
+// If the condition is a SETxx, we can just run a CMOV from the comparison that was
+// setting the flags.
+// Legend: HI=unsigned ABOVE, CS=unsigned BELOW, CC=unsigned ABOVE EQUAL, LS=unsigned BELOW EQUAL
+(CondSelect <t> x y (SET(EQ|NE|L|G|LE|GE|A|B|AE|BE|EQF|NEF|GF|GEF) cond)) && (is64BitInt(t) || isPtr(t))
+    => (CMOVQ(EQ|NE|LT|GT|LE|GE|HI|CS|CC|LS|EQF|NEF|GTF|GEF) y x cond)
+(CondSelect <t> x y (SET(EQ|NE|L|G|LE|GE|A|B|AE|BE|EQF|NEF|GF|GEF) cond)) && is32BitInt(t)
+    => (CMOVL(EQ|NE|LT|GT|LE|GE|HI|CS|CC|LS|EQF|NEF|GTF|GEF) y x cond)
+(CondSelect <t> x y (SET(EQ|NE|L|G|LE|GE|A|B|AE|BE|EQF|NEF|GF|GEF) cond)) && is16BitInt(t)
+    => (CMOVW(EQ|NE|LT|GT|LE|GE|HI|CS|CC|LS|EQF|NEF|GTF|GEF) y x cond)
+
+// If the condition does not set the flags, we need to generate a comparison.
+(CondSelect <t> x y check) && !check.Type.IsFlags() && check.Type.Size() == 1
+    => (CondSelect <t> x y (MOVBQZX <typ.UInt64> check))
+(CondSelect <t> x y check) && !check.Type.IsFlags() && check.Type.Size() == 2
+    => (CondSelect <t> x y (MOVWQZX <typ.UInt64> check))
+(CondSelect <t> x y check) && !check.Type.IsFlags() && check.Type.Size() == 4
+    => (CondSelect <t> x y (MOVLQZX <typ.UInt64> check))
+
+(CondSelect <t> x y check) && !check.Type.IsFlags() && check.Type.Size() == 8 && (is64BitInt(t) || isPtr(t))
+    => (CMOVQNE y x (CMPQconst [0] check))
+(CondSelect <t> x y check) && !check.Type.IsFlags() && check.Type.Size() == 8 && is32BitInt(t)
+    => (CMOVLNE y x (CMPQconst [0] check))
+(CondSelect <t> x y check) && !check.Type.IsFlags() && check.Type.Size() == 8 && is16BitInt(t)
+    => (CMOVWNE y x (CMPQconst [0] check))
+
+// Absorb InvertFlags
+(CMOVQ(EQ|NE|LT|GT|LE|GE|HI|CS|CC|LS) x y (InvertFlags cond))
+    => (CMOVQ(EQ|NE|GT|LT|GE|LE|CS|HI|LS|CC) x y cond)
+(CMOVL(EQ|NE|LT|GT|LE|GE|HI|CS|CC|LS) x y (InvertFlags cond))
+    => (CMOVL(EQ|NE|GT|LT|GE|LE|CS|HI|LS|CC) x y cond)
+(CMOVW(EQ|NE|LT|GT|LE|GE|HI|CS|CC|LS) x y (InvertFlags cond))
+    => (CMOVW(EQ|NE|GT|LT|GE|LE|CS|HI|LS|CC) x y cond)
+
+// Absorb constants generated during lower
+(CMOV(QEQ|QLE|QGE|QCC|QLS|LEQ|LLE|LGE|LCC|LLS|WEQ|WLE|WGE|WCC|WLS) _ x (FlagEQ)) => x
+(CMOV(QNE|QLT|QGT|QCS|QHI|LNE|LLT|LGT|LCS|LHI|WNE|WLT|WGT|WCS|WHI) y _ (FlagEQ)) => y
+(CMOV(QNE|QGT|QGE|QHI|QCC|LNE|LGT|LGE|LHI|LCC|WNE|WGT|WGE|WHI|WCC) _ x (FlagGT_UGT)) => x
+(CMOV(QEQ|QLE|QLT|QLS|QCS|LEQ|LLE|LLT|LLS|LCS|WEQ|WLE|WLT|WLS|WCS) y _ (FlagGT_UGT)) => y
+(CMOV(QNE|QGT|QGE|QLS|QCS|LNE|LGT|LGE|LLS|LCS|WNE|WGT|WGE|WLS|WCS) _ x (FlagGT_ULT)) => x
+(CMOV(QEQ|QLE|QLT|QHI|QCC|LEQ|LLE|LLT|LHI|LCC|WEQ|WLE|WLT|WHI|WCC) y _ (FlagGT_ULT)) => y
+(CMOV(QNE|QLT|QLE|QCS|QLS|LNE|LLT|LLE|LCS|LLS|WNE|WLT|WLE|WCS|WLS) _ x (FlagLT_ULT)) => x
+(CMOV(QEQ|QGT|QGE|QHI|QCC|LEQ|LGT|LGE|LHI|LCC|WEQ|WGT|WGE|WHI|WCC) y _ (FlagLT_ULT)) => y
+(CMOV(QNE|QLT|QLE|QHI|QCC|LNE|LLT|LLE|LHI|LCC|WNE|WLT|WLE|WHI|WCC) _ x (FlagLT_UGT)) => x
+(CMOV(QEQ|QGT|QGE|QCS|QLS|LEQ|LGT|LGE|LCS|LLS|WEQ|WGT|WGE|WCS|WLS) y _ (FlagLT_UGT)) => y
+
+// Miscellaneous
+(IsNonNil p) => (SETNE (TESTQ p p))
+(IsInBounds idx len) => (SETB (CMPQ idx len))
+(IsSliceInBounds idx len) => (SETBE (CMPQ idx len))
+(NilCheck ...) => (LoweredNilCheck ...)
+(GetG mem) && v.Block.Func.OwnAux.Fn.ABI() != obj.ABIInternal => (LoweredGetG mem) // only lower in old ABI. in new ABI we have a G register.
+(GetClosurePtr ...) => (LoweredGetClosurePtr ...)
+(GetCallerPC ...) => (LoweredGetCallerPC ...)
+(GetCallerSP ...) => (LoweredGetCallerSP ...)
+
+(HasCPUFeature {s}) => (SETNE (CMPLconst [0] (LoweredHasCPUFeature {s})))
+(Addr {sym} base) => (LEAQ {sym} base)
+(LocalAddr {sym} base _) => (LEAQ {sym} base)
+
+(MOVBstore [off] {sym} ptr y:(SETL x) mem) && y.Uses == 1 => (SETLstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr y:(SETLE x) mem) && y.Uses == 1 => (SETLEstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr y:(SETG x) mem) && y.Uses == 1 => (SETGstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr y:(SETGE x) mem) && y.Uses == 1 => (SETGEstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr y:(SETEQ x) mem) && y.Uses == 1 => (SETEQstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr y:(SETNE x) mem) && y.Uses == 1 => (SETNEstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr y:(SETB x) mem) && y.Uses == 1 => (SETBstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr y:(SETBE x) mem) && y.Uses == 1 => (SETBEstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr y:(SETA x) mem) && y.Uses == 1 => (SETAstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr y:(SETAE x) mem) && y.Uses == 1 => (SETAEstore [off] {sym} ptr x mem)
+
+// block rewrites
+(If (SETL  cmp) yes no) => (LT  cmp yes no)
+(If (SETLE cmp) yes no) => (LE  cmp yes no)
+(If (SETG  cmp) yes no) => (GT  cmp yes no)
+(If (SETGE cmp) yes no) => (GE  cmp yes no)
+(If (SETEQ cmp) yes no) => (EQ  cmp yes no)
+(If (SETNE cmp) yes no) => (NE  cmp yes no)
+(If (SETB  cmp) yes no) => (ULT cmp yes no)
+(If (SETBE cmp) yes no) => (ULE cmp yes no)
+(If (SETA  cmp) yes no) => (UGT cmp yes no)
+(If (SETAE cmp) yes no) => (UGE cmp yes no)
+(If (SETO cmp) yes no) => (OS cmp yes no)
+
+// Special case for floating point - LF/LEF not generated
+(If (SETGF  cmp) yes no) => (UGT  cmp yes no)
+(If (SETGEF cmp) yes no) => (UGE  cmp yes no)
+(If (SETEQF cmp) yes no) => (EQF  cmp yes no)
+(If (SETNEF cmp) yes no) => (NEF  cmp yes no)
+
+(If cond yes no) => (NE (TESTB cond cond) yes no)
+
+(JumpTable idx) => (JUMPTABLE {makeJumpTableSym(b)} idx (LEAQ <typ.Uintptr> {makeJumpTableSym(b)} (SB)))
+
+// Atomic loads.  Other than preserving their ordering with respect to other loads, nothing special here.
+(AtomicLoad8 ptr mem) => (MOVBatomicload ptr mem)
+(AtomicLoad32 ptr mem) => (MOVLatomicload ptr mem)
+(AtomicLoad64 ptr mem) => (MOVQatomicload ptr mem)
+(AtomicLoadPtr ptr mem) => (MOVQatomicload ptr mem)
+
+// Atomic stores.  We use XCHG to prevent the hardware reordering a subsequent load.
+// TODO: most runtime uses of atomic stores don't need that property.  Use normal stores for those?
+(AtomicStore8 ptr val mem) => (Select1 (XCHGB <types.NewTuple(typ.UInt8,types.TypeMem)> val ptr mem))
+(AtomicStore32 ptr val mem) => (Select1 (XCHGL <types.NewTuple(typ.UInt32,types.TypeMem)> val ptr mem))
+(AtomicStore64 ptr val mem) => (Select1 (XCHGQ <types.NewTuple(typ.UInt64,types.TypeMem)> val ptr mem))
+(AtomicStorePtrNoWB ptr val mem) => (Select1 (XCHGQ <types.NewTuple(typ.BytePtr,types.TypeMem)> val ptr mem))
+
+// Atomic exchanges.
+(AtomicExchange32 ptr val mem) => (XCHGL val ptr mem)
+(AtomicExchange64 ptr val mem) => (XCHGQ val ptr mem)
+
+// Atomic adds.
+(AtomicAdd32 ptr val mem) => (AddTupleFirst32 val (XADDLlock val ptr mem))
+(AtomicAdd64 ptr val mem) => (AddTupleFirst64 val (XADDQlock val ptr mem))
+(Select0 <t> (AddTupleFirst32 val tuple)) => (ADDL val (Select0 <t> tuple))
+(Select1     (AddTupleFirst32   _ tuple)) => (Select1 tuple)
+(Select0 <t> (AddTupleFirst64 val tuple)) => (ADDQ val (Select0 <t> tuple))
+(Select1     (AddTupleFirst64   _ tuple)) => (Select1 tuple)
+
+// Atomic compare and swap.
+(AtomicCompareAndSwap32 ptr old new_ mem) => (CMPXCHGLlock ptr old new_ mem)
+(AtomicCompareAndSwap64 ptr old new_ mem) => (CMPXCHGQlock ptr old new_ mem)
+
+// Atomic memory updates.
+(AtomicAnd8  ptr val mem) => (ANDBlock ptr val mem)
+(AtomicAnd32 ptr val mem) => (ANDLlock ptr val mem)
+(AtomicOr8   ptr val mem) => (ORBlock  ptr val mem)
+(AtomicOr32  ptr val mem) => (ORLlock  ptr val mem)
+
+// Write barrier.
+(WB ...) => (LoweredWB ...)
+
+(PanicBounds [kind] x y mem) && boundsABI(kind) == 0 => (LoweredPanicBoundsA [kind] x y mem)
+(PanicBounds [kind] x y mem) && boundsABI(kind) == 1 => (LoweredPanicBoundsB [kind] x y mem)
+(PanicBounds [kind] x y mem) && boundsABI(kind) == 2 => (LoweredPanicBoundsC [kind] x y mem)
+
+// lowering rotates
+(RotateLeft8  ...) => (ROLB ...)
+(RotateLeft16 ...) => (ROLW ...)
+(RotateLeft32 ...) => (ROLL ...)
+(RotateLeft64 ...) => (ROLQ ...)
+
+// ***************************
+// Above: lowering rules
+// Below: optimizations
+// ***************************
+// TODO: Should the optimizations be a separate pass?
+
+// Fold boolean tests into blocks
+(NE (TESTB (SETL  cmp) (SETL  cmp)) yes no) => (LT  cmp yes no)
+(NE (TESTB (SETLE cmp) (SETLE cmp)) yes no) => (LE  cmp yes no)
+(NE (TESTB (SETG  cmp) (SETG  cmp)) yes no) => (GT  cmp yes no)
+(NE (TESTB (SETGE cmp) (SETGE cmp)) yes no) => (GE  cmp yes no)
+(NE (TESTB (SETEQ cmp) (SETEQ cmp)) yes no) => (EQ  cmp yes no)
+(NE (TESTB (SETNE cmp) (SETNE cmp)) yes no) => (NE  cmp yes no)
+(NE (TESTB (SETB  cmp) (SETB  cmp)) yes no) => (ULT cmp yes no)
+(NE (TESTB (SETBE cmp) (SETBE cmp)) yes no) => (ULE cmp yes no)
+(NE (TESTB (SETA  cmp) (SETA  cmp)) yes no) => (UGT cmp yes no)
+(NE (TESTB (SETAE cmp) (SETAE cmp)) yes no) => (UGE cmp yes no)
+(NE (TESTB (SETO cmp) (SETO cmp)) yes no) => (OS cmp yes no)
+
+// Unsigned comparisons to 0/1
+(ULT (TEST(Q|L|W|B) x x) yes no) => (First no yes)
+(UGE (TEST(Q|L|W|B) x x) yes no) => (First yes no)
+(SETB (TEST(Q|L|W|B) x x)) => (ConstBool [false])
+(SETAE (TEST(Q|L|W|B) x x)) => (ConstBool [true])
+
+// x & 1 != 0 -> x & 1
+(SETNE (TEST(B|W)const [1] x)) => (AND(L|L)const [1] x)
+(SETB (BT(L|Q)const [0] x)) => (AND(L|Q)const [1] x)
+
+// Recognize bit tests: a&(1<<b) != 0 for b suitably bounded
+// Note that BTx instructions use the carry bit, so we need to convert tests for zero flag
+// into tests for carry flags.
+// ULT and SETB check the carry flag; they are identical to CS and SETCS. Same, mutatis
+// mutandis, for UGE and SETAE, and CC and SETCC.
+((NE|EQ) (TESTL (SHLL (MOVLconst [1]) x) y)) => ((ULT|UGE) (BTL x y))
+((NE|EQ) (TESTQ (SHLQ (MOVQconst [1]) x) y)) => ((ULT|UGE) (BTQ x y))
+((NE|EQ) (TESTLconst [c] x)) && isUint32PowerOfTwo(int64(c))
+    => ((ULT|UGE) (BTLconst [int8(log32(c))] x))
+((NE|EQ) (TESTQconst [c] x)) && isUint64PowerOfTwo(int64(c))
+    => ((ULT|UGE) (BTQconst [int8(log32(c))] x))
+((NE|EQ) (TESTQ (MOVQconst [c]) x)) && isUint64PowerOfTwo(c)
+    => ((ULT|UGE) (BTQconst [int8(log64(c))] x))
+(SET(NE|EQ) (TESTL (SHLL (MOVLconst [1]) x) y)) => (SET(B|AE)  (BTL x y))
+(SET(NE|EQ) (TESTQ (SHLQ (MOVQconst [1]) x) y)) => (SET(B|AE)  (BTQ x y))
+(SET(NE|EQ) (TESTLconst [c] x)) && isUint32PowerOfTwo(int64(c))
+    => (SET(B|AE)  (BTLconst [int8(log32(c))] x))
+(SET(NE|EQ) (TESTQconst [c] x)) && isUint64PowerOfTwo(int64(c))
+    => (SET(B|AE)  (BTQconst [int8(log32(c))] x))
+(SET(NE|EQ) (TESTQ (MOVQconst [c]) x)) && isUint64PowerOfTwo(c)
+    => (SET(B|AE)  (BTQconst [int8(log64(c))] x))
+// SET..store variant
+(SET(NE|EQ)store [off] {sym} ptr (TESTL (SHLL (MOVLconst [1]) x) y) mem)
+    => (SET(B|AE)store  [off] {sym} ptr (BTL x y) mem)
+(SET(NE|EQ)store [off] {sym} ptr (TESTQ (SHLQ (MOVQconst [1]) x) y) mem)
+    => (SET(B|AE)store  [off] {sym} ptr (BTQ x y) mem)
+(SET(NE|EQ)store [off] {sym} ptr (TESTLconst [c] x) mem) && isUint32PowerOfTwo(int64(c))
+    => (SET(B|AE)store  [off] {sym} ptr (BTLconst [int8(log32(c))] x) mem)
+(SET(NE|EQ)store [off] {sym} ptr (TESTQconst [c] x) mem) && isUint64PowerOfTwo(int64(c))
+    => (SET(B|AE)store  [off] {sym} ptr (BTQconst [int8(log32(c))] x) mem)
+(SET(NE|EQ)store [off] {sym} ptr (TESTQ (MOVQconst [c]) x) mem) && isUint64PowerOfTwo(c)
+    => (SET(B|AE)store  [off] {sym} ptr (BTQconst [int8(log64(c))] x) mem)
+
+// Handle bit-testing in the form (a>>b)&1 != 0 by building the above rules
+// and further combining shifts.
+(BT(Q|L)const [c] (SHRQconst [d] x)) && (c+d)<64 => (BTQconst [c+d] x)
+(BT(Q|L)const [c] (SHLQconst [d] x)) && c>d      => (BT(Q|L)const [c-d] x)
+(BT(Q|L)const [0] s:(SHRQ x y)) => (BTQ y x)
+(BTLconst [c] (SHRLconst [d] x)) && (c+d)<32 => (BTLconst [c+d] x)
+(BTLconst [c] (SHLLconst [d] x)) && c>d      => (BTLconst [c-d] x)
+(BTLconst [0] s:(SHR(L|XL) x y)) => (BTL y x)
+
+// Rewrite a & 1 != 1 into a & 1 == 0.
+// Among other things, this lets us turn (a>>b)&1 != 1 into a bit test.
+(SET(NE|EQ) (CMPLconst [1] s:(ANDLconst [1] _))) => (SET(EQ|NE) (CMPLconst [0] s))
+(SET(NE|EQ)store [off] {sym} ptr (CMPLconst [1] s:(ANDLconst [1] _)) mem) => (SET(EQ|NE)store [off] {sym} ptr (CMPLconst [0] s) mem)
+(SET(NE|EQ) (CMPQconst [1] s:(ANDQconst [1] _))) => (SET(EQ|NE) (CMPQconst [0] s))
+(SET(NE|EQ)store [off] {sym} ptr (CMPQconst [1] s:(ANDQconst [1] _)) mem) => (SET(EQ|NE)store [off] {sym} ptr (CMPQconst [0] s) mem)
+
+// Recognize bit setting (a |= 1<<b) and toggling (a ^= 1<<b)
+(OR(Q|L) (SHL(Q|L) (MOV(Q|L)const [1]) y) x) => (BTS(Q|L) x y)
+(XOR(Q|L) (SHL(Q|L) (MOV(Q|L)const [1]) y) x) => (BTC(Q|L) x y)
+
+// Convert ORconst into BTS, if the code gets smaller, with boundary being
+// (ORL $40,AX is 3 bytes, ORL $80,AX is 6 bytes).
+((ORQ|XORQ)const [c] x) && isUint64PowerOfTwo(int64(c)) && uint64(c) >= 128
+    => (BT(S|C)Qconst [int8(log32(c))] x)
+((ORL|XORL)const [c] x) && isUint32PowerOfTwo(int64(c)) && uint64(c) >= 128
+    => (BT(S|C)Lconst [int8(log32(c))] x)
+((ORQ|XORQ) (MOVQconst [c]) x) && isUint64PowerOfTwo(c) && uint64(c) >= 128
+    => (BT(S|C)Qconst [int8(log64(c))] x)
+((ORL|XORL) (MOVLconst [c]) x) && isUint32PowerOfTwo(int64(c)) && uint64(c) >= 128
+    => (BT(S|C)Lconst [int8(log32(c))] x)
+
+// Recognize bit clearing: a &^= 1<<b
+(AND(Q|L) (NOT(Q|L) (SHL(Q|L) (MOV(Q|L)const [1]) y)) x) => (BTR(Q|L) x y)
+(ANDN(Q|L) x (SHL(Q|L) (MOV(Q|L)const [1]) y)) => (BTR(Q|L) x y)
+(ANDQconst [c] x) && isUint64PowerOfTwo(int64(^c)) && uint64(^c) >= 128
+    => (BTRQconst [int8(log32(^c))] x)
+(ANDLconst [c] x) && isUint32PowerOfTwo(int64(^c)) && uint64(^c) >= 128
+    => (BTRLconst [int8(log32(^c))] x)
+(ANDQ (MOVQconst [c]) x) && isUint64PowerOfTwo(^c) && uint64(^c) >= 128
+    => (BTRQconst [int8(log64(^c))] x)
+(ANDL (MOVLconst [c]) x) && isUint32PowerOfTwo(int64(^c)) && uint64(^c) >= 128
+    => (BTRLconst [int8(log32(^c))] x)
+
+// Special-case bit patterns on first/last bit.
+// generic.rules changes ANDs of high-part/low-part masks into a couple of shifts,
+// for instance:
+//    x & 0xFFFF0000 -> (x >> 16) << 16
+//    x & 0x80000000 -> (x >> 31) << 31
+//
+// In case the mask is just one bit (like second example above), it conflicts
+// with the above rules to detect bit-testing / bit-clearing of first/last bit.
+// We thus special-case them, by detecting the shift patterns.
+
+// Special case resetting first/last bit
+(SHL(L|Q)const [1] (SHR(L|Q)const [1] x))
+	=> (BTR(L|Q)const [0] x)
+(SHRLconst [1] (SHLLconst [1] x))
+	=> (BTRLconst [31] x)
+(SHRQconst [1] (SHLQconst [1] x))
+	=> (BTRQconst [63] x)
+
+// Special case testing first/last bit (with double-shift generated by generic.rules)
+((SETNE|SETEQ|NE|EQ) (TESTQ z1:(SHLQconst [63] (SHRQconst [63] x)) z2)) && z1==z2
+    => ((SETB|SETAE|ULT|UGE) (BTQconst [63] x))
+((SETNE|SETEQ|NE|EQ) (TESTL z1:(SHLLconst [31] (SHRQconst [31] x)) z2)) && z1==z2
+    => ((SETB|SETAE|ULT|UGE) (BTQconst [31] x))
+(SET(NE|EQ)store [off] {sym} ptr (TESTQ z1:(SHLQconst [63] (SHRQconst [63] x)) z2) mem) && z1==z2
+    => (SET(B|AE)store [off] {sym} ptr (BTQconst [63] x) mem)
+(SET(NE|EQ)store [off] {sym} ptr (TESTL z1:(SHLLconst [31] (SHRLconst [31] x)) z2) mem) && z1==z2
+    => (SET(B|AE)store [off] {sym} ptr (BTLconst [31] x) mem)
+
+((SETNE|SETEQ|NE|EQ) (TESTQ z1:(SHRQconst [63] (SHLQconst [63] x)) z2)) && z1==z2
+    => ((SETB|SETAE|ULT|UGE)  (BTQconst [0] x))
+((SETNE|SETEQ|NE|EQ) (TESTL z1:(SHRLconst [31] (SHLLconst [31] x)) z2)) && z1==z2
+    => ((SETB|SETAE|ULT|UGE)  (BTLconst [0] x))
+(SET(NE|EQ)store [off] {sym} ptr (TESTQ z1:(SHRQconst [63] (SHLQconst [63] x)) z2) mem) && z1==z2
+    => (SET(B|AE)store [off] {sym} ptr (BTQconst [0] x) mem)
+(SET(NE|EQ)store [off] {sym} ptr (TESTL z1:(SHRLconst [31] (SHLLconst [31] x)) z2) mem) && z1==z2
+    => (SET(B|AE)store [off] {sym} ptr (BTLconst [0] x) mem)
+
+// Special-case manually testing last bit with "a>>63 != 0" (without "&1")
+((SETNE|SETEQ|NE|EQ) (TESTQ z1:(SHRQconst [63] x) z2)) && z1==z2
+    => ((SETB|SETAE|ULT|UGE) (BTQconst [63] x))
+((SETNE|SETEQ|NE|EQ) (TESTL z1:(SHRLconst [31] x) z2)) && z1==z2
+    => ((SETB|SETAE|ULT|UGE) (BTLconst [31] x))
+(SET(NE|EQ)store [off] {sym} ptr (TESTQ z1:(SHRQconst [63] x) z2) mem) && z1==z2
+    => (SET(B|AE)store [off] {sym} ptr (BTQconst [63] x) mem)
+(SET(NE|EQ)store [off] {sym} ptr (TESTL z1:(SHRLconst [31] x) z2) mem) && z1==z2
+    => (SET(B|AE)store [off] {sym} ptr (BTLconst [31] x) mem)
+
+// Fold combinations of bit ops on same bit. An example is math.Copysign(c,-1)
+(BTS(Q|L)const [c] (BTR(Q|L)const [c] x)) => (BTS(Q|L)const [c] x)
+(BTS(Q|L)const [c] (BTC(Q|L)const [c] x)) => (BTS(Q|L)const [c] x)
+(BTR(Q|L)const [c] (BTS(Q|L)const [c] x)) => (BTR(Q|L)const [c] x)
+(BTR(Q|L)const [c] (BTC(Q|L)const [c] x)) => (BTR(Q|L)const [c] x)
+
+// Fold boolean negation into SETcc.
+(XORLconst [1] (SETNE x)) => (SETEQ x)
+(XORLconst [1] (SETEQ x)) => (SETNE x)
+(XORLconst [1] (SETL  x)) => (SETGE x)
+(XORLconst [1] (SETGE x)) => (SETL  x)
+(XORLconst [1] (SETLE x)) => (SETG  x)
+(XORLconst [1] (SETG  x)) => (SETLE x)
+(XORLconst [1] (SETB  x)) => (SETAE x)
+(XORLconst [1] (SETAE x)) => (SETB  x)
+(XORLconst [1] (SETBE x)) => (SETA  x)
+(XORLconst [1] (SETA  x)) => (SETBE x)
+
+// Special case for floating point - LF/LEF not generated
+(NE (TESTB (SETGF  cmp) (SETGF  cmp)) yes no) => (UGT  cmp yes no)
+(NE (TESTB (SETGEF cmp) (SETGEF cmp)) yes no) => (UGE  cmp yes no)
+(NE (TESTB (SETEQF cmp) (SETEQF cmp)) yes no) => (EQF  cmp yes no)
+(NE (TESTB (SETNEF cmp) (SETNEF cmp)) yes no) => (NEF  cmp yes no)
+
+// Disabled because it interferes with the pattern match above and makes worse code.
+// (SETNEF x) => (ORQ (SETNE <typ.Int8> x) (SETNAN <typ.Int8> x))
+// (SETEQF x) => (ANDQ (SETEQ <typ.Int8> x) (SETORD <typ.Int8> x))
+
+// fold constants into instructions
+(ADDQ x (MOVQconst [c])) && is32Bit(c) => (ADDQconst [int32(c)] x)
+(ADDQ x (MOVLconst [c])) => (ADDQconst [c] x)
+(ADDL x (MOVLconst [c])) => (ADDLconst [c] x)
+
+(SUBQ x (MOVQconst [c])) && is32Bit(c) => (SUBQconst x [int32(c)])
+(SUBQ (MOVQconst [c]) x) && is32Bit(c) => (NEGQ (SUBQconst <v.Type> x [int32(c)]))
+(SUBL x (MOVLconst [c])) => (SUBLconst x [c])
+(SUBL (MOVLconst [c]) x) => (NEGL (SUBLconst <v.Type> x [c]))
+
+(MULQ x (MOVQconst [c])) && is32Bit(c) => (MULQconst [int32(c)] x)
+(MULL x (MOVLconst [c])) => (MULLconst [c] x)
+
+(ANDQ x (MOVQconst [c])) && is32Bit(c) => (ANDQconst [int32(c)] x)
+(ANDL x (MOVLconst [c])) => (ANDLconst [c] x)
+
+(AND(L|Q)const [c] (AND(L|Q)const [d] x)) => (AND(L|Q)const [c & d] x)
+(XOR(L|Q)const [c] (XOR(L|Q)const [d] x)) => (XOR(L|Q)const [c ^ d] x)
+(OR(L|Q)const  [c] (OR(L|Q)const  [d] x)) => (OR(L|Q)const  [c | d] x)
+
+(BTRLconst [c] (ANDLconst [d] x)) => (ANDLconst [d &^ (1<<uint32(c))] x)
+(ANDLconst [c] (BTRLconst [d] x)) => (ANDLconst [c &^ (1<<uint32(d))] x)
+(BTRLconst [c] (BTRLconst [d] x)) => (ANDLconst [^(1<<uint32(c) | 1<<uint32(d))] x)
+
+(BTCLconst [c] (XORLconst [d] x)) => (XORLconst [d ^ 1<<uint32(c)] x)
+(XORLconst [c] (BTCLconst [d] x)) => (XORLconst [c ^ 1<<uint32(d)] x)
+(BTCLconst [c] (BTCLconst [d] x)) => (XORLconst [1<<uint32(c) | 1<<uint32(d)] x)
+
+(BTSLconst [c] (ORLconst  [d] x)) => (ORLconst [d | 1<<uint32(c)] x)
+(ORLconst  [c] (BTSLconst [d] x)) => (ORLconst [c | 1<<uint32(d)] x)
+(BTSLconst [c] (BTSLconst [d] x)) => (ORLconst [1<<uint32(c) | 1<<uint32(d)] x)
+
+(BTRQconst [c] (ANDQconst [d] x)) && is32Bit(int64(d) &^ (1<<uint32(c)))     => (ANDQconst [d &^ (1<<uint32(c))] x)
+(ANDQconst [c] (BTRQconst [d] x)) && is32Bit(int64(c) &^ (1<<uint32(d)))     => (ANDQconst [c &^ (1<<uint32(d))] x)
+(BTRQconst [c] (BTRQconst [d] x)) && is32Bit(^(1<<uint32(c) | 1<<uint32(d))) => (ANDQconst [^(1<<uint32(c) | 1<<uint32(d))] x)
+
+(BTCQconst [c] (XORQconst [d] x)) && is32Bit(int64(d) ^ 1<<uint32(c))     => (XORQconst [d ^ 1<<uint32(c)] x)
+(XORQconst [c] (BTCQconst [d] x)) && is32Bit(int64(c) ^ 1<<uint32(d))     => (XORQconst [c ^ 1<<uint32(d)] x)
+(BTCQconst [c] (BTCQconst [d] x)) && is32Bit(1<<uint32(c) ^ 1<<uint32(d)) => (XORQconst [1<<uint32(c) ^ 1<<uint32(d)] x)
+
+(BTSQconst [c] (ORQconst  [d] x)) && is32Bit(int64(d) | 1<<uint32(c))     => (ORQconst [d | 1<<uint32(c)] x)
+(ORQconst  [c] (BTSQconst [d] x)) && is32Bit(int64(c) | 1<<uint32(d))     => (ORQconst [c | 1<<uint32(d)] x)
+(BTSQconst [c] (BTSQconst [d] x)) && is32Bit(1<<uint32(c) | 1<<uint32(d)) => (ORQconst [1<<uint32(c) | 1<<uint32(d)] x)
+
+
+(MULLconst [c] (MULLconst [d] x)) => (MULLconst [c * d] x)
+(MULQconst [c] (MULQconst [d] x)) && is32Bit(int64(c)*int64(d)) => (MULQconst [c * d] x)
+
+(ORQ x (MOVQconst [c])) && is32Bit(c) => (ORQconst [int32(c)] x)
+(ORQ x (MOVLconst [c])) => (ORQconst [c] x)
+(ORL x (MOVLconst [c])) => (ORLconst [c] x)
+
+(XORQ x (MOVQconst [c])) && is32Bit(c) => (XORQconst [int32(c)] x)
+(XORL x (MOVLconst [c])) => (XORLconst [c] x)
+
+(SHLQ x (MOV(Q|L)const [c])) => (SHLQconst [int8(c&63)] x)
+(SHLL x (MOV(Q|L)const [c])) => (SHLLconst [int8(c&31)] x)
+
+(SHRQ x (MOV(Q|L)const [c])) => (SHRQconst [int8(c&63)] x)
+(SHRL x (MOV(Q|L)const [c])) => (SHRLconst [int8(c&31)] x)
+(SHRW x (MOV(Q|L)const [c])) && c&31 < 16 => (SHRWconst [int8(c&31)] x)
+(SHRW _ (MOV(Q|L)const [c])) && c&31 >= 16 => (MOVLconst [0])
+(SHRB x (MOV(Q|L)const [c])) && c&31 < 8 => (SHRBconst [int8(c&31)] x)
+(SHRB _ (MOV(Q|L)const [c])) && c&31 >= 8 => (MOVLconst [0])
+
+(SARQ x (MOV(Q|L)const [c])) => (SARQconst [int8(c&63)] x)
+(SARL x (MOV(Q|L)const [c])) => (SARLconst [int8(c&31)] x)
+(SARW x (MOV(Q|L)const [c])) => (SARWconst [int8(min(int64(c)&31,15))] x)
+(SARB x (MOV(Q|L)const [c])) => (SARBconst [int8(min(int64(c)&31,7))] x)
+
+// Operations which don't affect the low 6/5 bits of the shift amount are NOPs.
+((SHLQ|SHRQ|SARQ) x (ADDQconst [c] y)) && c & 63 == 0  => ((SHLQ|SHRQ|SARQ) x y)
+((SHLQ|SHRQ|SARQ) x (NEGQ <t> (ADDQconst [c] y))) && c & 63 == 0  => ((SHLQ|SHRQ|SARQ) x (NEGQ <t> y))
+((SHLQ|SHRQ|SARQ) x (ANDQconst [c] y)) && c & 63 == 63 => ((SHLQ|SHRQ|SARQ) x y)
+((SHLQ|SHRQ|SARQ) x (NEGQ <t> (ANDQconst [c] y))) && c & 63 == 63 => ((SHLQ|SHRQ|SARQ) x (NEGQ <t> y))
+
+((SHLL|SHRL|SARL) x (ADDQconst [c] y)) && c & 31 == 0  => ((SHLL|SHRL|SARL) x y)
+((SHLL|SHRL|SARL) x (NEGQ <t> (ADDQconst [c] y))) && c & 31 == 0  => ((SHLL|SHRL|SARL) x (NEGQ <t> y))
+((SHLL|SHRL|SARL) x (ANDQconst [c] y)) && c & 31 == 31 => ((SHLL|SHRL|SARL) x y)
+((SHLL|SHRL|SARL) x (NEGQ <t> (ANDQconst [c] y))) && c & 31 == 31 => ((SHLL|SHRL|SARL) x (NEGQ <t> y))
+
+((SHLQ|SHRQ|SARQ) x (ADDLconst [c] y)) && c & 63 == 0  => ((SHLQ|SHRQ|SARQ) x y)
+((SHLQ|SHRQ|SARQ) x (NEGL <t> (ADDLconst [c] y))) && c & 63 == 0  => ((SHLQ|SHRQ|SARQ) x (NEGL <t> y))
+((SHLQ|SHRQ|SARQ) x (ANDLconst [c] y)) && c & 63 == 63 => ((SHLQ|SHRQ|SARQ) x y)
+((SHLQ|SHRQ|SARQ) x (NEGL <t> (ANDLconst [c] y))) && c & 63 == 63 => ((SHLQ|SHRQ|SARQ) x (NEGL <t> y))
+
+((SHLL|SHRL|SARL) x (ADDLconst [c] y)) && c & 31 == 0  => ((SHLL|SHRL|SARL) x y)
+((SHLL|SHRL|SARL) x (NEGL <t> (ADDLconst [c] y))) && c & 31 == 0  => ((SHLL|SHRL|SARL) x (NEGL <t> y))
+((SHLL|SHRL|SARL) x (ANDLconst [c] y)) && c & 31 == 31 => ((SHLL|SHRL|SARL) x y)
+((SHLL|SHRL|SARL) x (NEGL <t> (ANDLconst [c] y))) && c & 31 == 31 => ((SHLL|SHRL|SARL) x (NEGL <t> y))
+
+// rotate left negative = rotate right
+(ROLQ x (NEG(Q|L) y)) => (RORQ x y)
+(ROLL x (NEG(Q|L) y)) => (RORL x y)
+(ROLW x (NEG(Q|L) y)) => (RORW x y)
+(ROLB x (NEG(Q|L) y)) => (RORB x y)
+
+// rotate right negative = rotate left
+(RORQ x (NEG(Q|L) y)) => (ROLQ x y)
+(RORL x (NEG(Q|L) y)) => (ROLL x y)
+(RORW x (NEG(Q|L) y)) => (ROLW x y)
+(RORB x (NEG(Q|L) y)) => (ROLB x y)
+
+// rotate by constants
+(ROLQ x (MOV(Q|L)const [c])) => (ROLQconst [int8(c&63)] x)
+(ROLL x (MOV(Q|L)const [c])) => (ROLLconst [int8(c&31)] x)
+(ROLW x (MOV(Q|L)const [c])) => (ROLWconst [int8(c&15)] x)
+(ROLB x (MOV(Q|L)const [c])) => (ROLBconst [int8(c&7) ] x)
+
+(RORQ x (MOV(Q|L)const [c])) => (ROLQconst [int8((-c)&63)] x)
+(RORL x (MOV(Q|L)const [c])) => (ROLLconst [int8((-c)&31)] x)
+(RORW x (MOV(Q|L)const [c])) => (ROLWconst [int8((-c)&15)] x)
+(RORB x (MOV(Q|L)const [c])) => (ROLBconst [int8((-c)&7) ] x)
+
+// Constant shift simplifications
+((SHLQ|SHRQ|SARQ)const      x [0]) => x
+((SHLL|SHRL|SARL)const      x [0]) => x
+((SHRW|SARW)const           x [0]) => x
+((SHRB|SARB)const           x [0]) => x
+((ROLQ|ROLL|ROLW|ROLB)const x [0]) => x
+
+// Multi-register shifts
+(ORQ (SH(R|L)Q lo bits) (SH(L|R)Q hi (NEGQ bits))) => (SH(R|L)DQ lo hi bits)
+(ORQ (SH(R|L)XQ lo bits) (SH(L|R)XQ hi (NEGQ bits))) => (SH(R|L)DQ lo hi bits)
+
+// Note: the word and byte shifts keep the low 5 bits (not the low 4 or 3 bits)
+// because the x86 instructions are defined to use all 5 bits of the shift even
+// for the small shifts. I don't think we'll ever generate a weird shift (e.g.
+// (SHRW x (MOVLconst [24])), but just in case.
+
+(CMPQ x (MOVQconst [c])) && is32Bit(c) => (CMPQconst x [int32(c)])
+(CMPQ (MOVQconst [c]) x) && is32Bit(c) => (InvertFlags (CMPQconst x [int32(c)]))
+(CMPL x (MOVLconst [c])) => (CMPLconst x [c])
+(CMPL (MOVLconst [c]) x) => (InvertFlags (CMPLconst x [c]))
+(CMPW x (MOVLconst [c])) => (CMPWconst x [int16(c)])
+(CMPW (MOVLconst [c]) x) => (InvertFlags (CMPWconst x [int16(c)]))
+(CMPB x (MOVLconst [c])) => (CMPBconst x [int8(c)])
+(CMPB (MOVLconst [c]) x) => (InvertFlags (CMPBconst x [int8(c)]))
+
+// Canonicalize the order of arguments to comparisons - helps with CSE.
+(CMP(Q|L|W|B) x y) && canonLessThan(x,y) => (InvertFlags (CMP(Q|L|W|B) y x))
+
+// Using MOVZX instead of AND is cheaper.
+(AND(Q|L)const [  0xFF] x) => (MOVBQZX x)
+(AND(Q|L)const [0xFFFF] x) => (MOVWQZX x)
+// This rule is currently invalid because 0xFFFFFFFF is not representable by a signed int32.
+// Commenting out for now, because it also can't trigger because of the is32bit guard on the
+// ANDQconst lowering-rule, above, prevents 0xFFFFFFFF from matching (for the same reason)
+// Using an alternate form of this rule segfaults some binaries because of
+// adverse interactions with other passes.
+// (ANDQconst [0xFFFFFFFF] x) => (MOVLQZX x)
+
+// strength reduction
+// Assumes that the following costs from https://gmplib.org/~tege/x86-timing.pdf:
+//    1 - addq, shlq, leaq, negq, subq
+//    3 - imulq
+// This limits the rewrites to two instructions.
+// Note that negq always operates in-place,
+// which can require a register-register move
+// to preserve the original value,
+// so it must be used with care.
+(MUL(Q|L)const [-9] x) => (NEG(Q|L) (LEA(Q|L)8 <v.Type> x x))
+(MUL(Q|L)const [-5] x) => (NEG(Q|L) (LEA(Q|L)4 <v.Type> x x))
+(MUL(Q|L)const [-3] x) => (NEG(Q|L) (LEA(Q|L)2 <v.Type> x x))
+(MUL(Q|L)const [-1] x) => (NEG(Q|L) x)
+(MUL(Q|L)const [ 0] _) => (MOV(Q|L)const [0])
+(MUL(Q|L)const [ 1] x) => x
+(MUL(Q|L)const [ 3] x) => (LEA(Q|L)2 x x)
+(MUL(Q|L)const [ 5] x) => (LEA(Q|L)4 x x)
+(MUL(Q|L)const [ 7] x) => (LEA(Q|L)2 x (LEA(Q|L)2 <v.Type> x x))
+(MUL(Q|L)const [ 9] x) => (LEA(Q|L)8 x x)
+(MUL(Q|L)const [11] x) => (LEA(Q|L)2 x (LEA(Q|L)4 <v.Type> x x))
+(MUL(Q|L)const [13] x) => (LEA(Q|L)4 x (LEA(Q|L)2 <v.Type> x x))
+(MUL(Q|L)const [19] x) => (LEA(Q|L)2 x (LEA(Q|L)8 <v.Type> x x))
+(MUL(Q|L)const [21] x) => (LEA(Q|L)4 x (LEA(Q|L)4 <v.Type> x x))
+(MUL(Q|L)const [25] x) => (LEA(Q|L)8 x (LEA(Q|L)2 <v.Type> x x))
+(MUL(Q|L)const [27] x) => (LEA(Q|L)8 (LEA(Q|L)2 <v.Type> x x) (LEA(Q|L)2 <v.Type> x x))
+(MUL(Q|L)const [37] x) => (LEA(Q|L)4 x (LEA(Q|L)8 <v.Type> x x))
+(MUL(Q|L)const [41] x) => (LEA(Q|L)8 x (LEA(Q|L)4 <v.Type> x x))
+(MUL(Q|L)const [45] x) => (LEA(Q|L)8 (LEA(Q|L)4 <v.Type> x x) (LEA(Q|L)4 <v.Type> x x))
+(MUL(Q|L)const [73] x) => (LEA(Q|L)8 x (LEA(Q|L)8 <v.Type> x x))
+(MUL(Q|L)const [81] x) => (LEA(Q|L)8 (LEA(Q|L)8 <v.Type> x x) (LEA(Q|L)8 <v.Type> x x))
+
+(MUL(Q|L)const [c] x) && isPowerOfTwo64(int64(c)+1) && c >=  15 => (SUB(Q|L)  (SHL(Q|L)const <v.Type> [int8(log64(int64(c)+1))] x) x)
+(MUL(Q|L)const [c] x) && isPowerOfTwo32(c-1) && c >=  17 => (LEA(Q|L)1 (SHL(Q|L)const <v.Type> [int8(log32(c-1))] x) x)
+(MUL(Q|L)const [c] x) && isPowerOfTwo32(c-2) && c >=  34 => (LEA(Q|L)2 (SHL(Q|L)const <v.Type> [int8(log32(c-2))] x) x)
+(MUL(Q|L)const [c] x) && isPowerOfTwo32(c-4) && c >=  68 => (LEA(Q|L)4 (SHL(Q|L)const <v.Type> [int8(log32(c-4))] x) x)
+(MUL(Q|L)const [c] x) && isPowerOfTwo32(c-8) && c >= 136 => (LEA(Q|L)8 (SHL(Q|L)const <v.Type> [int8(log32(c-8))] x) x)
+(MUL(Q|L)const [c] x) && c%3 == 0 && isPowerOfTwo32(c/3) => (SHL(Q|L)const [int8(log32(c/3))] (LEA(Q|L)2 <v.Type> x x))
+(MUL(Q|L)const [c] x) && c%5 == 0 && isPowerOfTwo32(c/5) => (SHL(Q|L)const [int8(log32(c/5))] (LEA(Q|L)4 <v.Type> x x))
+(MUL(Q|L)const [c] x) && c%9 == 0 && isPowerOfTwo32(c/9) => (SHL(Q|L)const [int8(log32(c/9))] (LEA(Q|L)8 <v.Type> x x))
+
+// combine add/shift into LEAQ/LEAL
+(ADD(L|Q) x (SHL(L|Q)const [3] y)) => (LEA(L|Q)8 x y)
+(ADD(L|Q) x (SHL(L|Q)const [2] y)) => (LEA(L|Q)4 x y)
+(ADD(L|Q) x (SHL(L|Q)const [1] y)) => (LEA(L|Q)2 x y)
+(ADD(L|Q) x (ADD(L|Q) y y))        => (LEA(L|Q)2 x y)
+(ADD(L|Q) x (ADD(L|Q) x y))        => (LEA(L|Q)2 y x)
+
+// combine ADDQ/ADDQconst into LEAQ1/LEAL1
+(ADD(Q|L)const [c] (ADD(Q|L) x y)) => (LEA(Q|L)1 [c] x y)
+(ADD(Q|L) (ADD(Q|L)const [c] x) y) => (LEA(Q|L)1 [c] x y)
+(ADD(Q|L)const [c] (SHL(Q|L)const [1] x)) => (LEA(Q|L)1 [c] x x)
+
+// fold ADDQ/ADDL into LEAQ/LEAL
+(ADD(Q|L)const [c] (LEA(Q|L) [d] {s} x)) && is32Bit(int64(c)+int64(d)) => (LEA(Q|L) [c+d] {s} x)
+(LEA(Q|L) [c] {s} (ADD(Q|L)const [d] x)) && is32Bit(int64(c)+int64(d)) => (LEA(Q|L) [c+d] {s} x)
+(LEA(Q|L) [c] {s} (ADD(Q|L) x y)) && x.Op != OpSB && y.Op != OpSB => (LEA(Q|L)1 [c] {s} x y)
+(ADD(Q|L) x (LEA(Q|L) [c] {s} y)) && x.Op != OpSB && y.Op != OpSB => (LEA(Q|L)1 [c] {s} x y)
+
+// fold ADDQconst/ADDLconst into LEAQx/LEALx
+(ADD(Q|L)const [c] (LEA(Q|L)1 [d] {s} x y)) && is32Bit(int64(c)+int64(d)) => (LEA(Q|L)1 [c+d] {s} x y)
+(ADD(Q|L)const [c] (LEA(Q|L)2 [d] {s} x y)) && is32Bit(int64(c)+int64(d)) => (LEA(Q|L)2 [c+d] {s} x y)
+(ADD(Q|L)const [c] (LEA(Q|L)4 [d] {s} x y)) && is32Bit(int64(c)+int64(d)) => (LEA(Q|L)4 [c+d] {s} x y)
+(ADD(Q|L)const [c] (LEA(Q|L)8 [d] {s} x y)) && is32Bit(int64(c)+int64(d)) => (LEA(Q|L)8 [c+d] {s} x y)
+(LEA(Q|L)1 [c] {s} (ADD(Q|L)const [d] x) y) && is32Bit(int64(c)+int64(d))   && x.Op != OpSB => (LEA(Q|L)1 [c+d] {s} x y)
+(LEA(Q|L)2 [c] {s} (ADD(Q|L)const [d] x) y) && is32Bit(int64(c)+int64(d))   && x.Op != OpSB => (LEA(Q|L)2 [c+d] {s} x y)
+(LEA(Q|L)2 [c] {s} x (ADD(Q|L)const [d] y)) && is32Bit(int64(c)+2*int64(d)) && y.Op != OpSB => (LEA(Q|L)2 [c+2*d] {s} x y)
+(LEA(Q|L)4 [c] {s} (ADD(Q|L)const [d] x) y) && is32Bit(int64(c)+int64(d))   && x.Op != OpSB => (LEA(Q|L)4 [c+d] {s} x y)
+(LEA(Q|L)4 [c] {s} x (ADD(Q|L)const [d] y)) && is32Bit(int64(c)+4*int64(d)) && y.Op != OpSB => (LEA(Q|L)4 [c+4*d] {s} x y)
+(LEA(Q|L)8 [c] {s} (ADD(Q|L)const [d] x) y) && is32Bit(int64(c)+int64(d))   && x.Op != OpSB => (LEA(Q|L)8 [c+d] {s} x y)
+(LEA(Q|L)8 [c] {s} x (ADD(Q|L)const [d] y)) && is32Bit(int64(c)+8*int64(d)) && y.Op != OpSB => (LEA(Q|L)8 [c+8*d] {s} x y)
+
+// fold shifts into LEAQx/LEALx
+(LEA(Q|L)1 [c] {s} x (SHL(Q|L)const [1] y)) => (LEA(Q|L)2 [c] {s} x y)
+(LEA(Q|L)1 [c] {s} x (SHL(Q|L)const [2] y)) => (LEA(Q|L)4 [c] {s} x y)
+(LEA(Q|L)1 [c] {s} x (SHL(Q|L)const [3] y)) => (LEA(Q|L)8 [c] {s} x y)
+(LEA(Q|L)2 [c] {s} x (SHL(Q|L)const [1] y)) => (LEA(Q|L)4 [c] {s} x y)
+(LEA(Q|L)2 [c] {s} x (SHL(Q|L)const [2] y)) => (LEA(Q|L)8 [c] {s} x y)
+(LEA(Q|L)4 [c] {s} x (SHL(Q|L)const [1] y)) => (LEA(Q|L)8 [c] {s} x y)
+
+// reverse ordering of compare instruction
+(SETL (InvertFlags x)) => (SETG x)
+(SETG (InvertFlags x)) => (SETL x)
+(SETB (InvertFlags x)) => (SETA x)
+(SETA (InvertFlags x)) => (SETB x)
+(SETLE (InvertFlags x)) => (SETGE x)
+(SETGE (InvertFlags x)) => (SETLE x)
+(SETBE (InvertFlags x)) => (SETAE x)
+(SETAE (InvertFlags x)) => (SETBE x)
+(SETEQ (InvertFlags x)) => (SETEQ x)
+(SETNE (InvertFlags x)) => (SETNE x)
+
+(SETLstore [off] {sym} ptr (InvertFlags x) mem) => (SETGstore [off] {sym} ptr x mem)
+(SETGstore [off] {sym} ptr (InvertFlags x) mem) => (SETLstore [off] {sym} ptr x mem)
+(SETBstore [off] {sym} ptr (InvertFlags x) mem) => (SETAstore [off] {sym} ptr x mem)
+(SETAstore [off] {sym} ptr (InvertFlags x) mem) => (SETBstore [off] {sym} ptr x mem)
+(SETLEstore [off] {sym} ptr (InvertFlags x) mem) => (SETGEstore [off] {sym} ptr x mem)
+(SETGEstore [off] {sym} ptr (InvertFlags x) mem) => (SETLEstore [off] {sym} ptr x mem)
+(SETBEstore [off] {sym} ptr (InvertFlags x) mem) => (SETAEstore [off] {sym} ptr x mem)
+(SETAEstore [off] {sym} ptr (InvertFlags x) mem) => (SETBEstore [off] {sym} ptr x mem)
+(SETEQstore [off] {sym} ptr (InvertFlags x) mem) => (SETEQstore [off] {sym} ptr x mem)
+(SETNEstore [off] {sym} ptr (InvertFlags x) mem) => (SETNEstore [off] {sym} ptr x mem)
+
+// sign extended loads
+// Note: The combined instruction must end up in the same block
+// as the original load. If not, we end up making a value with
+// memory type live in two different blocks, which can lead to
+// multiple memory values alive simultaneously.
+// Make sure we don't combine these ops if the load has another use.
+// This prevents a single load from being split into multiple loads
+// which then might return different values.  See test/atomicload.go.
+(MOVBQSX x:(MOVBload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVBQSXload <v.Type> [off] {sym} ptr mem)
+(MOVBQSX x:(MOVWload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVBQSXload <v.Type> [off] {sym} ptr mem)
+(MOVBQSX x:(MOVLload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVBQSXload <v.Type> [off] {sym} ptr mem)
+(MOVBQSX x:(MOVQload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVBQSXload <v.Type> [off] {sym} ptr mem)
+(MOVBQZX x:(MOVBload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVBload <v.Type> [off] {sym} ptr mem)
+(MOVBQZX x:(MOVWload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVBload <v.Type> [off] {sym} ptr mem)
+(MOVBQZX x:(MOVLload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVBload <v.Type> [off] {sym} ptr mem)
+(MOVBQZX x:(MOVQload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVBload <v.Type> [off] {sym} ptr mem)
+(MOVWQSX x:(MOVWload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVWQSXload <v.Type> [off] {sym} ptr mem)
+(MOVWQSX x:(MOVLload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVWQSXload <v.Type> [off] {sym} ptr mem)
+(MOVWQSX x:(MOVQload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVWQSXload <v.Type> [off] {sym} ptr mem)
+(MOVWQZX x:(MOVWload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVWload <v.Type> [off] {sym} ptr mem)
+(MOVWQZX x:(MOVLload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVWload <v.Type> [off] {sym} ptr mem)
+(MOVWQZX x:(MOVQload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVWload <v.Type> [off] {sym} ptr mem)
+(MOVLQSX x:(MOVLload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVLQSXload <v.Type> [off] {sym} ptr mem)
+(MOVLQSX x:(MOVQload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVLQSXload <v.Type> [off] {sym} ptr mem)
+(MOVLQZX x:(MOVLload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVLload <v.Type> [off] {sym} ptr mem)
+(MOVLQZX x:(MOVQload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVLload <v.Type> [off] {sym} ptr mem)
+
+(MOVLQZX x) && zeroUpper32Bits(x,3) => x
+(MOVWQZX x) && zeroUpper48Bits(x,3) => x
+(MOVBQZX x) && zeroUpper56Bits(x,3) => x
+
+// replace load from same location as preceding store with zero/sign extension (or copy in case of full width)
+(MOVBload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVBQZX x)
+(MOVWload [off] {sym} ptr (MOVWstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVWQZX x)
+(MOVLload [off] {sym} ptr (MOVLstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVLQZX x)
+(MOVQload [off] {sym} ptr (MOVQstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => x
+(MOVBQSXload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVBQSX x)
+(MOVWQSXload [off] {sym} ptr (MOVWstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVWQSX x)
+(MOVLQSXload [off] {sym} ptr (MOVLstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVLQSX x)
+
+// Fold extensions and ANDs together.
+(MOVBQZX (ANDLconst [c] x)) => (ANDLconst [c & 0xff] x)
+(MOVWQZX (ANDLconst [c] x)) => (ANDLconst [c & 0xffff] x)
+(MOVLQZX (ANDLconst [c] x)) => (ANDLconst [c] x)
+(MOVBQSX (ANDLconst [c] x)) && c & 0x80 == 0 => (ANDLconst [c & 0x7f] x)
+(MOVWQSX (ANDLconst [c] x)) && c & 0x8000 == 0 => (ANDLconst [c & 0x7fff] x)
+(MOVLQSX (ANDLconst [c] x)) && uint32(c) & 0x80000000 == 0 => (ANDLconst [c & 0x7fffffff] x)
+
+// Don't extend before storing
+(MOVLstore [off] {sym} ptr (MOVLQSX x) mem) => (MOVLstore [off] {sym} ptr x mem)
+(MOVWstore [off] {sym} ptr (MOVWQSX x) mem) => (MOVWstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr (MOVBQSX x) mem) => (MOVBstore [off] {sym} ptr x mem)
+(MOVLstore [off] {sym} ptr (MOVLQZX x) mem) => (MOVLstore [off] {sym} ptr x mem)
+(MOVWstore [off] {sym} ptr (MOVWQZX x) mem) => (MOVWstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr (MOVBQZX x) mem) => (MOVBstore [off] {sym} ptr x mem)
+
+// fold constants into memory operations
+// Note that this is not always a good idea because if not all the uses of
+// the ADDQconst get eliminated, we still have to compute the ADDQconst and we now
+// have potentially two live values (ptr and (ADDQconst [off] ptr)) instead of one.
+// Nevertheless, let's do it!
+(MOV(Q|L|W|B|SS|SD|O)load  [off1] {sym} (ADDQconst [off2] ptr) mem) && is32Bit(int64(off1)+int64(off2)) =>
+    (MOV(Q|L|W|B|SS|SD|O)load  [off1+off2] {sym} ptr mem)
+(MOV(Q|L|W|B|SS|SD|O)store  [off1] {sym} (ADDQconst [off2] ptr) val mem) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOV(Q|L|W|B|SS|SD|O)store  [off1+off2] {sym} ptr val mem)
+(SET(L|G|B|A|LE|GE|BE|AE|EQ|NE)store [off1] {sym} (ADDQconst [off2] base) val mem) && is32Bit(int64(off1)+int64(off2)) =>
+	(SET(L|G|B|A|LE|GE|BE|AE|EQ|NE)store [off1+off2] {sym} base val mem)
+((ADD|SUB|AND|OR|XOR)Qload [off1] {sym} val (ADDQconst [off2] base) mem) && is32Bit(int64(off1)+int64(off2)) =>
+	((ADD|SUB|AND|OR|XOR)Qload [off1+off2] {sym} val base mem)
+((ADD|SUB|AND|OR|XOR)Lload [off1] {sym} val (ADDQconst [off2] base) mem) && is32Bit(int64(off1)+int64(off2)) =>
+	((ADD|SUB|AND|OR|XOR)Lload [off1+off2] {sym} val base mem)
+(CMP(Q|L|W|B)load [off1] {sym} (ADDQconst [off2] base) val mem) && is32Bit(int64(off1)+int64(off2)) =>
+	(CMP(Q|L|W|B)load [off1+off2] {sym} base val mem)
+(CMP(Q|L|W|B)constload [valoff1] {sym} (ADDQconst [off2] base) mem) && ValAndOff(valoff1).canAdd32(off2) =>
+	(CMP(Q|L|W|B)constload [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem)
+
+((ADD|SUB|MUL|DIV)SSload [off1] {sym} val (ADDQconst [off2] base) mem) && is32Bit(int64(off1)+int64(off2)) =>
+	((ADD|SUB|MUL|DIV)SSload [off1+off2] {sym} val base mem)
+((ADD|SUB|MUL|DIV)SDload [off1] {sym} val (ADDQconst [off2] base) mem) && is32Bit(int64(off1)+int64(off2)) =>
+	((ADD|SUB|MUL|DIV)SDload [off1+off2] {sym} val base mem)
+((ADD|AND|OR|XOR)Qconstmodify [valoff1] {sym} (ADDQconst [off2] base) mem) && ValAndOff(valoff1).canAdd32(off2) =>
+	((ADD|AND|OR|XOR)Qconstmodify [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem)
+((ADD|AND|OR|XOR)Lconstmodify [valoff1] {sym} (ADDQconst [off2] base) mem) && ValAndOff(valoff1).canAdd32(off2) =>
+	((ADD|AND|OR|XOR)Lconstmodify [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem)
+((ADD|SUB|AND|OR|XOR)Qmodify [off1] {sym} (ADDQconst [off2] base) val mem) && is32Bit(int64(off1)+int64(off2)) =>
+	((ADD|SUB|AND|OR|XOR)Qmodify [off1+off2] {sym} base val mem)
+((ADD|SUB|AND|OR|XOR)Lmodify [off1] {sym} (ADDQconst [off2] base) val mem) && is32Bit(int64(off1)+int64(off2)) =>
+	((ADD|SUB|AND|OR|XOR)Lmodify [off1+off2] {sym} base val mem)
+
+// Fold constants into stores.
+(MOVQstore [off] {sym} ptr (MOVQconst [c]) mem) && validVal(c) =>
+	(MOVQstoreconst [makeValAndOff(int32(c),off)] {sym} ptr mem)
+(MOVLstore [off] {sym} ptr (MOV(L|Q)const [c]) mem) =>
+	(MOVLstoreconst [makeValAndOff(int32(c),off)] {sym} ptr mem)
+(MOVWstore [off] {sym} ptr (MOV(L|Q)const [c]) mem) =>
+	(MOVWstoreconst [makeValAndOff(int32(int16(c)),off)] {sym} ptr mem)
+(MOVBstore [off] {sym} ptr (MOV(L|Q)const [c]) mem) =>
+	(MOVBstoreconst [makeValAndOff(int32(int8(c)),off)] {sym} ptr mem)
+
+// Fold address offsets into constant stores.
+(MOV(Q|L|W|B|O)storeconst [sc] {s} (ADDQconst [off] ptr) mem) && ValAndOff(sc).canAdd32(off) =>
+	(MOV(Q|L|W|B|O)storeconst [ValAndOff(sc).addOffset32(off)] {s} ptr mem)
+
+// We need to fold LEAQ into the MOVx ops so that the live variable analysis knows
+// what variables are being read/written by the ops.
+(MOV(Q|L|W|B|SS|SD|O|BQSX|WQSX|LQSX)load [off1] {sym1} (LEAQ [off2] {sym2} base) mem)
+	&& is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+	(MOV(Q|L|W|B|SS|SD|O|BQSX|WQSX|LQSX)load [off1+off2] {mergeSym(sym1,sym2)} base mem)
+(MOV(Q|L|W|B|SS|SD|O)store [off1] {sym1} (LEAQ [off2] {sym2} base) val mem)
+	&& is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+	(MOV(Q|L|W|B|SS|SD|O)store [off1+off2] {mergeSym(sym1,sym2)} base val mem)
+(MOV(Q|L|W|B|O)storeconst [sc] {sym1} (LEAQ [off] {sym2} ptr) mem) && canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd32(off) =>
+	(MOV(Q|L|W|B|O)storeconst [ValAndOff(sc).addOffset32(off)] {mergeSym(sym1, sym2)} ptr mem)
+(SET(L|G|B|A|LE|GE|BE|AE|EQ|NE)store [off1] {sym1} (LEAQ [off2] {sym2} base) val mem)
+	&& is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+	(SET(L|G|B|A|LE|GE|BE|AE|EQ|NE)store [off1+off2] {mergeSym(sym1,sym2)} base val mem)
+((ADD|SUB|AND|OR|XOR)Qload [off1] {sym1} val (LEAQ [off2] {sym2} base) mem)
+	&& is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+	((ADD|SUB|AND|OR|XOR)Qload [off1+off2] {mergeSym(sym1,sym2)} val base mem)
+((ADD|SUB|AND|OR|XOR)Lload [off1] {sym1} val (LEAQ [off2] {sym2} base) mem)
+	&& is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+	((ADD|SUB|AND|OR|XOR)Lload [off1+off2] {mergeSym(sym1,sym2)} val base mem)
+(CMP(Q|L|W|B)load [off1] {sym1} (LEAQ [off2] {sym2} base) val mem)
+	&& is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+	(CMP(Q|L|W|B)load [off1+off2] {mergeSym(sym1,sym2)} base val mem)
+(CMP(Q|L|W|B)constload [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem)
+	&& ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2) =>
+	(CMP(Q|L|W|B)constload [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem)
+
+((ADD|SUB|MUL|DIV)SSload [off1] {sym1} val (LEAQ [off2] {sym2} base) mem)
+	&& is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+	((ADD|SUB|MUL|DIV)SSload [off1+off2] {mergeSym(sym1,sym2)} val base mem)
+((ADD|SUB|MUL|DIV)SDload [off1] {sym1} val (LEAQ [off2] {sym2} base) mem)
+	&& is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+	((ADD|SUB|MUL|DIV)SDload [off1+off2] {mergeSym(sym1,sym2)} val base mem)
+((ADD|AND|OR|XOR)Qconstmodify [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem)
+	&& ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2) =>
+	((ADD|AND|OR|XOR)Qconstmodify [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem)
+((ADD|AND|OR|XOR)Lconstmodify [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem)
+	&& ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2) =>
+	((ADD|AND|OR|XOR)Lconstmodify [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem)
+((ADD|SUB|AND|OR|XOR)Qmodify [off1] {sym1} (LEAQ [off2] {sym2} base) val mem)
+	&& is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+	((ADD|SUB|AND|OR|XOR)Qmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem)
+((ADD|SUB|AND|OR|XOR)Lmodify [off1] {sym1} (LEAQ [off2] {sym2} base) val mem)
+	&& is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+	((ADD|SUB|AND|OR|XOR)Lmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem)
+
+// fold LEAQs together
+(LEAQ [off1] {sym1} (LEAQ [off2] {sym2} x)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+      (LEAQ [off1+off2] {mergeSym(sym1,sym2)} x)
+
+// LEAQ into LEAQ1
+(LEAQ1 [off1] {sym1} (LEAQ [off2] {sym2} x) y) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB =>
+       (LEAQ1 [off1+off2] {mergeSym(sym1,sym2)} x y)
+
+// LEAQ1 into LEAQ
+(LEAQ [off1] {sym1} (LEAQ1 [off2] {sym2} x y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+       (LEAQ1 [off1+off2] {mergeSym(sym1,sym2)} x y)
+
+// LEAQ into LEAQ[248]
+(LEAQ2 [off1] {sym1} (LEAQ [off2] {sym2} x) y) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB =>
+       (LEAQ2 [off1+off2] {mergeSym(sym1,sym2)} x y)
+(LEAQ4 [off1] {sym1} (LEAQ [off2] {sym2} x) y) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB =>
+       (LEAQ4 [off1+off2] {mergeSym(sym1,sym2)} x y)
+(LEAQ8 [off1] {sym1} (LEAQ [off2] {sym2} x) y) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB =>
+       (LEAQ8 [off1+off2] {mergeSym(sym1,sym2)} x y)
+
+// LEAQ[248] into LEAQ
+(LEAQ [off1] {sym1} (LEAQ2 [off2] {sym2} x y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+      (LEAQ2 [off1+off2] {mergeSym(sym1,sym2)} x y)
+(LEAQ [off1] {sym1} (LEAQ4 [off2] {sym2} x y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+      (LEAQ4 [off1+off2] {mergeSym(sym1,sym2)} x y)
+(LEAQ [off1] {sym1} (LEAQ8 [off2] {sym2} x y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+      (LEAQ8 [off1+off2] {mergeSym(sym1,sym2)} x y)
+
+// LEAQ[1248] into LEAQ[1248]. Only some such merges are possible.
+(LEAQ1 [off1] {sym1} x (LEAQ1 [off2] {sym2} y y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+      (LEAQ2 [off1+off2] {mergeSym(sym1, sym2)} x y)
+(LEAQ1 [off1] {sym1} x (LEAQ1 [off2] {sym2} x y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+      (LEAQ2 [off1+off2] {mergeSym(sym1, sym2)} y x)
+(LEAQ2 [off1] {sym1} x (LEAQ1 [off2] {sym2} y y)) && is32Bit(int64(off1)+2*int64(off2)) && sym2 == nil =>
+      (LEAQ4 [off1+2*off2] {sym1} x y)
+(LEAQ4 [off1] {sym1} x (LEAQ1 [off2] {sym2} y y)) && is32Bit(int64(off1)+4*int64(off2)) && sym2 == nil =>
+      (LEAQ8 [off1+4*off2] {sym1} x y)
+// TODO: more?
+
+// Lower LEAQ2/4/8 when the offset is a constant
+(LEAQ2 [off] {sym} x (MOV(Q|L)const [scale])) && is32Bit(int64(off)+int64(scale)*2) =>
+	(LEAQ [off+int32(scale)*2] {sym} x)
+(LEAQ4 [off] {sym} x (MOV(Q|L)const [scale])) && is32Bit(int64(off)+int64(scale)*4) =>
+	(LEAQ [off+int32(scale)*4] {sym} x)
+(LEAQ8 [off] {sym} x (MOV(Q|L)const [scale])) && is32Bit(int64(off)+int64(scale)*8) =>
+	(LEAQ [off+int32(scale)*8] {sym} x)
+
+// Absorb InvertFlags into branches.
+(LT (InvertFlags cmp) yes no) => (GT cmp yes no)
+(GT (InvertFlags cmp) yes no) => (LT cmp yes no)
+(LE (InvertFlags cmp) yes no) => (GE cmp yes no)
+(GE (InvertFlags cmp) yes no) => (LE cmp yes no)
+(ULT (InvertFlags cmp) yes no) => (UGT cmp yes no)
+(UGT (InvertFlags cmp) yes no) => (ULT cmp yes no)
+(ULE (InvertFlags cmp) yes no) => (UGE cmp yes no)
+(UGE (InvertFlags cmp) yes no) => (ULE cmp yes no)
+(EQ (InvertFlags cmp) yes no) => (EQ cmp yes no)
+(NE (InvertFlags cmp) yes no) => (NE cmp yes no)
+
+// Constant comparisons.
+(CMPQconst (MOVQconst [x]) [y]) && x==int64(y) => (FlagEQ)
+(CMPQconst (MOVQconst [x]) [y]) && x<int64(y) && uint64(x)<uint64(int64(y)) => (FlagLT_ULT)
+(CMPQconst (MOVQconst [x]) [y]) && x<int64(y) && uint64(x)>uint64(int64(y)) => (FlagLT_UGT)
+(CMPQconst (MOVQconst [x]) [y]) && x>int64(y) && uint64(x)<uint64(int64(y)) => (FlagGT_ULT)
+(CMPQconst (MOVQconst [x]) [y]) && x>int64(y) && uint64(x)>uint64(int64(y)) => (FlagGT_UGT)
+(CMPLconst (MOVLconst [x]) [y]) && x==y => (FlagEQ)
+(CMPLconst (MOVLconst [x]) [y]) && x<y && uint32(x)<uint32(y) => (FlagLT_ULT)
+(CMPLconst (MOVLconst [x]) [y]) && x<y && uint32(x)>uint32(y) => (FlagLT_UGT)
+(CMPLconst (MOVLconst [x]) [y]) && x>y && uint32(x)<uint32(y) => (FlagGT_ULT)
+(CMPLconst (MOVLconst [x]) [y]) && x>y && uint32(x)>uint32(y) => (FlagGT_UGT)
+(CMPWconst (MOVLconst [x]) [y]) && int16(x)==y => (FlagEQ)
+(CMPWconst (MOVLconst [x]) [y]) && int16(x)<y && uint16(x)<uint16(y) => (FlagLT_ULT)
+(CMPWconst (MOVLconst [x]) [y]) && int16(x)<y && uint16(x)>uint16(y) => (FlagLT_UGT)
+(CMPWconst (MOVLconst [x]) [y]) && int16(x)>y && uint16(x)<uint16(y) => (FlagGT_ULT)
+(CMPWconst (MOVLconst [x]) [y]) && int16(x)>y && uint16(x)>uint16(y) => (FlagGT_UGT)
+(CMPBconst (MOVLconst [x]) [y]) && int8(x)==y => (FlagEQ)
+(CMPBconst (MOVLconst [x]) [y]) && int8(x)<y && uint8(x)<uint8(y) => (FlagLT_ULT)
+(CMPBconst (MOVLconst [x]) [y]) && int8(x)<y && uint8(x)>uint8(y) => (FlagLT_UGT)
+(CMPBconst (MOVLconst [x]) [y]) && int8(x)>y && uint8(x)<uint8(y) => (FlagGT_ULT)
+(CMPBconst (MOVLconst [x]) [y]) && int8(x)>y && uint8(x)>uint8(y) => (FlagGT_UGT)
+
+// CMPQconst requires a 32 bit const, but we can still constant-fold 64 bit consts.
+// In theory this applies to any of the simplifications above,
+// but CMPQ is the only one I've actually seen occur.
+(CMPQ (MOVQconst [x]) (MOVQconst [y])) && x==y => (FlagEQ)
+(CMPQ (MOVQconst [x]) (MOVQconst [y])) && x<y && uint64(x)<uint64(y) => (FlagLT_ULT)
+(CMPQ (MOVQconst [x]) (MOVQconst [y])) && x<y && uint64(x)>uint64(y) => (FlagLT_UGT)
+(CMPQ (MOVQconst [x]) (MOVQconst [y])) && x>y && uint64(x)<uint64(y) => (FlagGT_ULT)
+(CMPQ (MOVQconst [x]) (MOVQconst [y])) && x>y && uint64(x)>uint64(y) => (FlagGT_UGT)
+
+// Other known comparisons.
+(CMPQconst (MOVBQZX _) [c]) && 0xFF < c => (FlagLT_ULT)
+(CMPQconst (MOVWQZX _) [c]) && 0xFFFF < c => (FlagLT_ULT)
+(CMPLconst (SHRLconst _ [c]) [n]) && 0 <= n && 0 < c && c <= 32 && (1<<uint64(32-c)) <= uint64(n) => (FlagLT_ULT)
+(CMPQconst (SHRQconst _ [c]) [n]) && 0 <= n && 0 < c && c <= 64 && (1<<uint64(64-c)) <= uint64(n) => (FlagLT_ULT)
+(CMPQconst (ANDQconst _ [m]) [n]) && 0 <= m && m < n => (FlagLT_ULT)
+(CMPQconst (ANDLconst _ [m]) [n]) && 0 <= m && m < n => (FlagLT_ULT)
+(CMPLconst (ANDLconst _ [m]) [n]) && 0 <= m && m < n => (FlagLT_ULT)
+(CMPWconst (ANDLconst _ [m]) [n]) && 0 <= int16(m) && int16(m) < n => (FlagLT_ULT)
+(CMPBconst (ANDLconst _ [m]) [n]) && 0 <= int8(m)  && int8(m)  < n => (FlagLT_ULT)
+
+// TESTQ c c sets flags like CMPQ c 0.
+(TESTQconst [c] (MOVQconst [d])) && int64(c) == d && c == 0 => (FlagEQ)
+(TESTLconst [c] (MOVLconst [c])) && c == 0 => (FlagEQ)
+(TESTQconst [c] (MOVQconst [d])) && int64(c) == d && c < 0  => (FlagLT_UGT)
+(TESTLconst [c] (MOVLconst [c])) && c < 0  => (FlagLT_UGT)
+(TESTQconst [c] (MOVQconst [d])) && int64(c) == d && c > 0  => (FlagGT_UGT)
+(TESTLconst [c] (MOVLconst [c])) && c > 0  => (FlagGT_UGT)
+
+// TODO: DIVxU also.
+
+// Absorb flag constants into SBB ops.
+(SBBQcarrymask (FlagEQ))     => (MOVQconst [0])
+(SBBQcarrymask (FlagLT_ULT)) => (MOVQconst [-1])
+(SBBQcarrymask (FlagLT_UGT)) => (MOVQconst [0])
+(SBBQcarrymask (FlagGT_ULT)) => (MOVQconst [-1])
+(SBBQcarrymask (FlagGT_UGT)) => (MOVQconst [0])
+(SBBLcarrymask (FlagEQ))     => (MOVLconst [0])
+(SBBLcarrymask (FlagLT_ULT)) => (MOVLconst [-1])
+(SBBLcarrymask (FlagLT_UGT)) => (MOVLconst [0])
+(SBBLcarrymask (FlagGT_ULT)) => (MOVLconst [-1])
+(SBBLcarrymask (FlagGT_UGT)) => (MOVLconst [0])
+
+// Absorb flag constants into branches.
+((EQ|LE|GE|ULE|UGE) (FlagEQ) yes no)     => (First yes no)
+((NE|LT|GT|ULT|UGT) (FlagEQ) yes no)     => (First no yes)
+((NE|LT|LE|ULT|ULE) (FlagLT_ULT) yes no) => (First yes no)
+((EQ|GT|GE|UGT|UGE) (FlagLT_ULT) yes no) => (First no yes)
+((NE|LT|LE|UGT|UGE) (FlagLT_UGT) yes no) => (First yes no)
+((EQ|GT|GE|ULT|ULE) (FlagLT_UGT) yes no) => (First no yes)
+((NE|GT|GE|ULT|ULE) (FlagGT_ULT) yes no) => (First yes no)
+((EQ|LT|LE|UGT|UGE) (FlagGT_ULT) yes no) => (First no yes)
+((NE|GT|GE|UGT|UGE) (FlagGT_UGT) yes no) => (First yes no)
+((EQ|LT|LE|ULT|ULE) (FlagGT_UGT) yes no) => (First no yes)
+
+// Absorb flag constants into SETxx ops.
+((SETEQ|SETLE|SETGE|SETBE|SETAE) (FlagEQ))     => (MOVLconst [1])
+((SETNE|SETL|SETG|SETB|SETA)     (FlagEQ))     => (MOVLconst [0])
+((SETNE|SETL|SETLE|SETB|SETBE)   (FlagLT_ULT)) => (MOVLconst [1])
+((SETEQ|SETG|SETGE|SETA|SETAE)   (FlagLT_ULT)) => (MOVLconst [0])
+((SETNE|SETL|SETLE|SETA|SETAE)   (FlagLT_UGT)) => (MOVLconst [1])
+((SETEQ|SETG|SETGE|SETB|SETBE)   (FlagLT_UGT)) => (MOVLconst [0])
+((SETNE|SETG|SETGE|SETB|SETBE)   (FlagGT_ULT)) => (MOVLconst [1])
+((SETEQ|SETL|SETLE|SETA|SETAE)   (FlagGT_ULT)) => (MOVLconst [0])
+((SETNE|SETG|SETGE|SETA|SETAE)   (FlagGT_UGT)) => (MOVLconst [1])
+((SETEQ|SETL|SETLE|SETB|SETBE)   (FlagGT_UGT)) => (MOVLconst [0])
+
+(SETEQstore [off] {sym} ptr (FlagEQ)     mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
+(SETEQstore [off] {sym} ptr (FlagLT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
+(SETEQstore [off] {sym} ptr (FlagLT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
+(SETEQstore [off] {sym} ptr (FlagGT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
+(SETEQstore [off] {sym} ptr (FlagGT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
+
+(SETNEstore [off] {sym} ptr (FlagEQ)     mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
+(SETNEstore [off] {sym} ptr (FlagLT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
+(SETNEstore [off] {sym} ptr (FlagLT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
+(SETNEstore [off] {sym} ptr (FlagGT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
+(SETNEstore [off] {sym} ptr (FlagGT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
+
+(SETLstore  [off] {sym} ptr (FlagEQ)     mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
+(SETLstore  [off] {sym} ptr (FlagLT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
+(SETLstore  [off] {sym} ptr (FlagLT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
+(SETLstore  [off] {sym} ptr (FlagGT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
+(SETLstore  [off] {sym} ptr (FlagGT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
+
+(SETLEstore [off] {sym} ptr (FlagEQ)     mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
+(SETLEstore [off] {sym} ptr (FlagLT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
+(SETLEstore [off] {sym} ptr (FlagLT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
+(SETLEstore [off] {sym} ptr (FlagGT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
+(SETLEstore [off] {sym} ptr (FlagGT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
+
+(SETGstore  [off] {sym} ptr (FlagEQ)     mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
+(SETGstore  [off] {sym} ptr (FlagLT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
+(SETGstore  [off] {sym} ptr (FlagLT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
+(SETGstore  [off] {sym} ptr (FlagGT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
+(SETGstore  [off] {sym} ptr (FlagGT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
+
+(SETGEstore [off] {sym} ptr (FlagEQ)     mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
+(SETGEstore [off] {sym} ptr (FlagLT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
+(SETGEstore [off] {sym} ptr (FlagLT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
+(SETGEstore [off] {sym} ptr (FlagGT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
+(SETGEstore [off] {sym} ptr (FlagGT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
+
+(SETBstore  [off] {sym} ptr (FlagEQ)     mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
+(SETBstore  [off] {sym} ptr (FlagLT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
+(SETBstore  [off] {sym} ptr (FlagLT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
+(SETBstore  [off] {sym} ptr (FlagGT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
+(SETBstore  [off] {sym} ptr (FlagGT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
+
+(SETBEstore [off] {sym} ptr (FlagEQ)     mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
+(SETBEstore [off] {sym} ptr (FlagLT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
+(SETBEstore [off] {sym} ptr (FlagLT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
+(SETBEstore [off] {sym} ptr (FlagGT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
+(SETBEstore [off] {sym} ptr (FlagGT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
+
+(SETAstore  [off] {sym} ptr (FlagEQ)     mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
+(SETAstore  [off] {sym} ptr (FlagLT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
+(SETAstore  [off] {sym} ptr (FlagLT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
+(SETAstore  [off] {sym} ptr (FlagGT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
+(SETAstore  [off] {sym} ptr (FlagGT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
+
+(SETAEstore [off] {sym} ptr (FlagEQ)     mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
+(SETAEstore [off] {sym} ptr (FlagLT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
+(SETAEstore [off] {sym} ptr (FlagLT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
+(SETAEstore [off] {sym} ptr (FlagGT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
+(SETAEstore [off] {sym} ptr (FlagGT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
+
+// Remove redundant *const ops
+(ADDQconst [0] x)          => x
+(ADDLconst [c] x) && c==0  => x
+(SUBQconst [0] x)          => x
+(SUBLconst [c] x) && c==0  => x
+(ANDQconst [0] _)          => (MOVQconst [0])
+(ANDLconst [c] _) && c==0  => (MOVLconst [0])
+(ANDQconst [-1] x)         => x
+(ANDLconst [c] x) && c==-1 => x
+(ORQconst [0] x)           => x
+(ORLconst [c] x)  && c==0  => x
+(ORQconst [-1] _)          => (MOVQconst [-1])
+(ORLconst [c] _)  && c==-1 => (MOVLconst [-1])
+(XORQconst [0] x)          => x
+(XORLconst [c] x) && c==0  => x
+// TODO: since we got rid of the W/B versions, we might miss
+// things like (ANDLconst [0x100] x) which were formerly
+// (ANDBconst [0] x).  Probably doesn't happen very often.
+// If we cared, we might do:
+//  (ANDLconst <t> [c] x) && t.Size()==1 && int8(x)==0 -> (MOVLconst [0])
+
+// Remove redundant ops
+// Not in generic rules, because they may appear after lowering e. g. Slicemask
+(NEG(Q|L) (NEG(Q|L) x)) => x
+(NEG(Q|L) s:(SUB(Q|L) x y)) && s.Uses == 1 => (SUB(Q|L) y x)
+
+// Convert constant subtracts to constant adds
+(SUBQconst [c] x) && c != -(1<<31) => (ADDQconst [-c] x)
+(SUBLconst [c] x) => (ADDLconst [-c] x)
+
+// generic constant folding
+// TODO: more of this
+(ADDQconst [c] (MOVQconst [d])) => (MOVQconst [int64(c)+d])
+(ADDLconst [c] (MOVLconst [d])) => (MOVLconst [c+d])
+(ADDQconst [c] (ADDQconst [d] x)) && is32Bit(int64(c)+int64(d)) => (ADDQconst [c+d] x)
+(ADDLconst [c] (ADDLconst [d] x)) => (ADDLconst [c+d] x)
+(SUBQconst (MOVQconst [d]) [c]) => (MOVQconst [d-int64(c)])
+(SUBQconst (SUBQconst x [d]) [c]) && is32Bit(int64(-c)-int64(d)) => (ADDQconst [-c-d] x)
+(SARQconst [c] (MOVQconst [d])) => (MOVQconst [d>>uint64(c)])
+(SARLconst [c] (MOVQconst [d])) => (MOVQconst [int64(int32(d))>>uint64(c)])
+(SARWconst [c] (MOVQconst [d])) => (MOVQconst [int64(int16(d))>>uint64(c)])
+(SARBconst [c] (MOVQconst [d])) => (MOVQconst [int64(int8(d))>>uint64(c)])
+(NEGQ (MOVQconst [c])) => (MOVQconst [-c])
+(NEGL (MOVLconst [c])) => (MOVLconst [-c])
+(MULQconst [c] (MOVQconst [d])) => (MOVQconst [int64(c)*d])
+(MULLconst [c] (MOVLconst [d])) => (MOVLconst [c*d])
+(ANDQconst [c] (MOVQconst [d])) => (MOVQconst [int64(c)&d])
+(ANDLconst [c] (MOVLconst [d])) => (MOVLconst [c&d])
+(ORQconst [c] (MOVQconst [d])) => (MOVQconst [int64(c)|d])
+(ORLconst [c] (MOVLconst [d])) => (MOVLconst [c|d])
+(XORQconst [c] (MOVQconst [d])) => (MOVQconst [int64(c)^d])
+(XORLconst [c] (MOVLconst [d])) => (MOVLconst [c^d])
+(NOTQ (MOVQconst [c])) => (MOVQconst [^c])
+(NOTL (MOVLconst [c])) => (MOVLconst [^c])
+(BTSQconst [c] (MOVQconst [d])) => (MOVQconst [d|(1<<uint32(c))])
+(BTSLconst [c] (MOVLconst [d])) => (MOVLconst [d|(1<<uint32(c))])
+(BTRQconst [c] (MOVQconst [d])) => (MOVQconst [d&^(1<<uint32(c))])
+(BTRLconst [c] (MOVLconst [d])) => (MOVLconst [d&^(1<<uint32(c))])
+(BTCQconst [c] (MOVQconst [d])) => (MOVQconst [d^(1<<uint32(c))])
+(BTCLconst [c] (MOVLconst [d])) => (MOVLconst [d^(1<<uint32(c))])
+
+// If c or d doesn't fit into 32 bits, then we can't construct ORQconst,
+// but we can still constant-fold.
+// In theory this applies to any of the simplifications above,
+// but ORQ is the only one I've actually seen occur.
+(ORQ (MOVQconst [c]) (MOVQconst [d])) => (MOVQconst [c|d])
+
+// generic simplifications
+// TODO: more of this
+(ADDQ x (NEGQ y)) => (SUBQ x y)
+(ADDL x (NEGL y)) => (SUBL x y)
+(SUBQ x x) => (MOVQconst [0])
+(SUBL x x) => (MOVLconst [0])
+(ANDQ x x) => x
+(ANDL x x) => x
+(ORQ x x)  => x
+(ORL x x)  => x
+(XORQ x x) => (MOVQconst [0])
+(XORL x x) => (MOVLconst [0])
+
+(SHLLconst [d] (MOVLconst [c])) => (MOVLconst [c << uint64(d)])
+(SHLQconst [d] (MOVQconst [c])) => (MOVQconst [c << uint64(d)])
+(SHLQconst [d] (MOVLconst [c])) => (MOVQconst [int64(c) << uint64(d)])
+
+// Fold NEG into ADDconst/MULconst. Take care to keep c in 32 bit range.
+(NEGQ (ADDQconst [c] (NEGQ x))) && c != -(1<<31) => (ADDQconst [-c] x)
+(MULQconst [c] (NEGQ x)) && c != -(1<<31) => (MULQconst [-c] x)
+
+// checking AND against 0.
+(CMPQconst a:(ANDQ x y) [0]) && a.Uses == 1 => (TESTQ x y)
+(CMPLconst a:(ANDL x y) [0]) && a.Uses == 1 => (TESTL x y)
+(CMPWconst a:(ANDL x y) [0]) && a.Uses == 1 => (TESTW x y)
+(CMPBconst a:(ANDL x y) [0]) && a.Uses == 1 => (TESTB x y)
+(CMPQconst a:(ANDQconst [c] x) [0]) && a.Uses == 1 => (TESTQconst [c] x)
+(CMPLconst a:(ANDLconst [c] x) [0]) && a.Uses == 1 => (TESTLconst [c] x)
+(CMPWconst a:(ANDLconst [c] x) [0]) && a.Uses == 1 => (TESTWconst [int16(c)] x)
+(CMPBconst a:(ANDLconst [c] x) [0]) && a.Uses == 1 => (TESTBconst [int8(c)] x)
+
+// Convert TESTx to TESTxconst if possible.
+(TESTQ (MOVQconst [c]) x) && is32Bit(c) => (TESTQconst [int32(c)] x)
+(TESTL (MOVLconst [c]) x) => (TESTLconst [c] x)
+(TESTW (MOVLconst [c]) x) => (TESTWconst [int16(c)] x)
+(TESTB (MOVLconst [c]) x) => (TESTBconst [int8(c)] x)
+
+// TEST %reg,%reg is shorter than CMP
+(CMPQconst x [0]) => (TESTQ x x)
+(CMPLconst x [0]) => (TESTL x x)
+(CMPWconst x [0]) => (TESTW x x)
+(CMPBconst x [0]) => (TESTB x x)
+(TESTQconst [-1] x) && x.Op != OpAMD64MOVQconst => (TESTQ x x)
+(TESTLconst [-1] x) && x.Op != OpAMD64MOVLconst => (TESTL x x)
+(TESTWconst [-1] x) && x.Op != OpAMD64MOVLconst => (TESTW x x)
+(TESTBconst [-1] x) && x.Op != OpAMD64MOVLconst => (TESTB x x)
+
+// Convert LEAQ1 back to ADDQ if we can
+(LEAQ1 [0] x y) && v.Aux == nil => (ADDQ x y)
+
+// Combining byte loads into larger (unaligned) loads.
+// There are many ways these combinations could occur.  This is
+// designed to match the way encoding/binary.LittleEndian does it.
+
+// Little-endian loads
+
+(OR(L|Q)                  x0:(MOVBload [i0] {s} p mem)
+    sh:(SHL(L|Q)const [8] x1:(MOVBload [i1] {s} p mem)))
+  && i1 == i0+1
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && sh.Uses == 1
+  && mergePoint(b,x0,x1) != nil
+  && clobber(x0, x1, sh)
+  => @mergePoint(b,x0,x1) (MOVWload [i0] {s} p mem)
+
+(OR(L|Q)                  x0:(MOVBload [i] {s} p0 mem)
+    sh:(SHL(L|Q)const [8] x1:(MOVBload [i] {s} p1 mem)))
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && sh.Uses == 1
+  && sequentialAddresses(p0, p1, 1)
+  && mergePoint(b,x0,x1) != nil
+  && clobber(x0, x1, sh)
+  => @mergePoint(b,x0,x1) (MOVWload [i] {s} p0 mem)
+
+(OR(L|Q)                   x0:(MOVWload [i0] {s} p mem)
+    sh:(SHL(L|Q)const [16] x1:(MOVWload [i1] {s} p mem)))
+  && i1 == i0+2
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && sh.Uses == 1
+  && mergePoint(b,x0,x1) != nil
+  && clobber(x0, x1, sh)
+  => @mergePoint(b,x0,x1) (MOVLload [i0] {s} p mem)
+
+(OR(L|Q)                   x0:(MOVWload [i] {s} p0 mem)
+    sh:(SHL(L|Q)const [16] x1:(MOVWload [i] {s} p1 mem)))
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && sh.Uses == 1
+  && sequentialAddresses(p0, p1, 2)
+  && mergePoint(b,x0,x1) != nil
+  && clobber(x0, x1, sh)
+  => @mergePoint(b,x0,x1) (MOVLload [i] {s} p0 mem)
+
+(ORQ                   x0:(MOVLload [i0] {s} p mem)
+    sh:(SHLQconst [32] x1:(MOVLload [i1] {s} p mem)))
+  && i1 == i0+4
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && sh.Uses == 1
+  && mergePoint(b,x0,x1) != nil
+  && clobber(x0, x1, sh)
+  => @mergePoint(b,x0,x1) (MOVQload [i0] {s} p mem)
+
+(ORQ                   x0:(MOVLload [i] {s} p0 mem)
+    sh:(SHLQconst [32] x1:(MOVLload [i] {s} p1 mem)))
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && sh.Uses == 1
+  && sequentialAddresses(p0, p1, 4)
+  && mergePoint(b,x0,x1) != nil
+  && clobber(x0, x1, sh)
+  => @mergePoint(b,x0,x1) (MOVQload [i] {s} p0 mem)
+
+(OR(L|Q)
+    s1:(SHL(L|Q)const [j1] x1:(MOVBload [i1] {s} p mem))
+    or:(OR(L|Q)
+        s0:(SHL(L|Q)const [j0] x0:(MOVBload [i0] {s} p mem))
+	y))
+  && i1 == i0+1
+  && j1 == j0+8
+  && j0 % 16 == 0
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && s0.Uses == 1
+  && s1.Uses == 1
+  && or.Uses == 1
+  && mergePoint(b,x0,x1,y) != nil
+  && clobber(x0, x1, s0, s1, or)
+  => @mergePoint(b,x0,x1,y) (OR(L|Q) <v.Type> (SHL(L|Q)const <v.Type> [j0] (MOVWload [i0] {s} p mem)) y)
+
+(OR(L|Q)
+    s1:(SHL(L|Q)const [j1] x1:(MOVBload [i] {s} p1 mem))
+    or:(OR(L|Q)
+        s0:(SHL(L|Q)const [j0] x0:(MOVBload [i] {s} p0 mem))
+	y))
+  && j1 == j0+8
+  && j0 % 16 == 0
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && s0.Uses == 1
+  && s1.Uses == 1
+  && or.Uses == 1
+  && sequentialAddresses(p0, p1, 1)
+  && mergePoint(b,x0,x1,y) != nil
+  && clobber(x0, x1, s0, s1, or)
+  => @mergePoint(b,x0,x1,y) (OR(L|Q) <v.Type> (SHL(L|Q)const <v.Type> [j0] (MOVWload [i] {s} p0 mem)) y)
+
+(ORQ
+    s1:(SHLQconst [j1] x1:(MOVWload [i1] {s} p mem))
+    or:(ORQ
+        s0:(SHLQconst [j0] x0:(MOVWload [i0] {s} p mem))
+	y))
+  && i1 == i0+2
+  && j1 == j0+16
+  && j0 % 32 == 0
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && s0.Uses == 1
+  && s1.Uses == 1
+  && or.Uses == 1
+  && mergePoint(b,x0,x1,y) != nil
+  && clobber(x0, x1, s0, s1, or)
+  => @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j0] (MOVLload [i0] {s} p mem)) y)
+
+(ORQ
+    s1:(SHLQconst [j1] x1:(MOVWload [i] {s} p1 mem))
+    or:(ORQ
+        s0:(SHLQconst [j0] x0:(MOVWload [i] {s} p0 mem))
+	y))
+  && j1 == j0+16
+  && j0 % 32 == 0
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && s0.Uses == 1
+  && s1.Uses == 1
+  && or.Uses == 1
+  && sequentialAddresses(p0, p1, 2)
+  && mergePoint(b,x0,x1,y) != nil
+  && clobber(x0, x1, s0, s1, or)
+  => @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j0] (MOVLload [i] {s} p0 mem)) y)
+
+// Big-endian loads
+
+(OR(L|Q)
+                           x1:(MOVBload [i1] {s} p mem)
+    sh:(SHL(L|Q)const [8]  x0:(MOVBload [i0] {s} p mem)))
+  && i1 == i0+1
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && sh.Uses == 1
+  && mergePoint(b,x0,x1) != nil
+  && clobber(x0, x1, sh)
+  => @mergePoint(b,x0,x1) (ROLWconst <v.Type> [8] (MOVWload [i0] {s} p mem))
+
+(OR(L|Q)
+                           x1:(MOVBload [i] {s} p1 mem)
+    sh:(SHL(L|Q)const [8]  x0:(MOVBload [i] {s} p0 mem)))
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && sh.Uses == 1
+  && sequentialAddresses(p0, p1, 1)
+  && mergePoint(b,x0,x1) != nil
+  && clobber(x0, x1, sh)
+  => @mergePoint(b,x0,x1) (ROLWconst <v.Type> [8] (MOVWload [i] {s} p0 mem))
+
+(OR(L|Q)
+                            r1:(ROLWconst [8] x1:(MOVWload [i1] {s} p mem))
+    sh:(SHL(L|Q)const [16]  r0:(ROLWconst [8] x0:(MOVWload [i0] {s} p mem))))
+  && i1 == i0+2
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && r0.Uses == 1
+  && r1.Uses == 1
+  && sh.Uses == 1
+  && mergePoint(b,x0,x1) != nil
+  && clobber(x0, x1, r0, r1, sh)
+  => @mergePoint(b,x0,x1) (BSWAPL <v.Type> (MOVLload [i0] {s} p mem))
+
+(OR(L|Q)
+                            r1:(ROLWconst [8] x1:(MOVWload [i] {s} p1 mem))
+    sh:(SHL(L|Q)const [16]  r0:(ROLWconst [8] x0:(MOVWload [i] {s} p0 mem))))
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && r0.Uses == 1
+  && r1.Uses == 1
+  && sh.Uses == 1
+  && sequentialAddresses(p0, p1, 2)
+  && mergePoint(b,x0,x1) != nil
+  && clobber(x0, x1, r0, r1, sh)
+  => @mergePoint(b,x0,x1) (BSWAPL <v.Type> (MOVLload [i] {s} p0 mem))
+
+(ORQ
+                        r1:(BSWAPL x1:(MOVLload [i1] {s} p mem))
+    sh:(SHLQconst [32]  r0:(BSWAPL x0:(MOVLload [i0] {s} p mem))))
+  && i1 == i0+4
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && r0.Uses == 1
+  && r1.Uses == 1
+  && sh.Uses == 1
+  && mergePoint(b,x0,x1) != nil
+  && clobber(x0, x1, r0, r1, sh)
+  => @mergePoint(b,x0,x1) (BSWAPQ <v.Type> (MOVQload [i0] {s} p mem))
+
+(ORQ
+                        r1:(BSWAPL x1:(MOVLload [i] {s} p1 mem))
+    sh:(SHLQconst [32]  r0:(BSWAPL x0:(MOVLload [i] {s} p0 mem))))
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && r0.Uses == 1
+  && r1.Uses == 1
+  && sh.Uses == 1
+  && sequentialAddresses(p0, p1, 4)
+  && mergePoint(b,x0,x1) != nil
+  && clobber(x0, x1, r0, r1, sh)
+  => @mergePoint(b,x0,x1) (BSWAPQ <v.Type> (MOVQload [i] {s} p0 mem))
+
+(OR(L|Q)
+    s0:(SHL(L|Q)const [j0] x0:(MOVBload [i0] {s} p mem))
+    or:(OR(L|Q)
+        s1:(SHL(L|Q)const [j1] x1:(MOVBload [i1] {s} p mem))
+	y))
+  && i1 == i0+1
+  && j1 == j0-8
+  && j1 % 16 == 0
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && s0.Uses == 1
+  && s1.Uses == 1
+  && or.Uses == 1
+  && mergePoint(b,x0,x1,y) != nil
+  && clobber(x0, x1, s0, s1, or)
+  => @mergePoint(b,x0,x1,y) (OR(L|Q) <v.Type> (SHL(L|Q)const <v.Type> [j1] (ROLWconst <typ.UInt16> [8] (MOVWload [i0] {s} p mem))) y)
+
+(OR(L|Q)
+    s0:(SHL(L|Q)const [j0] x0:(MOVBload [i] {s} p0 mem))
+    or:(OR(L|Q)
+        s1:(SHL(L|Q)const [j1] x1:(MOVBload [i] {s} p1 mem))
+	y))
+  && j1 == j0-8
+  && j1 % 16 == 0
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && s0.Uses == 1
+  && s1.Uses == 1
+  && or.Uses == 1
+  && sequentialAddresses(p0, p1, 1)
+  && mergePoint(b,x0,x1,y) != nil
+  && clobber(x0, x1, s0, s1, or)
+  => @mergePoint(b,x0,x1,y) (OR(L|Q) <v.Type> (SHL(L|Q)const <v.Type> [j1] (ROLWconst <typ.UInt16> [8] (MOVWload [i] {s} p0 mem))) y)
+
+(ORQ
+    s0:(SHLQconst [j0] r0:(ROLWconst [8] x0:(MOVWload [i0] {s} p mem)))
+    or:(ORQ
+        s1:(SHLQconst [j1] r1:(ROLWconst [8] x1:(MOVWload [i1] {s} p mem)))
+	y))
+  && i1 == i0+2
+  && j1 == j0-16
+  && j1 % 32 == 0
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && r0.Uses == 1
+  && r1.Uses == 1
+  && s0.Uses == 1
+  && s1.Uses == 1
+  && or.Uses == 1
+  && mergePoint(b,x0,x1,y) != nil
+  && clobber(x0, x1, r0, r1, s0, s1, or)
+  => @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j1] (BSWAPL <typ.UInt32> (MOVLload [i0] {s} p mem))) y)
+
+(ORQ
+    s0:(SHLQconst [j0] r0:(ROLWconst [8] x0:(MOVWload [i] {s} p0 mem)))
+    or:(ORQ
+        s1:(SHLQconst [j1] r1:(ROLWconst [8] x1:(MOVWload [i] {s} p1 mem)))
+	y))
+  && j1 == j0-16
+  && j1 % 32 == 0
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && r0.Uses == 1
+  && r1.Uses == 1
+  && s0.Uses == 1
+  && s1.Uses == 1
+  && or.Uses == 1
+  && sequentialAddresses(p0, p1, 2)
+  && mergePoint(b,x0,x1,y) != nil
+  && clobber(x0, x1, r0, r1, s0, s1, or)
+  => @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j1] (BSWAPL <typ.UInt32> (MOVLload [i] {s} p0 mem))) y)
+
+// Combine 2 byte stores + shift into rolw 8 + word store
+(MOVBstore [i] {s} p w
+  x0:(MOVBstore [i-1] {s} p (SHRWconst [8] w) mem))
+  && x0.Uses == 1
+  && clobber(x0)
+  => (MOVWstore [i-1] {s} p (ROLWconst <w.Type> [8] w) mem)
+(MOVBstore [i] {s} p1 w
+  x0:(MOVBstore [i] {s} p0 (SHRWconst [8] w) mem))
+  && x0.Uses == 1
+  && sequentialAddresses(p0, p1, 1)
+  && clobber(x0)
+  => (MOVWstore [i] {s} p0 (ROLWconst <w.Type> [8] w) mem)
+
+// Combine stores + shifts into bswap and larger (unaligned) stores
+(MOVBstore [i] {s} p w
+  x2:(MOVBstore [i-1] {s} p (SHRLconst [8] w)
+  x1:(MOVBstore [i-2] {s} p (SHRLconst [16] w)
+  x0:(MOVBstore [i-3] {s} p (SHRLconst [24] w) mem))))
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && x2.Uses == 1
+  && clobber(x0, x1, x2)
+  => (MOVLstore [i-3] {s} p (BSWAPL <w.Type> w) mem)
+(MOVBstore [i] {s} p3 w
+  x2:(MOVBstore [i] {s} p2 (SHRLconst [8] w)
+  x1:(MOVBstore [i] {s} p1 (SHRLconst [16] w)
+  x0:(MOVBstore [i] {s} p0 (SHRLconst [24] w) mem))))
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && x2.Uses == 1
+  && sequentialAddresses(p0, p1, 1)
+  && sequentialAddresses(p1, p2, 1)
+  && sequentialAddresses(p2, p3, 1)
+  && clobber(x0, x1, x2)
+  => (MOVLstore [i] {s} p0 (BSWAPL <w.Type> w) mem)
+
+(MOVBstore [i] {s} p w
+  x6:(MOVBstore [i-1] {s} p (SHRQconst [8] w)
+  x5:(MOVBstore [i-2] {s} p (SHRQconst [16] w)
+  x4:(MOVBstore [i-3] {s} p (SHRQconst [24] w)
+  x3:(MOVBstore [i-4] {s} p (SHRQconst [32] w)
+  x2:(MOVBstore [i-5] {s} p (SHRQconst [40] w)
+  x1:(MOVBstore [i-6] {s} p (SHRQconst [48] w)
+  x0:(MOVBstore [i-7] {s} p (SHRQconst [56] w) mem))))))))
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && x2.Uses == 1
+  && x3.Uses == 1
+  && x4.Uses == 1
+  && x5.Uses == 1
+  && x6.Uses == 1
+  && clobber(x0, x1, x2, x3, x4, x5, x6)
+  => (MOVQstore [i-7] {s} p (BSWAPQ <w.Type> w) mem)
+(MOVBstore [i] {s} p7 w
+  x6:(MOVBstore [i] {s} p6 (SHRQconst [8] w)
+  x5:(MOVBstore [i] {s} p5 (SHRQconst [16] w)
+  x4:(MOVBstore [i] {s} p4 (SHRQconst [24] w)
+  x3:(MOVBstore [i] {s} p3 (SHRQconst [32] w)
+  x2:(MOVBstore [i] {s} p2 (SHRQconst [40] w)
+  x1:(MOVBstore [i] {s} p1 (SHRQconst [48] w)
+  x0:(MOVBstore [i] {s} p0 (SHRQconst [56] w) mem))))))))
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && x2.Uses == 1
+  && x3.Uses == 1
+  && x4.Uses == 1
+  && x5.Uses == 1
+  && x6.Uses == 1
+  && sequentialAddresses(p0, p1, 1)
+  && sequentialAddresses(p1, p2, 1)
+  && sequentialAddresses(p2, p3, 1)
+  && sequentialAddresses(p3, p4, 1)
+  && sequentialAddresses(p4, p5, 1)
+  && sequentialAddresses(p5, p6, 1)
+  && sequentialAddresses(p6, p7, 1)
+  && clobber(x0, x1, x2, x3, x4, x5, x6)
+  => (MOVQstore [i] {s} p0 (BSWAPQ <w.Type> w) mem)
+
+// Combine constant stores into larger (unaligned) stores.
+(MOVBstoreconst [c] {s} p1 x:(MOVBstoreconst [a] {s} p0 mem))
+  && x.Uses == 1
+  && sequentialAddresses(p0, p1, int64(a.Off()+1-c.Off()))
+  && clobber(x)
+  => (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p0 mem)
+(MOVBstoreconst [a] {s} p0 x:(MOVBstoreconst [c] {s} p1 mem))
+  && x.Uses == 1
+  && sequentialAddresses(p0, p1, int64(a.Off()+1-c.Off()))
+  && clobber(x)
+  => (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p0 mem)
+(MOVWstoreconst [c] {s} p1 x:(MOVWstoreconst [a] {s} p0 mem))
+  && x.Uses == 1
+  && sequentialAddresses(p0, p1, int64(a.Off()+2-c.Off()))
+  && clobber(x)
+  => (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p0 mem)
+(MOVWstoreconst [a] {s} p0 x:(MOVWstoreconst [c] {s} p1 mem))
+  && x.Uses == 1
+  && sequentialAddresses(p0, p1, int64(a.Off()+2-c.Off()))
+  && clobber(x)
+  => (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p0 mem)
+(MOVLstoreconst [c] {s} p1 x:(MOVLstoreconst [a] {s} p0 mem))
+  && x.Uses == 1
+  && sequentialAddresses(p0, p1, int64(a.Off()+4-c.Off()))
+  && clobber(x)
+  => (MOVQstore [a.Off()] {s} p0 (MOVQconst [a.Val64()&0xffffffff | c.Val64()<<32]) mem)
+(MOVLstoreconst [a] {s} p0 x:(MOVLstoreconst [c] {s} p1 mem))
+  && x.Uses == 1
+  && sequentialAddresses(p0, p1, int64(a.Off()+4-c.Off()))
+  && clobber(x)
+  => (MOVQstore [a.Off()] {s} p0 (MOVQconst [a.Val64()&0xffffffff | c.Val64()<<32]) mem)
+(MOVQstoreconst [c] {s} p1 x:(MOVQstoreconst [a] {s} p0 mem))
+  && config.useSSE
+  && x.Uses == 1
+  && sequentialAddresses(p0, p1, int64(a.Off()+8-c.Off()))
+  && a.Val() == 0
+  && c.Val() == 0
+  && clobber(x)
+  => (MOVOstoreconst [makeValAndOff(0,a.Off())] {s} p0 mem)
+(MOVQstoreconst [a] {s} p0 x:(MOVQstoreconst [c] {s} p1 mem))
+  && config.useSSE
+  && x.Uses == 1
+  && sequentialAddresses(p0, p1, int64(a.Off()+8-c.Off()))
+  && a.Val() == 0
+  && c.Val() == 0
+  && clobber(x)
+  => (MOVOstoreconst [makeValAndOff(0,a.Off())] {s} p0 mem)
+
+// Combine stores into larger (unaligned) stores. Little endian.
+(MOVBstore [i] {s} p (SHR(W|L|Q)const [8] w) x:(MOVBstore [i-1] {s} p w mem))
+  && x.Uses == 1
+  && clobber(x)
+  => (MOVWstore [i-1] {s} p w mem)
+(MOVBstore [i] {s} p w x:(MOVBstore [i+1] {s} p (SHR(W|L|Q)const [8] w) mem))
+  && x.Uses == 1
+  && clobber(x)
+  => (MOVWstore [i] {s} p w mem)
+(MOVBstore [i] {s} p (SHR(L|Q)const [j] w) x:(MOVBstore [i-1] {s} p w0:(SHR(L|Q)const [j-8] w) mem))
+  && x.Uses == 1
+  && clobber(x)
+  => (MOVWstore [i-1] {s} p w0 mem)
+(MOVBstore [i] {s} p1 (SHR(W|L|Q)const [8] w) x:(MOVBstore [i] {s} p0 w mem))
+  && x.Uses == 1
+  && sequentialAddresses(p0, p1, 1)
+  && clobber(x)
+  => (MOVWstore [i] {s} p0 w mem)
+(MOVBstore [i] {s} p0 w x:(MOVBstore [i] {s} p1 (SHR(W|L|Q)const [8] w) mem))
+  && x.Uses == 1
+  && sequentialAddresses(p0, p1, 1)
+  && clobber(x)
+  => (MOVWstore [i] {s} p0 w mem)
+(MOVBstore [i] {s} p1 (SHR(L|Q)const [j] w) x:(MOVBstore [i] {s} p0 w0:(SHR(L|Q)const [j-8] w) mem))
+  && x.Uses == 1
+  && sequentialAddresses(p0, p1, 1)
+  && clobber(x)
+  => (MOVWstore [i] {s} p0 w0 mem)
+
+(MOVWstore [i] {s} p (SHR(L|Q)const [16] w) x:(MOVWstore [i-2] {s} p w mem))
+  && x.Uses == 1
+  && clobber(x)
+  => (MOVLstore [i-2] {s} p w mem)
+(MOVWstore [i] {s} p (SHR(L|Q)const [j] w) x:(MOVWstore [i-2] {s} p w0:(SHR(L|Q)const [j-16] w) mem))
+  && x.Uses == 1
+  && clobber(x)
+  => (MOVLstore [i-2] {s} p w0 mem)
+(MOVWstore [i] {s} p1 (SHR(L|Q)const [16] w) x:(MOVWstore [i] {s} p0 w mem))
+  && x.Uses == 1
+  && sequentialAddresses(p0, p1, 2)
+  && clobber(x)
+  => (MOVLstore [i] {s} p0 w mem)
+(MOVWstore [i] {s} p1 (SHR(L|Q)const [j] w) x:(MOVWstore [i] {s} p0 w0:(SHR(L|Q)const [j-16] w) mem))
+  && x.Uses == 1
+  && sequentialAddresses(p0, p1, 2)
+  && clobber(x)
+  => (MOVLstore [i] {s} p0 w0 mem)
+
+(MOVLstore [i] {s} p (SHRQconst [32] w) x:(MOVLstore [i-4] {s} p w mem))
+  && x.Uses == 1
+  && clobber(x)
+  => (MOVQstore [i-4] {s} p w mem)
+(MOVLstore [i] {s} p (SHRQconst [j] w) x:(MOVLstore [i-4] {s} p w0:(SHRQconst [j-32] w) mem))
+  && x.Uses == 1
+  && clobber(x)
+  => (MOVQstore [i-4] {s} p w0 mem)
+(MOVLstore [i] {s} p1 (SHRQconst [32] w) x:(MOVLstore [i] {s} p0 w mem))
+  && x.Uses == 1
+  && sequentialAddresses(p0, p1, 4)
+  && clobber(x)
+  => (MOVQstore [i] {s} p0 w mem)
+(MOVLstore [i] {s} p1 (SHRQconst [j] w) x:(MOVLstore [i] {s} p0 w0:(SHRQconst [j-32] w) mem))
+  && x.Uses == 1
+  && sequentialAddresses(p0, p1, 4)
+  && clobber(x)
+  => (MOVQstore [i] {s} p0 w0 mem)
+
+(MOVBstore  [c3] {s}  p3 (SHRQconst [56]  w)
+  x1:(MOVWstore [c2]  {s} p2  (SHRQconst [40] w)
+  x2:(MOVLstore [c1] {s} p1  (SHRQconst [8] w)
+  x3:(MOVBstore [c0] {s} p0  w mem))))
+  && x1.Uses == 1
+  && x2.Uses == 1
+  && x3.Uses == 1
+  && sequentialAddresses(p0, p1, int64(1 + c0 - c1))
+  && sequentialAddresses(p0, p2, int64(5 + c0 - c2))
+  && sequentialAddresses(p0, p3, int64(7 + c0 - c3))
+  && clobber(x1, x2, x3)
+  => (MOVQstore [c0] {s} p0 w mem)
+
+(MOVBstore [i] {s} p
+  x1:(MOVBload [j] {s2} p2 mem)
+    mem2:(MOVBstore [i-1] {s} p
+      x2:(MOVBload [j-1] {s2} p2 mem) mem))
+  && x1.Uses == 1
+  && x2.Uses == 1
+  && mem2.Uses == 1
+  && clobber(x1, x2, mem2)
+  => (MOVWstore [i-1] {s} p (MOVWload [j-1] {s2} p2 mem) mem)
+
+(MOVWstore [i] {s} p
+  x1:(MOVWload [j] {s2} p2 mem)
+    mem2:(MOVWstore [i-2] {s} p
+      x2:(MOVWload [j-2] {s2} p2 mem) mem))
+  && x1.Uses == 1
+  && x2.Uses == 1
+  && mem2.Uses == 1
+  && clobber(x1, x2, mem2)
+  => (MOVLstore [i-2] {s} p (MOVLload [j-2] {s2} p2 mem) mem)
+
+(MOVLstore [i] {s} p
+  x1:(MOVLload [j] {s2} p2 mem)
+    mem2:(MOVLstore [i-4] {s} p
+      x2:(MOVLload [j-4] {s2} p2 mem) mem))
+  && x1.Uses == 1
+  && x2.Uses == 1
+  && mem2.Uses == 1
+  && clobber(x1, x2, mem2)
+  => (MOVQstore [i-4] {s} p (MOVQload [j-4] {s2} p2 mem) mem)
+
+// Merge load and op
+// TODO: add indexed variants?
+((ADD|SUB|AND|OR|XOR)Q x l:(MOVQload [off] {sym} ptr mem)) && canMergeLoadClobber(v, l, x) && clobber(l) => ((ADD|SUB|AND|OR|XOR)Qload x [off] {sym} ptr mem)
+((ADD|SUB|AND|OR|XOR)L x l:(MOVLload [off] {sym} ptr mem)) && canMergeLoadClobber(v, l, x) && clobber(l) => ((ADD|SUB|AND|OR|XOR)Lload x [off] {sym} ptr mem)
+((ADD|SUB|MUL|DIV)SD x l:(MOVSDload [off] {sym} ptr mem)) && canMergeLoadClobber(v, l, x) && clobber(l) => ((ADD|SUB|MUL|DIV)SDload x [off] {sym} ptr mem)
+((ADD|SUB|MUL|DIV)SS x l:(MOVSSload [off] {sym} ptr mem)) && canMergeLoadClobber(v, l, x) && clobber(l) => ((ADD|SUB|MUL|DIV)SSload x [off] {sym} ptr mem)
+(MOVLstore {sym} [off] ptr y:((ADD|AND|OR|XOR)Lload x [off] {sym} ptr mem) mem) && y.Uses==1 && clobber(y) => ((ADD|AND|OR|XOR)Lmodify [off] {sym} ptr x mem)
+(MOVLstore {sym} [off] ptr y:((ADD|SUB|AND|OR|XOR)L l:(MOVLload [off] {sym} ptr mem) x) mem) && y.Uses==1 && l.Uses==1 && clobber(y, l) =>
+	((ADD|SUB|AND|OR|XOR)Lmodify [off] {sym} ptr x mem)
+(MOVQstore {sym} [off] ptr y:((ADD|AND|OR|XOR)Qload x [off] {sym} ptr mem) mem) && y.Uses==1 && clobber(y) => ((ADD|AND|OR|XOR)Qmodify [off] {sym} ptr x mem)
+(MOVQstore {sym} [off] ptr y:((ADD|SUB|AND|OR|XOR)Q l:(MOVQload [off] {sym} ptr mem) x) mem) && y.Uses==1 && l.Uses==1 && clobber(y, l) =>
+	((ADD|SUB|AND|OR|XOR)Qmodify [off] {sym} ptr x mem)
+
+// Merge ADDQconst and LEAQ into atomic loads.
+(MOV(Q|L|B)atomicload [off1] {sym} (ADDQconst [off2] ptr) mem) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOV(Q|L|B)atomicload [off1+off2] {sym} ptr mem)
+(MOV(Q|L|B)atomicload [off1] {sym1} (LEAQ [off2] {sym2} ptr) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+	(MOV(Q|L|B)atomicload [off1+off2] {mergeSym(sym1, sym2)} ptr mem)
+
+// Merge ADDQconst and LEAQ into atomic stores.
+(XCHGQ [off1] {sym} val (ADDQconst [off2] ptr) mem) && is32Bit(int64(off1)+int64(off2)) =>
+	(XCHGQ [off1+off2] {sym} val ptr mem)
+(XCHGQ [off1] {sym1} val (LEAQ [off2] {sym2} ptr) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && ptr.Op != OpSB =>
+	(XCHGQ [off1+off2] {mergeSym(sym1,sym2)} val ptr mem)
+(XCHGL [off1] {sym} val (ADDQconst [off2] ptr) mem) && is32Bit(int64(off1)+int64(off2)) =>
+	(XCHGL [off1+off2] {sym} val ptr mem)
+(XCHGL [off1] {sym1} val (LEAQ [off2] {sym2} ptr) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && ptr.Op != OpSB =>
+	(XCHGL [off1+off2] {mergeSym(sym1,sym2)} val ptr mem)
+
+// Merge ADDQconst into atomic adds.
+// TODO: merging LEAQ doesn't work, assembler doesn't like the resulting instructions.
+(XADDQlock [off1] {sym} val (ADDQconst [off2] ptr) mem) && is32Bit(int64(off1)+int64(off2)) =>
+	(XADDQlock [off1+off2] {sym} val ptr mem)
+(XADDLlock [off1] {sym} val (ADDQconst [off2] ptr) mem) && is32Bit(int64(off1)+int64(off2)) =>
+	(XADDLlock [off1+off2] {sym} val ptr mem)
+
+// Merge ADDQconst into atomic compare and swaps.
+// TODO: merging LEAQ doesn't work, assembler doesn't like the resulting instructions.
+(CMPXCHGQlock [off1] {sym} (ADDQconst [off2] ptr) old new_ mem) && is32Bit(int64(off1)+int64(off2)) =>
+	(CMPXCHGQlock [off1+off2] {sym} ptr old new_ mem)
+(CMPXCHGLlock [off1] {sym} (ADDQconst [off2] ptr) old new_ mem) && is32Bit(int64(off1)+int64(off2)) =>
+	(CMPXCHGLlock [off1+off2] {sym} ptr old new_ mem)
+
+// We don't need the conditional move if we know the arg of BSF is not zero.
+(CMOVQEQ x _ (Select1 (BS(F|R)Q (ORQconst [c] _)))) && c != 0 => x
+// Extension is unnecessary for trailing zeros.
+(BSFQ (ORQconst <t> [1<<8] (MOVBQZX x))) => (BSFQ (ORQconst <t> [1<<8] x))
+(BSFQ (ORQconst <t> [1<<16] (MOVWQZX x))) => (BSFQ (ORQconst <t> [1<<16] x))
+
+// Redundant sign/zero extensions
+// Note: see issue 21963. We have to make sure we use the right type on
+// the resulting extension (the outer type, not the inner type).
+(MOVLQSX (MOVLQSX x)) => (MOVLQSX x)
+(MOVLQSX (MOVWQSX x)) => (MOVWQSX x)
+(MOVLQSX (MOVBQSX x)) => (MOVBQSX x)
+(MOVWQSX (MOVWQSX x)) => (MOVWQSX x)
+(MOVWQSX (MOVBQSX x)) => (MOVBQSX x)
+(MOVBQSX (MOVBQSX x)) => (MOVBQSX x)
+(MOVLQZX (MOVLQZX x)) => (MOVLQZX x)
+(MOVLQZX (MOVWQZX x)) => (MOVWQZX x)
+(MOVLQZX (MOVBQZX x)) => (MOVBQZX x)
+(MOVWQZX (MOVWQZX x)) => (MOVWQZX x)
+(MOVWQZX (MOVBQZX x)) => (MOVBQZX x)
+(MOVBQZX (MOVBQZX x)) => (MOVBQZX x)
+
+(MOVQstore [off] {sym} ptr a:((ADD|AND|OR|XOR)Qconst [c] l:(MOVQload [off] {sym} ptr2 mem)) mem)
+	&& isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && clobber(l, a) =>
+	((ADD|AND|OR|XOR)Qconstmodify {sym} [makeValAndOff(int32(c),off)] ptr mem)
+(MOVLstore [off] {sym} ptr a:((ADD|AND|OR|XOR)Lconst [c] l:(MOVLload [off] {sym} ptr2 mem)) mem)
+	&& isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && clobber(l, a) =>
+	((ADD|AND|OR|XOR)Lconstmodify {sym} [makeValAndOff(int32(c),off)] ptr mem)
+
+// float <-> int register moves, with no conversion.
+// These come up when compiling math.{Float{32,64}bits,Float{32,64}frombits}.
+(MOVQload  [off] {sym} ptr (MOVSDstore [off] {sym} ptr val _)) => (MOVQf2i val)
+(MOVLload  [off] {sym} ptr (MOVSSstore [off] {sym} ptr val _)) => (MOVLf2i val)
+(MOVSDload [off] {sym} ptr (MOVQstore  [off] {sym} ptr val _)) => (MOVQi2f val)
+(MOVSSload [off] {sym} ptr (MOVLstore  [off] {sym} ptr val _)) => (MOVLi2f val)
+
+// Other load-like ops.
+(ADDQload x [off] {sym} ptr (MOVSDstore [off] {sym} ptr y _)) => (ADDQ x (MOVQf2i y))
+(ADDLload x [off] {sym} ptr (MOVSSstore [off] {sym} ptr y _)) => (ADDL x (MOVLf2i y))
+(SUBQload x [off] {sym} ptr (MOVSDstore [off] {sym} ptr y _)) => (SUBQ x (MOVQf2i y))
+(SUBLload x [off] {sym} ptr (MOVSSstore [off] {sym} ptr y _)) => (SUBL x (MOVLf2i y))
+(ANDQload x [off] {sym} ptr (MOVSDstore [off] {sym} ptr y _)) => (ANDQ x (MOVQf2i y))
+(ANDLload x [off] {sym} ptr (MOVSSstore [off] {sym} ptr y _)) => (ANDL x (MOVLf2i y))
+( ORQload x [off] {sym} ptr (MOVSDstore [off] {sym} ptr y _)) => ( ORQ x (MOVQf2i y))
+( ORLload x [off] {sym} ptr (MOVSSstore [off] {sym} ptr y _)) => ( ORL x (MOVLf2i y))
+(XORQload x [off] {sym} ptr (MOVSDstore [off] {sym} ptr y _)) => (XORQ x (MOVQf2i y))
+(XORLload x [off] {sym} ptr (MOVSSstore [off] {sym} ptr y _)) => (XORL x (MOVLf2i y))
+
+(ADDSDload x [off] {sym} ptr (MOVQstore [off] {sym} ptr y _)) => (ADDSD x (MOVQi2f y))
+(ADDSSload x [off] {sym} ptr (MOVLstore [off] {sym} ptr y _)) => (ADDSS x (MOVLi2f y))
+(SUBSDload x [off] {sym} ptr (MOVQstore [off] {sym} ptr y _)) => (SUBSD x (MOVQi2f y))
+(SUBSSload x [off] {sym} ptr (MOVLstore [off] {sym} ptr y _)) => (SUBSS x (MOVLi2f y))
+(MULSDload x [off] {sym} ptr (MOVQstore [off] {sym} ptr y _)) => (MULSD x (MOVQi2f y))
+(MULSSload x [off] {sym} ptr (MOVLstore [off] {sym} ptr y _)) => (MULSS x (MOVLi2f y))
+
+// Redirect stores to use the other register set.
+(MOVQstore  [off] {sym} ptr (MOVQf2i val) mem) => (MOVSDstore [off] {sym} ptr val mem)
+(MOVLstore  [off] {sym} ptr (MOVLf2i val) mem) => (MOVSSstore [off] {sym} ptr val mem)
+(MOVSDstore [off] {sym} ptr (MOVQi2f val) mem) => (MOVQstore  [off] {sym} ptr val mem)
+(MOVSSstore [off] {sym} ptr (MOVLi2f val) mem) => (MOVLstore  [off] {sym} ptr val mem)
+
+// Load args directly into the register class where it will be used.
+// We do this by just modifying the type of the Arg.
+(MOVQf2i <t> (Arg <u> [off] {sym})) && t.Size() == u.Size() => @b.Func.Entry (Arg <t> [off] {sym})
+(MOVLf2i <t> (Arg <u> [off] {sym})) && t.Size() == u.Size() => @b.Func.Entry (Arg <t> [off] {sym})
+(MOVQi2f <t> (Arg <u> [off] {sym})) && t.Size() == u.Size() => @b.Func.Entry (Arg <t> [off] {sym})
+(MOVLi2f <t> (Arg <u> [off] {sym})) && t.Size() == u.Size() => @b.Func.Entry (Arg <t> [off] {sym})
+
+// LEAQ is rematerializeable, so this helps to avoid register spill.
+// See issue 22947 for details
+(ADD(Q|L)const [off] x:(SP)) => (LEA(Q|L) [off] x)
+
+// HMULx is commutative, but its first argument must go in AX.
+// If possible, put a rematerializeable value in the first argument slot,
+// to reduce the odds that another value will be have to spilled
+// specifically to free up AX.
+(HMUL(Q|L)  x y) && !x.rematerializeable() && y.rematerializeable() => (HMUL(Q|L)  y x)
+(HMUL(Q|L)U x y) && !x.rematerializeable() && y.rematerializeable() => (HMUL(Q|L)U y x)
+
+// Fold loads into compares
+// Note: these may be undone by the flagalloc pass.
+(CMP(Q|L|W|B) l:(MOV(Q|L|W|B)load {sym} [off] ptr mem) x) && canMergeLoad(v, l) && clobber(l) => (CMP(Q|L|W|B)load {sym} [off] ptr x mem)
+(CMP(Q|L|W|B) x l:(MOV(Q|L|W|B)load {sym} [off] ptr mem)) && canMergeLoad(v, l) && clobber(l) => (InvertFlags (CMP(Q|L|W|B)load {sym} [off] ptr x mem))
+
+(CMP(Q|L)const l:(MOV(Q|L)load {sym} [off] ptr mem) [c])
+	&& l.Uses == 1
+	&& clobber(l) =>
[email protected] (CMP(Q|L)constload {sym} [makeValAndOff(c,off)] ptr mem)
+(CMP(W|B)const l:(MOV(W|B)load {sym} [off] ptr mem) [c])
+	&& l.Uses == 1
+	&& clobber(l) =>
[email protected] (CMP(W|B)constload {sym} [makeValAndOff(int32(c),off)] ptr mem)
+
+(CMPQload {sym} [off] ptr (MOVQconst [c]) mem) && validVal(c) => (CMPQconstload {sym} [makeValAndOff(int32(c),off)] ptr mem)
+(CMPLload {sym} [off] ptr (MOVLconst [c]) mem) => (CMPLconstload {sym} [makeValAndOff(c,off)] ptr mem)
+(CMPWload {sym} [off] ptr (MOVLconst [c]) mem) => (CMPWconstload {sym} [makeValAndOff(int32(int16(c)),off)] ptr mem)
+(CMPBload {sym} [off] ptr (MOVLconst [c]) mem) => (CMPBconstload {sym} [makeValAndOff(int32(int8(c)),off)] ptr mem)
+
+(TEST(Q|L|W|B)  l:(MOV(Q|L|W|B)load {sym} [off] ptr mem) l2)
+        && l == l2
+	&& l.Uses == 2
+	&& clobber(l) =>
+  @l.Block (CMP(Q|L|W|B)constload {sym} [makeValAndOff(0, off)] ptr mem)
+
+// Convert ANDload to MOVload when we can do the AND in a containing TEST op.
+// Only do when it's within the same block, so we don't have flags live across basic block boundaries.
+// See issue 44228.
+(TEST(Q|L) a:(AND(Q|L)load [off] {sym} x ptr mem) a) && a.Uses == 2 && a.Block == v.Block && clobber(a) => (TEST(Q|L) (MOV(Q|L)load <a.Type> [off] {sym} ptr mem) x)
+
+(MOVBload [off] {sym} (SB) _) && symIsRO(sym) => (MOVLconst [int32(read8(sym, int64(off)))])
+(MOVWload [off] {sym} (SB) _) && symIsRO(sym) => (MOVLconst [int32(read16(sym, int64(off), config.ctxt.Arch.ByteOrder))])
+(MOVLload [off] {sym} (SB) _) && symIsRO(sym) => (MOVQconst [int64(read32(sym, int64(off), config.ctxt.Arch.ByteOrder))])
+(MOVQload [off] {sym} (SB) _) && symIsRO(sym) => (MOVQconst [int64(read64(sym, int64(off), config.ctxt.Arch.ByteOrder))])
+(MOVOstore [dstOff] {dstSym} ptr (MOVOload [srcOff] {srcSym} (SB) _) mem) && symIsRO(srcSym) =>
+  (MOVQstore [dstOff+8] {dstSym} ptr (MOVQconst [int64(read64(srcSym, int64(srcOff)+8, config.ctxt.Arch.ByteOrder))])
+    (MOVQstore [dstOff] {dstSym} ptr (MOVQconst [int64(read64(srcSym, int64(srcOff), config.ctxt.Arch.ByteOrder))]) mem))
+
+// Arch-specific inlining for small or disjoint runtime.memmove
+// Match post-lowering calls, memory version.
+(SelectN [0] call:(CALLstatic {sym} s1:(MOVQstoreconst _ [sc] s2:(MOVQstore _ src s3:(MOVQstore _ dst mem)))))
+	&& sc.Val64() >= 0
+	&& isSameCall(sym, "runtime.memmove")
+	&& s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1
+	&& isInlinableMemmove(dst, src, sc.Val64(), config)
+	&& clobber(s1, s2, s3, call)
+	=> (Move [sc.Val64()] dst src mem)
+
+// Match post-lowering calls, register version.
+(SelectN [0] call:(CALLstatic {sym} dst src (MOVQconst [sz]) mem))
+	&& sz >= 0
+	&& isSameCall(sym, "runtime.memmove")
+	&& call.Uses == 1
+	&& isInlinableMemmove(dst, src, sz, config)
+	&& clobber(call)
+	=> (Move [sz] dst src mem)
+
+// Prefetch instructions
+(PrefetchCache ...)   => (PrefetchT0 ...)
+(PrefetchCacheStreamed ...) => (PrefetchNTA ...)
+
+// CPUID feature: BMI1.
+(AND(Q|L) x (NOT(Q|L) y))           && buildcfg.GOAMD64 >= 3 => (ANDN(Q|L) x y)
+(AND(Q|L) x (NEG(Q|L) x))           && buildcfg.GOAMD64 >= 3 => (BLSI(Q|L) x)
+(XOR(Q|L) x (ADD(Q|L)const [-1] x)) && buildcfg.GOAMD64 >= 3 => (BLSMSK(Q|L) x)
+(AND(Q|L) x (ADD(Q|L)const [-1] x)) && buildcfg.GOAMD64 >= 3 => (BLSR(Q|L) x)
+
+(BSWAP(Q|L) (BSWAP(Q|L) p)) => p
+
+// CPUID feature: MOVBE.
+(MOV(Q|L)store [i] {s} p x:(BSWAP(Q|L) w) mem) && x.Uses == 1 && buildcfg.GOAMD64 >= 3 => (MOVBE(Q|L)store [i] {s} p w mem)
+(BSWAP(Q|L) x:(MOV(Q|L)load [i] {s} p mem))    && x.Uses == 1 && buildcfg.GOAMD64 >= 3 => (MOVBE(Q|L)load [i] {s} p mem)
+(BSWAP(Q|L) (MOVBE(Q|L)load [i] {s} p m))    => (MOV(Q|L)load [i] {s} p m)
+(MOVBE(Q|L)store [i] {s} p (BSWAP(Q|L) x) m) => (MOV(Q|L)store [i] {s} p x m)
+(MOVWstore [i] {s} p x:(ROLWconst [8] w) mem)   && x.Uses == 1 && buildcfg.GOAMD64 >= 3 => (MOVBEWstore [i] {s} p w mem)
+(MOVBEWstore [i] {s} p x:(ROLWconst [8] w) mem) && x.Uses == 1 => (MOVWstore [i] {s} p w mem)
+
+(ORQ                   x0:(MOVBELload [i0] {s} p mem)
+    sh:(SHLQconst [32] x1:(MOVBELload [i1] {s} p mem)))
+  && i0 == i1+4
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && sh.Uses == 1
+  && mergePoint(b,x0,x1) != nil
+  && clobber(x0, x1, sh)
+  => @mergePoint(b,x0,x1) (MOVBEQload [i1] {s} p mem)
+
+(ORQ                   x0:(MOVBELload [i] {s} p0 mem)
+    sh:(SHLQconst [32] x1:(MOVBELload [i] {s} p1 mem)))
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && sh.Uses == 1
+  && sequentialAddresses(p1, p0, 4)
+  && mergePoint(b,x0,x1) != nil
+  && clobber(x0, x1, sh)
+  => @mergePoint(b,x0,x1) (MOVBEQload [i] {s} p1 mem)
+
+(SAR(Q|L) l:(MOV(Q|L)load [off] {sym} ptr mem) x) && buildcfg.GOAMD64 >= 3 && canMergeLoad(v, l) && clobber(l) => (SARX(Q|L)load [off] {sym} ptr x mem)
+(SHL(Q|L) l:(MOV(Q|L)load [off] {sym} ptr mem) x) && buildcfg.GOAMD64 >= 3 && canMergeLoad(v, l) && clobber(l) => (SHLX(Q|L)load [off] {sym} ptr x mem)
+(SHR(Q|L) l:(MOV(Q|L)load [off] {sym} ptr mem) x) && buildcfg.GOAMD64 >= 3 && canMergeLoad(v, l) && clobber(l) => (SHRX(Q|L)load [off] {sym} ptr x mem)
+
+((SHL|SHR|SAR)XQload [off] {sym} ptr (MOVQconst [c]) mem) => ((SHL|SHR|SAR)Qconst [int8(c&63)] (MOVQload [off] {sym} ptr mem))
+((SHL|SHR|SAR)XQload [off] {sym} ptr (MOVLconst [c]) mem) => ((SHL|SHR|SAR)Qconst [int8(c&63)] (MOVQload [off] {sym} ptr mem))
+((SHL|SHR|SAR)XLload [off] {sym} ptr (MOVLconst [c]) mem) => ((SHL|SHR|SAR)Lconst [int8(c&31)] (MOVLload [off] {sym} ptr mem))
diff --git a/src/cmd/compile/internal/ssa/_gen/AMD64Ops.go b/src/cmd/compile/internal/ssa/_gen/AMD64Ops.go
new file mode 100644
index 0000000..cbe1f5b
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/_gen/AMD64Ops.go
@@ -0,0 +1,1133 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "strings"
+
+// Notes:
+//  - Integer types live in the low portion of registers. Upper portions are junk.
+//  - Boolean types use the low-order byte of a register. 0=false, 1=true.
+//    Upper bytes are junk.
+//  - Floating-point types live in the low natural slot of an sse2 register.
+//    Unused portions are junk.
+//  - We do not use AH,BH,CH,DH registers.
+//  - When doing sub-register operations, we try to write the whole
+//    destination register to avoid a partial-register write.
+//  - Unused portions of AuxInt (or the Val portion of ValAndOff) are
+//    filled by sign-extending the used portion.  Users of AuxInt which interpret
+//    AuxInt as unsigned (e.g. shifts) must be careful.
+//  - All SymOff opcodes require their offset to fit in an int32.
+
+// Suffixes encode the bit width of various instructions.
+// Q (quad word) = 64 bit
+// L (long word) = 32 bit
+// W (word)      = 16 bit
+// B (byte)      = 8 bit
+// D (double)    = 64 bit float
+// S (single)    = 32 bit float
+
+// copied from ../../amd64/reg.go
+var regNamesAMD64 = []string{
+	"AX",
+	"CX",
+	"DX",
+	"BX",
+	"SP",
+	"BP",
+	"SI",
+	"DI",
+	"R8",
+	"R9",
+	"R10",
+	"R11",
+	"R12",
+	"R13",
+	"g", // a.k.a. R14
+	"R15",
+	"X0",
+	"X1",
+	"X2",
+	"X3",
+	"X4",
+	"X5",
+	"X6",
+	"X7",
+	"X8",
+	"X9",
+	"X10",
+	"X11",
+	"X12",
+	"X13",
+	"X14",
+	"X15", // constant 0 in ABIInternal
+
+	// If you add registers, update asyncPreempt in runtime
+
+	// pseudo-registers
+	"SB",
+}
+
+func init() {
+	// Make map from reg names to reg integers.
+	if len(regNamesAMD64) > 64 {
+		panic("too many registers")
+	}
+	num := map[string]int{}
+	for i, name := range regNamesAMD64 {
+		num[name] = i
+	}
+	buildReg := func(s string) regMask {
+		m := regMask(0)
+		for _, r := range strings.Split(s, " ") {
+			if n, ok := num[r]; ok {
+				m |= regMask(1) << uint(n)
+				continue
+			}
+			panic("register " + r + " not found")
+		}
+		return m
+	}
+
+	// Common individual register masks
+	var (
+		ax         = buildReg("AX")
+		cx         = buildReg("CX")
+		dx         = buildReg("DX")
+		bx         = buildReg("BX")
+		gp         = buildReg("AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15")
+		g          = buildReg("g")
+		fp         = buildReg("X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14")
+		x15        = buildReg("X15")
+		gpsp       = gp | buildReg("SP")
+		gpspsb     = gpsp | buildReg("SB")
+		gpspsbg    = gpspsb | g
+		callerSave = gp | fp | g // runtime.setg (and anything calling it) may clobber g
+	)
+	// Common slices of register masks
+	var (
+		gponly = []regMask{gp}
+		fponly = []regMask{fp}
+	)
+
+	// Common regInfo
+	var (
+		gp01           = regInfo{inputs: nil, outputs: gponly}
+		gp11           = regInfo{inputs: []regMask{gp}, outputs: gponly}
+		gp11sp         = regInfo{inputs: []regMask{gpsp}, outputs: gponly}
+		gp11sb         = regInfo{inputs: []regMask{gpspsbg}, outputs: gponly}
+		gp21           = regInfo{inputs: []regMask{gp, gp}, outputs: gponly}
+		gp21sp         = regInfo{inputs: []regMask{gpsp, gp}, outputs: gponly}
+		gp21sb         = regInfo{inputs: []regMask{gpspsbg, gpsp}, outputs: gponly}
+		gp21shift      = regInfo{inputs: []regMask{gp, cx}, outputs: []regMask{gp}}
+		gp31shift      = regInfo{inputs: []regMask{gp, gp, cx}, outputs: []regMask{gp}}
+		gp11div        = regInfo{inputs: []regMask{ax, gpsp &^ dx}, outputs: []regMask{ax, dx}}
+		gp21hmul       = regInfo{inputs: []regMask{ax, gpsp}, outputs: []regMask{dx}, clobbers: ax}
+		gp21flags      = regInfo{inputs: []regMask{gp, gp}, outputs: []regMask{gp, 0}}
+		gp2flags1flags = regInfo{inputs: []regMask{gp, gp, 0}, outputs: []regMask{gp, 0}}
+
+		gp2flags     = regInfo{inputs: []regMask{gpsp, gpsp}}
+		gp1flags     = regInfo{inputs: []regMask{gpsp}}
+		gp0flagsLoad = regInfo{inputs: []regMask{gpspsbg, 0}}
+		gp1flagsLoad = regInfo{inputs: []regMask{gpspsbg, gpsp, 0}}
+		gp2flagsLoad = regInfo{inputs: []regMask{gpspsbg, gpsp, gpsp, 0}}
+		flagsgp      = regInfo{inputs: nil, outputs: gponly}
+
+		gp11flags      = regInfo{inputs: []regMask{gp}, outputs: []regMask{gp, 0}}
+		gp1flags1flags = regInfo{inputs: []regMask{gp, 0}, outputs: []regMask{gp, 0}}
+
+		readflags = regInfo{inputs: nil, outputs: gponly}
+
+		gpload         = regInfo{inputs: []regMask{gpspsbg, 0}, outputs: gponly}
+		gp21load       = regInfo{inputs: []regMask{gp, gpspsbg, 0}, outputs: gponly}
+		gploadidx      = regInfo{inputs: []regMask{gpspsbg, gpsp, 0}, outputs: gponly}
+		gp21loadidx    = regInfo{inputs: []regMask{gp, gpspsbg, gpsp, 0}, outputs: gponly}
+		gp21shxload    = regInfo{inputs: []regMask{gpspsbg, gp, 0}, outputs: gponly}
+		gp21shxloadidx = regInfo{inputs: []regMask{gpspsbg, gpsp, gp, 0}, outputs: gponly}
+
+		gpstore         = regInfo{inputs: []regMask{gpspsbg, gpsp, 0}}
+		gpstoreconst    = regInfo{inputs: []regMask{gpspsbg, 0}}
+		gpstoreidx      = regInfo{inputs: []regMask{gpspsbg, gpsp, gpsp, 0}}
+		gpstoreconstidx = regInfo{inputs: []regMask{gpspsbg, gpsp, 0}}
+		gpstorexchg     = regInfo{inputs: []regMask{gp, gpspsbg, 0}, outputs: []regMask{gp}}
+		cmpxchg         = regInfo{inputs: []regMask{gp, ax, gp, 0}, outputs: []regMask{gp, 0}, clobbers: ax}
+
+		fp01        = regInfo{inputs: nil, outputs: fponly}
+		fp21        = regInfo{inputs: []regMask{fp, fp}, outputs: fponly}
+		fp31        = regInfo{inputs: []regMask{fp, fp, fp}, outputs: fponly}
+		fp21load    = regInfo{inputs: []regMask{fp, gpspsbg, 0}, outputs: fponly}
+		fp21loadidx = regInfo{inputs: []regMask{fp, gpspsbg, gpspsb, 0}, outputs: fponly}
+		fpgp        = regInfo{inputs: fponly, outputs: gponly}
+		gpfp        = regInfo{inputs: gponly, outputs: fponly}
+		fp11        = regInfo{inputs: fponly, outputs: fponly}
+		fp2flags    = regInfo{inputs: []regMask{fp, fp}}
+
+		fpload    = regInfo{inputs: []regMask{gpspsb, 0}, outputs: fponly}
+		fploadidx = regInfo{inputs: []regMask{gpspsb, gpsp, 0}, outputs: fponly}
+
+		fpstore    = regInfo{inputs: []regMask{gpspsb, fp, 0}}
+		fpstoreidx = regInfo{inputs: []regMask{gpspsb, gpsp, fp, 0}}
+
+		prefreg = regInfo{inputs: []regMask{gpspsbg}}
+	)
+
+	var AMD64ops = []opData{
+		// {ADD,SUB,MUL,DIV}Sx: floating-point arithmetic
+		// x==S for float32, x==D for float64
+		// computes arg0 OP arg1
+		{name: "ADDSS", argLength: 2, reg: fp21, asm: "ADDSS", commutative: true, resultInArg0: true},
+		{name: "ADDSD", argLength: 2, reg: fp21, asm: "ADDSD", commutative: true, resultInArg0: true},
+		{name: "SUBSS", argLength: 2, reg: fp21, asm: "SUBSS", resultInArg0: true},
+		{name: "SUBSD", argLength: 2, reg: fp21, asm: "SUBSD", resultInArg0: true},
+		{name: "MULSS", argLength: 2, reg: fp21, asm: "MULSS", commutative: true, resultInArg0: true},
+		{name: "MULSD", argLength: 2, reg: fp21, asm: "MULSD", commutative: true, resultInArg0: true},
+		{name: "DIVSS", argLength: 2, reg: fp21, asm: "DIVSS", resultInArg0: true},
+		{name: "DIVSD", argLength: 2, reg: fp21, asm: "DIVSD", resultInArg0: true},
+
+		// MOVSxload: floating-point loads
+		// x==S for float32, x==D for float64
+		// load from arg0+auxint+aux, arg1 = mem
+		{name: "MOVSSload", argLength: 2, reg: fpload, asm: "MOVSS", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},
+		{name: "MOVSDload", argLength: 2, reg: fpload, asm: "MOVSD", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},
+
+		// MOVSxconst: floatint-point constants
+		// x==S for float32, x==D for float64
+		{name: "MOVSSconst", reg: fp01, asm: "MOVSS", aux: "Float32", rematerializeable: true},
+		{name: "MOVSDconst", reg: fp01, asm: "MOVSD", aux: "Float64", rematerializeable: true},
+
+		// MOVSxloadidx: floating-point indexed loads
+		// x==S for float32, x==D for float64
+		// load from arg0 + scale*arg1+auxint+aux, arg2 = mem
+		{name: "MOVSSloadidx1", argLength: 3, reg: fploadidx, asm: "MOVSS", scale: 1, aux: "SymOff", symEffect: "Read"},
+		{name: "MOVSSloadidx4", argLength: 3, reg: fploadidx, asm: "MOVSS", scale: 4, aux: "SymOff", symEffect: "Read"},
+		{name: "MOVSDloadidx1", argLength: 3, reg: fploadidx, asm: "MOVSD", scale: 1, aux: "SymOff", symEffect: "Read"},
+		{name: "MOVSDloadidx8", argLength: 3, reg: fploadidx, asm: "MOVSD", scale: 8, aux: "SymOff", symEffect: "Read"},
+
+		// MOVSxstore: floating-point stores
+		// x==S for float32, x==D for float64
+		// does *(arg0+auxint+aux) = arg1, arg2 = mem
+		{name: "MOVSSstore", argLength: 3, reg: fpstore, asm: "MOVSS", aux: "SymOff", faultOnNilArg0: true, symEffect: "Write"},
+		{name: "MOVSDstore", argLength: 3, reg: fpstore, asm: "MOVSD", aux: "SymOff", faultOnNilArg0: true, symEffect: "Write"},
+
+		// MOVSxstoreidx: floating-point indexed stores
+		// x==S for float32, x==D for float64
+		// does *(arg0+scale*arg1+auxint+aux) = arg2, arg3 = mem
+		{name: "MOVSSstoreidx1", argLength: 4, reg: fpstoreidx, asm: "MOVSS", scale: 1, aux: "SymOff", symEffect: "Write"},
+		{name: "MOVSSstoreidx4", argLength: 4, reg: fpstoreidx, asm: "MOVSS", scale: 4, aux: "SymOff", symEffect: "Write"},
+		{name: "MOVSDstoreidx1", argLength: 4, reg: fpstoreidx, asm: "MOVSD", scale: 1, aux: "SymOff", symEffect: "Write"},
+		{name: "MOVSDstoreidx8", argLength: 4, reg: fpstoreidx, asm: "MOVSD", scale: 8, aux: "SymOff", symEffect: "Write"},
+
+		// {ADD,SUB,MUL,DIV}Sxload: floating-point load / op combo
+		// x==S for float32, x==D for float64
+		// computes arg0 OP *(arg1+auxint+aux), arg2=mem
+		{name: "ADDSSload", argLength: 3, reg: fp21load, asm: "ADDSS", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"},
+		{name: "ADDSDload", argLength: 3, reg: fp21load, asm: "ADDSD", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"},
+		{name: "SUBSSload", argLength: 3, reg: fp21load, asm: "SUBSS", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"},
+		{name: "SUBSDload", argLength: 3, reg: fp21load, asm: "SUBSD", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"},
+		{name: "MULSSload", argLength: 3, reg: fp21load, asm: "MULSS", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"},
+		{name: "MULSDload", argLength: 3, reg: fp21load, asm: "MULSD", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"},
+		{name: "DIVSSload", argLength: 3, reg: fp21load, asm: "DIVSS", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"},
+		{name: "DIVSDload", argLength: 3, reg: fp21load, asm: "DIVSD", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"},
+
+		// {ADD,SUB,MUL,DIV}Sxloadidx: floating-point indexed load / op combo
+		// x==S for float32, x==D for float64
+		// computes arg0 OP *(arg1+scale*arg2+auxint+aux), arg3=mem
+		{name: "ADDSSloadidx1", argLength: 4, reg: fp21loadidx, asm: "ADDSS", scale: 1, aux: "SymOff", resultInArg0: true, symEffect: "Read"},
+		{name: "ADDSSloadidx4", argLength: 4, reg: fp21loadidx, asm: "ADDSS", scale: 4, aux: "SymOff", resultInArg0: true, symEffect: "Read"},
+		{name: "ADDSDloadidx1", argLength: 4, reg: fp21loadidx, asm: "ADDSD", scale: 1, aux: "SymOff", resultInArg0: true, symEffect: "Read"},
+		{name: "ADDSDloadidx8", argLength: 4, reg: fp21loadidx, asm: "ADDSD", scale: 8, aux: "SymOff", resultInArg0: true, symEffect: "Read"},
+		{name: "SUBSSloadidx1", argLength: 4, reg: fp21loadidx, asm: "SUBSS", scale: 1, aux: "SymOff", resultInArg0: true, symEffect: "Read"},
+		{name: "SUBSSloadidx4", argLength: 4, reg: fp21loadidx, asm: "SUBSS", scale: 4, aux: "SymOff", resultInArg0: true, symEffect: "Read"},
+		{name: "SUBSDloadidx1", argLength: 4, reg: fp21loadidx, asm: "SUBSD", scale: 1, aux: "SymOff", resultInArg0: true, symEffect: "Read"},
+		{name: "SUBSDloadidx8", argLength: 4, reg: fp21loadidx, asm: "SUBSD", scale: 8, aux: "SymOff", resultInArg0: true, symEffect: "Read"},
+		{name: "MULSSloadidx1", argLength: 4, reg: fp21loadidx, asm: "MULSS", scale: 1, aux: "SymOff", resultInArg0: true, symEffect: "Read"},
+		{name: "MULSSloadidx4", argLength: 4, reg: fp21loadidx, asm: "MULSS", scale: 4, aux: "SymOff", resultInArg0: true, symEffect: "Read"},
+		{name: "MULSDloadidx1", argLength: 4, reg: fp21loadidx, asm: "MULSD", scale: 1, aux: "SymOff", resultInArg0: true, symEffect: "Read"},
+		{name: "MULSDloadidx8", argLength: 4, reg: fp21loadidx, asm: "MULSD", scale: 8, aux: "SymOff", resultInArg0: true, symEffect: "Read"},
+		{name: "DIVSSloadidx1", argLength: 4, reg: fp21loadidx, asm: "DIVSS", scale: 1, aux: "SymOff", resultInArg0: true, symEffect: "Read"},
+		{name: "DIVSSloadidx4", argLength: 4, reg: fp21loadidx, asm: "DIVSS", scale: 4, aux: "SymOff", resultInArg0: true, symEffect: "Read"},
+		{name: "DIVSDloadidx1", argLength: 4, reg: fp21loadidx, asm: "DIVSD", scale: 1, aux: "SymOff", resultInArg0: true, symEffect: "Read"},
+		{name: "DIVSDloadidx8", argLength: 4, reg: fp21loadidx, asm: "DIVSD", scale: 8, aux: "SymOff", resultInArg0: true, symEffect: "Read"},
+
+		// {ADD,SUB,MUL,DIV,AND,OR,XOR}x: binary integer ops
+		//   unadorned versions compute arg0 OP arg1
+		//       const versions compute arg0 OP auxint (auxint is a sign-extended 32-bit value)
+		// constmodify versions compute *(arg0+ValAndOff(AuxInt).Off().aux) OP= ValAndOff(AuxInt).Val(), arg1 = mem
+		// x==L operations zero the upper 4 bytes of the destination register (not meaningful for constmodify versions).
+		{name: "ADDQ", argLength: 2, reg: gp21sp, asm: "ADDQ", commutative: true, clobberFlags: true},
+		{name: "ADDL", argLength: 2, reg: gp21sp, asm: "ADDL", commutative: true, clobberFlags: true},
+		{name: "ADDQconst", argLength: 1, reg: gp11sp, asm: "ADDQ", aux: "Int32", typ: "UInt64", clobberFlags: true},
+		{name: "ADDLconst", argLength: 1, reg: gp11sp, asm: "ADDL", aux: "Int32", clobberFlags: true},
+		{name: "ADDQconstmodify", argLength: 2, reg: gpstoreconst, asm: "ADDQ", aux: "SymValAndOff", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"},
+		{name: "ADDLconstmodify", argLength: 2, reg: gpstoreconst, asm: "ADDL", aux: "SymValAndOff", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"},
+
+		{name: "SUBQ", argLength: 2, reg: gp21, asm: "SUBQ", resultInArg0: true, clobberFlags: true},
+		{name: "SUBL", argLength: 2, reg: gp21, asm: "SUBL", resultInArg0: true, clobberFlags: true},
+		{name: "SUBQconst", argLength: 1, reg: gp11, asm: "SUBQ", aux: "Int32", resultInArg0: true, clobberFlags: true},
+		{name: "SUBLconst", argLength: 1, reg: gp11, asm: "SUBL", aux: "Int32", resultInArg0: true, clobberFlags: true},
+
+		{name: "MULQ", argLength: 2, reg: gp21, asm: "IMULQ", commutative: true, resultInArg0: true, clobberFlags: true},
+		{name: "MULL", argLength: 2, reg: gp21, asm: "IMULL", commutative: true, resultInArg0: true, clobberFlags: true},
+		{name: "MULQconst", argLength: 1, reg: gp11, asm: "IMUL3Q", aux: "Int32", clobberFlags: true},
+		{name: "MULLconst", argLength: 1, reg: gp11, asm: "IMUL3L", aux: "Int32", clobberFlags: true},
+
+		// Let x = arg0*arg1 (full 32x32->64  unsigned multiply). Returns uint32(x), and flags set to overflow if uint32(x) != x.
+		{name: "MULLU", argLength: 2, reg: regInfo{inputs: []regMask{ax, gpsp}, outputs: []regMask{ax, 0}, clobbers: dx}, typ: "(UInt32,Flags)", asm: "MULL", commutative: true, clobberFlags: true},
+		// Let x = arg0*arg1 (full 64x64->128 unsigned multiply). Returns uint64(x), and flags set to overflow if uint64(x) != x.
+		{name: "MULQU", argLength: 2, reg: regInfo{inputs: []regMask{ax, gpsp}, outputs: []regMask{ax, 0}, clobbers: dx}, typ: "(UInt64,Flags)", asm: "MULQ", commutative: true, clobberFlags: true},
+
+		// HMULx[U]: computes the high bits of an integer multiply.
+		// computes arg0 * arg1 >> (x==L?32:64)
+		// The multiply is unsigned for the U versions, signed for the non-U versions.
+		// HMULx[U] are intentionally not marked as commutative, even though they are.
+		// This is because they have asymmetric register requirements.
+		// There are rewrite rules to try to place arguments in preferable slots.
+		{name: "HMULQ", argLength: 2, reg: gp21hmul, asm: "IMULQ", clobberFlags: true},
+		{name: "HMULL", argLength: 2, reg: gp21hmul, asm: "IMULL", clobberFlags: true},
+		{name: "HMULQU", argLength: 2, reg: gp21hmul, asm: "MULQ", clobberFlags: true},
+		{name: "HMULLU", argLength: 2, reg: gp21hmul, asm: "MULL", clobberFlags: true},
+
+		// (arg0 + arg1) / 2 as unsigned, all 64 result bits
+		{name: "AVGQU", argLength: 2, reg: gp21, commutative: true, resultInArg0: true, clobberFlags: true},
+
+		// DIVx[U] computes [arg0 / arg1, arg0 % arg1]
+		// For signed versions, AuxInt non-zero means that the divisor has been proved to be not -1.
+		{name: "DIVQ", argLength: 2, reg: gp11div, typ: "(Int64,Int64)", asm: "IDIVQ", aux: "Bool", clobberFlags: true},
+		{name: "DIVL", argLength: 2, reg: gp11div, typ: "(Int32,Int32)", asm: "IDIVL", aux: "Bool", clobberFlags: true},
+		{name: "DIVW", argLength: 2, reg: gp11div, typ: "(Int16,Int16)", asm: "IDIVW", aux: "Bool", clobberFlags: true},
+		{name: "DIVQU", argLength: 2, reg: gp11div, typ: "(UInt64,UInt64)", asm: "DIVQ", clobberFlags: true},
+		{name: "DIVLU", argLength: 2, reg: gp11div, typ: "(UInt32,UInt32)", asm: "DIVL", clobberFlags: true},
+		{name: "DIVWU", argLength: 2, reg: gp11div, typ: "(UInt16,UInt16)", asm: "DIVW", clobberFlags: true},
+
+		// computes -arg0, flags set for 0-arg0.
+		{name: "NEGLflags", argLength: 1, reg: gp11flags, typ: "(UInt32,Flags)", asm: "NEGL", resultInArg0: true},
+
+		// The following 4 add opcodes return the low 64 bits of the sum in the first result and
+		// the carry (the 65th bit) in the carry flag.
+		{name: "ADDQcarry", argLength: 2, reg: gp21flags, typ: "(UInt64,Flags)", asm: "ADDQ", commutative: true, resultInArg0: true}, // r = arg0+arg1
+		{name: "ADCQ", argLength: 3, reg: gp2flags1flags, typ: "(UInt64,Flags)", asm: "ADCQ", commutative: true, resultInArg0: true}, // r = arg0+arg1+carry(arg2)
+		{name: "ADDQconstcarry", argLength: 1, reg: gp11flags, typ: "(UInt64,Flags)", asm: "ADDQ", aux: "Int32", resultInArg0: true}, // r = arg0+auxint
+		{name: "ADCQconst", argLength: 2, reg: gp1flags1flags, typ: "(UInt64,Flags)", asm: "ADCQ", aux: "Int32", resultInArg0: true}, // r = arg0+auxint+carry(arg1)
+
+		// The following 4 add opcodes return the low 64 bits of the difference in the first result and
+		// the borrow (if the result is negative) in the carry flag.
+		{name: "SUBQborrow", argLength: 2, reg: gp21flags, typ: "(UInt64,Flags)", asm: "SUBQ", resultInArg0: true},                    // r = arg0-arg1
+		{name: "SBBQ", argLength: 3, reg: gp2flags1flags, typ: "(UInt64,Flags)", asm: "SBBQ", resultInArg0: true},                     // r = arg0-(arg1+carry(arg2))
+		{name: "SUBQconstborrow", argLength: 1, reg: gp11flags, typ: "(UInt64,Flags)", asm: "SUBQ", aux: "Int32", resultInArg0: true}, // r = arg0-auxint
+		{name: "SBBQconst", argLength: 2, reg: gp1flags1flags, typ: "(UInt64,Flags)", asm: "SBBQ", aux: "Int32", resultInArg0: true},  // r = arg0-(auxint+carry(arg1))
+
+		{name: "MULQU2", argLength: 2, reg: regInfo{inputs: []regMask{ax, gpsp}, outputs: []regMask{dx, ax}}, commutative: true, asm: "MULQ", clobberFlags: true}, // arg0 * arg1, returns (hi, lo)
+		{name: "DIVQU2", argLength: 3, reg: regInfo{inputs: []regMask{dx, ax, gpsp}, outputs: []regMask{ax, dx}}, asm: "DIVQ", clobberFlags: true},                // arg0:arg1 / arg2 (128-bit divided by 64-bit), returns (q, r)
+
+		{name: "ANDQ", argLength: 2, reg: gp21, asm: "ANDQ", commutative: true, resultInArg0: true, clobberFlags: true},                                                 // arg0 & arg1
+		{name: "ANDL", argLength: 2, reg: gp21, asm: "ANDL", commutative: true, resultInArg0: true, clobberFlags: true},                                                 // arg0 & arg1
+		{name: "ANDQconst", argLength: 1, reg: gp11, asm: "ANDQ", aux: "Int32", resultInArg0: true, clobberFlags: true},                                                 // arg0 & auxint
+		{name: "ANDLconst", argLength: 1, reg: gp11, asm: "ANDL", aux: "Int32", resultInArg0: true, clobberFlags: true},                                                 // arg0 & auxint
+		{name: "ANDQconstmodify", argLength: 2, reg: gpstoreconst, asm: "ANDQ", aux: "SymValAndOff", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"}, // and ValAndOff(AuxInt).Val() to arg0+ValAndOff(AuxInt).Off()+aux, arg1=mem
+		{name: "ANDLconstmodify", argLength: 2, reg: gpstoreconst, asm: "ANDL", aux: "SymValAndOff", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"}, // and ValAndOff(AuxInt).Val() to arg0+ValAndOff(AuxInt).Off()+aux, arg1=mem
+
+		{name: "ORQ", argLength: 2, reg: gp21, asm: "ORQ", commutative: true, resultInArg0: true, clobberFlags: true},                                                 // arg0 | arg1
+		{name: "ORL", argLength: 2, reg: gp21, asm: "ORL", commutative: true, resultInArg0: true, clobberFlags: true},                                                 // arg0 | arg1
+		{name: "ORQconst", argLength: 1, reg: gp11, asm: "ORQ", aux: "Int32", resultInArg0: true, clobberFlags: true},                                                 // arg0 | auxint
+		{name: "ORLconst", argLength: 1, reg: gp11, asm: "ORL", aux: "Int32", resultInArg0: true, clobberFlags: true},                                                 // arg0 | auxint
+		{name: "ORQconstmodify", argLength: 2, reg: gpstoreconst, asm: "ORQ", aux: "SymValAndOff", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"}, // or ValAndOff(AuxInt).Val() to arg0+ValAndOff(AuxInt).Off()+aux, arg1=mem
+		{name: "ORLconstmodify", argLength: 2, reg: gpstoreconst, asm: "ORL", aux: "SymValAndOff", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"}, // or ValAndOff(AuxInt).Val() to arg0+ValAndOff(AuxInt).Off()+aux, arg1=mem
+
+		{name: "XORQ", argLength: 2, reg: gp21, asm: "XORQ", commutative: true, resultInArg0: true, clobberFlags: true},                                                 // arg0 ^ arg1
+		{name: "XORL", argLength: 2, reg: gp21, asm: "XORL", commutative: true, resultInArg0: true, clobberFlags: true},                                                 // arg0 ^ arg1
+		{name: "XORQconst", argLength: 1, reg: gp11, asm: "XORQ", aux: "Int32", resultInArg0: true, clobberFlags: true},                                                 // arg0 ^ auxint
+		{name: "XORLconst", argLength: 1, reg: gp11, asm: "XORL", aux: "Int32", resultInArg0: true, clobberFlags: true},                                                 // arg0 ^ auxint
+		{name: "XORQconstmodify", argLength: 2, reg: gpstoreconst, asm: "XORQ", aux: "SymValAndOff", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"}, // xor ValAndOff(AuxInt).Val() to arg0+ValAndOff(AuxInt).Off()+aux, arg1=mem
+		{name: "XORLconstmodify", argLength: 2, reg: gpstoreconst, asm: "XORL", aux: "SymValAndOff", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"}, // xor ValAndOff(AuxInt).Val() to arg0+ValAndOff(AuxInt).Off()+aux, arg1=mem
+
+		// CMPx: compare arg0 to arg1.
+		{name: "CMPQ", argLength: 2, reg: gp2flags, asm: "CMPQ", typ: "Flags"},
+		{name: "CMPL", argLength: 2, reg: gp2flags, asm: "CMPL", typ: "Flags"},
+		{name: "CMPW", argLength: 2, reg: gp2flags, asm: "CMPW", typ: "Flags"},
+		{name: "CMPB", argLength: 2, reg: gp2flags, asm: "CMPB", typ: "Flags"},
+
+		// CMPxconst: compare arg0 to auxint.
+		{name: "CMPQconst", argLength: 1, reg: gp1flags, asm: "CMPQ", typ: "Flags", aux: "Int32"},
+		{name: "CMPLconst", argLength: 1, reg: gp1flags, asm: "CMPL", typ: "Flags", aux: "Int32"},
+		{name: "CMPWconst", argLength: 1, reg: gp1flags, asm: "CMPW", typ: "Flags", aux: "Int16"},
+		{name: "CMPBconst", argLength: 1, reg: gp1flags, asm: "CMPB", typ: "Flags", aux: "Int8"},
+
+		// CMPxload: compare *(arg0+auxint+aux) to arg1 (in that order). arg2=mem.
+		{name: "CMPQload", argLength: 3, reg: gp1flagsLoad, asm: "CMPQ", aux: "SymOff", typ: "Flags", symEffect: "Read", faultOnNilArg0: true},
+		{name: "CMPLload", argLength: 3, reg: gp1flagsLoad, asm: "CMPL", aux: "SymOff", typ: "Flags", symEffect: "Read", faultOnNilArg0: true},
+		{name: "CMPWload", argLength: 3, reg: gp1flagsLoad, asm: "CMPW", aux: "SymOff", typ: "Flags", symEffect: "Read", faultOnNilArg0: true},
+		{name: "CMPBload", argLength: 3, reg: gp1flagsLoad, asm: "CMPB", aux: "SymOff", typ: "Flags", symEffect: "Read", faultOnNilArg0: true},
+
+		// CMPxconstload: compare *(arg0+ValAndOff(AuxInt).Off()+aux) to ValAndOff(AuxInt).Val() (in that order). arg1=mem.
+		{name: "CMPQconstload", argLength: 2, reg: gp0flagsLoad, asm: "CMPQ", aux: "SymValAndOff", typ: "Flags", symEffect: "Read", faultOnNilArg0: true},
+		{name: "CMPLconstload", argLength: 2, reg: gp0flagsLoad, asm: "CMPL", aux: "SymValAndOff", typ: "Flags", symEffect: "Read", faultOnNilArg0: true},
+		{name: "CMPWconstload", argLength: 2, reg: gp0flagsLoad, asm: "CMPW", aux: "SymValAndOff", typ: "Flags", symEffect: "Read", faultOnNilArg0: true},
+		{name: "CMPBconstload", argLength: 2, reg: gp0flagsLoad, asm: "CMPB", aux: "SymValAndOff", typ: "Flags", symEffect: "Read", faultOnNilArg0: true},
+
+		// CMPxloadidx: compare *(arg0+N*arg1+auxint+aux) to arg2 (in that order). arg3=mem.
+		{name: "CMPQloadidx8", argLength: 4, reg: gp2flagsLoad, asm: "CMPQ", scale: 8, aux: "SymOff", typ: "Flags", symEffect: "Read"},
+		{name: "CMPQloadidx1", argLength: 4, reg: gp2flagsLoad, asm: "CMPQ", scale: 1, commutative: true, aux: "SymOff", typ: "Flags", symEffect: "Read"},
+		{name: "CMPLloadidx4", argLength: 4, reg: gp2flagsLoad, asm: "CMPL", scale: 4, aux: "SymOff", typ: "Flags", symEffect: "Read"},
+		{name: "CMPLloadidx1", argLength: 4, reg: gp2flagsLoad, asm: "CMPL", scale: 1, commutative: true, aux: "SymOff", typ: "Flags", symEffect: "Read"},
+		{name: "CMPWloadidx2", argLength: 4, reg: gp2flagsLoad, asm: "CMPW", scale: 2, aux: "SymOff", typ: "Flags", symEffect: "Read"},
+		{name: "CMPWloadidx1", argLength: 4, reg: gp2flagsLoad, asm: "CMPW", scale: 1, commutative: true, aux: "SymOff", typ: "Flags", symEffect: "Read"},
+		{name: "CMPBloadidx1", argLength: 4, reg: gp2flagsLoad, asm: "CMPB", scale: 1, commutative: true, aux: "SymOff", typ: "Flags", symEffect: "Read"},
+
+		// CMPxconstloadidx: compare *(arg0+N*arg1+ValAndOff(AuxInt).Off()+aux) to ValAndOff(AuxInt).Val() (in that order). arg2=mem.
+		{name: "CMPQconstloadidx8", argLength: 3, reg: gp1flagsLoad, asm: "CMPQ", scale: 8, aux: "SymValAndOff", typ: "Flags", symEffect: "Read"},
+		{name: "CMPQconstloadidx1", argLength: 3, reg: gp1flagsLoad, asm: "CMPQ", scale: 1, commutative: true, aux: "SymValAndOff", typ: "Flags", symEffect: "Read"},
+		{name: "CMPLconstloadidx4", argLength: 3, reg: gp1flagsLoad, asm: "CMPL", scale: 4, aux: "SymValAndOff", typ: "Flags", symEffect: "Read"},
+		{name: "CMPLconstloadidx1", argLength: 3, reg: gp1flagsLoad, asm: "CMPL", scale: 1, commutative: true, aux: "SymValAndOff", typ: "Flags", symEffect: "Read"},
+		{name: "CMPWconstloadidx2", argLength: 3, reg: gp1flagsLoad, asm: "CMPW", scale: 2, aux: "SymValAndOff", typ: "Flags", symEffect: "Read"},
+		{name: "CMPWconstloadidx1", argLength: 3, reg: gp1flagsLoad, asm: "CMPW", scale: 1, commutative: true, aux: "SymValAndOff", typ: "Flags", symEffect: "Read"},
+		{name: "CMPBconstloadidx1", argLength: 3, reg: gp1flagsLoad, asm: "CMPB", scale: 1, commutative: true, aux: "SymValAndOff", typ: "Flags", symEffect: "Read"},
+
+		// UCOMISx: floating-point compare arg0 to arg1
+		// x==S for float32, x==D for float64
+		{name: "UCOMISS", argLength: 2, reg: fp2flags, asm: "UCOMISS", typ: "Flags"},
+		{name: "UCOMISD", argLength: 2, reg: fp2flags, asm: "UCOMISD", typ: "Flags"},
+
+		// bit test/set/clear operations
+		{name: "BTL", argLength: 2, reg: gp2flags, asm: "BTL", typ: "Flags"},                                           // test whether bit arg0%32 in arg1 is set
+		{name: "BTQ", argLength: 2, reg: gp2flags, asm: "BTQ", typ: "Flags"},                                           // test whether bit arg0%64 in arg1 is set
+		{name: "BTCL", argLength: 2, reg: gp21, asm: "BTCL", resultInArg0: true, clobberFlags: true},                   // complement bit arg1%32 in arg0
+		{name: "BTCQ", argLength: 2, reg: gp21, asm: "BTCQ", resultInArg0: true, clobberFlags: true},                   // complement bit arg1%64 in arg0
+		{name: "BTRL", argLength: 2, reg: gp21, asm: "BTRL", resultInArg0: true, clobberFlags: true},                   // reset bit arg1%32 in arg0
+		{name: "BTRQ", argLength: 2, reg: gp21, asm: "BTRQ", resultInArg0: true, clobberFlags: true},                   // reset bit arg1%64 in arg0
+		{name: "BTSL", argLength: 2, reg: gp21, asm: "BTSL", resultInArg0: true, clobberFlags: true},                   // set bit arg1%32 in arg0
+		{name: "BTSQ", argLength: 2, reg: gp21, asm: "BTSQ", resultInArg0: true, clobberFlags: true},                   // set bit arg1%64 in arg0
+		{name: "BTLconst", argLength: 1, reg: gp1flags, asm: "BTL", typ: "Flags", aux: "Int8"},                         // test whether bit auxint in arg0 is set, 0 <= auxint < 32
+		{name: "BTQconst", argLength: 1, reg: gp1flags, asm: "BTQ", typ: "Flags", aux: "Int8"},                         // test whether bit auxint in arg0 is set, 0 <= auxint < 64
+		{name: "BTCLconst", argLength: 1, reg: gp11, asm: "BTCL", resultInArg0: true, clobberFlags: true, aux: "Int8"}, // complement bit auxint in arg0, 0 <= auxint < 32
+		{name: "BTCQconst", argLength: 1, reg: gp11, asm: "BTCQ", resultInArg0: true, clobberFlags: true, aux: "Int8"}, // complement bit auxint in arg0, 0 <= auxint < 64
+		{name: "BTRLconst", argLength: 1, reg: gp11, asm: "BTRL", resultInArg0: true, clobberFlags: true, aux: "Int8"}, // reset bit auxint in arg0, 0 <= auxint < 32
+		{name: "BTRQconst", argLength: 1, reg: gp11, asm: "BTRQ", resultInArg0: true, clobberFlags: true, aux: "Int8"}, // reset bit auxint in arg0, 0 <= auxint < 64
+		{name: "BTSLconst", argLength: 1, reg: gp11, asm: "BTSL", resultInArg0: true, clobberFlags: true, aux: "Int8"}, // set bit auxint in arg0, 0 <= auxint < 32
+		{name: "BTSQconst", argLength: 1, reg: gp11, asm: "BTSQ", resultInArg0: true, clobberFlags: true, aux: "Int8"}, // set bit auxint in arg0, 0 <= auxint < 64
+
+		// TESTx: compare (arg0 & arg1) to 0
+		{name: "TESTQ", argLength: 2, reg: gp2flags, commutative: true, asm: "TESTQ", typ: "Flags"},
+		{name: "TESTL", argLength: 2, reg: gp2flags, commutative: true, asm: "TESTL", typ: "Flags"},
+		{name: "TESTW", argLength: 2, reg: gp2flags, commutative: true, asm: "TESTW", typ: "Flags"},
+		{name: "TESTB", argLength: 2, reg: gp2flags, commutative: true, asm: "TESTB", typ: "Flags"},
+
+		// TESTxconst: compare (arg0 & auxint) to 0
+		{name: "TESTQconst", argLength: 1, reg: gp1flags, asm: "TESTQ", typ: "Flags", aux: "Int32"},
+		{name: "TESTLconst", argLength: 1, reg: gp1flags, asm: "TESTL", typ: "Flags", aux: "Int32"},
+		{name: "TESTWconst", argLength: 1, reg: gp1flags, asm: "TESTW", typ: "Flags", aux: "Int16"},
+		{name: "TESTBconst", argLength: 1, reg: gp1flags, asm: "TESTB", typ: "Flags", aux: "Int8"},
+
+		// S{HL, HR, AR}x: shift operations
+		// SHL: shift left
+		// SHR: shift right logical (0s are shifted in from beyond the word size)
+		// SAR: shift right arithmetic (sign bit is shifted in from beyond the word size)
+		// arg0 is the value being shifted
+		// arg1 is the amount to shift, interpreted mod (Q=64,L=32,W=32,B=32)
+		// (Note: x86 is weird, the 16 and 8 byte shifts still use all 5 bits of shift amount!)
+		// For *const versions, use auxint instead of arg1 as the shift amount. auxint must be in the range 0 to (Q=63,L=31,W=15,B=7) inclusive.
+		{name: "SHLQ", argLength: 2, reg: gp21shift, asm: "SHLQ", resultInArg0: true, clobberFlags: true},
+		{name: "SHLL", argLength: 2, reg: gp21shift, asm: "SHLL", resultInArg0: true, clobberFlags: true},
+		{name: "SHLQconst", argLength: 1, reg: gp11, asm: "SHLQ", aux: "Int8", resultInArg0: true, clobberFlags: true},
+		{name: "SHLLconst", argLength: 1, reg: gp11, asm: "SHLL", aux: "Int8", resultInArg0: true, clobberFlags: true},
+
+		{name: "SHRQ", argLength: 2, reg: gp21shift, asm: "SHRQ", resultInArg0: true, clobberFlags: true},
+		{name: "SHRL", argLength: 2, reg: gp21shift, asm: "SHRL", resultInArg0: true, clobberFlags: true},
+		{name: "SHRW", argLength: 2, reg: gp21shift, asm: "SHRW", resultInArg0: true, clobberFlags: true},
+		{name: "SHRB", argLength: 2, reg: gp21shift, asm: "SHRB", resultInArg0: true, clobberFlags: true},
+		{name: "SHRQconst", argLength: 1, reg: gp11, asm: "SHRQ", aux: "Int8", resultInArg0: true, clobberFlags: true},
+		{name: "SHRLconst", argLength: 1, reg: gp11, asm: "SHRL", aux: "Int8", resultInArg0: true, clobberFlags: true},
+		{name: "SHRWconst", argLength: 1, reg: gp11, asm: "SHRW", aux: "Int8", resultInArg0: true, clobberFlags: true},
+		{name: "SHRBconst", argLength: 1, reg: gp11, asm: "SHRB", aux: "Int8", resultInArg0: true, clobberFlags: true},
+
+		{name: "SARQ", argLength: 2, reg: gp21shift, asm: "SARQ", resultInArg0: true, clobberFlags: true},
+		{name: "SARL", argLength: 2, reg: gp21shift, asm: "SARL", resultInArg0: true, clobberFlags: true},
+		{name: "SARW", argLength: 2, reg: gp21shift, asm: "SARW", resultInArg0: true, clobberFlags: true},
+		{name: "SARB", argLength: 2, reg: gp21shift, asm: "SARB", resultInArg0: true, clobberFlags: true},
+		{name: "SARQconst", argLength: 1, reg: gp11, asm: "SARQ", aux: "Int8", resultInArg0: true, clobberFlags: true},
+		{name: "SARLconst", argLength: 1, reg: gp11, asm: "SARL", aux: "Int8", resultInArg0: true, clobberFlags: true},
+		{name: "SARWconst", argLength: 1, reg: gp11, asm: "SARW", aux: "Int8", resultInArg0: true, clobberFlags: true},
+		{name: "SARBconst", argLength: 1, reg: gp11, asm: "SARB", aux: "Int8", resultInArg0: true, clobberFlags: true},
+
+		// unsigned arg0 >> arg2, shifting in bits from arg1 (==(arg1<<64+arg0)>>arg2, keeping low 64 bits), shift amount is mod 64
+		{name: "SHRDQ", argLength: 3, reg: gp31shift, asm: "SHRQ", resultInArg0: true, clobberFlags: true},
+		// unsigned arg0 << arg2, shifting in bits from arg1 (==(arg0<<64+arg1)<<arg2, keeping high 64 bits), shift amount is mod 64
+		{name: "SHLDQ", argLength: 3, reg: gp31shift, asm: "SHLQ", resultInArg0: true, clobberFlags: true},
+
+		// RO{L,R}x: rotate instructions
+		// computes arg0 rotate (L=left,R=right) arg1 bits.
+		// Bits are rotated within the low (Q=64,L=32,W=16,B=8) bits of the register.
+		// For *const versions use auxint instead of arg1 as the rotate amount. auxint must be in the range 0 to (Q=63,L=31,W=15,B=7) inclusive.
+		// x==L versions zero the upper 32 bits of the destination register.
+		// x==W and x==B versions leave the upper bits unspecified.
+		{name: "ROLQ", argLength: 2, reg: gp21shift, asm: "ROLQ", resultInArg0: true, clobberFlags: true},
+		{name: "ROLL", argLength: 2, reg: gp21shift, asm: "ROLL", resultInArg0: true, clobberFlags: true},
+		{name: "ROLW", argLength: 2, reg: gp21shift, asm: "ROLW", resultInArg0: true, clobberFlags: true},
+		{name: "ROLB", argLength: 2, reg: gp21shift, asm: "ROLB", resultInArg0: true, clobberFlags: true},
+		{name: "RORQ", argLength: 2, reg: gp21shift, asm: "RORQ", resultInArg0: true, clobberFlags: true},
+		{name: "RORL", argLength: 2, reg: gp21shift, asm: "RORL", resultInArg0: true, clobberFlags: true},
+		{name: "RORW", argLength: 2, reg: gp21shift, asm: "RORW", resultInArg0: true, clobberFlags: true},
+		{name: "RORB", argLength: 2, reg: gp21shift, asm: "RORB", resultInArg0: true, clobberFlags: true},
+		{name: "ROLQconst", argLength: 1, reg: gp11, asm: "ROLQ", aux: "Int8", resultInArg0: true, clobberFlags: true},
+		{name: "ROLLconst", argLength: 1, reg: gp11, asm: "ROLL", aux: "Int8", resultInArg0: true, clobberFlags: true},
+		{name: "ROLWconst", argLength: 1, reg: gp11, asm: "ROLW", aux: "Int8", resultInArg0: true, clobberFlags: true},
+		{name: "ROLBconst", argLength: 1, reg: gp11, asm: "ROLB", aux: "Int8", resultInArg0: true, clobberFlags: true},
+
+		// [ADD,SUB,AND,OR]xload: integer load/op combo
+		// L = int32, Q = int64
+		// x==L operations zero the upper 4 bytes of the destination register.
+		// computes arg0 op *(arg1+auxint+aux), arg2=mem
+		{name: "ADDLload", argLength: 3, reg: gp21load, asm: "ADDL", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},
+		{name: "ADDQload", argLength: 3, reg: gp21load, asm: "ADDQ", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},
+		{name: "SUBQload", argLength: 3, reg: gp21load, asm: "SUBQ", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},
+		{name: "SUBLload", argLength: 3, reg: gp21load, asm: "SUBL", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},
+		{name: "ANDLload", argLength: 3, reg: gp21load, asm: "ANDL", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},
+		{name: "ANDQload", argLength: 3, reg: gp21load, asm: "ANDQ", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},
+		{name: "ORQload", argLength: 3, reg: gp21load, asm: "ORQ", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},
+		{name: "ORLload", argLength: 3, reg: gp21load, asm: "ORL", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},
+		{name: "XORQload", argLength: 3, reg: gp21load, asm: "XORQ", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},
+		{name: "XORLload", argLength: 3, reg: gp21load, asm: "XORL", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},
+
+		// integer indexed load/op combo
+		// L = int32, Q = int64
+		// L operations zero the upper 4 bytes of the destination register.
+		// computes arg0 op *(arg1+scale*arg2+auxint+aux), arg3=mem
+		{name: "ADDLloadidx1", argLength: 4, reg: gp21loadidx, asm: "ADDL", scale: 1, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},
+		{name: "ADDLloadidx4", argLength: 4, reg: gp21loadidx, asm: "ADDL", scale: 4, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},
+		{name: "ADDLloadidx8", argLength: 4, reg: gp21loadidx, asm: "ADDL", scale: 8, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},
+		{name: "ADDQloadidx1", argLength: 4, reg: gp21loadidx, asm: "ADDQ", scale: 1, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},
+		{name: "ADDQloadidx8", argLength: 4, reg: gp21loadidx, asm: "ADDQ", scale: 8, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},
+		{name: "SUBLloadidx1", argLength: 4, reg: gp21loadidx, asm: "SUBL", scale: 1, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},
+		{name: "SUBLloadidx4", argLength: 4, reg: gp21loadidx, asm: "SUBL", scale: 4, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},
+		{name: "SUBLloadidx8", argLength: 4, reg: gp21loadidx, asm: "SUBL", scale: 8, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},
+		{name: "SUBQloadidx1", argLength: 4, reg: gp21loadidx, asm: "SUBQ", scale: 1, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},
+		{name: "SUBQloadidx8", argLength: 4, reg: gp21loadidx, asm: "SUBQ", scale: 8, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},
+		{name: "ANDLloadidx1", argLength: 4, reg: gp21loadidx, asm: "ANDL", scale: 1, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},
+		{name: "ANDLloadidx4", argLength: 4, reg: gp21loadidx, asm: "ANDL", scale: 4, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},
+		{name: "ANDLloadidx8", argLength: 4, reg: gp21loadidx, asm: "ANDL", scale: 8, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},
+		{name: "ANDQloadidx1", argLength: 4, reg: gp21loadidx, asm: "ANDQ", scale: 1, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},
+		{name: "ANDQloadidx8", argLength: 4, reg: gp21loadidx, asm: "ANDQ", scale: 8, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},
+		{name: "ORLloadidx1", argLength: 4, reg: gp21loadidx, asm: "ORL", scale: 1, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},
+		{name: "ORLloadidx4", argLength: 4, reg: gp21loadidx, asm: "ORL", scale: 4, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},
+		{name: "ORLloadidx8", argLength: 4, reg: gp21loadidx, asm: "ORL", scale: 8, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},
+		{name: "ORQloadidx1", argLength: 4, reg: gp21loadidx, asm: "ORQ", scale: 1, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},
+		{name: "ORQloadidx8", argLength: 4, reg: gp21loadidx, asm: "ORQ", scale: 8, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},
+		{name: "XORLloadidx1", argLength: 4, reg: gp21loadidx, asm: "XORL", scale: 1, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},
+		{name: "XORLloadidx4", argLength: 4, reg: gp21loadidx, asm: "XORL", scale: 4, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},
+		{name: "XORLloadidx8", argLength: 4, reg: gp21loadidx, asm: "XORL", scale: 8, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},
+		{name: "XORQloadidx1", argLength: 4, reg: gp21loadidx, asm: "XORQ", scale: 1, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},
+		{name: "XORQloadidx8", argLength: 4, reg: gp21loadidx, asm: "XORQ", scale: 8, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},
+
+		// direct binary op on memory (read-modify-write)
+		// L = int32, Q = int64
+		// does *(arg0+auxint+aux) op= arg1, arg2=mem
+		{name: "ADDQmodify", argLength: 3, reg: gpstore, asm: "ADDQ", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"},
+		{name: "SUBQmodify", argLength: 3, reg: gpstore, asm: "SUBQ", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"},
+		{name: "ANDQmodify", argLength: 3, reg: gpstore, asm: "ANDQ", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"},
+		{name: "ORQmodify", argLength: 3, reg: gpstore, asm: "ORQ", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"},
+		{name: "XORQmodify", argLength: 3, reg: gpstore, asm: "XORQ", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"},
+		{name: "ADDLmodify", argLength: 3, reg: gpstore, asm: "ADDL", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"},
+		{name: "SUBLmodify", argLength: 3, reg: gpstore, asm: "SUBL", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"},
+		{name: "ANDLmodify", argLength: 3, reg: gpstore, asm: "ANDL", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"},
+		{name: "ORLmodify", argLength: 3, reg: gpstore, asm: "ORL", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"},
+		{name: "XORLmodify", argLength: 3, reg: gpstore, asm: "XORL", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"},
+
+		// indexed direct binary op on memory.
+		// does *(arg0+scale*arg1+auxint+aux) op= arg2, arg3=mem
+		{name: "ADDQmodifyidx1", argLength: 4, reg: gpstoreidx, asm: "ADDQ", scale: 1, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "ADDQmodifyidx8", argLength: 4, reg: gpstoreidx, asm: "ADDQ", scale: 8, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "SUBQmodifyidx1", argLength: 4, reg: gpstoreidx, asm: "SUBQ", scale: 1, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "SUBQmodifyidx8", argLength: 4, reg: gpstoreidx, asm: "SUBQ", scale: 8, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "ANDQmodifyidx1", argLength: 4, reg: gpstoreidx, asm: "ANDQ", scale: 1, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "ANDQmodifyidx8", argLength: 4, reg: gpstoreidx, asm: "ANDQ", scale: 8, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "ORQmodifyidx1", argLength: 4, reg: gpstoreidx, asm: "ORQ", scale: 1, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "ORQmodifyidx8", argLength: 4, reg: gpstoreidx, asm: "ORQ", scale: 8, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "XORQmodifyidx1", argLength: 4, reg: gpstoreidx, asm: "XORQ", scale: 1, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "XORQmodifyidx8", argLength: 4, reg: gpstoreidx, asm: "XORQ", scale: 8, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "ADDLmodifyidx1", argLength: 4, reg: gpstoreidx, asm: "ADDL", scale: 1, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "ADDLmodifyidx4", argLength: 4, reg: gpstoreidx, asm: "ADDL", scale: 4, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "ADDLmodifyidx8", argLength: 4, reg: gpstoreidx, asm: "ADDL", scale: 8, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "SUBLmodifyidx1", argLength: 4, reg: gpstoreidx, asm: "SUBL", scale: 1, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "SUBLmodifyidx4", argLength: 4, reg: gpstoreidx, asm: "SUBL", scale: 4, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "SUBLmodifyidx8", argLength: 4, reg: gpstoreidx, asm: "SUBL", scale: 8, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "ANDLmodifyidx1", argLength: 4, reg: gpstoreidx, asm: "ANDL", scale: 1, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "ANDLmodifyidx4", argLength: 4, reg: gpstoreidx, asm: "ANDL", scale: 4, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "ANDLmodifyidx8", argLength: 4, reg: gpstoreidx, asm: "ANDL", scale: 8, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "ORLmodifyidx1", argLength: 4, reg: gpstoreidx, asm: "ORL", scale: 1, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "ORLmodifyidx4", argLength: 4, reg: gpstoreidx, asm: "ORL", scale: 4, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "ORLmodifyidx8", argLength: 4, reg: gpstoreidx, asm: "ORL", scale: 8, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "XORLmodifyidx1", argLength: 4, reg: gpstoreidx, asm: "XORL", scale: 1, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "XORLmodifyidx4", argLength: 4, reg: gpstoreidx, asm: "XORL", scale: 4, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "XORLmodifyidx8", argLength: 4, reg: gpstoreidx, asm: "XORL", scale: 8, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+
+		// indexed direct binary op on memory with constant argument.
+		// does *(arg0+scale*arg1+ValAndOff(AuxInt).Off()+aux) op= ValAndOff(AuxInt).Val(), arg2=mem
+		{name: "ADDQconstmodifyidx1", argLength: 3, reg: gpstoreconstidx, asm: "ADDQ", scale: 1, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "ADDQconstmodifyidx8", argLength: 3, reg: gpstoreconstidx, asm: "ADDQ", scale: 8, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "ANDQconstmodifyidx1", argLength: 3, reg: gpstoreconstidx, asm: "ANDQ", scale: 1, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "ANDQconstmodifyidx8", argLength: 3, reg: gpstoreconstidx, asm: "ANDQ", scale: 8, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "ORQconstmodifyidx1", argLength: 3, reg: gpstoreconstidx, asm: "ORQ", scale: 1, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "ORQconstmodifyidx8", argLength: 3, reg: gpstoreconstidx, asm: "ORQ", scale: 8, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "XORQconstmodifyidx1", argLength: 3, reg: gpstoreconstidx, asm: "XORQ", scale: 1, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "XORQconstmodifyidx8", argLength: 3, reg: gpstoreconstidx, asm: "XORQ", scale: 8, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "ADDLconstmodifyidx1", argLength: 3, reg: gpstoreconstidx, asm: "ADDL", scale: 1, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "ADDLconstmodifyidx4", argLength: 3, reg: gpstoreconstidx, asm: "ADDL", scale: 4, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "ADDLconstmodifyidx8", argLength: 3, reg: gpstoreconstidx, asm: "ADDL", scale: 8, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "ANDLconstmodifyidx1", argLength: 3, reg: gpstoreconstidx, asm: "ANDL", scale: 1, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "ANDLconstmodifyidx4", argLength: 3, reg: gpstoreconstidx, asm: "ANDL", scale: 4, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "ANDLconstmodifyidx8", argLength: 3, reg: gpstoreconstidx, asm: "ANDL", scale: 8, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "ORLconstmodifyidx1", argLength: 3, reg: gpstoreconstidx, asm: "ORL", scale: 1, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "ORLconstmodifyidx4", argLength: 3, reg: gpstoreconstidx, asm: "ORL", scale: 4, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "ORLconstmodifyidx8", argLength: 3, reg: gpstoreconstidx, asm: "ORL", scale: 8, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "XORLconstmodifyidx1", argLength: 3, reg: gpstoreconstidx, asm: "XORL", scale: 1, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "XORLconstmodifyidx4", argLength: 3, reg: gpstoreconstidx, asm: "XORL", scale: 4, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+		{name: "XORLconstmodifyidx8", argLength: 3, reg: gpstoreconstidx, asm: "XORL", scale: 8, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},
+
+		// {NEG,NOT}x: unary ops
+		// computes [NEG:-,NOT:^]arg0
+		// L = int32, Q = int64
+		// L operations zero the upper 4 bytes of the destination register.
+		{name: "NEGQ", argLength: 1, reg: gp11, asm: "NEGQ", resultInArg0: true, clobberFlags: true},
+		{name: "NEGL", argLength: 1, reg: gp11, asm: "NEGL", resultInArg0: true, clobberFlags: true},
+		{name: "NOTQ", argLength: 1, reg: gp11, asm: "NOTQ", resultInArg0: true},
+		{name: "NOTL", argLength: 1, reg: gp11, asm: "NOTL", resultInArg0: true},
+
+		// BS{F,R}Q returns a tuple [result, flags]
+		// result is undefined if the input is zero.
+		// flags are set to "equal" if the input is zero, "not equal" otherwise.
+		// BS{F,R}L returns only the result.
+		{name: "BSFQ", argLength: 1, reg: gp11flags, asm: "BSFQ", typ: "(UInt64,Flags)"},        // # of low-order zeroes in 64-bit arg
+		{name: "BSFL", argLength: 1, reg: gp11, asm: "BSFL", typ: "UInt32", clobberFlags: true}, // # of low-order zeroes in 32-bit arg
+		{name: "BSRQ", argLength: 1, reg: gp11flags, asm: "BSRQ", typ: "(UInt64,Flags)"},        // # of high-order zeroes in 64-bit arg
+		{name: "BSRL", argLength: 1, reg: gp11, asm: "BSRL", typ: "UInt32", clobberFlags: true}, // # of high-order zeroes in 32-bit arg
+
+		// CMOV instructions: 64, 32 and 16-bit sizes.
+		// if arg2 encodes a true result, return arg1, else arg0
+		{name: "CMOVQEQ", argLength: 3, reg: gp21, asm: "CMOVQEQ", resultInArg0: true},
+		{name: "CMOVQNE", argLength: 3, reg: gp21, asm: "CMOVQNE", resultInArg0: true},
+		{name: "CMOVQLT", argLength: 3, reg: gp21, asm: "CMOVQLT", resultInArg0: true},
+		{name: "CMOVQGT", argLength: 3, reg: gp21, asm: "CMOVQGT", resultInArg0: true},
+		{name: "CMOVQLE", argLength: 3, reg: gp21, asm: "CMOVQLE", resultInArg0: true},
+		{name: "CMOVQGE", argLength: 3, reg: gp21, asm: "CMOVQGE", resultInArg0: true},
+		{name: "CMOVQLS", argLength: 3, reg: gp21, asm: "CMOVQLS", resultInArg0: true},
+		{name: "CMOVQHI", argLength: 3, reg: gp21, asm: "CMOVQHI", resultInArg0: true},
+		{name: "CMOVQCC", argLength: 3, reg: gp21, asm: "CMOVQCC", resultInArg0: true},
+		{name: "CMOVQCS", argLength: 3, reg: gp21, asm: "CMOVQCS", resultInArg0: true},
+
+		{name: "CMOVLEQ", argLength: 3, reg: gp21, asm: "CMOVLEQ", resultInArg0: true},
+		{name: "CMOVLNE", argLength: 3, reg: gp21, asm: "CMOVLNE", resultInArg0: true},
+		{name: "CMOVLLT", argLength: 3, reg: gp21, asm: "CMOVLLT", resultInArg0: true},
+		{name: "CMOVLGT", argLength: 3, reg: gp21, asm: "CMOVLGT", resultInArg0: true},
+		{name: "CMOVLLE", argLength: 3, reg: gp21, asm: "CMOVLLE", resultInArg0: true},
+		{name: "CMOVLGE", argLength: 3, reg: gp21, asm: "CMOVLGE", resultInArg0: true},
+		{name: "CMOVLLS", argLength: 3, reg: gp21, asm: "CMOVLLS", resultInArg0: true},
+		{name: "CMOVLHI", argLength: 3, reg: gp21, asm: "CMOVLHI", resultInArg0: true},
+		{name: "CMOVLCC", argLength: 3, reg: gp21, asm: "CMOVLCC", resultInArg0: true},
+		{name: "CMOVLCS", argLength: 3, reg: gp21, asm: "CMOVLCS", resultInArg0: true},
+
+		{name: "CMOVWEQ", argLength: 3, reg: gp21, asm: "CMOVWEQ", resultInArg0: true},
+		{name: "CMOVWNE", argLength: 3, reg: gp21, asm: "CMOVWNE", resultInArg0: true},
+		{name: "CMOVWLT", argLength: 3, reg: gp21, asm: "CMOVWLT", resultInArg0: true},
+		{name: "CMOVWGT", argLength: 3, reg: gp21, asm: "CMOVWGT", resultInArg0: true},
+		{name: "CMOVWLE", argLength: 3, reg: gp21, asm: "CMOVWLE", resultInArg0: true},
+		{name: "CMOVWGE", argLength: 3, reg: gp21, asm: "CMOVWGE", resultInArg0: true},
+		{name: "CMOVWLS", argLength: 3, reg: gp21, asm: "CMOVWLS", resultInArg0: true},
+		{name: "CMOVWHI", argLength: 3, reg: gp21, asm: "CMOVWHI", resultInArg0: true},
+		{name: "CMOVWCC", argLength: 3, reg: gp21, asm: "CMOVWCC", resultInArg0: true},
+		{name: "CMOVWCS", argLength: 3, reg: gp21, asm: "CMOVWCS", resultInArg0: true},
+
+		// CMOV with floating point instructions. We need separate pseudo-op to handle
+		// InvertFlags correctly, and to generate special code that handles NaN (unordered flag).
+		// NOTE: the fact that CMOV*EQF here is marked to generate CMOV*NE is not a bug. See
+		// code generation in amd64/ssa.go.
+		{name: "CMOVQEQF", argLength: 3, reg: gp21, asm: "CMOVQNE", resultInArg0: true, needIntTemp: true},
+		{name: "CMOVQNEF", argLength: 3, reg: gp21, asm: "CMOVQNE", resultInArg0: true},
+		{name: "CMOVQGTF", argLength: 3, reg: gp21, asm: "CMOVQHI", resultInArg0: true},
+		{name: "CMOVQGEF", argLength: 3, reg: gp21, asm: "CMOVQCC", resultInArg0: true},
+		{name: "CMOVLEQF", argLength: 3, reg: gp21, asm: "CMOVLNE", resultInArg0: true, needIntTemp: true},
+		{name: "CMOVLNEF", argLength: 3, reg: gp21, asm: "CMOVLNE", resultInArg0: true},
+		{name: "CMOVLGTF", argLength: 3, reg: gp21, asm: "CMOVLHI", resultInArg0: true},
+		{name: "CMOVLGEF", argLength: 3, reg: gp21, asm: "CMOVLCC", resultInArg0: true},
+		{name: "CMOVWEQF", argLength: 3, reg: gp21, asm: "CMOVWNE", resultInArg0: true, needIntTemp: true},
+		{name: "CMOVWNEF", argLength: 3, reg: gp21, asm: "CMOVWNE", resultInArg0: true},
+		{name: "CMOVWGTF", argLength: 3, reg: gp21, asm: "CMOVWHI", resultInArg0: true},
+		{name: "CMOVWGEF", argLength: 3, reg: gp21, asm: "CMOVWCC", resultInArg0: true},
+
+		// BSWAPx swaps the low-order (L=4,Q=8) bytes of arg0.
+		// Q: abcdefgh -> hgfedcba
+		// L: abcdefgh -> 0000hgfe (L zeros the upper 4 bytes)
+		{name: "BSWAPQ", argLength: 1, reg: gp11, asm: "BSWAPQ", resultInArg0: true},
+		{name: "BSWAPL", argLength: 1, reg: gp11, asm: "BSWAPL", resultInArg0: true},
+
+		// POPCNTx counts the number of set bits in the low-order (L=32,Q=64) bits of arg0.
+		// POPCNTx instructions are only guaranteed to be available if GOAMD64>=v2.
+		// For GOAMD64<v2, any use must be preceded by a successful runtime check of runtime.x86HasPOPCNT.
+		{name: "POPCNTQ", argLength: 1, reg: gp11, asm: "POPCNTQ", clobberFlags: true},
+		{name: "POPCNTL", argLength: 1, reg: gp11, asm: "POPCNTL", clobberFlags: true},
+
+		// SQRTSx computes sqrt(arg0)
+		// S = float32, D = float64
+		{name: "SQRTSD", argLength: 1, reg: fp11, asm: "SQRTSD"},
+		{name: "SQRTSS", argLength: 1, reg: fp11, asm: "SQRTSS"},
+
+		// ROUNDSD rounds arg0 to an integer depending on auxint
+		// 0 means math.RoundToEven, 1 means math.Floor, 2 math.Ceil, 3 math.Trunc
+		// (The result is still a float64.)
+		// ROUNDSD instruction is only guaraneteed to be available if GOAMD64>=v2.
+		// For GOAMD64<v2, any use must be preceded by a successful check of runtime.x86HasSSE41.
+		{name: "ROUNDSD", argLength: 1, reg: fp11, aux: "Int8", asm: "ROUNDSD"},
+
+		// VFMADD231SD only exists on platforms with the FMA3 instruction set.
+		// Any use must be preceded by a successful check of runtime.support_fma.
+		{name: "VFMADD231SD", argLength: 3, reg: fp31, resultInArg0: true, asm: "VFMADD231SD"},
+
+		{name: "SBBQcarrymask", argLength: 1, reg: flagsgp, asm: "SBBQ"}, // (int64)(-1) if carry is set, 0 if carry is clear.
+		{name: "SBBLcarrymask", argLength: 1, reg: flagsgp, asm: "SBBL"}, // (int32)(-1) if carry is set, 0 if carry is clear.
+		// Note: SBBW and SBBB are subsumed by SBBL
+
+		{name: "SETEQ", argLength: 1, reg: readflags, asm: "SETEQ"}, // extract == condition from arg0
+		{name: "SETNE", argLength: 1, reg: readflags, asm: "SETNE"}, // extract != condition from arg0
+		{name: "SETL", argLength: 1, reg: readflags, asm: "SETLT"},  // extract signed < condition from arg0
+		{name: "SETLE", argLength: 1, reg: readflags, asm: "SETLE"}, // extract signed <= condition from arg0
+		{name: "SETG", argLength: 1, reg: readflags, asm: "SETGT"},  // extract signed > condition from arg0
+		{name: "SETGE", argLength: 1, reg: readflags, asm: "SETGE"}, // extract signed >= condition from arg0
+		{name: "SETB", argLength: 1, reg: readflags, asm: "SETCS"},  // extract unsigned < condition from arg0
+		{name: "SETBE", argLength: 1, reg: readflags, asm: "SETLS"}, // extract unsigned <= condition from arg0
+		{name: "SETA", argLength: 1, reg: readflags, asm: "SETHI"},  // extract unsigned > condition from arg0
+		{name: "SETAE", argLength: 1, reg: readflags, asm: "SETCC"}, // extract unsigned >= condition from arg0
+		{name: "SETO", argLength: 1, reg: readflags, asm: "SETOS"},  // extract if overflow flag is set from arg0
+		// Variants that store result to memory
+		{name: "SETEQstore", argLength: 3, reg: gpstoreconst, asm: "SETEQ", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // extract == condition from arg1 to arg0+auxint+aux, arg2=mem
+		{name: "SETNEstore", argLength: 3, reg: gpstoreconst, asm: "SETNE", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // extract != condition from arg1 to arg0+auxint+aux, arg2=mem
+		{name: "SETLstore", argLength: 3, reg: gpstoreconst, asm: "SETLT", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},  // extract signed < condition from arg1 to arg0+auxint+aux, arg2=mem
+		{name: "SETLEstore", argLength: 3, reg: gpstoreconst, asm: "SETLE", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // extract signed <= condition from arg1 to arg0+auxint+aux, arg2=mem
+		{name: "SETGstore", argLength: 3, reg: gpstoreconst, asm: "SETGT", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},  // extract signed > condition from arg1 to arg0+auxint+aux, arg2=mem
+		{name: "SETGEstore", argLength: 3, reg: gpstoreconst, asm: "SETGE", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // extract signed >= condition from arg1 to arg0+auxint+aux, arg2=mem
+		{name: "SETBstore", argLength: 3, reg: gpstoreconst, asm: "SETCS", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},  // extract unsigned < condition from arg1 to arg0+auxint+aux, arg2=mem
+		{name: "SETBEstore", argLength: 3, reg: gpstoreconst, asm: "SETLS", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // extract unsigned <= condition from arg1 to arg0+auxint+aux, arg2=mem
+		{name: "SETAstore", argLength: 3, reg: gpstoreconst, asm: "SETHI", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},  // extract unsigned > condition from arg1 to arg0+auxint+aux, arg2=mem
+		{name: "SETAEstore", argLength: 3, reg: gpstoreconst, asm: "SETCC", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // extract unsigned >= condition from arg1 to arg0+auxint+aux, arg2=mem
+		// Need different opcodes for floating point conditions because
+		// any comparison involving a NaN is always FALSE and thus
+		// the patterns for inverting conditions cannot be used.
+		{name: "SETEQF", argLength: 1, reg: flagsgp, asm: "SETEQ", clobberFlags: true, needIntTemp: true}, // extract == condition from arg0
+		{name: "SETNEF", argLength: 1, reg: flagsgp, asm: "SETNE", clobberFlags: true, needIntTemp: true}, // extract != condition from arg0
+		{name: "SETORD", argLength: 1, reg: flagsgp, asm: "SETPC"},                                        // extract "ordered" (No Nan present) condition from arg0
+		{name: "SETNAN", argLength: 1, reg: flagsgp, asm: "SETPS"},                                        // extract "unordered" (Nan present) condition from arg0
+
+		{name: "SETGF", argLength: 1, reg: flagsgp, asm: "SETHI"},  // extract floating > condition from arg0
+		{name: "SETGEF", argLength: 1, reg: flagsgp, asm: "SETCC"}, // extract floating >= condition from arg0
+
+		{name: "MOVBQSX", argLength: 1, reg: gp11, asm: "MOVBQSX"}, // sign extend arg0 from int8 to int64
+		{name: "MOVBQZX", argLength: 1, reg: gp11, asm: "MOVBLZX"}, // zero extend arg0 from int8 to int64
+		{name: "MOVWQSX", argLength: 1, reg: gp11, asm: "MOVWQSX"}, // sign extend arg0 from int16 to int64
+		{name: "MOVWQZX", argLength: 1, reg: gp11, asm: "MOVWLZX"}, // zero extend arg0 from int16 to int64
+		{name: "MOVLQSX", argLength: 1, reg: gp11, asm: "MOVLQSX"}, // sign extend arg0 from int32 to int64
+		{name: "MOVLQZX", argLength: 1, reg: gp11, asm: "MOVL"},    // zero extend arg0 from int32 to int64
+
+		{name: "MOVLconst", reg: gp01, asm: "MOVL", typ: "UInt32", aux: "Int32", rematerializeable: true}, // 32 low bits of auxint
+		{name: "MOVQconst", reg: gp01, asm: "MOVQ", typ: "UInt64", aux: "Int64", rematerializeable: true}, // auxint
+
+		{name: "CVTTSD2SL", argLength: 1, reg: fpgp, asm: "CVTTSD2SL"}, // convert float64 to int32
+		{name: "CVTTSD2SQ", argLength: 1, reg: fpgp, asm: "CVTTSD2SQ"}, // convert float64 to int64
+		{name: "CVTTSS2SL", argLength: 1, reg: fpgp, asm: "CVTTSS2SL"}, // convert float32 to int32
+		{name: "CVTTSS2SQ", argLength: 1, reg: fpgp, asm: "CVTTSS2SQ"}, // convert float32 to int64
+		{name: "CVTSL2SS", argLength: 1, reg: gpfp, asm: "CVTSL2SS"},   // convert int32 to float32
+		{name: "CVTSL2SD", argLength: 1, reg: gpfp, asm: "CVTSL2SD"},   // convert int32 to float64
+		{name: "CVTSQ2SS", argLength: 1, reg: gpfp, asm: "CVTSQ2SS"},   // convert int64 to float32
+		{name: "CVTSQ2SD", argLength: 1, reg: gpfp, asm: "CVTSQ2SD"},   // convert int64 to float64
+		{name: "CVTSD2SS", argLength: 1, reg: fp11, asm: "CVTSD2SS"},   // convert float64 to float32
+		{name: "CVTSS2SD", argLength: 1, reg: fp11, asm: "CVTSS2SD"},   // convert float32 to float64
+
+		// Move values between int and float registers, with no conversion.
+		// TODO: should we have generic versions of these?
+		{name: "MOVQi2f", argLength: 1, reg: gpfp, typ: "Float64"}, // move 64 bits from int to float reg
+		{name: "MOVQf2i", argLength: 1, reg: fpgp, typ: "UInt64"},  // move 64 bits from float to int reg
+		{name: "MOVLi2f", argLength: 1, reg: gpfp, typ: "Float32"}, // move 32 bits from int to float reg
+		{name: "MOVLf2i", argLength: 1, reg: fpgp, typ: "UInt32"},  // move 32 bits from float to int reg, zero extend
+
+		{name: "PXOR", argLength: 2, reg: fp21, asm: "PXOR", commutative: true, resultInArg0: true}, // exclusive or, applied to X regs for float negation.
+
+		{name: "LEAQ", argLength: 1, reg: gp11sb, asm: "LEAQ", aux: "SymOff", rematerializeable: true, symEffect: "Addr"}, // arg0 + auxint + offset encoded in aux
+		{name: "LEAL", argLength: 1, reg: gp11sb, asm: "LEAL", aux: "SymOff", rematerializeable: true, symEffect: "Addr"}, // arg0 + auxint + offset encoded in aux
+		{name: "LEAW", argLength: 1, reg: gp11sb, asm: "LEAW", aux: "SymOff", rematerializeable: true, symEffect: "Addr"}, // arg0 + auxint + offset encoded in aux
+
+		// LEAxn computes arg0 + n*arg1 + auxint + aux
+		// x==L zeroes the upper 4 bytes.
+		{name: "LEAQ1", argLength: 2, reg: gp21sb, asm: "LEAQ", scale: 1, commutative: true, aux: "SymOff", symEffect: "Addr"}, // arg0 + arg1 + auxint + aux
+		{name: "LEAL1", argLength: 2, reg: gp21sb, asm: "LEAL", scale: 1, commutative: true, aux: "SymOff", symEffect: "Addr"}, // arg0 + arg1 + auxint + aux
+		{name: "LEAW1", argLength: 2, reg: gp21sb, asm: "LEAW", scale: 1, commutative: true, aux: "SymOff", symEffect: "Addr"}, // arg0 + arg1 + auxint + aux
+		{name: "LEAQ2", argLength: 2, reg: gp21sb, asm: "LEAQ", scale: 2, aux: "SymOff", symEffect: "Addr"},                    // arg0 + 2*arg1 + auxint + aux
+		{name: "LEAL2", argLength: 2, reg: gp21sb, asm: "LEAL", scale: 2, aux: "SymOff", symEffect: "Addr"},                    // arg0 + 2*arg1 + auxint + aux
+		{name: "LEAW2", argLength: 2, reg: gp21sb, asm: "LEAW", scale: 2, aux: "SymOff", symEffect: "Addr"},                    // arg0 + 2*arg1 + auxint + aux
+		{name: "LEAQ4", argLength: 2, reg: gp21sb, asm: "LEAQ", scale: 4, aux: "SymOff", symEffect: "Addr"},                    // arg0 + 4*arg1 + auxint + aux
+		{name: "LEAL4", argLength: 2, reg: gp21sb, asm: "LEAL", scale: 4, aux: "SymOff", symEffect: "Addr"},                    // arg0 + 4*arg1 + auxint + aux
+		{name: "LEAW4", argLength: 2, reg: gp21sb, asm: "LEAW", scale: 4, aux: "SymOff", symEffect: "Addr"},                    // arg0 + 4*arg1 + auxint + aux
+		{name: "LEAQ8", argLength: 2, reg: gp21sb, asm: "LEAQ", scale: 8, aux: "SymOff", symEffect: "Addr"},                    // arg0 + 8*arg1 + auxint + aux
+		{name: "LEAL8", argLength: 2, reg: gp21sb, asm: "LEAL", scale: 8, aux: "SymOff", symEffect: "Addr"},                    // arg0 + 8*arg1 + auxint + aux
+		{name: "LEAW8", argLength: 2, reg: gp21sb, asm: "LEAW", scale: 8, aux: "SymOff", symEffect: "Addr"},                    // arg0 + 8*arg1 + auxint + aux
+		// Note: LEAx{1,2,4,8} must not have OpSB as either argument.
+
+		// MOVxload: loads
+		// Load (Q=8,L=4,W=2,B=1) bytes from (arg0+auxint+aux), arg1=mem.
+		// "+auxint+aux" == add auxint and the offset of the symbol in aux (if any) to the effective address
+		// Standard versions zero extend the result. SX versions sign extend the result.
+		{name: "MOVBload", argLength: 2, reg: gpload, asm: "MOVBLZX", aux: "SymOff", typ: "UInt8", faultOnNilArg0: true, symEffect: "Read"},
+		{name: "MOVBQSXload", argLength: 2, reg: gpload, asm: "MOVBQSX", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},
+		{name: "MOVWload", argLength: 2, reg: gpload, asm: "MOVWLZX", aux: "SymOff", typ: "UInt16", faultOnNilArg0: true, symEffect: "Read"},
+		{name: "MOVWQSXload", argLength: 2, reg: gpload, asm: "MOVWQSX", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},
+		{name: "MOVLload", argLength: 2, reg: gpload, asm: "MOVL", aux: "SymOff", typ: "UInt32", faultOnNilArg0: true, symEffect: "Read"},
+		{name: "MOVLQSXload", argLength: 2, reg: gpload, asm: "MOVLQSX", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},
+		{name: "MOVQload", argLength: 2, reg: gpload, asm: "MOVQ", aux: "SymOff", typ: "UInt64", faultOnNilArg0: true, symEffect: "Read"},
+
+		// MOVxstore: stores
+		// Store (Q=8,L=4,W=2,B=1) low bytes of arg1.
+		// Does *(arg0+auxint+aux) = arg1, arg2=mem.
+		{name: "MOVBstore", argLength: 3, reg: gpstore, asm: "MOVB", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},
+		{name: "MOVWstore", argLength: 3, reg: gpstore, asm: "MOVW", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},
+		{name: "MOVLstore", argLength: 3, reg: gpstore, asm: "MOVL", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},
+		{name: "MOVQstore", argLength: 3, reg: gpstore, asm: "MOVQ", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},
+
+		// MOVOload/store: 16 byte load/store
+		// These operations are only used to move data around: there is no *O arithmetic, for example.
+		{name: "MOVOload", argLength: 2, reg: fpload, asm: "MOVUPS", aux: "SymOff", typ: "Int128", faultOnNilArg0: true, symEffect: "Read"}, // load 16 bytes from arg0+auxint+aux. arg1=mem
+		{name: "MOVOstore", argLength: 3, reg: fpstore, asm: "MOVUPS", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 16 bytes in arg1 to arg0+auxint+aux. arg2=mem
+
+		// MOVxloadidx: indexed loads
+		// load (Q=8,L=4,W=2,B=1) bytes from (arg0+scale*arg1+auxint+aux), arg2=mem.
+		// Results are zero-extended. (TODO: sign-extending indexed loads)
+		{name: "MOVBloadidx1", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVBLZX", scale: 1, aux: "SymOff", typ: "UInt8", symEffect: "Read"},
+		{name: "MOVWloadidx1", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVWLZX", scale: 1, aux: "SymOff", typ: "UInt16", symEffect: "Read"},
+		{name: "MOVWloadidx2", argLength: 3, reg: gploadidx, asm: "MOVWLZX", scale: 2, aux: "SymOff", typ: "UInt16", symEffect: "Read"},
+		{name: "MOVLloadidx1", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVL", scale: 1, aux: "SymOff", typ: "UInt32", symEffect: "Read"},
+		{name: "MOVLloadidx4", argLength: 3, reg: gploadidx, asm: "MOVL", scale: 4, aux: "SymOff", typ: "UInt32", symEffect: "Read"},
+		{name: "MOVLloadidx8", argLength: 3, reg: gploadidx, asm: "MOVL", scale: 8, aux: "SymOff", typ: "UInt32", symEffect: "Read"},
+		{name: "MOVQloadidx1", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVQ", scale: 1, aux: "SymOff", typ: "UInt64", symEffect: "Read"},
+		{name: "MOVQloadidx8", argLength: 3, reg: gploadidx, asm: "MOVQ", scale: 8, aux: "SymOff", typ: "UInt64", symEffect: "Read"},
+
+		// MOVxstoreidx: indexed stores
+		// Store (Q=8,L=4,W=2,B=1) low bytes of arg2.
+		// Does *(arg0+scale*arg1+auxint+aux) = arg2, arg3=mem.
+		{name: "MOVBstoreidx1", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVB", scale: 1, aux: "SymOff", symEffect: "Write"},
+		{name: "MOVWstoreidx1", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVW", scale: 1, aux: "SymOff", symEffect: "Write"},
+		{name: "MOVWstoreidx2", argLength: 4, reg: gpstoreidx, asm: "MOVW", scale: 2, aux: "SymOff", symEffect: "Write"},
+		{name: "MOVLstoreidx1", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVL", scale: 1, aux: "SymOff", symEffect: "Write"},
+		{name: "MOVLstoreidx4", argLength: 4, reg: gpstoreidx, asm: "MOVL", scale: 4, aux: "SymOff", symEffect: "Write"},
+		{name: "MOVLstoreidx8", argLength: 4, reg: gpstoreidx, asm: "MOVL", scale: 8, aux: "SymOff", symEffect: "Write"},
+		{name: "MOVQstoreidx1", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVQ", scale: 1, aux: "SymOff", symEffect: "Write"},
+		{name: "MOVQstoreidx8", argLength: 4, reg: gpstoreidx, asm: "MOVQ", scale: 8, aux: "SymOff", symEffect: "Write"},
+
+		// TODO: add size-mismatched indexed loads/stores, like MOVBstoreidx4?
+
+		// MOVxstoreconst: constant stores
+		// Store (O=16,Q=8,L=4,W=2,B=1) constant bytes.
+		// Does *(arg0+ValAndOff(AuxInt).Off()+aux) = ValAndOff(AuxInt).Val(), arg1=mem.
+		// O version can only store the constant 0.
+		{name: "MOVBstoreconst", argLength: 2, reg: gpstoreconst, asm: "MOVB", aux: "SymValAndOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},
+		{name: "MOVWstoreconst", argLength: 2, reg: gpstoreconst, asm: "MOVW", aux: "SymValAndOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},
+		{name: "MOVLstoreconst", argLength: 2, reg: gpstoreconst, asm: "MOVL", aux: "SymValAndOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},
+		{name: "MOVQstoreconst", argLength: 2, reg: gpstoreconst, asm: "MOVQ", aux: "SymValAndOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},
+		{name: "MOVOstoreconst", argLength: 2, reg: gpstoreconst, asm: "MOVUPS", aux: "SymValAndOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},
+
+		// MOVxstoreconstidx: constant indexed stores
+		// Store (Q=8,L=4,W=2,B=1) constant bytes.
+		// Does *(arg0+scale*arg1+ValAndOff(AuxInt).Off()+aux) = ValAndOff(AuxInt).Val(), arg2=mem.
+		{name: "MOVBstoreconstidx1", argLength: 3, reg: gpstoreconstidx, commutative: true, asm: "MOVB", scale: 1, aux: "SymValAndOff", typ: "Mem", symEffect: "Write"},
+		{name: "MOVWstoreconstidx1", argLength: 3, reg: gpstoreconstidx, commutative: true, asm: "MOVW", scale: 1, aux: "SymValAndOff", typ: "Mem", symEffect: "Write"},
+		{name: "MOVWstoreconstidx2", argLength: 3, reg: gpstoreconstidx, asm: "MOVW", scale: 2, aux: "SymValAndOff", typ: "Mem", symEffect: "Write"},
+		{name: "MOVLstoreconstidx1", argLength: 3, reg: gpstoreconstidx, commutative: true, asm: "MOVL", scale: 1, aux: "SymValAndOff", typ: "Mem", symEffect: "Write"},
+		{name: "MOVLstoreconstidx4", argLength: 3, reg: gpstoreconstidx, asm: "MOVL", scale: 4, aux: "SymValAndOff", typ: "Mem", symEffect: "Write"},
+		{name: "MOVQstoreconstidx1", argLength: 3, reg: gpstoreconstidx, commutative: true, asm: "MOVQ", scale: 1, aux: "SymValAndOff", typ: "Mem", symEffect: "Write"},
+		{name: "MOVQstoreconstidx8", argLength: 3, reg: gpstoreconstidx, asm: "MOVQ", scale: 8, aux: "SymValAndOff", typ: "Mem", symEffect: "Write"},
+
+		// arg0 = pointer to start of memory to zero
+		// arg1 = mem
+		// auxint = # of bytes to zero
+		// returns mem
+		{
+			name:      "DUFFZERO",
+			aux:       "Int64",
+			argLength: 2,
+			reg: regInfo{
+				inputs:   []regMask{buildReg("DI")},
+				clobbers: buildReg("DI"),
+			},
+			faultOnNilArg0: true,
+			unsafePoint:    true, // FP maintenance around DUFFCOPY can be clobbered by interrupts
+		},
+
+		// arg0 = address of memory to zero
+		// arg1 = # of 8-byte words to zero
+		// arg2 = value to store (will always be zero)
+		// arg3 = mem
+		// returns mem
+		{
+			name:      "REPSTOSQ",
+			argLength: 4,
+			reg: regInfo{
+				inputs:   []regMask{buildReg("DI"), buildReg("CX"), buildReg("AX")},
+				clobbers: buildReg("DI CX"),
+			},
+			faultOnNilArg0: true,
+		},
+
+		// With a register ABI, the actual register info for these instructions (i.e., what is used in regalloc) is augmented with per-call-site bindings of additional arguments to specific in and out registers.
+		{name: "CALLstatic", argLength: -1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                                              // call static function aux.(*obj.LSym).  last arg=mem, auxint=argsize, returns mem
+		{name: "CALLtail", argLength: -1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true, tailCall: true},                                // tail call static function aux.(*obj.LSym).  last arg=mem, auxint=argsize, returns mem
+		{name: "CALLclosure", argLength: -1, reg: regInfo{inputs: []regMask{gpsp, buildReg("DX"), 0}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call function via closure.  arg0=codeptr, arg1=closure, last arg=mem, auxint=argsize, returns mem
+		{name: "CALLinter", argLength: -1, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                        // call fn by pointer.  arg0=codeptr, last arg=mem, auxint=argsize, returns mem
+
+		// arg0 = destination pointer
+		// arg1 = source pointer
+		// arg2 = mem
+		// auxint = # of bytes to copy, must be multiple of 16
+		// returns memory
+		{
+			name:      "DUFFCOPY",
+			aux:       "Int64",
+			argLength: 3,
+			reg: regInfo{
+				inputs:   []regMask{buildReg("DI"), buildReg("SI")},
+				clobbers: buildReg("DI SI X0"), // uses X0 as a temporary
+			},
+			clobberFlags:   true,
+			faultOnNilArg0: true,
+			faultOnNilArg1: true,
+			unsafePoint:    true, // FP maintenance around DUFFCOPY can be clobbered by interrupts
+		},
+
+		// arg0 = destination pointer
+		// arg1 = source pointer
+		// arg2 = # of 8-byte words to copy
+		// arg3 = mem
+		// returns memory
+		{
+			name:      "REPMOVSQ",
+			argLength: 4,
+			reg: regInfo{
+				inputs:   []regMask{buildReg("DI"), buildReg("SI"), buildReg("CX")},
+				clobbers: buildReg("DI SI CX"),
+			},
+			faultOnNilArg0: true,
+			faultOnNilArg1: true,
+		},
+
+		// (InvertFlags (CMPQ a b)) == (CMPQ b a)
+		// So if we want (SETL (CMPQ a b)) but we can't do that because a is a constant,
+		// then we do (SETL (InvertFlags (CMPQ b a))) instead.
+		// Rewrites will convert this to (SETG (CMPQ b a)).
+		// InvertFlags is a pseudo-op which can't appear in assembly output.
+		{name: "InvertFlags", argLength: 1}, // reverse direction of arg0
+
+		// Pseudo-ops
+		{name: "LoweredGetG", argLength: 1, reg: gp01}, // arg0=mem
+		// Scheduler ensures LoweredGetClosurePtr occurs only in entry block,
+		// and sorts it to the very beginning of the block to prevent other
+		// use of DX (the closure pointer)
+		{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("DX")}}, zeroWidth: true},
+		// LoweredGetCallerPC evaluates to the PC to which its "caller" will return.
+		// I.e., if f calls g "calls" getcallerpc,
+		// the result should be the PC within f that g will return to.
+		// See runtime/stubs.go for a more detailed discussion.
+		{name: "LoweredGetCallerPC", reg: gp01, rematerializeable: true},
+		// LoweredGetCallerSP returns the SP of the caller of the current function.
+		{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
+		//arg0=ptr,arg1=mem, returns void.  Faults if ptr is nil.
+		{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpsp}}, clobberFlags: true, nilCheck: true, faultOnNilArg0: true},
+		// LoweredWB invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
+		// It saves all GP registers if necessary, but may clobber others.
+		{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("DI"), buildReg("AX CX DX BX BP SI R8 R9")}, clobbers: callerSave &^ (gp | g)}, clobberFlags: true, aux: "Sym", symEffect: "None"},
+
+		{name: "LoweredHasCPUFeature", argLength: 0, reg: gp01, rematerializeable: true, typ: "UInt64", aux: "Sym", symEffect: "None"},
+
+		// There are three of these functions so that they can have three different register inputs.
+		// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the
+		// default registers to match so we don't need to copy registers around unnecessarily.
+		{name: "LoweredPanicBoundsA", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{dx, bx}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
+		{name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{cx, dx}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
+		{name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{ax, cx}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
+
+		// Constant flag values. For any comparison, there are 5 possible
+		// outcomes: the three from the signed total order (<,==,>) and the
+		// three from the unsigned total order. The == cases overlap.
+		// Note: there's a sixth "unordered" outcome for floating-point
+		// comparisons, but we don't use such a beast yet.
+		// These ops are for temporary use by rewrite rules. They
+		// cannot appear in the generated assembly.
+		{name: "FlagEQ"},     // equal
+		{name: "FlagLT_ULT"}, // signed < and unsigned <
+		{name: "FlagLT_UGT"}, // signed < and unsigned >
+		{name: "FlagGT_UGT"}, // signed > and unsigned >
+		{name: "FlagGT_ULT"}, // signed > and unsigned <
+
+		// Atomic loads.  These are just normal loads but return <value,memory> tuples
+		// so they can be properly ordered with other loads.
+		// load from arg0+auxint+aux.  arg1=mem.
+		{name: "MOVBatomicload", argLength: 2, reg: gpload, asm: "MOVB", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},
+		{name: "MOVLatomicload", argLength: 2, reg: gpload, asm: "MOVL", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},
+		{name: "MOVQatomicload", argLength: 2, reg: gpload, asm: "MOVQ", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},
+
+		// Atomic stores and exchanges.  Stores use XCHG to get the right memory ordering semantics.
+		// store arg0 to arg1+auxint+aux, arg2=mem.
+		// These ops return a tuple of <old contents of *(arg1+auxint+aux), memory>.
+		// Note: arg0 and arg1 are backwards compared to MOVLstore (to facilitate resultInArg0)!
+		{name: "XCHGB", argLength: 3, reg: gpstorexchg, asm: "XCHGB", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, hasSideEffects: true, symEffect: "RdWr"},
+		{name: "XCHGL", argLength: 3, reg: gpstorexchg, asm: "XCHGL", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, hasSideEffects: true, symEffect: "RdWr"},
+		{name: "XCHGQ", argLength: 3, reg: gpstorexchg, asm: "XCHGQ", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, hasSideEffects: true, symEffect: "RdWr"},
+
+		// Atomic adds.
+		// *(arg1+auxint+aux) += arg0.  arg2=mem.
+		// Returns a tuple of <old contents of *(arg1+auxint+aux), memory>.
+		// Note: arg0 and arg1 are backwards compared to MOVLstore (to facilitate resultInArg0)!
+		{name: "XADDLlock", argLength: 3, reg: gpstorexchg, asm: "XADDL", typ: "(UInt32,Mem)", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, hasSideEffects: true, symEffect: "RdWr"},
+		{name: "XADDQlock", argLength: 3, reg: gpstorexchg, asm: "XADDQ", typ: "(UInt64,Mem)", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, hasSideEffects: true, symEffect: "RdWr"},
+		{name: "AddTupleFirst32", argLength: 2}, // arg1=tuple <x,y>.  Returns <x+arg0,y>.
+		{name: "AddTupleFirst64", argLength: 2}, // arg1=tuple <x,y>.  Returns <x+arg0,y>.
+
+		// Compare and swap.
+		// arg0 = pointer, arg1 = old value, arg2 = new value, arg3 = memory.
+		// if *(arg0+auxint+aux) == arg1 {
+		//   *(arg0+auxint+aux) = arg2
+		//   return (true, memory)
+		// } else {
+		//   return (false, memory)
+		// }
+		// Note that these instructions also return the old value in AX, but we ignore it.
+		// TODO: have these return flags instead of bool.  The current system generates:
+		//    CMPXCHGQ ...
+		//    SETEQ AX
+		//    CMPB  AX, $0
+		//    JNE ...
+		// instead of just
+		//    CMPXCHGQ ...
+		//    JEQ ...
+		// but we can't do that because memory-using ops can't generate flags yet
+		// (flagalloc wants to move flag-generating instructions around).
+		{name: "CMPXCHGLlock", argLength: 4, reg: cmpxchg, asm: "CMPXCHGL", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "RdWr"},
+		{name: "CMPXCHGQlock", argLength: 4, reg: cmpxchg, asm: "CMPXCHGQ", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "RdWr"},
+
+		// Atomic memory updates.
+		{name: "ANDBlock", argLength: 3, reg: gpstore, asm: "ANDB", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "RdWr"}, // *(arg0+auxint+aux) &= arg1
+		{name: "ANDLlock", argLength: 3, reg: gpstore, asm: "ANDL", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "RdWr"}, // *(arg0+auxint+aux) &= arg1
+		{name: "ORBlock", argLength: 3, reg: gpstore, asm: "ORB", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "RdWr"},   // *(arg0+auxint+aux) |= arg1
+		{name: "ORLlock", argLength: 3, reg: gpstore, asm: "ORL", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "RdWr"},   // *(arg0+auxint+aux) |= arg1
+
+		// Prefetch instructions
+		// Do prefetch arg0 address. arg0=addr, arg1=memory. Instruction variant selects locality hint
+		{name: "PrefetchT0", argLength: 2, reg: prefreg, asm: "PREFETCHT0", hasSideEffects: true},
+		{name: "PrefetchNTA", argLength: 2, reg: prefreg, asm: "PREFETCHNTA", hasSideEffects: true},
+
+		// CPUID feature: BMI1.
+		{name: "ANDNQ", argLength: 2, reg: gp21, asm: "ANDNQ", clobberFlags: true},     // arg0 &^ arg1
+		{name: "ANDNL", argLength: 2, reg: gp21, asm: "ANDNL", clobberFlags: true},     // arg0 &^ arg1
+		{name: "BLSIQ", argLength: 1, reg: gp11, asm: "BLSIQ", clobberFlags: true},     // arg0 & -arg0
+		{name: "BLSIL", argLength: 1, reg: gp11, asm: "BLSIL", clobberFlags: true},     // arg0 & -arg0
+		{name: "BLSMSKQ", argLength: 1, reg: gp11, asm: "BLSMSKQ", clobberFlags: true}, // arg0 ^ (arg0 - 1)
+		{name: "BLSMSKL", argLength: 1, reg: gp11, asm: "BLSMSKL", clobberFlags: true}, // arg0 ^ (arg0 - 1)
+		{name: "BLSRQ", argLength: 1, reg: gp11, asm: "BLSRQ", clobberFlags: true},     // arg0 & (arg0 - 1)
+		{name: "BLSRL", argLength: 1, reg: gp11, asm: "BLSRL", clobberFlags: true},     // arg0 & (arg0 - 1)
+		// count the number of trailing zero bits, prefer TZCNTQ over BSFQ, as TZCNTQ(0)==64
+		// and BSFQ(0) is undefined. Same for TZCNTL(0)==32
+		{name: "TZCNTQ", argLength: 1, reg: gp11, asm: "TZCNTQ", clobberFlags: true},
+		{name: "TZCNTL", argLength: 1, reg: gp11, asm: "TZCNTL", clobberFlags: true},
+
+		// CPUID feature: LZCNT.
+		// count the number of leading zero bits.
+		{name: "LZCNTQ", argLength: 1, reg: gp11, asm: "LZCNTQ", typ: "UInt64", clobberFlags: true},
+		{name: "LZCNTL", argLength: 1, reg: gp11, asm: "LZCNTL", typ: "UInt32", clobberFlags: true},
+
+		// CPUID feature: MOVBE
+		// MOVBEWload does not satisfy zero extended, so only use MOVBEWstore
+		{name: "MOVBEWstore", argLength: 3, reg: gpstore, asm: "MOVBEW", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // swap and store 2 bytes in arg1 to arg0+auxint+aux. arg2=mem
+		{name: "MOVBELload", argLength: 2, reg: gpload, asm: "MOVBEL", aux: "SymOff", typ: "UInt32", faultOnNilArg0: true, symEffect: "Read"}, // load and swap 4 bytes from arg0+auxint+aux. arg1=mem.  Zero extend.
+		{name: "MOVBELstore", argLength: 3, reg: gpstore, asm: "MOVBEL", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // swap and store 4 bytes in arg1 to arg0+auxint+aux. arg2=mem
+		{name: "MOVBEQload", argLength: 2, reg: gpload, asm: "MOVBEQ", aux: "SymOff", typ: "UInt64", faultOnNilArg0: true, symEffect: "Read"}, // load and swap 8 bytes from arg0+auxint+aux. arg1=mem
+		{name: "MOVBEQstore", argLength: 3, reg: gpstore, asm: "MOVBEQ", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // swap and store 8 bytes in arg1 to arg0+auxint+aux. arg2=mem
+		// indexed MOVBE loads
+		{name: "MOVBELloadidx1", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVBEL", scale: 1, aux: "SymOff", typ: "UInt32", symEffect: "Read"}, // load and swap 4 bytes from arg0+arg1+auxint+aux. arg2=mem. Zero extend.
+		{name: "MOVBELloadidx4", argLength: 3, reg: gploadidx, asm: "MOVBEL", scale: 4, aux: "SymOff", typ: "UInt32", symEffect: "Read"},                    // load and swap 4 bytes from arg0+4*arg1+auxint+aux. arg2=mem. Zero extend.
+		{name: "MOVBELloadidx8", argLength: 3, reg: gploadidx, asm: "MOVBEL", scale: 8, aux: "SymOff", typ: "UInt32", symEffect: "Read"},                    // load and swap 4 bytes from arg0+8*arg1+auxint+aux. arg2=mem. Zero extend.
+		{name: "MOVBEQloadidx1", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVBEQ", scale: 1, aux: "SymOff", typ: "UInt64", symEffect: "Read"}, // load and swap 8 bytes from arg0+arg1+auxint+aux. arg2=mem
+		{name: "MOVBEQloadidx8", argLength: 3, reg: gploadidx, asm: "MOVBEQ", scale: 8, aux: "SymOff", typ: "UInt64", symEffect: "Read"},                    // load and swap 8 bytes from arg0+8*arg1+auxint+aux. arg2=mem
+		// indexed MOVBE stores
+		{name: "MOVBEWstoreidx1", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVBEW", scale: 1, aux: "SymOff", symEffect: "Write"}, // swap and store 2 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem
+		{name: "MOVBEWstoreidx2", argLength: 4, reg: gpstoreidx, asm: "MOVBEW", scale: 2, aux: "SymOff", symEffect: "Write"},                    // swap and store 2 bytes in arg2 to arg0+2*arg1+auxint+aux. arg3=mem
+		{name: "MOVBELstoreidx1", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVBEL", scale: 1, aux: "SymOff", symEffect: "Write"}, // swap and store 4 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem
+		{name: "MOVBELstoreidx4", argLength: 4, reg: gpstoreidx, asm: "MOVBEL", scale: 4, aux: "SymOff", symEffect: "Write"},                    // swap and store 4 bytes in arg2 to arg0+4*arg1+auxint+aux. arg3=mem
+		{name: "MOVBELstoreidx8", argLength: 4, reg: gpstoreidx, asm: "MOVBEL", scale: 8, aux: "SymOff", symEffect: "Write"},                    // swap and store 4 bytes in arg2 to arg0+8*arg1+auxint+aux. arg3=mem
+		{name: "MOVBEQstoreidx1", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVBEQ", scale: 1, aux: "SymOff", symEffect: "Write"}, // swap and store 8 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem
+		{name: "MOVBEQstoreidx8", argLength: 4, reg: gpstoreidx, asm: "MOVBEQ", scale: 8, aux: "SymOff", symEffect: "Write"},                    // swap and store 8 bytes in arg2 to arg0+8*arg1+auxint+aux. arg3=mem
+
+		// CPUID feature: BMI2.
+		{name: "SARXQ", argLength: 2, reg: gp21, asm: "SARXQ"}, // signed arg0 >> arg1, shift amount is mod 64
+		{name: "SARXL", argLength: 2, reg: gp21, asm: "SARXL"}, // signed int32(arg0) >> arg1, shift amount is mod 32
+		{name: "SHLXQ", argLength: 2, reg: gp21, asm: "SHLXQ"}, // arg0 << arg1, shift amount is mod 64
+		{name: "SHLXL", argLength: 2, reg: gp21, asm: "SHLXL"}, // arg0 << arg1, shift amount is mod 32
+		{name: "SHRXQ", argLength: 2, reg: gp21, asm: "SHRXQ"}, // unsigned arg0 >> arg1, shift amount is mod 64
+		{name: "SHRXL", argLength: 2, reg: gp21, asm: "SHRXL"}, // unsigned uint32(arg0) >> arg1, shift amount is mod 32
+
+		{name: "SARXLload", argLength: 3, reg: gp21shxload, asm: "SARXL", aux: "SymOff", typ: "Uint32", faultOnNilArg0: true, symEffect: "Read"}, // signed *(arg0+auxint+aux) >> arg1, arg2=mem, shift amount is mod 32
+		{name: "SARXQload", argLength: 3, reg: gp21shxload, asm: "SARXQ", aux: "SymOff", typ: "Uint64", faultOnNilArg0: true, symEffect: "Read"}, // signed *(arg0+auxint+aux) >> arg1, arg2=mem, shift amount is mod 64
+		{name: "SHLXLload", argLength: 3, reg: gp21shxload, asm: "SHLXL", aux: "SymOff", typ: "Uint32", faultOnNilArg0: true, symEffect: "Read"}, // *(arg0+auxint+aux) << arg1, arg2=mem, shift amount is mod 32
+		{name: "SHLXQload", argLength: 3, reg: gp21shxload, asm: "SHLXQ", aux: "SymOff", typ: "Uint64", faultOnNilArg0: true, symEffect: "Read"}, // *(arg0+auxint+aux) << arg1, arg2=mem, shift amount is mod 64
+		{name: "SHRXLload", argLength: 3, reg: gp21shxload, asm: "SHRXL", aux: "SymOff", typ: "Uint32", faultOnNilArg0: true, symEffect: "Read"}, // unsigned *(arg0+auxint+aux) >> arg1, arg2=mem, shift amount is mod 32
+		{name: "SHRXQload", argLength: 3, reg: gp21shxload, asm: "SHRXQ", aux: "SymOff", typ: "Uint64", faultOnNilArg0: true, symEffect: "Read"}, // unsigned *(arg0+auxint+aux) >> arg1, arg2=mem, shift amount is mod 64
+
+		{name: "SARXLloadidx1", argLength: 4, reg: gp21shxloadidx, asm: "SARXL", scale: 1, aux: "SymOff", typ: "Uint32", faultOnNilArg0: true, symEffect: "Read"}, // signed *(arg0+1*arg1+auxint+aux) >> arg2, arg3=mem, shift amount is mod 32
+		{name: "SARXLloadidx4", argLength: 4, reg: gp21shxloadidx, asm: "SARXL", scale: 4, aux: "SymOff", typ: "Uint32", faultOnNilArg0: true, symEffect: "Read"}, // signed *(arg0+4*arg1+auxint+aux) >> arg2, arg3=mem, shift amount is mod 32
+		{name: "SARXLloadidx8", argLength: 4, reg: gp21shxloadidx, asm: "SARXL", scale: 8, aux: "SymOff", typ: "Uint32", faultOnNilArg0: true, symEffect: "Read"}, // signed *(arg0+8*arg1+auxint+aux) >> arg2, arg3=mem, shift amount is mod 32
+		{name: "SARXQloadidx1", argLength: 4, reg: gp21shxloadidx, asm: "SARXQ", scale: 1, aux: "SymOff", typ: "Uint64", faultOnNilArg0: true, symEffect: "Read"}, // signed *(arg0+1*arg1+auxint+aux) >> arg2, arg3=mem, shift amount is mod 64
+		{name: "SARXQloadidx8", argLength: 4, reg: gp21shxloadidx, asm: "SARXQ", scale: 8, aux: "SymOff", typ: "Uint64", faultOnNilArg0: true, symEffect: "Read"}, // signed *(arg0+8*arg1+auxint+aux) >> arg2, arg3=mem, shift amount is mod 64
+		{name: "SHLXLloadidx1", argLength: 4, reg: gp21shxloadidx, asm: "SHLXL", scale: 1, aux: "SymOff", typ: "Uint32", faultOnNilArg0: true, symEffect: "Read"}, // *(arg0+1*arg1+auxint+aux) << arg2, arg3=mem, shift amount is mod 32
+		{name: "SHLXLloadidx4", argLength: 4, reg: gp21shxloadidx, asm: "SHLXL", scale: 4, aux: "SymOff", typ: "Uint32", faultOnNilArg0: true, symEffect: "Read"}, // *(arg0+4*arg1+auxint+aux) << arg2, arg3=mem, shift amount is mod 32
+		{name: "SHLXLloadidx8", argLength: 4, reg: gp21shxloadidx, asm: "SHLXL", scale: 8, aux: "SymOff", typ: "Uint32", faultOnNilArg0: true, symEffect: "Read"}, // *(arg0+8*arg1+auxint+aux) << arg2, arg3=mem, shift amount is mod 32
+		{name: "SHLXQloadidx1", argLength: 4, reg: gp21shxloadidx, asm: "SHLXQ", scale: 1, aux: "SymOff", typ: "Uint64", faultOnNilArg0: true, symEffect: "Read"}, // *(arg0+1*arg1+auxint+aux) << arg2, arg3=mem, shift amount is mod 64
+		{name: "SHLXQloadidx8", argLength: 4, reg: gp21shxloadidx, asm: "SHLXQ", scale: 8, aux: "SymOff", typ: "Uint64", faultOnNilArg0: true, symEffect: "Read"}, // *(arg0+8*arg1+auxint+aux) << arg2, arg3=mem, shift amount is mod 64
+		{name: "SHRXLloadidx1", argLength: 4, reg: gp21shxloadidx, asm: "SHRXL", scale: 1, aux: "SymOff", typ: "Uint32", faultOnNilArg0: true, symEffect: "Read"}, // unsigned *(arg0+1*arg1+auxint+aux) >> arg2, arg3=mem, shift amount is mod 32
+		{name: "SHRXLloadidx4", argLength: 4, reg: gp21shxloadidx, asm: "SHRXL", scale: 4, aux: "SymOff", typ: "Uint32", faultOnNilArg0: true, symEffect: "Read"}, // unsigned *(arg0+4*arg1+auxint+aux) >> arg2, arg3=mem, shift amount is mod 32
+		{name: "SHRXLloadidx8", argLength: 4, reg: gp21shxloadidx, asm: "SHRXL", scale: 8, aux: "SymOff", typ: "Uint32", faultOnNilArg0: true, symEffect: "Read"}, // unsigned *(arg0+8*arg1+auxint+aux) >> arg2, arg3=mem, shift amount is mod 32
+		{name: "SHRXQloadidx1", argLength: 4, reg: gp21shxloadidx, asm: "SHRXQ", scale: 1, aux: "SymOff", typ: "Uint64", faultOnNilArg0: true, symEffect: "Read"}, // unsigned *(arg0+1*arg1+auxint+aux) >> arg2, arg3=mem, shift amount is mod 64
+		{name: "SHRXQloadidx8", argLength: 4, reg: gp21shxloadidx, asm: "SHRXQ", scale: 8, aux: "SymOff", typ: "Uint64", faultOnNilArg0: true, symEffect: "Read"}, // unsigned *(arg0+8*arg1+auxint+aux) >> arg2, arg3=mem, shift amount is mod 64
+	}
+
+	var AMD64blocks = []blockData{
+		{name: "EQ", controls: 1},
+		{name: "NE", controls: 1},
+		{name: "LT", controls: 1},
+		{name: "LE", controls: 1},
+		{name: "GT", controls: 1},
+		{name: "GE", controls: 1},
+		{name: "OS", controls: 1},
+		{name: "OC", controls: 1},
+		{name: "ULT", controls: 1},
+		{name: "ULE", controls: 1},
+		{name: "UGT", controls: 1},
+		{name: "UGE", controls: 1},
+		{name: "EQF", controls: 1},
+		{name: "NEF", controls: 1},
+		{name: "ORD", controls: 1}, // FP, ordered comparison (parity zero)
+		{name: "NAN", controls: 1}, // FP, unordered comparison (parity one)
+
+		// JUMPTABLE implements jump tables.
+		// Aux is the symbol (an *obj.LSym) for the jump table.
+		// control[0] is the index into the jump table.
+		// control[1] is the address of the jump table (the address of the symbol stored in Aux).
+		{name: "JUMPTABLE", controls: 2, aux: "Sym"},
+	}
+
+	archs = append(archs, arch{
+		name:               "AMD64",
+		pkg:                "cmd/internal/obj/x86",
+		genfile:            "../../amd64/ssa.go",
+		ops:                AMD64ops,
+		blocks:             AMD64blocks,
+		regnames:           regNamesAMD64,
+		ParamIntRegNames:   "AX BX CX DI SI R8 R9 R10 R11",
+		ParamFloatRegNames: "X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14",
+		gpregmask:          gp,
+		fpregmask:          fp,
+		specialregmask:     x15,
+		framepointerreg:    int8(num["BP"]),
+		linkreg:            -1, // not used
+	})
+}
diff --git a/src/cmd/compile/internal/ssa/_gen/AMD64latelower.rules b/src/cmd/compile/internal/ssa/_gen/AMD64latelower.rules
new file mode 100644
index 0000000..bcf4531
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/_gen/AMD64latelower.rules
@@ -0,0 +1,16 @@
+// Copyright 2022 The Go Authors. All rights reserved.

+// Use of this source code is governed by a BSD-style

+// license that can be found in the LICENSE file.

+

+// split 3 operand LEA.

+// Note: Don't split pointer computations in order to avoid invalid pointers.

+(LEA(Q|L|W)1 <t> [c] {s} x y) &&  isPtr(x.Type) && c != 0 && s == nil => (ADD(Q|L|L) x (ADD(Q|L|L)const <y.Type> [c] y))

+(LEA(Q|L|W)1 <t> [c] {s} x y) && !isPtr(x.Type) && c != 0 && s == nil => (ADD(Q|L|L) y (ADD(Q|L|L)const <x.Type> [c] x))

+(LEA(Q|L|W)2 <t> [c] {s} x y) && !isPtr(t)      && c != 0 && s == nil => (ADD(Q|L|L)const [c] (LEA(Q|L|W)2 <x.Type> x y))

+(LEA(Q|L|W)4 <t> [c] {s} x y) && !isPtr(t)      && c != 0 && s == nil => (ADD(Q|L|L)const [c] (LEA(Q|L|W)4 <x.Type> x y))

+(LEA(Q|L|W)8 <t> [c] {s} x y) && !isPtr(t)      && c != 0 && s == nil => (ADD(Q|L|L)const [c] (LEA(Q|L|W)8 <x.Type> x y))

+

+// Prefer SARX/SHLX/SHRX instruction because it has less register restriction on the shift input.

+(SAR(Q|L) x y) && buildcfg.GOAMD64 >= 3 => (SARX(Q|L) x y)

+(SHL(Q|L) x y) && buildcfg.GOAMD64 >= 3 => (SHLX(Q|L) x y)

+(SHR(Q|L) x y) && buildcfg.GOAMD64 >= 3 => (SHRX(Q|L) x y)

diff --git a/src/cmd/compile/internal/ssa/gen/AMD64splitload.rules b/src/cmd/compile/internal/ssa/_gen/AMD64splitload.rules
similarity index 100%
rename from src/cmd/compile/internal/ssa/gen/AMD64splitload.rules
rename to src/cmd/compile/internal/ssa/_gen/AMD64splitload.rules
diff --git a/src/cmd/compile/internal/ssa/_gen/ARM.rules b/src/cmd/compile/internal/ssa/_gen/ARM.rules
new file mode 100644
index 0000000..e5898b0
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/_gen/ARM.rules
@@ -0,0 +1,1474 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+(Add(Ptr|32|16|8) ...) => (ADD ...)
+(Add(32|64)F ...) => (ADD(F|D) ...)
+(Add32carry ...) => (ADDS ...)
+(Add32withcarry ...) => (ADC ...)
+
+(Sub(Ptr|32|16|8) ...) => (SUB ...)
+(Sub(32|64)F ...) => (SUB(F|D) ...)
+(Sub32carry ...) => (SUBS ...)
+(Sub32withcarry ...) => (SBC ...)
+
+(Mul(32|16|8) ...) => (MUL ...)
+(Mul(32|64)F ...) => (MUL(F|D) ...)
+(Hmul(32|32u) ...) => (HMU(L|LU) ...)
+(Mul32uhilo ...) => (MULLU ...)
+
+(Div32 x y) =>
+	(SUB (XOR <typ.UInt32>                                                        // negate the result if one operand is negative
+		(Select0 <typ.UInt32> (CALLudiv
+			(SUB <typ.UInt32> (XOR x <typ.UInt32> (Signmask x)) (Signmask x))   // negate x if negative
+			(SUB <typ.UInt32> (XOR y <typ.UInt32> (Signmask y)) (Signmask y)))) // negate y if negative
+		(Signmask (XOR <typ.UInt32> x y))) (Signmask (XOR <typ.UInt32> x y)))
+(Div32u x y) => (Select0 <typ.UInt32> (CALLudiv x y))
+(Div16 x y) => (Div32 (SignExt16to32 x) (SignExt16to32 y))
+(Div16u x y) => (Div32u (ZeroExt16to32 x) (ZeroExt16to32 y))
+(Div8 x y) => (Div32 (SignExt8to32 x) (SignExt8to32 y))
+(Div8u x y) => (Div32u (ZeroExt8to32 x) (ZeroExt8to32 y))
+(Div(32|64)F ...) => (DIV(F|D) ...)
+
+(Mod32 x y) =>
+	(SUB (XOR <typ.UInt32>                                                        // negate the result if x is negative
+		(Select1 <typ.UInt32> (CALLudiv
+			(SUB <typ.UInt32> (XOR <typ.UInt32> x (Signmask x)) (Signmask x))   // negate x if negative
+			(SUB <typ.UInt32> (XOR <typ.UInt32> y (Signmask y)) (Signmask y)))) // negate y if negative
+		(Signmask x)) (Signmask x))
+(Mod32u x y) => (Select1 <typ.UInt32> (CALLudiv x y))
+(Mod16 x y) => (Mod32 (SignExt16to32 x) (SignExt16to32 y))
+(Mod16u x y) => (Mod32u (ZeroExt16to32 x) (ZeroExt16to32 y))
+(Mod8 x y) => (Mod32 (SignExt8to32 x) (SignExt8to32 y))
+(Mod8u x y) => (Mod32u (ZeroExt8to32 x) (ZeroExt8to32 y))
+
+// (x + y) / 2 with x>=y -> (x - y) / 2 + y
+(Avg32u <t> x y) => (ADD (SRLconst <t> (SUB <t> x y) [1]) y)
+
+(And(32|16|8) ...) => (AND ...)
+(Or(32|16|8) ...) => (OR ...)
+(Xor(32|16|8) ...) => (XOR ...)
+
+// unary ops
+(Neg(32|16|8) x) => (RSBconst [0] x)
+(Neg(32|64)F ...) => (NEG(F|D) ...)
+
+(Com(32|16|8) ...) => (MVN ...)
+
+(Sqrt ...) => (SQRTD ...)
+(Sqrt32 ...) => (SQRTF ...)
+(Abs ...) => (ABSD ...)
+
+// TODO: optimize this for ARMv5 and ARMv6
+(Ctz32NonZero ...) => (Ctz32 ...)
+(Ctz16NonZero ...) => (Ctz32 ...)
+(Ctz8NonZero ...) => (Ctz32 ...)
+
+// count trailing zero for ARMv5 and ARMv6
+// 32 - CLZ(x&-x - 1)
+(Ctz32 <t> x) && buildcfg.GOARM<=6 =>
+	(RSBconst [32] (CLZ <t> (SUBconst <t> (AND <t> x (RSBconst <t> [0] x)) [1])))
+(Ctz16 <t> x) && buildcfg.GOARM<=6 =>
+	(RSBconst [32] (CLZ <t> (SUBconst <typ.UInt32> (AND <typ.UInt32> (ORconst <typ.UInt32> [0x10000] x) (RSBconst <typ.UInt32> [0] (ORconst <typ.UInt32> [0x10000] x))) [1])))
+(Ctz8 <t> x) && buildcfg.GOARM<=6 =>
+	(RSBconst [32] (CLZ <t> (SUBconst <typ.UInt32> (AND <typ.UInt32> (ORconst <typ.UInt32> [0x100] x) (RSBconst <typ.UInt32> [0] (ORconst <typ.UInt32> [0x100] x))) [1])))
+
+// count trailing zero for ARMv7
+(Ctz32 <t> x) && buildcfg.GOARM==7 => (CLZ <t> (RBIT <t> x))
+(Ctz16 <t> x) && buildcfg.GOARM==7 => (CLZ <t> (RBIT <typ.UInt32> (ORconst <typ.UInt32> [0x10000] x)))
+(Ctz8 <t> x) && buildcfg.GOARM==7 => (CLZ <t> (RBIT <typ.UInt32> (ORconst <typ.UInt32> [0x100] x)))
+
+// bit length
+(BitLen32 <t> x) => (RSBconst [32] (CLZ <t> x))
+
+// byte swap for ARMv5
+// let (a, b, c, d) be the bytes of x from high to low
+// t1 = x right rotate 16 bits -- (c,   d,   a,   b  )
+// t2 = x ^ t1                 -- (a^c, b^d, a^c, b^d)
+// t3 = t2 &^ 0xff0000         -- (a^c, 0,   a^c, b^d)
+// t4 = t3 >> 8                -- (0,   a^c, 0,   a^c)
+// t5 = x right rotate 8 bits  -- (d,   a,   b,   c  )
+// result = t4 ^ t5            -- (d,   c,   b,   a  )
+// using shifted ops this can be done in 4 instructions.
+(Bswap32 <t> x) && buildcfg.GOARM==5 =>
+	(XOR <t>
+		(SRLconst <t> (BICconst <t> (XOR <t> x (SRRconst <t> [16] x)) [0xff0000]) [8])
+		(SRRconst <t> x [8]))
+
+// byte swap for ARMv6 and above
+(Bswap32 x) && buildcfg.GOARM>=6 => (REV x)
+
+// boolean ops -- booleans are represented with 0=false, 1=true
+(AndB ...) => (AND ...)
+(OrB ...) => (OR ...)
+(EqB x y) => (XORconst [1] (XOR <typ.Bool> x y))
+(NeqB ...) => (XOR ...)
+(Not x) => (XORconst [1] x)
+
+// shifts
+// hardware instruction uses only the low byte of the shift
+// we compare to 256 to ensure Go semantics for large shifts
+(Lsh32x32 x y) => (CMOVWHSconst (SLL <x.Type> x y) (CMPconst [256] y) [0])
+(Lsh32x16 x y) => (CMOVWHSconst (SLL <x.Type> x (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0])
+(Lsh32x8  x y) => (SLL x (ZeroExt8to32 y))
+
+(Lsh16x32 x y) => (CMOVWHSconst (SLL <x.Type> x y) (CMPconst [256] y) [0])
+(Lsh16x16 x y) => (CMOVWHSconst (SLL <x.Type> x (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0])
+(Lsh16x8  x y) => (SLL x (ZeroExt8to32 y))
+
+(Lsh8x32 x y) => (CMOVWHSconst (SLL <x.Type> x y) (CMPconst [256] y) [0])
+(Lsh8x16 x y) => (CMOVWHSconst (SLL <x.Type> x (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0])
+(Lsh8x8  x y) => (SLL x (ZeroExt8to32 y))
+
+(Rsh32Ux32 x y) => (CMOVWHSconst (SRL <x.Type> x y) (CMPconst [256] y) [0])
+(Rsh32Ux16 x y) => (CMOVWHSconst (SRL <x.Type> x (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0])
+(Rsh32Ux8  x y) => (SRL x (ZeroExt8to32 y))
+
+(Rsh16Ux32 x y) => (CMOVWHSconst (SRL <x.Type> (ZeroExt16to32 x) y) (CMPconst [256] y) [0])
+(Rsh16Ux16 x y) => (CMOVWHSconst (SRL <x.Type> (ZeroExt16to32 x) (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0])
+(Rsh16Ux8  x y) => (SRL (ZeroExt16to32 x) (ZeroExt8to32 y))
+
+(Rsh8Ux32 x y) => (CMOVWHSconst (SRL <x.Type> (ZeroExt8to32 x) y) (CMPconst [256] y) [0])
+(Rsh8Ux16 x y) => (CMOVWHSconst (SRL <x.Type> (ZeroExt8to32 x) (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0])
+(Rsh8Ux8  x y) => (SRL (ZeroExt8to32 x) (ZeroExt8to32 y))
+
+(Rsh32x32 x y) => (SRAcond x y (CMPconst [256] y))
+(Rsh32x16 x y) => (SRAcond x (ZeroExt16to32 y) (CMPconst [256] (ZeroExt16to32 y)))
+(Rsh32x8  x y) => (SRA x (ZeroExt8to32 y))
+
+(Rsh16x32 x y) => (SRAcond (SignExt16to32 x) y (CMPconst [256] y))
+(Rsh16x16 x y) => (SRAcond (SignExt16to32 x) (ZeroExt16to32 y) (CMPconst [256] (ZeroExt16to32 y)))
+(Rsh16x8  x y) => (SRA (SignExt16to32 x) (ZeroExt8to32 y))
+
+(Rsh8x32 x y) => (SRAcond (SignExt8to32 x) y (CMPconst [256] y))
+(Rsh8x16 x y) => (SRAcond (SignExt8to32 x) (ZeroExt16to32 y) (CMPconst [256] (ZeroExt16to32 y)))
+(Rsh8x8  x y) => (SRA (SignExt8to32 x) (ZeroExt8to32 y))
+
+// constant shifts
+// generic opt rewrites all constant shifts to shift by Const64
+(Lsh32x64 x (Const64 [c])) && uint64(c) < 32 => (SLLconst x [int32(c)])
+(Rsh32x64 x (Const64 [c])) && uint64(c) < 32 => (SRAconst x [int32(c)])
+(Rsh32Ux64 x (Const64 [c])) && uint64(c) < 32 => (SRLconst x [int32(c)])
+(Lsh16x64 x (Const64 [c])) && uint64(c) < 16 => (SLLconst x [int32(c)])
+(Rsh16x64 x (Const64 [c])) && uint64(c) < 16 => (SRAconst (SLLconst <typ.UInt32> x [16]) [int32(c+16)])
+(Rsh16Ux64 x (Const64 [c])) && uint64(c) < 16 => (SRLconst (SLLconst <typ.UInt32> x [16]) [int32(c+16)])
+(Lsh8x64 x (Const64 [c])) && uint64(c) < 8 => (SLLconst x [int32(c)])
+(Rsh8x64 x (Const64 [c])) && uint64(c) < 8 => (SRAconst (SLLconst <typ.UInt32> x [24]) [int32(c+24)])
+(Rsh8Ux64 x (Const64 [c])) && uint64(c) < 8 => (SRLconst (SLLconst <typ.UInt32> x [24]) [int32(c+24)])
+
+// large constant shifts
+(Lsh32x64 _ (Const64 [c])) && uint64(c) >= 32 => (Const32 [0])
+(Rsh32Ux64 _ (Const64 [c])) && uint64(c) >= 32 => (Const32 [0])
+(Lsh16x64 _ (Const64 [c])) && uint64(c) >= 16 => (Const16 [0])
+(Rsh16Ux64 _ (Const64 [c])) && uint64(c) >= 16 => (Const16 [0])
+(Lsh8x64 _ (Const64 [c])) && uint64(c) >= 8 => (Const8 [0])
+(Rsh8Ux64 _ (Const64 [c])) && uint64(c) >= 8 => (Const8 [0])
+
+// large constant signed right shift, we leave the sign bit
+(Rsh32x64 x (Const64 [c])) && uint64(c) >= 32 => (SRAconst x [31])
+(Rsh16x64 x (Const64 [c])) && uint64(c) >= 16 => (SRAconst (SLLconst <typ.UInt32> x [16]) [31])
+(Rsh8x64 x (Const64 [c])) && uint64(c) >= 8 => (SRAconst (SLLconst <typ.UInt32> x [24]) [31])
+
+// constants
+(Const(8|16|32) [val]) => (MOVWconst [int32(val)])
+(Const(32|64)F [val]) => (MOV(F|D)const [float64(val)])
+(ConstNil) => (MOVWconst [0])
+(ConstBool [t]) => (MOVWconst [b2i32(t)])
+
+// truncations
+// Because we ignore high parts of registers, truncates are just copies.
+(Trunc16to8 ...) => (Copy ...)
+(Trunc32to8 ...) => (Copy ...)
+(Trunc32to16 ...) => (Copy ...)
+
+// Zero-/Sign-extensions
+(ZeroExt8to16 ...) => (MOVBUreg ...)
+(ZeroExt8to32 ...) => (MOVBUreg ...)
+(ZeroExt16to32 ...) => (MOVHUreg ...)
+
+(SignExt8to16 ...) => (MOVBreg ...)
+(SignExt8to32 ...) => (MOVBreg ...)
+(SignExt16to32 ...) => (MOVHreg ...)
+
+(Signmask x) => (SRAconst x [31])
+(Zeromask x) => (SRAconst (RSBshiftRL <typ.Int32> x x [1]) [31]) // sign bit of uint32(x)>>1 - x
+(Slicemask <t> x) => (SRAconst (RSBconst <t> [0] x) [31])
+
+// float <-> int conversion
+(Cvt32to32F ...) => (MOVWF ...)
+(Cvt32to64F ...) => (MOVWD ...)
+(Cvt32Uto32F ...) => (MOVWUF ...)
+(Cvt32Uto64F ...) => (MOVWUD ...)
+(Cvt32Fto32 ...) => (MOVFW ...)
+(Cvt64Fto32 ...) => (MOVDW ...)
+(Cvt32Fto32U ...) => (MOVFWU ...)
+(Cvt64Fto32U ...) => (MOVDWU ...)
+(Cvt32Fto64F ...) => (MOVFD ...)
+(Cvt64Fto32F ...) => (MOVDF ...)
+
+(Round(32|64)F ...) => (Copy ...)
+
+(CvtBoolToUint8 ...) => (Copy ...)
+
+// fused-multiply-add
+(FMA x y z) => (FMULAD z x y)
+
+// comparisons
+(Eq8 x y)  => (Equal (CMP (ZeroExt8to32 x) (ZeroExt8to32 y)))
+(Eq16 x y) => (Equal (CMP (ZeroExt16to32 x) (ZeroExt16to32 y)))
+(Eq32 x y) => (Equal (CMP x y))
+(EqPtr x y) => (Equal (CMP x y))
+(Eq(32|64)F x y) => (Equal (CMP(F|D) x y))
+
+(Neq8 x y)  => (NotEqual (CMP (ZeroExt8to32 x) (ZeroExt8to32 y)))
+(Neq16 x y) => (NotEqual (CMP (ZeroExt16to32 x) (ZeroExt16to32 y)))
+(Neq32 x y) => (NotEqual (CMP x y))
+(NeqPtr x y) => (NotEqual (CMP x y))
+(Neq(32|64)F x y) => (NotEqual (CMP(F|D) x y))
+
+(Less8 x y)  => (LessThan (CMP (SignExt8to32 x) (SignExt8to32 y)))
+(Less16 x y) => (LessThan (CMP (SignExt16to32 x) (SignExt16to32 y)))
+(Less32 x y) => (LessThan (CMP x y))
+(Less(32|64)F x y) => (GreaterThan (CMP(F|D) y x)) // reverse operands to work around NaN
+
+(Less8U x y)  => (LessThanU (CMP (ZeroExt8to32 x) (ZeroExt8to32 y)))
+(Less16U x y) => (LessThanU (CMP (ZeroExt16to32 x) (ZeroExt16to32 y)))
+(Less32U x y) => (LessThanU (CMP x y))
+
+(Leq8 x y)  => (LessEqual (CMP (SignExt8to32 x) (SignExt8to32 y)))
+(Leq16 x y) => (LessEqual (CMP (SignExt16to32 x) (SignExt16to32 y)))
+(Leq32 x y) => (LessEqual (CMP x y))
+(Leq(32|64)F x y) => (GreaterEqual (CMP(F|D) y x)) // reverse operands to work around NaN
+
+(Leq8U x y)  => (LessEqualU (CMP (ZeroExt8to32 x) (ZeroExt8to32 y)))
+(Leq16U x y) => (LessEqualU (CMP (ZeroExt16to32 x) (ZeroExt16to32 y)))
+(Leq32U x y) => (LessEqualU (CMP x y))
+
+(OffPtr [off] ptr:(SP)) => (MOVWaddr [int32(off)] ptr)
+(OffPtr [off] ptr) => (ADDconst [int32(off)] ptr)
+
+(Addr {sym} base) => (MOVWaddr {sym} base)
+(LocalAddr {sym} base _) => (MOVWaddr {sym} base)
+
+// loads
+(Load <t> ptr mem) && t.IsBoolean() => (MOVBUload ptr mem)
+(Load <t> ptr mem) && (is8BitInt(t) && isSigned(t)) => (MOVBload ptr mem)
+(Load <t> ptr mem) && (is8BitInt(t) && !isSigned(t)) => (MOVBUload ptr mem)
+(Load <t> ptr mem) && (is16BitInt(t) && isSigned(t)) => (MOVHload ptr mem)
+(Load <t> ptr mem) && (is16BitInt(t) && !isSigned(t)) => (MOVHUload ptr mem)
+(Load <t> ptr mem) && (is32BitInt(t) || isPtr(t)) => (MOVWload ptr mem)
+(Load <t> ptr mem) && is32BitFloat(t) => (MOVFload ptr mem)
+(Load <t> ptr mem) && is64BitFloat(t) => (MOVDload ptr mem)
+
+// stores
+(Store {t} ptr val mem) && t.Size() == 1 => (MOVBstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 2 => (MOVHstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 4 && !is32BitFloat(val.Type) => (MOVWstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 4 && is32BitFloat(val.Type) => (MOVFstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 8 && is64BitFloat(val.Type) => (MOVDstore ptr val mem)
+
+// zero instructions
+(Zero [0] _ mem) => mem
+(Zero [1] ptr mem) => (MOVBstore ptr (MOVWconst [0]) mem)
+(Zero [2] {t} ptr mem) && t.Alignment()%2 == 0 =>
+	(MOVHstore ptr (MOVWconst [0]) mem)
+(Zero [2] ptr mem) =>
+	(MOVBstore [1] ptr (MOVWconst [0])
+		(MOVBstore [0] ptr (MOVWconst [0]) mem))
+(Zero [4] {t} ptr mem) && t.Alignment()%4 == 0 =>
+	(MOVWstore ptr (MOVWconst [0]) mem)
+(Zero [4] {t} ptr mem) && t.Alignment()%2 == 0 =>
+	(MOVHstore [2] ptr (MOVWconst [0])
+		(MOVHstore [0] ptr (MOVWconst [0]) mem))
+(Zero [4] ptr mem) =>
+	(MOVBstore [3] ptr (MOVWconst [0])
+		(MOVBstore [2] ptr (MOVWconst [0])
+			(MOVBstore [1] ptr (MOVWconst [0])
+				(MOVBstore [0] ptr (MOVWconst [0]) mem))))
+
+(Zero [3] ptr mem) =>
+	(MOVBstore [2] ptr (MOVWconst [0])
+		(MOVBstore [1] ptr (MOVWconst [0])
+			(MOVBstore [0] ptr (MOVWconst [0]) mem)))
+
+// Medium zeroing uses a duff device
+// 4 and 128 are magic constants, see runtime/mkduff.go
+(Zero [s] {t} ptr mem)
+	&& s%4 == 0 && s > 4 && s <= 512
+	&& t.Alignment()%4 == 0 && !config.noDuffDevice =>
+	(DUFFZERO [4 * (128 - s/4)] ptr (MOVWconst [0]) mem)
+
+// Large zeroing uses a loop
+(Zero [s] {t} ptr mem)
+	&& (s > 512 || config.noDuffDevice) || t.Alignment()%4 != 0 =>
+	(LoweredZero [t.Alignment()]
+		ptr
+		(ADDconst <ptr.Type> ptr [int32(s-moveSize(t.Alignment(), config))])
+		(MOVWconst [0])
+		mem)
+
+// moves
+(Move [0] _ _ mem) => mem
+(Move [1] dst src mem) => (MOVBstore dst (MOVBUload src mem) mem)
+(Move [2] {t} dst src mem) && t.Alignment()%2 == 0 =>
+	(MOVHstore dst (MOVHUload src mem) mem)
+(Move [2] dst src mem) =>
+	(MOVBstore [1] dst (MOVBUload [1] src mem)
+		(MOVBstore dst (MOVBUload src mem) mem))
+(Move [4] {t} dst src mem) && t.Alignment()%4 == 0 =>
+	(MOVWstore dst (MOVWload src mem) mem)
+(Move [4] {t} dst src mem) && t.Alignment()%2 == 0 =>
+	(MOVHstore [2] dst (MOVHUload [2] src mem)
+		(MOVHstore dst (MOVHUload src mem) mem))
+(Move [4] dst src mem) =>
+	(MOVBstore [3] dst (MOVBUload [3] src mem)
+		(MOVBstore [2] dst (MOVBUload [2] src mem)
+			(MOVBstore [1] dst (MOVBUload [1] src mem)
+				(MOVBstore dst (MOVBUload src mem) mem))))
+
+(Move [3] dst src mem) =>
+	(MOVBstore [2] dst (MOVBUload [2] src mem)
+		(MOVBstore [1] dst (MOVBUload [1] src mem)
+			(MOVBstore dst (MOVBUload src mem) mem)))
+
+// Medium move uses a duff device
+// 8 and 128 are magic constants, see runtime/mkduff.go
+(Move [s] {t} dst src mem)
+	&& s%4 == 0 && s > 4 && s <= 512
+	&& t.Alignment()%4 == 0 && !config.noDuffDevice && logLargeCopy(v, s) =>
+	(DUFFCOPY [8 * (128 - s/4)] dst src mem)
+
+// Large move uses a loop
+(Move [s] {t} dst src mem)
+	&& ((s > 512 || config.noDuffDevice) || t.Alignment()%4 != 0) && logLargeCopy(v, s) =>
+	(LoweredMove [t.Alignment()]
+		dst
+		src
+		(ADDconst <src.Type> src [int32(s-moveSize(t.Alignment(), config))])
+		mem)
+
+// calls
+(StaticCall ...) => (CALLstatic ...)
+(ClosureCall ...) => (CALLclosure ...)
+(InterCall ...) => (CALLinter ...)
+(TailCall ...) => (CALLtail ...)
+
+// checks
+(NilCheck ...) => (LoweredNilCheck ...)
+(IsNonNil ptr) => (NotEqual (CMPconst [0] ptr))
+(IsInBounds idx len) => (LessThanU (CMP idx len))
+(IsSliceInBounds idx len) => (LessEqualU (CMP idx len))
+
+// pseudo-ops
+(GetClosurePtr ...) => (LoweredGetClosurePtr ...)
+(GetCallerSP ...) => (LoweredGetCallerSP ...)
+(GetCallerPC ...) => (LoweredGetCallerPC ...)
+
+// Absorb pseudo-ops into blocks.
+(If (Equal cc) yes no) => (EQ cc yes no)
+(If (NotEqual cc) yes no) => (NE cc yes no)
+(If (LessThan cc) yes no) => (LT cc yes no)
+(If (LessThanU cc) yes no) => (ULT cc yes no)
+(If (LessEqual cc) yes no) => (LE cc yes no)
+(If (LessEqualU cc) yes no) => (ULE cc yes no)
+(If (GreaterThan cc) yes no) => (GT cc yes no)
+(If (GreaterThanU cc) yes no) => (UGT cc yes no)
+(If (GreaterEqual cc) yes no) => (GE cc yes no)
+(If (GreaterEqualU cc) yes no) => (UGE cc yes no)
+
+(If cond yes no) => (NE (CMPconst [0] cond) yes no)
+
+// Absorb boolean tests into block
+(NE (CMPconst [0] (Equal cc)) yes no) => (EQ cc yes no)
+(NE (CMPconst [0] (NotEqual cc)) yes no) => (NE cc yes no)
+(NE (CMPconst [0] (LessThan cc)) yes no) => (LT cc yes no)
+(NE (CMPconst [0] (LessThanU cc)) yes no) => (ULT cc yes no)
+(NE (CMPconst [0] (LessEqual cc)) yes no) => (LE cc yes no)
+(NE (CMPconst [0] (LessEqualU cc)) yes no) => (ULE cc yes no)
+(NE (CMPconst [0] (GreaterThan cc)) yes no) => (GT cc yes no)
+(NE (CMPconst [0] (GreaterThanU cc)) yes no) => (UGT cc yes no)
+(NE (CMPconst [0] (GreaterEqual cc)) yes no) => (GE cc yes no)
+(NE (CMPconst [0] (GreaterEqualU cc)) yes no) => (UGE cc yes no)
+
+// Write barrier.
+(WB ...) => (LoweredWB ...)
+
+(PanicBounds [kind] x y mem) && boundsABI(kind) == 0 => (LoweredPanicBoundsA [kind] x y mem)
+(PanicBounds [kind] x y mem) && boundsABI(kind) == 1 => (LoweredPanicBoundsB [kind] x y mem)
+(PanicBounds [kind] x y mem) && boundsABI(kind) == 2 => (LoweredPanicBoundsC [kind] x y mem)
+
+(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 0 => (LoweredPanicExtendA [kind] hi lo y mem)
+(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 1 => (LoweredPanicExtendB [kind] hi lo y mem)
+(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 2 => (LoweredPanicExtendC [kind] hi lo y mem)
+
+// Optimizations
+
+// fold offset into address
+(ADDconst [off1] (MOVWaddr [off2] {sym} ptr)) => (MOVWaddr [off1+off2] {sym} ptr)
+(SUBconst [off1] (MOVWaddr [off2] {sym} ptr)) => (MOVWaddr [off2-off1] {sym} ptr)
+
+// fold address into load/store
+(MOVBload [off1] {sym} (ADDconst [off2] ptr) mem) => (MOVBload [off1+off2] {sym} ptr mem)
+(MOVBload [off1] {sym} (SUBconst [off2] ptr) mem) => (MOVBload [off1-off2] {sym} ptr mem)
+(MOVBUload [off1] {sym} (ADDconst [off2] ptr) mem) => (MOVBUload [off1+off2] {sym} ptr mem)
+(MOVBUload [off1] {sym} (SUBconst [off2] ptr) mem) => (MOVBUload [off1-off2] {sym} ptr mem)
+(MOVHload [off1] {sym} (ADDconst [off2] ptr) mem) => (MOVHload [off1+off2] {sym} ptr mem)
+(MOVHload [off1] {sym} (SUBconst [off2] ptr) mem) => (MOVHload [off1-off2] {sym} ptr mem)
+(MOVHUload [off1] {sym} (ADDconst [off2] ptr) mem) => (MOVHUload [off1+off2] {sym} ptr mem)
+(MOVHUload [off1] {sym} (SUBconst [off2] ptr) mem) => (MOVHUload [off1-off2] {sym} ptr mem)
+(MOVWload [off1] {sym} (ADDconst [off2] ptr) mem) => (MOVWload [off1+off2] {sym} ptr mem)
+(MOVWload [off1] {sym} (SUBconst [off2] ptr) mem) => (MOVWload [off1-off2] {sym} ptr mem)
+(MOVFload [off1] {sym} (ADDconst [off2] ptr) mem) => (MOVFload [off1+off2] {sym} ptr mem)
+(MOVFload [off1] {sym} (SUBconst [off2] ptr) mem) => (MOVFload [off1-off2] {sym} ptr mem)
+(MOVDload [off1] {sym} (ADDconst [off2] ptr) mem) => (MOVDload [off1+off2] {sym} ptr mem)
+(MOVDload [off1] {sym} (SUBconst [off2] ptr) mem) => (MOVDload [off1-off2] {sym} ptr mem)
+
+(MOVBstore [off1] {sym} (ADDconst [off2] ptr) val mem) => (MOVBstore [off1+off2] {sym} ptr val mem)
+(MOVBstore [off1] {sym} (SUBconst [off2] ptr) val mem) => (MOVBstore [off1-off2] {sym} ptr val mem)
+(MOVHstore [off1] {sym} (ADDconst [off2] ptr) val mem) => (MOVHstore [off1+off2] {sym} ptr val mem)
+(MOVHstore [off1] {sym} (SUBconst [off2] ptr) val mem) => (MOVHstore [off1-off2] {sym} ptr val mem)
+(MOVWstore [off1] {sym} (ADDconst [off2] ptr) val mem) => (MOVWstore [off1+off2] {sym} ptr val mem)
+(MOVWstore [off1] {sym} (SUBconst [off2] ptr) val mem) => (MOVWstore [off1-off2] {sym} ptr val mem)
+(MOVFstore [off1] {sym} (ADDconst [off2] ptr) val mem) => (MOVFstore [off1+off2] {sym} ptr val mem)
+(MOVFstore [off1] {sym} (SUBconst [off2] ptr) val mem) => (MOVFstore [off1-off2] {sym} ptr val mem)
+(MOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem) => (MOVDstore [off1+off2] {sym} ptr val mem)
+(MOVDstore [off1] {sym} (SUBconst [off2] ptr) val mem) => (MOVDstore [off1-off2] {sym} ptr val mem)
+
+(MOVBload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) =>
+	(MOVBload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+(MOVBUload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) =>
+	(MOVBUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+(MOVHload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) =>
+	(MOVHload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+(MOVHUload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) =>
+	(MOVHUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+(MOVWload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) =>
+	(MOVWload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+(MOVFload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) =>
+	(MOVFload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+(MOVDload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) =>
+	(MOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+
+(MOVBstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) =>
+	(MOVBstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
+(MOVHstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) =>
+	(MOVHstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
+(MOVWstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) =>
+	(MOVWstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
+(MOVFstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) =>
+	(MOVFstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
+(MOVDstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) =>
+	(MOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
+
+// replace load from same location as preceding store with zero/sign extension (or copy in case of full width)
+(MOVBload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVBreg x)
+(MOVBUload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVBUreg x)
+(MOVHload [off] {sym} ptr (MOVHstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVHreg x)
+(MOVHUload [off] {sym} ptr (MOVHstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVHUreg x)
+(MOVWload [off] {sym} ptr (MOVWstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => x
+
+(MOVFload [off] {sym} ptr (MOVFstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => x
+(MOVDload [off] {sym} ptr (MOVDstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => x
+
+(MOVWloadidx ptr idx (MOVWstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) => x
+(MOVWloadshiftLL ptr idx [c] (MOVWstoreshiftLL ptr2 idx [d] x _)) && c==d && isSamePtr(ptr, ptr2) => x
+(MOVWloadshiftRL ptr idx [c] (MOVWstoreshiftRL ptr2 idx [d] x _)) && c==d && isSamePtr(ptr, ptr2) => x
+(MOVWloadshiftRA ptr idx [c] (MOVWstoreshiftRA ptr2 idx [d] x _)) && c==d && isSamePtr(ptr, ptr2) => x
+(MOVBUloadidx ptr idx (MOVBstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) => (MOVBUreg x)
+(MOVBloadidx ptr idx (MOVBstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) => (MOVBreg x)
+(MOVHUloadidx ptr idx (MOVHstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) => (MOVHUreg x)
+(MOVHloadidx ptr idx (MOVHstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) => (MOVHreg x)
+
+// fold constant into arithmetic ops
+(ADD x (MOVWconst [c])) => (ADDconst [c] x)
+(SUB (MOVWconst [c]) x) => (RSBconst [c] x)
+(SUB x (MOVWconst [c])) => (SUBconst [c] x)
+(RSB (MOVWconst [c]) x) => (SUBconst [c] x)
+(RSB x (MOVWconst [c])) => (RSBconst [c] x)
+
+(ADDS x (MOVWconst [c])) => (ADDSconst [c] x)
+(SUBS x (MOVWconst [c])) => (SUBSconst [c] x)
+
+(ADC (MOVWconst [c]) x flags) => (ADCconst [c] x flags)
+(SBC (MOVWconst [c]) x flags) => (RSCconst [c] x flags)
+(SBC x (MOVWconst [c]) flags) => (SBCconst [c] x flags)
+
+(AND x (MOVWconst [c])) => (ANDconst [c] x)
+(OR  x (MOVWconst [c])) => (ORconst [c] x)
+(XOR x (MOVWconst [c])) => (XORconst [c] x)
+(BIC x (MOVWconst [c])) => (BICconst [c] x)
+
+(SLL x (MOVWconst [c])) && 0 <= c && c < 32 => (SLLconst x [c])
+(SRL x (MOVWconst [c])) && 0 <= c && c < 32 => (SRLconst x [c])
+(SRA x (MOVWconst [c])) && 0 <= c && c < 32 => (SRAconst x [c])
+
+(CMP x (MOVWconst [c])) => (CMPconst [c] x)
+(CMP (MOVWconst [c]) x) => (InvertFlags (CMPconst [c] x))
+(CMN x (MOVWconst [c])) => (CMNconst [c] x)
+(TST x (MOVWconst [c])) => (TSTconst [c] x)
+(TEQ x (MOVWconst [c])) => (TEQconst [c] x)
+
+(SRR x (MOVWconst [c])) => (SRRconst x [c&31])
+
+// Canonicalize the order of arguments to comparisons - helps with CSE.
+(CMP x y) && canonLessThan(x,y) => (InvertFlags (CMP y x))
+
+// don't extend after proper load
+// MOVWreg instruction is not emitted if src and dst registers are same, but it ensures the type.
+(MOVBreg x:(MOVBload _ _)) => (MOVWreg x)
+(MOVBUreg x:(MOVBUload _ _)) => (MOVWreg x)
+(MOVHreg x:(MOVBload _ _)) => (MOVWreg x)
+(MOVHreg x:(MOVBUload _ _)) => (MOVWreg x)
+(MOVHreg x:(MOVHload _ _)) => (MOVWreg x)
+(MOVHUreg x:(MOVBUload _ _)) => (MOVWreg x)
+(MOVHUreg x:(MOVHUload _ _)) => (MOVWreg x)
+
+// fold extensions and ANDs together
+(MOVBUreg (ANDconst [c] x)) => (ANDconst [c&0xff] x)
+(MOVHUreg (ANDconst [c] x)) => (ANDconst [c&0xffff] x)
+(MOVBreg (ANDconst [c] x)) && c & 0x80 == 0 => (ANDconst [c&0x7f] x)
+(MOVHreg (ANDconst [c] x)) && c & 0x8000 == 0 => (ANDconst [c&0x7fff] x)
+
+// fold double extensions
+(MOVBreg x:(MOVBreg _)) => (MOVWreg x)
+(MOVBUreg x:(MOVBUreg _)) => (MOVWreg x)
+(MOVHreg x:(MOVBreg _)) => (MOVWreg x)
+(MOVHreg x:(MOVBUreg _)) => (MOVWreg x)
+(MOVHreg x:(MOVHreg _)) => (MOVWreg x)
+(MOVHUreg x:(MOVBUreg _)) => (MOVWreg x)
+(MOVHUreg x:(MOVHUreg _)) => (MOVWreg x)
+
+// don't extend before store
+(MOVBstore [off] {sym} ptr (MOVBreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr (MOVBUreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr (MOVHreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr (MOVHUreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
+(MOVHstore [off] {sym} ptr (MOVHreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
+(MOVHstore [off] {sym} ptr (MOVHUreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
+
+// if a register move has only 1 use, just use the same register without emitting instruction
+// MOVWnop doesn't emit instruction, only for ensuring the type.
+(MOVWreg x) && x.Uses == 1 => (MOVWnop x)
+
+// TODO: we should be able to get rid of MOVWnop all together.
+// But for now, this is enough to get rid of lots of them.
+(MOVWnop (MOVWconst [c])) => (MOVWconst [c])
+
+// mul by constant
+(MUL x (MOVWconst [c])) && int32(c) == -1 => (RSBconst [0] x)
+(MUL _ (MOVWconst [0])) => (MOVWconst [0])
+(MUL x (MOVWconst [1])) => x
+(MUL x (MOVWconst [c])) && isPowerOfTwo32(c) => (SLLconst [int32(log32(c))] x)
+(MUL x (MOVWconst [c])) && isPowerOfTwo32(c-1) && c >= 3 => (ADDshiftLL x x [int32(log32(c-1))])
+(MUL x (MOVWconst [c])) && isPowerOfTwo32(c+1) && c >= 7 => (RSBshiftLL x x [int32(log32(c+1))])
+(MUL x (MOVWconst [c])) && c%3 == 0 && isPowerOfTwo32(c/3) => (SLLconst [int32(log32(c/3))] (ADDshiftLL <x.Type> x x [1]))
+(MUL x (MOVWconst [c])) && c%5 == 0 && isPowerOfTwo32(c/5) => (SLLconst [int32(log32(c/5))] (ADDshiftLL <x.Type> x x [2]))
+(MUL x (MOVWconst [c])) && c%7 == 0 && isPowerOfTwo32(c/7) => (SLLconst [int32(log32(c/7))] (RSBshiftLL <x.Type> x x [3]))
+(MUL x (MOVWconst [c])) && c%9 == 0 && isPowerOfTwo32(c/9) => (SLLconst [int32(log32(c/9))] (ADDshiftLL <x.Type> x x [3]))
+
+(MULA x (MOVWconst [c]) a) && c == -1 => (SUB a x)
+(MULA _ (MOVWconst [0]) a) => a
+(MULA x (MOVWconst [1]) a) => (ADD x a)
+(MULA x (MOVWconst [c]) a) && isPowerOfTwo32(c) => (ADD (SLLconst <x.Type> [int32(log32(c))] x) a)
+(MULA x (MOVWconst [c]) a) && isPowerOfTwo32(c-1) && c >= 3 => (ADD (ADDshiftLL <x.Type> x x [int32(log32(c-1))]) a)
+(MULA x (MOVWconst [c]) a) && isPowerOfTwo32(c+1) && c >= 7 => (ADD (RSBshiftLL <x.Type> x x [int32(log32(c+1))]) a)
+(MULA x (MOVWconst [c]) a) && c%3 == 0 && isPowerOfTwo32(c/3) => (ADD (SLLconst <x.Type> [int32(log32(c/3))] (ADDshiftLL <x.Type> x x [1])) a)
+(MULA x (MOVWconst [c]) a) && c%5 == 0 && isPowerOfTwo32(c/5) => (ADD (SLLconst <x.Type> [int32(log32(c/5))] (ADDshiftLL <x.Type> x x [2])) a)
+(MULA x (MOVWconst [c]) a) && c%7 == 0 && isPowerOfTwo32(c/7) => (ADD (SLLconst <x.Type> [int32(log32(c/7))] (RSBshiftLL <x.Type> x x [3])) a)
+(MULA x (MOVWconst [c]) a) && c%9 == 0 && isPowerOfTwo32(c/9) => (ADD (SLLconst <x.Type> [int32(log32(c/9))] (ADDshiftLL <x.Type> x x [3])) a)
+
+(MULA (MOVWconst [c]) x a) && c == -1 => (SUB a x)
+(MULA (MOVWconst [0]) _ a) => a
+(MULA (MOVWconst [1]) x a) => (ADD x a)
+(MULA (MOVWconst [c]) x a) && isPowerOfTwo32(c) => (ADD (SLLconst <x.Type> [int32(log32(c))] x) a)
+(MULA (MOVWconst [c]) x a) && isPowerOfTwo32(c-1) && c >= 3 => (ADD (ADDshiftLL <x.Type> x x [int32(log32(c-1))]) a)
+(MULA (MOVWconst [c]) x a) && isPowerOfTwo32(c+1) && c >= 7 => (ADD (RSBshiftLL <x.Type> x x [int32(log32(c+1))]) a)
+(MULA (MOVWconst [c]) x a) && c%3 == 0 && isPowerOfTwo32(c/3) => (ADD (SLLconst <x.Type> [int32(log32(c/3))] (ADDshiftLL <x.Type> x x [1])) a)
+(MULA (MOVWconst [c]) x a) && c%5 == 0 && isPowerOfTwo32(c/5) => (ADD (SLLconst <x.Type> [int32(log32(c/5))] (ADDshiftLL <x.Type> x x [2])) a)
+(MULA (MOVWconst [c]) x a) && c%7 == 0 && isPowerOfTwo32(c/7) => (ADD (SLLconst <x.Type> [int32(log32(c/7))] (RSBshiftLL <x.Type> x x [3])) a)
+(MULA (MOVWconst [c]) x a) && c%9 == 0 && isPowerOfTwo32(c/9) => (ADD (SLLconst <x.Type> [int32(log32(c/9))] (ADDshiftLL <x.Type> x x [3])) a)
+
+(MULS x (MOVWconst [c]) a) && c == -1 => (ADD a x)
+(MULS _ (MOVWconst [0]) a) => a
+(MULS x (MOVWconst [1]) a) => (RSB x a)
+(MULS x (MOVWconst [c]) a) && isPowerOfTwo32(c) => (RSB (SLLconst <x.Type> [int32(log32(c))] x) a)
+(MULS x (MOVWconst [c]) a) && isPowerOfTwo32(c-1) && c >= 3 => (RSB (ADDshiftLL <x.Type> x x [int32(log32(c-1))]) a)
+(MULS x (MOVWconst [c]) a) && isPowerOfTwo32(c+1) && c >= 7 => (RSB (RSBshiftLL <x.Type> x x [int32(log32(c+1))]) a)
+(MULS x (MOVWconst [c]) a) && c%3 == 0 && isPowerOfTwo32(c/3) => (RSB (SLLconst <x.Type> [int32(log32(c/3))] (ADDshiftLL <x.Type> x x [1])) a)
+(MULS x (MOVWconst [c]) a) && c%5 == 0 && isPowerOfTwo32(c/5) => (RSB (SLLconst <x.Type> [int32(log32(c/5))] (ADDshiftLL <x.Type> x x [2])) a)
+(MULS x (MOVWconst [c]) a) && c%7 == 0 && isPowerOfTwo32(c/7) => (RSB (SLLconst <x.Type> [int32(log32(c/7))] (RSBshiftLL <x.Type> x x [3])) a)
+(MULS x (MOVWconst [c]) a) && c%9 == 0 && isPowerOfTwo32(c/9) => (RSB (SLLconst <x.Type> [int32(log32(c/9))] (ADDshiftLL <x.Type> x x [3])) a)
+
+(MULS (MOVWconst [c]) x a) && c == -1 => (ADD a x)
+(MULS (MOVWconst [0]) _ a) => a
+(MULS (MOVWconst [1]) x a) => (RSB x a)
+(MULS (MOVWconst [c]) x a) && isPowerOfTwo32(c) => (RSB (SLLconst <x.Type> [int32(log32(c))] x) a)
+(MULS (MOVWconst [c]) x a) && isPowerOfTwo32(c-1) && c >= 3 => (RSB (ADDshiftLL <x.Type> x x [int32(log32(c-1))]) a)
+(MULS (MOVWconst [c]) x a) && isPowerOfTwo32(c+1) && c >= 7 => (RSB (RSBshiftLL <x.Type> x x [int32(log32(c+1))]) a)
+(MULS (MOVWconst [c]) x a) && c%3 == 0 && isPowerOfTwo32(c/3) => (RSB (SLLconst <x.Type> [int32(log32(c/3))] (ADDshiftLL <x.Type> x x [1])) a)
+(MULS (MOVWconst [c]) x a) && c%5 == 0 && isPowerOfTwo32(c/5) => (RSB (SLLconst <x.Type> [int32(log32(c/5))] (ADDshiftLL <x.Type> x x [2])) a)
+(MULS (MOVWconst [c]) x a) && c%7 == 0 && isPowerOfTwo32(c/7) => (RSB (SLLconst <x.Type> [int32(log32(c/7))] (RSBshiftLL <x.Type> x x [3])) a)
+(MULS (MOVWconst [c]) x a) && c%9 == 0 && isPowerOfTwo32(c/9) => (RSB (SLLconst <x.Type> [int32(log32(c/9))] (ADDshiftLL <x.Type> x x [3])) a)
+
+// div by constant
+(Select0 (CALLudiv x (MOVWconst [1]))) => x
+(Select1 (CALLudiv _ (MOVWconst [1]))) => (MOVWconst [0])
+(Select0 (CALLudiv x (MOVWconst [c]))) && isPowerOfTwo32(c) => (SRLconst [int32(log32(c))] x)
+(Select1 (CALLudiv x (MOVWconst [c]))) && isPowerOfTwo32(c) => (ANDconst [c-1] x)
+
+// constant comparisons
+(CMPconst (MOVWconst [x]) [y]) => (FlagConstant [subFlags32(x,y)])
+(CMNconst (MOVWconst [x]) [y]) => (FlagConstant [addFlags32(x,y)])
+(TSTconst (MOVWconst [x]) [y]) => (FlagConstant [logicFlags32(x&y)])
+(TEQconst (MOVWconst [x]) [y]) => (FlagConstant [logicFlags32(x^y)])
+
+// other known comparisons
+(CMPconst (MOVBUreg _) [c]) && 0xff < c => (FlagConstant [subFlags32(0, 1)])
+(CMPconst (MOVHUreg _) [c]) && 0xffff < c => (FlagConstant [subFlags32(0, 1)])
+(CMPconst (ANDconst _ [m]) [n]) && 0 <= m && m < n => (FlagConstant [subFlags32(0, 1)])
+(CMPconst (SRLconst _ [c]) [n]) && 0 <= n && 0 < c && c <= 32 && (1<<uint32(32-c)) <= uint32(n) => (FlagConstant [subFlags32(0, 1)])
+
+// absorb flag constants into branches
+(EQ (FlagConstant [fc]) yes no) &&  fc.eq() => (First yes no)
+(EQ (FlagConstant [fc]) yes no) && !fc.eq() => (First no yes)
+
+(NE (FlagConstant [fc]) yes no) &&  fc.ne() => (First yes no)
+(NE (FlagConstant [fc]) yes no) && !fc.ne() => (First no yes)
+
+(LT (FlagConstant [fc]) yes no) &&  fc.lt() => (First yes no)
+(LT (FlagConstant [fc]) yes no) && !fc.lt() => (First no yes)
+
+(LE (FlagConstant [fc]) yes no) &&  fc.le() => (First yes no)
+(LE (FlagConstant [fc]) yes no) && !fc.le() => (First no yes)
+
+(GT (FlagConstant [fc]) yes no) &&  fc.gt() => (First yes no)
+(GT (FlagConstant [fc]) yes no) && !fc.gt() => (First no yes)
+
+(GE (FlagConstant [fc]) yes no) &&  fc.ge() => (First yes no)
+(GE (FlagConstant [fc]) yes no) && !fc.ge() => (First no yes)
+
+(ULT (FlagConstant [fc]) yes no) &&  fc.ult() => (First yes no)
+(ULT (FlagConstant [fc]) yes no) && !fc.ult() => (First no yes)
+
+(ULE (FlagConstant [fc]) yes no) &&  fc.ule() => (First yes no)
+(ULE (FlagConstant [fc]) yes no) && !fc.ule() => (First no yes)
+
+(UGT (FlagConstant [fc]) yes no) &&  fc.ugt() => (First yes no)
+(UGT (FlagConstant [fc]) yes no) && !fc.ugt() => (First no yes)
+
+(UGE (FlagConstant [fc]) yes no) &&  fc.uge() => (First yes no)
+(UGE (FlagConstant [fc]) yes no) && !fc.uge() => (First no yes)
+
+(LTnoov (FlagConstant [fc]) yes no) &&  fc.ltNoov() => (First yes no)
+(LTnoov (FlagConstant [fc]) yes no) && !fc.ltNoov() => (First no yes)
+
+(LEnoov (FlagConstant [fc]) yes no) &&  fc.leNoov() => (First yes no)
+(LEnoov (FlagConstant [fc]) yes no) && !fc.leNoov() => (First no yes)
+
+(GTnoov (FlagConstant [fc]) yes no) &&  fc.gtNoov() => (First yes no)
+(GTnoov (FlagConstant [fc]) yes no) && !fc.gtNoov() => (First no yes)
+
+(GEnoov (FlagConstant [fc]) yes no) &&  fc.geNoov() => (First yes no)
+(GEnoov (FlagConstant [fc]) yes no) && !fc.geNoov() => (First no yes)
+
+// absorb InvertFlags into branches
+(LT (InvertFlags cmp) yes no) => (GT cmp yes no)
+(GT (InvertFlags cmp) yes no) => (LT cmp yes no)
+(LE (InvertFlags cmp) yes no) => (GE cmp yes no)
+(GE (InvertFlags cmp) yes no) => (LE cmp yes no)
+(ULT (InvertFlags cmp) yes no) => (UGT cmp yes no)
+(UGT (InvertFlags cmp) yes no) => (ULT cmp yes no)
+(ULE (InvertFlags cmp) yes no) => (UGE cmp yes no)
+(UGE (InvertFlags cmp) yes no) => (ULE cmp yes no)
+(EQ (InvertFlags cmp) yes no) => (EQ cmp yes no)
+(NE (InvertFlags cmp) yes no) => (NE cmp yes no)
+(LTnoov (InvertFlags cmp) yes no) => (GTnoov cmp yes no)
+(GEnoov (InvertFlags cmp) yes no) => (LEnoov cmp yes no)
+(LEnoov (InvertFlags cmp) yes no) => (GEnoov cmp yes no)
+(GTnoov (InvertFlags cmp) yes no) => (LTnoov cmp yes no)
+
+// absorb flag constants into boolean values
+(Equal (FlagConstant [fc])) => (MOVWconst [b2i32(fc.eq())])
+(NotEqual (FlagConstant [fc])) => (MOVWconst [b2i32(fc.ne())])
+(LessThan (FlagConstant [fc])) => (MOVWconst [b2i32(fc.lt())])
+(LessThanU (FlagConstant [fc])) => (MOVWconst [b2i32(fc.ult())])
+(LessEqual (FlagConstant [fc])) => (MOVWconst [b2i32(fc.le())])
+(LessEqualU (FlagConstant [fc])) => (MOVWconst [b2i32(fc.ule())])
+(GreaterThan (FlagConstant [fc])) => (MOVWconst [b2i32(fc.gt())])
+(GreaterThanU (FlagConstant [fc])) => (MOVWconst [b2i32(fc.ugt())])
+(GreaterEqual (FlagConstant [fc])) => (MOVWconst [b2i32(fc.ge())])
+(GreaterEqualU (FlagConstant [fc])) => (MOVWconst [b2i32(fc.uge())])
+
+// absorb InvertFlags into boolean values
+(Equal (InvertFlags x)) => (Equal x)
+(NotEqual (InvertFlags x)) => (NotEqual x)
+(LessThan (InvertFlags x)) => (GreaterThan x)
+(LessThanU (InvertFlags x)) => (GreaterThanU x)
+(GreaterThan (InvertFlags x)) => (LessThan x)
+(GreaterThanU (InvertFlags x)) => (LessThanU x)
+(LessEqual (InvertFlags x)) => (GreaterEqual x)
+(LessEqualU (InvertFlags x)) => (GreaterEqualU x)
+(GreaterEqual (InvertFlags x)) => (LessEqual x)
+(GreaterEqualU (InvertFlags x)) => (LessEqualU x)
+
+// absorb flag constants into conditional instructions
+(CMOVWLSconst _ (FlagConstant [fc]) [c]) && fc.ule() => (MOVWconst [c])
+(CMOVWLSconst x (FlagConstant [fc]) [c]) && fc.ugt() => x
+
+(CMOVWHSconst _ (FlagConstant [fc]) [c]) && fc.uge() => (MOVWconst [c])
+(CMOVWHSconst x (FlagConstant [fc]) [c]) && fc.ult() => x
+
+(CMOVWLSconst x (InvertFlags flags) [c]) => (CMOVWHSconst x flags [c])
+(CMOVWHSconst x (InvertFlags flags) [c]) => (CMOVWLSconst x flags [c])
+
+(SRAcond x _ (FlagConstant [fc])) && fc.uge() => (SRAconst x [31])
+(SRAcond x y (FlagConstant [fc])) && fc.ult() => (SRA x y)
+
+// remove redundant *const ops
+(ADDconst [0] x) => x
+(SUBconst [0] x) => x
+(ANDconst [0] _) => (MOVWconst [0])
+(ANDconst [c] x) && int32(c)==-1 => x
+(ORconst [0] x) => x
+(ORconst [c] _) && int32(c)==-1 => (MOVWconst [-1])
+(XORconst [0] x) => x
+(BICconst [0] x) => x
+(BICconst [c] _) && int32(c)==-1 => (MOVWconst [0])
+
+// generic constant folding
+(ADDconst [c] x) && !isARMImmRot(uint32(c)) && isARMImmRot(uint32(-c)) => (SUBconst [-c] x)
+(SUBconst [c] x) && !isARMImmRot(uint32(c)) && isARMImmRot(uint32(-c)) => (ADDconst [-c] x)
+(ANDconst [c] x) && !isARMImmRot(uint32(c)) && isARMImmRot(^uint32(c)) => (BICconst [int32(^uint32(c))] x)
+(BICconst [c] x) && !isARMImmRot(uint32(c)) && isARMImmRot(^uint32(c)) => (ANDconst [int32(^uint32(c))] x)
+(ADDconst [c] x) && buildcfg.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && uint32(-c)<=0xffff => (SUBconst [-c] x)
+(SUBconst [c] x) && buildcfg.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && uint32(-c)<=0xffff => (ADDconst [-c] x)
+(ANDconst [c] x) && buildcfg.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && ^uint32(c)<=0xffff => (BICconst [int32(^uint32(c))] x)
+(BICconst [c] x) && buildcfg.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && ^uint32(c)<=0xffff => (ANDconst [int32(^uint32(c))] x)
+(ADDconst [c] (MOVWconst [d])) => (MOVWconst [c+d])
+(ADDconst [c] (ADDconst [d] x)) => (ADDconst [c+d] x)
+(ADDconst [c] (SUBconst [d] x)) => (ADDconst [c-d] x)
+(ADDconst [c] (RSBconst [d] x)) => (RSBconst [c+d] x)
+(ADCconst [c] (ADDconst [d] x) flags) => (ADCconst [c+d] x flags)
+(ADCconst [c] (SUBconst [d] x) flags) => (ADCconst [c-d] x flags)
+(SUBconst [c] (MOVWconst [d])) => (MOVWconst [d-c])
+(SUBconst [c] (SUBconst [d] x)) => (ADDconst [-c-d] x)
+(SUBconst [c] (ADDconst [d] x)) => (ADDconst [-c+d] x)
+(SUBconst [c] (RSBconst [d] x)) => (RSBconst [-c+d] x)
+(SBCconst [c] (ADDconst [d] x) flags) => (SBCconst [c-d] x flags)
+(SBCconst [c] (SUBconst [d] x) flags) => (SBCconst [c+d] x flags)
+(RSBconst [c] (MOVWconst [d])) => (MOVWconst [c-d])
+(RSBconst [c] (RSBconst [d] x)) => (ADDconst [c-d] x)
+(RSBconst [c] (ADDconst [d] x)) => (RSBconst [c-d] x)
+(RSBconst [c] (SUBconst [d] x)) => (RSBconst [c+d] x)
+(RSCconst [c] (ADDconst [d] x) flags) => (RSCconst [c-d] x flags)
+(RSCconst [c] (SUBconst [d] x) flags) => (RSCconst [c+d] x flags)
+(SLLconst [c] (MOVWconst [d])) => (MOVWconst [d<<uint64(c)])
+(SRLconst [c] (MOVWconst [d])) => (MOVWconst [int32(uint32(d)>>uint64(c))])
+(SRAconst [c] (MOVWconst [d])) => (MOVWconst [d>>uint64(c)])
+(MUL (MOVWconst [c]) (MOVWconst [d])) => (MOVWconst [c*d])
+(MULA (MOVWconst [c]) (MOVWconst [d]) a) => (ADDconst [c*d] a)
+(MULS (MOVWconst [c]) (MOVWconst [d]) a) => (SUBconst [c*d] a)
+(Select0 (CALLudiv (MOVWconst [c]) (MOVWconst [d]))) && d != 0 => (MOVWconst [int32(uint32(c)/uint32(d))])
+(Select1 (CALLudiv (MOVWconst [c]) (MOVWconst [d]))) && d != 0 => (MOVWconst [int32(uint32(c)%uint32(d))])
+(ANDconst [c] (MOVWconst [d])) => (MOVWconst [c&d])
+(ANDconst [c] (ANDconst [d] x)) => (ANDconst [c&d] x)
+(ORconst [c] (MOVWconst [d])) => (MOVWconst [c|d])
+(ORconst [c] (ORconst [d] x)) => (ORconst [c|d] x)
+(XORconst [c] (MOVWconst [d])) => (MOVWconst [c^d])
+(XORconst [c] (XORconst [d] x)) => (XORconst [c^d] x)
+(BICconst [c] (MOVWconst [d])) => (MOVWconst [d&^c])
+(BICconst [c] (BICconst [d] x)) => (BICconst [c|d] x)
+(MVN (MOVWconst [c])) => (MOVWconst [^c])
+(MOVBreg (MOVWconst [c])) => (MOVWconst [int32(int8(c))])
+(MOVBUreg (MOVWconst [c])) => (MOVWconst [int32(uint8(c))])
+(MOVHreg (MOVWconst [c])) => (MOVWconst [int32(int16(c))])
+(MOVHUreg (MOVWconst [c])) => (MOVWconst [int32(uint16(c))])
+(MOVWreg (MOVWconst [c])) => (MOVWconst [c])
+// BFX: Width = c >> 8, LSB = c & 0xff, result = d << (32 - Width - LSB) >> (32 - Width)
+(BFX [c] (MOVWconst [d])) => (MOVWconst [d<<(32-uint32(c&0xff)-uint32(c>>8))>>(32-uint32(c>>8))])
+(BFXU [c] (MOVWconst [d])) => (MOVWconst [int32(uint32(d)<<(32-uint32(c&0xff)-uint32(c>>8))>>(32-uint32(c>>8)))])
+
+// absorb shifts into ops
+(ADD x (SLLconst [c] y)) => (ADDshiftLL x y [c])
+(ADD x (SRLconst [c] y)) => (ADDshiftRL x y [c])
+(ADD x (SRAconst [c] y)) => (ADDshiftRA x y [c])
+(ADD x (SLL y z)) => (ADDshiftLLreg x y z)
+(ADD x (SRL y z)) => (ADDshiftRLreg x y z)
+(ADD x (SRA y z)) => (ADDshiftRAreg x y z)
+(ADC x (SLLconst [c] y) flags) => (ADCshiftLL x y [c] flags)
+(ADC x (SRLconst [c] y) flags) => (ADCshiftRL x y [c] flags)
+(ADC x (SRAconst [c] y) flags) => (ADCshiftRA x y [c] flags)
+(ADC x (SLL y z) flags) => (ADCshiftLLreg x y z flags)
+(ADC x (SRL y z) flags) => (ADCshiftRLreg x y z flags)
+(ADC x (SRA y z) flags) => (ADCshiftRAreg x y z flags)
+(ADDS x (SLLconst [c] y)) => (ADDSshiftLL x y [c])
+(ADDS x (SRLconst [c] y)) => (ADDSshiftRL x y [c])
+(ADDS x (SRAconst [c] y)) => (ADDSshiftRA x y [c])
+(ADDS x (SLL y z)) => (ADDSshiftLLreg x y z)
+(ADDS x (SRL y z)) => (ADDSshiftRLreg x y z)
+(ADDS x (SRA y z)) => (ADDSshiftRAreg x y z)
+(SUB x (SLLconst [c] y)) => (SUBshiftLL x y [c])
+(SUB (SLLconst [c] y) x) => (RSBshiftLL x y [c])
+(SUB x (SRLconst [c] y)) => (SUBshiftRL x y [c])
+(SUB (SRLconst [c] y) x) => (RSBshiftRL x y [c])
+(SUB x (SRAconst [c] y)) => (SUBshiftRA x y [c])
+(SUB (SRAconst [c] y) x) => (RSBshiftRA x y [c])
+(SUB x (SLL y z)) => (SUBshiftLLreg x y z)
+(SUB (SLL y z) x) => (RSBshiftLLreg x y z)
+(SUB x (SRL y z)) => (SUBshiftRLreg x y z)
+(SUB (SRL y z) x) => (RSBshiftRLreg x y z)
+(SUB x (SRA y z)) => (SUBshiftRAreg x y z)
+(SUB (SRA y z) x) => (RSBshiftRAreg x y z)
+(SBC x (SLLconst [c] y) flags) => (SBCshiftLL x y [c] flags)
+(SBC (SLLconst [c] y) x flags) => (RSCshiftLL x y [c] flags)
+(SBC x (SRLconst [c] y) flags) => (SBCshiftRL x y [c] flags)
+(SBC (SRLconst [c] y) x flags) => (RSCshiftRL x y [c] flags)
+(SBC x (SRAconst [c] y) flags) => (SBCshiftRA x y [c] flags)
+(SBC (SRAconst [c] y) x flags) => (RSCshiftRA x y [c] flags)
+(SBC x (SLL y z) flags) => (SBCshiftLLreg x y z flags)
+(SBC (SLL y z) x flags) => (RSCshiftLLreg x y z flags)
+(SBC x (SRL y z) flags) => (SBCshiftRLreg x y z flags)
+(SBC (SRL y z) x flags) => (RSCshiftRLreg x y z flags)
+(SBC x (SRA y z) flags) => (SBCshiftRAreg x y z flags)
+(SBC (SRA y z) x flags) => (RSCshiftRAreg x y z flags)
+(SUBS x (SLLconst [c] y)) => (SUBSshiftLL x y [c])
+(SUBS (SLLconst [c] y) x) => (RSBSshiftLL x y [c])
+(SUBS x (SRLconst [c] y)) => (SUBSshiftRL x y [c])
+(SUBS (SRLconst [c] y) x) => (RSBSshiftRL x y [c])
+(SUBS x (SRAconst [c] y)) => (SUBSshiftRA x y [c])
+(SUBS (SRAconst [c] y) x) => (RSBSshiftRA x y [c])
+(SUBS x (SLL y z)) => (SUBSshiftLLreg x y z)
+(SUBS (SLL y z) x) => (RSBSshiftLLreg x y z)
+(SUBS x (SRL y z)) => (SUBSshiftRLreg x y z)
+(SUBS (SRL y z) x) => (RSBSshiftRLreg x y z)
+(SUBS x (SRA y z)) => (SUBSshiftRAreg x y z)
+(SUBS (SRA y z) x) => (RSBSshiftRAreg x y z)
+(RSB x (SLLconst [c] y)) => (RSBshiftLL x y [c])
+(RSB (SLLconst [c] y) x) => (SUBshiftLL x y [c])
+(RSB x (SRLconst [c] y)) => (RSBshiftRL x y [c])
+(RSB (SRLconst [c] y) x) => (SUBshiftRL x y [c])
+(RSB x (SRAconst [c] y)) => (RSBshiftRA x y [c])
+(RSB (SRAconst [c] y) x) => (SUBshiftRA x y [c])
+(RSB x (SLL y z)) => (RSBshiftLLreg x y z)
+(RSB (SLL y z) x) => (SUBshiftLLreg x y z)
+(RSB x (SRL y z)) => (RSBshiftRLreg x y z)
+(RSB (SRL y z) x) => (SUBshiftRLreg x y z)
+(RSB x (SRA y z)) => (RSBshiftRAreg x y z)
+(RSB (SRA y z) x) => (SUBshiftRAreg x y z)
+(AND x (SLLconst [c] y)) => (ANDshiftLL x y [c])
+(AND x (SRLconst [c] y)) => (ANDshiftRL x y [c])
+(AND x (SRAconst [c] y)) => (ANDshiftRA x y [c])
+(AND x (SLL y z)) => (ANDshiftLLreg x y z)
+(AND x (SRL y z)) => (ANDshiftRLreg x y z)
+(AND x (SRA y z)) => (ANDshiftRAreg x y z)
+(OR x (SLLconst [c] y)) => (ORshiftLL x y [c])
+(OR x (SRLconst [c] y)) => (ORshiftRL x y [c])
+(OR x (SRAconst [c] y)) => (ORshiftRA x y [c])
+(OR x (SLL y z)) => (ORshiftLLreg x y z)
+(OR x (SRL y z)) => (ORshiftRLreg x y z)
+(OR x (SRA y z)) => (ORshiftRAreg x y z)
+(XOR x (SLLconst [c] y)) => (XORshiftLL x y [c])
+(XOR x (SRLconst [c] y)) => (XORshiftRL x y [c])
+(XOR x (SRAconst [c] y)) => (XORshiftRA x y [c])
+(XOR x (SRRconst [c] y)) => (XORshiftRR x y [c])
+(XOR x (SLL y z)) => (XORshiftLLreg x y z)
+(XOR x (SRL y z)) => (XORshiftRLreg x y z)
+(XOR x (SRA y z)) => (XORshiftRAreg x y z)
+(BIC x (SLLconst [c] y)) => (BICshiftLL x y [c])
+(BIC x (SRLconst [c] y)) => (BICshiftRL x y [c])
+(BIC x (SRAconst [c] y)) => (BICshiftRA x y [c])
+(BIC x (SLL y z)) => (BICshiftLLreg x y z)
+(BIC x (SRL y z)) => (BICshiftRLreg x y z)
+(BIC x (SRA y z)) => (BICshiftRAreg x y z)
+(MVN (SLLconst [c] x)) => (MVNshiftLL x [c])
+(MVN (SRLconst [c] x)) => (MVNshiftRL x [c])
+(MVN (SRAconst [c] x)) => (MVNshiftRA x [c])
+(MVN (SLL x y)) => (MVNshiftLLreg x y)
+(MVN (SRL x y)) => (MVNshiftRLreg x y)
+(MVN (SRA x y)) => (MVNshiftRAreg x y)
+
+(CMP x (SLLconst [c] y)) => (CMPshiftLL x y [c])
+(CMP (SLLconst [c] y) x) => (InvertFlags (CMPshiftLL x y [c]))
+(CMP x (SRLconst [c] y)) => (CMPshiftRL x y [c])
+(CMP (SRLconst [c] y) x) => (InvertFlags (CMPshiftRL x y [c]))
+(CMP x (SRAconst [c] y)) => (CMPshiftRA x y [c])
+(CMP (SRAconst [c] y) x) => (InvertFlags (CMPshiftRA x y [c]))
+(CMP x (SLL y z)) => (CMPshiftLLreg x y z)
+(CMP (SLL y z) x) => (InvertFlags (CMPshiftLLreg x y z))
+(CMP x (SRL y z)) => (CMPshiftRLreg x y z)
+(CMP (SRL y z) x) => (InvertFlags (CMPshiftRLreg x y z))
+(CMP x (SRA y z)) => (CMPshiftRAreg x y z)
+(CMP (SRA y z) x) => (InvertFlags (CMPshiftRAreg x y z))
+(TST x (SLLconst [c] y)) => (TSTshiftLL x y [c])
+(TST x (SRLconst [c] y)) => (TSTshiftRL x y [c])
+(TST x (SRAconst [c] y)) => (TSTshiftRA x y [c])
+(TST x (SLL y z)) => (TSTshiftLLreg x y z)
+(TST x (SRL y z)) => (TSTshiftRLreg x y z)
+(TST x (SRA y z)) => (TSTshiftRAreg x y z)
+(TEQ x (SLLconst [c] y)) => (TEQshiftLL x y [c])
+(TEQ x (SRLconst [c] y)) => (TEQshiftRL x y [c])
+(TEQ x (SRAconst [c] y)) => (TEQshiftRA x y [c])
+(TEQ x (SLL y z)) => (TEQshiftLLreg x y z)
+(TEQ x (SRL y z)) => (TEQshiftRLreg x y z)
+(TEQ x (SRA y z)) => (TEQshiftRAreg x y z)
+(CMN x (SLLconst [c] y)) => (CMNshiftLL x y [c])
+(CMN x (SRLconst [c] y)) => (CMNshiftRL x y [c])
+(CMN x (SRAconst [c] y)) => (CMNshiftRA x y [c])
+(CMN x (SLL y z)) => (CMNshiftLLreg x y z)
+(CMN x (SRL y z)) => (CMNshiftRLreg x y z)
+(CMN x (SRA y z)) => (CMNshiftRAreg x y z)
+
+// prefer *const ops to *shift ops
+(ADDshiftLL (MOVWconst [c]) x [d]) => (ADDconst [c] (SLLconst <x.Type> x [d]))
+(ADDshiftRL (MOVWconst [c]) x [d]) => (ADDconst [c] (SRLconst <x.Type> x [d]))
+(ADDshiftRA (MOVWconst [c]) x [d]) => (ADDconst [c] (SRAconst <x.Type> x [d]))
+(ADCshiftLL (MOVWconst [c]) x [d] flags) => (ADCconst [c] (SLLconst <x.Type> x [d]) flags)
+(ADCshiftRL (MOVWconst [c]) x [d] flags) => (ADCconst [c] (SRLconst <x.Type> x [d]) flags)
+(ADCshiftRA (MOVWconst [c]) x [d] flags) => (ADCconst [c] (SRAconst <x.Type> x [d]) flags)
+(ADDSshiftLL (MOVWconst [c]) x [d]) => (ADDSconst [c] (SLLconst <x.Type> x [d]))
+(ADDSshiftRL (MOVWconst [c]) x [d]) => (ADDSconst [c] (SRLconst <x.Type> x [d]))
+(ADDSshiftRA (MOVWconst [c]) x [d]) => (ADDSconst [c] (SRAconst <x.Type> x [d]))
+(SUBshiftLL (MOVWconst [c]) x [d]) => (RSBconst [c] (SLLconst <x.Type> x [d]))
+(SUBshiftRL (MOVWconst [c]) x [d]) => (RSBconst [c] (SRLconst <x.Type> x [d]))
+(SUBshiftRA (MOVWconst [c]) x [d]) => (RSBconst [c] (SRAconst <x.Type> x [d]))
+(SBCshiftLL (MOVWconst [c]) x [d] flags) => (RSCconst [c] (SLLconst <x.Type> x [d]) flags)
+(SBCshiftRL (MOVWconst [c]) x [d] flags) => (RSCconst [c] (SRLconst <x.Type> x [d]) flags)
+(SBCshiftRA (MOVWconst [c]) x [d] flags) => (RSCconst [c] (SRAconst <x.Type> x [d]) flags)
+(SUBSshiftLL (MOVWconst [c]) x [d]) => (RSBSconst [c] (SLLconst <x.Type> x [d]))
+(SUBSshiftRL (MOVWconst [c]) x [d]) => (RSBSconst [c] (SRLconst <x.Type> x [d]))
+(SUBSshiftRA (MOVWconst [c]) x [d]) => (RSBSconst [c] (SRAconst <x.Type> x [d]))
+(RSBshiftLL (MOVWconst [c]) x [d]) => (SUBconst [c] (SLLconst <x.Type> x [d]))
+(RSBshiftRL (MOVWconst [c]) x [d]) => (SUBconst [c] (SRLconst <x.Type> x [d]))
+(RSBshiftRA (MOVWconst [c]) x [d]) => (SUBconst [c] (SRAconst <x.Type> x [d]))
+(RSCshiftLL (MOVWconst [c]) x [d] flags) => (SBCconst [c] (SLLconst <x.Type> x [d]) flags)
+(RSCshiftRL (MOVWconst [c]) x [d] flags) => (SBCconst [c] (SRLconst <x.Type> x [d]) flags)
+(RSCshiftRA (MOVWconst [c]) x [d] flags) => (SBCconst [c] (SRAconst <x.Type> x [d]) flags)
+(RSBSshiftLL (MOVWconst [c]) x [d]) => (SUBSconst [c] (SLLconst <x.Type> x [d]))
+(RSBSshiftRL (MOVWconst [c]) x [d]) => (SUBSconst [c] (SRLconst <x.Type> x [d]))
+(RSBSshiftRA (MOVWconst [c]) x [d]) => (SUBSconst [c] (SRAconst <x.Type> x [d]))
+(ANDshiftLL (MOVWconst [c]) x [d]) => (ANDconst [c] (SLLconst <x.Type> x [d]))
+(ANDshiftRL (MOVWconst [c]) x [d]) => (ANDconst [c] (SRLconst <x.Type> x [d]))
+(ANDshiftRA (MOVWconst [c]) x [d]) => (ANDconst [c] (SRAconst <x.Type> x [d]))
+(ORshiftLL (MOVWconst [c]) x [d]) => (ORconst [c] (SLLconst <x.Type> x [d]))
+(ORshiftRL (MOVWconst [c]) x [d]) => (ORconst [c] (SRLconst <x.Type> x [d]))
+(ORshiftRA (MOVWconst [c]) x [d]) => (ORconst [c] (SRAconst <x.Type> x [d]))
+(XORshiftLL (MOVWconst [c]) x [d]) => (XORconst [c] (SLLconst <x.Type> x [d]))
+(XORshiftRL (MOVWconst [c]) x [d]) => (XORconst [c] (SRLconst <x.Type> x [d]))
+(XORshiftRA (MOVWconst [c]) x [d]) => (XORconst [c] (SRAconst <x.Type> x [d]))
+(XORshiftRR (MOVWconst [c]) x [d]) => (XORconst [c] (SRRconst <x.Type> x [d]))
+(CMPshiftLL (MOVWconst [c]) x [d]) => (InvertFlags (CMPconst [c] (SLLconst <x.Type> x [d])))
+(CMPshiftRL (MOVWconst [c]) x [d]) => (InvertFlags (CMPconst [c] (SRLconst <x.Type> x [d])))
+(CMPshiftRA (MOVWconst [c]) x [d]) => (InvertFlags (CMPconst [c] (SRAconst <x.Type> x [d])))
+(TSTshiftLL (MOVWconst [c]) x [d]) => (TSTconst [c] (SLLconst <x.Type> x [d]))
+(TSTshiftRL (MOVWconst [c]) x [d]) => (TSTconst [c] (SRLconst <x.Type> x [d]))
+(TSTshiftRA (MOVWconst [c]) x [d]) => (TSTconst [c] (SRAconst <x.Type> x [d]))
+(TEQshiftLL (MOVWconst [c]) x [d]) => (TEQconst [c] (SLLconst <x.Type> x [d]))
+(TEQshiftRL (MOVWconst [c]) x [d]) => (TEQconst [c] (SRLconst <x.Type> x [d]))
+(TEQshiftRA (MOVWconst [c]) x [d]) => (TEQconst [c] (SRAconst <x.Type> x [d]))
+(CMNshiftLL (MOVWconst [c]) x [d]) => (CMNconst [c] (SLLconst <x.Type> x [d]))
+(CMNshiftRL (MOVWconst [c]) x [d]) => (CMNconst [c] (SRLconst <x.Type> x [d]))
+(CMNshiftRA (MOVWconst [c]) x [d]) => (CMNconst [c] (SRAconst <x.Type> x [d]))
+
+(ADDshiftLLreg (MOVWconst [c]) x y) => (ADDconst [c] (SLL <x.Type> x y))
+(ADDshiftRLreg (MOVWconst [c]) x y) => (ADDconst [c] (SRL <x.Type> x y))
+(ADDshiftRAreg (MOVWconst [c]) x y) => (ADDconst [c] (SRA <x.Type> x y))
+(ADCshiftLLreg (MOVWconst [c]) x y flags) => (ADCconst [c] (SLL <x.Type> x y) flags)
+(ADCshiftRLreg (MOVWconst [c]) x y flags) => (ADCconst [c] (SRL <x.Type> x y) flags)
+(ADCshiftRAreg (MOVWconst [c]) x y flags) => (ADCconst [c] (SRA <x.Type> x y) flags)
+(ADDSshiftLLreg (MOVWconst [c]) x y) => (ADDSconst [c] (SLL <x.Type> x y))
+(ADDSshiftRLreg (MOVWconst [c]) x y) => (ADDSconst [c] (SRL <x.Type> x y))
+(ADDSshiftRAreg (MOVWconst [c]) x y) => (ADDSconst [c] (SRA <x.Type> x y))
+(SUBshiftLLreg (MOVWconst [c]) x y) => (RSBconst [c] (SLL <x.Type> x y))
+(SUBshiftRLreg (MOVWconst [c]) x y) => (RSBconst [c] (SRL <x.Type> x y))
+(SUBshiftRAreg (MOVWconst [c]) x y) => (RSBconst [c] (SRA <x.Type> x y))
+(SBCshiftLLreg (MOVWconst [c]) x y flags) => (RSCconst [c] (SLL <x.Type> x y) flags)
+(SBCshiftRLreg (MOVWconst [c]) x y flags) => (RSCconst [c] (SRL <x.Type> x y) flags)
+(SBCshiftRAreg (MOVWconst [c]) x y flags) => (RSCconst [c] (SRA <x.Type> x y) flags)
+(SUBSshiftLLreg (MOVWconst [c]) x y) => (RSBSconst [c] (SLL <x.Type> x y))
+(SUBSshiftRLreg (MOVWconst [c]) x y) => (RSBSconst [c] (SRL <x.Type> x y))
+(SUBSshiftRAreg (MOVWconst [c]) x y) => (RSBSconst [c] (SRA <x.Type> x y))
+(RSBshiftLLreg (MOVWconst [c]) x y) => (SUBconst [c] (SLL <x.Type> x y))
+(RSBshiftRLreg (MOVWconst [c]) x y) => (SUBconst [c] (SRL <x.Type> x y))
+(RSBshiftRAreg (MOVWconst [c]) x y) => (SUBconst [c] (SRA <x.Type> x y))
+(RSCshiftLLreg (MOVWconst [c]) x y flags) => (SBCconst [c] (SLL <x.Type> x y) flags)
+(RSCshiftRLreg (MOVWconst [c]) x y flags) => (SBCconst [c] (SRL <x.Type> x y) flags)
+(RSCshiftRAreg (MOVWconst [c]) x y flags) => (SBCconst [c] (SRA <x.Type> x y) flags)
+(RSBSshiftLLreg (MOVWconst [c]) x y) => (SUBSconst [c] (SLL <x.Type> x y))
+(RSBSshiftRLreg (MOVWconst [c]) x y) => (SUBSconst [c] (SRL <x.Type> x y))
+(RSBSshiftRAreg (MOVWconst [c]) x y) => (SUBSconst [c] (SRA <x.Type> x y))
+(ANDshiftLLreg (MOVWconst [c]) x y) => (ANDconst [c] (SLL <x.Type> x y))
+(ANDshiftRLreg (MOVWconst [c]) x y) => (ANDconst [c] (SRL <x.Type> x y))
+(ANDshiftRAreg (MOVWconst [c]) x y) => (ANDconst [c] (SRA <x.Type> x y))
+(ORshiftLLreg (MOVWconst [c]) x y) => (ORconst [c] (SLL <x.Type> x y))
+(ORshiftRLreg (MOVWconst [c]) x y) => (ORconst [c] (SRL <x.Type> x y))
+(ORshiftRAreg (MOVWconst [c]) x y) => (ORconst [c] (SRA <x.Type> x y))
+(XORshiftLLreg (MOVWconst [c]) x y) => (XORconst [c] (SLL <x.Type> x y))
+(XORshiftRLreg (MOVWconst [c]) x y) => (XORconst [c] (SRL <x.Type> x y))
+(XORshiftRAreg (MOVWconst [c]) x y) => (XORconst [c] (SRA <x.Type> x y))
+(CMPshiftLLreg (MOVWconst [c]) x y) => (InvertFlags (CMPconst [c] (SLL <x.Type> x y)))
+(CMPshiftRLreg (MOVWconst [c]) x y) => (InvertFlags (CMPconst [c] (SRL <x.Type> x y)))
+(CMPshiftRAreg (MOVWconst [c]) x y) => (InvertFlags (CMPconst [c] (SRA <x.Type> x y)))
+(TSTshiftLLreg (MOVWconst [c]) x y) => (TSTconst [c] (SLL <x.Type> x y))
+(TSTshiftRLreg (MOVWconst [c]) x y) => (TSTconst [c] (SRL <x.Type> x y))
+(TSTshiftRAreg (MOVWconst [c]) x y) => (TSTconst [c] (SRA <x.Type> x y))
+(TEQshiftLLreg (MOVWconst [c]) x y) => (TEQconst [c] (SLL <x.Type> x y))
+(TEQshiftRLreg (MOVWconst [c]) x y) => (TEQconst [c] (SRL <x.Type> x y))
+(TEQshiftRAreg (MOVWconst [c]) x y) => (TEQconst [c] (SRA <x.Type> x y))
+(CMNshiftLLreg (MOVWconst [c]) x y) => (CMNconst [c] (SLL <x.Type> x y))
+(CMNshiftRLreg (MOVWconst [c]) x y) => (CMNconst [c] (SRL <x.Type> x y))
+(CMNshiftRAreg (MOVWconst [c]) x y) => (CMNconst [c] (SRA <x.Type> x y))
+
+// constant folding in *shift ops
+(ADDshiftLL x (MOVWconst [c]) [d]) => (ADDconst x [c<<uint64(d)])
+(ADDshiftRL x (MOVWconst [c]) [d]) => (ADDconst x [int32(uint32(c)>>uint64(d))])
+(ADDshiftRA x (MOVWconst [c]) [d]) => (ADDconst x [c>>uint64(d)])
+(ADCshiftLL x (MOVWconst [c]) [d] flags) => (ADCconst x [c<<uint64(d)] flags)
+(ADCshiftRL x (MOVWconst [c]) [d] flags) => (ADCconst x [int32(uint32(c)>>uint64(d))] flags)
+(ADCshiftRA x (MOVWconst [c]) [d] flags) => (ADCconst x [c>>uint64(d)] flags)
+(ADDSshiftLL x (MOVWconst [c]) [d]) => (ADDSconst x [c<<uint64(d)])
+(ADDSshiftRL x (MOVWconst [c]) [d]) => (ADDSconst x [int32(uint32(c)>>uint64(d))])
+(ADDSshiftRA x (MOVWconst [c]) [d]) => (ADDSconst x [c>>uint64(d)])
+(SUBshiftLL x (MOVWconst [c]) [d]) => (SUBconst x [c<<uint64(d)])
+(SUBshiftRL x (MOVWconst [c]) [d]) => (SUBconst x [int32(uint32(c)>>uint64(d))])
+(SUBshiftRA x (MOVWconst [c]) [d]) => (SUBconst x [c>>uint64(d)])
+(SBCshiftLL x (MOVWconst [c]) [d] flags) => (SBCconst x [c<<uint64(d)] flags)
+(SBCshiftRL x (MOVWconst [c]) [d] flags) => (SBCconst x [int32(uint32(c)>>uint64(d))] flags)
+(SBCshiftRA x (MOVWconst [c]) [d] flags) => (SBCconst x [c>>uint64(d)] flags)
+(SUBSshiftLL x (MOVWconst [c]) [d]) => (SUBSconst x [c<<uint64(d)])
+(SUBSshiftRL x (MOVWconst [c]) [d]) => (SUBSconst x [int32(uint32(c)>>uint64(d))])
+(SUBSshiftRA x (MOVWconst [c]) [d]) => (SUBSconst x [c>>uint64(d)])
+(RSBshiftLL x (MOVWconst [c]) [d]) => (RSBconst x [c<<uint64(d)])
+(RSBshiftRL x (MOVWconst [c]) [d]) => (RSBconst x [int32(uint32(c)>>uint64(d))])
+(RSBshiftRA x (MOVWconst [c]) [d]) => (RSBconst x [c>>uint64(d)])
+(RSCshiftLL x (MOVWconst [c]) [d] flags) => (RSCconst x [c<<uint64(d)] flags)
+(RSCshiftRL x (MOVWconst [c]) [d] flags) => (RSCconst x [int32(uint32(c)>>uint64(d))] flags)
+(RSCshiftRA x (MOVWconst [c]) [d] flags) => (RSCconst x [c>>uint64(d)] flags)
+(RSBSshiftLL x (MOVWconst [c]) [d]) => (RSBSconst x [c<<uint64(d)])
+(RSBSshiftRL x (MOVWconst [c]) [d]) => (RSBSconst x [int32(uint32(c)>>uint64(d))])
+(RSBSshiftRA x (MOVWconst [c]) [d]) => (RSBSconst x [c>>uint64(d)])
+(ANDshiftLL x (MOVWconst [c]) [d]) => (ANDconst x [c<<uint64(d)])
+(ANDshiftRL x (MOVWconst [c]) [d]) => (ANDconst x [int32(uint32(c)>>uint64(d))])
+(ANDshiftRA x (MOVWconst [c]) [d]) => (ANDconst x [c>>uint64(d)])
+(ORshiftLL x (MOVWconst [c]) [d]) => (ORconst x [c<<uint64(d)])
+(ORshiftRL x (MOVWconst [c]) [d]) => (ORconst x [int32(uint32(c)>>uint64(d))])
+(ORshiftRA x (MOVWconst [c]) [d]) => (ORconst x [c>>uint64(d)])
+(XORshiftLL x (MOVWconst [c]) [d]) => (XORconst x [c<<uint64(d)])
+(XORshiftRL x (MOVWconst [c]) [d]) => (XORconst x [int32(uint32(c)>>uint64(d))])
+(XORshiftRA x (MOVWconst [c]) [d]) => (XORconst x [c>>uint64(d)])
+(XORshiftRR x (MOVWconst [c]) [d]) => (XORconst x [int32(uint32(c)>>uint64(d)|uint32(c)<<uint64(32-d))])
+(BICshiftLL x (MOVWconst [c]) [d]) => (BICconst x [c<<uint64(d)])
+(BICshiftRL x (MOVWconst [c]) [d]) => (BICconst x [int32(uint32(c)>>uint64(d))])
+(BICshiftRA x (MOVWconst [c]) [d]) => (BICconst x [c>>uint64(d)])
+(MVNshiftLL (MOVWconst [c]) [d]) => (MOVWconst [^(c<<uint64(d))])
+(MVNshiftRL (MOVWconst [c]) [d]) => (MOVWconst [^int32(uint32(c)>>uint64(d))])
+(MVNshiftRA (MOVWconst [c]) [d]) => (MOVWconst [int32(c)>>uint64(d)])
+(CMPshiftLL x (MOVWconst [c]) [d]) => (CMPconst x [c<<uint64(d)])
+(CMPshiftRL x (MOVWconst [c]) [d]) => (CMPconst x [int32(uint32(c)>>uint64(d))])
+(CMPshiftRA x (MOVWconst [c]) [d]) => (CMPconst x [c>>uint64(d)])
+(TSTshiftLL x (MOVWconst [c]) [d]) => (TSTconst x [c<<uint64(d)])
+(TSTshiftRL x (MOVWconst [c]) [d]) => (TSTconst x [int32(uint32(c)>>uint64(d))])
+(TSTshiftRA x (MOVWconst [c]) [d]) => (TSTconst x [c>>uint64(d)])
+(TEQshiftLL x (MOVWconst [c]) [d]) => (TEQconst x [c<<uint64(d)])
+(TEQshiftRL x (MOVWconst [c]) [d]) => (TEQconst x [int32(uint32(c)>>uint64(d))])
+(TEQshiftRA x (MOVWconst [c]) [d]) => (TEQconst x [c>>uint64(d)])
+(CMNshiftLL x (MOVWconst [c]) [d]) => (CMNconst x [c<<uint64(d)])
+(CMNshiftRL x (MOVWconst [c]) [d]) => (CMNconst x [int32(uint32(c)>>uint64(d))])
+(CMNshiftRA x (MOVWconst [c]) [d]) => (CMNconst x [c>>uint64(d)])
+
+(ADDshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDshiftLL x y [c])
+(ADDshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDshiftRL x y [c])
+(ADDshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDshiftRA x y [c])
+(ADCshiftLLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (ADCshiftLL x y [c] flags)
+(ADCshiftRLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (ADCshiftRL x y [c] flags)
+(ADCshiftRAreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (ADCshiftRA x y [c] flags)
+(ADDSshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDSshiftLL x y [c])
+(ADDSshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDSshiftRL x y [c])
+(ADDSshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDSshiftRA x y [c])
+(SUBshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBshiftLL x y [c])
+(SUBshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBshiftRL x y [c])
+(SUBshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBshiftRA x y [c])
+(SBCshiftLLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (SBCshiftLL x y [c] flags)
+(SBCshiftRLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (SBCshiftRL x y [c] flags)
+(SBCshiftRAreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (SBCshiftRA x y [c] flags)
+(SUBSshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBSshiftLL x y [c])
+(SUBSshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBSshiftRL x y [c])
+(SUBSshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBSshiftRA x y [c])
+(RSBshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBshiftLL x y [c])
+(RSBshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBshiftRL x y [c])
+(RSBshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBshiftRA x y [c])
+(RSCshiftLLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (RSCshiftLL x y [c] flags)
+(RSCshiftRLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (RSCshiftRL x y [c] flags)
+(RSCshiftRAreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (RSCshiftRA x y [c] flags)
+(RSBSshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBSshiftLL x y [c])
+(RSBSshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBSshiftRL x y [c])
+(RSBSshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBSshiftRA x y [c])
+(ANDshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ANDshiftLL x y [c])
+(ANDshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ANDshiftRL x y [c])
+(ANDshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ANDshiftRA x y [c])
+(ORshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ORshiftLL x y [c])
+(ORshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ORshiftRL x y [c])
+(ORshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ORshiftRA x y [c])
+(XORshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (XORshiftLL x y [c])
+(XORshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (XORshiftRL x y [c])
+(XORshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (XORshiftRA x y [c])
+(BICshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (BICshiftLL x y [c])
+(BICshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (BICshiftRL x y [c])
+(BICshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (BICshiftRA x y [c])
+(MVNshiftLLreg x (MOVWconst [c])) && 0 <= c && c < 32 => (MVNshiftLL x [c])
+(MVNshiftRLreg x (MOVWconst [c])) && 0 <= c && c < 32 => (MVNshiftRL x [c])
+(MVNshiftRAreg x (MOVWconst [c])) && 0 <= c && c < 32 => (MVNshiftRA x [c])
+(CMPshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMPshiftLL x y [c])
+(CMPshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMPshiftRL x y [c])
+(CMPshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMPshiftRA x y [c])
+(TSTshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TSTshiftLL x y [c])
+(TSTshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TSTshiftRL x y [c])
+(TSTshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TSTshiftRA x y [c])
+(TEQshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TEQshiftLL x y [c])
+(TEQshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TEQshiftRL x y [c])
+(TEQshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TEQshiftRA x y [c])
+(CMNshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMNshiftLL x y [c])
+(CMNshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMNshiftRL x y [c])
+(CMNshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMNshiftRA x y [c])
+
+(RotateLeft16 <t> x (MOVWconst [c])) => (Or16 (Lsh16x32 <t> x (MOVWconst [c&15])) (Rsh16Ux32 <t> x (MOVWconst [-c&15])))
+(RotateLeft8 <t> x (MOVWconst [c])) => (Or8 (Lsh8x32 <t> x (MOVWconst [c&7])) (Rsh8Ux32 <t> x (MOVWconst [-c&7])))
+(RotateLeft32 x y) => (SRR x (RSBconst [0] <y.Type> y))
+
+// ((x>>8) | (x<<8)) -> (REV16 x), the type of x is uint16, "|" can also be "^" or "+".
+// UBFX instruction is supported by ARMv6T2, ARMv7 and above versions, REV16 is supported by
+// ARMv6 and above versions. So for ARMv6, we need to match SLLconst, SRLconst and ORshiftLL.
+((ADDshiftLL|ORshiftLL|XORshiftLL) <typ.UInt16> [8] (BFXU <typ.UInt16> [int32(armBFAuxInt(8, 8))] x) x) => (REV16 x)
+((ADDshiftLL|ORshiftLL|XORshiftLL) <typ.UInt16> [8] (SRLconst <typ.UInt16> [24] (SLLconst [16] x)) x) && buildcfg.GOARM>=6 => (REV16 x)
+
+// use indexed loads and stores
+(MOVWload [0] {sym} (ADD ptr idx) mem) && sym == nil => (MOVWloadidx ptr idx mem)
+(MOVWstore [0] {sym} (ADD ptr idx) val mem) && sym == nil => (MOVWstoreidx ptr idx val mem)
+(MOVWload [0] {sym} (ADDshiftLL ptr idx [c]) mem) && sym == nil => (MOVWloadshiftLL ptr idx [c] mem)
+(MOVWload [0] {sym} (ADDshiftRL ptr idx [c]) mem) && sym == nil => (MOVWloadshiftRL ptr idx [c] mem)
+(MOVWload [0] {sym} (ADDshiftRA ptr idx [c]) mem) && sym == nil => (MOVWloadshiftRA ptr idx [c] mem)
+(MOVWstore [0] {sym} (ADDshiftLL ptr idx [c]) val mem) && sym == nil => (MOVWstoreshiftLL ptr idx [c] val mem)
+(MOVWstore [0] {sym} (ADDshiftRL ptr idx [c]) val mem) && sym == nil => (MOVWstoreshiftRL ptr idx [c] val mem)
+(MOVWstore [0] {sym} (ADDshiftRA ptr idx [c]) val mem) && sym == nil => (MOVWstoreshiftRA ptr idx [c] val mem)
+(MOVBUload [0] {sym} (ADD ptr idx) mem) && sym == nil => (MOVBUloadidx ptr idx mem)
+(MOVBload [0] {sym} (ADD ptr idx) mem) && sym == nil => (MOVBloadidx ptr idx mem)
+(MOVBstore [0] {sym} (ADD ptr idx) val mem) && sym == nil => (MOVBstoreidx ptr idx val mem)
+(MOVHUload [0] {sym} (ADD ptr idx) mem) && sym == nil => (MOVHUloadidx ptr idx mem)
+(MOVHload [0] {sym} (ADD ptr idx) mem) && sym == nil => (MOVHloadidx ptr idx mem)
+(MOVHstore [0] {sym} (ADD ptr idx) val mem) && sym == nil => (MOVHstoreidx ptr idx val mem)
+
+// constant folding in indexed loads and stores
+(MOVWloadidx ptr (MOVWconst [c]) mem) => (MOVWload [c] ptr mem)
+(MOVWloadidx (MOVWconst [c]) ptr mem) => (MOVWload [c] ptr mem)
+(MOVBloadidx ptr (MOVWconst [c]) mem) => (MOVBload [c] ptr mem)
+(MOVBloadidx (MOVWconst [c]) ptr mem) => (MOVBload [c] ptr mem)
+(MOVBUloadidx ptr (MOVWconst [c]) mem) => (MOVBUload [c] ptr mem)
+(MOVBUloadidx (MOVWconst [c]) ptr mem) => (MOVBUload [c] ptr mem)
+(MOVHUloadidx ptr (MOVWconst [c]) mem) => (MOVHUload [c] ptr mem)
+(MOVHUloadidx (MOVWconst [c]) ptr mem) => (MOVHUload [c] ptr mem)
+(MOVHloadidx ptr (MOVWconst [c]) mem) => (MOVHload [c] ptr mem)
+(MOVHloadidx (MOVWconst [c]) ptr mem) => (MOVHload [c] ptr mem)
+
+(MOVWstoreidx ptr (MOVWconst [c]) val mem) => (MOVWstore [c] ptr val mem)
+(MOVWstoreidx (MOVWconst [c]) ptr val mem) => (MOVWstore [c] ptr val mem)
+(MOVBstoreidx ptr (MOVWconst [c]) val mem) => (MOVBstore [c] ptr val mem)
+(MOVBstoreidx (MOVWconst [c]) ptr val mem) => (MOVBstore [c] ptr val mem)
+(MOVHstoreidx ptr (MOVWconst [c]) val mem) => (MOVHstore [c] ptr val mem)
+(MOVHstoreidx (MOVWconst [c]) ptr val mem) => (MOVHstore [c] ptr val mem)
+
+(MOVWloadidx ptr (SLLconst idx [c]) mem) => (MOVWloadshiftLL ptr idx [c] mem)
+(MOVWloadidx (SLLconst idx [c]) ptr mem) => (MOVWloadshiftLL ptr idx [c] mem)
+(MOVWloadidx ptr (SRLconst idx [c]) mem) => (MOVWloadshiftRL ptr idx [c] mem)
+(MOVWloadidx (SRLconst idx [c]) ptr mem) => (MOVWloadshiftRL ptr idx [c] mem)
+(MOVWloadidx ptr (SRAconst idx [c]) mem) => (MOVWloadshiftRA ptr idx [c] mem)
+(MOVWloadidx (SRAconst idx [c]) ptr mem) => (MOVWloadshiftRA ptr idx [c] mem)
+
+(MOVWstoreidx ptr (SLLconst idx [c]) val mem) => (MOVWstoreshiftLL ptr idx [c] val mem)
+(MOVWstoreidx (SLLconst idx [c]) ptr val mem) => (MOVWstoreshiftLL ptr idx [c] val mem)
+(MOVWstoreidx ptr (SRLconst idx [c]) val mem) => (MOVWstoreshiftRL ptr idx [c] val mem)
+(MOVWstoreidx (SRLconst idx [c]) ptr val mem) => (MOVWstoreshiftRL ptr idx [c] val mem)
+(MOVWstoreidx ptr (SRAconst idx [c]) val mem) => (MOVWstoreshiftRA ptr idx [c] val mem)
+(MOVWstoreidx (SRAconst idx [c]) ptr val mem) => (MOVWstoreshiftRA ptr idx [c] val mem)
+
+(MOVWloadshiftLL ptr (MOVWconst [c]) [d] mem) => (MOVWload [int32(uint32(c)<<uint64(d))] ptr mem)
+(MOVWloadshiftRL ptr (MOVWconst [c]) [d] mem) => (MOVWload [int32(uint32(c)>>uint64(d))] ptr mem)
+(MOVWloadshiftRA ptr (MOVWconst [c]) [d] mem) => (MOVWload [c>>uint64(d)] ptr mem)
+
+(MOVWstoreshiftLL ptr (MOVWconst [c]) [d] val mem) => (MOVWstore [int32(uint32(c)<<uint64(d))] ptr val mem)
+(MOVWstoreshiftRL ptr (MOVWconst [c]) [d] val mem) => (MOVWstore [int32(uint32(c)>>uint64(d))] ptr val mem)
+(MOVWstoreshiftRA ptr (MOVWconst [c]) [d] val mem) => (MOVWstore [c>>uint64(d)] ptr val mem)
+
+// generic simplifications
+(ADD x (RSBconst [0] y)) => (SUB x y)
+(ADD <t> (RSBconst [c] x) (RSBconst [d] y)) => (RSBconst [c+d] (ADD <t> x y))
+(SUB x x) => (MOVWconst [0])
+(RSB x x) => (MOVWconst [0])
+(AND x x) => x
+(OR x x) => x
+(XOR x x) => (MOVWconst [0])
+(BIC x x) => (MOVWconst [0])
+
+(ADD (MUL x y) a) => (MULA x y a)
+(SUB a (MUL x y)) && buildcfg.GOARM == 7 => (MULS x y a)
+(RSB (MUL x y) a) && buildcfg.GOARM == 7 => (MULS x y a)
+
+(NEGF (MULF x y)) && buildcfg.GOARM >= 6 => (NMULF x y)
+(NEGD (MULD x y)) && buildcfg.GOARM >= 6 => (NMULD x y)
+(MULF (NEGF x) y) && buildcfg.GOARM >= 6 => (NMULF x y)
+(MULD (NEGD x) y) && buildcfg.GOARM >= 6 => (NMULD x y)
+(NMULF (NEGF x) y) => (MULF x y)
+(NMULD (NEGD x) y) => (MULD x y)
+
+// the result will overwrite the addend, since they are in the same register
+(ADDF a (MULF x y)) && a.Uses == 1 && buildcfg.GOARM >= 6 => (MULAF a x y)
+(ADDF a (NMULF x y)) && a.Uses == 1 && buildcfg.GOARM >= 6 => (MULSF a x y)
+(ADDD a (MULD x y)) && a.Uses == 1 && buildcfg.GOARM >= 6 => (MULAD a x y)
+(ADDD a (NMULD x y)) && a.Uses == 1 && buildcfg.GOARM >= 6 => (MULSD a x y)
+(SUBF a (MULF x y)) && a.Uses == 1 && buildcfg.GOARM >= 6 => (MULSF a x y)
+(SUBF a (NMULF x y)) && a.Uses == 1 && buildcfg.GOARM >= 6 => (MULAF a x y)
+(SUBD a (MULD x y)) && a.Uses == 1 && buildcfg.GOARM >= 6 => (MULSD a x y)
+(SUBD a (NMULD x y)) && a.Uses == 1 && buildcfg.GOARM >= 6 => (MULAD a x y)
+
+(AND x (MVN y)) => (BIC x y)
+
+// simplification with *shift ops
+(SUBshiftLL (SLLconst x [c]) x [c]) => (MOVWconst [0])
+(SUBshiftRL (SRLconst x [c]) x [c]) => (MOVWconst [0])
+(SUBshiftRA (SRAconst x [c]) x [c]) => (MOVWconst [0])
+(RSBshiftLL (SLLconst x [c]) x [c]) => (MOVWconst [0])
+(RSBshiftRL (SRLconst x [c]) x [c]) => (MOVWconst [0])
+(RSBshiftRA (SRAconst x [c]) x [c]) => (MOVWconst [0])
+(ANDshiftLL y:(SLLconst x [c]) x [c]) => y
+(ANDshiftRL y:(SRLconst x [c]) x [c]) => y
+(ANDshiftRA y:(SRAconst x [c]) x [c]) => y
+(ORshiftLL y:(SLLconst x [c]) x [c]) => y
+(ORshiftRL y:(SRLconst x [c]) x [c]) => y
+(ORshiftRA y:(SRAconst x [c]) x [c]) => y
+(XORshiftLL (SLLconst x [c]) x [c]) => (MOVWconst [0])
+(XORshiftRL (SRLconst x [c]) x [c]) => (MOVWconst [0])
+(XORshiftRA (SRAconst x [c]) x [c]) => (MOVWconst [0])
+(BICshiftLL (SLLconst x [c]) x [c]) => (MOVWconst [0])
+(BICshiftRL (SRLconst x [c]) x [c]) => (MOVWconst [0])
+(BICshiftRA (SRAconst x [c]) x [c]) => (MOVWconst [0])
+(AND x (MVNshiftLL y [c])) => (BICshiftLL x y [c])
+(AND x (MVNshiftRL y [c])) => (BICshiftRL x y [c])
+(AND x (MVNshiftRA y [c])) => (BICshiftRA x y [c])
+
+// floating point optimizations
+(CMPF x (MOVFconst [0])) => (CMPF0 x)
+(CMPD x (MOVDconst [0])) => (CMPD0 x)
+
+// bit extraction
+(SRAconst (SLLconst x [c]) [d]) && buildcfg.GOARM==7 && uint64(d)>=uint64(c) && uint64(d)<=31 => (BFX [(d-c)|(32-d)<<8] x)
+(SRLconst (SLLconst x [c]) [d]) && buildcfg.GOARM==7 && uint64(d)>=uint64(c) && uint64(d)<=31 => (BFXU [(d-c)|(32-d)<<8] x)
+
+// comparison simplification
+((EQ|NE) (CMP x (RSBconst [0] y))) => ((EQ|NE) (CMN x y)) // sense of carry bit not preserved; see also #50854
+((EQ|NE) (CMN x (RSBconst [0] y))) => ((EQ|NE) (CMP x y)) // sense of carry bit not preserved; see also #50864
+(EQ (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 => (EQ (CMP x y) yes no)
+(EQ (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 => (EQ (CMP a (MUL <x.Type> x y)) yes no)
+(EQ (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 => (EQ (CMPconst [c] x) yes no)
+(EQ (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 => (EQ (CMPshiftLL x y [c]) yes no)
+(EQ (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 => (EQ (CMPshiftRL x y [c]) yes no)
+(EQ (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 => (EQ (CMPshiftRA x y [c]) yes no)
+(EQ (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 => (EQ (CMPshiftLLreg x y z) yes no)
+(EQ (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 => (EQ (CMPshiftRLreg x y z) yes no)
+(EQ (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 => (EQ (CMPshiftRAreg x y z) yes no)
+(NE (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 => (NE (CMP x y) yes no)
+(NE (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 => (NE (CMP a (MUL <x.Type> x y)) yes no)
+(NE (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 => (NE (CMPconst [c] x) yes no)
+(NE (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 => (NE (CMPshiftLL x y [c]) yes no)
+(NE (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 => (NE (CMPshiftRL x y [c]) yes no)
+(NE (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 => (NE (CMPshiftRA x y [c]) yes no)
+(NE (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 => (NE (CMPshiftLLreg x y z) yes no)
+(NE (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 => (NE (CMPshiftRLreg x y z) yes no)
+(NE (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 => (NE (CMPshiftRAreg x y z) yes no)
+(EQ (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 => (EQ (CMN x y) yes no)
+(EQ (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 => (EQ (CMN a (MUL <x.Type> x y)) yes no)
+(EQ (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1 => (EQ (CMNconst [c] x) yes no)
+(EQ (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 => (EQ (CMNshiftLL x y [c]) yes no)
+(EQ (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 => (EQ (CMNshiftRL x y [c]) yes no)
+(EQ (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 => (EQ (CMNshiftRA x y [c]) yes no)
+(EQ (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 => (EQ (CMNshiftLLreg x y z) yes no)
+(EQ (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 => (EQ (CMNshiftRLreg x y z) yes no)
+(EQ (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 => (EQ (CMNshiftRAreg x y z) yes no)
+(NE (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 => (NE (CMN x y) yes no)
+(NE (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 => (NE (CMN a (MUL <x.Type> x y)) yes no)
+(NE (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1 => (NE (CMNconst [c] x) yes no)
+(NE (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 => (NE (CMNshiftLL x y [c]) yes no)
+(NE (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 => (NE (CMNshiftRL x y [c]) yes no)
+(NE (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 => (NE (CMNshiftRA x y [c]) yes no)
+(NE (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 => (NE (CMNshiftLLreg x y z) yes no)
+(NE (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 => (NE (CMNshiftRLreg x y z) yes no)
+(NE (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 => (NE (CMNshiftRAreg x y z) yes no)
+(EQ (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 => (EQ (TST x y) yes no)
+(EQ (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 => (EQ (TSTconst [c] x) yes no)
+(EQ (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 => (EQ (TSTshiftLL x y [c]) yes no)
+(EQ (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 => (EQ (TSTshiftRL x y [c]) yes no)
+(EQ (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 => (EQ (TSTshiftRA x y [c]) yes no)
+(EQ (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 => (EQ (TSTshiftLLreg x y z) yes no)
+(EQ (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 => (EQ (TSTshiftRLreg x y z) yes no)
+(EQ (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 => (EQ (TSTshiftRAreg x y z) yes no)
+(NE (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 => (NE (TST x y) yes no)
+(NE (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 => (NE (TSTconst [c] x) yes no)
+(NE (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 => (NE (TSTshiftLL x y [c]) yes no)
+(NE (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 => (NE (TSTshiftRL x y [c]) yes no)
+(NE (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 => (NE (TSTshiftRA x y [c]) yes no)
+(NE (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 => (NE (TSTshiftLLreg x y z) yes no)
+(NE (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 => (NE (TSTshiftRLreg x y z) yes no)
+(NE (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 => (NE (TSTshiftRAreg x y z) yes no)
+(EQ (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 => (EQ (TEQ x y) yes no)
+(EQ (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 => (EQ (TEQconst [c] x) yes no)
+(EQ (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 => (EQ (TEQshiftLL x y [c]) yes no)
+(EQ (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 => (EQ (TEQshiftRL x y [c]) yes no)
+(EQ (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 => (EQ (TEQshiftRA x y [c]) yes no)
+(EQ (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 => (EQ (TEQshiftLLreg x y z) yes no)
+(EQ (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 => (EQ (TEQshiftRLreg x y z) yes no)
+(EQ (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 => (EQ (TEQshiftRAreg x y z) yes no)
+(NE (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 => (NE (TEQ x y) yes no)
+(NE (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 => (NE (TEQconst [c] x) yes no)
+(NE (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 => (NE (TEQshiftLL x y [c]) yes no)
+(NE (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 => (NE (TEQshiftRL x y [c]) yes no)
+(NE (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 => (NE (TEQshiftRA x y [c]) yes no)
+(NE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 => (NE (TEQshiftLLreg x y z) yes no)
+(NE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 => (NE (TEQshiftRLreg x y z) yes no)
+(NE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 => (NE (TEQshiftRAreg x y z) yes no)
+(LT (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 => (LTnoov (CMP x y) yes no)
+(LT (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 => (LTnoov (CMP a (MUL <x.Type> x y)) yes no)
+(LT (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 => (LTnoov (CMPconst [c] x) yes no)
+(LT (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 => (LTnoov (CMPshiftLL x y [c]) yes no)
+(LT (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 => (LTnoov (CMPshiftRL x y [c]) yes no)
+(LT (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 => (LTnoov (CMPshiftRA x y [c]) yes no)
+(LT (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 => (LTnoov (CMPshiftLLreg x y z) yes no)
+(LT (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 => (LTnoov (CMPshiftRLreg x y z) yes no)
+(LT (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 => (LTnoov (CMPshiftRAreg x y z) yes no)
+(LE (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 => (LEnoov (CMP x y) yes no)
+(LE (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 => (LEnoov (CMP a (MUL <x.Type> x y)) yes no)
+(LE (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 => (LEnoov (CMPconst [c] x) yes no)
+(LE (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 => (LEnoov (CMPshiftLL x y [c]) yes no)
+(LE (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 => (LEnoov (CMPshiftRL x y [c]) yes no)
+(LE (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 => (LEnoov (CMPshiftRA x y [c]) yes no)
+(LE (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 => (LEnoov (CMPshiftLLreg x y z) yes no)
+(LE (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 => (LEnoov (CMPshiftRLreg x y z) yes no)
+(LE (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 => (LEnoov (CMPshiftRAreg x y z) yes no)
+(LT (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 => (LTnoov (CMN x y) yes no)
+(LT (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 => (LTnoov (CMN a (MUL <x.Type> x y)) yes no)
+(LT (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1 => (LTnoov (CMNconst [c] x) yes no)
+(LT (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 => (LTnoov (CMNshiftLL x y [c]) yes no)
+(LT (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 => (LTnoov (CMNshiftRL x y [c]) yes no)
+(LT (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 => (LTnoov (CMNshiftRA x y [c]) yes no)
+(LT (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 => (LTnoov (CMNshiftLLreg x y z) yes no)
+(LT (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 => (LTnoov (CMNshiftRLreg x y z) yes no)
+(LT (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 => (LTnoov (CMNshiftRAreg x y z) yes no)
+(LE (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 => (LEnoov (CMN x y) yes no)
+(LE (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 => (LEnoov (CMN a (MUL <x.Type> x y)) yes no)
+(LE (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1  => (LEnoov (CMNconst [c] x) yes no)
+(LE (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 => (LEnoov (CMNshiftLL x y [c]) yes no)
+(LE (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 => (LEnoov (CMNshiftRL x y [c]) yes no)
+(LE (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 => (LEnoov (CMNshiftRA x y [c]) yes no)
+(LE (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 => (LEnoov (CMNshiftLLreg x y z) yes no)
+(LE (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 => (LEnoov (CMNshiftRLreg x y z) yes no)
+(LE (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 => (LEnoov (CMNshiftRAreg x y z) yes no)
+(LT (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 => (LTnoov (TST x y) yes no)
+(LT (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 => (LTnoov (TSTconst [c] x) yes no)
+(LT (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 => (LTnoov (TSTshiftLL x y [c]) yes no)
+(LT (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 => (LTnoov (TSTshiftRL x y [c]) yes no)
+(LT (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 => (LTnoov (TSTshiftRA x y [c]) yes no)
+(LT (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 => (LTnoov (TSTshiftLLreg x y z) yes no)
+(LT (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 => (LTnoov (TSTshiftRLreg x y z) yes no)
+(LT (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 => (LTnoov (TSTshiftRAreg x y z) yes no)
+(LE (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 => (LEnoov (TST x y) yes no)
+(LE (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 => (LEnoov (TSTconst [c] x) yes no)
+(LE (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 => (LEnoov (TSTshiftLL x y [c]) yes no)
+(LE (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 => (LEnoov (TSTshiftRL x y [c]) yes no)
+(LE (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 => (LEnoov (TSTshiftRA x y [c]) yes no)
+(LE (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 => (LEnoov (TSTshiftLLreg x y z) yes no)
+(LE (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 => (LEnoov (TSTshiftRLreg x y z) yes no)
+(LE (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 => (LEnoov (TSTshiftRAreg x y z) yes no)
+(LT (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 => (LTnoov (TEQ x y) yes no)
+(LT (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 => (LTnoov (TEQconst [c] x) yes no)
+(LT (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 => (LTnoov (TEQshiftLL x y [c]) yes no)
+(LT (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 => (LTnoov (TEQshiftRL x y [c]) yes no)
+(LT (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 => (LTnoov (TEQshiftRA x y [c]) yes no)
+(LT (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 => (LTnoov (TEQshiftLLreg x y z) yes no)
+(LT (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 => (LTnoov (TEQshiftRLreg x y z) yes no)
+(LT (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 => (LTnoov (TEQshiftRAreg x y z) yes no)
+(LE (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 => (LEnoov (TEQ x y) yes no)
+(LE (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1  => (LEnoov (TEQconst [c] x) yes no)
+(LE (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 => (LEnoov (TEQshiftLL x y [c]) yes no)
+(LE (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 => (LEnoov (TEQshiftRL x y [c]) yes no)
+(LE (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 => (LEnoov (TEQshiftRA x y [c]) yes no)
+(LE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 => (LEnoov (TEQshiftLLreg x y z) yes no)
+(LE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 => (LEnoov (TEQshiftRLreg x y z) yes no)
+(LE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 => (LEnoov (TEQshiftRAreg x y z) yes no)
+(GT (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 => (GTnoov (CMP x y) yes no)
+(GT (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 => (GTnoov (CMP a (MUL <x.Type> x y)) yes no)
+(GT (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 => (GTnoov (CMPconst [c] x) yes no)
+(GT (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 => (GTnoov (CMPshiftLL x y [c]) yes no)
+(GT (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 => (GTnoov (CMPshiftRL x y [c]) yes no)
+(GT (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 => (GTnoov (CMPshiftRA x y [c]) yes no)
+(GT (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 => (GTnoov (CMPshiftLLreg x y z) yes no)
+(GT (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 => (GTnoov (CMPshiftRLreg x y z) yes no)
+(GT (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 => (GTnoov (CMPshiftRAreg x y z) yes no)
+(GE (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 => (GEnoov (CMP x y) yes no)
+(GE (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 => (GEnoov (CMP a (MUL <x.Type> x y)) yes no)
+(GE (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 => (GEnoov (CMPconst [c] x) yes no)
+(GE (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 => (GEnoov (CMPshiftLL x y [c]) yes no)
+(GE (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 => (GEnoov (CMPshiftRL x y [c]) yes no)
+(GE (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 => (GEnoov (CMPshiftRA x y [c]) yes no)
+(GE (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 => (GEnoov (CMPshiftLLreg x y z) yes no)
+(GE (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 => (GEnoov (CMPshiftRLreg x y z) yes no)
+(GE (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 => (GEnoov (CMPshiftRAreg x y z) yes no)
+(GT (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 => (GTnoov (CMN x y) yes no)
+(GT (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1 => (GTnoov (CMNconst [c] x) yes no)
+(GT (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 => (GTnoov (CMNshiftLL x y [c]) yes no)
+(GT (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 => (GTnoov (CMNshiftRL x y [c]) yes no)
+(GT (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 => (GTnoov (CMNshiftRA x y [c]) yes no)
+(GT (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 => (GTnoov (CMNshiftLLreg x y z) yes no)
+(GT (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 => (GTnoov (CMNshiftRLreg x y z) yes no)
+(GT (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 => (GTnoov (CMNshiftRAreg x y z) yes no)
+(GE (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 => (GEnoov (CMN x y) yes no)
+(GE (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 => (GEnoov (CMN a (MUL <x.Type> x y)) yes no)
+(GE (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1 => (GEnoov (CMNconst [c] x) yes no)
+(GE (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 => (GEnoov (CMNshiftLL x y [c]) yes no)
+(GE (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 => (GEnoov (CMNshiftRL x y [c]) yes no)
+(GE (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 => (GEnoov (CMNshiftRA x y [c]) yes no)
+(GE (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 => (GEnoov (CMNshiftLLreg x y z) yes no)
+(GE (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 => (GEnoov (CMNshiftRLreg x y z) yes no)
+(GE (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 => (GEnoov (CMNshiftRAreg x y z) yes no)
+(GT (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 => (GTnoov (CMN a (MUL <x.Type> x y)) yes no)
+(GT (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 => (GTnoov (TST x y) yes no)
+(GT (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 => (GTnoov (TSTconst [c] x) yes no)
+(GT (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 => (GTnoov (TSTshiftLL x y [c]) yes no)
+(GT (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 => (GTnoov (TSTshiftRL x y [c]) yes no)
+(GT (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 => (GTnoov (TSTshiftRA x y [c]) yes no)
+(GT (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 => (GTnoov (TSTshiftLLreg x y z) yes no)
+(GT (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 => (GTnoov (TSTshiftRLreg x y z) yes no)
+(GT (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 => (GTnoov (TSTshiftRAreg x y z) yes no)
+(GE (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 => (GEnoov (TST x y) yes no)
+(GE (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 => (GEnoov (TSTconst [c] x) yes no)
+(GE (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 => (GEnoov (TSTshiftLL x y [c]) yes no)
+(GE (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 => (GEnoov (TSTshiftRL x y [c]) yes no)
+(GE (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 => (GEnoov (TSTshiftRA x y [c]) yes no)
+(GE (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 => (GEnoov (TSTshiftLLreg x y z) yes no)
+(GE (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 => (GEnoov (TSTshiftRLreg x y z) yes no)
+(GE (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 => (GEnoov (TSTshiftRAreg x y z) yes no)
+(GT (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 => (GTnoov (TEQ x y) yes no)
+(GT (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 => (GTnoov (TEQconst [c] x) yes no)
+(GT (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 => (GTnoov (TEQshiftLL x y [c]) yes no)
+(GT (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 => (GTnoov (TEQshiftRL x y [c]) yes no)
+(GT (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 => (GTnoov (TEQshiftRA x y [c]) yes no)
+(GT (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 => (GTnoov (TEQshiftLLreg x y z) yes no)
+(GT (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 => (GTnoov (TEQshiftRLreg x y z) yes no)
+(GT (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 => (GTnoov (TEQshiftRAreg x y z) yes no)
+(GE (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 => (GEnoov (TEQ x y) yes no)
+(GE (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 => (GEnoov (TEQconst [c] x) yes no)
+(GE (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 => (GEnoov (TEQshiftLL x y [c]) yes no)
+(GE (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 => (GEnoov (TEQshiftRL x y [c]) yes no)
+(GE (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 => (GEnoov (TEQshiftRA x y [c]) yes no)
+(GE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 => (GEnoov (TEQshiftLLreg x y z) yes no)
+(GE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 => (GEnoov (TEQshiftRLreg x y z) yes no)
+(GE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 => (GEnoov (TEQshiftRAreg x y z) yes no)
+
+(MOVBUload [off] {sym} (SB) _) && symIsRO(sym) => (MOVWconst [int32(read8(sym, int64(off)))])
+(MOVHUload [off] {sym} (SB) _) && symIsRO(sym) => (MOVWconst [int32(read16(sym, int64(off), config.ctxt.Arch.ByteOrder))])
+(MOVWload [off] {sym} (SB) _) && symIsRO(sym) => (MOVWconst [int32(read32(sym, int64(off), config.ctxt.Arch.ByteOrder))])
diff --git a/src/cmd/compile/internal/ssa/_gen/ARM64.rules b/src/cmd/compile/internal/ssa/_gen/ARM64.rules
new file mode 100644
index 0000000..0c5a2e6
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/_gen/ARM64.rules
@@ -0,0 +1,2986 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+(Add(Ptr|64|32|16|8) ...) => (ADD ...)
+(Add(32F|64F) ...) => (FADD(S|D) ...)
+
+(Sub(Ptr|64|32|16|8) ...) => (SUB ...)
+(Sub(32F|64F) ...) => (FSUB(S|D) ...)
+
+(Mul64 ...) => (MUL ...)
+(Mul(32|16|8) ...) => (MULW ...)
+(Mul(32F|64F) ...) => (FMUL(S|D) ...)
+
+(Hmul64 ...) => (MULH ...)
+(Hmul64u ...) => (UMULH ...)
+(Hmul32 x y) => (SRAconst (MULL <typ.Int64> x y) [32])
+(Hmul32u x y) => (SRAconst (UMULL <typ.UInt64> x y) [32])
+(Select0 (Mul64uhilo x y)) => (UMULH x y)
+(Select1 (Mul64uhilo x y)) => (MUL x y)
+
+(Div64 [false] x y) => (DIV x y)
+(Div64u ...) => (UDIV ...)
+(Div32 [false] x y) => (DIVW x y)
+(Div32u ...) => (UDIVW ...)
+(Div16 [false] x y) => (DIVW (SignExt16to32 x) (SignExt16to32 y))
+(Div16u x y) => (UDIVW (ZeroExt16to32 x) (ZeroExt16to32 y))
+(Div8 x y) => (DIVW (SignExt8to32 x) (SignExt8to32 y))
+(Div8u x y) => (UDIVW (ZeroExt8to32 x) (ZeroExt8to32 y))
+(Div32F ...) => (FDIVS ...)
+(Div64F ...) => (FDIVD ...)
+
+(Mod64 x y) => (MOD x y)
+(Mod64u ...) => (UMOD ...)
+(Mod32 x y) => (MODW x y)
+(Mod32u ...) => (UMODW ...)
+(Mod16 x y) => (MODW (SignExt16to32 x) (SignExt16to32 y))
+(Mod16u x y) => (UMODW (ZeroExt16to32 x) (ZeroExt16to32 y))
+(Mod8 x y) => (MODW (SignExt8to32 x) (SignExt8to32 y))
+(Mod8u x y) => (UMODW (ZeroExt8to32 x) (ZeroExt8to32 y))
+
+// (x + y) / 2 with x>=y    =>    (x - y) / 2 + y
+(Avg64u <t> x y) => (ADD (SRLconst <t> (SUB <t> x y) [1]) y)
+
+(And(64|32|16|8) ...) => (AND ...)
+(Or(64|32|16|8) ...) => (OR ...)
+(Xor(64|32|16|8) ...) => (XOR ...)
+
+// unary ops
+(Neg(64|32|16|8) ...) => (NEG ...)
+(Neg(32F|64F) ...) => (FNEG(S|D) ...)
+(Com(64|32|16|8) ...) => (MVN ...)
+
+// math package intrinsics
+(Abs ...) => (FABSD ...)
+(Sqrt ...) => (FSQRTD ...)
+(Ceil ...) => (FRINTPD ...)
+(Floor ...) => (FRINTMD ...)
+(Round ...) => (FRINTAD ...)
+(RoundToEven ...) => (FRINTND ...)
+(Trunc ...) => (FRINTZD ...)
+(FMA x y z) => (FMADDD z x y)
+
+(Sqrt32 ...) => (FSQRTS ...)
+
+// lowering rotates
+// we do rotate detection in generic rules, if the following rules need to be changed, chcek generic rules first.
+(RotateLeft8 <t> x (MOVDconst [c])) => (Or8 (Lsh8x64 <t> x (MOVDconst [c&7])) (Rsh8Ux64 <t> x (MOVDconst [-c&7])))
+(RotateLeft8 <t> x y) => (OR <t> (SLL <t> x (ANDconst <typ.Int64> [7] y)) (SRL <t> (ZeroExt8to64 x) (ANDconst <typ.Int64> [7] (NEG <typ.Int64> y))))
+(RotateLeft16 <t> x (MOVDconst [c])) => (Or16 (Lsh16x64 <t> x (MOVDconst [c&15])) (Rsh16Ux64 <t> x (MOVDconst [-c&15])))
+(RotateLeft16 <t> x y) => (RORW <t> (ORshiftLL <typ.UInt32> (ZeroExt16to32 x) (ZeroExt16to32 x) [16]) (NEG <typ.Int64> y))
+(RotateLeft32 x y) => (RORW x (NEG <y.Type> y))
+(RotateLeft64 x y) => (ROR x (NEG <y.Type> y))
+
+(Ctz(64|32|16|8)NonZero ...) => (Ctz(64|32|32|32) ...)
+
+(Ctz64 <t> x) => (CLZ (RBIT <t> x))
+(Ctz32 <t> x) => (CLZW (RBITW <t> x))
+(Ctz16 <t> x) => (CLZW <t> (RBITW <typ.UInt32> (ORconst <typ.UInt32> [0x10000] x)))
+(Ctz8 <t> x) => (CLZW <t> (RBITW <typ.UInt32> (ORconst <typ.UInt32> [0x100] x)))
+
+(PopCount64 <t> x) => (FMOVDfpgp <t> (VUADDLV <typ.Float64> (VCNT <typ.Float64> (FMOVDgpfp <typ.Float64> x))))
+(PopCount32 <t> x) => (FMOVDfpgp <t> (VUADDLV <typ.Float64> (VCNT <typ.Float64> (FMOVDgpfp <typ.Float64> (ZeroExt32to64 x)))))
+(PopCount16 <t> x) => (FMOVDfpgp <t> (VUADDLV <typ.Float64> (VCNT <typ.Float64> (FMOVDgpfp <typ.Float64> (ZeroExt16to64 x)))))
+
+// Load args directly into the register class where it will be used.
+(FMOVDgpfp <t> (Arg [off] {sym})) => @b.Func.Entry (Arg <t> [off] {sym})
+(FMOVDfpgp <t> (Arg [off] {sym})) => @b.Func.Entry (Arg <t> [off] {sym})
+
+// Similarly for stores, if we see a store after FPR <=> GPR move, then redirect store to use the other register set.
+(MOVDstore [off] {sym} ptr (FMOVDfpgp val) mem) => (FMOVDstore [off] {sym} ptr val mem)
+(FMOVDstore [off] {sym} ptr (FMOVDgpfp val) mem) => (MOVDstore [off] {sym} ptr val mem)
+(MOVWstore [off] {sym} ptr (FMOVSfpgp val) mem) => (FMOVSstore [off] {sym} ptr val mem)
+(FMOVSstore [off] {sym} ptr (FMOVSgpfp val) mem) => (MOVWstore [off] {sym} ptr val mem)
+
+// float <=> int register moves, with no conversion.
+// These come up when compiling math.{Float64bits, Float64frombits, Float32bits, Float32frombits}.
+(MOVDload [off] {sym} ptr (FMOVDstore [off] {sym} ptr val _)) => (FMOVDfpgp val)
+(FMOVDload [off] {sym} ptr (MOVDstore [off] {sym} ptr val _)) => (FMOVDgpfp val)
+(MOVWUload [off] {sym} ptr (FMOVSstore [off] {sym} ptr val _)) => (FMOVSfpgp val)
+(FMOVSload [off] {sym} ptr (MOVWstore [off] {sym} ptr val _)) => (FMOVSgpfp val)
+
+(BitLen64 x) => (SUB (MOVDconst [64]) (CLZ <typ.Int> x))
+(BitLen32 x) => (SUB (MOVDconst [32]) (CLZW <typ.Int> x))
+
+(Bswap64 ...) => (REV ...)
+(Bswap32 ...) => (REVW ...)
+
+(BitRev64 ...) => (RBIT ...)
+(BitRev32 ...) => (RBITW ...)
+(BitRev16 x) => (SRLconst [48] (RBIT <typ.UInt64> x))
+(BitRev8 x) => (SRLconst [56] (RBIT <typ.UInt64> x))
+
+// In fact, UMOD will be translated into UREM instruction, and UREM is originally translated into
+// UDIV and MSUB instructions. But if there is already an identical UDIV instruction just before or
+// after UREM (case like quo, rem := z/y, z%y), then the second UDIV instruction becomes redundant.
+// The purpose of this rule is to have this extra UDIV instruction removed in CSE pass.
+(UMOD <typ.UInt64> x y) => (MSUB <typ.UInt64> x y (UDIV <typ.UInt64> x y))
+(UMODW <typ.UInt32> x y) => (MSUBW <typ.UInt32> x y (UDIVW <typ.UInt32> x y))
+
+// 64-bit addition with carry.
+(Select0 (Add64carry x y c)) => (Select0 <typ.UInt64> (ADCSflags x y (Select1 <types.TypeFlags> (ADDSconstflags [-1] c))))
+(Select1 (Add64carry x y c)) => (ADCzerocarry <typ.UInt64> (Select1 <types.TypeFlags> (ADCSflags x y (Select1 <types.TypeFlags> (ADDSconstflags [-1] c)))))
+
+// 64-bit subtraction with borrowing.
+(Select0 (Sub64borrow x y bo)) => (Select0 <typ.UInt64> (SBCSflags x y (Select1 <types.TypeFlags> (NEGSflags bo))))
+(Select1 (Sub64borrow x y bo)) => (NEG <typ.UInt64> (NGCzerocarry <typ.UInt64> (Select1 <types.TypeFlags> (SBCSflags x y (Select1 <types.TypeFlags> (NEGSflags bo))))))
+
+// boolean ops -- booleans are represented with 0=false, 1=true
+(AndB ...) => (AND ...)
+(OrB ...) => (OR ...)
+(EqB x y) => (XOR (MOVDconst [1]) (XOR <typ.Bool> x y))
+(NeqB ...) => (XOR ...)
+(Not x) => (XOR (MOVDconst [1]) x)
+
+// shifts
+// hardware instruction uses only the low 6 bits of the shift
+// we compare to 64 to ensure Go semantics for large shifts
+// Rules about rotates with non-const shift are based on the following rules,
+// if the following rules change, please also modify the rules based on them.
+
+// check shiftIsBounded first, if shift value is proved to be valid then we
+// can do the shift directly.
+// left shift
+(Lsh(64|32|16|8)x64 <t> x y) && shiftIsBounded(v) => (SLL <t> x y)
+(Lsh(64|32|16|8)x32 <t> x y) && shiftIsBounded(v) => (SLL <t> x y)
+(Lsh(64|32|16|8)x16 <t> x y) && shiftIsBounded(v) => (SLL <t> x y)
+(Lsh(64|32|16|8)x8 <t> x y) && shiftIsBounded(v) => (SLL <t> x y)
+
+// signed right shift
+(Rsh64x(64|32|16|8) <t> x y) && shiftIsBounded(v) => (SRA <t> x y)
+(Rsh32x(64|32|16|8) <t> x y) && shiftIsBounded(v) => (SRA <t> (SignExt32to64 x) y)
+(Rsh16x(64|32|16|8) <t> x y) && shiftIsBounded(v) => (SRA <t> (SignExt16to64 x) y)
+(Rsh8x(64|32|16|8)  <t> x y) && shiftIsBounded(v) => (SRA <t> (SignExt8to64 x) y)
+
+// unsigned right shift
+(Rsh64Ux(64|32|16|8) <t> x y) && shiftIsBounded(v) => (SRL <t> x y)
+(Rsh32Ux(64|32|16|8) <t> x y) && shiftIsBounded(v) => (SRL <t> (ZeroExt32to64 x) y)
+(Rsh16Ux(64|32|16|8) <t> x y) && shiftIsBounded(v) => (SRL <t> (ZeroExt16to64 x) y)
+(Rsh8Ux(64|32|16|8)  <t> x y) && shiftIsBounded(v) => (SRL <t> (ZeroExt8to64 x) y)
+
+// shift value may be out of range, use CMP + CSEL instead
+(Lsh64x64 <t> x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
+(Lsh64x32 <t> x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+(Lsh64x16 <t> x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+(Lsh64x8  <t> x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
+
+(Lsh32x64 <t> x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
+(Lsh32x32 <t> x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+(Lsh32x16 <t> x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+(Lsh32x8  <t> x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
+
+(Lsh16x64 <t> x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
+(Lsh16x32 <t> x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+(Lsh16x16 <t> x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+(Lsh16x8  <t> x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
+
+(Lsh8x64 <t> x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
+(Lsh8x32 <t> x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+(Lsh8x16 <t> x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+(Lsh8x8  <t> x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
+
+(Rsh64Ux64 <t> x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SRL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
+(Rsh64Ux32 <t> x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SRL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+(Rsh64Ux16 <t> x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SRL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+(Rsh64Ux8  <t> x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SRL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
+
+(Rsh32Ux64 <t> x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt32to64 x) y) (Const64 <t> [0]) (CMPconst [64] y))
+(Rsh32Ux32 <t> x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt32to64 x) y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+(Rsh32Ux16 <t> x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt32to64 x) y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+(Rsh32Ux8  <t> x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt32to64 x) y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
+
+(Rsh16Ux64 <t> x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt16to64 x) y) (Const64 <t> [0]) (CMPconst [64] y))
+(Rsh16Ux32 <t> x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt16to64 x) y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+(Rsh16Ux16 <t> x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt16to64 x) y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+(Rsh16Ux8  <t> x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt16to64 x) y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
+
+(Rsh8Ux64 <t> x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt8to64 x) y) (Const64 <t> [0]) (CMPconst [64] y))
+(Rsh8Ux32 <t> x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt8to64 x) y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+(Rsh8Ux16 <t> x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt8to64 x) y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+(Rsh8Ux8  <t> x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt8to64 x) y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
+
+(Rsh64x64 x y) && !shiftIsBounded(v) => (SRA x (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
+(Rsh64x32 x y) && !shiftIsBounded(v) => (SRA x (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
+(Rsh64x16 x y) && !shiftIsBounded(v) => (SRA x (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
+(Rsh64x8  x y) && !shiftIsBounded(v) => (SRA x (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64  y))))
+
+(Rsh32x64 x y) && !shiftIsBounded(v) => (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
+(Rsh32x32 x y) && !shiftIsBounded(v) => (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
+(Rsh32x16 x y) && !shiftIsBounded(v) => (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
+(Rsh32x8  x y) && !shiftIsBounded(v) => (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64  y))))
+
+(Rsh16x64 x y) && !shiftIsBounded(v) => (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
+(Rsh16x32 x y) && !shiftIsBounded(v) => (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
+(Rsh16x16 x y) && !shiftIsBounded(v) => (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
+(Rsh16x8  x y) && !shiftIsBounded(v) => (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64  y))))
+
+(Rsh8x64 x y) && !shiftIsBounded(v) => (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
+(Rsh8x32 x y) && !shiftIsBounded(v) => (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
+(Rsh8x16 x y) && !shiftIsBounded(v) => (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
+(Rsh8x8  x y) && !shiftIsBounded(v) => (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64  y))))
+
+// constants
+(Const(64|32|16|8) [val]) => (MOVDconst [int64(val)])
+(Const(32F|64F) [val]) => (FMOV(S|D)const [float64(val)])
+(ConstNil) => (MOVDconst [0])
+(ConstBool [t]) => (MOVDconst [b2i(t)])
+
+(Slicemask <t> x) => (SRAconst (NEG <t> x) [63])
+
+// truncations
+// Because we ignore high parts of registers, truncates are just copies.
+(Trunc16to8 ...) => (Copy ...)
+(Trunc32to8 ...) => (Copy ...)
+(Trunc32to16 ...) => (Copy ...)
+(Trunc64to8 ...) => (Copy ...)
+(Trunc64to16 ...) => (Copy ...)
+(Trunc64to32 ...) => (Copy ...)
+
+// Zero-/Sign-extensions
+(ZeroExt8to16 ...) => (MOVBUreg ...)
+(ZeroExt8to32 ...) => (MOVBUreg ...)
+(ZeroExt16to32 ...) => (MOVHUreg ...)
+(ZeroExt8to64 ...) => (MOVBUreg ...)
+(ZeroExt16to64 ...) => (MOVHUreg ...)
+(ZeroExt32to64 ...) => (MOVWUreg ...)
+
+(SignExt8to16 ...) => (MOVBreg ...)
+(SignExt8to32 ...) => (MOVBreg ...)
+(SignExt16to32 ...) => (MOVHreg ...)
+(SignExt8to64 ...) => (MOVBreg ...)
+(SignExt16to64 ...) => (MOVHreg ...)
+(SignExt32to64 ...) => (MOVWreg ...)
+
+// float <=> int conversion
+(Cvt32to32F ...) => (SCVTFWS ...)
+(Cvt32to64F ...) => (SCVTFWD ...)
+(Cvt64to32F ...) => (SCVTFS ...)
+(Cvt64to64F ...) => (SCVTFD ...)
+(Cvt32Uto32F ...) => (UCVTFWS ...)
+(Cvt32Uto64F ...) => (UCVTFWD ...)
+(Cvt64Uto32F ...) => (UCVTFS ...)
+(Cvt64Uto64F ...) => (UCVTFD ...)
+(Cvt32Fto32 ...) => (FCVTZSSW ...)
+(Cvt64Fto32 ...) => (FCVTZSDW ...)
+(Cvt32Fto64 ...) => (FCVTZSS ...)
+(Cvt64Fto64 ...) => (FCVTZSD ...)
+(Cvt32Fto32U ...) => (FCVTZUSW ...)
+(Cvt64Fto32U ...) => (FCVTZUDW ...)
+(Cvt32Fto64U ...) => (FCVTZUS ...)
+(Cvt64Fto64U ...) => (FCVTZUD ...)
+(Cvt32Fto64F ...) => (FCVTSD ...)
+(Cvt64Fto32F ...) => (FCVTDS ...)
+
+(CvtBoolToUint8 ...) => (Copy ...)
+
+(Round32F ...) => (LoweredRound32F ...)
+(Round64F ...) => (LoweredRound64F ...)
+
+// comparisons
+(Eq8 x y)  => (Equal (CMPW (ZeroExt8to32 x) (ZeroExt8to32 y)))
+(Eq16 x y) => (Equal (CMPW (ZeroExt16to32 x) (ZeroExt16to32 y)))
+(Eq32 x y) => (Equal (CMPW x y))
+(Eq64 x y) => (Equal (CMP x y))
+(EqPtr x y) => (Equal (CMP x y))
+(Eq32F x y) => (Equal (FCMPS x y))
+(Eq64F x y) => (Equal (FCMPD x y))
+
+(Neq8 x y)  => (NotEqual (CMPW (ZeroExt8to32 x) (ZeroExt8to32 y)))
+(Neq16 x y) => (NotEqual (CMPW (ZeroExt16to32 x) (ZeroExt16to32 y)))
+(Neq32 x y) => (NotEqual (CMPW x y))
+(Neq64 x y) => (NotEqual (CMP x y))
+(NeqPtr x y) => (NotEqual (CMP x y))
+(Neq32F x y) => (NotEqual (FCMPS x y))
+(Neq64F x y) => (NotEqual (FCMPD x y))
+
+(Less8 x y)  => (LessThan (CMPW (SignExt8to32 x) (SignExt8to32 y)))
+(Less16 x y) => (LessThan (CMPW (SignExt16to32 x) (SignExt16to32 y)))
+(Less32 x y) => (LessThan (CMPW x y))
+(Less64 x y) => (LessThan (CMP x y))
+
+// Set condition flags for floating-point comparisons "x < y"
+// and "x <= y". Because if either or both of the operands are
+// NaNs, all three of (x < y), (x == y) and (x > y) are false,
+// and ARM Manual says FCMP instruction sets PSTATE.<N,Z,C,V>
+// of this case to (0, 0, 1, 1).
+(Less32F x y) => (LessThanF (FCMPS x y))
+(Less64F x y) => (LessThanF (FCMPD x y))
+
+// For an unsigned integer x, the following rules are useful when combining branch
+// 0 <  x  =>  x != 0
+// x <= 0  =>  x == 0
+// x <  1  =>  x == 0
+// 1 <= x  =>  x != 0
+(Less(8U|16U|32U|64U) zero:(MOVDconst [0]) x) => (Neq(8|16|32|64) zero x)
+(Leq(8U|16U|32U|64U) x zero:(MOVDconst [0]))  => (Eq(8|16|32|64) x zero)
+(Less(8U|16U|32U|64U) x (MOVDconst [1])) => (Eq(8|16|32|64) x (MOVDconst [0]))
+(Leq(8U|16U|32U|64U) (MOVDconst [1]) x)  => (Neq(8|16|32|64) (MOVDconst [0]) x)
+
+(Less8U x y)  => (LessThanU (CMPW (ZeroExt8to32 x) (ZeroExt8to32 y)))
+(Less16U x y) => (LessThanU (CMPW (ZeroExt16to32 x) (ZeroExt16to32 y)))
+(Less32U x y) => (LessThanU (CMPW x y))
+(Less64U x y) => (LessThanU (CMP x y))
+
+(Leq8 x y)  => (LessEqual (CMPW (SignExt8to32 x) (SignExt8to32 y)))
+(Leq16 x y) => (LessEqual (CMPW (SignExt16to32 x) (SignExt16to32 y)))
+(Leq32 x y) => (LessEqual (CMPW x y))
+(Leq64 x y) => (LessEqual (CMP x y))
+
+// Refer to the comments for op Less64F above.
+(Leq32F x y) => (LessEqualF (FCMPS x y))
+(Leq64F x y) => (LessEqualF (FCMPD x y))
+
+(Leq8U x y)  => (LessEqualU (CMPW (ZeroExt8to32 x) (ZeroExt8to32 y)))
+(Leq16U x y) => (LessEqualU (CMPW (ZeroExt16to32 x) (ZeroExt16to32 y)))
+(Leq32U x y) => (LessEqualU (CMPW x y))
+(Leq64U x y) => (LessEqualU (CMP x y))
+
+// Optimize comparison between a floating-point value and 0.0 with "FCMP $(0.0), Fn"
+(FCMPS x (FMOVSconst [0])) => (FCMPS0 x)
+(FCMPS (FMOVSconst [0]) x) => (InvertFlags (FCMPS0 x))
+(FCMPD x (FMOVDconst [0])) => (FCMPD0 x)
+(FCMPD (FMOVDconst [0]) x) => (InvertFlags (FCMPD0 x))
+
+// CSEL needs a flag-generating argument. Synthesize a TSTW if necessary.
+(CondSelect x y boolval) && flagArg(boolval) != nil => (CSEL [boolval.Op] x y flagArg(boolval))
+(CondSelect x y boolval) && flagArg(boolval) == nil => (CSEL [OpARM64NotEqual] x y (TSTWconst [1] boolval))
+
+(OffPtr [off] ptr:(SP)) && is32Bit(off) => (MOVDaddr [int32(off)] ptr)
+(OffPtr [off] ptr) => (ADDconst [off] ptr)
+
+(Addr {sym} base) => (MOVDaddr {sym} base)
+(LocalAddr {sym} base _) => (MOVDaddr {sym} base)
+
+// loads
+(Load <t> ptr mem) && t.IsBoolean() => (MOVBUload ptr mem)
+(Load <t> ptr mem) && (is8BitInt(t)  && isSigned(t))  => (MOVBload ptr mem)
+(Load <t> ptr mem) && (is8BitInt(t)  && !isSigned(t)) => (MOVBUload ptr mem)
+(Load <t> ptr mem) && (is16BitInt(t) && isSigned(t))  => (MOVHload ptr mem)
+(Load <t> ptr mem) && (is16BitInt(t) && !isSigned(t)) => (MOVHUload ptr mem)
+(Load <t> ptr mem) && (is32BitInt(t) && isSigned(t))  => (MOVWload ptr mem)
+(Load <t> ptr mem) && (is32BitInt(t) && !isSigned(t)) => (MOVWUload ptr mem)
+(Load <t> ptr mem) && (is64BitInt(t) || isPtr(t)) => (MOVDload ptr mem)
+(Load <t> ptr mem) && is32BitFloat(t) => (FMOVSload ptr mem)
+(Load <t> ptr mem) && is64BitFloat(t) => (FMOVDload ptr mem)
+
+// stores
+(Store {t} ptr val mem) && t.Size() == 1 => (MOVBstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 2 => (MOVHstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 4 && !is32BitFloat(val.Type) => (MOVWstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 8 && !is64BitFloat(val.Type) => (MOVDstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 4 && is32BitFloat(val.Type) => (FMOVSstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 8 && is64BitFloat(val.Type) => (FMOVDstore ptr val mem)
+
+// zeroing
+(Zero [0] _ mem) => mem
+(Zero [1] ptr mem) => (MOVBstore ptr (MOVDconst [0]) mem)
+(Zero [2] ptr mem) => (MOVHstore ptr (MOVDconst [0]) mem)
+(Zero [4] ptr mem) => (MOVWstore ptr (MOVDconst [0]) mem)
+(Zero [3] ptr mem) =>
+	(MOVBstore [2] ptr (MOVDconst [0])
+		(MOVHstore ptr (MOVDconst [0]) mem))
+(Zero [5] ptr mem) =>
+	(MOVBstore [4] ptr (MOVDconst [0])
+		(MOVWstore ptr (MOVDconst [0]) mem))
+(Zero [6] ptr mem) =>
+	(MOVHstore [4] ptr (MOVDconst [0])
+		(MOVWstore ptr (MOVDconst [0]) mem))
+(Zero [7] ptr mem) =>
+	(MOVWstore [3] ptr (MOVDconst [0])
+		(MOVWstore ptr (MOVDconst [0]) mem))
+(Zero [8] ptr mem) => (MOVDstore ptr (MOVDconst [0]) mem)
+(Zero [9] ptr mem) =>
+	(MOVBstore [8] ptr (MOVDconst [0])
+		(MOVDstore ptr (MOVDconst [0]) mem))
+(Zero [10] ptr mem) =>
+	(MOVHstore [8] ptr (MOVDconst [0])
+		(MOVDstore ptr (MOVDconst [0]) mem))
+(Zero [11] ptr mem) =>
+	(MOVDstore [3] ptr (MOVDconst [0])
+		(MOVDstore ptr (MOVDconst [0]) mem))
+(Zero [12] ptr mem) =>
+	(MOVWstore [8] ptr (MOVDconst [0])
+		(MOVDstore ptr (MOVDconst [0]) mem))
+(Zero [13] ptr mem) =>
+	(MOVDstore [5] ptr (MOVDconst [0])
+		(MOVDstore ptr (MOVDconst [0]) mem))
+(Zero [14] ptr mem) =>
+	(MOVDstore [6] ptr (MOVDconst [0])
+		(MOVDstore ptr (MOVDconst [0]) mem))
+(Zero [15] ptr mem) =>
+	(MOVDstore [7] ptr (MOVDconst [0])
+		(MOVDstore ptr (MOVDconst [0]) mem))
+(Zero [16] ptr mem) =>
+	(STP [0] ptr (MOVDconst [0]) (MOVDconst [0]) mem)
+
+(Zero [32] ptr mem) =>
+	(STP [16] ptr (MOVDconst [0]) (MOVDconst [0])
+		(STP [0] ptr (MOVDconst [0]) (MOVDconst [0]) mem))
+
+(Zero [48] ptr mem) =>
+	(STP [32] ptr (MOVDconst [0]) (MOVDconst [0])
+		(STP [16] ptr (MOVDconst [0]) (MOVDconst [0])
+			(STP [0] ptr (MOVDconst [0]) (MOVDconst [0]) mem)))
+
+(Zero [64] ptr mem) =>
+	(STP [48] ptr (MOVDconst [0]) (MOVDconst [0])
+		(STP [32] ptr (MOVDconst [0]) (MOVDconst [0])
+			(STP [16] ptr (MOVDconst [0]) (MOVDconst [0])
+				(STP [0] ptr (MOVDconst [0]) (MOVDconst [0]) mem))))
+
+// strip off fractional word zeroing
+(Zero [s] ptr mem) && s%16 != 0 && s%16 <= 8 && s > 16 =>
+	(Zero [8]
+		(OffPtr <ptr.Type> ptr [s-8])
+		(Zero [s-s%16] ptr mem))
+(Zero [s] ptr mem) && s%16 != 0 && s%16 > 8 && s > 16 =>
+	(Zero [16]
+		(OffPtr <ptr.Type> ptr [s-16])
+		(Zero [s-s%16] ptr mem))
+
+// medium zeroing uses a duff device
+// 4, 16, and 64 are magic constants, see runtime/mkduff.go
+(Zero [s] ptr mem)
+	&& s%16 == 0 && s > 64 && s <= 16*64
+	&& !config.noDuffDevice =>
+	(DUFFZERO [4 * (64 - s/16)] ptr mem)
+
+// large zeroing uses a loop
+(Zero [s] ptr mem)
+	&& s%16 == 0 && (s > 16*64 || config.noDuffDevice) =>
+	(LoweredZero
+		ptr
+		(ADDconst <ptr.Type> [s-16] ptr)
+		mem)
+
+// moves
+(Move [0] _ _ mem) => mem
+(Move [1] dst src mem) => (MOVBstore dst (MOVBUload src mem) mem)
+(Move [2] dst src mem) => (MOVHstore dst (MOVHUload src mem) mem)
+(Move [3] dst src mem) =>
+	(MOVBstore [2] dst (MOVBUload [2] src mem)
+		(MOVHstore dst (MOVHUload src mem) mem))
+(Move [4] dst src mem) => (MOVWstore dst (MOVWUload src mem) mem)
+(Move [5] dst src mem) =>
+	(MOVBstore [4] dst (MOVBUload [4] src mem)
+		(MOVWstore dst (MOVWUload src mem) mem))
+(Move [6] dst src mem) =>
+	(MOVHstore [4] dst (MOVHUload [4] src mem)
+		(MOVWstore dst (MOVWUload src mem) mem))
+(Move [7] dst src mem) =>
+	(MOVWstore [3] dst (MOVWUload [3] src mem)
+		(MOVWstore dst (MOVWUload src mem) mem))
+(Move [8] dst src mem) => (MOVDstore dst (MOVDload src mem) mem)
+(Move [9] dst src mem) =>
+	(MOVBstore [8] dst (MOVBUload [8] src mem)
+		(MOVDstore dst (MOVDload src mem) mem))
+(Move [10] dst src mem) =>
+	(MOVHstore [8] dst (MOVHUload [8] src mem)
+		(MOVDstore dst (MOVDload src mem) mem))
+(Move [11] dst src mem) =>
+	(MOVDstore [3] dst (MOVDload [3] src mem)
+		(MOVDstore dst (MOVDload src mem) mem))
+(Move [12] dst src mem) =>
+	(MOVWstore [8] dst (MOVWUload [8] src mem)
+		(MOVDstore dst (MOVDload src mem) mem))
+(Move [13] dst src mem) =>
+	(MOVDstore [5] dst (MOVDload [5] src mem)
+		(MOVDstore dst (MOVDload src mem) mem))
+(Move [14] dst src mem) =>
+	(MOVDstore [6] dst (MOVDload [6] src mem)
+		(MOVDstore dst (MOVDload src mem) mem))
+(Move [15] dst src mem) =>
+	(MOVDstore [7] dst (MOVDload [7] src mem)
+		(MOVDstore dst (MOVDload src mem) mem))
+(Move [16] dst src mem) =>
+	(STP dst (Select0 <typ.UInt64> (LDP src mem)) (Select1 <typ.UInt64> (LDP src mem)) mem)
+(Move [32] dst src mem) =>
+	(STP [16] dst (Select0 <typ.UInt64> (LDP [16] src mem)) (Select1 <typ.UInt64> (LDP [16] src mem))
+		(STP dst (Select0 <typ.UInt64> (LDP src mem)) (Select1 <typ.UInt64> (LDP src mem)) mem))
+(Move [48] dst src mem) =>
+	(STP [32] dst (Select0 <typ.UInt64> (LDP [32] src mem)) (Select1 <typ.UInt64> (LDP [32] src mem))
+		(STP [16] dst (Select0 <typ.UInt64> (LDP [16] src mem)) (Select1 <typ.UInt64> (LDP [16] src mem))
+			(STP dst (Select0 <typ.UInt64> (LDP src mem)) (Select1 <typ.UInt64> (LDP src mem)) mem)))
+(Move [64] dst src mem) =>
+	(STP [48] dst (Select0 <typ.UInt64> (LDP [48] src mem)) (Select1 <typ.UInt64> (LDP [48] src mem))
+		(STP [32] dst (Select0 <typ.UInt64> (LDP [32] src mem)) (Select1 <typ.UInt64> (LDP [32] src mem))
+			(STP [16] dst (Select0 <typ.UInt64> (LDP [16] src mem)) (Select1 <typ.UInt64> (LDP [16] src mem))
+				(STP dst (Select0 <typ.UInt64> (LDP src mem)) (Select1 <typ.UInt64> (LDP src mem)) mem))))
+
+// strip off fractional word move
+(Move [s] dst src mem) && s%16 != 0 && s%16 <= 8 && s > 16 =>
+	(Move [8]
+		(OffPtr <dst.Type> dst [s-8])
+		(OffPtr <src.Type> src [s-8])
+		(Move [s-s%16] dst src mem))
+(Move [s] dst src mem) && s%16 != 0 && s%16 > 8 && s > 16 =>
+	(Move [16]
+		(OffPtr <dst.Type> dst [s-16])
+		(OffPtr <src.Type> src [s-16])
+		(Move [s-s%16] dst src mem))
+
+// medium move uses a duff device
+(Move [s] dst src mem)
+	&& s > 64 && s <= 16*64 && s%16 == 0
+	&& !config.noDuffDevice && logLargeCopy(v, s) =>
+	(DUFFCOPY [8 * (64 - s/16)] dst src mem)
+// 8 is the number of bytes to encode:
+//
+// LDP.P   16(R16), (R26, R27)
+// STP.P   (R26, R27), 16(R17)
+//
+// 64 is number of these blocks. See runtime/duff_arm64.s:duffcopy
+
+// large move uses a loop
+(Move [s] dst src mem)
+	&& s%16 == 0 && (s > 16*64 || config.noDuffDevice)
+	&& logLargeCopy(v, s) =>
+	(LoweredMove
+		dst
+		src
+		(ADDconst <src.Type> src [s-16])
+		mem)
+
+// calls
+(StaticCall ...) => (CALLstatic ...)
+(ClosureCall ...) => (CALLclosure ...)
+(InterCall ...) => (CALLinter ...)
+(TailCall ...) => (CALLtail ...)
+
+// checks
+(NilCheck ...) => (LoweredNilCheck ...)
+(IsNonNil ptr) => (NotEqual (CMPconst [0] ptr))
+(IsInBounds idx len) => (LessThanU (CMP idx len))
+(IsSliceInBounds idx len) => (LessEqualU (CMP idx len))
+
+// pseudo-ops
+(GetClosurePtr ...) => (LoweredGetClosurePtr ...)
+(GetCallerSP ...) => (LoweredGetCallerSP ...)
+(GetCallerPC ...) => (LoweredGetCallerPC ...)
+
+// Absorb pseudo-ops into blocks.
+(If (Equal cc) yes no) => (EQ cc yes no)
+(If (NotEqual cc) yes no) => (NE cc yes no)
+(If (LessThan cc) yes no) => (LT cc yes no)
+(If (LessThanU cc) yes no) => (ULT cc yes no)
+(If (LessEqual cc) yes no) => (LE cc yes no)
+(If (LessEqualU cc) yes no) => (ULE cc yes no)
+(If (GreaterThan cc) yes no) => (GT cc yes no)
+(If (GreaterThanU cc) yes no) => (UGT cc yes no)
+(If (GreaterEqual cc) yes no) => (GE cc yes no)
+(If (GreaterEqualU cc) yes no) => (UGE cc yes no)
+(If (LessThanF cc) yes no) => (FLT cc yes no)
+(If (LessEqualF cc) yes no) => (FLE cc yes no)
+(If (GreaterThanF cc) yes no) => (FGT cc yes no)
+(If (GreaterEqualF cc) yes no) => (FGE cc yes no)
+
+(If cond yes no) => (TBNZ [0] cond yes no)
+
+(JumpTable idx) => (JUMPTABLE {makeJumpTableSym(b)} idx (MOVDaddr <typ.Uintptr> {makeJumpTableSym(b)} (SB)))
+
+// atomic intrinsics
+// Note: these ops do not accept offset.
+(AtomicLoad8   ...) => (LDARB ...)
+(AtomicLoad32  ...) => (LDARW ...)
+(AtomicLoad64  ...) => (LDAR  ...)
+(AtomicLoadPtr ...) => (LDAR  ...)
+
+(AtomicStore8       ...) => (STLRB ...)
+(AtomicStore32      ...) => (STLRW ...)
+(AtomicStore64      ...) => (STLR  ...)
+(AtomicStorePtrNoWB ...) => (STLR  ...)
+
+(AtomicExchange(32|64)       ...) => (LoweredAtomicExchange(32|64) ...)
+(AtomicAdd(32|64)            ...) => (LoweredAtomicAdd(32|64) ...)
+(AtomicCompareAndSwap(32|64) ...) => (LoweredAtomicCas(32|64) ...)
+
+(AtomicAdd(32|64)Variant            ...) => (LoweredAtomicAdd(32|64)Variant      ...)
+(AtomicExchange(32|64)Variant       ...) => (LoweredAtomicExchange(32|64)Variant ...)
+(AtomicCompareAndSwap(32|64)Variant ...) => (LoweredAtomicCas(32|64)Variant      ...)
+
+// Currently the updated value is not used, but we need a register to temporarily hold it.
+(AtomicAnd8  ptr val mem) => (Select1 (LoweredAtomicAnd8  ptr val mem))
+(AtomicAnd32 ptr val mem) => (Select1 (LoweredAtomicAnd32 ptr val mem))
+(AtomicOr8   ptr val mem) => (Select1 (LoweredAtomicOr8   ptr val mem))
+(AtomicOr32  ptr val mem) => (Select1 (LoweredAtomicOr32  ptr val mem))
+
+(AtomicAnd8Variant  ptr val mem) => (Select1 (LoweredAtomicAnd8Variant  ptr val mem))
+(AtomicAnd32Variant ptr val mem) => (Select1 (LoweredAtomicAnd32Variant ptr val mem))
+(AtomicOr8Variant   ptr val mem) => (Select1 (LoweredAtomicOr8Variant   ptr val mem))
+(AtomicOr32Variant  ptr val mem) => (Select1 (LoweredAtomicOr32Variant  ptr val mem))
+
+// Write barrier.
+(WB ...) => (LoweredWB ...)
+
+// Publication barrier (0xe is ST option)
+(PubBarrier mem) => (DMB [0xe] mem)
+
+(PanicBounds [kind] x y mem) && boundsABI(kind) == 0 => (LoweredPanicBoundsA [kind] x y mem)
+(PanicBounds [kind] x y mem) && boundsABI(kind) == 1 => (LoweredPanicBoundsB [kind] x y mem)
+(PanicBounds [kind] x y mem) && boundsABI(kind) == 2 => (LoweredPanicBoundsC [kind] x y mem)
+
+// Optimizations
+
+// Absorb boolean tests into block
+(NZ (Equal cc) yes no) => (EQ cc yes no)
+(NZ (NotEqual cc) yes no) => (NE cc yes no)
+(NZ (LessThan cc) yes no) => (LT cc yes no)
+(NZ (LessThanU cc) yes no) => (ULT cc yes no)
+(NZ (LessEqual cc) yes no) => (LE cc yes no)
+(NZ (LessEqualU cc) yes no) => (ULE cc yes no)
+(NZ (GreaterThan cc) yes no) => (GT cc yes no)
+(NZ (GreaterThanU cc) yes no) => (UGT cc yes no)
+(NZ (GreaterEqual cc) yes no) => (GE cc yes no)
+(NZ (GreaterEqualU cc) yes no) => (UGE cc yes no)
+(NZ (LessThanF cc) yes no) => (FLT cc yes no)
+(NZ (LessEqualF cc) yes no) => (FLE cc yes no)
+(NZ (GreaterThanF cc) yes no) => (FGT cc yes no)
+(NZ (GreaterEqualF cc) yes no) => (FGE cc yes no)
+
+(TBNZ [0] (Equal cc) yes no) => (EQ cc yes no)
+(TBNZ [0] (NotEqual cc) yes no) => (NE cc yes no)
+(TBNZ [0] (LessThan cc) yes no) => (LT cc yes no)
+(TBNZ [0] (LessThanU cc) yes no) => (ULT cc yes no)
+(TBNZ [0] (LessEqual cc) yes no) => (LE cc yes no)
+(TBNZ [0] (LessEqualU cc) yes no) => (ULE cc yes no)
+(TBNZ [0] (GreaterThan cc) yes no) => (GT cc yes no)
+(TBNZ [0] (GreaterThanU cc) yes no) => (UGT cc yes no)
+(TBNZ [0] (GreaterEqual cc) yes no) => (GE cc yes no)
+(TBNZ [0] (GreaterEqualU cc) yes no) => (UGE cc yes no)
+(TBNZ [0] (LessThanF cc) yes no) => (FLT cc yes no)
+(TBNZ [0] (LessEqualF cc) yes no) => (FLE cc yes no)
+(TBNZ [0] (GreaterThanF cc) yes no) => (FGT cc yes no)
+(TBNZ [0] (GreaterEqualF cc) yes no) => (FGE cc yes no)
+
+(EQ (CMPconst [0] z:(AND x y)) yes no) && z.Uses == 1 => (EQ (TST x y) yes no)
+(NE (CMPconst [0] z:(AND x y)) yes no) && z.Uses == 1 => (NE (TST x y) yes no)
+(LT (CMPconst [0] z:(AND x y)) yes no) && z.Uses == 1 => (LT (TST x y) yes no)
+(LE (CMPconst [0] z:(AND x y)) yes no) && z.Uses == 1 => (LE (TST x y) yes no)
+(GT (CMPconst [0] z:(AND x y)) yes no) && z.Uses == 1 => (GT (TST x y) yes no)
+(GE (CMPconst [0] z:(AND x y)) yes no) && z.Uses == 1 => (GE (TST x y) yes no)
+
+(EQ (CMPconst [0] x:(ANDconst [c] y)) yes no) && x.Uses == 1 => (EQ (TSTconst [c] y) yes no)
+(NE (CMPconst [0] x:(ANDconst [c] y)) yes no) && x.Uses == 1 => (NE (TSTconst [c] y) yes no)
+(LT (CMPconst [0] x:(ANDconst [c] y)) yes no) && x.Uses == 1 => (LT (TSTconst [c] y) yes no)
+(LE (CMPconst [0] x:(ANDconst [c] y)) yes no) && x.Uses == 1 => (LE (TSTconst [c] y) yes no)
+(GT (CMPconst [0] x:(ANDconst [c] y)) yes no) && x.Uses == 1 => (GT (TSTconst [c] y) yes no)
+(GE (CMPconst [0] x:(ANDconst [c] y)) yes no) && x.Uses == 1 => (GE (TSTconst [c] y) yes no)
+
+(EQ (CMPWconst [0] z:(AND x y)) yes no) && z.Uses == 1 => (EQ (TSTW x y) yes no)
+(NE (CMPWconst [0] z:(AND x y)) yes no) && z.Uses == 1 => (NE (TSTW x y) yes no)
+(LT (CMPWconst [0] z:(AND x y)) yes no) && z.Uses == 1 => (LT (TSTW x y) yes no)
+(LE (CMPWconst [0] z:(AND x y)) yes no) && z.Uses == 1 => (LE (TSTW x y) yes no)
+(GT (CMPWconst [0] z:(AND x y)) yes no) && z.Uses == 1 => (GT (TSTW x y) yes no)
+(GE (CMPWconst [0] z:(AND x y)) yes no) && z.Uses == 1 => (GE (TSTW x y) yes no)
+
+(EQ (CMPWconst [0] x:(ANDconst [c] y)) yes no) && x.Uses == 1 => (EQ (TSTWconst [int32(c)] y) yes no)
+(NE (CMPWconst [0] x:(ANDconst [c] y)) yes no) && x.Uses == 1 => (NE (TSTWconst [int32(c)] y) yes no)
+(LT (CMPWconst [0] x:(ANDconst [c] y)) yes no) && x.Uses == 1 => (LT (TSTWconst [int32(c)] y) yes no)
+(LE (CMPWconst [0] x:(ANDconst [c] y)) yes no) && x.Uses == 1 => (LE (TSTWconst [int32(c)] y) yes no)
+(GT (CMPWconst [0] x:(ANDconst [c] y)) yes no) && x.Uses == 1 => (GT (TSTWconst [int32(c)] y) yes no)
+(GE (CMPWconst [0] x:(ANDconst [c] y)) yes no) && x.Uses == 1 => (GE (TSTWconst [int32(c)] y) yes no)
+
+// For conditional instructions such as CSET, CSEL.
+(Equal (CMPconst [0] z:(AND x y))) && z.Uses == 1 => (Equal (TST x y))
+(NotEqual (CMPconst [0] z:(AND x y))) && z.Uses == 1 => (NotEqual (TST x y))
+(LessThan (CMPconst [0] z:(AND x y))) && z.Uses == 1 => (LessThan (TST x y))
+(LessEqual (CMPconst [0] z:(AND x y))) && z.Uses == 1 => (LessEqual (TST x y))
+(GreaterThan (CMPconst [0] z:(AND x y))) && z.Uses == 1 => (GreaterThan (TST x y))
+(GreaterEqual (CMPconst [0] z:(AND x y))) && z.Uses == 1 => (GreaterEqual (TST x y))
+
+(Equal (CMPWconst [0] x:(ANDconst [c] y))) && x.Uses == 1 => (Equal (TSTWconst [int32(c)] y))
+(NotEqual (CMPWconst [0] x:(ANDconst [c] y))) && x.Uses == 1 => (NotEqual (TSTWconst [int32(c)] y))
+(LessThan (CMPWconst [0] x:(ANDconst [c] y))) && x.Uses == 1 => (LessThan (TSTWconst [int32(c)] y))
+(LessEqual (CMPWconst [0] x:(ANDconst [c] y))) && x.Uses == 1 => (LessEqual (TSTWconst [int32(c)] y))
+(GreaterThan (CMPWconst [0] x:(ANDconst [c] y))) && x.Uses == 1 => (GreaterThan (TSTWconst [int32(c)] y))
+(GreaterEqual (CMPWconst [0] x:(ANDconst [c] y))) && x.Uses == 1 => (GreaterEqual (TSTWconst [int32(c)] y))
+
+(Equal (CMPWconst [0] z:(AND x y))) && z.Uses == 1 => (Equal (TSTW x y))
+(NotEqual (CMPWconst [0] z:(AND x y))) && z.Uses == 1 => (NotEqual (TSTW x y))
+(LessThan (CMPWconst [0] z:(AND x y))) && z.Uses == 1 => (LessThan (TSTW x y))
+(LessEqual (CMPWconst [0] z:(AND x y))) && z.Uses == 1 => (LessEqual (TSTW x y))
+(GreaterThan (CMPWconst [0] z:(AND x y))) && z.Uses == 1 => (GreaterThan (TSTW x y))
+(GreaterEqual (CMPWconst [0] z:(AND x y))) && z.Uses == 1 => (GreaterEqual (TSTW x y))
+
+(Equal (CMPconst [0] x:(ANDconst [c] y))) && x.Uses == 1 => (Equal (TSTconst [c] y))
+(NotEqual (CMPconst [0] x:(ANDconst [c] y))) && x.Uses == 1 => (NotEqual (TSTconst [c] y))
+(LessThan (CMPWconst [0] x:(ANDconst [c] y))) && x.Uses == 1 => (LessThan (TSTconst [c] y))
+(LessEqual (CMPWconst [0] x:(ANDconst [c] y))) && x.Uses == 1 => (LessEqual (TSTconst [c] y))
+(GreaterThan (CMPWconst [0] x:(ANDconst [c] y))) && x.Uses == 1 => (GreaterThan (TSTconst [c] y))
+(GreaterEqual (CMPWconst [0] x:(ANDconst [c] y))) && x.Uses == 1 => (GreaterEqual (TSTconst [c] y))
+
+(EQ (CMPconst [0] x:(ADDconst [c] y)) yes no) && x.Uses == 1 => (EQ (CMNconst [c] y) yes no)
+(NE (CMPconst [0] x:(ADDconst [c] y)) yes no) && x.Uses == 1 => (NE (CMNconst [c] y) yes no)
+(LT (CMPconst [0] x:(ADDconst [c] y)) yes no) && x.Uses == 1 => (LTnoov (CMNconst [c] y) yes no)
+(LE (CMPconst [0] x:(ADDconst [c] y)) yes no) && x.Uses == 1 => (LEnoov (CMNconst [c] y) yes no)
+(GT (CMPconst [0] x:(ADDconst [c] y)) yes no) && x.Uses == 1 => (GTnoov (CMNconst [c] y) yes no)
+(GE (CMPconst [0] x:(ADDconst [c] y)) yes no) && x.Uses == 1 => (GEnoov (CMNconst [c] y) yes no)
+
+(EQ (CMPWconst [0] x:(ADDconst [c] y)) yes no) && x.Uses == 1 => (EQ (CMNWconst [int32(c)] y) yes no)
+(NE (CMPWconst [0] x:(ADDconst [c] y)) yes no) && x.Uses == 1 => (NE (CMNWconst [int32(c)] y) yes no)
+(LT (CMPWconst [0] x:(ADDconst [c] y)) yes no) && x.Uses == 1 => (LTnoov (CMNWconst [int32(c)] y) yes no)
+(LE (CMPWconst [0] x:(ADDconst [c] y)) yes no) && x.Uses == 1 => (LEnoov (CMNWconst [int32(c)] y) yes no)
+(GT (CMPWconst [0] x:(ADDconst [c] y)) yes no) && x.Uses == 1 => (GTnoov (CMNWconst [int32(c)] y) yes no)
+(GE (CMPWconst [0] x:(ADDconst [c] y)) yes no) && x.Uses == 1 => (GEnoov (CMNWconst [int32(c)] y) yes no)
+
+(EQ (CMPconst [0] z:(ADD x y)) yes no) && z.Uses == 1 => (EQ (CMN x y) yes no)
+(NE (CMPconst [0] z:(ADD x y)) yes no) && z.Uses == 1 => (NE (CMN x y) yes no)
+(LT (CMPconst [0] z:(ADD x y)) yes no) && z.Uses == 1 => (LTnoov (CMN x y) yes no)
+(LE (CMPconst [0] z:(ADD x y)) yes no) && z.Uses == 1 => (LEnoov (CMN x y) yes no)
+(GT (CMPconst [0] z:(ADD x y)) yes no) && z.Uses == 1 => (GTnoov (CMN x y) yes no)
+(GE (CMPconst [0] z:(ADD x y)) yes no) && z.Uses == 1 => (GEnoov (CMN x y) yes no)
+
+(EQ (CMPWconst [0] z:(ADD x y)) yes no) && z.Uses == 1 => (EQ (CMNW x y) yes no)
+(NE (CMPWconst [0] z:(ADD x y)) yes no) && z.Uses == 1 => (NE (CMNW x y) yes no)
+(LT (CMPWconst [0] z:(ADD x y)) yes no) && z.Uses == 1 => (LTnoov (CMNW x y) yes no)
+(LE (CMPWconst [0] z:(ADD x y)) yes no) && z.Uses == 1 => (LEnoov (CMNW x y) yes no)
+(GT (CMPWconst [0] z:(ADD x y)) yes no) && z.Uses == 1 => (GTnoov (CMNW x y) yes no)
+(GE (CMPWconst [0] z:(ADD x y)) yes no) && z.Uses == 1 => (GEnoov (CMNW x y) yes no)
+
+// CMP(x,-y) -> CMN(x,y) is only valid for unordered comparison, if y can be -1<<63
+(EQ (CMP x z:(NEG y)) yes no) && z.Uses == 1 => (EQ (CMN x y) yes no)
+(NE (CMP x z:(NEG y)) yes no) && z.Uses == 1 => (NE (CMN x y) yes no)
+
+(Equal (CMP x z:(NEG y))) && z.Uses == 1 => (Equal (CMN x y))
+(NotEqual (CMP x z:(NEG y))) && z.Uses == 1 => (NotEqual (CMN x y))
+
+// CMPW(x,-y) -> CMNW(x,y) is only valid for unordered comparison, if y can be -1<<31
+(EQ (CMPW x z:(NEG y)) yes no) && z.Uses == 1 => (EQ (CMNW x y) yes no)
+(NE (CMPW x z:(NEG y)) yes no) && z.Uses == 1 => (NE (CMNW x y) yes no)
+
+(Equal (CMPW x z:(NEG y))) && z.Uses == 1 => (Equal (CMNW x y))
+(NotEqual (CMPW x z:(NEG y))) && z.Uses == 1 => (NotEqual (CMNW x y))
+
+// For conditional instructions such as CSET, CSEL.
+// TODO: add support for LT, LE, GT, GE, overflow needs to be considered.
+(Equal (CMPconst [0] x:(ADDconst [c] y))) && x.Uses == 1 => (Equal (CMNconst [c] y))
+(NotEqual (CMPconst [0] x:(ADDconst [c] y))) && x.Uses == 1 => (NotEqual (CMNconst [c] y))
+
+(Equal (CMPWconst [0] x:(ADDconst [c] y))) && x.Uses == 1 => (Equal (CMNWconst [int32(c)] y))
+(NotEqual (CMPWconst [0] x:(ADDconst [c] y))) && x.Uses == 1 => (NotEqual (CMNWconst [int32(c)] y))
+
+(Equal (CMPconst [0] z:(ADD x y))) && z.Uses == 1 => (Equal (CMN x y))
+(NotEqual (CMPconst [0] z:(ADD x y))) && z.Uses == 1 => (NotEqual (CMN x y))
+
+(Equal (CMPWconst [0] z:(ADD x y))) && z.Uses == 1 => (Equal (CMNW x y))
+(NotEqual (CMPWconst [0] z:(ADD x y))) && z.Uses == 1 => (NotEqual (CMNW x y))
+
+(Equal (CMPconst [0] z:(MADD a x y))) && z.Uses==1 => (Equal (CMN a (MUL <x.Type> x y)))
+(NotEqual (CMPconst [0] z:(MADD a x y))) && z.Uses==1 => (NotEqual (CMN a (MUL <x.Type> x y)))
+
+(Equal (CMPconst [0] z:(MSUB a x y))) && z.Uses==1 => (Equal (CMP a (MUL <x.Type> x y)))
+(NotEqual (CMPconst [0] z:(MSUB a x y))) && z.Uses==1 => (NotEqual (CMP a (MUL <x.Type> x y)))
+
+(Equal (CMPWconst [0] z:(MADDW a x y))) && z.Uses==1 => (Equal (CMNW a (MULW <x.Type> x y)))
+(NotEqual (CMPWconst [0] z:(MADDW a x y))) && z.Uses==1 => (NotEqual (CMNW a (MULW <x.Type> x y)))
+
+(Equal (CMPWconst [0] z:(MSUBW a x y))) && z.Uses==1 => (Equal (CMPW a (MULW <x.Type> x y)))
+(NotEqual (CMPWconst [0] z:(MSUBW a x y))) && z.Uses==1 => (NotEqual (CMPW a (MULW <x.Type> x y)))
+
+(CMPconst [c] y) && c < 0 && c != -1<<63 => (CMNconst [-c] y)
+(CMPWconst [c] y) && c < 0 && c != -1<<31 => (CMNWconst [-c] y)
+(CMNconst [c] y) && c < 0 && c != -1<<63 => (CMPconst [-c] y)
+(CMNWconst [c] y) && c < 0 && c != -1<<31 => (CMPWconst [-c] y)
+
+(EQ (CMPconst [0] x) yes no) => (Z x yes no)
+(NE (CMPconst [0] x) yes no) => (NZ x yes no)
+(EQ (CMPWconst [0] x) yes no) => (ZW x yes no)
+(NE (CMPWconst [0] x) yes no) => (NZW x yes no)
+
+(EQ (CMPconst [0]  z:(MADD a x y)) yes no) && z.Uses==1 => (EQ (CMN a (MUL <x.Type> x y)) yes no)
+(NE (CMPconst [0]  z:(MADD a x y)) yes no) && z.Uses==1 => (NE (CMN a (MUL <x.Type> x y)) yes no)
+(LT (CMPconst [0]  z:(MADD a x y)) yes no) && z.Uses==1 => (LTnoov (CMN a (MUL <x.Type> x y)) yes no)
+(LE (CMPconst [0]  z:(MADD a x y)) yes no) && z.Uses==1 => (LEnoov (CMN a (MUL <x.Type> x y)) yes no)
+(GT (CMPconst [0]  z:(MADD a x y)) yes no) && z.Uses==1 => (GTnoov (CMN a (MUL <x.Type> x y)) yes no)
+(GE (CMPconst [0]  z:(MADD a x y)) yes no) && z.Uses==1 => (GEnoov (CMN a (MUL <x.Type> x y)) yes no)
+
+(EQ (CMPconst [0]  z:(MSUB a x y)) yes no) && z.Uses==1 => (EQ (CMP a (MUL <x.Type> x y)) yes no)
+(NE (CMPconst [0]  z:(MSUB a x y)) yes no) && z.Uses==1 => (NE (CMP a (MUL <x.Type> x y)) yes no)
+(LE (CMPconst [0]  z:(MSUB a x y)) yes no) && z.Uses==1 => (LEnoov (CMP a (MUL <x.Type> x y)) yes no)
+(LT (CMPconst [0]  z:(MSUB a x y)) yes no) && z.Uses==1 => (LTnoov (CMP a (MUL <x.Type> x y)) yes no)
+(GE (CMPconst [0]  z:(MSUB a x y)) yes no) && z.Uses==1 => (GEnoov (CMP a (MUL <x.Type> x y)) yes no)
+(GT (CMPconst [0]  z:(MSUB a x y)) yes no) && z.Uses==1 => (GTnoov (CMP a (MUL <x.Type> x y)) yes no)
+
+(EQ (CMPWconst [0] z:(MADDW a x y)) yes no) && z.Uses==1 => (EQ (CMNW a (MULW <x.Type> x y)) yes no)
+(NE (CMPWconst [0] z:(MADDW a x y)) yes no) && z.Uses==1 => (NE (CMNW a (MULW <x.Type> x y)) yes no)
+(LE (CMPWconst [0] z:(MADDW a x y)) yes no) && z.Uses==1 => (LEnoov (CMNW a (MULW <x.Type> x y)) yes no)
+(LT (CMPWconst [0] z:(MADDW a x y)) yes no) && z.Uses==1 => (LTnoov (CMNW a (MULW <x.Type> x y)) yes no)
+(GE (CMPWconst [0] z:(MADDW a x y)) yes no) && z.Uses==1 => (GEnoov (CMNW a (MULW <x.Type> x y)) yes no)
+(GT (CMPWconst [0] z:(MADDW a x y)) yes no) && z.Uses==1 => (GTnoov (CMNW a (MULW <x.Type> x y)) yes no)
+
+(EQ (CMPWconst [0] z:(MSUBW a x y)) yes no) && z.Uses==1 => (EQ (CMPW a (MULW <x.Type> x y)) yes no)
+(NE (CMPWconst [0] z:(MSUBW a x y)) yes no) && z.Uses==1 => (NE (CMPW a (MULW <x.Type> x y)) yes no)
+(LE (CMPWconst [0] z:(MSUBW a x y)) yes no) && z.Uses==1 => (LEnoov (CMPW a (MULW <x.Type> x y)) yes no)
+(LT (CMPWconst [0] z:(MSUBW a x y)) yes no) && z.Uses==1 => (LTnoov (CMPW a (MULW <x.Type> x y)) yes no)
+(GE (CMPWconst [0] z:(MSUBW a x y)) yes no) && z.Uses==1 => (GEnoov (CMPW a (MULW <x.Type> x y)) yes no)
+(GT (CMPWconst [0] z:(MSUBW a x y)) yes no) && z.Uses==1 => (GTnoov (CMPW a (MULW <x.Type> x y)) yes no)
+
+// Absorb bit-tests into block
+(Z  (ANDconst [c] x) yes no) && oneBit(c) => (TBZ  [int64(ntz64(c))] x yes no)
+(NZ (ANDconst [c] x) yes no) && oneBit(c) => (TBNZ [int64(ntz64(c))] x yes no)
+(ZW  (ANDconst [c] x) yes no) && oneBit(int64(uint32(c))) => (TBZ  [int64(ntz64(int64(uint32(c))))] x yes no)
+(NZW (ANDconst [c] x) yes no) && oneBit(int64(uint32(c))) => (TBNZ [int64(ntz64(int64(uint32(c))))] x yes no)
+(EQ (TSTconst [c] x) yes no) && oneBit(c) => (TBZ  [int64(ntz64(c))] x yes no)
+(NE (TSTconst [c] x) yes no) && oneBit(c) => (TBNZ [int64(ntz64(c))] x yes no)
+(EQ (TSTWconst [c] x) yes no) && oneBit(int64(uint32(c))) => (TBZ  [int64(ntz64(int64(uint32(c))))] x yes no)
+(NE (TSTWconst [c] x) yes no) && oneBit(int64(uint32(c))) => (TBNZ [int64(ntz64(int64(uint32(c))))] x yes no)
+
+// Test sign-bit for signed comparisons against zero
+(GE (CMPWconst [0] x) yes no) => (TBZ  [31] x yes no)
+(GE (CMPconst [0] x) yes no) => (TBZ  [63] x yes no)
+(LT (CMPWconst [0] x) yes no) => (TBNZ  [31] x yes no)
+(LT (CMPconst [0] x) yes no) => (TBNZ  [63] x yes no)
+
+// fold offset into address
+(ADDconst [off1] (MOVDaddr [off2] {sym} ptr)) && is32Bit(off1+int64(off2)) =>
+	 (MOVDaddr [int32(off1)+off2] {sym} ptr)
+
+// fold address into load/store
+(MOVBload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) =>
+	(MOVBload [off1+int32(off2)] {sym} ptr mem)
+(MOVBUload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) =>
+	(MOVBUload [off1+int32(off2)] {sym} ptr mem)
+(MOVHload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) =>
+	(MOVHload [off1+int32(off2)] {sym} ptr mem)
+(MOVHUload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) =>
+	(MOVHUload [off1+int32(off2)] {sym} ptr mem)
+(MOVWload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) =>
+	(MOVWload [off1+int32(off2)] {sym} ptr mem)
+(MOVWUload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) =>
+	(MOVWUload [off1+int32(off2)] {sym} ptr mem)
+(MOVDload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) =>
+	(MOVDload [off1+int32(off2)] {sym} ptr mem)
+(LDP [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) =>
+	(LDP [off1+int32(off2)] {sym} ptr mem)
+(FMOVSload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) =>
+	(FMOVSload [off1+int32(off2)] {sym} ptr mem)
+(FMOVDload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) =>
+	(FMOVDload [off1+int32(off2)] {sym} ptr mem)
+
+// register indexed load
+(MOVDload  [off] {sym} (ADD ptr idx) mem) && off == 0 && sym == nil => (MOVDloadidx ptr idx mem)
+(MOVWUload [off] {sym} (ADD ptr idx) mem) && off == 0 && sym == nil => (MOVWUloadidx ptr idx mem)
+(MOVWload  [off] {sym} (ADD ptr idx) mem) && off == 0 && sym == nil => (MOVWloadidx ptr idx mem)
+(MOVHUload [off] {sym} (ADD ptr idx) mem) && off == 0 && sym == nil => (MOVHUloadidx ptr idx mem)
+(MOVHload  [off] {sym} (ADD ptr idx) mem) && off == 0 && sym == nil => (MOVHloadidx ptr idx mem)
+(MOVBUload [off] {sym} (ADD ptr idx) mem) && off == 0 && sym == nil => (MOVBUloadidx ptr idx mem)
+(MOVBload  [off] {sym} (ADD ptr idx) mem) && off == 0 && sym == nil => (MOVBloadidx ptr idx mem)
+(FMOVSload [off] {sym} (ADD ptr idx) mem) && off == 0 && sym == nil => (FMOVSloadidx ptr idx mem)
+(FMOVDload [off] {sym} (ADD ptr idx) mem) && off == 0 && sym == nil => (FMOVDloadidx ptr idx mem)
+(MOVDloadidx  ptr (MOVDconst [c]) mem) && is32Bit(c) => (MOVDload  [int32(c)] ptr mem)
+(MOVDloadidx  (MOVDconst [c]) ptr mem) && is32Bit(c) => (MOVDload  [int32(c)] ptr mem)
+(MOVWUloadidx ptr (MOVDconst [c]) mem) && is32Bit(c) => (MOVWUload [int32(c)] ptr mem)
+(MOVWUloadidx (MOVDconst [c]) ptr mem) && is32Bit(c) => (MOVWUload [int32(c)] ptr mem)
+(MOVWloadidx  ptr (MOVDconst [c]) mem) && is32Bit(c) => (MOVWload  [int32(c)] ptr mem)
+(MOVWloadidx  (MOVDconst [c]) ptr mem) && is32Bit(c) => (MOVWload  [int32(c)] ptr mem)
+(MOVHUloadidx ptr (MOVDconst [c]) mem) && is32Bit(c) => (MOVHUload [int32(c)] ptr mem)
+(MOVHUloadidx (MOVDconst [c]) ptr mem) && is32Bit(c) => (MOVHUload [int32(c)] ptr mem)
+(MOVHloadidx  ptr (MOVDconst [c]) mem) && is32Bit(c) => (MOVHload  [int32(c)] ptr mem)
+(MOVHloadidx  (MOVDconst [c]) ptr mem) && is32Bit(c) => (MOVHload  [int32(c)] ptr mem)
+(MOVBUloadidx ptr (MOVDconst [c]) mem) && is32Bit(c) => (MOVBUload [int32(c)] ptr mem)
+(MOVBUloadidx (MOVDconst [c]) ptr mem) && is32Bit(c) => (MOVBUload [int32(c)] ptr mem)
+(MOVBloadidx  ptr (MOVDconst [c]) mem) && is32Bit(c) => (MOVBload  [int32(c)] ptr mem)
+(MOVBloadidx  (MOVDconst [c]) ptr mem) && is32Bit(c) => (MOVBload  [int32(c)] ptr mem)
+(FMOVSloadidx ptr (MOVDconst [c]) mem) && is32Bit(c) => (FMOVSload [int32(c)] ptr mem)
+(FMOVSloadidx (MOVDconst [c]) ptr mem) && is32Bit(c) => (FMOVSload [int32(c)] ptr mem)
+(FMOVDloadidx ptr (MOVDconst [c]) mem) && is32Bit(c) => (FMOVDload [int32(c)] ptr mem)
+(FMOVDloadidx (MOVDconst [c]) ptr mem) && is32Bit(c) => (FMOVDload [int32(c)] ptr mem)
+
+// shifted register indexed load
+(MOVDload  [off] {sym} (ADDshiftLL [3] ptr idx) mem) && off == 0 && sym == nil => (MOVDloadidx8 ptr idx mem)
+(MOVWUload [off] {sym} (ADDshiftLL [2] ptr idx) mem) && off == 0 && sym == nil => (MOVWUloadidx4 ptr idx mem)
+(MOVWload  [off] {sym} (ADDshiftLL [2] ptr idx) mem) && off == 0 && sym == nil => (MOVWloadidx4 ptr idx mem)
+(MOVHUload [off] {sym} (ADDshiftLL [1] ptr idx) mem) && off == 0 && sym == nil => (MOVHUloadidx2 ptr idx mem)
+(MOVHload  [off] {sym} (ADDshiftLL [1] ptr idx) mem) && off == 0 && sym == nil => (MOVHloadidx2 ptr idx mem)
+(MOVDloadidx  ptr (SLLconst [3] idx) mem) => (MOVDloadidx8 ptr idx mem)
+(MOVWloadidx  ptr (SLLconst [2] idx) mem) => (MOVWloadidx4 ptr idx mem)
+(MOVWUloadidx ptr (SLLconst [2] idx) mem) => (MOVWUloadidx4 ptr idx mem)
+(MOVHloadidx  ptr (SLLconst [1] idx) mem) => (MOVHloadidx2 ptr idx mem)
+(MOVHUloadidx ptr (SLLconst [1] idx) mem) => (MOVHUloadidx2 ptr idx mem)
+(MOVHloadidx  ptr (ADD idx idx) mem) => (MOVHloadidx2 ptr idx mem)
+(MOVHUloadidx ptr (ADD idx idx) mem) => (MOVHUloadidx2 ptr idx mem)
+(MOVDloadidx  (SLLconst [3] idx) ptr mem) => (MOVDloadidx8 ptr idx mem)
+(MOVWloadidx  (SLLconst [2] idx) ptr mem) => (MOVWloadidx4 ptr idx mem)
+(MOVWUloadidx (SLLconst [2] idx) ptr mem) => (MOVWUloadidx4 ptr idx mem)
+(MOVHloadidx  (ADD idx idx) ptr mem) => (MOVHloadidx2 ptr idx mem)
+(MOVHUloadidx (ADD idx idx) ptr mem) => (MOVHUloadidx2 ptr idx mem)
+(MOVDloadidx8  ptr (MOVDconst [c]) mem) && is32Bit(c<<3) => (MOVDload  [int32(c)<<3] ptr mem)
+(MOVWUloadidx4 ptr (MOVDconst [c]) mem) && is32Bit(c<<2) => (MOVWUload [int32(c)<<2] ptr mem)
+(MOVWloadidx4  ptr (MOVDconst [c]) mem) && is32Bit(c<<2) => (MOVWload  [int32(c)<<2] ptr mem)
+(MOVHUloadidx2 ptr (MOVDconst [c]) mem) && is32Bit(c<<1) => (MOVHUload [int32(c)<<1] ptr mem)
+(MOVHloadidx2  ptr (MOVDconst [c]) mem) && is32Bit(c<<1) => (MOVHload  [int32(c)<<1] ptr mem)
+
+(FMOVDload [off] {sym} (ADDshiftLL [3] ptr idx) mem) && off == 0 && sym == nil => (FMOVDloadidx8 ptr idx mem)
+(FMOVSload [off] {sym} (ADDshiftLL [2] ptr idx) mem) && off == 0 && sym == nil => (FMOVSloadidx4 ptr idx mem)
+(FMOVDloadidx ptr (SLLconst [3] idx) mem) => (FMOVDloadidx8 ptr idx mem)
+(FMOVSloadidx ptr (SLLconst [2] idx) mem) => (FMOVSloadidx4 ptr idx mem)
+(FMOVDloadidx (SLLconst [3] idx) ptr mem) => (FMOVDloadidx8 ptr idx mem)
+(FMOVSloadidx (SLLconst [2] idx) ptr mem) => (FMOVSloadidx4 ptr idx mem)
+(FMOVDloadidx8 ptr (MOVDconst [c]) mem) && is32Bit(c<<3) => (FMOVDload ptr [int32(c)<<3] mem)
+(FMOVSloadidx4 ptr (MOVDconst [c]) mem) && is32Bit(c<<2) => (FMOVSload ptr [int32(c)<<2] mem)
+
+(MOVBstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) =>
+	(MOVBstore [off1+int32(off2)] {sym} ptr val mem)
+(MOVHstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) =>
+	(MOVHstore [off1+int32(off2)] {sym} ptr val mem)
+(MOVWstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) =>
+	(MOVWstore [off1+int32(off2)] {sym} ptr val mem)
+(MOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) =>
+	(MOVDstore [off1+int32(off2)] {sym} ptr val mem)
+(STP [off1] {sym} (ADDconst [off2] ptr) val1 val2 mem) && is32Bit(int64(off1)+off2) =>
+	(STP [off1+int32(off2)] {sym} ptr val1 val2 mem)
+(FMOVSstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) =>
+	(FMOVSstore [off1+int32(off2)] {sym} ptr val mem)
+(FMOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) =>
+	(FMOVDstore [off1+int32(off2)] {sym} ptr val mem)
+(MOVBstorezero [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) =>
+	(MOVBstorezero [off1+int32(off2)] {sym} ptr mem)
+(MOVHstorezero [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) =>
+	(MOVHstorezero [off1+int32(off2)] {sym} ptr mem)
+(MOVWstorezero [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) =>
+	(MOVWstorezero [off1+int32(off2)] {sym} ptr mem)
+(MOVDstorezero [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) =>
+	(MOVDstorezero [off1+int32(off2)] {sym} ptr mem)
+(MOVQstorezero [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) =>
+	(MOVQstorezero [off1+int32(off2)] {sym} ptr mem)
+
+// register indexed store
+(MOVDstore [off] {sym} (ADD ptr idx) val mem) && off == 0 && sym == nil => (MOVDstoreidx ptr idx val mem)
+(MOVWstore [off] {sym} (ADD ptr idx) val mem) && off == 0 && sym == nil => (MOVWstoreidx ptr idx val mem)
+(MOVHstore [off] {sym} (ADD ptr idx) val mem) && off == 0 && sym == nil => (MOVHstoreidx ptr idx val mem)
+(MOVBstore [off] {sym} (ADD ptr idx) val mem) && off == 0 && sym == nil => (MOVBstoreidx ptr idx val mem)
+(FMOVDstore [off] {sym} (ADD ptr idx) val mem) && off == 0 && sym == nil => (FMOVDstoreidx ptr idx val mem)
+(FMOVSstore [off] {sym} (ADD ptr idx) val mem) && off == 0 && sym == nil => (FMOVSstoreidx ptr idx val mem)
+(MOVDstoreidx ptr (MOVDconst [c]) val mem) && is32Bit(c) => (MOVDstore [int32(c)] ptr val mem)
+(MOVDstoreidx (MOVDconst [c]) idx val mem) && is32Bit(c) => (MOVDstore [int32(c)] idx val mem)
+(MOVWstoreidx ptr (MOVDconst [c]) val mem) && is32Bit(c) => (MOVWstore [int32(c)] ptr val mem)
+(MOVWstoreidx (MOVDconst [c]) idx val mem) && is32Bit(c) => (MOVWstore [int32(c)] idx val mem)
+(MOVHstoreidx ptr (MOVDconst [c]) val mem) && is32Bit(c) => (MOVHstore [int32(c)] ptr val mem)
+(MOVHstoreidx (MOVDconst [c]) idx val mem) && is32Bit(c) => (MOVHstore [int32(c)] idx val mem)
+(MOVBstoreidx ptr (MOVDconst [c]) val mem) && is32Bit(c) => (MOVBstore [int32(c)] ptr val mem)
+(MOVBstoreidx (MOVDconst [c]) idx val mem) && is32Bit(c) => (MOVBstore [int32(c)] idx val mem)
+(FMOVDstoreidx ptr (MOVDconst [c]) val mem) && is32Bit(c) => (FMOVDstore [int32(c)] ptr val mem)
+(FMOVDstoreidx (MOVDconst [c]) idx val mem) && is32Bit(c) => (FMOVDstore [int32(c)] idx val mem)
+(FMOVSstoreidx ptr (MOVDconst [c]) val mem) && is32Bit(c) => (FMOVSstore [int32(c)] ptr val mem)
+(FMOVSstoreidx (MOVDconst [c]) idx val mem) && is32Bit(c) => (FMOVSstore [int32(c)] idx val mem)
+
+// shifted register indexed store
+(MOVDstore [off] {sym} (ADDshiftLL [3] ptr idx) val mem) && off == 0 && sym == nil => (MOVDstoreidx8 ptr idx val mem)
+(MOVWstore [off] {sym} (ADDshiftLL [2] ptr idx) val mem) && off == 0 && sym == nil => (MOVWstoreidx4 ptr idx val mem)
+(MOVHstore [off] {sym} (ADDshiftLL [1] ptr idx) val mem) && off == 0 && sym == nil => (MOVHstoreidx2 ptr idx val mem)
+(MOVDstoreidx ptr (SLLconst [3] idx) val mem) => (MOVDstoreidx8 ptr idx val mem)
+(MOVWstoreidx ptr (SLLconst [2] idx) val mem) => (MOVWstoreidx4 ptr idx val mem)
+(MOVHstoreidx ptr (SLLconst [1] idx) val mem) => (MOVHstoreidx2 ptr idx val mem)
+(MOVHstoreidx ptr (ADD idx idx) val mem) => (MOVHstoreidx2 ptr idx val mem)
+(MOVDstoreidx (SLLconst [3] idx) ptr val mem) => (MOVDstoreidx8 ptr idx val mem)
+(MOVWstoreidx (SLLconst [2] idx) ptr val mem) => (MOVWstoreidx4 ptr idx val mem)
+(MOVHstoreidx (SLLconst [1] idx) ptr val mem) => (MOVHstoreidx2 ptr idx val mem)
+(MOVHstoreidx (ADD idx idx) ptr val mem) => (MOVHstoreidx2 ptr idx val mem)
+(MOVDstoreidx8 ptr (MOVDconst [c]) val mem) && is32Bit(c<<3) => (MOVDstore [int32(c)<<3] ptr val mem)
+(MOVWstoreidx4 ptr (MOVDconst [c]) val mem) && is32Bit(c<<2) => (MOVWstore [int32(c)<<2] ptr val mem)
+(MOVHstoreidx2 ptr (MOVDconst [c]) val mem) && is32Bit(c<<1) => (MOVHstore [int32(c)<<1] ptr val mem)
+
+(FMOVDstore [off] {sym} (ADDshiftLL [3] ptr idx) val mem) && off == 0 && sym == nil => (FMOVDstoreidx8 ptr idx val mem)
+(FMOVSstore [off] {sym} (ADDshiftLL [2] ptr idx) val mem) && off == 0 && sym == nil => (FMOVSstoreidx4 ptr idx val mem)
+(FMOVDstoreidx ptr (SLLconst [3] idx) val mem) => (FMOVDstoreidx8 ptr idx val mem)
+(FMOVSstoreidx ptr (SLLconst [2] idx) val mem) => (FMOVSstoreidx4 ptr idx val mem)
+(FMOVDstoreidx (SLLconst [3] idx) ptr val mem) => (FMOVDstoreidx8 ptr idx val mem)
+(FMOVSstoreidx (SLLconst [2] idx) ptr val mem) => (FMOVSstoreidx4 ptr idx val mem)
+(FMOVDstoreidx8 ptr (MOVDconst [c]) val mem) && is32Bit(c<<3) => (FMOVDstore [int32(c)<<3] ptr val mem)
+(FMOVSstoreidx4 ptr (MOVDconst [c]) val mem) && is32Bit(c<<2) => (FMOVSstore [int32(c)<<2] ptr val mem)
+
+(MOVBload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
+	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVBload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+(MOVBUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
+	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVBUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+(MOVHload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
+	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVHload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+(MOVHUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
+	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVHUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+(MOVWload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
+	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVWload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+(MOVWUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
+	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVWUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+(MOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
+	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+(LDP [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
+	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(LDP [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+(FMOVSload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
+	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(FMOVSload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+(FMOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
+	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(FMOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+
+(MOVBstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
+	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVBstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
+(MOVHstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
+	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVHstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
+(MOVWstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
+	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVWstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
+(MOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
+	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
+(STP [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val1 val2 mem)
+	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(STP [off1+off2] {mergeSym(sym1,sym2)} ptr val1 val2 mem)
+(FMOVSstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
+	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(FMOVSstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
+(FMOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
+	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(FMOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
+(MOVBstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
+	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVBstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+(MOVHstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
+	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVHstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+(MOVWstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
+	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVWstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+(MOVDstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
+	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVDstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+(MOVQstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
+	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVQstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+
+// store zero
+(MOVBstore [off] {sym} ptr (MOVDconst [0]) mem) => (MOVBstorezero [off] {sym} ptr mem)
+(MOVHstore [off] {sym} ptr (MOVDconst [0]) mem) => (MOVHstorezero [off] {sym} ptr mem)
+(MOVWstore [off] {sym} ptr (MOVDconst [0]) mem) => (MOVWstorezero [off] {sym} ptr mem)
+(MOVDstore [off] {sym} ptr (MOVDconst [0]) mem) => (MOVDstorezero [off] {sym} ptr mem)
+(STP [off] {sym} ptr (MOVDconst [0]) (MOVDconst [0]) mem) => (MOVQstorezero [off] {sym} ptr mem)
+
+// register indexed store zero
+(MOVDstorezero [off] {sym} (ADD ptr idx) mem) && off == 0 && sym == nil => (MOVDstorezeroidx ptr idx mem)
+(MOVWstorezero [off] {sym} (ADD ptr idx) mem) && off == 0 && sym == nil => (MOVWstorezeroidx ptr idx mem)
+(MOVHstorezero [off] {sym} (ADD ptr idx) mem) && off == 0 && sym == nil => (MOVHstorezeroidx ptr idx mem)
+(MOVBstorezero [off] {sym} (ADD ptr idx) mem) && off == 0 && sym == nil => (MOVBstorezeroidx ptr idx mem)
+(MOVDstoreidx ptr idx (MOVDconst [0]) mem) => (MOVDstorezeroidx ptr idx mem)
+(MOVWstoreidx ptr idx (MOVDconst [0]) mem) => (MOVWstorezeroidx ptr idx mem)
+(MOVHstoreidx ptr idx (MOVDconst [0]) mem) => (MOVHstorezeroidx ptr idx mem)
+(MOVBstoreidx ptr idx (MOVDconst [0]) mem) => (MOVBstorezeroidx ptr idx mem)
+(MOVDstorezeroidx ptr (MOVDconst [c]) mem) && is32Bit(c) => (MOVDstorezero [int32(c)] ptr mem)
+(MOVDstorezeroidx (MOVDconst [c]) idx mem) && is32Bit(c) => (MOVDstorezero [int32(c)] idx mem)
+(MOVWstorezeroidx ptr (MOVDconst [c]) mem) && is32Bit(c) => (MOVWstorezero [int32(c)] ptr mem)
+(MOVWstorezeroidx (MOVDconst [c]) idx mem) && is32Bit(c) => (MOVWstorezero [int32(c)] idx mem)
+(MOVHstorezeroidx ptr (MOVDconst [c]) mem) && is32Bit(c) => (MOVHstorezero [int32(c)] ptr mem)
+(MOVHstorezeroidx (MOVDconst [c]) idx mem) && is32Bit(c) => (MOVHstorezero [int32(c)] idx mem)
+(MOVBstorezeroidx ptr (MOVDconst [c]) mem) && is32Bit(c) => (MOVBstorezero [int32(c)] ptr mem)
+(MOVBstorezeroidx (MOVDconst [c]) idx mem) && is32Bit(c) => (MOVBstorezero [int32(c)] idx mem)
+
+// shifted register indexed store zero
+(MOVDstorezero [off] {sym} (ADDshiftLL [3] ptr idx) mem) && off == 0 && sym == nil => (MOVDstorezeroidx8 ptr idx mem)
+(MOVWstorezero [off] {sym} (ADDshiftLL [2] ptr idx) mem) && off == 0 && sym == nil => (MOVWstorezeroidx4 ptr idx mem)
+(MOVHstorezero [off] {sym} (ADDshiftLL [1] ptr idx) mem) && off == 0 && sym == nil => (MOVHstorezeroidx2 ptr idx mem)
+(MOVDstorezeroidx ptr (SLLconst [3] idx) mem) => (MOVDstorezeroidx8 ptr idx mem)
+(MOVWstorezeroidx ptr (SLLconst [2] idx) mem) => (MOVWstorezeroidx4 ptr idx mem)
+(MOVHstorezeroidx ptr (SLLconst [1] idx) mem) => (MOVHstorezeroidx2 ptr idx mem)
+(MOVHstorezeroidx ptr (ADD idx idx) mem) => (MOVHstorezeroidx2 ptr idx mem)
+(MOVDstorezeroidx (SLLconst [3] idx) ptr mem) => (MOVDstorezeroidx8 ptr idx mem)
+(MOVWstorezeroidx (SLLconst [2] idx) ptr mem) => (MOVWstorezeroidx4 ptr idx mem)
+(MOVHstorezeroidx (SLLconst [1] idx) ptr mem) => (MOVHstorezeroidx2 ptr idx mem)
+(MOVHstorezeroidx (ADD idx idx) ptr mem) => (MOVHstorezeroidx2 ptr idx mem)
+(MOVDstoreidx8 ptr idx (MOVDconst [0]) mem) => (MOVDstorezeroidx8 ptr idx mem)
+(MOVWstoreidx4 ptr idx (MOVDconst [0]) mem) => (MOVWstorezeroidx4 ptr idx mem)
+(MOVHstoreidx2 ptr idx (MOVDconst [0]) mem) => (MOVHstorezeroidx2 ptr idx mem)
+(MOVDstorezeroidx8 ptr (MOVDconst [c]) mem) && is32Bit(c<<3) => (MOVDstorezero [int32(c<<3)] ptr mem)
+(MOVWstorezeroidx4 ptr (MOVDconst [c]) mem) && is32Bit(c<<2) => (MOVWstorezero [int32(c<<2)] ptr mem)
+(MOVHstorezeroidx2 ptr (MOVDconst [c]) mem) && is32Bit(c<<1) => (MOVHstorezero [int32(c<<1)] ptr mem)
+
+// replace load from same location as preceding store with zero/sign extension (or copy in case of full width)
+// these seem to have bad interaction with other rules, resulting in slower code
+//(MOVBload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> (MOVBreg x)
+//(MOVBUload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> (MOVBUreg x)
+//(MOVHload [off] {sym} ptr (MOVHstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> (MOVHreg x)
+//(MOVHUload [off] {sym} ptr (MOVHstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> (MOVHUreg x)
+//(MOVWload [off] {sym} ptr (MOVWstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> (MOVWreg x)
+//(MOVWUload [off] {sym} ptr (MOVWstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> (MOVWUreg x)
+//(MOVDload [off] {sym} ptr (MOVDstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> x
+//(LDP [off] {sym} ptr (STP [off2] {sym2} ptr2 x y _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> x y
+//(FMOVSload [off] {sym} ptr (FMOVSstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> x
+//(FMOVDload [off] {sym} ptr (FMOVDstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> x
+
+(MOVBload [off] {sym} ptr (MOVBstorezero [off2] {sym2} ptr2 _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVDconst [0])
+(MOVBUload [off] {sym} ptr (MOVBstorezero [off2] {sym2} ptr2 _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVDconst [0])
+(MOVHload [off] {sym} ptr (MOVHstorezero [off2] {sym2} ptr2 _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVDconst [0])
+(MOVHUload [off] {sym} ptr (MOVHstorezero [off2] {sym2} ptr2 _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVDconst [0])
+(MOVWload [off] {sym} ptr (MOVWstorezero [off2] {sym2} ptr2 _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVDconst [0])
+(MOVWUload [off] {sym} ptr (MOVWstorezero [off2] {sym2} ptr2 _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVDconst [0])
+(MOVDload [off] {sym} ptr (MOVDstorezero [off2] {sym2} ptr2 _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVDconst [0])
+
+(MOVBloadidx ptr idx (MOVBstorezeroidx ptr2 idx2 _))
+	&& (isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2)) => (MOVDconst [0])
+(MOVBUloadidx ptr idx (MOVBstorezeroidx ptr2 idx2 _))
+	&& (isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2)) => (MOVDconst [0])
+(MOVHloadidx ptr idx (MOVHstorezeroidx ptr2 idx2 _))
+	&& (isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2)) => (MOVDconst [0])
+(MOVHUloadidx ptr idx (MOVHstorezeroidx ptr2 idx2 _))
+	&& (isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2)) => (MOVDconst [0])
+(MOVWloadidx ptr idx (MOVWstorezeroidx ptr2 idx2 _))
+	&& (isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2)) => (MOVDconst [0])
+(MOVWUloadidx ptr idx (MOVWstorezeroidx ptr2 idx2 _))
+	&& (isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2)) => (MOVDconst [0])
+(MOVDloadidx ptr idx (MOVDstorezeroidx ptr2 idx2 _))
+	&& (isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2)) => (MOVDconst [0])
+
+(MOVHloadidx2 ptr idx (MOVHstorezeroidx2 ptr2 idx2 _)) && isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) => (MOVDconst [0])
+(MOVHUloadidx2 ptr idx (MOVHstorezeroidx2 ptr2 idx2 _)) && isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) => (MOVDconst [0])
+(MOVWloadidx4 ptr idx (MOVWstorezeroidx4 ptr2 idx2 _)) && isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) => (MOVDconst [0])
+(MOVWUloadidx4 ptr idx (MOVWstorezeroidx4 ptr2 idx2 _)) && isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) => (MOVDconst [0])
+(MOVDloadidx8 ptr idx (MOVDstorezeroidx8 ptr2 idx2 _)) && isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) => (MOVDconst [0])
+
+// don't extend after proper load
+(MOVBreg x:(MOVBload _ _)) => (MOVDreg x)
+(MOVBUreg x:(MOVBUload _ _)) => (MOVDreg x)
+(MOVHreg x:(MOVBload _ _)) => (MOVDreg x)
+(MOVHreg x:(MOVBUload _ _)) => (MOVDreg x)
+(MOVHreg x:(MOVHload _ _)) => (MOVDreg x)
+(MOVHUreg x:(MOVBUload _ _)) => (MOVDreg x)
+(MOVHUreg x:(MOVHUload _ _)) => (MOVDreg x)
+(MOVWreg x:(MOVBload _ _)) => (MOVDreg x)
+(MOVWreg x:(MOVBUload _ _)) => (MOVDreg x)
+(MOVWreg x:(MOVHload _ _)) => (MOVDreg x)
+(MOVWreg x:(MOVHUload _ _)) => (MOVDreg x)
+(MOVWreg x:(MOVWload _ _)) => (MOVDreg x)
+(MOVWUreg x:(MOVBUload _ _)) => (MOVDreg x)
+(MOVWUreg x:(MOVHUload _ _)) => (MOVDreg x)
+(MOVWUreg x:(MOVWUload _ _)) => (MOVDreg x)
+(MOVBreg x:(MOVBloadidx _  _ _)) => (MOVDreg x)
+(MOVBUreg x:(MOVBUloadidx _ _ _)) => (MOVDreg x)
+(MOVHreg x:(MOVBloadidx _ _ _)) => (MOVDreg x)
+(MOVHreg x:(MOVBUloadidx _ _ _)) => (MOVDreg x)
+(MOVHreg x:(MOVHloadidx _ _ _)) => (MOVDreg x)
+(MOVHUreg x:(MOVBUloadidx _ _ _)) => (MOVDreg x)
+(MOVHUreg x:(MOVHUloadidx _ _ _)) => (MOVDreg x)
+(MOVWreg x:(MOVBloadidx _ _ _)) => (MOVDreg x)
+(MOVWreg x:(MOVBUloadidx _ _ _)) => (MOVDreg x)
+(MOVWreg x:(MOVHloadidx _ _ _)) => (MOVDreg x)
+(MOVWreg x:(MOVHUloadidx _ _ _)) => (MOVDreg x)
+(MOVWreg x:(MOVWloadidx _ _ _)) => (MOVDreg x)
+(MOVWUreg x:(MOVBUloadidx _ _ _)) => (MOVDreg x)
+(MOVWUreg x:(MOVHUloadidx _ _ _)) => (MOVDreg x)
+(MOVWUreg x:(MOVWUloadidx _ _ _)) => (MOVDreg x)
+(MOVHreg x:(MOVHloadidx2 _ _ _)) => (MOVDreg x)
+(MOVHUreg x:(MOVHUloadidx2 _ _ _)) => (MOVDreg x)
+(MOVWreg x:(MOVHloadidx2 _ _ _)) => (MOVDreg x)
+(MOVWreg x:(MOVHUloadidx2 _ _ _)) => (MOVDreg x)
+(MOVWreg x:(MOVWloadidx4 _ _ _)) => (MOVDreg x)
+(MOVWUreg x:(MOVHUloadidx2 _ _ _)) => (MOVDreg x)
+(MOVWUreg x:(MOVWUloadidx4 _ _ _)) => (MOVDreg x)
+
+// fold double extensions
+(MOVBreg x:(MOVBreg _)) => (MOVDreg x)
+(MOVBUreg x:(MOVBUreg _)) => (MOVDreg x)
+(MOVHreg x:(MOVBreg _)) => (MOVDreg x)
+(MOVHreg x:(MOVBUreg _)) => (MOVDreg x)
+(MOVHreg x:(MOVHreg _)) => (MOVDreg x)
+(MOVHUreg x:(MOVBUreg _)) => (MOVDreg x)
+(MOVHUreg x:(MOVHUreg _)) => (MOVDreg x)
+(MOVWreg x:(MOVBreg _)) => (MOVDreg x)
+(MOVWreg x:(MOVBUreg _)) => (MOVDreg x)
+(MOVWreg x:(MOVHreg _)) => (MOVDreg x)
+(MOVWreg x:(MOVWreg _)) => (MOVDreg x)
+(MOVWUreg x:(MOVBUreg _)) => (MOVDreg x)
+(MOVWUreg x:(MOVHUreg _)) => (MOVDreg x)
+(MOVWUreg x:(MOVWUreg _)) => (MOVDreg x)
+
+// don't extend before store
+(MOVBstore [off] {sym} ptr (MOVBreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr (MOVBUreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr (MOVHreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr (MOVHUreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr (MOVWreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr (MOVWUreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
+(MOVHstore [off] {sym} ptr (MOVHreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
+(MOVHstore [off] {sym} ptr (MOVHUreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
+(MOVHstore [off] {sym} ptr (MOVWreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
+(MOVHstore [off] {sym} ptr (MOVWUreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
+(MOVWstore [off] {sym} ptr (MOVWreg x) mem) => (MOVWstore [off] {sym} ptr x mem)
+(MOVWstore [off] {sym} ptr (MOVWUreg x) mem) => (MOVWstore [off] {sym} ptr x mem)
+(MOVBstoreidx ptr idx (MOVBreg x) mem) => (MOVBstoreidx ptr idx x mem)
+(MOVBstoreidx ptr idx (MOVBUreg x) mem) => (MOVBstoreidx ptr idx x mem)
+(MOVBstoreidx ptr idx (MOVHreg x) mem) => (MOVBstoreidx ptr idx x mem)
+(MOVBstoreidx ptr idx (MOVHUreg x) mem) => (MOVBstoreidx ptr idx x mem)
+(MOVBstoreidx ptr idx (MOVWreg x) mem) => (MOVBstoreidx ptr idx x mem)
+(MOVBstoreidx ptr idx (MOVWUreg x) mem) => (MOVBstoreidx ptr idx x mem)
+(MOVHstoreidx ptr idx (MOVHreg x) mem) => (MOVHstoreidx ptr idx x mem)
+(MOVHstoreidx ptr idx (MOVHUreg x) mem) => (MOVHstoreidx ptr idx x mem)
+(MOVHstoreidx ptr idx (MOVWreg x) mem) => (MOVHstoreidx ptr idx x mem)
+(MOVHstoreidx ptr idx (MOVWUreg x) mem) => (MOVHstoreidx ptr idx x mem)
+(MOVWstoreidx ptr idx (MOVWreg x) mem) => (MOVWstoreidx ptr idx x mem)
+(MOVWstoreidx ptr idx (MOVWUreg x) mem) => (MOVWstoreidx ptr idx x mem)
+(MOVHstoreidx2 ptr idx (MOVHreg x) mem) => (MOVHstoreidx2 ptr idx x mem)
+(MOVHstoreidx2 ptr idx (MOVHUreg x) mem) => (MOVHstoreidx2 ptr idx x mem)
+(MOVHstoreidx2 ptr idx (MOVWreg x) mem) => (MOVHstoreidx2 ptr idx x mem)
+(MOVHstoreidx2 ptr idx (MOVWUreg x) mem) => (MOVHstoreidx2 ptr idx x mem)
+(MOVWstoreidx4 ptr idx (MOVWreg x) mem) => (MOVWstoreidx4 ptr idx x mem)
+(MOVWstoreidx4 ptr idx (MOVWUreg x) mem) => (MOVWstoreidx4 ptr idx x mem)
+
+// if a register move has only 1 use, just use the same register without emitting instruction
+// MOVDnop doesn't emit instruction, only for ensuring the type.
+(MOVDreg x) && x.Uses == 1 => (MOVDnop x)
+
+// TODO: we should be able to get rid of MOVDnop all together.
+// But for now, this is enough to get rid of lots of them.
+(MOVDnop (MOVDconst [c])) => (MOVDconst [c])
+
+// fold constant into arithmetic ops
+(ADD x (MOVDconst [c])) => (ADDconst [c] x)
+(SUB x (MOVDconst [c])) => (SUBconst [c] x)
+(AND x (MOVDconst [c])) => (ANDconst [c] x)
+(OR  x (MOVDconst [c])) => (ORconst  [c] x)
+(XOR x (MOVDconst [c])) => (XORconst [c] x)
+(TST x (MOVDconst [c])) => (TSTconst [c] x)
+(TSTW x (MOVDconst [c])) => (TSTWconst [int32(c)] x)
+(CMN x (MOVDconst [c])) => (CMNconst [c] x)
+(CMNW x (MOVDconst [c])) => (CMNWconst [int32(c)] x)
+(BIC x (MOVDconst [c])) => (ANDconst [^c] x)
+(EON x (MOVDconst [c])) => (XORconst [^c] x)
+(ORN x (MOVDconst [c])) => (ORconst  [^c] x)
+
+(SLL x (MOVDconst [c])) => (SLLconst x [c&63])
+(SRL x (MOVDconst [c])) => (SRLconst x [c&63])
+(SRA x (MOVDconst [c])) => (SRAconst x [c&63])
+(SLL x (ANDconst [63] y)) => (SLL x y)
+(SRL x (ANDconst [63] y)) => (SRL x y)
+(SRA x (ANDconst [63] y)) => (SRA x y)
+
+(CMP x (MOVDconst [c])) => (CMPconst [c] x)
+(CMP (MOVDconst [c]) x) => (InvertFlags (CMPconst [c] x))
+(CMPW x (MOVDconst [c])) => (CMPWconst [int32(c)] x)
+(CMPW (MOVDconst [c]) x) => (InvertFlags (CMPWconst [int32(c)] x))
+
+(ROR x (MOVDconst [c])) => (RORconst x [c&63])
+(RORW x (MOVDconst [c])) => (RORWconst x [c&31])
+
+(ADDSflags x (MOVDconst [c]))  => (ADDSconstflags [c] x)
+
+(ADDconst [c] y) && c < 0 => (SUBconst [-c] y)
+
+// Canonicalize the order of arguments to comparisons - helps with CSE.
+((CMP|CMPW) x y) && canonLessThan(x,y) => (InvertFlags ((CMP|CMPW) y x))
+
+// mul-neg => mneg
+(NEG (MUL x y)) => (MNEG x y)
+(NEG (MULW x y)) => (MNEGW x y)
+(MUL (NEG x) y) => (MNEG x y)
+(MULW (NEG x) y) => (MNEGW x y)
+
+// madd/msub
+(ADD a l:(MUL  x y)) && l.Uses==1 && clobber(l) => (MADD a x y)
+(SUB a l:(MUL  x y)) && l.Uses==1 && clobber(l) => (MSUB a x y)
+(ADD a l:(MNEG x y)) && l.Uses==1 && clobber(l) => (MSUB a x y)
+(SUB a l:(MNEG x y)) && l.Uses==1 && clobber(l) => (MADD a x y)
+
+(ADD a l:(MULW  x y)) && a.Type.Size() != 8 && l.Uses==1 && clobber(l) => (MADDW a x y)
+(SUB a l:(MULW  x y)) && a.Type.Size() != 8 && l.Uses==1 && clobber(l) => (MSUBW a x y)
+(ADD a l:(MNEGW x y)) && a.Type.Size() != 8 && l.Uses==1 && clobber(l) => (MSUBW a x y)
+(SUB a l:(MNEGW x y)) && a.Type.Size() != 8 && l.Uses==1 && clobber(l) => (MADDW a x y)
+
+// optimize ADCSflags, SBCSflags and friends
+(ADCSflags x y (Select1 <types.TypeFlags> (ADDSconstflags [-1] (ADCzerocarry <typ.UInt64> c)))) => (ADCSflags x y c)
+(ADCSflags x y (Select1 <types.TypeFlags> (ADDSconstflags [-1] (MOVDconst [0])))) => (ADDSflags x y)
+(SBCSflags x y (Select1 <types.TypeFlags> (NEGSflags (NEG <typ.UInt64> (NGCzerocarry <typ.UInt64> bo))))) => (SBCSflags x y bo)
+(SBCSflags x y (Select1 <types.TypeFlags> (NEGSflags (MOVDconst [0])))) => (SUBSflags x y)
+
+// mul by constant
+(MUL x (MOVDconst [-1])) => (NEG x)
+(MUL _ (MOVDconst [0])) => (MOVDconst [0])
+(MUL x (MOVDconst [1])) => x
+(MUL x (MOVDconst [c])) && isPowerOfTwo64(c) => (SLLconst [log64(c)] x)
+(MUL x (MOVDconst [c])) && isPowerOfTwo64(c-1) && c >= 3 => (ADDshiftLL x x [log64(c-1)])
+(MUL x (MOVDconst [c])) && isPowerOfTwo64(c+1) && c >= 7 => (ADDshiftLL (NEG <x.Type> x) x [log64(c+1)])
+(MUL x (MOVDconst [c])) && c%3 == 0 && isPowerOfTwo64(c/3) => (SLLconst [log64(c/3)] (ADDshiftLL <x.Type> x x [1]))
+(MUL x (MOVDconst [c])) && c%5 == 0 && isPowerOfTwo64(c/5) => (SLLconst [log64(c/5)] (ADDshiftLL <x.Type> x x [2]))
+(MUL x (MOVDconst [c])) && c%7 == 0 && isPowerOfTwo64(c/7) => (SLLconst [log64(c/7)] (ADDshiftLL <x.Type> (NEG <x.Type> x) x [3]))
+(MUL x (MOVDconst [c])) && c%9 == 0 && isPowerOfTwo64(c/9) => (SLLconst [log64(c/9)] (ADDshiftLL <x.Type> x x [3]))
+
+(MULW x (MOVDconst [c])) && int32(c)==-1 => (NEG x)
+(MULW _ (MOVDconst [c])) && int32(c)==0 => (MOVDconst [0])
+(MULW x (MOVDconst [c])) && int32(c)==1 => x
+(MULW x (MOVDconst [c])) && isPowerOfTwo64(c) => (SLLconst [log64(c)] x)
+(MULW x (MOVDconst [c])) && isPowerOfTwo64(c-1) && int32(c) >= 3 => (ADDshiftLL x x [log64(c-1)])
+(MULW x (MOVDconst [c])) && isPowerOfTwo64(c+1) && int32(c) >= 7 => (ADDshiftLL (NEG <x.Type> x) x [log64(c+1)])
+(MULW x (MOVDconst [c])) && c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c) => (SLLconst [log64(c/3)] (ADDshiftLL <x.Type> x x [1]))
+(MULW x (MOVDconst [c])) && c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c) => (SLLconst [log64(c/5)] (ADDshiftLL <x.Type> x x [2]))
+(MULW x (MOVDconst [c])) && c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c) => (SLLconst [log64(c/7)] (ADDshiftLL <x.Type> (NEG <x.Type> x) x [3]))
+(MULW x (MOVDconst [c])) && c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c) => (SLLconst [log64(c/9)] (ADDshiftLL <x.Type> x x [3]))
+
+// mneg by constant
+(MNEG x (MOVDconst [-1])) => x
+(MNEG _ (MOVDconst [0])) => (MOVDconst [0])
+(MNEG x (MOVDconst [1])) => (NEG x)
+(MNEG x (MOVDconst [c])) && isPowerOfTwo64(c) => (NEG (SLLconst <x.Type> [log64(c)] x))
+(MNEG x (MOVDconst [c])) && isPowerOfTwo64(c-1) && c >= 3 => (NEG (ADDshiftLL <x.Type> x x [log64(c-1)]))
+(MNEG x (MOVDconst [c])) && isPowerOfTwo64(c+1) && c >= 7 => (NEG (ADDshiftLL <x.Type> (NEG <x.Type> x) x [log64(c+1)]))
+(MNEG x (MOVDconst [c])) && c%3 == 0 && isPowerOfTwo64(c/3) => (SLLconst <x.Type> [log64(c/3)] (SUBshiftLL <x.Type> x x [2]))
+(MNEG x (MOVDconst [c])) && c%5 == 0 && isPowerOfTwo64(c/5) => (NEG (SLLconst <x.Type> [log64(c/5)] (ADDshiftLL <x.Type> x x [2])))
+(MNEG x (MOVDconst [c])) && c%7 == 0 && isPowerOfTwo64(c/7) => (SLLconst <x.Type> [log64(c/7)] (SUBshiftLL <x.Type> x x [3]))
+(MNEG x (MOVDconst [c])) && c%9 == 0 && isPowerOfTwo64(c/9) => (NEG (SLLconst <x.Type> [log64(c/9)] (ADDshiftLL <x.Type> x x [3])))
+
+
+(MNEGW x (MOVDconst [c])) && int32(c)==-1 => x
+(MNEGW _ (MOVDconst [c])) && int32(c)==0 => (MOVDconst [0])
+(MNEGW x (MOVDconst [c])) && int32(c)==1 => (NEG x)
+(MNEGW x (MOVDconst [c])) && isPowerOfTwo64(c) => (NEG (SLLconst <x.Type> [log64(c)] x))
+(MNEGW x (MOVDconst [c])) && isPowerOfTwo64(c-1) && int32(c) >= 3 => (NEG (ADDshiftLL <x.Type> x x [log64(c-1)]))
+(MNEGW x (MOVDconst [c])) && isPowerOfTwo64(c+1) && int32(c) >= 7 => (NEG (ADDshiftLL <x.Type> (NEG <x.Type> x) x [log64(c+1)]))
+(MNEGW x (MOVDconst [c])) && c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c) => (SLLconst <x.Type> [log64(c/3)] (SUBshiftLL <x.Type> x x [2]))
+(MNEGW x (MOVDconst [c])) && c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c) => (NEG (SLLconst <x.Type> [log64(c/5)] (ADDshiftLL <x.Type> x x [2])))
+(MNEGW x (MOVDconst [c])) && c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c) => (SLLconst <x.Type> [log64(c/7)] (SUBshiftLL <x.Type> x x [3]))
+(MNEGW x (MOVDconst [c])) && c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c) => (NEG (SLLconst <x.Type> [log64(c/9)] (ADDshiftLL <x.Type> x x [3])))
+
+
+(MADD a x (MOVDconst [-1])) => (SUB a x)
+(MADD a _ (MOVDconst [0])) => a
+(MADD a x (MOVDconst [1])) => (ADD a x)
+(MADD a x (MOVDconst [c])) && isPowerOfTwo64(c) => (ADDshiftLL a x [log64(c)])
+(MADD a x (MOVDconst [c])) && isPowerOfTwo64(c-1) && c>=3 => (ADD a (ADDshiftLL <x.Type> x x [log64(c-1)]))
+(MADD a x (MOVDconst [c])) && isPowerOfTwo64(c+1) && c>=7 => (SUB a (SUBshiftLL <x.Type> x x [log64(c+1)]))
+(MADD a x (MOVDconst [c])) && c%3 == 0 && isPowerOfTwo64(c/3) => (SUBshiftLL a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)])
+(MADD a x (MOVDconst [c])) && c%5 == 0 && isPowerOfTwo64(c/5) => (ADDshiftLL a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)])
+(MADD a x (MOVDconst [c])) && c%7 == 0 && isPowerOfTwo64(c/7) => (SUBshiftLL a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)])
+(MADD a x (MOVDconst [c])) && c%9 == 0 && isPowerOfTwo64(c/9) => (ADDshiftLL a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)])
+
+(MADD a (MOVDconst [-1]) x) => (SUB a x)
+(MADD a (MOVDconst [0]) _) => a
+(MADD a (MOVDconst [1]) x) => (ADD a x)
+(MADD a (MOVDconst [c]) x) && isPowerOfTwo64(c) => (ADDshiftLL a x [log64(c)])
+(MADD a (MOVDconst [c]) x) && isPowerOfTwo64(c-1) && c>=3 => (ADD a (ADDshiftLL <x.Type> x x [log64(c-1)]))
+(MADD a (MOVDconst [c]) x) && isPowerOfTwo64(c+1) && c>=7 => (SUB a (SUBshiftLL <x.Type> x x [log64(c+1)]))
+(MADD a (MOVDconst [c]) x) && c%3 == 0 && isPowerOfTwo64(c/3) => (SUBshiftLL a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)])
+(MADD a (MOVDconst [c]) x) && c%5 == 0 && isPowerOfTwo64(c/5) => (ADDshiftLL a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)])
+(MADD a (MOVDconst [c]) x) && c%7 == 0 && isPowerOfTwo64(c/7) => (SUBshiftLL a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)])
+(MADD a (MOVDconst [c]) x) && c%9 == 0 && isPowerOfTwo64(c/9) => (ADDshiftLL a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)])
+
+(MADDW a x (MOVDconst [c])) && int32(c)==-1 => (SUB a x)
+(MADDW a _ (MOVDconst [c])) && int32(c)==0 => a
+(MADDW a x (MOVDconst [c])) && int32(c)==1 => (ADD a x)
+(MADDW a x (MOVDconst [c])) && isPowerOfTwo64(c) => (ADDshiftLL a x [log64(c)])
+(MADDW a x (MOVDconst [c])) && isPowerOfTwo64(c-1) && int32(c)>=3 => (ADD a (ADDshiftLL <x.Type> x x [log64(c-1)]))
+(MADDW a x (MOVDconst [c])) && isPowerOfTwo64(c+1) && int32(c)>=7 => (SUB a (SUBshiftLL <x.Type> x x [log64(c+1)]))
+(MADDW a x (MOVDconst [c])) && c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c) => (SUBshiftLL a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)])
+(MADDW a x (MOVDconst [c])) && c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c) => (ADDshiftLL a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)])
+(MADDW a x (MOVDconst [c])) && c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c) => (SUBshiftLL a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)])
+(MADDW a x (MOVDconst [c])) && c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c) => (ADDshiftLL a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)])
+
+(MADDW a (MOVDconst [c]) x) && int32(c)==-1 => (SUB a x)
+(MADDW a (MOVDconst [c]) _) && int32(c)==0 => a
+(MADDW a (MOVDconst [c]) x) && int32(c)==1 => (ADD a x)
+(MADDW a (MOVDconst [c]) x) && isPowerOfTwo64(c) => (ADDshiftLL a x [log64(c)])
+(MADDW a (MOVDconst [c]) x) && isPowerOfTwo64(c-1) && int32(c)>=3 => (ADD a (ADDshiftLL <x.Type> x x [log64(c-1)]))
+(MADDW a (MOVDconst [c]) x) && isPowerOfTwo64(c+1) && int32(c)>=7 => (SUB a (SUBshiftLL <x.Type> x x [log64(c+1)]))
+(MADDW a (MOVDconst [c]) x) && c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c) => (SUBshiftLL a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)])
+(MADDW a (MOVDconst [c]) x) && c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c) => (ADDshiftLL a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)])
+(MADDW a (MOVDconst [c]) x) && c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c) => (SUBshiftLL a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)])
+(MADDW a (MOVDconst [c]) x) && c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c) => (ADDshiftLL a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)])
+
+(MSUB a x (MOVDconst [-1])) => (ADD a x)
+(MSUB a _ (MOVDconst [0])) => a
+(MSUB a x (MOVDconst [1])) => (SUB a x)
+(MSUB a x (MOVDconst [c])) && isPowerOfTwo64(c) => (SUBshiftLL a x [log64(c)])
+(MSUB a x (MOVDconst [c])) && isPowerOfTwo64(c-1) && c>=3 => (SUB a (ADDshiftLL <x.Type> x x [log64(c-1)]))
+(MSUB a x (MOVDconst [c])) && isPowerOfTwo64(c+1) && c>=7 => (ADD a (SUBshiftLL <x.Type> x x [log64(c+1)]))
+(MSUB a x (MOVDconst [c])) && c%3 == 0 && isPowerOfTwo64(c/3) => (ADDshiftLL a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)])
+(MSUB a x (MOVDconst [c])) && c%5 == 0 && isPowerOfTwo64(c/5) => (SUBshiftLL a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)])
+(MSUB a x (MOVDconst [c])) && c%7 == 0 && isPowerOfTwo64(c/7) => (ADDshiftLL a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)])
+(MSUB a x (MOVDconst [c])) && c%9 == 0 && isPowerOfTwo64(c/9) => (SUBshiftLL a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)])
+
+(MSUB a (MOVDconst [-1]) x) => (ADD a x)
+(MSUB a (MOVDconst [0]) _) => a
+(MSUB a (MOVDconst [1]) x) => (SUB a x)
+(MSUB a (MOVDconst [c]) x) && isPowerOfTwo64(c) => (SUBshiftLL a x [log64(c)])
+(MSUB a (MOVDconst [c]) x) && isPowerOfTwo64(c-1) && c>=3 => (SUB a (ADDshiftLL <x.Type> x x [log64(c-1)]))
+(MSUB a (MOVDconst [c]) x) && isPowerOfTwo64(c+1) && c>=7 => (ADD a (SUBshiftLL <x.Type> x x [log64(c+1)]))
+(MSUB a (MOVDconst [c]) x) && c%3 == 0 && isPowerOfTwo64(c/3) => (ADDshiftLL a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)])
+(MSUB a (MOVDconst [c]) x) && c%5 == 0 && isPowerOfTwo64(c/5) => (SUBshiftLL a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)])
+(MSUB a (MOVDconst [c]) x) && c%7 == 0 && isPowerOfTwo64(c/7) => (ADDshiftLL a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)])
+(MSUB a (MOVDconst [c]) x) && c%9 == 0 && isPowerOfTwo64(c/9) => (SUBshiftLL a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)])
+
+(MSUBW a x (MOVDconst [c])) && int32(c)==-1 => (ADD a x)
+(MSUBW a _ (MOVDconst [c])) && int32(c)==0 => a
+(MSUBW a x (MOVDconst [c])) && int32(c)==1 => (SUB a x)
+(MSUBW a x (MOVDconst [c])) && isPowerOfTwo64(c) => (SUBshiftLL a x [log64(c)])
+(MSUBW a x (MOVDconst [c])) && isPowerOfTwo64(c-1) && int32(c)>=3 => (SUB a (ADDshiftLL <x.Type> x x [log64(c-1)]))
+(MSUBW a x (MOVDconst [c])) && isPowerOfTwo64(c+1) && int32(c)>=7 => (ADD a (SUBshiftLL <x.Type> x x [log64(c+1)]))
+(MSUBW a x (MOVDconst [c])) && c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c) => (ADDshiftLL a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)])
+(MSUBW a x (MOVDconst [c])) && c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c) => (SUBshiftLL a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)])
+(MSUBW a x (MOVDconst [c])) && c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c) => (ADDshiftLL a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)])
+(MSUBW a x (MOVDconst [c])) && c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c) => (SUBshiftLL a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)])
+
+(MSUBW a (MOVDconst [c]) x) && int32(c)==-1 => (ADD a x)
+(MSUBW a (MOVDconst [c]) _) && int32(c)==0 => a
+(MSUBW a (MOVDconst [c]) x) && int32(c)==1 => (SUB a x)
+(MSUBW a (MOVDconst [c]) x) && isPowerOfTwo64(c) => (SUBshiftLL a x [log64(c)])
+(MSUBW a (MOVDconst [c]) x) && isPowerOfTwo64(c-1) && int32(c)>=3 => (SUB a (ADDshiftLL <x.Type> x x [log64(c-1)]))
+(MSUBW a (MOVDconst [c]) x) && isPowerOfTwo64(c+1) && int32(c)>=7 => (ADD a (SUBshiftLL <x.Type> x x [log64(c+1)]))
+(MSUBW a (MOVDconst [c]) x) && c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c) => (ADDshiftLL a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)])
+(MSUBW a (MOVDconst [c]) x) && c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c) => (SUBshiftLL a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)])
+(MSUBW a (MOVDconst [c]) x) && c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c) => (ADDshiftLL a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)])
+(MSUBW a (MOVDconst [c]) x) && c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c) => (SUBshiftLL a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)])
+
+// div by constant
+(UDIV x (MOVDconst [1])) => x
+(UDIV x (MOVDconst [c])) && isPowerOfTwo64(c) => (SRLconst [log64(c)] x)
+(UDIVW x (MOVDconst [c])) && uint32(c)==1 => x
+(UDIVW x (MOVDconst [c])) && isPowerOfTwo64(c) && is32Bit(c) => (SRLconst [log64(c)] x)
+(UMOD _ (MOVDconst [1])) => (MOVDconst [0])
+(UMOD x (MOVDconst [c])) && isPowerOfTwo64(c) => (ANDconst [c-1] x)
+(UMODW _ (MOVDconst [c])) && uint32(c)==1 => (MOVDconst [0])
+(UMODW x (MOVDconst [c])) && isPowerOfTwo64(c) && is32Bit(c) => (ANDconst [c-1] x)
+
+// generic simplifications
+(ADD x (NEG y)) => (SUB x y)
+(SUB x x) => (MOVDconst [0])
+(AND x x) => x
+(OR  x x) => x
+(XOR x x) => (MOVDconst [0])
+(BIC x x) => (MOVDconst [0])
+(EON x x) => (MOVDconst [-1])
+(ORN x x) => (MOVDconst [-1])
+(AND x (MVN y)) => (BIC x y)
+(XOR x (MVN y)) => (EON x y)
+(OR  x (MVN y)) => (ORN x y)
+(MVN (XOR x y)) => (EON x y)
+(NEG (NEG x)) => x
+
+(CSEL [cc] (MOVDconst [-1]) (MOVDconst [0]) flag) => (CSETM [cc] flag)
+(CSEL [cc] (MOVDconst [0]) (MOVDconst [-1]) flag) => (CSETM [arm64Negate(cc)] flag)
+(CSEL [cc] x (MOVDconst [0]) flag) => (CSEL0 [cc] x flag)
+(CSEL [cc] (MOVDconst [0]) y flag) => (CSEL0 [arm64Negate(cc)] y flag)
+(CSEL [cc] x (ADDconst [1] a) flag) => (CSINC [cc] x a flag)
+(CSEL [cc] (ADDconst [1] a) x flag) => (CSINC [arm64Negate(cc)] x a flag)
+(CSEL [cc] x (MVN a) flag) => (CSINV [cc] x a flag)
+(CSEL [cc] (MVN a) x flag) => (CSINV [arm64Negate(cc)] x a flag)
+(CSEL [cc] x (NEG a) flag) => (CSNEG [cc] x a flag)
+(CSEL [cc] (NEG a) x flag) => (CSNEG [arm64Negate(cc)] x a flag)
+
+(SUB x (SUB y z)) => (SUB (ADD <v.Type> x z) y)
+(SUB (SUB x y) z) => (SUB x (ADD <y.Type> y z))
+
+// remove redundant *const ops
+(ADDconst [0]  x) => x
+(SUBconst [0]  x) => x
+(ANDconst [0]  _) => (MOVDconst [0])
+(ANDconst [-1] x) => x
+(ORconst  [0]  x) => x
+(ORconst  [-1] _) => (MOVDconst [-1])
+(XORconst [0]  x) => x
+(XORconst [-1] x) => (MVN x)
+
+// generic constant folding
+(ADDconst [c] (MOVDconst [d]))  => (MOVDconst [c+d])
+(ADDconst [c] (ADDconst [d] x)) => (ADDconst [c+d] x)
+(ADDconst [c] (SUBconst [d] x)) => (ADDconst [c-d] x)
+(SUBconst [c] (MOVDconst [d]))  => (MOVDconst [d-c])
+(SUBconst [c] (SUBconst [d] x)) => (ADDconst [-c-d] x)
+(SUBconst [c] (ADDconst [d] x)) => (ADDconst [-c+d] x)
+(SLLconst [c] (MOVDconst [d]))  => (MOVDconst [d<<uint64(c)])
+(SRLconst [c] (MOVDconst [d]))  => (MOVDconst [int64(uint64(d)>>uint64(c))])
+(SRAconst [c] (MOVDconst [d]))  => (MOVDconst [d>>uint64(c)])
+(MUL   (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [c*d])
+(MULW  (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [int64(int32(c)*int32(d))])
+(MNEG  (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [-c*d])
+(MNEGW (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [-int64(int32(c)*int32(d))])
+(MADD  (MOVDconst [c]) x y) => (ADDconst [c] (MUL   <x.Type> x y))
+(MADDW (MOVDconst [c]) x y) => (ADDconst [c] (MULW  <x.Type> x y))
+(MSUB  (MOVDconst [c]) x y) => (ADDconst [c] (MNEG  <x.Type> x y))
+(MSUBW (MOVDconst [c]) x y) => (ADDconst [c] (MNEGW <x.Type> x y))
+(MADD  a (MOVDconst [c]) (MOVDconst [d])) => (ADDconst [c*d] a)
+(MADDW a (MOVDconst [c]) (MOVDconst [d])) => (ADDconst [int64(int32(c)*int32(d))] a)
+(MSUB  a (MOVDconst [c]) (MOVDconst [d])) => (SUBconst [c*d] a)
+(MSUBW a (MOVDconst [c]) (MOVDconst [d])) => (SUBconst [int64(int32(c)*int32(d))] a)
+(DIV   (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [c/d])
+(UDIV  (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [int64(uint64(c)/uint64(d))])
+(DIVW  (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [int64(int32(c)/int32(d))])
+(UDIVW (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [int64(uint32(c)/uint32(d))])
+(MOD   (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [c%d])
+(UMOD  (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [int64(uint64(c)%uint64(d))])
+(MODW  (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [int64(int32(c)%int32(d))])
+(UMODW (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [int64(uint32(c)%uint32(d))])
+(ANDconst [c] (MOVDconst [d]))  => (MOVDconst [c&d])
+(ANDconst [c] (ANDconst [d] x)) => (ANDconst [c&d] x)
+(ANDconst [c] (MOVWUreg x)) => (ANDconst [c&(1<<32-1)] x)
+(ANDconst [c] (MOVHUreg x)) => (ANDconst [c&(1<<16-1)] x)
+(ANDconst [c] (MOVBUreg x)) => (ANDconst [c&(1<<8-1)] x)
+(MOVWUreg (ANDconst [c] x)) => (ANDconst [c&(1<<32-1)] x)
+(MOVHUreg (ANDconst [c] x)) => (ANDconst [c&(1<<16-1)] x)
+(MOVBUreg (ANDconst [c] x)) => (ANDconst [c&(1<<8-1)] x)
+(ORconst  [c] (MOVDconst [d]))  => (MOVDconst [c|d])
+(ORconst  [c] (ORconst [d] x))  => (ORconst [c|d] x)
+(XORconst [c] (MOVDconst [d]))  => (MOVDconst [c^d])
+(XORconst [c] (XORconst [d] x)) => (XORconst [c^d] x)
+(MVN (MOVDconst [c])) => (MOVDconst [^c])
+(NEG (MOVDconst [c])) => (MOVDconst [-c])
+(MOVBreg  (MOVDconst [c])) => (MOVDconst [int64(int8(c))])
+(MOVBUreg (MOVDconst [c])) => (MOVDconst [int64(uint8(c))])
+(MOVHreg  (MOVDconst [c])) => (MOVDconst [int64(int16(c))])
+(MOVHUreg (MOVDconst [c])) => (MOVDconst [int64(uint16(c))])
+(MOVWreg  (MOVDconst [c])) => (MOVDconst [int64(int32(c))])
+(MOVWUreg (MOVDconst [c])) => (MOVDconst [int64(uint32(c))])
+(MOVDreg  (MOVDconst [c])) => (MOVDconst [c])
+
+// constant comparisons
+(CMPconst  (MOVDconst [x]) [y]) => (FlagConstant [subFlags64(x,y)])
+(CMPWconst (MOVDconst [x]) [y]) => (FlagConstant [subFlags32(int32(x),y)])
+(TSTconst  (MOVDconst [x]) [y]) => (FlagConstant [logicFlags64(x&y)])
+(TSTWconst (MOVDconst [x]) [y]) => (FlagConstant [logicFlags32(int32(x)&y)])
+(CMNconst  (MOVDconst [x]) [y]) => (FlagConstant [addFlags64(x,y)])
+(CMNWconst (MOVDconst [x]) [y]) => (FlagConstant [addFlags32(int32(x),y)])
+
+// other known comparisons
+(CMPconst (MOVBUreg _) [c]) && 0xff < c => (FlagConstant [subFlags64(0,1)])
+(CMPconst (MOVHUreg _) [c]) && 0xffff < c => (FlagConstant [subFlags64(0,1)])
+(CMPconst (MOVWUreg _) [c]) && 0xffffffff < c => (FlagConstant [subFlags64(0,1)])
+(CMPconst (ANDconst _ [m]) [n]) && 0 <= m && m < n => (FlagConstant [subFlags64(0,1)])
+(CMPconst (SRLconst _ [c]) [n]) && 0 <= n && 0 < c && c <= 63 && (1<<uint64(64-c)) <= uint64(n) => (FlagConstant [subFlags64(0,1)])
+(CMPWconst (MOVBUreg _) [c]) && 0xff < c => (FlagConstant [subFlags64(0,1)])
+(CMPWconst (MOVHUreg _) [c]) && 0xffff < c => (FlagConstant [subFlags64(0,1)])
+
+// absorb flag constants into branches
+(EQ (FlagConstant [fc]) yes no) &&  fc.eq() => (First yes no)
+(EQ (FlagConstant [fc]) yes no) && !fc.eq() => (First no yes)
+
+(NE (FlagConstant [fc]) yes no) &&  fc.ne() => (First yes no)
+(NE (FlagConstant [fc]) yes no) && !fc.ne() => (First no yes)
+
+(LT (FlagConstant [fc]) yes no) &&  fc.lt() => (First yes no)
+(LT (FlagConstant [fc]) yes no) && !fc.lt() => (First no yes)
+
+(LE (FlagConstant [fc]) yes no) &&  fc.le() => (First yes no)
+(LE (FlagConstant [fc]) yes no) && !fc.le() => (First no yes)
+
+(GT (FlagConstant [fc]) yes no) &&  fc.gt() => (First yes no)
+(GT (FlagConstant [fc]) yes no) && !fc.gt() => (First no yes)
+
+(GE (FlagConstant [fc]) yes no) &&  fc.ge() => (First yes no)
+(GE (FlagConstant [fc]) yes no) && !fc.ge() => (First no yes)
+
+(ULT (FlagConstant [fc]) yes no) &&  fc.ult() => (First yes no)
+(ULT (FlagConstant [fc]) yes no) && !fc.ult() => (First no yes)
+
+(ULE (FlagConstant [fc]) yes no) &&  fc.ule() => (First yes no)
+(ULE (FlagConstant [fc]) yes no) && !fc.ule() => (First no yes)
+
+(UGT (FlagConstant [fc]) yes no) &&  fc.ugt() => (First yes no)
+(UGT (FlagConstant [fc]) yes no) && !fc.ugt() => (First no yes)
+
+(UGE (FlagConstant [fc]) yes no) &&  fc.uge() => (First yes no)
+(UGE (FlagConstant [fc]) yes no) && !fc.uge() => (First no yes)
+
+(LTnoov (FlagConstant [fc]) yes no) &&  fc.ltNoov() => (First yes no)
+(LTnoov (FlagConstant [fc]) yes no) && !fc.ltNoov() => (First no yes)
+
+(LEnoov (FlagConstant [fc]) yes no) &&  fc.leNoov() => (First yes no)
+(LEnoov (FlagConstant [fc]) yes no) && !fc.leNoov() => (First no yes)
+
+(GTnoov (FlagConstant [fc]) yes no) &&  fc.gtNoov() => (First yes no)
+(GTnoov (FlagConstant [fc]) yes no) && !fc.gtNoov() => (First no yes)
+
+(GEnoov (FlagConstant [fc]) yes no) &&  fc.geNoov() => (First yes no)
+(GEnoov (FlagConstant [fc]) yes no) && !fc.geNoov() => (First no yes)
+
+(Z (MOVDconst [0]) yes no) => (First yes no)
+(Z (MOVDconst [c]) yes no) && c != 0 => (First no yes)
+(NZ (MOVDconst [0]) yes no) => (First no yes)
+(NZ (MOVDconst [c]) yes no) && c != 0 => (First yes no)
+(ZW (MOVDconst [c]) yes no) && int32(c) == 0 => (First yes no)
+(ZW (MOVDconst [c]) yes no) && int32(c) != 0 => (First no yes)
+(NZW (MOVDconst [c]) yes no) && int32(c) == 0 => (First no yes)
+(NZW (MOVDconst [c]) yes no) && int32(c) != 0 => (First yes no)
+
+// absorb InvertFlags into branches
+(LT (InvertFlags cmp) yes no) => (GT cmp yes no)
+(GT (InvertFlags cmp) yes no) => (LT cmp yes no)
+(LE (InvertFlags cmp) yes no) => (GE cmp yes no)
+(GE (InvertFlags cmp) yes no) => (LE cmp yes no)
+(ULT (InvertFlags cmp) yes no) => (UGT cmp yes no)
+(UGT (InvertFlags cmp) yes no) => (ULT cmp yes no)
+(ULE (InvertFlags cmp) yes no) => (UGE cmp yes no)
+(UGE (InvertFlags cmp) yes no) => (ULE cmp yes no)
+(EQ (InvertFlags cmp) yes no) => (EQ cmp yes no)
+(NE (InvertFlags cmp) yes no) => (NE cmp yes no)
+(FLT (InvertFlags cmp) yes no) => (FGT cmp yes no)
+(FGT (InvertFlags cmp) yes no) => (FLT cmp yes no)
+(FLE (InvertFlags cmp) yes no) => (FGE cmp yes no)
+(FGE (InvertFlags cmp) yes no) => (FLE cmp yes no)
+(LTnoov (InvertFlags cmp) yes no) => (GTnoov cmp yes no)
+(GEnoov (InvertFlags cmp) yes no) => (LEnoov cmp yes no)
+(LEnoov (InvertFlags cmp) yes no) => (GEnoov cmp yes no)
+(GTnoov (InvertFlags cmp) yes no) => (LTnoov cmp yes no)
+
+// absorb InvertFlags into conditional instructions
+(CSEL [cc] x y (InvertFlags cmp)) => (CSEL [arm64Invert(cc)] x y cmp)
+(CSEL0 [cc] x (InvertFlags cmp)) => (CSEL0 [arm64Invert(cc)] x cmp)
+(CSETM [cc] (InvertFlags cmp)) => (CSETM [arm64Invert(cc)] cmp)
+(CSINC [cc] x y (InvertFlags cmp)) => (CSINC [arm64Invert(cc)] x y cmp)
+(CSINV [cc] x y (InvertFlags cmp)) => (CSINV [arm64Invert(cc)] x y cmp)
+(CSNEG [cc] x y (InvertFlags cmp)) => (CSNEG [arm64Invert(cc)] x y cmp)
+
+// absorb flag constants into boolean values
+(Equal (FlagConstant [fc])) => (MOVDconst [b2i(fc.eq())])
+(NotEqual (FlagConstant [fc])) => (MOVDconst [b2i(fc.ne())])
+(LessThan (FlagConstant [fc])) => (MOVDconst [b2i(fc.lt())])
+(LessThanU (FlagConstant [fc])) => (MOVDconst [b2i(fc.ult())])
+(LessEqual (FlagConstant [fc])) => (MOVDconst [b2i(fc.le())])
+(LessEqualU (FlagConstant [fc])) => (MOVDconst [b2i(fc.ule())])
+(GreaterThan (FlagConstant [fc])) => (MOVDconst [b2i(fc.gt())])
+(GreaterThanU (FlagConstant [fc])) => (MOVDconst [b2i(fc.ugt())])
+(GreaterEqual (FlagConstant [fc])) => (MOVDconst [b2i(fc.ge())])
+(GreaterEqualU (FlagConstant [fc])) => (MOVDconst [b2i(fc.uge())])
+
+// absorb InvertFlags into boolean values
+(Equal (InvertFlags x)) => (Equal x)
+(NotEqual (InvertFlags x)) => (NotEqual x)
+(LessThan (InvertFlags x)) => (GreaterThan x)
+(LessThanU (InvertFlags x)) => (GreaterThanU x)
+(GreaterThan (InvertFlags x)) => (LessThan x)
+(GreaterThanU (InvertFlags x)) => (LessThanU x)
+(LessEqual (InvertFlags x)) => (GreaterEqual x)
+(LessEqualU (InvertFlags x)) => (GreaterEqualU x)
+(GreaterEqual (InvertFlags x)) => (LessEqual x)
+(GreaterEqualU (InvertFlags x)) => (LessEqualU x)
+(LessThanF (InvertFlags x)) => (GreaterThanF x)
+(LessEqualF (InvertFlags x)) => (GreaterEqualF x)
+(GreaterThanF (InvertFlags x)) => (LessThanF x)
+(GreaterEqualF (InvertFlags x)) => (LessEqualF x)
+
+// Boolean-generating instructions (NOTE: NOT all boolean Values) always
+// zero upper bit of the register; no need to zero-extend
+(MOVBUreg x:((Equal|NotEqual|LessThan|LessThanU|LessThanF|LessEqual|LessEqualU|LessEqualF|GreaterThan|GreaterThanU|GreaterThanF|GreaterEqual|GreaterEqualU|GreaterEqualF) _)) => (MOVDreg x)
+
+// absorb flag constants into conditional instructions
+(CSEL [cc] x _ flag) && ccARM64Eval(cc, flag) > 0 => x
+(CSEL [cc] _ y flag) && ccARM64Eval(cc, flag) < 0 => y
+(CSEL0 [cc] x flag) && ccARM64Eval(cc, flag) > 0 => x
+(CSEL0 [cc] _ flag) && ccARM64Eval(cc, flag) < 0 => (MOVDconst [0])
+(CSNEG [cc] x _ flag) && ccARM64Eval(cc, flag) > 0 => x
+(CSNEG [cc] _ y flag) && ccARM64Eval(cc, flag) < 0 => (NEG y)
+(CSINV [cc] x _ flag) && ccARM64Eval(cc, flag) > 0 => x
+(CSINV [cc] _ y flag) && ccARM64Eval(cc, flag) < 0 => (Not y)
+(CSINC [cc] x _ flag) && ccARM64Eval(cc, flag) > 0 => x
+(CSINC [cc] _ y flag) && ccARM64Eval(cc, flag) < 0 => (ADDconst [1] y)
+(CSETM [cc] flag) && ccARM64Eval(cc, flag) > 0 => (MOVDconst [-1])
+(CSETM [cc] flag) && ccARM64Eval(cc, flag) < 0 => (MOVDconst [0])
+
+// absorb flags back into boolean CSEL
+(CSEL [cc] x y (CMPWconst [0] boolval)) && cc == OpARM64NotEqual && flagArg(boolval) != nil =>
+      (CSEL [boolval.Op] x y flagArg(boolval))
+(CSEL [cc] x y (CMPWconst [0] boolval)) && cc == OpARM64Equal && flagArg(boolval) != nil =>
+      (CSEL [arm64Negate(boolval.Op)] x y flagArg(boolval))
+(CSEL0 [cc] x (CMPWconst [0] boolval)) && cc == OpARM64NotEqual && flagArg(boolval) != nil =>
+      (CSEL0 [boolval.Op] x flagArg(boolval))
+(CSEL0 [cc] x (CMPWconst [0] boolval)) && cc == OpARM64Equal && flagArg(boolval) != nil =>
+      (CSEL0 [arm64Negate(boolval.Op)] x flagArg(boolval))
+
+// absorb shifts into ops
+(NEG x:(SLLconst [c] y)) && clobberIfDead(x) => (NEGshiftLL [c] y)
+(NEG x:(SRLconst [c] y)) && clobberIfDead(x) => (NEGshiftRL [c] y)
+(NEG x:(SRAconst [c] y)) && clobberIfDead(x) => (NEGshiftRA [c] y)
+(MVN x:(SLLconst [c] y)) && clobberIfDead(x) => (MVNshiftLL [c] y)
+(MVN x:(SRLconst [c] y)) && clobberIfDead(x) => (MVNshiftRL [c] y)
+(MVN x:(SRAconst [c] y)) && clobberIfDead(x) => (MVNshiftRA [c] y)
+(MVN x:(RORconst [c] y)) && clobberIfDead(x) => (MVNshiftRO [c] y)
+(ADD x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) => (ADDshiftLL x0 y [c])
+(ADD x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) => (ADDshiftRL x0 y [c])
+(ADD x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) => (ADDshiftRA x0 y [c])
+(SUB x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) => (SUBshiftLL x0 y [c])
+(SUB x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) => (SUBshiftRL x0 y [c])
+(SUB x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) => (SUBshiftRA x0 y [c])
+(AND x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) => (ANDshiftLL x0 y [c])
+(AND x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) => (ANDshiftRL x0 y [c])
+(AND x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) => (ANDshiftRA x0 y [c])
+(AND x0 x1:(RORconst [c] y)) && clobberIfDead(x1) => (ANDshiftRO x0 y [c])
+(OR  x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) => (ORshiftLL  x0 y [c]) // useful for combined load
+(OR  x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) => (ORshiftRL  x0 y [c])
+(OR  x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) => (ORshiftRA  x0 y [c])
+(OR  x0 x1:(RORconst [c] y)) && clobberIfDead(x1) => (ORshiftRO  x0 y [c])
+(XOR x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) => (XORshiftLL x0 y [c])
+(XOR x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) => (XORshiftRL x0 y [c])
+(XOR x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) => (XORshiftRA x0 y [c])
+(XOR x0 x1:(RORconst [c] y)) && clobberIfDead(x1) => (XORshiftRO x0 y [c])
+(BIC x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) => (BICshiftLL x0 y [c])
+(BIC x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) => (BICshiftRL x0 y [c])
+(BIC x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) => (BICshiftRA x0 y [c])
+(BIC x0 x1:(RORconst [c] y)) && clobberIfDead(x1) => (BICshiftRO x0 y [c])
+(ORN x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) => (ORNshiftLL x0 y [c])
+(ORN x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) => (ORNshiftRL x0 y [c])
+(ORN x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) => (ORNshiftRA x0 y [c])
+(ORN x0 x1:(RORconst [c] y)) && clobberIfDead(x1) => (ORNshiftRO x0 y [c])
+(EON x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) => (EONshiftLL x0 y [c])
+(EON x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) => (EONshiftRL x0 y [c])
+(EON x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) => (EONshiftRA x0 y [c])
+(EON x0 x1:(RORconst [c] y)) && clobberIfDead(x1) => (EONshiftRO x0 y [c])
+(CMP x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) => (CMPshiftLL x0 y [c])
+(CMP x0:(SLLconst [c] y) x1) && clobberIfDead(x0) => (InvertFlags (CMPshiftLL x1 y [c]))
+(CMP x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) => (CMPshiftRL x0 y [c])
+(CMP x0:(SRLconst [c] y) x1) && clobberIfDead(x0) => (InvertFlags (CMPshiftRL x1 y [c]))
+(CMP x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) => (CMPshiftRA x0 y [c])
+(CMP x0:(SRAconst [c] y) x1) && clobberIfDead(x0) => (InvertFlags (CMPshiftRA x1 y [c]))
+(CMN x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) => (CMNshiftLL x0 y [c])
+(CMN x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) => (CMNshiftRL x0 y [c])
+(CMN x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) => (CMNshiftRA x0 y [c])
+(TST x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) => (TSTshiftLL x0 y [c])
+(TST x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) => (TSTshiftRL x0 y [c])
+(TST x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) => (TSTshiftRA x0 y [c])
+(TST x0 x1:(RORconst [c] y)) && clobberIfDead(x1) => (TSTshiftRO x0 y [c])
+
+// prefer *const ops to *shift ops
+(ADDshiftLL (MOVDconst [c]) x [d]) => (ADDconst [c] (SLLconst <x.Type> x [d]))
+(ADDshiftRL (MOVDconst [c]) x [d]) => (ADDconst [c] (SRLconst <x.Type> x [d]))
+(ADDshiftRA (MOVDconst [c]) x [d]) => (ADDconst [c] (SRAconst <x.Type> x [d]))
+(ANDshiftLL (MOVDconst [c]) x [d]) => (ANDconst [c] (SLLconst <x.Type> x [d]))
+(ANDshiftRL (MOVDconst [c]) x [d]) => (ANDconst [c] (SRLconst <x.Type> x [d]))
+(ANDshiftRA (MOVDconst [c]) x [d]) => (ANDconst [c] (SRAconst <x.Type> x [d]))
+(ANDshiftRO (MOVDconst [c]) x [d]) => (ANDconst [c] (RORconst <x.Type> x [d]))
+(ORshiftLL  (MOVDconst [c]) x [d]) => (ORconst  [c] (SLLconst <x.Type> x [d]))
+(ORshiftRL  (MOVDconst [c]) x [d]) => (ORconst  [c] (SRLconst <x.Type> x [d]))
+(ORshiftRA  (MOVDconst [c]) x [d]) => (ORconst  [c] (SRAconst <x.Type> x [d]))
+(ORshiftRO  (MOVDconst [c]) x [d]) => (ORconst  [c] (RORconst <x.Type> x [d]))
+(XORshiftLL (MOVDconst [c]) x [d]) => (XORconst [c] (SLLconst <x.Type> x [d]))
+(XORshiftRL (MOVDconst [c]) x [d]) => (XORconst [c] (SRLconst <x.Type> x [d]))
+(XORshiftRA (MOVDconst [c]) x [d]) => (XORconst [c] (SRAconst <x.Type> x [d]))
+(XORshiftRO (MOVDconst [c]) x [d]) => (XORconst [c] (RORconst <x.Type> x [d]))
+(CMPshiftLL (MOVDconst [c]) x [d]) => (InvertFlags (CMPconst [c] (SLLconst <x.Type> x [d])))
+(CMPshiftRL (MOVDconst [c]) x [d]) => (InvertFlags (CMPconst [c] (SRLconst <x.Type> x [d])))
+(CMPshiftRA (MOVDconst [c]) x [d]) => (InvertFlags (CMPconst [c] (SRAconst <x.Type> x [d])))
+(CMNshiftLL (MOVDconst [c]) x [d]) => (CMNconst [c] (SLLconst <x.Type> x [d]))
+(CMNshiftRL (MOVDconst [c]) x [d]) => (CMNconst [c] (SRLconst <x.Type> x [d]))
+(CMNshiftRA (MOVDconst [c]) x [d]) => (CMNconst [c] (SRAconst <x.Type> x [d]))
+(TSTshiftLL (MOVDconst [c]) x [d]) => (TSTconst [c] (SLLconst <x.Type> x [d]))
+(TSTshiftRL (MOVDconst [c]) x [d]) => (TSTconst [c] (SRLconst <x.Type> x [d]))
+(TSTshiftRA (MOVDconst [c]) x [d]) => (TSTconst [c] (SRAconst <x.Type> x [d]))
+(TSTshiftRO (MOVDconst [c]) x [d]) => (TSTconst [c] (RORconst <x.Type> x [d]))
+
+// constant folding in *shift ops
+(MVNshiftLL (MOVDconst [c]) [d]) => (MOVDconst [^int64(uint64(c)<<uint64(d))])
+(MVNshiftRL (MOVDconst [c]) [d]) => (MOVDconst [^int64(uint64(c)>>uint64(d))])
+(MVNshiftRA (MOVDconst [c]) [d]) => (MOVDconst [^(c>>uint64(d))])
+(MVNshiftRO (MOVDconst [c]) [d]) => (MOVDconst [^rotateRight64(c, d)])
+(NEGshiftLL (MOVDconst [c]) [d]) => (MOVDconst [-int64(uint64(c)<<uint64(d))])
+(NEGshiftRL (MOVDconst [c]) [d]) => (MOVDconst [-int64(uint64(c)>>uint64(d))])
+(NEGshiftRA (MOVDconst [c]) [d]) => (MOVDconst [-(c>>uint64(d))])
+(ADDshiftLL x (MOVDconst [c]) [d]) => (ADDconst x [int64(uint64(c)<<uint64(d))])
+(ADDshiftRL x (MOVDconst [c]) [d]) => (ADDconst x [int64(uint64(c)>>uint64(d))])
+(ADDshiftRA x (MOVDconst [c]) [d]) => (ADDconst x [c>>uint64(d)])
+(SUBshiftLL x (MOVDconst [c]) [d]) => (SUBconst x [int64(uint64(c)<<uint64(d))])
+(SUBshiftRL x (MOVDconst [c]) [d]) => (SUBconst x [int64(uint64(c)>>uint64(d))])
+(SUBshiftRA x (MOVDconst [c]) [d]) => (SUBconst x [c>>uint64(d)])
+(ANDshiftLL x (MOVDconst [c]) [d]) => (ANDconst x [int64(uint64(c)<<uint64(d))])
+(ANDshiftRL x (MOVDconst [c]) [d]) => (ANDconst x [int64(uint64(c)>>uint64(d))])
+(ANDshiftRA x (MOVDconst [c]) [d]) => (ANDconst x [c>>uint64(d)])
+(ANDshiftRO x (MOVDconst [c]) [d]) => (ANDconst x [rotateRight64(c, d)])
+(ORshiftLL  x (MOVDconst [c]) [d]) => (ORconst  x [int64(uint64(c)<<uint64(d))])
+(ORshiftRL  x (MOVDconst [c]) [d]) => (ORconst  x [int64(uint64(c)>>uint64(d))])
+(ORshiftRA  x (MOVDconst [c]) [d]) => (ORconst  x [c>>uint64(d)])
+(ORshiftRO  x (MOVDconst [c]) [d]) => (ORconst  x [rotateRight64(c, d)])
+(XORshiftLL x (MOVDconst [c]) [d]) => (XORconst x [int64(uint64(c)<<uint64(d))])
+(XORshiftRL x (MOVDconst [c]) [d]) => (XORconst x [int64(uint64(c)>>uint64(d))])
+(XORshiftRA x (MOVDconst [c]) [d]) => (XORconst x [c>>uint64(d)])
+(XORshiftRO x (MOVDconst [c]) [d]) => (XORconst x [rotateRight64(c, d)])
+(BICshiftLL x (MOVDconst [c]) [d]) => (ANDconst x [^int64(uint64(c)<<uint64(d))])
+(BICshiftRL x (MOVDconst [c]) [d]) => (ANDconst x [^int64(uint64(c)>>uint64(d))])
+(BICshiftRA x (MOVDconst [c]) [d]) => (ANDconst x [^(c>>uint64(d))])
+(BICshiftRO x (MOVDconst [c]) [d]) => (ANDconst x [^rotateRight64(c, d)])
+(ORNshiftLL x (MOVDconst [c]) [d]) => (ORconst  x [^int64(uint64(c)<<uint64(d))])
+(ORNshiftRL x (MOVDconst [c]) [d]) => (ORconst  x [^int64(uint64(c)>>uint64(d))])
+(ORNshiftRA x (MOVDconst [c]) [d]) => (ORconst  x [^(c>>uint64(d))])
+(ORNshiftRO x (MOVDconst [c]) [d]) => (ORconst  x [^rotateRight64(c, d)])
+(EONshiftLL x (MOVDconst [c]) [d]) => (XORconst x [^int64(uint64(c)<<uint64(d))])
+(EONshiftRL x (MOVDconst [c]) [d]) => (XORconst x [^int64(uint64(c)>>uint64(d))])
+(EONshiftRA x (MOVDconst [c]) [d]) => (XORconst x [^(c>>uint64(d))])
+(EONshiftRO x (MOVDconst [c]) [d]) => (XORconst x [^rotateRight64(c, d)])
+(CMPshiftLL x (MOVDconst [c]) [d]) => (CMPconst x [int64(uint64(c)<<uint64(d))])
+(CMPshiftRL x (MOVDconst [c]) [d]) => (CMPconst x [int64(uint64(c)>>uint64(d))])
+(CMPshiftRA x (MOVDconst [c]) [d]) => (CMPconst x [c>>uint64(d)])
+(CMNshiftLL x (MOVDconst [c]) [d]) => (CMNconst x [int64(uint64(c)<<uint64(d))])
+(CMNshiftRL x (MOVDconst [c]) [d]) => (CMNconst x [int64(uint64(c)>>uint64(d))])
+(CMNshiftRA x (MOVDconst [c]) [d]) => (CMNconst x [c>>uint64(d)])
+(TSTshiftLL x (MOVDconst [c]) [d]) => (TSTconst x [int64(uint64(c)<<uint64(d))])
+(TSTshiftRL x (MOVDconst [c]) [d]) => (TSTconst x [int64(uint64(c)>>uint64(d))])
+(TSTshiftRA x (MOVDconst [c]) [d]) => (TSTconst x [c>>uint64(d)])
+(TSTshiftRO x (MOVDconst [c]) [d]) => (TSTconst x [rotateRight64(c, d)])
+
+// simplification with *shift ops
+(SUBshiftLL (SLLconst x [c]) x [c]) => (MOVDconst [0])
+(SUBshiftRL (SRLconst x [c]) x [c]) => (MOVDconst [0])
+(SUBshiftRA (SRAconst x [c]) x [c]) => (MOVDconst [0])
+(ANDshiftLL y:(SLLconst x [c]) x [c]) => y
+(ANDshiftRL y:(SRLconst x [c]) x [c]) => y
+(ANDshiftRA y:(SRAconst x [c]) x [c]) => y
+(ANDshiftRO y:(RORconst x [c]) x [c]) => y
+(ORshiftLL  y:(SLLconst x [c]) x [c]) => y
+(ORshiftRL  y:(SRLconst x [c]) x [c]) => y
+(ORshiftRA  y:(SRAconst x [c]) x [c]) => y
+(ORshiftRO  y:(RORconst x [c]) x [c]) => y
+(XORshiftLL (SLLconst x [c]) x [c]) => (MOVDconst [0])
+(XORshiftRL (SRLconst x [c]) x [c]) => (MOVDconst [0])
+(XORshiftRA (SRAconst x [c]) x [c]) => (MOVDconst [0])
+(XORshiftRO (RORconst x [c]) x [c]) => (MOVDconst [0])
+(BICshiftLL (SLLconst x [c]) x [c]) => (MOVDconst [0])
+(BICshiftRL (SRLconst x [c]) x [c]) => (MOVDconst [0])
+(BICshiftRA (SRAconst x [c]) x [c]) => (MOVDconst [0])
+(BICshiftRO (RORconst x [c]) x [c]) => (MOVDconst [0])
+(EONshiftLL (SLLconst x [c]) x [c]) => (MOVDconst [-1])
+(EONshiftRL (SRLconst x [c]) x [c]) => (MOVDconst [-1])
+(EONshiftRA (SRAconst x [c]) x [c]) => (MOVDconst [-1])
+(EONshiftRO (RORconst x [c]) x [c]) => (MOVDconst [-1])
+(ORNshiftLL (SLLconst x [c]) x [c]) => (MOVDconst [-1])
+(ORNshiftRL (SRLconst x [c]) x [c]) => (MOVDconst [-1])
+(ORNshiftRA (SRAconst x [c]) x [c]) => (MOVDconst [-1])
+(ORNshiftRO (RORconst x [c]) x [c]) => (MOVDconst [-1])
+
+// rev16w | rev16
+// ((x>>8) | (x<<8)) => (REV16W x), the type of x is uint16, "|" can also be "^" or "+".
+((ADDshiftLL|ORshiftLL|XORshiftLL) <typ.UInt16> [8] (UBFX <typ.UInt16> [armBFAuxInt(8, 8)] x) x) => (REV16W x)
+
+// ((x & 0xff00ff00)>>8) | ((x & 0x00ff00ff)<<8), "|" can also be "^" or "+".
+((ADDshiftLL|ORshiftLL|XORshiftLL) [8] (UBFX [armBFAuxInt(8, 24)] (ANDconst [c1] x)) (ANDconst [c2] x))
+	&& uint32(c1) == 0xff00ff00 && uint32(c2) == 0x00ff00ff
+	=> (REV16W x)
+
+// ((x & 0xff00ff00ff00ff00)>>8) | ((x & 0x00ff00ff00ff00ff)<<8), "|" can also be "^" or "+".
+((ADDshiftLL|ORshiftLL|XORshiftLL) [8] (SRLconst [8] (ANDconst [c1] x)) (ANDconst [c2] x))
+	&& (uint64(c1) == 0xff00ff00ff00ff00 && uint64(c2) == 0x00ff00ff00ff00ff)
+	=> (REV16 x)
+
+// ((x & 0xff00ff00)>>8) | ((x & 0x00ff00ff)<<8), "|" can also be "^" or "+".
+((ADDshiftLL|ORshiftLL|XORshiftLL) [8] (SRLconst [8] (ANDconst [c1] x)) (ANDconst [c2] x))
+	&& (uint64(c1) == 0xff00ff00 && uint64(c2) == 0x00ff00ff)
+	=> (REV16 (ANDconst <x.Type> [0xffffffff] x))
+
+// Extract from reg pair
+(ADDshiftLL [c] (SRLconst x [64-c]) x2) => (EXTRconst [64-c] x2 x)
+( ORshiftLL [c] (SRLconst x [64-c]) x2) => (EXTRconst [64-c] x2 x)
+(XORshiftLL [c] (SRLconst x [64-c]) x2) => (EXTRconst [64-c] x2 x)
+
+(ADDshiftLL <t> [c] (UBFX [bfc] x) x2) && c < 32 && t.Size() == 4 && bfc == armBFAuxInt(32-c, c)
+	=> (EXTRWconst [32-c] x2 x)
+( ORshiftLL <t> [c] (UBFX [bfc] x) x2) && c < 32 && t.Size() == 4 && bfc == armBFAuxInt(32-c, c)
+	=> (EXTRWconst [32-c] x2 x)
+(XORshiftLL <t> [c] (UBFX [bfc] x) x2) && c < 32 && t.Size() == 4 && bfc == armBFAuxInt(32-c, c)
+	=> (EXTRWconst [32-c] x2 x)
+
+// Rewrite special pairs of shifts to AND.
+// On ARM64 the bitmask can fit into an instruction.
+(SRLconst [c] (SLLconst [c] x)) && 0 < c && c < 64 => (ANDconst [1<<uint(64-c)-1] x) // mask out high bits
+(SLLconst [c] (SRLconst [c] x)) && 0 < c && c < 64 => (ANDconst [^(1<<uint(c)-1)] x) // mask out low bits
+
+// Special case setting bit as 1. An example is math.Copysign(c,-1)
+(ORconst [c1] (ANDconst [c2] x)) && c2|c1 == ^0  => (ORconst [c1] x)
+
+// If the shift amount is larger than the datasize(32, 16, 8), we can optimize to constant 0.
+(MOVWUreg (SLLconst [lc] x)) && lc >= 32 => (MOVDconst [0])
+(MOVHUreg (SLLconst [lc] x)) && lc >= 16 => (MOVDconst [0])
+(MOVBUreg (SLLconst [lc] x)) && lc >= 8 => (MOVDconst [0])
+
+// After zero extension, the upper (64-datasize(32|16|8)) bits are zero, we can optimiza to constant 0.
+(SRLconst [rc] (MOVWUreg x)) && rc >= 32 => (MOVDconst [0])
+(SRLconst [rc] (MOVHUreg x)) && rc >= 16 => (MOVDconst [0])
+(SRLconst [rc] (MOVBUreg x)) && rc >= 8 => (MOVDconst [0])
+
+// bitfield ops
+
+// sbfiz
+// (x << lc) >> rc
+(SRAconst [rc] (SLLconst [lc] x)) && lc > rc => (SBFIZ [armBFAuxInt(lc-rc, 64-lc)] x)
+// int64(x << lc)
+(MOVWreg (SLLconst [lc] x)) && lc < 32 => (SBFIZ [armBFAuxInt(lc, 32-lc)] x)
+(MOVHreg (SLLconst [lc] x)) && lc < 16 => (SBFIZ [armBFAuxInt(lc, 16-lc)] x)
+(MOVBreg (SLLconst [lc] x)) && lc < 8 => (SBFIZ [armBFAuxInt(lc, 8-lc)] x)
+// int64(x) << lc
+(SLLconst [lc] (MOVWreg x))  => (SBFIZ [armBFAuxInt(lc, min(32, 64-lc))] x)
+(SLLconst [lc] (MOVHreg x))  => (SBFIZ [armBFAuxInt(lc, min(16, 64-lc))] x)
+(SLLconst [lc] (MOVBreg x))  => (SBFIZ [armBFAuxInt(lc, min(8, 64-lc))] x)
+
+// sbfx
+// (x << lc) >> rc
+(SRAconst [rc] (SLLconst [lc] x)) && lc <= rc => (SBFX [armBFAuxInt(rc-lc, 64-rc)] x)
+// int64(x) >> rc
+(SRAconst [rc] (MOVWreg x)) && rc < 32 => (SBFX [armBFAuxInt(rc, 32-rc)] x)
+(SRAconst [rc] (MOVHreg x)) && rc < 16 => (SBFX [armBFAuxInt(rc, 16-rc)] x)
+(SRAconst [rc] (MOVBreg x)) && rc < 8 => (SBFX [armBFAuxInt(rc, 8-rc)] x)
+// merge sbfx and sign-extension into sbfx
+(MOVWreg (SBFX [bfc] x)) && bfc.getARM64BFwidth() <= 32 => (SBFX [bfc] x)
+(MOVHreg (SBFX [bfc] x)) && bfc.getARM64BFwidth() <= 16 => (SBFX [bfc] x)
+(MOVBreg (SBFX [bfc] x)) && bfc.getARM64BFwidth() <=  8 => (SBFX [bfc] x)
+
+// sbfiz/sbfx combinations: merge shifts into bitfield ops
+(SRAconst [sc] (SBFIZ [bfc] x)) && sc < bfc.getARM64BFlsb()
+	=> (SBFIZ [armBFAuxInt(bfc.getARM64BFlsb()-sc, bfc.getARM64BFwidth())] x)
+(SRAconst [sc] (SBFIZ [bfc] x)) && sc >= bfc.getARM64BFlsb()
+	&& sc < bfc.getARM64BFlsb()+bfc.getARM64BFwidth()
+	=> (SBFX [armBFAuxInt(sc-bfc.getARM64BFlsb(), bfc.getARM64BFlsb()+bfc.getARM64BFwidth()-sc)] x)
+
+// ubfiz
+// (x << lc) >> rc
+(SRLconst [rc] (SLLconst [lc] x)) && lc > rc => (UBFIZ [armBFAuxInt(lc-rc, 64-lc)] x)
+// uint64(x) << lc
+(SLLconst [lc] (MOVWUreg x))  => (UBFIZ [armBFAuxInt(lc, min(32, 64-lc))] x)
+(SLLconst [lc] (MOVHUreg x))  => (UBFIZ [armBFAuxInt(lc, min(16, 64-lc))] x)
+(SLLconst [lc] (MOVBUreg x))  => (UBFIZ [armBFAuxInt(lc, min(8, 64-lc))] x)
+// uint64(x << lc)
+(MOVWUreg (SLLconst [lc] x)) && lc < 32 => (UBFIZ [armBFAuxInt(lc, 32-lc)] x)
+(MOVHUreg (SLLconst [lc] x)) && lc < 16 => (UBFIZ [armBFAuxInt(lc, 16-lc)] x)
+(MOVBUreg (SLLconst [lc] x)) && lc < 8 => (UBFIZ [armBFAuxInt(lc, 8-lc)] x)
+
+// merge ANDconst into ubfiz
+// (x & ac) << sc
+(SLLconst [sc] (ANDconst [ac] x)) && isARM64BFMask(sc, ac, 0)
+	=> (UBFIZ [armBFAuxInt(sc, arm64BFWidth(ac, 0))] x)
+// (x << sc) & ac
+(ANDconst [ac] (SLLconst [sc] x)) && isARM64BFMask(sc, ac, sc)
+	=> (UBFIZ [armBFAuxInt(sc, arm64BFWidth(ac, sc))] x)
+
+// ubfx
+// (x << lc) >> rc
+(SRLconst [rc] (SLLconst [lc] x)) && lc < rc => (UBFX [armBFAuxInt(rc-lc, 64-rc)] x)
+// uint64(x) >> rc
+(SRLconst [rc] (MOVWUreg x)) && rc < 32 => (UBFX [armBFAuxInt(rc, 32-rc)] x)
+(SRLconst [rc] (MOVHUreg x)) && rc < 16 => (UBFX [armBFAuxInt(rc, 16-rc)] x)
+(SRLconst [rc] (MOVBUreg x)) && rc < 8 => (UBFX [armBFAuxInt(rc, 8-rc)] x)
+// uint64(x >> rc)
+(MOVWUreg (SRLconst [rc] x)) && rc < 32 => (UBFX [armBFAuxInt(rc, 32)] x)
+(MOVHUreg (SRLconst [rc] x)) && rc < 16 => (UBFX [armBFAuxInt(rc, 16)] x)
+(MOVBUreg (SRLconst [rc] x)) && rc < 8 => (UBFX [armBFAuxInt(rc, 8)] x)
+// merge ANDconst into ubfx
+// (x >> sc) & ac
+(ANDconst [ac] (SRLconst [sc] x)) && isARM64BFMask(sc, ac, 0)
+	=> (UBFX [armBFAuxInt(sc, arm64BFWidth(ac, 0))] x)
+// (x & ac) >> sc
+(SRLconst [sc] (ANDconst [ac] x)) && isARM64BFMask(sc, ac, sc)
+	=> (UBFX [armBFAuxInt(sc, arm64BFWidth(ac, sc))] x)
+// merge ANDconst and ubfx into ubfx
+(ANDconst [c] (UBFX [bfc] x)) && isARM64BFMask(0, c, 0) =>
+	(UBFX [armBFAuxInt(bfc.getARM64BFlsb(), min(bfc.getARM64BFwidth(), arm64BFWidth(c, 0)))] x)
+(UBFX [bfc] (ANDconst [c] x)) && isARM64BFMask(0, c, 0) && bfc.getARM64BFlsb() + bfc.getARM64BFwidth() <= arm64BFWidth(c, 0) =>
+	(UBFX [bfc] x)
+// merge ubfx and zerso-extension into ubfx
+(MOVWUreg (UBFX [bfc] x)) && bfc.getARM64BFwidth() <= 32 => (UBFX [bfc] x)
+(MOVHUreg (UBFX [bfc] x)) && bfc.getARM64BFwidth() <= 16 => (UBFX [bfc] x)
+(MOVBUreg (UBFX [bfc] x)) && bfc.getARM64BFwidth() <=  8 => (UBFX [bfc] x)
+
+// ubfiz/ubfx combinations: merge shifts into bitfield ops
+(SRLconst [sc] (UBFX [bfc] x)) && sc < bfc.getARM64BFwidth()
+	=> (UBFX [armBFAuxInt(bfc.getARM64BFlsb()+sc, bfc.getARM64BFwidth()-sc)] x)
+(UBFX [bfc] (SRLconst [sc] x)) && sc+bfc.getARM64BFwidth()+bfc.getARM64BFlsb() < 64
+	=> (UBFX [armBFAuxInt(bfc.getARM64BFlsb()+sc, bfc.getARM64BFwidth())] x)
+(SLLconst [sc] (UBFIZ [bfc] x)) && sc+bfc.getARM64BFwidth()+bfc.getARM64BFlsb() < 64
+	=> (UBFIZ [armBFAuxInt(bfc.getARM64BFlsb()+sc, bfc.getARM64BFwidth())] x)
+(UBFIZ [bfc] (SLLconst [sc] x)) && sc < bfc.getARM64BFwidth()
+	=> (UBFIZ [armBFAuxInt(bfc.getARM64BFlsb()+sc, bfc.getARM64BFwidth()-sc)] x)
+// ((x << c1) >> c2) >> c3
+(SRLconst [sc] (UBFIZ [bfc] x)) && sc == bfc.getARM64BFlsb()
+	=> (ANDconst [1<<uint(bfc.getARM64BFwidth())-1] x)
+(SRLconst [sc] (UBFIZ [bfc] x)) && sc < bfc.getARM64BFlsb()
+	=> (UBFIZ [armBFAuxInt(bfc.getARM64BFlsb()-sc, bfc.getARM64BFwidth())] x)
+(SRLconst [sc] (UBFIZ [bfc] x)) && sc > bfc.getARM64BFlsb()
+	&& sc < bfc.getARM64BFlsb()+bfc.getARM64BFwidth()
+	=> (UBFX [armBFAuxInt(sc-bfc.getARM64BFlsb(), bfc.getARM64BFlsb()+bfc.getARM64BFwidth()-sc)] x)
+// ((x << c1) << c2) >> c3
+(UBFX [bfc] (SLLconst [sc] x)) && sc == bfc.getARM64BFlsb()
+	=> (ANDconst [1<<uint(bfc.getARM64BFwidth())-1] x)
+(UBFX [bfc] (SLLconst [sc] x)) && sc < bfc.getARM64BFlsb()
+	=> (UBFX [armBFAuxInt(bfc.getARM64BFlsb()-sc, bfc.getARM64BFwidth())] x)
+(UBFX [bfc] (SLLconst [sc] x)) && sc > bfc.getARM64BFlsb()
+	&& sc < bfc.getARM64BFlsb()+bfc.getARM64BFwidth()
+	=> (UBFIZ [armBFAuxInt(sc-bfc.getARM64BFlsb(), bfc.getARM64BFlsb()+bfc.getARM64BFwidth()-sc)] x)
+
+// bfi
+(OR (UBFIZ [bfc] x) (ANDconst [ac] y))
+	&& ac == ^((1<<uint(bfc.getARM64BFwidth())-1) << uint(bfc.getARM64BFlsb()))
+	=> (BFI [bfc] y x)
+(ORshiftRL [rc] (ANDconst [ac] x) (SLLconst [lc] y))
+	&& lc > rc && ac == ^((1<<uint(64-lc)-1) << uint64(lc-rc))
+	=> (BFI [armBFAuxInt(lc-rc, 64-lc)] x y)
+// bfxil
+(OR (UBFX [bfc] x) (ANDconst [ac] y)) && ac == ^(1<<uint(bfc.getARM64BFwidth())-1)
+	=> (BFXIL [bfc] y x)
+(ORshiftLL [sc] (UBFX [bfc] x) (SRLconst [sc] y)) && sc == bfc.getARM64BFwidth()
+	=> (BFXIL [bfc] y x)
+(ORshiftRL [rc] (ANDconst [ac] y) (SLLconst [lc] x)) && lc < rc && ac == ^((1<<uint(64-rc)-1))
+	=> (BFXIL [armBFAuxInt(rc-lc, 64-rc)] y x)
+
+// do combined loads
+// little endian loads
+// b[0] | b[1]<<8 => load 16-bit
+(ORshiftLL <t> [8]
+	y0:(MOVDnop x0:(MOVBUload [i0] {s} p mem))
+	y1:(MOVDnop x1:(MOVBUload [i1] {s} p mem)))
+	&& i1 == i0+1
+	&& x0.Uses == 1 && x1.Uses == 1
+	&& y0.Uses == 1 && y1.Uses == 1
+	&& mergePoint(b,x0,x1) != nil
+	&& clobber(x0, x1, y0, y1)
+	=> @mergePoint(b,x0,x1) (MOVHUload <t> {s} (OffPtr <p.Type> [int64(i0)] p) mem)
+(ORshiftLL <t> [8]
+	y0:(MOVDnop x0:(MOVBUloadidx ptr0 idx0 mem))
+	y1:(MOVDnop x1:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem)))
+	&& s == nil
+	&& x0.Uses == 1 && x1.Uses == 1
+	&& y0.Uses == 1 && y1.Uses == 1
+	&& mergePoint(b,x0,x1) != nil
+	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
+	&& clobber(x0, x1, y0, y1)
+	=> @mergePoint(b,x0,x1) (MOVHUloadidx <t> ptr0 idx0 mem)
+(ORshiftLL <t> [8]
+	y0:(MOVDnop x0:(MOVBUloadidx ptr idx mem))
+	y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [1] idx) mem)))
+	&& x0.Uses == 1 && x1.Uses == 1
+	&& y0.Uses == 1 && y1.Uses == 1
+	&& mergePoint(b,x0,x1) != nil
+	&& clobber(x0, x1, y0, y1)
+	=> @mergePoint(b,x0,x1) (MOVHUloadidx <t> ptr idx mem)
+
+// b[0] | b[1]<<8 | b[2]<<16 | b[3]<<24 => load 32-bit
+(ORshiftLL <t> [24] o0:(ORshiftLL [16]
+	            x0:(MOVHUload [i0] {s} p mem)
+	y1:(MOVDnop x1:(MOVBUload [i2] {s} p mem)))
+	y2:(MOVDnop x2:(MOVBUload [i3] {s} p mem)))
+	&& i2 == i0+2
+	&& i3 == i0+3
+	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1
+	&& y1.Uses == 1 && y2.Uses == 1
+	&& o0.Uses == 1
+	&& mergePoint(b,x0,x1,x2) != nil
+	&& clobber(x0, x1, x2, y1, y2, o0)
+	=> @mergePoint(b,x0,x1,x2) (MOVWUload <t> {s} (OffPtr <p.Type> [int64(i0)] p) mem)
+(ORshiftLL <t> [24] o0:(ORshiftLL [16]
+	            x0:(MOVHUloadidx ptr0 idx0 mem)
+	y1:(MOVDnop x1:(MOVBUload [2] {s} p1:(ADD ptr1 idx1) mem)))
+	y2:(MOVDnop x2:(MOVBUload [3] {s} p mem)))
+	&& s == nil
+	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1
+	&& y1.Uses == 1 && y2.Uses == 1
+	&& o0.Uses == 1
+	&& mergePoint(b,x0,x1,x2) != nil
+	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
+	&& isSamePtr(p1, p)
+	&& clobber(x0, x1, x2, y1, y2, o0)
+	=> @mergePoint(b,x0,x1,x2) (MOVWUloadidx <t> ptr0 idx0 mem)
+(ORshiftLL <t> [24] o0:(ORshiftLL [16]
+	            x0:(MOVHUloadidx ptr idx mem)
+	y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [2] idx) mem)))
+	y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [3] idx) mem)))
+	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1
+	&& y1.Uses == 1 && y2.Uses == 1
+	&& o0.Uses == 1
+	&& mergePoint(b,x0,x1,x2) != nil
+	&& clobber(x0, x1, x2, y1, y2, o0)
+	=> @mergePoint(b,x0,x1,x2) (MOVWUloadidx <t> ptr idx mem)
+(ORshiftLL <t> [24] o0:(ORshiftLL [16]
+	            x0:(MOVHUloadidx2 ptr0 idx0 mem)
+	y1:(MOVDnop x1:(MOVBUload [2] {s} p1:(ADDshiftLL [1] ptr1 idx1) mem)))
+	y2:(MOVDnop x2:(MOVBUload [3] {s} p mem)))
+	&& s == nil
+	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1
+	&& y1.Uses == 1 && y2.Uses == 1
+	&& o0.Uses == 1
+	&& mergePoint(b,x0,x1,x2) != nil
+	&& isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1)
+	&& isSamePtr(p1, p)
+	&& clobber(x0, x1, x2, y1, y2, o0)
+	=> @mergePoint(b,x0,x1,x2) (MOVWUloadidx <t> ptr0 (SLLconst <idx0.Type> [1] idx0) mem)
+
+// b[0] | b[1]<<8 | b[2]<<16 | b[3]<<24 | b[4]<<32 | b[5]<<40 | b[6]<<48 | b[7]<<56 => load 64-bit
+(ORshiftLL <t> [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32]
+	            x0:(MOVWUload [i0] {s} p mem)
+	y1:(MOVDnop x1:(MOVBUload [i4] {s} p mem)))
+	y2:(MOVDnop x2:(MOVBUload [i5] {s} p mem)))
+	y3:(MOVDnop x3:(MOVBUload [i6] {s} p mem)))
+	y4:(MOVDnop x4:(MOVBUload [i7] {s} p mem)))
+	&& i4 == i0+4
+	&& i5 == i0+5
+	&& i6 == i0+6
+	&& i7 == i0+7
+	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1
+	&& y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1
+	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1
+	&& mergePoint(b,x0,x1,x2,x3,x4) != nil
+	&& clobber(x0, x1, x2, x3, x4, y1, y2, y3, y4, o0, o1, o2)
+	=> @mergePoint(b,x0,x1,x2,x3,x4) (MOVDload <t> {s} (OffPtr <p.Type> [int64(i0)] p) mem)
+(ORshiftLL <t> [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32]
+	            x0:(MOVWUloadidx ptr0 idx0 mem)
+	y1:(MOVDnop x1:(MOVBUload [4] {s} p1:(ADD ptr1 idx1) mem)))
+	y2:(MOVDnop x2:(MOVBUload [5] {s} p mem)))
+	y3:(MOVDnop x3:(MOVBUload [6] {s} p mem)))
+	y4:(MOVDnop x4:(MOVBUload [7] {s} p mem)))
+	&& s == nil
+	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1
+	&& y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1
+	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1
+	&& mergePoint(b,x0,x1,x2,x3,x4) != nil
+	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
+	&& isSamePtr(p1, p)
+	&& clobber(x0, x1, x2, x3, x4, y1, y2, y3, y4, o0, o1, o2)
+	=> @mergePoint(b,x0,x1,x2,x3,x4) (MOVDloadidx <t> ptr0 idx0 mem)
+(ORshiftLL <t> [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32]
+	            x0:(MOVWUloadidx4 ptr0 idx0 mem)
+	y1:(MOVDnop x1:(MOVBUload [4] {s} p1:(ADDshiftLL [2] ptr1 idx1) mem)))
+	y2:(MOVDnop x2:(MOVBUload [5] {s} p mem)))
+	y3:(MOVDnop x3:(MOVBUload [6] {s} p mem)))
+	y4:(MOVDnop x4:(MOVBUload [7] {s} p mem)))
+	&& s == nil
+	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1
+	&& y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1
+	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1
+	&& mergePoint(b,x0,x1,x2,x3,x4) != nil
+	&& isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1)
+	&& isSamePtr(p1, p)
+	&& clobber(x0, x1, x2, x3, x4, y1, y2, y3, y4, o0, o1, o2)
+	=> @mergePoint(b,x0,x1,x2,x3,x4) (MOVDloadidx <t> ptr0 (SLLconst <idx0.Type> [2] idx0) mem)
+(ORshiftLL <t> [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32]
+	            x0:(MOVWUloadidx ptr idx mem)
+	y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [4] idx) mem)))
+	y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [5] idx) mem)))
+	y3:(MOVDnop x3:(MOVBUloadidx ptr (ADDconst [6] idx) mem)))
+	y4:(MOVDnop x4:(MOVBUloadidx ptr (ADDconst [7] idx) mem)))
+	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1
+	&& y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1
+	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1
+	&& mergePoint(b,x0,x1,x2,x3,x4) != nil
+	&& clobber(x0, x1, x2, x3, x4, y1, y2, y3, y4, o0, o1, o2)
+	=> @mergePoint(b,x0,x1,x2,x3,x4) (MOVDloadidx <t> ptr idx mem)
+
+// b[3]<<24 | b[2]<<16 | b[1]<<8 | b[0] => load 32-bit
+(OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24]
+	y0:(MOVDnop x0:(MOVBUload [i3] {s} p mem)))
+	y1:(MOVDnop x1:(MOVBUload [i2] {s} p mem)))
+	y2:(MOVDnop x2:(MOVBUload [i1] {s} p mem)))
+	y3:(MOVDnop x3:(MOVBUload [i0] {s} p mem)))
+	&& i1 == i0+1
+	&& i2 == i0+2
+	&& i3 == i0+3
+	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
+	&& y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1
+	&& o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1
+	&& mergePoint(b,x0,x1,x2,x3) != nil
+	&& clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)
+	=> @mergePoint(b,x0,x1,x2,x3) (MOVWUload <t> {s} (OffPtr <p.Type> [int64(i0)] p) mem)
+(OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24]
+	y0:(MOVDnop x0:(MOVBUload [3] {s} p mem)))
+	y1:(MOVDnop x1:(MOVBUload [2] {s} p mem)))
+	y2:(MOVDnop x2:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem)))
+	y3:(MOVDnop x3:(MOVBUloadidx ptr0 idx0 mem)))
+	&& s == nil
+	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
+	&& y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1
+	&& o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1
+	&& mergePoint(b,x0,x1,x2,x3) != nil
+	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
+	&& isSamePtr(p1, p)
+	&& clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)
+	=> @mergePoint(b,x0,x1,x2,x3) (MOVWUloadidx <t> ptr0 idx0 mem)
+(OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24]
+	y0:(MOVDnop x0:(MOVBUloadidx ptr (ADDconst [3] idx) mem)))
+	y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [2] idx) mem)))
+	y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [1] idx) mem)))
+	y3:(MOVDnop x3:(MOVBUloadidx ptr idx mem)))
+	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
+	&& y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1
+	&& o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1
+	&& mergePoint(b,x0,x1,x2,x3) != nil
+	&& clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)
+	=> @mergePoint(b,x0,x1,x2,x3) (MOVWUloadidx <t> ptr idx mem)
+
+// b[7]<<56 | b[6]<<48 | b[5]<<40 | b[4]<<32 | b[3]<<24 | b[2]<<16 | b[1]<<8 | b[0] => load 64-bit
+(OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56]
+	y0:(MOVDnop x0:(MOVBUload [i7] {s} p mem)))
+	y1:(MOVDnop x1:(MOVBUload [i6] {s} p mem)))
+	y2:(MOVDnop x2:(MOVBUload [i5] {s} p mem)))
+	y3:(MOVDnop x3:(MOVBUload [i4] {s} p mem)))
+	y4:(MOVDnop x4:(MOVBUload [i3] {s} p mem)))
+	y5:(MOVDnop x5:(MOVBUload [i2] {s} p mem)))
+	y6:(MOVDnop x6:(MOVBUload [i1] {s} p mem)))
+	y7:(MOVDnop x7:(MOVBUload [i0] {s} p mem)))
+	&& i1 == i0+1
+	&& i2 == i0+2
+	&& i3 == i0+3
+	&& i4 == i0+4
+	&& i5 == i0+5
+	&& i6 == i0+6
+	&& i7 == i0+7
+	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
+	&& x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1
+	&& y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1
+	&& y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1
+	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1
+	&& o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1
+	&& mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil
+	&& clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)
+	=> @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} (OffPtr <p.Type> [int64(i0)] p) mem)
+(OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56]
+	y0:(MOVDnop x0:(MOVBUload [7] {s} p mem)))
+	y1:(MOVDnop x1:(MOVBUload [6] {s} p mem)))
+	y2:(MOVDnop x2:(MOVBUload [5] {s} p mem)))
+	y3:(MOVDnop x3:(MOVBUload [4] {s} p mem)))
+	y4:(MOVDnop x4:(MOVBUload [3] {s} p mem)))
+	y5:(MOVDnop x5:(MOVBUload [2] {s} p mem)))
+	y6:(MOVDnop x6:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem)))
+	y7:(MOVDnop x7:(MOVBUloadidx ptr0 idx0 mem)))
+	&& s == nil
+	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
+	&& x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1
+	&& y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1
+	&& y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1
+	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1
+	&& o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1
+	&& mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil
+	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
+	&& isSamePtr(p1, p)
+	&& clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)
+	=> @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDloadidx <t> ptr0 idx0 mem)
+(OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56]
+	y0:(MOVDnop x0:(MOVBUloadidx ptr (ADDconst [7] idx) mem)))
+	y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [6] idx) mem)))
+	y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [5] idx) mem)))
+	y3:(MOVDnop x3:(MOVBUloadidx ptr (ADDconst [4] idx) mem)))
+	y4:(MOVDnop x4:(MOVBUloadidx ptr (ADDconst [3] idx) mem)))
+	y5:(MOVDnop x5:(MOVBUloadidx ptr (ADDconst [2] idx) mem)))
+	y6:(MOVDnop x6:(MOVBUloadidx ptr (ADDconst [1] idx) mem)))
+	y7:(MOVDnop x7:(MOVBUloadidx ptr idx mem)))
+	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
+	&& x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1
+	&& y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1
+	&& y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1
+	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1
+	&& o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1
+	&& mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil
+	&& clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)
+	=> @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDloadidx <t> ptr idx mem)
+
+// big endian loads
+// b[1] | b[0]<<8 => load 16-bit, reverse
+(ORshiftLL <t> [8]
+	y0:(MOVDnop x0:(MOVBUload [i1] {s} p mem))
+	y1:(MOVDnop x1:(MOVBUload [i0] {s} p mem)))
+	&& i1 == i0+1
+	&& x0.Uses == 1 && x1.Uses == 1
+	&& y0.Uses == 1 && y1.Uses == 1
+	&& mergePoint(b,x0,x1) != nil
+	&& clobber(x0, x1, y0, y1)
+	=> @mergePoint(b,x0,x1) (REV16W <t> (MOVHUload <t> [i0] {s} p mem))
+(ORshiftLL <t> [8]
+	y0:(MOVDnop x0:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem))
+	y1:(MOVDnop x1:(MOVBUloadidx ptr0 idx0 mem)))
+	&& s == nil
+	&& x0.Uses == 1 && x1.Uses == 1
+	&& y0.Uses == 1 && y1.Uses == 1
+	&& mergePoint(b,x0,x1) != nil
+	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
+	&& clobber(x0, x1, y0, y1)
+	=> @mergePoint(b,x0,x1) (REV16W <t> (MOVHUloadidx <t> ptr0 idx0 mem))
+(ORshiftLL <t> [8]
+	y0:(MOVDnop x0:(MOVBUloadidx ptr (ADDconst [1] idx) mem))
+	y1:(MOVDnop x1:(MOVBUloadidx ptr idx mem)))
+	&& x0.Uses == 1 && x1.Uses == 1
+	&& y0.Uses == 1 && y1.Uses == 1
+	&& mergePoint(b,x0,x1) != nil
+	&& clobber(x0, x1, y0, y1)
+	=> @mergePoint(b,x0,x1) (REV16W <t> (MOVHUloadidx <t> ptr idx mem))
+
+// b[3] | b[2]<<8 | b[1]<<16 | b[0]<<24 => load 32-bit, reverse
+(ORshiftLL <t> [24] o0:(ORshiftLL [16]
+	y0:(REV16W  x0:(MOVHUload [i2] {s} p mem))
+	y1:(MOVDnop x1:(MOVBUload [i1] {s} p mem)))
+	y2:(MOVDnop x2:(MOVBUload [i0] {s} p mem)))
+	&& i1 == i0+1
+	&& i2 == i0+2
+	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1
+	&& y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1
+	&& o0.Uses == 1
+	&& mergePoint(b,x0,x1,x2) != nil
+	&& clobber(x0, x1, x2, y0, y1, y2, o0)
+	=> @mergePoint(b,x0,x1,x2) (REVW <t> (MOVWUload <t> {s} (OffPtr <p.Type> [int64(i0)] p) mem))
+(ORshiftLL <t> [24] o0:(ORshiftLL [16]
+	y0:(REV16W  x0:(MOVHUload [2] {s} p mem))
+	y1:(MOVDnop x1:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem)))
+	y2:(MOVDnop x2:(MOVBUloadidx ptr0 idx0 mem)))
+	&& s == nil
+	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1
+	&& y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1
+	&& o0.Uses == 1
+	&& mergePoint(b,x0,x1,x2) != nil
+	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
+	&& isSamePtr(p1, p)
+	&& clobber(x0, x1, x2, y0, y1, y2, o0)
+	=> @mergePoint(b,x0,x1,x2) (REVW <t> (MOVWUloadidx <t> ptr0 idx0 mem))
+(ORshiftLL <t> [24] o0:(ORshiftLL [16]
+	y0:(REV16W  x0:(MOVHUloadidx ptr (ADDconst [2] idx) mem))
+	y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [1] idx) mem)))
+	y2:(MOVDnop x2:(MOVBUloadidx ptr idx mem)))
+	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1
+	&& y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1
+	&& o0.Uses == 1
+	&& mergePoint(b,x0,x1,x2) != nil
+	&& clobber(x0, x1, x2, y0, y1, y2, o0)
+	=> @mergePoint(b,x0,x1,x2) (REVW <t> (MOVWUloadidx <t> ptr idx mem))
+
+// b[7] | b[6]<<8 | b[5]<<16 | b[4]<<24 | b[3]<<32 | b[2]<<40 | b[1]<<48 | b[0]<<56 => load 64-bit, reverse
+(ORshiftLL <t> [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32]
+	y0:(REVW    x0:(MOVWUload [i4] {s} p mem))
+	y1:(MOVDnop x1:(MOVBUload [i3] {s} p mem)))
+	y2:(MOVDnop x2:(MOVBUload [i2] {s} p mem)))
+	y3:(MOVDnop x3:(MOVBUload [i1] {s} p mem)))
+	y4:(MOVDnop x4:(MOVBUload [i0] {s} p mem)))
+	&& i1 == i0+1
+	&& i2 == i0+2
+	&& i3 == i0+3
+	&& i4 == i0+4
+	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1
+	&& y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1
+	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1
+	&& mergePoint(b,x0,x1,x2,x3,x4) != nil
+	&& clobber(x0, x1, x2, x3, x4, y0, y1, y2, y3, y4, o0, o1, o2)
+	=> @mergePoint(b,x0,x1,x2,x3,x4) (REV <t> (MOVDload <t> {s} (OffPtr <p.Type> [int64(i0)] p) mem))
+(ORshiftLL <t> [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32]
+	y0:(REVW    x0:(MOVWUload [4] {s} p mem))
+	y1:(MOVDnop x1:(MOVBUload [3] {s} p mem)))
+	y2:(MOVDnop x2:(MOVBUload [2] {s} p mem)))
+	y3:(MOVDnop x3:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem)))
+	y4:(MOVDnop x4:(MOVBUloadidx ptr0 idx0 mem)))
+	&& s == nil
+	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1
+	&& y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1
+	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1
+	&& mergePoint(b,x0,x1,x2,x3,x4) != nil
+	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
+	&& isSamePtr(p1, p)
+	&& clobber(x0, x1, x2, x3, x4, y0, y1, y2, y3, y4, o0, o1, o2)
+	=> @mergePoint(b,x0,x1,x2,x3,x4) (REV <t> (MOVDloadidx <t> ptr0 idx0 mem))
+(ORshiftLL <t> [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32]
+	y0:(REVW    x0:(MOVWUloadidx ptr (ADDconst [4] idx) mem))
+	y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [3] idx) mem)))
+	y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [2] idx) mem)))
+	y3:(MOVDnop x3:(MOVBUloadidx ptr (ADDconst [1] idx) mem)))
+	y4:(MOVDnop x4:(MOVBUloadidx ptr idx mem)))
+	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1
+	&& y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1
+	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1
+	&& mergePoint(b,x0,x1,x2,x3,x4) != nil
+	&& clobber(x0, x1, x2, x3, x4, y0, y1, y2, y3, y4, o0, o1, o2)
+	=> @mergePoint(b,x0,x1,x2,x3,x4) (REV <t> (MOVDloadidx <t> ptr idx mem))
+
+// b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3] => load 32-bit, reverse
+(OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24]
+	y0:(MOVDnop x0:(MOVBUload [i0] {s} p mem)))
+	y1:(MOVDnop x1:(MOVBUload [i1] {s} p mem)))
+	y2:(MOVDnop x2:(MOVBUload [i2] {s} p mem)))
+	y3:(MOVDnop x3:(MOVBUload [i3] {s} p mem)))
+	&& i1 == i0+1
+	&& i2 == i0+2
+	&& i3 == i0+3
+	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
+	&& y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1
+	&& o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1
+	&& mergePoint(b,x0,x1,x2,x3) != nil
+	&& clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)
+	=> @mergePoint(b,x0,x1,x2,x3) (REVW <t> (MOVWUload <t> {s} (OffPtr <p.Type> [int64(i0)] p) mem))
+(OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24]
+	y0:(MOVDnop x0:(MOVBUloadidx ptr0 idx0 mem)))
+	y1:(MOVDnop x1:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem)))
+	y2:(MOVDnop x2:(MOVBUload [2] {s} p mem)))
+	y3:(MOVDnop x3:(MOVBUload [3] {s} p mem)))
+	&& s == nil
+	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
+	&& y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1
+	&& o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1
+	&& mergePoint(b,x0,x1,x2,x3) != nil
+	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
+	&& isSamePtr(p1, p)
+	&& clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)
+	=> @mergePoint(b,x0,x1,x2,x3) (REVW <t> (MOVWUloadidx <t> ptr0 idx0 mem))
+(OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24]
+	y0:(MOVDnop x0:(MOVBUloadidx ptr idx mem)))
+	y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [1] idx) mem)))
+	y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [2] idx) mem)))
+	y3:(MOVDnop x3:(MOVBUloadidx ptr (ADDconst [3] idx) mem)))
+	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
+	&& y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1
+	&& o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1
+	&& mergePoint(b,x0,x1,x2,x3) != nil
+	&& clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)
+	=> @mergePoint(b,x0,x1,x2,x3) (REVW <t> (MOVWUloadidx <t> ptr idx mem))
+
+// b[0]<<56 | b[1]<<48 | b[2]<<40 | b[3]<<32 | b[4]<<24 | b[5]<<16 | b[6]<<8 | b[7] => load 64-bit, reverse
+(OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56]
+	y0:(MOVDnop x0:(MOVBUload [i0] {s} p mem)))
+	y1:(MOVDnop x1:(MOVBUload [i1] {s} p mem)))
+	y2:(MOVDnop x2:(MOVBUload [i2] {s} p mem)))
+	y3:(MOVDnop x3:(MOVBUload [i3] {s} p mem)))
+	y4:(MOVDnop x4:(MOVBUload [i4] {s} p mem)))
+	y5:(MOVDnop x5:(MOVBUload [i5] {s} p mem)))
+	y6:(MOVDnop x6:(MOVBUload [i6] {s} p mem)))
+	y7:(MOVDnop x7:(MOVBUload [i7] {s} p mem)))
+	&& i1 == i0+1
+	&& i2 == i0+2
+	&& i3 == i0+3
+	&& i4 == i0+4
+	&& i5 == i0+5
+	&& i6 == i0+6
+	&& i7 == i0+7
+	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
+	&& x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1
+	&& y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1
+	&& y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1
+	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1
+	&& o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1
+	&& mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil
+	&& clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)
+	=> @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (REV <t> (MOVDload <t> {s} (OffPtr <p.Type> [int64(i0)] p) mem))
+(OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56]
+	y0:(MOVDnop x0:(MOVBUloadidx ptr0 idx0 mem)))
+	y1:(MOVDnop x1:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem)))
+	y2:(MOVDnop x2:(MOVBUload [2] {s} p mem)))
+	y3:(MOVDnop x3:(MOVBUload [3] {s} p mem)))
+	y4:(MOVDnop x4:(MOVBUload [4] {s} p mem)))
+	y5:(MOVDnop x5:(MOVBUload [5] {s} p mem)))
+	y6:(MOVDnop x6:(MOVBUload [6] {s} p mem)))
+	y7:(MOVDnop x7:(MOVBUload [7] {s} p mem)))
+	&& s == nil
+	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
+	&& x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1
+	&& y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1
+	&& y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1
+	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1
+	&& o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1
+	&& mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil
+	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
+	&& isSamePtr(p1, p)
+	&& clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)
+	=> @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (REV <t> (MOVDloadidx <t> ptr0 idx0 mem))
+(OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56]
+	y0:(MOVDnop x0:(MOVBUloadidx ptr idx mem)))
+	y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [1] idx) mem)))
+	y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [2] idx) mem)))
+	y3:(MOVDnop x3:(MOVBUloadidx ptr (ADDconst [3] idx) mem)))
+	y4:(MOVDnop x4:(MOVBUloadidx ptr (ADDconst [4] idx) mem)))
+	y5:(MOVDnop x5:(MOVBUloadidx ptr (ADDconst [5] idx) mem)))
+	y6:(MOVDnop x6:(MOVBUloadidx ptr (ADDconst [6] idx) mem)))
+	y7:(MOVDnop x7:(MOVBUloadidx ptr (ADDconst [7] idx) mem)))
+	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
+	&& x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1
+	&& y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1
+	&& y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1
+	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1
+	&& o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1
+	&& mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil
+	&& clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)
+	=> @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (REV <t> (MOVDloadidx <t> ptr idx mem))
+
+// Combine zero stores into larger (unaligned) stores.
+(MOVBstorezero [i] {s} ptr0 x:(MOVBstorezero [j] {s} ptr1 mem))
+	&& x.Uses == 1
+	&& areAdjacentOffsets(int64(i),int64(j),1)
+	&& isSamePtr(ptr0, ptr1)
+	&& clobber(x)
+	=> (MOVHstorezero [int32(min(int64(i),int64(j)))] {s} ptr0 mem)
+(MOVBstorezero [1] {s} (ADD ptr0 idx0) x:(MOVBstorezeroidx ptr1 idx1 mem))
+	&& x.Uses == 1
+	&& s == nil
+	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
+	&& clobber(x)
+	=> (MOVHstorezeroidx ptr1 idx1 mem)
+(MOVBstorezeroidx ptr (ADDconst [1] idx) x:(MOVBstorezeroidx ptr idx mem))
+	&& x.Uses == 1
+	&& clobber(x)
+	=> (MOVHstorezeroidx ptr idx mem)
+(MOVHstorezero [i] {s} ptr0 x:(MOVHstorezero [j] {s} ptr1 mem))
+	&& x.Uses == 1
+	&& areAdjacentOffsets(int64(i),int64(j),2)
+	&& isSamePtr(ptr0, ptr1)
+	&& clobber(x)
+	=> (MOVWstorezero [int32(min(int64(i),int64(j)))] {s} ptr0 mem)
+(MOVHstorezero [2] {s} (ADD ptr0 idx0) x:(MOVHstorezeroidx ptr1 idx1 mem))
+	&& x.Uses == 1
+	&& s == nil
+	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
+	&& clobber(x)
+	=> (MOVWstorezeroidx ptr1 idx1 mem)
+(MOVHstorezeroidx ptr (ADDconst [2] idx) x:(MOVHstorezeroidx ptr idx mem))
+	&& x.Uses == 1
+	&& clobber(x)
+	=> (MOVWstorezeroidx ptr idx mem)
+(MOVHstorezero [2] {s} (ADDshiftLL [1] ptr0 idx0) x:(MOVHstorezeroidx2 ptr1 idx1 mem))
+	&& x.Uses == 1
+	&& s == nil
+	&& isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1)
+	&& clobber(x)
+	=> (MOVWstorezeroidx ptr1 (SLLconst <idx1.Type> [1] idx1) mem)
+(MOVWstorezero [i] {s} ptr0 x:(MOVWstorezero [j] {s} ptr1 mem))
+	&& x.Uses == 1
+	&& areAdjacentOffsets(int64(i),int64(j),4)
+	&& isSamePtr(ptr0, ptr1)
+	&& clobber(x)
+	=> (MOVDstorezero [int32(min(int64(i),int64(j)))] {s} ptr0 mem)
+(MOVWstorezero [4] {s} (ADD ptr0 idx0) x:(MOVWstorezeroidx ptr1 idx1 mem))
+	&& x.Uses == 1
+	&& s == nil
+	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
+	&& clobber(x)
+	=> (MOVDstorezeroidx ptr1 idx1 mem)
+(MOVWstorezeroidx ptr (ADDconst [4] idx) x:(MOVWstorezeroidx ptr idx mem))
+	&& x.Uses == 1
+	&& clobber(x)
+	=> (MOVDstorezeroidx ptr idx mem)
+(MOVWstorezero [4] {s} (ADDshiftLL [2] ptr0 idx0) x:(MOVWstorezeroidx4 ptr1 idx1 mem))
+	&& x.Uses == 1
+	&& s == nil
+	&& isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1)
+	&& clobber(x)
+	=> (MOVDstorezeroidx ptr1 (SLLconst <idx1.Type> [2] idx1) mem)
+(MOVDstorezero [i] {s} ptr0 x:(MOVDstorezero [j] {s} ptr1 mem))
+	&& x.Uses == 1
+	&& areAdjacentOffsets(int64(i),int64(j),8)
+	&& isSamePtr(ptr0, ptr1)
+	&& clobber(x)
+	=> (MOVQstorezero [int32(min(int64(i),int64(j)))] {s} ptr0 mem)
+(MOVDstorezero [8] {s} p0:(ADD ptr0 idx0) x:(MOVDstorezeroidx ptr1 idx1 mem))
+	&& x.Uses == 1
+	&& s == nil
+	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
+	&& clobber(x)
+	=> (MOVQstorezero [0] {s} p0 mem)
+(MOVDstorezero [8] {s} p0:(ADDshiftLL [3] ptr0 idx0) x:(MOVDstorezeroidx8 ptr1 idx1 mem))
+	&& x.Uses == 1
+	&& s == nil
+	&& isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1)
+	&& clobber(x)
+	=> (MOVQstorezero [0] {s} p0 mem)
+
+// Combine stores into larger (unaligned) stores.
+(MOVBstore [i] {s} ptr0 (SRLconst [8] w) x:(MOVBstore [i-1] {s} ptr1 w mem))
+	&& x.Uses == 1
+	&& isSamePtr(ptr0, ptr1)
+	&& clobber(x)
+	=> (MOVHstore [i-1] {s} ptr0 w mem)
+(MOVBstore [1] {s} (ADD ptr0 idx0) (SRLconst [8] w) x:(MOVBstoreidx ptr1 idx1 w mem))
+	&& x.Uses == 1
+	&& s == nil
+	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
+	&& clobber(x)
+	=> (MOVHstoreidx ptr1 idx1 w mem)
+(MOVBstoreidx ptr (ADDconst [1] idx) (SRLconst [8] w) x:(MOVBstoreidx ptr idx w mem))
+	&& x.Uses == 1
+	&& clobber(x)
+	=> (MOVHstoreidx ptr idx w mem)
+(MOVBstore [i] {s} ptr0 (UBFX [armBFAuxInt(8, 8)] w) x:(MOVBstore [i-1] {s} ptr1 w mem))
+	&& x.Uses == 1
+	&& isSamePtr(ptr0, ptr1)
+	&& clobber(x)
+	=> (MOVHstore [i-1] {s} ptr0 w mem)
+(MOVBstore [1] {s} (ADD ptr0 idx0) (UBFX [armBFAuxInt(8, 8)] w) x:(MOVBstoreidx ptr1 idx1 w mem))
+	&& x.Uses == 1
+	&& s == nil
+	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
+	&& clobber(x)
+	=> (MOVHstoreidx ptr1 idx1 w mem)
+(MOVBstore [i] {s} ptr0 (UBFX [armBFAuxInt(8, 24)] w) x:(MOVBstore [i-1] {s} ptr1 w mem))
+	&& x.Uses == 1
+	&& isSamePtr(ptr0, ptr1)
+	&& clobber(x)
+	=> (MOVHstore [i-1] {s} ptr0 w mem)
+(MOVBstore [1] {s} (ADD ptr0 idx0) (UBFX [armBFAuxInt(8, 24)] w) x:(MOVBstoreidx ptr1 idx1 w mem))
+	&& x.Uses == 1
+	&& s == nil
+	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
+	&& clobber(x)
+	=> (MOVHstoreidx ptr1 idx1 w mem)
+(MOVBstore [i] {s} ptr0 (SRLconst [8] (MOVDreg w)) x:(MOVBstore [i-1] {s} ptr1 w mem))
+	&& x.Uses == 1
+	&& isSamePtr(ptr0, ptr1)
+	&& clobber(x)
+	=> (MOVHstore [i-1] {s} ptr0 w mem)
+(MOVBstore [1] {s} (ADD ptr0 idx0) (SRLconst [8] (MOVDreg w)) x:(MOVBstoreidx ptr1 idx1 w mem))
+	&& x.Uses == 1
+	&& s == nil
+	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
+	&& clobber(x)
+	=> (MOVHstoreidx ptr1 idx1 w mem)
+(MOVBstore [i] {s} ptr0 (SRLconst [j] w) x:(MOVBstore [i-1] {s} ptr1 w0:(SRLconst [j-8] w) mem))
+	&& x.Uses == 1
+	&& isSamePtr(ptr0, ptr1)
+	&& clobber(x)
+	=> (MOVHstore [i-1] {s} ptr0 w0 mem)
+(MOVBstore [1] {s} (ADD ptr0 idx0) (SRLconst [j] w) x:(MOVBstoreidx ptr1 idx1 w0:(SRLconst [j-8] w) mem))
+	&& x.Uses == 1
+	&& s == nil
+	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
+	&& clobber(x)
+	=> (MOVHstoreidx ptr1 idx1 w0 mem)
+(MOVBstore [i] {s} ptr0 (UBFX [bfc] w) x:(MOVBstore [i-1] {s} ptr1 w0:(UBFX [bfc2] w) mem))
+	&& x.Uses == 1
+	&& isSamePtr(ptr0, ptr1)
+	&& bfc.getARM64BFwidth() == 32 - bfc.getARM64BFlsb()
+	&& bfc2.getARM64BFwidth() == 32 - bfc2.getARM64BFlsb()
+	&& bfc2.getARM64BFlsb() == bfc.getARM64BFlsb() - 8
+	&& clobber(x)
+	=> (MOVHstore [i-1] {s} ptr0 w0 mem)
+(MOVBstore [1] {s} (ADD ptr0 idx0) (UBFX [bfc] w) x:(MOVBstoreidx ptr1 idx1 w0:(UBFX [bfc2] w) mem))
+	&& x.Uses == 1
+	&& s == nil
+	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
+	&& bfc.getARM64BFwidth() == 32 - bfc.getARM64BFlsb()
+	&& bfc2.getARM64BFwidth() == 32 - bfc2.getARM64BFlsb()
+	&& bfc2.getARM64BFlsb() == bfc.getARM64BFlsb() - 8
+	&& clobber(x)
+	=> (MOVHstoreidx ptr1 idx1 w0 mem)
+(MOVBstore [i] {s} ptr0 (SRLconst [j] (MOVDreg w)) x:(MOVBstore [i-1] {s} ptr1 w0:(SRLconst [j-8] (MOVDreg w)) mem))
+	&& x.Uses == 1
+	&& isSamePtr(ptr0, ptr1)
+	&& clobber(x)
+	=> (MOVHstore [i-1] {s} ptr0 w0 mem)
+(MOVBstore [1] {s} (ADD ptr0 idx0) (SRLconst [j] (MOVDreg w)) x:(MOVBstoreidx ptr1 idx1 w0:(SRLconst [j-8] (MOVDreg w)) mem))
+	&& x.Uses == 1
+	&& s == nil
+	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
+	&& clobber(x)
+	=> (MOVHstoreidx ptr1 idx1 w0 mem)
+(MOVHstore [i] {s} ptr0 (SRLconst [16] w) x:(MOVHstore [i-2] {s} ptr1 w mem))
+	&& x.Uses == 1
+	&& isSamePtr(ptr0, ptr1)
+	&& clobber(x)
+	=> (MOVWstore [i-2] {s} ptr0 w mem)
+(MOVHstore [2] {s} (ADD ptr0 idx0) (SRLconst [16] w) x:(MOVHstoreidx ptr1 idx1 w mem))
+	&& x.Uses == 1
+	&& s == nil
+	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
+	&& clobber(x)
+	=> (MOVWstoreidx ptr1 idx1 w mem)
+(MOVHstoreidx ptr (ADDconst [2] idx) (SRLconst [16] w) x:(MOVHstoreidx ptr idx w mem))
+	&& x.Uses == 1
+	&& clobber(x)
+	=> (MOVWstoreidx ptr idx w mem)
+(MOVHstore [2] {s} (ADDshiftLL [1] ptr0 idx0) (SRLconst [16] w) x:(MOVHstoreidx2 ptr1 idx1 w mem))
+	&& x.Uses == 1
+	&& s == nil
+	&& isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1)
+	&& clobber(x)
+	=> (MOVWstoreidx ptr1 (SLLconst <idx1.Type> [1] idx1) w mem)
+(MOVHstore [i] {s} ptr0 (UBFX [armBFAuxInt(16, 16)] w) x:(MOVHstore [i-2] {s} ptr1 w mem))
+	&& x.Uses == 1
+	&& isSamePtr(ptr0, ptr1)
+	&& clobber(x)
+	=> (MOVWstore [i-2] {s} ptr0 w mem)
+(MOVHstore [2] {s} (ADD ptr0 idx0) (UBFX [armBFAuxInt(16, 16)] w) x:(MOVHstoreidx ptr1 idx1 w mem))
+	&& x.Uses == 1
+	&& s == nil
+	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
+	&& clobber(x)
+	=> (MOVWstoreidx ptr1 idx1 w mem)
+(MOVHstore [2] {s} (ADDshiftLL [1] ptr0 idx0) (UBFX [armBFAuxInt(16, 16)] w) x:(MOVHstoreidx2 ptr1 idx1 w mem))
+	&& x.Uses == 1
+	&& s == nil
+	&& isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1)
+	&& clobber(x)
+	=> (MOVWstoreidx ptr1 (SLLconst <idx1.Type> [1] idx1) w mem)
+(MOVHstore [i] {s} ptr0 (SRLconst [16] (MOVDreg w)) x:(MOVHstore [i-2] {s} ptr1 w mem))
+	&& x.Uses == 1
+	&& isSamePtr(ptr0, ptr1)
+	&& clobber(x)
+	=> (MOVWstore [i-2] {s} ptr0 w mem)
+(MOVHstore [2] {s} (ADD ptr0 idx0) (SRLconst [16] (MOVDreg w)) x:(MOVHstoreidx ptr1 idx1 w mem))
+	&& x.Uses == 1
+	&& s == nil
+	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
+	&& clobber(x)
+	=> (MOVWstoreidx ptr1 idx1 w mem)
+(MOVHstore [2] {s} (ADDshiftLL [1] ptr0 idx0) (SRLconst [16] (MOVDreg w)) x:(MOVHstoreidx2 ptr1 idx1 w mem))
+	&& x.Uses == 1
+	&& s == nil
+	&& isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1)
+	&& clobber(x)
+	=> (MOVWstoreidx ptr1 (SLLconst <idx1.Type> [1] idx1) w mem)
+(MOVHstore [i] {s} ptr0 (SRLconst [j] w) x:(MOVHstore [i-2] {s} ptr1 w0:(SRLconst [j-16] w) mem))
+	&& x.Uses == 1
+	&& isSamePtr(ptr0, ptr1)
+	&& clobber(x)
+	=> (MOVWstore [i-2] {s} ptr0 w0 mem)
+(MOVHstore [2] {s} (ADD ptr0 idx0) (SRLconst [j] w) x:(MOVHstoreidx ptr1 idx1 w0:(SRLconst [j-16] w) mem))
+	&& x.Uses == 1
+	&& s == nil
+	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
+	&& clobber(x)
+	=> (MOVWstoreidx ptr1 idx1 w0 mem)
+(MOVHstore [2] {s} (ADDshiftLL [1] ptr0 idx0) (SRLconst [j] w) x:(MOVHstoreidx2 ptr1 idx1 w0:(SRLconst [j-16] w) mem))
+	&& x.Uses == 1
+	&& s == nil
+	&& isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1)
+	&& clobber(x)
+	=> (MOVWstoreidx ptr1 (SLLconst <idx1.Type> [1] idx1) w0 mem)
+(MOVWstore [i] {s} ptr0 (SRLconst [32] w) x:(MOVWstore [i-4] {s} ptr1 w mem))
+	&& x.Uses == 1
+	&& isSamePtr(ptr0, ptr1)
+	&& clobber(x)
+	=> (MOVDstore [i-4] {s} ptr0 w mem)
+(MOVWstore [4] {s} (ADD ptr0 idx0) (SRLconst [32] w) x:(MOVWstoreidx ptr1 idx1 w mem))
+	&& x.Uses == 1
+	&& s == nil
+	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
+	&& clobber(x)
+	=> (MOVDstoreidx ptr1 idx1 w mem)
+(MOVWstoreidx ptr (ADDconst [4] idx) (SRLconst [32] w) x:(MOVWstoreidx ptr idx w mem))
+	&& x.Uses == 1
+	&& clobber(x)
+	=> (MOVDstoreidx ptr idx w mem)
+(MOVWstore [4] {s} (ADDshiftLL [2] ptr0 idx0) (SRLconst [32] w) x:(MOVWstoreidx4 ptr1 idx1 w mem))
+	&& x.Uses == 1
+	&& s == nil
+	&& isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1)
+	&& clobber(x)
+	=> (MOVDstoreidx ptr1 (SLLconst <idx1.Type> [2] idx1) w mem)
+(MOVWstore [i] {s} ptr0 (SRLconst [j] w) x:(MOVWstore [i-4] {s} ptr1 w0:(SRLconst [j-32] w) mem))
+	&& x.Uses == 1
+	&& isSamePtr(ptr0, ptr1)
+	&& clobber(x)
+	=> (MOVDstore [i-4] {s} ptr0 w0 mem)
+(MOVWstore [4] {s} (ADD ptr0 idx0) (SRLconst [j] w) x:(MOVWstoreidx ptr1 idx1 w0:(SRLconst [j-32] w) mem))
+	&& x.Uses == 1
+	&& s == nil
+	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
+	&& clobber(x)
+	=> (MOVDstoreidx ptr1 idx1 w0 mem)
+(MOVWstore [4] {s} (ADDshiftLL [2] ptr0 idx0) (SRLconst [j] w) x:(MOVWstoreidx4 ptr1 idx1 w0:(SRLconst [j-32] w) mem))
+	&& x.Uses == 1
+	&& s == nil
+	&& isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1)
+	&& clobber(x)
+	=> (MOVDstoreidx ptr1 (SLLconst <idx1.Type> [2] idx1) w0 mem)
+(MOVBstore [i] {s} ptr w
+	x0:(MOVBstore [i-1] {s} ptr (SRLconst [8] w)
+	x1:(MOVBstore [i-2] {s} ptr (SRLconst [16] w)
+	x2:(MOVBstore [i-3] {s} ptr (SRLconst [24] w)
+	x3:(MOVBstore [i-4] {s} ptr (SRLconst [32] w)
+	x4:(MOVBstore [i-5] {s} ptr (SRLconst [40] w)
+	x5:(MOVBstore [i-6] {s} ptr (SRLconst [48] w)
+	x6:(MOVBstore [i-7] {s} ptr (SRLconst [56] w) mem))))))))
+	&& x0.Uses == 1
+	&& x1.Uses == 1
+	&& x2.Uses == 1
+	&& x3.Uses == 1
+	&& x4.Uses == 1
+	&& x5.Uses == 1
+	&& x6.Uses == 1
+	&& clobber(x0, x1, x2, x3, x4, x5, x6)
+	=> (MOVDstore [i-7] {s} ptr (REV <w.Type> w) mem)
+(MOVBstore [7] {s} p w
+	x0:(MOVBstore [6] {s} p (SRLconst [8] w)
+	x1:(MOVBstore [5] {s} p (SRLconst [16] w)
+	x2:(MOVBstore [4] {s} p (SRLconst [24] w)
+	x3:(MOVBstore [3] {s} p (SRLconst [32] w)
+	x4:(MOVBstore [2] {s} p (SRLconst [40] w)
+	x5:(MOVBstore [1] {s} p1:(ADD ptr1 idx1) (SRLconst [48] w)
+	x6:(MOVBstoreidx ptr0 idx0 (SRLconst [56] w) mem))))))))
+	&& x0.Uses == 1
+	&& x1.Uses == 1
+	&& x2.Uses == 1
+	&& x3.Uses == 1
+	&& x4.Uses == 1
+	&& x5.Uses == 1
+	&& x6.Uses == 1
+	&& s == nil
+	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
+	&& isSamePtr(p1, p)
+	&& clobber(x0, x1, x2, x3, x4, x5, x6)
+	=> (MOVDstoreidx ptr0 idx0 (REV <w.Type> w) mem)
+(MOVBstore [i] {s} ptr w
+	x0:(MOVBstore [i-1] {s} ptr (UBFX [armBFAuxInt(8, 24)] w)
+	x1:(MOVBstore [i-2] {s} ptr (UBFX [armBFAuxInt(16, 16)] w)
+	x2:(MOVBstore [i-3] {s} ptr (UBFX [armBFAuxInt(24, 8)] w) mem))))
+	&& x0.Uses == 1
+	&& x1.Uses == 1
+	&& x2.Uses == 1
+	&& clobber(x0, x1, x2)
+	=> (MOVWstore [i-3] {s} ptr (REVW <w.Type> w) mem)
+(MOVBstore [3] {s} p w
+	x0:(MOVBstore [2] {s} p (UBFX [armBFAuxInt(8, 24)] w)
+	x1:(MOVBstore [1] {s} p1:(ADD ptr1 idx1) (UBFX [armBFAuxInt(16, 16)] w)
+	x2:(MOVBstoreidx ptr0 idx0 (UBFX [armBFAuxInt(24, 8)] w) mem))))
+	&& x0.Uses == 1
+	&& x1.Uses == 1
+	&& x2.Uses == 1
+	&& s == nil
+	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
+	&& isSamePtr(p1, p)
+	&& clobber(x0, x1, x2)
+	=> (MOVWstoreidx ptr0 idx0 (REVW <w.Type> w) mem)
+(MOVBstoreidx ptr (ADDconst [3] idx) w
+	x0:(MOVBstoreidx ptr (ADDconst [2] idx) (UBFX [armBFAuxInt(8, 24)] w)
+	x1:(MOVBstoreidx ptr (ADDconst [1] idx) (UBFX [armBFAuxInt(16, 16)] w)
+	x2:(MOVBstoreidx ptr idx (UBFX [armBFAuxInt(24, 8)] w) mem))))
+	&& x0.Uses == 1
+	&& x1.Uses == 1
+	&& x2.Uses == 1
+	&& clobber(x0, x1, x2)
+	=> (MOVWstoreidx ptr idx (REVW <w.Type> w) mem)
+(MOVBstoreidx ptr idx w
+	x0:(MOVBstoreidx ptr (ADDconst [1] idx) (UBFX [armBFAuxInt(8, 24)] w)
+	x1:(MOVBstoreidx ptr (ADDconst [2] idx) (UBFX [armBFAuxInt(16, 16)] w)
+	x2:(MOVBstoreidx ptr (ADDconst [3] idx) (UBFX [armBFAuxInt(24, 8)] w) mem))))
+	&& x0.Uses == 1
+	&& x1.Uses == 1
+	&& x2.Uses == 1
+	&& clobber(x0, x1, x2)
+	=> (MOVWstoreidx ptr idx w mem)
+(MOVBstore [i] {s} ptr w
+	x0:(MOVBstore [i-1] {s} ptr (SRLconst [8] (MOVDreg w))
+	x1:(MOVBstore [i-2] {s} ptr (SRLconst [16] (MOVDreg w))
+	x2:(MOVBstore [i-3] {s} ptr (SRLconst [24] (MOVDreg w)) mem))))
+	&& x0.Uses == 1
+	&& x1.Uses == 1
+	&& x2.Uses == 1
+	&& clobber(x0, x1, x2)
+	=> (MOVWstore [i-3] {s} ptr (REVW <w.Type> w) mem)
+(MOVBstore [3] {s} p w
+	x0:(MOVBstore [2] {s} p (SRLconst [8] (MOVDreg w))
+	x1:(MOVBstore [1] {s} p1:(ADD ptr1 idx1) (SRLconst [16] (MOVDreg w))
+	x2:(MOVBstoreidx ptr0 idx0 (SRLconst [24] (MOVDreg w)) mem))))
+	&& x0.Uses == 1
+	&& x1.Uses == 1
+	&& x2.Uses == 1
+	&& s == nil
+	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
+	&& isSamePtr(p1, p)
+	&& clobber(x0, x1, x2)
+	=> (MOVWstoreidx ptr0 idx0 (REVW <w.Type> w) mem)
+(MOVBstore [i] {s} ptr w
+	x0:(MOVBstore [i-1] {s} ptr (SRLconst [8] w)
+	x1:(MOVBstore [i-2] {s} ptr (SRLconst [16] w)
+	x2:(MOVBstore [i-3] {s} ptr (SRLconst [24] w) mem))))
+	&& x0.Uses == 1
+	&& x1.Uses == 1
+	&& x2.Uses == 1
+	&& clobber(x0, x1, x2)
+	=> (MOVWstore [i-3] {s} ptr (REVW <w.Type> w) mem)
+(MOVBstore [3] {s} p w
+	x0:(MOVBstore [2] {s} p (SRLconst [8] w)
+	x1:(MOVBstore [1] {s} p1:(ADD ptr1 idx1) (SRLconst [16] w)
+	x2:(MOVBstoreidx ptr0 idx0 (SRLconst [24] w) mem))))
+	&& x0.Uses == 1
+	&& x1.Uses == 1
+	&& x2.Uses == 1
+	&& s == nil
+	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
+	&& isSamePtr(p1, p)
+	&& clobber(x0, x1, x2)
+	=> (MOVWstoreidx ptr0 idx0 (REVW <w.Type> w) mem)
+(MOVBstore [i] {s} ptr w x:(MOVBstore [i-1] {s} ptr (SRLconst [8] w) mem))
+	&& x.Uses == 1
+	&& clobber(x)
+	=> (MOVHstore [i-1] {s} ptr (REV16W <w.Type> w) mem)
+(MOVBstore [1] {s} (ADD ptr1 idx1) w x:(MOVBstoreidx ptr0 idx0 (SRLconst [8] w) mem))
+	&& x.Uses == 1
+	&& s == nil
+	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
+	&& clobber(x)
+	=> (MOVHstoreidx ptr0 idx0 (REV16W <w.Type> w) mem)
+(MOVBstore [i] {s} ptr w x:(MOVBstore [i-1] {s} ptr (UBFX [armBFAuxInt(8, 8)] w) mem))
+	&& x.Uses == 1
+	&& clobber(x)
+	=> (MOVHstore [i-1] {s} ptr (REV16W <w.Type> w) mem)
+(MOVBstore [1] {s} (ADD ptr1 idx1) w x:(MOVBstoreidx ptr0 idx0 (UBFX [armBFAuxInt(8, 8)] w) mem))
+	&& x.Uses == 1
+	&& s == nil
+	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
+	&& clobber(x)
+	=> (MOVHstoreidx ptr0 idx0 (REV16W <w.Type> w) mem)
+(MOVBstoreidx ptr (ADDconst [1] idx) w x:(MOVBstoreidx ptr idx (UBFX [armBFAuxInt(8, 8)] w) mem))
+	&& x.Uses == 1
+	&& clobber(x)
+	=> (MOVHstoreidx ptr idx (REV16W <w.Type> w) mem)
+(MOVBstoreidx ptr idx w x:(MOVBstoreidx ptr (ADDconst [1] idx) (UBFX [armBFAuxInt(8, 8)] w) mem))
+	&& x.Uses == 1
+	&& clobber(x)
+	=> (MOVHstoreidx ptr idx w mem)
+(MOVBstore [i] {s} ptr w x:(MOVBstore [i-1] {s} ptr (SRLconst [8] (MOVDreg w)) mem))
+	&& x.Uses == 1
+	&& clobber(x)
+	=> (MOVHstore [i-1] {s} ptr (REV16W <w.Type> w) mem)
+(MOVBstore [1] {s} (ADD ptr1 idx1) w x:(MOVBstoreidx ptr0 idx0 (SRLconst [8] (MOVDreg w)) mem))
+	&& x.Uses == 1
+	&& s == nil
+	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
+	&& clobber(x)
+	=> (MOVHstoreidx ptr0 idx0 (REV16W <w.Type> w) mem)
+(MOVBstore [i] {s} ptr w x:(MOVBstore [i-1] {s} ptr (UBFX [armBFAuxInt(8, 24)] w) mem))
+	&& x.Uses == 1
+	&& clobber(x)
+	=> (MOVHstore [i-1] {s} ptr (REV16W <w.Type> w) mem)
+(MOVBstore [1] {s} (ADD ptr1 idx1) w x:(MOVBstoreidx ptr0 idx0 (UBFX [armBFAuxInt(8, 24)] w) mem))
+	&& x.Uses == 1
+	&& s == nil
+	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
+	&& clobber(x)
+	=> (MOVHstoreidx ptr0 idx0 (REV16W <w.Type> w) mem)
+
+// FP simplification
+(FNEGS (FMULS x y)) => (FNMULS x y)
+(FNEGD (FMULD x y)) => (FNMULD x y)
+(FMULS (FNEGS x) y) => (FNMULS x y)
+(FMULD (FNEGD x) y) => (FNMULD x y)
+(FNEGS (FNMULS x y)) => (FMULS x y)
+(FNEGD (FNMULD x y)) => (FMULD x y)
+(FNMULS (FNEGS x) y) => (FMULS x y)
+(FNMULD (FNEGD x) y) => (FMULD x y)
+
+(FADDS a (FMULS x y)) && a.Block.Func.useFMA(v) => (FMADDS a x y)
+(FADDD a (FMULD x y)) && a.Block.Func.useFMA(v) => (FMADDD a x y)
+(FSUBS a (FMULS x y)) && a.Block.Func.useFMA(v) => (FMSUBS a x y)
+(FSUBD a (FMULD x y)) && a.Block.Func.useFMA(v) => (FMSUBD a x y)
+(FSUBS (FMULS x y) a) && a.Block.Func.useFMA(v) => (FNMSUBS a x y)
+(FSUBD (FMULD x y) a) && a.Block.Func.useFMA(v) => (FNMSUBD a x y)
+(FADDS a (FNMULS x y)) && a.Block.Func.useFMA(v) => (FMSUBS a x y)
+(FADDD a (FNMULD x y)) && a.Block.Func.useFMA(v) => (FMSUBD a x y)
+(FSUBS a (FNMULS x y)) && a.Block.Func.useFMA(v) => (FMADDS a x y)
+(FSUBD a (FNMULD x y)) && a.Block.Func.useFMA(v) => (FMADDD a x y)
+(FSUBS (FNMULS x y) a) && a.Block.Func.useFMA(v) => (FNMADDS a x y)
+(FSUBD (FNMULD x y) a) && a.Block.Func.useFMA(v) => (FNMADDD a x y)
+
+(MOVBUload [off] {sym} (SB) _) && symIsRO(sym) => (MOVDconst [int64(read8(sym, int64(off)))])
+(MOVHUload [off] {sym} (SB) _) && symIsRO(sym) => (MOVDconst [int64(read16(sym, int64(off), config.ctxt.Arch.ByteOrder))])
+(MOVWUload [off] {sym} (SB) _) && symIsRO(sym) => (MOVDconst [int64(read32(sym, int64(off), config.ctxt.Arch.ByteOrder))])
+(MOVDload  [off] {sym} (SB) _) && symIsRO(sym) => (MOVDconst [int64(read64(sym, int64(off), config.ctxt.Arch.ByteOrder))])
+
+// Prefetch instructions (aux is option: 0 - PLDL1KEEP; 1 - PLDL1STRM)
+(PrefetchCache addr mem)         => (PRFM [0] addr mem)
+(PrefetchCacheStreamed addr mem) => (PRFM [1] addr mem)
+
+// Arch-specific inlining for small or disjoint runtime.memmove
+(SelectN [0] call:(CALLstatic {sym} s1:(MOVDstore _ (MOVDconst [sz]) s2:(MOVDstore  _ src s3:(MOVDstore {t} _ dst mem)))))
+	&& sz >= 0
+	&& isSameCall(sym, "runtime.memmove")
+	&& s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1
+	&& isInlinableMemmove(dst, src, sz, config)
+	&& clobber(s1, s2, s3, call)
+	=> (Move [sz] dst src mem)
+
+// Match post-lowering calls, register version.
+(SelectN [0] call:(CALLstatic {sym} dst src (MOVDconst [sz]) mem))
+	&& sz >= 0
+	&& isSameCall(sym, "runtime.memmove")
+	&& call.Uses == 1
+	&& isInlinableMemmove(dst, src, sz, config)
+	&& clobber(call)
+	=> (Move [sz] dst src mem)
+
+((REV|REVW) ((REV|REVW) p)) => p
+
+// runtime/internal/math.MulUintptr intrinsics
+
+(Select0 (Mul64uover x y)) => (MUL x y)
+(Select1 (Mul64uover x y)) => (NotEqual (CMPconst (UMULH <typ.UInt64> x y) [0]))
diff --git a/src/cmd/compile/internal/ssa/_gen/ARM64Ops.go b/src/cmd/compile/internal/ssa/_gen/ARM64Ops.go
new file mode 100644
index 0000000..f7cc47b
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/_gen/ARM64Ops.go
@@ -0,0 +1,794 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "strings"
+
+// Notes:
+//  - Integer types live in the low portion of registers. Upper portions are junk.
+//  - Boolean types use the low-order byte of a register. 0=false, 1=true.
+//    Upper bytes are junk.
+//  - *const instructions may use a constant larger than the instruction can encode.
+//    In this case the assembler expands to multiple instructions and uses tmp
+//    register (R27).
+
+// Suffixes encode the bit width of various instructions.
+// D (double word) = 64 bit
+// W (word)        = 32 bit
+// H (half word)   = 16 bit
+// HU              = 16 bit unsigned
+// B (byte)        = 8 bit
+// BU              = 8 bit unsigned
+// S (single)      = 32 bit float
+// D (double)      = 64 bit float
+
+// Note: registers not used in regalloc are not included in this list,
+// so that regmask stays within int64
+// Be careful when hand coding regmasks.
+var regNamesARM64 = []string{
+	"R0",
+	"R1",
+	"R2",
+	"R3",
+	"R4",
+	"R5",
+	"R6",
+	"R7",
+	"R8",
+	"R9",
+	"R10",
+	"R11",
+	"R12",
+	"R13",
+	"R14",
+	"R15",
+	"R16",
+	"R17",
+	"R18", // platform register, not used
+	"R19",
+	"R20",
+	"R21",
+	"R22",
+	"R23",
+	"R24",
+	"R25",
+	"R26",
+	// R27 = REGTMP not used in regalloc
+	"g",   // aka R28
+	"R29", // frame pointer, not used
+	"R30", // aka REGLINK
+	"SP",  // aka R31
+
+	"F0",
+	"F1",
+	"F2",
+	"F3",
+	"F4",
+	"F5",
+	"F6",
+	"F7",
+	"F8",
+	"F9",
+	"F10",
+	"F11",
+	"F12",
+	"F13",
+	"F14",
+	"F15",
+	"F16",
+	"F17",
+	"F18",
+	"F19",
+	"F20",
+	"F21",
+	"F22",
+	"F23",
+	"F24",
+	"F25",
+	"F26",
+	"F27",
+	"F28",
+	"F29",
+	"F30",
+	"F31",
+
+	// If you add registers, update asyncPreempt in runtime.
+
+	// pseudo-registers
+	"SB",
+}
+
+func init() {
+	// Make map from reg names to reg integers.
+	if len(regNamesARM64) > 64 {
+		panic("too many registers")
+	}
+	num := map[string]int{}
+	for i, name := range regNamesARM64 {
+		num[name] = i
+	}
+	buildReg := func(s string) regMask {
+		m := regMask(0)
+		for _, r := range strings.Split(s, " ") {
+			if n, ok := num[r]; ok {
+				m |= regMask(1) << uint(n)
+				continue
+			}
+			panic("register " + r + " not found")
+		}
+		return m
+	}
+
+	// Common individual register masks
+	var (
+		gp         = buildReg("R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30")
+		gpg        = gp | buildReg("g")
+		gpsp       = gp | buildReg("SP")
+		gpspg      = gpg | buildReg("SP")
+		gpspsbg    = gpspg | buildReg("SB")
+		fp         = buildReg("F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31")
+		callerSave = gp | fp | buildReg("g") // runtime.setg (and anything calling it) may clobber g
+		r0         = buildReg("R0")
+		r1         = buildReg("R1")
+		r2         = buildReg("R2")
+		r3         = buildReg("R3")
+	)
+	// Common regInfo
+	var (
+		gp01           = regInfo{inputs: nil, outputs: []regMask{gp}}
+		gp0flags1      = regInfo{inputs: []regMask{0}, outputs: []regMask{gp}}
+		gp11           = regInfo{inputs: []regMask{gpg}, outputs: []regMask{gp}}
+		gp11sp         = regInfo{inputs: []regMask{gpspg}, outputs: []regMask{gp}}
+		gp1flags       = regInfo{inputs: []regMask{gpg}}
+		gp1flags1      = regInfo{inputs: []regMask{gpg}, outputs: []regMask{gp}}
+		gp11flags      = regInfo{inputs: []regMask{gpg}, outputs: []regMask{gp, 0}}
+		gp21           = regInfo{inputs: []regMask{gpg, gpg}, outputs: []regMask{gp}}
+		gp21nog        = regInfo{inputs: []regMask{gp, gp}, outputs: []regMask{gp}}
+		gp21flags      = regInfo{inputs: []regMask{gp, gp}, outputs: []regMask{gp, 0}}
+		gp2flags       = regInfo{inputs: []regMask{gpg, gpg}}
+		gp2flags1      = regInfo{inputs: []regMask{gp, gp}, outputs: []regMask{gp}}
+		gp2flags1flags = regInfo{inputs: []regMask{gp, gp, 0}, outputs: []regMask{gp, 0}}
+		gp2load        = regInfo{inputs: []regMask{gpspsbg, gpg}, outputs: []regMask{gp}}
+		gp31           = regInfo{inputs: []regMask{gpg, gpg, gpg}, outputs: []regMask{gp}}
+		gpload         = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{gp}}
+		gpload2        = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{gpg, gpg}}
+		gpstore        = regInfo{inputs: []regMask{gpspsbg, gpg}}
+		gpstore0       = regInfo{inputs: []regMask{gpspsbg}}
+		gpstore2       = regInfo{inputs: []regMask{gpspsbg, gpg, gpg}}
+		gpxchg         = regInfo{inputs: []regMask{gpspsbg, gpg}, outputs: []regMask{gp}}
+		gpcas          = regInfo{inputs: []regMask{gpspsbg, gpg, gpg}, outputs: []regMask{gp}}
+		fp01           = regInfo{inputs: nil, outputs: []regMask{fp}}
+		fp11           = regInfo{inputs: []regMask{fp}, outputs: []regMask{fp}}
+		fpgp           = regInfo{inputs: []regMask{fp}, outputs: []regMask{gp}}
+		gpfp           = regInfo{inputs: []regMask{gp}, outputs: []regMask{fp}}
+		fp21           = regInfo{inputs: []regMask{fp, fp}, outputs: []regMask{fp}}
+		fp31           = regInfo{inputs: []regMask{fp, fp, fp}, outputs: []regMask{fp}}
+		fp2flags       = regInfo{inputs: []regMask{fp, fp}}
+		fp1flags       = regInfo{inputs: []regMask{fp}}
+		fpload         = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{fp}}
+		fp2load        = regInfo{inputs: []regMask{gpspsbg, gpg}, outputs: []regMask{fp}}
+		fpstore        = regInfo{inputs: []regMask{gpspsbg, fp}}
+		fpstore2       = regInfo{inputs: []regMask{gpspsbg, gpg, fp}}
+		readflags      = regInfo{inputs: nil, outputs: []regMask{gp}}
+		prefreg        = regInfo{inputs: []regMask{gpspsbg}}
+	)
+	ops := []opData{
+		// binary ops
+		{name: "ADCSflags", argLength: 3, reg: gp2flags1flags, typ: "(UInt64,Flags)", asm: "ADCS", commutative: true}, // arg0+arg1+carry, set flags.
+		{name: "ADCzerocarry", argLength: 1, reg: gp0flags1, typ: "UInt64", asm: "ADC"},                               // ZR+ZR+carry
+		{name: "ADD", argLength: 2, reg: gp21, asm: "ADD", commutative: true},                                         // arg0 + arg1
+		{name: "ADDconst", argLength: 1, reg: gp11sp, asm: "ADD", aux: "Int64"},                                       // arg0 + auxInt
+		{name: "ADDSconstflags", argLength: 1, reg: gp11flags, typ: "(UInt64,Flags)", asm: "ADDS", aux: "Int64"},      // arg0+auxint, set flags.
+		{name: "ADDSflags", argLength: 2, reg: gp21flags, typ: "(UInt64,Flags)", asm: "ADDS", commutative: true},      // arg0+arg1, set flags.
+		{name: "SUB", argLength: 2, reg: gp21, asm: "SUB"},                                                            // arg0 - arg1
+		{name: "SUBconst", argLength: 1, reg: gp11, asm: "SUB", aux: "Int64"},                                         // arg0 - auxInt
+		{name: "SBCSflags", argLength: 3, reg: gp2flags1flags, typ: "(UInt64,Flags)", asm: "SBCS"},                    // arg0-(arg1+borrowing), set flags.
+		{name: "SUBSflags", argLength: 2, reg: gp21flags, typ: "(UInt64,Flags)", asm: "SUBS"},                         // arg0 - arg1, set flags.
+		{name: "MUL", argLength: 2, reg: gp21, asm: "MUL", commutative: true},                                         // arg0 * arg1
+		{name: "MULW", argLength: 2, reg: gp21, asm: "MULW", commutative: true},                                       // arg0 * arg1, 32-bit
+		{name: "MNEG", argLength: 2, reg: gp21, asm: "MNEG", commutative: true},                                       // -arg0 * arg1
+		{name: "MNEGW", argLength: 2, reg: gp21, asm: "MNEGW", commutative: true},                                     // -arg0 * arg1, 32-bit
+		{name: "MULH", argLength: 2, reg: gp21, asm: "SMULH", commutative: true},                                      // (arg0 * arg1) >> 64, signed
+		{name: "UMULH", argLength: 2, reg: gp21, asm: "UMULH", commutative: true},                                     // (arg0 * arg1) >> 64, unsigned
+		{name: "MULL", argLength: 2, reg: gp21, asm: "SMULL", commutative: true},                                      // arg0 * arg1, signed, 32-bit mult results in 64-bit
+		{name: "UMULL", argLength: 2, reg: gp21, asm: "UMULL", commutative: true},                                     // arg0 * arg1, unsigned, 32-bit mult results in 64-bit
+		{name: "DIV", argLength: 2, reg: gp21, asm: "SDIV"},                                                           // arg0 / arg1, signed
+		{name: "UDIV", argLength: 2, reg: gp21, asm: "UDIV"},                                                          // arg0 / arg1, unsighed
+		{name: "DIVW", argLength: 2, reg: gp21, asm: "SDIVW"},                                                         // arg0 / arg1, signed, 32 bit
+		{name: "UDIVW", argLength: 2, reg: gp21, asm: "UDIVW"},                                                        // arg0 / arg1, unsighed, 32 bit
+		{name: "MOD", argLength: 2, reg: gp21, asm: "REM"},                                                            // arg0 % arg1, signed
+		{name: "UMOD", argLength: 2, reg: gp21, asm: "UREM"},                                                          // arg0 % arg1, unsigned
+		{name: "MODW", argLength: 2, reg: gp21, asm: "REMW"},                                                          // arg0 % arg1, signed, 32 bit
+		{name: "UMODW", argLength: 2, reg: gp21, asm: "UREMW"},                                                        // arg0 % arg1, unsigned, 32 bit
+
+		{name: "FADDS", argLength: 2, reg: fp21, asm: "FADDS", commutative: true},   // arg0 + arg1
+		{name: "FADDD", argLength: 2, reg: fp21, asm: "FADDD", commutative: true},   // arg0 + arg1
+		{name: "FSUBS", argLength: 2, reg: fp21, asm: "FSUBS"},                      // arg0 - arg1
+		{name: "FSUBD", argLength: 2, reg: fp21, asm: "FSUBD"},                      // arg0 - arg1
+		{name: "FMULS", argLength: 2, reg: fp21, asm: "FMULS", commutative: true},   // arg0 * arg1
+		{name: "FMULD", argLength: 2, reg: fp21, asm: "FMULD", commutative: true},   // arg0 * arg1
+		{name: "FNMULS", argLength: 2, reg: fp21, asm: "FNMULS", commutative: true}, // -(arg0 * arg1)
+		{name: "FNMULD", argLength: 2, reg: fp21, asm: "FNMULD", commutative: true}, // -(arg0 * arg1)
+		{name: "FDIVS", argLength: 2, reg: fp21, asm: "FDIVS"},                      // arg0 / arg1
+		{name: "FDIVD", argLength: 2, reg: fp21, asm: "FDIVD"},                      // arg0 / arg1
+
+		{name: "AND", argLength: 2, reg: gp21, asm: "AND", commutative: true}, // arg0 & arg1
+		{name: "ANDconst", argLength: 1, reg: gp11, asm: "AND", aux: "Int64"}, // arg0 & auxInt
+		{name: "OR", argLength: 2, reg: gp21, asm: "ORR", commutative: true},  // arg0 | arg1
+		{name: "ORconst", argLength: 1, reg: gp11, asm: "ORR", aux: "Int64"},  // arg0 | auxInt
+		{name: "XOR", argLength: 2, reg: gp21, asm: "EOR", commutative: true}, // arg0 ^ arg1
+		{name: "XORconst", argLength: 1, reg: gp11, asm: "EOR", aux: "Int64"}, // arg0 ^ auxInt
+		{name: "BIC", argLength: 2, reg: gp21, asm: "BIC"},                    // arg0 &^ arg1
+		{name: "EON", argLength: 2, reg: gp21, asm: "EON"},                    // arg0 ^ ^arg1
+		{name: "ORN", argLength: 2, reg: gp21, asm: "ORN"},                    // arg0 | ^arg1
+
+		// unary ops
+		{name: "MVN", argLength: 1, reg: gp11, asm: "MVN"},                                    // ^arg0
+		{name: "NEG", argLength: 1, reg: gp11, asm: "NEG"},                                    // -arg0
+		{name: "NEGSflags", argLength: 1, reg: gp11flags, typ: "(UInt64,Flags)", asm: "NEGS"}, // -arg0, set flags.
+		{name: "NGCzerocarry", argLength: 1, reg: gp0flags1, typ: "UInt64", asm: "NGC"},       // -1 if borrowing, 0 otherwise.
+		{name: "FABSD", argLength: 1, reg: fp11, asm: "FABSD"},                                // abs(arg0), float64
+		{name: "FNEGS", argLength: 1, reg: fp11, asm: "FNEGS"},                                // -arg0, float32
+		{name: "FNEGD", argLength: 1, reg: fp11, asm: "FNEGD"},                                // -arg0, float64
+		{name: "FSQRTD", argLength: 1, reg: fp11, asm: "FSQRTD"},                              // sqrt(arg0), float64
+		{name: "FSQRTS", argLength: 1, reg: fp11, asm: "FSQRTS"},                              // sqrt(arg0), float32
+		{name: "REV", argLength: 1, reg: gp11, asm: "REV"},                                    // byte reverse, 64-bit
+		{name: "REVW", argLength: 1, reg: gp11, asm: "REVW"},                                  // byte reverse, 32-bit
+		{name: "REV16", argLength: 1, reg: gp11, asm: "REV16"},                                // byte reverse in each 16-bit halfword, 64-bit
+		{name: "REV16W", argLength: 1, reg: gp11, asm: "REV16W"},                              // byte reverse in each 16-bit halfword, 32-bit
+		{name: "RBIT", argLength: 1, reg: gp11, asm: "RBIT"},                                  // bit reverse, 64-bit
+		{name: "RBITW", argLength: 1, reg: gp11, asm: "RBITW"},                                // bit reverse, 32-bit
+		{name: "CLZ", argLength: 1, reg: gp11, asm: "CLZ"},                                    // count leading zero, 64-bit
+		{name: "CLZW", argLength: 1, reg: gp11, asm: "CLZW"},                                  // count leading zero, 32-bit
+		{name: "VCNT", argLength: 1, reg: fp11, asm: "VCNT"},                                  // count set bits for each 8-bit unit and store the result in each 8-bit unit
+		{name: "VUADDLV", argLength: 1, reg: fp11, asm: "VUADDLV"},                            // unsigned sum of eight bytes in a 64-bit value, zero extended to 64-bit.
+		{name: "LoweredRound32F", argLength: 1, reg: fp11, resultInArg0: true, zeroWidth: true},
+		{name: "LoweredRound64F", argLength: 1, reg: fp11, resultInArg0: true, zeroWidth: true},
+
+		// 3-operand, the addend comes first
+		{name: "FMADDS", argLength: 3, reg: fp31, asm: "FMADDS"},   // +arg0 + (arg1 * arg2)
+		{name: "FMADDD", argLength: 3, reg: fp31, asm: "FMADDD"},   // +arg0 + (arg1 * arg2)
+		{name: "FNMADDS", argLength: 3, reg: fp31, asm: "FNMADDS"}, // -arg0 - (arg1 * arg2)
+		{name: "FNMADDD", argLength: 3, reg: fp31, asm: "FNMADDD"}, // -arg0 - (arg1 * arg2)
+		{name: "FMSUBS", argLength: 3, reg: fp31, asm: "FMSUBS"},   // +arg0 - (arg1 * arg2)
+		{name: "FMSUBD", argLength: 3, reg: fp31, asm: "FMSUBD"},   // +arg0 - (arg1 * arg2)
+		{name: "FNMSUBS", argLength: 3, reg: fp31, asm: "FNMSUBS"}, // -arg0 + (arg1 * arg2)
+		{name: "FNMSUBD", argLength: 3, reg: fp31, asm: "FNMSUBD"}, // -arg0 + (arg1 * arg2)
+		{name: "MADD", argLength: 3, reg: gp31, asm: "MADD"},       // +arg0 + (arg1 * arg2)
+		{name: "MADDW", argLength: 3, reg: gp31, asm: "MADDW"},     // +arg0 + (arg1 * arg2), 32-bit
+		{name: "MSUB", argLength: 3, reg: gp31, asm: "MSUB"},       // +arg0 - (arg1 * arg2)
+		{name: "MSUBW", argLength: 3, reg: gp31, asm: "MSUBW"},     // +arg0 - (arg1 * arg2), 32-bit
+
+		// shifts
+		{name: "SLL", argLength: 2, reg: gp21, asm: "LSL"},                        // arg0 << arg1, shift amount is mod 64
+		{name: "SLLconst", argLength: 1, reg: gp11, asm: "LSL", aux: "Int64"},     // arg0 << auxInt, auxInt should be in the range 0 to 63.
+		{name: "SRL", argLength: 2, reg: gp21, asm: "LSR"},                        // arg0 >> arg1, unsigned, shift amount is mod 64
+		{name: "SRLconst", argLength: 1, reg: gp11, asm: "LSR", aux: "Int64"},     // arg0 >> auxInt, unsigned, auxInt should be in the range 0 to 63.
+		{name: "SRA", argLength: 2, reg: gp21, asm: "ASR"},                        // arg0 >> arg1, signed, shift amount is mod 64
+		{name: "SRAconst", argLength: 1, reg: gp11, asm: "ASR", aux: "Int64"},     // arg0 >> auxInt, signed, auxInt should be in the range 0 to 63.
+		{name: "ROR", argLength: 2, reg: gp21, asm: "ROR"},                        // arg0 right rotate by (arg1 mod 64) bits
+		{name: "RORW", argLength: 2, reg: gp21, asm: "RORW"},                      // arg0 right rotate by (arg1 mod 32) bits
+		{name: "RORconst", argLength: 1, reg: gp11, asm: "ROR", aux: "Int64"},     // arg0 right rotate by auxInt bits, auxInt should be in the range 0 to 63.
+		{name: "RORWconst", argLength: 1, reg: gp11, asm: "RORW", aux: "Int64"},   // uint32(arg0) right rotate by auxInt bits, auxInt should be in the range 0 to 31.
+		{name: "EXTRconst", argLength: 2, reg: gp21, asm: "EXTR", aux: "Int64"},   // extract 64 bits from arg0:arg1 starting at lsb auxInt, auxInt should be in the range 0 to 63.
+		{name: "EXTRWconst", argLength: 2, reg: gp21, asm: "EXTRW", aux: "Int64"}, // extract 32 bits from arg0[31:0]:arg1[31:0] starting at lsb auxInt and zero top 32 bits, auxInt should be in the range 0 to 31.
+
+		// comparisons
+		{name: "CMP", argLength: 2, reg: gp2flags, asm: "CMP", typ: "Flags"},                      // arg0 compare to arg1
+		{name: "CMPconst", argLength: 1, reg: gp1flags, asm: "CMP", aux: "Int64", typ: "Flags"},   // arg0 compare to auxInt
+		{name: "CMPW", argLength: 2, reg: gp2flags, asm: "CMPW", typ: "Flags"},                    // arg0 compare to arg1, 32 bit
+		{name: "CMPWconst", argLength: 1, reg: gp1flags, asm: "CMPW", aux: "Int32", typ: "Flags"}, // arg0 compare to auxInt, 32 bit
+		{name: "CMN", argLength: 2, reg: gp2flags, asm: "CMN", typ: "Flags", commutative: true},   // arg0 compare to -arg1, provided arg1 is not 1<<63
+		{name: "CMNconst", argLength: 1, reg: gp1flags, asm: "CMN", aux: "Int64", typ: "Flags"},   // arg0 compare to -auxInt
+		{name: "CMNW", argLength: 2, reg: gp2flags, asm: "CMNW", typ: "Flags", commutative: true}, // arg0 compare to -arg1, 32 bit, provided arg1 is not 1<<31
+		{name: "CMNWconst", argLength: 1, reg: gp1flags, asm: "CMNW", aux: "Int32", typ: "Flags"}, // arg0 compare to -auxInt, 32 bit
+		{name: "TST", argLength: 2, reg: gp2flags, asm: "TST", typ: "Flags", commutative: true},   // arg0 & arg1 compare to 0
+		{name: "TSTconst", argLength: 1, reg: gp1flags, asm: "TST", aux: "Int64", typ: "Flags"},   // arg0 & auxInt compare to 0
+		{name: "TSTW", argLength: 2, reg: gp2flags, asm: "TSTW", typ: "Flags", commutative: true}, // arg0 & arg1 compare to 0, 32 bit
+		{name: "TSTWconst", argLength: 1, reg: gp1flags, asm: "TSTW", aux: "Int32", typ: "Flags"}, // arg0 & auxInt compare to 0, 32 bit
+		{name: "FCMPS", argLength: 2, reg: fp2flags, asm: "FCMPS", typ: "Flags"},                  // arg0 compare to arg1, float32
+		{name: "FCMPD", argLength: 2, reg: fp2flags, asm: "FCMPD", typ: "Flags"},                  // arg0 compare to arg1, float64
+		{name: "FCMPS0", argLength: 1, reg: fp1flags, asm: "FCMPS", typ: "Flags"},                 // arg0 compare to 0, float32
+		{name: "FCMPD0", argLength: 1, reg: fp1flags, asm: "FCMPD", typ: "Flags"},                 // arg0 compare to 0, float64
+
+		// shifted ops
+		{name: "MVNshiftLL", argLength: 1, reg: gp11, asm: "MVN", aux: "Int64"},                   // ^(arg0<<auxInt), auxInt should be in the range 0 to 63.
+		{name: "MVNshiftRL", argLength: 1, reg: gp11, asm: "MVN", aux: "Int64"},                   // ^(arg0>>auxInt), unsigned shift, auxInt should be in the range 0 to 63.
+		{name: "MVNshiftRA", argLength: 1, reg: gp11, asm: "MVN", aux: "Int64"},                   // ^(arg0>>auxInt), signed shift, auxInt should be in the range 0 to 63.
+		{name: "MVNshiftRO", argLength: 1, reg: gp11, asm: "MVN", aux: "Int64"},                   // ^(arg0 ROR auxInt), signed shift, auxInt should be in the range 0 to 63.
+		{name: "NEGshiftLL", argLength: 1, reg: gp11, asm: "NEG", aux: "Int64"},                   // -(arg0<<auxInt), auxInt should be in the range 0 to 63.
+		{name: "NEGshiftRL", argLength: 1, reg: gp11, asm: "NEG", aux: "Int64"},                   // -(arg0>>auxInt), unsigned shift, auxInt should be in the range 0 to 63.
+		{name: "NEGshiftRA", argLength: 1, reg: gp11, asm: "NEG", aux: "Int64"},                   // -(arg0>>auxInt), signed shift, auxInt should be in the range 0 to 63.
+		{name: "ADDshiftLL", argLength: 2, reg: gp21, asm: "ADD", aux: "Int64"},                   // arg0 + arg1<<auxInt, auxInt should be in the range 0 to 63.
+		{name: "ADDshiftRL", argLength: 2, reg: gp21, asm: "ADD", aux: "Int64"},                   // arg0 + arg1>>auxInt, unsigned shift, auxInt should be in the range 0 to 63.
+		{name: "ADDshiftRA", argLength: 2, reg: gp21, asm: "ADD", aux: "Int64"},                   // arg0 + arg1>>auxInt, signed shift, auxInt should be in the range 0 to 63.
+		{name: "SUBshiftLL", argLength: 2, reg: gp21, asm: "SUB", aux: "Int64"},                   // arg0 - arg1<<auxInt, auxInt should be in the range 0 to 63.
+		{name: "SUBshiftRL", argLength: 2, reg: gp21, asm: "SUB", aux: "Int64"},                   // arg0 - arg1>>auxInt, unsigned shift, auxInt should be in the range 0 to 63.
+		{name: "SUBshiftRA", argLength: 2, reg: gp21, asm: "SUB", aux: "Int64"},                   // arg0 - arg1>>auxInt, signed shift, auxInt should be in the range 0 to 63.
+		{name: "ANDshiftLL", argLength: 2, reg: gp21, asm: "AND", aux: "Int64"},                   // arg0 & (arg1<<auxInt), auxInt should be in the range 0 to 63.
+		{name: "ANDshiftRL", argLength: 2, reg: gp21, asm: "AND", aux: "Int64"},                   // arg0 & (arg1>>auxInt), unsigned shift, auxInt should be in the range 0 to 63.
+		{name: "ANDshiftRA", argLength: 2, reg: gp21, asm: "AND", aux: "Int64"},                   // arg0 & (arg1>>auxInt), signed shift, auxInt should be in the range 0 to 63.
+		{name: "ANDshiftRO", argLength: 2, reg: gp21, asm: "AND", aux: "Int64"},                   // arg0 & (arg1 ROR auxInt), signed shift, auxInt should be in the range 0 to 63.
+		{name: "ORshiftLL", argLength: 2, reg: gp21, asm: "ORR", aux: "Int64"},                    // arg0 | arg1<<auxInt, auxInt should be in the range 0 to 63.
+		{name: "ORshiftRL", argLength: 2, reg: gp21, asm: "ORR", aux: "Int64"},                    // arg0 | arg1>>auxInt, unsigned shift, auxInt should be in the range 0 to 63.
+		{name: "ORshiftRA", argLength: 2, reg: gp21, asm: "ORR", aux: "Int64"},                    // arg0 | arg1>>auxInt, signed shift, auxInt should be in the range 0 to 63.
+		{name: "ORshiftRO", argLength: 2, reg: gp21, asm: "ORR", aux: "Int64"},                    // arg0 | arg1 ROR auxInt, signed shift, auxInt should be in the range 0 to 63.
+		{name: "XORshiftLL", argLength: 2, reg: gp21, asm: "EOR", aux: "Int64"},                   // arg0 ^ arg1<<auxInt, auxInt should be in the range 0 to 63.
+		{name: "XORshiftRL", argLength: 2, reg: gp21, asm: "EOR", aux: "Int64"},                   // arg0 ^ arg1>>auxInt, unsigned shift, auxInt should be in the range 0 to 63.
+		{name: "XORshiftRA", argLength: 2, reg: gp21, asm: "EOR", aux: "Int64"},                   // arg0 ^ arg1>>auxInt, signed shift, auxInt should be in the range 0 to 63.
+		{name: "XORshiftRO", argLength: 2, reg: gp21, asm: "EOR", aux: "Int64"},                   // arg0 ^ arg1 ROR auxInt, signed shift, auxInt should be in the range 0 to 63.
+		{name: "BICshiftLL", argLength: 2, reg: gp21, asm: "BIC", aux: "Int64"},                   // arg0 &^ (arg1<<auxInt), auxInt should be in the range 0 to 63.
+		{name: "BICshiftRL", argLength: 2, reg: gp21, asm: "BIC", aux: "Int64"},                   // arg0 &^ (arg1>>auxInt), unsigned shift, auxInt should be in the range 0 to 63.
+		{name: "BICshiftRA", argLength: 2, reg: gp21, asm: "BIC", aux: "Int64"},                   // arg0 &^ (arg1>>auxInt), signed shift, auxInt should be in the range 0 to 63.
+		{name: "BICshiftRO", argLength: 2, reg: gp21, asm: "BIC", aux: "Int64"},                   // arg0 &^ (arg1 ROR auxInt), signed shift, auxInt should be in the range 0 to 63.
+		{name: "EONshiftLL", argLength: 2, reg: gp21, asm: "EON", aux: "Int64"},                   // arg0 ^ ^(arg1<<auxInt), auxInt should be in the range 0 to 63.
+		{name: "EONshiftRL", argLength: 2, reg: gp21, asm: "EON", aux: "Int64"},                   // arg0 ^ ^(arg1>>auxInt), unsigned shift, auxInt should be in the range 0 to 63.
+		{name: "EONshiftRA", argLength: 2, reg: gp21, asm: "EON", aux: "Int64"},                   // arg0 ^ ^(arg1>>auxInt), signed shift, auxInt should be in the range 0 to 63.
+		{name: "EONshiftRO", argLength: 2, reg: gp21, asm: "EON", aux: "Int64"},                   // arg0 ^ ^(arg1 ROR auxInt), signed shift, auxInt should be in the range 0 to 63.
+		{name: "ORNshiftLL", argLength: 2, reg: gp21, asm: "ORN", aux: "Int64"},                   // arg0 | ^(arg1<<auxInt), auxInt should be in the range 0 to 63.
+		{name: "ORNshiftRL", argLength: 2, reg: gp21, asm: "ORN", aux: "Int64"},                   // arg0 | ^(arg1>>auxInt), unsigned shift, auxInt should be in the range 0 to 63.
+		{name: "ORNshiftRA", argLength: 2, reg: gp21, asm: "ORN", aux: "Int64"},                   // arg0 | ^(arg1>>auxInt), signed shift, auxInt should be in the range 0 to 63.
+		{name: "ORNshiftRO", argLength: 2, reg: gp21, asm: "ORN", aux: "Int64"},                   // arg0 | ^(arg1 ROR auxInt), signed shift, auxInt should be in the range 0 to 63.
+		{name: "CMPshiftLL", argLength: 2, reg: gp2flags, asm: "CMP", aux: "Int64", typ: "Flags"}, // arg0 compare to arg1<<auxInt, auxInt should be in the range 0 to 63.
+		{name: "CMPshiftRL", argLength: 2, reg: gp2flags, asm: "CMP", aux: "Int64", typ: "Flags"}, // arg0 compare to arg1>>auxInt, unsigned shift, auxInt should be in the range 0 to 63.
+		{name: "CMPshiftRA", argLength: 2, reg: gp2flags, asm: "CMP", aux: "Int64", typ: "Flags"}, // arg0 compare to arg1>>auxInt, signed shift, auxInt should be in the range 0 to 63.
+		{name: "CMNshiftLL", argLength: 2, reg: gp2flags, asm: "CMN", aux: "Int64", typ: "Flags"}, // (arg0 + arg1<<auxInt) compare to 0, auxInt should be in the range 0 to 63.
+		{name: "CMNshiftRL", argLength: 2, reg: gp2flags, asm: "CMN", aux: "Int64", typ: "Flags"}, // (arg0 + arg1>>auxInt) compare to 0, unsigned shift, auxInt should be in the range 0 to 63.
+		{name: "CMNshiftRA", argLength: 2, reg: gp2flags, asm: "CMN", aux: "Int64", typ: "Flags"}, // (arg0 + arg1>>auxInt) compare to 0, signed shift, auxInt should be in the range 0 to 63.
+		{name: "TSTshiftLL", argLength: 2, reg: gp2flags, asm: "TST", aux: "Int64", typ: "Flags"}, // (arg0 & arg1<<auxInt) compare to 0, auxInt should be in the range 0 to 63.
+		{name: "TSTshiftRL", argLength: 2, reg: gp2flags, asm: "TST", aux: "Int64", typ: "Flags"}, // (arg0 & arg1>>auxInt) compare to 0, unsigned shift, auxInt should be in the range 0 to 63.
+		{name: "TSTshiftRA", argLength: 2, reg: gp2flags, asm: "TST", aux: "Int64", typ: "Flags"}, // (arg0 & arg1>>auxInt) compare to 0, signed shift, auxInt should be in the range 0 to 63.
+		{name: "TSTshiftRO", argLength: 2, reg: gp2flags, asm: "TST", aux: "Int64", typ: "Flags"}, // (arg0 & arg1 ROR auxInt) compare to 0, signed shift, auxInt should be in the range 0 to 63.
+
+		// bitfield ops
+		// for all bitfield ops lsb is auxInt>>8, width is auxInt&0xff
+		// insert low width bits of arg1 into the result starting at bit lsb, copy other bits from arg0
+		{name: "BFI", argLength: 2, reg: gp21nog, asm: "BFI", aux: "ARM64BitField", resultInArg0: true},
+		// extract width bits of arg1 starting at bit lsb and insert at low end of result, copy other bits from arg0
+		{name: "BFXIL", argLength: 2, reg: gp21nog, asm: "BFXIL", aux: "ARM64BitField", resultInArg0: true},
+		// insert low width bits of arg0 into the result starting at bit lsb, bits to the left of the inserted bit field are set to the high/sign bit of the inserted bit field, bits to the right are zeroed
+		{name: "SBFIZ", argLength: 1, reg: gp11, asm: "SBFIZ", aux: "ARM64BitField"},
+		// extract width bits of arg0 starting at bit lsb and insert at low end of result, remaining high bits are set to the high/sign bit of the extracted bitfield
+		{name: "SBFX", argLength: 1, reg: gp11, asm: "SBFX", aux: "ARM64BitField"},
+		// insert low width bits of arg0 into the result starting at bit lsb, bits to the left and right of the inserted bit field are zeroed
+		{name: "UBFIZ", argLength: 1, reg: gp11, asm: "UBFIZ", aux: "ARM64BitField"},
+		// extract width bits of arg0 starting at bit lsb and insert at low end of result, remaining high bits are zeroed
+		{name: "UBFX", argLength: 1, reg: gp11, asm: "UBFX", aux: "ARM64BitField"},
+
+		// moves
+		{name: "MOVDconst", argLength: 0, reg: gp01, aux: "Int64", asm: "MOVD", typ: "UInt64", rematerializeable: true},      // 64 bits from auxint
+		{name: "FMOVSconst", argLength: 0, reg: fp01, aux: "Float64", asm: "FMOVS", typ: "Float32", rematerializeable: true}, // auxint as 64-bit float, convert to 32-bit float
+		{name: "FMOVDconst", argLength: 0, reg: fp01, aux: "Float64", asm: "FMOVD", typ: "Float64", rematerializeable: true}, // auxint as 64-bit float
+
+		{name: "MOVDaddr", argLength: 1, reg: regInfo{inputs: []regMask{buildReg("SP") | buildReg("SB")}, outputs: []regMask{gp}}, aux: "SymOff", asm: "MOVD", rematerializeable: true, symEffect: "Addr"}, // arg0 + auxInt + aux.(*gc.Sym), arg0=SP/SB
+
+		{name: "MOVBload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVB", typ: "Int8", faultOnNilArg0: true, symEffect: "Read"},       // load from arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVBUload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVBU", typ: "UInt8", faultOnNilArg0: true, symEffect: "Read"},    // load from arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVHload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVH", typ: "Int16", faultOnNilArg0: true, symEffect: "Read"},      // load from arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVHUload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVHU", typ: "UInt16", faultOnNilArg0: true, symEffect: "Read"},   // load from arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVWload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVW", typ: "Int32", faultOnNilArg0: true, symEffect: "Read"},      // load from arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVWUload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVWU", typ: "UInt32", faultOnNilArg0: true, symEffect: "Read"},   // load from arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVDload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVD", typ: "UInt64", faultOnNilArg0: true, symEffect: "Read"},     // load from arg0 + auxInt + aux.  arg1=mem.
+		{name: "LDP", argLength: 2, reg: gpload2, aux: "SymOff", asm: "LDP", typ: "(UInt64,UInt64)", faultOnNilArg0: true, symEffect: "Read"}, // load from ptr = arg0 + auxInt + aux, returns the tuple <*(*uint64)ptr, *(*uint64)(ptr+8)>. arg1=mem.
+		{name: "FMOVSload", argLength: 2, reg: fpload, aux: "SymOff", asm: "FMOVS", typ: "Float32", faultOnNilArg0: true, symEffect: "Read"},  // load from arg0 + auxInt + aux.  arg1=mem.
+		{name: "FMOVDload", argLength: 2, reg: fpload, aux: "SymOff", asm: "FMOVD", typ: "Float64", faultOnNilArg0: true, symEffect: "Read"},  // load from arg0 + auxInt + aux.  arg1=mem.
+
+		// register indexed load
+		{name: "MOVDloadidx", argLength: 3, reg: gp2load, asm: "MOVD", typ: "UInt64"},    // load 64-bit dword from arg0 + arg1, arg2 = mem.
+		{name: "MOVWloadidx", argLength: 3, reg: gp2load, asm: "MOVW", typ: "Int32"},     // load 32-bit word from arg0 + arg1, sign-extended to 64-bit, arg2=mem.
+		{name: "MOVWUloadidx", argLength: 3, reg: gp2load, asm: "MOVWU", typ: "UInt32"},  // load 32-bit word from arg0 + arg1, zero-extended to 64-bit, arg2=mem.
+		{name: "MOVHloadidx", argLength: 3, reg: gp2load, asm: "MOVH", typ: "Int16"},     // load 16-bit word from arg0 + arg1, sign-extended to 64-bit, arg2=mem.
+		{name: "MOVHUloadidx", argLength: 3, reg: gp2load, asm: "MOVHU", typ: "UInt16"},  // load 16-bit word from arg0 + arg1, zero-extended to 64-bit, arg2=mem.
+		{name: "MOVBloadidx", argLength: 3, reg: gp2load, asm: "MOVB", typ: "Int8"},      // load 8-bit word from arg0 + arg1, sign-extended to 64-bit, arg2=mem.
+		{name: "MOVBUloadidx", argLength: 3, reg: gp2load, asm: "MOVBU", typ: "UInt8"},   // load 8-bit word from arg0 + arg1, zero-extended to 64-bit, arg2=mem.
+		{name: "FMOVSloadidx", argLength: 3, reg: fp2load, asm: "FMOVS", typ: "Float32"}, // load 32-bit float from arg0 + arg1, arg2=mem.
+		{name: "FMOVDloadidx", argLength: 3, reg: fp2load, asm: "FMOVD", typ: "Float64"}, // load 64-bit float from arg0 + arg1, arg2=mem.
+
+		// shifted register indexed load
+		{name: "MOVHloadidx2", argLength: 3, reg: gp2load, asm: "MOVH", typ: "Int16"},     // load 16-bit half-word from arg0 + arg1*2, sign-extended to 64-bit, arg2=mem.
+		{name: "MOVHUloadidx2", argLength: 3, reg: gp2load, asm: "MOVHU", typ: "UInt16"},  // load 16-bit half-word from arg0 + arg1*2, zero-extended to 64-bit, arg2=mem.
+		{name: "MOVWloadidx4", argLength: 3, reg: gp2load, asm: "MOVW", typ: "Int32"},     // load 32-bit word from arg0 + arg1*4, sign-extended to 64-bit, arg2=mem.
+		{name: "MOVWUloadidx4", argLength: 3, reg: gp2load, asm: "MOVWU", typ: "UInt32"},  // load 32-bit word from arg0 + arg1*4, zero-extended to 64-bit, arg2=mem.
+		{name: "MOVDloadidx8", argLength: 3, reg: gp2load, asm: "MOVD", typ: "UInt64"},    // load 64-bit double-word from arg0 + arg1*8, arg2 = mem.
+		{name: "FMOVSloadidx4", argLength: 3, reg: fp2load, asm: "FMOVS", typ: "Float32"}, // load 32-bit float from arg0 + arg1*4, arg2 = mem.
+		{name: "FMOVDloadidx8", argLength: 3, reg: fp2load, asm: "FMOVD", typ: "Float64"}, // load 64-bit float from arg0 + arg1*8, arg2 = mem.
+
+		{name: "MOVBstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVB", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},   // store 1 byte of arg1 to arg0 + auxInt + aux.  arg2=mem.
+		{name: "MOVHstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVH", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},   // store 2 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
+		{name: "MOVWstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVW", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},   // store 4 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
+		{name: "MOVDstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVD", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},   // store 8 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
+		{name: "STP", argLength: 4, reg: gpstore2, aux: "SymOff", asm: "STP", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},         // store 16 bytes of arg1 and arg2 to arg0 + auxInt + aux.  arg3=mem.
+		{name: "FMOVSstore", argLength: 3, reg: fpstore, aux: "SymOff", asm: "FMOVS", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
+		{name: "FMOVDstore", argLength: 3, reg: fpstore, aux: "SymOff", asm: "FMOVD", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
+
+		// register indexed store
+		{name: "MOVBstoreidx", argLength: 4, reg: gpstore2, asm: "MOVB", typ: "Mem"},   // store 1 byte of arg2 to arg0 + arg1, arg3 = mem.
+		{name: "MOVHstoreidx", argLength: 4, reg: gpstore2, asm: "MOVH", typ: "Mem"},   // store 2 bytes of arg2 to arg0 + arg1, arg3 = mem.
+		{name: "MOVWstoreidx", argLength: 4, reg: gpstore2, asm: "MOVW", typ: "Mem"},   // store 4 bytes of arg2 to arg0 + arg1, arg3 = mem.
+		{name: "MOVDstoreidx", argLength: 4, reg: gpstore2, asm: "MOVD", typ: "Mem"},   // store 8 bytes of arg2 to arg0 + arg1, arg3 = mem.
+		{name: "FMOVSstoreidx", argLength: 4, reg: fpstore2, asm: "FMOVS", typ: "Mem"}, // store 32-bit float of arg2 to arg0 + arg1, arg3=mem.
+		{name: "FMOVDstoreidx", argLength: 4, reg: fpstore2, asm: "FMOVD", typ: "Mem"}, // store 64-bit float of arg2 to arg0 + arg1, arg3=mem.
+
+		// shifted register indexed store
+		{name: "MOVHstoreidx2", argLength: 4, reg: gpstore2, asm: "MOVH", typ: "Mem"},   // store 2 bytes of arg2 to arg0 + arg1*2, arg3 = mem.
+		{name: "MOVWstoreidx4", argLength: 4, reg: gpstore2, asm: "MOVW", typ: "Mem"},   // store 4 bytes of arg2 to arg0 + arg1*4, arg3 = mem.
+		{name: "MOVDstoreidx8", argLength: 4, reg: gpstore2, asm: "MOVD", typ: "Mem"},   // store 8 bytes of arg2 to arg0 + arg1*8, arg3 = mem.
+		{name: "FMOVSstoreidx4", argLength: 4, reg: fpstore2, asm: "FMOVS", typ: "Mem"}, // store 32-bit float of arg2 to arg0 + arg1*4, arg3=mem.
+		{name: "FMOVDstoreidx8", argLength: 4, reg: fpstore2, asm: "FMOVD", typ: "Mem"}, // store 64-bit float of arg2 to arg0 + arg1*8, arg3=mem.
+
+		{name: "MOVBstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVB", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 1 byte of zero to arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVHstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVH", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 2 bytes of zero to arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVWstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVW", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes of zero to arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVDstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVD", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes of zero to arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVQstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "STP", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},  // store 16 bytes of zero to arg0 + auxInt + aux.  arg1=mem.
+
+		// register indexed store zero
+		{name: "MOVBstorezeroidx", argLength: 3, reg: gpstore, asm: "MOVB", typ: "Mem"}, // store 1 byte of zero to arg0 + arg1, arg2 = mem.
+		{name: "MOVHstorezeroidx", argLength: 3, reg: gpstore, asm: "MOVH", typ: "Mem"}, // store 2 bytes of zero to arg0 + arg1, arg2 = mem.
+		{name: "MOVWstorezeroidx", argLength: 3, reg: gpstore, asm: "MOVW", typ: "Mem"}, // store 4 bytes of zero to arg0 + arg1, arg2 = mem.
+		{name: "MOVDstorezeroidx", argLength: 3, reg: gpstore, asm: "MOVD", typ: "Mem"}, // store 8 bytes of zero to arg0 + arg1, arg2 = mem.
+
+		// shifted register indexed store zero
+		{name: "MOVHstorezeroidx2", argLength: 3, reg: gpstore, asm: "MOVH", typ: "Mem"}, // store 2 bytes of zero to arg0 + arg1*2, arg2 = mem.
+		{name: "MOVWstorezeroidx4", argLength: 3, reg: gpstore, asm: "MOVW", typ: "Mem"}, // store 4 bytes of zero to arg0 + arg1*4, arg2 = mem.
+		{name: "MOVDstorezeroidx8", argLength: 3, reg: gpstore, asm: "MOVD", typ: "Mem"}, // store 8 bytes of zero to arg0 + arg1*8, arg2 = mem.
+
+		{name: "FMOVDgpfp", argLength: 1, reg: gpfp, asm: "FMOVD"}, // move int64 to float64 (no conversion)
+		{name: "FMOVDfpgp", argLength: 1, reg: fpgp, asm: "FMOVD"}, // move float64 to int64 (no conversion)
+		{name: "FMOVSgpfp", argLength: 1, reg: gpfp, asm: "FMOVS"}, // move 32bits from int to float reg (no conversion)
+		{name: "FMOVSfpgp", argLength: 1, reg: fpgp, asm: "FMOVS"}, // move 32bits from float to int reg, zero extend (no conversion)
+
+		// conversions
+		{name: "MOVBreg", argLength: 1, reg: gp11, asm: "MOVB"},   // move from arg0, sign-extended from byte
+		{name: "MOVBUreg", argLength: 1, reg: gp11, asm: "MOVBU"}, // move from arg0, unsign-extended from byte
+		{name: "MOVHreg", argLength: 1, reg: gp11, asm: "MOVH"},   // move from arg0, sign-extended from half
+		{name: "MOVHUreg", argLength: 1, reg: gp11, asm: "MOVHU"}, // move from arg0, unsign-extended from half
+		{name: "MOVWreg", argLength: 1, reg: gp11, asm: "MOVW"},   // move from arg0, sign-extended from word
+		{name: "MOVWUreg", argLength: 1, reg: gp11, asm: "MOVWU"}, // move from arg0, unsign-extended from word
+		{name: "MOVDreg", argLength: 1, reg: gp11, asm: "MOVD"},   // move from arg0
+
+		{name: "MOVDnop", argLength: 1, reg: regInfo{inputs: []regMask{gp}, outputs: []regMask{gp}}, resultInArg0: true}, // nop, return arg0 in same register
+
+		{name: "SCVTFWS", argLength: 1, reg: gpfp, asm: "SCVTFWS"},   // int32 -> float32
+		{name: "SCVTFWD", argLength: 1, reg: gpfp, asm: "SCVTFWD"},   // int32 -> float64
+		{name: "UCVTFWS", argLength: 1, reg: gpfp, asm: "UCVTFWS"},   // uint32 -> float32
+		{name: "UCVTFWD", argLength: 1, reg: gpfp, asm: "UCVTFWD"},   // uint32 -> float64
+		{name: "SCVTFS", argLength: 1, reg: gpfp, asm: "SCVTFS"},     // int64 -> float32
+		{name: "SCVTFD", argLength: 1, reg: gpfp, asm: "SCVTFD"},     // int64 -> float64
+		{name: "UCVTFS", argLength: 1, reg: gpfp, asm: "UCVTFS"},     // uint64 -> float32
+		{name: "UCVTFD", argLength: 1, reg: gpfp, asm: "UCVTFD"},     // uint64 -> float64
+		{name: "FCVTZSSW", argLength: 1, reg: fpgp, asm: "FCVTZSSW"}, // float32 -> int32
+		{name: "FCVTZSDW", argLength: 1, reg: fpgp, asm: "FCVTZSDW"}, // float64 -> int32
+		{name: "FCVTZUSW", argLength: 1, reg: fpgp, asm: "FCVTZUSW"}, // float32 -> uint32
+		{name: "FCVTZUDW", argLength: 1, reg: fpgp, asm: "FCVTZUDW"}, // float64 -> uint32
+		{name: "FCVTZSS", argLength: 1, reg: fpgp, asm: "FCVTZSS"},   // float32 -> int64
+		{name: "FCVTZSD", argLength: 1, reg: fpgp, asm: "FCVTZSD"},   // float64 -> int64
+		{name: "FCVTZUS", argLength: 1, reg: fpgp, asm: "FCVTZUS"},   // float32 -> uint64
+		{name: "FCVTZUD", argLength: 1, reg: fpgp, asm: "FCVTZUD"},   // float64 -> uint64
+		{name: "FCVTSD", argLength: 1, reg: fp11, asm: "FCVTSD"},     // float32 -> float64
+		{name: "FCVTDS", argLength: 1, reg: fp11, asm: "FCVTDS"},     // float64 -> float32
+
+		// floating-point round to integral
+		{name: "FRINTAD", argLength: 1, reg: fp11, asm: "FRINTAD"},
+		{name: "FRINTMD", argLength: 1, reg: fp11, asm: "FRINTMD"},
+		{name: "FRINTND", argLength: 1, reg: fp11, asm: "FRINTND"},
+		{name: "FRINTPD", argLength: 1, reg: fp11, asm: "FRINTPD"},
+		{name: "FRINTZD", argLength: 1, reg: fp11, asm: "FRINTZD"},
+
+		// conditional instructions; auxint is
+		// one of the arm64 comparison pseudo-ops (LessThan, LessThanU, etc.)
+		{name: "CSEL", argLength: 3, reg: gp2flags1, asm: "CSEL", aux: "CCop"},   // auxint(flags) ? arg0 : arg1
+		{name: "CSEL0", argLength: 2, reg: gp1flags1, asm: "CSEL", aux: "CCop"},  // auxint(flags) ? arg0 : 0
+		{name: "CSINC", argLength: 3, reg: gp2flags1, asm: "CSINC", aux: "CCop"}, // auxint(flags) ? arg0 : arg1 + 1
+		{name: "CSINV", argLength: 3, reg: gp2flags1, asm: "CSINV", aux: "CCop"}, // auxint(flags) ? arg0 : ^arg1
+		{name: "CSNEG", argLength: 3, reg: gp2flags1, asm: "CSNEG", aux: "CCop"}, // auxint(flags) ? arg0 : -arg1
+		{name: "CSETM", argLength: 1, reg: readflags, asm: "CSETM", aux: "CCop"}, // auxint(flags) ? -1 : 0
+
+		// function calls
+		{name: "CALLstatic", argLength: -1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                                               // call static function aux.(*obj.LSym).  last arg=mem, auxint=argsize, returns mem
+		{name: "CALLtail", argLength: -1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true, tailCall: true},                                 // tail call static function aux.(*obj.LSym).  last arg=mem, auxint=argsize, returns mem
+		{name: "CALLclosure", argLength: -1, reg: regInfo{inputs: []regMask{gpsp, buildReg("R26"), 0}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call function via closure.  arg0=codeptr, arg1=closure, last arg=mem, auxint=argsize, returns mem
+		{name: "CALLinter", argLength: -1, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                         // call fn by pointer.  arg0=codeptr, last arg=mem, auxint=argsize, returns mem
+
+		// pseudo-ops
+		{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpg}}, nilCheck: true, faultOnNilArg0: true}, // panic if arg0 is nil.  arg1=mem.
+
+		{name: "Equal", argLength: 1, reg: readflags},            // bool, true flags encode x==y false otherwise.
+		{name: "NotEqual", argLength: 1, reg: readflags},         // bool, true flags encode x!=y false otherwise.
+		{name: "LessThan", argLength: 1, reg: readflags},         // bool, true flags encode signed x<y false otherwise.
+		{name: "LessEqual", argLength: 1, reg: readflags},        // bool, true flags encode signed x<=y false otherwise.
+		{name: "GreaterThan", argLength: 1, reg: readflags},      // bool, true flags encode signed x>y false otherwise.
+		{name: "GreaterEqual", argLength: 1, reg: readflags},     // bool, true flags encode signed x>=y false otherwise.
+		{name: "LessThanU", argLength: 1, reg: readflags},        // bool, true flags encode unsigned x<y false otherwise.
+		{name: "LessEqualU", argLength: 1, reg: readflags},       // bool, true flags encode unsigned x<=y false otherwise.
+		{name: "GreaterThanU", argLength: 1, reg: readflags},     // bool, true flags encode unsigned x>y false otherwise.
+		{name: "GreaterEqualU", argLength: 1, reg: readflags},    // bool, true flags encode unsigned x>=y false otherwise.
+		{name: "LessThanF", argLength: 1, reg: readflags},        // bool, true flags encode floating-point x<y false otherwise.
+		{name: "LessEqualF", argLength: 1, reg: readflags},       // bool, true flags encode floating-point x<=y false otherwise.
+		{name: "GreaterThanF", argLength: 1, reg: readflags},     // bool, true flags encode floating-point x>y false otherwise.
+		{name: "GreaterEqualF", argLength: 1, reg: readflags},    // bool, true flags encode floating-point x>=y false otherwise.
+		{name: "NotLessThanF", argLength: 1, reg: readflags},     // bool, true flags encode floating-point x>=y || x is unordered with y, false otherwise.
+		{name: "NotLessEqualF", argLength: 1, reg: readflags},    // bool, true flags encode floating-point x>y || x is unordered with y, false otherwise.
+		{name: "NotGreaterThanF", argLength: 1, reg: readflags},  // bool, true flags encode floating-point x<=y || x is unordered with y, false otherwise.
+		{name: "NotGreaterEqualF", argLength: 1, reg: readflags}, // bool, true flags encode floating-point x<y || x is unordered with y, false otherwise.
+		// duffzero
+		// arg0 = address of memory to zero
+		// arg1 = mem
+		// auxint = offset into duffzero code to start executing
+		// returns mem
+		// R20 changed as side effect
+		// R16 and R17 may be clobbered by linker trampoline.
+		{
+			name:      "DUFFZERO",
+			aux:       "Int64",
+			argLength: 2,
+			reg: regInfo{
+				inputs:   []regMask{buildReg("R20")},
+				clobbers: buildReg("R16 R17 R20 R30"),
+			},
+			faultOnNilArg0: true,
+			unsafePoint:    true, // FP maintenance around DUFFZERO can be clobbered by interrupts
+		},
+
+		// large zeroing
+		// arg0 = address of memory to zero (in R16 aka arm64.REGRT1, changed as side effect)
+		// arg1 = address of the last 16-byte unit to zero
+		// arg2 = mem
+		// returns mem
+		//	STP.P	(ZR,ZR), 16(R16)
+		//	CMP	Rarg1, R16
+		//	BLE	-2(PC)
+		// Note: the-end-of-the-memory may be not a valid pointer. it's a problem if it is spilled.
+		// the-end-of-the-memory - 16 is with the area to zero, ok to spill.
+		{
+			name:      "LoweredZero",
+			argLength: 3,
+			reg: regInfo{
+				inputs:   []regMask{buildReg("R16"), gp},
+				clobbers: buildReg("R16"),
+			},
+			clobberFlags:   true,
+			faultOnNilArg0: true,
+		},
+
+		// duffcopy
+		// arg0 = address of dst memory (in R21, changed as side effect)
+		// arg1 = address of src memory (in R20, changed as side effect)
+		// arg2 = mem
+		// auxint = offset into duffcopy code to start executing
+		// returns mem
+		// R20, R21 changed as side effect
+		// R16 and R17 may be clobbered by linker trampoline.
+		{
+			name:      "DUFFCOPY",
+			aux:       "Int64",
+			argLength: 3,
+			reg: regInfo{
+				inputs:   []regMask{buildReg("R21"), buildReg("R20")},
+				clobbers: buildReg("R16 R17 R20 R21 R26 R30"),
+			},
+			faultOnNilArg0: true,
+			faultOnNilArg1: true,
+			unsafePoint:    true, // FP maintenance around DUFFCOPY can be clobbered by interrupts
+		},
+
+		// large move
+		// arg0 = address of dst memory (in R17 aka arm64.REGRT2, changed as side effect)
+		// arg1 = address of src memory (in R16 aka arm64.REGRT1, changed as side effect)
+		// arg2 = address of the last element of src
+		// arg3 = mem
+		// returns mem
+		//	LDP.P	16(R16), (R25, Rtmp)
+		//	STP.P	(R25, Rtmp), 16(R17)
+		//	CMP	Rarg2, R16
+		//	BLE	-3(PC)
+		// Note: the-end-of-src may be not a valid pointer. it's a problem if it is spilled.
+		// the-end-of-src - 16 is within the area to copy, ok to spill.
+		{
+			name:      "LoweredMove",
+			argLength: 4,
+			reg: regInfo{
+				inputs:   []regMask{buildReg("R17"), buildReg("R16"), gp &^ buildReg("R25")},
+				clobbers: buildReg("R16 R17 R25"),
+			},
+			clobberFlags:   true,
+			faultOnNilArg0: true,
+			faultOnNilArg1: true,
+		},
+
+		// Scheduler ensures LoweredGetClosurePtr occurs only in entry block,
+		// and sorts it to the very beginning of the block to prevent other
+		// use of R26 (arm64.REGCTXT, the closure pointer)
+		{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R26")}}, zeroWidth: true},
+
+		// LoweredGetCallerSP returns the SP of the caller of the current function.
+		{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
+
+		// LoweredGetCallerPC evaluates to the PC to which its "caller" will return.
+		// I.e., if f calls g "calls" getcallerpc,
+		// the result should be the PC within f that g will return to.
+		// See runtime/stubs.go for a more detailed discussion.
+		{name: "LoweredGetCallerPC", reg: gp01, rematerializeable: true},
+
+		// Constant flag value.
+		// Note: there's an "unordered" outcome for floating-point
+		// comparisons, but we don't use such a beast yet.
+		// This op is for temporary use by rewrite rules. It
+		// cannot appear in the generated assembly.
+		{name: "FlagConstant", aux: "FlagConstant"},
+
+		// (InvertFlags (CMP a b)) == (CMP b a)
+		// InvertFlags is a pseudo-op which can't appear in assembly output.
+		{name: "InvertFlags", argLength: 1}, // reverse direction of arg0
+
+		// atomic loads.
+		// load from arg0. arg1=mem. auxint must be zero.
+		// returns <value,memory> so they can be properly ordered with other loads.
+		{name: "LDAR", argLength: 2, reg: gpload, asm: "LDAR", faultOnNilArg0: true},
+		{name: "LDARB", argLength: 2, reg: gpload, asm: "LDARB", faultOnNilArg0: true},
+		{name: "LDARW", argLength: 2, reg: gpload, asm: "LDARW", faultOnNilArg0: true},
+
+		// atomic stores.
+		// store arg1 to arg0. arg2=mem. returns memory. auxint must be zero.
+		{name: "STLRB", argLength: 3, reg: gpstore, asm: "STLRB", faultOnNilArg0: true, hasSideEffects: true},
+		{name: "STLR", argLength: 3, reg: gpstore, asm: "STLR", faultOnNilArg0: true, hasSideEffects: true},
+		{name: "STLRW", argLength: 3, reg: gpstore, asm: "STLRW", faultOnNilArg0: true, hasSideEffects: true},
+
+		// atomic exchange.
+		// store arg1 to arg0. arg2=mem. returns <old content of *arg0, memory>. auxint must be zero.
+		// LDAXR	(Rarg0), Rout
+		// STLXR	Rarg1, (Rarg0), Rtmp
+		// CBNZ		Rtmp, -2(PC)
+		{name: "LoweredAtomicExchange64", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+		{name: "LoweredAtomicExchange32", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+
+		// atomic exchange variant.
+		// store arg1 to arg0. arg2=mem. returns <old content of *arg0, memory>. auxint must be zero.
+		// SWPALD	Rarg1, (Rarg0), Rout
+		{name: "LoweredAtomicExchange64Variant", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
+		{name: "LoweredAtomicExchange32Variant", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
+
+		// atomic add.
+		// *arg0 += arg1. arg2=mem. returns <new content of *arg0, memory>. auxint must be zero.
+		// LDAXR	(Rarg0), Rout
+		// ADD		Rarg1, Rout
+		// STLXR	Rout, (Rarg0), Rtmp
+		// CBNZ		Rtmp, -3(PC)
+		{name: "LoweredAtomicAdd64", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+		{name: "LoweredAtomicAdd32", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+
+		// atomic add variant.
+		// *arg0 += arg1. arg2=mem. returns <new content of *arg0, memory>. auxint must be zero.
+		// LDADDAL	(Rarg0), Rarg1, Rout
+		// ADD		Rarg1, Rout
+		{name: "LoweredAtomicAdd64Variant", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
+		{name: "LoweredAtomicAdd32Variant", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
+
+		// atomic compare and swap.
+		// arg0 = pointer, arg1 = old value, arg2 = new value, arg3 = memory. auxint must be zero.
+		// if *arg0 == arg1 {
+		//   *arg0 = arg2
+		//   return (true, memory)
+		// } else {
+		//   return (false, memory)
+		// }
+		// LDAXR	(Rarg0), Rtmp
+		// CMP		Rarg1, Rtmp
+		// BNE		3(PC)
+		// STLXR	Rarg2, (Rarg0), Rtmp
+		// CBNZ		Rtmp, -4(PC)
+		// CSET		EQ, Rout
+		{name: "LoweredAtomicCas64", argLength: 4, reg: gpcas, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+		{name: "LoweredAtomicCas32", argLength: 4, reg: gpcas, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+
+		// atomic compare and swap variant.
+		// arg0 = pointer, arg1 = old value, arg2 = new value, arg3 = memory. auxint must be zero.
+		// if *arg0 == arg1 {
+		//   *arg0 = arg2
+		//   return (true, memory)
+		// } else {
+		//   return (false, memory)
+		// }
+		// MOV  	Rarg1, Rtmp
+		// CASAL	Rtmp, (Rarg0), Rarg2
+		// CMP  	Rarg1, Rtmp
+		// CSET 	EQ, Rout
+		{name: "LoweredAtomicCas64Variant", argLength: 4, reg: gpcas, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+		{name: "LoweredAtomicCas32Variant", argLength: 4, reg: gpcas, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+
+		// atomic and/or.
+		// *arg0 &= (|=) arg1. arg2=mem. returns <new content of *arg0, memory>. auxint must be zero.
+		// LDAXR	(Rarg0), Rout
+		// AND/OR	Rarg1, Rout
+		// STLXR	Rout, (Rarg0), Rtmp
+		// CBNZ		Rtmp, -3(PC)
+		{name: "LoweredAtomicAnd8", argLength: 3, reg: gpxchg, resultNotInArgs: true, asm: "AND", typ: "(UInt8,Mem)", faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+		{name: "LoweredAtomicAnd32", argLength: 3, reg: gpxchg, resultNotInArgs: true, asm: "AND", typ: "(UInt32,Mem)", faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+		{name: "LoweredAtomicOr8", argLength: 3, reg: gpxchg, resultNotInArgs: true, asm: "ORR", typ: "(UInt8,Mem)", faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+		{name: "LoweredAtomicOr32", argLength: 3, reg: gpxchg, resultNotInArgs: true, asm: "ORR", typ: "(UInt32,Mem)", faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+
+		// atomic and/or variant.
+		// *arg0 &= (|=) arg1. arg2=mem. returns <new content of *arg0, memory>. auxint must be zero.
+		//   AND:
+		// MNV       Rarg1, Rtemp
+		// LDANDALB  Rtemp, (Rarg0), Rout
+		// AND       Rarg1, Rout
+		//   OR:
+		// LDORALB  Rarg1, (Rarg0), Rout
+		// ORR       Rarg1, Rout
+		{name: "LoweredAtomicAnd8Variant", argLength: 3, reg: gpxchg, resultNotInArgs: true, typ: "(UInt8,Mem)", faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+		{name: "LoweredAtomicAnd32Variant", argLength: 3, reg: gpxchg, resultNotInArgs: true, typ: "(UInt32,Mem)", faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+		{name: "LoweredAtomicOr8Variant", argLength: 3, reg: gpxchg, resultNotInArgs: true, typ: "(UInt8,Mem)", faultOnNilArg0: true, hasSideEffects: true},
+		{name: "LoweredAtomicOr32Variant", argLength: 3, reg: gpxchg, resultNotInArgs: true, typ: "(UInt32,Mem)", faultOnNilArg0: true, hasSideEffects: true},
+
+		// LoweredWB invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
+		// It saves all GP registers if necessary,
+		// but clobbers R30 (LR) because it's a call.
+		// R16 and R17 may be clobbered by linker trampoline.
+		{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R2"), buildReg("R3")}, clobbers: (callerSave &^ gpg) | buildReg("R16 R17 R30")}, clobberFlags: true, aux: "Sym", symEffect: "None"},
+
+		// There are three of these functions so that they can have three different register inputs.
+		// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the
+		// default registers to match so we don't need to copy registers around unnecessarily.
+		{name: "LoweredPanicBoundsA", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r2, r3}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
+		{name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r1, r2}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
+		{name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r0, r1}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
+
+		// Prefetch instruction
+		// Do prefetch arg0 address with option aux. arg0=addr, arg1=memory, aux=option.
+		{name: "PRFM", argLength: 2, aux: "Int64", reg: prefreg, asm: "PRFM", hasSideEffects: true},
+
+		// Publication barrier
+		{name: "DMB", argLength: 1, aux: "Int64", asm: "DMB", hasSideEffects: true}, // Do data barrier. arg0=memory, aux=option.
+	}
+
+	blocks := []blockData{
+		{name: "EQ", controls: 1},
+		{name: "NE", controls: 1},
+		{name: "LT", controls: 1},
+		{name: "LE", controls: 1},
+		{name: "GT", controls: 1},
+		{name: "GE", controls: 1},
+		{name: "ULT", controls: 1},
+		{name: "ULE", controls: 1},
+		{name: "UGT", controls: 1},
+		{name: "UGE", controls: 1},
+		{name: "Z", controls: 1},                  // Control == 0 (take a register instead of flags)
+		{name: "NZ", controls: 1},                 // Control != 0
+		{name: "ZW", controls: 1},                 // Control == 0, 32-bit
+		{name: "NZW", controls: 1},                // Control != 0, 32-bit
+		{name: "TBZ", controls: 1, aux: "Int64"},  // Control & (1 << AuxInt) == 0
+		{name: "TBNZ", controls: 1, aux: "Int64"}, // Control & (1 << AuxInt) != 0
+		{name: "FLT", controls: 1},
+		{name: "FLE", controls: 1},
+		{name: "FGT", controls: 1},
+		{name: "FGE", controls: 1},
+		{name: "LTnoov", controls: 1}, // 'LT' but without honoring overflow
+		{name: "LEnoov", controls: 1}, // 'LE' but without honoring overflow
+		{name: "GTnoov", controls: 1}, // 'GT' but without honoring overflow
+		{name: "GEnoov", controls: 1}, // 'GE' but without honoring overflow
+
+		// JUMPTABLE implements jump tables.
+		// Aux is the symbol (an *obj.LSym) for the jump table.
+		// control[0] is the index into the jump table.
+		// control[1] is the address of the jump table (the address of the symbol stored in Aux).
+		{name: "JUMPTABLE", controls: 2, aux: "Sym"},
+	}
+
+	archs = append(archs, arch{
+		name:               "ARM64",
+		pkg:                "cmd/internal/obj/arm64",
+		genfile:            "../../arm64/ssa.go",
+		ops:                ops,
+		blocks:             blocks,
+		regnames:           regNamesARM64,
+		ParamIntRegNames:   "R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15",
+		ParamFloatRegNames: "F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15",
+		gpregmask:          gp,
+		fpregmask:          fp,
+		framepointerreg:    -1, // not used
+		linkreg:            int8(num["R30"]),
+	})
+}
diff --git a/src/cmd/compile/internal/ssa/_gen/ARM64latelower.rules b/src/cmd/compile/internal/ssa/_gen/ARM64latelower.rules
new file mode 100644
index 0000000..d0c2099
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/_gen/ARM64latelower.rules
@@ -0,0 +1,21 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains rules used by the laterLower pass.
+// These are often the exact inverse of rules in ARM64.rules.
+
+(ADDconst [c] x) && !isARM64addcon(c)  => (ADD x (MOVDconst [c]))
+(SUBconst [c] x) && !isARM64addcon(c)  => (SUB x (MOVDconst [c]))
+(ANDconst [c] x) && !isARM64bitcon(uint64(c)) => (AND x (MOVDconst [c]))
+(ORconst  [c] x) && !isARM64bitcon(uint64(c))  => (OR  x (MOVDconst [c]))
+(XORconst [c] x) && !isARM64bitcon(uint64(c))  => (XOR x (MOVDconst [c]))
+(TSTconst [c] x) && !isARM64bitcon(uint64(c))  => (TST x (MOVDconst [c]))
+(TSTWconst [c] x) && !isARM64bitcon(uint64(c)|uint64(c)<<32)  => (TSTW x (MOVDconst [int64(c)]))
+
+(CMPconst [c] x) && !isARM64addcon(c)  => (CMP x (MOVDconst [c]))
+(CMPWconst [c] x) && !isARM64addcon(int64(c))  => (CMPW x (MOVDconst [int64(c)]))
+(CMNconst [c] x) && !isARM64addcon(c)  => (CMN x (MOVDconst [c]))
+(CMNWconst [c] x) && !isARM64addcon(int64(c))  => (CMNW x (MOVDconst [int64(c)]))
+
+(ADDSconstflags [c] x) && !isARM64addcon(c)  => (ADDSflags x (MOVDconst [c]))
diff --git a/src/cmd/compile/internal/ssa/_gen/ARMOps.go b/src/cmd/compile/internal/ssa/_gen/ARMOps.go
new file mode 100644
index 0000000..de477a2
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/_gen/ARMOps.go
@@ -0,0 +1,600 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "strings"
+
+// Notes:
+//  - Integer types live in the low portion of registers. Upper portions are junk.
+//  - Boolean types use the low-order byte of a register. 0=false, 1=true.
+//    Upper bytes are junk.
+//  - *const instructions may use a constant larger than the instruction can encode.
+//    In this case the assembler expands to multiple instructions and uses tmp
+//    register (R11).
+
+// Suffixes encode the bit width of various instructions.
+// W (word)      = 32 bit
+// H (half word) = 16 bit
+// HU            = 16 bit unsigned
+// B (byte)      = 8 bit
+// BU            = 8 bit unsigned
+// F (float)     = 32 bit float
+// D (double)    = 64 bit float
+
+var regNamesARM = []string{
+	"R0",
+	"R1",
+	"R2",
+	"R3",
+	"R4",
+	"R5",
+	"R6",
+	"R7",
+	"R8",
+	"R9",
+	"g",   // aka R10
+	"R11", // tmp
+	"R12",
+	"SP",  // aka R13
+	"R14", // link
+	"R15", // pc
+
+	"F0",
+	"F1",
+	"F2",
+	"F3",
+	"F4",
+	"F5",
+	"F6",
+	"F7",
+	"F8",
+	"F9",
+	"F10",
+	"F11",
+	"F12",
+	"F13",
+	"F14",
+	"F15", // tmp
+
+	// If you add registers, update asyncPreempt in runtime.
+
+	// pseudo-registers
+	"SB",
+}
+
+func init() {
+	// Make map from reg names to reg integers.
+	if len(regNamesARM) > 64 {
+		panic("too many registers")
+	}
+	num := map[string]int{}
+	for i, name := range regNamesARM {
+		num[name] = i
+	}
+	buildReg := func(s string) regMask {
+		m := regMask(0)
+		for _, r := range strings.Split(s, " ") {
+			if n, ok := num[r]; ok {
+				m |= regMask(1) << uint(n)
+				continue
+			}
+			panic("register " + r + " not found")
+		}
+		return m
+	}
+
+	// Common individual register masks
+	var (
+		gp         = buildReg("R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14")
+		gpg        = gp | buildReg("g")
+		gpsp       = gp | buildReg("SP")
+		gpspg      = gpg | buildReg("SP")
+		gpspsbg    = gpspg | buildReg("SB")
+		fp         = buildReg("F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15")
+		callerSave = gp | fp | buildReg("g") // runtime.setg (and anything calling it) may clobber g
+		r0         = buildReg("R0")
+		r1         = buildReg("R1")
+		r2         = buildReg("R2")
+		r3         = buildReg("R3")
+		r4         = buildReg("R4")
+	)
+	// Common regInfo
+	var (
+		gp01      = regInfo{inputs: nil, outputs: []regMask{gp}}
+		gp11      = regInfo{inputs: []regMask{gpg}, outputs: []regMask{gp}}
+		gp11carry = regInfo{inputs: []regMask{gpg}, outputs: []regMask{gp, 0}}
+		gp11sp    = regInfo{inputs: []regMask{gpspg}, outputs: []regMask{gp}}
+		gp1flags  = regInfo{inputs: []regMask{gpg}}
+		gp1flags1 = regInfo{inputs: []regMask{gp}, outputs: []regMask{gp}}
+		gp21      = regInfo{inputs: []regMask{gpg, gpg}, outputs: []regMask{gp}}
+		gp21carry = regInfo{inputs: []regMask{gpg, gpg}, outputs: []regMask{gp, 0}}
+		gp2flags  = regInfo{inputs: []regMask{gpg, gpg}}
+		gp2flags1 = regInfo{inputs: []regMask{gp, gp}, outputs: []regMask{gp}}
+		gp22      = regInfo{inputs: []regMask{gpg, gpg}, outputs: []regMask{gp, gp}}
+		gp31      = regInfo{inputs: []regMask{gp, gp, gp}, outputs: []regMask{gp}}
+		gp31carry = regInfo{inputs: []regMask{gp, gp, gp}, outputs: []regMask{gp, 0}}
+		gp3flags  = regInfo{inputs: []regMask{gp, gp, gp}}
+		gp3flags1 = regInfo{inputs: []regMask{gp, gp, gp}, outputs: []regMask{gp}}
+		gpload    = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{gp}}
+		gpstore   = regInfo{inputs: []regMask{gpspsbg, gpg}}
+		gp2load   = regInfo{inputs: []regMask{gpspsbg, gpg}, outputs: []regMask{gp}}
+		gp2store  = regInfo{inputs: []regMask{gpspsbg, gpg, gpg}}
+		fp01      = regInfo{inputs: nil, outputs: []regMask{fp}}
+		fp11      = regInfo{inputs: []regMask{fp}, outputs: []regMask{fp}}
+		fp1flags  = regInfo{inputs: []regMask{fp}}
+		fpgp      = regInfo{inputs: []regMask{fp}, outputs: []regMask{gp}, clobbers: buildReg("F15")} // int-float conversion uses F15 as tmp
+		gpfp      = regInfo{inputs: []regMask{gp}, outputs: []regMask{fp}, clobbers: buildReg("F15")}
+		fp21      = regInfo{inputs: []regMask{fp, fp}, outputs: []regMask{fp}}
+		fp31      = regInfo{inputs: []regMask{fp, fp, fp}, outputs: []regMask{fp}}
+		fp2flags  = regInfo{inputs: []regMask{fp, fp}}
+		fpload    = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{fp}}
+		fpstore   = regInfo{inputs: []regMask{gpspsbg, fp}}
+		readflags = regInfo{inputs: nil, outputs: []regMask{gp}}
+	)
+	ops := []opData{
+		// binary ops
+		{name: "ADD", argLength: 2, reg: gp21, asm: "ADD", commutative: true},     // arg0 + arg1
+		{name: "ADDconst", argLength: 1, reg: gp11sp, asm: "ADD", aux: "Int32"},   // arg0 + auxInt
+		{name: "SUB", argLength: 2, reg: gp21, asm: "SUB"},                        // arg0 - arg1
+		{name: "SUBconst", argLength: 1, reg: gp11, asm: "SUB", aux: "Int32"},     // arg0 - auxInt
+		{name: "RSB", argLength: 2, reg: gp21, asm: "RSB"},                        // arg1 - arg0
+		{name: "RSBconst", argLength: 1, reg: gp11, asm: "RSB", aux: "Int32"},     // auxInt - arg0
+		{name: "MUL", argLength: 2, reg: gp21, asm: "MUL", commutative: true},     // arg0 * arg1
+		{name: "HMUL", argLength: 2, reg: gp21, asm: "MULL", commutative: true},   // (arg0 * arg1) >> 32, signed
+		{name: "HMULU", argLength: 2, reg: gp21, asm: "MULLU", commutative: true}, // (arg0 * arg1) >> 32, unsigned
+
+		// udiv runtime call for soft division
+		// output0 = arg0/arg1, output1 = arg0%arg1
+		// see ../../../../../runtime/vlop_arm.s
+		{
+			name:      "CALLudiv",
+			argLength: 2,
+			reg: regInfo{
+				inputs:   []regMask{buildReg("R1"), buildReg("R0")},
+				outputs:  []regMask{buildReg("R0"), buildReg("R1")},
+				clobbers: buildReg("R2 R3 R12 R14"), // R14 is LR, R12 is linker trampoline scratch register
+			},
+			clobberFlags: true,
+			typ:          "(UInt32,UInt32)",
+			call:         false, // TODO(mdempsky): Should this be true?
+		},
+
+		{name: "ADDS", argLength: 2, reg: gp21carry, asm: "ADD", commutative: true}, // arg0 + arg1, set carry flag
+		{name: "ADDSconst", argLength: 1, reg: gp11carry, asm: "ADD", aux: "Int32"}, // arg0 + auxInt, set carry flag
+		{name: "ADC", argLength: 3, reg: gp2flags1, asm: "ADC", commutative: true},  // arg0 + arg1 + carry, arg2=flags
+		{name: "ADCconst", argLength: 2, reg: gp1flags1, asm: "ADC", aux: "Int32"},  // arg0 + auxInt + carry, arg1=flags
+		{name: "SUBS", argLength: 2, reg: gp21carry, asm: "SUB"},                    // arg0 - arg1, set carry flag
+		{name: "SUBSconst", argLength: 1, reg: gp11carry, asm: "SUB", aux: "Int32"}, // arg0 - auxInt, set carry flag
+		{name: "RSBSconst", argLength: 1, reg: gp11carry, asm: "RSB", aux: "Int32"}, // auxInt - arg0, set carry flag
+		{name: "SBC", argLength: 3, reg: gp2flags1, asm: "SBC"},                     // arg0 - arg1 - carry, arg2=flags
+		{name: "SBCconst", argLength: 2, reg: gp1flags1, asm: "SBC", aux: "Int32"},  // arg0 - auxInt - carry, arg1=flags
+		{name: "RSCconst", argLength: 2, reg: gp1flags1, asm: "RSC", aux: "Int32"},  // auxInt - arg0 - carry, arg1=flags
+
+		{name: "MULLU", argLength: 2, reg: gp22, asm: "MULLU", commutative: true}, // arg0 * arg1, high 32 bits in out0, low 32 bits in out1
+		{name: "MULA", argLength: 3, reg: gp31, asm: "MULA"},                      // arg0 * arg1 + arg2
+		{name: "MULS", argLength: 3, reg: gp31, asm: "MULS"},                      // arg2 - arg0 * arg1
+
+		{name: "ADDF", argLength: 2, reg: fp21, asm: "ADDF", commutative: true},   // arg0 + arg1
+		{name: "ADDD", argLength: 2, reg: fp21, asm: "ADDD", commutative: true},   // arg0 + arg1
+		{name: "SUBF", argLength: 2, reg: fp21, asm: "SUBF"},                      // arg0 - arg1
+		{name: "SUBD", argLength: 2, reg: fp21, asm: "SUBD"},                      // arg0 - arg1
+		{name: "MULF", argLength: 2, reg: fp21, asm: "MULF", commutative: true},   // arg0 * arg1
+		{name: "MULD", argLength: 2, reg: fp21, asm: "MULD", commutative: true},   // arg0 * arg1
+		{name: "NMULF", argLength: 2, reg: fp21, asm: "NMULF", commutative: true}, // -(arg0 * arg1)
+		{name: "NMULD", argLength: 2, reg: fp21, asm: "NMULD", commutative: true}, // -(arg0 * arg1)
+		{name: "DIVF", argLength: 2, reg: fp21, asm: "DIVF"},                      // arg0 / arg1
+		{name: "DIVD", argLength: 2, reg: fp21, asm: "DIVD"},                      // arg0 / arg1
+
+		{name: "MULAF", argLength: 3, reg: fp31, asm: "MULAF", resultInArg0: true}, // arg0 + (arg1 * arg2)
+		{name: "MULAD", argLength: 3, reg: fp31, asm: "MULAD", resultInArg0: true}, // arg0 + (arg1 * arg2)
+		{name: "MULSF", argLength: 3, reg: fp31, asm: "MULSF", resultInArg0: true}, // arg0 - (arg1 * arg2)
+		{name: "MULSD", argLength: 3, reg: fp31, asm: "MULSD", resultInArg0: true}, // arg0 - (arg1 * arg2)
+
+		// FMULAD only exists on platforms with the VFPv4 instruction set.
+		// Any use must be preceded by a successful check of runtime.arm_support_vfpv4.
+		{name: "FMULAD", argLength: 3, reg: fp31, asm: "FMULAD", resultInArg0: true}, // arg0 + (arg1 * arg2)
+
+		{name: "AND", argLength: 2, reg: gp21, asm: "AND", commutative: true}, // arg0 & arg1
+		{name: "ANDconst", argLength: 1, reg: gp11, asm: "AND", aux: "Int32"}, // arg0 & auxInt
+		{name: "OR", argLength: 2, reg: gp21, asm: "ORR", commutative: true},  // arg0 | arg1
+		{name: "ORconst", argLength: 1, reg: gp11, asm: "ORR", aux: "Int32"},  // arg0 | auxInt
+		{name: "XOR", argLength: 2, reg: gp21, asm: "EOR", commutative: true}, // arg0 ^ arg1
+		{name: "XORconst", argLength: 1, reg: gp11, asm: "EOR", aux: "Int32"}, // arg0 ^ auxInt
+		{name: "BIC", argLength: 2, reg: gp21, asm: "BIC"},                    // arg0 &^ arg1
+		{name: "BICconst", argLength: 1, reg: gp11, asm: "BIC", aux: "Int32"}, // arg0 &^ auxInt
+
+		// bit extraction, AuxInt = Width<<8 | LSB
+		{name: "BFX", argLength: 1, reg: gp11, asm: "BFX", aux: "Int32"},   // extract W bits from bit L in arg0, then signed extend
+		{name: "BFXU", argLength: 1, reg: gp11, asm: "BFXU", aux: "Int32"}, // extract W bits from bit L in arg0, then unsigned extend
+
+		// unary ops
+		{name: "MVN", argLength: 1, reg: gp11, asm: "MVN"}, // ^arg0
+
+		{name: "NEGF", argLength: 1, reg: fp11, asm: "NEGF"},   // -arg0, float32
+		{name: "NEGD", argLength: 1, reg: fp11, asm: "NEGD"},   // -arg0, float64
+		{name: "SQRTD", argLength: 1, reg: fp11, asm: "SQRTD"}, // sqrt(arg0), float64
+		{name: "SQRTF", argLength: 1, reg: fp11, asm: "SQRTF"}, // sqrt(arg0), float32
+		{name: "ABSD", argLength: 1, reg: fp11, asm: "ABSD"},   // abs(arg0), float64
+
+		{name: "CLZ", argLength: 1, reg: gp11, asm: "CLZ"},     // count leading zero
+		{name: "REV", argLength: 1, reg: gp11, asm: "REV"},     // reverse byte order
+		{name: "REV16", argLength: 1, reg: gp11, asm: "REV16"}, // reverse byte order in 16-bit halfwords
+		{name: "RBIT", argLength: 1, reg: gp11, asm: "RBIT"},   // reverse bit order
+
+		// shifts
+		{name: "SLL", argLength: 2, reg: gp21, asm: "SLL"},                    // arg0 << arg1, shift amount is mod 256
+		{name: "SLLconst", argLength: 1, reg: gp11, asm: "SLL", aux: "Int32"}, // arg0 << auxInt, 0 <= auxInt < 32
+		{name: "SRL", argLength: 2, reg: gp21, asm: "SRL"},                    // arg0 >> arg1, unsigned, shift amount is mod 256
+		{name: "SRLconst", argLength: 1, reg: gp11, asm: "SRL", aux: "Int32"}, // arg0 >> auxInt, unsigned, 0 <= auxInt < 32
+		{name: "SRA", argLength: 2, reg: gp21, asm: "SRA"},                    // arg0 >> arg1, signed, shift amount is mod 256
+		{name: "SRAconst", argLength: 1, reg: gp11, asm: "SRA", aux: "Int32"}, // arg0 >> auxInt, signed, 0 <= auxInt < 32
+		{name: "SRR", argLength: 2, reg: gp21},                                // arg0 right rotate by arg1 bits
+		{name: "SRRconst", argLength: 1, reg: gp11, aux: "Int32"},             // arg0 right rotate by auxInt bits, 0 <= auxInt < 32
+
+		// auxInt for all of these satisfy 0 <= auxInt < 32
+		{name: "ADDshiftLL", argLength: 2, reg: gp21, asm: "ADD", aux: "Int32"}, // arg0 + arg1<<auxInt
+		{name: "ADDshiftRL", argLength: 2, reg: gp21, asm: "ADD", aux: "Int32"}, // arg0 + arg1>>auxInt, unsigned shift
+		{name: "ADDshiftRA", argLength: 2, reg: gp21, asm: "ADD", aux: "Int32"}, // arg0 + arg1>>auxInt, signed shift
+		{name: "SUBshiftLL", argLength: 2, reg: gp21, asm: "SUB", aux: "Int32"}, // arg0 - arg1<<auxInt
+		{name: "SUBshiftRL", argLength: 2, reg: gp21, asm: "SUB", aux: "Int32"}, // arg0 - arg1>>auxInt, unsigned shift
+		{name: "SUBshiftRA", argLength: 2, reg: gp21, asm: "SUB", aux: "Int32"}, // arg0 - arg1>>auxInt, signed shift
+		{name: "RSBshiftLL", argLength: 2, reg: gp21, asm: "RSB", aux: "Int32"}, // arg1<<auxInt - arg0
+		{name: "RSBshiftRL", argLength: 2, reg: gp21, asm: "RSB", aux: "Int32"}, // arg1>>auxInt - arg0, unsigned shift
+		{name: "RSBshiftRA", argLength: 2, reg: gp21, asm: "RSB", aux: "Int32"}, // arg1>>auxInt - arg0, signed shift
+		{name: "ANDshiftLL", argLength: 2, reg: gp21, asm: "AND", aux: "Int32"}, // arg0 & (arg1<<auxInt)
+		{name: "ANDshiftRL", argLength: 2, reg: gp21, asm: "AND", aux: "Int32"}, // arg0 & (arg1>>auxInt), unsigned shift
+		{name: "ANDshiftRA", argLength: 2, reg: gp21, asm: "AND", aux: "Int32"}, // arg0 & (arg1>>auxInt), signed shift
+		{name: "ORshiftLL", argLength: 2, reg: gp21, asm: "ORR", aux: "Int32"},  // arg0 | arg1<<auxInt
+		{name: "ORshiftRL", argLength: 2, reg: gp21, asm: "ORR", aux: "Int32"},  // arg0 | arg1>>auxInt, unsigned shift
+		{name: "ORshiftRA", argLength: 2, reg: gp21, asm: "ORR", aux: "Int32"},  // arg0 | arg1>>auxInt, signed shift
+		{name: "XORshiftLL", argLength: 2, reg: gp21, asm: "EOR", aux: "Int32"}, // arg0 ^ arg1<<auxInt
+		{name: "XORshiftRL", argLength: 2, reg: gp21, asm: "EOR", aux: "Int32"}, // arg0 ^ arg1>>auxInt, unsigned shift
+		{name: "XORshiftRA", argLength: 2, reg: gp21, asm: "EOR", aux: "Int32"}, // arg0 ^ arg1>>auxInt, signed shift
+		{name: "XORshiftRR", argLength: 2, reg: gp21, asm: "EOR", aux: "Int32"}, // arg0 ^ (arg1 right rotate by auxInt)
+		{name: "BICshiftLL", argLength: 2, reg: gp21, asm: "BIC", aux: "Int32"}, // arg0 &^ (arg1<<auxInt)
+		{name: "BICshiftRL", argLength: 2, reg: gp21, asm: "BIC", aux: "Int32"}, // arg0 &^ (arg1>>auxInt), unsigned shift
+		{name: "BICshiftRA", argLength: 2, reg: gp21, asm: "BIC", aux: "Int32"}, // arg0 &^ (arg1>>auxInt), signed shift
+		{name: "MVNshiftLL", argLength: 1, reg: gp11, asm: "MVN", aux: "Int32"}, // ^(arg0<<auxInt)
+		{name: "MVNshiftRL", argLength: 1, reg: gp11, asm: "MVN", aux: "Int32"}, // ^(arg0>>auxInt), unsigned shift
+		{name: "MVNshiftRA", argLength: 1, reg: gp11, asm: "MVN", aux: "Int32"}, // ^(arg0>>auxInt), signed shift
+
+		{name: "ADCshiftLL", argLength: 3, reg: gp2flags1, asm: "ADC", aux: "Int32"}, // arg0 + arg1<<auxInt + carry, arg2=flags
+		{name: "ADCshiftRL", argLength: 3, reg: gp2flags1, asm: "ADC", aux: "Int32"}, // arg0 + arg1>>auxInt + carry, unsigned shift, arg2=flags
+		{name: "ADCshiftRA", argLength: 3, reg: gp2flags1, asm: "ADC", aux: "Int32"}, // arg0 + arg1>>auxInt + carry, signed shift, arg2=flags
+		{name: "SBCshiftLL", argLength: 3, reg: gp2flags1, asm: "SBC", aux: "Int32"}, // arg0 - arg1<<auxInt - carry, arg2=flags
+		{name: "SBCshiftRL", argLength: 3, reg: gp2flags1, asm: "SBC", aux: "Int32"}, // arg0 - arg1>>auxInt - carry, unsigned shift, arg2=flags
+		{name: "SBCshiftRA", argLength: 3, reg: gp2flags1, asm: "SBC", aux: "Int32"}, // arg0 - arg1>>auxInt - carry, signed shift, arg2=flags
+		{name: "RSCshiftLL", argLength: 3, reg: gp2flags1, asm: "RSC", aux: "Int32"}, // arg1<<auxInt - arg0 - carry, arg2=flags
+		{name: "RSCshiftRL", argLength: 3, reg: gp2flags1, asm: "RSC", aux: "Int32"}, // arg1>>auxInt - arg0 - carry, unsigned shift, arg2=flags
+		{name: "RSCshiftRA", argLength: 3, reg: gp2flags1, asm: "RSC", aux: "Int32"}, // arg1>>auxInt - arg0 - carry, signed shift, arg2=flags
+
+		{name: "ADDSshiftLL", argLength: 2, reg: gp21carry, asm: "ADD", aux: "Int32"}, // arg0 + arg1<<auxInt, set carry flag
+		{name: "ADDSshiftRL", argLength: 2, reg: gp21carry, asm: "ADD", aux: "Int32"}, // arg0 + arg1>>auxInt, unsigned shift, set carry flag
+		{name: "ADDSshiftRA", argLength: 2, reg: gp21carry, asm: "ADD", aux: "Int32"}, // arg0 + arg1>>auxInt, signed shift, set carry flag
+		{name: "SUBSshiftLL", argLength: 2, reg: gp21carry, asm: "SUB", aux: "Int32"}, // arg0 - arg1<<auxInt, set carry flag
+		{name: "SUBSshiftRL", argLength: 2, reg: gp21carry, asm: "SUB", aux: "Int32"}, // arg0 - arg1>>auxInt, unsigned shift, set carry flag
+		{name: "SUBSshiftRA", argLength: 2, reg: gp21carry, asm: "SUB", aux: "Int32"}, // arg0 - arg1>>auxInt, signed shift, set carry flag
+		{name: "RSBSshiftLL", argLength: 2, reg: gp21carry, asm: "RSB", aux: "Int32"}, // arg1<<auxInt - arg0, set carry flag
+		{name: "RSBSshiftRL", argLength: 2, reg: gp21carry, asm: "RSB", aux: "Int32"}, // arg1>>auxInt - arg0, unsigned shift, set carry flag
+		{name: "RSBSshiftRA", argLength: 2, reg: gp21carry, asm: "RSB", aux: "Int32"}, // arg1>>auxInt - arg0, signed shift, set carry flag
+
+		{name: "ADDshiftLLreg", argLength: 3, reg: gp31, asm: "ADD"}, // arg0 + arg1<<arg2
+		{name: "ADDshiftRLreg", argLength: 3, reg: gp31, asm: "ADD"}, // arg0 + arg1>>arg2, unsigned shift
+		{name: "ADDshiftRAreg", argLength: 3, reg: gp31, asm: "ADD"}, // arg0 + arg1>>arg2, signed shift
+		{name: "SUBshiftLLreg", argLength: 3, reg: gp31, asm: "SUB"}, // arg0 - arg1<<arg2
+		{name: "SUBshiftRLreg", argLength: 3, reg: gp31, asm: "SUB"}, // arg0 - arg1>>arg2, unsigned shift
+		{name: "SUBshiftRAreg", argLength: 3, reg: gp31, asm: "SUB"}, // arg0 - arg1>>arg2, signed shift
+		{name: "RSBshiftLLreg", argLength: 3, reg: gp31, asm: "RSB"}, // arg1<<arg2 - arg0
+		{name: "RSBshiftRLreg", argLength: 3, reg: gp31, asm: "RSB"}, // arg1>>arg2 - arg0, unsigned shift
+		{name: "RSBshiftRAreg", argLength: 3, reg: gp31, asm: "RSB"}, // arg1>>arg2 - arg0, signed shift
+		{name: "ANDshiftLLreg", argLength: 3, reg: gp31, asm: "AND"}, // arg0 & (arg1<<arg2)
+		{name: "ANDshiftRLreg", argLength: 3, reg: gp31, asm: "AND"}, // arg0 & (arg1>>arg2), unsigned shift
+		{name: "ANDshiftRAreg", argLength: 3, reg: gp31, asm: "AND"}, // arg0 & (arg1>>arg2), signed shift
+		{name: "ORshiftLLreg", argLength: 3, reg: gp31, asm: "ORR"},  // arg0 | arg1<<arg2
+		{name: "ORshiftRLreg", argLength: 3, reg: gp31, asm: "ORR"},  // arg0 | arg1>>arg2, unsigned shift
+		{name: "ORshiftRAreg", argLength: 3, reg: gp31, asm: "ORR"},  // arg0 | arg1>>arg2, signed shift
+		{name: "XORshiftLLreg", argLength: 3, reg: gp31, asm: "EOR"}, // arg0 ^ arg1<<arg2
+		{name: "XORshiftRLreg", argLength: 3, reg: gp31, asm: "EOR"}, // arg0 ^ arg1>>arg2, unsigned shift
+		{name: "XORshiftRAreg", argLength: 3, reg: gp31, asm: "EOR"}, // arg0 ^ arg1>>arg2, signed shift
+		{name: "BICshiftLLreg", argLength: 3, reg: gp31, asm: "BIC"}, // arg0 &^ (arg1<<arg2)
+		{name: "BICshiftRLreg", argLength: 3, reg: gp31, asm: "BIC"}, // arg0 &^ (arg1>>arg2), unsigned shift
+		{name: "BICshiftRAreg", argLength: 3, reg: gp31, asm: "BIC"}, // arg0 &^ (arg1>>arg2), signed shift
+		{name: "MVNshiftLLreg", argLength: 2, reg: gp21, asm: "MVN"}, // ^(arg0<<arg1)
+		{name: "MVNshiftRLreg", argLength: 2, reg: gp21, asm: "MVN"}, // ^(arg0>>arg1), unsigned shift
+		{name: "MVNshiftRAreg", argLength: 2, reg: gp21, asm: "MVN"}, // ^(arg0>>arg1), signed shift
+
+		{name: "ADCshiftLLreg", argLength: 4, reg: gp3flags1, asm: "ADC"}, // arg0 + arg1<<arg2 + carry, arg3=flags
+		{name: "ADCshiftRLreg", argLength: 4, reg: gp3flags1, asm: "ADC"}, // arg0 + arg1>>arg2 + carry, unsigned shift, arg3=flags
+		{name: "ADCshiftRAreg", argLength: 4, reg: gp3flags1, asm: "ADC"}, // arg0 + arg1>>arg2 + carry, signed shift, arg3=flags
+		{name: "SBCshiftLLreg", argLength: 4, reg: gp3flags1, asm: "SBC"}, // arg0 - arg1<<arg2 - carry, arg3=flags
+		{name: "SBCshiftRLreg", argLength: 4, reg: gp3flags1, asm: "SBC"}, // arg0 - arg1>>arg2 - carry, unsigned shift, arg3=flags
+		{name: "SBCshiftRAreg", argLength: 4, reg: gp3flags1, asm: "SBC"}, // arg0 - arg1>>arg2 - carry, signed shift, arg3=flags
+		{name: "RSCshiftLLreg", argLength: 4, reg: gp3flags1, asm: "RSC"}, // arg1<<arg2 - arg0 - carry, arg3=flags
+		{name: "RSCshiftRLreg", argLength: 4, reg: gp3flags1, asm: "RSC"}, // arg1>>arg2 - arg0 - carry, unsigned shift, arg3=flags
+		{name: "RSCshiftRAreg", argLength: 4, reg: gp3flags1, asm: "RSC"}, // arg1>>arg2 - arg0 - carry, signed shift, arg3=flags
+
+		{name: "ADDSshiftLLreg", argLength: 3, reg: gp31carry, asm: "ADD"}, // arg0 + arg1<<arg2, set carry flag
+		{name: "ADDSshiftRLreg", argLength: 3, reg: gp31carry, asm: "ADD"}, // arg0 + arg1>>arg2, unsigned shift, set carry flag
+		{name: "ADDSshiftRAreg", argLength: 3, reg: gp31carry, asm: "ADD"}, // arg0 + arg1>>arg2, signed shift, set carry flag
+		{name: "SUBSshiftLLreg", argLength: 3, reg: gp31carry, asm: "SUB"}, // arg0 - arg1<<arg2, set carry flag
+		{name: "SUBSshiftRLreg", argLength: 3, reg: gp31carry, asm: "SUB"}, // arg0 - arg1>>arg2, unsigned shift, set carry flag
+		{name: "SUBSshiftRAreg", argLength: 3, reg: gp31carry, asm: "SUB"}, // arg0 - arg1>>arg2, signed shift, set carry flag
+		{name: "RSBSshiftLLreg", argLength: 3, reg: gp31carry, asm: "RSB"}, // arg1<<arg2 - arg0, set carry flag
+		{name: "RSBSshiftRLreg", argLength: 3, reg: gp31carry, asm: "RSB"}, // arg1>>arg2 - arg0, unsigned shift, set carry flag
+		{name: "RSBSshiftRAreg", argLength: 3, reg: gp31carry, asm: "RSB"}, // arg1>>arg2 - arg0, signed shift, set carry flag
+
+		// comparisons
+		{name: "CMP", argLength: 2, reg: gp2flags, asm: "CMP", typ: "Flags"},                    // arg0 compare to arg1
+		{name: "CMPconst", argLength: 1, reg: gp1flags, asm: "CMP", aux: "Int32", typ: "Flags"}, // arg0 compare to auxInt
+		{name: "CMN", argLength: 2, reg: gp2flags, asm: "CMN", typ: "Flags", commutative: true}, // arg0 compare to -arg1, provided arg1 is not 1<<63
+		{name: "CMNconst", argLength: 1, reg: gp1flags, asm: "CMN", aux: "Int32", typ: "Flags"}, // arg0 compare to -auxInt
+		{name: "TST", argLength: 2, reg: gp2flags, asm: "TST", typ: "Flags", commutative: true}, // arg0 & arg1 compare to 0
+		{name: "TSTconst", argLength: 1, reg: gp1flags, asm: "TST", aux: "Int32", typ: "Flags"}, // arg0 & auxInt compare to 0
+		{name: "TEQ", argLength: 2, reg: gp2flags, asm: "TEQ", typ: "Flags", commutative: true}, // arg0 ^ arg1 compare to 0
+		{name: "TEQconst", argLength: 1, reg: gp1flags, asm: "TEQ", aux: "Int32", typ: "Flags"}, // arg0 ^ auxInt compare to 0
+		{name: "CMPF", argLength: 2, reg: fp2flags, asm: "CMPF", typ: "Flags"},                  // arg0 compare to arg1, float32
+		{name: "CMPD", argLength: 2, reg: fp2flags, asm: "CMPD", typ: "Flags"},                  // arg0 compare to arg1, float64
+
+		{name: "CMPshiftLL", argLength: 2, reg: gp2flags, asm: "CMP", aux: "Int32", typ: "Flags"}, // arg0 compare to arg1<<auxInt
+		{name: "CMPshiftRL", argLength: 2, reg: gp2flags, asm: "CMP", aux: "Int32", typ: "Flags"}, // arg0 compare to arg1>>auxInt, unsigned shift
+		{name: "CMPshiftRA", argLength: 2, reg: gp2flags, asm: "CMP", aux: "Int32", typ: "Flags"}, // arg0 compare to arg1>>auxInt, signed shift
+		{name: "CMNshiftLL", argLength: 2, reg: gp2flags, asm: "CMN", aux: "Int32", typ: "Flags"}, // arg0 compare to -(arg1<<auxInt)
+		{name: "CMNshiftRL", argLength: 2, reg: gp2flags, asm: "CMN", aux: "Int32", typ: "Flags"}, // arg0 compare to -(arg1>>auxInt), unsigned shift
+		{name: "CMNshiftRA", argLength: 2, reg: gp2flags, asm: "CMN", aux: "Int32", typ: "Flags"}, // arg0 compare to -(arg1>>auxInt), signed shift
+		{name: "TSTshiftLL", argLength: 2, reg: gp2flags, asm: "TST", aux: "Int32", typ: "Flags"}, // arg0 & (arg1<<auxInt) compare to 0
+		{name: "TSTshiftRL", argLength: 2, reg: gp2flags, asm: "TST", aux: "Int32", typ: "Flags"}, // arg0 & (arg1>>auxInt) compare to 0, unsigned shift
+		{name: "TSTshiftRA", argLength: 2, reg: gp2flags, asm: "TST", aux: "Int32", typ: "Flags"}, // arg0 & (arg1>>auxInt) compare to 0, signed shift
+		{name: "TEQshiftLL", argLength: 2, reg: gp2flags, asm: "TEQ", aux: "Int32", typ: "Flags"}, // arg0 ^ (arg1<<auxInt) compare to 0
+		{name: "TEQshiftRL", argLength: 2, reg: gp2flags, asm: "TEQ", aux: "Int32", typ: "Flags"}, // arg0 ^ (arg1>>auxInt) compare to 0, unsigned shift
+		{name: "TEQshiftRA", argLength: 2, reg: gp2flags, asm: "TEQ", aux: "Int32", typ: "Flags"}, // arg0 ^ (arg1>>auxInt) compare to 0, signed shift
+
+		{name: "CMPshiftLLreg", argLength: 3, reg: gp3flags, asm: "CMP", typ: "Flags"}, // arg0 compare to arg1<<arg2
+		{name: "CMPshiftRLreg", argLength: 3, reg: gp3flags, asm: "CMP", typ: "Flags"}, // arg0 compare to arg1>>arg2, unsigned shift
+		{name: "CMPshiftRAreg", argLength: 3, reg: gp3flags, asm: "CMP", typ: "Flags"}, // arg0 compare to arg1>>arg2, signed shift
+		{name: "CMNshiftLLreg", argLength: 3, reg: gp3flags, asm: "CMN", typ: "Flags"}, // arg0 + (arg1<<arg2) compare to 0
+		{name: "CMNshiftRLreg", argLength: 3, reg: gp3flags, asm: "CMN", typ: "Flags"}, // arg0 + (arg1>>arg2) compare to 0, unsigned shift
+		{name: "CMNshiftRAreg", argLength: 3, reg: gp3flags, asm: "CMN", typ: "Flags"}, // arg0 + (arg1>>arg2) compare to 0, signed shift
+		{name: "TSTshiftLLreg", argLength: 3, reg: gp3flags, asm: "TST", typ: "Flags"}, // arg0 & (arg1<<arg2) compare to 0
+		{name: "TSTshiftRLreg", argLength: 3, reg: gp3flags, asm: "TST", typ: "Flags"}, // arg0 & (arg1>>arg2) compare to 0, unsigned shift
+		{name: "TSTshiftRAreg", argLength: 3, reg: gp3flags, asm: "TST", typ: "Flags"}, // arg0 & (arg1>>arg2) compare to 0, signed shift
+		{name: "TEQshiftLLreg", argLength: 3, reg: gp3flags, asm: "TEQ", typ: "Flags"}, // arg0 ^ (arg1<<arg2) compare to 0
+		{name: "TEQshiftRLreg", argLength: 3, reg: gp3flags, asm: "TEQ", typ: "Flags"}, // arg0 ^ (arg1>>arg2) compare to 0, unsigned shift
+		{name: "TEQshiftRAreg", argLength: 3, reg: gp3flags, asm: "TEQ", typ: "Flags"}, // arg0 ^ (arg1>>arg2) compare to 0, signed shift
+
+		{name: "CMPF0", argLength: 1, reg: fp1flags, asm: "CMPF", typ: "Flags"}, // arg0 compare to 0, float32
+		{name: "CMPD0", argLength: 1, reg: fp1flags, asm: "CMPD", typ: "Flags"}, // arg0 compare to 0, float64
+
+		// moves
+		{name: "MOVWconst", argLength: 0, reg: gp01, aux: "Int32", asm: "MOVW", typ: "UInt32", rematerializeable: true},    // 32 low bits of auxint
+		{name: "MOVFconst", argLength: 0, reg: fp01, aux: "Float64", asm: "MOVF", typ: "Float32", rematerializeable: true}, // auxint as 64-bit float, convert to 32-bit float
+		{name: "MOVDconst", argLength: 0, reg: fp01, aux: "Float64", asm: "MOVD", typ: "Float64", rematerializeable: true}, // auxint as 64-bit float
+
+		{name: "MOVWaddr", argLength: 1, reg: regInfo{inputs: []regMask{buildReg("SP") | buildReg("SB")}, outputs: []regMask{gp}}, aux: "SymOff", asm: "MOVW", rematerializeable: true, symEffect: "Addr"}, // arg0 + auxInt + aux.(*gc.Sym), arg0=SP/SB
+
+		{name: "MOVBload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVB", typ: "Int8", faultOnNilArg0: true, symEffect: "Read"},     // load from arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVBUload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVBU", typ: "UInt8", faultOnNilArg0: true, symEffect: "Read"},  // load from arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVHload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVH", typ: "Int16", faultOnNilArg0: true, symEffect: "Read"},    // load from arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVHUload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVHU", typ: "UInt16", faultOnNilArg0: true, symEffect: "Read"}, // load from arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVWload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVW", typ: "UInt32", faultOnNilArg0: true, symEffect: "Read"},   // load from arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVFload", argLength: 2, reg: fpload, aux: "SymOff", asm: "MOVF", typ: "Float32", faultOnNilArg0: true, symEffect: "Read"},  // load from arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVDload", argLength: 2, reg: fpload, aux: "SymOff", asm: "MOVD", typ: "Float64", faultOnNilArg0: true, symEffect: "Read"},  // load from arg0 + auxInt + aux.  arg1=mem.
+
+		{name: "MOVBstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVB", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 1 byte of arg1 to arg0 + auxInt + aux.  arg2=mem.
+		{name: "MOVHstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVH", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 2 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
+		{name: "MOVWstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVW", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
+		{name: "MOVFstore", argLength: 3, reg: fpstore, aux: "SymOff", asm: "MOVF", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
+		{name: "MOVDstore", argLength: 3, reg: fpstore, aux: "SymOff", asm: "MOVD", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
+
+		{name: "MOVWloadidx", argLength: 3, reg: gp2load, asm: "MOVW", typ: "UInt32"},                   // load from arg0 + arg1. arg2=mem
+		{name: "MOVWloadshiftLL", argLength: 3, reg: gp2load, asm: "MOVW", aux: "Int32", typ: "UInt32"}, // load from arg0 + arg1<<auxInt. arg2=mem
+		{name: "MOVWloadshiftRL", argLength: 3, reg: gp2load, asm: "MOVW", aux: "Int32", typ: "UInt32"}, // load from arg0 + arg1>>auxInt, unsigned shift. arg2=mem
+		{name: "MOVWloadshiftRA", argLength: 3, reg: gp2load, asm: "MOVW", aux: "Int32", typ: "UInt32"}, // load from arg0 + arg1>>auxInt, signed shift. arg2=mem
+		{name: "MOVBUloadidx", argLength: 3, reg: gp2load, asm: "MOVBU", typ: "UInt8"},                  // load from arg0 + arg1. arg2=mem
+		{name: "MOVBloadidx", argLength: 3, reg: gp2load, asm: "MOVB", typ: "Int8"},                     // load from arg0 + arg1. arg2=mem
+		{name: "MOVHUloadidx", argLength: 3, reg: gp2load, asm: "MOVHU", typ: "UInt16"},                 // load from arg0 + arg1. arg2=mem
+		{name: "MOVHloadidx", argLength: 3, reg: gp2load, asm: "MOVH", typ: "Int16"},                    // load from arg0 + arg1. arg2=mem
+
+		{name: "MOVWstoreidx", argLength: 4, reg: gp2store, asm: "MOVW", typ: "Mem"},                   // store arg2 to arg0 + arg1. arg3=mem
+		{name: "MOVWstoreshiftLL", argLength: 4, reg: gp2store, asm: "MOVW", aux: "Int32", typ: "Mem"}, // store arg2 to arg0 + arg1<<auxInt. arg3=mem
+		{name: "MOVWstoreshiftRL", argLength: 4, reg: gp2store, asm: "MOVW", aux: "Int32", typ: "Mem"}, // store arg2 to arg0 + arg1>>auxInt, unsigned shift. arg3=mem
+		{name: "MOVWstoreshiftRA", argLength: 4, reg: gp2store, asm: "MOVW", aux: "Int32", typ: "Mem"}, // store arg2 to arg0 + arg1>>auxInt, signed shift. arg3=mem
+		{name: "MOVBstoreidx", argLength: 4, reg: gp2store, asm: "MOVB", typ: "Mem"},                   // store arg2 to arg0 + arg1. arg3=mem
+		{name: "MOVHstoreidx", argLength: 4, reg: gp2store, asm: "MOVH", typ: "Mem"},                   // store arg2 to arg0 + arg1. arg3=mem
+
+		{name: "MOVBreg", argLength: 1, reg: gp11, asm: "MOVBS"},  // move from arg0, sign-extended from byte
+		{name: "MOVBUreg", argLength: 1, reg: gp11, asm: "MOVBU"}, // move from arg0, unsign-extended from byte
+		{name: "MOVHreg", argLength: 1, reg: gp11, asm: "MOVHS"},  // move from arg0, sign-extended from half
+		{name: "MOVHUreg", argLength: 1, reg: gp11, asm: "MOVHU"}, // move from arg0, unsign-extended from half
+		{name: "MOVWreg", argLength: 1, reg: gp11, asm: "MOVW"},   // move from arg0
+
+		{name: "MOVWnop", argLength: 1, reg: regInfo{inputs: []regMask{gp}, outputs: []regMask{gp}}, resultInArg0: true}, // nop, return arg0 in same register
+
+		{name: "MOVWF", argLength: 1, reg: gpfp, asm: "MOVWF"},  // int32 -> float32
+		{name: "MOVWD", argLength: 1, reg: gpfp, asm: "MOVWD"},  // int32 -> float64
+		{name: "MOVWUF", argLength: 1, reg: gpfp, asm: "MOVWF"}, // uint32 -> float32, set U bit in the instruction
+		{name: "MOVWUD", argLength: 1, reg: gpfp, asm: "MOVWD"}, // uint32 -> float64, set U bit in the instruction
+		{name: "MOVFW", argLength: 1, reg: fpgp, asm: "MOVFW"},  // float32 -> int32
+		{name: "MOVDW", argLength: 1, reg: fpgp, asm: "MOVDW"},  // float64 -> int32
+		{name: "MOVFWU", argLength: 1, reg: fpgp, asm: "MOVFW"}, // float32 -> uint32, set U bit in the instruction
+		{name: "MOVDWU", argLength: 1, reg: fpgp, asm: "MOVDW"}, // float64 -> uint32, set U bit in the instruction
+		{name: "MOVFD", argLength: 1, reg: fp11, asm: "MOVFD"},  // float32 -> float64
+		{name: "MOVDF", argLength: 1, reg: fp11, asm: "MOVDF"},  // float64 -> float32
+
+		// conditional instructions, for lowering shifts
+		{name: "CMOVWHSconst", argLength: 2, reg: gp1flags1, asm: "MOVW", aux: "Int32", resultInArg0: true}, // replace arg0 w/ const if flags indicates HS, arg1=flags
+		{name: "CMOVWLSconst", argLength: 2, reg: gp1flags1, asm: "MOVW", aux: "Int32", resultInArg0: true}, // replace arg0 w/ const if flags indicates LS, arg1=flags
+		{name: "SRAcond", argLength: 3, reg: gp2flags1, asm: "SRA"},                                         // arg0 >> 31 if flags indicates HS, arg0 >> arg1 otherwise, signed shift, arg2=flags
+
+		// function calls
+		{name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                                              // call static function aux.(*obj.LSym).  arg0=mem, auxint=argsize, returns mem
+		{name: "CALLtail", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true, tailCall: true},                                // tail call static function aux.(*obj.LSym).  arg0=mem, auxint=argsize, returns mem
+		{name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{gpsp, buildReg("R7"), 0}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call function via closure.  arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem
+		{name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                        // call fn by pointer.  arg0=codeptr, arg1=mem, auxint=argsize, returns mem
+
+		// pseudo-ops
+		{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpg}}, nilCheck: true, faultOnNilArg0: true}, // panic if arg0 is nil.  arg1=mem.
+
+		{name: "Equal", argLength: 1, reg: readflags},         // bool, true flags encode x==y false otherwise.
+		{name: "NotEqual", argLength: 1, reg: readflags},      // bool, true flags encode x!=y false otherwise.
+		{name: "LessThan", argLength: 1, reg: readflags},      // bool, true flags encode signed x<y false otherwise.
+		{name: "LessEqual", argLength: 1, reg: readflags},     // bool, true flags encode signed x<=y false otherwise.
+		{name: "GreaterThan", argLength: 1, reg: readflags},   // bool, true flags encode signed x>y false otherwise.
+		{name: "GreaterEqual", argLength: 1, reg: readflags},  // bool, true flags encode signed x>=y false otherwise.
+		{name: "LessThanU", argLength: 1, reg: readflags},     // bool, true flags encode unsigned x<y false otherwise.
+		{name: "LessEqualU", argLength: 1, reg: readflags},    // bool, true flags encode unsigned x<=y false otherwise.
+		{name: "GreaterThanU", argLength: 1, reg: readflags},  // bool, true flags encode unsigned x>y false otherwise.
+		{name: "GreaterEqualU", argLength: 1, reg: readflags}, // bool, true flags encode unsigned x>=y false otherwise.
+
+		// duffzero (must be 4-byte aligned)
+		// arg0 = address of memory to zero (in R1, changed as side effect)
+		// arg1 = value to store (always zero)
+		// arg2 = mem
+		// auxint = offset into duffzero code to start executing
+		// returns mem
+		{
+			name:      "DUFFZERO",
+			aux:       "Int64",
+			argLength: 3,
+			reg: regInfo{
+				inputs:   []regMask{buildReg("R1"), buildReg("R0")},
+				clobbers: buildReg("R1 R12 R14"), // R14 is LR, R12 is linker trampoline scratch register
+			},
+			faultOnNilArg0: true,
+		},
+
+		// duffcopy (must be 4-byte aligned)
+		// arg0 = address of dst memory (in R2, changed as side effect)
+		// arg1 = address of src memory (in R1, changed as side effect)
+		// arg2 = mem
+		// auxint = offset into duffcopy code to start executing
+		// returns mem
+		{
+			name:      "DUFFCOPY",
+			aux:       "Int64",
+			argLength: 3,
+			reg: regInfo{
+				inputs:   []regMask{buildReg("R2"), buildReg("R1")},
+				clobbers: buildReg("R0 R1 R2 R12 R14"), // R14 is LR, R12 is linker trampoline scratch register
+			},
+			faultOnNilArg0: true,
+			faultOnNilArg1: true,
+		},
+
+		// large or unaligned zeroing
+		// arg0 = address of memory to zero (in R1, changed as side effect)
+		// arg1 = address of the last element to zero
+		// arg2 = value to store (always zero)
+		// arg3 = mem
+		// returns mem
+		//	MOVW.P	Rarg2, 4(R1)
+		//	CMP	R1, Rarg1
+		//	BLE	-2(PC)
+		{
+			name:      "LoweredZero",
+			aux:       "Int64",
+			argLength: 4,
+			reg: regInfo{
+				inputs:   []regMask{buildReg("R1"), gp, gp},
+				clobbers: buildReg("R1"),
+			},
+			clobberFlags:   true,
+			faultOnNilArg0: true,
+		},
+
+		// large or unaligned move
+		// arg0 = address of dst memory (in R2, changed as side effect)
+		// arg1 = address of src memory (in R1, changed as side effect)
+		// arg2 = address of the last element of src
+		// arg3 = mem
+		// returns mem
+		//	MOVW.P	4(R1), Rtmp
+		//	MOVW.P	Rtmp, 4(R2)
+		//	CMP	R1, Rarg2
+		//	BLE	-3(PC)
+		{
+			name:      "LoweredMove",
+			aux:       "Int64",
+			argLength: 4,
+			reg: regInfo{
+				inputs:   []regMask{buildReg("R2"), buildReg("R1"), gp},
+				clobbers: buildReg("R1 R2"),
+			},
+			clobberFlags:   true,
+			faultOnNilArg0: true,
+			faultOnNilArg1: true,
+		},
+
+		// Scheduler ensures LoweredGetClosurePtr occurs only in entry block,
+		// and sorts it to the very beginning of the block to prevent other
+		// use of R7 (arm.REGCTXT, the closure pointer)
+		{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R7")}}, zeroWidth: true},
+
+		// LoweredGetCallerSP returns the SP of the caller of the current function.
+		{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
+
+		// LoweredGetCallerPC evaluates to the PC to which its "caller" will return.
+		// I.e., if f calls g "calls" getcallerpc,
+		// the result should be the PC within f that g will return to.
+		// See runtime/stubs.go for a more detailed discussion.
+		{name: "LoweredGetCallerPC", reg: gp01, rematerializeable: true},
+
+		// There are three of these functions so that they can have three different register inputs.
+		// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the
+		// default registers to match so we don't need to copy registers around unnecessarily.
+		{name: "LoweredPanicBoundsA", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r2, r3}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
+		{name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r1, r2}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
+		{name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r0, r1}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
+		// Extend ops are the same as Bounds ops except the indexes are 64-bit.
+		{name: "LoweredPanicExtendA", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{r4, r2, r3}}, typ: "Mem", call: true}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
+		{name: "LoweredPanicExtendB", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{r4, r1, r2}}, typ: "Mem", call: true}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
+		{name: "LoweredPanicExtendC", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{r4, r0, r1}}, typ: "Mem", call: true}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
+
+		// Constant flag value.
+		// Note: there's an "unordered" outcome for floating-point
+		// comparisons, but we don't use such a beast yet.
+		// This op is for temporary use by rewrite rules. It
+		// cannot appear in the generated assembly.
+		{name: "FlagConstant", aux: "FlagConstant"},
+
+		// (InvertFlags (CMP a b)) == (CMP b a)
+		// InvertFlags is a pseudo-op which can't appear in assembly output.
+		{name: "InvertFlags", argLength: 1}, // reverse direction of arg0
+
+		// LoweredWB invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
+		// It saves all GP registers if necessary,
+		// but clobbers R14 (LR) because it's a call, and R12 which is linker trampoline scratch register.
+		{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R2"), buildReg("R3")}, clobbers: (callerSave &^ gpg) | buildReg("R12 R14")}, clobberFlags: true, aux: "Sym", symEffect: "None"},
+	}
+
+	blocks := []blockData{
+		{name: "EQ", controls: 1},
+		{name: "NE", controls: 1},
+		{name: "LT", controls: 1},
+		{name: "LE", controls: 1},
+		{name: "GT", controls: 1},
+		{name: "GE", controls: 1},
+		{name: "ULT", controls: 1},
+		{name: "ULE", controls: 1},
+		{name: "UGT", controls: 1},
+		{name: "UGE", controls: 1},
+		{name: "LTnoov", controls: 1}, // 'LT' but without honoring overflow
+		{name: "LEnoov", controls: 1}, // 'LE' but without honoring overflow
+		{name: "GTnoov", controls: 1}, // 'GT' but without honoring overflow
+		{name: "GEnoov", controls: 1}, // 'GE' but without honoring overflow
+	}
+
+	archs = append(archs, arch{
+		name:            "ARM",
+		pkg:             "cmd/internal/obj/arm",
+		genfile:         "../../arm/ssa.go",
+		ops:             ops,
+		blocks:          blocks,
+		regnames:        regNamesARM,
+		gpregmask:       gp,
+		fpregmask:       fp,
+		framepointerreg: -1, // not used
+		linkreg:         int8(num["R14"]),
+	})
+}
diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64.rules b/src/cmd/compile/internal/ssa/_gen/LOONG64.rules
new file mode 100644
index 0000000..1caaf13
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/_gen/LOONG64.rules
@@ -0,0 +1,694 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+(Add(Ptr|64|32|16|8) ...) => (ADDV ...)
+(Add(32|64)F ...) => (ADD(F|D) ...)
+
+(Sub(Ptr|64|32|16|8) ...) => (SUBV ...)
+(Sub(32|64)F ...) => (SUB(F|D) ...)
+
+(Mul(64|32|16|8) x y) => (Select1 (MULVU x y))
+(Mul(32|64)F ...) => (MUL(F|D) ...)
+(Mul64uhilo ...) => (MULVU ...)
+(Select0 (Mul64uover x y)) => (Select1 <typ.UInt64> (MULVU x y))
+(Select1 (Mul64uover x y)) => (SGTU <typ.Bool> (Select0 <typ.UInt64> (MULVU x y)) (MOVVconst <typ.UInt64> [0]))
+
+(Hmul64 x y) => (Select0 (MULV x y))
+(Hmul64u x y) => (Select0 (MULVU x y))
+(Hmul32 x y) => (SRAVconst (Select1 <typ.Int64> (MULV (SignExt32to64 x) (SignExt32to64 y))) [32])
+(Hmul32u x y) => (SRLVconst (Select1 <typ.UInt64> (MULVU (ZeroExt32to64 x) (ZeroExt32to64 y))) [32])
+
+(Div64 x y) => (Select1 (DIVV x y))
+(Div64u x y) => (Select1 (DIVVU x y))
+(Div32 x y) => (Select1 (DIVV (SignExt32to64 x) (SignExt32to64 y)))
+(Div32u x y) => (Select1 (DIVVU (ZeroExt32to64 x) (ZeroExt32to64 y)))
+(Div16 x y) => (Select1 (DIVV (SignExt16to64 x) (SignExt16to64 y)))
+(Div16u x y) => (Select1 (DIVVU (ZeroExt16to64 x) (ZeroExt16to64 y)))
+(Div8 x y) => (Select1 (DIVV (SignExt8to64 x) (SignExt8to64 y)))
+(Div8u x y) => (Select1 (DIVVU (ZeroExt8to64 x) (ZeroExt8to64 y)))
+(Div(32|64)F ...) => (DIV(F|D) ...)
+
+(Mod64 x y) => (Select0 (DIVV x y))
+(Mod64u x y) => (Select0 (DIVVU x y))
+(Mod32 x y) => (Select0 (DIVV (SignExt32to64 x) (SignExt32to64 y)))
+(Mod32u x y) => (Select0 (DIVVU (ZeroExt32to64 x) (ZeroExt32to64 y)))
+(Mod16 x y) => (Select0 (DIVV (SignExt16to64 x) (SignExt16to64 y)))
+(Mod16u x y) => (Select0 (DIVVU (ZeroExt16to64 x) (ZeroExt16to64 y)))
+(Mod8 x y) => (Select0 (DIVV (SignExt8to64 x) (SignExt8to64 y)))
+(Mod8u x y) => (Select0 (DIVVU (ZeroExt8to64 x) (ZeroExt8to64 y)))
+
+(Select0 <t> (Add64carry x y c)) => (ADDV (ADDV <t> x y) c)
+(Select1 <t> (Add64carry x y c)) =>
+	(OR (SGTU <t> x s:(ADDV <t> x y)) (SGTU <t> s (ADDV <t> s c)))
+
+(Select0 <t> (Sub64borrow x y c)) => (SUBV (SUBV <t> x y) c)
+(Select1 <t> (Sub64borrow x y c)) =>
+	(OR (SGTU <t> s:(SUBV <t> x y) x) (SGTU <t> (SUBV <t> s c) s))
+
+// (x + y) / 2 with x>=y => (x - y) / 2 + y
+(Avg64u <t> x y) => (ADDV (SRLVconst <t> (SUBV <t> x y) [1]) y)
+
+(And(64|32|16|8) ...) => (AND ...)
+(Or(64|32|16|8) ...) => (OR ...)
+(Xor(64|32|16|8) ...) => (XOR ...)
+
+// shifts
+// hardware instruction uses only the low 6 bits of the shift
+// we compare to 64 to ensure Go semantics for large shifts
+(Lsh64x64 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SLLV <t> x y))
+(Lsh64x32 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SLLV <t> x (ZeroExt32to64 y)))
+(Lsh64x16 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SLLV <t> x (ZeroExt16to64 y)))
+(Lsh64x8  <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SLLV <t> x (ZeroExt8to64  y)))
+
+(Lsh32x64 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SLLV <t> x y))
+(Lsh32x32 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SLLV <t> x (ZeroExt32to64 y)))
+(Lsh32x16 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SLLV <t> x (ZeroExt16to64 y)))
+(Lsh32x8  <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SLLV <t> x (ZeroExt8to64  y)))
+
+(Lsh16x64 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SLLV <t> x y))
+(Lsh16x32 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SLLV <t> x (ZeroExt32to64 y)))
+(Lsh16x16 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SLLV <t> x (ZeroExt16to64 y)))
+(Lsh16x8  <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SLLV <t> x (ZeroExt8to64  y)))
+
+(Lsh8x64 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SLLV <t> x y))
+(Lsh8x32 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SLLV <t> x (ZeroExt32to64 y)))
+(Lsh8x16 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SLLV <t> x (ZeroExt16to64 y)))
+(Lsh8x8  <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SLLV <t> x (ZeroExt8to64  y)))
+
+(Rsh64Ux64 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SRLV <t> x y))
+(Rsh64Ux32 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SRLV <t> x (ZeroExt32to64 y)))
+(Rsh64Ux16 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SRLV <t> x (ZeroExt16to64 y)))
+(Rsh64Ux8  <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SRLV <t> x (ZeroExt8to64  y)))
+
+(Rsh32Ux64 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SRLV <t> (ZeroExt32to64 x) y))
+(Rsh32Ux32 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SRLV <t> (ZeroExt32to64 x) (ZeroExt32to64 y)))
+(Rsh32Ux16 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SRLV <t> (ZeroExt32to64 x) (ZeroExt16to64 y)))
+(Rsh32Ux8  <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SRLV <t> (ZeroExt32to64 x) (ZeroExt8to64  y)))
+
+(Rsh16Ux64 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SRLV <t> (ZeroExt16to64 x) y))
+(Rsh16Ux32 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SRLV <t> (ZeroExt16to64 x) (ZeroExt32to64 y)))
+(Rsh16Ux16 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SRLV <t> (ZeroExt16to64 x) (ZeroExt16to64 y)))
+(Rsh16Ux8  <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SRLV <t> (ZeroExt16to64 x) (ZeroExt8to64  y)))
+
+(Rsh8Ux64 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SRLV <t> (ZeroExt8to64 x) y))
+(Rsh8Ux32 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SRLV <t> (ZeroExt8to64 x) (ZeroExt32to64 y)))
+(Rsh8Ux16 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SRLV <t> (ZeroExt8to64 x) (ZeroExt16to64 y)))
+(Rsh8Ux8  <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SRLV <t> (ZeroExt8to64 x) (ZeroExt8to64  y)))
+
+(Rsh64x64 <t> x y) => (SRAV x (OR <t> (NEGV <t> (SGTU y (MOVVconst <typ.UInt64> [63]))) y))
+(Rsh64x32 <t> x y) => (SRAV x (OR <t> (NEGV <t> (SGTU (ZeroExt32to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt32to64 y)))
+(Rsh64x16 <t> x y) => (SRAV x (OR <t> (NEGV <t> (SGTU (ZeroExt16to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt16to64 y)))
+(Rsh64x8  <t> x y) => (SRAV x (OR <t> (NEGV <t> (SGTU (ZeroExt8to64  y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt8to64  y)))
+
+(Rsh32x64 <t> x y) => (SRAV (SignExt32to64 x) (OR <t> (NEGV <t> (SGTU y (MOVVconst <typ.UInt64> [63]))) y))
+(Rsh32x32 <t> x y) => (SRAV (SignExt32to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt32to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt32to64 y)))
+(Rsh32x16 <t> x y) => (SRAV (SignExt32to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt16to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt16to64 y)))
+(Rsh32x8  <t> x y) => (SRAV (SignExt32to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt8to64  y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt8to64  y)))
+
+(Rsh16x64 <t> x y) => (SRAV (SignExt16to64 x) (OR <t> (NEGV <t> (SGTU y (MOVVconst <typ.UInt64> [63]))) y))
+(Rsh16x32 <t> x y) => (SRAV (SignExt16to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt32to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt32to64 y)))
+(Rsh16x16 <t> x y) => (SRAV (SignExt16to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt16to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt16to64 y)))
+(Rsh16x8  <t> x y) => (SRAV (SignExt16to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt8to64  y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt8to64  y)))
+
+(Rsh8x64 <t> x y) => (SRAV (SignExt8to64 x) (OR <t> (NEGV <t> (SGTU y (MOVVconst <typ.UInt64> [63]))) y))
+(Rsh8x32 <t> x y) => (SRAV (SignExt8to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt32to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt32to64 y)))
+(Rsh8x16 <t> x y) => (SRAV (SignExt8to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt16to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt16to64 y)))
+(Rsh8x8  <t> x y) => (SRAV (SignExt8to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt8to64  y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt8to64  y)))
+
+// rotates
+(RotateLeft8 <t> x (MOVVconst [c])) => (Or8 (Lsh8x64 <t> x (MOVVconst [c&7])) (Rsh8Ux64 <t> x (MOVVconst [-c&7])))
+(RotateLeft16 <t> x (MOVVconst [c])) => (Or16 (Lsh16x64 <t> x (MOVVconst [c&15])) (Rsh16Ux64 <t> x (MOVVconst [-c&15])))
+(RotateLeft32 x y) => (ROTR  x (NEGV <y.Type> y))
+(RotateLeft64 x y) => (ROTRV x (NEGV <y.Type> y))
+
+// unary ops
+(Neg(64|32|16|8) ...) => (NEGV ...)
+(Neg(32|64)F ...) => (NEG(F|D) ...)
+
+(Com(64|32|16|8) x) => (NOR (MOVVconst [0]) x)
+
+(Sqrt ...) => (SQRTD ...)
+(Sqrt32 ...) => (SQRTF ...)
+
+// boolean ops -- booleans are represented with 0=false, 1=true
+(AndB ...) => (AND ...)
+(OrB ...) => (OR ...)
+(EqB x y) => (XOR (MOVVconst [1]) (XOR <typ.Bool> x y))
+(NeqB ...) => (XOR ...)
+(Not x) => (XORconst [1] x)
+
+// constants
+(Const(64|32|16|8) [val]) => (MOVVconst [int64(val)])
+(Const(32|64)F [val]) => (MOV(F|D)const [float64(val)])
+(ConstNil) => (MOVVconst [0])
+(ConstBool [t]) => (MOVVconst [int64(b2i(t))])
+
+(Slicemask <t> x) => (SRAVconst (NEGV <t> x) [63])
+
+// truncations
+// Because we ignore high parts of registers, truncates are just copies.
+(Trunc16to8 ...) => (Copy ...)
+(Trunc32to8 ...) => (Copy ...)
+(Trunc32to16 ...) => (Copy ...)
+(Trunc64to8 ...) => (Copy ...)
+(Trunc64to16 ...) => (Copy ...)
+(Trunc64to32 ...) => (Copy ...)
+
+// Zero-/Sign-extensions
+(ZeroExt8to16 ...) => (MOVBUreg ...)
+(ZeroExt8to32 ...) => (MOVBUreg ...)
+(ZeroExt16to32 ...) => (MOVHUreg ...)
+(ZeroExt8to64 ...) => (MOVBUreg ...)
+(ZeroExt16to64 ...) => (MOVHUreg ...)
+(ZeroExt32to64 ...) => (MOVWUreg ...)
+
+(SignExt8to16 ...) => (MOVBreg ...)
+(SignExt8to32 ...) => (MOVBreg ...)
+(SignExt16to32 ...) => (MOVHreg ...)
+(SignExt8to64 ...) => (MOVBreg ...)
+(SignExt16to64 ...) => (MOVHreg ...)
+(SignExt32to64 ...) => (MOVWreg ...)
+
+// float <=> int conversion
+(Cvt32to32F ...) => (MOVWF ...)
+(Cvt32to64F ...) => (MOVWD ...)
+(Cvt64to32F ...) => (MOVVF ...)
+(Cvt64to64F ...) => (MOVVD ...)
+(Cvt32Fto32 ...) => (TRUNCFW ...)
+(Cvt64Fto32 ...) => (TRUNCDW ...)
+(Cvt32Fto64 ...) => (TRUNCFV ...)
+(Cvt64Fto64 ...) => (TRUNCDV ...)
+(Cvt32Fto64F ...) => (MOVFD ...)
+(Cvt64Fto32F ...) => (MOVDF ...)
+
+(CvtBoolToUint8 ...) => (Copy ...)
+
+(Round(32|64)F ...) => (Copy ...)
+
+// comparisons
+(Eq8 x y)  => (SGTU (MOVVconst [1]) (XOR (ZeroExt8to64 x) (ZeroExt8to64 y)))
+(Eq16 x y) => (SGTU (MOVVconst [1]) (XOR (ZeroExt16to64 x) (ZeroExt16to64 y)))
+(Eq32 x y) => (SGTU (MOVVconst [1]) (XOR (ZeroExt32to64 x) (ZeroExt32to64 y)))
+(Eq64 x y) => (SGTU (MOVVconst [1]) (XOR x y))
+(EqPtr x y) => (SGTU (MOVVconst [1]) (XOR x y))
+(Eq(32|64)F x y) => (FPFlagTrue (CMPEQ(F|D) x y))
+
+(Neq8 x y)  => (SGTU (XOR (ZeroExt8to64 x) (ZeroExt8to64 y)) (MOVVconst [0]))
+(Neq16 x y) => (SGTU (XOR (ZeroExt16to32 x) (ZeroExt16to64 y)) (MOVVconst [0]))
+(Neq32 x y) => (SGTU (XOR (ZeroExt32to64 x) (ZeroExt32to64 y)) (MOVVconst [0]))
+(Neq64 x y) => (SGTU (XOR x y) (MOVVconst [0]))
+(NeqPtr x y) => (SGTU (XOR x y) (MOVVconst [0]))
+(Neq(32|64)F x y) => (FPFlagFalse (CMPEQ(F|D) x y))
+
+(Less8 x y)  => (SGT (SignExt8to64 y) (SignExt8to64 x))
+(Less16 x y) => (SGT (SignExt16to64 y) (SignExt16to64 x))
+(Less32 x y) => (SGT (SignExt32to64 y) (SignExt32to64 x))
+(Less64 x y) => (SGT y x)
+(Less(32|64)F x y) => (FPFlagTrue (CMPGT(F|D) y x)) // reverse operands to work around NaN
+
+(Less8U x y)  => (SGTU (ZeroExt8to64 y) (ZeroExt8to64 x))
+(Less16U x y) => (SGTU (ZeroExt16to64 y) (ZeroExt16to64 x))
+(Less32U x y) => (SGTU (ZeroExt32to64 y) (ZeroExt32to64 x))
+(Less64U x y) => (SGTU y x)
+
+(Leq8 x y)  => (XOR (MOVVconst [1]) (SGT (SignExt8to64 x) (SignExt8to64 y)))
+(Leq16 x y) => (XOR (MOVVconst [1]) (SGT (SignExt16to64 x) (SignExt16to64 y)))
+(Leq32 x y) => (XOR (MOVVconst [1]) (SGT (SignExt32to64 x) (SignExt32to64 y)))
+(Leq64 x y) => (XOR (MOVVconst [1]) (SGT x y))
+(Leq(32|64)F x y) => (FPFlagTrue (CMPGE(F|D) y x)) // reverse operands to work around NaN
+
+(Leq8U x y)  => (XOR (MOVVconst [1]) (SGTU (ZeroExt8to64 x) (ZeroExt8to64 y)))
+(Leq16U x y) => (XOR (MOVVconst [1]) (SGTU (ZeroExt16to64 x) (ZeroExt16to64 y)))
+(Leq32U x y) => (XOR (MOVVconst [1]) (SGTU (ZeroExt32to64 x) (ZeroExt32to64 y)))
+(Leq64U x y) => (XOR (MOVVconst [1]) (SGTU x y))
+
+(OffPtr [off] ptr:(SP)) => (MOVVaddr [int32(off)] ptr)
+(OffPtr [off] ptr) => (ADDVconst [off] ptr)
+
+(Addr {sym} base) => (MOVVaddr {sym} base)
+(LocalAddr {sym} base _) => (MOVVaddr {sym} base)
+
+// loads
+(Load <t> ptr mem) && t.IsBoolean() => (MOVBUload ptr mem)
+(Load <t> ptr mem) && (is8BitInt(t) && isSigned(t)) => (MOVBload ptr mem)
+(Load <t> ptr mem) && (is8BitInt(t) && !isSigned(t)) => (MOVBUload ptr mem)
+(Load <t> ptr mem) && (is16BitInt(t) && isSigned(t)) => (MOVHload ptr mem)
+(Load <t> ptr mem) && (is16BitInt(t) && !isSigned(t)) => (MOVHUload ptr mem)
+(Load <t> ptr mem) && (is32BitInt(t) && isSigned(t)) => (MOVWload ptr mem)
+(Load <t> ptr mem) && (is32BitInt(t) && !isSigned(t)) => (MOVWUload ptr mem)
+(Load <t> ptr mem) && (is64BitInt(t) || isPtr(t)) => (MOVVload ptr mem)
+(Load <t> ptr mem) && is32BitFloat(t) => (MOVFload ptr mem)
+(Load <t> ptr mem) && is64BitFloat(t) => (MOVDload ptr mem)
+
+// stores
+(Store {t} ptr val mem) && t.Size() == 1 => (MOVBstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 2 => (MOVHstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 4 && !is32BitFloat(val.Type) => (MOVWstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 8 && !is64BitFloat(val.Type) => (MOVVstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 4 && is32BitFloat(val.Type) => (MOVFstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 8 && is64BitFloat(val.Type) => (MOVDstore ptr val mem)
+
+// zeroing
+(Zero [0] _ mem) => mem
+(Zero [1] ptr mem) => (MOVBstore ptr (MOVVconst [0]) mem)
+(Zero [2] {t} ptr mem) && t.Alignment()%2 == 0 =>
+	(MOVHstore ptr (MOVVconst [0]) mem)
+(Zero [2] ptr mem) =>
+	(MOVBstore [1] ptr (MOVVconst [0])
+		(MOVBstore [0] ptr (MOVVconst [0]) mem))
+(Zero [4] {t} ptr mem) && t.Alignment()%4 == 0 =>
+	(MOVWstore ptr (MOVVconst [0]) mem)
+(Zero [4] {t} ptr mem) && t.Alignment()%2 == 0 =>
+	(MOVHstore [2] ptr (MOVVconst [0])
+		(MOVHstore [0] ptr (MOVVconst [0]) mem))
+(Zero [4] ptr mem) =>
+	(MOVBstore [3] ptr (MOVVconst [0])
+		(MOVBstore [2] ptr (MOVVconst [0])
+			(MOVBstore [1] ptr (MOVVconst [0])
+				(MOVBstore [0] ptr (MOVVconst [0]) mem))))
+(Zero [8] {t} ptr mem) && t.Alignment()%8 == 0 =>
+	(MOVVstore ptr (MOVVconst [0]) mem)
+(Zero [8] {t} ptr mem) && t.Alignment()%4 == 0 =>
+	(MOVWstore [4] ptr (MOVVconst [0])
+		(MOVWstore [0] ptr (MOVVconst [0]) mem))
+(Zero [8] {t} ptr mem) && t.Alignment()%2 == 0 =>
+	(MOVHstore [6] ptr (MOVVconst [0])
+		(MOVHstore [4] ptr (MOVVconst [0])
+			(MOVHstore [2] ptr (MOVVconst [0])
+				(MOVHstore [0] ptr (MOVVconst [0]) mem))))
+
+(Zero [3] ptr mem) =>
+	(MOVBstore [2] ptr (MOVVconst [0])
+		(MOVBstore [1] ptr (MOVVconst [0])
+			(MOVBstore [0] ptr (MOVVconst [0]) mem)))
+(Zero [6] {t} ptr mem) && t.Alignment()%2 == 0 =>
+	(MOVHstore [4] ptr (MOVVconst [0])
+		(MOVHstore [2] ptr (MOVVconst [0])
+			(MOVHstore [0] ptr (MOVVconst [0]) mem)))
+(Zero [12] {t} ptr mem) && t.Alignment()%4 == 0 =>
+	(MOVWstore [8] ptr (MOVVconst [0])
+		(MOVWstore [4] ptr (MOVVconst [0])
+			(MOVWstore [0] ptr (MOVVconst [0]) mem)))
+(Zero [16] {t} ptr mem) && t.Alignment()%8 == 0 =>
+	(MOVVstore [8] ptr (MOVVconst [0])
+		(MOVVstore [0] ptr (MOVVconst [0]) mem))
+(Zero [24] {t} ptr mem) && t.Alignment()%8 == 0 =>
+	(MOVVstore [16] ptr (MOVVconst [0])
+		(MOVVstore [8] ptr (MOVVconst [0])
+			(MOVVstore [0] ptr (MOVVconst [0]) mem)))
+
+// medium zeroing uses a duff device
+// 8, and 128 are magic constants, see runtime/mkduff.go
+(Zero [s] {t} ptr mem)
+	&& s%8 == 0 && s > 24 && s <= 8*128
+	&& t.Alignment()%8 == 0 && !config.noDuffDevice =>
+	(DUFFZERO [8 * (128 - s/8)] ptr mem)
+
+// large or unaligned zeroing uses a loop
+(Zero [s] {t} ptr mem)
+	&& (s > 8*128 || config.noDuffDevice) || t.Alignment()%8 != 0 =>
+	(LoweredZero [t.Alignment()]
+		ptr
+		(ADDVconst <ptr.Type> ptr [s-moveSize(t.Alignment(), config)])
+		mem)
+
+// moves
+(Move [0] _ _ mem) => mem
+(Move [1] dst src mem) => (MOVBstore dst (MOVBload src mem) mem)
+(Move [2] {t} dst src mem) && t.Alignment()%2 == 0 =>
+	(MOVHstore dst (MOVHload src mem) mem)
+(Move [2] dst src mem) =>
+	(MOVBstore [1] dst (MOVBload [1] src mem)
+		(MOVBstore dst (MOVBload src mem) mem))
+(Move [4] {t} dst src mem) && t.Alignment()%4 == 0 =>
+	(MOVWstore dst (MOVWload src mem) mem)
+(Move [4] {t} dst src mem) && t.Alignment()%2 == 0 =>
+	(MOVHstore [2] dst (MOVHload [2] src mem)
+		(MOVHstore dst (MOVHload src mem) mem))
+(Move [4] dst src mem) =>
+	(MOVBstore [3] dst (MOVBload [3] src mem)
+		(MOVBstore [2] dst (MOVBload [2] src mem)
+			(MOVBstore [1] dst (MOVBload [1] src mem)
+				(MOVBstore dst (MOVBload src mem) mem))))
+(Move [8] {t} dst src mem) && t.Alignment()%8 == 0 =>
+	(MOVVstore dst (MOVVload src mem) mem)
+(Move [8] {t} dst src mem) && t.Alignment()%4 == 0 =>
+	(MOVWstore [4] dst (MOVWload [4] src mem)
+		(MOVWstore dst (MOVWload src mem) mem))
+(Move [8] {t} dst src mem) && t.Alignment()%2 == 0 =>
+	(MOVHstore [6] dst (MOVHload [6] src mem)
+		(MOVHstore [4] dst (MOVHload [4] src mem)
+			(MOVHstore [2] dst (MOVHload [2] src mem)
+				(MOVHstore dst (MOVHload src mem) mem))))
+
+(Move [3] dst src mem) =>
+	(MOVBstore [2] dst (MOVBload [2] src mem)
+		(MOVBstore [1] dst (MOVBload [1] src mem)
+			(MOVBstore dst (MOVBload src mem) mem)))
+(Move [6] {t} dst src mem) && t.Alignment()%2 == 0 =>
+	(MOVHstore [4] dst (MOVHload [4] src mem)
+		(MOVHstore [2] dst (MOVHload [2] src mem)
+			(MOVHstore dst (MOVHload src mem) mem)))
+(Move [12] {t} dst src mem) && t.Alignment()%4 == 0 =>
+	(MOVWstore [8] dst (MOVWload [8] src mem)
+		(MOVWstore [4] dst (MOVWload [4] src mem)
+			(MOVWstore dst (MOVWload src mem) mem)))
+(Move [16] {t} dst src mem) && t.Alignment()%8 == 0 =>
+	(MOVVstore [8] dst (MOVVload [8] src mem)
+		(MOVVstore dst (MOVVload src mem) mem))
+(Move [24] {t} dst src mem) && t.Alignment()%8 == 0 =>
+	(MOVVstore [16] dst (MOVVload [16] src mem)
+		(MOVVstore [8] dst (MOVVload [8] src mem)
+			(MOVVstore dst (MOVVload src mem) mem)))
+
+// medium move uses a duff device
+(Move [s] {t} dst src mem)
+	&& s%8 == 0 && s >= 24 && s <= 8*128 && t.Alignment()%8 == 0
+	&& !config.noDuffDevice && logLargeCopy(v, s)  =>
+	(DUFFCOPY [16 * (128 - s/8)] dst src mem)
+// 16 and 128 are magic constants.  16 is the number of bytes to encode:
+//	MOVV	(R1), R23
+//	ADDV	$8, R1
+//	MOVV	R23, (R2)
+//	ADDV	$8, R2
+// and 128 is the number of such blocks. See runtime/duff_mips64.s:duffcopy.
+
+// large or unaligned move uses a loop
+(Move [s] {t} dst src mem)
+	&& s > 24 && logLargeCopy(v, s) || t.Alignment()%8 != 0 =>
+	(LoweredMove [t.Alignment()]
+		dst
+		src
+		(ADDVconst <src.Type> src [s-moveSize(t.Alignment(), config)])
+		mem)
+
+// calls
+(StaticCall ...) => (CALLstatic ...)
+(ClosureCall ...) => (CALLclosure ...)
+(InterCall ...) => (CALLinter ...)
+(TailCall ...) => (CALLtail ...)
+
+// atomic intrinsics
+(AtomicLoad(8|32|64)   ...) => (LoweredAtomicLoad(8|32|64)  ...)
+(AtomicLoadPtr ...) => (LoweredAtomicLoad64 ...)
+
+(AtomicStore(8|32|64) ...) => (LoweredAtomicStore(8|32|64)  ...)
+(AtomicStorePtrNoWB ...) => (LoweredAtomicStore64 ...)
+
+(AtomicExchange(32|64) ...) => (LoweredAtomicExchange(32|64) ...)
+
+(AtomicAdd(32|64) ...) => (LoweredAtomicAdd(32|64) ...)
+
+(AtomicCompareAndSwap32 ptr old new mem) => (LoweredAtomicCas32 ptr (SignExt32to64 old) new mem)
+(AtomicCompareAndSwap64 ...) => (LoweredAtomicCas64 ...)
+
+// checks
+(NilCheck ...) => (LoweredNilCheck ...)
+(IsNonNil ptr) => (SGTU ptr (MOVVconst [0]))
+(IsInBounds idx len) => (SGTU len idx)
+(IsSliceInBounds idx len) => (XOR (MOVVconst [1]) (SGTU idx len))
+
+// pseudo-ops
+(GetClosurePtr ...) => (LoweredGetClosurePtr ...)
+(GetCallerSP ...) => (LoweredGetCallerSP ...)
+(GetCallerPC ...) => (LoweredGetCallerPC ...)
+
+(If cond yes no) => (NE cond yes no)
+
+// Write barrier.
+(WB ...) => (LoweredWB ...)
+
+(PanicBounds [kind] x y mem) && boundsABI(kind) == 0 => (LoweredPanicBoundsA [kind] x y mem)
+(PanicBounds [kind] x y mem) && boundsABI(kind) == 1 => (LoweredPanicBoundsB [kind] x y mem)
+(PanicBounds [kind] x y mem) && boundsABI(kind) == 2 => (LoweredPanicBoundsC [kind] x y mem)
+
+(CondSelect <t> x y cond) => (OR (MASKEQZ <t> x cond) (MASKNEZ <t> y cond))
+
+// Optimizations
+
+// Absorb boolean tests into block
+(NE (FPFlagTrue cmp) yes no) => (FPT cmp yes no)
+(NE (FPFlagFalse cmp) yes no) => (FPF cmp yes no)
+(EQ (FPFlagTrue cmp) yes no) => (FPF cmp yes no)
+(EQ (FPFlagFalse cmp) yes no) => (FPT cmp yes no)
+(NE (XORconst [1] cmp:(SGT _ _)) yes no) => (EQ cmp yes no)
+(NE (XORconst [1] cmp:(SGTU _ _)) yes no) => (EQ cmp yes no)
+(NE (XORconst [1] cmp:(SGTconst _)) yes no) => (EQ cmp yes no)
+(NE (XORconst [1] cmp:(SGTUconst _)) yes no) => (EQ cmp yes no)
+(EQ (XORconst [1] cmp:(SGT _ _)) yes no) => (NE cmp yes no)
+(EQ (XORconst [1] cmp:(SGTU _ _)) yes no) => (NE cmp yes no)
+(EQ (XORconst [1] cmp:(SGTconst _)) yes no) => (NE cmp yes no)
+(EQ (XORconst [1] cmp:(SGTUconst _)) yes no) => (NE cmp yes no)
+(NE (SGTUconst [1] x) yes no) => (EQ x yes no)
+(EQ (SGTUconst [1] x) yes no) => (NE x yes no)
+(NE (SGTU x (MOVVconst [0])) yes no) => (NE x yes no)
+(EQ (SGTU x (MOVVconst [0])) yes no) => (EQ x yes no)
+(NE (SGTconst [0] x) yes no) => (LTZ x yes no)
+(EQ (SGTconst [0] x) yes no) => (GEZ x yes no)
+(NE (SGT x (MOVVconst [0])) yes no) => (GTZ x yes no)
+(EQ (SGT x (MOVVconst [0])) yes no) => (LEZ x yes no)
+
+// fold offset into address
+(ADDVconst [off1] (MOVVaddr [off2] {sym} ptr)) && is32Bit(off1+int64(off2)) => (MOVVaddr [int32(off1)+int32(off2)] {sym} ptr)
+
+// fold address into load/store
+(MOVBload  [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVBload  [off1+int32(off2)] {sym} ptr mem)
+(MOVBUload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVBUload [off1+int32(off2)] {sym} ptr mem)
+(MOVHload  [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVHload  [off1+int32(off2)] {sym} ptr mem)
+(MOVHUload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVHUload [off1+int32(off2)] {sym} ptr mem)
+(MOVWload  [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVWload  [off1+int32(off2)] {sym} ptr mem)
+(MOVWUload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVWUload [off1+int32(off2)] {sym} ptr mem)
+(MOVVload  [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVVload  [off1+int32(off2)] {sym} ptr mem)
+(MOVFload  [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVFload  [off1+int32(off2)] {sym} ptr mem)
+(MOVDload  [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVDload  [off1+int32(off2)] {sym} ptr mem)
+
+(MOVBstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVBstore [off1+int32(off2)] {sym} ptr val mem)
+(MOVHstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVHstore [off1+int32(off2)] {sym} ptr val mem)
+(MOVWstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVWstore [off1+int32(off2)] {sym} ptr val mem)
+(MOVVstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVVstore [off1+int32(off2)] {sym} ptr val mem)
+(MOVFstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVFstore [off1+int32(off2)] {sym} ptr val mem)
+(MOVDstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVDstore [off1+int32(off2)] {sym} ptr val mem)
+(MOVBstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVBstorezero [off1+int32(off2)] {sym} ptr mem)
+(MOVHstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVHstorezero [off1+int32(off2)] {sym} ptr mem)
+(MOVWstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVWstorezero [off1+int32(off2)] {sym} ptr mem)
+(MOVVstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVVstorezero [off1+int32(off2)] {sym} ptr mem)
+
+(MOVBload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVBload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
+(MOVBUload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVBUload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
+(MOVHload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVHload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
+(MOVHUload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVHUload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
+(MOVWload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVWload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
+(MOVWUload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVWUload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
+(MOVVload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVVload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
+(MOVFload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVFload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
+(MOVDload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVDload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
+
+(MOVBstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVBstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem)
+(MOVHstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVHstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem)
+(MOVWstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVWstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem)
+(MOVVstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVVstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem)
+(MOVFstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVFstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem)
+(MOVDstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVDstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem)
+(MOVBstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVBstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
+(MOVHstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVHstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
+(MOVWstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVWstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
+(MOVVstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVVstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
+
+(LoweredAtomicStore(32|64) ptr (MOVVconst [0]) mem) => (LoweredAtomicStorezero(32|64) ptr mem)
+(LoweredAtomicAdd32 ptr (MOVVconst [c]) mem) && is32Bit(c) => (LoweredAtomicAddconst32 [int32(c)] ptr mem)
+(LoweredAtomicAdd64 ptr (MOVVconst [c]) mem) && is32Bit(c) => (LoweredAtomicAddconst64 [c] ptr mem)
+
+// don't extend after proper load
+(MOVBreg x:(MOVBload _ _)) => (MOVVreg x)
+(MOVBUreg x:(MOVBUload _ _)) => (MOVVreg x)
+(MOVHreg x:(MOVBload _ _)) => (MOVVreg x)
+(MOVHreg x:(MOVBUload _ _)) => (MOVVreg x)
+(MOVHreg x:(MOVHload _ _)) => (MOVVreg x)
+(MOVHUreg x:(MOVBUload _ _)) => (MOVVreg x)
+(MOVHUreg x:(MOVHUload _ _)) => (MOVVreg x)
+(MOVWreg x:(MOVBload _ _)) => (MOVVreg x)
+(MOVWreg x:(MOVBUload _ _)) => (MOVVreg x)
+(MOVWreg x:(MOVHload _ _)) => (MOVVreg x)
+(MOVWreg x:(MOVHUload _ _)) => (MOVVreg x)
+(MOVWreg x:(MOVWload _ _)) => (MOVVreg x)
+(MOVWUreg x:(MOVBUload _ _)) => (MOVVreg x)
+(MOVWUreg x:(MOVHUload _ _)) => (MOVVreg x)
+(MOVWUreg x:(MOVWUload _ _)) => (MOVVreg x)
+
+// fold double extensions
+(MOVBreg x:(MOVBreg _)) => (MOVVreg x)
+(MOVBUreg x:(MOVBUreg _)) => (MOVVreg x)
+(MOVHreg x:(MOVBreg _)) => (MOVVreg x)
+(MOVHreg x:(MOVBUreg _)) => (MOVVreg x)
+(MOVHreg x:(MOVHreg _)) => (MOVVreg x)
+(MOVHUreg x:(MOVBUreg _)) => (MOVVreg x)
+(MOVHUreg x:(MOVHUreg _)) => (MOVVreg x)
+(MOVWreg x:(MOVBreg _)) => (MOVVreg x)
+(MOVWreg x:(MOVBUreg _)) => (MOVVreg x)
+(MOVWreg x:(MOVHreg _)) => (MOVVreg x)
+(MOVWreg x:(MOVWreg _)) => (MOVVreg x)
+(MOVWUreg x:(MOVBUreg _)) => (MOVVreg x)
+(MOVWUreg x:(MOVHUreg _)) => (MOVVreg x)
+(MOVWUreg x:(MOVWUreg _)) => (MOVVreg x)
+
+// don't extend before store
+(MOVBstore [off] {sym} ptr (MOVBreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr (MOVBUreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr (MOVHreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr (MOVHUreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr (MOVWreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr (MOVWUreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
+(MOVHstore [off] {sym} ptr (MOVHreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
+(MOVHstore [off] {sym} ptr (MOVHUreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
+(MOVHstore [off] {sym} ptr (MOVWreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
+(MOVHstore [off] {sym} ptr (MOVWUreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
+(MOVWstore [off] {sym} ptr (MOVWreg x) mem) => (MOVWstore [off] {sym} ptr x mem)
+(MOVWstore [off] {sym} ptr (MOVWUreg x) mem) => (MOVWstore [off] {sym} ptr x mem)
+
+// if a register move has only 1 use, just use the same register without emitting instruction
+// MOVVnop doesn't emit instruction, only for ensuring the type.
+(MOVVreg x) && x.Uses == 1 => (MOVVnop x)
+
+// fold constant into arithmetic ops
+(ADDV x (MOVVconst [c])) && is32Bit(c) => (ADDVconst [c] x)
+(SUBV x (MOVVconst [c])) && is32Bit(c) => (SUBVconst [c] x)
+(AND x (MOVVconst [c])) && is32Bit(c) => (ANDconst [c] x)
+(OR  x (MOVVconst [c])) && is32Bit(c) => (ORconst  [c] x)
+(XOR x (MOVVconst [c])) && is32Bit(c) => (XORconst [c] x)
+(NOR x (MOVVconst [c])) && is32Bit(c) => (NORconst [c] x)
+
+(SLLV _ (MOVVconst [c])) && uint64(c)>=64 => (MOVVconst [0])
+(SRLV _ (MOVVconst [c])) && uint64(c)>=64 => (MOVVconst [0])
+(SRAV x (MOVVconst [c])) && uint64(c)>=64 => (SRAVconst x [63])
+(SLLV x (MOVVconst [c])) => (SLLVconst x [c])
+(SRLV x (MOVVconst [c])) => (SRLVconst x [c])
+(SRAV x (MOVVconst [c])) => (SRAVconst x [c])
+(ROTR x (MOVVconst [c]))  => (ROTRconst x [c&31])
+(ROTRV x (MOVVconst [c])) => (ROTRVconst x [c&63])
+
+(SGT  (MOVVconst [c]) x) && is32Bit(c) => (SGTconst  [c] x)
+(SGTU (MOVVconst [c]) x) && is32Bit(c) => (SGTUconst [c] x)
+
+// mul by constant
+(Select1 (MULVU x (MOVVconst [-1]))) => (NEGV x)
+(Select1 (MULVU _ (MOVVconst [0]))) => (MOVVconst [0])
+(Select1 (MULVU x (MOVVconst [1]))) => x
+(Select1 (MULVU x (MOVVconst [c]))) && isPowerOfTwo64(c) => (SLLVconst [log64(c)] x)
+
+// div by constant
+(Select1 (DIVVU x (MOVVconst [1]))) => x
+(Select1 (DIVVU x (MOVVconst [c]))) && isPowerOfTwo64(c) => (SRLVconst [log64(c)] x)
+(Select0 (DIVVU _ (MOVVconst [1]))) => (MOVVconst [0])                       // mod
+(Select0 (DIVVU x (MOVVconst [c]))) && isPowerOfTwo64(c) => (ANDconst [c-1] x) // mod
+
+// generic simplifications
+(ADDV x (NEGV y)) => (SUBV x y)
+(SUBV x x) => (MOVVconst [0])
+(SUBV (MOVVconst [0]) x) => (NEGV x)
+(AND x x) => x
+(OR  x x) => x
+(XOR x x) => (MOVVconst [0])
+
+// remove redundant *const ops
+(ADDVconst [0]  x) => x
+(SUBVconst [0]  x) => x
+(ANDconst [0]  _) => (MOVVconst [0])
+(ANDconst [-1] x) => x
+(ORconst  [0]  x) => x
+(ORconst  [-1] _) => (MOVVconst [-1])
+(XORconst [0]  x) => x
+(XORconst [-1] x) => (NORconst [0] x)
+(MASKEQZ (MOVVconst [0]) cond) => (MOVVconst [0])
+(MASKNEZ (MOVVconst [0]) cond) => (MOVVconst [0])
+
+// generic constant folding
+(ADDVconst [c] (MOVVconst [d]))  => (MOVVconst [c+d])
+(ADDVconst [c] (ADDVconst [d] x)) && is32Bit(c+d) => (ADDVconst [c+d] x)
+(ADDVconst [c] (SUBVconst [d] x)) && is32Bit(c-d) => (ADDVconst [c-d] x)
+(SUBVconst [c] (MOVVconst [d]))  => (MOVVconst [d-c])
+(SUBVconst [c] (SUBVconst [d] x)) && is32Bit(-c-d) => (ADDVconst [-c-d] x)
+(SUBVconst [c] (ADDVconst [d] x)) && is32Bit(-c+d) => (ADDVconst [-c+d] x)
+(SLLVconst [c] (MOVVconst [d]))  => (MOVVconst [d<<uint64(c)])
+(SRLVconst [c] (MOVVconst [d]))  => (MOVVconst [int64(uint64(d)>>uint64(c))])
+(SRAVconst [c] (MOVVconst [d]))  => (MOVVconst [d>>uint64(c)])
+(Select1 (MULVU (MOVVconst [c]) (MOVVconst [d]))) => (MOVVconst [c*d])
+(Select1 (DIVV  (MOVVconst [c]) (MOVVconst [d]))) && d != 0 => (MOVVconst [c/d])
+(Select1 (DIVVU (MOVVconst [c]) (MOVVconst [d]))) && d != 0 => (MOVVconst [int64(uint64(c)/uint64(d))])
+(Select0 (DIVV  (MOVVconst [c]) (MOVVconst [d]))) && d != 0 => (MOVVconst [c%d])   // mod
+(Select0 (DIVVU (MOVVconst [c]) (MOVVconst [d]))) && d != 0 => (MOVVconst [int64(uint64(c)%uint64(d))]) // mod
+(ANDconst [c] (MOVVconst [d])) => (MOVVconst [c&d])
+(ANDconst [c] (ANDconst [d] x)) => (ANDconst [c&d] x)
+(ORconst [c] (MOVVconst [d])) => (MOVVconst [c|d])
+(ORconst [c] (ORconst [d] x)) && is32Bit(c|d) => (ORconst [c|d] x)
+(XORconst [c] (MOVVconst [d])) => (MOVVconst [c^d])
+(XORconst [c] (XORconst [d] x)) && is32Bit(c^d) => (XORconst [c^d] x)
+(NORconst [c] (MOVVconst [d])) => (MOVVconst [^(c|d)])
+(NEGV (MOVVconst [c])) => (MOVVconst [-c])
+(MOVBreg  (MOVVconst [c])) => (MOVVconst [int64(int8(c))])
+(MOVBUreg (MOVVconst [c])) => (MOVVconst [int64(uint8(c))])
+(MOVHreg  (MOVVconst [c])) => (MOVVconst [int64(int16(c))])
+(MOVHUreg (MOVVconst [c])) => (MOVVconst [int64(uint16(c))])
+(MOVWreg  (MOVVconst [c])) => (MOVVconst [int64(int32(c))])
+(MOVWUreg (MOVVconst [c])) => (MOVVconst [int64(uint32(c))])
+(MOVVreg  (MOVVconst [c])) => (MOVVconst [c])
+
+// constant comparisons
+(SGTconst [c] (MOVVconst [d])) && c>d => (MOVVconst [1])
+(SGTconst [c] (MOVVconst [d])) && c<=d => (MOVVconst [0])
+(SGTUconst [c] (MOVVconst [d])) && uint64(c)>uint64(d) => (MOVVconst [1])
+(SGTUconst [c] (MOVVconst [d])) && uint64(c)<=uint64(d) => (MOVVconst [0])
+
+// other known comparisons
+(SGTconst [c] (MOVBreg _)) && 0x7f < c => (MOVVconst [1])
+(SGTconst [c] (MOVBreg _)) && c <= -0x80 => (MOVVconst [0])
+(SGTconst [c] (MOVBUreg _)) && 0xff < c => (MOVVconst [1])
+(SGTconst [c] (MOVBUreg _)) && c < 0 => (MOVVconst [0])
+(SGTUconst [c] (MOVBUreg _)) && 0xff < uint64(c) => (MOVVconst [1])
+(SGTconst [c] (MOVHreg _)) && 0x7fff < c => (MOVVconst [1])
+(SGTconst [c] (MOVHreg _)) && c <= -0x8000 => (MOVVconst [0])
+(SGTconst [c] (MOVHUreg _)) && 0xffff < c => (MOVVconst [1])
+(SGTconst [c] (MOVHUreg _)) && c < 0 => (MOVVconst [0])
+(SGTUconst [c] (MOVHUreg _)) && 0xffff < uint64(c) => (MOVVconst [1])
+(SGTconst [c] (MOVWUreg _)) && c < 0 => (MOVVconst [0])
+(SGTconst [c] (ANDconst [m] _)) && 0 <= m && m < c => (MOVVconst [1])
+(SGTUconst [c] (ANDconst [m] _)) && uint64(m) < uint64(c) => (MOVVconst [1])
+(SGTconst [c] (SRLVconst _ [d])) && 0 <= c && 0 < d && d <= 63 && 0xffffffffffffffff>>uint64(d) < uint64(c) => (MOVVconst [1])
+(SGTUconst [c] (SRLVconst _ [d])) && 0 < d && d <= 63 && 0xffffffffffffffff>>uint64(d) < uint64(c) => (MOVVconst [1])
+
+// absorb constants into branches
+(EQ  (MOVVconst [0]) yes no) => (First yes no)
+(EQ  (MOVVconst [c]) yes no) && c != 0 => (First no yes)
+(NE  (MOVVconst [0]) yes no) => (First no yes)
+(NE  (MOVVconst [c]) yes no) && c != 0 => (First yes no)
+(LTZ (MOVVconst [c]) yes no) && c <  0 => (First yes no)
+(LTZ (MOVVconst [c]) yes no) && c >= 0 => (First no yes)
+(LEZ (MOVVconst [c]) yes no) && c <= 0 => (First yes no)
+(LEZ (MOVVconst [c]) yes no) && c >  0 => (First no yes)
+(GTZ (MOVVconst [c]) yes no) && c >  0 => (First yes no)
+(GTZ (MOVVconst [c]) yes no) && c <= 0 => (First no yes)
+(GEZ (MOVVconst [c]) yes no) && c >= 0 => (First yes no)
+(GEZ (MOVVconst [c]) yes no) && c <  0 => (First no yes)
+
+// SGT/SGTU with known outcomes.
+(SGT  x x) => (MOVVconst [0])
+(SGTU x x) => (MOVVconst [0])
diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go
new file mode 100644
index 0000000..22a83fb
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go
@@ -0,0 +1,484 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "strings"
+
+// Notes:
+//  - Integer types live in the low portion of registers. Upper portions are junk.
+//  - Boolean types use the low-order byte of a register. 0=false, 1=true.
+//    Upper bytes are junk.
+//  - *const instructions may use a constant larger than the instruction can encode.
+//    In this case the assembler expands to multiple instructions and uses tmp
+//    register (R23).
+
+// Suffixes encode the bit width of various instructions.
+// V (vlong)     = 64 bit
+// WU (word)     = 32 bit unsigned
+// W (word)      = 32 bit
+// H (half word) = 16 bit
+// HU            = 16 bit unsigned
+// B (byte)      = 8 bit
+// BU            = 8 bit unsigned
+// F (float)     = 32 bit float
+// D (double)    = 64 bit float
+
+// Note: registers not used in regalloc are not included in this list,
+// so that regmask stays within int64
+// Be careful when hand coding regmasks.
+var regNamesLOONG64 = []string{
+	"R0", // constant 0
+	"R1",
+	"SP", // aka R3
+	"R4",
+	"R5",
+	"R6",
+	"R7",
+	"R8",
+	"R9",
+	"R10",
+	"R11",
+	"R12",
+	"R13",
+	"R14",
+	"R15",
+	"R16",
+	"R17",
+	"R18",
+	"R19",
+	"R20",
+	"R21",
+	"g", // aka R22
+	"R23",
+	"R24",
+	"R25",
+	"R26",
+	"R27",
+	"R28",
+	"R29",
+	// R30 is REGTMP not used in regalloc
+	"R31",
+
+	"F0",
+	"F1",
+	"F2",
+	"F3",
+	"F4",
+	"F5",
+	"F6",
+	"F7",
+	"F8",
+	"F9",
+	"F10",
+	"F11",
+	"F12",
+	"F13",
+	"F14",
+	"F15",
+	"F16",
+	"F17",
+	"F18",
+	"F19",
+	"F20",
+	"F21",
+	"F22",
+	"F23",
+	"F24",
+	"F25",
+	"F26",
+	"F27",
+	"F28",
+	"F29",
+	"F30",
+	"F31",
+
+	// If you add registers, update asyncPreempt in runtime.
+
+	// pseudo-registers
+	"SB",
+}
+
+func init() {
+	// Make map from reg names to reg integers.
+	if len(regNamesLOONG64) > 64 {
+		panic("too many registers")
+	}
+	num := map[string]int{}
+	for i, name := range regNamesLOONG64 {
+		num[name] = i
+	}
+	buildReg := func(s string) regMask {
+		m := regMask(0)
+		for _, r := range strings.Split(s, " ") {
+			if n, ok := num[r]; ok {
+				m |= regMask(1) << uint(n)
+				continue
+			}
+			panic("register " + r + " not found")
+		}
+		return m
+	}
+
+	// Common individual register masks
+	var (
+		gp         = buildReg("R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31") // R1 is LR, R2 is thread pointer, R3 is stack pointer, R21-unused, R22 is g, R30 is REGTMP
+		gps        = buildReg("R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31") | buildReg("g")
+		gpg        = gp | buildReg("g")
+		gpsp       = gp | buildReg("SP")
+		gpspg      = gpg | buildReg("SP")
+		gpspsbg    = gpspg | buildReg("SB")
+		fp         = buildReg("F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31")
+		callerSave = gp | fp | buildReg("g") // runtime.setg (and anything calling it) may clobber g
+		r1         = buildReg("R19")
+		r2         = buildReg("R18")
+		r3         = buildReg("R17")
+		r4         = buildReg("R4")
+	)
+	// Common regInfo
+	var (
+		gp01      = regInfo{inputs: nil, outputs: []regMask{gp}}
+		gp11      = regInfo{inputs: []regMask{gpg}, outputs: []regMask{gp}}
+		gp11sp    = regInfo{inputs: []regMask{gpspg}, outputs: []regMask{gp}}
+		gp21      = regInfo{inputs: []regMask{gpg, gpg}, outputs: []regMask{gp}}
+		gp22      = regInfo{inputs: []regMask{gps, gps}, outputs: []regMask{gp, gp}}
+		gpload    = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{gp}}
+		gpstore   = regInfo{inputs: []regMask{gpspsbg, gpg}}
+		gpstore0  = regInfo{inputs: []regMask{gpspsbg}}
+		gpxchg    = regInfo{inputs: []regMask{gpspsbg, gpg}, outputs: []regMask{gp}}
+		gpcas     = regInfo{inputs: []regMask{gpspsbg, gpg, gpg}, outputs: []regMask{gp}}
+		fp01      = regInfo{inputs: nil, outputs: []regMask{fp}}
+		fp11      = regInfo{inputs: []regMask{fp}, outputs: []regMask{fp}}
+		fp21      = regInfo{inputs: []regMask{fp, fp}, outputs: []regMask{fp}}
+		fp2flags  = regInfo{inputs: []regMask{fp, fp}}
+		fpload    = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{fp}}
+		fpstore   = regInfo{inputs: []regMask{gpspsbg, fp}}
+		readflags = regInfo{inputs: nil, outputs: []regMask{gp}}
+	)
+	ops := []opData{
+		// binary ops
+		{name: "ADDV", argLength: 2, reg: gp21, asm: "ADDVU", commutative: true},   // arg0 + arg1
+		{name: "ADDVconst", argLength: 1, reg: gp11sp, asm: "ADDVU", aux: "Int64"}, // arg0 + auxInt. auxInt is 32-bit, also in other *const ops.
+		{name: "SUBV", argLength: 2, reg: gp21, asm: "SUBVU"},                      // arg0 - arg1
+		{name: "SUBVconst", argLength: 1, reg: gp11, asm: "SUBVU", aux: "Int64"},   // arg0 - auxInt
+
+		{name: "MULV", argLength: 2, reg: gp22, resultNotInArgs: true, commutative: true, typ: "(Int64,Int64)"},    // arg0 * arg1, signed
+		{name: "MULVU", argLength: 2, reg: gp22, resultNotInArgs: true, commutative: true, typ: "(UInt64,UInt64)"}, // arg0 * arg1, unsigned
+		{name: "DIVV", argLength: 2, reg: gp22, resultNotInArgs: true, typ: "(Int64,Int64)"},                       // arg0 / arg1, signed
+		{name: "DIVVU", argLength: 2, reg: gp22, resultNotInArgs: true, typ: "(UInt64,UInt64)"},                    // arg0 / arg1, unsigned
+
+		{name: "ADDF", argLength: 2, reg: fp21, asm: "ADDF", commutative: true}, // arg0 + arg1
+		{name: "ADDD", argLength: 2, reg: fp21, asm: "ADDD", commutative: true}, // arg0 + arg1
+		{name: "SUBF", argLength: 2, reg: fp21, asm: "SUBF"},                    // arg0 - arg1
+		{name: "SUBD", argLength: 2, reg: fp21, asm: "SUBD"},                    // arg0 - arg1
+		{name: "MULF", argLength: 2, reg: fp21, asm: "MULF", commutative: true}, // arg0 * arg1
+		{name: "MULD", argLength: 2, reg: fp21, asm: "MULD", commutative: true}, // arg0 * arg1
+		{name: "DIVF", argLength: 2, reg: fp21, asm: "DIVF"},                    // arg0 / arg1
+		{name: "DIVD", argLength: 2, reg: fp21, asm: "DIVD"},                    // arg0 / arg1
+
+		{name: "AND", argLength: 2, reg: gp21, asm: "AND", commutative: true},                // arg0 & arg1
+		{name: "ANDconst", argLength: 1, reg: gp11, asm: "AND", aux: "Int64"},                // arg0 & auxInt
+		{name: "OR", argLength: 2, reg: gp21, asm: "OR", commutative: true},                  // arg0 | arg1
+		{name: "ORconst", argLength: 1, reg: gp11, asm: "OR", aux: "Int64"},                  // arg0 | auxInt
+		{name: "XOR", argLength: 2, reg: gp21, asm: "XOR", commutative: true, typ: "UInt64"}, // arg0 ^ arg1
+		{name: "XORconst", argLength: 1, reg: gp11, asm: "XOR", aux: "Int64", typ: "UInt64"}, // arg0 ^ auxInt
+		{name: "NOR", argLength: 2, reg: gp21, asm: "NOR", commutative: true},                // ^(arg0 | arg1)
+		{name: "NORconst", argLength: 1, reg: gp11, asm: "NOR", aux: "Int64"},                // ^(arg0 | auxInt)
+
+		{name: "NEGV", argLength: 1, reg: gp11},                // -arg0
+		{name: "NEGF", argLength: 1, reg: fp11, asm: "NEGF"},   // -arg0, float32
+		{name: "NEGD", argLength: 1, reg: fp11, asm: "NEGD"},   // -arg0, float64
+		{name: "SQRTD", argLength: 1, reg: fp11, asm: "SQRTD"}, // sqrt(arg0), float64
+		{name: "SQRTF", argLength: 1, reg: fp11, asm: "SQRTF"}, // sqrt(arg0), float32
+
+		{name: "MASKEQZ", argLength: 2, reg: gp21, asm: "MASKEQZ"}, // returns 0 if arg1 == 0, otherwise returns arg0
+		{name: "MASKNEZ", argLength: 2, reg: gp21, asm: "MASKNEZ"}, // returns 0 if arg1 != 0, otherwise returns arg0
+
+		// shifts
+		{name: "SLLV", argLength: 2, reg: gp21, asm: "SLLV"},                      // arg0 << arg1, shift amount is mod 64
+		{name: "SLLVconst", argLength: 1, reg: gp11, asm: "SLLV", aux: "Int64"},   // arg0 << auxInt
+		{name: "SRLV", argLength: 2, reg: gp21, asm: "SRLV"},                      // arg0 >> arg1, unsigned, shift amount is mod 64
+		{name: "SRLVconst", argLength: 1, reg: gp11, asm: "SRLV", aux: "Int64"},   // arg0 >> auxInt, unsigned
+		{name: "SRAV", argLength: 2, reg: gp21, asm: "SRAV"},                      // arg0 >> arg1, signed, shift amount is mod 64
+		{name: "SRAVconst", argLength: 1, reg: gp11, asm: "SRAV", aux: "Int64"},   // arg0 >> auxInt, signed
+		{name: "ROTR", argLength: 2, reg: gp21, asm: "ROTR"},                      // arg0 right rotate by (arg1 mod 32) bits
+		{name: "ROTRV", argLength: 2, reg: gp21, asm: "ROTRV"},                    // arg0 right rotate by (arg1 mod 64) bits
+		{name: "ROTRconst", argLength: 1, reg: gp11, asm: "ROTR", aux: "Int64"},   // uint32(arg0) right rotate by auxInt bits, auxInt should be in the range 0 to 31.
+		{name: "ROTRVconst", argLength: 1, reg: gp11, asm: "ROTRV", aux: "Int64"}, // arg0 right rotate by auxInt bits, auxInt should be in the range 0 to 63.
+
+		// comparisons
+		{name: "SGT", argLength: 2, reg: gp21, asm: "SGT", typ: "Bool"},                      // 1 if arg0 > arg1 (signed), 0 otherwise
+		{name: "SGTconst", argLength: 1, reg: gp11, asm: "SGT", aux: "Int64", typ: "Bool"},   // 1 if auxInt > arg0 (signed), 0 otherwise
+		{name: "SGTU", argLength: 2, reg: gp21, asm: "SGTU", typ: "Bool"},                    // 1 if arg0 > arg1 (unsigned), 0 otherwise
+		{name: "SGTUconst", argLength: 1, reg: gp11, asm: "SGTU", aux: "Int64", typ: "Bool"}, // 1 if auxInt > arg0 (unsigned), 0 otherwise
+
+		{name: "CMPEQF", argLength: 2, reg: fp2flags, asm: "CMPEQF", typ: "Flags"}, // flags=true if arg0 = arg1, float32
+		{name: "CMPEQD", argLength: 2, reg: fp2flags, asm: "CMPEQD", typ: "Flags"}, // flags=true if arg0 = arg1, float64
+		{name: "CMPGEF", argLength: 2, reg: fp2flags, asm: "CMPGEF", typ: "Flags"}, // flags=true if arg0 >= arg1, float32
+		{name: "CMPGED", argLength: 2, reg: fp2flags, asm: "CMPGED", typ: "Flags"}, // flags=true if arg0 >= arg1, float64
+		{name: "CMPGTF", argLength: 2, reg: fp2flags, asm: "CMPGTF", typ: "Flags"}, // flags=true if arg0 > arg1, float32
+		{name: "CMPGTD", argLength: 2, reg: fp2flags, asm: "CMPGTD", typ: "Flags"}, // flags=true if arg0 > arg1, float64
+
+		// moves
+		{name: "MOVVconst", argLength: 0, reg: gp01, aux: "Int64", asm: "MOVV", typ: "UInt64", rematerializeable: true},    // auxint
+		{name: "MOVFconst", argLength: 0, reg: fp01, aux: "Float64", asm: "MOVF", typ: "Float32", rematerializeable: true}, // auxint as 64-bit float, convert to 32-bit float
+		{name: "MOVDconst", argLength: 0, reg: fp01, aux: "Float64", asm: "MOVD", typ: "Float64", rematerializeable: true}, // auxint as 64-bit float
+
+		{name: "MOVVaddr", argLength: 1, reg: regInfo{inputs: []regMask{buildReg("SP") | buildReg("SB")}, outputs: []regMask{gp}}, aux: "SymOff", asm: "MOVV", rematerializeable: true, symEffect: "Addr"}, // arg0 + auxInt + aux.(*gc.Sym), arg0=SP/SB
+
+		{name: "MOVBload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVB", typ: "Int8", faultOnNilArg0: true, symEffect: "Read"},     // load from arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVBUload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVBU", typ: "UInt8", faultOnNilArg0: true, symEffect: "Read"},  // load from arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVHload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVH", typ: "Int16", faultOnNilArg0: true, symEffect: "Read"},    // load from arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVHUload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVHU", typ: "UInt16", faultOnNilArg0: true, symEffect: "Read"}, // load from arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVWload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVW", typ: "Int32", faultOnNilArg0: true, symEffect: "Read"},    // load from arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVWUload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVWU", typ: "UInt32", faultOnNilArg0: true, symEffect: "Read"}, // load from arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVVload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVV", typ: "UInt64", faultOnNilArg0: true, symEffect: "Read"},   // load from arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVFload", argLength: 2, reg: fpload, aux: "SymOff", asm: "MOVF", typ: "Float32", faultOnNilArg0: true, symEffect: "Read"},  // load from arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVDload", argLength: 2, reg: fpload, aux: "SymOff", asm: "MOVD", typ: "Float64", faultOnNilArg0: true, symEffect: "Read"},  // load from arg0 + auxInt + aux.  arg1=mem.
+
+		{name: "MOVBstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVB", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 1 byte of arg1 to arg0 + auxInt + aux.  arg2=mem.
+		{name: "MOVHstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVH", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 2 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
+		{name: "MOVWstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVW", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
+		{name: "MOVVstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVV", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
+		{name: "MOVFstore", argLength: 3, reg: fpstore, aux: "SymOff", asm: "MOVF", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
+		{name: "MOVDstore", argLength: 3, reg: fpstore, aux: "SymOff", asm: "MOVD", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
+
+		{name: "MOVBstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVB", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 1 byte of zero to arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVHstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVH", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 2 bytes of zero to arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVWstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVW", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes of zero to arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVVstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVV", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes of zero to arg0 + auxInt + aux.  ar12=mem.
+
+		// conversions
+		{name: "MOVBreg", argLength: 1, reg: gp11, asm: "MOVB"},   // move from arg0, sign-extended from byte
+		{name: "MOVBUreg", argLength: 1, reg: gp11, asm: "MOVBU"}, // move from arg0, unsign-extended from byte
+		{name: "MOVHreg", argLength: 1, reg: gp11, asm: "MOVH"},   // move from arg0, sign-extended from half
+		{name: "MOVHUreg", argLength: 1, reg: gp11, asm: "MOVHU"}, // move from arg0, unsign-extended from half
+		{name: "MOVWreg", argLength: 1, reg: gp11, asm: "MOVW"},   // move from arg0, sign-extended from word
+		{name: "MOVWUreg", argLength: 1, reg: gp11, asm: "MOVWU"}, // move from arg0, unsign-extended from word
+		{name: "MOVVreg", argLength: 1, reg: gp11, asm: "MOVV"},   // move from arg0
+
+		{name: "MOVVnop", argLength: 1, reg: regInfo{inputs: []regMask{gp}, outputs: []regMask{gp}}, resultInArg0: true}, // nop, return arg0 in same register
+
+		{name: "MOVWF", argLength: 1, reg: fp11, asm: "MOVWF"},     // int32 -> float32
+		{name: "MOVWD", argLength: 1, reg: fp11, asm: "MOVWD"},     // int32 -> float64
+		{name: "MOVVF", argLength: 1, reg: fp11, asm: "MOVVF"},     // int64 -> float32
+		{name: "MOVVD", argLength: 1, reg: fp11, asm: "MOVVD"},     // int64 -> float64
+		{name: "TRUNCFW", argLength: 1, reg: fp11, asm: "TRUNCFW"}, // float32 -> int32
+		{name: "TRUNCDW", argLength: 1, reg: fp11, asm: "TRUNCDW"}, // float64 -> int32
+		{name: "TRUNCFV", argLength: 1, reg: fp11, asm: "TRUNCFV"}, // float32 -> int64
+		{name: "TRUNCDV", argLength: 1, reg: fp11, asm: "TRUNCDV"}, // float64 -> int64
+		{name: "MOVFD", argLength: 1, reg: fp11, asm: "MOVFD"},     // float32 -> float64
+		{name: "MOVDF", argLength: 1, reg: fp11, asm: "MOVDF"},     // float64 -> float32
+
+		// function calls
+		{name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                                               // call static function aux.(*obj.LSym).  arg0=mem, auxint=argsize, returns mem
+		{name: "CALLtail", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true, tailCall: true},                                 // tail call static function aux.(*obj.LSym).  arg0=mem, auxint=argsize, returns mem
+		{name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{gpsp, buildReg("R29"), 0}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call function via closure.  arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem
+		{name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                         // call fn by pointer.  arg0=codeptr, arg1=mem, auxint=argsize, returns mem
+
+		// duffzero
+		// arg0 = address of memory to zero
+		// arg1 = mem
+		// auxint = offset into duffzero code to start executing
+		// returns mem
+		// R19 aka loong64.REGRT1 changed as side effect
+		{
+			name:      "DUFFZERO",
+			aux:       "Int64",
+			argLength: 2,
+			reg: regInfo{
+				inputs:   []regMask{gp},
+				clobbers: buildReg("R19 R1"),
+			},
+			faultOnNilArg0: true,
+		},
+
+		// duffcopy
+		// arg0 = address of dst memory (in R20, changed as side effect) REGRT2
+		// arg1 = address of src memory (in R19, changed as side effect) REGRT1
+		// arg2 = mem
+		// auxint = offset into duffcopy code to start executing
+		// returns mem
+		{
+			name:      "DUFFCOPY",
+			aux:       "Int64",
+			argLength: 3,
+			reg: regInfo{
+				inputs:   []regMask{buildReg("R20"), buildReg("R19")},
+				clobbers: buildReg("R19 R20 R1"),
+			},
+			faultOnNilArg0: true,
+			faultOnNilArg1: true,
+		},
+
+		// large or unaligned zeroing
+		// arg0 = address of memory to zero (in R19, changed as side effect)
+		// arg1 = address of the last element to zero
+		// arg2 = mem
+		// auxint = alignment
+		// returns mem
+		//	SUBV	$8, R19
+		//	MOVV	R0, 8(R19)
+		//	ADDV	$8, R19
+		//	BNE	Rarg1, R19, -2(PC)
+		{
+			name:      "LoweredZero",
+			aux:       "Int64",
+			argLength: 3,
+			reg: regInfo{
+				inputs:   []regMask{buildReg("R19"), gp},
+				clobbers: buildReg("R19"),
+			},
+			clobberFlags:   true,
+			faultOnNilArg0: true,
+		},
+
+		// large or unaligned move
+		// arg0 = address of dst memory (in R4, changed as side effect)
+		// arg1 = address of src memory (in R19, changed as side effect)
+		// arg2 = address of the last element of src
+		// arg3 = mem
+		// auxint = alignment
+		// returns mem
+		//	SUBV	$8, R19
+		//	MOVV	8(R19), Rtmp
+		//	MOVV	Rtmp, (R4)
+		//	ADDV	$8, R19
+		//	ADDV	$8, R4
+		//	BNE	Rarg2, R19, -4(PC)
+		{
+			name:      "LoweredMove",
+			aux:       "Int64",
+			argLength: 4,
+			reg: regInfo{
+				inputs:   []regMask{buildReg("R4"), buildReg("R19"), gp},
+				clobbers: buildReg("R19 R4"),
+			},
+			clobberFlags:   true,
+			faultOnNilArg0: true,
+			faultOnNilArg1: true,
+		},
+
+		// atomic loads.
+		// load from arg0. arg1=mem.
+		// returns <value,memory> so they can be properly ordered with other loads.
+		{name: "LoweredAtomicLoad8", argLength: 2, reg: gpload, faultOnNilArg0: true},
+		{name: "LoweredAtomicLoad32", argLength: 2, reg: gpload, faultOnNilArg0: true},
+		{name: "LoweredAtomicLoad64", argLength: 2, reg: gpload, faultOnNilArg0: true},
+
+		// atomic stores.
+		// store arg1 to arg0. arg2=mem. returns memory.
+		{name: "LoweredAtomicStore8", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true},
+		{name: "LoweredAtomicStore32", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true},
+		{name: "LoweredAtomicStore64", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true},
+		// store zero to arg0. arg1=mem. returns memory.
+		{name: "LoweredAtomicStorezero32", argLength: 2, reg: gpstore0, faultOnNilArg0: true, hasSideEffects: true},
+		{name: "LoweredAtomicStorezero64", argLength: 2, reg: gpstore0, faultOnNilArg0: true, hasSideEffects: true},
+
+		// atomic exchange.
+		// store arg1 to arg0. arg2=mem. returns <old content of *arg0, memory>.
+		// DBAR
+		// LL	(Rarg0), Rout
+		// MOVV Rarg1, Rtmp
+		// SC	Rtmp, (Rarg0)
+		// BEQ	Rtmp, -3(PC)
+		// DBAR
+		{name: "LoweredAtomicExchange32", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+		{name: "LoweredAtomicExchange64", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+
+		// atomic add.
+		// *arg0 += arg1. arg2=mem. returns <new content of *arg0, memory>.
+		// DBAR
+		// LL	(Rarg0), Rout
+		// ADDV Rarg1, Rout, Rtmp
+		// SC	Rtmp, (Rarg0)
+		// BEQ	Rtmp, -3(PC)
+		// DBAR
+		// ADDV Rarg1, Rout
+		{name: "LoweredAtomicAdd32", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+		{name: "LoweredAtomicAdd64", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+		// *arg0 += auxint. arg1=mem. returns <new content of *arg0, memory>. auxint is 32-bit.
+		{name: "LoweredAtomicAddconst32", argLength: 2, reg: regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{gp}}, aux: "Int32", resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+		{name: "LoweredAtomicAddconst64", argLength: 2, reg: regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{gp}}, aux: "Int64", resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+
+		// atomic compare and swap.
+		// arg0 = pointer, arg1 = old value, arg2 = new value, arg3 = memory.
+		// if *arg0 == arg1 {
+		//   *arg0 = arg2
+		//   return (true, memory)
+		// } else {
+		//   return (false, memory)
+		// }
+		// DBAR
+		// MOVV $0, Rout
+		// LL	(Rarg0), Rtmp
+		// BNE	Rtmp, Rarg1, 4(PC)
+		// MOVV Rarg2, Rout
+		// SC	Rout, (Rarg0)
+		// BEQ	Rout, -4(PC)
+		// DBAR
+		{name: "LoweredAtomicCas32", argLength: 4, reg: gpcas, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+		{name: "LoweredAtomicCas64", argLength: 4, reg: gpcas, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+
+		// pseudo-ops
+		{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpg}}, nilCheck: true, faultOnNilArg0: true}, // panic if arg0 is nil.  arg1=mem.
+
+		{name: "FPFlagTrue", argLength: 1, reg: readflags},  // bool, true if FP flag is true
+		{name: "FPFlagFalse", argLength: 1, reg: readflags}, // bool, true if FP flag is false
+
+		// Scheduler ensures LoweredGetClosurePtr occurs only in entry block,
+		// and sorts it to the very beginning of the block to prevent other
+		// use of R22 (loong64.REGCTXT, the closure pointer)
+		{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R29")}}, zeroWidth: true},
+
+		// LoweredGetCallerSP returns the SP of the caller of the current function.
+		{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
+
+		// LoweredGetCallerPC evaluates to the PC to which its "caller" will return.
+		// I.e., if f calls g "calls" getcallerpc,
+		// the result should be the PC within f that g will return to.
+		// See runtime/stubs.go for a more detailed discussion.
+		{name: "LoweredGetCallerPC", reg: gp01, rematerializeable: true},
+
+		// LoweredWB invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
+		// It saves all GP registers if necessary,
+		// but clobbers R1 (LR) because it's a call
+		// and R30 (REGTMP).
+		{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R27"), buildReg("R28")}, clobbers: (callerSave &^ gpg) | buildReg("R1")}, clobberFlags: true, aux: "Sym", symEffect: "None"},
+
+		// There are three of these functions so that they can have three different register inputs.
+		// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the
+		// default registers to match so we don't need to copy registers around unnecessarily.
+		{name: "LoweredPanicBoundsA", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r3, r4}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
+		{name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r2, r3}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
+		{name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r1, r2}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
+	}
+
+	blocks := []blockData{
+		{name: "EQ", controls: 1},
+		{name: "NE", controls: 1},
+		{name: "LTZ", controls: 1}, // < 0
+		{name: "LEZ", controls: 1}, // <= 0
+		{name: "GTZ", controls: 1}, // > 0
+		{name: "GEZ", controls: 1}, // >= 0
+		{name: "FPT", controls: 1}, // FP flag is true
+		{name: "FPF", controls: 1}, // FP flag is false
+	}
+
+	archs = append(archs, arch{
+		name:     "LOONG64",
+		pkg:      "cmd/internal/obj/loong64",
+		genfile:  "../../loong64/ssa.go",
+		ops:      ops,
+		blocks:   blocks,
+		regnames: regNamesLOONG64,
+		// TODO: support register ABI on loong64
+		ParamIntRegNames:   "R4 R5 R6 R7 R8 R9 R10 R11",
+		ParamFloatRegNames: "F0 F1 F2 F3 F4 F5 F6 F7",
+		gpregmask:          gp,
+		fpregmask:          fp,
+		framepointerreg:    -1, // not used
+		linkreg:            int8(num["R1"]),
+	})
+}
diff --git a/src/cmd/compile/internal/ssa/gen/MIPS.rules b/src/cmd/compile/internal/ssa/_gen/MIPS.rules
similarity index 100%
rename from src/cmd/compile/internal/ssa/gen/MIPS.rules
rename to src/cmd/compile/internal/ssa/_gen/MIPS.rules
diff --git a/src/cmd/compile/internal/ssa/_gen/MIPS64.rules b/src/cmd/compile/internal/ssa/_gen/MIPS64.rules
new file mode 100644
index 0000000..a594df2
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/_gen/MIPS64.rules
@@ -0,0 +1,691 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+(Add(Ptr|64|32|16|8) ...) => (ADDV ...)
+(Add(32|64)F ...) => (ADD(F|D) ...)
+
+(Sub(Ptr|64|32|16|8) ...) => (SUBV ...)
+(Sub(32|64)F ...) => (SUB(F|D) ...)
+
+(Mul(64|32|16|8) x y) => (Select1 (MULVU x y))
+(Mul(32|64)F ...) => (MUL(F|D) ...)
+(Mul64uhilo ...) => (MULVU ...)
+(Select0 (Mul64uover x y)) => (Select1 <typ.UInt64> (MULVU x y))
+(Select1 (Mul64uover x y)) => (SGTU <typ.Bool> (Select0 <typ.UInt64> (MULVU x y)) (MOVVconst <typ.UInt64> [0]))
+
+(Hmul64 x y) => (Select0 (MULV x y))
+(Hmul64u x y) => (Select0 (MULVU x y))
+(Hmul32 x y) => (SRAVconst (Select1 <typ.Int64> (MULV (SignExt32to64 x) (SignExt32to64 y))) [32])
+(Hmul32u x y) => (SRLVconst (Select1 <typ.UInt64> (MULVU (ZeroExt32to64 x) (ZeroExt32to64 y))) [32])
+
+(Div64 x y) => (Select1 (DIVV x y))
+(Div64u x y) => (Select1 (DIVVU x y))
+(Div32 x y) => (Select1 (DIVV (SignExt32to64 x) (SignExt32to64 y)))
+(Div32u x y) => (Select1 (DIVVU (ZeroExt32to64 x) (ZeroExt32to64 y)))
+(Div16 x y) => (Select1 (DIVV (SignExt16to64 x) (SignExt16to64 y)))
+(Div16u x y) => (Select1 (DIVVU (ZeroExt16to64 x) (ZeroExt16to64 y)))
+(Div8 x y) => (Select1 (DIVV (SignExt8to64 x) (SignExt8to64 y)))
+(Div8u x y) => (Select1 (DIVVU (ZeroExt8to64 x) (ZeroExt8to64 y)))
+(Div(32|64)F ...) => (DIV(F|D) ...)
+
+(Mod64 x y) => (Select0 (DIVV x y))
+(Mod64u x y) => (Select0 (DIVVU x y))
+(Mod32 x y) => (Select0 (DIVV (SignExt32to64 x) (SignExt32to64 y)))
+(Mod32u x y) => (Select0 (DIVVU (ZeroExt32to64 x) (ZeroExt32to64 y)))
+(Mod16 x y) => (Select0 (DIVV (SignExt16to64 x) (SignExt16to64 y)))
+(Mod16u x y) => (Select0 (DIVVU (ZeroExt16to64 x) (ZeroExt16to64 y)))
+(Mod8 x y) => (Select0 (DIVV (SignExt8to64 x) (SignExt8to64 y)))
+(Mod8u x y) => (Select0 (DIVVU (ZeroExt8to64 x) (ZeroExt8to64 y)))
+
+// (x + y) / 2 with x>=y => (x - y) / 2 + y
+(Avg64u <t> x y) => (ADDV (SRLVconst <t> (SUBV <t> x y) [1]) y)
+
+(And(64|32|16|8) ...) => (AND ...)
+(Or(64|32|16|8) ...) => (OR ...)
+(Xor(64|32|16|8) ...) => (XOR ...)
+
+// shifts
+// hardware instruction uses only the low 6 bits of the shift
+// we compare to 64 to ensure Go semantics for large shifts
+(Lsh64x64 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SLLV <t> x y))
+(Lsh64x32 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SLLV <t> x (ZeroExt32to64 y)))
+(Lsh64x16 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SLLV <t> x (ZeroExt16to64 y)))
+(Lsh64x8  <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SLLV <t> x (ZeroExt8to64  y)))
+
+(Lsh32x64 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SLLV <t> x y))
+(Lsh32x32 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SLLV <t> x (ZeroExt32to64 y)))
+(Lsh32x16 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SLLV <t> x (ZeroExt16to64 y)))
+(Lsh32x8  <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SLLV <t> x (ZeroExt8to64  y)))
+
+(Lsh16x64 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SLLV <t> x y))
+(Lsh16x32 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SLLV <t> x (ZeroExt32to64 y)))
+(Lsh16x16 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SLLV <t> x (ZeroExt16to64 y)))
+(Lsh16x8  <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SLLV <t> x (ZeroExt8to64  y)))
+
+(Lsh8x64 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SLLV <t> x y))
+(Lsh8x32 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SLLV <t> x (ZeroExt32to64 y)))
+(Lsh8x16 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SLLV <t> x (ZeroExt16to64 y)))
+(Lsh8x8  <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SLLV <t> x (ZeroExt8to64  y)))
+
+(Rsh64Ux64 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SRLV <t> x y))
+(Rsh64Ux32 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SRLV <t> x (ZeroExt32to64 y)))
+(Rsh64Ux16 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SRLV <t> x (ZeroExt16to64 y)))
+(Rsh64Ux8  <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SRLV <t> x (ZeroExt8to64  y)))
+
+(Rsh32Ux64 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SRLV <t> (ZeroExt32to64 x) y))
+(Rsh32Ux32 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SRLV <t> (ZeroExt32to64 x) (ZeroExt32to64 y)))
+(Rsh32Ux16 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SRLV <t> (ZeroExt32to64 x) (ZeroExt16to64 y)))
+(Rsh32Ux8  <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SRLV <t> (ZeroExt32to64 x) (ZeroExt8to64  y)))
+
+(Rsh16Ux64 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SRLV <t> (ZeroExt16to64 x) y))
+(Rsh16Ux32 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SRLV <t> (ZeroExt16to64 x) (ZeroExt32to64 y)))
+(Rsh16Ux16 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SRLV <t> (ZeroExt16to64 x) (ZeroExt16to64 y)))
+(Rsh16Ux8  <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SRLV <t> (ZeroExt16to64 x) (ZeroExt8to64  y)))
+
+(Rsh8Ux64 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SRLV <t> (ZeroExt8to64 x) y))
+(Rsh8Ux32 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SRLV <t> (ZeroExt8to64 x) (ZeroExt32to64 y)))
+(Rsh8Ux16 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SRLV <t> (ZeroExt8to64 x) (ZeroExt16to64 y)))
+(Rsh8Ux8  <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SRLV <t> (ZeroExt8to64 x) (ZeroExt8to64  y)))
+
+(Rsh64x64 <t> x y) => (SRAV x (OR <t> (NEGV <t> (SGTU y (MOVVconst <typ.UInt64> [63]))) y))
+(Rsh64x32 <t> x y) => (SRAV x (OR <t> (NEGV <t> (SGTU (ZeroExt32to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt32to64 y)))
+(Rsh64x16 <t> x y) => (SRAV x (OR <t> (NEGV <t> (SGTU (ZeroExt16to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt16to64 y)))
+(Rsh64x8  <t> x y) => (SRAV x (OR <t> (NEGV <t> (SGTU (ZeroExt8to64  y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt8to64  y)))
+
+(Rsh32x64 <t> x y) => (SRAV (SignExt32to64 x) (OR <t> (NEGV <t> (SGTU y (MOVVconst <typ.UInt64> [63]))) y))
+(Rsh32x32 <t> x y) => (SRAV (SignExt32to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt32to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt32to64 y)))
+(Rsh32x16 <t> x y) => (SRAV (SignExt32to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt16to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt16to64 y)))
+(Rsh32x8  <t> x y) => (SRAV (SignExt32to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt8to64  y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt8to64  y)))
+
+(Rsh16x64 <t> x y) => (SRAV (SignExt16to64 x) (OR <t> (NEGV <t> (SGTU y (MOVVconst <typ.UInt64> [63]))) y))
+(Rsh16x32 <t> x y) => (SRAV (SignExt16to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt32to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt32to64 y)))
+(Rsh16x16 <t> x y) => (SRAV (SignExt16to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt16to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt16to64 y)))
+(Rsh16x8  <t> x y) => (SRAV (SignExt16to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt8to64  y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt8to64  y)))
+
+(Rsh8x64 <t> x y) => (SRAV (SignExt8to64 x) (OR <t> (NEGV <t> (SGTU y (MOVVconst <typ.UInt64> [63]))) y))
+(Rsh8x32 <t> x y) => (SRAV (SignExt8to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt32to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt32to64 y)))
+(Rsh8x16 <t> x y) => (SRAV (SignExt8to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt16to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt16to64 y)))
+(Rsh8x8  <t> x y) => (SRAV (SignExt8to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt8to64  y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt8to64  y)))
+
+// rotates
+(RotateLeft8 <t> x (MOVVconst [c])) => (Or8 (Lsh8x64 <t> x (MOVVconst [c&7])) (Rsh8Ux64 <t> x (MOVVconst [-c&7])))
+(RotateLeft16 <t> x (MOVVconst [c])) => (Or16 (Lsh16x64 <t> x (MOVVconst [c&15])) (Rsh16Ux64 <t> x (MOVVconst [-c&15])))
+(RotateLeft32 <t> x (MOVVconst [c])) => (Or32 (Lsh32x64 <t> x (MOVVconst [c&31])) (Rsh32Ux64 <t> x (MOVVconst [-c&31])))
+(RotateLeft64 <t> x (MOVVconst [c])) => (Or64 (Lsh64x64 <t> x (MOVVconst [c&63])) (Rsh64Ux64 <t> x (MOVVconst [-c&63])))
+
+// unary ops
+(Neg(64|32|16|8) ...) => (NEGV ...)
+(Neg(32|64)F ...) => (NEG(F|D) ...)
+
+(Com(64|32|16|8) x) => (NOR (MOVVconst [0]) x)
+
+(Sqrt ...) => (SQRTD ...)
+(Sqrt32 ...) => (SQRTF ...)
+
+// boolean ops -- booleans are represented with 0=false, 1=true
+(AndB ...) => (AND ...)
+(OrB ...) => (OR ...)
+(EqB x y) => (XOR (MOVVconst [1]) (XOR <typ.Bool> x y))
+(NeqB ...) => (XOR ...)
+(Not x) => (XORconst [1] x)
+
+// constants
+(Const(64|32|16|8) [val]) => (MOVVconst [int64(val)])
+(Const(32|64)F [val]) => (MOV(F|D)const [float64(val)])
+(ConstNil) => (MOVVconst [0])
+(ConstBool [t]) => (MOVVconst [int64(b2i(t))])
+
+(Slicemask <t> x) => (SRAVconst (NEGV <t> x) [63])
+
+// truncations
+// Because we ignore high parts of registers, truncates are just copies.
+(Trunc16to8 ...) => (Copy ...)
+(Trunc32to8 ...) => (Copy ...)
+(Trunc32to16 ...) => (Copy ...)
+(Trunc64to8 ...) => (Copy ...)
+(Trunc64to16 ...) => (Copy ...)
+(Trunc64to32 ...) => (Copy ...)
+
+// Zero-/Sign-extensions
+(ZeroExt8to16 ...) => (MOVBUreg ...)
+(ZeroExt8to32 ...) => (MOVBUreg ...)
+(ZeroExt16to32 ...) => (MOVHUreg ...)
+(ZeroExt8to64 ...) => (MOVBUreg ...)
+(ZeroExt16to64 ...) => (MOVHUreg ...)
+(ZeroExt32to64 ...) => (MOVWUreg ...)
+
+(SignExt8to16 ...) => (MOVBreg ...)
+(SignExt8to32 ...) => (MOVBreg ...)
+(SignExt16to32 ...) => (MOVHreg ...)
+(SignExt8to64 ...) => (MOVBreg ...)
+(SignExt16to64 ...) => (MOVHreg ...)
+(SignExt32to64 ...) => (MOVWreg ...)
+
+// float <=> int conversion
+(Cvt32to32F ...) => (MOVWF ...)
+(Cvt32to64F ...) => (MOVWD ...)
+(Cvt64to32F ...) => (MOVVF ...)
+(Cvt64to64F ...) => (MOVVD ...)
+(Cvt32Fto32 ...) => (TRUNCFW ...)
+(Cvt64Fto32 ...) => (TRUNCDW ...)
+(Cvt32Fto64 ...) => (TRUNCFV ...)
+(Cvt64Fto64 ...) => (TRUNCDV ...)
+(Cvt32Fto64F ...) => (MOVFD ...)
+(Cvt64Fto32F ...) => (MOVDF ...)
+
+(CvtBoolToUint8 ...) => (Copy ...)
+
+(Round(32|64)F ...) => (Copy ...)
+
+// comparisons
+(Eq8 x y)  => (SGTU (MOVVconst [1]) (XOR (ZeroExt8to64 x) (ZeroExt8to64 y)))
+(Eq16 x y) => (SGTU (MOVVconst [1]) (XOR (ZeroExt16to64 x) (ZeroExt16to64 y)))
+(Eq32 x y) => (SGTU (MOVVconst [1]) (XOR (ZeroExt32to64 x) (ZeroExt32to64 y)))
+(Eq64 x y) => (SGTU (MOVVconst [1]) (XOR x y))
+(EqPtr x y) => (SGTU (MOVVconst [1]) (XOR x y))
+(Eq(32|64)F x y) => (FPFlagTrue (CMPEQ(F|D) x y))
+
+(Neq8 x y)  => (SGTU (XOR (ZeroExt8to64 x) (ZeroExt8to64 y)) (MOVVconst [0]))
+(Neq16 x y) => (SGTU (XOR (ZeroExt16to32 x) (ZeroExt16to64 y)) (MOVVconst [0]))
+(Neq32 x y) => (SGTU (XOR (ZeroExt32to64 x) (ZeroExt32to64 y)) (MOVVconst [0]))
+(Neq64 x y) => (SGTU (XOR x y) (MOVVconst [0]))
+(NeqPtr x y) => (SGTU (XOR x y) (MOVVconst [0]))
+(Neq(32|64)F x y) => (FPFlagFalse (CMPEQ(F|D) x y))
+
+(Less8 x y)  => (SGT (SignExt8to64 y) (SignExt8to64 x))
+(Less16 x y) => (SGT (SignExt16to64 y) (SignExt16to64 x))
+(Less32 x y) => (SGT (SignExt32to64 y) (SignExt32to64 x))
+(Less64 x y) => (SGT y x)
+(Less(32|64)F x y) => (FPFlagTrue (CMPGT(F|D) y x)) // reverse operands to work around NaN
+
+(Less8U x y)  => (SGTU (ZeroExt8to64 y) (ZeroExt8to64 x))
+(Less16U x y) => (SGTU (ZeroExt16to64 y) (ZeroExt16to64 x))
+(Less32U x y) => (SGTU (ZeroExt32to64 y) (ZeroExt32to64 x))
+(Less64U x y) => (SGTU y x)
+
+(Leq8 x y)  => (XOR (MOVVconst [1]) (SGT (SignExt8to64 x) (SignExt8to64 y)))
+(Leq16 x y) => (XOR (MOVVconst [1]) (SGT (SignExt16to64 x) (SignExt16to64 y)))
+(Leq32 x y) => (XOR (MOVVconst [1]) (SGT (SignExt32to64 x) (SignExt32to64 y)))
+(Leq64 x y) => (XOR (MOVVconst [1]) (SGT x y))
+(Leq(32|64)F x y) => (FPFlagTrue (CMPGE(F|D) y x)) // reverse operands to work around NaN
+
+(Leq8U x y)  => (XOR (MOVVconst [1]) (SGTU (ZeroExt8to64 x) (ZeroExt8to64 y)))
+(Leq16U x y) => (XOR (MOVVconst [1]) (SGTU (ZeroExt16to64 x) (ZeroExt16to64 y)))
+(Leq32U x y) => (XOR (MOVVconst [1]) (SGTU (ZeroExt32to64 x) (ZeroExt32to64 y)))
+(Leq64U x y) => (XOR (MOVVconst [1]) (SGTU x y))
+
+(OffPtr [off] ptr:(SP)) && is32Bit(off) => (MOVVaddr [int32(off)] ptr)
+(OffPtr [off] ptr) => (ADDVconst [off] ptr)
+
+(Addr {sym} base) => (MOVVaddr {sym} base)
+(LocalAddr {sym} base _) => (MOVVaddr {sym} base)
+
+// loads
+(Load <t> ptr mem) && t.IsBoolean() => (MOVBUload ptr mem)
+(Load <t> ptr mem) && (is8BitInt(t) && isSigned(t)) => (MOVBload ptr mem)
+(Load <t> ptr mem) && (is8BitInt(t) && !isSigned(t)) => (MOVBUload ptr mem)
+(Load <t> ptr mem) && (is16BitInt(t) && isSigned(t)) => (MOVHload ptr mem)
+(Load <t> ptr mem) && (is16BitInt(t) && !isSigned(t)) => (MOVHUload ptr mem)
+(Load <t> ptr mem) && (is32BitInt(t) && isSigned(t)) => (MOVWload ptr mem)
+(Load <t> ptr mem) && (is32BitInt(t) && !isSigned(t)) => (MOVWUload ptr mem)
+(Load <t> ptr mem) && (is64BitInt(t) || isPtr(t)) => (MOVVload ptr mem)
+(Load <t> ptr mem) && is32BitFloat(t) => (MOVFload ptr mem)
+(Load <t> ptr mem) && is64BitFloat(t) => (MOVDload ptr mem)
+
+// stores
+(Store {t} ptr val mem) && t.Size() == 1 => (MOVBstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 2 => (MOVHstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 4 && !is32BitFloat(val.Type) => (MOVWstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 8 && !is64BitFloat(val.Type) => (MOVVstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 4 && is32BitFloat(val.Type) => (MOVFstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 8 && is64BitFloat(val.Type) => (MOVDstore ptr val mem)
+
+// zeroing
+(Zero [0] _ mem) => mem
+(Zero [1] ptr mem) => (MOVBstore ptr (MOVVconst [0]) mem)
+(Zero [2] {t} ptr mem) && t.Alignment()%2 == 0 =>
+	(MOVHstore ptr (MOVVconst [0]) mem)
+(Zero [2] ptr mem) =>
+	(MOVBstore [1] ptr (MOVVconst [0])
+		(MOVBstore [0] ptr (MOVVconst [0]) mem))
+(Zero [4] {t} ptr mem) && t.Alignment()%4 == 0 =>
+	(MOVWstore ptr (MOVVconst [0]) mem)
+(Zero [4] {t} ptr mem) && t.Alignment()%2 == 0 =>
+	(MOVHstore [2] ptr (MOVVconst [0])
+		(MOVHstore [0] ptr (MOVVconst [0]) mem))
+(Zero [4] ptr mem) =>
+	(MOVBstore [3] ptr (MOVVconst [0])
+		(MOVBstore [2] ptr (MOVVconst [0])
+			(MOVBstore [1] ptr (MOVVconst [0])
+				(MOVBstore [0] ptr (MOVVconst [0]) mem))))
+(Zero [8] {t} ptr mem) && t.Alignment()%8 == 0 =>
+	(MOVVstore ptr (MOVVconst [0]) mem)
+(Zero [8] {t} ptr mem) && t.Alignment()%4 == 0 =>
+	(MOVWstore [4] ptr (MOVVconst [0])
+		(MOVWstore [0] ptr (MOVVconst [0]) mem))
+(Zero [8] {t} ptr mem) && t.Alignment()%2 == 0 =>
+	(MOVHstore [6] ptr (MOVVconst [0])
+		(MOVHstore [4] ptr (MOVVconst [0])
+			(MOVHstore [2] ptr (MOVVconst [0])
+				(MOVHstore [0] ptr (MOVVconst [0]) mem))))
+
+(Zero [3] ptr mem) =>
+	(MOVBstore [2] ptr (MOVVconst [0])
+		(MOVBstore [1] ptr (MOVVconst [0])
+			(MOVBstore [0] ptr (MOVVconst [0]) mem)))
+(Zero [6] {t} ptr mem) && t.Alignment()%2 == 0 =>
+	(MOVHstore [4] ptr (MOVVconst [0])
+		(MOVHstore [2] ptr (MOVVconst [0])
+			(MOVHstore [0] ptr (MOVVconst [0]) mem)))
+(Zero [12] {t} ptr mem) && t.Alignment()%4 == 0 =>
+	(MOVWstore [8] ptr (MOVVconst [0])
+		(MOVWstore [4] ptr (MOVVconst [0])
+			(MOVWstore [0] ptr (MOVVconst [0]) mem)))
+(Zero [16] {t} ptr mem) && t.Alignment()%8 == 0 =>
+	(MOVVstore [8] ptr (MOVVconst [0])
+		(MOVVstore [0] ptr (MOVVconst [0]) mem))
+(Zero [24] {t} ptr mem) && t.Alignment()%8 == 0 =>
+	(MOVVstore [16] ptr (MOVVconst [0])
+		(MOVVstore [8] ptr (MOVVconst [0])
+			(MOVVstore [0] ptr (MOVVconst [0]) mem)))
+
+// medium zeroing uses a duff device
+// 8, and 128 are magic constants, see runtime/mkduff.go
+(Zero [s] {t} ptr mem)
+	&& s%8 == 0 && s > 24 && s <= 8*128
+	&& t.Alignment()%8 == 0 && !config.noDuffDevice =>
+	(DUFFZERO [8 * (128 - s/8)] ptr mem)
+
+// large or unaligned zeroing uses a loop
+(Zero [s] {t} ptr mem)
+	&& (s > 8*128 || config.noDuffDevice) || t.Alignment()%8 != 0 =>
+	(LoweredZero [t.Alignment()]
+		ptr
+		(ADDVconst <ptr.Type> ptr [s-moveSize(t.Alignment(), config)])
+		mem)
+
+// moves
+(Move [0] _ _ mem) => mem
+(Move [1] dst src mem) => (MOVBstore dst (MOVBload src mem) mem)
+(Move [2] {t} dst src mem) && t.Alignment()%2 == 0 =>
+	(MOVHstore dst (MOVHload src mem) mem)
+(Move [2] dst src mem) =>
+	(MOVBstore [1] dst (MOVBload [1] src mem)
+		(MOVBstore dst (MOVBload src mem) mem))
+(Move [4] {t} dst src mem) && t.Alignment()%4 == 0 =>
+	(MOVWstore dst (MOVWload src mem) mem)
+(Move [4] {t} dst src mem) && t.Alignment()%2 == 0 =>
+	(MOVHstore [2] dst (MOVHload [2] src mem)
+		(MOVHstore dst (MOVHload src mem) mem))
+(Move [4] dst src mem) =>
+	(MOVBstore [3] dst (MOVBload [3] src mem)
+		(MOVBstore [2] dst (MOVBload [2] src mem)
+			(MOVBstore [1] dst (MOVBload [1] src mem)
+				(MOVBstore dst (MOVBload src mem) mem))))
+(Move [8] {t} dst src mem) && t.Alignment()%8 == 0 =>
+	(MOVVstore dst (MOVVload src mem) mem)
+(Move [8] {t} dst src mem) && t.Alignment()%4 == 0 =>
+	(MOVWstore [4] dst (MOVWload [4] src mem)
+		(MOVWstore dst (MOVWload src mem) mem))
+(Move [8] {t} dst src mem) && t.Alignment()%2 == 0 =>
+	(MOVHstore [6] dst (MOVHload [6] src mem)
+		(MOVHstore [4] dst (MOVHload [4] src mem)
+			(MOVHstore [2] dst (MOVHload [2] src mem)
+				(MOVHstore dst (MOVHload src mem) mem))))
+
+(Move [3] dst src mem) =>
+	(MOVBstore [2] dst (MOVBload [2] src mem)
+		(MOVBstore [1] dst (MOVBload [1] src mem)
+			(MOVBstore dst (MOVBload src mem) mem)))
+(Move [6] {t} dst src mem) && t.Alignment()%2 == 0 =>
+	(MOVHstore [4] dst (MOVHload [4] src mem)
+		(MOVHstore [2] dst (MOVHload [2] src mem)
+			(MOVHstore dst (MOVHload src mem) mem)))
+(Move [12] {t} dst src mem) && t.Alignment()%4 == 0 =>
+	(MOVWstore [8] dst (MOVWload [8] src mem)
+		(MOVWstore [4] dst (MOVWload [4] src mem)
+			(MOVWstore dst (MOVWload src mem) mem)))
+(Move [16] {t} dst src mem) && t.Alignment()%8 == 0 =>
+	(MOVVstore [8] dst (MOVVload [8] src mem)
+		(MOVVstore dst (MOVVload src mem) mem))
+(Move [24] {t} dst src mem) && t.Alignment()%8 == 0 =>
+	(MOVVstore [16] dst (MOVVload [16] src mem)
+		(MOVVstore [8] dst (MOVVload [8] src mem)
+			(MOVVstore dst (MOVVload src mem) mem)))
+
+// medium move uses a duff device
+(Move [s] {t} dst src mem)
+	&& s%8 == 0 && s >= 24 && s <= 8*128 && t.Alignment()%8 == 0
+	&& !config.noDuffDevice && logLargeCopy(v, s)  =>
+	(DUFFCOPY [16 * (128 - s/8)] dst src mem)
+// 16 and 128 are magic constants.  16 is the number of bytes to encode:
+//	MOVV	(R1), R23
+//	ADDV	$8, R1
+//	MOVV	R23, (R2)
+//	ADDV	$8, R2
+// and 128 is the number of such blocks. See runtime/duff_mips64.s:duffcopy.
+
+// large or unaligned move uses a loop
+(Move [s] {t} dst src mem)
+	&& s > 24 && logLargeCopy(v, s) || t.Alignment()%8 != 0 =>
+	(LoweredMove [t.Alignment()]
+		dst
+		src
+		(ADDVconst <src.Type> src [s-moveSize(t.Alignment(), config)])
+		mem)
+
+// calls
+(StaticCall ...) => (CALLstatic ...)
+(ClosureCall ...) => (CALLclosure ...)
+(InterCall ...) => (CALLinter ...)
+(TailCall ...) => (CALLtail ...)
+
+// atomic intrinsics
+(AtomicLoad(8|32|64) ...) => (LoweredAtomicLoad(8|32|64) ...)
+(AtomicLoadPtr ...) => (LoweredAtomicLoad64 ...)
+
+(AtomicStore(8|32|64) ...) => (LoweredAtomicStore(8|32|64) ...)
+(AtomicStorePtrNoWB ...) => (LoweredAtomicStore64 ...)
+
+(AtomicExchange(32|64) ...) => (LoweredAtomicExchange(32|64) ...)
+
+(AtomicAdd(32|64) ...) => (LoweredAtomicAdd(32|64) ...)
+
+(AtomicCompareAndSwap32 ptr old new mem) => (LoweredAtomicCas32 ptr (SignExt32to64 old) new mem)
+(AtomicCompareAndSwap64 ...) => (LoweredAtomicCas64 ...)
+
+// checks
+(NilCheck ...) => (LoweredNilCheck ...)
+(IsNonNil ptr) => (SGTU ptr (MOVVconst [0]))
+(IsInBounds idx len) => (SGTU len idx)
+(IsSliceInBounds idx len) => (XOR (MOVVconst [1]) (SGTU idx len))
+
+// pseudo-ops
+(GetClosurePtr ...) => (LoweredGetClosurePtr ...)
+(GetCallerSP ...) => (LoweredGetCallerSP ...)
+(GetCallerPC ...) => (LoweredGetCallerPC ...)
+
+(If cond yes no) => (NE cond yes no)
+
+// Write barrier.
+(WB ...) => (LoweredWB ...)
+
+(PanicBounds [kind] x y mem) && boundsABI(kind) == 0 => (LoweredPanicBoundsA [kind] x y mem)
+(PanicBounds [kind] x y mem) && boundsABI(kind) == 1 => (LoweredPanicBoundsB [kind] x y mem)
+(PanicBounds [kind] x y mem) && boundsABI(kind) == 2 => (LoweredPanicBoundsC [kind] x y mem)
+
+// Optimizations
+
+// Absorb boolean tests into block
+(NE (FPFlagTrue cmp) yes no) => (FPT cmp yes no)
+(NE (FPFlagFalse cmp) yes no) => (FPF cmp yes no)
+(EQ (FPFlagTrue cmp) yes no) => (FPF cmp yes no)
+(EQ (FPFlagFalse cmp) yes no) => (FPT cmp yes no)
+(NE (XORconst [1] cmp:(SGT _ _)) yes no) => (EQ cmp yes no)
+(NE (XORconst [1] cmp:(SGTU _ _)) yes no) => (EQ cmp yes no)
+(NE (XORconst [1] cmp:(SGTconst _)) yes no) => (EQ cmp yes no)
+(NE (XORconst [1] cmp:(SGTUconst _)) yes no) => (EQ cmp yes no)
+(EQ (XORconst [1] cmp:(SGT _ _)) yes no) => (NE cmp yes no)
+(EQ (XORconst [1] cmp:(SGTU _ _)) yes no) => (NE cmp yes no)
+(EQ (XORconst [1] cmp:(SGTconst _)) yes no) => (NE cmp yes no)
+(EQ (XORconst [1] cmp:(SGTUconst _)) yes no) => (NE cmp yes no)
+(NE (SGTUconst [1] x) yes no) => (EQ x yes no)
+(EQ (SGTUconst [1] x) yes no) => (NE x yes no)
+(NE (SGTU x (MOVVconst [0])) yes no) => (NE x yes no)
+(EQ (SGTU x (MOVVconst [0])) yes no) => (EQ x yes no)
+(NE (SGTconst [0] x) yes no) => (LTZ x yes no)
+(EQ (SGTconst [0] x) yes no) => (GEZ x yes no)
+(NE (SGT x (MOVVconst [0])) yes no) => (GTZ x yes no)
+(EQ (SGT x (MOVVconst [0])) yes no) => (LEZ x yes no)
+
+// fold offset into address
+(ADDVconst [off1] (MOVVaddr [off2] {sym} ptr)) && is32Bit(off1+int64(off2)) => (MOVVaddr [int32(off1)+int32(off2)] {sym} ptr)
+
+// fold address into load/store
+(MOVBload  [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVBload  [off1+int32(off2)] {sym} ptr mem)
+(MOVBUload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVBUload [off1+int32(off2)] {sym} ptr mem)
+(MOVHload  [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVHload  [off1+int32(off2)] {sym} ptr mem)
+(MOVHUload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVHUload [off1+int32(off2)] {sym} ptr mem)
+(MOVWload  [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVWload  [off1+int32(off2)] {sym} ptr mem)
+(MOVWUload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVWUload [off1+int32(off2)] {sym} ptr mem)
+(MOVVload  [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVVload  [off1+int32(off2)] {sym} ptr mem)
+(MOVFload  [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVFload  [off1+int32(off2)] {sym} ptr mem)
+(MOVDload  [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVDload  [off1+int32(off2)] {sym} ptr mem)
+
+(MOVBstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVBstore [off1+int32(off2)] {sym} ptr val mem)
+(MOVHstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVHstore [off1+int32(off2)] {sym} ptr val mem)
+(MOVWstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVWstore [off1+int32(off2)] {sym} ptr val mem)
+(MOVVstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVVstore [off1+int32(off2)] {sym} ptr val mem)
+(MOVFstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVFstore [off1+int32(off2)] {sym} ptr val mem)
+(MOVDstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVDstore [off1+int32(off2)] {sym} ptr val mem)
+(MOVBstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVBstorezero [off1+int32(off2)] {sym} ptr mem)
+(MOVHstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVHstorezero [off1+int32(off2)] {sym} ptr mem)
+(MOVWstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVWstorezero [off1+int32(off2)] {sym} ptr mem)
+(MOVVstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVVstorezero [off1+int32(off2)] {sym} ptr mem)
+
+(MOVBload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVBload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
+(MOVBUload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVBUload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
+(MOVHload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVHload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
+(MOVHUload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVHUload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
+(MOVWload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVWload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
+(MOVWUload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVWUload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
+(MOVVload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVVload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
+(MOVFload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVFload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
+(MOVDload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVDload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
+
+(MOVBstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVBstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem)
+(MOVHstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVHstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem)
+(MOVWstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVWstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem)
+(MOVVstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVVstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem)
+(MOVFstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVFstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem)
+(MOVDstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVDstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem)
+(MOVBstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVBstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
+(MOVHstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVHstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
+(MOVWstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVWstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
+(MOVVstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVVstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
+
+// store zero
+(MOVBstore [off] {sym} ptr (MOVVconst [0]) mem) => (MOVBstorezero [off] {sym} ptr mem)
+(MOVHstore [off] {sym} ptr (MOVVconst [0]) mem) => (MOVHstorezero [off] {sym} ptr mem)
+(MOVWstore [off] {sym} ptr (MOVVconst [0]) mem) => (MOVWstorezero [off] {sym} ptr mem)
+(MOVVstore [off] {sym} ptr (MOVVconst [0]) mem) => (MOVVstorezero [off] {sym} ptr mem)
+
+// don't extend after proper load
+(MOVBreg x:(MOVBload _ _)) => (MOVVreg x)
+(MOVBUreg x:(MOVBUload _ _)) => (MOVVreg x)
+(MOVHreg x:(MOVBload _ _)) => (MOVVreg x)
+(MOVHreg x:(MOVBUload _ _)) => (MOVVreg x)
+(MOVHreg x:(MOVHload _ _)) => (MOVVreg x)
+(MOVHUreg x:(MOVBUload _ _)) => (MOVVreg x)
+(MOVHUreg x:(MOVHUload _ _)) => (MOVVreg x)
+(MOVWreg x:(MOVBload _ _)) => (MOVVreg x)
+(MOVWreg x:(MOVBUload _ _)) => (MOVVreg x)
+(MOVWreg x:(MOVHload _ _)) => (MOVVreg x)
+(MOVWreg x:(MOVHUload _ _)) => (MOVVreg x)
+(MOVWreg x:(MOVWload _ _)) => (MOVVreg x)
+(MOVWUreg x:(MOVBUload _ _)) => (MOVVreg x)
+(MOVWUreg x:(MOVHUload _ _)) => (MOVVreg x)
+(MOVWUreg x:(MOVWUload _ _)) => (MOVVreg x)
+
+// fold double extensions
+(MOVBreg x:(MOVBreg _)) => (MOVVreg x)
+(MOVBUreg x:(MOVBUreg _)) => (MOVVreg x)
+(MOVHreg x:(MOVBreg _)) => (MOVVreg x)
+(MOVHreg x:(MOVBUreg _)) => (MOVVreg x)
+(MOVHreg x:(MOVHreg _)) => (MOVVreg x)
+(MOVHUreg x:(MOVBUreg _)) => (MOVVreg x)
+(MOVHUreg x:(MOVHUreg _)) => (MOVVreg x)
+(MOVWreg x:(MOVBreg _)) => (MOVVreg x)
+(MOVWreg x:(MOVBUreg _)) => (MOVVreg x)
+(MOVWreg x:(MOVHreg _)) => (MOVVreg x)
+(MOVWreg x:(MOVWreg _)) => (MOVVreg x)
+(MOVWUreg x:(MOVBUreg _)) => (MOVVreg x)
+(MOVWUreg x:(MOVHUreg _)) => (MOVVreg x)
+(MOVWUreg x:(MOVWUreg _)) => (MOVVreg x)
+
+// don't extend before store
+(MOVBstore [off] {sym} ptr (MOVBreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr (MOVBUreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr (MOVHreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr (MOVHUreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr (MOVWreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr (MOVWUreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
+(MOVHstore [off] {sym} ptr (MOVHreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
+(MOVHstore [off] {sym} ptr (MOVHUreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
+(MOVHstore [off] {sym} ptr (MOVWreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
+(MOVHstore [off] {sym} ptr (MOVWUreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
+(MOVWstore [off] {sym} ptr (MOVWreg x) mem) => (MOVWstore [off] {sym} ptr x mem)
+(MOVWstore [off] {sym} ptr (MOVWUreg x) mem) => (MOVWstore [off] {sym} ptr x mem)
+
+// if a register move has only 1 use, just use the same register without emitting instruction
+// MOVVnop doesn't emit instruction, only for ensuring the type.
+(MOVVreg x) && x.Uses == 1 => (MOVVnop x)
+
+// TODO: we should be able to get rid of MOVVnop all together.
+// But for now, this is enough to get rid of lots of them.
+(MOVVnop (MOVVconst [c])) => (MOVVconst [c])
+
+// fold constant into arithmetic ops
+(ADDV x (MOVVconst [c])) && is32Bit(c) => (ADDVconst [c] x)
+(SUBV x (MOVVconst [c])) && is32Bit(c) => (SUBVconst [c] x)
+(AND x (MOVVconst [c])) && is32Bit(c) => (ANDconst [c] x)
+(OR  x (MOVVconst [c])) && is32Bit(c) => (ORconst  [c] x)
+(XOR x (MOVVconst [c])) && is32Bit(c) => (XORconst [c] x)
+(NOR x (MOVVconst [c])) && is32Bit(c) => (NORconst [c] x)
+
+(SLLV _ (MOVVconst [c])) && uint64(c)>=64 => (MOVVconst [0])
+(SRLV _ (MOVVconst [c])) && uint64(c)>=64 => (MOVVconst [0])
+(SRAV x (MOVVconst [c])) && uint64(c)>=64 => (SRAVconst x [63])
+(SLLV x (MOVVconst [c])) => (SLLVconst x [c])
+(SRLV x (MOVVconst [c])) => (SRLVconst x [c])
+(SRAV x (MOVVconst [c])) => (SRAVconst x [c])
+
+(SGT  (MOVVconst [c]) x) && is32Bit(c) => (SGTconst  [c] x)
+(SGTU (MOVVconst [c]) x) && is32Bit(c) => (SGTUconst [c] x)
+
+// mul by constant
+(Select1 (MULVU x (MOVVconst [-1]))) => (NEGV x)
+(Select1 (MULVU _ (MOVVconst [0]))) => (MOVVconst [0])
+(Select1 (MULVU x (MOVVconst [1]))) => x
+(Select1 (MULVU x (MOVVconst [c]))) && isPowerOfTwo64(c) => (SLLVconst [log64(c)] x)
+
+// div by constant
+(Select1 (DIVVU x (MOVVconst [1]))) => x
+(Select1 (DIVVU x (MOVVconst [c]))) && isPowerOfTwo64(c) => (SRLVconst [log64(c)] x)
+(Select0 (DIVVU _ (MOVVconst [1]))) => (MOVVconst [0])                       // mod
+(Select0 (DIVVU x (MOVVconst [c]))) && isPowerOfTwo64(c) => (ANDconst [c-1] x) // mod
+
+// generic simplifications
+(ADDV x (NEGV y)) => (SUBV x y)
+(SUBV x x) => (MOVVconst [0])
+(SUBV (MOVVconst [0]) x) => (NEGV x)
+(AND x x) => x
+(OR  x x) => x
+(XOR x x) => (MOVVconst [0])
+
+// remove redundant *const ops
+(ADDVconst [0]  x) => x
+(SUBVconst [0]  x) => x
+(ANDconst [0]  _) => (MOVVconst [0])
+(ANDconst [-1] x) => x
+(ORconst  [0]  x) => x
+(ORconst  [-1] _) => (MOVVconst [-1])
+(XORconst [0]  x) => x
+(XORconst [-1] x) => (NORconst [0] x)
+
+// generic constant folding
+(ADDVconst [c] (MOVVconst [d]))  => (MOVVconst [c+d])
+(ADDVconst [c] (ADDVconst [d] x)) && is32Bit(c+d) => (ADDVconst [c+d] x)
+(ADDVconst [c] (SUBVconst [d] x)) && is32Bit(c-d) => (ADDVconst [c-d] x)
+(SUBVconst [c] (MOVVconst [d]))  => (MOVVconst [d-c])
+(SUBVconst [c] (SUBVconst [d] x)) && is32Bit(-c-d) => (ADDVconst [-c-d] x)
+(SUBVconst [c] (ADDVconst [d] x)) && is32Bit(-c+d) => (ADDVconst [-c+d] x)
+(SLLVconst [c] (MOVVconst [d]))  => (MOVVconst [d<<uint64(c)])
+(SRLVconst [c] (MOVVconst [d]))  => (MOVVconst [int64(uint64(d)>>uint64(c))])
+(SRAVconst [c] (MOVVconst [d]))  => (MOVVconst [d>>uint64(c)])
+(Select1 (MULVU (MOVVconst [c]) (MOVVconst [d]))) => (MOVVconst [c*d])
+(Select1 (DIVV  (MOVVconst [c]) (MOVVconst [d]))) && d != 0 => (MOVVconst [c/d])
+(Select1 (DIVVU (MOVVconst [c]) (MOVVconst [d]))) && d != 0 => (MOVVconst [int64(uint64(c)/uint64(d))])
+(Select0 (DIVV  (MOVVconst [c]) (MOVVconst [d]))) && d != 0 => (MOVVconst [c%d])   // mod
+(Select0 (DIVVU (MOVVconst [c]) (MOVVconst [d]))) && d != 0 => (MOVVconst [int64(uint64(c)%uint64(d))]) // mod
+(ANDconst [c] (MOVVconst [d])) => (MOVVconst [c&d])
+(ANDconst [c] (ANDconst [d] x)) => (ANDconst [c&d] x)
+(ORconst [c] (MOVVconst [d])) => (MOVVconst [c|d])
+(ORconst [c] (ORconst [d] x)) && is32Bit(c|d) => (ORconst [c|d] x)
+(XORconst [c] (MOVVconst [d])) => (MOVVconst [c^d])
+(XORconst [c] (XORconst [d] x)) && is32Bit(c^d) => (XORconst [c^d] x)
+(NORconst [c] (MOVVconst [d])) => (MOVVconst [^(c|d)])
+(NEGV (MOVVconst [c])) => (MOVVconst [-c])
+(MOVBreg  (MOVVconst [c])) => (MOVVconst [int64(int8(c))])
+(MOVBUreg (MOVVconst [c])) => (MOVVconst [int64(uint8(c))])
+(MOVHreg  (MOVVconst [c])) => (MOVVconst [int64(int16(c))])
+(MOVHUreg (MOVVconst [c])) => (MOVVconst [int64(uint16(c))])
+(MOVWreg  (MOVVconst [c])) => (MOVVconst [int64(int32(c))])
+(MOVWUreg (MOVVconst [c])) => (MOVVconst [int64(uint32(c))])
+(MOVVreg  (MOVVconst [c])) => (MOVVconst [c])
+(LoweredAtomicStore(32|64) ptr (MOVVconst [0]) mem) => (LoweredAtomicStorezero(32|64) ptr mem)
+(LoweredAtomicAdd32 ptr (MOVVconst [c]) mem) && is32Bit(c) => (LoweredAtomicAddconst32 [int32(c)] ptr mem)
+(LoweredAtomicAdd64 ptr (MOVVconst [c]) mem) && is32Bit(c) => (LoweredAtomicAddconst64 [c] ptr mem)
+
+// constant comparisons
+(SGTconst [c] (MOVVconst [d])) && c>d => (MOVVconst [1])
+(SGTconst [c] (MOVVconst [d])) && c<=d => (MOVVconst [0])
+(SGTUconst [c] (MOVVconst [d])) && uint64(c)>uint64(d) => (MOVVconst [1])
+(SGTUconst [c] (MOVVconst [d])) && uint64(c)<=uint64(d) => (MOVVconst [0])
+
+// other known comparisons
+(SGTconst [c] (MOVBreg _)) && 0x7f < c => (MOVVconst [1])
+(SGTconst [c] (MOVBreg _)) && c <= -0x80 => (MOVVconst [0])
+(SGTconst [c] (MOVBUreg _)) && 0xff < c => (MOVVconst [1])
+(SGTconst [c] (MOVBUreg _)) && c < 0 => (MOVVconst [0])
+(SGTUconst [c] (MOVBUreg _)) && 0xff < uint64(c) => (MOVVconst [1])
+(SGTconst [c] (MOVHreg _)) && 0x7fff < c => (MOVVconst [1])
+(SGTconst [c] (MOVHreg _)) && c <= -0x8000 => (MOVVconst [0])
+(SGTconst [c] (MOVHUreg _)) && 0xffff < c => (MOVVconst [1])
+(SGTconst [c] (MOVHUreg _)) && c < 0 => (MOVVconst [0])
+(SGTUconst [c] (MOVHUreg _)) && 0xffff < uint64(c) => (MOVVconst [1])
+(SGTconst [c] (MOVWUreg _)) && c < 0 => (MOVVconst [0])
+(SGTconst [c] (ANDconst [m] _)) && 0 <= m && m < c => (MOVVconst [1])
+(SGTUconst [c] (ANDconst [m] _)) && uint64(m) < uint64(c) => (MOVVconst [1])
+(SGTconst [c] (SRLVconst _ [d])) && 0 <= c && 0 < d && d <= 63 && 0xffffffffffffffff>>uint64(d) < uint64(c) => (MOVVconst [1])
+(SGTUconst [c] (SRLVconst _ [d])) && 0 < d && d <= 63 && 0xffffffffffffffff>>uint64(d) < uint64(c) => (MOVVconst [1])
+
+// absorb constants into branches
+(EQ  (MOVVconst [0]) yes no) => (First yes no)
+(EQ  (MOVVconst [c]) yes no) && c != 0 => (First no yes)
+(NE  (MOVVconst [0]) yes no) => (First no yes)
+(NE  (MOVVconst [c]) yes no) && c != 0 => (First yes no)
+(LTZ (MOVVconst [c]) yes no) && c <  0 => (First yes no)
+(LTZ (MOVVconst [c]) yes no) && c >= 0 => (First no yes)
+(LEZ (MOVVconst [c]) yes no) && c <= 0 => (First yes no)
+(LEZ (MOVVconst [c]) yes no) && c >  0 => (First no yes)
+(GTZ (MOVVconst [c]) yes no) && c >  0 => (First yes no)
+(GTZ (MOVVconst [c]) yes no) && c <= 0 => (First no yes)
+(GEZ (MOVVconst [c]) yes no) && c >= 0 => (First yes no)
+(GEZ (MOVVconst [c]) yes no) && c <  0 => (First no yes)
+
+// fold readonly sym load
+(MOVBload [off] {sym} (SB) _) && symIsRO(sym) => (MOVVconst [int64(read8(sym, int64(off)))])
+(MOVHload [off] {sym} (SB) _) && symIsRO(sym) => (MOVVconst [int64(read16(sym, int64(off), config.ctxt.Arch.ByteOrder))])
+(MOVWload [off] {sym} (SB) _) && symIsRO(sym) => (MOVVconst [int64(read32(sym, int64(off), config.ctxt.Arch.ByteOrder))])
+(MOVVload  [off] {sym} (SB) _) && symIsRO(sym) => (MOVVconst [int64(read64(sym, int64(off), config.ctxt.Arch.ByteOrder))])
diff --git a/src/cmd/compile/internal/ssa/_gen/MIPS64Ops.go b/src/cmd/compile/internal/ssa/_gen/MIPS64Ops.go
new file mode 100644
index 0000000..89c8772
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/_gen/MIPS64Ops.go
@@ -0,0 +1,482 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "strings"
+
+// Notes:
+//  - Integer types live in the low portion of registers. Upper portions are junk.
+//  - Boolean types use the low-order byte of a register. 0=false, 1=true.
+//    Upper bytes are junk.
+//  - *const instructions may use a constant larger than the instruction can encode.
+//    In this case the assembler expands to multiple instructions and uses tmp
+//    register (R23).
+
+// Suffixes encode the bit width of various instructions.
+// V (vlong)     = 64 bit
+// WU (word)     = 32 bit unsigned
+// W (word)      = 32 bit
+// H (half word) = 16 bit
+// HU            = 16 bit unsigned
+// B (byte)      = 8 bit
+// BU            = 8 bit unsigned
+// F (float)     = 32 bit float
+// D (double)    = 64 bit float
+
+// Note: registers not used in regalloc are not included in this list,
+// so that regmask stays within int64
+// Be careful when hand coding regmasks.
+var regNamesMIPS64 = []string{
+	"R0", // constant 0
+	"R1",
+	"R2",
+	"R3",
+	"R4",
+	"R5",
+	"R6",
+	"R7",
+	"R8",
+	"R9",
+	"R10",
+	"R11",
+	"R12",
+	"R13",
+	"R14",
+	"R15",
+	"R16",
+	"R17",
+	"R18",
+	"R19",
+	"R20",
+	"R21",
+	"R22",
+	// R23 = REGTMP not used in regalloc
+	"R24",
+	"R25",
+	// R26 reserved by kernel
+	// R27 reserved by kernel
+	// R28 = REGSB not used in regalloc
+	"SP",  // aka R29
+	"g",   // aka R30
+	"R31", // aka REGLINK
+
+	"F0",
+	"F1",
+	"F2",
+	"F3",
+	"F4",
+	"F5",
+	"F6",
+	"F7",
+	"F8",
+	"F9",
+	"F10",
+	"F11",
+	"F12",
+	"F13",
+	"F14",
+	"F15",
+	"F16",
+	"F17",
+	"F18",
+	"F19",
+	"F20",
+	"F21",
+	"F22",
+	"F23",
+	"F24",
+	"F25",
+	"F26",
+	"F27",
+	"F28",
+	"F29",
+	"F30",
+	"F31",
+
+	"HI", // high bits of multiplication
+	"LO", // low bits of multiplication
+
+	// If you add registers, update asyncPreempt in runtime.
+
+	// pseudo-registers
+	"SB",
+}
+
+func init() {
+	// Make map from reg names to reg integers.
+	if len(regNamesMIPS64) > 64 {
+		panic("too many registers")
+	}
+	num := map[string]int{}
+	for i, name := range regNamesMIPS64 {
+		num[name] = i
+	}
+	buildReg := func(s string) regMask {
+		m := regMask(0)
+		for _, r := range strings.Split(s, " ") {
+			if n, ok := num[r]; ok {
+				m |= regMask(1) << uint(n)
+				continue
+			}
+			panic("register " + r + " not found")
+		}
+		return m
+	}
+
+	// Common individual register masks
+	var (
+		gp         = buildReg("R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R31")
+		gpg        = gp | buildReg("g")
+		gpsp       = gp | buildReg("SP")
+		gpspg      = gpg | buildReg("SP")
+		gpspsbg    = gpspg | buildReg("SB")
+		fp         = buildReg("F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31")
+		lo         = buildReg("LO")
+		hi         = buildReg("HI")
+		callerSave = gp | fp | lo | hi | buildReg("g") // runtime.setg (and anything calling it) may clobber g
+		r1         = buildReg("R1")
+		r2         = buildReg("R2")
+		r3         = buildReg("R3")
+		r4         = buildReg("R4")
+	)
+	// Common regInfo
+	var (
+		gp01     = regInfo{inputs: nil, outputs: []regMask{gp}}
+		gp11     = regInfo{inputs: []regMask{gpg}, outputs: []regMask{gp}}
+		gp11sp   = regInfo{inputs: []regMask{gpspg}, outputs: []regMask{gp}}
+		gp21     = regInfo{inputs: []regMask{gpg, gpg}, outputs: []regMask{gp}}
+		gp2hilo  = regInfo{inputs: []regMask{gpg, gpg}, outputs: []regMask{hi, lo}}
+		gpload   = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{gp}}
+		gpstore  = regInfo{inputs: []regMask{gpspsbg, gpg}}
+		gpstore0 = regInfo{inputs: []regMask{gpspsbg}}
+		gpxchg   = regInfo{inputs: []regMask{gpspsbg, gpg}, outputs: []regMask{gp}}
+		gpcas    = regInfo{inputs: []regMask{gpspsbg, gpg, gpg}, outputs: []regMask{gp}}
+		fp01     = regInfo{inputs: nil, outputs: []regMask{fp}}
+		fp11     = regInfo{inputs: []regMask{fp}, outputs: []regMask{fp}}
+		//fp1flags  = regInfo{inputs: []regMask{fp}}
+		//fpgp      = regInfo{inputs: []regMask{fp}, outputs: []regMask{gp}}
+		//gpfp      = regInfo{inputs: []regMask{gp}, outputs: []regMask{fp}}
+		fp21      = regInfo{inputs: []regMask{fp, fp}, outputs: []regMask{fp}}
+		fp2flags  = regInfo{inputs: []regMask{fp, fp}}
+		fpload    = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{fp}}
+		fpstore   = regInfo{inputs: []regMask{gpspsbg, fp}}
+		readflags = regInfo{inputs: nil, outputs: []regMask{gp}}
+	)
+	ops := []opData{
+		// binary ops
+		{name: "ADDV", argLength: 2, reg: gp21, asm: "ADDVU", commutative: true},                             // arg0 + arg1
+		{name: "ADDVconst", argLength: 1, reg: gp11sp, asm: "ADDVU", aux: "Int64"},                           // arg0 + auxInt. auxInt is 32-bit, also in other *const ops.
+		{name: "SUBV", argLength: 2, reg: gp21, asm: "SUBVU"},                                                // arg0 - arg1
+		{name: "SUBVconst", argLength: 1, reg: gp11, asm: "SUBVU", aux: "Int64"},                             // arg0 - auxInt
+		{name: "MULV", argLength: 2, reg: gp2hilo, asm: "MULV", commutative: true, typ: "(Int64,Int64)"},     // arg0 * arg1, signed, results hi,lo
+		{name: "MULVU", argLength: 2, reg: gp2hilo, asm: "MULVU", commutative: true, typ: "(UInt64,UInt64)"}, // arg0 * arg1, unsigned, results hi,lo
+		{name: "DIVV", argLength: 2, reg: gp2hilo, asm: "DIVV", typ: "(Int64,Int64)"},                        // arg0 / arg1, signed, results hi=arg0%arg1,lo=arg0/arg1
+		{name: "DIVVU", argLength: 2, reg: gp2hilo, asm: "DIVVU", typ: "(UInt64,UInt64)"},                    // arg0 / arg1, signed, results hi=arg0%arg1,lo=arg0/arg1
+
+		{name: "ADDF", argLength: 2, reg: fp21, asm: "ADDF", commutative: true}, // arg0 + arg1
+		{name: "ADDD", argLength: 2, reg: fp21, asm: "ADDD", commutative: true}, // arg0 + arg1
+		{name: "SUBF", argLength: 2, reg: fp21, asm: "SUBF"},                    // arg0 - arg1
+		{name: "SUBD", argLength: 2, reg: fp21, asm: "SUBD"},                    // arg0 - arg1
+		{name: "MULF", argLength: 2, reg: fp21, asm: "MULF", commutative: true}, // arg0 * arg1
+		{name: "MULD", argLength: 2, reg: fp21, asm: "MULD", commutative: true}, // arg0 * arg1
+		{name: "DIVF", argLength: 2, reg: fp21, asm: "DIVF"},                    // arg0 / arg1
+		{name: "DIVD", argLength: 2, reg: fp21, asm: "DIVD"},                    // arg0 / arg1
+
+		{name: "AND", argLength: 2, reg: gp21, asm: "AND", commutative: true},                // arg0 & arg1
+		{name: "ANDconst", argLength: 1, reg: gp11, asm: "AND", aux: "Int64"},                // arg0 & auxInt
+		{name: "OR", argLength: 2, reg: gp21, asm: "OR", commutative: true},                  // arg0 | arg1
+		{name: "ORconst", argLength: 1, reg: gp11, asm: "OR", aux: "Int64"},                  // arg0 | auxInt
+		{name: "XOR", argLength: 2, reg: gp21, asm: "XOR", commutative: true, typ: "UInt64"}, // arg0 ^ arg1
+		{name: "XORconst", argLength: 1, reg: gp11, asm: "XOR", aux: "Int64", typ: "UInt64"}, // arg0 ^ auxInt
+		{name: "NOR", argLength: 2, reg: gp21, asm: "NOR", commutative: true},                // ^(arg0 | arg1)
+		{name: "NORconst", argLength: 1, reg: gp11, asm: "NOR", aux: "Int64"},                // ^(arg0 | auxInt)
+
+		{name: "NEGV", argLength: 1, reg: gp11},                // -arg0
+		{name: "NEGF", argLength: 1, reg: fp11, asm: "NEGF"},   // -arg0, float32
+		{name: "NEGD", argLength: 1, reg: fp11, asm: "NEGD"},   // -arg0, float64
+		{name: "SQRTD", argLength: 1, reg: fp11, asm: "SQRTD"}, // sqrt(arg0), float64
+		{name: "SQRTF", argLength: 1, reg: fp11, asm: "SQRTF"}, // sqrt(arg0), float32
+
+		// shifts
+		{name: "SLLV", argLength: 2, reg: gp21, asm: "SLLV"},                    // arg0 << arg1, shift amount is mod 64
+		{name: "SLLVconst", argLength: 1, reg: gp11, asm: "SLLV", aux: "Int64"}, // arg0 << auxInt
+		{name: "SRLV", argLength: 2, reg: gp21, asm: "SRLV"},                    // arg0 >> arg1, unsigned, shift amount is mod 64
+		{name: "SRLVconst", argLength: 1, reg: gp11, asm: "SRLV", aux: "Int64"}, // arg0 >> auxInt, unsigned
+		{name: "SRAV", argLength: 2, reg: gp21, asm: "SRAV"},                    // arg0 >> arg1, signed, shift amount is mod 64
+		{name: "SRAVconst", argLength: 1, reg: gp11, asm: "SRAV", aux: "Int64"}, // arg0 >> auxInt, signed
+
+		// comparisons
+		{name: "SGT", argLength: 2, reg: gp21, asm: "SGT", typ: "Bool"},                      // 1 if arg0 > arg1 (signed), 0 otherwise
+		{name: "SGTconst", argLength: 1, reg: gp11, asm: "SGT", aux: "Int64", typ: "Bool"},   // 1 if auxInt > arg0 (signed), 0 otherwise
+		{name: "SGTU", argLength: 2, reg: gp21, asm: "SGTU", typ: "Bool"},                    // 1 if arg0 > arg1 (unsigned), 0 otherwise
+		{name: "SGTUconst", argLength: 1, reg: gp11, asm: "SGTU", aux: "Int64", typ: "Bool"}, // 1 if auxInt > arg0 (unsigned), 0 otherwise
+
+		{name: "CMPEQF", argLength: 2, reg: fp2flags, asm: "CMPEQF", typ: "Flags"}, // flags=true if arg0 = arg1, float32
+		{name: "CMPEQD", argLength: 2, reg: fp2flags, asm: "CMPEQD", typ: "Flags"}, // flags=true if arg0 = arg1, float64
+		{name: "CMPGEF", argLength: 2, reg: fp2flags, asm: "CMPGEF", typ: "Flags"}, // flags=true if arg0 >= arg1, float32
+		{name: "CMPGED", argLength: 2, reg: fp2flags, asm: "CMPGED", typ: "Flags"}, // flags=true if arg0 >= arg1, float64
+		{name: "CMPGTF", argLength: 2, reg: fp2flags, asm: "CMPGTF", typ: "Flags"}, // flags=true if arg0 > arg1, float32
+		{name: "CMPGTD", argLength: 2, reg: fp2flags, asm: "CMPGTD", typ: "Flags"}, // flags=true if arg0 > arg1, float64
+
+		// moves
+		{name: "MOVVconst", argLength: 0, reg: gp01, aux: "Int64", asm: "MOVV", typ: "UInt64", rematerializeable: true},    // auxint
+		{name: "MOVFconst", argLength: 0, reg: fp01, aux: "Float64", asm: "MOVF", typ: "Float32", rematerializeable: true}, // auxint as 64-bit float, convert to 32-bit float
+		{name: "MOVDconst", argLength: 0, reg: fp01, aux: "Float64", asm: "MOVD", typ: "Float64", rematerializeable: true}, // auxint as 64-bit float
+
+		{name: "MOVVaddr", argLength: 1, reg: regInfo{inputs: []regMask{buildReg("SP") | buildReg("SB")}, outputs: []regMask{gp}}, aux: "SymOff", asm: "MOVV", rematerializeable: true, symEffect: "Addr"}, // arg0 + auxInt + aux.(*gc.Sym), arg0=SP/SB
+
+		{name: "MOVBload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVB", typ: "Int8", faultOnNilArg0: true, symEffect: "Read"},     // load from arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVBUload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVBU", typ: "UInt8", faultOnNilArg0: true, symEffect: "Read"},  // load from arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVHload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVH", typ: "Int16", faultOnNilArg0: true, symEffect: "Read"},    // load from arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVHUload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVHU", typ: "UInt16", faultOnNilArg0: true, symEffect: "Read"}, // load from arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVWload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVW", typ: "Int32", faultOnNilArg0: true, symEffect: "Read"},    // load from arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVWUload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVWU", typ: "UInt32", faultOnNilArg0: true, symEffect: "Read"}, // load from arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVVload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVV", typ: "UInt64", faultOnNilArg0: true, symEffect: "Read"},   // load from arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVFload", argLength: 2, reg: fpload, aux: "SymOff", asm: "MOVF", typ: "Float32", faultOnNilArg0: true, symEffect: "Read"},  // load from arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVDload", argLength: 2, reg: fpload, aux: "SymOff", asm: "MOVD", typ: "Float64", faultOnNilArg0: true, symEffect: "Read"},  // load from arg0 + auxInt + aux.  arg1=mem.
+
+		{name: "MOVBstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVB", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 1 byte of arg1 to arg0 + auxInt + aux.  arg2=mem.
+		{name: "MOVHstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVH", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 2 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
+		{name: "MOVWstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVW", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
+		{name: "MOVVstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVV", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
+		{name: "MOVFstore", argLength: 3, reg: fpstore, aux: "SymOff", asm: "MOVF", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
+		{name: "MOVDstore", argLength: 3, reg: fpstore, aux: "SymOff", asm: "MOVD", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
+
+		{name: "MOVBstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVB", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 1 byte of zero to arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVHstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVH", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 2 bytes of zero to arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVWstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVW", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes of zero to arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVVstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVV", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes of zero to arg0 + auxInt + aux.  ar12=mem.
+
+		// conversions
+		{name: "MOVBreg", argLength: 1, reg: gp11, asm: "MOVB"},   // move from arg0, sign-extended from byte
+		{name: "MOVBUreg", argLength: 1, reg: gp11, asm: "MOVBU"}, // move from arg0, unsign-extended from byte
+		{name: "MOVHreg", argLength: 1, reg: gp11, asm: "MOVH"},   // move from arg0, sign-extended from half
+		{name: "MOVHUreg", argLength: 1, reg: gp11, asm: "MOVHU"}, // move from arg0, unsign-extended from half
+		{name: "MOVWreg", argLength: 1, reg: gp11, asm: "MOVW"},   // move from arg0, sign-extended from word
+		{name: "MOVWUreg", argLength: 1, reg: gp11, asm: "MOVWU"}, // move from arg0, unsign-extended from word
+		{name: "MOVVreg", argLength: 1, reg: gp11, asm: "MOVV"},   // move from arg0
+
+		{name: "MOVVnop", argLength: 1, reg: regInfo{inputs: []regMask{gp}, outputs: []regMask{gp}}, resultInArg0: true}, // nop, return arg0 in same register
+
+		{name: "MOVWF", argLength: 1, reg: fp11, asm: "MOVWF"},     // int32 -> float32
+		{name: "MOVWD", argLength: 1, reg: fp11, asm: "MOVWD"},     // int32 -> float64
+		{name: "MOVVF", argLength: 1, reg: fp11, asm: "MOVVF"},     // int64 -> float32
+		{name: "MOVVD", argLength: 1, reg: fp11, asm: "MOVVD"},     // int64 -> float64
+		{name: "TRUNCFW", argLength: 1, reg: fp11, asm: "TRUNCFW"}, // float32 -> int32
+		{name: "TRUNCDW", argLength: 1, reg: fp11, asm: "TRUNCDW"}, // float64 -> int32
+		{name: "TRUNCFV", argLength: 1, reg: fp11, asm: "TRUNCFV"}, // float32 -> int64
+		{name: "TRUNCDV", argLength: 1, reg: fp11, asm: "TRUNCDV"}, // float64 -> int64
+		{name: "MOVFD", argLength: 1, reg: fp11, asm: "MOVFD"},     // float32 -> float64
+		{name: "MOVDF", argLength: 1, reg: fp11, asm: "MOVDF"},     // float64 -> float32
+
+		// function calls
+		{name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                                               // call static function aux.(*obj.LSym).  arg0=mem, auxint=argsize, returns mem
+		{name: "CALLtail", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true, tailCall: true},                                 // tail call static function aux.(*obj.LSym).  arg0=mem, auxint=argsize, returns mem
+		{name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{gpsp, buildReg("R22"), 0}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call function via closure.  arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem
+		{name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                         // call fn by pointer.  arg0=codeptr, arg1=mem, auxint=argsize, returns mem
+
+		// duffzero
+		// arg0 = address of memory to zero
+		// arg1 = mem
+		// auxint = offset into duffzero code to start executing
+		// returns mem
+		// R1 aka mips.REGRT1 changed as side effect
+		{
+			name:      "DUFFZERO",
+			aux:       "Int64",
+			argLength: 2,
+			reg: regInfo{
+				inputs:   []regMask{gp},
+				clobbers: buildReg("R1 R31"),
+			},
+			faultOnNilArg0: true,
+		},
+
+		// duffcopy
+		// arg0 = address of dst memory (in R2, changed as side effect)
+		// arg1 = address of src memory (in R1, changed as side effect)
+		// arg2 = mem
+		// auxint = offset into duffcopy code to start executing
+		// returns mem
+		{
+			name:      "DUFFCOPY",
+			aux:       "Int64",
+			argLength: 3,
+			reg: regInfo{
+				inputs:   []regMask{buildReg("R2"), buildReg("R1")},
+				clobbers: buildReg("R1 R2 R31"),
+			},
+			faultOnNilArg0: true,
+			faultOnNilArg1: true,
+		},
+
+		// large or unaligned zeroing
+		// arg0 = address of memory to zero (in R1, changed as side effect)
+		// arg1 = address of the last element to zero
+		// arg2 = mem
+		// auxint = alignment
+		// returns mem
+		//	SUBV	$8, R1
+		//	MOVV	R0, 8(R1)
+		//	ADDV	$8, R1
+		//	BNE	Rarg1, R1, -2(PC)
+		{
+			name:      "LoweredZero",
+			aux:       "Int64",
+			argLength: 3,
+			reg: regInfo{
+				inputs:   []regMask{buildReg("R1"), gp},
+				clobbers: buildReg("R1"),
+			},
+			clobberFlags:   true,
+			faultOnNilArg0: true,
+		},
+
+		// large or unaligned move
+		// arg0 = address of dst memory (in R2, changed as side effect)
+		// arg1 = address of src memory (in R1, changed as side effect)
+		// arg2 = address of the last element of src
+		// arg3 = mem
+		// auxint = alignment
+		// returns mem
+		//	SUBV	$8, R1
+		//	MOVV	8(R1), Rtmp
+		//	MOVV	Rtmp, (R2)
+		//	ADDV	$8, R1
+		//	ADDV	$8, R2
+		//	BNE	Rarg2, R1, -4(PC)
+		{
+			name:      "LoweredMove",
+			aux:       "Int64",
+			argLength: 4,
+			reg: regInfo{
+				inputs:   []regMask{buildReg("R2"), buildReg("R1"), gp},
+				clobbers: buildReg("R1 R2"),
+			},
+			clobberFlags:   true,
+			faultOnNilArg0: true,
+			faultOnNilArg1: true,
+		},
+
+		// atomic loads.
+		// load from arg0. arg1=mem.
+		// returns <value,memory> so they can be properly ordered with other loads.
+		{name: "LoweredAtomicLoad8", argLength: 2, reg: gpload, faultOnNilArg0: true},
+		{name: "LoweredAtomicLoad32", argLength: 2, reg: gpload, faultOnNilArg0: true},
+		{name: "LoweredAtomicLoad64", argLength: 2, reg: gpload, faultOnNilArg0: true},
+
+		// atomic stores.
+		// store arg1 to arg0. arg2=mem. returns memory.
+		{name: "LoweredAtomicStore8", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true},
+		{name: "LoweredAtomicStore32", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true},
+		{name: "LoweredAtomicStore64", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true},
+		// store zero to arg0. arg1=mem. returns memory.
+		{name: "LoweredAtomicStorezero32", argLength: 2, reg: gpstore0, faultOnNilArg0: true, hasSideEffects: true},
+		{name: "LoweredAtomicStorezero64", argLength: 2, reg: gpstore0, faultOnNilArg0: true, hasSideEffects: true},
+
+		// atomic exchange.
+		// store arg1 to arg0. arg2=mem. returns <old content of *arg0, memory>.
+		// SYNC
+		// LL	(Rarg0), Rout
+		// MOVV Rarg1, Rtmp
+		// SC	Rtmp, (Rarg0)
+		// BEQ	Rtmp, -3(PC)
+		// SYNC
+		{name: "LoweredAtomicExchange32", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+		{name: "LoweredAtomicExchange64", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+
+		// atomic add.
+		// *arg0 += arg1. arg2=mem. returns <new content of *arg0, memory>.
+		// SYNC
+		// LL	(Rarg0), Rout
+		// ADDV Rarg1, Rout, Rtmp
+		// SC	Rtmp, (Rarg0)
+		// BEQ	Rtmp, -3(PC)
+		// SYNC
+		// ADDV Rarg1, Rout
+		{name: "LoweredAtomicAdd32", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+		{name: "LoweredAtomicAdd64", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+		// *arg0 += auxint. arg1=mem. returns <new content of *arg0, memory>. auxint is 32-bit.
+		{name: "LoweredAtomicAddconst32", argLength: 2, reg: regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{gp}}, aux: "Int32", resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+		{name: "LoweredAtomicAddconst64", argLength: 2, reg: regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{gp}}, aux: "Int64", resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+
+		// atomic compare and swap.
+		// arg0 = pointer, arg1 = old value, arg2 = new value, arg3 = memory.
+		// if *arg0 == arg1 {
+		//   *arg0 = arg2
+		//   return (true, memory)
+		// } else {
+		//   return (false, memory)
+		// }
+		// SYNC
+		// MOVV $0, Rout
+		// LL	(Rarg0), Rtmp
+		// BNE	Rtmp, Rarg1, 4(PC)
+		// MOVV Rarg2, Rout
+		// SC	Rout, (Rarg0)
+		// BEQ	Rout, -4(PC)
+		// SYNC
+		{name: "LoweredAtomicCas32", argLength: 4, reg: gpcas, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+		{name: "LoweredAtomicCas64", argLength: 4, reg: gpcas, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+
+		// pseudo-ops
+		{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpg}}, nilCheck: true, faultOnNilArg0: true}, // panic if arg0 is nil.  arg1=mem.
+
+		{name: "FPFlagTrue", argLength: 1, reg: readflags},  // bool, true if FP flag is true
+		{name: "FPFlagFalse", argLength: 1, reg: readflags}, // bool, true if FP flag is false
+
+		// Scheduler ensures LoweredGetClosurePtr occurs only in entry block,
+		// and sorts it to the very beginning of the block to prevent other
+		// use of R22 (mips.REGCTXT, the closure pointer)
+		{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R22")}}, zeroWidth: true},
+
+		// LoweredGetCallerSP returns the SP of the caller of the current function.
+		{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
+
+		// LoweredGetCallerPC evaluates to the PC to which its "caller" will return.
+		// I.e., if f calls g "calls" getcallerpc,
+		// the result should be the PC within f that g will return to.
+		// See runtime/stubs.go for a more detailed discussion.
+		{name: "LoweredGetCallerPC", reg: gp01, rematerializeable: true},
+
+		// LoweredWB invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
+		// It saves all GP registers if necessary,
+		// but clobbers R31 (LR) because it's a call
+		// and R23 (REGTMP).
+		{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R20"), buildReg("R21")}, clobbers: (callerSave &^ gpg) | buildReg("R31")}, clobberFlags: true, aux: "Sym", symEffect: "None"},
+
+		// There are three of these functions so that they can have three different register inputs.
+		// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the
+		// default registers to match so we don't need to copy registers around unnecessarily.
+		{name: "LoweredPanicBoundsA", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r3, r4}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
+		{name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r2, r3}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
+		{name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r1, r2}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
+	}
+
+	blocks := []blockData{
+		{name: "EQ", controls: 1},
+		{name: "NE", controls: 1},
+		{name: "LTZ", controls: 1}, // < 0
+		{name: "LEZ", controls: 1}, // <= 0
+		{name: "GTZ", controls: 1}, // > 0
+		{name: "GEZ", controls: 1}, // >= 0
+		{name: "FPT", controls: 1}, // FP flag is true
+		{name: "FPF", controls: 1}, // FP flag is false
+	}
+
+	archs = append(archs, arch{
+		name:            "MIPS64",
+		pkg:             "cmd/internal/obj/mips",
+		genfile:         "../../mips64/ssa.go",
+		ops:             ops,
+		blocks:          blocks,
+		regnames:        regNamesMIPS64,
+		gpregmask:       gp,
+		fpregmask:       fp,
+		specialregmask:  hi | lo,
+		framepointerreg: -1, // not used
+		linkreg:         int8(num["R31"]),
+	})
+}
diff --git a/src/cmd/compile/internal/ssa/_gen/MIPSOps.go b/src/cmd/compile/internal/ssa/_gen/MIPSOps.go
new file mode 100644
index 0000000..22a7a5c
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/_gen/MIPSOps.go
@@ -0,0 +1,439 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "strings"
+
+// Notes:
+//  - Integer types live in the low portion of registers. Upper portions are junk.
+//  - Boolean types use the low-order byte of a register. 0=false, 1=true.
+//    Upper bytes are junk.
+//  - Unused portions of AuxInt are filled by sign-extending the used portion.
+//  - *const instructions may use a constant larger than the instruction can encode.
+//    In this case the assembler expands to multiple instructions and uses tmp
+//    register (R23).
+
+// Suffixes encode the bit width of various instructions.
+// W (word)      = 32 bit
+// H (half word) = 16 bit
+// HU            = 16 bit unsigned
+// B (byte)      = 8 bit
+// BU            = 8 bit unsigned
+// F (float)     = 32 bit float
+// D (double)    = 64 bit float
+
+// Note: registers not used in regalloc are not included in this list,
+// so that regmask stays within int64
+// Be careful when hand coding regmasks.
+var regNamesMIPS = []string{
+	"R0", // constant 0
+	"R1",
+	"R2",
+	"R3",
+	"R4",
+	"R5",
+	"R6",
+	"R7",
+	"R8",
+	"R9",
+	"R10",
+	"R11",
+	"R12",
+	"R13",
+	"R14",
+	"R15",
+	"R16",
+	"R17",
+	"R18",
+	"R19",
+	"R20",
+	"R21",
+	"R22",
+	//REGTMP
+	"R24",
+	"R25",
+	// R26 reserved by kernel
+	// R27 reserved by kernel
+	"R28",
+	"SP",  // aka R29
+	"g",   // aka R30
+	"R31", // REGLINK
+
+	// odd FP registers contain high parts of 64-bit FP values
+	"F0",
+	"F2",
+	"F4",
+	"F6",
+	"F8",
+	"F10",
+	"F12",
+	"F14",
+	"F16",
+	"F18",
+	"F20",
+	"F22",
+	"F24",
+	"F26",
+	"F28",
+	"F30",
+
+	"HI", // high bits of multiplication
+	"LO", // low bits of multiplication
+
+	// If you add registers, update asyncPreempt in runtime.
+
+	// pseudo-registers
+	"SB",
+}
+
+func init() {
+	// Make map from reg names to reg integers.
+	if len(regNamesMIPS) > 64 {
+		panic("too many registers")
+	}
+	num := map[string]int{}
+	for i, name := range regNamesMIPS {
+		num[name] = i
+	}
+	buildReg := func(s string) regMask {
+		m := regMask(0)
+		for _, r := range strings.Split(s, " ") {
+			if n, ok := num[r]; ok {
+				m |= regMask(1) << uint(n)
+				continue
+			}
+			panic("register " + r + " not found")
+		}
+		return m
+	}
+
+	// Common individual register masks
+	var (
+		gp         = buildReg("R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R28 R31")
+		gpg        = gp | buildReg("g")
+		gpsp       = gp | buildReg("SP")
+		gpspg      = gpg | buildReg("SP")
+		gpspsbg    = gpspg | buildReg("SB")
+		fp         = buildReg("F0 F2 F4 F6 F8 F10 F12 F14 F16 F18 F20 F22 F24 F26 F28 F30")
+		lo         = buildReg("LO")
+		hi         = buildReg("HI")
+		callerSave = gp | fp | lo | hi | buildReg("g") // runtime.setg (and anything calling it) may clobber g
+		r1         = buildReg("R1")
+		r2         = buildReg("R2")
+		r3         = buildReg("R3")
+		r4         = buildReg("R4")
+		r5         = buildReg("R5")
+	)
+	// Common regInfo
+	var (
+		gp01      = regInfo{inputs: nil, outputs: []regMask{gp}}
+		gp11      = regInfo{inputs: []regMask{gpg}, outputs: []regMask{gp}}
+		gp11sp    = regInfo{inputs: []regMask{gpspg}, outputs: []regMask{gp}}
+		gp21      = regInfo{inputs: []regMask{gpg, gpg}, outputs: []regMask{gp}}
+		gp31      = regInfo{inputs: []regMask{gp, gp, gp}, outputs: []regMask{gp}}
+		gp2hilo   = regInfo{inputs: []regMask{gpg, gpg}, outputs: []regMask{hi, lo}}
+		gpload    = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{gp}}
+		gpstore   = regInfo{inputs: []regMask{gpspsbg, gpg}}
+		gpxchg    = regInfo{inputs: []regMask{gpspsbg, gpg}, outputs: []regMask{gp}}
+		gpcas     = regInfo{inputs: []regMask{gpspsbg, gpg, gpg}, outputs: []regMask{gp}}
+		gpstore0  = regInfo{inputs: []regMask{gpspsbg}}
+		fp01      = regInfo{inputs: nil, outputs: []regMask{fp}}
+		fp11      = regInfo{inputs: []regMask{fp}, outputs: []regMask{fp}}
+		fp21      = regInfo{inputs: []regMask{fp, fp}, outputs: []regMask{fp}}
+		fp2flags  = regInfo{inputs: []regMask{fp, fp}}
+		fpload    = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{fp}}
+		fpstore   = regInfo{inputs: []regMask{gpspsbg, fp}}
+		readflags = regInfo{inputs: nil, outputs: []regMask{gp}}
+	)
+	ops := []opData{
+		{name: "ADD", argLength: 2, reg: gp21, asm: "ADDU", commutative: true},                                                                           // arg0 + arg1
+		{name: "ADDconst", argLength: 1, reg: gp11sp, asm: "ADDU", aux: "Int32"},                                                                         // arg0 + auxInt
+		{name: "SUB", argLength: 2, reg: gp21, asm: "SUBU"},                                                                                              // arg0 - arg1
+		{name: "SUBconst", argLength: 1, reg: gp11, asm: "SUBU", aux: "Int32"},                                                                           // arg0 - auxInt
+		{name: "MUL", argLength: 2, reg: regInfo{inputs: []regMask{gpg, gpg}, outputs: []regMask{gp}, clobbers: hi | lo}, asm: "MUL", commutative: true}, // arg0 * arg1
+		{name: "MULT", argLength: 2, reg: gp2hilo, asm: "MUL", commutative: true, typ: "(Int32,Int32)"},                                                  // arg0 * arg1, signed, results hi,lo
+		{name: "MULTU", argLength: 2, reg: gp2hilo, asm: "MULU", commutative: true, typ: "(UInt32,UInt32)"},                                              // arg0 * arg1, unsigned, results hi,lo
+		{name: "DIV", argLength: 2, reg: gp2hilo, asm: "DIV", typ: "(Int32,Int32)"},                                                                      // arg0 / arg1, signed, results hi=arg0%arg1,lo=arg0/arg1
+		{name: "DIVU", argLength: 2, reg: gp2hilo, asm: "DIVU", typ: "(UInt32,UInt32)"},                                                                  // arg0 / arg1, signed, results hi=arg0%arg1,lo=arg0/arg1
+
+		{name: "ADDF", argLength: 2, reg: fp21, asm: "ADDF", commutative: true}, // arg0 + arg1
+		{name: "ADDD", argLength: 2, reg: fp21, asm: "ADDD", commutative: true}, // arg0 + arg1
+		{name: "SUBF", argLength: 2, reg: fp21, asm: "SUBF"},                    // arg0 - arg1
+		{name: "SUBD", argLength: 2, reg: fp21, asm: "SUBD"},                    // arg0 - arg1
+		{name: "MULF", argLength: 2, reg: fp21, asm: "MULF", commutative: true}, // arg0 * arg1
+		{name: "MULD", argLength: 2, reg: fp21, asm: "MULD", commutative: true}, // arg0 * arg1
+		{name: "DIVF", argLength: 2, reg: fp21, asm: "DIVF"},                    // arg0 / arg1
+		{name: "DIVD", argLength: 2, reg: fp21, asm: "DIVD"},                    // arg0 / arg1
+
+		{name: "AND", argLength: 2, reg: gp21, asm: "AND", commutative: true},                // arg0 & arg1
+		{name: "ANDconst", argLength: 1, reg: gp11, asm: "AND", aux: "Int32"},                // arg0 & auxInt
+		{name: "OR", argLength: 2, reg: gp21, asm: "OR", commutative: true},                  // arg0 | arg1
+		{name: "ORconst", argLength: 1, reg: gp11, asm: "OR", aux: "Int32"},                  // arg0 | auxInt
+		{name: "XOR", argLength: 2, reg: gp21, asm: "XOR", commutative: true, typ: "UInt32"}, // arg0 ^ arg1
+		{name: "XORconst", argLength: 1, reg: gp11, asm: "XOR", aux: "Int32", typ: "UInt32"}, // arg0 ^ auxInt
+		{name: "NOR", argLength: 2, reg: gp21, asm: "NOR", commutative: true},                // ^(arg0 | arg1)
+		{name: "NORconst", argLength: 1, reg: gp11, asm: "NOR", aux: "Int32"},                // ^(arg0 | auxInt)
+
+		{name: "NEG", argLength: 1, reg: gp11},                 // -arg0
+		{name: "NEGF", argLength: 1, reg: fp11, asm: "NEGF"},   // -arg0, float32
+		{name: "NEGD", argLength: 1, reg: fp11, asm: "NEGD"},   // -arg0, float64
+		{name: "SQRTD", argLength: 1, reg: fp11, asm: "SQRTD"}, // sqrt(arg0), float64
+		{name: "SQRTF", argLength: 1, reg: fp11, asm: "SQRTF"}, // sqrt(arg0), float32
+
+		// shifts
+		{name: "SLL", argLength: 2, reg: gp21, asm: "SLL"},                    // arg0 << arg1, shift amount is mod 32
+		{name: "SLLconst", argLength: 1, reg: gp11, asm: "SLL", aux: "Int32"}, // arg0 << auxInt, shift amount must be 0 through 31 inclusive
+		{name: "SRL", argLength: 2, reg: gp21, asm: "SRL"},                    // arg0 >> arg1, unsigned, shift amount is mod 32
+		{name: "SRLconst", argLength: 1, reg: gp11, asm: "SRL", aux: "Int32"}, // arg0 >> auxInt, shift amount must be 0 through 31 inclusive
+		{name: "SRA", argLength: 2, reg: gp21, asm: "SRA"},                    // arg0 >> arg1, signed, shift amount is mod 32
+		{name: "SRAconst", argLength: 1, reg: gp11, asm: "SRA", aux: "Int32"}, // arg0 >> auxInt, signed, shift amount must be 0 through 31 inclusive
+
+		{name: "CLZ", argLength: 1, reg: gp11, asm: "CLZ"},
+
+		// comparisons
+		{name: "SGT", argLength: 2, reg: gp21, asm: "SGT", typ: "Bool"},                      // 1 if arg0 > arg1 (signed), 0 otherwise
+		{name: "SGTconst", argLength: 1, reg: gp11, asm: "SGT", aux: "Int32", typ: "Bool"},   // 1 if auxInt > arg0 (signed), 0 otherwise
+		{name: "SGTzero", argLength: 1, reg: gp11, asm: "SGT", typ: "Bool"},                  // 1 if arg0 > 0 (signed), 0 otherwise
+		{name: "SGTU", argLength: 2, reg: gp21, asm: "SGTU", typ: "Bool"},                    // 1 if arg0 > arg1 (unsigned), 0 otherwise
+		{name: "SGTUconst", argLength: 1, reg: gp11, asm: "SGTU", aux: "Int32", typ: "Bool"}, // 1 if auxInt > arg0 (unsigned), 0 otherwise
+		{name: "SGTUzero", argLength: 1, reg: gp11, asm: "SGTU", typ: "Bool"},                // 1 if arg0 > 0 (unsigned), 0 otherwise
+
+		{name: "CMPEQF", argLength: 2, reg: fp2flags, asm: "CMPEQF", typ: "Flags"}, // flags=true if arg0 = arg1, float32
+		{name: "CMPEQD", argLength: 2, reg: fp2flags, asm: "CMPEQD", typ: "Flags"}, // flags=true if arg0 = arg1, float64
+		{name: "CMPGEF", argLength: 2, reg: fp2flags, asm: "CMPGEF", typ: "Flags"}, // flags=true if arg0 >= arg1, float32
+		{name: "CMPGED", argLength: 2, reg: fp2flags, asm: "CMPGED", typ: "Flags"}, // flags=true if arg0 >= arg1, float64
+		{name: "CMPGTF", argLength: 2, reg: fp2flags, asm: "CMPGTF", typ: "Flags"}, // flags=true if arg0 > arg1, float32
+		{name: "CMPGTD", argLength: 2, reg: fp2flags, asm: "CMPGTD", typ: "Flags"}, // flags=true if arg0 > arg1, float64
+
+		// moves
+		{name: "MOVWconst", argLength: 0, reg: gp01, aux: "Int32", asm: "MOVW", typ: "UInt32", rematerializeable: true},    // auxint
+		{name: "MOVFconst", argLength: 0, reg: fp01, aux: "Float32", asm: "MOVF", typ: "Float32", rematerializeable: true}, // auxint as 64-bit float, convert to 32-bit float
+		{name: "MOVDconst", argLength: 0, reg: fp01, aux: "Float64", asm: "MOVD", typ: "Float64", rematerializeable: true}, // auxint as 64-bit float
+
+		{name: "MOVWaddr", argLength: 1, reg: regInfo{inputs: []regMask{buildReg("SP") | buildReg("SB")}, outputs: []regMask{gp}}, aux: "SymOff", asm: "MOVW", rematerializeable: true, symEffect: "Addr"}, // arg0 + auxInt + aux.(*gc.Sym), arg0=SP/SB
+
+		{name: "MOVBload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVB", typ: "Int8", faultOnNilArg0: true, symEffect: "Read"},     // load from arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVBUload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVBU", typ: "UInt8", faultOnNilArg0: true, symEffect: "Read"},  // load from arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVHload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVH", typ: "Int16", faultOnNilArg0: true, symEffect: "Read"},    // load from arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVHUload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVHU", typ: "UInt16", faultOnNilArg0: true, symEffect: "Read"}, // load from arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVWload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVW", typ: "UInt32", faultOnNilArg0: true, symEffect: "Read"},   // load from arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVFload", argLength: 2, reg: fpload, aux: "SymOff", asm: "MOVF", typ: "Float32", faultOnNilArg0: true, symEffect: "Read"},  // load from arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVDload", argLength: 2, reg: fpload, aux: "SymOff", asm: "MOVD", typ: "Float64", faultOnNilArg0: true, symEffect: "Read"},  // load from arg0 + auxInt + aux.  arg1=mem.
+
+		{name: "MOVBstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVB", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 1 byte of arg1 to arg0 + auxInt + aux.  arg2=mem.
+		{name: "MOVHstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVH", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 2 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
+		{name: "MOVWstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVW", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
+		{name: "MOVFstore", argLength: 3, reg: fpstore, aux: "SymOff", asm: "MOVF", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
+		{name: "MOVDstore", argLength: 3, reg: fpstore, aux: "SymOff", asm: "MOVD", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
+
+		{name: "MOVBstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVB", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 1 byte of zero to arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVHstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVH", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 2 bytes of zero to arg0 + auxInt + aux.  arg1=mem.
+		{name: "MOVWstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVW", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes of zero to arg0 + auxInt + aux.  arg1=mem.
+
+		// conversions
+		{name: "MOVBreg", argLength: 1, reg: gp11, asm: "MOVB"},   // move from arg0, sign-extended from byte
+		{name: "MOVBUreg", argLength: 1, reg: gp11, asm: "MOVBU"}, // move from arg0, unsign-extended from byte
+		{name: "MOVHreg", argLength: 1, reg: gp11, asm: "MOVH"},   // move from arg0, sign-extended from half
+		{name: "MOVHUreg", argLength: 1, reg: gp11, asm: "MOVHU"}, // move from arg0, unsign-extended from half
+		{name: "MOVWreg", argLength: 1, reg: gp11, asm: "MOVW"},   // move from arg0
+
+		{name: "MOVWnop", argLength: 1, reg: regInfo{inputs: []regMask{gp}, outputs: []regMask{gp}}, resultInArg0: true}, // nop, return arg0 in same register
+
+		// conditional move on zero (returns arg1 if arg2 is 0, otherwise arg0)
+		// order of parameters is reversed so we can use resultInArg0 (OpCMOVZ result arg1 arg2-> CMOVZ arg2reg, arg1reg, resultReg)
+		{name: "CMOVZ", argLength: 3, reg: gp31, asm: "CMOVZ", resultInArg0: true},
+		{name: "CMOVZzero", argLength: 2, reg: regInfo{inputs: []regMask{gp, gpg}, outputs: []regMask{gp}}, asm: "CMOVZ", resultInArg0: true},
+
+		{name: "MOVWF", argLength: 1, reg: fp11, asm: "MOVWF"},     // int32 -> float32
+		{name: "MOVWD", argLength: 1, reg: fp11, asm: "MOVWD"},     // int32 -> float64
+		{name: "TRUNCFW", argLength: 1, reg: fp11, asm: "TRUNCFW"}, // float32 -> int32
+		{name: "TRUNCDW", argLength: 1, reg: fp11, asm: "TRUNCDW"}, // float64 -> int32
+		{name: "MOVFD", argLength: 1, reg: fp11, asm: "MOVFD"},     // float32 -> float64
+		{name: "MOVDF", argLength: 1, reg: fp11, asm: "MOVDF"},     // float64 -> float32
+
+		// function calls
+		{name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                                               // call static function aux.(*obj.LSym).  arg0=mem, auxint=argsize, returns mem
+		{name: "CALLtail", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true, tailCall: true},                                 //  tail call static function aux.(*obj.LSym).  arg0=mem, auxint=argsize, returns mem
+		{name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{gpsp, buildReg("R22"), 0}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call function via closure.  arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem
+		{name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                         // call fn by pointer.  arg0=codeptr, arg1=mem, auxint=argsize, returns mem
+
+		// atomic ops
+
+		// load from arg0. arg1=mem.
+		// returns <value,memory> so they can be properly ordered with other loads.
+		// SYNC
+		// MOV(B|W)	(Rarg0), Rout
+		// SYNC
+		{name: "LoweredAtomicLoad8", argLength: 2, reg: gpload, faultOnNilArg0: true},
+		{name: "LoweredAtomicLoad32", argLength: 2, reg: gpload, faultOnNilArg0: true},
+
+		// store arg1 to arg0. arg2=mem. returns memory.
+		// SYNC
+		// MOV(B|W)	Rarg1, (Rarg0)
+		// SYNC
+		{name: "LoweredAtomicStore8", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true},
+		{name: "LoweredAtomicStore32", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true},
+		{name: "LoweredAtomicStorezero", argLength: 2, reg: gpstore0, faultOnNilArg0: true, hasSideEffects: true},
+
+		// atomic exchange.
+		// store arg1 to arg0. arg2=mem. returns <old content of *arg0, memory>.
+		// SYNC
+		// LL	(Rarg0), Rout
+		// MOVW Rarg1, Rtmp
+		// SC	Rtmp, (Rarg0)
+		// BEQ	Rtmp, -3(PC)
+		// SYNC
+		{name: "LoweredAtomicExchange", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+
+		// atomic add.
+		// *arg0 += arg1. arg2=mem. returns <new content of *arg0, memory>.
+		// SYNC
+		// LL	(Rarg0), Rout
+		// ADDU Rarg1, Rout, Rtmp
+		// SC	Rtmp, (Rarg0)
+		// BEQ	Rtmp, -3(PC)
+		// SYNC
+		// ADDU Rarg1, Rout
+		{name: "LoweredAtomicAdd", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+		{name: "LoweredAtomicAddconst", argLength: 2, reg: regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{gp}}, aux: "Int32", resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+
+		// atomic compare and swap.
+		// arg0 = pointer, arg1 = old value, arg2 = new value, arg3 = memory.
+		// if *arg0 == arg1 {
+		//   *arg0 = arg2
+		//   return (true, memory)
+		// } else {
+		//   return (false, memory)
+		// }
+		// SYNC
+		// MOVW $0, Rout
+		// LL	(Rarg0), Rtmp
+		// BNE	Rtmp, Rarg1, 4(PC)
+		// MOVW Rarg2, Rout
+		// SC	Rout, (Rarg0)
+		// BEQ	Rout, -4(PC)
+		// SYNC
+		{name: "LoweredAtomicCas", argLength: 4, reg: gpcas, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+
+		// atomic and/or.
+		// *arg0 &= (|=) arg1. arg2=mem. returns memory.
+		// SYNC
+		// LL	(Rarg0), Rtmp
+		// AND	Rarg1, Rtmp
+		// SC	Rtmp, (Rarg0)
+		// BEQ	Rtmp, -3(PC)
+		// SYNC
+		{name: "LoweredAtomicAnd", argLength: 3, reg: gpstore, asm: "AND", faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+		{name: "LoweredAtomicOr", argLength: 3, reg: gpstore, asm: "OR", faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+
+		// large or unaligned zeroing
+		// arg0 = address of memory to zero (in R1, changed as side effect)
+		// arg1 = address of the last element to zero
+		// arg2 = mem
+		// auxint = alignment
+		// returns mem
+		//	SUBU	$4, R1
+		//	MOVW	R0, 4(R1)
+		//	ADDU	$4, R1
+		//	BNE	Rarg1, R1, -2(PC)
+		{
+			name:      "LoweredZero",
+			aux:       "Int32",
+			argLength: 3,
+			reg: regInfo{
+				inputs:   []regMask{buildReg("R1"), gp},
+				clobbers: buildReg("R1"),
+			},
+			faultOnNilArg0: true,
+		},
+
+		// large or unaligned move
+		// arg0 = address of dst memory (in R2, changed as side effect)
+		// arg1 = address of src memory (in R1, changed as side effect)
+		// arg2 = address of the last element of src
+		// arg3 = mem
+		// auxint = alignment
+		// returns mem
+		//	SUBU	$4, R1
+		//	MOVW	4(R1), Rtmp
+		//	MOVW	Rtmp, (R2)
+		//	ADDU	$4, R1
+		//	ADDU	$4, R2
+		//	BNE	Rarg2, R1, -4(PC)
+		{
+			name:      "LoweredMove",
+			aux:       "Int32",
+			argLength: 4,
+			reg: regInfo{
+				inputs:   []regMask{buildReg("R2"), buildReg("R1"), gp},
+				clobbers: buildReg("R1 R2"),
+			},
+			faultOnNilArg0: true,
+			faultOnNilArg1: true,
+		},
+
+		// pseudo-ops
+		{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpg}}, nilCheck: true, faultOnNilArg0: true}, // panic if arg0 is nil.  arg1=mem.
+
+		{name: "FPFlagTrue", argLength: 1, reg: readflags},  // bool, true if FP flag is true
+		{name: "FPFlagFalse", argLength: 1, reg: readflags}, // bool, true if FP flag is false
+
+		// Scheduler ensures LoweredGetClosurePtr occurs only in entry block,
+		// and sorts it to the very beginning of the block to prevent other
+		// use of R22 (mips.REGCTXT, the closure pointer)
+		{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R22")}}, zeroWidth: true},
+
+		// LoweredGetCallerSP returns the SP of the caller of the current function.
+		{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
+
+		// LoweredGetCallerPC evaluates to the PC to which its "caller" will return.
+		// I.e., if f calls g "calls" getcallerpc,
+		// the result should be the PC within f that g will return to.
+		// See runtime/stubs.go for a more detailed discussion.
+		{name: "LoweredGetCallerPC", reg: gp01, rematerializeable: true},
+
+		// LoweredWB invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
+		// It saves all GP registers if necessary,
+		// but clobbers R31 (LR) because it's a call
+		// and R23 (REGTMP).
+		{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R20"), buildReg("R21")}, clobbers: (callerSave &^ gpg) | buildReg("R31")}, clobberFlags: true, aux: "Sym", symEffect: "None"},
+
+		// There are three of these functions so that they can have three different register inputs.
+		// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the
+		// default registers to match so we don't need to copy registers around unnecessarily.
+		{name: "LoweredPanicBoundsA", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r3, r4}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
+		{name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r2, r3}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
+		{name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r1, r2}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
+		// Extend ops are the same as Bounds ops except the indexes are 64-bit.
+		{name: "LoweredPanicExtendA", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{r5, r3, r4}}, typ: "Mem", call: true}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
+		{name: "LoweredPanicExtendB", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{r5, r2, r3}}, typ: "Mem", call: true}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
+		{name: "LoweredPanicExtendC", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{r5, r1, r2}}, typ: "Mem", call: true}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
+	}
+
+	blocks := []blockData{
+		{name: "EQ", controls: 1},
+		{name: "NE", controls: 1},
+		{name: "LTZ", controls: 1}, // < 0
+		{name: "LEZ", controls: 1}, // <= 0
+		{name: "GTZ", controls: 1}, // > 0
+		{name: "GEZ", controls: 1}, // >= 0
+		{name: "FPT", controls: 1}, // FP flag is true
+		{name: "FPF", controls: 1}, // FP flag is false
+	}
+
+	archs = append(archs, arch{
+		name:            "MIPS",
+		pkg:             "cmd/internal/obj/mips",
+		genfile:         "../../mips/ssa.go",
+		ops:             ops,
+		blocks:          blocks,
+		regnames:        regNamesMIPS,
+		gpregmask:       gp,
+		fpregmask:       fp,
+		specialregmask:  hi | lo,
+		framepointerreg: -1, // not used
+		linkreg:         int8(num["R31"]),
+	})
+}
diff --git a/src/cmd/compile/internal/ssa/_gen/PPC64.rules b/src/cmd/compile/internal/ssa/_gen/PPC64.rules
new file mode 100644
index 0000000..5a68de0
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/_gen/PPC64.rules
@@ -0,0 +1,1274 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Lowering arithmetic
+(Add(Ptr|64|32|16|8) ...) => (ADD ...)
+(Add64F ...) => (FADD ...)
+(Add32F ...) => (FADDS ...)
+
+(Sub(Ptr|64|32|16|8) ...) => (SUB ...)
+(Sub32F ...) => (FSUBS ...)
+(Sub64F ...) => (FSUB ...)
+
+// Combine 64 bit integer multiply and adds
+(ADD l:(MULLD x y) z) && buildcfg.GOPPC64 >= 9 && l.Uses == 1 && clobber(l) => (MADDLD x y z)
+
+(Mod16 x y) => (Mod32 (SignExt16to32 x) (SignExt16to32 y))
+(Mod16u x y) => (Mod32u (ZeroExt16to32 x) (ZeroExt16to32 y))
+(Mod8 x y) => (Mod32 (SignExt8to32 x) (SignExt8to32 y))
+(Mod8u x y) => (Mod32u (ZeroExt8to32 x) (ZeroExt8to32 y))
+(Mod64 x y) && buildcfg.GOPPC64 >=9 => (MODSD x y)
+(Mod64 x y) && buildcfg.GOPPC64 <=8 => (SUB x (MULLD y (DIVD x y)))
+(Mod64u x y) && buildcfg.GOPPC64 >= 9 => (MODUD x y)
+(Mod64u x y) && buildcfg.GOPPC64 <= 8 => (SUB x (MULLD y (DIVDU x y)))
+(Mod32 x y) && buildcfg.GOPPC64 >= 9 => (MODSW x y)
+(Mod32 x y) && buildcfg.GOPPC64 <= 8 => (SUB x (MULLW y (DIVW x y)))
+(Mod32u x y) && buildcfg.GOPPC64 >= 9 => (MODUW x y)
+(Mod32u x y) && buildcfg.GOPPC64 <= 8 => (SUB x (MULLW y (DIVWU x y)))
+
+// (x + y) / 2 with x>=y => (x - y) / 2 + y
+(Avg64u <t> x y) => (ADD (SRDconst <t> (SUB <t> x y) [1]) y)
+
+(Mul64 ...) => (MULLD ...)
+(Mul(32|16|8) ...) => (MULLW ...)
+(Select0 (Mul64uhilo x y)) => (MULHDU x y)
+(Select1 (Mul64uhilo x y)) => (MULLD x y)
+
+(Div64 [false] x y) => (DIVD x y)
+(Div64u ...) => (DIVDU ...)
+(Div32 [false] x y) => (DIVW x y)
+(Div32u ...) => (DIVWU ...)
+(Div16 [false]  x y) => (DIVW  (SignExt16to32 x) (SignExt16to32 y))
+(Div16u x y) => (DIVWU (ZeroExt16to32 x) (ZeroExt16to32 y))
+(Div8 x y) => (DIVW  (SignExt8to32 x) (SignExt8to32 y))
+(Div8u x y) => (DIVWU (ZeroExt8to32 x) (ZeroExt8to32 y))
+
+(Hmul(64|64u|32|32u) ...) => (MULH(D|DU|W|WU) ...)
+
+(Mul(32|64)F ...) => ((FMULS|FMUL) ...)
+
+(Div(32|64)F ...) => ((FDIVS|FDIV) ...)
+
+// Lowering float <=> int
+(Cvt32to(32|64)F x) => ((FCFIDS|FCFID) (MTVSRD (SignExt32to64 x)))
+(Cvt64to(32|64)F x) => ((FCFIDS|FCFID) (MTVSRD x))
+
+(Cvt32Fto(32|64) x) => (MFVSRD (FCTI(W|D)Z x))
+(Cvt64Fto(32|64) x) => (MFVSRD (FCTI(W|D)Z x))
+
+(Cvt32Fto64F ...) => (Copy ...) // Note v will have the wrong type for patterns dependent on Float32/Float64
+(Cvt64Fto32F ...) => (FRSP ...)
+
+(CvtBoolToUint8 ...) => (Copy ...)
+
+(Round(32|64)F ...) => (LoweredRound(32|64)F ...)
+
+(Sqrt ...) => (FSQRT ...)
+(Sqrt32 ...) => (FSQRTS ...)
+(Floor ...) => (FFLOOR ...)
+(Ceil ...) => (FCEIL ...)
+(Trunc ...) => (FTRUNC ...)
+(Round ...) => (FROUND ...)
+(Copysign x y) => (FCPSGN y x)
+(Abs ...) => (FABS ...)
+(FMA ...) => (FMADD ...)
+
+// Lowering extension
+// Note: we always extend to 64 bits even though some ops don't need that many result bits.
+(SignExt8to(16|32|64) ...) => (MOVBreg ...)
+(SignExt16to(32|64) ...) => (MOVHreg ...)
+(SignExt32to64 ...) => (MOVWreg ...)
+
+(ZeroExt8to(16|32|64) ...) => (MOVBZreg ...)
+(ZeroExt16to(32|64) ...) => (MOVHZreg ...)
+(ZeroExt32to64 ...) => (MOVWZreg ...)
+
+(Trunc(16|32|64)to8 <t> x) && isSigned(t) => (MOVBreg x)
+(Trunc(16|32|64)to8  x) => (MOVBZreg x)
+(Trunc(32|64)to16 <t> x) && isSigned(t) => (MOVHreg x)
+(Trunc(32|64)to16 x) => (MOVHZreg x)
+(Trunc64to32 <t> x) && isSigned(t) => (MOVWreg x)
+(Trunc64to32 x) => (MOVWZreg x)
+
+// Lowering constants
+(Const(64|32|16|8) [val]) => (MOVDconst [int64(val)])
+(Const(32|64)F ...) => (FMOV(S|D)const ...)
+(ConstNil) => (MOVDconst [0])
+(ConstBool [t]) => (MOVDconst [b2i(t)])
+
+// Carrying addition.
+(Select0 (Add64carry x y c)) =>            (Select0 <typ.UInt64> (ADDE x y (Select1 <typ.UInt64> (ADDCconst c [-1]))))
+(Select1 (Add64carry x y c)) => (ADDZEzero (Select1 <typ.UInt64> (ADDE x y (Select1 <typ.UInt64> (ADDCconst c [-1])))))
+// Fold initial carry bit if 0.
+(ADDE x y (Select1 <typ.UInt64> (ADDCconst (MOVDconst [0]) [-1]))) => (ADDC x y)
+// Fold transfer of CA -> GPR -> CA. Note 2 uses when feeding into a chained Add64carry.
+(Select1 (ADDCconst n:(ADDZEzero x) [-1])) && n.Uses <= 2 => x
+
+// Borrowing subtraction.
+(Select0 (Sub64borrow x y c)) =>                 (Select0 <typ.UInt64> (SUBE x y (Select1 <typ.UInt64> (SUBCconst c [0]))))
+(Select1 (Sub64borrow x y c)) => (NEG (SUBZEzero (Select1 <typ.UInt64> (SUBE x y (Select1 <typ.UInt64> (SUBCconst c [0]))))))
+// Fold initial borrow bit if 0.
+(SUBE x y (Select1 <typ.UInt64> (SUBCconst (MOVDconst [0]) [0]))) => (SUBC x y)
+// Fold transfer of CA -> GPR -> CA. Note 2 uses when feeding into a chained Sub64borrow.
+(Select1 (SUBCconst n:(NEG (SUBZEzero x)) [0])) && n.Uses <= 2 => x
+
+// Constant folding
+(FABS (FMOVDconst [x])) => (FMOVDconst [math.Abs(x)])
+(FSQRT (FMOVDconst [x])) && x >= 0 => (FMOVDconst [math.Sqrt(x)])
+(FFLOOR (FMOVDconst [x])) => (FMOVDconst [math.Floor(x)])
+(FCEIL (FMOVDconst [x])) => (FMOVDconst [math.Ceil(x)])
+(FTRUNC (FMOVDconst [x])) => (FMOVDconst [math.Trunc(x)])
+
+// Rotates
+(RotateLeft8 <t> x (MOVDconst [c])) => (Or8 (Lsh8x64 <t> x (MOVDconst [c&7])) (Rsh8Ux64 <t> x (MOVDconst [-c&7])))
+(RotateLeft16 <t> x (MOVDconst [c])) => (Or16 (Lsh16x64 <t> x (MOVDconst [c&15])) (Rsh16Ux64 <t> x (MOVDconst [-c&15])))
+(RotateLeft(32|64) ...) => ((ROTLW|ROTL) ...)
+
+// Constant rotate generation
+(ROTLW  x (MOVDconst [c])) => (ROTLWconst  x [c&31])
+(ROTL   x (MOVDconst [c])) => (ROTLconst   x [c&63])
+
+// Combine rotate and mask operations
+(Select0 (ANDCCconst [m] (ROTLWconst [r] x))) && isPPC64WordRotateMask(m) => (RLWINM [encodePPC64RotateMask(r,m,32)] x)
+(AND (MOVDconst [m]) (ROTLWconst [r] x)) && isPPC64WordRotateMask(m) => (RLWINM [encodePPC64RotateMask(r,m,32)] x)
+(Select0 (ANDCCconst [m] (ROTLW x r))) && isPPC64WordRotateMask(m) => (RLWNM [encodePPC64RotateMask(0,m,32)] x r)
+(AND (MOVDconst [m]) (ROTLW x r)) && isPPC64WordRotateMask(m) => (RLWNM [encodePPC64RotateMask(0,m,32)] x r)
+
+// Note, any rotated word bitmask is still a valid word bitmask.
+(ROTLWconst [r] (AND (MOVDconst [m]) x)) && isPPC64WordRotateMask(m) => (RLWINM [encodePPC64RotateMask(r,rotateLeft32(m,r),32)] x)
+(ROTLWconst [r] (Select0 (ANDCCconst [m] x))) && isPPC64WordRotateMask(m) => (RLWINM [encodePPC64RotateMask(r,rotateLeft32(m,r),32)] x)
+
+(Select0 (ANDCCconst [m] (SRWconst x [s]))) && mergePPC64RShiftMask(m,s,32) == 0 => (MOVDconst [0])
+(Select0 (ANDCCconst [m] (SRWconst x [s]))) && mergePPC64AndSrwi(m,s) != 0 => (RLWINM [mergePPC64AndSrwi(m,s)] x)
+(AND (MOVDconst [m]) (SRWconst x [s])) && mergePPC64RShiftMask(m,s,32) == 0 => (MOVDconst [0])
+(AND (MOVDconst [m]) (SRWconst x [s])) && mergePPC64AndSrwi(m,s) != 0 => (RLWINM [mergePPC64AndSrwi(m,s)] x)
+
+(SRWconst (Select0 (ANDCCconst [m] x)) [s]) && mergePPC64RShiftMask(m>>uint(s),s,32) == 0 => (MOVDconst [0])
+(SRWconst (Select0 (ANDCCconst [m] x)) [s]) && mergePPC64AndSrwi(m>>uint(s),s) != 0 => (RLWINM [mergePPC64AndSrwi(m>>uint(s),s)] x)
+(SRWconst (AND (MOVDconst [m]) x) [s]) && mergePPC64RShiftMask(m>>uint(s),s,32) == 0 => (MOVDconst [0])
+(SRWconst (AND (MOVDconst [m]) x) [s]) && mergePPC64AndSrwi(m>>uint(s),s) != 0 => (RLWINM [mergePPC64AndSrwi(m>>uint(s),s)] x)
+
+// Merge shift right + shift left and clear left (e.g for a table lookup)
+(CLRLSLDI [c] (SRWconst [s] x)) && mergePPC64ClrlsldiSrw(int64(c),s) != 0 => (RLWINM [mergePPC64ClrlsldiSrw(int64(c),s)] x)
+(SLDconst [l] (SRWconst [r] x)) && mergePPC64SldiSrw(l,r) != 0 => (RLWINM [mergePPC64SldiSrw(l,r)] x)
+// The following reduction shows up frequently too. e.g b[(x>>14)&0xFF]
+(CLRLSLDI [c] i:(RLWINM [s] x)) && mergePPC64ClrlsldiRlwinm(c,s) != 0 => (RLWINM [mergePPC64ClrlsldiRlwinm(c,s)] x)
+
+// large constant signed right shift, we leave the sign bit
+(Rsh64x64 x (MOVDconst [c])) && uint64(c) >= 64 => (SRADconst x [63])
+(Rsh32x64 x (MOVDconst [c])) && uint64(c) >= 32 => (SRAWconst x [63])
+(Rsh16x64 x (MOVDconst [c])) && uint64(c) >= 16 => (SRAWconst (SignExt16to32 x) [63])
+(Rsh8x64  x (MOVDconst [c])) && uint64(c) >= 8  => (SRAWconst (SignExt8to32  x) [63])
+
+// constant shifts
+((Lsh64|Rsh64|Rsh64U)x64  x (MOVDconst [c])) && uint64(c) < 64 => (S(L|RA|R)Dconst x [c])
+((Lsh32|Rsh32|Rsh32U)x64  x (MOVDconst [c])) && uint64(c) < 32 => (S(L|RA|R)Wconst x [c])
+((Rsh16|Rsh16U)x64  x (MOVDconst [c])) && uint64(c) < 16 => (SR(AW|W)const ((Sign|Zero)Ext16to32 x) [c])
+(Lsh16x64  x (MOVDconst [c])) && uint64(c) < 16 => (SLWconst x [c])
+((Rsh8|Rsh8U)x64  x (MOVDconst [c])) && uint64(c) < 8 => (SR(AW|W)const ((Sign|Zero)Ext8to32 x) [c])
+(Lsh8x64  x (MOVDconst [c])) && uint64(c) < 8 => (SLWconst x [c])
+
+// Lower bounded shifts first. No need to check shift value.
+(Lsh64x(64|32|16|8)  x y) && shiftIsBounded(v) => (SLD x y)
+(Lsh32x(64|32|16|8)  x y) && shiftIsBounded(v) => (SLW x y)
+(Lsh16x(64|32|16|8)  x y) && shiftIsBounded(v) => (SLW x y)
+(Lsh8x(64|32|16|8)   x y) && shiftIsBounded(v) => (SLW x y)
+(Rsh64Ux(64|32|16|8) x y) && shiftIsBounded(v) => (SRD x y)
+(Rsh32Ux(64|32|16|8) x y) && shiftIsBounded(v) => (SRW x y)
+(Rsh16Ux(64|32|16|8) x y) && shiftIsBounded(v) => (SRW (MOVHZreg x) y)
+(Rsh8Ux(64|32|16|8)  x y) && shiftIsBounded(v) => (SRW (MOVBZreg x) y)
+(Rsh64x(64|32|16|8)  x y) && shiftIsBounded(v) => (SRAD x y)
+(Rsh32x(64|32|16|8)  x y) && shiftIsBounded(v) => (SRAW x y)
+(Rsh16x(64|32|16|8)  x y) && shiftIsBounded(v) => (SRAW (MOVHreg x) y)
+(Rsh8x(64|32|16|8)   x y) && shiftIsBounded(v) => (SRAW (MOVBreg x) y)
+
+// non-constant rotates
+// If shift > 64 then use -1 as shift count to shift all bits.
+((Lsh64|Rsh64|Rsh64U)x64 x y)  => (S(L|RA|R)D  x (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [64]))))
+((Rsh32|Rsh32U|Lsh32)x64 x y)  => (S(RA|R|L)W x (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [32]))))
+
+(Rsh(16|16U)x64 x y)  => (SR(AW|W) ((Sign|Zero)Ext16to32 x) (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [16]))))
+(Lsh16x64 x y)  => (SLW  x                 (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [16]))))
+
+(Rsh(8|8U)x64 x y)  => (SR(AW|W) ((Sign|Zero)Ext8to32 x) (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [8]))))
+(Lsh8x64 x y)  => (SLW  x                (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [8]))))
+
+((Rsh64|Rsh64U|Lsh64)x32 x y)  => (S(RA|R|L)D x (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [64]))))
+((Rsh32|Rsh32U|Lsh32)x32 x y)  => (S(RA|R|L)W x (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [32]))))
+
+(Rsh(16|16U)x32 x y)  => (SR(AW|W) ((Sign|Zero)Ext16to32 x) (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [16]))))
+(Lsh16x32 x y)  => (SLW  x                 (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [16]))))
+
+(Rsh(8|8U)x32 x y)  => (SR(AW|W) ((Sign|Zero)Ext8to32 x) (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [8]))))
+(Lsh8x32 x y)  => (SLW  x                (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [8]))))
+
+((Rsh64|Rsh64U|Lsh64)x16 x y)  => (S(RA|R|L)D x (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt16to64 y) (MOVDconst [64]))))
+
+((Rsh32|Rsh32U|Lsh32)x16 x y)  => (S(RA|R|L)W x (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt16to64 y) (MOVDconst [32]))))
+
+(Rsh(16|16U)x16 x y)  => (S(RA|R)W ((Sign|Zero)Ext16to32 x) (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt16to64 y) (MOVDconst [16]))))
+(Lsh16x16 x y)  => (SLW  x                 (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt16to64 y) (MOVDconst [16]))))
+
+(Rsh(8|8U)x16 x y)  => (SR(AW|W) ((Sign|Zero)Ext8to32 x) (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt16to64 y) (MOVDconst [8]))))
+(Lsh8x16 x y)  => (SLW  x                (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt16to64 y) (MOVDconst [8]))))
+
+
+((Rsh64|Rsh64U|Lsh64)x8 x y)  => (S(RA|R|L)D x (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt8to64 y) (MOVDconst [64]))))
+
+((Rsh32|Rsh32U|Lsh32)x8 x y)  => (S(RA|R|L)W x (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt8to64 y) (MOVDconst [32]))))
+
+(Rsh(16|16U)x8 x y)  => (S(RA|R)W ((Sign|Zero)Ext16to32 x) (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt8to64 y) (MOVDconst [16]))))
+(Lsh16x8 x y)  => (SLW  x                 (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt8to64 y) (MOVDconst [16]))))
+
+(Rsh(8|8U)x8 x y)  => (S(RA|R)W ((Sign|Zero)Ext8to32 x) (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt8to64 y) (MOVDconst [8]))))
+(Lsh8x8 x y)  => (SLW  x                (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt8to64 y) (MOVDconst [8]))))
+
+// Cleaning up shift ops
+(ISEL [0] (Select0 (ANDCCconst [d] y)) (MOVDconst [-1]) (CMPU (Select0 (ANDCCconst [d] y)) (MOVDconst [c]))) && c >= d => (Select0 (ANDCCconst [d] y))
+(ISEL [0] (Select0 (ANDCCconst [d] y)) (MOVDconst [-1]) (CMPUconst [c] (Select0 (ANDCCconst [d] y)))) && c >= d => (Select0 (ANDCCconst [d] y))
+(ORN x (MOVDconst [-1])) => x
+
+(S(RAD|RD|LD) x (MOVDconst [c])) => (S(RAD|RD|LD)const [c&63 | (c>>6&1*63)] x)
+(S(RAW|RW|LW) x (MOVDconst [c])) => (S(RAW|RW|LW)const [c&31 | (c>>5&1*31)] x)
+
+(Addr {sym} base) => (MOVDaddr {sym} [0] base)
+(LocalAddr {sym} base _) => (MOVDaddr {sym} base)
+(OffPtr [off] ptr) => (ADD (MOVDconst <typ.Int64> [off]) ptr)
+
+// TODO: optimize these cases?
+(Ctz32NonZero ...) => (Ctz32 ...)
+(Ctz64NonZero ...) => (Ctz64 ...)
+
+(Ctz64 x) && buildcfg.GOPPC64<=8 => (POPCNTD (ANDN <typ.Int64> (ADDconst <typ.Int64> [-1] x) x))
+(Ctz64 x) => (CNTTZD x)
+(Ctz32 x) && buildcfg.GOPPC64<=8 => (POPCNTW (MOVWZreg (ANDN <typ.Int> (ADDconst <typ.Int> [-1] x) x)))
+(Ctz32 x) => (CNTTZW (MOVWZreg x))
+(Ctz16 x) => (POPCNTW (MOVHZreg (ANDN <typ.Int16> (ADDconst <typ.Int16> [-1] x) x)))
+(Ctz8 x)  => (POPCNTB (MOVBZreg (ANDN <typ.UInt8> (ADDconst <typ.UInt8> [-1] x) x)))
+
+(BitLen64 x) => (SUBFCconst [64] (CNTLZD <typ.Int> x))
+(BitLen32 x) => (SUBFCconst [32] (CNTLZW <typ.Int> x))
+
+(PopCount64 ...) => (POPCNTD ...)
+(PopCount(32|16|8) x) => (POPCNT(W|W|B) (MOV(W|H|B)Zreg x))
+
+(And(64|32|16|8) ...) => (AND ...)
+(Or(64|32|16|8) ...) => (OR ...)
+(Xor(64|32|16|8) ...) => (XOR ...)
+
+(Neg(64|32|16|8) ...) => (NEG ...)
+(Neg(64|32)F ...) => (FNEG ...)
+
+(Com(64|32|16|8) x) => (NOR x x)
+
+// Lowering boolean ops
+(AndB ...) => (AND ...)
+(OrB ...) => (OR ...)
+(Not x) => (XORconst [1] x)
+
+// Merge logical operations
+(AND x (NOR y y)) => (ANDN x y)
+(OR x (NOR y y)) => (ORN x y)
+
+// Lowering comparisons
+(EqB x y)  => (Select0 <typ.Int> (ANDCCconst [1] (EQV x y)))
+// Sign extension dependence on operand sign sets up for sign/zero-extension elision later
+(Eq(8|16) x y) && isSigned(x.Type) && isSigned(y.Type) => (Equal (CMPW (SignExt(8|16)to32 x) (SignExt(8|16)to32 y)))
+(Eq(8|16) x y) => (Equal (CMPW (ZeroExt(8|16)to32 x) (ZeroExt(8|16)to32 y)))
+(Eq(32|64|Ptr) x y) => (Equal ((CMPW|CMP|CMP) x y))
+(Eq(32|64)F x y) => (Equal (FCMPU x y))
+
+(NeqB ...) => (XOR ...)
+// Like Eq8 and Eq16, prefer sign extension likely to enable later elision.
+(Neq(8|16) x y) && isSigned(x.Type) && isSigned(y.Type) => (NotEqual (CMPW (SignExt(8|16)to32 x) (SignExt(8|16)to32 y)))
+(Neq(8|16) x y)  => (NotEqual (CMPW (ZeroExt(8|16)to32 x) (ZeroExt(8|16)to32 y)))
+(Neq(32|64|Ptr) x y) => (NotEqual ((CMPW|CMP|CMP) x y))
+(Neq(32|64)F x y) => (NotEqual (FCMPU x y))
+
+(Less(8|16) x y)  => (LessThan (CMPW (SignExt(8|16)to32 x) (SignExt(8|16)to32 y)))
+(Less(32|64) x y) => (LessThan ((CMPW|CMP) x y))
+(Less(32|64)F x y) => (FLessThan (FCMPU x y))
+
+(Less(8|16)U x y)  => (LessThan (CMPWU (ZeroExt(8|16)to32 x) (ZeroExt(8|16)to32 y)))
+(Less(32|64)U x y) => (LessThan ((CMPWU|CMPU) x y))
+
+(Leq(8|16) x y)  => (LessEqual (CMPW (SignExt(8|16)to32 x) (SignExt(8|16)to32 y)))
+(Leq(32|64) x y) => (LessEqual ((CMPW|CMP) x y))
+(Leq(32|64)F x y) => (FLessEqual (FCMPU x y))
+
+(Leq(8|16)U x y)  => (LessEqual (CMPWU (ZeroExt(8|16)to32 x) (ZeroExt(8|16)to32 y)))
+(Leq(32|64)U x y) => (LessEqual (CMP(WU|U) x y))
+
+// Absorb pseudo-ops into blocks.
+(If (Equal cc) yes no) => (EQ cc yes no)
+(If (NotEqual cc) yes no) => (NE cc yes no)
+(If (LessThan cc) yes no) => (LT cc yes no)
+(If (LessEqual cc) yes no) => (LE cc yes no)
+(If (GreaterThan cc) yes no) => (GT cc yes no)
+(If (GreaterEqual cc) yes no) => (GE cc yes no)
+(If (FLessThan cc) yes no) => (FLT cc yes no)
+(If (FLessEqual cc) yes no) => (FLE cc yes no)
+(If (FGreaterThan cc) yes no) => (FGT cc yes no)
+(If (FGreaterEqual cc) yes no) => (FGE cc yes no)
+
+(If cond yes no) => (NE (CMPWconst [0] (Select0 <typ.UInt32> (ANDCCconst [1] cond))) yes no)
+
+// Absorb boolean tests into block
+(NE (CMPWconst [0] (Select0 (ANDCCconst [1] ((Equal|NotEqual|LessThan|LessEqual|GreaterThan|GreaterEqual) cc)))) yes no) => ((EQ|NE|LT|LE|GT|GE) cc yes no)
+(NE (CMPWconst [0] (Select0 (ANDCCconst [1] ((FLessThan|FLessEqual|FGreaterThan|FGreaterEqual) cc)))) yes no) => ((FLT|FLE|FGT|FGE) cc yes no)
+
+// Elide compares of bit tests
+((EQ|NE) (CMPconst [0] (Select0 (ANDCCconst [c] x))) yes no) => ((EQ|NE) (Select1 <types.TypeFlags> (ANDCCconst [c] x)) yes no)
+((EQ|NE) (CMPWconst [0] (Select0 (ANDCCconst [c] x))) yes no) => ((EQ|NE) (Select1 <types.TypeFlags> (ANDCCconst [c] x)) yes no)
+
+// absorb flag constants into branches
+(EQ (FlagEQ) yes no) => (First yes no)
+(EQ (FlagLT) yes no) => (First no yes)
+(EQ (FlagGT) yes no) => (First no yes)
+
+(NE (FlagEQ) yes no) => (First no yes)
+(NE (FlagLT) yes no) => (First yes no)
+(NE (FlagGT) yes no) => (First yes no)
+
+(LT (FlagEQ) yes no) => (First no yes)
+(LT (FlagLT) yes no) => (First yes no)
+(LT (FlagGT) yes no) => (First no yes)
+
+(LE (FlagEQ) yes no) => (First yes no)
+(LE (FlagLT) yes no) => (First yes no)
+(LE (FlagGT) yes no) => (First no yes)
+
+(GT (FlagEQ) yes no) => (First no yes)
+(GT (FlagLT) yes no) => (First no yes)
+(GT (FlagGT) yes no) => (First yes no)
+
+(GE (FlagEQ) yes no) => (First yes no)
+(GE (FlagLT) yes no) => (First no yes)
+(GE (FlagGT) yes no) => (First yes no)
+
+// absorb InvertFlags into branches
+(LT (InvertFlags cmp) yes no) => (GT cmp yes no)
+(GT (InvertFlags cmp) yes no) => (LT cmp yes no)
+(LE (InvertFlags cmp) yes no) => (GE cmp yes no)
+(GE (InvertFlags cmp) yes no) => (LE cmp yes no)
+(EQ (InvertFlags cmp) yes no) => (EQ cmp yes no)
+(NE (InvertFlags cmp) yes no) => (NE cmp yes no)
+
+// constant comparisons
+(CMPWconst (MOVDconst [x]) [y]) && int32(x)==int32(y) => (FlagEQ)
+(CMPWconst (MOVDconst [x]) [y]) && int32(x)<int32(y)  => (FlagLT)
+(CMPWconst (MOVDconst [x]) [y]) && int32(x)>int32(y)  => (FlagGT)
+
+(CMPconst (MOVDconst [x]) [y]) && x==y => (FlagEQ)
+(CMPconst (MOVDconst [x]) [y]) && x<y  => (FlagLT)
+(CMPconst (MOVDconst [x]) [y]) && x>y  => (FlagGT)
+
+(CMPWUconst (MOVDconst [x]) [y]) && int32(x)==int32(y)  => (FlagEQ)
+(CMPWUconst (MOVDconst [x]) [y]) && uint32(x)<uint32(y) => (FlagLT)
+(CMPWUconst (MOVDconst [x]) [y]) && uint32(x)>uint32(y) => (FlagGT)
+
+(CMPUconst (MOVDconst [x]) [y]) && x==y  => (FlagEQ)
+(CMPUconst (MOVDconst [x]) [y]) && uint64(x)<uint64(y) => (FlagLT)
+(CMPUconst (MOVDconst [x]) [y]) && uint64(x)>uint64(y) => (FlagGT)
+
+// absorb flag constants into boolean values
+(Equal (FlagEQ)) => (MOVDconst [1])
+(Equal (FlagLT)) => (MOVDconst [0])
+(Equal (FlagGT)) => (MOVDconst [0])
+
+(NotEqual (FlagEQ)) => (MOVDconst [0])
+(NotEqual (FlagLT)) => (MOVDconst [1])
+(NotEqual (FlagGT)) => (MOVDconst [1])
+
+(LessThan (FlagEQ)) => (MOVDconst [0])
+(LessThan (FlagLT)) => (MOVDconst [1])
+(LessThan (FlagGT)) => (MOVDconst [0])
+
+(LessEqual (FlagEQ)) => (MOVDconst [1])
+(LessEqual (FlagLT)) => (MOVDconst [1])
+(LessEqual (FlagGT)) => (MOVDconst [0])
+
+(GreaterThan (FlagEQ)) => (MOVDconst [0])
+(GreaterThan (FlagLT)) => (MOVDconst [0])
+(GreaterThan (FlagGT)) => (MOVDconst [1])
+
+(GreaterEqual (FlagEQ)) => (MOVDconst [1])
+(GreaterEqual (FlagLT)) => (MOVDconst [0])
+(GreaterEqual (FlagGT)) => (MOVDconst [1])
+
+// absorb InvertFlags into boolean values
+((Equal|NotEqual|LessThan|GreaterThan|LessEqual|GreaterEqual) (InvertFlags x)) => ((Equal|NotEqual|GreaterThan|LessThan|GreaterEqual|LessEqual) x)
+
+
+// Elide compares of bit tests
+((EQ|NE|LT|LE|GT|GE) (CMPconst [0] (Select0 (ANDCCconst [c] x))) yes no) => ((EQ|NE|LT|LE|GT|GE) (Select1 <types.TypeFlags> (ANDCCconst [c] x)) yes no)
+((EQ|NE|LT|LE|GT|GE) (CMPWconst [0] (Select0 (ANDCCconst [c] x))) yes no) => ((EQ|NE|LT|LE|GT|GE) (Select1 <types.TypeFlags> (ANDCCconst [c] x)) yes no)
+((EQ|NE|LT|LE|GT|GE) (CMPconst [0] z:(AND x y)) yes no) && z.Uses == 1 => ((EQ|NE|LT|LE|GT|GE) (Select1 <types.TypeFlags> (ANDCC x y)) yes no)
+((EQ|NE|LT|LE|GT|GE) (CMPconst [0] z:(OR x y)) yes no) && z.Uses == 1 => ((EQ|NE|LT|LE|GT|GE) (Select1 <types.TypeFlags> (ORCC x y)) yes no)
+((EQ|NE|LT|LE|GT|GE) (CMPconst [0] z:(XOR x y)) yes no) && z.Uses == 1 => ((EQ|NE|LT|LE|GT|GE) (Select1 <types.TypeFlags> (XORCC x y)) yes no)
+
+// Only lower after bool is lowered. It should always lower. This helps ensure the folding below happens reliably.
+(CondSelect x y bool) && flagArg(bool) == nil => (ISEL [6] x y (Select1 <types.TypeFlags> (ANDCCconst [1] bool)))
+// Fold any CR -> GPR -> CR transfers when applying the above rule.
+(ISEL [6] x y (Select1 (ANDCCconst [1] (ISELB [c] one cmp)))) => (ISEL [c] x y cmp)
+
+// Lowering loads
+(Load <t> ptr mem) && (is64BitInt(t) || isPtr(t)) => (MOVDload ptr mem)
+(Load <t> ptr mem) && is32BitInt(t) && isSigned(t) => (MOVWload ptr mem)
+(Load <t> ptr mem) && is32BitInt(t) && !isSigned(t) => (MOVWZload ptr mem)
+(Load <t> ptr mem) && is16BitInt(t) && isSigned(t) => (MOVHload ptr mem)
+(Load <t> ptr mem) && is16BitInt(t) && !isSigned(t) => (MOVHZload ptr mem)
+(Load <t> ptr mem) && t.IsBoolean() => (MOVBZload ptr mem)
+(Load <t> ptr mem) && is8BitInt(t) && isSigned(t) => (MOVBreg (MOVBZload ptr mem)) // PPC has no signed-byte load.
+(Load <t> ptr mem) && is8BitInt(t) && !isSigned(t) => (MOVBZload ptr mem)
+
+(Load <t> ptr mem) && is32BitFloat(t) => (FMOVSload ptr mem)
+(Load <t> ptr mem) && is64BitFloat(t) => (FMOVDload ptr mem)
+
+(Store {t} ptr val mem) && t.Size() == 8 && is64BitFloat(val.Type) => (FMOVDstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 8 && is32BitFloat(val.Type) => (FMOVDstore ptr val mem) // glitch from (Cvt32Fto64F x) => x -- type is wrong
+(Store {t} ptr val mem) && t.Size() == 4 && is32BitFloat(val.Type) => (FMOVSstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 8 && !is64BitFloat(val.Type) => (MOVDstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 4 && is32BitInt(val.Type) => (MOVWstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 2 => (MOVHstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 1 => (MOVBstore ptr val mem)
+
+// Using Zero instead of LoweredZero allows the
+// target address to be folded where possible.
+(Zero [0] _ mem) => mem
+(Zero [1] destptr mem) => (MOVBstorezero destptr mem)
+(Zero [2] destptr mem) =>
+	(MOVHstorezero destptr mem)
+(Zero [3] destptr mem) =>
+	(MOVBstorezero [2] destptr
+		(MOVHstorezero destptr mem))
+(Zero [4] destptr mem) =>
+	(MOVWstorezero destptr mem)
+(Zero [5] destptr mem) =>
+	(MOVBstorezero [4] destptr
+        	(MOVWstorezero destptr mem))
+(Zero [6] destptr mem) =>
+	(MOVHstorezero [4] destptr
+		(MOVWstorezero destptr mem))
+(Zero [7] destptr mem) =>
+	(MOVBstorezero [6] destptr
+		(MOVHstorezero [4] destptr
+			(MOVWstorezero destptr mem)))
+
+(Zero [8] {t} destptr mem) => (MOVDstorezero destptr mem)
+(Zero [12] {t} destptr mem) =>
+        (MOVWstorezero [8] destptr
+                (MOVDstorezero [0] destptr mem))
+(Zero [16] {t} destptr mem) =>
+       (MOVDstorezero [8] destptr
+                (MOVDstorezero [0] destptr mem))
+(Zero [24] {t} destptr mem) =>
+       (MOVDstorezero [16] destptr
+               (MOVDstorezero [8] destptr
+                       (MOVDstorezero [0] destptr mem)))
+(Zero [32] {t} destptr mem) =>
+       (MOVDstorezero [24] destptr
+               (MOVDstorezero [16] destptr
+                       (MOVDstorezero [8] destptr
+                               (MOVDstorezero [0] destptr mem))))
+
+// Handle cases not handled above
+// Lowered Short cases do not generate loops, and as a result don't clobber
+// the address registers or flags.
+(Zero [s] ptr mem) && buildcfg.GOPPC64 <= 8 && s < 64 => (LoweredZeroShort [s] ptr mem)
+(Zero [s] ptr mem) && buildcfg.GOPPC64 <= 8 => (LoweredZero [s] ptr mem)
+(Zero [s] ptr mem) && s < 128 && buildcfg.GOPPC64 >= 9 => (LoweredQuadZeroShort [s] ptr mem)
+(Zero [s] ptr mem) && buildcfg.GOPPC64 >= 9 => (LoweredQuadZero [s] ptr mem)
+
+// moves
+(Move [0] _ _ mem) => mem
+(Move [1] dst src mem) => (MOVBstore dst (MOVBZload src mem) mem)
+(Move [2] dst src mem) =>
+        (MOVHstore dst (MOVHZload src mem) mem)
+(Move [4] dst src mem) =>
+	(MOVWstore dst (MOVWZload src mem) mem)
+// MOVD for load and store must have offsets that are multiple of 4
+(Move [8] {t} dst src mem) =>
+	(MOVDstore dst (MOVDload src mem) mem)
+(Move [3] dst src mem) =>
+        (MOVBstore [2] dst (MOVBZload [2] src mem)
+                (MOVHstore dst (MOVHload src mem) mem))
+(Move [5] dst src mem) =>
+        (MOVBstore [4] dst (MOVBZload [4] src mem)
+                (MOVWstore dst (MOVWZload src mem) mem))
+(Move [6] dst src mem) =>
+        (MOVHstore [4] dst (MOVHZload [4] src mem)
+                (MOVWstore dst (MOVWZload src mem) mem))
+(Move [7] dst src mem) =>
+        (MOVBstore [6] dst (MOVBZload [6] src mem)
+                (MOVHstore [4] dst (MOVHZload [4] src mem)
+                        (MOVWstore dst (MOVWZload src mem) mem)))
+
+// Large move uses a loop. Since the address is computed and the
+// offset is zero, any alignment can be used.
+(Move [s] dst src mem) && s > 8 && buildcfg.GOPPC64 <= 8 && logLargeCopy(v, s) =>
+        (LoweredMove [s] dst src mem)
+(Move [s] dst src mem) && s > 8 && s <= 64 && buildcfg.GOPPC64 >= 9 =>
+        (LoweredQuadMoveShort [s] dst src mem)
+(Move [s] dst src mem) && s > 8 && buildcfg.GOPPC64 >= 9 && logLargeCopy(v, s) =>
+        (LoweredQuadMove [s] dst src mem)
+
+// Calls
+// Lowering calls
+(StaticCall ...) => (CALLstatic ...)
+(ClosureCall ...) => (CALLclosure ...)
+(InterCall ...) => (CALLinter ...)
+(TailCall ...) => (CALLtail ...)
+
+// Miscellaneous
+(GetClosurePtr ...) => (LoweredGetClosurePtr ...)
+(GetCallerSP ...) => (LoweredGetCallerSP ...)
+(GetCallerPC ...) => (LoweredGetCallerPC ...)
+(IsNonNil ptr) => (NotEqual (CMPconst [0] ptr))
+(IsInBounds idx len) => (LessThan (CMPU idx len))
+(IsSliceInBounds idx len) => (LessEqual (CMPU idx len))
+(NilCheck ...) => (LoweredNilCheck ...)
+
+// Write barrier.
+(WB ...) => (LoweredWB ...)
+
+// Publication barrier as intrinsic
+(PubBarrier ...) => (LoweredPubBarrier ...)
+
+(PanicBounds [kind] x y mem) && boundsABI(kind) == 0 => (LoweredPanicBoundsA [kind] x y mem)
+(PanicBounds [kind] x y mem) && boundsABI(kind) == 1 => (LoweredPanicBoundsB [kind] x y mem)
+(PanicBounds [kind] x y mem) && boundsABI(kind) == 2 => (LoweredPanicBoundsC [kind] x y mem)
+
+// Optimizations
+// Note that PPC "logical" immediates come in 0:15 and 16:31 unsigned immediate forms,
+// so ORconst, XORconst easily expand into a pair.
+
+// Include very-large constants in the const-const case.
+(AND (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [c&d])
+(OR (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [c|d])
+(XOR (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [c^d])
+(ORN (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [c|^d])
+(ANDN (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [c&^d])
+(NOR (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [^(c|d)])
+
+// Discover consts
+(AND x (MOVDconst [c])) && isU16Bit(c) => (Select0 (ANDCCconst [c] x))
+(XOR x (MOVDconst [c])) && isU32Bit(c) => (XORconst [c] x)
+(OR x (MOVDconst [c])) && isU32Bit(c) => (ORconst [c] x)
+
+// Simplify consts
+(Select0 (ANDCCconst [c] (Select0 (ANDCCconst [d] x)))) => (Select0 (ANDCCconst [c&d] x))
+(ORconst [c] (ORconst [d] x)) => (ORconst [c|d] x)
+(XORconst [c] (XORconst [d] x)) => (XORconst [c^d] x)
+(Select0 (ANDCCconst [-1] x)) => x
+(Select0 (ANDCCconst [0] _)) => (MOVDconst [0])
+(XORconst [0] x) => x
+(ORconst [-1] _) => (MOVDconst [-1])
+(ORconst [0] x) => x
+
+// zero-extend of small and => small and
+(MOVBZreg y:(Select0 (ANDCCconst [c] _))) && uint64(c) <= 0xFF => y
+(MOVHZreg y:(Select0 (ANDCCconst [c] _))) && uint64(c) <= 0xFFFF => y
+(MOVWZreg y:(Select0 (ANDCCconst [c] _))) && uint64(c) <= 0xFFFFFFFF => y
+(MOVWZreg y:(AND (MOVDconst [c]) _)) && uint64(c) <= 0xFFFFFFFF => y
+
+// sign extend of small-positive and => small-positive-and
+(MOVBreg y:(Select0 (ANDCCconst [c] _))) && uint64(c) <= 0x7F => y
+(MOVHreg y:(Select0 (ANDCCconst [c] _))) && uint64(c) <= 0x7FFF => y
+(MOVWreg y:(Select0 (ANDCCconst [c] _))) && uint64(c) <= 0xFFFF => y // 0xFFFF is largest immediate constant, when regarded as 32-bit is > 0
+(MOVWreg y:(AND (MOVDconst [c]) _)) && uint64(c) <= 0x7FFFFFFF => y
+
+// small and of zero-extend => either zero-extend or small and
+(Select0 (ANDCCconst [c] y:(MOVBZreg _))) && c&0xFF == 0xFF => y
+(Select0 (ANDCCconst [0xFF] y:(MOVBreg _))) => y
+(Select0 (ANDCCconst [c] y:(MOVHZreg _)))  && c&0xFFFF == 0xFFFF => y
+(Select0 (ANDCCconst [0xFFFF] y:(MOVHreg _))) => y
+
+(AND (MOVDconst [c]) y:(MOVWZreg _))  && c&0xFFFFFFFF == 0xFFFFFFFF => y
+(AND (MOVDconst [0xFFFFFFFF]) y:(MOVWreg x)) => (MOVWZreg x)
+// normal case
+(Select0 (ANDCCconst [c] (MOV(B|BZ)reg x))) => (Select0 (ANDCCconst [c&0xFF] x))
+(Select0 (ANDCCconst [c] (MOV(H|HZ)reg x))) => (Select0 (ANDCCconst [c&0xFFFF] x))
+(Select0 (ANDCCconst [c] (MOV(W|WZ)reg x))) => (Select0 (ANDCCconst [c&0xFFFFFFFF] x))
+
+// Eliminate unnecessary sign/zero extend following right shift
+(MOV(B|H|W)Zreg (SRWconst [c] (MOVBZreg x))) => (SRWconst [c] (MOVBZreg x))
+(MOV(H|W)Zreg (SRWconst [c] (MOVHZreg x))) => (SRWconst [c] (MOVHZreg x))
+(MOVWZreg (SRWconst [c] (MOVWZreg x))) => (SRWconst [c] (MOVWZreg x))
+(MOV(B|H|W)reg (SRAWconst [c] (MOVBreg x))) => (SRAWconst [c] (MOVBreg x))
+(MOV(H|W)reg (SRAWconst [c] (MOVHreg x))) => (SRAWconst [c] (MOVHreg x))
+(MOVWreg (SRAWconst [c] (MOVWreg x))) => (SRAWconst [c] (MOVWreg x))
+
+(MOV(WZ|W)reg (S(R|RA)Wconst [c] x)) && sizeof(x.Type) <= 32 => (S(R|RA)Wconst [c] x)
+(MOV(HZ|H)reg (S(R|RA)Wconst [c] x)) && sizeof(x.Type) <= 16 => (S(R|RA)Wconst [c] x)
+(MOV(BZ|B)reg (S(R|RA)Wconst [c] x)) && sizeof(x.Type) == 8 => (S(R|RA)Wconst [c] x)
+
+// initial right shift will handle sign/zero extend
+(MOVBZreg (SRDconst [c] x)) && c>=56 => (SRDconst [c] x)
+(MOVBreg (SRDconst [c] x)) && c>56 => (SRDconst [c] x)
+(MOVBreg (SRDconst [c] x)) && c==56 => (SRADconst [c] x)
+(MOVBreg (SRADconst [c] x)) && c>=56 => (SRADconst [c] x)
+(MOVBZreg (SRWconst [c] x)) && c>=24 => (SRWconst [c] x)
+(MOVBreg (SRWconst [c] x)) && c>24 => (SRWconst [c] x)
+(MOVBreg (SRWconst [c] x)) && c==24 => (SRAWconst [c] x)
+(MOVBreg (SRAWconst [c] x)) && c>=24 => (SRAWconst [c] x)
+
+(MOVHZreg (SRDconst [c] x)) && c>=48 => (SRDconst [c] x)
+(MOVHreg (SRDconst [c] x)) && c>48 => (SRDconst [c] x)
+(MOVHreg (SRDconst [c] x)) && c==48 => (SRADconst [c] x)
+(MOVHreg (SRADconst [c] x)) && c>=48 => (SRADconst [c] x)
+(MOVHZreg (SRWconst [c] x)) && c>=16 => (SRWconst [c] x)
+(MOVHreg (SRWconst [c] x)) && c>16 => (SRWconst [c] x)
+(MOVHreg (SRAWconst [c] x)) && c>=16 => (SRAWconst [c] x)
+(MOVHreg (SRWconst [c] x)) && c==16 => (SRAWconst [c] x)
+
+(MOVWZreg (SRDconst [c] x)) && c>=32 => (SRDconst [c] x)
+(MOVWreg (SRDconst [c] x)) && c>32 => (SRDconst [c] x)
+(MOVWreg (SRADconst [c] x)) && c>=32 => (SRADconst [c] x)
+(MOVWreg (SRDconst [c] x)) && c==32 => (SRADconst [c] x)
+
+// Various redundant zero/sign extension combinations.
+(MOVBZreg y:(MOVBZreg _)) => y  // repeat
+(MOVBreg y:(MOVBreg _)) => y // repeat
+(MOVBreg (MOVBZreg x)) => (MOVBreg x)
+(MOVBZreg (MOVBreg x)) => (MOVBZreg x)
+
+// H - there are more combinations than these
+
+(MOVHZreg y:(MOV(H|B)Zreg _)) => y // repeat
+(MOVHZreg y:(MOVHBRload _ _)) => y
+
+(MOVHreg y:(MOV(H|B)reg _)) => y // repeat
+
+(MOV(H|HZ)reg y:(MOV(HZ|H)reg x)) => (MOV(H|HZ)reg x)
+
+// W - there are more combinations than these
+
+(MOV(WZ|WZ|WZ|W|W|W)reg y:(MOV(WZ|HZ|BZ|W|H|B)reg _)) => y // repeat
+(MOVWZreg y:(MOV(H|W)BRload _ _)) => y
+
+(MOV(W|WZ)reg y:(MOV(WZ|W)reg x)) => (MOV(W|WZ)reg x)
+
+// Truncate then logical then truncate: omit first, lesser or equal truncate
+(MOVWZreg ((OR|XOR|AND) <t> x (MOVWZreg y))) => (MOVWZreg ((OR|XOR|AND) <t> x y))
+(MOVHZreg ((OR|XOR|AND) <t> x (MOVWZreg y))) => (MOVHZreg ((OR|XOR|AND) <t> x y))
+(MOVHZreg ((OR|XOR|AND) <t> x (MOVHZreg y))) => (MOVHZreg ((OR|XOR|AND) <t> x y))
+(MOVBZreg ((OR|XOR|AND) <t> x (MOVWZreg y))) => (MOVBZreg ((OR|XOR|AND) <t> x y))
+(MOVBZreg ((OR|XOR|AND) <t> x (MOVHZreg y))) => (MOVBZreg ((OR|XOR|AND) <t> x y))
+(MOVBZreg ((OR|XOR|AND) <t> x (MOVBZreg y))) => (MOVBZreg ((OR|XOR|AND) <t> x y))
+
+(MOV(B|H|W)Zreg z:(Select0 (ANDCCconst [c] (MOVBZload ptr x)))) => z
+(MOV(B|H|W)Zreg z:(AND y (MOV(B|H|W)Zload ptr x))) => z
+(MOV(H|W)Zreg z:(Select0 (ANDCCconst [c] (MOVHZload ptr x)))) => z
+(MOVWZreg z:(Select0 (ANDCCconst [c] (MOVWZload ptr x)))) => z
+
+// Arithmetic constant ops
+
+(ADD x (MOVDconst [c])) && is32Bit(c) => (ADDconst [c] x)
+(ADDconst [c] (ADDconst [d] x)) && is32Bit(c+d) => (ADDconst [c+d] x)
+(ADDconst [0] x) => x
+(SUB x (MOVDconst [c])) && is32Bit(-c) => (ADDconst [-c] x)
+
+(ADDconst [c] (MOVDaddr [d] {sym} x)) && is32Bit(c+int64(d)) => (MOVDaddr [int32(c+int64(d))] {sym} x)
+(ADDconst [c] x:(SP)) && is32Bit(c) => (MOVDaddr [int32(c)] x) // so it is rematerializeable
+
+(MULL(W|D) x (MOVDconst [c])) && is16Bit(c) => (MULL(W|D)const [int32(c)] x)
+
+// Subtract from (with carry, but ignored) constant.
+// Note, these clobber the carry bit.
+(SUB (MOVDconst [c]) x) && is32Bit(c) => (SUBFCconst [c] x)
+(SUBFCconst [c] (NEG x)) => (ADDconst [c] x)
+(SUBFCconst [c] (SUBFCconst [d] x)) && is32Bit(c-d) => (ADDconst [c-d] x)
+(SUBFCconst [0] x) => (NEG x)
+(ADDconst [c] (SUBFCconst [d] x)) && is32Bit(c+d) => (SUBFCconst [c+d] x)
+(NEG (ADDconst [c] x)) && is32Bit(-c) => (SUBFCconst [-c] x)
+(NEG (SUBFCconst [c] x)) && is32Bit(-c) => (ADDconst [-c] x)
+(NEG (SUB x y)) => (SUB y x)
+(NEG (NEG x)) => x
+
+// Use register moves instead of stores and loads to move int<=>float values
+// Common with math Float64bits, Float64frombits
+(MOVDload [off] {sym} ptr (FMOVDstore [off] {sym} ptr x _)) => (MFVSRD x)
+(FMOVDload [off] {sym} ptr (MOVDstore [off] {sym} ptr x _)) => (MTVSRD x)
+
+(FMOVDstore [off] {sym} ptr (MTVSRD x) mem) => (MOVDstore [off] {sym} ptr x mem)
+(MOVDstore [off] {sym} ptr (MFVSRD x) mem) => (FMOVDstore [off] {sym} ptr x mem)
+
+(MTVSRD (MOVDconst [c])) && !math.IsNaN(math.Float64frombits(uint64(c))) => (FMOVDconst [math.Float64frombits(uint64(c))])
+(MFVSRD (FMOVDconst [c])) => (MOVDconst [int64(math.Float64bits(c))])
+
+(MTVSRD x:(MOVDload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (FMOVDload [off] {sym} ptr mem)
+(MFVSRD x:(FMOVDload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVDload [off] {sym} ptr mem)
+
+// Fold offsets for stores.
+(MOV(D|W|H|B)store [off1] {sym} (ADDconst [off2] x) val mem) && is16Bit(int64(off1)+off2) => (MOV(D|W|H|B)store [off1+int32(off2)] {sym} x val mem)
+
+(FMOV(S|D)store [off1] {sym} (ADDconst [off2] ptr) val mem) && is16Bit(int64(off1)+off2) => (FMOV(S|D)store [off1+int32(off2)] {sym} ptr val mem)
+
+// Fold address into load/store.
+// The assembler needs to generate several instructions and use
+// temp register for accessing global, and each time it will reload
+// the temp register. So don't fold address of global, unless there
+// is only one use.
+(MOV(B|H|W|D)store [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2)
+	&& is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) =>
+        (MOV(B|H|W|D)store [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
+
+(FMOV(S|D)store [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2)
+	&& is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) =>
+        (FMOV(S|D)store [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
+
+(MOV(B|H|W)Zload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
+	&& is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) =>
+        (MOV(B|H|W)Zload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+(MOV(H|W|D)load [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
+	&& is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) =>
+        (MOV(H|W|D)load [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+(FMOV(S|D)load [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
+	&& is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) =>
+        (FMOV(S|D)load [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+
+// Fold offsets for loads.
+(FMOV(S|D)load [off1] {sym} (ADDconst [off2] ptr) mem) && is16Bit(int64(off1)+off2) => (FMOV(S|D)load [off1+int32(off2)] {sym} ptr mem)
+
+(MOV(D|W|WZ|H|HZ|BZ)load [off1] {sym} (ADDconst [off2] x) mem) && is16Bit(int64(off1)+off2) => (MOV(D|W|WZ|H|HZ|BZ)load [off1+int32(off2)] {sym} x mem)
+
+// Determine load + addressing that can be done as a register indexed load
+(MOV(D|W|WZ|H|HZ|BZ)load [0] {sym} p:(ADD ptr idx) mem) && sym == nil && p.Uses == 1 => (MOV(D|W|WZ|H|HZ|BZ)loadidx ptr idx mem)
+
+// Determine if there is benefit to using a non-indexed load, since that saves the load
+// of the index register. With MOVDload and MOVWload, there is no benefit if the offset
+// value is not a multiple of 4, since that results in an extra instruction in the base
+// register address computation.
+(MOV(D|W)loadidx ptr (MOVDconst [c]) mem) && is16Bit(c) && c%4 == 0 => (MOV(D|W)load [int32(c)] ptr mem)
+(MOV(WZ|H|HZ|BZ)loadidx ptr (MOVDconst [c]) mem) && is16Bit(c) => (MOV(WZ|H|HZ|BZ)load [int32(c)] ptr mem)
+(MOV(D|W)loadidx (MOVDconst [c]) ptr mem) && is16Bit(c) && c%4 == 0 => (MOV(D|W)load [int32(c)] ptr mem)
+(MOV(WZ|H|HZ|BZ)loadidx (MOVDconst [c]) ptr mem) && is16Bit(c) => (MOV(WZ|H|HZ|BZ)load [int32(c)] ptr mem)
+
+// Store of zero => storezero
+(MOV(D|W|H|B)store [off] {sym} ptr (MOVDconst [0]) mem) => (MOV(D|W|H|B)storezero [off] {sym} ptr mem)
+
+// Fold offsets for storezero
+(MOV(D|W|H|B)storezero [off1] {sym} (ADDconst [off2] x) mem) && is16Bit(int64(off1)+off2) =>
+    (MOV(D|W|H|B)storezero [off1+int32(off2)] {sym} x mem)
+
+// Stores with addressing that can be done as indexed stores
+(MOV(D|W|H|B)store [0] {sym} p:(ADD ptr idx) val mem) && sym == nil && p.Uses == 1 => (MOV(D|W|H|B)storeidx ptr idx val mem)
+
+// Stores with constant index values can be done without indexed instructions
+// No need to lower the idx cases if c%4 is not 0
+(MOVDstoreidx ptr (MOVDconst [c]) val mem) && is16Bit(c) && c%4 == 0 => (MOVDstore [int32(c)] ptr val mem)
+(MOV(W|H|B)storeidx ptr (MOVDconst [c]) val mem) && is16Bit(c) => (MOV(W|H|B)store [int32(c)] ptr val mem)
+(MOVDstoreidx (MOVDconst [c]) ptr val mem) && is16Bit(c) && c%4 == 0 => (MOVDstore [int32(c)] ptr val mem)
+(MOV(W|H|B)storeidx (MOVDconst [c]) ptr val mem) && is16Bit(c) => (MOV(W|H|B)store [int32(c)] ptr val mem)
+
+// Fold symbols into storezero
+(MOV(D|W|H|B)storezero [off1] {sym1} p:(MOVDaddr [off2] {sym2} x) mem) && canMergeSym(sym1,sym2)
+	&& (x.Op != OpSB || p.Uses == 1) =>
+    (MOV(D|W|H|B)storezero [off1+off2] {mergeSym(sym1,sym2)} x mem)
+
+// atomic intrinsics
+(AtomicLoad(8|32|64|Ptr)  ptr mem) => (LoweredAtomicLoad(8|32|64|Ptr) [1] ptr mem)
+(AtomicLoadAcq(32|64)     ptr mem) => (LoweredAtomicLoad(32|64) [0] ptr mem)
+
+(AtomicStore(8|32|64)    ptr val mem) => (LoweredAtomicStore(8|32|64) [1] ptr val mem)
+(AtomicStoreRel(32|64)   ptr val mem) => (LoweredAtomicStore(32|64) [0] ptr val mem)
+
+(AtomicExchange(32|64) ...) => (LoweredAtomicExchange(32|64) ...)
+
+(AtomicAdd(32|64) ...) => (LoweredAtomicAdd(32|64) ...)
+
+(AtomicCompareAndSwap(32|64) ptr old new_ mem) => (LoweredAtomicCas(32|64) [1] ptr old new_ mem)
+(AtomicCompareAndSwapRel32   ptr old new_ mem) => (LoweredAtomicCas32 [0] ptr old new_ mem)
+
+(AtomicAnd(8|32)  ...) => (LoweredAtomicAnd(8|32)  ...)
+(AtomicOr(8|32)   ...) => (LoweredAtomicOr(8|32)   ...)
+
+(Slicemask <t> x) => (SRADconst (NEG <t> x) [63])
+
+// Note that MOV??reg returns a 64-bit int, x is not necessarily that wide
+// This may interact with other patterns in the future. (Compare with arm64)
+(MOV(B|H|W)Zreg x:(MOVBZload _ _)) => x
+(MOV(B|H|W)Zreg x:(MOVBZloadidx _ _ _)) => x
+(MOV(H|W)Zreg x:(MOVHZload _ _)) => x
+(MOV(H|W)Zreg x:(MOVHZloadidx _ _ _)) => x
+(MOV(H|W)reg x:(MOVHload _ _)) => x
+(MOV(H|W)reg x:(MOVHloadidx _ _ _)) => x
+(MOV(WZ|W)reg x:(MOV(WZ|W)load _ _)) => x
+(MOV(WZ|W)reg x:(MOV(WZ|W)loadidx _ _ _)) => x
+(MOV(B|W)Zreg x:(Select0 (LoweredAtomicLoad(8|32) _ _))) => x
+
+// don't extend if argument is already extended
+(MOVBreg x:(Arg <t>)) && is8BitInt(t) && isSigned(t) => x
+(MOVBZreg x:(Arg <t>)) && is8BitInt(t) && !isSigned(t) => x
+(MOVHreg x:(Arg <t>)) && (is8BitInt(t) || is16BitInt(t)) && isSigned(t) => x
+(MOVHZreg x:(Arg <t>)) && (is8BitInt(t) || is16BitInt(t)) && !isSigned(t) => x
+(MOVWreg x:(Arg <t>)) && (is8BitInt(t) || is16BitInt(t) || is32BitInt(t)) && isSigned(t) => x
+(MOVWZreg x:(Arg <t>)) && (is8BitInt(t) || is16BitInt(t) || is32BitInt(t)) && !isSigned(t) => x
+
+(MOVBZreg (MOVDconst [c]))  => (MOVDconst [int64(uint8(c))])
+(MOVBreg (MOVDconst [c]))  => (MOVDconst [int64(int8(c))])
+(MOVHZreg (MOVDconst [c]))  => (MOVDconst [int64(uint16(c))])
+(MOVHreg (MOVDconst [c]))  => (MOVDconst [int64(int16(c))])
+(MOVWreg (MOVDconst [c])) => (MOVDconst [int64(int32(c))])
+(MOVWZreg (MOVDconst [c])) => (MOVDconst [int64(uint32(c))])
+
+// Implement clrsldi and clrslwi extended mnemonics as described in
+// ISA 3.0 section C.8. AuxInt field contains values needed for
+// the instructions, packed together since there is only one available.
+(SLDconst [c] z:(MOVBZreg x)) && c < 8 && z.Uses == 1 => (CLRLSLDI [newPPC64ShiftAuxInt(c,56,63,64)] x)
+(SLDconst [c] z:(MOVHZreg x)) && c < 16 && z.Uses == 1 => (CLRLSLDI [newPPC64ShiftAuxInt(c,48,63,64)] x)
+(SLDconst [c] z:(MOVWZreg x)) && c < 32 && z.Uses == 1 => (CLRLSLDI [newPPC64ShiftAuxInt(c,32,63,64)] x)
+
+(SLDconst [c] z:(Select0 (ANDCCconst [d] x))) && z.Uses == 1 && isPPC64ValidShiftMask(d) && c <= (64-getPPC64ShiftMaskLength(d)) => (CLRLSLDI [newPPC64ShiftAuxInt(c,64-getPPC64ShiftMaskLength(d),63,64)] x)
+(SLDconst [c] z:(AND (MOVDconst [d]) x)) && z.Uses == 1 && isPPC64ValidShiftMask(d) && c<=(64-getPPC64ShiftMaskLength(d)) => (CLRLSLDI [newPPC64ShiftAuxInt(c,64-getPPC64ShiftMaskLength(d),63,64)] x)
+(SLWconst [c] z:(MOVBZreg x)) && z.Uses == 1 && c < 8 => (CLRLSLWI [newPPC64ShiftAuxInt(c,24,31,32)] x)
+(SLWconst [c] z:(MOVHZreg x)) && z.Uses == 1 && c < 16 => (CLRLSLWI [newPPC64ShiftAuxInt(c,16,31,32)] x)
+(SLWconst [c] z:(Select0 (ANDCCconst [d] x))) && z.Uses == 1 && isPPC64ValidShiftMask(d) && c<=(32-getPPC64ShiftMaskLength(d)) => (CLRLSLWI [newPPC64ShiftAuxInt(c,32-getPPC64ShiftMaskLength(d),31,32)] x)
+(SLWconst [c] z:(AND (MOVDconst [d]) x)) && z.Uses == 1 && isPPC64ValidShiftMask(d) && c<=(32-getPPC64ShiftMaskLength(d)) => (CLRLSLWI [newPPC64ShiftAuxInt(c,32-getPPC64ShiftMaskLength(d),31,32)] x)
+// special case for power9
+(SL(W|D)const [c] z:(MOVWreg x)) && c < 32 && buildcfg.GOPPC64 >= 9 => (EXTSWSLconst [c] x)
+
+// Lose widening ops fed to stores
+(MOVBstore [off] {sym} ptr (MOV(B|BZ|H|HZ|W|WZ)reg x) mem) => (MOVBstore [off] {sym} ptr x mem)
+(MOVHstore [off] {sym} ptr (MOV(H|HZ|W|WZ)reg x) mem) => (MOVHstore [off] {sym} ptr x mem)
+(MOVWstore [off] {sym} ptr (MOV(W|WZ)reg x) mem) => (MOVWstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr (SRWconst (MOV(H|HZ)reg x) [c]) mem) && c <= 8 => (MOVBstore [off] {sym} ptr (SRWconst <typ.UInt32> x [c]) mem)
+(MOVBstore [off] {sym} ptr (SRWconst (MOV(W|WZ)reg x) [c]) mem) && c <= 24 => (MOVBstore [off] {sym} ptr (SRWconst <typ.UInt32> x [c]) mem)
+(MOVBstoreidx ptr idx (MOV(B|BZ|H|HZ|W|WZ)reg x) mem) => (MOVBstoreidx ptr idx x mem)
+(MOVHstoreidx ptr idx (MOV(H|HZ|W|WZ)reg x) mem) => (MOVHstoreidx ptr idx x mem)
+(MOVWstoreidx ptr idx (MOV(W|WZ)reg x) mem) => (MOVWstoreidx ptr idx x mem)
+(MOVBstoreidx ptr idx (SRWconst (MOV(H|HZ)reg x) [c]) mem) && c <= 8 => (MOVBstoreidx ptr idx (SRWconst <typ.UInt32> x [c]) mem)
+(MOVBstoreidx ptr idx (SRWconst (MOV(W|WZ)reg x) [c]) mem) && c <= 24 => (MOVBstoreidx ptr idx (SRWconst <typ.UInt32> x [c]) mem)
+(MOVHBRstore {sym} ptr (MOV(H|HZ|W|WZ)reg x) mem) => (MOVHBRstore {sym} ptr x mem)
+(MOVWBRstore {sym} ptr (MOV(W|WZ)reg x) mem) => (MOVWBRstore {sym} ptr x mem)
+
+// Lose W-widening ops fed to compare-W
+(CMP(W|WU) x (MOV(W|WZ)reg y)) => (CMP(W|WU) x y)
+(CMP(W|WU) (MOV(W|WZ)reg x) y) => (CMP(W|WU) x y)
+
+(CMP x (MOVDconst [c])) && is16Bit(c) => (CMPconst x [c])
+(CMP (MOVDconst [c]) y) && is16Bit(c) => (InvertFlags (CMPconst y [c]))
+(CMPW x (MOVDconst [c])) && is16Bit(c) => (CMPWconst x [int32(c)])
+(CMPW (MOVDconst [c]) y) && is16Bit(c) => (InvertFlags (CMPWconst y [int32(c)]))
+
+(CMPU x (MOVDconst [c])) && isU16Bit(c) => (CMPUconst x [c])
+(CMPU (MOVDconst [c]) y) && isU16Bit(c) => (InvertFlags (CMPUconst y [c]))
+(CMPWU x (MOVDconst [c])) && isU16Bit(c) => (CMPWUconst x [int32(c)])
+(CMPWU (MOVDconst [c]) y) && isU16Bit(c) => (InvertFlags (CMPWUconst y [int32(c)]))
+
+// Canonicalize the order of arguments to comparisons - helps with CSE.
+((CMP|CMPW|CMPU|CMPWU) x y) && canonLessThan(x,y) => (InvertFlags ((CMP|CMPW|CMPU|CMPWU) y x))
+
+// ISEL auxInt values 0=LT 1=GT 2=EQ   arg2 ? arg0 : arg1
+// ISEL auxInt values 4=GE 5=LE 6=NE   !arg2 ? arg1 : arg0
+// ISELB special case where arg0, arg1 values are 0, 1
+
+(Equal cmp) => (ISELB [2] (MOVDconst [1]) cmp)
+(NotEqual cmp) => (ISELB [6] (MOVDconst [1]) cmp)
+(LessThan cmp) => (ISELB [0] (MOVDconst [1]) cmp)
+(FLessThan cmp) => (ISELB [0] (MOVDconst [1]) cmp)
+(FLessEqual cmp) => (ISEL [2] (MOVDconst [1]) (ISELB [0] (MOVDconst [1]) cmp) cmp)
+(GreaterEqual cmp) => (ISELB [4] (MOVDconst [1]) cmp)
+(GreaterThan cmp) => (ISELB [1] (MOVDconst [1]) cmp)
+(FGreaterThan cmp) => (ISELB [1] (MOVDconst [1]) cmp)
+(FGreaterEqual cmp) => (ISEL [2] (MOVDconst [1]) (ISELB [1] (MOVDconst [1]) cmp) cmp)
+(LessEqual cmp) => (ISELB [5] (MOVDconst [1]) cmp)
+
+(ISELB [0] _ (FlagLT)) => (MOVDconst [1])
+(ISELB [0] _ (Flag(GT|EQ))) => (MOVDconst [0])
+(ISELB [1] _ (FlagGT)) => (MOVDconst [1])
+(ISELB [1] _ (Flag(LT|EQ))) => (MOVDconst [0])
+(ISELB [2] _ (FlagEQ)) => (MOVDconst [1])
+(ISELB [2] _ (Flag(LT|GT))) => (MOVDconst [0])
+(ISELB [4] _ (FlagLT)) => (MOVDconst [0])
+(ISELB [4] _ (Flag(GT|EQ))) => (MOVDconst [1])
+(ISELB [5] _ (FlagGT)) => (MOVDconst [0])
+(ISELB [5] _ (Flag(LT|EQ))) => (MOVDconst [1])
+(ISELB [6] _ (FlagEQ)) => (MOVDconst [0])
+(ISELB [6] _ (Flag(LT|GT))) => (MOVDconst [1])
+
+(ISEL [2] x _ (FlagEQ)) => x
+(ISEL [2] _ y (Flag(LT|GT))) => y
+
+(ISEL [6] _ y (FlagEQ)) => y
+(ISEL [6] x _ (Flag(LT|GT))) => x
+
+(ISEL [0] _ y (Flag(EQ|GT))) => y
+(ISEL [0] x _ (FlagLT)) => x
+
+(ISEL [5] _ x (Flag(EQ|LT))) => x
+(ISEL [5] y _ (FlagGT)) => y
+
+(ISEL [1] _ y (Flag(EQ|LT))) => y
+(ISEL [1] x _ (FlagGT)) => x
+
+(ISEL [4] x _ (Flag(EQ|GT))) => x
+(ISEL [4] _ y (FlagLT)) => y
+
+(ISEL [2] x y ((CMP|CMPW)const [0] (Select0 (ANDCCconst [n] z)))) => (ISEL [2] x y (Select1 <types.TypeFlags> (ANDCCconst [n] z )))
+(ISEL [6] x y ((CMP|CMPW)const [0] (Select0 (ANDCCconst [n] z)))) => (ISEL [6] x y (Select1 <types.TypeFlags> (ANDCCconst [n] z )))
+(ISELB [2] x ((CMP|CMPW)const [0] (Select0 (ANDCCconst [1] z)))) => (XORconst [1] (Select0 <typ.UInt64> (ANDCCconst [1] z )))
+(ISELB [6] x ((CMP|CMPW)const [0] (Select0 (ANDCCconst [1] z)))) => (Select0 <typ.UInt64> (ANDCCconst [1] z ))
+
+(ISELB [2] x (CMPWconst [0] (Select0 (ANDCCconst [n] z)))) => (ISELB [2] x (Select1 <types.TypeFlags> (ANDCCconst [n] z )))
+(ISELB [6] x (CMPWconst [0] (Select0 (ANDCCconst [n] z)))) => (ISELB [6] x (Select1 <types.TypeFlags> (ANDCCconst [n] z )))
+
+// Only CMPconst for these in case AND|OR|XOR result is > 32 bits
+(ISELB [2] x (CMPconst [0] a:(AND y z))) && a.Uses == 1 => (ISELB [2] x (Select1 <types.TypeFlags> (ANDCC y z )))
+(ISELB [6] x (CMPconst [0] a:(AND y z))) && a.Uses == 1 => (ISELB [6] x (Select1 <types.TypeFlags> (ANDCC y z )))
+
+(ISELB [2] x (CMPconst [0] o:(OR y z))) && o.Uses == 1 => (ISELB [2] x (Select1 <types.TypeFlags> (ORCC y z )))
+(ISELB [6] x (CMPconst [0] o:(OR y z))) && o.Uses == 1 => (ISELB [6] x (Select1 <types.TypeFlags> (ORCC y z )))
+
+(ISELB [2] x (CMPconst [0] a:(XOR y z))) && a.Uses == 1 => (ISELB [2] x (Select1 <types.TypeFlags> (XORCC y z )))
+(ISELB [6] x (CMPconst [0] a:(XOR y z))) && a.Uses == 1 => (ISELB [6] x (Select1 <types.TypeFlags> (XORCC y z )))
+
+(ISELB [n] (MOVDconst [1]) (InvertFlags bool)) && n%4 == 0 => (ISELB [n+1] (MOVDconst [1]) bool)
+(ISELB [n] (MOVDconst [1]) (InvertFlags bool)) && n%4 == 1 => (ISELB [n-1] (MOVDconst [1]) bool)
+(ISELB [n] (MOVDconst [1]) (InvertFlags bool)) && n%4 == 2 => (ISELB [n] (MOVDconst [1]) bool)
+(ISEL [n] x y (InvertFlags bool)) && n%4 == 0 => (ISEL [n+1] x y bool)
+(ISEL [n] x y (InvertFlags bool)) && n%4 == 1 => (ISEL [n-1] x y bool)
+(ISEL [n] x y (InvertFlags bool)) && n%4 == 2 => (ISEL [n] x y bool)
+(XORconst [1] (ISELB [6] (MOVDconst [1]) cmp)) => (ISELB [2] (MOVDconst [1]) cmp)
+(XORconst [1] (ISELB [5] (MOVDconst [1]) cmp)) => (ISELB [1] (MOVDconst [1]) cmp)
+(XORconst [1] (ISELB [4] (MOVDconst [1]) cmp)) => (ISELB [0] (MOVDconst [1]) cmp)
+
+// A particular pattern seen in cgo code:
+(AND (MOVDconst [c]) x:(MOVBZload _ _)) => (Select0 (ANDCCconst [c&0xFF] x))
+
+// floating point negative abs
+(FNEG (F(ABS|NABS) x)) => (F(NABS|ABS) x)
+
+// floating-point fused multiply-add/sub
+(F(ADD|SUB) (FMUL x y) z) && x.Block.Func.useFMA(v) => (FM(ADD|SUB) x y z)
+(F(ADDS|SUBS) (FMULS x y) z) && x.Block.Func.useFMA(v) => (FM(ADDS|SUBS) x y z)
+
+// The following statements are found in encoding/binary functions UintXX (load) and PutUintXX (store)
+// and convert the statements in these functions from multiple single byte loads or stores to
+// the single largest possible load or store.
+// Some are marked big or little endian based on the order in which the bytes are loaded or stored,
+// not on the ordering of the machine. These are intended for little endian machines.
+// To implement for big endian machines, most rules would have to be duplicated but the
+// resulting rule would be reversed, i. e., MOVHZload on little endian would be MOVHBRload on big endian
+// and vice versa.
+// b[0] | b[1]<<8 => load 16-bit Little endian
+(OR <t> x0:(MOVBZload [i0] {s} p mem)
+	o1:(SL(W|D)const x1:(MOVBZload [i1] {s} p mem) [8]))
+	&& !config.BigEndian
+	&& i1 == i0+1
+	&& x0.Uses ==1 && x1.Uses == 1
+	&& o1.Uses == 1
+	&& mergePoint(b, x0, x1) != nil
+	&& clobber(x0, x1, o1)
+	 => @mergePoint(b,x0,x1) (MOVHZload <t> {s} [i0] p mem)
+
+// b[0]<<8 | b[1] => load 16-bit Big endian on Little endian arch.
+// Use byte-reverse indexed load for 2 bytes.
+(OR <t> x0:(MOVBZload [i1] {s} p mem)
+	o1:(SL(W|D)const x1:(MOVBZload [i0] {s} p mem) [8]))
+	&& !config.BigEndian
+	&& i1 == i0+1
+	&& x0.Uses ==1 && x1.Uses == 1
+	&& o1.Uses == 1
+	&& mergePoint(b, x0, x1) != nil
+	&& clobber(x0, x1, o1)
+	  => @mergePoint(b,x0,x1) (MOVHBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem)
+
+// b[0]<<n+8 | b[1]<<n => load 16-bit Big endian (where n%8== 0)
+// Use byte-reverse indexed load for 2 bytes,
+// then shift left to the correct position. Used to match subrules
+// from longer rules.
+(OR <t> s0:(SL(W|D)const x0:(MOVBZload [i1] {s} p mem) [n1])
+	s1:(SL(W|D)const x1:(MOVBZload [i0] {s} p mem) [n2]))
+	&& !config.BigEndian
+	&& i1 == i0+1
+	&& n1%8 == 0
+	&& n2 == n1+8
+	&& x0.Uses == 1 && x1.Uses == 1
+	&& s0.Uses == 1 && s1.Uses == 1
+	&& mergePoint(b, x0, x1) != nil
+	&& clobber(x0, x1, s0, s1)
+	  => @mergePoint(b,x0,x1) (SLDconst <t> (MOVHBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem) [n1])
+
+// b[0] | b[1]<<8 | b[2]<<16 | b[3]<<24 => load 32-bit Little endian
+// Use byte-reverse indexed load for 4 bytes.
+(OR <t> s1:(SL(W|D)const x2:(MOVBZload [i3] {s} p mem) [24])
+	o0:(OR <t> s0:(SL(W|D)const x1:(MOVBZload [i2] {s} p mem) [16])
+	x0:(MOVHZload [i0] {s} p mem)))
+	&& !config.BigEndian
+	&& i2 == i0+2
+	&& i3 == i0+3
+	&& x0.Uses ==1 && x1.Uses == 1 && x2.Uses == 1
+	&& o0.Uses == 1
+	&& s0.Uses == 1 && s1.Uses == 1
+	&& mergePoint(b, x0, x1, x2) != nil
+	&& clobber(x0, x1, x2, s0, s1, o0)
+	 => @mergePoint(b,x0,x1,x2) (MOVWZload <t> {s} [i0] p mem)
+
+// b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3] => load 32-bit Big endian order on Little endian arch
+// Use byte-reverse indexed load for 4 bytes with computed address.
+// Could be used to match subrules of a longer rule.
+(OR <t> s1:(SL(W|D)const x2:(MOVBZload [i0] {s} p mem) [24])
+	o0:(OR <t> s0:(SL(W|D)const x1:(MOVBZload [i1] {s} p mem) [16])
+	x0:(MOVHBRload <t> (MOVDaddr <typ.Uintptr> [i2] {s} p) mem)))
+	&& !config.BigEndian
+	&& i1 == i0+1
+	&& i2 == i0+2
+	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1
+	&& o0.Uses == 1
+	&& s0.Uses == 1 && s1.Uses == 1
+	&& mergePoint(b, x0, x1, x2) != nil
+	&& clobber(x0, x1, x2, s0, s1, o0)
+	  => @mergePoint(b,x0,x1,x2) (MOVWBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem)
+
+// b[3] | b[2]<<8 | b[1]<<16 | b[0]<<24 => load 32-bit Big endian order on Little endian arch
+// Use byte-reverse indexed load for 4 bytes with computed address.
+// Could be used to match subrules of a longer rule.
+(OR <t> x0:(MOVBZload [i3] {s} p mem)
+	o0:(OR <t> s0:(SL(W|D)const x1:(MOVBZload [i2] {s} p mem) [8])
+	s1:(SL(W|D)const x2:(MOVHBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem) [16])))
+	&& !config.BigEndian
+	&& i2 == i0+2
+	&& i3 == i0+3
+	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1
+	&& o0.Uses == 1
+	&& s0.Uses == 1 && s1.Uses == 1
+	&& mergePoint(b, x0, x1, x2) != nil
+	&& clobber(x0, x1, x2, s0, s1, o0)
+	  => @mergePoint(b,x0,x1,x2) (MOVWBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem)
+
+// b[0]<<56 | b[1]<<48 | b[2]<<40 | b[3]<<32 => load 32-bit Big endian order on Little endian arch
+// Use byte-reverse indexed load to for 4 bytes with computed address.
+// Used to match longer rules.
+(OR <t> s2:(SLDconst x2:(MOVBZload [i3] {s} p mem) [32])
+	o0:(OR <t> s1:(SLDconst x1:(MOVBZload [i2] {s} p mem) [40])
+	s0:(SLDconst x0:(MOVHBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem) [48])))
+	&& !config.BigEndian
+	&& i2 == i0+2
+	&& i3 == i0+3
+	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1
+	&& o0.Uses == 1
+	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1
+	&& mergePoint(b, x0, x1, x2) != nil
+	&& clobber(x0, x1, x2, s0, s1, s2, o0)
+	  => @mergePoint(b,x0,x1,x2) (SLDconst <t> (MOVWBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem) [32])
+
+// b[3]<<32 | b[2]<<40 | b[1]<<48 | b[0]<<56 => load 32-bit Big endian order on Little endian arch
+// Use byte-reverse indexed load for 4 bytes with constant address.
+// Used to match longer rules.
+(OR <t> s2:(SLDconst x2:(MOVBZload [i0] {s} p mem) [56])
+        o0:(OR <t> s1:(SLDconst x1:(MOVBZload [i1] {s} p mem) [48])
+        s0:(SLDconst x0:(MOVHBRload <t> (MOVDaddr <typ.Uintptr> [i2] {s} p) mem) [32])))
+        && !config.BigEndian
+        && i1 == i0+1
+        && i2 == i0+2
+        && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1
+        && o0.Uses == 1
+        && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1
+        && mergePoint(b, x0, x1, x2) != nil
+        && clobber(x0, x1, x2, s0, s1, s2, o0)
+          => @mergePoint(b,x0,x1,x2) (SLDconst <t> (MOVWBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem) [32])
+
+// b[0] | b[1]<<8 | b[2]<<16 | b[3]<<24 | b[4] <<32 | b[5]<<40 | b[6]<<48 | b[7]<<56 => load 64-bit Little endian
+// Rules with commutative ops and many operands will result in extremely large functions in rewritePPC64,
+// so matching shorter previously defined subrules is important.
+// Offset must be multiple of 4 for MOVD
+(OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56])
+	o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])
+	o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40])
+	o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])
+	x0:(MOVWZload {s} [i0] p mem)))))
+	&& !config.BigEndian
+	&& i4 == i0+4
+	&& i5 == i0+5
+	&& i6 == i0+6
+	&& i7 == i0+7
+	&& x0.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1
+	&& o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1
+	&& s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1
+	&& mergePoint(b, x0, x4, x5, x6, x7) != nil
+	&& clobber(x0, x4, x5, x6, x7, s3, s4, s5, s6, o3, o4, o5)
+	  => @mergePoint(b,x0,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
+
+// b[7] | b[6]<<8 | b[5]<<16 | b[4]<<24 | b[3]<<32 | b[2]<<40 | b[1]<<48 | b[0]<<56 load 64-bit Big endian ordered bytes on Little endian arch
+// Use byte-reverse indexed load of 8 bytes.
+// Rules with commutative ops and many operands can result in extremely large functions in rewritePPC64,
+// so matching shorter previously defined subrules is important.
+(OR <t> s0:(SLDconst x0:(MOVBZload [i0] {s} p mem) [56])
+	o0:(OR <t> s1:(SLDconst x1:(MOVBZload [i1] {s} p mem) [48])
+	o1:(OR <t> s2:(SLDconst x2:(MOVBZload [i2] {s} p mem) [40])
+	o2:(OR <t> s3:(SLDconst x3:(MOVBZload [i3] {s} p mem) [32])
+	x4:(MOVWBRload <t> (MOVDaddr <typ.Uintptr> [i4] p) mem)))))
+	&& !config.BigEndian
+	&& i1 == i0+1
+	&& i2 == i0+2
+	&& i3 == i0+3
+	&& i4 == i0+4
+	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1
+	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1
+	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1
+	&& mergePoint(b, x0, x1, x2, x3, x4) != nil
+	&& clobber(x0, x1, x2, x3, x4, o0, o1, o2, s0, s1, s2, s3)
+	  => @mergePoint(b,x0,x1,x2,x3,x4) (MOVDBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem)
+
+// b[0]<<56 | b[1]<<48 | b[2]<<40 | b[3]<<32 | b[4]<<24 | b[5]<<16 | b[6]<<8 | b[7] => load 64-bit Big endian ordered bytes on Little endian arch
+// Use byte-reverse indexed load of 8 bytes.
+// Rules with commutative ops and many operands can result in extremely large functions in rewritePPC64,
+// so matching shorter previously defined subrules is important.
+(OR <t> x7:(MOVBZload [i7] {s} p mem)
+	o5:(OR <t> s6:(SLDconst x6:(MOVBZload [i6] {s} p mem) [8])
+	o4:(OR <t> s5:(SLDconst x5:(MOVBZload [i5] {s} p mem) [16])
+	o3:(OR <t> s4:(SLDconst x4:(MOVBZload [i4] {s} p mem) [24])
+	s0:(SL(W|D)const x3:(MOVWBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem) [32])))))
+	&& !config.BigEndian
+	&& i4 == i0+4
+	&& i5 == i0+5
+	&& i6 == i0+6
+	&& i7 == i0+7
+	&& x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1
+	&& o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1
+	&& s0.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1
+	&& mergePoint(b, x3, x4, x5, x6, x7) != nil
+	&& clobber(x3, x4, x5, x6, x7, o3, o4, o5, s0, s4, s5, s6)
+	=> @mergePoint(b,x3,x4,x5,x6,x7) (MOVDBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem)
+
+// 2 byte store Little endian as in:
+//      b[0] = byte(v >> 16)
+//      b[1] = byte(v >> 24)
+// Added for use in matching longer rules.
+(MOVBstore [i1] {s} p (SR(W|D)const w [24])
+        x0:(MOVBstore [i0] {s} p (SR(W|D)const w [16]) mem))
+        && !config.BigEndian
+        && x0.Uses == 1
+        && i1 == i0+1
+        && clobber(x0)
+          => (MOVHstore [i0] {s} p (SRWconst <typ.UInt16> w [16]) mem)
+
+// 2 byte store Little endian as in:
+//      b[0] = byte(v)
+//      b[1] = byte(v >> 8)
+(MOVBstore [i1] {s} p (SR(W|D)const w [8])
+	x0:(MOVBstore [i0] {s} p w mem))
+	&& !config.BigEndian
+	&& x0.Uses == 1
+	&& i1 == i0+1
+	&& clobber(x0)
+	  => (MOVHstore [i0] {s} p w mem)
+
+// 4 byte store Little endian as in:
+//     b[0:1] = uint16(v)
+//     b[2:3] = uint16(v >> 16)
+(MOVHstore [i1] {s} p (SR(W|D)const w [16])
+	x0:(MOVHstore [i0] {s} p w mem))
+	&& !config.BigEndian
+	&& x0.Uses == 1
+	&& i1 == i0+2
+	&& clobber(x0)
+	  => (MOVWstore [i0] {s} p w mem)
+
+// 4 byte store Big endian as in:
+//     b[0] = byte(v >> 24)
+//     b[1] = byte(v >> 16)
+//     b[2] = byte(v >> 8)
+//     b[3] = byte(v)
+// Use byte-reverse indexed 4 byte store.
+(MOVBstore [i3] {s} p w
+	x0:(MOVBstore [i2] {s} p (SRWconst w [8])
+	x1:(MOVBstore [i1] {s} p (SRWconst w [16])
+	x2:(MOVBstore [i0] {s} p (SRWconst w [24]) mem))))
+	&& !config.BigEndian
+	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1
+	&& i1 == i0+1 && i2 == i0+2 && i3 == i0+3
+	&& clobber(x0, x1, x2)
+	  => (MOVWBRstore (MOVDaddr <typ.Uintptr> [i0] {s} p) w mem)
+
+// The 2 byte store appears after the 4 byte store so that the
+// match for the 2 byte store is not done first.
+// If the 4 byte store is based on the 2 byte store then there are
+// variations on the MOVDaddr subrule that would require additional
+// rules to be written.
+
+// 2 byte store Big endian as in:
+//      b[0] = byte(v >> 8)
+//      b[1] = byte(v)
+(MOVBstore [i1] {s} p w x0:(MOVBstore [i0] {s} p (SRWconst w [8]) mem))
+	&& !config.BigEndian
+	&& x0.Uses == 1
+	&& i1 == i0+1
+	&& clobber(x0)
+	  => (MOVHBRstore (MOVDaddr <typ.Uintptr> [i0] {s} p) w mem)
+
+// 8 byte store Little endian as in:
+//	b[0] = byte(v)
+//	b[1] = byte(v >> 8)
+//	b[2] = byte(v >> 16)
+//	b[3] = byte(v >> 24)
+//	b[4] = byte(v >> 32)
+//	b[5] = byte(v >> 40)
+//	b[6] = byte(v >> 48)
+//	b[7] = byte(v >> 56)
+// Built on previously defined rules
+// Offset must be multiple of 4 for MOVDstore
+(MOVBstore [i7] {s} p (SRDconst w [56])
+	x0:(MOVBstore [i6] {s} p (SRDconst w [48])
+	x1:(MOVBstore [i5] {s} p (SRDconst w [40])
+	x2:(MOVBstore [i4] {s} p (SRDconst w [32])
+	x3:(MOVWstore [i0] {s} p w mem)))))
+	&& !config.BigEndian
+	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
+	&& i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7
+	&& clobber(x0, x1, x2, x3)
+	  => (MOVDstore [i0] {s} p w mem)
+
+// 8 byte store Big endian as in:
+//      b[0] = byte(v >> 56)
+//      b[1] = byte(v >> 48)
+//      b[2] = byte(v >> 40)
+//      b[3] = byte(v >> 32)
+//      b[4] = byte(v >> 24)
+//      b[5] = byte(v >> 16)
+//      b[6] = byte(v >> 8)
+//      b[7] = byte(v)
+// Use byte-reverse indexed 8 byte store.
+(MOVBstore [i7] {s} p w
+        x0:(MOVBstore [i6] {s} p (SRDconst w [8])
+        x1:(MOVBstore [i5] {s} p (SRDconst w [16])
+        x2:(MOVBstore [i4] {s} p (SRDconst w [24])
+        x3:(MOVBstore [i3] {s} p (SRDconst w [32])
+        x4:(MOVBstore [i2] {s} p (SRDconst w [40])
+        x5:(MOVBstore [i1] {s} p (SRDconst w [48])
+        x6:(MOVBstore [i0] {s} p (SRDconst w [56]) mem))))))))
+        && !config.BigEndian
+        && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1
+        && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7
+        && clobber(x0, x1, x2, x3, x4, x5, x6)
+          => (MOVDBRstore (MOVDaddr <typ.Uintptr> [i0] {s} p) w mem)
+
+// Arch-specific inlining for small or disjoint runtime.memmove
+(SelectN [0] call:(CALLstatic {sym} s1:(MOVDstore _ (MOVDconst [sz]) s2:(MOVDstore  _ src s3:(MOVDstore {t} _ dst mem)))))
+        && sz >= 0
+        && isSameCall(sym, "runtime.memmove")
+        && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1
+        && isInlinableMemmove(dst, src, sz, config)
+        && clobber(s1, s2, s3, call)
+        => (Move [sz] dst src mem)
+
+// Match post-lowering calls, register version.
+(SelectN [0] call:(CALLstatic {sym} dst src (MOVDconst [sz]) mem))
+        && sz >= 0
+        && isSameCall(sym, "runtime.memmove")
+        && call.Uses == 1
+        && isInlinableMemmove(dst, src, sz, config)
+        && clobber(call)
+        => (Move [sz] dst src mem)
+
+// Prefetch instructions (TH specified using aux field)
+// For DCBT Ra,Rb,TH, A value of TH indicates:
+//     0, hint this cache line will be used soon. (PrefetchCache)
+//     16, hint this cache line will not be used for long. (PrefetchCacheStreamed)
+// See ISA 3.0 Book II 4.3.2 for more detail. https://openpower.foundation/specifications/isa/
+(PrefetchCache ptr mem)          => (DCBT ptr mem [0])
+(PrefetchCacheStreamed ptr mem)  => (DCBT ptr mem [16])
+
diff --git a/src/cmd/compile/internal/ssa/_gen/PPC64Ops.go b/src/cmd/compile/internal/ssa/_gen/PPC64Ops.go
new file mode 100644
index 0000000..2d651dd
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/_gen/PPC64Ops.go
@@ -0,0 +1,740 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "strings"
+
+// Notes:
+//  - Less-than-64-bit integer types live in the low portion of registers.
+//    The upper portion is junk.
+//  - Boolean types are zero or 1; stored in a byte, with upper bytes of the register containing junk.
+//  - *const instructions may use a constant larger than the instruction can encode.
+//    In this case the assembler expands to multiple instructions and uses tmp
+//    register (R31).
+
+var regNamesPPC64 = []string{
+	"R0", // REGZERO, not used, but simplifies counting in regalloc
+	"SP", // REGSP
+	"SB", // REGSB
+	"R3",
+	"R4",
+	"R5",
+	"R6",
+	"R7",
+	"R8",
+	"R9",
+	"R10",
+	"R11", // REGCTXT for closures
+	"R12",
+	"R13", // REGTLS
+	"R14",
+	"R15",
+	"R16",
+	"R17",
+	"R18",
+	"R19",
+	"R20",
+	"R21",
+	"R22",
+	"R23",
+	"R24",
+	"R25",
+	"R26",
+	"R27",
+	"R28",
+	"R29",
+	"g",   // REGG.  Using name "g" and setting Config.hasGReg makes it "just happen".
+	"R31", // REGTMP
+
+	"F0",
+	"F1",
+	"F2",
+	"F3",
+	"F4",
+	"F5",
+	"F6",
+	"F7",
+	"F8",
+	"F9",
+	"F10",
+	"F11",
+	"F12",
+	"F13",
+	"F14",
+	"F15",
+	"F16",
+	"F17",
+	"F18",
+	"F19",
+	"F20",
+	"F21",
+	"F22",
+	"F23",
+	"F24",
+	"F25",
+	"F26",
+	"F27",
+	"F28",
+	"F29",
+	"F30",
+	// "F31", the allocator is limited to 64 entries. We sacrifice this FPR to support XER.
+
+	"XER",
+
+	// If you add registers, update asyncPreempt in runtime.
+
+	// "CR0",
+	// "CR1",
+	// "CR2",
+	// "CR3",
+	// "CR4",
+	// "CR5",
+	// "CR6",
+	// "CR7",
+
+	// "CR",
+	// "LR",
+	// "CTR",
+}
+
+func init() {
+	// Make map from reg names to reg integers.
+	if len(regNamesPPC64) > 64 {
+		panic("too many registers")
+	}
+	num := map[string]int{}
+	for i, name := range regNamesPPC64 {
+		num[name] = i
+	}
+	buildReg := func(s string) regMask {
+		m := regMask(0)
+		for _, r := range strings.Split(s, " ") {
+			if n, ok := num[r]; ok {
+				m |= regMask(1) << uint(n)
+				continue
+			}
+			panic("register " + r + " not found")
+		}
+		return m
+	}
+
+	var (
+		gp  = buildReg("R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29")
+		fp  = buildReg("F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30")
+		sp  = buildReg("SP")
+		sb  = buildReg("SB")
+		gr  = buildReg("g")
+		xer = buildReg("XER")
+		// cr  = buildReg("CR")
+		// ctr = buildReg("CTR")
+		// lr  = buildReg("LR")
+		tmp     = buildReg("R31")
+		ctxt    = buildReg("R11")
+		callptr = buildReg("R12")
+		// tls = buildReg("R13")
+		gp01        = regInfo{inputs: nil, outputs: []regMask{gp}}
+		gp11        = regInfo{inputs: []regMask{gp | sp | sb}, outputs: []regMask{gp}}
+		xergp       = regInfo{inputs: []regMask{xer}, outputs: []regMask{gp}, clobbers: xer}
+		gp11cxer    = regInfo{inputs: []regMask{gp | sp | sb}, outputs: []regMask{gp}, clobbers: xer}
+		gp11xer     = regInfo{inputs: []regMask{gp | sp | sb}, outputs: []regMask{gp, xer}}
+		gp21        = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb}, outputs: []regMask{gp}}
+		gp21a0      = regInfo{inputs: []regMask{gp, gp | sp | sb}, outputs: []regMask{gp}}
+		gp21cxer    = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb}, outputs: []regMask{gp}, clobbers: xer}
+		gp21xer     = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb}, outputs: []regMask{gp, xer}, clobbers: xer}
+		gp2xer1xer  = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb, xer}, outputs: []regMask{gp, xer}, clobbers: xer}
+		gp31        = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb, gp | sp | sb}, outputs: []regMask{gp}}
+		gp1cr       = regInfo{inputs: []regMask{gp | sp | sb}}
+		gp2cr       = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb}}
+		crgp        = regInfo{inputs: nil, outputs: []regMask{gp}}
+		crgp11      = regInfo{inputs: []regMask{gp}, outputs: []regMask{gp}}
+		crgp21      = regInfo{inputs: []regMask{gp, gp}, outputs: []regMask{gp}}
+		gpload      = regInfo{inputs: []regMask{gp | sp | sb}, outputs: []regMask{gp}}
+		gploadidx   = regInfo{inputs: []regMask{gp | sp | sb, gp}, outputs: []regMask{gp}}
+		prefreg     = regInfo{inputs: []regMask{gp | sp | sb}}
+		gpstore     = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb}}
+		gpstoreidx  = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb, gp | sp | sb}}
+		gpstorezero = regInfo{inputs: []regMask{gp | sp | sb}} // ppc64.REGZERO is reserved zero value
+		gpxchg      = regInfo{inputs: []regMask{gp | sp | sb, gp}, outputs: []regMask{gp}}
+		gpcas       = regInfo{inputs: []regMask{gp | sp | sb, gp, gp}, outputs: []regMask{gp}}
+		fp01        = regInfo{inputs: nil, outputs: []regMask{fp}}
+		fp11        = regInfo{inputs: []regMask{fp}, outputs: []regMask{fp}}
+		fpgp        = regInfo{inputs: []regMask{fp}, outputs: []regMask{gp}}
+		gpfp        = regInfo{inputs: []regMask{gp}, outputs: []regMask{fp}}
+		fp21        = regInfo{inputs: []regMask{fp, fp}, outputs: []regMask{fp}}
+		fp31        = regInfo{inputs: []regMask{fp, fp, fp}, outputs: []regMask{fp}}
+		fp2cr       = regInfo{inputs: []regMask{fp, fp}}
+		fpload      = regInfo{inputs: []regMask{gp | sp | sb}, outputs: []regMask{fp}}
+		fploadidx   = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb}, outputs: []regMask{fp}}
+		fpstore     = regInfo{inputs: []regMask{gp | sp | sb, fp}}
+		fpstoreidx  = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb, fp}}
+		callerSave  = regMask(gp | fp | gr | xer)
+		r3          = buildReg("R3")
+		r4          = buildReg("R4")
+		r5          = buildReg("R5")
+		r6          = buildReg("R6")
+	)
+	ops := []opData{
+		{name: "ADD", argLength: 2, reg: gp21, asm: "ADD", commutative: true},        // arg0 + arg1
+		{name: "ADDconst", argLength: 1, reg: gp11, asm: "ADD", aux: "Int64"},        // arg0 + auxInt
+		{name: "FADD", argLength: 2, reg: fp21, asm: "FADD", commutative: true},      // arg0+arg1
+		{name: "FADDS", argLength: 2, reg: fp21, asm: "FADDS", commutative: true},    // arg0+arg1
+		{name: "SUB", argLength: 2, reg: gp21, asm: "SUB"},                           // arg0-arg1
+		{name: "SUBFCconst", argLength: 1, reg: gp11cxer, asm: "SUBC", aux: "Int64"}, // auxInt - arg0 (carry is ignored)
+		{name: "FSUB", argLength: 2, reg: fp21, asm: "FSUB"},                         // arg0-arg1
+		{name: "FSUBS", argLength: 2, reg: fp21, asm: "FSUBS"},                       // arg0-arg1
+
+		{name: "MULLD", argLength: 2, reg: gp21, asm: "MULLD", typ: "Int64", commutative: true}, // arg0*arg1 (signed 64-bit)
+		{name: "MULLW", argLength: 2, reg: gp21, asm: "MULLW", typ: "Int32", commutative: true}, // arg0*arg1 (signed 32-bit)
+		{name: "MULLDconst", argLength: 1, reg: gp11, asm: "MULLD", aux: "Int32", typ: "Int64"}, // arg0*auxInt (signed 64-bit)
+		{name: "MULLWconst", argLength: 1, reg: gp11, asm: "MULLW", aux: "Int32", typ: "Int64"}, // arg0*auxInt (signed 64-bit)
+		{name: "MADDLD", argLength: 3, reg: gp31, asm: "MADDLD", typ: "Int64"},                  // (arg0*arg1)+arg2 (signed 64-bit)
+
+		{name: "MULHD", argLength: 2, reg: gp21, asm: "MULHD", commutative: true},   // (arg0 * arg1) >> 64, signed
+		{name: "MULHW", argLength: 2, reg: gp21, asm: "MULHW", commutative: true},   // (arg0 * arg1) >> 32, signed
+		{name: "MULHDU", argLength: 2, reg: gp21, asm: "MULHDU", commutative: true}, // (arg0 * arg1) >> 64, unsigned
+		{name: "MULHWU", argLength: 2, reg: gp21, asm: "MULHWU", commutative: true}, // (arg0 * arg1) >> 32, unsigned
+
+		{name: "FMUL", argLength: 2, reg: fp21, asm: "FMUL", commutative: true},   // arg0*arg1
+		{name: "FMULS", argLength: 2, reg: fp21, asm: "FMULS", commutative: true}, // arg0*arg1
+
+		{name: "FMADD", argLength: 3, reg: fp31, asm: "FMADD"},   // arg0*arg1 + arg2
+		{name: "FMADDS", argLength: 3, reg: fp31, asm: "FMADDS"}, // arg0*arg1 + arg2
+		{name: "FMSUB", argLength: 3, reg: fp31, asm: "FMSUB"},   // arg0*arg1 - arg2
+		{name: "FMSUBS", argLength: 3, reg: fp31, asm: "FMSUBS"}, // arg0*arg1 - arg2
+
+		{name: "SRAD", argLength: 2, reg: gp21cxer, asm: "SRAD"}, // signed arg0 >> (arg1&127), 64 bit width (note: 127, not 63!)
+		{name: "SRAW", argLength: 2, reg: gp21cxer, asm: "SRAW"}, // signed arg0 >> (arg1&63), 32 bit width
+		{name: "SRD", argLength: 2, reg: gp21, asm: "SRD"},       // unsigned arg0 >> (arg1&127), 64 bit width
+		{name: "SRW", argLength: 2, reg: gp21, asm: "SRW"},       // unsigned arg0 >> (arg1&63), 32 bit width
+		{name: "SLD", argLength: 2, reg: gp21, asm: "SLD"},       // arg0 << (arg1&127), 64 bit width
+		{name: "SLW", argLength: 2, reg: gp21, asm: "SLW"},       // arg0 << (arg1&63), 32 bit width
+
+		{name: "ROTL", argLength: 2, reg: gp21, asm: "ROTL"},   // arg0 rotate left by arg1 mod 64
+		{name: "ROTLW", argLength: 2, reg: gp21, asm: "ROTLW"}, // uint32(arg0) rotate left by arg1 mod 32
+		// The following are ops to implement the extended mnemonics for shifts as described in section C.8 of the ISA.
+		// The constant shift values are packed into the aux int32.
+		{name: "RLDICL", argLength: 1, reg: gp11, asm: "RLDICL", aux: "Int32"},     // arg0 extract bits identified by shift params"
+		{name: "CLRLSLWI", argLength: 1, reg: gp11, asm: "CLRLSLWI", aux: "Int32"}, //
+		{name: "CLRLSLDI", argLength: 1, reg: gp11, asm: "CLRLSLDI", aux: "Int32"}, //
+
+		// Operations which consume or generate the CA (xer)
+		{name: "ADDC", argLength: 2, reg: gp21xer, asm: "ADDC", commutative: true, typ: "(UInt64, UInt64)"},    // arg0 + arg1 -> out, CA
+		{name: "SUBC", argLength: 2, reg: gp21xer, asm: "SUBC", typ: "(UInt64, UInt64)"},                       // arg0 - arg1 -> out, CA
+		{name: "ADDCconst", argLength: 1, reg: gp11xer, asm: "ADDC", typ: "(UInt64, UInt64)", aux: "Int64"},    // arg0 + imm16 -> out, CA
+		{name: "SUBCconst", argLength: 1, reg: gp11xer, asm: "SUBC", typ: "(UInt64, UInt64)", aux: "Int64"},    // imm16 - arg0 -> out, CA
+		{name: "ADDE", argLength: 3, reg: gp2xer1xer, asm: "ADDE", typ: "(UInt64, UInt64)", commutative: true}, // arg0 + arg1 + CA (arg2) -> out, CA
+		{name: "SUBE", argLength: 3, reg: gp2xer1xer, asm: "SUBE", typ: "(UInt64, UInt64)"},                    // arg0 - arg1 - CA (arg2) -> out, CA
+		{name: "ADDZEzero", argLength: 1, reg: xergp, asm: "ADDZE", typ: "UInt64"},                             // CA (arg0) + $0 -> out
+		{name: "SUBZEzero", argLength: 1, reg: xergp, asm: "SUBZE", typ: "UInt64"},                             // $0 - CA (arg0) -> out
+
+		{name: "SRADconst", argLength: 1, reg: gp11cxer, asm: "SRAD", aux: "Int64"}, // signed arg0 >> auxInt, 0 <= auxInt < 64, 64 bit width
+		{name: "SRAWconst", argLength: 1, reg: gp11cxer, asm: "SRAW", aux: "Int64"}, // signed arg0 >> auxInt, 0 <= auxInt < 32, 32 bit width
+		{name: "SRDconst", argLength: 1, reg: gp11, asm: "SRD", aux: "Int64"},       // unsigned arg0 >> auxInt, 0 <= auxInt < 64, 64 bit width
+		{name: "SRWconst", argLength: 1, reg: gp11, asm: "SRW", aux: "Int64"},       // unsigned arg0 >> auxInt, 0 <= auxInt < 32, 32 bit width
+		{name: "SLDconst", argLength: 1, reg: gp11, asm: "SLD", aux: "Int64"},       // arg0 << auxInt, 0 <= auxInt < 64, 64 bit width
+		{name: "SLWconst", argLength: 1, reg: gp11, asm: "SLW", aux: "Int64"},       // arg0 << auxInt, 0 <= auxInt < 32, 32 bit width
+
+		{name: "ROTLconst", argLength: 1, reg: gp11, asm: "ROTL", aux: "Int64"},   // arg0 rotate left by auxInt bits
+		{name: "ROTLWconst", argLength: 1, reg: gp11, asm: "ROTLW", aux: "Int64"}, // uint32(arg0) rotate left by auxInt bits
+		{name: "EXTSWSLconst", argLength: 1, reg: gp11, asm: "EXTSWSLI", aux: "Int64"},
+
+		{name: "RLWINM", argLength: 1, reg: gp11, asm: "RLWNM", aux: "Int64"},                      // Rotate and mask by immediate "rlwinm". encodePPC64RotateMask describes aux
+		{name: "RLWNM", argLength: 2, reg: gp21, asm: "RLWNM", aux: "Int64"},                       // Rotate and mask by "rlwnm". encodePPC64RotateMask describes aux
+		{name: "RLWMI", argLength: 2, reg: gp21a0, asm: "RLWMI", aux: "Int64", resultInArg0: true}, // "rlwimi" similar aux encoding as above
+
+		{name: "CNTLZD", argLength: 1, reg: gp11, asm: "CNTLZD", clobberFlags: true}, // count leading zeros
+		{name: "CNTLZW", argLength: 1, reg: gp11, asm: "CNTLZW", clobberFlags: true}, // count leading zeros (32 bit)
+
+		{name: "CNTTZD", argLength: 1, reg: gp11, asm: "CNTTZD"}, // count trailing zeros
+		{name: "CNTTZW", argLength: 1, reg: gp11, asm: "CNTTZW"}, // count trailing zeros (32 bit)
+
+		{name: "POPCNTD", argLength: 1, reg: gp11, asm: "POPCNTD"}, // number of set bits in arg0
+		{name: "POPCNTW", argLength: 1, reg: gp11, asm: "POPCNTW"}, // number of set bits in each word of arg0 placed in corresponding word
+		{name: "POPCNTB", argLength: 1, reg: gp11, asm: "POPCNTB"}, // number of set bits in each byte of arg0 placed in corresponding byte
+
+		{name: "FDIV", argLength: 2, reg: fp21, asm: "FDIV"},   // arg0/arg1
+		{name: "FDIVS", argLength: 2, reg: fp21, asm: "FDIVS"}, // arg0/arg1
+
+		{name: "DIVD", argLength: 2, reg: gp21, asm: "DIVD", typ: "Int64"},   // arg0/arg1 (signed 64-bit)
+		{name: "DIVW", argLength: 2, reg: gp21, asm: "DIVW", typ: "Int32"},   // arg0/arg1 (signed 32-bit)
+		{name: "DIVDU", argLength: 2, reg: gp21, asm: "DIVDU", typ: "Int64"}, // arg0/arg1 (unsigned 64-bit)
+		{name: "DIVWU", argLength: 2, reg: gp21, asm: "DIVWU", typ: "Int32"}, // arg0/arg1 (unsigned 32-bit)
+
+		{name: "MODUD", argLength: 2, reg: gp21, asm: "MODUD", typ: "UInt64"}, // arg0 % arg1 (unsigned 64-bit)
+		{name: "MODSD", argLength: 2, reg: gp21, asm: "MODSD", typ: "Int64"},  // arg0 % arg1 (signed 64-bit)
+		{name: "MODUW", argLength: 2, reg: gp21, asm: "MODUW", typ: "UInt32"}, // arg0 % arg1 (unsigned 32-bit)
+		{name: "MODSW", argLength: 2, reg: gp21, asm: "MODSW", typ: "Int32"},  // arg0 % arg1 (signed 32-bit)
+		// MOD is implemented as rem := arg0 - (arg0/arg1) * arg1
+
+		// Conversions are all float-to-float register operations.  "Integer" refers to encoding in the FP register.
+		{name: "FCTIDZ", argLength: 1, reg: fp11, asm: "FCTIDZ", typ: "Float64"}, // convert float to 64-bit int round towards zero
+		{name: "FCTIWZ", argLength: 1, reg: fp11, asm: "FCTIWZ", typ: "Float64"}, // convert float to 32-bit int round towards zero
+		{name: "FCFID", argLength: 1, reg: fp11, asm: "FCFID", typ: "Float64"},   // convert 64-bit integer to float
+		{name: "FCFIDS", argLength: 1, reg: fp11, asm: "FCFIDS", typ: "Float32"}, // convert 32-bit integer to float
+		{name: "FRSP", argLength: 1, reg: fp11, asm: "FRSP", typ: "Float64"},     // round float to 32-bit value
+
+		// Movement between float and integer registers with no change in bits; accomplished with stores+loads on PPC.
+		// Because the 32-bit load-literal-bits instructions have impoverished addressability, always widen the
+		// data instead and use FMOVDload and FMOVDstore instead (this will also dodge endianess issues).
+		// There are optimizations that should apply -- (Xi2f64 (MOVWload (not-ADD-ptr+offset) ) ) could use
+		// the word-load instructions.  (Xi2f64 (MOVDload ptr )) can be (FMOVDload ptr)
+
+		{name: "MFVSRD", argLength: 1, reg: fpgp, asm: "MFVSRD", typ: "Int64"},   // move 64 bits of F register into G register
+		{name: "MTVSRD", argLength: 1, reg: gpfp, asm: "MTVSRD", typ: "Float64"}, // move 64 bits of G register into F register
+
+		{name: "AND", argLength: 2, reg: gp21, asm: "AND", commutative: true},                                               // arg0&arg1
+		{name: "ANDN", argLength: 2, reg: gp21, asm: "ANDN"},                                                                // arg0&^arg1
+		{name: "ANDCC", argLength: 2, reg: gp21, asm: "ANDCC", commutative: true, clobberFlags: true, typ: "(Int64,Flags)"}, // arg0&arg1 sets CC
+		{name: "OR", argLength: 2, reg: gp21, asm: "OR", commutative: true},                                                 // arg0|arg1
+		{name: "ORN", argLength: 2, reg: gp21, asm: "ORN"},                                                                  // arg0|^arg1
+		{name: "ORCC", argLength: 2, reg: gp21, asm: "ORCC", commutative: true, clobberFlags: true, typ: "(Int,Flags)"},     // arg0|arg1 sets CC
+		{name: "NOR", argLength: 2, reg: gp21, asm: "NOR", commutative: true},                                               // ^(arg0|arg1)
+		{name: "XOR", argLength: 2, reg: gp21, asm: "XOR", typ: "Int64", commutative: true},                                 // arg0^arg1
+		{name: "XORCC", argLength: 2, reg: gp21, asm: "XORCC", commutative: true, clobberFlags: true, typ: "(Int,Flags)"},   // arg0^arg1 sets CC
+		{name: "EQV", argLength: 2, reg: gp21, asm: "EQV", typ: "Int64", commutative: true},                                 // arg0^^arg1
+		{name: "NEG", argLength: 1, reg: gp11, asm: "NEG"},                                                                  // -arg0 (integer)
+		{name: "FNEG", argLength: 1, reg: fp11, asm: "FNEG"},                                                                // -arg0 (floating point)
+		{name: "FSQRT", argLength: 1, reg: fp11, asm: "FSQRT"},                                                              // sqrt(arg0) (floating point)
+		{name: "FSQRTS", argLength: 1, reg: fp11, asm: "FSQRTS"},                                                            // sqrt(arg0) (floating point, single precision)
+		{name: "FFLOOR", argLength: 1, reg: fp11, asm: "FRIM"},                                                              // floor(arg0), float64
+		{name: "FCEIL", argLength: 1, reg: fp11, asm: "FRIP"},                                                               // ceil(arg0), float64
+		{name: "FTRUNC", argLength: 1, reg: fp11, asm: "FRIZ"},                                                              // trunc(arg0), float64
+		{name: "FROUND", argLength: 1, reg: fp11, asm: "FRIN"},                                                              // round(arg0), float64
+		{name: "FABS", argLength: 1, reg: fp11, asm: "FABS"},                                                                // abs(arg0), float64
+		{name: "FNABS", argLength: 1, reg: fp11, asm: "FNABS"},                                                              // -abs(arg0), float64
+		{name: "FCPSGN", argLength: 2, reg: fp21, asm: "FCPSGN"},                                                            // copysign arg0 -> arg1, float64
+
+		{name: "ORconst", argLength: 1, reg: gp11, asm: "OR", aux: "Int64"},   // arg0|aux
+		{name: "XORconst", argLength: 1, reg: gp11, asm: "XOR", aux: "Int64"}, // arg0^aux
+		{name: "ANDCCconst", argLength: 1, reg: regInfo{inputs: []regMask{gp | sp | sb}, outputs: []regMask{gp}}, asm: "ANDCC", aux: "Int64", clobberFlags: true, typ: "(Int,Flags)"}, // arg0&aux == 0 // and-immediate sets CC on PPC, always.
+
+		{name: "MOVBreg", argLength: 1, reg: gp11, asm: "MOVB", typ: "Int64"},   // sign extend int8 to int64
+		{name: "MOVBZreg", argLength: 1, reg: gp11, asm: "MOVBZ", typ: "Int64"}, // zero extend uint8 to uint64
+		{name: "MOVHreg", argLength: 1, reg: gp11, asm: "MOVH", typ: "Int64"},   // sign extend int16 to int64
+		{name: "MOVHZreg", argLength: 1, reg: gp11, asm: "MOVHZ", typ: "Int64"}, // zero extend uint16 to uint64
+		{name: "MOVWreg", argLength: 1, reg: gp11, asm: "MOVW", typ: "Int64"},   // sign extend int32 to int64
+		{name: "MOVWZreg", argLength: 1, reg: gp11, asm: "MOVWZ", typ: "Int64"}, // zero extend uint32 to uint64
+
+		// Load bytes in the endian order of the arch from arg0+aux+auxint into a 64 bit register.
+		{name: "MOVBZload", argLength: 2, reg: gpload, asm: "MOVBZ", aux: "SymOff", typ: "UInt8", faultOnNilArg0: true, symEffect: "Read"},  // load byte zero extend
+		{name: "MOVHload", argLength: 2, reg: gpload, asm: "MOVH", aux: "SymOff", typ: "Int16", faultOnNilArg0: true, symEffect: "Read"},    // load 2 bytes sign extend
+		{name: "MOVHZload", argLength: 2, reg: gpload, asm: "MOVHZ", aux: "SymOff", typ: "UInt16", faultOnNilArg0: true, symEffect: "Read"}, // load 2 bytes zero extend
+		{name: "MOVWload", argLength: 2, reg: gpload, asm: "MOVW", aux: "SymOff", typ: "Int32", faultOnNilArg0: true, symEffect: "Read"},    // load 4 bytes sign extend
+		{name: "MOVWZload", argLength: 2, reg: gpload, asm: "MOVWZ", aux: "SymOff", typ: "UInt32", faultOnNilArg0: true, symEffect: "Read"}, // load 4 bytes zero extend
+		{name: "MOVDload", argLength: 2, reg: gpload, asm: "MOVD", aux: "SymOff", typ: "Int64", faultOnNilArg0: true, symEffect: "Read"},    // load 8 bytes
+
+		// Load bytes in reverse endian order of the arch from arg0 into a 64 bit register, all zero extend.
+		// The generated instructions are indexed loads with no offset field in the instruction so the aux fields are not used.
+		// In these cases the index register field is set to 0 and the full address is in the base register.
+		{name: "MOVDBRload", argLength: 2, reg: gpload, asm: "MOVDBR", aux: "SymOff", typ: "Int64", faultOnNilArg0: true, symEffect: "Read"}, // load 8 bytes reverse order
+		{name: "MOVWBRload", argLength: 2, reg: gpload, asm: "MOVWBR", aux: "SymOff", typ: "Int32", faultOnNilArg0: true, symEffect: "Read"}, // load 4 bytes zero extend reverse order
+		{name: "MOVHBRload", argLength: 2, reg: gpload, asm: "MOVHBR", aux: "SymOff", typ: "Int16", faultOnNilArg0: true, symEffect: "Read"}, // load 2 bytes zero extend reverse order
+
+		// In these cases an index register is used in addition to a base register
+		// Loads from memory location arg[0] + arg[1].
+		{name: "MOVBZloadidx", argLength: 3, reg: gploadidx, asm: "MOVBZ", typ: "UInt8"},  // zero extend uint8 to uint64
+		{name: "MOVHloadidx", argLength: 3, reg: gploadidx, asm: "MOVH", typ: "Int16"},    // sign extend int16 to int64
+		{name: "MOVHZloadidx", argLength: 3, reg: gploadidx, asm: "MOVHZ", typ: "UInt16"}, // zero extend uint16 to uint64
+		{name: "MOVWloadidx", argLength: 3, reg: gploadidx, asm: "MOVW", typ: "Int32"},    // sign extend int32 to int64
+		{name: "MOVWZloadidx", argLength: 3, reg: gploadidx, asm: "MOVWZ", typ: "UInt32"}, // zero extend uint32 to uint64
+		{name: "MOVDloadidx", argLength: 3, reg: gploadidx, asm: "MOVD", typ: "Int64"},
+		{name: "MOVHBRloadidx", argLength: 3, reg: gploadidx, asm: "MOVHBR", typ: "Int16"}, // sign extend int16 to int64
+		{name: "MOVWBRloadidx", argLength: 3, reg: gploadidx, asm: "MOVWBR", typ: "Int32"}, // sign extend int32 to int64
+		{name: "MOVDBRloadidx", argLength: 3, reg: gploadidx, asm: "MOVDBR", typ: "Int64"},
+		{name: "FMOVDloadidx", argLength: 3, reg: fploadidx, asm: "FMOVD", typ: "Float64"},
+		{name: "FMOVSloadidx", argLength: 3, reg: fploadidx, asm: "FMOVS", typ: "Float32"},
+
+		// Prefetch instruction
+		// Do prefetch of address generated with arg0 and arg1 with option aux. arg0=addr,arg1=memory, aux=option.
+		{name: "DCBT", argLength: 2, aux: "Int64", reg: prefreg, asm: "DCBT", hasSideEffects: true},
+
+		// Store bytes in the reverse endian order of the arch into arg0.
+		// These are indexed stores with no offset field in the instruction so the auxint fields are not used.
+		{name: "MOVDBRstore", argLength: 3, reg: gpstore, asm: "MOVDBR", aux: "Sym", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes reverse order
+		{name: "MOVWBRstore", argLength: 3, reg: gpstore, asm: "MOVWBR", aux: "Sym", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes reverse order
+		{name: "MOVHBRstore", argLength: 3, reg: gpstore, asm: "MOVHBR", aux: "Sym", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 2 bytes reverse order
+
+		// Floating point loads from arg0+aux+auxint
+		{name: "FMOVDload", argLength: 2, reg: fpload, asm: "FMOVD", aux: "SymOff", typ: "Float64", faultOnNilArg0: true, symEffect: "Read"}, // load double float
+		{name: "FMOVSload", argLength: 2, reg: fpload, asm: "FMOVS", aux: "SymOff", typ: "Float32", faultOnNilArg0: true, symEffect: "Read"}, // load single float
+
+		// Store bytes in the endian order of the arch into arg0+aux+auxint
+		{name: "MOVBstore", argLength: 3, reg: gpstore, asm: "MOVB", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store byte
+		{name: "MOVHstore", argLength: 3, reg: gpstore, asm: "MOVH", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 2 bytes
+		{name: "MOVWstore", argLength: 3, reg: gpstore, asm: "MOVW", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes
+		{name: "MOVDstore", argLength: 3, reg: gpstore, asm: "MOVD", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes
+
+		// Store floating point value into arg0+aux+auxint
+		{name: "FMOVDstore", argLength: 3, reg: fpstore, asm: "FMOVD", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store double flot
+		{name: "FMOVSstore", argLength: 3, reg: fpstore, asm: "FMOVS", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store single float
+
+		// Stores using index and base registers
+		// Stores to arg[0] + arg[1]
+		{name: "MOVBstoreidx", argLength: 4, reg: gpstoreidx, asm: "MOVB", typ: "Mem"},     // store bye
+		{name: "MOVHstoreidx", argLength: 4, reg: gpstoreidx, asm: "MOVH", typ: "Mem"},     // store half word
+		{name: "MOVWstoreidx", argLength: 4, reg: gpstoreidx, asm: "MOVW", typ: "Mem"},     // store word
+		{name: "MOVDstoreidx", argLength: 4, reg: gpstoreidx, asm: "MOVD", typ: "Mem"},     // store double word
+		{name: "FMOVDstoreidx", argLength: 4, reg: fpstoreidx, asm: "FMOVD", typ: "Mem"},   // store double float
+		{name: "FMOVSstoreidx", argLength: 4, reg: fpstoreidx, asm: "FMOVS", typ: "Mem"},   // store single float
+		{name: "MOVHBRstoreidx", argLength: 4, reg: gpstoreidx, asm: "MOVHBR", typ: "Mem"}, // store half word reversed byte using index reg
+		{name: "MOVWBRstoreidx", argLength: 4, reg: gpstoreidx, asm: "MOVWBR", typ: "Mem"}, // store word reversed byte using index reg
+		{name: "MOVDBRstoreidx", argLength: 4, reg: gpstoreidx, asm: "MOVDBR", typ: "Mem"}, // store double word reversed byte using index reg
+
+		// The following ops store 0 into arg0+aux+auxint arg1=mem
+		{name: "MOVBstorezero", argLength: 2, reg: gpstorezero, asm: "MOVB", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store zero 1 byte
+		{name: "MOVHstorezero", argLength: 2, reg: gpstorezero, asm: "MOVH", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store zero 2 bytes
+		{name: "MOVWstorezero", argLength: 2, reg: gpstorezero, asm: "MOVW", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store zero 4 bytes
+		{name: "MOVDstorezero", argLength: 2, reg: gpstorezero, asm: "MOVD", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store zero 8 bytes
+
+		{name: "MOVDaddr", argLength: 1, reg: regInfo{inputs: []regMask{sp | sb | gp}, outputs: []regMask{gp}}, aux: "SymOff", asm: "MOVD", rematerializeable: true, symEffect: "Addr"}, // arg0 + auxInt + aux.(*gc.Sym), arg0=SP/SB/GP
+
+		{name: "MOVDconst", argLength: 0, reg: gp01, aux: "Int64", asm: "MOVD", typ: "Int64", rematerializeable: true}, //
+		{name: "FMOVDconst", argLength: 0, reg: fp01, aux: "Float64", asm: "FMOVD", rematerializeable: true},           //
+		{name: "FMOVSconst", argLength: 0, reg: fp01, aux: "Float32", asm: "FMOVS", rematerializeable: true},           //
+		{name: "FCMPU", argLength: 2, reg: fp2cr, asm: "FCMPU", typ: "Flags"},
+
+		{name: "CMP", argLength: 2, reg: gp2cr, asm: "CMP", typ: "Flags"},     // arg0 compare to arg1
+		{name: "CMPU", argLength: 2, reg: gp2cr, asm: "CMPU", typ: "Flags"},   // arg0 compare to arg1
+		{name: "CMPW", argLength: 2, reg: gp2cr, asm: "CMPW", typ: "Flags"},   // arg0 compare to arg1
+		{name: "CMPWU", argLength: 2, reg: gp2cr, asm: "CMPWU", typ: "Flags"}, // arg0 compare to arg1
+		{name: "CMPconst", argLength: 1, reg: gp1cr, asm: "CMP", aux: "Int64", typ: "Flags"},
+		{name: "CMPUconst", argLength: 1, reg: gp1cr, asm: "CMPU", aux: "Int64", typ: "Flags"},
+		{name: "CMPWconst", argLength: 1, reg: gp1cr, asm: "CMPW", aux: "Int32", typ: "Flags"},
+		{name: "CMPWUconst", argLength: 1, reg: gp1cr, asm: "CMPWU", aux: "Int32", typ: "Flags"},
+
+		// ISEL  arg2 ? arg0 : arg1
+		// ISELB arg1 ? arg0 : $0. arg0 is some register holding $1.
+		// ISELZ arg1 ? arg0 : $0
+		// auxInt values 0=LT 1=GT 2=EQ 3=SO (summary overflow/unordered) 4=GE 5=LE 6=NE 7=NSO (not summary overflow/not unordered)
+		// Note, auxInt^4 inverts the comparison condition. For example, LT^4 becomes GE, and "ISEL [a] x y z" is equivalent to ISEL [a^4] y x z".
+		{name: "ISEL", argLength: 3, reg: crgp21, asm: "ISEL", aux: "Int32", typ: "Int32"},
+		{name: "ISELB", argLength: 2, reg: crgp11, asm: "ISEL", aux: "Int32", typ: "Int32"},
+		{name: "ISELZ", argLength: 2, reg: crgp11, asm: "ISEL", aux: "Int32"},
+
+		// pseudo-ops
+		{name: "Equal", argLength: 1, reg: crgp},         // bool, true flags encode x==y false otherwise.
+		{name: "NotEqual", argLength: 1, reg: crgp},      // bool, true flags encode x!=y false otherwise.
+		{name: "LessThan", argLength: 1, reg: crgp},      // bool, true flags encode  x<y false otherwise.
+		{name: "FLessThan", argLength: 1, reg: crgp},     // bool, true flags encode  x<y false otherwise.
+		{name: "LessEqual", argLength: 1, reg: crgp},     // bool, true flags encode  x<=y false otherwise.
+		{name: "FLessEqual", argLength: 1, reg: crgp},    // bool, true flags encode  x<=y false otherwise; PPC <= === !> which is wrong for NaN
+		{name: "GreaterThan", argLength: 1, reg: crgp},   // bool, true flags encode  x>y false otherwise.
+		{name: "FGreaterThan", argLength: 1, reg: crgp},  // bool, true flags encode  x>y false otherwise.
+		{name: "GreaterEqual", argLength: 1, reg: crgp},  // bool, true flags encode  x>=y false otherwise.
+		{name: "FGreaterEqual", argLength: 1, reg: crgp}, // bool, true flags encode  x>=y false otherwise.; PPC >= === !< which is wrong for NaN
+
+		// Scheduler ensures LoweredGetClosurePtr occurs only in entry block,
+		// and sorts it to the very beginning of the block to prevent other
+		// use of the closure pointer.
+		{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{ctxt}}, zeroWidth: true},
+
+		// LoweredGetCallerSP returns the SP of the caller of the current function.
+		{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
+
+		// LoweredGetCallerPC evaluates to the PC to which its "caller" will return.
+		// I.e., if f calls g "calls" getcallerpc,
+		// the result should be the PC within f that g will return to.
+		// See runtime/stubs.go for a more detailed discussion.
+		{name: "LoweredGetCallerPC", reg: gp01, rematerializeable: true},
+
+		//arg0=ptr,arg1=mem, returns void.  Faults if ptr is nil.
+		{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gp | sp | sb}, clobbers: tmp}, clobberFlags: true, nilCheck: true, faultOnNilArg0: true},
+		// Round ops to block fused-multiply-add extraction.
+		{name: "LoweredRound32F", argLength: 1, reg: fp11, resultInArg0: true, zeroWidth: true},
+		{name: "LoweredRound64F", argLength: 1, reg: fp11, resultInArg0: true, zeroWidth: true},
+
+		{name: "CALLstatic", argLength: -1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                                       // call static function aux.(*obj.LSym).  arg0=mem, auxint=argsize, returns mem
+		{name: "CALLtail", argLength: -1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true, tailCall: true},                         // tail call static function aux.(*obj.LSym).  arg0=mem, auxint=argsize, returns mem
+		{name: "CALLclosure", argLength: -1, reg: regInfo{inputs: []regMask{callptr, ctxt, 0}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call function via closure.  arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem
+		{name: "CALLinter", argLength: -1, reg: regInfo{inputs: []regMask{callptr}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},            // call fn by pointer.  arg0=codeptr, arg1=mem, auxint=argsize, returns mem
+
+		// large or unaligned zeroing
+		// arg0 = address of memory to zero (in R3, changed as side effect)
+		// returns mem
+		//
+		// a loop is generated when there is more than one iteration
+		// needed to clear 4 doublewords
+		//
+		//	XXLXOR	VS32,VS32,VS32
+		// 	MOVD	$len/32,R31
+		//	MOVD	R31,CTR
+		//	MOVD	$16,R31
+		//	loop:
+		//	STXVD2X VS32,(R0)(R3)
+		//	STXVD2X	VS32,(R31),R3)
+		//	ADD	R3,32
+		//	BC	loop
+
+		// remaining doubleword clears generated as needed
+		//	MOVD	R0,(R3)
+		//	MOVD	R0,8(R3)
+		//	MOVD	R0,16(R3)
+		//	MOVD	R0,24(R3)
+
+		// one or more of these to clear remainder < 8 bytes
+		//	MOVW	R0,n1(R3)
+		//	MOVH	R0,n2(R3)
+		//	MOVB	R0,n3(R3)
+		{
+			name:      "LoweredZero",
+			aux:       "Int64",
+			argLength: 2,
+			reg: regInfo{
+				inputs:   []regMask{buildReg("R20")},
+				clobbers: buildReg("R20"),
+			},
+			clobberFlags:   true,
+			typ:            "Mem",
+			faultOnNilArg0: true,
+			unsafePoint:    true,
+		},
+		{
+			name:      "LoweredZeroShort",
+			aux:       "Int64",
+			argLength: 2,
+			reg: regInfo{
+				inputs: []regMask{gp}},
+			typ:            "Mem",
+			faultOnNilArg0: true,
+			unsafePoint:    true,
+		},
+		{
+			name:      "LoweredQuadZeroShort",
+			aux:       "Int64",
+			argLength: 2,
+			reg: regInfo{
+				inputs: []regMask{gp},
+			},
+			typ:            "Mem",
+			faultOnNilArg0: true,
+			unsafePoint:    true,
+		},
+		{
+			name:      "LoweredQuadZero",
+			aux:       "Int64",
+			argLength: 2,
+			reg: regInfo{
+				inputs:   []regMask{buildReg("R20")},
+				clobbers: buildReg("R20"),
+			},
+			clobberFlags:   true,
+			typ:            "Mem",
+			faultOnNilArg0: true,
+			unsafePoint:    true,
+		},
+
+		// R31 is temp register
+		// Loop code:
+		//	MOVD len/32,R31		set up loop ctr
+		//	MOVD R31,CTR
+		//	MOVD $16,R31		index register
+		// loop:
+		//	LXVD2X (R0)(R4),VS32
+		//	LXVD2X (R31)(R4),VS33
+		//	ADD  R4,$32          increment src
+		//	STXVD2X VS32,(R0)(R3)
+		//	STXVD2X VS33,(R31)(R3)
+		//	ADD  R3,$32          increment dst
+		//	BC 16,0,loop         branch ctr
+		// For this purpose, VS32 and VS33 are treated as
+		// scratch registers. Since regalloc does not
+		// track vector registers, even if it could be marked
+		// as clobbered it would have no effect.
+		// TODO: If vector registers are managed by regalloc
+		// mark these as clobbered.
+		//
+		// Bytes not moved by this loop are moved
+		// with a combination of the following instructions,
+		// starting with the largest sizes and generating as
+		// many as needed, using the appropriate offset value.
+		//	MOVD  n(R4),R14
+		//	MOVD  R14,n(R3)
+		//	MOVW  n1(R4),R14
+		//	MOVW  R14,n1(R3)
+		//	MOVH  n2(R4),R14
+		//	MOVH  R14,n2(R3)
+		//	MOVB  n3(R4),R14
+		//	MOVB  R14,n3(R3)
+
+		{
+			name:      "LoweredMove",
+			aux:       "Int64",
+			argLength: 3,
+			reg: regInfo{
+				inputs:   []regMask{buildReg("R20"), buildReg("R21")},
+				clobbers: buildReg("R20 R21"),
+			},
+			clobberFlags:   true,
+			typ:            "Mem",
+			faultOnNilArg0: true,
+			faultOnNilArg1: true,
+			unsafePoint:    true,
+		},
+		{
+			name:      "LoweredMoveShort",
+			aux:       "Int64",
+			argLength: 3,
+			reg: regInfo{
+				inputs: []regMask{gp, gp},
+			},
+			typ:            "Mem",
+			faultOnNilArg0: true,
+			faultOnNilArg1: true,
+			unsafePoint:    true,
+		},
+
+		// The following is similar to the LoweredMove, but uses
+		// LXV instead of LXVD2X, which does not require an index
+		// register and will do 4 in a loop instead of only.
+		{
+			name:      "LoweredQuadMove",
+			aux:       "Int64",
+			argLength: 3,
+			reg: regInfo{
+				inputs:   []regMask{buildReg("R20"), buildReg("R21")},
+				clobbers: buildReg("R20 R21"),
+			},
+			clobberFlags:   true,
+			typ:            "Mem",
+			faultOnNilArg0: true,
+			faultOnNilArg1: true,
+			unsafePoint:    true,
+		},
+
+		{
+			name:      "LoweredQuadMoveShort",
+			aux:       "Int64",
+			argLength: 3,
+			reg: regInfo{
+				inputs: []regMask{gp, gp},
+			},
+			typ:            "Mem",
+			faultOnNilArg0: true,
+			faultOnNilArg1: true,
+			unsafePoint:    true,
+		},
+
+		{name: "LoweredAtomicStore8", argLength: 3, reg: gpstore, typ: "Mem", aux: "Int64", faultOnNilArg0: true, hasSideEffects: true},
+		{name: "LoweredAtomicStore32", argLength: 3, reg: gpstore, typ: "Mem", aux: "Int64", faultOnNilArg0: true, hasSideEffects: true},
+		{name: "LoweredAtomicStore64", argLength: 3, reg: gpstore, typ: "Mem", aux: "Int64", faultOnNilArg0: true, hasSideEffects: true},
+
+		{name: "LoweredAtomicLoad8", argLength: 2, reg: gpload, typ: "UInt8", aux: "Int64", clobberFlags: true, faultOnNilArg0: true},
+		{name: "LoweredAtomicLoad32", argLength: 2, reg: gpload, typ: "UInt32", aux: "Int64", clobberFlags: true, faultOnNilArg0: true},
+		{name: "LoweredAtomicLoad64", argLength: 2, reg: gpload, typ: "Int64", aux: "Int64", clobberFlags: true, faultOnNilArg0: true},
+		{name: "LoweredAtomicLoadPtr", argLength: 2, reg: gpload, typ: "Int64", aux: "Int64", clobberFlags: true, faultOnNilArg0: true},
+
+		// atomic add32, 64
+		// LWSYNC
+		// LDAR         (Rarg0), Rout
+		// ADD		Rarg1, Rout
+		// STDCCC       Rout, (Rarg0)
+		// BNE          -3(PC)
+		// return new sum
+		{name: "LoweredAtomicAdd32", argLength: 3, reg: gpxchg, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true},
+		{name: "LoweredAtomicAdd64", argLength: 3, reg: gpxchg, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true},
+
+		// atomic exchange32, 64
+		// LWSYNC
+		// LDAR         (Rarg0), Rout
+		// STDCCC       Rarg1, (Rarg0)
+		// BNE          -2(PC)
+		// ISYNC
+		// return old val
+		{name: "LoweredAtomicExchange32", argLength: 3, reg: gpxchg, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true},
+		{name: "LoweredAtomicExchange64", argLength: 3, reg: gpxchg, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true},
+
+		// atomic compare and swap.
+		// arg0 = pointer, arg1 = old value, arg2 = new value, arg3 = memory. auxint must be zero.
+		// if *arg0 == arg1 {
+		//   *arg0 = arg2
+		//   return (true, memory)
+		// } else {
+		//   return (false, memory)
+		// }
+		// SYNC
+		// LDAR		(Rarg0), Rtmp
+		// CMP		Rarg1, Rtmp
+		// BNE		3(PC)
+		// STDCCC	Rarg2, (Rarg0)
+		// BNE		-4(PC)
+		// CBNZ         Rtmp, -4(PC)
+		// CSET         EQ, Rout
+		{name: "LoweredAtomicCas64", argLength: 4, reg: gpcas, resultNotInArgs: true, aux: "Int64", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true},
+		{name: "LoweredAtomicCas32", argLength: 4, reg: gpcas, resultNotInArgs: true, aux: "Int64", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true},
+
+		// atomic 8/32 and/or.
+		// *arg0 &= (|=) arg1. arg2=mem. returns memory. auxint must be zero.
+		// LBAR/LWAT	(Rarg0), Rtmp
+		// AND/OR	Rarg1, Rtmp
+		// STBCCC/STWCCC Rtmp, (Rarg0), Rtmp
+		// BNE		Rtmp, -3(PC)
+		{name: "LoweredAtomicAnd8", argLength: 3, reg: gpstore, asm: "AND", faultOnNilArg0: true, hasSideEffects: true},
+		{name: "LoweredAtomicAnd32", argLength: 3, reg: gpstore, asm: "AND", faultOnNilArg0: true, hasSideEffects: true},
+		{name: "LoweredAtomicOr8", argLength: 3, reg: gpstore, asm: "OR", faultOnNilArg0: true, hasSideEffects: true},
+		{name: "LoweredAtomicOr32", argLength: 3, reg: gpstore, asm: "OR", faultOnNilArg0: true, hasSideEffects: true},
+
+		// LoweredWB invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
+		// It preserves R0 through R17 (except special registers R1, R2, R11, R12, R13), g, and its arguments R20 and R21,
+		// but may clobber anything else, including R31 (REGTMP).
+		{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R20"), buildReg("R21")}, clobbers: (callerSave &^ buildReg("R0 R3 R4 R5 R6 R7 R8 R9 R10 R14 R15 R16 R17 R20 R21 g")) | buildReg("R31")}, clobberFlags: true, aux: "Sym", symEffect: "None"},
+
+		{name: "LoweredPubBarrier", argLength: 1, asm: "LWSYNC", hasSideEffects: true}, // Do data barrier. arg0=memory
+		// There are three of these functions so that they can have three different register inputs.
+		// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the
+		// default registers to match so we don't need to copy registers around unnecessarily.
+		{name: "LoweredPanicBoundsA", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r5, r6}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
+		{name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r4, r5}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
+		{name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r3, r4}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
+
+		// (InvertFlags (CMP a b)) == (CMP b a)
+		// So if we want (LessThan (CMP a b)) but we can't do that because a is a constant,
+		// then we do (LessThan (InvertFlags (CMP b a))) instead.
+		// Rewrites will convert this to (GreaterThan (CMP b a)).
+		// InvertFlags is a pseudo-op which can't appear in assembly output.
+		{name: "InvertFlags", argLength: 1}, // reverse direction of arg0
+
+		// Constant flag values. For any comparison, there are 3 possible
+		// outcomes: either the three from the signed total order (<,==,>)
+		// or the three from the unsigned total order, depending on which
+		// comparison operation was used (CMP or CMPU -- PPC is different from
+		// the other architectures, which have a single comparison producing
+		// both signed and unsigned comparison results.)
+
+		// These ops are for temporary use by rewrite rules. They
+		// cannot appear in the generated assembly.
+		{name: "FlagEQ"}, // equal
+		{name: "FlagLT"}, // signed < or unsigned <
+		{name: "FlagGT"}, // signed > or unsigned >
+	}
+
+	blocks := []blockData{
+		{name: "EQ", controls: 1},
+		{name: "NE", controls: 1},
+		{name: "LT", controls: 1},
+		{name: "LE", controls: 1},
+		{name: "GT", controls: 1},
+		{name: "GE", controls: 1},
+		{name: "FLT", controls: 1},
+		{name: "FLE", controls: 1},
+		{name: "FGT", controls: 1},
+		{name: "FGE", controls: 1},
+	}
+
+	archs = append(archs, arch{
+		name:               "PPC64",
+		pkg:                "cmd/internal/obj/ppc64",
+		genfile:            "../../ppc64/ssa.go",
+		ops:                ops,
+		blocks:             blocks,
+		regnames:           regNamesPPC64,
+		ParamIntRegNames:   "R3 R4 R5 R6 R7 R8 R9 R10 R14 R15 R16 R17",
+		ParamFloatRegNames: "F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12",
+		gpregmask:          gp,
+		fpregmask:          fp,
+		specialregmask:     xer,
+		framepointerreg:    -1,
+		linkreg:            -1, // not used
+	})
+}
diff --git a/src/cmd/compile/internal/ssa/_gen/PPC64latelower.rules b/src/cmd/compile/internal/ssa/_gen/PPC64latelower.rules
new file mode 100644
index 0000000..ada97b2
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/_gen/PPC64latelower.rules
@@ -0,0 +1,10 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains rules used by the laterLower pass.
+
+// Simplify ISEL x $0 z into ISELZ
+(ISEL [a] x (MOVDconst [0]) z) => (ISELZ [a] x z)
+// Simplify ISEL $0 y z into ISELZ by inverting comparison and reversing arguments.
+(ISEL [a] (MOVDconst [0]) y z) => (ISELZ [a^0x4] y z)
diff --git a/src/cmd/compile/internal/ssa/_gen/README b/src/cmd/compile/internal/ssa/_gen/README
new file mode 100644
index 0000000..0c7ceba
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/_gen/README
@@ -0,0 +1,7 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+This package generates opcode tables, rewrite rules, etc. for the ssa compiler.
+Run it with go-1.13 (or above):
+   go run .
diff --git a/src/cmd/compile/internal/ssa/_gen/RISCV64.rules b/src/cmd/compile/internal/ssa/_gen/RISCV64.rules
new file mode 100644
index 0000000..59f71be
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/_gen/RISCV64.rules
@@ -0,0 +1,845 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Lowering arithmetic
+(Add64 ...) => (ADD ...)
+(AddPtr ...) => (ADD ...)
+(Add32 ...) => (ADD ...)
+(Add16 ...) => (ADD ...)
+(Add8 ...) => (ADD ...)
+(Add32F ...) => (FADDS ...)
+(Add64F ...) => (FADDD ...)
+
+(Sub64 ...) => (SUB ...)
+(SubPtr ...) => (SUB ...)
+(Sub32 ...) => (SUB ...)
+(Sub16 ...) => (SUB ...)
+(Sub8 ...) => (SUB ...)
+(Sub32F ...) => (FSUBS ...)
+(Sub64F ...) => (FSUBD ...)
+
+(Mul64 ...) => (MUL  ...)
+(Mul64uhilo ...) => (LoweredMuluhilo ...)
+(Mul64uover ...) => (LoweredMuluover ...)
+(Mul32 ...) => (MULW ...)
+(Mul16 x y) => (MULW (SignExt16to32 x) (SignExt16to32 y))
+(Mul8 x y)  => (MULW (SignExt8to32 x)  (SignExt8to32 y))
+(Mul32F ...) => (FMULS ...)
+(Mul64F ...) => (FMULD ...)
+
+(Div32F ...) => (FDIVS ...)
+(Div64F ...) => (FDIVD ...)
+
+(Div64 x y [false])  => (DIV x y)
+(Div64u ...) => (DIVU ...)
+(Div32 x y [false])  => (DIVW x y)
+(Div32u ...) => (DIVUW ...)
+(Div16 x y [false])  => (DIVW  (SignExt16to32 x) (SignExt16to32 y))
+(Div16u x y) => (DIVUW (ZeroExt16to32 x) (ZeroExt16to32 y))
+(Div8 x y)   => (DIVW  (SignExt8to32 x)  (SignExt8to32 y))
+(Div8u x y)  => (DIVUW (ZeroExt8to32 x)  (ZeroExt8to32 y))
+
+(Hmul64 ...)  => (MULH  ...)
+(Hmul64u ...) => (MULHU ...)
+(Hmul32 x y)  => (SRAI [32] (MUL  (SignExt32to64 x) (SignExt32to64 y)))
+(Hmul32u x y) => (SRLI [32] (MUL  (ZeroExt32to64 x) (ZeroExt32to64 y)))
+
+(Select0 (Add64carry x y c)) => (ADD (ADD <typ.UInt64> x y) c)
+(Select1 (Add64carry x y c)) =>
+	(OR (SLTU <typ.UInt64> s:(ADD <typ.UInt64> x y) x) (SLTU <typ.UInt64> (ADD <typ.UInt64> s c) s))
+
+(Select0 (Sub64borrow x y c)) => (SUB (SUB <typ.UInt64> x y) c)
+(Select1 (Sub64borrow x y c)) =>
+	(OR (SLTU <typ.UInt64> x s:(SUB <typ.UInt64> x y)) (SLTU <typ.UInt64> s (SUB <typ.UInt64> s c)))
+
+// (x + y) / 2 => (x / 2) + (y / 2) + (x & y & 1)
+(Avg64u <t> x y) => (ADD (ADD <t> (SRLI <t> [1] x) (SRLI <t> [1] y)) (ANDI <t> [1] (AND <t> x y)))
+
+(Mod64 x y [false])  => (REM x y)
+(Mod64u ...) => (REMU  ...)
+(Mod32 x y [false])  => (REMW x y)
+(Mod32u ...) => (REMUW ...)
+(Mod16 x y [false])  => (REMW  (SignExt16to32 x) (SignExt16to32 y))
+(Mod16u x y) => (REMUW (ZeroExt16to32 x) (ZeroExt16to32 y))
+(Mod8 x y)   => (REMW  (SignExt8to32  x) (SignExt8to32  y))
+(Mod8u x y)  => (REMUW (ZeroExt8to32  x) (ZeroExt8to32  y))
+
+(And64 ...) => (AND ...)
+(And32 ...) => (AND ...)
+(And16 ...) => (AND ...)
+(And8  ...) => (AND ...)
+
+(Or64 ...) => (OR ...)
+(Or32 ...) => (OR ...)
+(Or16 ...) => (OR ...)
+(Or8  ...) => (OR ...)
+
+(Xor64 ...) => (XOR ...)
+(Xor32 ...) => (XOR ...)
+(Xor16 ...) => (XOR ...)
+(Xor8  ...) => (XOR ...)
+
+(Neg64  ...) => (NEG ...)
+(Neg32  ...) => (NEG ...)
+(Neg16  ...) => (NEG ...)
+(Neg8   ...) => (NEG ...)
+(Neg32F ...) => (FNEGS ...)
+(Neg64F ...) => (FNEGD ...)
+
+(Com64 ...) => (NOT ...)
+(Com32 ...) => (NOT ...)
+(Com16 ...) => (NOT ...)
+(Com8  ...) => (NOT ...)
+
+(Sqrt ...) => (FSQRTD ...)
+(Sqrt32 ...) => (FSQRTS ...)
+
+(Copysign ...) => (FSGNJD ...)
+
+(Abs ...) => (FABSD ...)
+
+(FMA ...) => (FMADDD ...)
+
+// Sign and zero extension.
+
+(SignExt8to16  ...) => (MOVBreg ...)
+(SignExt8to32  ...) => (MOVBreg ...)
+(SignExt8to64  ...) => (MOVBreg ...)
+(SignExt16to32 ...) => (MOVHreg ...)
+(SignExt16to64 ...) => (MOVHreg ...)
+(SignExt32to64 ...) => (MOVWreg ...)
+
+(ZeroExt8to16  ...) => (MOVBUreg ...)
+(ZeroExt8to32  ...) => (MOVBUreg ...)
+(ZeroExt8to64  ...) => (MOVBUreg ...)
+(ZeroExt16to32 ...) => (MOVHUreg ...)
+(ZeroExt16to64 ...) => (MOVHUreg ...)
+(ZeroExt32to64 ...) => (MOVWUreg ...)
+
+(Cvt32to32F ...) => (FCVTSW ...)
+(Cvt32to64F ...) => (FCVTDW ...)
+(Cvt64to32F ...) => (FCVTSL ...)
+(Cvt64to64F ...) => (FCVTDL ...)
+
+(Cvt32Fto32 ...) => (FCVTWS ...)
+(Cvt32Fto64 ...) => (FCVTLS ...)
+(Cvt64Fto32 ...) => (FCVTWD ...)
+(Cvt64Fto64 ...) => (FCVTLD ...)
+
+(Cvt32Fto64F ...) => (FCVTDS ...)
+(Cvt64Fto32F ...) => (FCVTSD ...)
+
+(CvtBoolToUint8 ...) => (Copy ...)
+
+(Round32F ...) => (Copy ...)
+(Round64F ...) => (Copy ...)
+
+(Slicemask <t> x) => (SRAI [63] (NEG <t> x))
+
+// Truncations
+// We ignore the unused high parts of registers, so truncates are just copies.
+(Trunc16to8  ...) => (Copy ...)
+(Trunc32to8  ...) => (Copy ...)
+(Trunc32to16 ...) => (Copy ...)
+(Trunc64to8  ...) => (Copy ...)
+(Trunc64to16 ...) => (Copy ...)
+(Trunc64to32 ...) => (Copy ...)
+
+// Shifts
+
+// SLL only considers the bottom 6 bits of y. If y > 64, the result should
+// always be 0.
+//
+// Breaking down the operation:
+//
+// (SLL x y) generates x << (y & 63).
+//
+// If y < 64, this is the value we want. Otherwise, we want zero.
+//
+// So, we AND with -1 * uint64(y < 64), which is 0xfffff... if y < 64 and 0 otherwise.
+(Lsh8x8   <t> x y) && !shiftIsBounded(v) => (AND (SLL <t> x y) (Neg8  <t> (SLTIU <t> [64] (ZeroExt8to64  y))))
+(Lsh8x16  <t> x y) && !shiftIsBounded(v) => (AND (SLL <t> x y) (Neg8  <t> (SLTIU <t> [64] (ZeroExt16to64 y))))
+(Lsh8x32  <t> x y) && !shiftIsBounded(v) => (AND (SLL <t> x y) (Neg8  <t> (SLTIU <t> [64] (ZeroExt32to64 y))))
+(Lsh8x64  <t> x y) && !shiftIsBounded(v) => (AND (SLL <t> x y) (Neg8  <t> (SLTIU <t> [64] y)))
+(Lsh16x8  <t> x y) && !shiftIsBounded(v) => (AND (SLL <t> x y) (Neg16 <t> (SLTIU <t> [64] (ZeroExt8to64  y))))
+(Lsh16x16 <t> x y) && !shiftIsBounded(v) => (AND (SLL <t> x y) (Neg16 <t> (SLTIU <t> [64] (ZeroExt16to64 y))))
+(Lsh16x32 <t> x y) && !shiftIsBounded(v) => (AND (SLL <t> x y) (Neg16 <t> (SLTIU <t> [64] (ZeroExt32to64 y))))
+(Lsh16x64 <t> x y) && !shiftIsBounded(v) => (AND (SLL <t> x y) (Neg16 <t> (SLTIU <t> [64] y)))
+(Lsh32x8  <t> x y) && !shiftIsBounded(v) => (AND (SLL <t> x y) (Neg32 <t> (SLTIU <t> [64] (ZeroExt8to64  y))))
+(Lsh32x16 <t> x y) && !shiftIsBounded(v) => (AND (SLL <t> x y) (Neg32 <t> (SLTIU <t> [64] (ZeroExt16to64 y))))
+(Lsh32x32 <t> x y) && !shiftIsBounded(v) => (AND (SLL <t> x y) (Neg32 <t> (SLTIU <t> [64] (ZeroExt32to64 y))))
+(Lsh32x64 <t> x y) && !shiftIsBounded(v) => (AND (SLL <t> x y) (Neg32 <t> (SLTIU <t> [64] y)))
+(Lsh64x8  <t> x y) && !shiftIsBounded(v) => (AND (SLL <t> x y) (Neg64 <t> (SLTIU <t> [64] (ZeroExt8to64  y))))
+(Lsh64x16 <t> x y) && !shiftIsBounded(v) => (AND (SLL <t> x y) (Neg64 <t> (SLTIU <t> [64] (ZeroExt16to64 y))))
+(Lsh64x32 <t> x y) && !shiftIsBounded(v) => (AND (SLL <t> x y) (Neg64 <t> (SLTIU <t> [64] (ZeroExt32to64 y))))
+(Lsh64x64 <t> x y) && !shiftIsBounded(v) => (AND (SLL <t> x y) (Neg64 <t> (SLTIU <t> [64] y)))
+
+(Lsh8x(64|32|16|8)  x y) && shiftIsBounded(v) => (SLL x y)
+(Lsh16x(64|32|16|8) x y) && shiftIsBounded(v) => (SLL x y)
+(Lsh32x(64|32|16|8) x y) && shiftIsBounded(v) => (SLL x y)
+(Lsh64x(64|32|16|8) x y) && shiftIsBounded(v) => (SLL x y)
+
+// SRL only considers the bottom 6 bits of y. If y > 64, the result should
+// always be 0. See Lsh above for a detailed description.
+(Rsh8Ux8   <t> x y) && !shiftIsBounded(v) => (AND (SRL <t> (ZeroExt8to64  x) y) (Neg8  <t> (SLTIU <t> [64] (ZeroExt8to64  y))))
+(Rsh8Ux16  <t> x y) && !shiftIsBounded(v) => (AND (SRL <t> (ZeroExt8to64  x) y) (Neg8  <t> (SLTIU <t> [64] (ZeroExt16to64 y))))
+(Rsh8Ux32  <t> x y) && !shiftIsBounded(v) => (AND (SRL <t> (ZeroExt8to64  x) y) (Neg8  <t> (SLTIU <t> [64] (ZeroExt32to64 y))))
+(Rsh8Ux64  <t> x y) && !shiftIsBounded(v) => (AND (SRL <t> (ZeroExt8to64  x) y) (Neg8  <t> (SLTIU <t> [64] y)))
+(Rsh16Ux8  <t> x y) && !shiftIsBounded(v) => (AND (SRL <t> (ZeroExt16to64 x) y) (Neg16 <t> (SLTIU <t> [64] (ZeroExt8to64  y))))
+(Rsh16Ux16 <t> x y) && !shiftIsBounded(v) => (AND (SRL <t> (ZeroExt16to64 x) y) (Neg16 <t> (SLTIU <t> [64] (ZeroExt16to64 y))))
+(Rsh16Ux32 <t> x y) && !shiftIsBounded(v) => (AND (SRL <t> (ZeroExt16to64 x) y) (Neg16 <t> (SLTIU <t> [64] (ZeroExt32to64 y))))
+(Rsh16Ux64 <t> x y) && !shiftIsBounded(v) => (AND (SRL <t> (ZeroExt16to64 x) y) (Neg16 <t> (SLTIU <t> [64] y)))
+(Rsh32Ux8  <t> x y) && !shiftIsBounded(v) => (AND (SRL <t> (ZeroExt32to64 x) y) (Neg32 <t> (SLTIU <t> [64] (ZeroExt8to64  y))))
+(Rsh32Ux16 <t> x y) && !shiftIsBounded(v) => (AND (SRL <t> (ZeroExt32to64 x) y) (Neg32 <t> (SLTIU <t> [64] (ZeroExt16to64 y))))
+(Rsh32Ux32 <t> x y) && !shiftIsBounded(v) => (AND (SRL <t> (ZeroExt32to64 x) y) (Neg32 <t> (SLTIU <t> [64] (ZeroExt32to64 y))))
+(Rsh32Ux64 <t> x y) && !shiftIsBounded(v) => (AND (SRL <t> (ZeroExt32to64 x) y) (Neg32 <t> (SLTIU <t> [64] y)))
+(Rsh64Ux8  <t> x y) && !shiftIsBounded(v) => (AND (SRL <t> x                 y) (Neg64 <t> (SLTIU <t> [64] (ZeroExt8to64  y))))
+(Rsh64Ux16 <t> x y) && !shiftIsBounded(v) => (AND (SRL <t> x                 y) (Neg64 <t> (SLTIU <t> [64] (ZeroExt16to64 y))))
+(Rsh64Ux32 <t> x y) && !shiftIsBounded(v) => (AND (SRL <t> x                 y) (Neg64 <t> (SLTIU <t> [64] (ZeroExt32to64 y))))
+(Rsh64Ux64 <t> x y) && !shiftIsBounded(v) => (AND (SRL <t> x                 y) (Neg64 <t> (SLTIU <t> [64] y)))
+
+(Rsh8Ux(64|32|16|8)  x y) && shiftIsBounded(v) => (SRL (ZeroExt8to64  x) y)
+(Rsh16Ux(64|32|16|8) x y) && shiftIsBounded(v) => (SRL (ZeroExt16to64 x) y)
+(Rsh32Ux(64|32|16|8) x y) && shiftIsBounded(v) => (SRL (ZeroExt32to64 x) y)
+(Rsh64Ux(64|32|16|8) x y) && shiftIsBounded(v) => (SRL x                 y)
+
+// SRA only considers the bottom 6 bits of y. If y > 64, the result should
+// be either 0 or -1 based on the sign bit.
+//
+// We implement this by performing the max shift (-1) if y >= 64.
+//
+// We OR (uint64(y < 64) - 1) into y before passing it to SRA. This leaves
+// us with -1 (0xffff...) if y >= 64.
+//
+// We don't need to sign-extend the OR result, as it will be at minimum 8 bits,
+// more than the 6 bits SRA cares about.
+(Rsh8x8   <t> x y) && !shiftIsBounded(v) => (SRA <t> (SignExt8to64  x) (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] (ZeroExt8to64  y)))))
+(Rsh8x16  <t> x y) && !shiftIsBounded(v) => (SRA <t> (SignExt8to64  x) (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] (ZeroExt16to64 y)))))
+(Rsh8x32  <t> x y) && !shiftIsBounded(v) => (SRA <t> (SignExt8to64  x) (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] (ZeroExt32to64 y)))))
+(Rsh8x64  <t> x y) && !shiftIsBounded(v) => (SRA <t> (SignExt8to64  x) (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] y))))
+(Rsh16x8  <t> x y) && !shiftIsBounded(v) => (SRA <t> (SignExt16to64 x) (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] (ZeroExt8to64  y)))))
+(Rsh16x16 <t> x y) && !shiftIsBounded(v) => (SRA <t> (SignExt16to64 x) (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] (ZeroExt16to64 y)))))
+(Rsh16x32 <t> x y) && !shiftIsBounded(v) => (SRA <t> (SignExt16to64 x) (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] (ZeroExt32to64 y)))))
+(Rsh16x64 <t> x y) && !shiftIsBounded(v) => (SRA <t> (SignExt16to64 x) (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] y))))
+(Rsh32x8  <t> x y) && !shiftIsBounded(v) => (SRA <t> (SignExt32to64 x) (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] (ZeroExt8to64  y)))))
+(Rsh32x16 <t> x y) && !shiftIsBounded(v) => (SRA <t> (SignExt32to64 x) (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] (ZeroExt16to64 y)))))
+(Rsh32x32 <t> x y) && !shiftIsBounded(v) => (SRA <t> (SignExt32to64 x) (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] (ZeroExt32to64 y)))))
+(Rsh32x64 <t> x y) && !shiftIsBounded(v) => (SRA <t> (SignExt32to64 x) (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] y))))
+(Rsh64x8  <t> x y) && !shiftIsBounded(v) => (SRA <t> x                 (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] (ZeroExt8to64  y)))))
+(Rsh64x16 <t> x y) && !shiftIsBounded(v) => (SRA <t> x                 (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] (ZeroExt16to64 y)))))
+(Rsh64x32 <t> x y) && !shiftIsBounded(v) => (SRA <t> x                 (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] (ZeroExt32to64 y)))))
+(Rsh64x64 <t> x y) && !shiftIsBounded(v) => (SRA <t> x                 (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] y))))
+
+(Rsh8x(64|32|16|8)  x y) && shiftIsBounded(v) => (SRA (SignExt8to64  x) y)
+(Rsh16x(64|32|16|8) x y) && shiftIsBounded(v) => (SRA (SignExt16to64 x) y)
+(Rsh32x(64|32|16|8) x y) && shiftIsBounded(v) => (SRA (SignExt32to64 x) y)
+(Rsh64x(64|32|16|8) x y) && shiftIsBounded(v) => (SRA x                 y)
+
+// Rotates.
+(RotateLeft8  <t> x (MOVDconst [c])) => (Or8  (Lsh8x64  <t> x (MOVDconst [c&7]))  (Rsh8Ux64  <t> x (MOVDconst [-c&7])))
+(RotateLeft16 <t> x (MOVDconst [c])) => (Or16 (Lsh16x64 <t> x (MOVDconst [c&15])) (Rsh16Ux64 <t> x (MOVDconst [-c&15])))
+(RotateLeft32 <t> x (MOVDconst [c])) => (Or32 (Lsh32x64 <t> x (MOVDconst [c&31])) (Rsh32Ux64 <t> x (MOVDconst [-c&31])))
+(RotateLeft64 <t> x (MOVDconst [c])) => (Or64 (Lsh64x64 <t> x (MOVDconst [c&63])) (Rsh64Ux64 <t> x (MOVDconst [-c&63])))
+
+(Less64  ...) => (SLT  ...)
+(Less32  x y) => (SLT  (SignExt32to64 x) (SignExt32to64 y))
+(Less16  x y) => (SLT  (SignExt16to64 x) (SignExt16to64 y))
+(Less8   x y) => (SLT  (SignExt8to64  x) (SignExt8to64  y))
+(Less64U ...) => (SLTU ...)
+(Less32U x y) => (SLTU (ZeroExt32to64 x) (ZeroExt32to64 y))
+(Less16U x y) => (SLTU (ZeroExt16to64 x) (ZeroExt16to64 y))
+(Less8U  x y) => (SLTU (ZeroExt8to64  x) (ZeroExt8to64  y))
+(Less64F ...) => (FLTD ...)
+(Less32F ...) => (FLTS ...)
+
+// Convert x <= y to !(y > x).
+(Leq64  x y) => (Not (Less64  y x))
+(Leq32  x y) => (Not (Less32  y x))
+(Leq16  x y) => (Not (Less16  y x))
+(Leq8   x y) => (Not (Less8   y x))
+(Leq64U x y) => (Not (Less64U y x))
+(Leq32U x y) => (Not (Less32U y x))
+(Leq16U x y) => (Not (Less16U y x))
+(Leq8U  x y) => (Not (Less8U  y x))
+(Leq64F ...) => (FLED ...)
+(Leq32F ...) => (FLES ...)
+
+(EqPtr x y) => (SEQZ (SUB <typ.Uintptr> x y))
+(Eq64  x y) => (SEQZ (SUB <x.Type> x y))
+(Eq32  x y) => (SEQZ (SUB <x.Type> (ZeroExt32to64 x) (ZeroExt32to64 y)))
+(Eq16  x y) => (SEQZ (SUB <x.Type> (ZeroExt16to64 x) (ZeroExt16to64 y)))
+(Eq8   x y) => (SEQZ (SUB <x.Type> (ZeroExt8to64  x) (ZeroExt8to64  y)))
+(Eq64F ...) => (FEQD ...)
+(Eq32F ...) => (FEQS ...)
+
+(NeqPtr x y) => (SNEZ (SUB <typ.Uintptr> x y))
+(Neq64  x y) => (SNEZ (SUB <x.Type> x y))
+(Neq32  x y) => (SNEZ (SUB <x.Type> (ZeroExt32to64 x) (ZeroExt32to64 y)))
+(Neq16  x y) => (SNEZ (SUB <x.Type> (ZeroExt16to64 x) (ZeroExt16to64 y)))
+(Neq8   x y) => (SNEZ (SUB <x.Type> (ZeroExt8to64  x) (ZeroExt8to64  y)))
+(Neq64F ...) => (FNED ...)
+(Neq32F ...) => (FNES ...)
+
+// Loads
+(Load <t> ptr mem) &&  t.IsBoolean()                  => (MOVBUload ptr mem)
+(Load <t> ptr mem) && ( is8BitInt(t) &&  isSigned(t)) => (MOVBload  ptr mem)
+(Load <t> ptr mem) && ( is8BitInt(t) && !isSigned(t)) => (MOVBUload ptr mem)
+(Load <t> ptr mem) && (is16BitInt(t) &&  isSigned(t)) => (MOVHload  ptr mem)
+(Load <t> ptr mem) && (is16BitInt(t) && !isSigned(t)) => (MOVHUload ptr mem)
+(Load <t> ptr mem) && (is32BitInt(t) &&  isSigned(t)) => (MOVWload  ptr mem)
+(Load <t> ptr mem) && (is32BitInt(t) && !isSigned(t)) => (MOVWUload ptr mem)
+(Load <t> ptr mem) && (is64BitInt(t) || isPtr(t))     => (MOVDload  ptr mem)
+(Load <t> ptr mem) &&  is32BitFloat(t)                => (FMOVWload ptr mem)
+(Load <t> ptr mem) &&  is64BitFloat(t)                => (FMOVDload ptr mem)
+
+// Stores
+(Store {t} ptr val mem) && t.Size() == 1 => (MOVBstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 2 => (MOVHstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 4 && !is32BitFloat(val.Type) => (MOVWstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 8 && !is64BitFloat(val.Type) => (MOVDstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 4 &&  is32BitFloat(val.Type) => (FMOVWstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 8 &&  is64BitFloat(val.Type) => (FMOVDstore ptr val mem)
+
+// We need to fold MOVaddr into the LD/MOVDstore ops so that the live variable analysis
+// knows what variables are being read/written by the ops.
+(MOVBUload [off1] {sym1} (MOVaddr [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+	(MOVBUload [off1+off2] {mergeSym(sym1,sym2)} base mem)
+(MOVBload  [off1] {sym1} (MOVaddr [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+	(MOVBload  [off1+off2] {mergeSym(sym1,sym2)} base mem)
+(MOVHUload [off1] {sym1} (MOVaddr [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+	(MOVHUload [off1+off2] {mergeSym(sym1,sym2)} base mem)
+(MOVHload  [off1] {sym1} (MOVaddr [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+	(MOVHload  [off1+off2] {mergeSym(sym1,sym2)} base mem)
+(MOVWUload [off1] {sym1} (MOVaddr [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+	(MOVWUload [off1+off2] {mergeSym(sym1,sym2)} base mem)
+(MOVWload  [off1] {sym1} (MOVaddr [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+	(MOVWload  [off1+off2] {mergeSym(sym1,sym2)} base mem)
+(MOVDload  [off1] {sym1} (MOVaddr [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+	(MOVDload  [off1+off2] {mergeSym(sym1,sym2)} base mem)
+
+(MOVBstore [off1] {sym1} (MOVaddr [off2] {sym2} base) val mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+	(MOVBstore [off1+off2] {mergeSym(sym1,sym2)} base val mem)
+(MOVHstore [off1] {sym1} (MOVaddr [off2] {sym2} base) val mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+	(MOVHstore [off1+off2] {mergeSym(sym1,sym2)} base val mem)
+(MOVWstore [off1] {sym1} (MOVaddr [off2] {sym2} base) val mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+	(MOVWstore [off1+off2] {mergeSym(sym1,sym2)} base val mem)
+(MOVDstore [off1] {sym1} (MOVaddr [off2] {sym2} base) val mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+	(MOVDstore [off1+off2] {mergeSym(sym1,sym2)} base val mem)
+(MOVBstorezero [off1] {sym1} (MOVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVBstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+(MOVHstorezero [off1] {sym1} (MOVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVHstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+(MOVWstorezero [off1] {sym1} (MOVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVWstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+(MOVDstorezero [off1] {sym1} (MOVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
+	(MOVDstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+
+(MOVBUload [off1] {sym} (ADDI [off2] base) mem) && is32Bit(int64(off1)+off2) =>
+	(MOVBUload [off1+int32(off2)] {sym} base mem)
+(MOVBload  [off1] {sym} (ADDI [off2] base) mem) && is32Bit(int64(off1)+off2) =>
+	(MOVBload  [off1+int32(off2)] {sym} base mem)
+(MOVHUload [off1] {sym} (ADDI [off2] base) mem) && is32Bit(int64(off1)+off2) =>
+	(MOVHUload [off1+int32(off2)] {sym} base mem)
+(MOVHload  [off1] {sym} (ADDI [off2] base) mem) && is32Bit(int64(off1)+off2) =>
+	(MOVHload  [off1+int32(off2)] {sym} base mem)
+(MOVWUload [off1] {sym} (ADDI [off2] base) mem) && is32Bit(int64(off1)+off2) =>
+	(MOVWUload [off1+int32(off2)] {sym} base mem)
+(MOVWload  [off1] {sym} (ADDI [off2] base) mem) && is32Bit(int64(off1)+off2) =>
+	(MOVWload  [off1+int32(off2)] {sym} base mem)
+(MOVDload  [off1] {sym} (ADDI [off2] base) mem) && is32Bit(int64(off1)+off2) =>
+	(MOVDload  [off1+int32(off2)] {sym} base mem)
+
+(MOVBstore [off1] {sym} (ADDI [off2] base) val mem) && is32Bit(int64(off1)+off2) =>
+	(MOVBstore [off1+int32(off2)] {sym} base val mem)
+(MOVHstore [off1] {sym} (ADDI [off2] base) val mem) && is32Bit(int64(off1)+off2) =>
+	(MOVHstore [off1+int32(off2)] {sym} base val mem)
+(MOVWstore [off1] {sym} (ADDI [off2] base) val mem) && is32Bit(int64(off1)+off2) =>
+	(MOVWstore [off1+int32(off2)] {sym} base val mem)
+(MOVDstore [off1] {sym} (ADDI [off2] base) val mem) && is32Bit(int64(off1)+off2) =>
+	(MOVDstore [off1+int32(off2)] {sym} base val mem)
+(MOVBstorezero [off1] {sym} (ADDI [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVBstorezero [off1+int32(off2)] {sym} ptr mem)
+(MOVHstorezero [off1] {sym} (ADDI [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVHstorezero [off1+int32(off2)] {sym} ptr mem)
+(MOVWstorezero [off1] {sym} (ADDI [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVWstorezero [off1+int32(off2)] {sym} ptr mem)
+(MOVDstorezero [off1] {sym} (ADDI [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVDstorezero [off1+int32(off2)] {sym} ptr mem)
+
+// Similarly, fold ADDI into MOVaddr to avoid confusing live variable analysis
+// with OffPtr -> ADDI.
+(ADDI [c] (MOVaddr [d] {s} x)) && is32Bit(c+int64(d)) => (MOVaddr [int32(c)+d] {s} x)
+
+// Small zeroing
+(Zero [0] _ mem) => mem
+(Zero [1] ptr mem) => (MOVBstore ptr (MOVDconst [0]) mem)
+(Zero [2] {t} ptr mem) && t.Alignment()%2 == 0 =>
+	(MOVHstore ptr (MOVDconst [0]) mem)
+(Zero [2] ptr mem) =>
+	(MOVBstore [1] ptr (MOVDconst [0])
+		(MOVBstore ptr (MOVDconst [0]) mem))
+(Zero [4] {t} ptr mem) && t.Alignment()%4 == 0 =>
+	(MOVWstore ptr (MOVDconst [0]) mem)
+(Zero [4] {t} ptr mem) && t.Alignment()%2 == 0 =>
+	(MOVHstore [2] ptr (MOVDconst [0])
+		(MOVHstore ptr (MOVDconst [0]) mem))
+(Zero [4] ptr mem) =>
+	(MOVBstore [3] ptr (MOVDconst [0])
+		(MOVBstore [2] ptr (MOVDconst [0])
+			(MOVBstore [1] ptr (MOVDconst [0])
+				(MOVBstore ptr (MOVDconst [0]) mem))))
+(Zero [8] {t} ptr mem) && t.Alignment()%8 == 0 =>
+	(MOVDstore ptr (MOVDconst [0]) mem)
+(Zero [8] {t} ptr mem) && t.Alignment()%4 == 0 =>
+	(MOVWstore [4] ptr (MOVDconst [0])
+		(MOVWstore ptr (MOVDconst [0]) mem))
+(Zero [8] {t} ptr mem) && t.Alignment()%2 == 0 =>
+	(MOVHstore [6] ptr (MOVDconst [0])
+		(MOVHstore [4] ptr (MOVDconst [0])
+			(MOVHstore [2] ptr (MOVDconst [0])
+				(MOVHstore ptr (MOVDconst [0]) mem))))
+
+(Zero [3] ptr mem) =>
+	(MOVBstore [2] ptr (MOVDconst [0])
+		(MOVBstore [1] ptr (MOVDconst [0])
+			(MOVBstore ptr (MOVDconst [0]) mem)))
+(Zero [6] {t} ptr mem) && t.Alignment()%2 == 0 =>
+	(MOVHstore [4] ptr (MOVDconst [0])
+		(MOVHstore [2] ptr (MOVDconst [0])
+			(MOVHstore ptr (MOVDconst [0]) mem)))
+(Zero [12] {t} ptr mem) && t.Alignment()%4 == 0 =>
+	(MOVWstore [8] ptr (MOVDconst [0])
+		(MOVWstore [4] ptr (MOVDconst [0])
+			(MOVWstore ptr (MOVDconst [0]) mem)))
+(Zero [16] {t} ptr mem) && t.Alignment()%8 == 0 =>
+	(MOVDstore [8] ptr (MOVDconst [0])
+		(MOVDstore ptr (MOVDconst [0]) mem))
+(Zero [24] {t} ptr mem) && t.Alignment()%8 == 0 =>
+	(MOVDstore [16] ptr (MOVDconst [0])
+		(MOVDstore [8] ptr (MOVDconst [0])
+			(MOVDstore ptr (MOVDconst [0]) mem)))
+(Zero [32] {t} ptr mem) && t.Alignment()%8 == 0 =>
+	(MOVDstore [24] ptr (MOVDconst [0])
+		(MOVDstore [16] ptr (MOVDconst [0])
+			(MOVDstore [8] ptr (MOVDconst [0])
+				(MOVDstore ptr (MOVDconst [0]) mem))))
+
+// Medium 8-aligned zeroing uses a Duff's device
+// 8 and 128 are magic constants, see runtime/mkduff.go
+(Zero [s] {t} ptr mem)
+	&& s%8 == 0 && s <= 8*128
+	&& t.Alignment()%8 == 0 && !config.noDuffDevice =>
+	(DUFFZERO [8 * (128 - s/8)] ptr mem)
+
+// Generic zeroing uses a loop
+(Zero [s] {t} ptr mem) =>
+	(LoweredZero [t.Alignment()]
+		ptr
+		(ADD <ptr.Type> ptr (MOVDconst [s-moveSize(t.Alignment(), config)]))
+		mem)
+
+(Convert ...) => (MOVconvert ...)
+
+// Checks
+(IsNonNil ...) => (SNEZ ...)
+(IsInBounds ...) => (Less64U ...)
+(IsSliceInBounds ...) => (Leq64U ...)
+
+// Trivial lowering
+(NilCheck ...) => (LoweredNilCheck ...)
+(GetClosurePtr ...) => (LoweredGetClosurePtr ...)
+(GetCallerSP ...) => (LoweredGetCallerSP ...)
+(GetCallerPC ...) => (LoweredGetCallerPC ...)
+
+// Write barrier.
+(WB ...) => (LoweredWB ...)
+
+(PanicBounds [kind] x y mem) && boundsABI(kind) == 0 => (LoweredPanicBoundsA [kind] x y mem)
+(PanicBounds [kind] x y mem) && boundsABI(kind) == 1 => (LoweredPanicBoundsB [kind] x y mem)
+(PanicBounds [kind] x y mem) && boundsABI(kind) == 2 => (LoweredPanicBoundsC [kind] x y mem)
+
+// Small moves
+(Move [0] _ _ mem) => mem
+(Move [1] dst src mem) => (MOVBstore dst (MOVBload src mem) mem)
+(Move [2] {t} dst src mem) && t.Alignment()%2 == 0 =>
+	(MOVHstore dst (MOVHload src mem) mem)
+(Move [2] dst src mem) =>
+	(MOVBstore [1] dst (MOVBload [1] src mem)
+		(MOVBstore dst (MOVBload src mem) mem))
+(Move [4] {t} dst src mem) && t.Alignment()%4 == 0 =>
+	(MOVWstore dst (MOVWload src mem) mem)
+(Move [4] {t} dst src mem) && t.Alignment()%2 == 0 =>
+	(MOVHstore [2] dst (MOVHload [2] src mem)
+		(MOVHstore dst (MOVHload src mem) mem))
+(Move [4] dst src mem) =>
+	(MOVBstore [3] dst (MOVBload [3] src mem)
+		(MOVBstore [2] dst (MOVBload [2] src mem)
+			(MOVBstore [1] dst (MOVBload [1] src mem)
+				(MOVBstore dst (MOVBload src mem) mem))))
+(Move [8] {t} dst src mem) && t.Alignment()%8 == 0 =>
+	(MOVDstore dst (MOVDload src mem) mem)
+(Move [8] {t} dst src mem) && t.Alignment()%4 == 0 =>
+	(MOVWstore [4] dst (MOVWload [4] src mem)
+		(MOVWstore dst (MOVWload src mem) mem))
+(Move [8] {t} dst src mem) && t.Alignment()%2 == 0 =>
+	(MOVHstore [6] dst (MOVHload [6] src mem)
+		(MOVHstore [4] dst (MOVHload [4] src mem)
+			(MOVHstore [2] dst (MOVHload [2] src mem)
+				(MOVHstore dst (MOVHload src mem) mem))))
+
+(Move [3] dst src mem) =>
+	(MOVBstore [2] dst (MOVBload [2] src mem)
+		(MOVBstore [1] dst (MOVBload [1] src mem)
+			(MOVBstore dst (MOVBload src mem) mem)))
+(Move [6] {t} dst src mem) && t.Alignment()%2 == 0 =>
+	(MOVHstore [4] dst (MOVHload [4] src mem)
+		(MOVHstore [2] dst (MOVHload [2] src mem)
+			(MOVHstore dst (MOVHload src mem) mem)))
+(Move [12] {t} dst src mem) && t.Alignment()%4 == 0 =>
+	(MOVWstore [8] dst (MOVWload [8] src mem)
+		(MOVWstore [4] dst (MOVWload [4] src mem)
+			(MOVWstore dst (MOVWload src mem) mem)))
+(Move [16] {t} dst src mem) && t.Alignment()%8 == 0 =>
+	(MOVDstore [8] dst (MOVDload [8] src mem)
+		(MOVDstore dst (MOVDload src mem) mem))
+(Move [24] {t} dst src mem) && t.Alignment()%8 == 0 =>
+	(MOVDstore [16] dst (MOVDload [16] src mem)
+		(MOVDstore [8] dst (MOVDload [8] src mem)
+			(MOVDstore dst (MOVDload src mem) mem)))
+(Move [32] {t} dst src mem) && t.Alignment()%8 == 0 =>
+	(MOVDstore [24] dst (MOVDload [24] src mem)
+		(MOVDstore [16] dst (MOVDload [16] src mem)
+			(MOVDstore [8] dst (MOVDload [8] src mem)
+				(MOVDstore dst (MOVDload src mem) mem))))
+
+// Medium 8-aligned move uses a Duff's device
+// 16 and 128 are magic constants, see runtime/mkduff.go
+(Move [s] {t} dst src mem)
+	&& s%8 == 0 && s <= 8*128 && t.Alignment()%8 == 0
+	&& !config.noDuffDevice && logLargeCopy(v, s) =>
+	(DUFFCOPY [16 * (128 - s/8)] dst src mem)
+
+// Generic move uses a loop
+(Move [s] {t} dst src mem) && (s <= 16 || logLargeCopy(v, s)) =>
+	(LoweredMove [t.Alignment()]
+		dst
+		src
+		(ADDI <src.Type> [s-moveSize(t.Alignment(), config)] src)
+		mem)
+
+// Boolean ops; 0=false, 1=true
+(AndB ...) => (AND ...)
+(OrB  ...) => (OR  ...)
+(EqB  x y) => (SEQZ (SUB <typ.Bool> x y))
+(NeqB x y) => (SNEZ (SUB <typ.Bool> x y))
+(Not  ...) => (SEQZ ...)
+
+// Lowering pointer arithmetic
+// TODO: Special handling for SP offsets, like ARM
+(OffPtr [off] ptr:(SP)) && is32Bit(off) => (MOVaddr [int32(off)] ptr)
+(OffPtr [off] ptr) && is32Bit(off) => (ADDI [off] ptr)
+(OffPtr [off] ptr) => (ADD (MOVDconst [off]) ptr)
+
+(Const8  [val]) => (MOVDconst [int64(val)])
+(Const16 [val]) => (MOVDconst [int64(val)])
+(Const32 [val]) => (MOVDconst [int64(val)])
+(Const64 [val]) => (MOVDconst [int64(val)])
+(Const32F [val]) => (FMVSX (MOVDconst [int64(math.Float32bits(val))]))
+(Const64F [val]) => (FMVDX (MOVDconst [int64(math.Float64bits(val))]))
+(ConstNil) => (MOVDconst [0])
+(ConstBool [val]) => (MOVDconst [int64(b2i(val))])
+
+(Addr {sym} base) => (MOVaddr {sym} [0] base)
+(LocalAddr {sym} base _) => (MOVaddr {sym} base)
+
+// Calls
+(StaticCall  ...) => (CALLstatic  ...)
+(ClosureCall ...) => (CALLclosure ...)
+(InterCall   ...) => (CALLinter   ...)
+(TailCall ...) => (CALLtail ...)
+
+// Atomic Intrinsics
+(AtomicLoad8   ...) => (LoweredAtomicLoad8  ...)
+(AtomicLoad32  ...) => (LoweredAtomicLoad32 ...)
+(AtomicLoad64  ...) => (LoweredAtomicLoad64 ...)
+(AtomicLoadPtr ...) => (LoweredAtomicLoad64 ...)
+
+(AtomicStore8       ...) => (LoweredAtomicStore8  ...)
+(AtomicStore32      ...) => (LoweredAtomicStore32 ...)
+(AtomicStore64      ...) => (LoweredAtomicStore64 ...)
+(AtomicStorePtrNoWB ...) => (LoweredAtomicStore64 ...)
+
+(AtomicAdd32 ...) => (LoweredAtomicAdd32 ...)
+(AtomicAdd64 ...) => (LoweredAtomicAdd64 ...)
+
+// AtomicAnd8(ptr,val) => LoweredAtomicAnd32(ptr&^3, ^((uint8(val) ^ 0xff) << ((ptr & 3) * 8)))
+(AtomicAnd8 ptr val mem) =>
+	(LoweredAtomicAnd32 (ANDI <typ.Uintptr> [^3] ptr)
+		(NOT <typ.UInt32> (SLL <typ.UInt32> (XORI <typ.UInt32> [0xff] (ZeroExt8to32 val))
+			(SLLI <typ.UInt64> [3] (ANDI <typ.UInt64> [3] ptr)))) mem)
+
+(AtomicAnd32 ...) => (LoweredAtomicAnd32 ...)
+
+(AtomicCompareAndSwap32 ptr old new mem) => (LoweredAtomicCas32 ptr (SignExt32to64 old) new mem)
+(AtomicCompareAndSwap64 ...) => (LoweredAtomicCas64 ...)
+
+(AtomicExchange32 ...) => (LoweredAtomicExchange32 ...)
+(AtomicExchange64 ...) => (LoweredAtomicExchange64 ...)
+
+// AtomicOr8(ptr,val)  => LoweredAtomicOr32(ptr&^3, uint32(val)<<((ptr&3)*8))
+(AtomicOr8 ptr val mem) =>
+	(LoweredAtomicOr32 (ANDI <typ.Uintptr> [^3] ptr)
+		(SLL <typ.UInt32> (ZeroExt8to32 val)
+			(SLLI <typ.UInt64> [3] (ANDI <typ.UInt64> [3] ptr))) mem)
+
+(AtomicOr32  ...) => (LoweredAtomicOr32  ...)
+
+// Conditional branches
+(If cond yes no) => (BNEZ (MOVBUreg <typ.UInt64> cond) yes no)
+
+// Optimizations
+
+// Absorb SEQZ/SNEZ into branch.
+(BEQZ (SEQZ x) yes no) => (BNEZ x yes no)
+(BEQZ (SNEZ x) yes no) => (BEQZ x yes no)
+(BNEZ (SEQZ x) yes no) => (BEQZ x yes no)
+(BNEZ (SNEZ x) yes no) => (BNEZ x yes no)
+
+// Remove redundant NEG from BEQZ/BNEZ.
+(BEQZ (NEG x) yes no) => (BEQZ x yes no)
+(BNEZ (NEG x) yes no) => (BNEZ x yes no)
+
+// Negate comparison with FNES/FNED.
+(BEQZ (FNES <t> x y) yes no) => (BNEZ (FEQS <t> x y) yes no)
+(BNEZ (FNES <t> x y) yes no) => (BEQZ (FEQS <t> x y) yes no)
+(BEQZ (FNED <t> x y) yes no) => (BNEZ (FEQD <t> x y) yes no)
+(BNEZ (FNED <t> x y) yes no) => (BEQZ (FEQD <t> x y) yes no)
+
+// Convert BEQZ/BNEZ into more optimal branch conditions.
+(BEQZ (SUB x y) yes no) => (BEQ x y yes no)
+(BNEZ (SUB x y) yes no) => (BNE x y yes no)
+(BEQZ (SLT x y) yes no) => (BGE x y yes no)
+(BNEZ (SLT x y) yes no) => (BLT x y yes no)
+(BEQZ (SLTU x y) yes no) => (BGEU x y yes no)
+(BNEZ (SLTU x y) yes no) => (BLTU x y yes no)
+(BEQZ (SLTI [x] y) yes no) => (BGE y (MOVDconst [x]) yes no)
+(BNEZ (SLTI [x] y) yes no) => (BLT y (MOVDconst [x]) yes no)
+(BEQZ (SLTIU [x] y) yes no) => (BGEU y (MOVDconst [x]) yes no)
+(BNEZ (SLTIU [x] y) yes no) => (BLTU y (MOVDconst [x]) yes no)
+
+// Convert branch with zero to more optimal branch zero.
+(BEQ (MOVDconst [0]) cond yes no) => (BEQZ cond yes no)
+(BEQ cond (MOVDconst [0]) yes no) => (BEQZ cond yes no)
+(BNE (MOVDconst [0]) cond yes no) => (BNEZ cond yes no)
+(BNE cond (MOVDconst [0]) yes no) => (BNEZ cond yes no)
+(BLT (MOVDconst [0]) cond yes no) => (BGTZ cond yes no)
+(BLT cond (MOVDconst [0]) yes no) => (BLTZ cond yes no)
+(BGE (MOVDconst [0]) cond yes no) => (BLEZ cond yes no)
+(BGE cond (MOVDconst [0]) yes no) => (BGEZ cond yes no)
+
+// Remove redundant NEG from SEQZ/SNEZ.
+(SEQZ (NEG x)) => (SEQZ x)
+(SNEZ (NEG x)) => (SNEZ x)
+
+// Remove redundant SEQZ/SNEZ.
+(SEQZ (SEQZ x)) => (SNEZ x)
+(SEQZ (SNEZ x)) => (SEQZ x)
+(SNEZ (SEQZ x)) => (SEQZ x)
+(SNEZ (SNEZ x)) => (SNEZ x)
+
+// Store zero.
+(MOVBstore [off] {sym} ptr (MOVDconst [0]) mem) => (MOVBstorezero [off] {sym} ptr mem)
+(MOVHstore [off] {sym} ptr (MOVDconst [0]) mem) => (MOVHstorezero [off] {sym} ptr mem)
+(MOVWstore [off] {sym} ptr (MOVDconst [0]) mem) => (MOVWstorezero [off] {sym} ptr mem)
+(MOVDstore [off] {sym} ptr (MOVDconst [0]) mem) => (MOVDstorezero [off] {sym} ptr mem)
+
+// Boolean ops are already extended.
+(MOVBUreg x:((FLES|FLTS|FEQS|FNES) _ _)) => x
+(MOVBUreg x:((FLED|FLTD|FEQD|FNED) _ _)) => x
+(MOVBUreg x:((SEQZ|SNEZ) _)) => x
+(MOVBUreg x:((SLT|SLTU) _ _)) => x
+
+// Avoid extending when already sufficiently masked.
+(MOVBreg  x:(ANDI [c] y)) && c >= 0 && int64(int8(c)) == c => x
+(MOVHreg  x:(ANDI [c] y)) && c >= 0 && int64(int16(c)) == c => x
+(MOVWreg  x:(ANDI [c] y)) && c >= 0 && int64(int32(c)) == c => x
+(MOVBUreg x:(ANDI [c] y)) && c >= 0 && int64(uint8(c)) == c => x
+(MOVHUreg x:(ANDI [c] y)) && c >= 0 && int64(uint16(c)) == c => x
+(MOVWUreg x:(ANDI [c] y)) && c >= 0 && int64(uint32(c)) == c => x
+
+// Combine masking and zero extension.
+(MOVBUreg (ANDI [c] x)) && c < 0 => (ANDI [int64(uint8(c))] x)
+(MOVHUreg (ANDI [c] x)) && c < 0 => (ANDI [int64(uint16(c))] x)
+(MOVWUreg (ANDI [c] x)) && c < 0 => (AND (MOVDconst [int64(uint32(c))]) x)
+
+// Avoid sign/zero extension for consts.
+(MOVBreg  (MOVDconst [c])) => (MOVDconst [int64(int8(c))])
+(MOVHreg  (MOVDconst [c])) => (MOVDconst [int64(int16(c))])
+(MOVWreg  (MOVDconst [c])) => (MOVDconst [int64(int32(c))])
+(MOVBUreg (MOVDconst [c])) => (MOVDconst [int64(uint8(c))])
+(MOVHUreg (MOVDconst [c])) => (MOVDconst [int64(uint16(c))])
+(MOVWUreg (MOVDconst [c])) => (MOVDconst [int64(uint32(c))])
+
+// Avoid sign/zero extension after properly typed load.
+(MOVBreg  x:(MOVBload  _ _)) => (MOVDreg x)
+(MOVHreg  x:(MOVBload  _ _)) => (MOVDreg x)
+(MOVHreg  x:(MOVBUload _ _)) => (MOVDreg x)
+(MOVHreg  x:(MOVHload  _ _)) => (MOVDreg x)
+(MOVWreg  x:(MOVBload  _ _)) => (MOVDreg x)
+(MOVWreg  x:(MOVBUload _ _)) => (MOVDreg x)
+(MOVWreg  x:(MOVHload  _ _)) => (MOVDreg x)
+(MOVWreg  x:(MOVHUload _ _)) => (MOVDreg x)
+(MOVWreg  x:(MOVWload  _ _)) => (MOVDreg x)
+(MOVBUreg x:(MOVBUload _ _)) => (MOVDreg x)
+(MOVHUreg x:(MOVBUload _ _)) => (MOVDreg x)
+(MOVHUreg x:(MOVHUload _ _)) => (MOVDreg x)
+(MOVWUreg x:(MOVBUload _ _)) => (MOVDreg x)
+(MOVWUreg x:(MOVHUload _ _)) => (MOVDreg x)
+(MOVWUreg x:(MOVWUload _ _)) => (MOVDreg x)
+
+// Avoid zero extension after properly typed atomic operation.
+(MOVBUreg x:(Select0 (LoweredAtomicLoad8 _ _))) => (MOVDreg x)
+(MOVBUreg x:(Select0 (LoweredAtomicCas32 _ _ _ _))) => (MOVDreg x)
+(MOVBUreg x:(Select0 (LoweredAtomicCas64 _ _ _ _))) => (MOVDreg x)
+
+// Avoid sign extension after word arithmetic.
+(MOVWreg x:(ADDIW   _)) => (MOVDreg x)
+(MOVWreg x:(SUBW  _ _)) => (MOVDreg x)
+(MOVWreg x:(NEGW    _)) => (MOVDreg x)
+(MOVWreg x:(MULW  _ _)) => (MOVDreg x)
+(MOVWreg x:(DIVW  _ _)) => (MOVDreg x)
+(MOVWreg x:(DIVUW _ _)) => (MOVDreg x)
+(MOVWreg x:(REMW  _ _)) => (MOVDreg x)
+(MOVWreg x:(REMUW _ _)) => (MOVDreg x)
+
+// Fold double extensions.
+(MOVBreg  x:(MOVBreg  _)) => (MOVDreg x)
+(MOVHreg  x:(MOVBreg  _)) => (MOVDreg x)
+(MOVHreg  x:(MOVBUreg _)) => (MOVDreg x)
+(MOVHreg  x:(MOVHreg  _)) => (MOVDreg x)
+(MOVWreg  x:(MOVBreg  _)) => (MOVDreg x)
+(MOVWreg  x:(MOVBUreg _)) => (MOVDreg x)
+(MOVWreg  x:(MOVHreg  _)) => (MOVDreg x)
+(MOVWreg  x:(MOVWreg  _)) => (MOVDreg x)
+(MOVBUreg x:(MOVBUreg _)) => (MOVDreg x)
+(MOVHUreg x:(MOVBUreg _)) => (MOVDreg x)
+(MOVHUreg x:(MOVHUreg _)) => (MOVDreg x)
+(MOVWUreg x:(MOVBUreg _)) => (MOVDreg x)
+(MOVWUreg x:(MOVHUreg _)) => (MOVDreg x)
+(MOVWUreg x:(MOVWUreg _)) => (MOVDreg x)
+
+// Do not extend before store.
+(MOVBstore [off] {sym} ptr (MOVBreg  x) mem) => (MOVBstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr (MOVHreg  x) mem) => (MOVBstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr (MOVWreg  x) mem) => (MOVBstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr (MOVBUreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr (MOVHUreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr (MOVWUreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
+(MOVHstore [off] {sym} ptr (MOVHreg  x) mem) => (MOVHstore [off] {sym} ptr x mem)
+(MOVHstore [off] {sym} ptr (MOVWreg  x) mem) => (MOVHstore [off] {sym} ptr x mem)
+(MOVHstore [off] {sym} ptr (MOVHUreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
+(MOVHstore [off] {sym} ptr (MOVWUreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
+(MOVWstore [off] {sym} ptr (MOVWreg  x) mem) => (MOVWstore [off] {sym} ptr x mem)
+(MOVWstore [off] {sym} ptr (MOVWUreg x) mem) => (MOVWstore [off] {sym} ptr x mem)
+
+// Replace extend after load with alternate load where possible.
+(MOVBreg  <t> x:(MOVBUload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVBload  <t> [off] {sym} ptr mem)
+(MOVHreg  <t> x:(MOVHUload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVHload  <t> [off] {sym} ptr mem)
+(MOVWreg  <t> x:(MOVWUload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVWload  <t> [off] {sym} ptr mem)
+(MOVBUreg <t> x:(MOVBload  [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVBUload <t> [off] {sym} ptr mem)
+(MOVHUreg <t> x:(MOVHload  [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVHUload <t> [off] {sym} ptr mem)
+(MOVWUreg <t> x:(MOVWload  [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVWUload <t> [off] {sym} ptr mem)
+
+// If a register move has only 1 use, just use the same register without emitting instruction
+// MOVnop does not emit an instruction, only for ensuring the type.
+(MOVDreg x) && x.Uses == 1 => (MOVDnop x)
+
+// TODO: we should be able to get rid of MOVDnop all together.
+// But for now, this is enough to get rid of lots of them.
+(MOVDnop (MOVDconst [c])) => (MOVDconst [c])
+
+// Fold constant into immediate instructions where possible.
+(ADD (MOVDconst [val]) x) && is32Bit(val) => (ADDI [val] x)
+(AND (MOVDconst [val]) x) && is32Bit(val) => (ANDI [val] x)
+(OR  (MOVDconst [val]) x) && is32Bit(val) => (ORI  [val] x)
+(XOR (MOVDconst [val]) x) && is32Bit(val) => (XORI [val] x)
+(SLL  x (MOVDconst [val])) => (SLLI [int64(val&63)] x)
+(SRL  x (MOVDconst [val])) => (SRLI [int64(val&63)] x)
+(SRA  x (MOVDconst [val])) => (SRAI [int64(val&63)] x)
+(SLT  x (MOVDconst [val])) && val >= -2048 && val <= 2047 => (SLTI  [val] x)
+(SLTU x (MOVDconst [val])) && val >= -2048 && val <= 2047 => (SLTIU [val] x)
+
+// Convert const subtraction into ADDI with negative immediate, where possible.
+(SUB x (MOVDconst [val])) && is32Bit(-val) => (ADDI [-val] x)
+(SUB <t> (MOVDconst [val]) y) && is32Bit(-val) => (NEG (ADDI <t> [-val] y))
+
+// Subtraction of zero.
+(SUB  x (MOVDconst [0])) => x
+(SUBW x (MOVDconst [0])) => (ADDIW [0] x)
+
+// Subtraction from zero.
+(SUB  (MOVDconst [0]) x) => (NEG x)
+(SUBW (MOVDconst [0]) x) => (NEGW x)
+
+// Fold negation into subtraction.
+(NEG (SUB x y)) => (SUB y x)
+(NEG <t> s:(ADDI [val] (SUB x y))) && s.Uses == 1 && is32Bit(-val) => (ADDI [-val] (SUB <t> y x))
+
+// Double negation.
+(NEG (NEG x)) => x
+
+// Addition of zero or two constants.
+(ADDI [0] x) => x
+(ADDI [x] (MOVDconst [y])) && is32Bit(x + y) => (MOVDconst [x + y])
+
+// ANDI with all zeros, all ones or two constants.
+(ANDI [0]  x) => (MOVDconst [0])
+(ANDI [-1] x) => x
+(ANDI [x] (MOVDconst [y])) => (MOVDconst [x & y])
+
+// ORI with all zeroes, all ones or two constants.
+(ORI [0]  x) => x
+(ORI [-1] x) => (MOVDconst [-1])
+(ORI [x] (MOVDconst [y])) => (MOVDconst [x | y])
+
+// Combine operations with immediate.
+(ADDI [x] (ADDI [y] z)) && is32Bit(x + y) => (ADDI [x + y] z)
+(ANDI [x] (ANDI [y] z)) => (ANDI [x & y] z)
+(ORI  [x] (ORI  [y] z)) => (ORI  [x | y] z)
+
+// Negation of a constant.
+(NEG  (MOVDconst [x])) => (MOVDconst [-x])
+(NEGW (MOVDconst [x])) => (MOVDconst [int64(int32(-x))])
+
+// Shift of a constant.
+(SLLI [x] (MOVDconst [y])) && is32Bit(y << uint32(x)) => (MOVDconst [y << uint32(x)])
+(SRLI [x] (MOVDconst [y])) => (MOVDconst [int64(uint64(y) >> uint32(x))])
+(SRAI [x] (MOVDconst [y])) => (MOVDconst [int64(y) >> uint32(x)])
+
+// SLTI/SLTIU with constants.
+(SLTI  [x] (MOVDconst [y])) => (MOVDconst [b2i(int64(y) < int64(x))])
+(SLTIU [x] (MOVDconst [y])) => (MOVDconst [b2i(uint64(y) < uint64(x))])
+
+// SLTI/SLTIU with known outcomes.
+(SLTI  [x] (ANDI [y] _)) && y >= 0 && int64(y) < int64(x) => (MOVDconst [1])
+(SLTIU [x] (ANDI [y] _)) && y >= 0 && uint64(y) < uint64(x) => (MOVDconst [1])
+(SLTI  [x] (ORI  [y] _)) && y >= 0 && int64(y) >= int64(x) => (MOVDconst [0])
+(SLTIU [x] (ORI  [y] _)) && y >= 0 && uint64(y) >= uint64(x) => (MOVDconst [0])
+
+// SLT/SLTU with known outcomes.
+(SLT  x x) => (MOVDconst [0])
+(SLTU x x) => (MOVDconst [0])
+
+// Deadcode for LoweredMuluhilo
+(Select0 m:(LoweredMuluhilo x y)) && m.Uses == 1 => (MULHU x y)
+(Select1 m:(LoweredMuluhilo x y)) && m.Uses == 1 => (MUL x y)
+
+// Merge negation into fused multiply-add and multiply-subtract.
+//
+// Key:
+//
+//   [+ -](x * y) [+ -] z.
+//    _ N          A S
+//                 D U
+//                 D B
+//
+// Note: multiplication commutativity handled by rule generator.
+(F(MADD|NMADD|MSUB|NMSUB)D neg:(FNEGD x) y z) && neg.Uses == 1 => (F(NMADD|MADD|NMSUB|MSUB)D x y z)
+(F(MADD|NMADD|MSUB|NMSUB)D x y neg:(FNEGD z)) && neg.Uses == 1 => (F(MSUB|NMSUB|MADD|NMADD)D x y z)
diff --git a/src/cmd/compile/internal/ssa/_gen/RISCV64Ops.go b/src/cmd/compile/internal/ssa/_gen/RISCV64Ops.go
new file mode 100644
index 0000000..09b1620
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/_gen/RISCV64Ops.go
@@ -0,0 +1,482 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"fmt"
+)
+
+// Notes:
+//  - Boolean types occupy the entire register. 0=false, 1=true.
+
+// Suffixes encode the bit width of various instructions:
+//
+// D (double word) = 64 bit int
+// W (word)        = 32 bit int
+// H (half word)   = 16 bit int
+// B (byte)        = 8 bit int
+// S (single)      = 32 bit float
+// D (double)      = 64 bit float
+// L               = 64 bit int, used when the opcode starts with F
+
+const (
+	riscv64REG_G    = 27
+	riscv64REG_CTXT = 26
+	riscv64REG_LR   = 1
+	riscv64REG_SP   = 2
+	riscv64REG_GP   = 3
+	riscv64REG_TP   = 4
+	riscv64REG_TMP  = 31
+	riscv64REG_ZERO = 0
+)
+
+func riscv64RegName(r int) string {
+	switch {
+	case r == riscv64REG_G:
+		return "g"
+	case r == riscv64REG_SP:
+		return "SP"
+	case 0 <= r && r <= 31:
+		return fmt.Sprintf("X%d", r)
+	case 32 <= r && r <= 63:
+		return fmt.Sprintf("F%d", r-32)
+	default:
+		panic(fmt.Sprintf("unknown register %d", r))
+	}
+}
+
+func init() {
+	var regNamesRISCV64 []string
+	var gpMask, fpMask, gpgMask, gpspMask, gpspsbMask, gpspsbgMask regMask
+	regNamed := make(map[string]regMask)
+
+	// Build the list of register names, creating an appropriately indexed
+	// regMask for the gp and fp registers as we go.
+	//
+	// If name is specified, use it rather than the riscv reg number.
+	addreg := func(r int, name string) regMask {
+		mask := regMask(1) << uint(len(regNamesRISCV64))
+		if name == "" {
+			name = riscv64RegName(r)
+		}
+		regNamesRISCV64 = append(regNamesRISCV64, name)
+		regNamed[name] = mask
+		return mask
+	}
+
+	// General purpose registers.
+	for r := 0; r <= 31; r++ {
+		if r == riscv64REG_LR {
+			// LR is not used by regalloc, so we skip it to leave
+			// room for pseudo-register SB.
+			continue
+		}
+
+		mask := addreg(r, "")
+
+		// Add general purpose registers to gpMask.
+		switch r {
+		// ZERO, GP, TP and TMP are not in any gp mask.
+		case riscv64REG_ZERO, riscv64REG_GP, riscv64REG_TP, riscv64REG_TMP:
+		case riscv64REG_G:
+			gpgMask |= mask
+			gpspsbgMask |= mask
+		case riscv64REG_SP:
+			gpspMask |= mask
+			gpspsbMask |= mask
+			gpspsbgMask |= mask
+		default:
+			gpMask |= mask
+			gpgMask |= mask
+			gpspMask |= mask
+			gpspsbMask |= mask
+			gpspsbgMask |= mask
+		}
+	}
+
+	// Floating pointer registers.
+	for r := 32; r <= 63; r++ {
+		mask := addreg(r, "")
+		fpMask |= mask
+	}
+
+	// Pseudo-register: SB
+	mask := addreg(-1, "SB")
+	gpspsbMask |= mask
+	gpspsbgMask |= mask
+
+	if len(regNamesRISCV64) > 64 {
+		// regMask is only 64 bits.
+		panic("Too many RISCV64 registers")
+	}
+
+	regCtxt := regNamed["X26"]
+	callerSave := gpMask | fpMask | regNamed["g"]
+
+	var (
+		gpstore  = regInfo{inputs: []regMask{gpspsbMask, gpspMask, 0}} // SB in first input so we can load from a global, but not in second to avoid using SB as a temporary register
+		gpstore0 = regInfo{inputs: []regMask{gpspsbMask}}
+		gp01     = regInfo{outputs: []regMask{gpMask}}
+		gp11     = regInfo{inputs: []regMask{gpMask}, outputs: []regMask{gpMask}}
+		gp21     = regInfo{inputs: []regMask{gpMask, gpMask}, outputs: []regMask{gpMask}}
+		gp22     = regInfo{inputs: []regMask{gpMask, gpMask}, outputs: []regMask{gpMask, gpMask}}
+		gpload   = regInfo{inputs: []regMask{gpspsbMask, 0}, outputs: []regMask{gpMask}}
+		gp11sb   = regInfo{inputs: []regMask{gpspsbMask}, outputs: []regMask{gpMask}}
+		gpxchg   = regInfo{inputs: []regMask{gpspsbgMask, gpgMask}, outputs: []regMask{gpMask}}
+		gpcas    = regInfo{inputs: []regMask{gpspsbgMask, gpgMask, gpgMask}, outputs: []regMask{gpMask}}
+		gpatomic = regInfo{inputs: []regMask{gpspsbgMask, gpgMask}}
+
+		fp11    = regInfo{inputs: []regMask{fpMask}, outputs: []regMask{fpMask}}
+		fp21    = regInfo{inputs: []regMask{fpMask, fpMask}, outputs: []regMask{fpMask}}
+		fp31    = regInfo{inputs: []regMask{fpMask, fpMask, fpMask}, outputs: []regMask{fpMask}}
+		gpfp    = regInfo{inputs: []regMask{gpMask}, outputs: []regMask{fpMask}}
+		fpgp    = regInfo{inputs: []regMask{fpMask}, outputs: []regMask{gpMask}}
+		fpstore = regInfo{inputs: []regMask{gpspsbMask, fpMask, 0}}
+		fpload  = regInfo{inputs: []regMask{gpspsbMask, 0}, outputs: []regMask{fpMask}}
+		fp2gp   = regInfo{inputs: []regMask{fpMask, fpMask}, outputs: []regMask{gpMask}}
+
+		call        = regInfo{clobbers: callerSave}
+		callClosure = regInfo{inputs: []regMask{gpspMask, regCtxt, 0}, clobbers: callerSave}
+		callInter   = regInfo{inputs: []regMask{gpMask}, clobbers: callerSave}
+	)
+
+	RISCV64ops := []opData{
+		{name: "ADD", argLength: 2, reg: gp21, asm: "ADD", commutative: true}, // arg0 + arg1
+		{name: "ADDI", argLength: 1, reg: gp11sb, asm: "ADDI", aux: "Int64"},  // arg0 + auxint
+		{name: "ADDIW", argLength: 1, reg: gp11, asm: "ADDIW", aux: "Int64"},  // 32 low bits of arg0 + auxint, sign extended to 64 bits
+		{name: "NEG", argLength: 1, reg: gp11, asm: "NEG"},                    // -arg0
+		{name: "NEGW", argLength: 1, reg: gp11, asm: "NEGW"},                  // -arg0 of 32 bits, sign extended to 64 bits
+		{name: "SUB", argLength: 2, reg: gp21, asm: "SUB"},                    // arg0 - arg1
+		{name: "SUBW", argLength: 2, reg: gp21, asm: "SUBW"},                  // 32 low bits of arg 0 - 32 low bits of arg 1, sign extended to 64 bits
+
+		// M extension. H means high (i.e., it returns the top bits of
+		// the result). U means unsigned. W means word (i.e., 32-bit).
+		{name: "MUL", argLength: 2, reg: gp21, asm: "MUL", commutative: true, typ: "Int64"}, // arg0 * arg1
+		{name: "MULW", argLength: 2, reg: gp21, asm: "MULW", commutative: true, typ: "Int32"},
+		{name: "MULH", argLength: 2, reg: gp21, asm: "MULH", commutative: true, typ: "Int64"},
+		{name: "MULHU", argLength: 2, reg: gp21, asm: "MULHU", commutative: true, typ: "UInt64"},
+		{name: "LoweredMuluhilo", argLength: 2, reg: gp22, resultNotInArgs: true}, // arg0 * arg1, return (hi, lo)
+		{name: "LoweredMuluover", argLength: 2, reg: gp22, resultNotInArgs: true}, // arg0 * arg1, return (64 bits of arg0*arg1, overflow)
+
+		{name: "DIV", argLength: 2, reg: gp21, asm: "DIV", typ: "Int64"}, // arg0 / arg1
+		{name: "DIVU", argLength: 2, reg: gp21, asm: "DIVU", typ: "UInt64"},
+		{name: "DIVW", argLength: 2, reg: gp21, asm: "DIVW", typ: "Int32"},
+		{name: "DIVUW", argLength: 2, reg: gp21, asm: "DIVUW", typ: "UInt32"},
+		{name: "REM", argLength: 2, reg: gp21, asm: "REM", typ: "Int64"}, // arg0 % arg1
+		{name: "REMU", argLength: 2, reg: gp21, asm: "REMU", typ: "UInt64"},
+		{name: "REMW", argLength: 2, reg: gp21, asm: "REMW", typ: "Int32"},
+		{name: "REMUW", argLength: 2, reg: gp21, asm: "REMUW", typ: "UInt32"},
+
+		{name: "MOVaddr", argLength: 1, reg: gp11sb, asm: "MOV", aux: "SymOff", rematerializeable: true, symEffect: "RdWr"}, // arg0 + auxint + offset encoded in aux
+		// auxint+aux == add auxint and the offset of the symbol in aux (if any) to the effective address
+
+		{name: "MOVDconst", reg: gp01, asm: "MOV", typ: "UInt64", aux: "Int64", rematerializeable: true}, // auxint
+
+		// Loads: load <size> bits from arg0+auxint+aux and extend to 64 bits; arg1=mem
+		{name: "MOVBload", argLength: 2, reg: gpload, asm: "MOVB", aux: "SymOff", typ: "Int8", faultOnNilArg0: true, symEffect: "Read"},     //  8 bits, sign extend
+		{name: "MOVHload", argLength: 2, reg: gpload, asm: "MOVH", aux: "SymOff", typ: "Int16", faultOnNilArg0: true, symEffect: "Read"},    // 16 bits, sign extend
+		{name: "MOVWload", argLength: 2, reg: gpload, asm: "MOVW", aux: "SymOff", typ: "Int32", faultOnNilArg0: true, symEffect: "Read"},    // 32 bits, sign extend
+		{name: "MOVDload", argLength: 2, reg: gpload, asm: "MOV", aux: "SymOff", typ: "Int64", faultOnNilArg0: true, symEffect: "Read"},     // 64 bits
+		{name: "MOVBUload", argLength: 2, reg: gpload, asm: "MOVBU", aux: "SymOff", typ: "UInt8", faultOnNilArg0: true, symEffect: "Read"},  //  8 bits, zero extend
+		{name: "MOVHUload", argLength: 2, reg: gpload, asm: "MOVHU", aux: "SymOff", typ: "UInt16", faultOnNilArg0: true, symEffect: "Read"}, // 16 bits, zero extend
+		{name: "MOVWUload", argLength: 2, reg: gpload, asm: "MOVWU", aux: "SymOff", typ: "UInt32", faultOnNilArg0: true, symEffect: "Read"}, // 32 bits, zero extend
+
+		// Stores: store <size> lowest bits in arg1 to arg0+auxint+aux; arg2=mem
+		{name: "MOVBstore", argLength: 3, reg: gpstore, asm: "MOVB", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, //  8 bits
+		{name: "MOVHstore", argLength: 3, reg: gpstore, asm: "MOVH", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // 16 bits
+		{name: "MOVWstore", argLength: 3, reg: gpstore, asm: "MOVW", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // 32 bits
+		{name: "MOVDstore", argLength: 3, reg: gpstore, asm: "MOV", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},  // 64 bits
+
+		// Stores: store <size> of zero in arg0+auxint+aux; arg1=mem
+		{name: "MOVBstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVB", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, //  8 bits
+		{name: "MOVHstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVH", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // 16 bits
+		{name: "MOVWstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVW", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // 32 bits
+		{name: "MOVDstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOV", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},  // 64 bits
+
+		// Conversions
+		{name: "MOVBreg", argLength: 1, reg: gp11, asm: "MOVB"},   // move from arg0, sign-extended from byte
+		{name: "MOVHreg", argLength: 1, reg: gp11, asm: "MOVH"},   // move from arg0, sign-extended from half
+		{name: "MOVWreg", argLength: 1, reg: gp11, asm: "MOVW"},   // move from arg0, sign-extended from word
+		{name: "MOVDreg", argLength: 1, reg: gp11, asm: "MOV"},    // move from arg0
+		{name: "MOVBUreg", argLength: 1, reg: gp11, asm: "MOVBU"}, // move from arg0, unsign-extended from byte
+		{name: "MOVHUreg", argLength: 1, reg: gp11, asm: "MOVHU"}, // move from arg0, unsign-extended from half
+		{name: "MOVWUreg", argLength: 1, reg: gp11, asm: "MOVWU"}, // move from arg0, unsign-extended from word
+
+		{name: "MOVDnop", argLength: 1, reg: regInfo{inputs: []regMask{gpMask}, outputs: []regMask{gpMask}}, resultInArg0: true}, // nop, return arg0 in same register
+
+		// Shift ops
+		{name: "SLL", argLength: 2, reg: gp21, asm: "SLL"},                 // arg0 << (aux1 & 63)
+		{name: "SRA", argLength: 2, reg: gp21, asm: "SRA"},                 // arg0 >> (aux1 & 63), signed
+		{name: "SRL", argLength: 2, reg: gp21, asm: "SRL"},                 // arg0 >> (aux1 & 63), unsigned
+		{name: "SLLI", argLength: 1, reg: gp11, asm: "SLLI", aux: "Int64"}, // arg0 << auxint, shift amount 0-63
+		{name: "SRAI", argLength: 1, reg: gp11, asm: "SRAI", aux: "Int64"}, // arg0 >> auxint, signed, shift amount 0-63
+		{name: "SRLI", argLength: 1, reg: gp11, asm: "SRLI", aux: "Int64"}, // arg0 >> auxint, unsigned, shift amount 0-63
+
+		// Bitwise ops
+		{name: "XOR", argLength: 2, reg: gp21, asm: "XOR", commutative: true}, // arg0 ^ arg1
+		{name: "XORI", argLength: 1, reg: gp11, asm: "XORI", aux: "Int64"},    // arg0 ^ auxint
+		{name: "OR", argLength: 2, reg: gp21, asm: "OR", commutative: true},   // arg0 | arg1
+		{name: "ORI", argLength: 1, reg: gp11, asm: "ORI", aux: "Int64"},      // arg0 | auxint
+		{name: "AND", argLength: 2, reg: gp21, asm: "AND", commutative: true}, // arg0 & arg1
+		{name: "ANDI", argLength: 1, reg: gp11, asm: "ANDI", aux: "Int64"},    // arg0 & auxint
+		{name: "NOT", argLength: 1, reg: gp11, asm: "NOT"},                    // ^arg0
+
+		// Generate boolean values
+		{name: "SEQZ", argLength: 1, reg: gp11, asm: "SEQZ"},                 // arg0 == 0, result is 0 or 1
+		{name: "SNEZ", argLength: 1, reg: gp11, asm: "SNEZ"},                 // arg0 != 0, result is 0 or 1
+		{name: "SLT", argLength: 2, reg: gp21, asm: "SLT"},                   // arg0 < arg1, result is 0 or 1
+		{name: "SLTI", argLength: 1, reg: gp11, asm: "SLTI", aux: "Int64"},   // arg0 < auxint, result is 0 or 1
+		{name: "SLTU", argLength: 2, reg: gp21, asm: "SLTU"},                 // arg0 < arg1, unsigned, result is 0 or 1
+		{name: "SLTIU", argLength: 1, reg: gp11, asm: "SLTIU", aux: "Int64"}, // arg0 < auxint, unsigned, result is 0 or 1
+
+		// MOVconvert converts between pointers and integers.
+		// We have a special op for this so as to not confuse GC
+		// (particularly stack maps). It takes a memory arg so it
+		// gets correctly ordered with respect to GC safepoints.
+		{name: "MOVconvert", argLength: 2, reg: gp11, asm: "MOV"}, // arg0, but converted to int/ptr as appropriate; arg1=mem
+
+		// Calls
+		{name: "CALLstatic", argLength: -1, reg: call, aux: "CallOff", call: true},               // call static function aux.(*gc.Sym). last arg=mem, auxint=argsize, returns mem
+		{name: "CALLtail", argLength: -1, reg: call, aux: "CallOff", call: true, tailCall: true}, // tail call static function aux.(*gc.Sym). last arg=mem, auxint=argsize, returns mem
+		{name: "CALLclosure", argLength: -1, reg: callClosure, aux: "CallOff", call: true},       // call function via closure. arg0=codeptr, arg1=closure, last arg=mem, auxint=argsize, returns mem
+		{name: "CALLinter", argLength: -1, reg: callInter, aux: "CallOff", call: true},           // call fn by pointer. arg0=codeptr, last arg=mem, auxint=argsize, returns mem
+
+		// duffzero
+		// arg0 = address of memory to zero (in X25, changed as side effect)
+		// arg1 = mem
+		// auxint = offset into duffzero code to start executing
+		// X1 (link register) changed because of function call
+		// returns mem
+		{
+			name:      "DUFFZERO",
+			aux:       "Int64",
+			argLength: 2,
+			reg: regInfo{
+				inputs:   []regMask{regNamed["X25"]},
+				clobbers: regNamed["X1"] | regNamed["X25"],
+			},
+			typ:            "Mem",
+			faultOnNilArg0: true,
+		},
+
+		// duffcopy
+		// arg0 = address of dst memory (in X25, changed as side effect)
+		// arg1 = address of src memory (in X24, changed as side effect)
+		// arg2 = mem
+		// auxint = offset into duffcopy code to start executing
+		// X1 (link register) changed because of function call
+		// returns mem
+		{
+			name:      "DUFFCOPY",
+			aux:       "Int64",
+			argLength: 3,
+			reg: regInfo{
+				inputs:   []regMask{regNamed["X25"], regNamed["X24"]},
+				clobbers: regNamed["X1"] | regNamed["X24"] | regNamed["X25"],
+			},
+			typ:            "Mem",
+			faultOnNilArg0: true,
+			faultOnNilArg1: true,
+		},
+
+		// Generic moves and zeros
+
+		// general unaligned zeroing
+		// arg0 = address of memory to zero (in X5, changed as side effect)
+		// arg1 = address of the last element to zero (inclusive)
+		// arg2 = mem
+		// auxint = element size
+		// returns mem
+		//	mov	ZERO, (X5)
+		//	ADD	$sz, X5
+		//	BGEU	Rarg1, X5, -2(PC)
+		{
+			name:      "LoweredZero",
+			aux:       "Int64",
+			argLength: 3,
+			reg: regInfo{
+				inputs:   []regMask{regNamed["X5"], gpMask},
+				clobbers: regNamed["X5"],
+			},
+			typ:            "Mem",
+			faultOnNilArg0: true,
+		},
+
+		// general unaligned move
+		// arg0 = address of dst memory (in X5, changed as side effect)
+		// arg1 = address of src memory (in X6, changed as side effect)
+		// arg2 = address of the last element of src (can't be X7 as we clobber it before using arg2)
+		// arg3 = mem
+		// auxint = alignment
+		// clobbers X7 as a tmp register.
+		// returns mem
+		//	mov	(X6), X7
+		//	mov	X7, (X5)
+		//	ADD	$sz, X5
+		//	ADD	$sz, X6
+		//	BGEU	Rarg2, X5, -4(PC)
+		{
+			name:      "LoweredMove",
+			aux:       "Int64",
+			argLength: 4,
+			reg: regInfo{
+				inputs:   []regMask{regNamed["X5"], regNamed["X6"], gpMask &^ regNamed["X7"]},
+				clobbers: regNamed["X5"] | regNamed["X6"] | regNamed["X7"],
+			},
+			typ:            "Mem",
+			faultOnNilArg0: true,
+			faultOnNilArg1: true,
+		},
+
+		// Atomic loads.
+		// load from arg0. arg1=mem.
+		// returns <value,memory> so they can be properly ordered with other loads.
+		{name: "LoweredAtomicLoad8", argLength: 2, reg: gpload, faultOnNilArg0: true},
+		{name: "LoweredAtomicLoad32", argLength: 2, reg: gpload, faultOnNilArg0: true},
+		{name: "LoweredAtomicLoad64", argLength: 2, reg: gpload, faultOnNilArg0: true},
+
+		// Atomic stores.
+		// store arg1 to *arg0. arg2=mem. returns memory.
+		{name: "LoweredAtomicStore8", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true},
+		{name: "LoweredAtomicStore32", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true},
+		{name: "LoweredAtomicStore64", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true},
+
+		// Atomic exchange.
+		// store arg1 to *arg0. arg2=mem. returns <old content of *arg0, memory>.
+		{name: "LoweredAtomicExchange32", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
+		{name: "LoweredAtomicExchange64", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
+
+		// Atomic add.
+		// *arg0 += arg1. arg2=mem. returns <new content of *arg0, memory>.
+		{name: "LoweredAtomicAdd32", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+		{name: "LoweredAtomicAdd64", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+
+		// Atomic compare and swap.
+		// arg0 = pointer, arg1 = old value, arg2 = new value, arg3 = memory.
+		// if *arg0 == arg1 {
+		//   *arg0 = arg2
+		//   return (true, memory)
+		// } else {
+		//   return (false, memory)
+		// }
+		// MOV  $0, Rout
+		// LR	(Rarg0), Rtmp
+		// BNE	Rtmp, Rarg1, 3(PC)
+		// SC	Rarg2, (Rarg0), Rtmp
+		// BNE	Rtmp, ZERO, -3(PC)
+		// MOV  $1, Rout
+		{name: "LoweredAtomicCas32", argLength: 4, reg: gpcas, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+		{name: "LoweredAtomicCas64", argLength: 4, reg: gpcas, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
+
+		// Atomic 32 bit AND/OR.
+		// *arg0 &= (|=) arg1. arg2=mem. returns nil.
+		{name: "LoweredAtomicAnd32", argLength: 3, reg: gpatomic, asm: "AMOANDW", faultOnNilArg0: true, hasSideEffects: true},
+		{name: "LoweredAtomicOr32", argLength: 3, reg: gpatomic, asm: "AMOORW", faultOnNilArg0: true, hasSideEffects: true},
+
+		// Lowering pass-throughs
+		{name: "LoweredNilCheck", argLength: 2, faultOnNilArg0: true, nilCheck: true, reg: regInfo{inputs: []regMask{gpspMask}}}, // arg0=ptr,arg1=mem, returns void.  Faults if ptr is nil.
+		{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{regCtxt}}},                                                // scheduler ensures only at beginning of entry block
+
+		// LoweredGetCallerSP returns the SP of the caller of the current function.
+		{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
+
+		// LoweredGetCallerPC evaluates to the PC to which its "caller" will return.
+		// I.e., if f calls g "calls" getcallerpc,
+		// the result should be the PC within f that g will return to.
+		// See runtime/stubs.go for a more detailed discussion.
+		{name: "LoweredGetCallerPC", reg: gp01, rematerializeable: true},
+
+		// LoweredWB invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
+		// It saves all GP registers if necessary,
+		// but clobbers RA (LR) because it's a call
+		// and T6 (REG_TMP).
+		{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{regNamed["X5"], regNamed["X6"]}, clobbers: (callerSave &^ (gpMask | regNamed["g"])) | regNamed["X1"]}, clobberFlags: true, aux: "Sym", symEffect: "None"},
+
+		// There are three of these functions so that they can have three different register inputs.
+		// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the
+		// default registers to match so we don't need to copy registers around unnecessarily.
+		{name: "LoweredPanicBoundsA", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{regNamed["X7"], regNamed["X28"]}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
+		{name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{regNamed["X6"], regNamed["X7"]}}, typ: "Mem", call: true},  // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
+		{name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{regNamed["X5"], regNamed["X6"]}}, typ: "Mem", call: true},  // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
+
+		// F extension.
+		{name: "FADDS", argLength: 2, reg: fp21, asm: "FADDS", commutative: true, typ: "Float32"},                                           // arg0 + arg1
+		{name: "FSUBS", argLength: 2, reg: fp21, asm: "FSUBS", commutative: false, typ: "Float32"},                                          // arg0 - arg1
+		{name: "FMULS", argLength: 2, reg: fp21, asm: "FMULS", commutative: true, typ: "Float32"},                                           // arg0 * arg1
+		{name: "FDIVS", argLength: 2, reg: fp21, asm: "FDIVS", commutative: false, typ: "Float32"},                                          // arg0 / arg1
+		{name: "FSQRTS", argLength: 1, reg: fp11, asm: "FSQRTS", typ: "Float32"},                                                            // sqrt(arg0)
+		{name: "FNEGS", argLength: 1, reg: fp11, asm: "FNEGS", typ: "Float32"},                                                              // -arg0
+		{name: "FMVSX", argLength: 1, reg: gpfp, asm: "FMVSX", typ: "Float32"},                                                              // reinterpret arg0 as float
+		{name: "FCVTSW", argLength: 1, reg: gpfp, asm: "FCVTSW", typ: "Float32"},                                                            // float32(low 32 bits of arg0)
+		{name: "FCVTSL", argLength: 1, reg: gpfp, asm: "FCVTSL", typ: "Float32"},                                                            // float32(arg0)
+		{name: "FCVTWS", argLength: 1, reg: fpgp, asm: "FCVTWS", typ: "Int32"},                                                              // int32(arg0)
+		{name: "FCVTLS", argLength: 1, reg: fpgp, asm: "FCVTLS", typ: "Int64"},                                                              // int64(arg0)
+		{name: "FMOVWload", argLength: 2, reg: fpload, asm: "MOVF", aux: "SymOff", typ: "Float32", faultOnNilArg0: true, symEffect: "Read"}, // load float32 from arg0+auxint+aux
+		{name: "FMOVWstore", argLength: 3, reg: fpstore, asm: "MOVF", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},  // store float32 to arg0+auxint+aux
+		{name: "FEQS", argLength: 2, reg: fp2gp, asm: "FEQS", commutative: true},                                                            // arg0 == arg1
+		{name: "FNES", argLength: 2, reg: fp2gp, asm: "FNES", commutative: true},                                                            // arg0 != arg1
+		{name: "FLTS", argLength: 2, reg: fp2gp, asm: "FLTS"},                                                                               // arg0 < arg1
+		{name: "FLES", argLength: 2, reg: fp2gp, asm: "FLES"},                                                                               // arg0 <= arg1
+
+		// D extension.
+		{name: "FADDD", argLength: 2, reg: fp21, asm: "FADDD", commutative: true, typ: "Float64"},                                           // arg0 + arg1
+		{name: "FSUBD", argLength: 2, reg: fp21, asm: "FSUBD", commutative: false, typ: "Float64"},                                          // arg0 - arg1
+		{name: "FMULD", argLength: 2, reg: fp21, asm: "FMULD", commutative: true, typ: "Float64"},                                           // arg0 * arg1
+		{name: "FDIVD", argLength: 2, reg: fp21, asm: "FDIVD", commutative: false, typ: "Float64"},                                          // arg0 / arg1
+		{name: "FMADDD", argLength: 3, reg: fp31, asm: "FMADDD", commutative: true, typ: "Float64"},                                         // (arg0 * arg1) + arg2
+		{name: "FMSUBD", argLength: 3, reg: fp31, asm: "FMSUBD", commutative: true, typ: "Float64"},                                         // (arg0 * arg1) - arg2
+		{name: "FNMADDD", argLength: 3, reg: fp31, asm: "FNMADDD", commutative: true, typ: "Float64"},                                       // -(arg0 * arg1) + arg2
+		{name: "FNMSUBD", argLength: 3, reg: fp31, asm: "FNMSUBD", commutative: true, typ: "Float64"},                                       // -(arg0 * arg1) - arg2
+		{name: "FSQRTD", argLength: 1, reg: fp11, asm: "FSQRTD", typ: "Float64"},                                                            // sqrt(arg0)
+		{name: "FNEGD", argLength: 1, reg: fp11, asm: "FNEGD", typ: "Float64"},                                                              // -arg0
+		{name: "FABSD", argLength: 1, reg: fp11, asm: "FABSD", typ: "Float64"},                                                              // abs(arg0)
+		{name: "FSGNJD", argLength: 2, reg: fp21, asm: "FSGNJD", typ: "Float64"},                                                            // copy sign of arg1 to arg0
+		{name: "FMVDX", argLength: 1, reg: gpfp, asm: "FMVDX", typ: "Float64"},                                                              // reinterpret arg0 as float
+		{name: "FCVTDW", argLength: 1, reg: gpfp, asm: "FCVTDW", typ: "Float64"},                                                            // float64(low 32 bits of arg0)
+		{name: "FCVTDL", argLength: 1, reg: gpfp, asm: "FCVTDL", typ: "Float64"},                                                            // float64(arg0)
+		{name: "FCVTWD", argLength: 1, reg: fpgp, asm: "FCVTWD", typ: "Int32"},                                                              // int32(arg0)
+		{name: "FCVTLD", argLength: 1, reg: fpgp, asm: "FCVTLD", typ: "Int64"},                                                              // int64(arg0)
+		{name: "FCVTDS", argLength: 1, reg: fp11, asm: "FCVTDS", typ: "Float64"},                                                            // float64(arg0)
+		{name: "FCVTSD", argLength: 1, reg: fp11, asm: "FCVTSD", typ: "Float32"},                                                            // float32(arg0)
+		{name: "FMOVDload", argLength: 2, reg: fpload, asm: "MOVD", aux: "SymOff", typ: "Float64", faultOnNilArg0: true, symEffect: "Read"}, // load float64 from arg0+auxint+aux
+		{name: "FMOVDstore", argLength: 3, reg: fpstore, asm: "MOVD", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},  // store float6 to arg0+auxint+aux
+		{name: "FEQD", argLength: 2, reg: fp2gp, asm: "FEQD", commutative: true},                                                            // arg0 == arg1
+		{name: "FNED", argLength: 2, reg: fp2gp, asm: "FNED", commutative: true},                                                            // arg0 != arg1
+		{name: "FLTD", argLength: 2, reg: fp2gp, asm: "FLTD"},                                                                               // arg0 < arg1
+		{name: "FLED", argLength: 2, reg: fp2gp, asm: "FLED"},                                                                               // arg0 <= arg1
+	}
+
+	RISCV64blocks := []blockData{
+		{name: "BEQ", controls: 2},
+		{name: "BNE", controls: 2},
+		{name: "BLT", controls: 2},
+		{name: "BGE", controls: 2},
+		{name: "BLTU", controls: 2},
+		{name: "BGEU", controls: 2},
+
+		{name: "BEQZ", controls: 1},
+		{name: "BNEZ", controls: 1},
+		{name: "BLEZ", controls: 1},
+		{name: "BGEZ", controls: 1},
+		{name: "BLTZ", controls: 1},
+		{name: "BGTZ", controls: 1},
+	}
+
+	archs = append(archs, arch{
+		name:            "RISCV64",
+		pkg:             "cmd/internal/obj/riscv",
+		genfile:         "../../riscv64/ssa.go",
+		ops:             RISCV64ops,
+		blocks:          RISCV64blocks,
+		regnames:        regNamesRISCV64,
+		gpregmask:       gpMask,
+		fpregmask:       fpMask,
+		framepointerreg: -1, // not used
+		// Integer parameters passed in register X10-X17, X8-X9, X18-X23
+		ParamIntRegNames: "X10 X11 X12 X13 X14 X15 X16 X17 X8 X9 X18 X19 X20 X21 X22 X23",
+		// Float parameters passed in register F10-F17, F8-F9, F18-F23
+		ParamFloatRegNames: "F10 F11 F12 F13 F14 F15 F16 F17 F8 F9 F18 F19 F20 F21 F22 F23",
+	})
+}
diff --git a/src/cmd/compile/internal/ssa/_gen/RISCV64latelower.rules b/src/cmd/compile/internal/ssa/_gen/RISCV64latelower.rules
new file mode 100644
index 0000000..cd55331
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/_gen/RISCV64latelower.rules
@@ -0,0 +1,19 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Fold constant shift with extension.
+(SRAI [c] (MOVBreg  x)) && c <   8 => (SRAI [56+c] (SLLI <typ.Int64> [56] x))
+(SRAI [c] (MOVHreg  x)) && c <  16 => (SRAI [48+c] (SLLI <typ.Int64> [48] x))
+(SRAI [c] (MOVWreg  x)) && c <  32 => (SRAI [32+c] (SLLI <typ.Int64> [32] x))
+(SRLI [c] (MOVBUreg x)) && c <   8 => (SRLI [56+c] (SLLI <typ.UInt64> [56] x))
+(SRLI [c] (MOVHUreg x)) && c <  16 => (SRLI [48+c] (SLLI <typ.UInt64> [48] x))
+(SRLI [c] (MOVWUreg x)) && c <  32 => (SRLI [32+c] (SLLI <typ.UInt64> [32] x))
+(SLLI [c] (MOVBUreg x)) && c <= 56 => (SRLI [56-c] (SLLI <typ.UInt64> [56] x))
+(SLLI [c] (MOVHUreg x)) && c <= 48 => (SRLI [48-c] (SLLI <typ.UInt64> [48] x))
+(SLLI [c] (MOVWUreg x)) && c <= 32 => (SRLI [32-c] (SLLI <typ.UInt64> [32] x))
+
+// Shift by zero.
+(SRAI [0] x) => x
+(SRLI [0] x) => x
+(SLLI [0] x) => x
diff --git a/src/cmd/compile/internal/ssa/_gen/S390X.rules b/src/cmd/compile/internal/ssa/_gen/S390X.rules
new file mode 100644
index 0000000..e9becb2
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/_gen/S390X.rules
@@ -0,0 +1,1704 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Lowering arithmetic
+(Add(64|Ptr) ...) => (ADD ...)
+(Add(32|16|8) ...) => (ADDW ...)
+(Add32F x y) => (Select0 (FADDS x y))
+(Add64F x y) => (Select0 (FADD x y))
+
+(Sub(64|Ptr) ...) => (SUB ...)
+(Sub(32|16|8) ...) => (SUBW ...)
+(Sub32F x y) => (Select0 (FSUBS x y))
+(Sub64F x y) => (Select0 (FSUB x y))
+
+(Mul64 ...) => (MULLD ...)
+(Mul(32|16|8) ...) => (MULLW ...)
+(Mul32F ...) => (FMULS ...)
+(Mul64F ...) => (FMUL ...)
+(Mul64uhilo ...) => (MLGR ...)
+
+(Div32F ...) => (FDIVS ...)
+(Div64F ...) => (FDIV ...)
+
+(Div64 x y) => (DIVD x y)
+(Div64u ...) => (DIVDU ...)
+// DIVW/DIVWU has a 64-bit dividend and a 32-bit divisor,
+// so a sign/zero extension of the dividend is required.
+(Div32  x y) => (DIVW  (MOVWreg x) y)
+(Div32u x y) => (DIVWU (MOVWZreg x) y)
+(Div16  x y) => (DIVW  (MOVHreg x) (MOVHreg y))
+(Div16u x y) => (DIVWU (MOVHZreg x) (MOVHZreg y))
+(Div8   x y) => (DIVW  (MOVBreg x) (MOVBreg y))
+(Div8u  x y) => (DIVWU (MOVBZreg x) (MOVBZreg y))
+
+(Hmul(64|64u) ...) => (MULH(D|DU) ...)
+(Hmul32  x y) => (SRDconst [32] (MULLD (MOVWreg x) (MOVWreg y)))
+(Hmul32u x y) => (SRDconst [32] (MULLD (MOVWZreg x) (MOVWZreg y)))
+
+(Mod64 x y) => (MODD x y)
+(Mod64u ...) => (MODDU ...)
+// MODW/MODWU has a 64-bit dividend and a 32-bit divisor,
+// so a sign/zero extension of the dividend is required.
+(Mod32  x y) => (MODW  (MOVWreg x) y)
+(Mod32u x y) => (MODWU (MOVWZreg x) y)
+(Mod16  x y) => (MODW  (MOVHreg x) (MOVHreg y))
+(Mod16u x y) => (MODWU (MOVHZreg x) (MOVHZreg y))
+(Mod8   x y) => (MODW  (MOVBreg x) (MOVBreg y))
+(Mod8u  x y) => (MODWU (MOVBZreg x) (MOVBZreg y))
+
+// (x + y) / 2 with x>=y -> (x - y) / 2 + y
+(Avg64u <t> x y) => (ADD (SRDconst <t> (SUB <t> x y) [1]) y)
+
+(And64 ...) => (AND ...)
+(And(32|16|8) ...) => (ANDW ...)
+
+(Or64 ...) => (OR ...)
+(Or(32|16|8) ...) => (ORW ...)
+
+(Xor64 ...) => (XOR ...)
+(Xor(32|16|8) ...) => (XORW ...)
+
+(Neg64 ...) => (NEG ...)
+(Neg(32|16|8) ...) => (NEGW ...)
+(Neg32F ...) => (FNEGS ...)
+(Neg64F ...) => (FNEG ...)
+
+(Com64 ...) => (NOT ...)
+(Com(32|16|8) ...) => (NOTW ...)
+(NOT x) => (XOR (MOVDconst [-1]) x)
+(NOTW x) => (XORWconst [-1] x)
+
+// Lowering boolean ops
+(AndB ...) => (ANDW ...)
+(OrB ...) => (ORW ...)
+(Not x) => (XORWconst [1] x)
+
+// Lowering pointer arithmetic
+(OffPtr [off] ptr:(SP)) => (MOVDaddr [int32(off)] ptr)
+(OffPtr [off] ptr) && is32Bit(off) => (ADDconst [int32(off)] ptr)
+(OffPtr [off] ptr) => (ADD (MOVDconst [off]) ptr)
+
+// TODO: optimize these cases?
+(Ctz64NonZero ...) => (Ctz64 ...)
+(Ctz32NonZero ...) => (Ctz32 ...)
+
+// Ctz(x) = 64 - findLeftmostOne((x-1)&^x)
+(Ctz64 <t> x) => (SUB (MOVDconst [64]) (FLOGR (AND <t> (SUBconst <t> [1] x) (NOT <t> x))))
+(Ctz32 <t> x) => (SUB (MOVDconst [64]) (FLOGR (MOVWZreg (ANDW <t> (SUBWconst <t> [1] x) (NOTW <t> x)))))
+
+(BitLen64 x) => (SUB (MOVDconst [64]) (FLOGR x))
+
+// POPCNT treats the input register as a vector of 8 bytes, producing
+// a population count for each individual byte. For inputs larger than
+// a single byte we therefore need to sum the individual bytes produced
+// by the POPCNT instruction. For example, the following instruction
+// sequence could be used to calculate the population count of a 4-byte
+// value:
+//
+//     MOVD   $0x12345678, R1 // R1=0x12345678 <-- input
+//     POPCNT R1, R2          // R2=0x02030404
+//     SRW    $16, R2, R3     // R3=0x00000203
+//     ADDW   R2, R3, R4      // R4=0x02030607
+//     SRW    $8, R4, R5      // R5=0x00020306
+//     ADDW   R4, R5, R6      // R6=0x0205090d
+//     MOVBZ  R6, R7          // R7=0x0000000d <-- result is 13
+//
+(PopCount8  x) => (POPCNT (MOVBZreg x))
+(PopCount16 x) => (MOVBZreg (SumBytes2 (POPCNT <typ.UInt16> x)))
+(PopCount32 x) => (MOVBZreg (SumBytes4 (POPCNT <typ.UInt32> x)))
+(PopCount64 x) => (MOVBZreg (SumBytes8 (POPCNT <typ.UInt64> x)))
+
+// SumBytes{2,4,8} pseudo operations sum the values of the rightmost
+// 2, 4 or 8 bytes respectively. The result is a single byte however
+// other bytes might contain junk so a zero extension is required if
+// the desired output type is larger than 1 byte.
+(SumBytes2 x) => (ADDW (SRWconst <typ.UInt8> x [8]) x)
+(SumBytes4 x) => (SumBytes2 (ADDW <typ.UInt16> (SRWconst <typ.UInt16> x [16]) x))
+(SumBytes8 x) => (SumBytes4 (ADDW <typ.UInt32> (SRDconst <typ.UInt32> x [32]) x))
+
+(Bswap64 ...) => (MOVDBR ...)
+(Bswap32 ...) => (MOVWBR ...)
+
+// add with carry
+(Select0 (Add64carry x y c))
+  => (Select0 <typ.UInt64> (ADDE x y (Select1 <types.TypeFlags> (ADDCconst c [-1]))))
+(Select1 (Add64carry x y c))
+  => (Select0 <typ.UInt64> (ADDE (MOVDconst [0]) (MOVDconst [0]) (Select1 <types.TypeFlags> (ADDE x y (Select1 <types.TypeFlags> (ADDCconst c [-1]))))))
+
+// subtract with borrow
+(Select0 (Sub64borrow x y c))
+  => (Select0 <typ.UInt64> (SUBE x y (Select1 <types.TypeFlags> (SUBC (MOVDconst [0]) c))))
+(Select1 (Sub64borrow x y c))
+  => (NEG (Select0 <typ.UInt64> (SUBE (MOVDconst [0]) (MOVDconst [0]) (Select1 <types.TypeFlags> (SUBE x y (Select1 <types.TypeFlags> (SUBC (MOVDconst [0]) c)))))))
+
+// math package intrinsics
+(Sqrt      ...) => (FSQRT ...)
+(Floor       x) => (FIDBR [7] x)
+(Ceil        x) => (FIDBR [6] x)
+(Trunc       x) => (FIDBR [5] x)
+(RoundToEven x) => (FIDBR [4] x)
+(Round       x) => (FIDBR [1] x)
+(FMA     x y z) => (FMADD z x y)
+
+(Sqrt32    ...) => (FSQRTS ...)
+
+// Atomic loads and stores.
+// The SYNC instruction (fast-BCR-serialization) prevents store-load
+// reordering. Other sequences of memory operations (load-load,
+// store-store and load-store) are already guaranteed not to be reordered.
+(AtomicLoad(8|32|Acq32|64|Ptr) ptr mem) => (MOV(BZ|WZ|WZ|D|D)atomicload ptr mem)
+(AtomicStore(8|32|64|PtrNoWB) ptr val mem) => (SYNC (MOV(B|W|D|D)atomicstore ptr val mem))
+
+// Store-release doesn't require store-load ordering.
+(AtomicStoreRel32 ptr val mem) => (MOVWatomicstore ptr val mem)
+
+// Atomic adds.
+(AtomicAdd32 ptr val mem) => (AddTupleFirst32 val (LAA ptr val mem))
+(AtomicAdd64 ptr val mem) => (AddTupleFirst64 val (LAAG ptr val mem))
+(Select0 <t> (AddTupleFirst32 val tuple)) => (ADDW val (Select0 <t> tuple))
+(Select1     (AddTupleFirst32   _ tuple)) => (Select1 tuple)
+(Select0 <t> (AddTupleFirst64 val tuple)) => (ADD val (Select0 <t> tuple))
+(Select1     (AddTupleFirst64   _ tuple)) => (Select1 tuple)
+
+// Atomic exchanges.
+(AtomicExchange32 ptr val mem) => (LoweredAtomicExchange32 ptr val mem)
+(AtomicExchange64 ptr val mem) => (LoweredAtomicExchange64 ptr val mem)
+
+// Atomic compare and swap.
+(AtomicCompareAndSwap32 ptr old new_ mem) => (LoweredAtomicCas32 ptr old new_ mem)
+(AtomicCompareAndSwap64 ptr old new_ mem) => (LoweredAtomicCas64 ptr old new_ mem)
+
+// Atomic and: *(*uint8)(ptr) &= val
+//
+// Round pointer down to nearest word boundary and pad value with ones before
+// applying atomic AND operation to target word.
+//
+// *(*uint32)(ptr &^ 3) &= rotateleft(uint32(val) | 0xffffff00, ((3 << 3) ^ ((ptr & 3) << 3))
+//
+(AtomicAnd8 ptr val mem)
+  => (LANfloor
+       ptr
+       (RLL <typ.UInt32>
+         (ORWconst <typ.UInt32> val [-1<<8])
+         (RXSBG <typ.UInt32> {s390x.NewRotateParams(59, 60, 3)} (MOVDconst [3<<3]) ptr))
+       mem)
+
+// Atomic or: *(*uint8)(ptr) |= val
+//
+// Round pointer down to nearest word boundary and pad value with zeros before
+// applying atomic OR operation to target word.
+//
+// *(*uint32)(ptr &^ 3) |= uint32(val) << ((3 << 3) ^ ((ptr & 3) << 3))
+//
+(AtomicOr8  ptr val mem)
+  => (LAOfloor
+       ptr
+       (SLW <typ.UInt32>
+         (MOVBZreg <typ.UInt32> val)
+         (RXSBG <typ.UInt32> {s390x.NewRotateParams(59, 60, 3)} (MOVDconst [3<<3]) ptr))
+       mem)
+
+(AtomicAnd32 ...) => (LAN ...)
+(AtomicOr32  ...) => (LAO ...)
+
+// Lowering extension
+// Note: we always extend to 64 bits even though some ops don't need that many result bits.
+(SignExt8to(16|32|64) ...) => (MOVBreg ...)
+(SignExt16to(32|64) ...) => (MOVHreg ...)
+(SignExt32to64 ...) => (MOVWreg ...)
+
+(ZeroExt8to(16|32|64) ...) => (MOVBZreg ...)
+(ZeroExt16to(32|64) ...) => (MOVHZreg ...)
+(ZeroExt32to64 ...) => (MOVWZreg ...)
+
+(Slicemask <t> x) => (SRADconst (NEG <t> x) [63])
+
+// Lowering truncation
+// Because we ignore high parts of registers, truncates are just copies.
+(Trunc(16|32|64)to8 ...) => (Copy ...)
+(Trunc(32|64)to16 ...) => (Copy ...)
+(Trunc64to32 ...) => (Copy ...)
+
+// Lowering float <-> int
+(Cvt32to32F ...) => (CEFBRA ...)
+(Cvt32to64F ...) => (CDFBRA ...)
+(Cvt64to32F ...) => (CEGBRA ...)
+(Cvt64to64F ...) => (CDGBRA ...)
+
+(Cvt32Fto32 ...) => (CFEBRA ...)
+(Cvt32Fto64 ...) => (CGEBRA ...)
+(Cvt64Fto32 ...) => (CFDBRA ...)
+(Cvt64Fto64 ...) => (CGDBRA ...)
+
+// Lowering float <-> uint
+(Cvt32Uto32F ...) => (CELFBR ...)
+(Cvt32Uto64F ...) => (CDLFBR ...)
+(Cvt64Uto32F ...) => (CELGBR ...)
+(Cvt64Uto64F ...) => (CDLGBR ...)
+
+(Cvt32Fto32U ...) => (CLFEBR ...)
+(Cvt32Fto64U ...) => (CLGEBR ...)
+(Cvt64Fto32U ...) => (CLFDBR ...)
+(Cvt64Fto64U ...) => (CLGDBR ...)
+
+// Lowering float32 <-> float64
+(Cvt32Fto64F ...) => (LDEBR ...)
+(Cvt64Fto32F ...) => (LEDBR ...)
+
+(CvtBoolToUint8 ...) => (Copy ...)
+
+(Round(32|64)F ...) => (LoweredRound(32|64)F ...)
+
+// Lowering shifts
+
+// Lower bounded shifts first. No need to check shift value.
+(Lsh64x(64|32|16|8)  x y) && shiftIsBounded(v) => (SLD x y)
+(Lsh32x(64|32|16|8)  x y) && shiftIsBounded(v) => (SLW x y)
+(Lsh16x(64|32|16|8)  x y) && shiftIsBounded(v) => (SLW x y)
+(Lsh8x(64|32|16|8)   x y) && shiftIsBounded(v) => (SLW x y)
+(Rsh64Ux(64|32|16|8) x y) && shiftIsBounded(v) => (SRD x y)
+(Rsh32Ux(64|32|16|8) x y) && shiftIsBounded(v) => (SRW x y)
+(Rsh16Ux(64|32|16|8) x y) && shiftIsBounded(v) => (SRW (MOVHZreg x) y)
+(Rsh8Ux(64|32|16|8)  x y) && shiftIsBounded(v) => (SRW (MOVBZreg x) y)
+(Rsh64x(64|32|16|8)  x y) && shiftIsBounded(v) => (SRAD x y)
+(Rsh32x(64|32|16|8)  x y) && shiftIsBounded(v) => (SRAW x y)
+(Rsh16x(64|32|16|8)  x y) && shiftIsBounded(v) => (SRAW (MOVHreg x) y)
+(Rsh8x(64|32|16|8)   x y) && shiftIsBounded(v) => (SRAW (MOVBreg x) y)
+
+// Unsigned shifts need to return 0 if shift amount is >= width of shifted value.
+//   result = shift >= 64 ? 0 : arg << shift
+(Lsh(64|32|16|8)x64 <t> x y) => (LOCGR {s390x.GreaterOrEqual} <t> (SL(D|W|W|W) <t> x y) (MOVDconst [0]) (CMPUconst y [64]))
+(Lsh(64|32|16|8)x32 <t> x y) => (LOCGR {s390x.GreaterOrEqual} <t> (SL(D|W|W|W) <t> x y) (MOVDconst [0]) (CMPWUconst y [64]))
+(Lsh(64|32|16|8)x16 <t> x y) => (LOCGR {s390x.GreaterOrEqual} <t> (SL(D|W|W|W) <t> x y) (MOVDconst [0]) (CMPWUconst (MOVHZreg y) [64]))
+(Lsh(64|32|16|8)x8  <t> x y) => (LOCGR {s390x.GreaterOrEqual} <t> (SL(D|W|W|W) <t> x y) (MOVDconst [0]) (CMPWUconst (MOVBZreg y) [64]))
+
+(Rsh(64|32)Ux64 <t> x y) => (LOCGR {s390x.GreaterOrEqual} <t> (SR(D|W) <t> x y) (MOVDconst [0]) (CMPUconst y [64]))
+(Rsh(64|32)Ux32 <t> x y) => (LOCGR {s390x.GreaterOrEqual} <t> (SR(D|W) <t> x y) (MOVDconst [0]) (CMPWUconst y [64]))
+(Rsh(64|32)Ux16 <t> x y) => (LOCGR {s390x.GreaterOrEqual} <t> (SR(D|W) <t> x y) (MOVDconst [0]) (CMPWUconst (MOVHZreg y) [64]))
+(Rsh(64|32)Ux8  <t> x y) => (LOCGR {s390x.GreaterOrEqual} <t> (SR(D|W) <t> x y) (MOVDconst [0]) (CMPWUconst (MOVBZreg y) [64]))
+
+(Rsh(16|8)Ux64 <t> x y) => (LOCGR {s390x.GreaterOrEqual} <t> (SRW <t> (MOV(H|B)Zreg x) y) (MOVDconst [0]) (CMPUconst y [64]))
+(Rsh(16|8)Ux32 <t> x y) => (LOCGR {s390x.GreaterOrEqual} <t> (SRW <t> (MOV(H|B)Zreg x) y) (MOVDconst [0]) (CMPWUconst y [64]))
+(Rsh(16|8)Ux16 <t> x y) => (LOCGR {s390x.GreaterOrEqual} <t> (SRW <t> (MOV(H|B)Zreg x) y) (MOVDconst [0]) (CMPWUconst (MOVHZreg y) [64]))
+(Rsh(16|8)Ux8  <t> x y) => (LOCGR {s390x.GreaterOrEqual} <t> (SRW <t> (MOV(H|B)Zreg x) y) (MOVDconst [0]) (CMPWUconst (MOVBZreg y) [64]))
+
+// Signed right shift needs to return 0/-1 if shift amount is >= width of shifted value.
+// We implement this by setting the shift value to 63 (all ones) if the shift value is more than 63.
+//   result = arg >> (shift >= 64 ? 63 : shift)
+(Rsh(64|32)x64 x y) => (SRA(D|W) x (LOCGR {s390x.GreaterOrEqual} <y.Type> y (MOVDconst <y.Type> [63]) (CMPUconst  y [64])))
+(Rsh(64|32)x32 x y) => (SRA(D|W) x (LOCGR {s390x.GreaterOrEqual} <y.Type> y (MOVDconst <y.Type> [63]) (CMPWUconst y [64])))
+(Rsh(64|32)x16 x y) => (SRA(D|W) x (LOCGR {s390x.GreaterOrEqual} <y.Type> y (MOVDconst <y.Type> [63]) (CMPWUconst (MOVHZreg y) [64])))
+(Rsh(64|32)x8  x y) => (SRA(D|W) x (LOCGR {s390x.GreaterOrEqual} <y.Type> y (MOVDconst <y.Type> [63]) (CMPWUconst (MOVBZreg y) [64])))
+
+(Rsh(16|8)x64 x y) => (SRAW (MOV(H|B)reg x) (LOCGR {s390x.GreaterOrEqual} <y.Type> y (MOVDconst <y.Type> [63]) (CMPUconst  y [64])))
+(Rsh(16|8)x32 x y) => (SRAW (MOV(H|B)reg x) (LOCGR {s390x.GreaterOrEqual} <y.Type> y (MOVDconst <y.Type> [63]) (CMPWUconst y [64])))
+(Rsh(16|8)x16 x y) => (SRAW (MOV(H|B)reg x) (LOCGR {s390x.GreaterOrEqual} <y.Type> y (MOVDconst <y.Type> [63]) (CMPWUconst (MOVHZreg y) [64])))
+(Rsh(16|8)x8  x y) => (SRAW (MOV(H|B)reg x) (LOCGR {s390x.GreaterOrEqual} <y.Type> y (MOVDconst <y.Type> [63]) (CMPWUconst (MOVBZreg y) [64])))
+
+// Lowering rotates
+(RotateLeft8 <t> x (MOVDconst [c])) => (Or8 (Lsh8x64 <t> x (MOVDconst [c&7])) (Rsh8Ux64 <t> x (MOVDconst [-c&7])))
+(RotateLeft16 <t> x (MOVDconst [c])) => (Or16 (Lsh16x64 <t> x (MOVDconst [c&15])) (Rsh16Ux64 <t> x (MOVDconst [-c&15])))
+(RotateLeft32 ...) => (RLL  ...)
+(RotateLeft64 ...) => (RLLG ...)
+
+// Lowering comparisons
+(Less64      x y) => (LOCGR {s390x.Less} (MOVDconst [0]) (MOVDconst [1]) (CMP x y))
+(Less32      x y) => (LOCGR {s390x.Less} (MOVDconst [0]) (MOVDconst [1]) (CMPW x y))
+(Less(16|8)  x y) => (LOCGR {s390x.Less} (MOVDconst [0]) (MOVDconst [1]) (CMPW (MOV(H|B)reg x) (MOV(H|B)reg y)))
+(Less64U     x y) => (LOCGR {s390x.Less} (MOVDconst [0]) (MOVDconst [1]) (CMPU x y))
+(Less32U     x y) => (LOCGR {s390x.Less} (MOVDconst [0]) (MOVDconst [1]) (CMPWU x y))
+(Less(16|8)U x y) => (LOCGR {s390x.Less} (MOVDconst [0]) (MOVDconst [1]) (CMPWU (MOV(H|B)Zreg x) (MOV(H|B)Zreg y)))
+(Less64F     x y) => (LOCGR {s390x.Less} (MOVDconst [0]) (MOVDconst [1]) (FCMP x y))
+(Less32F     x y) => (LOCGR {s390x.Less} (MOVDconst [0]) (MOVDconst [1]) (FCMPS x y))
+
+(Leq64      x y) => (LOCGR {s390x.LessOrEqual} (MOVDconst [0]) (MOVDconst [1]) (CMP x y))
+(Leq32      x y) => (LOCGR {s390x.LessOrEqual} (MOVDconst [0]) (MOVDconst [1]) (CMPW x y))
+(Leq(16|8)  x y) => (LOCGR {s390x.LessOrEqual} (MOVDconst [0]) (MOVDconst [1]) (CMPW (MOV(H|B)reg x) (MOV(H|B)reg y)))
+(Leq64U     x y) => (LOCGR {s390x.LessOrEqual} (MOVDconst [0]) (MOVDconst [1]) (CMPU x y))
+(Leq32U     x y) => (LOCGR {s390x.LessOrEqual} (MOVDconst [0]) (MOVDconst [1]) (CMPWU x y))
+(Leq(16|8)U x y) => (LOCGR {s390x.LessOrEqual} (MOVDconst [0]) (MOVDconst [1]) (CMPWU (MOV(H|B)Zreg x) (MOV(H|B)Zreg y)))
+(Leq64F     x y) => (LOCGR {s390x.LessOrEqual} (MOVDconst [0]) (MOVDconst [1]) (FCMP x y))
+(Leq32F     x y) => (LOCGR {s390x.LessOrEqual} (MOVDconst [0]) (MOVDconst [1]) (FCMPS x y))
+
+(Eq(64|Ptr) x y) => (LOCGR {s390x.Equal} (MOVDconst [0]) (MOVDconst [1]) (CMP x y))
+(Eq32       x y) => (LOCGR {s390x.Equal} (MOVDconst [0]) (MOVDconst [1]) (CMPW x y))
+(Eq(16|8|B) x y) => (LOCGR {s390x.Equal} (MOVDconst [0]) (MOVDconst [1]) (CMPW (MOV(H|B|B)reg x) (MOV(H|B|B)reg y)))
+(Eq64F      x y) => (LOCGR {s390x.Equal} (MOVDconst [0]) (MOVDconst [1]) (FCMP x y))
+(Eq32F      x y) => (LOCGR {s390x.Equal} (MOVDconst [0]) (MOVDconst [1]) (FCMPS x y))
+
+(Neq(64|Ptr) x y) => (LOCGR {s390x.NotEqual} (MOVDconst [0]) (MOVDconst [1]) (CMP x y))
+(Neq32       x y) => (LOCGR {s390x.NotEqual} (MOVDconst [0]) (MOVDconst [1]) (CMPW x y))
+(Neq(16|8|B) x y) => (LOCGR {s390x.NotEqual} (MOVDconst [0]) (MOVDconst [1]) (CMPW (MOV(H|B|B)reg x) (MOV(H|B|B)reg y)))
+(Neq64F      x y) => (LOCGR {s390x.NotEqual} (MOVDconst [0]) (MOVDconst [1]) (FCMP x y))
+(Neq32F      x y) => (LOCGR {s390x.NotEqual} (MOVDconst [0]) (MOVDconst [1]) (FCMPS x y))
+
+// Lowering loads
+(Load <t> ptr mem) && (is64BitInt(t) || isPtr(t)) => (MOVDload ptr mem)
+(Load <t> ptr mem) && is32BitInt(t) && isSigned(t) => (MOVWload ptr mem)
+(Load <t> ptr mem) && is32BitInt(t) && !isSigned(t) => (MOVWZload ptr mem)
+(Load <t> ptr mem) && is16BitInt(t) && isSigned(t) => (MOVHload ptr mem)
+(Load <t> ptr mem) && is16BitInt(t) && !isSigned(t) => (MOVHZload ptr mem)
+(Load <t> ptr mem) && is8BitInt(t) && isSigned(t) => (MOVBload ptr mem)
+(Load <t> ptr mem) && (t.IsBoolean() || (is8BitInt(t) && !isSigned(t))) => (MOVBZload ptr mem)
+(Load <t> ptr mem) && is32BitFloat(t) => (FMOVSload ptr mem)
+(Load <t> ptr mem) && is64BitFloat(t) => (FMOVDload ptr mem)
+
+// Lowering stores
+// These more-specific FP versions of Store pattern should come first.
+(Store {t} ptr val mem) && t.Size() == 8 && is64BitFloat(val.Type) => (FMOVDstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 4 && is32BitFloat(val.Type) => (FMOVSstore ptr val mem)
+
+(Store {t} ptr val mem) && t.Size() == 8 => (MOVDstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 4 => (MOVWstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 2 => (MOVHstore ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 1 => (MOVBstore ptr val mem)
+
+// Lowering moves
+
+// Load and store for small copies.
+(Move [0] _ _ mem) => mem
+(Move [1] dst src mem) => (MOVBstore dst (MOVBZload src mem) mem)
+(Move [2] dst src mem) => (MOVHstore dst (MOVHZload src mem) mem)
+(Move [4] dst src mem) => (MOVWstore dst (MOVWZload src mem) mem)
+(Move [8] dst src mem) => (MOVDstore dst (MOVDload src mem) mem)
+(Move [16] dst src mem) =>
+	(MOVDstore [8] dst (MOVDload [8] src mem)
+		(MOVDstore dst (MOVDload src mem) mem))
+(Move [24] dst src mem) =>
+        (MOVDstore [16] dst (MOVDload [16] src mem)
+	        (MOVDstore [8] dst (MOVDload [8] src mem)
+                (MOVDstore dst (MOVDload src mem) mem)))
+(Move [3] dst src mem) =>
+	(MOVBstore [2] dst (MOVBZload [2] src mem)
+		(MOVHstore dst (MOVHZload src mem) mem))
+(Move [5] dst src mem) =>
+	(MOVBstore [4] dst (MOVBZload [4] src mem)
+		(MOVWstore dst (MOVWZload src mem) mem))
+(Move [6] dst src mem) =>
+	(MOVHstore [4] dst (MOVHZload [4] src mem)
+		(MOVWstore dst (MOVWZload src mem) mem))
+(Move [7] dst src mem) =>
+	(MOVBstore [6] dst (MOVBZload [6] src mem)
+		(MOVHstore [4] dst (MOVHZload [4] src mem)
+			(MOVWstore dst (MOVWZload src mem) mem)))
+
+// MVC for other moves. Use up to 4 instructions (sizes up to 1024 bytes).
+(Move [s] dst src mem) && s > 0 && s <= 256 && logLargeCopy(v, s) =>
+	(MVC [makeValAndOff(int32(s), 0)] dst src mem)
+(Move [s] dst src mem) && s > 256 && s <= 512 && logLargeCopy(v, s) =>
+	(MVC [makeValAndOff(int32(s)-256, 256)] dst src (MVC [makeValAndOff(256, 0)] dst src mem))
+(Move [s] dst src mem) && s > 512 && s <= 768 && logLargeCopy(v, s) =>
+	(MVC [makeValAndOff(int32(s)-512, 512)] dst src (MVC [makeValAndOff(256, 256)] dst src (MVC [makeValAndOff(256, 0)] dst src mem)))
+(Move [s] dst src mem) && s > 768 && s <= 1024 && logLargeCopy(v, s) =>
+	(MVC [makeValAndOff(int32(s)-768, 768)] dst src (MVC [makeValAndOff(256, 512)] dst src (MVC [makeValAndOff(256, 256)] dst src (MVC [makeValAndOff(256, 0)] dst src mem))))
+
+// Move more than 1024 bytes using a loop.
+(Move [s] dst src mem) && s > 1024 && logLargeCopy(v, s) =>
+	(LoweredMove [s%256] dst src (ADD <src.Type> src (MOVDconst [(s/256)*256])) mem)
+
+// Lowering Zero instructions
+(Zero [0] _ mem) => mem
+(Zero [1] destptr mem) => (MOVBstoreconst [0] destptr mem)
+(Zero [2] destptr mem) => (MOVHstoreconst [0] destptr mem)
+(Zero [4] destptr mem) => (MOVWstoreconst [0] destptr mem)
+(Zero [8] destptr mem) => (MOVDstoreconst [0] destptr mem)
+(Zero [3] destptr mem) =>
+	(MOVBstoreconst [makeValAndOff(0,2)] destptr
+		(MOVHstoreconst [0] destptr mem))
+(Zero [5] destptr mem) =>
+	(MOVBstoreconst [makeValAndOff(0,4)] destptr
+		(MOVWstoreconst [0] destptr mem))
+(Zero [6] destptr mem) =>
+	(MOVHstoreconst [makeValAndOff(0,4)] destptr
+		(MOVWstoreconst [0] destptr mem))
+(Zero [7] destptr mem) =>
+	(MOVWstoreconst [makeValAndOff(0,3)] destptr
+		(MOVWstoreconst [0] destptr mem))
+
+(Zero [s] destptr mem) && s > 0 && s <= 1024 =>
+	(CLEAR [makeValAndOff(int32(s), 0)] destptr mem)
+
+// Zero more than 1024 bytes using a loop.
+(Zero [s] destptr mem) && s > 1024 =>
+	(LoweredZero [s%256] destptr (ADDconst <destptr.Type> destptr [(int32(s)/256)*256]) mem)
+
+// Lowering constants
+(Const(64|32|16|8) [val]) => (MOVDconst [int64(val)])
+(Const(32|64)F ...) => (FMOV(S|D)const ...)
+(ConstNil) => (MOVDconst [0])
+(ConstBool [t]) => (MOVDconst [b2i(t)])
+
+// Lowering calls
+(StaticCall ...) => (CALLstatic ...)
+(ClosureCall ...) => (CALLclosure ...)
+(InterCall ...) => (CALLinter ...)
+(TailCall ...) => (CALLtail ...)
+
+// Miscellaneous
+(IsNonNil p) => (LOCGR {s390x.NotEqual} (MOVDconst [0]) (MOVDconst [1]) (CMPconst p [0]))
+(IsInBounds idx len) => (LOCGR {s390x.Less} (MOVDconst [0]) (MOVDconst [1]) (CMPU idx len))
+(IsSliceInBounds idx len) => (LOCGR {s390x.LessOrEqual} (MOVDconst [0]) (MOVDconst [1]) (CMPU idx len))
+(NilCheck ...) => (LoweredNilCheck ...)
+(GetG ...) => (LoweredGetG ...)
+(GetClosurePtr ...) => (LoweredGetClosurePtr ...)
+(GetCallerSP ...) => (LoweredGetCallerSP ...)
+(GetCallerPC ...) => (LoweredGetCallerPC ...)
+(Addr {sym} base) => (MOVDaddr {sym} base)
+(LocalAddr {sym} base _) => (MOVDaddr {sym} base)
+(ITab (Load ptr mem)) => (MOVDload ptr mem)
+
+// block rewrites
+(If cond yes no) => (CLIJ {s390x.LessOrGreater} (MOVBZreg <typ.Bool> cond) [0] yes no)
+
+// Write barrier.
+(WB ...) => (LoweredWB ...)
+
+(PanicBounds [kind] x y mem) && boundsABI(kind) == 0 => (LoweredPanicBoundsA [kind] x y mem)
+(PanicBounds [kind] x y mem) && boundsABI(kind) == 1 => (LoweredPanicBoundsB [kind] x y mem)
+(PanicBounds [kind] x y mem) && boundsABI(kind) == 2 => (LoweredPanicBoundsC [kind] x y mem)
+
+// ***************************
+// Above: lowering rules
+// Below: optimizations
+// ***************************
+// TODO: Should the optimizations be a separate pass?
+
+// Note: when removing unnecessary sign/zero extensions.
+//
+// After a value is spilled it is restored using a sign- or zero-extension
+// to register-width as appropriate for its type. For example, a uint8 will
+// be restored using a MOVBZ (llgc) instruction which will zero extend the
+// 8-bit value to 64-bits.
+//
+// This is a hazard when folding sign- and zero-extensions since we need to
+// ensure not only that the value in the argument register is correctly
+// extended but also that it will still be correctly extended if it is
+// spilled and restored.
+//
+// In general this means we need type checks when the RHS of a rule is an
+// OpCopy (i.e. "(... x:(...) ...) -> x").
+
+// Merge double extensions.
+(MOV(H|HZ)reg e:(MOV(B|BZ)reg x)) && clobberIfDead(e) => (MOV(B|BZ)reg x)
+(MOV(W|WZ)reg e:(MOV(B|BZ)reg x)) && clobberIfDead(e) => (MOV(B|BZ)reg x)
+(MOV(W|WZ)reg e:(MOV(H|HZ)reg x)) && clobberIfDead(e) => (MOV(H|HZ)reg x)
+
+// Bypass redundant sign extensions.
+(MOV(B|BZ)reg e:(MOVBreg x)) && clobberIfDead(e) => (MOV(B|BZ)reg x)
+(MOV(B|BZ)reg e:(MOVHreg x)) && clobberIfDead(e) => (MOV(B|BZ)reg x)
+(MOV(B|BZ)reg e:(MOVWreg x)) && clobberIfDead(e) => (MOV(B|BZ)reg x)
+(MOV(H|HZ)reg e:(MOVHreg x)) && clobberIfDead(e) => (MOV(H|HZ)reg x)
+(MOV(H|HZ)reg e:(MOVWreg x)) && clobberIfDead(e) => (MOV(H|HZ)reg x)
+(MOV(W|WZ)reg e:(MOVWreg x)) && clobberIfDead(e) => (MOV(W|WZ)reg x)
+
+// Bypass redundant zero extensions.
+(MOV(B|BZ)reg e:(MOVBZreg x)) && clobberIfDead(e) => (MOV(B|BZ)reg x)
+(MOV(B|BZ)reg e:(MOVHZreg x)) && clobberIfDead(e) => (MOV(B|BZ)reg x)
+(MOV(B|BZ)reg e:(MOVWZreg x)) && clobberIfDead(e) => (MOV(B|BZ)reg x)
+(MOV(H|HZ)reg e:(MOVHZreg x)) && clobberIfDead(e) => (MOV(H|HZ)reg x)
+(MOV(H|HZ)reg e:(MOVWZreg x)) && clobberIfDead(e) => (MOV(H|HZ)reg x)
+(MOV(W|WZ)reg e:(MOVWZreg x)) && clobberIfDead(e) => (MOV(W|WZ)reg x)
+
+// Remove zero extensions after zero extending load.
+// Note: take care that if x is spilled it is restored correctly.
+(MOV(B|H|W)Zreg x:(MOVBZload    _   _)) && (!x.Type.IsSigned() || x.Type.Size() > 1) => x
+(MOV(H|W)Zreg   x:(MOVHZload    _   _)) && (!x.Type.IsSigned() || x.Type.Size() > 2) => x
+(MOVWZreg       x:(MOVWZload    _   _)) && (!x.Type.IsSigned() || x.Type.Size() > 4) => x
+
+// Remove sign extensions after sign extending load.
+// Note: take care that if x is spilled it is restored correctly.
+(MOV(B|H|W)reg x:(MOVBload    _   _)) && (x.Type.IsSigned() || x.Type.Size() == 8) => x
+(MOV(H|W)reg   x:(MOVHload    _   _)) && (x.Type.IsSigned() || x.Type.Size() == 8) => x
+(MOVWreg       x:(MOVWload    _   _)) && (x.Type.IsSigned() || x.Type.Size() == 8) => x
+
+// Remove sign extensions after zero extending load.
+// These type checks are probably unnecessary but do them anyway just in case.
+(MOV(H|W)reg x:(MOVBZload    _   _)) && (!x.Type.IsSigned() || x.Type.Size() > 1) => x
+(MOVWreg     x:(MOVHZload    _   _)) && (!x.Type.IsSigned() || x.Type.Size() > 2) => x
+
+// Fold sign and zero extensions into loads.
+//
+// Note: The combined instruction must end up in the same block
+// as the original load. If not, we end up making a value with
+// memory type live in two different blocks, which can lead to
+// multiple memory values alive simultaneously.
+//
+// Make sure we don't combine these ops if the load has another use.
+// This prevents a single load from being split into multiple loads
+// which then might return different values.  See test/atomicload.go.
+(MOV(B|H|W)Zreg <t> x:(MOV(B|H|W)load [o] {s} p mem))
+  && x.Uses == 1
+  && clobber(x)
+  => @x.Block (MOV(B|H|W)Zload <t> [o] {s} p mem)
+(MOV(B|H|W)reg <t> x:(MOV(B|H|W)Zload [o] {s} p mem))
+  && x.Uses == 1
+  && clobber(x)
+  => @x.Block (MOV(B|H|W)load <t> [o] {s} p mem)
+
+// Remove zero extensions after argument load.
+(MOVBZreg x:(Arg <t>)) && !t.IsSigned() && t.Size() == 1 => x
+(MOVHZreg x:(Arg <t>)) && !t.IsSigned() && t.Size() <= 2 => x
+(MOVWZreg x:(Arg <t>)) && !t.IsSigned() && t.Size() <= 4 => x
+
+// Remove sign extensions after argument load.
+(MOVBreg x:(Arg <t>)) && t.IsSigned() && t.Size() == 1 => x
+(MOVHreg x:(Arg <t>)) && t.IsSigned() && t.Size() <= 2 => x
+(MOVWreg x:(Arg <t>)) && t.IsSigned() && t.Size() <= 4 => x
+
+// Fold zero extensions into constants.
+(MOVBZreg (MOVDconst [c])) => (MOVDconst [int64( uint8(c))])
+(MOVHZreg (MOVDconst [c])) => (MOVDconst [int64(uint16(c))])
+(MOVWZreg (MOVDconst [c])) => (MOVDconst [int64(uint32(c))])
+
+// Fold sign extensions into constants.
+(MOVBreg (MOVDconst [c])) => (MOVDconst [int64( int8(c))])
+(MOVHreg (MOVDconst [c])) => (MOVDconst [int64(int16(c))])
+(MOVWreg (MOVDconst [c])) => (MOVDconst [int64(int32(c))])
+
+// Remove zero extension of conditional move.
+// Note: only for MOVBZreg for now since it is added as part of 'if' statement lowering.
+(MOVBZreg x:(LOCGR (MOVDconst [c]) (MOVDconst [d]) _))
+  && int64(uint8(c)) == c
+  && int64(uint8(d)) == d
+  && (!x.Type.IsSigned() || x.Type.Size() > 1)
+  => x
+
+// Fold boolean tests into blocks.
+// Note: this must match If statement lowering.
+(CLIJ {s390x.LessOrGreater} (LOCGR {d} (MOVDconst [0]) (MOVDconst [x]) cmp) [0] yes no)
+  && int32(x) != 0
+  => (BRC {d} cmp yes no)
+
+// Canonicalize BRC condition code mask by removing impossible conditions.
+// Integer comparisons cannot generate the unordered condition.
+(BRC {c} x:((CMP|CMPW|CMPU|CMPWU)    _ _) yes no) && c&s390x.Unordered != 0 => (BRC {c&^s390x.Unordered} x yes no)
+(BRC {c} x:((CMP|CMPW|CMPU|CMPWU)const _) yes no) && c&s390x.Unordered != 0 => (BRC {c&^s390x.Unordered} x yes no)
+
+// Compare-and-branch.
+// Note: bit 3 (unordered) must not be set so we mask out s390x.Unordered.
+(BRC {c} (CMP   x y) yes no) => (CGRJ  {c&^s390x.Unordered} x y yes no)
+(BRC {c} (CMPW  x y) yes no) => (CRJ   {c&^s390x.Unordered} x y yes no)
+(BRC {c} (CMPU  x y) yes no) => (CLGRJ {c&^s390x.Unordered} x y yes no)
+(BRC {c} (CMPWU x y) yes no) => (CLRJ  {c&^s390x.Unordered} x y yes no)
+
+// Compare-and-branch (immediate).
+// Note: bit 3 (unordered) must not be set so we mask out s390x.Unordered.
+(BRC {c} (CMPconst   x [y]) yes no) && y == int32( int8(y)) => (CGIJ  {c&^s390x.Unordered} x [ int8(y)] yes no)
+(BRC {c} (CMPWconst  x [y]) yes no) && y == int32( int8(y)) => (CIJ   {c&^s390x.Unordered} x [ int8(y)] yes no)
+(BRC {c} (CMPUconst  x [y]) yes no) && y == int32(uint8(y)) => (CLGIJ {c&^s390x.Unordered} x [uint8(y)] yes no)
+(BRC {c} (CMPWUconst x [y]) yes no) && y == int32(uint8(y)) => (CLIJ  {c&^s390x.Unordered} x [uint8(y)] yes no)
+
+// Absorb immediate into compare-and-branch.
+(C(R|GR)J  {c} x (MOVDconst [y]) yes no) && is8Bit(y)  => (C(I|GI)J  {c} x [ int8(y)] yes no)
+(CL(R|GR)J {c} x (MOVDconst [y]) yes no) && isU8Bit(y) => (CL(I|GI)J {c} x [uint8(y)] yes no)
+(C(R|GR)J  {c} (MOVDconst [x]) y yes no) && is8Bit(x)  => (C(I|GI)J  {c.ReverseComparison()} y [ int8(x)] yes no)
+(CL(R|GR)J {c} (MOVDconst [x]) y yes no) && isU8Bit(x) => (CL(I|GI)J {c.ReverseComparison()} y [uint8(x)] yes no)
+
+// Prefer comparison with immediate to compare-and-branch.
+(CGRJ  {c} x (MOVDconst [y]) yes no) && !is8Bit(y)  && is32Bit(y)  => (BRC {c} (CMPconst   x [int32(y)]) yes no)
+(CRJ   {c} x (MOVDconst [y]) yes no) && !is8Bit(y)  && is32Bit(y)  => (BRC {c} (CMPWconst  x [int32(y)]) yes no)
+(CLGRJ {c} x (MOVDconst [y]) yes no) && !isU8Bit(y) && isU32Bit(y) => (BRC {c} (CMPUconst  x [int32(y)]) yes no)
+(CLRJ  {c} x (MOVDconst [y]) yes no) && !isU8Bit(y) && isU32Bit(y) => (BRC {c} (CMPWUconst x [int32(y)]) yes no)
+(CGRJ  {c} (MOVDconst [x]) y yes no) && !is8Bit(x)  && is32Bit(x)  => (BRC {c.ReverseComparison()} (CMPconst   y [int32(x)]) yes no)
+(CRJ   {c} (MOVDconst [x]) y yes no) && !is8Bit(x)  && is32Bit(x)  => (BRC {c.ReverseComparison()} (CMPWconst  y [int32(x)]) yes no)
+(CLGRJ {c} (MOVDconst [x]) y yes no) && !isU8Bit(x) && isU32Bit(x) => (BRC {c.ReverseComparison()} (CMPUconst  y [int32(x)]) yes no)
+(CLRJ  {c} (MOVDconst [x]) y yes no) && !isU8Bit(x) && isU32Bit(x) => (BRC {c.ReverseComparison()} (CMPWUconst y [int32(x)]) yes no)
+
+// Absorb sign/zero extensions into 32-bit compare-and-branch.
+(CIJ  {c} (MOV(W|WZ)reg x) [y] yes no) => (CIJ  {c} x [y] yes no)
+(CLIJ {c} (MOV(W|WZ)reg x) [y] yes no) => (CLIJ {c} x [y] yes no)
+
+// Bring out-of-range signed immediates into range by varying branch condition.
+(BRC {s390x.Less}           (CMPconst  x [ 128]) yes no) => (CGIJ {s390x.LessOrEqual}    x [ 127] yes no)
+(BRC {s390x.Less}           (CMPWconst x [ 128]) yes no) => (CIJ  {s390x.LessOrEqual}    x [ 127] yes no)
+(BRC {s390x.LessOrEqual}    (CMPconst  x [-129]) yes no) => (CGIJ {s390x.Less}           x [-128] yes no)
+(BRC {s390x.LessOrEqual}    (CMPWconst x [-129]) yes no) => (CIJ  {s390x.Less}           x [-128] yes no)
+(BRC {s390x.Greater}        (CMPconst  x [-129]) yes no) => (CGIJ {s390x.GreaterOrEqual} x [-128] yes no)
+(BRC {s390x.Greater}        (CMPWconst x [-129]) yes no) => (CIJ  {s390x.GreaterOrEqual} x [-128] yes no)
+(BRC {s390x.GreaterOrEqual} (CMPconst  x [ 128]) yes no) => (CGIJ {s390x.Greater}        x [ 127] yes no)
+(BRC {s390x.GreaterOrEqual} (CMPWconst x [ 128]) yes no) => (CIJ  {s390x.Greater}        x [ 127] yes no)
+
+// Bring out-of-range unsigned immediates into range by varying branch condition.
+(BRC {s390x.Less}           (CMP(WU|U)const  x [256]) yes no) => (C(L|LG)IJ {s390x.LessOrEqual} x [255] yes no)
+(BRC {s390x.GreaterOrEqual} (CMP(WU|U)const  x [256]) yes no) => (C(L|LG)IJ {s390x.Greater}     x [255] yes no)
+
+// Bring out-of-range immediates into range by switching signedness (only == and !=).
+(BRC {c} (CMPconst   x [y]) yes no) && y == int32(uint8(y)) && (c == s390x.Equal || c == s390x.LessOrGreater) => (CLGIJ {c} x [uint8(y)] yes no)
+(BRC {c} (CMPWconst  x [y]) yes no) && y == int32(uint8(y)) && (c == s390x.Equal || c == s390x.LessOrGreater) => (CLIJ  {c} x [uint8(y)] yes no)
+(BRC {c} (CMPUconst  x [y]) yes no) && y == int32( int8(y)) && (c == s390x.Equal || c == s390x.LessOrGreater) => (CGIJ  {c} x [ int8(y)] yes no)
+(BRC {c} (CMPWUconst x [y]) yes no) && y == int32( int8(y)) && (c == s390x.Equal || c == s390x.LessOrGreater) => (CIJ   {c} x [ int8(y)] yes no)
+
+// Fold constants into instructions.
+(ADD x (MOVDconst [c])) && is32Bit(c) => (ADDconst [int32(c)] x)
+(ADDW x (MOVDconst [c])) => (ADDWconst [int32(c)] x)
+
+(SUB x (MOVDconst [c])) && is32Bit(c) => (SUBconst x [int32(c)])
+(SUB (MOVDconst [c]) x) && is32Bit(c) => (NEG (SUBconst <v.Type> x [int32(c)]))
+(SUBW x (MOVDconst [c])) => (SUBWconst x [int32(c)])
+(SUBW (MOVDconst [c]) x) => (NEGW (SUBWconst <v.Type> x [int32(c)]))
+
+(MULLD x (MOVDconst [c])) && is32Bit(c) => (MULLDconst [int32(c)] x)
+(MULLW x (MOVDconst [c])) => (MULLWconst [int32(c)] x)
+
+// NILF instructions leave the high 32 bits unchanged which is
+// equivalent to the leftmost 32 bits being set.
+// TODO(mundaym): modify the assembler to accept 64-bit values
+// and use isU32Bit(^c).
+(AND x (MOVDconst [c]))
+  && s390x.NewRotateParams(0, 63, 0).OutMerge(uint64(c)) != nil
+  => (RISBGZ x {*s390x.NewRotateParams(0, 63, 0).OutMerge(uint64(c))})
+(AND x (MOVDconst [c]))
+  && is32Bit(c)
+  && c < 0
+  => (ANDconst [c] x)
+(AND x (MOVDconst [c]))
+  && is32Bit(c)
+  && c >= 0
+  => (MOVWZreg (ANDWconst <typ.UInt32> [int32(c)] x))
+
+(ANDW x (MOVDconst [c])) => (ANDWconst [int32(c)] x)
+
+((AND|ANDW)const [c] ((AND|ANDW)const [d] x)) => ((AND|ANDW)const [c&d] x)
+
+((OR|XOR) x (MOVDconst [c])) && isU32Bit(c) => ((OR|XOR)const [c] x)
+((OR|XOR)W x (MOVDconst [c])) => ((OR|XOR)Wconst [int32(c)] x)
+
+// Constant shifts.
+(S(LD|RD|RAD) x (MOVDconst [c])) => (S(LD|RD|RAD)const x [uint8(c&63)])
+(S(LW|RW|RAW) x (MOVDconst [c])) && c&32 == 0 => (S(LW|RW|RAW)const x [uint8(c&31)])
+(S(LW|RW)     _ (MOVDconst [c])) && c&32 != 0 => (MOVDconst [0])
+(SRAW         x (MOVDconst [c])) && c&32 != 0 => (SRAWconst x [31])
+
+// Shifts only use the rightmost 6 bits of the shift value.
+(S(LD|RD|RAD|LW|RW|RAW) x (RISBGZ y {r}))
+  && r.Amount == 0
+  && r.OutMask()&63 == 63
+  => (S(LD|RD|RAD|LW|RW|RAW) x y)
+(S(LD|RD|RAD|LW|RW|RAW) x (AND (MOVDconst [c]) y))
+  => (S(LD|RD|RAD|LW|RW|RAW) x (ANDWconst <typ.UInt32> [int32(c&63)] y))
+(S(LD|RD|RAD|LW|RW|RAW) x (ANDWconst [c] y)) && c&63 == 63
+  => (S(LD|RD|RAD|LW|RW|RAW) x y)
+(SLD  x (MOV(W|H|B|WZ|HZ|BZ)reg y)) => (SLD  x y)
+(SRD  x (MOV(W|H|B|WZ|HZ|BZ)reg y)) => (SRD  x y)
+(SRAD x (MOV(W|H|B|WZ|HZ|BZ)reg y)) => (SRAD x y)
+(SLW  x (MOV(W|H|B|WZ|HZ|BZ)reg y)) => (SLW  x y)
+(SRW  x (MOV(W|H|B|WZ|HZ|BZ)reg y)) => (SRW  x y)
+(SRAW x (MOV(W|H|B|WZ|HZ|BZ)reg y)) => (SRAW x y)
+
+// Match rotate by constant.
+(RLLG x (MOVDconst [c])) => (RISBGZ x {s390x.NewRotateParams(0, 63, uint8(c&63))})
+(RLL  x (MOVDconst [c])) => (RLLconst x [uint8(c&31)])
+
+// Signed 64-bit comparison with immediate.
+(CMP x (MOVDconst [c])) && is32Bit(c) => (CMPconst x [int32(c)])
+(CMP (MOVDconst [c]) x) && is32Bit(c) => (InvertFlags (CMPconst x [int32(c)]))
+
+// Unsigned 64-bit comparison with immediate.
+(CMPU x (MOVDconst [c])) && isU32Bit(c) => (CMPUconst x [int32(c)])
+(CMPU (MOVDconst [c]) x) && isU32Bit(c) => (InvertFlags (CMPUconst x [int32(c)]))
+
+// Signed and unsigned 32-bit comparison with immediate.
+(CMP(W|WU) x (MOVDconst [c])) => (CMP(W|WU)const x [int32(c)])
+(CMP(W|WU) (MOVDconst [c]) x) => (InvertFlags (CMP(W|WU)const x [int32(c)]))
+
+// Match (x >> c) << d to 'rotate then insert selected bits [into zero]'.
+(SLDconst (SRDconst x [c]) [d]) => (RISBGZ x {s390x.NewRotateParams(uint8(max8(0, int8(c-d))), 63-d, uint8(int8(d-c)&63))})
+
+// Match (x << c) >> d to 'rotate then insert selected bits [into zero]'.
+(SRDconst (SLDconst x [c]) [d]) => (RISBGZ x {s390x.NewRotateParams(d, uint8(min8(63, int8(63-c+d))), uint8(int8(c-d)&63))})
+
+// Absorb input zero extension into 'rotate then insert selected bits [into zero]'.
+(RISBGZ (MOVWZreg x) {r}) && r.InMerge(0xffffffff) != nil => (RISBGZ x {*r.InMerge(0xffffffff)})
+(RISBGZ (MOVHZreg x) {r}) && r.InMerge(0x0000ffff) != nil => (RISBGZ x {*r.InMerge(0x0000ffff)})
+(RISBGZ (MOVBZreg x) {r}) && r.InMerge(0x000000ff) != nil => (RISBGZ x {*r.InMerge(0x000000ff)})
+
+// Absorb 'rotate then insert selected bits [into zero]' into zero extension.
+(MOVWZreg (RISBGZ x {r})) && r.OutMerge(0xffffffff) != nil => (RISBGZ x {*r.OutMerge(0xffffffff)})
+(MOVHZreg (RISBGZ x {r})) && r.OutMerge(0x0000ffff) != nil => (RISBGZ x {*r.OutMerge(0x0000ffff)})
+(MOVBZreg (RISBGZ x {r})) && r.OutMerge(0x000000ff) != nil => (RISBGZ x {*r.OutMerge(0x000000ff)})
+
+// Absorb shift into 'rotate then insert selected bits [into zero]'.
+//
+// Any unsigned shift can be represented as a rotate and mask operation:
+//
+//   x << c => RotateLeft64(x, c) & (^uint64(0) << c)
+//   x >> c => RotateLeft64(x, -c) & (^uint64(0) >> c)
+//
+// Therefore when a shift is used as the input to a rotate then insert
+// selected bits instruction we can merge the two together. We just have
+// to be careful that the resultant mask is representable (non-zero and
+// contiguous). For example, assuming that x is variable and c, y and m
+// are constants, a shift followed by a rotate then insert selected bits
+// could be represented as:
+//
+//   RotateLeft64(RotateLeft64(x, c) & (^uint64(0) << c), y) & m
+//
+// We can split the rotation by y into two, one rotate for x and one for
+// the mask:
+//
+//   RotateLeft64(RotateLeft64(x, c), y) & (RotateLeft64(^uint64(0) << c, y)) & m
+//
+// The rotations of x by c followed by y can then be combined:
+//
+//   RotateLeft64(x, c+y) & (RotateLeft64(^uint64(0) << c, y)) & m
+//   ^^^^^^^^^^^^^^^^^^^^   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//          rotate                          mask
+//
+// To perform this optimization we therefore just need to check that it
+// is valid to merge the shift mask (^(uint64(0)<<c)) into the selected
+// bits mask (i.e. that the resultant mask is non-zero and contiguous).
+//
+(RISBGZ (SLDconst x [c]) {r}) && r.InMerge(^uint64(0)<<c) != nil => (RISBGZ x {(*r.InMerge(^uint64(0)<<c)).RotateLeft(c)})
+(RISBGZ (SRDconst x [c]) {r}) && r.InMerge(^uint64(0)>>c) != nil => (RISBGZ x {(*r.InMerge(^uint64(0)>>c)).RotateLeft(-c)})
+
+// Absorb 'rotate then insert selected bits [into zero]' into left shift.
+(SLDconst (RISBGZ x {r}) [c])
+  && s390x.NewRotateParams(0, 63-c, c).InMerge(r.OutMask()) != nil
+  => (RISBGZ x {(*s390x.NewRotateParams(0, 63-c, c).InMerge(r.OutMask())).RotateLeft(r.Amount)})
+
+// Absorb 'rotate then insert selected bits [into zero]' into right shift.
+(SRDconst (RISBGZ x {r}) [c])
+  && s390x.NewRotateParams(c, 63, -c&63).InMerge(r.OutMask()) != nil
+  => (RISBGZ x {(*s390x.NewRotateParams(c, 63, -c&63).InMerge(r.OutMask())).RotateLeft(r.Amount)})
+
+// Merge 'rotate then insert selected bits [into zero]' instructions together.
+(RISBGZ (RISBGZ x {y}) {z})
+  && z.InMerge(y.OutMask()) != nil
+  => (RISBGZ x {(*z.InMerge(y.OutMask())).RotateLeft(y.Amount)})
+
+// Convert RISBGZ into 64-bit shift (helps CSE).
+(RISBGZ x {r}) && r.End == 63 && r.Start == -r.Amount&63 => (SRDconst x [-r.Amount&63])
+(RISBGZ x {r}) && r.Start == 0 && r.End == 63-r.Amount => (SLDconst x [r.Amount])
+
+// Optimize single bit isolation when it is known to be equivalent to
+// the most significant bit due to mask produced by arithmetic shift.
+// Simply isolate the most significant bit itself and place it in the
+// correct position.
+//
+// Example: (int64(x) >> 63) & 0x8 -> RISBGZ $60, $60, $4, Rsrc, Rdst
+(RISBGZ (SRADconst x [c]) {r})
+  && r.Start == r.End           // single bit selected
+  && (r.Start+r.Amount)&63 <= c // equivalent to most significant bit of x
+  => (RISBGZ x {s390x.NewRotateParams(r.Start, r.Start, -r.Start&63)})
+
+// Canonicalize the order of arguments to comparisons - helps with CSE.
+((CMP|CMPW|CMPU|CMPWU) x y) && canonLessThan(x,y) => (InvertFlags ((CMP|CMPW|CMPU|CMPWU) y x))
+
+// Use sign/zero extend instead of RISBGZ.
+(RISBGZ x {r}) && r == s390x.NewRotateParams(56, 63, 0) => (MOVBZreg x)
+(RISBGZ x {r}) && r == s390x.NewRotateParams(48, 63, 0) => (MOVHZreg x)
+(RISBGZ x {r}) && r == s390x.NewRotateParams(32, 63, 0) => (MOVWZreg x)
+
+// Use sign/zero extend instead of ANDW.
+(ANDWconst [0x00ff] x) => (MOVBZreg x)
+(ANDWconst [0xffff] x) => (MOVHZreg x)
+
+// Strength reduce multiplication to the sum (or difference) of two powers of two.
+//
+// Examples:
+//     5x -> 4x + 1x
+//    10x -> 8x + 2x
+//   120x -> 128x - 8x
+//  -120x -> 8x - 128x
+//
+// We know that the rightmost bit of any positive value, once isolated, must either
+// be a power of 2 (because it is a single bit) or 0 (if the original value is 0).
+// In all of these rules we use a rightmost bit calculation to determine one operand
+// for the addition or subtraction. We then just need to calculate if the other
+// operand is a valid power of 2 before we can match the rule.
+//
+// Notes:
+//   - the generic rules have already matched single powers of two so we ignore them here
+//   - isPowerOfTwo32 asserts that its argument is greater than 0
+//   - c&(c-1) = clear rightmost bit
+//   - c&^(c-1) = isolate rightmost bit
+
+// c = 2ˣ + 2ʸ => c - 2ˣ = 2ʸ
+(MULL(D|W)const <t> x [c]) && isPowerOfTwo32(c&(c-1))
+  => ((ADD|ADDW) (SL(D|W)const <t> x [uint8(log32(c&(c-1)))])
+                 (SL(D|W)const <t> x [uint8(log32(c&^(c-1)))]))
+
+// c = 2ʸ - 2ˣ => c + 2ˣ = 2ʸ
+(MULL(D|W)const <t> x [c]) && isPowerOfTwo32(c+(c&^(c-1)))
+  => ((SUB|SUBW) (SL(D|W)const <t> x [uint8(log32(c+(c&^(c-1))))])
+                 (SL(D|W)const <t> x [uint8(log32(c&^(c-1)))]))
+
+// c = 2ˣ - 2ʸ => -c + 2ˣ = 2ʸ
+(MULL(D|W)const <t> x [c]) && isPowerOfTwo32(-c+(-c&^(-c-1)))
+  => ((SUB|SUBW) (SL(D|W)const <t> x [uint8(log32(-c&^(-c-1)))])
+                 (SL(D|W)const <t> x [uint8(log32(-c+(-c&^(-c-1))))]))
+
+// Fold ADD into MOVDaddr. Odd offsets from SB shouldn't be folded (LARL can't handle them).
+(ADDconst [c] (MOVDaddr [d] {s} x:(SB))) && ((c+d)&1 == 0) && is32Bit(int64(c)+int64(d)) => (MOVDaddr [c+d] {s} x)
+(ADDconst [c] (MOVDaddr [d] {s} x)) && x.Op != OpSB && is20Bit(int64(c)+int64(d)) => (MOVDaddr [c+d] {s} x)
+(ADD idx (MOVDaddr [c] {s} ptr)) && ptr.Op != OpSB => (MOVDaddridx [c] {s} ptr idx)
+
+// fold ADDconst into MOVDaddrx
+(ADDconst [c] (MOVDaddridx [d] {s} x y)) && is20Bit(int64(c)+int64(d)) => (MOVDaddridx [c+d] {s} x y)
+(MOVDaddridx [c] {s} (ADDconst [d] x) y) && is20Bit(int64(c)+int64(d)) => (MOVDaddridx [c+d] {s} x y)
+(MOVDaddridx [c] {s} x (ADDconst [d] y)) && is20Bit(int64(c)+int64(d)) => (MOVDaddridx [c+d] {s} x y)
+
+// reverse ordering of compare instruction
+(LOCGR {c} x y (InvertFlags cmp)) => (LOCGR {c.ReverseComparison()} x y cmp)
+
+// replace load from same location as preceding store with copy
+(MOVDload  [off] {sym} ptr1 (MOVDstore  [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) => x
+(MOVWload  [off] {sym} ptr1 (MOVWstore  [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) => (MOVWreg x)
+(MOVHload  [off] {sym} ptr1 (MOVHstore  [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) => (MOVHreg x)
+(MOVBload  [off] {sym} ptr1 (MOVBstore  [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) => (MOVBreg x)
+(MOVWZload [off] {sym} ptr1 (MOVWstore  [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) => (MOVWZreg x)
+(MOVHZload [off] {sym} ptr1 (MOVHstore  [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) => (MOVHZreg x)
+(MOVBZload [off] {sym} ptr1 (MOVBstore  [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) => (MOVBZreg x)
+(MOVDload  [off] {sym} ptr1 (FMOVDstore [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) => (LGDR x)
+(FMOVDload [off] {sym} ptr1 (MOVDstore  [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) => (LDGR x)
+(FMOVDload [off] {sym} ptr1 (FMOVDstore [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) => x
+(FMOVSload [off] {sym} ptr1 (FMOVSstore [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) => x
+
+// prefer FPR <-> GPR moves over combined load ops
+(MULLDload <t> [off] {sym} x ptr1 (FMOVDstore [off] {sym} ptr2 y _)) && isSamePtr(ptr1, ptr2) => (MULLD x (LGDR <t> y))
+(ADDload   <t> [off] {sym} x ptr1 (FMOVDstore [off] {sym} ptr2 y _)) && isSamePtr(ptr1, ptr2) => (ADD   x (LGDR <t> y))
+(SUBload   <t> [off] {sym} x ptr1 (FMOVDstore [off] {sym} ptr2 y _)) && isSamePtr(ptr1, ptr2) => (SUB   x (LGDR <t> y))
+(ORload    <t> [off] {sym} x ptr1 (FMOVDstore [off] {sym} ptr2 y _)) && isSamePtr(ptr1, ptr2) => (OR    x (LGDR <t> y))
+(ANDload   <t> [off] {sym} x ptr1 (FMOVDstore [off] {sym} ptr2 y _)) && isSamePtr(ptr1, ptr2) => (AND   x (LGDR <t> y))
+(XORload   <t> [off] {sym} x ptr1 (FMOVDstore [off] {sym} ptr2 y _)) && isSamePtr(ptr1, ptr2) => (XOR   x (LGDR <t> y))
+
+// detect attempts to set/clear the sign bit
+// may need to be reworked when NIHH/OIHH are added
+(RISBGZ (LGDR <t> x) {r}) && r == s390x.NewRotateParams(1, 63, 0) => (LGDR <t> (LPDFR <x.Type> x))
+(LDGR <t> (RISBGZ x {r})) && r == s390x.NewRotateParams(1, 63, 0) => (LPDFR (LDGR <t> x))
+(OR (MOVDconst [-1<<63]) (LGDR <t> x)) => (LGDR <t> (LNDFR <x.Type> x))
+(LDGR <t> (OR (MOVDconst [-1<<63]) x)) => (LNDFR (LDGR <t> x))
+
+// detect attempts to set the sign bit with load
+(LDGR <t> x:(ORload <t1> [off] {sym} (MOVDconst [-1<<63]) ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (LNDFR <t> (LDGR <t> (MOVDload <t1> [off] {sym} ptr mem)))
+
+// detect copysign
+(OR (RISBGZ (LGDR x) {r}) (LGDR (LPDFR <t> y)))
+  && r == s390x.NewRotateParams(0, 0, 0)
+  => (LGDR (CPSDR <t> y x))
+(OR (RISBGZ (LGDR x) {r}) (MOVDconst [c]))
+  && c >= 0
+  && r == s390x.NewRotateParams(0, 0, 0)
+  => (LGDR (CPSDR <x.Type> (FMOVDconst <x.Type> [math.Float64frombits(uint64(c))]) x))
+(CPSDR y (FMOVDconst [c])) && !math.Signbit(c) => (LPDFR y)
+(CPSDR y (FMOVDconst [c])) && math.Signbit(c)  => (LNDFR y)
+
+// absorb negations into set/clear sign bit
+(FNEG  (LPDFR x)) => (LNDFR x)
+(FNEG  (LNDFR x)) => (LPDFR x)
+(FNEGS (LPDFR x)) => (LNDFR x)
+(FNEGS (LNDFR x)) => (LPDFR x)
+
+// no need to convert float32 to float64 to set/clear sign bit
+(LEDBR (LPDFR (LDEBR x))) => (LPDFR x)
+(LEDBR (LNDFR (LDEBR x))) => (LNDFR x)
+
+// remove unnecessary FPR <-> GPR moves
+(LDGR (LGDR x)) => x
+(LGDR (LDGR x)) => x
+
+// Don't extend before storing
+(MOVWstore [off] {sym} ptr (MOVWreg x) mem) => (MOVWstore [off] {sym} ptr x mem)
+(MOVHstore [off] {sym} ptr (MOVHreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr (MOVBreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
+(MOVWstore [off] {sym} ptr (MOVWZreg x) mem) => (MOVWstore [off] {sym} ptr x mem)
+(MOVHstore [off] {sym} ptr (MOVHZreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
+(MOVBstore [off] {sym} ptr (MOVBZreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
+
+// Fold constants into memory operations.
+// Note that this is not always a good idea because if not all the uses of
+// the ADDconst get eliminated, we still have to compute the ADDconst and we now
+// have potentially two live values (ptr and (ADDconst [off] ptr)) instead of one.
+// Nevertheless, let's do it!
+(MOVDload   [off1] {sym} (ADDconst [off2] ptr) mem) && is20Bit(int64(off1)+int64(off2)) => (MOVDload  [off1+off2] {sym} ptr mem)
+(MOVWload   [off1] {sym} (ADDconst [off2] ptr) mem) && is20Bit(int64(off1)+int64(off2)) => (MOVWload  [off1+off2] {sym} ptr mem)
+(MOVHload   [off1] {sym} (ADDconst [off2] ptr) mem) && is20Bit(int64(off1)+int64(off2)) => (MOVHload  [off1+off2] {sym} ptr mem)
+(MOVBload   [off1] {sym} (ADDconst [off2] ptr) mem) && is20Bit(int64(off1)+int64(off2)) => (MOVBload  [off1+off2] {sym} ptr mem)
+(MOVWZload  [off1] {sym} (ADDconst [off2] ptr) mem) && is20Bit(int64(off1)+int64(off2)) => (MOVWZload [off1+off2] {sym} ptr mem)
+(MOVHZload  [off1] {sym} (ADDconst [off2] ptr) mem) && is20Bit(int64(off1)+int64(off2)) => (MOVHZload [off1+off2] {sym} ptr mem)
+(MOVBZload  [off1] {sym} (ADDconst [off2] ptr) mem) && is20Bit(int64(off1)+int64(off2)) => (MOVBZload [off1+off2] {sym} ptr mem)
+(FMOVSload  [off1] {sym} (ADDconst [off2] ptr) mem) && is20Bit(int64(off1)+int64(off2)) => (FMOVSload [off1+off2] {sym} ptr mem)
+(FMOVDload  [off1] {sym} (ADDconst [off2] ptr) mem) && is20Bit(int64(off1)+int64(off2)) => (FMOVDload [off1+off2] {sym} ptr mem)
+
+(MOVDstore  [off1] {sym} (ADDconst [off2] ptr) val mem) && is20Bit(int64(off1)+int64(off2)) => (MOVDstore  [off1+off2] {sym} ptr val mem)
+(MOVWstore  [off1] {sym} (ADDconst [off2] ptr) val mem) && is20Bit(int64(off1)+int64(off2)) => (MOVWstore  [off1+off2] {sym} ptr val mem)
+(MOVHstore  [off1] {sym} (ADDconst [off2] ptr) val mem) && is20Bit(int64(off1)+int64(off2)) => (MOVHstore  [off1+off2] {sym} ptr val mem)
+(MOVBstore  [off1] {sym} (ADDconst [off2] ptr) val mem) && is20Bit(int64(off1)+int64(off2)) => (MOVBstore  [off1+off2] {sym} ptr val mem)
+(FMOVSstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is20Bit(int64(off1)+int64(off2)) => (FMOVSstore [off1+off2] {sym} ptr val mem)
+(FMOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is20Bit(int64(off1)+int64(off2)) => (FMOVDstore [off1+off2] {sym} ptr val mem)
+
+(ADDload   [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2)) => (ADDload   [off1+off2] {sym} x ptr mem)
+(ADDWload  [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2)) => (ADDWload  [off1+off2] {sym} x ptr mem)
+(MULLDload [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2)) => (MULLDload [off1+off2] {sym} x ptr mem)
+(MULLWload [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2)) => (MULLWload [off1+off2] {sym} x ptr mem)
+(SUBload   [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2)) => (SUBload   [off1+off2] {sym} x ptr mem)
+(SUBWload  [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2)) => (SUBWload  [off1+off2] {sym} x ptr mem)
+
+(ANDload   [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2)) => (ANDload   [off1+off2] {sym} x ptr mem)
+(ANDWload  [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2)) => (ANDWload  [off1+off2] {sym} x ptr mem)
+(ORload    [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2)) => (ORload    [off1+off2] {sym} x ptr mem)
+(ORWload   [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2)) => (ORWload   [off1+off2] {sym} x ptr mem)
+(XORload   [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2)) => (XORload   [off1+off2] {sym} x ptr mem)
+(XORWload  [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2)) => (XORWload  [off1+off2] {sym} x ptr mem)
+
+// Fold constants into stores.
+(MOVDstore [off] {sym} ptr (MOVDconst [c]) mem) && is16Bit(c) && isU12Bit(int64(off)) && ptr.Op != OpSB =>
+	(MOVDstoreconst [makeValAndOff(int32(c),off)] {sym} ptr mem)
+(MOVWstore [off] {sym} ptr (MOVDconst [c]) mem) && is16Bit(c) && isU12Bit(int64(off)) && ptr.Op != OpSB =>
+	(MOVWstoreconst [makeValAndOff(int32(c),off)] {sym} ptr mem)
+(MOVHstore [off] {sym} ptr (MOVDconst [c]) mem) && isU12Bit(int64(off)) && ptr.Op != OpSB =>
+	(MOVHstoreconst [makeValAndOff(int32(int16(c)),off)] {sym} ptr mem)
+(MOVBstore [off] {sym} ptr (MOVDconst [c]) mem) && is20Bit(int64(off)) && ptr.Op != OpSB =>
+	(MOVBstoreconst [makeValAndOff(int32(int8(c)),off)] {sym} ptr mem)
+
+// Fold address offsets into constant stores.
+(MOVDstoreconst [sc] {s} (ADDconst [off] ptr) mem) && isU12Bit(sc.Off64()+int64(off)) =>
+	(MOVDstoreconst [sc.addOffset32(off)] {s} ptr mem)
+(MOVWstoreconst [sc] {s} (ADDconst [off] ptr) mem) && isU12Bit(sc.Off64()+int64(off)) =>
+	(MOVWstoreconst [sc.addOffset32(off)] {s} ptr mem)
+(MOVHstoreconst [sc] {s} (ADDconst [off] ptr) mem) && isU12Bit(sc.Off64()+int64(off)) =>
+	(MOVHstoreconst [sc.addOffset32(off)] {s} ptr mem)
+(MOVBstoreconst [sc] {s} (ADDconst [off] ptr) mem) && is20Bit(sc.Off64()+int64(off)) =>
+	(MOVBstoreconst [sc.addOffset32(off)] {s} ptr mem)
+
+// Merge address calculations into loads and stores.
+// Offsets from SB must not be merged into unaligned memory accesses because
+// loads/stores using PC-relative addressing directly must be aligned to the
+// size of the target.
+(MOVDload   [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%8 == 0 && (off1+off2)%8 == 0)) =>
+	(MOVDload  [off1+off2] {mergeSym(sym1,sym2)} base mem)
+(MOVWZload  [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%4 == 0 && (off1+off2)%4 == 0)) =>
+	(MOVWZload  [off1+off2] {mergeSym(sym1,sym2)} base mem)
+(MOVHZload  [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%2 == 0 && (off1+off2)%2 == 0)) =>
+	(MOVHZload  [off1+off2] {mergeSym(sym1,sym2)} base mem)
+(MOVBZload  [off1] {sym1} (MOVDaddr [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+	(MOVBZload  [off1+off2] {mergeSym(sym1,sym2)} base mem)
+(FMOVSload [off1] {sym1} (MOVDaddr [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+	(FMOVSload [off1+off2] {mergeSym(sym1,sym2)} base mem)
+(FMOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+	(FMOVDload [off1+off2] {mergeSym(sym1,sym2)} base mem)
+
+(MOVWload [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%4 == 0 && (off1+off2)%4 == 0)) =>
+	(MOVWload [off1+off2] {mergeSym(sym1,sym2)} base mem)
+(MOVHload [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%2 == 0 && (off1+off2)%2 == 0)) =>
+	(MOVHload [off1+off2] {mergeSym(sym1,sym2)} base mem)
+(MOVBload [off1] {sym1} (MOVDaddr [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+	(MOVBload [off1+off2] {mergeSym(sym1,sym2)} base mem)
+
+(MOVDstore  [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) val mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%8 == 0 && (off1+off2)%8 == 0)) =>
+	(MOVDstore  [off1+off2] {mergeSym(sym1,sym2)} base val mem)
+(MOVWstore  [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) val mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%4 == 0 && (off1+off2)%4 == 0)) =>
+	(MOVWstore  [off1+off2] {mergeSym(sym1,sym2)} base val mem)
+(MOVHstore  [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) val mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%2 == 0 && (off1+off2)%2 == 0)) =>
+	(MOVHstore  [off1+off2] {mergeSym(sym1,sym2)} base val mem)
+(MOVBstore  [off1] {sym1} (MOVDaddr [off2] {sym2} base) val mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+	(MOVBstore  [off1+off2] {mergeSym(sym1,sym2)} base val mem)
+(FMOVSstore [off1] {sym1} (MOVDaddr [off2] {sym2} base) val mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+	(FMOVSstore [off1+off2] {mergeSym(sym1,sym2)} base val mem)
+(FMOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} base) val mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
+	(FMOVDstore [off1+off2] {mergeSym(sym1,sym2)} base val mem)
+
+(ADDload   [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (ADDload   [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+(ADDWload  [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (ADDWload  [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+(MULLDload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (MULLDload [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+(MULLWload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (MULLWload [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+(SUBload   [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (SUBload   [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+(SUBWload  [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (SUBWload  [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+
+(ANDload   [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (ANDload   [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+(ANDWload  [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (ANDWload  [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+(ORload    [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (ORload    [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+(ORWload   [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (ORWload   [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+(XORload   [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (XORload   [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+(XORWload  [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (XORWload  [o1+o2] {mergeSym(s1, s2)} x ptr mem)
+
+// Cannot store constant to SB directly (no 'move relative long immediate' instructions).
+(MOVDstoreconst [sc] {sym1} (MOVDaddr [off] {sym2} ptr) mem) && ptr.Op != OpSB && canMergeSym(sym1, sym2) && sc.canAdd32(off) =>
+	(MOVDstoreconst [sc.addOffset32(off)] {mergeSym(sym1, sym2)} ptr mem)
+(MOVWstoreconst [sc] {sym1} (MOVDaddr [off] {sym2} ptr) mem) && ptr.Op != OpSB && canMergeSym(sym1, sym2) && sc.canAdd32(off) =>
+	(MOVWstoreconst [sc.addOffset32(off)] {mergeSym(sym1, sym2)} ptr mem)
+(MOVHstoreconst [sc] {sym1} (MOVDaddr [off] {sym2} ptr) mem) && ptr.Op != OpSB && canMergeSym(sym1, sym2) && sc.canAdd32(off) =>
+	(MOVHstoreconst [sc.addOffset32(off)] {mergeSym(sym1, sym2)} ptr mem)
+(MOVBstoreconst [sc] {sym1} (MOVDaddr [off] {sym2} ptr) mem) && ptr.Op != OpSB && canMergeSym(sym1, sym2) && sc.canAdd32(off) =>
+	(MOVBstoreconst [sc.addOffset32(off)] {mergeSym(sym1, sym2)} ptr mem)
+
+// MOVDaddr into MOVDaddridx
+(MOVDaddridx [off1] {sym1} (MOVDaddr [off2] {sym2} x) y) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB =>
+       (MOVDaddridx [off1+off2] {mergeSym(sym1,sym2)} x y)
+(MOVDaddridx [off1] {sym1} x (MOVDaddr [off2] {sym2} y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && y.Op != OpSB =>
+       (MOVDaddridx [off1+off2] {mergeSym(sym1,sym2)} x y)
+
+// Absorb InvertFlags into branches.
+(BRC {c} (InvertFlags cmp) yes no) => (BRC {c.ReverseComparison()} cmp yes no)
+
+// Constant comparisons.
+(CMPconst (MOVDconst [x]) [y]) && x==int64(y) => (FlagEQ)
+(CMPconst (MOVDconst [x]) [y]) && x<int64(y) => (FlagLT)
+(CMPconst (MOVDconst [x]) [y]) && x>int64(y) => (FlagGT)
+(CMPUconst (MOVDconst [x]) [y]) && uint64(x)==uint64(y) => (FlagEQ)
+(CMPUconst (MOVDconst [x]) [y]) && uint64(x)<uint64(y) => (FlagLT)
+(CMPUconst (MOVDconst [x]) [y]) && uint64(x)>uint64(y) => (FlagGT)
+
+(CMPWconst (MOVDconst [x]) [y]) && int32(x)==int32(y) => (FlagEQ)
+(CMPWconst (MOVDconst [x]) [y]) && int32(x)<int32(y) => (FlagLT)
+(CMPWconst (MOVDconst [x]) [y]) && int32(x)>int32(y) => (FlagGT)
+(CMPWUconst (MOVDconst [x]) [y]) && uint32(x)==uint32(y) => (FlagEQ)
+(CMPWUconst (MOVDconst [x]) [y]) && uint32(x)<uint32(y) => (FlagLT)
+(CMPWUconst (MOVDconst [x]) [y]) && uint32(x)>uint32(y) => (FlagGT)
+
+(CMP(W|WU)const (MOVBZreg _) [c]) &&   0xff < c => (FlagLT)
+(CMP(W|WU)const (MOVHZreg _) [c]) && 0xffff < c => (FlagLT)
+
+(CMPconst  (SRDconst _ [c]) [n]) && c > 0 && n < 0 => (FlagGT)
+(CMPWconst (SRWconst _ [c]) [n]) && c > 0 && n < 0 => (FlagGT)
+
+(CMPUconst  (SRDconst _ [c]) [n]) && c > 0 && c < 64 && (1<<uint(64-c)) <= uint64(n) => (FlagLT)
+(CMPWUconst (SRWconst _ [c]) [n]) && c > 0 && c < 32 && (1<<uint(32-c)) <= uint32(n) => (FlagLT)
+
+(CMPWconst  (ANDWconst _ [m]) [n]) && int32(m) >= 0 &&  int32(m) <  int32(n) => (FlagLT)
+(CMPWUconst (ANDWconst _ [m]) [n]) && uint32(m) < uint32(n) => (FlagLT)
+
+(CMPconst  (RISBGZ x {r}) [c]) && c > 0 && r.OutMask() < uint64(c) => (FlagLT)
+(CMPUconst (RISBGZ x {r}) [c]) && r.OutMask() < uint64(uint32(c)) => (FlagLT)
+
+// Constant compare-and-branch with immediate.
+(CGIJ  {c} (MOVDconst [x]) [y] yes no) && c&s390x.Equal   != 0 &&  int64(x) ==  int64(y) => (First yes no)
+(CGIJ  {c} (MOVDconst [x]) [y] yes no) && c&s390x.Less    != 0 &&  int64(x) <   int64(y) => (First yes no)
+(CGIJ  {c} (MOVDconst [x]) [y] yes no) && c&s390x.Greater != 0 &&  int64(x) >   int64(y) => (First yes no)
+(CIJ   {c} (MOVDconst [x]) [y] yes no) && c&s390x.Equal   != 0 &&  int32(x) ==  int32(y) => (First yes no)
+(CIJ   {c} (MOVDconst [x]) [y] yes no) && c&s390x.Less    != 0 &&  int32(x) <   int32(y) => (First yes no)
+(CIJ   {c} (MOVDconst [x]) [y] yes no) && c&s390x.Greater != 0 &&  int32(x) >   int32(y) => (First yes no)
+(CLGIJ {c} (MOVDconst [x]) [y] yes no) && c&s390x.Equal   != 0 && uint64(x) == uint64(y) => (First yes no)
+(CLGIJ {c} (MOVDconst [x]) [y] yes no) && c&s390x.Less    != 0 && uint64(x) <  uint64(y) => (First yes no)
+(CLGIJ {c} (MOVDconst [x]) [y] yes no) && c&s390x.Greater != 0 && uint64(x) >  uint64(y) => (First yes no)
+(CLIJ  {c} (MOVDconst [x]) [y] yes no) && c&s390x.Equal   != 0 && uint32(x) == uint32(y) => (First yes no)
+(CLIJ  {c} (MOVDconst [x]) [y] yes no) && c&s390x.Less    != 0 && uint32(x) <  uint32(y) => (First yes no)
+(CLIJ  {c} (MOVDconst [x]) [y] yes no) && c&s390x.Greater != 0 && uint32(x) >  uint32(y) => (First yes no)
+(CGIJ  {c} (MOVDconst [x]) [y] yes no) && c&s390x.Equal   == 0 &&  int64(x) ==  int64(y) => (First no yes)
+(CGIJ  {c} (MOVDconst [x]) [y] yes no) && c&s390x.Less    == 0 &&  int64(x) <   int64(y) => (First no yes)
+(CGIJ  {c} (MOVDconst [x]) [y] yes no) && c&s390x.Greater == 0 &&  int64(x) >   int64(y) => (First no yes)
+(CIJ   {c} (MOVDconst [x]) [y] yes no) && c&s390x.Equal   == 0 &&  int32(x) ==  int32(y) => (First no yes)
+(CIJ   {c} (MOVDconst [x]) [y] yes no) && c&s390x.Less    == 0 &&  int32(x) <   int32(y) => (First no yes)
+(CIJ   {c} (MOVDconst [x]) [y] yes no) && c&s390x.Greater == 0 &&  int32(x) >   int32(y) => (First no yes)
+(CLGIJ {c} (MOVDconst [x]) [y] yes no) && c&s390x.Equal   == 0 && uint64(x) == uint64(y) => (First no yes)
+(CLGIJ {c} (MOVDconst [x]) [y] yes no) && c&s390x.Less    == 0 && uint64(x) <  uint64(y) => (First no yes)
+(CLGIJ {c} (MOVDconst [x]) [y] yes no) && c&s390x.Greater == 0 && uint64(x) >  uint64(y) => (First no yes)
+(CLIJ  {c} (MOVDconst [x]) [y] yes no) && c&s390x.Equal   == 0 && uint32(x) == uint32(y) => (First no yes)
+(CLIJ  {c} (MOVDconst [x]) [y] yes no) && c&s390x.Less    == 0 && uint32(x) <  uint32(y) => (First no yes)
+(CLIJ  {c} (MOVDconst [x]) [y] yes no) && c&s390x.Greater == 0 && uint32(x) >  uint32(y) => (First no yes)
+
+// Constant compare-and-branch with immediate when unsigned comparison with zero.
+(C(L|LG)IJ {s390x.GreaterOrEqual} _ [0] yes no) => (First yes no)
+(C(L|LG)IJ {s390x.Less}           _ [0] yes no) => (First no yes)
+
+// Constant compare-and-branch when operands match.
+(C(GR|R|LGR|LR)J {c} x y yes no) && x == y && c&s390x.Equal != 0 => (First yes no)
+(C(GR|R|LGR|LR)J {c} x y yes no) && x == y && c&s390x.Equal == 0 => (First no yes)
+
+// Convert 64-bit comparisons to 32-bit comparisons and signed comparisons
+// to unsigned comparisons.
+// Helps simplify constant comparison detection.
+(CM(P|PU)const (MOV(W|WZ)reg x) [c]) => (CMP(W|WU)const x [c])
+(CM(P|P|PU|PU)const x:(MOV(H|HZ|H|HZ)reg _) [c]) => (CMP(W|W|WU|WU)const x [c])
+(CM(P|P|PU|PU)const x:(MOV(B|BZ|B|BZ)reg _) [c]) => (CMP(W|W|WU|WU)const x [c])
+(CMPconst  (MOV(WZ|W)reg x:(ANDWconst [m] _)) [c]) && int32(m) >= 0 && c >= 0 => (CMPWUconst x [c])
+(CMPUconst (MOV(WZ|W)reg x:(ANDWconst [m] _)) [c]) && int32(m) >= 0           => (CMPWUconst x [c])
+(CMPconst  x:(SRDconst _ [c]) [n]) && c > 0 && n >= 0 => (CMPUconst  x [n])
+(CMPWconst x:(SRWconst _ [c]) [n]) && c > 0 && n >= 0 => (CMPWUconst x [n])
+
+// Absorb sign and zero extensions into 32-bit comparisons.
+(CMP(W|W|WU|WU)      x (MOV(W|WZ|W|WZ)reg y))   => (CMP(W|W|WU|WU) x y)
+(CMP(W|W|WU|WU)      (MOV(W|WZ|W|WZ)reg x) y)   => (CMP(W|W|WU|WU) x y)
+(CMP(W|W|WU|WU)const (MOV(W|WZ|W|WZ)reg x) [c]) => (CMP(W|W|WU|WU)const x [c])
+
+// Absorb flag constants into branches.
+(BRC {c} (FlagEQ) yes no) && c&s390x.Equal     != 0 => (First yes no)
+(BRC {c} (FlagLT) yes no) && c&s390x.Less      != 0 => (First yes no)
+(BRC {c} (FlagGT) yes no) && c&s390x.Greater   != 0 => (First yes no)
+(BRC {c} (FlagOV) yes no) && c&s390x.Unordered != 0 => (First yes no)
+
+(BRC {c} (FlagEQ) yes no) && c&s390x.Equal     == 0 => (First no yes)
+(BRC {c} (FlagLT) yes no) && c&s390x.Less      == 0 => (First no yes)
+(BRC {c} (FlagGT) yes no) && c&s390x.Greater   == 0 => (First no yes)
+(BRC {c} (FlagOV) yes no) && c&s390x.Unordered == 0 => (First no yes)
+
+// Absorb flag constants into SETxx ops.
+(LOCGR {c} _ x (FlagEQ)) && c&s390x.Equal     != 0 => x
+(LOCGR {c} _ x (FlagLT)) && c&s390x.Less      != 0 => x
+(LOCGR {c} _ x (FlagGT)) && c&s390x.Greater   != 0 => x
+(LOCGR {c} _ x (FlagOV)) && c&s390x.Unordered != 0 => x
+
+(LOCGR {c} x _ (FlagEQ)) && c&s390x.Equal     == 0 => x
+(LOCGR {c} x _ (FlagLT)) && c&s390x.Less      == 0 => x
+(LOCGR {c} x _ (FlagGT)) && c&s390x.Greater   == 0 => x
+(LOCGR {c} x _ (FlagOV)) && c&s390x.Unordered == 0 => x
+
+// Remove redundant *const ops
+(ADDconst [0] x) => x
+(ADDWconst [c] x) && int32(c)==0 => x
+(SUBconst [0] x) => x
+(SUBWconst [c] x) && int32(c) == 0 => x
+(ANDconst [0] _)                 => (MOVDconst [0])
+(ANDWconst [c] _) && int32(c)==0  => (MOVDconst [0])
+(ANDconst [-1] x)                => x
+(ANDWconst [c] x) && int32(c)==-1 => x
+(ORconst [0] x)                  => x
+(ORWconst [c] x) && int32(c)==0   => x
+(ORconst [-1] _)                 => (MOVDconst [-1])
+(ORWconst [c] _) && int32(c)==-1  => (MOVDconst [-1])
+(XORconst [0] x)                  => x
+(XORWconst [c] x) && int32(c)==0   => x
+
+// Shifts by zero (may be inserted during multiplication strength reduction).
+((SLD|SLW|SRD|SRW|SRAD|SRAW)const x [0]) => x
+
+// Convert constant subtracts to constant adds.
+(SUBconst [c] x) && c != -(1<<31) => (ADDconst [-c] x)
+(SUBWconst [c] x) => (ADDWconst [-int32(c)] x)
+
+// generic constant folding
+// TODO: more of this
+(ADDconst [c] (MOVDconst [d])) => (MOVDconst [int64(c)+d])
+(ADDWconst [c] (MOVDconst [d])) => (MOVDconst [int64(c)+d])
+(ADDconst [c] (ADDconst [d] x)) && is32Bit(int64(c)+int64(d)) => (ADDconst [c+d] x)
+(ADDWconst [c] (ADDWconst [d] x)) => (ADDWconst [int32(c+d)] x)
+(SUBconst (MOVDconst [d]) [c]) => (MOVDconst [d-int64(c)])
+(SUBconst (SUBconst x [d]) [c]) && is32Bit(-int64(c)-int64(d)) => (ADDconst [-c-d] x)
+(SRADconst [c] (MOVDconst [d])) => (MOVDconst [d>>uint64(c)])
+(SRAWconst [c] (MOVDconst [d])) => (MOVDconst [int64(int32(d))>>uint64(c)])
+(NEG (MOVDconst [c])) => (MOVDconst [-c])
+(NEGW (MOVDconst [c])) => (MOVDconst [int64(int32(-c))])
+(MULLDconst [c] (MOVDconst [d])) => (MOVDconst [int64(c)*d])
+(MULLWconst [c] (MOVDconst [d])) => (MOVDconst [int64(c*int32(d))])
+(AND (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [c&d])
+(ANDconst [c] (MOVDconst [d])) => (MOVDconst [c&d])
+(ANDWconst [c] (MOVDconst [d])) => (MOVDconst [int64(c)&d])
+(OR (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [c|d])
+(ORconst [c] (MOVDconst [d])) => (MOVDconst [c|d])
+(ORWconst [c] (MOVDconst [d])) => (MOVDconst [int64(c)|d])
+(XOR (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [c^d])
+(XORconst [c] (MOVDconst [d])) => (MOVDconst [c^d])
+(XORWconst [c] (MOVDconst [d])) => (MOVDconst [int64(c)^d])
+(LoweredRound32F x:(FMOVSconst)) => x
+(LoweredRound64F x:(FMOVDconst)) => x
+
+// generic simplifications
+// TODO: more of this
+(ADD x (NEG y)) => (SUB x y)
+(ADDW x (NEGW y)) => (SUBW x y)
+(SUB x x) => (MOVDconst [0])
+(SUBW x x) => (MOVDconst [0])
+(AND x x) => x
+(ANDW x x) => x
+(OR x x) => x
+(ORW x x) => x
+(XOR x x) => (MOVDconst [0])
+(XORW x x) => (MOVDconst [0])
+(NEG (ADDconst [c] (NEG x))) && c != -(1<<31) => (ADDconst [-c] x)
+(MOVBZreg (ANDWconst [m] x)) => (MOVWZreg (ANDWconst <typ.UInt32> [int32( uint8(m))] x))
+(MOVHZreg (ANDWconst [m] x)) => (MOVWZreg (ANDWconst <typ.UInt32> [int32(uint16(m))] x))
+(MOVBreg  (ANDWconst [m] x)) &&  int8(m) >= 0 => (MOVWZreg (ANDWconst <typ.UInt32> [int32( uint8(m))] x))
+(MOVHreg  (ANDWconst [m] x)) && int16(m) >= 0 => (MOVWZreg (ANDWconst <typ.UInt32> [int32(uint16(m))] x))
+
+// carry flag generation
+// (only constant fold carry of zero)
+(Select1 (ADDCconst (MOVDconst [c]) [d]))
+  && uint64(c+int64(d)) >= uint64(c) && c+int64(d) == 0
+  => (FlagEQ)
+(Select1 (ADDCconst (MOVDconst [c]) [d]))
+  && uint64(c+int64(d)) >= uint64(c) && c+int64(d) != 0
+  => (FlagLT)
+
+// borrow flag generation
+// (only constant fold borrow of zero)
+(Select1 (SUBC (MOVDconst [c]) (MOVDconst [d])))
+  && uint64(d) <= uint64(c) && c-d == 0
+  => (FlagGT)
+(Select1 (SUBC (MOVDconst [c]) (MOVDconst [d])))
+  && uint64(d) <= uint64(c) && c-d != 0
+  => (FlagOV)
+
+// add with carry
+(ADDE x y (FlagEQ)) => (ADDC x y)
+(ADDE x y (FlagLT)) => (ADDC x y)
+(ADDC x (MOVDconst [c])) && is16Bit(c) => (ADDCconst x [int16(c)])
+(Select0 (ADDCconst (MOVDconst [c]) [d])) => (MOVDconst [c+int64(d)])
+
+// subtract with borrow
+(SUBE x y (FlagGT)) => (SUBC x y)
+(SUBE x y (FlagOV)) => (SUBC x y)
+(Select0 (SUBC (MOVDconst [c]) (MOVDconst [d]))) => (MOVDconst [c-d])
+
+// collapse carry chain
+(ADDE x y (Select1 (ADDCconst [-1] (Select0 (ADDE (MOVDconst [0]) (MOVDconst [0]) c)))))
+  => (ADDE x y c)
+
+// collapse borrow chain
+(SUBE x y (Select1 (SUBC (MOVDconst [0]) (NEG (Select0 (SUBE (MOVDconst [0]) (MOVDconst [0]) c))))))
+  => (SUBE x y c)
+
+// branch on carry
+(C(G|LG)IJ {s390x.Equal}         (Select0 (ADDE (MOVDconst [0]) (MOVDconst [0]) carry)) [0]) => (BRC {s390x.NoCarry} carry)
+(C(G|LG)IJ {s390x.Equal}         (Select0 (ADDE (MOVDconst [0]) (MOVDconst [0]) carry)) [1]) => (BRC {s390x.Carry}   carry)
+(C(G|LG)IJ {s390x.LessOrGreater} (Select0 (ADDE (MOVDconst [0]) (MOVDconst [0]) carry)) [0]) => (BRC {s390x.Carry}   carry)
+(C(G|LG)IJ {s390x.LessOrGreater} (Select0 (ADDE (MOVDconst [0]) (MOVDconst [0]) carry)) [1]) => (BRC {s390x.NoCarry} carry)
+(C(G|LG)IJ {s390x.Greater}       (Select0 (ADDE (MOVDconst [0]) (MOVDconst [0]) carry)) [0]) => (BRC {s390x.Carry}   carry)
+
+// branch on borrow
+(C(G|LG)IJ {s390x.Equal}         (NEG (Select0 (SUBE (MOVDconst [0]) (MOVDconst [0]) borrow))) [0]) => (BRC {s390x.NoBorrow} borrow)
+(C(G|LG)IJ {s390x.Equal}         (NEG (Select0 (SUBE (MOVDconst [0]) (MOVDconst [0]) borrow))) [1]) => (BRC {s390x.Borrow}   borrow)
+(C(G|LG)IJ {s390x.LessOrGreater} (NEG (Select0 (SUBE (MOVDconst [0]) (MOVDconst [0]) borrow))) [0]) => (BRC {s390x.Borrow}   borrow)
+(C(G|LG)IJ {s390x.LessOrGreater} (NEG (Select0 (SUBE (MOVDconst [0]) (MOVDconst [0]) borrow))) [1]) => (BRC {s390x.NoBorrow} borrow)
+(C(G|LG)IJ {s390x.Greater}       (NEG (Select0 (SUBE (MOVDconst [0]) (MOVDconst [0]) borrow))) [0]) => (BRC {s390x.Borrow}   borrow)
+
+// fused multiply-add
+(Select0 (F(ADD|SUB) (FMUL y z) x)) && x.Block.Func.useFMA(v) => (FM(ADD|SUB) x y z)
+(Select0 (F(ADDS|SUBS) (FMULS y z) x)) && x.Block.Func.useFMA(v) => (FM(ADDS|SUBS) x y z)
+
+// Convert floating point comparisons against zero into 'load and test' instructions.
+(F(CMP|CMPS) x (FMOV(D|S)const [0.0])) => (LT(D|E)BR x)
+(F(CMP|CMPS) (FMOV(D|S)const [0.0]) x) => (InvertFlags (LT(D|E)BR <v.Type> x))
+
+// FSUB, FSUBS, FADD, FADDS now produce a condition code representing the
+// comparison of the result with 0.0. If a compare with zero instruction
+// (e.g. LTDBR) is following one of those instructions, we can use the
+// generated flag and remove the comparison instruction.
+// Note: when inserting Select1 ops we need to ensure they are in the
+// same block as their argument. We could also use @x.Block for this
+// but moving the flag generating value to a different block seems to
+// increase the likelihood that the flags value will have to be regenerated
+// by flagalloc which is not what we want.
+(LTDBR (Select0 x:(F(ADD|SUB) _ _)))   && b == x.Block => (Select1 x)
+(LTEBR (Select0 x:(F(ADDS|SUBS) _ _))) && b == x.Block => (Select1 x)
+
+// Fold memory operations into operations.
+// Exclude global data (SB) because these instructions cannot handle relative addresses.
+// TODO(mundaym): indexed versions of these?
+((ADD|SUB|MULLD|AND|OR|XOR) <t> x g:(MOVDload [off] {sym} ptr mem))
+  && ptr.Op != OpSB
+  && is20Bit(int64(off))
+  && canMergeLoadClobber(v, g, x)
+  && clobber(g)
+  => ((ADD|SUB|MULLD|AND|OR|XOR)load <t> [off] {sym} x ptr mem)
+((ADD|SUB|MULL|AND|OR|XOR)W <t> x g:(MOVWload [off] {sym} ptr mem))
+  && ptr.Op != OpSB
+  && is20Bit(int64(off))
+  && canMergeLoadClobber(v, g, x)
+  && clobber(g)
+  => ((ADD|SUB|MULL|AND|OR|XOR)Wload <t> [off] {sym} x ptr mem)
+((ADD|SUB|MULL|AND|OR|XOR)W <t> x g:(MOVWZload [off] {sym} ptr mem))
+  && ptr.Op != OpSB
+  && is20Bit(int64(off))
+  && canMergeLoadClobber(v, g, x)
+  && clobber(g)
+  => ((ADD|SUB|MULL|AND|OR|XOR)Wload <t> [off] {sym} x ptr mem)
+
+// Combine constant stores into larger (unaligned) stores.
+// Avoid SB because constant stores to relative offsets are
+// emulated by the assembler and also can't handle unaligned offsets.
+(MOVBstoreconst [c] {s} p x:(MOVBstoreconst [a] {s} p mem))
+  && p.Op != OpSB
+  && x.Uses == 1
+  && a.Off() + 1 == c.Off()
+  && clobber(x)
+  => (MOVHstoreconst [makeValAndOff(c.Val()&0xff | a.Val()<<8, a.Off())] {s} p mem)
+(MOVHstoreconst [c] {s} p x:(MOVHstoreconst [a] {s} p mem))
+  && p.Op != OpSB
+  && x.Uses == 1
+  && a.Off() + 2 == c.Off()
+  && clobber(x)
+  => (MOVWstore [a.Off()] {s} p (MOVDconst [int64(c.Val()&0xffff | a.Val()<<16)]) mem)
+(MOVWstoreconst [c] {s} p x:(MOVWstoreconst [a] {s} p mem))
+  && p.Op != OpSB
+  && x.Uses == 1
+  && a.Off() + 4 == c.Off()
+  && clobber(x)
+  => (MOVDstore [a.Off()] {s} p (MOVDconst [c.Val64()&0xffffffff | a.Val64()<<32]) mem)
+
+// Combine stores into larger (unaligned) stores.
+// It doesn't work on global data (based on SB) because stores with relative addressing
+// require that the memory operand be aligned.
+(MOVBstore [i] {s} p w x:(MOVBstore [i-1] {s} p (SRDconst [8] w) mem))
+  && p.Op != OpSB
+  && x.Uses == 1
+  && clobber(x)
+  => (MOVHstore [i-1] {s} p w mem)
+(MOVBstore [i] {s} p w0:(SRDconst [j] w) x:(MOVBstore [i-1] {s} p (SRDconst [j+8] w) mem))
+  && p.Op != OpSB
+  && x.Uses == 1
+  && clobber(x)
+  => (MOVHstore [i-1] {s} p w0 mem)
+(MOVBstore [i] {s} p w x:(MOVBstore [i-1] {s} p (SRWconst [8] w) mem))
+  && p.Op != OpSB
+  && x.Uses == 1
+  && clobber(x)
+  => (MOVHstore [i-1] {s} p w mem)
+(MOVBstore [i] {s} p w0:(SRWconst [j] w) x:(MOVBstore [i-1] {s} p (SRWconst [j+8] w) mem))
+  && p.Op != OpSB
+  && x.Uses == 1
+  && clobber(x)
+  => (MOVHstore [i-1] {s} p w0 mem)
+(MOVHstore [i] {s} p w x:(MOVHstore [i-2] {s} p (SRDconst [16] w) mem))
+  && p.Op != OpSB
+  && x.Uses == 1
+  && clobber(x)
+  => (MOVWstore [i-2] {s} p w mem)
+(MOVHstore [i] {s} p w0:(SRDconst [j] w) x:(MOVHstore [i-2] {s} p (SRDconst [j+16] w) mem))
+  && p.Op != OpSB
+  && x.Uses == 1
+  && clobber(x)
+  => (MOVWstore [i-2] {s} p w0 mem)
+(MOVHstore [i] {s} p w x:(MOVHstore [i-2] {s} p (SRWconst [16] w) mem))
+  && p.Op != OpSB
+  && x.Uses == 1
+  && clobber(x)
+  => (MOVWstore [i-2] {s} p w mem)
+(MOVHstore [i] {s} p w0:(SRWconst [j] w) x:(MOVHstore [i-2] {s} p (SRWconst [j+16] w) mem))
+  && p.Op != OpSB
+  && x.Uses == 1
+  && clobber(x)
+  => (MOVWstore [i-2] {s} p w0 mem)
+(MOVWstore [i] {s} p (SRDconst [32] w) x:(MOVWstore [i-4] {s} p w mem))
+  && p.Op != OpSB
+  && x.Uses == 1
+  && clobber(x)
+  => (MOVDstore [i-4] {s} p w mem)
+(MOVWstore [i] {s} p w0:(SRDconst [j] w) x:(MOVWstore [i-4] {s} p (SRDconst [j+32] w) mem))
+  && p.Op != OpSB
+  && x.Uses == 1
+  && clobber(x)
+  => (MOVDstore [i-4] {s} p w0 mem)
+
+// Combine stores into larger (unaligned) stores with the bytes reversed (little endian).
+// Store-with-bytes-reversed instructions do not support relative memory addresses,
+// so these stores can't operate on global data (SB).
+(MOVBstore [i] {s} p (SRDconst [8] w) x:(MOVBstore [i-1] {s} p w mem))
+  && p.Op != OpSB
+  && x.Uses == 1
+  && clobber(x)
+  => (MOVHBRstore [i-1] {s} p w mem)
+(MOVBstore [i] {s} p (SRDconst [j] w) x:(MOVBstore [i-1] {s} p w0:(SRDconst [j-8] w) mem))
+  && p.Op != OpSB
+  && x.Uses == 1
+  && clobber(x)
+  => (MOVHBRstore [i-1] {s} p w0 mem)
+(MOVBstore [i] {s} p (SRWconst [8] w) x:(MOVBstore [i-1] {s} p w mem))
+  && p.Op != OpSB
+  && x.Uses == 1
+  && clobber(x)
+  => (MOVHBRstore [i-1] {s} p w mem)
+(MOVBstore [i] {s} p (SRWconst [j] w) x:(MOVBstore [i-1] {s} p w0:(SRWconst [j-8] w) mem))
+  && p.Op != OpSB
+  && x.Uses == 1
+  && clobber(x)
+  => (MOVHBRstore [i-1] {s} p w0 mem)
+(MOVHBRstore [i] {s} p (SRDconst [16] w) x:(MOVHBRstore [i-2] {s} p w mem))
+  && x.Uses == 1
+  && clobber(x)
+  => (MOVWBRstore [i-2] {s} p w mem)
+(MOVHBRstore [i] {s} p (SRDconst [j] w) x:(MOVHBRstore [i-2] {s} p w0:(SRDconst [j-16] w) mem))
+  && x.Uses == 1
+  && clobber(x)
+  => (MOVWBRstore [i-2] {s} p w0 mem)
+(MOVHBRstore [i] {s} p (SRWconst [16] w) x:(MOVHBRstore [i-2] {s} p w mem))
+  && x.Uses == 1
+  && clobber(x)
+  => (MOVWBRstore [i-2] {s} p w mem)
+(MOVHBRstore [i] {s} p (SRWconst [j] w) x:(MOVHBRstore [i-2] {s} p w0:(SRWconst [j-16] w) mem))
+  && x.Uses == 1
+  && clobber(x)
+  => (MOVWBRstore [i-2] {s} p w0 mem)
+(MOVWBRstore [i] {s} p (SRDconst [32] w) x:(MOVWBRstore [i-4] {s} p w mem))
+  && x.Uses == 1
+  && clobber(x)
+  => (MOVDBRstore [i-4] {s} p w mem)
+(MOVWBRstore [i] {s} p (SRDconst [j] w) x:(MOVWBRstore [i-4] {s} p w0:(SRDconst [j-32] w) mem))
+  && x.Uses == 1
+  && clobber(x)
+  => (MOVDBRstore [i-4] {s} p w0 mem)
+
+(MOVBstore [7] {s} p1 (SRDconst w)
+  x1:(MOVHBRstore [5] {s} p1 (SRDconst w)
+  x2:(MOVWBRstore [1] {s} p1 (SRDconst w)
+  x3:(MOVBstore [0] {s} p1 w mem))))
+  && x1.Uses == 1
+  && x2.Uses == 1
+  && x3.Uses == 1
+  && clobber(x1, x2, x3)
+  => (MOVDBRstore {s} p1 w mem)
+
+// Combining byte loads into larger (unaligned) loads.
+
+// Big-endian loads
+
+(ORW                 x1:(MOVBZload [i1] {s} p mem)
+    sh:(SLWconst [8] x0:(MOVBZload [i0] {s} p mem)))
+  && i1 == i0+1
+  && p.Op != OpSB
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && sh.Uses == 1
+  && mergePoint(b,x0,x1) != nil
+  && clobber(x0, x1, sh)
+  => @mergePoint(b,x0,x1) (MOVHZload [i0] {s} p mem)
+
+(OR                  x1:(MOVBZload [i1] {s} p mem)
+    sh:(SLDconst [8] x0:(MOVBZload [i0] {s} p mem)))
+  && i1 == i0+1
+  && p.Op != OpSB
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && sh.Uses == 1
+  && mergePoint(b,x0,x1) != nil
+  && clobber(x0, x1, sh)
+  => @mergePoint(b,x0,x1) (MOVHZload [i0] {s} p mem)
+
+(ORW                  x1:(MOVHZload [i1] {s} p mem)
+    sh:(SLWconst [16] x0:(MOVHZload [i0] {s} p mem)))
+  && i1 == i0+2
+  && p.Op != OpSB
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && sh.Uses == 1
+  && mergePoint(b,x0,x1) != nil
+  && clobber(x0, x1, sh)
+  => @mergePoint(b,x0,x1) (MOVWZload [i0] {s} p mem)
+
+(OR                   x1:(MOVHZload [i1] {s} p mem)
+    sh:(SLDconst [16] x0:(MOVHZload [i0] {s} p mem)))
+  && i1 == i0+2
+  && p.Op != OpSB
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && sh.Uses == 1
+  && mergePoint(b,x0,x1) != nil
+  && clobber(x0, x1, sh)
+  => @mergePoint(b,x0,x1) (MOVWZload [i0] {s} p mem)
+
+(OR                   x1:(MOVWZload [i1] {s} p mem)
+    sh:(SLDconst [32] x0:(MOVWZload [i0] {s} p mem)))
+  && i1 == i0+4
+  && p.Op != OpSB
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && sh.Uses == 1
+  && mergePoint(b,x0,x1) != nil
+  && clobber(x0, x1, sh)
+  => @mergePoint(b,x0,x1) (MOVDload [i0] {s} p mem)
+
+(ORW
+    s0:(SLWconst [j0] x0:(MOVBZload [i0] {s} p mem))
+    or:(ORW
+        s1:(SLWconst [j1] x1:(MOVBZload [i1] {s} p mem))
+	y))
+  && i1 == i0+1
+  && j1 == j0-8
+  && j1 % 16 == 0
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && s0.Uses == 1
+  && s1.Uses == 1
+  && or.Uses == 1
+  && mergePoint(b,x0,x1,y) != nil
+  && clobber(x0, x1, s0, s1, or)
+  => @mergePoint(b,x0,x1,y) (ORW <v.Type> (SLWconst <v.Type> [j1] (MOVHZload [i0] {s} p mem)) y)
+
+(OR
+    s0:(SLDconst [j0] x0:(MOVBZload [i0] {s} p mem))
+    or:(OR
+        s1:(SLDconst [j1] x1:(MOVBZload [i1] {s} p mem))
+	y))
+  && i1 == i0+1
+  && j1 == j0-8
+  && j1 % 16 == 0
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && s0.Uses == 1
+  && s1.Uses == 1
+  && or.Uses == 1
+  && mergePoint(b,x0,x1,y) != nil
+  && clobber(x0, x1, s0, s1, or)
+  => @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j1] (MOVHZload [i0] {s} p mem)) y)
+
+(OR
+    s0:(SLDconst [j0] x0:(MOVHZload [i0] {s} p mem))
+    or:(OR
+        s1:(SLDconst [j1] x1:(MOVHZload [i1] {s} p mem))
+	y))
+  && i1 == i0+2
+  && j1 == j0-16
+  && j1 % 32 == 0
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && s0.Uses == 1
+  && s1.Uses == 1
+  && or.Uses == 1
+  && mergePoint(b,x0,x1,y) != nil
+  && clobber(x0, x1, s0, s1, or)
+  => @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j1] (MOVWZload [i0] {s} p mem)) y)
+
+// Little-endian loads
+
+(ORW                 x0:(MOVBZload [i0] {s} p mem)
+    sh:(SLWconst [8] x1:(MOVBZload [i1] {s} p mem)))
+  && p.Op != OpSB
+  && i1 == i0+1
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && sh.Uses == 1
+  && mergePoint(b,x0,x1) != nil
+  && clobber(x0, x1, sh)
+  => @mergePoint(b,x0,x1) (MOVHZreg (MOVHBRload [i0] {s} p mem))
+
+(OR                  x0:(MOVBZload [i0] {s} p mem)
+    sh:(SLDconst [8] x1:(MOVBZload [i1] {s} p mem)))
+  && p.Op != OpSB
+  && i1 == i0+1
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && sh.Uses == 1
+  && mergePoint(b,x0,x1) != nil
+  && clobber(x0, x1, sh)
+  => @mergePoint(b,x0,x1) (MOVHZreg (MOVHBRload [i0] {s} p mem))
+
+(ORW                  r0:(MOVHZreg x0:(MOVHBRload [i0] {s} p mem))
+    sh:(SLWconst [16] r1:(MOVHZreg x1:(MOVHBRload [i1] {s} p mem))))
+  && i1 == i0+2
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && r0.Uses == 1
+  && r1.Uses == 1
+  && sh.Uses == 1
+  && mergePoint(b,x0,x1) != nil
+  && clobber(x0, x1, r0, r1, sh)
+  => @mergePoint(b,x0,x1) (MOVWBRload [i0] {s} p mem)
+
+(OR                   r0:(MOVHZreg x0:(MOVHBRload [i0] {s} p mem))
+    sh:(SLDconst [16] r1:(MOVHZreg x1:(MOVHBRload [i1] {s} p mem))))
+  && i1 == i0+2
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && r0.Uses == 1
+  && r1.Uses == 1
+  && sh.Uses == 1
+  && mergePoint(b,x0,x1) != nil
+  && clobber(x0, x1, r0, r1, sh)
+  => @mergePoint(b,x0,x1) (MOVWZreg (MOVWBRload [i0] {s} p mem))
+
+(OR                   r0:(MOVWZreg x0:(MOVWBRload [i0] {s} p mem))
+    sh:(SLDconst [32] r1:(MOVWZreg x1:(MOVWBRload [i1] {s} p mem))))
+  && i1 == i0+4
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && r0.Uses == 1
+  && r1.Uses == 1
+  && sh.Uses == 1
+  && mergePoint(b,x0,x1) != nil
+  && clobber(x0, x1, r0, r1, sh)
+  => @mergePoint(b,x0,x1) (MOVDBRload [i0] {s} p mem)
+
+(ORW
+    s1:(SLWconst [j1] x1:(MOVBZload [i1] {s} p mem))
+    or:(ORW
+        s0:(SLWconst [j0] x0:(MOVBZload [i0] {s} p mem))
+	y))
+  && p.Op != OpSB
+  && i1 == i0+1
+  && j1 == j0+8
+  && j0 % 16 == 0
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && s0.Uses == 1
+  && s1.Uses == 1
+  && or.Uses == 1
+  && mergePoint(b,x0,x1,y) != nil
+  && clobber(x0, x1, s0, s1, or)
+  => @mergePoint(b,x0,x1,y) (ORW <v.Type> (SLWconst <v.Type> [j0] (MOVHZreg (MOVHBRload [i0] {s} p mem))) y)
+
+(OR
+    s1:(SLDconst [j1] x1:(MOVBZload [i1] {s} p mem))
+    or:(OR
+        s0:(SLDconst [j0] x0:(MOVBZload [i0] {s} p mem))
+	y))
+  && p.Op != OpSB
+  && i1 == i0+1
+  && j1 == j0+8
+  && j0 % 16 == 0
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && s0.Uses == 1
+  && s1.Uses == 1
+  && or.Uses == 1
+  && mergePoint(b,x0,x1,y) != nil
+  && clobber(x0, x1, s0, s1, or)
+  => @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j0] (MOVHZreg (MOVHBRload [i0] {s} p mem))) y)
+
+(OR
+    s1:(SLDconst [j1] r1:(MOVHZreg x1:(MOVHBRload [i1] {s} p mem)))
+    or:(OR
+        s0:(SLDconst [j0] r0:(MOVHZreg x0:(MOVHBRload [i0] {s} p mem)))
+	y))
+  && i1 == i0+2
+  && j1 == j0+16
+  && j0 % 32 == 0
+  && x0.Uses == 1
+  && x1.Uses == 1
+  && r0.Uses == 1
+  && r1.Uses == 1
+  && s0.Uses == 1
+  && s1.Uses == 1
+  && or.Uses == 1
+  && mergePoint(b,x0,x1,y) != nil
+  && clobber(x0, x1, r0, r1, s0, s1, or)
+  => @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j0] (MOVWZreg (MOVWBRload [i0] {s} p mem))) y)
+
+// Combine stores into store multiples.
+// 32-bit
+(MOVWstore [i] {s} p w1 x:(MOVWstore [i-4] {s} p w0 mem))
+  && p.Op != OpSB
+  && x.Uses == 1
+  && is20Bit(int64(i)-4)
+  && clobber(x)
+  => (STM2 [i-4] {s} p w0 w1 mem)
+(MOVWstore [i] {s} p w2 x:(STM2 [i-8] {s} p w0 w1 mem))
+  && x.Uses == 1
+  && is20Bit(int64(i)-8)
+  && clobber(x)
+  => (STM3 [i-8] {s} p w0 w1 w2 mem)
+(MOVWstore [i] {s} p w3 x:(STM3 [i-12] {s} p w0 w1 w2 mem))
+  && x.Uses == 1
+  && is20Bit(int64(i)-12)
+  && clobber(x)
+  => (STM4 [i-12] {s} p w0 w1 w2 w3 mem)
+(STM2 [i] {s} p w2 w3 x:(STM2 [i-8] {s} p w0 w1 mem))
+  && x.Uses == 1
+  && is20Bit(int64(i)-8)
+  && clobber(x)
+  => (STM4 [i-8] {s} p w0 w1 w2 w3 mem)
+// 64-bit
+(MOVDstore [i] {s} p w1 x:(MOVDstore [i-8] {s} p w0 mem))
+  && p.Op != OpSB
+  && x.Uses == 1
+  && is20Bit(int64(i)-8)
+  && clobber(x)
+  => (STMG2 [i-8] {s} p w0 w1 mem)
+(MOVDstore [i] {s} p w2 x:(STMG2 [i-16] {s} p w0 w1 mem))
+  && x.Uses == 1
+  && is20Bit(int64(i)-16)
+  && clobber(x)
+  => (STMG3 [i-16] {s} p w0 w1 w2 mem)
+(MOVDstore [i] {s} p w3 x:(STMG3 [i-24] {s} p w0 w1 w2 mem))
+  && x.Uses == 1
+  && is20Bit(int64(i)-24)
+  && clobber(x)
+  => (STMG4 [i-24] {s} p w0 w1 w2 w3 mem)
+(STMG2 [i] {s} p w2 w3 x:(STMG2 [i-16] {s} p w0 w1 mem))
+  && x.Uses == 1
+  && is20Bit(int64(i)-16)
+  && clobber(x)
+  => (STMG4 [i-16] {s} p w0 w1 w2 w3 mem)
+
+// Convert 32-bit store multiples into 64-bit stores.
+(STM2 [i] {s} p (SRDconst [32] x) x mem) => (MOVDstore [i] {s} p x mem)
diff --git a/src/cmd/compile/internal/ssa/_gen/S390XOps.go b/src/cmd/compile/internal/ssa/_gen/S390XOps.go
new file mode 100644
index 0000000..896fdaa
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/_gen/S390XOps.go
@@ -0,0 +1,817 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "strings"
+
+// Notes:
+//  - Integer types live in the low portion of registers. Upper portions are junk.
+//  - Boolean types use the low-order byte of a register. 0=false, 1=true.
+//    Upper bytes are junk.
+//  - When doing sub-register operations, we try to write the whole
+//    destination register to avoid a partial-register write.
+//  - Unused portions of AuxInt (or the Val portion of ValAndOff) are
+//    filled by sign-extending the used portion. Users of AuxInt which interpret
+//    AuxInt as unsigned (e.g. shifts) must be careful.
+//  - The SB 'register' is implemented using instruction-relative addressing. This
+//    places some limitations on when and how memory operands that are addressed
+//    relative to SB can be used:
+//
+//     1. Pseudo-instructions do not always map to a single machine instruction when
+//        using the SB 'register' to address data. This is because many machine
+//        instructions do not have relative long (RL suffix) equivalents. For example,
+//        ADDload, which is assembled as AG.
+//
+//     2. Loads and stores using relative addressing require the data be aligned
+//        according to its size (8-bytes for double words, 4-bytes for words
+//        and so on).
+//
+//    We can always work around these by inserting LARL instructions (load address
+//    relative long) in the assembler, but typically this results in worse code
+//    generation because the address can't be re-used. Inserting instructions in the
+//    assembler also means clobbering the temp register and it is a long-term goal
+//    to prevent the compiler doing this so that it can be allocated as a normal
+//    register.
+//
+// For more information about the z/Architecture, the instruction set and the
+// addressing modes it supports take a look at the z/Architecture Principles of
+// Operation: http://publibfp.boulder.ibm.com/epubs/pdf/dz9zr010.pdf
+//
+// Suffixes encode the bit width of pseudo-instructions.
+// D (double word)  = 64 bit (frequently omitted)
+// W (word)         = 32 bit
+// H (half word)    = 16 bit
+// B (byte)         = 8 bit
+// S (single prec.) = 32 bit (double precision is omitted)
+
+// copied from ../../s390x/reg.go
+var regNamesS390X = []string{
+	"R0",
+	"R1",
+	"R2",
+	"R3",
+	"R4",
+	"R5",
+	"R6",
+	"R7",
+	"R8",
+	"R9",
+	"R10",
+	"R11",
+	"R12",
+	"g", // R13
+	"R14",
+	"SP", // R15
+	"F0",
+	"F1",
+	"F2",
+	"F3",
+	"F4",
+	"F5",
+	"F6",
+	"F7",
+	"F8",
+	"F9",
+	"F10",
+	"F11",
+	"F12",
+	"F13",
+	"F14",
+	"F15",
+
+	// If you add registers, update asyncPreempt in runtime.
+
+	//pseudo-registers
+	"SB",
+}
+
+func init() {
+	// Make map from reg names to reg integers.
+	if len(regNamesS390X) > 64 {
+		panic("too many registers")
+	}
+	num := map[string]int{}
+	for i, name := range regNamesS390X {
+		num[name] = i
+	}
+	buildReg := func(s string) regMask {
+		m := regMask(0)
+		for _, r := range strings.Split(s, " ") {
+			if n, ok := num[r]; ok {
+				m |= regMask(1) << uint(n)
+				continue
+			}
+			panic("register " + r + " not found")
+		}
+		return m
+	}
+
+	// Common individual register masks
+	var (
+		sp  = buildReg("SP")
+		sb  = buildReg("SB")
+		r0  = buildReg("R0")
+		tmp = buildReg("R11") // R11 is used as a temporary in a small number of instructions.
+
+		// R10 is reserved by the assembler.
+		gp   = buildReg("R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R11 R12 R14")
+		gpg  = gp | buildReg("g")
+		gpsp = gp | sp
+
+		// R0 is considered to contain the value 0 in address calculations.
+		ptr     = gp &^ r0
+		ptrsp   = ptr | sp
+		ptrspsb = ptrsp | sb
+
+		fp         = buildReg("F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15")
+		callerSave = gp | fp | buildReg("g") // runtime.setg (and anything calling it) may clobber g
+		r1         = buildReg("R1")
+		r2         = buildReg("R2")
+		r3         = buildReg("R3")
+	)
+	// Common slices of register masks
+	var (
+		gponly = []regMask{gp}
+		fponly = []regMask{fp}
+	)
+
+	// Common regInfo
+	var (
+		gp01    = regInfo{inputs: []regMask{}, outputs: gponly}
+		gp11    = regInfo{inputs: []regMask{gp}, outputs: gponly}
+		gp11sp  = regInfo{inputs: []regMask{gpsp}, outputs: gponly}
+		gp21    = regInfo{inputs: []regMask{gp, gp}, outputs: gponly}
+		gp21sp  = regInfo{inputs: []regMask{gpsp, gp}, outputs: gponly}
+		gp21tmp = regInfo{inputs: []regMask{gp &^ tmp, gp &^ tmp}, outputs: []regMask{gp &^ tmp}, clobbers: tmp}
+
+		// R0 evaluates to 0 when used as the number of bits to shift
+		// so we need to exclude it from that operand.
+		sh21 = regInfo{inputs: []regMask{gp, ptr}, outputs: gponly}
+
+		addr    = regInfo{inputs: []regMask{sp | sb}, outputs: gponly}
+		addridx = regInfo{inputs: []regMask{sp | sb, ptrsp}, outputs: gponly}
+
+		gp2flags       = regInfo{inputs: []regMask{gpsp, gpsp}}
+		gp1flags       = regInfo{inputs: []regMask{gpsp}}
+		gp2flags1      = regInfo{inputs: []regMask{gp, gp}, outputs: gponly}
+		gp11flags      = regInfo{inputs: []regMask{gp}, outputs: gponly}
+		gp21flags      = regInfo{inputs: []regMask{gp, gp}, outputs: gponly}
+		gp2flags1flags = regInfo{inputs: []regMask{gp, gp}, outputs: gponly}
+
+		gpload       = regInfo{inputs: []regMask{ptrspsb, 0}, outputs: gponly}
+		gploadidx    = regInfo{inputs: []regMask{ptrspsb, ptrsp, 0}, outputs: gponly}
+		gpopload     = regInfo{inputs: []regMask{gp, ptrsp, 0}, outputs: gponly}
+		gpstore      = regInfo{inputs: []regMask{ptrspsb, gpsp, 0}}
+		gpstoreconst = regInfo{inputs: []regMask{ptrspsb, 0}}
+		gpstoreidx   = regInfo{inputs: []regMask{ptrsp, ptrsp, gpsp, 0}}
+		gpstorebr    = regInfo{inputs: []regMask{ptrsp, gpsp, 0}}
+		gpstorelaa   = regInfo{inputs: []regMask{ptrspsb, gpsp, 0}, outputs: gponly}
+		gpstorelab   = regInfo{inputs: []regMask{r1, gpsp, 0}, clobbers: r1}
+
+		gpmvc = regInfo{inputs: []regMask{ptrsp, ptrsp, 0}}
+
+		fp01        = regInfo{inputs: []regMask{}, outputs: fponly}
+		fp21        = regInfo{inputs: []regMask{fp, fp}, outputs: fponly}
+		fp31        = regInfo{inputs: []regMask{fp, fp, fp}, outputs: fponly}
+		fp21clobber = regInfo{inputs: []regMask{fp, fp}, outputs: fponly}
+		fpgp        = regInfo{inputs: fponly, outputs: gponly}
+		gpfp        = regInfo{inputs: gponly, outputs: fponly}
+		fp11        = regInfo{inputs: fponly, outputs: fponly}
+		fp1flags    = regInfo{inputs: []regMask{fp}}
+		fp11clobber = regInfo{inputs: fponly, outputs: fponly}
+		fp2flags    = regInfo{inputs: []regMask{fp, fp}}
+
+		fpload    = regInfo{inputs: []regMask{ptrspsb, 0}, outputs: fponly}
+		fploadidx = regInfo{inputs: []regMask{ptrsp, ptrsp, 0}, outputs: fponly}
+
+		fpstore    = regInfo{inputs: []regMask{ptrspsb, fp, 0}}
+		fpstoreidx = regInfo{inputs: []regMask{ptrsp, ptrsp, fp, 0}}
+
+		sync = regInfo{inputs: []regMask{0}}
+
+		// LoweredAtomicCas may overwrite arg1, so force it to R0 for now.
+		cas = regInfo{inputs: []regMask{ptrsp, r0, gpsp, 0}, outputs: []regMask{gp, 0}, clobbers: r0}
+
+		// LoweredAtomicExchange overwrites the output before executing
+		// CS{,G}, so the output register must not be the same as the
+		// input register. For now we just force the output register to
+		// R0.
+		exchange = regInfo{inputs: []regMask{ptrsp, gpsp &^ r0, 0}, outputs: []regMask{r0, 0}}
+	)
+
+	var S390Xops = []opData{
+		// fp ops
+		{name: "FADDS", argLength: 2, reg: fp21clobber, typ: "(Float32,Flags)", asm: "FADDS", commutative: true, resultInArg0: true}, // fp32 arg0 + arg1
+		{name: "FADD", argLength: 2, reg: fp21clobber, typ: "(Float64,Flags)", asm: "FADD", commutative: true, resultInArg0: true},   // fp64 arg0 + arg1
+		{name: "FSUBS", argLength: 2, reg: fp21clobber, typ: "(Float32,Flags)", asm: "FSUBS", resultInArg0: true},                    // fp32 arg0 - arg1
+		{name: "FSUB", argLength: 2, reg: fp21clobber, typ: "(Float64,Flags)", asm: "FSUB", resultInArg0: true},                      // fp64 arg0 - arg1
+		{name: "FMULS", argLength: 2, reg: fp21, asm: "FMULS", commutative: true, resultInArg0: true},                                // fp32 arg0 * arg1
+		{name: "FMUL", argLength: 2, reg: fp21, asm: "FMUL", commutative: true, resultInArg0: true},                                  // fp64 arg0 * arg1
+		{name: "FDIVS", argLength: 2, reg: fp21, asm: "FDIVS", resultInArg0: true},                                                   // fp32 arg0 / arg1
+		{name: "FDIV", argLength: 2, reg: fp21, asm: "FDIV", resultInArg0: true},                                                     // fp64 arg0 / arg1
+		{name: "FNEGS", argLength: 1, reg: fp11clobber, asm: "FNEGS", clobberFlags: true},                                            // fp32 -arg0
+		{name: "FNEG", argLength: 1, reg: fp11clobber, asm: "FNEG", clobberFlags: true},                                              // fp64 -arg0
+		{name: "FMADDS", argLength: 3, reg: fp31, asm: "FMADDS", resultInArg0: true},                                                 // fp32 arg1 * arg2 + arg0
+		{name: "FMADD", argLength: 3, reg: fp31, asm: "FMADD", resultInArg0: true},                                                   // fp64 arg1 * arg2 + arg0
+		{name: "FMSUBS", argLength: 3, reg: fp31, asm: "FMSUBS", resultInArg0: true},                                                 // fp32 arg1 * arg2 - arg0
+		{name: "FMSUB", argLength: 3, reg: fp31, asm: "FMSUB", resultInArg0: true},                                                   // fp64 arg1 * arg2 - arg0
+		{name: "LPDFR", argLength: 1, reg: fp11, asm: "LPDFR"},                                                                       // fp64/fp32 set sign bit
+		{name: "LNDFR", argLength: 1, reg: fp11, asm: "LNDFR"},                                                                       // fp64/fp32 clear sign bit
+		{name: "CPSDR", argLength: 2, reg: fp21, asm: "CPSDR"},                                                                       // fp64/fp32 copy arg1 sign bit to arg0
+
+		// Round to integer, float64 only.
+		//
+		// aux | rounding mode
+		// ----+-----------------------------------
+		//   1 | round to nearest, ties away from 0
+		//   4 | round to nearest, ties to even
+		//   5 | round toward 0
+		//   6 | round toward +∞
+		//   7 | round toward -∞
+		{name: "FIDBR", argLength: 1, reg: fp11, asm: "FIDBR", aux: "Int8"},
+
+		{name: "FMOVSload", argLength: 2, reg: fpload, asm: "FMOVS", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"}, // fp32 load
+		{name: "FMOVDload", argLength: 2, reg: fpload, asm: "FMOVD", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"}, // fp64 load
+		{name: "FMOVSconst", reg: fp01, asm: "FMOVS", aux: "Float32", rematerializeable: true},                               // fp32 constant
+		{name: "FMOVDconst", reg: fp01, asm: "FMOVD", aux: "Float64", rematerializeable: true},                               // fp64 constant
+		{name: "FMOVSloadidx", argLength: 3, reg: fploadidx, asm: "FMOVS", aux: "SymOff", symEffect: "Read"},                 // fp32 load indexed by i
+		{name: "FMOVDloadidx", argLength: 3, reg: fploadidx, asm: "FMOVD", aux: "SymOff", symEffect: "Read"},                 // fp64 load indexed by i
+
+		{name: "FMOVSstore", argLength: 3, reg: fpstore, asm: "FMOVS", aux: "SymOff", faultOnNilArg0: true, symEffect: "Write"}, // fp32 store
+		{name: "FMOVDstore", argLength: 3, reg: fpstore, asm: "FMOVD", aux: "SymOff", faultOnNilArg0: true, symEffect: "Write"}, // fp64 store
+		{name: "FMOVSstoreidx", argLength: 4, reg: fpstoreidx, asm: "FMOVS", aux: "SymOff", symEffect: "Write"},                 // fp32 indexed by i store
+		{name: "FMOVDstoreidx", argLength: 4, reg: fpstoreidx, asm: "FMOVD", aux: "SymOff", symEffect: "Write"},                 // fp64 indexed by i store
+
+		// binary ops
+		{name: "ADD", argLength: 2, reg: gp21sp, asm: "ADD", commutative: true, clobberFlags: true},                                                                  // arg0 + arg1
+		{name: "ADDW", argLength: 2, reg: gp21sp, asm: "ADDW", commutative: true, clobberFlags: true},                                                                // arg0 + arg1
+		{name: "ADDconst", argLength: 1, reg: gp11sp, asm: "ADD", aux: "Int32", typ: "UInt64", clobberFlags: true},                                                   // arg0 + auxint
+		{name: "ADDWconst", argLength: 1, reg: gp11sp, asm: "ADDW", aux: "Int32", clobberFlags: true},                                                                // arg0 + auxint
+		{name: "ADDload", argLength: 3, reg: gpopload, asm: "ADD", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},   // arg0 + *arg1. arg2=mem
+		{name: "ADDWload", argLength: 3, reg: gpopload, asm: "ADDW", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"}, // arg0 + *arg1. arg2=mem
+
+		{name: "SUB", argLength: 2, reg: gp21, asm: "SUB", clobberFlags: true},                                                                                       // arg0 - arg1
+		{name: "SUBW", argLength: 2, reg: gp21, asm: "SUBW", clobberFlags: true},                                                                                     // arg0 - arg1
+		{name: "SUBconst", argLength: 1, reg: gp11, asm: "SUB", aux: "Int32", resultInArg0: true, clobberFlags: true},                                                // arg0 - auxint
+		{name: "SUBWconst", argLength: 1, reg: gp11, asm: "SUBW", aux: "Int32", resultInArg0: true, clobberFlags: true},                                              // arg0 - auxint
+		{name: "SUBload", argLength: 3, reg: gpopload, asm: "SUB", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},   // arg0 - *arg1. arg2=mem
+		{name: "SUBWload", argLength: 3, reg: gpopload, asm: "SUBW", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"}, // arg0 - *arg1. arg2=mem
+
+		{name: "MULLD", argLength: 2, reg: gp21, asm: "MULLD", typ: "Int64", commutative: true, resultInArg0: true, clobberFlags: true},                                // arg0 * arg1
+		{name: "MULLW", argLength: 2, reg: gp21, asm: "MULLW", typ: "Int32", commutative: true, resultInArg0: true, clobberFlags: true},                                // arg0 * arg1
+		{name: "MULLDconst", argLength: 1, reg: gp11, asm: "MULLD", aux: "Int32", typ: "Int64", resultInArg0: true, clobberFlags: true},                                // arg0 * auxint
+		{name: "MULLWconst", argLength: 1, reg: gp11, asm: "MULLW", aux: "Int32", typ: "Int32", resultInArg0: true, clobberFlags: true},                                // arg0 * auxint
+		{name: "MULLDload", argLength: 3, reg: gpopload, asm: "MULLD", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"}, // arg0 * *arg1. arg2=mem
+		{name: "MULLWload", argLength: 3, reg: gpopload, asm: "MULLW", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"}, // arg0 * *arg1. arg2=mem
+
+		{name: "MULHD", argLength: 2, reg: gp21tmp, asm: "MULHD", typ: "Int64", commutative: true, resultInArg0: true, clobberFlags: true},   // (arg0 * arg1) >> width
+		{name: "MULHDU", argLength: 2, reg: gp21tmp, asm: "MULHDU", typ: "Int64", commutative: true, resultInArg0: true, clobberFlags: true}, // (arg0 * arg1) >> width
+
+		{name: "DIVD", argLength: 2, reg: gp21tmp, asm: "DIVD", resultInArg0: true, clobberFlags: true},   // arg0 / arg1
+		{name: "DIVW", argLength: 2, reg: gp21tmp, asm: "DIVW", resultInArg0: true, clobberFlags: true},   // arg0 / arg1
+		{name: "DIVDU", argLength: 2, reg: gp21tmp, asm: "DIVDU", resultInArg0: true, clobberFlags: true}, // arg0 / arg1
+		{name: "DIVWU", argLength: 2, reg: gp21tmp, asm: "DIVWU", resultInArg0: true, clobberFlags: true}, // arg0 / arg1
+
+		{name: "MODD", argLength: 2, reg: gp21tmp, asm: "MODD", resultInArg0: true, clobberFlags: true}, // arg0 % arg1
+		{name: "MODW", argLength: 2, reg: gp21tmp, asm: "MODW", resultInArg0: true, clobberFlags: true}, // arg0 % arg1
+
+		{name: "MODDU", argLength: 2, reg: gp21tmp, asm: "MODDU", resultInArg0: true, clobberFlags: true}, // arg0 % arg1
+		{name: "MODWU", argLength: 2, reg: gp21tmp, asm: "MODWU", resultInArg0: true, clobberFlags: true}, // arg0 % arg1
+
+		{name: "AND", argLength: 2, reg: gp21, asm: "AND", commutative: true, clobberFlags: true},                                                                    // arg0 & arg1
+		{name: "ANDW", argLength: 2, reg: gp21, asm: "ANDW", commutative: true, clobberFlags: true},                                                                  // arg0 & arg1
+		{name: "ANDconst", argLength: 1, reg: gp11, asm: "AND", aux: "Int64", resultInArg0: true, clobberFlags: true},                                                // arg0 & auxint
+		{name: "ANDWconst", argLength: 1, reg: gp11, asm: "ANDW", aux: "Int32", resultInArg0: true, clobberFlags: true},                                              // arg0 & auxint
+		{name: "ANDload", argLength: 3, reg: gpopload, asm: "AND", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},   // arg0 & *arg1. arg2=mem
+		{name: "ANDWload", argLength: 3, reg: gpopload, asm: "ANDW", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"}, // arg0 & *arg1. arg2=mem
+
+		{name: "OR", argLength: 2, reg: gp21, asm: "OR", commutative: true, clobberFlags: true},                                                                    // arg0 | arg1
+		{name: "ORW", argLength: 2, reg: gp21, asm: "ORW", commutative: true, clobberFlags: true},                                                                  // arg0 | arg1
+		{name: "ORconst", argLength: 1, reg: gp11, asm: "OR", aux: "Int64", resultInArg0: true, clobberFlags: true},                                                // arg0 | auxint
+		{name: "ORWconst", argLength: 1, reg: gp11, asm: "ORW", aux: "Int32", resultInArg0: true, clobberFlags: true},                                              // arg0 | auxint
+		{name: "ORload", argLength: 3, reg: gpopload, asm: "OR", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},   // arg0 | *arg1. arg2=mem
+		{name: "ORWload", argLength: 3, reg: gpopload, asm: "ORW", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"}, // arg0 | *arg1. arg2=mem
+
+		{name: "XOR", argLength: 2, reg: gp21, asm: "XOR", commutative: true, clobberFlags: true},                                                                    // arg0 ^ arg1
+		{name: "XORW", argLength: 2, reg: gp21, asm: "XORW", commutative: true, clobberFlags: true},                                                                  // arg0 ^ arg1
+		{name: "XORconst", argLength: 1, reg: gp11, asm: "XOR", aux: "Int64", resultInArg0: true, clobberFlags: true},                                                // arg0 ^ auxint
+		{name: "XORWconst", argLength: 1, reg: gp11, asm: "XORW", aux: "Int32", resultInArg0: true, clobberFlags: true},                                              // arg0 ^ auxint
+		{name: "XORload", argLength: 3, reg: gpopload, asm: "XOR", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},   // arg0 ^ *arg1. arg2=mem
+		{name: "XORWload", argLength: 3, reg: gpopload, asm: "XORW", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"}, // arg0 ^ *arg1. arg2=mem
+
+		// Arithmetic ops with carry/borrow chain.
+		//
+		// A carry is represented by a condition code of 2 or 3 (GT or OV).
+		// A borrow is represented by a condition code of 0 or 1 (EQ or LT).
+		{name: "ADDC", argLength: 2, reg: gp21flags, asm: "ADDC", typ: "(UInt64,Flags)", commutative: true},                          // (arg0 + arg1, carry out)
+		{name: "ADDCconst", argLength: 1, reg: gp11flags, asm: "ADDC", typ: "(UInt64,Flags)", aux: "Int16"},                          // (arg0 + auxint, carry out)
+		{name: "ADDE", argLength: 3, reg: gp2flags1flags, asm: "ADDE", typ: "(UInt64,Flags)", commutative: true, resultInArg0: true}, // (arg0 + arg1 + arg2 (carry in), carry out)
+		{name: "SUBC", argLength: 2, reg: gp21flags, asm: "SUBC", typ: "(UInt64,Flags)"},                                             // (arg0 - arg1, borrow out)
+		{name: "SUBE", argLength: 3, reg: gp2flags1flags, asm: "SUBE", typ: "(UInt64,Flags)", resultInArg0: true},                    // (arg0 - arg1 - arg2 (borrow in), borrow out)
+
+		// Comparisons.
+		{name: "CMP", argLength: 2, reg: gp2flags, asm: "CMP", typ: "Flags"},   // arg0 compare to arg1
+		{name: "CMPW", argLength: 2, reg: gp2flags, asm: "CMPW", typ: "Flags"}, // arg0 compare to arg1
+
+		{name: "CMPU", argLength: 2, reg: gp2flags, asm: "CMPU", typ: "Flags"},   // arg0 compare to arg1
+		{name: "CMPWU", argLength: 2, reg: gp2flags, asm: "CMPWU", typ: "Flags"}, // arg0 compare to arg1
+
+		{name: "CMPconst", argLength: 1, reg: gp1flags, asm: "CMP", typ: "Flags", aux: "Int32"},     // arg0 compare to auxint
+		{name: "CMPWconst", argLength: 1, reg: gp1flags, asm: "CMPW", typ: "Flags", aux: "Int32"},   // arg0 compare to auxint
+		{name: "CMPUconst", argLength: 1, reg: gp1flags, asm: "CMPU", typ: "Flags", aux: "Int32"},   // arg0 compare to auxint
+		{name: "CMPWUconst", argLength: 1, reg: gp1flags, asm: "CMPWU", typ: "Flags", aux: "Int32"}, // arg0 compare to auxint
+
+		{name: "FCMPS", argLength: 2, reg: fp2flags, asm: "CEBR", typ: "Flags"},  // arg0 compare to arg1, f32
+		{name: "FCMP", argLength: 2, reg: fp2flags, asm: "FCMPU", typ: "Flags"},  // arg0 compare to arg1, f64
+		{name: "LTDBR", argLength: 1, reg: fp1flags, asm: "LTDBR", typ: "Flags"}, // arg0 compare to 0, f64
+		{name: "LTEBR", argLength: 1, reg: fp1flags, asm: "LTEBR", typ: "Flags"}, // arg0 compare to 0, f32
+
+		{name: "SLD", argLength: 2, reg: sh21, asm: "SLD"},                    // arg0 << arg1, shift amount is mod 64
+		{name: "SLW", argLength: 2, reg: sh21, asm: "SLW"},                    // arg0 << arg1, shift amount is mod 64
+		{name: "SLDconst", argLength: 1, reg: gp11, asm: "SLD", aux: "UInt8"}, // arg0 << auxint, shift amount 0-63
+		{name: "SLWconst", argLength: 1, reg: gp11, asm: "SLW", aux: "UInt8"}, // arg0 << auxint, shift amount 0-31
+
+		{name: "SRD", argLength: 2, reg: sh21, asm: "SRD"},                    // unsigned arg0 >> arg1, shift amount is mod 64
+		{name: "SRW", argLength: 2, reg: sh21, asm: "SRW"},                    // unsigned uint32(arg0) >> arg1, shift amount is mod 64
+		{name: "SRDconst", argLength: 1, reg: gp11, asm: "SRD", aux: "UInt8"}, // unsigned arg0 >> auxint, shift amount 0-63
+		{name: "SRWconst", argLength: 1, reg: gp11, asm: "SRW", aux: "UInt8"}, // unsigned uint32(arg0) >> auxint, shift amount 0-31
+
+		// Arithmetic shifts clobber flags.
+		{name: "SRAD", argLength: 2, reg: sh21, asm: "SRAD", clobberFlags: true},                    // signed arg0 >> arg1, shift amount is mod 64
+		{name: "SRAW", argLength: 2, reg: sh21, asm: "SRAW", clobberFlags: true},                    // signed int32(arg0) >> arg1, shift amount is mod 64
+		{name: "SRADconst", argLength: 1, reg: gp11, asm: "SRAD", aux: "UInt8", clobberFlags: true}, // signed arg0 >> auxint, shift amount 0-63
+		{name: "SRAWconst", argLength: 1, reg: gp11, asm: "SRAW", aux: "UInt8", clobberFlags: true}, // signed int32(arg0) >> auxint, shift amount 0-31
+
+		// Rotate instructions.
+		// Note: no RLLGconst - use RISBGZ instead.
+		{name: "RLLG", argLength: 2, reg: sh21, asm: "RLLG"},                  // arg0 rotate left arg1, rotate amount 0-63
+		{name: "RLL", argLength: 2, reg: sh21, asm: "RLL"},                    // arg0 rotate left arg1, rotate amount 0-31
+		{name: "RLLconst", argLength: 1, reg: gp11, asm: "RLL", aux: "UInt8"}, // arg0 rotate left auxint, rotate amount 0-31
+
+		// Rotate then (and|or|xor|insert) selected bits instructions.
+		//
+		// Aux is an s390x.RotateParams struct containing Start, End and rotation
+		// Amount fields.
+		//
+		// arg1 is rotated left by the rotation amount then the bits from the start
+		// bit to the end bit (inclusive) are combined with arg0 using the logical
+		// operation specified. Bit indices are specified from left to right - the
+		// MSB is 0 and the LSB is 63.
+		//
+		// Examples:
+		//               |          aux         |
+		// | instruction | start | end | amount |          arg0         |          arg1         |         result        |
+		// +-------------+-------+-----+--------+-----------------------+-----------------------+-----------------------+
+		// | RXSBG (XOR) |     0 |   1 |      0 | 0xffff_ffff_ffff_ffff | 0xffff_ffff_ffff_ffff | 0x3fff_ffff_ffff_ffff |
+		// | RXSBG (XOR) |    62 |  63 |      0 | 0xffff_ffff_ffff_ffff | 0xffff_ffff_ffff_ffff | 0xffff_ffff_ffff_fffc |
+		// | RXSBG (XOR) |     0 |  47 |     16 | 0xffff_ffff_ffff_ffff | 0x0000_0000_0000_ffff | 0xffff_ffff_0000_ffff |
+		// +-------------+-------+-----+--------+-----------------------+-----------------------+-----------------------+
+		//
+		{name: "RXSBG", argLength: 2, reg: gp21, asm: "RXSBG", resultInArg0: true, aux: "S390XRotateParams", clobberFlags: true}, // rotate then xor selected bits
+		{name: "RISBGZ", argLength: 1, reg: gp11, asm: "RISBGZ", aux: "S390XRotateParams", clobberFlags: true},                   // rotate then insert selected bits [into zero]
+
+		// unary ops
+		{name: "NEG", argLength: 1, reg: gp11, asm: "NEG", clobberFlags: true},   // -arg0
+		{name: "NEGW", argLength: 1, reg: gp11, asm: "NEGW", clobberFlags: true}, // -arg0
+
+		{name: "NOT", argLength: 1, reg: gp11, resultInArg0: true, clobberFlags: true},  // ^arg0
+		{name: "NOTW", argLength: 1, reg: gp11, resultInArg0: true, clobberFlags: true}, // ^arg0
+
+		{name: "FSQRT", argLength: 1, reg: fp11, asm: "FSQRT"},   // sqrt(arg0)
+		{name: "FSQRTS", argLength: 1, reg: fp11, asm: "FSQRTS"}, // sqrt(arg0), float32
+
+		// Conditional register-register moves.
+		// The aux for these values is an s390x.CCMask value representing the condition code mask.
+		{name: "LOCGR", argLength: 3, reg: gp2flags1, resultInArg0: true, asm: "LOCGR", aux: "S390XCCMask"}, // load arg1 into arg0 if the condition code in arg2 matches a masked bit in aux.
+
+		{name: "MOVBreg", argLength: 1, reg: gp11sp, asm: "MOVB", typ: "Int64"},    // sign extend arg0 from int8 to int64
+		{name: "MOVBZreg", argLength: 1, reg: gp11sp, asm: "MOVBZ", typ: "UInt64"}, // zero extend arg0 from int8 to int64
+		{name: "MOVHreg", argLength: 1, reg: gp11sp, asm: "MOVH", typ: "Int64"},    // sign extend arg0 from int16 to int64
+		{name: "MOVHZreg", argLength: 1, reg: gp11sp, asm: "MOVHZ", typ: "UInt64"}, // zero extend arg0 from int16 to int64
+		{name: "MOVWreg", argLength: 1, reg: gp11sp, asm: "MOVW", typ: "Int64"},    // sign extend arg0 from int32 to int64
+		{name: "MOVWZreg", argLength: 1, reg: gp11sp, asm: "MOVWZ", typ: "UInt64"}, // zero extend arg0 from int32 to int64
+
+		{name: "MOVDconst", reg: gp01, asm: "MOVD", typ: "UInt64", aux: "Int64", rematerializeable: true}, // auxint
+
+		{name: "LDGR", argLength: 1, reg: gpfp, asm: "LDGR"}, // move int64 to float64 (no conversion)
+		{name: "LGDR", argLength: 1, reg: fpgp, asm: "LGDR"}, // move float64 to int64 (no conversion)
+
+		{name: "CFDBRA", argLength: 1, reg: fpgp, asm: "CFDBRA", clobberFlags: true}, // convert float64 to int32
+		{name: "CGDBRA", argLength: 1, reg: fpgp, asm: "CGDBRA", clobberFlags: true}, // convert float64 to int64
+		{name: "CFEBRA", argLength: 1, reg: fpgp, asm: "CFEBRA", clobberFlags: true}, // convert float32 to int32
+		{name: "CGEBRA", argLength: 1, reg: fpgp, asm: "CGEBRA", clobberFlags: true}, // convert float32 to int64
+		{name: "CEFBRA", argLength: 1, reg: gpfp, asm: "CEFBRA", clobberFlags: true}, // convert int32 to float32
+		{name: "CDFBRA", argLength: 1, reg: gpfp, asm: "CDFBRA", clobberFlags: true}, // convert int32 to float64
+		{name: "CEGBRA", argLength: 1, reg: gpfp, asm: "CEGBRA", clobberFlags: true}, // convert int64 to float32
+		{name: "CDGBRA", argLength: 1, reg: gpfp, asm: "CDGBRA", clobberFlags: true}, // convert int64 to float64
+		{name: "CLFEBR", argLength: 1, reg: fpgp, asm: "CLFEBR", clobberFlags: true}, // convert float32 to uint32
+		{name: "CLFDBR", argLength: 1, reg: fpgp, asm: "CLFDBR", clobberFlags: true}, // convert float64 to uint32
+		{name: "CLGEBR", argLength: 1, reg: fpgp, asm: "CLGEBR", clobberFlags: true}, // convert float32 to uint64
+		{name: "CLGDBR", argLength: 1, reg: fpgp, asm: "CLGDBR", clobberFlags: true}, // convert float64 to uint64
+		{name: "CELFBR", argLength: 1, reg: gpfp, asm: "CELFBR", clobberFlags: true}, // convert uint32 to float32
+		{name: "CDLFBR", argLength: 1, reg: gpfp, asm: "CDLFBR", clobberFlags: true}, // convert uint32 to float64
+		{name: "CELGBR", argLength: 1, reg: gpfp, asm: "CELGBR", clobberFlags: true}, // convert uint64 to float32
+		{name: "CDLGBR", argLength: 1, reg: gpfp, asm: "CDLGBR", clobberFlags: true}, // convert uint64 to float64
+
+		{name: "LEDBR", argLength: 1, reg: fp11, asm: "LEDBR"}, // convert float64 to float32
+		{name: "LDEBR", argLength: 1, reg: fp11, asm: "LDEBR"}, // convert float32 to float64
+
+		{name: "MOVDaddr", argLength: 1, reg: addr, aux: "SymOff", rematerializeable: true, symEffect: "Read"}, // arg0 + auxint + offset encoded in aux
+		{name: "MOVDaddridx", argLength: 2, reg: addridx, aux: "SymOff", symEffect: "Read"},                    // arg0 + arg1 + auxint + aux
+
+		// auxint+aux == add auxint and the offset of the symbol in aux (if any) to the effective address
+		{name: "MOVBZload", argLength: 2, reg: gpload, asm: "MOVBZ", aux: "SymOff", typ: "UInt8", faultOnNilArg0: true, symEffect: "Read"},  // load byte from arg0+auxint+aux. arg1=mem.  Zero extend.
+		{name: "MOVBload", argLength: 2, reg: gpload, asm: "MOVB", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},                  // ditto, sign extend to int64
+		{name: "MOVHZload", argLength: 2, reg: gpload, asm: "MOVHZ", aux: "SymOff", typ: "UInt16", faultOnNilArg0: true, symEffect: "Read"}, // load 2 bytes from arg0+auxint+aux. arg1=mem.  Zero extend.
+		{name: "MOVHload", argLength: 2, reg: gpload, asm: "MOVH", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},                  // ditto, sign extend to int64
+		{name: "MOVWZload", argLength: 2, reg: gpload, asm: "MOVWZ", aux: "SymOff", typ: "UInt32", faultOnNilArg0: true, symEffect: "Read"}, // load 4 bytes from arg0+auxint+aux. arg1=mem.  Zero extend.
+		{name: "MOVWload", argLength: 2, reg: gpload, asm: "MOVW", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},                  // ditto, sign extend to int64
+		{name: "MOVDload", argLength: 2, reg: gpload, asm: "MOVD", aux: "SymOff", typ: "UInt64", faultOnNilArg0: true, symEffect: "Read"},   // load 8 bytes from arg0+auxint+aux. arg1=mem
+
+		{name: "MOVWBR", argLength: 1, reg: gp11, asm: "MOVWBR"}, // arg0 swap bytes
+		{name: "MOVDBR", argLength: 1, reg: gp11, asm: "MOVDBR"}, // arg0 swap bytes
+
+		{name: "MOVHBRload", argLength: 2, reg: gpload, asm: "MOVHBR", aux: "SymOff", typ: "UInt16", faultOnNilArg0: true, symEffect: "Read"}, // load 2 bytes from arg0+auxint+aux. arg1=mem. Reverse bytes.
+		{name: "MOVWBRload", argLength: 2, reg: gpload, asm: "MOVWBR", aux: "SymOff", typ: "UInt32", faultOnNilArg0: true, symEffect: "Read"}, // load 4 bytes from arg0+auxint+aux. arg1=mem. Reverse bytes.
+		{name: "MOVDBRload", argLength: 2, reg: gpload, asm: "MOVDBR", aux: "SymOff", typ: "UInt64", faultOnNilArg0: true, symEffect: "Read"}, // load 8 bytes from arg0+auxint+aux. arg1=mem. Reverse bytes.
+
+		{name: "MOVBstore", argLength: 3, reg: gpstore, asm: "MOVB", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},       // store byte in arg1 to arg0+auxint+aux. arg2=mem
+		{name: "MOVHstore", argLength: 3, reg: gpstore, asm: "MOVH", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},       // store 2 bytes in arg1 to arg0+auxint+aux. arg2=mem
+		{name: "MOVWstore", argLength: 3, reg: gpstore, asm: "MOVW", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},       // store 4 bytes in arg1 to arg0+auxint+aux. arg2=mem
+		{name: "MOVDstore", argLength: 3, reg: gpstore, asm: "MOVD", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},       // store 8 bytes in arg1 to arg0+auxint+aux. arg2=mem
+		{name: "MOVHBRstore", argLength: 3, reg: gpstorebr, asm: "MOVHBR", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 2 bytes in arg1 to arg0+auxint+aux. arg2=mem. Reverse bytes.
+		{name: "MOVWBRstore", argLength: 3, reg: gpstorebr, asm: "MOVWBR", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes in arg1 to arg0+auxint+aux. arg2=mem. Reverse bytes.
+		{name: "MOVDBRstore", argLength: 3, reg: gpstorebr, asm: "MOVDBR", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes in arg1 to arg0+auxint+aux. arg2=mem. Reverse bytes.
+
+		{name: "MVC", argLength: 3, reg: gpmvc, asm: "MVC", aux: "SymValAndOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, faultOnNilArg1: true, symEffect: "None"}, // arg0=destptr, arg1=srcptr, arg2=mem, auxint=size,off
+
+		// indexed loads/stores
+		{name: "MOVBZloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVBZ", aux: "SymOff", typ: "UInt8", symEffect: "Read"},   // load a byte from arg0+arg1+auxint+aux. arg2=mem. Zero extend.
+		{name: "MOVBloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVB", aux: "SymOff", typ: "Int8", symEffect: "Read"},      // load a byte from arg0+arg1+auxint+aux. arg2=mem. Sign extend.
+		{name: "MOVHZloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVHZ", aux: "SymOff", typ: "UInt16", symEffect: "Read"},  // load 2 bytes from arg0+arg1+auxint+aux. arg2=mem. Zero extend.
+		{name: "MOVHloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVH", aux: "SymOff", typ: "Int16", symEffect: "Read"},     // load 2 bytes from arg0+arg1+auxint+aux. arg2=mem. Sign extend.
+		{name: "MOVWZloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVWZ", aux: "SymOff", typ: "UInt32", symEffect: "Read"},  // load 4 bytes from arg0+arg1+auxint+aux. arg2=mem. Zero extend.
+		{name: "MOVWloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVW", aux: "SymOff", typ: "Int32", symEffect: "Read"},     // load 4 bytes from arg0+arg1+auxint+aux. arg2=mem. Sign extend.
+		{name: "MOVDloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVD", aux: "SymOff", typ: "UInt64", symEffect: "Read"},    // load 8 bytes from arg0+arg1+auxint+aux. arg2=mem
+		{name: "MOVHBRloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVHBR", aux: "SymOff", typ: "Int16", symEffect: "Read"}, // load 2 bytes from arg0+arg1+auxint+aux. arg2=mem. Reverse bytes.
+		{name: "MOVWBRloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVWBR", aux: "SymOff", typ: "Int32", symEffect: "Read"}, // load 4 bytes from arg0+arg1+auxint+aux. arg2=mem. Reverse bytes.
+		{name: "MOVDBRloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVDBR", aux: "SymOff", typ: "Int64", symEffect: "Read"}, // load 8 bytes from arg0+arg1+auxint+aux. arg2=mem. Reverse bytes.
+		{name: "MOVBstoreidx", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVB", aux: "SymOff", symEffect: "Write"},                // store byte in arg2 to arg0+arg1+auxint+aux. arg3=mem
+		{name: "MOVHstoreidx", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVH", aux: "SymOff", symEffect: "Write"},                // store 2 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem
+		{name: "MOVWstoreidx", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVW", aux: "SymOff", symEffect: "Write"},                // store 4 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem
+		{name: "MOVDstoreidx", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVD", aux: "SymOff", symEffect: "Write"},                // store 8 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem
+		{name: "MOVHBRstoreidx", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVHBR", aux: "SymOff", symEffect: "Write"},            // store 2 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem. Reverse bytes.
+		{name: "MOVWBRstoreidx", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVWBR", aux: "SymOff", symEffect: "Write"},            // store 4 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem. Reverse bytes.
+		{name: "MOVDBRstoreidx", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVDBR", aux: "SymOff", symEffect: "Write"},            // store 8 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem. Reverse bytes.
+
+		// For storeconst ops, the AuxInt field encodes both
+		// the value to store and an address offset of the store.
+		// Cast AuxInt to a ValAndOff to extract Val and Off fields.
+		{name: "MOVBstoreconst", argLength: 2, reg: gpstoreconst, asm: "MOVB", aux: "SymValAndOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store low byte of ValAndOff(AuxInt).Val() to arg0+ValAndOff(AuxInt).Off()+aux.  arg1=mem
+		{name: "MOVHstoreconst", argLength: 2, reg: gpstoreconst, asm: "MOVH", aux: "SymValAndOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store low 2 bytes of ...
+		{name: "MOVWstoreconst", argLength: 2, reg: gpstoreconst, asm: "MOVW", aux: "SymValAndOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store low 4 bytes of ...
+		{name: "MOVDstoreconst", argLength: 2, reg: gpstoreconst, asm: "MOVD", aux: "SymValAndOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes of ...
+
+		{name: "CLEAR", argLength: 2, reg: regInfo{inputs: []regMask{ptr, 0}}, asm: "CLEAR", aux: "SymValAndOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Write"},
+
+		{name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                                                // call static function aux.(*obj.LSym).  arg0=mem, auxint=argsize, returns mem
+		{name: "CALLtail", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true, tailCall: true},                                  // tail call static function aux.(*obj.LSym).  arg0=mem, auxint=argsize, returns mem
+		{name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{ptrsp, buildReg("R12"), 0}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call function via closure.  arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem
+		{name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{ptr}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                         // call fn by pointer.  arg0=codeptr, arg1=mem, auxint=argsize, returns mem
+
+		// (InvertFlags (CMP a b)) == (CMP b a)
+		// InvertFlags is a pseudo-op which can't appear in assembly output.
+		{name: "InvertFlags", argLength: 1}, // reverse direction of arg0
+
+		// Pseudo-ops
+		{name: "LoweredGetG", argLength: 1, reg: gp01}, // arg0=mem
+		// Scheduler ensures LoweredGetClosurePtr occurs only in entry block,
+		// and sorts it to the very beginning of the block to prevent other
+		// use of R12 (the closure pointer)
+		{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R12")}}, zeroWidth: true},
+		// arg0=ptr,arg1=mem, returns void.  Faults if ptr is nil.
+		// LoweredGetCallerSP returns the SP of the caller of the current function.
+		{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
+		// LoweredGetCallerPC evaluates to the PC to which its "caller" will return.
+		// I.e., if f calls g "calls" getcallerpc,
+		// the result should be the PC within f that g will return to.
+		// See runtime/stubs.go for a more detailed discussion.
+		{name: "LoweredGetCallerPC", reg: gp01, rematerializeable: true},
+		{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{ptrsp}}, clobberFlags: true, nilCheck: true, faultOnNilArg0: true},
+		// Round ops to block fused-multiply-add extraction.
+		{name: "LoweredRound32F", argLength: 1, reg: fp11, resultInArg0: true, zeroWidth: true},
+		{name: "LoweredRound64F", argLength: 1, reg: fp11, resultInArg0: true, zeroWidth: true},
+
+		// LoweredWB invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
+		// It saves all GP registers if necessary,
+		// but clobbers R14 (LR) because it's a call,
+		// and also clobbers R1 as the PLT stub does.
+		{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R2"), buildReg("R3")}, clobbers: (callerSave &^ gpg) | buildReg("R14") | r1}, clobberFlags: true, aux: "Sym", symEffect: "None"},
+
+		// There are three of these functions so that they can have three different register inputs.
+		// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the
+		// default registers to match so we don't need to copy registers around unnecessarily.
+		{name: "LoweredPanicBoundsA", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r2, r3}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
+		{name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r1, r2}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
+		{name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r0, r1}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
+
+		// Constant condition code values. The condition code can be 0, 1, 2 or 3.
+		{name: "FlagEQ"}, // CC=0 (equal)
+		{name: "FlagLT"}, // CC=1 (less than)
+		{name: "FlagGT"}, // CC=2 (greater than)
+		{name: "FlagOV"}, // CC=3 (overflow)
+
+		// Fast-BCR-serialization to ensure store-load ordering.
+		{name: "SYNC", argLength: 1, reg: sync, asm: "SYNC", typ: "Mem"},
+
+		// Atomic loads. These are just normal loads but return <value,memory> tuples
+		// so they can be properly ordered with other loads.
+		// load from arg0+auxint+aux.  arg1=mem.
+		{name: "MOVBZatomicload", argLength: 2, reg: gpload, asm: "MOVBZ", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},
+		{name: "MOVWZatomicload", argLength: 2, reg: gpload, asm: "MOVWZ", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},
+		{name: "MOVDatomicload", argLength: 2, reg: gpload, asm: "MOVD", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},
+
+		// Atomic stores. These are just normal stores.
+		// store arg1 to arg0+auxint+aux. arg2=mem.
+		{name: "MOVBatomicstore", argLength: 3, reg: gpstore, asm: "MOVB", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "Write"},
+		{name: "MOVWatomicstore", argLength: 3, reg: gpstore, asm: "MOVW", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "Write"},
+		{name: "MOVDatomicstore", argLength: 3, reg: gpstore, asm: "MOVD", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "Write"},
+
+		// Atomic adds.
+		// *(arg0+auxint+aux) += arg1.  arg2=mem.
+		// Returns a tuple of <old contents of *(arg0+auxint+aux), memory>.
+		{name: "LAA", argLength: 3, reg: gpstorelaa, asm: "LAA", typ: "(UInt32,Mem)", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "RdWr"},
+		{name: "LAAG", argLength: 3, reg: gpstorelaa, asm: "LAAG", typ: "(UInt64,Mem)", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "RdWr"},
+		{name: "AddTupleFirst32", argLength: 2}, // arg1=tuple <x,y>.  Returns <x+arg0,y>.
+		{name: "AddTupleFirst64", argLength: 2}, // arg1=tuple <x,y>.  Returns <x+arg0,y>.
+
+		// Atomic bitwise operations.
+		// Note: 'floor' operations round the pointer down to the nearest word boundary
+		// which reflects how they are used in the runtime.
+		{name: "LAN", argLength: 3, reg: gpstore, asm: "LAN", typ: "Mem", clobberFlags: true, hasSideEffects: true},         // *arg0 &= arg1. arg2 = mem.
+		{name: "LANfloor", argLength: 3, reg: gpstorelab, asm: "LAN", typ: "Mem", clobberFlags: true, hasSideEffects: true}, // *(floor(arg0, 4)) &= arg1. arg2 = mem.
+		{name: "LAO", argLength: 3, reg: gpstore, asm: "LAO", typ: "Mem", clobberFlags: true, hasSideEffects: true},         // *arg0 |= arg1. arg2 = mem.
+		{name: "LAOfloor", argLength: 3, reg: gpstorelab, asm: "LAO", typ: "Mem", clobberFlags: true, hasSideEffects: true}, // *(floor(arg0, 4)) |= arg1. arg2 = mem.
+
+		// Compare and swap.
+		// arg0 = pointer, arg1 = old value, arg2 = new value, arg3 = memory.
+		// if *(arg0+auxint+aux) == arg1 {
+		//   *(arg0+auxint+aux) = arg2
+		//   return (true, memory)
+		// } else {
+		//   return (false, memory)
+		// }
+		// Note that these instructions also return the old value in arg1, but we ignore it.
+		// TODO: have these return flags instead of bool.  The current system generates:
+		//    CS ...
+		//    MOVD  $0, ret
+		//    BNE   2(PC)
+		//    MOVD  $1, ret
+		//    CMPW  ret, $0
+		//    BNE ...
+		// instead of just
+		//    CS ...
+		//    BEQ ...
+		// but we can't do that because memory-using ops can't generate flags yet
+		// (flagalloc wants to move flag-generating instructions around).
+		{name: "LoweredAtomicCas32", argLength: 4, reg: cas, asm: "CS", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "RdWr"},
+		{name: "LoweredAtomicCas64", argLength: 4, reg: cas, asm: "CSG", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "RdWr"},
+
+		// Lowered atomic swaps, emulated using compare-and-swap.
+		// store arg1 to arg0+auxint+aux, arg2=mem.
+		{name: "LoweredAtomicExchange32", argLength: 3, reg: exchange, asm: "CS", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "RdWr"},
+		{name: "LoweredAtomicExchange64", argLength: 3, reg: exchange, asm: "CSG", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "RdWr"},
+
+		// find leftmost one
+		{
+			name:         "FLOGR",
+			argLength:    1,
+			reg:          regInfo{inputs: gponly, outputs: []regMask{buildReg("R0")}, clobbers: buildReg("R1")},
+			asm:          "FLOGR",
+			typ:          "UInt64",
+			clobberFlags: true,
+		},
+
+		// population count
+		//
+		// Counts the number of ones in each byte of arg0
+		// and places the result into the corresponding byte
+		// of the result.
+		{
+			name:         "POPCNT",
+			argLength:    1,
+			reg:          gp11,
+			asm:          "POPCNT",
+			typ:          "UInt64",
+			clobberFlags: true,
+		},
+
+		// unsigned multiplication (64x64 → 128)
+		//
+		// Multiply the two 64-bit input operands together and place the 128-bit result into
+		// an even-odd register pair. The second register in the target pair also contains
+		// one of the input operands. Since we don't currently have a way to specify an
+		// even-odd register pair we hardcode this register pair as R2:R3.
+		{
+			name:      "MLGR",
+			argLength: 2,
+			reg:       regInfo{inputs: []regMask{gp, r3}, outputs: []regMask{r2, r3}},
+			asm:       "MLGR",
+		},
+
+		// pseudo operations to sum the output of the POPCNT instruction
+		{name: "SumBytes2", argLength: 1, typ: "UInt8"}, // sum the rightmost 2 bytes in arg0 ignoring overflow
+		{name: "SumBytes4", argLength: 1, typ: "UInt8"}, // sum the rightmost 4 bytes in arg0 ignoring overflow
+		{name: "SumBytes8", argLength: 1, typ: "UInt8"}, // sum all the bytes in arg0 ignoring overflow
+
+		// store multiple
+		{
+			name:           "STMG2",
+			argLength:      4,
+			reg:            regInfo{inputs: []regMask{ptrsp, buildReg("R1"), buildReg("R2"), 0}},
+			aux:            "SymOff",
+			typ:            "Mem",
+			asm:            "STMG",
+			faultOnNilArg0: true,
+			symEffect:      "Write",
+			clobberFlags:   true, // TODO(mundaym): currently uses AGFI to handle large offsets
+		},
+		{
+			name:           "STMG3",
+			argLength:      5,
+			reg:            regInfo{inputs: []regMask{ptrsp, buildReg("R1"), buildReg("R2"), buildReg("R3"), 0}},
+			aux:            "SymOff",
+			typ:            "Mem",
+			asm:            "STMG",
+			faultOnNilArg0: true,
+			symEffect:      "Write",
+			clobberFlags:   true, // TODO(mundaym): currently uses AGFI to handle large offsets
+		},
+		{
+			name:      "STMG4",
+			argLength: 6,
+			reg: regInfo{inputs: []regMask{
+				ptrsp,
+				buildReg("R1"),
+				buildReg("R2"),
+				buildReg("R3"),
+				buildReg("R4"),
+				0,
+			}},
+			aux:            "SymOff",
+			typ:            "Mem",
+			asm:            "STMG",
+			faultOnNilArg0: true,
+			symEffect:      "Write",
+			clobberFlags:   true, // TODO(mundaym): currently uses AGFI to handle large offsets
+		},
+		{
+			name:           "STM2",
+			argLength:      4,
+			reg:            regInfo{inputs: []regMask{ptrsp, buildReg("R1"), buildReg("R2"), 0}},
+			aux:            "SymOff",
+			typ:            "Mem",
+			asm:            "STMY",
+			faultOnNilArg0: true,
+			symEffect:      "Write",
+			clobberFlags:   true, // TODO(mundaym): currently uses AGFI to handle large offsets
+		},
+		{
+			name:           "STM3",
+			argLength:      5,
+			reg:            regInfo{inputs: []regMask{ptrsp, buildReg("R1"), buildReg("R2"), buildReg("R3"), 0}},
+			aux:            "SymOff",
+			typ:            "Mem",
+			asm:            "STMY",
+			faultOnNilArg0: true,
+			symEffect:      "Write",
+			clobberFlags:   true, // TODO(mundaym): currently uses AGFI to handle large offsets
+		},
+		{
+			name:      "STM4",
+			argLength: 6,
+			reg: regInfo{inputs: []regMask{
+				ptrsp,
+				buildReg("R1"),
+				buildReg("R2"),
+				buildReg("R3"),
+				buildReg("R4"),
+				0,
+			}},
+			aux:            "SymOff",
+			typ:            "Mem",
+			asm:            "STMY",
+			faultOnNilArg0: true,
+			symEffect:      "Write",
+			clobberFlags:   true, // TODO(mundaym): currently uses AGFI to handle large offsets
+		},
+
+		// large move
+		// auxint = remaining bytes after loop (rem)
+		// arg0 = address of dst memory (in R1, changed as a side effect)
+		// arg1 = address of src memory (in R2, changed as a side effect)
+		// arg2 = pointer to last address to move in loop + 256
+		// arg3 = mem
+		// returns mem
+		//
+		// mvc: MVC  $256, 0(R2), 0(R1)
+		//      MOVD $256(R1), R1
+		//      MOVD $256(R2), R2
+		//      CMP  R2, Rarg2
+		//      BNE  mvc
+		//	MVC  $rem, 0(R2), 0(R1) // if rem > 0
+		{
+			name:      "LoweredMove",
+			aux:       "Int64",
+			argLength: 4,
+			reg: regInfo{
+				inputs:   []regMask{buildReg("R1"), buildReg("R2"), gpsp},
+				clobbers: buildReg("R1 R2"),
+			},
+			clobberFlags:   true,
+			typ:            "Mem",
+			faultOnNilArg0: true,
+			faultOnNilArg1: true,
+		},
+
+		// large clear
+		// auxint = remaining bytes after loop (rem)
+		// arg0 = address of dst memory (in R1, changed as a side effect)
+		// arg1 = pointer to last address to zero in loop + 256
+		// arg2 = mem
+		// returns mem
+		//
+		// clear: CLEAR $256, 0(R1)
+		//        MOVD  $256(R1), R1
+		//        CMP   R1, Rarg2
+		//        BNE   clear
+		//	  CLEAR $rem, 0(R1) // if rem > 0
+		{
+			name:      "LoweredZero",
+			aux:       "Int64",
+			argLength: 3,
+			reg: regInfo{
+				inputs:   []regMask{buildReg("R1"), gpsp},
+				clobbers: buildReg("R1"),
+			},
+			clobberFlags:   true,
+			typ:            "Mem",
+			faultOnNilArg0: true,
+		},
+	}
+
+	// All blocks on s390x have their condition code mask (s390x.CCMask) as the Aux value.
+	// The condition code mask is a 4-bit mask where each bit corresponds to a condition
+	// code value. If the value of the condition code matches a bit set in the condition
+	// code mask then the first successor is executed. Otherwise the second successor is
+	// executed.
+	//
+	// | condition code value |  mask bit  |
+	// +----------------------+------------+
+	// | 0 (equal)            | 0b1000 (8) |
+	// | 1 (less than)        | 0b0100 (4) |
+	// | 2 (greater than)     | 0b0010 (2) |
+	// | 3 (unordered)        | 0b0001 (1) |
+	//
+	// Note: that compare-and-branch instructions must not have bit 3 (0b0001) set.
+	var S390Xblocks = []blockData{
+		// branch on condition
+		{name: "BRC", controls: 1, aux: "S390XCCMask"}, // condition code value (flags) is Controls[0]
+
+		// compare-and-branch (register-register)
+		//  - integrates comparison of Controls[0] with Controls[1]
+		//  - both control values must be in general purpose registers
+		{name: "CRJ", controls: 2, aux: "S390XCCMask"},   // signed 32-bit integer comparison
+		{name: "CGRJ", controls: 2, aux: "S390XCCMask"},  // signed 64-bit integer comparison
+		{name: "CLRJ", controls: 2, aux: "S390XCCMask"},  // unsigned 32-bit integer comparison
+		{name: "CLGRJ", controls: 2, aux: "S390XCCMask"}, // unsigned 64-bit integer comparison
+
+		// compare-and-branch (register-immediate)
+		//  - integrates comparison of Controls[0] with AuxInt
+		//  - control value must be in a general purpose register
+		//  - the AuxInt value is sign-extended for signed comparisons
+		//    and zero-extended for unsigned comparisons
+		{name: "CIJ", controls: 1, aux: "S390XCCMaskInt8"},    // signed 32-bit integer comparison
+		{name: "CGIJ", controls: 1, aux: "S390XCCMaskInt8"},   // signed 64-bit integer comparison
+		{name: "CLIJ", controls: 1, aux: "S390XCCMaskUint8"},  // unsigned 32-bit integer comparison
+		{name: "CLGIJ", controls: 1, aux: "S390XCCMaskUint8"}, // unsigned 64-bit integer comparison
+	}
+
+	archs = append(archs, arch{
+		name:            "S390X",
+		pkg:             "cmd/internal/obj/s390x",
+		genfile:         "../../s390x/ssa.go",
+		ops:             S390Xops,
+		blocks:          S390Xblocks,
+		regnames:        regNamesS390X,
+		gpregmask:       gp,
+		fpregmask:       fp,
+		framepointerreg: -1, // not used
+		linkreg:         int8(num["R14"]),
+		imports: []string{
+			"cmd/internal/obj/s390x",
+		},
+	})
+}
diff --git a/src/cmd/compile/internal/ssa/_gen/Wasm.rules b/src/cmd/compile/internal/ssa/_gen/Wasm.rules
new file mode 100644
index 0000000..a9ed82e
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/_gen/Wasm.rules
@@ -0,0 +1,396 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Lowering arithmetic
+(Add(64|32|16|8|Ptr) ...) => (I64Add ...)
+(Add(64|32)F ...) => (F(64|32)Add ...)
+
+(Sub(64|32|16|8|Ptr) ...) => (I64Sub ...)
+(Sub(64|32)F ...) => (F(64|32)Sub ...)
+
+(Mul(64|32|16|8) ...) => (I64Mul ...)
+(Mul(64|32)F ...) => (F(64|32)Mul ...)
+
+(Div64 [false] x y) => (I64DivS x y)
+(Div32 [false] x y) => (I64DivS (SignExt32to64 x) (SignExt32to64 y))
+(Div16 [false] x y) => (I64DivS (SignExt16to64 x) (SignExt16to64 y))
+(Div8          x y) => (I64DivS (SignExt8to64 x) (SignExt8to64 y))
+(Div64u ...) => (I64DivU ...)
+(Div32u x y) => (I64DivU (ZeroExt32to64 x) (ZeroExt32to64 y))
+(Div16u x y) => (I64DivU (ZeroExt16to64 x) (ZeroExt16to64 y))
+(Div8u  x y) => (I64DivU (ZeroExt8to64 x) (ZeroExt8to64 y))
+(Div(64|32)F ...) => (F(64|32)Div ...)
+
+(Mod64 [false] x y) => (I64RemS x y)
+(Mod32 [false] x y) => (I64RemS (SignExt32to64 x) (SignExt32to64 y))
+(Mod16 [false] x y) => (I64RemS (SignExt16to64 x) (SignExt16to64 y))
+(Mod8          x y) => (I64RemS (SignExt8to64  x) (SignExt8to64  y))
+(Mod64u ...) => (I64RemU ...)
+(Mod32u x y) => (I64RemU (ZeroExt32to64 x) (ZeroExt32to64 y))
+(Mod16u x y) => (I64RemU (ZeroExt16to64 x) (ZeroExt16to64 y))
+(Mod8u  x y) => (I64RemU (ZeroExt8to64  x) (ZeroExt8to64  y))
+
+(And(64|32|16|8|B) ...) => (I64And ...)
+
+(Or(64|32|16|8|B) ...) => (I64Or ...)
+
+(Xor(64|32|16|8) ...) => (I64Xor ...)
+
+(Neg(64|32|16|8) x) => (I64Sub (I64Const [0]) x)
+(Neg(64|32)F ...) => (F(64|32)Neg ...)
+
+(Com(64|32|16|8) x) => (I64Xor x (I64Const [-1]))
+
+(Not ...) => (I64Eqz ...)
+
+// Lowering pointer arithmetic
+(OffPtr ...) => (I64AddConst ...)
+
+// Lowering extension
+// It is unnecessary to extend loads
+(SignExt32to64        x:(I64Load32S _ _)) => x
+(SignExt16to(64|32)   x:(I64Load16S _ _)) => x
+(SignExt8to(64|32|16) x:(I64Load8S  _ _)) => x
+(ZeroExt32to64        x:(I64Load32U _ _)) => x
+(ZeroExt16to(64|32)   x:(I64Load16U _ _)) => x
+(ZeroExt8to(64|32|16) x:(I64Load8U  _ _)) => x
+(SignExt32to64        x) && buildcfg.GOWASM.SignExt => (I64Extend32S x)
+(SignExt8to(64|32|16) x) && buildcfg.GOWASM.SignExt => (I64Extend8S x)
+(SignExt16to(64|32)   x) && buildcfg.GOWASM.SignExt => (I64Extend16S x)
+(SignExt32to64        x) => (I64ShrS (I64Shl x (I64Const [32])) (I64Const [32]))
+(SignExt16to(64|32)   x) => (I64ShrS (I64Shl x (I64Const [48])) (I64Const [48]))
+(SignExt8to(64|32|16) x) => (I64ShrS (I64Shl x (I64Const [56])) (I64Const [56]))
+(ZeroExt32to64        x) => (I64And x (I64Const [0xffffffff]))
+(ZeroExt16to(64|32)   x) => (I64And x (I64Const [0xffff]))
+(ZeroExt8to(64|32|16) x) => (I64And x (I64Const [0xff]))
+
+(Slicemask x) => (I64ShrS (I64Sub (I64Const [0]) x) (I64Const [63]))
+
+// Lowering truncation
+// Because we ignore the high parts, truncates are just copies.
+(Trunc64to(32|16|8) ...) => (Copy ...)
+(Trunc32to(16|8)    ...) => (Copy ...)
+(Trunc16to8         ...) => (Copy ...)
+
+// Lowering float <=> int
+(Cvt32to(64|32)F x) => (F(64|32)ConvertI64S (SignExt32to64 x))
+(Cvt64to(64|32)F ...) => (F(64|32)ConvertI64S ...)
+(Cvt32Uto(64|32)F x) => (F(64|32)ConvertI64U (ZeroExt32to64 x))
+(Cvt64Uto(64|32)F ...) => (F(64|32)ConvertI64U ...)
+
+(Cvt32Fto32 ...) => (I64TruncSatF32S ...)
+(Cvt32Fto64 ...) => (I64TruncSatF32S ...)
+(Cvt64Fto32 ...) => (I64TruncSatF64S ...)
+(Cvt64Fto64 ...) => (I64TruncSatF64S ...)
+(Cvt32Fto32U ...) => (I64TruncSatF32U ...)
+(Cvt32Fto64U ...) => (I64TruncSatF32U ...)
+(Cvt64Fto32U ...) => (I64TruncSatF64U ...)
+(Cvt64Fto64U ...) => (I64TruncSatF64U ...)
+
+(Cvt32Fto64F ...) => (F64PromoteF32 ...)
+(Cvt64Fto32F ...) => (F32DemoteF64 ...)
+
+(CvtBoolToUint8 ...) => (Copy ...)
+
+(Round32F ...) => (Copy ...)
+(Round64F ...) => (Copy ...)
+
+// Lowering shifts
+// Unsigned shifts need to return 0 if shift amount is >= width of shifted value.
+
+(Lsh64x64 x y) && shiftIsBounded(v) => (I64Shl x y)
+(Lsh64x64 x (I64Const [c])) && uint64(c) < 64 => (I64Shl x (I64Const [c]))
+(Lsh64x64 x (I64Const [c])) && uint64(c) >= 64 => (I64Const [0])
+(Lsh64x64 x y) => (Select (I64Shl x y) (I64Const [0]) (I64LtU y (I64Const [64])))
+(Lsh64x(32|16|8) [c] x y) => (Lsh64x64 [c] x (ZeroExt(32|16|8)to64 y))
+
+(Lsh32x64 ...) => (Lsh64x64 ...)
+(Lsh32x(32|16|8) [c] x y) => (Lsh64x64 [c] x (ZeroExt(32|16|8)to64 y))
+
+(Lsh16x64 ...) => (Lsh64x64 ...)
+(Lsh16x(32|16|8) [c] x y) => (Lsh64x64 [c] x (ZeroExt(32|16|8)to64 y))
+
+(Lsh8x64 ...) => (Lsh64x64 ...)
+(Lsh8x(32|16|8) [c] x y) => (Lsh64x64 [c] x (ZeroExt(32|16|8)to64 y))
+
+(Rsh64Ux64 x y) && shiftIsBounded(v) => (I64ShrU x y)
+(Rsh64Ux64 x (I64Const [c])) && uint64(c) < 64 => (I64ShrU x (I64Const [c]))
+(Rsh64Ux64 x (I64Const [c])) && uint64(c) >= 64 => (I64Const [0])
+(Rsh64Ux64 x y) => (Select (I64ShrU x y) (I64Const [0]) (I64LtU y (I64Const [64])))
+(Rsh64Ux(32|16|8) [c] x y) => (Rsh64Ux64 [c] x (ZeroExt(32|16|8)to64 y))
+
+(Rsh32Ux64 [c] x y) => (Rsh64Ux64 [c] (ZeroExt32to64 x) y)
+(Rsh32Ux(32|16|8) [c] x y) => (Rsh64Ux64 [c] (ZeroExt32to64 x) (ZeroExt(32|16|8)to64 y))
+
+(Rsh16Ux64 [c] x y) => (Rsh64Ux64 [c] (ZeroExt16to64 x) y)
+(Rsh16Ux(32|16|8) [c] x y) => (Rsh64Ux64 [c] (ZeroExt16to64 x) (ZeroExt(32|16|8)to64 y))
+
+(Rsh8Ux64 [c] x y) => (Rsh64Ux64 [c] (ZeroExt8to64 x) y)
+(Rsh8Ux(32|16|8) [c] x y) => (Rsh64Ux64 [c] (ZeroExt8to64 x) (ZeroExt(32|16|8)to64 y))
+
+// Signed right shift needs to return 0/-1 if shift amount is >= width of shifted value.
+// We implement this by setting the shift value to (width - 1) if the shift value is >= width.
+
+(Rsh64x64 x y) && shiftIsBounded(v) => (I64ShrS x y)
+(Rsh64x64 x (I64Const [c])) && uint64(c) < 64 => (I64ShrS x (I64Const [c]))
+(Rsh64x64 x (I64Const [c])) && uint64(c) >= 64 => (I64ShrS x (I64Const [63]))
+(Rsh64x64 x y) => (I64ShrS x (Select <typ.Int64> y (I64Const [63]) (I64LtU y (I64Const [64]))))
+(Rsh64x(32|16|8) [c] x y) => (Rsh64x64 [c] x (ZeroExt(32|16|8)to64 y))
+
+(Rsh32x64 [c] x y) => (Rsh64x64 [c] (SignExt32to64 x) y)
+(Rsh32x(32|16|8) [c] x y) => (Rsh64x64 [c] (SignExt32to64 x) (ZeroExt(32|16|8)to64 y))
+
+(Rsh16x64 [c] x y) => (Rsh64x64 [c] (SignExt16to64 x) y)
+(Rsh16x(32|16|8) [c] x y) => (Rsh64x64 [c] (SignExt16to64 x) (ZeroExt(32|16|8)to64 y))
+
+(Rsh8x64 [c] x y)  => (Rsh64x64 [c] (SignExt8to64 x) y)
+(Rsh8x(32|16|8) [c] x y)  => (Rsh64x64 [c] (SignExt8to64 x) (ZeroExt(32|16|8)to64 y))
+
+// Lowering rotates
+(RotateLeft8 <t> x (I64Const [c])) => (Or8 (Lsh8x64 <t> x (I64Const [c&7])) (Rsh8Ux64 <t> x (I64Const [-c&7])))
+(RotateLeft16 <t> x (I64Const [c])) => (Or16 (Lsh16x64 <t> x (I64Const [c&15])) (Rsh16Ux64 <t> x (I64Const [-c&15])))
+(RotateLeft32 ...) => (I32Rotl ...)
+(RotateLeft64 ...) => (I64Rotl ...)
+
+// Lowering comparisons
+(Less64  ...) => (I64LtS ...)
+(Less32  x y) => (I64LtS (SignExt32to64 x) (SignExt32to64 y))
+(Less16  x y) => (I64LtS (SignExt16to64 x) (SignExt16to64 y))
+(Less8   x y) => (I64LtS (SignExt8to64  x) (SignExt8to64  y))
+(Less64U ...) => (I64LtU ...)
+(Less32U x y) => (I64LtU (ZeroExt32to64 x) (ZeroExt32to64 y))
+(Less16U x y) => (I64LtU (ZeroExt16to64 x) (ZeroExt16to64 y))
+(Less8U  x y) => (I64LtU (ZeroExt8to64  x) (ZeroExt8to64  y))
+(Less(64|32)F ...) => (F(64|32)Lt ...)
+
+(Leq64  ...) => (I64LeS ...)
+(Leq32  x y) => (I64LeS (SignExt32to64 x) (SignExt32to64 y))
+(Leq16  x y) => (I64LeS (SignExt16to64 x) (SignExt16to64 y))
+(Leq8   x y) => (I64LeS (SignExt8to64  x) (SignExt8to64  y))
+(Leq64U ...) => (I64LeU ...)
+(Leq32U x y) => (I64LeU (ZeroExt32to64 x) (ZeroExt32to64 y))
+(Leq16U x y) => (I64LeU (ZeroExt16to64 x) (ZeroExt16to64 y))
+(Leq8U  x y) => (I64LeU (ZeroExt8to64  x) (ZeroExt8to64  y))
+(Leq(64|32)F ...) => (F(64|32)Le ...)
+
+(Eq64  ...) => (I64Eq ...)
+(Eq32  x y) => (I64Eq (ZeroExt32to64 x) (ZeroExt32to64 y))
+(Eq16  x y) => (I64Eq (ZeroExt16to64 x) (ZeroExt16to64 y))
+(Eq8   x y) => (I64Eq (ZeroExt8to64  x) (ZeroExt8to64  y))
+(EqB   ...) => (I64Eq ...)
+(EqPtr ...) => (I64Eq ...)
+(Eq(64|32)F ...) => (F(64|32)Eq ...)
+
+(Neq64  ...) => (I64Ne ...)
+(Neq32  x y) => (I64Ne (ZeroExt32to64 x) (ZeroExt32to64 y))
+(Neq16  x y) => (I64Ne (ZeroExt16to64 x) (ZeroExt16to64 y))
+(Neq8   x y) => (I64Ne (ZeroExt8to64  x) (ZeroExt8to64  y))
+(NeqB   ...) => (I64Ne ...)
+(NeqPtr ...) => (I64Ne ...)
+(Neq(64|32)F ...) => (F(64|32)Ne ...)
+
+// Lowering loads
+(Load <t> ptr mem) && is32BitFloat(t) => (F32Load ptr mem)
+(Load <t> ptr mem) && is64BitFloat(t) => (F64Load ptr mem)
+(Load <t> ptr mem) && t.Size() == 8 => (I64Load ptr mem)
+(Load <t> ptr mem) && t.Size() == 4 && !t.IsSigned() => (I64Load32U ptr mem)
+(Load <t> ptr mem) && t.Size() == 4 &&  t.IsSigned() => (I64Load32S ptr mem)
+(Load <t> ptr mem) && t.Size() == 2 && !t.IsSigned() => (I64Load16U ptr mem)
+(Load <t> ptr mem) && t.Size() == 2 &&  t.IsSigned() => (I64Load16S ptr mem)
+(Load <t> ptr mem) && t.Size() == 1 && !t.IsSigned() => (I64Load8U ptr mem)
+(Load <t> ptr mem) && t.Size() == 1 &&  t.IsSigned() => (I64Load8S ptr mem)
+
+// Lowering stores
+(Store {t} ptr val mem) && is64BitFloat(t) => (F64Store ptr val mem)
+(Store {t} ptr val mem) && is32BitFloat(t) => (F32Store ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 8 => (I64Store ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 4 => (I64Store32 ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 2 => (I64Store16 ptr val mem)
+(Store {t} ptr val mem) && t.Size() == 1 => (I64Store8 ptr val mem)
+
+// Lowering moves
+(Move [0] _ _ mem) => mem
+(Move [1] dst src mem) => (I64Store8 dst (I64Load8U src mem) mem)
+(Move [2] dst src mem) => (I64Store16 dst (I64Load16U src mem) mem)
+(Move [4] dst src mem) => (I64Store32 dst (I64Load32U src mem) mem)
+(Move [8] dst src mem) => (I64Store dst (I64Load src mem) mem)
+(Move [16] dst src mem) =>
+	(I64Store [8] dst (I64Load [8] src mem)
+		(I64Store dst (I64Load src mem) mem))
+(Move [3] dst src mem) =>
+	(I64Store8 [2] dst (I64Load8U [2] src mem)
+		(I64Store16 dst (I64Load16U src mem) mem))
+(Move [5] dst src mem) =>
+	(I64Store8 [4] dst (I64Load8U [4] src mem)
+		(I64Store32 dst (I64Load32U src mem) mem))
+(Move [6] dst src mem) =>
+	(I64Store16 [4] dst (I64Load16U [4] src mem)
+		(I64Store32 dst (I64Load32U src mem) mem))
+(Move [7] dst src mem) =>
+	(I64Store32 [3] dst (I64Load32U [3] src mem)
+		(I64Store32 dst (I64Load32U src mem) mem))
+(Move [s] dst src mem) && s > 8 && s < 16 =>
+	(I64Store [s-8] dst (I64Load [s-8] src mem)
+		(I64Store dst (I64Load src mem) mem))
+
+// Large copying uses helper.
+(Move [s] dst src mem) && logLargeCopy(v, s) =>
+	(LoweredMove [s] dst src mem)
+
+// Lowering Zero instructions
+(Zero [0] _ mem) => mem
+(Zero [1] destptr mem) => (I64Store8 destptr (I64Const [0]) mem)
+(Zero [2] destptr mem) => (I64Store16 destptr (I64Const [0]) mem)
+(Zero [4] destptr mem) => (I64Store32 destptr (I64Const [0]) mem)
+(Zero [8] destptr mem) => (I64Store destptr (I64Const [0]) mem)
+
+(Zero [3] destptr mem) =>
+	(I64Store8 [2] destptr (I64Const [0])
+		(I64Store16 destptr (I64Const [0]) mem))
+(Zero [5] destptr mem) =>
+	(I64Store8 [4] destptr (I64Const [0])
+		(I64Store32 destptr (I64Const [0]) mem))
+(Zero [6] destptr mem) =>
+	(I64Store16 [4] destptr (I64Const [0])
+		(I64Store32 destptr (I64Const [0]) mem))
+(Zero [7] destptr mem) =>
+	(I64Store32 [3] destptr (I64Const [0])
+		(I64Store32 destptr (I64Const [0]) mem))
+
+// Strip off any fractional word zeroing.
+(Zero [s] destptr mem) && s%8 != 0 && s > 8 && s < 32 =>
+	(Zero [s-s%8] (OffPtr <destptr.Type> destptr [s%8])
+		(I64Store destptr (I64Const [0]) mem))
+
+// Zero small numbers of words directly.
+(Zero [16] destptr mem) =>
+	(I64Store [8] destptr (I64Const [0])
+		(I64Store destptr (I64Const [0]) mem))
+(Zero [24] destptr mem) =>
+	(I64Store [16] destptr (I64Const [0])
+		(I64Store [8] destptr (I64Const [0])
+			(I64Store destptr (I64Const [0]) mem)))
+(Zero [32] destptr mem) =>
+	(I64Store [24] destptr (I64Const [0])
+		(I64Store [16] destptr (I64Const [0])
+			(I64Store [8] destptr (I64Const [0])
+				(I64Store destptr (I64Const [0]) mem))))
+
+// Large zeroing uses helper.
+(Zero [s] destptr mem) =>
+	(LoweredZero [s] destptr mem)
+
+// Lowering constants
+(Const64 ...) => (I64Const ...)
+(Const(32|16|8) [c]) => (I64Const [int64(c)])
+(Const(64|32)F ...) => (F(64|32)Const ...)
+(ConstNil) => (I64Const [0])
+(ConstBool [c]) => (I64Const [b2i(c)])
+
+// Lowering calls
+(StaticCall ...) => (LoweredStaticCall ...)
+(ClosureCall ...) => (LoweredClosureCall ...)
+(InterCall ...) => (LoweredInterCall ...)
+(TailCall ...) => (LoweredTailCall ...)
+
+// Miscellaneous
+(Convert ...) => (LoweredConvert ...)
+(IsNonNil p) => (I64Eqz (I64Eqz p))
+(IsInBounds ...) => (I64LtU ...)
+(IsSliceInBounds ...) => (I64LeU ...)
+(NilCheck ...) => (LoweredNilCheck ...)
+(GetClosurePtr ...) => (LoweredGetClosurePtr ...)
+(GetCallerPC ...) => (LoweredGetCallerPC ...)
+(GetCallerSP ...) => (LoweredGetCallerSP ...)
+(Addr {sym} base) => (LoweredAddr {sym} [0] base)
+(LocalAddr {sym} base _) => (LoweredAddr {sym} base)
+
+// Write barrier.
+(WB ...) => (LoweredWB ...)
+
+// --- Intrinsics ---
+(Sqrt ...) => (F64Sqrt ...)
+(Trunc ...) => (F64Trunc ...)
+(Ceil ...) => (F64Ceil ...)
+(Floor ...) => (F64Floor ...)
+(RoundToEven ...) => (F64Nearest ...)
+(Abs ...) => (F64Abs ...)
+(Copysign ...) => (F64Copysign ...)
+
+(Sqrt32 ...) => (F32Sqrt ...)
+
+(Ctz64 ...) => (I64Ctz ...)
+(Ctz32 x) => (I64Ctz (I64Or x (I64Const [0x100000000])))
+(Ctz16 x) => (I64Ctz (I64Or x (I64Const [0x10000])))
+(Ctz8  x) => (I64Ctz (I64Or x (I64Const [0x100])))
+
+(Ctz(64|32|16|8)NonZero ...) => (I64Ctz ...)
+
+(BitLen64 x) => (I64Sub (I64Const [64]) (I64Clz x))
+
+(PopCount64 ...) => (I64Popcnt ...)
+(PopCount32 x) => (I64Popcnt (ZeroExt32to64 x))
+(PopCount16 x) => (I64Popcnt (ZeroExt16to64 x))
+(PopCount8  x) => (I64Popcnt (ZeroExt8to64  x))
+
+(CondSelect ...) => (Select ...)
+
+// --- Optimizations ---
+(I64Add (I64Const [x]) (I64Const [y])) => (I64Const [x + y])
+(I64Mul (I64Const [x]) (I64Const [y])) => (I64Const [x * y])
+(I64And (I64Const [x]) (I64Const [y])) => (I64Const [x & y])
+(I64Or  (I64Const [x]) (I64Const [y])) => (I64Const [x | y])
+(I64Xor (I64Const [x]) (I64Const [y])) => (I64Const [x ^ y])
+(F64Add (F64Const [x]) (F64Const [y])) => (F64Const [x + y])
+(F64Mul (F64Const [x]) (F64Const [y])) && !math.IsNaN(x * y) => (F64Const [x * y])
+(I64Eq  (I64Const [x]) (I64Const [y])) && x == y => (I64Const [1])
+(I64Eq  (I64Const [x]) (I64Const [y])) && x != y => (I64Const [0])
+(I64Ne  (I64Const [x]) (I64Const [y])) && x == y => (I64Const [0])
+(I64Ne  (I64Const [x]) (I64Const [y])) && x != y => (I64Const [1])
+
+(I64Shl (I64Const [x]) (I64Const [y])) => (I64Const [x << uint64(y)])
+(I64ShrU (I64Const [x]) (I64Const [y])) => (I64Const [int64(uint64(x) >> uint64(y))])
+(I64ShrS (I64Const [x]) (I64Const [y])) => (I64Const [x >> uint64(y)])
+
+// TODO: declare these operations as commutative and get rid of these rules?
+(I64Add (I64Const [x]) y) && y.Op != OpWasmI64Const => (I64Add y (I64Const [x]))
+(I64Mul (I64Const [x]) y) && y.Op != OpWasmI64Const => (I64Mul y (I64Const [x]))
+(I64And (I64Const [x]) y) && y.Op != OpWasmI64Const => (I64And y (I64Const [x]))
+(I64Or  (I64Const [x]) y) && y.Op != OpWasmI64Const => (I64Or  y (I64Const [x]))
+(I64Xor (I64Const [x]) y) && y.Op != OpWasmI64Const => (I64Xor y (I64Const [x]))
+(F64Add (F64Const [x]) y) && y.Op != OpWasmF64Const => (F64Add y (F64Const [x]))
+(F64Mul (F64Const [x]) y) && y.Op != OpWasmF64Const => (F64Mul y (F64Const [x]))
+(I64Eq  (I64Const [x]) y) && y.Op != OpWasmI64Const => (I64Eq y  (I64Const [x]))
+(I64Ne  (I64Const [x]) y) && y.Op != OpWasmI64Const => (I64Ne y  (I64Const [x]))
+
+(I64Eq x (I64Const [0])) => (I64Eqz x)
+(I64LtU (I64Const [0]) x) => (I64Eqz (I64Eqz x))
+(I64LeU x (I64Const [0])) => (I64Eqz x)
+(I64LtU x (I64Const [1])) => (I64Eqz x)
+(I64LeU (I64Const [1]) x) => (I64Eqz (I64Eqz x))
+(I64Ne x (I64Const [0])) => (I64Eqz (I64Eqz x))
+
+(I64Add x (I64Const [y])) => (I64AddConst [y] x)
+(I64AddConst [0] x) => x
+(I64Eqz (I64Eqz (I64Eqz x))) => (I64Eqz x)
+
+// folding offset into load/store
+((I64Load|I64Load32U|I64Load32S|I64Load16U|I64Load16S|I64Load8U|I64Load8S) [off] (I64AddConst [off2] ptr) mem)
+	&& isU32Bit(off+off2) =>
+	((I64Load|I64Load32U|I64Load32S|I64Load16U|I64Load16S|I64Load8U|I64Load8S) [off+off2] ptr mem)
+
+((I64Store|I64Store32|I64Store16|I64Store8) [off] (I64AddConst [off2] ptr) val mem)
+	&& isU32Bit(off+off2) =>
+	((I64Store|I64Store32|I64Store16|I64Store8) [off+off2] ptr val mem)
+
+// folding offset into address
+(I64AddConst [off] (LoweredAddr {sym} [off2] base)) && isU32Bit(off+int64(off2)) =>
+	(LoweredAddr {sym} [int32(off)+off2] base)
+(I64AddConst [off] x:(SP)) && isU32Bit(off) => (LoweredAddr [int32(off)] x) // so it is rematerializeable
+
+// transforming readonly globals into constants
+(I64Load [off] (LoweredAddr {sym} [off2] (SB)) _) && symIsRO(sym) && isU32Bit(off+int64(off2)) => (I64Const [int64(read64(sym, off+int64(off2), config.ctxt.Arch.ByteOrder))])
+(I64Load32U [off] (LoweredAddr {sym} [off2] (SB)) _) && symIsRO(sym) && isU32Bit(off+int64(off2)) => (I64Const [int64(read32(sym, off+int64(off2), config.ctxt.Arch.ByteOrder))])
+(I64Load16U [off] (LoweredAddr {sym} [off2] (SB)) _) && symIsRO(sym) && isU32Bit(off+int64(off2)) => (I64Const [int64(read16(sym, off+int64(off2), config.ctxt.Arch.ByteOrder))])
+(I64Load8U [off] (LoweredAddr {sym} [off2] (SB)) _) && symIsRO(sym) && isU32Bit(off+int64(off2)) => (I64Const [int64(read8(sym, off+int64(off2)))])
diff --git a/src/cmd/compile/internal/ssa/_gen/WasmOps.go b/src/cmd/compile/internal/ssa/_gen/WasmOps.go
new file mode 100644
index 0000000..cd127b5
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/_gen/WasmOps.go
@@ -0,0 +1,277 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "strings"
+
+var regNamesWasm = []string{
+	"R0",
+	"R1",
+	"R2",
+	"R3",
+	"R4",
+	"R5",
+	"R6",
+	"R7",
+	"R8",
+	"R9",
+	"R10",
+	"R11",
+	"R12",
+	"R13",
+	"R14",
+	"R15",
+
+	"F0",
+	"F1",
+	"F2",
+	"F3",
+	"F4",
+	"F5",
+	"F6",
+	"F7",
+	"F8",
+	"F9",
+	"F10",
+	"F11",
+	"F12",
+	"F13",
+	"F14",
+	"F15",
+
+	"F16",
+	"F17",
+	"F18",
+	"F19",
+	"F20",
+	"F21",
+	"F22",
+	"F23",
+	"F24",
+	"F25",
+	"F26",
+	"F27",
+	"F28",
+	"F29",
+	"F30",
+	"F31",
+
+	"SP",
+	"g",
+
+	// pseudo-registers
+	"SB",
+}
+
+func init() {
+	// Make map from reg names to reg integers.
+	if len(regNamesWasm) > 64 {
+		panic("too many registers")
+	}
+	num := map[string]int{}
+	for i, name := range regNamesWasm {
+		num[name] = i
+	}
+	buildReg := func(s string) regMask {
+		m := regMask(0)
+		for _, r := range strings.Split(s, " ") {
+			if n, ok := num[r]; ok {
+				m |= regMask(1) << uint(n)
+				continue
+			}
+			panic("register " + r + " not found")
+		}
+		return m
+	}
+
+	var (
+		gp     = buildReg("R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15")
+		fp32   = buildReg("F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15")
+		fp64   = buildReg("F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31")
+		gpsp   = gp | buildReg("SP")
+		gpspsb = gpsp | buildReg("SB")
+		// The "registers", which are actually local variables, can get clobbered
+		// if we're switching goroutines, because it unwinds the WebAssembly stack.
+		callerSave = gp | fp32 | fp64 | buildReg("g")
+	)
+
+	// Common regInfo
+	var (
+		gp01      = regInfo{inputs: nil, outputs: []regMask{gp}}
+		gp11      = regInfo{inputs: []regMask{gpsp}, outputs: []regMask{gp}}
+		gp21      = regInfo{inputs: []regMask{gpsp, gpsp}, outputs: []regMask{gp}}
+		gp31      = regInfo{inputs: []regMask{gpsp, gpsp, gpsp}, outputs: []regMask{gp}}
+		fp32_01   = regInfo{inputs: nil, outputs: []regMask{fp32}}
+		fp32_11   = regInfo{inputs: []regMask{fp32}, outputs: []regMask{fp32}}
+		fp32_21   = regInfo{inputs: []regMask{fp32, fp32}, outputs: []regMask{fp32}}
+		fp32_21gp = regInfo{inputs: []regMask{fp32, fp32}, outputs: []regMask{gp}}
+		fp64_01   = regInfo{inputs: nil, outputs: []regMask{fp64}}
+		fp64_11   = regInfo{inputs: []regMask{fp64}, outputs: []regMask{fp64}}
+		fp64_21   = regInfo{inputs: []regMask{fp64, fp64}, outputs: []regMask{fp64}}
+		fp64_21gp = regInfo{inputs: []regMask{fp64, fp64}, outputs: []regMask{gp}}
+		gpload    = regInfo{inputs: []regMask{gpspsb, 0}, outputs: []regMask{gp}}
+		gpstore   = regInfo{inputs: []regMask{gpspsb, gpsp, 0}}
+		fp32load  = regInfo{inputs: []regMask{gpspsb, 0}, outputs: []regMask{fp32}}
+		fp32store = regInfo{inputs: []regMask{gpspsb, fp32, 0}}
+		fp64load  = regInfo{inputs: []regMask{gpspsb, 0}, outputs: []regMask{fp64}}
+		fp64store = regInfo{inputs: []regMask{gpspsb, fp64, 0}}
+	)
+
+	var WasmOps = []opData{
+		{name: "LoweredStaticCall", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", call: true},                                // call static function aux.(*obj.LSym). arg0=mem, auxint=argsize, returns mem
+		{name: "LoweredTailCall", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", call: true, tailCall: true},                  // tail call static function aux.(*obj.LSym). arg0=mem, auxint=argsize, returns mem
+		{name: "LoweredClosureCall", argLength: 3, reg: regInfo{inputs: []regMask{gp, gp, 0}, clobbers: callerSave}, aux: "CallOff", call: true}, // call function via closure. arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem
+		{name: "LoweredInterCall", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "CallOff", call: true},          // call fn by pointer. arg0=codeptr, arg1=mem, auxint=argsize, returns mem
+
+		{name: "LoweredAddr", argLength: 1, reg: gp11, aux: "SymOff", rematerializeable: true, symEffect: "Addr"}, // returns base+aux+auxint, arg0=base
+		{name: "LoweredMove", argLength: 3, reg: regInfo{inputs: []regMask{gp, gp}}, aux: "Int64"},                // large move. arg0=dst, arg1=src, arg2=mem, auxint=len, returns mem
+		{name: "LoweredZero", argLength: 2, reg: regInfo{inputs: []regMask{gp}}, aux: "Int64"},                    // large zeroing. arg0=start, arg1=mem, auxint=len, returns mem
+
+		{name: "LoweredGetClosurePtr", reg: gp01},                                                                          // returns wasm.REG_CTXT, the closure pointer
+		{name: "LoweredGetCallerPC", reg: gp01, rematerializeable: true},                                                   // returns the PC of the caller of the current function
+		{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},                                                   // returns the SP of the caller of the current function
+		{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gp}}, nilCheck: true, faultOnNilArg0: true}, // panic if arg0 is nil. arg1=mem
+		{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{gp, gp}}, aux: "Sym", symEffect: "None"},          // invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
+
+		// LoweredConvert converts between pointers and integers.
+		// We have a special op for this so as to not confuse GCCallOff
+		// (particularly stack maps). It takes a memory arg so it
+		// gets correctly ordered with respect to GC safepoints.
+		// arg0=ptr/int arg1=mem, output=int/ptr
+		//
+		// TODO(neelance): LoweredConvert should not be necessary any more, since OpConvert does not need to be lowered any more (CL 108496).
+		{name: "LoweredConvert", argLength: 2, reg: regInfo{inputs: []regMask{gp}, outputs: []regMask{gp}}},
+
+		// The following are native WebAssembly instructions, see https://webassembly.github.io/spec/core/syntax/instructions.html
+
+		{name: "Select", asm: "Select", argLength: 3, reg: gp31}, // returns arg0 if arg2 != 0, otherwise returns arg1
+
+		{name: "I64Load8U", asm: "I64Load8U", argLength: 2, reg: gpload, aux: "Int64", typ: "UInt8"},    // read unsigned 8-bit integer from address arg0+aux, arg1=mem
+		{name: "I64Load8S", asm: "I64Load8S", argLength: 2, reg: gpload, aux: "Int64", typ: "Int8"},     // read signed 8-bit integer from address arg0+aux, arg1=mem
+		{name: "I64Load16U", asm: "I64Load16U", argLength: 2, reg: gpload, aux: "Int64", typ: "UInt16"}, // read unsigned 16-bit integer from address arg0+aux, arg1=mem
+		{name: "I64Load16S", asm: "I64Load16S", argLength: 2, reg: gpload, aux: "Int64", typ: "Int16"},  // read signed 16-bit integer from address arg0+aux, arg1=mem
+		{name: "I64Load32U", asm: "I64Load32U", argLength: 2, reg: gpload, aux: "Int64", typ: "UInt32"}, // read unsigned 32-bit integer from address arg0+aux, arg1=mem
+		{name: "I64Load32S", asm: "I64Load32S", argLength: 2, reg: gpload, aux: "Int64", typ: "Int32"},  // read signed 32-bit integer from address arg0+aux, arg1=mem
+		{name: "I64Load", asm: "I64Load", argLength: 2, reg: gpload, aux: "Int64", typ: "UInt64"},       // read 64-bit integer from address arg0+aux, arg1=mem
+		{name: "I64Store8", asm: "I64Store8", argLength: 3, reg: gpstore, aux: "Int64", typ: "Mem"},     // store 8-bit integer arg1 at address arg0+aux, arg2=mem, returns mem
+		{name: "I64Store16", asm: "I64Store16", argLength: 3, reg: gpstore, aux: "Int64", typ: "Mem"},   // store 16-bit integer arg1 at address arg0+aux, arg2=mem, returns mem
+		{name: "I64Store32", asm: "I64Store32", argLength: 3, reg: gpstore, aux: "Int64", typ: "Mem"},   // store 32-bit integer arg1 at address arg0+aux, arg2=mem, returns mem
+		{name: "I64Store", asm: "I64Store", argLength: 3, reg: gpstore, aux: "Int64", typ: "Mem"},       // store 64-bit integer arg1 at address arg0+aux, arg2=mem, returns mem
+
+		{name: "F32Load", asm: "F32Load", argLength: 2, reg: fp32load, aux: "Int64", typ: "Float32"}, // read 32-bit float from address arg0+aux, arg1=mem
+		{name: "F64Load", asm: "F64Load", argLength: 2, reg: fp64load, aux: "Int64", typ: "Float64"}, // read 64-bit float from address arg0+aux, arg1=mem
+		{name: "F32Store", asm: "F32Store", argLength: 3, reg: fp32store, aux: "Int64", typ: "Mem"},  // store 32-bit float arg1 at address arg0+aux, arg2=mem, returns mem
+		{name: "F64Store", asm: "F64Store", argLength: 3, reg: fp64store, aux: "Int64", typ: "Mem"},  // store 64-bit float arg1 at address arg0+aux, arg2=mem, returns mem
+
+		{name: "I64Const", reg: gp01, aux: "Int64", rematerializeable: true, typ: "Int64"},        // returns the constant integer aux
+		{name: "F32Const", reg: fp32_01, aux: "Float32", rematerializeable: true, typ: "Float32"}, // returns the constant float aux
+		{name: "F64Const", reg: fp64_01, aux: "Float64", rematerializeable: true, typ: "Float64"}, // returns the constant float aux
+
+		{name: "I64Eqz", asm: "I64Eqz", argLength: 1, reg: gp11, typ: "Bool"}, // arg0 == 0
+		{name: "I64Eq", asm: "I64Eq", argLength: 2, reg: gp21, typ: "Bool"},   // arg0 == arg1
+		{name: "I64Ne", asm: "I64Ne", argLength: 2, reg: gp21, typ: "Bool"},   // arg0 != arg1
+		{name: "I64LtS", asm: "I64LtS", argLength: 2, reg: gp21, typ: "Bool"}, // arg0 < arg1 (signed)
+		{name: "I64LtU", asm: "I64LtU", argLength: 2, reg: gp21, typ: "Bool"}, // arg0 < arg1 (unsigned)
+		{name: "I64GtS", asm: "I64GtS", argLength: 2, reg: gp21, typ: "Bool"}, // arg0 > arg1 (signed)
+		{name: "I64GtU", asm: "I64GtU", argLength: 2, reg: gp21, typ: "Bool"}, // arg0 > arg1 (unsigned)
+		{name: "I64LeS", asm: "I64LeS", argLength: 2, reg: gp21, typ: "Bool"}, // arg0 <= arg1 (signed)
+		{name: "I64LeU", asm: "I64LeU", argLength: 2, reg: gp21, typ: "Bool"}, // arg0 <= arg1 (unsigned)
+		{name: "I64GeS", asm: "I64GeS", argLength: 2, reg: gp21, typ: "Bool"}, // arg0 >= arg1 (signed)
+		{name: "I64GeU", asm: "I64GeU", argLength: 2, reg: gp21, typ: "Bool"}, // arg0 >= arg1 (unsigned)
+
+		{name: "F32Eq", asm: "F32Eq", argLength: 2, reg: fp32_21gp, typ: "Bool"}, // arg0 == arg1
+		{name: "F32Ne", asm: "F32Ne", argLength: 2, reg: fp32_21gp, typ: "Bool"}, // arg0 != arg1
+		{name: "F32Lt", asm: "F32Lt", argLength: 2, reg: fp32_21gp, typ: "Bool"}, // arg0 < arg1
+		{name: "F32Gt", asm: "F32Gt", argLength: 2, reg: fp32_21gp, typ: "Bool"}, // arg0 > arg1
+		{name: "F32Le", asm: "F32Le", argLength: 2, reg: fp32_21gp, typ: "Bool"}, // arg0 <= arg1
+		{name: "F32Ge", asm: "F32Ge", argLength: 2, reg: fp32_21gp, typ: "Bool"}, // arg0 >= arg1
+
+		{name: "F64Eq", asm: "F64Eq", argLength: 2, reg: fp64_21gp, typ: "Bool"}, // arg0 == arg1
+		{name: "F64Ne", asm: "F64Ne", argLength: 2, reg: fp64_21gp, typ: "Bool"}, // arg0 != arg1
+		{name: "F64Lt", asm: "F64Lt", argLength: 2, reg: fp64_21gp, typ: "Bool"}, // arg0 < arg1
+		{name: "F64Gt", asm: "F64Gt", argLength: 2, reg: fp64_21gp, typ: "Bool"}, // arg0 > arg1
+		{name: "F64Le", asm: "F64Le", argLength: 2, reg: fp64_21gp, typ: "Bool"}, // arg0 <= arg1
+		{name: "F64Ge", asm: "F64Ge", argLength: 2, reg: fp64_21gp, typ: "Bool"}, // arg0 >= arg1
+
+		{name: "I64Add", asm: "I64Add", argLength: 2, reg: gp21, typ: "Int64"},                    // arg0 + arg1
+		{name: "I64AddConst", asm: "I64Add", argLength: 1, reg: gp11, aux: "Int64", typ: "Int64"}, // arg0 + aux
+		{name: "I64Sub", asm: "I64Sub", argLength: 2, reg: gp21, typ: "Int64"},                    // arg0 - arg1
+		{name: "I64Mul", asm: "I64Mul", argLength: 2, reg: gp21, typ: "Int64"},                    // arg0 * arg1
+		{name: "I64DivS", asm: "I64DivS", argLength: 2, reg: gp21, typ: "Int64"},                  // arg0 / arg1 (signed)
+		{name: "I64DivU", asm: "I64DivU", argLength: 2, reg: gp21, typ: "Int64"},                  // arg0 / arg1 (unsigned)
+		{name: "I64RemS", asm: "I64RemS", argLength: 2, reg: gp21, typ: "Int64"},                  // arg0 % arg1 (signed)
+		{name: "I64RemU", asm: "I64RemU", argLength: 2, reg: gp21, typ: "Int64"},                  // arg0 % arg1 (unsigned)
+		{name: "I64And", asm: "I64And", argLength: 2, reg: gp21, typ: "Int64"},                    // arg0 & arg1
+		{name: "I64Or", asm: "I64Or", argLength: 2, reg: gp21, typ: "Int64"},                      // arg0 | arg1
+		{name: "I64Xor", asm: "I64Xor", argLength: 2, reg: gp21, typ: "Int64"},                    // arg0 ^ arg1
+		{name: "I64Shl", asm: "I64Shl", argLength: 2, reg: gp21, typ: "Int64"},                    // arg0 << (arg1 % 64)
+		{name: "I64ShrS", asm: "I64ShrS", argLength: 2, reg: gp21, typ: "Int64"},                  // arg0 >> (arg1 % 64) (signed)
+		{name: "I64ShrU", asm: "I64ShrU", argLength: 2, reg: gp21, typ: "Int64"},                  // arg0 >> (arg1 % 64) (unsigned)
+
+		{name: "F32Neg", asm: "F32Neg", argLength: 1, reg: fp32_11, typ: "Float32"}, // -arg0
+		{name: "F32Add", asm: "F32Add", argLength: 2, reg: fp32_21, typ: "Float32"}, // arg0 + arg1
+		{name: "F32Sub", asm: "F32Sub", argLength: 2, reg: fp32_21, typ: "Float32"}, // arg0 - arg1
+		{name: "F32Mul", asm: "F32Mul", argLength: 2, reg: fp32_21, typ: "Float32"}, // arg0 * arg1
+		{name: "F32Div", asm: "F32Div", argLength: 2, reg: fp32_21, typ: "Float32"}, // arg0 / arg1
+
+		{name: "F64Neg", asm: "F64Neg", argLength: 1, reg: fp64_11, typ: "Float64"}, // -arg0
+		{name: "F64Add", asm: "F64Add", argLength: 2, reg: fp64_21, typ: "Float64"}, // arg0 + arg1
+		{name: "F64Sub", asm: "F64Sub", argLength: 2, reg: fp64_21, typ: "Float64"}, // arg0 - arg1
+		{name: "F64Mul", asm: "F64Mul", argLength: 2, reg: fp64_21, typ: "Float64"}, // arg0 * arg1
+		{name: "F64Div", asm: "F64Div", argLength: 2, reg: fp64_21, typ: "Float64"}, // arg0 / arg1
+
+		{name: "I64TruncSatF64S", asm: "I64TruncSatF64S", argLength: 1, reg: regInfo{inputs: []regMask{fp64}, outputs: []regMask{gp}}, typ: "Int64"}, // truncates the float arg0 to a signed integer (saturating)
+		{name: "I64TruncSatF64U", asm: "I64TruncSatF64U", argLength: 1, reg: regInfo{inputs: []regMask{fp64}, outputs: []regMask{gp}}, typ: "Int64"}, // truncates the float arg0 to an unsigned integer (saturating)
+		{name: "I64TruncSatF32S", asm: "I64TruncSatF32S", argLength: 1, reg: regInfo{inputs: []regMask{fp32}, outputs: []regMask{gp}}, typ: "Int64"}, // truncates the float arg0 to a signed integer (saturating)
+		{name: "I64TruncSatF32U", asm: "I64TruncSatF32U", argLength: 1, reg: regInfo{inputs: []regMask{fp32}, outputs: []regMask{gp}}, typ: "Int64"}, // truncates the float arg0 to an unsigned integer (saturating)
+		{name: "F32ConvertI64S", asm: "F32ConvertI64S", argLength: 1, reg: regInfo{inputs: []regMask{gp}, outputs: []regMask{fp32}}, typ: "Float32"}, // converts the signed integer arg0 to a float
+		{name: "F32ConvertI64U", asm: "F32ConvertI64U", argLength: 1, reg: regInfo{inputs: []regMask{gp}, outputs: []regMask{fp32}}, typ: "Float32"}, // converts the unsigned integer arg0 to a float
+		{name: "F64ConvertI64S", asm: "F64ConvertI64S", argLength: 1, reg: regInfo{inputs: []regMask{gp}, outputs: []regMask{fp64}}, typ: "Float64"}, // converts the signed integer arg0 to a float
+		{name: "F64ConvertI64U", asm: "F64ConvertI64U", argLength: 1, reg: regInfo{inputs: []regMask{gp}, outputs: []regMask{fp64}}, typ: "Float64"}, // converts the unsigned integer arg0 to a float
+		{name: "F32DemoteF64", asm: "F32DemoteF64", argLength: 1, reg: regInfo{inputs: []regMask{fp64}, outputs: []regMask{fp32}}, typ: "Float32"},
+		{name: "F64PromoteF32", asm: "F64PromoteF32", argLength: 1, reg: regInfo{inputs: []regMask{fp32}, outputs: []regMask{fp64}}, typ: "Float64"},
+
+		{name: "I64Extend8S", asm: "I64Extend8S", argLength: 1, reg: gp11, typ: "Int64"},   // sign-extend arg0 from 8 to 64 bit
+		{name: "I64Extend16S", asm: "I64Extend16S", argLength: 1, reg: gp11, typ: "Int64"}, // sign-extend arg0 from 16 to 64 bit
+		{name: "I64Extend32S", asm: "I64Extend32S", argLength: 1, reg: gp11, typ: "Int64"}, // sign-extend arg0 from 32 to 64 bit
+
+		{name: "F32Sqrt", asm: "F32Sqrt", argLength: 1, reg: fp32_11, typ: "Float32"},         // sqrt(arg0)
+		{name: "F32Trunc", asm: "F32Trunc", argLength: 1, reg: fp32_11, typ: "Float32"},       // trunc(arg0)
+		{name: "F32Ceil", asm: "F32Ceil", argLength: 1, reg: fp32_11, typ: "Float32"},         // ceil(arg0)
+		{name: "F32Floor", asm: "F32Floor", argLength: 1, reg: fp32_11, typ: "Float32"},       // floor(arg0)
+		{name: "F32Nearest", asm: "F32Nearest", argLength: 1, reg: fp32_11, typ: "Float32"},   // round(arg0)
+		{name: "F32Abs", asm: "F32Abs", argLength: 1, reg: fp32_11, typ: "Float32"},           // abs(arg0)
+		{name: "F32Copysign", asm: "F32Copysign", argLength: 2, reg: fp32_21, typ: "Float32"}, // copysign(arg0, arg1)
+
+		{name: "F64Sqrt", asm: "F64Sqrt", argLength: 1, reg: fp64_11, typ: "Float64"},         // sqrt(arg0)
+		{name: "F64Trunc", asm: "F64Trunc", argLength: 1, reg: fp64_11, typ: "Float64"},       // trunc(arg0)
+		{name: "F64Ceil", asm: "F64Ceil", argLength: 1, reg: fp64_11, typ: "Float64"},         // ceil(arg0)
+		{name: "F64Floor", asm: "F64Floor", argLength: 1, reg: fp64_11, typ: "Float64"},       // floor(arg0)
+		{name: "F64Nearest", asm: "F64Nearest", argLength: 1, reg: fp64_11, typ: "Float64"},   // round(arg0)
+		{name: "F64Abs", asm: "F64Abs", argLength: 1, reg: fp64_11, typ: "Float64"},           // abs(arg0)
+		{name: "F64Copysign", asm: "F64Copysign", argLength: 2, reg: fp64_21, typ: "Float64"}, // copysign(arg0, arg1)
+
+		{name: "I64Ctz", asm: "I64Ctz", argLength: 1, reg: gp11, typ: "Int64"},       // ctz(arg0)
+		{name: "I64Clz", asm: "I64Clz", argLength: 1, reg: gp11, typ: "Int64"},       // clz(arg0)
+		{name: "I32Rotl", asm: "I32Rotl", argLength: 2, reg: gp21, typ: "Int32"},     // rotl(arg0, arg1)
+		{name: "I64Rotl", asm: "I64Rotl", argLength: 2, reg: gp21, typ: "Int64"},     // rotl(arg0, arg1)
+		{name: "I64Popcnt", asm: "I64Popcnt", argLength: 1, reg: gp11, typ: "Int64"}, // popcnt(arg0)
+	}
+
+	archs = append(archs, arch{
+		name:            "Wasm",
+		pkg:             "cmd/internal/obj/wasm",
+		genfile:         "../../wasm/ssa.go",
+		ops:             WasmOps,
+		blocks:          nil,
+		regnames:        regNamesWasm,
+		gpregmask:       gp,
+		fpregmask:       fp32 | fp64,
+		fp32regmask:     fp32,
+		fp64regmask:     fp64,
+		framepointerreg: -1, // not used
+		linkreg:         -1, // not used
+	})
+}
diff --git a/src/cmd/compile/internal/ssa/_gen/allocators.go b/src/cmd/compile/internal/ssa/_gen/allocators.go
new file mode 100644
index 0000000..0f3968c
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/_gen/allocators.go
@@ -0,0 +1,198 @@
+package main
+
+// TODO: should we share backing storage for similarly-shaped types?
+// e.g. []*Value and []*Block, or even []int32 and []bool.
+
+import (
+	"bytes"
+	"fmt"
+	"go/format"
+	"io"
+	"log"
+	"os"
+)
+
+type allocator struct {
+	name     string // name for alloc/free functions
+	typ      string // the type they return/accept
+	mak      string // code to make a new object (takes power-of-2 size as fmt arg)
+	capacity string // code to calculate the capacity of an object. Should always report a power of 2.
+	resize   string // code to shrink to sub-power-of-two size (takes size as fmt arg)
+	clear    string // code for clearing object before putting it on the free list
+	minLog   int    // log_2 of minimum allocation size
+	maxLog   int    // log_2 of maximum allocation size
+}
+
+func genAllocators() {
+	allocators := []allocator{
+		{
+			name:     "ValueSlice",
+			typ:      "[]*Value",
+			capacity: "cap(%s)",
+			mak:      "make([]*Value, %s)",
+			resize:   "%s[:%s]",
+			clear:    "for i := range %[1]s {\n%[1]s[i] = nil\n}",
+			minLog:   5,
+			maxLog:   32,
+		},
+		{
+			name:     "BlockSlice",
+			typ:      "[]*Block",
+			capacity: "cap(%s)",
+			mak:      "make([]*Block, %s)",
+			resize:   "%s[:%s]",
+			clear:    "for i := range %[1]s {\n%[1]s[i] = nil\n}",
+			minLog:   5,
+			maxLog:   32,
+		},
+		{
+			name:     "BoolSlice",
+			typ:      "[]bool",
+			capacity: "cap(%s)",
+			mak:      "make([]bool, %s)",
+			resize:   "%s[:%s]",
+			clear:    "for i := range %[1]s {\n%[1]s[i] = false\n}",
+			minLog:   8,
+			maxLog:   32,
+		},
+		{
+			name:     "IntSlice",
+			typ:      "[]int",
+			capacity: "cap(%s)",
+			mak:      "make([]int, %s)",
+			resize:   "%s[:%s]",
+			clear:    "for i := range %[1]s {\n%[1]s[i] = 0\n}",
+			minLog:   5,
+			maxLog:   32,
+		},
+		{
+			name:     "Int32Slice",
+			typ:      "[]int32",
+			capacity: "cap(%s)",
+			mak:      "make([]int32, %s)",
+			resize:   "%s[:%s]",
+			clear:    "for i := range %[1]s {\n%[1]s[i] = 0\n}",
+			minLog:   6,
+			maxLog:   32,
+		},
+		{
+			name:     "Int8Slice",
+			typ:      "[]int8",
+			capacity: "cap(%s)",
+			mak:      "make([]int8, %s)",
+			resize:   "%s[:%s]",
+			clear:    "for i := range %[1]s {\n%[1]s[i] = 0\n}",
+			minLog:   8,
+			maxLog:   32,
+		},
+		{
+			name:     "IDSlice",
+			typ:      "[]ID",
+			capacity: "cap(%s)",
+			mak:      "make([]ID, %s)",
+			resize:   "%s[:%s]",
+			clear:    "for i := range %[1]s {\n%[1]s[i] = 0\n}",
+			minLog:   6,
+			maxLog:   32,
+		},
+		{
+			name:     "SparseSet",
+			typ:      "*sparseSet",
+			capacity: "%s.cap()",
+			mak:      "newSparseSet(%s)",
+			resize:   "", // larger-sized sparse sets are ok
+			clear:    "%s.clear()",
+			minLog:   5,
+			maxLog:   32,
+		},
+		{
+			name:     "SparseMap",
+			typ:      "*sparseMap",
+			capacity: "%s.cap()",
+			mak:      "newSparseMap(%s)",
+			resize:   "", // larger-sized sparse maps are ok
+			clear:    "%s.clear()",
+			minLog:   5,
+			maxLog:   32,
+		},
+		{
+			name:     "SparseMapPos",
+			typ:      "*sparseMapPos",
+			capacity: "%s.cap()",
+			mak:      "newSparseMapPos(%s)",
+			resize:   "", // larger-sized sparse maps are ok
+			clear:    "%s.clear()",
+			minLog:   5,
+			maxLog:   32,
+		},
+	}
+
+	w := new(bytes.Buffer)
+	fmt.Fprintf(w, "// Code generated from _gen/allocators.go; DO NOT EDIT.\n")
+	fmt.Fprintln(w)
+	fmt.Fprintln(w, "package ssa")
+
+	fmt.Fprintln(w, "import (")
+	fmt.Fprintln(w, "\"math/bits\"")
+	fmt.Fprintln(w, "\"sync\"")
+	fmt.Fprintln(w, ")")
+	for _, a := range allocators {
+		genAllocator(w, a)
+	}
+	// gofmt result
+	b := w.Bytes()
+	var err error
+	b, err = format.Source(b)
+	if err != nil {
+		fmt.Printf("%s\n", w.Bytes())
+		panic(err)
+	}
+
+	if err := os.WriteFile("../allocators.go", b, 0666); err != nil {
+		log.Fatalf("can't write output: %v\n", err)
+	}
+}
+func genAllocator(w io.Writer, a allocator) {
+	fmt.Fprintf(w, "var poolFree%s [%d]sync.Pool\n", a.name, a.maxLog-a.minLog)
+	fmt.Fprintf(w, "func (c *Cache) alloc%s(n int) %s {\n", a.name, a.typ)
+	fmt.Fprintf(w, "var s %s\n", a.typ)
+	fmt.Fprintf(w, "n2 := n\n")
+	fmt.Fprintf(w, "if n2 < %d { n2 = %d }\n", 1<<a.minLog, 1<<a.minLog)
+	fmt.Fprintf(w, "b := bits.Len(uint(n2-1))\n")
+	fmt.Fprintf(w, "v := poolFree%s[b-%d].Get()\n", a.name, a.minLog)
+	fmt.Fprintf(w, "if v == nil {\n")
+	fmt.Fprintf(w, "  s = %s\n", fmt.Sprintf(a.mak, "1<<b"))
+	fmt.Fprintf(w, "} else {\n")
+	if a.typ[0] == '*' {
+		fmt.Fprintf(w, "s = v.(%s)\n", a.typ)
+	} else {
+		fmt.Fprintf(w, "sp := v.(*%s)\n", a.typ)
+		fmt.Fprintf(w, "s = *sp\n")
+		fmt.Fprintf(w, "*sp = nil\n")
+		fmt.Fprintf(w, "c.hdr%s = append(c.hdr%s, sp)\n", a.name, a.name)
+	}
+	fmt.Fprintf(w, "}\n")
+	if a.resize != "" {
+		fmt.Fprintf(w, "s = %s\n", fmt.Sprintf(a.resize, "s", "n"))
+	}
+	fmt.Fprintf(w, "return s\n")
+	fmt.Fprintf(w, "}\n")
+	fmt.Fprintf(w, "func (c *Cache) free%s(s %s) {\n", a.name, a.typ)
+	fmt.Fprintf(w, "%s\n", fmt.Sprintf(a.clear, "s"))
+	fmt.Fprintf(w, "b := bits.Len(uint(%s) - 1)\n", fmt.Sprintf(a.capacity, "s"))
+	if a.typ[0] == '*' {
+		fmt.Fprintf(w, "poolFree%s[b-%d].Put(s)\n", a.name, a.minLog)
+	} else {
+		fmt.Fprintf(w, "var sp *%s\n", a.typ)
+		fmt.Fprintf(w, "if len(c.hdr%s) == 0 {\n", a.name)
+		fmt.Fprintf(w, "  sp = new(%s)\n", a.typ)
+		fmt.Fprintf(w, "} else {\n")
+		fmt.Fprintf(w, "  sp = c.hdr%s[len(c.hdr%s)-1]\n", a.name, a.name)
+		fmt.Fprintf(w, "  c.hdr%s[len(c.hdr%s)-1] = nil\n", a.name, a.name)
+		fmt.Fprintf(w, "  c.hdr%s = c.hdr%s[:len(c.hdr%s)-1]\n", a.name, a.name, a.name)
+		fmt.Fprintf(w, "}\n")
+		fmt.Fprintf(w, "*sp = s\n")
+		fmt.Fprintf(w, "poolFree%s[b-%d].Put(sp)\n", a.name, a.minLog)
+	}
+	fmt.Fprintf(w, "}\n")
+}
diff --git a/src/cmd/compile/internal/ssa/_gen/cover.bash b/src/cmd/compile/internal/ssa/_gen/cover.bash
new file mode 100755
index 0000000..7311cfb
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/_gen/cover.bash
@@ -0,0 +1,26 @@
+#!/usr/bin/env bash
+# Copyright 2020 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+# A quick and dirty way to obtain code coverage from rulegen's main func. For
+# example:
+#
+#     ./cover.bash && go tool cover -html=cover.out
+#
+# This script is needed to set up a temporary test file, so that we don't break
+# regular 'go run .' usage to run the generator.
+
+cat >main_test.go <<-EOF
+	// +build ignore
+
+	package main
+
+	import "testing"
+
+	func TestCoverage(t *testing.T) { main() }
+EOF
+
+go test -run='^TestCoverage$' -coverprofile=cover.out "$@" *.go
+
+rm -f main_test.go
diff --git a/src/cmd/compile/internal/ssa/gen/dec.rules b/src/cmd/compile/internal/ssa/_gen/dec.rules
similarity index 100%
rename from src/cmd/compile/internal/ssa/gen/dec.rules
rename to src/cmd/compile/internal/ssa/_gen/dec.rules
diff --git a/src/cmd/compile/internal/ssa/_gen/dec64.rules b/src/cmd/compile/internal/ssa/_gen/dec64.rules
new file mode 100644
index 0000000..ba776af
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/_gen/dec64.rules
@@ -0,0 +1,401 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains rules to decompose [u]int64 types on 32-bit
+// architectures. These rules work together with the decomposeBuiltIn
+// pass which handles phis of these typ.
+
+(Int64Hi (Int64Make hi _)) => hi
+(Int64Lo (Int64Make _ lo)) => lo
+
+(Load <t> ptr mem) && is64BitInt(t) && !config.BigEndian && t.IsSigned() =>
+	(Int64Make
+		(Load <typ.Int32> (OffPtr <typ.Int32Ptr> [4] ptr) mem)
+		(Load <typ.UInt32> ptr mem))
+
+(Load <t> ptr mem) && is64BitInt(t) && !config.BigEndian && !t.IsSigned() =>
+	(Int64Make
+		(Load <typ.UInt32> (OffPtr <typ.UInt32Ptr> [4] ptr) mem)
+		(Load <typ.UInt32> ptr mem))
+
+(Load <t> ptr mem) && is64BitInt(t) && config.BigEndian && t.IsSigned() =>
+	(Int64Make
+		(Load <typ.Int32> ptr mem)
+		(Load <typ.UInt32> (OffPtr <typ.UInt32Ptr> [4] ptr) mem))
+
+(Load <t> ptr mem) && is64BitInt(t) && config.BigEndian && !t.IsSigned() =>
+	(Int64Make
+		(Load <typ.UInt32> ptr mem)
+		(Load <typ.UInt32> (OffPtr <typ.UInt32Ptr> [4] ptr) mem))
+
+(Store {t} dst (Int64Make hi lo) mem) && t.Size() == 8 && !config.BigEndian =>
+	(Store {hi.Type}
+		(OffPtr <hi.Type.PtrTo()> [4] dst)
+		hi
+		(Store {lo.Type} dst lo mem))
+
+(Store {t} dst (Int64Make hi lo) mem) && t.Size() == 8 && config.BigEndian =>
+	(Store {lo.Type}
+		(OffPtr <lo.Type.PtrTo()> [4] dst)
+		lo
+		(Store {hi.Type} dst hi mem))
+
+// These are not enabled during decomposeBuiltin if late call expansion, but they are always enabled for softFloat
+(Arg {n} [off]) && is64BitInt(v.Type) && !config.BigEndian && v.Type.IsSigned() && !(b.Func.pass.name == "decompose builtin") =>
+  (Int64Make
+    (Arg <typ.Int32> {n} [off+4])
+    (Arg <typ.UInt32> {n} [off]))
+(Arg {n} [off]) && is64BitInt(v.Type) && !config.BigEndian && !v.Type.IsSigned() && !(b.Func.pass.name == "decompose builtin")  =>
+  (Int64Make
+    (Arg <typ.UInt32> {n} [off+4])
+    (Arg <typ.UInt32> {n} [off]))
+
+(Arg {n} [off]) && is64BitInt(v.Type) && config.BigEndian && v.Type.IsSigned() && !(b.Func.pass.name == "decompose builtin") =>
+  (Int64Make
+    (Arg <typ.Int32> {n} [off])
+    (Arg <typ.UInt32> {n} [off+4]))
+(Arg {n} [off]) && is64BitInt(v.Type) && config.BigEndian && !v.Type.IsSigned() && !(b.Func.pass.name == "decompose builtin") =>
+  (Int64Make
+    (Arg <typ.UInt32> {n} [off])
+    (Arg <typ.UInt32> {n} [off+4]))
+
+(Add64 x y) =>
+	(Int64Make
+		(Add32withcarry <typ.Int32>
+			(Int64Hi x)
+			(Int64Hi y)
+			(Select1 <types.TypeFlags> (Add32carry (Int64Lo x) (Int64Lo y))))
+		(Select0 <typ.UInt32> (Add32carry (Int64Lo x) (Int64Lo y))))
+
+(Sub64 x y) =>
+	(Int64Make
+		(Sub32withcarry <typ.Int32>
+			(Int64Hi x)
+			(Int64Hi y)
+			(Select1 <types.TypeFlags> (Sub32carry (Int64Lo x) (Int64Lo y))))
+		(Select0 <typ.UInt32> (Sub32carry (Int64Lo x) (Int64Lo y))))
+
+(Mul64 x y) =>
+	(Int64Make
+		(Add32 <typ.UInt32>
+			(Mul32 <typ.UInt32> (Int64Lo x) (Int64Hi y))
+			(Add32 <typ.UInt32>
+				(Mul32 <typ.UInt32> (Int64Hi x) (Int64Lo y))
+				(Select0 <typ.UInt32> (Mul32uhilo (Int64Lo x) (Int64Lo y)))))
+		(Select1 <typ.UInt32> (Mul32uhilo (Int64Lo x) (Int64Lo y))))
+
+(And64 x y) =>
+	(Int64Make
+		(And32 <typ.UInt32> (Int64Hi x) (Int64Hi y))
+		(And32 <typ.UInt32> (Int64Lo x) (Int64Lo y)))
+
+(Or64 x y) =>
+	(Int64Make
+		(Or32 <typ.UInt32> (Int64Hi x) (Int64Hi y))
+		(Or32 <typ.UInt32> (Int64Lo x) (Int64Lo y)))
+
+(Xor64 x y) =>
+	(Int64Make
+		(Xor32 <typ.UInt32> (Int64Hi x) (Int64Hi y))
+		(Xor32 <typ.UInt32> (Int64Lo x) (Int64Lo y)))
+
+(Neg64 <t> x) => (Sub64 (Const64 <t> [0]) x)
+
+(Com64 x) =>
+	(Int64Make
+		(Com32 <typ.UInt32> (Int64Hi x))
+		(Com32 <typ.UInt32> (Int64Lo x)))
+
+// Sadly, just because we know that x is non-zero,
+// we don't know whether either component is,
+// so just treat Ctz64NonZero the same as Ctz64.
+(Ctz64NonZero ...) => (Ctz64 ...)
+
+(Ctz64 x) =>
+	(Add32 <typ.UInt32>
+		(Ctz32 <typ.UInt32> (Int64Lo x))
+		(And32 <typ.UInt32>
+			(Com32 <typ.UInt32> (Zeromask (Int64Lo x)))
+			(Ctz32 <typ.UInt32> (Int64Hi x))))
+
+(BitLen64 x) =>
+	(Add32 <typ.Int>
+		(BitLen32 <typ.Int> (Int64Hi x))
+		(BitLen32 <typ.Int>
+			(Or32 <typ.UInt32>
+				(Int64Lo x)
+				(Zeromask (Int64Hi x)))))
+
+(Bswap64 x) =>
+	(Int64Make
+		(Bswap32 <typ.UInt32> (Int64Lo x))
+		(Bswap32 <typ.UInt32> (Int64Hi x)))
+
+(SignExt32to64 x) => (Int64Make (Signmask x) x)
+(SignExt16to64 x) => (SignExt32to64 (SignExt16to32 x))
+(SignExt8to64 x) => (SignExt32to64 (SignExt8to32 x))
+
+(ZeroExt32to64 x) => (Int64Make (Const32 <typ.UInt32> [0]) x)
+(ZeroExt16to64 x) => (ZeroExt32to64 (ZeroExt16to32 x))
+(ZeroExt8to64 x) => (ZeroExt32to64 (ZeroExt8to32 x))
+
+(Trunc64to32 (Int64Make _ lo)) => lo
+(Trunc64to16 (Int64Make _ lo)) => (Trunc32to16 lo)
+(Trunc64to8 (Int64Make _ lo)) => (Trunc32to8 lo)
+// Most general
+(Trunc64to32 x) => (Int64Lo x)
+(Trunc64to16 x) => (Trunc32to16 (Int64Lo x))
+(Trunc64to8 x) => (Trunc32to8 (Int64Lo x))
+
+(Lsh32x64 _ (Int64Make (Const32 [c]) _)) && c != 0 => (Const32 [0])
+(Rsh32x64 x (Int64Make (Const32 [c]) _)) && c != 0 => (Signmask x)
+(Rsh32Ux64 _ (Int64Make (Const32 [c]) _)) && c != 0 => (Const32 [0])
+(Lsh16x64 _ (Int64Make (Const32 [c]) _)) && c != 0 => (Const32 [0])
+(Rsh16x64 x (Int64Make (Const32 [c]) _)) && c != 0 => (Signmask (SignExt16to32 x))
+(Rsh16Ux64 _ (Int64Make (Const32 [c]) _)) && c != 0 => (Const32 [0])
+(Lsh8x64 _ (Int64Make (Const32 [c]) _)) && c != 0 => (Const32 [0])
+(Rsh8x64 x (Int64Make (Const32 [c]) _)) && c != 0 => (Signmask (SignExt8to32 x))
+(Rsh8Ux64 _ (Int64Make (Const32 [c]) _)) && c != 0 => (Const32 [0])
+
+(Lsh32x64 [c] x (Int64Make (Const32 [0]) lo)) => (Lsh32x32 [c] x lo)
+(Rsh32x64 [c] x (Int64Make (Const32 [0]) lo)) => (Rsh32x32 [c] x lo)
+(Rsh32Ux64 [c] x (Int64Make (Const32 [0]) lo)) => (Rsh32Ux32 [c] x lo)
+(Lsh16x64 [c] x (Int64Make (Const32 [0]) lo)) => (Lsh16x32 [c] x lo)
+(Rsh16x64 [c] x (Int64Make (Const32 [0]) lo)) => (Rsh16x32 [c] x lo)
+(Rsh16Ux64 [c] x (Int64Make (Const32 [0]) lo)) => (Rsh16Ux32 [c] x lo)
+(Lsh8x64 [c] x (Int64Make (Const32 [0]) lo)) => (Lsh8x32 [c] x lo)
+(Rsh8x64 [c] x (Int64Make (Const32 [0]) lo)) => (Rsh8x32 [c] x lo)
+(Rsh8Ux64 [c] x (Int64Make (Const32 [0]) lo)) => (Rsh8Ux32 [c] x lo)
+
+(Lsh64x64 _ (Int64Make (Const32 [c]) _)) && c != 0 => (Const64 [0])
+(Rsh64x64 x (Int64Make (Const32 [c]) _)) && c != 0 => (Int64Make (Signmask (Int64Hi x)) (Signmask (Int64Hi x)))
+(Rsh64Ux64 _ (Int64Make (Const32 [c]) _)) && c != 0 => (Const64 [0])
+
+(Lsh64x64 [c] x (Int64Make (Const32 [0]) lo)) => (Lsh64x32 [c] x lo)
+(Rsh64x64 [c] x (Int64Make (Const32 [0]) lo)) => (Rsh64x32 [c] x lo)
+(Rsh64Ux64 [c] x (Int64Make (Const32 [0]) lo)) => (Rsh64Ux32 [c] x lo)
+
+// turn x64 non-constant shifts to x32 shifts
+// if high 32-bit of the shift is nonzero, make a huge shift
+(Lsh64x64 x (Int64Make hi lo)) && hi.Op != OpConst32 =>
+       (Lsh64x32 x (Or32 <typ.UInt32> (Zeromask hi) lo))
+(Rsh64x64 x (Int64Make hi lo)) && hi.Op != OpConst32 =>
+       (Rsh64x32 x (Or32 <typ.UInt32> (Zeromask hi) lo))
+(Rsh64Ux64 x (Int64Make hi lo)) && hi.Op != OpConst32 =>
+       (Rsh64Ux32 x (Or32 <typ.UInt32> (Zeromask hi) lo))
+(Lsh32x64 x (Int64Make hi lo)) && hi.Op != OpConst32 =>
+       (Lsh32x32 x (Or32 <typ.UInt32> (Zeromask hi) lo))
+(Rsh32x64 x (Int64Make hi lo)) && hi.Op != OpConst32 =>
+       (Rsh32x32 x (Or32 <typ.UInt32> (Zeromask hi) lo))
+(Rsh32Ux64 x (Int64Make hi lo)) && hi.Op != OpConst32 =>
+       (Rsh32Ux32 x (Or32 <typ.UInt32> (Zeromask hi) lo))
+(Lsh16x64 x (Int64Make hi lo)) && hi.Op != OpConst32 =>
+       (Lsh16x32 x (Or32 <typ.UInt32> (Zeromask hi) lo))
+(Rsh16x64 x (Int64Make hi lo)) && hi.Op != OpConst32 =>
+       (Rsh16x32 x (Or32 <typ.UInt32> (Zeromask hi) lo))
+(Rsh16Ux64 x (Int64Make hi lo)) && hi.Op != OpConst32 =>
+       (Rsh16Ux32 x (Or32 <typ.UInt32> (Zeromask hi) lo))
+(Lsh8x64 x (Int64Make hi lo)) && hi.Op != OpConst32 =>
+       (Lsh8x32 x (Or32 <typ.UInt32> (Zeromask hi) lo))
+(Rsh8x64 x (Int64Make hi lo)) && hi.Op != OpConst32 =>
+       (Rsh8x32 x (Or32 <typ.UInt32> (Zeromask hi) lo))
+(Rsh8Ux64 x (Int64Make hi lo)) && hi.Op != OpConst32 =>
+       (Rsh8Ux32 x (Or32 <typ.UInt32> (Zeromask hi) lo))
+
+// Most general
+(Lsh64x64 x y)  => (Lsh64x32  x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y)))
+(Rsh64x64 x y)  => (Rsh64x32  x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y)))
+(Rsh64Ux64 x y) => (Rsh64Ux32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y)))
+(Lsh32x64 x y)  => (Lsh32x32  x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y)))
+(Rsh32x64 x y)  => (Rsh32x32  x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y)))
+(Rsh32Ux64 x y) => (Rsh32Ux32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y)))
+(Lsh16x64 x y)  => (Lsh16x32  x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y)))
+(Rsh16x64 x y)  => (Rsh16x32  x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y)))
+(Rsh16Ux64 x y) => (Rsh16Ux32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y)))
+(Lsh8x64 x y)   => (Lsh8x32   x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y)))
+(Rsh8x64 x y)   => (Rsh8x32   x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y)))
+(Rsh8Ux64 x y)  => (Rsh8Ux32  x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y)))
+
+(RotateLeft64 x (Int64Make hi lo)) => (RotateLeft64 x lo)
+(RotateLeft32 x (Int64Make hi lo)) => (RotateLeft32 x lo)
+(RotateLeft16 x (Int64Make hi lo)) => (RotateLeft16 x lo)
+(RotateLeft8  x (Int64Make hi lo)) => (RotateLeft8  x lo)
+
+// Clean up constants a little
+(Or32 <typ.UInt32> (Zeromask (Const32 [c])) y) && c == 0 => y
+(Or32 <typ.UInt32> (Zeromask (Const32 [c])) y) && c != 0 => (Const32 <typ.UInt32> [-1])
+
+// 64x left shift
+// result.hi = hi<<s | lo>>(32-s) | lo<<(s-32) // >> is unsigned, large shifts result 0
+// result.lo = lo<<s
+(Lsh64x32 x s) =>
+	(Int64Make
+		(Or32 <typ.UInt32>
+			(Or32 <typ.UInt32>
+				(Lsh32x32 <typ.UInt32> (Int64Hi x) s)
+				(Rsh32Ux32 <typ.UInt32>
+					(Int64Lo x)
+					(Sub32 <typ.UInt32> (Const32 <typ.UInt32> [32]) s)))
+			(Lsh32x32 <typ.UInt32>
+				(Int64Lo x)
+				(Sub32 <typ.UInt32> s (Const32 <typ.UInt32> [32]))))
+		(Lsh32x32 <typ.UInt32> (Int64Lo x) s))
+(Lsh64x16 x s) =>
+	(Int64Make
+		(Or32 <typ.UInt32>
+			(Or32 <typ.UInt32>
+				(Lsh32x16 <typ.UInt32> (Int64Hi x) s)
+				(Rsh32Ux16 <typ.UInt32>
+					(Int64Lo x)
+					(Sub16 <typ.UInt16> (Const16 <typ.UInt16> [32]) s)))
+			(Lsh32x16 <typ.UInt32>
+				(Int64Lo x)
+				(Sub16 <typ.UInt16> s (Const16 <typ.UInt16> [32]))))
+		(Lsh32x16 <typ.UInt32> (Int64Lo x) s))
+(Lsh64x8 x s) =>
+	(Int64Make
+		(Or32 <typ.UInt32>
+			(Or32 <typ.UInt32>
+				(Lsh32x8 <typ.UInt32> (Int64Hi x) s)
+				(Rsh32Ux8 <typ.UInt32>
+					(Int64Lo x)
+					(Sub8 <typ.UInt8> (Const8 <typ.UInt8> [32]) s)))
+			(Lsh32x8 <typ.UInt32>
+				(Int64Lo x)
+				(Sub8 <typ.UInt8> s (Const8 <typ.UInt8> [32]))))
+		(Lsh32x8 <typ.UInt32> (Int64Lo x) s))
+
+// 64x unsigned right shift
+// result.hi = hi>>s
+// result.lo = lo>>s | hi<<(32-s) | hi>>(s-32) // >> is unsigned, large shifts result 0
+(Rsh64Ux32 x s) =>
+	(Int64Make
+		(Rsh32Ux32 <typ.UInt32> (Int64Hi x) s)
+		(Or32 <typ.UInt32>
+			(Or32 <typ.UInt32>
+				(Rsh32Ux32 <typ.UInt32> (Int64Lo x) s)
+				(Lsh32x32 <typ.UInt32>
+					(Int64Hi x)
+					(Sub32 <typ.UInt32> (Const32 <typ.UInt32> [32]) s)))
+			(Rsh32Ux32 <typ.UInt32>
+				(Int64Hi x)
+				(Sub32 <typ.UInt32> s (Const32 <typ.UInt32> [32])))))
+(Rsh64Ux16 x s) =>
+	(Int64Make
+		(Rsh32Ux16 <typ.UInt32> (Int64Hi x) s)
+		(Or32 <typ.UInt32>
+			(Or32 <typ.UInt32>
+				(Rsh32Ux16 <typ.UInt32> (Int64Lo x) s)
+				(Lsh32x16 <typ.UInt32>
+					(Int64Hi x)
+					(Sub16 <typ.UInt16> (Const16 <typ.UInt16> [32]) s)))
+			(Rsh32Ux16 <typ.UInt32>
+				(Int64Hi x)
+				(Sub16 <typ.UInt16> s (Const16 <typ.UInt16> [32])))))
+(Rsh64Ux8 x s) =>
+	(Int64Make
+		(Rsh32Ux8 <typ.UInt32> (Int64Hi x) s)
+		(Or32 <typ.UInt32>
+			(Or32 <typ.UInt32>
+				(Rsh32Ux8 <typ.UInt32> (Int64Lo x) s)
+				(Lsh32x8 <typ.UInt32>
+					(Int64Hi x)
+					(Sub8 <typ.UInt8> (Const8 <typ.UInt8> [32]) s)))
+			(Rsh32Ux8 <typ.UInt32>
+				(Int64Hi x)
+				(Sub8 <typ.UInt8> s (Const8 <typ.UInt8> [32])))))
+
+// 64x signed right shift
+// result.hi = hi>>s
+// result.lo = lo>>s | hi<<(32-s) | (hi>>(s-32))&zeromask(s>>5) // hi>>(s-32) is signed, large shifts result 0/-1
+(Rsh64x32 x s) =>
+	(Int64Make
+		(Rsh32x32 <typ.UInt32> (Int64Hi x) s)
+		(Or32 <typ.UInt32>
+			(Or32 <typ.UInt32>
+				(Rsh32Ux32 <typ.UInt32> (Int64Lo x) s)
+				(Lsh32x32 <typ.UInt32>
+					(Int64Hi x)
+					(Sub32 <typ.UInt32> (Const32 <typ.UInt32> [32]) s)))
+			(And32 <typ.UInt32>
+				(Rsh32x32 <typ.UInt32>
+					(Int64Hi x)
+					(Sub32 <typ.UInt32> s (Const32 <typ.UInt32> [32])))
+				(Zeromask
+					(Rsh32Ux32 <typ.UInt32> s (Const32 <typ.UInt32> [5]))))))
+(Rsh64x16 x s) =>
+	(Int64Make
+		(Rsh32x16 <typ.UInt32> (Int64Hi x) s)
+		(Or32 <typ.UInt32>
+			(Or32 <typ.UInt32>
+				(Rsh32Ux16 <typ.UInt32> (Int64Lo x) s)
+				(Lsh32x16 <typ.UInt32>
+					(Int64Hi x)
+					(Sub16 <typ.UInt16> (Const16 <typ.UInt16> [32]) s)))
+			(And32 <typ.UInt32>
+				(Rsh32x16 <typ.UInt32>
+					(Int64Hi x)
+					(Sub16 <typ.UInt16> s (Const16 <typ.UInt16> [32])))
+				(Zeromask
+					(ZeroExt16to32
+						(Rsh16Ux32 <typ.UInt16> s (Const32 <typ.UInt32> [5])))))))
+(Rsh64x8 x s) =>
+	(Int64Make
+		(Rsh32x8 <typ.UInt32> (Int64Hi x) s)
+		(Or32 <typ.UInt32>
+			(Or32 <typ.UInt32>
+				(Rsh32Ux8 <typ.UInt32> (Int64Lo x) s)
+				(Lsh32x8 <typ.UInt32>
+					(Int64Hi x)
+					(Sub8 <typ.UInt8> (Const8 <typ.UInt8> [32]) s)))
+			(And32 <typ.UInt32>
+				(Rsh32x8 <typ.UInt32>
+					(Int64Hi x)
+					(Sub8 <typ.UInt8> s (Const8 <typ.UInt8> [32])))
+				(Zeromask
+					(ZeroExt8to32
+						(Rsh8Ux32 <typ.UInt8> s (Const32 <typ.UInt32> [5])))))))
+
+(Const64 <t> [c]) && t.IsSigned() =>
+	(Int64Make (Const32 <typ.Int32> [int32(c>>32)]) (Const32 <typ.UInt32> [int32(c)]))
+(Const64 <t> [c]) && !t.IsSigned() =>
+	(Int64Make (Const32 <typ.UInt32> [int32(c>>32)]) (Const32 <typ.UInt32> [int32(c)]))
+
+(Eq64 x y) =>
+	(AndB
+		(Eq32 (Int64Hi x) (Int64Hi y))
+		(Eq32 (Int64Lo x) (Int64Lo y)))
+
+(Neq64 x y) =>
+	(OrB
+		(Neq32 (Int64Hi x) (Int64Hi y))
+		(Neq32 (Int64Lo x) (Int64Lo y)))
+
+(Less64U x y) =>
+	(OrB
+		(Less32U (Int64Hi x) (Int64Hi y))
+		(AndB
+			(Eq32 (Int64Hi x) (Int64Hi y))
+			(Less32U (Int64Lo x) (Int64Lo y))))
+
+(Leq64U x y) =>
+	(OrB
+		(Less32U (Int64Hi x) (Int64Hi y))
+		(AndB
+			(Eq32 (Int64Hi x) (Int64Hi y))
+			(Leq32U (Int64Lo x) (Int64Lo y))))
+
+(Less64 x y) =>
+	(OrB
+		(Less32 (Int64Hi x) (Int64Hi y))
+		(AndB
+			(Eq32 (Int64Hi x) (Int64Hi y))
+			(Less32U (Int64Lo x) (Int64Lo y))))
+
+(Leq64 x y) =>
+	(OrB
+		(Less32 (Int64Hi x) (Int64Hi y))
+		(AndB
+			(Eq32 (Int64Hi x) (Int64Hi y))
+			(Leq32U (Int64Lo x) (Int64Lo y))))
diff --git a/src/cmd/compile/internal/ssa/_gen/dec64Ops.go b/src/cmd/compile/internal/ssa/_gen/dec64Ops.go
new file mode 100644
index 0000000..bba218e
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/_gen/dec64Ops.go
@@ -0,0 +1,18 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+var dec64Ops = []opData{}
+
+var dec64Blocks = []blockData{}
+
+func init() {
+	archs = append(archs, arch{
+		name:    "dec64",
+		ops:     dec64Ops,
+		blocks:  dec64Blocks,
+		generic: true,
+	})
+}
diff --git a/src/cmd/compile/internal/ssa/_gen/decOps.go b/src/cmd/compile/internal/ssa/_gen/decOps.go
new file mode 100644
index 0000000..0cc11cb
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/_gen/decOps.go
@@ -0,0 +1,18 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+var decOps = []opData{}
+
+var decBlocks = []blockData{}
+
+func init() {
+	archs = append(archs, arch{
+		name:    "dec",
+		ops:     decOps,
+		blocks:  decBlocks,
+		generic: true,
+	})
+}
diff --git a/src/cmd/compile/internal/ssa/_gen/generic.rules b/src/cmd/compile/internal/ssa/_gen/generic.rules
new file mode 100644
index 0000000..0406fbb
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/_gen/generic.rules
@@ -0,0 +1,2672 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Simplifications that apply to all backend architectures. As an example, this
+// Go source code
+//
+// y := 0 * x
+//
+// can be translated into y := 0 without losing any information, which saves a
+// pointless multiplication instruction. Other .rules files in this directory
+// (for example AMD64.rules) contain rules specific to the architecture in the
+// filename. The rules here apply to every architecture.
+//
+// The code for parsing this file lives in rulegen.go; this file generates
+// ssa/rewritegeneric.go.
+
+// values are specified using the following format:
+// (op <type> [auxint] {aux} arg0 arg1 ...)
+// the type, aux, and auxint fields are optional
+// on the matching side
+//  - the type, aux, and auxint fields must match if they are specified.
+//  - the first occurrence of a variable defines that variable.  Subsequent
+//    uses must match (be == to) the first use.
+//  - v is defined to be the value matched.
+//  - an additional conditional can be provided after the match pattern with "&&".
+// on the generated side
+//  - the type of the top-level expression is the same as the one on the left-hand side.
+//  - the type of any subexpressions must be specified explicitly (or
+//    be specified in the op's type field).
+//  - auxint will be 0 if not specified.
+//  - aux will be nil if not specified.
+
+// blocks are specified using the following format:
+// (kind controlvalue succ0 succ1 ...)
+// controlvalue must be "nil" or a value expression
+// succ* fields must be variables
+// For now, the generated successors must be a permutation of the matched successors.
+
+// constant folding
+(Trunc16to8  (Const16  [c])) => (Const8   [int8(c)])
+(Trunc32to8  (Const32  [c])) => (Const8   [int8(c)])
+(Trunc32to16 (Const32  [c])) => (Const16  [int16(c)])
+(Trunc64to8  (Const64  [c])) => (Const8   [int8(c)])
+(Trunc64to16 (Const64  [c])) => (Const16  [int16(c)])
+(Trunc64to32 (Const64  [c])) => (Const32  [int32(c)])
+(Cvt64Fto32F (Const64F [c])) => (Const32F [float32(c)])
+(Cvt32Fto64F (Const32F [c])) => (Const64F [float64(c)])
+(Cvt32to32F  (Const32  [c])) => (Const32F [float32(c)])
+(Cvt32to64F  (Const32  [c])) => (Const64F [float64(c)])
+(Cvt64to32F  (Const64  [c])) => (Const32F [float32(c)])
+(Cvt64to64F  (Const64  [c])) => (Const64F [float64(c)])
+(Cvt32Fto32  (Const32F [c])) => (Const32  [int32(c)])
+(Cvt32Fto64  (Const32F [c])) => (Const64  [int64(c)])
+(Cvt64Fto32  (Const64F [c])) => (Const32  [int32(c)])
+(Cvt64Fto64  (Const64F [c])) => (Const64  [int64(c)])
+(Round32F x:(Const32F)) => x
+(Round64F x:(Const64F)) => x
+(CvtBoolToUint8 (ConstBool [false])) => (Const8 [0])
+(CvtBoolToUint8 (ConstBool [true])) => (Const8 [1])
+
+(Trunc16to8  (ZeroExt8to16  x)) => x
+(Trunc32to8  (ZeroExt8to32  x)) => x
+(Trunc32to16 (ZeroExt8to32  x)) => (ZeroExt8to16  x)
+(Trunc32to16 (ZeroExt16to32 x)) => x
+(Trunc64to8  (ZeroExt8to64  x)) => x
+(Trunc64to16 (ZeroExt8to64  x)) => (ZeroExt8to16  x)
+(Trunc64to16 (ZeroExt16to64 x)) => x
+(Trunc64to32 (ZeroExt8to64  x)) => (ZeroExt8to32  x)
+(Trunc64to32 (ZeroExt16to64 x)) => (ZeroExt16to32 x)
+(Trunc64to32 (ZeroExt32to64 x)) => x
+(Trunc16to8  (SignExt8to16  x)) => x
+(Trunc32to8  (SignExt8to32  x)) => x
+(Trunc32to16 (SignExt8to32  x)) => (SignExt8to16  x)
+(Trunc32to16 (SignExt16to32 x)) => x
+(Trunc64to8  (SignExt8to64  x)) => x
+(Trunc64to16 (SignExt8to64  x)) => (SignExt8to16  x)
+(Trunc64to16 (SignExt16to64 x)) => x
+(Trunc64to32 (SignExt8to64  x)) => (SignExt8to32  x)
+(Trunc64to32 (SignExt16to64 x)) => (SignExt16to32 x)
+(Trunc64to32 (SignExt32to64 x)) => x
+
+(ZeroExt8to16  (Const8  [c])) => (Const16 [int16( uint8(c))])
+(ZeroExt8to32  (Const8  [c])) => (Const32 [int32( uint8(c))])
+(ZeroExt8to64  (Const8  [c])) => (Const64 [int64( uint8(c))])
+(ZeroExt16to32 (Const16 [c])) => (Const32 [int32(uint16(c))])
+(ZeroExt16to64 (Const16 [c])) => (Const64 [int64(uint16(c))])
+(ZeroExt32to64 (Const32 [c])) => (Const64 [int64(uint32(c))])
+(SignExt8to16  (Const8  [c])) => (Const16 [int16(c)])
+(SignExt8to32  (Const8  [c])) => (Const32 [int32(c)])
+(SignExt8to64  (Const8  [c])) => (Const64 [int64(c)])
+(SignExt16to32 (Const16 [c])) => (Const32 [int32(c)])
+(SignExt16to64 (Const16 [c])) => (Const64 [int64(c)])
+(SignExt32to64 (Const32 [c])) => (Const64 [int64(c)])
+
+(Neg8   (Const8   [c])) => (Const8   [-c])
+(Neg16  (Const16  [c])) => (Const16  [-c])
+(Neg32  (Const32  [c])) => (Const32  [-c])
+(Neg64  (Const64  [c])) => (Const64  [-c])
+(Neg32F (Const32F [c])) && c != 0 => (Const32F [-c])
+(Neg64F (Const64F [c])) && c != 0 => (Const64F [-c])
+
+(Add8   (Const8 [c])   (Const8 [d]))   => (Const8  [c+d])
+(Add16  (Const16 [c])  (Const16 [d]))  => (Const16 [c+d])
+(Add32  (Const32 [c])  (Const32 [d]))  => (Const32 [c+d])
+(Add64  (Const64 [c])  (Const64 [d]))  => (Const64 [c+d])
+(Add32F (Const32F [c]) (Const32F [d])) && c+d == c+d => (Const32F [c+d])
+(Add64F (Const64F [c]) (Const64F [d])) && c+d == c+d => (Const64F [c+d])
+(AddPtr <t> x (Const64 [c])) => (OffPtr <t> x [c])
+(AddPtr <t> x (Const32 [c])) => (OffPtr <t> x [int64(c)])
+
+(Sub8   (Const8 [c]) (Const8 [d]))     => (Const8 [c-d])
+(Sub16  (Const16 [c]) (Const16 [d]))   => (Const16 [c-d])
+(Sub32  (Const32 [c]) (Const32 [d]))   => (Const32 [c-d])
+(Sub64  (Const64 [c]) (Const64 [d]))   => (Const64 [c-d])
+(Sub32F (Const32F [c]) (Const32F [d])) && c-d == c-d => (Const32F [c-d])
+(Sub64F (Const64F [c]) (Const64F [d])) && c-d == c-d => (Const64F [c-d])
+
+(Mul8   (Const8 [c])   (Const8 [d]))   => (Const8  [c*d])
+(Mul16  (Const16 [c])  (Const16 [d]))  => (Const16 [c*d])
+(Mul32  (Const32 [c])  (Const32 [d]))  => (Const32 [c*d])
+(Mul64  (Const64 [c])  (Const64 [d]))  => (Const64 [c*d])
+(Mul32F (Const32F [c]) (Const32F [d])) && c*d == c*d => (Const32F [c*d])
+(Mul64F (Const64F [c]) (Const64F [d])) && c*d == c*d => (Const64F [c*d])
+
+(And8   (Const8 [c])   (Const8 [d]))   => (Const8  [c&d])
+(And16  (Const16 [c])  (Const16 [d]))  => (Const16 [c&d])
+(And32  (Const32 [c])  (Const32 [d]))  => (Const32 [c&d])
+(And64  (Const64 [c])  (Const64 [d]))  => (Const64 [c&d])
+
+(Or8   (Const8 [c])   (Const8 [d]))   => (Const8  [c|d])
+(Or16  (Const16 [c])  (Const16 [d]))  => (Const16 [c|d])
+(Or32  (Const32 [c])  (Const32 [d]))  => (Const32 [c|d])
+(Or64  (Const64 [c])  (Const64 [d]))  => (Const64 [c|d])
+
+(Xor8   (Const8 [c])   (Const8 [d]))   => (Const8  [c^d])
+(Xor16  (Const16 [c])  (Const16 [d]))  => (Const16 [c^d])
+(Xor32  (Const32 [c])  (Const32 [d]))  => (Const32 [c^d])
+(Xor64  (Const64 [c])  (Const64 [d]))  => (Const64 [c^d])
+
+(Ctz64 (Const64 [c])) && config.PtrSize == 4 => (Const32 [int32(ntz64(c))])
+(Ctz32 (Const32 [c])) && config.PtrSize == 4 => (Const32 [int32(ntz32(c))])
+(Ctz16 (Const16 [c])) && config.PtrSize == 4 => (Const32 [int32(ntz16(c))])
+(Ctz8  (Const8  [c])) && config.PtrSize == 4 => (Const32 [int32(ntz8(c))])
+
+(Ctz64 (Const64 [c])) && config.PtrSize == 8 => (Const64 [int64(ntz64(c))])
+(Ctz32 (Const32 [c])) && config.PtrSize == 8 => (Const64 [int64(ntz32(c))])
+(Ctz16 (Const16 [c])) && config.PtrSize == 8 => (Const64 [int64(ntz16(c))])
+(Ctz8  (Const8  [c])) && config.PtrSize == 8 => (Const64 [int64(ntz8(c))])
+
+(Div8   (Const8  [c])  (Const8  [d])) && d != 0 => (Const8  [c/d])
+(Div16  (Const16 [c])  (Const16 [d])) && d != 0 => (Const16 [c/d])
+(Div32  (Const32 [c])  (Const32 [d])) && d != 0 => (Const32 [c/d])
+(Div64  (Const64 [c])  (Const64 [d])) && d != 0 => (Const64 [c/d])
+(Div8u  (Const8  [c])  (Const8  [d])) && d != 0 => (Const8  [int8(uint8(c)/uint8(d))])
+(Div16u (Const16 [c])  (Const16 [d])) && d != 0 => (Const16 [int16(uint16(c)/uint16(d))])
+(Div32u (Const32 [c])  (Const32 [d])) && d != 0 => (Const32 [int32(uint32(c)/uint32(d))])
+(Div64u (Const64 [c])  (Const64 [d])) && d != 0 => (Const64 [int64(uint64(c)/uint64(d))])
+(Div32F (Const32F [c]) (Const32F [d])) && c/d == c/d => (Const32F [c/d])
+(Div64F (Const64F [c]) (Const64F [d])) && c/d == c/d => (Const64F [c/d])
+(Select0 (Div128u (Const64 [0]) lo y)) => (Div64u lo y)
+(Select1 (Div128u (Const64 [0]) lo y)) => (Mod64u lo y)
+
+(Not (ConstBool [c])) => (ConstBool [!c])
+
+(Floor       (Const64F [c])) => (Const64F [math.Floor(c)])
+(Ceil        (Const64F [c])) => (Const64F [math.Ceil(c)])
+(Trunc       (Const64F [c])) => (Const64F [math.Trunc(c)])
+(RoundToEven (Const64F [c])) => (Const64F [math.RoundToEven(c)])
+
+// Convert x * 1 to x.
+(Mul(8|16|32|64)  (Const(8|16|32|64)  [1]) x) => x
+(Select0 (Mul(32|64)uover (Const(32|64) [1]) x)) => x
+(Select1 (Mul(32|64)uover (Const(32|64) [1]) x)) => (ConstBool [false])
+
+// Convert x * -1 to -x.
+(Mul(8|16|32|64)  (Const(8|16|32|64)  [-1]) x) => (Neg(8|16|32|64)  x)
+
+// Convert multiplication by a power of two to a shift.
+(Mul8  <t> n (Const8  [c])) && isPowerOfTwo8(c) => (Lsh8x64  <t> n (Const64 <typ.UInt64> [log8(c)]))
+(Mul16 <t> n (Const16 [c])) && isPowerOfTwo16(c) => (Lsh16x64 <t> n (Const64 <typ.UInt64> [log16(c)]))
+(Mul32 <t> n (Const32 [c])) && isPowerOfTwo32(c) => (Lsh32x64 <t> n (Const64 <typ.UInt64> [log32(c)]))
+(Mul64 <t> n (Const64 [c])) && isPowerOfTwo64(c) => (Lsh64x64 <t> n (Const64 <typ.UInt64> [log64(c)]))
+(Mul8  <t> n (Const8  [c])) && t.IsSigned() && isPowerOfTwo8(-c)  => (Neg8  (Lsh8x64  <t> n (Const64 <typ.UInt64> [log8(-c)])))
+(Mul16 <t> n (Const16 [c])) && t.IsSigned() && isPowerOfTwo16(-c) => (Neg16 (Lsh16x64 <t> n (Const64 <typ.UInt64> [log16(-c)])))
+(Mul32 <t> n (Const32 [c])) && t.IsSigned() && isPowerOfTwo32(-c) => (Neg32 (Lsh32x64 <t> n (Const64 <typ.UInt64> [log32(-c)])))
+(Mul64 <t> n (Const64 [c])) && t.IsSigned() && isPowerOfTwo64(-c) => (Neg64 (Lsh64x64 <t> n (Const64 <typ.UInt64> [log64(-c)])))
+
+(Mod8  (Const8  [c]) (Const8  [d])) && d != 0 => (Const8  [c % d])
+(Mod16 (Const16 [c]) (Const16 [d])) && d != 0 => (Const16 [c % d])
+(Mod32 (Const32 [c]) (Const32 [d])) && d != 0 => (Const32 [c % d])
+(Mod64 (Const64 [c]) (Const64 [d])) && d != 0 => (Const64 [c % d])
+
+(Mod8u  (Const8 [c])  (Const8  [d])) && d != 0 => (Const8  [int8(uint8(c) % uint8(d))])
+(Mod16u (Const16 [c]) (Const16 [d])) && d != 0 => (Const16 [int16(uint16(c) % uint16(d))])
+(Mod32u (Const32 [c]) (Const32 [d])) && d != 0 => (Const32 [int32(uint32(c) % uint32(d))])
+(Mod64u (Const64 [c]) (Const64 [d])) && d != 0 => (Const64 [int64(uint64(c) % uint64(d))])
+
+(Lsh64x64  (Const64 [c]) (Const64 [d])) => (Const64 [c << uint64(d)])
+(Rsh64x64  (Const64 [c]) (Const64 [d])) => (Const64 [c >> uint64(d)])
+(Rsh64Ux64 (Const64 [c]) (Const64 [d])) => (Const64 [int64(uint64(c) >> uint64(d))])
+(Lsh32x64  (Const32 [c]) (Const64 [d])) => (Const32 [c << uint64(d)])
+(Rsh32x64  (Const32 [c]) (Const64 [d])) => (Const32 [c >> uint64(d)])
+(Rsh32Ux64 (Const32 [c]) (Const64 [d])) => (Const32 [int32(uint32(c) >> uint64(d))])
+(Lsh16x64  (Const16 [c]) (Const64 [d])) => (Const16 [c << uint64(d)])
+(Rsh16x64  (Const16 [c]) (Const64 [d])) => (Const16 [c >> uint64(d)])
+(Rsh16Ux64 (Const16 [c]) (Const64 [d])) => (Const16 [int16(uint16(c) >> uint64(d))])
+(Lsh8x64   (Const8  [c]) (Const64 [d])) => (Const8  [c << uint64(d)])
+(Rsh8x64   (Const8  [c]) (Const64 [d])) => (Const8  [c >> uint64(d)])
+(Rsh8Ux64  (Const8  [c]) (Const64 [d])) => (Const8  [int8(uint8(c) >> uint64(d))])
+
+// Fold IsInBounds when the range of the index cannot exceed the limit.
+(IsInBounds (ZeroExt8to32  _) (Const32 [c])) && (1 << 8)  <= c => (ConstBool [true])
+(IsInBounds (ZeroExt8to64  _) (Const64 [c])) && (1 << 8)  <= c => (ConstBool [true])
+(IsInBounds (ZeroExt16to32 _) (Const32 [c])) && (1 << 16) <= c => (ConstBool [true])
+(IsInBounds (ZeroExt16to64 _) (Const64 [c])) && (1 << 16) <= c => (ConstBool [true])
+(IsInBounds x x) => (ConstBool [false])
+(IsInBounds                (And8  (Const8  [c]) _)  (Const8  [d])) && 0 <= c && c < d => (ConstBool [true])
+(IsInBounds (ZeroExt8to16  (And8  (Const8  [c]) _)) (Const16 [d])) && 0 <= c && int16(c) < d => (ConstBool [true])
+(IsInBounds (ZeroExt8to32  (And8  (Const8  [c]) _)) (Const32 [d])) && 0 <= c && int32(c) < d => (ConstBool [true])
+(IsInBounds (ZeroExt8to64  (And8  (Const8  [c]) _)) (Const64 [d])) && 0 <= c && int64(c) < d => (ConstBool [true])
+(IsInBounds                (And16 (Const16 [c]) _)  (Const16 [d])) && 0 <= c && c < d => (ConstBool [true])
+(IsInBounds (ZeroExt16to32 (And16 (Const16 [c]) _)) (Const32 [d])) && 0 <= c && int32(c) < d => (ConstBool [true])
+(IsInBounds (ZeroExt16to64 (And16 (Const16 [c]) _)) (Const64 [d])) && 0 <= c && int64(c) < d => (ConstBool [true])
+(IsInBounds                (And32 (Const32 [c]) _)  (Const32 [d])) && 0 <= c && c < d => (ConstBool [true])
+(IsInBounds (ZeroExt32to64 (And32 (Const32 [c]) _)) (Const64 [d])) && 0 <= c && int64(c) < d => (ConstBool [true])
+(IsInBounds                (And64 (Const64 [c]) _)  (Const64 [d])) && 0 <= c && c < d => (ConstBool [true])
+(IsInBounds (Const32 [c]) (Const32 [d])) => (ConstBool [0 <= c && c < d])
+(IsInBounds (Const64 [c]) (Const64 [d])) => (ConstBool [0 <= c && c < d])
+// (Mod64u x y) is always between 0 (inclusive) and y (exclusive).
+(IsInBounds (Mod32u _ y) y) => (ConstBool [true])
+(IsInBounds (Mod64u _ y) y) => (ConstBool [true])
+// Right shifting an unsigned number limits its value.
+(IsInBounds (ZeroExt8to64  (Rsh8Ux64  _ (Const64 [c]))) (Const64 [d])) && 0 < c && c <  8 && 1<<uint( 8-c)-1 < d => (ConstBool [true])
+(IsInBounds (ZeroExt8to32  (Rsh8Ux64  _ (Const64 [c]))) (Const32 [d])) && 0 < c && c <  8 && 1<<uint( 8-c)-1 < d => (ConstBool [true])
+(IsInBounds (ZeroExt8to16  (Rsh8Ux64  _ (Const64 [c]))) (Const16 [d])) && 0 < c && c <  8 && 1<<uint( 8-c)-1 < d => (ConstBool [true])
+(IsInBounds                (Rsh8Ux64  _ (Const64 [c]))  (Const64 [d])) && 0 < c && c <  8 && 1<<uint( 8-c)-1 < d => (ConstBool [true])
+(IsInBounds (ZeroExt16to64 (Rsh16Ux64 _ (Const64 [c]))) (Const64 [d])) && 0 < c && c < 16 && 1<<uint(16-c)-1 < d => (ConstBool [true])
+(IsInBounds (ZeroExt16to32 (Rsh16Ux64 _ (Const64 [c]))) (Const64 [d])) && 0 < c && c < 16 && 1<<uint(16-c)-1 < d => (ConstBool [true])
+(IsInBounds                (Rsh16Ux64 _ (Const64 [c]))  (Const64 [d])) && 0 < c && c < 16 && 1<<uint(16-c)-1 < d => (ConstBool [true])
+(IsInBounds (ZeroExt32to64 (Rsh32Ux64 _ (Const64 [c]))) (Const64 [d])) && 0 < c && c < 32 && 1<<uint(32-c)-1 < d => (ConstBool [true])
+(IsInBounds                (Rsh32Ux64 _ (Const64 [c]))  (Const64 [d])) && 0 < c && c < 32 && 1<<uint(32-c)-1 < d => (ConstBool [true])
+(IsInBounds                (Rsh64Ux64 _ (Const64 [c]))  (Const64 [d])) && 0 < c && c < 64 && 1<<uint(64-c)-1 < d => (ConstBool [true])
+
+(IsSliceInBounds x x) => (ConstBool [true])
+(IsSliceInBounds (And32 (Const32 [c]) _) (Const32 [d])) && 0 <= c && c <= d => (ConstBool [true])
+(IsSliceInBounds (And64 (Const64 [c]) _) (Const64 [d])) && 0 <= c && c <= d => (ConstBool [true])
+(IsSliceInBounds (Const32 [0]) _) => (ConstBool [true])
+(IsSliceInBounds (Const64 [0]) _) => (ConstBool [true])
+(IsSliceInBounds (Const32 [c]) (Const32 [d])) => (ConstBool [0 <= c && c <= d])
+(IsSliceInBounds (Const64 [c]) (Const64 [d])) => (ConstBool [0 <= c && c <= d])
+(IsSliceInBounds (SliceLen x) (SliceCap x)) => (ConstBool [true])
+
+(Eq(64|32|16|8) x x) => (ConstBool [true])
+(EqB (ConstBool [c]) (ConstBool [d])) => (ConstBool [c == d])
+(EqB (ConstBool [false]) x) => (Not x)
+(EqB (ConstBool [true]) x) => x
+
+(Neq(64|32|16|8) x x) => (ConstBool [false])
+(NeqB (ConstBool [c]) (ConstBool [d])) => (ConstBool [c != d])
+(NeqB (ConstBool [false]) x) => x
+(NeqB (ConstBool [true]) x) => (Not x)
+(NeqB (Not x) (Not y)) => (NeqB x y)
+
+(Eq64 (Const64 <t> [c]) (Add64 (Const64 <t> [d]) x)) => (Eq64 (Const64 <t> [c-d]) x)
+(Eq32 (Const32 <t> [c]) (Add32 (Const32 <t> [d]) x)) => (Eq32 (Const32 <t> [c-d]) x)
+(Eq16 (Const16 <t> [c]) (Add16 (Const16 <t> [d]) x)) => (Eq16 (Const16 <t> [c-d]) x)
+(Eq8  (Const8  <t> [c]) (Add8  (Const8  <t> [d]) x)) => (Eq8  (Const8  <t> [c-d]) x)
+
+(Neq64 (Const64 <t> [c]) (Add64 (Const64 <t> [d]) x)) => (Neq64 (Const64 <t> [c-d]) x)
+(Neq32 (Const32 <t> [c]) (Add32 (Const32 <t> [d]) x)) => (Neq32 (Const32 <t> [c-d]) x)
+(Neq16 (Const16 <t> [c]) (Add16 (Const16 <t> [d]) x)) => (Neq16 (Const16 <t> [c-d]) x)
+(Neq8  (Const8  <t> [c]) (Add8  (Const8  <t> [d]) x)) => (Neq8  (Const8  <t> [c-d]) x)
+
+// signed integer range: ( c <= x && x (<|<=) d ) -> ( unsigned(x-c) (<|<=) unsigned(d-c) )
+(AndB (Leq64 (Const64 [c]) x) ((Less|Leq)64 x (Const64 [d]))) && d >= c => ((Less|Leq)64U (Sub64 <x.Type> x (Const64 <x.Type> [c])) (Const64 <x.Type> [d-c]))
+(AndB (Leq32 (Const32 [c]) x) ((Less|Leq)32 x (Const32 [d]))) && d >= c => ((Less|Leq)32U (Sub32 <x.Type> x (Const32 <x.Type> [c])) (Const32 <x.Type> [d-c]))
+(AndB (Leq16 (Const16 [c]) x) ((Less|Leq)16 x (Const16 [d]))) && d >= c => ((Less|Leq)16U (Sub16 <x.Type> x (Const16 <x.Type> [c])) (Const16 <x.Type> [d-c]))
+(AndB (Leq8  (Const8  [c]) x) ((Less|Leq)8  x (Const8  [d]))) && d >= c => ((Less|Leq)8U  (Sub8  <x.Type> x (Const8  <x.Type> [c])) (Const8  <x.Type> [d-c]))
+
+// signed integer range: ( c < x && x (<|<=) d ) -> ( unsigned(x-(c+1)) (<|<=) unsigned(d-(c+1)) )
+(AndB (Less64 (Const64 [c]) x) ((Less|Leq)64 x (Const64 [d]))) && d >= c+1 && c+1 > c => ((Less|Leq)64U (Sub64 <x.Type> x (Const64 <x.Type> [c+1])) (Const64 <x.Type> [d-c-1]))
+(AndB (Less32 (Const32 [c]) x) ((Less|Leq)32 x (Const32 [d]))) && d >= c+1 && c+1 > c => ((Less|Leq)32U (Sub32 <x.Type> x (Const32 <x.Type> [c+1])) (Const32 <x.Type> [d-c-1]))
+(AndB (Less16 (Const16 [c]) x) ((Less|Leq)16 x (Const16 [d]))) && d >= c+1 && c+1 > c => ((Less|Leq)16U (Sub16 <x.Type> x (Const16 <x.Type> [c+1])) (Const16 <x.Type> [d-c-1]))
+(AndB (Less8  (Const8  [c]) x) ((Less|Leq)8  x (Const8  [d]))) && d >= c+1 && c+1 > c => ((Less|Leq)8U  (Sub8  <x.Type> x (Const8  <x.Type> [c+1])) (Const8  <x.Type> [d-c-1]))
+
+// unsigned integer range: ( c <= x && x (<|<=) d ) -> ( x-c (<|<=) d-c )
+(AndB (Leq64U (Const64 [c]) x) ((Less|Leq)64U x (Const64 [d]))) && uint64(d) >= uint64(c) => ((Less|Leq)64U (Sub64 <x.Type> x (Const64 <x.Type> [c])) (Const64 <x.Type> [d-c]))
+(AndB (Leq32U (Const32 [c]) x) ((Less|Leq)32U x (Const32 [d]))) && uint32(d) >= uint32(c) => ((Less|Leq)32U (Sub32 <x.Type> x (Const32 <x.Type> [c])) (Const32 <x.Type> [d-c]))
+(AndB (Leq16U (Const16 [c]) x) ((Less|Leq)16U x (Const16 [d]))) && uint16(d) >= uint16(c) => ((Less|Leq)16U (Sub16 <x.Type> x (Const16 <x.Type> [c])) (Const16 <x.Type> [d-c]))
+(AndB (Leq8U  (Const8  [c]) x) ((Less|Leq)8U  x (Const8  [d]))) && uint8(d)  >= uint8(c)  => ((Less|Leq)8U  (Sub8  <x.Type> x (Const8  <x.Type> [c])) (Const8  <x.Type> [d-c]))
+
+// unsigned integer range: ( c < x && x (<|<=) d ) -> ( x-(c+1) (<|<=) d-(c+1) )
+(AndB (Less64U (Const64 [c]) x) ((Less|Leq)64U x (Const64 [d]))) && uint64(d) >= uint64(c+1) && uint64(c+1) > uint64(c) => ((Less|Leq)64U (Sub64 <x.Type> x (Const64 <x.Type> [c+1])) (Const64 <x.Type> [d-c-1]))
+(AndB (Less32U (Const32 [c]) x) ((Less|Leq)32U x (Const32 [d]))) && uint32(d) >= uint32(c+1) && uint32(c+1) > uint32(c) => ((Less|Leq)32U (Sub32 <x.Type> x (Const32 <x.Type> [c+1])) (Const32 <x.Type> [d-c-1]))
+(AndB (Less16U (Const16 [c]) x) ((Less|Leq)16U x (Const16 [d]))) && uint16(d) >= uint16(c+1) && uint16(c+1) > uint16(c) => ((Less|Leq)16U (Sub16 <x.Type> x (Const16 <x.Type> [c+1])) (Const16 <x.Type> [d-c-1]))
+(AndB (Less8U  (Const8  [c]) x) ((Less|Leq)8U  x (Const8  [d]))) && uint8(d)  >= uint8(c+1)  && uint8(c+1)  > uint8(c)  => ((Less|Leq)8U  (Sub8  <x.Type> x (Const8  <x.Type> [c+1]))  (Const8  <x.Type> [d-c-1]))
+
+// signed integer range: ( c (<|<=) x || x < d ) -> ( unsigned(c-d) (<|<=) unsigned(x-d) )
+(OrB ((Less|Leq)64 (Const64 [c]) x) (Less64 x (Const64 [d]))) && c >= d => ((Less|Leq)64U (Const64 <x.Type> [c-d]) (Sub64 <x.Type> x (Const64 <x.Type> [d])))
+(OrB ((Less|Leq)32 (Const32 [c]) x) (Less32 x (Const32 [d]))) && c >= d => ((Less|Leq)32U (Const32 <x.Type> [c-d]) (Sub32 <x.Type> x (Const32 <x.Type> [d])))
+(OrB ((Less|Leq)16 (Const16 [c]) x) (Less16 x (Const16 [d]))) && c >= d => ((Less|Leq)16U (Const16 <x.Type> [c-d]) (Sub16 <x.Type> x (Const16 <x.Type> [d])))
+(OrB ((Less|Leq)8  (Const8  [c]) x) (Less8  x (Const8  [d]))) && c >= d => ((Less|Leq)8U  (Const8  <x.Type> [c-d]) (Sub8  <x.Type> x (Const8  <x.Type> [d])))
+
+// signed integer range: ( c (<|<=) x || x <= d ) -> ( unsigned(c-(d+1)) (<|<=) unsigned(x-(d+1)) )
+(OrB ((Less|Leq)64 (Const64 [c]) x) (Leq64 x (Const64 [d]))) && c >= d+1 && d+1 > d => ((Less|Leq)64U (Const64 <x.Type> [c-d-1]) (Sub64 <x.Type> x (Const64 <x.Type> [d+1])))
+(OrB ((Less|Leq)32 (Const32 [c]) x) (Leq32 x (Const32 [d]))) && c >= d+1 && d+1 > d => ((Less|Leq)32U (Const32 <x.Type> [c-d-1]) (Sub32 <x.Type> x (Const32 <x.Type> [d+1])))
+(OrB ((Less|Leq)16 (Const16 [c]) x) (Leq16 x (Const16 [d]))) && c >= d+1 && d+1 > d => ((Less|Leq)16U (Const16 <x.Type> [c-d-1]) (Sub16 <x.Type> x (Const16 <x.Type> [d+1])))
+(OrB ((Less|Leq)8  (Const8  [c]) x) (Leq8  x (Const8  [d]))) && c >= d+1 && d+1 > d => ((Less|Leq)8U  (Const8  <x.Type> [c-d-1]) (Sub8  <x.Type> x (Const8  <x.Type> [d+1])))
+
+// unsigned integer range: ( c (<|<=) x || x < d ) -> ( c-d (<|<=) x-d )
+(OrB ((Less|Leq)64U (Const64 [c]) x) (Less64U x (Const64 [d]))) && uint64(c) >= uint64(d) => ((Less|Leq)64U (Const64 <x.Type> [c-d]) (Sub64 <x.Type> x (Const64 <x.Type> [d])))
+(OrB ((Less|Leq)32U (Const32 [c]) x) (Less32U x (Const32 [d]))) && uint32(c) >= uint32(d) => ((Less|Leq)32U (Const32 <x.Type> [c-d]) (Sub32 <x.Type> x (Const32 <x.Type> [d])))
+(OrB ((Less|Leq)16U (Const16 [c]) x) (Less16U x (Const16 [d]))) && uint16(c) >= uint16(d) => ((Less|Leq)16U (Const16 <x.Type> [c-d]) (Sub16 <x.Type> x (Const16 <x.Type> [d])))
+(OrB ((Less|Leq)8U  (Const8  [c]) x) (Less8U  x (Const8  [d]))) && uint8(c)  >= uint8(d)  => ((Less|Leq)8U  (Const8  <x.Type> [c-d]) (Sub8  <x.Type> x (Const8  <x.Type> [d])))
+
+// unsigned integer range: ( c (<|<=) x || x <= d ) -> ( c-(d+1) (<|<=) x-(d+1) )
+(OrB ((Less|Leq)64U (Const64 [c]) x) (Leq64U x (Const64 [d]))) && uint64(c) >= uint64(d+1) && uint64(d+1) > uint64(d) => ((Less|Leq)64U (Const64 <x.Type> [c-d-1]) (Sub64 <x.Type> x (Const64 <x.Type> [d+1])))
+(OrB ((Less|Leq)32U (Const32 [c]) x) (Leq32U x (Const32 [d]))) && uint32(c) >= uint32(d+1) && uint32(d+1) > uint32(d) => ((Less|Leq)32U (Const32 <x.Type> [c-d-1]) (Sub32 <x.Type> x (Const32 <x.Type> [d+1])))
+(OrB ((Less|Leq)16U (Const16 [c]) x) (Leq16U x (Const16 [d]))) && uint16(c) >= uint16(d+1) && uint16(d+1) > uint16(d) => ((Less|Leq)16U (Const16 <x.Type> [c-d-1]) (Sub16 <x.Type> x (Const16 <x.Type> [d+1])))
+(OrB ((Less|Leq)8U  (Const8  [c]) x) (Leq8U  x (Const8  [d]))) && uint8(c)  >= uint8(d+1)  && uint8(d+1)  > uint8(d)  => ((Less|Leq)8U  (Const8  <x.Type> [c-d-1]) (Sub8  <x.Type> x (Const8  <x.Type> [d+1])))
+
+// Canonicalize x-const to x+(-const)
+(Sub64 x (Const64 <t> [c])) && x.Op != OpConst64 => (Add64 (Const64 <t> [-c]) x)
+(Sub32 x (Const32 <t> [c])) && x.Op != OpConst32 => (Add32 (Const32 <t> [-c]) x)
+(Sub16 x (Const16 <t> [c])) && x.Op != OpConst16 => (Add16 (Const16 <t> [-c]) x)
+(Sub8  x (Const8  <t> [c])) && x.Op != OpConst8  => (Add8  (Const8  <t> [-c]) x)
+
+// fold negation into comparison operators
+(Not (Eq(64|32|16|8|B|Ptr|64F|32F) x y)) => (Neq(64|32|16|8|B|Ptr|64F|32F) x y)
+(Not (Neq(64|32|16|8|B|Ptr|64F|32F) x y)) => (Eq(64|32|16|8|B|Ptr|64F|32F) x y)
+
+(Not (Less(64|32|16|8) x y)) => (Leq(64|32|16|8) y x)
+(Not (Less(64|32|16|8)U x y)) => (Leq(64|32|16|8)U y x)
+(Not (Leq(64|32|16|8) x y)) => (Less(64|32|16|8) y x)
+(Not (Leq(64|32|16|8)U x y)) => (Less(64|32|16|8)U y x)
+
+// Distribute multiplication c * (d+x) -> c*d + c*x. Useful for:
+// a[i].b = ...; a[i+1].b = ...
+(Mul64 (Const64 <t> [c]) (Add64 <t> (Const64 <t> [d]) x)) =>
+  (Add64 (Const64 <t> [c*d]) (Mul64 <t> (Const64 <t> [c]) x))
+(Mul32 (Const32 <t> [c]) (Add32 <t> (Const32 <t> [d]) x)) =>
+  (Add32 (Const32 <t> [c*d]) (Mul32 <t> (Const32 <t> [c]) x))
+
+// Rewrite x*y ± x*z  to  x*(y±z)
+(Add(64|32|16|8) <t> (Mul(64|32|16|8) x y) (Mul(64|32|16|8) x z))
+	=> (Mul(64|32|16|8) x (Add(64|32|16|8) <t> y z))
+(Sub(64|32|16|8) <t> (Mul(64|32|16|8) x y) (Mul(64|32|16|8) x z))
+	=> (Mul(64|32|16|8) x (Sub(64|32|16|8) <t> y z))
+
+// rewrite shifts of 8/16/32 bit consts into 64 bit consts to reduce
+// the number of the other rewrite rules for const shifts
+(Lsh64x32  <t> x (Const32 [c])) => (Lsh64x64  x (Const64 <t> [int64(uint32(c))]))
+(Lsh64x16  <t> x (Const16 [c])) => (Lsh64x64  x (Const64 <t> [int64(uint16(c))]))
+(Lsh64x8   <t> x (Const8  [c])) => (Lsh64x64  x (Const64 <t> [int64(uint8(c))]))
+(Rsh64x32  <t> x (Const32 [c])) => (Rsh64x64  x (Const64 <t> [int64(uint32(c))]))
+(Rsh64x16  <t> x (Const16 [c])) => (Rsh64x64  x (Const64 <t> [int64(uint16(c))]))
+(Rsh64x8   <t> x (Const8  [c])) => (Rsh64x64  x (Const64 <t> [int64(uint8(c))]))
+(Rsh64Ux32 <t> x (Const32 [c])) => (Rsh64Ux64 x (Const64 <t> [int64(uint32(c))]))
+(Rsh64Ux16 <t> x (Const16 [c])) => (Rsh64Ux64 x (Const64 <t> [int64(uint16(c))]))
+(Rsh64Ux8  <t> x (Const8  [c])) => (Rsh64Ux64 x (Const64 <t> [int64(uint8(c))]))
+
+(Lsh32x32  <t> x (Const32 [c])) => (Lsh32x64  x (Const64 <t> [int64(uint32(c))]))
+(Lsh32x16  <t> x (Const16 [c])) => (Lsh32x64  x (Const64 <t> [int64(uint16(c))]))
+(Lsh32x8   <t> x (Const8  [c])) => (Lsh32x64  x (Const64 <t> [int64(uint8(c))]))
+(Rsh32x32  <t> x (Const32 [c])) => (Rsh32x64  x (Const64 <t> [int64(uint32(c))]))
+(Rsh32x16  <t> x (Const16 [c])) => (Rsh32x64  x (Const64 <t> [int64(uint16(c))]))
+(Rsh32x8   <t> x (Const8  [c])) => (Rsh32x64  x (Const64 <t> [int64(uint8(c))]))
+(Rsh32Ux32 <t> x (Const32 [c])) => (Rsh32Ux64 x (Const64 <t> [int64(uint32(c))]))
+(Rsh32Ux16 <t> x (Const16 [c])) => (Rsh32Ux64 x (Const64 <t> [int64(uint16(c))]))
+(Rsh32Ux8  <t> x (Const8  [c])) => (Rsh32Ux64 x (Const64 <t> [int64(uint8(c))]))
+
+(Lsh16x32  <t> x (Const32 [c])) => (Lsh16x64  x (Const64 <t> [int64(uint32(c))]))
+(Lsh16x16  <t> x (Const16 [c])) => (Lsh16x64  x (Const64 <t> [int64(uint16(c))]))
+(Lsh16x8   <t> x (Const8  [c])) => (Lsh16x64  x (Const64 <t> [int64(uint8(c))]))
+(Rsh16x32  <t> x (Const32 [c])) => (Rsh16x64  x (Const64 <t> [int64(uint32(c))]))
+(Rsh16x16  <t> x (Const16 [c])) => (Rsh16x64  x (Const64 <t> [int64(uint16(c))]))
+(Rsh16x8   <t> x (Const8  [c])) => (Rsh16x64  x (Const64 <t> [int64(uint8(c))]))
+(Rsh16Ux32 <t> x (Const32 [c])) => (Rsh16Ux64 x (Const64 <t> [int64(uint32(c))]))
+(Rsh16Ux16 <t> x (Const16 [c])) => (Rsh16Ux64 x (Const64 <t> [int64(uint16(c))]))
+(Rsh16Ux8  <t> x (Const8  [c])) => (Rsh16Ux64 x (Const64 <t> [int64(uint8(c))]))
+
+(Lsh8x32  <t> x (Const32 [c])) => (Lsh8x64  x (Const64 <t> [int64(uint32(c))]))
+(Lsh8x16  <t> x (Const16 [c])) => (Lsh8x64  x (Const64 <t> [int64(uint16(c))]))
+(Lsh8x8   <t> x (Const8  [c])) => (Lsh8x64  x (Const64 <t> [int64(uint8(c))]))
+(Rsh8x32  <t> x (Const32 [c])) => (Rsh8x64  x (Const64 <t> [int64(uint32(c))]))
+(Rsh8x16  <t> x (Const16 [c])) => (Rsh8x64  x (Const64 <t> [int64(uint16(c))]))
+(Rsh8x8   <t> x (Const8  [c])) => (Rsh8x64  x (Const64 <t> [int64(uint8(c))]))
+(Rsh8Ux32 <t> x (Const32 [c])) => (Rsh8Ux64 x (Const64 <t> [int64(uint32(c))]))
+(Rsh8Ux16 <t> x (Const16 [c])) => (Rsh8Ux64 x (Const64 <t> [int64(uint16(c))]))
+(Rsh8Ux8  <t> x (Const8  [c])) => (Rsh8Ux64 x (Const64 <t> [int64(uint8(c))]))
+
+// shifts by zero
+(Lsh(64|32|16|8)x64  x (Const64 [0])) => x
+(Rsh(64|32|16|8)x64  x (Const64 [0])) => x
+(Rsh(64|32|16|8)Ux64 x (Const64 [0])) => x
+
+// rotates by multiples of register width
+(RotateLeft64 x (Const64 [c])) && c%64 == 0 => x
+(RotateLeft32 x (Const32 [c])) && c%32 == 0 => x
+(RotateLeft16 x (Const16 [c])) && c%16 == 0 => x
+(RotateLeft8  x (Const8 [c]))  && c%8  == 0 => x
+
+// zero shifted
+(Lsh64x(64|32|16|8)  (Const64 [0]) _) => (Const64 [0])
+(Rsh64x(64|32|16|8)  (Const64 [0]) _) => (Const64 [0])
+(Rsh64Ux(64|32|16|8) (Const64 [0]) _) => (Const64 [0])
+(Lsh32x(64|32|16|8)  (Const32 [0]) _) => (Const32 [0])
+(Rsh32x(64|32|16|8)  (Const32 [0]) _) => (Const32 [0])
+(Rsh32Ux(64|32|16|8) (Const32 [0]) _) => (Const32 [0])
+(Lsh16x(64|32|16|8)  (Const16 [0]) _) => (Const16 [0])
+(Rsh16x(64|32|16|8)  (Const16 [0]) _) => (Const16 [0])
+(Rsh16Ux(64|32|16|8) (Const16 [0]) _) => (Const16 [0])
+(Lsh8x(64|32|16|8)   (Const8  [0]) _) => (Const8  [0])
+(Rsh8x(64|32|16|8)   (Const8  [0]) _) => (Const8  [0])
+(Rsh8Ux(64|32|16|8)  (Const8  [0]) _) => (Const8  [0])
+
+// large left shifts of all values, and right shifts of unsigned values
+((Lsh64|Rsh64U)x64  _ (Const64 [c])) && uint64(c) >= 64 => (Const64 [0])
+((Lsh32|Rsh32U)x64  _ (Const64 [c])) && uint64(c) >= 32 => (Const32 [0])
+((Lsh16|Rsh16U)x64  _ (Const64 [c])) && uint64(c) >= 16 => (Const16 [0])
+((Lsh8|Rsh8U)x64    _ (Const64 [c])) && uint64(c) >= 8  => (Const8  [0])
+
+// combine const shifts
+(Lsh64x64 <t> (Lsh64x64 x (Const64 [c])) (Const64 [d])) && !uaddOvf(c,d) => (Lsh64x64 x (Const64 <t> [c+d]))
+(Lsh32x64 <t> (Lsh32x64 x (Const64 [c])) (Const64 [d])) && !uaddOvf(c,d) => (Lsh32x64 x (Const64 <t> [c+d]))
+(Lsh16x64 <t> (Lsh16x64 x (Const64 [c])) (Const64 [d])) && !uaddOvf(c,d) => (Lsh16x64 x (Const64 <t> [c+d]))
+(Lsh8x64  <t> (Lsh8x64  x (Const64 [c])) (Const64 [d])) && !uaddOvf(c,d) => (Lsh8x64  x (Const64 <t> [c+d]))
+
+(Rsh64x64 <t> (Rsh64x64 x (Const64 [c])) (Const64 [d])) && !uaddOvf(c,d) => (Rsh64x64 x (Const64 <t> [c+d]))
+(Rsh32x64 <t> (Rsh32x64 x (Const64 [c])) (Const64 [d])) && !uaddOvf(c,d) => (Rsh32x64 x (Const64 <t> [c+d]))
+(Rsh16x64 <t> (Rsh16x64 x (Const64 [c])) (Const64 [d])) && !uaddOvf(c,d) => (Rsh16x64 x (Const64 <t> [c+d]))
+(Rsh8x64  <t> (Rsh8x64  x (Const64 [c])) (Const64 [d])) && !uaddOvf(c,d) => (Rsh8x64  x (Const64 <t> [c+d]))
+
+(Rsh64Ux64 <t> (Rsh64Ux64 x (Const64 [c])) (Const64 [d])) && !uaddOvf(c,d) => (Rsh64Ux64 x (Const64 <t> [c+d]))
+(Rsh32Ux64 <t> (Rsh32Ux64 x (Const64 [c])) (Const64 [d])) && !uaddOvf(c,d) => (Rsh32Ux64 x (Const64 <t> [c+d]))
+(Rsh16Ux64 <t> (Rsh16Ux64 x (Const64 [c])) (Const64 [d])) && !uaddOvf(c,d) => (Rsh16Ux64 x (Const64 <t> [c+d]))
+(Rsh8Ux64  <t> (Rsh8Ux64  x (Const64 [c])) (Const64 [d])) && !uaddOvf(c,d) => (Rsh8Ux64  x (Const64 <t> [c+d]))
+
+// Remove signed right shift before an unsigned right shift that extracts the sign bit.
+(Rsh8Ux64  (Rsh8x64  x _) (Const64 <t> [7] )) => (Rsh8Ux64  x (Const64 <t> [7] ))
+(Rsh16Ux64 (Rsh16x64 x _) (Const64 <t> [15])) => (Rsh16Ux64 x (Const64 <t> [15]))
+(Rsh32Ux64 (Rsh32x64 x _) (Const64 <t> [31])) => (Rsh32Ux64 x (Const64 <t> [31]))
+(Rsh64Ux64 (Rsh64x64 x _) (Const64 <t> [63])) => (Rsh64Ux64 x (Const64 <t> [63]))
+
+// Convert x>>c<<c to x&^(1<<c-1)
+(Lsh64x64 i:(Rsh(64|64U)x64  x (Const64 [c])) (Const64 [c])) && c >= 0 && c < 64 && i.Uses == 1 => (And64 x (Const64 <v.Type> [int64(-1) << c]))
+(Lsh32x64 i:(Rsh(32|32U)x64  x (Const64 [c])) (Const64 [c])) && c >= 0 && c < 32 && i.Uses == 1 => (And32 x (Const32 <v.Type> [int32(-1) << c]))
+(Lsh16x64 i:(Rsh(16|16U)x64  x (Const64 [c])) (Const64 [c])) && c >= 0 && c < 16 && i.Uses == 1 => (And16 x (Const16 <v.Type> [int16(-1) << c]))
+(Lsh8x64  i:(Rsh(8|8U)x64    x (Const64 [c])) (Const64 [c])) && c >= 0 && c < 8  && i.Uses == 1 => (And8  x (Const8  <v.Type> [int8(-1)  << c]))
+// similarly for x<<c>>c
+(Rsh64Ux64 i:(Lsh64x64 x (Const64 [c])) (Const64 [c])) && c >= 0 && c < 64 && i.Uses == 1 => (And64 x (Const64 <v.Type> [int64(^uint64(0)>>c)]))
+(Rsh32Ux64 i:(Lsh32x64 x (Const64 [c])) (Const64 [c])) && c >= 0 && c < 32 && i.Uses == 1 => (And32 x (Const32 <v.Type> [int32(^uint32(0)>>c)]))
+(Rsh16Ux64 i:(Lsh16x64 x (Const64 [c])) (Const64 [c])) && c >= 0 && c < 16 && i.Uses == 1 => (And16 x (Const16 <v.Type> [int16(^uint16(0)>>c)]))
+(Rsh8Ux64  i:(Lsh8x64  x (Const64 [c])) (Const64 [c])) && c >= 0 && c < 8  && i.Uses == 1 => (And8  x (Const8  <v.Type> [int8 (^uint8 (0)>>c)]))
+
+// ((x >> c1) << c2) >> c3
+(Rsh(64|32|16|8)Ux64 (Lsh(64|32|16|8)x64 (Rsh(64|32|16|8)Ux64 x (Const64 [c1])) (Const64 [c2])) (Const64 [c3]))
+  && uint64(c1) >= uint64(c2) && uint64(c3) >= uint64(c2) && !uaddOvf(c1-c2, c3)
+  => (Rsh(64|32|16|8)Ux64 x (Const64 <typ.UInt64> [c1-c2+c3]))
+
+// ((x << c1) >> c2) << c3
+(Lsh(64|32|16|8)x64 (Rsh(64|32|16|8)Ux64 (Lsh(64|32|16|8)x64 x (Const64 [c1])) (Const64 [c2])) (Const64 [c3]))
+  && uint64(c1) >= uint64(c2) && uint64(c3) >= uint64(c2) && !uaddOvf(c1-c2, c3)
+  => (Lsh(64|32|16|8)x64 x (Const64 <typ.UInt64> [c1-c2+c3]))
+
+// (x >> c) & uppermask = 0
+(And64 (Const64 [m]) (Rsh64Ux64 _ (Const64 [c]))) && c >= int64(64-ntz64(m)) => (Const64 [0])
+(And32 (Const32 [m]) (Rsh32Ux64 _ (Const64 [c]))) && c >= int64(32-ntz32(m)) => (Const32 [0])
+(And16 (Const16 [m]) (Rsh16Ux64 _ (Const64 [c]))) && c >= int64(16-ntz16(m)) => (Const16 [0])
+(And8  (Const8  [m]) (Rsh8Ux64  _ (Const64 [c]))) && c >= int64(8-ntz8(m))  => (Const8  [0])
+
+// (x << c) & lowermask = 0
+(And64 (Const64 [m]) (Lsh64x64  _ (Const64 [c]))) && c >= int64(64-nlz64(m)) => (Const64 [0])
+(And32 (Const32 [m]) (Lsh32x64  _ (Const64 [c]))) && c >= int64(32-nlz32(m)) => (Const32 [0])
+(And16 (Const16 [m]) (Lsh16x64  _ (Const64 [c]))) && c >= int64(16-nlz16(m)) => (Const16 [0])
+(And8  (Const8  [m]) (Lsh8x64   _ (Const64 [c]))) && c >= int64(8-nlz8(m))  => (Const8  [0])
+
+// replace shifts with zero extensions
+(Rsh16Ux64 (Lsh16x64 x (Const64  [8])) (Const64  [8])) => (ZeroExt8to16  (Trunc16to8  <typ.UInt8>  x))
+(Rsh32Ux64 (Lsh32x64 x (Const64 [24])) (Const64 [24])) => (ZeroExt8to32  (Trunc32to8  <typ.UInt8>  x))
+(Rsh64Ux64 (Lsh64x64 x (Const64 [56])) (Const64 [56])) => (ZeroExt8to64  (Trunc64to8  <typ.UInt8>  x))
+(Rsh32Ux64 (Lsh32x64 x (Const64 [16])) (Const64 [16])) => (ZeroExt16to32 (Trunc32to16 <typ.UInt16> x))
+(Rsh64Ux64 (Lsh64x64 x (Const64 [48])) (Const64 [48])) => (ZeroExt16to64 (Trunc64to16 <typ.UInt16> x))
+(Rsh64Ux64 (Lsh64x64 x (Const64 [32])) (Const64 [32])) => (ZeroExt32to64 (Trunc64to32 <typ.UInt32> x))
+
+// replace shifts with sign extensions
+(Rsh16x64 (Lsh16x64 x (Const64  [8])) (Const64  [8])) => (SignExt8to16  (Trunc16to8  <typ.Int8>  x))
+(Rsh32x64 (Lsh32x64 x (Const64 [24])) (Const64 [24])) => (SignExt8to32  (Trunc32to8  <typ.Int8>  x))
+(Rsh64x64 (Lsh64x64 x (Const64 [56])) (Const64 [56])) => (SignExt8to64  (Trunc64to8  <typ.Int8>  x))
+(Rsh32x64 (Lsh32x64 x (Const64 [16])) (Const64 [16])) => (SignExt16to32 (Trunc32to16 <typ.Int16> x))
+(Rsh64x64 (Lsh64x64 x (Const64 [48])) (Const64 [48])) => (SignExt16to64 (Trunc64to16 <typ.Int16> x))
+(Rsh64x64 (Lsh64x64 x (Const64 [32])) (Const64 [32])) => (SignExt32to64 (Trunc64to32 <typ.Int32> x))
+
+// constant comparisons
+(Eq(64|32|16|8)   (Const(64|32|16|8) [c]) (Const(64|32|16|8) [d])) => (ConstBool [c == d])
+(Neq(64|32|16|8)  (Const(64|32|16|8) [c]) (Const(64|32|16|8) [d])) => (ConstBool [c != d])
+(Less(64|32|16|8) (Const(64|32|16|8) [c]) (Const(64|32|16|8) [d])) => (ConstBool [c < d])
+(Leq(64|32|16|8)  (Const(64|32|16|8) [c]) (Const(64|32|16|8) [d])) => (ConstBool [c <= d])
+
+(Less64U (Const64 [c]) (Const64 [d])) => (ConstBool [uint64(c) < uint64(d)])
+(Less32U (Const32 [c]) (Const32 [d])) => (ConstBool [uint32(c) < uint32(d)])
+(Less16U (Const16 [c]) (Const16 [d])) => (ConstBool [uint16(c) < uint16(d)])
+(Less8U  (Const8  [c]) (Const8  [d])) => (ConstBool [ uint8(c) <  uint8(d)])
+
+(Leq64U (Const64 [c]) (Const64 [d])) => (ConstBool [uint64(c) <= uint64(d)])
+(Leq32U (Const32 [c]) (Const32 [d])) => (ConstBool [uint32(c) <= uint32(d)])
+(Leq16U (Const16 [c]) (Const16 [d])) => (ConstBool [uint16(c) <= uint16(d)])
+(Leq8U  (Const8  [c]) (Const8  [d])) => (ConstBool [ uint8(c) <=  uint8(d)])
+
+(Leq8  (Const8  [0]) (And8  _ (Const8  [c]))) && c >= 0 => (ConstBool [true])
+(Leq16 (Const16 [0]) (And16 _ (Const16 [c]))) && c >= 0 => (ConstBool [true])
+(Leq32 (Const32 [0]) (And32 _ (Const32 [c]))) && c >= 0 => (ConstBool [true])
+(Leq64 (Const64 [0]) (And64 _ (Const64 [c]))) && c >= 0 => (ConstBool [true])
+
+(Leq8  (Const8  [0]) (Rsh8Ux64  _ (Const64 [c]))) && c > 0 => (ConstBool [true])
+(Leq16 (Const16 [0]) (Rsh16Ux64 _ (Const64 [c]))) && c > 0 => (ConstBool [true])
+(Leq32 (Const32 [0]) (Rsh32Ux64 _ (Const64 [c]))) && c > 0 => (ConstBool [true])
+(Leq64 (Const64 [0]) (Rsh64Ux64 _ (Const64 [c]))) && c > 0 => (ConstBool [true])
+
+(Less(64|32|16|8) (Const(64|32|16|8) <t> [0]) x) && isNonNegative(x) => (Neq(64|32|16|8) (Const(64|32|16|8) <t> [0]) x)
+(Less(64|32|16|8) x (Const(64|32|16|8) <t> [1])) && isNonNegative(x) => (Eq(64|32|16|8) (Const(64|32|16|8) <t> [0]) x)
+
+// constant floating point comparisons
+(Eq32F   (Const32F [c]) (Const32F [d])) => (ConstBool [c == d])
+(Eq64F   (Const64F [c]) (Const64F [d])) => (ConstBool [c == d])
+(Neq32F  (Const32F [c]) (Const32F [d])) => (ConstBool [c != d])
+(Neq64F  (Const64F [c]) (Const64F [d])) => (ConstBool [c != d])
+(Less32F (Const32F [c]) (Const32F [d])) => (ConstBool [c < d])
+(Less64F (Const64F [c]) (Const64F [d])) => (ConstBool [c < d])
+(Leq32F  (Const32F [c]) (Const32F [d])) => (ConstBool [c <= d])
+(Leq64F  (Const64F [c]) (Const64F [d])) => (ConstBool [c <= d])
+
+// simplifications
+(Or(64|32|16|8) x x) => x
+(Or(64|32|16|8) (Const(64|32|16|8)  [0]) x) => x
+(Or(64|32|16|8) (Const(64|32|16|8) [-1]) _) => (Const(64|32|16|8) [-1])
+(Or(64|32|16|8) (Com(64|32|16|8)     x)  x) => (Const(64|32|16|8) [-1])
+
+(And(64|32|16|8) x x) => x
+(And(64|32|16|8) (Const(64|32|16|8) [-1]) x) => x
+(And(64|32|16|8) (Const(64|32|16|8)  [0]) _) => (Const(64|32|16|8) [0])
+(And(64|32|16|8) (Com(64|32|16|8)     x)  x) => (Const(64|32|16|8) [0])
+
+(Xor(64|32|16|8) x x) => (Const(64|32|16|8) [0])
+(Xor(64|32|16|8) (Const(64|32|16|8) [0]) x) => x
+(Xor(64|32|16|8) (Com(64|32|16|8)    x)  x) => (Const(64|32|16|8) [-1])
+
+(Add(64|32|16|8) (Const(64|32|16|8) [0]) x) => x
+(Sub(64|32|16|8) x x) => (Const(64|32|16|8) [0])
+(Mul(64|32|16|8) (Const(64|32|16|8) [0]) _) => (Const(64|32|16|8) [0])
+(Select0 (Mul(64|32)uover (Const(64|32) [0]) x)) => (Const(64|32) [0])
+(Select1 (Mul(64|32)uover (Const(64|32) [0]) x)) => (ConstBool [false])
+
+(Com(64|32|16|8) (Com(64|32|16|8)  x)) => x
+(Com(64|32|16|8) (Const(64|32|16|8) [c])) => (Const(64|32|16|8) [^c])
+
+(Neg(64|32|16|8) (Sub(64|32|16|8) x y)) => (Sub(64|32|16|8) y x)
+(Add(64|32|16|8) x (Neg(64|32|16|8) y)) => (Sub(64|32|16|8) x y)
+
+(Xor(64|32|16|8) (Const(64|32|16|8) [-1]) x) => (Com(64|32|16|8) x)
+
+(Sub(64|32|16|8) (Neg(64|32|16|8) x) (Com(64|32|16|8) x)) => (Const(64|32|16|8) [1])
+(Sub(64|32|16|8) (Com(64|32|16|8) x) (Neg(64|32|16|8) x)) => (Const(64|32|16|8) [-1])
+(Add(64|32|16|8) (Com(64|32|16|8) x)                  x)  => (Const(64|32|16|8) [-1])
+
+// ^(x-1) == ^x+1 == -x
+(Add(64|32|16|8) (Const(64|32|16|8) [1]) (Com(64|32|16|8) x)) => (Neg(64|32|16|8) x)
+(Com(64|32|16|8) (Add(64|32|16|8) (Const(64|32|16|8) [-1]) x)) => (Neg(64|32|16|8) x)
+
+// -(-x) == x
+(Neg(64|32|16|8) (Neg(64|32|16|8) x)) => x
+
+// -^x == x+1
+(Neg(64|32|16|8) <t> (Com(64|32|16|8) x)) => (Add(64|32|16|8) (Const(64|32|16|8) <t> [1]) x)
+
+(And(64|32|16|8) x (And(64|32|16|8) x y)) => (And(64|32|16|8) x y)
+(Or(64|32|16|8) x (Or(64|32|16|8) x y)) => (Or(64|32|16|8) x y)
+(Xor(64|32|16|8) x (Xor(64|32|16|8) x y)) => y
+
+// Unsigned comparisons to zero.
+(Less(64U|32U|16U|8U) _ (Const(64|32|16|8) [0])) => (ConstBool [false])
+(Leq(64U|32U|16U|8U) (Const(64|32|16|8) [0]) _)  => (ConstBool [true])
+
+// Ands clear bits. Ors set bits.
+// If a subsequent Or will set all the bits
+// that an And cleared, we can skip the And.
+// This happens in bitmasking code like:
+//   x &^= 3 << shift // clear two old bits
+//   x  |= v << shift // set two new bits
+// when shift is a small constant and v ends up a constant 3.
+(Or8  (And8  x (Const8  [c2])) (Const8  <t> [c1])) && ^(c1 | c2) == 0 => (Or8  (Const8  <t> [c1]) x)
+(Or16 (And16 x (Const16 [c2])) (Const16 <t> [c1])) && ^(c1 | c2) == 0 => (Or16 (Const16 <t> [c1]) x)
+(Or32 (And32 x (Const32 [c2])) (Const32 <t> [c1])) && ^(c1 | c2) == 0 => (Or32 (Const32 <t> [c1]) x)
+(Or64 (And64 x (Const64 [c2])) (Const64 <t> [c1])) && ^(c1 | c2) == 0 => (Or64 (Const64 <t> [c1]) x)
+
+(Trunc64to8  (And64 (Const64 [y]) x)) && y&0xFF == 0xFF => (Trunc64to8 x)
+(Trunc64to16 (And64 (Const64 [y]) x)) && y&0xFFFF == 0xFFFF => (Trunc64to16 x)
+(Trunc64to32 (And64 (Const64 [y]) x)) && y&0xFFFFFFFF == 0xFFFFFFFF => (Trunc64to32 x)
+(Trunc32to8  (And32 (Const32 [y]) x)) && y&0xFF == 0xFF => (Trunc32to8 x)
+(Trunc32to16 (And32 (Const32 [y]) x)) && y&0xFFFF == 0xFFFF => (Trunc32to16 x)
+(Trunc16to8  (And16 (Const16 [y]) x)) && y&0xFF == 0xFF => (Trunc16to8 x)
+
+(ZeroExt8to64  (Trunc64to8  x:(Rsh64Ux64 _ (Const64 [s])))) && s >= 56 => x
+(ZeroExt16to64 (Trunc64to16 x:(Rsh64Ux64 _ (Const64 [s])))) && s >= 48 => x
+(ZeroExt32to64 (Trunc64to32 x:(Rsh64Ux64 _ (Const64 [s])))) && s >= 32 => x
+(ZeroExt8to32  (Trunc32to8  x:(Rsh32Ux64 _ (Const64 [s])))) && s >= 24 => x
+(ZeroExt16to32 (Trunc32to16 x:(Rsh32Ux64 _ (Const64 [s])))) && s >= 16 => x
+(ZeroExt8to16  (Trunc16to8  x:(Rsh16Ux64 _ (Const64 [s])))) && s >= 8 => x
+
+(SignExt8to64  (Trunc64to8  x:(Rsh64x64 _ (Const64 [s])))) && s >= 56 => x
+(SignExt16to64 (Trunc64to16 x:(Rsh64x64 _ (Const64 [s])))) && s >= 48 => x
+(SignExt32to64 (Trunc64to32 x:(Rsh64x64 _ (Const64 [s])))) && s >= 32 => x
+(SignExt8to32  (Trunc32to8  x:(Rsh32x64 _ (Const64 [s])))) && s >= 24 => x
+(SignExt16to32 (Trunc32to16 x:(Rsh32x64 _ (Const64 [s])))) && s >= 16 => x
+(SignExt8to16  (Trunc16to8  x:(Rsh16x64 _ (Const64 [s])))) && s >= 8 => x
+
+(Slicemask (Const32 [x])) && x > 0 => (Const32 [-1])
+(Slicemask (Const32 [0]))          => (Const32 [0])
+(Slicemask (Const64 [x])) && x > 0 => (Const64 [-1])
+(Slicemask (Const64 [0]))          => (Const64 [0])
+
+// simplifications often used for lengths.  e.g. len(s[i:i+5])==5
+(Sub(64|32|16|8) (Add(64|32|16|8) x y) x) => y
+(Sub(64|32|16|8) (Add(64|32|16|8) x y) y) => x
+(Sub(64|32|16|8) (Sub(64|32|16|8) x y) x) => (Neg(64|32|16|8) y)
+(Sub(64|32|16|8) x (Add(64|32|16|8) x y)) => (Neg(64|32|16|8) y)
+(Add(64|32|16|8) x (Sub(64|32|16|8) y x)) => y
+(Add(64|32|16|8) x (Add(64|32|16|8) y (Sub(64|32|16|8) z x))) => (Add(64|32|16|8) y z)
+
+// basic phi simplifications
+(Phi (Const8  [c]) (Const8  [c])) => (Const8  [c])
+(Phi (Const16 [c]) (Const16 [c])) => (Const16 [c])
+(Phi (Const32 [c]) (Const32 [c])) => (Const32 [c])
+(Phi (Const64 [c]) (Const64 [c])) => (Const64 [c])
+
+// slice and interface comparisons
+// The frontend ensures that we can only compare against nil,
+// so we need only compare the first word (interface type or slice ptr).
+(EqInter x y)  => (EqPtr  (ITab x) (ITab y))
+(NeqInter x y) => (NeqPtr (ITab x) (ITab y))
+(EqSlice x y)  => (EqPtr  (SlicePtr x) (SlicePtr y))
+(NeqSlice x y) => (NeqPtr (SlicePtr x) (SlicePtr y))
+
+// Load of store of same address, with compatibly typed value and same size
+(Load <t1> p1 (Store {t2} p2 x _))
+	&& isSamePtr(p1, p2)
+	&& t1.Compare(x.Type) == types.CMPeq
+	&& t1.Size() == t2.Size()
+	=> x
+(Load <t1> p1 (Store {t2} p2 _ (Store {t3} p3 x _)))
+	&& isSamePtr(p1, p3)
+	&& t1.Compare(x.Type) == types.CMPeq
+	&& t1.Size() == t2.Size()
+	&& disjoint(p3, t3.Size(), p2, t2.Size())
+	=> x
+(Load <t1> p1 (Store {t2} p2 _ (Store {t3} p3 _ (Store {t4} p4 x _))))
+	&& isSamePtr(p1, p4)
+	&& t1.Compare(x.Type) == types.CMPeq
+	&& t1.Size() == t2.Size()
+	&& disjoint(p4, t4.Size(), p2, t2.Size())
+	&& disjoint(p4, t4.Size(), p3, t3.Size())
+	=> x
+(Load <t1> p1 (Store {t2} p2 _ (Store {t3} p3 _ (Store {t4} p4 _ (Store {t5} p5 x _)))))
+	&& isSamePtr(p1, p5)
+	&& t1.Compare(x.Type) == types.CMPeq
+	&& t1.Size() == t2.Size()
+	&& disjoint(p5, t5.Size(), p2, t2.Size())
+	&& disjoint(p5, t5.Size(), p3, t3.Size())
+	&& disjoint(p5, t5.Size(), p4, t4.Size())
+	=> x
+
+// Pass constants through math.Float{32,64}bits and math.Float{32,64}frombits
+        (Load <t1> p1 (Store {t2} p2 (Const64  [x]) _)) && isSamePtr(p1,p2) && sizeof(t2) == 8 && is64BitFloat(t1) && !math.IsNaN(math.Float64frombits(uint64(x))) => (Const64F [math.Float64frombits(uint64(x))])
+        (Load <t1> p1 (Store {t2} p2 (Const32  [x]) _)) && isSamePtr(p1,p2) && sizeof(t2) == 4 && is32BitFloat(t1) && !math.IsNaN(float64(math.Float32frombits(uint32(x)))) => (Const32F [math.Float32frombits(uint32(x))])
+(Load <t1> p1 (Store {t2} p2 (Const64F [x]) _)) && isSamePtr(p1,p2) && sizeof(t2) == 8 && is64BitInt(t1)   => (Const64  [int64(math.Float64bits(x))])
+(Load <t1> p1 (Store {t2} p2 (Const32F [x]) _)) && isSamePtr(p1,p2) && sizeof(t2) == 4 && is32BitInt(t1)   => (Const32  [int32(math.Float32bits(x))])
+
+// Float Loads up to Zeros so they can be constant folded.
+(Load <t1> op:(OffPtr [o1] p1)
+	(Store {t2} p2 _
+		mem:(Zero [n] p3 _)))
+	&& o1 >= 0 && o1+t1.Size() <= n && isSamePtr(p1, p3)
+	&& fe.CanSSA(t1)
+	&& disjoint(op, t1.Size(), p2, t2.Size())
+	=> @mem.Block (Load <t1> (OffPtr <op.Type> [o1] p3) mem)
+(Load <t1> op:(OffPtr [o1] p1)
+	(Store {t2} p2 _
+		(Store {t3} p3 _
+			mem:(Zero [n] p4 _))))
+	&& o1 >= 0 && o1+t1.Size() <= n && isSamePtr(p1, p4)
+	&& fe.CanSSA(t1)
+	&& disjoint(op, t1.Size(), p2, t2.Size())
+	&& disjoint(op, t1.Size(), p3, t3.Size())
+	=> @mem.Block (Load <t1> (OffPtr <op.Type> [o1] p4) mem)
+(Load <t1> op:(OffPtr [o1] p1)
+	(Store {t2} p2 _
+		(Store {t3} p3 _
+			(Store {t4} p4 _
+				mem:(Zero [n] p5 _)))))
+	&& o1 >= 0 && o1+t1.Size() <= n && isSamePtr(p1, p5)
+	&& fe.CanSSA(t1)
+	&& disjoint(op, t1.Size(), p2, t2.Size())
+	&& disjoint(op, t1.Size(), p3, t3.Size())
+	&& disjoint(op, t1.Size(), p4, t4.Size())
+	=> @mem.Block (Load <t1> (OffPtr <op.Type> [o1] p5) mem)
+(Load <t1> op:(OffPtr [o1] p1)
+	(Store {t2} p2 _
+		(Store {t3} p3 _
+			(Store {t4} p4 _
+				(Store {t5} p5 _
+					mem:(Zero [n] p6 _))))))
+	&& o1 >= 0 && o1+t1.Size() <= n && isSamePtr(p1, p6)
+	&& fe.CanSSA(t1)
+	&& disjoint(op, t1.Size(), p2, t2.Size())
+	&& disjoint(op, t1.Size(), p3, t3.Size())
+	&& disjoint(op, t1.Size(), p4, t4.Size())
+	&& disjoint(op, t1.Size(), p5, t5.Size())
+	=> @mem.Block (Load <t1> (OffPtr <op.Type> [o1] p6) mem)
+
+// Zero to Load forwarding.
+(Load <t1> (OffPtr [o] p1) (Zero [n] p2 _))
+	&& t1.IsBoolean()
+	&& isSamePtr(p1, p2)
+	&& n >= o + 1
+	=> (ConstBool [false])
+(Load <t1> (OffPtr [o] p1) (Zero [n] p2 _))
+	&& is8BitInt(t1)
+	&& isSamePtr(p1, p2)
+	&& n >= o + 1
+	=> (Const8 [0])
+(Load <t1> (OffPtr [o] p1) (Zero [n] p2 _))
+	&& is16BitInt(t1)
+	&& isSamePtr(p1, p2)
+	&& n >= o + 2
+	=> (Const16 [0])
+(Load <t1> (OffPtr [o] p1) (Zero [n] p2 _))
+	&& is32BitInt(t1)
+	&& isSamePtr(p1, p2)
+	&& n >= o + 4
+	=> (Const32 [0])
+(Load <t1> (OffPtr [o] p1) (Zero [n] p2 _))
+	&& is64BitInt(t1)
+	&& isSamePtr(p1, p2)
+	&& n >= o + 8
+	=> (Const64 [0])
+(Load <t1> (OffPtr [o] p1) (Zero [n] p2 _))
+	&& is32BitFloat(t1)
+	&& isSamePtr(p1, p2)
+	&& n >= o + 4
+	=> (Const32F [0])
+(Load <t1> (OffPtr [o] p1) (Zero [n] p2 _))
+	&& is64BitFloat(t1)
+	&& isSamePtr(p1, p2)
+	&& n >= o + 8
+	=> (Const64F [0])
+
+// Eliminate stores of values that have just been loaded from the same location.
+// We also handle the common case where there are some intermediate stores.
+(Store {t1} p1 (Load <t2> p2 mem) mem)
+	&& isSamePtr(p1, p2)
+	&& t2.Size() == t1.Size()
+	=> mem
+(Store {t1} p1 (Load <t2> p2 oldmem) mem:(Store {t3} p3 _ oldmem))
+	&& isSamePtr(p1, p2)
+	&& t2.Size() == t1.Size()
+	&& disjoint(p1, t1.Size(), p3, t3.Size())
+	=> mem
+(Store {t1} p1 (Load <t2> p2 oldmem) mem:(Store {t3} p3 _ (Store {t4} p4 _ oldmem)))
+	&& isSamePtr(p1, p2)
+	&& t2.Size() == t1.Size()
+	&& disjoint(p1, t1.Size(), p3, t3.Size())
+	&& disjoint(p1, t1.Size(), p4, t4.Size())
+	=> mem
+(Store {t1} p1 (Load <t2> p2 oldmem) mem:(Store {t3} p3 _ (Store {t4} p4 _ (Store {t5} p5 _ oldmem))))
+	&& isSamePtr(p1, p2)
+	&& t2.Size() == t1.Size()
+	&& disjoint(p1, t1.Size(), p3, t3.Size())
+	&& disjoint(p1, t1.Size(), p4, t4.Size())
+	&& disjoint(p1, t1.Size(), p5, t5.Size())
+	=> mem
+
+// Don't Store zeros to cleared variables.
+(Store {t} (OffPtr [o] p1) x mem:(Zero [n] p2 _))
+	&& isConstZero(x)
+	&& o >= 0 && t.Size() + o <= n && isSamePtr(p1, p2)
+	=> mem
+(Store {t1} op:(OffPtr [o1] p1) x mem:(Store {t2} p2 _ (Zero [n] p3 _)))
+	&& isConstZero(x)
+	&& o1 >= 0 && t1.Size() + o1 <= n && isSamePtr(p1, p3)
+	&& disjoint(op, t1.Size(), p2, t2.Size())
+	=> mem
+(Store {t1} op:(OffPtr [o1] p1) x mem:(Store {t2} p2 _ (Store {t3} p3 _ (Zero [n] p4 _))))
+	&& isConstZero(x)
+	&& o1 >= 0 && t1.Size() + o1 <= n && isSamePtr(p1, p4)
+	&& disjoint(op, t1.Size(), p2, t2.Size())
+	&& disjoint(op, t1.Size(), p3, t3.Size())
+	=> mem
+(Store {t1} op:(OffPtr [o1] p1) x mem:(Store {t2} p2 _ (Store {t3} p3 _ (Store {t4} p4 _ (Zero [n] p5 _)))))
+	&& isConstZero(x)
+	&& o1 >= 0 && t1.Size() + o1 <= n && isSamePtr(p1, p5)
+	&& disjoint(op, t1.Size(), p2, t2.Size())
+	&& disjoint(op, t1.Size(), p3, t3.Size())
+	&& disjoint(op, t1.Size(), p4, t4.Size())
+	=> mem
+
+// Collapse OffPtr
+(OffPtr (OffPtr p [y]) [x]) => (OffPtr p [x+y])
+(OffPtr p [0]) && v.Type.Compare(p.Type) == types.CMPeq => p
+
+// indexing operations
+// Note: bounds check has already been done
+(PtrIndex <t> ptr idx) && config.PtrSize == 4 && is32Bit(t.Elem().Size()) => (AddPtr ptr (Mul32 <typ.Int> idx (Const32 <typ.Int> [int32(t.Elem().Size())])))
+(PtrIndex <t> ptr idx) && config.PtrSize == 8 => (AddPtr ptr (Mul64 <typ.Int> idx (Const64 <typ.Int> [t.Elem().Size()])))
+
+// struct operations
+(StructSelect (StructMake1 x)) => x
+(StructSelect [0] (StructMake2 x _)) => x
+(StructSelect [1] (StructMake2 _ x)) => x
+(StructSelect [0] (StructMake3 x _ _)) => x
+(StructSelect [1] (StructMake3 _ x _)) => x
+(StructSelect [2] (StructMake3 _ _ x)) => x
+(StructSelect [0] (StructMake4 x _ _ _)) => x
+(StructSelect [1] (StructMake4 _ x _ _)) => x
+(StructSelect [2] (StructMake4 _ _ x _)) => x
+(StructSelect [3] (StructMake4 _ _ _ x)) => x
+
+(Load <t> _ _) && t.IsStruct() && t.NumFields() == 0 && fe.CanSSA(t) =>
+  (StructMake0)
+(Load <t> ptr mem) && t.IsStruct() && t.NumFields() == 1 && fe.CanSSA(t) =>
+  (StructMake1
+    (Load <t.FieldType(0)> (OffPtr <t.FieldType(0).PtrTo()> [0] ptr) mem))
+(Load <t> ptr mem) && t.IsStruct() && t.NumFields() == 2 && fe.CanSSA(t) =>
+  (StructMake2
+    (Load <t.FieldType(0)> (OffPtr <t.FieldType(0).PtrTo()> [0]             ptr) mem)
+    (Load <t.FieldType(1)> (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] ptr) mem))
+(Load <t> ptr mem) && t.IsStruct() && t.NumFields() == 3 && fe.CanSSA(t) =>
+  (StructMake3
+    (Load <t.FieldType(0)> (OffPtr <t.FieldType(0).PtrTo()> [0]             ptr) mem)
+    (Load <t.FieldType(1)> (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] ptr) mem)
+    (Load <t.FieldType(2)> (OffPtr <t.FieldType(2).PtrTo()> [t.FieldOff(2)] ptr) mem))
+(Load <t> ptr mem) && t.IsStruct() && t.NumFields() == 4 && fe.CanSSA(t) =>
+  (StructMake4
+    (Load <t.FieldType(0)> (OffPtr <t.FieldType(0).PtrTo()> [0]             ptr) mem)
+    (Load <t.FieldType(1)> (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] ptr) mem)
+    (Load <t.FieldType(2)> (OffPtr <t.FieldType(2).PtrTo()> [t.FieldOff(2)] ptr) mem)
+    (Load <t.FieldType(3)> (OffPtr <t.FieldType(3).PtrTo()> [t.FieldOff(3)] ptr) mem))
+
+(StructSelect [i] x:(Load <t> ptr mem)) && !fe.CanSSA(t) =>
+  @x.Block (Load <v.Type> (OffPtr <v.Type.PtrTo()> [t.FieldOff(int(i))] ptr) mem)
+
+(Store _ (StructMake0) mem) => mem
+(Store dst (StructMake1 <t> f0) mem) =>
+  (Store {t.FieldType(0)} (OffPtr <t.FieldType(0).PtrTo()> [0] dst) f0 mem)
+(Store dst (StructMake2 <t> f0 f1) mem) =>
+  (Store {t.FieldType(1)}
+    (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst)
+    f1
+    (Store {t.FieldType(0)}
+      (OffPtr <t.FieldType(0).PtrTo()> [0] dst)
+        f0 mem))
+(Store dst (StructMake3 <t> f0 f1 f2) mem) =>
+  (Store {t.FieldType(2)}
+    (OffPtr <t.FieldType(2).PtrTo()> [t.FieldOff(2)] dst)
+    f2
+    (Store {t.FieldType(1)}
+      (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst)
+      f1
+      (Store {t.FieldType(0)}
+        (OffPtr <t.FieldType(0).PtrTo()> [0] dst)
+          f0 mem)))
+(Store dst (StructMake4 <t> f0 f1 f2 f3) mem) =>
+  (Store {t.FieldType(3)}
+    (OffPtr <t.FieldType(3).PtrTo()> [t.FieldOff(3)] dst)
+    f3
+    (Store {t.FieldType(2)}
+      (OffPtr <t.FieldType(2).PtrTo()> [t.FieldOff(2)] dst)
+      f2
+      (Store {t.FieldType(1)}
+        (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst)
+        f1
+        (Store {t.FieldType(0)}
+          (OffPtr <t.FieldType(0).PtrTo()> [0] dst)
+            f0 mem))))
+
+// Putting struct{*byte} and similar into direct interfaces.
+(IMake _typ (StructMake1 val)) => (IMake _typ val)
+(StructSelect [0] (IData x)) => (IData x)
+
+// un-SSAable values use mem->mem copies
+(Store {t} dst (Load src mem) mem) && !fe.CanSSA(t) =>
+	(Move {t} [t.Size()] dst src mem)
+(Store {t} dst (Load src mem) (VarDef {x} mem)) && !fe.CanSSA(t) =>
+	(Move {t} [t.Size()] dst src (VarDef {x} mem))
+
+// array ops
+(ArraySelect (ArrayMake1 x)) => x
+
+(Load <t> _ _) && t.IsArray() && t.NumElem() == 0 =>
+  (ArrayMake0)
+
+(Load <t> ptr mem) && t.IsArray() && t.NumElem() == 1 && fe.CanSSA(t) =>
+  (ArrayMake1 (Load <t.Elem()> ptr mem))
+
+(Store _ (ArrayMake0) mem) => mem
+(Store dst (ArrayMake1 e) mem) => (Store {e.Type} dst e mem)
+
+// Putting [1]*byte and similar into direct interfaces.
+(IMake _typ (ArrayMake1 val)) => (IMake _typ val)
+(ArraySelect [0] (IData x)) => (IData x)
+
+// string ops
+// Decomposing StringMake and lowering of StringPtr and StringLen
+// happens in a later pass, dec, so that these operations are available
+// to other passes for optimizations.
+(StringPtr (StringMake (Addr <t> {s} base) _)) => (Addr <t> {s} base)
+(StringLen (StringMake _ (Const64 <t> [c]))) => (Const64 <t> [c])
+(ConstString {str}) && config.PtrSize == 4 && str == "" =>
+  (StringMake (ConstNil) (Const32 <typ.Int> [0]))
+(ConstString {str}) && config.PtrSize == 8 && str == "" =>
+  (StringMake (ConstNil) (Const64 <typ.Int> [0]))
+(ConstString {str}) && config.PtrSize == 4 && str != "" =>
+  (StringMake
+    (Addr <typ.BytePtr> {fe.StringData(str)}
+      (SB))
+    (Const32 <typ.Int> [int32(len(str))]))
+(ConstString {str}) && config.PtrSize == 8 && str != "" =>
+  (StringMake
+    (Addr <typ.BytePtr> {fe.StringData(str)}
+      (SB))
+    (Const64 <typ.Int> [int64(len(str))]))
+
+// slice ops
+// Only a few slice rules are provided here.  See dec.rules for
+// a more comprehensive set.
+(SliceLen (SliceMake _ (Const64 <t> [c]) _)) => (Const64 <t> [c])
+(SliceCap (SliceMake _ _ (Const64 <t> [c]))) => (Const64 <t> [c])
+(SliceLen (SliceMake _ (Const32 <t> [c]) _)) => (Const32 <t> [c])
+(SliceCap (SliceMake _ _ (Const32 <t> [c]))) => (Const32 <t> [c])
+(SlicePtr (SliceMake (SlicePtr x) _ _)) => (SlicePtr x)
+(SliceLen (SliceMake _ (SliceLen x) _)) => (SliceLen x)
+(SliceCap (SliceMake _ _ (SliceCap x))) => (SliceCap x)
+(SliceCap (SliceMake _ _ (SliceLen x))) => (SliceLen x)
+(ConstSlice) && config.PtrSize == 4 =>
+  (SliceMake
+    (ConstNil <v.Type.Elem().PtrTo()>)
+    (Const32 <typ.Int> [0])
+    (Const32 <typ.Int> [0]))
+(ConstSlice) && config.PtrSize == 8 =>
+  (SliceMake
+    (ConstNil <v.Type.Elem().PtrTo()>)
+    (Const64 <typ.Int> [0])
+    (Const64 <typ.Int> [0]))
+
+// interface ops
+(ConstInterface) =>
+  (IMake
+    (ConstNil <typ.Uintptr>)
+    (ConstNil <typ.BytePtr>))
+
+(NilCheck (GetG mem) mem) => mem
+
+(If (Not cond) yes no) => (If cond no yes)
+(If (ConstBool [c]) yes no) && c => (First yes no)
+(If (ConstBool [c]) yes no) && !c => (First no yes)
+
+(Phi <t> nx:(Not x) ny:(Not y)) && nx.Uses == 1 && ny.Uses == 1 => (Not (Phi <t> x y))
+
+// Get rid of Convert ops for pointer arithmetic on unsafe.Pointer.
+(Convert (Add(64|32) (Convert ptr mem) off) mem) => (AddPtr ptr off)
+(Convert (Convert ptr mem) mem) => ptr
+
+// strength reduction of divide by a constant.
+// See ../magic.go for a detailed description of these algorithms.
+
+// Unsigned divide by power of 2.  Strength reduce to a shift.
+(Div8u  n (Const8  [c])) && isPowerOfTwo8(c)  => (Rsh8Ux64  n (Const64 <typ.UInt64> [log8(c)]))
+(Div16u n (Const16 [c])) && isPowerOfTwo16(c) => (Rsh16Ux64 n (Const64 <typ.UInt64> [log16(c)]))
+(Div32u n (Const32 [c])) && isPowerOfTwo32(c) => (Rsh32Ux64 n (Const64 <typ.UInt64> [log32(c)]))
+(Div64u n (Const64 [c])) && isPowerOfTwo64(c) => (Rsh64Ux64 n (Const64 <typ.UInt64> [log64(c)]))
+(Div64u n (Const64 [-1<<63]))                 => (Rsh64Ux64 n (Const64 <typ.UInt64> [63]))
+
+// Signed non-negative divide by power of 2.
+(Div8  n (Const8  [c])) && isNonNegative(n) && isPowerOfTwo8(c)  => (Rsh8Ux64  n (Const64 <typ.UInt64> [log8(c)]))
+(Div16 n (Const16 [c])) && isNonNegative(n) && isPowerOfTwo16(c) => (Rsh16Ux64 n (Const64 <typ.UInt64> [log16(c)]))
+(Div32 n (Const32 [c])) && isNonNegative(n) && isPowerOfTwo32(c) => (Rsh32Ux64 n (Const64 <typ.UInt64> [log32(c)]))
+(Div64 n (Const64 [c])) && isNonNegative(n) && isPowerOfTwo64(c) => (Rsh64Ux64 n (Const64 <typ.UInt64> [log64(c)]))
+(Div64 n (Const64 [-1<<63])) && isNonNegative(n)                 => (Const64 [0])
+
+// Unsigned divide, not a power of 2.  Strength reduce to a multiply.
+// For 8-bit divides, we just do a direct 9-bit by 8-bit multiply.
+(Div8u x (Const8 [c])) && umagicOK8(c) =>
+  (Trunc32to8
+    (Rsh32Ux64 <typ.UInt32>
+      (Mul32 <typ.UInt32>
+        (Const32 <typ.UInt32> [int32(1<<8+umagic8(c).m)])
+        (ZeroExt8to32 x))
+      (Const64 <typ.UInt64> [8+umagic8(c).s])))
+
+// For 16-bit divides on 64-bit machines, we do a direct 17-bit by 16-bit multiply.
+(Div16u x (Const16 [c])) && umagicOK16(c) && config.RegSize == 8 =>
+  (Trunc64to16
+    (Rsh64Ux64 <typ.UInt64>
+      (Mul64 <typ.UInt64>
+        (Const64 <typ.UInt64> [int64(1<<16+umagic16(c).m)])
+        (ZeroExt16to64 x))
+      (Const64 <typ.UInt64> [16+umagic16(c).s])))
+
+// For 16-bit divides on 32-bit machines
+(Div16u x (Const16 [c])) && umagicOK16(c) && config.RegSize == 4 && umagic16(c).m&1 == 0 =>
+  (Trunc32to16
+    (Rsh32Ux64 <typ.UInt32>
+      (Mul32 <typ.UInt32>
+        (Const32 <typ.UInt32> [int32(1<<15+umagic16(c).m/2)])
+        (ZeroExt16to32 x))
+      (Const64 <typ.UInt64> [16+umagic16(c).s-1])))
+(Div16u x (Const16 [c])) && umagicOK16(c) && config.RegSize == 4 && c&1 == 0 =>
+  (Trunc32to16
+    (Rsh32Ux64 <typ.UInt32>
+      (Mul32 <typ.UInt32>
+        (Const32 <typ.UInt32> [int32(1<<15+(umagic16(c).m+1)/2)])
+        (Rsh32Ux64 <typ.UInt32> (ZeroExt16to32 x) (Const64 <typ.UInt64> [1])))
+      (Const64 <typ.UInt64> [16+umagic16(c).s-2])))
+(Div16u x (Const16 [c])) && umagicOK16(c) && config.RegSize == 4 && config.useAvg =>
+  (Trunc32to16
+    (Rsh32Ux64 <typ.UInt32>
+      (Avg32u
+        (Lsh32x64 <typ.UInt32> (ZeroExt16to32 x) (Const64 <typ.UInt64> [16]))
+        (Mul32 <typ.UInt32>
+          (Const32 <typ.UInt32> [int32(umagic16(c).m)])
+          (ZeroExt16to32 x)))
+      (Const64 <typ.UInt64> [16+umagic16(c).s-1])))
+
+// For 32-bit divides on 32-bit machines
+(Div32u x (Const32 [c])) && umagicOK32(c) && config.RegSize == 4 && umagic32(c).m&1 == 0 && config.useHmul =>
+  (Rsh32Ux64 <typ.UInt32>
+    (Hmul32u <typ.UInt32>
+      (Const32 <typ.UInt32> [int32(1<<31+umagic32(c).m/2)])
+      x)
+    (Const64 <typ.UInt64> [umagic32(c).s-1]))
+(Div32u x (Const32 [c])) && umagicOK32(c) && config.RegSize == 4 && c&1 == 0 && config.useHmul =>
+  (Rsh32Ux64 <typ.UInt32>
+    (Hmul32u <typ.UInt32>
+      (Const32 <typ.UInt32> [int32(1<<31+(umagic32(c).m+1)/2)])
+      (Rsh32Ux64 <typ.UInt32> x (Const64 <typ.UInt64> [1])))
+    (Const64 <typ.UInt64> [umagic32(c).s-2]))
+(Div32u x (Const32 [c])) && umagicOK32(c) && config.RegSize == 4 && config.useAvg && config.useHmul =>
+  (Rsh32Ux64 <typ.UInt32>
+    (Avg32u
+      x
+      (Hmul32u <typ.UInt32>
+        (Const32 <typ.UInt32> [int32(umagic32(c).m)])
+        x))
+    (Const64 <typ.UInt64> [umagic32(c).s-1]))
+
+// For 32-bit divides on 64-bit machines
+// We'll use a regular (non-hi) multiply for this case.
+(Div32u x (Const32 [c])) && umagicOK32(c) && config.RegSize == 8 && umagic32(c).m&1 == 0 =>
+  (Trunc64to32
+    (Rsh64Ux64 <typ.UInt64>
+      (Mul64 <typ.UInt64>
+        (Const64 <typ.UInt64> [int64(1<<31+umagic32(c).m/2)])
+        (ZeroExt32to64 x))
+      (Const64 <typ.UInt64> [32+umagic32(c).s-1])))
+(Div32u x (Const32 [c])) && umagicOK32(c) && config.RegSize == 8 && c&1 == 0 =>
+  (Trunc64to32
+    (Rsh64Ux64 <typ.UInt64>
+      (Mul64 <typ.UInt64>
+        (Const64 <typ.UInt64> [int64(1<<31+(umagic32(c).m+1)/2)])
+        (Rsh64Ux64 <typ.UInt64> (ZeroExt32to64 x) (Const64 <typ.UInt64> [1])))
+      (Const64 <typ.UInt64> [32+umagic32(c).s-2])))
+(Div32u x (Const32 [c])) && umagicOK32(c) && config.RegSize == 8 && config.useAvg =>
+  (Trunc64to32
+    (Rsh64Ux64 <typ.UInt64>
+      (Avg64u
+        (Lsh64x64 <typ.UInt64> (ZeroExt32to64 x) (Const64 <typ.UInt64> [32]))
+        (Mul64 <typ.UInt64>
+          (Const64 <typ.UInt32> [int64(umagic32(c).m)])
+          (ZeroExt32to64 x)))
+      (Const64 <typ.UInt64> [32+umagic32(c).s-1])))
+
+// For unsigned 64-bit divides on 32-bit machines,
+// if the constant fits in 16 bits (so that the last term
+// fits in 32 bits), convert to three 32-bit divides by a constant.
+//
+// If 1<<32 = Q * c + R
+// and    x = hi << 32 + lo
+//
+// Then x = (hi/c*c + hi%c) << 32 + lo
+//        = hi/c*c<<32 + hi%c<<32 + lo
+//        = hi/c*c<<32 + (hi%c)*(Q*c+R) + lo/c*c + lo%c
+//        = hi/c*c<<32 + (hi%c)*Q*c + lo/c*c + (hi%c*R+lo%c)
+// and x / c = (hi/c)<<32 + (hi%c)*Q + lo/c + (hi%c*R+lo%c)/c
+(Div64u x (Const64 [c])) && c > 0 && c <= 0xFFFF && umagicOK32(int32(c)) && config.RegSize == 4 && config.useHmul =>
+  (Add64
+    (Add64 <typ.UInt64>
+      (Add64 <typ.UInt64>
+        (Lsh64x64 <typ.UInt64>
+          (ZeroExt32to64
+            (Div32u <typ.UInt32>
+              (Trunc64to32 <typ.UInt32> (Rsh64Ux64 <typ.UInt64> x (Const64 <typ.UInt64> [32])))
+              (Const32 <typ.UInt32> [int32(c)])))
+          (Const64 <typ.UInt64> [32]))
+        (ZeroExt32to64 (Div32u <typ.UInt32> (Trunc64to32 <typ.UInt32> x) (Const32 <typ.UInt32> [int32(c)]))))
+      (Mul64 <typ.UInt64>
+        (ZeroExt32to64 <typ.UInt64>
+          (Mod32u <typ.UInt32>
+            (Trunc64to32 <typ.UInt32> (Rsh64Ux64 <typ.UInt64> x (Const64 <typ.UInt64> [32])))
+            (Const32 <typ.UInt32> [int32(c)])))
+        (Const64 <typ.UInt64> [int64((1<<32)/c)])))
+      (ZeroExt32to64
+        (Div32u <typ.UInt32>
+          (Add32 <typ.UInt32>
+            (Mod32u <typ.UInt32> (Trunc64to32 <typ.UInt32> x) (Const32 <typ.UInt32> [int32(c)]))
+            (Mul32 <typ.UInt32>
+              (Mod32u <typ.UInt32>
+                (Trunc64to32 <typ.UInt32> (Rsh64Ux64 <typ.UInt64> x (Const64 <typ.UInt64> [32])))
+                (Const32 <typ.UInt32> [int32(c)]))
+              (Const32 <typ.UInt32> [int32((1<<32)%c)])))
+          (Const32 <typ.UInt32> [int32(c)]))))
+
+// For 64-bit divides on 64-bit machines
+// (64-bit divides on 32-bit machines are lowered to a runtime call by the walk pass.)
+(Div64u x (Const64 [c])) && umagicOK64(c) && config.RegSize == 8 && umagic64(c).m&1 == 0 && config.useHmul =>
+  (Rsh64Ux64 <typ.UInt64>
+    (Hmul64u <typ.UInt64>
+      (Const64 <typ.UInt64> [int64(1<<63+umagic64(c).m/2)])
+      x)
+    (Const64 <typ.UInt64> [umagic64(c).s-1]))
+(Div64u x (Const64 [c])) && umagicOK64(c) && config.RegSize == 8 && c&1 == 0 && config.useHmul =>
+  (Rsh64Ux64 <typ.UInt64>
+    (Hmul64u <typ.UInt64>
+      (Const64 <typ.UInt64> [int64(1<<63+(umagic64(c).m+1)/2)])
+      (Rsh64Ux64 <typ.UInt64> x (Const64 <typ.UInt64> [1])))
+    (Const64 <typ.UInt64> [umagic64(c).s-2]))
+(Div64u x (Const64 [c])) && umagicOK64(c) && config.RegSize == 8 && config.useAvg && config.useHmul =>
+  (Rsh64Ux64 <typ.UInt64>
+    (Avg64u
+      x
+      (Hmul64u <typ.UInt64>
+        (Const64 <typ.UInt64> [int64(umagic64(c).m)])
+        x))
+    (Const64 <typ.UInt64> [umagic64(c).s-1]))
+
+// Signed divide by a negative constant.  Rewrite to divide by a positive constant.
+(Div8  <t> n (Const8  [c])) && c < 0 && c != -1<<7  => (Neg8  (Div8  <t> n (Const8  <t> [-c])))
+(Div16 <t> n (Const16 [c])) && c < 0 && c != -1<<15 => (Neg16 (Div16 <t> n (Const16 <t> [-c])))
+(Div32 <t> n (Const32 [c])) && c < 0 && c != -1<<31 => (Neg32 (Div32 <t> n (Const32 <t> [-c])))
+(Div64 <t> n (Const64 [c])) && c < 0 && c != -1<<63 => (Neg64 (Div64 <t> n (Const64 <t> [-c])))
+
+// Dividing by the most-negative number.  Result is always 0 except
+// if the input is also the most-negative number.
+// We can detect that using the sign bit of x & -x.
+(Div8  <t> x (Const8  [-1<<7 ])) => (Rsh8Ux64  (And8  <t> x (Neg8  <t> x)) (Const64 <typ.UInt64> [7 ]))
+(Div16 <t> x (Const16 [-1<<15])) => (Rsh16Ux64 (And16 <t> x (Neg16 <t> x)) (Const64 <typ.UInt64> [15]))
+(Div32 <t> x (Const32 [-1<<31])) => (Rsh32Ux64 (And32 <t> x (Neg32 <t> x)) (Const64 <typ.UInt64> [31]))
+(Div64 <t> x (Const64 [-1<<63])) => (Rsh64Ux64 (And64 <t> x (Neg64 <t> x)) (Const64 <typ.UInt64> [63]))
+
+// Signed divide by power of 2.
+// n / c =       n >> log(c) if n >= 0
+//       = (n+c-1) >> log(c) if n < 0
+// We conditionally add c-1 by adding n>>63>>(64-log(c)) (first shift signed, second shift unsigned).
+(Div8  <t> n (Const8  [c])) && isPowerOfTwo8(c) =>
+  (Rsh8x64
+    (Add8  <t> n (Rsh8Ux64  <t> (Rsh8x64  <t> n (Const64 <typ.UInt64> [ 7])) (Const64 <typ.UInt64> [int64( 8-log8(c))])))
+    (Const64 <typ.UInt64> [int64(log8(c))]))
+(Div16 <t> n (Const16 [c])) && isPowerOfTwo16(c) =>
+  (Rsh16x64
+    (Add16 <t> n (Rsh16Ux64 <t> (Rsh16x64 <t> n (Const64 <typ.UInt64> [15])) (Const64 <typ.UInt64> [int64(16-log16(c))])))
+    (Const64 <typ.UInt64> [int64(log16(c))]))
+(Div32 <t> n (Const32 [c])) && isPowerOfTwo32(c) =>
+  (Rsh32x64
+    (Add32 <t> n (Rsh32Ux64 <t> (Rsh32x64 <t> n (Const64 <typ.UInt64> [31])) (Const64 <typ.UInt64> [int64(32-log32(c))])))
+    (Const64 <typ.UInt64> [int64(log32(c))]))
+(Div64 <t> n (Const64 [c])) && isPowerOfTwo64(c) =>
+  (Rsh64x64
+    (Add64 <t> n (Rsh64Ux64 <t> (Rsh64x64 <t> n (Const64 <typ.UInt64> [63])) (Const64 <typ.UInt64> [int64(64-log64(c))])))
+    (Const64 <typ.UInt64> [int64(log64(c))]))
+
+// Signed divide, not a power of 2.  Strength reduce to a multiply.
+(Div8 <t> x (Const8 [c])) && smagicOK8(c) =>
+  (Sub8 <t>
+    (Rsh32x64 <t>
+      (Mul32 <typ.UInt32>
+        (Const32 <typ.UInt32> [int32(smagic8(c).m)])
+        (SignExt8to32 x))
+      (Const64 <typ.UInt64> [8+smagic8(c).s]))
+    (Rsh32x64 <t>
+      (SignExt8to32 x)
+      (Const64 <typ.UInt64> [31])))
+(Div16 <t> x (Const16 [c])) && smagicOK16(c) =>
+  (Sub16 <t>
+    (Rsh32x64 <t>
+      (Mul32 <typ.UInt32>
+        (Const32 <typ.UInt32> [int32(smagic16(c).m)])
+        (SignExt16to32 x))
+      (Const64 <typ.UInt64> [16+smagic16(c).s]))
+    (Rsh32x64 <t>
+      (SignExt16to32 x)
+      (Const64 <typ.UInt64> [31])))
+(Div32 <t> x (Const32 [c])) && smagicOK32(c) && config.RegSize == 8 =>
+  (Sub32 <t>
+    (Rsh64x64 <t>
+      (Mul64 <typ.UInt64>
+        (Const64 <typ.UInt64> [int64(smagic32(c).m)])
+        (SignExt32to64 x))
+      (Const64 <typ.UInt64> [32+smagic32(c).s]))
+    (Rsh64x64 <t>
+      (SignExt32to64 x)
+      (Const64 <typ.UInt64> [63])))
+(Div32 <t> x (Const32 [c])) && smagicOK32(c) && config.RegSize == 4 && smagic32(c).m&1 == 0 && config.useHmul =>
+  (Sub32 <t>
+    (Rsh32x64 <t>
+      (Hmul32 <t>
+        (Const32 <typ.UInt32> [int32(smagic32(c).m/2)])
+        x)
+      (Const64 <typ.UInt64> [smagic32(c).s-1]))
+    (Rsh32x64 <t>
+      x
+      (Const64 <typ.UInt64> [31])))
+(Div32 <t> x (Const32 [c])) && smagicOK32(c) && config.RegSize == 4 && smagic32(c).m&1 != 0 && config.useHmul =>
+  (Sub32 <t>
+    (Rsh32x64 <t>
+      (Add32 <t>
+        (Hmul32 <t>
+          (Const32 <typ.UInt32> [int32(smagic32(c).m)])
+          x)
+        x)
+      (Const64 <typ.UInt64> [smagic32(c).s]))
+    (Rsh32x64 <t>
+      x
+      (Const64 <typ.UInt64> [31])))
+(Div64 <t> x (Const64 [c])) && smagicOK64(c) && smagic64(c).m&1 == 0 && config.useHmul =>
+  (Sub64 <t>
+    (Rsh64x64 <t>
+      (Hmul64 <t>
+        (Const64 <typ.UInt64> [int64(smagic64(c).m/2)])
+        x)
+      (Const64 <typ.UInt64> [smagic64(c).s-1]))
+    (Rsh64x64 <t>
+      x
+      (Const64 <typ.UInt64> [63])))
+(Div64 <t> x (Const64 [c])) && smagicOK64(c) && smagic64(c).m&1 != 0 && config.useHmul =>
+  (Sub64 <t>
+    (Rsh64x64 <t>
+      (Add64 <t>
+        (Hmul64 <t>
+          (Const64 <typ.UInt64> [int64(smagic64(c).m)])
+          x)
+        x)
+      (Const64 <typ.UInt64> [smagic64(c).s]))
+    (Rsh64x64 <t>
+      x
+      (Const64 <typ.UInt64> [63])))
+
+// Unsigned mod by power of 2 constant.
+(Mod8u  <t> n (Const8  [c])) && isPowerOfTwo8(c)  => (And8  n (Const8  <t> [c-1]))
+(Mod16u <t> n (Const16 [c])) && isPowerOfTwo16(c) => (And16 n (Const16 <t> [c-1]))
+(Mod32u <t> n (Const32 [c])) && isPowerOfTwo32(c) => (And32 n (Const32 <t> [c-1]))
+(Mod64u <t> n (Const64 [c])) && isPowerOfTwo64(c) => (And64 n (Const64 <t> [c-1]))
+(Mod64u <t> n (Const64 [-1<<63]))                 => (And64 n (Const64 <t> [1<<63-1]))
+
+// Signed non-negative mod by power of 2 constant.
+(Mod8  <t> n (Const8  [c])) && isNonNegative(n) && isPowerOfTwo8(c)  => (And8  n (Const8  <t> [c-1]))
+(Mod16 <t> n (Const16 [c])) && isNonNegative(n) && isPowerOfTwo16(c) => (And16 n (Const16 <t> [c-1]))
+(Mod32 <t> n (Const32 [c])) && isNonNegative(n) && isPowerOfTwo32(c) => (And32 n (Const32 <t> [c-1]))
+(Mod64 <t> n (Const64 [c])) && isNonNegative(n) && isPowerOfTwo64(c) => (And64 n (Const64 <t> [c-1]))
+(Mod64 n (Const64 [-1<<63])) && isNonNegative(n)                   => n
+
+// Signed mod by negative constant.
+(Mod8  <t> n (Const8  [c])) && c < 0 && c != -1<<7  => (Mod8  <t> n (Const8  <t> [-c]))
+(Mod16 <t> n (Const16 [c])) && c < 0 && c != -1<<15 => (Mod16 <t> n (Const16 <t> [-c]))
+(Mod32 <t> n (Const32 [c])) && c < 0 && c != -1<<31 => (Mod32 <t> n (Const32 <t> [-c]))
+(Mod64 <t> n (Const64 [c])) && c < 0 && c != -1<<63 => (Mod64 <t> n (Const64 <t> [-c]))
+
+// All other mods by constants, do A%B = A-(A/B*B).
+// This implements % with two * and a bunch of ancillary ops.
+// One of the * is free if the user's code also computes A/B.
+(Mod8   <t> x (Const8  [c])) && x.Op != OpConst8  && (c > 0 || c == -1<<7)
+  => (Sub8  x (Mul8  <t> (Div8   <t> x (Const8  <t> [c])) (Const8  <t> [c])))
+(Mod16  <t> x (Const16 [c])) && x.Op != OpConst16 && (c > 0 || c == -1<<15)
+  => (Sub16 x (Mul16 <t> (Div16  <t> x (Const16 <t> [c])) (Const16 <t> [c])))
+(Mod32  <t> x (Const32 [c])) && x.Op != OpConst32 && (c > 0 || c == -1<<31)
+  => (Sub32 x (Mul32 <t> (Div32  <t> x (Const32 <t> [c])) (Const32 <t> [c])))
+(Mod64  <t> x (Const64 [c])) && x.Op != OpConst64 && (c > 0 || c == -1<<63)
+  => (Sub64 x (Mul64 <t> (Div64  <t> x (Const64 <t> [c])) (Const64 <t> [c])))
+(Mod8u  <t> x (Const8  [c])) && x.Op != OpConst8  && c > 0 && umagicOK8( c)
+  => (Sub8  x (Mul8  <t> (Div8u  <t> x (Const8  <t> [c])) (Const8  <t> [c])))
+(Mod16u <t> x (Const16 [c])) && x.Op != OpConst16 && c > 0 && umagicOK16(c)
+  => (Sub16 x (Mul16 <t> (Div16u <t> x (Const16 <t> [c])) (Const16 <t> [c])))
+(Mod32u <t> x (Const32 [c])) && x.Op != OpConst32 && c > 0 && umagicOK32(c)
+  => (Sub32 x (Mul32 <t> (Div32u <t> x (Const32 <t> [c])) (Const32 <t> [c])))
+(Mod64u <t> x (Const64 [c])) && x.Op != OpConst64 && c > 0 && umagicOK64(c)
+  => (Sub64 x (Mul64 <t> (Div64u <t> x (Const64 <t> [c])) (Const64 <t> [c])))
+
+// For architectures without rotates on less than 32-bits, promote these checks to 32-bit.
+(Eq8 (Mod8u x (Const8  [c])) (Const8 [0])) && x.Op != OpConst8 && udivisibleOK8(c) && !hasSmallRotate(config) =>
+	(Eq32 (Mod32u <typ.UInt32> (ZeroExt8to32 <typ.UInt32> x) (Const32 <typ.UInt32> [int32(uint8(c))])) (Const32 <typ.UInt32> [0]))
+(Eq16 (Mod16u x (Const16  [c])) (Const16 [0])) && x.Op != OpConst16 && udivisibleOK16(c) && !hasSmallRotate(config) =>
+	(Eq32 (Mod32u <typ.UInt32> (ZeroExt16to32 <typ.UInt32> x) (Const32 <typ.UInt32> [int32(uint16(c))])) (Const32 <typ.UInt32> [0]))
+(Eq8 (Mod8 x (Const8  [c])) (Const8 [0])) && x.Op != OpConst8 && sdivisibleOK8(c) && !hasSmallRotate(config) =>
+	(Eq32 (Mod32 <typ.Int32> (SignExt8to32 <typ.Int32> x) (Const32 <typ.Int32> [int32(c)])) (Const32 <typ.Int32> [0]))
+(Eq16 (Mod16 x (Const16  [c])) (Const16 [0])) && x.Op != OpConst16 && sdivisibleOK16(c) && !hasSmallRotate(config) =>
+	(Eq32 (Mod32 <typ.Int32> (SignExt16to32 <typ.Int32> x) (Const32 <typ.Int32> [int32(c)])) (Const32 <typ.Int32> [0]))
+
+// Divisibility checks x%c == 0 convert to multiply and rotate.
+// Note, x%c == 0 is rewritten as x == c*(x/c) during the opt pass
+// where (x/c) is performed using multiplication with magic constants.
+// To rewrite x%c == 0 requires pattern matching the rewritten expression
+// and checking that the division by the same constant wasn't already calculated.
+// This check is made by counting uses of the magic constant multiplication.
+// Note that if there were an intermediate opt pass, this rule could be applied
+// directly on the Div op and magic division rewrites could be delayed to late opt.
+
+// Unsigned divisibility checks convert to multiply and rotate.
+(Eq8 x (Mul8 (Const8 [c])
+  (Trunc32to8
+    (Rsh32Ux64
+      mul:(Mul32
+        (Const32 [m])
+        (ZeroExt8to32 x))
+      (Const64 [s])))
+	)
+)
+  && v.Block.Func.pass.name != "opt" && mul.Uses == 1
+  && m == int32(1<<8+umagic8(c).m) && s == 8+umagic8(c).s
+  && x.Op != OpConst8 && udivisibleOK8(c)
+ => (Leq8U
+			(RotateLeft8 <typ.UInt8>
+				(Mul8 <typ.UInt8>
+					(Const8 <typ.UInt8> [int8(udivisible8(c).m)])
+					x)
+				(Const8 <typ.UInt8> [int8(8-udivisible8(c).k)])
+				)
+			(Const8 <typ.UInt8> [int8(udivisible8(c).max)])
+		)
+
+(Eq16 x (Mul16 (Const16 [c])
+  (Trunc64to16
+    (Rsh64Ux64
+      mul:(Mul64
+        (Const64 [m])
+        (ZeroExt16to64 x))
+      (Const64 [s])))
+	)
+)
+  && v.Block.Func.pass.name != "opt" && mul.Uses == 1
+  && m == int64(1<<16+umagic16(c).m) && s == 16+umagic16(c).s
+  && x.Op != OpConst16 && udivisibleOK16(c)
+ => (Leq16U
+			(RotateLeft16 <typ.UInt16>
+				(Mul16 <typ.UInt16>
+					(Const16 <typ.UInt16> [int16(udivisible16(c).m)])
+					x)
+				(Const16 <typ.UInt16> [int16(16-udivisible16(c).k)])
+				)
+			(Const16 <typ.UInt16> [int16(udivisible16(c).max)])
+		)
+
+(Eq16 x (Mul16 (Const16 [c])
+  (Trunc32to16
+    (Rsh32Ux64
+      mul:(Mul32
+        (Const32 [m])
+        (ZeroExt16to32 x))
+      (Const64 [s])))
+	)
+)
+  && v.Block.Func.pass.name != "opt" && mul.Uses == 1
+  && m == int32(1<<15+umagic16(c).m/2) && s == 16+umagic16(c).s-1
+  && x.Op != OpConst16 && udivisibleOK16(c)
+ => (Leq16U
+			(RotateLeft16 <typ.UInt16>
+				(Mul16 <typ.UInt16>
+					(Const16 <typ.UInt16> [int16(udivisible16(c).m)])
+					x)
+				(Const16 <typ.UInt16> [int16(16-udivisible16(c).k)])
+				)
+			(Const16 <typ.UInt16> [int16(udivisible16(c).max)])
+		)
+
+(Eq16 x (Mul16 (Const16 [c])
+  (Trunc32to16
+    (Rsh32Ux64
+      mul:(Mul32
+        (Const32 [m])
+        (Rsh32Ux64 (ZeroExt16to32 x) (Const64 [1])))
+      (Const64 [s])))
+	)
+)
+  && v.Block.Func.pass.name != "opt" && mul.Uses == 1
+  && m == int32(1<<15+(umagic16(c).m+1)/2) && s == 16+umagic16(c).s-2
+  && x.Op != OpConst16 && udivisibleOK16(c)
+ => (Leq16U
+			(RotateLeft16 <typ.UInt16>
+				(Mul16 <typ.UInt16>
+					(Const16 <typ.UInt16> [int16(udivisible16(c).m)])
+					x)
+				(Const16 <typ.UInt16> [int16(16-udivisible16(c).k)])
+				)
+			(Const16 <typ.UInt16> [int16(udivisible16(c).max)])
+		)
+
+(Eq16 x (Mul16 (Const16 [c])
+  (Trunc32to16
+    (Rsh32Ux64
+      (Avg32u
+        (Lsh32x64 (ZeroExt16to32 x) (Const64 [16]))
+        mul:(Mul32
+          (Const32 [m])
+          (ZeroExt16to32 x)))
+      (Const64 [s])))
+	)
+)
+  && v.Block.Func.pass.name != "opt" && mul.Uses == 1
+  && m == int32(umagic16(c).m) && s == 16+umagic16(c).s-1
+  && x.Op != OpConst16 && udivisibleOK16(c)
+ => (Leq16U
+			(RotateLeft16 <typ.UInt16>
+				(Mul16 <typ.UInt16>
+					(Const16 <typ.UInt16> [int16(udivisible16(c).m)])
+					x)
+				(Const16 <typ.UInt16> [int16(16-udivisible16(c).k)])
+				)
+			(Const16 <typ.UInt16> [int16(udivisible16(c).max)])
+		)
+
+(Eq32 x (Mul32 (Const32 [c])
+	(Rsh32Ux64
+		mul:(Hmul32u
+			(Const32 [m])
+			x)
+		(Const64 [s]))
+	)
+)
+  && v.Block.Func.pass.name != "opt" && mul.Uses == 1
+  && m == int32(1<<31+umagic32(c).m/2) && s == umagic32(c).s-1
+	&& x.Op != OpConst32 && udivisibleOK32(c)
+ => (Leq32U
+			(RotateLeft32 <typ.UInt32>
+				(Mul32 <typ.UInt32>
+					(Const32 <typ.UInt32> [int32(udivisible32(c).m)])
+					x)
+				(Const32 <typ.UInt32> [int32(32-udivisible32(c).k)])
+				)
+			(Const32 <typ.UInt32> [int32(udivisible32(c).max)])
+		)
+
+(Eq32 x (Mul32 (Const32 [c])
+  (Rsh32Ux64
+    mul:(Hmul32u
+      (Const32 <typ.UInt32> [m])
+      (Rsh32Ux64 x (Const64 [1])))
+    (Const64 [s]))
+	)
+)
+  && v.Block.Func.pass.name != "opt" && mul.Uses == 1
+  && m == int32(1<<31+(umagic32(c).m+1)/2) && s == umagic32(c).s-2
+	&& x.Op != OpConst32 && udivisibleOK32(c)
+ => (Leq32U
+			(RotateLeft32 <typ.UInt32>
+				(Mul32 <typ.UInt32>
+					(Const32 <typ.UInt32> [int32(udivisible32(c).m)])
+					x)
+				(Const32 <typ.UInt32> [int32(32-udivisible32(c).k)])
+				)
+			(Const32 <typ.UInt32> [int32(udivisible32(c).max)])
+		)
+
+(Eq32 x (Mul32 (Const32 [c])
+  (Rsh32Ux64
+    (Avg32u
+      x
+      mul:(Hmul32u
+        (Const32 [m])
+        x))
+    (Const64 [s]))
+	)
+)
+  && v.Block.Func.pass.name != "opt" && mul.Uses == 1
+  && m == int32(umagic32(c).m) && s == umagic32(c).s-1
+	&& x.Op != OpConst32 && udivisibleOK32(c)
+ => (Leq32U
+			(RotateLeft32 <typ.UInt32>
+				(Mul32 <typ.UInt32>
+					(Const32 <typ.UInt32> [int32(udivisible32(c).m)])
+					x)
+				(Const32 <typ.UInt32> [int32(32-udivisible32(c).k)])
+				)
+			(Const32 <typ.UInt32> [int32(udivisible32(c).max)])
+		)
+
+(Eq32 x (Mul32 (Const32 [c])
+  (Trunc64to32
+    (Rsh64Ux64
+      mul:(Mul64
+        (Const64 [m])
+        (ZeroExt32to64 x))
+      (Const64 [s])))
+	)
+)
+  && v.Block.Func.pass.name != "opt" && mul.Uses == 1
+  && m == int64(1<<31+umagic32(c).m/2) && s == 32+umagic32(c).s-1
+	&& x.Op != OpConst32 && udivisibleOK32(c)
+ => (Leq32U
+			(RotateLeft32 <typ.UInt32>
+				(Mul32 <typ.UInt32>
+					(Const32 <typ.UInt32> [int32(udivisible32(c).m)])
+					x)
+				(Const32 <typ.UInt32> [int32(32-udivisible32(c).k)])
+				)
+			(Const32 <typ.UInt32> [int32(udivisible32(c).max)])
+		)
+
+(Eq32 x (Mul32 (Const32 [c])
+  (Trunc64to32
+    (Rsh64Ux64
+      mul:(Mul64
+        (Const64 [m])
+        (Rsh64Ux64 (ZeroExt32to64 x) (Const64 [1])))
+      (Const64 [s])))
+	)
+)
+  && v.Block.Func.pass.name != "opt" && mul.Uses == 1
+  && m == int64(1<<31+(umagic32(c).m+1)/2) && s == 32+umagic32(c).s-2
+	&& x.Op != OpConst32 && udivisibleOK32(c)
+ => (Leq32U
+			(RotateLeft32 <typ.UInt32>
+				(Mul32 <typ.UInt32>
+					(Const32 <typ.UInt32> [int32(udivisible32(c).m)])
+					x)
+				(Const32 <typ.UInt32> [int32(32-udivisible32(c).k)])
+				)
+			(Const32 <typ.UInt32> [int32(udivisible32(c).max)])
+		)
+
+(Eq32 x (Mul32 (Const32 [c])
+  (Trunc64to32
+    (Rsh64Ux64
+      (Avg64u
+        (Lsh64x64 (ZeroExt32to64 x) (Const64 [32]))
+        mul:(Mul64
+          (Const64 [m])
+          (ZeroExt32to64 x)))
+      (Const64 [s])))
+	)
+)
+  && v.Block.Func.pass.name != "opt" && mul.Uses == 1
+  && m == int64(umagic32(c).m) && s == 32+umagic32(c).s-1
+	&& x.Op != OpConst32 && udivisibleOK32(c)
+ => (Leq32U
+			(RotateLeft32 <typ.UInt32>
+				(Mul32 <typ.UInt32>
+					(Const32 <typ.UInt32> [int32(udivisible32(c).m)])
+					x)
+				(Const32 <typ.UInt32> [int32(32-udivisible32(c).k)])
+				)
+			(Const32 <typ.UInt32> [int32(udivisible32(c).max)])
+		)
+
+(Eq64 x (Mul64 (Const64 [c])
+	(Rsh64Ux64
+		mul:(Hmul64u
+			(Const64 [m])
+			x)
+		(Const64 [s]))
+	)
+) && v.Block.Func.pass.name != "opt" && mul.Uses == 1
+  && m == int64(1<<63+umagic64(c).m/2) && s == umagic64(c).s-1
+  && x.Op != OpConst64 && udivisibleOK64(c)
+ => (Leq64U
+			(RotateLeft64 <typ.UInt64>
+				(Mul64 <typ.UInt64>
+					(Const64 <typ.UInt64> [int64(udivisible64(c).m)])
+					x)
+				(Const64 <typ.UInt64> [64-udivisible64(c).k])
+				)
+			(Const64 <typ.UInt64> [int64(udivisible64(c).max)])
+		)
+(Eq64 x (Mul64 (Const64 [c])
+	(Rsh64Ux64
+		mul:(Hmul64u
+			(Const64 [m])
+			(Rsh64Ux64 x (Const64 [1])))
+		(Const64 [s]))
+	)
+) && v.Block.Func.pass.name != "opt" && mul.Uses == 1
+  && m == int64(1<<63+(umagic64(c).m+1)/2) && s == umagic64(c).s-2
+  && x.Op != OpConst64 && udivisibleOK64(c)
+ => (Leq64U
+			(RotateLeft64 <typ.UInt64>
+				(Mul64 <typ.UInt64>
+					(Const64 <typ.UInt64> [int64(udivisible64(c).m)])
+					x)
+				(Const64 <typ.UInt64> [64-udivisible64(c).k])
+				)
+			(Const64 <typ.UInt64> [int64(udivisible64(c).max)])
+		)
+(Eq64 x (Mul64 (Const64 [c])
+	(Rsh64Ux64
+		(Avg64u
+			x
+			mul:(Hmul64u
+				(Const64 [m])
+				x))
+		(Const64 [s]))
+	)
+) && v.Block.Func.pass.name != "opt" && mul.Uses == 1
+  && m == int64(umagic64(c).m) && s == umagic64(c).s-1
+  && x.Op != OpConst64 && udivisibleOK64(c)
+ => (Leq64U
+			(RotateLeft64 <typ.UInt64>
+				(Mul64 <typ.UInt64>
+					(Const64 <typ.UInt64> [int64(udivisible64(c).m)])
+					x)
+				(Const64 <typ.UInt64> [64-udivisible64(c).k])
+				)
+			(Const64 <typ.UInt64> [int64(udivisible64(c).max)])
+		)
+
+// Signed divisibility checks convert to multiply, add and rotate.
+(Eq8 x (Mul8 (Const8 [c])
+  (Sub8
+    (Rsh32x64
+      mul:(Mul32
+        (Const32 [m])
+        (SignExt8to32 x))
+      (Const64 [s]))
+    (Rsh32x64
+      (SignExt8to32 x)
+      (Const64 [31])))
+	)
+)
+  && v.Block.Func.pass.name != "opt" && mul.Uses == 1
+  && m == int32(smagic8(c).m) && s == 8+smagic8(c).s
+	&& x.Op != OpConst8 && sdivisibleOK8(c)
+ => (Leq8U
+			(RotateLeft8 <typ.UInt8>
+				(Add8 <typ.UInt8>
+					(Mul8 <typ.UInt8>
+						(Const8 <typ.UInt8> [int8(sdivisible8(c).m)])
+						x)
+					(Const8 <typ.UInt8> [int8(sdivisible8(c).a)])
+				)
+				(Const8 <typ.UInt8> [int8(8-sdivisible8(c).k)])
+			)
+			(Const8 <typ.UInt8> [int8(sdivisible8(c).max)])
+		)
+
+(Eq16 x (Mul16 (Const16 [c])
+  (Sub16
+    (Rsh32x64
+      mul:(Mul32
+        (Const32 [m])
+        (SignExt16to32 x))
+      (Const64 [s]))
+    (Rsh32x64
+      (SignExt16to32 x)
+      (Const64 [31])))
+	)
+)
+  && v.Block.Func.pass.name != "opt" && mul.Uses == 1
+  && m == int32(smagic16(c).m) && s == 16+smagic16(c).s
+	&& x.Op != OpConst16 && sdivisibleOK16(c)
+ => (Leq16U
+			(RotateLeft16 <typ.UInt16>
+				(Add16 <typ.UInt16>
+					(Mul16 <typ.UInt16>
+						(Const16 <typ.UInt16> [int16(sdivisible16(c).m)])
+						x)
+					(Const16 <typ.UInt16> [int16(sdivisible16(c).a)])
+				)
+				(Const16 <typ.UInt16> [int16(16-sdivisible16(c).k)])
+			)
+			(Const16 <typ.UInt16> [int16(sdivisible16(c).max)])
+		)
+
+(Eq32 x (Mul32 (Const32 [c])
+  (Sub32
+    (Rsh64x64
+      mul:(Mul64
+        (Const64 [m])
+        (SignExt32to64 x))
+      (Const64 [s]))
+    (Rsh64x64
+      (SignExt32to64 x)
+      (Const64 [63])))
+	)
+)
+  && v.Block.Func.pass.name != "opt" && mul.Uses == 1
+  && m == int64(smagic32(c).m) && s == 32+smagic32(c).s
+	&& x.Op != OpConst32 && sdivisibleOK32(c)
+ => (Leq32U
+			(RotateLeft32 <typ.UInt32>
+				(Add32 <typ.UInt32>
+					(Mul32 <typ.UInt32>
+						(Const32 <typ.UInt32> [int32(sdivisible32(c).m)])
+						x)
+					(Const32 <typ.UInt32> [int32(sdivisible32(c).a)])
+				)
+				(Const32 <typ.UInt32> [int32(32-sdivisible32(c).k)])
+			)
+			(Const32 <typ.UInt32> [int32(sdivisible32(c).max)])
+		)
+
+(Eq32 x (Mul32 (Const32 [c])
+  (Sub32
+    (Rsh32x64
+      mul:(Hmul32
+        (Const32 [m])
+        x)
+      (Const64 [s]))
+    (Rsh32x64
+      x
+      (Const64 [31])))
+	)
+)
+  && v.Block.Func.pass.name != "opt" && mul.Uses == 1
+  && m == int32(smagic32(c).m/2) && s == smagic32(c).s-1
+	&& x.Op != OpConst32 && sdivisibleOK32(c)
+ => (Leq32U
+			(RotateLeft32 <typ.UInt32>
+				(Add32 <typ.UInt32>
+					(Mul32 <typ.UInt32>
+						(Const32 <typ.UInt32> [int32(sdivisible32(c).m)])
+						x)
+					(Const32 <typ.UInt32> [int32(sdivisible32(c).a)])
+				)
+				(Const32 <typ.UInt32> [int32(32-sdivisible32(c).k)])
+			)
+			(Const32 <typ.UInt32> [int32(sdivisible32(c).max)])
+		)
+
+(Eq32 x (Mul32 (Const32 [c])
+  (Sub32
+    (Rsh32x64
+      (Add32
+        mul:(Hmul32
+          (Const32 [m])
+          x)
+        x)
+      (Const64 [s]))
+    (Rsh32x64
+      x
+      (Const64 [31])))
+	)
+)
+  && v.Block.Func.pass.name != "opt" && mul.Uses == 1
+  && m == int32(smagic32(c).m) && s == smagic32(c).s
+	&& x.Op != OpConst32 && sdivisibleOK32(c)
+ => (Leq32U
+			(RotateLeft32 <typ.UInt32>
+				(Add32 <typ.UInt32>
+					(Mul32 <typ.UInt32>
+						(Const32 <typ.UInt32> [int32(sdivisible32(c).m)])
+						x)
+					(Const32 <typ.UInt32> [int32(sdivisible32(c).a)])
+				)
+				(Const32 <typ.UInt32> [int32(32-sdivisible32(c).k)])
+			)
+			(Const32 <typ.UInt32> [int32(sdivisible32(c).max)])
+		)
+
+(Eq64 x (Mul64 (Const64 [c])
+  (Sub64
+    (Rsh64x64
+      mul:(Hmul64
+        (Const64 [m])
+        x)
+      (Const64 [s]))
+    (Rsh64x64
+      x
+      (Const64 [63])))
+	)
+)
+  && v.Block.Func.pass.name != "opt" && mul.Uses == 1
+  && m == int64(smagic64(c).m/2) && s == smagic64(c).s-1
+	&& x.Op != OpConst64 && sdivisibleOK64(c)
+ => (Leq64U
+			(RotateLeft64 <typ.UInt64>
+				(Add64 <typ.UInt64>
+					(Mul64 <typ.UInt64>
+						(Const64 <typ.UInt64> [int64(sdivisible64(c).m)])
+						x)
+					(Const64 <typ.UInt64> [int64(sdivisible64(c).a)])
+				)
+				(Const64 <typ.UInt64> [64-sdivisible64(c).k])
+			)
+			(Const64 <typ.UInt64> [int64(sdivisible64(c).max)])
+		)
+
+(Eq64 x (Mul64 (Const64 [c])
+  (Sub64
+    (Rsh64x64
+      (Add64
+        mul:(Hmul64
+          (Const64 [m])
+          x)
+        x)
+      (Const64 [s]))
+    (Rsh64x64
+      x
+      (Const64 [63])))
+	)
+)
+  && v.Block.Func.pass.name != "opt" && mul.Uses == 1
+  && m == int64(smagic64(c).m) && s == smagic64(c).s
+	&& x.Op != OpConst64 && sdivisibleOK64(c)
+ => (Leq64U
+			(RotateLeft64 <typ.UInt64>
+				(Add64 <typ.UInt64>
+					(Mul64 <typ.UInt64>
+						(Const64 <typ.UInt64> [int64(sdivisible64(c).m)])
+						x)
+					(Const64 <typ.UInt64> [int64(sdivisible64(c).a)])
+				)
+				(Const64 <typ.UInt64> [64-sdivisible64(c).k])
+			)
+			(Const64 <typ.UInt64> [int64(sdivisible64(c).max)])
+		)
+
+// Divisibility check for signed integers for power of two constant are simple mask.
+// However, we must match against the rewritten n%c == 0 -> n - c*(n/c) == 0 -> n == c*(n/c)
+// where n/c contains fixup code to handle signed n.
+((Eq8|Neq8) n (Lsh8x64
+  (Rsh8x64
+    (Add8  <t> n (Rsh8Ux64  <t> (Rsh8x64  <t> n (Const64 <typ.UInt64> [ 7])) (Const64 <typ.UInt64> [kbar])))
+    (Const64 <typ.UInt64> [k]))
+	(Const64 <typ.UInt64> [k]))
+) && k > 0 && k < 7 && kbar == 8 - k
+  => ((Eq8|Neq8) (And8 <t> n (Const8 <t> [1<<uint(k)-1])) (Const8 <t> [0]))
+
+((Eq16|Neq16) n (Lsh16x64
+  (Rsh16x64
+    (Add16 <t> n (Rsh16Ux64 <t> (Rsh16x64 <t> n (Const64 <typ.UInt64> [15])) (Const64 <typ.UInt64> [kbar])))
+    (Const64 <typ.UInt64> [k]))
+	(Const64 <typ.UInt64> [k]))
+) && k > 0 && k < 15 && kbar == 16 - k
+  => ((Eq16|Neq16) (And16 <t> n (Const16 <t> [1<<uint(k)-1])) (Const16 <t> [0]))
+
+((Eq32|Neq32) n (Lsh32x64
+  (Rsh32x64
+    (Add32 <t> n (Rsh32Ux64 <t> (Rsh32x64 <t> n (Const64 <typ.UInt64> [31])) (Const64 <typ.UInt64> [kbar])))
+    (Const64 <typ.UInt64> [k]))
+	(Const64 <typ.UInt64> [k]))
+) && k > 0 && k < 31 && kbar == 32 - k
+  => ((Eq32|Neq32) (And32 <t> n (Const32 <t> [1<<uint(k)-1])) (Const32 <t> [0]))
+
+((Eq64|Neq64) n (Lsh64x64
+  (Rsh64x64
+    (Add64 <t> n (Rsh64Ux64 <t> (Rsh64x64 <t> n (Const64 <typ.UInt64> [63])) (Const64 <typ.UInt64> [kbar])))
+    (Const64 <typ.UInt64> [k]))
+	(Const64 <typ.UInt64> [k]))
+) && k > 0 && k < 63 && kbar == 64 - k
+  => ((Eq64|Neq64) (And64 <t> n (Const64 <t> [1<<uint(k)-1])) (Const64 <t> [0]))
+
+(Eq(8|16|32|64)  s:(Sub(8|16|32|64) x y) (Const(8|16|32|64) [0])) && s.Uses == 1 => (Eq(8|16|32|64)  x y)
+(Neq(8|16|32|64) s:(Sub(8|16|32|64) x y) (Const(8|16|32|64) [0])) && s.Uses == 1 => (Neq(8|16|32|64) x y)
+
+// Optimize bitsets
+(Eq8 (And8 <t> x (Const8 <t> [y])) (Const8 <t> [y])) && oneBit8(y)
+  => (Neq8 (And8 <t> x (Const8 <t> [y])) (Const8 <t> [0]))
+(Eq16 (And16 <t> x (Const16 <t> [y])) (Const16 <t> [y])) && oneBit16(y)
+  => (Neq16 (And16 <t> x (Const16 <t> [y])) (Const16 <t> [0]))
+(Eq32 (And32 <t> x (Const32 <t> [y])) (Const32 <t> [y])) && oneBit32(y)
+  => (Neq32 (And32 <t> x (Const32 <t> [y])) (Const32 <t> [0]))
+(Eq64 (And64 <t> x (Const64 <t> [y])) (Const64 <t> [y])) && oneBit64(y)
+  => (Neq64 (And64 <t> x (Const64 <t> [y])) (Const64 <t> [0]))
+(Neq8 (And8 <t> x (Const8 <t> [y])) (Const8 <t> [y])) && oneBit8(y)
+  => (Eq8 (And8 <t> x (Const8 <t> [y])) (Const8 <t> [0]))
+(Neq16 (And16 <t> x (Const16 <t> [y])) (Const16 <t> [y])) && oneBit16(y)
+  => (Eq16 (And16 <t> x (Const16 <t> [y])) (Const16 <t> [0]))
+(Neq32 (And32 <t> x (Const32 <t> [y])) (Const32 <t> [y])) && oneBit32(y)
+  => (Eq32 (And32 <t> x (Const32 <t> [y])) (Const32 <t> [0]))
+(Neq64 (And64 <t> x (Const64 <t> [y])) (Const64 <t> [y])) && oneBit64(y)
+  => (Eq64 (And64 <t> x (Const64 <t> [y])) (Const64 <t> [0]))
+
+// Reassociate expressions involving
+// constants such that constants come first,
+// exposing obvious constant-folding opportunities.
+// Reassociate (op (op y C) x) to (op C (op x y)) or similar, where C
+// is constant, which pushes constants to the outside
+// of the expression. At that point, any constant-folding
+// opportunities should be obvious.
+// Note: don't include AddPtr here! In order to maintain the
+// invariant that pointers must stay within the pointed-to object,
+// we can't pull part of a pointer computation above the AddPtr.
+// See issue 37881.
+// Note: we don't need to handle any (x-C) cases because we already rewrite
+// (x-C) to (x+(-C)).
+
+// x + (C + z) -> C + (x + z)
+(Add64 (Add64 i:(Const64 <t>) z) x) && (z.Op != OpConst64 && x.Op != OpConst64) => (Add64 i (Add64 <t> z x))
+(Add32 (Add32 i:(Const32 <t>) z) x) && (z.Op != OpConst32 && x.Op != OpConst32) => (Add32 i (Add32 <t> z x))
+(Add16 (Add16 i:(Const16 <t>) z) x) && (z.Op != OpConst16 && x.Op != OpConst16) => (Add16 i (Add16 <t> z x))
+(Add8  (Add8  i:(Const8  <t>) z) x) && (z.Op != OpConst8  && x.Op != OpConst8)  => (Add8  i (Add8  <t> z x))
+
+// x + (C - z) -> C + (x - z)
+(Add64 (Sub64 i:(Const64 <t>) z) x) && (z.Op != OpConst64 && x.Op != OpConst64) => (Add64 i (Sub64 <t> x z))
+(Add32 (Sub32 i:(Const32 <t>) z) x) && (z.Op != OpConst32 && x.Op != OpConst32) => (Add32 i (Sub32 <t> x z))
+(Add16 (Sub16 i:(Const16 <t>) z) x) && (z.Op != OpConst16 && x.Op != OpConst16) => (Add16 i (Sub16 <t> x z))
+(Add8  (Sub8  i:(Const8  <t>) z) x) && (z.Op != OpConst8  && x.Op != OpConst8)  => (Add8  i (Sub8  <t> x z))
+
+// x - (C - z) -> x + (z - C) -> (x + z) - C
+(Sub64 x (Sub64 i:(Const64 <t>) z)) && (z.Op != OpConst64 && x.Op != OpConst64) => (Sub64 (Add64 <t> x z) i)
+(Sub32 x (Sub32 i:(Const32 <t>) z)) && (z.Op != OpConst32 && x.Op != OpConst32) => (Sub32 (Add32 <t> x z) i)
+(Sub16 x (Sub16 i:(Const16 <t>) z)) && (z.Op != OpConst16 && x.Op != OpConst16) => (Sub16 (Add16 <t> x z) i)
+(Sub8  x (Sub8  i:(Const8  <t>) z)) && (z.Op != OpConst8  && x.Op != OpConst8)  => (Sub8  (Add8  <t> x z) i)
+
+// x - (z + C) -> x + (-z - C) -> (x - z) - C
+(Sub64 x (Add64 z i:(Const64 <t>))) && (z.Op != OpConst64 && x.Op != OpConst64) => (Sub64 (Sub64 <t> x z) i)
+(Sub32 x (Add32 z i:(Const32 <t>))) && (z.Op != OpConst32 && x.Op != OpConst32) => (Sub32 (Sub32 <t> x z) i)
+(Sub16 x (Add16 z i:(Const16 <t>))) && (z.Op != OpConst16 && x.Op != OpConst16) => (Sub16 (Sub16 <t> x z) i)
+(Sub8  x (Add8  z i:(Const8  <t>))) && (z.Op != OpConst8  && x.Op != OpConst8)  => (Sub8 (Sub8  <t> x z) i)
+
+// (C - z) - x -> C - (z + x)
+(Sub64 (Sub64 i:(Const64 <t>) z) x) && (z.Op != OpConst64 && x.Op != OpConst64) => (Sub64 i (Add64 <t> z x))
+(Sub32 (Sub32 i:(Const32 <t>) z) x) && (z.Op != OpConst32 && x.Op != OpConst32) => (Sub32 i (Add32 <t> z x))
+(Sub16 (Sub16 i:(Const16 <t>) z) x) && (z.Op != OpConst16 && x.Op != OpConst16) => (Sub16 i (Add16 <t> z x))
+(Sub8  (Sub8  i:(Const8  <t>) z) x) && (z.Op != OpConst8  && x.Op != OpConst8)  => (Sub8  i (Add8  <t> z x))
+
+// (z + C) -x -> C + (z - x)
+(Sub64 (Add64 z i:(Const64 <t>)) x) && (z.Op != OpConst64 && x.Op != OpConst64) => (Add64 i (Sub64 <t> z x))
+(Sub32 (Add32 z i:(Const32 <t>)) x) && (z.Op != OpConst32 && x.Op != OpConst32) => (Add32 i (Sub32 <t> z x))
+(Sub16 (Add16 z i:(Const16 <t>)) x) && (z.Op != OpConst16 && x.Op != OpConst16) => (Add16 i (Sub16 <t> z x))
+(Sub8  (Add8  z i:(Const8  <t>)) x) && (z.Op != OpConst8  && x.Op != OpConst8)  => (Add8  i (Sub8  <t> z x))
+
+// x & (C & z) -> C & (x & z)
+(And64 (And64 i:(Const64 <t>) z) x) && (z.Op != OpConst64 && x.Op != OpConst64) => (And64 i (And64 <t> z x))
+(And32 (And32 i:(Const32 <t>) z) x) && (z.Op != OpConst32 && x.Op != OpConst32) => (And32 i (And32 <t> z x))
+(And16 (And16 i:(Const16 <t>) z) x) && (z.Op != OpConst16 && x.Op != OpConst16) => (And16 i (And16 <t> z x))
+(And8  (And8  i:(Const8  <t>) z) x) && (z.Op != OpConst8  && x.Op != OpConst8)  => (And8  i (And8  <t> z x))
+
+// x | (C | z) -> C | (x | z)
+(Or64 (Or64 i:(Const64 <t>) z) x) && (z.Op != OpConst64 && x.Op != OpConst64) => (Or64 i (Or64 <t> z x))
+(Or32 (Or32 i:(Const32 <t>) z) x) && (z.Op != OpConst32 && x.Op != OpConst32) => (Or32 i (Or32 <t> z x))
+(Or16 (Or16 i:(Const16 <t>) z) x) && (z.Op != OpConst16 && x.Op != OpConst16) => (Or16 i (Or16 <t> z x))
+(Or8  (Or8  i:(Const8  <t>) z) x) && (z.Op != OpConst8  && x.Op != OpConst8)  => (Or8  i (Or8  <t> z x))
+
+// x ^ (C ^ z) -> C ^ (x ^ z)
+(Xor64 (Xor64 i:(Const64 <t>) z) x) && (z.Op != OpConst64 && x.Op != OpConst64) => (Xor64 i (Xor64 <t> z x))
+(Xor32 (Xor32 i:(Const32 <t>) z) x) && (z.Op != OpConst32 && x.Op != OpConst32) => (Xor32 i (Xor32 <t> z x))
+(Xor16 (Xor16 i:(Const16 <t>) z) x) && (z.Op != OpConst16 && x.Op != OpConst16) => (Xor16 i (Xor16 <t> z x))
+(Xor8  (Xor8  i:(Const8  <t>) z) x) && (z.Op != OpConst8  && x.Op != OpConst8)  => (Xor8  i (Xor8  <t> z x))
+
+// x * (D * z) = D * (x * z)
+(Mul64 (Mul64 i:(Const64 <t>) z) x) && (z.Op != OpConst64 && x.Op != OpConst64) => (Mul64 i (Mul64 <t> x z))
+(Mul32 (Mul32 i:(Const32 <t>) z) x) && (z.Op != OpConst32 && x.Op != OpConst32) => (Mul32 i (Mul32 <t> x z))
+(Mul16 (Mul16 i:(Const16 <t>) z) x) && (z.Op != OpConst16 && x.Op != OpConst16) => (Mul16 i (Mul16 <t> x z))
+(Mul8  (Mul8  i:(Const8  <t>) z) x) && (z.Op != OpConst8  && x.Op != OpConst8)  => (Mul8  i (Mul8  <t> x z))
+
+// C + (D + x) -> (C + D) + x
+(Add64 (Const64 <t> [c]) (Add64 (Const64 <t> [d]) x)) => (Add64 (Const64 <t> [c+d]) x)
+(Add32 (Const32 <t> [c]) (Add32 (Const32 <t> [d]) x)) => (Add32 (Const32 <t> [c+d]) x)
+(Add16 (Const16 <t> [c]) (Add16 (Const16 <t> [d]) x)) => (Add16 (Const16 <t> [c+d]) x)
+(Add8  (Const8  <t> [c]) (Add8  (Const8  <t> [d]) x)) => (Add8  (Const8  <t> [c+d]) x)
+
+// C + (D - x) -> (C + D) - x
+(Add64 (Const64 <t> [c]) (Sub64 (Const64 <t> [d]) x)) => (Sub64 (Const64 <t> [c+d]) x)
+(Add32 (Const32 <t> [c]) (Sub32 (Const32 <t> [d]) x)) => (Sub32 (Const32 <t> [c+d]) x)
+(Add16 (Const16 <t> [c]) (Sub16 (Const16 <t> [d]) x)) => (Sub16 (Const16 <t> [c+d]) x)
+(Add8  (Const8  <t> [c]) (Sub8  (Const8  <t> [d]) x)) => (Sub8  (Const8  <t> [c+d]) x)
+
+// C - (D - x) -> (C - D) + x
+(Sub64 (Const64 <t> [c]) (Sub64 (Const64 <t> [d]) x)) => (Add64 (Const64 <t> [c-d]) x)
+(Sub32 (Const32 <t> [c]) (Sub32 (Const32 <t> [d]) x)) => (Add32 (Const32 <t> [c-d]) x)
+(Sub16 (Const16 <t> [c]) (Sub16 (Const16 <t> [d]) x)) => (Add16 (Const16 <t> [c-d]) x)
+(Sub8  (Const8  <t> [c]) (Sub8  (Const8  <t> [d]) x)) => (Add8  (Const8  <t> [c-d]) x)
+
+// C - (D + x) -> (C - D) - x
+(Sub64 (Const64 <t> [c]) (Add64 (Const64 <t> [d]) x)) => (Sub64 (Const64 <t> [c-d]) x)
+(Sub32 (Const32 <t> [c]) (Add32 (Const32 <t> [d]) x)) => (Sub32 (Const32 <t> [c-d]) x)
+(Sub16 (Const16 <t> [c]) (Add16 (Const16 <t> [d]) x)) => (Sub16 (Const16 <t> [c-d]) x)
+(Sub8  (Const8  <t> [c]) (Add8  (Const8  <t> [d]) x)) => (Sub8  (Const8  <t> [c-d]) x)
+
+// C & (D & x) -> (C & D) & x
+(And64 (Const64 <t> [c]) (And64 (Const64 <t> [d]) x)) => (And64 (Const64 <t> [c&d]) x)
+(And32 (Const32 <t> [c]) (And32 (Const32 <t> [d]) x)) => (And32 (Const32 <t> [c&d]) x)
+(And16 (Const16 <t> [c]) (And16 (Const16 <t> [d]) x)) => (And16 (Const16 <t> [c&d]) x)
+(And8  (Const8  <t> [c]) (And8  (Const8  <t> [d]) x)) => (And8  (Const8  <t> [c&d]) x)
+
+// C | (D | x) -> (C | D) | x
+(Or64 (Const64 <t> [c]) (Or64 (Const64 <t> [d]) x)) => (Or64 (Const64 <t> [c|d]) x)
+(Or32 (Const32 <t> [c]) (Or32 (Const32 <t> [d]) x)) => (Or32 (Const32 <t> [c|d]) x)
+(Or16 (Const16 <t> [c]) (Or16 (Const16 <t> [d]) x)) => (Or16 (Const16 <t> [c|d]) x)
+(Or8  (Const8  <t> [c]) (Or8  (Const8  <t> [d]) x)) => (Or8  (Const8  <t> [c|d]) x)
+
+// C ^ (D ^ x) -> (C ^ D) ^ x
+(Xor64 (Const64 <t> [c]) (Xor64 (Const64 <t> [d]) x)) => (Xor64 (Const64 <t> [c^d]) x)
+(Xor32 (Const32 <t> [c]) (Xor32 (Const32 <t> [d]) x)) => (Xor32 (Const32 <t> [c^d]) x)
+(Xor16 (Const16 <t> [c]) (Xor16 (Const16 <t> [d]) x)) => (Xor16 (Const16 <t> [c^d]) x)
+(Xor8  (Const8  <t> [c]) (Xor8  (Const8  <t> [d]) x)) => (Xor8  (Const8  <t> [c^d]) x)
+
+// C * (D * x) = (C * D) * x
+(Mul64 (Const64 <t> [c]) (Mul64 (Const64 <t> [d]) x)) => (Mul64 (Const64 <t> [c*d]) x)
+(Mul32 (Const32 <t> [c]) (Mul32 (Const32 <t> [d]) x)) => (Mul32 (Const32 <t> [c*d]) x)
+(Mul16 (Const16 <t> [c]) (Mul16 (Const16 <t> [d]) x)) => (Mul16 (Const16 <t> [c*d]) x)
+(Mul8  (Const8  <t> [c]) (Mul8  (Const8  <t> [d]) x)) => (Mul8  (Const8  <t> [c*d]) x)
+
+// floating point optimizations
+(Mul(32|64)F x (Const(32|64)F [1])) => x
+(Mul32F x (Const32F [-1])) => (Neg32F x)
+(Mul64F x (Const64F [-1])) => (Neg64F x)
+(Mul32F x (Const32F [2])) => (Add32F x x)
+(Mul64F x (Const64F [2])) => (Add64F x x)
+
+(Div32F x (Const32F <t> [c])) && reciprocalExact32(c) => (Mul32F x (Const32F <t> [1/c]))
+(Div64F x (Const64F <t> [c])) && reciprocalExact64(c) => (Mul64F x (Const64F <t> [1/c]))
+
+// rewrite single-precision sqrt expression "float32(math.Sqrt(float64(x)))"
+(Cvt64Fto32F sqrt0:(Sqrt (Cvt32Fto64F x))) && sqrt0.Uses==1 => (Sqrt32 x)
+
+(Sqrt (Const64F [c])) && !math.IsNaN(math.Sqrt(c)) => (Const64F [math.Sqrt(c)])
+
+// for rewriting results of some late-expanded rewrites (below)
+(SelectN [0] (MakeResult x ___)) => x
+(SelectN [1] (MakeResult x y ___)) => y
+(SelectN [2] (MakeResult x y z ___)) => z
+
+// for late-expanded calls, recognize newobject and remove zeroing and nilchecks
+(Zero (SelectN [0] call:(StaticLECall _ _)) mem:(SelectN [1] call))
+	&& isSameCall(call.Aux, "runtime.newobject")
+	=> mem
+
+(Store (SelectN [0] call:(StaticLECall _ _)) x mem:(SelectN [1] call))
+	&& isConstZero(x)
+	&& isSameCall(call.Aux, "runtime.newobject")
+	=> mem
+
+(Store (OffPtr (SelectN [0] call:(StaticLECall _ _))) x mem:(SelectN [1] call))
+	&& isConstZero(x)
+	&& isSameCall(call.Aux, "runtime.newobject")
+	=> mem
+
+(NilCheck (SelectN [0] call:(StaticLECall _ _)) _)
+	&& isSameCall(call.Aux, "runtime.newobject")
+	&& warnRule(fe.Debug_checknil(), v, "removed nil check")
+	=> (Invalid)
+
+(NilCheck (OffPtr (SelectN [0] call:(StaticLECall _ _))) _)
+	&& isSameCall(call.Aux, "runtime.newobject")
+	&& warnRule(fe.Debug_checknil(), v, "removed nil check")
+	=> (Invalid)
+
+// for late-expanded calls, recognize memequal applied to a single constant byte
+// Support is limited by 1, 2, 4, 8 byte sizes
+(StaticLECall {callAux} sptr (Addr {scon} (SB)) (Const64 [1]) mem)
+  && isSameCall(callAux, "runtime.memequal")
+  && symIsRO(scon)
+  => (MakeResult (Eq8 (Load <typ.Int8> sptr mem) (Const8 <typ.Int8> [int8(read8(scon,0))])) mem)
+
+(StaticLECall {callAux} sptr (Addr {scon} (SB)) (Const64 [2]) mem)
+  && isSameCall(callAux, "runtime.memequal")
+  && symIsRO(scon)
+  && canLoadUnaligned(config)
+  => (MakeResult (Eq16 (Load <typ.Int16> sptr mem) (Const16 <typ.Int16> [int16(read16(scon,0,config.ctxt.Arch.ByteOrder))])) mem)
+
+(StaticLECall {callAux} sptr (Addr {scon} (SB)) (Const64 [4]) mem)
+  && isSameCall(callAux, "runtime.memequal")
+  && symIsRO(scon)
+  && canLoadUnaligned(config)
+  => (MakeResult (Eq32 (Load <typ.Int32> sptr mem) (Const32 <typ.Int32> [int32(read32(scon,0,config.ctxt.Arch.ByteOrder))])) mem)
+
+(StaticLECall {callAux} sptr (Addr {scon} (SB)) (Const64 [8]) mem)
+  && isSameCall(callAux, "runtime.memequal")
+  && symIsRO(scon)
+  && canLoadUnaligned(config) && config.PtrSize == 8
+  => (MakeResult (Eq64 (Load <typ.Int64> sptr mem) (Const64 <typ.Int64> [int64(read64(scon,0,config.ctxt.Arch.ByteOrder))])) mem)
+
+// Evaluate constant address comparisons.
+(EqPtr  x x) => (ConstBool [true])
+(NeqPtr x x) => (ConstBool [false])
+(EqPtr  (Addr {x} _) (Addr {y} _)) => (ConstBool [x == y])
+(EqPtr  (Addr {x} _) (OffPtr [o] (Addr {y} _))) => (ConstBool [x == y && o == 0])
+(EqPtr  (OffPtr [o1] (Addr {x} _)) (OffPtr [o2] (Addr {y} _))) => (ConstBool [x == y && o1 == o2])
+(NeqPtr (Addr {x} _) (Addr {y} _)) => (ConstBool [x != y])
+(NeqPtr (Addr {x} _) (OffPtr [o] (Addr {y} _))) => (ConstBool [x != y || o != 0])
+(NeqPtr (OffPtr [o1] (Addr {x} _)) (OffPtr [o2] (Addr {y} _))) => (ConstBool [x != y || o1 != o2])
+(EqPtr  (LocalAddr {x} _ _) (LocalAddr {y} _ _)) => (ConstBool [x == y])
+(EqPtr  (LocalAddr {x} _ _) (OffPtr [o] (LocalAddr {y} _ _))) => (ConstBool [x == y && o == 0])
+(EqPtr  (OffPtr [o1] (LocalAddr {x} _ _)) (OffPtr [o2] (LocalAddr {y} _ _))) => (ConstBool [x == y && o1 == o2])
+(NeqPtr (LocalAddr {x} _ _) (LocalAddr {y} _ _)) => (ConstBool [x != y])
+(NeqPtr (LocalAddr {x} _ _) (OffPtr [o] (LocalAddr {y} _ _))) => (ConstBool [x != y || o != 0])
+(NeqPtr (OffPtr [o1] (LocalAddr {x} _ _)) (OffPtr [o2] (LocalAddr {y} _ _))) => (ConstBool [x != y || o1 != o2])
+(EqPtr  (OffPtr [o1] p1) p2) && isSamePtr(p1, p2) => (ConstBool [o1 == 0])
+(NeqPtr (OffPtr [o1] p1) p2) && isSamePtr(p1, p2) => (ConstBool [o1 != 0])
+(EqPtr  (OffPtr [o1] p1) (OffPtr [o2] p2)) && isSamePtr(p1, p2) => (ConstBool [o1 == o2])
+(NeqPtr (OffPtr [o1] p1) (OffPtr [o2] p2)) && isSamePtr(p1, p2) => (ConstBool [o1 != o2])
+(EqPtr  (Const(32|64) [c]) (Const(32|64) [d])) => (ConstBool [c == d])
+(NeqPtr (Const(32|64) [c]) (Const(32|64) [d])) => (ConstBool [c != d])
+
+(EqPtr  (LocalAddr _ _) (Addr _)) => (ConstBool [false])
+(EqPtr  (OffPtr (LocalAddr _ _)) (Addr _)) => (ConstBool [false])
+(EqPtr  (LocalAddr _ _) (OffPtr (Addr _))) => (ConstBool [false])
+(EqPtr  (OffPtr (LocalAddr _ _)) (OffPtr (Addr _))) => (ConstBool [false])
+(NeqPtr (LocalAddr _ _) (Addr _)) => (ConstBool [true])
+(NeqPtr (OffPtr (LocalAddr _ _)) (Addr _)) => (ConstBool [true])
+(NeqPtr (LocalAddr _ _) (OffPtr (Addr _))) => (ConstBool [true])
+(NeqPtr (OffPtr (LocalAddr _ _)) (OffPtr (Addr _))) => (ConstBool [true])
+
+// Simplify address comparisons.
+(EqPtr  (AddPtr p1 o1) p2) && isSamePtr(p1, p2) => (Not (IsNonNil o1))
+(NeqPtr (AddPtr p1 o1) p2) && isSamePtr(p1, p2) => (IsNonNil o1)
+(EqPtr  (Const(32|64) [0]) p) => (Not (IsNonNil p))
+(NeqPtr (Const(32|64) [0]) p) => (IsNonNil p)
+(EqPtr  (ConstNil) p) => (Not (IsNonNil p))
+(NeqPtr (ConstNil) p) => (IsNonNil p)
+
+// Evaluate constant user nil checks.
+(IsNonNil (ConstNil)) => (ConstBool [false])
+(IsNonNil (Const(32|64) [c])) => (ConstBool [c != 0])
+(IsNonNil (Addr _)) => (ConstBool [true])
+(IsNonNil (LocalAddr _ _)) => (ConstBool [true])
+
+// Inline small or disjoint runtime.memmove calls with constant length.
+// See the comment in op Move in genericOps.go for discussion of the type.
+//
+// Note that we've lost any knowledge of the type and alignment requirements
+// of the source and destination. We only know the size, and that the type
+// contains no pointers.
+// The type of the move is not necessarily v.Args[0].Type().Elem()!
+// See issue 55122 for details.
+//
+// Because expand calls runs after prove, constants useful to this pattern may not appear.
+// Both versions need to exist; the memory and register variants.
+//
+// Match post-expansion calls, memory version.
+(SelectN [0] call:(StaticCall {sym} s1:(Store _ (Const(64|32) [sz]) s2:(Store  _ src s3:(Store {t} _ dst mem)))))
+	&& sz >= 0
+	&& isSameCall(sym, "runtime.memmove")
+	&& s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1
+	&& isInlinableMemmove(dst, src, int64(sz), config)
+	&& clobber(s1, s2, s3, call)
+	=> (Move {types.Types[types.TUINT8]} [int64(sz)] dst src mem)
+
+// Match post-expansion calls, register version.
+(SelectN [0] call:(StaticCall {sym} dst src (Const(64|32) [sz]) mem))
+	&& sz >= 0
+	&& call.Uses == 1 // this will exclude all calls with results
+	&& isSameCall(sym, "runtime.memmove")
+	&& isInlinableMemmove(dst, src, int64(sz), config)
+	&& clobber(call)
+	=> (Move {types.Types[types.TUINT8]} [int64(sz)] dst src mem)
+
+// Match pre-expansion calls.
+(SelectN [0] call:(StaticLECall {sym} dst src (Const(64|32) [sz]) mem))
+	&& sz >= 0
+	&& call.Uses == 1 // this will exclude all calls with results
+	&& isSameCall(sym, "runtime.memmove")
+	&& isInlinableMemmove(dst, src, int64(sz), config)
+	&& clobber(call)
+	=> (Move {types.Types[types.TUINT8]} [int64(sz)] dst src mem)
+
+// De-virtualize late-expanded interface calls into late-expanded static calls.
+// Note that (ITab (IMake)) doesn't get rewritten until after the first opt pass,
+// so this rule should trigger reliably.
+// devirtLECall removes the first argument, adds the devirtualized symbol to the AuxCall, and changes the opcode
+(InterLECall [argsize] {auxCall} (Load (OffPtr [off] (ITab (IMake (Addr {itab} (SB)) _))) _) ___) && devirtLESym(v, auxCall, itab, off) !=
+    nil => devirtLECall(v, devirtLESym(v, auxCall, itab, off))
+
+// Move and Zero optimizations.
+// Move source and destination may overlap.
+
+// Convert Moves into Zeros when the source is known to be zeros.
+(Move {t} [n] dst1 src mem:(Zero {t} [n] dst2 _)) && isSamePtr(src, dst2)
+	=> (Zero {t} [n] dst1 mem)
+(Move {t} [n] dst1 src mem:(VarDef (Zero {t} [n] dst0 _))) && isSamePtr(src, dst0)
+	=> (Zero {t} [n] dst1 mem)
+(Move {t} [n] dst (Addr {sym} (SB)) mem) && symIsROZero(sym) => (Zero {t} [n] dst mem)
+
+// Don't Store to variables that are about to be overwritten by Move/Zero.
+(Zero {t1} [n] p1 store:(Store {t2} (OffPtr [o2] p2) _ mem))
+	&& isSamePtr(p1, p2) && store.Uses == 1
+	&& n >= o2 + t2.Size()
+	&& clobber(store)
+	=> (Zero {t1} [n] p1 mem)
+(Move {t1} [n] dst1 src1 store:(Store {t2} op:(OffPtr [o2] dst2) _ mem))
+	&& isSamePtr(dst1, dst2) && store.Uses == 1
+	&& n >= o2 + t2.Size()
+	&& disjoint(src1, n, op, t2.Size())
+	&& clobber(store)
+	=> (Move {t1} [n] dst1 src1 mem)
+
+// Don't Move to variables that are immediately completely overwritten.
+(Zero {t} [n] dst1 move:(Move {t} [n] dst2 _ mem))
+	&& move.Uses == 1
+	&& isSamePtr(dst1, dst2)
+	&& clobber(move)
+	=> (Zero {t} [n] dst1 mem)
+(Move {t} [n] dst1 src1 move:(Move {t} [n] dst2 _ mem))
+	&& move.Uses == 1
+	&& isSamePtr(dst1, dst2) && disjoint(src1, n, dst2, n)
+	&& clobber(move)
+	=> (Move {t} [n] dst1 src1 mem)
+(Zero {t} [n] dst1 vardef:(VarDef {x} move:(Move {t} [n] dst2 _ mem)))
+	&& move.Uses == 1 && vardef.Uses == 1
+	&& isSamePtr(dst1, dst2)
+	&& clobber(move, vardef)
+	=> (Zero {t} [n] dst1 (VarDef {x} mem))
+(Move {t} [n] dst1 src1 vardef:(VarDef {x} move:(Move {t} [n] dst2 _ mem)))
+	&& move.Uses == 1 && vardef.Uses == 1
+	&& isSamePtr(dst1, dst2) && disjoint(src1, n, dst2, n)
+	&& clobber(move, vardef)
+	=> (Move {t} [n] dst1 src1 (VarDef {x} mem))
+(Store {t1} op1:(OffPtr [o1] p1) d1
+	m2:(Store {t2} op2:(OffPtr [0] p2) d2
+		m3:(Move [n] p3 _ mem)))
+	&& m2.Uses == 1 && m3.Uses == 1
+	&& o1 == t2.Size()
+	&& n == t2.Size() + t1.Size()
+	&& isSamePtr(p1, p2) && isSamePtr(p2, p3)
+	&& clobber(m2, m3)
+	=> (Store {t1} op1 d1 (Store {t2} op2 d2 mem))
+(Store {t1} op1:(OffPtr [o1] p1) d1
+	m2:(Store {t2} op2:(OffPtr [o2] p2) d2
+		m3:(Store {t3} op3:(OffPtr [0] p3) d3
+			m4:(Move [n] p4 _ mem))))
+	&& m2.Uses == 1 && m3.Uses == 1 && m4.Uses == 1
+	&& o2 == t3.Size()
+	&& o1-o2 == t2.Size()
+	&& n == t3.Size() + t2.Size() + t1.Size()
+	&& isSamePtr(p1, p2) && isSamePtr(p2, p3) && isSamePtr(p3, p4)
+	&& clobber(m2, m3, m4)
+	=> (Store {t1} op1 d1 (Store {t2} op2 d2 (Store {t3} op3 d3 mem)))
+(Store {t1} op1:(OffPtr [o1] p1) d1
+	m2:(Store {t2} op2:(OffPtr [o2] p2) d2
+		m3:(Store {t3} op3:(OffPtr [o3] p3) d3
+			m4:(Store {t4} op4:(OffPtr [0] p4) d4
+				m5:(Move [n] p5 _ mem)))))
+	&& m2.Uses == 1 && m3.Uses == 1 && m4.Uses == 1 && m5.Uses == 1
+	&& o3 == t4.Size()
+	&& o2-o3 == t3.Size()
+	&& o1-o2 == t2.Size()
+	&& n == t4.Size() + t3.Size() + t2.Size() + t1.Size()
+	&& isSamePtr(p1, p2) && isSamePtr(p2, p3) && isSamePtr(p3, p4) && isSamePtr(p4, p5)
+	&& clobber(m2, m3, m4, m5)
+	=> (Store {t1} op1 d1 (Store {t2} op2 d2 (Store {t3} op3 d3 (Store {t4} op4 d4 mem))))
+
+// Don't Zero variables that are immediately completely overwritten
+// before being accessed.
+(Move {t} [n] dst1 src1 zero:(Zero {t} [n] dst2 mem))
+	&& zero.Uses == 1
+	&& isSamePtr(dst1, dst2) && disjoint(src1, n, dst2, n)
+	&& clobber(zero)
+	=> (Move {t} [n] dst1 src1 mem)
+(Move {t} [n] dst1 src1 vardef:(VarDef {x} zero:(Zero {t} [n] dst2 mem)))
+	&& zero.Uses == 1 && vardef.Uses == 1
+	&& isSamePtr(dst1, dst2) && disjoint(src1, n, dst2, n)
+	&& clobber(zero, vardef)
+	=> (Move {t} [n] dst1 src1 (VarDef {x} mem))
+(Store {t1} op1:(OffPtr [o1] p1) d1
+	m2:(Store {t2} op2:(OffPtr [0] p2) d2
+		m3:(Zero [n] p3 mem)))
+	&& m2.Uses == 1 && m3.Uses == 1
+	&& o1 == t2.Size()
+	&& n == t2.Size() + t1.Size()
+	&& isSamePtr(p1, p2) && isSamePtr(p2, p3)
+	&& clobber(m2, m3)
+	=> (Store {t1} op1 d1 (Store {t2} op2 d2 mem))
+(Store {t1} op1:(OffPtr [o1] p1) d1
+	m2:(Store {t2} op2:(OffPtr [o2] p2) d2
+		m3:(Store {t3} op3:(OffPtr [0] p3) d3
+			m4:(Zero [n] p4 mem))))
+	&& m2.Uses == 1 && m3.Uses == 1 && m4.Uses == 1
+	&& o2 == t3.Size()
+	&& o1-o2 == t2.Size()
+	&& n == t3.Size() + t2.Size() + t1.Size()
+	&& isSamePtr(p1, p2) && isSamePtr(p2, p3) && isSamePtr(p3, p4)
+	&& clobber(m2, m3, m4)
+	=> (Store {t1} op1 d1 (Store {t2} op2 d2 (Store {t3} op3 d3 mem)))
+(Store {t1} op1:(OffPtr [o1] p1) d1
+	m2:(Store {t2} op2:(OffPtr [o2] p2) d2
+		m3:(Store {t3} op3:(OffPtr [o3] p3) d3
+			m4:(Store {t4} op4:(OffPtr [0] p4) d4
+				m5:(Zero [n] p5 mem)))))
+	&& m2.Uses == 1 && m3.Uses == 1 && m4.Uses == 1 && m5.Uses == 1
+	&& o3 == t4.Size()
+	&& o2-o3 == t3.Size()
+	&& o1-o2 == t2.Size()
+	&& n == t4.Size() + t3.Size() + t2.Size() + t1.Size()
+	&& isSamePtr(p1, p2) && isSamePtr(p2, p3) && isSamePtr(p3, p4) && isSamePtr(p4, p5)
+	&& clobber(m2, m3, m4, m5)
+	=> (Store {t1} op1 d1 (Store {t2} op2 d2 (Store {t3} op3 d3 (Store {t4} op4 d4 mem))))
+
+// Don't Move from memory if the values are likely to already be
+// in registers.
+(Move {t1} [n] dst p1
+	mem:(Store {t2} op2:(OffPtr <tt2> [o2] p2) d1
+		(Store {t3} op3:(OffPtr <tt3> [0] p3) d2 _)))
+	&& isSamePtr(p1, p2) && isSamePtr(p2, p3)
+	&& t2.Alignment() <= t1.Alignment()
+	&& t3.Alignment() <= t1.Alignment()
+	&& registerizable(b, t2)
+	&& registerizable(b, t3)
+	&& o2 == t3.Size()
+	&& n == t2.Size() + t3.Size()
+	=> (Store {t2} (OffPtr <tt2> [o2] dst) d1
+		(Store {t3} (OffPtr <tt3> [0] dst) d2 mem))
+(Move {t1} [n] dst p1
+	mem:(Store {t2} op2:(OffPtr <tt2> [o2] p2) d1
+		(Store {t3} op3:(OffPtr <tt3> [o3] p3) d2
+			(Store {t4} op4:(OffPtr <tt4> [0] p4) d3 _))))
+	&& isSamePtr(p1, p2) && isSamePtr(p2, p3) && isSamePtr(p3, p4)
+	&& t2.Alignment() <= t1.Alignment()
+	&& t3.Alignment() <= t1.Alignment()
+	&& t4.Alignment() <= t1.Alignment()
+	&& registerizable(b, t2)
+	&& registerizable(b, t3)
+	&& registerizable(b, t4)
+	&& o3 == t4.Size()
+	&& o2-o3 == t3.Size()
+	&& n == t2.Size() + t3.Size() + t4.Size()
+	=> (Store {t2} (OffPtr <tt2> [o2] dst) d1
+		(Store {t3} (OffPtr <tt3> [o3] dst) d2
+			(Store {t4} (OffPtr <tt4> [0] dst) d3 mem)))
+(Move {t1} [n] dst p1
+	mem:(Store {t2} op2:(OffPtr <tt2> [o2] p2) d1
+		(Store {t3} op3:(OffPtr <tt3> [o3] p3) d2
+			(Store {t4} op4:(OffPtr <tt4> [o4] p4) d3
+				(Store {t5} op5:(OffPtr <tt5> [0] p5) d4 _)))))
+	&& isSamePtr(p1, p2) && isSamePtr(p2, p3) && isSamePtr(p3, p4) && isSamePtr(p4, p5)
+	&& t2.Alignment() <= t1.Alignment()
+	&& t3.Alignment() <= t1.Alignment()
+	&& t4.Alignment() <= t1.Alignment()
+	&& t5.Alignment() <= t1.Alignment()
+	&& registerizable(b, t2)
+	&& registerizable(b, t3)
+	&& registerizable(b, t4)
+	&& registerizable(b, t5)
+	&& o4 == t5.Size()
+	&& o3-o4 == t4.Size()
+	&& o2-o3 == t3.Size()
+	&& n == t2.Size() + t3.Size() + t4.Size() + t5.Size()
+	=> (Store {t2} (OffPtr <tt2> [o2] dst) d1
+		(Store {t3} (OffPtr <tt3> [o3] dst) d2
+			(Store {t4} (OffPtr <tt4> [o4] dst) d3
+				(Store {t5} (OffPtr <tt5> [0] dst) d4 mem))))
+
+// Same thing but with VarDef in the middle.
+(Move {t1} [n] dst p1
+	mem:(VarDef
+		(Store {t2} op2:(OffPtr <tt2> [o2] p2) d1
+			(Store {t3} op3:(OffPtr <tt3> [0] p3) d2 _))))
+	&& isSamePtr(p1, p2) && isSamePtr(p2, p3)
+	&& t2.Alignment() <= t1.Alignment()
+	&& t3.Alignment() <= t1.Alignment()
+	&& registerizable(b, t2)
+	&& registerizable(b, t3)
+	&& o2 == t3.Size()
+	&& n == t2.Size() + t3.Size()
+	=> (Store {t2} (OffPtr <tt2> [o2] dst) d1
+		(Store {t3} (OffPtr <tt3> [0] dst) d2 mem))
+(Move {t1} [n] dst p1
+	mem:(VarDef
+		(Store {t2} op2:(OffPtr <tt2> [o2] p2) d1
+			(Store {t3} op3:(OffPtr <tt3> [o3] p3) d2
+				(Store {t4} op4:(OffPtr <tt4> [0] p4) d3 _)))))
+	&& isSamePtr(p1, p2) && isSamePtr(p2, p3) && isSamePtr(p3, p4)
+	&& t2.Alignment() <= t1.Alignment()
+	&& t3.Alignment() <= t1.Alignment()
+	&& t4.Alignment() <= t1.Alignment()
+	&& registerizable(b, t2)
+	&& registerizable(b, t3)
+	&& registerizable(b, t4)
+	&& o3 == t4.Size()
+	&& o2-o3 == t3.Size()
+	&& n == t2.Size() + t3.Size() + t4.Size()
+	=> (Store {t2} (OffPtr <tt2> [o2] dst) d1
+		(Store {t3} (OffPtr <tt3> [o3] dst) d2
+			(Store {t4} (OffPtr <tt4> [0] dst) d3 mem)))
+(Move {t1} [n] dst p1
+	mem:(VarDef
+		(Store {t2} op2:(OffPtr <tt2> [o2] p2) d1
+			(Store {t3} op3:(OffPtr <tt3> [o3] p3) d2
+				(Store {t4} op4:(OffPtr <tt4> [o4] p4) d3
+					(Store {t5} op5:(OffPtr <tt5> [0] p5) d4 _))))))
+	&& isSamePtr(p1, p2) && isSamePtr(p2, p3) && isSamePtr(p3, p4) && isSamePtr(p4, p5)
+	&& t2.Alignment() <= t1.Alignment()
+	&& t3.Alignment() <= t1.Alignment()
+	&& t4.Alignment() <= t1.Alignment()
+	&& t5.Alignment() <= t1.Alignment()
+	&& registerizable(b, t2)
+	&& registerizable(b, t3)
+	&& registerizable(b, t4)
+	&& registerizable(b, t5)
+	&& o4 == t5.Size()
+	&& o3-o4 == t4.Size()
+	&& o2-o3 == t3.Size()
+	&& n == t2.Size() + t3.Size() + t4.Size() + t5.Size()
+	=> (Store {t2} (OffPtr <tt2> [o2] dst) d1
+		(Store {t3} (OffPtr <tt3> [o3] dst) d2
+			(Store {t4} (OffPtr <tt4> [o4] dst) d3
+				(Store {t5} (OffPtr <tt5> [0] dst) d4 mem))))
+
+// Prefer to Zero and Store than to Move.
+(Move {t1} [n] dst p1
+	mem:(Store {t2} op2:(OffPtr <tt2> [o2] p2) d1
+		(Zero {t3} [n] p3 _)))
+	&& isSamePtr(p1, p2) && isSamePtr(p2, p3)
+	&& t2.Alignment() <= t1.Alignment()
+	&& t3.Alignment() <= t1.Alignment()
+	&& registerizable(b, t2)
+	&& n >= o2 + t2.Size()
+	=> (Store {t2} (OffPtr <tt2> [o2] dst) d1
+		(Zero {t1} [n] dst mem))
+(Move {t1} [n] dst p1
+	mem:(Store {t2} (OffPtr <tt2> [o2] p2) d1
+		(Store {t3} (OffPtr <tt3> [o3] p3) d2
+			(Zero {t4} [n] p4 _))))
+	&& isSamePtr(p1, p2) && isSamePtr(p2, p3) && isSamePtr(p3, p4)
+	&& t2.Alignment() <= t1.Alignment()
+	&& t3.Alignment() <= t1.Alignment()
+	&& t4.Alignment() <= t1.Alignment()
+	&& registerizable(b, t2)
+	&& registerizable(b, t3)
+	&& n >= o2 + t2.Size()
+	&& n >= o3 + t3.Size()
+	=> (Store {t2} (OffPtr <tt2> [o2] dst) d1
+		(Store {t3} (OffPtr <tt3> [o3] dst) d2
+			(Zero {t1} [n] dst mem)))
+(Move {t1} [n] dst p1
+	mem:(Store {t2} (OffPtr <tt2> [o2] p2) d1
+		(Store {t3} (OffPtr <tt3> [o3] p3) d2
+			(Store {t4} (OffPtr <tt4> [o4] p4) d3
+				(Zero {t5} [n] p5 _)))))
+	&& isSamePtr(p1, p2) && isSamePtr(p2, p3) && isSamePtr(p3, p4) && isSamePtr(p4, p5)
+	&& t2.Alignment() <= t1.Alignment()
+	&& t3.Alignment() <= t1.Alignment()
+	&& t4.Alignment() <= t1.Alignment()
+	&& t5.Alignment() <= t1.Alignment()
+	&& registerizable(b, t2)
+	&& registerizable(b, t3)
+	&& registerizable(b, t4)
+	&& n >= o2 + t2.Size()
+	&& n >= o3 + t3.Size()
+	&& n >= o4 + t4.Size()
+	=> (Store {t2} (OffPtr <tt2> [o2] dst) d1
+		(Store {t3} (OffPtr <tt3> [o3] dst) d2
+			(Store {t4} (OffPtr <tt4> [o4] dst) d3
+				(Zero {t1} [n] dst mem))))
+(Move {t1} [n] dst p1
+	mem:(Store {t2} (OffPtr <tt2> [o2] p2) d1
+		(Store {t3} (OffPtr <tt3> [o3] p3) d2
+			(Store {t4} (OffPtr <tt4> [o4] p4) d3
+				(Store {t5} (OffPtr <tt5> [o5] p5) d4
+					(Zero {t6} [n] p6 _))))))
+	&& isSamePtr(p1, p2) && isSamePtr(p2, p3) && isSamePtr(p3, p4) && isSamePtr(p4, p5) && isSamePtr(p5, p6)
+	&& t2.Alignment() <= t1.Alignment()
+	&& t3.Alignment() <= t1.Alignment()
+	&& t4.Alignment() <= t1.Alignment()
+	&& t5.Alignment() <= t1.Alignment()
+	&& t6.Alignment() <= t1.Alignment()
+	&& registerizable(b, t2)
+	&& registerizable(b, t3)
+	&& registerizable(b, t4)
+	&& registerizable(b, t5)
+	&& n >= o2 + t2.Size()
+	&& n >= o3 + t3.Size()
+	&& n >= o4 + t4.Size()
+	&& n >= o5 + t5.Size()
+	=> (Store {t2} (OffPtr <tt2> [o2] dst) d1
+		(Store {t3} (OffPtr <tt3> [o3] dst) d2
+			(Store {t4} (OffPtr <tt4> [o4] dst) d3
+				(Store {t5} (OffPtr <tt5> [o5] dst) d4
+					(Zero {t1} [n] dst mem)))))
+(Move {t1} [n] dst p1
+	mem:(VarDef
+		(Store {t2} op2:(OffPtr <tt2> [o2] p2) d1
+			(Zero {t3} [n] p3 _))))
+	&& isSamePtr(p1, p2) && isSamePtr(p2, p3)
+	&& t2.Alignment() <= t1.Alignment()
+	&& t3.Alignment() <= t1.Alignment()
+	&& registerizable(b, t2)
+	&& n >= o2 + t2.Size()
+	=> (Store {t2} (OffPtr <tt2> [o2] dst) d1
+		(Zero {t1} [n] dst mem))
+(Move {t1} [n] dst p1
+	mem:(VarDef
+		(Store {t2} (OffPtr <tt2> [o2] p2) d1
+			(Store {t3} (OffPtr <tt3> [o3] p3) d2
+				(Zero {t4} [n] p4 _)))))
+	&& isSamePtr(p1, p2) && isSamePtr(p2, p3) && isSamePtr(p3, p4)
+	&& t2.Alignment() <= t1.Alignment()
+	&& t3.Alignment() <= t1.Alignment()
+	&& t4.Alignment() <= t1.Alignment()
+	&& registerizable(b, t2)
+	&& registerizable(b, t3)
+	&& n >= o2 + t2.Size()
+	&& n >= o3 + t3.Size()
+	=> (Store {t2} (OffPtr <tt2> [o2] dst) d1
+		(Store {t3} (OffPtr <tt3> [o3] dst) d2
+			(Zero {t1} [n] dst mem)))
+(Move {t1} [n] dst p1
+	mem:(VarDef
+		(Store {t2} (OffPtr <tt2> [o2] p2) d1
+			(Store {t3} (OffPtr <tt3> [o3] p3) d2
+				(Store {t4} (OffPtr <tt4> [o4] p4) d3
+					(Zero {t5} [n] p5 _))))))
+	&& isSamePtr(p1, p2) && isSamePtr(p2, p3) && isSamePtr(p3, p4) && isSamePtr(p4, p5)
+	&& t2.Alignment() <= t1.Alignment()
+	&& t3.Alignment() <= t1.Alignment()
+	&& t4.Alignment() <= t1.Alignment()
+	&& t5.Alignment() <= t1.Alignment()
+	&& registerizable(b, t2)
+	&& registerizable(b, t3)
+	&& registerizable(b, t4)
+	&& n >= o2 + t2.Size()
+	&& n >= o3 + t3.Size()
+	&& n >= o4 + t4.Size()
+	=> (Store {t2} (OffPtr <tt2> [o2] dst) d1
+		(Store {t3} (OffPtr <tt3> [o3] dst) d2
+			(Store {t4} (OffPtr <tt4> [o4] dst) d3
+				(Zero {t1} [n] dst mem))))
+(Move {t1} [n] dst p1
+	mem:(VarDef
+		(Store {t2} (OffPtr <tt2> [o2] p2) d1
+			(Store {t3} (OffPtr <tt3> [o3] p3) d2
+				(Store {t4} (OffPtr <tt4> [o4] p4) d3
+					(Store {t5} (OffPtr <tt5> [o5] p5) d4
+						(Zero {t6} [n] p6 _)))))))
+	&& isSamePtr(p1, p2) && isSamePtr(p2, p3) && isSamePtr(p3, p4) && isSamePtr(p4, p5) && isSamePtr(p5, p6)
+	&& t2.Alignment() <= t1.Alignment()
+	&& t3.Alignment() <= t1.Alignment()
+	&& t4.Alignment() <= t1.Alignment()
+	&& t5.Alignment() <= t1.Alignment()
+	&& t6.Alignment() <= t1.Alignment()
+	&& registerizable(b, t2)
+	&& registerizable(b, t3)
+	&& registerizable(b, t4)
+	&& registerizable(b, t5)
+	&& n >= o2 + t2.Size()
+	&& n >= o3 + t3.Size()
+	&& n >= o4 + t4.Size()
+	&& n >= o5 + t5.Size()
+	=> (Store {t2} (OffPtr <tt2> [o2] dst) d1
+		(Store {t3} (OffPtr <tt3> [o3] dst) d2
+			(Store {t4} (OffPtr <tt4> [o4] dst) d3
+				(Store {t5} (OffPtr <tt5> [o5] dst) d4
+					(Zero {t1} [n] dst mem)))))
+
+(SelectN [0] call:(StaticLECall {sym} a x)) && needRaceCleanup(sym, call) && clobber(call) => x
+(SelectN [0] call:(StaticLECall {sym} x)) && needRaceCleanup(sym, call) && clobber(call) => x
+
+// When rewriting append to growslice, we use as the the new length the result of
+// growslice so that we don't have to spill/restore the new length around the growslice call.
+// The exception here is that if the new length is a constant, avoiding spilling it
+// is pointless and its constantness is sometimes useful for subsequent optimizations.
+// See issue 56440.
+// Note there are 2 rules here, one for the pre-decomposed []T result and one for
+// the post-decomposed (*T,int,int) result. (The latter is generated after call expansion.)
+(SliceLen (SelectN [0] (StaticLECall {sym} _ newLen:(Const(64|32)) _ _ _ _))) && isSameCall(sym, "runtime.growslice") => newLen
+(SelectN [1] (StaticCall {sym} _ newLen:(Const(64|32)) _ _ _ _)) && v.Type.IsInteger() && isSameCall(sym, "runtime.growslice") => newLen
+
+// Collapse moving A -> B -> C into just A -> C.
+// Later passes (deadstore, elim unread auto) will remove the A -> B move, if possible.
+// This happens most commonly when B is an autotmp inserted earlier
+// during compilation to ensure correctness.
+// Take care that overlapping moves are preserved.
+// Restrict this optimization to the stack, to avoid duplicating loads from the heap;
+// see CL 145208 for discussion.
+(Move {t1} [s] dst tmp1 midmem:(Move {t2} [s] tmp2 src _))
+	&& t1.Compare(t2) == types.CMPeq
+	&& isSamePtr(tmp1, tmp2)
+	&& isStackPtr(src) && !isVolatile(src)
+	&& disjoint(src, s, tmp2, s)
+	&& (disjoint(src, s, dst, s) || isInlinableMemmove(dst, src, s, config))
+	=> (Move {t1} [s] dst src midmem)
+
+// Same, but for large types that require VarDefs.
+(Move {t1} [s] dst tmp1 midmem:(VarDef (Move {t2} [s] tmp2 src _)))
+	&& t1.Compare(t2) == types.CMPeq
+	&& isSamePtr(tmp1, tmp2)
+	&& isStackPtr(src) && !isVolatile(src)
+	&& disjoint(src, s, tmp2, s)
+	&& (disjoint(src, s, dst, s) || isInlinableMemmove(dst, src, s, config))
+	=> (Move {t1} [s] dst src midmem)
+
+// Don't zero the same bits twice.
+(Zero {t} [s] dst1 zero:(Zero {t} [s] dst2 _)) && isSamePtr(dst1, dst2) => zero
+(Zero {t} [s] dst1 vardef:(VarDef (Zero {t} [s] dst2 _))) && isSamePtr(dst1, dst2) => vardef
+
+// Elide self-moves. This only happens rarely (e.g test/fixedbugs/bug277.go).
+// However, this rule is needed to prevent the previous rule from looping forever in such cases.
+(Move dst src mem) && isSamePtr(dst, src) => mem
+
+// Constant rotate detection.
+((Add64|Or64|Xor64) (Lsh64x64 x z:(Const64 <t> [c])) (Rsh64Ux64 x (Const64 [d]))) && c < 64 && d == 64-c && canRotate(config, 64) => (RotateLeft64 x z)
+((Add32|Or32|Xor32) (Lsh32x64 x z:(Const64 <t> [c])) (Rsh32Ux64 x (Const64 [d]))) && c < 32 && d == 32-c && canRotate(config, 32) => (RotateLeft32 x z)
+((Add16|Or16|Xor16) (Lsh16x64 x z:(Const64 <t> [c])) (Rsh16Ux64 x (Const64 [d]))) && c < 16 && d == 16-c && canRotate(config, 16) => (RotateLeft16 x z)
+((Add8|Or8|Xor8) (Lsh8x64 x z:(Const64 <t> [c])) (Rsh8Ux64 x (Const64 [d]))) && c < 8 && d == 8-c && canRotate(config, 8) => (RotateLeft8 x z)
+
+// Non-constant rotate detection.
+// We use shiftIsBounded to make sure that neither of the shifts are >64.
+// Note: these rules are subtle when the shift amounts are 0/64, as Go shifts
+// are different from most native shifts. But it works out.
+((Add64|Or64|Xor64) left:(Lsh64x64 x y) right:(Rsh64Ux64 x (Sub64 (Const64 [64]) y))) && (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64) => (RotateLeft64 x y)
+((Add64|Or64|Xor64) left:(Lsh64x32 x y) right:(Rsh64Ux32 x (Sub32 (Const32 [64]) y))) && (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64) => (RotateLeft64 x y)
+((Add64|Or64|Xor64) left:(Lsh64x16 x y) right:(Rsh64Ux16 x (Sub16 (Const16 [64]) y))) && (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64) => (RotateLeft64 x y)
+((Add64|Or64|Xor64) left:(Lsh64x8  x y) right:(Rsh64Ux8  x (Sub8  (Const8  [64]) y))) && (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64) => (RotateLeft64 x y)
+
+((Add64|Or64|Xor64) right:(Rsh64Ux64 x y) left:(Lsh64x64 x z:(Sub64 (Const64 [64]) y))) && (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64) => (RotateLeft64 x z)
+((Add64|Or64|Xor64) right:(Rsh64Ux32 x y) left:(Lsh64x32 x z:(Sub32 (Const32 [64]) y))) && (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64) => (RotateLeft64 x z)
+((Add64|Or64|Xor64) right:(Rsh64Ux16 x y) left:(Lsh64x16 x z:(Sub16 (Const16 [64]) y))) && (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64) => (RotateLeft64 x z)
+((Add64|Or64|Xor64) right:(Rsh64Ux8  x y) left:(Lsh64x8  x z:(Sub8  (Const8  [64]) y))) && (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64) => (RotateLeft64 x z)
+
+((Add32|Or32|Xor32) left:(Lsh32x64 x y) right:(Rsh32Ux64 x (Sub64 (Const64 [32]) y))) && (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32) => (RotateLeft32 x y)
+((Add32|Or32|Xor32) left:(Lsh32x32 x y) right:(Rsh32Ux32 x (Sub32 (Const32 [32]) y))) && (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32) => (RotateLeft32 x y)
+((Add32|Or32|Xor32) left:(Lsh32x16 x y) right:(Rsh32Ux16 x (Sub16 (Const16 [32]) y))) && (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32) => (RotateLeft32 x y)
+((Add32|Or32|Xor32) left:(Lsh32x8  x y) right:(Rsh32Ux8  x (Sub8  (Const8  [32]) y))) && (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32) => (RotateLeft32 x y)
+
+((Add32|Or32|Xor32) right:(Rsh32Ux64 x y) left:(Lsh32x64 x z:(Sub64 (Const64 [32]) y))) && (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32) => (RotateLeft32 x z)
+((Add32|Or32|Xor32) right:(Rsh32Ux32 x y) left:(Lsh32x32 x z:(Sub32 (Const32 [32]) y))) && (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32) => (RotateLeft32 x z)
+((Add32|Or32|Xor32) right:(Rsh32Ux16 x y) left:(Lsh32x16 x z:(Sub16 (Const16 [32]) y))) && (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32) => (RotateLeft32 x z)
+((Add32|Or32|Xor32) right:(Rsh32Ux8  x y) left:(Lsh32x8  x z:(Sub8  (Const8  [32]) y))) && (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32) => (RotateLeft32 x z)
+
+((Add16|Or16|Xor16) left:(Lsh16x64 x y) right:(Rsh16Ux64 x (Sub64 (Const64 [16]) y))) && (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16) => (RotateLeft16 x y)
+((Add16|Or16|Xor16) left:(Lsh16x32 x y) right:(Rsh16Ux32 x (Sub32 (Const32 [16]) y))) && (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16) => (RotateLeft16 x y)
+((Add16|Or16|Xor16) left:(Lsh16x16 x y) right:(Rsh16Ux16 x (Sub16 (Const16 [16]) y))) && (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16) => (RotateLeft16 x y)
+((Add16|Or16|Xor16) left:(Lsh16x8  x y) right:(Rsh16Ux8  x (Sub8  (Const8  [16]) y))) && (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16) => (RotateLeft16 x y)
+
+((Add16|Or16|Xor16) right:(Rsh16Ux64 x y) left:(Lsh16x64 x z:(Sub64 (Const64 [16]) y))) && (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16) => (RotateLeft16 x z)
+((Add16|Or16|Xor16) right:(Rsh16Ux32 x y) left:(Lsh16x32 x z:(Sub32 (Const32 [16]) y))) && (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16) => (RotateLeft16 x z)
+((Add16|Or16|Xor16) right:(Rsh16Ux16 x y) left:(Lsh16x16 x z:(Sub16 (Const16 [16]) y))) && (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16) => (RotateLeft16 x z)
+((Add16|Or16|Xor16) right:(Rsh16Ux8  x y) left:(Lsh16x8  x z:(Sub8  (Const8  [16]) y))) && (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16) => (RotateLeft16 x z)
+
+((Add8|Or8|Xor8) left:(Lsh8x64 x y) right:(Rsh8Ux64 x (Sub64 (Const64 [8]) y))) && (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8) => (RotateLeft8 x y)
+((Add8|Or8|Xor8) left:(Lsh8x32 x y) right:(Rsh8Ux32 x (Sub32 (Const32 [8]) y))) && (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8) => (RotateLeft8 x y)
+((Add8|Or8|Xor8) left:(Lsh8x16 x y) right:(Rsh8Ux16 x (Sub16 (Const16 [8]) y))) && (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8) => (RotateLeft8 x y)
+((Add8|Or8|Xor8) left:(Lsh8x8  x y) right:(Rsh8Ux8  x (Sub8  (Const8  [8]) y))) && (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8) => (RotateLeft8 x y)
+
+((Add8|Or8|Xor8) right:(Rsh8Ux64 x y) left:(Lsh8x64 x z:(Sub64 (Const64 [8]) y))) && (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8) => (RotateLeft8 x z)
+((Add8|Or8|Xor8) right:(Rsh8Ux32 x y) left:(Lsh8x32 x z:(Sub32 (Const32 [8]) y))) && (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8) => (RotateLeft8 x z)
+((Add8|Or8|Xor8) right:(Rsh8Ux16 x y) left:(Lsh8x16 x z:(Sub16 (Const16 [8]) y))) && (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8) => (RotateLeft8 x z)
+((Add8|Or8|Xor8) right:(Rsh8Ux8  x y) left:(Lsh8x8  x z:(Sub8  (Const8  [8]) y))) && (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8) => (RotateLeft8 x z)
+
+// Rotating by y&c, with c a mask that doesn't change the bottom bits, is the same as rotating by y.
+(RotateLeft64 x (And(64|32|16|8) y (Const(64|32|16|8) [c]))) && c&63 == 63 => (RotateLeft64 x y)
+(RotateLeft32 x (And(64|32|16|8) y (Const(64|32|16|8) [c]))) && c&31 == 31 => (RotateLeft32 x y)
+(RotateLeft16 x (And(64|32|16|8) y (Const(64|32|16|8) [c]))) && c&15 == 15 => (RotateLeft16 x y)
+(RotateLeft8  x (And(64|32|16|8) y (Const(64|32|16|8) [c]))) && c&7  == 7  => (RotateLeft8  x y)
+
+// Rotating by -(y&c), with c a mask that doesn't change the bottom bits, is the same as rotating by -y.
+(RotateLeft64 x (Neg(64|32|16|8) (And(64|32|16|8) y (Const(64|32|16|8) [c])))) && c&63 == 63 => (RotateLeft64 x (Neg(64|32|16|8) <y.Type> y))
+(RotateLeft32 x (Neg(64|32|16|8) (And(64|32|16|8) y (Const(64|32|16|8) [c])))) && c&31 == 31 => (RotateLeft32 x (Neg(64|32|16|8) <y.Type> y))
+(RotateLeft16 x (Neg(64|32|16|8) (And(64|32|16|8) y (Const(64|32|16|8) [c])))) && c&15 == 15 => (RotateLeft16 x (Neg(64|32|16|8) <y.Type> y))
+(RotateLeft8  x (Neg(64|32|16|8) (And(64|32|16|8) y (Const(64|32|16|8) [c])))) && c&7  == 7  => (RotateLeft8  x (Neg(64|32|16|8) <y.Type> y))
+
+// Rotating by y+c, with c a multiple of the value width, is the same as rotating by y.
+(RotateLeft64 x (Add(64|32|16|8) y (Const(64|32|16|8) [c]))) && c&63 == 0 => (RotateLeft64 x y)
+(RotateLeft32 x (Add(64|32|16|8) y (Const(64|32|16|8) [c]))) && c&31 == 0 => (RotateLeft32 x y)
+(RotateLeft16 x (Add(64|32|16|8) y (Const(64|32|16|8) [c]))) && c&15 == 0 => (RotateLeft16 x y)
+(RotateLeft8  x (Add(64|32|16|8) y (Const(64|32|16|8) [c]))) && c&7  == 0 => (RotateLeft8  x y)
+
+// Rotating by c-y, with c a multiple of the value width, is the same as rotating by -y.
+(RotateLeft64 x (Sub(64|32|16|8) (Const(64|32|16|8) [c]) y)) && c&63 == 0 => (RotateLeft64 x (Neg(64|32|16|8) <y.Type> y))
+(RotateLeft32 x (Sub(64|32|16|8) (Const(64|32|16|8) [c]) y)) && c&31 == 0 => (RotateLeft32 x (Neg(64|32|16|8) <y.Type> y))
+(RotateLeft16 x (Sub(64|32|16|8) (Const(64|32|16|8) [c]) y)) && c&15 == 0 => (RotateLeft16 x (Neg(64|32|16|8) <y.Type> y))
+(RotateLeft8  x (Sub(64|32|16|8) (Const(64|32|16|8) [c]) y)) && c&7  == 0 => (RotateLeft8  x (Neg(64|32|16|8) <y.Type> y))
+
+// Ensure we don't do Const64 rotates in a 32-bit system.
+(RotateLeft64 x (Const64 <t> [c])) && config.PtrSize == 4 => (RotateLeft64 x (Const32 <t> [int32(c)]))
+(RotateLeft32 x (Const64 <t> [c])) && config.PtrSize == 4 => (RotateLeft32 x (Const32 <t> [int32(c)]))
+(RotateLeft16 x (Const64 <t> [c])) && config.PtrSize == 4 => (RotateLeft16 x (Const32 <t> [int32(c)]))
+(RotateLeft8  x (Const64 <t> [c])) && config.PtrSize == 4 => (RotateLeft8  x (Const32 <t> [int32(c)]))
+
+// Rotating by c, then by d, is the same as rotating by c+d.
+// We're trading a rotate for an add, which seems generally a good choice. It is especially good when c and d are constants.
+// This rule is a bit tricky as c and d might be different widths. We handle only cases where they are the same width.
+(RotateLeft(64|32|16|8) (RotateLeft(64|32|16|8) x c) d) && c.Type.Size() == 8 && d.Type.Size() == 8 => (RotateLeft(64|32|16|8) x (Add64 <c.Type> c d))
+(RotateLeft(64|32|16|8) (RotateLeft(64|32|16|8) x c) d) && c.Type.Size() == 4 && d.Type.Size() == 4 => (RotateLeft(64|32|16|8) x (Add32 <c.Type> c d))
+(RotateLeft(64|32|16|8) (RotateLeft(64|32|16|8) x c) d) && c.Type.Size() == 2 && d.Type.Size() == 2 => (RotateLeft(64|32|16|8) x (Add16 <c.Type> c d))
+(RotateLeft(64|32|16|8) (RotateLeft(64|32|16|8) x c) d) && c.Type.Size() == 1 && d.Type.Size() == 1 => (RotateLeft(64|32|16|8) x (Add8  <c.Type> c d))
diff --git a/src/cmd/compile/internal/ssa/_gen/genericOps.go b/src/cmd/compile/internal/ssa/_gen/genericOps.go
new file mode 100644
index 0000000..a4c8fc9
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/_gen/genericOps.go
@@ -0,0 +1,664 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+// Generic opcodes typically specify a width. The inputs and outputs
+// of that op are the given number of bits wide. There is no notion of
+// "sign", so Add32 can be used both for signed and unsigned 32-bit
+// addition.
+
+// Signed/unsigned is explicit with the extension ops
+// (SignExt*/ZeroExt*) and implicit as the arg to some opcodes
+// (e.g. the second argument to shifts is unsigned). If not mentioned,
+// all args take signed inputs, or don't care whether their inputs
+// are signed or unsigned.
+
+var genericOps = []opData{
+	// 2-input arithmetic
+	// Types must be consistent with Go typing. Add, for example, must take two values
+	// of the same type and produces that same type.
+	{name: "Add8", argLength: 2, commutative: true}, // arg0 + arg1
+	{name: "Add16", argLength: 2, commutative: true},
+	{name: "Add32", argLength: 2, commutative: true},
+	{name: "Add64", argLength: 2, commutative: true},
+	{name: "AddPtr", argLength: 2}, // For address calculations.  arg0 is a pointer and arg1 is an int.
+	{name: "Add32F", argLength: 2, commutative: true},
+	{name: "Add64F", argLength: 2, commutative: true},
+
+	{name: "Sub8", argLength: 2}, // arg0 - arg1
+	{name: "Sub16", argLength: 2},
+	{name: "Sub32", argLength: 2},
+	{name: "Sub64", argLength: 2},
+	{name: "SubPtr", argLength: 2},
+	{name: "Sub32F", argLength: 2},
+	{name: "Sub64F", argLength: 2},
+
+	{name: "Mul8", argLength: 2, commutative: true}, // arg0 * arg1
+	{name: "Mul16", argLength: 2, commutative: true},
+	{name: "Mul32", argLength: 2, commutative: true},
+	{name: "Mul64", argLength: 2, commutative: true},
+	{name: "Mul32F", argLength: 2, commutative: true},
+	{name: "Mul64F", argLength: 2, commutative: true},
+
+	{name: "Div32F", argLength: 2}, // arg0 / arg1
+	{name: "Div64F", argLength: 2},
+
+	{name: "Hmul32", argLength: 2, commutative: true},
+	{name: "Hmul32u", argLength: 2, commutative: true},
+	{name: "Hmul64", argLength: 2, commutative: true},
+	{name: "Hmul64u", argLength: 2, commutative: true},
+
+	{name: "Mul32uhilo", argLength: 2, typ: "(UInt32,UInt32)", commutative: true}, // arg0 * arg1, returns (hi, lo)
+	{name: "Mul64uhilo", argLength: 2, typ: "(UInt64,UInt64)", commutative: true}, // arg0 * arg1, returns (hi, lo)
+
+	{name: "Mul32uover", argLength: 2, typ: "(UInt32,Bool)", commutative: true}, // Let x = arg0*arg1 (full 32x32-> 64 unsigned multiply), returns (uint32(x), (uint32(x) != x))
+	{name: "Mul64uover", argLength: 2, typ: "(UInt64,Bool)", commutative: true}, // Let x = arg0*arg1 (full 64x64->128 unsigned multiply), returns (uint64(x), (uint64(x) != x))
+
+	// Weird special instructions for use in the strength reduction of divides.
+	// These ops compute unsigned (arg0 + arg1) / 2, correct to all
+	// 32/64 bits, even when the intermediate result of the add has 33/65 bits.
+	// These ops can assume arg0 >= arg1.
+	// Note: these ops aren't commutative!
+	{name: "Avg32u", argLength: 2, typ: "UInt32"}, // 32-bit platforms only
+	{name: "Avg64u", argLength: 2, typ: "UInt64"}, // 64-bit platforms only
+
+	// For Div16, Div32 and Div64, AuxInt non-zero means that the divisor has been proved to be not -1
+	// or that the dividend is not the most negative value.
+	{name: "Div8", argLength: 2},  // arg0 / arg1, signed
+	{name: "Div8u", argLength: 2}, // arg0 / arg1, unsigned
+	{name: "Div16", argLength: 2, aux: "Bool"},
+	{name: "Div16u", argLength: 2},
+	{name: "Div32", argLength: 2, aux: "Bool"},
+	{name: "Div32u", argLength: 2},
+	{name: "Div64", argLength: 2, aux: "Bool"},
+	{name: "Div64u", argLength: 2},
+	{name: "Div128u", argLength: 3}, // arg0:arg1 / arg2 (128-bit divided by 64-bit), returns (q, r)
+
+	// For Mod16, Mod32 and Mod64, AuxInt non-zero means that the divisor has been proved to be not -1.
+	{name: "Mod8", argLength: 2},  // arg0 % arg1, signed
+	{name: "Mod8u", argLength: 2}, // arg0 % arg1, unsigned
+	{name: "Mod16", argLength: 2, aux: "Bool"},
+	{name: "Mod16u", argLength: 2},
+	{name: "Mod32", argLength: 2, aux: "Bool"},
+	{name: "Mod32u", argLength: 2},
+	{name: "Mod64", argLength: 2, aux: "Bool"},
+	{name: "Mod64u", argLength: 2},
+
+	{name: "And8", argLength: 2, commutative: true}, // arg0 & arg1
+	{name: "And16", argLength: 2, commutative: true},
+	{name: "And32", argLength: 2, commutative: true},
+	{name: "And64", argLength: 2, commutative: true},
+
+	{name: "Or8", argLength: 2, commutative: true}, // arg0 | arg1
+	{name: "Or16", argLength: 2, commutative: true},
+	{name: "Or32", argLength: 2, commutative: true},
+	{name: "Or64", argLength: 2, commutative: true},
+
+	{name: "Xor8", argLength: 2, commutative: true}, // arg0 ^ arg1
+	{name: "Xor16", argLength: 2, commutative: true},
+	{name: "Xor32", argLength: 2, commutative: true},
+	{name: "Xor64", argLength: 2, commutative: true},
+
+	// For shifts, AxB means the shifted value has A bits and the shift amount has B bits.
+	// Shift amounts are considered unsigned.
+	// If arg1 is known to be nonnegative and less than the number of bits in arg0,
+	// then auxInt may be set to 1.
+	// This enables better code generation on some platforms.
+	{name: "Lsh8x8", argLength: 2, aux: "Bool"}, // arg0 << arg1
+	{name: "Lsh8x16", argLength: 2, aux: "Bool"},
+	{name: "Lsh8x32", argLength: 2, aux: "Bool"},
+	{name: "Lsh8x64", argLength: 2, aux: "Bool"},
+	{name: "Lsh16x8", argLength: 2, aux: "Bool"},
+	{name: "Lsh16x16", argLength: 2, aux: "Bool"},
+	{name: "Lsh16x32", argLength: 2, aux: "Bool"},
+	{name: "Lsh16x64", argLength: 2, aux: "Bool"},
+	{name: "Lsh32x8", argLength: 2, aux: "Bool"},
+	{name: "Lsh32x16", argLength: 2, aux: "Bool"},
+	{name: "Lsh32x32", argLength: 2, aux: "Bool"},
+	{name: "Lsh32x64", argLength: 2, aux: "Bool"},
+	{name: "Lsh64x8", argLength: 2, aux: "Bool"},
+	{name: "Lsh64x16", argLength: 2, aux: "Bool"},
+	{name: "Lsh64x32", argLength: 2, aux: "Bool"},
+	{name: "Lsh64x64", argLength: 2, aux: "Bool"},
+
+	{name: "Rsh8x8", argLength: 2, aux: "Bool"}, // arg0 >> arg1, signed
+	{name: "Rsh8x16", argLength: 2, aux: "Bool"},
+	{name: "Rsh8x32", argLength: 2, aux: "Bool"},
+	{name: "Rsh8x64", argLength: 2, aux: "Bool"},
+	{name: "Rsh16x8", argLength: 2, aux: "Bool"},
+	{name: "Rsh16x16", argLength: 2, aux: "Bool"},
+	{name: "Rsh16x32", argLength: 2, aux: "Bool"},
+	{name: "Rsh16x64", argLength: 2, aux: "Bool"},
+	{name: "Rsh32x8", argLength: 2, aux: "Bool"},
+	{name: "Rsh32x16", argLength: 2, aux: "Bool"},
+	{name: "Rsh32x32", argLength: 2, aux: "Bool"},
+	{name: "Rsh32x64", argLength: 2, aux: "Bool"},
+	{name: "Rsh64x8", argLength: 2, aux: "Bool"},
+	{name: "Rsh64x16", argLength: 2, aux: "Bool"},
+	{name: "Rsh64x32", argLength: 2, aux: "Bool"},
+	{name: "Rsh64x64", argLength: 2, aux: "Bool"},
+
+	{name: "Rsh8Ux8", argLength: 2, aux: "Bool"}, // arg0 >> arg1, unsigned
+	{name: "Rsh8Ux16", argLength: 2, aux: "Bool"},
+	{name: "Rsh8Ux32", argLength: 2, aux: "Bool"},
+	{name: "Rsh8Ux64", argLength: 2, aux: "Bool"},
+	{name: "Rsh16Ux8", argLength: 2, aux: "Bool"},
+	{name: "Rsh16Ux16", argLength: 2, aux: "Bool"},
+	{name: "Rsh16Ux32", argLength: 2, aux: "Bool"},
+	{name: "Rsh16Ux64", argLength: 2, aux: "Bool"},
+	{name: "Rsh32Ux8", argLength: 2, aux: "Bool"},
+	{name: "Rsh32Ux16", argLength: 2, aux: "Bool"},
+	{name: "Rsh32Ux32", argLength: 2, aux: "Bool"},
+	{name: "Rsh32Ux64", argLength: 2, aux: "Bool"},
+	{name: "Rsh64Ux8", argLength: 2, aux: "Bool"},
+	{name: "Rsh64Ux16", argLength: 2, aux: "Bool"},
+	{name: "Rsh64Ux32", argLength: 2, aux: "Bool"},
+	{name: "Rsh64Ux64", argLength: 2, aux: "Bool"},
+
+	// 2-input comparisons
+	{name: "Eq8", argLength: 2, commutative: true, typ: "Bool"}, // arg0 == arg1
+	{name: "Eq16", argLength: 2, commutative: true, typ: "Bool"},
+	{name: "Eq32", argLength: 2, commutative: true, typ: "Bool"},
+	{name: "Eq64", argLength: 2, commutative: true, typ: "Bool"},
+	{name: "EqPtr", argLength: 2, commutative: true, typ: "Bool"},
+	{name: "EqInter", argLength: 2, typ: "Bool"}, // arg0 or arg1 is nil; other cases handled by frontend
+	{name: "EqSlice", argLength: 2, typ: "Bool"}, // arg0 or arg1 is nil; other cases handled by frontend
+	{name: "Eq32F", argLength: 2, commutative: true, typ: "Bool"},
+	{name: "Eq64F", argLength: 2, commutative: true, typ: "Bool"},
+
+	{name: "Neq8", argLength: 2, commutative: true, typ: "Bool"}, // arg0 != arg1
+	{name: "Neq16", argLength: 2, commutative: true, typ: "Bool"},
+	{name: "Neq32", argLength: 2, commutative: true, typ: "Bool"},
+	{name: "Neq64", argLength: 2, commutative: true, typ: "Bool"},
+	{name: "NeqPtr", argLength: 2, commutative: true, typ: "Bool"},
+	{name: "NeqInter", argLength: 2, typ: "Bool"}, // arg0 or arg1 is nil; other cases handled by frontend
+	{name: "NeqSlice", argLength: 2, typ: "Bool"}, // arg0 or arg1 is nil; other cases handled by frontend
+	{name: "Neq32F", argLength: 2, commutative: true, typ: "Bool"},
+	{name: "Neq64F", argLength: 2, commutative: true, typ: "Bool"},
+
+	{name: "Less8", argLength: 2, typ: "Bool"},  // arg0 < arg1, signed
+	{name: "Less8U", argLength: 2, typ: "Bool"}, // arg0 < arg1, unsigned
+	{name: "Less16", argLength: 2, typ: "Bool"},
+	{name: "Less16U", argLength: 2, typ: "Bool"},
+	{name: "Less32", argLength: 2, typ: "Bool"},
+	{name: "Less32U", argLength: 2, typ: "Bool"},
+	{name: "Less64", argLength: 2, typ: "Bool"},
+	{name: "Less64U", argLength: 2, typ: "Bool"},
+	{name: "Less32F", argLength: 2, typ: "Bool"},
+	{name: "Less64F", argLength: 2, typ: "Bool"},
+
+	{name: "Leq8", argLength: 2, typ: "Bool"},  // arg0 <= arg1, signed
+	{name: "Leq8U", argLength: 2, typ: "Bool"}, // arg0 <= arg1, unsigned
+	{name: "Leq16", argLength: 2, typ: "Bool"},
+	{name: "Leq16U", argLength: 2, typ: "Bool"},
+	{name: "Leq32", argLength: 2, typ: "Bool"},
+	{name: "Leq32U", argLength: 2, typ: "Bool"},
+	{name: "Leq64", argLength: 2, typ: "Bool"},
+	{name: "Leq64U", argLength: 2, typ: "Bool"},
+	{name: "Leq32F", argLength: 2, typ: "Bool"},
+	{name: "Leq64F", argLength: 2, typ: "Bool"},
+
+	// the type of a CondSelect is the same as the type of its first
+	// two arguments, which should be register-width scalars; the third
+	// argument should be a boolean
+	{name: "CondSelect", argLength: 3}, // arg2 ? arg0 : arg1
+
+	// boolean ops
+	{name: "AndB", argLength: 2, commutative: true, typ: "Bool"}, // arg0 && arg1 (not shortcircuited)
+	{name: "OrB", argLength: 2, commutative: true, typ: "Bool"},  // arg0 || arg1 (not shortcircuited)
+	{name: "EqB", argLength: 2, commutative: true, typ: "Bool"},  // arg0 == arg1
+	{name: "NeqB", argLength: 2, commutative: true, typ: "Bool"}, // arg0 != arg1
+	{name: "Not", argLength: 1, typ: "Bool"},                     // !arg0, boolean
+
+	// 1-input ops
+	{name: "Neg8", argLength: 1}, // -arg0
+	{name: "Neg16", argLength: 1},
+	{name: "Neg32", argLength: 1},
+	{name: "Neg64", argLength: 1},
+	{name: "Neg32F", argLength: 1},
+	{name: "Neg64F", argLength: 1},
+
+	{name: "Com8", argLength: 1}, // ^arg0
+	{name: "Com16", argLength: 1},
+	{name: "Com32", argLength: 1},
+	{name: "Com64", argLength: 1},
+
+	{name: "Ctz8", argLength: 1},         // Count trailing (low order) zeroes (returns 0-8)
+	{name: "Ctz16", argLength: 1},        // Count trailing (low order) zeroes (returns 0-16)
+	{name: "Ctz32", argLength: 1},        // Count trailing (low order) zeroes (returns 0-32)
+	{name: "Ctz64", argLength: 1},        // Count trailing (low order) zeroes (returns 0-64)
+	{name: "Ctz8NonZero", argLength: 1},  // same as above, but arg[0] known to be non-zero, returns 0-7
+	{name: "Ctz16NonZero", argLength: 1}, // same as above, but arg[0] known to be non-zero, returns 0-15
+	{name: "Ctz32NonZero", argLength: 1}, // same as above, but arg[0] known to be non-zero, returns 0-31
+	{name: "Ctz64NonZero", argLength: 1}, // same as above, but arg[0] known to be non-zero, returns 0-63
+	{name: "BitLen8", argLength: 1},      // Number of bits in arg[0] (returns 0-8)
+	{name: "BitLen16", argLength: 1},     // Number of bits in arg[0] (returns 0-16)
+	{name: "BitLen32", argLength: 1},     // Number of bits in arg[0] (returns 0-32)
+	{name: "BitLen64", argLength: 1},     // Number of bits in arg[0] (returns 0-64)
+
+	{name: "Bswap32", argLength: 1}, // Swap bytes
+	{name: "Bswap64", argLength: 1}, // Swap bytes
+
+	{name: "BitRev8", argLength: 1},  // Reverse the bits in arg[0]
+	{name: "BitRev16", argLength: 1}, // Reverse the bits in arg[0]
+	{name: "BitRev32", argLength: 1}, // Reverse the bits in arg[0]
+	{name: "BitRev64", argLength: 1}, // Reverse the bits in arg[0]
+
+	{name: "PopCount8", argLength: 1},  // Count bits in arg[0]
+	{name: "PopCount16", argLength: 1}, // Count bits in arg[0]
+	{name: "PopCount32", argLength: 1}, // Count bits in arg[0]
+	{name: "PopCount64", argLength: 1}, // Count bits in arg[0]
+
+	// RotateLeftX instructions rotate the X bits of arg[0] to the left
+	// by the low lg_2(X) bits of arg[1], interpreted as an unsigned value.
+	// Note that this works out regardless of the bit width or signedness of
+	// arg[1]. In particular, RotateLeft by x is the same as RotateRight by -x.
+	{name: "RotateLeft64", argLength: 2},
+	{name: "RotateLeft32", argLength: 2},
+	{name: "RotateLeft16", argLength: 2},
+	{name: "RotateLeft8", argLength: 2},
+
+	// Square root.
+	// Special cases:
+	//   +∞  → +∞
+	//   ±0  → ±0 (sign preserved)
+	//   x<0 → NaN
+	//   NaN → NaN
+	{name: "Sqrt", argLength: 1},   // √arg0 (floating point, double precision)
+	{name: "Sqrt32", argLength: 1}, // √arg0 (floating point, single precision)
+
+	// Round to integer, float64 only.
+	// Special cases:
+	//   ±∞  → ±∞ (sign preserved)
+	//   ±0  → ±0 (sign preserved)
+	//   NaN → NaN
+	{name: "Floor", argLength: 1},       // round arg0 toward -∞
+	{name: "Ceil", argLength: 1},        // round arg0 toward +∞
+	{name: "Trunc", argLength: 1},       // round arg0 toward 0
+	{name: "Round", argLength: 1},       // round arg0 to nearest, ties away from 0
+	{name: "RoundToEven", argLength: 1}, // round arg0 to nearest, ties to even
+
+	// Modify the sign bit
+	{name: "Abs", argLength: 1},      // absolute value arg0
+	{name: "Copysign", argLength: 2}, // copy sign from arg0 to arg1
+
+	// 3-input opcode.
+	// Fused-multiply-add, float64 only.
+	// When a*b+c is exactly zero (before rounding), then the result is +0 or -0.
+	// The 0's sign is determined according to the standard rules for the
+	// addition (-0 if both a*b and c are -0, +0 otherwise).
+	//
+	// Otherwise, when a*b+c rounds to zero, then the resulting 0's sign is
+	// determined by the sign of the exact result a*b+c.
+	// See section 6.3 in ieee754.
+	//
+	// When the multiply is an infinity times a zero, the result is NaN.
+	// See section 7.2 in ieee754.
+	{name: "FMA", argLength: 3}, // compute (a*b)+c without intermediate rounding
+
+	// Data movement. Max argument length for Phi is indefinite.
+	{name: "Phi", argLength: -1, zeroWidth: true}, // select an argument based on which predecessor block we came from
+	{name: "Copy", argLength: 1},                  // output = arg0
+	// Convert converts between pointers and integers.
+	// We have a special op for this so as to not confuse GC
+	// (particularly stack maps).  It takes a memory arg so it
+	// gets correctly ordered with respect to GC safepoints.
+	// It gets compiled to nothing, so its result must in the same
+	// register as its argument. regalloc knows it can use any
+	// allocatable integer register for OpConvert.
+	// arg0=ptr/int arg1=mem, output=int/ptr
+	{name: "Convert", argLength: 2, zeroWidth: true, resultInArg0: true},
+
+	// constants. Constant values are stored in the aux or
+	// auxint fields.
+	{name: "ConstBool", aux: "Bool"},     // auxint is 0 for false and 1 for true
+	{name: "ConstString", aux: "String"}, // value is aux.(string)
+	{name: "ConstNil", typ: "BytePtr"},   // nil pointer
+	{name: "Const8", aux: "Int8"},        // auxint is sign-extended 8 bits
+	{name: "Const16", aux: "Int16"},      // auxint is sign-extended 16 bits
+	{name: "Const32", aux: "Int32"},      // auxint is sign-extended 32 bits
+	// Note: ConstX are sign-extended even when the type of the value is unsigned.
+	// For instance, uint8(0xaa) is stored as auxint=0xffffffffffffffaa.
+	{name: "Const64", aux: "Int64"}, // value is auxint
+	// Note: for both Const32F and Const64F, we disallow encoding NaNs.
+	// Signaling NaNs are tricky because if you do anything with them, they become quiet.
+	// Particularly, converting a 32 bit sNaN to 64 bit and back converts it to a qNaN.
+	// See issue 36399 and 36400.
+	// Encodings of +inf, -inf, and -0 are fine.
+	{name: "Const32F", aux: "Float32"}, // value is math.Float64frombits(uint64(auxint)) and is exactly representable as float 32
+	{name: "Const64F", aux: "Float64"}, // value is math.Float64frombits(uint64(auxint))
+	{name: "ConstInterface"},           // nil interface
+	{name: "ConstSlice"},               // nil slice
+
+	// Constant-like things
+	{name: "InitMem", zeroWidth: true},                               // memory input to the function.
+	{name: "Arg", aux: "SymOff", symEffect: "Read", zeroWidth: true}, // argument to the function.  aux=GCNode of arg, off = offset in that arg.
+
+	// Like Arg, these are generic ops that survive lowering. AuxInt is a register index, and the actual output register for each index is defined by the architecture.
+	// AuxInt = integer argument index (not a register number). ABI-specified spill loc obtained from function
+	{name: "ArgIntReg", aux: "NameOffsetInt8", zeroWidth: true},   // argument to the function in an int reg.
+	{name: "ArgFloatReg", aux: "NameOffsetInt8", zeroWidth: true}, // argument to the function in a float reg.
+
+	// The address of a variable.  arg0 is the base pointer.
+	// If the variable is a global, the base pointer will be SB and
+	// the Aux field will be a *obj.LSym.
+	// If the variable is a local, the base pointer will be SP and
+	// the Aux field will be a *gc.Node.
+	{name: "Addr", argLength: 1, aux: "Sym", symEffect: "Addr"},      // Address of a variable.  Arg0=SB.  Aux identifies the variable.
+	{name: "LocalAddr", argLength: 2, aux: "Sym", symEffect: "Addr"}, // Address of a variable.  Arg0=SP. Arg1=mem. Aux identifies the variable.
+
+	{name: "SP", zeroWidth: true},                 // stack pointer
+	{name: "SB", typ: "Uintptr", zeroWidth: true}, // static base pointer (a.k.a. globals pointer)
+	{name: "Invalid"},                             // unused value
+
+	// Memory operations
+	{name: "Load", argLength: 2},                          // Load from arg0.  arg1=memory
+	{name: "Dereference", argLength: 2},                   // Load from arg0.  arg1=memory.  Helper op for arg/result passing, result is an otherwise not-SSA-able "value".
+	{name: "Store", argLength: 3, typ: "Mem", aux: "Typ"}, // Store arg1 to arg0.  arg2=memory, aux=type.  Returns memory.
+	// Normally we require that the source and destination of Move do not overlap.
+	// There is an exception when we know all the loads will happen before all
+	// the stores. In that case, overlap is ok. See
+	// memmove inlining in generic.rules. When inlineablememmovesize (in ../rewrite.go)
+	// returns true, we must do all loads before all stores, when lowering Move.
+	// The type of Move is used for the write barrier pass to insert write barriers
+	// and for alignment on some architectures.
+	// For pointerless types, it is possible for the type to be inaccurate.
+	// For type alignment and pointer information, use the type in Aux;
+	// for type size, use the size in AuxInt.
+	// The "inline runtime.memmove" rewrite rule generates Moves with inaccurate types,
+	// such as type byte instead of the more accurate type [8]byte.
+	{name: "Move", argLength: 3, typ: "Mem", aux: "TypSize"}, // arg0=destptr, arg1=srcptr, arg2=mem, auxint=size, aux=type.  Returns memory.
+	{name: "Zero", argLength: 2, typ: "Mem", aux: "TypSize"}, // arg0=destptr, arg1=mem, auxint=size, aux=type. Returns memory.
+
+	// Memory operations with write barriers.
+	// Expand to runtime calls. Write barrier will be removed if write on stack.
+	{name: "StoreWB", argLength: 3, typ: "Mem", aux: "Typ"},    // Store arg1 to arg0. arg2=memory, aux=type.  Returns memory.
+	{name: "MoveWB", argLength: 3, typ: "Mem", aux: "TypSize"}, // arg0=destptr, arg1=srcptr, arg2=mem, auxint=size, aux=type.  Returns memory.
+	{name: "ZeroWB", argLength: 2, typ: "Mem", aux: "TypSize"}, // arg0=destptr, arg1=mem, auxint=size, aux=type. Returns memory.
+
+	// WB invokes runtime.gcWriteBarrier. This is not a normal
+	// call: it takes arguments in registers, doesn't clobber
+	// general-purpose registers (the exact clobber set is
+	// arch-dependent), and is not a safe-point.
+	{name: "WB", argLength: 3, typ: "Mem", aux: "Sym", symEffect: "None"}, // arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
+
+	{name: "HasCPUFeature", argLength: 0, typ: "bool", aux: "Sym", symEffect: "None"}, // aux=place that this feature flag can be loaded from
+
+	// PanicBounds and PanicExtend generate a runtime panic.
+	// Their arguments provide index values to use in panic messages.
+	// Both PanicBounds and PanicExtend have an AuxInt value from the BoundsKind type (in ../op.go).
+	// PanicBounds' index is int sized.
+	// PanicExtend's index is int64 sized. (PanicExtend is only used on 32-bit archs.)
+	{name: "PanicBounds", argLength: 3, aux: "Int64", typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory.
+	{name: "PanicExtend", argLength: 4, aux: "Int64", typ: "Mem", call: true}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory.
+
+	// Function calls. Arguments to the call have already been written to the stack.
+	// Return values appear on the stack. The method receiver, if any, is treated
+	// as a phantom first argument.
+	// TODO(josharian): ClosureCall and InterCall should have Int32 aux
+	// to match StaticCall's 32 bit arg size limit.
+	// TODO(drchase,josharian): could the arg size limit be bundled into the rules for CallOff?
+
+	// Before lowering, LECalls receive their fixed inputs (first), memory (last),
+	// and a variable number of input values in the middle.
+	// They produce a variable number of result values.
+	// These values are not necessarily "SSA-able"; they can be too large,
+	// but in that case inputs are loaded immediately before with OpDereference,
+	// and outputs are stored immediately with OpStore.
+	//
+	// After call expansion, Calls have the same fixed-middle-memory arrangement of inputs,
+	// with the difference that the "middle" is only the register-resident inputs,
+	// and the non-register inputs are instead stored at ABI-defined offsets from SP
+	// (and the stores thread through the memory that is ultimately an input to the call).
+	// Outputs follow a similar pattern; register-resident outputs are the leading elements
+	// of a Result-typed output, with memory last, and any memory-resident outputs have been
+	// stored to ABI-defined locations.  Each non-memory input or output fits in a register.
+	//
+	// Subsequent architecture-specific lowering only changes the opcode.
+
+	{name: "ClosureCall", argLength: -1, aux: "CallOff", call: true}, // arg0=code pointer, arg1=context ptr, arg2..argN-1 are register inputs, argN=memory.  auxint=arg size.  Returns Result of register results, plus memory.
+	{name: "StaticCall", argLength: -1, aux: "CallOff", call: true},  // call function aux.(*obj.LSym), arg0..argN-1 are register inputs, argN=memory.  auxint=arg size.  Returns Result of register results, plus memory.
+	{name: "InterCall", argLength: -1, aux: "CallOff", call: true},   // interface call.  arg0=code pointer, arg1..argN-1 are register inputs, argN=memory, auxint=arg size.  Returns Result of register results, plus memory.
+	{name: "TailCall", argLength: -1, aux: "CallOff", call: true},    // tail call function aux.(*obj.LSym), arg0..argN-1 are register inputs, argN=memory.  auxint=arg size.  Returns Result of register results, plus memory.
+
+	{name: "ClosureLECall", argLength: -1, aux: "CallOff", call: true}, // late-expanded closure call. arg0=code pointer, arg1=context ptr,  arg2..argN-1 are inputs, argN is mem. auxint = arg size. Result is tuple of result(s), plus mem.
+	{name: "StaticLECall", argLength: -1, aux: "CallOff", call: true},  // late-expanded static call function aux.(*ssa.AuxCall.Fn). arg0..argN-1 are inputs, argN is mem. auxint = arg size. Result is tuple of result(s), plus mem.
+	{name: "InterLECall", argLength: -1, aux: "CallOff", call: true},   // late-expanded interface call. arg0=code pointer, arg1..argN-1 are inputs, argN is mem. auxint = arg size. Result is tuple of result(s), plus mem.
+	{name: "TailLECall", argLength: -1, aux: "CallOff", call: true},    // late-expanded static tail call function aux.(*ssa.AuxCall.Fn). arg0..argN-1 are inputs, argN is mem. auxint = arg size. Result is tuple of result(s), plus mem.
+
+	// Conversions: signed extensions, zero (unsigned) extensions, truncations
+	{name: "SignExt8to16", argLength: 1, typ: "Int16"},
+	{name: "SignExt8to32", argLength: 1, typ: "Int32"},
+	{name: "SignExt8to64", argLength: 1, typ: "Int64"},
+	{name: "SignExt16to32", argLength: 1, typ: "Int32"},
+	{name: "SignExt16to64", argLength: 1, typ: "Int64"},
+	{name: "SignExt32to64", argLength: 1, typ: "Int64"},
+	{name: "ZeroExt8to16", argLength: 1, typ: "UInt16"},
+	{name: "ZeroExt8to32", argLength: 1, typ: "UInt32"},
+	{name: "ZeroExt8to64", argLength: 1, typ: "UInt64"},
+	{name: "ZeroExt16to32", argLength: 1, typ: "UInt32"},
+	{name: "ZeroExt16to64", argLength: 1, typ: "UInt64"},
+	{name: "ZeroExt32to64", argLength: 1, typ: "UInt64"},
+	{name: "Trunc16to8", argLength: 1},
+	{name: "Trunc32to8", argLength: 1},
+	{name: "Trunc32to16", argLength: 1},
+	{name: "Trunc64to8", argLength: 1},
+	{name: "Trunc64to16", argLength: 1},
+	{name: "Trunc64to32", argLength: 1},
+
+	{name: "Cvt32to32F", argLength: 1},
+	{name: "Cvt32to64F", argLength: 1},
+	{name: "Cvt64to32F", argLength: 1},
+	{name: "Cvt64to64F", argLength: 1},
+	{name: "Cvt32Fto32", argLength: 1},
+	{name: "Cvt32Fto64", argLength: 1},
+	{name: "Cvt64Fto32", argLength: 1},
+	{name: "Cvt64Fto64", argLength: 1},
+	{name: "Cvt32Fto64F", argLength: 1},
+	{name: "Cvt64Fto32F", argLength: 1},
+	{name: "CvtBoolToUint8", argLength: 1},
+
+	// Force rounding to precision of type.
+	{name: "Round32F", argLength: 1},
+	{name: "Round64F", argLength: 1},
+
+	// Automatically inserted safety checks
+	{name: "IsNonNil", argLength: 1, typ: "Bool"},        // arg0 != nil
+	{name: "IsInBounds", argLength: 2, typ: "Bool"},      // 0 <= arg0 < arg1. arg1 is guaranteed >= 0.
+	{name: "IsSliceInBounds", argLength: 2, typ: "Bool"}, // 0 <= arg0 <= arg1. arg1 is guaranteed >= 0.
+	{name: "NilCheck", argLength: 2, typ: "Void"},        // arg0=ptr, arg1=mem. Panics if arg0 is nil. Returns void.
+
+	// Pseudo-ops
+	{name: "GetG", argLength: 1, zeroWidth: true}, // runtime.getg() (read g pointer). arg0=mem
+	{name: "GetClosurePtr"},                       // get closure pointer from dedicated register
+	{name: "GetCallerPC"},                         // for getcallerpc intrinsic
+	{name: "GetCallerSP"},                         // for getcallersp intrinsic
+
+	// Indexing operations
+	{name: "PtrIndex", argLength: 2},             // arg0=ptr, arg1=index. Computes ptr+sizeof(*v.type)*index, where index is extended to ptrwidth type
+	{name: "OffPtr", argLength: 1, aux: "Int64"}, // arg0 + auxint (arg0 and result are pointers)
+
+	// Slices
+	{name: "SliceMake", argLength: 3},                // arg0=ptr, arg1=len, arg2=cap
+	{name: "SlicePtr", argLength: 1, typ: "BytePtr"}, // ptr(arg0)
+	{name: "SliceLen", argLength: 1},                 // len(arg0)
+	{name: "SliceCap", argLength: 1},                 // cap(arg0)
+	// SlicePtrUnchecked, like SlicePtr, extracts the pointer from a slice.
+	// SlicePtr values are assumed non-nil, because they are guarded by bounds checks.
+	// SlicePtrUnchecked values can be nil.
+	{name: "SlicePtrUnchecked", argLength: 1},
+
+	// Complex (part/whole)
+	{name: "ComplexMake", argLength: 2}, // arg0=real, arg1=imag
+	{name: "ComplexReal", argLength: 1}, // real(arg0)
+	{name: "ComplexImag", argLength: 1}, // imag(arg0)
+
+	// Strings
+	{name: "StringMake", argLength: 2},                // arg0=ptr, arg1=len
+	{name: "StringPtr", argLength: 1, typ: "BytePtr"}, // ptr(arg0)
+	{name: "StringLen", argLength: 1, typ: "Int"},     // len(arg0)
+
+	// Interfaces
+	{name: "IMake", argLength: 2},                // arg0=itab, arg1=data
+	{name: "ITab", argLength: 1, typ: "Uintptr"}, // arg0=interface, returns itable field
+	{name: "IData", argLength: 1},                // arg0=interface, returns data field
+
+	// Structs
+	{name: "StructMake0"},                              // Returns struct with 0 fields.
+	{name: "StructMake1", argLength: 1},                // arg0=field0.  Returns struct.
+	{name: "StructMake2", argLength: 2},                // arg0,arg1=field0,field1.  Returns struct.
+	{name: "StructMake3", argLength: 3},                // arg0..2=field0..2.  Returns struct.
+	{name: "StructMake4", argLength: 4},                // arg0..3=field0..3.  Returns struct.
+	{name: "StructSelect", argLength: 1, aux: "Int64"}, // arg0=struct, auxint=field index.  Returns the auxint'th field.
+
+	// Arrays
+	{name: "ArrayMake0"},                              // Returns array with 0 elements
+	{name: "ArrayMake1", argLength: 1},                // Returns array with 1 element
+	{name: "ArraySelect", argLength: 1, aux: "Int64"}, // arg0=array, auxint=index. Returns a[i].
+
+	// Spill&restore ops for the register allocator. These are
+	// semantically identical to OpCopy; they do not take/return
+	// stores like regular memory ops do. We can get away without memory
+	// args because we know there is no aliasing of spill slots on the stack.
+	{name: "StoreReg", argLength: 1},
+	{name: "LoadReg", argLength: 1},
+
+	// Used during ssa construction. Like Copy, but the arg has not been specified yet.
+	{name: "FwdRef", aux: "Sym", symEffect: "None"},
+
+	// Unknown value. Used for Values whose values don't matter because they are dead code.
+	{name: "Unknown"},
+
+	{name: "VarDef", argLength: 1, aux: "Sym", typ: "Mem", symEffect: "None", zeroWidth: true}, // aux is a *gc.Node of a variable that is about to be initialized.  arg0=mem, returns mem
+	// TODO: what's the difference between VarLive and KeepAlive?
+	{name: "VarLive", argLength: 1, aux: "Sym", symEffect: "Read", zeroWidth: true}, // aux is a *gc.Node of a variable that must be kept live.  arg0=mem, returns mem
+	{name: "KeepAlive", argLength: 2, typ: "Mem", zeroWidth: true},                  // arg[0] is a value that must be kept alive until this mark.  arg[1]=mem, returns mem
+
+	// InlMark marks the start of an inlined function body. Its AuxInt field
+	// distinguishes which entry in the local inline tree it is marking.
+	{name: "InlMark", argLength: 1, aux: "Int32", typ: "Void"}, // arg[0]=mem, returns void.
+
+	// Ops for breaking 64-bit operations on 32-bit architectures
+	{name: "Int64Make", argLength: 2, typ: "UInt64"}, // arg0=hi, arg1=lo
+	{name: "Int64Hi", argLength: 1, typ: "UInt32"},   // high 32-bit of arg0
+	{name: "Int64Lo", argLength: 1, typ: "UInt32"},   // low 32-bit of arg0
+
+	{name: "Add32carry", argLength: 2, commutative: true, typ: "(UInt32,Flags)"}, // arg0 + arg1, returns (value, carry)
+	{name: "Add32withcarry", argLength: 3, commutative: true},                    // arg0 + arg1 + arg2, arg2=carry (0 or 1)
+
+	{name: "Sub32carry", argLength: 2, typ: "(UInt32,Flags)"}, // arg0 - arg1, returns (value, carry)
+	{name: "Sub32withcarry", argLength: 3},                    // arg0 - arg1 - arg2, arg2=carry (0 or 1)
+
+	{name: "Add64carry", argLength: 3, commutative: true, typ: "(UInt64,UInt64)"}, // arg0 + arg1 + arg2, arg2 must be 0 or 1. returns (value, value>>64)
+	{name: "Sub64borrow", argLength: 3, typ: "(UInt64,UInt64)"},                   // arg0 - (arg1 + arg2), arg2 must be 0 or 1. returns (value, value>>64&1)
+
+	{name: "Signmask", argLength: 1, typ: "Int32"},  // 0 if arg0 >= 0, -1 if arg0 < 0
+	{name: "Zeromask", argLength: 1, typ: "UInt32"}, // 0 if arg0 == 0, 0xffffffff if arg0 != 0
+	{name: "Slicemask", argLength: 1},               // 0 if arg0 == 0, -1 if arg0 > 0, undef if arg0<0. Type is native int size.
+
+	{name: "SpectreIndex", argLength: 2},      // arg0 if 0 <= arg0 < arg1, 0 otherwise. Type is native int size.
+	{name: "SpectreSliceIndex", argLength: 2}, // arg0 if 0 <= arg0 <= arg1, 0 otherwise. Type is native int size.
+
+	{name: "Cvt32Uto32F", argLength: 1}, // uint32 -> float32, only used on 32-bit arch
+	{name: "Cvt32Uto64F", argLength: 1}, // uint32 -> float64, only used on 32-bit arch
+	{name: "Cvt32Fto32U", argLength: 1}, // float32 -> uint32, only used on 32-bit arch
+	{name: "Cvt64Fto32U", argLength: 1}, // float64 -> uint32, only used on 32-bit arch
+	{name: "Cvt64Uto32F", argLength: 1}, // uint64 -> float32, only used on archs that has the instruction
+	{name: "Cvt64Uto64F", argLength: 1}, // uint64 -> float64, only used on archs that has the instruction
+	{name: "Cvt32Fto64U", argLength: 1}, // float32 -> uint64, only used on archs that has the instruction
+	{name: "Cvt64Fto64U", argLength: 1}, // float64 -> uint64, only used on archs that has the instruction
+
+	// pseudo-ops for breaking Tuple
+	{name: "Select0", argLength: 1, zeroWidth: true},  // the first component of a tuple
+	{name: "Select1", argLength: 1, zeroWidth: true},  // the second component of a tuple
+	{name: "SelectN", argLength: 1, aux: "Int64"},     // arg0=result, auxint=field index.  Returns the auxint'th member.
+	{name: "SelectNAddr", argLength: 1, aux: "Int64"}, // arg0=result, auxint=field index.  Returns the address of auxint'th member. Used for un-SSA-able result types.
+	{name: "MakeResult", argLength: -1},               // arg0 .. are components of a "Result" (like the result from a Call). The last arg should be memory (like the result from a call).
+
+	// Atomic operations used for semantically inlining sync/atomic and
+	// runtime/internal/atomic. Atomic loads return a new memory so that
+	// the loads are properly ordered with respect to other loads and
+	// stores.
+	{name: "AtomicLoad8", argLength: 2, typ: "(UInt8,Mem)"},                                    // Load from arg0.  arg1=memory.  Returns loaded value and new memory.
+	{name: "AtomicLoad32", argLength: 2, typ: "(UInt32,Mem)"},                                  // Load from arg0.  arg1=memory.  Returns loaded value and new memory.
+	{name: "AtomicLoad64", argLength: 2, typ: "(UInt64,Mem)"},                                  // Load from arg0.  arg1=memory.  Returns loaded value and new memory.
+	{name: "AtomicLoadPtr", argLength: 2, typ: "(BytePtr,Mem)"},                                // Load from arg0.  arg1=memory.  Returns loaded value and new memory.
+	{name: "AtomicLoadAcq32", argLength: 2, typ: "(UInt32,Mem)"},                               // Load from arg0.  arg1=memory.  Lock acquisition, returns loaded value and new memory.
+	{name: "AtomicLoadAcq64", argLength: 2, typ: "(UInt64,Mem)"},                               // Load from arg0.  arg1=memory.  Lock acquisition, returns loaded value and new memory.
+	{name: "AtomicStore8", argLength: 3, typ: "Mem", hasSideEffects: true},                     // Store arg1 to *arg0.  arg2=memory.  Returns memory.
+	{name: "AtomicStore32", argLength: 3, typ: "Mem", hasSideEffects: true},                    // Store arg1 to *arg0.  arg2=memory.  Returns memory.
+	{name: "AtomicStore64", argLength: 3, typ: "Mem", hasSideEffects: true},                    // Store arg1 to *arg0.  arg2=memory.  Returns memory.
+	{name: "AtomicStorePtrNoWB", argLength: 3, typ: "Mem", hasSideEffects: true},               // Store arg1 to *arg0.  arg2=memory.  Returns memory.
+	{name: "AtomicStoreRel32", argLength: 3, typ: "Mem", hasSideEffects: true},                 // Store arg1 to *arg0.  arg2=memory.  Lock release, returns memory.
+	{name: "AtomicStoreRel64", argLength: 3, typ: "Mem", hasSideEffects: true},                 // Store arg1 to *arg0.  arg2=memory.  Lock release, returns memory.
+	{name: "AtomicExchange32", argLength: 3, typ: "(UInt32,Mem)", hasSideEffects: true},        // Store arg1 to *arg0.  arg2=memory.  Returns old contents of *arg0 and new memory.
+	{name: "AtomicExchange64", argLength: 3, typ: "(UInt64,Mem)", hasSideEffects: true},        // Store arg1 to *arg0.  arg2=memory.  Returns old contents of *arg0 and new memory.
+	{name: "AtomicAdd32", argLength: 3, typ: "(UInt32,Mem)", hasSideEffects: true},             // Do *arg0 += arg1.  arg2=memory.  Returns sum and new memory.
+	{name: "AtomicAdd64", argLength: 3, typ: "(UInt64,Mem)", hasSideEffects: true},             // Do *arg0 += arg1.  arg2=memory.  Returns sum and new memory.
+	{name: "AtomicCompareAndSwap32", argLength: 4, typ: "(Bool,Mem)", hasSideEffects: true},    // if *arg0==arg1, then set *arg0=arg2.  Returns true if store happens and new memory.
+	{name: "AtomicCompareAndSwap64", argLength: 4, typ: "(Bool,Mem)", hasSideEffects: true},    // if *arg0==arg1, then set *arg0=arg2.  Returns true if store happens and new memory.
+	{name: "AtomicCompareAndSwapRel32", argLength: 4, typ: "(Bool,Mem)", hasSideEffects: true}, // if *arg0==arg1, then set *arg0=arg2.  Lock release, reports whether store happens and new memory.
+	{name: "AtomicAnd8", argLength: 3, typ: "Mem", hasSideEffects: true},                       // *arg0 &= arg1.  arg2=memory.  Returns memory.
+	{name: "AtomicAnd32", argLength: 3, typ: "Mem", hasSideEffects: true},                      // *arg0 &= arg1.  arg2=memory.  Returns memory.
+	{name: "AtomicOr8", argLength: 3, typ: "Mem", hasSideEffects: true},                        // *arg0 |= arg1.  arg2=memory.  Returns memory.
+	{name: "AtomicOr32", argLength: 3, typ: "Mem", hasSideEffects: true},                       // *arg0 |= arg1.  arg2=memory.  Returns memory.
+
+	// Atomic operation variants
+	// These variants have the same semantics as above atomic operations.
+	// But they are used for generating more efficient code on certain modern machines, with run-time CPU feature detection.
+	// Currently, they are used on ARM64 only.
+	{name: "AtomicAdd32Variant", argLength: 3, typ: "(UInt32,Mem)", hasSideEffects: true},          // Do *arg0 += arg1.  arg2=memory.  Returns sum and new memory.
+	{name: "AtomicAdd64Variant", argLength: 3, typ: "(UInt64,Mem)", hasSideEffects: true},          // Do *arg0 += arg1.  arg2=memory.  Returns sum and new memory.
+	{name: "AtomicExchange32Variant", argLength: 3, typ: "(UInt32,Mem)", hasSideEffects: true},     // Store arg1 to *arg0.  arg2=memory.  Returns old contents of *arg0 and new memory.
+	{name: "AtomicExchange64Variant", argLength: 3, typ: "(UInt64,Mem)", hasSideEffects: true},     // Store arg1 to *arg0.  arg2=memory.  Returns old contents of *arg0 and new memory.
+	{name: "AtomicCompareAndSwap32Variant", argLength: 4, typ: "(Bool,Mem)", hasSideEffects: true}, // if *arg0==arg1, then set *arg0=arg2.  Returns true if store happens and new memory.
+	{name: "AtomicCompareAndSwap64Variant", argLength: 4, typ: "(Bool,Mem)", hasSideEffects: true}, // if *arg0==arg1, then set *arg0=arg2.  Returns true if store happens and new memory.
+	{name: "AtomicAnd8Variant", argLength: 3, typ: "Mem", hasSideEffects: true},                    // *arg0 &= arg1.  arg2=memory.  Returns memory.
+	{name: "AtomicAnd32Variant", argLength: 3, typ: "Mem", hasSideEffects: true},                   // *arg0 &= arg1.  arg2=memory.  Returns memory.
+	{name: "AtomicOr8Variant", argLength: 3, typ: "Mem", hasSideEffects: true},                     // *arg0 |= arg1.  arg2=memory.  Returns memory.
+	{name: "AtomicOr32Variant", argLength: 3, typ: "Mem", hasSideEffects: true},                    // *arg0 |= arg1.  arg2=memory.  Returns memory.
+
+	// Publication barrier
+	{name: "PubBarrier", argLength: 1, hasSideEffects: true}, // Do data barrier. arg0=memory.
+
+	// Clobber experiment op
+	{name: "Clobber", argLength: 0, typ: "Void", aux: "SymOff", symEffect: "None"}, // write an invalid pointer value to the given pointer slot of a stack variable
+	{name: "ClobberReg", argLength: 0, typ: "Void"},                                // clobber a register
+
+	// Prefetch instruction
+	{name: "PrefetchCache", argLength: 2, hasSideEffects: true},         // Do prefetch arg0 to cache. arg0=addr, arg1=memory.
+	{name: "PrefetchCacheStreamed", argLength: 2, hasSideEffects: true}, // Do non-temporal or streamed prefetch arg0 to cache. arg0=addr, arg1=memory.
+}
+
+//     kind          controls        successors   implicit exit
+//   ----------------------------------------------------------
+//     Exit      [return mem]                []             yes
+//      Ret      [return mem]                []             yes
+//   RetJmp      [return mem]                []             yes
+//    Plain                []            [next]
+//       If   [boolean Value]      [then, else]
+//    First                []   [always, never]
+
+var genericBlocks = []blockData{
+	{name: "Plain"},                  // a single successor
+	{name: "If", controls: 1},        // if Controls[0] goto Succs[0] else goto Succs[1]
+	{name: "Defer", controls: 1},     // Succs[0]=defer queued, Succs[1]=defer recovered. Controls[0] is call op (of memory type)
+	{name: "Ret", controls: 1},       // no successors, Controls[0] value is memory result
+	{name: "RetJmp", controls: 1},    // no successors, Controls[0] value is a tail call
+	{name: "Exit", controls: 1},      // no successors, Controls[0] value generates a panic
+	{name: "JumpTable", controls: 1}, // multiple successors, the integer Controls[0] selects which one
+
+	// transient block state used for dead code removal
+	{name: "First"}, // 2 successors, always takes the first one (second is dead)
+}
+
+func init() {
+	archs = append(archs, arch{
+		name:    "generic",
+		ops:     genericOps,
+		blocks:  genericBlocks,
+		generic: true,
+	})
+}
diff --git a/src/cmd/compile/internal/ssa/_gen/main.go b/src/cmd/compile/internal/ssa/_gen/main.go
new file mode 100644
index 0000000..9251ba5
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/_gen/main.go
@@ -0,0 +1,571 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// The gen command generates Go code (in the parent directory) for all
+// the architecture-specific opcodes, blocks, and rewrites.
+package main
+
+import (
+	"bytes"
+	"flag"
+	"fmt"
+	"go/format"
+	"log"
+	"math/bits"
+	"os"
+	"path"
+	"regexp"
+	"runtime"
+	"runtime/pprof"
+	"runtime/trace"
+	"sort"
+	"strings"
+	"sync"
+)
+
+// TODO: capitalize these types, so that we can more easily tell variable names
+// apart from type names, and avoid awkward func parameters like "arch arch".
+
+type arch struct {
+	name               string
+	pkg                string // obj package to import for this arch.
+	genfile            string // source file containing opcode code generation.
+	ops                []opData
+	blocks             []blockData
+	regnames           []string
+	ParamIntRegNames   string
+	ParamFloatRegNames string
+	gpregmask          regMask
+	fpregmask          regMask
+	fp32regmask        regMask
+	fp64regmask        regMask
+	specialregmask     regMask
+	framepointerreg    int8
+	linkreg            int8
+	generic            bool
+	imports            []string
+}
+
+type opData struct {
+	name              string
+	reg               regInfo
+	asm               string
+	typ               string // default result type
+	aux               string
+	rematerializeable bool
+	argLength         int32  // number of arguments, if -1, then this operation has a variable number of arguments
+	commutative       bool   // this operation is commutative on its first 2 arguments (e.g. addition)
+	resultInArg0      bool   // (first, if a tuple) output of v and v.Args[0] must be allocated to the same register
+	resultNotInArgs   bool   // outputs must not be allocated to the same registers as inputs
+	clobberFlags      bool   // this op clobbers flags register
+	needIntTemp       bool   // need a temporary free integer register
+	call              bool   // is a function call
+	tailCall          bool   // is a tail call
+	nilCheck          bool   // this op is a nil check on arg0
+	faultOnNilArg0    bool   // this op will fault if arg0 is nil (and aux encodes a small offset)
+	faultOnNilArg1    bool   // this op will fault if arg1 is nil (and aux encodes a small offset)
+	hasSideEffects    bool   // for "reasons", not to be eliminated.  E.g., atomic store, #19182.
+	zeroWidth         bool   // op never translates into any machine code. example: copy, which may sometimes translate to machine code, is not zero-width.
+	unsafePoint       bool   // this op is an unsafe point, i.e. not safe for async preemption
+	symEffect         string // effect this op has on symbol in aux
+	scale             uint8  // amd64/386 indexed load scale
+}
+
+type blockData struct {
+	name     string // the suffix for this block ("EQ", "LT", etc.)
+	controls int    // the number of control values this type of block requires
+	aux      string // the type of the Aux/AuxInt value, if any
+}
+
+type regInfo struct {
+	// inputs[i] encodes the set of registers allowed for the i'th input.
+	// Inputs that don't use registers (flags, memory, etc.) should be 0.
+	inputs []regMask
+	// clobbers encodes the set of registers that are overwritten by
+	// the instruction (other than the output registers).
+	clobbers regMask
+	// outputs[i] encodes the set of registers allowed for the i'th output.
+	outputs []regMask
+}
+
+type regMask uint64
+
+func (a arch) regMaskComment(r regMask) string {
+	var buf strings.Builder
+	for i := uint64(0); r != 0; i++ {
+		if r&1 != 0 {
+			if buf.Len() == 0 {
+				buf.WriteString(" //")
+			}
+			buf.WriteString(" ")
+			buf.WriteString(a.regnames[i])
+		}
+		r >>= 1
+	}
+	return buf.String()
+}
+
+var archs []arch
+
+var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to `file`")
+var memprofile = flag.String("memprofile", "", "write memory profile to `file`")
+var tracefile = flag.String("trace", "", "write trace to `file`")
+
+func main() {
+	flag.Parse()
+	if *cpuprofile != "" {
+		f, err := os.Create(*cpuprofile)
+		if err != nil {
+			log.Fatal("could not create CPU profile: ", err)
+		}
+		defer f.Close()
+		if err := pprof.StartCPUProfile(f); err != nil {
+			log.Fatal("could not start CPU profile: ", err)
+		}
+		defer pprof.StopCPUProfile()
+	}
+	if *tracefile != "" {
+		f, err := os.Create(*tracefile)
+		if err != nil {
+			log.Fatalf("failed to create trace output file: %v", err)
+		}
+		defer func() {
+			if err := f.Close(); err != nil {
+				log.Fatalf("failed to close trace file: %v", err)
+			}
+		}()
+
+		if err := trace.Start(f); err != nil {
+			log.Fatalf("failed to start trace: %v", err)
+		}
+		defer trace.Stop()
+	}
+
+	sort.Sort(ArchsByName(archs))
+
+	// The generate tasks are run concurrently, since they are CPU-intensive
+	// that can easily make use of many cores on a machine.
+	//
+	// Note that there is no limit on the concurrency at the moment. On a
+	// four-core laptop at the time of writing, peak RSS usually reaches
+	// ~200MiB, which seems doable by practically any machine nowadays. If
+	// that stops being the case, we can cap this func to a fixed number of
+	// architectures being generated at once.
+
+	tasks := []func(){
+		genOp,
+		genAllocators,
+	}
+	for _, a := range archs {
+		a := a // the funcs are ran concurrently at a later time
+		tasks = append(tasks, func() {
+			genRules(a)
+			genSplitLoadRules(a)
+			genLateLowerRules(a)
+		})
+	}
+	var wg sync.WaitGroup
+	for _, task := range tasks {
+		task := task
+		wg.Add(1)
+		go func() {
+			task()
+			wg.Done()
+		}()
+	}
+	wg.Wait()
+
+	if *memprofile != "" {
+		f, err := os.Create(*memprofile)
+		if err != nil {
+			log.Fatal("could not create memory profile: ", err)
+		}
+		defer f.Close()
+		runtime.GC() // get up-to-date statistics
+		if err := pprof.WriteHeapProfile(f); err != nil {
+			log.Fatal("could not write memory profile: ", err)
+		}
+	}
+}
+
+func genOp() {
+	w := new(bytes.Buffer)
+	fmt.Fprintf(w, "// Code generated from _gen/*Ops.go; DO NOT EDIT.\n")
+	fmt.Fprintln(w)
+	fmt.Fprintln(w, "package ssa")
+
+	fmt.Fprintln(w, "import (")
+	fmt.Fprintln(w, "\"cmd/internal/obj\"")
+	for _, a := range archs {
+		if a.pkg != "" {
+			fmt.Fprintf(w, "%q\n", a.pkg)
+		}
+	}
+	fmt.Fprintln(w, ")")
+
+	// generate Block* declarations
+	fmt.Fprintln(w, "const (")
+	fmt.Fprintln(w, "BlockInvalid BlockKind = iota")
+	for _, a := range archs {
+		fmt.Fprintln(w)
+		for _, d := range a.blocks {
+			fmt.Fprintf(w, "Block%s%s\n", a.Name(), d.name)
+		}
+	}
+	fmt.Fprintln(w, ")")
+
+	// generate block kind string method
+	fmt.Fprintln(w, "var blockString = [...]string{")
+	fmt.Fprintln(w, "BlockInvalid:\"BlockInvalid\",")
+	for _, a := range archs {
+		fmt.Fprintln(w)
+		for _, b := range a.blocks {
+			fmt.Fprintf(w, "Block%s%s:\"%s\",\n", a.Name(), b.name, b.name)
+		}
+	}
+	fmt.Fprintln(w, "}")
+	fmt.Fprintln(w, "func (k BlockKind) String() string {return blockString[k]}")
+
+	// generate block kind auxint method
+	fmt.Fprintln(w, "func (k BlockKind) AuxIntType() string {")
+	fmt.Fprintln(w, "switch k {")
+	for _, a := range archs {
+		for _, b := range a.blocks {
+			if b.auxIntType() == "invalid" {
+				continue
+			}
+			fmt.Fprintf(w, "case Block%s%s: return \"%s\"\n", a.Name(), b.name, b.auxIntType())
+		}
+	}
+	fmt.Fprintln(w, "}")
+	fmt.Fprintln(w, "return \"\"")
+	fmt.Fprintln(w, "}")
+
+	// generate Op* declarations
+	fmt.Fprintln(w, "const (")
+	fmt.Fprintln(w, "OpInvalid Op = iota") // make sure OpInvalid is 0.
+	for _, a := range archs {
+		fmt.Fprintln(w)
+		for _, v := range a.ops {
+			if v.name == "Invalid" {
+				continue
+			}
+			fmt.Fprintf(w, "Op%s%s\n", a.Name(), v.name)
+		}
+	}
+	fmt.Fprintln(w, ")")
+
+	// generate OpInfo table
+	fmt.Fprintln(w, "var opcodeTable = [...]opInfo{")
+	fmt.Fprintln(w, " { name: \"OpInvalid\" },")
+	for _, a := range archs {
+		fmt.Fprintln(w)
+
+		pkg := path.Base(a.pkg)
+		for _, v := range a.ops {
+			if v.name == "Invalid" {
+				continue
+			}
+			fmt.Fprintln(w, "{")
+			fmt.Fprintf(w, "name:\"%s\",\n", v.name)
+
+			// flags
+			if v.aux != "" {
+				fmt.Fprintf(w, "auxType: aux%s,\n", v.aux)
+			}
+			fmt.Fprintf(w, "argLen: %d,\n", v.argLength)
+
+			if v.rematerializeable {
+				if v.reg.clobbers != 0 {
+					log.Fatalf("%s is rematerializeable and clobbers registers", v.name)
+				}
+				if v.clobberFlags {
+					log.Fatalf("%s is rematerializeable and clobbers flags", v.name)
+				}
+				fmt.Fprintln(w, "rematerializeable: true,")
+			}
+			if v.commutative {
+				fmt.Fprintln(w, "commutative: true,")
+			}
+			if v.resultInArg0 {
+				fmt.Fprintln(w, "resultInArg0: true,")
+				// OpConvert's register mask is selected dynamically,
+				// so don't try to check it in the static table.
+				if v.name != "Convert" && v.reg.inputs[0] != v.reg.outputs[0] {
+					log.Fatalf("%s: input[0] and output[0] must use the same registers for %s", a.name, v.name)
+				}
+				if v.name != "Convert" && v.commutative && v.reg.inputs[1] != v.reg.outputs[0] {
+					log.Fatalf("%s: input[1] and output[0] must use the same registers for %s", a.name, v.name)
+				}
+			}
+			if v.resultNotInArgs {
+				fmt.Fprintln(w, "resultNotInArgs: true,")
+			}
+			if v.clobberFlags {
+				fmt.Fprintln(w, "clobberFlags: true,")
+			}
+			if v.needIntTemp {
+				fmt.Fprintln(w, "needIntTemp: true,")
+			}
+			if v.call {
+				fmt.Fprintln(w, "call: true,")
+			}
+			if v.tailCall {
+				fmt.Fprintln(w, "tailCall: true,")
+			}
+			if v.nilCheck {
+				fmt.Fprintln(w, "nilCheck: true,")
+			}
+			if v.faultOnNilArg0 {
+				fmt.Fprintln(w, "faultOnNilArg0: true,")
+				if v.aux != "Sym" && v.aux != "SymOff" && v.aux != "SymValAndOff" && v.aux != "Int64" && v.aux != "Int32" && v.aux != "" {
+					log.Fatalf("faultOnNilArg0 with aux %s not allowed", v.aux)
+				}
+			}
+			if v.faultOnNilArg1 {
+				fmt.Fprintln(w, "faultOnNilArg1: true,")
+				if v.aux != "Sym" && v.aux != "SymOff" && v.aux != "SymValAndOff" && v.aux != "Int64" && v.aux != "Int32" && v.aux != "" {
+					log.Fatalf("faultOnNilArg1 with aux %s not allowed", v.aux)
+				}
+			}
+			if v.hasSideEffects {
+				fmt.Fprintln(w, "hasSideEffects: true,")
+			}
+			if v.zeroWidth {
+				fmt.Fprintln(w, "zeroWidth: true,")
+			}
+			if v.unsafePoint {
+				fmt.Fprintln(w, "unsafePoint: true,")
+			}
+			needEffect := strings.HasPrefix(v.aux, "Sym")
+			if v.symEffect != "" {
+				if !needEffect {
+					log.Fatalf("symEffect with aux %s not allowed", v.aux)
+				}
+				fmt.Fprintf(w, "symEffect: Sym%s,\n", strings.Replace(v.symEffect, ",", "|Sym", -1))
+			} else if needEffect {
+				log.Fatalf("symEffect needed for aux %s", v.aux)
+			}
+			if a.name == "generic" {
+				fmt.Fprintln(w, "generic:true,")
+				fmt.Fprintln(w, "},") // close op
+				// generic ops have no reg info or asm
+				continue
+			}
+			if v.asm != "" {
+				fmt.Fprintf(w, "asm: %s.A%s,\n", pkg, v.asm)
+			}
+			if v.scale != 0 {
+				fmt.Fprintf(w, "scale: %d,\n", v.scale)
+			}
+			fmt.Fprintln(w, "reg:regInfo{")
+
+			// Compute input allocation order. We allocate from the
+			// most to the least constrained input. This order guarantees
+			// that we will always be able to find a register.
+			var s []intPair
+			for i, r := range v.reg.inputs {
+				if r != 0 {
+					s = append(s, intPair{countRegs(r), i})
+				}
+			}
+			if len(s) > 0 {
+				sort.Sort(byKey(s))
+				fmt.Fprintln(w, "inputs: []inputInfo{")
+				for _, p := range s {
+					r := v.reg.inputs[p.val]
+					fmt.Fprintf(w, "{%d,%d},%s\n", p.val, r, a.regMaskComment(r))
+				}
+				fmt.Fprintln(w, "},")
+			}
+
+			if v.reg.clobbers > 0 {
+				fmt.Fprintf(w, "clobbers: %d,%s\n", v.reg.clobbers, a.regMaskComment(v.reg.clobbers))
+			}
+
+			// reg outputs
+			s = s[:0]
+			for i, r := range v.reg.outputs {
+				s = append(s, intPair{countRegs(r), i})
+			}
+			if len(s) > 0 {
+				sort.Sort(byKey(s))
+				fmt.Fprintln(w, "outputs: []outputInfo{")
+				for _, p := range s {
+					r := v.reg.outputs[p.val]
+					fmt.Fprintf(w, "{%d,%d},%s\n", p.val, r, a.regMaskComment(r))
+				}
+				fmt.Fprintln(w, "},")
+			}
+			fmt.Fprintln(w, "},") // close reg info
+			fmt.Fprintln(w, "},") // close op
+		}
+	}
+	fmt.Fprintln(w, "}")
+
+	fmt.Fprintln(w, "func (o Op) Asm() obj.As {return opcodeTable[o].asm}")
+	fmt.Fprintln(w, "func (o Op) Scale() int16 {return int16(opcodeTable[o].scale)}")
+
+	// generate op string method
+	fmt.Fprintln(w, "func (o Op) String() string {return opcodeTable[o].name }")
+
+	fmt.Fprintln(w, "func (o Op) SymEffect() SymEffect { return opcodeTable[o].symEffect }")
+	fmt.Fprintln(w, "func (o Op) IsCall() bool { return opcodeTable[o].call }")
+	fmt.Fprintln(w, "func (o Op) IsTailCall() bool { return opcodeTable[o].tailCall }")
+	fmt.Fprintln(w, "func (o Op) HasSideEffects() bool { return opcodeTable[o].hasSideEffects }")
+	fmt.Fprintln(w, "func (o Op) UnsafePoint() bool { return opcodeTable[o].unsafePoint }")
+	fmt.Fprintln(w, "func (o Op) ResultInArg0() bool { return opcodeTable[o].resultInArg0 }")
+
+	// generate registers
+	for _, a := range archs {
+		if a.generic {
+			continue
+		}
+		fmt.Fprintf(w, "var registers%s = [...]Register {\n", a.name)
+		var gcRegN int
+		num := map[string]int8{}
+		for i, r := range a.regnames {
+			num[r] = int8(i)
+			pkg := a.pkg[len("cmd/internal/obj/"):]
+			var objname string // name in cmd/internal/obj/$ARCH
+			switch r {
+			case "SB":
+				// SB isn't a real register.  cmd/internal/obj expects 0 in this case.
+				objname = "0"
+			case "SP":
+				objname = pkg + ".REGSP"
+			case "g":
+				objname = pkg + ".REGG"
+			default:
+				objname = pkg + ".REG_" + r
+			}
+			// Assign a GC register map index to registers
+			// that may contain pointers.
+			gcRegIdx := -1
+			if a.gpregmask&(1<<uint(i)) != 0 {
+				gcRegIdx = gcRegN
+				gcRegN++
+			}
+			fmt.Fprintf(w, "  {%d, %s, %d, \"%s\"},\n", i, objname, gcRegIdx, r)
+		}
+		parameterRegisterList := func(paramNamesString string) []int8 {
+			paramNamesString = strings.TrimSpace(paramNamesString)
+			if paramNamesString == "" {
+				return nil
+			}
+			paramNames := strings.Split(paramNamesString, " ")
+			var paramRegs []int8
+			for _, regName := range paramNames {
+				if regName == "" {
+					// forgive extra spaces
+					continue
+				}
+				if regNum, ok := num[regName]; ok {
+					paramRegs = append(paramRegs, regNum)
+					delete(num, regName)
+				} else {
+					log.Fatalf("parameter register %s for architecture %s not a register name (or repeated in parameter list)", regName, a.name)
+				}
+			}
+			return paramRegs
+		}
+
+		paramIntRegs := parameterRegisterList(a.ParamIntRegNames)
+		paramFloatRegs := parameterRegisterList(a.ParamFloatRegNames)
+
+		if gcRegN > 32 {
+			// Won't fit in a uint32 mask.
+			log.Fatalf("too many GC registers (%d > 32) on %s", gcRegN, a.name)
+		}
+		fmt.Fprintln(w, "}")
+		fmt.Fprintf(w, "var paramIntReg%s = %#v\n", a.name, paramIntRegs)
+		fmt.Fprintf(w, "var paramFloatReg%s = %#v\n", a.name, paramFloatRegs)
+		fmt.Fprintf(w, "var gpRegMask%s = regMask(%d)\n", a.name, a.gpregmask)
+		fmt.Fprintf(w, "var fpRegMask%s = regMask(%d)\n", a.name, a.fpregmask)
+		if a.fp32regmask != 0 {
+			fmt.Fprintf(w, "var fp32RegMask%s = regMask(%d)\n", a.name, a.fp32regmask)
+		}
+		if a.fp64regmask != 0 {
+			fmt.Fprintf(w, "var fp64RegMask%s = regMask(%d)\n", a.name, a.fp64regmask)
+		}
+		fmt.Fprintf(w, "var specialRegMask%s = regMask(%d)\n", a.name, a.specialregmask)
+		fmt.Fprintf(w, "var framepointerReg%s = int8(%d)\n", a.name, a.framepointerreg)
+		fmt.Fprintf(w, "var linkReg%s = int8(%d)\n", a.name, a.linkreg)
+	}
+
+	// gofmt result
+	b := w.Bytes()
+	var err error
+	b, err = format.Source(b)
+	if err != nil {
+		fmt.Printf("%s\n", w.Bytes())
+		panic(err)
+	}
+
+	if err := os.WriteFile("../opGen.go", b, 0666); err != nil {
+		log.Fatalf("can't write output: %v\n", err)
+	}
+
+	// Check that the arch genfile handles all the arch-specific opcodes.
+	// This is very much a hack, but it is better than nothing.
+	//
+	// Do a single regexp pass to record all ops being handled in a map, and
+	// then compare that with the ops list. This is much faster than one
+	// regexp pass per opcode.
+	for _, a := range archs {
+		if a.genfile == "" {
+			continue
+		}
+
+		pattern := fmt.Sprintf(`\Wssa\.Op%s([a-zA-Z0-9_]+)\W`, a.name)
+		rxOp, err := regexp.Compile(pattern)
+		if err != nil {
+			log.Fatalf("bad opcode regexp %s: %v", pattern, err)
+		}
+
+		src, err := os.ReadFile(a.genfile)
+		if err != nil {
+			log.Fatalf("can't read %s: %v", a.genfile, err)
+		}
+		seen := make(map[string]bool, len(a.ops))
+		for _, m := range rxOp.FindAllSubmatch(src, -1) {
+			seen[string(m[1])] = true
+		}
+		for _, op := range a.ops {
+			if !seen[op.name] {
+				log.Fatalf("Op%s%s has no code generation in %s", a.name, op.name, a.genfile)
+			}
+		}
+	}
+}
+
+// Name returns the name of the architecture for use in Op* and Block* enumerations.
+func (a arch) Name() string {
+	s := a.name
+	if s == "generic" {
+		s = ""
+	}
+	return s
+}
+
+// countRegs returns the number of set bits in the register mask.
+func countRegs(r regMask) int {
+	return bits.OnesCount64(uint64(r))
+}
+
+// for sorting a pair of integers by key
+type intPair struct {
+	key, val int
+}
+type byKey []intPair
+
+func (a byKey) Len() int           { return len(a) }
+func (a byKey) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
+func (a byKey) Less(i, j int) bool { return a[i].key < a[j].key }
+
+type ArchsByName []arch
+
+func (x ArchsByName) Len() int           { return len(x) }
+func (x ArchsByName) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
+func (x ArchsByName) Less(i, j int) bool { return x[i].name < x[j].name }
diff --git a/src/cmd/compile/internal/ssa/_gen/rulegen.go b/src/cmd/compile/internal/ssa/_gen/rulegen.go
new file mode 100644
index 0000000..80fa37a
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/_gen/rulegen.go
@@ -0,0 +1,1885 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This program generates Go code that applies rewrite rules to a Value.
+// The generated code implements a function of type func (v *Value) bool
+// which reports whether if did something.
+// Ideas stolen from Swift: http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-2000-2.html
+
+package main
+
+import (
+	"bufio"
+	"bytes"
+	"flag"
+	"fmt"
+	"go/ast"
+	"go/format"
+	"go/parser"
+	"go/printer"
+	"go/token"
+	"io"
+	"log"
+	"os"
+	"path"
+	"regexp"
+	"sort"
+	"strconv"
+	"strings"
+
+	"golang.org/x/tools/go/ast/astutil"
+)
+
+// rule syntax:
+//  sexpr [&& extra conditions] => [@block] sexpr
+//
+// sexpr are s-expressions (lisp-like parenthesized groupings)
+// sexpr ::= [variable:](opcode sexpr*)
+//         | variable
+//         | <type>
+//         | [auxint]
+//         | {aux}
+//
+// aux      ::= variable | {code}
+// type     ::= variable | {code}
+// variable ::= some token
+// opcode   ::= one of the opcodes from the *Ops.go files
+
+// special rules: trailing ellipsis "..." (in the outermost sexpr?) must match on both sides of a rule.
+//                trailing three underscore "___" in the outermost match sexpr indicate the presence of
+//                   extra ignored args that need not appear in the replacement
+
+// extra conditions is just a chunk of Go that evaluates to a boolean. It may use
+// variables declared in the matching tsexpr. The variable "v" is predefined to be
+// the value matched by the entire rule.
+
+// If multiple rules match, the first one in file order is selected.
+
+var (
+	genLog  = flag.Bool("log", false, "generate code that logs; for debugging only")
+	addLine = flag.Bool("line", false, "add line number comment to generated rules; for debugging only")
+)
+
+type Rule struct {
+	Rule string
+	Loc  string // file name & line number
+}
+
+func (r Rule) String() string {
+	return fmt.Sprintf("rule %q at %s", r.Rule, r.Loc)
+}
+
+func normalizeSpaces(s string) string {
+	return strings.Join(strings.Fields(strings.TrimSpace(s)), " ")
+}
+
+// parse returns the matching part of the rule, additional conditions, and the result.
+func (r Rule) parse() (match, cond, result string) {
+	s := strings.Split(r.Rule, "=>")
+	match = normalizeSpaces(s[0])
+	result = normalizeSpaces(s[1])
+	cond = ""
+	if i := strings.Index(match, "&&"); i >= 0 {
+		cond = normalizeSpaces(match[i+2:])
+		match = normalizeSpaces(match[:i])
+	}
+	return match, cond, result
+}
+
+func genRules(arch arch)          { genRulesSuffix(arch, "") }
+func genSplitLoadRules(arch arch) { genRulesSuffix(arch, "splitload") }
+func genLateLowerRules(arch arch) { genRulesSuffix(arch, "latelower") }
+
+func genRulesSuffix(arch arch, suff string) {
+	// Open input file.
+	text, err := os.Open(arch.name + suff + ".rules")
+	if err != nil {
+		if suff == "" {
+			// All architectures must have a plain rules file.
+			log.Fatalf("can't read rule file: %v", err)
+		}
+		// Some architectures have bonus rules files that others don't share. That's fine.
+		return
+	}
+
+	// oprules contains a list of rules for each block and opcode
+	blockrules := map[string][]Rule{}
+	oprules := map[string][]Rule{}
+
+	// read rule file
+	scanner := bufio.NewScanner(text)
+	rule := ""
+	var lineno int
+	var ruleLineno int // line number of "=>"
+	for scanner.Scan() {
+		lineno++
+		line := scanner.Text()
+		if i := strings.Index(line, "//"); i >= 0 {
+			// Remove comments. Note that this isn't string safe, so
+			// it will truncate lines with // inside strings. Oh well.
+			line = line[:i]
+		}
+		rule += " " + line
+		rule = strings.TrimSpace(rule)
+		if rule == "" {
+			continue
+		}
+		if !strings.Contains(rule, "=>") {
+			continue
+		}
+		if ruleLineno == 0 {
+			ruleLineno = lineno
+		}
+		if strings.HasSuffix(rule, "=>") {
+			continue // continue on the next line
+		}
+		if n := balance(rule); n > 0 {
+			continue // open parentheses remain, continue on the next line
+		} else if n < 0 {
+			break // continuing the line can't help, and it will only make errors worse
+		}
+
+		loc := fmt.Sprintf("%s%s.rules:%d", arch.name, suff, ruleLineno)
+		for _, rule2 := range expandOr(rule) {
+			r := Rule{Rule: rule2, Loc: loc}
+			if rawop := strings.Split(rule2, " ")[0][1:]; isBlock(rawop, arch) {
+				blockrules[rawop] = append(blockrules[rawop], r)
+				continue
+			}
+			// Do fancier value op matching.
+			match, _, _ := r.parse()
+			op, oparch, _, _, _, _ := parseValue(match, arch, loc)
+			opname := fmt.Sprintf("Op%s%s", oparch, op.name)
+			oprules[opname] = append(oprules[opname], r)
+		}
+		rule = ""
+		ruleLineno = 0
+	}
+	if err := scanner.Err(); err != nil {
+		log.Fatalf("scanner failed: %v\n", err)
+	}
+	if balance(rule) != 0 {
+		log.Fatalf("%s.rules:%d: unbalanced rule: %v\n", arch.name, lineno, rule)
+	}
+
+	// Order all the ops.
+	var ops []string
+	for op := range oprules {
+		ops = append(ops, op)
+	}
+	sort.Strings(ops)
+
+	genFile := &File{Arch: arch, Suffix: suff}
+	// Main rewrite routine is a switch on v.Op.
+	fn := &Func{Kind: "Value", ArgLen: -1}
+
+	sw := &Switch{Expr: exprf("v.Op")}
+	for _, op := range ops {
+		eop, ok := parseEllipsisRules(oprules[op], arch)
+		if ok {
+			if strings.Contains(oprules[op][0].Rule, "=>") && opByName(arch, op).aux != opByName(arch, eop).aux {
+				panic(fmt.Sprintf("can't use ... for ops that have different aux types: %s and %s", op, eop))
+			}
+			swc := &Case{Expr: exprf("%s", op)}
+			swc.add(stmtf("v.Op = %s", eop))
+			swc.add(stmtf("return true"))
+			sw.add(swc)
+			continue
+		}
+
+		swc := &Case{Expr: exprf("%s", op)}
+		swc.add(stmtf("return rewriteValue%s%s_%s(v)", arch.name, suff, op))
+		sw.add(swc)
+	}
+	if len(sw.List) > 0 { // skip if empty
+		fn.add(sw)
+	}
+	fn.add(stmtf("return false"))
+	genFile.add(fn)
+
+	// Generate a routine per op. Note that we don't make one giant routine
+	// because it is too big for some compilers.
+	for _, op := range ops {
+		rules := oprules[op]
+		_, ok := parseEllipsisRules(oprules[op], arch)
+		if ok {
+			continue
+		}
+
+		// rr is kept between iterations, so that each rule can check
+		// that the previous rule wasn't unconditional.
+		var rr *RuleRewrite
+		fn := &Func{
+			Kind:   "Value",
+			Suffix: fmt.Sprintf("_%s", op),
+			ArgLen: opByName(arch, op).argLength,
+		}
+		fn.add(declReserved("b", "v.Block"))
+		fn.add(declReserved("config", "b.Func.Config"))
+		fn.add(declReserved("fe", "b.Func.fe"))
+		fn.add(declReserved("typ", "&b.Func.Config.Types"))
+		for _, rule := range rules {
+			if rr != nil && !rr.CanFail {
+				log.Fatalf("unconditional rule %s is followed by other rules", rr.Match)
+			}
+			rr = &RuleRewrite{Loc: rule.Loc}
+			rr.Match, rr.Cond, rr.Result = rule.parse()
+			pos, _ := genMatch(rr, arch, rr.Match, fn.ArgLen >= 0)
+			if pos == "" {
+				pos = "v.Pos"
+			}
+			if rr.Cond != "" {
+				rr.add(breakf("!(%s)", rr.Cond))
+			}
+			genResult(rr, arch, rr.Result, pos)
+			if *genLog {
+				rr.add(stmtf("logRule(%q)", rule.Loc))
+			}
+			fn.add(rr)
+		}
+		if rr.CanFail {
+			fn.add(stmtf("return false"))
+		}
+		genFile.add(fn)
+	}
+
+	// Generate block rewrite function. There are only a few block types
+	// so we can make this one function with a switch.
+	fn = &Func{Kind: "Block"}
+	fn.add(declReserved("config", "b.Func.Config"))
+	fn.add(declReserved("typ", "&b.Func.Config.Types"))
+
+	sw = &Switch{Expr: exprf("b.Kind")}
+	ops = ops[:0]
+	for op := range blockrules {
+		ops = append(ops, op)
+	}
+	sort.Strings(ops)
+	for _, op := range ops {
+		name, data := getBlockInfo(op, arch)
+		swc := &Case{Expr: exprf("%s", name)}
+		for _, rule := range blockrules[op] {
+			swc.add(genBlockRewrite(rule, arch, data))
+		}
+		sw.add(swc)
+	}
+	if len(sw.List) > 0 { // skip if empty
+		fn.add(sw)
+	}
+	fn.add(stmtf("return false"))
+	genFile.add(fn)
+
+	// Remove unused imports and variables.
+	buf := new(bytes.Buffer)
+	fprint(buf, genFile)
+	fset := token.NewFileSet()
+	file, err := parser.ParseFile(fset, "", buf, parser.ParseComments)
+	if err != nil {
+		filename := fmt.Sprintf("%s_broken.go", arch.name)
+		if err := os.WriteFile(filename, buf.Bytes(), 0644); err != nil {
+			log.Printf("failed to dump broken code to %s: %v", filename, err)
+		} else {
+			log.Printf("dumped broken code to %s", filename)
+		}
+		log.Fatalf("failed to parse generated code for arch %s: %v", arch.name, err)
+	}
+	tfile := fset.File(file.Pos())
+
+	// First, use unusedInspector to find the unused declarations by their
+	// start position.
+	u := unusedInspector{unused: make(map[token.Pos]bool)}
+	u.node(file)
+
+	// Then, delete said nodes via astutil.Apply.
+	pre := func(c *astutil.Cursor) bool {
+		node := c.Node()
+		if node == nil {
+			return true
+		}
+		if u.unused[node.Pos()] {
+			c.Delete()
+			// Unused imports and declarations use exactly
+			// one line. Prevent leaving an empty line.
+			tfile.MergeLine(tfile.Position(node.Pos()).Line)
+			return false
+		}
+		return true
+	}
+	post := func(c *astutil.Cursor) bool {
+		switch node := c.Node().(type) {
+		case *ast.GenDecl:
+			if len(node.Specs) == 0 {
+				// Don't leave a broken or empty GenDecl behind,
+				// such as "import ()".
+				c.Delete()
+			}
+		}
+		return true
+	}
+	file = astutil.Apply(file, pre, post).(*ast.File)
+
+	// Write the well-formatted source to file
+	f, err := os.Create("../rewrite" + arch.name + suff + ".go")
+	if err != nil {
+		log.Fatalf("can't write output: %v", err)
+	}
+	defer f.Close()
+	// gofmt result; use a buffered writer, as otherwise go/format spends
+	// far too much time in syscalls.
+	bw := bufio.NewWriter(f)
+	if err := format.Node(bw, fset, file); err != nil {
+		log.Fatalf("can't format output: %v", err)
+	}
+	if err := bw.Flush(); err != nil {
+		log.Fatalf("can't write output: %v", err)
+	}
+	if err := f.Close(); err != nil {
+		log.Fatalf("can't write output: %v", err)
+	}
+}
+
+// unusedInspector can be used to detect unused variables and imports in an
+// ast.Node via its node method. The result is available in the "unused" map.
+//
+// note that unusedInspector is lazy and best-effort; it only supports the node
+// types and patterns used by the rulegen program.
+type unusedInspector struct {
+	// scope is the current scope, which can never be nil when a declaration
+	// is encountered. That is, the unusedInspector.node entrypoint should
+	// generally be an entire file or block.
+	scope *scope
+
+	// unused is the resulting set of unused declared names, indexed by the
+	// starting position of the node that declared the name.
+	unused map[token.Pos]bool
+
+	// defining is the object currently being defined; this is useful so
+	// that if "foo := bar" is unused and removed, we can then detect if
+	// "bar" becomes unused as well.
+	defining *object
+}
+
+// scoped opens a new scope when called, and returns a function which closes
+// that same scope. When a scope is closed, unused variables are recorded.
+func (u *unusedInspector) scoped() func() {
+	outer := u.scope
+	u.scope = &scope{outer: outer, objects: map[string]*object{}}
+	return func() {
+		for anyUnused := true; anyUnused; {
+			anyUnused = false
+			for _, obj := range u.scope.objects {
+				if obj.numUses > 0 {
+					continue
+				}
+				u.unused[obj.pos] = true
+				for _, used := range obj.used {
+					if used.numUses--; used.numUses == 0 {
+						anyUnused = true
+					}
+				}
+				// We've decremented numUses for each of the
+				// objects in used. Zero this slice too, to keep
+				// everything consistent.
+				obj.used = nil
+			}
+		}
+		u.scope = outer
+	}
+}
+
+func (u *unusedInspector) exprs(list []ast.Expr) {
+	for _, x := range list {
+		u.node(x)
+	}
+}
+
+func (u *unusedInspector) node(node ast.Node) {
+	switch node := node.(type) {
+	case *ast.File:
+		defer u.scoped()()
+		for _, decl := range node.Decls {
+			u.node(decl)
+		}
+	case *ast.GenDecl:
+		for _, spec := range node.Specs {
+			u.node(spec)
+		}
+	case *ast.ImportSpec:
+		impPath, _ := strconv.Unquote(node.Path.Value)
+		name := path.Base(impPath)
+		u.scope.objects[name] = &object{
+			name: name,
+			pos:  node.Pos(),
+		}
+	case *ast.FuncDecl:
+		u.node(node.Type)
+		if node.Body != nil {
+			u.node(node.Body)
+		}
+	case *ast.FuncType:
+		if node.Params != nil {
+			u.node(node.Params)
+		}
+		if node.Results != nil {
+			u.node(node.Results)
+		}
+	case *ast.FieldList:
+		for _, field := range node.List {
+			u.node(field)
+		}
+	case *ast.Field:
+		u.node(node.Type)
+
+	// statements
+
+	case *ast.BlockStmt:
+		defer u.scoped()()
+		for _, stmt := range node.List {
+			u.node(stmt)
+		}
+	case *ast.DeclStmt:
+		u.node(node.Decl)
+	case *ast.IfStmt:
+		if node.Init != nil {
+			u.node(node.Init)
+		}
+		u.node(node.Cond)
+		u.node(node.Body)
+		if node.Else != nil {
+			u.node(node.Else)
+		}
+	case *ast.ForStmt:
+		if node.Init != nil {
+			u.node(node.Init)
+		}
+		if node.Cond != nil {
+			u.node(node.Cond)
+		}
+		if node.Post != nil {
+			u.node(node.Post)
+		}
+		u.node(node.Body)
+	case *ast.SwitchStmt:
+		if node.Init != nil {
+			u.node(node.Init)
+		}
+		if node.Tag != nil {
+			u.node(node.Tag)
+		}
+		u.node(node.Body)
+	case *ast.CaseClause:
+		u.exprs(node.List)
+		defer u.scoped()()
+		for _, stmt := range node.Body {
+			u.node(stmt)
+		}
+	case *ast.BranchStmt:
+	case *ast.ExprStmt:
+		u.node(node.X)
+	case *ast.AssignStmt:
+		if node.Tok != token.DEFINE {
+			u.exprs(node.Rhs)
+			u.exprs(node.Lhs)
+			break
+		}
+		lhs := node.Lhs
+		if len(lhs) == 2 && lhs[1].(*ast.Ident).Name == "_" {
+			lhs = lhs[:1]
+		}
+		if len(lhs) != 1 {
+			panic("no support for := with multiple names")
+		}
+
+		name := lhs[0].(*ast.Ident)
+		obj := &object{
+			name: name.Name,
+			pos:  name.NamePos,
+		}
+
+		old := u.defining
+		u.defining = obj
+		u.exprs(node.Rhs)
+		u.defining = old
+
+		u.scope.objects[name.Name] = obj
+	case *ast.ReturnStmt:
+		u.exprs(node.Results)
+	case *ast.IncDecStmt:
+		u.node(node.X)
+
+	// expressions
+
+	case *ast.CallExpr:
+		u.node(node.Fun)
+		u.exprs(node.Args)
+	case *ast.SelectorExpr:
+		u.node(node.X)
+	case *ast.UnaryExpr:
+		u.node(node.X)
+	case *ast.BinaryExpr:
+		u.node(node.X)
+		u.node(node.Y)
+	case *ast.StarExpr:
+		u.node(node.X)
+	case *ast.ParenExpr:
+		u.node(node.X)
+	case *ast.IndexExpr:
+		u.node(node.X)
+		u.node(node.Index)
+	case *ast.TypeAssertExpr:
+		u.node(node.X)
+		u.node(node.Type)
+	case *ast.Ident:
+		if obj := u.scope.Lookup(node.Name); obj != nil {
+			obj.numUses++
+			if u.defining != nil {
+				u.defining.used = append(u.defining.used, obj)
+			}
+		}
+	case *ast.BasicLit:
+	case *ast.ValueSpec:
+		u.exprs(node.Values)
+	default:
+		panic(fmt.Sprintf("unhandled node: %T", node))
+	}
+}
+
+// scope keeps track of a certain scope and its declared names, as well as the
+// outer (parent) scope.
+type scope struct {
+	outer   *scope             // can be nil, if this is the top-level scope
+	objects map[string]*object // indexed by each declared name
+}
+
+func (s *scope) Lookup(name string) *object {
+	if obj := s.objects[name]; obj != nil {
+		return obj
+	}
+	if s.outer == nil {
+		return nil
+	}
+	return s.outer.Lookup(name)
+}
+
+// object keeps track of a declared name, such as a variable or import.
+type object struct {
+	name string
+	pos  token.Pos // start position of the node declaring the object
+
+	numUses int       // number of times this object is used
+	used    []*object // objects that its declaration makes use of
+}
+
+func fprint(w io.Writer, n Node) {
+	switch n := n.(type) {
+	case *File:
+		file := n
+		seenRewrite := make(map[[3]string]string)
+		fmt.Fprintf(w, "// Code generated from _gen/%s%s.rules; DO NOT EDIT.\n", n.Arch.name, n.Suffix)
+		fmt.Fprintf(w, "// generated with: cd _gen; go run .\n")
+		fmt.Fprintf(w, "\npackage ssa\n")
+		for _, path := range append([]string{
+			"fmt",
+			"internal/buildcfg",
+			"math",
+			"cmd/internal/obj",
+			"cmd/compile/internal/base",
+			"cmd/compile/internal/types",
+		}, n.Arch.imports...) {
+			fmt.Fprintf(w, "import %q\n", path)
+		}
+		for _, f := range n.List {
+			f := f.(*Func)
+			fmt.Fprintf(w, "func rewrite%s%s%s%s(", f.Kind, n.Arch.name, n.Suffix, f.Suffix)
+			fmt.Fprintf(w, "%c *%s) bool {\n", strings.ToLower(f.Kind)[0], f.Kind)
+			if f.Kind == "Value" && f.ArgLen > 0 {
+				for i := f.ArgLen - 1; i >= 0; i-- {
+					fmt.Fprintf(w, "v_%d := v.Args[%d]\n", i, i)
+				}
+			}
+			for _, n := range f.List {
+				fprint(w, n)
+
+				if rr, ok := n.(*RuleRewrite); ok {
+					k := [3]string{
+						normalizeMatch(rr.Match, file.Arch),
+						normalizeWhitespace(rr.Cond),
+						normalizeWhitespace(rr.Result),
+					}
+					if prev, ok := seenRewrite[k]; ok {
+						log.Fatalf("duplicate rule %s, previously seen at %s\n", rr.Loc, prev)
+					}
+					seenRewrite[k] = rr.Loc
+				}
+			}
+			fmt.Fprintf(w, "}\n")
+		}
+	case *Switch:
+		fmt.Fprintf(w, "switch ")
+		fprint(w, n.Expr)
+		fmt.Fprintf(w, " {\n")
+		for _, n := range n.List {
+			fprint(w, n)
+		}
+		fmt.Fprintf(w, "}\n")
+	case *Case:
+		fmt.Fprintf(w, "case ")
+		fprint(w, n.Expr)
+		fmt.Fprintf(w, ":\n")
+		for _, n := range n.List {
+			fprint(w, n)
+		}
+	case *RuleRewrite:
+		if *addLine {
+			fmt.Fprintf(w, "// %s\n", n.Loc)
+		}
+		fmt.Fprintf(w, "// match: %s\n", n.Match)
+		if n.Cond != "" {
+			fmt.Fprintf(w, "// cond: %s\n", n.Cond)
+		}
+		fmt.Fprintf(w, "// result: %s\n", n.Result)
+		fmt.Fprintf(w, "for %s {\n", n.Check)
+		nCommutative := 0
+		for _, n := range n.List {
+			if b, ok := n.(*CondBreak); ok {
+				b.InsideCommuteLoop = nCommutative > 0
+			}
+			fprint(w, n)
+			if loop, ok := n.(StartCommuteLoop); ok {
+				if nCommutative != loop.Depth {
+					panic("mismatch commute loop depth")
+				}
+				nCommutative++
+			}
+		}
+		fmt.Fprintf(w, "return true\n")
+		for i := 0; i < nCommutative; i++ {
+			fmt.Fprintln(w, "}")
+		}
+		if n.CommuteDepth > 0 && n.CanFail {
+			fmt.Fprint(w, "break\n")
+		}
+		fmt.Fprintf(w, "}\n")
+	case *Declare:
+		fmt.Fprintf(w, "%s := ", n.Name)
+		fprint(w, n.Value)
+		fmt.Fprintln(w)
+	case *CondBreak:
+		fmt.Fprintf(w, "if ")
+		fprint(w, n.Cond)
+		fmt.Fprintf(w, " {\n")
+		if n.InsideCommuteLoop {
+			fmt.Fprintf(w, "continue")
+		} else {
+			fmt.Fprintf(w, "break")
+		}
+		fmt.Fprintf(w, "\n}\n")
+	case ast.Node:
+		printConfig.Fprint(w, emptyFset, n)
+		if _, ok := n.(ast.Stmt); ok {
+			fmt.Fprintln(w)
+		}
+	case StartCommuteLoop:
+		fmt.Fprintf(w, "for _i%[1]d := 0; _i%[1]d <= 1; _i%[1]d, %[2]s_0, %[2]s_1 = _i%[1]d + 1, %[2]s_1, %[2]s_0 {\n", n.Depth, n.V)
+	default:
+		log.Fatalf("cannot print %T", n)
+	}
+}
+
+var printConfig = printer.Config{
+	Mode: printer.RawFormat, // we use go/format later, so skip work here
+}
+
+var emptyFset = token.NewFileSet()
+
+// Node can be a Statement or an ast.Expr.
+type Node interface{}
+
+// Statement can be one of our high-level statement struct types, or an
+// ast.Stmt under some limited circumstances.
+type Statement interface{}
+
+// BodyBase is shared by all of our statement pseudo-node types which can
+// contain other statements.
+type BodyBase struct {
+	List    []Statement
+	CanFail bool
+}
+
+func (w *BodyBase) add(node Statement) {
+	var last Statement
+	if len(w.List) > 0 {
+		last = w.List[len(w.List)-1]
+	}
+	if node, ok := node.(*CondBreak); ok {
+		w.CanFail = true
+		if last, ok := last.(*CondBreak); ok {
+			// Add to the previous "if <cond> { break }" via a
+			// logical OR, which will save verbosity.
+			last.Cond = &ast.BinaryExpr{
+				Op: token.LOR,
+				X:  last.Cond,
+				Y:  node.Cond,
+			}
+			return
+		}
+	}
+
+	w.List = append(w.List, node)
+}
+
+// predeclared contains globally known tokens that should not be redefined.
+var predeclared = map[string]bool{
+	"nil":   true,
+	"false": true,
+	"true":  true,
+}
+
+// declared reports if the body contains a Declare with the given name.
+func (w *BodyBase) declared(name string) bool {
+	if predeclared[name] {
+		// Treat predeclared names as having already been declared.
+		// This lets us use nil to match an aux field or
+		// true and false to match an auxint field.
+		return true
+	}
+	for _, s := range w.List {
+		if decl, ok := s.(*Declare); ok && decl.Name == name {
+			return true
+		}
+	}
+	return false
+}
+
+// These types define some high-level statement struct types, which can be used
+// as a Statement. This allows us to keep some node structs simpler, and have
+// higher-level nodes such as an entire rule rewrite.
+//
+// Note that ast.Expr is always used as-is; we don't declare our own expression
+// nodes.
+type (
+	File struct {
+		BodyBase // []*Func
+		Arch     arch
+		Suffix   string
+	}
+	Func struct {
+		BodyBase
+		Kind   string // "Value" or "Block"
+		Suffix string
+		ArgLen int32 // if kind == "Value", number of args for this op
+	}
+	Switch struct {
+		BodyBase // []*Case
+		Expr     ast.Expr
+	}
+	Case struct {
+		BodyBase
+		Expr ast.Expr
+	}
+	RuleRewrite struct {
+		BodyBase
+		Match, Cond, Result string // top comments
+		Check               string // top-level boolean expression
+
+		Alloc        int    // for unique var names
+		Loc          string // file name & line number of the original rule
+		CommuteDepth int    // used to track depth of commute loops
+	}
+	Declare struct {
+		Name  string
+		Value ast.Expr
+	}
+	CondBreak struct {
+		Cond              ast.Expr
+		InsideCommuteLoop bool
+	}
+	StartCommuteLoop struct {
+		Depth int
+		V     string
+	}
+)
+
+// exprf parses a Go expression generated from fmt.Sprintf, panicking if an
+// error occurs.
+func exprf(format string, a ...interface{}) ast.Expr {
+	src := fmt.Sprintf(format, a...)
+	expr, err := parser.ParseExpr(src)
+	if err != nil {
+		log.Fatalf("expr parse error on %q: %v", src, err)
+	}
+	return expr
+}
+
+// stmtf parses a Go statement generated from fmt.Sprintf. This function is only
+// meant for simple statements that don't have a custom Statement node declared
+// in this package, such as ast.ReturnStmt or ast.ExprStmt.
+func stmtf(format string, a ...interface{}) Statement {
+	src := fmt.Sprintf(format, a...)
+	fsrc := "package p\nfunc _() {\n" + src + "\n}\n"
+	file, err := parser.ParseFile(token.NewFileSet(), "", fsrc, 0)
+	if err != nil {
+		log.Fatalf("stmt parse error on %q: %v", src, err)
+	}
+	return file.Decls[0].(*ast.FuncDecl).Body.List[0]
+}
+
+var reservedNames = map[string]bool{
+	"v":      true, // Values[i], etc
+	"b":      true, // v.Block
+	"config": true, // b.Func.Config
+	"fe":     true, // b.Func.fe
+	"typ":    true, // &b.Func.Config.Types
+}
+
+// declf constructs a simple "name := value" declaration,
+// using exprf for its value.
+//
+// name must not be one of reservedNames.
+// This helps prevent unintended shadowing and name clashes.
+// To declare a reserved name, use declReserved.
+func declf(loc, name, format string, a ...interface{}) *Declare {
+	if reservedNames[name] {
+		log.Fatalf("rule %s uses the reserved name %s", loc, name)
+	}
+	return &Declare{name, exprf(format, a...)}
+}
+
+// declReserved is like declf, but the name must be one of reservedNames.
+// Calls to declReserved should generally be static and top-level.
+func declReserved(name, value string) *Declare {
+	if !reservedNames[name] {
+		panic(fmt.Sprintf("declReserved call does not use a reserved name: %q", name))
+	}
+	return &Declare{name, exprf(value)}
+}
+
+// breakf constructs a simple "if cond { break }" statement, using exprf for its
+// condition.
+func breakf(format string, a ...interface{}) *CondBreak {
+	return &CondBreak{Cond: exprf(format, a...)}
+}
+
+func genBlockRewrite(rule Rule, arch arch, data blockData) *RuleRewrite {
+	rr := &RuleRewrite{Loc: rule.Loc}
+	rr.Match, rr.Cond, rr.Result = rule.parse()
+	_, _, auxint, aux, s := extract(rr.Match) // remove parens, then split
+
+	// check match of control values
+	if len(s) < data.controls {
+		log.Fatalf("incorrect number of arguments in %s, got %v wanted at least %v", rule, len(s), data.controls)
+	}
+	controls := s[:data.controls]
+	pos := make([]string, data.controls)
+	for i, arg := range controls {
+		cname := fmt.Sprintf("b.Controls[%v]", i)
+		if strings.Contains(arg, "(") {
+			vname, expr := splitNameExpr(arg)
+			if vname == "" {
+				vname = fmt.Sprintf("v_%v", i)
+			}
+			rr.add(declf(rr.Loc, vname, cname))
+			p, op := genMatch0(rr, arch, expr, vname, nil, false) // TODO: pass non-nil cnt?
+			if op != "" {
+				check := fmt.Sprintf("%s.Op == %s", cname, op)
+				if rr.Check == "" {
+					rr.Check = check
+				} else {
+					rr.Check += " && " + check
+				}
+			}
+			if p == "" {
+				p = vname + ".Pos"
+			}
+			pos[i] = p
+		} else {
+			rr.add(declf(rr.Loc, arg, cname))
+			pos[i] = arg + ".Pos"
+		}
+	}
+	for _, e := range []struct {
+		name, field, dclType string
+	}{
+		{auxint, "AuxInt", data.auxIntType()},
+		{aux, "Aux", data.auxType()},
+	} {
+		if e.name == "" {
+			continue
+		}
+
+		if e.dclType == "" {
+			log.Fatalf("op %s has no declared type for %s", data.name, e.field)
+		}
+		if !token.IsIdentifier(e.name) || rr.declared(e.name) {
+			rr.add(breakf("%sTo%s(b.%s) != %s", unTitle(e.field), title(e.dclType), e.field, e.name))
+		} else {
+			rr.add(declf(rr.Loc, e.name, "%sTo%s(b.%s)", unTitle(e.field), title(e.dclType), e.field))
+		}
+	}
+	if rr.Cond != "" {
+		rr.add(breakf("!(%s)", rr.Cond))
+	}
+
+	// Rule matches. Generate result.
+	outop, _, auxint, aux, t := extract(rr.Result) // remove parens, then split
+	blockName, outdata := getBlockInfo(outop, arch)
+	if len(t) < outdata.controls {
+		log.Fatalf("incorrect number of output arguments in %s, got %v wanted at least %v", rule, len(s), outdata.controls)
+	}
+
+	// Check if newsuccs is the same set as succs.
+	succs := s[data.controls:]
+	newsuccs := t[outdata.controls:]
+	m := map[string]bool{}
+	for _, succ := range succs {
+		if m[succ] {
+			log.Fatalf("can't have a repeat successor name %s in %s", succ, rule)
+		}
+		m[succ] = true
+	}
+	for _, succ := range newsuccs {
+		if !m[succ] {
+			log.Fatalf("unknown successor %s in %s", succ, rule)
+		}
+		delete(m, succ)
+	}
+	if len(m) != 0 {
+		log.Fatalf("unmatched successors %v in %s", m, rule)
+	}
+
+	var genControls [2]string
+	for i, control := range t[:outdata.controls] {
+		// Select a source position for any new control values.
+		// TODO: does it always make sense to use the source position
+		// of the original control values or should we be using the
+		// block's source position in some cases?
+		newpos := "b.Pos" // default to block's source position
+		if i < len(pos) && pos[i] != "" {
+			// Use the previous control value's source position.
+			newpos = pos[i]
+		}
+
+		// Generate a new control value (or copy an existing value).
+		genControls[i] = genResult0(rr, arch, control, false, false, newpos, nil)
+	}
+	switch outdata.controls {
+	case 0:
+		rr.add(stmtf("b.Reset(%s)", blockName))
+	case 1:
+		rr.add(stmtf("b.resetWithControl(%s, %s)", blockName, genControls[0]))
+	case 2:
+		rr.add(stmtf("b.resetWithControl2(%s, %s, %s)", blockName, genControls[0], genControls[1]))
+	default:
+		log.Fatalf("too many controls: %d", outdata.controls)
+	}
+
+	if auxint != "" {
+		// Make sure auxint value has the right type.
+		rr.add(stmtf("b.AuxInt = %sToAuxInt(%s)", unTitle(outdata.auxIntType()), auxint))
+	}
+	if aux != "" {
+		// Make sure aux value has the right type.
+		rr.add(stmtf("b.Aux = %sToAux(%s)", unTitle(outdata.auxType()), aux))
+	}
+
+	succChanged := false
+	for i := 0; i < len(succs); i++ {
+		if succs[i] != newsuccs[i] {
+			succChanged = true
+		}
+	}
+	if succChanged {
+		if len(succs) != 2 {
+			log.Fatalf("changed successors, len!=2 in %s", rule)
+		}
+		if succs[0] != newsuccs[1] || succs[1] != newsuccs[0] {
+			log.Fatalf("can only handle swapped successors in %s", rule)
+		}
+		rr.add(stmtf("b.swapSuccessors()"))
+	}
+
+	if *genLog {
+		rr.add(stmtf("logRule(%q)", rule.Loc))
+	}
+	return rr
+}
+
+// genMatch returns the variable whose source position should be used for the
+// result (or "" if no opinion), and a boolean that reports whether the match can fail.
+func genMatch(rr *RuleRewrite, arch arch, match string, pregenTop bool) (pos, checkOp string) {
+	cnt := varCount(rr)
+	return genMatch0(rr, arch, match, "v", cnt, pregenTop)
+}
+
+func genMatch0(rr *RuleRewrite, arch arch, match, v string, cnt map[string]int, pregenTop bool) (pos, checkOp string) {
+	if match[0] != '(' || match[len(match)-1] != ')' {
+		log.Fatalf("%s: non-compound expr in genMatch0: %q", rr.Loc, match)
+	}
+	op, oparch, typ, auxint, aux, args := parseValue(match, arch, rr.Loc)
+
+	checkOp = fmt.Sprintf("Op%s%s", oparch, op.name)
+
+	if op.faultOnNilArg0 || op.faultOnNilArg1 {
+		// Prefer the position of an instruction which could fault.
+		pos = v + ".Pos"
+	}
+
+	// If the last argument is ___, it means "don't care about trailing arguments, really"
+	// The likely/intended use is for rewrites that are too tricky to express in the existing pattern language
+	// Do a length check early because long patterns fed short (ultimately not-matching) inputs will
+	// do an indexing error in pattern-matching.
+	if op.argLength == -1 {
+		l := len(args)
+		if l == 0 || args[l-1] != "___" {
+			rr.add(breakf("len(%s.Args) != %d", v, l))
+		} else if l > 1 && args[l-1] == "___" {
+			rr.add(breakf("len(%s.Args) < %d", v, l-1))
+		}
+	}
+
+	for _, e := range []struct {
+		name, field, dclType string
+	}{
+		{typ, "Type", "*types.Type"},
+		{auxint, "AuxInt", op.auxIntType()},
+		{aux, "Aux", op.auxType()},
+	} {
+		if e.name == "" {
+			continue
+		}
+
+		if e.dclType == "" {
+			log.Fatalf("op %s has no declared type for %s", op.name, e.field)
+		}
+		if !token.IsIdentifier(e.name) || rr.declared(e.name) {
+			switch e.field {
+			case "Aux":
+				rr.add(breakf("auxTo%s(%s.%s) != %s", title(e.dclType), v, e.field, e.name))
+			case "AuxInt":
+				rr.add(breakf("auxIntTo%s(%s.%s) != %s", title(e.dclType), v, e.field, e.name))
+			case "Type":
+				rr.add(breakf("%s.%s != %s", v, e.field, e.name))
+			}
+		} else {
+			switch e.field {
+			case "Aux":
+				rr.add(declf(rr.Loc, e.name, "auxTo%s(%s.%s)", title(e.dclType), v, e.field))
+			case "AuxInt":
+				rr.add(declf(rr.Loc, e.name, "auxIntTo%s(%s.%s)", title(e.dclType), v, e.field))
+			case "Type":
+				rr.add(declf(rr.Loc, e.name, "%s.%s", v, e.field))
+			}
+		}
+	}
+
+	commutative := op.commutative
+	if commutative {
+		if args[0] == args[1] {
+			// When we have (Add x x), for any x,
+			// even if there are other uses of x besides these two,
+			// and even if x is not a variable,
+			// we can skip the commutative match.
+			commutative = false
+		}
+		if cnt[args[0]] == 1 && cnt[args[1]] == 1 {
+			// When we have (Add x y) with no other uses
+			// of x and y in the matching rule and condition,
+			// then we can skip the commutative match (Add y x).
+			commutative = false
+		}
+	}
+
+	if !pregenTop {
+		// Access last argument first to minimize bounds checks.
+		for n := len(args) - 1; n > 0; n-- {
+			a := args[n]
+			if a == "_" {
+				continue
+			}
+			if !rr.declared(a) && token.IsIdentifier(a) && !(commutative && len(args) == 2) {
+				rr.add(declf(rr.Loc, a, "%s.Args[%d]", v, n))
+				// delete the last argument so it is not reprocessed
+				args = args[:n]
+			} else {
+				rr.add(stmtf("_ = %s.Args[%d]", v, n))
+			}
+			break
+		}
+	}
+	if commutative && !pregenTop {
+		for i := 0; i <= 1; i++ {
+			vname := fmt.Sprintf("%s_%d", v, i)
+			rr.add(declf(rr.Loc, vname, "%s.Args[%d]", v, i))
+		}
+	}
+	if commutative {
+		rr.add(StartCommuteLoop{rr.CommuteDepth, v})
+		rr.CommuteDepth++
+	}
+	for i, arg := range args {
+		if arg == "_" {
+			continue
+		}
+		var rhs string
+		if (commutative && i < 2) || pregenTop {
+			rhs = fmt.Sprintf("%s_%d", v, i)
+		} else {
+			rhs = fmt.Sprintf("%s.Args[%d]", v, i)
+		}
+		if !strings.Contains(arg, "(") {
+			// leaf variable
+			if rr.declared(arg) {
+				// variable already has a definition. Check whether
+				// the old definition and the new definition match.
+				// For example, (add x x).  Equality is just pointer equality
+				// on Values (so cse is important to do before lowering).
+				rr.add(breakf("%s != %s", arg, rhs))
+			} else {
+				if arg != rhs {
+					rr.add(declf(rr.Loc, arg, "%s", rhs))
+				}
+			}
+			continue
+		}
+		// compound sexpr
+		argname, expr := splitNameExpr(arg)
+		if argname == "" {
+			argname = fmt.Sprintf("%s_%d", v, i)
+		}
+		if argname == "b" {
+			log.Fatalf("don't name args 'b', it is ambiguous with blocks")
+		}
+
+		if argname != rhs {
+			rr.add(declf(rr.Loc, argname, "%s", rhs))
+		}
+		bexpr := exprf("%s.Op != addLater", argname)
+		rr.add(&CondBreak{Cond: bexpr})
+		argPos, argCheckOp := genMatch0(rr, arch, expr, argname, cnt, false)
+		bexpr.(*ast.BinaryExpr).Y.(*ast.Ident).Name = argCheckOp
+
+		if argPos != "" {
+			// Keep the argument in preference to the parent, as the
+			// argument is normally earlier in program flow.
+			// Keep the argument in preference to an earlier argument,
+			// as that prefers the memory argument which is also earlier
+			// in the program flow.
+			pos = argPos
+		}
+	}
+
+	return pos, checkOp
+}
+
+func genResult(rr *RuleRewrite, arch arch, result, pos string) {
+	move := result[0] == '@'
+	if move {
+		// parse @block directive
+		s := strings.SplitN(result[1:], " ", 2)
+		rr.add(stmtf("b = %s", s[0]))
+		result = s[1]
+	}
+	cse := make(map[string]string)
+	genResult0(rr, arch, result, true, move, pos, cse)
+}
+
+func genResult0(rr *RuleRewrite, arch arch, result string, top, move bool, pos string, cse map[string]string) string {
+	resname, expr := splitNameExpr(result)
+	result = expr
+	// TODO: when generating a constant result, use f.constVal to avoid
+	// introducing copies just to clean them up again.
+	if result[0] != '(' {
+		// variable
+		if top {
+			// It in not safe in general to move a variable between blocks
+			// (and particularly not a phi node).
+			// Introduce a copy.
+			rr.add(stmtf("v.copyOf(%s)", result))
+		}
+		return result
+	}
+
+	w := normalizeWhitespace(result)
+	if prev := cse[w]; prev != "" {
+		return prev
+	}
+
+	op, oparch, typ, auxint, aux, args := parseValue(result, arch, rr.Loc)
+
+	// Find the type of the variable.
+	typeOverride := typ != ""
+	if typ == "" && op.typ != "" {
+		typ = typeName(op.typ)
+	}
+
+	v := "v"
+	if top && !move {
+		rr.add(stmtf("v.reset(Op%s%s)", oparch, op.name))
+		if typeOverride {
+			rr.add(stmtf("v.Type = %s", typ))
+		}
+	} else {
+		if typ == "" {
+			log.Fatalf("sub-expression %s (op=Op%s%s) at %s must have a type", result, oparch, op.name, rr.Loc)
+		}
+		if resname == "" {
+			v = fmt.Sprintf("v%d", rr.Alloc)
+		} else {
+			v = resname
+		}
+		rr.Alloc++
+		rr.add(declf(rr.Loc, v, "b.NewValue0(%s, Op%s%s, %s)", pos, oparch, op.name, typ))
+		if move && top {
+			// Rewrite original into a copy
+			rr.add(stmtf("v.copyOf(%s)", v))
+		}
+	}
+
+	if auxint != "" {
+		// Make sure auxint value has the right type.
+		rr.add(stmtf("%s.AuxInt = %sToAuxInt(%s)", v, unTitle(op.auxIntType()), auxint))
+	}
+	if aux != "" {
+		// Make sure aux value has the right type.
+		rr.add(stmtf("%s.Aux = %sToAux(%s)", v, unTitle(op.auxType()), aux))
+	}
+	all := new(strings.Builder)
+	for i, arg := range args {
+		x := genResult0(rr, arch, arg, false, move, pos, cse)
+		if i > 0 {
+			all.WriteString(", ")
+		}
+		all.WriteString(x)
+	}
+	switch len(args) {
+	case 0:
+	case 1:
+		rr.add(stmtf("%s.AddArg(%s)", v, all.String()))
+	default:
+		rr.add(stmtf("%s.AddArg%d(%s)", v, len(args), all.String()))
+	}
+
+	if cse != nil {
+		cse[w] = v
+	}
+	return v
+}
+
+func split(s string) []string {
+	var r []string
+
+outer:
+	for s != "" {
+		d := 0               // depth of ({[<
+		var open, close byte // opening and closing markers ({[< or )}]>
+		nonsp := false       // found a non-space char so far
+		for i := 0; i < len(s); i++ {
+			switch {
+			case d == 0 && s[i] == '(':
+				open, close = '(', ')'
+				d++
+			case d == 0 && s[i] == '<':
+				open, close = '<', '>'
+				d++
+			case d == 0 && s[i] == '[':
+				open, close = '[', ']'
+				d++
+			case d == 0 && s[i] == '{':
+				open, close = '{', '}'
+				d++
+			case d == 0 && (s[i] == ' ' || s[i] == '\t'):
+				if nonsp {
+					r = append(r, strings.TrimSpace(s[:i]))
+					s = s[i:]
+					continue outer
+				}
+			case d > 0 && s[i] == open:
+				d++
+			case d > 0 && s[i] == close:
+				d--
+			default:
+				nonsp = true
+			}
+		}
+		if d != 0 {
+			log.Fatalf("imbalanced expression: %q", s)
+		}
+		if nonsp {
+			r = append(r, strings.TrimSpace(s))
+		}
+		break
+	}
+	return r
+}
+
+// isBlock reports whether this op is a block opcode.
+func isBlock(name string, arch arch) bool {
+	for _, b := range genericBlocks {
+		if b.name == name {
+			return true
+		}
+	}
+	for _, b := range arch.blocks {
+		if b.name == name {
+			return true
+		}
+	}
+	return false
+}
+
+func extract(val string) (op, typ, auxint, aux string, args []string) {
+	val = val[1 : len(val)-1] // remove ()
+
+	// Split val up into regions.
+	// Split by spaces/tabs, except those contained in (), {}, [], or <>.
+	s := split(val)
+
+	// Extract restrictions and args.
+	op = s[0]
+	for _, a := range s[1:] {
+		switch a[0] {
+		case '<':
+			typ = a[1 : len(a)-1] // remove <>
+		case '[':
+			auxint = a[1 : len(a)-1] // remove []
+		case '{':
+			aux = a[1 : len(a)-1] // remove {}
+		default:
+			args = append(args, a)
+		}
+	}
+	return
+}
+
+// parseValue parses a parenthesized value from a rule.
+// The value can be from the match or the result side.
+// It returns the op and unparsed strings for typ, auxint, and aux restrictions and for all args.
+// oparch is the architecture that op is located in, or "" for generic.
+func parseValue(val string, arch arch, loc string) (op opData, oparch, typ, auxint, aux string, args []string) {
+	// Resolve the op.
+	var s string
+	s, typ, auxint, aux, args = extract(val)
+
+	// match reports whether x is a good op to select.
+	// If strict is true, rule generation might succeed.
+	// If strict is false, rule generation has failed,
+	// but we're trying to generate a useful error.
+	// Doing strict=true then strict=false allows
+	// precise op matching while retaining good error messages.
+	match := func(x opData, strict bool, archname string) bool {
+		if x.name != s {
+			return false
+		}
+		if x.argLength != -1 && int(x.argLength) != len(args) && (len(args) != 1 || args[0] != "...") {
+			if strict {
+				return false
+			}
+			log.Printf("%s: op %s (%s) should have %d args, has %d", loc, s, archname, x.argLength, len(args))
+		}
+		return true
+	}
+
+	for _, x := range genericOps {
+		if match(x, true, "generic") {
+			op = x
+			break
+		}
+	}
+	for _, x := range arch.ops {
+		if arch.name != "generic" && match(x, true, arch.name) {
+			if op.name != "" {
+				log.Fatalf("%s: matches for op %s found in both generic and %s", loc, op.name, arch.name)
+			}
+			op = x
+			oparch = arch.name
+			break
+		}
+	}
+
+	if op.name == "" {
+		// Failed to find the op.
+		// Run through everything again with strict=false
+		// to generate useful diagnosic messages before failing.
+		for _, x := range genericOps {
+			match(x, false, "generic")
+		}
+		for _, x := range arch.ops {
+			match(x, false, arch.name)
+		}
+		log.Fatalf("%s: unknown op %s", loc, s)
+	}
+
+	// Sanity check aux, auxint.
+	if auxint != "" && !opHasAuxInt(op) {
+		log.Fatalf("%s: op %s %s can't have auxint", loc, op.name, op.aux)
+	}
+	if aux != "" && !opHasAux(op) {
+		log.Fatalf("%s: op %s %s can't have aux", loc, op.name, op.aux)
+	}
+	return
+}
+
+func opHasAuxInt(op opData) bool {
+	switch op.aux {
+	case "Bool", "Int8", "Int16", "Int32", "Int64", "Int128", "UInt8", "Float32", "Float64",
+		"SymOff", "CallOff", "SymValAndOff", "TypSize", "ARM64BitField", "FlagConstant", "CCop":
+		return true
+	}
+	return false
+}
+
+func opHasAux(op opData) bool {
+	switch op.aux {
+	case "String", "Sym", "SymOff", "Call", "CallOff", "SymValAndOff", "Typ", "TypSize",
+		"S390XCCMask", "S390XRotateParams":
+		return true
+	}
+	return false
+}
+
+// splitNameExpr splits s-expr arg, possibly prefixed by "name:",
+// into name and the unprefixed expression.
+// For example, "x:(Foo)" yields "x", "(Foo)",
+// and "(Foo)" yields "", "(Foo)".
+func splitNameExpr(arg string) (name, expr string) {
+	colon := strings.Index(arg, ":")
+	if colon < 0 {
+		return "", arg
+	}
+	openparen := strings.Index(arg, "(")
+	if openparen < 0 {
+		log.Fatalf("splitNameExpr(%q): colon but no open parens", arg)
+	}
+	if colon > openparen {
+		// colon is inside the parens, such as in "(Foo x:(Bar))".
+		return "", arg
+	}
+	return arg[:colon], arg[colon+1:]
+}
+
+func getBlockInfo(op string, arch arch) (name string, data blockData) {
+	for _, b := range genericBlocks {
+		if b.name == op {
+			return "Block" + op, b
+		}
+	}
+	for _, b := range arch.blocks {
+		if b.name == op {
+			return "Block" + arch.name + op, b
+		}
+	}
+	log.Fatalf("could not find block data for %s", op)
+	panic("unreachable")
+}
+
+// typeName returns the string to use to generate a type.
+func typeName(typ string) string {
+	if typ[0] == '(' {
+		ts := strings.Split(typ[1:len(typ)-1], ",")
+		if len(ts) != 2 {
+			log.Fatalf("Tuple expect 2 arguments")
+		}
+		return "types.NewTuple(" + typeName(ts[0]) + ", " + typeName(ts[1]) + ")"
+	}
+	switch typ {
+	case "Flags", "Mem", "Void", "Int128":
+		return "types.Type" + typ
+	default:
+		return "typ." + typ
+	}
+}
+
+// balance returns the number of unclosed '(' characters in s.
+// If a ')' appears without a corresponding '(', balance returns -1.
+func balance(s string) int {
+	balance := 0
+	for _, c := range s {
+		switch c {
+		case '(':
+			balance++
+		case ')':
+			balance--
+			if balance < 0 {
+				// don't allow ")(" to return 0
+				return -1
+			}
+		}
+	}
+	return balance
+}
+
+// findAllOpcode is a function to find the opcode portion of s-expressions.
+var findAllOpcode = regexp.MustCompile(`[(](\w+[|])+\w+[)]`).FindAllStringIndex
+
+// excludeFromExpansion reports whether the substring s[idx[0]:idx[1]] in a rule
+// should be disregarded as a candidate for | expansion.
+// It uses simple syntactic checks to see whether the substring
+// is inside an AuxInt expression or inside the && conditions.
+func excludeFromExpansion(s string, idx []int) bool {
+	left := s[:idx[0]]
+	if strings.LastIndexByte(left, '[') > strings.LastIndexByte(left, ']') {
+		// Inside an AuxInt expression.
+		return true
+	}
+	right := s[idx[1]:]
+	if strings.Contains(left, "&&") && strings.Contains(right, "=>") {
+		// Inside && conditions.
+		return true
+	}
+	return false
+}
+
+// expandOr converts a rule into multiple rules by expanding | ops.
+func expandOr(r string) []string {
+	// Find every occurrence of |-separated things.
+	// They look like MOV(B|W|L|Q|SS|SD)load or MOV(Q|L)loadidx(1|8).
+	// Generate rules selecting one case from each |-form.
+
+	// Count width of |-forms.  They must match.
+	n := 1
+	for _, idx := range findAllOpcode(r, -1) {
+		if excludeFromExpansion(r, idx) {
+			continue
+		}
+		s := r[idx[0]:idx[1]]
+		c := strings.Count(s, "|") + 1
+		if c == 1 {
+			continue
+		}
+		if n > 1 && n != c {
+			log.Fatalf("'|' count doesn't match in %s: both %d and %d\n", r, n, c)
+		}
+		n = c
+	}
+	if n == 1 {
+		// No |-form in this rule.
+		return []string{r}
+	}
+	// Build each new rule.
+	res := make([]string, n)
+	for i := 0; i < n; i++ {
+		buf := new(strings.Builder)
+		x := 0
+		for _, idx := range findAllOpcode(r, -1) {
+			if excludeFromExpansion(r, idx) {
+				continue
+			}
+			buf.WriteString(r[x:idx[0]])              // write bytes we've skipped over so far
+			s := r[idx[0]+1 : idx[1]-1]               // remove leading "(" and trailing ")"
+			buf.WriteString(strings.Split(s, "|")[i]) // write the op component for this rule
+			x = idx[1]                                // note that we've written more bytes
+		}
+		buf.WriteString(r[x:])
+		res[i] = buf.String()
+	}
+	return res
+}
+
+// varCount returns a map which counts the number of occurrences of
+// Value variables in the s-expression rr.Match and the Go expression rr.Cond.
+func varCount(rr *RuleRewrite) map[string]int {
+	cnt := map[string]int{}
+	varCount1(rr.Loc, rr.Match, cnt)
+	if rr.Cond != "" {
+		expr, err := parser.ParseExpr(rr.Cond)
+		if err != nil {
+			log.Fatalf("%s: failed to parse cond %q: %v", rr.Loc, rr.Cond, err)
+		}
+		ast.Inspect(expr, func(n ast.Node) bool {
+			if id, ok := n.(*ast.Ident); ok {
+				cnt[id.Name]++
+			}
+			return true
+		})
+	}
+	return cnt
+}
+
+func varCount1(loc, m string, cnt map[string]int) {
+	if m[0] == '<' || m[0] == '[' || m[0] == '{' {
+		return
+	}
+	if token.IsIdentifier(m) {
+		cnt[m]++
+		return
+	}
+	// Split up input.
+	name, expr := splitNameExpr(m)
+	if name != "" {
+		cnt[name]++
+	}
+	if expr[0] != '(' || expr[len(expr)-1] != ')' {
+		log.Fatalf("%s: non-compound expr in varCount1: %q", loc, expr)
+	}
+	s := split(expr[1 : len(expr)-1])
+	for _, arg := range s[1:] {
+		varCount1(loc, arg, cnt)
+	}
+}
+
+// normalizeWhitespace replaces 2+ whitespace sequences with a single space.
+func normalizeWhitespace(x string) string {
+	x = strings.Join(strings.Fields(x), " ")
+	x = strings.Replace(x, "( ", "(", -1)
+	x = strings.Replace(x, " )", ")", -1)
+	x = strings.Replace(x, "[ ", "[", -1)
+	x = strings.Replace(x, " ]", "]", -1)
+	x = strings.Replace(x, ")=>", ") =>", -1)
+	return x
+}
+
+// opIsCommutative reports whether op s is commutative.
+func opIsCommutative(op string, arch arch) bool {
+	for _, x := range genericOps {
+		if op == x.name {
+			if x.commutative {
+				return true
+			}
+			break
+		}
+	}
+	if arch.name != "generic" {
+		for _, x := range arch.ops {
+			if op == x.name {
+				if x.commutative {
+					return true
+				}
+				break
+			}
+		}
+	}
+	return false
+}
+
+func normalizeMatch(m string, arch arch) string {
+	if token.IsIdentifier(m) {
+		return m
+	}
+	op, typ, auxint, aux, args := extract(m)
+	if opIsCommutative(op, arch) {
+		if args[1] < args[0] {
+			args[0], args[1] = args[1], args[0]
+		}
+	}
+	s := new(strings.Builder)
+	fmt.Fprintf(s, "%s <%s> [%s] {%s}", op, typ, auxint, aux)
+	for _, arg := range args {
+		prefix, expr := splitNameExpr(arg)
+		fmt.Fprint(s, " ", prefix, normalizeMatch(expr, arch))
+	}
+	return s.String()
+}
+
+func parseEllipsisRules(rules []Rule, arch arch) (newop string, ok bool) {
+	if len(rules) != 1 {
+		for _, r := range rules {
+			if strings.Contains(r.Rule, "...") {
+				log.Fatalf("%s: found ellipsis in rule, but there are other rules with the same op", r.Loc)
+			}
+		}
+		return "", false
+	}
+	rule := rules[0]
+	match, cond, result := rule.parse()
+	if cond != "" || !isEllipsisValue(match) || !isEllipsisValue(result) {
+		if strings.Contains(rule.Rule, "...") {
+			log.Fatalf("%s: found ellipsis in non-ellipsis rule", rule.Loc)
+		}
+		checkEllipsisRuleCandidate(rule, arch)
+		return "", false
+	}
+	op, oparch, _, _, _, _ := parseValue(result, arch, rule.Loc)
+	return fmt.Sprintf("Op%s%s", oparch, op.name), true
+}
+
+// isEllipsisValue reports whether s is of the form (OpX ...).
+func isEllipsisValue(s string) bool {
+	if len(s) < 2 || s[0] != '(' || s[len(s)-1] != ')' {
+		return false
+	}
+	c := split(s[1 : len(s)-1])
+	if len(c) != 2 || c[1] != "..." {
+		return false
+	}
+	return true
+}
+
+func checkEllipsisRuleCandidate(rule Rule, arch arch) {
+	match, cond, result := rule.parse()
+	if cond != "" {
+		return
+	}
+	op, _, _, auxint, aux, args := parseValue(match, arch, rule.Loc)
+	var auxint2, aux2 string
+	var args2 []string
+	var usingCopy string
+	var eop opData
+	if result[0] != '(' {
+		// Check for (Foo x) => x, which can be converted to (Foo ...) => (Copy ...).
+		args2 = []string{result}
+		usingCopy = " using Copy"
+	} else {
+		eop, _, _, auxint2, aux2, args2 = parseValue(result, arch, rule.Loc)
+	}
+	// Check that all restrictions in match are reproduced exactly in result.
+	if aux != aux2 || auxint != auxint2 || len(args) != len(args2) {
+		return
+	}
+	if strings.Contains(rule.Rule, "=>") && op.aux != eop.aux {
+		return
+	}
+	for i := range args {
+		if args[i] != args2[i] {
+			return
+		}
+	}
+	switch {
+	case opHasAux(op) && aux == "" && aux2 == "":
+		fmt.Printf("%s: rule silently zeros aux, either copy aux or explicitly zero\n", rule.Loc)
+	case opHasAuxInt(op) && auxint == "" && auxint2 == "":
+		fmt.Printf("%s: rule silently zeros auxint, either copy auxint or explicitly zero\n", rule.Loc)
+	default:
+		fmt.Printf("%s: possible ellipsis rule candidate%s: %q\n", rule.Loc, usingCopy, rule.Rule)
+	}
+}
+
+func opByName(arch arch, name string) opData {
+	name = name[2:]
+	for _, x := range genericOps {
+		if name == x.name {
+			return x
+		}
+	}
+	if arch.name != "generic" {
+		name = name[len(arch.name):]
+		for _, x := range arch.ops {
+			if name == x.name {
+				return x
+			}
+		}
+	}
+	log.Fatalf("failed to find op named %s in arch %s", name, arch.name)
+	panic("unreachable")
+}
+
+// auxType returns the Go type that this operation should store in its aux field.
+func (op opData) auxType() string {
+	switch op.aux {
+	case "String":
+		return "string"
+	case "Sym":
+		// Note: a Sym can be an *obj.LSym, a *gc.Node, or nil.
+		return "Sym"
+	case "SymOff":
+		return "Sym"
+	case "Call":
+		return "Call"
+	case "CallOff":
+		return "Call"
+	case "SymValAndOff":
+		return "Sym"
+	case "Typ":
+		return "*types.Type"
+	case "TypSize":
+		return "*types.Type"
+	case "S390XCCMask":
+		return "s390x.CCMask"
+	case "S390XRotateParams":
+		return "s390x.RotateParams"
+	default:
+		return "invalid"
+	}
+}
+
+// auxIntType returns the Go type that this operation should store in its auxInt field.
+func (op opData) auxIntType() string {
+	switch op.aux {
+	case "Bool":
+		return "bool"
+	case "Int8":
+		return "int8"
+	case "Int16":
+		return "int16"
+	case "Int32":
+		return "int32"
+	case "Int64":
+		return "int64"
+	case "Int128":
+		return "int128"
+	case "UInt8":
+		return "uint8"
+	case "Float32":
+		return "float32"
+	case "Float64":
+		return "float64"
+	case "CallOff":
+		return "int32"
+	case "SymOff":
+		return "int32"
+	case "SymValAndOff":
+		return "ValAndOff"
+	case "TypSize":
+		return "int64"
+	case "CCop":
+		return "Op"
+	case "FlagConstant":
+		return "flagConstant"
+	case "ARM64BitField":
+		return "arm64BitField"
+	default:
+		return "invalid"
+	}
+}
+
+// auxType returns the Go type that this block should store in its aux field.
+func (b blockData) auxType() string {
+	switch b.aux {
+	case "Sym":
+		return "Sym"
+	case "S390XCCMask", "S390XCCMaskInt8", "S390XCCMaskUint8":
+		return "s390x.CCMask"
+	case "S390XRotateParams":
+		return "s390x.RotateParams"
+	default:
+		return "invalid"
+	}
+}
+
+// auxIntType returns the Go type that this block should store in its auxInt field.
+func (b blockData) auxIntType() string {
+	switch b.aux {
+	case "S390XCCMaskInt8":
+		return "int8"
+	case "S390XCCMaskUint8":
+		return "uint8"
+	case "Int64":
+		return "int64"
+	default:
+		return "invalid"
+	}
+}
+
+func title(s string) string {
+	if i := strings.Index(s, "."); i >= 0 {
+		switch strings.ToLower(s[:i]) {
+		case "s390x": // keep arch prefix for clarity
+			s = s[:i] + s[i+1:]
+		default:
+			s = s[i+1:]
+		}
+	}
+	return strings.Title(s)
+}
+
+func unTitle(s string) string {
+	if i := strings.Index(s, "."); i >= 0 {
+		switch strings.ToLower(s[:i]) {
+		case "s390x": // keep arch prefix for clarity
+			s = s[:i] + s[i+1:]
+		default:
+			s = s[i+1:]
+		}
+	}
+	return strings.ToLower(s[:1]) + s[1:]
+}
diff --git a/src/cmd/compile/internal/ssa/addressingmodes.go b/src/cmd/compile/internal/ssa/addressingmodes.go
index 469ba0d..699f6e4 100644
--- a/src/cmd/compile/internal/ssa/addressingmodes.go
+++ b/src/cmd/compile/internal/ssa/addressingmodes.go
@@ -196,7 +196,7 @@
 	[2]Op{OpAMD64MOVQstoreconst, OpAMD64LEAQ8}: OpAMD64MOVQstoreconstidx8,
 
 	// These instructions are re-split differently for performance, see needSplit above.
-	// TODO if 386 versions are created, also update needSplit and gen/386splitload.rules
+	// TODO if 386 versions are created, also update needSplit and _gen/386splitload.rules
 	[2]Op{OpAMD64CMPBload, OpAMD64ADDQ}: OpAMD64CMPBloadidx1,
 	[2]Op{OpAMD64CMPWload, OpAMD64ADDQ}: OpAMD64CMPWloadidx1,
 	[2]Op{OpAMD64CMPLload, OpAMD64ADDQ}: OpAMD64CMPLloadidx1,
diff --git a/src/cmd/compile/internal/ssa/allocators.go b/src/cmd/compile/internal/ssa/allocators.go
new file mode 100644
index 0000000..7cd7cad
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/allocators.go
@@ -0,0 +1,343 @@
+// Code generated from _gen/allocators.go; DO NOT EDIT.
+
+package ssa
+
+import (
+	"math/bits"
+	"sync"
+)
+
+var poolFreeValueSlice [27]sync.Pool
+
+func (c *Cache) allocValueSlice(n int) []*Value {
+	var s []*Value
+	n2 := n
+	if n2 < 32 {
+		n2 = 32
+	}
+	b := bits.Len(uint(n2 - 1))
+	v := poolFreeValueSlice[b-5].Get()
+	if v == nil {
+		s = make([]*Value, 1<<b)
+	} else {
+		sp := v.(*[]*Value)
+		s = *sp
+		*sp = nil
+		c.hdrValueSlice = append(c.hdrValueSlice, sp)
+	}
+	s = s[:n]
+	return s
+}
+func (c *Cache) freeValueSlice(s []*Value) {
+	for i := range s {
+		s[i] = nil
+	}
+	b := bits.Len(uint(cap(s)) - 1)
+	var sp *[]*Value
+	if len(c.hdrValueSlice) == 0 {
+		sp = new([]*Value)
+	} else {
+		sp = c.hdrValueSlice[len(c.hdrValueSlice)-1]
+		c.hdrValueSlice[len(c.hdrValueSlice)-1] = nil
+		c.hdrValueSlice = c.hdrValueSlice[:len(c.hdrValueSlice)-1]
+	}
+	*sp = s
+	poolFreeValueSlice[b-5].Put(sp)
+}
+
+var poolFreeBlockSlice [27]sync.Pool
+
+func (c *Cache) allocBlockSlice(n int) []*Block {
+	var s []*Block
+	n2 := n
+	if n2 < 32 {
+		n2 = 32
+	}
+	b := bits.Len(uint(n2 - 1))
+	v := poolFreeBlockSlice[b-5].Get()
+	if v == nil {
+		s = make([]*Block, 1<<b)
+	} else {
+		sp := v.(*[]*Block)
+		s = *sp
+		*sp = nil
+		c.hdrBlockSlice = append(c.hdrBlockSlice, sp)
+	}
+	s = s[:n]
+	return s
+}
+func (c *Cache) freeBlockSlice(s []*Block) {
+	for i := range s {
+		s[i] = nil
+	}
+	b := bits.Len(uint(cap(s)) - 1)
+	var sp *[]*Block
+	if len(c.hdrBlockSlice) == 0 {
+		sp = new([]*Block)
+	} else {
+		sp = c.hdrBlockSlice[len(c.hdrBlockSlice)-1]
+		c.hdrBlockSlice[len(c.hdrBlockSlice)-1] = nil
+		c.hdrBlockSlice = c.hdrBlockSlice[:len(c.hdrBlockSlice)-1]
+	}
+	*sp = s
+	poolFreeBlockSlice[b-5].Put(sp)
+}
+
+var poolFreeBoolSlice [24]sync.Pool
+
+func (c *Cache) allocBoolSlice(n int) []bool {
+	var s []bool
+	n2 := n
+	if n2 < 256 {
+		n2 = 256
+	}
+	b := bits.Len(uint(n2 - 1))
+	v := poolFreeBoolSlice[b-8].Get()
+	if v == nil {
+		s = make([]bool, 1<<b)
+	} else {
+		sp := v.(*[]bool)
+		s = *sp
+		*sp = nil
+		c.hdrBoolSlice = append(c.hdrBoolSlice, sp)
+	}
+	s = s[:n]
+	return s
+}
+func (c *Cache) freeBoolSlice(s []bool) {
+	for i := range s {
+		s[i] = false
+	}
+	b := bits.Len(uint(cap(s)) - 1)
+	var sp *[]bool
+	if len(c.hdrBoolSlice) == 0 {
+		sp = new([]bool)
+	} else {
+		sp = c.hdrBoolSlice[len(c.hdrBoolSlice)-1]
+		c.hdrBoolSlice[len(c.hdrBoolSlice)-1] = nil
+		c.hdrBoolSlice = c.hdrBoolSlice[:len(c.hdrBoolSlice)-1]
+	}
+	*sp = s
+	poolFreeBoolSlice[b-8].Put(sp)
+}
+
+var poolFreeIntSlice [27]sync.Pool
+
+func (c *Cache) allocIntSlice(n int) []int {
+	var s []int
+	n2 := n
+	if n2 < 32 {
+		n2 = 32
+	}
+	b := bits.Len(uint(n2 - 1))
+	v := poolFreeIntSlice[b-5].Get()
+	if v == nil {
+		s = make([]int, 1<<b)
+	} else {
+		sp := v.(*[]int)
+		s = *sp
+		*sp = nil
+		c.hdrIntSlice = append(c.hdrIntSlice, sp)
+	}
+	s = s[:n]
+	return s
+}
+func (c *Cache) freeIntSlice(s []int) {
+	for i := range s {
+		s[i] = 0
+	}
+	b := bits.Len(uint(cap(s)) - 1)
+	var sp *[]int
+	if len(c.hdrIntSlice) == 0 {
+		sp = new([]int)
+	} else {
+		sp = c.hdrIntSlice[len(c.hdrIntSlice)-1]
+		c.hdrIntSlice[len(c.hdrIntSlice)-1] = nil
+		c.hdrIntSlice = c.hdrIntSlice[:len(c.hdrIntSlice)-1]
+	}
+	*sp = s
+	poolFreeIntSlice[b-5].Put(sp)
+}
+
+var poolFreeInt32Slice [26]sync.Pool
+
+func (c *Cache) allocInt32Slice(n int) []int32 {
+	var s []int32
+	n2 := n
+	if n2 < 64 {
+		n2 = 64
+	}
+	b := bits.Len(uint(n2 - 1))
+	v := poolFreeInt32Slice[b-6].Get()
+	if v == nil {
+		s = make([]int32, 1<<b)
+	} else {
+		sp := v.(*[]int32)
+		s = *sp
+		*sp = nil
+		c.hdrInt32Slice = append(c.hdrInt32Slice, sp)
+	}
+	s = s[:n]
+	return s
+}
+func (c *Cache) freeInt32Slice(s []int32) {
+	for i := range s {
+		s[i] = 0
+	}
+	b := bits.Len(uint(cap(s)) - 1)
+	var sp *[]int32
+	if len(c.hdrInt32Slice) == 0 {
+		sp = new([]int32)
+	} else {
+		sp = c.hdrInt32Slice[len(c.hdrInt32Slice)-1]
+		c.hdrInt32Slice[len(c.hdrInt32Slice)-1] = nil
+		c.hdrInt32Slice = c.hdrInt32Slice[:len(c.hdrInt32Slice)-1]
+	}
+	*sp = s
+	poolFreeInt32Slice[b-6].Put(sp)
+}
+
+var poolFreeInt8Slice [24]sync.Pool
+
+func (c *Cache) allocInt8Slice(n int) []int8 {
+	var s []int8
+	n2 := n
+	if n2 < 256 {
+		n2 = 256
+	}
+	b := bits.Len(uint(n2 - 1))
+	v := poolFreeInt8Slice[b-8].Get()
+	if v == nil {
+		s = make([]int8, 1<<b)
+	} else {
+		sp := v.(*[]int8)
+		s = *sp
+		*sp = nil
+		c.hdrInt8Slice = append(c.hdrInt8Slice, sp)
+	}
+	s = s[:n]
+	return s
+}
+func (c *Cache) freeInt8Slice(s []int8) {
+	for i := range s {
+		s[i] = 0
+	}
+	b := bits.Len(uint(cap(s)) - 1)
+	var sp *[]int8
+	if len(c.hdrInt8Slice) == 0 {
+		sp = new([]int8)
+	} else {
+		sp = c.hdrInt8Slice[len(c.hdrInt8Slice)-1]
+		c.hdrInt8Slice[len(c.hdrInt8Slice)-1] = nil
+		c.hdrInt8Slice = c.hdrInt8Slice[:len(c.hdrInt8Slice)-1]
+	}
+	*sp = s
+	poolFreeInt8Slice[b-8].Put(sp)
+}
+
+var poolFreeIDSlice [26]sync.Pool
+
+func (c *Cache) allocIDSlice(n int) []ID {
+	var s []ID
+	n2 := n
+	if n2 < 64 {
+		n2 = 64
+	}
+	b := bits.Len(uint(n2 - 1))
+	v := poolFreeIDSlice[b-6].Get()
+	if v == nil {
+		s = make([]ID, 1<<b)
+	} else {
+		sp := v.(*[]ID)
+		s = *sp
+		*sp = nil
+		c.hdrIDSlice = append(c.hdrIDSlice, sp)
+	}
+	s = s[:n]
+	return s
+}
+func (c *Cache) freeIDSlice(s []ID) {
+	for i := range s {
+		s[i] = 0
+	}
+	b := bits.Len(uint(cap(s)) - 1)
+	var sp *[]ID
+	if len(c.hdrIDSlice) == 0 {
+		sp = new([]ID)
+	} else {
+		sp = c.hdrIDSlice[len(c.hdrIDSlice)-1]
+		c.hdrIDSlice[len(c.hdrIDSlice)-1] = nil
+		c.hdrIDSlice = c.hdrIDSlice[:len(c.hdrIDSlice)-1]
+	}
+	*sp = s
+	poolFreeIDSlice[b-6].Put(sp)
+}
+
+var poolFreeSparseSet [27]sync.Pool
+
+func (c *Cache) allocSparseSet(n int) *sparseSet {
+	var s *sparseSet
+	n2 := n
+	if n2 < 32 {
+		n2 = 32
+	}
+	b := bits.Len(uint(n2 - 1))
+	v := poolFreeSparseSet[b-5].Get()
+	if v == nil {
+		s = newSparseSet(1 << b)
+	} else {
+		s = v.(*sparseSet)
+	}
+	return s
+}
+func (c *Cache) freeSparseSet(s *sparseSet) {
+	s.clear()
+	b := bits.Len(uint(s.cap()) - 1)
+	poolFreeSparseSet[b-5].Put(s)
+}
+
+var poolFreeSparseMap [27]sync.Pool
+
+func (c *Cache) allocSparseMap(n int) *sparseMap {
+	var s *sparseMap
+	n2 := n
+	if n2 < 32 {
+		n2 = 32
+	}
+	b := bits.Len(uint(n2 - 1))
+	v := poolFreeSparseMap[b-5].Get()
+	if v == nil {
+		s = newSparseMap(1 << b)
+	} else {
+		s = v.(*sparseMap)
+	}
+	return s
+}
+func (c *Cache) freeSparseMap(s *sparseMap) {
+	s.clear()
+	b := bits.Len(uint(s.cap()) - 1)
+	poolFreeSparseMap[b-5].Put(s)
+}
+
+var poolFreeSparseMapPos [27]sync.Pool
+
+func (c *Cache) allocSparseMapPos(n int) *sparseMapPos {
+	var s *sparseMapPos
+	n2 := n
+	if n2 < 32 {
+		n2 = 32
+	}
+	b := bits.Len(uint(n2 - 1))
+	v := poolFreeSparseMapPos[b-5].Get()
+	if v == nil {
+		s = newSparseMapPos(1 << b)
+	} else {
+		s = v.(*sparseMapPos)
+	}
+	return s
+}
+func (c *Cache) freeSparseMapPos(s *sparseMapPos) {
+	s.clear()
+	b := bits.Len(uint(s.cap()) - 1)
+	poolFreeSparseMapPos[b-5].Put(s)
+}
diff --git a/src/cmd/compile/internal/ssa/biasedsparsemap.go b/src/cmd/compile/internal/ssa/biasedsparsemap.go
index 0d35154..948aef9 100644
--- a/src/cmd/compile/internal/ssa/biasedsparsemap.go
+++ b/src/cmd/compile/internal/ssa/biasedsparsemap.go
@@ -5,7 +5,6 @@
 package ssa
 
 import (
-	"cmd/internal/src"
 	"math"
 )
 
@@ -86,7 +85,7 @@
 	if int(x) < s.first || int(x) >= s.cap() {
 		return
 	}
-	s.s.set(ID(int(x)-s.first), 0, src.NoXPos)
+	s.s.set(ID(int(x)-s.first), 0)
 }
 
 // add inserts x->v into s, provided that x is in the range of keys stored in s.
@@ -94,7 +93,7 @@
 	if int(x) < s.first || int(x) >= s.cap() {
 		return
 	}
-	s.s.set(ID(int(x)-s.first), v, src.NoXPos)
+	s.s.set(ID(int(x)-s.first), v)
 }
 
 // remove removes key x from s.
diff --git a/src/cmd/compile/internal/ssa/branchelim.go b/src/cmd/compile/internal/ssa/branchelim.go
index 7a08654..f16959d 100644
--- a/src/cmd/compile/internal/ssa/branchelim.go
+++ b/src/cmd/compile/internal/ssa/branchelim.go
@@ -22,7 +22,7 @@
 func branchelim(f *Func) {
 	// FIXME: add support for lowering CondSelects on more architectures
 	switch f.Config.arch {
-	case "arm64", "ppc64le", "ppc64", "amd64", "wasm":
+	case "arm64", "ppc64le", "ppc64", "amd64", "wasm", "loong64":
 		// implemented
 	default:
 		return
@@ -83,6 +83,15 @@
 		// See issue #26306.
 		return false
 	}
+	if arch == "loong64" {
+		// We should not generate conditional moves if neither of the arguments is constant zero,
+		// because it requires three instructions (OR, MASKEQZ, MASKNEZ) and will increase the
+		// register pressure.
+		if !(v.Args[0].isGenericIntConst() && v.Args[0].AuxInt == 0) &&
+			!(v.Args[1].isGenericIntConst() && v.Args[1].AuxInt == 0) {
+			return false
+		}
+	}
 	// For now, stick to simple scalars that fit in registers
 	switch {
 	case v.Type.Size() > v.Block.Func.Config.RegSize:
@@ -427,7 +436,7 @@
 	// don't fuse memory ops, Phi ops, divides (can panic),
 	// or anything else with side-effects
 	for _, v := range b.Values {
-		if v.Op == OpPhi || isDivMod(v.Op) || v.Type.IsMemory() ||
+		if v.Op == OpPhi || isDivMod(v.Op) || isPtrArithmetic(v.Op) || v.Type.IsMemory() ||
 			v.MemoryArg() != nil || opcodeTable[v.Op].hasSideEffects {
 			return false
 		}
@@ -447,3 +456,15 @@
 		return false
 	}
 }
+
+func isPtrArithmetic(op Op) bool {
+	// Pointer arithmetic can't be speculatively executed because the result
+	// may be an invalid pointer (if, for example, the condition is that the
+	// base pointer is not nil). See issue 56990.
+	switch op {
+	case OpOffPtr, OpAddPtr, OpSubPtr:
+		return true
+	default:
+		return false
+	}
+}
diff --git a/src/cmd/compile/internal/ssa/cache.go b/src/cmd/compile/internal/ssa/cache.go
index dbec2e1..dd17f5f 100644
--- a/src/cmd/compile/internal/ssa/cache.go
+++ b/src/cmd/compile/internal/ssa/cache.go
@@ -21,17 +21,8 @@
 	// See stackalloc.go's {new,put}StackAllocState.
 	stackAllocState *stackAllocState
 
-	domblockstore []ID         // scratch space for computing dominators
-	scrSparseSet  []*sparseSet // scratch sparse sets to be re-used.
-	scrSparseMap  []*sparseMap // scratch sparse maps to be re-used.
-	scrPoset      []*poset     // scratch poset to be reused
-	// deadcode contains reusable slices specifically for the deadcode pass.
-	// It gets special treatment because of the frequency with which it is run.
-	deadcode struct {
-		liveOrderStmts []*Value
-		live           []bool
-		q              []*Value
-	}
+	scrPoset []*poset // scratch poset to be reused
+
 	// Reusable regalloc state.
 	regallocValues []valState
 
@@ -39,6 +30,16 @@
 	debugState       debugState
 
 	Liveness interface{} // *gc.livenessFuncCache
+
+	// Free "headers" for use by the allocators in allocators.go.
+	// Used to put slices in sync.Pools without allocation.
+	hdrValueSlice []*[]*Value
+	hdrBlockSlice []*[]*Block
+	hdrBoolSlice  []*[]bool
+	hdrIntSlice   []*[]int
+	hdrInt32Slice []*[]int32
+	hdrInt8Slice  []*[]int8
+	hdrIDSlice    []*[]ID
 }
 
 func (c *Cache) Reset() {
@@ -63,19 +64,4 @@
 	for i := range c.regallocValues {
 		c.regallocValues[i] = valState{}
 	}
-
-	// liveOrderStmts gets used multiple times during compilation of a function.
-	// We don't know where the high water mark was, so reslice to cap and search.
-	c.deadcode.liveOrderStmts = c.deadcode.liveOrderStmts[:cap(c.deadcode.liveOrderStmts)]
-	no := sort.Search(len(c.deadcode.liveOrderStmts), func(i int) bool { return c.deadcode.liveOrderStmts[i] == nil })
-	xo := c.deadcode.liveOrderStmts[:no]
-	for i := range xo {
-		xo[i] = nil
-	}
-	c.deadcode.q = c.deadcode.q[:cap(c.deadcode.q)]
-	nq := sort.Search(len(c.deadcode.q), func(i int) bool { return c.deadcode.q[i] == nil })
-	xq := c.deadcode.q[:nq]
-	for i := range xq {
-		xq[i] = nil
-	}
 }
diff --git a/src/cmd/compile/internal/ssa/check.go b/src/cmd/compile/internal/ssa/check.go
index df677e6..f34b907 100644
--- a/src/cmd/compile/internal/ssa/check.go
+++ b/src/cmd/compile/internal/ssa/check.go
@@ -5,6 +5,7 @@
 package ssa
 
 import (
+	"cmd/compile/internal/ir"
 	"cmd/internal/obj/s390x"
 	"math"
 	"math/bits"
@@ -312,6 +313,10 @@
 				if !v.Args[1].Type.IsInteger() {
 					f.Fatalf("bad arg 1 type to %s: want integer, have %s", v.Op, v.Args[1].LongString())
 				}
+			case OpVarDef:
+				if !v.Aux.(*ir.Name).Type().HasPointers() {
+					f.Fatalf("vardef must have pointer type %s", v.Aux.(*ir.Name).Type().String())
+				}
 
 			}
 
diff --git a/src/cmd/compile/internal/ssa/compile.go b/src/cmd/compile/internal/ssa/compile.go
index 5e898ab..769f225 100644
--- a/src/cmd/compile/internal/ssa/compile.go
+++ b/src/cmd/compile/internal/ssa/compile.go
@@ -5,7 +5,6 @@
 package ssa
 
 import (
-	"bytes"
 	"cmd/internal/src"
 	"fmt"
 	"hash/crc32"
@@ -152,7 +151,7 @@
 			keys = append(keys, key)
 		}
 		sort.Strings(keys)
-		buf := new(bytes.Buffer)
+		buf := new(strings.Builder)
 		fmt.Fprintf(buf, "%s: ", f.Name)
 		for _, key := range keys {
 			fmt.Fprintf(buf, "%s=%d ", key, f.ruleMatches[key])
@@ -488,6 +487,7 @@
 		disabled: !buildcfg.Experiment.PreemptibleLoops}, // insert resched checks in loops.
 	{name: "lower", fn: lower, required: true},
 	{name: "addressing modes", fn: addressingModes, required: false},
+	{name: "late lower", fn: lateLower, required: true},
 	{name: "lowered deadcode for cse", fn: deadcode}, // deadcode immediately before CSE avoids CSE making dead values live again
 	{name: "lowered cse", fn: cse},
 	{name: "elim unread autos", fn: elimUnreadAutos},
@@ -560,9 +560,14 @@
 	{"critical", "regalloc"},
 	// regalloc requires all the values in a block to be scheduled
 	{"schedule", "regalloc"},
+	// the rules in late lower run after the general rules.
+	{"lower", "late lower"},
+	// late lower may generate some values that need to be CSEed.
+	{"late lower", "lowered cse"},
 	// checkLower must run after lowering & subsequent dead code elim
 	{"lower", "checkLower"},
 	{"lowered deadcode", "checkLower"},
+	{"late lower", "checkLower"},
 	// late nilcheck needs instructions to be scheduled.
 	{"schedule", "late nilcheck"},
 	// flagalloc needs instructions to be scheduled.
diff --git a/src/cmd/compile/internal/ssa/config.go b/src/cmd/compile/internal/ssa/config.go
index 79b6849..ed84430 100644
--- a/src/cmd/compile/internal/ssa/config.go
+++ b/src/cmd/compile/internal/ssa/config.go
@@ -21,8 +21,10 @@
 	PtrSize        int64  // 4 or 8; copy of cmd/internal/sys.Arch.PtrSize
 	RegSize        int64  // 4 or 8; copy of cmd/internal/sys.Arch.RegSize
 	Types          Types
-	lowerBlock     blockRewriter  // lowering function
-	lowerValue     valueRewriter  // lowering function
+	lowerBlock     blockRewriter  // block lowering function, first round
+	lowerValue     valueRewriter  // value lowering function, first round
+	lateLowerBlock blockRewriter  // block lowering function that needs to be run after the first round; only used on some architectures
+	lateLowerValue valueRewriter  // value lowering function that needs to be run after the first round; only used on some architectures
 	splitLoad      valueRewriter  // function for splitting merged load ops; only used on some architectures
 	registers      []Register     // machine registers
 	gpRegMask      regMask        // general purpose integer register mask
@@ -184,6 +186,8 @@
 		c.RegSize = 8
 		c.lowerBlock = rewriteBlockAMD64
 		c.lowerValue = rewriteValueAMD64
+		c.lateLowerBlock = rewriteBlockAMD64latelower
+		c.lateLowerValue = rewriteValueAMD64latelower
 		c.splitLoad = rewriteValueAMD64splitload
 		c.registers = registersAMD64[:]
 		c.gpRegMask = gpRegMaskAMD64
@@ -222,6 +226,8 @@
 		c.RegSize = 8
 		c.lowerBlock = rewriteBlockARM64
 		c.lowerValue = rewriteValueARM64
+		c.lateLowerBlock = rewriteBlockARM64latelower
+		c.lateLowerValue = rewriteValueARM64latelower
 		c.registers = registersARM64[:]
 		c.gpRegMask = gpRegMaskARM64
 		c.fpRegMask = fpRegMaskARM64
@@ -230,7 +236,6 @@
 		c.FPReg = framepointerRegARM64
 		c.LinkReg = linkRegARM64
 		c.hasGReg = true
-		c.noDuffDevice = buildcfg.GOOS == "darwin" || buildcfg.GOOS == "ios" // darwin linker cannot handle BR26 reloc with non-zero addend
 	case "ppc64":
 		c.BigEndian = true
 		fallthrough
@@ -239,6 +244,8 @@
 		c.RegSize = 8
 		c.lowerBlock = rewriteBlockPPC64
 		c.lowerValue = rewriteValuePPC64
+		c.lateLowerBlock = rewriteBlockPPC64latelower
+		c.lateLowerValue = rewriteValuePPC64latelower
 		c.registers = registersPPC64[:]
 		c.gpRegMask = gpRegMaskPPC64
 		c.fpRegMask = fpRegMaskPPC64
@@ -308,6 +315,8 @@
 		c.RegSize = 8
 		c.lowerBlock = rewriteBlockRISCV64
 		c.lowerValue = rewriteValueRISCV64
+		c.lateLowerBlock = rewriteBlockRISCV64latelower
+		c.lateLowerValue = rewriteValueRISCV64latelower
 		c.registers = registersRISCV64[:]
 		c.gpRegMask = gpRegMaskRISCV64
 		c.fpRegMask = fpRegMaskRISCV64
diff --git a/src/cmd/compile/internal/ssa/critical.go b/src/cmd/compile/internal/ssa/critical.go
index 500ce3a..ddf1c0f 100644
--- a/src/cmd/compile/internal/ssa/critical.go
+++ b/src/cmd/compile/internal/ssa/critical.go
@@ -9,7 +9,8 @@
 // Regalloc wants a critical-edge-free CFG so it can implement phi values.
 func critical(f *Func) {
 	// maps from phi arg ID to the new block created for that argument
-	blocks := make([]*Block, f.NumValues())
+	blocks := f.Cache.allocBlockSlice(f.NumValues())
+	defer f.Cache.freeBlockSlice(blocks)
 	// need to iterate over f.Blocks without range, as we might
 	// need to split critical edges on newly constructed blocks
 	for j := 0; j < len(f.Blocks); j++ {
diff --git a/src/cmd/compile/internal/ssa/cse.go b/src/cmd/compile/internal/ssa/cse.go
index a71b78c..d649797 100644
--- a/src/cmd/compile/internal/ssa/cse.go
+++ b/src/cmd/compile/internal/ssa/cse.go
@@ -31,7 +31,9 @@
 	// until it reaches a fixed point.
 
 	// Make initial coarse partitions by using a subset of the conditions above.
-	a := make([]*Value, 0, f.NumValues())
+	a := f.Cache.allocValueSlice(f.NumValues())
+	defer func() { f.Cache.freeValueSlice(a) }() // inside closure to use final value of a
+	a = a[:0]
 	if f.auxmap == nil {
 		f.auxmap = auxmap{}
 	}
@@ -49,7 +51,8 @@
 	partition := partitionValues(a, f.auxmap)
 
 	// map from value id back to eqclass id
-	valueEqClass := make([]ID, f.NumValues())
+	valueEqClass := f.Cache.allocIDSlice(f.NumValues())
+	defer f.Cache.freeIDSlice(valueEqClass)
 	for _, b := range f.Blocks {
 		for _, v := range b.Values {
 			// Use negative equivalence class #s for unique values.
@@ -159,7 +162,8 @@
 
 	// Compute substitutions we would like to do. We substitute v for w
 	// if v and w are in the same equivalence class and v dominates w.
-	rewrite := make([]*Value, f.NumValues())
+	rewrite := f.Cache.allocValueSlice(f.NumValues())
+	defer f.Cache.freeValueSlice(rewrite)
 	byDom := new(partitionByDom) // reusable partitionByDom to reduce allocs
 	for _, e := range partition {
 		byDom.a = e
diff --git a/src/cmd/compile/internal/ssa/cse_test.go b/src/cmd/compile/internal/ssa/cse_test.go
index 8052016..813ebe4 100644
--- a/src/cmd/compile/internal/ssa/cse_test.go
+++ b/src/cmd/compile/internal/ssa/cse_test.go
@@ -22,7 +22,7 @@
 	arg1Aux := &tstAux{"arg1-aux"}
 	arg2Aux := &tstAux{"arg2-aux"}
 	arg3Aux := &tstAux{"arg3-aux"}
-	a := c.Frontend().Auto(src.NoXPos, c.config.Types.Int8)
+	a := c.Frontend().Auto(src.NoXPos, c.config.Types.Int8.PtrTo())
 
 	// construct lots of values with args that have aux values and place
 	// them in an order that triggers the bug
@@ -93,7 +93,7 @@
 // TestZCSE tests the zero arg cse.
 func TestZCSE(t *testing.T) {
 	c := testConfig(t)
-	a := c.Frontend().Auto(src.NoXPos, c.config.Types.Int8)
+	a := c.Frontend().Auto(src.NoXPos, c.config.Types.Int8.PtrTo())
 
 	fun := c.Fun("entry",
 		Bloc("entry",
diff --git a/src/cmd/compile/internal/ssa/deadcode.go b/src/cmd/compile/internal/ssa/deadcode.go
index b47b106..cfadda8 100644
--- a/src/cmd/compile/internal/ssa/deadcode.go
+++ b/src/cmd/compile/internal/ssa/deadcode.go
@@ -9,12 +9,12 @@
 )
 
 // findlive returns the reachable blocks and live values in f.
-// The caller should call f.retDeadcodeLive(live) when it is done with it.
+// The caller should call f.Cache.freeBoolSlice(live) when it is done with it.
 func findlive(f *Func) (reachable []bool, live []bool) {
 	reachable = ReachableBlocks(f)
 	var order []*Value
 	live, order = liveValues(f, reachable)
-	f.retDeadcodeLiveOrderStmts(order)
+	f.Cache.freeValueSlice(order)
 	return
 }
 
@@ -51,21 +51,11 @@
 // to be statements in reversed data flow order.
 // The second result is used to help conserve statement boundaries for debugging.
 // reachable is a map from block ID to whether the block is reachable.
-// The caller should call f.retDeadcodeLive(live) and f.retDeadcodeLiveOrderStmts(liveOrderStmts)
+// The caller should call f.Cache.freeBoolSlice(live) and f.Cache.freeValueSlice(liveOrderStmts).
 // when they are done with the return values.
 func liveValues(f *Func, reachable []bool) (live []bool, liveOrderStmts []*Value) {
-	live = f.newDeadcodeLive()
-	if cap(live) < f.NumValues() {
-		live = make([]bool, f.NumValues())
-	} else {
-		live = live[:f.NumValues()]
-		for i := range live {
-			live[i] = false
-		}
-	}
-
-	liveOrderStmts = f.newDeadcodeLiveOrderStmts()
-	liveOrderStmts = liveOrderStmts[:0]
+	live = f.Cache.allocBoolSlice(f.NumValues())
+	liveOrderStmts = f.Cache.allocValueSlice(f.NumValues())[:0]
 
 	// After regalloc, consider all values to be live.
 	// See the comment at the top of regalloc.go and in deadcode for details.
@@ -101,8 +91,8 @@
 	}
 
 	// Find all live values
-	q := f.Cache.deadcode.q[:0]
-	defer func() { f.Cache.deadcode.q = q }()
+	q := f.Cache.allocValueSlice(f.NumValues())[:0]
+	defer f.Cache.freeValueSlice(q)
 
 	// Starting set: all control values of reachable blocks are live.
 	// Calls are live (because callee can observe the memory state).
@@ -149,6 +139,7 @@
 	for len(q) > 0 {
 		// pop a reachable value
 		v := q[len(q)-1]
+		q[len(q)-1] = nil
 		q = q[:len(q)-1]
 		for i, x := range v.Args {
 			if v.Op == OpPhi && !reachable[v.Block.Preds[i].b.ID] {
@@ -213,8 +204,8 @@
 
 	// Find live values.
 	live, order := liveValues(f, reachable)
-	defer f.retDeadcodeLive(live)
-	defer f.retDeadcodeLiveOrderStmts(order)
+	defer func() { f.Cache.freeBoolSlice(live) }()
+	defer func() { f.Cache.freeValueSlice(order) }()
 
 	// Remove dead & duplicate entries from namedValues map.
 	s := f.newSparseSet(f.NumValues())
diff --git a/src/cmd/compile/internal/ssa/deadstore.go b/src/cmd/compile/internal/ssa/deadstore.go
index d694133..648b68a 100644
--- a/src/cmd/compile/internal/ssa/deadstore.go
+++ b/src/cmd/compile/internal/ssa/deadstore.go
@@ -7,7 +7,6 @@
 import (
 	"cmd/compile/internal/ir"
 	"cmd/compile/internal/types"
-	"cmd/internal/src"
 )
 
 // dse does dead-store elimination on the Function.
@@ -39,7 +38,7 @@
 				for _, a := range v.Args {
 					if a.Block == b && a.Type.IsMemory() {
 						storeUse.add(a.ID)
-						if v.Op != OpStore && v.Op != OpZero && v.Op != OpVarDef && v.Op != OpVarKill {
+						if v.Op != OpStore && v.Op != OpZero && v.Op != OpVarDef {
 							// CALL, DUFFCOPY, etc. are both
 							// reads and writes.
 							loadUse.add(a.ID)
@@ -112,7 +111,7 @@
 				if sz > 0x7fffffff { // work around sparseMap's int32 value type
 					sz = 0x7fffffff
 				}
-				shadowed.set(v.Args[0].ID, int32(sz), src.NoXPos)
+				shadowed.set(v.Args[0].ID, int32(sz))
 			}
 		}
 		// walk to previous store
@@ -156,7 +155,7 @@
 				changed = true
 			}
 			return
-		case OpVarDef, OpVarKill:
+		case OpVarDef:
 			// v should be eliminated if we eliminate the auto.
 			n, ok := v.Aux.(*ir.Name)
 			if !ok || n.Class != ir.PAUTO {
diff --git a/src/cmd/compile/internal/ssa/debug.go b/src/cmd/compile/internal/ssa/debug.go
index 4ed016f..584aaef 100644
--- a/src/cmd/compile/internal/ssa/debug.go
+++ b/src/cmd/compile/internal/ssa/debug.go
@@ -38,6 +38,8 @@
 	// Register-resident output parameters for the function. This is filled in at
 	// SSA generation time.
 	RegOutputParams []*ir.Name
+	// Variable declarations that were removed during optimization
+	OptDcl []*ir.Name
 
 	// Filled in by the user. Translates Block and Value ID to PC.
 	GetPC func(ID, ID) int64
@@ -613,7 +615,7 @@
 	// This would probably be better as an output from stackframe.
 	for _, b := range f.Blocks {
 		for _, v := range b.Values {
-			if v.Op == OpVarDef || v.Op == OpVarKill {
+			if v.Op == OpVarDef {
 				n := v.Aux.(*ir.Name)
 				if ir.IsSynthetic(n) {
 					continue
@@ -1080,7 +1082,7 @@
 	}
 
 	switch {
-	case v.Op == OpVarDef, v.Op == OpVarKill:
+	case v.Op == OpVarDef:
 		n := v.Aux.(*ir.Name)
 		if ir.IsSynthetic(n) {
 			break
diff --git a/src/cmd/compile/internal/ssa/debug_lines_test.go b/src/cmd/compile/internal/ssa/debug_lines_test.go
index a763589..6678a96 100644
--- a/src/cmd/compile/internal/ssa/debug_lines_test.go
+++ b/src/cmd/compile/internal/ssa/debug_lines_test.go
@@ -8,31 +8,29 @@
 	"bufio"
 	"bytes"
 	"flag"
-	"internal/buildcfg"
-	"runtime"
-	"sort"
-
 	"fmt"
+	"internal/buildcfg"
 	"internal/testenv"
-	"io/ioutil"
 	"os"
-	"os/exec"
 	"path/filepath"
 	"reflect"
 	"regexp"
+	"runtime"
+	"sort"
 	"strconv"
+	"strings"
 	"testing"
 )
 
 // Matches lines in genssa output that are marked "isstmt", and the parenthesized plus-prefixed line number is a submatch
-var asmLine *regexp.Regexp = regexp.MustCompile(`^\s[vb][0-9]+\s+[0-9]+\s\(\+([0-9]+)\)`)
+var asmLine *regexp.Regexp = regexp.MustCompile(`^\s[vb]\d+\s+\d+\s\(\+(\d+)\)`)
 
 // this matches e.g.                            `   v123456789   000007   (+9876654310) MOVUPS	X15, ""..autotmp_2-32(SP)`
 
 // Matches lines in genssa output that describe an inlined file.
 // Note it expects an unadventurous choice of basename.
 var sepRE = regexp.QuoteMeta(string(filepath.Separator))
-var inlineLine *regexp.Regexp = regexp.MustCompile(`^#\s.*` + sepRE + `[-a-zA-Z0-9_]+\.go:([0-9]+)`)
+var inlineLine *regexp.Regexp = regexp.MustCompile(`^#\s.*` + sepRE + `[-\w]+\.go:(\d+)`)
 
 // this matches e.g.                                 #  /pa/inline-dumpxxxx.go:6
 
@@ -45,28 +43,40 @@
 	return *testGoArchFlag
 }
 
+func hasRegisterABI() bool {
+	switch testGoArch() {
+	case "amd64", "arm64", "ppc64", "ppc64le", "riscv":
+		return true
+	}
+	return false
+}
+
+func unixOnly(t *testing.T) {
+	if runtime.GOOS != "linux" && runtime.GOOS != "darwin" { // in particular, it could be windows.
+		t.Skip("this test depends on creating a file with a wonky name, only works for sure on Linux and Darwin")
+	}
+}
+
+// testDebugLinesDefault removes the first wanted statement on architectures that are not (yet) register ABI.
+func testDebugLinesDefault(t *testing.T, gcflags, file, function string, wantStmts []int, ignoreRepeats bool) {
+	unixOnly(t)
+	if !hasRegisterABI() {
+		wantStmts = wantStmts[1:]
+	}
+	testDebugLines(t, gcflags, file, function, wantStmts, ignoreRepeats)
+}
+
 func TestDebugLinesSayHi(t *testing.T) {
 	// This test is potentially fragile, the goal is that debugging should step properly through "sayhi"
 	// If the blocks are reordered in a way that changes the statement order but execution flows correctly,
 	// then rearrange the expected numbers.  Register abi and not-register-abi also have different sequences,
 	// at least for now.
 
-	switch testGoArch() {
-	case "arm64", "amd64": // register ABI
-		testDebugLines(t, "-N -l", "sayhi.go", "sayhi", []int{8, 9, 10, 11}, false)
-
-	case "arm", "386": // probably not register ABI for a while
-		testDebugLines(t, "-N -l", "sayhi.go", "sayhi", []int{9, 10, 11}, false)
-
-	default: // expect ppc64le and riscv will pick up register ABI soonish, not sure about others
-		t.Skip("skipped for many architectures, also changes w/ register ABI")
-	}
+	testDebugLinesDefault(t, "-N -l", "sayhi.go", "sayhi", []int{8, 9, 10, 11}, false)
 }
 
 func TestDebugLinesPushback(t *testing.T) {
-	if runtime.GOOS != "linux" && runtime.GOOS != "darwin" { // in particular, it could be windows.
-		t.Skip("this test depends on creating a file with a wonky name, only works for sure on Linux and Darwin")
-	}
+	unixOnly(t)
 
 	switch testGoArch() {
 	default:
@@ -76,16 +86,14 @@
 		fn := "(*List[go.shape.int_0]).PushBack"
 		if buildcfg.Experiment.Unified {
 			// Unified mangles differently
-			fn = "(*List[int]).PushBack"
+			fn = "(*List[go.shape.int]).PushBack"
 		}
 		testDebugLines(t, "-N -l", "pushback.go", fn, []int{17, 18, 19, 20, 21, 22, 24}, true)
 	}
 }
 
 func TestDebugLinesConvert(t *testing.T) {
-	if runtime.GOOS != "linux" && runtime.GOOS != "darwin" { // in particular, it could be windows.
-		t.Skip("this test depends on creating a file with a wonky name, only works for sure on Linux and Darwin")
-	}
+	unixOnly(t)
 
 	switch testGoArch() {
 	default:
@@ -95,7 +103,7 @@
 		fn := "G[go.shape.int_0]"
 		if buildcfg.Experiment.Unified {
 			// Unified mangles differently
-			fn = "G[int]"
+			fn = "G[go.shape.int]"
 		}
 		testDebugLines(t, "-N -l", "convertline.go", fn, []int{9, 10, 11}, true)
 	}
@@ -111,10 +119,14 @@
 	testInlineStack(t, "inline-dump.go", "f", want)
 }
 
+func TestDebugLines_53456(t *testing.T) {
+	testDebugLinesDefault(t, "-N -l", "b53456.go", "(*T).Inc", []int{15, 16, 17, 18}, true)
+}
+
 func compileAndDump(t *testing.T, file, function, moreGCFlags string) []byte {
 	testenv.MustHaveGoBuild(t)
 
-	tmpdir, err := ioutil.TempDir("", "debug_lines_test")
+	tmpdir, err := os.MkdirTemp("", "debug_lines_test")
 	if err != nil {
 		panic(fmt.Sprintf("Problem creating TempDir, error %v", err))
 	}
@@ -129,7 +141,7 @@
 		panic(fmt.Sprintf("Could not get abspath of testdata directory and file, %v", err))
 	}
 
-	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", "foo.o", "-gcflags=-d=ssa/genssa/dump="+function+" "+moreGCFlags, source)
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-o", "foo.o", "-gcflags=-d=ssa/genssa/dump="+function+" "+moreGCFlags, source)
 	cmd.Dir = tmpdir
 	cmd.Env = replaceEnv(cmd.Env, "GOSSADIR", tmpdir)
 	testGoos := "linux" // default to linux
@@ -143,7 +155,7 @@
 		fmt.Printf("About to run %s\n", asCommandLine("", cmd))
 	}
 
-	var stdout, stderr bytes.Buffer
+	var stdout, stderr strings.Builder
 	cmd.Stdout = &stdout
 	cmd.Stderr = &stderr
 
diff --git a/src/cmd/compile/internal/ssa/debug_test.go b/src/cmd/compile/internal/ssa/debug_test.go
index c807863..094d1a9 100644
--- a/src/cmd/compile/internal/ssa/debug_test.go
+++ b/src/cmd/compile/internal/ssa/debug_test.go
@@ -5,12 +5,10 @@
 package ssa_test
 
 import (
-	"bytes"
 	"flag"
 	"fmt"
 	"internal/testenv"
 	"io"
-	"io/ioutil"
 	"os"
 	"os/exec"
 	"path/filepath"
@@ -34,11 +32,11 @@
 
 var (
 	hexRe                 = regexp.MustCompile("0x[a-zA-Z0-9]+")
-	numRe                 = regexp.MustCompile("-?[0-9]+")
+	numRe                 = regexp.MustCompile("-?\\d+")
 	stringRe              = regexp.MustCompile("\"([^\\\"]|(\\.))*\"")
-	leadingDollarNumberRe = regexp.MustCompile("^[$][0-9]+")
+	leadingDollarNumberRe = regexp.MustCompile("^[$]\\d+")
 	optOutGdbRe           = regexp.MustCompile("[<]optimized out[>]")
-	numberColonRe         = regexp.MustCompile("^ *[0-9]+:")
+	numberColonRe         = regexp.MustCompile("^ *\\d+:")
 )
 
 var gdb = "gdb"      // Might be "ggdb" on Darwin, because gdb no longer part of XCode
@@ -224,7 +222,7 @@
 
 	// Use a temporary directory unless -f is specified
 	if !*force {
-		tmpdir, err := ioutil.TempDir("", "debug_test")
+		tmpdir, err := os.MkdirTemp("", "debug_test")
 		if err != nil {
 			panic(fmt.Sprintf("Problem creating TempDir, error %v\n", err))
 		}
@@ -246,9 +244,9 @@
 	tmplog := tmpbase + ".nexts"
 	var dbg dbgr
 	if *useGdb {
-		dbg = newGdb(tag, exe)
+		dbg = newGdb(t, tag, exe)
 	} else {
-		dbg = newDelve(tag, exe)
+		dbg = newDelve(t, tag, exe)
 	}
 	h1 := runDbgr(dbg, count)
 	if *dryrun {
@@ -263,7 +261,7 @@
 		if !h0.equals(h1) {
 			// Be very noisy about exactly what's wrong to simplify debugging.
 			h1.write(tmplog)
-			cmd := exec.Command("diff", "-u", nextlog, tmplog)
+			cmd := testenv.Command(t, "diff", "-u", nextlog, tmplog)
 			line := asCommandLine("", cmd)
 			bytes, err := cmd.CombinedOutput()
 			if err != nil && len(bytes) == 0 {
@@ -298,8 +296,8 @@
 }
 
 func runGo(t *testing.T, dir string, args ...string) string {
-	var stdout, stderr bytes.Buffer
-	cmd := exec.Command(testenv.GoToolPath(t), args...)
+	var stdout, stderr strings.Builder
+	cmd := testenv.Command(t, testenv.GoToolPath(t), args...)
 	cmd.Dir = dir
 	if *dryrun {
 		fmt.Printf("%s\n", asCommandLine("", cmd))
@@ -367,7 +365,7 @@
 
 func (h *nextHist) read(filename string) {
 	h.f2i = make(map[string]uint8)
-	bytes, err := ioutil.ReadFile(filename)
+	bytes, err := os.ReadFile(filename)
 	if err != nil {
 		panic(fmt.Sprintf("Problem reading %s, error %v\n", filename, err))
 	}
@@ -503,8 +501,8 @@
 	function         string
 }
 
-func newDelve(tag, executable string, args ...string) dbgr {
-	cmd := exec.Command("dlv", "exec", executable)
+func newDelve(t testing.TB, tag, executable string, args ...string) dbgr {
+	cmd := testenv.Command(t, "dlv", "exec", executable)
 	cmd.Env = replaceEnv(cmd.Env, "TERM", "dumb")
 	if len(args) > 0 {
 		cmd.Args = append(cmd.Args, "--")
@@ -588,9 +586,9 @@
 	function         string
 }
 
-func newGdb(tag, executable string, args ...string) dbgr {
+func newGdb(t testing.TB, tag, executable string, args ...string) dbgr {
 	// Turn off shell, necessary for Darwin apparently
-	cmd := exec.Command(gdb, "-nx",
+	cmd := testenv.Command(t, gdb, "-nx",
 		"-iex", fmt.Sprintf("add-auto-load-safe-path %s/src/runtime", runtime.GOROOT()),
 		"-ex", "set startup-with-shell off", executable)
 	cmd.Env = replaceEnv(cmd.Env, "TERM", "dumb")
diff --git a/src/cmd/compile/internal/ssa/decompose.go b/src/cmd/compile/internal/ssa/decompose.go
index 753d69c..2293fc0 100644
--- a/src/cmd/compile/internal/ssa/decompose.go
+++ b/src/cmd/compile/internal/ssa/decompose.go
@@ -135,7 +135,7 @@
 	case v.Type.IsFloat():
 		// floats are never decomposed, even ones bigger than RegSize
 	case v.Type.Size() > v.Block.Func.Config.RegSize:
-		v.Fatalf("undecomposed type %s", v.Type)
+		v.Fatalf("%v undecomposed type %v", v, v.Type)
 	}
 }
 
diff --git a/src/cmd/compile/internal/ssa/dom.go b/src/cmd/compile/internal/ssa/dom.go
index f31e7df..39ba4d1 100644
--- a/src/cmd/compile/internal/ssa/dom.go
+++ b/src/cmd/compile/internal/ssa/dom.go
@@ -21,7 +21,8 @@
 // postorderWithNumbering provides a DFS postordering.
 // This seems to make loop-finding more robust.
 func postorderWithNumbering(f *Func, ponums []int32) []*Block {
-	seen := make([]bool, f.NumBlocks())
+	seen := f.Cache.allocBoolSlice(f.NumBlocks())
+	defer f.Cache.freeBoolSlice(seen)
 
 	// result ordering
 	order := make([]*Block, 0, len(f.Blocks))
@@ -56,44 +57,6 @@
 
 type linkedBlocks func(*Block) []Edge
 
-const nscratchslices = 7
-
-// experimentally, functions with 512 or fewer blocks account
-// for 75% of memory (size) allocation for dominator computation
-// in make.bash.
-const minscratchblocks = 512
-
-func (cache *Cache) scratchBlocksForDom(maxBlockID int) (a, b, c, d, e, f, g []ID) {
-	tot := maxBlockID * nscratchslices
-	scratch := cache.domblockstore
-	if len(scratch) < tot {
-		// req = min(1.5*tot, nscratchslices*minscratchblocks)
-		// 50% padding allows for graph growth in later phases.
-		req := (tot * 3) >> 1
-		if req < nscratchslices*minscratchblocks {
-			req = nscratchslices * minscratchblocks
-		}
-		scratch = make([]ID, req)
-		cache.domblockstore = scratch
-	} else {
-		// Clear as much of scratch as we will (re)use
-		scratch = scratch[0:tot]
-		for i := range scratch {
-			scratch[i] = 0
-		}
-	}
-
-	a = scratch[0*maxBlockID : 1*maxBlockID]
-	b = scratch[1*maxBlockID : 2*maxBlockID]
-	c = scratch[2*maxBlockID : 3*maxBlockID]
-	d = scratch[3*maxBlockID : 4*maxBlockID]
-	e = scratch[4*maxBlockID : 5*maxBlockID]
-	f = scratch[5*maxBlockID : 6*maxBlockID]
-	g = scratch[6*maxBlockID : 7*maxBlockID]
-
-	return
-}
-
 func dominators(f *Func) []*Block {
 	preds := func(b *Block) []Edge { return b.Preds }
 	succs := func(b *Block) []Edge { return b.Succs }
@@ -110,12 +73,21 @@
 	// Adapted directly from the original TOPLAS article's "simple" algorithm
 
 	maxBlockID := entry.Func.NumBlocks()
-	semi, vertex, label, parent, ancestor, bucketHead, bucketLink := f.Cache.scratchBlocksForDom(maxBlockID)
+	scratch := f.Cache.allocIDSlice(7 * maxBlockID)
+	defer f.Cache.freeIDSlice(scratch)
+	semi := scratch[0*maxBlockID : 1*maxBlockID]
+	vertex := scratch[1*maxBlockID : 2*maxBlockID]
+	label := scratch[2*maxBlockID : 3*maxBlockID]
+	parent := scratch[3*maxBlockID : 4*maxBlockID]
+	ancestor := scratch[4*maxBlockID : 5*maxBlockID]
+	bucketHead := scratch[5*maxBlockID : 6*maxBlockID]
+	bucketLink := scratch[6*maxBlockID : 7*maxBlockID]
 
 	// This version uses integers for most of the computation,
 	// to make the work arrays smaller and pointer-free.
 	// fromID translates from ID to *Block where that is needed.
-	fromID := make([]*Block, maxBlockID)
+	fromID := f.Cache.allocBlockSlice(maxBlockID)
+	defer f.Cache.freeBlockSlice(fromID)
 	for _, v := range f.Blocks {
 		fromID[v.ID] = v
 	}
@@ -172,7 +144,7 @@
 	return idom
 }
 
-// dfs performs a depth first search over the blocks starting at entry block
+// dfsOrig performs a depth first search over the blocks starting at entry block
 // (in arbitrary order).  This is a de-recursed version of dfs from the
 // original Tarjan-Lengauer TOPLAS article.  It's important to return the
 // same values for parent as the original algorithm.
@@ -207,7 +179,7 @@
 	return n
 }
 
-// compressOrig is the "simple" compress function from LT paper
+// compressOrig is the "simple" compress function from LT paper.
 func compressOrig(v ID, ancestor, semi, label []ID) {
 	if ancestor[ancestor[v]] != 0 {
 		compressOrig(ancestor[v], ancestor, semi, label)
@@ -218,7 +190,7 @@
 	}
 }
 
-// evalOrig is the "simple" eval function from LT paper
+// evalOrig is the "simple" eval function from LT paper.
 func evalOrig(v ID, ancestor, semi, label []ID) ID {
 	if ancestor[v] == 0 {
 		return v
@@ -231,7 +203,7 @@
 	ancestor[w] = v
 }
 
-// dominators computes the dominator tree for f. It returns a slice
+// dominatorsSimple computes the dominator tree for f. It returns a slice
 // which maps block ID to the immediate dominator of that block.
 // Unreachable blocks map to nil. The entry block maps to nil.
 func dominatorsSimple(f *Func) []*Block {
@@ -243,7 +215,8 @@
 	post := f.postorder()
 
 	// Make map from block id to order index (for intersect call)
-	postnum := make([]int, f.NumBlocks())
+	postnum := f.Cache.allocIntSlice(f.NumBlocks())
+	defer f.Cache.freeIntSlice(postnum)
 	for i, b := range post {
 		postnum[b.ID] = i
 	}
diff --git a/src/cmd/compile/internal/ssa/expand_calls.go b/src/cmd/compile/internal/ssa/expand_calls.go
index 90ea2d5..949a8d3 100644
--- a/src/cmd/compile/internal/ssa/expand_calls.go
+++ b/src/cmd/compile/internal/ssa/expand_calls.go
@@ -1742,7 +1742,7 @@
 			toReplace.Type = t
 			w = toReplace
 		} else {
-			w = baseArg.Block.NewValue0IA(pos, OpArg, t, auxInt, aux)
+			w = baseArg.Block.NewValue0IA(baseArg.Pos, OpArg, t, auxInt, aux)
 		}
 		x.commonArgs[key] = w
 		if toReplace != nil {
@@ -1773,7 +1773,7 @@
 		toReplace.Type = t
 		w = toReplace
 	} else {
-		w = baseArg.Block.NewValue0IA(pos, op, t, auxInt, aux)
+		w = baseArg.Block.NewValue0IA(baseArg.Pos, op, t, auxInt, aux)
 	}
 	x.commonArgs[key] = w
 	if toReplace != nil {
@@ -1786,7 +1786,7 @@
 
 }
 
-// argOpAndRegisterFor converts an abi register index into an ssa Op and corresponding
+// ArgOpAndRegisterFor converts an abi register index into an ssa Op and corresponding
 // arg register index.
 func ArgOpAndRegisterFor(r abi.RegIndex, abiConfig *abi.ABIConfig) (Op, int64) {
 	i := abiConfig.FloatIndexFor(r)
diff --git a/src/cmd/compile/internal/ssa/export_test.go b/src/cmd/compile/internal/ssa/export_test.go
index 87d1b41..f98437b 100644
--- a/src/cmd/compile/internal/ssa/export_test.go
+++ b/src/cmd/compile/internal/ssa/export_test.go
@@ -72,6 +72,7 @@
 }
 func (TestFrontend) Auto(pos src.XPos, t *types.Type) *ir.Name {
 	n := ir.NewNameAt(pos, &types.Sym{Name: "aFakeAuto"})
+	n.SetType(t)
 	n.Class = ir.PAUTO
 	return n
 }
diff --git a/src/cmd/compile/internal/ssa/flagalloc.go b/src/cmd/compile/internal/ssa/flagalloc.go
index 61c45a6..cf2c9a0 100644
--- a/src/cmd/compile/internal/ssa/flagalloc.go
+++ b/src/cmd/compile/internal/ssa/flagalloc.go
@@ -11,7 +11,8 @@
 	// Compute the in-register flag value we want at the end of
 	// each block. This is basically a best-effort live variable
 	// analysis, so it can be much simpler than a full analysis.
-	end := make([]*Value, f.NumBlocks())
+	end := f.Cache.allocValueSlice(f.NumBlocks())
+	defer f.Cache.freeValueSlice(end)
 	po := f.postorder()
 	for n := 0; n < 2; n++ {
 		for _, b := range po {
diff --git a/src/cmd/compile/internal/ssa/flags_test.go b/src/cmd/compile/internal/ssa/flags_test.go
index 0bc1097..d0079ac 100644
--- a/src/cmd/compile/internal/ssa/flags_test.go
+++ b/src/cmd/compile/internal/ssa/flags_test.go
@@ -3,7 +3,6 @@
 // license that can be found in the LICENSE file.
 
 //go:build amd64 || arm64
-// +build amd64 arm64
 
 package ssa
 
diff --git a/src/cmd/compile/internal/ssa/fmahash_test.go b/src/cmd/compile/internal/ssa/fmahash_test.go
new file mode 100644
index 0000000..8bdb3bf
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/fmahash_test.go
@@ -0,0 +1,57 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssa_test
+
+import (
+	"internal/testenv"
+	"os"
+	"path/filepath"
+	"regexp"
+	"runtime"
+	"testing"
+)
+
+// TestFmaHash checks that the hash-test machinery works properly for a single case.
+// It also runs ssa/check and gccheck to be sure that those are checked at least a
+// little in each run.bash.  It does not check or run the generated code.
+// The test file is however a useful example of fused-vs-cascaded multiply-add.
+func TestFmaHash(t *testing.T) {
+	switch runtime.GOOS {
+	case "linux", "darwin":
+	default:
+		t.Skipf("Slow test, usually avoid it, os=%s not linux or darwin", runtime.GOOS)
+	}
+	switch runtime.GOARCH {
+	case "amd64", "arm64":
+	default:
+		t.Skipf("Slow test, usually avoid it, arch=%s not amd64 or arm64", runtime.GOARCH)
+	}
+
+	testenv.MustHaveGoBuild(t)
+	gocmd := testenv.GoToolPath(t)
+	tmpdir, err := os.MkdirTemp("", "x")
+	if err != nil {
+		t.Error(err)
+	}
+	defer os.RemoveAll(tmpdir)
+	source := filepath.Join("testdata", "fma.go")
+	output := filepath.Join(tmpdir, "fma.exe")
+	cmd := testenv.Command(t, gocmd, "build", "-o", output, source)
+	// The hash-dependence on file path name is dodged by specifying "all hashes ending in 1" plus "all hashes ending in 0"
+	// i.e., all hashes.  This will print all the FMAs; this test is only interested in one of them (that should appear near the end).
+	cmd.Env = append(cmd.Env, "GOCOMPILEDEBUG=fmahash=1/0", "GOOS=linux", "GOARCH=arm64", "HOME="+tmpdir)
+	t.Logf("%v", cmd)
+	t.Logf("%v", cmd.Env)
+	b, e := cmd.CombinedOutput()
+	if e != nil {
+		t.Error(e)
+	}
+	s := string(b) // Looking for "GOFMAHASH triggered main.main:24"
+	re := "fmahash(0?) triggered POS=.*fma.go:29:..;.*fma.go:18:.."
+	match := regexp.MustCompile(re)
+	if !match.MatchString(s) {
+		t.Errorf("Expected to match '%s' with \n-----\n%s-----", re, s)
+	}
+}
diff --git a/src/cmd/compile/internal/ssa/func.go b/src/cmd/compile/internal/ssa/func.go
index 75f1763..b10911a 100644
--- a/src/cmd/compile/internal/ssa/func.go
+++ b/src/cmd/compile/internal/ssa/func.go
@@ -8,20 +8,12 @@
 	"cmd/compile/internal/abi"
 	"cmd/compile/internal/base"
 	"cmd/compile/internal/types"
-	"cmd/internal/notsha256"
 	"cmd/internal/src"
 	"fmt"
-	"io"
 	"math"
-	"os"
 	"strings"
 )
 
-type writeSyncer interface {
-	io.Writer
-	Sync() error
-}
-
 // A Func represents a Go func declaration (or function literal) and its body.
 // This package compiles each Func independently.
 // Funcs are single-use; a new Func must be created for every compiled function.
@@ -38,11 +30,7 @@
 	bid idAlloc // block ID allocator
 	vid idAlloc // value ID allocator
 
-	// Given an environment variable used for debug hash match,
-	// what file (if any) receives the yes/no logging?
-	logfiles       map[string]writeSyncer
 	HTMLWriter     *HTMLWriter    // html writer, for debugging
-	DebugTest      bool           // default true unless $GOSSAHASH != ""; as a debugging aid, make new code conditional on this and use GOSSAHASH to binary search for failing cases
 	PrintOrHtmlSSA bool           // true if GOSSAFUNC matches, true even if fe.Log() (spew phase results to stdout) is false.  There's an odd dependence on this in debug.go for method logf.
 	ruleMatches    map[string]int // number of times countRule was called during compilation for any given string
 	ABI0           *abi.ABIConfig // A copy, for no-sync access
@@ -58,6 +46,9 @@
 	// when register allocation is done, maps value ids to locations
 	RegAlloc []Location
 
+	// temporary registers allocated to rare instructions
+	tempRegs map[ID]*Register
+
 	// map from LocalSlot to set of Values that we want to store in that slot.
 	NamedValues map[LocalSlot][]*Value
 	// Names is a copy of NamedValues.Keys. We keep a separate list
@@ -116,50 +107,35 @@
 
 // newSparseSet returns a sparse set that can store at least up to n integers.
 func (f *Func) newSparseSet(n int) *sparseSet {
-	for i, scr := range f.Cache.scrSparseSet {
-		if scr != nil && scr.cap() >= n {
-			f.Cache.scrSparseSet[i] = nil
-			scr.clear()
-			return scr
-		}
-	}
-	return newSparseSet(n)
+	return f.Cache.allocSparseSet(n)
 }
 
 // retSparseSet returns a sparse set to the config's cache of sparse
 // sets to be reused by f.newSparseSet.
 func (f *Func) retSparseSet(ss *sparseSet) {
-	for i, scr := range f.Cache.scrSparseSet {
-		if scr == nil {
-			f.Cache.scrSparseSet[i] = ss
-			return
-		}
-	}
-	f.Cache.scrSparseSet = append(f.Cache.scrSparseSet, ss)
+	f.Cache.freeSparseSet(ss)
 }
 
 // newSparseMap returns a sparse map that can store at least up to n integers.
 func (f *Func) newSparseMap(n int) *sparseMap {
-	for i, scr := range f.Cache.scrSparseMap {
-		if scr != nil && scr.cap() >= n {
-			f.Cache.scrSparseMap[i] = nil
-			scr.clear()
-			return scr
-		}
-	}
-	return newSparseMap(n)
+	return f.Cache.allocSparseMap(n)
 }
 
 // retSparseMap returns a sparse map to the config's cache of sparse
 // sets to be reused by f.newSparseMap.
 func (f *Func) retSparseMap(ss *sparseMap) {
-	for i, scr := range f.Cache.scrSparseMap {
-		if scr == nil {
-			f.Cache.scrSparseMap[i] = ss
-			return
-		}
-	}
-	f.Cache.scrSparseMap = append(f.Cache.scrSparseMap, ss)
+	f.Cache.freeSparseMap(ss)
+}
+
+// newSparseMapPos returns a sparse map that can store at least up to n integers.
+func (f *Func) newSparseMapPos(n int) *sparseMapPos {
+	return f.Cache.allocSparseMapPos(n)
+}
+
+// retSparseMapPos returns a sparse map to the config's cache of sparse
+// sets to be reused by f.newSparseMapPos.
+func (f *Func) retSparseMapPos(ss *sparseMapPos) {
+	f.Cache.freeSparseMapPos(ss)
 }
 
 // newPoset returns a new poset from the internal cache
@@ -177,33 +153,6 @@
 	f.Cache.scrPoset = append(f.Cache.scrPoset, po)
 }
 
-// newDeadcodeLive returns a slice for the
-// deadcode pass to use to indicate which values are live.
-func (f *Func) newDeadcodeLive() []bool {
-	r := f.Cache.deadcode.live
-	f.Cache.deadcode.live = nil
-	return r
-}
-
-// retDeadcodeLive returns a deadcode live value slice for re-use.
-func (f *Func) retDeadcodeLive(live []bool) {
-	f.Cache.deadcode.live = live
-}
-
-// newDeadcodeLiveOrderStmts returns a slice for the
-// deadcode pass to use to indicate which values
-// need special treatment for statement boundaries.
-func (f *Func) newDeadcodeLiveOrderStmts() []*Value {
-	r := f.Cache.deadcode.liveOrderStmts
-	f.Cache.deadcode.liveOrderStmts = nil
-	return r
-}
-
-// retDeadcodeLiveOrderStmts returns a deadcode liveOrderStmts slice for re-use.
-func (f *Func) retDeadcodeLiveOrderStmts(liveOrderStmts []*Value) {
-	f.Cache.deadcode.liveOrderStmts = liveOrderStmts
-}
-
 func (f *Func) localSlotAddr(slot LocalSlot) *LocalSlot {
 	a, ok := f.CanonicalLocalSlots[slot]
 	if !ok {
@@ -355,7 +304,7 @@
 	return v
 }
 
-// logPassStat writes a string key and int value as a warning in a
+// LogStat writes a string key and int value as a warning in a
 // tab-separated format easily handled by spreadsheets or awk.
 // file names, lines, and function names are included to provide enough (?)
 // context to allow item-by-item comparisons across runs.
@@ -438,7 +387,7 @@
 	f.freeValues = v
 }
 
-// newBlock allocates a new Block of the given kind and places it at the end of f.Blocks.
+// NewBlock allocates a new Block of the given kind and places it at the end of f.Blocks.
 func (f *Func) NewBlock(kind BlockKind) *Block {
 	var b *Block
 	if f.freeBlocks != nil {
@@ -484,7 +433,7 @@
 	return v
 }
 
-// NewValue returns a new value in the block with no arguments and an auxint value.
+// NewValue0I returns a new value in the block with no arguments and an auxint value.
 func (b *Block) NewValue0I(pos src.XPos, op Op, t *types.Type, auxint int64) *Value {
 	v := b.Func.newValue(op, t, b, pos)
 	v.AuxInt = auxint
@@ -492,7 +441,7 @@
 	return v
 }
 
-// NewValue returns a new value in the block with no arguments and an aux value.
+// NewValue0A returns a new value in the block with no arguments and an aux value.
 func (b *Block) NewValue0A(pos src.XPos, op Op, t *types.Type, aux Aux) *Value {
 	v := b.Func.newValue(op, t, b, pos)
 	v.AuxInt = 0
@@ -501,7 +450,7 @@
 	return v
 }
 
-// NewValue returns a new value in the block with no arguments and both an auxint and aux values.
+// NewValue0IA returns a new value in the block with no arguments and both an auxint and aux values.
 func (b *Block) NewValue0IA(pos src.XPos, op Op, t *types.Type, auxint int64, aux Aux) *Value {
 	v := b.Func.newValue(op, t, b, pos)
 	v.AuxInt = auxint
@@ -705,7 +654,7 @@
 	constEmptyStringMagic = 4455667788
 )
 
-// ConstInt returns an int constant representing its argument.
+// ConstBool returns an int constant representing its argument.
 func (f *Func) ConstBool(t *types.Type, c bool) *Value {
 	i := int64(0)
 	if c {
@@ -819,88 +768,19 @@
 	f.cachedLoopnest = nil
 }
 
-// DebugHashMatch reports whether environment variable evname
-//  1. is empty (this is a special more-quickly implemented case of 3)
-//  2. is "y" or "Y"
-//  3. is a suffix of the sha1 hash of name
-//  4. is a suffix of the environment variable
-//     fmt.Sprintf("%s%d", evname, n)
-//     provided that all such variables are nonempty for 0 <= i <= n
+// DebugHashMatch returns
 //
-// Otherwise it returns false.
-// When true is returned the message
+//	base.DebugHashMatch(this function's package.name)
 //
-//	"%s triggered %s\n", evname, name
-//
-// is printed on the file named in environment variable
-//
-//	GSHS_LOGFILE
-//
-// or standard out if that is empty or there is an error
-// opening the file.
-func (f *Func) DebugHashMatch(evname string) bool {
+// for use in bug isolation.  The return value is true unless
+// environment variable GOSSAHASH is set, in which case "it depends".
+// See [base.DebugHashMatch] for more information.
+func (f *Func) DebugHashMatch() bool {
+	if !base.HasDebugHash() {
+		return true
+	}
 	name := f.fe.MyImportPath() + "." + f.Name
-	evhash := os.Getenv(evname)
-	switch evhash {
-	case "":
-		return true // default behavior with no EV is "on"
-	case "y", "Y":
-		f.logDebugHashMatch(evname, name)
-		return true
-	case "n", "N":
-		return false
-	}
-	// Check the hash of the name against a partial input hash.
-	// We use this feature to do a binary search to
-	// find a function that is incorrectly compiled.
-	hstr := ""
-	for _, b := range notsha256.Sum256([]byte(name)) {
-		hstr += fmt.Sprintf("%08b", b)
-	}
-
-	if strings.HasSuffix(hstr, evhash) {
-		f.logDebugHashMatch(evname, name)
-		return true
-	}
-
-	// Iteratively try additional hashes to allow tests for multi-point
-	// failure.
-	for i := 0; true; i++ {
-		ev := fmt.Sprintf("%s%d", evname, i)
-		evv := os.Getenv(ev)
-		if evv == "" {
-			break
-		}
-		if strings.HasSuffix(hstr, evv) {
-			f.logDebugHashMatch(ev, name)
-			return true
-		}
-	}
-	return false
-}
-
-func (f *Func) logDebugHashMatch(evname, name string) {
-	if f.logfiles == nil {
-		f.logfiles = make(map[string]writeSyncer)
-	}
-	file := f.logfiles[evname]
-	if file == nil {
-		file = os.Stdout
-		if tmpfile := os.Getenv("GSHS_LOGFILE"); tmpfile != "" {
-			var err error
-			file, err = os.OpenFile(tmpfile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
-			if err != nil {
-				f.Fatalf("could not open hash-testing logfile %s", tmpfile)
-			}
-		}
-		f.logfiles[evname] = file
-	}
-	fmt.Fprintf(file, "%s triggered %s\n", evname, name)
-	file.Sync()
-}
-
-func DebugNameMatch(evname, name string) bool {
-	return os.Getenv(evname) == name
+	return base.DebugHashMatch(name)
 }
 
 func (f *Func) spSb() (sp, sb *Value) {
@@ -924,3 +804,16 @@
 	}
 	return
 }
+
+// useFMA allows targeted debugging w/ GOFMAHASH
+// If you have an architecture-dependent FP glitch, this will help you find it.
+func (f *Func) useFMA(v *Value) bool {
+	if !f.Config.UseFMA {
+		return false
+	}
+	if base.FmaHash == nil {
+		return true
+	}
+	ctxt := v.Block.Func.Config.Ctxt()
+	return base.FmaHash.DebugHashMatchPos(ctxt, v.Pos)
+}
diff --git a/src/cmd/compile/internal/ssa/fuse.go b/src/cmd/compile/internal/ssa/fuse.go
index 2b176df..6d3fb70 100644
--- a/src/cmd/compile/internal/ssa/fuse.go
+++ b/src/cmd/compile/internal/ssa/fuse.go
@@ -6,6 +6,7 @@
 
 import (
 	"cmd/internal/src"
+	"fmt"
 )
 
 // fuseEarly runs fuse(f, fuseTypePlain|fuseTypeIntInRange).
@@ -28,7 +29,9 @@
 func fuse(f *Func, typ fuseType) {
 	for changed := true; changed; {
 		changed = false
-		// Fuse from end to beginning, to avoid quadratic behavior in fuseBlockPlain. See issue 13554.
+		// Be sure to avoid quadratic behavior in fuseBlockPlain. See issue 13554.
+		// Previously this was dealt with using backwards iteration, now fuseBlockPlain
+		// handles large runs of blocks.
 		for i := len(f.Blocks) - 1; i >= 0; i-- {
 			b := f.Blocks[i]
 			if typ&fuseTypeIf != 0 {
@@ -44,6 +47,7 @@
 				changed = shortcircuitBlock(b) || changed
 			}
 		}
+
 		if typ&fuseTypeBranchRedirect != 0 {
 			changed = fuseBranchRedirect(f) || changed
 		}
@@ -172,65 +176,134 @@
 	return true
 }
 
+// fuseBlockPlain handles a run of blocks with length >= 2,
+// whose interior has single predecessors and successors,
+// b must be BlockPlain, allowing it to be any node except the
+// last (multiple successors means not BlockPlain).
+// Cycles are handled and merged into b's successor.
 func fuseBlockPlain(b *Block) bool {
 	if b.Kind != BlockPlain {
 		return false
 	}
 
 	c := b.Succs[0].b
-	if len(c.Preds) != 1 {
+	if len(c.Preds) != 1 || c == b { // At least 2 distinct blocks.
 		return false
 	}
 
-	// If a block happened to end in a statement marker,
-	// try to preserve it.
-	if b.Pos.IsStmt() == src.PosIsStmt {
-		l := b.Pos.Line()
-		for _, v := range c.Values {
-			if v.Pos.IsStmt() == src.PosNotStmt {
-				continue
+	// find earliest block in run.  Avoid simple cycles.
+	for len(b.Preds) == 1 && b.Preds[0].b != c && b.Preds[0].b.Kind == BlockPlain {
+		b = b.Preds[0].b
+	}
+
+	// find latest block in run.  Still beware of simple cycles.
+	for {
+		if c.Kind != BlockPlain {
+			break
+		} // Has exactly 1 successor
+		cNext := c.Succs[0].b
+		if cNext == b {
+			break
+		} // not a cycle
+		if len(cNext.Preds) != 1 {
+			break
+		} // no other incoming edge
+		c = cNext
+	}
+
+	// Try to preserve any statement marks on the ends of blocks; move values to C
+	var b_next *Block
+	for bx := b; bx != c; bx = b_next {
+		// For each bx with an end-of-block statement marker,
+		// try to move it to a value in the next block,
+		// or to the next block's end, if possible.
+		b_next = bx.Succs[0].b
+		if bx.Pos.IsStmt() == src.PosIsStmt {
+			l := bx.Pos.Line() // looking for another place to mark for line l
+			outOfOrder := false
+			for _, v := range b_next.Values {
+				if v.Pos.IsStmt() == src.PosNotStmt {
+					continue
+				}
+				if l == v.Pos.Line() { // Found a Value with same line, therefore done.
+					v.Pos = v.Pos.WithIsStmt()
+					l = 0
+					break
+				}
+				if l < v.Pos.Line() {
+					// The order of values in a block is not specified so OOO in a block is not interesting,
+					// but they do all come before the end of the block, so this disqualifies attaching to end of b_next.
+					outOfOrder = true
+				}
 			}
-			if l == v.Pos.Line() {
-				v.Pos = v.Pos.WithIsStmt()
-				l = 0
-				break
+			if l != 0 && !outOfOrder && (b_next.Pos.Line() == l || b_next.Pos.IsStmt() != src.PosIsStmt) {
+				b_next.Pos = bx.Pos.WithIsStmt()
 			}
 		}
-		if l != 0 && c.Pos.Line() == l {
-			c.Pos = c.Pos.WithIsStmt()
+		// move all of bx's values to c (note containing loop excludes c)
+		for _, v := range bx.Values {
+			v.Block = c
 		}
 	}
 
-	// move all of b's values to c.
-	for _, v := range b.Values {
-		v.Block = c
+	// Compute the total number of values and find the largest value slice in the run, to maximize chance of storage reuse.
+	total := 0
+	totalBeforeMax := 0 // number of elements preceding the maximum block (i.e. its position in the result).
+	max_b := b          // block with maximum capacity
+
+	for bx := b; ; bx = bx.Succs[0].b {
+		if cap(bx.Values) > cap(max_b.Values) {
+			totalBeforeMax = total
+			max_b = bx
+		}
+		total += len(bx.Values)
+		if bx == c {
+			break
+		}
 	}
-	// Use whichever value slice is larger, in the hopes of avoiding growth.
-	// However, take care to avoid c.Values pointing to b.valstorage.
+
+	// Use c's storage if fused blocks will fit, else use the max if that will fit, else allocate new storage.
+
+	// Take care to avoid c.Values pointing to b.valstorage.
 	// See golang.org/issue/18602.
+
 	// It's important to keep the elements in the same order; maintenance of
 	// debugging information depends on the order of *Values in Blocks.
 	// This can also cause changes in the order (which may affect other
 	// optimizations and possibly compiler output) for 32-vs-64 bit compilation
 	// platforms (word size affects allocation bucket size affects slice capacity).
-	if cap(c.Values) >= cap(b.Values) || len(b.Values) <= len(b.valstorage) {
-		bl := len(b.Values)
-		cl := len(c.Values)
-		var t []*Value // construct t = b.Values followed-by c.Values, but with attention to allocation.
-		if cap(c.Values) < bl+cl {
-			// reallocate
-			t = make([]*Value, bl+cl)
-		} else {
-			// in place.
-			t = c.Values[0 : bl+cl]
-		}
-		copy(t[bl:], c.Values) // possibly in-place
-		c.Values = t
-		copy(c.Values, b.Values)
+
+	// figure out what slice will hold the values,
+	// preposition the destination elements if not allocating new storage
+	var t []*Value
+	if total <= len(c.valstorage) {
+		t = c.valstorage[:total]
+		max_b = c
+		totalBeforeMax = total - len(c.Values)
+		copy(t[totalBeforeMax:], c.Values)
+	} else if total <= cap(max_b.Values) { // in place, somewhere
+		t = max_b.Values[0:total]
+		copy(t[totalBeforeMax:], max_b.Values)
 	} else {
-		c.Values = append(b.Values, c.Values...)
+		t = make([]*Value, total)
+		max_b = nil
 	}
 
+	// copy the values
+	copyTo := 0
+	for bx := b; ; bx = bx.Succs[0].b {
+		if bx != max_b {
+			copy(t[copyTo:], bx.Values)
+		} else if copyTo != totalBeforeMax { // trust but verify.
+			panic(fmt.Errorf("totalBeforeMax (%d) != copyTo (%d), max_b=%v, b=%v, c=%v", totalBeforeMax, copyTo, max_b, b, c))
+		}
+		if bx == c {
+			break
+		}
+		copyTo += len(bx.Values)
+	}
+	c.Values = t
+
 	// replace b->c edge with preds(b) -> c
 	c.predstorage[0] = Edge{}
 	if len(b.Preds) > len(b.predstorage) {
@@ -247,10 +320,14 @@
 		f.Entry = c
 	}
 
-	// trash b, just in case
-	b.Kind = BlockInvalid
-	b.Values = nil
-	b.Preds = nil
-	b.Succs = nil
+	// trash b's fields, just in case
+	for bx := b; bx != c; bx = b_next {
+		b_next = bx.Succs[0].b
+
+		bx.Kind = BlockInvalid
+		bx.Values = nil
+		bx.Preds = nil
+		bx.Succs = nil
+	}
 	return true
 }
diff --git a/src/cmd/compile/internal/ssa/fuse_test.go b/src/cmd/compile/internal/ssa/fuse_test.go
index 27a14b1..fa7921a 100644
--- a/src/cmd/compile/internal/ssa/fuse_test.go
+++ b/src/cmd/compile/internal/ssa/fuse_test.go
@@ -1,3 +1,7 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
 package ssa
 
 import (
diff --git a/src/cmd/compile/internal/ssa/gen/386.rules b/src/cmd/compile/internal/ssa/gen/386.rules
deleted file mode 100644
index 7bdebed..0000000
--- a/src/cmd/compile/internal/ssa/gen/386.rules
+++ /dev/null
@@ -1,1112 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Lowering arithmetic
-(Add(Ptr|32|16|8) ...) => (ADDL ...)
-(Add(32|64)F ...) => (ADDS(S|D) ...)
-(Add32carry ...) => (ADDLcarry ...)
-(Add32withcarry ...) => (ADCL ...)
-
-(Sub(Ptr|32|16|8) ...) => (SUBL ...)
-(Sub(32|64)F ...) => (SUBS(S|D) ...)
-(Sub32carry ...) => (SUBLcarry ...)
-(Sub32withcarry ...) => (SBBL ...)
-
-(Mul(32|16|8) ...) => (MULL ...)
-(Mul(32|64)F ...) => (MULS(S|D) ...)
-(Mul32uhilo ...) => (MULLQU ...)
-
-(Select0 (Mul32uover x y)) => (Select0 <typ.UInt32> (MULLU x y))
-(Select1 (Mul32uover x y)) => (SETO (Select1 <types.TypeFlags> (MULLU x y)))
-
-(Avg32u ...) => (AVGLU ...)
-
-(Div(32|64)F ...) => (DIVS(S|D) ...)
-(Div(32|32u|16|16u) ...) => (DIV(L|LU|W|WU) ...)
-(Div8   x y) => (DIVW  (SignExt8to16 x) (SignExt8to16 y))
-(Div8u  x y) => (DIVWU (ZeroExt8to16 x) (ZeroExt8to16 y))
-
-(Hmul(32|32u) ...) => (HMUL(L|LU) ...)
-
-(Mod(32|32u|16|16u) ...) => (MOD(L|LU|W|WU) ...)
-(Mod8   x y) => (MODW  (SignExt8to16 x) (SignExt8to16 y))
-(Mod8u  x y) => (MODWU (ZeroExt8to16 x) (ZeroExt8to16 y))
-
-(And(32|16|8) ...) => (ANDL ...)
-(Or(32|16|8) ...) => (ORL ...)
-(Xor(32|16|8) ...) => (XORL ...)
-
-(Neg(32|16|8) ...) => (NEGL ...)
-(Neg32F x) => (PXOR x (MOVSSconst <typ.Float32> [float32(math.Copysign(0, -1))]))
-(Neg64F x) => (PXOR x (MOVSDconst <typ.Float64> [math.Copysign(0, -1)]))
-
-(Com(32|16|8) ...) => (NOTL ...)
-
-// Lowering boolean ops
-(AndB ...) => (ANDL ...)
-(OrB ...) => (ORL ...)
-(Not x) => (XORLconst [1] x)
-
-// Lowering pointer arithmetic
-(OffPtr [off] ptr) => (ADDLconst [int32(off)] ptr)
-
-(Bswap32 ...) => (BSWAPL ...)
-
-(Sqrt ...) => (SQRTSD ...)
-(Sqrt32 ...) => (SQRTSS ...)
-
-(Ctz16 x) => (BSFL (ORLconst <typ.UInt32> [0x10000] x))
-(Ctz16NonZero ...) => (BSFL ...)
-
-// Lowering extension
-(SignExt8to16  ...) => (MOVBLSX ...)
-(SignExt8to32  ...) => (MOVBLSX ...)
-(SignExt16to32 ...) => (MOVWLSX ...)
-
-(ZeroExt8to16  ...) => (MOVBLZX ...)
-(ZeroExt8to32  ...) => (MOVBLZX ...)
-(ZeroExt16to32 ...) => (MOVWLZX ...)
-
-(Signmask x) => (SARLconst x [31])
-(Zeromask <t> x) => (XORLconst [-1] (SBBLcarrymask <t> (CMPLconst x [1])))
-(Slicemask <t> x) => (SARLconst (NEGL <t> x) [31])
-
-// Lowering truncation
-// Because we ignore high parts of registers, truncates are just copies.
-(Trunc16to8  ...) => (Copy ...)
-(Trunc32to8  ...) => (Copy ...)
-(Trunc32to16 ...) => (Copy ...)
-
-// Lowering float-int conversions
-(Cvt32to32F ...) => (CVTSL2SS ...)
-(Cvt32to64F ...) => (CVTSL2SD ...)
-
-(Cvt32Fto32 ...) => (CVTTSS2SL ...)
-(Cvt64Fto32 ...) => (CVTTSD2SL ...)
-
-(Cvt32Fto64F ...) => (CVTSS2SD ...)
-(Cvt64Fto32F ...) => (CVTSD2SS ...)
-
-(Round32F ...) => (Copy ...)
-(Round64F ...) => (Copy ...)
-
-(CvtBoolToUint8 ...) => (Copy ...)
-
-// Lowering shifts
-// Unsigned shifts need to return 0 if shift amount is >= width of shifted value.
-//   result = (arg << shift) & (shift >= argbits ? 0 : 0xffffffffffffffff)
-(Lsh32x(32|16|8) <t> x y) && !shiftIsBounded(v) => (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMP(L|W|B)const y [32])))
-(Lsh16x(32|16|8) <t> x y) && !shiftIsBounded(v) => (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMP(L|W|B)const y [32])))
-(Lsh8x(32|16|8)  <t> x y) && !shiftIsBounded(v) => (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMP(L|W|B)const y [32])))
-
-(Lsh32x(32|16|8) <t> x y) && shiftIsBounded(v) => (SHLL <t> x y)
-(Lsh16x(32|16|8) <t> x y) && shiftIsBounded(v) => (SHLL <t> x y)
-(Lsh8x(32|16|8)  <t> x y) && shiftIsBounded(v) => (SHLL <t> x y)
-
-(Rsh32Ux(32|16|8) <t> x y) && !shiftIsBounded(v) => (ANDL (SHRL <t> x y) (SBBLcarrymask <t> (CMP(L|W|B)const y [32])))
-(Rsh16Ux(32|16|8) <t> x y) && !shiftIsBounded(v) => (ANDL (SHRW <t> x y) (SBBLcarrymask <t> (CMP(L|W|B)const y [16])))
-(Rsh8Ux(32|16|8)  <t> x y) && !shiftIsBounded(v) => (ANDL (SHRB <t> x y) (SBBLcarrymask <t> (CMP(L|W|B)const y [8])))
-
-(Rsh32Ux(32|16|8) <t> x y) && shiftIsBounded(v) => (SHRL <t> x y)
-(Rsh16Ux(32|16|8) <t> x y) && shiftIsBounded(v) => (SHRW <t> x y)
-(Rsh8Ux(32|16|8)  <t> x y) && shiftIsBounded(v) => (SHRB <t> x y)
-
-// Signed right shift needs to return 0/-1 if shift amount is >= width of shifted value.
-// We implement this by setting the shift value to -1 (all ones) if the shift value is >= width.
-
-(Rsh32x(32|16|8) <t> x y) && !shiftIsBounded(v) => (SARL <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMP(L|W|B)const y [32])))))
-(Rsh16x(32|16|8) <t> x y) && !shiftIsBounded(v) => (SARW <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMP(L|W|B)const y [16])))))
-(Rsh8x(32|16|8) <t> x y)  && !shiftIsBounded(v) => (SARB <t> x (ORL <y.Type> y (NOTL <y.Type> (SBBLcarrymask <y.Type> (CMP(L|W|B)const y [8])))))
-
-(Rsh32x(32|16|8) <t> x y) && shiftIsBounded(v) => (SARL x y)
-(Rsh16x(32|16|8) <t> x y) && shiftIsBounded(v) => (SARW x y)
-(Rsh8x(32|16|8) <t> x y)  && shiftIsBounded(v) => (SARB x y)
-
-// constant shifts
-// generic opt rewrites all constant shifts to shift by Const64
-(Lsh32x64 x (Const64 [c])) && uint64(c) < 32 => (SHLLconst x [int32(c)])
-(Rsh32x64 x (Const64 [c])) && uint64(c) < 32 => (SARLconst x [int32(c)])
-(Rsh32Ux64 x (Const64 [c])) && uint64(c) < 32 => (SHRLconst x [int32(c)])
-(Lsh16x64 x (Const64 [c])) && uint64(c) < 16 => (SHLLconst x [int32(c)])
-(Rsh16x64 x (Const64 [c])) && uint64(c) < 16 => (SARWconst x [int16(c)])
-(Rsh16Ux64 x (Const64 [c])) && uint64(c) < 16 => (SHRWconst x [int16(c)])
-(Lsh8x64 x (Const64 [c])) && uint64(c) < 8 => (SHLLconst x [int32(c)])
-(Rsh8x64 x (Const64 [c])) && uint64(c) < 8 => (SARBconst x [int8(c)])
-(Rsh8Ux64 x (Const64 [c])) && uint64(c) < 8 => (SHRBconst x [int8(c)])
-
-// large constant shifts
-(Lsh32x64 _ (Const64 [c])) && uint64(c) >= 32 => (Const32 [0])
-(Rsh32Ux64 _ (Const64 [c])) && uint64(c) >= 32 => (Const32 [0])
-(Lsh16x64 _ (Const64 [c])) && uint64(c) >= 16 => (Const16 [0])
-(Rsh16Ux64 _ (Const64 [c])) && uint64(c) >= 16 => (Const16 [0])
-(Lsh8x64 _ (Const64 [c])) && uint64(c) >= 8 => (Const8 [0])
-(Rsh8Ux64 _ (Const64 [c])) && uint64(c) >= 8 => (Const8 [0])
-
-// large constant signed right shift, we leave the sign bit
-(Rsh32x64 x (Const64 [c])) && uint64(c) >= 32 => (SARLconst x [31])
-(Rsh16x64 x (Const64 [c])) && uint64(c) >= 16 => (SARWconst x [15])
-(Rsh8x64 x (Const64 [c])) && uint64(c) >= 8 => (SARBconst x [7])
-
-// constant rotates
-(RotateLeft32 x (MOVLconst [c])) => (ROLLconst [c&31] x)
-(RotateLeft16 x (MOVLconst [c])) => (ROLWconst [int16(c&15)] x)
-(RotateLeft8 x (MOVLconst [c]))  => (ROLBconst [int8(c&7)] x)
-
-// Lowering comparisons
-(Less32  x y) => (SETL (CMPL x y))
-(Less16  x y) => (SETL (CMPW x y))
-(Less8   x y) => (SETL (CMPB x y))
-(Less32U x y) => (SETB (CMPL x y))
-(Less16U x y) => (SETB (CMPW x y))
-(Less8U  x y) => (SETB (CMPB x y))
-// Use SETGF with reversed operands to dodge NaN case
-(Less64F x y) => (SETGF (UCOMISD y x))
-(Less32F x y) => (SETGF (UCOMISS y x))
-
-(Leq32  x y) => (SETLE (CMPL x y))
-(Leq16  x y) => (SETLE (CMPW x y))
-(Leq8   x y) => (SETLE (CMPB x y))
-(Leq32U x y) => (SETBE (CMPL x y))
-(Leq16U x y) => (SETBE (CMPW x y))
-(Leq8U  x y) => (SETBE (CMPB x y))
-// Use SETGEF with reversed operands to dodge NaN case
-(Leq64F x y) => (SETGEF (UCOMISD y x))
-(Leq32F x y) => (SETGEF (UCOMISS y x))
-
-(Eq32  x y) => (SETEQ (CMPL x y))
-(Eq16  x y) => (SETEQ (CMPW x y))
-(Eq8   x y) => (SETEQ (CMPB x y))
-(EqB   x y) => (SETEQ (CMPB x y))
-(EqPtr x y) => (SETEQ (CMPL x y))
-(Eq64F x y) => (SETEQF (UCOMISD x y))
-(Eq32F x y) => (SETEQF (UCOMISS x y))
-
-(Neq32  x y) => (SETNE (CMPL x y))
-(Neq16  x y) => (SETNE (CMPW x y))
-(Neq8   x y) => (SETNE (CMPB x y))
-(NeqB   x y) => (SETNE (CMPB x y))
-(NeqPtr x y) => (SETNE (CMPL x y))
-(Neq64F x y) => (SETNEF (UCOMISD x y))
-(Neq32F x y) => (SETNEF (UCOMISS x y))
-
-// Lowering loads
-(Load <t> ptr mem) && (is32BitInt(t) || isPtr(t)) => (MOVLload ptr mem)
-(Load <t> ptr mem) && is16BitInt(t) => (MOVWload ptr mem)
-(Load <t> ptr mem) && (t.IsBoolean() || is8BitInt(t)) => (MOVBload ptr mem)
-(Load <t> ptr mem) && is32BitFloat(t) => (MOVSSload ptr mem)
-(Load <t> ptr mem) && is64BitFloat(t) => (MOVSDload ptr mem)
-
-// Lowering stores
-// These more-specific FP versions of Store pattern should come first.
-(Store {t} ptr val mem) && t.Size() == 8 && is64BitFloat(val.Type) => (MOVSDstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 4 && is32BitFloat(val.Type) => (MOVSSstore ptr val mem)
-
-(Store {t} ptr val mem) && t.Size() == 4 => (MOVLstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 2 => (MOVWstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 1 => (MOVBstore ptr val mem)
-
-// Lowering moves
-(Move [0] _ _ mem) => mem
-(Move [1] dst src mem) => (MOVBstore dst (MOVBload src mem) mem)
-(Move [2] dst src mem) => (MOVWstore dst (MOVWload src mem) mem)
-(Move [4] dst src mem) => (MOVLstore dst (MOVLload src mem) mem)
-(Move [3] dst src mem) =>
-	(MOVBstore [2] dst (MOVBload [2] src mem)
-		(MOVWstore dst (MOVWload src mem) mem))
-(Move [5] dst src mem) =>
-	(MOVBstore [4] dst (MOVBload [4] src mem)
-		(MOVLstore dst (MOVLload src mem) mem))
-(Move [6] dst src mem) =>
-	(MOVWstore [4] dst (MOVWload [4] src mem)
-		(MOVLstore dst (MOVLload src mem) mem))
-(Move [7] dst src mem) =>
-	(MOVLstore [3] dst (MOVLload [3] src mem)
-		(MOVLstore dst (MOVLload src mem) mem))
-(Move [8] dst src mem) =>
-	(MOVLstore [4] dst (MOVLload [4] src mem)
-		(MOVLstore dst (MOVLload src mem) mem))
-
-// Adjust moves to be a multiple of 4 bytes.
-(Move [s] dst src mem)
-	&& s > 8 && s%4 != 0 =>
-	(Move [s-s%4]
-		(ADDLconst <dst.Type> dst [int32(s%4)])
-		(ADDLconst <src.Type> src [int32(s%4)])
-		(MOVLstore dst (MOVLload src mem) mem))
-
-// Medium copying uses a duff device.
-(Move [s] dst src mem)
-	&& s > 8 && s <= 4*128 && s%4 == 0
-	&& !config.noDuffDevice && logLargeCopy(v, s) =>
-	(DUFFCOPY [10*(128-s/4)] dst src mem)
-// 10 and 128 are magic constants.  10 is the number of bytes to encode:
-//	MOVL	(SI), CX
-//	ADDL	$4, SI
-//	MOVL	CX, (DI)
-//	ADDL	$4, DI
-// and 128 is the number of such blocks. See src/runtime/duff_386.s:duffcopy.
-
-// Large copying uses REP MOVSL.
-(Move [s] dst src mem) && (s > 4*128 || config.noDuffDevice) && s%4 == 0 && logLargeCopy(v, s) =>
-	(REPMOVSL dst src (MOVLconst [int32(s/4)]) mem)
-
-// Lowering Zero instructions
-(Zero [0] _ mem) => mem
-(Zero [1] destptr mem) => (MOVBstoreconst [0] destptr mem)
-(Zero [2] destptr mem) => (MOVWstoreconst [0] destptr mem)
-(Zero [4] destptr mem) => (MOVLstoreconst [0] destptr mem)
-
-(Zero [3] destptr mem) =>
-	(MOVBstoreconst [makeValAndOff(0,2)] destptr
-		(MOVWstoreconst [makeValAndOff(0,0)] destptr mem))
-(Zero [5] destptr mem) =>
-	(MOVBstoreconst [makeValAndOff(0,4)] destptr
-		(MOVLstoreconst [makeValAndOff(0,0)] destptr mem))
-(Zero [6] destptr mem) =>
-	(MOVWstoreconst [makeValAndOff(0,4)] destptr
-		(MOVLstoreconst [makeValAndOff(0,0)] destptr mem))
-(Zero [7] destptr mem) =>
-	(MOVLstoreconst [makeValAndOff(0,3)] destptr
-		(MOVLstoreconst [makeValAndOff(0,0)] destptr mem))
-
-// Strip off any fractional word zeroing.
-(Zero [s] destptr mem) && s%4 != 0 && s > 4 =>
-	(Zero [s-s%4] (ADDLconst destptr [int32(s%4)])
-		(MOVLstoreconst [0] destptr mem))
-
-// Zero small numbers of words directly.
-(Zero [8] destptr mem) =>
-	(MOVLstoreconst [makeValAndOff(0,4)] destptr
-		(MOVLstoreconst [makeValAndOff(0,0)] destptr mem))
-(Zero [12] destptr mem) =>
-	(MOVLstoreconst [makeValAndOff(0,8)] destptr
-		(MOVLstoreconst [makeValAndOff(0,4)] destptr
-			(MOVLstoreconst [makeValAndOff(0,0)] destptr mem)))
-(Zero [16] destptr mem) =>
-	(MOVLstoreconst [makeValAndOff(0,12)] destptr
-		(MOVLstoreconst [makeValAndOff(0,8)] destptr
-			(MOVLstoreconst [makeValAndOff(0,4)] destptr
-				(MOVLstoreconst [makeValAndOff(0,0)] destptr mem))))
-
-// Medium zeroing uses a duff device.
-(Zero [s] destptr mem)
-  && s > 16 && s <= 4*128 && s%4 == 0
-  && !config.noDuffDevice =>
-	(DUFFZERO [1*(128-s/4)] destptr (MOVLconst [0]) mem)
-// 1 and 128 are magic constants.  1 is the number of bytes to encode STOSL.
-// 128 is the number of STOSL instructions in duffzero.
-// See src/runtime/duff_386.s:duffzero.
-
-// Large zeroing uses REP STOSQ.
-(Zero [s] destptr mem)
-  && (s > 4*128 || (config.noDuffDevice && s > 16))
-  && s%4 == 0 =>
-	(REPSTOSL destptr (MOVLconst [int32(s/4)]) (MOVLconst [0]) mem)
-
-
-// Lowering constants
-(Const8   [c]) => (MOVLconst [int32(c)])
-(Const16  [c]) => (MOVLconst [int32(c)])
-(Const32  ...) => (MOVLconst ...)
-(Const(32|64)F ...) => (MOVS(S|D)const ...)
-(ConstNil) => (MOVLconst [0])
-(ConstBool [c]) => (MOVLconst [b2i32(c)])
-
-// Lowering calls
-(StaticCall ...) => (CALLstatic ...)
-(ClosureCall ...) => (CALLclosure ...)
-(InterCall ...) => (CALLinter ...)
-(TailCall ...) => (CALLtail ...)
-
-// Miscellaneous
-(IsNonNil p) => (SETNE (TESTL p p))
-(IsInBounds idx len) => (SETB (CMPL idx len))
-(IsSliceInBounds idx len) => (SETBE (CMPL idx len))
-(NilCheck ...) => (LoweredNilCheck ...)
-(GetG ...) => (LoweredGetG ...)
-(GetClosurePtr ...) => (LoweredGetClosurePtr ...)
-(GetCallerPC ...) => (LoweredGetCallerPC ...)
-(GetCallerSP ...) => (LoweredGetCallerSP ...)
-(Addr {sym} base) => (LEAL {sym} base)
-(LocalAddr {sym} base _) => (LEAL {sym} base)
-
-// block rewrites
-(If (SETL  cmp) yes no) => (LT  cmp yes no)
-(If (SETLE cmp) yes no) => (LE  cmp yes no)
-(If (SETG  cmp) yes no) => (GT  cmp yes no)
-(If (SETGE cmp) yes no) => (GE  cmp yes no)
-(If (SETEQ cmp) yes no) => (EQ  cmp yes no)
-(If (SETNE cmp) yes no) => (NE  cmp yes no)
-(If (SETB  cmp) yes no) => (ULT cmp yes no)
-(If (SETBE cmp) yes no) => (ULE cmp yes no)
-(If (SETA  cmp) yes no) => (UGT cmp yes no)
-(If (SETAE cmp) yes no) => (UGE cmp yes no)
-(If (SETO  cmp) yes no) => (OS cmp yes no)
-
-// Special case for floating point - LF/LEF not generated
-(If (SETGF  cmp) yes no) => (UGT  cmp yes no)
-(If (SETGEF cmp) yes no) => (UGE  cmp yes no)
-(If (SETEQF cmp) yes no) => (EQF  cmp yes no)
-(If (SETNEF cmp) yes no) => (NEF  cmp yes no)
-
-(If cond yes no) => (NE (TESTB cond cond) yes no)
-
-// Write barrier.
-(WB ...) => (LoweredWB ...)
-
-(PanicBounds [kind] x y mem) && boundsABI(kind) == 0 => (LoweredPanicBoundsA [kind] x y mem)
-(PanicBounds [kind] x y mem) && boundsABI(kind) == 1 => (LoweredPanicBoundsB [kind] x y mem)
-(PanicBounds [kind] x y mem) && boundsABI(kind) == 2 => (LoweredPanicBoundsC [kind] x y mem)
-
-(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 0 => (LoweredPanicExtendA [kind] hi lo y mem)
-(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 1 => (LoweredPanicExtendB [kind] hi lo y mem)
-(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 2 => (LoweredPanicExtendC [kind] hi lo y mem)
-
-// ***************************
-// Above: lowering rules
-// Below: optimizations
-// ***************************
-// TODO: Should the optimizations be a separate pass?
-
-// Fold boolean tests into blocks
-(NE (TESTB (SETL  cmp) (SETL  cmp)) yes no) => (LT  cmp yes no)
-(NE (TESTB (SETLE cmp) (SETLE cmp)) yes no) => (LE  cmp yes no)
-(NE (TESTB (SETG  cmp) (SETG  cmp)) yes no) => (GT  cmp yes no)
-(NE (TESTB (SETGE cmp) (SETGE cmp)) yes no) => (GE  cmp yes no)
-(NE (TESTB (SETEQ cmp) (SETEQ cmp)) yes no) => (EQ  cmp yes no)
-(NE (TESTB (SETNE cmp) (SETNE cmp)) yes no) => (NE  cmp yes no)
-(NE (TESTB (SETB  cmp) (SETB  cmp)) yes no) => (ULT cmp yes no)
-(NE (TESTB (SETBE cmp) (SETBE cmp)) yes no) => (ULE cmp yes no)
-(NE (TESTB (SETA  cmp) (SETA  cmp)) yes no) => (UGT cmp yes no)
-(NE (TESTB (SETAE cmp) (SETAE cmp)) yes no) => (UGE cmp yes no)
-(NE (TESTB (SETO cmp) (SETO cmp)) yes no) => (OS cmp yes no)
-
-// Special case for floating point - LF/LEF not generated
-(NE (TESTB (SETGF  cmp) (SETGF  cmp)) yes no) => (UGT  cmp yes no)
-(NE (TESTB (SETGEF cmp) (SETGEF cmp)) yes no) => (UGE  cmp yes no)
-(NE (TESTB (SETEQF cmp) (SETEQF cmp)) yes no) => (EQF  cmp yes no)
-(NE (TESTB (SETNEF cmp) (SETNEF cmp)) yes no) => (NEF  cmp yes no)
-
-// fold constants into instructions
-(ADDL x (MOVLconst [c])) => (ADDLconst [c] x)
-(ADDLcarry x (MOVLconst [c])) => (ADDLconstcarry [c] x)
-(ADCL x (MOVLconst [c]) f) => (ADCLconst [c] x f)
-
-(SUBL x (MOVLconst [c])) => (SUBLconst x [c])
-(SUBL (MOVLconst [c]) x) => (NEGL (SUBLconst <v.Type> x [c]))
-(SUBLcarry x (MOVLconst [c])) => (SUBLconstcarry [c] x)
-(SBBL x (MOVLconst [c]) f) => (SBBLconst [c] x f)
-
-(MULL x (MOVLconst [c])) => (MULLconst [c] x)
-(ANDL x (MOVLconst [c])) => (ANDLconst [c] x)
-
-(ANDLconst [c] (ANDLconst [d] x)) => (ANDLconst [c & d] x)
-(XORLconst [c] (XORLconst [d] x)) => (XORLconst [c ^ d] x)
-(MULLconst [c] (MULLconst [d] x)) => (MULLconst [c * d] x)
-
-(ORL x (MOVLconst [c])) => (ORLconst [c] x)
-(XORL x (MOVLconst [c])) => (XORLconst [c] x)
-
-(SHLL x (MOVLconst [c])) => (SHLLconst [c&31] x)
-(SHRL x (MOVLconst [c])) => (SHRLconst [c&31] x)
-(SHRW x (MOVLconst [c])) && c&31 < 16 => (SHRWconst [int16(c&31)] x)
-(SHRW _ (MOVLconst [c])) && c&31 >= 16 => (MOVLconst [0])
-(SHRB x (MOVLconst [c])) && c&31 < 8 => (SHRBconst [int8(c&31)] x)
-(SHRB _ (MOVLconst [c])) && c&31 >= 8 => (MOVLconst [0])
-
-(SARL x (MOVLconst [c])) => (SARLconst [c&31] x)
-(SARW x (MOVLconst [c])) => (SARWconst [int16(min(int64(c&31),15))] x)
-(SARB x (MOVLconst [c])) => (SARBconst [int8(min(int64(c&31),7))] x)
-
-(SARL x (ANDLconst [31] y)) => (SARL x y)
-(SHLL x (ANDLconst [31] y)) => (SHLL x y)
-(SHRL x (ANDLconst [31] y)) => (SHRL x y)
-
-// Rotate instructions
-
-(ADDL (SHLLconst [c] x) (SHRLconst [d] x)) && d == 32-c => (ROLLconst [c] x)
-( ORL (SHLLconst [c] x) (SHRLconst [d] x)) && d == 32-c => (ROLLconst [c] x)
-(XORL (SHLLconst [c] x) (SHRLconst [d] x)) && d == 32-c => (ROLLconst [c] x)
-
-(ADDL <t> (SHLLconst x [c]) (SHRWconst x [d])) && c < 16 && d == int16(16-c) && t.Size() == 2
-  => (ROLWconst x [int16(c)])
-( ORL <t> (SHLLconst x [c]) (SHRWconst x [d])) && c < 16 && d == int16(16-c) && t.Size() == 2
-  => (ROLWconst x [int16(c)])
-(XORL <t> (SHLLconst x [c]) (SHRWconst x [d])) && c < 16 && d == int16(16-c) && t.Size() == 2
-  => (ROLWconst x [int16(c)])
-
-(ADDL <t> (SHLLconst x [c]) (SHRBconst x [d])) && c < 8 && d == int8(8-c) && t.Size() == 1
-  => (ROLBconst x [int8(c)])
-( ORL <t> (SHLLconst x [c]) (SHRBconst x [d])) && c < 8 && d == int8(8-c) && t.Size() == 1
-  => (ROLBconst x [int8(c)])
-(XORL <t> (SHLLconst x [c]) (SHRBconst x [d])) && c < 8 && d == int8(8-c) && t.Size() == 1
-  => (ROLBconst x [int8(c)])
-
-(ROLLconst [c] (ROLLconst [d] x)) => (ROLLconst [(c+d)&31] x)
-(ROLWconst [c] (ROLWconst [d] x)) => (ROLWconst [(c+d)&15] x)
-(ROLBconst [c] (ROLBconst [d] x)) => (ROLBconst [(c+d)& 7] x)
-
-
-// Constant shift simplifications
-
-(SHLLconst x [0]) => x
-(SHRLconst x [0]) => x
-(SARLconst x [0]) => x
-
-(SHRWconst x [0]) => x
-(SARWconst x [0]) => x
-
-(SHRBconst x [0]) => x
-(SARBconst x [0]) => x
-
-(ROLLconst [0] x) => x
-(ROLWconst [0] x) => x
-(ROLBconst [0] x) => x
-
-// Note: the word and byte shifts keep the low 5 bits (not the low 4 or 3 bits)
-// because the x86 instructions are defined to use all 5 bits of the shift even
-// for the small shifts. I don't think we'll ever generate a weird shift (e.g.
-// (SHRW x (MOVLconst [24])), but just in case.
-
-(CMPL x (MOVLconst [c])) => (CMPLconst x [c])
-(CMPL (MOVLconst [c]) x) => (InvertFlags (CMPLconst x [c]))
-(CMPW x (MOVLconst [c])) => (CMPWconst x [int16(c)])
-(CMPW (MOVLconst [c]) x) => (InvertFlags (CMPWconst x [int16(c)]))
-(CMPB x (MOVLconst [c])) => (CMPBconst x [int8(c)])
-(CMPB (MOVLconst [c]) x) => (InvertFlags (CMPBconst x [int8(c)]))
-
-// Canonicalize the order of arguments to comparisons - helps with CSE.
-(CMP(L|W|B) x y) && canonLessThan(x,y) => (InvertFlags (CMP(L|W|B) y x))
-
-// strength reduction
-// Assumes that the following costs from https://gmplib.org/~tege/x86-timing.pdf:
-//    1 - addl, shll, leal, negl, subl
-//    3 - imull
-// This limits the rewrites to two instructions.
-// Note that negl always operates in-place,
-// which can require a register-register move
-// to preserve the original value,
-// so it must be used with care.
-(MULLconst [-9] x) => (NEGL (LEAL8 <v.Type> x x))
-(MULLconst [-5] x) => (NEGL (LEAL4 <v.Type> x x))
-(MULLconst [-3] x) => (NEGL (LEAL2 <v.Type> x x))
-(MULLconst [-1] x) => (NEGL x)
-(MULLconst [0] _) => (MOVLconst [0])
-(MULLconst [1] x) => x
-(MULLconst [3] x) => (LEAL2 x x)
-(MULLconst [5] x) => (LEAL4 x x)
-(MULLconst [7] x) => (LEAL2 x (LEAL2 <v.Type> x x))
-(MULLconst [9] x) => (LEAL8 x x)
-(MULLconst [11] x) => (LEAL2 x (LEAL4 <v.Type> x x))
-(MULLconst [13] x) => (LEAL4 x (LEAL2 <v.Type> x x))
-(MULLconst [19] x) => (LEAL2 x (LEAL8 <v.Type> x x))
-(MULLconst [21] x) => (LEAL4 x (LEAL4 <v.Type> x x))
-(MULLconst [25] x) => (LEAL8 x (LEAL2 <v.Type> x x))
-(MULLconst [27] x) => (LEAL8 (LEAL2 <v.Type> x x) (LEAL2 <v.Type> x x))
-(MULLconst [37] x) => (LEAL4 x (LEAL8 <v.Type> x x))
-(MULLconst [41] x) => (LEAL8 x (LEAL4 <v.Type> x x))
-(MULLconst [45] x) => (LEAL8 (LEAL4 <v.Type> x x) (LEAL4 <v.Type> x x))
-(MULLconst [73] x) => (LEAL8 x (LEAL8 <v.Type> x x))
-(MULLconst [81] x) => (LEAL8 (LEAL8 <v.Type> x x) (LEAL8 <v.Type> x x))
-
-(MULLconst [c] x) && isPowerOfTwo32(c+1) && c >= 15 => (SUBL (SHLLconst <v.Type> [int32(log32(c+1))] x) x)
-(MULLconst [c] x) && isPowerOfTwo32(c-1) && c >= 17 => (LEAL1 (SHLLconst <v.Type> [int32(log32(c-1))] x) x)
-(MULLconst [c] x) && isPowerOfTwo32(c-2) && c >= 34 => (LEAL2 (SHLLconst <v.Type> [int32(log32(c-2))] x) x)
-(MULLconst [c] x) && isPowerOfTwo32(c-4) && c >= 68 => (LEAL4 (SHLLconst <v.Type> [int32(log32(c-4))] x) x)
-(MULLconst [c] x) && isPowerOfTwo32(c-8) && c >= 136 => (LEAL8 (SHLLconst <v.Type> [int32(log32(c-8))] x) x)
-(MULLconst [c] x) && c%3 == 0 && isPowerOfTwo32(c/3) => (SHLLconst [int32(log32(c/3))] (LEAL2 <v.Type> x x))
-(MULLconst [c] x) && c%5 == 0 && isPowerOfTwo32(c/5) => (SHLLconst [int32(log32(c/5))] (LEAL4 <v.Type> x x))
-(MULLconst [c] x) && c%9 == 0 && isPowerOfTwo32(c/9) => (SHLLconst [int32(log32(c/9))] (LEAL8 <v.Type> x x))
-
-// combine add/shift into LEAL
-(ADDL x (SHLLconst [3] y)) => (LEAL8 x y)
-(ADDL x (SHLLconst [2] y)) => (LEAL4 x y)
-(ADDL x (SHLLconst [1] y)) => (LEAL2 x y)
-(ADDL x (ADDL y y)) => (LEAL2 x y)
-(ADDL x (ADDL x y)) => (LEAL2 y x)
-
-// combine ADDL/ADDLconst into LEAL1
-(ADDLconst [c] (ADDL x y)) => (LEAL1 [c] x y)
-(ADDL (ADDLconst [c] x) y) => (LEAL1 [c] x y)
-
-// fold ADDL into LEAL
-(ADDLconst [c] (LEAL [d] {s} x)) && is32Bit(int64(c)+int64(d)) => (LEAL [c+d] {s} x)
-(LEAL [c] {s} (ADDLconst [d] x)) && is32Bit(int64(c)+int64(d)) => (LEAL [c+d] {s} x)
-(ADDLconst [c] x:(SP)) => (LEAL [c] x) // so it is rematerializeable
-(LEAL [c] {s} (ADDL x y)) && x.Op != OpSB && y.Op != OpSB => (LEAL1 [c] {s} x y)
-(ADDL x (LEAL [c] {s} y)) && x.Op != OpSB && y.Op != OpSB => (LEAL1 [c] {s} x y)
-
-// fold ADDLconst into LEALx
-(ADDLconst [c] (LEAL1 [d] {s} x y)) && is32Bit(int64(c)+int64(d)) => (LEAL1 [c+d] {s} x y)
-(ADDLconst [c] (LEAL2 [d] {s} x y)) && is32Bit(int64(c)+int64(d)) => (LEAL2 [c+d] {s} x y)
-(ADDLconst [c] (LEAL4 [d] {s} x y)) && is32Bit(int64(c)+int64(d)) => (LEAL4 [c+d] {s} x y)
-(ADDLconst [c] (LEAL8 [d] {s} x y)) && is32Bit(int64(c)+int64(d)) => (LEAL8 [c+d] {s} x y)
-(LEAL1 [c] {s} (ADDLconst [d] x) y) && is32Bit(int64(c)+int64(d))   && x.Op != OpSB => (LEAL1 [c+d] {s} x y)
-(LEAL2 [c] {s} (ADDLconst [d] x) y) && is32Bit(int64(c)+int64(d))   && x.Op != OpSB => (LEAL2 [c+d] {s} x y)
-(LEAL2 [c] {s} x (ADDLconst [d] y)) && is32Bit(int64(c)+2*int64(d)) && y.Op != OpSB => (LEAL2 [c+2*d] {s} x y)
-(LEAL4 [c] {s} (ADDLconst [d] x) y) && is32Bit(int64(c)+int64(d))   && x.Op != OpSB => (LEAL4 [c+d] {s} x y)
-(LEAL4 [c] {s} x (ADDLconst [d] y)) && is32Bit(int64(c)+4*int64(d)) && y.Op != OpSB => (LEAL4 [c+4*d] {s} x y)
-(LEAL8 [c] {s} (ADDLconst [d] x) y) && is32Bit(int64(c)+int64(d))   && x.Op != OpSB => (LEAL8 [c+d] {s} x y)
-(LEAL8 [c] {s} x (ADDLconst [d] y)) && is32Bit(int64(c)+8*int64(d)) && y.Op != OpSB => (LEAL8 [c+8*d] {s} x y)
-
-// fold shifts into LEALx
-(LEAL1 [c] {s} x (SHLLconst [1] y)) => (LEAL2 [c] {s} x y)
-(LEAL1 [c] {s} x (SHLLconst [2] y)) => (LEAL4 [c] {s} x y)
-(LEAL1 [c] {s} x (SHLLconst [3] y)) => (LEAL8 [c] {s} x y)
-(LEAL2 [c] {s} x (SHLLconst [1] y)) => (LEAL4 [c] {s} x y)
-(LEAL2 [c] {s} x (SHLLconst [2] y)) => (LEAL8 [c] {s} x y)
-(LEAL4 [c] {s} x (SHLLconst [1] y)) => (LEAL8 [c] {s} x y)
-
-// reverse ordering of compare instruction
-(SETL (InvertFlags x)) => (SETG x)
-(SETG (InvertFlags x)) => (SETL x)
-(SETB (InvertFlags x)) => (SETA x)
-(SETA (InvertFlags x)) => (SETB x)
-(SETLE (InvertFlags x)) => (SETGE x)
-(SETGE (InvertFlags x)) => (SETLE x)
-(SETBE (InvertFlags x)) => (SETAE x)
-(SETAE (InvertFlags x)) => (SETBE x)
-(SETEQ (InvertFlags x)) => (SETEQ x)
-(SETNE (InvertFlags x)) => (SETNE x)
-
-// sign extended loads
-// Note: The combined instruction must end up in the same block
-// as the original load. If not, we end up making a value with
-// memory type live in two different blocks, which can lead to
-// multiple memory values alive simultaneously.
-// Make sure we don't combine these ops if the load has another use.
-// This prevents a single load from being split into multiple loads
-// which then might return different values.  See test/atomicload.go.
-(MOVBLSX x:(MOVBload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVBLSXload <v.Type> [off] {sym} ptr mem)
-(MOVBLZX x:(MOVBload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVBload <v.Type> [off] {sym} ptr mem)
-(MOVWLSX x:(MOVWload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVWLSXload <v.Type> [off] {sym} ptr mem)
-(MOVWLZX x:(MOVWload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVWload <v.Type> [off] {sym} ptr mem)
-
-// replace load from same location as preceding store with zero/sign extension (or copy in case of full width)
-(MOVBload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVBLZX x)
-(MOVWload [off] {sym} ptr (MOVWstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVWLZX x)
-(MOVLload [off] {sym} ptr (MOVLstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => x
-(MOVBLSXload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVBLSX x)
-(MOVWLSXload [off] {sym} ptr (MOVWstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVWLSX x)
-
-// Fold extensions and ANDs together.
-(MOVBLZX (ANDLconst [c] x)) => (ANDLconst [c & 0xff] x)
-(MOVWLZX (ANDLconst [c] x)) => (ANDLconst [c & 0xffff] x)
-(MOVBLSX (ANDLconst [c] x)) && c & 0x80 == 0 => (ANDLconst [c & 0x7f] x)
-(MOVWLSX (ANDLconst [c] x)) && c & 0x8000 == 0 => (ANDLconst [c & 0x7fff] x)
-
-// Don't extend before storing
-(MOVWstore [off] {sym} ptr (MOVWL(S|Z)X x) mem) => (MOVWstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr (MOVBL(S|Z)X x) mem) => (MOVBstore [off] {sym} ptr x mem)
-
-// fold constants into memory operations
-// Note that this is not always a good idea because if not all the uses of
-// the ADDLconst get eliminated, we still have to compute the ADDLconst and we now
-// have potentially two live values (ptr and (ADDLconst [off] ptr)) instead of one.
-// Nevertheless, let's do it!
-(MOV(L|W|B|SS|SD)load  [off1] {sym} (ADDLconst [off2] ptr) mem) && is32Bit(int64(off1)+int64(off2)) =>
-    (MOV(L|W|B|SS|SD)load  [off1+off2] {sym} ptr mem)
-(MOV(L|W|B|SS|SD)store  [off1] {sym} (ADDLconst [off2] ptr) val mem) && is32Bit(int64(off1)+int64(off2)) =>
-    (MOV(L|W|B|SS|SD)store  [off1+off2] {sym} ptr val mem)
-
-((ADD|SUB|MUL|AND|OR|XOR)Lload [off1] {sym} val (ADDLconst [off2] base) mem) && is32Bit(int64(off1)+int64(off2)) =>
-	((ADD|SUB|MUL|AND|OR|XOR)Lload [off1+off2] {sym} val base mem)
-((ADD|SUB|MUL|DIV)SSload [off1] {sym} val (ADDLconst [off2] base) mem) && is32Bit(int64(off1)+int64(off2)) =>
-	((ADD|SUB|MUL|DIV)SSload [off1+off2] {sym} val base mem)
-((ADD|SUB|MUL|DIV)SDload [off1] {sym} val (ADDLconst [off2] base) mem) && is32Bit(int64(off1)+int64(off2)) =>
-	((ADD|SUB|MUL|DIV)SDload [off1+off2] {sym} val base mem)
-((ADD|SUB|AND|OR|XOR)Lmodify [off1] {sym} (ADDLconst [off2] base) val mem) && is32Bit(int64(off1)+int64(off2)) =>
-	((ADD|SUB|AND|OR|XOR)Lmodify [off1+off2] {sym} base val mem)
-((ADD|AND|OR|XOR)Lconstmodify [valoff1] {sym} (ADDLconst [off2] base) mem) && valoff1.canAdd32(off2) =>
-	((ADD|AND|OR|XOR)Lconstmodify [valoff1.addOffset32(off2)] {sym} base mem)
-
-// Fold constants into stores.
-(MOVLstore [off] {sym} ptr (MOVLconst [c]) mem) =>
-	(MOVLstoreconst [makeValAndOff(c,off)] {sym} ptr mem)
-(MOVWstore [off] {sym} ptr (MOVLconst [c]) mem) =>
-	(MOVWstoreconst [makeValAndOff(c,off)] {sym} ptr mem)
-(MOVBstore [off] {sym} ptr (MOVLconst [c]) mem) =>
-	(MOVBstoreconst [makeValAndOff(c,off)] {sym} ptr mem)
-
-// Fold address offsets into constant stores.
-(MOV(L|W|B)storeconst [sc] {s} (ADDLconst [off] ptr) mem) && sc.canAdd32(off) =>
-	(MOV(L|W|B)storeconst [sc.addOffset32(off)] {s} ptr mem)
-
-// We need to fold LEAL into the MOVx ops so that the live variable analysis knows
-// what variables are being read/written by the ops.
-// Note: we turn off this merging for operations on globals when building
-// position-independent code (when Flag_shared is set).
-// PIC needs a spare register to load the PC into.  Having the LEAL be
-// a separate instruction gives us that register.  Having the LEAL be
-// a separate instruction also allows it to be CSEd (which is good because
-// it compiles to a thunk call).
-(MOV(L|W|B|SS|SD|BLSX|WLSX)load  [off1] {sym1} (LEAL [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)
-  && (base.Op != OpSB || !config.ctxt.Flag_shared) =>
-        (MOV(L|W|B|SS|SD|BLSX|WLSX)load  [off1+off2] {mergeSym(sym1,sym2)} base mem)
-
-(MOV(L|W|B|SS|SD)store  [off1] {sym1} (LEAL [off2] {sym2} base) val mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2)
-  && (base.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(MOV(L|W|B|SS|SD)store  [off1+off2] {mergeSym(sym1,sym2)} base val mem)
-
-(MOV(L|W|B)storeconst [sc] {sym1} (LEAL [off] {sym2} ptr) mem) && canMergeSym(sym1, sym2) && sc.canAdd32(off)
-  && (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(MOV(L|W|B)storeconst [sc.addOffset32(off)] {mergeSym(sym1, sym2)} ptr mem)
-
-((ADD|SUB|MUL|AND|OR|XOR)Lload [off1] {sym1} val (LEAL [off2] {sym2} base) mem)
-	&& is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) =>
-	((ADD|SUB|MUL|AND|OR|XOR)Lload [off1+off2] {mergeSym(sym1,sym2)} val base mem)
-((ADD|SUB|MUL|DIV)SSload [off1] {sym1} val (LEAL [off2] {sym2} base) mem)
-	&& is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) =>
-	((ADD|SUB|MUL|DIV)SSload [off1+off2] {mergeSym(sym1,sym2)} val base mem)
-((ADD|SUB|MUL|DIV)SDload [off1] {sym1} val (LEAL [off2] {sym2} base) mem)
-	&& is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) =>
-	((ADD|SUB|MUL|DIV)SDload [off1+off2] {mergeSym(sym1,sym2)} val base mem)
-((ADD|SUB|AND|OR|XOR)Lmodify [off1] {sym1} (LEAL [off2] {sym2} base) val mem)
-	&& is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) =>
-	((ADD|SUB|AND|OR|XOR)Lmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem)
-((ADD|AND|OR|XOR)Lconstmodify [valoff1] {sym1} (LEAL [off2] {sym2} base) mem)
-	&& valoff1.canAdd32(off2) && canMergeSym(sym1, sym2) && (base.Op != OpSB || !config.ctxt.Flag_shared) =>
-	((ADD|AND|OR|XOR)Lconstmodify [valoff1.addOffset32(off2)] {mergeSym(sym1,sym2)} base mem)
-
-// Merge load/store to op
-((ADD|AND|OR|XOR|SUB|MUL)L x l:(MOVLload [off] {sym} ptr mem)) && canMergeLoadClobber(v, l, x) && clobber(l) => ((ADD|AND|OR|XOR|SUB|MUL)Lload x [off] {sym} ptr mem)
-((ADD|SUB|MUL|DIV)SD x l:(MOVSDload [off] {sym} ptr mem)) && canMergeLoadClobber(v, l, x) && clobber(l) => ((ADD|SUB|MUL|DIV)SDload x [off] {sym} ptr mem)
-((ADD|SUB|MUL|DIV)SS x l:(MOVSSload [off] {sym} ptr mem)) && canMergeLoadClobber(v, l, x) && clobber(l) => ((ADD|SUB|MUL|DIV)SSload x [off] {sym} ptr mem)
-(MOVLstore {sym} [off] ptr y:((ADD|AND|OR|XOR)Lload x [off] {sym} ptr mem) mem) && y.Uses==1 && clobber(y) => ((ADD|AND|OR|XOR)Lmodify [off] {sym} ptr x mem)
-(MOVLstore {sym} [off] ptr y:((ADD|SUB|AND|OR|XOR)L l:(MOVLload [off] {sym} ptr mem) x) mem) && y.Uses==1 && l.Uses==1 && clobber(y, l) =>
-	((ADD|SUB|AND|OR|XOR)Lmodify [off] {sym} ptr x mem)
-(MOVLstore {sym} [off] ptr y:((ADD|AND|OR|XOR)Lconst [c] l:(MOVLload [off] {sym} ptr mem)) mem)
-	&& y.Uses==1 && l.Uses==1 && clobber(y, l) =>
-	((ADD|AND|OR|XOR)Lconstmodify [makeValAndOff(c,off)] {sym} ptr mem)
-
-// fold LEALs together
-(LEAL [off1] {sym1} (LEAL [off2] {sym2} x)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-      (LEAL [off1+off2] {mergeSym(sym1,sym2)} x)
-
-// LEAL into LEAL1
-(LEAL1 [off1] {sym1} (LEAL [off2] {sym2} x) y) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB =>
-       (LEAL1 [off1+off2] {mergeSym(sym1,sym2)} x y)
-
-// LEAL1 into LEAL
-(LEAL [off1] {sym1} (LEAL1 [off2] {sym2} x y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-       (LEAL1 [off1+off2] {mergeSym(sym1,sym2)} x y)
-
-// LEAL into LEAL[248]
-(LEAL2 [off1] {sym1} (LEAL [off2] {sym2} x) y) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB =>
-       (LEAL2 [off1+off2] {mergeSym(sym1,sym2)} x y)
-(LEAL4 [off1] {sym1} (LEAL [off2] {sym2} x) y) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB =>
-       (LEAL4 [off1+off2] {mergeSym(sym1,sym2)} x y)
-(LEAL8 [off1] {sym1} (LEAL [off2] {sym2} x) y) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB =>
-       (LEAL8 [off1+off2] {mergeSym(sym1,sym2)} x y)
-
-// LEAL[248] into LEAL
-(LEAL [off1] {sym1} (LEAL2 [off2] {sym2} x y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-      (LEAL2 [off1+off2] {mergeSym(sym1,sym2)} x y)
-(LEAL [off1] {sym1} (LEAL4 [off2] {sym2} x y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-      (LEAL4 [off1+off2] {mergeSym(sym1,sym2)} x y)
-(LEAL [off1] {sym1} (LEAL8 [off2] {sym2} x y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-      (LEAL8 [off1+off2] {mergeSym(sym1,sym2)} x y)
-
-// LEAL[1248] into LEAL[1248]. Only some such merges are possible.
-(LEAL1 [off1] {sym1} x (LEAL1 [off2] {sym2} y y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-      (LEAL2 [off1+off2] {mergeSym(sym1, sym2)} x y)
-(LEAL1 [off1] {sym1} x (LEAL1 [off2] {sym2} x y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-      (LEAL2 [off1+off2] {mergeSym(sym1, sym2)} y x)
-(LEAL2 [off1] {sym} x (LEAL1 [off2] {nil} y y)) && is32Bit(int64(off1)+2*int64(off2)) =>
-      (LEAL4 [off1+2*off2] {sym} x y)
-(LEAL4 [off1] {sym} x (LEAL1 [off2] {nil} y y)) && is32Bit(int64(off1)+4*int64(off2)) =>
-      (LEAL8 [off1+4*off2] {sym} x y)
-
-// Absorb InvertFlags into branches.
-(LT (InvertFlags cmp) yes no) => (GT cmp yes no)
-(GT (InvertFlags cmp) yes no) => (LT cmp yes no)
-(LE (InvertFlags cmp) yes no) => (GE cmp yes no)
-(GE (InvertFlags cmp) yes no) => (LE cmp yes no)
-(ULT (InvertFlags cmp) yes no) => (UGT cmp yes no)
-(UGT (InvertFlags cmp) yes no) => (ULT cmp yes no)
-(ULE (InvertFlags cmp) yes no) => (UGE cmp yes no)
-(UGE (InvertFlags cmp) yes no) => (ULE cmp yes no)
-(EQ (InvertFlags cmp) yes no) => (EQ cmp yes no)
-(NE (InvertFlags cmp) yes no) => (NE cmp yes no)
-
-// Constant comparisons.
-(CMPLconst (MOVLconst [x]) [y]) && x==y                       => (FlagEQ)
-(CMPLconst (MOVLconst [x]) [y]) && x<y && uint32(x)<uint32(y) => (FlagLT_ULT)
-(CMPLconst (MOVLconst [x]) [y]) && x<y && uint32(x)>uint32(y) => (FlagLT_UGT)
-(CMPLconst (MOVLconst [x]) [y]) && x>y && uint32(x)<uint32(y) => (FlagGT_ULT)
-(CMPLconst (MOVLconst [x]) [y]) && x>y && uint32(x)>uint32(y) => (FlagGT_UGT)
-
-(CMPWconst (MOVLconst [x]) [y]) && int16(x)==y                       => (FlagEQ)
-(CMPWconst (MOVLconst [x]) [y]) && int16(x)<y && uint16(x)<uint16(y) => (FlagLT_ULT)
-(CMPWconst (MOVLconst [x]) [y]) && int16(x)<y && uint16(x)>uint16(y) => (FlagLT_UGT)
-(CMPWconst (MOVLconst [x]) [y]) && int16(x)>y && uint16(x)<uint16(y) => (FlagGT_ULT)
-(CMPWconst (MOVLconst [x]) [y]) && int16(x)>y && uint16(x)>uint16(y) => (FlagGT_UGT)
-
-(CMPBconst (MOVLconst [x]) [y]) && int8(x)==y                      => (FlagEQ)
-(CMPBconst (MOVLconst [x]) [y]) && int8(x)<y && uint8(x)<uint8(y) => (FlagLT_ULT)
-(CMPBconst (MOVLconst [x]) [y]) && int8(x)<y && uint8(x)>uint8(y) => (FlagLT_UGT)
-(CMPBconst (MOVLconst [x]) [y]) && int8(x)>y && uint8(x)<uint8(y) => (FlagGT_ULT)
-(CMPBconst (MOVLconst [x]) [y]) && int8(x)>y && uint8(x)>uint8(y) => (FlagGT_UGT)
-
-// Other known comparisons.
-(CMPLconst (SHRLconst _ [c]) [n]) && 0 <= n && 0 < c && c <= 32 && (1<<uint64(32-c)) <= uint64(n) => (FlagLT_ULT)
-(CMPLconst (ANDLconst _ [m]) [n]) && 0 <= m && m < n => (FlagLT_ULT)
-(CMPWconst (ANDLconst _ [m]) [n]) && 0 <= int16(m) && int16(m) < n => (FlagLT_ULT)
-(CMPBconst (ANDLconst _ [m]) [n]) && 0 <= int8(m) && int8(m) < n => (FlagLT_ULT)
-// TODO: DIVxU also.
-
-// Absorb flag constants into SBB ops.
-(SBBLcarrymask (FlagEQ)) => (MOVLconst [0])
-(SBBLcarrymask (FlagLT_ULT)) => (MOVLconst [-1])
-(SBBLcarrymask (FlagLT_UGT)) => (MOVLconst [0])
-(SBBLcarrymask (FlagGT_ULT)) => (MOVLconst [-1])
-(SBBLcarrymask (FlagGT_UGT)) => (MOVLconst [0])
-
-// Absorb flag constants into branches.
-(EQ (FlagEQ) yes no) => (First yes no)
-(EQ (FlagLT_ULT) yes no) => (First no yes)
-(EQ (FlagLT_UGT) yes no) => (First no yes)
-(EQ (FlagGT_ULT) yes no) => (First no yes)
-(EQ (FlagGT_UGT) yes no) => (First no yes)
-
-(NE (FlagEQ) yes no) => (First no yes)
-(NE (FlagLT_ULT) yes no) => (First yes no)
-(NE (FlagLT_UGT) yes no) => (First yes no)
-(NE (FlagGT_ULT) yes no) => (First yes no)
-(NE (FlagGT_UGT) yes no) => (First yes no)
-
-(LT (FlagEQ) yes no) => (First no yes)
-(LT (FlagLT_ULT) yes no) => (First yes no)
-(LT (FlagLT_UGT) yes no) => (First yes no)
-(LT (FlagGT_ULT) yes no) => (First no yes)
-(LT (FlagGT_UGT) yes no) => (First no yes)
-
-(LE (FlagEQ) yes no) => (First yes no)
-(LE (FlagLT_ULT) yes no) => (First yes no)
-(LE (FlagLT_UGT) yes no) => (First yes no)
-(LE (FlagGT_ULT) yes no) => (First no yes)
-(LE (FlagGT_UGT) yes no) => (First no yes)
-
-(GT (FlagEQ) yes no) => (First no yes)
-(GT (FlagLT_ULT) yes no) => (First no yes)
-(GT (FlagLT_UGT) yes no) => (First no yes)
-(GT (FlagGT_ULT) yes no) => (First yes no)
-(GT (FlagGT_UGT) yes no) => (First yes no)
-
-(GE (FlagEQ) yes no) => (First yes no)
-(GE (FlagLT_ULT) yes no) => (First no yes)
-(GE (FlagLT_UGT) yes no) => (First no yes)
-(GE (FlagGT_ULT) yes no) => (First yes no)
-(GE (FlagGT_UGT) yes no) => (First yes no)
-
-(ULT (FlagEQ) yes no) => (First no yes)
-(ULT (FlagLT_ULT) yes no) => (First yes no)
-(ULT (FlagLT_UGT) yes no) => (First no yes)
-(ULT (FlagGT_ULT) yes no) => (First yes no)
-(ULT (FlagGT_UGT) yes no) => (First no yes)
-
-(ULE (FlagEQ) yes no) => (First yes no)
-(ULE (FlagLT_ULT) yes no) => (First yes no)
-(ULE (FlagLT_UGT) yes no) => (First no yes)
-(ULE (FlagGT_ULT) yes no) => (First yes no)
-(ULE (FlagGT_UGT) yes no) => (First no yes)
-
-(UGT (FlagEQ) yes no) => (First no yes)
-(UGT (FlagLT_ULT) yes no) => (First no yes)
-(UGT (FlagLT_UGT) yes no) => (First yes no)
-(UGT (FlagGT_ULT) yes no) => (First no yes)
-(UGT (FlagGT_UGT) yes no) => (First yes no)
-
-(UGE (FlagEQ) yes no) => (First yes no)
-(UGE (FlagLT_ULT) yes no) => (First no yes)
-(UGE (FlagLT_UGT) yes no) => (First yes no)
-(UGE (FlagGT_ULT) yes no) => (First no yes)
-(UGE (FlagGT_UGT) yes no) => (First yes no)
-
-// Absorb flag constants into SETxx ops.
-(SETEQ (FlagEQ)) => (MOVLconst [1])
-(SETEQ (FlagLT_ULT)) => (MOVLconst [0])
-(SETEQ (FlagLT_UGT)) => (MOVLconst [0])
-(SETEQ (FlagGT_ULT)) => (MOVLconst [0])
-(SETEQ (FlagGT_UGT)) => (MOVLconst [0])
-
-(SETNE (FlagEQ)) => (MOVLconst [0])
-(SETNE (FlagLT_ULT)) => (MOVLconst [1])
-(SETNE (FlagLT_UGT)) => (MOVLconst [1])
-(SETNE (FlagGT_ULT)) => (MOVLconst [1])
-(SETNE (FlagGT_UGT)) => (MOVLconst [1])
-
-(SETL (FlagEQ)) => (MOVLconst [0])
-(SETL (FlagLT_ULT)) => (MOVLconst [1])
-(SETL (FlagLT_UGT)) => (MOVLconst [1])
-(SETL (FlagGT_ULT)) => (MOVLconst [0])
-(SETL (FlagGT_UGT)) => (MOVLconst [0])
-
-(SETLE (FlagEQ)) => (MOVLconst [1])
-(SETLE (FlagLT_ULT)) => (MOVLconst [1])
-(SETLE (FlagLT_UGT)) => (MOVLconst [1])
-(SETLE (FlagGT_ULT)) => (MOVLconst [0])
-(SETLE (FlagGT_UGT)) => (MOVLconst [0])
-
-(SETG (FlagEQ)) => (MOVLconst [0])
-(SETG (FlagLT_ULT)) => (MOVLconst [0])
-(SETG (FlagLT_UGT)) => (MOVLconst [0])
-(SETG (FlagGT_ULT)) => (MOVLconst [1])
-(SETG (FlagGT_UGT)) => (MOVLconst [1])
-
-(SETGE (FlagEQ)) => (MOVLconst [1])
-(SETGE (FlagLT_ULT)) => (MOVLconst [0])
-(SETGE (FlagLT_UGT)) => (MOVLconst [0])
-(SETGE (FlagGT_ULT)) => (MOVLconst [1])
-(SETGE (FlagGT_UGT)) => (MOVLconst [1])
-
-(SETB (FlagEQ)) => (MOVLconst [0])
-(SETB (FlagLT_ULT)) => (MOVLconst [1])
-(SETB (FlagLT_UGT)) => (MOVLconst [0])
-(SETB (FlagGT_ULT)) => (MOVLconst [1])
-(SETB (FlagGT_UGT)) => (MOVLconst [0])
-
-(SETBE (FlagEQ)) => (MOVLconst [1])
-(SETBE (FlagLT_ULT)) => (MOVLconst [1])
-(SETBE (FlagLT_UGT)) => (MOVLconst [0])
-(SETBE (FlagGT_ULT)) => (MOVLconst [1])
-(SETBE (FlagGT_UGT)) => (MOVLconst [0])
-
-(SETA (FlagEQ)) => (MOVLconst [0])
-(SETA (FlagLT_ULT)) => (MOVLconst [0])
-(SETA (FlagLT_UGT)) => (MOVLconst [1])
-(SETA (FlagGT_ULT)) => (MOVLconst [0])
-(SETA (FlagGT_UGT)) => (MOVLconst [1])
-
-(SETAE (FlagEQ)) => (MOVLconst [1])
-(SETAE (FlagLT_ULT)) => (MOVLconst [0])
-(SETAE (FlagLT_UGT)) => (MOVLconst [1])
-(SETAE (FlagGT_ULT)) => (MOVLconst [0])
-(SETAE (FlagGT_UGT)) => (MOVLconst [1])
-
-// Remove redundant *const ops
-(ADDLconst [c] x) && c==0  => x
-(SUBLconst [c] x) && c==0  => x
-(ANDLconst [c] _) && c==0  => (MOVLconst [0])
-(ANDLconst [c] x) && c==-1 => x
-(ORLconst [c] x)  && c==0  => x
-(ORLconst [c] _)  && c==-1 => (MOVLconst [-1])
-(XORLconst [c] x) && c==0  => x
-// TODO: since we got rid of the W/B versions, we might miss
-// things like (ANDLconst [0x100] x) which were formerly
-// (ANDBconst [0] x).  Probably doesn't happen very often.
-// If we cared, we might do:
-//  (ANDLconst <t> [c] x) && t.Size()==1 && int8(x)==0 => (MOVLconst [0])
-
-// Convert constant subtracts to constant adds
-(SUBLconst [c] x) => (ADDLconst [-c] x)
-
-// generic constant folding
-// TODO: more of this
-(ADDLconst [c] (MOVLconst [d])) => (MOVLconst [c+d])
-(ADDLconst [c] (ADDLconst [d] x)) => (ADDLconst [c+d] x)
-(SARLconst [c] (MOVLconst [d])) => (MOVLconst [d>>uint64(c)])
-(SARWconst [c] (MOVLconst [d])) => (MOVLconst [d>>uint64(c)])
-(SARBconst [c] (MOVLconst [d])) => (MOVLconst [d>>uint64(c)])
-(NEGL (MOVLconst [c])) => (MOVLconst [-c])
-(MULLconst [c] (MOVLconst [d])) => (MOVLconst [c*d])
-(ANDLconst [c] (MOVLconst [d])) => (MOVLconst [c&d])
-(ORLconst [c] (MOVLconst [d])) => (MOVLconst [c|d])
-(XORLconst [c] (MOVLconst [d])) => (MOVLconst [c^d])
-(NOTL (MOVLconst [c])) => (MOVLconst [^c])
-
-// generic simplifications
-// TODO: more of this
-(ADDL x (NEGL y)) => (SUBL x y)
-(SUBL x x) => (MOVLconst [0])
-(ANDL x x) => x
-(ORL x x) => x
-(XORL x x) => (MOVLconst [0])
-
-// checking AND against 0.
-(CMP(L|W|B)const l:(ANDL x y) [0]) && l.Uses==1 => (TEST(L|W|B) x y)
-(CMPLconst l:(ANDLconst [c] x) [0]) && l.Uses==1 => (TESTLconst [c] x)
-(CMPWconst l:(ANDLconst [c] x) [0]) && l.Uses==1 => (TESTWconst [int16(c)] x)
-(CMPBconst l:(ANDLconst [c] x) [0]) && l.Uses==1 => (TESTBconst [int8(c)] x)
-
-// TEST %reg,%reg is shorter than CMP
-(CMP(L|W|B)const x [0]) => (TEST(L|W|B) x x)
-
-// Convert LEAL1 back to ADDL if we can
-(LEAL1 [0] {nil} x y) => (ADDL x y)
-
-// Combining byte loads into larger (unaligned) loads.
-// There are many ways these combinations could occur.  This is
-// designed to match the way encoding/binary.LittleEndian does it.
-(ORL                  x0:(MOVBload [i0] {s} p mem)
-    s0:(SHLLconst [8] x1:(MOVBload [i1] {s} p mem)))
-  && i1 == i0+1
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && s0.Uses == 1
-  && mergePoint(b,x0,x1) != nil
-  && clobber(x0, x1, s0)
-  => @mergePoint(b,x0,x1) (MOVWload [i0] {s} p mem)
-
-(ORL                  x0:(MOVBload [i] {s} p0 mem)
-    s0:(SHLLconst [8] x1:(MOVBload [i] {s} p1 mem)))
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && s0.Uses == 1
-  && sequentialAddresses(p0, p1, 1)
-  && mergePoint(b,x0,x1) != nil
-  && clobber(x0, x1, s0)
-  => @mergePoint(b,x0,x1) (MOVWload [i] {s} p0 mem)
-
-(ORL o0:(ORL
-                       x0:(MOVWload [i0] {s} p mem)
-    s0:(SHLLconst [16] x1:(MOVBload [i2] {s} p mem)))
-    s1:(SHLLconst [24] x2:(MOVBload [i3] {s} p mem)))
-  && i2 == i0+2
-  && i3 == i0+3
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && x2.Uses == 1
-  && s0.Uses == 1
-  && s1.Uses == 1
-  && o0.Uses == 1
-  && mergePoint(b,x0,x1,x2) != nil
-  && clobber(x0, x1, x2, s0, s1, o0)
-  => @mergePoint(b,x0,x1,x2) (MOVLload [i0] {s} p mem)
-
-(ORL o0:(ORL
-                       x0:(MOVWload [i] {s} p0 mem)
-    s0:(SHLLconst [16] x1:(MOVBload [i] {s} p1 mem)))
-    s1:(SHLLconst [24] x2:(MOVBload [i] {s} p2 mem)))
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && x2.Uses == 1
-  && s0.Uses == 1
-  && s1.Uses == 1
-  && o0.Uses == 1
-  && sequentialAddresses(p0, p1, 2)
-  && sequentialAddresses(p1, p2, 1)
-  && mergePoint(b,x0,x1,x2) != nil
-  && clobber(x0, x1, x2, s0, s1, o0)
-  => @mergePoint(b,x0,x1,x2) (MOVLload [i] {s} p0 mem)
-
-// Combine constant stores into larger (unaligned) stores.
-(MOVBstoreconst [c] {s} p x:(MOVBstoreconst [a] {s} p mem))
-  && x.Uses == 1
-  && a.Off() + 1 == c.Off()
-  && clobber(x)
-  => (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p mem)
-(MOVBstoreconst [a] {s} p x:(MOVBstoreconst [c] {s} p mem))
-  && x.Uses == 1
-  && a.Off() + 1 == c.Off()
-  && clobber(x)
-  => (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p mem)
-
-(MOVBstoreconst [c] {s} p1 x:(MOVBstoreconst [a] {s} p0 mem))
-  && x.Uses == 1
-  && a.Off() == c.Off()
-  && sequentialAddresses(p0, p1, 1)
-  && clobber(x)
-  => (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p0 mem)
-(MOVBstoreconst [a] {s} p0 x:(MOVBstoreconst [c] {s} p1 mem))
-  && x.Uses == 1
-  && a.Off() == c.Off()
-  && sequentialAddresses(p0, p1, 1)
-  && clobber(x)
-  => (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p0 mem)
-
-(MOVWstoreconst [c] {s} p x:(MOVWstoreconst [a] {s} p mem))
-  && x.Uses == 1
-  && a.Off() + 2 == c.Off()
-  && clobber(x)
-  => (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p mem)
-(MOVWstoreconst [a] {s} p x:(MOVWstoreconst [c] {s} p mem))
-  && x.Uses == 1
-  && ValAndOff(a).Off() + 2 == ValAndOff(c).Off()
-  && clobber(x)
-  => (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p mem)
-
-(MOVWstoreconst [c] {s} p1 x:(MOVWstoreconst [a] {s} p0 mem))
-  && x.Uses == 1
-  && a.Off() == c.Off()
-  && sequentialAddresses(p0, p1, 2)
-  && clobber(x)
-  => (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p0 mem)
-(MOVWstoreconst [a] {s} p0 x:(MOVWstoreconst [c] {s} p1 mem))
-  && x.Uses == 1
-  && a.Off() == c.Off()
-  && sequentialAddresses(p0, p1, 2)
-  && clobber(x)
-  => (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p0 mem)
-
-// Combine stores into larger (unaligned) stores.
-(MOVBstore [i] {s} p (SHR(W|L)const [8] w) x:(MOVBstore [i-1] {s} p w mem))
-  && x.Uses == 1
-  && clobber(x)
-  => (MOVWstore [i-1] {s} p w mem)
-(MOVBstore [i] {s} p w x:(MOVBstore {s} [i+1] p (SHR(W|L)const [8] w) mem))
-  && x.Uses == 1
-  && clobber(x)
-  => (MOVWstore [i] {s} p w mem)
-(MOVBstore [i] {s} p (SHRLconst [j] w) x:(MOVBstore [i-1] {s} p w0:(SHRLconst [j-8] w) mem))
-  && x.Uses == 1
-  && clobber(x)
-  => (MOVWstore [i-1] {s} p w0 mem)
-
-(MOVBstore [i] {s} p1 (SHR(W|L)const [8] w) x:(MOVBstore [i] {s} p0 w mem))
-  && x.Uses == 1
-  && sequentialAddresses(p0, p1, 1)
-  && clobber(x)
-  => (MOVWstore [i] {s} p0 w mem)
-(MOVBstore [i] {s} p0 w x:(MOVBstore {s} [i] p1 (SHR(W|L)const [8] w) mem))
-  && x.Uses == 1
-  && sequentialAddresses(p0, p1, 1)
-  && clobber(x)
-  => (MOVWstore [i] {s} p0 w mem)
-(MOVBstore [i] {s} p1 (SHRLconst [j] w) x:(MOVBstore [i] {s} p0 w0:(SHRLconst [j-8] w) mem))
-  && x.Uses == 1
-  && sequentialAddresses(p0, p1, 1)
-  && clobber(x)
-  => (MOVWstore [i] {s} p0 w0 mem)
-
-(MOVWstore [i] {s} p (SHRLconst [16] w) x:(MOVWstore [i-2] {s} p w mem))
-  && x.Uses == 1
-  && clobber(x)
-  => (MOVLstore [i-2] {s} p w mem)
-(MOVWstore [i] {s} p (SHRLconst [j] w) x:(MOVWstore [i-2] {s} p w0:(SHRLconst [j-16] w) mem))
-  && x.Uses == 1
-  && clobber(x)
-  => (MOVLstore [i-2] {s} p w0 mem)
-
-(MOVWstore [i] {s} p1 (SHRLconst [16] w) x:(MOVWstore [i] {s} p0 w mem))
-  && x.Uses == 1
-  && sequentialAddresses(p0, p1, 2)
-  && clobber(x)
-  => (MOVLstore [i] {s} p0 w mem)
-(MOVWstore [i] {s} p1 (SHRLconst [j] w) x:(MOVWstore [i] {s} p0 w0:(SHRLconst [j-16] w) mem))
-  && x.Uses == 1
-  && sequentialAddresses(p0, p1, 2)
-  && clobber(x)
-  => (MOVLstore [i] {s} p0 w0 mem)
-
-// For PIC, break floating-point constant loading into two instructions so we have
-// a register to use for holding the address of the constant pool entry.
-(MOVSSconst [c]) && config.ctxt.Flag_shared => (MOVSSconst2 (MOVSSconst1 [c]))
-(MOVSDconst [c]) && config.ctxt.Flag_shared => (MOVSDconst2 (MOVSDconst1 [c]))
-
-(CMP(L|W|B) l:(MOV(L|W|B)load {sym} [off] ptr mem) x) && canMergeLoad(v, l) && clobber(l) => (CMP(L|W|B)load {sym} [off] ptr x mem)
-(CMP(L|W|B) x l:(MOV(L|W|B)load {sym} [off] ptr mem)) && canMergeLoad(v, l) && clobber(l) => (InvertFlags (CMP(L|W|B)load {sym} [off] ptr x mem))
-
-(CMP(L|W|B)const l:(MOV(L|W|B)load {sym} [off] ptr mem) [c])
-	&& l.Uses == 1
-	&& clobber(l) =>
-  @l.Block (CMP(L|W|B)constload {sym} [makeValAndOff(int32(c),off)] ptr mem)
-
-(CMPLload {sym} [off] ptr (MOVLconst [c]) mem) => (CMPLconstload {sym} [makeValAndOff(c,off)] ptr mem)
-(CMPWload {sym} [off] ptr (MOVLconst [c]) mem) => (CMPWconstload {sym} [makeValAndOff(int32(int16(c)),off)] ptr mem)
-(CMPBload {sym} [off] ptr (MOVLconst [c]) mem) => (CMPBconstload {sym} [makeValAndOff(int32(int8(c)),off)] ptr mem)
-
-(MOVBload [off] {sym} (SB) _) && symIsRO(sym) => (MOVLconst [int32(read8(sym, int64(off)))])
-(MOVWload [off] {sym} (SB) _) && symIsRO(sym) => (MOVLconst [int32(read16(sym, int64(off), config.ctxt.Arch.ByteOrder))])
-(MOVLload [off] {sym} (SB) _) && symIsRO(sym) => (MOVLconst [int32(read32(sym, int64(off), config.ctxt.Arch.ByteOrder))])
diff --git a/src/cmd/compile/internal/ssa/gen/386Ops.go b/src/cmd/compile/internal/ssa/gen/386Ops.go
deleted file mode 100644
index 8ec9c68..0000000
--- a/src/cmd/compile/internal/ssa/gen/386Ops.go
+++ /dev/null
@@ -1,588 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build ignore
-// +build ignore
-
-package main
-
-import "strings"
-
-// Notes:
-//  - Integer types live in the low portion of registers. Upper portions are junk.
-//  - Boolean types use the low-order byte of a register. 0=false, 1=true.
-//    Upper bytes are junk.
-//  - Floating-point types live in the low natural slot of an sse2 register.
-//    Unused portions are junk.
-//  - We do not use AH,BH,CH,DH registers.
-//  - When doing sub-register operations, we try to write the whole
-//    destination register to avoid a partial-register write.
-//  - Unused portions of AuxInt (or the Val portion of ValAndOff) are
-//    filled by sign-extending the used portion.  Users of AuxInt which interpret
-//    AuxInt as unsigned (e.g. shifts) must be careful.
-
-// Suffixes encode the bit width of various instructions.
-// L (long word) = 32 bit
-// W (word)      = 16 bit
-// B (byte)      = 8 bit
-
-// copied from ../../x86/reg.go
-var regNames386 = []string{
-	"AX",
-	"CX",
-	"DX",
-	"BX",
-	"SP",
-	"BP",
-	"SI",
-	"DI",
-	"X0",
-	"X1",
-	"X2",
-	"X3",
-	"X4",
-	"X5",
-	"X6",
-	"X7",
-
-	// If you add registers, update asyncPreempt in runtime
-
-	// pseudo-registers
-	"SB",
-}
-
-func init() {
-	// Make map from reg names to reg integers.
-	if len(regNames386) > 64 {
-		panic("too many registers")
-	}
-	num := map[string]int{}
-	for i, name := range regNames386 {
-		num[name] = i
-	}
-	buildReg := func(s string) regMask {
-		m := regMask(0)
-		for _, r := range strings.Split(s, " ") {
-			if n, ok := num[r]; ok {
-				m |= regMask(1) << uint(n)
-				continue
-			}
-			panic("register " + r + " not found")
-		}
-		return m
-	}
-
-	// Common individual register masks
-	var (
-		ax         = buildReg("AX")
-		cx         = buildReg("CX")
-		dx         = buildReg("DX")
-		bx         = buildReg("BX")
-		si         = buildReg("SI")
-		gp         = buildReg("AX CX DX BX BP SI DI")
-		fp         = buildReg("X0 X1 X2 X3 X4 X5 X6 X7")
-		gpsp       = gp | buildReg("SP")
-		gpspsb     = gpsp | buildReg("SB")
-		callerSave = gp | fp
-	)
-	// Common slices of register masks
-	var (
-		gponly = []regMask{gp}
-		fponly = []regMask{fp}
-	)
-
-	// Common regInfo
-	var (
-		gp01      = regInfo{inputs: nil, outputs: gponly}
-		gp11      = regInfo{inputs: []regMask{gp}, outputs: gponly}
-		gp11sp    = regInfo{inputs: []regMask{gpsp}, outputs: gponly}
-		gp11sb    = regInfo{inputs: []regMask{gpspsb}, outputs: gponly}
-		gp21      = regInfo{inputs: []regMask{gp, gp}, outputs: gponly}
-		gp11carry = regInfo{inputs: []regMask{gp}, outputs: []regMask{gp, 0}}
-		gp21carry = regInfo{inputs: []regMask{gp, gp}, outputs: []regMask{gp, 0}}
-		gp1carry1 = regInfo{inputs: []regMask{gp}, outputs: gponly}
-		gp2carry1 = regInfo{inputs: []regMask{gp, gp}, outputs: gponly}
-		gp21sp    = regInfo{inputs: []regMask{gpsp, gp}, outputs: gponly}
-		gp21sb    = regInfo{inputs: []regMask{gpspsb, gpsp}, outputs: gponly}
-		gp21shift = regInfo{inputs: []regMask{gp, cx}, outputs: []regMask{gp}}
-		gp11div   = regInfo{inputs: []regMask{ax, gpsp &^ dx}, outputs: []regMask{ax}, clobbers: dx}
-		gp21hmul  = regInfo{inputs: []regMask{ax, gpsp}, outputs: []regMask{dx}, clobbers: ax}
-		gp11mod   = regInfo{inputs: []regMask{ax, gpsp &^ dx}, outputs: []regMask{dx}, clobbers: ax}
-		gp21mul   = regInfo{inputs: []regMask{ax, gpsp}, outputs: []regMask{dx, ax}}
-
-		gp2flags     = regInfo{inputs: []regMask{gpsp, gpsp}}
-		gp1flags     = regInfo{inputs: []regMask{gpsp}}
-		gp0flagsLoad = regInfo{inputs: []regMask{gpspsb, 0}}
-		gp1flagsLoad = regInfo{inputs: []regMask{gpspsb, gpsp, 0}}
-		flagsgp      = regInfo{inputs: nil, outputs: gponly}
-
-		readflags = regInfo{inputs: nil, outputs: gponly}
-		flagsgpax = regInfo{inputs: nil, clobbers: ax, outputs: []regMask{gp &^ ax}}
-
-		gpload      = regInfo{inputs: []regMask{gpspsb, 0}, outputs: gponly}
-		gp21load    = regInfo{inputs: []regMask{gp, gpspsb, 0}, outputs: gponly}
-		gploadidx   = regInfo{inputs: []regMask{gpspsb, gpsp, 0}, outputs: gponly}
-		gp21loadidx = regInfo{inputs: []regMask{gp, gpspsb, gpsp, 0}, outputs: gponly}
-
-		gpstore         = regInfo{inputs: []regMask{gpspsb, gpsp, 0}}
-		gpstoreconst    = regInfo{inputs: []regMask{gpspsb, 0}}
-		gpstoreidx      = regInfo{inputs: []regMask{gpspsb, gpsp, gpsp, 0}}
-		gpstoreconstidx = regInfo{inputs: []regMask{gpspsb, gpsp, 0}}
-
-		fp01     = regInfo{inputs: nil, outputs: fponly}
-		fp21     = regInfo{inputs: []regMask{fp, fp}, outputs: fponly}
-		fp21load = regInfo{inputs: []regMask{fp, gpspsb, 0}, outputs: fponly}
-		fpgp     = regInfo{inputs: fponly, outputs: gponly}
-		gpfp     = regInfo{inputs: gponly, outputs: fponly}
-		fp11     = regInfo{inputs: fponly, outputs: fponly}
-		fp2flags = regInfo{inputs: []regMask{fp, fp}}
-
-		fpload    = regInfo{inputs: []regMask{gpspsb, 0}, outputs: fponly}
-		fploadidx = regInfo{inputs: []regMask{gpspsb, gpsp, 0}, outputs: fponly}
-
-		fpstore    = regInfo{inputs: []regMask{gpspsb, fp, 0}}
-		fpstoreidx = regInfo{inputs: []regMask{gpspsb, gpsp, fp, 0}}
-	)
-
-	var _386ops = []opData{
-		// fp ops
-		{name: "ADDSS", argLength: 2, reg: fp21, asm: "ADDSS", commutative: true, resultInArg0: true}, // fp32 add
-		{name: "ADDSD", argLength: 2, reg: fp21, asm: "ADDSD", commutative: true, resultInArg0: true}, // fp64 add
-		{name: "SUBSS", argLength: 2, reg: fp21, asm: "SUBSS", resultInArg0: true},                    // fp32 sub
-		{name: "SUBSD", argLength: 2, reg: fp21, asm: "SUBSD", resultInArg0: true},                    // fp64 sub
-		{name: "MULSS", argLength: 2, reg: fp21, asm: "MULSS", commutative: true, resultInArg0: true}, // fp32 mul
-		{name: "MULSD", argLength: 2, reg: fp21, asm: "MULSD", commutative: true, resultInArg0: true}, // fp64 mul
-		{name: "DIVSS", argLength: 2, reg: fp21, asm: "DIVSS", resultInArg0: true},                    // fp32 div
-		{name: "DIVSD", argLength: 2, reg: fp21, asm: "DIVSD", resultInArg0: true},                    // fp64 div
-
-		{name: "MOVSSload", argLength: 2, reg: fpload, asm: "MOVSS", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"}, // fp32 load
-		{name: "MOVSDload", argLength: 2, reg: fpload, asm: "MOVSD", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"}, // fp64 load
-		{name: "MOVSSconst", reg: fp01, asm: "MOVSS", aux: "Float32", rematerializeable: true},                               // fp32 constant
-		{name: "MOVSDconst", reg: fp01, asm: "MOVSD", aux: "Float64", rematerializeable: true},                               // fp64 constant
-		{name: "MOVSSloadidx1", argLength: 3, reg: fploadidx, asm: "MOVSS", aux: "SymOff", symEffect: "Read"},                // fp32 load indexed by i
-		{name: "MOVSSloadidx4", argLength: 3, reg: fploadidx, asm: "MOVSS", aux: "SymOff", symEffect: "Read"},                // fp32 load indexed by 4*i
-		{name: "MOVSDloadidx1", argLength: 3, reg: fploadidx, asm: "MOVSD", aux: "SymOff", symEffect: "Read"},                // fp64 load indexed by i
-		{name: "MOVSDloadidx8", argLength: 3, reg: fploadidx, asm: "MOVSD", aux: "SymOff", symEffect: "Read"},                // fp64 load indexed by 8*i
-
-		{name: "MOVSSstore", argLength: 3, reg: fpstore, asm: "MOVSS", aux: "SymOff", faultOnNilArg0: true, symEffect: "Write"}, // fp32 store
-		{name: "MOVSDstore", argLength: 3, reg: fpstore, asm: "MOVSD", aux: "SymOff", faultOnNilArg0: true, symEffect: "Write"}, // fp64 store
-		{name: "MOVSSstoreidx1", argLength: 4, reg: fpstoreidx, asm: "MOVSS", aux: "SymOff", symEffect: "Write"},                // fp32 indexed by i store
-		{name: "MOVSSstoreidx4", argLength: 4, reg: fpstoreidx, asm: "MOVSS", aux: "SymOff", symEffect: "Write"},                // fp32 indexed by 4i store
-		{name: "MOVSDstoreidx1", argLength: 4, reg: fpstoreidx, asm: "MOVSD", aux: "SymOff", symEffect: "Write"},                // fp64 indexed by i store
-		{name: "MOVSDstoreidx8", argLength: 4, reg: fpstoreidx, asm: "MOVSD", aux: "SymOff", symEffect: "Write"},                // fp64 indexed by 8i store
-
-		{name: "ADDSSload", argLength: 3, reg: fp21load, asm: "ADDSS", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"}, // fp32 arg0 + tmp, tmp loaded from arg1+auxint+aux, arg2 = mem
-		{name: "ADDSDload", argLength: 3, reg: fp21load, asm: "ADDSD", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"}, // fp64 arg0 + tmp, tmp loaded from arg1+auxint+aux, arg2 = mem
-		{name: "SUBSSload", argLength: 3, reg: fp21load, asm: "SUBSS", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"}, // fp32 arg0 - tmp, tmp loaded from arg1+auxint+aux, arg2 = mem
-		{name: "SUBSDload", argLength: 3, reg: fp21load, asm: "SUBSD", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"}, // fp64 arg0 - tmp, tmp loaded from arg1+auxint+aux, arg2 = mem
-		{name: "MULSSload", argLength: 3, reg: fp21load, asm: "MULSS", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"}, // fp32 arg0 * tmp, tmp loaded from arg1+auxint+aux, arg2 = mem
-		{name: "MULSDload", argLength: 3, reg: fp21load, asm: "MULSD", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"}, // fp64 arg0 * tmp, tmp loaded from arg1+auxint+aux, arg2 = mem
-		{name: "DIVSSload", argLength: 3, reg: fp21load, asm: "DIVSS", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"}, // fp32 arg0 / tmp, tmp loaded from arg1+auxint+aux, arg2 = mem
-		{name: "DIVSDload", argLength: 3, reg: fp21load, asm: "DIVSD", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"}, // fp64 arg0 / tmp, tmp loaded from arg1+auxint+aux, arg2 = mem
-
-		// binary ops
-		{name: "ADDL", argLength: 2, reg: gp21sp, asm: "ADDL", commutative: true, clobberFlags: true},                // arg0 + arg1
-		{name: "ADDLconst", argLength: 1, reg: gp11sp, asm: "ADDL", aux: "Int32", typ: "UInt32", clobberFlags: true}, // arg0 + auxint
-
-		{name: "ADDLcarry", argLength: 2, reg: gp21carry, asm: "ADDL", commutative: true, resultInArg0: true},                // arg0 + arg1, generates <carry,result> pair
-		{name: "ADDLconstcarry", argLength: 1, reg: gp11carry, asm: "ADDL", aux: "Int32", resultInArg0: true},                // arg0 + auxint, generates <carry,result> pair
-		{name: "ADCL", argLength: 3, reg: gp2carry1, asm: "ADCL", commutative: true, resultInArg0: true, clobberFlags: true}, // arg0+arg1+carry(arg2), where arg2 is flags
-		{name: "ADCLconst", argLength: 2, reg: gp1carry1, asm: "ADCL", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0+auxint+carry(arg1), where arg1 is flags
-
-		{name: "SUBL", argLength: 2, reg: gp21, asm: "SUBL", resultInArg0: true, clobberFlags: true},                    // arg0 - arg1
-		{name: "SUBLconst", argLength: 1, reg: gp11, asm: "SUBL", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 - auxint
-
-		{name: "SUBLcarry", argLength: 2, reg: gp21carry, asm: "SUBL", resultInArg0: true},                                   // arg0-arg1, generates <borrow,result> pair
-		{name: "SUBLconstcarry", argLength: 1, reg: gp11carry, asm: "SUBL", aux: "Int32", resultInArg0: true},                // arg0-auxint, generates <borrow,result> pair
-		{name: "SBBL", argLength: 3, reg: gp2carry1, asm: "SBBL", resultInArg0: true, clobberFlags: true},                    // arg0-arg1-borrow(arg2), where arg2 is flags
-		{name: "SBBLconst", argLength: 2, reg: gp1carry1, asm: "SBBL", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0-auxint-borrow(arg1), where arg1 is flags
-
-		{name: "MULL", argLength: 2, reg: gp21, asm: "IMULL", commutative: true, resultInArg0: true, clobberFlags: true}, // arg0 * arg1
-		{name: "MULLconst", argLength: 1, reg: gp11, asm: "IMUL3L", aux: "Int32", clobberFlags: true},                    // arg0 * auxint
-
-		{name: "MULLU", argLength: 2, reg: regInfo{inputs: []regMask{ax, gpsp}, outputs: []regMask{ax, 0}, clobbers: dx}, typ: "(UInt32,Flags)", asm: "MULL", commutative: true, clobberFlags: true}, // Let x = arg0*arg1 (full 32x32->64  unsigned multiply). Returns uint32(x), and flags set to overflow if uint32(x) != x.
-
-		{name: "HMULL", argLength: 2, reg: gp21hmul, commutative: true, asm: "IMULL", clobberFlags: true}, // (arg0 * arg1) >> width
-		{name: "HMULLU", argLength: 2, reg: gp21hmul, commutative: true, asm: "MULL", clobberFlags: true}, // (arg0 * arg1) >> width
-
-		{name: "MULLQU", argLength: 2, reg: gp21mul, commutative: true, asm: "MULL", clobberFlags: true}, // arg0 * arg1, high 32 in result[0], low 32 in result[1]
-
-		{name: "AVGLU", argLength: 2, reg: gp21, commutative: true, resultInArg0: true, clobberFlags: true}, // (arg0 + arg1) / 2 as unsigned, all 32 result bits
-
-		// For DIVL, DIVW, MODL and MODW, AuxInt non-zero means that the divisor has been proved to be not -1.
-		{name: "DIVL", argLength: 2, reg: gp11div, asm: "IDIVL", aux: "Bool", clobberFlags: true}, // arg0 / arg1
-		{name: "DIVW", argLength: 2, reg: gp11div, asm: "IDIVW", aux: "Bool", clobberFlags: true}, // arg0 / arg1
-		{name: "DIVLU", argLength: 2, reg: gp11div, asm: "DIVL", clobberFlags: true},              // arg0 / arg1
-		{name: "DIVWU", argLength: 2, reg: gp11div, asm: "DIVW", clobberFlags: true},              // arg0 / arg1
-
-		{name: "MODL", argLength: 2, reg: gp11mod, asm: "IDIVL", aux: "Bool", clobberFlags: true}, // arg0 % arg1
-		{name: "MODW", argLength: 2, reg: gp11mod, asm: "IDIVW", aux: "Bool", clobberFlags: true}, // arg0 % arg1
-		{name: "MODLU", argLength: 2, reg: gp11mod, asm: "DIVL", clobberFlags: true},              // arg0 % arg1
-		{name: "MODWU", argLength: 2, reg: gp11mod, asm: "DIVW", clobberFlags: true},              // arg0 % arg1
-
-		{name: "ANDL", argLength: 2, reg: gp21, asm: "ANDL", commutative: true, resultInArg0: true, clobberFlags: true}, // arg0 & arg1
-		{name: "ANDLconst", argLength: 1, reg: gp11, asm: "ANDL", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 & auxint
-
-		{name: "ORL", argLength: 2, reg: gp21, asm: "ORL", commutative: true, resultInArg0: true, clobberFlags: true}, // arg0 | arg1
-		{name: "ORLconst", argLength: 1, reg: gp11, asm: "ORL", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 | auxint
-
-		{name: "XORL", argLength: 2, reg: gp21, asm: "XORL", commutative: true, resultInArg0: true, clobberFlags: true}, // arg0 ^ arg1
-		{name: "XORLconst", argLength: 1, reg: gp11, asm: "XORL", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 ^ auxint
-
-		{name: "CMPL", argLength: 2, reg: gp2flags, asm: "CMPL", typ: "Flags"},                    // arg0 compare to arg1
-		{name: "CMPW", argLength: 2, reg: gp2flags, asm: "CMPW", typ: "Flags"},                    // arg0 compare to arg1
-		{name: "CMPB", argLength: 2, reg: gp2flags, asm: "CMPB", typ: "Flags"},                    // arg0 compare to arg1
-		{name: "CMPLconst", argLength: 1, reg: gp1flags, asm: "CMPL", typ: "Flags", aux: "Int32"}, // arg0 compare to auxint
-		{name: "CMPWconst", argLength: 1, reg: gp1flags, asm: "CMPW", typ: "Flags", aux: "Int16"}, // arg0 compare to auxint
-		{name: "CMPBconst", argLength: 1, reg: gp1flags, asm: "CMPB", typ: "Flags", aux: "Int8"},  // arg0 compare to auxint
-
-		// compare *(arg0+auxint+aux) to arg1 (in that order). arg2=mem.
-		{name: "CMPLload", argLength: 3, reg: gp1flagsLoad, asm: "CMPL", aux: "SymOff", typ: "Flags", symEffect: "Read", faultOnNilArg0: true},
-		{name: "CMPWload", argLength: 3, reg: gp1flagsLoad, asm: "CMPW", aux: "SymOff", typ: "Flags", symEffect: "Read", faultOnNilArg0: true},
-		{name: "CMPBload", argLength: 3, reg: gp1flagsLoad, asm: "CMPB", aux: "SymOff", typ: "Flags", symEffect: "Read", faultOnNilArg0: true},
-
-		// compare *(arg0+ValAndOff(AuxInt).Off()+aux) to ValAndOff(AuxInt).Val() (in that order). arg1=mem.
-		{name: "CMPLconstload", argLength: 2, reg: gp0flagsLoad, asm: "CMPL", aux: "SymValAndOff", typ: "Flags", symEffect: "Read", faultOnNilArg0: true},
-		{name: "CMPWconstload", argLength: 2, reg: gp0flagsLoad, asm: "CMPW", aux: "SymValAndOff", typ: "Flags", symEffect: "Read", faultOnNilArg0: true},
-		{name: "CMPBconstload", argLength: 2, reg: gp0flagsLoad, asm: "CMPB", aux: "SymValAndOff", typ: "Flags", symEffect: "Read", faultOnNilArg0: true},
-
-		{name: "UCOMISS", argLength: 2, reg: fp2flags, asm: "UCOMISS", typ: "Flags"}, // arg0 compare to arg1, f32
-		{name: "UCOMISD", argLength: 2, reg: fp2flags, asm: "UCOMISD", typ: "Flags"}, // arg0 compare to arg1, f64
-
-		{name: "TESTL", argLength: 2, reg: gp2flags, commutative: true, asm: "TESTL", typ: "Flags"}, // (arg0 & arg1) compare to 0
-		{name: "TESTW", argLength: 2, reg: gp2flags, commutative: true, asm: "TESTW", typ: "Flags"}, // (arg0 & arg1) compare to 0
-		{name: "TESTB", argLength: 2, reg: gp2flags, commutative: true, asm: "TESTB", typ: "Flags"}, // (arg0 & arg1) compare to 0
-		{name: "TESTLconst", argLength: 1, reg: gp1flags, asm: "TESTL", typ: "Flags", aux: "Int32"}, // (arg0 & auxint) compare to 0
-		{name: "TESTWconst", argLength: 1, reg: gp1flags, asm: "TESTW", typ: "Flags", aux: "Int16"}, // (arg0 & auxint) compare to 0
-		{name: "TESTBconst", argLength: 1, reg: gp1flags, asm: "TESTB", typ: "Flags", aux: "Int8"},  // (arg0 & auxint) compare to 0
-
-		{name: "SHLL", argLength: 2, reg: gp21shift, asm: "SHLL", resultInArg0: true, clobberFlags: true},               // arg0 << arg1, shift amount is mod 32
-		{name: "SHLLconst", argLength: 1, reg: gp11, asm: "SHLL", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 << auxint, shift amount 0-31
-		// Note: x86 is weird, the 16 and 8 byte shifts still use all 5 bits of shift amount!
-
-		{name: "SHRL", argLength: 2, reg: gp21shift, asm: "SHRL", resultInArg0: true, clobberFlags: true},               // unsigned arg0 >> arg1, shift amount is mod 32
-		{name: "SHRW", argLength: 2, reg: gp21shift, asm: "SHRW", resultInArg0: true, clobberFlags: true},               // unsigned arg0 >> arg1, shift amount is mod 32
-		{name: "SHRB", argLength: 2, reg: gp21shift, asm: "SHRB", resultInArg0: true, clobberFlags: true},               // unsigned arg0 >> arg1, shift amount is mod 32
-		{name: "SHRLconst", argLength: 1, reg: gp11, asm: "SHRL", aux: "Int32", resultInArg0: true, clobberFlags: true}, // unsigned arg0 >> auxint, shift amount 0-31
-		{name: "SHRWconst", argLength: 1, reg: gp11, asm: "SHRW", aux: "Int16", resultInArg0: true, clobberFlags: true}, // unsigned arg0 >> auxint, shift amount 0-15
-		{name: "SHRBconst", argLength: 1, reg: gp11, asm: "SHRB", aux: "Int8", resultInArg0: true, clobberFlags: true},  // unsigned arg0 >> auxint, shift amount 0-7
-
-		{name: "SARL", argLength: 2, reg: gp21shift, asm: "SARL", resultInArg0: true, clobberFlags: true},               // signed arg0 >> arg1, shift amount is mod 32
-		{name: "SARW", argLength: 2, reg: gp21shift, asm: "SARW", resultInArg0: true, clobberFlags: true},               // signed arg0 >> arg1, shift amount is mod 32
-		{name: "SARB", argLength: 2, reg: gp21shift, asm: "SARB", resultInArg0: true, clobberFlags: true},               // signed arg0 >> arg1, shift amount is mod 32
-		{name: "SARLconst", argLength: 1, reg: gp11, asm: "SARL", aux: "Int32", resultInArg0: true, clobberFlags: true}, // signed arg0 >> auxint, shift amount 0-31
-		{name: "SARWconst", argLength: 1, reg: gp11, asm: "SARW", aux: "Int16", resultInArg0: true, clobberFlags: true}, // signed arg0 >> auxint, shift amount 0-15
-		{name: "SARBconst", argLength: 1, reg: gp11, asm: "SARB", aux: "Int8", resultInArg0: true, clobberFlags: true},  // signed arg0 >> auxint, shift amount 0-7
-
-		{name: "ROLLconst", argLength: 1, reg: gp11, asm: "ROLL", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 rotate left auxint, rotate amount 0-31
-		{name: "ROLWconst", argLength: 1, reg: gp11, asm: "ROLW", aux: "Int16", resultInArg0: true, clobberFlags: true}, // arg0 rotate left auxint, rotate amount 0-15
-		{name: "ROLBconst", argLength: 1, reg: gp11, asm: "ROLB", aux: "Int8", resultInArg0: true, clobberFlags: true},  // arg0 rotate left auxint, rotate amount 0-7
-
-		// binary-op with a memory source operand
-		{name: "ADDLload", argLength: 3, reg: gp21load, asm: "ADDL", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},  // arg0 + tmp, tmp loaded from  arg1+auxint+aux, arg2 = mem
-		{name: "SUBLload", argLength: 3, reg: gp21load, asm: "SUBL", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},  // arg0 - tmp, tmp loaded from  arg1+auxint+aux, arg2 = mem
-		{name: "MULLload", argLength: 3, reg: gp21load, asm: "IMULL", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"}, // arg0 * tmp, tmp loaded from  arg1+auxint+aux, arg2 = mem
-		{name: "ANDLload", argLength: 3, reg: gp21load, asm: "ANDL", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},  // arg0 & tmp, tmp loaded from  arg1+auxint+aux, arg2 = mem
-		{name: "ORLload", argLength: 3, reg: gp21load, asm: "ORL", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},    // arg0 | tmp, tmp loaded from  arg1+auxint+aux, arg2 = mem
-		{name: "XORLload", argLength: 3, reg: gp21load, asm: "XORL", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},  // arg0 ^ tmp, tmp loaded from  arg1+auxint+aux, arg2 = mem
-
-		// binary-op with an indexed memory source operand
-		{name: "ADDLloadidx4", argLength: 4, reg: gp21loadidx, asm: "ADDL", aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},  // arg0 + tmp, tmp loaded from  arg1+arg2*4+auxint+aux, arg3 = mem
-		{name: "SUBLloadidx4", argLength: 4, reg: gp21loadidx, asm: "SUBL", aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},  // arg0 - tmp, tmp loaded from  arg1+arg2*4+auxint+aux, arg3 = mem
-		{name: "MULLloadidx4", argLength: 4, reg: gp21loadidx, asm: "IMULL", aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"}, // arg0 * tmp, tmp loaded from  arg1+arg2*4+auxint+aux, arg3 = mem
-		{name: "ANDLloadidx4", argLength: 4, reg: gp21loadidx, asm: "ANDL", aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},  // arg0 & tmp, tmp loaded from  arg1+arg2*4+auxint+aux, arg3 = mem
-		{name: "ORLloadidx4", argLength: 4, reg: gp21loadidx, asm: "ORL", aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},    // arg0 | tmp, tmp loaded from  arg1+arg2*4+auxint+aux, arg3 = mem
-		{name: "XORLloadidx4", argLength: 4, reg: gp21loadidx, asm: "XORL", aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},  // arg0 ^ tmp, tmp loaded from  arg1+arg2*4+auxint+aux, arg3 = mem
-
-		// unary ops
-		{name: "NEGL", argLength: 1, reg: gp11, asm: "NEGL", resultInArg0: true, clobberFlags: true}, // -arg0
-
-		{name: "NOTL", argLength: 1, reg: gp11, asm: "NOTL", resultInArg0: true}, // ^arg0
-
-		{name: "BSFL", argLength: 1, reg: gp11, asm: "BSFL", clobberFlags: true}, // arg0 # of low-order zeroes ; undef if zero
-		{name: "BSFW", argLength: 1, reg: gp11, asm: "BSFW", clobberFlags: true}, // arg0 # of low-order zeroes ; undef if zero
-
-		{name: "BSRL", argLength: 1, reg: gp11, asm: "BSRL", clobberFlags: true}, // arg0 # of high-order zeroes ; undef if zero
-		{name: "BSRW", argLength: 1, reg: gp11, asm: "BSRW", clobberFlags: true}, // arg0 # of high-order zeroes ; undef if zero
-
-		{name: "BSWAPL", argLength: 1, reg: gp11, asm: "BSWAPL", resultInArg0: true}, // arg0 swap bytes
-
-		{name: "SQRTSD", argLength: 1, reg: fp11, asm: "SQRTSD"}, // sqrt(arg0)
-		{name: "SQRTSS", argLength: 1, reg: fp11, asm: "SQRTSS"}, // sqrt(arg0), float32
-
-		{name: "SBBLcarrymask", argLength: 1, reg: flagsgp, asm: "SBBL"}, // (int32)(-1) if carry is set, 0 if carry is clear.
-		// Note: SBBW and SBBB are subsumed by SBBL
-
-		{name: "SETEQ", argLength: 1, reg: readflags, asm: "SETEQ"}, // extract == condition from arg0
-		{name: "SETNE", argLength: 1, reg: readflags, asm: "SETNE"}, // extract != condition from arg0
-		{name: "SETL", argLength: 1, reg: readflags, asm: "SETLT"},  // extract signed < condition from arg0
-		{name: "SETLE", argLength: 1, reg: readflags, asm: "SETLE"}, // extract signed <= condition from arg0
-		{name: "SETG", argLength: 1, reg: readflags, asm: "SETGT"},  // extract signed > condition from arg0
-		{name: "SETGE", argLength: 1, reg: readflags, asm: "SETGE"}, // extract signed >= condition from arg0
-		{name: "SETB", argLength: 1, reg: readflags, asm: "SETCS"},  // extract unsigned < condition from arg0
-		{name: "SETBE", argLength: 1, reg: readflags, asm: "SETLS"}, // extract unsigned <= condition from arg0
-		{name: "SETA", argLength: 1, reg: readflags, asm: "SETHI"},  // extract unsigned > condition from arg0
-		{name: "SETAE", argLength: 1, reg: readflags, asm: "SETCC"}, // extract unsigned >= condition from arg0
-		{name: "SETO", argLength: 1, reg: readflags, asm: "SETOS"},  // extract if overflow flag is set from arg0
-		// Need different opcodes for floating point conditions because
-		// any comparison involving a NaN is always FALSE and thus
-		// the patterns for inverting conditions cannot be used.
-		{name: "SETEQF", argLength: 1, reg: flagsgpax, asm: "SETEQ", clobberFlags: true}, // extract == condition from arg0
-		{name: "SETNEF", argLength: 1, reg: flagsgpax, asm: "SETNE", clobberFlags: true}, // extract != condition from arg0
-		{name: "SETORD", argLength: 1, reg: flagsgp, asm: "SETPC"},                       // extract "ordered" (No Nan present) condition from arg0
-		{name: "SETNAN", argLength: 1, reg: flagsgp, asm: "SETPS"},                       // extract "unordered" (Nan present) condition from arg0
-
-		{name: "SETGF", argLength: 1, reg: flagsgp, asm: "SETHI"},  // extract floating > condition from arg0
-		{name: "SETGEF", argLength: 1, reg: flagsgp, asm: "SETCC"}, // extract floating >= condition from arg0
-
-		{name: "MOVBLSX", argLength: 1, reg: gp11, asm: "MOVBLSX"}, // sign extend arg0 from int8 to int32
-		{name: "MOVBLZX", argLength: 1, reg: gp11, asm: "MOVBLZX"}, // zero extend arg0 from int8 to int32
-		{name: "MOVWLSX", argLength: 1, reg: gp11, asm: "MOVWLSX"}, // sign extend arg0 from int16 to int32
-		{name: "MOVWLZX", argLength: 1, reg: gp11, asm: "MOVWLZX"}, // zero extend arg0 from int16 to int32
-
-		{name: "MOVLconst", reg: gp01, asm: "MOVL", typ: "UInt32", aux: "Int32", rematerializeable: true}, // 32 low bits of auxint
-
-		{name: "CVTTSD2SL", argLength: 1, reg: fpgp, asm: "CVTTSD2SL"}, // convert float64 to int32
-		{name: "CVTTSS2SL", argLength: 1, reg: fpgp, asm: "CVTTSS2SL"}, // convert float32 to int32
-		{name: "CVTSL2SS", argLength: 1, reg: gpfp, asm: "CVTSL2SS"},   // convert int32 to float32
-		{name: "CVTSL2SD", argLength: 1, reg: gpfp, asm: "CVTSL2SD"},   // convert int32 to float64
-		{name: "CVTSD2SS", argLength: 1, reg: fp11, asm: "CVTSD2SS"},   // convert float64 to float32
-		{name: "CVTSS2SD", argLength: 1, reg: fp11, asm: "CVTSS2SD"},   // convert float32 to float64
-
-		{name: "PXOR", argLength: 2, reg: fp21, asm: "PXOR", commutative: true, resultInArg0: true}, // exclusive or, applied to X regs for float negation.
-
-		{name: "LEAL", argLength: 1, reg: gp11sb, aux: "SymOff", rematerializeable: true, symEffect: "Addr"}, // arg0 + auxint + offset encoded in aux
-		{name: "LEAL1", argLength: 2, reg: gp21sb, commutative: true, aux: "SymOff", symEffect: "Addr"},      // arg0 + arg1 + auxint + aux
-		{name: "LEAL2", argLength: 2, reg: gp21sb, aux: "SymOff", symEffect: "Addr"},                         // arg0 + 2*arg1 + auxint + aux
-		{name: "LEAL4", argLength: 2, reg: gp21sb, aux: "SymOff", symEffect: "Addr"},                         // arg0 + 4*arg1 + auxint + aux
-		{name: "LEAL8", argLength: 2, reg: gp21sb, aux: "SymOff", symEffect: "Addr"},                         // arg0 + 8*arg1 + auxint + aux
-		// Note: LEAL{1,2,4,8} must not have OpSB as either argument.
-
-		// auxint+aux == add auxint and the offset of the symbol in aux (if any) to the effective address
-		{name: "MOVBload", argLength: 2, reg: gpload, asm: "MOVBLZX", aux: "SymOff", typ: "UInt8", faultOnNilArg0: true, symEffect: "Read"},  // load byte from arg0+auxint+aux. arg1=mem.  Zero extend.
-		{name: "MOVBLSXload", argLength: 2, reg: gpload, asm: "MOVBLSX", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},             // ditto, sign extend to int32
-		{name: "MOVWload", argLength: 2, reg: gpload, asm: "MOVWLZX", aux: "SymOff", typ: "UInt16", faultOnNilArg0: true, symEffect: "Read"}, // load 2 bytes from arg0+auxint+aux. arg1=mem.  Zero extend.
-		{name: "MOVWLSXload", argLength: 2, reg: gpload, asm: "MOVWLSX", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},             // ditto, sign extend to int32
-		{name: "MOVLload", argLength: 2, reg: gpload, asm: "MOVL", aux: "SymOff", typ: "UInt32", faultOnNilArg0: true, symEffect: "Read"},    // load 4 bytes from arg0+auxint+aux. arg1=mem.  Zero extend.
-		{name: "MOVBstore", argLength: 3, reg: gpstore, asm: "MOVB", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},    // store byte in arg1 to arg0+auxint+aux. arg2=mem
-		{name: "MOVWstore", argLength: 3, reg: gpstore, asm: "MOVW", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},    // store 2 bytes in arg1 to arg0+auxint+aux. arg2=mem
-		{name: "MOVLstore", argLength: 3, reg: gpstore, asm: "MOVL", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},    // store 4 bytes in arg1 to arg0+auxint+aux. arg2=mem
-
-		// direct binary-op on memory (read-modify-write)
-		{name: "ADDLmodify", argLength: 3, reg: gpstore, asm: "ADDL", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+auxint+aux) += arg1, arg2=mem
-		{name: "SUBLmodify", argLength: 3, reg: gpstore, asm: "SUBL", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+auxint+aux) -= arg1, arg2=mem
-		{name: "ANDLmodify", argLength: 3, reg: gpstore, asm: "ANDL", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+auxint+aux) &= arg1, arg2=mem
-		{name: "ORLmodify", argLength: 3, reg: gpstore, asm: "ORL", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, clobberFlags: true, symEffect: "Read,Write"},   // *(arg0+auxint+aux) |= arg1, arg2=mem
-		{name: "XORLmodify", argLength: 3, reg: gpstore, asm: "XORL", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+auxint+aux) ^= arg1, arg2=mem
-
-		// direct binary-op on indexed memory (read-modify-write)
-		{name: "ADDLmodifyidx4", argLength: 4, reg: gpstoreidx, asm: "ADDL", aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+arg1*4+auxint+aux) += arg2, arg3=mem
-		{name: "SUBLmodifyidx4", argLength: 4, reg: gpstoreidx, asm: "SUBL", aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+arg1*4+auxint+aux) -= arg2, arg3=mem
-		{name: "ANDLmodifyidx4", argLength: 4, reg: gpstoreidx, asm: "ANDL", aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+arg1*4+auxint+aux) &= arg2, arg3=mem
-		{name: "ORLmodifyidx4", argLength: 4, reg: gpstoreidx, asm: "ORL", aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},   // *(arg0+arg1*4+auxint+aux) |= arg2, arg3=mem
-		{name: "XORLmodifyidx4", argLength: 4, reg: gpstoreidx, asm: "XORL", aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+arg1*4+auxint+aux) ^= arg2, arg3=mem
-
-		// direct binary-op on memory with a constant (read-modify-write)
-		{name: "ADDLconstmodify", argLength: 2, reg: gpstoreconst, asm: "ADDL", aux: "SymValAndOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"}, // add ValAndOff(AuxInt).Val() to arg0+ValAndOff(AuxInt).Off()+aux, arg1=mem
-		{name: "ANDLconstmodify", argLength: 2, reg: gpstoreconst, asm: "ANDL", aux: "SymValAndOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"}, // and ValAndOff(AuxInt).Val() to arg0+ValAndOff(AuxInt).Off()+aux, arg1=mem
-		{name: "ORLconstmodify", argLength: 2, reg: gpstoreconst, asm: "ORL", aux: "SymValAndOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"},   // or  ValAndOff(AuxInt).Val() to arg0+ValAndOff(AuxInt).Off()+aux, arg1=mem
-		{name: "XORLconstmodify", argLength: 2, reg: gpstoreconst, asm: "XORL", aux: "SymValAndOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"}, // xor ValAndOff(AuxInt).Val() to arg0+ValAndOff(AuxInt).Off()+aux, arg1=mem
-
-		// direct binary-op on indexed memory with a constant (read-modify-write)
-		{name: "ADDLconstmodifyidx4", argLength: 3, reg: gpstoreconstidx, asm: "ADDL", aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // add ValAndOff(AuxInt).Val() to arg0+arg1*4+ValAndOff(AuxInt).Off()+aux, arg2=mem
-		{name: "ANDLconstmodifyidx4", argLength: 3, reg: gpstoreconstidx, asm: "ANDL", aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // and ValAndOff(AuxInt).Val() to arg0+arg1*4+ValAndOff(AuxInt).Off()+aux, arg2=mem
-		{name: "ORLconstmodifyidx4", argLength: 3, reg: gpstoreconstidx, asm: "ORL", aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},   // or  ValAndOff(AuxInt).Val() to arg0+arg1*4+ValAndOff(AuxInt).Off()+aux, arg2=mem
-		{name: "XORLconstmodifyidx4", argLength: 3, reg: gpstoreconstidx, asm: "XORL", aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // xor ValAndOff(AuxInt).Val() to arg0+arg1*4+ValAndOff(AuxInt).Off()+aux, arg2=mem
-
-		// indexed loads/stores
-		{name: "MOVBloadidx1", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVBLZX", aux: "SymOff", symEffect: "Read"}, // load a byte from arg0+arg1+auxint+aux. arg2=mem
-		{name: "MOVWloadidx1", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVWLZX", aux: "SymOff", symEffect: "Read"}, // load 2 bytes from arg0+arg1+auxint+aux. arg2=mem
-		{name: "MOVWloadidx2", argLength: 3, reg: gploadidx, asm: "MOVWLZX", aux: "SymOff", symEffect: "Read"},                    // load 2 bytes from arg0+2*arg1+auxint+aux. arg2=mem
-		{name: "MOVLloadidx1", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVL", aux: "SymOff", symEffect: "Read"},    // load 4 bytes from arg0+arg1+auxint+aux. arg2=mem
-		{name: "MOVLloadidx4", argLength: 3, reg: gploadidx, asm: "MOVL", aux: "SymOff", symEffect: "Read"},                       // load 4 bytes from arg0+4*arg1+auxint+aux. arg2=mem
-		// TODO: sign-extending indexed loads
-		{name: "MOVBstoreidx1", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVB", aux: "SymOff", symEffect: "Write"}, // store byte in arg2 to arg0+arg1+auxint+aux. arg3=mem
-		{name: "MOVWstoreidx1", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVW", aux: "SymOff", symEffect: "Write"}, // store 2 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem
-		{name: "MOVWstoreidx2", argLength: 4, reg: gpstoreidx, asm: "MOVW", aux: "SymOff", symEffect: "Write"},                    // store 2 bytes in arg2 to arg0+2*arg1+auxint+aux. arg3=mem
-		{name: "MOVLstoreidx1", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVL", aux: "SymOff", symEffect: "Write"}, // store 4 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem
-		{name: "MOVLstoreidx4", argLength: 4, reg: gpstoreidx, asm: "MOVL", aux: "SymOff", symEffect: "Write"},                    // store 4 bytes in arg2 to arg0+4*arg1+auxint+aux. arg3=mem
-		// TODO: add size-mismatched indexed loads, like MOVBstoreidx4.
-
-		// For storeconst ops, the AuxInt field encodes both
-		// the value to store and an address offset of the store.
-		// Cast AuxInt to a ValAndOff to extract Val and Off fields.
-		{name: "MOVBstoreconst", argLength: 2, reg: gpstoreconst, asm: "MOVB", aux: "SymValAndOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store low byte of ValAndOff(AuxInt).Val() to arg0+ValAndOff(AuxInt).Off()+aux.  arg1=mem
-		{name: "MOVWstoreconst", argLength: 2, reg: gpstoreconst, asm: "MOVW", aux: "SymValAndOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store low 2 bytes of ...
-		{name: "MOVLstoreconst", argLength: 2, reg: gpstoreconst, asm: "MOVL", aux: "SymValAndOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store low 4 bytes of ...
-
-		{name: "MOVBstoreconstidx1", argLength: 3, reg: gpstoreconstidx, asm: "MOVB", aux: "SymValAndOff", typ: "Mem", symEffect: "Write"}, // store low byte of ValAndOff(AuxInt).Val() to arg0+1*arg1+ValAndOff(AuxInt).Off()+aux.  arg2=mem
-		{name: "MOVWstoreconstidx1", argLength: 3, reg: gpstoreconstidx, asm: "MOVW", aux: "SymValAndOff", typ: "Mem", symEffect: "Write"}, // store low 2 bytes of ... arg1 ...
-		{name: "MOVWstoreconstidx2", argLength: 3, reg: gpstoreconstidx, asm: "MOVW", aux: "SymValAndOff", typ: "Mem", symEffect: "Write"}, // store low 2 bytes of ... 2*arg1 ...
-		{name: "MOVLstoreconstidx1", argLength: 3, reg: gpstoreconstidx, asm: "MOVL", aux: "SymValAndOff", typ: "Mem", symEffect: "Write"}, // store low 4 bytes of ... arg1 ...
-		{name: "MOVLstoreconstidx4", argLength: 3, reg: gpstoreconstidx, asm: "MOVL", aux: "SymValAndOff", typ: "Mem", symEffect: "Write"}, // store low 4 bytes of ... 4*arg1 ...
-
-		// arg0 = pointer to start of memory to zero
-		// arg1 = value to store (will always be zero)
-		// arg2 = mem
-		// auxint = offset into duffzero code to start executing
-		// returns mem
-		{
-			name:      "DUFFZERO",
-			aux:       "Int64",
-			argLength: 3,
-			reg: regInfo{
-				inputs:   []regMask{buildReg("DI"), buildReg("AX")},
-				clobbers: buildReg("DI CX"),
-				// Note: CX is only clobbered when dynamic linking.
-			},
-			faultOnNilArg0: true,
-		},
-
-		// arg0 = address of memory to zero
-		// arg1 = # of 4-byte words to zero
-		// arg2 = value to store (will always be zero)
-		// arg3 = mem
-		// returns mem
-		{
-			name:      "REPSTOSL",
-			argLength: 4,
-			reg: regInfo{
-				inputs:   []regMask{buildReg("DI"), buildReg("CX"), buildReg("AX")},
-				clobbers: buildReg("DI CX"),
-			},
-			faultOnNilArg0: true,
-		},
-
-		{name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                                              // call static function aux.(*obj.LSym).  arg0=mem, auxint=argsize, returns mem
-		{name: "CALLtail", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true, tailCall: true},                                // tail call static function aux.(*obj.LSym).  arg0=mem, auxint=argsize, returns mem
-		{name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{gpsp, buildReg("DX"), 0}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call function via closure.  arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem
-		{name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                        // call fn by pointer.  arg0=codeptr, arg1=mem, auxint=argsize, returns mem
-
-		// arg0 = destination pointer
-		// arg1 = source pointer
-		// arg2 = mem
-		// auxint = offset from duffcopy symbol to call
-		// returns memory
-		{
-			name:      "DUFFCOPY",
-			aux:       "Int64",
-			argLength: 3,
-			reg: regInfo{
-				inputs:   []regMask{buildReg("DI"), buildReg("SI")},
-				clobbers: buildReg("DI SI CX"), // uses CX as a temporary
-			},
-			clobberFlags:   true,
-			faultOnNilArg0: true,
-			faultOnNilArg1: true,
-		},
-
-		// arg0 = destination pointer
-		// arg1 = source pointer
-		// arg2 = # of 8-byte words to copy
-		// arg3 = mem
-		// returns memory
-		{
-			name:      "REPMOVSL",
-			argLength: 4,
-			reg: regInfo{
-				inputs:   []regMask{buildReg("DI"), buildReg("SI"), buildReg("CX")},
-				clobbers: buildReg("DI SI CX"),
-			},
-			faultOnNilArg0: true,
-			faultOnNilArg1: true,
-		},
-
-		// (InvertFlags (CMPL a b)) == (CMPL b a)
-		// So if we want (SETL (CMPL a b)) but we can't do that because a is a constant,
-		// then we do (SETL (InvertFlags (CMPL b a))) instead.
-		// Rewrites will convert this to (SETG (CMPL b a)).
-		// InvertFlags is a pseudo-op which can't appear in assembly output.
-		{name: "InvertFlags", argLength: 1}, // reverse direction of arg0
-
-		// Pseudo-ops
-		{name: "LoweredGetG", argLength: 1, reg: gp01}, // arg0=mem
-		// Scheduler ensures LoweredGetClosurePtr occurs only in entry block,
-		// and sorts it to the very beginning of the block to prevent other
-		// use of DX (the closure pointer)
-		{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("DX")}}, zeroWidth: true},
-		// LoweredGetCallerPC evaluates to the PC to which its "caller" will return.
-		// I.e., if f calls g "calls" getcallerpc,
-		// the result should be the PC within f that g will return to.
-		// See runtime/stubs.go for a more detailed discussion.
-		{name: "LoweredGetCallerPC", reg: gp01, rematerializeable: true},
-		// LoweredGetCallerSP returns the SP of the caller of the current function.
-		{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
-		//arg0=ptr,arg1=mem, returns void.  Faults if ptr is nil.
-		{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpsp}}, clobberFlags: true, nilCheck: true, faultOnNilArg0: true},
-
-		// LoweredWB invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
-		// It saves all GP registers if necessary, but may clobber others.
-		{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("DI"), ax}, clobbers: callerSave &^ gp}, clobberFlags: true, aux: "Sym", symEffect: "None"},
-
-		// There are three of these functions so that they can have three different register inputs.
-		// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the
-		// default registers to match so we don't need to copy registers around unnecessarily.
-		{name: "LoweredPanicBoundsA", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{dx, bx}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
-		{name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{cx, dx}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
-		{name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{ax, cx}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
-		// Extend ops are the same as Bounds ops except the indexes are 64-bit.
-		{name: "LoweredPanicExtendA", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{si, dx, bx}}, typ: "Mem", call: true}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
-		{name: "LoweredPanicExtendB", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{si, cx, dx}}, typ: "Mem", call: true}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
-		{name: "LoweredPanicExtendC", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{si, ax, cx}}, typ: "Mem", call: true}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
-
-		// Constant flag values. For any comparison, there are 5 possible
-		// outcomes: the three from the signed total order (<,==,>) and the
-		// three from the unsigned total order. The == cases overlap.
-		// Note: there's a sixth "unordered" outcome for floating-point
-		// comparisons, but we don't use such a beast yet.
-		// These ops are for temporary use by rewrite rules. They
-		// cannot appear in the generated assembly.
-		{name: "FlagEQ"},     // equal
-		{name: "FlagLT_ULT"}, // signed < and unsigned <
-		{name: "FlagLT_UGT"}, // signed < and unsigned >
-		{name: "FlagGT_UGT"}, // signed > and unsigned <
-		{name: "FlagGT_ULT"}, // signed > and unsigned >
-
-		// Special ops for PIC floating-point constants.
-		// MOVSXconst1 loads the address of the constant-pool entry into a register.
-		// MOVSXconst2 loads the constant from that address.
-		// MOVSXconst1 returns a pointer, but we type it as uint32 because it can never point to the Go heap.
-		{name: "MOVSSconst1", reg: gp01, typ: "UInt32", aux: "Float32"},
-		{name: "MOVSDconst1", reg: gp01, typ: "UInt32", aux: "Float64"},
-		{name: "MOVSSconst2", argLength: 1, reg: gpfp, asm: "MOVSS"},
-		{name: "MOVSDconst2", argLength: 1, reg: gpfp, asm: "MOVSD"},
-	}
-
-	var _386blocks = []blockData{
-		{name: "EQ", controls: 1},
-		{name: "NE", controls: 1},
-		{name: "LT", controls: 1},
-		{name: "LE", controls: 1},
-		{name: "GT", controls: 1},
-		{name: "GE", controls: 1},
-		{name: "OS", controls: 1},
-		{name: "OC", controls: 1},
-		{name: "ULT", controls: 1},
-		{name: "ULE", controls: 1},
-		{name: "UGT", controls: 1},
-		{name: "UGE", controls: 1},
-		{name: "EQF", controls: 1},
-		{name: "NEF", controls: 1},
-		{name: "ORD", controls: 1}, // FP, ordered comparison (parity zero)
-		{name: "NAN", controls: 1}, // FP, unordered comparison (parity one)
-	}
-
-	archs = append(archs, arch{
-		name:            "386",
-		pkg:             "cmd/internal/obj/x86",
-		genfile:         "../../x86/ssa.go",
-		ops:             _386ops,
-		blocks:          _386blocks,
-		regnames:        regNames386,
-		gpregmask:       gp,
-		fpregmask:       fp,
-		framepointerreg: int8(num["BP"]),
-		linkreg:         -1, // not used
-	})
-}
diff --git a/src/cmd/compile/internal/ssa/gen/AMD64.rules b/src/cmd/compile/internal/ssa/gen/AMD64.rules
deleted file mode 100644
index c0a376e..0000000
--- a/src/cmd/compile/internal/ssa/gen/AMD64.rules
+++ /dev/null
@@ -1,2311 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Lowering arithmetic
-(Add(64|32|16|8) ...) => (ADD(Q|L|L|L) ...)
-(AddPtr ...) => (ADDQ ...)
-(Add(32|64)F ...) => (ADDS(S|D) ...)
-
-(Sub(64|32|16|8) ...) => (SUB(Q|L|L|L) ...)
-(SubPtr ...) => (SUBQ ...)
-(Sub(32|64)F ...) => (SUBS(S|D) ...)
-
-(Mul(64|32|16|8) ...) => (MUL(Q|L|L|L) ...)
-(Mul(32|64)F ...) => (MULS(S|D) ...)
-
-(Select0 (Mul64uover x y)) => (Select0 <typ.UInt64> (MULQU x y))
-(Select0 (Mul32uover x y)) => (Select0 <typ.UInt32> (MULLU x y))
-(Select1 (Mul(64|32)uover x y)) => (SETO (Select1 <types.TypeFlags> (MUL(Q|L)U x y)))
-
-(Hmul(64|32) ...) => (HMUL(Q|L) ...)
-(Hmul(64|32)u ...) => (HMUL(Q|L)U ...)
-
-(Div(64|32|16) [a] x y) => (Select0 (DIV(Q|L|W) [a] x y))
-(Div8  x y) => (Select0 (DIVW  (SignExt8to16 x) (SignExt8to16 y)))
-(Div(64|32|16)u x y) => (Select0 (DIV(Q|L|W)U x y))
-(Div8u x y) => (Select0 (DIVWU (ZeroExt8to16 x) (ZeroExt8to16 y)))
-(Div(32|64)F ...) => (DIVS(S|D) ...)
-
-(Select0 (Add64carry x y c)) =>
-	(Select0 <typ.UInt64> (ADCQ x y (Select1 <types.TypeFlags> (NEGLflags c))))
-(Select1 (Add64carry x y c)) =>
-	(NEGQ <typ.UInt64> (SBBQcarrymask <typ.UInt64> (Select1 <types.TypeFlags> (ADCQ x y (Select1 <types.TypeFlags> (NEGLflags c))))))
-(Select0 (Sub64borrow x y c)) =>
-	(Select0 <typ.UInt64> (SBBQ x y (Select1 <types.TypeFlags> (NEGLflags c))))
-(Select1 (Sub64borrow x y c)) =>
-	(NEGQ <typ.UInt64> (SBBQcarrymask <typ.UInt64> (Select1 <types.TypeFlags> (SBBQ x y (Select1 <types.TypeFlags> (NEGLflags c))))))
-
-// Optimize ADCQ and friends
-(ADCQ x (MOVQconst [c]) carry) && is32Bit(c) => (ADCQconst x [int32(c)] carry)
-(ADCQ x y (FlagEQ)) => (ADDQcarry x y)
-(ADCQconst x [c] (FlagEQ)) => (ADDQconstcarry x [c])
-(ADDQcarry x (MOVQconst [c])) && is32Bit(c) => (ADDQconstcarry x [int32(c)])
-(SBBQ x (MOVQconst [c]) borrow) && is32Bit(c) => (SBBQconst x [int32(c)] borrow)
-(SBBQ x y (FlagEQ)) => (SUBQborrow x y)
-(SBBQconst x [c] (FlagEQ)) => (SUBQconstborrow x [c])
-(SUBQborrow x (MOVQconst [c])) && is32Bit(c) => (SUBQconstborrow x [int32(c)])
-(Select1 (NEGLflags (MOVQconst [0]))) => (FlagEQ)
-(Select1 (NEGLflags (NEGQ (SBBQcarrymask x)))) => x
-
-
-(Mul64uhilo ...) => (MULQU2 ...)
-(Div128u ...) => (DIVQU2 ...)
-
-(Avg64u ...) => (AVGQU ...)
-
-(Mod(64|32|16) [a] x y) => (Select1 (DIV(Q|L|W) [a] x y))
-(Mod8  x y) => (Select1 (DIVW  (SignExt8to16 x) (SignExt8to16 y)))
-(Mod(64|32|16)u x y) => (Select1 (DIV(Q|L|W)U x y))
-(Mod8u x y) => (Select1 (DIVWU (ZeroExt8to16 x) (ZeroExt8to16 y)))
-
-(And(64|32|16|8) ...) => (AND(Q|L|L|L) ...)
-(Or(64|32|16|8) ...) => (OR(Q|L|L|L) ...)
-(Xor(64|32|16|8) ...) => (XOR(Q|L|L|L) ...)
-(Com(64|32|16|8) ...) => (NOT(Q|L|L|L) ...)
-
-(Neg(64|32|16|8) ...) => (NEG(Q|L|L|L) ...)
-(Neg32F x) => (PXOR x (MOVSSconst <typ.Float32> [float32(math.Copysign(0, -1))]))
-(Neg64F x) => (PXOR x (MOVSDconst <typ.Float64> [math.Copysign(0, -1)]))
-
-// Lowering boolean ops
-(AndB ...) => (ANDL ...)
-(OrB ...) => (ORL ...)
-(Not x) => (XORLconst [1] x)
-
-// Lowering pointer arithmetic
-(OffPtr [off] ptr) && is32Bit(off) => (ADDQconst [int32(off)] ptr)
-(OffPtr [off] ptr) => (ADDQ (MOVQconst [off]) ptr)
-
-// Lowering other arithmetic
-(Ctz64 x)     && buildcfg.GOAMD64 >= 3 => (TZCNTQ x)
-(Ctz32 x)     && buildcfg.GOAMD64 >= 3 => (TZCNTL x)
-(Ctz64 <t> x) && buildcfg.GOAMD64 <  3 => (CMOVQEQ (Select0 <t> (BSFQ x)) (MOVQconst <t> [64]) (Select1 <types.TypeFlags> (BSFQ x)))
-(Ctz32 x)     && buildcfg.GOAMD64 <  3 => (Select0 (BSFQ (BTSQconst <typ.UInt64> [32] x)))
-(Ctz16 x) => (BSFL (BTSLconst <typ.UInt32> [16] x))
-(Ctz8  x) => (BSFL (BTSLconst <typ.UInt32> [ 8] x))
-
-(Ctz64NonZero x) && buildcfg.GOAMD64 >= 3 => (TZCNTQ x)
-(Ctz32NonZero x) && buildcfg.GOAMD64 >= 3 => (TZCNTL x)
-(Ctz16NonZero x) && buildcfg.GOAMD64 >= 3 => (TZCNTL x)
-(Ctz8NonZero  x) && buildcfg.GOAMD64 >= 3 => (TZCNTL x)
-(Ctz64NonZero x) && buildcfg.GOAMD64 <  3 => (Select0 (BSFQ x))
-(Ctz32NonZero x) && buildcfg.GOAMD64 <  3 => (BSFL x)
-(Ctz16NonZero x) && buildcfg.GOAMD64 <  3 => (BSFL x)
-(Ctz8NonZero  x) && buildcfg.GOAMD64 <  3 => (BSFL x)
-
-// BitLen64 of a 64 bit value x requires checking whether x == 0, since BSRQ is undefined when x == 0.
-// However, for zero-extended values, we can cheat a bit, and calculate
-// BSR(x<<1 + 1), which is guaranteed to be non-zero, and which conveniently
-// places the index of the highest set bit where we want it.
-// For GOAMD64>=3, BitLen can be calculated by OperandSize - LZCNT(x).
-(BitLen64 <t> x) && buildcfg.GOAMD64 < 3 => (ADDQconst [1] (CMOVQEQ <t> (Select0 <t> (BSRQ x)) (MOVQconst <t> [-1]) (Select1 <types.TypeFlags> (BSRQ x))))
-(BitLen32 x) && buildcfg.GOAMD64 <  3 => (Select0 (BSRQ (LEAQ1 <typ.UInt64> [1] (MOVLQZX <typ.UInt64> x) (MOVLQZX <typ.UInt64> x))))
-(BitLen16 x) && buildcfg.GOAMD64 <  3 => (BSRL (LEAL1 <typ.UInt32> [1] (MOVWQZX <typ.UInt32> x) (MOVWQZX <typ.UInt32> x)))
-(BitLen8  x) && buildcfg.GOAMD64 <  3 => (BSRL (LEAL1 <typ.UInt32> [1] (MOVBQZX <typ.UInt32> x) (MOVBQZX <typ.UInt32> x)))
-(BitLen64 <t> x)        && buildcfg.GOAMD64 >= 3 => (NEGQ (ADDQconst <t> [-64] (LZCNTQ x)))
-// Use 64-bit version to allow const-fold remove unnecessary arithmetic.
-(BitLen32 <t> x) && buildcfg.GOAMD64 >= 3 => (NEGQ (ADDQconst <t> [-32] (LZCNTL x)))
-(BitLen16 <t> x) && buildcfg.GOAMD64 >= 3 => (NEGQ (ADDQconst <t> [-32] (LZCNTL (MOVWQZX <x.Type> x))))
-(BitLen8 <t> x) && buildcfg.GOAMD64 >= 3 => (NEGQ (ADDQconst <t> [-32] (LZCNTL (MOVBQZX <x.Type> x))))
-
-(Bswap(64|32) ...) => (BSWAP(Q|L) ...)
-
-(PopCount(64|32) ...) => (POPCNT(Q|L) ...)
-(PopCount16 x) => (POPCNTL (MOVWQZX <typ.UInt32> x))
-(PopCount8 x) => (POPCNTL (MOVBQZX <typ.UInt32> x))
-
-(Sqrt ...) => (SQRTSD ...)
-(Sqrt32 ...) => (SQRTSS ...)
-
-(RoundToEven x) => (ROUNDSD [0] x)
-(Floor x)       => (ROUNDSD [1] x)
-(Ceil x)        => (ROUNDSD [2] x)
-(Trunc x)       => (ROUNDSD [3] x)
-
-(FMA x y z) => (VFMADD231SD z x y)
-
-// Lowering extension
-// Note: we always extend to 64 bits even though some ops don't need that many result bits.
-(SignExt8to16  ...) => (MOVBQSX ...)
-(SignExt8to32  ...) => (MOVBQSX ...)
-(SignExt8to64  ...) => (MOVBQSX ...)
-(SignExt16to32 ...) => (MOVWQSX ...)
-(SignExt16to64 ...) => (MOVWQSX ...)
-(SignExt32to64 ...) => (MOVLQSX ...)
-
-(ZeroExt8to16  ...) => (MOVBQZX ...)
-(ZeroExt8to32  ...) => (MOVBQZX ...)
-(ZeroExt8to64  ...) => (MOVBQZX ...)
-(ZeroExt16to32 ...) => (MOVWQZX ...)
-(ZeroExt16to64 ...) => (MOVWQZX ...)
-(ZeroExt32to64 ...) => (MOVLQZX ...)
-
-(Slicemask <t> x) => (SARQconst (NEGQ <t> x) [63])
-
-(SpectreIndex <t> x y) => (CMOVQCC x (MOVQconst [0]) (CMPQ x y))
-(SpectreSliceIndex <t> x y) => (CMOVQHI x (MOVQconst [0]) (CMPQ x y))
-
-// Lowering truncation
-// Because we ignore high parts of registers, truncates are just copies.
-(Trunc16to8  ...) => (Copy ...)
-(Trunc32to8  ...) => (Copy ...)
-(Trunc32to16 ...) => (Copy ...)
-(Trunc64to8  ...) => (Copy ...)
-(Trunc64to16 ...) => (Copy ...)
-(Trunc64to32 ...) => (Copy ...)
-
-// Lowering float <-> int
-(Cvt32to32F ...) => (CVTSL2SS ...)
-(Cvt32to64F ...) => (CVTSL2SD ...)
-(Cvt64to32F ...) => (CVTSQ2SS ...)
-(Cvt64to64F ...) => (CVTSQ2SD ...)
-
-(Cvt32Fto32 ...) => (CVTTSS2SL ...)
-(Cvt32Fto64 ...) => (CVTTSS2SQ ...)
-(Cvt64Fto32 ...) => (CVTTSD2SL ...)
-(Cvt64Fto64 ...) => (CVTTSD2SQ ...)
-
-(Cvt32Fto64F ...) => (CVTSS2SD ...)
-(Cvt64Fto32F ...) => (CVTSD2SS ...)
-
-(Round(32|64)F ...) => (Copy ...)
-
-(CvtBoolToUint8 ...) => (Copy ...)
-
-// Lowering shifts
-// Unsigned shifts need to return 0 if shift amount is >= width of shifted value.
-//   result = (arg << shift) & (shift >= argbits ? 0 : 0xffffffffffffffff)
-(Lsh64x(64|32|16|8) <t> x y) && !shiftIsBounded(v) => (ANDQ (SHLQ <t> x y) (SBBQcarrymask <t> (CMP(Q|L|W|B)const y [64])))
-(Lsh32x(64|32|16|8) <t> x y) && !shiftIsBounded(v) => (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMP(Q|L|W|B)const y [32])))
-(Lsh16x(64|32|16|8) <t> x y) && !shiftIsBounded(v) => (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMP(Q|L|W|B)const y [32])))
-(Lsh8x(64|32|16|8)  <t> x y) && !shiftIsBounded(v) => (ANDL (SHLL <t> x y) (SBBLcarrymask <t> (CMP(Q|L|W|B)const y [32])))
-
-(Lsh64x(64|32|16|8) x y) && shiftIsBounded(v) => (SHLQ x y)
-(Lsh32x(64|32|16|8) x y) && shiftIsBounded(v) => (SHLL x y)
-(Lsh16x(64|32|16|8) x y) && shiftIsBounded(v) => (SHLL x y)
-(Lsh8x(64|32|16|8)  x y) && shiftIsBounded(v) => (SHLL x y)
-
-(Rsh64Ux(64|32|16|8) <t> x y) && !shiftIsBounded(v) => (ANDQ (SHRQ <t> x y) (SBBQcarrymask <t> (CMP(Q|L|W|B)const y [64])))
-(Rsh32Ux(64|32|16|8) <t> x y) && !shiftIsBounded(v) => (ANDL (SHRL <t> x y) (SBBLcarrymask <t> (CMP(Q|L|W|B)const y [32])))
-(Rsh16Ux(64|32|16|8) <t> x y) && !shiftIsBounded(v) => (ANDL (SHRW <t> x y) (SBBLcarrymask <t> (CMP(Q|L|W|B)const y [16])))
-(Rsh8Ux(64|32|16|8)  <t> x y) && !shiftIsBounded(v) => (ANDL (SHRB <t> x y) (SBBLcarrymask <t> (CMP(Q|L|W|B)const y [8])))
-
-(Rsh64Ux(64|32|16|8) x y) && shiftIsBounded(v) => (SHRQ x y)
-(Rsh32Ux(64|32|16|8) x y) && shiftIsBounded(v) => (SHRL x y)
-(Rsh16Ux(64|32|16|8) x y) && shiftIsBounded(v) => (SHRW x y)
-(Rsh8Ux(64|32|16|8)  x y) && shiftIsBounded(v) => (SHRB x y)
-
-// Signed right shift needs to return 0/-1 if shift amount is >= width of shifted value.
-// We implement this by setting the shift value to -1 (all ones) if the shift value is >= width.
-(Rsh64x(64|32|16|8) <t> x y) && !shiftIsBounded(v) => (SARQ <t> x (OR(Q|L|L|L) <y.Type> y (NOT(Q|L|L|L) <y.Type> (SBB(Q|L|L|L)carrymask <y.Type> (CMP(Q|L|W|B)const y [64])))))
-(Rsh32x(64|32|16|8) <t> x y) && !shiftIsBounded(v) => (SARL <t> x (OR(Q|L|L|L) <y.Type> y (NOT(Q|L|L|L) <y.Type> (SBB(Q|L|L|L)carrymask <y.Type> (CMP(Q|L|W|B)const y [32])))))
-(Rsh16x(64|32|16|8) <t> x y) && !shiftIsBounded(v) => (SARW <t> x (OR(Q|L|L|L) <y.Type> y (NOT(Q|L|L|L) <y.Type> (SBB(Q|L|L|L)carrymask <y.Type> (CMP(Q|L|W|B)const y [16])))))
-(Rsh8x(64|32|16|8)  <t> x y) && !shiftIsBounded(v) => (SARB <t> x (OR(Q|L|L|L) <y.Type> y (NOT(Q|L|L|L) <y.Type> (SBB(Q|L|L|L)carrymask <y.Type> (CMP(Q|L|W|B)const y [8])))))
-
-(Rsh64x(64|32|16|8) x y) && shiftIsBounded(v) => (SARQ x y)
-(Rsh32x(64|32|16|8) x y) && shiftIsBounded(v) => (SARL x y)
-(Rsh16x(64|32|16|8) x y) && shiftIsBounded(v) => (SARW x y)
-(Rsh8x(64|32|16|8) x y)  && shiftIsBounded(v) => (SARB x y)
-
-// Prefer SARX/SHLX/SHRX instruction because it has less register restriction on the shift input.
-(SAR(Q|L) x y) && buildcfg.GOAMD64 >= 3 => (SARX(Q|L) x y)
-(SHL(Q|L) x y) && buildcfg.GOAMD64 >= 3 => (SHLX(Q|L) x y)
-(SHR(Q|L) x y) && buildcfg.GOAMD64 >= 3 => (SHRX(Q|L) x y)
-
-// Lowering integer comparisons
-(Less(64|32|16|8)      x y) => (SETL  (CMP(Q|L|W|B)     x y))
-(Less(64|32|16|8)U     x y) => (SETB  (CMP(Q|L|W|B)     x y))
-(Leq(64|32|16|8)       x y) => (SETLE (CMP(Q|L|W|B)     x y))
-(Leq(64|32|16|8)U      x y) => (SETBE (CMP(Q|L|W|B)     x y))
-(Eq(Ptr|64|32|16|8|B)  x y) => (SETEQ (CMP(Q|Q|L|W|B|B) x y))
-(Neq(Ptr|64|32|16|8|B) x y) => (SETNE (CMP(Q|Q|L|W|B|B) x y))
-
-// Lowering floating point comparisons
-// Note Go assembler gets UCOMISx operand order wrong, but it is right here
-// and the operands are reversed when generating assembly language.
-(Eq(32|64)F   x y) => (SETEQF (UCOMIS(S|D) x y))
-(Neq(32|64)F  x y) => (SETNEF (UCOMIS(S|D) x y))
-// Use SETGF/SETGEF with reversed operands to dodge NaN case.
-(Less(32|64)F x y) => (SETGF  (UCOMIS(S|D) y x))
-(Leq(32|64)F  x y) => (SETGEF (UCOMIS(S|D) y x))
-
-// Lowering loads
-(Load <t> ptr mem) && (is64BitInt(t) || isPtr(t)) => (MOVQload ptr mem)
-(Load <t> ptr mem) && is32BitInt(t) => (MOVLload ptr mem)
-(Load <t> ptr mem) && is16BitInt(t) => (MOVWload ptr mem)
-(Load <t> ptr mem) && (t.IsBoolean() || is8BitInt(t)) => (MOVBload ptr mem)
-(Load <t> ptr mem) && is32BitFloat(t) => (MOVSSload ptr mem)
-(Load <t> ptr mem) && is64BitFloat(t) => (MOVSDload ptr mem)
-
-// Lowering stores
-// These more-specific FP versions of Store pattern should come first.
-(Store {t} ptr val mem) && t.Size() == 8 && is64BitFloat(val.Type) => (MOVSDstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 4 && is32BitFloat(val.Type) => (MOVSSstore ptr val mem)
-
-(Store {t} ptr val mem) && t.Size() == 8 => (MOVQstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 4 => (MOVLstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 2 => (MOVWstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 1 => (MOVBstore ptr val mem)
-
-// Lowering moves
-(Move [0] _ _ mem) => mem
-(Move [1] dst src mem) => (MOVBstore dst (MOVBload src mem) mem)
-(Move [2] dst src mem) => (MOVWstore dst (MOVWload src mem) mem)
-(Move [4] dst src mem) => (MOVLstore dst (MOVLload src mem) mem)
-(Move [8] dst src mem) => (MOVQstore dst (MOVQload src mem) mem)
-(Move [16] dst src mem) && config.useSSE => (MOVOstore dst (MOVOload src mem) mem)
-(Move [16] dst src mem) && !config.useSSE =>
-	(MOVQstore [8] dst (MOVQload [8] src mem)
-		(MOVQstore dst (MOVQload src mem) mem))
-
-(Move [32] dst src mem) =>
-	(Move [16]
-		(OffPtr <dst.Type> dst [16])
-		(OffPtr <src.Type> src [16])
-		(Move [16] dst src mem))
-
-(Move [48] dst src mem) && config.useSSE =>
-	(Move [32]
-		(OffPtr <dst.Type> dst [16])
-		(OffPtr <src.Type> src [16])
-		(Move [16] dst src mem))
-
-(Move [64] dst src mem) && config.useSSE =>
-	(Move [32]
-		(OffPtr <dst.Type> dst [32])
-		(OffPtr <src.Type> src [32])
-		(Move [32] dst src mem))
-
-(Move [3] dst src mem) =>
-	(MOVBstore [2] dst (MOVBload [2] src mem)
-		(MOVWstore dst (MOVWload src mem) mem))
-(Move [5] dst src mem) =>
-	(MOVBstore [4] dst (MOVBload [4] src mem)
-		(MOVLstore dst (MOVLload src mem) mem))
-(Move [6] dst src mem) =>
-	(MOVWstore [4] dst (MOVWload [4] src mem)
-		(MOVLstore dst (MOVLload src mem) mem))
-(Move [7] dst src mem) =>
-	(MOVLstore [3] dst (MOVLload [3] src mem)
-		(MOVLstore dst (MOVLload src mem) mem))
-(Move [9] dst src mem) =>
-	(MOVBstore [8] dst (MOVBload [8] src mem)
-		(MOVQstore dst (MOVQload src mem) mem))
-(Move [10] dst src mem) =>
-	(MOVWstore [8] dst (MOVWload [8] src mem)
-		(MOVQstore dst (MOVQload src mem) mem))
-(Move [12] dst src mem) =>
-	(MOVLstore [8] dst (MOVLload [8] src mem)
-		(MOVQstore dst (MOVQload src mem) mem))
-(Move [s] dst src mem) && s == 11 || s >= 13 && s <= 15 =>
-	(MOVQstore [int32(s-8)] dst (MOVQload [int32(s-8)] src mem)
-		(MOVQstore dst (MOVQload src mem) mem))
-
-// Adjust moves to be a multiple of 16 bytes.
-(Move [s] dst src mem)
-	&& s > 16 && s%16 != 0 && s%16 <= 8 =>
-	(Move [s-s%16]
-		(OffPtr <dst.Type> dst [s%16])
-		(OffPtr <src.Type> src [s%16])
-		(MOVQstore dst (MOVQload src mem) mem))
-(Move [s] dst src mem)
-	&& s > 16 && s%16 != 0 && s%16 > 8 && config.useSSE =>
-	(Move [s-s%16]
-		(OffPtr <dst.Type> dst [s%16])
-		(OffPtr <src.Type> src [s%16])
-		(MOVOstore dst (MOVOload src mem) mem))
-(Move [s] dst src mem)
-	&& s > 16 && s%16 != 0 && s%16 > 8 && !config.useSSE =>
-	(Move [s-s%16]
-		(OffPtr <dst.Type> dst [s%16])
-		(OffPtr <src.Type> src [s%16])
-		(MOVQstore [8] dst (MOVQload [8] src mem)
-			(MOVQstore dst (MOVQload src mem) mem)))
-
-// Medium copying uses a duff device.
-(Move [s] dst src mem)
-	&& s > 64 && s <= 16*64 && s%16 == 0
-	&& !config.noDuffDevice && logLargeCopy(v, s) =>
-	(DUFFCOPY [s] dst src mem)
-
-// Large copying uses REP MOVSQ.
-(Move [s] dst src mem) && (s > 16*64 || config.noDuffDevice) && s%8 == 0 && logLargeCopy(v, s) =>
-	(REPMOVSQ dst src (MOVQconst [s/8]) mem)
-
-// Lowering Zero instructions
-(Zero [0] _ mem) => mem
-(Zero [1] destptr mem) => (MOVBstoreconst [makeValAndOff(0,0)] destptr mem)
-(Zero [2] destptr mem) => (MOVWstoreconst [makeValAndOff(0,0)] destptr mem)
-(Zero [4] destptr mem) => (MOVLstoreconst [makeValAndOff(0,0)] destptr mem)
-(Zero [8] destptr mem) => (MOVQstoreconst [makeValAndOff(0,0)] destptr mem)
-
-(Zero [3] destptr mem) =>
-	(MOVBstoreconst [makeValAndOff(0,2)] destptr
-		(MOVWstoreconst [makeValAndOff(0,0)] destptr mem))
-(Zero [5] destptr mem) =>
-	(MOVBstoreconst [makeValAndOff(0,4)] destptr
-		(MOVLstoreconst [makeValAndOff(0,0)] destptr mem))
-(Zero [6] destptr mem) =>
-	(MOVWstoreconst [makeValAndOff(0,4)] destptr
-		(MOVLstoreconst [makeValAndOff(0,0)] destptr mem))
-(Zero [7] destptr mem) =>
-	(MOVLstoreconst [makeValAndOff(0,3)] destptr
-		(MOVLstoreconst [makeValAndOff(0,0)] destptr mem))
-
-// Strip off any fractional word zeroing.
-(Zero [s] destptr mem) && s%8 != 0 && s > 8 && !config.useSSE =>
-	(Zero [s-s%8] (OffPtr <destptr.Type> destptr [s%8])
-		(MOVQstoreconst [makeValAndOff(0,0)] destptr mem))
-
-// Zero small numbers of words directly.
-(Zero [16] destptr mem) && !config.useSSE =>
-	(MOVQstoreconst [makeValAndOff(0,8)] destptr
-		(MOVQstoreconst [makeValAndOff(0,0)] destptr mem))
-(Zero [24] destptr mem) && !config.useSSE =>
-	(MOVQstoreconst [makeValAndOff(0,16)] destptr
-		(MOVQstoreconst [makeValAndOff(0,8)] destptr
-			(MOVQstoreconst [makeValAndOff(0,0)] destptr mem)))
-(Zero [32] destptr mem) && !config.useSSE =>
-	(MOVQstoreconst [makeValAndOff(0,24)] destptr
-		(MOVQstoreconst [makeValAndOff(0,16)] destptr
-			(MOVQstoreconst [makeValAndOff(0,8)] destptr
-				(MOVQstoreconst [makeValAndOff(0,0)] destptr mem))))
-
-(Zero [s] destptr mem) && s > 8 && s < 16 && config.useSSE =>
-	(MOVQstoreconst [makeValAndOff(0,int32(s-8))] destptr
-		(MOVQstoreconst [makeValAndOff(0,0)] destptr mem))
-
-// Adjust zeros to be a multiple of 16 bytes.
-(Zero [s] destptr mem) && s%16 != 0 && s > 16 && s%16 > 8 && config.useSSE =>
-	(Zero [s-s%16] (OffPtr <destptr.Type> destptr [s%16])
-		(MOVOstoreconst [makeValAndOff(0,0)] destptr mem))
-
-(Zero [s] destptr mem) && s%16 != 0 && s > 16 && s%16 <= 8 && config.useSSE =>
-	(Zero [s-s%16] (OffPtr <destptr.Type> destptr [s%16])
-		(MOVOstoreconst [makeValAndOff(0,0)] destptr mem))
-
-(Zero [16] destptr mem) && config.useSSE =>
-	(MOVOstoreconst [makeValAndOff(0,0)] destptr mem)
-(Zero [32] destptr mem) && config.useSSE =>
-	(MOVOstoreconst [makeValAndOff(0,16)] destptr
-		(MOVOstoreconst [makeValAndOff(0,0)] destptr mem))
-(Zero [48] destptr mem) && config.useSSE =>
-	(MOVOstoreconst [makeValAndOff(0,32)] destptr
-		(MOVOstoreconst [makeValAndOff(0,16)] destptr
-			(MOVOstoreconst [makeValAndOff(0,0)] destptr mem)))
-(Zero [64] destptr mem) && config.useSSE =>
-	(MOVOstoreconst [makeValAndOff(0,48)] destptr
-		(MOVOstoreconst [makeValAndOff(0,32)] destptr
-			(MOVOstoreconst [makeValAndOff(0,16)] destptr
-				(MOVOstoreconst [makeValAndOff(0,0)] destptr mem))))
-
-// Medium zeroing uses a duff device.
-(Zero [s] destptr mem)
-	&& s > 64 && s <= 1024 && s%16 == 0 && !config.noDuffDevice =>
-	(DUFFZERO [s] destptr mem)
-
-// Large zeroing uses REP STOSQ.
-(Zero [s] destptr mem)
-	&& (s > 1024 || (config.noDuffDevice && s > 64 || !config.useSSE && s > 32))
-	&& s%8 == 0 =>
-	(REPSTOSQ destptr (MOVQconst [s/8]) (MOVQconst [0]) mem)
-
-// Lowering constants
-(Const8   [c]) => (MOVLconst [int32(c)])
-(Const16  [c]) => (MOVLconst [int32(c)])
-(Const32  ...) => (MOVLconst ...)
-(Const64  ...) => (MOVQconst ...)
-(Const32F ...) => (MOVSSconst ...)
-(Const64F ...) => (MOVSDconst ...)
-(ConstNil    ) => (MOVQconst [0])
-(ConstBool [c]) => (MOVLconst [b2i32(c)])
-
-// Lowering calls
-(StaticCall ...) => (CALLstatic ...)
-(ClosureCall ...) => (CALLclosure ...)
-(InterCall ...) => (CALLinter ...)
-(TailCall ...) => (CALLtail ...)
-
-// Lowering conditional moves
-// If the condition is a SETxx, we can just run a CMOV from the comparison that was
-// setting the flags.
-// Legend: HI=unsigned ABOVE, CS=unsigned BELOW, CC=unsigned ABOVE EQUAL, LS=unsigned BELOW EQUAL
-(CondSelect <t> x y (SET(EQ|NE|L|G|LE|GE|A|B|AE|BE|EQF|NEF|GF|GEF) cond)) && (is64BitInt(t) || isPtr(t))
-    => (CMOVQ(EQ|NE|LT|GT|LE|GE|HI|CS|CC|LS|EQF|NEF|GTF|GEF) y x cond)
-(CondSelect <t> x y (SET(EQ|NE|L|G|LE|GE|A|B|AE|BE|EQF|NEF|GF|GEF) cond)) && is32BitInt(t)
-    => (CMOVL(EQ|NE|LT|GT|LE|GE|HI|CS|CC|LS|EQF|NEF|GTF|GEF) y x cond)
-(CondSelect <t> x y (SET(EQ|NE|L|G|LE|GE|A|B|AE|BE|EQF|NEF|GF|GEF) cond)) && is16BitInt(t)
-    => (CMOVW(EQ|NE|LT|GT|LE|GE|HI|CS|CC|LS|EQF|NEF|GTF|GEF) y x cond)
-
-// If the condition does not set the flags, we need to generate a comparison.
-(CondSelect <t> x y check) && !check.Type.IsFlags() && check.Type.Size() == 1
-    => (CondSelect <t> x y (MOVBQZX <typ.UInt64> check))
-(CondSelect <t> x y check) && !check.Type.IsFlags() && check.Type.Size() == 2
-    => (CondSelect <t> x y (MOVWQZX <typ.UInt64> check))
-(CondSelect <t> x y check) && !check.Type.IsFlags() && check.Type.Size() == 4
-    => (CondSelect <t> x y (MOVLQZX <typ.UInt64> check))
-
-(CondSelect <t> x y check) && !check.Type.IsFlags() && check.Type.Size() == 8 && (is64BitInt(t) || isPtr(t))
-    => (CMOVQNE y x (CMPQconst [0] check))
-(CondSelect <t> x y check) && !check.Type.IsFlags() && check.Type.Size() == 8 && is32BitInt(t)
-    => (CMOVLNE y x (CMPQconst [0] check))
-(CondSelect <t> x y check) && !check.Type.IsFlags() && check.Type.Size() == 8 && is16BitInt(t)
-    => (CMOVWNE y x (CMPQconst [0] check))
-
-// Absorb InvertFlags
-(CMOVQ(EQ|NE|LT|GT|LE|GE|HI|CS|CC|LS) x y (InvertFlags cond))
-    => (CMOVQ(EQ|NE|GT|LT|GE|LE|CS|HI|LS|CC) x y cond)
-(CMOVL(EQ|NE|LT|GT|LE|GE|HI|CS|CC|LS) x y (InvertFlags cond))
-    => (CMOVL(EQ|NE|GT|LT|GE|LE|CS|HI|LS|CC) x y cond)
-(CMOVW(EQ|NE|LT|GT|LE|GE|HI|CS|CC|LS) x y (InvertFlags cond))
-    => (CMOVW(EQ|NE|GT|LT|GE|LE|CS|HI|LS|CC) x y cond)
-
-// Absorb constants generated during lower
-(CMOV(QEQ|QLE|QGE|QCC|QLS|LEQ|LLE|LGE|LCC|LLS|WEQ|WLE|WGE|WCC|WLS) _ x (FlagEQ)) => x
-(CMOV(QNE|QLT|QGT|QCS|QHI|LNE|LLT|LGT|LCS|LHI|WNE|WLT|WGT|WCS|WHI) y _ (FlagEQ)) => y
-(CMOV(QNE|QGT|QGE|QHI|QCC|LNE|LGT|LGE|LHI|LCC|WNE|WGT|WGE|WHI|WCC) _ x (FlagGT_UGT)) => x
-(CMOV(QEQ|QLE|QLT|QLS|QCS|LEQ|LLE|LLT|LLS|LCS|WEQ|WLE|WLT|WLS|WCS) y _ (FlagGT_UGT)) => y
-(CMOV(QNE|QGT|QGE|QLS|QCS|LNE|LGT|LGE|LLS|LCS|WNE|WGT|WGE|WLS|WCS) _ x (FlagGT_ULT)) => x
-(CMOV(QEQ|QLE|QLT|QHI|QCC|LEQ|LLE|LLT|LHI|LCC|WEQ|WLE|WLT|WHI|WCC) y _ (FlagGT_ULT)) => y
-(CMOV(QNE|QLT|QLE|QCS|QLS|LNE|LLT|LLE|LCS|LLS|WNE|WLT|WLE|WCS|WLS) _ x (FlagLT_ULT)) => x
-(CMOV(QEQ|QGT|QGE|QHI|QCC|LEQ|LGT|LGE|LHI|LCC|WEQ|WGT|WGE|WHI|WCC) y _ (FlagLT_ULT)) => y
-(CMOV(QNE|QLT|QLE|QHI|QCC|LNE|LLT|LLE|LHI|LCC|WNE|WLT|WLE|WHI|WCC) _ x (FlagLT_UGT)) => x
-(CMOV(QEQ|QGT|QGE|QCS|QLS|LEQ|LGT|LGE|LCS|LLS|WEQ|WGT|WGE|WCS|WLS) y _ (FlagLT_UGT)) => y
-
-// Miscellaneous
-(IsNonNil p) => (SETNE (TESTQ p p))
-(IsInBounds idx len) => (SETB (CMPQ idx len))
-(IsSliceInBounds idx len) => (SETBE (CMPQ idx len))
-(NilCheck ...) => (LoweredNilCheck ...)
-(GetG mem) && v.Block.Func.OwnAux.Fn.ABI() != obj.ABIInternal => (LoweredGetG mem) // only lower in old ABI. in new ABI we have a G register.
-(GetClosurePtr ...) => (LoweredGetClosurePtr ...)
-(GetCallerPC ...) => (LoweredGetCallerPC ...)
-(GetCallerSP ...) => (LoweredGetCallerSP ...)
-
-(HasCPUFeature {s}) => (SETNE (CMPLconst [0] (LoweredHasCPUFeature {s})))
-(Addr {sym} base) => (LEAQ {sym} base)
-(LocalAddr {sym} base _) => (LEAQ {sym} base)
-
-(MOVBstore [off] {sym} ptr y:(SETL x) mem) && y.Uses == 1 => (SETLstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr y:(SETLE x) mem) && y.Uses == 1 => (SETLEstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr y:(SETG x) mem) && y.Uses == 1 => (SETGstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr y:(SETGE x) mem) && y.Uses == 1 => (SETGEstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr y:(SETEQ x) mem) && y.Uses == 1 => (SETEQstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr y:(SETNE x) mem) && y.Uses == 1 => (SETNEstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr y:(SETB x) mem) && y.Uses == 1 => (SETBstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr y:(SETBE x) mem) && y.Uses == 1 => (SETBEstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr y:(SETA x) mem) && y.Uses == 1 => (SETAstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr y:(SETAE x) mem) && y.Uses == 1 => (SETAEstore [off] {sym} ptr x mem)
-
-// block rewrites
-(If (SETL  cmp) yes no) => (LT  cmp yes no)
-(If (SETLE cmp) yes no) => (LE  cmp yes no)
-(If (SETG  cmp) yes no) => (GT  cmp yes no)
-(If (SETGE cmp) yes no) => (GE  cmp yes no)
-(If (SETEQ cmp) yes no) => (EQ  cmp yes no)
-(If (SETNE cmp) yes no) => (NE  cmp yes no)
-(If (SETB  cmp) yes no) => (ULT cmp yes no)
-(If (SETBE cmp) yes no) => (ULE cmp yes no)
-(If (SETA  cmp) yes no) => (UGT cmp yes no)
-(If (SETAE cmp) yes no) => (UGE cmp yes no)
-(If (SETO cmp) yes no) => (OS cmp yes no)
-
-// Special case for floating point - LF/LEF not generated
-(If (SETGF  cmp) yes no) => (UGT  cmp yes no)
-(If (SETGEF cmp) yes no) => (UGE  cmp yes no)
-(If (SETEQF cmp) yes no) => (EQF  cmp yes no)
-(If (SETNEF cmp) yes no) => (NEF  cmp yes no)
-
-(If cond yes no) => (NE (TESTB cond cond) yes no)
-
-(JumpTable idx) => (JUMPTABLE {makeJumpTableSym(b)} idx (LEAQ <typ.Uintptr> {makeJumpTableSym(b)} (SB)))
-
-// Atomic loads.  Other than preserving their ordering with respect to other loads, nothing special here.
-(AtomicLoad8 ptr mem) => (MOVBatomicload ptr mem)
-(AtomicLoad32 ptr mem) => (MOVLatomicload ptr mem)
-(AtomicLoad64 ptr mem) => (MOVQatomicload ptr mem)
-(AtomicLoadPtr ptr mem) => (MOVQatomicload ptr mem)
-
-// Atomic stores.  We use XCHG to prevent the hardware reordering a subsequent load.
-// TODO: most runtime uses of atomic stores don't need that property.  Use normal stores for those?
-(AtomicStore8 ptr val mem) => (Select1 (XCHGB <types.NewTuple(typ.UInt8,types.TypeMem)> val ptr mem))
-(AtomicStore32 ptr val mem) => (Select1 (XCHGL <types.NewTuple(typ.UInt32,types.TypeMem)> val ptr mem))
-(AtomicStore64 ptr val mem) => (Select1 (XCHGQ <types.NewTuple(typ.UInt64,types.TypeMem)> val ptr mem))
-(AtomicStorePtrNoWB ptr val mem) => (Select1 (XCHGQ <types.NewTuple(typ.BytePtr,types.TypeMem)> val ptr mem))
-
-// Atomic exchanges.
-(AtomicExchange32 ptr val mem) => (XCHGL val ptr mem)
-(AtomicExchange64 ptr val mem) => (XCHGQ val ptr mem)
-
-// Atomic adds.
-(AtomicAdd32 ptr val mem) => (AddTupleFirst32 val (XADDLlock val ptr mem))
-(AtomicAdd64 ptr val mem) => (AddTupleFirst64 val (XADDQlock val ptr mem))
-(Select0 <t> (AddTupleFirst32 val tuple)) => (ADDL val (Select0 <t> tuple))
-(Select1     (AddTupleFirst32   _ tuple)) => (Select1 tuple)
-(Select0 <t> (AddTupleFirst64 val tuple)) => (ADDQ val (Select0 <t> tuple))
-(Select1     (AddTupleFirst64   _ tuple)) => (Select1 tuple)
-
-// Atomic compare and swap.
-(AtomicCompareAndSwap32 ptr old new_ mem) => (CMPXCHGLlock ptr old new_ mem)
-(AtomicCompareAndSwap64 ptr old new_ mem) => (CMPXCHGQlock ptr old new_ mem)
-
-// Atomic memory updates.
-(AtomicAnd8  ptr val mem) => (ANDBlock ptr val mem)
-(AtomicAnd32 ptr val mem) => (ANDLlock ptr val mem)
-(AtomicOr8   ptr val mem) => (ORBlock  ptr val mem)
-(AtomicOr32  ptr val mem) => (ORLlock  ptr val mem)
-
-// Write barrier.
-(WB ...) => (LoweredWB ...)
-
-(PanicBounds [kind] x y mem) && boundsABI(kind) == 0 => (LoweredPanicBoundsA [kind] x y mem)
-(PanicBounds [kind] x y mem) && boundsABI(kind) == 1 => (LoweredPanicBoundsB [kind] x y mem)
-(PanicBounds [kind] x y mem) && boundsABI(kind) == 2 => (LoweredPanicBoundsC [kind] x y mem)
-
-// ***************************
-// Above: lowering rules
-// Below: optimizations
-// ***************************
-// TODO: Should the optimizations be a separate pass?
-
-// Fold boolean tests into blocks
-(NE (TESTB (SETL  cmp) (SETL  cmp)) yes no) => (LT  cmp yes no)
-(NE (TESTB (SETLE cmp) (SETLE cmp)) yes no) => (LE  cmp yes no)
-(NE (TESTB (SETG  cmp) (SETG  cmp)) yes no) => (GT  cmp yes no)
-(NE (TESTB (SETGE cmp) (SETGE cmp)) yes no) => (GE  cmp yes no)
-(NE (TESTB (SETEQ cmp) (SETEQ cmp)) yes no) => (EQ  cmp yes no)
-(NE (TESTB (SETNE cmp) (SETNE cmp)) yes no) => (NE  cmp yes no)
-(NE (TESTB (SETB  cmp) (SETB  cmp)) yes no) => (ULT cmp yes no)
-(NE (TESTB (SETBE cmp) (SETBE cmp)) yes no) => (ULE cmp yes no)
-(NE (TESTB (SETA  cmp) (SETA  cmp)) yes no) => (UGT cmp yes no)
-(NE (TESTB (SETAE cmp) (SETAE cmp)) yes no) => (UGE cmp yes no)
-(NE (TESTB (SETO cmp) (SETO cmp)) yes no) => (OS cmp yes no)
-
-// Unsigned comparisons to 0/1
-(ULT (TEST(Q|L|W|B) x x) yes no) => (First no yes)
-(UGE (TEST(Q|L|W|B) x x) yes no) => (First yes no)
-(SETB (TEST(Q|L|W|B) x x)) => (ConstBool [false])
-(SETAE (TEST(Q|L|W|B) x x)) => (ConstBool [true])
-
-// x & 1 != 0 -> x & 1
-(SETNE (TEST(B|W)const [1] x)) => (AND(L|L)const [1] x)
-(SETB (BT(L|Q)const [0] x)) => (AND(L|Q)const [1] x)
-
-// Recognize bit tests: a&(1<<b) != 0 for b suitably bounded
-// Note that BTx instructions use the carry bit, so we need to convert tests for zero flag
-// into tests for carry flags.
-// ULT and SETB check the carry flag; they are identical to CS and SETCS. Same, mutatis
-// mutandis, for UGE and SETAE, and CC and SETCC.
-((NE|EQ) (TESTL (SHLL (MOVLconst [1]) x) y)) => ((ULT|UGE) (BTL x y))
-((NE|EQ) (TESTQ (SHLQ (MOVQconst [1]) x) y)) => ((ULT|UGE) (BTQ x y))
-((NE|EQ) (TESTL (SHLXL (MOVLconst [1]) x) y)) => ((ULT|UGE) (BTL x y))
-((NE|EQ) (TESTQ (SHLXQ (MOVQconst [1]) x) y)) => ((ULT|UGE) (BTQ x y))
-((NE|EQ) (TESTLconst [c] x)) && isUint32PowerOfTwo(int64(c))
-    => ((ULT|UGE) (BTLconst [int8(log32(c))] x))
-((NE|EQ) (TESTQconst [c] x)) && isUint64PowerOfTwo(int64(c))
-    => ((ULT|UGE) (BTQconst [int8(log32(c))] x))
-((NE|EQ) (TESTQ (MOVQconst [c]) x)) && isUint64PowerOfTwo(c)
-    => ((ULT|UGE) (BTQconst [int8(log64(c))] x))
-(SET(NE|EQ) (TESTL (SHLL (MOVLconst [1]) x) y)) => (SET(B|AE)  (BTL x y))
-(SET(NE|EQ) (TESTQ (SHLQ (MOVQconst [1]) x) y)) => (SET(B|AE)  (BTQ x y))
-(SET(NE|EQ) (TESTL (SHLXL (MOVLconst [1]) x) y)) => (SET(B|AE)  (BTL x y))
-(SET(NE|EQ) (TESTQ (SHLXQ (MOVQconst [1]) x) y)) => (SET(B|AE)  (BTQ x y))
-(SET(NE|EQ) (TESTLconst [c] x)) && isUint32PowerOfTwo(int64(c))
-    => (SET(B|AE)  (BTLconst [int8(log32(c))] x))
-(SET(NE|EQ) (TESTQconst [c] x)) && isUint64PowerOfTwo(int64(c))
-    => (SET(B|AE)  (BTQconst [int8(log32(c))] x))
-(SET(NE|EQ) (TESTQ (MOVQconst [c]) x)) && isUint64PowerOfTwo(c)
-    => (SET(B|AE)  (BTQconst [int8(log64(c))] x))
-// SET..store variant
-(SET(NE|EQ)store [off] {sym} ptr (TESTL (SHLL (MOVLconst [1]) x) y) mem)
-    => (SET(B|AE)store  [off] {sym} ptr (BTL x y) mem)
-(SET(NE|EQ)store [off] {sym} ptr (TESTQ (SHLQ (MOVQconst [1]) x) y) mem)
-    => (SET(B|AE)store  [off] {sym} ptr (BTQ x y) mem)
-(SET(NE|EQ)store [off] {sym} ptr (TESTL (SHLXL (MOVLconst [1]) x) y) mem)
-    => (SET(B|AE)store  [off] {sym} ptr (BTL x y) mem)
-(SET(NE|EQ)store [off] {sym} ptr (TESTQ (SHLXQ (MOVQconst [1]) x) y) mem)
-    => (SET(B|AE)store  [off] {sym} ptr (BTQ x y) mem)
-(SET(NE|EQ)store [off] {sym} ptr (TESTLconst [c] x) mem) && isUint32PowerOfTwo(int64(c))
-    => (SET(B|AE)store  [off] {sym} ptr (BTLconst [int8(log32(c))] x) mem)
-(SET(NE|EQ)store [off] {sym} ptr (TESTQconst [c] x) mem) && isUint64PowerOfTwo(int64(c))
-    => (SET(B|AE)store  [off] {sym} ptr (BTQconst [int8(log32(c))] x) mem)
-(SET(NE|EQ)store [off] {sym} ptr (TESTQ (MOVQconst [c]) x) mem) && isUint64PowerOfTwo(c)
-    => (SET(B|AE)store  [off] {sym} ptr (BTQconst [int8(log64(c))] x) mem)
-
-// Handle bit-testing in the form (a>>b)&1 != 0 by building the above rules
-// and further combining shifts.
-(BT(Q|L)const [c] (SHRQconst [d] x)) && (c+d)<64 => (BTQconst [c+d] x)
-(BT(Q|L)const [c] (SHLQconst [d] x)) && c>d      => (BT(Q|L)const [c-d] x)
-(BT(Q|L)const [0] s:(SHRQ x y)) => (BTQ y x)
-(BT(Q|L)const [0] s:(SHRXQ x y)) => (BTQ y x)
-(BTLconst [c] (SHRLconst [d] x)) && (c+d)<32 => (BTLconst [c+d] x)
-(BTLconst [c] (SHLLconst [d] x)) && c>d      => (BTLconst [c-d] x)
-(BTLconst [0] s:(SHR(L|XL) x y)) => (BTL y x)
-
-// Rewrite a & 1 != 1 into a & 1 == 0.
-// Among other things, this lets us turn (a>>b)&1 != 1 into a bit test.
-(SET(NE|EQ) (CMPLconst [1] s:(ANDLconst [1] _))) => (SET(EQ|NE) (CMPLconst [0] s))
-(SET(NE|EQ)store [off] {sym} ptr (CMPLconst [1] s:(ANDLconst [1] _)) mem) => (SET(EQ|NE)store [off] {sym} ptr (CMPLconst [0] s) mem)
-(SET(NE|EQ) (CMPQconst [1] s:(ANDQconst [1] _))) => (SET(EQ|NE) (CMPQconst [0] s))
-(SET(NE|EQ)store [off] {sym} ptr (CMPQconst [1] s:(ANDQconst [1] _)) mem) => (SET(EQ|NE)store [off] {sym} ptr (CMPQconst [0] s) mem)
-
-// Recognize bit setting (a |= 1<<b) and toggling (a ^= 1<<b)
-(OR(Q|L) (SHL(Q|L) (MOV(Q|L)const [1]) y) x) => (BTS(Q|L) x y)
-(XOR(Q|L) (SHL(Q|L) (MOV(Q|L)const [1]) y) x) => (BTC(Q|L) x y)
-(OR(Q|L) (SHLX(Q|L) (MOV(Q|L)const [1]) y) x) => (BTS(Q|L) x y)
-(XOR(Q|L) (SHLX(Q|L) (MOV(Q|L)const [1]) y) x) => (BTC(Q|L) x y)
-
-// Convert ORconst into BTS, if the code gets smaller, with boundary being
-// (ORL $40,AX is 3 bytes, ORL $80,AX is 6 bytes).
-((ORQ|XORQ)const [c] x) && isUint64PowerOfTwo(int64(c)) && uint64(c) >= 128
-    => (BT(S|C)Qconst [int8(log32(c))] x)
-((ORL|XORL)const [c] x) && isUint32PowerOfTwo(int64(c)) && uint64(c) >= 128
-    => (BT(S|C)Lconst [int8(log32(c))] x)
-((ORQ|XORQ) (MOVQconst [c]) x) && isUint64PowerOfTwo(c) && uint64(c) >= 128
-    => (BT(S|C)Qconst [int8(log64(c))] x)
-((ORL|XORL) (MOVLconst [c]) x) && isUint32PowerOfTwo(int64(c)) && uint64(c) >= 128
-    => (BT(S|C)Lconst [int8(log32(c))] x)
-
-// Recognize bit clearing: a &^= 1<<b
-(AND(Q|L) (NOT(Q|L) (SHL(Q|L) (MOV(Q|L)const [1]) y)) x) => (BTR(Q|L) x y)
-(ANDN(Q|L) x (SHL(Q|L) (MOV(Q|L)const [1]) y)) => (BTR(Q|L) x y)
-(AND(Q|L) (NOT(Q|L) (SHLX(Q|L) (MOV(Q|L)const [1]) y)) x) => (BTR(Q|L) x y)
-(ANDN(Q|L) x (SHLX(Q|L) (MOV(Q|L)const [1]) y)) => (BTR(Q|L) x y)
-(ANDQconst [c] x) && isUint64PowerOfTwo(int64(^c)) && uint64(^c) >= 128
-    => (BTRQconst [int8(log32(^c))] x)
-(ANDLconst [c] x) && isUint32PowerOfTwo(int64(^c)) && uint64(^c) >= 128
-    => (BTRLconst [int8(log32(^c))] x)
-(ANDQ (MOVQconst [c]) x) && isUint64PowerOfTwo(^c) && uint64(^c) >= 128
-    => (BTRQconst [int8(log64(^c))] x)
-(ANDL (MOVLconst [c]) x) && isUint32PowerOfTwo(int64(^c)) && uint64(^c) >= 128
-    => (BTRLconst [int8(log32(^c))] x)
-
-// Special-case bit patterns on first/last bit.
-// generic.rules changes ANDs of high-part/low-part masks into a couple of shifts,
-// for instance:
-//    x & 0xFFFF0000 -> (x >> 16) << 16
-//    x & 0x80000000 -> (x >> 31) << 31
-//
-// In case the mask is just one bit (like second example above), it conflicts
-// with the above rules to detect bit-testing / bit-clearing of first/last bit.
-// We thus special-case them, by detecting the shift patterns.
-
-// Special case resetting first/last bit
-(SHL(L|Q)const [1] (SHR(L|Q)const [1] x))
-	=> (BTR(L|Q)const [0] x)
-(SHRLconst [1] (SHLLconst [1] x))
-	=> (BTRLconst [31] x)
-(SHRQconst [1] (SHLQconst [1] x))
-	=> (BTRQconst [63] x)
-
-// Special case testing first/last bit (with double-shift generated by generic.rules)
-((SETNE|SETEQ|NE|EQ) (TESTQ z1:(SHLQconst [63] (SHRQconst [63] x)) z2)) && z1==z2
-    => ((SETB|SETAE|ULT|UGE) (BTQconst [63] x))
-((SETNE|SETEQ|NE|EQ) (TESTL z1:(SHLLconst [31] (SHRQconst [31] x)) z2)) && z1==z2
-    => ((SETB|SETAE|ULT|UGE) (BTQconst [31] x))
-(SET(NE|EQ)store [off] {sym} ptr (TESTQ z1:(SHLQconst [63] (SHRQconst [63] x)) z2) mem) && z1==z2
-    => (SET(B|AE)store [off] {sym} ptr (BTQconst [63] x) mem)
-(SET(NE|EQ)store [off] {sym} ptr (TESTL z1:(SHLLconst [31] (SHRLconst [31] x)) z2) mem) && z1==z2
-    => (SET(B|AE)store [off] {sym} ptr (BTLconst [31] x) mem)
-
-((SETNE|SETEQ|NE|EQ) (TESTQ z1:(SHRQconst [63] (SHLQconst [63] x)) z2)) && z1==z2
-    => ((SETB|SETAE|ULT|UGE)  (BTQconst [0] x))
-((SETNE|SETEQ|NE|EQ) (TESTL z1:(SHRLconst [31] (SHLLconst [31] x)) z2)) && z1==z2
-    => ((SETB|SETAE|ULT|UGE)  (BTLconst [0] x))
-(SET(NE|EQ)store [off] {sym} ptr (TESTQ z1:(SHRQconst [63] (SHLQconst [63] x)) z2) mem) && z1==z2
-    => (SET(B|AE)store [off] {sym} ptr (BTQconst [0] x) mem)
-(SET(NE|EQ)store [off] {sym} ptr (TESTL z1:(SHRLconst [31] (SHLLconst [31] x)) z2) mem) && z1==z2
-    => (SET(B|AE)store [off] {sym} ptr (BTLconst [0] x) mem)
-
-// Special-case manually testing last bit with "a>>63 != 0" (without "&1")
-((SETNE|SETEQ|NE|EQ) (TESTQ z1:(SHRQconst [63] x) z2)) && z1==z2
-    => ((SETB|SETAE|ULT|UGE) (BTQconst [63] x))
-((SETNE|SETEQ|NE|EQ) (TESTL z1:(SHRLconst [31] x) z2)) && z1==z2
-    => ((SETB|SETAE|ULT|UGE) (BTLconst [31] x))
-(SET(NE|EQ)store [off] {sym} ptr (TESTQ z1:(SHRQconst [63] x) z2) mem) && z1==z2
-    => (SET(B|AE)store [off] {sym} ptr (BTQconst [63] x) mem)
-(SET(NE|EQ)store [off] {sym} ptr (TESTL z1:(SHRLconst [31] x) z2) mem) && z1==z2
-    => (SET(B|AE)store [off] {sym} ptr (BTLconst [31] x) mem)
-
-// Fold combinations of bit ops on same bit. An example is math.Copysign(c,-1)
-(BTS(Q|L)const [c] (BTR(Q|L)const [c] x)) => (BTS(Q|L)const [c] x)
-(BTS(Q|L)const [c] (BTC(Q|L)const [c] x)) => (BTS(Q|L)const [c] x)
-(BTR(Q|L)const [c] (BTS(Q|L)const [c] x)) => (BTR(Q|L)const [c] x)
-(BTR(Q|L)const [c] (BTC(Q|L)const [c] x)) => (BTR(Q|L)const [c] x)
-
-// Fold boolean negation into SETcc.
-(XORLconst [1] (SETNE x)) => (SETEQ x)
-(XORLconst [1] (SETEQ x)) => (SETNE x)
-(XORLconst [1] (SETL  x)) => (SETGE x)
-(XORLconst [1] (SETGE x)) => (SETL  x)
-(XORLconst [1] (SETLE x)) => (SETG  x)
-(XORLconst [1] (SETG  x)) => (SETLE x)
-(XORLconst [1] (SETB  x)) => (SETAE x)
-(XORLconst [1] (SETAE x)) => (SETB  x)
-(XORLconst [1] (SETBE x)) => (SETA  x)
-(XORLconst [1] (SETA  x)) => (SETBE x)
-
-// Special case for floating point - LF/LEF not generated
-(NE (TESTB (SETGF  cmp) (SETGF  cmp)) yes no) => (UGT  cmp yes no)
-(NE (TESTB (SETGEF cmp) (SETGEF cmp)) yes no) => (UGE  cmp yes no)
-(NE (TESTB (SETEQF cmp) (SETEQF cmp)) yes no) => (EQF  cmp yes no)
-(NE (TESTB (SETNEF cmp) (SETNEF cmp)) yes no) => (NEF  cmp yes no)
-
-// Disabled because it interferes with the pattern match above and makes worse code.
-// (SETNEF x) => (ORQ (SETNE <typ.Int8> x) (SETNAN <typ.Int8> x))
-// (SETEQF x) => (ANDQ (SETEQ <typ.Int8> x) (SETORD <typ.Int8> x))
-
-// fold constants into instructions
-(ADDQ x (MOVQconst [c])) && is32Bit(c) => (ADDQconst [int32(c)] x)
-(ADDQ x (MOVLconst [c])) => (ADDQconst [c] x)
-(ADDL x (MOVLconst [c])) => (ADDLconst [c] x)
-
-(SUBQ x (MOVQconst [c])) && is32Bit(c) => (SUBQconst x [int32(c)])
-(SUBQ (MOVQconst [c]) x) && is32Bit(c) => (NEGQ (SUBQconst <v.Type> x [int32(c)]))
-(SUBL x (MOVLconst [c])) => (SUBLconst x [c])
-(SUBL (MOVLconst [c]) x) => (NEGL (SUBLconst <v.Type> x [c]))
-
-(MULQ x (MOVQconst [c])) && is32Bit(c) => (MULQconst [int32(c)] x)
-(MULL x (MOVLconst [c])) => (MULLconst [c] x)
-
-(ANDQ x (MOVQconst [c])) && is32Bit(c) => (ANDQconst [int32(c)] x)
-(ANDL x (MOVLconst [c])) => (ANDLconst [c] x)
-
-(AND(L|Q)const [c] (AND(L|Q)const [d] x)) => (AND(L|Q)const [c & d] x)
-(XOR(L|Q)const [c] (XOR(L|Q)const [d] x)) => (XOR(L|Q)const [c ^ d] x)
-(OR(L|Q)const  [c] (OR(L|Q)const  [d] x)) => (OR(L|Q)const  [c | d] x)
-
-(BTRLconst [c] (ANDLconst [d] x)) => (ANDLconst [d &^ (1<<uint32(c))] x)
-(ANDLconst [c] (BTRLconst [d] x)) => (ANDLconst [c &^ (1<<uint32(d))] x)
-(BTRLconst [c] (BTRLconst [d] x)) => (ANDLconst [^(1<<uint32(c) | 1<<uint32(d))] x)
-
-(BTCLconst [c] (XORLconst [d] x)) => (XORLconst [d ^ 1<<uint32(c)] x)
-(XORLconst [c] (BTCLconst [d] x)) => (XORLconst [c ^ 1<<uint32(d)] x)
-(BTCLconst [c] (BTCLconst [d] x)) => (XORLconst [1<<uint32(c) | 1<<uint32(d)] x)
-
-(BTSLconst [c] (ORLconst  [d] x)) => (ORLconst [d | 1<<uint32(c)] x)
-(ORLconst  [c] (BTSLconst [d] x)) => (ORLconst [c | 1<<uint32(d)] x)
-(BTSLconst [c] (BTSLconst [d] x)) => (ORLconst [1<<uint32(c) | 1<<uint32(d)] x)
-
-(BTRQconst [c] (ANDQconst [d] x)) && is32Bit(int64(d) &^ (1<<uint32(c)))     => (ANDQconst [d &^ (1<<uint32(c))] x)
-(ANDQconst [c] (BTRQconst [d] x)) && is32Bit(int64(c) &^ (1<<uint32(d)))     => (ANDQconst [c &^ (1<<uint32(d))] x)
-(BTRQconst [c] (BTRQconst [d] x)) && is32Bit(^(1<<uint32(c) | 1<<uint32(d))) => (ANDQconst [^(1<<uint32(c) | 1<<uint32(d))] x)
-
-(BTCQconst [c] (XORQconst [d] x)) && is32Bit(int64(d) ^ 1<<uint32(c))     => (XORQconst [d ^ 1<<uint32(c)] x)
-(XORQconst [c] (BTCQconst [d] x)) && is32Bit(int64(c) ^ 1<<uint32(d))     => (XORQconst [c ^ 1<<uint32(d)] x)
-(BTCQconst [c] (BTCQconst [d] x)) && is32Bit(1<<uint32(c) ^ 1<<uint32(d)) => (XORQconst [1<<uint32(c) ^ 1<<uint32(d)] x)
-
-(BTSQconst [c] (ORQconst  [d] x)) && is32Bit(int64(d) | 1<<uint32(c))     => (ORQconst [d | 1<<uint32(c)] x)
-(ORQconst  [c] (BTSQconst [d] x)) && is32Bit(int64(c) | 1<<uint32(d))     => (ORQconst [c | 1<<uint32(d)] x)
-(BTSQconst [c] (BTSQconst [d] x)) && is32Bit(1<<uint32(c) | 1<<uint32(d)) => (ORQconst [1<<uint32(c) | 1<<uint32(d)] x)
-
-
-(MULLconst [c] (MULLconst [d] x)) => (MULLconst [c * d] x)
-(MULQconst [c] (MULQconst [d] x)) && is32Bit(int64(c)*int64(d)) => (MULQconst [c * d] x)
-
-(ORQ x (MOVQconst [c])) && is32Bit(c) => (ORQconst [int32(c)] x)
-(ORQ x (MOVLconst [c])) => (ORQconst [c] x)
-(ORL x (MOVLconst [c])) => (ORLconst [c] x)
-
-(XORQ x (MOVQconst [c])) && is32Bit(c) => (XORQconst [int32(c)] x)
-(XORL x (MOVLconst [c])) => (XORLconst [c] x)
-
-(SHLQ x (MOV(Q|L)const [c])) => (SHLQconst [int8(c&63)] x)
-(SHLL x (MOV(Q|L)const [c])) => (SHLLconst [int8(c&31)] x)
-(SHLXQ x (MOV(Q|L)const [c])) => (SHLQconst [int8(c&63)] x)
-(SHLXL x (MOV(Q|L)const [c])) => (SHLLconst [int8(c&31)] x)
-
-(SHRQ x (MOV(Q|L)const [c])) => (SHRQconst [int8(c&63)] x)
-(SHRL x (MOV(Q|L)const [c])) => (SHRLconst [int8(c&31)] x)
-(SHRW x (MOV(Q|L)const [c])) && c&31 < 16 => (SHRWconst [int8(c&31)] x)
-(SHRW _ (MOV(Q|L)const [c])) && c&31 >= 16 => (MOVLconst [0])
-(SHRB x (MOV(Q|L)const [c])) && c&31 < 8 => (SHRBconst [int8(c&31)] x)
-(SHRB _ (MOV(Q|L)const [c])) && c&31 >= 8 => (MOVLconst [0])
-(SHRXQ x (MOV(Q|L)const [c])) => (SHRQconst [int8(c&63)] x)
-(SHRXL x (MOV(Q|L)const [c])) => (SHRLconst [int8(c&31)] x)
-
-(SARQ x (MOV(Q|L)const [c])) => (SARQconst [int8(c&63)] x)
-(SARL x (MOV(Q|L)const [c])) => (SARLconst [int8(c&31)] x)
-(SARW x (MOV(Q|L)const [c])) => (SARWconst [int8(min(int64(c)&31,15))] x)
-(SARB x (MOV(Q|L)const [c])) => (SARBconst [int8(min(int64(c)&31,7))] x)
-(SARXQ x (MOV(Q|L)const [c])) => (SARQconst [int8(c&63)] x)
-(SARXL x (MOV(Q|L)const [c])) => (SARLconst [int8(c&31)] x)
-
-// Operations which don't affect the low 6/5 bits of the shift amount are NOPs.
-((SHLQ|SHRQ|SARQ|SHLXQ|SHRXQ|SARXQ) x (ADDQconst [c] y)) && c & 63 == 0  => ((SHLQ|SHRQ|SARQ|SHLXQ|SHRXQ|SARXQ) x y)
-((SHLQ|SHRQ|SARQ|SHLXQ|SHRXQ|SARXQ) x (NEGQ <t> (ADDQconst [c] y))) && c & 63 == 0  => ((SHLQ|SHRQ|SARQ|SHLXQ|SHRXQ|SARXQ) x (NEGQ <t> y))
-((SHLQ|SHRQ|SARQ|SHLXQ|SHRXQ|SARXQ) x (ANDQconst [c] y)) && c & 63 == 63 => ((SHLQ|SHRQ|SARQ|SHLXQ|SHRXQ|SARXQ) x y)
-((SHLQ|SHRQ|SARQ|SHLXQ|SHRXQ|SARXQ) x (NEGQ <t> (ANDQconst [c] y))) && c & 63 == 63 => ((SHLQ|SHRQ|SARQ|SHLXQ|SHRXQ|SARXQ) x (NEGQ <t> y))
-
-((SHLL|SHRL|SARL|SHLXL|SHRXL|SARXL) x (ADDQconst [c] y)) && c & 31 == 0  => ((SHLL|SHRL|SARL|SHLXL|SHRXL|SARXL) x y)
-((SHLL|SHRL|SARL|SHLXL|SHRXL|SARXL) x (NEGQ <t> (ADDQconst [c] y))) && c & 31 == 0  => ((SHLL|SHRL|SARL|SHLXL|SHRXL|SARXL) x (NEGQ <t> y))
-((SHLL|SHRL|SARL|SHLXL|SHRXL|SARXL) x (ANDQconst [c] y)) && c & 31 == 31 => ((SHLL|SHRL|SARL|SHLXL|SHRXL|SARXL) x y)
-((SHLL|SHRL|SARL|SHLXL|SHRXL|SARXL) x (NEGQ <t> (ANDQconst [c] y))) && c & 31 == 31 => ((SHLL|SHRL|SARL|SHLXL|SHRXL|SARXL) x (NEGQ <t> y))
-
-((SHLQ|SHRQ|SARQ|SHLXQ|SHRXQ|SARXQ) x (ADDLconst [c] y)) && c & 63 == 0  => ((SHLQ|SHRQ|SARQ|SHLXQ|SHRXQ|SARXQ) x y)
-((SHLQ|SHRQ|SARQ|SHLXQ|SHRXQ|SARXQ) x (NEGL <t> (ADDLconst [c] y))) && c & 63 == 0  => ((SHLQ|SHRQ|SARQ|SHLXQ|SHRXQ|SARXQ) x (NEGL <t> y))
-((SHLQ|SHRQ|SARQ|SHLXQ|SHRXQ|SARXQ) x (ANDLconst [c] y)) && c & 63 == 63 => ((SHLQ|SHRQ|SARQ|SHLXQ|SHRXQ|SARXQ) x y)
-((SHLQ|SHRQ|SARQ|SHLXQ|SHRXQ|SARXQ) x (NEGL <t> (ANDLconst [c] y))) && c & 63 == 63 => ((SHLQ|SHRQ|SARQ|SHLXQ|SHRXQ|SARXQ) x (NEGL <t> y))
-
-((SHLL|SHRL|SARL|SHLXL|SHRXL|SARXL) x (ADDLconst [c] y)) && c & 31 == 0  => ((SHLL|SHRL|SARL|SHLXL|SHRXL|SARXL) x y)
-((SHLL|SHRL|SARL|SHLXL|SHRXL|SARXL) x (NEGL <t> (ADDLconst [c] y))) && c & 31 == 0  => ((SHLL|SHRL|SARL|SHLXL|SHRXL|SARXL) x (NEGL <t> y))
-((SHLL|SHRL|SARL|SHLXL|SHRXL|SARXL) x (ANDLconst [c] y)) && c & 31 == 31 => ((SHLL|SHRL|SARL|SHLXL|SHRXL|SARXL) x y)
-((SHLL|SHRL|SARL|SHLXL|SHRXL|SARXL) x (NEGL <t> (ANDLconst [c] y))) && c & 31 == 31 => ((SHLL|SHRL|SARL|SHLXL|SHRXL|SARXL) x (NEGL <t> y))
-
-// Constant rotate instructions
-((ADDQ|ORQ|XORQ) (SHLQconst x [c]) (SHRQconst x [d])) && d==64-c => (ROLQconst x [c])
-((ADDL|ORL|XORL) (SHLLconst x [c]) (SHRLconst x [d])) && d==32-c => (ROLLconst x [c])
-
-((ADDL|ORL|XORL) <t> (SHLLconst x [c]) (SHRWconst x [d])) && d==16-c && c < 16 && t.Size() == 2 => (ROLWconst x [c])
-((ADDL|ORL|XORL) <t> (SHLLconst x [c]) (SHRBconst x [d])) && d==8-c  && c < 8  && t.Size() == 1 => (ROLBconst x [c])
-
-(ROLQconst [c] (ROLQconst [d] x)) => (ROLQconst [(c+d)&63] x)
-(ROLLconst [c] (ROLLconst [d] x)) => (ROLLconst [(c+d)&31] x)
-(ROLWconst [c] (ROLWconst [d] x)) => (ROLWconst [(c+d)&15] x)
-(ROLBconst [c] (ROLBconst [d] x)) => (ROLBconst [(c+d)& 7] x)
-
-(RotateLeft8  ...) => (ROLB ...)
-(RotateLeft16 ...) => (ROLW ...)
-(RotateLeft32 ...) => (ROLL ...)
-(RotateLeft64 ...) => (ROLQ ...)
-
-// Non-constant rotates.
-// We want to issue a rotate when the Go source contains code like
-//     y &= 63
-//     x << y | x >> (64-y)
-// The shift rules above convert << to SHLx and >> to SHRx.
-// SHRx converts its shift argument from 64-y to -y.
-// A tricky situation occurs when y==0. Then the original code would be:
-//     x << 0 | x >> 64
-// But x >> 64 is 0, not x. So there's an additional mask that is ANDed in
-// to force the second term to 0. We don't need that mask, but we must match
-// it in order to strip it out.
-(ORQ (SHLQ x y) (ANDQ (SHRQ x (NEG(Q|L) y)) (SBBQcarrymask (CMP(Q|L)const (NEG(Q|L) (ADD(Q|L)const (AND(Q|L)const y [63]) [-64])) [64])))) => (ROLQ x y)
-(ORQ (SHRQ x y) (ANDQ (SHLQ x (NEG(Q|L) y)) (SBBQcarrymask (CMP(Q|L)const (NEG(Q|L) (ADD(Q|L)const (AND(Q|L)const y [63]) [-64])) [64])))) => (RORQ x y)
-(ORQ (SHLXQ x y) (ANDQ (SHRXQ x (NEG(Q|L) y)) (SBBQcarrymask (CMP(Q|L)const (NEG(Q|L) (ADD(Q|L)const (AND(Q|L)const y [63]) [-64])) [64])))) => (ROLQ x y)
-(ORQ (SHRXQ x y) (ANDQ (SHLXQ x (NEG(Q|L) y)) (SBBQcarrymask (CMP(Q|L)const (NEG(Q|L) (ADD(Q|L)const (AND(Q|L)const y [63]) [-64])) [64])))) => (RORQ x y)
-
-(ORL (SHLL x y) (ANDL (SHRL x (NEG(Q|L) y)) (SBBLcarrymask (CMP(Q|L)const (NEG(Q|L) (ADD(Q|L)const (AND(Q|L)const y [31]) [-32])) [32])))) => (ROLL x y)
-(ORL (SHRL x y) (ANDL (SHLL x (NEG(Q|L) y)) (SBBLcarrymask (CMP(Q|L)const (NEG(Q|L) (ADD(Q|L)const (AND(Q|L)const y [31]) [-32])) [32])))) => (RORL x y)
-(ORL (SHLXL x y) (ANDL (SHRXL x (NEG(Q|L) y)) (SBBLcarrymask (CMP(Q|L)const (NEG(Q|L) (ADD(Q|L)const (AND(Q|L)const y [31]) [-32])) [32])))) => (ROLL x y)
-(ORL (SHRXL x y) (ANDL (SHLXL x (NEG(Q|L) y)) (SBBLcarrymask (CMP(Q|L)const (NEG(Q|L) (ADD(Q|L)const (AND(Q|L)const y [31]) [-32])) [32])))) => (RORL x y)
-
-// Help with rotate detection
-(CMPQconst (NEGQ (ADDQconst [-16] (ANDQconst [15] _))) [32]) => (FlagLT_ULT)
-(CMPQconst (NEGQ (ADDQconst [ -8] (ANDQconst  [7] _))) [32]) => (FlagLT_ULT)
-
-(ORL (SHLL x (AND(Q|L)const y [15]))
-     (ANDL (SHRW x (NEG(Q|L) (ADD(Q|L)const (AND(Q|L)const y [15]) [-16])))
-           (SBBLcarrymask (CMP(Q|L)const (NEG(Q|L) (ADD(Q|L)const (AND(Q|L)const y [15]) [-16])) [16]))))
-  && v.Type.Size() == 2
-  => (ROLW x y)
-(ORL (SHRW x (AND(Q|L)const y [15]))
-     (SHLL x (NEG(Q|L) (ADD(Q|L)const (AND(Q|L)const y [15]) [-16]))))
-  && v.Type.Size() == 2
-  => (RORW x y)
-(ORL (SHLXL x (AND(Q|L)const y [15]))
-     (ANDL (SHRW x (NEG(Q|L) (ADD(Q|L)const (AND(Q|L)const y [15]) [-16])))
-           (SBBLcarrymask (CMP(Q|L)const (NEG(Q|L) (ADD(Q|L)const (AND(Q|L)const y [15]) [-16])) [16]))))
-  && v.Type.Size() == 2
-  => (ROLW x y)
-(ORL (SHRW x (AND(Q|L)const y [15]))
-     (SHLXL x (NEG(Q|L) (ADD(Q|L)const (AND(Q|L)const y [15]) [-16]))))
-  && v.Type.Size() == 2
-  => (RORW x y)
-
-(ORL (SHLL x (AND(Q|L)const y [ 7]))
-     (ANDL (SHRB x (NEG(Q|L) (ADD(Q|L)const (AND(Q|L)const y [ 7]) [ -8])))
-           (SBBLcarrymask (CMP(Q|L)const (NEG(Q|L) (ADD(Q|L)const (AND(Q|L)const y [ 7]) [ -8])) [ 8]))))
-  && v.Type.Size() == 1
-  => (ROLB x y)
-(ORL (SHRB x (AND(Q|L)const y [ 7]))
-     (SHLL x (NEG(Q|L) (ADD(Q|L)const (AND(Q|L)const y [ 7]) [ -8]))))
-  && v.Type.Size() == 1
-  => (RORB x y)
-(ORL (SHLXL x (AND(Q|L)const y [ 7]))
-     (ANDL (SHRB x (NEG(Q|L) (ADD(Q|L)const (AND(Q|L)const y [ 7]) [ -8])))
-           (SBBLcarrymask (CMP(Q|L)const (NEG(Q|L) (ADD(Q|L)const (AND(Q|L)const y [ 7]) [ -8])) [ 8]))))
-  && v.Type.Size() == 1
-  => (ROLB x y)
-(ORL (SHRB x (AND(Q|L)const y [ 7]))
-     (SHLXL x (NEG(Q|L) (ADD(Q|L)const (AND(Q|L)const y [ 7]) [ -8]))))
-  && v.Type.Size() == 1
-  => (RORB x y)
-
-// rotate left negative = rotate right
-(ROLQ x (NEG(Q|L) y)) => (RORQ x y)
-(ROLL x (NEG(Q|L) y)) => (RORL x y)
-(ROLW x (NEG(Q|L) y)) => (RORW x y)
-(ROLB x (NEG(Q|L) y)) => (RORB x y)
-
-// rotate right negative = rotate left
-(RORQ x (NEG(Q|L) y)) => (ROLQ x y)
-(RORL x (NEG(Q|L) y)) => (ROLL x y)
-(RORW x (NEG(Q|L) y)) => (ROLW x y)
-(RORB x (NEG(Q|L) y)) => (ROLB x y)
-
-// rotate by constants
-(ROLQ x (MOV(Q|L)const [c])) => (ROLQconst [int8(c&63)] x)
-(ROLL x (MOV(Q|L)const [c])) => (ROLLconst [int8(c&31)] x)
-(ROLW x (MOV(Q|L)const [c])) => (ROLWconst [int8(c&15)] x)
-(ROLB x (MOV(Q|L)const [c])) => (ROLBconst [int8(c&7) ] x)
-
-(RORQ x (MOV(Q|L)const [c])) => (ROLQconst [int8((-c)&63)] x)
-(RORL x (MOV(Q|L)const [c])) => (ROLLconst [int8((-c)&31)] x)
-(RORW x (MOV(Q|L)const [c])) => (ROLWconst [int8((-c)&15)] x)
-(RORB x (MOV(Q|L)const [c])) => (ROLBconst [int8((-c)&7) ] x)
-
-// Constant shift simplifications
-((SHLQ|SHRQ|SARQ)const      x [0]) => x
-((SHLL|SHRL|SARL)const      x [0]) => x
-((SHRW|SARW)const           x [0]) => x
-((SHRB|SARB)const           x [0]) => x
-((ROLQ|ROLL|ROLW|ROLB)const x [0]) => x
-
-// Multi-register shifts
-(ORQ (SH(R|L)Q lo bits) (SH(L|R)Q hi (NEGQ bits))) => (SH(R|L)DQ lo hi bits)
-(ORQ (SH(R|L)XQ lo bits) (SH(L|R)XQ hi (NEGQ bits))) => (SH(R|L)DQ lo hi bits)
-
-// Note: the word and byte shifts keep the low 5 bits (not the low 4 or 3 bits)
-// because the x86 instructions are defined to use all 5 bits of the shift even
-// for the small shifts. I don't think we'll ever generate a weird shift (e.g.
-// (SHRW x (MOVLconst [24])), but just in case.
-
-(CMPQ x (MOVQconst [c])) && is32Bit(c) => (CMPQconst x [int32(c)])
-(CMPQ (MOVQconst [c]) x) && is32Bit(c) => (InvertFlags (CMPQconst x [int32(c)]))
-(CMPL x (MOVLconst [c])) => (CMPLconst x [c])
-(CMPL (MOVLconst [c]) x) => (InvertFlags (CMPLconst x [c]))
-(CMPW x (MOVLconst [c])) => (CMPWconst x [int16(c)])
-(CMPW (MOVLconst [c]) x) => (InvertFlags (CMPWconst x [int16(c)]))
-(CMPB x (MOVLconst [c])) => (CMPBconst x [int8(c)])
-(CMPB (MOVLconst [c]) x) => (InvertFlags (CMPBconst x [int8(c)]))
-
-// Canonicalize the order of arguments to comparisons - helps with CSE.
-(CMP(Q|L|W|B) x y) && canonLessThan(x,y) => (InvertFlags (CMP(Q|L|W|B) y x))
-
-// Using MOVZX instead of AND is cheaper.
-(AND(Q|L)const [  0xFF] x) => (MOVBQZX x)
-(AND(Q|L)const [0xFFFF] x) => (MOVWQZX x)
-// This rule is currently invalid because 0xFFFFFFFF is not representable by a signed int32.
-// Commenting out for now, because it also can't trigger because of the is32bit guard on the
-// ANDQconst lowering-rule, above, prevents 0xFFFFFFFF from matching (for the same reason)
-// Using an alternate form of this rule segfaults some binaries because of
-// adverse interactions with other passes.
-// (ANDQconst [0xFFFFFFFF] x) => (MOVLQZX x)
-
-// strength reduction
-// Assumes that the following costs from https://gmplib.org/~tege/x86-timing.pdf:
-//    1 - addq, shlq, leaq, negq, subq
-//    3 - imulq
-// This limits the rewrites to two instructions.
-// Note that negq always operates in-place,
-// which can require a register-register move
-// to preserve the original value,
-// so it must be used with care.
-(MUL(Q|L)const [-9] x) => (NEG(Q|L) (LEA(Q|L)8 <v.Type> x x))
-(MUL(Q|L)const [-5] x) => (NEG(Q|L) (LEA(Q|L)4 <v.Type> x x))
-(MUL(Q|L)const [-3] x) => (NEG(Q|L) (LEA(Q|L)2 <v.Type> x x))
-(MUL(Q|L)const [-1] x) => (NEG(Q|L) x)
-(MUL(Q|L)const [ 0] _) => (MOV(Q|L)const [0])
-(MUL(Q|L)const [ 1] x) => x
-(MUL(Q|L)const [ 3] x) => (LEA(Q|L)2 x x)
-(MUL(Q|L)const [ 5] x) => (LEA(Q|L)4 x x)
-(MUL(Q|L)const [ 7] x) => (LEA(Q|L)2 x (LEA(Q|L)2 <v.Type> x x))
-(MUL(Q|L)const [ 9] x) => (LEA(Q|L)8 x x)
-(MUL(Q|L)const [11] x) => (LEA(Q|L)2 x (LEA(Q|L)4 <v.Type> x x))
-(MUL(Q|L)const [13] x) => (LEA(Q|L)4 x (LEA(Q|L)2 <v.Type> x x))
-(MUL(Q|L)const [19] x) => (LEA(Q|L)2 x (LEA(Q|L)8 <v.Type> x x))
-(MUL(Q|L)const [21] x) => (LEA(Q|L)4 x (LEA(Q|L)4 <v.Type> x x))
-(MUL(Q|L)const [25] x) => (LEA(Q|L)8 x (LEA(Q|L)2 <v.Type> x x))
-(MUL(Q|L)const [27] x) => (LEA(Q|L)8 (LEA(Q|L)2 <v.Type> x x) (LEA(Q|L)2 <v.Type> x x))
-(MUL(Q|L)const [37] x) => (LEA(Q|L)4 x (LEA(Q|L)8 <v.Type> x x))
-(MUL(Q|L)const [41] x) => (LEA(Q|L)8 x (LEA(Q|L)4 <v.Type> x x))
-(MUL(Q|L)const [45] x) => (LEA(Q|L)8 (LEA(Q|L)4 <v.Type> x x) (LEA(Q|L)4 <v.Type> x x))
-(MUL(Q|L)const [73] x) => (LEA(Q|L)8 x (LEA(Q|L)8 <v.Type> x x))
-(MUL(Q|L)const [81] x) => (LEA(Q|L)8 (LEA(Q|L)8 <v.Type> x x) (LEA(Q|L)8 <v.Type> x x))
-
-(MUL(Q|L)const [c] x) && isPowerOfTwo64(int64(c)+1) && c >=  15 => (SUB(Q|L)  (SHL(Q|L)const <v.Type> [int8(log64(int64(c)+1))] x) x)
-(MUL(Q|L)const [c] x) && isPowerOfTwo32(c-1) && c >=  17 => (LEA(Q|L)1 (SHL(Q|L)const <v.Type> [int8(log32(c-1))] x) x)
-(MUL(Q|L)const [c] x) && isPowerOfTwo32(c-2) && c >=  34 => (LEA(Q|L)2 (SHL(Q|L)const <v.Type> [int8(log32(c-2))] x) x)
-(MUL(Q|L)const [c] x) && isPowerOfTwo32(c-4) && c >=  68 => (LEA(Q|L)4 (SHL(Q|L)const <v.Type> [int8(log32(c-4))] x) x)
-(MUL(Q|L)const [c] x) && isPowerOfTwo32(c-8) && c >= 136 => (LEA(Q|L)8 (SHL(Q|L)const <v.Type> [int8(log32(c-8))] x) x)
-(MUL(Q|L)const [c] x) && c%3 == 0 && isPowerOfTwo32(c/3) => (SHL(Q|L)const [int8(log32(c/3))] (LEA(Q|L)2 <v.Type> x x))
-(MUL(Q|L)const [c] x) && c%5 == 0 && isPowerOfTwo32(c/5) => (SHL(Q|L)const [int8(log32(c/5))] (LEA(Q|L)4 <v.Type> x x))
-(MUL(Q|L)const [c] x) && c%9 == 0 && isPowerOfTwo32(c/9) => (SHL(Q|L)const [int8(log32(c/9))] (LEA(Q|L)8 <v.Type> x x))
-
-// combine add/shift into LEAQ/LEAL
-(ADD(L|Q) x (SHL(L|Q)const [3] y)) => (LEA(L|Q)8 x y)
-(ADD(L|Q) x (SHL(L|Q)const [2] y)) => (LEA(L|Q)4 x y)
-(ADD(L|Q) x (SHL(L|Q)const [1] y)) => (LEA(L|Q)2 x y)
-(ADD(L|Q) x (ADD(L|Q) y y))        => (LEA(L|Q)2 x y)
-(ADD(L|Q) x (ADD(L|Q) x y))        => (LEA(L|Q)2 y x)
-
-// combine ADDQ/ADDQconst into LEAQ1/LEAL1
-(ADD(Q|L)const [c] (ADD(Q|L) x y)) => (LEA(Q|L)1 [c] x y)
-(ADD(Q|L) (ADD(Q|L)const [c] x) y) => (LEA(Q|L)1 [c] x y)
-(ADD(Q|L)const [c] (SHL(Q|L)const [1] x)) => (LEA(Q|L)1 [c] x x)
-
-// fold ADDQ/ADDL into LEAQ/LEAL
-(ADD(Q|L)const [c] (LEA(Q|L) [d] {s} x)) && is32Bit(int64(c)+int64(d)) => (LEA(Q|L) [c+d] {s} x)
-(LEA(Q|L) [c] {s} (ADD(Q|L)const [d] x)) && is32Bit(int64(c)+int64(d)) => (LEA(Q|L) [c+d] {s} x)
-(LEA(Q|L) [c] {s} (ADD(Q|L) x y)) && x.Op != OpSB && y.Op != OpSB => (LEA(Q|L)1 [c] {s} x y)
-(ADD(Q|L) x (LEA(Q|L) [c] {s} y)) && x.Op != OpSB && y.Op != OpSB => (LEA(Q|L)1 [c] {s} x y)
-
-// fold ADDQconst/ADDLconst into LEAQx/LEALx
-(ADD(Q|L)const [c] (LEA(Q|L)1 [d] {s} x y)) && is32Bit(int64(c)+int64(d)) => (LEA(Q|L)1 [c+d] {s} x y)
-(ADD(Q|L)const [c] (LEA(Q|L)2 [d] {s} x y)) && is32Bit(int64(c)+int64(d)) => (LEA(Q|L)2 [c+d] {s} x y)
-(ADD(Q|L)const [c] (LEA(Q|L)4 [d] {s} x y)) && is32Bit(int64(c)+int64(d)) => (LEA(Q|L)4 [c+d] {s} x y)
-(ADD(Q|L)const [c] (LEA(Q|L)8 [d] {s} x y)) && is32Bit(int64(c)+int64(d)) => (LEA(Q|L)8 [c+d] {s} x y)
-(LEA(Q|L)1 [c] {s} (ADD(Q|L)const [d] x) y) && is32Bit(int64(c)+int64(d))   && x.Op != OpSB => (LEA(Q|L)1 [c+d] {s} x y)
-(LEA(Q|L)2 [c] {s} (ADD(Q|L)const [d] x) y) && is32Bit(int64(c)+int64(d))   && x.Op != OpSB => (LEA(Q|L)2 [c+d] {s} x y)
-(LEA(Q|L)2 [c] {s} x (ADD(Q|L)const [d] y)) && is32Bit(int64(c)+2*int64(d)) && y.Op != OpSB => (LEA(Q|L)2 [c+2*d] {s} x y)
-(LEA(Q|L)4 [c] {s} (ADD(Q|L)const [d] x) y) && is32Bit(int64(c)+int64(d))   && x.Op != OpSB => (LEA(Q|L)4 [c+d] {s} x y)
-(LEA(Q|L)4 [c] {s} x (ADD(Q|L)const [d] y)) && is32Bit(int64(c)+4*int64(d)) && y.Op != OpSB => (LEA(Q|L)4 [c+4*d] {s} x y)
-(LEA(Q|L)8 [c] {s} (ADD(Q|L)const [d] x) y) && is32Bit(int64(c)+int64(d))   && x.Op != OpSB => (LEA(Q|L)8 [c+d] {s} x y)
-(LEA(Q|L)8 [c] {s} x (ADD(Q|L)const [d] y)) && is32Bit(int64(c)+8*int64(d)) && y.Op != OpSB => (LEA(Q|L)8 [c+8*d] {s} x y)
-
-// fold shifts into LEAQx/LEALx
-(LEA(Q|L)1 [c] {s} x (SHL(Q|L)const [1] y)) => (LEA(Q|L)2 [c] {s} x y)
-(LEA(Q|L)1 [c] {s} x (SHL(Q|L)const [2] y)) => (LEA(Q|L)4 [c] {s} x y)
-(LEA(Q|L)1 [c] {s} x (SHL(Q|L)const [3] y)) => (LEA(Q|L)8 [c] {s} x y)
-(LEA(Q|L)2 [c] {s} x (SHL(Q|L)const [1] y)) => (LEA(Q|L)4 [c] {s} x y)
-(LEA(Q|L)2 [c] {s} x (SHL(Q|L)const [2] y)) => (LEA(Q|L)8 [c] {s} x y)
-(LEA(Q|L)4 [c] {s} x (SHL(Q|L)const [1] y)) => (LEA(Q|L)8 [c] {s} x y)
-
-// reverse ordering of compare instruction
-(SETL (InvertFlags x)) => (SETG x)
-(SETG (InvertFlags x)) => (SETL x)
-(SETB (InvertFlags x)) => (SETA x)
-(SETA (InvertFlags x)) => (SETB x)
-(SETLE (InvertFlags x)) => (SETGE x)
-(SETGE (InvertFlags x)) => (SETLE x)
-(SETBE (InvertFlags x)) => (SETAE x)
-(SETAE (InvertFlags x)) => (SETBE x)
-(SETEQ (InvertFlags x)) => (SETEQ x)
-(SETNE (InvertFlags x)) => (SETNE x)
-
-(SETLstore [off] {sym} ptr (InvertFlags x) mem) => (SETGstore [off] {sym} ptr x mem)
-(SETGstore [off] {sym} ptr (InvertFlags x) mem) => (SETLstore [off] {sym} ptr x mem)
-(SETBstore [off] {sym} ptr (InvertFlags x) mem) => (SETAstore [off] {sym} ptr x mem)
-(SETAstore [off] {sym} ptr (InvertFlags x) mem) => (SETBstore [off] {sym} ptr x mem)
-(SETLEstore [off] {sym} ptr (InvertFlags x) mem) => (SETGEstore [off] {sym} ptr x mem)
-(SETGEstore [off] {sym} ptr (InvertFlags x) mem) => (SETLEstore [off] {sym} ptr x mem)
-(SETBEstore [off] {sym} ptr (InvertFlags x) mem) => (SETAEstore [off] {sym} ptr x mem)
-(SETAEstore [off] {sym} ptr (InvertFlags x) mem) => (SETBEstore [off] {sym} ptr x mem)
-(SETEQstore [off] {sym} ptr (InvertFlags x) mem) => (SETEQstore [off] {sym} ptr x mem)
-(SETNEstore [off] {sym} ptr (InvertFlags x) mem) => (SETNEstore [off] {sym} ptr x mem)
-
-// sign extended loads
-// Note: The combined instruction must end up in the same block
-// as the original load. If not, we end up making a value with
-// memory type live in two different blocks, which can lead to
-// multiple memory values alive simultaneously.
-// Make sure we don't combine these ops if the load has another use.
-// This prevents a single load from being split into multiple loads
-// which then might return different values.  See test/atomicload.go.
-(MOVBQSX x:(MOVBload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVBQSXload <v.Type> [off] {sym} ptr mem)
-(MOVBQSX x:(MOVWload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVBQSXload <v.Type> [off] {sym} ptr mem)
-(MOVBQSX x:(MOVLload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVBQSXload <v.Type> [off] {sym} ptr mem)
-(MOVBQSX x:(MOVQload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVBQSXload <v.Type> [off] {sym} ptr mem)
-(MOVBQZX x:(MOVBload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVBload <v.Type> [off] {sym} ptr mem)
-(MOVBQZX x:(MOVWload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVBload <v.Type> [off] {sym} ptr mem)
-(MOVBQZX x:(MOVLload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVBload <v.Type> [off] {sym} ptr mem)
-(MOVBQZX x:(MOVQload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVBload <v.Type> [off] {sym} ptr mem)
-(MOVWQSX x:(MOVWload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVWQSXload <v.Type> [off] {sym} ptr mem)
-(MOVWQSX x:(MOVLload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVWQSXload <v.Type> [off] {sym} ptr mem)
-(MOVWQSX x:(MOVQload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVWQSXload <v.Type> [off] {sym} ptr mem)
-(MOVWQZX x:(MOVWload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVWload <v.Type> [off] {sym} ptr mem)
-(MOVWQZX x:(MOVLload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVWload <v.Type> [off] {sym} ptr mem)
-(MOVWQZX x:(MOVQload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVWload <v.Type> [off] {sym} ptr mem)
-(MOVLQSX x:(MOVLload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVLQSXload <v.Type> [off] {sym} ptr mem)
-(MOVLQSX x:(MOVQload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVLQSXload <v.Type> [off] {sym} ptr mem)
-(MOVLQZX x:(MOVLload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVLload <v.Type> [off] {sym} ptr mem)
-(MOVLQZX x:(MOVQload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVLload <v.Type> [off] {sym} ptr mem)
-
-(MOVLQZX x) && zeroUpper32Bits(x,3) => x
-(MOVWQZX x) && zeroUpper48Bits(x,3) => x
-(MOVBQZX x) && zeroUpper56Bits(x,3) => x
-
-// replace load from same location as preceding store with zero/sign extension (or copy in case of full width)
-(MOVBload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVBQZX x)
-(MOVWload [off] {sym} ptr (MOVWstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVWQZX x)
-(MOVLload [off] {sym} ptr (MOVLstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVLQZX x)
-(MOVQload [off] {sym} ptr (MOVQstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => x
-(MOVBQSXload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVBQSX x)
-(MOVWQSXload [off] {sym} ptr (MOVWstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVWQSX x)
-(MOVLQSXload [off] {sym} ptr (MOVLstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVLQSX x)
-
-// Fold extensions and ANDs together.
-(MOVBQZX (ANDLconst [c] x)) => (ANDLconst [c & 0xff] x)
-(MOVWQZX (ANDLconst [c] x)) => (ANDLconst [c & 0xffff] x)
-(MOVLQZX (ANDLconst [c] x)) => (ANDLconst [c] x)
-(MOVBQSX (ANDLconst [c] x)) && c & 0x80 == 0 => (ANDLconst [c & 0x7f] x)
-(MOVWQSX (ANDLconst [c] x)) && c & 0x8000 == 0 => (ANDLconst [c & 0x7fff] x)
-(MOVLQSX (ANDLconst [c] x)) && uint32(c) & 0x80000000 == 0 => (ANDLconst [c & 0x7fffffff] x)
-
-// Don't extend before storing
-(MOVLstore [off] {sym} ptr (MOVLQSX x) mem) => (MOVLstore [off] {sym} ptr x mem)
-(MOVWstore [off] {sym} ptr (MOVWQSX x) mem) => (MOVWstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr (MOVBQSX x) mem) => (MOVBstore [off] {sym} ptr x mem)
-(MOVLstore [off] {sym} ptr (MOVLQZX x) mem) => (MOVLstore [off] {sym} ptr x mem)
-(MOVWstore [off] {sym} ptr (MOVWQZX x) mem) => (MOVWstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr (MOVBQZX x) mem) => (MOVBstore [off] {sym} ptr x mem)
-
-// fold constants into memory operations
-// Note that this is not always a good idea because if not all the uses of
-// the ADDQconst get eliminated, we still have to compute the ADDQconst and we now
-// have potentially two live values (ptr and (ADDQconst [off] ptr)) instead of one.
-// Nevertheless, let's do it!
-(MOV(Q|L|W|B|SS|SD|O)load  [off1] {sym} (ADDQconst [off2] ptr) mem) && is32Bit(int64(off1)+int64(off2)) =>
-    (MOV(Q|L|W|B|SS|SD|O)load  [off1+off2] {sym} ptr mem)
-(MOV(Q|L|W|B|SS|SD|O)store  [off1] {sym} (ADDQconst [off2] ptr) val mem) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOV(Q|L|W|B|SS|SD|O)store  [off1+off2] {sym} ptr val mem)
-(SET(L|G|B|A|LE|GE|BE|AE|EQ|NE)store [off1] {sym} (ADDQconst [off2] base) val mem) && is32Bit(int64(off1)+int64(off2)) =>
-	(SET(L|G|B|A|LE|GE|BE|AE|EQ|NE)store [off1+off2] {sym} base val mem)
-((ADD|SUB|AND|OR|XOR)Qload [off1] {sym} val (ADDQconst [off2] base) mem) && is32Bit(int64(off1)+int64(off2)) =>
-	((ADD|SUB|AND|OR|XOR)Qload [off1+off2] {sym} val base mem)
-((ADD|SUB|AND|OR|XOR)Lload [off1] {sym} val (ADDQconst [off2] base) mem) && is32Bit(int64(off1)+int64(off2)) =>
-	((ADD|SUB|AND|OR|XOR)Lload [off1+off2] {sym} val base mem)
-(CMP(Q|L|W|B)load [off1] {sym} (ADDQconst [off2] base) val mem) && is32Bit(int64(off1)+int64(off2)) =>
-	(CMP(Q|L|W|B)load [off1+off2] {sym} base val mem)
-(CMP(Q|L|W|B)constload [valoff1] {sym} (ADDQconst [off2] base) mem) && ValAndOff(valoff1).canAdd32(off2) =>
-	(CMP(Q|L|W|B)constload [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem)
-
-((ADD|SUB|MUL|DIV)SSload [off1] {sym} val (ADDQconst [off2] base) mem) && is32Bit(int64(off1)+int64(off2)) =>
-	((ADD|SUB|MUL|DIV)SSload [off1+off2] {sym} val base mem)
-((ADD|SUB|MUL|DIV)SDload [off1] {sym} val (ADDQconst [off2] base) mem) && is32Bit(int64(off1)+int64(off2)) =>
-	((ADD|SUB|MUL|DIV)SDload [off1+off2] {sym} val base mem)
-((ADD|AND|OR|XOR)Qconstmodify [valoff1] {sym} (ADDQconst [off2] base) mem) && ValAndOff(valoff1).canAdd32(off2) =>
-	((ADD|AND|OR|XOR)Qconstmodify [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem)
-((ADD|AND|OR|XOR)Lconstmodify [valoff1] {sym} (ADDQconst [off2] base) mem) && ValAndOff(valoff1).canAdd32(off2) =>
-	((ADD|AND|OR|XOR)Lconstmodify [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem)
-((ADD|SUB|AND|OR|XOR)Qmodify [off1] {sym} (ADDQconst [off2] base) val mem) && is32Bit(int64(off1)+int64(off2)) =>
-	((ADD|SUB|AND|OR|XOR)Qmodify [off1+off2] {sym} base val mem)
-((ADD|SUB|AND|OR|XOR)Lmodify [off1] {sym} (ADDQconst [off2] base) val mem) && is32Bit(int64(off1)+int64(off2)) =>
-	((ADD|SUB|AND|OR|XOR)Lmodify [off1+off2] {sym} base val mem)
-
-// Fold constants into stores.
-(MOVQstore [off] {sym} ptr (MOVQconst [c]) mem) && validVal(c) =>
-	(MOVQstoreconst [makeValAndOff(int32(c),off)] {sym} ptr mem)
-(MOVLstore [off] {sym} ptr (MOV(L|Q)const [c]) mem) =>
-	(MOVLstoreconst [makeValAndOff(int32(c),off)] {sym} ptr mem)
-(MOVWstore [off] {sym} ptr (MOV(L|Q)const [c]) mem) =>
-	(MOVWstoreconst [makeValAndOff(int32(int16(c)),off)] {sym} ptr mem)
-(MOVBstore [off] {sym} ptr (MOV(L|Q)const [c]) mem) =>
-	(MOVBstoreconst [makeValAndOff(int32(int8(c)),off)] {sym} ptr mem)
-
-// Fold address offsets into constant stores.
-(MOV(Q|L|W|B|O)storeconst [sc] {s} (ADDQconst [off] ptr) mem) && ValAndOff(sc).canAdd32(off) =>
-	(MOV(Q|L|W|B|O)storeconst [ValAndOff(sc).addOffset32(off)] {s} ptr mem)
-
-// We need to fold LEAQ into the MOVx ops so that the live variable analysis knows
-// what variables are being read/written by the ops.
-(MOV(Q|L|W|B|SS|SD|O|BQSX|WQSX|LQSX)load [off1] {sym1} (LEAQ [off2] {sym2} base) mem)
-	&& is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-	(MOV(Q|L|W|B|SS|SD|O|BQSX|WQSX|LQSX)load [off1+off2] {mergeSym(sym1,sym2)} base mem)
-(MOV(Q|L|W|B|SS|SD|O)store [off1] {sym1} (LEAQ [off2] {sym2} base) val mem)
-	&& is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-	(MOV(Q|L|W|B|SS|SD|O)store [off1+off2] {mergeSym(sym1,sym2)} base val mem)
-(MOV(Q|L|W|B|O)storeconst [sc] {sym1} (LEAQ [off] {sym2} ptr) mem) && canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd32(off) =>
-	(MOV(Q|L|W|B|O)storeconst [ValAndOff(sc).addOffset32(off)] {mergeSym(sym1, sym2)} ptr mem)
-(SET(L|G|B|A|LE|GE|BE|AE|EQ|NE)store [off1] {sym1} (LEAQ [off2] {sym2} base) val mem)
-	&& is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-	(SET(L|G|B|A|LE|GE|BE|AE|EQ|NE)store [off1+off2] {mergeSym(sym1,sym2)} base val mem)
-((ADD|SUB|AND|OR|XOR)Qload [off1] {sym1} val (LEAQ [off2] {sym2} base) mem)
-	&& is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-	((ADD|SUB|AND|OR|XOR)Qload [off1+off2] {mergeSym(sym1,sym2)} val base mem)
-((ADD|SUB|AND|OR|XOR)Lload [off1] {sym1} val (LEAQ [off2] {sym2} base) mem)
-	&& is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-	((ADD|SUB|AND|OR|XOR)Lload [off1+off2] {mergeSym(sym1,sym2)} val base mem)
-(CMP(Q|L|W|B)load [off1] {sym1} (LEAQ [off2] {sym2} base) val mem)
-	&& is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-	(CMP(Q|L|W|B)load [off1+off2] {mergeSym(sym1,sym2)} base val mem)
-(CMP(Q|L|W|B)constload [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem)
-	&& ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2) =>
-	(CMP(Q|L|W|B)constload [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem)
-
-((ADD|SUB|MUL|DIV)SSload [off1] {sym1} val (LEAQ [off2] {sym2} base) mem)
-	&& is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-	((ADD|SUB|MUL|DIV)SSload [off1+off2] {mergeSym(sym1,sym2)} val base mem)
-((ADD|SUB|MUL|DIV)SDload [off1] {sym1} val (LEAQ [off2] {sym2} base) mem)
-	&& is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-	((ADD|SUB|MUL|DIV)SDload [off1+off2] {mergeSym(sym1,sym2)} val base mem)
-((ADD|AND|OR|XOR)Qconstmodify [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem)
-	&& ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2) =>
-	((ADD|AND|OR|XOR)Qconstmodify [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem)
-((ADD|AND|OR|XOR)Lconstmodify [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem)
-	&& ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2) =>
-	((ADD|AND|OR|XOR)Lconstmodify [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem)
-((ADD|SUB|AND|OR|XOR)Qmodify [off1] {sym1} (LEAQ [off2] {sym2} base) val mem)
-	&& is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-	((ADD|SUB|AND|OR|XOR)Qmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem)
-((ADD|SUB|AND|OR|XOR)Lmodify [off1] {sym1} (LEAQ [off2] {sym2} base) val mem)
-	&& is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-	((ADD|SUB|AND|OR|XOR)Lmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem)
-
-// fold LEAQs together
-(LEAQ [off1] {sym1} (LEAQ [off2] {sym2} x)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-      (LEAQ [off1+off2] {mergeSym(sym1,sym2)} x)
-
-// LEAQ into LEAQ1
-(LEAQ1 [off1] {sym1} (LEAQ [off2] {sym2} x) y) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB =>
-       (LEAQ1 [off1+off2] {mergeSym(sym1,sym2)} x y)
-
-// LEAQ1 into LEAQ
-(LEAQ [off1] {sym1} (LEAQ1 [off2] {sym2} x y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-       (LEAQ1 [off1+off2] {mergeSym(sym1,sym2)} x y)
-
-// LEAQ into LEAQ[248]
-(LEAQ2 [off1] {sym1} (LEAQ [off2] {sym2} x) y) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB =>
-       (LEAQ2 [off1+off2] {mergeSym(sym1,sym2)} x y)
-(LEAQ4 [off1] {sym1} (LEAQ [off2] {sym2} x) y) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB =>
-       (LEAQ4 [off1+off2] {mergeSym(sym1,sym2)} x y)
-(LEAQ8 [off1] {sym1} (LEAQ [off2] {sym2} x) y) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB =>
-       (LEAQ8 [off1+off2] {mergeSym(sym1,sym2)} x y)
-
-// LEAQ[248] into LEAQ
-(LEAQ [off1] {sym1} (LEAQ2 [off2] {sym2} x y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-      (LEAQ2 [off1+off2] {mergeSym(sym1,sym2)} x y)
-(LEAQ [off1] {sym1} (LEAQ4 [off2] {sym2} x y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-      (LEAQ4 [off1+off2] {mergeSym(sym1,sym2)} x y)
-(LEAQ [off1] {sym1} (LEAQ8 [off2] {sym2} x y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-      (LEAQ8 [off1+off2] {mergeSym(sym1,sym2)} x y)
-
-// LEAQ[1248] into LEAQ[1248]. Only some such merges are possible.
-(LEAQ1 [off1] {sym1} x (LEAQ1 [off2] {sym2} y y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-      (LEAQ2 [off1+off2] {mergeSym(sym1, sym2)} x y)
-(LEAQ1 [off1] {sym1} x (LEAQ1 [off2] {sym2} x y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-      (LEAQ2 [off1+off2] {mergeSym(sym1, sym2)} y x)
-(LEAQ2 [off1] {sym1} x (LEAQ1 [off2] {sym2} y y)) && is32Bit(int64(off1)+2*int64(off2)) && sym2 == nil =>
-      (LEAQ4 [off1+2*off2] {sym1} x y)
-(LEAQ4 [off1] {sym1} x (LEAQ1 [off2] {sym2} y y)) && is32Bit(int64(off1)+4*int64(off2)) && sym2 == nil =>
-      (LEAQ8 [off1+4*off2] {sym1} x y)
-// TODO: more?
-
-// Lower LEAQ2/4/8 when the offset is a constant
-(LEAQ2 [off] {sym} x (MOV(Q|L)const [scale])) && is32Bit(int64(off)+int64(scale)*2) =>
-	(LEAQ [off+int32(scale)*2] {sym} x)
-(LEAQ4 [off] {sym} x (MOV(Q|L)const [scale])) && is32Bit(int64(off)+int64(scale)*4) =>
-	(LEAQ [off+int32(scale)*4] {sym} x)
-(LEAQ8 [off] {sym} x (MOV(Q|L)const [scale])) && is32Bit(int64(off)+int64(scale)*8) =>
-	(LEAQ [off+int32(scale)*8] {sym} x)
-
-// Absorb InvertFlags into branches.
-(LT (InvertFlags cmp) yes no) => (GT cmp yes no)
-(GT (InvertFlags cmp) yes no) => (LT cmp yes no)
-(LE (InvertFlags cmp) yes no) => (GE cmp yes no)
-(GE (InvertFlags cmp) yes no) => (LE cmp yes no)
-(ULT (InvertFlags cmp) yes no) => (UGT cmp yes no)
-(UGT (InvertFlags cmp) yes no) => (ULT cmp yes no)
-(ULE (InvertFlags cmp) yes no) => (UGE cmp yes no)
-(UGE (InvertFlags cmp) yes no) => (ULE cmp yes no)
-(EQ (InvertFlags cmp) yes no) => (EQ cmp yes no)
-(NE (InvertFlags cmp) yes no) => (NE cmp yes no)
-
-// Constant comparisons.
-(CMPQconst (MOVQconst [x]) [y]) && x==int64(y) => (FlagEQ)
-(CMPQconst (MOVQconst [x]) [y]) && x<int64(y) && uint64(x)<uint64(int64(y)) => (FlagLT_ULT)
-(CMPQconst (MOVQconst [x]) [y]) && x<int64(y) && uint64(x)>uint64(int64(y)) => (FlagLT_UGT)
-(CMPQconst (MOVQconst [x]) [y]) && x>int64(y) && uint64(x)<uint64(int64(y)) => (FlagGT_ULT)
-(CMPQconst (MOVQconst [x]) [y]) && x>int64(y) && uint64(x)>uint64(int64(y)) => (FlagGT_UGT)
-(CMPLconst (MOVLconst [x]) [y]) && x==y => (FlagEQ)
-(CMPLconst (MOVLconst [x]) [y]) && x<y && uint32(x)<uint32(y) => (FlagLT_ULT)
-(CMPLconst (MOVLconst [x]) [y]) && x<y && uint32(x)>uint32(y) => (FlagLT_UGT)
-(CMPLconst (MOVLconst [x]) [y]) && x>y && uint32(x)<uint32(y) => (FlagGT_ULT)
-(CMPLconst (MOVLconst [x]) [y]) && x>y && uint32(x)>uint32(y) => (FlagGT_UGT)
-(CMPWconst (MOVLconst [x]) [y]) && int16(x)==y => (FlagEQ)
-(CMPWconst (MOVLconst [x]) [y]) && int16(x)<y && uint16(x)<uint16(y) => (FlagLT_ULT)
-(CMPWconst (MOVLconst [x]) [y]) && int16(x)<y && uint16(x)>uint16(y) => (FlagLT_UGT)
-(CMPWconst (MOVLconst [x]) [y]) && int16(x)>y && uint16(x)<uint16(y) => (FlagGT_ULT)
-(CMPWconst (MOVLconst [x]) [y]) && int16(x)>y && uint16(x)>uint16(y) => (FlagGT_UGT)
-(CMPBconst (MOVLconst [x]) [y]) && int8(x)==y => (FlagEQ)
-(CMPBconst (MOVLconst [x]) [y]) && int8(x)<y && uint8(x)<uint8(y) => (FlagLT_ULT)
-(CMPBconst (MOVLconst [x]) [y]) && int8(x)<y && uint8(x)>uint8(y) => (FlagLT_UGT)
-(CMPBconst (MOVLconst [x]) [y]) && int8(x)>y && uint8(x)<uint8(y) => (FlagGT_ULT)
-(CMPBconst (MOVLconst [x]) [y]) && int8(x)>y && uint8(x)>uint8(y) => (FlagGT_UGT)
-
-// CMPQconst requires a 32 bit const, but we can still constant-fold 64 bit consts.
-// In theory this applies to any of the simplifications above,
-// but CMPQ is the only one I've actually seen occur.
-(CMPQ (MOVQconst [x]) (MOVQconst [y])) && x==y => (FlagEQ)
-(CMPQ (MOVQconst [x]) (MOVQconst [y])) && x<y && uint64(x)<uint64(y) => (FlagLT_ULT)
-(CMPQ (MOVQconst [x]) (MOVQconst [y])) && x<y && uint64(x)>uint64(y) => (FlagLT_UGT)
-(CMPQ (MOVQconst [x]) (MOVQconst [y])) && x>y && uint64(x)<uint64(y) => (FlagGT_ULT)
-(CMPQ (MOVQconst [x]) (MOVQconst [y])) && x>y && uint64(x)>uint64(y) => (FlagGT_UGT)
-
-// Other known comparisons.
-(CMPQconst (MOVBQZX _) [c]) && 0xFF < c => (FlagLT_ULT)
-(CMPQconst (MOVWQZX _) [c]) && 0xFFFF < c => (FlagLT_ULT)
-(CMPLconst (SHRLconst _ [c]) [n]) && 0 <= n && 0 < c && c <= 32 && (1<<uint64(32-c)) <= uint64(n) => (FlagLT_ULT)
-(CMPQconst (SHRQconst _ [c]) [n]) && 0 <= n && 0 < c && c <= 64 && (1<<uint64(64-c)) <= uint64(n) => (FlagLT_ULT)
-(CMPQconst (ANDQconst _ [m]) [n]) && 0 <= m && m < n => (FlagLT_ULT)
-(CMPQconst (ANDLconst _ [m]) [n]) && 0 <= m && m < n => (FlagLT_ULT)
-(CMPLconst (ANDLconst _ [m]) [n]) && 0 <= m && m < n => (FlagLT_ULT)
-(CMPWconst (ANDLconst _ [m]) [n]) && 0 <= int16(m) && int16(m) < n => (FlagLT_ULT)
-(CMPBconst (ANDLconst _ [m]) [n]) && 0 <= int8(m)  && int8(m)  < n => (FlagLT_ULT)
-
-// TESTQ c c sets flags like CMPQ c 0.
-(TESTQconst [c] (MOVQconst [d])) && int64(c) == d && c == 0 => (FlagEQ)
-(TESTLconst [c] (MOVLconst [c])) && c == 0 => (FlagEQ)
-(TESTQconst [c] (MOVQconst [d])) && int64(c) == d && c < 0  => (FlagLT_UGT)
-(TESTLconst [c] (MOVLconst [c])) && c < 0  => (FlagLT_UGT)
-(TESTQconst [c] (MOVQconst [d])) && int64(c) == d && c > 0  => (FlagGT_UGT)
-(TESTLconst [c] (MOVLconst [c])) && c > 0  => (FlagGT_UGT)
-
-// TODO: DIVxU also.
-
-// Absorb flag constants into SBB ops.
-(SBBQcarrymask (FlagEQ))     => (MOVQconst [0])
-(SBBQcarrymask (FlagLT_ULT)) => (MOVQconst [-1])
-(SBBQcarrymask (FlagLT_UGT)) => (MOVQconst [0])
-(SBBQcarrymask (FlagGT_ULT)) => (MOVQconst [-1])
-(SBBQcarrymask (FlagGT_UGT)) => (MOVQconst [0])
-(SBBLcarrymask (FlagEQ))     => (MOVLconst [0])
-(SBBLcarrymask (FlagLT_ULT)) => (MOVLconst [-1])
-(SBBLcarrymask (FlagLT_UGT)) => (MOVLconst [0])
-(SBBLcarrymask (FlagGT_ULT)) => (MOVLconst [-1])
-(SBBLcarrymask (FlagGT_UGT)) => (MOVLconst [0])
-
-// Absorb flag constants into branches.
-((EQ|LE|GE|ULE|UGE) (FlagEQ) yes no)     => (First yes no)
-((NE|LT|GT|ULT|UGT) (FlagEQ) yes no)     => (First no yes)
-((NE|LT|LE|ULT|ULE) (FlagLT_ULT) yes no) => (First yes no)
-((EQ|GT|GE|UGT|UGE) (FlagLT_ULT) yes no) => (First no yes)
-((NE|LT|LE|UGT|UGE) (FlagLT_UGT) yes no) => (First yes no)
-((EQ|GT|GE|ULT|ULE) (FlagLT_UGT) yes no) => (First no yes)
-((NE|GT|GE|ULT|ULE) (FlagGT_ULT) yes no) => (First yes no)
-((EQ|LT|LE|UGT|UGE) (FlagGT_ULT) yes no) => (First no yes)
-((NE|GT|GE|UGT|UGE) (FlagGT_UGT) yes no) => (First yes no)
-((EQ|LT|LE|ULT|ULE) (FlagGT_UGT) yes no) => (First no yes)
-
-// Absorb flag constants into SETxx ops.
-((SETEQ|SETLE|SETGE|SETBE|SETAE) (FlagEQ))     => (MOVLconst [1])
-((SETNE|SETL|SETG|SETB|SETA)     (FlagEQ))     => (MOVLconst [0])
-((SETNE|SETL|SETLE|SETB|SETBE)   (FlagLT_ULT)) => (MOVLconst [1])
-((SETEQ|SETG|SETGE|SETA|SETAE)   (FlagLT_ULT)) => (MOVLconst [0])
-((SETNE|SETL|SETLE|SETA|SETAE)   (FlagLT_UGT)) => (MOVLconst [1])
-((SETEQ|SETG|SETGE|SETB|SETBE)   (FlagLT_UGT)) => (MOVLconst [0])
-((SETNE|SETG|SETGE|SETB|SETBE)   (FlagGT_ULT)) => (MOVLconst [1])
-((SETEQ|SETL|SETLE|SETA|SETAE)   (FlagGT_ULT)) => (MOVLconst [0])
-((SETNE|SETG|SETGE|SETA|SETAE)   (FlagGT_UGT)) => (MOVLconst [1])
-((SETEQ|SETL|SETLE|SETB|SETBE)   (FlagGT_UGT)) => (MOVLconst [0])
-
-(SETEQstore [off] {sym} ptr (FlagEQ)     mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
-(SETEQstore [off] {sym} ptr (FlagLT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
-(SETEQstore [off] {sym} ptr (FlagLT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
-(SETEQstore [off] {sym} ptr (FlagGT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
-(SETEQstore [off] {sym} ptr (FlagGT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
-
-(SETNEstore [off] {sym} ptr (FlagEQ)     mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
-(SETNEstore [off] {sym} ptr (FlagLT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
-(SETNEstore [off] {sym} ptr (FlagLT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
-(SETNEstore [off] {sym} ptr (FlagGT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
-(SETNEstore [off] {sym} ptr (FlagGT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
-
-(SETLstore  [off] {sym} ptr (FlagEQ)     mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
-(SETLstore  [off] {sym} ptr (FlagLT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
-(SETLstore  [off] {sym} ptr (FlagLT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
-(SETLstore  [off] {sym} ptr (FlagGT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
-(SETLstore  [off] {sym} ptr (FlagGT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
-
-(SETLEstore [off] {sym} ptr (FlagEQ)     mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
-(SETLEstore [off] {sym} ptr (FlagLT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
-(SETLEstore [off] {sym} ptr (FlagLT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
-(SETLEstore [off] {sym} ptr (FlagGT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
-(SETLEstore [off] {sym} ptr (FlagGT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
-
-(SETGstore  [off] {sym} ptr (FlagEQ)     mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
-(SETGstore  [off] {sym} ptr (FlagLT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
-(SETGstore  [off] {sym} ptr (FlagLT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
-(SETGstore  [off] {sym} ptr (FlagGT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
-(SETGstore  [off] {sym} ptr (FlagGT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
-
-(SETGEstore [off] {sym} ptr (FlagEQ)     mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
-(SETGEstore [off] {sym} ptr (FlagLT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
-(SETGEstore [off] {sym} ptr (FlagLT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
-(SETGEstore [off] {sym} ptr (FlagGT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
-(SETGEstore [off] {sym} ptr (FlagGT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
-
-(SETBstore  [off] {sym} ptr (FlagEQ)     mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
-(SETBstore  [off] {sym} ptr (FlagLT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
-(SETBstore  [off] {sym} ptr (FlagLT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
-(SETBstore  [off] {sym} ptr (FlagGT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
-(SETBstore  [off] {sym} ptr (FlagGT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
-
-(SETBEstore [off] {sym} ptr (FlagEQ)     mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
-(SETBEstore [off] {sym} ptr (FlagLT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
-(SETBEstore [off] {sym} ptr (FlagLT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
-(SETBEstore [off] {sym} ptr (FlagGT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
-(SETBEstore [off] {sym} ptr (FlagGT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
-
-(SETAstore  [off] {sym} ptr (FlagEQ)     mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
-(SETAstore  [off] {sym} ptr (FlagLT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
-(SETAstore  [off] {sym} ptr (FlagLT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
-(SETAstore  [off] {sym} ptr (FlagGT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
-(SETAstore  [off] {sym} ptr (FlagGT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
-
-(SETAEstore [off] {sym} ptr (FlagEQ)     mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
-(SETAEstore [off] {sym} ptr (FlagLT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
-(SETAEstore [off] {sym} ptr (FlagLT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
-(SETAEstore [off] {sym} ptr (FlagGT_ULT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [0]) mem)
-(SETAEstore [off] {sym} ptr (FlagGT_UGT) mem) => (MOVBstore [off] {sym} ptr (MOVLconst <typ.UInt8> [1]) mem)
-
-// Remove redundant *const ops
-(ADDQconst [0] x)          => x
-(ADDLconst [c] x) && c==0  => x
-(SUBQconst [0] x)          => x
-(SUBLconst [c] x) && c==0  => x
-(ANDQconst [0] _)          => (MOVQconst [0])
-(ANDLconst [c] _) && c==0  => (MOVLconst [0])
-(ANDQconst [-1] x)         => x
-(ANDLconst [c] x) && c==-1 => x
-(ORQconst [0] x)           => x
-(ORLconst [c] x)  && c==0  => x
-(ORQconst [-1] _)          => (MOVQconst [-1])
-(ORLconst [c] _)  && c==-1 => (MOVLconst [-1])
-(XORQconst [0] x)          => x
-(XORLconst [c] x) && c==0  => x
-// TODO: since we got rid of the W/B versions, we might miss
-// things like (ANDLconst [0x100] x) which were formerly
-// (ANDBconst [0] x).  Probably doesn't happen very often.
-// If we cared, we might do:
-//  (ANDLconst <t> [c] x) && t.Size()==1 && int8(x)==0 -> (MOVLconst [0])
-
-// Remove redundant ops
-// Not in generic rules, because they may appear after lowering e. g. Slicemask
-(NEG(Q|L) (NEG(Q|L) x)) => x
-(NEG(Q|L) s:(SUB(Q|L) x y)) && s.Uses == 1 => (SUB(Q|L) y x)
-
-// Convert constant subtracts to constant adds
-(SUBQconst [c] x) && c != -(1<<31) => (ADDQconst [-c] x)
-(SUBLconst [c] x) => (ADDLconst [-c] x)
-
-// generic constant folding
-// TODO: more of this
-(ADDQconst [c] (MOVQconst [d])) => (MOVQconst [int64(c)+d])
-(ADDLconst [c] (MOVLconst [d])) => (MOVLconst [c+d])
-(ADDQconst [c] (ADDQconst [d] x)) && is32Bit(int64(c)+int64(d)) => (ADDQconst [c+d] x)
-(ADDLconst [c] (ADDLconst [d] x)) => (ADDLconst [c+d] x)
-(SUBQconst (MOVQconst [d]) [c]) => (MOVQconst [d-int64(c)])
-(SUBQconst (SUBQconst x [d]) [c]) && is32Bit(int64(-c)-int64(d)) => (ADDQconst [-c-d] x)
-(SARQconst [c] (MOVQconst [d])) => (MOVQconst [d>>uint64(c)])
-(SARLconst [c] (MOVQconst [d])) => (MOVQconst [int64(int32(d))>>uint64(c)])
-(SARWconst [c] (MOVQconst [d])) => (MOVQconst [int64(int16(d))>>uint64(c)])
-(SARBconst [c] (MOVQconst [d])) => (MOVQconst [int64(int8(d))>>uint64(c)])
-(NEGQ (MOVQconst [c])) => (MOVQconst [-c])
-(NEGL (MOVLconst [c])) => (MOVLconst [-c])
-(MULQconst [c] (MOVQconst [d])) => (MOVQconst [int64(c)*d])
-(MULLconst [c] (MOVLconst [d])) => (MOVLconst [c*d])
-(ANDQconst [c] (MOVQconst [d])) => (MOVQconst [int64(c)&d])
-(ANDLconst [c] (MOVLconst [d])) => (MOVLconst [c&d])
-(ORQconst [c] (MOVQconst [d])) => (MOVQconst [int64(c)|d])
-(ORLconst [c] (MOVLconst [d])) => (MOVLconst [c|d])
-(XORQconst [c] (MOVQconst [d])) => (MOVQconst [int64(c)^d])
-(XORLconst [c] (MOVLconst [d])) => (MOVLconst [c^d])
-(NOTQ (MOVQconst [c])) => (MOVQconst [^c])
-(NOTL (MOVLconst [c])) => (MOVLconst [^c])
-(BTSQconst [c] (MOVQconst [d])) => (MOVQconst [d|(1<<uint32(c))])
-(BTSLconst [c] (MOVLconst [d])) => (MOVLconst [d|(1<<uint32(c))])
-(BTRQconst [c] (MOVQconst [d])) => (MOVQconst [d&^(1<<uint32(c))])
-(BTRLconst [c] (MOVLconst [d])) => (MOVLconst [d&^(1<<uint32(c))])
-(BTCQconst [c] (MOVQconst [d])) => (MOVQconst [d^(1<<uint32(c))])
-(BTCLconst [c] (MOVLconst [d])) => (MOVLconst [d^(1<<uint32(c))])
-
-// If c or d doesn't fit into 32 bits, then we can't construct ORQconst,
-// but we can still constant-fold.
-// In theory this applies to any of the simplifications above,
-// but ORQ is the only one I've actually seen occur.
-(ORQ (MOVQconst [c]) (MOVQconst [d])) => (MOVQconst [c|d])
-
-// generic simplifications
-// TODO: more of this
-(ADDQ x (NEGQ y)) => (SUBQ x y)
-(ADDL x (NEGL y)) => (SUBL x y)
-(SUBQ x x) => (MOVQconst [0])
-(SUBL x x) => (MOVLconst [0])
-(ANDQ x x) => x
-(ANDL x x) => x
-(ORQ x x)  => x
-(ORL x x)  => x
-(XORQ x x) => (MOVQconst [0])
-(XORL x x) => (MOVLconst [0])
-
-(SHLLconst [d] (MOVLconst [c])) => (MOVLconst [c << uint64(d)])
-(SHLQconst [d] (MOVQconst [c])) => (MOVQconst [c << uint64(d)])
-(SHLQconst [d] (MOVLconst [c])) => (MOVQconst [int64(c) << uint64(d)])
-
-// Fold NEG into ADDconst/MULconst. Take care to keep c in 32 bit range.
-(NEGQ (ADDQconst [c] (NEGQ x))) && c != -(1<<31) => (ADDQconst [-c] x)
-(MULQconst [c] (NEGQ x)) && c != -(1<<31) => (MULQconst [-c] x)
-
-// checking AND against 0.
-(CMPQconst a:(ANDQ x y) [0]) && a.Uses == 1 => (TESTQ x y)
-(CMPLconst a:(ANDL x y) [0]) && a.Uses == 1 => (TESTL x y)
-(CMPWconst a:(ANDL x y) [0]) && a.Uses == 1 => (TESTW x y)
-(CMPBconst a:(ANDL x y) [0]) && a.Uses == 1 => (TESTB x y)
-(CMPQconst a:(ANDQconst [c] x) [0]) && a.Uses == 1 => (TESTQconst [c] x)
-(CMPLconst a:(ANDLconst [c] x) [0]) && a.Uses == 1 => (TESTLconst [c] x)
-(CMPWconst a:(ANDLconst [c] x) [0]) && a.Uses == 1 => (TESTWconst [int16(c)] x)
-(CMPBconst a:(ANDLconst [c] x) [0]) && a.Uses == 1 => (TESTBconst [int8(c)] x)
-
-// Convert TESTx to TESTxconst if possible.
-(TESTQ (MOVQconst [c]) x) && is32Bit(c) => (TESTQconst [int32(c)] x)
-(TESTL (MOVLconst [c]) x) => (TESTLconst [c] x)
-(TESTW (MOVLconst [c]) x) => (TESTWconst [int16(c)] x)
-(TESTB (MOVLconst [c]) x) => (TESTBconst [int8(c)] x)
-
-// TEST %reg,%reg is shorter than CMP
-(CMPQconst x [0]) => (TESTQ x x)
-(CMPLconst x [0]) => (TESTL x x)
-(CMPWconst x [0]) => (TESTW x x)
-(CMPBconst x [0]) => (TESTB x x)
-(TESTQconst [-1] x) && x.Op != OpAMD64MOVQconst => (TESTQ x x)
-(TESTLconst [-1] x) && x.Op != OpAMD64MOVLconst => (TESTL x x)
-(TESTWconst [-1] x) && x.Op != OpAMD64MOVLconst => (TESTW x x)
-(TESTBconst [-1] x) && x.Op != OpAMD64MOVLconst => (TESTB x x)
-
-// Convert LEAQ1 back to ADDQ if we can
-(LEAQ1 [0] x y) && v.Aux == nil => (ADDQ x y)
-
-// Combining byte loads into larger (unaligned) loads.
-// There are many ways these combinations could occur.  This is
-// designed to match the way encoding/binary.LittleEndian does it.
-
-// Little-endian loads
-
-(OR(L|Q)                  x0:(MOVBload [i0] {s} p mem)
-    sh:(SHL(L|Q)const [8] x1:(MOVBload [i1] {s} p mem)))
-  && i1 == i0+1
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && sh.Uses == 1
-  && mergePoint(b,x0,x1) != nil
-  && clobber(x0, x1, sh)
-  => @mergePoint(b,x0,x1) (MOVWload [i0] {s} p mem)
-
-(OR(L|Q)                  x0:(MOVBload [i] {s} p0 mem)
-    sh:(SHL(L|Q)const [8] x1:(MOVBload [i] {s} p1 mem)))
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && sh.Uses == 1
-  && sequentialAddresses(p0, p1, 1)
-  && mergePoint(b,x0,x1) != nil
-  && clobber(x0, x1, sh)
-  => @mergePoint(b,x0,x1) (MOVWload [i] {s} p0 mem)
-
-(OR(L|Q)                   x0:(MOVWload [i0] {s} p mem)
-    sh:(SHL(L|Q)const [16] x1:(MOVWload [i1] {s} p mem)))
-  && i1 == i0+2
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && sh.Uses == 1
-  && mergePoint(b,x0,x1) != nil
-  && clobber(x0, x1, sh)
-  => @mergePoint(b,x0,x1) (MOVLload [i0] {s} p mem)
-
-(OR(L|Q)                   x0:(MOVWload [i] {s} p0 mem)
-    sh:(SHL(L|Q)const [16] x1:(MOVWload [i] {s} p1 mem)))
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && sh.Uses == 1
-  && sequentialAddresses(p0, p1, 2)
-  && mergePoint(b,x0,x1) != nil
-  && clobber(x0, x1, sh)
-  => @mergePoint(b,x0,x1) (MOVLload [i] {s} p0 mem)
-
-(ORQ                   x0:(MOVLload [i0] {s} p mem)
-    sh:(SHLQconst [32] x1:(MOVLload [i1] {s} p mem)))
-  && i1 == i0+4
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && sh.Uses == 1
-  && mergePoint(b,x0,x1) != nil
-  && clobber(x0, x1, sh)
-  => @mergePoint(b,x0,x1) (MOVQload [i0] {s} p mem)
-
-(ORQ                   x0:(MOVLload [i] {s} p0 mem)
-    sh:(SHLQconst [32] x1:(MOVLload [i] {s} p1 mem)))
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && sh.Uses == 1
-  && sequentialAddresses(p0, p1, 4)
-  && mergePoint(b,x0,x1) != nil
-  && clobber(x0, x1, sh)
-  => @mergePoint(b,x0,x1) (MOVQload [i] {s} p0 mem)
-
-(OR(L|Q)
-    s1:(SHL(L|Q)const [j1] x1:(MOVBload [i1] {s} p mem))
-    or:(OR(L|Q)
-        s0:(SHL(L|Q)const [j0] x0:(MOVBload [i0] {s} p mem))
-	y))
-  && i1 == i0+1
-  && j1 == j0+8
-  && j0 % 16 == 0
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && s0.Uses == 1
-  && s1.Uses == 1
-  && or.Uses == 1
-  && mergePoint(b,x0,x1,y) != nil
-  && clobber(x0, x1, s0, s1, or)
-  => @mergePoint(b,x0,x1,y) (OR(L|Q) <v.Type> (SHL(L|Q)const <v.Type> [j0] (MOVWload [i0] {s} p mem)) y)
-
-(OR(L|Q)
-    s1:(SHL(L|Q)const [j1] x1:(MOVBload [i] {s} p1 mem))
-    or:(OR(L|Q)
-        s0:(SHL(L|Q)const [j0] x0:(MOVBload [i] {s} p0 mem))
-	y))
-  && j1 == j0+8
-  && j0 % 16 == 0
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && s0.Uses == 1
-  && s1.Uses == 1
-  && or.Uses == 1
-  && sequentialAddresses(p0, p1, 1)
-  && mergePoint(b,x0,x1,y) != nil
-  && clobber(x0, x1, s0, s1, or)
-  => @mergePoint(b,x0,x1,y) (OR(L|Q) <v.Type> (SHL(L|Q)const <v.Type> [j0] (MOVWload [i] {s} p0 mem)) y)
-
-(ORQ
-    s1:(SHLQconst [j1] x1:(MOVWload [i1] {s} p mem))
-    or:(ORQ
-        s0:(SHLQconst [j0] x0:(MOVWload [i0] {s} p mem))
-	y))
-  && i1 == i0+2
-  && j1 == j0+16
-  && j0 % 32 == 0
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && s0.Uses == 1
-  && s1.Uses == 1
-  && or.Uses == 1
-  && mergePoint(b,x0,x1,y) != nil
-  && clobber(x0, x1, s0, s1, or)
-  => @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j0] (MOVLload [i0] {s} p mem)) y)
-
-(ORQ
-    s1:(SHLQconst [j1] x1:(MOVWload [i] {s} p1 mem))
-    or:(ORQ
-        s0:(SHLQconst [j0] x0:(MOVWload [i] {s} p0 mem))
-	y))
-  && j1 == j0+16
-  && j0 % 32 == 0
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && s0.Uses == 1
-  && s1.Uses == 1
-  && or.Uses == 1
-  && sequentialAddresses(p0, p1, 2)
-  && mergePoint(b,x0,x1,y) != nil
-  && clobber(x0, x1, s0, s1, or)
-  => @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j0] (MOVLload [i] {s} p0 mem)) y)
-
-// Big-endian loads
-
-(OR(L|Q)
-                           x1:(MOVBload [i1] {s} p mem)
-    sh:(SHL(L|Q)const [8]  x0:(MOVBload [i0] {s} p mem)))
-  && i1 == i0+1
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && sh.Uses == 1
-  && mergePoint(b,x0,x1) != nil
-  && clobber(x0, x1, sh)
-  => @mergePoint(b,x0,x1) (ROLWconst <v.Type> [8] (MOVWload [i0] {s} p mem))
-
-(OR(L|Q)
-                           x1:(MOVBload [i] {s} p1 mem)
-    sh:(SHL(L|Q)const [8]  x0:(MOVBload [i] {s} p0 mem)))
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && sh.Uses == 1
-  && sequentialAddresses(p0, p1, 1)
-  && mergePoint(b,x0,x1) != nil
-  && clobber(x0, x1, sh)
-  => @mergePoint(b,x0,x1) (ROLWconst <v.Type> [8] (MOVWload [i] {s} p0 mem))
-
-(OR(L|Q)
-                            r1:(ROLWconst [8] x1:(MOVWload [i1] {s} p mem))
-    sh:(SHL(L|Q)const [16]  r0:(ROLWconst [8] x0:(MOVWload [i0] {s} p mem))))
-  && i1 == i0+2
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && r0.Uses == 1
-  && r1.Uses == 1
-  && sh.Uses == 1
-  && mergePoint(b,x0,x1) != nil
-  && clobber(x0, x1, r0, r1, sh)
-  => @mergePoint(b,x0,x1) (BSWAPL <v.Type> (MOVLload [i0] {s} p mem))
-
-(OR(L|Q)
-                            r1:(ROLWconst [8] x1:(MOVWload [i] {s} p1 mem))
-    sh:(SHL(L|Q)const [16]  r0:(ROLWconst [8] x0:(MOVWload [i] {s} p0 mem))))
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && r0.Uses == 1
-  && r1.Uses == 1
-  && sh.Uses == 1
-  && sequentialAddresses(p0, p1, 2)
-  && mergePoint(b,x0,x1) != nil
-  && clobber(x0, x1, r0, r1, sh)
-  => @mergePoint(b,x0,x1) (BSWAPL <v.Type> (MOVLload [i] {s} p0 mem))
-
-(ORQ
-                        r1:(BSWAPL x1:(MOVLload [i1] {s} p mem))
-    sh:(SHLQconst [32]  r0:(BSWAPL x0:(MOVLload [i0] {s} p mem))))
-  && i1 == i0+4
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && r0.Uses == 1
-  && r1.Uses == 1
-  && sh.Uses == 1
-  && mergePoint(b,x0,x1) != nil
-  && clobber(x0, x1, r0, r1, sh)
-  => @mergePoint(b,x0,x1) (BSWAPQ <v.Type> (MOVQload [i0] {s} p mem))
-
-(ORQ
-                        r1:(BSWAPL x1:(MOVLload [i] {s} p1 mem))
-    sh:(SHLQconst [32]  r0:(BSWAPL x0:(MOVLload [i] {s} p0 mem))))
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && r0.Uses == 1
-  && r1.Uses == 1
-  && sh.Uses == 1
-  && sequentialAddresses(p0, p1, 4)
-  && mergePoint(b,x0,x1) != nil
-  && clobber(x0, x1, r0, r1, sh)
-  => @mergePoint(b,x0,x1) (BSWAPQ <v.Type> (MOVQload [i] {s} p0 mem))
-
-(OR(L|Q)
-    s0:(SHL(L|Q)const [j0] x0:(MOVBload [i0] {s} p mem))
-    or:(OR(L|Q)
-        s1:(SHL(L|Q)const [j1] x1:(MOVBload [i1] {s} p mem))
-	y))
-  && i1 == i0+1
-  && j1 == j0-8
-  && j1 % 16 == 0
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && s0.Uses == 1
-  && s1.Uses == 1
-  && or.Uses == 1
-  && mergePoint(b,x0,x1,y) != nil
-  && clobber(x0, x1, s0, s1, or)
-  => @mergePoint(b,x0,x1,y) (OR(L|Q) <v.Type> (SHL(L|Q)const <v.Type> [j1] (ROLWconst <typ.UInt16> [8] (MOVWload [i0] {s} p mem))) y)
-
-(OR(L|Q)
-    s0:(SHL(L|Q)const [j0] x0:(MOVBload [i] {s} p0 mem))
-    or:(OR(L|Q)
-        s1:(SHL(L|Q)const [j1] x1:(MOVBload [i] {s} p1 mem))
-	y))
-  && j1 == j0-8
-  && j1 % 16 == 0
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && s0.Uses == 1
-  && s1.Uses == 1
-  && or.Uses == 1
-  && sequentialAddresses(p0, p1, 1)
-  && mergePoint(b,x0,x1,y) != nil
-  && clobber(x0, x1, s0, s1, or)
-  => @mergePoint(b,x0,x1,y) (OR(L|Q) <v.Type> (SHL(L|Q)const <v.Type> [j1] (ROLWconst <typ.UInt16> [8] (MOVWload [i] {s} p0 mem))) y)
-
-(ORQ
-    s0:(SHLQconst [j0] r0:(ROLWconst [8] x0:(MOVWload [i0] {s} p mem)))
-    or:(ORQ
-        s1:(SHLQconst [j1] r1:(ROLWconst [8] x1:(MOVWload [i1] {s} p mem)))
-	y))
-  && i1 == i0+2
-  && j1 == j0-16
-  && j1 % 32 == 0
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && r0.Uses == 1
-  && r1.Uses == 1
-  && s0.Uses == 1
-  && s1.Uses == 1
-  && or.Uses == 1
-  && mergePoint(b,x0,x1,y) != nil
-  && clobber(x0, x1, r0, r1, s0, s1, or)
-  => @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j1] (BSWAPL <typ.UInt32> (MOVLload [i0] {s} p mem))) y)
-
-(ORQ
-    s0:(SHLQconst [j0] r0:(ROLWconst [8] x0:(MOVWload [i] {s} p0 mem)))
-    or:(ORQ
-        s1:(SHLQconst [j1] r1:(ROLWconst [8] x1:(MOVWload [i] {s} p1 mem)))
-	y))
-  && j1 == j0-16
-  && j1 % 32 == 0
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && r0.Uses == 1
-  && r1.Uses == 1
-  && s0.Uses == 1
-  && s1.Uses == 1
-  && or.Uses == 1
-  && sequentialAddresses(p0, p1, 2)
-  && mergePoint(b,x0,x1,y) != nil
-  && clobber(x0, x1, r0, r1, s0, s1, or)
-  => @mergePoint(b,x0,x1,y) (ORQ <v.Type> (SHLQconst <v.Type> [j1] (BSWAPL <typ.UInt32> (MOVLload [i] {s} p0 mem))) y)
-
-// Combine 2 byte stores + shift into rolw 8 + word store
-(MOVBstore [i] {s} p w
-  x0:(MOVBstore [i-1] {s} p (SHRWconst [8] w) mem))
-  && x0.Uses == 1
-  && clobber(x0)
-  => (MOVWstore [i-1] {s} p (ROLWconst <w.Type> [8] w) mem)
-(MOVBstore [i] {s} p1 w
-  x0:(MOVBstore [i] {s} p0 (SHRWconst [8] w) mem))
-  && x0.Uses == 1
-  && sequentialAddresses(p0, p1, 1)
-  && clobber(x0)
-  => (MOVWstore [i] {s} p0 (ROLWconst <w.Type> [8] w) mem)
-
-// Combine stores + shifts into bswap and larger (unaligned) stores
-(MOVBstore [i] {s} p w
-  x2:(MOVBstore [i-1] {s} p (SHRLconst [8] w)
-  x1:(MOVBstore [i-2] {s} p (SHRLconst [16] w)
-  x0:(MOVBstore [i-3] {s} p (SHRLconst [24] w) mem))))
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && x2.Uses == 1
-  && clobber(x0, x1, x2)
-  => (MOVLstore [i-3] {s} p (BSWAPL <w.Type> w) mem)
-(MOVBstore [i] {s} p3 w
-  x2:(MOVBstore [i] {s} p2 (SHRLconst [8] w)
-  x1:(MOVBstore [i] {s} p1 (SHRLconst [16] w)
-  x0:(MOVBstore [i] {s} p0 (SHRLconst [24] w) mem))))
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && x2.Uses == 1
-  && sequentialAddresses(p0, p1, 1)
-  && sequentialAddresses(p1, p2, 1)
-  && sequentialAddresses(p2, p3, 1)
-  && clobber(x0, x1, x2)
-  => (MOVLstore [i] {s} p0 (BSWAPL <w.Type> w) mem)
-
-(MOVBstore [i] {s} p w
-  x6:(MOVBstore [i-1] {s} p (SHRQconst [8] w)
-  x5:(MOVBstore [i-2] {s} p (SHRQconst [16] w)
-  x4:(MOVBstore [i-3] {s} p (SHRQconst [24] w)
-  x3:(MOVBstore [i-4] {s} p (SHRQconst [32] w)
-  x2:(MOVBstore [i-5] {s} p (SHRQconst [40] w)
-  x1:(MOVBstore [i-6] {s} p (SHRQconst [48] w)
-  x0:(MOVBstore [i-7] {s} p (SHRQconst [56] w) mem))))))))
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && x2.Uses == 1
-  && x3.Uses == 1
-  && x4.Uses == 1
-  && x5.Uses == 1
-  && x6.Uses == 1
-  && clobber(x0, x1, x2, x3, x4, x5, x6)
-  => (MOVQstore [i-7] {s} p (BSWAPQ <w.Type> w) mem)
-(MOVBstore [i] {s} p7 w
-  x6:(MOVBstore [i] {s} p6 (SHRQconst [8] w)
-  x5:(MOVBstore [i] {s} p5 (SHRQconst [16] w)
-  x4:(MOVBstore [i] {s} p4 (SHRQconst [24] w)
-  x3:(MOVBstore [i] {s} p3 (SHRQconst [32] w)
-  x2:(MOVBstore [i] {s} p2 (SHRQconst [40] w)
-  x1:(MOVBstore [i] {s} p1 (SHRQconst [48] w)
-  x0:(MOVBstore [i] {s} p0 (SHRQconst [56] w) mem))))))))
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && x2.Uses == 1
-  && x3.Uses == 1
-  && x4.Uses == 1
-  && x5.Uses == 1
-  && x6.Uses == 1
-  && sequentialAddresses(p0, p1, 1)
-  && sequentialAddresses(p1, p2, 1)
-  && sequentialAddresses(p2, p3, 1)
-  && sequentialAddresses(p3, p4, 1)
-  && sequentialAddresses(p4, p5, 1)
-  && sequentialAddresses(p5, p6, 1)
-  && sequentialAddresses(p6, p7, 1)
-  && clobber(x0, x1, x2, x3, x4, x5, x6)
-  => (MOVQstore [i] {s} p0 (BSWAPQ <w.Type> w) mem)
-
-// Combine constant stores into larger (unaligned) stores.
-(MOVBstoreconst [c] {s} p x:(MOVBstoreconst [a] {s} p mem))
-  && x.Uses == 1
-  && a.Off() + 1 == c.Off()
-  && clobber(x)
-  => (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p mem)
-(MOVBstoreconst [a] {s} p x:(MOVBstoreconst [c] {s} p mem))
-  && x.Uses == 1
-  && a.Off() + 1 == c.Off()
-  && clobber(x)
-  => (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p mem)
-(MOVWstoreconst [c] {s} p x:(MOVWstoreconst [a] {s} p mem))
-  && x.Uses == 1
-  && a.Off() + 2 == c.Off()
-  && clobber(x)
-  => (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p mem)
-(MOVWstoreconst [a] {s} p x:(MOVWstoreconst [c] {s} p mem))
-  && x.Uses == 1
-  && a.Off() + 2 == c.Off()
-  && clobber(x)
-  => (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p mem)
-(MOVLstoreconst [c] {s} p x:(MOVLstoreconst [a] {s} p mem))
-  && x.Uses == 1
-  && a.Off() + 4 == c.Off()
-  && clobber(x)
-  => (MOVQstore [a.Off()] {s} p (MOVQconst [a.Val64()&0xffffffff | c.Val64()<<32]) mem)
-(MOVLstoreconst [a] {s} p x:(MOVLstoreconst [c] {s} p mem))
-  && x.Uses == 1
-  && a.Off() + 4 == c.Off()
-  && clobber(x)
-  => (MOVQstore [a.Off()] {s} p (MOVQconst [a.Val64()&0xffffffff | c.Val64()<<32]) mem)
-(MOVQstoreconst [c] {s} p x:(MOVQstoreconst [a] {s} p mem))
-  && config.useSSE
-  && x.Uses == 1
-  && a.Off() + 8 == c.Off()
-  && a.Val() == 0
-  && c.Val() == 0
-  && clobber(x)
-  => (MOVOstoreconst [makeValAndOff(0,a.Off())] {s} p mem)
-(MOVQstoreconst [a] {s} p x:(MOVQstoreconst [c] {s} p mem))
-  && config.useSSE
-  && x.Uses == 1
-  && a.Off() + 8 == c.Off()
-  && a.Val() == 0
-  && c.Val() == 0
-  && clobber(x)
-  => (MOVOstoreconst [makeValAndOff(0,a.Off())] {s} p mem)
-
-// Combine stores into larger (unaligned) stores. Little endian.
-(MOVBstore [i] {s} p (SHR(W|L|Q)const [8] w) x:(MOVBstore [i-1] {s} p w mem))
-  && x.Uses == 1
-  && clobber(x)
-  => (MOVWstore [i-1] {s} p w mem)
-(MOVBstore [i] {s} p w x:(MOVBstore [i+1] {s} p (SHR(W|L|Q)const [8] w) mem))
-  && x.Uses == 1
-  && clobber(x)
-  => (MOVWstore [i] {s} p w mem)
-(MOVBstore [i] {s} p (SHR(L|Q)const [j] w) x:(MOVBstore [i-1] {s} p w0:(SHR(L|Q)const [j-8] w) mem))
-  && x.Uses == 1
-  && clobber(x)
-  => (MOVWstore [i-1] {s} p w0 mem)
-(MOVBstore [i] {s} p1 (SHR(W|L|Q)const [8] w) x:(MOVBstore [i] {s} p0 w mem))
-  && x.Uses == 1
-  && sequentialAddresses(p0, p1, 1)
-  && clobber(x)
-  => (MOVWstore [i] {s} p0 w mem)
-(MOVBstore [i] {s} p0 w x:(MOVBstore [i] {s} p1 (SHR(W|L|Q)const [8] w) mem))
-  && x.Uses == 1
-  && sequentialAddresses(p0, p1, 1)
-  && clobber(x)
-  => (MOVWstore [i] {s} p0 w mem)
-(MOVBstore [i] {s} p1 (SHR(L|Q)const [j] w) x:(MOVBstore [i] {s} p0 w0:(SHR(L|Q)const [j-8] w) mem))
-  && x.Uses == 1
-  && sequentialAddresses(p0, p1, 1)
-  && clobber(x)
-  => (MOVWstore [i] {s} p0 w0 mem)
-
-(MOVWstore [i] {s} p (SHR(L|Q)const [16] w) x:(MOVWstore [i-2] {s} p w mem))
-  && x.Uses == 1
-  && clobber(x)
-  => (MOVLstore [i-2] {s} p w mem)
-(MOVWstore [i] {s} p (SHR(L|Q)const [j] w) x:(MOVWstore [i-2] {s} p w0:(SHR(L|Q)const [j-16] w) mem))
-  && x.Uses == 1
-  && clobber(x)
-  => (MOVLstore [i-2] {s} p w0 mem)
-(MOVWstore [i] {s} p1 (SHR(L|Q)const [16] w) x:(MOVWstore [i] {s} p0 w mem))
-  && x.Uses == 1
-  && sequentialAddresses(p0, p1, 2)
-  && clobber(x)
-  => (MOVLstore [i] {s} p0 w mem)
-(MOVWstore [i] {s} p1 (SHR(L|Q)const [j] w) x:(MOVWstore [i] {s} p0 w0:(SHR(L|Q)const [j-16] w) mem))
-  && x.Uses == 1
-  && sequentialAddresses(p0, p1, 2)
-  && clobber(x)
-  => (MOVLstore [i] {s} p0 w0 mem)
-
-(MOVLstore [i] {s} p (SHRQconst [32] w) x:(MOVLstore [i-4] {s} p w mem))
-  && x.Uses == 1
-  && clobber(x)
-  => (MOVQstore [i-4] {s} p w mem)
-(MOVLstore [i] {s} p (SHRQconst [j] w) x:(MOVLstore [i-4] {s} p w0:(SHRQconst [j-32] w) mem))
-  && x.Uses == 1
-  && clobber(x)
-  => (MOVQstore [i-4] {s} p w0 mem)
-(MOVLstore [i] {s} p1 (SHRQconst [32] w) x:(MOVLstore [i] {s} p0 w mem))
-  && x.Uses == 1
-  && sequentialAddresses(p0, p1, 4)
-  && clobber(x)
-  => (MOVQstore [i] {s} p0 w mem)
-(MOVLstore [i] {s} p1 (SHRQconst [j] w) x:(MOVLstore [i] {s} p0 w0:(SHRQconst [j-32] w) mem))
-  && x.Uses == 1
-  && sequentialAddresses(p0, p1, 4)
-  && clobber(x)
-  => (MOVQstore [i] {s} p0 w0 mem)
-
-(MOVBstore [7] {s} p1 (SHRQconst [56] w)
-  x1:(MOVWstore [5] {s} p1 (SHRQconst [40] w)
-  x2:(MOVLstore [1] {s} p1 (SHRQconst [8] w)
-  x3:(MOVBstore [0] {s} p1 w mem))))
-  && x1.Uses == 1
-  && x2.Uses == 1
-  && x3.Uses == 1
-  && clobber(x1, x2, x3)
-  => (MOVQstore {s} p1 w mem)
-
-(MOVBstore [i] {s} p
-  x1:(MOVBload [j] {s2} p2 mem)
-    mem2:(MOVBstore [i-1] {s} p
-      x2:(MOVBload [j-1] {s2} p2 mem) mem))
-  && x1.Uses == 1
-  && x2.Uses == 1
-  && mem2.Uses == 1
-  && clobber(x1, x2, mem2)
-  => (MOVWstore [i-1] {s} p (MOVWload [j-1] {s2} p2 mem) mem)
-
-(MOVWstore [i] {s} p
-  x1:(MOVWload [j] {s2} p2 mem)
-    mem2:(MOVWstore [i-2] {s} p
-      x2:(MOVWload [j-2] {s2} p2 mem) mem))
-  && x1.Uses == 1
-  && x2.Uses == 1
-  && mem2.Uses == 1
-  && clobber(x1, x2, mem2)
-  => (MOVLstore [i-2] {s} p (MOVLload [j-2] {s2} p2 mem) mem)
-
-(MOVLstore [i] {s} p
-  x1:(MOVLload [j] {s2} p2 mem)
-    mem2:(MOVLstore [i-4] {s} p
-      x2:(MOVLload [j-4] {s2} p2 mem) mem))
-  && x1.Uses == 1
-  && x2.Uses == 1
-  && mem2.Uses == 1
-  && clobber(x1, x2, mem2)
-  => (MOVQstore [i-4] {s} p (MOVQload [j-4] {s2} p2 mem) mem)
-
-// Merge load and op
-// TODO: add indexed variants?
-((ADD|SUB|AND|OR|XOR)Q x l:(MOVQload [off] {sym} ptr mem)) && canMergeLoadClobber(v, l, x) && clobber(l) => ((ADD|SUB|AND|OR|XOR)Qload x [off] {sym} ptr mem)
-((ADD|SUB|AND|OR|XOR)L x l:(MOVLload [off] {sym} ptr mem)) && canMergeLoadClobber(v, l, x) && clobber(l) => ((ADD|SUB|AND|OR|XOR)Lload x [off] {sym} ptr mem)
-((ADD|SUB|MUL|DIV)SD x l:(MOVSDload [off] {sym} ptr mem)) && canMergeLoadClobber(v, l, x) && clobber(l) => ((ADD|SUB|MUL|DIV)SDload x [off] {sym} ptr mem)
-((ADD|SUB|MUL|DIV)SS x l:(MOVSSload [off] {sym} ptr mem)) && canMergeLoadClobber(v, l, x) && clobber(l) => ((ADD|SUB|MUL|DIV)SSload x [off] {sym} ptr mem)
-(MOVLstore {sym} [off] ptr y:((ADD|AND|OR|XOR)Lload x [off] {sym} ptr mem) mem) && y.Uses==1 && clobber(y) => ((ADD|AND|OR|XOR)Lmodify [off] {sym} ptr x mem)
-(MOVLstore {sym} [off] ptr y:((ADD|SUB|AND|OR|XOR)L l:(MOVLload [off] {sym} ptr mem) x) mem) && y.Uses==1 && l.Uses==1 && clobber(y, l) =>
-	((ADD|SUB|AND|OR|XOR)Lmodify [off] {sym} ptr x mem)
-(MOVQstore {sym} [off] ptr y:((ADD|AND|OR|XOR)Qload x [off] {sym} ptr mem) mem) && y.Uses==1 && clobber(y) => ((ADD|AND|OR|XOR)Qmodify [off] {sym} ptr x mem)
-(MOVQstore {sym} [off] ptr y:((ADD|SUB|AND|OR|XOR)Q l:(MOVQload [off] {sym} ptr mem) x) mem) && y.Uses==1 && l.Uses==1 && clobber(y, l) =>
-	((ADD|SUB|AND|OR|XOR)Qmodify [off] {sym} ptr x mem)
-
-// Merge ADDQconst and LEAQ into atomic loads.
-(MOV(Q|L|B)atomicload [off1] {sym} (ADDQconst [off2] ptr) mem) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOV(Q|L|B)atomicload [off1+off2] {sym} ptr mem)
-(MOV(Q|L|B)atomicload [off1] {sym1} (LEAQ [off2] {sym2} ptr) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-	(MOV(Q|L|B)atomicload [off1+off2] {mergeSym(sym1, sym2)} ptr mem)
-
-// Merge ADDQconst and LEAQ into atomic stores.
-(XCHGQ [off1] {sym} val (ADDQconst [off2] ptr) mem) && is32Bit(int64(off1)+int64(off2)) =>
-	(XCHGQ [off1+off2] {sym} val ptr mem)
-(XCHGQ [off1] {sym1} val (LEAQ [off2] {sym2} ptr) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && ptr.Op != OpSB =>
-	(XCHGQ [off1+off2] {mergeSym(sym1,sym2)} val ptr mem)
-(XCHGL [off1] {sym} val (ADDQconst [off2] ptr) mem) && is32Bit(int64(off1)+int64(off2)) =>
-	(XCHGL [off1+off2] {sym} val ptr mem)
-(XCHGL [off1] {sym1} val (LEAQ [off2] {sym2} ptr) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && ptr.Op != OpSB =>
-	(XCHGL [off1+off2] {mergeSym(sym1,sym2)} val ptr mem)
-
-// Merge ADDQconst into atomic adds.
-// TODO: merging LEAQ doesn't work, assembler doesn't like the resulting instructions.
-(XADDQlock [off1] {sym} val (ADDQconst [off2] ptr) mem) && is32Bit(int64(off1)+int64(off2)) =>
-	(XADDQlock [off1+off2] {sym} val ptr mem)
-(XADDLlock [off1] {sym} val (ADDQconst [off2] ptr) mem) && is32Bit(int64(off1)+int64(off2)) =>
-	(XADDLlock [off1+off2] {sym} val ptr mem)
-
-// Merge ADDQconst into atomic compare and swaps.
-// TODO: merging LEAQ doesn't work, assembler doesn't like the resulting instructions.
-(CMPXCHGQlock [off1] {sym} (ADDQconst [off2] ptr) old new_ mem) && is32Bit(int64(off1)+int64(off2)) =>
-	(CMPXCHGQlock [off1+off2] {sym} ptr old new_ mem)
-(CMPXCHGLlock [off1] {sym} (ADDQconst [off2] ptr) old new_ mem) && is32Bit(int64(off1)+int64(off2)) =>
-	(CMPXCHGLlock [off1+off2] {sym} ptr old new_ mem)
-
-// We don't need the conditional move if we know the arg of BSF is not zero.
-(CMOVQEQ x _ (Select1 (BS(F|R)Q (ORQconst [c] _)))) && c != 0 => x
-// Extension is unnecessary for trailing zeros.
-(BSFQ (ORQconst <t> [1<<8] (MOVBQZX x))) => (BSFQ (ORQconst <t> [1<<8] x))
-(BSFQ (ORQconst <t> [1<<16] (MOVWQZX x))) => (BSFQ (ORQconst <t> [1<<16] x))
-
-// Redundant sign/zero extensions
-// Note: see issue 21963. We have to make sure we use the right type on
-// the resulting extension (the outer type, not the inner type).
-(MOVLQSX (MOVLQSX x)) => (MOVLQSX x)
-(MOVLQSX (MOVWQSX x)) => (MOVWQSX x)
-(MOVLQSX (MOVBQSX x)) => (MOVBQSX x)
-(MOVWQSX (MOVWQSX x)) => (MOVWQSX x)
-(MOVWQSX (MOVBQSX x)) => (MOVBQSX x)
-(MOVBQSX (MOVBQSX x)) => (MOVBQSX x)
-(MOVLQZX (MOVLQZX x)) => (MOVLQZX x)
-(MOVLQZX (MOVWQZX x)) => (MOVWQZX x)
-(MOVLQZX (MOVBQZX x)) => (MOVBQZX x)
-(MOVWQZX (MOVWQZX x)) => (MOVWQZX x)
-(MOVWQZX (MOVBQZX x)) => (MOVBQZX x)
-(MOVBQZX (MOVBQZX x)) => (MOVBQZX x)
-
-(MOVQstore [off] {sym} ptr a:((ADD|AND|OR|XOR)Qconst [c] l:(MOVQload [off] {sym} ptr2 mem)) mem)
-	&& isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && clobber(l, a) =>
-	((ADD|AND|OR|XOR)Qconstmodify {sym} [makeValAndOff(int32(c),off)] ptr mem)
-(MOVLstore [off] {sym} ptr a:((ADD|AND|OR|XOR)Lconst [c] l:(MOVLload [off] {sym} ptr2 mem)) mem)
-	&& isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && clobber(l, a) =>
-	((ADD|AND|OR|XOR)Lconstmodify {sym} [makeValAndOff(int32(c),off)] ptr mem)
-
-// float <-> int register moves, with no conversion.
-// These come up when compiling math.{Float{32,64}bits,Float{32,64}frombits}.
-(MOVQload  [off] {sym} ptr (MOVSDstore [off] {sym} ptr val _)) => (MOVQf2i val)
-(MOVLload  [off] {sym} ptr (MOVSSstore [off] {sym} ptr val _)) => (MOVLf2i val)
-(MOVSDload [off] {sym} ptr (MOVQstore  [off] {sym} ptr val _)) => (MOVQi2f val)
-(MOVSSload [off] {sym} ptr (MOVLstore  [off] {sym} ptr val _)) => (MOVLi2f val)
-
-// Other load-like ops.
-(ADDQload x [off] {sym} ptr (MOVSDstore [off] {sym} ptr y _)) => (ADDQ x (MOVQf2i y))
-(ADDLload x [off] {sym} ptr (MOVSSstore [off] {sym} ptr y _)) => (ADDL x (MOVLf2i y))
-(SUBQload x [off] {sym} ptr (MOVSDstore [off] {sym} ptr y _)) => (SUBQ x (MOVQf2i y))
-(SUBLload x [off] {sym} ptr (MOVSSstore [off] {sym} ptr y _)) => (SUBL x (MOVLf2i y))
-(ANDQload x [off] {sym} ptr (MOVSDstore [off] {sym} ptr y _)) => (ANDQ x (MOVQf2i y))
-(ANDLload x [off] {sym} ptr (MOVSSstore [off] {sym} ptr y _)) => (ANDL x (MOVLf2i y))
-( ORQload x [off] {sym} ptr (MOVSDstore [off] {sym} ptr y _)) => ( ORQ x (MOVQf2i y))
-( ORLload x [off] {sym} ptr (MOVSSstore [off] {sym} ptr y _)) => ( ORL x (MOVLf2i y))
-(XORQload x [off] {sym} ptr (MOVSDstore [off] {sym} ptr y _)) => (XORQ x (MOVQf2i y))
-(XORLload x [off] {sym} ptr (MOVSSstore [off] {sym} ptr y _)) => (XORL x (MOVLf2i y))
-
-(ADDSDload x [off] {sym} ptr (MOVQstore [off] {sym} ptr y _)) => (ADDSD x (MOVQi2f y))
-(ADDSSload x [off] {sym} ptr (MOVLstore [off] {sym} ptr y _)) => (ADDSS x (MOVLi2f y))
-(SUBSDload x [off] {sym} ptr (MOVQstore [off] {sym} ptr y _)) => (SUBSD x (MOVQi2f y))
-(SUBSSload x [off] {sym} ptr (MOVLstore [off] {sym} ptr y _)) => (SUBSS x (MOVLi2f y))
-(MULSDload x [off] {sym} ptr (MOVQstore [off] {sym} ptr y _)) => (MULSD x (MOVQi2f y))
-(MULSSload x [off] {sym} ptr (MOVLstore [off] {sym} ptr y _)) => (MULSS x (MOVLi2f y))
-
-// Redirect stores to use the other register set.
-(MOVQstore  [off] {sym} ptr (MOVQf2i val) mem) => (MOVSDstore [off] {sym} ptr val mem)
-(MOVLstore  [off] {sym} ptr (MOVLf2i val) mem) => (MOVSSstore [off] {sym} ptr val mem)
-(MOVSDstore [off] {sym} ptr (MOVQi2f val) mem) => (MOVQstore  [off] {sym} ptr val mem)
-(MOVSSstore [off] {sym} ptr (MOVLi2f val) mem) => (MOVLstore  [off] {sym} ptr val mem)
-
-// Load args directly into the register class where it will be used.
-// We do this by just modifying the type of the Arg.
-(MOVQf2i <t> (Arg <u> [off] {sym})) && t.Size() == u.Size() => @b.Func.Entry (Arg <t> [off] {sym})
-(MOVLf2i <t> (Arg <u> [off] {sym})) && t.Size() == u.Size() => @b.Func.Entry (Arg <t> [off] {sym})
-(MOVQi2f <t> (Arg <u> [off] {sym})) && t.Size() == u.Size() => @b.Func.Entry (Arg <t> [off] {sym})
-(MOVLi2f <t> (Arg <u> [off] {sym})) && t.Size() == u.Size() => @b.Func.Entry (Arg <t> [off] {sym})
-
-// LEAQ is rematerializeable, so this helps to avoid register spill.
-// See issue 22947 for details
-(ADD(Q|L)const [off] x:(SP)) => (LEA(Q|L) [off] x)
-
-// HMULx is commutative, but its first argument must go in AX.
-// If possible, put a rematerializeable value in the first argument slot,
-// to reduce the odds that another value will be have to spilled
-// specifically to free up AX.
-(HMUL(Q|L)  x y) && !x.rematerializeable() && y.rematerializeable() => (HMUL(Q|L)  y x)
-(HMUL(Q|L)U x y) && !x.rematerializeable() && y.rematerializeable() => (HMUL(Q|L)U y x)
-
-// Fold loads into compares
-// Note: these may be undone by the flagalloc pass.
-(CMP(Q|L|W|B) l:(MOV(Q|L|W|B)load {sym} [off] ptr mem) x) && canMergeLoad(v, l) && clobber(l) => (CMP(Q|L|W|B)load {sym} [off] ptr x mem)
-(CMP(Q|L|W|B) x l:(MOV(Q|L|W|B)load {sym} [off] ptr mem)) && canMergeLoad(v, l) && clobber(l) => (InvertFlags (CMP(Q|L|W|B)load {sym} [off] ptr x mem))
-
-(CMP(Q|L)const l:(MOV(Q|L)load {sym} [off] ptr mem) [c])
-	&& l.Uses == 1
-	&& clobber(l) =>
[email protected] (CMP(Q|L)constload {sym} [makeValAndOff(c,off)] ptr mem)
-(CMP(W|B)const l:(MOV(W|B)load {sym} [off] ptr mem) [c])
-	&& l.Uses == 1
-	&& clobber(l) =>
[email protected] (CMP(W|B)constload {sym} [makeValAndOff(int32(c),off)] ptr mem)
-
-(CMPQload {sym} [off] ptr (MOVQconst [c]) mem) && validVal(c) => (CMPQconstload {sym} [makeValAndOff(int32(c),off)] ptr mem)
-(CMPLload {sym} [off] ptr (MOVLconst [c]) mem) => (CMPLconstload {sym} [makeValAndOff(c,off)] ptr mem)
-(CMPWload {sym} [off] ptr (MOVLconst [c]) mem) => (CMPWconstload {sym} [makeValAndOff(int32(int16(c)),off)] ptr mem)
-(CMPBload {sym} [off] ptr (MOVLconst [c]) mem) => (CMPBconstload {sym} [makeValAndOff(int32(int8(c)),off)] ptr mem)
-
-(TEST(Q|L|W|B)  l:(MOV(Q|L|W|B)load {sym} [off] ptr mem) l2)
-        && l == l2
-	&& l.Uses == 2
-	&& clobber(l) =>
-  @l.Block (CMP(Q|L|W|B)constload {sym} [makeValAndOff(0, off)] ptr mem)
-
-// Convert ANDload to MOVload when we can do the AND in a containing TEST op.
-// Only do when it's within the same block, so we don't have flags live across basic block boundaries.
-// See issue 44228.
-(TEST(Q|L) a:(AND(Q|L)load [off] {sym} x ptr mem) a) && a.Uses == 2 && a.Block == v.Block && clobber(a) => (TEST(Q|L) (MOV(Q|L)load <a.Type> [off] {sym} ptr mem) x)
-
-(MOVBload [off] {sym} (SB) _) && symIsRO(sym) => (MOVLconst [int32(read8(sym, int64(off)))])
-(MOVWload [off] {sym} (SB) _) && symIsRO(sym) => (MOVLconst [int32(read16(sym, int64(off), config.ctxt.Arch.ByteOrder))])
-(MOVLload [off] {sym} (SB) _) && symIsRO(sym) => (MOVQconst [int64(read32(sym, int64(off), config.ctxt.Arch.ByteOrder))])
-(MOVQload [off] {sym} (SB) _) && symIsRO(sym) => (MOVQconst [int64(read64(sym, int64(off), config.ctxt.Arch.ByteOrder))])
-(MOVOstore [dstOff] {dstSym} ptr (MOVOload [srcOff] {srcSym} (SB) _) mem) && symIsRO(srcSym) =>
-  (MOVQstore [dstOff+8] {dstSym} ptr (MOVQconst [int64(read64(srcSym, int64(srcOff)+8, config.ctxt.Arch.ByteOrder))])
-    (MOVQstore [dstOff] {dstSym} ptr (MOVQconst [int64(read64(srcSym, int64(srcOff), config.ctxt.Arch.ByteOrder))]) mem))
-
-// Arch-specific inlining for small or disjoint runtime.memmove
-// Match post-lowering calls, memory version.
-(SelectN [0] call:(CALLstatic {sym} s1:(MOVQstoreconst _ [sc] s2:(MOVQstore _ src s3:(MOVQstore _ dst mem)))))
-	&& sc.Val64() >= 0
-	&& isSameCall(sym, "runtime.memmove")
-	&& s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1
-	&& isInlinableMemmove(dst, src, sc.Val64(), config)
-	&& clobber(s1, s2, s3, call)
-	=> (Move [sc.Val64()] dst src mem)
-
-// Match post-lowering calls, register version.
-(SelectN [0] call:(CALLstatic {sym} dst src (MOVQconst [sz]) mem))
-	&& sz >= 0
-	&& isSameCall(sym, "runtime.memmove")
-	&& call.Uses == 1
-	&& isInlinableMemmove(dst, src, sz, config)
-	&& clobber(call)
-	=> (Move [sz] dst src mem)
-
-// Prefetch instructions
-(PrefetchCache ...)   => (PrefetchT0 ...)
-(PrefetchCacheStreamed ...) => (PrefetchNTA ...)
-
-// CPUID feature: BMI1.
-(AND(Q|L) x (NOT(Q|L) y))           && buildcfg.GOAMD64 >= 3 => (ANDN(Q|L) x y)
-(AND(Q|L) x (NEG(Q|L) x))           && buildcfg.GOAMD64 >= 3 => (BLSI(Q|L) x)
-(XOR(Q|L) x (ADD(Q|L)const [-1] x)) && buildcfg.GOAMD64 >= 3 => (BLSMSK(Q|L) x)
-(AND(Q|L) x (ADD(Q|L)const [-1] x)) && buildcfg.GOAMD64 >= 3 => (BLSR(Q|L) x)
-
-(BSWAP(Q|L) (BSWAP(Q|L) p)) => p
-
-// CPUID feature: MOVBE.
-(MOV(Q|L)store [i] {s} p x:(BSWAP(Q|L) w) mem) && x.Uses == 1 && buildcfg.GOAMD64 >= 3 => (MOVBE(Q|L)store [i] {s} p w mem)
-(BSWAP(Q|L) x:(MOV(Q|L)load [i] {s} p mem))    && x.Uses == 1 && buildcfg.GOAMD64 >= 3 => (MOVBE(Q|L)load [i] {s} p mem)
-(BSWAP(Q|L) (MOVBE(Q|L)load [i] {s} p m))    => (MOV(Q|L)load [i] {s} p m)
-(MOVBE(Q|L)store [i] {s} p (BSWAP(Q|L) x) m) => (MOV(Q|L)store [i] {s} p x m)
-(MOVWstore [i] {s} p x:(ROLWconst [8] w) mem)   && x.Uses == 1 && buildcfg.GOAMD64 >= 3 => (MOVBEWstore [i] {s} p w mem)
-(MOVBEWstore [i] {s} p x:(ROLWconst [8] w) mem) && x.Uses == 1 => (MOVWstore [i] {s} p w mem)
-
-(ORQ                   x0:(MOVBELload [i0] {s} p mem)
-    sh:(SHLQconst [32] x1:(MOVBELload [i1] {s} p mem)))
-  && i0 == i1+4
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && sh.Uses == 1
-  && mergePoint(b,x0,x1) != nil
-  && clobber(x0, x1, sh)
-  => @mergePoint(b,x0,x1) (MOVBEQload [i1] {s} p mem)
-
-(ORQ                   x0:(MOVBELload [i] {s} p0 mem)
-    sh:(SHLQconst [32] x1:(MOVBELload [i] {s} p1 mem)))
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && sh.Uses == 1
-  && sequentialAddresses(p1, p0, 4)
-  && mergePoint(b,x0,x1) != nil
-  && clobber(x0, x1, sh)
-  => @mergePoint(b,x0,x1) (MOVBEQload [i] {s} p1 mem)
-
-(SARX(Q|L) l:(MOV(Q|L)load [off] {sym} ptr mem) x) && canMergeLoad(v, l) && clobber(l) => (SARX(Q|L)load [off] {sym} ptr x mem)
-(SHLX(Q|L) l:(MOV(Q|L)load [off] {sym} ptr mem) x) && canMergeLoad(v, l) && clobber(l) => (SHLX(Q|L)load [off] {sym} ptr x mem)
-(SHRX(Q|L) l:(MOV(Q|L)load [off] {sym} ptr mem) x) && canMergeLoad(v, l) && clobber(l) => (SHRX(Q|L)load [off] {sym} ptr x mem)
-
-((SHL|SHR|SAR)XQload [off] {sym} ptr (MOVQconst [c]) mem) => ((SHL|SHR|SAR)Qconst [int8(c&63)] (MOVQload [off] {sym} ptr mem))
-((SHL|SHR|SAR)XQload [off] {sym} ptr (MOVLconst [c]) mem) => ((SHL|SHR|SAR)Qconst [int8(c&63)] (MOVQload [off] {sym} ptr mem))
-((SHL|SHR|SAR)XLload [off] {sym} ptr (MOVLconst [c]) mem) => ((SHL|SHR|SAR)Lconst [int8(c&31)] (MOVLload [off] {sym} ptr mem))
diff --git a/src/cmd/compile/internal/ssa/gen/AMD64Ops.go b/src/cmd/compile/internal/ssa/gen/AMD64Ops.go
deleted file mode 100644
index fc42fa5..0000000
--- a/src/cmd/compile/internal/ssa/gen/AMD64Ops.go
+++ /dev/null
@@ -1,1027 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build ignore
-// +build ignore
-
-package main
-
-import "strings"
-
-// Notes:
-//  - Integer types live in the low portion of registers. Upper portions are junk.
-//  - Boolean types use the low-order byte of a register. 0=false, 1=true.
-//    Upper bytes are junk.
-//  - Floating-point types live in the low natural slot of an sse2 register.
-//    Unused portions are junk.
-//  - We do not use AH,BH,CH,DH registers.
-//  - When doing sub-register operations, we try to write the whole
-//    destination register to avoid a partial-register write.
-//  - Unused portions of AuxInt (or the Val portion of ValAndOff) are
-//    filled by sign-extending the used portion.  Users of AuxInt which interpret
-//    AuxInt as unsigned (e.g. shifts) must be careful.
-//  - All SymOff opcodes require their offset to fit in an int32.
-
-// Suffixes encode the bit width of various instructions.
-// Q (quad word) = 64 bit
-// L (long word) = 32 bit
-// W (word)      = 16 bit
-// B (byte)      = 8 bit
-
-// copied from ../../amd64/reg.go
-var regNamesAMD64 = []string{
-	"AX",
-	"CX",
-	"DX",
-	"BX",
-	"SP",
-	"BP",
-	"SI",
-	"DI",
-	"R8",
-	"R9",
-	"R10",
-	"R11",
-	"R12",
-	"R13",
-	"g", // a.k.a. R14
-	"R15",
-	"X0",
-	"X1",
-	"X2",
-	"X3",
-	"X4",
-	"X5",
-	"X6",
-	"X7",
-	"X8",
-	"X9",
-	"X10",
-	"X11",
-	"X12",
-	"X13",
-	"X14",
-	"X15", // constant 0 in ABIInternal
-
-	// If you add registers, update asyncPreempt in runtime
-
-	// pseudo-registers
-	"SB",
-}
-
-func init() {
-	// Make map from reg names to reg integers.
-	if len(regNamesAMD64) > 64 {
-		panic("too many registers")
-	}
-	num := map[string]int{}
-	for i, name := range regNamesAMD64 {
-		num[name] = i
-	}
-	buildReg := func(s string) regMask {
-		m := regMask(0)
-		for _, r := range strings.Split(s, " ") {
-			if n, ok := num[r]; ok {
-				m |= regMask(1) << uint(n)
-				continue
-			}
-			panic("register " + r + " not found")
-		}
-		return m
-	}
-
-	// Common individual register masks
-	var (
-		ax         = buildReg("AX")
-		cx         = buildReg("CX")
-		dx         = buildReg("DX")
-		bx         = buildReg("BX")
-		gp         = buildReg("AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15")
-		g          = buildReg("g")
-		fp         = buildReg("X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14")
-		x15        = buildReg("X15")
-		gpsp       = gp | buildReg("SP")
-		gpspsb     = gpsp | buildReg("SB")
-		gpspsbg    = gpspsb | g
-		callerSave = gp | fp | g // runtime.setg (and anything calling it) may clobber g
-	)
-	// Common slices of register masks
-	var (
-		gponly = []regMask{gp}
-		fponly = []regMask{fp}
-	)
-
-	// Common regInfo
-	var (
-		gp01           = regInfo{inputs: nil, outputs: gponly}
-		gp11           = regInfo{inputs: []regMask{gp}, outputs: gponly}
-		gp11sp         = regInfo{inputs: []regMask{gpsp}, outputs: gponly}
-		gp11sb         = regInfo{inputs: []regMask{gpspsbg}, outputs: gponly}
-		gp21           = regInfo{inputs: []regMask{gp, gp}, outputs: gponly}
-		gp21sp         = regInfo{inputs: []regMask{gpsp, gp}, outputs: gponly}
-		gp21sb         = regInfo{inputs: []regMask{gpspsbg, gpsp}, outputs: gponly}
-		gp21shift      = regInfo{inputs: []regMask{gp, cx}, outputs: []regMask{gp}}
-		gp31shift      = regInfo{inputs: []regMask{gp, gp, cx}, outputs: []regMask{gp}}
-		gp11div        = regInfo{inputs: []regMask{ax, gpsp &^ dx}, outputs: []regMask{ax, dx}}
-		gp21hmul       = regInfo{inputs: []regMask{ax, gpsp}, outputs: []regMask{dx}, clobbers: ax}
-		gp21flags      = regInfo{inputs: []regMask{gp, gp}, outputs: []regMask{gp, 0}}
-		gp2flags1flags = regInfo{inputs: []regMask{gp, gp, 0}, outputs: []regMask{gp, 0}}
-
-		gp2flags     = regInfo{inputs: []regMask{gpsp, gpsp}}
-		gp1flags     = regInfo{inputs: []regMask{gpsp}}
-		gp0flagsLoad = regInfo{inputs: []regMask{gpspsbg, 0}}
-		gp1flagsLoad = regInfo{inputs: []regMask{gpspsbg, gpsp, 0}}
-		gp2flagsLoad = regInfo{inputs: []regMask{gpspsbg, gpsp, gpsp, 0}}
-		flagsgp      = regInfo{inputs: nil, outputs: gponly}
-
-		gp11flags      = regInfo{inputs: []regMask{gp}, outputs: []regMask{gp, 0}}
-		gp1flags1flags = regInfo{inputs: []regMask{gp, 0}, outputs: []regMask{gp, 0}}
-
-		readflags = regInfo{inputs: nil, outputs: gponly}
-		flagsgpax = regInfo{inputs: nil, clobbers: ax, outputs: []regMask{gp &^ ax}}
-
-		gpload         = regInfo{inputs: []regMask{gpspsbg, 0}, outputs: gponly}
-		gp21load       = regInfo{inputs: []regMask{gp, gpspsbg, 0}, outputs: gponly}
-		gploadidx      = regInfo{inputs: []regMask{gpspsbg, gpsp, 0}, outputs: gponly}
-		gp21loadidx    = regInfo{inputs: []regMask{gp, gpspsbg, gpsp, 0}, outputs: gponly}
-		gp21pax        = regInfo{inputs: []regMask{gp &^ ax, gp}, outputs: []regMask{gp &^ ax}, clobbers: ax}
-		gp21shxload    = regInfo{inputs: []regMask{gpspsbg, gp, 0}, outputs: gponly}
-		gp21shxloadidx = regInfo{inputs: []regMask{gpspsbg, gpsp, gp, 0}, outputs: gponly}
-
-		gpstore         = regInfo{inputs: []regMask{gpspsbg, gpsp, 0}}
-		gpstoreconst    = regInfo{inputs: []regMask{gpspsbg, 0}}
-		gpstoreidx      = regInfo{inputs: []regMask{gpspsbg, gpsp, gpsp, 0}}
-		gpstoreconstidx = regInfo{inputs: []regMask{gpspsbg, gpsp, 0}}
-		gpstorexchg     = regInfo{inputs: []regMask{gp, gpspsbg, 0}, outputs: []regMask{gp}}
-		cmpxchg         = regInfo{inputs: []regMask{gp, ax, gp, 0}, outputs: []regMask{gp, 0}, clobbers: ax}
-
-		fp01        = regInfo{inputs: nil, outputs: fponly}
-		fp21        = regInfo{inputs: []regMask{fp, fp}, outputs: fponly}
-		fp31        = regInfo{inputs: []regMask{fp, fp, fp}, outputs: fponly}
-		fp21load    = regInfo{inputs: []regMask{fp, gpspsbg, 0}, outputs: fponly}
-		fp21loadidx = regInfo{inputs: []regMask{fp, gpspsbg, gpspsb, 0}, outputs: fponly}
-		fpgp        = regInfo{inputs: fponly, outputs: gponly}
-		gpfp        = regInfo{inputs: gponly, outputs: fponly}
-		fp11        = regInfo{inputs: fponly, outputs: fponly}
-		fp2flags    = regInfo{inputs: []regMask{fp, fp}}
-
-		fpload    = regInfo{inputs: []regMask{gpspsb, 0}, outputs: fponly}
-		fploadidx = regInfo{inputs: []regMask{gpspsb, gpsp, 0}, outputs: fponly}
-
-		fpstore    = regInfo{inputs: []regMask{gpspsb, fp, 0}}
-		fpstoreidx = regInfo{inputs: []regMask{gpspsb, gpsp, fp, 0}}
-
-		prefreg = regInfo{inputs: []regMask{gpspsbg}}
-	)
-
-	var AMD64ops = []opData{
-		// fp ops
-		{name: "ADDSS", argLength: 2, reg: fp21, asm: "ADDSS", commutative: true, resultInArg0: true}, // fp32 add
-		{name: "ADDSD", argLength: 2, reg: fp21, asm: "ADDSD", commutative: true, resultInArg0: true}, // fp64 add
-		{name: "SUBSS", argLength: 2, reg: fp21, asm: "SUBSS", resultInArg0: true},                    // fp32 sub
-		{name: "SUBSD", argLength: 2, reg: fp21, asm: "SUBSD", resultInArg0: true},                    // fp64 sub
-		{name: "MULSS", argLength: 2, reg: fp21, asm: "MULSS", commutative: true, resultInArg0: true}, // fp32 mul
-		{name: "MULSD", argLength: 2, reg: fp21, asm: "MULSD", commutative: true, resultInArg0: true}, // fp64 mul
-		{name: "DIVSS", argLength: 2, reg: fp21, asm: "DIVSS", resultInArg0: true},                    // fp32 div
-		{name: "DIVSD", argLength: 2, reg: fp21, asm: "DIVSD", resultInArg0: true},                    // fp64 div
-
-		{name: "MOVSSload", argLength: 2, reg: fpload, asm: "MOVSS", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"}, // fp32 load
-		{name: "MOVSDload", argLength: 2, reg: fpload, asm: "MOVSD", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"}, // fp64 load
-		{name: "MOVSSconst", reg: fp01, asm: "MOVSS", aux: "Float32", rematerializeable: true},                               // fp32 constant
-		{name: "MOVSDconst", reg: fp01, asm: "MOVSD", aux: "Float64", rematerializeable: true},                               // fp64 constant
-		{name: "MOVSSloadidx1", argLength: 3, reg: fploadidx, asm: "MOVSS", scale: 1, aux: "SymOff", symEffect: "Read"},      // fp32 load indexed by i
-		{name: "MOVSSloadidx4", argLength: 3, reg: fploadidx, asm: "MOVSS", scale: 4, aux: "SymOff", symEffect: "Read"},      // fp32 load indexed by 4*i
-		{name: "MOVSDloadidx1", argLength: 3, reg: fploadidx, asm: "MOVSD", scale: 1, aux: "SymOff", symEffect: "Read"},      // fp64 load indexed by i
-		{name: "MOVSDloadidx8", argLength: 3, reg: fploadidx, asm: "MOVSD", scale: 8, aux: "SymOff", symEffect: "Read"},      // fp64 load indexed by 8*i
-
-		{name: "MOVSSstore", argLength: 3, reg: fpstore, asm: "MOVSS", aux: "SymOff", faultOnNilArg0: true, symEffect: "Write"}, // fp32 store
-		{name: "MOVSDstore", argLength: 3, reg: fpstore, asm: "MOVSD", aux: "SymOff", faultOnNilArg0: true, symEffect: "Write"}, // fp64 store
-		{name: "MOVSSstoreidx1", argLength: 4, reg: fpstoreidx, asm: "MOVSS", scale: 1, aux: "SymOff", symEffect: "Write"},      // fp32 indexed by i store
-		{name: "MOVSSstoreidx4", argLength: 4, reg: fpstoreidx, asm: "MOVSS", scale: 4, aux: "SymOff", symEffect: "Write"},      // fp32 indexed by 4i store
-		{name: "MOVSDstoreidx1", argLength: 4, reg: fpstoreidx, asm: "MOVSD", scale: 1, aux: "SymOff", symEffect: "Write"},      // fp64 indexed by i store
-		{name: "MOVSDstoreidx8", argLength: 4, reg: fpstoreidx, asm: "MOVSD", scale: 8, aux: "SymOff", symEffect: "Write"},      // fp64 indexed by 8i store
-
-		{name: "ADDSSload", argLength: 3, reg: fp21load, asm: "ADDSS", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"}, // fp32 arg0 + tmp, tmp loaded from arg1+auxint+aux, arg2 = mem
-		{name: "ADDSDload", argLength: 3, reg: fp21load, asm: "ADDSD", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"}, // fp64 arg0 + tmp, tmp loaded from arg1+auxint+aux, arg2 = mem
-		{name: "SUBSSload", argLength: 3, reg: fp21load, asm: "SUBSS", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"}, // fp32 arg0 - tmp, tmp loaded from arg1+auxint+aux, arg2 = mem
-		{name: "SUBSDload", argLength: 3, reg: fp21load, asm: "SUBSD", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"}, // fp64 arg0 - tmp, tmp loaded from arg1+auxint+aux, arg2 = mem
-		{name: "MULSSload", argLength: 3, reg: fp21load, asm: "MULSS", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"}, // fp32 arg0 * tmp, tmp loaded from arg1+auxint+aux, arg2 = mem
-		{name: "MULSDload", argLength: 3, reg: fp21load, asm: "MULSD", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"}, // fp64 arg0 * tmp, tmp loaded from arg1+auxint+aux, arg2 = mem
-		{name: "DIVSSload", argLength: 3, reg: fp21load, asm: "DIVSS", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"}, // fp32 arg0 / tmp, tmp loaded from arg1+auxint+aux, arg2 = mem
-		{name: "DIVSDload", argLength: 3, reg: fp21load, asm: "DIVSD", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, symEffect: "Read"}, // fp64 arg0 / tmp, tmp loaded from arg1+auxint+aux, arg2 = mem
-
-		{name: "ADDSSloadidx1", argLength: 4, reg: fp21loadidx, asm: "ADDSS", scale: 1, aux: "SymOff", resultInArg0: true, symEffect: "Read"}, // fp32 arg0 + tmp, tmp loaded from arg1+arg2+auxint+aux, arg3 = mem
-		{name: "ADDSSloadidx4", argLength: 4, reg: fp21loadidx, asm: "ADDSS", scale: 4, aux: "SymOff", resultInArg0: true, symEffect: "Read"}, // fp32 arg0 + tmp, tmp loaded from arg1+4*arg2+auxint+aux, arg3 = mem
-		{name: "ADDSDloadidx1", argLength: 4, reg: fp21loadidx, asm: "ADDSD", scale: 1, aux: "SymOff", resultInArg0: true, symEffect: "Read"}, // fp64 arg0 + tmp, tmp loaded from arg1+arg2+auxint+aux, arg3 = mem
-		{name: "ADDSDloadidx8", argLength: 4, reg: fp21loadidx, asm: "ADDSD", scale: 8, aux: "SymOff", resultInArg0: true, symEffect: "Read"}, // fp64 arg0 + tmp, tmp loaded from arg1+8*arg2+auxint+aux, arg3 = mem
-		{name: "SUBSSloadidx1", argLength: 4, reg: fp21loadidx, asm: "SUBSS", scale: 1, aux: "SymOff", resultInArg0: true, symEffect: "Read"}, // fp32 arg0 - tmp, tmp loaded from arg1+arg2+auxint+aux, arg3 = mem
-		{name: "SUBSSloadidx4", argLength: 4, reg: fp21loadidx, asm: "SUBSS", scale: 4, aux: "SymOff", resultInArg0: true, symEffect: "Read"}, // fp32 arg0 - tmp, tmp loaded from arg1+4*arg2+auxint+aux, arg3 = mem
-		{name: "SUBSDloadidx1", argLength: 4, reg: fp21loadidx, asm: "SUBSD", scale: 1, aux: "SymOff", resultInArg0: true, symEffect: "Read"}, // fp64 arg0 - tmp, tmp loaded from arg1+arg2+auxint+aux, arg3 = mem
-		{name: "SUBSDloadidx8", argLength: 4, reg: fp21loadidx, asm: "SUBSD", scale: 8, aux: "SymOff", resultInArg0: true, symEffect: "Read"}, // fp64 arg0 - tmp, tmp loaded from arg1+8*arg2+auxint+aux, arg3 = mem
-		{name: "MULSSloadidx1", argLength: 4, reg: fp21loadidx, asm: "MULSS", scale: 1, aux: "SymOff", resultInArg0: true, symEffect: "Read"}, // fp32 arg0 * tmp, tmp loaded from arg1+arg2+auxint+aux, arg3 = mem
-		{name: "MULSSloadidx4", argLength: 4, reg: fp21loadidx, asm: "MULSS", scale: 4, aux: "SymOff", resultInArg0: true, symEffect: "Read"}, // fp32 arg0 * tmp, tmp loaded from arg1+4*arg2+auxint+aux, arg3 = mem
-		{name: "MULSDloadidx1", argLength: 4, reg: fp21loadidx, asm: "MULSD", scale: 1, aux: "SymOff", resultInArg0: true, symEffect: "Read"}, // fp64 arg0 * tmp, tmp loaded from arg1+arg2+auxint+aux, arg3 = mem
-		{name: "MULSDloadidx8", argLength: 4, reg: fp21loadidx, asm: "MULSD", scale: 8, aux: "SymOff", resultInArg0: true, symEffect: "Read"}, // fp64 arg0 * tmp, tmp loaded from arg1+8*arg2+auxint+aux, arg3 = mem
-		{name: "DIVSSloadidx1", argLength: 4, reg: fp21loadidx, asm: "DIVSS", scale: 1, aux: "SymOff", resultInArg0: true, symEffect: "Read"}, // fp32 arg0 / tmp, tmp loaded from arg1+arg2+auxint+aux, arg3 = mem
-		{name: "DIVSSloadidx4", argLength: 4, reg: fp21loadidx, asm: "DIVSS", scale: 4, aux: "SymOff", resultInArg0: true, symEffect: "Read"}, // fp32 arg0 / tmp, tmp loaded from arg1+4*arg2+auxint+aux, arg3 = mem
-		{name: "DIVSDloadidx1", argLength: 4, reg: fp21loadidx, asm: "DIVSD", scale: 1, aux: "SymOff", resultInArg0: true, symEffect: "Read"}, // fp64 arg0 / tmp, tmp loaded from arg1+arg2+auxint+aux, arg3 = mem
-		{name: "DIVSDloadidx8", argLength: 4, reg: fp21loadidx, asm: "DIVSD", scale: 8, aux: "SymOff", resultInArg0: true, symEffect: "Read"}, // fp64 arg0 / tmp, tmp loaded from arg1+8*arg2+auxint+aux, arg3 = mem
-
-		// binary ops
-		{name: "ADDQ", argLength: 2, reg: gp21sp, asm: "ADDQ", commutative: true, clobberFlags: true},                                                                   // arg0 + arg1
-		{name: "ADDL", argLength: 2, reg: gp21sp, asm: "ADDL", commutative: true, clobberFlags: true},                                                                   // arg0 + arg1
-		{name: "ADDQconst", argLength: 1, reg: gp11sp, asm: "ADDQ", aux: "Int32", typ: "UInt64", clobberFlags: true},                                                    // arg0 + auxint
-		{name: "ADDLconst", argLength: 1, reg: gp11sp, asm: "ADDL", aux: "Int32", clobberFlags: true},                                                                   // arg0 + auxint
-		{name: "ADDQconstmodify", argLength: 2, reg: gpstoreconst, asm: "ADDQ", aux: "SymValAndOff", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"}, // add ValAndOff(AuxInt).Val() to arg0+ValAndOff(AuxInt).Off()+aux, arg1=mem
-		{name: "ADDLconstmodify", argLength: 2, reg: gpstoreconst, asm: "ADDL", aux: "SymValAndOff", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"}, // add ValAndOff(AuxInt).Val() to arg0+ValAndOff(AuxInt).Off()+aux, arg1=mem
-
-		{name: "SUBQ", argLength: 2, reg: gp21, asm: "SUBQ", resultInArg0: true, clobberFlags: true},                    // arg0 - arg1
-		{name: "SUBL", argLength: 2, reg: gp21, asm: "SUBL", resultInArg0: true, clobberFlags: true},                    // arg0 - arg1
-		{name: "SUBQconst", argLength: 1, reg: gp11, asm: "SUBQ", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 - auxint
-		{name: "SUBLconst", argLength: 1, reg: gp11, asm: "SUBL", aux: "Int32", resultInArg0: true, clobberFlags: true}, // arg0 - auxint
-
-		{name: "MULQ", argLength: 2, reg: gp21, asm: "IMULQ", commutative: true, resultInArg0: true, clobberFlags: true}, // arg0 * arg1
-		{name: "MULL", argLength: 2, reg: gp21, asm: "IMULL", commutative: true, resultInArg0: true, clobberFlags: true}, // arg0 * arg1
-		{name: "MULQconst", argLength: 1, reg: gp11, asm: "IMUL3Q", aux: "Int32", clobberFlags: true},                    // arg0 * auxint
-		{name: "MULLconst", argLength: 1, reg: gp11, asm: "IMUL3L", aux: "Int32", clobberFlags: true},                    // arg0 * auxint
-
-		{name: "MULLU", argLength: 2, reg: regInfo{inputs: []regMask{ax, gpsp}, outputs: []regMask{ax, 0}, clobbers: dx}, typ: "(UInt32,Flags)", asm: "MULL", commutative: true, clobberFlags: true}, // Let x = arg0*arg1 (full 32x32->64  unsigned multiply). Returns uint32(x), and flags set to overflow if uint32(x) != x.
-		{name: "MULQU", argLength: 2, reg: regInfo{inputs: []regMask{ax, gpsp}, outputs: []regMask{ax, 0}, clobbers: dx}, typ: "(UInt64,Flags)", asm: "MULQ", commutative: true, clobberFlags: true}, // Let x = arg0*arg1 (full 64x64->128 unsigned multiply). Returns uint64(x), and flags set to overflow if uint64(x) != x.
-
-		// HMULx[U] are intentionally not marked as commutative, even though they are.
-		// This is because they have asymmetric register requirements.
-		// There are rewrite rules to try to place arguments in preferable slots.
-		{name: "HMULQ", argLength: 2, reg: gp21hmul, asm: "IMULQ", clobberFlags: true}, // (arg0 * arg1) >> width
-		{name: "HMULL", argLength: 2, reg: gp21hmul, asm: "IMULL", clobberFlags: true}, // (arg0 * arg1) >> width
-		{name: "HMULQU", argLength: 2, reg: gp21hmul, asm: "MULQ", clobberFlags: true}, // (arg0 * arg1) >> width
-		{name: "HMULLU", argLength: 2, reg: gp21hmul, asm: "MULL", clobberFlags: true}, // (arg0 * arg1) >> width
-
-		{name: "AVGQU", argLength: 2, reg: gp21, commutative: true, resultInArg0: true, clobberFlags: true}, // (arg0 + arg1) / 2 as unsigned, all 64 result bits
-
-		// For DIVQ, DIVL and DIVW, AuxInt non-zero means that the divisor has been proved to be not -1.
-		{name: "DIVQ", argLength: 2, reg: gp11div, typ: "(Int64,Int64)", asm: "IDIVQ", aux: "Bool", clobberFlags: true}, // [arg0 / arg1, arg0 % arg1]
-		{name: "DIVL", argLength: 2, reg: gp11div, typ: "(Int32,Int32)", asm: "IDIVL", aux: "Bool", clobberFlags: true}, // [arg0 / arg1, arg0 % arg1]
-		{name: "DIVW", argLength: 2, reg: gp11div, typ: "(Int16,Int16)", asm: "IDIVW", aux: "Bool", clobberFlags: true}, // [arg0 / arg1, arg0 % arg1]
-
-		{name: "DIVQU", argLength: 2, reg: gp11div, typ: "(UInt64,UInt64)", asm: "DIVQ", clobberFlags: true}, // [arg0 / arg1, arg0 % arg1]
-		{name: "DIVLU", argLength: 2, reg: gp11div, typ: "(UInt32,UInt32)", asm: "DIVL", clobberFlags: true}, // [arg0 / arg1, arg0 % arg1]
-		{name: "DIVWU", argLength: 2, reg: gp11div, typ: "(UInt16,UInt16)", asm: "DIVW", clobberFlags: true}, // [arg0 / arg1, arg0 % arg1]
-
-		{name: "NEGLflags", argLength: 1, reg: gp11flags, typ: "(UInt32,Flags)", asm: "NEGL", resultInArg0: true}, // -arg0, flags set for 0-arg0.
-		// The following 4 add opcodes return the low 64 bits of the sum in the first result and
-		// the carry (the 65th bit) in the carry flag.
-		{name: "ADDQcarry", argLength: 2, reg: gp21flags, typ: "(UInt64,Flags)", asm: "ADDQ", commutative: true, resultInArg0: true}, // r = arg0+arg1
-		{name: "ADCQ", argLength: 3, reg: gp2flags1flags, typ: "(UInt64,Flags)", asm: "ADCQ", commutative: true, resultInArg0: true}, // r = arg0+arg1+carry(arg2)
-		{name: "ADDQconstcarry", argLength: 1, reg: gp11flags, typ: "(UInt64,Flags)", asm: "ADDQ", aux: "Int32", resultInArg0: true}, // r = arg0+auxint
-		{name: "ADCQconst", argLength: 2, reg: gp1flags1flags, typ: "(UInt64,Flags)", asm: "ADCQ", aux: "Int32", resultInArg0: true}, // r = arg0+auxint+carry(arg1)
-
-		// The following 4 add opcodes return the low 64 bits of the difference in the first result and
-		// the borrow (if the result is negative) in the carry flag.
-		{name: "SUBQborrow", argLength: 2, reg: gp21flags, typ: "(UInt64,Flags)", asm: "SUBQ", resultInArg0: true},                    // r = arg0-arg1
-		{name: "SBBQ", argLength: 3, reg: gp2flags1flags, typ: "(UInt64,Flags)", asm: "SBBQ", resultInArg0: true},                     // r = arg0-(arg1+carry(arg2))
-		{name: "SUBQconstborrow", argLength: 1, reg: gp11flags, typ: "(UInt64,Flags)", asm: "SUBQ", aux: "Int32", resultInArg0: true}, // r = arg0-auxint
-		{name: "SBBQconst", argLength: 2, reg: gp1flags1flags, typ: "(UInt64,Flags)", asm: "SBBQ", aux: "Int32", resultInArg0: true},  // r = arg0-(auxint+carry(arg1))
-
-		{name: "MULQU2", argLength: 2, reg: regInfo{inputs: []regMask{ax, gpsp}, outputs: []regMask{dx, ax}}, commutative: true, asm: "MULQ", clobberFlags: true}, // arg0 * arg1, returns (hi, lo)
-		{name: "DIVQU2", argLength: 3, reg: regInfo{inputs: []regMask{dx, ax, gpsp}, outputs: []regMask{ax, dx}}, asm: "DIVQ", clobberFlags: true},                // arg0:arg1 / arg2 (128-bit divided by 64-bit), returns (q, r)
-
-		{name: "ANDQ", argLength: 2, reg: gp21, asm: "ANDQ", commutative: true, resultInArg0: true, clobberFlags: true},                                                 // arg0 & arg1
-		{name: "ANDL", argLength: 2, reg: gp21, asm: "ANDL", commutative: true, resultInArg0: true, clobberFlags: true},                                                 // arg0 & arg1
-		{name: "ANDQconst", argLength: 1, reg: gp11, asm: "ANDQ", aux: "Int32", resultInArg0: true, clobberFlags: true},                                                 // arg0 & auxint
-		{name: "ANDLconst", argLength: 1, reg: gp11, asm: "ANDL", aux: "Int32", resultInArg0: true, clobberFlags: true},                                                 // arg0 & auxint
-		{name: "ANDQconstmodify", argLength: 2, reg: gpstoreconst, asm: "ANDQ", aux: "SymValAndOff", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"}, // and ValAndOff(AuxInt).Val() to arg0+ValAndOff(AuxInt).Off()+aux, arg1=mem
-		{name: "ANDLconstmodify", argLength: 2, reg: gpstoreconst, asm: "ANDL", aux: "SymValAndOff", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"}, // and ValAndOff(AuxInt).Val() to arg0+ValAndOff(AuxInt).Off()+aux, arg1=mem
-
-		{name: "ORQ", argLength: 2, reg: gp21, asm: "ORQ", commutative: true, resultInArg0: true, clobberFlags: true},                                                 // arg0 | arg1
-		{name: "ORL", argLength: 2, reg: gp21, asm: "ORL", commutative: true, resultInArg0: true, clobberFlags: true},                                                 // arg0 | arg1
-		{name: "ORQconst", argLength: 1, reg: gp11, asm: "ORQ", aux: "Int32", resultInArg0: true, clobberFlags: true},                                                 // arg0 | auxint
-		{name: "ORLconst", argLength: 1, reg: gp11, asm: "ORL", aux: "Int32", resultInArg0: true, clobberFlags: true},                                                 // arg0 | auxint
-		{name: "ORQconstmodify", argLength: 2, reg: gpstoreconst, asm: "ORQ", aux: "SymValAndOff", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"}, // or ValAndOff(AuxInt).Val() to arg0+ValAndOff(AuxInt).Off()+aux, arg1=mem
-		{name: "ORLconstmodify", argLength: 2, reg: gpstoreconst, asm: "ORL", aux: "SymValAndOff", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"}, // or ValAndOff(AuxInt).Val() to arg0+ValAndOff(AuxInt).Off()+aux, arg1=mem
-
-		{name: "XORQ", argLength: 2, reg: gp21, asm: "XORQ", commutative: true, resultInArg0: true, clobberFlags: true},                                                 // arg0 ^ arg1
-		{name: "XORL", argLength: 2, reg: gp21, asm: "XORL", commutative: true, resultInArg0: true, clobberFlags: true},                                                 // arg0 ^ arg1
-		{name: "XORQconst", argLength: 1, reg: gp11, asm: "XORQ", aux: "Int32", resultInArg0: true, clobberFlags: true},                                                 // arg0 ^ auxint
-		{name: "XORLconst", argLength: 1, reg: gp11, asm: "XORL", aux: "Int32", resultInArg0: true, clobberFlags: true},                                                 // arg0 ^ auxint
-		{name: "XORQconstmodify", argLength: 2, reg: gpstoreconst, asm: "XORQ", aux: "SymValAndOff", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"}, // xor ValAndOff(AuxInt).Val() to arg0+ValAndOff(AuxInt).Off()+aux, arg1=mem
-		{name: "XORLconstmodify", argLength: 2, reg: gpstoreconst, asm: "XORL", aux: "SymValAndOff", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"}, // xor ValAndOff(AuxInt).Val() to arg0+ValAndOff(AuxInt).Off()+aux, arg1=mem
-
-		{name: "CMPQ", argLength: 2, reg: gp2flags, asm: "CMPQ", typ: "Flags"},                    // arg0 compare to arg1
-		{name: "CMPL", argLength: 2, reg: gp2flags, asm: "CMPL", typ: "Flags"},                    // arg0 compare to arg1
-		{name: "CMPW", argLength: 2, reg: gp2flags, asm: "CMPW", typ: "Flags"},                    // arg0 compare to arg1
-		{name: "CMPB", argLength: 2, reg: gp2flags, asm: "CMPB", typ: "Flags"},                    // arg0 compare to arg1
-		{name: "CMPQconst", argLength: 1, reg: gp1flags, asm: "CMPQ", typ: "Flags", aux: "Int32"}, // arg0 compare to auxint
-		{name: "CMPLconst", argLength: 1, reg: gp1flags, asm: "CMPL", typ: "Flags", aux: "Int32"}, // arg0 compare to auxint
-		{name: "CMPWconst", argLength: 1, reg: gp1flags, asm: "CMPW", typ: "Flags", aux: "Int16"}, // arg0 compare to auxint
-		{name: "CMPBconst", argLength: 1, reg: gp1flags, asm: "CMPB", typ: "Flags", aux: "Int8"},  // arg0 compare to auxint
-
-		// compare *(arg0+auxint+aux) to arg1 (in that order). arg2=mem.
-		{name: "CMPQload", argLength: 3, reg: gp1flagsLoad, asm: "CMPQ", aux: "SymOff", typ: "Flags", symEffect: "Read", faultOnNilArg0: true},
-		{name: "CMPLload", argLength: 3, reg: gp1flagsLoad, asm: "CMPL", aux: "SymOff", typ: "Flags", symEffect: "Read", faultOnNilArg0: true},
-		{name: "CMPWload", argLength: 3, reg: gp1flagsLoad, asm: "CMPW", aux: "SymOff", typ: "Flags", symEffect: "Read", faultOnNilArg0: true},
-		{name: "CMPBload", argLength: 3, reg: gp1flagsLoad, asm: "CMPB", aux: "SymOff", typ: "Flags", symEffect: "Read", faultOnNilArg0: true},
-
-		// compare *(arg0+ValAndOff(AuxInt).Off()+aux) to ValAndOff(AuxInt).Val() (in that order). arg1=mem.
-		{name: "CMPQconstload", argLength: 2, reg: gp0flagsLoad, asm: "CMPQ", aux: "SymValAndOff", typ: "Flags", symEffect: "Read", faultOnNilArg0: true},
-		{name: "CMPLconstload", argLength: 2, reg: gp0flagsLoad, asm: "CMPL", aux: "SymValAndOff", typ: "Flags", symEffect: "Read", faultOnNilArg0: true},
-		{name: "CMPWconstload", argLength: 2, reg: gp0flagsLoad, asm: "CMPW", aux: "SymValAndOff", typ: "Flags", symEffect: "Read", faultOnNilArg0: true},
-		{name: "CMPBconstload", argLength: 2, reg: gp0flagsLoad, asm: "CMPB", aux: "SymValAndOff", typ: "Flags", symEffect: "Read", faultOnNilArg0: true},
-
-		// compare *(arg0+N*arg1+auxint+aux) to arg2 (in that order). arg3=mem.
-		{name: "CMPQloadidx8", argLength: 4, reg: gp2flagsLoad, asm: "CMPQ", scale: 8, aux: "SymOff", typ: "Flags", symEffect: "Read"},
-		{name: "CMPQloadidx1", argLength: 4, reg: gp2flagsLoad, asm: "CMPQ", scale: 1, commutative: true, aux: "SymOff", typ: "Flags", symEffect: "Read"},
-		{name: "CMPLloadidx4", argLength: 4, reg: gp2flagsLoad, asm: "CMPL", scale: 4, aux: "SymOff", typ: "Flags", symEffect: "Read"},
-		{name: "CMPLloadidx1", argLength: 4, reg: gp2flagsLoad, asm: "CMPL", scale: 1, commutative: true, aux: "SymOff", typ: "Flags", symEffect: "Read"},
-		{name: "CMPWloadidx2", argLength: 4, reg: gp2flagsLoad, asm: "CMPW", scale: 2, aux: "SymOff", typ: "Flags", symEffect: "Read"},
-		{name: "CMPWloadidx1", argLength: 4, reg: gp2flagsLoad, asm: "CMPW", scale: 1, commutative: true, aux: "SymOff", typ: "Flags", symEffect: "Read"},
-		{name: "CMPBloadidx1", argLength: 4, reg: gp2flagsLoad, asm: "CMPB", scale: 1, commutative: true, aux: "SymOff", typ: "Flags", symEffect: "Read"},
-
-		// compare *(arg0+N*arg1+ValAndOff(AuxInt).Off()+aux) to ValAndOff(AuxInt).Val() (in that order). arg2=mem.
-		{name: "CMPQconstloadidx8", argLength: 3, reg: gp1flagsLoad, asm: "CMPQ", scale: 8, aux: "SymValAndOff", typ: "Flags", symEffect: "Read"},
-		{name: "CMPQconstloadidx1", argLength: 3, reg: gp1flagsLoad, asm: "CMPQ", scale: 1, commutative: true, aux: "SymValAndOff", typ: "Flags", symEffect: "Read"},
-		{name: "CMPLconstloadidx4", argLength: 3, reg: gp1flagsLoad, asm: "CMPL", scale: 4, aux: "SymValAndOff", typ: "Flags", symEffect: "Read"},
-		{name: "CMPLconstloadidx1", argLength: 3, reg: gp1flagsLoad, asm: "CMPL", scale: 1, commutative: true, aux: "SymValAndOff", typ: "Flags", symEffect: "Read"},
-		{name: "CMPWconstloadidx2", argLength: 3, reg: gp1flagsLoad, asm: "CMPW", scale: 2, aux: "SymValAndOff", typ: "Flags", symEffect: "Read"},
-		{name: "CMPWconstloadidx1", argLength: 3, reg: gp1flagsLoad, asm: "CMPW", scale: 1, commutative: true, aux: "SymValAndOff", typ: "Flags", symEffect: "Read"},
-		{name: "CMPBconstloadidx1", argLength: 3, reg: gp1flagsLoad, asm: "CMPB", scale: 1, commutative: true, aux: "SymValAndOff", typ: "Flags", symEffect: "Read"},
-
-		{name: "UCOMISS", argLength: 2, reg: fp2flags, asm: "UCOMISS", typ: "Flags"}, // arg0 compare to arg1, f32
-		{name: "UCOMISD", argLength: 2, reg: fp2flags, asm: "UCOMISD", typ: "Flags"}, // arg0 compare to arg1, f64
-
-		{name: "BTL", argLength: 2, reg: gp2flags, asm: "BTL", typ: "Flags"},                                           // test whether bit arg0%32 in arg1 is set
-		{name: "BTQ", argLength: 2, reg: gp2flags, asm: "BTQ", typ: "Flags"},                                           // test whether bit arg0%64 in arg1 is set
-		{name: "BTCL", argLength: 2, reg: gp21, asm: "BTCL", resultInArg0: true, clobberFlags: true},                   // complement bit arg1%32 in arg0
-		{name: "BTCQ", argLength: 2, reg: gp21, asm: "BTCQ", resultInArg0: true, clobberFlags: true},                   // complement bit arg1%64 in arg0
-		{name: "BTRL", argLength: 2, reg: gp21, asm: "BTRL", resultInArg0: true, clobberFlags: true},                   // reset bit arg1%32 in arg0
-		{name: "BTRQ", argLength: 2, reg: gp21, asm: "BTRQ", resultInArg0: true, clobberFlags: true},                   // reset bit arg1%64 in arg0
-		{name: "BTSL", argLength: 2, reg: gp21, asm: "BTSL", resultInArg0: true, clobberFlags: true},                   // set bit arg1%32 in arg0
-		{name: "BTSQ", argLength: 2, reg: gp21, asm: "BTSQ", resultInArg0: true, clobberFlags: true},                   // set bit arg1%64 in arg0
-		{name: "BTLconst", argLength: 1, reg: gp1flags, asm: "BTL", typ: "Flags", aux: "Int8"},                         // test whether bit auxint in arg0 is set, 0 <= auxint < 32
-		{name: "BTQconst", argLength: 1, reg: gp1flags, asm: "BTQ", typ: "Flags", aux: "Int8"},                         // test whether bit auxint in arg0 is set, 0 <= auxint < 64
-		{name: "BTCLconst", argLength: 1, reg: gp11, asm: "BTCL", resultInArg0: true, clobberFlags: true, aux: "Int8"}, // complement bit auxint in arg0, 0 <= auxint < 32
-		{name: "BTCQconst", argLength: 1, reg: gp11, asm: "BTCQ", resultInArg0: true, clobberFlags: true, aux: "Int8"}, // complement bit auxint in arg0, 0 <= auxint < 64
-		{name: "BTRLconst", argLength: 1, reg: gp11, asm: "BTRL", resultInArg0: true, clobberFlags: true, aux: "Int8"}, // reset bit auxint in arg0, 0 <= auxint < 32
-		{name: "BTRQconst", argLength: 1, reg: gp11, asm: "BTRQ", resultInArg0: true, clobberFlags: true, aux: "Int8"}, // reset bit auxint in arg0, 0 <= auxint < 64
-		{name: "BTSLconst", argLength: 1, reg: gp11, asm: "BTSL", resultInArg0: true, clobberFlags: true, aux: "Int8"}, // set bit auxint in arg0, 0 <= auxint < 32
-		{name: "BTSQconst", argLength: 1, reg: gp11, asm: "BTSQ", resultInArg0: true, clobberFlags: true, aux: "Int8"}, // set bit auxint in arg0, 0 <= auxint < 64
-
-		{name: "TESTQ", argLength: 2, reg: gp2flags, commutative: true, asm: "TESTQ", typ: "Flags"}, // (arg0 & arg1) compare to 0
-		{name: "TESTL", argLength: 2, reg: gp2flags, commutative: true, asm: "TESTL", typ: "Flags"}, // (arg0 & arg1) compare to 0
-		{name: "TESTW", argLength: 2, reg: gp2flags, commutative: true, asm: "TESTW", typ: "Flags"}, // (arg0 & arg1) compare to 0
-		{name: "TESTB", argLength: 2, reg: gp2flags, commutative: true, asm: "TESTB", typ: "Flags"}, // (arg0 & arg1) compare to 0
-		{name: "TESTQconst", argLength: 1, reg: gp1flags, asm: "TESTQ", typ: "Flags", aux: "Int32"}, // (arg0 & auxint) compare to 0
-		{name: "TESTLconst", argLength: 1, reg: gp1flags, asm: "TESTL", typ: "Flags", aux: "Int32"}, // (arg0 & auxint) compare to 0
-		{name: "TESTWconst", argLength: 1, reg: gp1flags, asm: "TESTW", typ: "Flags", aux: "Int16"}, // (arg0 & auxint) compare to 0
-		{name: "TESTBconst", argLength: 1, reg: gp1flags, asm: "TESTB", typ: "Flags", aux: "Int8"},  // (arg0 & auxint) compare to 0
-
-		{name: "SHLQ", argLength: 2, reg: gp21shift, asm: "SHLQ", resultInArg0: true, clobberFlags: true},              // arg0 << arg1, shift amount is mod 64
-		{name: "SHLL", argLength: 2, reg: gp21shift, asm: "SHLL", resultInArg0: true, clobberFlags: true},              // arg0 << arg1, shift amount is mod 32
-		{name: "SHLQconst", argLength: 1, reg: gp11, asm: "SHLQ", aux: "Int8", resultInArg0: true, clobberFlags: true}, // arg0 << auxint, shift amount 0-63
-		{name: "SHLLconst", argLength: 1, reg: gp11, asm: "SHLL", aux: "Int8", resultInArg0: true, clobberFlags: true}, // arg0 << auxint, shift amount 0-31
-		// Note: x86 is weird, the 16 and 8 byte shifts still use all 5 bits of shift amount!
-
-		{name: "SHRQ", argLength: 2, reg: gp21shift, asm: "SHRQ", resultInArg0: true, clobberFlags: true},              // unsigned arg0 >> arg1, shift amount is mod 64
-		{name: "SHRL", argLength: 2, reg: gp21shift, asm: "SHRL", resultInArg0: true, clobberFlags: true},              // unsigned uint32(arg0) >> arg1, shift amount is mod 32
-		{name: "SHRW", argLength: 2, reg: gp21shift, asm: "SHRW", resultInArg0: true, clobberFlags: true},              // unsigned uint16(arg0) >> arg1, shift amount is mod 32
-		{name: "SHRB", argLength: 2, reg: gp21shift, asm: "SHRB", resultInArg0: true, clobberFlags: true},              // unsigned uint8(arg0) >> arg1, shift amount is mod 32
-		{name: "SHRQconst", argLength: 1, reg: gp11, asm: "SHRQ", aux: "Int8", resultInArg0: true, clobberFlags: true}, // unsigned arg0 >> auxint, shift amount 0-63
-		{name: "SHRLconst", argLength: 1, reg: gp11, asm: "SHRL", aux: "Int8", resultInArg0: true, clobberFlags: true}, // unsigned uint32(arg0) >> auxint, shift amount 0-31
-		{name: "SHRWconst", argLength: 1, reg: gp11, asm: "SHRW", aux: "Int8", resultInArg0: true, clobberFlags: true}, // unsigned uint16(arg0) >> auxint, shift amount 0-15
-		{name: "SHRBconst", argLength: 1, reg: gp11, asm: "SHRB", aux: "Int8", resultInArg0: true, clobberFlags: true}, // unsigned uint8(arg0) >> auxint, shift amount 0-7
-
-		{name: "SARQ", argLength: 2, reg: gp21shift, asm: "SARQ", resultInArg0: true, clobberFlags: true},              // signed arg0 >> arg1, shift amount is mod 64
-		{name: "SARL", argLength: 2, reg: gp21shift, asm: "SARL", resultInArg0: true, clobberFlags: true},              // signed int32(arg0) >> arg1, shift amount is mod 32
-		{name: "SARW", argLength: 2, reg: gp21shift, asm: "SARW", resultInArg0: true, clobberFlags: true},              // signed int16(arg0) >> arg1, shift amount is mod 32
-		{name: "SARB", argLength: 2, reg: gp21shift, asm: "SARB", resultInArg0: true, clobberFlags: true},              // signed int8(arg0) >> arg1, shift amount is mod 32
-		{name: "SARQconst", argLength: 1, reg: gp11, asm: "SARQ", aux: "Int8", resultInArg0: true, clobberFlags: true}, // signed arg0 >> auxint, shift amount 0-63
-		{name: "SARLconst", argLength: 1, reg: gp11, asm: "SARL", aux: "Int8", resultInArg0: true, clobberFlags: true}, // signed int32(arg0) >> auxint, shift amount 0-31
-		{name: "SARWconst", argLength: 1, reg: gp11, asm: "SARW", aux: "Int8", resultInArg0: true, clobberFlags: true}, // signed int16(arg0) >> auxint, shift amount 0-15
-		{name: "SARBconst", argLength: 1, reg: gp11, asm: "SARB", aux: "Int8", resultInArg0: true, clobberFlags: true}, // signed int8(arg0) >> auxint, shift amount 0-7
-
-		{name: "SHRDQ", argLength: 3, reg: gp31shift, asm: "SHRQ", resultInArg0: true, clobberFlags: true}, // unsigned arg0 >> arg2, shifting in bits from arg1 (==(arg1<<64+arg0)>>arg2, keeping low 64 bits), shift amount is mod 64
-		{name: "SHLDQ", argLength: 3, reg: gp31shift, asm: "SHLQ", resultInArg0: true, clobberFlags: true}, // unsigned arg0 << arg2, shifting in bits from arg1 (==(arg0<<64+arg1)<<arg2, keeping high 64 bits), shift amount is mod 64
-
-		{name: "ROLQ", argLength: 2, reg: gp21shift, asm: "ROLQ", resultInArg0: true, clobberFlags: true},              // arg0 rotate left arg1 bits.
-		{name: "ROLL", argLength: 2, reg: gp21shift, asm: "ROLL", resultInArg0: true, clobberFlags: true},              // arg0 rotate left arg1 bits.
-		{name: "ROLW", argLength: 2, reg: gp21shift, asm: "ROLW", resultInArg0: true, clobberFlags: true},              // arg0 rotate left arg1 bits.
-		{name: "ROLB", argLength: 2, reg: gp21shift, asm: "ROLB", resultInArg0: true, clobberFlags: true},              // arg0 rotate left arg1 bits.
-		{name: "RORQ", argLength: 2, reg: gp21shift, asm: "RORQ", resultInArg0: true, clobberFlags: true},              // arg0 rotate right arg1 bits.
-		{name: "RORL", argLength: 2, reg: gp21shift, asm: "RORL", resultInArg0: true, clobberFlags: true},              // arg0 rotate right arg1 bits.
-		{name: "RORW", argLength: 2, reg: gp21shift, asm: "RORW", resultInArg0: true, clobberFlags: true},              // arg0 rotate right arg1 bits.
-		{name: "RORB", argLength: 2, reg: gp21shift, asm: "RORB", resultInArg0: true, clobberFlags: true},              // arg0 rotate right arg1 bits.
-		{name: "ROLQconst", argLength: 1, reg: gp11, asm: "ROLQ", aux: "Int8", resultInArg0: true, clobberFlags: true}, // arg0 rotate left auxint, rotate amount 0-63
-		{name: "ROLLconst", argLength: 1, reg: gp11, asm: "ROLL", aux: "Int8", resultInArg0: true, clobberFlags: true}, // arg0 rotate left auxint, rotate amount 0-31
-		{name: "ROLWconst", argLength: 1, reg: gp11, asm: "ROLW", aux: "Int8", resultInArg0: true, clobberFlags: true}, // arg0 rotate left auxint, rotate amount 0-15
-		{name: "ROLBconst", argLength: 1, reg: gp11, asm: "ROLB", aux: "Int8", resultInArg0: true, clobberFlags: true}, // arg0 rotate left auxint, rotate amount 0-7
-
-		{name: "ADDLload", argLength: 3, reg: gp21load, asm: "ADDL", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"}, // arg0 + tmp, tmp loaded from  arg1+auxint+aux, arg2 = mem
-		{name: "ADDQload", argLength: 3, reg: gp21load, asm: "ADDQ", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"}, // arg0 + tmp, tmp loaded from  arg1+auxint+aux, arg2 = mem
-		{name: "SUBQload", argLength: 3, reg: gp21load, asm: "SUBQ", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"}, // arg0 - tmp, tmp loaded from  arg1+auxint+aux, arg2 = mem
-		{name: "SUBLload", argLength: 3, reg: gp21load, asm: "SUBL", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"}, // arg0 - tmp, tmp loaded from  arg1+auxint+aux, arg2 = mem
-		{name: "ANDLload", argLength: 3, reg: gp21load, asm: "ANDL", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"}, // arg0 & tmp, tmp loaded from  arg1+auxint+aux, arg2 = mem
-		{name: "ANDQload", argLength: 3, reg: gp21load, asm: "ANDQ", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"}, // arg0 & tmp, tmp loaded from  arg1+auxint+aux, arg2 = mem
-		{name: "ORQload", argLength: 3, reg: gp21load, asm: "ORQ", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},   // arg0 | tmp, tmp loaded from  arg1+auxint+aux, arg2 = mem
-		{name: "ORLload", argLength: 3, reg: gp21load, asm: "ORL", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},   // arg0 | tmp, tmp loaded from  arg1+auxint+aux, arg2 = mem
-		{name: "XORQload", argLength: 3, reg: gp21load, asm: "XORQ", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"}, // arg0 ^ tmp, tmp loaded from  arg1+auxint+aux, arg2 = mem
-		{name: "XORLload", argLength: 3, reg: gp21load, asm: "XORL", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"}, // arg0 ^ tmp, tmp loaded from  arg1+auxint+aux, arg2 = mem
-
-		{name: "ADDLloadidx1", argLength: 4, reg: gp21loadidx, asm: "ADDL", scale: 1, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"}, // arg0 + tmp, tmp loaded from  arg1+  arg2+auxint+aux, arg3 = mem
-		{name: "ADDLloadidx4", argLength: 4, reg: gp21loadidx, asm: "ADDL", scale: 4, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"}, // arg0 + tmp, tmp loaded from  arg1+4*arg2+auxint+aux, arg3 = mem
-		{name: "ADDLloadidx8", argLength: 4, reg: gp21loadidx, asm: "ADDL", scale: 8, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"}, // arg0 + tmp, tmp loaded from  arg1+8*arg2+auxint+aux, arg3 = mem
-		{name: "ADDQloadidx1", argLength: 4, reg: gp21loadidx, asm: "ADDQ", scale: 1, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"}, // arg0 + tmp, tmp loaded from  arg1+  arg2+auxint+aux, arg3 = mem
-		{name: "ADDQloadidx8", argLength: 4, reg: gp21loadidx, asm: "ADDQ", scale: 8, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"}, // arg0 + tmp, tmp loaded from  arg1+8*arg2+auxint+aux, arg3 = mem
-		{name: "SUBLloadidx1", argLength: 4, reg: gp21loadidx, asm: "SUBL", scale: 1, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"}, // arg0 - tmp, tmp loaded from  arg1+  arg2+auxint+aux, arg3 = mem
-		{name: "SUBLloadidx4", argLength: 4, reg: gp21loadidx, asm: "SUBL", scale: 4, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"}, // arg0 - tmp, tmp loaded from  arg1+4*arg2+auxint+aux, arg3 = mem
-		{name: "SUBLloadidx8", argLength: 4, reg: gp21loadidx, asm: "SUBL", scale: 8, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"}, // arg0 - tmp, tmp loaded from  arg1+8*arg2+auxint+aux, arg3 = mem
-		{name: "SUBQloadidx1", argLength: 4, reg: gp21loadidx, asm: "SUBQ", scale: 1, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"}, // arg0 - tmp, tmp loaded from  arg1+  arg2+auxint+aux, arg3 = mem
-		{name: "SUBQloadidx8", argLength: 4, reg: gp21loadidx, asm: "SUBQ", scale: 8, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"}, // arg0 - tmp, tmp loaded from  arg1+8*arg2+auxint+aux, arg3 = mem
-		{name: "ANDLloadidx1", argLength: 4, reg: gp21loadidx, asm: "ANDL", scale: 1, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"}, // arg0 & tmp, tmp loaded from  arg1+  arg2+auxint+aux, arg3 = mem
-		{name: "ANDLloadidx4", argLength: 4, reg: gp21loadidx, asm: "ANDL", scale: 4, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"}, // arg0 & tmp, tmp loaded from  arg1+4*arg2+auxint+aux, arg3 = mem
-		{name: "ANDLloadidx8", argLength: 4, reg: gp21loadidx, asm: "ANDL", scale: 8, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"}, // arg0 & tmp, tmp loaded from  arg1+8*arg2+auxint+aux, arg3 = mem
-		{name: "ANDQloadidx1", argLength: 4, reg: gp21loadidx, asm: "ANDQ", scale: 1, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"}, // arg0 & tmp, tmp loaded from  arg1+  arg2+auxint+aux, arg3 = mem
-		{name: "ANDQloadidx8", argLength: 4, reg: gp21loadidx, asm: "ANDQ", scale: 8, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"}, // arg0 & tmp, tmp loaded from  arg1+8*arg2+auxint+aux, arg3 = mem
-		{name: "ORLloadidx1", argLength: 4, reg: gp21loadidx, asm: "ORL", scale: 1, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},   // arg0 | tmp, tmp loaded from  arg1+  arg2+auxint+aux, arg3 = mem
-		{name: "ORLloadidx4", argLength: 4, reg: gp21loadidx, asm: "ORL", scale: 4, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},   // arg0 | tmp, tmp loaded from  arg1+4*arg2+auxint+aux, arg3 = mem
-		{name: "ORLloadidx8", argLength: 4, reg: gp21loadidx, asm: "ORL", scale: 8, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},   // arg0 | tmp, tmp loaded from  arg1+8*arg2+auxint+aux, arg3 = mem
-		{name: "ORQloadidx1", argLength: 4, reg: gp21loadidx, asm: "ORQ", scale: 1, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},   // arg0 | tmp, tmp loaded from  arg1+  arg2+auxint+aux, arg3 = mem
-		{name: "ORQloadidx8", argLength: 4, reg: gp21loadidx, asm: "ORQ", scale: 8, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"},   // arg0 | tmp, tmp loaded from  arg1+8*arg2+auxint+aux, arg3 = mem
-		{name: "XORLloadidx1", argLength: 4, reg: gp21loadidx, asm: "XORL", scale: 1, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"}, // arg0 ^ tmp, tmp loaded from  arg1+  arg2+auxint+aux, arg3 = mem
-		{name: "XORLloadidx4", argLength: 4, reg: gp21loadidx, asm: "XORL", scale: 4, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"}, // arg0 ^ tmp, tmp loaded from  arg1+4*arg2+auxint+aux, arg3 = mem
-		{name: "XORLloadidx8", argLength: 4, reg: gp21loadidx, asm: "XORL", scale: 8, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"}, // arg0 ^ tmp, tmp loaded from  arg1+8*arg2+auxint+aux, arg3 = mem
-		{name: "XORQloadidx1", argLength: 4, reg: gp21loadidx, asm: "XORQ", scale: 1, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"}, // arg0 ^ tmp, tmp loaded from  arg1+  arg2+auxint+aux, arg3 = mem
-		{name: "XORQloadidx8", argLength: 4, reg: gp21loadidx, asm: "XORQ", scale: 8, aux: "SymOff", resultInArg0: true, clobberFlags: true, symEffect: "Read"}, // arg0 ^ tmp, tmp loaded from  arg1+8*arg2+auxint+aux, arg3 = mem
-
-		// direct binary-op on memory (read-modify-write)
-		{name: "ADDQmodify", argLength: 3, reg: gpstore, asm: "ADDQ", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"}, // *(arg0+auxint+aux) += arg1, arg2=mem
-		{name: "SUBQmodify", argLength: 3, reg: gpstore, asm: "SUBQ", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"}, // *(arg0+auxint+aux) -= arg1, arg2=mem
-		{name: "ANDQmodify", argLength: 3, reg: gpstore, asm: "ANDQ", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"}, // *(arg0+auxint+aux) &= arg1, arg2=mem
-		{name: "ORQmodify", argLength: 3, reg: gpstore, asm: "ORQ", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"},   // *(arg0+auxint+aux) |= arg1, arg2=mem
-		{name: "XORQmodify", argLength: 3, reg: gpstore, asm: "XORQ", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"}, // *(arg0+auxint+aux) ^= arg1, arg2=mem
-		{name: "ADDLmodify", argLength: 3, reg: gpstore, asm: "ADDL", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"}, // *(arg0+auxint+aux) += arg1, arg2=mem
-		{name: "SUBLmodify", argLength: 3, reg: gpstore, asm: "SUBL", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"}, // *(arg0+auxint+aux) -= arg1, arg2=mem
-		{name: "ANDLmodify", argLength: 3, reg: gpstore, asm: "ANDL", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"}, // *(arg0+auxint+aux) &= arg1, arg2=mem
-		{name: "ORLmodify", argLength: 3, reg: gpstore, asm: "ORL", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"},   // *(arg0+auxint+aux) |= arg1, arg2=mem
-		{name: "XORLmodify", argLength: 3, reg: gpstore, asm: "XORL", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Read,Write"}, // *(arg0+auxint+aux) ^= arg1, arg2=mem
-
-		{name: "ADDQmodifyidx1", argLength: 4, reg: gpstoreidx, asm: "ADDQ", scale: 1, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+1*arg1+auxint+aux) += arg2, arg3=mem
-		{name: "ADDQmodifyidx8", argLength: 4, reg: gpstoreidx, asm: "ADDQ", scale: 8, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+8*arg1+auxint+aux) += arg2, arg3=mem
-		{name: "SUBQmodifyidx1", argLength: 4, reg: gpstoreidx, asm: "SUBQ", scale: 1, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+1*arg1+auxint+aux) -= arg2, arg3=mem
-		{name: "SUBQmodifyidx8", argLength: 4, reg: gpstoreidx, asm: "SUBQ", scale: 8, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+8*arg1+auxint+aux) -= arg2, arg3=mem
-		{name: "ANDQmodifyidx1", argLength: 4, reg: gpstoreidx, asm: "ANDQ", scale: 1, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+1*arg1+auxint+aux) &= arg2, arg3=mem
-		{name: "ANDQmodifyidx8", argLength: 4, reg: gpstoreidx, asm: "ANDQ", scale: 8, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+8*arg1+auxint+aux) &= arg2, arg3=mem
-		{name: "ORQmodifyidx1", argLength: 4, reg: gpstoreidx, asm: "ORQ", scale: 1, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},   // *(arg0+1*arg1+auxint+aux) |= arg2, arg3=mem
-		{name: "ORQmodifyidx8", argLength: 4, reg: gpstoreidx, asm: "ORQ", scale: 8, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},   // *(arg0+8*arg1+auxint+aux) |= arg2, arg3=mem
-		{name: "XORQmodifyidx1", argLength: 4, reg: gpstoreidx, asm: "XORQ", scale: 1, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+1*arg1+auxint+aux) ^= arg2, arg3=mem
-		{name: "XORQmodifyidx8", argLength: 4, reg: gpstoreidx, asm: "XORQ", scale: 8, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+8*arg1+auxint+aux) ^= arg2, arg3=mem
-		{name: "ADDLmodifyidx1", argLength: 4, reg: gpstoreidx, asm: "ADDL", scale: 1, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+1*arg1+auxint+aux) += arg2, arg3=mem
-		{name: "ADDLmodifyidx4", argLength: 4, reg: gpstoreidx, asm: "ADDL", scale: 4, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+4*arg1+auxint+aux) += arg2, arg3=mem
-		{name: "ADDLmodifyidx8", argLength: 4, reg: gpstoreidx, asm: "ADDL", scale: 8, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+8*arg1+auxint+aux) += arg2, arg3=mem
-		{name: "SUBLmodifyidx1", argLength: 4, reg: gpstoreidx, asm: "SUBL", scale: 1, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+1*arg1+auxint+aux) -= arg2, arg3=mem
-		{name: "SUBLmodifyidx4", argLength: 4, reg: gpstoreidx, asm: "SUBL", scale: 4, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+4*arg1+auxint+aux) -= arg2, arg3=mem
-		{name: "SUBLmodifyidx8", argLength: 4, reg: gpstoreidx, asm: "SUBL", scale: 8, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+8*arg1+auxint+aux) -= arg2, arg3=mem
-		{name: "ANDLmodifyidx1", argLength: 4, reg: gpstoreidx, asm: "ANDL", scale: 1, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+1*arg1+auxint+aux) &= arg2, arg3=mem
-		{name: "ANDLmodifyidx4", argLength: 4, reg: gpstoreidx, asm: "ANDL", scale: 4, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+4*arg1+auxint+aux) &= arg2, arg3=mem
-		{name: "ANDLmodifyidx8", argLength: 4, reg: gpstoreidx, asm: "ANDL", scale: 8, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+8*arg1+auxint+aux) &= arg2, arg3=mem
-		{name: "ORLmodifyidx1", argLength: 4, reg: gpstoreidx, asm: "ORL", scale: 1, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},   // *(arg0+1*arg1+auxint+aux) |= arg2, arg3=mem
-		{name: "ORLmodifyidx4", argLength: 4, reg: gpstoreidx, asm: "ORL", scale: 4, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},   // *(arg0+4*arg1+auxint+aux) |= arg2, arg3=mem
-		{name: "ORLmodifyidx8", argLength: 4, reg: gpstoreidx, asm: "ORL", scale: 8, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},   // *(arg0+8*arg1+auxint+aux) |= arg2, arg3=mem
-		{name: "XORLmodifyidx1", argLength: 4, reg: gpstoreidx, asm: "XORL", scale: 1, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+1*arg1+auxint+aux) ^= arg2, arg3=mem
-		{name: "XORLmodifyidx4", argLength: 4, reg: gpstoreidx, asm: "XORL", scale: 4, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+4*arg1+auxint+aux) ^= arg2, arg3=mem
-		{name: "XORLmodifyidx8", argLength: 4, reg: gpstoreidx, asm: "XORL", scale: 8, aux: "SymOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+8*arg1+auxint+aux) ^= arg2, arg3=mem
-
-		{name: "ADDQconstmodifyidx1", argLength: 3, reg: gpstoreconstidx, asm: "ADDQ", scale: 1, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+1*arg1+ValAndOff(AuxInt).Off()+aux) += ValAndOff(AuxInt).Val(), arg2=mem
-		{name: "ADDQconstmodifyidx8", argLength: 3, reg: gpstoreconstidx, asm: "ADDQ", scale: 8, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+8*arg1+ValAndOff(AuxInt).Off()+aux) += ValAndOff(AuxInt).Val(), arg2=mem
-		{name: "ANDQconstmodifyidx1", argLength: 3, reg: gpstoreconstidx, asm: "ANDQ", scale: 1, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+1*arg1+ValAndOff(AuxInt).Off()+aux) &= ValAndOff(AuxInt).Val(), arg2=mem
-		{name: "ANDQconstmodifyidx8", argLength: 3, reg: gpstoreconstidx, asm: "ANDQ", scale: 8, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+8*arg1+ValAndOff(AuxInt).Off()+aux) &= ValAndOff(AuxInt).Val(), arg2=mem
-		{name: "ORQconstmodifyidx1", argLength: 3, reg: gpstoreconstidx, asm: "ORQ", scale: 1, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},   // *(arg0+1*arg1+ValAndOff(AuxInt).Off()+aux) |= ValAndOff(AuxInt).Val(), arg2=mem
-		{name: "ORQconstmodifyidx8", argLength: 3, reg: gpstoreconstidx, asm: "ORQ", scale: 8, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},   // *(arg0+8*arg1+ValAndOff(AuxInt).Off()+aux) |= ValAndOff(AuxInt).Val(), arg2=mem
-		{name: "XORQconstmodifyidx1", argLength: 3, reg: gpstoreconstidx, asm: "XORQ", scale: 1, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+1*arg1+ValAndOff(AuxInt).Off()+aux) ^= ValAndOff(AuxInt).Val(), arg2=mem
-		{name: "XORQconstmodifyidx8", argLength: 3, reg: gpstoreconstidx, asm: "XORQ", scale: 8, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+8*arg1+ValAndOff(AuxInt).Off()+aux) ^= ValAndOff(AuxInt).Val(), arg2=mem
-		{name: "ADDLconstmodifyidx1", argLength: 3, reg: gpstoreconstidx, asm: "ADDL", scale: 1, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+1*arg1+ValAndOff(AuxInt).Off()+aux) += ValAndOff(AuxInt).Val(), arg2=mem
-		{name: "ADDLconstmodifyidx4", argLength: 3, reg: gpstoreconstidx, asm: "ADDL", scale: 4, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+4*arg1+ValAndOff(AuxInt).Off()+aux) += ValAndOff(AuxInt).Val(), arg2=mem
-		{name: "ADDLconstmodifyidx8", argLength: 3, reg: gpstoreconstidx, asm: "ADDL", scale: 8, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+8*arg1+ValAndOff(AuxInt).Off()+aux) += ValAndOff(AuxInt).Val(), arg2=mem
-		{name: "ANDLconstmodifyidx1", argLength: 3, reg: gpstoreconstidx, asm: "ANDL", scale: 1, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+1*arg1+ValAndOff(AuxInt).Off()+aux) &= ValAndOff(AuxInt).Val(), arg2=mem
-		{name: "ANDLconstmodifyidx4", argLength: 3, reg: gpstoreconstidx, asm: "ANDL", scale: 4, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+4*arg1+ValAndOff(AuxInt).Off()+aux) &= ValAndOff(AuxInt).Val(), arg2=mem
-		{name: "ANDLconstmodifyidx8", argLength: 3, reg: gpstoreconstidx, asm: "ANDL", scale: 8, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+8*arg1+ValAndOff(AuxInt).Off()+aux) &= ValAndOff(AuxInt).Val(), arg2=mem
-		{name: "ORLconstmodifyidx1", argLength: 3, reg: gpstoreconstidx, asm: "ORL", scale: 1, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},   // *(arg0+1*arg1+ValAndOff(AuxInt).Off()+aux) |= ValAndOff(AuxInt).Val(), arg2=mem
-		{name: "ORLconstmodifyidx4", argLength: 3, reg: gpstoreconstidx, asm: "ORL", scale: 4, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},   // *(arg0+4*arg1+ValAndOff(AuxInt).Off()+aux) |= ValAndOff(AuxInt).Val(), arg2=mem
-		{name: "ORLconstmodifyidx8", argLength: 3, reg: gpstoreconstidx, asm: "ORL", scale: 8, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"},   // *(arg0+8*arg1+ValAndOff(AuxInt).Off()+aux) |= ValAndOff(AuxInt).Val(), arg2=mem
-		{name: "XORLconstmodifyidx1", argLength: 3, reg: gpstoreconstidx, asm: "XORL", scale: 1, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+1*arg1+ValAndOff(AuxInt).Off()+aux) ^= ValAndOff(AuxInt).Val(), arg2=mem
-		{name: "XORLconstmodifyidx4", argLength: 3, reg: gpstoreconstidx, asm: "XORL", scale: 4, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+4*arg1+ValAndOff(AuxInt).Off()+aux) ^= ValAndOff(AuxInt).Val(), arg2=mem
-		{name: "XORLconstmodifyidx8", argLength: 3, reg: gpstoreconstidx, asm: "XORL", scale: 8, aux: "SymValAndOff", typ: "Mem", clobberFlags: true, symEffect: "Read,Write"}, // *(arg0+8*arg1+ValAndOff(AuxInt).Off()+aux) ^= ValAndOff(AuxInt).Val(), arg2=mem
-
-		// unary ops
-		{name: "NEGQ", argLength: 1, reg: gp11, asm: "NEGQ", resultInArg0: true, clobberFlags: true}, // -arg0
-		{name: "NEGL", argLength: 1, reg: gp11, asm: "NEGL", resultInArg0: true, clobberFlags: true}, // -arg0
-
-		{name: "NOTQ", argLength: 1, reg: gp11, asm: "NOTQ", resultInArg0: true}, // ^arg0
-		{name: "NOTL", argLength: 1, reg: gp11, asm: "NOTL", resultInArg0: true}, // ^arg0
-
-		// BS{F,R}Q returns a tuple [result, flags]
-		// result is undefined if the input is zero.
-		// flags are set to "equal" if the input is zero, "not equal" otherwise.
-		// BS{F,R}L returns only the result.
-		{name: "BSFQ", argLength: 1, reg: gp11flags, asm: "BSFQ", typ: "(UInt64,Flags)"},        // # of low-order zeroes in 64-bit arg
-		{name: "BSFL", argLength: 1, reg: gp11, asm: "BSFL", typ: "UInt32", clobberFlags: true}, // # of low-order zeroes in 32-bit arg
-		{name: "BSRQ", argLength: 1, reg: gp11flags, asm: "BSRQ", typ: "(UInt64,Flags)"},        // # of high-order zeroes in 64-bit arg
-		{name: "BSRL", argLength: 1, reg: gp11, asm: "BSRL", typ: "UInt32", clobberFlags: true}, // # of high-order zeroes in 32-bit arg
-
-		// CMOV instructions: 64, 32 and 16-bit sizes.
-		// if arg2 encodes a true result, return arg1, else arg0
-		{name: "CMOVQEQ", argLength: 3, reg: gp21, asm: "CMOVQEQ", resultInArg0: true},
-		{name: "CMOVQNE", argLength: 3, reg: gp21, asm: "CMOVQNE", resultInArg0: true},
-		{name: "CMOVQLT", argLength: 3, reg: gp21, asm: "CMOVQLT", resultInArg0: true},
-		{name: "CMOVQGT", argLength: 3, reg: gp21, asm: "CMOVQGT", resultInArg0: true},
-		{name: "CMOVQLE", argLength: 3, reg: gp21, asm: "CMOVQLE", resultInArg0: true},
-		{name: "CMOVQGE", argLength: 3, reg: gp21, asm: "CMOVQGE", resultInArg0: true},
-		{name: "CMOVQLS", argLength: 3, reg: gp21, asm: "CMOVQLS", resultInArg0: true},
-		{name: "CMOVQHI", argLength: 3, reg: gp21, asm: "CMOVQHI", resultInArg0: true},
-		{name: "CMOVQCC", argLength: 3, reg: gp21, asm: "CMOVQCC", resultInArg0: true},
-		{name: "CMOVQCS", argLength: 3, reg: gp21, asm: "CMOVQCS", resultInArg0: true},
-
-		{name: "CMOVLEQ", argLength: 3, reg: gp21, asm: "CMOVLEQ", resultInArg0: true},
-		{name: "CMOVLNE", argLength: 3, reg: gp21, asm: "CMOVLNE", resultInArg0: true},
-		{name: "CMOVLLT", argLength: 3, reg: gp21, asm: "CMOVLLT", resultInArg0: true},
-		{name: "CMOVLGT", argLength: 3, reg: gp21, asm: "CMOVLGT", resultInArg0: true},
-		{name: "CMOVLLE", argLength: 3, reg: gp21, asm: "CMOVLLE", resultInArg0: true},
-		{name: "CMOVLGE", argLength: 3, reg: gp21, asm: "CMOVLGE", resultInArg0: true},
-		{name: "CMOVLLS", argLength: 3, reg: gp21, asm: "CMOVLLS", resultInArg0: true},
-		{name: "CMOVLHI", argLength: 3, reg: gp21, asm: "CMOVLHI", resultInArg0: true},
-		{name: "CMOVLCC", argLength: 3, reg: gp21, asm: "CMOVLCC", resultInArg0: true},
-		{name: "CMOVLCS", argLength: 3, reg: gp21, asm: "CMOVLCS", resultInArg0: true},
-
-		{name: "CMOVWEQ", argLength: 3, reg: gp21, asm: "CMOVWEQ", resultInArg0: true},
-		{name: "CMOVWNE", argLength: 3, reg: gp21, asm: "CMOVWNE", resultInArg0: true},
-		{name: "CMOVWLT", argLength: 3, reg: gp21, asm: "CMOVWLT", resultInArg0: true},
-		{name: "CMOVWGT", argLength: 3, reg: gp21, asm: "CMOVWGT", resultInArg0: true},
-		{name: "CMOVWLE", argLength: 3, reg: gp21, asm: "CMOVWLE", resultInArg0: true},
-		{name: "CMOVWGE", argLength: 3, reg: gp21, asm: "CMOVWGE", resultInArg0: true},
-		{name: "CMOVWLS", argLength: 3, reg: gp21, asm: "CMOVWLS", resultInArg0: true},
-		{name: "CMOVWHI", argLength: 3, reg: gp21, asm: "CMOVWHI", resultInArg0: true},
-		{name: "CMOVWCC", argLength: 3, reg: gp21, asm: "CMOVWCC", resultInArg0: true},
-		{name: "CMOVWCS", argLength: 3, reg: gp21, asm: "CMOVWCS", resultInArg0: true},
-
-		// CMOV with floating point instructions. We need separate pseudo-op to handle
-		// InvertFlags correctly, and to generate special code that handles NaN (unordered flag).
-		// NOTE: the fact that CMOV*EQF here is marked to generate CMOV*NE is not a bug. See
-		// code generation in amd64/ssa.go.
-		{name: "CMOVQEQF", argLength: 3, reg: gp21pax, asm: "CMOVQNE", resultInArg0: true},
-		{name: "CMOVQNEF", argLength: 3, reg: gp21, asm: "CMOVQNE", resultInArg0: true},
-		{name: "CMOVQGTF", argLength: 3, reg: gp21, asm: "CMOVQHI", resultInArg0: true},
-		{name: "CMOVQGEF", argLength: 3, reg: gp21, asm: "CMOVQCC", resultInArg0: true},
-		{name: "CMOVLEQF", argLength: 3, reg: gp21pax, asm: "CMOVLNE", resultInArg0: true},
-		{name: "CMOVLNEF", argLength: 3, reg: gp21, asm: "CMOVLNE", resultInArg0: true},
-		{name: "CMOVLGTF", argLength: 3, reg: gp21, asm: "CMOVLHI", resultInArg0: true},
-		{name: "CMOVLGEF", argLength: 3, reg: gp21, asm: "CMOVLCC", resultInArg0: true},
-		{name: "CMOVWEQF", argLength: 3, reg: gp21pax, asm: "CMOVWNE", resultInArg0: true},
-		{name: "CMOVWNEF", argLength: 3, reg: gp21, asm: "CMOVWNE", resultInArg0: true},
-		{name: "CMOVWGTF", argLength: 3, reg: gp21, asm: "CMOVWHI", resultInArg0: true},
-		{name: "CMOVWGEF", argLength: 3, reg: gp21, asm: "CMOVWCC", resultInArg0: true},
-
-		{name: "BSWAPQ", argLength: 1, reg: gp11, asm: "BSWAPQ", resultInArg0: true}, // arg0 swap bytes
-		{name: "BSWAPL", argLength: 1, reg: gp11, asm: "BSWAPL", resultInArg0: true}, // arg0 swap bytes
-
-		// POPCNT instructions aren't guaranteed to be on the target platform (they are SSE4).
-		// Any use must be preceded by a successful check of runtime.x86HasPOPCNT.
-		{name: "POPCNTQ", argLength: 1, reg: gp11, asm: "POPCNTQ", clobberFlags: true}, // count number of set bits in arg0
-		{name: "POPCNTL", argLength: 1, reg: gp11, asm: "POPCNTL", clobberFlags: true}, // count number of set bits in arg0
-
-		{name: "SQRTSD", argLength: 1, reg: fp11, asm: "SQRTSD"}, // sqrt(arg0)
-		{name: "SQRTSS", argLength: 1, reg: fp11, asm: "SQRTSS"}, // sqrt(arg0), float32
-
-		// ROUNDSD instruction isn't guaranteed to be on the target platform (it is SSE4.1)
-		// Any use must be preceded by a successful check of runtime.x86HasSSE41.
-		{name: "ROUNDSD", argLength: 1, reg: fp11, aux: "Int8", asm: "ROUNDSD"}, // rounds arg0 depending on auxint, 1 means math.Floor, 2 Ceil, 3 Trunc
-
-		// VFMADD231SD only exists on platforms with the FMA3 instruction set.
-		// Any use must be preceded by a successful check of runtime.support_fma.
-		{name: "VFMADD231SD", argLength: 3, reg: fp31, resultInArg0: true, asm: "VFMADD231SD"},
-
-		{name: "SBBQcarrymask", argLength: 1, reg: flagsgp, asm: "SBBQ"}, // (int64)(-1) if carry is set, 0 if carry is clear.
-		{name: "SBBLcarrymask", argLength: 1, reg: flagsgp, asm: "SBBL"}, // (int32)(-1) if carry is set, 0 if carry is clear.
-		// Note: SBBW and SBBB are subsumed by SBBL
-
-		{name: "SETEQ", argLength: 1, reg: readflags, asm: "SETEQ"}, // extract == condition from arg0
-		{name: "SETNE", argLength: 1, reg: readflags, asm: "SETNE"}, // extract != condition from arg0
-		{name: "SETL", argLength: 1, reg: readflags, asm: "SETLT"},  // extract signed < condition from arg0
-		{name: "SETLE", argLength: 1, reg: readflags, asm: "SETLE"}, // extract signed <= condition from arg0
-		{name: "SETG", argLength: 1, reg: readflags, asm: "SETGT"},  // extract signed > condition from arg0
-		{name: "SETGE", argLength: 1, reg: readflags, asm: "SETGE"}, // extract signed >= condition from arg0
-		{name: "SETB", argLength: 1, reg: readflags, asm: "SETCS"},  // extract unsigned < condition from arg0
-		{name: "SETBE", argLength: 1, reg: readflags, asm: "SETLS"}, // extract unsigned <= condition from arg0
-		{name: "SETA", argLength: 1, reg: readflags, asm: "SETHI"},  // extract unsigned > condition from arg0
-		{name: "SETAE", argLength: 1, reg: readflags, asm: "SETCC"}, // extract unsigned >= condition from arg0
-		{name: "SETO", argLength: 1, reg: readflags, asm: "SETOS"},  // extract if overflow flag is set from arg0
-		// Variants that store result to memory
-		{name: "SETEQstore", argLength: 3, reg: gpstoreconst, asm: "SETEQ", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // extract == condition from arg1 to arg0+auxint+aux, arg2=mem
-		{name: "SETNEstore", argLength: 3, reg: gpstoreconst, asm: "SETNE", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // extract != condition from arg1 to arg0+auxint+aux, arg2=mem
-		{name: "SETLstore", argLength: 3, reg: gpstoreconst, asm: "SETLT", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},  // extract signed < condition from arg1 to arg0+auxint+aux, arg2=mem
-		{name: "SETLEstore", argLength: 3, reg: gpstoreconst, asm: "SETLE", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // extract signed <= condition from arg1 to arg0+auxint+aux, arg2=mem
-		{name: "SETGstore", argLength: 3, reg: gpstoreconst, asm: "SETGT", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},  // extract signed > condition from arg1 to arg0+auxint+aux, arg2=mem
-		{name: "SETGEstore", argLength: 3, reg: gpstoreconst, asm: "SETGE", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // extract signed >= condition from arg1 to arg0+auxint+aux, arg2=mem
-		{name: "SETBstore", argLength: 3, reg: gpstoreconst, asm: "SETCS", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},  // extract unsigned < condition from arg1 to arg0+auxint+aux, arg2=mem
-		{name: "SETBEstore", argLength: 3, reg: gpstoreconst, asm: "SETLS", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // extract unsigned <= condition from arg1 to arg0+auxint+aux, arg2=mem
-		{name: "SETAstore", argLength: 3, reg: gpstoreconst, asm: "SETHI", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},  // extract unsigned > condition from arg1 to arg0+auxint+aux, arg2=mem
-		{name: "SETAEstore", argLength: 3, reg: gpstoreconst, asm: "SETCC", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // extract unsigned >= condition from arg1 to arg0+auxint+aux, arg2=mem
-		// Need different opcodes for floating point conditions because
-		// any comparison involving a NaN is always FALSE and thus
-		// the patterns for inverting conditions cannot be used.
-		{name: "SETEQF", argLength: 1, reg: flagsgpax, asm: "SETEQ", clobberFlags: true}, // extract == condition from arg0
-		{name: "SETNEF", argLength: 1, reg: flagsgpax, asm: "SETNE", clobberFlags: true}, // extract != condition from arg0
-		{name: "SETORD", argLength: 1, reg: flagsgp, asm: "SETPC"},                       // extract "ordered" (No Nan present) condition from arg0
-		{name: "SETNAN", argLength: 1, reg: flagsgp, asm: "SETPS"},                       // extract "unordered" (Nan present) condition from arg0
-
-		{name: "SETGF", argLength: 1, reg: flagsgp, asm: "SETHI"},  // extract floating > condition from arg0
-		{name: "SETGEF", argLength: 1, reg: flagsgp, asm: "SETCC"}, // extract floating >= condition from arg0
-
-		{name: "MOVBQSX", argLength: 1, reg: gp11, asm: "MOVBQSX"}, // sign extend arg0 from int8 to int64
-		{name: "MOVBQZX", argLength: 1, reg: gp11, asm: "MOVBLZX"}, // zero extend arg0 from int8 to int64
-		{name: "MOVWQSX", argLength: 1, reg: gp11, asm: "MOVWQSX"}, // sign extend arg0 from int16 to int64
-		{name: "MOVWQZX", argLength: 1, reg: gp11, asm: "MOVWLZX"}, // zero extend arg0 from int16 to int64
-		{name: "MOVLQSX", argLength: 1, reg: gp11, asm: "MOVLQSX"}, // sign extend arg0 from int32 to int64
-		{name: "MOVLQZX", argLength: 1, reg: gp11, asm: "MOVL"},    // zero extend arg0 from int32 to int64
-
-		{name: "MOVLconst", reg: gp01, asm: "MOVL", typ: "UInt32", aux: "Int32", rematerializeable: true}, // 32 low bits of auxint
-		{name: "MOVQconst", reg: gp01, asm: "MOVQ", typ: "UInt64", aux: "Int64", rematerializeable: true}, // auxint
-
-		{name: "CVTTSD2SL", argLength: 1, reg: fpgp, asm: "CVTTSD2SL"}, // convert float64 to int32
-		{name: "CVTTSD2SQ", argLength: 1, reg: fpgp, asm: "CVTTSD2SQ"}, // convert float64 to int64
-		{name: "CVTTSS2SL", argLength: 1, reg: fpgp, asm: "CVTTSS2SL"}, // convert float32 to int32
-		{name: "CVTTSS2SQ", argLength: 1, reg: fpgp, asm: "CVTTSS2SQ"}, // convert float32 to int64
-		{name: "CVTSL2SS", argLength: 1, reg: gpfp, asm: "CVTSL2SS"},   // convert int32 to float32
-		{name: "CVTSL2SD", argLength: 1, reg: gpfp, asm: "CVTSL2SD"},   // convert int32 to float64
-		{name: "CVTSQ2SS", argLength: 1, reg: gpfp, asm: "CVTSQ2SS"},   // convert int64 to float32
-		{name: "CVTSQ2SD", argLength: 1, reg: gpfp, asm: "CVTSQ2SD"},   // convert int64 to float64
-		{name: "CVTSD2SS", argLength: 1, reg: fp11, asm: "CVTSD2SS"},   // convert float64 to float32
-		{name: "CVTSS2SD", argLength: 1, reg: fp11, asm: "CVTSS2SD"},   // convert float32 to float64
-
-		// Move values between int and float registers, with no conversion.
-		// TODO: should we have generic versions of these?
-		{name: "MOVQi2f", argLength: 1, reg: gpfp, typ: "Float64"}, // move 64 bits from int to float reg
-		{name: "MOVQf2i", argLength: 1, reg: fpgp, typ: "UInt64"},  // move 64 bits from float to int reg
-		{name: "MOVLi2f", argLength: 1, reg: gpfp, typ: "Float32"}, // move 32 bits from int to float reg
-		{name: "MOVLf2i", argLength: 1, reg: fpgp, typ: "UInt32"},  // move 32 bits from float to int reg, zero extend
-
-		{name: "PXOR", argLength: 2, reg: fp21, asm: "PXOR", commutative: true, resultInArg0: true}, // exclusive or, applied to X regs for float negation.
-
-		{name: "LEAQ", argLength: 1, reg: gp11sb, asm: "LEAQ", aux: "SymOff", rematerializeable: true, symEffect: "Addr"},      // arg0 + auxint + offset encoded in aux
-		{name: "LEAL", argLength: 1, reg: gp11sb, asm: "LEAL", aux: "SymOff", rematerializeable: true, symEffect: "Addr"},      // arg0 + auxint + offset encoded in aux
-		{name: "LEAW", argLength: 1, reg: gp11sb, asm: "LEAW", aux: "SymOff", rematerializeable: true, symEffect: "Addr"},      // arg0 + auxint + offset encoded in aux
-		{name: "LEAQ1", argLength: 2, reg: gp21sb, asm: "LEAQ", scale: 1, commutative: true, aux: "SymOff", symEffect: "Addr"}, // arg0 + arg1 + auxint + aux
-		{name: "LEAL1", argLength: 2, reg: gp21sb, asm: "LEAL", scale: 1, commutative: true, aux: "SymOff", symEffect: "Addr"}, // arg0 + arg1 + auxint + aux
-		{name: "LEAW1", argLength: 2, reg: gp21sb, asm: "LEAW", scale: 1, commutative: true, aux: "SymOff", symEffect: "Addr"}, // arg0 + arg1 + auxint + aux
-		{name: "LEAQ2", argLength: 2, reg: gp21sb, asm: "LEAQ", scale: 2, aux: "SymOff", symEffect: "Addr"},                    // arg0 + 2*arg1 + auxint + aux
-		{name: "LEAL2", argLength: 2, reg: gp21sb, asm: "LEAL", scale: 2, aux: "SymOff", symEffect: "Addr"},                    // arg0 + 2*arg1 + auxint + aux
-		{name: "LEAW2", argLength: 2, reg: gp21sb, asm: "LEAW", scale: 2, aux: "SymOff", symEffect: "Addr"},                    // arg0 + 2*arg1 + auxint + aux
-		{name: "LEAQ4", argLength: 2, reg: gp21sb, asm: "LEAQ", scale: 4, aux: "SymOff", symEffect: "Addr"},                    // arg0 + 4*arg1 + auxint + aux
-		{name: "LEAL4", argLength: 2, reg: gp21sb, asm: "LEAL", scale: 4, aux: "SymOff", symEffect: "Addr"},                    // arg0 + 4*arg1 + auxint + aux
-		{name: "LEAW4", argLength: 2, reg: gp21sb, asm: "LEAW", scale: 4, aux: "SymOff", symEffect: "Addr"},                    // arg0 + 4*arg1 + auxint + aux
-		{name: "LEAQ8", argLength: 2, reg: gp21sb, asm: "LEAQ", scale: 8, aux: "SymOff", symEffect: "Addr"},                    // arg0 + 8*arg1 + auxint + aux
-		{name: "LEAL8", argLength: 2, reg: gp21sb, asm: "LEAL", scale: 8, aux: "SymOff", symEffect: "Addr"},                    // arg0 + 8*arg1 + auxint + aux
-		{name: "LEAW8", argLength: 2, reg: gp21sb, asm: "LEAW", scale: 8, aux: "SymOff", symEffect: "Addr"},                    // arg0 + 8*arg1 + auxint + aux
-		// Note: LEAx{1,2,4,8} must not have OpSB as either argument.
-
-		// auxint+aux == add auxint and the offset of the symbol in aux (if any) to the effective address
-		{name: "MOVBload", argLength: 2, reg: gpload, asm: "MOVBLZX", aux: "SymOff", typ: "UInt8", faultOnNilArg0: true, symEffect: "Read"},  // load byte from arg0+auxint+aux. arg1=mem.  Zero extend.
-		{name: "MOVBQSXload", argLength: 2, reg: gpload, asm: "MOVBQSX", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},             // ditto, sign extend to int64
-		{name: "MOVWload", argLength: 2, reg: gpload, asm: "MOVWLZX", aux: "SymOff", typ: "UInt16", faultOnNilArg0: true, symEffect: "Read"}, // load 2 bytes from arg0+auxint+aux. arg1=mem.  Zero extend.
-		{name: "MOVWQSXload", argLength: 2, reg: gpload, asm: "MOVWQSX", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},             // ditto, sign extend to int64
-		{name: "MOVLload", argLength: 2, reg: gpload, asm: "MOVL", aux: "SymOff", typ: "UInt32", faultOnNilArg0: true, symEffect: "Read"},    // load 4 bytes from arg0+auxint+aux. arg1=mem.  Zero extend.
-		{name: "MOVLQSXload", argLength: 2, reg: gpload, asm: "MOVLQSX", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},             // ditto, sign extend to int64
-		{name: "MOVQload", argLength: 2, reg: gpload, asm: "MOVQ", aux: "SymOff", typ: "UInt64", faultOnNilArg0: true, symEffect: "Read"},    // load 8 bytes from arg0+auxint+aux. arg1=mem
-		{name: "MOVBstore", argLength: 3, reg: gpstore, asm: "MOVB", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},    // store byte in arg1 to arg0+auxint+aux. arg2=mem
-		{name: "MOVWstore", argLength: 3, reg: gpstore, asm: "MOVW", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},    // store 2 bytes in arg1 to arg0+auxint+aux. arg2=mem
-		{name: "MOVLstore", argLength: 3, reg: gpstore, asm: "MOVL", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},    // store 4 bytes in arg1 to arg0+auxint+aux. arg2=mem
-		{name: "MOVQstore", argLength: 3, reg: gpstore, asm: "MOVQ", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},    // store 8 bytes in arg1 to arg0+auxint+aux. arg2=mem
-		{name: "MOVOload", argLength: 2, reg: fpload, asm: "MOVUPS", aux: "SymOff", typ: "Int128", faultOnNilArg0: true, symEffect: "Read"},  // load 16 bytes from arg0+auxint+aux. arg1=mem
-		{name: "MOVOstore", argLength: 3, reg: fpstore, asm: "MOVUPS", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},  // store 16 bytes in arg1 to arg0+auxint+aux. arg2=mem
-
-		// indexed loads/stores
-		{name: "MOVBloadidx1", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVBLZX", scale: 1, aux: "SymOff", typ: "UInt8", symEffect: "Read"},  // load a byte from arg0+arg1+auxint+aux. arg2=mem
-		{name: "MOVWloadidx1", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVWLZX", scale: 1, aux: "SymOff", typ: "UInt16", symEffect: "Read"}, // load 2 bytes from arg0+arg1+auxint+aux. arg2=mem
-		{name: "MOVWloadidx2", argLength: 3, reg: gploadidx, asm: "MOVWLZX", scale: 2, aux: "SymOff", typ: "UInt16", symEffect: "Read"},                    // load 2 bytes from arg0+2*arg1+auxint+aux. arg2=mem
-		{name: "MOVLloadidx1", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVL", scale: 1, aux: "SymOff", typ: "UInt32", symEffect: "Read"},    // load 4 bytes from arg0+arg1+auxint+aux. arg2=mem
-		{name: "MOVLloadidx4", argLength: 3, reg: gploadidx, asm: "MOVL", scale: 4, aux: "SymOff", typ: "UInt32", symEffect: "Read"},                       // load 4 bytes from arg0+4*arg1+auxint+aux. arg2=mem
-		{name: "MOVLloadidx8", argLength: 3, reg: gploadidx, asm: "MOVL", scale: 8, aux: "SymOff", typ: "UInt32", symEffect: "Read"},                       // load 4 bytes from arg0+8*arg1+auxint+aux. arg2=mem
-		{name: "MOVQloadidx1", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVQ", scale: 1, aux: "SymOff", typ: "UInt64", symEffect: "Read"},    // load 8 bytes from arg0+arg1+auxint+aux. arg2=mem
-		{name: "MOVQloadidx8", argLength: 3, reg: gploadidx, asm: "MOVQ", scale: 8, aux: "SymOff", typ: "UInt64", symEffect: "Read"},                       // load 8 bytes from arg0+8*arg1+auxint+aux. arg2=mem
-		// TODO: sign-extending indexed loads
-		{name: "MOVBstoreidx1", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVB", scale: 1, aux: "SymOff", symEffect: "Write"}, // store byte in arg2 to arg0+arg1+auxint+aux. arg3=mem
-		{name: "MOVWstoreidx1", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVW", scale: 1, aux: "SymOff", symEffect: "Write"}, // store 2 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem
-		{name: "MOVWstoreidx2", argLength: 4, reg: gpstoreidx, asm: "MOVW", scale: 2, aux: "SymOff", symEffect: "Write"},                    // store 2 bytes in arg2 to arg0+2*arg1+auxint+aux. arg3=mem
-		{name: "MOVLstoreidx1", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVL", scale: 1, aux: "SymOff", symEffect: "Write"}, // store 4 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem
-		{name: "MOVLstoreidx4", argLength: 4, reg: gpstoreidx, asm: "MOVL", scale: 4, aux: "SymOff", symEffect: "Write"},                    // store 4 bytes in arg2 to arg0+4*arg1+auxint+aux. arg3=mem
-		{name: "MOVLstoreidx8", argLength: 4, reg: gpstoreidx, asm: "MOVL", scale: 8, aux: "SymOff", symEffect: "Write"},                    // store 4 bytes in arg2 to arg0+8*arg1+auxint+aux. arg3=mem
-		{name: "MOVQstoreidx1", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVQ", scale: 1, aux: "SymOff", symEffect: "Write"}, // store 8 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem
-		{name: "MOVQstoreidx8", argLength: 4, reg: gpstoreidx, asm: "MOVQ", scale: 8, aux: "SymOff", symEffect: "Write"},                    // store 8 bytes in arg2 to arg0+8*arg1+auxint+aux. arg3=mem
-		// TODO: add size-mismatched indexed loads, like MOVBstoreidx4.
-
-		// For storeconst ops, the AuxInt field encodes both
-		// the value to store and an address offset of the store.
-		// Cast AuxInt to a ValAndOff to extract Val and Off fields.
-		{name: "MOVBstoreconst", argLength: 2, reg: gpstoreconst, asm: "MOVB", aux: "SymValAndOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},   // store low byte of ValAndOff(AuxInt).Val() to arg0+ValAndOff(AuxInt).Off()+aux.  arg1=mem
-		{name: "MOVWstoreconst", argLength: 2, reg: gpstoreconst, asm: "MOVW", aux: "SymValAndOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},   // store low 2 bytes of ...
-		{name: "MOVLstoreconst", argLength: 2, reg: gpstoreconst, asm: "MOVL", aux: "SymValAndOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},   // store low 4 bytes of ...
-		{name: "MOVQstoreconst", argLength: 2, reg: gpstoreconst, asm: "MOVQ", aux: "SymValAndOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},   // store 8 bytes of ...
-		{name: "MOVOstoreconst", argLength: 2, reg: gpstoreconst, asm: "MOVUPS", aux: "SymValAndOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 16 bytes of ...
-
-		{name: "MOVBstoreconstidx1", argLength: 3, reg: gpstoreconstidx, commutative: true, asm: "MOVB", scale: 1, aux: "SymValAndOff", typ: "Mem", symEffect: "Write"}, // store low byte of ValAndOff(AuxInt).Val() to arg0+1*arg1+ValAndOff(AuxInt).Off()+aux.  arg2=mem
-		{name: "MOVWstoreconstidx1", argLength: 3, reg: gpstoreconstidx, commutative: true, asm: "MOVW", scale: 1, aux: "SymValAndOff", typ: "Mem", symEffect: "Write"}, // store low 2 bytes of ... arg1 ...
-		{name: "MOVWstoreconstidx2", argLength: 3, reg: gpstoreconstidx, asm: "MOVW", scale: 2, aux: "SymValAndOff", typ: "Mem", symEffect: "Write"},                    // store low 2 bytes of ... 2*arg1 ...
-		{name: "MOVLstoreconstidx1", argLength: 3, reg: gpstoreconstidx, commutative: true, asm: "MOVL", scale: 1, aux: "SymValAndOff", typ: "Mem", symEffect: "Write"}, // store low 4 bytes of ... arg1 ...
-		{name: "MOVLstoreconstidx4", argLength: 3, reg: gpstoreconstidx, asm: "MOVL", scale: 4, aux: "SymValAndOff", typ: "Mem", symEffect: "Write"},                    // store low 4 bytes of ... 4*arg1 ...
-		{name: "MOVQstoreconstidx1", argLength: 3, reg: gpstoreconstidx, commutative: true, asm: "MOVQ", scale: 1, aux: "SymValAndOff", typ: "Mem", symEffect: "Write"}, // store 8 bytes of ... arg1 ...
-		{name: "MOVQstoreconstidx8", argLength: 3, reg: gpstoreconstidx, asm: "MOVQ", scale: 8, aux: "SymValAndOff", typ: "Mem", symEffect: "Write"},                    // store 8 bytes of ... 8*arg1 ...
-
-		// arg0 = pointer to start of memory to zero
-		// arg1 = mem
-		// auxint = # of bytes to zero
-		// returns mem
-		{
-			name:      "DUFFZERO",
-			aux:       "Int64",
-			argLength: 2,
-			reg: regInfo{
-				inputs:   []regMask{buildReg("DI")},
-				clobbers: buildReg("DI"),
-			},
-			faultOnNilArg0: true,
-			unsafePoint:    true, // FP maintenance around DUFFCOPY can be clobbered by interrupts
-		},
-
-		// arg0 = address of memory to zero
-		// arg1 = # of 8-byte words to zero
-		// arg2 = value to store (will always be zero)
-		// arg3 = mem
-		// returns mem
-		{
-			name:      "REPSTOSQ",
-			argLength: 4,
-			reg: regInfo{
-				inputs:   []regMask{buildReg("DI"), buildReg("CX"), buildReg("AX")},
-				clobbers: buildReg("DI CX"),
-			},
-			faultOnNilArg0: true,
-		},
-
-		// With a register ABI, the actual register info for these instructions (i.e., what is used in regalloc) is augmented with per-call-site bindings of additional arguments to specific in and out registers.
-		{name: "CALLstatic", argLength: -1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                                              // call static function aux.(*obj.LSym).  last arg=mem, auxint=argsize, returns mem
-		{name: "CALLtail", argLength: -1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true, tailCall: true},                                // tail call static function aux.(*obj.LSym).  last arg=mem, auxint=argsize, returns mem
-		{name: "CALLclosure", argLength: -1, reg: regInfo{inputs: []regMask{gpsp, buildReg("DX"), 0}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call function via closure.  arg0=codeptr, arg1=closure, last arg=mem, auxint=argsize, returns mem
-		{name: "CALLinter", argLength: -1, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                        // call fn by pointer.  arg0=codeptr, last arg=mem, auxint=argsize, returns mem
-
-		// arg0 = destination pointer
-		// arg1 = source pointer
-		// arg2 = mem
-		// auxint = # of bytes to copy, must be multiple of 16
-		// returns memory
-		{
-			name:      "DUFFCOPY",
-			aux:       "Int64",
-			argLength: 3,
-			reg: regInfo{
-				inputs:   []regMask{buildReg("DI"), buildReg("SI")},
-				clobbers: buildReg("DI SI X0"), // uses X0 as a temporary
-			},
-			clobberFlags:   true,
-			faultOnNilArg0: true,
-			faultOnNilArg1: true,
-			unsafePoint:    true, // FP maintenance around DUFFCOPY can be clobbered by interrupts
-		},
-
-		// arg0 = destination pointer
-		// arg1 = source pointer
-		// arg2 = # of 8-byte words to copy
-		// arg3 = mem
-		// returns memory
-		{
-			name:      "REPMOVSQ",
-			argLength: 4,
-			reg: regInfo{
-				inputs:   []regMask{buildReg("DI"), buildReg("SI"), buildReg("CX")},
-				clobbers: buildReg("DI SI CX"),
-			},
-			faultOnNilArg0: true,
-			faultOnNilArg1: true,
-		},
-
-		// (InvertFlags (CMPQ a b)) == (CMPQ b a)
-		// So if we want (SETL (CMPQ a b)) but we can't do that because a is a constant,
-		// then we do (SETL (InvertFlags (CMPQ b a))) instead.
-		// Rewrites will convert this to (SETG (CMPQ b a)).
-		// InvertFlags is a pseudo-op which can't appear in assembly output.
-		{name: "InvertFlags", argLength: 1}, // reverse direction of arg0
-
-		// Pseudo-ops
-		{name: "LoweredGetG", argLength: 1, reg: gp01}, // arg0=mem
-		// Scheduler ensures LoweredGetClosurePtr occurs only in entry block,
-		// and sorts it to the very beginning of the block to prevent other
-		// use of DX (the closure pointer)
-		{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("DX")}}, zeroWidth: true},
-		// LoweredGetCallerPC evaluates to the PC to which its "caller" will return.
-		// I.e., if f calls g "calls" getcallerpc,
-		// the result should be the PC within f that g will return to.
-		// See runtime/stubs.go for a more detailed discussion.
-		{name: "LoweredGetCallerPC", reg: gp01, rematerializeable: true},
-		// LoweredGetCallerSP returns the SP of the caller of the current function.
-		{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
-		//arg0=ptr,arg1=mem, returns void.  Faults if ptr is nil.
-		{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpsp}}, clobberFlags: true, nilCheck: true, faultOnNilArg0: true},
-		// LoweredWB invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
-		// It saves all GP registers if necessary, but may clobber others.
-		{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("DI"), buildReg("AX CX DX BX BP SI R8 R9")}, clobbers: callerSave &^ (gp | g)}, clobberFlags: true, aux: "Sym", symEffect: "None"},
-
-		{name: "LoweredHasCPUFeature", argLength: 0, reg: gp01, rematerializeable: true, typ: "UInt64", aux: "Sym", symEffect: "None"},
-
-		// There are three of these functions so that they can have three different register inputs.
-		// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the
-		// default registers to match so we don't need to copy registers around unnecessarily.
-		{name: "LoweredPanicBoundsA", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{dx, bx}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
-		{name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{cx, dx}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
-		{name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{ax, cx}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
-
-		// Constant flag values. For any comparison, there are 5 possible
-		// outcomes: the three from the signed total order (<,==,>) and the
-		// three from the unsigned total order. The == cases overlap.
-		// Note: there's a sixth "unordered" outcome for floating-point
-		// comparisons, but we don't use such a beast yet.
-		// These ops are for temporary use by rewrite rules. They
-		// cannot appear in the generated assembly.
-		{name: "FlagEQ"},     // equal
-		{name: "FlagLT_ULT"}, // signed < and unsigned <
-		{name: "FlagLT_UGT"}, // signed < and unsigned >
-		{name: "FlagGT_UGT"}, // signed > and unsigned >
-		{name: "FlagGT_ULT"}, // signed > and unsigned <
-
-		// Atomic loads.  These are just normal loads but return <value,memory> tuples
-		// so they can be properly ordered with other loads.
-		// load from arg0+auxint+aux.  arg1=mem.
-		{name: "MOVBatomicload", argLength: 2, reg: gpload, asm: "MOVB", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},
-		{name: "MOVLatomicload", argLength: 2, reg: gpload, asm: "MOVL", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},
-		{name: "MOVQatomicload", argLength: 2, reg: gpload, asm: "MOVQ", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},
-
-		// Atomic stores and exchanges.  Stores use XCHG to get the right memory ordering semantics.
-		// store arg0 to arg1+auxint+aux, arg2=mem.
-		// These ops return a tuple of <old contents of *(arg1+auxint+aux), memory>.
-		// Note: arg0 and arg1 are backwards compared to MOVLstore (to facilitate resultInArg0)!
-		{name: "XCHGB", argLength: 3, reg: gpstorexchg, asm: "XCHGB", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, hasSideEffects: true, symEffect: "RdWr"},
-		{name: "XCHGL", argLength: 3, reg: gpstorexchg, asm: "XCHGL", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, hasSideEffects: true, symEffect: "RdWr"},
-		{name: "XCHGQ", argLength: 3, reg: gpstorexchg, asm: "XCHGQ", aux: "SymOff", resultInArg0: true, faultOnNilArg1: true, hasSideEffects: true, symEffect: "RdWr"},
-
-		// Atomic adds.
-		// *(arg1+auxint+aux) += arg0.  arg2=mem.
-		// Returns a tuple of <old contents of *(arg1+auxint+aux), memory>.
-		// Note: arg0 and arg1 are backwards compared to MOVLstore (to facilitate resultInArg0)!
-		{name: "XADDLlock", argLength: 3, reg: gpstorexchg, asm: "XADDL", typ: "(UInt32,Mem)", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, hasSideEffects: true, symEffect: "RdWr"},
-		{name: "XADDQlock", argLength: 3, reg: gpstorexchg, asm: "XADDQ", typ: "(UInt64,Mem)", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, hasSideEffects: true, symEffect: "RdWr"},
-		{name: "AddTupleFirst32", argLength: 2}, // arg1=tuple <x,y>.  Returns <x+arg0,y>.
-		{name: "AddTupleFirst64", argLength: 2}, // arg1=tuple <x,y>.  Returns <x+arg0,y>.
-
-		// Compare and swap.
-		// arg0 = pointer, arg1 = old value, arg2 = new value, arg3 = memory.
-		// if *(arg0+auxint+aux) == arg1 {
-		//   *(arg0+auxint+aux) = arg2
-		//   return (true, memory)
-		// } else {
-		//   return (false, memory)
-		// }
-		// Note that these instructions also return the old value in AX, but we ignore it.
-		// TODO: have these return flags instead of bool.  The current system generates:
-		//    CMPXCHGQ ...
-		//    SETEQ AX
-		//    CMPB  AX, $0
-		//    JNE ...
-		// instead of just
-		//    CMPXCHGQ ...
-		//    JEQ ...
-		// but we can't do that because memory-using ops can't generate flags yet
-		// (flagalloc wants to move flag-generating instructions around).
-		{name: "CMPXCHGLlock", argLength: 4, reg: cmpxchg, asm: "CMPXCHGL", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "RdWr"},
-		{name: "CMPXCHGQlock", argLength: 4, reg: cmpxchg, asm: "CMPXCHGQ", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "RdWr"},
-
-		// Atomic memory updates.
-		{name: "ANDBlock", argLength: 3, reg: gpstore, asm: "ANDB", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "RdWr"}, // *(arg0+auxint+aux) &= arg1
-		{name: "ANDLlock", argLength: 3, reg: gpstore, asm: "ANDL", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "RdWr"}, // *(arg0+auxint+aux) &= arg1
-		{name: "ORBlock", argLength: 3, reg: gpstore, asm: "ORB", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "RdWr"},   // *(arg0+auxint+aux) |= arg1
-		{name: "ORLlock", argLength: 3, reg: gpstore, asm: "ORL", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "RdWr"},   // *(arg0+auxint+aux) |= arg1
-
-		// Prefetch instructions
-		// Do prefetch arg0 address. arg0=addr, arg1=memory. Instruction variant selects locality hint
-		{name: "PrefetchT0", argLength: 2, reg: prefreg, asm: "PREFETCHT0", hasSideEffects: true},
-		{name: "PrefetchNTA", argLength: 2, reg: prefreg, asm: "PREFETCHNTA", hasSideEffects: true},
-
-		// CPUID feature: BMI1.
-		{name: "ANDNQ", argLength: 2, reg: gp21, asm: "ANDNQ", clobberFlags: true},     // arg0 &^ arg1
-		{name: "ANDNL", argLength: 2, reg: gp21, asm: "ANDNL", clobberFlags: true},     // arg0 &^ arg1
-		{name: "BLSIQ", argLength: 1, reg: gp11, asm: "BLSIQ", clobberFlags: true},     // arg0 & -arg0
-		{name: "BLSIL", argLength: 1, reg: gp11, asm: "BLSIL", clobberFlags: true},     // arg0 & -arg0
-		{name: "BLSMSKQ", argLength: 1, reg: gp11, asm: "BLSMSKQ", clobberFlags: true}, // arg0 ^ (arg0 - 1)
-		{name: "BLSMSKL", argLength: 1, reg: gp11, asm: "BLSMSKL", clobberFlags: true}, // arg0 ^ (arg0 - 1)
-		{name: "BLSRQ", argLength: 1, reg: gp11, asm: "BLSRQ", clobberFlags: true},     // arg0 & (arg0 - 1)
-		{name: "BLSRL", argLength: 1, reg: gp11, asm: "BLSRL", clobberFlags: true},     // arg0 & (arg0 - 1)
-		// count the number of trailing zero bits, prefer TZCNTQ over BSFQ, as TZCNTQ(0)==64
-		// and BSFQ(0) is undefined. Same for TZCNTL(0)==32
-		{name: "TZCNTQ", argLength: 1, reg: gp11, asm: "TZCNTQ", clobberFlags: true},
-		{name: "TZCNTL", argLength: 1, reg: gp11, asm: "TZCNTL", clobberFlags: true},
-
-		// CPUID feature: LZCNT.
-		// count the number of leading zero bits.
-		{name: "LZCNTQ", argLength: 1, reg: gp11, asm: "LZCNTQ", typ: "UInt64", clobberFlags: true},
-		{name: "LZCNTL", argLength: 1, reg: gp11, asm: "LZCNTL", typ: "UInt32", clobberFlags: true},
-
-		// CPUID feature: MOVBE
-		// MOVBEWload does not satisfy zero extended, so only use MOVBEWstore
-		{name: "MOVBEWstore", argLength: 3, reg: gpstore, asm: "MOVBEW", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // swap and store 2 bytes in arg1 to arg0+auxint+aux. arg2=mem
-		{name: "MOVBELload", argLength: 2, reg: gpload, asm: "MOVBEL", aux: "SymOff", typ: "UInt32", faultOnNilArg0: true, symEffect: "Read"}, // load and swap 4 bytes from arg0+auxint+aux. arg1=mem.  Zero extend.
-		{name: "MOVBELstore", argLength: 3, reg: gpstore, asm: "MOVBEL", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // swap and store 4 bytes in arg1 to arg0+auxint+aux. arg2=mem
-		{name: "MOVBEQload", argLength: 2, reg: gpload, asm: "MOVBEQ", aux: "SymOff", typ: "UInt64", faultOnNilArg0: true, symEffect: "Read"}, // load and swap 8 bytes from arg0+auxint+aux. arg1=mem
-		{name: "MOVBEQstore", argLength: 3, reg: gpstore, asm: "MOVBEQ", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // swap and store 8 bytes in arg1 to arg0+auxint+aux. arg2=mem
-		// indexed MOVBE loads
-		{name: "MOVBELloadidx1", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVBEL", scale: 1, aux: "SymOff", typ: "UInt32", symEffect: "Read"}, // load and swap 4 bytes from arg0+arg1+auxint+aux. arg2=mem. Zero extend.
-		{name: "MOVBELloadidx4", argLength: 3, reg: gploadidx, asm: "MOVBEL", scale: 4, aux: "SymOff", typ: "UInt32", symEffect: "Read"},                    // load and swap 4 bytes from arg0+4*arg1+auxint+aux. arg2=mem. Zero extend.
-		{name: "MOVBELloadidx8", argLength: 3, reg: gploadidx, asm: "MOVBEL", scale: 8, aux: "SymOff", typ: "UInt32", symEffect: "Read"},                    // load and swap 4 bytes from arg0+8*arg1+auxint+aux. arg2=mem. Zero extend.
-		{name: "MOVBEQloadidx1", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVBEQ", scale: 1, aux: "SymOff", typ: "UInt64", symEffect: "Read"}, // load and swap 8 bytes from arg0+arg1+auxint+aux. arg2=mem
-		{name: "MOVBEQloadidx8", argLength: 3, reg: gploadidx, asm: "MOVBEQ", scale: 8, aux: "SymOff", typ: "UInt64", symEffect: "Read"},                    // load and swap 8 bytes from arg0+8*arg1+auxint+aux. arg2=mem
-		// indexed MOVBE stores
-		{name: "MOVBEWstoreidx1", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVBEW", scale: 1, aux: "SymOff", symEffect: "Write"}, // swap and store 2 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem
-		{name: "MOVBEWstoreidx2", argLength: 4, reg: gpstoreidx, asm: "MOVBEW", scale: 2, aux: "SymOff", symEffect: "Write"},                    // swap and store 2 bytes in arg2 to arg0+2*arg1+auxint+aux. arg3=mem
-		{name: "MOVBELstoreidx1", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVBEL", scale: 1, aux: "SymOff", symEffect: "Write"}, // swap and store 4 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem
-		{name: "MOVBELstoreidx4", argLength: 4, reg: gpstoreidx, asm: "MOVBEL", scale: 4, aux: "SymOff", symEffect: "Write"},                    // swap and store 4 bytes in arg2 to arg0+4*arg1+auxint+aux. arg3=mem
-		{name: "MOVBELstoreidx8", argLength: 4, reg: gpstoreidx, asm: "MOVBEL", scale: 8, aux: "SymOff", symEffect: "Write"},                    // swap and store 4 bytes in arg2 to arg0+8*arg1+auxint+aux. arg3=mem
-		{name: "MOVBEQstoreidx1", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVBEQ", scale: 1, aux: "SymOff", symEffect: "Write"}, // swap and store 8 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem
-		{name: "MOVBEQstoreidx8", argLength: 4, reg: gpstoreidx, asm: "MOVBEQ", scale: 8, aux: "SymOff", symEffect: "Write"},                    // swap and store 8 bytes in arg2 to arg0+8*arg1+auxint+aux. arg3=mem
-
-		// CPUID feature: BMI2.
-		{name: "SARXQ", argLength: 2, reg: gp21, asm: "SARXQ"}, // signed arg0 >> arg1, shift amount is mod 64
-		{name: "SARXL", argLength: 2, reg: gp21, asm: "SARXL"}, // signed int32(arg0) >> arg1, shift amount is mod 32
-		{name: "SHLXQ", argLength: 2, reg: gp21, asm: "SHLXQ"}, // arg0 << arg1, shift amount is mod 64
-		{name: "SHLXL", argLength: 2, reg: gp21, asm: "SHLXL"}, // arg0 << arg1, shift amount is mod 32
-		{name: "SHRXQ", argLength: 2, reg: gp21, asm: "SHRXQ"}, // unsigned arg0 >> arg1, shift amount is mod 64
-		{name: "SHRXL", argLength: 2, reg: gp21, asm: "SHRXL"}, // unsigned uint32(arg0) >> arg1, shift amount is mod 32
-
-		{name: "SARXLload", argLength: 3, reg: gp21shxload, asm: "SARXL", aux: "SymOff", typ: "Uint32", faultOnNilArg0: true, symEffect: "Read"}, // signed *(arg0+auxint+aux) >> arg1, arg2=mem, shift amount is mod 32
-		{name: "SARXQload", argLength: 3, reg: gp21shxload, asm: "SARXQ", aux: "SymOff", typ: "Uint64", faultOnNilArg0: true, symEffect: "Read"}, // signed *(arg0+auxint+aux) >> arg1, arg2=mem, shift amount is mod 64
-		{name: "SHLXLload", argLength: 3, reg: gp21shxload, asm: "SHLXL", aux: "SymOff", typ: "Uint32", faultOnNilArg0: true, symEffect: "Read"}, // *(arg0+auxint+aux) << arg1, arg2=mem, shift amount is mod 32
-		{name: "SHLXQload", argLength: 3, reg: gp21shxload, asm: "SHLXQ", aux: "SymOff", typ: "Uint64", faultOnNilArg0: true, symEffect: "Read"}, // *(arg0+auxint+aux) << arg1, arg2=mem, shift amount is mod 64
-		{name: "SHRXLload", argLength: 3, reg: gp21shxload, asm: "SHRXL", aux: "SymOff", typ: "Uint32", faultOnNilArg0: true, symEffect: "Read"}, // unsigned *(arg0+auxint+aux) >> arg1, arg2=mem, shift amount is mod 32
-		{name: "SHRXQload", argLength: 3, reg: gp21shxload, asm: "SHRXQ", aux: "SymOff", typ: "Uint64", faultOnNilArg0: true, symEffect: "Read"}, // unsigned *(arg0+auxint+aux) >> arg1, arg2=mem, shift amount is mod 64
-
-		{name: "SARXLloadidx1", argLength: 4, reg: gp21shxloadidx, asm: "SARXL", scale: 1, aux: "SymOff", typ: "Uint32", faultOnNilArg0: true, symEffect: "Read"}, // signed *(arg0+1*arg1+auxint+aux) >> arg2, arg3=mem, shift amount is mod 32
-		{name: "SARXLloadidx4", argLength: 4, reg: gp21shxloadidx, asm: "SARXL", scale: 4, aux: "SymOff", typ: "Uint32", faultOnNilArg0: true, symEffect: "Read"}, // signed *(arg0+4*arg1+auxint+aux) >> arg2, arg3=mem, shift amount is mod 32
-		{name: "SARXLloadidx8", argLength: 4, reg: gp21shxloadidx, asm: "SARXL", scale: 8, aux: "SymOff", typ: "Uint32", faultOnNilArg0: true, symEffect: "Read"}, // signed *(arg0+8*arg1+auxint+aux) >> arg2, arg3=mem, shift amount is mod 32
-		{name: "SARXQloadidx1", argLength: 4, reg: gp21shxloadidx, asm: "SARXQ", scale: 1, aux: "SymOff", typ: "Uint64", faultOnNilArg0: true, symEffect: "Read"}, // signed *(arg0+1*arg1+auxint+aux) >> arg2, arg3=mem, shift amount is mod 64
-		{name: "SARXQloadidx8", argLength: 4, reg: gp21shxloadidx, asm: "SARXQ", scale: 8, aux: "SymOff", typ: "Uint64", faultOnNilArg0: true, symEffect: "Read"}, // signed *(arg0+8*arg1+auxint+aux) >> arg2, arg3=mem, shift amount is mod 64
-		{name: "SHLXLloadidx1", argLength: 4, reg: gp21shxloadidx, asm: "SHLXL", scale: 1, aux: "SymOff", typ: "Uint32", faultOnNilArg0: true, symEffect: "Read"}, // *(arg0+1*arg1+auxint+aux) << arg2, arg3=mem, shift amount is mod 32
-		{name: "SHLXLloadidx4", argLength: 4, reg: gp21shxloadidx, asm: "SHLXL", scale: 4, aux: "SymOff", typ: "Uint32", faultOnNilArg0: true, symEffect: "Read"}, // *(arg0+4*arg1+auxint+aux) << arg2, arg3=mem, shift amount is mod 32
-		{name: "SHLXLloadidx8", argLength: 4, reg: gp21shxloadidx, asm: "SHLXL", scale: 8, aux: "SymOff", typ: "Uint32", faultOnNilArg0: true, symEffect: "Read"}, // *(arg0+8*arg1+auxint+aux) << arg2, arg3=mem, shift amount is mod 32
-		{name: "SHLXQloadidx1", argLength: 4, reg: gp21shxloadidx, asm: "SHLXQ", scale: 1, aux: "SymOff", typ: "Uint64", faultOnNilArg0: true, symEffect: "Read"}, // *(arg0+1*arg1+auxint+aux) << arg2, arg3=mem, shift amount is mod 64
-		{name: "SHLXQloadidx8", argLength: 4, reg: gp21shxloadidx, asm: "SHLXQ", scale: 8, aux: "SymOff", typ: "Uint64", faultOnNilArg0: true, symEffect: "Read"}, // *(arg0+8*arg1+auxint+aux) << arg2, arg3=mem, shift amount is mod 64
-		{name: "SHRXLloadidx1", argLength: 4, reg: gp21shxloadidx, asm: "SHRXL", scale: 1, aux: "SymOff", typ: "Uint32", faultOnNilArg0: true, symEffect: "Read"}, // unsigned *(arg0+1*arg1+auxint+aux) >> arg2, arg3=mem, shift amount is mod 32
-		{name: "SHRXLloadidx4", argLength: 4, reg: gp21shxloadidx, asm: "SHRXL", scale: 4, aux: "SymOff", typ: "Uint32", faultOnNilArg0: true, symEffect: "Read"}, // unsigned *(arg0+4*arg1+auxint+aux) >> arg2, arg3=mem, shift amount is mod 32
-		{name: "SHRXLloadidx8", argLength: 4, reg: gp21shxloadidx, asm: "SHRXL", scale: 8, aux: "SymOff", typ: "Uint32", faultOnNilArg0: true, symEffect: "Read"}, // unsigned *(arg0+8*arg1+auxint+aux) >> arg2, arg3=mem, shift amount is mod 32
-		{name: "SHRXQloadidx1", argLength: 4, reg: gp21shxloadidx, asm: "SHRXQ", scale: 1, aux: "SymOff", typ: "Uint64", faultOnNilArg0: true, symEffect: "Read"}, // unsigned *(arg0+1*arg1+auxint+aux) >> arg2, arg3=mem, shift amount is mod 64
-		{name: "SHRXQloadidx8", argLength: 4, reg: gp21shxloadidx, asm: "SHRXQ", scale: 8, aux: "SymOff", typ: "Uint64", faultOnNilArg0: true, symEffect: "Read"}, // unsigned *(arg0+8*arg1+auxint+aux) >> arg2, arg3=mem, shift amount is mod 64
-	}
-
-	var AMD64blocks = []blockData{
-		{name: "EQ", controls: 1},
-		{name: "NE", controls: 1},
-		{name: "LT", controls: 1},
-		{name: "LE", controls: 1},
-		{name: "GT", controls: 1},
-		{name: "GE", controls: 1},
-		{name: "OS", controls: 1},
-		{name: "OC", controls: 1},
-		{name: "ULT", controls: 1},
-		{name: "ULE", controls: 1},
-		{name: "UGT", controls: 1},
-		{name: "UGE", controls: 1},
-		{name: "EQF", controls: 1},
-		{name: "NEF", controls: 1},
-		{name: "ORD", controls: 1}, // FP, ordered comparison (parity zero)
-		{name: "NAN", controls: 1}, // FP, unordered comparison (parity one)
-
-		// JUMPTABLE implements jump tables.
-		// Aux is the symbol (an *obj.LSym) for the jump table.
-		// control[0] is the index into the jump table.
-		// control[1] is the address of the jump table (the address of the symbol stored in Aux).
-		{name: "JUMPTABLE", controls: 2, aux: "Sym"},
-	}
-
-	archs = append(archs, arch{
-		name:               "AMD64",
-		pkg:                "cmd/internal/obj/x86",
-		genfile:            "../../amd64/ssa.go",
-		ops:                AMD64ops,
-		blocks:             AMD64blocks,
-		regnames:           regNamesAMD64,
-		ParamIntRegNames:   "AX BX CX DI SI R8 R9 R10 R11",
-		ParamFloatRegNames: "X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14",
-		gpregmask:          gp,
-		fpregmask:          fp,
-		specialregmask:     x15,
-		framepointerreg:    int8(num["BP"]),
-		linkreg:            -1, // not used
-	})
-}
diff --git a/src/cmd/compile/internal/ssa/gen/ARM.rules b/src/cmd/compile/internal/ssa/gen/ARM.rules
deleted file mode 100644
index 7328461..0000000
--- a/src/cmd/compile/internal/ssa/gen/ARM.rules
+++ /dev/null
@@ -1,1482 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-(Add(Ptr|32|16|8) ...) => (ADD ...)
-(Add(32|64)F ...) => (ADD(F|D) ...)
-(Add32carry ...) => (ADDS ...)
-(Add32withcarry ...) => (ADC ...)
-
-(Sub(Ptr|32|16|8) ...) => (SUB ...)
-(Sub(32|64)F ...) => (SUB(F|D) ...)
-(Sub32carry ...) => (SUBS ...)
-(Sub32withcarry ...) => (SBC ...)
-
-(Mul(32|16|8) ...) => (MUL ...)
-(Mul(32|64)F ...) => (MUL(F|D) ...)
-(Hmul(32|32u) ...) => (HMU(L|LU) ...)
-(Mul32uhilo ...) => (MULLU ...)
-
-(Div32 x y) =>
-	(SUB (XOR <typ.UInt32>                                                        // negate the result if one operand is negative
-		(Select0 <typ.UInt32> (CALLudiv
-			(SUB <typ.UInt32> (XOR x <typ.UInt32> (Signmask x)) (Signmask x))   // negate x if negative
-			(SUB <typ.UInt32> (XOR y <typ.UInt32> (Signmask y)) (Signmask y)))) // negate y if negative
-		(Signmask (XOR <typ.UInt32> x y))) (Signmask (XOR <typ.UInt32> x y)))
-(Div32u x y) => (Select0 <typ.UInt32> (CALLudiv x y))
-(Div16 x y) => (Div32 (SignExt16to32 x) (SignExt16to32 y))
-(Div16u x y) => (Div32u (ZeroExt16to32 x) (ZeroExt16to32 y))
-(Div8 x y) => (Div32 (SignExt8to32 x) (SignExt8to32 y))
-(Div8u x y) => (Div32u (ZeroExt8to32 x) (ZeroExt8to32 y))
-(Div(32|64)F ...) => (DIV(F|D) ...)
-
-(Mod32 x y) =>
-	(SUB (XOR <typ.UInt32>                                                        // negate the result if x is negative
-		(Select1 <typ.UInt32> (CALLudiv
-			(SUB <typ.UInt32> (XOR <typ.UInt32> x (Signmask x)) (Signmask x))   // negate x if negative
-			(SUB <typ.UInt32> (XOR <typ.UInt32> y (Signmask y)) (Signmask y)))) // negate y if negative
-		(Signmask x)) (Signmask x))
-(Mod32u x y) => (Select1 <typ.UInt32> (CALLudiv x y))
-(Mod16 x y) => (Mod32 (SignExt16to32 x) (SignExt16to32 y))
-(Mod16u x y) => (Mod32u (ZeroExt16to32 x) (ZeroExt16to32 y))
-(Mod8 x y) => (Mod32 (SignExt8to32 x) (SignExt8to32 y))
-(Mod8u x y) => (Mod32u (ZeroExt8to32 x) (ZeroExt8to32 y))
-
-// (x + y) / 2 with x>=y -> (x - y) / 2 + y
-(Avg32u <t> x y) => (ADD (SRLconst <t> (SUB <t> x y) [1]) y)
-
-(And(32|16|8) ...) => (AND ...)
-(Or(32|16|8) ...) => (OR ...)
-(Xor(32|16|8) ...) => (XOR ...)
-
-// unary ops
-(Neg(32|16|8) x) => (RSBconst [0] x)
-(Neg(32|64)F ...) => (NEG(F|D) ...)
-
-(Com(32|16|8) ...) => (MVN ...)
-
-(Sqrt ...) => (SQRTD ...)
-(Sqrt32 ...) => (SQRTF ...)
-(Abs ...) => (ABSD ...)
-
-// TODO: optimize this for ARMv5 and ARMv6
-(Ctz32NonZero ...) => (Ctz32 ...)
-(Ctz16NonZero ...) => (Ctz32 ...)
-(Ctz8NonZero ...) => (Ctz32 ...)
-
-// count trailing zero for ARMv5 and ARMv6
-// 32 - CLZ(x&-x - 1)
-(Ctz32 <t> x) && buildcfg.GOARM<=6 =>
-	(RSBconst [32] (CLZ <t> (SUBconst <t> (AND <t> x (RSBconst <t> [0] x)) [1])))
-(Ctz16 <t> x) && buildcfg.GOARM<=6 =>
-	(RSBconst [32] (CLZ <t> (SUBconst <typ.UInt32> (AND <typ.UInt32> (ORconst <typ.UInt32> [0x10000] x) (RSBconst <typ.UInt32> [0] (ORconst <typ.UInt32> [0x10000] x))) [1])))
-(Ctz8 <t> x) && buildcfg.GOARM<=6 =>
-	(RSBconst [32] (CLZ <t> (SUBconst <typ.UInt32> (AND <typ.UInt32> (ORconst <typ.UInt32> [0x100] x) (RSBconst <typ.UInt32> [0] (ORconst <typ.UInt32> [0x100] x))) [1])))
-
-// count trailing zero for ARMv7
-(Ctz32 <t> x) && buildcfg.GOARM==7 => (CLZ <t> (RBIT <t> x))
-(Ctz16 <t> x) && buildcfg.GOARM==7 => (CLZ <t> (RBIT <typ.UInt32> (ORconst <typ.UInt32> [0x10000] x)))
-(Ctz8 <t> x) && buildcfg.GOARM==7 => (CLZ <t> (RBIT <typ.UInt32> (ORconst <typ.UInt32> [0x100] x)))
-
-// bit length
-(BitLen32 <t> x) => (RSBconst [32] (CLZ <t> x))
-
-// byte swap for ARMv5
-// let (a, b, c, d) be the bytes of x from high to low
-// t1 = x right rotate 16 bits -- (c,   d,   a,   b  )
-// t2 = x ^ t1                 -- (a^c, b^d, a^c, b^d)
-// t3 = t2 &^ 0xff0000         -- (a^c, 0,   a^c, b^d)
-// t4 = t3 >> 8                -- (0,   a^c, 0,   a^c)
-// t5 = x right rotate 8 bits  -- (d,   a,   b,   c  )
-// result = t4 ^ t5            -- (d,   c,   b,   a  )
-// using shifted ops this can be done in 4 instructions.
-(Bswap32 <t> x) && buildcfg.GOARM==5 =>
-	(XOR <t>
-		(SRLconst <t> (BICconst <t> (XOR <t> x (SRRconst <t> [16] x)) [0xff0000]) [8])
-		(SRRconst <t> x [8]))
-
-// byte swap for ARMv6 and above
-(Bswap32 x) && buildcfg.GOARM>=6 => (REV x)
-
-// boolean ops -- booleans are represented with 0=false, 1=true
-(AndB ...) => (AND ...)
-(OrB ...) => (OR ...)
-(EqB x y) => (XORconst [1] (XOR <typ.Bool> x y))
-(NeqB ...) => (XOR ...)
-(Not x) => (XORconst [1] x)
-
-// shifts
-// hardware instruction uses only the low byte of the shift
-// we compare to 256 to ensure Go semantics for large shifts
-(Lsh32x32 x y) => (CMOVWHSconst (SLL <x.Type> x y) (CMPconst [256] y) [0])
-(Lsh32x16 x y) => (CMOVWHSconst (SLL <x.Type> x (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0])
-(Lsh32x8  x y) => (SLL x (ZeroExt8to32 y))
-
-(Lsh16x32 x y) => (CMOVWHSconst (SLL <x.Type> x y) (CMPconst [256] y) [0])
-(Lsh16x16 x y) => (CMOVWHSconst (SLL <x.Type> x (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0])
-(Lsh16x8  x y) => (SLL x (ZeroExt8to32 y))
-
-(Lsh8x32 x y) => (CMOVWHSconst (SLL <x.Type> x y) (CMPconst [256] y) [0])
-(Lsh8x16 x y) => (CMOVWHSconst (SLL <x.Type> x (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0])
-(Lsh8x8  x y) => (SLL x (ZeroExt8to32 y))
-
-(Rsh32Ux32 x y) => (CMOVWHSconst (SRL <x.Type> x y) (CMPconst [256] y) [0])
-(Rsh32Ux16 x y) => (CMOVWHSconst (SRL <x.Type> x (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0])
-(Rsh32Ux8  x y) => (SRL x (ZeroExt8to32 y))
-
-(Rsh16Ux32 x y) => (CMOVWHSconst (SRL <x.Type> (ZeroExt16to32 x) y) (CMPconst [256] y) [0])
-(Rsh16Ux16 x y) => (CMOVWHSconst (SRL <x.Type> (ZeroExt16to32 x) (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0])
-(Rsh16Ux8  x y) => (SRL (ZeroExt16to32 x) (ZeroExt8to32 y))
-
-(Rsh8Ux32 x y) => (CMOVWHSconst (SRL <x.Type> (ZeroExt8to32 x) y) (CMPconst [256] y) [0])
-(Rsh8Ux16 x y) => (CMOVWHSconst (SRL <x.Type> (ZeroExt8to32 x) (ZeroExt16to32 y)) (CMPconst [256] (ZeroExt16to32 y)) [0])
-(Rsh8Ux8  x y) => (SRL (ZeroExt8to32 x) (ZeroExt8to32 y))
-
-(Rsh32x32 x y) => (SRAcond x y (CMPconst [256] y))
-(Rsh32x16 x y) => (SRAcond x (ZeroExt16to32 y) (CMPconst [256] (ZeroExt16to32 y)))
-(Rsh32x8  x y) => (SRA x (ZeroExt8to32 y))
-
-(Rsh16x32 x y) => (SRAcond (SignExt16to32 x) y (CMPconst [256] y))
-(Rsh16x16 x y) => (SRAcond (SignExt16to32 x) (ZeroExt16to32 y) (CMPconst [256] (ZeroExt16to32 y)))
-(Rsh16x8  x y) => (SRA (SignExt16to32 x) (ZeroExt8to32 y))
-
-(Rsh8x32 x y) => (SRAcond (SignExt8to32 x) y (CMPconst [256] y))
-(Rsh8x16 x y) => (SRAcond (SignExt8to32 x) (ZeroExt16to32 y) (CMPconst [256] (ZeroExt16to32 y)))
-(Rsh8x8  x y) => (SRA (SignExt8to32 x) (ZeroExt8to32 y))
-
-// constant shifts
-// generic opt rewrites all constant shifts to shift by Const64
-(Lsh32x64 x (Const64 [c])) && uint64(c) < 32 => (SLLconst x [int32(c)])
-(Rsh32x64 x (Const64 [c])) && uint64(c) < 32 => (SRAconst x [int32(c)])
-(Rsh32Ux64 x (Const64 [c])) && uint64(c) < 32 => (SRLconst x [int32(c)])
-(Lsh16x64 x (Const64 [c])) && uint64(c) < 16 => (SLLconst x [int32(c)])
-(Rsh16x64 x (Const64 [c])) && uint64(c) < 16 => (SRAconst (SLLconst <typ.UInt32> x [16]) [int32(c+16)])
-(Rsh16Ux64 x (Const64 [c])) && uint64(c) < 16 => (SRLconst (SLLconst <typ.UInt32> x [16]) [int32(c+16)])
-(Lsh8x64 x (Const64 [c])) && uint64(c) < 8 => (SLLconst x [int32(c)])
-(Rsh8x64 x (Const64 [c])) && uint64(c) < 8 => (SRAconst (SLLconst <typ.UInt32> x [24]) [int32(c+24)])
-(Rsh8Ux64 x (Const64 [c])) && uint64(c) < 8 => (SRLconst (SLLconst <typ.UInt32> x [24]) [int32(c+24)])
-
-// large constant shifts
-(Lsh32x64 _ (Const64 [c])) && uint64(c) >= 32 => (Const32 [0])
-(Rsh32Ux64 _ (Const64 [c])) && uint64(c) >= 32 => (Const32 [0])
-(Lsh16x64 _ (Const64 [c])) && uint64(c) >= 16 => (Const16 [0])
-(Rsh16Ux64 _ (Const64 [c])) && uint64(c) >= 16 => (Const16 [0])
-(Lsh8x64 _ (Const64 [c])) && uint64(c) >= 8 => (Const8 [0])
-(Rsh8Ux64 _ (Const64 [c])) && uint64(c) >= 8 => (Const8 [0])
-
-// large constant signed right shift, we leave the sign bit
-(Rsh32x64 x (Const64 [c])) && uint64(c) >= 32 => (SRAconst x [31])
-(Rsh16x64 x (Const64 [c])) && uint64(c) >= 16 => (SRAconst (SLLconst <typ.UInt32> x [16]) [31])
-(Rsh8x64 x (Const64 [c])) && uint64(c) >= 8 => (SRAconst (SLLconst <typ.UInt32> x [24]) [31])
-
-// constants
-(Const(8|16|32) [val]) => (MOVWconst [int32(val)])
-(Const(32|64)F [val]) => (MOV(F|D)const [float64(val)])
-(ConstNil) => (MOVWconst [0])
-(ConstBool [t]) => (MOVWconst [b2i32(t)])
-
-// truncations
-// Because we ignore high parts of registers, truncates are just copies.
-(Trunc16to8 ...) => (Copy ...)
-(Trunc32to8 ...) => (Copy ...)
-(Trunc32to16 ...) => (Copy ...)
-
-// Zero-/Sign-extensions
-(ZeroExt8to16 ...) => (MOVBUreg ...)
-(ZeroExt8to32 ...) => (MOVBUreg ...)
-(ZeroExt16to32 ...) => (MOVHUreg ...)
-
-(SignExt8to16 ...) => (MOVBreg ...)
-(SignExt8to32 ...) => (MOVBreg ...)
-(SignExt16to32 ...) => (MOVHreg ...)
-
-(Signmask x) => (SRAconst x [31])
-(Zeromask x) => (SRAconst (RSBshiftRL <typ.Int32> x x [1]) [31]) // sign bit of uint32(x)>>1 - x
-(Slicemask <t> x) => (SRAconst (RSBconst <t> [0] x) [31])
-
-// float <-> int conversion
-(Cvt32to32F ...) => (MOVWF ...)
-(Cvt32to64F ...) => (MOVWD ...)
-(Cvt32Uto32F ...) => (MOVWUF ...)
-(Cvt32Uto64F ...) => (MOVWUD ...)
-(Cvt32Fto32 ...) => (MOVFW ...)
-(Cvt64Fto32 ...) => (MOVDW ...)
-(Cvt32Fto32U ...) => (MOVFWU ...)
-(Cvt64Fto32U ...) => (MOVDWU ...)
-(Cvt32Fto64F ...) => (MOVFD ...)
-(Cvt64Fto32F ...) => (MOVDF ...)
-
-(Round(32|64)F ...) => (Copy ...)
-
-(CvtBoolToUint8 ...) => (Copy ...)
-
-// fused-multiply-add
-(FMA x y z) => (FMULAD z x y)
-
-// comparisons
-(Eq8 x y)  => (Equal (CMP (ZeroExt8to32 x) (ZeroExt8to32 y)))
-(Eq16 x y) => (Equal (CMP (ZeroExt16to32 x) (ZeroExt16to32 y)))
-(Eq32 x y) => (Equal (CMP x y))
-(EqPtr x y) => (Equal (CMP x y))
-(Eq(32|64)F x y) => (Equal (CMP(F|D) x y))
-
-(Neq8 x y)  => (NotEqual (CMP (ZeroExt8to32 x) (ZeroExt8to32 y)))
-(Neq16 x y) => (NotEqual (CMP (ZeroExt16to32 x) (ZeroExt16to32 y)))
-(Neq32 x y) => (NotEqual (CMP x y))
-(NeqPtr x y) => (NotEqual (CMP x y))
-(Neq(32|64)F x y) => (NotEqual (CMP(F|D) x y))
-
-(Less8 x y)  => (LessThan (CMP (SignExt8to32 x) (SignExt8to32 y)))
-(Less16 x y) => (LessThan (CMP (SignExt16to32 x) (SignExt16to32 y)))
-(Less32 x y) => (LessThan (CMP x y))
-(Less(32|64)F x y) => (GreaterThan (CMP(F|D) y x)) // reverse operands to work around NaN
-
-(Less8U x y)  => (LessThanU (CMP (ZeroExt8to32 x) (ZeroExt8to32 y)))
-(Less16U x y) => (LessThanU (CMP (ZeroExt16to32 x) (ZeroExt16to32 y)))
-(Less32U x y) => (LessThanU (CMP x y))
-
-(Leq8 x y)  => (LessEqual (CMP (SignExt8to32 x) (SignExt8to32 y)))
-(Leq16 x y) => (LessEqual (CMP (SignExt16to32 x) (SignExt16to32 y)))
-(Leq32 x y) => (LessEqual (CMP x y))
-(Leq(32|64)F x y) => (GreaterEqual (CMP(F|D) y x)) // reverse operands to work around NaN
-
-(Leq8U x y)  => (LessEqualU (CMP (ZeroExt8to32 x) (ZeroExt8to32 y)))
-(Leq16U x y) => (LessEqualU (CMP (ZeroExt16to32 x) (ZeroExt16to32 y)))
-(Leq32U x y) => (LessEqualU (CMP x y))
-
-(OffPtr [off] ptr:(SP)) => (MOVWaddr [int32(off)] ptr)
-(OffPtr [off] ptr) => (ADDconst [int32(off)] ptr)
-
-(Addr {sym} base) => (MOVWaddr {sym} base)
-(LocalAddr {sym} base _) => (MOVWaddr {sym} base)
-
-// loads
-(Load <t> ptr mem) && t.IsBoolean() => (MOVBUload ptr mem)
-(Load <t> ptr mem) && (is8BitInt(t) && isSigned(t)) => (MOVBload ptr mem)
-(Load <t> ptr mem) && (is8BitInt(t) && !isSigned(t)) => (MOVBUload ptr mem)
-(Load <t> ptr mem) && (is16BitInt(t) && isSigned(t)) => (MOVHload ptr mem)
-(Load <t> ptr mem) && (is16BitInt(t) && !isSigned(t)) => (MOVHUload ptr mem)
-(Load <t> ptr mem) && (is32BitInt(t) || isPtr(t)) => (MOVWload ptr mem)
-(Load <t> ptr mem) && is32BitFloat(t) => (MOVFload ptr mem)
-(Load <t> ptr mem) && is64BitFloat(t) => (MOVDload ptr mem)
-
-// stores
-(Store {t} ptr val mem) && t.Size() == 1 => (MOVBstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 2 => (MOVHstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 4 && !is32BitFloat(val.Type) => (MOVWstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 4 && is32BitFloat(val.Type) => (MOVFstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 8 && is64BitFloat(val.Type) => (MOVDstore ptr val mem)
-
-// zero instructions
-(Zero [0] _ mem) => mem
-(Zero [1] ptr mem) => (MOVBstore ptr (MOVWconst [0]) mem)
-(Zero [2] {t} ptr mem) && t.Alignment()%2 == 0 =>
-	(MOVHstore ptr (MOVWconst [0]) mem)
-(Zero [2] ptr mem) =>
-	(MOVBstore [1] ptr (MOVWconst [0])
-		(MOVBstore [0] ptr (MOVWconst [0]) mem))
-(Zero [4] {t} ptr mem) && t.Alignment()%4 == 0 =>
-	(MOVWstore ptr (MOVWconst [0]) mem)
-(Zero [4] {t} ptr mem) && t.Alignment()%2 == 0 =>
-	(MOVHstore [2] ptr (MOVWconst [0])
-		(MOVHstore [0] ptr (MOVWconst [0]) mem))
-(Zero [4] ptr mem) =>
-	(MOVBstore [3] ptr (MOVWconst [0])
-		(MOVBstore [2] ptr (MOVWconst [0])
-			(MOVBstore [1] ptr (MOVWconst [0])
-				(MOVBstore [0] ptr (MOVWconst [0]) mem))))
-
-(Zero [3] ptr mem) =>
-	(MOVBstore [2] ptr (MOVWconst [0])
-		(MOVBstore [1] ptr (MOVWconst [0])
-			(MOVBstore [0] ptr (MOVWconst [0]) mem)))
-
-// Medium zeroing uses a duff device
-// 4 and 128 are magic constants, see runtime/mkduff.go
-(Zero [s] {t} ptr mem)
-	&& s%4 == 0 && s > 4 && s <= 512
-	&& t.Alignment()%4 == 0 && !config.noDuffDevice =>
-	(DUFFZERO [4 * (128 - s/4)] ptr (MOVWconst [0]) mem)
-
-// Large zeroing uses a loop
-(Zero [s] {t} ptr mem)
-	&& (s > 512 || config.noDuffDevice) || t.Alignment()%4 != 0 =>
-	(LoweredZero [t.Alignment()]
-		ptr
-		(ADDconst <ptr.Type> ptr [int32(s-moveSize(t.Alignment(), config))])
-		(MOVWconst [0])
-		mem)
-
-// moves
-(Move [0] _ _ mem) => mem
-(Move [1] dst src mem) => (MOVBstore dst (MOVBUload src mem) mem)
-(Move [2] {t} dst src mem) && t.Alignment()%2 == 0 =>
-	(MOVHstore dst (MOVHUload src mem) mem)
-(Move [2] dst src mem) =>
-	(MOVBstore [1] dst (MOVBUload [1] src mem)
-		(MOVBstore dst (MOVBUload src mem) mem))
-(Move [4] {t} dst src mem) && t.Alignment()%4 == 0 =>
-	(MOVWstore dst (MOVWload src mem) mem)
-(Move [4] {t} dst src mem) && t.Alignment()%2 == 0 =>
-	(MOVHstore [2] dst (MOVHUload [2] src mem)
-		(MOVHstore dst (MOVHUload src mem) mem))
-(Move [4] dst src mem) =>
-	(MOVBstore [3] dst (MOVBUload [3] src mem)
-		(MOVBstore [2] dst (MOVBUload [2] src mem)
-			(MOVBstore [1] dst (MOVBUload [1] src mem)
-				(MOVBstore dst (MOVBUload src mem) mem))))
-
-(Move [3] dst src mem) =>
-	(MOVBstore [2] dst (MOVBUload [2] src mem)
-		(MOVBstore [1] dst (MOVBUload [1] src mem)
-			(MOVBstore dst (MOVBUload src mem) mem)))
-
-// Medium move uses a duff device
-// 8 and 128 are magic constants, see runtime/mkduff.go
-(Move [s] {t} dst src mem)
-	&& s%4 == 0 && s > 4 && s <= 512
-	&& t.Alignment()%4 == 0 && !config.noDuffDevice && logLargeCopy(v, s) =>
-	(DUFFCOPY [8 * (128 - s/4)] dst src mem)
-
-// Large move uses a loop
-(Move [s] {t} dst src mem)
-	&& ((s > 512 || config.noDuffDevice) || t.Alignment()%4 != 0) && logLargeCopy(v, s) =>
-	(LoweredMove [t.Alignment()]
-		dst
-		src
-		(ADDconst <src.Type> src [int32(s-moveSize(t.Alignment(), config))])
-		mem)
-
-// calls
-(StaticCall ...) => (CALLstatic ...)
-(ClosureCall ...) => (CALLclosure ...)
-(InterCall ...) => (CALLinter ...)
-(TailCall ...) => (CALLtail ...)
-
-// checks
-(NilCheck ...) => (LoweredNilCheck ...)
-(IsNonNil ptr) => (NotEqual (CMPconst [0] ptr))
-(IsInBounds idx len) => (LessThanU (CMP idx len))
-(IsSliceInBounds idx len) => (LessEqualU (CMP idx len))
-
-// pseudo-ops
-(GetClosurePtr ...) => (LoweredGetClosurePtr ...)
-(GetCallerSP ...) => (LoweredGetCallerSP ...)
-(GetCallerPC ...) => (LoweredGetCallerPC ...)
-
-// Absorb pseudo-ops into blocks.
-(If (Equal cc) yes no) => (EQ cc yes no)
-(If (NotEqual cc) yes no) => (NE cc yes no)
-(If (LessThan cc) yes no) => (LT cc yes no)
-(If (LessThanU cc) yes no) => (ULT cc yes no)
-(If (LessEqual cc) yes no) => (LE cc yes no)
-(If (LessEqualU cc) yes no) => (ULE cc yes no)
-(If (GreaterThan cc) yes no) => (GT cc yes no)
-(If (GreaterThanU cc) yes no) => (UGT cc yes no)
-(If (GreaterEqual cc) yes no) => (GE cc yes no)
-(If (GreaterEqualU cc) yes no) => (UGE cc yes no)
-
-(If cond yes no) => (NE (CMPconst [0] cond) yes no)
-
-// Absorb boolean tests into block
-(NE (CMPconst [0] (Equal cc)) yes no) => (EQ cc yes no)
-(NE (CMPconst [0] (NotEqual cc)) yes no) => (NE cc yes no)
-(NE (CMPconst [0] (LessThan cc)) yes no) => (LT cc yes no)
-(NE (CMPconst [0] (LessThanU cc)) yes no) => (ULT cc yes no)
-(NE (CMPconst [0] (LessEqual cc)) yes no) => (LE cc yes no)
-(NE (CMPconst [0] (LessEqualU cc)) yes no) => (ULE cc yes no)
-(NE (CMPconst [0] (GreaterThan cc)) yes no) => (GT cc yes no)
-(NE (CMPconst [0] (GreaterThanU cc)) yes no) => (UGT cc yes no)
-(NE (CMPconst [0] (GreaterEqual cc)) yes no) => (GE cc yes no)
-(NE (CMPconst [0] (GreaterEqualU cc)) yes no) => (UGE cc yes no)
-
-// Write barrier.
-(WB ...) => (LoweredWB ...)
-
-(PanicBounds [kind] x y mem) && boundsABI(kind) == 0 => (LoweredPanicBoundsA [kind] x y mem)
-(PanicBounds [kind] x y mem) && boundsABI(kind) == 1 => (LoweredPanicBoundsB [kind] x y mem)
-(PanicBounds [kind] x y mem) && boundsABI(kind) == 2 => (LoweredPanicBoundsC [kind] x y mem)
-
-(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 0 => (LoweredPanicExtendA [kind] hi lo y mem)
-(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 1 => (LoweredPanicExtendB [kind] hi lo y mem)
-(PanicExtend [kind] hi lo y mem) && boundsABI(kind) == 2 => (LoweredPanicExtendC [kind] hi lo y mem)
-
-// Optimizations
-
-// fold offset into address
-(ADDconst [off1] (MOVWaddr [off2] {sym} ptr)) => (MOVWaddr [off1+off2] {sym} ptr)
-(SUBconst [off1] (MOVWaddr [off2] {sym} ptr)) => (MOVWaddr [off2-off1] {sym} ptr)
-
-// fold address into load/store
-(MOVBload [off1] {sym} (ADDconst [off2] ptr) mem) => (MOVBload [off1+off2] {sym} ptr mem)
-(MOVBload [off1] {sym} (SUBconst [off2] ptr) mem) => (MOVBload [off1-off2] {sym} ptr mem)
-(MOVBUload [off1] {sym} (ADDconst [off2] ptr) mem) => (MOVBUload [off1+off2] {sym} ptr mem)
-(MOVBUload [off1] {sym} (SUBconst [off2] ptr) mem) => (MOVBUload [off1-off2] {sym} ptr mem)
-(MOVHload [off1] {sym} (ADDconst [off2] ptr) mem) => (MOVHload [off1+off2] {sym} ptr mem)
-(MOVHload [off1] {sym} (SUBconst [off2] ptr) mem) => (MOVHload [off1-off2] {sym} ptr mem)
-(MOVHUload [off1] {sym} (ADDconst [off2] ptr) mem) => (MOVHUload [off1+off2] {sym} ptr mem)
-(MOVHUload [off1] {sym} (SUBconst [off2] ptr) mem) => (MOVHUload [off1-off2] {sym} ptr mem)
-(MOVWload [off1] {sym} (ADDconst [off2] ptr) mem) => (MOVWload [off1+off2] {sym} ptr mem)
-(MOVWload [off1] {sym} (SUBconst [off2] ptr) mem) => (MOVWload [off1-off2] {sym} ptr mem)
-(MOVFload [off1] {sym} (ADDconst [off2] ptr) mem) => (MOVFload [off1+off2] {sym} ptr mem)
-(MOVFload [off1] {sym} (SUBconst [off2] ptr) mem) => (MOVFload [off1-off2] {sym} ptr mem)
-(MOVDload [off1] {sym} (ADDconst [off2] ptr) mem) => (MOVDload [off1+off2] {sym} ptr mem)
-(MOVDload [off1] {sym} (SUBconst [off2] ptr) mem) => (MOVDload [off1-off2] {sym} ptr mem)
-
-(MOVBstore [off1] {sym} (ADDconst [off2] ptr) val mem) => (MOVBstore [off1+off2] {sym} ptr val mem)
-(MOVBstore [off1] {sym} (SUBconst [off2] ptr) val mem) => (MOVBstore [off1-off2] {sym} ptr val mem)
-(MOVHstore [off1] {sym} (ADDconst [off2] ptr) val mem) => (MOVHstore [off1+off2] {sym} ptr val mem)
-(MOVHstore [off1] {sym} (SUBconst [off2] ptr) val mem) => (MOVHstore [off1-off2] {sym} ptr val mem)
-(MOVWstore [off1] {sym} (ADDconst [off2] ptr) val mem) => (MOVWstore [off1+off2] {sym} ptr val mem)
-(MOVWstore [off1] {sym} (SUBconst [off2] ptr) val mem) => (MOVWstore [off1-off2] {sym} ptr val mem)
-(MOVFstore [off1] {sym} (ADDconst [off2] ptr) val mem) => (MOVFstore [off1+off2] {sym} ptr val mem)
-(MOVFstore [off1] {sym} (SUBconst [off2] ptr) val mem) => (MOVFstore [off1-off2] {sym} ptr val mem)
-(MOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem) => (MOVDstore [off1+off2] {sym} ptr val mem)
-(MOVDstore [off1] {sym} (SUBconst [off2] ptr) val mem) => (MOVDstore [off1-off2] {sym} ptr val mem)
-
-(MOVBload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) =>
-	(MOVBload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-(MOVBUload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) =>
-	(MOVBUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-(MOVHload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) =>
-	(MOVHload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-(MOVHUload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) =>
-	(MOVHUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-(MOVWload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) =>
-	(MOVWload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-(MOVFload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) =>
-	(MOVFload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-(MOVDload [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) =>
-	(MOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-
-(MOVBstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) =>
-	(MOVBstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
-(MOVHstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) =>
-	(MOVHstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
-(MOVWstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) =>
-	(MOVWstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
-(MOVFstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) =>
-	(MOVFstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
-(MOVDstore [off1] {sym1} (MOVWaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) =>
-	(MOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
-
-// replace load from same location as preceding store with zero/sign extension (or copy in case of full width)
-(MOVBload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVBreg x)
-(MOVBUload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVBUreg x)
-(MOVHload [off] {sym} ptr (MOVHstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVHreg x)
-(MOVHUload [off] {sym} ptr (MOVHstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVHUreg x)
-(MOVWload [off] {sym} ptr (MOVWstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => x
-
-(MOVFload [off] {sym} ptr (MOVFstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => x
-(MOVDload [off] {sym} ptr (MOVDstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => x
-
-(MOVWloadidx ptr idx (MOVWstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) => x
-(MOVWloadshiftLL ptr idx [c] (MOVWstoreshiftLL ptr2 idx [d] x _)) && c==d && isSamePtr(ptr, ptr2) => x
-(MOVWloadshiftRL ptr idx [c] (MOVWstoreshiftRL ptr2 idx [d] x _)) && c==d && isSamePtr(ptr, ptr2) => x
-(MOVWloadshiftRA ptr idx [c] (MOVWstoreshiftRA ptr2 idx [d] x _)) && c==d && isSamePtr(ptr, ptr2) => x
-(MOVBUloadidx ptr idx (MOVBstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) => (MOVBUreg x)
-(MOVBloadidx ptr idx (MOVBstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) => (MOVBreg x)
-(MOVHUloadidx ptr idx (MOVHstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) => (MOVHUreg x)
-(MOVHloadidx ptr idx (MOVHstoreidx ptr2 idx x _)) && isSamePtr(ptr, ptr2) => (MOVHreg x)
-
-// fold constant into arithmetic ops
-(ADD x (MOVWconst [c])) => (ADDconst [c] x)
-(SUB (MOVWconst [c]) x) => (RSBconst [c] x)
-(SUB x (MOVWconst [c])) => (SUBconst [c] x)
-(RSB (MOVWconst [c]) x) => (SUBconst [c] x)
-(RSB x (MOVWconst [c])) => (RSBconst [c] x)
-
-(ADDS x (MOVWconst [c])) => (ADDSconst [c] x)
-(SUBS x (MOVWconst [c])) => (SUBSconst [c] x)
-
-(ADC (MOVWconst [c]) x flags) => (ADCconst [c] x flags)
-(SBC (MOVWconst [c]) x flags) => (RSCconst [c] x flags)
-(SBC x (MOVWconst [c]) flags) => (SBCconst [c] x flags)
-
-(AND x (MOVWconst [c])) => (ANDconst [c] x)
-(OR  x (MOVWconst [c])) => (ORconst [c] x)
-(XOR x (MOVWconst [c])) => (XORconst [c] x)
-(BIC x (MOVWconst [c])) => (BICconst [c] x)
-
-(SLL x (MOVWconst [c])) && 0 <= c && c < 32 => (SLLconst x [c])
-(SRL x (MOVWconst [c])) && 0 <= c && c < 32 => (SRLconst x [c])
-(SRA x (MOVWconst [c])) && 0 <= c && c < 32 => (SRAconst x [c])
-
-(CMP x (MOVWconst [c])) => (CMPconst [c] x)
-(CMP (MOVWconst [c]) x) => (InvertFlags (CMPconst [c] x))
-(CMN x (MOVWconst [c])) => (CMNconst [c] x)
-(TST x (MOVWconst [c])) => (TSTconst [c] x)
-(TEQ x (MOVWconst [c])) => (TEQconst [c] x)
-
-(SRR x (MOVWconst [c])) => (SRRconst x [c&31])
-
-// Canonicalize the order of arguments to comparisons - helps with CSE.
-(CMP x y) && canonLessThan(x,y) => (InvertFlags (CMP y x))
-
-// don't extend after proper load
-// MOVWreg instruction is not emitted if src and dst registers are same, but it ensures the type.
-(MOVBreg x:(MOVBload _ _)) => (MOVWreg x)
-(MOVBUreg x:(MOVBUload _ _)) => (MOVWreg x)
-(MOVHreg x:(MOVBload _ _)) => (MOVWreg x)
-(MOVHreg x:(MOVBUload _ _)) => (MOVWreg x)
-(MOVHreg x:(MOVHload _ _)) => (MOVWreg x)
-(MOVHUreg x:(MOVBUload _ _)) => (MOVWreg x)
-(MOVHUreg x:(MOVHUload _ _)) => (MOVWreg x)
-
-// fold extensions and ANDs together
-(MOVBUreg (ANDconst [c] x)) => (ANDconst [c&0xff] x)
-(MOVHUreg (ANDconst [c] x)) => (ANDconst [c&0xffff] x)
-(MOVBreg (ANDconst [c] x)) && c & 0x80 == 0 => (ANDconst [c&0x7f] x)
-(MOVHreg (ANDconst [c] x)) && c & 0x8000 == 0 => (ANDconst [c&0x7fff] x)
-
-// fold double extensions
-(MOVBreg x:(MOVBreg _)) => (MOVWreg x)
-(MOVBUreg x:(MOVBUreg _)) => (MOVWreg x)
-(MOVHreg x:(MOVBreg _)) => (MOVWreg x)
-(MOVHreg x:(MOVBUreg _)) => (MOVWreg x)
-(MOVHreg x:(MOVHreg _)) => (MOVWreg x)
-(MOVHUreg x:(MOVBUreg _)) => (MOVWreg x)
-(MOVHUreg x:(MOVHUreg _)) => (MOVWreg x)
-
-// don't extend before store
-(MOVBstore [off] {sym} ptr (MOVBreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr (MOVBUreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr (MOVHreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr (MOVHUreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
-(MOVHstore [off] {sym} ptr (MOVHreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
-(MOVHstore [off] {sym} ptr (MOVHUreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
-
-// if a register move has only 1 use, just use the same register without emitting instruction
-// MOVWnop doesn't emit instruction, only for ensuring the type.
-(MOVWreg x) && x.Uses == 1 => (MOVWnop x)
-
-// TODO: we should be able to get rid of MOVWnop all together.
-// But for now, this is enough to get rid of lots of them.
-(MOVWnop (MOVWconst [c])) => (MOVWconst [c])
-
-// mul by constant
-(MUL x (MOVWconst [c])) && int32(c) == -1 => (RSBconst [0] x)
-(MUL _ (MOVWconst [0])) => (MOVWconst [0])
-(MUL x (MOVWconst [1])) => x
-(MUL x (MOVWconst [c])) && isPowerOfTwo32(c) => (SLLconst [int32(log32(c))] x)
-(MUL x (MOVWconst [c])) && isPowerOfTwo32(c-1) && c >= 3 => (ADDshiftLL x x [int32(log32(c-1))])
-(MUL x (MOVWconst [c])) && isPowerOfTwo32(c+1) && c >= 7 => (RSBshiftLL x x [int32(log32(c+1))])
-(MUL x (MOVWconst [c])) && c%3 == 0 && isPowerOfTwo32(c/3) => (SLLconst [int32(log32(c/3))] (ADDshiftLL <x.Type> x x [1]))
-(MUL x (MOVWconst [c])) && c%5 == 0 && isPowerOfTwo32(c/5) => (SLLconst [int32(log32(c/5))] (ADDshiftLL <x.Type> x x [2]))
-(MUL x (MOVWconst [c])) && c%7 == 0 && isPowerOfTwo32(c/7) => (SLLconst [int32(log32(c/7))] (RSBshiftLL <x.Type> x x [3]))
-(MUL x (MOVWconst [c])) && c%9 == 0 && isPowerOfTwo32(c/9) => (SLLconst [int32(log32(c/9))] (ADDshiftLL <x.Type> x x [3]))
-
-(MULA x (MOVWconst [c]) a) && c == -1 => (SUB a x)
-(MULA _ (MOVWconst [0]) a) => a
-(MULA x (MOVWconst [1]) a) => (ADD x a)
-(MULA x (MOVWconst [c]) a) && isPowerOfTwo32(c) => (ADD (SLLconst <x.Type> [int32(log32(c))] x) a)
-(MULA x (MOVWconst [c]) a) && isPowerOfTwo32(c-1) && c >= 3 => (ADD (ADDshiftLL <x.Type> x x [int32(log32(c-1))]) a)
-(MULA x (MOVWconst [c]) a) && isPowerOfTwo32(c+1) && c >= 7 => (ADD (RSBshiftLL <x.Type> x x [int32(log32(c+1))]) a)
-(MULA x (MOVWconst [c]) a) && c%3 == 0 && isPowerOfTwo32(c/3) => (ADD (SLLconst <x.Type> [int32(log32(c/3))] (ADDshiftLL <x.Type> x x [1])) a)
-(MULA x (MOVWconst [c]) a) && c%5 == 0 && isPowerOfTwo32(c/5) => (ADD (SLLconst <x.Type> [int32(log32(c/5))] (ADDshiftLL <x.Type> x x [2])) a)
-(MULA x (MOVWconst [c]) a) && c%7 == 0 && isPowerOfTwo32(c/7) => (ADD (SLLconst <x.Type> [int32(log32(c/7))] (RSBshiftLL <x.Type> x x [3])) a)
-(MULA x (MOVWconst [c]) a) && c%9 == 0 && isPowerOfTwo32(c/9) => (ADD (SLLconst <x.Type> [int32(log32(c/9))] (ADDshiftLL <x.Type> x x [3])) a)
-
-(MULA (MOVWconst [c]) x a) && c == -1 => (SUB a x)
-(MULA (MOVWconst [0]) _ a) => a
-(MULA (MOVWconst [1]) x a) => (ADD x a)
-(MULA (MOVWconst [c]) x a) && isPowerOfTwo32(c) => (ADD (SLLconst <x.Type> [int32(log32(c))] x) a)
-(MULA (MOVWconst [c]) x a) && isPowerOfTwo32(c-1) && c >= 3 => (ADD (ADDshiftLL <x.Type> x x [int32(log32(c-1))]) a)
-(MULA (MOVWconst [c]) x a) && isPowerOfTwo32(c+1) && c >= 7 => (ADD (RSBshiftLL <x.Type> x x [int32(log32(c+1))]) a)
-(MULA (MOVWconst [c]) x a) && c%3 == 0 && isPowerOfTwo32(c/3) => (ADD (SLLconst <x.Type> [int32(log32(c/3))] (ADDshiftLL <x.Type> x x [1])) a)
-(MULA (MOVWconst [c]) x a) && c%5 == 0 && isPowerOfTwo32(c/5) => (ADD (SLLconst <x.Type> [int32(log32(c/5))] (ADDshiftLL <x.Type> x x [2])) a)
-(MULA (MOVWconst [c]) x a) && c%7 == 0 && isPowerOfTwo32(c/7) => (ADD (SLLconst <x.Type> [int32(log32(c/7))] (RSBshiftLL <x.Type> x x [3])) a)
-(MULA (MOVWconst [c]) x a) && c%9 == 0 && isPowerOfTwo32(c/9) => (ADD (SLLconst <x.Type> [int32(log32(c/9))] (ADDshiftLL <x.Type> x x [3])) a)
-
-(MULS x (MOVWconst [c]) a) && c == -1 => (ADD a x)
-(MULS _ (MOVWconst [0]) a) => a
-(MULS x (MOVWconst [1]) a) => (RSB x a)
-(MULS x (MOVWconst [c]) a) && isPowerOfTwo32(c) => (RSB (SLLconst <x.Type> [int32(log32(c))] x) a)
-(MULS x (MOVWconst [c]) a) && isPowerOfTwo32(c-1) && c >= 3 => (RSB (ADDshiftLL <x.Type> x x [int32(log32(c-1))]) a)
-(MULS x (MOVWconst [c]) a) && isPowerOfTwo32(c+1) && c >= 7 => (RSB (RSBshiftLL <x.Type> x x [int32(log32(c+1))]) a)
-(MULS x (MOVWconst [c]) a) && c%3 == 0 && isPowerOfTwo32(c/3) => (RSB (SLLconst <x.Type> [int32(log32(c/3))] (ADDshiftLL <x.Type> x x [1])) a)
-(MULS x (MOVWconst [c]) a) && c%5 == 0 && isPowerOfTwo32(c/5) => (RSB (SLLconst <x.Type> [int32(log32(c/5))] (ADDshiftLL <x.Type> x x [2])) a)
-(MULS x (MOVWconst [c]) a) && c%7 == 0 && isPowerOfTwo32(c/7) => (RSB (SLLconst <x.Type> [int32(log32(c/7))] (RSBshiftLL <x.Type> x x [3])) a)
-(MULS x (MOVWconst [c]) a) && c%9 == 0 && isPowerOfTwo32(c/9) => (RSB (SLLconst <x.Type> [int32(log32(c/9))] (ADDshiftLL <x.Type> x x [3])) a)
-
-(MULS (MOVWconst [c]) x a) && c == -1 => (ADD a x)
-(MULS (MOVWconst [0]) _ a) => a
-(MULS (MOVWconst [1]) x a) => (RSB x a)
-(MULS (MOVWconst [c]) x a) && isPowerOfTwo32(c) => (RSB (SLLconst <x.Type> [int32(log32(c))] x) a)
-(MULS (MOVWconst [c]) x a) && isPowerOfTwo32(c-1) && c >= 3 => (RSB (ADDshiftLL <x.Type> x x [int32(log32(c-1))]) a)
-(MULS (MOVWconst [c]) x a) && isPowerOfTwo32(c+1) && c >= 7 => (RSB (RSBshiftLL <x.Type> x x [int32(log32(c+1))]) a)
-(MULS (MOVWconst [c]) x a) && c%3 == 0 && isPowerOfTwo32(c/3) => (RSB (SLLconst <x.Type> [int32(log32(c/3))] (ADDshiftLL <x.Type> x x [1])) a)
-(MULS (MOVWconst [c]) x a) && c%5 == 0 && isPowerOfTwo32(c/5) => (RSB (SLLconst <x.Type> [int32(log32(c/5))] (ADDshiftLL <x.Type> x x [2])) a)
-(MULS (MOVWconst [c]) x a) && c%7 == 0 && isPowerOfTwo32(c/7) => (RSB (SLLconst <x.Type> [int32(log32(c/7))] (RSBshiftLL <x.Type> x x [3])) a)
-(MULS (MOVWconst [c]) x a) && c%9 == 0 && isPowerOfTwo32(c/9) => (RSB (SLLconst <x.Type> [int32(log32(c/9))] (ADDshiftLL <x.Type> x x [3])) a)
-
-// div by constant
-(Select0 (CALLudiv x (MOVWconst [1]))) => x
-(Select1 (CALLudiv _ (MOVWconst [1]))) => (MOVWconst [0])
-(Select0 (CALLudiv x (MOVWconst [c]))) && isPowerOfTwo32(c) => (SRLconst [int32(log32(c))] x)
-(Select1 (CALLudiv x (MOVWconst [c]))) && isPowerOfTwo32(c) => (ANDconst [c-1] x)
-
-// constant comparisons
-(CMPconst (MOVWconst [x]) [y]) => (FlagConstant [subFlags32(x,y)])
-(CMNconst (MOVWconst [x]) [y]) => (FlagConstant [addFlags32(x,y)])
-(TSTconst (MOVWconst [x]) [y]) => (FlagConstant [logicFlags32(x&y)])
-(TEQconst (MOVWconst [x]) [y]) => (FlagConstant [logicFlags32(x^y)])
-
-// other known comparisons
-(CMPconst (MOVBUreg _) [c]) && 0xff < c => (FlagConstant [subFlags32(0, 1)])
-(CMPconst (MOVHUreg _) [c]) && 0xffff < c => (FlagConstant [subFlags32(0, 1)])
-(CMPconst (ANDconst _ [m]) [n]) && 0 <= m && m < n => (FlagConstant [subFlags32(0, 1)])
-(CMPconst (SRLconst _ [c]) [n]) && 0 <= n && 0 < c && c <= 32 && (1<<uint32(32-c)) <= uint32(n) => (FlagConstant [subFlags32(0, 1)])
-
-// absorb flag constants into branches
-(EQ (FlagConstant [fc]) yes no) &&  fc.eq() => (First yes no)
-(EQ (FlagConstant [fc]) yes no) && !fc.eq() => (First no yes)
-
-(NE (FlagConstant [fc]) yes no) &&  fc.ne() => (First yes no)
-(NE (FlagConstant [fc]) yes no) && !fc.ne() => (First no yes)
-
-(LT (FlagConstant [fc]) yes no) &&  fc.lt() => (First yes no)
-(LT (FlagConstant [fc]) yes no) && !fc.lt() => (First no yes)
-
-(LE (FlagConstant [fc]) yes no) &&  fc.le() => (First yes no)
-(LE (FlagConstant [fc]) yes no) && !fc.le() => (First no yes)
-
-(GT (FlagConstant [fc]) yes no) &&  fc.gt() => (First yes no)
-(GT (FlagConstant [fc]) yes no) && !fc.gt() => (First no yes)
-
-(GE (FlagConstant [fc]) yes no) &&  fc.ge() => (First yes no)
-(GE (FlagConstant [fc]) yes no) && !fc.ge() => (First no yes)
-
-(ULT (FlagConstant [fc]) yes no) &&  fc.ult() => (First yes no)
-(ULT (FlagConstant [fc]) yes no) && !fc.ult() => (First no yes)
-
-(ULE (FlagConstant [fc]) yes no) &&  fc.ule() => (First yes no)
-(ULE (FlagConstant [fc]) yes no) && !fc.ule() => (First no yes)
-
-(UGT (FlagConstant [fc]) yes no) &&  fc.ugt() => (First yes no)
-(UGT (FlagConstant [fc]) yes no) && !fc.ugt() => (First no yes)
-
-(UGE (FlagConstant [fc]) yes no) &&  fc.uge() => (First yes no)
-(UGE (FlagConstant [fc]) yes no) && !fc.uge() => (First no yes)
-
-(LTnoov (FlagConstant [fc]) yes no) &&  fc.ltNoov() => (First yes no)
-(LTnoov (FlagConstant [fc]) yes no) && !fc.ltNoov() => (First no yes)
-
-(LEnoov (FlagConstant [fc]) yes no) &&  fc.leNoov() => (First yes no)
-(LEnoov (FlagConstant [fc]) yes no) && !fc.leNoov() => (First no yes)
-
-(GTnoov (FlagConstant [fc]) yes no) &&  fc.gtNoov() => (First yes no)
-(GTnoov (FlagConstant [fc]) yes no) && !fc.gtNoov() => (First no yes)
-
-(GEnoov (FlagConstant [fc]) yes no) &&  fc.geNoov() => (First yes no)
-(GEnoov (FlagConstant [fc]) yes no) && !fc.geNoov() => (First no yes)
-
-// absorb InvertFlags into branches
-(LT (InvertFlags cmp) yes no) => (GT cmp yes no)
-(GT (InvertFlags cmp) yes no) => (LT cmp yes no)
-(LE (InvertFlags cmp) yes no) => (GE cmp yes no)
-(GE (InvertFlags cmp) yes no) => (LE cmp yes no)
-(ULT (InvertFlags cmp) yes no) => (UGT cmp yes no)
-(UGT (InvertFlags cmp) yes no) => (ULT cmp yes no)
-(ULE (InvertFlags cmp) yes no) => (UGE cmp yes no)
-(UGE (InvertFlags cmp) yes no) => (ULE cmp yes no)
-(EQ (InvertFlags cmp) yes no) => (EQ cmp yes no)
-(NE (InvertFlags cmp) yes no) => (NE cmp yes no)
-(LTnoov (InvertFlags cmp) yes no) => (GTnoov cmp yes no)
-(GEnoov (InvertFlags cmp) yes no) => (LEnoov cmp yes no)
-(LEnoov (InvertFlags cmp) yes no) => (GEnoov cmp yes no)
-(GTnoov (InvertFlags cmp) yes no) => (LTnoov cmp yes no)
-
-// absorb flag constants into boolean values
-(Equal (FlagConstant [fc])) => (MOVWconst [b2i32(fc.eq())])
-(NotEqual (FlagConstant [fc])) => (MOVWconst [b2i32(fc.ne())])
-(LessThan (FlagConstant [fc])) => (MOVWconst [b2i32(fc.lt())])
-(LessThanU (FlagConstant [fc])) => (MOVWconst [b2i32(fc.ult())])
-(LessEqual (FlagConstant [fc])) => (MOVWconst [b2i32(fc.le())])
-(LessEqualU (FlagConstant [fc])) => (MOVWconst [b2i32(fc.ule())])
-(GreaterThan (FlagConstant [fc])) => (MOVWconst [b2i32(fc.gt())])
-(GreaterThanU (FlagConstant [fc])) => (MOVWconst [b2i32(fc.ugt())])
-(GreaterEqual (FlagConstant [fc])) => (MOVWconst [b2i32(fc.ge())])
-(GreaterEqualU (FlagConstant [fc])) => (MOVWconst [b2i32(fc.uge())])
-
-// absorb InvertFlags into boolean values
-(Equal (InvertFlags x)) => (Equal x)
-(NotEqual (InvertFlags x)) => (NotEqual x)
-(LessThan (InvertFlags x)) => (GreaterThan x)
-(LessThanU (InvertFlags x)) => (GreaterThanU x)
-(GreaterThan (InvertFlags x)) => (LessThan x)
-(GreaterThanU (InvertFlags x)) => (LessThanU x)
-(LessEqual (InvertFlags x)) => (GreaterEqual x)
-(LessEqualU (InvertFlags x)) => (GreaterEqualU x)
-(GreaterEqual (InvertFlags x)) => (LessEqual x)
-(GreaterEqualU (InvertFlags x)) => (LessEqualU x)
-
-// absorb flag constants into conditional instructions
-(CMOVWLSconst _ (FlagConstant [fc]) [c]) && fc.ule() => (MOVWconst [c])
-(CMOVWLSconst x (FlagConstant [fc]) [c]) && fc.ugt() => x
-
-(CMOVWHSconst _ (FlagConstant [fc]) [c]) && fc.uge() => (MOVWconst [c])
-(CMOVWHSconst x (FlagConstant [fc]) [c]) && fc.ult() => x
-
-(CMOVWLSconst x (InvertFlags flags) [c]) => (CMOVWHSconst x flags [c])
-(CMOVWHSconst x (InvertFlags flags) [c]) => (CMOVWLSconst x flags [c])
-
-(SRAcond x _ (FlagConstant [fc])) && fc.uge() => (SRAconst x [31])
-(SRAcond x y (FlagConstant [fc])) && fc.ult() => (SRA x y)
-
-// remove redundant *const ops
-(ADDconst [0] x) => x
-(SUBconst [0] x) => x
-(ANDconst [0] _) => (MOVWconst [0])
-(ANDconst [c] x) && int32(c)==-1 => x
-(ORconst [0] x) => x
-(ORconst [c] _) && int32(c)==-1 => (MOVWconst [-1])
-(XORconst [0] x) => x
-(BICconst [0] x) => x
-(BICconst [c] _) && int32(c)==-1 => (MOVWconst [0])
-
-// generic constant folding
-(ADDconst [c] x) && !isARMImmRot(uint32(c)) && isARMImmRot(uint32(-c)) => (SUBconst [-c] x)
-(SUBconst [c] x) && !isARMImmRot(uint32(c)) && isARMImmRot(uint32(-c)) => (ADDconst [-c] x)
-(ANDconst [c] x) && !isARMImmRot(uint32(c)) && isARMImmRot(^uint32(c)) => (BICconst [int32(^uint32(c))] x)
-(BICconst [c] x) && !isARMImmRot(uint32(c)) && isARMImmRot(^uint32(c)) => (ANDconst [int32(^uint32(c))] x)
-(ADDconst [c] x) && buildcfg.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && uint32(-c)<=0xffff => (SUBconst [-c] x)
-(SUBconst [c] x) && buildcfg.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && uint32(-c)<=0xffff => (ADDconst [-c] x)
-(ANDconst [c] x) && buildcfg.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && ^uint32(c)<=0xffff => (BICconst [int32(^uint32(c))] x)
-(BICconst [c] x) && buildcfg.GOARM==7 && !isARMImmRot(uint32(c)) && uint32(c)>0xffff && ^uint32(c)<=0xffff => (ANDconst [int32(^uint32(c))] x)
-(ADDconst [c] (MOVWconst [d])) => (MOVWconst [c+d])
-(ADDconst [c] (ADDconst [d] x)) => (ADDconst [c+d] x)
-(ADDconst [c] (SUBconst [d] x)) => (ADDconst [c-d] x)
-(ADDconst [c] (RSBconst [d] x)) => (RSBconst [c+d] x)
-(ADCconst [c] (ADDconst [d] x) flags) => (ADCconst [c+d] x flags)
-(ADCconst [c] (SUBconst [d] x) flags) => (ADCconst [c-d] x flags)
-(SUBconst [c] (MOVWconst [d])) => (MOVWconst [d-c])
-(SUBconst [c] (SUBconst [d] x)) => (ADDconst [-c-d] x)
-(SUBconst [c] (ADDconst [d] x)) => (ADDconst [-c+d] x)
-(SUBconst [c] (RSBconst [d] x)) => (RSBconst [-c+d] x)
-(SBCconst [c] (ADDconst [d] x) flags) => (SBCconst [c-d] x flags)
-(SBCconst [c] (SUBconst [d] x) flags) => (SBCconst [c+d] x flags)
-(RSBconst [c] (MOVWconst [d])) => (MOVWconst [c-d])
-(RSBconst [c] (RSBconst [d] x)) => (ADDconst [c-d] x)
-(RSBconst [c] (ADDconst [d] x)) => (RSBconst [c-d] x)
-(RSBconst [c] (SUBconst [d] x)) => (RSBconst [c+d] x)
-(RSCconst [c] (ADDconst [d] x) flags) => (RSCconst [c-d] x flags)
-(RSCconst [c] (SUBconst [d] x) flags) => (RSCconst [c+d] x flags)
-(SLLconst [c] (MOVWconst [d])) => (MOVWconst [d<<uint64(c)])
-(SRLconst [c] (MOVWconst [d])) => (MOVWconst [int32(uint32(d)>>uint64(c))])
-(SRAconst [c] (MOVWconst [d])) => (MOVWconst [d>>uint64(c)])
-(MUL (MOVWconst [c]) (MOVWconst [d])) => (MOVWconst [c*d])
-(MULA (MOVWconst [c]) (MOVWconst [d]) a) => (ADDconst [c*d] a)
-(MULS (MOVWconst [c]) (MOVWconst [d]) a) => (SUBconst [c*d] a)
-(Select0 (CALLudiv (MOVWconst [c]) (MOVWconst [d]))) && d != 0 => (MOVWconst [int32(uint32(c)/uint32(d))])
-(Select1 (CALLudiv (MOVWconst [c]) (MOVWconst [d]))) && d != 0 => (MOVWconst [int32(uint32(c)%uint32(d))])
-(ANDconst [c] (MOVWconst [d])) => (MOVWconst [c&d])
-(ANDconst [c] (ANDconst [d] x)) => (ANDconst [c&d] x)
-(ORconst [c] (MOVWconst [d])) => (MOVWconst [c|d])
-(ORconst [c] (ORconst [d] x)) => (ORconst [c|d] x)
-(XORconst [c] (MOVWconst [d])) => (MOVWconst [c^d])
-(XORconst [c] (XORconst [d] x)) => (XORconst [c^d] x)
-(BICconst [c] (MOVWconst [d])) => (MOVWconst [d&^c])
-(BICconst [c] (BICconst [d] x)) => (BICconst [c|d] x)
-(MVN (MOVWconst [c])) => (MOVWconst [^c])
-(MOVBreg (MOVWconst [c])) => (MOVWconst [int32(int8(c))])
-(MOVBUreg (MOVWconst [c])) => (MOVWconst [int32(uint8(c))])
-(MOVHreg (MOVWconst [c])) => (MOVWconst [int32(int16(c))])
-(MOVHUreg (MOVWconst [c])) => (MOVWconst [int32(uint16(c))])
-(MOVWreg (MOVWconst [c])) => (MOVWconst [c])
-// BFX: Width = c >> 8, LSB = c & 0xff, result = d << (32 - Width - LSB) >> (32 - Width)
-(BFX [c] (MOVWconst [d])) => (MOVWconst [d<<(32-uint32(c&0xff)-uint32(c>>8))>>(32-uint32(c>>8))])
-(BFXU [c] (MOVWconst [d])) => (MOVWconst [int32(uint32(d)<<(32-uint32(c&0xff)-uint32(c>>8))>>(32-uint32(c>>8)))])
-
-// absorb shifts into ops
-(ADD x (SLLconst [c] y)) => (ADDshiftLL x y [c])
-(ADD x (SRLconst [c] y)) => (ADDshiftRL x y [c])
-(ADD x (SRAconst [c] y)) => (ADDshiftRA x y [c])
-(ADD x (SLL y z)) => (ADDshiftLLreg x y z)
-(ADD x (SRL y z)) => (ADDshiftRLreg x y z)
-(ADD x (SRA y z)) => (ADDshiftRAreg x y z)
-(ADC x (SLLconst [c] y) flags) => (ADCshiftLL x y [c] flags)
-(ADC x (SRLconst [c] y) flags) => (ADCshiftRL x y [c] flags)
-(ADC x (SRAconst [c] y) flags) => (ADCshiftRA x y [c] flags)
-(ADC x (SLL y z) flags) => (ADCshiftLLreg x y z flags)
-(ADC x (SRL y z) flags) => (ADCshiftRLreg x y z flags)
-(ADC x (SRA y z) flags) => (ADCshiftRAreg x y z flags)
-(ADDS x (SLLconst [c] y)) => (ADDSshiftLL x y [c])
-(ADDS x (SRLconst [c] y)) => (ADDSshiftRL x y [c])
-(ADDS x (SRAconst [c] y)) => (ADDSshiftRA x y [c])
-(ADDS x (SLL y z)) => (ADDSshiftLLreg x y z)
-(ADDS x (SRL y z)) => (ADDSshiftRLreg x y z)
-(ADDS x (SRA y z)) => (ADDSshiftRAreg x y z)
-(SUB x (SLLconst [c] y)) => (SUBshiftLL x y [c])
-(SUB (SLLconst [c] y) x) => (RSBshiftLL x y [c])
-(SUB x (SRLconst [c] y)) => (SUBshiftRL x y [c])
-(SUB (SRLconst [c] y) x) => (RSBshiftRL x y [c])
-(SUB x (SRAconst [c] y)) => (SUBshiftRA x y [c])
-(SUB (SRAconst [c] y) x) => (RSBshiftRA x y [c])
-(SUB x (SLL y z)) => (SUBshiftLLreg x y z)
-(SUB (SLL y z) x) => (RSBshiftLLreg x y z)
-(SUB x (SRL y z)) => (SUBshiftRLreg x y z)
-(SUB (SRL y z) x) => (RSBshiftRLreg x y z)
-(SUB x (SRA y z)) => (SUBshiftRAreg x y z)
-(SUB (SRA y z) x) => (RSBshiftRAreg x y z)
-(SBC x (SLLconst [c] y) flags) => (SBCshiftLL x y [c] flags)
-(SBC (SLLconst [c] y) x flags) => (RSCshiftLL x y [c] flags)
-(SBC x (SRLconst [c] y) flags) => (SBCshiftRL x y [c] flags)
-(SBC (SRLconst [c] y) x flags) => (RSCshiftRL x y [c] flags)
-(SBC x (SRAconst [c] y) flags) => (SBCshiftRA x y [c] flags)
-(SBC (SRAconst [c] y) x flags) => (RSCshiftRA x y [c] flags)
-(SBC x (SLL y z) flags) => (SBCshiftLLreg x y z flags)
-(SBC (SLL y z) x flags) => (RSCshiftLLreg x y z flags)
-(SBC x (SRL y z) flags) => (SBCshiftRLreg x y z flags)
-(SBC (SRL y z) x flags) => (RSCshiftRLreg x y z flags)
-(SBC x (SRA y z) flags) => (SBCshiftRAreg x y z flags)
-(SBC (SRA y z) x flags) => (RSCshiftRAreg x y z flags)
-(SUBS x (SLLconst [c] y)) => (SUBSshiftLL x y [c])
-(SUBS (SLLconst [c] y) x) => (RSBSshiftLL x y [c])
-(SUBS x (SRLconst [c] y)) => (SUBSshiftRL x y [c])
-(SUBS (SRLconst [c] y) x) => (RSBSshiftRL x y [c])
-(SUBS x (SRAconst [c] y)) => (SUBSshiftRA x y [c])
-(SUBS (SRAconst [c] y) x) => (RSBSshiftRA x y [c])
-(SUBS x (SLL y z)) => (SUBSshiftLLreg x y z)
-(SUBS (SLL y z) x) => (RSBSshiftLLreg x y z)
-(SUBS x (SRL y z)) => (SUBSshiftRLreg x y z)
-(SUBS (SRL y z) x) => (RSBSshiftRLreg x y z)
-(SUBS x (SRA y z)) => (SUBSshiftRAreg x y z)
-(SUBS (SRA y z) x) => (RSBSshiftRAreg x y z)
-(RSB x (SLLconst [c] y)) => (RSBshiftLL x y [c])
-(RSB (SLLconst [c] y) x) => (SUBshiftLL x y [c])
-(RSB x (SRLconst [c] y)) => (RSBshiftRL x y [c])
-(RSB (SRLconst [c] y) x) => (SUBshiftRL x y [c])
-(RSB x (SRAconst [c] y)) => (RSBshiftRA x y [c])
-(RSB (SRAconst [c] y) x) => (SUBshiftRA x y [c])
-(RSB x (SLL y z)) => (RSBshiftLLreg x y z)
-(RSB (SLL y z) x) => (SUBshiftLLreg x y z)
-(RSB x (SRL y z)) => (RSBshiftRLreg x y z)
-(RSB (SRL y z) x) => (SUBshiftRLreg x y z)
-(RSB x (SRA y z)) => (RSBshiftRAreg x y z)
-(RSB (SRA y z) x) => (SUBshiftRAreg x y z)
-(AND x (SLLconst [c] y)) => (ANDshiftLL x y [c])
-(AND x (SRLconst [c] y)) => (ANDshiftRL x y [c])
-(AND x (SRAconst [c] y)) => (ANDshiftRA x y [c])
-(AND x (SLL y z)) => (ANDshiftLLreg x y z)
-(AND x (SRL y z)) => (ANDshiftRLreg x y z)
-(AND x (SRA y z)) => (ANDshiftRAreg x y z)
-(OR x (SLLconst [c] y)) => (ORshiftLL x y [c])
-(OR x (SRLconst [c] y)) => (ORshiftRL x y [c])
-(OR x (SRAconst [c] y)) => (ORshiftRA x y [c])
-(OR x (SLL y z)) => (ORshiftLLreg x y z)
-(OR x (SRL y z)) => (ORshiftRLreg x y z)
-(OR x (SRA y z)) => (ORshiftRAreg x y z)
-(XOR x (SLLconst [c] y)) => (XORshiftLL x y [c])
-(XOR x (SRLconst [c] y)) => (XORshiftRL x y [c])
-(XOR x (SRAconst [c] y)) => (XORshiftRA x y [c])
-(XOR x (SRRconst [c] y)) => (XORshiftRR x y [c])
-(XOR x (SLL y z)) => (XORshiftLLreg x y z)
-(XOR x (SRL y z)) => (XORshiftRLreg x y z)
-(XOR x (SRA y z)) => (XORshiftRAreg x y z)
-(BIC x (SLLconst [c] y)) => (BICshiftLL x y [c])
-(BIC x (SRLconst [c] y)) => (BICshiftRL x y [c])
-(BIC x (SRAconst [c] y)) => (BICshiftRA x y [c])
-(BIC x (SLL y z)) => (BICshiftLLreg x y z)
-(BIC x (SRL y z)) => (BICshiftRLreg x y z)
-(BIC x (SRA y z)) => (BICshiftRAreg x y z)
-(MVN (SLLconst [c] x)) => (MVNshiftLL x [c])
-(MVN (SRLconst [c] x)) => (MVNshiftRL x [c])
-(MVN (SRAconst [c] x)) => (MVNshiftRA x [c])
-(MVN (SLL x y)) => (MVNshiftLLreg x y)
-(MVN (SRL x y)) => (MVNshiftRLreg x y)
-(MVN (SRA x y)) => (MVNshiftRAreg x y)
-
-(CMP x (SLLconst [c] y)) => (CMPshiftLL x y [c])
-(CMP (SLLconst [c] y) x) => (InvertFlags (CMPshiftLL x y [c]))
-(CMP x (SRLconst [c] y)) => (CMPshiftRL x y [c])
-(CMP (SRLconst [c] y) x) => (InvertFlags (CMPshiftRL x y [c]))
-(CMP x (SRAconst [c] y)) => (CMPshiftRA x y [c])
-(CMP (SRAconst [c] y) x) => (InvertFlags (CMPshiftRA x y [c]))
-(CMP x (SLL y z)) => (CMPshiftLLreg x y z)
-(CMP (SLL y z) x) => (InvertFlags (CMPshiftLLreg x y z))
-(CMP x (SRL y z)) => (CMPshiftRLreg x y z)
-(CMP (SRL y z) x) => (InvertFlags (CMPshiftRLreg x y z))
-(CMP x (SRA y z)) => (CMPshiftRAreg x y z)
-(CMP (SRA y z) x) => (InvertFlags (CMPshiftRAreg x y z))
-(TST x (SLLconst [c] y)) => (TSTshiftLL x y [c])
-(TST x (SRLconst [c] y)) => (TSTshiftRL x y [c])
-(TST x (SRAconst [c] y)) => (TSTshiftRA x y [c])
-(TST x (SLL y z)) => (TSTshiftLLreg x y z)
-(TST x (SRL y z)) => (TSTshiftRLreg x y z)
-(TST x (SRA y z)) => (TSTshiftRAreg x y z)
-(TEQ x (SLLconst [c] y)) => (TEQshiftLL x y [c])
-(TEQ x (SRLconst [c] y)) => (TEQshiftRL x y [c])
-(TEQ x (SRAconst [c] y)) => (TEQshiftRA x y [c])
-(TEQ x (SLL y z)) => (TEQshiftLLreg x y z)
-(TEQ x (SRL y z)) => (TEQshiftRLreg x y z)
-(TEQ x (SRA y z)) => (TEQshiftRAreg x y z)
-(CMN x (SLLconst [c] y)) => (CMNshiftLL x y [c])
-(CMN x (SRLconst [c] y)) => (CMNshiftRL x y [c])
-(CMN x (SRAconst [c] y)) => (CMNshiftRA x y [c])
-(CMN x (SLL y z)) => (CMNshiftLLreg x y z)
-(CMN x (SRL y z)) => (CMNshiftRLreg x y z)
-(CMN x (SRA y z)) => (CMNshiftRAreg x y z)
-
-// prefer *const ops to *shift ops
-(ADDshiftLL (MOVWconst [c]) x [d]) => (ADDconst [c] (SLLconst <x.Type> x [d]))
-(ADDshiftRL (MOVWconst [c]) x [d]) => (ADDconst [c] (SRLconst <x.Type> x [d]))
-(ADDshiftRA (MOVWconst [c]) x [d]) => (ADDconst [c] (SRAconst <x.Type> x [d]))
-(ADCshiftLL (MOVWconst [c]) x [d] flags) => (ADCconst [c] (SLLconst <x.Type> x [d]) flags)
-(ADCshiftRL (MOVWconst [c]) x [d] flags) => (ADCconst [c] (SRLconst <x.Type> x [d]) flags)
-(ADCshiftRA (MOVWconst [c]) x [d] flags) => (ADCconst [c] (SRAconst <x.Type> x [d]) flags)
-(ADDSshiftLL (MOVWconst [c]) x [d]) => (ADDSconst [c] (SLLconst <x.Type> x [d]))
-(ADDSshiftRL (MOVWconst [c]) x [d]) => (ADDSconst [c] (SRLconst <x.Type> x [d]))
-(ADDSshiftRA (MOVWconst [c]) x [d]) => (ADDSconst [c] (SRAconst <x.Type> x [d]))
-(SUBshiftLL (MOVWconst [c]) x [d]) => (RSBconst [c] (SLLconst <x.Type> x [d]))
-(SUBshiftRL (MOVWconst [c]) x [d]) => (RSBconst [c] (SRLconst <x.Type> x [d]))
-(SUBshiftRA (MOVWconst [c]) x [d]) => (RSBconst [c] (SRAconst <x.Type> x [d]))
-(SBCshiftLL (MOVWconst [c]) x [d] flags) => (RSCconst [c] (SLLconst <x.Type> x [d]) flags)
-(SBCshiftRL (MOVWconst [c]) x [d] flags) => (RSCconst [c] (SRLconst <x.Type> x [d]) flags)
-(SBCshiftRA (MOVWconst [c]) x [d] flags) => (RSCconst [c] (SRAconst <x.Type> x [d]) flags)
-(SUBSshiftLL (MOVWconst [c]) x [d]) => (RSBSconst [c] (SLLconst <x.Type> x [d]))
-(SUBSshiftRL (MOVWconst [c]) x [d]) => (RSBSconst [c] (SRLconst <x.Type> x [d]))
-(SUBSshiftRA (MOVWconst [c]) x [d]) => (RSBSconst [c] (SRAconst <x.Type> x [d]))
-(RSBshiftLL (MOVWconst [c]) x [d]) => (SUBconst [c] (SLLconst <x.Type> x [d]))
-(RSBshiftRL (MOVWconst [c]) x [d]) => (SUBconst [c] (SRLconst <x.Type> x [d]))
-(RSBshiftRA (MOVWconst [c]) x [d]) => (SUBconst [c] (SRAconst <x.Type> x [d]))
-(RSCshiftLL (MOVWconst [c]) x [d] flags) => (SBCconst [c] (SLLconst <x.Type> x [d]) flags)
-(RSCshiftRL (MOVWconst [c]) x [d] flags) => (SBCconst [c] (SRLconst <x.Type> x [d]) flags)
-(RSCshiftRA (MOVWconst [c]) x [d] flags) => (SBCconst [c] (SRAconst <x.Type> x [d]) flags)
-(RSBSshiftLL (MOVWconst [c]) x [d]) => (SUBSconst [c] (SLLconst <x.Type> x [d]))
-(RSBSshiftRL (MOVWconst [c]) x [d]) => (SUBSconst [c] (SRLconst <x.Type> x [d]))
-(RSBSshiftRA (MOVWconst [c]) x [d]) => (SUBSconst [c] (SRAconst <x.Type> x [d]))
-(ANDshiftLL (MOVWconst [c]) x [d]) => (ANDconst [c] (SLLconst <x.Type> x [d]))
-(ANDshiftRL (MOVWconst [c]) x [d]) => (ANDconst [c] (SRLconst <x.Type> x [d]))
-(ANDshiftRA (MOVWconst [c]) x [d]) => (ANDconst [c] (SRAconst <x.Type> x [d]))
-(ORshiftLL (MOVWconst [c]) x [d]) => (ORconst [c] (SLLconst <x.Type> x [d]))
-(ORshiftRL (MOVWconst [c]) x [d]) => (ORconst [c] (SRLconst <x.Type> x [d]))
-(ORshiftRA (MOVWconst [c]) x [d]) => (ORconst [c] (SRAconst <x.Type> x [d]))
-(XORshiftLL (MOVWconst [c]) x [d]) => (XORconst [c] (SLLconst <x.Type> x [d]))
-(XORshiftRL (MOVWconst [c]) x [d]) => (XORconst [c] (SRLconst <x.Type> x [d]))
-(XORshiftRA (MOVWconst [c]) x [d]) => (XORconst [c] (SRAconst <x.Type> x [d]))
-(XORshiftRR (MOVWconst [c]) x [d]) => (XORconst [c] (SRRconst <x.Type> x [d]))
-(CMPshiftLL (MOVWconst [c]) x [d]) => (InvertFlags (CMPconst [c] (SLLconst <x.Type> x [d])))
-(CMPshiftRL (MOVWconst [c]) x [d]) => (InvertFlags (CMPconst [c] (SRLconst <x.Type> x [d])))
-(CMPshiftRA (MOVWconst [c]) x [d]) => (InvertFlags (CMPconst [c] (SRAconst <x.Type> x [d])))
-(TSTshiftLL (MOVWconst [c]) x [d]) => (TSTconst [c] (SLLconst <x.Type> x [d]))
-(TSTshiftRL (MOVWconst [c]) x [d]) => (TSTconst [c] (SRLconst <x.Type> x [d]))
-(TSTshiftRA (MOVWconst [c]) x [d]) => (TSTconst [c] (SRAconst <x.Type> x [d]))
-(TEQshiftLL (MOVWconst [c]) x [d]) => (TEQconst [c] (SLLconst <x.Type> x [d]))
-(TEQshiftRL (MOVWconst [c]) x [d]) => (TEQconst [c] (SRLconst <x.Type> x [d]))
-(TEQshiftRA (MOVWconst [c]) x [d]) => (TEQconst [c] (SRAconst <x.Type> x [d]))
-(CMNshiftLL (MOVWconst [c]) x [d]) => (CMNconst [c] (SLLconst <x.Type> x [d]))
-(CMNshiftRL (MOVWconst [c]) x [d]) => (CMNconst [c] (SRLconst <x.Type> x [d]))
-(CMNshiftRA (MOVWconst [c]) x [d]) => (CMNconst [c] (SRAconst <x.Type> x [d]))
-
-(ADDshiftLLreg (MOVWconst [c]) x y) => (ADDconst [c] (SLL <x.Type> x y))
-(ADDshiftRLreg (MOVWconst [c]) x y) => (ADDconst [c] (SRL <x.Type> x y))
-(ADDshiftRAreg (MOVWconst [c]) x y) => (ADDconst [c] (SRA <x.Type> x y))
-(ADCshiftLLreg (MOVWconst [c]) x y flags) => (ADCconst [c] (SLL <x.Type> x y) flags)
-(ADCshiftRLreg (MOVWconst [c]) x y flags) => (ADCconst [c] (SRL <x.Type> x y) flags)
-(ADCshiftRAreg (MOVWconst [c]) x y flags) => (ADCconst [c] (SRA <x.Type> x y) flags)
-(ADDSshiftLLreg (MOVWconst [c]) x y) => (ADDSconst [c] (SLL <x.Type> x y))
-(ADDSshiftRLreg (MOVWconst [c]) x y) => (ADDSconst [c] (SRL <x.Type> x y))
-(ADDSshiftRAreg (MOVWconst [c]) x y) => (ADDSconst [c] (SRA <x.Type> x y))
-(SUBshiftLLreg (MOVWconst [c]) x y) => (RSBconst [c] (SLL <x.Type> x y))
-(SUBshiftRLreg (MOVWconst [c]) x y) => (RSBconst [c] (SRL <x.Type> x y))
-(SUBshiftRAreg (MOVWconst [c]) x y) => (RSBconst [c] (SRA <x.Type> x y))
-(SBCshiftLLreg (MOVWconst [c]) x y flags) => (RSCconst [c] (SLL <x.Type> x y) flags)
-(SBCshiftRLreg (MOVWconst [c]) x y flags) => (RSCconst [c] (SRL <x.Type> x y) flags)
-(SBCshiftRAreg (MOVWconst [c]) x y flags) => (RSCconst [c] (SRA <x.Type> x y) flags)
-(SUBSshiftLLreg (MOVWconst [c]) x y) => (RSBSconst [c] (SLL <x.Type> x y))
-(SUBSshiftRLreg (MOVWconst [c]) x y) => (RSBSconst [c] (SRL <x.Type> x y))
-(SUBSshiftRAreg (MOVWconst [c]) x y) => (RSBSconst [c] (SRA <x.Type> x y))
-(RSBshiftLLreg (MOVWconst [c]) x y) => (SUBconst [c] (SLL <x.Type> x y))
-(RSBshiftRLreg (MOVWconst [c]) x y) => (SUBconst [c] (SRL <x.Type> x y))
-(RSBshiftRAreg (MOVWconst [c]) x y) => (SUBconst [c] (SRA <x.Type> x y))
-(RSCshiftLLreg (MOVWconst [c]) x y flags) => (SBCconst [c] (SLL <x.Type> x y) flags)
-(RSCshiftRLreg (MOVWconst [c]) x y flags) => (SBCconst [c] (SRL <x.Type> x y) flags)
-(RSCshiftRAreg (MOVWconst [c]) x y flags) => (SBCconst [c] (SRA <x.Type> x y) flags)
-(RSBSshiftLLreg (MOVWconst [c]) x y) => (SUBSconst [c] (SLL <x.Type> x y))
-(RSBSshiftRLreg (MOVWconst [c]) x y) => (SUBSconst [c] (SRL <x.Type> x y))
-(RSBSshiftRAreg (MOVWconst [c]) x y) => (SUBSconst [c] (SRA <x.Type> x y))
-(ANDshiftLLreg (MOVWconst [c]) x y) => (ANDconst [c] (SLL <x.Type> x y))
-(ANDshiftRLreg (MOVWconst [c]) x y) => (ANDconst [c] (SRL <x.Type> x y))
-(ANDshiftRAreg (MOVWconst [c]) x y) => (ANDconst [c] (SRA <x.Type> x y))
-(ORshiftLLreg (MOVWconst [c]) x y) => (ORconst [c] (SLL <x.Type> x y))
-(ORshiftRLreg (MOVWconst [c]) x y) => (ORconst [c] (SRL <x.Type> x y))
-(ORshiftRAreg (MOVWconst [c]) x y) => (ORconst [c] (SRA <x.Type> x y))
-(XORshiftLLreg (MOVWconst [c]) x y) => (XORconst [c] (SLL <x.Type> x y))
-(XORshiftRLreg (MOVWconst [c]) x y) => (XORconst [c] (SRL <x.Type> x y))
-(XORshiftRAreg (MOVWconst [c]) x y) => (XORconst [c] (SRA <x.Type> x y))
-(CMPshiftLLreg (MOVWconst [c]) x y) => (InvertFlags (CMPconst [c] (SLL <x.Type> x y)))
-(CMPshiftRLreg (MOVWconst [c]) x y) => (InvertFlags (CMPconst [c] (SRL <x.Type> x y)))
-(CMPshiftRAreg (MOVWconst [c]) x y) => (InvertFlags (CMPconst [c] (SRA <x.Type> x y)))
-(TSTshiftLLreg (MOVWconst [c]) x y) => (TSTconst [c] (SLL <x.Type> x y))
-(TSTshiftRLreg (MOVWconst [c]) x y) => (TSTconst [c] (SRL <x.Type> x y))
-(TSTshiftRAreg (MOVWconst [c]) x y) => (TSTconst [c] (SRA <x.Type> x y))
-(TEQshiftLLreg (MOVWconst [c]) x y) => (TEQconst [c] (SLL <x.Type> x y))
-(TEQshiftRLreg (MOVWconst [c]) x y) => (TEQconst [c] (SRL <x.Type> x y))
-(TEQshiftRAreg (MOVWconst [c]) x y) => (TEQconst [c] (SRA <x.Type> x y))
-(CMNshiftLLreg (MOVWconst [c]) x y) => (CMNconst [c] (SLL <x.Type> x y))
-(CMNshiftRLreg (MOVWconst [c]) x y) => (CMNconst [c] (SRL <x.Type> x y))
-(CMNshiftRAreg (MOVWconst [c]) x y) => (CMNconst [c] (SRA <x.Type> x y))
-
-// constant folding in *shift ops
-(ADDshiftLL x (MOVWconst [c]) [d]) => (ADDconst x [c<<uint64(d)])
-(ADDshiftRL x (MOVWconst [c]) [d]) => (ADDconst x [int32(uint32(c)>>uint64(d))])
-(ADDshiftRA x (MOVWconst [c]) [d]) => (ADDconst x [c>>uint64(d)])
-(ADCshiftLL x (MOVWconst [c]) [d] flags) => (ADCconst x [c<<uint64(d)] flags)
-(ADCshiftRL x (MOVWconst [c]) [d] flags) => (ADCconst x [int32(uint32(c)>>uint64(d))] flags)
-(ADCshiftRA x (MOVWconst [c]) [d] flags) => (ADCconst x [c>>uint64(d)] flags)
-(ADDSshiftLL x (MOVWconst [c]) [d]) => (ADDSconst x [c<<uint64(d)])
-(ADDSshiftRL x (MOVWconst [c]) [d]) => (ADDSconst x [int32(uint32(c)>>uint64(d))])
-(ADDSshiftRA x (MOVWconst [c]) [d]) => (ADDSconst x [c>>uint64(d)])
-(SUBshiftLL x (MOVWconst [c]) [d]) => (SUBconst x [c<<uint64(d)])
-(SUBshiftRL x (MOVWconst [c]) [d]) => (SUBconst x [int32(uint32(c)>>uint64(d))])
-(SUBshiftRA x (MOVWconst [c]) [d]) => (SUBconst x [c>>uint64(d)])
-(SBCshiftLL x (MOVWconst [c]) [d] flags) => (SBCconst x [c<<uint64(d)] flags)
-(SBCshiftRL x (MOVWconst [c]) [d] flags) => (SBCconst x [int32(uint32(c)>>uint64(d))] flags)
-(SBCshiftRA x (MOVWconst [c]) [d] flags) => (SBCconst x [c>>uint64(d)] flags)
-(SUBSshiftLL x (MOVWconst [c]) [d]) => (SUBSconst x [c<<uint64(d)])
-(SUBSshiftRL x (MOVWconst [c]) [d]) => (SUBSconst x [int32(uint32(c)>>uint64(d))])
-(SUBSshiftRA x (MOVWconst [c]) [d]) => (SUBSconst x [c>>uint64(d)])
-(RSBshiftLL x (MOVWconst [c]) [d]) => (RSBconst x [c<<uint64(d)])
-(RSBshiftRL x (MOVWconst [c]) [d]) => (RSBconst x [int32(uint32(c)>>uint64(d))])
-(RSBshiftRA x (MOVWconst [c]) [d]) => (RSBconst x [c>>uint64(d)])
-(RSCshiftLL x (MOVWconst [c]) [d] flags) => (RSCconst x [c<<uint64(d)] flags)
-(RSCshiftRL x (MOVWconst [c]) [d] flags) => (RSCconst x [int32(uint32(c)>>uint64(d))] flags)
-(RSCshiftRA x (MOVWconst [c]) [d] flags) => (RSCconst x [c>>uint64(d)] flags)
-(RSBSshiftLL x (MOVWconst [c]) [d]) => (RSBSconst x [c<<uint64(d)])
-(RSBSshiftRL x (MOVWconst [c]) [d]) => (RSBSconst x [int32(uint32(c)>>uint64(d))])
-(RSBSshiftRA x (MOVWconst [c]) [d]) => (RSBSconst x [c>>uint64(d)])
-(ANDshiftLL x (MOVWconst [c]) [d]) => (ANDconst x [c<<uint64(d)])
-(ANDshiftRL x (MOVWconst [c]) [d]) => (ANDconst x [int32(uint32(c)>>uint64(d))])
-(ANDshiftRA x (MOVWconst [c]) [d]) => (ANDconst x [c>>uint64(d)])
-(ORshiftLL x (MOVWconst [c]) [d]) => (ORconst x [c<<uint64(d)])
-(ORshiftRL x (MOVWconst [c]) [d]) => (ORconst x [int32(uint32(c)>>uint64(d))])
-(ORshiftRA x (MOVWconst [c]) [d]) => (ORconst x [c>>uint64(d)])
-(XORshiftLL x (MOVWconst [c]) [d]) => (XORconst x [c<<uint64(d)])
-(XORshiftRL x (MOVWconst [c]) [d]) => (XORconst x [int32(uint32(c)>>uint64(d))])
-(XORshiftRA x (MOVWconst [c]) [d]) => (XORconst x [c>>uint64(d)])
-(XORshiftRR x (MOVWconst [c]) [d]) => (XORconst x [int32(uint32(c)>>uint64(d)|uint32(c)<<uint64(32-d))])
-(BICshiftLL x (MOVWconst [c]) [d]) => (BICconst x [c<<uint64(d)])
-(BICshiftRL x (MOVWconst [c]) [d]) => (BICconst x [int32(uint32(c)>>uint64(d))])
-(BICshiftRA x (MOVWconst [c]) [d]) => (BICconst x [c>>uint64(d)])
-(MVNshiftLL (MOVWconst [c]) [d]) => (MOVWconst [^(c<<uint64(d))])
-(MVNshiftRL (MOVWconst [c]) [d]) => (MOVWconst [^int32(uint32(c)>>uint64(d))])
-(MVNshiftRA (MOVWconst [c]) [d]) => (MOVWconst [int32(c)>>uint64(d)])
-(CMPshiftLL x (MOVWconst [c]) [d]) => (CMPconst x [c<<uint64(d)])
-(CMPshiftRL x (MOVWconst [c]) [d]) => (CMPconst x [int32(uint32(c)>>uint64(d))])
-(CMPshiftRA x (MOVWconst [c]) [d]) => (CMPconst x [c>>uint64(d)])
-(TSTshiftLL x (MOVWconst [c]) [d]) => (TSTconst x [c<<uint64(d)])
-(TSTshiftRL x (MOVWconst [c]) [d]) => (TSTconst x [int32(uint32(c)>>uint64(d))])
-(TSTshiftRA x (MOVWconst [c]) [d]) => (TSTconst x [c>>uint64(d)])
-(TEQshiftLL x (MOVWconst [c]) [d]) => (TEQconst x [c<<uint64(d)])
-(TEQshiftRL x (MOVWconst [c]) [d]) => (TEQconst x [int32(uint32(c)>>uint64(d))])
-(TEQshiftRA x (MOVWconst [c]) [d]) => (TEQconst x [c>>uint64(d)])
-(CMNshiftLL x (MOVWconst [c]) [d]) => (CMNconst x [c<<uint64(d)])
-(CMNshiftRL x (MOVWconst [c]) [d]) => (CMNconst x [int32(uint32(c)>>uint64(d))])
-(CMNshiftRA x (MOVWconst [c]) [d]) => (CMNconst x [c>>uint64(d)])
-
-(ADDshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDshiftLL x y [c])
-(ADDshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDshiftRL x y [c])
-(ADDshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDshiftRA x y [c])
-(ADCshiftLLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (ADCshiftLL x y [c] flags)
-(ADCshiftRLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (ADCshiftRL x y [c] flags)
-(ADCshiftRAreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (ADCshiftRA x y [c] flags)
-(ADDSshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDSshiftLL x y [c])
-(ADDSshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDSshiftRL x y [c])
-(ADDSshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ADDSshiftRA x y [c])
-(SUBshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBshiftLL x y [c])
-(SUBshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBshiftRL x y [c])
-(SUBshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBshiftRA x y [c])
-(SBCshiftLLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (SBCshiftLL x y [c] flags)
-(SBCshiftRLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (SBCshiftRL x y [c] flags)
-(SBCshiftRAreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (SBCshiftRA x y [c] flags)
-(SUBSshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBSshiftLL x y [c])
-(SUBSshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBSshiftRL x y [c])
-(SUBSshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (SUBSshiftRA x y [c])
-(RSBshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBshiftLL x y [c])
-(RSBshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBshiftRL x y [c])
-(RSBshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBshiftRA x y [c])
-(RSCshiftLLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (RSCshiftLL x y [c] flags)
-(RSCshiftRLreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (RSCshiftRL x y [c] flags)
-(RSCshiftRAreg x y (MOVWconst [c]) flags) && 0 <= c && c < 32 => (RSCshiftRA x y [c] flags)
-(RSBSshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBSshiftLL x y [c])
-(RSBSshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBSshiftRL x y [c])
-(RSBSshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (RSBSshiftRA x y [c])
-(ANDshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ANDshiftLL x y [c])
-(ANDshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ANDshiftRL x y [c])
-(ANDshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ANDshiftRA x y [c])
-(ORshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ORshiftLL x y [c])
-(ORshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ORshiftRL x y [c])
-(ORshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (ORshiftRA x y [c])
-(XORshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (XORshiftLL x y [c])
-(XORshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (XORshiftRL x y [c])
-(XORshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (XORshiftRA x y [c])
-(BICshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (BICshiftLL x y [c])
-(BICshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (BICshiftRL x y [c])
-(BICshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (BICshiftRA x y [c])
-(MVNshiftLLreg x (MOVWconst [c])) && 0 <= c && c < 32 => (MVNshiftLL x [c])
-(MVNshiftRLreg x (MOVWconst [c])) && 0 <= c && c < 32 => (MVNshiftRL x [c])
-(MVNshiftRAreg x (MOVWconst [c])) && 0 <= c && c < 32 => (MVNshiftRA x [c])
-(CMPshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMPshiftLL x y [c])
-(CMPshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMPshiftRL x y [c])
-(CMPshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMPshiftRA x y [c])
-(TSTshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TSTshiftLL x y [c])
-(TSTshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TSTshiftRL x y [c])
-(TSTshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TSTshiftRA x y [c])
-(TEQshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TEQshiftLL x y [c])
-(TEQshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TEQshiftRL x y [c])
-(TEQshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (TEQshiftRA x y [c])
-(CMNshiftLLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMNshiftLL x y [c])
-(CMNshiftRLreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMNshiftRL x y [c])
-(CMNshiftRAreg x y (MOVWconst [c])) && 0 <= c && c < 32 => (CMNshiftRA x y [c])
-
-// Generate rotates
-(ADDshiftLL [c] (SRLconst x [32-c]) x) => (SRRconst [32-c] x)
-( ORshiftLL [c] (SRLconst x [32-c]) x) => (SRRconst [32-c] x)
-(XORshiftLL [c] (SRLconst x [32-c]) x) => (SRRconst [32-c] x)
-(ADDshiftRL [c] (SLLconst x [32-c]) x) => (SRRconst [   c] x)
-( ORshiftRL [c] (SLLconst x [32-c]) x) => (SRRconst [   c] x)
-(XORshiftRL [c] (SLLconst x [32-c]) x) => (SRRconst [   c] x)
-
-(RotateLeft16 <t> x (MOVWconst [c])) => (Or16 (Lsh16x32 <t> x (MOVWconst [c&15])) (Rsh16Ux32 <t> x (MOVWconst [-c&15])))
-(RotateLeft8 <t> x (MOVWconst [c])) => (Or8 (Lsh8x32 <t> x (MOVWconst [c&7])) (Rsh8Ux32 <t> x (MOVWconst [-c&7])))
-(RotateLeft32 x y) => (SRR x (RSBconst [0] <y.Type> y))
-
-// ((x>>8) | (x<<8)) -> (REV16 x), the type of x is uint16, "|" can also be "^" or "+".
-// UBFX instruction is supported by ARMv6T2, ARMv7 and above versions, REV16 is supported by
-// ARMv6 and above versions. So for ARMv6, we need to match SLLconst, SRLconst and ORshiftLL.
-((ADDshiftLL|ORshiftLL|XORshiftLL) <typ.UInt16> [8] (BFXU <typ.UInt16> [int32(armBFAuxInt(8, 8))] x) x) => (REV16 x)
-((ADDshiftLL|ORshiftLL|XORshiftLL) <typ.UInt16> [8] (SRLconst <typ.UInt16> [24] (SLLconst [16] x)) x) && buildcfg.GOARM>=6 => (REV16 x)
-
-// use indexed loads and stores
-(MOVWload [0] {sym} (ADD ptr idx) mem) && sym == nil => (MOVWloadidx ptr idx mem)
-(MOVWstore [0] {sym} (ADD ptr idx) val mem) && sym == nil => (MOVWstoreidx ptr idx val mem)
-(MOVWload [0] {sym} (ADDshiftLL ptr idx [c]) mem) && sym == nil => (MOVWloadshiftLL ptr idx [c] mem)
-(MOVWload [0] {sym} (ADDshiftRL ptr idx [c]) mem) && sym == nil => (MOVWloadshiftRL ptr idx [c] mem)
-(MOVWload [0] {sym} (ADDshiftRA ptr idx [c]) mem) && sym == nil => (MOVWloadshiftRA ptr idx [c] mem)
-(MOVWstore [0] {sym} (ADDshiftLL ptr idx [c]) val mem) && sym == nil => (MOVWstoreshiftLL ptr idx [c] val mem)
-(MOVWstore [0] {sym} (ADDshiftRL ptr idx [c]) val mem) && sym == nil => (MOVWstoreshiftRL ptr idx [c] val mem)
-(MOVWstore [0] {sym} (ADDshiftRA ptr idx [c]) val mem) && sym == nil => (MOVWstoreshiftRA ptr idx [c] val mem)
-(MOVBUload [0] {sym} (ADD ptr idx) mem) && sym == nil => (MOVBUloadidx ptr idx mem)
-(MOVBload [0] {sym} (ADD ptr idx) mem) && sym == nil => (MOVBloadidx ptr idx mem)
-(MOVBstore [0] {sym} (ADD ptr idx) val mem) && sym == nil => (MOVBstoreidx ptr idx val mem)
-(MOVHUload [0] {sym} (ADD ptr idx) mem) && sym == nil => (MOVHUloadidx ptr idx mem)
-(MOVHload [0] {sym} (ADD ptr idx) mem) && sym == nil => (MOVHloadidx ptr idx mem)
-(MOVHstore [0] {sym} (ADD ptr idx) val mem) && sym == nil => (MOVHstoreidx ptr idx val mem)
-
-// constant folding in indexed loads and stores
-(MOVWloadidx ptr (MOVWconst [c]) mem) => (MOVWload [c] ptr mem)
-(MOVWloadidx (MOVWconst [c]) ptr mem) => (MOVWload [c] ptr mem)
-(MOVBloadidx ptr (MOVWconst [c]) mem) => (MOVBload [c] ptr mem)
-(MOVBloadidx (MOVWconst [c]) ptr mem) => (MOVBload [c] ptr mem)
-(MOVBUloadidx ptr (MOVWconst [c]) mem) => (MOVBUload [c] ptr mem)
-(MOVBUloadidx (MOVWconst [c]) ptr mem) => (MOVBUload [c] ptr mem)
-(MOVHUloadidx ptr (MOVWconst [c]) mem) => (MOVHUload [c] ptr mem)
-(MOVHUloadidx (MOVWconst [c]) ptr mem) => (MOVHUload [c] ptr mem)
-(MOVHloadidx ptr (MOVWconst [c]) mem) => (MOVHload [c] ptr mem)
-(MOVHloadidx (MOVWconst [c]) ptr mem) => (MOVHload [c] ptr mem)
-
-(MOVWstoreidx ptr (MOVWconst [c]) val mem) => (MOVWstore [c] ptr val mem)
-(MOVWstoreidx (MOVWconst [c]) ptr val mem) => (MOVWstore [c] ptr val mem)
-(MOVBstoreidx ptr (MOVWconst [c]) val mem) => (MOVBstore [c] ptr val mem)
-(MOVBstoreidx (MOVWconst [c]) ptr val mem) => (MOVBstore [c] ptr val mem)
-(MOVHstoreidx ptr (MOVWconst [c]) val mem) => (MOVHstore [c] ptr val mem)
-(MOVHstoreidx (MOVWconst [c]) ptr val mem) => (MOVHstore [c] ptr val mem)
-
-(MOVWloadidx ptr (SLLconst idx [c]) mem) => (MOVWloadshiftLL ptr idx [c] mem)
-(MOVWloadidx (SLLconst idx [c]) ptr mem) => (MOVWloadshiftLL ptr idx [c] mem)
-(MOVWloadidx ptr (SRLconst idx [c]) mem) => (MOVWloadshiftRL ptr idx [c] mem)
-(MOVWloadidx (SRLconst idx [c]) ptr mem) => (MOVWloadshiftRL ptr idx [c] mem)
-(MOVWloadidx ptr (SRAconst idx [c]) mem) => (MOVWloadshiftRA ptr idx [c] mem)
-(MOVWloadidx (SRAconst idx [c]) ptr mem) => (MOVWloadshiftRA ptr idx [c] mem)
-
-(MOVWstoreidx ptr (SLLconst idx [c]) val mem) => (MOVWstoreshiftLL ptr idx [c] val mem)
-(MOVWstoreidx (SLLconst idx [c]) ptr val mem) => (MOVWstoreshiftLL ptr idx [c] val mem)
-(MOVWstoreidx ptr (SRLconst idx [c]) val mem) => (MOVWstoreshiftRL ptr idx [c] val mem)
-(MOVWstoreidx (SRLconst idx [c]) ptr val mem) => (MOVWstoreshiftRL ptr idx [c] val mem)
-(MOVWstoreidx ptr (SRAconst idx [c]) val mem) => (MOVWstoreshiftRA ptr idx [c] val mem)
-(MOVWstoreidx (SRAconst idx [c]) ptr val mem) => (MOVWstoreshiftRA ptr idx [c] val mem)
-
-(MOVWloadshiftLL ptr (MOVWconst [c]) [d] mem) => (MOVWload [int32(uint32(c)<<uint64(d))] ptr mem)
-(MOVWloadshiftRL ptr (MOVWconst [c]) [d] mem) => (MOVWload [int32(uint32(c)>>uint64(d))] ptr mem)
-(MOVWloadshiftRA ptr (MOVWconst [c]) [d] mem) => (MOVWload [c>>uint64(d)] ptr mem)
-
-(MOVWstoreshiftLL ptr (MOVWconst [c]) [d] val mem) => (MOVWstore [int32(uint32(c)<<uint64(d))] ptr val mem)
-(MOVWstoreshiftRL ptr (MOVWconst [c]) [d] val mem) => (MOVWstore [int32(uint32(c)>>uint64(d))] ptr val mem)
-(MOVWstoreshiftRA ptr (MOVWconst [c]) [d] val mem) => (MOVWstore [c>>uint64(d)] ptr val mem)
-
-// generic simplifications
-(ADD x (RSBconst [0] y)) => (SUB x y)
-(ADD <t> (RSBconst [c] x) (RSBconst [d] y)) => (RSBconst [c+d] (ADD <t> x y))
-(SUB x x) => (MOVWconst [0])
-(RSB x x) => (MOVWconst [0])
-(AND x x) => x
-(OR x x) => x
-(XOR x x) => (MOVWconst [0])
-(BIC x x) => (MOVWconst [0])
-
-(ADD (MUL x y) a) => (MULA x y a)
-(SUB a (MUL x y)) && buildcfg.GOARM == 7 => (MULS x y a)
-(RSB (MUL x y) a) && buildcfg.GOARM == 7 => (MULS x y a)
-
-(NEGF (MULF x y)) && buildcfg.GOARM >= 6 => (NMULF x y)
-(NEGD (MULD x y)) && buildcfg.GOARM >= 6 => (NMULD x y)
-(MULF (NEGF x) y) && buildcfg.GOARM >= 6 => (NMULF x y)
-(MULD (NEGD x) y) && buildcfg.GOARM >= 6 => (NMULD x y)
-(NMULF (NEGF x) y) => (MULF x y)
-(NMULD (NEGD x) y) => (MULD x y)
-
-// the result will overwrite the addend, since they are in the same register
-(ADDF a (MULF x y)) && a.Uses == 1 && buildcfg.GOARM >= 6 => (MULAF a x y)
-(ADDF a (NMULF x y)) && a.Uses == 1 && buildcfg.GOARM >= 6 => (MULSF a x y)
-(ADDD a (MULD x y)) && a.Uses == 1 && buildcfg.GOARM >= 6 => (MULAD a x y)
-(ADDD a (NMULD x y)) && a.Uses == 1 && buildcfg.GOARM >= 6 => (MULSD a x y)
-(SUBF a (MULF x y)) && a.Uses == 1 && buildcfg.GOARM >= 6 => (MULSF a x y)
-(SUBF a (NMULF x y)) && a.Uses == 1 && buildcfg.GOARM >= 6 => (MULAF a x y)
-(SUBD a (MULD x y)) && a.Uses == 1 && buildcfg.GOARM >= 6 => (MULSD a x y)
-(SUBD a (NMULD x y)) && a.Uses == 1 && buildcfg.GOARM >= 6 => (MULAD a x y)
-
-(AND x (MVN y)) => (BIC x y)
-
-// simplification with *shift ops
-(SUBshiftLL (SLLconst x [c]) x [c]) => (MOVWconst [0])
-(SUBshiftRL (SRLconst x [c]) x [c]) => (MOVWconst [0])
-(SUBshiftRA (SRAconst x [c]) x [c]) => (MOVWconst [0])
-(RSBshiftLL (SLLconst x [c]) x [c]) => (MOVWconst [0])
-(RSBshiftRL (SRLconst x [c]) x [c]) => (MOVWconst [0])
-(RSBshiftRA (SRAconst x [c]) x [c]) => (MOVWconst [0])
-(ANDshiftLL y:(SLLconst x [c]) x [c]) => y
-(ANDshiftRL y:(SRLconst x [c]) x [c]) => y
-(ANDshiftRA y:(SRAconst x [c]) x [c]) => y
-(ORshiftLL y:(SLLconst x [c]) x [c]) => y
-(ORshiftRL y:(SRLconst x [c]) x [c]) => y
-(ORshiftRA y:(SRAconst x [c]) x [c]) => y
-(XORshiftLL (SLLconst x [c]) x [c]) => (MOVWconst [0])
-(XORshiftRL (SRLconst x [c]) x [c]) => (MOVWconst [0])
-(XORshiftRA (SRAconst x [c]) x [c]) => (MOVWconst [0])
-(BICshiftLL (SLLconst x [c]) x [c]) => (MOVWconst [0])
-(BICshiftRL (SRLconst x [c]) x [c]) => (MOVWconst [0])
-(BICshiftRA (SRAconst x [c]) x [c]) => (MOVWconst [0])
-(AND x (MVNshiftLL y [c])) => (BICshiftLL x y [c])
-(AND x (MVNshiftRL y [c])) => (BICshiftRL x y [c])
-(AND x (MVNshiftRA y [c])) => (BICshiftRA x y [c])
-
-// floating point optimizations
-(CMPF x (MOVFconst [0])) => (CMPF0 x)
-(CMPD x (MOVDconst [0])) => (CMPD0 x)
-
-// bit extraction
-(SRAconst (SLLconst x [c]) [d]) && buildcfg.GOARM==7 && uint64(d)>=uint64(c) && uint64(d)<=31 => (BFX [(d-c)|(32-d)<<8] x)
-(SRLconst (SLLconst x [c]) [d]) && buildcfg.GOARM==7 && uint64(d)>=uint64(c) && uint64(d)<=31 => (BFXU [(d-c)|(32-d)<<8] x)
-
-// comparison simplification
-((EQ|NE) (CMP x (RSBconst [0] y))) => ((EQ|NE) (CMN x y)) // sense of carry bit not preserved; see also #50854
-((EQ|NE) (CMN x (RSBconst [0] y))) => ((EQ|NE) (CMP x y)) // sense of carry bit not preserved; see also #50864
-(EQ (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 => (EQ (CMP x y) yes no)
-(EQ (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 => (EQ (CMP a (MUL <x.Type> x y)) yes no)
-(EQ (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 => (EQ (CMPconst [c] x) yes no)
-(EQ (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 => (EQ (CMPshiftLL x y [c]) yes no)
-(EQ (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 => (EQ (CMPshiftRL x y [c]) yes no)
-(EQ (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 => (EQ (CMPshiftRA x y [c]) yes no)
-(EQ (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 => (EQ (CMPshiftLLreg x y z) yes no)
-(EQ (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 => (EQ (CMPshiftRLreg x y z) yes no)
-(EQ (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 => (EQ (CMPshiftRAreg x y z) yes no)
-(NE (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 => (NE (CMP x y) yes no)
-(NE (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 => (NE (CMP a (MUL <x.Type> x y)) yes no)
-(NE (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 => (NE (CMPconst [c] x) yes no)
-(NE (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 => (NE (CMPshiftLL x y [c]) yes no)
-(NE (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 => (NE (CMPshiftRL x y [c]) yes no)
-(NE (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 => (NE (CMPshiftRA x y [c]) yes no)
-(NE (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 => (NE (CMPshiftLLreg x y z) yes no)
-(NE (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 => (NE (CMPshiftRLreg x y z) yes no)
-(NE (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 => (NE (CMPshiftRAreg x y z) yes no)
-(EQ (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 => (EQ (CMN x y) yes no)
-(EQ (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 => (EQ (CMN a (MUL <x.Type> x y)) yes no)
-(EQ (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1 => (EQ (CMNconst [c] x) yes no)
-(EQ (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 => (EQ (CMNshiftLL x y [c]) yes no)
-(EQ (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 => (EQ (CMNshiftRL x y [c]) yes no)
-(EQ (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 => (EQ (CMNshiftRA x y [c]) yes no)
-(EQ (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 => (EQ (CMNshiftLLreg x y z) yes no)
-(EQ (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 => (EQ (CMNshiftRLreg x y z) yes no)
-(EQ (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 => (EQ (CMNshiftRAreg x y z) yes no)
-(NE (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 => (NE (CMN x y) yes no)
-(NE (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 => (NE (CMN a (MUL <x.Type> x y)) yes no)
-(NE (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1 => (NE (CMNconst [c] x) yes no)
-(NE (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 => (NE (CMNshiftLL x y [c]) yes no)
-(NE (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 => (NE (CMNshiftRL x y [c]) yes no)
-(NE (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 => (NE (CMNshiftRA x y [c]) yes no)
-(NE (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 => (NE (CMNshiftLLreg x y z) yes no)
-(NE (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 => (NE (CMNshiftRLreg x y z) yes no)
-(NE (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 => (NE (CMNshiftRAreg x y z) yes no)
-(EQ (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 => (EQ (TST x y) yes no)
-(EQ (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 => (EQ (TSTconst [c] x) yes no)
-(EQ (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 => (EQ (TSTshiftLL x y [c]) yes no)
-(EQ (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 => (EQ (TSTshiftRL x y [c]) yes no)
-(EQ (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 => (EQ (TSTshiftRA x y [c]) yes no)
-(EQ (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 => (EQ (TSTshiftLLreg x y z) yes no)
-(EQ (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 => (EQ (TSTshiftRLreg x y z) yes no)
-(EQ (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 => (EQ (TSTshiftRAreg x y z) yes no)
-(NE (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 => (NE (TST x y) yes no)
-(NE (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 => (NE (TSTconst [c] x) yes no)
-(NE (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 => (NE (TSTshiftLL x y [c]) yes no)
-(NE (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 => (NE (TSTshiftRL x y [c]) yes no)
-(NE (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 => (NE (TSTshiftRA x y [c]) yes no)
-(NE (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 => (NE (TSTshiftLLreg x y z) yes no)
-(NE (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 => (NE (TSTshiftRLreg x y z) yes no)
-(NE (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 => (NE (TSTshiftRAreg x y z) yes no)
-(EQ (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 => (EQ (TEQ x y) yes no)
-(EQ (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 => (EQ (TEQconst [c] x) yes no)
-(EQ (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 => (EQ (TEQshiftLL x y [c]) yes no)
-(EQ (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 => (EQ (TEQshiftRL x y [c]) yes no)
-(EQ (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 => (EQ (TEQshiftRA x y [c]) yes no)
-(EQ (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 => (EQ (TEQshiftLLreg x y z) yes no)
-(EQ (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 => (EQ (TEQshiftRLreg x y z) yes no)
-(EQ (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 => (EQ (TEQshiftRAreg x y z) yes no)
-(NE (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 => (NE (TEQ x y) yes no)
-(NE (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 => (NE (TEQconst [c] x) yes no)
-(NE (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 => (NE (TEQshiftLL x y [c]) yes no)
-(NE (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 => (NE (TEQshiftRL x y [c]) yes no)
-(NE (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 => (NE (TEQshiftRA x y [c]) yes no)
-(NE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 => (NE (TEQshiftLLreg x y z) yes no)
-(NE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 => (NE (TEQshiftRLreg x y z) yes no)
-(NE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 => (NE (TEQshiftRAreg x y z) yes no)
-(LT (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 => (LTnoov (CMP x y) yes no)
-(LT (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 => (LTnoov (CMP a (MUL <x.Type> x y)) yes no)
-(LT (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 => (LTnoov (CMPconst [c] x) yes no)
-(LT (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 => (LTnoov (CMPshiftLL x y [c]) yes no)
-(LT (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 => (LTnoov (CMPshiftRL x y [c]) yes no)
-(LT (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 => (LTnoov (CMPshiftRA x y [c]) yes no)
-(LT (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 => (LTnoov (CMPshiftLLreg x y z) yes no)
-(LT (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 => (LTnoov (CMPshiftRLreg x y z) yes no)
-(LT (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 => (LTnoov (CMPshiftRAreg x y z) yes no)
-(LE (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 => (LEnoov (CMP x y) yes no)
-(LE (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 => (LEnoov (CMP a (MUL <x.Type> x y)) yes no)
-(LE (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 => (LEnoov (CMPconst [c] x) yes no)
-(LE (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 => (LEnoov (CMPshiftLL x y [c]) yes no)
-(LE (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 => (LEnoov (CMPshiftRL x y [c]) yes no)
-(LE (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 => (LEnoov (CMPshiftRA x y [c]) yes no)
-(LE (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 => (LEnoov (CMPshiftLLreg x y z) yes no)
-(LE (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 => (LEnoov (CMPshiftRLreg x y z) yes no)
-(LE (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 => (LEnoov (CMPshiftRAreg x y z) yes no)
-(LT (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 => (LTnoov (CMN x y) yes no)
-(LT (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 => (LTnoov (CMN a (MUL <x.Type> x y)) yes no)
-(LT (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1 => (LTnoov (CMNconst [c] x) yes no)
-(LT (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 => (LTnoov (CMNshiftLL x y [c]) yes no)
-(LT (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 => (LTnoov (CMNshiftRL x y [c]) yes no)
-(LT (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 => (LTnoov (CMNshiftRA x y [c]) yes no)
-(LT (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 => (LTnoov (CMNshiftLLreg x y z) yes no)
-(LT (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 => (LTnoov (CMNshiftRLreg x y z) yes no)
-(LT (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 => (LTnoov (CMNshiftRAreg x y z) yes no)
-(LE (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 => (LEnoov (CMN x y) yes no)
-(LE (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 => (LEnoov (CMN a (MUL <x.Type> x y)) yes no)
-(LE (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1  => (LEnoov (CMNconst [c] x) yes no)
-(LE (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 => (LEnoov (CMNshiftLL x y [c]) yes no)
-(LE (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 => (LEnoov (CMNshiftRL x y [c]) yes no)
-(LE (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 => (LEnoov (CMNshiftRA x y [c]) yes no)
-(LE (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 => (LEnoov (CMNshiftLLreg x y z) yes no)
-(LE (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 => (LEnoov (CMNshiftRLreg x y z) yes no)
-(LE (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 => (LEnoov (CMNshiftRAreg x y z) yes no)
-(LT (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 => (LTnoov (TST x y) yes no)
-(LT (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 => (LTnoov (TSTconst [c] x) yes no)
-(LT (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 => (LTnoov (TSTshiftLL x y [c]) yes no)
-(LT (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 => (LTnoov (TSTshiftRL x y [c]) yes no)
-(LT (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 => (LTnoov (TSTshiftRA x y [c]) yes no)
-(LT (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 => (LTnoov (TSTshiftLLreg x y z) yes no)
-(LT (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 => (LTnoov (TSTshiftRLreg x y z) yes no)
-(LT (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 => (LTnoov (TSTshiftRAreg x y z) yes no)
-(LE (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 => (LEnoov (TST x y) yes no)
-(LE (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 => (LEnoov (TSTconst [c] x) yes no)
-(LE (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 => (LEnoov (TSTshiftLL x y [c]) yes no)
-(LE (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 => (LEnoov (TSTshiftRL x y [c]) yes no)
-(LE (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 => (LEnoov (TSTshiftRA x y [c]) yes no)
-(LE (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 => (LEnoov (TSTshiftLLreg x y z) yes no)
-(LE (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 => (LEnoov (TSTshiftRLreg x y z) yes no)
-(LE (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 => (LEnoov (TSTshiftRAreg x y z) yes no)
-(LT (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 => (LTnoov (TEQ x y) yes no)
-(LT (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 => (LTnoov (TEQconst [c] x) yes no)
-(LT (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 => (LTnoov (TEQshiftLL x y [c]) yes no)
-(LT (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 => (LTnoov (TEQshiftRL x y [c]) yes no)
-(LT (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 => (LTnoov (TEQshiftRA x y [c]) yes no)
-(LT (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 => (LTnoov (TEQshiftLLreg x y z) yes no)
-(LT (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 => (LTnoov (TEQshiftRLreg x y z) yes no)
-(LT (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 => (LTnoov (TEQshiftRAreg x y z) yes no)
-(LE (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 => (LEnoov (TEQ x y) yes no)
-(LE (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1  => (LEnoov (TEQconst [c] x) yes no)
-(LE (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 => (LEnoov (TEQshiftLL x y [c]) yes no)
-(LE (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 => (LEnoov (TEQshiftRL x y [c]) yes no)
-(LE (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 => (LEnoov (TEQshiftRA x y [c]) yes no)
-(LE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 => (LEnoov (TEQshiftLLreg x y z) yes no)
-(LE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 => (LEnoov (TEQshiftRLreg x y z) yes no)
-(LE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 => (LEnoov (TEQshiftRAreg x y z) yes no)
-(GT (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 => (GTnoov (CMP x y) yes no)
-(GT (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 => (GTnoov (CMP a (MUL <x.Type> x y)) yes no)
-(GT (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 => (GTnoov (CMPconst [c] x) yes no)
-(GT (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 => (GTnoov (CMPshiftLL x y [c]) yes no)
-(GT (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 => (GTnoov (CMPshiftRL x y [c]) yes no)
-(GT (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 => (GTnoov (CMPshiftRA x y [c]) yes no)
-(GT (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 => (GTnoov (CMPshiftLLreg x y z) yes no)
-(GT (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 => (GTnoov (CMPshiftRLreg x y z) yes no)
-(GT (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 => (GTnoov (CMPshiftRAreg x y z) yes no)
-(GE (CMPconst [0] l:(SUB x y)) yes no) && l.Uses==1 => (GEnoov (CMP x y) yes no)
-(GE (CMPconst [0] l:(MULS x y a)) yes no) && l.Uses==1 => (GEnoov (CMP a (MUL <x.Type> x y)) yes no)
-(GE (CMPconst [0] l:(SUBconst [c] x)) yes no) && l.Uses==1 => (GEnoov (CMPconst [c] x) yes no)
-(GE (CMPconst [0] l:(SUBshiftLL x y [c])) yes no) && l.Uses==1 => (GEnoov (CMPshiftLL x y [c]) yes no)
-(GE (CMPconst [0] l:(SUBshiftRL x y [c])) yes no) && l.Uses==1 => (GEnoov (CMPshiftRL x y [c]) yes no)
-(GE (CMPconst [0] l:(SUBshiftRA x y [c])) yes no) && l.Uses==1 => (GEnoov (CMPshiftRA x y [c]) yes no)
-(GE (CMPconst [0] l:(SUBshiftLLreg x y z)) yes no) && l.Uses==1 => (GEnoov (CMPshiftLLreg x y z) yes no)
-(GE (CMPconst [0] l:(SUBshiftRLreg x y z)) yes no) && l.Uses==1 => (GEnoov (CMPshiftRLreg x y z) yes no)
-(GE (CMPconst [0] l:(SUBshiftRAreg x y z)) yes no) && l.Uses==1 => (GEnoov (CMPshiftRAreg x y z) yes no)
-(GT (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 => (GTnoov (CMN x y) yes no)
-(GT (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1 => (GTnoov (CMNconst [c] x) yes no)
-(GT (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 => (GTnoov (CMNshiftLL x y [c]) yes no)
-(GT (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 => (GTnoov (CMNshiftRL x y [c]) yes no)
-(GT (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 => (GTnoov (CMNshiftRA x y [c]) yes no)
-(GT (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 => (GTnoov (CMNshiftLLreg x y z) yes no)
-(GT (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 => (GTnoov (CMNshiftRLreg x y z) yes no)
-(GT (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 => (GTnoov (CMNshiftRAreg x y z) yes no)
-(GE (CMPconst [0] l:(ADD x y)) yes no) && l.Uses==1 => (GEnoov (CMN x y) yes no)
-(GE (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 => (GEnoov (CMN a (MUL <x.Type> x y)) yes no)
-(GE (CMPconst [0] l:(ADDconst [c] x)) yes no) && l.Uses==1 => (GEnoov (CMNconst [c] x) yes no)
-(GE (CMPconst [0] l:(ADDshiftLL x y [c])) yes no) && l.Uses==1 => (GEnoov (CMNshiftLL x y [c]) yes no)
-(GE (CMPconst [0] l:(ADDshiftRL x y [c])) yes no) && l.Uses==1 => (GEnoov (CMNshiftRL x y [c]) yes no)
-(GE (CMPconst [0] l:(ADDshiftRA x y [c])) yes no) && l.Uses==1 => (GEnoov (CMNshiftRA x y [c]) yes no)
-(GE (CMPconst [0] l:(ADDshiftLLreg x y z)) yes no) && l.Uses==1 => (GEnoov (CMNshiftLLreg x y z) yes no)
-(GE (CMPconst [0] l:(ADDshiftRLreg x y z)) yes no) && l.Uses==1 => (GEnoov (CMNshiftRLreg x y z) yes no)
-(GE (CMPconst [0] l:(ADDshiftRAreg x y z)) yes no) && l.Uses==1 => (GEnoov (CMNshiftRAreg x y z) yes no)
-(GT (CMPconst [0] l:(MULA x y a)) yes no) && l.Uses==1 => (GTnoov (CMN a (MUL <x.Type> x y)) yes no)
-(GT (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 => (GTnoov (TST x y) yes no)
-(GT (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 => (GTnoov (TSTconst [c] x) yes no)
-(GT (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 => (GTnoov (TSTshiftLL x y [c]) yes no)
-(GT (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 => (GTnoov (TSTshiftRL x y [c]) yes no)
-(GT (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 => (GTnoov (TSTshiftRA x y [c]) yes no)
-(GT (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 => (GTnoov (TSTshiftLLreg x y z) yes no)
-(GT (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 => (GTnoov (TSTshiftRLreg x y z) yes no)
-(GT (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 => (GTnoov (TSTshiftRAreg x y z) yes no)
-(GE (CMPconst [0] l:(AND x y)) yes no) && l.Uses==1 => (GEnoov (TST x y) yes no)
-(GE (CMPconst [0] l:(ANDconst [c] x)) yes no) && l.Uses==1 => (GEnoov (TSTconst [c] x) yes no)
-(GE (CMPconst [0] l:(ANDshiftLL x y [c])) yes no) && l.Uses==1 => (GEnoov (TSTshiftLL x y [c]) yes no)
-(GE (CMPconst [0] l:(ANDshiftRL x y [c])) yes no) && l.Uses==1 => (GEnoov (TSTshiftRL x y [c]) yes no)
-(GE (CMPconst [0] l:(ANDshiftRA x y [c])) yes no) && l.Uses==1 => (GEnoov (TSTshiftRA x y [c]) yes no)
-(GE (CMPconst [0] l:(ANDshiftLLreg x y z)) yes no) && l.Uses==1 => (GEnoov (TSTshiftLLreg x y z) yes no)
-(GE (CMPconst [0] l:(ANDshiftRLreg x y z)) yes no) && l.Uses==1 => (GEnoov (TSTshiftRLreg x y z) yes no)
-(GE (CMPconst [0] l:(ANDshiftRAreg x y z)) yes no) && l.Uses==1 => (GEnoov (TSTshiftRAreg x y z) yes no)
-(GT (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 => (GTnoov (TEQ x y) yes no)
-(GT (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 => (GTnoov (TEQconst [c] x) yes no)
-(GT (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 => (GTnoov (TEQshiftLL x y [c]) yes no)
-(GT (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 => (GTnoov (TEQshiftRL x y [c]) yes no)
-(GT (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 => (GTnoov (TEQshiftRA x y [c]) yes no)
-(GT (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 => (GTnoov (TEQshiftLLreg x y z) yes no)
-(GT (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 => (GTnoov (TEQshiftRLreg x y z) yes no)
-(GT (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 => (GTnoov (TEQshiftRAreg x y z) yes no)
-(GE (CMPconst [0] l:(XOR x y)) yes no) && l.Uses==1 => (GEnoov (TEQ x y) yes no)
-(GE (CMPconst [0] l:(XORconst [c] x)) yes no) && l.Uses==1 => (GEnoov (TEQconst [c] x) yes no)
-(GE (CMPconst [0] l:(XORshiftLL x y [c])) yes no) && l.Uses==1 => (GEnoov (TEQshiftLL x y [c]) yes no)
-(GE (CMPconst [0] l:(XORshiftRL x y [c])) yes no) && l.Uses==1 => (GEnoov (TEQshiftRL x y [c]) yes no)
-(GE (CMPconst [0] l:(XORshiftRA x y [c])) yes no) && l.Uses==1 => (GEnoov (TEQshiftRA x y [c]) yes no)
-(GE (CMPconst [0] l:(XORshiftLLreg x y z)) yes no) && l.Uses==1 => (GEnoov (TEQshiftLLreg x y z) yes no)
-(GE (CMPconst [0] l:(XORshiftRLreg x y z)) yes no) && l.Uses==1 => (GEnoov (TEQshiftRLreg x y z) yes no)
-(GE (CMPconst [0] l:(XORshiftRAreg x y z)) yes no) && l.Uses==1 => (GEnoov (TEQshiftRAreg x y z) yes no)
-
-(MOVBUload [off] {sym} (SB) _) && symIsRO(sym) => (MOVWconst [int32(read8(sym, int64(off)))])
-(MOVHUload [off] {sym} (SB) _) && symIsRO(sym) => (MOVWconst [int32(read16(sym, int64(off), config.ctxt.Arch.ByteOrder))])
-(MOVWload [off] {sym} (SB) _) && symIsRO(sym) => (MOVWconst [int32(read32(sym, int64(off), config.ctxt.Arch.ByteOrder))])
diff --git a/src/cmd/compile/internal/ssa/gen/ARM64.rules b/src/cmd/compile/internal/ssa/gen/ARM64.rules
deleted file mode 100644
index 3776b3c..0000000
--- a/src/cmd/compile/internal/ssa/gen/ARM64.rules
+++ /dev/null
@@ -1,2950 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-(Add(Ptr|64|32|16|8) ...) => (ADD ...)
-(Add(32F|64F) ...) => (FADD(S|D) ...)
-
-(Sub(Ptr|64|32|16|8) ...) => (SUB ...)
-(Sub(32F|64F) ...) => (FSUB(S|D) ...)
-
-(Mul64 ...) => (MUL ...)
-(Mul(32|16|8) ...) => (MULW ...)
-(Mul(32F|64F) ...) => (FMUL(S|D) ...)
-
-(Hmul64 ...) => (MULH ...)
-(Hmul64u ...) => (UMULH ...)
-(Hmul32 x y) => (SRAconst (MULL <typ.Int64> x y) [32])
-(Hmul32u x y) => (SRAconst (UMULL <typ.UInt64> x y) [32])
-(Mul64uhilo ...) => (LoweredMuluhilo ...)
-
-(Div64 [false] x y) => (DIV x y)
-(Div64u ...) => (UDIV ...)
-(Div32 [false] x y) => (DIVW x y)
-(Div32u ...) => (UDIVW ...)
-(Div16 [false] x y) => (DIVW (SignExt16to32 x) (SignExt16to32 y))
-(Div16u x y) => (UDIVW (ZeroExt16to32 x) (ZeroExt16to32 y))
-(Div8 x y) => (DIVW (SignExt8to32 x) (SignExt8to32 y))
-(Div8u x y) => (UDIVW (ZeroExt8to32 x) (ZeroExt8to32 y))
-(Div32F ...) => (FDIVS ...)
-(Div64F ...) => (FDIVD ...)
-
-(Mod64 x y) => (MOD x y)
-(Mod64u ...) => (UMOD ...)
-(Mod32 x y) => (MODW x y)
-(Mod32u ...) => (UMODW ...)
-(Mod16 x y) => (MODW (SignExt16to32 x) (SignExt16to32 y))
-(Mod16u x y) => (UMODW (ZeroExt16to32 x) (ZeroExt16to32 y))
-(Mod8 x y) => (MODW (SignExt8to32 x) (SignExt8to32 y))
-(Mod8u x y) => (UMODW (ZeroExt8to32 x) (ZeroExt8to32 y))
-
-// (x + y) / 2 with x>=y    =>    (x - y) / 2 + y
-(Avg64u <t> x y) => (ADD (SRLconst <t> (SUB <t> x y) [1]) y)
-
-(And(64|32|16|8) ...) => (AND ...)
-(Or(64|32|16|8) ...) => (OR ...)
-(Xor(64|32|16|8) ...) => (XOR ...)
-
-// unary ops
-(Neg(64|32|16|8) ...) => (NEG ...)
-(Neg(32F|64F) ...) => (FNEG(S|D) ...)
-(Com(64|32|16|8) ...) => (MVN ...)
-
-// math package intrinsics
-(Abs ...) => (FABSD ...)
-(Sqrt ...) => (FSQRTD ...)
-(Ceil ...) => (FRINTPD ...)
-(Floor ...) => (FRINTMD ...)
-(Round ...) => (FRINTAD ...)
-(RoundToEven ...) => (FRINTND ...)
-(Trunc ...) => (FRINTZD ...)
-(FMA x y z) => (FMADDD z x y)
-
-(Sqrt32 ...) => (FSQRTS ...)
-
-// lowering rotates
-(RotateLeft8 <t> x (MOVDconst [c])) => (Or8 (Lsh8x64 <t> x (MOVDconst [c&7])) (Rsh8Ux64 <t> x (MOVDconst [-c&7])))
-(RotateLeft16 <t> x (MOVDconst [c])) => (Or16 (Lsh16x64 <t> x (MOVDconst [c&15])) (Rsh16Ux64 <t> x (MOVDconst [-c&15])))
-(RotateLeft32 x y) => (RORW x (NEG <y.Type> y))
-(RotateLeft64 x y) => (ROR x (NEG <y.Type> y))
-
-(Ctz(64|32|16|8)NonZero ...) => (Ctz(64|32|32|32) ...)
-
-(Ctz64 <t> x) => (CLZ (RBIT <t> x))
-(Ctz32 <t> x) => (CLZW (RBITW <t> x))
-(Ctz16 <t> x) => (CLZW <t> (RBITW <typ.UInt32> (ORconst <typ.UInt32> [0x10000] x)))
-(Ctz8 <t> x) => (CLZW <t> (RBITW <typ.UInt32> (ORconst <typ.UInt32> [0x100] x)))
-
-(PopCount64 <t> x) => (FMOVDfpgp <t> (VUADDLV <typ.Float64> (VCNT <typ.Float64> (FMOVDgpfp <typ.Float64> x))))
-(PopCount32 <t> x) => (FMOVDfpgp <t> (VUADDLV <typ.Float64> (VCNT <typ.Float64> (FMOVDgpfp <typ.Float64> (ZeroExt32to64 x)))))
-(PopCount16 <t> x) => (FMOVDfpgp <t> (VUADDLV <typ.Float64> (VCNT <typ.Float64> (FMOVDgpfp <typ.Float64> (ZeroExt16to64 x)))))
-
-// Load args directly into the register class where it will be used.
-(FMOVDgpfp <t> (Arg [off] {sym})) => @b.Func.Entry (Arg <t> [off] {sym})
-(FMOVDfpgp <t> (Arg [off] {sym})) => @b.Func.Entry (Arg <t> [off] {sym})
-
-// Similarly for stores, if we see a store after FPR <=> GPR move, then redirect store to use the other register set.
-(MOVDstore [off] {sym} ptr (FMOVDfpgp val) mem) => (FMOVDstore [off] {sym} ptr val mem)
-(FMOVDstore [off] {sym} ptr (FMOVDgpfp val) mem) => (MOVDstore [off] {sym} ptr val mem)
-(MOVWstore [off] {sym} ptr (FMOVSfpgp val) mem) => (FMOVSstore [off] {sym} ptr val mem)
-(FMOVSstore [off] {sym} ptr (FMOVSgpfp val) mem) => (MOVWstore [off] {sym} ptr val mem)
-
-// float <=> int register moves, with no conversion.
-// These come up when compiling math.{Float64bits, Float64frombits, Float32bits, Float32frombits}.
-(MOVDload [off] {sym} ptr (FMOVDstore [off] {sym} ptr val _)) => (FMOVDfpgp val)
-(FMOVDload [off] {sym} ptr (MOVDstore [off] {sym} ptr val _)) => (FMOVDgpfp val)
-(MOVWUload [off] {sym} ptr (FMOVSstore [off] {sym} ptr val _)) => (FMOVSfpgp val)
-(FMOVSload [off] {sym} ptr (MOVWstore [off] {sym} ptr val _)) => (FMOVSgpfp val)
-
-(BitLen64 x) => (SUB (MOVDconst [64]) (CLZ <typ.Int> x))
-(BitLen32 x) => (SUB (MOVDconst [32]) (CLZW <typ.Int> x))
-
-(Bswap64 ...) => (REV ...)
-(Bswap32 ...) => (REVW ...)
-
-(BitRev64 ...) => (RBIT ...)
-(BitRev32 ...) => (RBITW ...)
-(BitRev16 x) => (SRLconst [48] (RBIT <typ.UInt64> x))
-(BitRev8 x) => (SRLconst [56] (RBIT <typ.UInt64> x))
-
-// In fact, UMOD will be translated into UREM instruction, and UREM is originally translated into
-// UDIV and MSUB instructions. But if there is already an identical UDIV instruction just before or
-// after UREM (case like quo, rem := z/y, z%y), then the second UDIV instruction becomes redundant.
-// The purpose of this rule is to have this extra UDIV instruction removed in CSE pass.
-(UMOD <typ.UInt64> x y) => (MSUB <typ.UInt64> x y (UDIV <typ.UInt64> x y))
-(UMODW <typ.UInt32> x y) => (MSUBW <typ.UInt32> x y (UDIVW <typ.UInt32> x y))
-
-// 64-bit addition with carry.
-(Select0 (Add64carry x y c)) => (Select0 <typ.UInt64> (ADCSflags x y (Select1 <types.TypeFlags> (ADDSconstflags [-1] c))))
-(Select1 (Add64carry x y c)) => (ADCzerocarry <typ.UInt64> (Select1 <types.TypeFlags> (ADCSflags x y (Select1 <types.TypeFlags> (ADDSconstflags [-1] c)))))
-
-// 64-bit subtraction with borrowing.
-(Select0 (Sub64borrow x y bo)) => (Select0 <typ.UInt64> (SBCSflags x y (Select1 <types.TypeFlags> (NEGSflags bo))))
-(Select1 (Sub64borrow x y bo)) => (NEG <typ.UInt64> (NGCzerocarry <typ.UInt64> (Select1 <types.TypeFlags> (SBCSflags x y (Select1 <types.TypeFlags> (NEGSflags bo))))))
-
-// boolean ops -- booleans are represented with 0=false, 1=true
-(AndB ...) => (AND ...)
-(OrB ...) => (OR ...)
-(EqB x y) => (XOR (MOVDconst [1]) (XOR <typ.Bool> x y))
-(NeqB ...) => (XOR ...)
-(Not x) => (XOR (MOVDconst [1]) x)
-
-// shifts
-// hardware instruction uses only the low 6 bits of the shift
-// we compare to 64 to ensure Go semantics for large shifts
-// Rules about rotates with non-const shift are based on the following rules,
-// if the following rules change, please also modify the rules based on them.
-(Lsh64x64 <t> x y) => (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
-(Lsh64x32 <t> x y) => (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
-(Lsh64x16 <t> x y) => (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
-(Lsh64x8  <t> x y) => (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt8to64  y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
-
-(Lsh32x64 <t> x y) => (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
-(Lsh32x32 <t> x y) => (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
-(Lsh32x16 <t> x y) => (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
-(Lsh32x8  <t> x y) => (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt8to64  y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
-
-(Lsh16x64 <t> x y) => (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
-(Lsh16x32 <t> x y) => (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
-(Lsh16x16 <t> x y) => (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
-(Lsh16x8  <t> x y) => (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt8to64  y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
-
-(Lsh8x64 <t> x y) => (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
-(Lsh8x32 <t> x y) => (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
-(Lsh8x16 <t> x y) => (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
-(Lsh8x8  <t> x y) => (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt8to64  y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
-
-(Rsh64Ux64 <t> x y) => (CSEL [OpARM64LessThanU] (SRL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
-(Rsh64Ux32 <t> x y) => (CSEL [OpARM64LessThanU] (SRL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
-(Rsh64Ux16 <t> x y) => (CSEL [OpARM64LessThanU] (SRL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
-(Rsh64Ux8  <t> x y) => (CSEL [OpARM64LessThanU] (SRL <t> x (ZeroExt8to64  y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
-
-(Rsh32Ux64 <t> x y) => (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt32to64 x) y) (Const64 <t> [0]) (CMPconst [64] y))
-(Rsh32Ux32 <t> x y) => (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt32to64 x) (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
-(Rsh32Ux16 <t> x y) => (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt32to64 x) (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
-(Rsh32Ux8  <t> x y) => (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt32to64 x) (ZeroExt8to64  y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
-
-(Rsh16Ux64 <t> x y) => (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt16to64 x) y) (Const64 <t> [0]) (CMPconst [64] y))
-(Rsh16Ux32 <t> x y) => (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt16to64 x) (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
-(Rsh16Ux16 <t> x y) => (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt16to64 x) (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
-(Rsh16Ux8  <t> x y) => (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt16to64 x) (ZeroExt8to64  y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
-
-(Rsh8Ux64 <t> x y) => (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt8to64 x) y) (Const64 <t> [0]) (CMPconst [64] y))
-(Rsh8Ux32 <t> x y) => (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt8to64 x) (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
-(Rsh8Ux16 <t> x y) => (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt8to64 x) (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
-(Rsh8Ux8  <t> x y) => (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt8to64 x) (ZeroExt8to64  y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64  y)))
-
-(Rsh64x64 x y) => (SRA x (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
-(Rsh64x32 x y) => (SRA x (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt32to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
-(Rsh64x16 x y) => (SRA x (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt16to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
-(Rsh64x8  x y) => (SRA x (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt8to64  y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64  y))))
-
-(Rsh32x64 x y) => (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
-(Rsh32x32 x y) => (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt32to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
-(Rsh32x16 x y) => (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt16to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
-(Rsh32x8  x y) => (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt8to64  y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64  y))))
-
-(Rsh16x64 x y) => (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
-(Rsh16x32 x y) => (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt32to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
-(Rsh16x16 x y) => (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt16to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
-(Rsh16x8  x y) => (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt8to64  y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64  y))))
-
-(Rsh8x64 x y) => (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
-(Rsh8x32 x y) => (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt32to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
-(Rsh8x16 x y) => (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt16to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
-(Rsh8x8  x y) => (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt8to64  y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64  y))))
-
-// constants
-(Const(64|32|16|8) [val]) => (MOVDconst [int64(val)])
-(Const(32F|64F) [val]) => (FMOV(S|D)const [float64(val)])
-(ConstNil) => (MOVDconst [0])
-(ConstBool [t]) => (MOVDconst [b2i(t)])
-
-(Slicemask <t> x) => (SRAconst (NEG <t> x) [63])
-
-// truncations
-// Because we ignore high parts of registers, truncates are just copies.
-(Trunc16to8 ...) => (Copy ...)
-(Trunc32to8 ...) => (Copy ...)
-(Trunc32to16 ...) => (Copy ...)
-(Trunc64to8 ...) => (Copy ...)
-(Trunc64to16 ...) => (Copy ...)
-(Trunc64to32 ...) => (Copy ...)
-
-// Zero-/Sign-extensions
-(ZeroExt8to16 ...) => (MOVBUreg ...)
-(ZeroExt8to32 ...) => (MOVBUreg ...)
-(ZeroExt16to32 ...) => (MOVHUreg ...)
-(ZeroExt8to64 ...) => (MOVBUreg ...)
-(ZeroExt16to64 ...) => (MOVHUreg ...)
-(ZeroExt32to64 ...) => (MOVWUreg ...)
-
-(SignExt8to16 ...) => (MOVBreg ...)
-(SignExt8to32 ...) => (MOVBreg ...)
-(SignExt16to32 ...) => (MOVHreg ...)
-(SignExt8to64 ...) => (MOVBreg ...)
-(SignExt16to64 ...) => (MOVHreg ...)
-(SignExt32to64 ...) => (MOVWreg ...)
-
-// float <=> int conversion
-(Cvt32to32F ...) => (SCVTFWS ...)
-(Cvt32to64F ...) => (SCVTFWD ...)
-(Cvt64to32F ...) => (SCVTFS ...)
-(Cvt64to64F ...) => (SCVTFD ...)
-(Cvt32Uto32F ...) => (UCVTFWS ...)
-(Cvt32Uto64F ...) => (UCVTFWD ...)
-(Cvt64Uto32F ...) => (UCVTFS ...)
-(Cvt64Uto64F ...) => (UCVTFD ...)
-(Cvt32Fto32 ...) => (FCVTZSSW ...)
-(Cvt64Fto32 ...) => (FCVTZSDW ...)
-(Cvt32Fto64 ...) => (FCVTZSS ...)
-(Cvt64Fto64 ...) => (FCVTZSD ...)
-(Cvt32Fto32U ...) => (FCVTZUSW ...)
-(Cvt64Fto32U ...) => (FCVTZUDW ...)
-(Cvt32Fto64U ...) => (FCVTZUS ...)
-(Cvt64Fto64U ...) => (FCVTZUD ...)
-(Cvt32Fto64F ...) => (FCVTSD ...)
-(Cvt64Fto32F ...) => (FCVTDS ...)
-
-(CvtBoolToUint8 ...) => (Copy ...)
-
-(Round32F ...) => (LoweredRound32F ...)
-(Round64F ...) => (LoweredRound64F ...)
-
-// comparisons
-(Eq8 x y)  => (Equal (CMPW (ZeroExt8to32 x) (ZeroExt8to32 y)))
-(Eq16 x y) => (Equal (CMPW (ZeroExt16to32 x) (ZeroExt16to32 y)))
-(Eq32 x y) => (Equal (CMPW x y))
-(Eq64 x y) => (Equal (CMP x y))
-(EqPtr x y) => (Equal (CMP x y))
-(Eq32F x y) => (Equal (FCMPS x y))
-(Eq64F x y) => (Equal (FCMPD x y))
-
-(Neq8 x y)  => (NotEqual (CMPW (ZeroExt8to32 x) (ZeroExt8to32 y)))
-(Neq16 x y) => (NotEqual (CMPW (ZeroExt16to32 x) (ZeroExt16to32 y)))
-(Neq32 x y) => (NotEqual (CMPW x y))
-(Neq64 x y) => (NotEqual (CMP x y))
-(NeqPtr x y) => (NotEqual (CMP x y))
-(Neq32F x y) => (NotEqual (FCMPS x y))
-(Neq64F x y) => (NotEqual (FCMPD x y))
-
-(Less8 x y)  => (LessThan (CMPW (SignExt8to32 x) (SignExt8to32 y)))
-(Less16 x y) => (LessThan (CMPW (SignExt16to32 x) (SignExt16to32 y)))
-(Less32 x y) => (LessThan (CMPW x y))
-(Less64 x y) => (LessThan (CMP x y))
-
-// Set condition flags for floating-point comparisons "x < y"
-// and "x <= y". Because if either or both of the operands are
-// NaNs, all three of (x < y), (x == y) and (x > y) are false,
-// and ARM Manual says FCMP instruction sets PSTATE.<N,Z,C,V>
-// of this case to (0, 0, 1, 1).
-(Less32F x y) => (LessThanF (FCMPS x y))
-(Less64F x y) => (LessThanF (FCMPD x y))
-
-// For an unsigned integer x, the following rules are useful when combining branch
-// 0 <  x  =>  x != 0
-// x <= 0  =>  x == 0
-// x <  1  =>  x == 0
-// 1 <= x  =>  x != 0
-(Less(8U|16U|32U|64U) zero:(MOVDconst [0]) x) => (Neq(8|16|32|64) zero x)
-(Leq(8U|16U|32U|64U) x zero:(MOVDconst [0]))  => (Eq(8|16|32|64) x zero)
-(Less(8U|16U|32U|64U) x (MOVDconst [1])) => (Eq(8|16|32|64) x (MOVDconst [0]))
-(Leq(8U|16U|32U|64U) (MOVDconst [1]) x)  => (Neq(8|16|32|64) (MOVDconst [0]) x)
-
-(Less8U x y)  => (LessThanU (CMPW (ZeroExt8to32 x) (ZeroExt8to32 y)))
-(Less16U x y) => (LessThanU (CMPW (ZeroExt16to32 x) (ZeroExt16to32 y)))
-(Less32U x y) => (LessThanU (CMPW x y))
-(Less64U x y) => (LessThanU (CMP x y))
-
-(Leq8 x y)  => (LessEqual (CMPW (SignExt8to32 x) (SignExt8to32 y)))
-(Leq16 x y) => (LessEqual (CMPW (SignExt16to32 x) (SignExt16to32 y)))
-(Leq32 x y) => (LessEqual (CMPW x y))
-(Leq64 x y) => (LessEqual (CMP x y))
-
-// Refer to the comments for op Less64F above.
-(Leq32F x y) => (LessEqualF (FCMPS x y))
-(Leq64F x y) => (LessEqualF (FCMPD x y))
-
-(Leq8U x y)  => (LessEqualU (CMPW (ZeroExt8to32 x) (ZeroExt8to32 y)))
-(Leq16U x y) => (LessEqualU (CMPW (ZeroExt16to32 x) (ZeroExt16to32 y)))
-(Leq32U x y) => (LessEqualU (CMPW x y))
-(Leq64U x y) => (LessEqualU (CMP x y))
-
-// Optimize comparison between a floating-point value and 0.0 with "FCMP $(0.0), Fn"
-(FCMPS x (FMOVSconst [0])) => (FCMPS0 x)
-(FCMPS (FMOVSconst [0]) x) => (InvertFlags (FCMPS0 x))
-(FCMPD x (FMOVDconst [0])) => (FCMPD0 x)
-(FCMPD (FMOVDconst [0]) x) => (InvertFlags (FCMPD0 x))
-
-// CSEL needs a flag-generating argument. Synthesize a CMPW if necessary.
-(CondSelect x y boolval) && flagArg(boolval) != nil => (CSEL [boolval.Op] x y flagArg(boolval))
-(CondSelect x y boolval) && flagArg(boolval) == nil => (CSEL [OpARM64NotEqual] x y (CMPWconst [0] boolval))
-
-(OffPtr [off] ptr:(SP)) && is32Bit(off) => (MOVDaddr [int32(off)] ptr)
-(OffPtr [off] ptr) => (ADDconst [off] ptr)
-
-(Addr {sym} base) => (MOVDaddr {sym} base)
-(LocalAddr {sym} base _) => (MOVDaddr {sym} base)
-
-// loads
-(Load <t> ptr mem) && t.IsBoolean() => (MOVBUload ptr mem)
-(Load <t> ptr mem) && (is8BitInt(t)  && isSigned(t))  => (MOVBload ptr mem)
-(Load <t> ptr mem) && (is8BitInt(t)  && !isSigned(t)) => (MOVBUload ptr mem)
-(Load <t> ptr mem) && (is16BitInt(t) && isSigned(t))  => (MOVHload ptr mem)
-(Load <t> ptr mem) && (is16BitInt(t) && !isSigned(t)) => (MOVHUload ptr mem)
-(Load <t> ptr mem) && (is32BitInt(t) && isSigned(t))  => (MOVWload ptr mem)
-(Load <t> ptr mem) && (is32BitInt(t) && !isSigned(t)) => (MOVWUload ptr mem)
-(Load <t> ptr mem) && (is64BitInt(t) || isPtr(t)) => (MOVDload ptr mem)
-(Load <t> ptr mem) && is32BitFloat(t) => (FMOVSload ptr mem)
-(Load <t> ptr mem) && is64BitFloat(t) => (FMOVDload ptr mem)
-
-// stores
-(Store {t} ptr val mem) && t.Size() == 1 => (MOVBstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 2 => (MOVHstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 4 && !is32BitFloat(val.Type) => (MOVWstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 8 && !is64BitFloat(val.Type) => (MOVDstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 4 && is32BitFloat(val.Type) => (FMOVSstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 8 && is64BitFloat(val.Type) => (FMOVDstore ptr val mem)
-
-// zeroing
-(Zero [0] _ mem) => mem
-(Zero [1] ptr mem) => (MOVBstore ptr (MOVDconst [0]) mem)
-(Zero [2] ptr mem) => (MOVHstore ptr (MOVDconst [0]) mem)
-(Zero [4] ptr mem) => (MOVWstore ptr (MOVDconst [0]) mem)
-(Zero [8] ptr mem) => (MOVDstore ptr (MOVDconst [0]) mem)
-
-(Zero [3] ptr mem) =>
-	(MOVBstore [2] ptr (MOVDconst [0])
-		(MOVHstore ptr (MOVDconst [0]) mem))
-(Zero [5] ptr mem) =>
-	(MOVBstore [4] ptr (MOVDconst [0])
-		(MOVWstore ptr (MOVDconst [0]) mem))
-(Zero [6] ptr mem) =>
-	(MOVHstore [4] ptr (MOVDconst [0])
-		(MOVWstore ptr (MOVDconst [0]) mem))
-(Zero [7] ptr mem) =>
-	(MOVBstore [6] ptr (MOVDconst [0])
-		(MOVHstore [4] ptr (MOVDconst [0])
-			(MOVWstore ptr (MOVDconst [0]) mem)))
-(Zero [9] ptr mem) =>
-	(MOVBstore [8] ptr (MOVDconst [0])
-		(MOVDstore ptr (MOVDconst [0]) mem))
-(Zero [10] ptr mem) =>
-	(MOVHstore [8] ptr (MOVDconst [0])
-		(MOVDstore ptr (MOVDconst [0]) mem))
-(Zero [11] ptr mem) =>
-	(MOVBstore [10] ptr (MOVDconst [0])
-		(MOVHstore [8] ptr (MOVDconst [0])
-			(MOVDstore ptr (MOVDconst [0]) mem)))
-(Zero [12] ptr mem) =>
-	(MOVWstore [8] ptr (MOVDconst [0])
-		(MOVDstore ptr (MOVDconst [0]) mem))
-(Zero [13] ptr mem) =>
-	(MOVBstore [12] ptr (MOVDconst [0])
-		(MOVWstore [8] ptr (MOVDconst [0])
-			(MOVDstore ptr (MOVDconst [0]) mem)))
-(Zero [14] ptr mem) =>
-	(MOVHstore [12] ptr (MOVDconst [0])
-		(MOVWstore [8] ptr (MOVDconst [0])
-			(MOVDstore ptr (MOVDconst [0]) mem)))
-(Zero [15] ptr mem) =>
-	(MOVBstore [14] ptr (MOVDconst [0])
-		(MOVHstore [12] ptr (MOVDconst [0])
-			(MOVWstore [8] ptr (MOVDconst [0])
-				(MOVDstore ptr (MOVDconst [0]) mem))))
-(Zero [16] ptr mem) =>
-	(STP [0] ptr (MOVDconst [0]) (MOVDconst [0]) mem)
-
-(Zero [32] ptr mem) =>
-	(STP [16] ptr (MOVDconst [0]) (MOVDconst [0])
-		(STP [0] ptr (MOVDconst [0]) (MOVDconst [0]) mem))
-
-(Zero [48] ptr mem) =>
-	(STP [32] ptr (MOVDconst [0]) (MOVDconst [0])
-		(STP [16] ptr (MOVDconst [0]) (MOVDconst [0])
-			(STP [0] ptr (MOVDconst [0]) (MOVDconst [0]) mem)))
-
-(Zero [64] ptr mem) =>
-	(STP [48] ptr (MOVDconst [0]) (MOVDconst [0])
-		(STP [32] ptr (MOVDconst [0]) (MOVDconst [0])
-			(STP [16] ptr (MOVDconst [0]) (MOVDconst [0])
-				(STP [0] ptr (MOVDconst [0]) (MOVDconst [0]) mem))))
-
-// strip off fractional word zeroing
-(Zero [s] ptr mem) && s%16 != 0 && s%16 <= 8 && s > 16 =>
-	(Zero [8]
-		(OffPtr <ptr.Type> ptr [s-8])
-		(Zero [s-s%16] ptr mem))
-(Zero [s] ptr mem) && s%16 != 0 && s%16 > 8 && s > 16 =>
-	(Zero [16]
-		(OffPtr <ptr.Type> ptr [s-16])
-		(Zero [s-s%16] ptr mem))
-
-// medium zeroing uses a duff device
-// 4, 16, and 64 are magic constants, see runtime/mkduff.go
-(Zero [s] ptr mem)
-	&& s%16 == 0 && s > 64 && s <= 16*64
-	&& !config.noDuffDevice =>
-	(DUFFZERO [4 * (64 - s/16)] ptr mem)
-
-// large zeroing uses a loop
-(Zero [s] ptr mem)
-	&& s%16 == 0 && (s > 16*64 || config.noDuffDevice) =>
-	(LoweredZero
-		ptr
-		(ADDconst <ptr.Type> [s-16] ptr)
-		mem)
-
-// moves
-(Move [0] _ _ mem) => mem
-(Move [1] dst src mem) => (MOVBstore dst (MOVBUload src mem) mem)
-(Move [2] dst src mem) => (MOVHstore dst (MOVHUload src mem) mem)
-(Move [4] dst src mem) => (MOVWstore dst (MOVWUload src mem) mem)
-(Move [8] dst src mem) => (MOVDstore dst (MOVDload src mem) mem)
-
-(Move [3] dst src mem) =>
-	(MOVBstore [2] dst (MOVBUload [2] src mem)
-		(MOVHstore dst (MOVHUload src mem) mem))
-(Move [5] dst src mem) =>
-	(MOVBstore [4] dst (MOVBUload [4] src mem)
-		(MOVWstore dst (MOVWUload src mem) mem))
-(Move [6] dst src mem) =>
-	(MOVHstore [4] dst (MOVHUload [4] src mem)
-		(MOVWstore dst (MOVWUload src mem) mem))
-(Move [7] dst src mem) =>
-	(MOVBstore [6] dst (MOVBUload [6] src mem)
-		(MOVHstore [4] dst (MOVHUload [4] src mem)
-			(MOVWstore dst (MOVWUload src mem) mem)))
-(Move [12] dst src mem) =>
-	(MOVWstore [8] dst (MOVWUload [8] src mem)
-		(MOVDstore dst (MOVDload src mem) mem))
-(Move [16] dst src mem) =>
-	(MOVDstore [8] dst (MOVDload [8] src mem)
-		(MOVDstore dst (MOVDload src mem) mem))
-(Move [24] dst src mem) =>
-	(MOVDstore [16] dst (MOVDload [16] src mem)
-		(MOVDstore [8] dst (MOVDload [8] src mem)
-			(MOVDstore dst (MOVDload src mem) mem)))
-
-// strip off fractional word move
-(Move [s] dst src mem) && s%8 != 0 && s > 8 =>
-	(Move [s%8]
-		(OffPtr <dst.Type> dst [s-s%8])
-		(OffPtr <src.Type> src [s-s%8])
-		(Move [s-s%8] dst src mem))
-
-// medium move uses a duff device
-(Move [s] dst src mem)
-	&& s > 32 && s <= 16*64 && s%16 == 8
-	&& !config.noDuffDevice && logLargeCopy(v, s) =>
-	(MOVDstore [int32(s-8)] dst (MOVDload [int32(s-8)] src mem)
-		(DUFFCOPY <types.TypeMem> [8*(64-(s-8)/16)] dst src mem))
-(Move [s] dst src mem)
-	&& s > 32 && s <= 16*64 && s%16 == 0
-	&& !config.noDuffDevice && logLargeCopy(v, s) =>
-	(DUFFCOPY [8 * (64 - s/16)] dst src mem)
-// 8 is the number of bytes to encode:
-//
-// LDP.P   16(R16), (R26, R27)
-// STP.P   (R26, R27), 16(R17)
-//
-// 64 is number of these blocks. See runtime/duff_arm64.s:duffcopy
-
-// large move uses a loop
-(Move [s] dst src mem)
-	&& s > 24 && s%8 == 0 && logLargeCopy(v, s) =>
-	(LoweredMove
-		dst
-		src
-		(ADDconst <src.Type> src [s-8])
-		mem)
-
-// calls
-(StaticCall ...) => (CALLstatic ...)
-(ClosureCall ...) => (CALLclosure ...)
-(InterCall ...) => (CALLinter ...)
-(TailCall ...) => (CALLtail ...)
-
-// checks
-(NilCheck ...) => (LoweredNilCheck ...)
-(IsNonNil ptr) => (NotEqual (CMPconst [0] ptr))
-(IsInBounds idx len) => (LessThanU (CMP idx len))
-(IsSliceInBounds idx len) => (LessEqualU (CMP idx len))
-
-// pseudo-ops
-(GetClosurePtr ...) => (LoweredGetClosurePtr ...)
-(GetCallerSP ...) => (LoweredGetCallerSP ...)
-(GetCallerPC ...) => (LoweredGetCallerPC ...)
-
-// Absorb pseudo-ops into blocks.
-(If (Equal cc) yes no) => (EQ cc yes no)
-(If (NotEqual cc) yes no) => (NE cc yes no)
-(If (LessThan cc) yes no) => (LT cc yes no)
-(If (LessThanU cc) yes no) => (ULT cc yes no)
-(If (LessEqual cc) yes no) => (LE cc yes no)
-(If (LessEqualU cc) yes no) => (ULE cc yes no)
-(If (GreaterThan cc) yes no) => (GT cc yes no)
-(If (GreaterThanU cc) yes no) => (UGT cc yes no)
-(If (GreaterEqual cc) yes no) => (GE cc yes no)
-(If (GreaterEqualU cc) yes no) => (UGE cc yes no)
-(If (LessThanF cc) yes no) => (FLT cc yes no)
-(If (LessEqualF cc) yes no) => (FLE cc yes no)
-(If (GreaterThanF cc) yes no) => (FGT cc yes no)
-(If (GreaterEqualF cc) yes no) => (FGE cc yes no)
-
-(If cond yes no) => (TBNZ [0] cond yes no)
-
-(JumpTable idx) => (JUMPTABLE {makeJumpTableSym(b)} idx (MOVDaddr <typ.Uintptr> {makeJumpTableSym(b)} (SB)))
-
-// atomic intrinsics
-// Note: these ops do not accept offset.
-(AtomicLoad8   ...) => (LDARB ...)
-(AtomicLoad32  ...) => (LDARW ...)
-(AtomicLoad64  ...) => (LDAR  ...)
-(AtomicLoadPtr ...) => (LDAR  ...)
-
-(AtomicStore8       ...) => (STLRB ...)
-(AtomicStore32      ...) => (STLRW ...)
-(AtomicStore64      ...) => (STLR  ...)
-(AtomicStorePtrNoWB ...) => (STLR  ...)
-
-(AtomicExchange(32|64)       ...) => (LoweredAtomicExchange(32|64) ...)
-(AtomicAdd(32|64)            ...) => (LoweredAtomicAdd(32|64) ...)
-(AtomicCompareAndSwap(32|64) ...) => (LoweredAtomicCas(32|64) ...)
-
-(AtomicAdd(32|64)Variant            ...) => (LoweredAtomicAdd(32|64)Variant      ...)
-(AtomicExchange(32|64)Variant       ...) => (LoweredAtomicExchange(32|64)Variant ...)
-(AtomicCompareAndSwap(32|64)Variant ...) => (LoweredAtomicCas(32|64)Variant      ...)
-
-// Currently the updated value is not used, but we need a register to temporarily hold it.
-(AtomicAnd8  ptr val mem) => (Select1 (LoweredAtomicAnd8  ptr val mem))
-(AtomicAnd32 ptr val mem) => (Select1 (LoweredAtomicAnd32 ptr val mem))
-(AtomicOr8   ptr val mem) => (Select1 (LoweredAtomicOr8   ptr val mem))
-(AtomicOr32  ptr val mem) => (Select1 (LoweredAtomicOr32  ptr val mem))
-
-(AtomicAnd8Variant  ptr val mem) => (Select1 (LoweredAtomicAnd8Variant  ptr val mem))
-(AtomicAnd32Variant ptr val mem) => (Select1 (LoweredAtomicAnd32Variant ptr val mem))
-(AtomicOr8Variant   ptr val mem) => (Select1 (LoweredAtomicOr8Variant   ptr val mem))
-(AtomicOr32Variant  ptr val mem) => (Select1 (LoweredAtomicOr32Variant  ptr val mem))
-
-// Write barrier.
-(WB ...) => (LoweredWB ...)
-
-// Publication barrier (0xe is ST option)
-(PubBarrier mem) => (DMB [0xe] mem)
-
-(PanicBounds [kind] x y mem) && boundsABI(kind) == 0 => (LoweredPanicBoundsA [kind] x y mem)
-(PanicBounds [kind] x y mem) && boundsABI(kind) == 1 => (LoweredPanicBoundsB [kind] x y mem)
-(PanicBounds [kind] x y mem) && boundsABI(kind) == 2 => (LoweredPanicBoundsC [kind] x y mem)
-
-// Optimizations
-
-// Absorb boolean tests into block
-(NZ (Equal cc) yes no) => (EQ cc yes no)
-(NZ (NotEqual cc) yes no) => (NE cc yes no)
-(NZ (LessThan cc) yes no) => (LT cc yes no)
-(NZ (LessThanU cc) yes no) => (ULT cc yes no)
-(NZ (LessEqual cc) yes no) => (LE cc yes no)
-(NZ (LessEqualU cc) yes no) => (ULE cc yes no)
-(NZ (GreaterThan cc) yes no) => (GT cc yes no)
-(NZ (GreaterThanU cc) yes no) => (UGT cc yes no)
-(NZ (GreaterEqual cc) yes no) => (GE cc yes no)
-(NZ (GreaterEqualU cc) yes no) => (UGE cc yes no)
-(NZ (LessThanF cc) yes no) => (FLT cc yes no)
-(NZ (LessEqualF cc) yes no) => (FLE cc yes no)
-(NZ (GreaterThanF cc) yes no) => (FGT cc yes no)
-(NZ (GreaterEqualF cc) yes no) => (FGE cc yes no)
-
-(TBNZ [0] (Equal cc) yes no) => (EQ cc yes no)
-(TBNZ [0] (NotEqual cc) yes no) => (NE cc yes no)
-(TBNZ [0] (LessThan cc) yes no) => (LT cc yes no)
-(TBNZ [0] (LessThanU cc) yes no) => (ULT cc yes no)
-(TBNZ [0] (LessEqual cc) yes no) => (LE cc yes no)
-(TBNZ [0] (LessEqualU cc) yes no) => (ULE cc yes no)
-(TBNZ [0] (GreaterThan cc) yes no) => (GT cc yes no)
-(TBNZ [0] (GreaterThanU cc) yes no) => (UGT cc yes no)
-(TBNZ [0] (GreaterEqual cc) yes no) => (GE cc yes no)
-(TBNZ [0] (GreaterEqualU cc) yes no) => (UGE cc yes no)
-(TBNZ [0] (LessThanF cc) yes no) => (FLT cc yes no)
-(TBNZ [0] (LessEqualF cc) yes no) => (FLE cc yes no)
-(TBNZ [0] (GreaterThanF cc) yes no) => (FGT cc yes no)
-(TBNZ [0] (GreaterEqualF cc) yes no) => (FGE cc yes no)
-
-(EQ (CMPWconst [0] x:(ANDconst [c] y)) yes no) && x.Uses == 1 => (EQ (TSTWconst [int32(c)] y) yes no)
-(NE (CMPWconst [0] x:(ANDconst [c] y)) yes no) && x.Uses == 1 => (NE (TSTWconst [int32(c)] y) yes no)
-(LT (CMPWconst [0] x:(ANDconst [c] y)) yes no) && x.Uses == 1 => (LT (TSTWconst [int32(c)] y) yes no)
-(LE (CMPWconst [0] x:(ANDconst [c] y)) yes no) && x.Uses == 1 => (LE (TSTWconst [int32(c)] y) yes no)
-(GT (CMPWconst [0] x:(ANDconst [c] y)) yes no) && x.Uses == 1 => (GT (TSTWconst [int32(c)] y) yes no)
-(GE (CMPWconst [0] x:(ANDconst [c] y)) yes no) && x.Uses == 1 => (GE (TSTWconst [int32(c)] y) yes no)
-
-(EQ (CMPconst [0] z:(AND x y)) yes no) && z.Uses == 1 => (EQ (TST x y) yes no)
-(NE (CMPconst [0] z:(AND x y)) yes no) && z.Uses == 1 => (NE (TST x y) yes no)
-(LT (CMPconst [0] z:(AND x y)) yes no) && z.Uses == 1 => (LT (TST x y) yes no)
-(LE (CMPconst [0] z:(AND x y)) yes no) && z.Uses == 1 => (LE (TST x y) yes no)
-(GT (CMPconst [0] z:(AND x y)) yes no) && z.Uses == 1 => (GT (TST x y) yes no)
-(GE (CMPconst [0] z:(AND x y)) yes no) && z.Uses == 1 => (GE (TST x y) yes no)
-
-(EQ (CMPWconst [0] z:(AND x y)) yes no) && z.Uses == 1 => (EQ (TSTW x y) yes no)
-(NE (CMPWconst [0] z:(AND x y)) yes no) && z.Uses == 1 => (NE (TSTW x y) yes no)
-(LT (CMPWconst [0] z:(AND x y)) yes no) && z.Uses == 1 => (LT (TSTW x y) yes no)
-(LE (CMPWconst [0] z:(AND x y)) yes no) && z.Uses == 1 => (LE (TSTW x y) yes no)
-(GT (CMPWconst [0] z:(AND x y)) yes no) && z.Uses == 1 => (GT (TSTW x y) yes no)
-(GE (CMPWconst [0] z:(AND x y)) yes no) && z.Uses == 1 => (GE (TSTW x y) yes no)
-
-(EQ (CMPconst [0] x:(ANDconst [c] y)) yes no) && x.Uses == 1 => (EQ (TSTconst [c] y) yes no)
-(NE (CMPconst [0] x:(ANDconst [c] y)) yes no) && x.Uses == 1 => (NE (TSTconst [c] y) yes no)
-(LT (CMPconst [0] x:(ANDconst [c] y)) yes no) && x.Uses == 1 => (LT (TSTconst [c] y) yes no)
-(LE (CMPconst [0] x:(ANDconst [c] y)) yes no) && x.Uses == 1 => (LE (TSTconst [c] y) yes no)
-(GT (CMPconst [0] x:(ANDconst [c] y)) yes no) && x.Uses == 1 => (GT (TSTconst [c] y) yes no)
-(GE (CMPconst [0] x:(ANDconst [c] y)) yes no) && x.Uses == 1 => (GE (TSTconst [c] y) yes no)
-
-(EQ (CMPconst [0] x:(ADDconst [c] y)) yes no) && x.Uses == 1 => (EQ (CMNconst [c] y) yes no)
-(NE (CMPconst [0] x:(ADDconst [c] y)) yes no) && x.Uses == 1 => (NE (CMNconst [c] y) yes no)
-(LT (CMPconst [0] x:(ADDconst [c] y)) yes no) && x.Uses == 1 => (LTnoov (CMNconst [c] y) yes no)
-(LE (CMPconst [0] x:(ADDconst [c] y)) yes no) && x.Uses == 1 => (LEnoov (CMNconst [c] y) yes no)
-(GT (CMPconst [0] x:(ADDconst [c] y)) yes no) && x.Uses == 1 => (GTnoov (CMNconst [c] y) yes no)
-(GE (CMPconst [0] x:(ADDconst [c] y)) yes no) && x.Uses == 1 => (GEnoov (CMNconst [c] y) yes no)
-
-(EQ (CMPWconst [0] x:(ADDconst [c] y)) yes no) && x.Uses == 1 => (EQ (CMNWconst [int32(c)] y) yes no)
-(NE (CMPWconst [0] x:(ADDconst [c] y)) yes no) && x.Uses == 1 => (NE (CMNWconst [int32(c)] y) yes no)
-(LT (CMPWconst [0] x:(ADDconst [c] y)) yes no) && x.Uses == 1 => (LTnoov (CMNWconst [int32(c)] y) yes no)
-(LE (CMPWconst [0] x:(ADDconst [c] y)) yes no) && x.Uses == 1 => (LEnoov (CMNWconst [int32(c)] y) yes no)
-(GT (CMPWconst [0] x:(ADDconst [c] y)) yes no) && x.Uses == 1 => (GTnoov (CMNWconst [int32(c)] y) yes no)
-(GE (CMPWconst [0] x:(ADDconst [c] y)) yes no) && x.Uses == 1 => (GEnoov (CMNWconst [int32(c)] y) yes no)
-
-(EQ (CMPconst [0] z:(ADD x y)) yes no) && z.Uses == 1 => (EQ (CMN x y) yes no)
-(NE (CMPconst [0] z:(ADD x y)) yes no) && z.Uses == 1 => (NE (CMN x y) yes no)
-(LT (CMPconst [0] z:(ADD x y)) yes no) && z.Uses == 1 => (LTnoov (CMN x y) yes no)
-(LE (CMPconst [0] z:(ADD x y)) yes no) && z.Uses == 1 => (LEnoov (CMN x y) yes no)
-(GT (CMPconst [0] z:(ADD x y)) yes no) && z.Uses == 1 => (GTnoov (CMN x y) yes no)
-(GE (CMPconst [0] z:(ADD x y)) yes no) && z.Uses == 1 => (GEnoov (CMN x y) yes no)
-
-(EQ (CMPWconst [0] z:(ADD x y)) yes no) && z.Uses == 1 => (EQ (CMNW x y) yes no)
-(NE (CMPWconst [0] z:(ADD x y)) yes no) && z.Uses == 1 => (NE (CMNW x y) yes no)
-(LT (CMPWconst [0] z:(ADD x y)) yes no) && z.Uses == 1 => (LTnoov (CMNW x y) yes no)
-(LE (CMPWconst [0] z:(ADD x y)) yes no) && z.Uses == 1 => (LEnoov (CMNW x y) yes no)
-(GT (CMPWconst [0] z:(ADD x y)) yes no) && z.Uses == 1 => (GTnoov (CMNW x y) yes no)
-(GE (CMPWconst [0] z:(ADD x y)) yes no) && z.Uses == 1 => (GEnoov (CMNW x y) yes no)
-
-// CMP(x,-y) -> CMN(x,y) is only valid for unordered comparison, if y can be -1<<63
-(EQ (CMP x z:(NEG y)) yes no) && z.Uses == 1 => (EQ (CMN x y) yes no)
-(NE (CMP x z:(NEG y)) yes no) && z.Uses == 1 => (NE (CMN x y) yes no)
-
-// CMPW(x,-y) -> CMNW(x,y) is only valid for unordered comparison, if y can be -1<<31
-(EQ (CMPW x z:(NEG y)) yes no) && z.Uses == 1 => (EQ (CMNW x y) yes no)
-(NE (CMPW x z:(NEG y)) yes no) && z.Uses == 1 => (NE (CMNW x y) yes no)
-
-(EQ (CMPconst [0] x) yes no) => (Z x yes no)
-(NE (CMPconst [0] x) yes no) => (NZ x yes no)
-(EQ (CMPWconst [0] x) yes no) => (ZW x yes no)
-(NE (CMPWconst [0] x) yes no) => (NZW x yes no)
-
-(EQ (CMPconst [0]  z:(MADD a x y)) yes no) && z.Uses==1 => (EQ (CMN a (MUL <x.Type> x y)) yes no)
-(NE (CMPconst [0]  z:(MADD a x y)) yes no) && z.Uses==1 => (NE (CMN a (MUL <x.Type> x y)) yes no)
-(LT (CMPconst [0]  z:(MADD a x y)) yes no) && z.Uses==1 => (LTnoov (CMN a (MUL <x.Type> x y)) yes no)
-(LE (CMPconst [0]  z:(MADD a x y)) yes no) && z.Uses==1 => (LEnoov (CMN a (MUL <x.Type> x y)) yes no)
-(GT (CMPconst [0]  z:(MADD a x y)) yes no) && z.Uses==1 => (GTnoov (CMN a (MUL <x.Type> x y)) yes no)
-(GE (CMPconst [0]  z:(MADD a x y)) yes no) && z.Uses==1 => (GEnoov (CMN a (MUL <x.Type> x y)) yes no)
-
-(EQ (CMPconst [0]  z:(MSUB a x y)) yes no) && z.Uses==1 => (EQ (CMP a (MUL <x.Type> x y)) yes no)
-(NE (CMPconst [0]  z:(MSUB a x y)) yes no) && z.Uses==1 => (NE (CMP a (MUL <x.Type> x y)) yes no)
-(LE (CMPconst [0]  z:(MSUB a x y)) yes no) && z.Uses==1 => (LEnoov (CMP a (MUL <x.Type> x y)) yes no)
-(LT (CMPconst [0]  z:(MSUB a x y)) yes no) && z.Uses==1 => (LTnoov (CMP a (MUL <x.Type> x y)) yes no)
-(GE (CMPconst [0]  z:(MSUB a x y)) yes no) && z.Uses==1 => (GEnoov (CMP a (MUL <x.Type> x y)) yes no)
-(GT (CMPconst [0]  z:(MSUB a x y)) yes no) && z.Uses==1 => (GTnoov (CMP a (MUL <x.Type> x y)) yes no)
-
-(EQ (CMPWconst [0] z:(MADDW a x y)) yes no) && z.Uses==1 => (EQ (CMNW a (MULW <x.Type> x y)) yes no)
-(NE (CMPWconst [0] z:(MADDW a x y)) yes no) && z.Uses==1 => (NE (CMNW a (MULW <x.Type> x y)) yes no)
-(LE (CMPWconst [0] z:(MADDW a x y)) yes no) && z.Uses==1 => (LEnoov (CMNW a (MULW <x.Type> x y)) yes no)
-(LT (CMPWconst [0] z:(MADDW a x y)) yes no) && z.Uses==1 => (LTnoov (CMNW a (MULW <x.Type> x y)) yes no)
-(GE (CMPWconst [0] z:(MADDW a x y)) yes no) && z.Uses==1 => (GEnoov (CMNW a (MULW <x.Type> x y)) yes no)
-(GT (CMPWconst [0] z:(MADDW a x y)) yes no) && z.Uses==1 => (GTnoov (CMNW a (MULW <x.Type> x y)) yes no)
-
-(EQ (CMPWconst [0] z:(MSUBW a x y)) yes no) && z.Uses==1 => (EQ (CMPW a (MULW <x.Type> x y)) yes no)
-(NE (CMPWconst [0] z:(MSUBW a x y)) yes no) && z.Uses==1 => (NE (CMPW a (MULW <x.Type> x y)) yes no)
-(LE (CMPWconst [0] z:(MSUBW a x y)) yes no) && z.Uses==1 => (LEnoov (CMPW a (MULW <x.Type> x y)) yes no)
-(LT (CMPWconst [0] z:(MSUBW a x y)) yes no) && z.Uses==1 => (LTnoov (CMPW a (MULW <x.Type> x y)) yes no)
-(GE (CMPWconst [0] z:(MSUBW a x y)) yes no) && z.Uses==1 => (GEnoov (CMPW a (MULW <x.Type> x y)) yes no)
-(GT (CMPWconst [0] z:(MSUBW a x y)) yes no) && z.Uses==1 => (GTnoov (CMPW a (MULW <x.Type> x y)) yes no)
-
-// Absorb bit-tests into block
-(Z  (ANDconst [c] x) yes no) && oneBit(c) => (TBZ  [int64(ntz64(c))] x yes no)
-(NZ (ANDconst [c] x) yes no) && oneBit(c) => (TBNZ [int64(ntz64(c))] x yes no)
-(ZW  (ANDconst [c] x) yes no) && oneBit(int64(uint32(c))) => (TBZ  [int64(ntz64(int64(uint32(c))))] x yes no)
-(NZW (ANDconst [c] x) yes no) && oneBit(int64(uint32(c))) => (TBNZ [int64(ntz64(int64(uint32(c))))] x yes no)
-(EQ (TSTconst [c] x) yes no) && oneBit(c) => (TBZ  [int64(ntz64(c))] x yes no)
-(NE (TSTconst [c] x) yes no) && oneBit(c) => (TBNZ [int64(ntz64(c))] x yes no)
-(EQ (TSTWconst [c] x) yes no) && oneBit(int64(uint32(c))) => (TBZ  [int64(ntz64(int64(uint32(c))))] x yes no)
-(NE (TSTWconst [c] x) yes no) && oneBit(int64(uint32(c))) => (TBNZ [int64(ntz64(int64(uint32(c))))] x yes no)
-
-// Test sign-bit for signed comparisons against zero
-(GE (CMPWconst [0] x) yes no) => (TBZ  [31] x yes no)
-(GE (CMPconst [0] x) yes no) => (TBZ  [63] x yes no)
-(LT (CMPWconst [0] x) yes no) => (TBNZ  [31] x yes no)
-(LT (CMPconst [0] x) yes no) => (TBNZ  [63] x yes no)
-
-// fold offset into address
-(ADDconst [off1] (MOVDaddr [off2] {sym} ptr)) && is32Bit(off1+int64(off2)) =>
-	 (MOVDaddr [int32(off1)+off2] {sym} ptr)
-
-// fold address into load/store
-(MOVBload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(MOVBload [off1+int32(off2)] {sym} ptr mem)
-(MOVBUload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(MOVBUload [off1+int32(off2)] {sym} ptr mem)
-(MOVHload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(MOVHload [off1+int32(off2)] {sym} ptr mem)
-(MOVHUload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(MOVHUload [off1+int32(off2)] {sym} ptr mem)
-(MOVWload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(MOVWload [off1+int32(off2)] {sym} ptr mem)
-(MOVWUload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(MOVWUload [off1+int32(off2)] {sym} ptr mem)
-(MOVDload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(MOVDload [off1+int32(off2)] {sym} ptr mem)
-(FMOVSload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(FMOVSload [off1+int32(off2)] {sym} ptr mem)
-(FMOVDload [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(FMOVDload [off1+int32(off2)] {sym} ptr mem)
-
-// register indexed load
-(MOVDload  [off] {sym} (ADD ptr idx) mem) && off == 0 && sym == nil => (MOVDloadidx ptr idx mem)
-(MOVWUload [off] {sym} (ADD ptr idx) mem) && off == 0 && sym == nil => (MOVWUloadidx ptr idx mem)
-(MOVWload  [off] {sym} (ADD ptr idx) mem) && off == 0 && sym == nil => (MOVWloadidx ptr idx mem)
-(MOVHUload [off] {sym} (ADD ptr idx) mem) && off == 0 && sym == nil => (MOVHUloadidx ptr idx mem)
-(MOVHload  [off] {sym} (ADD ptr idx) mem) && off == 0 && sym == nil => (MOVHloadidx ptr idx mem)
-(MOVBUload [off] {sym} (ADD ptr idx) mem) && off == 0 && sym == nil => (MOVBUloadidx ptr idx mem)
-(MOVBload  [off] {sym} (ADD ptr idx) mem) && off == 0 && sym == nil => (MOVBloadidx ptr idx mem)
-(FMOVSload [off] {sym} (ADD ptr idx) mem) && off == 0 && sym == nil => (FMOVSloadidx ptr idx mem)
-(FMOVDload [off] {sym} (ADD ptr idx) mem) && off == 0 && sym == nil => (FMOVDloadidx ptr idx mem)
-(MOVDloadidx  ptr (MOVDconst [c]) mem) && is32Bit(c) => (MOVDload  [int32(c)] ptr mem)
-(MOVDloadidx  (MOVDconst [c]) ptr mem) && is32Bit(c) => (MOVDload  [int32(c)] ptr mem)
-(MOVWUloadidx ptr (MOVDconst [c]) mem) && is32Bit(c) => (MOVWUload [int32(c)] ptr mem)
-(MOVWUloadidx (MOVDconst [c]) ptr mem) && is32Bit(c) => (MOVWUload [int32(c)] ptr mem)
-(MOVWloadidx  ptr (MOVDconst [c]) mem) && is32Bit(c) => (MOVWload  [int32(c)] ptr mem)
-(MOVWloadidx  (MOVDconst [c]) ptr mem) && is32Bit(c) => (MOVWload  [int32(c)] ptr mem)
-(MOVHUloadidx ptr (MOVDconst [c]) mem) && is32Bit(c) => (MOVHUload [int32(c)] ptr mem)
-(MOVHUloadidx (MOVDconst [c]) ptr mem) && is32Bit(c) => (MOVHUload [int32(c)] ptr mem)
-(MOVHloadidx  ptr (MOVDconst [c]) mem) && is32Bit(c) => (MOVHload  [int32(c)] ptr mem)
-(MOVHloadidx  (MOVDconst [c]) ptr mem) && is32Bit(c) => (MOVHload  [int32(c)] ptr mem)
-(MOVBUloadidx ptr (MOVDconst [c]) mem) && is32Bit(c) => (MOVBUload [int32(c)] ptr mem)
-(MOVBUloadidx (MOVDconst [c]) ptr mem) && is32Bit(c) => (MOVBUload [int32(c)] ptr mem)
-(MOVBloadidx  ptr (MOVDconst [c]) mem) && is32Bit(c) => (MOVBload  [int32(c)] ptr mem)
-(MOVBloadidx  (MOVDconst [c]) ptr mem) && is32Bit(c) => (MOVBload  [int32(c)] ptr mem)
-(FMOVSloadidx ptr (MOVDconst [c]) mem) && is32Bit(c) => (FMOVSload [int32(c)] ptr mem)
-(FMOVSloadidx (MOVDconst [c]) ptr mem) && is32Bit(c) => (FMOVSload [int32(c)] ptr mem)
-(FMOVDloadidx ptr (MOVDconst [c]) mem) && is32Bit(c) => (FMOVDload [int32(c)] ptr mem)
-(FMOVDloadidx (MOVDconst [c]) ptr mem) && is32Bit(c) => (FMOVDload [int32(c)] ptr mem)
-
-// shifted register indexed load
-(MOVDload  [off] {sym} (ADDshiftLL [3] ptr idx) mem) && off == 0 && sym == nil => (MOVDloadidx8 ptr idx mem)
-(MOVWUload [off] {sym} (ADDshiftLL [2] ptr idx) mem) && off == 0 && sym == nil => (MOVWUloadidx4 ptr idx mem)
-(MOVWload  [off] {sym} (ADDshiftLL [2] ptr idx) mem) && off == 0 && sym == nil => (MOVWloadidx4 ptr idx mem)
-(MOVHUload [off] {sym} (ADDshiftLL [1] ptr idx) mem) && off == 0 && sym == nil => (MOVHUloadidx2 ptr idx mem)
-(MOVHload  [off] {sym} (ADDshiftLL [1] ptr idx) mem) && off == 0 && sym == nil => (MOVHloadidx2 ptr idx mem)
-(MOVDloadidx  ptr (SLLconst [3] idx) mem) => (MOVDloadidx8 ptr idx mem)
-(MOVWloadidx  ptr (SLLconst [2] idx) mem) => (MOVWloadidx4 ptr idx mem)
-(MOVWUloadidx ptr (SLLconst [2] idx) mem) => (MOVWUloadidx4 ptr idx mem)
-(MOVHloadidx  ptr (SLLconst [1] idx) mem) => (MOVHloadidx2 ptr idx mem)
-(MOVHUloadidx ptr (SLLconst [1] idx) mem) => (MOVHUloadidx2 ptr idx mem)
-(MOVHloadidx  ptr (ADD idx idx) mem) => (MOVHloadidx2 ptr idx mem)
-(MOVHUloadidx ptr (ADD idx idx) mem) => (MOVHUloadidx2 ptr idx mem)
-(MOVDloadidx  (SLLconst [3] idx) ptr mem) => (MOVDloadidx8 ptr idx mem)
-(MOVWloadidx  (SLLconst [2] idx) ptr mem) => (MOVWloadidx4 ptr idx mem)
-(MOVWUloadidx (SLLconst [2] idx) ptr mem) => (MOVWUloadidx4 ptr idx mem)
-(MOVHloadidx  (ADD idx idx) ptr mem) => (MOVHloadidx2 ptr idx mem)
-(MOVHUloadidx (ADD idx idx) ptr mem) => (MOVHUloadidx2 ptr idx mem)
-(MOVDloadidx8  ptr (MOVDconst [c]) mem) && is32Bit(c<<3) => (MOVDload  [int32(c)<<3] ptr mem)
-(MOVWUloadidx4 ptr (MOVDconst [c]) mem) && is32Bit(c<<2) => (MOVWUload [int32(c)<<2] ptr mem)
-(MOVWloadidx4  ptr (MOVDconst [c]) mem) && is32Bit(c<<2) => (MOVWload  [int32(c)<<2] ptr mem)
-(MOVHUloadidx2 ptr (MOVDconst [c]) mem) && is32Bit(c<<1) => (MOVHUload [int32(c)<<1] ptr mem)
-(MOVHloadidx2  ptr (MOVDconst [c]) mem) && is32Bit(c<<1) => (MOVHload  [int32(c)<<1] ptr mem)
-
-(FMOVDload [off] {sym} (ADDshiftLL [3] ptr idx) mem) && off == 0 && sym == nil => (FMOVDloadidx8 ptr idx mem)
-(FMOVSload [off] {sym} (ADDshiftLL [2] ptr idx) mem) && off == 0 && sym == nil => (FMOVSloadidx4 ptr idx mem)
-(FMOVDloadidx ptr (SLLconst [3] idx) mem) => (FMOVDloadidx8 ptr idx mem)
-(FMOVSloadidx ptr (SLLconst [2] idx) mem) => (FMOVSloadidx4 ptr idx mem)
-(FMOVDloadidx (SLLconst [3] idx) ptr mem) => (FMOVDloadidx8 ptr idx mem)
-(FMOVSloadidx (SLLconst [2] idx) ptr mem) => (FMOVSloadidx4 ptr idx mem)
-(FMOVDloadidx8 ptr (MOVDconst [c]) mem) && is32Bit(c<<3) => (FMOVDload ptr [int32(c)<<3] mem)
-(FMOVSloadidx4 ptr (MOVDconst [c]) mem) && is32Bit(c<<2) => (FMOVSload ptr [int32(c)<<2] mem)
-
-(MOVBstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2)
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(MOVBstore [off1+int32(off2)] {sym} ptr val mem)
-(MOVHstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2)
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(MOVHstore [off1+int32(off2)] {sym} ptr val mem)
-(MOVWstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2)
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(MOVWstore [off1+int32(off2)] {sym} ptr val mem)
-(MOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2)
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(MOVDstore [off1+int32(off2)] {sym} ptr val mem)
-(STP [off1] {sym} (ADDconst [off2] ptr) val1 val2 mem) && is32Bit(int64(off1)+off2)
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(STP [off1+int32(off2)] {sym} ptr val1 val2 mem)
-(FMOVSstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2)
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(FMOVSstore [off1+int32(off2)] {sym} ptr val mem)
-(FMOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2)
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(FMOVDstore [off1+int32(off2)] {sym} ptr val mem)
-(MOVBstorezero [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(MOVBstorezero [off1+int32(off2)] {sym} ptr mem)
-(MOVHstorezero [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(MOVHstorezero [off1+int32(off2)] {sym} ptr mem)
-(MOVWstorezero [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(MOVWstorezero [off1+int32(off2)] {sym} ptr mem)
-(MOVDstorezero [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(MOVDstorezero [off1+int32(off2)] {sym} ptr mem)
-(MOVQstorezero [off1] {sym} (ADDconst [off2] ptr) mem) && is32Bit(int64(off1)+off2)
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(MOVQstorezero [off1+int32(off2)] {sym} ptr mem)
-
-// register indexed store
-(MOVDstore [off] {sym} (ADD ptr idx) val mem) && off == 0 && sym == nil => (MOVDstoreidx ptr idx val mem)
-(MOVWstore [off] {sym} (ADD ptr idx) val mem) && off == 0 && sym == nil => (MOVWstoreidx ptr idx val mem)
-(MOVHstore [off] {sym} (ADD ptr idx) val mem) && off == 0 && sym == nil => (MOVHstoreidx ptr idx val mem)
-(MOVBstore [off] {sym} (ADD ptr idx) val mem) && off == 0 && sym == nil => (MOVBstoreidx ptr idx val mem)
-(FMOVDstore [off] {sym} (ADD ptr idx) val mem) && off == 0 && sym == nil => (FMOVDstoreidx ptr idx val mem)
-(FMOVSstore [off] {sym} (ADD ptr idx) val mem) && off == 0 && sym == nil => (FMOVSstoreidx ptr idx val mem)
-(MOVDstoreidx ptr (MOVDconst [c]) val mem) && is32Bit(c) => (MOVDstore [int32(c)] ptr val mem)
-(MOVDstoreidx (MOVDconst [c]) idx val mem) && is32Bit(c) => (MOVDstore [int32(c)] idx val mem)
-(MOVWstoreidx ptr (MOVDconst [c]) val mem) && is32Bit(c) => (MOVWstore [int32(c)] ptr val mem)
-(MOVWstoreidx (MOVDconst [c]) idx val mem) && is32Bit(c) => (MOVWstore [int32(c)] idx val mem)
-(MOVHstoreidx ptr (MOVDconst [c]) val mem) && is32Bit(c) => (MOVHstore [int32(c)] ptr val mem)
-(MOVHstoreidx (MOVDconst [c]) idx val mem) && is32Bit(c) => (MOVHstore [int32(c)] idx val mem)
-(MOVBstoreidx ptr (MOVDconst [c]) val mem) && is32Bit(c) => (MOVBstore [int32(c)] ptr val mem)
-(MOVBstoreidx (MOVDconst [c]) idx val mem) && is32Bit(c) => (MOVBstore [int32(c)] idx val mem)
-(FMOVDstoreidx ptr (MOVDconst [c]) val mem) && is32Bit(c) => (FMOVDstore [int32(c)] ptr val mem)
-(FMOVDstoreidx (MOVDconst [c]) idx val mem) && is32Bit(c) => (FMOVDstore [int32(c)] idx val mem)
-(FMOVSstoreidx ptr (MOVDconst [c]) val mem) && is32Bit(c) => (FMOVSstore [int32(c)] ptr val mem)
-(FMOVSstoreidx (MOVDconst [c]) idx val mem) && is32Bit(c) => (FMOVSstore [int32(c)] idx val mem)
-
-// shifted register indexed store
-(MOVDstore [off] {sym} (ADDshiftLL [3] ptr idx) val mem) && off == 0 && sym == nil => (MOVDstoreidx8 ptr idx val mem)
-(MOVWstore [off] {sym} (ADDshiftLL [2] ptr idx) val mem) && off == 0 && sym == nil => (MOVWstoreidx4 ptr idx val mem)
-(MOVHstore [off] {sym} (ADDshiftLL [1] ptr idx) val mem) && off == 0 && sym == nil => (MOVHstoreidx2 ptr idx val mem)
-(MOVDstoreidx ptr (SLLconst [3] idx) val mem) => (MOVDstoreidx8 ptr idx val mem)
-(MOVWstoreidx ptr (SLLconst [2] idx) val mem) => (MOVWstoreidx4 ptr idx val mem)
-(MOVHstoreidx ptr (SLLconst [1] idx) val mem) => (MOVHstoreidx2 ptr idx val mem)
-(MOVHstoreidx ptr (ADD idx idx) val mem) => (MOVHstoreidx2 ptr idx val mem)
-(MOVDstoreidx (SLLconst [3] idx) ptr val mem) => (MOVDstoreidx8 ptr idx val mem)
-(MOVWstoreidx (SLLconst [2] idx) ptr val mem) => (MOVWstoreidx4 ptr idx val mem)
-(MOVHstoreidx (SLLconst [1] idx) ptr val mem) => (MOVHstoreidx2 ptr idx val mem)
-(MOVHstoreidx (ADD idx idx) ptr val mem) => (MOVHstoreidx2 ptr idx val mem)
-(MOVDstoreidx8 ptr (MOVDconst [c]) val mem) && is32Bit(c<<3) => (MOVDstore [int32(c)<<3] ptr val mem)
-(MOVWstoreidx4 ptr (MOVDconst [c]) val mem) && is32Bit(c<<2) => (MOVWstore [int32(c)<<2] ptr val mem)
-(MOVHstoreidx2 ptr (MOVDconst [c]) val mem) && is32Bit(c<<1) => (MOVHstore [int32(c)<<1] ptr val mem)
-
-(FMOVDstore [off] {sym} (ADDshiftLL [3] ptr idx) val mem) && off == 0 && sym == nil => (FMOVDstoreidx8 ptr idx val mem)
-(FMOVSstore [off] {sym} (ADDshiftLL [2] ptr idx) val mem) && off == 0 && sym == nil => (FMOVSstoreidx4 ptr idx val mem)
-(FMOVDstoreidx ptr (SLLconst [3] idx) val mem) => (FMOVDstoreidx8 ptr idx val mem)
-(FMOVSstoreidx ptr (SLLconst [2] idx) val mem) => (FMOVSstoreidx4 ptr idx val mem)
-(FMOVDstoreidx (SLLconst [3] idx) ptr val mem) => (FMOVDstoreidx8 ptr idx val mem)
-(FMOVSstoreidx (SLLconst [2] idx) ptr val mem) => (FMOVSstoreidx4 ptr idx val mem)
-(FMOVDstoreidx8 ptr (MOVDconst [c]) val mem) && is32Bit(c<<3) => (FMOVDstore [int32(c)<<3] ptr val mem)
-(FMOVSstoreidx4 ptr (MOVDconst [c]) val mem) && is32Bit(c<<2) => (FMOVSstore [int32(c)<<2] ptr val mem)
-
-(MOVBload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(MOVBload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-(MOVBUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(MOVBUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-(MOVHload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(MOVHload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-(MOVHUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(MOVHUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-(MOVWload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(MOVWload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-(MOVWUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(MOVWUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-(MOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(MOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-(FMOVSload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(FMOVSload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-(FMOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(FMOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-
-(MOVBstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
-	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(MOVBstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
-(MOVHstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
-	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(MOVHstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
-(MOVWstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
-	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(MOVWstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
-(MOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
-	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(MOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
-(STP [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val1 val2 mem)
-	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(STP [off1+off2] {mergeSym(sym1,sym2)} ptr val1 val2 mem)
-(FMOVSstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
-	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(FMOVSstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
-(FMOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
-	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(FMOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
-(MOVBstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(MOVBstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-(MOVHstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(MOVHstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-(MOVWstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(MOVWstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-(MOVDstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(MOVDstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-(MOVQstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-	&& canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
-	&& (ptr.Op != OpSB || !config.ctxt.Flag_shared) =>
-	(MOVQstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-
-// store zero
-(MOVBstore [off] {sym} ptr (MOVDconst [0]) mem) => (MOVBstorezero [off] {sym} ptr mem)
-(MOVHstore [off] {sym} ptr (MOVDconst [0]) mem) => (MOVHstorezero [off] {sym} ptr mem)
-(MOVWstore [off] {sym} ptr (MOVDconst [0]) mem) => (MOVWstorezero [off] {sym} ptr mem)
-(MOVDstore [off] {sym} ptr (MOVDconst [0]) mem) => (MOVDstorezero [off] {sym} ptr mem)
-(STP [off] {sym} ptr (MOVDconst [0]) (MOVDconst [0]) mem) => (MOVQstorezero [off] {sym} ptr mem)
-
-// register indexed store zero
-(MOVDstorezero [off] {sym} (ADD ptr idx) mem) && off == 0 && sym == nil => (MOVDstorezeroidx ptr idx mem)
-(MOVWstorezero [off] {sym} (ADD ptr idx) mem) && off == 0 && sym == nil => (MOVWstorezeroidx ptr idx mem)
-(MOVHstorezero [off] {sym} (ADD ptr idx) mem) && off == 0 && sym == nil => (MOVHstorezeroidx ptr idx mem)
-(MOVBstorezero [off] {sym} (ADD ptr idx) mem) && off == 0 && sym == nil => (MOVBstorezeroidx ptr idx mem)
-(MOVDstoreidx ptr idx (MOVDconst [0]) mem) => (MOVDstorezeroidx ptr idx mem)
-(MOVWstoreidx ptr idx (MOVDconst [0]) mem) => (MOVWstorezeroidx ptr idx mem)
-(MOVHstoreidx ptr idx (MOVDconst [0]) mem) => (MOVHstorezeroidx ptr idx mem)
-(MOVBstoreidx ptr idx (MOVDconst [0]) mem) => (MOVBstorezeroidx ptr idx mem)
-(MOVDstorezeroidx ptr (MOVDconst [c]) mem) && is32Bit(c) => (MOVDstorezero [int32(c)] ptr mem)
-(MOVDstorezeroidx (MOVDconst [c]) idx mem) && is32Bit(c) => (MOVDstorezero [int32(c)] idx mem)
-(MOVWstorezeroidx ptr (MOVDconst [c]) mem) && is32Bit(c) => (MOVWstorezero [int32(c)] ptr mem)
-(MOVWstorezeroidx (MOVDconst [c]) idx mem) && is32Bit(c) => (MOVWstorezero [int32(c)] idx mem)
-(MOVHstorezeroidx ptr (MOVDconst [c]) mem) && is32Bit(c) => (MOVHstorezero [int32(c)] ptr mem)
-(MOVHstorezeroidx (MOVDconst [c]) idx mem) && is32Bit(c) => (MOVHstorezero [int32(c)] idx mem)
-(MOVBstorezeroidx ptr (MOVDconst [c]) mem) && is32Bit(c) => (MOVBstorezero [int32(c)] ptr mem)
-(MOVBstorezeroidx (MOVDconst [c]) idx mem) && is32Bit(c) => (MOVBstorezero [int32(c)] idx mem)
-
-// shifted register indexed store zero
-(MOVDstorezero [off] {sym} (ADDshiftLL [3] ptr idx) mem) && off == 0 && sym == nil => (MOVDstorezeroidx8 ptr idx mem)
-(MOVWstorezero [off] {sym} (ADDshiftLL [2] ptr idx) mem) && off == 0 && sym == nil => (MOVWstorezeroidx4 ptr idx mem)
-(MOVHstorezero [off] {sym} (ADDshiftLL [1] ptr idx) mem) && off == 0 && sym == nil => (MOVHstorezeroidx2 ptr idx mem)
-(MOVDstorezeroidx ptr (SLLconst [3] idx) mem) => (MOVDstorezeroidx8 ptr idx mem)
-(MOVWstorezeroidx ptr (SLLconst [2] idx) mem) => (MOVWstorezeroidx4 ptr idx mem)
-(MOVHstorezeroidx ptr (SLLconst [1] idx) mem) => (MOVHstorezeroidx2 ptr idx mem)
-(MOVHstorezeroidx ptr (ADD idx idx) mem) => (MOVHstorezeroidx2 ptr idx mem)
-(MOVDstorezeroidx (SLLconst [3] idx) ptr mem) => (MOVDstorezeroidx8 ptr idx mem)
-(MOVWstorezeroidx (SLLconst [2] idx) ptr mem) => (MOVWstorezeroidx4 ptr idx mem)
-(MOVHstorezeroidx (SLLconst [1] idx) ptr mem) => (MOVHstorezeroidx2 ptr idx mem)
-(MOVHstorezeroidx (ADD idx idx) ptr mem) => (MOVHstorezeroidx2 ptr idx mem)
-(MOVDstoreidx8 ptr idx (MOVDconst [0]) mem) => (MOVDstorezeroidx8 ptr idx mem)
-(MOVWstoreidx4 ptr idx (MOVDconst [0]) mem) => (MOVWstorezeroidx4 ptr idx mem)
-(MOVHstoreidx2 ptr idx (MOVDconst [0]) mem) => (MOVHstorezeroidx2 ptr idx mem)
-(MOVDstorezeroidx8 ptr (MOVDconst [c]) mem) && is32Bit(c<<3) => (MOVDstorezero [int32(c<<3)] ptr mem)
-(MOVWstorezeroidx4 ptr (MOVDconst [c]) mem) && is32Bit(c<<2) => (MOVWstorezero [int32(c<<2)] ptr mem)
-(MOVHstorezeroidx2 ptr (MOVDconst [c]) mem) && is32Bit(c<<1) => (MOVHstorezero [int32(c<<1)] ptr mem)
-
-// replace load from same location as preceding store with zero/sign extension (or copy in case of full width)
-// these seem to have bad interaction with other rules, resulting in slower code
-//(MOVBload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> (MOVBreg x)
-//(MOVBUload [off] {sym} ptr (MOVBstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> (MOVBUreg x)
-//(MOVHload [off] {sym} ptr (MOVHstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> (MOVHreg x)
-//(MOVHUload [off] {sym} ptr (MOVHstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> (MOVHUreg x)
-//(MOVWload [off] {sym} ptr (MOVWstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> (MOVWreg x)
-//(MOVWUload [off] {sym} ptr (MOVWstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> (MOVWUreg x)
-//(MOVDload [off] {sym} ptr (MOVDstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> x
-//(FMOVSload [off] {sym} ptr (FMOVSstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> x
-//(FMOVDload [off] {sym} ptr (FMOVDstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> x
-
-(MOVBload [off] {sym} ptr (MOVBstorezero [off2] {sym2} ptr2 _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVDconst [0])
-(MOVBUload [off] {sym} ptr (MOVBstorezero [off2] {sym2} ptr2 _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVDconst [0])
-(MOVHload [off] {sym} ptr (MOVHstorezero [off2] {sym2} ptr2 _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVDconst [0])
-(MOVHUload [off] {sym} ptr (MOVHstorezero [off2] {sym2} ptr2 _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVDconst [0])
-(MOVWload [off] {sym} ptr (MOVWstorezero [off2] {sym2} ptr2 _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVDconst [0])
-(MOVWUload [off] {sym} ptr (MOVWstorezero [off2] {sym2} ptr2 _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVDconst [0])
-(MOVDload [off] {sym} ptr (MOVDstorezero [off2] {sym2} ptr2 _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) => (MOVDconst [0])
-
-(MOVBloadidx ptr idx (MOVBstorezeroidx ptr2 idx2 _))
-	&& (isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2)) => (MOVDconst [0])
-(MOVBUloadidx ptr idx (MOVBstorezeroidx ptr2 idx2 _))
-	&& (isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2)) => (MOVDconst [0])
-(MOVHloadidx ptr idx (MOVHstorezeroidx ptr2 idx2 _))
-	&& (isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2)) => (MOVDconst [0])
-(MOVHUloadidx ptr idx (MOVHstorezeroidx ptr2 idx2 _))
-	&& (isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2)) => (MOVDconst [0])
-(MOVWloadidx ptr idx (MOVWstorezeroidx ptr2 idx2 _))
-	&& (isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2)) => (MOVDconst [0])
-(MOVWUloadidx ptr idx (MOVWstorezeroidx ptr2 idx2 _))
-	&& (isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2)) => (MOVDconst [0])
-(MOVDloadidx ptr idx (MOVDstorezeroidx ptr2 idx2 _))
-	&& (isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) || isSamePtr(ptr, idx2) && isSamePtr(idx, ptr2)) => (MOVDconst [0])
-
-(MOVHloadidx2 ptr idx (MOVHstorezeroidx2 ptr2 idx2 _)) && isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) => (MOVDconst [0])
-(MOVHUloadidx2 ptr idx (MOVHstorezeroidx2 ptr2 idx2 _)) && isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) => (MOVDconst [0])
-(MOVWloadidx4 ptr idx (MOVWstorezeroidx4 ptr2 idx2 _)) && isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) => (MOVDconst [0])
-(MOVWUloadidx4 ptr idx (MOVWstorezeroidx4 ptr2 idx2 _)) && isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) => (MOVDconst [0])
-(MOVDloadidx8 ptr idx (MOVDstorezeroidx8 ptr2 idx2 _)) && isSamePtr(ptr, ptr2) && isSamePtr(idx, idx2) => (MOVDconst [0])
-
-// don't extend after proper load
-(MOVBreg x:(MOVBload _ _)) => (MOVDreg x)
-(MOVBUreg x:(MOVBUload _ _)) => (MOVDreg x)
-(MOVHreg x:(MOVBload _ _)) => (MOVDreg x)
-(MOVHreg x:(MOVBUload _ _)) => (MOVDreg x)
-(MOVHreg x:(MOVHload _ _)) => (MOVDreg x)
-(MOVHUreg x:(MOVBUload _ _)) => (MOVDreg x)
-(MOVHUreg x:(MOVHUload _ _)) => (MOVDreg x)
-(MOVWreg x:(MOVBload _ _)) => (MOVDreg x)
-(MOVWreg x:(MOVBUload _ _)) => (MOVDreg x)
-(MOVWreg x:(MOVHload _ _)) => (MOVDreg x)
-(MOVWreg x:(MOVHUload _ _)) => (MOVDreg x)
-(MOVWreg x:(MOVWload _ _)) => (MOVDreg x)
-(MOVWUreg x:(MOVBUload _ _)) => (MOVDreg x)
-(MOVWUreg x:(MOVHUload _ _)) => (MOVDreg x)
-(MOVWUreg x:(MOVWUload _ _)) => (MOVDreg x)
-(MOVBreg x:(MOVBloadidx _  _ _)) => (MOVDreg x)
-(MOVBUreg x:(MOVBUloadidx _ _ _)) => (MOVDreg x)
-(MOVHreg x:(MOVBloadidx _ _ _)) => (MOVDreg x)
-(MOVHreg x:(MOVBUloadidx _ _ _)) => (MOVDreg x)
-(MOVHreg x:(MOVHloadidx _ _ _)) => (MOVDreg x)
-(MOVHUreg x:(MOVBUloadidx _ _ _)) => (MOVDreg x)
-(MOVHUreg x:(MOVHUloadidx _ _ _)) => (MOVDreg x)
-(MOVWreg x:(MOVBloadidx _ _ _)) => (MOVDreg x)
-(MOVWreg x:(MOVBUloadidx _ _ _)) => (MOVDreg x)
-(MOVWreg x:(MOVHloadidx _ _ _)) => (MOVDreg x)
-(MOVWreg x:(MOVHUloadidx _ _ _)) => (MOVDreg x)
-(MOVWreg x:(MOVWloadidx _ _ _)) => (MOVDreg x)
-(MOVWUreg x:(MOVBUloadidx _ _ _)) => (MOVDreg x)
-(MOVWUreg x:(MOVHUloadidx _ _ _)) => (MOVDreg x)
-(MOVWUreg x:(MOVWUloadidx _ _ _)) => (MOVDreg x)
-(MOVHreg x:(MOVHloadidx2 _ _ _)) => (MOVDreg x)
-(MOVHUreg x:(MOVHUloadidx2 _ _ _)) => (MOVDreg x)
-(MOVWreg x:(MOVHloadidx2 _ _ _)) => (MOVDreg x)
-(MOVWreg x:(MOVHUloadidx2 _ _ _)) => (MOVDreg x)
-(MOVWreg x:(MOVWloadidx4 _ _ _)) => (MOVDreg x)
-(MOVWUreg x:(MOVHUloadidx2 _ _ _)) => (MOVDreg x)
-(MOVWUreg x:(MOVWUloadidx4 _ _ _)) => (MOVDreg x)
-
-// fold double extensions
-(MOVBreg x:(MOVBreg _)) => (MOVDreg x)
-(MOVBUreg x:(MOVBUreg _)) => (MOVDreg x)
-(MOVHreg x:(MOVBreg _)) => (MOVDreg x)
-(MOVHreg x:(MOVBUreg _)) => (MOVDreg x)
-(MOVHreg x:(MOVHreg _)) => (MOVDreg x)
-(MOVHUreg x:(MOVBUreg _)) => (MOVDreg x)
-(MOVHUreg x:(MOVHUreg _)) => (MOVDreg x)
-(MOVWreg x:(MOVBreg _)) => (MOVDreg x)
-(MOVWreg x:(MOVBUreg _)) => (MOVDreg x)
-(MOVWreg x:(MOVHreg _)) => (MOVDreg x)
-(MOVWreg x:(MOVWreg _)) => (MOVDreg x)
-(MOVWUreg x:(MOVBUreg _)) => (MOVDreg x)
-(MOVWUreg x:(MOVHUreg _)) => (MOVDreg x)
-(MOVWUreg x:(MOVWUreg _)) => (MOVDreg x)
-
-// don't extend before store
-(MOVBstore [off] {sym} ptr (MOVBreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr (MOVBUreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr (MOVHreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr (MOVHUreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr (MOVWreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr (MOVWUreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
-(MOVHstore [off] {sym} ptr (MOVHreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
-(MOVHstore [off] {sym} ptr (MOVHUreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
-(MOVHstore [off] {sym} ptr (MOVWreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
-(MOVHstore [off] {sym} ptr (MOVWUreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
-(MOVWstore [off] {sym} ptr (MOVWreg x) mem) => (MOVWstore [off] {sym} ptr x mem)
-(MOVWstore [off] {sym} ptr (MOVWUreg x) mem) => (MOVWstore [off] {sym} ptr x mem)
-(MOVBstoreidx ptr idx (MOVBreg x) mem) => (MOVBstoreidx ptr idx x mem)
-(MOVBstoreidx ptr idx (MOVBUreg x) mem) => (MOVBstoreidx ptr idx x mem)
-(MOVBstoreidx ptr idx (MOVHreg x) mem) => (MOVBstoreidx ptr idx x mem)
-(MOVBstoreidx ptr idx (MOVHUreg x) mem) => (MOVBstoreidx ptr idx x mem)
-(MOVBstoreidx ptr idx (MOVWreg x) mem) => (MOVBstoreidx ptr idx x mem)
-(MOVBstoreidx ptr idx (MOVWUreg x) mem) => (MOVBstoreidx ptr idx x mem)
-(MOVHstoreidx ptr idx (MOVHreg x) mem) => (MOVHstoreidx ptr idx x mem)
-(MOVHstoreidx ptr idx (MOVHUreg x) mem) => (MOVHstoreidx ptr idx x mem)
-(MOVHstoreidx ptr idx (MOVWreg x) mem) => (MOVHstoreidx ptr idx x mem)
-(MOVHstoreidx ptr idx (MOVWUreg x) mem) => (MOVHstoreidx ptr idx x mem)
-(MOVWstoreidx ptr idx (MOVWreg x) mem) => (MOVWstoreidx ptr idx x mem)
-(MOVWstoreidx ptr idx (MOVWUreg x) mem) => (MOVWstoreidx ptr idx x mem)
-(MOVHstoreidx2 ptr idx (MOVHreg x) mem) => (MOVHstoreidx2 ptr idx x mem)
-(MOVHstoreidx2 ptr idx (MOVHUreg x) mem) => (MOVHstoreidx2 ptr idx x mem)
-(MOVHstoreidx2 ptr idx (MOVWreg x) mem) => (MOVHstoreidx2 ptr idx x mem)
-(MOVHstoreidx2 ptr idx (MOVWUreg x) mem) => (MOVHstoreidx2 ptr idx x mem)
-(MOVWstoreidx4 ptr idx (MOVWreg x) mem) => (MOVWstoreidx4 ptr idx x mem)
-(MOVWstoreidx4 ptr idx (MOVWUreg x) mem) => (MOVWstoreidx4 ptr idx x mem)
-
-// if a register move has only 1 use, just use the same register without emitting instruction
-// MOVDnop doesn't emit instruction, only for ensuring the type.
-(MOVDreg x) && x.Uses == 1 => (MOVDnop x)
-
-// TODO: we should be able to get rid of MOVDnop all together.
-// But for now, this is enough to get rid of lots of them.
-(MOVDnop (MOVDconst [c])) => (MOVDconst [c])
-
-// fold constant into arithmetic ops
-(ADD x (MOVDconst [c])) => (ADDconst [c] x)
-(SUB x (MOVDconst [c])) => (SUBconst [c] x)
-(AND x (MOVDconst [c])) => (ANDconst [c] x)
-(OR  x (MOVDconst [c])) => (ORconst  [c] x)
-(XOR x (MOVDconst [c])) => (XORconst [c] x)
-(TST x (MOVDconst [c])) => (TSTconst [c] x)
-(TSTW x (MOVDconst [c])) => (TSTWconst [int32(c)] x)
-(CMN x (MOVDconst [c])) => (CMNconst [c] x)
-(CMNW x (MOVDconst [c])) => (CMNWconst [int32(c)] x)
-(BIC x (MOVDconst [c])) => (ANDconst [^c] x)
-(EON x (MOVDconst [c])) => (XORconst [^c] x)
-(ORN x (MOVDconst [c])) => (ORconst  [^c] x)
-
-(SLL x (MOVDconst [c])) => (SLLconst x [c&63]) // Note: I don't think we ever generate bad constant shifts (i.e. c>=64)
-(SRL x (MOVDconst [c])) => (SRLconst x [c&63])
-(SRA x (MOVDconst [c])) => (SRAconst x [c&63])
-
-(CMP x (MOVDconst [c])) => (CMPconst [c] x)
-(CMP (MOVDconst [c]) x) => (InvertFlags (CMPconst [c] x))
-(CMPW x (MOVDconst [c])) => (CMPWconst [int32(c)] x)
-(CMPW (MOVDconst [c]) x) => (InvertFlags (CMPWconst [int32(c)] x))
-
-(ROR x (MOVDconst [c])) => (RORconst x [c&63])
-(RORW x (MOVDconst [c])) => (RORWconst x [c&31])
-
-// Canonicalize the order of arguments to comparisons - helps with CSE.
-((CMP|CMPW) x y) && canonLessThan(x,y) => (InvertFlags ((CMP|CMPW) y x))
-
-// mul-neg => mneg
-(NEG (MUL x y)) => (MNEG x y)
-(NEG (MULW x y)) => (MNEGW x y)
-(MUL (NEG x) y) => (MNEG x y)
-(MULW (NEG x) y) => (MNEGW x y)
-
-// madd/msub
-(ADD a l:(MUL  x y)) && l.Uses==1 && clobber(l) => (MADD a x y)
-(SUB a l:(MUL  x y)) && l.Uses==1 && clobber(l) => (MSUB a x y)
-(ADD a l:(MNEG x y)) && l.Uses==1 && clobber(l) => (MSUB a x y)
-(SUB a l:(MNEG x y)) && l.Uses==1 && clobber(l) => (MADD a x y)
-
-(ADD a l:(MULW  x y)) && a.Type.Size() != 8 && l.Uses==1 && clobber(l) => (MADDW a x y)
-(SUB a l:(MULW  x y)) && a.Type.Size() != 8 && l.Uses==1 && clobber(l) => (MSUBW a x y)
-(ADD a l:(MNEGW x y)) && a.Type.Size() != 8 && l.Uses==1 && clobber(l) => (MSUBW a x y)
-(SUB a l:(MNEGW x y)) && a.Type.Size() != 8 && l.Uses==1 && clobber(l) => (MADDW a x y)
-
-// optimize ADCSflags, SBCSflags and friends
-(ADCSflags x y (Select1 <types.TypeFlags> (ADDSconstflags [-1] (ADCzerocarry <typ.UInt64> c)))) => (ADCSflags x y c)
-(ADCSflags x y (Select1 <types.TypeFlags> (ADDSconstflags [-1] (MOVDconst [0])))) => (ADDSflags x y)
-(SBCSflags x y (Select1 <types.TypeFlags> (NEGSflags (NEG <typ.UInt64> (NGCzerocarry <typ.UInt64> bo))))) => (SBCSflags x y bo)
-(SBCSflags x y (Select1 <types.TypeFlags> (NEGSflags (MOVDconst [0])))) => (SUBSflags x y)
-
-// mul by constant
-(MUL x (MOVDconst [-1])) => (NEG x)
-(MUL _ (MOVDconst [0])) => (MOVDconst [0])
-(MUL x (MOVDconst [1])) => x
-(MUL x (MOVDconst [c])) && isPowerOfTwo64(c) => (SLLconst [log64(c)] x)
-(MUL x (MOVDconst [c])) && isPowerOfTwo64(c-1) && c >= 3 => (ADDshiftLL x x [log64(c-1)])
-(MUL x (MOVDconst [c])) && isPowerOfTwo64(c+1) && c >= 7 => (ADDshiftLL (NEG <x.Type> x) x [log64(c+1)])
-(MUL x (MOVDconst [c])) && c%3 == 0 && isPowerOfTwo64(c/3) => (SLLconst [log64(c/3)] (ADDshiftLL <x.Type> x x [1]))
-(MUL x (MOVDconst [c])) && c%5 == 0 && isPowerOfTwo64(c/5) => (SLLconst [log64(c/5)] (ADDshiftLL <x.Type> x x [2]))
-(MUL x (MOVDconst [c])) && c%7 == 0 && isPowerOfTwo64(c/7) => (SLLconst [log64(c/7)] (ADDshiftLL <x.Type> (NEG <x.Type> x) x [3]))
-(MUL x (MOVDconst [c])) && c%9 == 0 && isPowerOfTwo64(c/9) => (SLLconst [log64(c/9)] (ADDshiftLL <x.Type> x x [3]))
-
-(MULW x (MOVDconst [c])) && int32(c)==-1 => (NEG x)
-(MULW _ (MOVDconst [c])) && int32(c)==0 => (MOVDconst [0])
-(MULW x (MOVDconst [c])) && int32(c)==1 => x
-(MULW x (MOVDconst [c])) && isPowerOfTwo64(c) => (SLLconst [log64(c)] x)
-(MULW x (MOVDconst [c])) && isPowerOfTwo64(c-1) && int32(c) >= 3 => (ADDshiftLL x x [log64(c-1)])
-(MULW x (MOVDconst [c])) && isPowerOfTwo64(c+1) && int32(c) >= 7 => (ADDshiftLL (NEG <x.Type> x) x [log64(c+1)])
-(MULW x (MOVDconst [c])) && c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c) => (SLLconst [log64(c/3)] (ADDshiftLL <x.Type> x x [1]))
-(MULW x (MOVDconst [c])) && c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c) => (SLLconst [log64(c/5)] (ADDshiftLL <x.Type> x x [2]))
-(MULW x (MOVDconst [c])) && c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c) => (SLLconst [log64(c/7)] (ADDshiftLL <x.Type> (NEG <x.Type> x) x [3]))
-(MULW x (MOVDconst [c])) && c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c) => (SLLconst [log64(c/9)] (ADDshiftLL <x.Type> x x [3]))
-
-// mneg by constant
-(MNEG x (MOVDconst [-1])) => x
-(MNEG _ (MOVDconst [0])) => (MOVDconst [0])
-(MNEG x (MOVDconst [1])) => (NEG x)
-(MNEG x (MOVDconst [c])) && isPowerOfTwo64(c) => (NEG (SLLconst <x.Type> [log64(c)] x))
-(MNEG x (MOVDconst [c])) && isPowerOfTwo64(c-1) && c >= 3 => (NEG (ADDshiftLL <x.Type> x x [log64(c-1)]))
-(MNEG x (MOVDconst [c])) && isPowerOfTwo64(c+1) && c >= 7 => (NEG (ADDshiftLL <x.Type> (NEG <x.Type> x) x [log64(c+1)]))
-(MNEG x (MOVDconst [c])) && c%3 == 0 && isPowerOfTwo64(c/3) => (SLLconst <x.Type> [log64(c/3)] (SUBshiftLL <x.Type> x x [2]))
-(MNEG x (MOVDconst [c])) && c%5 == 0 && isPowerOfTwo64(c/5) => (NEG (SLLconst <x.Type> [log64(c/5)] (ADDshiftLL <x.Type> x x [2])))
-(MNEG x (MOVDconst [c])) && c%7 == 0 && isPowerOfTwo64(c/7) => (SLLconst <x.Type> [log64(c/7)] (SUBshiftLL <x.Type> x x [3]))
-(MNEG x (MOVDconst [c])) && c%9 == 0 && isPowerOfTwo64(c/9) => (NEG (SLLconst <x.Type> [log64(c/9)] (ADDshiftLL <x.Type> x x [3])))
-
-
-(MNEGW x (MOVDconst [c])) && int32(c)==-1 => x
-(MNEGW _ (MOVDconst [c])) && int32(c)==0 => (MOVDconst [0])
-(MNEGW x (MOVDconst [c])) && int32(c)==1 => (NEG x)
-(MNEGW x (MOVDconst [c])) && isPowerOfTwo64(c) => (NEG (SLLconst <x.Type> [log64(c)] x))
-(MNEGW x (MOVDconst [c])) && isPowerOfTwo64(c-1) && int32(c) >= 3 => (NEG (ADDshiftLL <x.Type> x x [log64(c-1)]))
-(MNEGW x (MOVDconst [c])) && isPowerOfTwo64(c+1) && int32(c) >= 7 => (NEG (ADDshiftLL <x.Type> (NEG <x.Type> x) x [log64(c+1)]))
-(MNEGW x (MOVDconst [c])) && c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c) => (SLLconst <x.Type> [log64(c/3)] (SUBshiftLL <x.Type> x x [2]))
-(MNEGW x (MOVDconst [c])) && c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c) => (NEG (SLLconst <x.Type> [log64(c/5)] (ADDshiftLL <x.Type> x x [2])))
-(MNEGW x (MOVDconst [c])) && c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c) => (SLLconst <x.Type> [log64(c/7)] (SUBshiftLL <x.Type> x x [3]))
-(MNEGW x (MOVDconst [c])) && c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c) => (NEG (SLLconst <x.Type> [log64(c/9)] (ADDshiftLL <x.Type> x x [3])))
-
-
-(MADD a x (MOVDconst [-1])) => (SUB a x)
-(MADD a _ (MOVDconst [0])) => a
-(MADD a x (MOVDconst [1])) => (ADD a x)
-(MADD a x (MOVDconst [c])) && isPowerOfTwo64(c) => (ADDshiftLL a x [log64(c)])
-(MADD a x (MOVDconst [c])) && isPowerOfTwo64(c-1) && c>=3 => (ADD a (ADDshiftLL <x.Type> x x [log64(c-1)]))
-(MADD a x (MOVDconst [c])) && isPowerOfTwo64(c+1) && c>=7 => (SUB a (SUBshiftLL <x.Type> x x [log64(c+1)]))
-(MADD a x (MOVDconst [c])) && c%3 == 0 && isPowerOfTwo64(c/3) => (SUBshiftLL a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)])
-(MADD a x (MOVDconst [c])) && c%5 == 0 && isPowerOfTwo64(c/5) => (ADDshiftLL a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)])
-(MADD a x (MOVDconst [c])) && c%7 == 0 && isPowerOfTwo64(c/7) => (SUBshiftLL a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)])
-(MADD a x (MOVDconst [c])) && c%9 == 0 && isPowerOfTwo64(c/9) => (ADDshiftLL a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)])
-
-(MADD a (MOVDconst [-1]) x) => (SUB a x)
-(MADD a (MOVDconst [0]) _) => a
-(MADD a (MOVDconst [1]) x) => (ADD a x)
-(MADD a (MOVDconst [c]) x) && isPowerOfTwo64(c) => (ADDshiftLL a x [log64(c)])
-(MADD a (MOVDconst [c]) x) && isPowerOfTwo64(c-1) && c>=3 => (ADD a (ADDshiftLL <x.Type> x x [log64(c-1)]))
-(MADD a (MOVDconst [c]) x) && isPowerOfTwo64(c+1) && c>=7 => (SUB a (SUBshiftLL <x.Type> x x [log64(c+1)]))
-(MADD a (MOVDconst [c]) x) && c%3 == 0 && isPowerOfTwo64(c/3) => (SUBshiftLL a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)])
-(MADD a (MOVDconst [c]) x) && c%5 == 0 && isPowerOfTwo64(c/5) => (ADDshiftLL a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)])
-(MADD a (MOVDconst [c]) x) && c%7 == 0 && isPowerOfTwo64(c/7) => (SUBshiftLL a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)])
-(MADD a (MOVDconst [c]) x) && c%9 == 0 && isPowerOfTwo64(c/9) => (ADDshiftLL a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)])
-
-(MADDW a x (MOVDconst [c])) && int32(c)==-1 => (SUB a x)
-(MADDW a _ (MOVDconst [c])) && int32(c)==0 => a
-(MADDW a x (MOVDconst [c])) && int32(c)==1 => (ADD a x)
-(MADDW a x (MOVDconst [c])) && isPowerOfTwo64(c) => (ADDshiftLL a x [log64(c)])
-(MADDW a x (MOVDconst [c])) && isPowerOfTwo64(c-1) && int32(c)>=3 => (ADD a (ADDshiftLL <x.Type> x x [log64(c-1)]))
-(MADDW a x (MOVDconst [c])) && isPowerOfTwo64(c+1) && int32(c)>=7 => (SUB a (SUBshiftLL <x.Type> x x [log64(c+1)]))
-(MADDW a x (MOVDconst [c])) && c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c) => (SUBshiftLL a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)])
-(MADDW a x (MOVDconst [c])) && c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c) => (ADDshiftLL a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)])
-(MADDW a x (MOVDconst [c])) && c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c) => (SUBshiftLL a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)])
-(MADDW a x (MOVDconst [c])) && c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c) => (ADDshiftLL a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)])
-
-(MADDW a (MOVDconst [c]) x) && int32(c)==-1 => (SUB a x)
-(MADDW a (MOVDconst [c]) _) && int32(c)==0 => a
-(MADDW a (MOVDconst [c]) x) && int32(c)==1 => (ADD a x)
-(MADDW a (MOVDconst [c]) x) && isPowerOfTwo64(c) => (ADDshiftLL a x [log64(c)])
-(MADDW a (MOVDconst [c]) x) && isPowerOfTwo64(c-1) && int32(c)>=3 => (ADD a (ADDshiftLL <x.Type> x x [log64(c-1)]))
-(MADDW a (MOVDconst [c]) x) && isPowerOfTwo64(c+1) && int32(c)>=7 => (SUB a (SUBshiftLL <x.Type> x x [log64(c+1)]))
-(MADDW a (MOVDconst [c]) x) && c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c) => (SUBshiftLL a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)])
-(MADDW a (MOVDconst [c]) x) && c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c) => (ADDshiftLL a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)])
-(MADDW a (MOVDconst [c]) x) && c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c) => (SUBshiftLL a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)])
-(MADDW a (MOVDconst [c]) x) && c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c) => (ADDshiftLL a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)])
-
-(MSUB a x (MOVDconst [-1])) => (ADD a x)
-(MSUB a _ (MOVDconst [0])) => a
-(MSUB a x (MOVDconst [1])) => (SUB a x)
-(MSUB a x (MOVDconst [c])) && isPowerOfTwo64(c) => (SUBshiftLL a x [log64(c)])
-(MSUB a x (MOVDconst [c])) && isPowerOfTwo64(c-1) && c>=3 => (SUB a (ADDshiftLL <x.Type> x x [log64(c-1)]))
-(MSUB a x (MOVDconst [c])) && isPowerOfTwo64(c+1) && c>=7 => (ADD a (SUBshiftLL <x.Type> x x [log64(c+1)]))
-(MSUB a x (MOVDconst [c])) && c%3 == 0 && isPowerOfTwo64(c/3) => (ADDshiftLL a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)])
-(MSUB a x (MOVDconst [c])) && c%5 == 0 && isPowerOfTwo64(c/5) => (SUBshiftLL a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)])
-(MSUB a x (MOVDconst [c])) && c%7 == 0 && isPowerOfTwo64(c/7) => (ADDshiftLL a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)])
-(MSUB a x (MOVDconst [c])) && c%9 == 0 && isPowerOfTwo64(c/9) => (SUBshiftLL a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)])
-
-(MSUB a (MOVDconst [-1]) x) => (ADD a x)
-(MSUB a (MOVDconst [0]) _) => a
-(MSUB a (MOVDconst [1]) x) => (SUB a x)
-(MSUB a (MOVDconst [c]) x) && isPowerOfTwo64(c) => (SUBshiftLL a x [log64(c)])
-(MSUB a (MOVDconst [c]) x) && isPowerOfTwo64(c-1) && c>=3 => (SUB a (ADDshiftLL <x.Type> x x [log64(c-1)]))
-(MSUB a (MOVDconst [c]) x) && isPowerOfTwo64(c+1) && c>=7 => (ADD a (SUBshiftLL <x.Type> x x [log64(c+1)]))
-(MSUB a (MOVDconst [c]) x) && c%3 == 0 && isPowerOfTwo64(c/3) => (ADDshiftLL a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)])
-(MSUB a (MOVDconst [c]) x) && c%5 == 0 && isPowerOfTwo64(c/5) => (SUBshiftLL a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)])
-(MSUB a (MOVDconst [c]) x) && c%7 == 0 && isPowerOfTwo64(c/7) => (ADDshiftLL a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)])
-(MSUB a (MOVDconst [c]) x) && c%9 == 0 && isPowerOfTwo64(c/9) => (SUBshiftLL a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)])
-
-(MSUBW a x (MOVDconst [c])) && int32(c)==-1 => (ADD a x)
-(MSUBW a _ (MOVDconst [c])) && int32(c)==0 => a
-(MSUBW a x (MOVDconst [c])) && int32(c)==1 => (SUB a x)
-(MSUBW a x (MOVDconst [c])) && isPowerOfTwo64(c) => (SUBshiftLL a x [log64(c)])
-(MSUBW a x (MOVDconst [c])) && isPowerOfTwo64(c-1) && int32(c)>=3 => (SUB a (ADDshiftLL <x.Type> x x [log64(c-1)]))
-(MSUBW a x (MOVDconst [c])) && isPowerOfTwo64(c+1) && int32(c)>=7 => (ADD a (SUBshiftLL <x.Type> x x [log64(c+1)]))
-(MSUBW a x (MOVDconst [c])) && c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c) => (ADDshiftLL a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)])
-(MSUBW a x (MOVDconst [c])) && c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c) => (SUBshiftLL a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)])
-(MSUBW a x (MOVDconst [c])) && c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c) => (ADDshiftLL a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)])
-(MSUBW a x (MOVDconst [c])) && c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c) => (SUBshiftLL a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)])
-
-(MSUBW a (MOVDconst [c]) x) && int32(c)==-1 => (ADD a x)
-(MSUBW a (MOVDconst [c]) _) && int32(c)==0 => a
-(MSUBW a (MOVDconst [c]) x) && int32(c)==1 => (SUB a x)
-(MSUBW a (MOVDconst [c]) x) && isPowerOfTwo64(c) => (SUBshiftLL a x [log64(c)])
-(MSUBW a (MOVDconst [c]) x) && isPowerOfTwo64(c-1) && int32(c)>=3 => (SUB a (ADDshiftLL <x.Type> x x [log64(c-1)]))
-(MSUBW a (MOVDconst [c]) x) && isPowerOfTwo64(c+1) && int32(c)>=7 => (ADD a (SUBshiftLL <x.Type> x x [log64(c+1)]))
-(MSUBW a (MOVDconst [c]) x) && c%3 == 0 && isPowerOfTwo64(c/3) && is32Bit(c) => (ADDshiftLL a (SUBshiftLL <x.Type> x x [2]) [log64(c/3)])
-(MSUBW a (MOVDconst [c]) x) && c%5 == 0 && isPowerOfTwo64(c/5) && is32Bit(c) => (SUBshiftLL a (ADDshiftLL <x.Type> x x [2]) [log64(c/5)])
-(MSUBW a (MOVDconst [c]) x) && c%7 == 0 && isPowerOfTwo64(c/7) && is32Bit(c) => (ADDshiftLL a (SUBshiftLL <x.Type> x x [3]) [log64(c/7)])
-(MSUBW a (MOVDconst [c]) x) && c%9 == 0 && isPowerOfTwo64(c/9) && is32Bit(c) => (SUBshiftLL a (ADDshiftLL <x.Type> x x [3]) [log64(c/9)])
-
-// div by constant
-(UDIV x (MOVDconst [1])) => x
-(UDIV x (MOVDconst [c])) && isPowerOfTwo64(c) => (SRLconst [log64(c)] x)
-(UDIVW x (MOVDconst [c])) && uint32(c)==1 => x
-(UDIVW x (MOVDconst [c])) && isPowerOfTwo64(c) && is32Bit(c) => (SRLconst [log64(c)] x)
-(UMOD _ (MOVDconst [1])) => (MOVDconst [0])
-(UMOD x (MOVDconst [c])) && isPowerOfTwo64(c) => (ANDconst [c-1] x)
-(UMODW _ (MOVDconst [c])) && uint32(c)==1 => (MOVDconst [0])
-(UMODW x (MOVDconst [c])) && isPowerOfTwo64(c) && is32Bit(c) => (ANDconst [c-1] x)
-
-// generic simplifications
-(ADD x (NEG y)) => (SUB x y)
-(SUB x x) => (MOVDconst [0])
-(AND x x) => x
-(OR  x x) => x
-(XOR x x) => (MOVDconst [0])
-(BIC x x) => (MOVDconst [0])
-(EON x x) => (MOVDconst [-1])
-(ORN x x) => (MOVDconst [-1])
-(AND x (MVN y)) => (BIC x y)
-(XOR x (MVN y)) => (EON x y)
-(OR  x (MVN y)) => (ORN x y)
-(MVN (XOR x y)) => (EON x y)
-(NEG (NEG x)) => x
-
-(CSEL [cc] (MOVDconst [-1]) (MOVDconst [0]) flag) => (CSETM [cc] flag)
-(CSEL [cc] (MOVDconst [0]) (MOVDconst [-1]) flag) => (CSETM [arm64Negate(cc)] flag)
-(CSEL [cc] x (MOVDconst [0]) flag) => (CSEL0 [cc] x flag)
-(CSEL [cc] (MOVDconst [0]) y flag) => (CSEL0 [arm64Negate(cc)] y flag)
-(CSEL [cc] x (ADDconst [1] a) flag) => (CSINC [cc] x a flag)
-(CSEL [cc] (ADDconst [1] a) x flag) => (CSINC [arm64Negate(cc)] x a flag)
-(CSEL [cc] x (MVN a) flag) => (CSINV [cc] x a flag)
-(CSEL [cc] (MVN a) x flag) => (CSINV [arm64Negate(cc)] x a flag)
-(CSEL [cc] x (NEG a) flag) => (CSNEG [cc] x a flag)
-(CSEL [cc] (NEG a) x flag) => (CSNEG [arm64Negate(cc)] x a flag)
-
-(SUB x (SUB y z)) => (SUB (ADD <v.Type> x z) y)
-(SUB (SUB x y) z) => (SUB x (ADD <y.Type> y z))
-
-// remove redundant *const ops
-(ADDconst [0]  x) => x
-(SUBconst [0]  x) => x
-(ANDconst [0]  _) => (MOVDconst [0])
-(ANDconst [-1] x) => x
-(ORconst  [0]  x) => x
-(ORconst  [-1] _) => (MOVDconst [-1])
-(XORconst [0]  x) => x
-(XORconst [-1] x) => (MVN x)
-
-// generic constant folding
-(ADDconst [c] (MOVDconst [d]))  => (MOVDconst [c+d])
-(ADDconst [c] (ADDconst [d] x)) => (ADDconst [c+d] x)
-(ADDconst [c] (SUBconst [d] x)) => (ADDconst [c-d] x)
-(SUBconst [c] (MOVDconst [d]))  => (MOVDconst [d-c])
-(SUBconst [c] (SUBconst [d] x)) => (ADDconst [-c-d] x)
-(SUBconst [c] (ADDconst [d] x)) => (ADDconst [-c+d] x)
-(SLLconst [c] (MOVDconst [d]))  => (MOVDconst [d<<uint64(c)])
-(SRLconst [c] (MOVDconst [d]))  => (MOVDconst [int64(uint64(d)>>uint64(c))])
-(SRAconst [c] (MOVDconst [d]))  => (MOVDconst [d>>uint64(c)])
-(MUL   (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [c*d])
-(MULW  (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [int64(int32(c)*int32(d))])
-(MNEG  (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [-c*d])
-(MNEGW (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [-int64(int32(c)*int32(d))])
-(MADD  (MOVDconst [c]) x y) => (ADDconst [c] (MUL   <x.Type> x y))
-(MADDW (MOVDconst [c]) x y) => (ADDconst [c] (MULW  <x.Type> x y))
-(MSUB  (MOVDconst [c]) x y) => (ADDconst [c] (MNEG  <x.Type> x y))
-(MSUBW (MOVDconst [c]) x y) => (ADDconst [c] (MNEGW <x.Type> x y))
-(MADD  a (MOVDconst [c]) (MOVDconst [d])) => (ADDconst [c*d] a)
-(MADDW a (MOVDconst [c]) (MOVDconst [d])) => (ADDconst [int64(int32(c)*int32(d))] a)
-(MSUB  a (MOVDconst [c]) (MOVDconst [d])) => (SUBconst [c*d] a)
-(MSUBW a (MOVDconst [c]) (MOVDconst [d])) => (SUBconst [int64(int32(c)*int32(d))] a)
-(DIV   (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [c/d])
-(UDIV  (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [int64(uint64(c)/uint64(d))])
-(DIVW  (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [int64(int32(c)/int32(d))])
-(UDIVW (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [int64(uint32(c)/uint32(d))])
-(MOD   (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [c%d])
-(UMOD  (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [int64(uint64(c)%uint64(d))])
-(MODW  (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [int64(int32(c)%int32(d))])
-(UMODW (MOVDconst [c]) (MOVDconst [d])) && d != 0 => (MOVDconst [int64(uint32(c)%uint32(d))])
-(ANDconst [c] (MOVDconst [d]))  => (MOVDconst [c&d])
-(ANDconst [c] (ANDconst [d] x)) => (ANDconst [c&d] x)
-(ANDconst [c] (MOVWUreg x)) => (ANDconst [c&(1<<32-1)] x)
-(ANDconst [c] (MOVHUreg x)) => (ANDconst [c&(1<<16-1)] x)
-(ANDconst [c] (MOVBUreg x)) => (ANDconst [c&(1<<8-1)] x)
-(MOVWUreg (ANDconst [c] x)) => (ANDconst [c&(1<<32-1)] x)
-(MOVHUreg (ANDconst [c] x)) => (ANDconst [c&(1<<16-1)] x)
-(MOVBUreg (ANDconst [c] x)) => (ANDconst [c&(1<<8-1)] x)
-(ORconst  [c] (MOVDconst [d]))  => (MOVDconst [c|d])
-(ORconst  [c] (ORconst [d] x))  => (ORconst [c|d] x)
-(XORconst [c] (MOVDconst [d]))  => (MOVDconst [c^d])
-(XORconst [c] (XORconst [d] x)) => (XORconst [c^d] x)
-(MVN (MOVDconst [c])) => (MOVDconst [^c])
-(NEG (MOVDconst [c])) => (MOVDconst [-c])
-(MOVBreg  (MOVDconst [c])) => (MOVDconst [int64(int8(c))])
-(MOVBUreg (MOVDconst [c])) => (MOVDconst [int64(uint8(c))])
-(MOVHreg  (MOVDconst [c])) => (MOVDconst [int64(int16(c))])
-(MOVHUreg (MOVDconst [c])) => (MOVDconst [int64(uint16(c))])
-(MOVWreg  (MOVDconst [c])) => (MOVDconst [int64(int32(c))])
-(MOVWUreg (MOVDconst [c])) => (MOVDconst [int64(uint32(c))])
-(MOVDreg  (MOVDconst [c])) => (MOVDconst [c])
-
-// constant comparisons
-(CMPconst  (MOVDconst [x]) [y]) => (FlagConstant [subFlags64(x,y)])
-(CMPWconst (MOVDconst [x]) [y]) => (FlagConstant [subFlags32(int32(x),y)])
-(TSTconst  (MOVDconst [x]) [y]) => (FlagConstant [logicFlags64(x&y)])
-(TSTWconst (MOVDconst [x]) [y]) => (FlagConstant [logicFlags32(int32(x)&y)])
-(CMNconst  (MOVDconst [x]) [y]) => (FlagConstant [addFlags64(x,y)])
-(CMNWconst (MOVDconst [x]) [y]) => (FlagConstant [addFlags32(int32(x),y)])
-
-// other known comparisons
-(CMPconst (MOVBUreg _) [c]) && 0xff < c => (FlagConstant [subFlags64(0,1)])
-(CMPconst (MOVHUreg _) [c]) && 0xffff < c => (FlagConstant [subFlags64(0,1)])
-(CMPconst (MOVWUreg _) [c]) && 0xffffffff < c => (FlagConstant [subFlags64(0,1)])
-(CMPconst (ANDconst _ [m]) [n]) && 0 <= m && m < n => (FlagConstant [subFlags64(0,1)])
-(CMPconst (SRLconst _ [c]) [n]) && 0 <= n && 0 < c && c <= 63 && (1<<uint64(64-c)) <= uint64(n) => (FlagConstant [subFlags64(0,1)])
-(CMPWconst (MOVBUreg _) [c]) && 0xff < c => (FlagConstant [subFlags64(0,1)])
-(CMPWconst (MOVHUreg _) [c]) && 0xffff < c => (FlagConstant [subFlags64(0,1)])
-
-// absorb flag constants into branches
-(EQ (FlagConstant [fc]) yes no) &&  fc.eq() => (First yes no)
-(EQ (FlagConstant [fc]) yes no) && !fc.eq() => (First no yes)
-
-(NE (FlagConstant [fc]) yes no) &&  fc.ne() => (First yes no)
-(NE (FlagConstant [fc]) yes no) && !fc.ne() => (First no yes)
-
-(LT (FlagConstant [fc]) yes no) &&  fc.lt() => (First yes no)
-(LT (FlagConstant [fc]) yes no) && !fc.lt() => (First no yes)
-
-(LE (FlagConstant [fc]) yes no) &&  fc.le() => (First yes no)
-(LE (FlagConstant [fc]) yes no) && !fc.le() => (First no yes)
-
-(GT (FlagConstant [fc]) yes no) &&  fc.gt() => (First yes no)
-(GT (FlagConstant [fc]) yes no) && !fc.gt() => (First no yes)
-
-(GE (FlagConstant [fc]) yes no) &&  fc.ge() => (First yes no)
-(GE (FlagConstant [fc]) yes no) && !fc.ge() => (First no yes)
-
-(ULT (FlagConstant [fc]) yes no) &&  fc.ult() => (First yes no)
-(ULT (FlagConstant [fc]) yes no) && !fc.ult() => (First no yes)
-
-(ULE (FlagConstant [fc]) yes no) &&  fc.ule() => (First yes no)
-(ULE (FlagConstant [fc]) yes no) && !fc.ule() => (First no yes)
-
-(UGT (FlagConstant [fc]) yes no) &&  fc.ugt() => (First yes no)
-(UGT (FlagConstant [fc]) yes no) && !fc.ugt() => (First no yes)
-
-(UGE (FlagConstant [fc]) yes no) &&  fc.uge() => (First yes no)
-(UGE (FlagConstant [fc]) yes no) && !fc.uge() => (First no yes)
-
-(LTnoov (FlagConstant [fc]) yes no) &&  fc.ltNoov() => (First yes no)
-(LTnoov (FlagConstant [fc]) yes no) && !fc.ltNoov() => (First no yes)
-
-(LEnoov (FlagConstant [fc]) yes no) &&  fc.leNoov() => (First yes no)
-(LEnoov (FlagConstant [fc]) yes no) && !fc.leNoov() => (First no yes)
-
-(GTnoov (FlagConstant [fc]) yes no) &&  fc.gtNoov() => (First yes no)
-(GTnoov (FlagConstant [fc]) yes no) && !fc.gtNoov() => (First no yes)
-
-(GEnoov (FlagConstant [fc]) yes no) &&  fc.geNoov() => (First yes no)
-(GEnoov (FlagConstant [fc]) yes no) && !fc.geNoov() => (First no yes)
-
-(Z (MOVDconst [0]) yes no) => (First yes no)
-(Z (MOVDconst [c]) yes no) && c != 0 => (First no yes)
-(NZ (MOVDconst [0]) yes no) => (First no yes)
-(NZ (MOVDconst [c]) yes no) && c != 0 => (First yes no)
-(ZW (MOVDconst [c]) yes no) && int32(c) == 0 => (First yes no)
-(ZW (MOVDconst [c]) yes no) && int32(c) != 0 => (First no yes)
-(NZW (MOVDconst [c]) yes no) && int32(c) == 0 => (First no yes)
-(NZW (MOVDconst [c]) yes no) && int32(c) != 0 => (First yes no)
-
-// absorb InvertFlags into branches
-(LT (InvertFlags cmp) yes no) => (GT cmp yes no)
-(GT (InvertFlags cmp) yes no) => (LT cmp yes no)
-(LE (InvertFlags cmp) yes no) => (GE cmp yes no)
-(GE (InvertFlags cmp) yes no) => (LE cmp yes no)
-(ULT (InvertFlags cmp) yes no) => (UGT cmp yes no)
-(UGT (InvertFlags cmp) yes no) => (ULT cmp yes no)
-(ULE (InvertFlags cmp) yes no) => (UGE cmp yes no)
-(UGE (InvertFlags cmp) yes no) => (ULE cmp yes no)
-(EQ (InvertFlags cmp) yes no) => (EQ cmp yes no)
-(NE (InvertFlags cmp) yes no) => (NE cmp yes no)
-(FLT (InvertFlags cmp) yes no) => (FGT cmp yes no)
-(FGT (InvertFlags cmp) yes no) => (FLT cmp yes no)
-(FLE (InvertFlags cmp) yes no) => (FGE cmp yes no)
-(FGE (InvertFlags cmp) yes no) => (FLE cmp yes no)
-(LTnoov (InvertFlags cmp) yes no) => (GTnoov cmp yes no)
-(GEnoov (InvertFlags cmp) yes no) => (LEnoov cmp yes no)
-(LEnoov (InvertFlags cmp) yes no) => (GEnoov cmp yes no)
-(GTnoov (InvertFlags cmp) yes no) => (LTnoov cmp yes no)
-
-// absorb InvertFlags into conditional instructions
-(CSEL [cc] x y (InvertFlags cmp)) => (CSEL [arm64Invert(cc)] x y cmp)
-(CSEL0 [cc] x (InvertFlags cmp)) => (CSEL0 [arm64Invert(cc)] x cmp)
-(CSETM [cc] (InvertFlags cmp)) => (CSETM [arm64Invert(cc)] cmp)
-(CSINC [cc] x y (InvertFlags cmp)) => (CSINC [arm64Invert(cc)] x y cmp)
-(CSINV [cc] x y (InvertFlags cmp)) => (CSINV [arm64Invert(cc)] x y cmp)
-(CSNEG [cc] x y (InvertFlags cmp)) => (CSNEG [arm64Invert(cc)] x y cmp)
-
-// absorb flag constants into boolean values
-(Equal (FlagConstant [fc])) => (MOVDconst [b2i(fc.eq())])
-(NotEqual (FlagConstant [fc])) => (MOVDconst [b2i(fc.ne())])
-(LessThan (FlagConstant [fc])) => (MOVDconst [b2i(fc.lt())])
-(LessThanU (FlagConstant [fc])) => (MOVDconst [b2i(fc.ult())])
-(LessEqual (FlagConstant [fc])) => (MOVDconst [b2i(fc.le())])
-(LessEqualU (FlagConstant [fc])) => (MOVDconst [b2i(fc.ule())])
-(GreaterThan (FlagConstant [fc])) => (MOVDconst [b2i(fc.gt())])
-(GreaterThanU (FlagConstant [fc])) => (MOVDconst [b2i(fc.ugt())])
-(GreaterEqual (FlagConstant [fc])) => (MOVDconst [b2i(fc.ge())])
-(GreaterEqualU (FlagConstant [fc])) => (MOVDconst [b2i(fc.uge())])
-
-// absorb InvertFlags into boolean values
-(Equal (InvertFlags x)) => (Equal x)
-(NotEqual (InvertFlags x)) => (NotEqual x)
-(LessThan (InvertFlags x)) => (GreaterThan x)
-(LessThanU (InvertFlags x)) => (GreaterThanU x)
-(GreaterThan (InvertFlags x)) => (LessThan x)
-(GreaterThanU (InvertFlags x)) => (LessThanU x)
-(LessEqual (InvertFlags x)) => (GreaterEqual x)
-(LessEqualU (InvertFlags x)) => (GreaterEqualU x)
-(GreaterEqual (InvertFlags x)) => (LessEqual x)
-(GreaterEqualU (InvertFlags x)) => (LessEqualU x)
-(LessThanF (InvertFlags x)) => (GreaterThanF x)
-(LessEqualF (InvertFlags x)) => (GreaterEqualF x)
-(GreaterThanF (InvertFlags x)) => (LessThanF x)
-(GreaterEqualF (InvertFlags x)) => (LessEqualF x)
-
-// Boolean-generating instructions (NOTE: NOT all boolean Values) always
-// zero upper bit of the register; no need to zero-extend
-(MOVBUreg x:((Equal|NotEqual|LessThan|LessThanU|LessThanF|LessEqual|LessEqualU|LessEqualF|GreaterThan|GreaterThanU|GreaterThanF|GreaterEqual|GreaterEqualU|GreaterEqualF) _)) => (MOVDreg x)
-
-// absorb flag constants into conditional instructions
-(CSEL [cc] x _ flag) && ccARM64Eval(cc, flag) > 0 => x
-(CSEL [cc] _ y flag) && ccARM64Eval(cc, flag) < 0 => y
-(CSEL0 [cc] x flag) && ccARM64Eval(cc, flag) > 0 => x
-(CSEL0 [cc] _ flag) && ccARM64Eval(cc, flag) < 0 => (MOVDconst [0])
-(CSNEG [cc] x _ flag) && ccARM64Eval(cc, flag) > 0 => x
-(CSNEG [cc] _ y flag) && ccARM64Eval(cc, flag) < 0 => (NEG y)
-(CSINV [cc] x _ flag) && ccARM64Eval(cc, flag) > 0 => x
-(CSINV [cc] _ y flag) && ccARM64Eval(cc, flag) < 0 => (Not y)
-(CSINC [cc] x _ flag) && ccARM64Eval(cc, flag) > 0 => x
-(CSINC [cc] _ y flag) && ccARM64Eval(cc, flag) < 0 => (ADDconst [1] y)
-(CSETM [cc] flag) && ccARM64Eval(cc, flag) > 0 => (MOVDconst [-1])
-(CSETM [cc] flag) && ccARM64Eval(cc, flag) < 0 => (MOVDconst [0])
-
-// absorb flags back into boolean CSEL
-(CSEL [cc] x y (CMPWconst [0] boolval)) && cc == OpARM64NotEqual && flagArg(boolval) != nil =>
-      (CSEL [boolval.Op] x y flagArg(boolval))
-(CSEL [cc] x y (CMPWconst [0] boolval)) && cc == OpARM64Equal && flagArg(boolval) != nil =>
-      (CSEL [arm64Negate(boolval.Op)] x y flagArg(boolval))
-(CSEL0 [cc] x (CMPWconst [0] boolval)) && cc == OpARM64NotEqual && flagArg(boolval) != nil =>
-      (CSEL0 [boolval.Op] x flagArg(boolval))
-(CSEL0 [cc] x (CMPWconst [0] boolval)) && cc == OpARM64Equal && flagArg(boolval) != nil =>
-      (CSEL0 [arm64Negate(boolval.Op)] x flagArg(boolval))
-
-// absorb shifts into ops
-(NEG x:(SLLconst [c] y)) && clobberIfDead(x) => (NEGshiftLL [c] y)
-(NEG x:(SRLconst [c] y)) && clobberIfDead(x) => (NEGshiftRL [c] y)
-(NEG x:(SRAconst [c] y)) && clobberIfDead(x) => (NEGshiftRA [c] y)
-(MVN x:(SLLconst [c] y)) && clobberIfDead(x) => (MVNshiftLL [c] y)
-(MVN x:(SRLconst [c] y)) && clobberIfDead(x) => (MVNshiftRL [c] y)
-(MVN x:(SRAconst [c] y)) && clobberIfDead(x) => (MVNshiftRA [c] y)
-(MVN x:(RORconst [c] y)) && clobberIfDead(x) => (MVNshiftRO [c] y)
-(ADD x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) => (ADDshiftLL x0 y [c])
-(ADD x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) => (ADDshiftRL x0 y [c])
-(ADD x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) => (ADDshiftRA x0 y [c])
-(SUB x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) => (SUBshiftLL x0 y [c])
-(SUB x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) => (SUBshiftRL x0 y [c])
-(SUB x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) => (SUBshiftRA x0 y [c])
-(AND x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) => (ANDshiftLL x0 y [c])
-(AND x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) => (ANDshiftRL x0 y [c])
-(AND x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) => (ANDshiftRA x0 y [c])
-(AND x0 x1:(RORconst [c] y)) && clobberIfDead(x1) => (ANDshiftRO x0 y [c])
-(OR  x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) => (ORshiftLL  x0 y [c]) // useful for combined load
-(OR  x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) => (ORshiftRL  x0 y [c])
-(OR  x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) => (ORshiftRA  x0 y [c])
-(OR  x0 x1:(RORconst [c] y)) && clobberIfDead(x1) => (ORshiftRO  x0 y [c])
-(XOR x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) => (XORshiftLL x0 y [c])
-(XOR x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) => (XORshiftRL x0 y [c])
-(XOR x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) => (XORshiftRA x0 y [c])
-(XOR x0 x1:(RORconst [c] y)) && clobberIfDead(x1) => (XORshiftRO x0 y [c])
-(BIC x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) => (BICshiftLL x0 y [c])
-(BIC x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) => (BICshiftRL x0 y [c])
-(BIC x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) => (BICshiftRA x0 y [c])
-(BIC x0 x1:(RORconst [c] y)) && clobberIfDead(x1) => (BICshiftRO x0 y [c])
-(ORN x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) => (ORNshiftLL x0 y [c])
-(ORN x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) => (ORNshiftRL x0 y [c])
-(ORN x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) => (ORNshiftRA x0 y [c])
-(ORN x0 x1:(RORconst [c] y)) && clobberIfDead(x1) => (ORNshiftRO x0 y [c])
-(EON x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) => (EONshiftLL x0 y [c])
-(EON x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) => (EONshiftRL x0 y [c])
-(EON x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) => (EONshiftRA x0 y [c])
-(EON x0 x1:(RORconst [c] y)) && clobberIfDead(x1) => (EONshiftRO x0 y [c])
-(CMP x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) => (CMPshiftLL x0 y [c])
-(CMP x0:(SLLconst [c] y) x1) && clobberIfDead(x0) => (InvertFlags (CMPshiftLL x1 y [c]))
-(CMP x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) => (CMPshiftRL x0 y [c])
-(CMP x0:(SRLconst [c] y) x1) && clobberIfDead(x0) => (InvertFlags (CMPshiftRL x1 y [c]))
-(CMP x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) => (CMPshiftRA x0 y [c])
-(CMP x0:(SRAconst [c] y) x1) && clobberIfDead(x0) => (InvertFlags (CMPshiftRA x1 y [c]))
-(CMN x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) => (CMNshiftLL x0 y [c])
-(CMN x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) => (CMNshiftRL x0 y [c])
-(CMN x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) => (CMNshiftRA x0 y [c])
-(TST x0 x1:(SLLconst [c] y)) && clobberIfDead(x1) => (TSTshiftLL x0 y [c])
-(TST x0 x1:(SRLconst [c] y)) && clobberIfDead(x1) => (TSTshiftRL x0 y [c])
-(TST x0 x1:(SRAconst [c] y)) && clobberIfDead(x1) => (TSTshiftRA x0 y [c])
-(TST x0 x1:(RORconst [c] y)) && clobberIfDead(x1) => (TSTshiftRO x0 y [c])
-
-// prefer *const ops to *shift ops
-(ADDshiftLL (MOVDconst [c]) x [d]) => (ADDconst [c] (SLLconst <x.Type> x [d]))
-(ADDshiftRL (MOVDconst [c]) x [d]) => (ADDconst [c] (SRLconst <x.Type> x [d]))
-(ADDshiftRA (MOVDconst [c]) x [d]) => (ADDconst [c] (SRAconst <x.Type> x [d]))
-(ANDshiftLL (MOVDconst [c]) x [d]) => (ANDconst [c] (SLLconst <x.Type> x [d]))
-(ANDshiftRL (MOVDconst [c]) x [d]) => (ANDconst [c] (SRLconst <x.Type> x [d]))
-(ANDshiftRA (MOVDconst [c]) x [d]) => (ANDconst [c] (SRAconst <x.Type> x [d]))
-(ANDshiftRO (MOVDconst [c]) x [d]) => (ANDconst [c] (RORconst <x.Type> x [d]))
-(ORshiftLL  (MOVDconst [c]) x [d]) => (ORconst  [c] (SLLconst <x.Type> x [d]))
-(ORshiftRL  (MOVDconst [c]) x [d]) => (ORconst  [c] (SRLconst <x.Type> x [d]))
-(ORshiftRA  (MOVDconst [c]) x [d]) => (ORconst  [c] (SRAconst <x.Type> x [d]))
-(ORshiftRO  (MOVDconst [c]) x [d]) => (ORconst  [c] (RORconst <x.Type> x [d]))
-(XORshiftLL (MOVDconst [c]) x [d]) => (XORconst [c] (SLLconst <x.Type> x [d]))
-(XORshiftRL (MOVDconst [c]) x [d]) => (XORconst [c] (SRLconst <x.Type> x [d]))
-(XORshiftRA (MOVDconst [c]) x [d]) => (XORconst [c] (SRAconst <x.Type> x [d]))
-(XORshiftRO (MOVDconst [c]) x [d]) => (XORconst [c] (RORconst <x.Type> x [d]))
-(CMPshiftLL (MOVDconst [c]) x [d]) => (InvertFlags (CMPconst [c] (SLLconst <x.Type> x [d])))
-(CMPshiftRL (MOVDconst [c]) x [d]) => (InvertFlags (CMPconst [c] (SRLconst <x.Type> x [d])))
-(CMPshiftRA (MOVDconst [c]) x [d]) => (InvertFlags (CMPconst [c] (SRAconst <x.Type> x [d])))
-(CMNshiftLL (MOVDconst [c]) x [d]) => (CMNconst [c] (SLLconst <x.Type> x [d]))
-(CMNshiftRL (MOVDconst [c]) x [d]) => (CMNconst [c] (SRLconst <x.Type> x [d]))
-(CMNshiftRA (MOVDconst [c]) x [d]) => (CMNconst [c] (SRAconst <x.Type> x [d]))
-(TSTshiftLL (MOVDconst [c]) x [d]) => (TSTconst [c] (SLLconst <x.Type> x [d]))
-(TSTshiftRL (MOVDconst [c]) x [d]) => (TSTconst [c] (SRLconst <x.Type> x [d]))
-(TSTshiftRA (MOVDconst [c]) x [d]) => (TSTconst [c] (SRAconst <x.Type> x [d]))
-(TSTshiftRO (MOVDconst [c]) x [d]) => (TSTconst [c] (RORconst <x.Type> x [d]))
-
-// constant folding in *shift ops
-(MVNshiftLL (MOVDconst [c]) [d]) => (MOVDconst [^int64(uint64(c)<<uint64(d))])
-(MVNshiftRL (MOVDconst [c]) [d]) => (MOVDconst [^int64(uint64(c)>>uint64(d))])
-(MVNshiftRA (MOVDconst [c]) [d]) => (MOVDconst [^(c>>uint64(d))])
-(MVNshiftRO (MOVDconst [c]) [d]) => (MOVDconst [^rotateRight64(c, d)])
-(NEGshiftLL (MOVDconst [c]) [d]) => (MOVDconst [-int64(uint64(c)<<uint64(d))])
-(NEGshiftRL (MOVDconst [c]) [d]) => (MOVDconst [-int64(uint64(c)>>uint64(d))])
-(NEGshiftRA (MOVDconst [c]) [d]) => (MOVDconst [-(c>>uint64(d))])
-(ADDshiftLL x (MOVDconst [c]) [d]) => (ADDconst x [int64(uint64(c)<<uint64(d))])
-(ADDshiftRL x (MOVDconst [c]) [d]) => (ADDconst x [int64(uint64(c)>>uint64(d))])
-(ADDshiftRA x (MOVDconst [c]) [d]) => (ADDconst x [c>>uint64(d)])
-(SUBshiftLL x (MOVDconst [c]) [d]) => (SUBconst x [int64(uint64(c)<<uint64(d))])
-(SUBshiftRL x (MOVDconst [c]) [d]) => (SUBconst x [int64(uint64(c)>>uint64(d))])
-(SUBshiftRA x (MOVDconst [c]) [d]) => (SUBconst x [c>>uint64(d)])
-(ANDshiftLL x (MOVDconst [c]) [d]) => (ANDconst x [int64(uint64(c)<<uint64(d))])
-(ANDshiftRL x (MOVDconst [c]) [d]) => (ANDconst x [int64(uint64(c)>>uint64(d))])
-(ANDshiftRA x (MOVDconst [c]) [d]) => (ANDconst x [c>>uint64(d)])
-(ANDshiftRO x (MOVDconst [c]) [d]) => (ANDconst x [rotateRight64(c, d)])
-(ORshiftLL  x (MOVDconst [c]) [d]) => (ORconst  x [int64(uint64(c)<<uint64(d))])
-(ORshiftRL  x (MOVDconst [c]) [d]) => (ORconst  x [int64(uint64(c)>>uint64(d))])
-(ORshiftRA  x (MOVDconst [c]) [d]) => (ORconst  x [c>>uint64(d)])
-(ORshiftRO  x (MOVDconst [c]) [d]) => (ORconst  x [rotateRight64(c, d)])
-(XORshiftLL x (MOVDconst [c]) [d]) => (XORconst x [int64(uint64(c)<<uint64(d))])
-(XORshiftRL x (MOVDconst [c]) [d]) => (XORconst x [int64(uint64(c)>>uint64(d))])
-(XORshiftRA x (MOVDconst [c]) [d]) => (XORconst x [c>>uint64(d)])
-(XORshiftRO x (MOVDconst [c]) [d]) => (XORconst x [rotateRight64(c, d)])
-(BICshiftLL x (MOVDconst [c]) [d]) => (ANDconst x [^int64(uint64(c)<<uint64(d))])
-(BICshiftRL x (MOVDconst [c]) [d]) => (ANDconst x [^int64(uint64(c)>>uint64(d))])
-(BICshiftRA x (MOVDconst [c]) [d]) => (ANDconst x [^(c>>uint64(d))])
-(BICshiftRO x (MOVDconst [c]) [d]) => (ANDconst x [^rotateRight64(c, d)])
-(ORNshiftLL x (MOVDconst [c]) [d]) => (ORconst  x [^int64(uint64(c)<<uint64(d))])
-(ORNshiftRL x (MOVDconst [c]) [d]) => (ORconst  x [^int64(uint64(c)>>uint64(d))])
-(ORNshiftRA x (MOVDconst [c]) [d]) => (ORconst  x [^(c>>uint64(d))])
-(ORNshiftRO x (MOVDconst [c]) [d]) => (ORconst  x [^rotateRight64(c, d)])
-(EONshiftLL x (MOVDconst [c]) [d]) => (XORconst x [^int64(uint64(c)<<uint64(d))])
-(EONshiftRL x (MOVDconst [c]) [d]) => (XORconst x [^int64(uint64(c)>>uint64(d))])
-(EONshiftRA x (MOVDconst [c]) [d]) => (XORconst x [^(c>>uint64(d))])
-(EONshiftRO x (MOVDconst [c]) [d]) => (XORconst x [^rotateRight64(c, d)])
-(CMPshiftLL x (MOVDconst [c]) [d]) => (CMPconst x [int64(uint64(c)<<uint64(d))])
-(CMPshiftRL x (MOVDconst [c]) [d]) => (CMPconst x [int64(uint64(c)>>uint64(d))])
-(CMPshiftRA x (MOVDconst [c]) [d]) => (CMPconst x [c>>uint64(d)])
-(CMNshiftLL x (MOVDconst [c]) [d]) => (CMNconst x [int64(uint64(c)<<uint64(d))])
-(CMNshiftRL x (MOVDconst [c]) [d]) => (CMNconst x [int64(uint64(c)>>uint64(d))])
-(CMNshiftRA x (MOVDconst [c]) [d]) => (CMNconst x [c>>uint64(d)])
-(TSTshiftLL x (MOVDconst [c]) [d]) => (TSTconst x [int64(uint64(c)<<uint64(d))])
-(TSTshiftRL x (MOVDconst [c]) [d]) => (TSTconst x [int64(uint64(c)>>uint64(d))])
-(TSTshiftRA x (MOVDconst [c]) [d]) => (TSTconst x [c>>uint64(d)])
-(TSTshiftRO x (MOVDconst [c]) [d]) => (TSTconst x [rotateRight64(c, d)])
-
-// simplification with *shift ops
-(SUBshiftLL (SLLconst x [c]) x [c]) => (MOVDconst [0])
-(SUBshiftRL (SRLconst x [c]) x [c]) => (MOVDconst [0])
-(SUBshiftRA (SRAconst x [c]) x [c]) => (MOVDconst [0])
-(ANDshiftLL y:(SLLconst x [c]) x [c]) => y
-(ANDshiftRL y:(SRLconst x [c]) x [c]) => y
-(ANDshiftRA y:(SRAconst x [c]) x [c]) => y
-(ANDshiftRO y:(RORconst x [c]) x [c]) => y
-(ORshiftLL  y:(SLLconst x [c]) x [c]) => y
-(ORshiftRL  y:(SRLconst x [c]) x [c]) => y
-(ORshiftRA  y:(SRAconst x [c]) x [c]) => y
-(ORshiftRO  y:(RORconst x [c]) x [c]) => y
-(XORshiftLL (SLLconst x [c]) x [c]) => (MOVDconst [0])
-(XORshiftRL (SRLconst x [c]) x [c]) => (MOVDconst [0])
-(XORshiftRA (SRAconst x [c]) x [c]) => (MOVDconst [0])
-(XORshiftRO (RORconst x [c]) x [c]) => (MOVDconst [0])
-(BICshiftLL (SLLconst x [c]) x [c]) => (MOVDconst [0])
-(BICshiftRL (SRLconst x [c]) x [c]) => (MOVDconst [0])
-(BICshiftRA (SRAconst x [c]) x [c]) => (MOVDconst [0])
-(BICshiftRO (RORconst x [c]) x [c]) => (MOVDconst [0])
-(EONshiftLL (SLLconst x [c]) x [c]) => (MOVDconst [-1])
-(EONshiftRL (SRLconst x [c]) x [c]) => (MOVDconst [-1])
-(EONshiftRA (SRAconst x [c]) x [c]) => (MOVDconst [-1])
-(EONshiftRO (RORconst x [c]) x [c]) => (MOVDconst [-1])
-(ORNshiftLL (SLLconst x [c]) x [c]) => (MOVDconst [-1])
-(ORNshiftRL (SRLconst x [c]) x [c]) => (MOVDconst [-1])
-(ORNshiftRA (SRAconst x [c]) x [c]) => (MOVDconst [-1])
-(ORNshiftRO (RORconst x [c]) x [c]) => (MOVDconst [-1])
-
-// Generate rotates with const shift
-(ADDshiftLL [c] (SRLconst x [64-c]) x) => (RORconst [64-c] x)
-( ORshiftLL [c] (SRLconst x [64-c]) x) => (RORconst [64-c] x)
-(XORshiftLL [c] (SRLconst x [64-c]) x) => (RORconst [64-c] x)
-(ADDshiftRL [c] (SLLconst x [64-c]) x) => (RORconst [   c] x)
-( ORshiftRL [c] (SLLconst x [64-c]) x) => (RORconst [   c] x)
-(XORshiftRL [c] (SLLconst x [64-c]) x) => (RORconst [   c] x)
-
-(ADDshiftLL <t> [c] (UBFX [bfc] x) x) && c < 32 && t.Size() == 4 && bfc == armBFAuxInt(32-c, c)
-	=> (RORWconst [32-c] x)
-( ORshiftLL <t> [c] (UBFX [bfc] x) x) && c < 32 && t.Size() == 4 && bfc == armBFAuxInt(32-c, c)
-	=> (RORWconst [32-c] x)
-(XORshiftLL <t> [c] (UBFX [bfc] x) x) && c < 32 && t.Size() == 4 && bfc == armBFAuxInt(32-c, c)
-	=> (RORWconst [32-c] x)
-(ADDshiftRL <t> [c] (SLLconst x [32-c]) (MOVWUreg x)) && c < 32 && t.Size() == 4 => (RORWconst [c] x)
-( ORshiftRL <t> [c] (SLLconst x [32-c]) (MOVWUreg x)) && c < 32 && t.Size() == 4 => (RORWconst [c] x)
-(XORshiftRL <t> [c] (SLLconst x [32-c]) (MOVWUreg x)) && c < 32 && t.Size() == 4 => (RORWconst [c] x)
-
-(RORconst [c] (RORconst [d] x)) => (RORconst [(c+d)&63] x)
-(RORWconst [c] (RORWconst [d] x)) => (RORWconst [(c+d)&31] x)
-
-// Generate rotates with non-const shift.
-// These rules match the Go source code like
-//	y &= 63
-//	x << y | x >> (64-y)
-// "|" can also be "^" or "+".
-// As arm64 does not have a ROL instruction, so ROL(x, y) is replaced by ROR(x, -y).
-((ADD|OR|XOR) (SLL x (ANDconst <t> [63] y))
-	(CSEL0 <typ.UInt64> [cc] (SRL <typ.UInt64> x (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y)))
-		(CMPconst [64] (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y))))) && cc == OpARM64LessThanU
-	=> (ROR x (NEG <t> y))
-((ADD|OR|XOR) (SRL <typ.UInt64> x (ANDconst <t> [63] y))
-	(CSEL0 <typ.UInt64> [cc] (SLL x (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y)))
-		(CMPconst [64] (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y))))) && cc == OpARM64LessThanU
-	=> (ROR x y)
-
-// These rules match the Go source code like
-//	y &= 31
-//	x << y | x >> (32-y)
-// "|" can also be "^" or "+".
-// As arm64 does not have a ROLW instruction, so ROLW(x, y) is replaced by RORW(x, -y).
-((ADD|OR|XOR) (SLL x (ANDconst <t> [31] y))
-	(CSEL0 <typ.UInt32> [cc] (SRL <typ.UInt32> (MOVWUreg x) (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y)))
-		(CMPconst [64]  (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y))))) && cc == OpARM64LessThanU
-	=> (RORW x (NEG <t> y))
-((ADD|OR|XOR) (SRL <typ.UInt32> (MOVWUreg x) (ANDconst <t> [31] y))
-	(CSEL0 <typ.UInt32> [cc] (SLL x (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y)))
-		(CMPconst [64]  (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y))))) && cc == OpARM64LessThanU
-	=> (RORW x y)
-
-// rev16w | rev16
-// ((x>>8) | (x<<8)) => (REV16W x), the type of x is uint16, "|" can also be "^" or "+".
-((ADDshiftLL|ORshiftLL|XORshiftLL) <typ.UInt16> [8] (UBFX <typ.UInt16> [armBFAuxInt(8, 8)] x) x) => (REV16W x)
-
-// ((x & 0xff00ff00)>>8) | ((x & 0x00ff00ff)<<8), "|" can also be "^" or "+".
-((ADDshiftLL|ORshiftLL|XORshiftLL) [8] (UBFX [armBFAuxInt(8, 24)] (ANDconst [c1] x)) (ANDconst [c2] x))
-	&& uint32(c1) == 0xff00ff00 && uint32(c2) == 0x00ff00ff
-	=> (REV16W x)
-
-// ((x & 0xff00ff00ff00ff00)>>8) | ((x & 0x00ff00ff00ff00ff)<<8), "|" can also be "^" or "+".
-((ADDshiftLL|ORshiftLL|XORshiftLL) [8] (SRLconst [8] (ANDconst [c1] x)) (ANDconst [c2] x))
-	&& (uint64(c1) == 0xff00ff00ff00ff00 && uint64(c2) == 0x00ff00ff00ff00ff)
-	=> (REV16 x)
-
-// ((x & 0xff00ff00)>>8) | ((x & 0x00ff00ff)<<8), "|" can also be "^" or "+".
-((ADDshiftLL|ORshiftLL|XORshiftLL) [8] (SRLconst [8] (ANDconst [c1] x)) (ANDconst [c2] x))
-	&& (uint64(c1) == 0xff00ff00 && uint64(c2) == 0x00ff00ff)
-	=> (REV16 (ANDconst <x.Type> [0xffffffff] x))
-
-// Extract from reg pair
-(ADDshiftLL [c] (SRLconst x [64-c]) x2) => (EXTRconst [64-c] x2 x)
-( ORshiftLL [c] (SRLconst x [64-c]) x2) => (EXTRconst [64-c] x2 x)
-(XORshiftLL [c] (SRLconst x [64-c]) x2) => (EXTRconst [64-c] x2 x)
-
-(ADDshiftLL <t> [c] (UBFX [bfc] x) x2) && c < 32 && t.Size() == 4 && bfc == armBFAuxInt(32-c, c)
-	=> (EXTRWconst [32-c] x2 x)
-( ORshiftLL <t> [c] (UBFX [bfc] x) x2) && c < 32 && t.Size() == 4 && bfc == armBFAuxInt(32-c, c)
-	=> (EXTRWconst [32-c] x2 x)
-(XORshiftLL <t> [c] (UBFX [bfc] x) x2) && c < 32 && t.Size() == 4 && bfc == armBFAuxInt(32-c, c)
-	=> (EXTRWconst [32-c] x2 x)
-
-// Rewrite special pairs of shifts to AND.
-// On ARM64 the bitmask can fit into an instruction.
-(SRLconst [c] (SLLconst [c] x)) && 0 < c && c < 64 => (ANDconst [1<<uint(64-c)-1] x) // mask out high bits
-(SLLconst [c] (SRLconst [c] x)) && 0 < c && c < 64 => (ANDconst [^(1<<uint(c)-1)] x) // mask out low bits
-
-// Special case setting bit as 1. An example is math.Copysign(c,-1)
-(ORconst [c1] (ANDconst [c2] x)) && c2|c1 == ^0  => (ORconst [c1] x)
-
-// If the shift amount is larger than the datasize(32, 16, 8), we can optimize to constant 0.
-(MOVWUreg (SLLconst [lc] x)) && lc >= 32 => (MOVDconst [0])
-(MOVHUreg (SLLconst [lc] x)) && lc >= 16 => (MOVDconst [0])
-(MOVBUreg (SLLconst [lc] x)) && lc >= 8 => (MOVDconst [0])
-
-// After zero extension, the upper (64-datasize(32|16|8)) bits are zero, we can optimiza to constant 0.
-(SRLconst [rc] (MOVWUreg x)) && rc >= 32 => (MOVDconst [0])
-(SRLconst [rc] (MOVHUreg x)) && rc >= 16 => (MOVDconst [0])
-(SRLconst [rc] (MOVBUreg x)) && rc >= 8 => (MOVDconst [0])
-
-// bitfield ops
-
-// sbfiz
-// (x << lc) >> rc
-(SRAconst [rc] (SLLconst [lc] x)) && lc > rc => (SBFIZ [armBFAuxInt(lc-rc, 64-lc)] x)
-// int64(x << lc)
-(MOVWreg (SLLconst [lc] x)) && lc < 32 => (SBFIZ [armBFAuxInt(lc, 32-lc)] x)
-(MOVHreg (SLLconst [lc] x)) && lc < 16 => (SBFIZ [armBFAuxInt(lc, 16-lc)] x)
-(MOVBreg (SLLconst [lc] x)) && lc < 8 => (SBFIZ [armBFAuxInt(lc, 8-lc)] x)
-// int64(x) << lc
-(SLLconst [lc] (MOVWreg x))  => (SBFIZ [armBFAuxInt(lc, min(32, 64-lc))] x)
-(SLLconst [lc] (MOVHreg x))  => (SBFIZ [armBFAuxInt(lc, min(16, 64-lc))] x)
-(SLLconst [lc] (MOVBreg x))  => (SBFIZ [armBFAuxInt(lc, min(8, 64-lc))] x)
-
-// sbfx
-// (x << lc) >> rc
-(SRAconst [rc] (SLLconst [lc] x)) && lc <= rc => (SBFX [armBFAuxInt(rc-lc, 64-rc)] x)
-// int64(x) >> rc
-(SRAconst [rc] (MOVWreg x)) && rc < 32 => (SBFX [armBFAuxInt(rc, 32-rc)] x)
-(SRAconst [rc] (MOVHreg x)) && rc < 16 => (SBFX [armBFAuxInt(rc, 16-rc)] x)
-(SRAconst [rc] (MOVBreg x)) && rc < 8 => (SBFX [armBFAuxInt(rc, 8-rc)] x)
-// merge sbfx and sign-extension into sbfx
-(MOVWreg (SBFX [bfc] x)) && bfc.getARM64BFwidth() <= 32 => (SBFX [bfc] x)
-(MOVHreg (SBFX [bfc] x)) && bfc.getARM64BFwidth() <= 16 => (SBFX [bfc] x)
-(MOVBreg (SBFX [bfc] x)) && bfc.getARM64BFwidth() <=  8 => (SBFX [bfc] x)
-
-// sbfiz/sbfx combinations: merge shifts into bitfield ops
-(SRAconst [sc] (SBFIZ [bfc] x)) && sc < bfc.getARM64BFlsb()
-	=> (SBFIZ [armBFAuxInt(bfc.getARM64BFlsb()-sc, bfc.getARM64BFwidth())] x)
-(SRAconst [sc] (SBFIZ [bfc] x)) && sc >= bfc.getARM64BFlsb()
-	&& sc < bfc.getARM64BFlsb()+bfc.getARM64BFwidth()
-	=> (SBFX [armBFAuxInt(sc-bfc.getARM64BFlsb(), bfc.getARM64BFlsb()+bfc.getARM64BFwidth()-sc)] x)
-
-// ubfiz
-// (x << lc) >> rc
-(SRLconst [rc] (SLLconst [lc] x)) && lc > rc => (UBFIZ [armBFAuxInt(lc-rc, 64-lc)] x)
-// uint64(x) << lc
-(SLLconst [lc] (MOVWUreg x))  => (UBFIZ [armBFAuxInt(lc, min(32, 64-lc))] x)
-(SLLconst [lc] (MOVHUreg x))  => (UBFIZ [armBFAuxInt(lc, min(16, 64-lc))] x)
-(SLLconst [lc] (MOVBUreg x))  => (UBFIZ [armBFAuxInt(lc, min(8, 64-lc))] x)
-// uint64(x << lc)
-(MOVWUreg (SLLconst [lc] x)) && lc < 32 => (UBFIZ [armBFAuxInt(lc, 32-lc)] x)
-(MOVHUreg (SLLconst [lc] x)) && lc < 16 => (UBFIZ [armBFAuxInt(lc, 16-lc)] x)
-(MOVBUreg (SLLconst [lc] x)) && lc < 8 => (UBFIZ [armBFAuxInt(lc, 8-lc)] x)
-
-// merge ANDconst into ubfiz
-// (x & ac) << sc
-(SLLconst [sc] (ANDconst [ac] x)) && isARM64BFMask(sc, ac, 0)
-	=> (UBFIZ [armBFAuxInt(sc, arm64BFWidth(ac, 0))] x)
-// (x << sc) & ac
-(ANDconst [ac] (SLLconst [sc] x)) && isARM64BFMask(sc, ac, sc)
-	=> (UBFIZ [armBFAuxInt(sc, arm64BFWidth(ac, sc))] x)
-
-// ubfx
-// (x << lc) >> rc
-(SRLconst [rc] (SLLconst [lc] x)) && lc < rc => (UBFX [armBFAuxInt(rc-lc, 64-rc)] x)
-// uint64(x) >> rc
-(SRLconst [rc] (MOVWUreg x)) && rc < 32 => (UBFX [armBFAuxInt(rc, 32-rc)] x)
-(SRLconst [rc] (MOVHUreg x)) && rc < 16 => (UBFX [armBFAuxInt(rc, 16-rc)] x)
-(SRLconst [rc] (MOVBUreg x)) && rc < 8 => (UBFX [armBFAuxInt(rc, 8-rc)] x)
-// uint64(x >> rc)
-(MOVWUreg (SRLconst [rc] x)) && rc < 32 => (UBFX [armBFAuxInt(rc, 32)] x)
-(MOVHUreg (SRLconst [rc] x)) && rc < 16 => (UBFX [armBFAuxInt(rc, 16)] x)
-(MOVBUreg (SRLconst [rc] x)) && rc < 8 => (UBFX [armBFAuxInt(rc, 8)] x)
-// merge ANDconst into ubfx
-// (x >> sc) & ac
-(ANDconst [ac] (SRLconst [sc] x)) && isARM64BFMask(sc, ac, 0)
-	=> (UBFX [armBFAuxInt(sc, arm64BFWidth(ac, 0))] x)
-// (x & ac) >> sc
-(SRLconst [sc] (ANDconst [ac] x)) && isARM64BFMask(sc, ac, sc)
-	=> (UBFX [armBFAuxInt(sc, arm64BFWidth(ac, sc))] x)
-// merge ANDconst and ubfx into ubfx
-(ANDconst [c] (UBFX [bfc] x)) && isARM64BFMask(0, c, 0) =>
-	(UBFX [armBFAuxInt(bfc.getARM64BFlsb(), min(bfc.getARM64BFwidth(), arm64BFWidth(c, 0)))] x)
-(UBFX [bfc] (ANDconst [c] x)) && isARM64BFMask(0, c, 0) && bfc.getARM64BFlsb() + bfc.getARM64BFwidth() <= arm64BFWidth(c, 0) =>
-	(UBFX [bfc] x)
-// merge ubfx and zerso-extension into ubfx
-(MOVWUreg (UBFX [bfc] x)) && bfc.getARM64BFwidth() <= 32 => (UBFX [bfc] x)
-(MOVHUreg (UBFX [bfc] x)) && bfc.getARM64BFwidth() <= 16 => (UBFX [bfc] x)
-(MOVBUreg (UBFX [bfc] x)) && bfc.getARM64BFwidth() <=  8 => (UBFX [bfc] x)
-
-// ubfiz/ubfx combinations: merge shifts into bitfield ops
-(SRLconst [sc] (UBFX [bfc] x)) && sc < bfc.getARM64BFwidth()
-	=> (UBFX [armBFAuxInt(bfc.getARM64BFlsb()+sc, bfc.getARM64BFwidth()-sc)] x)
-(UBFX [bfc] (SRLconst [sc] x)) && sc+bfc.getARM64BFwidth()+bfc.getARM64BFlsb() < 64
-	=> (UBFX [armBFAuxInt(bfc.getARM64BFlsb()+sc, bfc.getARM64BFwidth())] x)
-(SLLconst [sc] (UBFIZ [bfc] x)) && sc+bfc.getARM64BFwidth()+bfc.getARM64BFlsb() < 64
-	=> (UBFIZ [armBFAuxInt(bfc.getARM64BFlsb()+sc, bfc.getARM64BFwidth())] x)
-(UBFIZ [bfc] (SLLconst [sc] x)) && sc < bfc.getARM64BFwidth()
-	=> (UBFIZ [armBFAuxInt(bfc.getARM64BFlsb()+sc, bfc.getARM64BFwidth()-sc)] x)
-// ((x << c1) >> c2) >> c3
-(SRLconst [sc] (UBFIZ [bfc] x)) && sc == bfc.getARM64BFlsb()
-	=> (ANDconst [1<<uint(bfc.getARM64BFwidth())-1] x)
-(SRLconst [sc] (UBFIZ [bfc] x)) && sc < bfc.getARM64BFlsb()
-	=> (UBFIZ [armBFAuxInt(bfc.getARM64BFlsb()-sc, bfc.getARM64BFwidth())] x)
-(SRLconst [sc] (UBFIZ [bfc] x)) && sc > bfc.getARM64BFlsb()
-	&& sc < bfc.getARM64BFlsb()+bfc.getARM64BFwidth()
-	=> (UBFX [armBFAuxInt(sc-bfc.getARM64BFlsb(), bfc.getARM64BFlsb()+bfc.getARM64BFwidth()-sc)] x)
-// ((x << c1) << c2) >> c3
-(UBFX [bfc] (SLLconst [sc] x)) && sc == bfc.getARM64BFlsb()
-	=> (ANDconst [1<<uint(bfc.getARM64BFwidth())-1] x)
-(UBFX [bfc] (SLLconst [sc] x)) && sc < bfc.getARM64BFlsb()
-	=> (UBFX [armBFAuxInt(bfc.getARM64BFlsb()-sc, bfc.getARM64BFwidth())] x)
-(UBFX [bfc] (SLLconst [sc] x)) && sc > bfc.getARM64BFlsb()
-	&& sc < bfc.getARM64BFlsb()+bfc.getARM64BFwidth()
-	=> (UBFIZ [armBFAuxInt(sc-bfc.getARM64BFlsb(), bfc.getARM64BFlsb()+bfc.getARM64BFwidth()-sc)] x)
-
-// bfi
-(OR (UBFIZ [bfc] x) (ANDconst [ac] y))
-	&& ac == ^((1<<uint(bfc.getARM64BFwidth())-1) << uint(bfc.getARM64BFlsb()))
-	=> (BFI [bfc] y x)
-(ORshiftRL [rc] (ANDconst [ac] x) (SLLconst [lc] y))
-	&& lc > rc && ac == ^((1<<uint(64-lc)-1) << uint64(lc-rc))
-	=> (BFI [armBFAuxInt(lc-rc, 64-lc)] x y)
-// bfxil
-(OR (UBFX [bfc] x) (ANDconst [ac] y)) && ac == ^(1<<uint(bfc.getARM64BFwidth())-1)
-	=> (BFXIL [bfc] y x)
-(ORshiftLL [sc] (UBFX [bfc] x) (SRLconst [sc] y)) && sc == bfc.getARM64BFwidth()
-	=> (BFXIL [bfc] y x)
-(ORshiftRL [rc] (ANDconst [ac] y) (SLLconst [lc] x)) && lc < rc && ac == ^((1<<uint(64-rc)-1))
-	=> (BFXIL [armBFAuxInt(rc-lc, 64-rc)] y x)
-
-// do combined loads
-// little endian loads
-// b[0] | b[1]<<8 => load 16-bit
-(ORshiftLL <t> [8]
-	y0:(MOVDnop x0:(MOVBUload [i0] {s} p mem))
-	y1:(MOVDnop x1:(MOVBUload [i1] {s} p mem)))
-	&& i1 == i0+1
-	&& x0.Uses == 1 && x1.Uses == 1
-	&& y0.Uses == 1 && y1.Uses == 1
-	&& mergePoint(b,x0,x1) != nil
-	&& clobber(x0, x1, y0, y1)
-	=> @mergePoint(b,x0,x1) (MOVHUload <t> {s} (OffPtr <p.Type> [int64(i0)] p) mem)
-(ORshiftLL <t> [8]
-	y0:(MOVDnop x0:(MOVBUloadidx ptr0 idx0 mem))
-	y1:(MOVDnop x1:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem)))
-	&& s == nil
-	&& x0.Uses == 1 && x1.Uses == 1
-	&& y0.Uses == 1 && y1.Uses == 1
-	&& mergePoint(b,x0,x1) != nil
-	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
-	&& clobber(x0, x1, y0, y1)
-	=> @mergePoint(b,x0,x1) (MOVHUloadidx <t> ptr0 idx0 mem)
-(ORshiftLL <t> [8]
-	y0:(MOVDnop x0:(MOVBUloadidx ptr idx mem))
-	y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [1] idx) mem)))
-	&& x0.Uses == 1 && x1.Uses == 1
-	&& y0.Uses == 1 && y1.Uses == 1
-	&& mergePoint(b,x0,x1) != nil
-	&& clobber(x0, x1, y0, y1)
-	=> @mergePoint(b,x0,x1) (MOVHUloadidx <t> ptr idx mem)
-
-// b[0] | b[1]<<8 | b[2]<<16 | b[3]<<24 => load 32-bit
-(ORshiftLL <t> [24] o0:(ORshiftLL [16]
-	            x0:(MOVHUload [i0] {s} p mem)
-	y1:(MOVDnop x1:(MOVBUload [i2] {s} p mem)))
-	y2:(MOVDnop x2:(MOVBUload [i3] {s} p mem)))
-	&& i2 == i0+2
-	&& i3 == i0+3
-	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1
-	&& y1.Uses == 1 && y2.Uses == 1
-	&& o0.Uses == 1
-	&& mergePoint(b,x0,x1,x2) != nil
-	&& clobber(x0, x1, x2, y1, y2, o0)
-	=> @mergePoint(b,x0,x1,x2) (MOVWUload <t> {s} (OffPtr <p.Type> [int64(i0)] p) mem)
-(ORshiftLL <t> [24] o0:(ORshiftLL [16]
-	            x0:(MOVHUloadidx ptr0 idx0 mem)
-	y1:(MOVDnop x1:(MOVBUload [2] {s} p1:(ADD ptr1 idx1) mem)))
-	y2:(MOVDnop x2:(MOVBUload [3] {s} p mem)))
-	&& s == nil
-	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1
-	&& y1.Uses == 1 && y2.Uses == 1
-	&& o0.Uses == 1
-	&& mergePoint(b,x0,x1,x2) != nil
-	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
-	&& isSamePtr(p1, p)
-	&& clobber(x0, x1, x2, y1, y2, o0)
-	=> @mergePoint(b,x0,x1,x2) (MOVWUloadidx <t> ptr0 idx0 mem)
-(ORshiftLL <t> [24] o0:(ORshiftLL [16]
-	            x0:(MOVHUloadidx ptr idx mem)
-	y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [2] idx) mem)))
-	y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [3] idx) mem)))
-	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1
-	&& y1.Uses == 1 && y2.Uses == 1
-	&& o0.Uses == 1
-	&& mergePoint(b,x0,x1,x2) != nil
-	&& clobber(x0, x1, x2, y1, y2, o0)
-	=> @mergePoint(b,x0,x1,x2) (MOVWUloadidx <t> ptr idx mem)
-(ORshiftLL <t> [24] o0:(ORshiftLL [16]
-	            x0:(MOVHUloadidx2 ptr0 idx0 mem)
-	y1:(MOVDnop x1:(MOVBUload [2] {s} p1:(ADDshiftLL [1] ptr1 idx1) mem)))
-	y2:(MOVDnop x2:(MOVBUload [3] {s} p mem)))
-	&& s == nil
-	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1
-	&& y1.Uses == 1 && y2.Uses == 1
-	&& o0.Uses == 1
-	&& mergePoint(b,x0,x1,x2) != nil
-	&& isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1)
-	&& isSamePtr(p1, p)
-	&& clobber(x0, x1, x2, y1, y2, o0)
-	=> @mergePoint(b,x0,x1,x2) (MOVWUloadidx <t> ptr0 (SLLconst <idx0.Type> [1] idx0) mem)
-
-// b[0] | b[1]<<8 | b[2]<<16 | b[3]<<24 | b[4]<<32 | b[5]<<40 | b[6]<<48 | b[7]<<56 => load 64-bit
-(ORshiftLL <t> [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32]
-	            x0:(MOVWUload [i0] {s} p mem)
-	y1:(MOVDnop x1:(MOVBUload [i4] {s} p mem)))
-	y2:(MOVDnop x2:(MOVBUload [i5] {s} p mem)))
-	y3:(MOVDnop x3:(MOVBUload [i6] {s} p mem)))
-	y4:(MOVDnop x4:(MOVBUload [i7] {s} p mem)))
-	&& i4 == i0+4
-	&& i5 == i0+5
-	&& i6 == i0+6
-	&& i7 == i0+7
-	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1
-	&& y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1
-	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1
-	&& mergePoint(b,x0,x1,x2,x3,x4) != nil
-	&& clobber(x0, x1, x2, x3, x4, y1, y2, y3, y4, o0, o1, o2)
-	=> @mergePoint(b,x0,x1,x2,x3,x4) (MOVDload <t> {s} (OffPtr <p.Type> [int64(i0)] p) mem)
-(ORshiftLL <t> [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32]
-	            x0:(MOVWUloadidx ptr0 idx0 mem)
-	y1:(MOVDnop x1:(MOVBUload [4] {s} p1:(ADD ptr1 idx1) mem)))
-	y2:(MOVDnop x2:(MOVBUload [5] {s} p mem)))
-	y3:(MOVDnop x3:(MOVBUload [6] {s} p mem)))
-	y4:(MOVDnop x4:(MOVBUload [7] {s} p mem)))
-	&& s == nil
-	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1
-	&& y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1
-	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1
-	&& mergePoint(b,x0,x1,x2,x3,x4) != nil
-	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
-	&& isSamePtr(p1, p)
-	&& clobber(x0, x1, x2, x3, x4, y1, y2, y3, y4, o0, o1, o2)
-	=> @mergePoint(b,x0,x1,x2,x3,x4) (MOVDloadidx <t> ptr0 idx0 mem)
-(ORshiftLL <t> [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32]
-	            x0:(MOVWUloadidx4 ptr0 idx0 mem)
-	y1:(MOVDnop x1:(MOVBUload [4] {s} p1:(ADDshiftLL [2] ptr1 idx1) mem)))
-	y2:(MOVDnop x2:(MOVBUload [5] {s} p mem)))
-	y3:(MOVDnop x3:(MOVBUload [6] {s} p mem)))
-	y4:(MOVDnop x4:(MOVBUload [7] {s} p mem)))
-	&& s == nil
-	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1
-	&& y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1
-	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1
-	&& mergePoint(b,x0,x1,x2,x3,x4) != nil
-	&& isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1)
-	&& isSamePtr(p1, p)
-	&& clobber(x0, x1, x2, x3, x4, y1, y2, y3, y4, o0, o1, o2)
-	=> @mergePoint(b,x0,x1,x2,x3,x4) (MOVDloadidx <t> ptr0 (SLLconst <idx0.Type> [2] idx0) mem)
-(ORshiftLL <t> [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32]
-	            x0:(MOVWUloadidx ptr idx mem)
-	y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [4] idx) mem)))
-	y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [5] idx) mem)))
-	y3:(MOVDnop x3:(MOVBUloadidx ptr (ADDconst [6] idx) mem)))
-	y4:(MOVDnop x4:(MOVBUloadidx ptr (ADDconst [7] idx) mem)))
-	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1
-	&& y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1
-	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1
-	&& mergePoint(b,x0,x1,x2,x3,x4) != nil
-	&& clobber(x0, x1, x2, x3, x4, y1, y2, y3, y4, o0, o1, o2)
-	=> @mergePoint(b,x0,x1,x2,x3,x4) (MOVDloadidx <t> ptr idx mem)
-
-// b[3]<<24 | b[2]<<16 | b[1]<<8 | b[0] => load 32-bit
-(OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24]
-	y0:(MOVDnop x0:(MOVBUload [i3] {s} p mem)))
-	y1:(MOVDnop x1:(MOVBUload [i2] {s} p mem)))
-	y2:(MOVDnop x2:(MOVBUload [i1] {s} p mem)))
-	y3:(MOVDnop x3:(MOVBUload [i0] {s} p mem)))
-	&& i1 == i0+1
-	&& i2 == i0+2
-	&& i3 == i0+3
-	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
-	&& y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1
-	&& o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1
-	&& mergePoint(b,x0,x1,x2,x3) != nil
-	&& clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)
-	=> @mergePoint(b,x0,x1,x2,x3) (MOVWUload <t> {s} (OffPtr <p.Type> [int64(i0)] p) mem)
-(OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24]
-	y0:(MOVDnop x0:(MOVBUload [3] {s} p mem)))
-	y1:(MOVDnop x1:(MOVBUload [2] {s} p mem)))
-	y2:(MOVDnop x2:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem)))
-	y3:(MOVDnop x3:(MOVBUloadidx ptr0 idx0 mem)))
-	&& s == nil
-	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
-	&& y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1
-	&& o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1
-	&& mergePoint(b,x0,x1,x2,x3) != nil
-	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
-	&& isSamePtr(p1, p)
-	&& clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)
-	=> @mergePoint(b,x0,x1,x2,x3) (MOVWUloadidx <t> ptr0 idx0 mem)
-(OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24]
-	y0:(MOVDnop x0:(MOVBUloadidx ptr (ADDconst [3] idx) mem)))
-	y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [2] idx) mem)))
-	y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [1] idx) mem)))
-	y3:(MOVDnop x3:(MOVBUloadidx ptr idx mem)))
-	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
-	&& y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1
-	&& o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1
-	&& mergePoint(b,x0,x1,x2,x3) != nil
-	&& clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)
-	=> @mergePoint(b,x0,x1,x2,x3) (MOVWUloadidx <t> ptr idx mem)
-
-// b[7]<<56 | b[6]<<48 | b[5]<<40 | b[4]<<32 | b[3]<<24 | b[2]<<16 | b[1]<<8 | b[0] => load 64-bit
-(OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56]
-	y0:(MOVDnop x0:(MOVBUload [i7] {s} p mem)))
-	y1:(MOVDnop x1:(MOVBUload [i6] {s} p mem)))
-	y2:(MOVDnop x2:(MOVBUload [i5] {s} p mem)))
-	y3:(MOVDnop x3:(MOVBUload [i4] {s} p mem)))
-	y4:(MOVDnop x4:(MOVBUload [i3] {s} p mem)))
-	y5:(MOVDnop x5:(MOVBUload [i2] {s} p mem)))
-	y6:(MOVDnop x6:(MOVBUload [i1] {s} p mem)))
-	y7:(MOVDnop x7:(MOVBUload [i0] {s} p mem)))
-	&& i1 == i0+1
-	&& i2 == i0+2
-	&& i3 == i0+3
-	&& i4 == i0+4
-	&& i5 == i0+5
-	&& i6 == i0+6
-	&& i7 == i0+7
-	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
-	&& x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1
-	&& y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1
-	&& y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1
-	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1
-	&& o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1
-	&& mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil
-	&& clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)
-	=> @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDload <t> {s} (OffPtr <p.Type> [int64(i0)] p) mem)
-(OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56]
-	y0:(MOVDnop x0:(MOVBUload [7] {s} p mem)))
-	y1:(MOVDnop x1:(MOVBUload [6] {s} p mem)))
-	y2:(MOVDnop x2:(MOVBUload [5] {s} p mem)))
-	y3:(MOVDnop x3:(MOVBUload [4] {s} p mem)))
-	y4:(MOVDnop x4:(MOVBUload [3] {s} p mem)))
-	y5:(MOVDnop x5:(MOVBUload [2] {s} p mem)))
-	y6:(MOVDnop x6:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem)))
-	y7:(MOVDnop x7:(MOVBUloadidx ptr0 idx0 mem)))
-	&& s == nil
-	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
-	&& x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1
-	&& y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1
-	&& y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1
-	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1
-	&& o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1
-	&& mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil
-	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
-	&& isSamePtr(p1, p)
-	&& clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)
-	=> @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDloadidx <t> ptr0 idx0 mem)
-(OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56]
-	y0:(MOVDnop x0:(MOVBUloadidx ptr (ADDconst [7] idx) mem)))
-	y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [6] idx) mem)))
-	y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [5] idx) mem)))
-	y3:(MOVDnop x3:(MOVBUloadidx ptr (ADDconst [4] idx) mem)))
-	y4:(MOVDnop x4:(MOVBUloadidx ptr (ADDconst [3] idx) mem)))
-	y5:(MOVDnop x5:(MOVBUloadidx ptr (ADDconst [2] idx) mem)))
-	y6:(MOVDnop x6:(MOVBUloadidx ptr (ADDconst [1] idx) mem)))
-	y7:(MOVDnop x7:(MOVBUloadidx ptr idx mem)))
-	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
-	&& x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1
-	&& y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1
-	&& y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1
-	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1
-	&& o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1
-	&& mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil
-	&& clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)
-	=> @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (MOVDloadidx <t> ptr idx mem)
-
-// big endian loads
-// b[1] | b[0]<<8 => load 16-bit, reverse
-(ORshiftLL <t> [8]
-	y0:(MOVDnop x0:(MOVBUload [i1] {s} p mem))
-	y1:(MOVDnop x1:(MOVBUload [i0] {s} p mem)))
-	&& i1 == i0+1
-	&& x0.Uses == 1 && x1.Uses == 1
-	&& y0.Uses == 1 && y1.Uses == 1
-	&& mergePoint(b,x0,x1) != nil
-	&& clobber(x0, x1, y0, y1)
-	=> @mergePoint(b,x0,x1) (REV16W <t> (MOVHUload <t> [i0] {s} p mem))
-(ORshiftLL <t> [8]
-	y0:(MOVDnop x0:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem))
-	y1:(MOVDnop x1:(MOVBUloadidx ptr0 idx0 mem)))
-	&& s == nil
-	&& x0.Uses == 1 && x1.Uses == 1
-	&& y0.Uses == 1 && y1.Uses == 1
-	&& mergePoint(b,x0,x1) != nil
-	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
-	&& clobber(x0, x1, y0, y1)
-	=> @mergePoint(b,x0,x1) (REV16W <t> (MOVHUloadidx <t> ptr0 idx0 mem))
-(ORshiftLL <t> [8]
-	y0:(MOVDnop x0:(MOVBUloadidx ptr (ADDconst [1] idx) mem))
-	y1:(MOVDnop x1:(MOVBUloadidx ptr idx mem)))
-	&& x0.Uses == 1 && x1.Uses == 1
-	&& y0.Uses == 1 && y1.Uses == 1
-	&& mergePoint(b,x0,x1) != nil
-	&& clobber(x0, x1, y0, y1)
-	=> @mergePoint(b,x0,x1) (REV16W <t> (MOVHUloadidx <t> ptr idx mem))
-
-// b[3] | b[2]<<8 | b[1]<<16 | b[0]<<24 => load 32-bit, reverse
-(ORshiftLL <t> [24] o0:(ORshiftLL [16]
-	y0:(REV16W  x0:(MOVHUload [i2] {s} p mem))
-	y1:(MOVDnop x1:(MOVBUload [i1] {s} p mem)))
-	y2:(MOVDnop x2:(MOVBUload [i0] {s} p mem)))
-	&& i1 == i0+1
-	&& i2 == i0+2
-	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1
-	&& y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1
-	&& o0.Uses == 1
-	&& mergePoint(b,x0,x1,x2) != nil
-	&& clobber(x0, x1, x2, y0, y1, y2, o0)
-	=> @mergePoint(b,x0,x1,x2) (REVW <t> (MOVWUload <t> {s} (OffPtr <p.Type> [int64(i0)] p) mem))
-(ORshiftLL <t> [24] o0:(ORshiftLL [16]
-	y0:(REV16W  x0:(MOVHUload [2] {s} p mem))
-	y1:(MOVDnop x1:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem)))
-	y2:(MOVDnop x2:(MOVBUloadidx ptr0 idx0 mem)))
-	&& s == nil
-	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1
-	&& y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1
-	&& o0.Uses == 1
-	&& mergePoint(b,x0,x1,x2) != nil
-	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
-	&& isSamePtr(p1, p)
-	&& clobber(x0, x1, x2, y0, y1, y2, o0)
-	=> @mergePoint(b,x0,x1,x2) (REVW <t> (MOVWUloadidx <t> ptr0 idx0 mem))
-(ORshiftLL <t> [24] o0:(ORshiftLL [16]
-	y0:(REV16W  x0:(MOVHUloadidx ptr (ADDconst [2] idx) mem))
-	y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [1] idx) mem)))
-	y2:(MOVDnop x2:(MOVBUloadidx ptr idx mem)))
-	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1
-	&& y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1
-	&& o0.Uses == 1
-	&& mergePoint(b,x0,x1,x2) != nil
-	&& clobber(x0, x1, x2, y0, y1, y2, o0)
-	=> @mergePoint(b,x0,x1,x2) (REVW <t> (MOVWUloadidx <t> ptr idx mem))
-
-// b[7] | b[6]<<8 | b[5]<<16 | b[4]<<24 | b[3]<<32 | b[2]<<40 | b[1]<<48 | b[0]<<56 => load 64-bit, reverse
-(ORshiftLL <t> [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32]
-	y0:(REVW    x0:(MOVWUload [i4] {s} p mem))
-	y1:(MOVDnop x1:(MOVBUload [i3] {s} p mem)))
-	y2:(MOVDnop x2:(MOVBUload [i2] {s} p mem)))
-	y3:(MOVDnop x3:(MOVBUload [i1] {s} p mem)))
-	y4:(MOVDnop x4:(MOVBUload [i0] {s} p mem)))
-	&& i1 == i0+1
-	&& i2 == i0+2
-	&& i3 == i0+3
-	&& i4 == i0+4
-	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1
-	&& y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1
-	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1
-	&& mergePoint(b,x0,x1,x2,x3,x4) != nil
-	&& clobber(x0, x1, x2, x3, x4, y0, y1, y2, y3, y4, o0, o1, o2)
-	=> @mergePoint(b,x0,x1,x2,x3,x4) (REV <t> (MOVDload <t> {s} (OffPtr <p.Type> [int64(i0)] p) mem))
-(ORshiftLL <t> [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32]
-	y0:(REVW    x0:(MOVWUload [4] {s} p mem))
-	y1:(MOVDnop x1:(MOVBUload [3] {s} p mem)))
-	y2:(MOVDnop x2:(MOVBUload [2] {s} p mem)))
-	y3:(MOVDnop x3:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem)))
-	y4:(MOVDnop x4:(MOVBUloadidx ptr0 idx0 mem)))
-	&& s == nil
-	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1
-	&& y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1
-	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1
-	&& mergePoint(b,x0,x1,x2,x3,x4) != nil
-	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
-	&& isSamePtr(p1, p)
-	&& clobber(x0, x1, x2, x3, x4, y0, y1, y2, y3, y4, o0, o1, o2)
-	=> @mergePoint(b,x0,x1,x2,x3,x4) (REV <t> (MOVDloadidx <t> ptr0 idx0 mem))
-(ORshiftLL <t> [56] o0:(ORshiftLL [48] o1:(ORshiftLL [40] o2:(ORshiftLL [32]
-	y0:(REVW    x0:(MOVWUloadidx ptr (ADDconst [4] idx) mem))
-	y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [3] idx) mem)))
-	y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [2] idx) mem)))
-	y3:(MOVDnop x3:(MOVBUloadidx ptr (ADDconst [1] idx) mem)))
-	y4:(MOVDnop x4:(MOVBUloadidx ptr idx mem)))
-	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1
-	&& y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1 && y4.Uses == 1
-	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1
-	&& mergePoint(b,x0,x1,x2,x3,x4) != nil
-	&& clobber(x0, x1, x2, x3, x4, y0, y1, y2, y3, y4, o0, o1, o2)
-	=> @mergePoint(b,x0,x1,x2,x3,x4) (REV <t> (MOVDloadidx <t> ptr idx mem))
-
-// b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3] => load 32-bit, reverse
-(OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24]
-	y0:(MOVDnop x0:(MOVBUload [i0] {s} p mem)))
-	y1:(MOVDnop x1:(MOVBUload [i1] {s} p mem)))
-	y2:(MOVDnop x2:(MOVBUload [i2] {s} p mem)))
-	y3:(MOVDnop x3:(MOVBUload [i3] {s} p mem)))
-	&& i1 == i0+1
-	&& i2 == i0+2
-	&& i3 == i0+3
-	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
-	&& y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1
-	&& o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1
-	&& mergePoint(b,x0,x1,x2,x3) != nil
-	&& clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)
-	=> @mergePoint(b,x0,x1,x2,x3) (REVW <t> (MOVWUload <t> {s} (OffPtr <p.Type> [int64(i0)] p) mem))
-(OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24]
-	y0:(MOVDnop x0:(MOVBUloadidx ptr0 idx0 mem)))
-	y1:(MOVDnop x1:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem)))
-	y2:(MOVDnop x2:(MOVBUload [2] {s} p mem)))
-	y3:(MOVDnop x3:(MOVBUload [3] {s} p mem)))
-	&& s == nil
-	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
-	&& y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1
-	&& o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1
-	&& mergePoint(b,x0,x1,x2,x3) != nil
-	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
-	&& isSamePtr(p1, p)
-	&& clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)
-	=> @mergePoint(b,x0,x1,x2,x3) (REVW <t> (MOVWUloadidx <t> ptr0 idx0 mem))
-(OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] s0:(SLLconst [24]
-	y0:(MOVDnop x0:(MOVBUloadidx ptr idx mem)))
-	y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [1] idx) mem)))
-	y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [2] idx) mem)))
-	y3:(MOVDnop x3:(MOVBUloadidx ptr (ADDconst [3] idx) mem)))
-	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
-	&& y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1
-	&& o0.Uses == 1 && o1.Uses == 1 && s0.Uses == 1
-	&& mergePoint(b,x0,x1,x2,x3) != nil
-	&& clobber(x0, x1, x2, x3, y0, y1, y2, y3, o0, o1, s0)
-	=> @mergePoint(b,x0,x1,x2,x3) (REVW <t> (MOVWUloadidx <t> ptr idx mem))
-
-// b[0]<<56 | b[1]<<48 | b[2]<<40 | b[3]<<32 | b[4]<<24 | b[5]<<16 | b[6]<<8 | b[7] => load 64-bit, reverse
-(OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56]
-	y0:(MOVDnop x0:(MOVBUload [i0] {s} p mem)))
-	y1:(MOVDnop x1:(MOVBUload [i1] {s} p mem)))
-	y2:(MOVDnop x2:(MOVBUload [i2] {s} p mem)))
-	y3:(MOVDnop x3:(MOVBUload [i3] {s} p mem)))
-	y4:(MOVDnop x4:(MOVBUload [i4] {s} p mem)))
-	y5:(MOVDnop x5:(MOVBUload [i5] {s} p mem)))
-	y6:(MOVDnop x6:(MOVBUload [i6] {s} p mem)))
-	y7:(MOVDnop x7:(MOVBUload [i7] {s} p mem)))
-	&& i1 == i0+1
-	&& i2 == i0+2
-	&& i3 == i0+3
-	&& i4 == i0+4
-	&& i5 == i0+5
-	&& i6 == i0+6
-	&& i7 == i0+7
-	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
-	&& x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1
-	&& y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1
-	&& y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1
-	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1
-	&& o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1
-	&& mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil
-	&& clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)
-	=> @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (REV <t> (MOVDload <t> {s} (OffPtr <p.Type> [int64(i0)] p) mem))
-(OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56]
-	y0:(MOVDnop x0:(MOVBUloadidx ptr0 idx0 mem)))
-	y1:(MOVDnop x1:(MOVBUload [1] {s} p1:(ADD ptr1 idx1) mem)))
-	y2:(MOVDnop x2:(MOVBUload [2] {s} p mem)))
-	y3:(MOVDnop x3:(MOVBUload [3] {s} p mem)))
-	y4:(MOVDnop x4:(MOVBUload [4] {s} p mem)))
-	y5:(MOVDnop x5:(MOVBUload [5] {s} p mem)))
-	y6:(MOVDnop x6:(MOVBUload [6] {s} p mem)))
-	y7:(MOVDnop x7:(MOVBUload [7] {s} p mem)))
-	&& s == nil
-	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
-	&& x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1
-	&& y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1
-	&& y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1
-	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1
-	&& o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1
-	&& mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil
-	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
-	&& isSamePtr(p1, p)
-	&& clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)
-	=> @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (REV <t> (MOVDloadidx <t> ptr0 idx0 mem))
-(OR <t> o0:(ORshiftLL [8] o1:(ORshiftLL [16] o2:(ORshiftLL [24] o3:(ORshiftLL [32] o4:(ORshiftLL [40] o5:(ORshiftLL [48] s0:(SLLconst [56]
-	y0:(MOVDnop x0:(MOVBUloadidx ptr idx mem)))
-	y1:(MOVDnop x1:(MOVBUloadidx ptr (ADDconst [1] idx) mem)))
-	y2:(MOVDnop x2:(MOVBUloadidx ptr (ADDconst [2] idx) mem)))
-	y3:(MOVDnop x3:(MOVBUloadidx ptr (ADDconst [3] idx) mem)))
-	y4:(MOVDnop x4:(MOVBUloadidx ptr (ADDconst [4] idx) mem)))
-	y5:(MOVDnop x5:(MOVBUloadidx ptr (ADDconst [5] idx) mem)))
-	y6:(MOVDnop x6:(MOVBUloadidx ptr (ADDconst [6] idx) mem)))
-	y7:(MOVDnop x7:(MOVBUloadidx ptr (ADDconst [7] idx) mem)))
-	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
-	&& x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1
-	&& y0.Uses == 1 && y1.Uses == 1 && y2.Uses == 1 && y3.Uses == 1
-	&& y4.Uses == 1 && y5.Uses == 1 && y6.Uses == 1 && y7.Uses == 1
-	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1 && o3.Uses == 1
-	&& o4.Uses == 1 && o5.Uses == 1 && s0.Uses == 1
-	&& mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) != nil
-	&& clobber(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7, o0, o1, o2, o3, o4, o5, s0)
-	=> @mergePoint(b,x0,x1,x2,x3,x4,x5,x6,x7) (REV <t> (MOVDloadidx <t> ptr idx mem))
-
-// Combine zero stores into larger (unaligned) stores.
-(MOVBstorezero [i] {s} ptr0 x:(MOVBstorezero [j] {s} ptr1 mem))
-	&& x.Uses == 1
-	&& areAdjacentOffsets(int64(i),int64(j),1)
-	&& isSamePtr(ptr0, ptr1)
-	&& clobber(x)
-	=> (MOVHstorezero [int32(min(int64(i),int64(j)))] {s} ptr0 mem)
-(MOVBstorezero [1] {s} (ADD ptr0 idx0) x:(MOVBstorezeroidx ptr1 idx1 mem))
-	&& x.Uses == 1
-	&& s == nil
-	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
-	&& clobber(x)
-	=> (MOVHstorezeroidx ptr1 idx1 mem)
-(MOVBstorezeroidx ptr (ADDconst [1] idx) x:(MOVBstorezeroidx ptr idx mem))
-	&& x.Uses == 1
-	&& clobber(x)
-	=> (MOVHstorezeroidx ptr idx mem)
-(MOVHstorezero [i] {s} ptr0 x:(MOVHstorezero [j] {s} ptr1 mem))
-	&& x.Uses == 1
-	&& areAdjacentOffsets(int64(i),int64(j),2)
-	&& isSamePtr(ptr0, ptr1)
-	&& clobber(x)
-	=> (MOVWstorezero [int32(min(int64(i),int64(j)))] {s} ptr0 mem)
-(MOVHstorezero [2] {s} (ADD ptr0 idx0) x:(MOVHstorezeroidx ptr1 idx1 mem))
-	&& x.Uses == 1
-	&& s == nil
-	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
-	&& clobber(x)
-	=> (MOVWstorezeroidx ptr1 idx1 mem)
-(MOVHstorezeroidx ptr (ADDconst [2] idx) x:(MOVHstorezeroidx ptr idx mem))
-	&& x.Uses == 1
-	&& clobber(x)
-	=> (MOVWstorezeroidx ptr idx mem)
-(MOVHstorezero [2] {s} (ADDshiftLL [1] ptr0 idx0) x:(MOVHstorezeroidx2 ptr1 idx1 mem))
-	&& x.Uses == 1
-	&& s == nil
-	&& isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1)
-	&& clobber(x)
-	=> (MOVWstorezeroidx ptr1 (SLLconst <idx1.Type> [1] idx1) mem)
-(MOVWstorezero [i] {s} ptr0 x:(MOVWstorezero [j] {s} ptr1 mem))
-	&& x.Uses == 1
-	&& areAdjacentOffsets(int64(i),int64(j),4)
-	&& isSamePtr(ptr0, ptr1)
-	&& clobber(x)
-	=> (MOVDstorezero [int32(min(int64(i),int64(j)))] {s} ptr0 mem)
-(MOVWstorezero [4] {s} (ADD ptr0 idx0) x:(MOVWstorezeroidx ptr1 idx1 mem))
-	&& x.Uses == 1
-	&& s == nil
-	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
-	&& clobber(x)
-	=> (MOVDstorezeroidx ptr1 idx1 mem)
-(MOVWstorezeroidx ptr (ADDconst [4] idx) x:(MOVWstorezeroidx ptr idx mem))
-	&& x.Uses == 1
-	&& clobber(x)
-	=> (MOVDstorezeroidx ptr idx mem)
-(MOVWstorezero [4] {s} (ADDshiftLL [2] ptr0 idx0) x:(MOVWstorezeroidx4 ptr1 idx1 mem))
-	&& x.Uses == 1
-	&& s == nil
-	&& isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1)
-	&& clobber(x)
-	=> (MOVDstorezeroidx ptr1 (SLLconst <idx1.Type> [2] idx1) mem)
-(MOVDstorezero [i] {s} ptr0 x:(MOVDstorezero [j] {s} ptr1 mem))
-	&& x.Uses == 1
-	&& areAdjacentOffsets(int64(i),int64(j),8)
-	&& isSamePtr(ptr0, ptr1)
-	&& clobber(x)
-	=> (MOVQstorezero [int32(min(int64(i),int64(j)))] {s} ptr0 mem)
-(MOVDstorezero [8] {s} p0:(ADD ptr0 idx0) x:(MOVDstorezeroidx ptr1 idx1 mem))
-	&& x.Uses == 1
-	&& s == nil
-	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
-	&& clobber(x)
-	=> (MOVQstorezero [0] {s} p0 mem)
-(MOVDstorezero [8] {s} p0:(ADDshiftLL [3] ptr0 idx0) x:(MOVDstorezeroidx8 ptr1 idx1 mem))
-	&& x.Uses == 1
-	&& s == nil
-	&& isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1)
-	&& clobber(x)
-	=> (MOVQstorezero [0] {s} p0 mem)
-
-// Combine stores into larger (unaligned) stores.
-(MOVBstore [i] {s} ptr0 (SRLconst [8] w) x:(MOVBstore [i-1] {s} ptr1 w mem))
-	&& x.Uses == 1
-	&& isSamePtr(ptr0, ptr1)
-	&& clobber(x)
-	=> (MOVHstore [i-1] {s} ptr0 w mem)
-(MOVBstore [1] {s} (ADD ptr0 idx0) (SRLconst [8] w) x:(MOVBstoreidx ptr1 idx1 w mem))
-	&& x.Uses == 1
-	&& s == nil
-	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
-	&& clobber(x)
-	=> (MOVHstoreidx ptr1 idx1 w mem)
-(MOVBstoreidx ptr (ADDconst [1] idx) (SRLconst [8] w) x:(MOVBstoreidx ptr idx w mem))
-	&& x.Uses == 1
-	&& clobber(x)
-	=> (MOVHstoreidx ptr idx w mem)
-(MOVBstore [i] {s} ptr0 (UBFX [armBFAuxInt(8, 8)] w) x:(MOVBstore [i-1] {s} ptr1 w mem))
-	&& x.Uses == 1
-	&& isSamePtr(ptr0, ptr1)
-	&& clobber(x)
-	=> (MOVHstore [i-1] {s} ptr0 w mem)
-(MOVBstore [1] {s} (ADD ptr0 idx0) (UBFX [armBFAuxInt(8, 8)] w) x:(MOVBstoreidx ptr1 idx1 w mem))
-	&& x.Uses == 1
-	&& s == nil
-	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
-	&& clobber(x)
-	=> (MOVHstoreidx ptr1 idx1 w mem)
-(MOVBstore [i] {s} ptr0 (UBFX [armBFAuxInt(8, 24)] w) x:(MOVBstore [i-1] {s} ptr1 w mem))
-	&& x.Uses == 1
-	&& isSamePtr(ptr0, ptr1)
-	&& clobber(x)
-	=> (MOVHstore [i-1] {s} ptr0 w mem)
-(MOVBstore [1] {s} (ADD ptr0 idx0) (UBFX [armBFAuxInt(8, 24)] w) x:(MOVBstoreidx ptr1 idx1 w mem))
-	&& x.Uses == 1
-	&& s == nil
-	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
-	&& clobber(x)
-	=> (MOVHstoreidx ptr1 idx1 w mem)
-(MOVBstore [i] {s} ptr0 (SRLconst [8] (MOVDreg w)) x:(MOVBstore [i-1] {s} ptr1 w mem))
-	&& x.Uses == 1
-	&& isSamePtr(ptr0, ptr1)
-	&& clobber(x)
-	=> (MOVHstore [i-1] {s} ptr0 w mem)
-(MOVBstore [1] {s} (ADD ptr0 idx0) (SRLconst [8] (MOVDreg w)) x:(MOVBstoreidx ptr1 idx1 w mem))
-	&& x.Uses == 1
-	&& s == nil
-	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
-	&& clobber(x)
-	=> (MOVHstoreidx ptr1 idx1 w mem)
-(MOVBstore [i] {s} ptr0 (SRLconst [j] w) x:(MOVBstore [i-1] {s} ptr1 w0:(SRLconst [j-8] w) mem))
-	&& x.Uses == 1
-	&& isSamePtr(ptr0, ptr1)
-	&& clobber(x)
-	=> (MOVHstore [i-1] {s} ptr0 w0 mem)
-(MOVBstore [1] {s} (ADD ptr0 idx0) (SRLconst [j] w) x:(MOVBstoreidx ptr1 idx1 w0:(SRLconst [j-8] w) mem))
-	&& x.Uses == 1
-	&& s == nil
-	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
-	&& clobber(x)
-	=> (MOVHstoreidx ptr1 idx1 w0 mem)
-(MOVBstore [i] {s} ptr0 (UBFX [bfc] w) x:(MOVBstore [i-1] {s} ptr1 w0:(UBFX [bfc2] w) mem))
-	&& x.Uses == 1
-	&& isSamePtr(ptr0, ptr1)
-	&& bfc.getARM64BFwidth() == 32 - bfc.getARM64BFlsb()
-	&& bfc2.getARM64BFwidth() == 32 - bfc2.getARM64BFlsb()
-	&& bfc2.getARM64BFlsb() == bfc.getARM64BFlsb() - 8
-	&& clobber(x)
-	=> (MOVHstore [i-1] {s} ptr0 w0 mem)
-(MOVBstore [1] {s} (ADD ptr0 idx0) (UBFX [bfc] w) x:(MOVBstoreidx ptr1 idx1 w0:(UBFX [bfc2] w) mem))
-	&& x.Uses == 1
-	&& s == nil
-	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
-	&& bfc.getARM64BFwidth() == 32 - bfc.getARM64BFlsb()
-	&& bfc2.getARM64BFwidth() == 32 - bfc2.getARM64BFlsb()
-	&& bfc2.getARM64BFlsb() == bfc.getARM64BFlsb() - 8
-	&& clobber(x)
-	=> (MOVHstoreidx ptr1 idx1 w0 mem)
-(MOVBstore [i] {s} ptr0 (SRLconst [j] (MOVDreg w)) x:(MOVBstore [i-1] {s} ptr1 w0:(SRLconst [j-8] (MOVDreg w)) mem))
-	&& x.Uses == 1
-	&& isSamePtr(ptr0, ptr1)
-	&& clobber(x)
-	=> (MOVHstore [i-1] {s} ptr0 w0 mem)
-(MOVBstore [1] {s} (ADD ptr0 idx0) (SRLconst [j] (MOVDreg w)) x:(MOVBstoreidx ptr1 idx1 w0:(SRLconst [j-8] (MOVDreg w)) mem))
-	&& x.Uses == 1
-	&& s == nil
-	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
-	&& clobber(x)
-	=> (MOVHstoreidx ptr1 idx1 w0 mem)
-(MOVHstore [i] {s} ptr0 (SRLconst [16] w) x:(MOVHstore [i-2] {s} ptr1 w mem))
-	&& x.Uses == 1
-	&& isSamePtr(ptr0, ptr1)
-	&& clobber(x)
-	=> (MOVWstore [i-2] {s} ptr0 w mem)
-(MOVHstore [2] {s} (ADD ptr0 idx0) (SRLconst [16] w) x:(MOVHstoreidx ptr1 idx1 w mem))
-	&& x.Uses == 1
-	&& s == nil
-	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
-	&& clobber(x)
-	=> (MOVWstoreidx ptr1 idx1 w mem)
-(MOVHstoreidx ptr (ADDconst [2] idx) (SRLconst [16] w) x:(MOVHstoreidx ptr idx w mem))
-	&& x.Uses == 1
-	&& clobber(x)
-	=> (MOVWstoreidx ptr idx w mem)
-(MOVHstore [2] {s} (ADDshiftLL [1] ptr0 idx0) (SRLconst [16] w) x:(MOVHstoreidx2 ptr1 idx1 w mem))
-	&& x.Uses == 1
-	&& s == nil
-	&& isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1)
-	&& clobber(x)
-	=> (MOVWstoreidx ptr1 (SLLconst <idx1.Type> [1] idx1) w mem)
-(MOVHstore [i] {s} ptr0 (UBFX [armBFAuxInt(16, 16)] w) x:(MOVHstore [i-2] {s} ptr1 w mem))
-	&& x.Uses == 1
-	&& isSamePtr(ptr0, ptr1)
-	&& clobber(x)
-	=> (MOVWstore [i-2] {s} ptr0 w mem)
-(MOVHstore [2] {s} (ADD ptr0 idx0) (UBFX [armBFAuxInt(16, 16)] w) x:(MOVHstoreidx ptr1 idx1 w mem))
-	&& x.Uses == 1
-	&& s == nil
-	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
-	&& clobber(x)
-	=> (MOVWstoreidx ptr1 idx1 w mem)
-(MOVHstore [2] {s} (ADDshiftLL [1] ptr0 idx0) (UBFX [armBFAuxInt(16, 16)] w) x:(MOVHstoreidx2 ptr1 idx1 w mem))
-	&& x.Uses == 1
-	&& s == nil
-	&& isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1)
-	&& clobber(x)
-	=> (MOVWstoreidx ptr1 (SLLconst <idx1.Type> [1] idx1) w mem)
-(MOVHstore [i] {s} ptr0 (SRLconst [16] (MOVDreg w)) x:(MOVHstore [i-2] {s} ptr1 w mem))
-	&& x.Uses == 1
-	&& isSamePtr(ptr0, ptr1)
-	&& clobber(x)
-	=> (MOVWstore [i-2] {s} ptr0 w mem)
-(MOVHstore [2] {s} (ADD ptr0 idx0) (SRLconst [16] (MOVDreg w)) x:(MOVHstoreidx ptr1 idx1 w mem))
-	&& x.Uses == 1
-	&& s == nil
-	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
-	&& clobber(x)
-	=> (MOVWstoreidx ptr1 idx1 w mem)
-(MOVHstore [2] {s} (ADDshiftLL [1] ptr0 idx0) (SRLconst [16] (MOVDreg w)) x:(MOVHstoreidx2 ptr1 idx1 w mem))
-	&& x.Uses == 1
-	&& s == nil
-	&& isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1)
-	&& clobber(x)
-	=> (MOVWstoreidx ptr1 (SLLconst <idx1.Type> [1] idx1) w mem)
-(MOVHstore [i] {s} ptr0 (SRLconst [j] w) x:(MOVHstore [i-2] {s} ptr1 w0:(SRLconst [j-16] w) mem))
-	&& x.Uses == 1
-	&& isSamePtr(ptr0, ptr1)
-	&& clobber(x)
-	=> (MOVWstore [i-2] {s} ptr0 w0 mem)
-(MOVHstore [2] {s} (ADD ptr0 idx0) (SRLconst [j] w) x:(MOVHstoreidx ptr1 idx1 w0:(SRLconst [j-16] w) mem))
-	&& x.Uses == 1
-	&& s == nil
-	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
-	&& clobber(x)
-	=> (MOVWstoreidx ptr1 idx1 w0 mem)
-(MOVHstore [2] {s} (ADDshiftLL [1] ptr0 idx0) (SRLconst [j] w) x:(MOVHstoreidx2 ptr1 idx1 w0:(SRLconst [j-16] w) mem))
-	&& x.Uses == 1
-	&& s == nil
-	&& isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1)
-	&& clobber(x)
-	=> (MOVWstoreidx ptr1 (SLLconst <idx1.Type> [1] idx1) w0 mem)
-(MOVWstore [i] {s} ptr0 (SRLconst [32] w) x:(MOVWstore [i-4] {s} ptr1 w mem))
-	&& x.Uses == 1
-	&& isSamePtr(ptr0, ptr1)
-	&& clobber(x)
-	=> (MOVDstore [i-4] {s} ptr0 w mem)
-(MOVWstore [4] {s} (ADD ptr0 idx0) (SRLconst [32] w) x:(MOVWstoreidx ptr1 idx1 w mem))
-	&& x.Uses == 1
-	&& s == nil
-	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
-	&& clobber(x)
-	=> (MOVDstoreidx ptr1 idx1 w mem)
-(MOVWstoreidx ptr (ADDconst [4] idx) (SRLconst [32] w) x:(MOVWstoreidx ptr idx w mem))
-	&& x.Uses == 1
-	&& clobber(x)
-	=> (MOVDstoreidx ptr idx w mem)
-(MOVWstore [4] {s} (ADDshiftLL [2] ptr0 idx0) (SRLconst [32] w) x:(MOVWstoreidx4 ptr1 idx1 w mem))
-	&& x.Uses == 1
-	&& s == nil
-	&& isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1)
-	&& clobber(x)
-	=> (MOVDstoreidx ptr1 (SLLconst <idx1.Type> [2] idx1) w mem)
-(MOVWstore [i] {s} ptr0 (SRLconst [j] w) x:(MOVWstore [i-4] {s} ptr1 w0:(SRLconst [j-32] w) mem))
-	&& x.Uses == 1
-	&& isSamePtr(ptr0, ptr1)
-	&& clobber(x)
-	=> (MOVDstore [i-4] {s} ptr0 w0 mem)
-(MOVWstore [4] {s} (ADD ptr0 idx0) (SRLconst [j] w) x:(MOVWstoreidx ptr1 idx1 w0:(SRLconst [j-32] w) mem))
-	&& x.Uses == 1
-	&& s == nil
-	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
-	&& clobber(x)
-	=> (MOVDstoreidx ptr1 idx1 w0 mem)
-(MOVWstore [4] {s} (ADDshiftLL [2] ptr0 idx0) (SRLconst [j] w) x:(MOVWstoreidx4 ptr1 idx1 w0:(SRLconst [j-32] w) mem))
-	&& x.Uses == 1
-	&& s == nil
-	&& isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1)
-	&& clobber(x)
-	=> (MOVDstoreidx ptr1 (SLLconst <idx1.Type> [2] idx1) w0 mem)
-(MOVBstore [i] {s} ptr w
-	x0:(MOVBstore [i-1] {s} ptr (SRLconst [8] w)
-	x1:(MOVBstore [i-2] {s} ptr (SRLconst [16] w)
-	x2:(MOVBstore [i-3] {s} ptr (SRLconst [24] w)
-	x3:(MOVBstore [i-4] {s} ptr (SRLconst [32] w)
-	x4:(MOVBstore [i-5] {s} ptr (SRLconst [40] w)
-	x5:(MOVBstore [i-6] {s} ptr (SRLconst [48] w)
-	x6:(MOVBstore [i-7] {s} ptr (SRLconst [56] w) mem))))))))
-	&& x0.Uses == 1
-	&& x1.Uses == 1
-	&& x2.Uses == 1
-	&& x3.Uses == 1
-	&& x4.Uses == 1
-	&& x5.Uses == 1
-	&& x6.Uses == 1
-	&& clobber(x0, x1, x2, x3, x4, x5, x6)
-	=> (MOVDstore [i-7] {s} ptr (REV <w.Type> w) mem)
-(MOVBstore [7] {s} p w
-	x0:(MOVBstore [6] {s} p (SRLconst [8] w)
-	x1:(MOVBstore [5] {s} p (SRLconst [16] w)
-	x2:(MOVBstore [4] {s} p (SRLconst [24] w)
-	x3:(MOVBstore [3] {s} p (SRLconst [32] w)
-	x4:(MOVBstore [2] {s} p (SRLconst [40] w)
-	x5:(MOVBstore [1] {s} p1:(ADD ptr1 idx1) (SRLconst [48] w)
-	x6:(MOVBstoreidx ptr0 idx0 (SRLconst [56] w) mem))))))))
-	&& x0.Uses == 1
-	&& x1.Uses == 1
-	&& x2.Uses == 1
-	&& x3.Uses == 1
-	&& x4.Uses == 1
-	&& x5.Uses == 1
-	&& x6.Uses == 1
-	&& s == nil
-	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
-	&& isSamePtr(p1, p)
-	&& clobber(x0, x1, x2, x3, x4, x5, x6)
-	=> (MOVDstoreidx ptr0 idx0 (REV <w.Type> w) mem)
-(MOVBstore [i] {s} ptr w
-	x0:(MOVBstore [i-1] {s} ptr (UBFX [armBFAuxInt(8, 24)] w)
-	x1:(MOVBstore [i-2] {s} ptr (UBFX [armBFAuxInt(16, 16)] w)
-	x2:(MOVBstore [i-3] {s} ptr (UBFX [armBFAuxInt(24, 8)] w) mem))))
-	&& x0.Uses == 1
-	&& x1.Uses == 1
-	&& x2.Uses == 1
-	&& clobber(x0, x1, x2)
-	=> (MOVWstore [i-3] {s} ptr (REVW <w.Type> w) mem)
-(MOVBstore [3] {s} p w
-	x0:(MOVBstore [2] {s} p (UBFX [armBFAuxInt(8, 24)] w)
-	x1:(MOVBstore [1] {s} p1:(ADD ptr1 idx1) (UBFX [armBFAuxInt(16, 16)] w)
-	x2:(MOVBstoreidx ptr0 idx0 (UBFX [armBFAuxInt(24, 8)] w) mem))))
-	&& x0.Uses == 1
-	&& x1.Uses == 1
-	&& x2.Uses == 1
-	&& s == nil
-	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
-	&& isSamePtr(p1, p)
-	&& clobber(x0, x1, x2)
-	=> (MOVWstoreidx ptr0 idx0 (REVW <w.Type> w) mem)
-(MOVBstoreidx ptr (ADDconst [3] idx) w
-	x0:(MOVBstoreidx ptr (ADDconst [2] idx) (UBFX [armBFAuxInt(8, 24)] w)
-	x1:(MOVBstoreidx ptr (ADDconst [1] idx) (UBFX [armBFAuxInt(16, 16)] w)
-	x2:(MOVBstoreidx ptr idx (UBFX [armBFAuxInt(24, 8)] w) mem))))
-	&& x0.Uses == 1
-	&& x1.Uses == 1
-	&& x2.Uses == 1
-	&& clobber(x0, x1, x2)
-	=> (MOVWstoreidx ptr idx (REVW <w.Type> w) mem)
-(MOVBstoreidx ptr idx w
-	x0:(MOVBstoreidx ptr (ADDconst [1] idx) (UBFX [armBFAuxInt(8, 24)] w)
-	x1:(MOVBstoreidx ptr (ADDconst [2] idx) (UBFX [armBFAuxInt(16, 16)] w)
-	x2:(MOVBstoreidx ptr (ADDconst [3] idx) (UBFX [armBFAuxInt(24, 8)] w) mem))))
-	&& x0.Uses == 1
-	&& x1.Uses == 1
-	&& x2.Uses == 1
-	&& clobber(x0, x1, x2)
-	=> (MOVWstoreidx ptr idx w mem)
-(MOVBstore [i] {s} ptr w
-	x0:(MOVBstore [i-1] {s} ptr (SRLconst [8] (MOVDreg w))
-	x1:(MOVBstore [i-2] {s} ptr (SRLconst [16] (MOVDreg w))
-	x2:(MOVBstore [i-3] {s} ptr (SRLconst [24] (MOVDreg w)) mem))))
-	&& x0.Uses == 1
-	&& x1.Uses == 1
-	&& x2.Uses == 1
-	&& clobber(x0, x1, x2)
-	=> (MOVWstore [i-3] {s} ptr (REVW <w.Type> w) mem)
-(MOVBstore [3] {s} p w
-	x0:(MOVBstore [2] {s} p (SRLconst [8] (MOVDreg w))
-	x1:(MOVBstore [1] {s} p1:(ADD ptr1 idx1) (SRLconst [16] (MOVDreg w))
-	x2:(MOVBstoreidx ptr0 idx0 (SRLconst [24] (MOVDreg w)) mem))))
-	&& x0.Uses == 1
-	&& x1.Uses == 1
-	&& x2.Uses == 1
-	&& s == nil
-	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
-	&& isSamePtr(p1, p)
-	&& clobber(x0, x1, x2)
-	=> (MOVWstoreidx ptr0 idx0 (REVW <w.Type> w) mem)
-(MOVBstore [i] {s} ptr w
-	x0:(MOVBstore [i-1] {s} ptr (SRLconst [8] w)
-	x1:(MOVBstore [i-2] {s} ptr (SRLconst [16] w)
-	x2:(MOVBstore [i-3] {s} ptr (SRLconst [24] w) mem))))
-	&& x0.Uses == 1
-	&& x1.Uses == 1
-	&& x2.Uses == 1
-	&& clobber(x0, x1, x2)
-	=> (MOVWstore [i-3] {s} ptr (REVW <w.Type> w) mem)
-(MOVBstore [3] {s} p w
-	x0:(MOVBstore [2] {s} p (SRLconst [8] w)
-	x1:(MOVBstore [1] {s} p1:(ADD ptr1 idx1) (SRLconst [16] w)
-	x2:(MOVBstoreidx ptr0 idx0 (SRLconst [24] w) mem))))
-	&& x0.Uses == 1
-	&& x1.Uses == 1
-	&& x2.Uses == 1
-	&& s == nil
-	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
-	&& isSamePtr(p1, p)
-	&& clobber(x0, x1, x2)
-	=> (MOVWstoreidx ptr0 idx0 (REVW <w.Type> w) mem)
-(MOVBstore [i] {s} ptr w x:(MOVBstore [i-1] {s} ptr (SRLconst [8] w) mem))
-	&& x.Uses == 1
-	&& clobber(x)
-	=> (MOVHstore [i-1] {s} ptr (REV16W <w.Type> w) mem)
-(MOVBstore [1] {s} (ADD ptr1 idx1) w x:(MOVBstoreidx ptr0 idx0 (SRLconst [8] w) mem))
-	&& x.Uses == 1
-	&& s == nil
-	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
-	&& clobber(x)
-	=> (MOVHstoreidx ptr0 idx0 (REV16W <w.Type> w) mem)
-(MOVBstore [i] {s} ptr w x:(MOVBstore [i-1] {s} ptr (UBFX [armBFAuxInt(8, 8)] w) mem))
-	&& x.Uses == 1
-	&& clobber(x)
-	=> (MOVHstore [i-1] {s} ptr (REV16W <w.Type> w) mem)
-(MOVBstore [1] {s} (ADD ptr1 idx1) w x:(MOVBstoreidx ptr0 idx0 (UBFX [armBFAuxInt(8, 8)] w) mem))
-	&& x.Uses == 1
-	&& s == nil
-	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
-	&& clobber(x)
-	=> (MOVHstoreidx ptr0 idx0 (REV16W <w.Type> w) mem)
-(MOVBstoreidx ptr (ADDconst [1] idx) w x:(MOVBstoreidx ptr idx (UBFX [armBFAuxInt(8, 8)] w) mem))
-	&& x.Uses == 1
-	&& clobber(x)
-	=> (MOVHstoreidx ptr idx (REV16W <w.Type> w) mem)
-(MOVBstoreidx ptr idx w x:(MOVBstoreidx ptr (ADDconst [1] idx) (UBFX [armBFAuxInt(8, 8)] w) mem))
-	&& x.Uses == 1
-	&& clobber(x)
-	=> (MOVHstoreidx ptr idx w mem)
-(MOVBstore [i] {s} ptr w x:(MOVBstore [i-1] {s} ptr (SRLconst [8] (MOVDreg w)) mem))
-	&& x.Uses == 1
-	&& clobber(x)
-	=> (MOVHstore [i-1] {s} ptr (REV16W <w.Type> w) mem)
-(MOVBstore [1] {s} (ADD ptr1 idx1) w x:(MOVBstoreidx ptr0 idx0 (SRLconst [8] (MOVDreg w)) mem))
-	&& x.Uses == 1
-	&& s == nil
-	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
-	&& clobber(x)
-	=> (MOVHstoreidx ptr0 idx0 (REV16W <w.Type> w) mem)
-(MOVBstore [i] {s} ptr w x:(MOVBstore [i-1] {s} ptr (UBFX [armBFAuxInt(8, 24)] w) mem))
-	&& x.Uses == 1
-	&& clobber(x)
-	=> (MOVHstore [i-1] {s} ptr (REV16W <w.Type> w) mem)
-(MOVBstore [1] {s} (ADD ptr1 idx1) w x:(MOVBstoreidx ptr0 idx0 (UBFX [armBFAuxInt(8, 24)] w) mem))
-	&& x.Uses == 1
-	&& s == nil
-	&& (isSamePtr(ptr0, ptr1) && isSamePtr(idx0, idx1) || isSamePtr(ptr0, idx1) && isSamePtr(idx0, ptr1))
-	&& clobber(x)
-	=> (MOVHstoreidx ptr0 idx0 (REV16W <w.Type> w) mem)
-
-// FP simplification
-(FNEGS (FMULS x y)) => (FNMULS x y)
-(FNEGD (FMULD x y)) => (FNMULD x y)
-(FMULS (FNEGS x) y) => (FNMULS x y)
-(FMULD (FNEGD x) y) => (FNMULD x y)
-(FNEGS (FNMULS x y)) => (FMULS x y)
-(FNEGD (FNMULD x y)) => (FMULD x y)
-(FNMULS (FNEGS x) y) => (FMULS x y)
-(FNMULD (FNEGD x) y) => (FMULD x y)
-(FADDS a (FMULS x y)) => (FMADDS a x y)
-(FADDD a (FMULD x y)) => (FMADDD a x y)
-(FSUBS a (FMULS x y)) => (FMSUBS a x y)
-(FSUBD a (FMULD x y)) => (FMSUBD a x y)
-(FSUBS (FMULS x y) a) => (FNMSUBS a x y)
-(FSUBD (FMULD x y) a) => (FNMSUBD a x y)
-(FADDS a (FNMULS x y)) => (FMSUBS a x y)
-(FADDD a (FNMULD x y)) => (FMSUBD a x y)
-(FSUBS a (FNMULS x y)) => (FMADDS a x y)
-(FSUBD a (FNMULD x y)) => (FMADDD a x y)
-(FSUBS (FNMULS x y) a) => (FNMADDS a x y)
-(FSUBD (FNMULD x y) a) => (FNMADDD a x y)
-
-(MOVBUload [off] {sym} (SB) _) && symIsRO(sym) => (MOVDconst [int64(read8(sym, int64(off)))])
-(MOVHUload [off] {sym} (SB) _) && symIsRO(sym) => (MOVDconst [int64(read16(sym, int64(off), config.ctxt.Arch.ByteOrder))])
-(MOVWUload [off] {sym} (SB) _) && symIsRO(sym) => (MOVDconst [int64(read32(sym, int64(off), config.ctxt.Arch.ByteOrder))])
-(MOVDload  [off] {sym} (SB) _) && symIsRO(sym) => (MOVDconst [int64(read64(sym, int64(off), config.ctxt.Arch.ByteOrder))])
-
-// Prefetch instructions (aux is option: 0 - PLDL1KEEP; 1 - PLDL1STRM)
-(PrefetchCache addr mem)         => (PRFM [0] addr mem)
-(PrefetchCacheStreamed addr mem) => (PRFM [1] addr mem)
-
-// Arch-specific inlining for small or disjoint runtime.memmove
-(SelectN [0] call:(CALLstatic {sym} s1:(MOVDstore _ (MOVDconst [sz]) s2:(MOVDstore  _ src s3:(MOVDstore {t} _ dst mem)))))
-	&& sz >= 0
-	&& isSameCall(sym, "runtime.memmove")
-	&& s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1
-	&& isInlinableMemmove(dst, src, sz, config)
-	&& clobber(s1, s2, s3, call)
-	=> (Move [sz] dst src mem)
-
-// Match post-lowering calls, register version.
-(SelectN [0] call:(CALLstatic {sym} dst src (MOVDconst [sz]) mem))
-	&& sz >= 0
-	&& isSameCall(sym, "runtime.memmove")
-	&& call.Uses == 1
-	&& isInlinableMemmove(dst, src, sz, config)
-	&& clobber(call)
-	=> (Move [sz] dst src mem)
-
-((REV|REVW) ((REV|REVW) p)) => p
diff --git a/src/cmd/compile/internal/ssa/gen/ARM64Ops.go b/src/cmd/compile/internal/ssa/gen/ARM64Ops.go
deleted file mode 100644
index 8234bce..0000000
--- a/src/cmd/compile/internal/ssa/gen/ARM64Ops.go
+++ /dev/null
@@ -1,798 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build ignore
-// +build ignore
-
-package main
-
-import "strings"
-
-// Notes:
-//  - Integer types live in the low portion of registers. Upper portions are junk.
-//  - Boolean types use the low-order byte of a register. 0=false, 1=true.
-//    Upper bytes are junk.
-//  - *const instructions may use a constant larger than the instruction can encode.
-//    In this case the assembler expands to multiple instructions and uses tmp
-//    register (R27).
-
-// Suffixes encode the bit width of various instructions.
-// D (double word) = 64 bit
-// W (word)        = 32 bit
-// H (half word)   = 16 bit
-// HU              = 16 bit unsigned
-// B (byte)        = 8 bit
-// BU              = 8 bit unsigned
-// S (single)      = 32 bit float
-// D (double)      = 64 bit float
-
-// Note: registers not used in regalloc are not included in this list,
-// so that regmask stays within int64
-// Be careful when hand coding regmasks.
-var regNamesARM64 = []string{
-	"R0",
-	"R1",
-	"R2",
-	"R3",
-	"R4",
-	"R5",
-	"R6",
-	"R7",
-	"R8",
-	"R9",
-	"R10",
-	"R11",
-	"R12",
-	"R13",
-	"R14",
-	"R15",
-	"R16",
-	"R17",
-	"R18", // platform register, not used
-	"R19",
-	"R20",
-	"R21",
-	"R22",
-	"R23",
-	"R24",
-	"R25",
-	"R26",
-	// R27 = REGTMP not used in regalloc
-	"g",   // aka R28
-	"R29", // frame pointer, not used
-	"R30", // aka REGLINK
-	"SP",  // aka R31
-
-	"F0",
-	"F1",
-	"F2",
-	"F3",
-	"F4",
-	"F5",
-	"F6",
-	"F7",
-	"F8",
-	"F9",
-	"F10",
-	"F11",
-	"F12",
-	"F13",
-	"F14",
-	"F15",
-	"F16",
-	"F17",
-	"F18",
-	"F19",
-	"F20",
-	"F21",
-	"F22",
-	"F23",
-	"F24",
-	"F25",
-	"F26",
-	"F27",
-	"F28",
-	"F29",
-	"F30",
-	"F31",
-
-	// If you add registers, update asyncPreempt in runtime.
-
-	// pseudo-registers
-	"SB",
-}
-
-func init() {
-	// Make map from reg names to reg integers.
-	if len(regNamesARM64) > 64 {
-		panic("too many registers")
-	}
-	num := map[string]int{}
-	for i, name := range regNamesARM64 {
-		num[name] = i
-	}
-	buildReg := func(s string) regMask {
-		m := regMask(0)
-		for _, r := range strings.Split(s, " ") {
-			if n, ok := num[r]; ok {
-				m |= regMask(1) << uint(n)
-				continue
-			}
-			panic("register " + r + " not found")
-		}
-		return m
-	}
-
-	// Common individual register masks
-	var (
-		gp         = buildReg("R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30")
-		gpg        = gp | buildReg("g")
-		gpsp       = gp | buildReg("SP")
-		gpspg      = gpg | buildReg("SP")
-		gpspsbg    = gpspg | buildReg("SB")
-		fp         = buildReg("F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31")
-		callerSave = gp | fp | buildReg("g") // runtime.setg (and anything calling it) may clobber g
-		r0         = buildReg("R0")
-		r1         = buildReg("R1")
-		r2         = buildReg("R2")
-		r3         = buildReg("R3")
-	)
-	// Common regInfo
-	var (
-		gp01           = regInfo{inputs: nil, outputs: []regMask{gp}}
-		gp0flags1      = regInfo{inputs: []regMask{0}, outputs: []regMask{gp}}
-		gp11           = regInfo{inputs: []regMask{gpg}, outputs: []regMask{gp}}
-		gp11sp         = regInfo{inputs: []regMask{gpspg}, outputs: []regMask{gp}}
-		gp1flags       = regInfo{inputs: []regMask{gpg}}
-		gp1flags1      = regInfo{inputs: []regMask{gpg}, outputs: []regMask{gp}}
-		gp11flags      = regInfo{inputs: []regMask{gpg}, outputs: []regMask{gp, 0}}
-		gp21           = regInfo{inputs: []regMask{gpg, gpg}, outputs: []regMask{gp}}
-		gp21nog        = regInfo{inputs: []regMask{gp, gp}, outputs: []regMask{gp}}
-		gp21flags      = regInfo{inputs: []regMask{gp, gp}, outputs: []regMask{gp, 0}}
-		gp2flags       = regInfo{inputs: []regMask{gpg, gpg}}
-		gp2flags1      = regInfo{inputs: []regMask{gp, gp}, outputs: []regMask{gp}}
-		gp2flags1flags = regInfo{inputs: []regMask{gp, gp, 0}, outputs: []regMask{gp, 0}}
-		gp2load        = regInfo{inputs: []regMask{gpspsbg, gpg}, outputs: []regMask{gp}}
-		gp22           = regInfo{inputs: []regMask{gpg, gpg}, outputs: []regMask{gp, gp}}
-		gp31           = regInfo{inputs: []regMask{gpg, gpg, gpg}, outputs: []regMask{gp}}
-		gpload         = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{gp}}
-		gpstore        = regInfo{inputs: []regMask{gpspsbg, gpg}}
-		gpstore0       = regInfo{inputs: []regMask{gpspsbg}}
-		gpstore2       = regInfo{inputs: []regMask{gpspsbg, gpg, gpg}}
-		gpxchg         = regInfo{inputs: []regMask{gpspsbg, gpg}, outputs: []regMask{gp}}
-		gpcas          = regInfo{inputs: []regMask{gpspsbg, gpg, gpg}, outputs: []regMask{gp}}
-		fp01           = regInfo{inputs: nil, outputs: []regMask{fp}}
-		fp11           = regInfo{inputs: []regMask{fp}, outputs: []regMask{fp}}
-		fpgp           = regInfo{inputs: []regMask{fp}, outputs: []regMask{gp}}
-		gpfp           = regInfo{inputs: []regMask{gp}, outputs: []regMask{fp}}
-		fp21           = regInfo{inputs: []regMask{fp, fp}, outputs: []regMask{fp}}
-		fp31           = regInfo{inputs: []regMask{fp, fp, fp}, outputs: []regMask{fp}}
-		fp2flags       = regInfo{inputs: []regMask{fp, fp}}
-		fp1flags       = regInfo{inputs: []regMask{fp}}
-		fpload         = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{fp}}
-		fp2load        = regInfo{inputs: []regMask{gpspsbg, gpg}, outputs: []regMask{fp}}
-		fpstore        = regInfo{inputs: []regMask{gpspsbg, fp}}
-		fpstore2       = regInfo{inputs: []regMask{gpspsbg, gpg, fp}}
-		readflags      = regInfo{inputs: nil, outputs: []regMask{gp}}
-		prefreg        = regInfo{inputs: []regMask{gpspsbg}}
-	)
-	ops := []opData{
-		// binary ops
-		{name: "ADCSflags", argLength: 3, reg: gp2flags1flags, typ: "(UInt64,Flags)", asm: "ADCS", commutative: true}, // arg0+arg1+carry, set flags.
-		{name: "ADCzerocarry", argLength: 1, reg: gp0flags1, typ: "UInt64", asm: "ADC"},                               // ZR+ZR+carry
-		{name: "ADD", argLength: 2, reg: gp21, asm: "ADD", commutative: true},                                         // arg0 + arg1
-		{name: "ADDconst", argLength: 1, reg: gp11sp, asm: "ADD", aux: "Int64"},                                       // arg0 + auxInt
-		{name: "ADDSconstflags", argLength: 1, reg: gp11flags, typ: "(UInt64,Flags)", asm: "ADDS", aux: "Int64"},      // arg0+auxint, set flags.
-		{name: "ADDSflags", argLength: 2, reg: gp21flags, typ: "(UInt64,Flags)", asm: "ADDS", commutative: true},      // arg0+arg1, set flags.
-		{name: "SUB", argLength: 2, reg: gp21, asm: "SUB"},                                                            // arg0 - arg1
-		{name: "SUBconst", argLength: 1, reg: gp11, asm: "SUB", aux: "Int64"},                                         // arg0 - auxInt
-		{name: "SBCSflags", argLength: 3, reg: gp2flags1flags, typ: "(UInt64,Flags)", asm: "SBCS"},                    // arg0-(arg1+borrowing), set flags.
-		{name: "SUBSflags", argLength: 2, reg: gp21flags, typ: "(UInt64,Flags)", asm: "SUBS"},                         // arg0 - arg1, set flags.
-		{name: "MUL", argLength: 2, reg: gp21, asm: "MUL", commutative: true},                                         // arg0 * arg1
-		{name: "MULW", argLength: 2, reg: gp21, asm: "MULW", commutative: true},                                       // arg0 * arg1, 32-bit
-		{name: "MNEG", argLength: 2, reg: gp21, asm: "MNEG", commutative: true},                                       // -arg0 * arg1
-		{name: "MNEGW", argLength: 2, reg: gp21, asm: "MNEGW", commutative: true},                                     // -arg0 * arg1, 32-bit
-		{name: "MULH", argLength: 2, reg: gp21, asm: "SMULH", commutative: true},                                      // (arg0 * arg1) >> 64, signed
-		{name: "UMULH", argLength: 2, reg: gp21, asm: "UMULH", commutative: true},                                     // (arg0 * arg1) >> 64, unsigned
-		{name: "MULL", argLength: 2, reg: gp21, asm: "SMULL", commutative: true},                                      // arg0 * arg1, signed, 32-bit mult results in 64-bit
-		{name: "UMULL", argLength: 2, reg: gp21, asm: "UMULL", commutative: true},                                     // arg0 * arg1, unsigned, 32-bit mult results in 64-bit
-		{name: "DIV", argLength: 2, reg: gp21, asm: "SDIV"},                                                           // arg0 / arg1, signed
-		{name: "UDIV", argLength: 2, reg: gp21, asm: "UDIV"},                                                          // arg0 / arg1, unsighed
-		{name: "DIVW", argLength: 2, reg: gp21, asm: "SDIVW"},                                                         // arg0 / arg1, signed, 32 bit
-		{name: "UDIVW", argLength: 2, reg: gp21, asm: "UDIVW"},                                                        // arg0 / arg1, unsighed, 32 bit
-		{name: "MOD", argLength: 2, reg: gp21, asm: "REM"},                                                            // arg0 % arg1, signed
-		{name: "UMOD", argLength: 2, reg: gp21, asm: "UREM"},                                                          // arg0 % arg1, unsigned
-		{name: "MODW", argLength: 2, reg: gp21, asm: "REMW"},                                                          // arg0 % arg1, signed, 32 bit
-		{name: "UMODW", argLength: 2, reg: gp21, asm: "UREMW"},                                                        // arg0 % arg1, unsigned, 32 bit
-
-		{name: "FADDS", argLength: 2, reg: fp21, asm: "FADDS", commutative: true},   // arg0 + arg1
-		{name: "FADDD", argLength: 2, reg: fp21, asm: "FADDD", commutative: true},   // arg0 + arg1
-		{name: "FSUBS", argLength: 2, reg: fp21, asm: "FSUBS"},                      // arg0 - arg1
-		{name: "FSUBD", argLength: 2, reg: fp21, asm: "FSUBD"},                      // arg0 - arg1
-		{name: "FMULS", argLength: 2, reg: fp21, asm: "FMULS", commutative: true},   // arg0 * arg1
-		{name: "FMULD", argLength: 2, reg: fp21, asm: "FMULD", commutative: true},   // arg0 * arg1
-		{name: "FNMULS", argLength: 2, reg: fp21, asm: "FNMULS", commutative: true}, // -(arg0 * arg1)
-		{name: "FNMULD", argLength: 2, reg: fp21, asm: "FNMULD", commutative: true}, // -(arg0 * arg1)
-		{name: "FDIVS", argLength: 2, reg: fp21, asm: "FDIVS"},                      // arg0 / arg1
-		{name: "FDIVD", argLength: 2, reg: fp21, asm: "FDIVD"},                      // arg0 / arg1
-
-		{name: "AND", argLength: 2, reg: gp21, asm: "AND", commutative: true}, // arg0 & arg1
-		{name: "ANDconst", argLength: 1, reg: gp11, asm: "AND", aux: "Int64"}, // arg0 & auxInt
-		{name: "OR", argLength: 2, reg: gp21, asm: "ORR", commutative: true},  // arg0 | arg1
-		{name: "ORconst", argLength: 1, reg: gp11, asm: "ORR", aux: "Int64"},  // arg0 | auxInt
-		{name: "XOR", argLength: 2, reg: gp21, asm: "EOR", commutative: true}, // arg0 ^ arg1
-		{name: "XORconst", argLength: 1, reg: gp11, asm: "EOR", aux: "Int64"}, // arg0 ^ auxInt
-		{name: "BIC", argLength: 2, reg: gp21, asm: "BIC"},                    // arg0 &^ arg1
-		{name: "EON", argLength: 2, reg: gp21, asm: "EON"},                    // arg0 ^ ^arg1
-		{name: "ORN", argLength: 2, reg: gp21, asm: "ORN"},                    // arg0 | ^arg1
-
-		{name: "LoweredMuluhilo", argLength: 2, reg: gp22, resultNotInArgs: true}, // arg0 * arg1, returns (hi, lo)
-
-		// unary ops
-		{name: "MVN", argLength: 1, reg: gp11, asm: "MVN"},                                    // ^arg0
-		{name: "NEG", argLength: 1, reg: gp11, asm: "NEG"},                                    // -arg0
-		{name: "NEGSflags", argLength: 1, reg: gp11flags, typ: "(UInt64,Flags)", asm: "NEGS"}, // -arg0, set flags.
-		{name: "NGCzerocarry", argLength: 1, reg: gp0flags1, typ: "UInt64", asm: "NGC"},       // -1 if borrowing, 0 otherwise.
-		{name: "FABSD", argLength: 1, reg: fp11, asm: "FABSD"},                                // abs(arg0), float64
-		{name: "FNEGS", argLength: 1, reg: fp11, asm: "FNEGS"},                                // -arg0, float32
-		{name: "FNEGD", argLength: 1, reg: fp11, asm: "FNEGD"},                                // -arg0, float64
-		{name: "FSQRTD", argLength: 1, reg: fp11, asm: "FSQRTD"},                              // sqrt(arg0), float64
-		{name: "FSQRTS", argLength: 1, reg: fp11, asm: "FSQRTS"},                              // sqrt(arg0), float32
-		{name: "REV", argLength: 1, reg: gp11, asm: "REV"},                                    // byte reverse, 64-bit
-		{name: "REVW", argLength: 1, reg: gp11, asm: "REVW"},                                  // byte reverse, 32-bit
-		{name: "REV16", argLength: 1, reg: gp11, asm: "REV16"},                                // byte reverse in each 16-bit halfword, 64-bit
-		{name: "REV16W", argLength: 1, reg: gp11, asm: "REV16W"},                              // byte reverse in each 16-bit halfword, 32-bit
-		{name: "RBIT", argLength: 1, reg: gp11, asm: "RBIT"},                                  // bit reverse, 64-bit
-		{name: "RBITW", argLength: 1, reg: gp11, asm: "RBITW"},                                // bit reverse, 32-bit
-		{name: "CLZ", argLength: 1, reg: gp11, asm: "CLZ"},                                    // count leading zero, 64-bit
-		{name: "CLZW", argLength: 1, reg: gp11, asm: "CLZW"},                                  // count leading zero, 32-bit
-		{name: "VCNT", argLength: 1, reg: fp11, asm: "VCNT"},                                  // count set bits for each 8-bit unit and store the result in each 8-bit unit
-		{name: "VUADDLV", argLength: 1, reg: fp11, asm: "VUADDLV"},                            // unsigned sum of eight bytes in a 64-bit value, zero extended to 64-bit.
-		{name: "LoweredRound32F", argLength: 1, reg: fp11, resultInArg0: true, zeroWidth: true},
-		{name: "LoweredRound64F", argLength: 1, reg: fp11, resultInArg0: true, zeroWidth: true},
-
-		// 3-operand, the addend comes first
-		{name: "FMADDS", argLength: 3, reg: fp31, asm: "FMADDS"},   // +arg0 + (arg1 * arg2)
-		{name: "FMADDD", argLength: 3, reg: fp31, asm: "FMADDD"},   // +arg0 + (arg1 * arg2)
-		{name: "FNMADDS", argLength: 3, reg: fp31, asm: "FNMADDS"}, // -arg0 - (arg1 * arg2)
-		{name: "FNMADDD", argLength: 3, reg: fp31, asm: "FNMADDD"}, // -arg0 - (arg1 * arg2)
-		{name: "FMSUBS", argLength: 3, reg: fp31, asm: "FMSUBS"},   // +arg0 - (arg1 * arg2)
-		{name: "FMSUBD", argLength: 3, reg: fp31, asm: "FMSUBD"},   // +arg0 - (arg1 * arg2)
-		{name: "FNMSUBS", argLength: 3, reg: fp31, asm: "FNMSUBS"}, // -arg0 + (arg1 * arg2)
-		{name: "FNMSUBD", argLength: 3, reg: fp31, asm: "FNMSUBD"}, // -arg0 + (arg1 * arg2)
-		{name: "MADD", argLength: 3, reg: gp31, asm: "MADD"},       // +arg0 + (arg1 * arg2)
-		{name: "MADDW", argLength: 3, reg: gp31, asm: "MADDW"},     // +arg0 + (arg1 * arg2), 32-bit
-		{name: "MSUB", argLength: 3, reg: gp31, asm: "MSUB"},       // +arg0 - (arg1 * arg2)
-		{name: "MSUBW", argLength: 3, reg: gp31, asm: "MSUBW"},     // +arg0 - (arg1 * arg2), 32-bit
-
-		// shifts
-		{name: "SLL", argLength: 2, reg: gp21, asm: "LSL"},                        // arg0 << arg1, shift amount is mod 64
-		{name: "SLLconst", argLength: 1, reg: gp11, asm: "LSL", aux: "Int64"},     // arg0 << auxInt, auxInt should be in the range 0 to 63.
-		{name: "SRL", argLength: 2, reg: gp21, asm: "LSR"},                        // arg0 >> arg1, unsigned, shift amount is mod 64
-		{name: "SRLconst", argLength: 1, reg: gp11, asm: "LSR", aux: "Int64"},     // arg0 >> auxInt, unsigned, auxInt should be in the range 0 to 63.
-		{name: "SRA", argLength: 2, reg: gp21, asm: "ASR"},                        // arg0 >> arg1, signed, shift amount is mod 64
-		{name: "SRAconst", argLength: 1, reg: gp11, asm: "ASR", aux: "Int64"},     // arg0 >> auxInt, signed, auxInt should be in the range 0 to 63.
-		{name: "ROR", argLength: 2, reg: gp21, asm: "ROR"},                        // arg0 right rotate by (arg1 mod 64) bits
-		{name: "RORW", argLength: 2, reg: gp21, asm: "RORW"},                      // arg0 right rotate by (arg1 mod 32) bits
-		{name: "RORconst", argLength: 1, reg: gp11, asm: "ROR", aux: "Int64"},     // arg0 right rotate by auxInt bits, auxInt should be in the range 0 to 63.
-		{name: "RORWconst", argLength: 1, reg: gp11, asm: "RORW", aux: "Int64"},   // uint32(arg0) right rotate by auxInt bits, auxInt should be in the range 0 to 31.
-		{name: "EXTRconst", argLength: 2, reg: gp21, asm: "EXTR", aux: "Int64"},   // extract 64 bits from arg0:arg1 starting at lsb auxInt, auxInt should be in the range 0 to 63.
-		{name: "EXTRWconst", argLength: 2, reg: gp21, asm: "EXTRW", aux: "Int64"}, // extract 32 bits from arg0[31:0]:arg1[31:0] starting at lsb auxInt and zero top 32 bits, auxInt should be in the range 0 to 31.
-
-		// comparisons
-		{name: "CMP", argLength: 2, reg: gp2flags, asm: "CMP", typ: "Flags"},                      // arg0 compare to arg1
-		{name: "CMPconst", argLength: 1, reg: gp1flags, asm: "CMP", aux: "Int64", typ: "Flags"},   // arg0 compare to auxInt
-		{name: "CMPW", argLength: 2, reg: gp2flags, asm: "CMPW", typ: "Flags"},                    // arg0 compare to arg1, 32 bit
-		{name: "CMPWconst", argLength: 1, reg: gp1flags, asm: "CMPW", aux: "Int32", typ: "Flags"}, // arg0 compare to auxInt, 32 bit
-		{name: "CMN", argLength: 2, reg: gp2flags, asm: "CMN", typ: "Flags", commutative: true},   // arg0 compare to -arg1, provided arg1 is not 1<<63
-		{name: "CMNconst", argLength: 1, reg: gp1flags, asm: "CMN", aux: "Int64", typ: "Flags"},   // arg0 compare to -auxInt
-		{name: "CMNW", argLength: 2, reg: gp2flags, asm: "CMNW", typ: "Flags", commutative: true}, // arg0 compare to -arg1, 32 bit, provided arg1 is not 1<<31
-		{name: "CMNWconst", argLength: 1, reg: gp1flags, asm: "CMNW", aux: "Int32", typ: "Flags"}, // arg0 compare to -auxInt, 32 bit
-		{name: "TST", argLength: 2, reg: gp2flags, asm: "TST", typ: "Flags", commutative: true},   // arg0 & arg1 compare to 0
-		{name: "TSTconst", argLength: 1, reg: gp1flags, asm: "TST", aux: "Int64", typ: "Flags"},   // arg0 & auxInt compare to 0
-		{name: "TSTW", argLength: 2, reg: gp2flags, asm: "TSTW", typ: "Flags", commutative: true}, // arg0 & arg1 compare to 0, 32 bit
-		{name: "TSTWconst", argLength: 1, reg: gp1flags, asm: "TSTW", aux: "Int32", typ: "Flags"}, // arg0 & auxInt compare to 0, 32 bit
-		{name: "FCMPS", argLength: 2, reg: fp2flags, asm: "FCMPS", typ: "Flags"},                  // arg0 compare to arg1, float32
-		{name: "FCMPD", argLength: 2, reg: fp2flags, asm: "FCMPD", typ: "Flags"},                  // arg0 compare to arg1, float64
-		{name: "FCMPS0", argLength: 1, reg: fp1flags, asm: "FCMPS", typ: "Flags"},                 // arg0 compare to 0, float32
-		{name: "FCMPD0", argLength: 1, reg: fp1flags, asm: "FCMPD", typ: "Flags"},                 // arg0 compare to 0, float64
-
-		// shifted ops
-		{name: "MVNshiftLL", argLength: 1, reg: gp11, asm: "MVN", aux: "Int64"},                   // ^(arg0<<auxInt), auxInt should be in the range 0 to 63.
-		{name: "MVNshiftRL", argLength: 1, reg: gp11, asm: "MVN", aux: "Int64"},                   // ^(arg0>>auxInt), unsigned shift, auxInt should be in the range 0 to 63.
-		{name: "MVNshiftRA", argLength: 1, reg: gp11, asm: "MVN", aux: "Int64"},                   // ^(arg0>>auxInt), signed shift, auxInt should be in the range 0 to 63.
-		{name: "MVNshiftRO", argLength: 1, reg: gp11, asm: "MVN", aux: "Int64"},                   // ^(arg0 ROR auxInt), signed shift, auxInt should be in the range 0 to 63.
-		{name: "NEGshiftLL", argLength: 1, reg: gp11, asm: "NEG", aux: "Int64"},                   // -(arg0<<auxInt), auxInt should be in the range 0 to 63.
-		{name: "NEGshiftRL", argLength: 1, reg: gp11, asm: "NEG", aux: "Int64"},                   // -(arg0>>auxInt), unsigned shift, auxInt should be in the range 0 to 63.
-		{name: "NEGshiftRA", argLength: 1, reg: gp11, asm: "NEG", aux: "Int64"},                   // -(arg0>>auxInt), signed shift, auxInt should be in the range 0 to 63.
-		{name: "ADDshiftLL", argLength: 2, reg: gp21, asm: "ADD", aux: "Int64"},                   // arg0 + arg1<<auxInt, auxInt should be in the range 0 to 63.
-		{name: "ADDshiftRL", argLength: 2, reg: gp21, asm: "ADD", aux: "Int64"},                   // arg0 + arg1>>auxInt, unsigned shift, auxInt should be in the range 0 to 63.
-		{name: "ADDshiftRA", argLength: 2, reg: gp21, asm: "ADD", aux: "Int64"},                   // arg0 + arg1>>auxInt, signed shift, auxInt should be in the range 0 to 63.
-		{name: "SUBshiftLL", argLength: 2, reg: gp21, asm: "SUB", aux: "Int64"},                   // arg0 - arg1<<auxInt, auxInt should be in the range 0 to 63.
-		{name: "SUBshiftRL", argLength: 2, reg: gp21, asm: "SUB", aux: "Int64"},                   // arg0 - arg1>>auxInt, unsigned shift, auxInt should be in the range 0 to 63.
-		{name: "SUBshiftRA", argLength: 2, reg: gp21, asm: "SUB", aux: "Int64"},                   // arg0 - arg1>>auxInt, signed shift, auxInt should be in the range 0 to 63.
-		{name: "ANDshiftLL", argLength: 2, reg: gp21, asm: "AND", aux: "Int64"},                   // arg0 & (arg1<<auxInt), auxInt should be in the range 0 to 63.
-		{name: "ANDshiftRL", argLength: 2, reg: gp21, asm: "AND", aux: "Int64"},                   // arg0 & (arg1>>auxInt), unsigned shift, auxInt should be in the range 0 to 63.
-		{name: "ANDshiftRA", argLength: 2, reg: gp21, asm: "AND", aux: "Int64"},                   // arg0 & (arg1>>auxInt), signed shift, auxInt should be in the range 0 to 63.
-		{name: "ANDshiftRO", argLength: 2, reg: gp21, asm: "AND", aux: "Int64"},                   // arg0 & (arg1 ROR auxInt), signed shift, auxInt should be in the range 0 to 63.
-		{name: "ORshiftLL", argLength: 2, reg: gp21, asm: "ORR", aux: "Int64"},                    // arg0 | arg1<<auxInt, auxInt should be in the range 0 to 63.
-		{name: "ORshiftRL", argLength: 2, reg: gp21, asm: "ORR", aux: "Int64"},                    // arg0 | arg1>>auxInt, unsigned shift, auxInt should be in the range 0 to 63.
-		{name: "ORshiftRA", argLength: 2, reg: gp21, asm: "ORR", aux: "Int64"},                    // arg0 | arg1>>auxInt, signed shift, auxInt should be in the range 0 to 63.
-		{name: "ORshiftRO", argLength: 2, reg: gp21, asm: "ORR", aux: "Int64"},                    // arg0 | arg1 ROR auxInt, signed shift, auxInt should be in the range 0 to 63.
-		{name: "XORshiftLL", argLength: 2, reg: gp21, asm: "EOR", aux: "Int64"},                   // arg0 ^ arg1<<auxInt, auxInt should be in the range 0 to 63.
-		{name: "XORshiftRL", argLength: 2, reg: gp21, asm: "EOR", aux: "Int64"},                   // arg0 ^ arg1>>auxInt, unsigned shift, auxInt should be in the range 0 to 63.
-		{name: "XORshiftRA", argLength: 2, reg: gp21, asm: "EOR", aux: "Int64"},                   // arg0 ^ arg1>>auxInt, signed shift, auxInt should be in the range 0 to 63.
-		{name: "XORshiftRO", argLength: 2, reg: gp21, asm: "EOR", aux: "Int64"},                   // arg0 ^ arg1 ROR auxInt, signed shift, auxInt should be in the range 0 to 63.
-		{name: "BICshiftLL", argLength: 2, reg: gp21, asm: "BIC", aux: "Int64"},                   // arg0 &^ (arg1<<auxInt), auxInt should be in the range 0 to 63.
-		{name: "BICshiftRL", argLength: 2, reg: gp21, asm: "BIC", aux: "Int64"},                   // arg0 &^ (arg1>>auxInt), unsigned shift, auxInt should be in the range 0 to 63.
-		{name: "BICshiftRA", argLength: 2, reg: gp21, asm: "BIC", aux: "Int64"},                   // arg0 &^ (arg1>>auxInt), signed shift, auxInt should be in the range 0 to 63.
-		{name: "BICshiftRO", argLength: 2, reg: gp21, asm: "BIC", aux: "Int64"},                   // arg0 &^ (arg1 ROR auxInt), signed shift, auxInt should be in the range 0 to 63.
-		{name: "EONshiftLL", argLength: 2, reg: gp21, asm: "EON", aux: "Int64"},                   // arg0 ^ ^(arg1<<auxInt), auxInt should be in the range 0 to 63.
-		{name: "EONshiftRL", argLength: 2, reg: gp21, asm: "EON", aux: "Int64"},                   // arg0 ^ ^(arg1>>auxInt), unsigned shift, auxInt should be in the range 0 to 63.
-		{name: "EONshiftRA", argLength: 2, reg: gp21, asm: "EON", aux: "Int64"},                   // arg0 ^ ^(arg1>>auxInt), signed shift, auxInt should be in the range 0 to 63.
-		{name: "EONshiftRO", argLength: 2, reg: gp21, asm: "EON", aux: "Int64"},                   // arg0 ^ ^(arg1 ROR auxInt), signed shift, auxInt should be in the range 0 to 63.
-		{name: "ORNshiftLL", argLength: 2, reg: gp21, asm: "ORN", aux: "Int64"},                   // arg0 | ^(arg1<<auxInt), auxInt should be in the range 0 to 63.
-		{name: "ORNshiftRL", argLength: 2, reg: gp21, asm: "ORN", aux: "Int64"},                   // arg0 | ^(arg1>>auxInt), unsigned shift, auxInt should be in the range 0 to 63.
-		{name: "ORNshiftRA", argLength: 2, reg: gp21, asm: "ORN", aux: "Int64"},                   // arg0 | ^(arg1>>auxInt), signed shift, auxInt should be in the range 0 to 63.
-		{name: "ORNshiftRO", argLength: 2, reg: gp21, asm: "ORN", aux: "Int64"},                   // arg0 | ^(arg1 ROR auxInt), signed shift, auxInt should be in the range 0 to 63.
-		{name: "CMPshiftLL", argLength: 2, reg: gp2flags, asm: "CMP", aux: "Int64", typ: "Flags"}, // arg0 compare to arg1<<auxInt, auxInt should be in the range 0 to 63.
-		{name: "CMPshiftRL", argLength: 2, reg: gp2flags, asm: "CMP", aux: "Int64", typ: "Flags"}, // arg0 compare to arg1>>auxInt, unsigned shift, auxInt should be in the range 0 to 63.
-		{name: "CMPshiftRA", argLength: 2, reg: gp2flags, asm: "CMP", aux: "Int64", typ: "Flags"}, // arg0 compare to arg1>>auxInt, signed shift, auxInt should be in the range 0 to 63.
-		{name: "CMNshiftLL", argLength: 2, reg: gp2flags, asm: "CMN", aux: "Int64", typ: "Flags"}, // (arg0 + arg1<<auxInt) compare to 0, auxInt should be in the range 0 to 63.
-		{name: "CMNshiftRL", argLength: 2, reg: gp2flags, asm: "CMN", aux: "Int64", typ: "Flags"}, // (arg0 + arg1>>auxInt) compare to 0, unsigned shift, auxInt should be in the range 0 to 63.
-		{name: "CMNshiftRA", argLength: 2, reg: gp2flags, asm: "CMN", aux: "Int64", typ: "Flags"}, // (arg0 + arg1>>auxInt) compare to 0, signed shift, auxInt should be in the range 0 to 63.
-		{name: "TSTshiftLL", argLength: 2, reg: gp2flags, asm: "TST", aux: "Int64", typ: "Flags"}, // (arg0 & arg1<<auxInt) compare to 0, auxInt should be in the range 0 to 63.
-		{name: "TSTshiftRL", argLength: 2, reg: gp2flags, asm: "TST", aux: "Int64", typ: "Flags"}, // (arg0 & arg1>>auxInt) compare to 0, unsigned shift, auxInt should be in the range 0 to 63.
-		{name: "TSTshiftRA", argLength: 2, reg: gp2flags, asm: "TST", aux: "Int64", typ: "Flags"}, // (arg0 & arg1>>auxInt) compare to 0, signed shift, auxInt should be in the range 0 to 63.
-		{name: "TSTshiftRO", argLength: 2, reg: gp2flags, asm: "TST", aux: "Int64", typ: "Flags"}, // (arg0 & arg1 ROR auxInt) compare to 0, signed shift, auxInt should be in the range 0 to 63.
-
-		// bitfield ops
-		// for all bitfield ops lsb is auxInt>>8, width is auxInt&0xff
-		// insert low width bits of arg1 into the result starting at bit lsb, copy other bits from arg0
-		{name: "BFI", argLength: 2, reg: gp21nog, asm: "BFI", aux: "ARM64BitField", resultInArg0: true},
-		// extract width bits of arg1 starting at bit lsb and insert at low end of result, copy other bits from arg0
-		{name: "BFXIL", argLength: 2, reg: gp21nog, asm: "BFXIL", aux: "ARM64BitField", resultInArg0: true},
-		// insert low width bits of arg0 into the result starting at bit lsb, bits to the left of the inserted bit field are set to the high/sign bit of the inserted bit field, bits to the right are zeroed
-		{name: "SBFIZ", argLength: 1, reg: gp11, asm: "SBFIZ", aux: "ARM64BitField"},
-		// extract width bits of arg0 starting at bit lsb and insert at low end of result, remaining high bits are set to the high/sign bit of the extracted bitfield
-		{name: "SBFX", argLength: 1, reg: gp11, asm: "SBFX", aux: "ARM64BitField"},
-		// insert low width bits of arg0 into the result starting at bit lsb, bits to the left and right of the inserted bit field are zeroed
-		{name: "UBFIZ", argLength: 1, reg: gp11, asm: "UBFIZ", aux: "ARM64BitField"},
-		// extract width bits of arg0 starting at bit lsb and insert at low end of result, remaining high bits are zeroed
-		{name: "UBFX", argLength: 1, reg: gp11, asm: "UBFX", aux: "ARM64BitField"},
-
-		// moves
-		{name: "MOVDconst", argLength: 0, reg: gp01, aux: "Int64", asm: "MOVD", typ: "UInt64", rematerializeable: true},      // 64 bits from auxint
-		{name: "FMOVSconst", argLength: 0, reg: fp01, aux: "Float64", asm: "FMOVS", typ: "Float32", rematerializeable: true}, // auxint as 64-bit float, convert to 32-bit float
-		{name: "FMOVDconst", argLength: 0, reg: fp01, aux: "Float64", asm: "FMOVD", typ: "Float64", rematerializeable: true}, // auxint as 64-bit float
-
-		{name: "MOVDaddr", argLength: 1, reg: regInfo{inputs: []regMask{buildReg("SP") | buildReg("SB")}, outputs: []regMask{gp}}, aux: "SymOff", asm: "MOVD", rematerializeable: true, symEffect: "Addr"}, // arg0 + auxInt + aux.(*gc.Sym), arg0=SP/SB
-
-		{name: "MOVBload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVB", typ: "Int8", faultOnNilArg0: true, symEffect: "Read"},      // load from arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVBUload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVBU", typ: "UInt8", faultOnNilArg0: true, symEffect: "Read"},   // load from arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVHload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVH", typ: "Int16", faultOnNilArg0: true, symEffect: "Read"},     // load from arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVHUload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVHU", typ: "UInt16", faultOnNilArg0: true, symEffect: "Read"},  // load from arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVWload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVW", typ: "Int32", faultOnNilArg0: true, symEffect: "Read"},     // load from arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVWUload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVWU", typ: "UInt32", faultOnNilArg0: true, symEffect: "Read"},  // load from arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVDload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVD", typ: "UInt64", faultOnNilArg0: true, symEffect: "Read"},    // load from arg0 + auxInt + aux.  arg1=mem.
-		{name: "FMOVSload", argLength: 2, reg: fpload, aux: "SymOff", asm: "FMOVS", typ: "Float32", faultOnNilArg0: true, symEffect: "Read"}, // load from arg0 + auxInt + aux.  arg1=mem.
-		{name: "FMOVDload", argLength: 2, reg: fpload, aux: "SymOff", asm: "FMOVD", typ: "Float64", faultOnNilArg0: true, symEffect: "Read"}, // load from arg0 + auxInt + aux.  arg1=mem.
-
-		// register indexed load
-		{name: "MOVDloadidx", argLength: 3, reg: gp2load, asm: "MOVD", typ: "UInt64"},    // load 64-bit dword from arg0 + arg1, arg2 = mem.
-		{name: "MOVWloadidx", argLength: 3, reg: gp2load, asm: "MOVW", typ: "Int32"},     // load 32-bit word from arg0 + arg1, sign-extended to 64-bit, arg2=mem.
-		{name: "MOVWUloadidx", argLength: 3, reg: gp2load, asm: "MOVWU", typ: "UInt32"},  // load 32-bit word from arg0 + arg1, zero-extended to 64-bit, arg2=mem.
-		{name: "MOVHloadidx", argLength: 3, reg: gp2load, asm: "MOVH", typ: "Int16"},     // load 16-bit word from arg0 + arg1, sign-extended to 64-bit, arg2=mem.
-		{name: "MOVHUloadidx", argLength: 3, reg: gp2load, asm: "MOVHU", typ: "UInt16"},  // load 16-bit word from arg0 + arg1, zero-extended to 64-bit, arg2=mem.
-		{name: "MOVBloadidx", argLength: 3, reg: gp2load, asm: "MOVB", typ: "Int8"},      // load 8-bit word from arg0 + arg1, sign-extended to 64-bit, arg2=mem.
-		{name: "MOVBUloadidx", argLength: 3, reg: gp2load, asm: "MOVBU", typ: "UInt8"},   // load 8-bit word from arg0 + arg1, zero-extended to 64-bit, arg2=mem.
-		{name: "FMOVSloadidx", argLength: 3, reg: fp2load, asm: "FMOVS", typ: "Float32"}, // load 32-bit float from arg0 + arg1, arg2=mem.
-		{name: "FMOVDloadidx", argLength: 3, reg: fp2load, asm: "FMOVD", typ: "Float64"}, // load 64-bit float from arg0 + arg1, arg2=mem.
-
-		// shifted register indexed load
-		{name: "MOVHloadidx2", argLength: 3, reg: gp2load, asm: "MOVH", typ: "Int16"},     // load 16-bit half-word from arg0 + arg1*2, sign-extended to 64-bit, arg2=mem.
-		{name: "MOVHUloadidx2", argLength: 3, reg: gp2load, asm: "MOVHU", typ: "UInt16"},  // load 16-bit half-word from arg0 + arg1*2, zero-extended to 64-bit, arg2=mem.
-		{name: "MOVWloadidx4", argLength: 3, reg: gp2load, asm: "MOVW", typ: "Int32"},     // load 32-bit word from arg0 + arg1*4, sign-extended to 64-bit, arg2=mem.
-		{name: "MOVWUloadidx4", argLength: 3, reg: gp2load, asm: "MOVWU", typ: "UInt32"},  // load 32-bit word from arg0 + arg1*4, zero-extended to 64-bit, arg2=mem.
-		{name: "MOVDloadidx8", argLength: 3, reg: gp2load, asm: "MOVD", typ: "UInt64"},    // load 64-bit double-word from arg0 + arg1*8, arg2 = mem.
-		{name: "FMOVSloadidx4", argLength: 3, reg: fp2load, asm: "FMOVS", typ: "Float32"}, // load 32-bit float from arg0 + arg1*4, arg2 = mem.
-		{name: "FMOVDloadidx8", argLength: 3, reg: fp2load, asm: "FMOVD", typ: "Float64"}, // load 64-bit float from arg0 + arg1*8, arg2 = mem.
-
-		{name: "MOVBstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVB", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},   // store 1 byte of arg1 to arg0 + auxInt + aux.  arg2=mem.
-		{name: "MOVHstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVH", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},   // store 2 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
-		{name: "MOVWstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVW", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},   // store 4 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
-		{name: "MOVDstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVD", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},   // store 8 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
-		{name: "STP", argLength: 4, reg: gpstore2, aux: "SymOff", asm: "STP", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},         // store 16 bytes of arg1 and arg2 to arg0 + auxInt + aux.  arg3=mem.
-		{name: "FMOVSstore", argLength: 3, reg: fpstore, aux: "SymOff", asm: "FMOVS", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
-		{name: "FMOVDstore", argLength: 3, reg: fpstore, aux: "SymOff", asm: "FMOVD", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
-
-		// register indexed store
-		{name: "MOVBstoreidx", argLength: 4, reg: gpstore2, asm: "MOVB", typ: "Mem"},   // store 1 byte of arg2 to arg0 + arg1, arg3 = mem.
-		{name: "MOVHstoreidx", argLength: 4, reg: gpstore2, asm: "MOVH", typ: "Mem"},   // store 2 bytes of arg2 to arg0 + arg1, arg3 = mem.
-		{name: "MOVWstoreidx", argLength: 4, reg: gpstore2, asm: "MOVW", typ: "Mem"},   // store 4 bytes of arg2 to arg0 + arg1, arg3 = mem.
-		{name: "MOVDstoreidx", argLength: 4, reg: gpstore2, asm: "MOVD", typ: "Mem"},   // store 8 bytes of arg2 to arg0 + arg1, arg3 = mem.
-		{name: "FMOVSstoreidx", argLength: 4, reg: fpstore2, asm: "FMOVS", typ: "Mem"}, // store 32-bit float of arg2 to arg0 + arg1, arg3=mem.
-		{name: "FMOVDstoreidx", argLength: 4, reg: fpstore2, asm: "FMOVD", typ: "Mem"}, // store 64-bit float of arg2 to arg0 + arg1, arg3=mem.
-
-		// shifted register indexed store
-		{name: "MOVHstoreidx2", argLength: 4, reg: gpstore2, asm: "MOVH", typ: "Mem"},   // store 2 bytes of arg2 to arg0 + arg1*2, arg3 = mem.
-		{name: "MOVWstoreidx4", argLength: 4, reg: gpstore2, asm: "MOVW", typ: "Mem"},   // store 4 bytes of arg2 to arg0 + arg1*4, arg3 = mem.
-		{name: "MOVDstoreidx8", argLength: 4, reg: gpstore2, asm: "MOVD", typ: "Mem"},   // store 8 bytes of arg2 to arg0 + arg1*8, arg3 = mem.
-		{name: "FMOVSstoreidx4", argLength: 4, reg: fpstore2, asm: "FMOVS", typ: "Mem"}, // store 32-bit float of arg2 to arg0 + arg1*4, arg3=mem.
-		{name: "FMOVDstoreidx8", argLength: 4, reg: fpstore2, asm: "FMOVD", typ: "Mem"}, // store 64-bit float of arg2 to arg0 + arg1*8, arg3=mem.
-
-		{name: "MOVBstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVB", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 1 byte of zero to arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVHstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVH", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 2 bytes of zero to arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVWstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVW", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes of zero to arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVDstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVD", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes of zero to arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVQstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "STP", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},  // store 16 bytes of zero to arg0 + auxInt + aux.  arg1=mem.
-
-		// register indexed store zero
-		{name: "MOVBstorezeroidx", argLength: 3, reg: gpstore, asm: "MOVB", typ: "Mem"}, // store 1 byte of zero to arg0 + arg1, arg2 = mem.
-		{name: "MOVHstorezeroidx", argLength: 3, reg: gpstore, asm: "MOVH", typ: "Mem"}, // store 2 bytes of zero to arg0 + arg1, arg2 = mem.
-		{name: "MOVWstorezeroidx", argLength: 3, reg: gpstore, asm: "MOVW", typ: "Mem"}, // store 4 bytes of zero to arg0 + arg1, arg2 = mem.
-		{name: "MOVDstorezeroidx", argLength: 3, reg: gpstore, asm: "MOVD", typ: "Mem"}, // store 8 bytes of zero to arg0 + arg1, arg2 = mem.
-
-		// shifted register indexed store zero
-		{name: "MOVHstorezeroidx2", argLength: 3, reg: gpstore, asm: "MOVH", typ: "Mem"}, // store 2 bytes of zero to arg0 + arg1*2, arg2 = mem.
-		{name: "MOVWstorezeroidx4", argLength: 3, reg: gpstore, asm: "MOVW", typ: "Mem"}, // store 4 bytes of zero to arg0 + arg1*4, arg2 = mem.
-		{name: "MOVDstorezeroidx8", argLength: 3, reg: gpstore, asm: "MOVD", typ: "Mem"}, // store 8 bytes of zero to arg0 + arg1*8, arg2 = mem.
-
-		{name: "FMOVDgpfp", argLength: 1, reg: gpfp, asm: "FMOVD"}, // move int64 to float64 (no conversion)
-		{name: "FMOVDfpgp", argLength: 1, reg: fpgp, asm: "FMOVD"}, // move float64 to int64 (no conversion)
-		{name: "FMOVSgpfp", argLength: 1, reg: gpfp, asm: "FMOVS"}, // move 32bits from int to float reg (no conversion)
-		{name: "FMOVSfpgp", argLength: 1, reg: fpgp, asm: "FMOVS"}, // move 32bits from float to int reg, zero extend (no conversion)
-
-		// conversions
-		{name: "MOVBreg", argLength: 1, reg: gp11, asm: "MOVB"},   // move from arg0, sign-extended from byte
-		{name: "MOVBUreg", argLength: 1, reg: gp11, asm: "MOVBU"}, // move from arg0, unsign-extended from byte
-		{name: "MOVHreg", argLength: 1, reg: gp11, asm: "MOVH"},   // move from arg0, sign-extended from half
-		{name: "MOVHUreg", argLength: 1, reg: gp11, asm: "MOVHU"}, // move from arg0, unsign-extended from half
-		{name: "MOVWreg", argLength: 1, reg: gp11, asm: "MOVW"},   // move from arg0, sign-extended from word
-		{name: "MOVWUreg", argLength: 1, reg: gp11, asm: "MOVWU"}, // move from arg0, unsign-extended from word
-		{name: "MOVDreg", argLength: 1, reg: gp11, asm: "MOVD"},   // move from arg0
-
-		{name: "MOVDnop", argLength: 1, reg: regInfo{inputs: []regMask{gp}, outputs: []regMask{gp}}, resultInArg0: true}, // nop, return arg0 in same register
-
-		{name: "SCVTFWS", argLength: 1, reg: gpfp, asm: "SCVTFWS"},   // int32 -> float32
-		{name: "SCVTFWD", argLength: 1, reg: gpfp, asm: "SCVTFWD"},   // int32 -> float64
-		{name: "UCVTFWS", argLength: 1, reg: gpfp, asm: "UCVTFWS"},   // uint32 -> float32
-		{name: "UCVTFWD", argLength: 1, reg: gpfp, asm: "UCVTFWD"},   // uint32 -> float64
-		{name: "SCVTFS", argLength: 1, reg: gpfp, asm: "SCVTFS"},     // int64 -> float32
-		{name: "SCVTFD", argLength: 1, reg: gpfp, asm: "SCVTFD"},     // int64 -> float64
-		{name: "UCVTFS", argLength: 1, reg: gpfp, asm: "UCVTFS"},     // uint64 -> float32
-		{name: "UCVTFD", argLength: 1, reg: gpfp, asm: "UCVTFD"},     // uint64 -> float64
-		{name: "FCVTZSSW", argLength: 1, reg: fpgp, asm: "FCVTZSSW"}, // float32 -> int32
-		{name: "FCVTZSDW", argLength: 1, reg: fpgp, asm: "FCVTZSDW"}, // float64 -> int32
-		{name: "FCVTZUSW", argLength: 1, reg: fpgp, asm: "FCVTZUSW"}, // float32 -> uint32
-		{name: "FCVTZUDW", argLength: 1, reg: fpgp, asm: "FCVTZUDW"}, // float64 -> uint32
-		{name: "FCVTZSS", argLength: 1, reg: fpgp, asm: "FCVTZSS"},   // float32 -> int64
-		{name: "FCVTZSD", argLength: 1, reg: fpgp, asm: "FCVTZSD"},   // float64 -> int64
-		{name: "FCVTZUS", argLength: 1, reg: fpgp, asm: "FCVTZUS"},   // float32 -> uint64
-		{name: "FCVTZUD", argLength: 1, reg: fpgp, asm: "FCVTZUD"},   // float64 -> uint64
-		{name: "FCVTSD", argLength: 1, reg: fp11, asm: "FCVTSD"},     // float32 -> float64
-		{name: "FCVTDS", argLength: 1, reg: fp11, asm: "FCVTDS"},     // float64 -> float32
-
-		// floating-point round to integral
-		{name: "FRINTAD", argLength: 1, reg: fp11, asm: "FRINTAD"},
-		{name: "FRINTMD", argLength: 1, reg: fp11, asm: "FRINTMD"},
-		{name: "FRINTND", argLength: 1, reg: fp11, asm: "FRINTND"},
-		{name: "FRINTPD", argLength: 1, reg: fp11, asm: "FRINTPD"},
-		{name: "FRINTZD", argLength: 1, reg: fp11, asm: "FRINTZD"},
-
-		// conditional instructions; auxint is
-		// one of the arm64 comparison pseudo-ops (LessThan, LessThanU, etc.)
-		{name: "CSEL", argLength: 3, reg: gp2flags1, asm: "CSEL", aux: "CCop"},   // auxint(flags) ? arg0 : arg1
-		{name: "CSEL0", argLength: 2, reg: gp1flags1, asm: "CSEL", aux: "CCop"},  // auxint(flags) ? arg0 : 0
-		{name: "CSINC", argLength: 3, reg: gp2flags1, asm: "CSINC", aux: "CCop"}, // auxint(flags) ? arg0 : arg1 + 1
-		{name: "CSINV", argLength: 3, reg: gp2flags1, asm: "CSINV", aux: "CCop"}, // auxint(flags) ? arg0 : ^arg1
-		{name: "CSNEG", argLength: 3, reg: gp2flags1, asm: "CSNEG", aux: "CCop"}, // auxint(flags) ? arg0 : -arg1
-		{name: "CSETM", argLength: 1, reg: readflags, asm: "CSETM", aux: "CCop"}, // auxint(flags) ? -1 : 0
-
-		// function calls
-		{name: "CALLstatic", argLength: -1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                                               // call static function aux.(*obj.LSym).  last arg=mem, auxint=argsize, returns mem
-		{name: "CALLtail", argLength: -1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true, tailCall: true},                                 // tail call static function aux.(*obj.LSym).  last arg=mem, auxint=argsize, returns mem
-		{name: "CALLclosure", argLength: -1, reg: regInfo{inputs: []regMask{gpsp, buildReg("R26"), 0}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call function via closure.  arg0=codeptr, arg1=closure, last arg=mem, auxint=argsize, returns mem
-		{name: "CALLinter", argLength: -1, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                         // call fn by pointer.  arg0=codeptr, last arg=mem, auxint=argsize, returns mem
-
-		// pseudo-ops
-		{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpg}}, nilCheck: true, faultOnNilArg0: true}, // panic if arg0 is nil.  arg1=mem.
-
-		{name: "Equal", argLength: 1, reg: readflags},            // bool, true flags encode x==y false otherwise.
-		{name: "NotEqual", argLength: 1, reg: readflags},         // bool, true flags encode x!=y false otherwise.
-		{name: "LessThan", argLength: 1, reg: readflags},         // bool, true flags encode signed x<y false otherwise.
-		{name: "LessEqual", argLength: 1, reg: readflags},        // bool, true flags encode signed x<=y false otherwise.
-		{name: "GreaterThan", argLength: 1, reg: readflags},      // bool, true flags encode signed x>y false otherwise.
-		{name: "GreaterEqual", argLength: 1, reg: readflags},     // bool, true flags encode signed x>=y false otherwise.
-		{name: "LessThanU", argLength: 1, reg: readflags},        // bool, true flags encode unsigned x<y false otherwise.
-		{name: "LessEqualU", argLength: 1, reg: readflags},       // bool, true flags encode unsigned x<=y false otherwise.
-		{name: "GreaterThanU", argLength: 1, reg: readflags},     // bool, true flags encode unsigned x>y false otherwise.
-		{name: "GreaterEqualU", argLength: 1, reg: readflags},    // bool, true flags encode unsigned x>=y false otherwise.
-		{name: "LessThanF", argLength: 1, reg: readflags},        // bool, true flags encode floating-point x<y false otherwise.
-		{name: "LessEqualF", argLength: 1, reg: readflags},       // bool, true flags encode floating-point x<=y false otherwise.
-		{name: "GreaterThanF", argLength: 1, reg: readflags},     // bool, true flags encode floating-point x>y false otherwise.
-		{name: "GreaterEqualF", argLength: 1, reg: readflags},    // bool, true flags encode floating-point x>=y false otherwise.
-		{name: "NotLessThanF", argLength: 1, reg: readflags},     // bool, true flags encode floating-point x>=y || x is unordered with y, false otherwise.
-		{name: "NotLessEqualF", argLength: 1, reg: readflags},    // bool, true flags encode floating-point x>y || x is unordered with y, false otherwise.
-		{name: "NotGreaterThanF", argLength: 1, reg: readflags},  // bool, true flags encode floating-point x<=y || x is unordered with y, false otherwise.
-		{name: "NotGreaterEqualF", argLength: 1, reg: readflags}, // bool, true flags encode floating-point x<y || x is unordered with y, false otherwise.
-		// duffzero
-		// arg0 = address of memory to zero
-		// arg1 = mem
-		// auxint = offset into duffzero code to start executing
-		// returns mem
-		// R20 changed as side effect
-		// R16 and R17 may be clobbered by linker trampoline.
-		{
-			name:      "DUFFZERO",
-			aux:       "Int64",
-			argLength: 2,
-			reg: regInfo{
-				inputs:   []regMask{buildReg("R20")},
-				clobbers: buildReg("R16 R17 R20 R30"),
-			},
-			faultOnNilArg0: true,
-			unsafePoint:    true, // FP maintenance around DUFFZERO can be clobbered by interrupts
-		},
-
-		// large zeroing
-		// arg0 = address of memory to zero (in R16 aka arm64.REGRT1, changed as side effect)
-		// arg1 = address of the last 16-byte unit to zero
-		// arg2 = mem
-		// returns mem
-		//	STP.P	(ZR,ZR), 16(R16)
-		//	CMP	Rarg1, R16
-		//	BLE	-2(PC)
-		// Note: the-end-of-the-memory may be not a valid pointer. it's a problem if it is spilled.
-		// the-end-of-the-memory - 16 is with the area to zero, ok to spill.
-		{
-			name:      "LoweredZero",
-			argLength: 3,
-			reg: regInfo{
-				inputs:   []regMask{buildReg("R16"), gp},
-				clobbers: buildReg("R16"),
-			},
-			clobberFlags:   true,
-			faultOnNilArg0: true,
-		},
-
-		// duffcopy
-		// arg0 = address of dst memory (in R21, changed as side effect)
-		// arg1 = address of src memory (in R20, changed as side effect)
-		// arg2 = mem
-		// auxint = offset into duffcopy code to start executing
-		// returns mem
-		// R20, R21 changed as side effect
-		// R16 and R17 may be clobbered by linker trampoline.
-		{
-			name:      "DUFFCOPY",
-			aux:       "Int64",
-			argLength: 3,
-			reg: regInfo{
-				inputs:   []regMask{buildReg("R21"), buildReg("R20")},
-				clobbers: buildReg("R16 R17 R20 R21 R26 R30"),
-			},
-			faultOnNilArg0: true,
-			faultOnNilArg1: true,
-			unsafePoint:    true, // FP maintenance around DUFFCOPY can be clobbered by interrupts
-		},
-
-		// large move
-		// arg0 = address of dst memory (in R17 aka arm64.REGRT2, changed as side effect)
-		// arg1 = address of src memory (in R16 aka arm64.REGRT1, changed as side effect)
-		// arg2 = address of the last element of src
-		// arg3 = mem
-		// returns mem
-		//	MOVD.P	8(R16), Rtmp
-		//	MOVD.P	Rtmp, 8(R17)
-		//	CMP	Rarg2, R16
-		//	BLE	-3(PC)
-		// Note: the-end-of-src may be not a valid pointer. it's a problem if it is spilled.
-		// the-end-of-src - 8 is within the area to copy, ok to spill.
-		{
-			name:      "LoweredMove",
-			argLength: 4,
-			reg: regInfo{
-				inputs:   []regMask{buildReg("R17"), buildReg("R16"), gp},
-				clobbers: buildReg("R16 R17"),
-			},
-			clobberFlags:   true,
-			faultOnNilArg0: true,
-			faultOnNilArg1: true,
-		},
-
-		// Scheduler ensures LoweredGetClosurePtr occurs only in entry block,
-		// and sorts it to the very beginning of the block to prevent other
-		// use of R26 (arm64.REGCTXT, the closure pointer)
-		{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R26")}}, zeroWidth: true},
-
-		// LoweredGetCallerSP returns the SP of the caller of the current function.
-		{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
-
-		// LoweredGetCallerPC evaluates to the PC to which its "caller" will return.
-		// I.e., if f calls g "calls" getcallerpc,
-		// the result should be the PC within f that g will return to.
-		// See runtime/stubs.go for a more detailed discussion.
-		{name: "LoweredGetCallerPC", reg: gp01, rematerializeable: true},
-
-		// Constant flag value.
-		// Note: there's an "unordered" outcome for floating-point
-		// comparisons, but we don't use such a beast yet.
-		// This op is for temporary use by rewrite rules. It
-		// cannot appear in the generated assembly.
-		{name: "FlagConstant", aux: "FlagConstant"},
-
-		// (InvertFlags (CMP a b)) == (CMP b a)
-		// InvertFlags is a pseudo-op which can't appear in assembly output.
-		{name: "InvertFlags", argLength: 1}, // reverse direction of arg0
-
-		// atomic loads.
-		// load from arg0. arg1=mem. auxint must be zero.
-		// returns <value,memory> so they can be properly ordered with other loads.
-		{name: "LDAR", argLength: 2, reg: gpload, asm: "LDAR", faultOnNilArg0: true},
-		{name: "LDARB", argLength: 2, reg: gpload, asm: "LDARB", faultOnNilArg0: true},
-		{name: "LDARW", argLength: 2, reg: gpload, asm: "LDARW", faultOnNilArg0: true},
-
-		// atomic stores.
-		// store arg1 to arg0. arg2=mem. returns memory. auxint must be zero.
-		{name: "STLRB", argLength: 3, reg: gpstore, asm: "STLRB", faultOnNilArg0: true, hasSideEffects: true},
-		{name: "STLR", argLength: 3, reg: gpstore, asm: "STLR", faultOnNilArg0: true, hasSideEffects: true},
-		{name: "STLRW", argLength: 3, reg: gpstore, asm: "STLRW", faultOnNilArg0: true, hasSideEffects: true},
-
-		// atomic exchange.
-		// store arg1 to arg0. arg2=mem. returns <old content of *arg0, memory>. auxint must be zero.
-		// LDAXR	(Rarg0), Rout
-		// STLXR	Rarg1, (Rarg0), Rtmp
-		// CBNZ		Rtmp, -2(PC)
-		{name: "LoweredAtomicExchange64", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-		{name: "LoweredAtomicExchange32", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-
-		// atomic exchange variant.
-		// store arg1 to arg0. arg2=mem. returns <old content of *arg0, memory>. auxint must be zero.
-		// SWPALD	Rarg1, (Rarg0), Rout
-		{name: "LoweredAtomicExchange64Variant", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
-		{name: "LoweredAtomicExchange32Variant", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
-
-		// atomic add.
-		// *arg0 += arg1. arg2=mem. returns <new content of *arg0, memory>. auxint must be zero.
-		// LDAXR	(Rarg0), Rout
-		// ADD		Rarg1, Rout
-		// STLXR	Rout, (Rarg0), Rtmp
-		// CBNZ		Rtmp, -3(PC)
-		{name: "LoweredAtomicAdd64", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-		{name: "LoweredAtomicAdd32", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-
-		// atomic add variant.
-		// *arg0 += arg1. arg2=mem. returns <new content of *arg0, memory>. auxint must be zero.
-		// LDADDAL	(Rarg0), Rarg1, Rout
-		// ADD		Rarg1, Rout
-		{name: "LoweredAtomicAdd64Variant", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
-		{name: "LoweredAtomicAdd32Variant", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
-
-		// atomic compare and swap.
-		// arg0 = pointer, arg1 = old value, arg2 = new value, arg3 = memory. auxint must be zero.
-		// if *arg0 == arg1 {
-		//   *arg0 = arg2
-		//   return (true, memory)
-		// } else {
-		//   return (false, memory)
-		// }
-		// LDAXR	(Rarg0), Rtmp
-		// CMP		Rarg1, Rtmp
-		// BNE		3(PC)
-		// STLXR	Rarg2, (Rarg0), Rtmp
-		// CBNZ		Rtmp, -4(PC)
-		// CSET		EQ, Rout
-		{name: "LoweredAtomicCas64", argLength: 4, reg: gpcas, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-		{name: "LoweredAtomicCas32", argLength: 4, reg: gpcas, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-
-		// atomic compare and swap variant.
-		// arg0 = pointer, arg1 = old value, arg2 = new value, arg3 = memory. auxint must be zero.
-		// if *arg0 == arg1 {
-		//   *arg0 = arg2
-		//   return (true, memory)
-		// } else {
-		//   return (false, memory)
-		// }
-		// MOV  	Rarg1, Rtmp
-		// CASAL	Rtmp, (Rarg0), Rarg2
-		// CMP  	Rarg1, Rtmp
-		// CSET 	EQ, Rout
-		{name: "LoweredAtomicCas64Variant", argLength: 4, reg: gpcas, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-		{name: "LoweredAtomicCas32Variant", argLength: 4, reg: gpcas, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-
-		// atomic and/or.
-		// *arg0 &= (|=) arg1. arg2=mem. returns <new content of *arg0, memory>. auxint must be zero.
-		// LDAXR	(Rarg0), Rout
-		// AND/OR	Rarg1, Rout
-		// STLXR	Rout, (Rarg0), Rtmp
-		// CBNZ		Rtmp, -3(PC)
-		{name: "LoweredAtomicAnd8", argLength: 3, reg: gpxchg, resultNotInArgs: true, asm: "AND", typ: "(UInt8,Mem)", faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-		{name: "LoweredAtomicAnd32", argLength: 3, reg: gpxchg, resultNotInArgs: true, asm: "AND", typ: "(UInt32,Mem)", faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-		{name: "LoweredAtomicOr8", argLength: 3, reg: gpxchg, resultNotInArgs: true, asm: "ORR", typ: "(UInt8,Mem)", faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-		{name: "LoweredAtomicOr32", argLength: 3, reg: gpxchg, resultNotInArgs: true, asm: "ORR", typ: "(UInt32,Mem)", faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-
-		// atomic and/or variant.
-		// *arg0 &= (|=) arg1. arg2=mem. returns <new content of *arg0, memory>. auxint must be zero.
-		//   AND:
-		// MNV       Rarg1, Rtemp
-		// LDANDALB  Rtemp, (Rarg0), Rout
-		// AND       Rarg1, Rout
-		//   OR:
-		// LDORALB  Rarg1, (Rarg0), Rout
-		// ORR       Rarg1, Rout
-		{name: "LoweredAtomicAnd8Variant", argLength: 3, reg: gpxchg, resultNotInArgs: true, typ: "(UInt8,Mem)", faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-		{name: "LoweredAtomicAnd32Variant", argLength: 3, reg: gpxchg, resultNotInArgs: true, typ: "(UInt32,Mem)", faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-		{name: "LoweredAtomicOr8Variant", argLength: 3, reg: gpxchg, resultNotInArgs: true, typ: "(UInt8,Mem)", faultOnNilArg0: true, hasSideEffects: true},
-		{name: "LoweredAtomicOr32Variant", argLength: 3, reg: gpxchg, resultNotInArgs: true, typ: "(UInt32,Mem)", faultOnNilArg0: true, hasSideEffects: true},
-
-		// LoweredWB invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
-		// It saves all GP registers if necessary,
-		// but clobbers R30 (LR) because it's a call.
-		// R16 and R17 may be clobbered by linker trampoline.
-		{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R2"), buildReg("R3")}, clobbers: (callerSave &^ gpg) | buildReg("R16 R17 R30")}, clobberFlags: true, aux: "Sym", symEffect: "None"},
-
-		// There are three of these functions so that they can have three different register inputs.
-		// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the
-		// default registers to match so we don't need to copy registers around unnecessarily.
-		{name: "LoweredPanicBoundsA", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r2, r3}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
-		{name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r1, r2}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
-		{name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r0, r1}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
-
-		// Prefetch instruction
-		// Do prefetch arg0 address with option aux. arg0=addr, arg1=memory, aux=option.
-		{name: "PRFM", argLength: 2, aux: "Int64", reg: prefreg, asm: "PRFM", hasSideEffects: true},
-
-		// Publication barrier
-		{name: "DMB", argLength: 1, aux: "Int64", asm: "DMB", hasSideEffects: true}, // Do data barrier. arg0=memory, aux=option.
-	}
-
-	blocks := []blockData{
-		{name: "EQ", controls: 1},
-		{name: "NE", controls: 1},
-		{name: "LT", controls: 1},
-		{name: "LE", controls: 1},
-		{name: "GT", controls: 1},
-		{name: "GE", controls: 1},
-		{name: "ULT", controls: 1},
-		{name: "ULE", controls: 1},
-		{name: "UGT", controls: 1},
-		{name: "UGE", controls: 1},
-		{name: "Z", controls: 1},                  // Control == 0 (take a register instead of flags)
-		{name: "NZ", controls: 1},                 // Control != 0
-		{name: "ZW", controls: 1},                 // Control == 0, 32-bit
-		{name: "NZW", controls: 1},                // Control != 0, 32-bit
-		{name: "TBZ", controls: 1, aux: "Int64"},  // Control & (1 << AuxInt) == 0
-		{name: "TBNZ", controls: 1, aux: "Int64"}, // Control & (1 << AuxInt) != 0
-		{name: "FLT", controls: 1},
-		{name: "FLE", controls: 1},
-		{name: "FGT", controls: 1},
-		{name: "FGE", controls: 1},
-		{name: "LTnoov", controls: 1}, // 'LT' but without honoring overflow
-		{name: "LEnoov", controls: 1}, // 'LE' but without honoring overflow
-		{name: "GTnoov", controls: 1}, // 'GT' but without honoring overflow
-		{name: "GEnoov", controls: 1}, // 'GE' but without honoring overflow
-
-		// JUMPTABLE implements jump tables.
-		// Aux is the symbol (an *obj.LSym) for the jump table.
-		// control[0] is the index into the jump table.
-		// control[1] is the address of the jump table (the address of the symbol stored in Aux).
-		{name: "JUMPTABLE", controls: 2, aux: "Sym"},
-	}
-
-	archs = append(archs, arch{
-		name:               "ARM64",
-		pkg:                "cmd/internal/obj/arm64",
-		genfile:            "../../arm64/ssa.go",
-		ops:                ops,
-		blocks:             blocks,
-		regnames:           regNamesARM64,
-		ParamIntRegNames:   "R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15",
-		ParamFloatRegNames: "F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15",
-		gpregmask:          gp,
-		fpregmask:          fp,
-		framepointerreg:    -1, // not used
-		linkreg:            int8(num["R30"]),
-	})
-}
diff --git a/src/cmd/compile/internal/ssa/gen/ARMOps.go b/src/cmd/compile/internal/ssa/gen/ARMOps.go
deleted file mode 100644
index 3803f27..0000000
--- a/src/cmd/compile/internal/ssa/gen/ARMOps.go
+++ /dev/null
@@ -1,603 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build ignore
-// +build ignore
-
-package main
-
-import "strings"
-
-// Notes:
-//  - Integer types live in the low portion of registers. Upper portions are junk.
-//  - Boolean types use the low-order byte of a register. 0=false, 1=true.
-//    Upper bytes are junk.
-//  - *const instructions may use a constant larger than the instruction can encode.
-//    In this case the assembler expands to multiple instructions and uses tmp
-//    register (R11).
-
-// Suffixes encode the bit width of various instructions.
-// W (word)      = 32 bit
-// H (half word) = 16 bit
-// HU            = 16 bit unsigned
-// B (byte)      = 8 bit
-// BU            = 8 bit unsigned
-// F (float)     = 32 bit float
-// D (double)    = 64 bit float
-
-var regNamesARM = []string{
-	"R0",
-	"R1",
-	"R2",
-	"R3",
-	"R4",
-	"R5",
-	"R6",
-	"R7",
-	"R8",
-	"R9",
-	"g",   // aka R10
-	"R11", // tmp
-	"R12",
-	"SP",  // aka R13
-	"R14", // link
-	"R15", // pc
-
-	"F0",
-	"F1",
-	"F2",
-	"F3",
-	"F4",
-	"F5",
-	"F6",
-	"F7",
-	"F8",
-	"F9",
-	"F10",
-	"F11",
-	"F12",
-	"F13",
-	"F14",
-	"F15", // tmp
-
-	// If you add registers, update asyncPreempt in runtime.
-
-	// pseudo-registers
-	"SB",
-}
-
-func init() {
-	// Make map from reg names to reg integers.
-	if len(regNamesARM) > 64 {
-		panic("too many registers")
-	}
-	num := map[string]int{}
-	for i, name := range regNamesARM {
-		num[name] = i
-	}
-	buildReg := func(s string) regMask {
-		m := regMask(0)
-		for _, r := range strings.Split(s, " ") {
-			if n, ok := num[r]; ok {
-				m |= regMask(1) << uint(n)
-				continue
-			}
-			panic("register " + r + " not found")
-		}
-		return m
-	}
-
-	// Common individual register masks
-	var (
-		gp         = buildReg("R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R12 R14")
-		gpg        = gp | buildReg("g")
-		gpsp       = gp | buildReg("SP")
-		gpspg      = gpg | buildReg("SP")
-		gpspsbg    = gpspg | buildReg("SB")
-		fp         = buildReg("F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15")
-		callerSave = gp | fp | buildReg("g") // runtime.setg (and anything calling it) may clobber g
-		r0         = buildReg("R0")
-		r1         = buildReg("R1")
-		r2         = buildReg("R2")
-		r3         = buildReg("R3")
-		r4         = buildReg("R4")
-	)
-	// Common regInfo
-	var (
-		gp01      = regInfo{inputs: nil, outputs: []regMask{gp}}
-		gp11      = regInfo{inputs: []regMask{gpg}, outputs: []regMask{gp}}
-		gp11carry = regInfo{inputs: []regMask{gpg}, outputs: []regMask{gp, 0}}
-		gp11sp    = regInfo{inputs: []regMask{gpspg}, outputs: []regMask{gp}}
-		gp1flags  = regInfo{inputs: []regMask{gpg}}
-		gp1flags1 = regInfo{inputs: []regMask{gp}, outputs: []regMask{gp}}
-		gp21      = regInfo{inputs: []regMask{gpg, gpg}, outputs: []regMask{gp}}
-		gp21carry = regInfo{inputs: []regMask{gpg, gpg}, outputs: []regMask{gp, 0}}
-		gp2flags  = regInfo{inputs: []regMask{gpg, gpg}}
-		gp2flags1 = regInfo{inputs: []regMask{gp, gp}, outputs: []regMask{gp}}
-		gp22      = regInfo{inputs: []regMask{gpg, gpg}, outputs: []regMask{gp, gp}}
-		gp31      = regInfo{inputs: []regMask{gp, gp, gp}, outputs: []regMask{gp}}
-		gp31carry = regInfo{inputs: []regMask{gp, gp, gp}, outputs: []regMask{gp, 0}}
-		gp3flags  = regInfo{inputs: []regMask{gp, gp, gp}}
-		gp3flags1 = regInfo{inputs: []regMask{gp, gp, gp}, outputs: []regMask{gp}}
-		gpload    = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{gp}}
-		gpstore   = regInfo{inputs: []regMask{gpspsbg, gpg}}
-		gp2load   = regInfo{inputs: []regMask{gpspsbg, gpg}, outputs: []regMask{gp}}
-		gp2store  = regInfo{inputs: []regMask{gpspsbg, gpg, gpg}}
-		fp01      = regInfo{inputs: nil, outputs: []regMask{fp}}
-		fp11      = regInfo{inputs: []regMask{fp}, outputs: []regMask{fp}}
-		fp1flags  = regInfo{inputs: []regMask{fp}}
-		fpgp      = regInfo{inputs: []regMask{fp}, outputs: []regMask{gp}, clobbers: buildReg("F15")} // int-float conversion uses F15 as tmp
-		gpfp      = regInfo{inputs: []regMask{gp}, outputs: []regMask{fp}, clobbers: buildReg("F15")}
-		fp21      = regInfo{inputs: []regMask{fp, fp}, outputs: []regMask{fp}}
-		fp31      = regInfo{inputs: []regMask{fp, fp, fp}, outputs: []regMask{fp}}
-		fp2flags  = regInfo{inputs: []regMask{fp, fp}}
-		fpload    = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{fp}}
-		fpstore   = regInfo{inputs: []regMask{gpspsbg, fp}}
-		readflags = regInfo{inputs: nil, outputs: []regMask{gp}}
-	)
-	ops := []opData{
-		// binary ops
-		{name: "ADD", argLength: 2, reg: gp21, asm: "ADD", commutative: true},     // arg0 + arg1
-		{name: "ADDconst", argLength: 1, reg: gp11sp, asm: "ADD", aux: "Int32"},   // arg0 + auxInt
-		{name: "SUB", argLength: 2, reg: gp21, asm: "SUB"},                        // arg0 - arg1
-		{name: "SUBconst", argLength: 1, reg: gp11, asm: "SUB", aux: "Int32"},     // arg0 - auxInt
-		{name: "RSB", argLength: 2, reg: gp21, asm: "RSB"},                        // arg1 - arg0
-		{name: "RSBconst", argLength: 1, reg: gp11, asm: "RSB", aux: "Int32"},     // auxInt - arg0
-		{name: "MUL", argLength: 2, reg: gp21, asm: "MUL", commutative: true},     // arg0 * arg1
-		{name: "HMUL", argLength: 2, reg: gp21, asm: "MULL", commutative: true},   // (arg0 * arg1) >> 32, signed
-		{name: "HMULU", argLength: 2, reg: gp21, asm: "MULLU", commutative: true}, // (arg0 * arg1) >> 32, unsigned
-
-		// udiv runtime call for soft division
-		// output0 = arg0/arg1, output1 = arg0%arg1
-		// see ../../../../../runtime/vlop_arm.s
-		{
-			name:      "CALLudiv",
-			argLength: 2,
-			reg: regInfo{
-				inputs:   []regMask{buildReg("R1"), buildReg("R0")},
-				outputs:  []regMask{buildReg("R0"), buildReg("R1")},
-				clobbers: buildReg("R2 R3 R12 R14"), // R14 is LR, R12 is linker trampoline scratch register
-			},
-			clobberFlags: true,
-			typ:          "(UInt32,UInt32)",
-			call:         false, // TODO(mdempsky): Should this be true?
-		},
-
-		{name: "ADDS", argLength: 2, reg: gp21carry, asm: "ADD", commutative: true}, // arg0 + arg1, set carry flag
-		{name: "ADDSconst", argLength: 1, reg: gp11carry, asm: "ADD", aux: "Int32"}, // arg0 + auxInt, set carry flag
-		{name: "ADC", argLength: 3, reg: gp2flags1, asm: "ADC", commutative: true},  // arg0 + arg1 + carry, arg2=flags
-		{name: "ADCconst", argLength: 2, reg: gp1flags1, asm: "ADC", aux: "Int32"},  // arg0 + auxInt + carry, arg1=flags
-		{name: "SUBS", argLength: 2, reg: gp21carry, asm: "SUB"},                    // arg0 - arg1, set carry flag
-		{name: "SUBSconst", argLength: 1, reg: gp11carry, asm: "SUB", aux: "Int32"}, // arg0 - auxInt, set carry flag
-		{name: "RSBSconst", argLength: 1, reg: gp11carry, asm: "RSB", aux: "Int32"}, // auxInt - arg0, set carry flag
-		{name: "SBC", argLength: 3, reg: gp2flags1, asm: "SBC"},                     // arg0 - arg1 - carry, arg2=flags
-		{name: "SBCconst", argLength: 2, reg: gp1flags1, asm: "SBC", aux: "Int32"},  // arg0 - auxInt - carry, arg1=flags
-		{name: "RSCconst", argLength: 2, reg: gp1flags1, asm: "RSC", aux: "Int32"},  // auxInt - arg0 - carry, arg1=flags
-
-		{name: "MULLU", argLength: 2, reg: gp22, asm: "MULLU", commutative: true}, // arg0 * arg1, high 32 bits in out0, low 32 bits in out1
-		{name: "MULA", argLength: 3, reg: gp31, asm: "MULA"},                      // arg0 * arg1 + arg2
-		{name: "MULS", argLength: 3, reg: gp31, asm: "MULS"},                      // arg2 - arg0 * arg1
-
-		{name: "ADDF", argLength: 2, reg: fp21, asm: "ADDF", commutative: true},   // arg0 + arg1
-		{name: "ADDD", argLength: 2, reg: fp21, asm: "ADDD", commutative: true},   // arg0 + arg1
-		{name: "SUBF", argLength: 2, reg: fp21, asm: "SUBF"},                      // arg0 - arg1
-		{name: "SUBD", argLength: 2, reg: fp21, asm: "SUBD"},                      // arg0 - arg1
-		{name: "MULF", argLength: 2, reg: fp21, asm: "MULF", commutative: true},   // arg0 * arg1
-		{name: "MULD", argLength: 2, reg: fp21, asm: "MULD", commutative: true},   // arg0 * arg1
-		{name: "NMULF", argLength: 2, reg: fp21, asm: "NMULF", commutative: true}, // -(arg0 * arg1)
-		{name: "NMULD", argLength: 2, reg: fp21, asm: "NMULD", commutative: true}, // -(arg0 * arg1)
-		{name: "DIVF", argLength: 2, reg: fp21, asm: "DIVF"},                      // arg0 / arg1
-		{name: "DIVD", argLength: 2, reg: fp21, asm: "DIVD"},                      // arg0 / arg1
-
-		{name: "MULAF", argLength: 3, reg: fp31, asm: "MULAF", resultInArg0: true}, // arg0 + (arg1 * arg2)
-		{name: "MULAD", argLength: 3, reg: fp31, asm: "MULAD", resultInArg0: true}, // arg0 + (arg1 * arg2)
-		{name: "MULSF", argLength: 3, reg: fp31, asm: "MULSF", resultInArg0: true}, // arg0 - (arg1 * arg2)
-		{name: "MULSD", argLength: 3, reg: fp31, asm: "MULSD", resultInArg0: true}, // arg0 - (arg1 * arg2)
-
-		// FMULAD only exists on platforms with the VFPv4 instruction set.
-		// Any use must be preceded by a successful check of runtime.arm_support_vfpv4.
-		{name: "FMULAD", argLength: 3, reg: fp31, asm: "FMULAD", resultInArg0: true}, // arg0 + (arg1 * arg2)
-
-		{name: "AND", argLength: 2, reg: gp21, asm: "AND", commutative: true}, // arg0 & arg1
-		{name: "ANDconst", argLength: 1, reg: gp11, asm: "AND", aux: "Int32"}, // arg0 & auxInt
-		{name: "OR", argLength: 2, reg: gp21, asm: "ORR", commutative: true},  // arg0 | arg1
-		{name: "ORconst", argLength: 1, reg: gp11, asm: "ORR", aux: "Int32"},  // arg0 | auxInt
-		{name: "XOR", argLength: 2, reg: gp21, asm: "EOR", commutative: true}, // arg0 ^ arg1
-		{name: "XORconst", argLength: 1, reg: gp11, asm: "EOR", aux: "Int32"}, // arg0 ^ auxInt
-		{name: "BIC", argLength: 2, reg: gp21, asm: "BIC"},                    // arg0 &^ arg1
-		{name: "BICconst", argLength: 1, reg: gp11, asm: "BIC", aux: "Int32"}, // arg0 &^ auxInt
-
-		// bit extraction, AuxInt = Width<<8 | LSB
-		{name: "BFX", argLength: 1, reg: gp11, asm: "BFX", aux: "Int32"},   // extract W bits from bit L in arg0, then signed extend
-		{name: "BFXU", argLength: 1, reg: gp11, asm: "BFXU", aux: "Int32"}, // extract W bits from bit L in arg0, then unsigned extend
-
-		// unary ops
-		{name: "MVN", argLength: 1, reg: gp11, asm: "MVN"}, // ^arg0
-
-		{name: "NEGF", argLength: 1, reg: fp11, asm: "NEGF"},   // -arg0, float32
-		{name: "NEGD", argLength: 1, reg: fp11, asm: "NEGD"},   // -arg0, float64
-		{name: "SQRTD", argLength: 1, reg: fp11, asm: "SQRTD"}, // sqrt(arg0), float64
-		{name: "SQRTF", argLength: 1, reg: fp11, asm: "SQRTF"}, // sqrt(arg0), float32
-		{name: "ABSD", argLength: 1, reg: fp11, asm: "ABSD"},   // abs(arg0), float64
-
-		{name: "CLZ", argLength: 1, reg: gp11, asm: "CLZ"},     // count leading zero
-		{name: "REV", argLength: 1, reg: gp11, asm: "REV"},     // reverse byte order
-		{name: "REV16", argLength: 1, reg: gp11, asm: "REV16"}, // reverse byte order in 16-bit halfwords
-		{name: "RBIT", argLength: 1, reg: gp11, asm: "RBIT"},   // reverse bit order
-
-		// shifts
-		{name: "SLL", argLength: 2, reg: gp21, asm: "SLL"},                    // arg0 << arg1, shift amount is mod 256
-		{name: "SLLconst", argLength: 1, reg: gp11, asm: "SLL", aux: "Int32"}, // arg0 << auxInt, 0 <= auxInt < 32
-		{name: "SRL", argLength: 2, reg: gp21, asm: "SRL"},                    // arg0 >> arg1, unsigned, shift amount is mod 256
-		{name: "SRLconst", argLength: 1, reg: gp11, asm: "SRL", aux: "Int32"}, // arg0 >> auxInt, unsigned, 0 <= auxInt < 32
-		{name: "SRA", argLength: 2, reg: gp21, asm: "SRA"},                    // arg0 >> arg1, signed, shift amount is mod 256
-		{name: "SRAconst", argLength: 1, reg: gp11, asm: "SRA", aux: "Int32"}, // arg0 >> auxInt, signed, 0 <= auxInt < 32
-		{name: "SRR", argLength: 2, reg: gp21},                                // arg0 right rotate by arg1 bits
-		{name: "SRRconst", argLength: 1, reg: gp11, aux: "Int32"},             // arg0 right rotate by auxInt bits, 0 <= auxInt < 32
-
-		// auxInt for all of these satisfy 0 <= auxInt < 32
-		{name: "ADDshiftLL", argLength: 2, reg: gp21, asm: "ADD", aux: "Int32"}, // arg0 + arg1<<auxInt
-		{name: "ADDshiftRL", argLength: 2, reg: gp21, asm: "ADD", aux: "Int32"}, // arg0 + arg1>>auxInt, unsigned shift
-		{name: "ADDshiftRA", argLength: 2, reg: gp21, asm: "ADD", aux: "Int32"}, // arg0 + arg1>>auxInt, signed shift
-		{name: "SUBshiftLL", argLength: 2, reg: gp21, asm: "SUB", aux: "Int32"}, // arg0 - arg1<<auxInt
-		{name: "SUBshiftRL", argLength: 2, reg: gp21, asm: "SUB", aux: "Int32"}, // arg0 - arg1>>auxInt, unsigned shift
-		{name: "SUBshiftRA", argLength: 2, reg: gp21, asm: "SUB", aux: "Int32"}, // arg0 - arg1>>auxInt, signed shift
-		{name: "RSBshiftLL", argLength: 2, reg: gp21, asm: "RSB", aux: "Int32"}, // arg1<<auxInt - arg0
-		{name: "RSBshiftRL", argLength: 2, reg: gp21, asm: "RSB", aux: "Int32"}, // arg1>>auxInt - arg0, unsigned shift
-		{name: "RSBshiftRA", argLength: 2, reg: gp21, asm: "RSB", aux: "Int32"}, // arg1>>auxInt - arg0, signed shift
-		{name: "ANDshiftLL", argLength: 2, reg: gp21, asm: "AND", aux: "Int32"}, // arg0 & (arg1<<auxInt)
-		{name: "ANDshiftRL", argLength: 2, reg: gp21, asm: "AND", aux: "Int32"}, // arg0 & (arg1>>auxInt), unsigned shift
-		{name: "ANDshiftRA", argLength: 2, reg: gp21, asm: "AND", aux: "Int32"}, // arg0 & (arg1>>auxInt), signed shift
-		{name: "ORshiftLL", argLength: 2, reg: gp21, asm: "ORR", aux: "Int32"},  // arg0 | arg1<<auxInt
-		{name: "ORshiftRL", argLength: 2, reg: gp21, asm: "ORR", aux: "Int32"},  // arg0 | arg1>>auxInt, unsigned shift
-		{name: "ORshiftRA", argLength: 2, reg: gp21, asm: "ORR", aux: "Int32"},  // arg0 | arg1>>auxInt, signed shift
-		{name: "XORshiftLL", argLength: 2, reg: gp21, asm: "EOR", aux: "Int32"}, // arg0 ^ arg1<<auxInt
-		{name: "XORshiftRL", argLength: 2, reg: gp21, asm: "EOR", aux: "Int32"}, // arg0 ^ arg1>>auxInt, unsigned shift
-		{name: "XORshiftRA", argLength: 2, reg: gp21, asm: "EOR", aux: "Int32"}, // arg0 ^ arg1>>auxInt, signed shift
-		{name: "XORshiftRR", argLength: 2, reg: gp21, asm: "EOR", aux: "Int32"}, // arg0 ^ (arg1 right rotate by auxInt)
-		{name: "BICshiftLL", argLength: 2, reg: gp21, asm: "BIC", aux: "Int32"}, // arg0 &^ (arg1<<auxInt)
-		{name: "BICshiftRL", argLength: 2, reg: gp21, asm: "BIC", aux: "Int32"}, // arg0 &^ (arg1>>auxInt), unsigned shift
-		{name: "BICshiftRA", argLength: 2, reg: gp21, asm: "BIC", aux: "Int32"}, // arg0 &^ (arg1>>auxInt), signed shift
-		{name: "MVNshiftLL", argLength: 1, reg: gp11, asm: "MVN", aux: "Int32"}, // ^(arg0<<auxInt)
-		{name: "MVNshiftRL", argLength: 1, reg: gp11, asm: "MVN", aux: "Int32"}, // ^(arg0>>auxInt), unsigned shift
-		{name: "MVNshiftRA", argLength: 1, reg: gp11, asm: "MVN", aux: "Int32"}, // ^(arg0>>auxInt), signed shift
-
-		{name: "ADCshiftLL", argLength: 3, reg: gp2flags1, asm: "ADC", aux: "Int32"}, // arg0 + arg1<<auxInt + carry, arg2=flags
-		{name: "ADCshiftRL", argLength: 3, reg: gp2flags1, asm: "ADC", aux: "Int32"}, // arg0 + arg1>>auxInt + carry, unsigned shift, arg2=flags
-		{name: "ADCshiftRA", argLength: 3, reg: gp2flags1, asm: "ADC", aux: "Int32"}, // arg0 + arg1>>auxInt + carry, signed shift, arg2=flags
-		{name: "SBCshiftLL", argLength: 3, reg: gp2flags1, asm: "SBC", aux: "Int32"}, // arg0 - arg1<<auxInt - carry, arg2=flags
-		{name: "SBCshiftRL", argLength: 3, reg: gp2flags1, asm: "SBC", aux: "Int32"}, // arg0 - arg1>>auxInt - carry, unsigned shift, arg2=flags
-		{name: "SBCshiftRA", argLength: 3, reg: gp2flags1, asm: "SBC", aux: "Int32"}, // arg0 - arg1>>auxInt - carry, signed shift, arg2=flags
-		{name: "RSCshiftLL", argLength: 3, reg: gp2flags1, asm: "RSC", aux: "Int32"}, // arg1<<auxInt - arg0 - carry, arg2=flags
-		{name: "RSCshiftRL", argLength: 3, reg: gp2flags1, asm: "RSC", aux: "Int32"}, // arg1>>auxInt - arg0 - carry, unsigned shift, arg2=flags
-		{name: "RSCshiftRA", argLength: 3, reg: gp2flags1, asm: "RSC", aux: "Int32"}, // arg1>>auxInt - arg0 - carry, signed shift, arg2=flags
-
-		{name: "ADDSshiftLL", argLength: 2, reg: gp21carry, asm: "ADD", aux: "Int32"}, // arg0 + arg1<<auxInt, set carry flag
-		{name: "ADDSshiftRL", argLength: 2, reg: gp21carry, asm: "ADD", aux: "Int32"}, // arg0 + arg1>>auxInt, unsigned shift, set carry flag
-		{name: "ADDSshiftRA", argLength: 2, reg: gp21carry, asm: "ADD", aux: "Int32"}, // arg0 + arg1>>auxInt, signed shift, set carry flag
-		{name: "SUBSshiftLL", argLength: 2, reg: gp21carry, asm: "SUB", aux: "Int32"}, // arg0 - arg1<<auxInt, set carry flag
-		{name: "SUBSshiftRL", argLength: 2, reg: gp21carry, asm: "SUB", aux: "Int32"}, // arg0 - arg1>>auxInt, unsigned shift, set carry flag
-		{name: "SUBSshiftRA", argLength: 2, reg: gp21carry, asm: "SUB", aux: "Int32"}, // arg0 - arg1>>auxInt, signed shift, set carry flag
-		{name: "RSBSshiftLL", argLength: 2, reg: gp21carry, asm: "RSB", aux: "Int32"}, // arg1<<auxInt - arg0, set carry flag
-		{name: "RSBSshiftRL", argLength: 2, reg: gp21carry, asm: "RSB", aux: "Int32"}, // arg1>>auxInt - arg0, unsigned shift, set carry flag
-		{name: "RSBSshiftRA", argLength: 2, reg: gp21carry, asm: "RSB", aux: "Int32"}, // arg1>>auxInt - arg0, signed shift, set carry flag
-
-		{name: "ADDshiftLLreg", argLength: 3, reg: gp31, asm: "ADD"}, // arg0 + arg1<<arg2
-		{name: "ADDshiftRLreg", argLength: 3, reg: gp31, asm: "ADD"}, // arg0 + arg1>>arg2, unsigned shift
-		{name: "ADDshiftRAreg", argLength: 3, reg: gp31, asm: "ADD"}, // arg0 + arg1>>arg2, signed shift
-		{name: "SUBshiftLLreg", argLength: 3, reg: gp31, asm: "SUB"}, // arg0 - arg1<<arg2
-		{name: "SUBshiftRLreg", argLength: 3, reg: gp31, asm: "SUB"}, // arg0 - arg1>>arg2, unsigned shift
-		{name: "SUBshiftRAreg", argLength: 3, reg: gp31, asm: "SUB"}, // arg0 - arg1>>arg2, signed shift
-		{name: "RSBshiftLLreg", argLength: 3, reg: gp31, asm: "RSB"}, // arg1<<arg2 - arg0
-		{name: "RSBshiftRLreg", argLength: 3, reg: gp31, asm: "RSB"}, // arg1>>arg2 - arg0, unsigned shift
-		{name: "RSBshiftRAreg", argLength: 3, reg: gp31, asm: "RSB"}, // arg1>>arg2 - arg0, signed shift
-		{name: "ANDshiftLLreg", argLength: 3, reg: gp31, asm: "AND"}, // arg0 & (arg1<<arg2)
-		{name: "ANDshiftRLreg", argLength: 3, reg: gp31, asm: "AND"}, // arg0 & (arg1>>arg2), unsigned shift
-		{name: "ANDshiftRAreg", argLength: 3, reg: gp31, asm: "AND"}, // arg0 & (arg1>>arg2), signed shift
-		{name: "ORshiftLLreg", argLength: 3, reg: gp31, asm: "ORR"},  // arg0 | arg1<<arg2
-		{name: "ORshiftRLreg", argLength: 3, reg: gp31, asm: "ORR"},  // arg0 | arg1>>arg2, unsigned shift
-		{name: "ORshiftRAreg", argLength: 3, reg: gp31, asm: "ORR"},  // arg0 | arg1>>arg2, signed shift
-		{name: "XORshiftLLreg", argLength: 3, reg: gp31, asm: "EOR"}, // arg0 ^ arg1<<arg2
-		{name: "XORshiftRLreg", argLength: 3, reg: gp31, asm: "EOR"}, // arg0 ^ arg1>>arg2, unsigned shift
-		{name: "XORshiftRAreg", argLength: 3, reg: gp31, asm: "EOR"}, // arg0 ^ arg1>>arg2, signed shift
-		{name: "BICshiftLLreg", argLength: 3, reg: gp31, asm: "BIC"}, // arg0 &^ (arg1<<arg2)
-		{name: "BICshiftRLreg", argLength: 3, reg: gp31, asm: "BIC"}, // arg0 &^ (arg1>>arg2), unsigned shift
-		{name: "BICshiftRAreg", argLength: 3, reg: gp31, asm: "BIC"}, // arg0 &^ (arg1>>arg2), signed shift
-		{name: "MVNshiftLLreg", argLength: 2, reg: gp21, asm: "MVN"}, // ^(arg0<<arg1)
-		{name: "MVNshiftRLreg", argLength: 2, reg: gp21, asm: "MVN"}, // ^(arg0>>arg1), unsigned shift
-		{name: "MVNshiftRAreg", argLength: 2, reg: gp21, asm: "MVN"}, // ^(arg0>>arg1), signed shift
-
-		{name: "ADCshiftLLreg", argLength: 4, reg: gp3flags1, asm: "ADC"}, // arg0 + arg1<<arg2 + carry, arg3=flags
-		{name: "ADCshiftRLreg", argLength: 4, reg: gp3flags1, asm: "ADC"}, // arg0 + arg1>>arg2 + carry, unsigned shift, arg3=flags
-		{name: "ADCshiftRAreg", argLength: 4, reg: gp3flags1, asm: "ADC"}, // arg0 + arg1>>arg2 + carry, signed shift, arg3=flags
-		{name: "SBCshiftLLreg", argLength: 4, reg: gp3flags1, asm: "SBC"}, // arg0 - arg1<<arg2 - carry, arg3=flags
-		{name: "SBCshiftRLreg", argLength: 4, reg: gp3flags1, asm: "SBC"}, // arg0 - arg1>>arg2 - carry, unsigned shift, arg3=flags
-		{name: "SBCshiftRAreg", argLength: 4, reg: gp3flags1, asm: "SBC"}, // arg0 - arg1>>arg2 - carry, signed shift, arg3=flags
-		{name: "RSCshiftLLreg", argLength: 4, reg: gp3flags1, asm: "RSC"}, // arg1<<arg2 - arg0 - carry, arg3=flags
-		{name: "RSCshiftRLreg", argLength: 4, reg: gp3flags1, asm: "RSC"}, // arg1>>arg2 - arg0 - carry, unsigned shift, arg3=flags
-		{name: "RSCshiftRAreg", argLength: 4, reg: gp3flags1, asm: "RSC"}, // arg1>>arg2 - arg0 - carry, signed shift, arg3=flags
-
-		{name: "ADDSshiftLLreg", argLength: 3, reg: gp31carry, asm: "ADD"}, // arg0 + arg1<<arg2, set carry flag
-		{name: "ADDSshiftRLreg", argLength: 3, reg: gp31carry, asm: "ADD"}, // arg0 + arg1>>arg2, unsigned shift, set carry flag
-		{name: "ADDSshiftRAreg", argLength: 3, reg: gp31carry, asm: "ADD"}, // arg0 + arg1>>arg2, signed shift, set carry flag
-		{name: "SUBSshiftLLreg", argLength: 3, reg: gp31carry, asm: "SUB"}, // arg0 - arg1<<arg2, set carry flag
-		{name: "SUBSshiftRLreg", argLength: 3, reg: gp31carry, asm: "SUB"}, // arg0 - arg1>>arg2, unsigned shift, set carry flag
-		{name: "SUBSshiftRAreg", argLength: 3, reg: gp31carry, asm: "SUB"}, // arg0 - arg1>>arg2, signed shift, set carry flag
-		{name: "RSBSshiftLLreg", argLength: 3, reg: gp31carry, asm: "RSB"}, // arg1<<arg2 - arg0, set carry flag
-		{name: "RSBSshiftRLreg", argLength: 3, reg: gp31carry, asm: "RSB"}, // arg1>>arg2 - arg0, unsigned shift, set carry flag
-		{name: "RSBSshiftRAreg", argLength: 3, reg: gp31carry, asm: "RSB"}, // arg1>>arg2 - arg0, signed shift, set carry flag
-
-		// comparisons
-		{name: "CMP", argLength: 2, reg: gp2flags, asm: "CMP", typ: "Flags"},                    // arg0 compare to arg1
-		{name: "CMPconst", argLength: 1, reg: gp1flags, asm: "CMP", aux: "Int32", typ: "Flags"}, // arg0 compare to auxInt
-		{name: "CMN", argLength: 2, reg: gp2flags, asm: "CMN", typ: "Flags", commutative: true}, // arg0 compare to -arg1, provided arg1 is not 1<<63
-		{name: "CMNconst", argLength: 1, reg: gp1flags, asm: "CMN", aux: "Int32", typ: "Flags"}, // arg0 compare to -auxInt
-		{name: "TST", argLength: 2, reg: gp2flags, asm: "TST", typ: "Flags", commutative: true}, // arg0 & arg1 compare to 0
-		{name: "TSTconst", argLength: 1, reg: gp1flags, asm: "TST", aux: "Int32", typ: "Flags"}, // arg0 & auxInt compare to 0
-		{name: "TEQ", argLength: 2, reg: gp2flags, asm: "TEQ", typ: "Flags", commutative: true}, // arg0 ^ arg1 compare to 0
-		{name: "TEQconst", argLength: 1, reg: gp1flags, asm: "TEQ", aux: "Int32", typ: "Flags"}, // arg0 ^ auxInt compare to 0
-		{name: "CMPF", argLength: 2, reg: fp2flags, asm: "CMPF", typ: "Flags"},                  // arg0 compare to arg1, float32
-		{name: "CMPD", argLength: 2, reg: fp2flags, asm: "CMPD", typ: "Flags"},                  // arg0 compare to arg1, float64
-
-		{name: "CMPshiftLL", argLength: 2, reg: gp2flags, asm: "CMP", aux: "Int32", typ: "Flags"}, // arg0 compare to arg1<<auxInt
-		{name: "CMPshiftRL", argLength: 2, reg: gp2flags, asm: "CMP", aux: "Int32", typ: "Flags"}, // arg0 compare to arg1>>auxInt, unsigned shift
-		{name: "CMPshiftRA", argLength: 2, reg: gp2flags, asm: "CMP", aux: "Int32", typ: "Flags"}, // arg0 compare to arg1>>auxInt, signed shift
-		{name: "CMNshiftLL", argLength: 2, reg: gp2flags, asm: "CMN", aux: "Int32", typ: "Flags"}, // arg0 compare to -(arg1<<auxInt)
-		{name: "CMNshiftRL", argLength: 2, reg: gp2flags, asm: "CMN", aux: "Int32", typ: "Flags"}, // arg0 compare to -(arg1>>auxInt), unsigned shift
-		{name: "CMNshiftRA", argLength: 2, reg: gp2flags, asm: "CMN", aux: "Int32", typ: "Flags"}, // arg0 compare to -(arg1>>auxInt), signed shift
-		{name: "TSTshiftLL", argLength: 2, reg: gp2flags, asm: "TST", aux: "Int32", typ: "Flags"}, // arg0 & (arg1<<auxInt) compare to 0
-		{name: "TSTshiftRL", argLength: 2, reg: gp2flags, asm: "TST", aux: "Int32", typ: "Flags"}, // arg0 & (arg1>>auxInt) compare to 0, unsigned shift
-		{name: "TSTshiftRA", argLength: 2, reg: gp2flags, asm: "TST", aux: "Int32", typ: "Flags"}, // arg0 & (arg1>>auxInt) compare to 0, signed shift
-		{name: "TEQshiftLL", argLength: 2, reg: gp2flags, asm: "TEQ", aux: "Int32", typ: "Flags"}, // arg0 ^ (arg1<<auxInt) compare to 0
-		{name: "TEQshiftRL", argLength: 2, reg: gp2flags, asm: "TEQ", aux: "Int32", typ: "Flags"}, // arg0 ^ (arg1>>auxInt) compare to 0, unsigned shift
-		{name: "TEQshiftRA", argLength: 2, reg: gp2flags, asm: "TEQ", aux: "Int32", typ: "Flags"}, // arg0 ^ (arg1>>auxInt) compare to 0, signed shift
-
-		{name: "CMPshiftLLreg", argLength: 3, reg: gp3flags, asm: "CMP", typ: "Flags"}, // arg0 compare to arg1<<arg2
-		{name: "CMPshiftRLreg", argLength: 3, reg: gp3flags, asm: "CMP", typ: "Flags"}, // arg0 compare to arg1>>arg2, unsigned shift
-		{name: "CMPshiftRAreg", argLength: 3, reg: gp3flags, asm: "CMP", typ: "Flags"}, // arg0 compare to arg1>>arg2, signed shift
-		{name: "CMNshiftLLreg", argLength: 3, reg: gp3flags, asm: "CMN", typ: "Flags"}, // arg0 + (arg1<<arg2) compare to 0
-		{name: "CMNshiftRLreg", argLength: 3, reg: gp3flags, asm: "CMN", typ: "Flags"}, // arg0 + (arg1>>arg2) compare to 0, unsigned shift
-		{name: "CMNshiftRAreg", argLength: 3, reg: gp3flags, asm: "CMN", typ: "Flags"}, // arg0 + (arg1>>arg2) compare to 0, signed shift
-		{name: "TSTshiftLLreg", argLength: 3, reg: gp3flags, asm: "TST", typ: "Flags"}, // arg0 & (arg1<<arg2) compare to 0
-		{name: "TSTshiftRLreg", argLength: 3, reg: gp3flags, asm: "TST", typ: "Flags"}, // arg0 & (arg1>>arg2) compare to 0, unsigned shift
-		{name: "TSTshiftRAreg", argLength: 3, reg: gp3flags, asm: "TST", typ: "Flags"}, // arg0 & (arg1>>arg2) compare to 0, signed shift
-		{name: "TEQshiftLLreg", argLength: 3, reg: gp3flags, asm: "TEQ", typ: "Flags"}, // arg0 ^ (arg1<<arg2) compare to 0
-		{name: "TEQshiftRLreg", argLength: 3, reg: gp3flags, asm: "TEQ", typ: "Flags"}, // arg0 ^ (arg1>>arg2) compare to 0, unsigned shift
-		{name: "TEQshiftRAreg", argLength: 3, reg: gp3flags, asm: "TEQ", typ: "Flags"}, // arg0 ^ (arg1>>arg2) compare to 0, signed shift
-
-		{name: "CMPF0", argLength: 1, reg: fp1flags, asm: "CMPF", typ: "Flags"}, // arg0 compare to 0, float32
-		{name: "CMPD0", argLength: 1, reg: fp1flags, asm: "CMPD", typ: "Flags"}, // arg0 compare to 0, float64
-
-		// moves
-		{name: "MOVWconst", argLength: 0, reg: gp01, aux: "Int32", asm: "MOVW", typ: "UInt32", rematerializeable: true},    // 32 low bits of auxint
-		{name: "MOVFconst", argLength: 0, reg: fp01, aux: "Float64", asm: "MOVF", typ: "Float32", rematerializeable: true}, // auxint as 64-bit float, convert to 32-bit float
-		{name: "MOVDconst", argLength: 0, reg: fp01, aux: "Float64", asm: "MOVD", typ: "Float64", rematerializeable: true}, // auxint as 64-bit float
-
-		{name: "MOVWaddr", argLength: 1, reg: regInfo{inputs: []regMask{buildReg("SP") | buildReg("SB")}, outputs: []regMask{gp}}, aux: "SymOff", asm: "MOVW", rematerializeable: true, symEffect: "Addr"}, // arg0 + auxInt + aux.(*gc.Sym), arg0=SP/SB
-
-		{name: "MOVBload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVB", typ: "Int8", faultOnNilArg0: true, symEffect: "Read"},     // load from arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVBUload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVBU", typ: "UInt8", faultOnNilArg0: true, symEffect: "Read"},  // load from arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVHload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVH", typ: "Int16", faultOnNilArg0: true, symEffect: "Read"},    // load from arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVHUload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVHU", typ: "UInt16", faultOnNilArg0: true, symEffect: "Read"}, // load from arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVWload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVW", typ: "UInt32", faultOnNilArg0: true, symEffect: "Read"},   // load from arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVFload", argLength: 2, reg: fpload, aux: "SymOff", asm: "MOVF", typ: "Float32", faultOnNilArg0: true, symEffect: "Read"},  // load from arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVDload", argLength: 2, reg: fpload, aux: "SymOff", asm: "MOVD", typ: "Float64", faultOnNilArg0: true, symEffect: "Read"},  // load from arg0 + auxInt + aux.  arg1=mem.
-
-		{name: "MOVBstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVB", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 1 byte of arg1 to arg0 + auxInt + aux.  arg2=mem.
-		{name: "MOVHstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVH", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 2 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
-		{name: "MOVWstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVW", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
-		{name: "MOVFstore", argLength: 3, reg: fpstore, aux: "SymOff", asm: "MOVF", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
-		{name: "MOVDstore", argLength: 3, reg: fpstore, aux: "SymOff", asm: "MOVD", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
-
-		{name: "MOVWloadidx", argLength: 3, reg: gp2load, asm: "MOVW", typ: "UInt32"},                   // load from arg0 + arg1. arg2=mem
-		{name: "MOVWloadshiftLL", argLength: 3, reg: gp2load, asm: "MOVW", aux: "Int32", typ: "UInt32"}, // load from arg0 + arg1<<auxInt. arg2=mem
-		{name: "MOVWloadshiftRL", argLength: 3, reg: gp2load, asm: "MOVW", aux: "Int32", typ: "UInt32"}, // load from arg0 + arg1>>auxInt, unsigned shift. arg2=mem
-		{name: "MOVWloadshiftRA", argLength: 3, reg: gp2load, asm: "MOVW", aux: "Int32", typ: "UInt32"}, // load from arg0 + arg1>>auxInt, signed shift. arg2=mem
-		{name: "MOVBUloadidx", argLength: 3, reg: gp2load, asm: "MOVBU", typ: "UInt8"},                  // load from arg0 + arg1. arg2=mem
-		{name: "MOVBloadidx", argLength: 3, reg: gp2load, asm: "MOVB", typ: "Int8"},                     // load from arg0 + arg1. arg2=mem
-		{name: "MOVHUloadidx", argLength: 3, reg: gp2load, asm: "MOVHU", typ: "UInt16"},                 // load from arg0 + arg1. arg2=mem
-		{name: "MOVHloadidx", argLength: 3, reg: gp2load, asm: "MOVH", typ: "Int16"},                    // load from arg0 + arg1. arg2=mem
-
-		{name: "MOVWstoreidx", argLength: 4, reg: gp2store, asm: "MOVW", typ: "Mem"},                   // store arg2 to arg0 + arg1. arg3=mem
-		{name: "MOVWstoreshiftLL", argLength: 4, reg: gp2store, asm: "MOVW", aux: "Int32", typ: "Mem"}, // store arg2 to arg0 + arg1<<auxInt. arg3=mem
-		{name: "MOVWstoreshiftRL", argLength: 4, reg: gp2store, asm: "MOVW", aux: "Int32", typ: "Mem"}, // store arg2 to arg0 + arg1>>auxInt, unsigned shift. arg3=mem
-		{name: "MOVWstoreshiftRA", argLength: 4, reg: gp2store, asm: "MOVW", aux: "Int32", typ: "Mem"}, // store arg2 to arg0 + arg1>>auxInt, signed shift. arg3=mem
-		{name: "MOVBstoreidx", argLength: 4, reg: gp2store, asm: "MOVB", typ: "Mem"},                   // store arg2 to arg0 + arg1. arg3=mem
-		{name: "MOVHstoreidx", argLength: 4, reg: gp2store, asm: "MOVH", typ: "Mem"},                   // store arg2 to arg0 + arg1. arg3=mem
-
-		{name: "MOVBreg", argLength: 1, reg: gp11, asm: "MOVBS"},  // move from arg0, sign-extended from byte
-		{name: "MOVBUreg", argLength: 1, reg: gp11, asm: "MOVBU"}, // move from arg0, unsign-extended from byte
-		{name: "MOVHreg", argLength: 1, reg: gp11, asm: "MOVHS"},  // move from arg0, sign-extended from half
-		{name: "MOVHUreg", argLength: 1, reg: gp11, asm: "MOVHU"}, // move from arg0, unsign-extended from half
-		{name: "MOVWreg", argLength: 1, reg: gp11, asm: "MOVW"},   // move from arg0
-
-		{name: "MOVWnop", argLength: 1, reg: regInfo{inputs: []regMask{gp}, outputs: []regMask{gp}}, resultInArg0: true}, // nop, return arg0 in same register
-
-		{name: "MOVWF", argLength: 1, reg: gpfp, asm: "MOVWF"},  // int32 -> float32
-		{name: "MOVWD", argLength: 1, reg: gpfp, asm: "MOVWD"},  // int32 -> float64
-		{name: "MOVWUF", argLength: 1, reg: gpfp, asm: "MOVWF"}, // uint32 -> float32, set U bit in the instruction
-		{name: "MOVWUD", argLength: 1, reg: gpfp, asm: "MOVWD"}, // uint32 -> float64, set U bit in the instruction
-		{name: "MOVFW", argLength: 1, reg: fpgp, asm: "MOVFW"},  // float32 -> int32
-		{name: "MOVDW", argLength: 1, reg: fpgp, asm: "MOVDW"},  // float64 -> int32
-		{name: "MOVFWU", argLength: 1, reg: fpgp, asm: "MOVFW"}, // float32 -> uint32, set U bit in the instruction
-		{name: "MOVDWU", argLength: 1, reg: fpgp, asm: "MOVDW"}, // float64 -> uint32, set U bit in the instruction
-		{name: "MOVFD", argLength: 1, reg: fp11, asm: "MOVFD"},  // float32 -> float64
-		{name: "MOVDF", argLength: 1, reg: fp11, asm: "MOVDF"},  // float64 -> float32
-
-		// conditional instructions, for lowering shifts
-		{name: "CMOVWHSconst", argLength: 2, reg: gp1flags1, asm: "MOVW", aux: "Int32", resultInArg0: true}, // replace arg0 w/ const if flags indicates HS, arg1=flags
-		{name: "CMOVWLSconst", argLength: 2, reg: gp1flags1, asm: "MOVW", aux: "Int32", resultInArg0: true}, // replace arg0 w/ const if flags indicates LS, arg1=flags
-		{name: "SRAcond", argLength: 3, reg: gp2flags1, asm: "SRA"},                                         // arg0 >> 31 if flags indicates HS, arg0 >> arg1 otherwise, signed shift, arg2=flags
-
-		// function calls
-		{name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                                              // call static function aux.(*obj.LSym).  arg0=mem, auxint=argsize, returns mem
-		{name: "CALLtail", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true, tailCall: true},                                // tail call static function aux.(*obj.LSym).  arg0=mem, auxint=argsize, returns mem
-		{name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{gpsp, buildReg("R7"), 0}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call function via closure.  arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem
-		{name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                        // call fn by pointer.  arg0=codeptr, arg1=mem, auxint=argsize, returns mem
-
-		// pseudo-ops
-		{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpg}}, nilCheck: true, faultOnNilArg0: true}, // panic if arg0 is nil.  arg1=mem.
-
-		{name: "Equal", argLength: 1, reg: readflags},         // bool, true flags encode x==y false otherwise.
-		{name: "NotEqual", argLength: 1, reg: readflags},      // bool, true flags encode x!=y false otherwise.
-		{name: "LessThan", argLength: 1, reg: readflags},      // bool, true flags encode signed x<y false otherwise.
-		{name: "LessEqual", argLength: 1, reg: readflags},     // bool, true flags encode signed x<=y false otherwise.
-		{name: "GreaterThan", argLength: 1, reg: readflags},   // bool, true flags encode signed x>y false otherwise.
-		{name: "GreaterEqual", argLength: 1, reg: readflags},  // bool, true flags encode signed x>=y false otherwise.
-		{name: "LessThanU", argLength: 1, reg: readflags},     // bool, true flags encode unsigned x<y false otherwise.
-		{name: "LessEqualU", argLength: 1, reg: readflags},    // bool, true flags encode unsigned x<=y false otherwise.
-		{name: "GreaterThanU", argLength: 1, reg: readflags},  // bool, true flags encode unsigned x>y false otherwise.
-		{name: "GreaterEqualU", argLength: 1, reg: readflags}, // bool, true flags encode unsigned x>=y false otherwise.
-
-		// duffzero (must be 4-byte aligned)
-		// arg0 = address of memory to zero (in R1, changed as side effect)
-		// arg1 = value to store (always zero)
-		// arg2 = mem
-		// auxint = offset into duffzero code to start executing
-		// returns mem
-		{
-			name:      "DUFFZERO",
-			aux:       "Int64",
-			argLength: 3,
-			reg: regInfo{
-				inputs:   []regMask{buildReg("R1"), buildReg("R0")},
-				clobbers: buildReg("R1 R12 R14"), // R14 is LR, R12 is linker trampoline scratch register
-			},
-			faultOnNilArg0: true,
-		},
-
-		// duffcopy (must be 4-byte aligned)
-		// arg0 = address of dst memory (in R2, changed as side effect)
-		// arg1 = address of src memory (in R1, changed as side effect)
-		// arg2 = mem
-		// auxint = offset into duffcopy code to start executing
-		// returns mem
-		{
-			name:      "DUFFCOPY",
-			aux:       "Int64",
-			argLength: 3,
-			reg: regInfo{
-				inputs:   []regMask{buildReg("R2"), buildReg("R1")},
-				clobbers: buildReg("R0 R1 R2 R12 R14"), // R14 is LR, R12 is linker trampoline scratch register
-			},
-			faultOnNilArg0: true,
-			faultOnNilArg1: true,
-		},
-
-		// large or unaligned zeroing
-		// arg0 = address of memory to zero (in R1, changed as side effect)
-		// arg1 = address of the last element to zero
-		// arg2 = value to store (always zero)
-		// arg3 = mem
-		// returns mem
-		//	MOVW.P	Rarg2, 4(R1)
-		//	CMP	R1, Rarg1
-		//	BLE	-2(PC)
-		{
-			name:      "LoweredZero",
-			aux:       "Int64",
-			argLength: 4,
-			reg: regInfo{
-				inputs:   []regMask{buildReg("R1"), gp, gp},
-				clobbers: buildReg("R1"),
-			},
-			clobberFlags:   true,
-			faultOnNilArg0: true,
-		},
-
-		// large or unaligned move
-		// arg0 = address of dst memory (in R2, changed as side effect)
-		// arg1 = address of src memory (in R1, changed as side effect)
-		// arg2 = address of the last element of src
-		// arg3 = mem
-		// returns mem
-		//	MOVW.P	4(R1), Rtmp
-		//	MOVW.P	Rtmp, 4(R2)
-		//	CMP	R1, Rarg2
-		//	BLE	-3(PC)
-		{
-			name:      "LoweredMove",
-			aux:       "Int64",
-			argLength: 4,
-			reg: regInfo{
-				inputs:   []regMask{buildReg("R2"), buildReg("R1"), gp},
-				clobbers: buildReg("R1 R2"),
-			},
-			clobberFlags:   true,
-			faultOnNilArg0: true,
-			faultOnNilArg1: true,
-		},
-
-		// Scheduler ensures LoweredGetClosurePtr occurs only in entry block,
-		// and sorts it to the very beginning of the block to prevent other
-		// use of R7 (arm.REGCTXT, the closure pointer)
-		{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R7")}}, zeroWidth: true},
-
-		// LoweredGetCallerSP returns the SP of the caller of the current function.
-		{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
-
-		// LoweredGetCallerPC evaluates to the PC to which its "caller" will return.
-		// I.e., if f calls g "calls" getcallerpc,
-		// the result should be the PC within f that g will return to.
-		// See runtime/stubs.go for a more detailed discussion.
-		{name: "LoweredGetCallerPC", reg: gp01, rematerializeable: true},
-
-		// There are three of these functions so that they can have three different register inputs.
-		// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the
-		// default registers to match so we don't need to copy registers around unnecessarily.
-		{name: "LoweredPanicBoundsA", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r2, r3}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
-		{name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r1, r2}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
-		{name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r0, r1}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
-		// Extend ops are the same as Bounds ops except the indexes are 64-bit.
-		{name: "LoweredPanicExtendA", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{r4, r2, r3}}, typ: "Mem", call: true}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
-		{name: "LoweredPanicExtendB", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{r4, r1, r2}}, typ: "Mem", call: true}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
-		{name: "LoweredPanicExtendC", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{r4, r0, r1}}, typ: "Mem", call: true}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
-
-		// Constant flag value.
-		// Note: there's an "unordered" outcome for floating-point
-		// comparisons, but we don't use such a beast yet.
-		// This op is for temporary use by rewrite rules. It
-		// cannot appear in the generated assembly.
-		{name: "FlagConstant", aux: "FlagConstant"},
-
-		// (InvertFlags (CMP a b)) == (CMP b a)
-		// InvertFlags is a pseudo-op which can't appear in assembly output.
-		{name: "InvertFlags", argLength: 1}, // reverse direction of arg0
-
-		// LoweredWB invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
-		// It saves all GP registers if necessary,
-		// but clobbers R14 (LR) because it's a call, and R12 which is linker trampoline scratch register.
-		{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R2"), buildReg("R3")}, clobbers: (callerSave &^ gpg) | buildReg("R12 R14")}, clobberFlags: true, aux: "Sym", symEffect: "None"},
-	}
-
-	blocks := []blockData{
-		{name: "EQ", controls: 1},
-		{name: "NE", controls: 1},
-		{name: "LT", controls: 1},
-		{name: "LE", controls: 1},
-		{name: "GT", controls: 1},
-		{name: "GE", controls: 1},
-		{name: "ULT", controls: 1},
-		{name: "ULE", controls: 1},
-		{name: "UGT", controls: 1},
-		{name: "UGE", controls: 1},
-		{name: "LTnoov", controls: 1}, // 'LT' but without honoring overflow
-		{name: "LEnoov", controls: 1}, // 'LE' but without honoring overflow
-		{name: "GTnoov", controls: 1}, // 'GT' but without honoring overflow
-		{name: "GEnoov", controls: 1}, // 'GE' but without honoring overflow
-	}
-
-	archs = append(archs, arch{
-		name:            "ARM",
-		pkg:             "cmd/internal/obj/arm",
-		genfile:         "../../arm/ssa.go",
-		ops:             ops,
-		blocks:          blocks,
-		regnames:        regNamesARM,
-		gpregmask:       gp,
-		fpregmask:       fp,
-		framepointerreg: -1, // not used
-		linkreg:         int8(num["R14"]),
-	})
-}
diff --git a/src/cmd/compile/internal/ssa/gen/LOONG64.rules b/src/cmd/compile/internal/ssa/gen/LOONG64.rules
deleted file mode 100644
index 3ba25e0..0000000
--- a/src/cmd/compile/internal/ssa/gen/LOONG64.rules
+++ /dev/null
@@ -1,675 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-(Add(Ptr|64|32|16|8) ...) => (ADDV ...)
-(Add(32|64)F ...) => (ADD(F|D) ...)
-
-(Sub(Ptr|64|32|16|8) ...) => (SUBV ...)
-(Sub(32|64)F ...) => (SUB(F|D) ...)
-
-(Mul(64|32|16|8) x y) => (Select1 (MULVU x y))
-(Mul(32|64)F ...) => (MUL(F|D) ...)
-(Mul64uhilo ...) => (MULVU ...)
-(Select0 (Mul64uover x y)) => (Select1 <typ.UInt64> (MULVU x y))
-(Select1 (Mul64uover x y)) => (SGTU <typ.Bool> (Select0 <typ.UInt64> (MULVU x y)) (MOVVconst <typ.UInt64> [0]))
-
-(Hmul64 x y) => (Select0 (MULV x y))
-(Hmul64u x y) => (Select0 (MULVU x y))
-(Hmul32 x y) => (SRAVconst (Select1 <typ.Int64> (MULV (SignExt32to64 x) (SignExt32to64 y))) [32])
-(Hmul32u x y) => (SRLVconst (Select1 <typ.UInt64> (MULVU (ZeroExt32to64 x) (ZeroExt32to64 y))) [32])
-
-(Div64 x y) => (Select1 (DIVV x y))
-(Div64u x y) => (Select1 (DIVVU x y))
-(Div32 x y) => (Select1 (DIVV (SignExt32to64 x) (SignExt32to64 y)))
-(Div32u x y) => (Select1 (DIVVU (ZeroExt32to64 x) (ZeroExt32to64 y)))
-(Div16 x y) => (Select1 (DIVV (SignExt16to64 x) (SignExt16to64 y)))
-(Div16u x y) => (Select1 (DIVVU (ZeroExt16to64 x) (ZeroExt16to64 y)))
-(Div8 x y) => (Select1 (DIVV (SignExt8to64 x) (SignExt8to64 y)))
-(Div8u x y) => (Select1 (DIVVU (ZeroExt8to64 x) (ZeroExt8to64 y)))
-(Div(32|64)F ...) => (DIV(F|D) ...)
-
-(Mod64 x y) => (Select0 (DIVV x y))
-(Mod64u x y) => (Select0 (DIVVU x y))
-(Mod32 x y) => (Select0 (DIVV (SignExt32to64 x) (SignExt32to64 y)))
-(Mod32u x y) => (Select0 (DIVVU (ZeroExt32to64 x) (ZeroExt32to64 y)))
-(Mod16 x y) => (Select0 (DIVV (SignExt16to64 x) (SignExt16to64 y)))
-(Mod16u x y) => (Select0 (DIVVU (ZeroExt16to64 x) (ZeroExt16to64 y)))
-(Mod8 x y) => (Select0 (DIVV (SignExt8to64 x) (SignExt8to64 y)))
-(Mod8u x y) => (Select0 (DIVVU (ZeroExt8to64 x) (ZeroExt8to64 y)))
-
-// (x + y) / 2 with x>=y => (x - y) / 2 + y
-(Avg64u <t> x y) => (ADDV (SRLVconst <t> (SUBV <t> x y) [1]) y)
-
-(And(64|32|16|8) ...) => (AND ...)
-(Or(64|32|16|8) ...) => (OR ...)
-(Xor(64|32|16|8) ...) => (XOR ...)
-
-// shifts
-// hardware instruction uses only the low 6 bits of the shift
-// we compare to 64 to ensure Go semantics for large shifts
-(Lsh64x64 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SLLV <t> x y))
-(Lsh64x32 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SLLV <t> x (ZeroExt32to64 y)))
-(Lsh64x16 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SLLV <t> x (ZeroExt16to64 y)))
-(Lsh64x8  <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SLLV <t> x (ZeroExt8to64  y)))
-
-(Lsh32x64 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SLLV <t> x y))
-(Lsh32x32 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SLLV <t> x (ZeroExt32to64 y)))
-(Lsh32x16 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SLLV <t> x (ZeroExt16to64 y)))
-(Lsh32x8  <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SLLV <t> x (ZeroExt8to64  y)))
-
-(Lsh16x64 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SLLV <t> x y))
-(Lsh16x32 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SLLV <t> x (ZeroExt32to64 y)))
-(Lsh16x16 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SLLV <t> x (ZeroExt16to64 y)))
-(Lsh16x8  <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SLLV <t> x (ZeroExt8to64  y)))
-
-(Lsh8x64 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SLLV <t> x y))
-(Lsh8x32 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SLLV <t> x (ZeroExt32to64 y)))
-(Lsh8x16 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SLLV <t> x (ZeroExt16to64 y)))
-(Lsh8x8  <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SLLV <t> x (ZeroExt8to64  y)))
-
-(Rsh64Ux64 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SRLV <t> x y))
-(Rsh64Ux32 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SRLV <t> x (ZeroExt32to64 y)))
-(Rsh64Ux16 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SRLV <t> x (ZeroExt16to64 y)))
-(Rsh64Ux8  <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SRLV <t> x (ZeroExt8to64  y)))
-
-(Rsh32Ux64 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SRLV <t> (ZeroExt32to64 x) y))
-(Rsh32Ux32 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SRLV <t> (ZeroExt32to64 x) (ZeroExt32to64 y)))
-(Rsh32Ux16 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SRLV <t> (ZeroExt32to64 x) (ZeroExt16to64 y)))
-(Rsh32Ux8  <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SRLV <t> (ZeroExt32to64 x) (ZeroExt8to64  y)))
-
-(Rsh16Ux64 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SRLV <t> (ZeroExt16to64 x) y))
-(Rsh16Ux32 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SRLV <t> (ZeroExt16to64 x) (ZeroExt32to64 y)))
-(Rsh16Ux16 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SRLV <t> (ZeroExt16to64 x) (ZeroExt16to64 y)))
-(Rsh16Ux8  <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SRLV <t> (ZeroExt16to64 x) (ZeroExt8to64  y)))
-
-(Rsh8Ux64 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SRLV <t> (ZeroExt8to64 x) y))
-(Rsh8Ux32 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SRLV <t> (ZeroExt8to64 x) (ZeroExt32to64 y)))
-(Rsh8Ux16 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SRLV <t> (ZeroExt8to64 x) (ZeroExt16to64 y)))
-(Rsh8Ux8  <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SRLV <t> (ZeroExt8to64 x) (ZeroExt8to64  y)))
-
-(Rsh64x64 <t> x y) => (SRAV x (OR <t> (NEGV <t> (SGTU y (MOVVconst <typ.UInt64> [63]))) y))
-(Rsh64x32 <t> x y) => (SRAV x (OR <t> (NEGV <t> (SGTU (ZeroExt32to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt32to64 y)))
-(Rsh64x16 <t> x y) => (SRAV x (OR <t> (NEGV <t> (SGTU (ZeroExt16to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt16to64 y)))
-(Rsh64x8  <t> x y) => (SRAV x (OR <t> (NEGV <t> (SGTU (ZeroExt8to64  y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt8to64  y)))
-
-(Rsh32x64 <t> x y) => (SRAV (SignExt32to64 x) (OR <t> (NEGV <t> (SGTU y (MOVVconst <typ.UInt64> [63]))) y))
-(Rsh32x32 <t> x y) => (SRAV (SignExt32to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt32to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt32to64 y)))
-(Rsh32x16 <t> x y) => (SRAV (SignExt32to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt16to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt16to64 y)))
-(Rsh32x8  <t> x y) => (SRAV (SignExt32to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt8to64  y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt8to64  y)))
-
-(Rsh16x64 <t> x y) => (SRAV (SignExt16to64 x) (OR <t> (NEGV <t> (SGTU y (MOVVconst <typ.UInt64> [63]))) y))
-(Rsh16x32 <t> x y) => (SRAV (SignExt16to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt32to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt32to64 y)))
-(Rsh16x16 <t> x y) => (SRAV (SignExt16to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt16to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt16to64 y)))
-(Rsh16x8  <t> x y) => (SRAV (SignExt16to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt8to64  y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt8to64  y)))
-
-(Rsh8x64 <t> x y) => (SRAV (SignExt8to64 x) (OR <t> (NEGV <t> (SGTU y (MOVVconst <typ.UInt64> [63]))) y))
-(Rsh8x32 <t> x y) => (SRAV (SignExt8to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt32to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt32to64 y)))
-(Rsh8x16 <t> x y) => (SRAV (SignExt8to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt16to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt16to64 y)))
-(Rsh8x8  <t> x y) => (SRAV (SignExt8to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt8to64  y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt8to64  y)))
-
-// rotates
-(RotateLeft8 <t> x (MOVVconst [c])) => (Or8 (Lsh8x64 <t> x (MOVVconst [c&7])) (Rsh8Ux64 <t> x (MOVVconst [-c&7])))
-(RotateLeft16 <t> x (MOVVconst [c])) => (Or16 (Lsh16x64 <t> x (MOVVconst [c&15])) (Rsh16Ux64 <t> x (MOVVconst [-c&15])))
-(RotateLeft32 <t> x (MOVVconst [c])) => (Or32 (Lsh32x64 <t> x (MOVVconst [c&31])) (Rsh32Ux64 <t> x (MOVVconst [-c&31])))
-(RotateLeft64 <t> x (MOVVconst [c])) => (Or64 (Lsh64x64 <t> x (MOVVconst [c&63])) (Rsh64Ux64 <t> x (MOVVconst [-c&63])))
-
-// unary ops
-(Neg(64|32|16|8) ...) => (NEGV ...)
-(Neg(32|64)F ...) => (NEG(F|D) ...)
-
-(Com(64|32|16|8) x) => (NOR (MOVVconst [0]) x)
-
-(Sqrt ...) => (SQRTD ...)
-(Sqrt32 ...) => (SQRTF ...)
-
-// boolean ops -- booleans are represented with 0=false, 1=true
-(AndB ...) => (AND ...)
-(OrB ...) => (OR ...)
-(EqB x y) => (XOR (MOVVconst [1]) (XOR <typ.Bool> x y))
-(NeqB ...) => (XOR ...)
-(Not x) => (XORconst [1] x)
-
-// constants
-(Const(64|32|16|8) [val]) => (MOVVconst [int64(val)])
-(Const(32|64)F [val]) => (MOV(F|D)const [float64(val)])
-(ConstNil) => (MOVVconst [0])
-(ConstBool [t]) => (MOVVconst [int64(b2i(t))])
-
-(Slicemask <t> x) => (SRAVconst (NEGV <t> x) [63])
-
-// truncations
-// Because we ignore high parts of registers, truncates are just copies.
-(Trunc16to8 ...) => (Copy ...)
-(Trunc32to8 ...) => (Copy ...)
-(Trunc32to16 ...) => (Copy ...)
-(Trunc64to8 ...) => (Copy ...)
-(Trunc64to16 ...) => (Copy ...)
-(Trunc64to32 ...) => (Copy ...)
-
-// Zero-/Sign-extensions
-(ZeroExt8to16 ...) => (MOVBUreg ...)
-(ZeroExt8to32 ...) => (MOVBUreg ...)
-(ZeroExt16to32 ...) => (MOVHUreg ...)
-(ZeroExt8to64 ...) => (MOVBUreg ...)
-(ZeroExt16to64 ...) => (MOVHUreg ...)
-(ZeroExt32to64 ...) => (MOVWUreg ...)
-
-(SignExt8to16 ...) => (MOVBreg ...)
-(SignExt8to32 ...) => (MOVBreg ...)
-(SignExt16to32 ...) => (MOVHreg ...)
-(SignExt8to64 ...) => (MOVBreg ...)
-(SignExt16to64 ...) => (MOVHreg ...)
-(SignExt32to64 ...) => (MOVWreg ...)
-
-// float <=> int conversion
-(Cvt32to32F ...) => (MOVWF ...)
-(Cvt32to64F ...) => (MOVWD ...)
-(Cvt64to32F ...) => (MOVVF ...)
-(Cvt64to64F ...) => (MOVVD ...)
-(Cvt32Fto32 ...) => (TRUNCFW ...)
-(Cvt64Fto32 ...) => (TRUNCDW ...)
-(Cvt32Fto64 ...) => (TRUNCFV ...)
-(Cvt64Fto64 ...) => (TRUNCDV ...)
-(Cvt32Fto64F ...) => (MOVFD ...)
-(Cvt64Fto32F ...) => (MOVDF ...)
-
-(CvtBoolToUint8 ...) => (Copy ...)
-
-(Round(32|64)F ...) => (Copy ...)
-
-// comparisons
-(Eq8 x y)  => (SGTU (MOVVconst [1]) (XOR (ZeroExt8to64 x) (ZeroExt8to64 y)))
-(Eq16 x y) => (SGTU (MOVVconst [1]) (XOR (ZeroExt16to64 x) (ZeroExt16to64 y)))
-(Eq32 x y) => (SGTU (MOVVconst [1]) (XOR (ZeroExt32to64 x) (ZeroExt32to64 y)))
-(Eq64 x y) => (SGTU (MOVVconst [1]) (XOR x y))
-(EqPtr x y) => (SGTU (MOVVconst [1]) (XOR x y))
-(Eq(32|64)F x y) => (FPFlagTrue (CMPEQ(F|D) x y))
-
-(Neq8 x y)  => (SGTU (XOR (ZeroExt8to64 x) (ZeroExt8to64 y)) (MOVVconst [0]))
-(Neq16 x y) => (SGTU (XOR (ZeroExt16to32 x) (ZeroExt16to64 y)) (MOVVconst [0]))
-(Neq32 x y) => (SGTU (XOR (ZeroExt32to64 x) (ZeroExt32to64 y)) (MOVVconst [0]))
-(Neq64 x y) => (SGTU (XOR x y) (MOVVconst [0]))
-(NeqPtr x y) => (SGTU (XOR x y) (MOVVconst [0]))
-(Neq(32|64)F x y) => (FPFlagFalse (CMPEQ(F|D) x y))
-
-(Less8 x y)  => (SGT (SignExt8to64 y) (SignExt8to64 x))
-(Less16 x y) => (SGT (SignExt16to64 y) (SignExt16to64 x))
-(Less32 x y) => (SGT (SignExt32to64 y) (SignExt32to64 x))
-(Less64 x y) => (SGT y x)
-(Less(32|64)F x y) => (FPFlagTrue (CMPGT(F|D) y x)) // reverse operands to work around NaN
-
-(Less8U x y)  => (SGTU (ZeroExt8to64 y) (ZeroExt8to64 x))
-(Less16U x y) => (SGTU (ZeroExt16to64 y) (ZeroExt16to64 x))
-(Less32U x y) => (SGTU (ZeroExt32to64 y) (ZeroExt32to64 x))
-(Less64U x y) => (SGTU y x)
-
-(Leq8 x y)  => (XOR (MOVVconst [1]) (SGT (SignExt8to64 x) (SignExt8to64 y)))
-(Leq16 x y) => (XOR (MOVVconst [1]) (SGT (SignExt16to64 x) (SignExt16to64 y)))
-(Leq32 x y) => (XOR (MOVVconst [1]) (SGT (SignExt32to64 x) (SignExt32to64 y)))
-(Leq64 x y) => (XOR (MOVVconst [1]) (SGT x y))
-(Leq(32|64)F x y) => (FPFlagTrue (CMPGE(F|D) y x)) // reverse operands to work around NaN
-
-(Leq8U x y)  => (XOR (MOVVconst [1]) (SGTU (ZeroExt8to64 x) (ZeroExt8to64 y)))
-(Leq16U x y) => (XOR (MOVVconst [1]) (SGTU (ZeroExt16to64 x) (ZeroExt16to64 y)))
-(Leq32U x y) => (XOR (MOVVconst [1]) (SGTU (ZeroExt32to64 x) (ZeroExt32to64 y)))
-(Leq64U x y) => (XOR (MOVVconst [1]) (SGTU x y))
-
-(OffPtr [off] ptr:(SP)) => (MOVVaddr [int32(off)] ptr)
-(OffPtr [off] ptr) => (ADDVconst [off] ptr)
-
-(Addr {sym} base) => (MOVVaddr {sym} base)
-(LocalAddr {sym} base _) => (MOVVaddr {sym} base)
-
-// loads
-(Load <t> ptr mem) && t.IsBoolean() => (MOVBUload ptr mem)
-(Load <t> ptr mem) && (is8BitInt(t) && isSigned(t)) => (MOVBload ptr mem)
-(Load <t> ptr mem) && (is8BitInt(t) && !isSigned(t)) => (MOVBUload ptr mem)
-(Load <t> ptr mem) && (is16BitInt(t) && isSigned(t)) => (MOVHload ptr mem)
-(Load <t> ptr mem) && (is16BitInt(t) && !isSigned(t)) => (MOVHUload ptr mem)
-(Load <t> ptr mem) && (is32BitInt(t) && isSigned(t)) => (MOVWload ptr mem)
-(Load <t> ptr mem) && (is32BitInt(t) && !isSigned(t)) => (MOVWUload ptr mem)
-(Load <t> ptr mem) && (is64BitInt(t) || isPtr(t)) => (MOVVload ptr mem)
-(Load <t> ptr mem) && is32BitFloat(t) => (MOVFload ptr mem)
-(Load <t> ptr mem) && is64BitFloat(t) => (MOVDload ptr mem)
-
-// stores
-(Store {t} ptr val mem) && t.Size() == 1 => (MOVBstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 2 => (MOVHstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 4 && !is32BitFloat(val.Type) => (MOVWstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 8 && !is64BitFloat(val.Type) => (MOVVstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 4 && is32BitFloat(val.Type) => (MOVFstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 8 && is64BitFloat(val.Type) => (MOVDstore ptr val mem)
-
-// zeroing
-(Zero [0] _ mem) => mem
-(Zero [1] ptr mem) => (MOVBstore ptr (MOVVconst [0]) mem)
-(Zero [2] {t} ptr mem) && t.Alignment()%2 == 0 =>
-	(MOVHstore ptr (MOVVconst [0]) mem)
-(Zero [2] ptr mem) =>
-	(MOVBstore [1] ptr (MOVVconst [0])
-		(MOVBstore [0] ptr (MOVVconst [0]) mem))
-(Zero [4] {t} ptr mem) && t.Alignment()%4 == 0 =>
-	(MOVWstore ptr (MOVVconst [0]) mem)
-(Zero [4] {t} ptr mem) && t.Alignment()%2 == 0 =>
-	(MOVHstore [2] ptr (MOVVconst [0])
-		(MOVHstore [0] ptr (MOVVconst [0]) mem))
-(Zero [4] ptr mem) =>
-	(MOVBstore [3] ptr (MOVVconst [0])
-		(MOVBstore [2] ptr (MOVVconst [0])
-			(MOVBstore [1] ptr (MOVVconst [0])
-				(MOVBstore [0] ptr (MOVVconst [0]) mem))))
-(Zero [8] {t} ptr mem) && t.Alignment()%8 == 0 =>
-	(MOVVstore ptr (MOVVconst [0]) mem)
-(Zero [8] {t} ptr mem) && t.Alignment()%4 == 0 =>
-	(MOVWstore [4] ptr (MOVVconst [0])
-		(MOVWstore [0] ptr (MOVVconst [0]) mem))
-(Zero [8] {t} ptr mem) && t.Alignment()%2 == 0 =>
-	(MOVHstore [6] ptr (MOVVconst [0])
-		(MOVHstore [4] ptr (MOVVconst [0])
-			(MOVHstore [2] ptr (MOVVconst [0])
-				(MOVHstore [0] ptr (MOVVconst [0]) mem))))
-
-(Zero [3] ptr mem) =>
-	(MOVBstore [2] ptr (MOVVconst [0])
-		(MOVBstore [1] ptr (MOVVconst [0])
-			(MOVBstore [0] ptr (MOVVconst [0]) mem)))
-(Zero [6] {t} ptr mem) && t.Alignment()%2 == 0 =>
-	(MOVHstore [4] ptr (MOVVconst [0])
-		(MOVHstore [2] ptr (MOVVconst [0])
-			(MOVHstore [0] ptr (MOVVconst [0]) mem)))
-(Zero [12] {t} ptr mem) && t.Alignment()%4 == 0 =>
-	(MOVWstore [8] ptr (MOVVconst [0])
-		(MOVWstore [4] ptr (MOVVconst [0])
-			(MOVWstore [0] ptr (MOVVconst [0]) mem)))
-(Zero [16] {t} ptr mem) && t.Alignment()%8 == 0 =>
-	(MOVVstore [8] ptr (MOVVconst [0])
-		(MOVVstore [0] ptr (MOVVconst [0]) mem))
-(Zero [24] {t} ptr mem) && t.Alignment()%8 == 0 =>
-	(MOVVstore [16] ptr (MOVVconst [0])
-		(MOVVstore [8] ptr (MOVVconst [0])
-			(MOVVstore [0] ptr (MOVVconst [0]) mem)))
-
-// medium zeroing uses a duff device
-// 8, and 128 are magic constants, see runtime/mkduff.go
-(Zero [s] {t} ptr mem)
-	&& s%8 == 0 && s > 24 && s <= 8*128
-	&& t.Alignment()%8 == 0 && !config.noDuffDevice =>
-	(DUFFZERO [8 * (128 - s/8)] ptr mem)
-
-// large or unaligned zeroing uses a loop
-(Zero [s] {t} ptr mem)
-	&& (s > 8*128 || config.noDuffDevice) || t.Alignment()%8 != 0 =>
-	(LoweredZero [t.Alignment()]
-		ptr
-		(ADDVconst <ptr.Type> ptr [s-moveSize(t.Alignment(), config)])
-		mem)
-
-// moves
-(Move [0] _ _ mem) => mem
-(Move [1] dst src mem) => (MOVBstore dst (MOVBload src mem) mem)
-(Move [2] {t} dst src mem) && t.Alignment()%2 == 0 =>
-	(MOVHstore dst (MOVHload src mem) mem)
-(Move [2] dst src mem) =>
-	(MOVBstore [1] dst (MOVBload [1] src mem)
-		(MOVBstore dst (MOVBload src mem) mem))
-(Move [4] {t} dst src mem) && t.Alignment()%4 == 0 =>
-	(MOVWstore dst (MOVWload src mem) mem)
-(Move [4] {t} dst src mem) && t.Alignment()%2 == 0 =>
-	(MOVHstore [2] dst (MOVHload [2] src mem)
-		(MOVHstore dst (MOVHload src mem) mem))
-(Move [4] dst src mem) =>
-	(MOVBstore [3] dst (MOVBload [3] src mem)
-		(MOVBstore [2] dst (MOVBload [2] src mem)
-			(MOVBstore [1] dst (MOVBload [1] src mem)
-				(MOVBstore dst (MOVBload src mem) mem))))
-(Move [8] {t} dst src mem) && t.Alignment()%8 == 0 =>
-	(MOVVstore dst (MOVVload src mem) mem)
-(Move [8] {t} dst src mem) && t.Alignment()%4 == 0 =>
-	(MOVWstore [4] dst (MOVWload [4] src mem)
-		(MOVWstore dst (MOVWload src mem) mem))
-(Move [8] {t} dst src mem) && t.Alignment()%2 == 0 =>
-	(MOVHstore [6] dst (MOVHload [6] src mem)
-		(MOVHstore [4] dst (MOVHload [4] src mem)
-			(MOVHstore [2] dst (MOVHload [2] src mem)
-				(MOVHstore dst (MOVHload src mem) mem))))
-
-(Move [3] dst src mem) =>
-	(MOVBstore [2] dst (MOVBload [2] src mem)
-		(MOVBstore [1] dst (MOVBload [1] src mem)
-			(MOVBstore dst (MOVBload src mem) mem)))
-(Move [6] {t} dst src mem) && t.Alignment()%2 == 0 =>
-	(MOVHstore [4] dst (MOVHload [4] src mem)
-		(MOVHstore [2] dst (MOVHload [2] src mem)
-			(MOVHstore dst (MOVHload src mem) mem)))
-(Move [12] {t} dst src mem) && t.Alignment()%4 == 0 =>
-	(MOVWstore [8] dst (MOVWload [8] src mem)
-		(MOVWstore [4] dst (MOVWload [4] src mem)
-			(MOVWstore dst (MOVWload src mem) mem)))
-(Move [16] {t} dst src mem) && t.Alignment()%8 == 0 =>
-	(MOVVstore [8] dst (MOVVload [8] src mem)
-		(MOVVstore dst (MOVVload src mem) mem))
-(Move [24] {t} dst src mem) && t.Alignment()%8 == 0 =>
-	(MOVVstore [16] dst (MOVVload [16] src mem)
-		(MOVVstore [8] dst (MOVVload [8] src mem)
-			(MOVVstore dst (MOVVload src mem) mem)))
-
-// medium move uses a duff device
-(Move [s] {t} dst src mem)
-	&& s%8 == 0 && s >= 24 && s <= 8*128 && t.Alignment()%8 == 0
-	&& !config.noDuffDevice && logLargeCopy(v, s)  =>
-	(DUFFCOPY [16 * (128 - s/8)] dst src mem)
-// 16 and 128 are magic constants.  16 is the number of bytes to encode:
-//	MOVV	(R1), R23
-//	ADDV	$8, R1
-//	MOVV	R23, (R2)
-//	ADDV	$8, R2
-// and 128 is the number of such blocks. See runtime/duff_mips64.s:duffcopy.
-
-// large or unaligned move uses a loop
-(Move [s] {t} dst src mem)
-	&& s > 24 && logLargeCopy(v, s) || t.Alignment()%8 != 0 =>
-	(LoweredMove [t.Alignment()]
-		dst
-		src
-		(ADDVconst <src.Type> src [s-moveSize(t.Alignment(), config)])
-		mem)
-
-// calls
-(StaticCall ...) => (CALLstatic ...)
-(ClosureCall ...) => (CALLclosure ...)
-(InterCall ...) => (CALLinter ...)
-(TailCall ...) => (CALLtail ...)
-
-// atomic intrinsics
-(AtomicLoad(8|32|64)   ...) => (LoweredAtomicLoad(8|32|64)  ...)
-(AtomicLoadPtr ...) => (LoweredAtomicLoad64 ...)
-
-(AtomicStore(8|32|64) ...) => (LoweredAtomicStore(8|32|64)  ...)
-(AtomicStorePtrNoWB ...) => (LoweredAtomicStore64 ...)
-
-(AtomicExchange(32|64) ...) => (LoweredAtomicExchange(32|64) ...)
-
-(AtomicAdd(32|64) ...) => (LoweredAtomicAdd(32|64) ...)
-
-(AtomicCompareAndSwap(32|64) ...) => (LoweredAtomicCas(32|64) ...)
-
-// checks
-(NilCheck ...) => (LoweredNilCheck ...)
-(IsNonNil ptr) => (SGTU ptr (MOVVconst [0]))
-(IsInBounds idx len) => (SGTU len idx)
-(IsSliceInBounds idx len) => (XOR (MOVVconst [1]) (SGTU idx len))
-
-// pseudo-ops
-(GetClosurePtr ...) => (LoweredGetClosurePtr ...)
-(GetCallerSP ...) => (LoweredGetCallerSP ...)
-(GetCallerPC ...) => (LoweredGetCallerPC ...)
-
-(If cond yes no) => (NE cond yes no)
-
-// Write barrier.
-(WB ...) => (LoweredWB ...)
-
-(PanicBounds [kind] x y mem) && boundsABI(kind) == 0 => (LoweredPanicBoundsA [kind] x y mem)
-(PanicBounds [kind] x y mem) && boundsABI(kind) == 1 => (LoweredPanicBoundsB [kind] x y mem)
-(PanicBounds [kind] x y mem) && boundsABI(kind) == 2 => (LoweredPanicBoundsC [kind] x y mem)
-
-// Optimizations
-
-// Absorb boolean tests into block
-(NE (FPFlagTrue cmp) yes no) => (FPT cmp yes no)
-(NE (FPFlagFalse cmp) yes no) => (FPF cmp yes no)
-(EQ (FPFlagTrue cmp) yes no) => (FPF cmp yes no)
-(EQ (FPFlagFalse cmp) yes no) => (FPT cmp yes no)
-(NE (XORconst [1] cmp:(SGT _ _)) yes no) => (EQ cmp yes no)
-(NE (XORconst [1] cmp:(SGTU _ _)) yes no) => (EQ cmp yes no)
-(NE (XORconst [1] cmp:(SGTconst _)) yes no) => (EQ cmp yes no)
-(NE (XORconst [1] cmp:(SGTUconst _)) yes no) => (EQ cmp yes no)
-(EQ (XORconst [1] cmp:(SGT _ _)) yes no) => (NE cmp yes no)
-(EQ (XORconst [1] cmp:(SGTU _ _)) yes no) => (NE cmp yes no)
-(EQ (XORconst [1] cmp:(SGTconst _)) yes no) => (NE cmp yes no)
-(EQ (XORconst [1] cmp:(SGTUconst _)) yes no) => (NE cmp yes no)
-(NE (SGTUconst [1] x) yes no) => (EQ x yes no)
-(EQ (SGTUconst [1] x) yes no) => (NE x yes no)
-(NE (SGTU x (MOVVconst [0])) yes no) => (NE x yes no)
-(EQ (SGTU x (MOVVconst [0])) yes no) => (EQ x yes no)
-(NE (SGTconst [0] x) yes no) => (LTZ x yes no)
-(EQ (SGTconst [0] x) yes no) => (GEZ x yes no)
-(NE (SGT x (MOVVconst [0])) yes no) => (GTZ x yes no)
-(EQ (SGT x (MOVVconst [0])) yes no) => (LEZ x yes no)
-
-// fold offset into address
-(ADDVconst [off1] (MOVVaddr [off2] {sym} ptr)) && is32Bit(off1+int64(off2)) => (MOVVaddr [int32(off1)+int32(off2)] {sym} ptr)
-
-// fold address into load/store
-(MOVBload  [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVBload  [off1+int32(off2)] {sym} ptr mem)
-(MOVBUload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVBUload [off1+int32(off2)] {sym} ptr mem)
-(MOVHload  [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVHload  [off1+int32(off2)] {sym} ptr mem)
-(MOVHUload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVHUload [off1+int32(off2)] {sym} ptr mem)
-(MOVWload  [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVWload  [off1+int32(off2)] {sym} ptr mem)
-(MOVWUload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVWUload [off1+int32(off2)] {sym} ptr mem)
-(MOVVload  [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVVload  [off1+int32(off2)] {sym} ptr mem)
-(MOVFload  [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVFload  [off1+int32(off2)] {sym} ptr mem)
-(MOVDload  [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVDload  [off1+int32(off2)] {sym} ptr mem)
-
-(MOVBstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVBstore [off1+int32(off2)] {sym} ptr val mem)
-(MOVHstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVHstore [off1+int32(off2)] {sym} ptr val mem)
-(MOVWstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVWstore [off1+int32(off2)] {sym} ptr val mem)
-(MOVVstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVVstore [off1+int32(off2)] {sym} ptr val mem)
-(MOVFstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVFstore [off1+int32(off2)] {sym} ptr val mem)
-(MOVDstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVDstore [off1+int32(off2)] {sym} ptr val mem)
-(MOVBstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVBstorezero [off1+int32(off2)] {sym} ptr mem)
-(MOVHstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVHstorezero [off1+int32(off2)] {sym} ptr mem)
-(MOVWstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVWstorezero [off1+int32(off2)] {sym} ptr mem)
-(MOVVstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVVstorezero [off1+int32(off2)] {sym} ptr mem)
-
-(MOVBload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVBload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
-(MOVBUload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVBUload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
-(MOVHload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVHload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
-(MOVHUload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVHUload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
-(MOVWload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVWload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
-(MOVWUload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVWUload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
-(MOVVload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVVload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
-(MOVFload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVFload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
-(MOVDload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVDload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
-
-(MOVBstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVBstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem)
-(MOVHstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVHstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem)
-(MOVWstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVWstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem)
-(MOVVstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVVstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem)
-(MOVFstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVFstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem)
-(MOVDstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVDstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem)
-(MOVBstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVBstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
-(MOVHstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVHstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
-(MOVWstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVWstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
-(MOVVstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVVstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
-
-(LoweredAtomicStore(32|64) ptr (MOVVconst [0]) mem) => (LoweredAtomicStorezero(32|64) ptr mem)
-(LoweredAtomicAdd32 ptr (MOVVconst [c]) mem) && is32Bit(c) => (LoweredAtomicAddconst32 [int32(c)] ptr mem)
-(LoweredAtomicAdd64 ptr (MOVVconst [c]) mem) && is32Bit(c) => (LoweredAtomicAddconst64 [c] ptr mem)
-
-// don't extend after proper load
-(MOVBreg x:(MOVBload _ _)) => (MOVVreg x)
-(MOVBUreg x:(MOVBUload _ _)) => (MOVVreg x)
-(MOVHreg x:(MOVBload _ _)) => (MOVVreg x)
-(MOVHreg x:(MOVBUload _ _)) => (MOVVreg x)
-(MOVHreg x:(MOVHload _ _)) => (MOVVreg x)
-(MOVHUreg x:(MOVBUload _ _)) => (MOVVreg x)
-(MOVHUreg x:(MOVHUload _ _)) => (MOVVreg x)
-(MOVWreg x:(MOVBload _ _)) => (MOVVreg x)
-(MOVWreg x:(MOVBUload _ _)) => (MOVVreg x)
-(MOVWreg x:(MOVHload _ _)) => (MOVVreg x)
-(MOVWreg x:(MOVHUload _ _)) => (MOVVreg x)
-(MOVWreg x:(MOVWload _ _)) => (MOVVreg x)
-(MOVWUreg x:(MOVBUload _ _)) => (MOVVreg x)
-(MOVWUreg x:(MOVHUload _ _)) => (MOVVreg x)
-(MOVWUreg x:(MOVWUload _ _)) => (MOVVreg x)
-
-// fold double extensions
-(MOVBreg x:(MOVBreg _)) => (MOVVreg x)
-(MOVBUreg x:(MOVBUreg _)) => (MOVVreg x)
-(MOVHreg x:(MOVBreg _)) => (MOVVreg x)
-(MOVHreg x:(MOVBUreg _)) => (MOVVreg x)
-(MOVHreg x:(MOVHreg _)) => (MOVVreg x)
-(MOVHUreg x:(MOVBUreg _)) => (MOVVreg x)
-(MOVHUreg x:(MOVHUreg _)) => (MOVVreg x)
-(MOVWreg x:(MOVBreg _)) => (MOVVreg x)
-(MOVWreg x:(MOVBUreg _)) => (MOVVreg x)
-(MOVWreg x:(MOVHreg _)) => (MOVVreg x)
-(MOVWreg x:(MOVWreg _)) => (MOVVreg x)
-(MOVWUreg x:(MOVBUreg _)) => (MOVVreg x)
-(MOVWUreg x:(MOVHUreg _)) => (MOVVreg x)
-(MOVWUreg x:(MOVWUreg _)) => (MOVVreg x)
-
-// don't extend before store
-(MOVBstore [off] {sym} ptr (MOVBreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr (MOVBUreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr (MOVHreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr (MOVHUreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr (MOVWreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr (MOVWUreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
-(MOVHstore [off] {sym} ptr (MOVHreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
-(MOVHstore [off] {sym} ptr (MOVHUreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
-(MOVHstore [off] {sym} ptr (MOVWreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
-(MOVHstore [off] {sym} ptr (MOVWUreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
-(MOVWstore [off] {sym} ptr (MOVWreg x) mem) => (MOVWstore [off] {sym} ptr x mem)
-(MOVWstore [off] {sym} ptr (MOVWUreg x) mem) => (MOVWstore [off] {sym} ptr x mem)
-
-// if a register move has only 1 use, just use the same register without emitting instruction
-// MOVVnop doesn't emit instruction, only for ensuring the type.
-(MOVVreg x) && x.Uses == 1 => (MOVVnop x)
-
-// fold constant into arithmetic ops
-(ADDV x (MOVVconst [c])) && is32Bit(c) => (ADDVconst [c] x)
-(SUBV x (MOVVconst [c])) && is32Bit(c) => (SUBVconst [c] x)
-(AND x (MOVVconst [c])) && is32Bit(c) => (ANDconst [c] x)
-(OR  x (MOVVconst [c])) && is32Bit(c) => (ORconst  [c] x)
-(XOR x (MOVVconst [c])) && is32Bit(c) => (XORconst [c] x)
-(NOR x (MOVVconst [c])) && is32Bit(c) => (NORconst [c] x)
-
-(SLLV _ (MOVVconst [c])) && uint64(c)>=64 => (MOVVconst [0])
-(SRLV _ (MOVVconst [c])) && uint64(c)>=64 => (MOVVconst [0])
-(SRAV x (MOVVconst [c])) && uint64(c)>=64 => (SRAVconst x [63])
-(SLLV x (MOVVconst [c])) => (SLLVconst x [c])
-(SRLV x (MOVVconst [c])) => (SRLVconst x [c])
-(SRAV x (MOVVconst [c])) => (SRAVconst x [c])
-
-(SGT  (MOVVconst [c]) x) && is32Bit(c) => (SGTconst  [c] x)
-(SGTU (MOVVconst [c]) x) && is32Bit(c) => (SGTUconst [c] x)
-
-// mul by constant
-(Select1 (MULVU x (MOVVconst [-1]))) => (NEGV x)
-(Select1 (MULVU _ (MOVVconst [0]))) => (MOVVconst [0])
-(Select1 (MULVU x (MOVVconst [1]))) => x
-(Select1 (MULVU x (MOVVconst [c]))) && isPowerOfTwo64(c) => (SLLVconst [log64(c)] x)
-
-// div by constant
-(Select1 (DIVVU x (MOVVconst [1]))) => x
-(Select1 (DIVVU x (MOVVconst [c]))) && isPowerOfTwo64(c) => (SRLVconst [log64(c)] x)
-(Select0 (DIVVU _ (MOVVconst [1]))) => (MOVVconst [0])                       // mod
-(Select0 (DIVVU x (MOVVconst [c]))) && isPowerOfTwo64(c) => (ANDconst [c-1] x) // mod
-
-// generic simplifications
-(ADDV x (NEGV y)) => (SUBV x y)
-(SUBV x x) => (MOVVconst [0])
-(SUBV (MOVVconst [0]) x) => (NEGV x)
-(AND x x) => x
-(OR  x x) => x
-(XOR x x) => (MOVVconst [0])
-
-// remove redundant *const ops
-(ADDVconst [0]  x) => x
-(SUBVconst [0]  x) => x
-(ANDconst [0]  _) => (MOVVconst [0])
-(ANDconst [-1] x) => x
-(ORconst  [0]  x) => x
-(ORconst  [-1] _) => (MOVVconst [-1])
-(XORconst [0]  x) => x
-(XORconst [-1] x) => (NORconst [0] x)
-
-// generic constant folding
-(ADDVconst [c] (MOVVconst [d]))  => (MOVVconst [c+d])
-(ADDVconst [c] (ADDVconst [d] x)) && is32Bit(c+d) => (ADDVconst [c+d] x)
-(ADDVconst [c] (SUBVconst [d] x)) && is32Bit(c-d) => (ADDVconst [c-d] x)
-(SUBVconst [c] (MOVVconst [d]))  => (MOVVconst [d-c])
-(SUBVconst [c] (SUBVconst [d] x)) && is32Bit(-c-d) => (ADDVconst [-c-d] x)
-(SUBVconst [c] (ADDVconst [d] x)) && is32Bit(-c+d) => (ADDVconst [-c+d] x)
-(SLLVconst [c] (MOVVconst [d]))  => (MOVVconst [d<<uint64(c)])
-(SRLVconst [c] (MOVVconst [d]))  => (MOVVconst [int64(uint64(d)>>uint64(c))])
-(SRAVconst [c] (MOVVconst [d]))  => (MOVVconst [d>>uint64(c)])
-(Select1 (MULVU (MOVVconst [c]) (MOVVconst [d]))) => (MOVVconst [c*d])
-(Select1 (DIVV  (MOVVconst [c]) (MOVVconst [d]))) && d != 0 => (MOVVconst [c/d])
-(Select1 (DIVVU (MOVVconst [c]) (MOVVconst [d]))) && d != 0 => (MOVVconst [int64(uint64(c)/uint64(d))])
-(Select0 (DIVV  (MOVVconst [c]) (MOVVconst [d]))) && d != 0 => (MOVVconst [c%d])   // mod
-(Select0 (DIVVU (MOVVconst [c]) (MOVVconst [d]))) && d != 0 => (MOVVconst [int64(uint64(c)%uint64(d))]) // mod
-(ANDconst [c] (MOVVconst [d])) => (MOVVconst [c&d])
-(ANDconst [c] (ANDconst [d] x)) => (ANDconst [c&d] x)
-(ORconst [c] (MOVVconst [d])) => (MOVVconst [c|d])
-(ORconst [c] (ORconst [d] x)) && is32Bit(c|d) => (ORconst [c|d] x)
-(XORconst [c] (MOVVconst [d])) => (MOVVconst [c^d])
-(XORconst [c] (XORconst [d] x)) && is32Bit(c^d) => (XORconst [c^d] x)
-(NORconst [c] (MOVVconst [d])) => (MOVVconst [^(c|d)])
-(NEGV (MOVVconst [c])) => (MOVVconst [-c])
-(MOVBreg  (MOVVconst [c])) => (MOVVconst [int64(int8(c))])
-(MOVBUreg (MOVVconst [c])) => (MOVVconst [int64(uint8(c))])
-(MOVHreg  (MOVVconst [c])) => (MOVVconst [int64(int16(c))])
-(MOVHUreg (MOVVconst [c])) => (MOVVconst [int64(uint16(c))])
-(MOVWreg  (MOVVconst [c])) => (MOVVconst [int64(int32(c))])
-(MOVWUreg (MOVVconst [c])) => (MOVVconst [int64(uint32(c))])
-(MOVVreg  (MOVVconst [c])) => (MOVVconst [c])
-
-// constant comparisons
-(SGTconst [c] (MOVVconst [d])) && c>d => (MOVVconst [1])
-(SGTconst [c] (MOVVconst [d])) && c<=d => (MOVVconst [0])
-(SGTUconst [c] (MOVVconst [d])) && uint64(c)>uint64(d) => (MOVVconst [1])
-(SGTUconst [c] (MOVVconst [d])) && uint64(c)<=uint64(d) => (MOVVconst [0])
-
-// other known comparisons
-(SGTconst [c] (MOVBreg _)) && 0x7f < c => (MOVVconst [1])
-(SGTconst [c] (MOVBreg _)) && c <= -0x80 => (MOVVconst [0])
-(SGTconst [c] (MOVBUreg _)) && 0xff < c => (MOVVconst [1])
-(SGTconst [c] (MOVBUreg _)) && c < 0 => (MOVVconst [0])
-(SGTUconst [c] (MOVBUreg _)) && 0xff < uint64(c) => (MOVVconst [1])
-(SGTconst [c] (MOVHreg _)) && 0x7fff < c => (MOVVconst [1])
-(SGTconst [c] (MOVHreg _)) && c <= -0x8000 => (MOVVconst [0])
-(SGTconst [c] (MOVHUreg _)) && 0xffff < c => (MOVVconst [1])
-(SGTconst [c] (MOVHUreg _)) && c < 0 => (MOVVconst [0])
-(SGTUconst [c] (MOVHUreg _)) && 0xffff < uint64(c) => (MOVVconst [1])
-(SGTconst [c] (MOVWUreg _)) && c < 0 => (MOVVconst [0])
-(SGTconst [c] (ANDconst [m] _)) && 0 <= m && m < c => (MOVVconst [1])
-(SGTUconst [c] (ANDconst [m] _)) && uint64(m) < uint64(c) => (MOVVconst [1])
-(SGTconst [c] (SRLVconst _ [d])) && 0 <= c && 0 < d && d <= 63 && 0xffffffffffffffff>>uint64(d) < uint64(c) => (MOVVconst [1])
-(SGTUconst [c] (SRLVconst _ [d])) && 0 < d && d <= 63 && 0xffffffffffffffff>>uint64(d) < uint64(c) => (MOVVconst [1])
-
-// absorb constants into branches
-(EQ  (MOVVconst [0]) yes no) => (First yes no)
-(EQ  (MOVVconst [c]) yes no) && c != 0 => (First no yes)
-(NE  (MOVVconst [0]) yes no) => (First no yes)
-(NE  (MOVVconst [c]) yes no) && c != 0 => (First yes no)
-(LTZ (MOVVconst [c]) yes no) && c <  0 => (First yes no)
-(LTZ (MOVVconst [c]) yes no) && c >= 0 => (First no yes)
-(LEZ (MOVVconst [c]) yes no) && c <= 0 => (First yes no)
-(LEZ (MOVVconst [c]) yes no) && c >  0 => (First no yes)
-(GTZ (MOVVconst [c]) yes no) && c >  0 => (First yes no)
-(GTZ (MOVVconst [c]) yes no) && c <= 0 => (First no yes)
-(GEZ (MOVVconst [c]) yes no) && c >= 0 => (First yes no)
-(GEZ (MOVVconst [c]) yes no) && c <  0 => (First no yes)
diff --git a/src/cmd/compile/internal/ssa/gen/LOONG64Ops.go b/src/cmd/compile/internal/ssa/gen/LOONG64Ops.go
deleted file mode 100644
index e06ad16..0000000
--- a/src/cmd/compile/internal/ssa/gen/LOONG64Ops.go
+++ /dev/null
@@ -1,480 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build ignore
-// +build ignore
-
-package main
-
-import "strings"
-
-// Notes:
-//  - Integer types live in the low portion of registers. Upper portions are junk.
-//  - Boolean types use the low-order byte of a register. 0=false, 1=true.
-//    Upper bytes are junk.
-//  - *const instructions may use a constant larger than the instruction can encode.
-//    In this case the assembler expands to multiple instructions and uses tmp
-//    register (R23).
-
-// Suffixes encode the bit width of various instructions.
-// V (vlong)     = 64 bit
-// WU (word)     = 32 bit unsigned
-// W (word)      = 32 bit
-// H (half word) = 16 bit
-// HU            = 16 bit unsigned
-// B (byte)      = 8 bit
-// BU            = 8 bit unsigned
-// F (float)     = 32 bit float
-// D (double)    = 64 bit float
-
-// Note: registers not used in regalloc are not included in this list,
-// so that regmask stays within int64
-// Be careful when hand coding regmasks.
-var regNamesLOONG64 = []string{
-	"R0", // constant 0
-	"R1",
-	"SP", // aka R3
-	"R4",
-	"R5",
-	"R6",
-	"R7",
-	"R8",
-	"R9",
-	"R10",
-	"R11",
-	"R12",
-	"R13",
-	"R14",
-	"R15",
-	"R16",
-	"R17",
-	"R18",
-	"R19",
-	"R20",
-	"R21",
-	"g", // aka R22
-	"R23",
-	"R24",
-	"R25",
-	"R26",
-	"R27",
-	"R28",
-	"R29",
-	// R30 is REGTMP not used in regalloc
-	"R31",
-
-	"F0",
-	"F1",
-	"F2",
-	"F3",
-	"F4",
-	"F5",
-	"F6",
-	"F7",
-	"F8",
-	"F9",
-	"F10",
-	"F11",
-	"F12",
-	"F13",
-	"F14",
-	"F15",
-	"F16",
-	"F17",
-	"F18",
-	"F19",
-	"F20",
-	"F21",
-	"F22",
-	"F23",
-	"F24",
-	"F25",
-	"F26",
-	"F27",
-	"F28",
-	"F29",
-	"F30",
-	"F31",
-
-	// If you add registers, update asyncPreempt in runtime.
-
-	// pseudo-registers
-	"SB",
-}
-
-func init() {
-	// Make map from reg names to reg integers.
-	if len(regNamesLOONG64) > 64 {
-		panic("too many registers")
-	}
-	num := map[string]int{}
-	for i, name := range regNamesLOONG64 {
-		num[name] = i
-	}
-	buildReg := func(s string) regMask {
-		m := regMask(0)
-		for _, r := range strings.Split(s, " ") {
-			if n, ok := num[r]; ok {
-				m |= regMask(1) << uint(n)
-				continue
-			}
-			panic("register " + r + " not found")
-		}
-		return m
-	}
-
-	// Common individual register masks
-	var (
-		gp         = buildReg("R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31") // R1 is LR, R2 is thread pointer, R3 is stack pointer, R21-unused, R22 is g, R30 is REGTMP
-		gps        = buildReg("R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31") | buildReg("g")
-		gpg        = gp | buildReg("g")
-		gpsp       = gp | buildReg("SP")
-		gpspg      = gpg | buildReg("SP")
-		gpspsbg    = gpspg | buildReg("SB")
-		fp         = buildReg("F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31")
-		callerSave = gp | fp | buildReg("g") // runtime.setg (and anything calling it) may clobber g
-		r1         = buildReg("R19")
-		r2         = buildReg("R18")
-		r3         = buildReg("R17")
-		r4         = buildReg("R4")
-	)
-	// Common regInfo
-	var (
-		gp01      = regInfo{inputs: nil, outputs: []regMask{gp}}
-		gp11      = regInfo{inputs: []regMask{gpg}, outputs: []regMask{gp}}
-		gp11sp    = regInfo{inputs: []regMask{gpspg}, outputs: []regMask{gp}}
-		gp21      = regInfo{inputs: []regMask{gpg, gpg}, outputs: []regMask{gp}}
-		gpmuldiv  = regInfo{inputs: []regMask{gps, gps}, outputs: []regMask{buildReg("R17"), buildReg("R18")}}
-		gpload    = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{gp}}
-		gpstore   = regInfo{inputs: []regMask{gpspsbg, gpg}}
-		gpstore0  = regInfo{inputs: []regMask{gpspsbg}}
-		gpxchg    = regInfo{inputs: []regMask{gpspsbg, gpg}, outputs: []regMask{gp}}
-		gpcas     = regInfo{inputs: []regMask{gpspsbg, gpg, gpg}, outputs: []regMask{gp}}
-		fp01      = regInfo{inputs: nil, outputs: []regMask{fp}}
-		fp11      = regInfo{inputs: []regMask{fp}, outputs: []regMask{fp}}
-		fp21      = regInfo{inputs: []regMask{fp, fp}, outputs: []regMask{fp}}
-		fp2flags  = regInfo{inputs: []regMask{fp, fp}}
-		fpload    = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{fp}}
-		fpstore   = regInfo{inputs: []regMask{gpspsbg, fp}}
-		readflags = regInfo{inputs: nil, outputs: []regMask{gp}}
-	)
-	ops := []opData{
-		// binary ops
-		{name: "ADDV", argLength: 2, reg: gp21, asm: "ADDVU", commutative: true},   // arg0 + arg1
-		{name: "ADDVconst", argLength: 1, reg: gp11sp, asm: "ADDVU", aux: "Int64"}, // arg0 + auxInt. auxInt is 32-bit, also in other *const ops.
-		{name: "SUBV", argLength: 2, reg: gp21, asm: "SUBVU"},                      // arg0 - arg1
-		{name: "SUBVconst", argLength: 1, reg: gp11, asm: "SUBVU", aux: "Int64"},   // arg0 - auxInt
-
-		{name: "MULV", argLength: 2, reg: gpmuldiv, commutative: true, typ: "(Int64,Int64)"},    // arg0 * arg1, signed
-		{name: "MULVU", argLength: 2, reg: gpmuldiv, commutative: true, typ: "(UInt64,UInt64)"}, // arg0 * arg1, unsigned
-		{name: "DIVV", argLength: 2, reg: gpmuldiv, typ: "(Int64,Int64)"},                       // arg0 / arg1, signed
-		{name: "DIVVU", argLength: 2, reg: gpmuldiv, typ: "(UInt64,UInt64)"},                    // arg0 / arg1, unsigned
-
-		{name: "ADDF", argLength: 2, reg: fp21, asm: "ADDF", commutative: true}, // arg0 + arg1
-		{name: "ADDD", argLength: 2, reg: fp21, asm: "ADDD", commutative: true}, // arg0 + arg1
-		{name: "SUBF", argLength: 2, reg: fp21, asm: "SUBF"},                    // arg0 - arg1
-		{name: "SUBD", argLength: 2, reg: fp21, asm: "SUBD"},                    // arg0 - arg1
-		{name: "MULF", argLength: 2, reg: fp21, asm: "MULF", commutative: true}, // arg0 * arg1
-		{name: "MULD", argLength: 2, reg: fp21, asm: "MULD", commutative: true}, // arg0 * arg1
-		{name: "DIVF", argLength: 2, reg: fp21, asm: "DIVF"},                    // arg0 / arg1
-		{name: "DIVD", argLength: 2, reg: fp21, asm: "DIVD"},                    // arg0 / arg1
-
-		{name: "AND", argLength: 2, reg: gp21, asm: "AND", commutative: true},                // arg0 & arg1
-		{name: "ANDconst", argLength: 1, reg: gp11, asm: "AND", aux: "Int64"},                // arg0 & auxInt
-		{name: "OR", argLength: 2, reg: gp21, asm: "OR", commutative: true},                  // arg0 | arg1
-		{name: "ORconst", argLength: 1, reg: gp11, asm: "OR", aux: "Int64"},                  // arg0 | auxInt
-		{name: "XOR", argLength: 2, reg: gp21, asm: "XOR", commutative: true, typ: "UInt64"}, // arg0 ^ arg1
-		{name: "XORconst", argLength: 1, reg: gp11, asm: "XOR", aux: "Int64", typ: "UInt64"}, // arg0 ^ auxInt
-		{name: "NOR", argLength: 2, reg: gp21, asm: "NOR", commutative: true},                // ^(arg0 | arg1)
-		{name: "NORconst", argLength: 1, reg: gp11, asm: "NOR", aux: "Int64"},                // ^(arg0 | auxInt)
-
-		{name: "NEGV", argLength: 1, reg: gp11},                // -arg0
-		{name: "NEGF", argLength: 1, reg: fp11, asm: "NEGF"},   // -arg0, float32
-		{name: "NEGD", argLength: 1, reg: fp11, asm: "NEGD"},   // -arg0, float64
-		{name: "SQRTD", argLength: 1, reg: fp11, asm: "SQRTD"}, // sqrt(arg0), float64
-		{name: "SQRTF", argLength: 1, reg: fp11, asm: "SQRTF"}, // sqrt(arg0), float32
-
-		// shifts
-		{name: "SLLV", argLength: 2, reg: gp21, asm: "SLLV"},                    // arg0 << arg1, shift amount is mod 64
-		{name: "SLLVconst", argLength: 1, reg: gp11, asm: "SLLV", aux: "Int64"}, // arg0 << auxInt
-		{name: "SRLV", argLength: 2, reg: gp21, asm: "SRLV"},                    // arg0 >> arg1, unsigned, shift amount is mod 64
-		{name: "SRLVconst", argLength: 1, reg: gp11, asm: "SRLV", aux: "Int64"}, // arg0 >> auxInt, unsigned
-		{name: "SRAV", argLength: 2, reg: gp21, asm: "SRAV"},                    // arg0 >> arg1, signed, shift amount is mod 64
-		{name: "SRAVconst", argLength: 1, reg: gp11, asm: "SRAV", aux: "Int64"}, // arg0 >> auxInt, signed
-
-		// comparisons
-		{name: "SGT", argLength: 2, reg: gp21, asm: "SGT", typ: "Bool"},                      // 1 if arg0 > arg1 (signed), 0 otherwise
-		{name: "SGTconst", argLength: 1, reg: gp11, asm: "SGT", aux: "Int64", typ: "Bool"},   // 1 if auxInt > arg0 (signed), 0 otherwise
-		{name: "SGTU", argLength: 2, reg: gp21, asm: "SGTU", typ: "Bool"},                    // 1 if arg0 > arg1 (unsigned), 0 otherwise
-		{name: "SGTUconst", argLength: 1, reg: gp11, asm: "SGTU", aux: "Int64", typ: "Bool"}, // 1 if auxInt > arg0 (unsigned), 0 otherwise
-
-		{name: "CMPEQF", argLength: 2, reg: fp2flags, asm: "CMPEQF", typ: "Flags"}, // flags=true if arg0 = arg1, float32
-		{name: "CMPEQD", argLength: 2, reg: fp2flags, asm: "CMPEQD", typ: "Flags"}, // flags=true if arg0 = arg1, float64
-		{name: "CMPGEF", argLength: 2, reg: fp2flags, asm: "CMPGEF", typ: "Flags"}, // flags=true if arg0 >= arg1, float32
-		{name: "CMPGED", argLength: 2, reg: fp2flags, asm: "CMPGED", typ: "Flags"}, // flags=true if arg0 >= arg1, float64
-		{name: "CMPGTF", argLength: 2, reg: fp2flags, asm: "CMPGTF", typ: "Flags"}, // flags=true if arg0 > arg1, float32
-		{name: "CMPGTD", argLength: 2, reg: fp2flags, asm: "CMPGTD", typ: "Flags"}, // flags=true if arg0 > arg1, float64
-
-		// moves
-		{name: "MOVVconst", argLength: 0, reg: gp01, aux: "Int64", asm: "MOVV", typ: "UInt64", rematerializeable: true},    // auxint
-		{name: "MOVFconst", argLength: 0, reg: fp01, aux: "Float64", asm: "MOVF", typ: "Float32", rematerializeable: true}, // auxint as 64-bit float, convert to 32-bit float
-		{name: "MOVDconst", argLength: 0, reg: fp01, aux: "Float64", asm: "MOVD", typ: "Float64", rematerializeable: true}, // auxint as 64-bit float
-
-		{name: "MOVVaddr", argLength: 1, reg: regInfo{inputs: []regMask{buildReg("SP") | buildReg("SB")}, outputs: []regMask{gp}}, aux: "SymOff", asm: "MOVV", rematerializeable: true, symEffect: "Addr"}, // arg0 + auxInt + aux.(*gc.Sym), arg0=SP/SB
-
-		{name: "MOVBload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVB", typ: "Int8", faultOnNilArg0: true, symEffect: "Read"},     // load from arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVBUload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVBU", typ: "UInt8", faultOnNilArg0: true, symEffect: "Read"},  // load from arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVHload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVH", typ: "Int16", faultOnNilArg0: true, symEffect: "Read"},    // load from arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVHUload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVHU", typ: "UInt16", faultOnNilArg0: true, symEffect: "Read"}, // load from arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVWload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVW", typ: "Int32", faultOnNilArg0: true, symEffect: "Read"},    // load from arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVWUload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVWU", typ: "UInt32", faultOnNilArg0: true, symEffect: "Read"}, // load from arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVVload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVV", typ: "UInt64", faultOnNilArg0: true, symEffect: "Read"},   // load from arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVFload", argLength: 2, reg: fpload, aux: "SymOff", asm: "MOVF", typ: "Float32", faultOnNilArg0: true, symEffect: "Read"},  // load from arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVDload", argLength: 2, reg: fpload, aux: "SymOff", asm: "MOVD", typ: "Float64", faultOnNilArg0: true, symEffect: "Read"},  // load from arg0 + auxInt + aux.  arg1=mem.
-
-		{name: "MOVBstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVB", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 1 byte of arg1 to arg0 + auxInt + aux.  arg2=mem.
-		{name: "MOVHstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVH", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 2 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
-		{name: "MOVWstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVW", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
-		{name: "MOVVstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVV", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
-		{name: "MOVFstore", argLength: 3, reg: fpstore, aux: "SymOff", asm: "MOVF", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
-		{name: "MOVDstore", argLength: 3, reg: fpstore, aux: "SymOff", asm: "MOVD", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
-
-		{name: "MOVBstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVB", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 1 byte of zero to arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVHstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVH", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 2 bytes of zero to arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVWstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVW", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes of zero to arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVVstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVV", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes of zero to arg0 + auxInt + aux.  ar12=mem.
-
-		// conversions
-		{name: "MOVBreg", argLength: 1, reg: gp11, asm: "MOVB"},   // move from arg0, sign-extended from byte
-		{name: "MOVBUreg", argLength: 1, reg: gp11, asm: "MOVBU"}, // move from arg0, unsign-extended from byte
-		{name: "MOVHreg", argLength: 1, reg: gp11, asm: "MOVH"},   // move from arg0, sign-extended from half
-		{name: "MOVHUreg", argLength: 1, reg: gp11, asm: "MOVHU"}, // move from arg0, unsign-extended from half
-		{name: "MOVWreg", argLength: 1, reg: gp11, asm: "MOVW"},   // move from arg0, sign-extended from word
-		{name: "MOVWUreg", argLength: 1, reg: gp11, asm: "MOVWU"}, // move from arg0, unsign-extended from word
-		{name: "MOVVreg", argLength: 1, reg: gp11, asm: "MOVV"},   // move from arg0
-
-		{name: "MOVVnop", argLength: 1, reg: regInfo{inputs: []regMask{gp}, outputs: []regMask{gp}}, resultInArg0: true}, // nop, return arg0 in same register
-
-		{name: "MOVWF", argLength: 1, reg: fp11, asm: "MOVWF"},     // int32 -> float32
-		{name: "MOVWD", argLength: 1, reg: fp11, asm: "MOVWD"},     // int32 -> float64
-		{name: "MOVVF", argLength: 1, reg: fp11, asm: "MOVVF"},     // int64 -> float32
-		{name: "MOVVD", argLength: 1, reg: fp11, asm: "MOVVD"},     // int64 -> float64
-		{name: "TRUNCFW", argLength: 1, reg: fp11, asm: "TRUNCFW"}, // float32 -> int32
-		{name: "TRUNCDW", argLength: 1, reg: fp11, asm: "TRUNCDW"}, // float64 -> int32
-		{name: "TRUNCFV", argLength: 1, reg: fp11, asm: "TRUNCFV"}, // float32 -> int64
-		{name: "TRUNCDV", argLength: 1, reg: fp11, asm: "TRUNCDV"}, // float64 -> int64
-		{name: "MOVFD", argLength: 1, reg: fp11, asm: "MOVFD"},     // float32 -> float64
-		{name: "MOVDF", argLength: 1, reg: fp11, asm: "MOVDF"},     // float64 -> float32
-
-		// function calls
-		{name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                                               // call static function aux.(*obj.LSym).  arg0=mem, auxint=argsize, returns mem
-		{name: "CALLtail", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                                                 // tail call static function aux.(*obj.LSym).  arg0=mem, auxint=argsize, returns mem
-		{name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{gpsp, buildReg("R29"), 0}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call function via closure.  arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem
-		{name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                         // call fn by pointer.  arg0=codeptr, arg1=mem, auxint=argsize, returns mem
-
-		// duffzero
-		// arg0 = address of memory to zero
-		// arg1 = mem
-		// auxint = offset into duffzero code to start executing
-		// returns mem
-		// R19 aka loong64.REGRT1 changed as side effect
-		{
-			name:      "DUFFZERO",
-			aux:       "Int64",
-			argLength: 2,
-			reg: regInfo{
-				inputs:   []regMask{gp},
-				clobbers: buildReg("R19 R1"),
-			},
-			faultOnNilArg0: true,
-		},
-
-		// duffcopy
-		// arg0 = address of dst memory (in R20, changed as side effect) REGRT2
-		// arg1 = address of src memory (in R19, changed as side effect) REGRT1
-		// arg2 = mem
-		// auxint = offset into duffcopy code to start executing
-		// returns mem
-		{
-			name:      "DUFFCOPY",
-			aux:       "Int64",
-			argLength: 3,
-			reg: regInfo{
-				inputs:   []regMask{buildReg("R20"), buildReg("R19")},
-				clobbers: buildReg("R19 R20 R1"),
-			},
-			faultOnNilArg0: true,
-			faultOnNilArg1: true,
-		},
-
-		// large or unaligned zeroing
-		// arg0 = address of memory to zero (in R19, changed as side effect)
-		// arg1 = address of the last element to zero
-		// arg2 = mem
-		// auxint = alignment
-		// returns mem
-		//	SUBV	$8, R19
-		//	MOVV	R0, 8(R19)
-		//	ADDV	$8, R19
-		//	BNE	Rarg1, R19, -2(PC)
-		{
-			name:      "LoweredZero",
-			aux:       "Int64",
-			argLength: 3,
-			reg: regInfo{
-				inputs:   []regMask{buildReg("R19"), gp},
-				clobbers: buildReg("R19"),
-			},
-			clobberFlags:   true,
-			faultOnNilArg0: true,
-		},
-
-		// large or unaligned move
-		// arg0 = address of dst memory (in R4, changed as side effect)
-		// arg1 = address of src memory (in R19, changed as side effect)
-		// arg2 = address of the last element of src
-		// arg3 = mem
-		// auxint = alignment
-		// returns mem
-		//	SUBV	$8, R19
-		//	MOVV	8(R19), Rtmp
-		//	MOVV	Rtmp, (R4)
-		//	ADDV	$8, R19
-		//	ADDV	$8, R4
-		//	BNE	Rarg2, R19, -4(PC)
-		{
-			name:      "LoweredMove",
-			aux:       "Int64",
-			argLength: 4,
-			reg: regInfo{
-				inputs:   []regMask{buildReg("R4"), buildReg("R19"), gp},
-				clobbers: buildReg("R19 R4"),
-			},
-			clobberFlags:   true,
-			faultOnNilArg0: true,
-			faultOnNilArg1: true,
-		},
-
-		// atomic loads.
-		// load from arg0. arg1=mem.
-		// returns <value,memory> so they can be properly ordered with other loads.
-		{name: "LoweredAtomicLoad8", argLength: 2, reg: gpload, faultOnNilArg0: true},
-		{name: "LoweredAtomicLoad32", argLength: 2, reg: gpload, faultOnNilArg0: true},
-		{name: "LoweredAtomicLoad64", argLength: 2, reg: gpload, faultOnNilArg0: true},
-
-		// atomic stores.
-		// store arg1 to arg0. arg2=mem. returns memory.
-		{name: "LoweredAtomicStore8", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true},
-		{name: "LoweredAtomicStore32", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true},
-		{name: "LoweredAtomicStore64", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true},
-		// store zero to arg0. arg1=mem. returns memory.
-		{name: "LoweredAtomicStorezero32", argLength: 2, reg: gpstore0, faultOnNilArg0: true, hasSideEffects: true},
-		{name: "LoweredAtomicStorezero64", argLength: 2, reg: gpstore0, faultOnNilArg0: true, hasSideEffects: true},
-
-		// atomic exchange.
-		// store arg1 to arg0. arg2=mem. returns <old content of *arg0, memory>.
-		// DBAR
-		// LL	(Rarg0), Rout
-		// MOVV Rarg1, Rtmp
-		// SC	Rtmp, (Rarg0)
-		// BEQ	Rtmp, -3(PC)
-		// DBAR
-		{name: "LoweredAtomicExchange32", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-		{name: "LoweredAtomicExchange64", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-
-		// atomic add.
-		// *arg0 += arg1. arg2=mem. returns <new content of *arg0, memory>.
-		// DBAR
-		// LL	(Rarg0), Rout
-		// ADDV Rarg1, Rout, Rtmp
-		// SC	Rtmp, (Rarg0)
-		// BEQ	Rtmp, -3(PC)
-		// DBAR
-		// ADDV Rarg1, Rout
-		{name: "LoweredAtomicAdd32", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-		{name: "LoweredAtomicAdd64", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-		// *arg0 += auxint. arg1=mem. returns <new content of *arg0, memory>. auxint is 32-bit.
-		{name: "LoweredAtomicAddconst32", argLength: 2, reg: regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{gp}}, aux: "Int32", resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-		{name: "LoweredAtomicAddconst64", argLength: 2, reg: regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{gp}}, aux: "Int64", resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-
-		// atomic compare and swap.
-		// arg0 = pointer, arg1 = old value, arg2 = new value, arg3 = memory.
-		// if *arg0 == arg1 {
-		//   *arg0 = arg2
-		//   return (true, memory)
-		// } else {
-		//   return (false, memory)
-		// }
-		// DBAR
-		// MOVV $0, Rout
-		// LL	(Rarg0), Rtmp
-		// BNE	Rtmp, Rarg1, 4(PC)
-		// MOVV Rarg2, Rout
-		// SC	Rout, (Rarg0)
-		// BEQ	Rout, -4(PC)
-		// DBAR
-		{name: "LoweredAtomicCas32", argLength: 4, reg: gpcas, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-		{name: "LoweredAtomicCas64", argLength: 4, reg: gpcas, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-
-		// pseudo-ops
-		{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpg}}, nilCheck: true, faultOnNilArg0: true}, // panic if arg0 is nil.  arg1=mem.
-
-		{name: "FPFlagTrue", argLength: 1, reg: readflags},  // bool, true if FP flag is true
-		{name: "FPFlagFalse", argLength: 1, reg: readflags}, // bool, true if FP flag is false
-
-		// Scheduler ensures LoweredGetClosurePtr occurs only in entry block,
-		// and sorts it to the very beginning of the block to prevent other
-		// use of R22 (loong64.REGCTXT, the closure pointer)
-		{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R29")}}, zeroWidth: true},
-
-		// LoweredGetCallerSP returns the SP of the caller of the current function.
-		{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
-
-		// LoweredGetCallerPC evaluates to the PC to which its "caller" will return.
-		// I.e., if f calls g "calls" getcallerpc,
-		// the result should be the PC within f that g will return to.
-		// See runtime/stubs.go for a more detailed discussion.
-		{name: "LoweredGetCallerPC", reg: gp01, rematerializeable: true},
-
-		// LoweredWB invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
-		// It saves all GP registers if necessary,
-		// but clobbers R1 (LR) because it's a call
-		// and R30 (REGTMP).
-		{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R27"), buildReg("R28")}, clobbers: (callerSave &^ gpg) | buildReg("R1")}, clobberFlags: true, aux: "Sym", symEffect: "None"},
-
-		// There are three of these functions so that they can have three different register inputs.
-		// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the
-		// default registers to match so we don't need to copy registers around unnecessarily.
-		{name: "LoweredPanicBoundsA", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r3, r4}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
-		{name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r2, r3}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
-		{name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r1, r2}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
-	}
-
-	blocks := []blockData{
-		{name: "EQ", controls: 1},
-		{name: "NE", controls: 1},
-		{name: "LTZ", controls: 1}, // < 0
-		{name: "LEZ", controls: 1}, // <= 0
-		{name: "GTZ", controls: 1}, // > 0
-		{name: "GEZ", controls: 1}, // >= 0
-		{name: "FPT", controls: 1}, // FP flag is true
-		{name: "FPF", controls: 1}, // FP flag is false
-	}
-
-	archs = append(archs, arch{
-		name:     "LOONG64",
-		pkg:      "cmd/internal/obj/loong64",
-		genfile:  "../../loong64/ssa.go",
-		ops:      ops,
-		blocks:   blocks,
-		regnames: regNamesLOONG64,
-		// TODO: support register ABI on loong64
-		ParamIntRegNames:   "R4 R5 R6 R7 R8 R9 R10 R11",
-		ParamFloatRegNames: "F0 F1 F2 F3 F4 F5 F6 F7",
-		gpregmask:          gp,
-		fpregmask:          fp,
-		framepointerreg:    -1, // not used
-		linkreg:            int8(num["R1"]),
-	})
-}
diff --git a/src/cmd/compile/internal/ssa/gen/MIPS64.rules b/src/cmd/compile/internal/ssa/gen/MIPS64.rules
deleted file mode 100644
index 17634af..0000000
--- a/src/cmd/compile/internal/ssa/gen/MIPS64.rules
+++ /dev/null
@@ -1,690 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-(Add(Ptr|64|32|16|8) ...) => (ADDV ...)
-(Add(32|64)F ...) => (ADD(F|D) ...)
-
-(Sub(Ptr|64|32|16|8) ...) => (SUBV ...)
-(Sub(32|64)F ...) => (SUB(F|D) ...)
-
-(Mul(64|32|16|8) x y) => (Select1 (MULVU x y))
-(Mul(32|64)F ...) => (MUL(F|D) ...)
-(Mul64uhilo ...) => (MULVU ...)
-(Select0 (Mul64uover x y)) => (Select1 <typ.UInt64> (MULVU x y))
-(Select1 (Mul64uover x y)) => (SGTU <typ.Bool> (Select0 <typ.UInt64> (MULVU x y)) (MOVVconst <typ.UInt64> [0]))
-
-(Hmul64 x y) => (Select0 (MULV x y))
-(Hmul64u x y) => (Select0 (MULVU x y))
-(Hmul32 x y) => (SRAVconst (Select1 <typ.Int64> (MULV (SignExt32to64 x) (SignExt32to64 y))) [32])
-(Hmul32u x y) => (SRLVconst (Select1 <typ.UInt64> (MULVU (ZeroExt32to64 x) (ZeroExt32to64 y))) [32])
-
-(Div64 x y) => (Select1 (DIVV x y))
-(Div64u x y) => (Select1 (DIVVU x y))
-(Div32 x y) => (Select1 (DIVV (SignExt32to64 x) (SignExt32to64 y)))
-(Div32u x y) => (Select1 (DIVVU (ZeroExt32to64 x) (ZeroExt32to64 y)))
-(Div16 x y) => (Select1 (DIVV (SignExt16to64 x) (SignExt16to64 y)))
-(Div16u x y) => (Select1 (DIVVU (ZeroExt16to64 x) (ZeroExt16to64 y)))
-(Div8 x y) => (Select1 (DIVV (SignExt8to64 x) (SignExt8to64 y)))
-(Div8u x y) => (Select1 (DIVVU (ZeroExt8to64 x) (ZeroExt8to64 y)))
-(Div(32|64)F ...) => (DIV(F|D) ...)
-
-(Mod64 x y) => (Select0 (DIVV x y))
-(Mod64u x y) => (Select0 (DIVVU x y))
-(Mod32 x y) => (Select0 (DIVV (SignExt32to64 x) (SignExt32to64 y)))
-(Mod32u x y) => (Select0 (DIVVU (ZeroExt32to64 x) (ZeroExt32to64 y)))
-(Mod16 x y) => (Select0 (DIVV (SignExt16to64 x) (SignExt16to64 y)))
-(Mod16u x y) => (Select0 (DIVVU (ZeroExt16to64 x) (ZeroExt16to64 y)))
-(Mod8 x y) => (Select0 (DIVV (SignExt8to64 x) (SignExt8to64 y)))
-(Mod8u x y) => (Select0 (DIVVU (ZeroExt8to64 x) (ZeroExt8to64 y)))
-
-// (x + y) / 2 with x>=y => (x - y) / 2 + y
-(Avg64u <t> x y) => (ADDV (SRLVconst <t> (SUBV <t> x y) [1]) y)
-
-(And(64|32|16|8) ...) => (AND ...)
-(Or(64|32|16|8) ...) => (OR ...)
-(Xor(64|32|16|8) ...) => (XOR ...)
-
-// shifts
-// hardware instruction uses only the low 6 bits of the shift
-// we compare to 64 to ensure Go semantics for large shifts
-(Lsh64x64 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SLLV <t> x y))
-(Lsh64x32 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SLLV <t> x (ZeroExt32to64 y)))
-(Lsh64x16 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SLLV <t> x (ZeroExt16to64 y)))
-(Lsh64x8  <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SLLV <t> x (ZeroExt8to64  y)))
-
-(Lsh32x64 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SLLV <t> x y))
-(Lsh32x32 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SLLV <t> x (ZeroExt32to64 y)))
-(Lsh32x16 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SLLV <t> x (ZeroExt16to64 y)))
-(Lsh32x8  <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SLLV <t> x (ZeroExt8to64  y)))
-
-(Lsh16x64 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SLLV <t> x y))
-(Lsh16x32 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SLLV <t> x (ZeroExt32to64 y)))
-(Lsh16x16 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SLLV <t> x (ZeroExt16to64 y)))
-(Lsh16x8  <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SLLV <t> x (ZeroExt8to64  y)))
-
-(Lsh8x64 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SLLV <t> x y))
-(Lsh8x32 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SLLV <t> x (ZeroExt32to64 y)))
-(Lsh8x16 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SLLV <t> x (ZeroExt16to64 y)))
-(Lsh8x8  <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SLLV <t> x (ZeroExt8to64  y)))
-
-(Rsh64Ux64 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SRLV <t> x y))
-(Rsh64Ux32 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SRLV <t> x (ZeroExt32to64 y)))
-(Rsh64Ux16 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SRLV <t> x (ZeroExt16to64 y)))
-(Rsh64Ux8  <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SRLV <t> x (ZeroExt8to64  y)))
-
-(Rsh32Ux64 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SRLV <t> (ZeroExt32to64 x) y))
-(Rsh32Ux32 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SRLV <t> (ZeroExt32to64 x) (ZeroExt32to64 y)))
-(Rsh32Ux16 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SRLV <t> (ZeroExt32to64 x) (ZeroExt16to64 y)))
-(Rsh32Ux8  <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SRLV <t> (ZeroExt32to64 x) (ZeroExt8to64  y)))
-
-(Rsh16Ux64 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SRLV <t> (ZeroExt16to64 x) y))
-(Rsh16Ux32 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SRLV <t> (ZeroExt16to64 x) (ZeroExt32to64 y)))
-(Rsh16Ux16 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SRLV <t> (ZeroExt16to64 x) (ZeroExt16to64 y)))
-(Rsh16Ux8  <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SRLV <t> (ZeroExt16to64 x) (ZeroExt8to64  y)))
-
-(Rsh8Ux64 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) y)) (SRLV <t> (ZeroExt8to64 x) y))
-(Rsh8Ux32 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt32to64 y))) (SRLV <t> (ZeroExt8to64 x) (ZeroExt32to64 y)))
-(Rsh8Ux16 <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt16to64 y))) (SRLV <t> (ZeroExt8to64 x) (ZeroExt16to64 y)))
-(Rsh8Ux8  <t> x y) => (AND (NEGV <t> (SGTU (MOVVconst <typ.UInt64> [64]) (ZeroExt8to64  y))) (SRLV <t> (ZeroExt8to64 x) (ZeroExt8to64  y)))
-
-(Rsh64x64 <t> x y) => (SRAV x (OR <t> (NEGV <t> (SGTU y (MOVVconst <typ.UInt64> [63]))) y))
-(Rsh64x32 <t> x y) => (SRAV x (OR <t> (NEGV <t> (SGTU (ZeroExt32to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt32to64 y)))
-(Rsh64x16 <t> x y) => (SRAV x (OR <t> (NEGV <t> (SGTU (ZeroExt16to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt16to64 y)))
-(Rsh64x8  <t> x y) => (SRAV x (OR <t> (NEGV <t> (SGTU (ZeroExt8to64  y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt8to64  y)))
-
-(Rsh32x64 <t> x y) => (SRAV (SignExt32to64 x) (OR <t> (NEGV <t> (SGTU y (MOVVconst <typ.UInt64> [63]))) y))
-(Rsh32x32 <t> x y) => (SRAV (SignExt32to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt32to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt32to64 y)))
-(Rsh32x16 <t> x y) => (SRAV (SignExt32to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt16to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt16to64 y)))
-(Rsh32x8  <t> x y) => (SRAV (SignExt32to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt8to64  y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt8to64  y)))
-
-(Rsh16x64 <t> x y) => (SRAV (SignExt16to64 x) (OR <t> (NEGV <t> (SGTU y (MOVVconst <typ.UInt64> [63]))) y))
-(Rsh16x32 <t> x y) => (SRAV (SignExt16to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt32to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt32to64 y)))
-(Rsh16x16 <t> x y) => (SRAV (SignExt16to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt16to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt16to64 y)))
-(Rsh16x8  <t> x y) => (SRAV (SignExt16to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt8to64  y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt8to64  y)))
-
-(Rsh8x64 <t> x y) => (SRAV (SignExt8to64 x) (OR <t> (NEGV <t> (SGTU y (MOVVconst <typ.UInt64> [63]))) y))
-(Rsh8x32 <t> x y) => (SRAV (SignExt8to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt32to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt32to64 y)))
-(Rsh8x16 <t> x y) => (SRAV (SignExt8to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt16to64 y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt16to64 y)))
-(Rsh8x8  <t> x y) => (SRAV (SignExt8to64 x) (OR <t> (NEGV <t> (SGTU (ZeroExt8to64  y) (MOVVconst <typ.UInt64> [63]))) (ZeroExt8to64  y)))
-
-// rotates
-(RotateLeft8 <t> x (MOVVconst [c])) => (Or8 (Lsh8x64 <t> x (MOVVconst [c&7])) (Rsh8Ux64 <t> x (MOVVconst [-c&7])))
-(RotateLeft16 <t> x (MOVVconst [c])) => (Or16 (Lsh16x64 <t> x (MOVVconst [c&15])) (Rsh16Ux64 <t> x (MOVVconst [-c&15])))
-(RotateLeft32 <t> x (MOVVconst [c])) => (Or32 (Lsh32x64 <t> x (MOVVconst [c&31])) (Rsh32Ux64 <t> x (MOVVconst [-c&31])))
-(RotateLeft64 <t> x (MOVVconst [c])) => (Or64 (Lsh64x64 <t> x (MOVVconst [c&63])) (Rsh64Ux64 <t> x (MOVVconst [-c&63])))
-
-// unary ops
-(Neg(64|32|16|8) ...) => (NEGV ...)
-(Neg(32|64)F ...) => (NEG(F|D) ...)
-
-(Com(64|32|16|8) x) => (NOR (MOVVconst [0]) x)
-
-(Sqrt ...) => (SQRTD ...)
-(Sqrt32 ...) => (SQRTF ...)
-
-// boolean ops -- booleans are represented with 0=false, 1=true
-(AndB ...) => (AND ...)
-(OrB ...) => (OR ...)
-(EqB x y) => (XOR (MOVVconst [1]) (XOR <typ.Bool> x y))
-(NeqB ...) => (XOR ...)
-(Not x) => (XORconst [1] x)
-
-// constants
-(Const(64|32|16|8) [val]) => (MOVVconst [int64(val)])
-(Const(32|64)F [val]) => (MOV(F|D)const [float64(val)])
-(ConstNil) => (MOVVconst [0])
-(ConstBool [t]) => (MOVVconst [int64(b2i(t))])
-
-(Slicemask <t> x) => (SRAVconst (NEGV <t> x) [63])
-
-// truncations
-// Because we ignore high parts of registers, truncates are just copies.
-(Trunc16to8 ...) => (Copy ...)
-(Trunc32to8 ...) => (Copy ...)
-(Trunc32to16 ...) => (Copy ...)
-(Trunc64to8 ...) => (Copy ...)
-(Trunc64to16 ...) => (Copy ...)
-(Trunc64to32 ...) => (Copy ...)
-
-// Zero-/Sign-extensions
-(ZeroExt8to16 ...) => (MOVBUreg ...)
-(ZeroExt8to32 ...) => (MOVBUreg ...)
-(ZeroExt16to32 ...) => (MOVHUreg ...)
-(ZeroExt8to64 ...) => (MOVBUreg ...)
-(ZeroExt16to64 ...) => (MOVHUreg ...)
-(ZeroExt32to64 ...) => (MOVWUreg ...)
-
-(SignExt8to16 ...) => (MOVBreg ...)
-(SignExt8to32 ...) => (MOVBreg ...)
-(SignExt16to32 ...) => (MOVHreg ...)
-(SignExt8to64 ...) => (MOVBreg ...)
-(SignExt16to64 ...) => (MOVHreg ...)
-(SignExt32to64 ...) => (MOVWreg ...)
-
-// float <=> int conversion
-(Cvt32to32F ...) => (MOVWF ...)
-(Cvt32to64F ...) => (MOVWD ...)
-(Cvt64to32F ...) => (MOVVF ...)
-(Cvt64to64F ...) => (MOVVD ...)
-(Cvt32Fto32 ...) => (TRUNCFW ...)
-(Cvt64Fto32 ...) => (TRUNCDW ...)
-(Cvt32Fto64 ...) => (TRUNCFV ...)
-(Cvt64Fto64 ...) => (TRUNCDV ...)
-(Cvt32Fto64F ...) => (MOVFD ...)
-(Cvt64Fto32F ...) => (MOVDF ...)
-
-(CvtBoolToUint8 ...) => (Copy ...)
-
-(Round(32|64)F ...) => (Copy ...)
-
-// comparisons
-(Eq8 x y)  => (SGTU (MOVVconst [1]) (XOR (ZeroExt8to64 x) (ZeroExt8to64 y)))
-(Eq16 x y) => (SGTU (MOVVconst [1]) (XOR (ZeroExt16to64 x) (ZeroExt16to64 y)))
-(Eq32 x y) => (SGTU (MOVVconst [1]) (XOR (ZeroExt32to64 x) (ZeroExt32to64 y)))
-(Eq64 x y) => (SGTU (MOVVconst [1]) (XOR x y))
-(EqPtr x y) => (SGTU (MOVVconst [1]) (XOR x y))
-(Eq(32|64)F x y) => (FPFlagTrue (CMPEQ(F|D) x y))
-
-(Neq8 x y)  => (SGTU (XOR (ZeroExt8to64 x) (ZeroExt8to64 y)) (MOVVconst [0]))
-(Neq16 x y) => (SGTU (XOR (ZeroExt16to32 x) (ZeroExt16to64 y)) (MOVVconst [0]))
-(Neq32 x y) => (SGTU (XOR (ZeroExt32to64 x) (ZeroExt32to64 y)) (MOVVconst [0]))
-(Neq64 x y) => (SGTU (XOR x y) (MOVVconst [0]))
-(NeqPtr x y) => (SGTU (XOR x y) (MOVVconst [0]))
-(Neq(32|64)F x y) => (FPFlagFalse (CMPEQ(F|D) x y))
-
-(Less8 x y)  => (SGT (SignExt8to64 y) (SignExt8to64 x))
-(Less16 x y) => (SGT (SignExt16to64 y) (SignExt16to64 x))
-(Less32 x y) => (SGT (SignExt32to64 y) (SignExt32to64 x))
-(Less64 x y) => (SGT y x)
-(Less(32|64)F x y) => (FPFlagTrue (CMPGT(F|D) y x)) // reverse operands to work around NaN
-
-(Less8U x y)  => (SGTU (ZeroExt8to64 y) (ZeroExt8to64 x))
-(Less16U x y) => (SGTU (ZeroExt16to64 y) (ZeroExt16to64 x))
-(Less32U x y) => (SGTU (ZeroExt32to64 y) (ZeroExt32to64 x))
-(Less64U x y) => (SGTU y x)
-
-(Leq8 x y)  => (XOR (MOVVconst [1]) (SGT (SignExt8to64 x) (SignExt8to64 y)))
-(Leq16 x y) => (XOR (MOVVconst [1]) (SGT (SignExt16to64 x) (SignExt16to64 y)))
-(Leq32 x y) => (XOR (MOVVconst [1]) (SGT (SignExt32to64 x) (SignExt32to64 y)))
-(Leq64 x y) => (XOR (MOVVconst [1]) (SGT x y))
-(Leq(32|64)F x y) => (FPFlagTrue (CMPGE(F|D) y x)) // reverse operands to work around NaN
-
-(Leq8U x y)  => (XOR (MOVVconst [1]) (SGTU (ZeroExt8to64 x) (ZeroExt8to64 y)))
-(Leq16U x y) => (XOR (MOVVconst [1]) (SGTU (ZeroExt16to64 x) (ZeroExt16to64 y)))
-(Leq32U x y) => (XOR (MOVVconst [1]) (SGTU (ZeroExt32to64 x) (ZeroExt32to64 y)))
-(Leq64U x y) => (XOR (MOVVconst [1]) (SGTU x y))
-
-(OffPtr [off] ptr:(SP)) && is32Bit(off) => (MOVVaddr [int32(off)] ptr)
-(OffPtr [off] ptr) => (ADDVconst [off] ptr)
-
-(Addr {sym} base) => (MOVVaddr {sym} base)
-(LocalAddr {sym} base _) => (MOVVaddr {sym} base)
-
-// loads
-(Load <t> ptr mem) && t.IsBoolean() => (MOVBUload ptr mem)
-(Load <t> ptr mem) && (is8BitInt(t) && isSigned(t)) => (MOVBload ptr mem)
-(Load <t> ptr mem) && (is8BitInt(t) && !isSigned(t)) => (MOVBUload ptr mem)
-(Load <t> ptr mem) && (is16BitInt(t) && isSigned(t)) => (MOVHload ptr mem)
-(Load <t> ptr mem) && (is16BitInt(t) && !isSigned(t)) => (MOVHUload ptr mem)
-(Load <t> ptr mem) && (is32BitInt(t) && isSigned(t)) => (MOVWload ptr mem)
-(Load <t> ptr mem) && (is32BitInt(t) && !isSigned(t)) => (MOVWUload ptr mem)
-(Load <t> ptr mem) && (is64BitInt(t) || isPtr(t)) => (MOVVload ptr mem)
-(Load <t> ptr mem) && is32BitFloat(t) => (MOVFload ptr mem)
-(Load <t> ptr mem) && is64BitFloat(t) => (MOVDload ptr mem)
-
-// stores
-(Store {t} ptr val mem) && t.Size() == 1 => (MOVBstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 2 => (MOVHstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 4 && !is32BitFloat(val.Type) => (MOVWstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 8 && !is64BitFloat(val.Type) => (MOVVstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 4 && is32BitFloat(val.Type) => (MOVFstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 8 && is64BitFloat(val.Type) => (MOVDstore ptr val mem)
-
-// zeroing
-(Zero [0] _ mem) => mem
-(Zero [1] ptr mem) => (MOVBstore ptr (MOVVconst [0]) mem)
-(Zero [2] {t} ptr mem) && t.Alignment()%2 == 0 =>
-	(MOVHstore ptr (MOVVconst [0]) mem)
-(Zero [2] ptr mem) =>
-	(MOVBstore [1] ptr (MOVVconst [0])
-		(MOVBstore [0] ptr (MOVVconst [0]) mem))
-(Zero [4] {t} ptr mem) && t.Alignment()%4 == 0 =>
-	(MOVWstore ptr (MOVVconst [0]) mem)
-(Zero [4] {t} ptr mem) && t.Alignment()%2 == 0 =>
-	(MOVHstore [2] ptr (MOVVconst [0])
-		(MOVHstore [0] ptr (MOVVconst [0]) mem))
-(Zero [4] ptr mem) =>
-	(MOVBstore [3] ptr (MOVVconst [0])
-		(MOVBstore [2] ptr (MOVVconst [0])
-			(MOVBstore [1] ptr (MOVVconst [0])
-				(MOVBstore [0] ptr (MOVVconst [0]) mem))))
-(Zero [8] {t} ptr mem) && t.Alignment()%8 == 0 =>
-	(MOVVstore ptr (MOVVconst [0]) mem)
-(Zero [8] {t} ptr mem) && t.Alignment()%4 == 0 =>
-	(MOVWstore [4] ptr (MOVVconst [0])
-		(MOVWstore [0] ptr (MOVVconst [0]) mem))
-(Zero [8] {t} ptr mem) && t.Alignment()%2 == 0 =>
-	(MOVHstore [6] ptr (MOVVconst [0])
-		(MOVHstore [4] ptr (MOVVconst [0])
-			(MOVHstore [2] ptr (MOVVconst [0])
-				(MOVHstore [0] ptr (MOVVconst [0]) mem))))
-
-(Zero [3] ptr mem) =>
-	(MOVBstore [2] ptr (MOVVconst [0])
-		(MOVBstore [1] ptr (MOVVconst [0])
-			(MOVBstore [0] ptr (MOVVconst [0]) mem)))
-(Zero [6] {t} ptr mem) && t.Alignment()%2 == 0 =>
-	(MOVHstore [4] ptr (MOVVconst [0])
-		(MOVHstore [2] ptr (MOVVconst [0])
-			(MOVHstore [0] ptr (MOVVconst [0]) mem)))
-(Zero [12] {t} ptr mem) && t.Alignment()%4 == 0 =>
-	(MOVWstore [8] ptr (MOVVconst [0])
-		(MOVWstore [4] ptr (MOVVconst [0])
-			(MOVWstore [0] ptr (MOVVconst [0]) mem)))
-(Zero [16] {t} ptr mem) && t.Alignment()%8 == 0 =>
-	(MOVVstore [8] ptr (MOVVconst [0])
-		(MOVVstore [0] ptr (MOVVconst [0]) mem))
-(Zero [24] {t} ptr mem) && t.Alignment()%8 == 0 =>
-	(MOVVstore [16] ptr (MOVVconst [0])
-		(MOVVstore [8] ptr (MOVVconst [0])
-			(MOVVstore [0] ptr (MOVVconst [0]) mem)))
-
-// medium zeroing uses a duff device
-// 8, and 128 are magic constants, see runtime/mkduff.go
-(Zero [s] {t} ptr mem)
-	&& s%8 == 0 && s > 24 && s <= 8*128
-	&& t.Alignment()%8 == 0 && !config.noDuffDevice =>
-	(DUFFZERO [8 * (128 - s/8)] ptr mem)
-
-// large or unaligned zeroing uses a loop
-(Zero [s] {t} ptr mem)
-	&& (s > 8*128 || config.noDuffDevice) || t.Alignment()%8 != 0 =>
-	(LoweredZero [t.Alignment()]
-		ptr
-		(ADDVconst <ptr.Type> ptr [s-moveSize(t.Alignment(), config)])
-		mem)
-
-// moves
-(Move [0] _ _ mem) => mem
-(Move [1] dst src mem) => (MOVBstore dst (MOVBload src mem) mem)
-(Move [2] {t} dst src mem) && t.Alignment()%2 == 0 =>
-	(MOVHstore dst (MOVHload src mem) mem)
-(Move [2] dst src mem) =>
-	(MOVBstore [1] dst (MOVBload [1] src mem)
-		(MOVBstore dst (MOVBload src mem) mem))
-(Move [4] {t} dst src mem) && t.Alignment()%4 == 0 =>
-	(MOVWstore dst (MOVWload src mem) mem)
-(Move [4] {t} dst src mem) && t.Alignment()%2 == 0 =>
-	(MOVHstore [2] dst (MOVHload [2] src mem)
-		(MOVHstore dst (MOVHload src mem) mem))
-(Move [4] dst src mem) =>
-	(MOVBstore [3] dst (MOVBload [3] src mem)
-		(MOVBstore [2] dst (MOVBload [2] src mem)
-			(MOVBstore [1] dst (MOVBload [1] src mem)
-				(MOVBstore dst (MOVBload src mem) mem))))
-(Move [8] {t} dst src mem) && t.Alignment()%8 == 0 =>
-	(MOVVstore dst (MOVVload src mem) mem)
-(Move [8] {t} dst src mem) && t.Alignment()%4 == 0 =>
-	(MOVWstore [4] dst (MOVWload [4] src mem)
-		(MOVWstore dst (MOVWload src mem) mem))
-(Move [8] {t} dst src mem) && t.Alignment()%2 == 0 =>
-	(MOVHstore [6] dst (MOVHload [6] src mem)
-		(MOVHstore [4] dst (MOVHload [4] src mem)
-			(MOVHstore [2] dst (MOVHload [2] src mem)
-				(MOVHstore dst (MOVHload src mem) mem))))
-
-(Move [3] dst src mem) =>
-	(MOVBstore [2] dst (MOVBload [2] src mem)
-		(MOVBstore [1] dst (MOVBload [1] src mem)
-			(MOVBstore dst (MOVBload src mem) mem)))
-(Move [6] {t} dst src mem) && t.Alignment()%2 == 0 =>
-	(MOVHstore [4] dst (MOVHload [4] src mem)
-		(MOVHstore [2] dst (MOVHload [2] src mem)
-			(MOVHstore dst (MOVHload src mem) mem)))
-(Move [12] {t} dst src mem) && t.Alignment()%4 == 0 =>
-	(MOVWstore [8] dst (MOVWload [8] src mem)
-		(MOVWstore [4] dst (MOVWload [4] src mem)
-			(MOVWstore dst (MOVWload src mem) mem)))
-(Move [16] {t} dst src mem) && t.Alignment()%8 == 0 =>
-	(MOVVstore [8] dst (MOVVload [8] src mem)
-		(MOVVstore dst (MOVVload src mem) mem))
-(Move [24] {t} dst src mem) && t.Alignment()%8 == 0 =>
-	(MOVVstore [16] dst (MOVVload [16] src mem)
-		(MOVVstore [8] dst (MOVVload [8] src mem)
-			(MOVVstore dst (MOVVload src mem) mem)))
-
-// medium move uses a duff device
-(Move [s] {t} dst src mem)
-	&& s%8 == 0 && s >= 24 && s <= 8*128 && t.Alignment()%8 == 0
-	&& !config.noDuffDevice && logLargeCopy(v, s)  =>
-	(DUFFCOPY [16 * (128 - s/8)] dst src mem)
-// 16 and 128 are magic constants.  16 is the number of bytes to encode:
-//	MOVV	(R1), R23
-//	ADDV	$8, R1
-//	MOVV	R23, (R2)
-//	ADDV	$8, R2
-// and 128 is the number of such blocks. See runtime/duff_mips64.s:duffcopy.
-
-// large or unaligned move uses a loop
-(Move [s] {t} dst src mem)
-	&& s > 24 && logLargeCopy(v, s) || t.Alignment()%8 != 0 =>
-	(LoweredMove [t.Alignment()]
-		dst
-		src
-		(ADDVconst <src.Type> src [s-moveSize(t.Alignment(), config)])
-		mem)
-
-// calls
-(StaticCall ...) => (CALLstatic ...)
-(ClosureCall ...) => (CALLclosure ...)
-(InterCall ...) => (CALLinter ...)
-(TailCall ...) => (CALLtail ...)
-
-// atomic intrinsics
-(AtomicLoad(8|32|64) ...) => (LoweredAtomicLoad(8|32|64) ...)
-(AtomicLoadPtr ...) => (LoweredAtomicLoad64 ...)
-
-(AtomicStore(8|32|64) ...) => (LoweredAtomicStore(8|32|64) ...)
-(AtomicStorePtrNoWB ...) => (LoweredAtomicStore64 ...)
-
-(AtomicExchange(32|64) ...) => (LoweredAtomicExchange(32|64) ...)
-
-(AtomicAdd(32|64) ...) => (LoweredAtomicAdd(32|64) ...)
-
-(AtomicCompareAndSwap(32|64) ...) => (LoweredAtomicCas(32|64) ...)
-
-// checks
-(NilCheck ...) => (LoweredNilCheck ...)
-(IsNonNil ptr) => (SGTU ptr (MOVVconst [0]))
-(IsInBounds idx len) => (SGTU len idx)
-(IsSliceInBounds idx len) => (XOR (MOVVconst [1]) (SGTU idx len))
-
-// pseudo-ops
-(GetClosurePtr ...) => (LoweredGetClosurePtr ...)
-(GetCallerSP ...) => (LoweredGetCallerSP ...)
-(GetCallerPC ...) => (LoweredGetCallerPC ...)
-
-(If cond yes no) => (NE cond yes no)
-
-// Write barrier.
-(WB ...) => (LoweredWB ...)
-
-(PanicBounds [kind] x y mem) && boundsABI(kind) == 0 => (LoweredPanicBoundsA [kind] x y mem)
-(PanicBounds [kind] x y mem) && boundsABI(kind) == 1 => (LoweredPanicBoundsB [kind] x y mem)
-(PanicBounds [kind] x y mem) && boundsABI(kind) == 2 => (LoweredPanicBoundsC [kind] x y mem)
-
-// Optimizations
-
-// Absorb boolean tests into block
-(NE (FPFlagTrue cmp) yes no) => (FPT cmp yes no)
-(NE (FPFlagFalse cmp) yes no) => (FPF cmp yes no)
-(EQ (FPFlagTrue cmp) yes no) => (FPF cmp yes no)
-(EQ (FPFlagFalse cmp) yes no) => (FPT cmp yes no)
-(NE (XORconst [1] cmp:(SGT _ _)) yes no) => (EQ cmp yes no)
-(NE (XORconst [1] cmp:(SGTU _ _)) yes no) => (EQ cmp yes no)
-(NE (XORconst [1] cmp:(SGTconst _)) yes no) => (EQ cmp yes no)
-(NE (XORconst [1] cmp:(SGTUconst _)) yes no) => (EQ cmp yes no)
-(EQ (XORconst [1] cmp:(SGT _ _)) yes no) => (NE cmp yes no)
-(EQ (XORconst [1] cmp:(SGTU _ _)) yes no) => (NE cmp yes no)
-(EQ (XORconst [1] cmp:(SGTconst _)) yes no) => (NE cmp yes no)
-(EQ (XORconst [1] cmp:(SGTUconst _)) yes no) => (NE cmp yes no)
-(NE (SGTUconst [1] x) yes no) => (EQ x yes no)
-(EQ (SGTUconst [1] x) yes no) => (NE x yes no)
-(NE (SGTU x (MOVVconst [0])) yes no) => (NE x yes no)
-(EQ (SGTU x (MOVVconst [0])) yes no) => (EQ x yes no)
-(NE (SGTconst [0] x) yes no) => (LTZ x yes no)
-(EQ (SGTconst [0] x) yes no) => (GEZ x yes no)
-(NE (SGT x (MOVVconst [0])) yes no) => (GTZ x yes no)
-(EQ (SGT x (MOVVconst [0])) yes no) => (LEZ x yes no)
-
-// fold offset into address
-(ADDVconst [off1] (MOVVaddr [off2] {sym} ptr)) && is32Bit(off1+int64(off2)) => (MOVVaddr [int32(off1)+int32(off2)] {sym} ptr)
-
-// fold address into load/store
-(MOVBload  [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVBload  [off1+int32(off2)] {sym} ptr mem)
-(MOVBUload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVBUload [off1+int32(off2)] {sym} ptr mem)
-(MOVHload  [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVHload  [off1+int32(off2)] {sym} ptr mem)
-(MOVHUload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVHUload [off1+int32(off2)] {sym} ptr mem)
-(MOVWload  [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVWload  [off1+int32(off2)] {sym} ptr mem)
-(MOVWUload [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVWUload [off1+int32(off2)] {sym} ptr mem)
-(MOVVload  [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVVload  [off1+int32(off2)] {sym} ptr mem)
-(MOVFload  [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVFload  [off1+int32(off2)] {sym} ptr mem)
-(MOVDload  [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVDload  [off1+int32(off2)] {sym} ptr mem)
-
-(MOVBstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVBstore [off1+int32(off2)] {sym} ptr val mem)
-(MOVHstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVHstore [off1+int32(off2)] {sym} ptr val mem)
-(MOVWstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVWstore [off1+int32(off2)] {sym} ptr val mem)
-(MOVVstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVVstore [off1+int32(off2)] {sym} ptr val mem)
-(MOVFstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVFstore [off1+int32(off2)] {sym} ptr val mem)
-(MOVDstore [off1] {sym} (ADDVconst [off2] ptr) val mem) && is32Bit(int64(off1)+off2) => (MOVDstore [off1+int32(off2)] {sym} ptr val mem)
-(MOVBstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVBstorezero [off1+int32(off2)] {sym} ptr mem)
-(MOVHstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVHstorezero [off1+int32(off2)] {sym} ptr mem)
-(MOVWstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVWstorezero [off1+int32(off2)] {sym} ptr mem)
-(MOVVstorezero [off1] {sym} (ADDVconst [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVVstorezero [off1+int32(off2)] {sym} ptr mem)
-
-(MOVBload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVBload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
-(MOVBUload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVBUload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
-(MOVHload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVHload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
-(MOVHUload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVHUload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
-(MOVWload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVWload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
-(MOVWUload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVWUload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
-(MOVVload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVVload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
-(MOVFload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVFload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
-(MOVDload [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVDload [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
-
-(MOVBstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVBstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem)
-(MOVHstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVHstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem)
-(MOVWstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVWstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem)
-(MOVVstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVVstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem)
-(MOVFstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVFstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem)
-(MOVDstore [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVDstore [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr val mem)
-(MOVBstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVBstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
-(MOVHstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVHstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
-(MOVWstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVWstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
-(MOVVstorezero [off1] {sym1} (MOVVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVVstorezero [off1+int32(off2)] {mergeSym(sym1,sym2)} ptr mem)
-
-// store zero
-(MOVBstore [off] {sym} ptr (MOVVconst [0]) mem) => (MOVBstorezero [off] {sym} ptr mem)
-(MOVHstore [off] {sym} ptr (MOVVconst [0]) mem) => (MOVHstorezero [off] {sym} ptr mem)
-(MOVWstore [off] {sym} ptr (MOVVconst [0]) mem) => (MOVWstorezero [off] {sym} ptr mem)
-(MOVVstore [off] {sym} ptr (MOVVconst [0]) mem) => (MOVVstorezero [off] {sym} ptr mem)
-
-// don't extend after proper load
-(MOVBreg x:(MOVBload _ _)) => (MOVVreg x)
-(MOVBUreg x:(MOVBUload _ _)) => (MOVVreg x)
-(MOVHreg x:(MOVBload _ _)) => (MOVVreg x)
-(MOVHreg x:(MOVBUload _ _)) => (MOVVreg x)
-(MOVHreg x:(MOVHload _ _)) => (MOVVreg x)
-(MOVHUreg x:(MOVBUload _ _)) => (MOVVreg x)
-(MOVHUreg x:(MOVHUload _ _)) => (MOVVreg x)
-(MOVWreg x:(MOVBload _ _)) => (MOVVreg x)
-(MOVWreg x:(MOVBUload _ _)) => (MOVVreg x)
-(MOVWreg x:(MOVHload _ _)) => (MOVVreg x)
-(MOVWreg x:(MOVHUload _ _)) => (MOVVreg x)
-(MOVWreg x:(MOVWload _ _)) => (MOVVreg x)
-(MOVWUreg x:(MOVBUload _ _)) => (MOVVreg x)
-(MOVWUreg x:(MOVHUload _ _)) => (MOVVreg x)
-(MOVWUreg x:(MOVWUload _ _)) => (MOVVreg x)
-
-// fold double extensions
-(MOVBreg x:(MOVBreg _)) => (MOVVreg x)
-(MOVBUreg x:(MOVBUreg _)) => (MOVVreg x)
-(MOVHreg x:(MOVBreg _)) => (MOVVreg x)
-(MOVHreg x:(MOVBUreg _)) => (MOVVreg x)
-(MOVHreg x:(MOVHreg _)) => (MOVVreg x)
-(MOVHUreg x:(MOVBUreg _)) => (MOVVreg x)
-(MOVHUreg x:(MOVHUreg _)) => (MOVVreg x)
-(MOVWreg x:(MOVBreg _)) => (MOVVreg x)
-(MOVWreg x:(MOVBUreg _)) => (MOVVreg x)
-(MOVWreg x:(MOVHreg _)) => (MOVVreg x)
-(MOVWreg x:(MOVWreg _)) => (MOVVreg x)
-(MOVWUreg x:(MOVBUreg _)) => (MOVVreg x)
-(MOVWUreg x:(MOVHUreg _)) => (MOVVreg x)
-(MOVWUreg x:(MOVWUreg _)) => (MOVVreg x)
-
-// don't extend before store
-(MOVBstore [off] {sym} ptr (MOVBreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr (MOVBUreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr (MOVHreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr (MOVHUreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr (MOVWreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr (MOVWUreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
-(MOVHstore [off] {sym} ptr (MOVHreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
-(MOVHstore [off] {sym} ptr (MOVHUreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
-(MOVHstore [off] {sym} ptr (MOVWreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
-(MOVHstore [off] {sym} ptr (MOVWUreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
-(MOVWstore [off] {sym} ptr (MOVWreg x) mem) => (MOVWstore [off] {sym} ptr x mem)
-(MOVWstore [off] {sym} ptr (MOVWUreg x) mem) => (MOVWstore [off] {sym} ptr x mem)
-
-// if a register move has only 1 use, just use the same register without emitting instruction
-// MOVVnop doesn't emit instruction, only for ensuring the type.
-(MOVVreg x) && x.Uses == 1 => (MOVVnop x)
-
-// TODO: we should be able to get rid of MOVVnop all together.
-// But for now, this is enough to get rid of lots of them.
-(MOVVnop (MOVVconst [c])) => (MOVVconst [c])
-
-// fold constant into arithmetic ops
-(ADDV x (MOVVconst [c])) && is32Bit(c) => (ADDVconst [c] x)
-(SUBV x (MOVVconst [c])) && is32Bit(c) => (SUBVconst [c] x)
-(AND x (MOVVconst [c])) && is32Bit(c) => (ANDconst [c] x)
-(OR  x (MOVVconst [c])) && is32Bit(c) => (ORconst  [c] x)
-(XOR x (MOVVconst [c])) && is32Bit(c) => (XORconst [c] x)
-(NOR x (MOVVconst [c])) && is32Bit(c) => (NORconst [c] x)
-
-(SLLV _ (MOVVconst [c])) && uint64(c)>=64 => (MOVVconst [0])
-(SRLV _ (MOVVconst [c])) && uint64(c)>=64 => (MOVVconst [0])
-(SRAV x (MOVVconst [c])) && uint64(c)>=64 => (SRAVconst x [63])
-(SLLV x (MOVVconst [c])) => (SLLVconst x [c])
-(SRLV x (MOVVconst [c])) => (SRLVconst x [c])
-(SRAV x (MOVVconst [c])) => (SRAVconst x [c])
-
-(SGT  (MOVVconst [c]) x) && is32Bit(c) => (SGTconst  [c] x)
-(SGTU (MOVVconst [c]) x) && is32Bit(c) => (SGTUconst [c] x)
-
-// mul by constant
-(Select1 (MULVU x (MOVVconst [-1]))) => (NEGV x)
-(Select1 (MULVU _ (MOVVconst [0]))) => (MOVVconst [0])
-(Select1 (MULVU x (MOVVconst [1]))) => x
-(Select1 (MULVU x (MOVVconst [c]))) && isPowerOfTwo64(c) => (SLLVconst [log64(c)] x)
-
-// div by constant
-(Select1 (DIVVU x (MOVVconst [1]))) => x
-(Select1 (DIVVU x (MOVVconst [c]))) && isPowerOfTwo64(c) => (SRLVconst [log64(c)] x)
-(Select0 (DIVVU _ (MOVVconst [1]))) => (MOVVconst [0])                       // mod
-(Select0 (DIVVU x (MOVVconst [c]))) && isPowerOfTwo64(c) => (ANDconst [c-1] x) // mod
-
-// generic simplifications
-(ADDV x (NEGV y)) => (SUBV x y)
-(SUBV x x) => (MOVVconst [0])
-(SUBV (MOVVconst [0]) x) => (NEGV x)
-(AND x x) => x
-(OR  x x) => x
-(XOR x x) => (MOVVconst [0])
-
-// remove redundant *const ops
-(ADDVconst [0]  x) => x
-(SUBVconst [0]  x) => x
-(ANDconst [0]  _) => (MOVVconst [0])
-(ANDconst [-1] x) => x
-(ORconst  [0]  x) => x
-(ORconst  [-1] _) => (MOVVconst [-1])
-(XORconst [0]  x) => x
-(XORconst [-1] x) => (NORconst [0] x)
-
-// generic constant folding
-(ADDVconst [c] (MOVVconst [d]))  => (MOVVconst [c+d])
-(ADDVconst [c] (ADDVconst [d] x)) && is32Bit(c+d) => (ADDVconst [c+d] x)
-(ADDVconst [c] (SUBVconst [d] x)) && is32Bit(c-d) => (ADDVconst [c-d] x)
-(SUBVconst [c] (MOVVconst [d]))  => (MOVVconst [d-c])
-(SUBVconst [c] (SUBVconst [d] x)) && is32Bit(-c-d) => (ADDVconst [-c-d] x)
-(SUBVconst [c] (ADDVconst [d] x)) && is32Bit(-c+d) => (ADDVconst [-c+d] x)
-(SLLVconst [c] (MOVVconst [d]))  => (MOVVconst [d<<uint64(c)])
-(SRLVconst [c] (MOVVconst [d]))  => (MOVVconst [int64(uint64(d)>>uint64(c))])
-(SRAVconst [c] (MOVVconst [d]))  => (MOVVconst [d>>uint64(c)])
-(Select1 (MULVU (MOVVconst [c]) (MOVVconst [d]))) => (MOVVconst [c*d])
-(Select1 (DIVV  (MOVVconst [c]) (MOVVconst [d]))) && d != 0 => (MOVVconst [c/d])
-(Select1 (DIVVU (MOVVconst [c]) (MOVVconst [d]))) && d != 0 => (MOVVconst [int64(uint64(c)/uint64(d))])
-(Select0 (DIVV  (MOVVconst [c]) (MOVVconst [d]))) && d != 0 => (MOVVconst [c%d])   // mod
-(Select0 (DIVVU (MOVVconst [c]) (MOVVconst [d]))) && d != 0 => (MOVVconst [int64(uint64(c)%uint64(d))]) // mod
-(ANDconst [c] (MOVVconst [d])) => (MOVVconst [c&d])
-(ANDconst [c] (ANDconst [d] x)) => (ANDconst [c&d] x)
-(ORconst [c] (MOVVconst [d])) => (MOVVconst [c|d])
-(ORconst [c] (ORconst [d] x)) && is32Bit(c|d) => (ORconst [c|d] x)
-(XORconst [c] (MOVVconst [d])) => (MOVVconst [c^d])
-(XORconst [c] (XORconst [d] x)) && is32Bit(c^d) => (XORconst [c^d] x)
-(NORconst [c] (MOVVconst [d])) => (MOVVconst [^(c|d)])
-(NEGV (MOVVconst [c])) => (MOVVconst [-c])
-(MOVBreg  (MOVVconst [c])) => (MOVVconst [int64(int8(c))])
-(MOVBUreg (MOVVconst [c])) => (MOVVconst [int64(uint8(c))])
-(MOVHreg  (MOVVconst [c])) => (MOVVconst [int64(int16(c))])
-(MOVHUreg (MOVVconst [c])) => (MOVVconst [int64(uint16(c))])
-(MOVWreg  (MOVVconst [c])) => (MOVVconst [int64(int32(c))])
-(MOVWUreg (MOVVconst [c])) => (MOVVconst [int64(uint32(c))])
-(MOVVreg  (MOVVconst [c])) => (MOVVconst [c])
-(LoweredAtomicStore(32|64) ptr (MOVVconst [0]) mem) => (LoweredAtomicStorezero(32|64) ptr mem)
-(LoweredAtomicAdd32 ptr (MOVVconst [c]) mem) && is32Bit(c) => (LoweredAtomicAddconst32 [int32(c)] ptr mem)
-(LoweredAtomicAdd64 ptr (MOVVconst [c]) mem) && is32Bit(c) => (LoweredAtomicAddconst64 [c] ptr mem)
-
-// constant comparisons
-(SGTconst [c] (MOVVconst [d])) && c>d => (MOVVconst [1])
-(SGTconst [c] (MOVVconst [d])) && c<=d => (MOVVconst [0])
-(SGTUconst [c] (MOVVconst [d])) && uint64(c)>uint64(d) => (MOVVconst [1])
-(SGTUconst [c] (MOVVconst [d])) && uint64(c)<=uint64(d) => (MOVVconst [0])
-
-// other known comparisons
-(SGTconst [c] (MOVBreg _)) && 0x7f < c => (MOVVconst [1])
-(SGTconst [c] (MOVBreg _)) && c <= -0x80 => (MOVVconst [0])
-(SGTconst [c] (MOVBUreg _)) && 0xff < c => (MOVVconst [1])
-(SGTconst [c] (MOVBUreg _)) && c < 0 => (MOVVconst [0])
-(SGTUconst [c] (MOVBUreg _)) && 0xff < uint64(c) => (MOVVconst [1])
-(SGTconst [c] (MOVHreg _)) && 0x7fff < c => (MOVVconst [1])
-(SGTconst [c] (MOVHreg _)) && c <= -0x8000 => (MOVVconst [0])
-(SGTconst [c] (MOVHUreg _)) && 0xffff < c => (MOVVconst [1])
-(SGTconst [c] (MOVHUreg _)) && c < 0 => (MOVVconst [0])
-(SGTUconst [c] (MOVHUreg _)) && 0xffff < uint64(c) => (MOVVconst [1])
-(SGTconst [c] (MOVWUreg _)) && c < 0 => (MOVVconst [0])
-(SGTconst [c] (ANDconst [m] _)) && 0 <= m && m < c => (MOVVconst [1])
-(SGTUconst [c] (ANDconst [m] _)) && uint64(m) < uint64(c) => (MOVVconst [1])
-(SGTconst [c] (SRLVconst _ [d])) && 0 <= c && 0 < d && d <= 63 && 0xffffffffffffffff>>uint64(d) < uint64(c) => (MOVVconst [1])
-(SGTUconst [c] (SRLVconst _ [d])) && 0 < d && d <= 63 && 0xffffffffffffffff>>uint64(d) < uint64(c) => (MOVVconst [1])
-
-// absorb constants into branches
-(EQ  (MOVVconst [0]) yes no) => (First yes no)
-(EQ  (MOVVconst [c]) yes no) && c != 0 => (First no yes)
-(NE  (MOVVconst [0]) yes no) => (First no yes)
-(NE  (MOVVconst [c]) yes no) && c != 0 => (First yes no)
-(LTZ (MOVVconst [c]) yes no) && c <  0 => (First yes no)
-(LTZ (MOVVconst [c]) yes no) && c >= 0 => (First no yes)
-(LEZ (MOVVconst [c]) yes no) && c <= 0 => (First yes no)
-(LEZ (MOVVconst [c]) yes no) && c >  0 => (First no yes)
-(GTZ (MOVVconst [c]) yes no) && c >  0 => (First yes no)
-(GTZ (MOVVconst [c]) yes no) && c <= 0 => (First no yes)
-(GEZ (MOVVconst [c]) yes no) && c >= 0 => (First yes no)
-(GEZ (MOVVconst [c]) yes no) && c <  0 => (First no yes)
-
-// fold readonly sym load
-(MOVBload [off] {sym} (SB) _) && symIsRO(sym) => (MOVVconst [int64(read8(sym, int64(off)))])
-(MOVHload [off] {sym} (SB) _) && symIsRO(sym) => (MOVVconst [int64(read16(sym, int64(off), config.ctxt.Arch.ByteOrder))])
-(MOVWload [off] {sym} (SB) _) && symIsRO(sym) => (MOVVconst [int64(read32(sym, int64(off), config.ctxt.Arch.ByteOrder))])
-(MOVVload  [off] {sym} (SB) _) && symIsRO(sym) => (MOVVconst [int64(read64(sym, int64(off), config.ctxt.Arch.ByteOrder))])
diff --git a/src/cmd/compile/internal/ssa/gen/MIPS64Ops.go b/src/cmd/compile/internal/ssa/gen/MIPS64Ops.go
deleted file mode 100644
index 7b18c42..0000000
--- a/src/cmd/compile/internal/ssa/gen/MIPS64Ops.go
+++ /dev/null
@@ -1,485 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build ignore
-// +build ignore
-
-package main
-
-import "strings"
-
-// Notes:
-//  - Integer types live in the low portion of registers. Upper portions are junk.
-//  - Boolean types use the low-order byte of a register. 0=false, 1=true.
-//    Upper bytes are junk.
-//  - *const instructions may use a constant larger than the instruction can encode.
-//    In this case the assembler expands to multiple instructions and uses tmp
-//    register (R23).
-
-// Suffixes encode the bit width of various instructions.
-// V (vlong)     = 64 bit
-// WU (word)     = 32 bit unsigned
-// W (word)      = 32 bit
-// H (half word) = 16 bit
-// HU            = 16 bit unsigned
-// B (byte)      = 8 bit
-// BU            = 8 bit unsigned
-// F (float)     = 32 bit float
-// D (double)    = 64 bit float
-
-// Note: registers not used in regalloc are not included in this list,
-// so that regmask stays within int64
-// Be careful when hand coding regmasks.
-var regNamesMIPS64 = []string{
-	"R0", // constant 0
-	"R1",
-	"R2",
-	"R3",
-	"R4",
-	"R5",
-	"R6",
-	"R7",
-	"R8",
-	"R9",
-	"R10",
-	"R11",
-	"R12",
-	"R13",
-	"R14",
-	"R15",
-	"R16",
-	"R17",
-	"R18",
-	"R19",
-	"R20",
-	"R21",
-	"R22",
-	// R23 = REGTMP not used in regalloc
-	"R24",
-	"R25",
-	// R26 reserved by kernel
-	// R27 reserved by kernel
-	// R28 = REGSB not used in regalloc
-	"SP",  // aka R29
-	"g",   // aka R30
-	"R31", // aka REGLINK
-
-	"F0",
-	"F1",
-	"F2",
-	"F3",
-	"F4",
-	"F5",
-	"F6",
-	"F7",
-	"F8",
-	"F9",
-	"F10",
-	"F11",
-	"F12",
-	"F13",
-	"F14",
-	"F15",
-	"F16",
-	"F17",
-	"F18",
-	"F19",
-	"F20",
-	"F21",
-	"F22",
-	"F23",
-	"F24",
-	"F25",
-	"F26",
-	"F27",
-	"F28",
-	"F29",
-	"F30",
-	"F31",
-
-	"HI", // high bits of multiplication
-	"LO", // low bits of multiplication
-
-	// If you add registers, update asyncPreempt in runtime.
-
-	// pseudo-registers
-	"SB",
-}
-
-func init() {
-	// Make map from reg names to reg integers.
-	if len(regNamesMIPS64) > 64 {
-		panic("too many registers")
-	}
-	num := map[string]int{}
-	for i, name := range regNamesMIPS64 {
-		num[name] = i
-	}
-	buildReg := func(s string) regMask {
-		m := regMask(0)
-		for _, r := range strings.Split(s, " ") {
-			if n, ok := num[r]; ok {
-				m |= regMask(1) << uint(n)
-				continue
-			}
-			panic("register " + r + " not found")
-		}
-		return m
-	}
-
-	// Common individual register masks
-	var (
-		gp         = buildReg("R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R31")
-		gpg        = gp | buildReg("g")
-		gpsp       = gp | buildReg("SP")
-		gpspg      = gpg | buildReg("SP")
-		gpspsbg    = gpspg | buildReg("SB")
-		fp         = buildReg("F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31")
-		lo         = buildReg("LO")
-		hi         = buildReg("HI")
-		callerSave = gp | fp | lo | hi | buildReg("g") // runtime.setg (and anything calling it) may clobber g
-		r1         = buildReg("R1")
-		r2         = buildReg("R2")
-		r3         = buildReg("R3")
-		r4         = buildReg("R4")
-	)
-	// Common regInfo
-	var (
-		gp01     = regInfo{inputs: nil, outputs: []regMask{gp}}
-		gp11     = regInfo{inputs: []regMask{gpg}, outputs: []regMask{gp}}
-		gp11sp   = regInfo{inputs: []regMask{gpspg}, outputs: []regMask{gp}}
-		gp21     = regInfo{inputs: []regMask{gpg, gpg}, outputs: []regMask{gp}}
-		gp2hilo  = regInfo{inputs: []regMask{gpg, gpg}, outputs: []regMask{hi, lo}}
-		gpload   = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{gp}}
-		gpstore  = regInfo{inputs: []regMask{gpspsbg, gpg}}
-		gpstore0 = regInfo{inputs: []regMask{gpspsbg}}
-		gpxchg   = regInfo{inputs: []regMask{gpspsbg, gpg}, outputs: []regMask{gp}}
-		gpcas    = regInfo{inputs: []regMask{gpspsbg, gpg, gpg}, outputs: []regMask{gp}}
-		fp01     = regInfo{inputs: nil, outputs: []regMask{fp}}
-		fp11     = regInfo{inputs: []regMask{fp}, outputs: []regMask{fp}}
-		//fp1flags  = regInfo{inputs: []regMask{fp}}
-		//fpgp      = regInfo{inputs: []regMask{fp}, outputs: []regMask{gp}}
-		//gpfp      = regInfo{inputs: []regMask{gp}, outputs: []regMask{fp}}
-		fp21      = regInfo{inputs: []regMask{fp, fp}, outputs: []regMask{fp}}
-		fp2flags  = regInfo{inputs: []regMask{fp, fp}}
-		fpload    = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{fp}}
-		fpstore   = regInfo{inputs: []regMask{gpspsbg, fp}}
-		readflags = regInfo{inputs: nil, outputs: []regMask{gp}}
-	)
-	ops := []opData{
-		// binary ops
-		{name: "ADDV", argLength: 2, reg: gp21, asm: "ADDVU", commutative: true},                             // arg0 + arg1
-		{name: "ADDVconst", argLength: 1, reg: gp11sp, asm: "ADDVU", aux: "Int64"},                           // arg0 + auxInt. auxInt is 32-bit, also in other *const ops.
-		{name: "SUBV", argLength: 2, reg: gp21, asm: "SUBVU"},                                                // arg0 - arg1
-		{name: "SUBVconst", argLength: 1, reg: gp11, asm: "SUBVU", aux: "Int64"},                             // arg0 - auxInt
-		{name: "MULV", argLength: 2, reg: gp2hilo, asm: "MULV", commutative: true, typ: "(Int64,Int64)"},     // arg0 * arg1, signed, results hi,lo
-		{name: "MULVU", argLength: 2, reg: gp2hilo, asm: "MULVU", commutative: true, typ: "(UInt64,UInt64)"}, // arg0 * arg1, unsigned, results hi,lo
-		{name: "DIVV", argLength: 2, reg: gp2hilo, asm: "DIVV", typ: "(Int64,Int64)"},                        // arg0 / arg1, signed, results hi=arg0%arg1,lo=arg0/arg1
-		{name: "DIVVU", argLength: 2, reg: gp2hilo, asm: "DIVVU", typ: "(UInt64,UInt64)"},                    // arg0 / arg1, signed, results hi=arg0%arg1,lo=arg0/arg1
-
-		{name: "ADDF", argLength: 2, reg: fp21, asm: "ADDF", commutative: true}, // arg0 + arg1
-		{name: "ADDD", argLength: 2, reg: fp21, asm: "ADDD", commutative: true}, // arg0 + arg1
-		{name: "SUBF", argLength: 2, reg: fp21, asm: "SUBF"},                    // arg0 - arg1
-		{name: "SUBD", argLength: 2, reg: fp21, asm: "SUBD"},                    // arg0 - arg1
-		{name: "MULF", argLength: 2, reg: fp21, asm: "MULF", commutative: true}, // arg0 * arg1
-		{name: "MULD", argLength: 2, reg: fp21, asm: "MULD", commutative: true}, // arg0 * arg1
-		{name: "DIVF", argLength: 2, reg: fp21, asm: "DIVF"},                    // arg0 / arg1
-		{name: "DIVD", argLength: 2, reg: fp21, asm: "DIVD"},                    // arg0 / arg1
-
-		{name: "AND", argLength: 2, reg: gp21, asm: "AND", commutative: true},                // arg0 & arg1
-		{name: "ANDconst", argLength: 1, reg: gp11, asm: "AND", aux: "Int64"},                // arg0 & auxInt
-		{name: "OR", argLength: 2, reg: gp21, asm: "OR", commutative: true},                  // arg0 | arg1
-		{name: "ORconst", argLength: 1, reg: gp11, asm: "OR", aux: "Int64"},                  // arg0 | auxInt
-		{name: "XOR", argLength: 2, reg: gp21, asm: "XOR", commutative: true, typ: "UInt64"}, // arg0 ^ arg1
-		{name: "XORconst", argLength: 1, reg: gp11, asm: "XOR", aux: "Int64", typ: "UInt64"}, // arg0 ^ auxInt
-		{name: "NOR", argLength: 2, reg: gp21, asm: "NOR", commutative: true},                // ^(arg0 | arg1)
-		{name: "NORconst", argLength: 1, reg: gp11, asm: "NOR", aux: "Int64"},                // ^(arg0 | auxInt)
-
-		{name: "NEGV", argLength: 1, reg: gp11},                // -arg0
-		{name: "NEGF", argLength: 1, reg: fp11, asm: "NEGF"},   // -arg0, float32
-		{name: "NEGD", argLength: 1, reg: fp11, asm: "NEGD"},   // -arg0, float64
-		{name: "SQRTD", argLength: 1, reg: fp11, asm: "SQRTD"}, // sqrt(arg0), float64
-		{name: "SQRTF", argLength: 1, reg: fp11, asm: "SQRTF"}, // sqrt(arg0), float32
-
-		// shifts
-		{name: "SLLV", argLength: 2, reg: gp21, asm: "SLLV"},                    // arg0 << arg1, shift amount is mod 64
-		{name: "SLLVconst", argLength: 1, reg: gp11, asm: "SLLV", aux: "Int64"}, // arg0 << auxInt
-		{name: "SRLV", argLength: 2, reg: gp21, asm: "SRLV"},                    // arg0 >> arg1, unsigned, shift amount is mod 64
-		{name: "SRLVconst", argLength: 1, reg: gp11, asm: "SRLV", aux: "Int64"}, // arg0 >> auxInt, unsigned
-		{name: "SRAV", argLength: 2, reg: gp21, asm: "SRAV"},                    // arg0 >> arg1, signed, shift amount is mod 64
-		{name: "SRAVconst", argLength: 1, reg: gp11, asm: "SRAV", aux: "Int64"}, // arg0 >> auxInt, signed
-
-		// comparisons
-		{name: "SGT", argLength: 2, reg: gp21, asm: "SGT", typ: "Bool"},                      // 1 if arg0 > arg1 (signed), 0 otherwise
-		{name: "SGTconst", argLength: 1, reg: gp11, asm: "SGT", aux: "Int64", typ: "Bool"},   // 1 if auxInt > arg0 (signed), 0 otherwise
-		{name: "SGTU", argLength: 2, reg: gp21, asm: "SGTU", typ: "Bool"},                    // 1 if arg0 > arg1 (unsigned), 0 otherwise
-		{name: "SGTUconst", argLength: 1, reg: gp11, asm: "SGTU", aux: "Int64", typ: "Bool"}, // 1 if auxInt > arg0 (unsigned), 0 otherwise
-
-		{name: "CMPEQF", argLength: 2, reg: fp2flags, asm: "CMPEQF", typ: "Flags"}, // flags=true if arg0 = arg1, float32
-		{name: "CMPEQD", argLength: 2, reg: fp2flags, asm: "CMPEQD", typ: "Flags"}, // flags=true if arg0 = arg1, float64
-		{name: "CMPGEF", argLength: 2, reg: fp2flags, asm: "CMPGEF", typ: "Flags"}, // flags=true if arg0 >= arg1, float32
-		{name: "CMPGED", argLength: 2, reg: fp2flags, asm: "CMPGED", typ: "Flags"}, // flags=true if arg0 >= arg1, float64
-		{name: "CMPGTF", argLength: 2, reg: fp2flags, asm: "CMPGTF", typ: "Flags"}, // flags=true if arg0 > arg1, float32
-		{name: "CMPGTD", argLength: 2, reg: fp2flags, asm: "CMPGTD", typ: "Flags"}, // flags=true if arg0 > arg1, float64
-
-		// moves
-		{name: "MOVVconst", argLength: 0, reg: gp01, aux: "Int64", asm: "MOVV", typ: "UInt64", rematerializeable: true},    // auxint
-		{name: "MOVFconst", argLength: 0, reg: fp01, aux: "Float64", asm: "MOVF", typ: "Float32", rematerializeable: true}, // auxint as 64-bit float, convert to 32-bit float
-		{name: "MOVDconst", argLength: 0, reg: fp01, aux: "Float64", asm: "MOVD", typ: "Float64", rematerializeable: true}, // auxint as 64-bit float
-
-		{name: "MOVVaddr", argLength: 1, reg: regInfo{inputs: []regMask{buildReg("SP") | buildReg("SB")}, outputs: []regMask{gp}}, aux: "SymOff", asm: "MOVV", rematerializeable: true, symEffect: "Addr"}, // arg0 + auxInt + aux.(*gc.Sym), arg0=SP/SB
-
-		{name: "MOVBload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVB", typ: "Int8", faultOnNilArg0: true, symEffect: "Read"},     // load from arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVBUload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVBU", typ: "UInt8", faultOnNilArg0: true, symEffect: "Read"},  // load from arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVHload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVH", typ: "Int16", faultOnNilArg0: true, symEffect: "Read"},    // load from arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVHUload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVHU", typ: "UInt16", faultOnNilArg0: true, symEffect: "Read"}, // load from arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVWload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVW", typ: "Int32", faultOnNilArg0: true, symEffect: "Read"},    // load from arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVWUload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVWU", typ: "UInt32", faultOnNilArg0: true, symEffect: "Read"}, // load from arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVVload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVV", typ: "UInt64", faultOnNilArg0: true, symEffect: "Read"},   // load from arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVFload", argLength: 2, reg: fpload, aux: "SymOff", asm: "MOVF", typ: "Float32", faultOnNilArg0: true, symEffect: "Read"},  // load from arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVDload", argLength: 2, reg: fpload, aux: "SymOff", asm: "MOVD", typ: "Float64", faultOnNilArg0: true, symEffect: "Read"},  // load from arg0 + auxInt + aux.  arg1=mem.
-
-		{name: "MOVBstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVB", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 1 byte of arg1 to arg0 + auxInt + aux.  arg2=mem.
-		{name: "MOVHstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVH", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 2 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
-		{name: "MOVWstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVW", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
-		{name: "MOVVstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVV", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
-		{name: "MOVFstore", argLength: 3, reg: fpstore, aux: "SymOff", asm: "MOVF", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
-		{name: "MOVDstore", argLength: 3, reg: fpstore, aux: "SymOff", asm: "MOVD", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
-
-		{name: "MOVBstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVB", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 1 byte of zero to arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVHstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVH", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 2 bytes of zero to arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVWstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVW", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes of zero to arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVVstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVV", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes of zero to arg0 + auxInt + aux.  ar12=mem.
-
-		// conversions
-		{name: "MOVBreg", argLength: 1, reg: gp11, asm: "MOVB"},   // move from arg0, sign-extended from byte
-		{name: "MOVBUreg", argLength: 1, reg: gp11, asm: "MOVBU"}, // move from arg0, unsign-extended from byte
-		{name: "MOVHreg", argLength: 1, reg: gp11, asm: "MOVH"},   // move from arg0, sign-extended from half
-		{name: "MOVHUreg", argLength: 1, reg: gp11, asm: "MOVHU"}, // move from arg0, unsign-extended from half
-		{name: "MOVWreg", argLength: 1, reg: gp11, asm: "MOVW"},   // move from arg0, sign-extended from word
-		{name: "MOVWUreg", argLength: 1, reg: gp11, asm: "MOVWU"}, // move from arg0, unsign-extended from word
-		{name: "MOVVreg", argLength: 1, reg: gp11, asm: "MOVV"},   // move from arg0
-
-		{name: "MOVVnop", argLength: 1, reg: regInfo{inputs: []regMask{gp}, outputs: []regMask{gp}}, resultInArg0: true}, // nop, return arg0 in same register
-
-		{name: "MOVWF", argLength: 1, reg: fp11, asm: "MOVWF"},     // int32 -> float32
-		{name: "MOVWD", argLength: 1, reg: fp11, asm: "MOVWD"},     // int32 -> float64
-		{name: "MOVVF", argLength: 1, reg: fp11, asm: "MOVVF"},     // int64 -> float32
-		{name: "MOVVD", argLength: 1, reg: fp11, asm: "MOVVD"},     // int64 -> float64
-		{name: "TRUNCFW", argLength: 1, reg: fp11, asm: "TRUNCFW"}, // float32 -> int32
-		{name: "TRUNCDW", argLength: 1, reg: fp11, asm: "TRUNCDW"}, // float64 -> int32
-		{name: "TRUNCFV", argLength: 1, reg: fp11, asm: "TRUNCFV"}, // float32 -> int64
-		{name: "TRUNCDV", argLength: 1, reg: fp11, asm: "TRUNCDV"}, // float64 -> int64
-		{name: "MOVFD", argLength: 1, reg: fp11, asm: "MOVFD"},     // float32 -> float64
-		{name: "MOVDF", argLength: 1, reg: fp11, asm: "MOVDF"},     // float64 -> float32
-
-		// function calls
-		{name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                                               // call static function aux.(*obj.LSym).  arg0=mem, auxint=argsize, returns mem
-		{name: "CALLtail", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true, tailCall: true},                                 // tail call static function aux.(*obj.LSym).  arg0=mem, auxint=argsize, returns mem
-		{name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{gpsp, buildReg("R22"), 0}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call function via closure.  arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem
-		{name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                         // call fn by pointer.  arg0=codeptr, arg1=mem, auxint=argsize, returns mem
-
-		// duffzero
-		// arg0 = address of memory to zero
-		// arg1 = mem
-		// auxint = offset into duffzero code to start executing
-		// returns mem
-		// R1 aka mips.REGRT1 changed as side effect
-		{
-			name:      "DUFFZERO",
-			aux:       "Int64",
-			argLength: 2,
-			reg: regInfo{
-				inputs:   []regMask{gp},
-				clobbers: buildReg("R1 R31"),
-			},
-			faultOnNilArg0: true,
-		},
-
-		// duffcopy
-		// arg0 = address of dst memory (in R2, changed as side effect)
-		// arg1 = address of src memory (in R1, changed as side effect)
-		// arg2 = mem
-		// auxint = offset into duffcopy code to start executing
-		// returns mem
-		{
-			name:      "DUFFCOPY",
-			aux:       "Int64",
-			argLength: 3,
-			reg: regInfo{
-				inputs:   []regMask{buildReg("R2"), buildReg("R1")},
-				clobbers: buildReg("R1 R2 R31"),
-			},
-			faultOnNilArg0: true,
-			faultOnNilArg1: true,
-		},
-
-		// large or unaligned zeroing
-		// arg0 = address of memory to zero (in R1, changed as side effect)
-		// arg1 = address of the last element to zero
-		// arg2 = mem
-		// auxint = alignment
-		// returns mem
-		//	SUBV	$8, R1
-		//	MOVV	R0, 8(R1)
-		//	ADDV	$8, R1
-		//	BNE	Rarg1, R1, -2(PC)
-		{
-			name:      "LoweredZero",
-			aux:       "Int64",
-			argLength: 3,
-			reg: regInfo{
-				inputs:   []regMask{buildReg("R1"), gp},
-				clobbers: buildReg("R1"),
-			},
-			clobberFlags:   true,
-			faultOnNilArg0: true,
-		},
-
-		// large or unaligned move
-		// arg0 = address of dst memory (in R2, changed as side effect)
-		// arg1 = address of src memory (in R1, changed as side effect)
-		// arg2 = address of the last element of src
-		// arg3 = mem
-		// auxint = alignment
-		// returns mem
-		//	SUBV	$8, R1
-		//	MOVV	8(R1), Rtmp
-		//	MOVV	Rtmp, (R2)
-		//	ADDV	$8, R1
-		//	ADDV	$8, R2
-		//	BNE	Rarg2, R1, -4(PC)
-		{
-			name:      "LoweredMove",
-			aux:       "Int64",
-			argLength: 4,
-			reg: regInfo{
-				inputs:   []regMask{buildReg("R2"), buildReg("R1"), gp},
-				clobbers: buildReg("R1 R2"),
-			},
-			clobberFlags:   true,
-			faultOnNilArg0: true,
-			faultOnNilArg1: true,
-		},
-
-		// atomic loads.
-		// load from arg0. arg1=mem.
-		// returns <value,memory> so they can be properly ordered with other loads.
-		{name: "LoweredAtomicLoad8", argLength: 2, reg: gpload, faultOnNilArg0: true},
-		{name: "LoweredAtomicLoad32", argLength: 2, reg: gpload, faultOnNilArg0: true},
-		{name: "LoweredAtomicLoad64", argLength: 2, reg: gpload, faultOnNilArg0: true},
-
-		// atomic stores.
-		// store arg1 to arg0. arg2=mem. returns memory.
-		{name: "LoweredAtomicStore8", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true},
-		{name: "LoweredAtomicStore32", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true},
-		{name: "LoweredAtomicStore64", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true},
-		// store zero to arg0. arg1=mem. returns memory.
-		{name: "LoweredAtomicStorezero32", argLength: 2, reg: gpstore0, faultOnNilArg0: true, hasSideEffects: true},
-		{name: "LoweredAtomicStorezero64", argLength: 2, reg: gpstore0, faultOnNilArg0: true, hasSideEffects: true},
-
-		// atomic exchange.
-		// store arg1 to arg0. arg2=mem. returns <old content of *arg0, memory>.
-		// SYNC
-		// LL	(Rarg0), Rout
-		// MOVV Rarg1, Rtmp
-		// SC	Rtmp, (Rarg0)
-		// BEQ	Rtmp, -3(PC)
-		// SYNC
-		{name: "LoweredAtomicExchange32", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-		{name: "LoweredAtomicExchange64", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-
-		// atomic add.
-		// *arg0 += arg1. arg2=mem. returns <new content of *arg0, memory>.
-		// SYNC
-		// LL	(Rarg0), Rout
-		// ADDV Rarg1, Rout, Rtmp
-		// SC	Rtmp, (Rarg0)
-		// BEQ	Rtmp, -3(PC)
-		// SYNC
-		// ADDV Rarg1, Rout
-		{name: "LoweredAtomicAdd32", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-		{name: "LoweredAtomicAdd64", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-		// *arg0 += auxint. arg1=mem. returns <new content of *arg0, memory>. auxint is 32-bit.
-		{name: "LoweredAtomicAddconst32", argLength: 2, reg: regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{gp}}, aux: "Int32", resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-		{name: "LoweredAtomicAddconst64", argLength: 2, reg: regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{gp}}, aux: "Int64", resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-
-		// atomic compare and swap.
-		// arg0 = pointer, arg1 = old value, arg2 = new value, arg3 = memory.
-		// if *arg0 == arg1 {
-		//   *arg0 = arg2
-		//   return (true, memory)
-		// } else {
-		//   return (false, memory)
-		// }
-		// SYNC
-		// MOVV $0, Rout
-		// LL	(Rarg0), Rtmp
-		// BNE	Rtmp, Rarg1, 4(PC)
-		// MOVV Rarg2, Rout
-		// SC	Rout, (Rarg0)
-		// BEQ	Rout, -4(PC)
-		// SYNC
-		{name: "LoweredAtomicCas32", argLength: 4, reg: gpcas, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-		{name: "LoweredAtomicCas64", argLength: 4, reg: gpcas, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-
-		// pseudo-ops
-		{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpg}}, nilCheck: true, faultOnNilArg0: true}, // panic if arg0 is nil.  arg1=mem.
-
-		{name: "FPFlagTrue", argLength: 1, reg: readflags},  // bool, true if FP flag is true
-		{name: "FPFlagFalse", argLength: 1, reg: readflags}, // bool, true if FP flag is false
-
-		// Scheduler ensures LoweredGetClosurePtr occurs only in entry block,
-		// and sorts it to the very beginning of the block to prevent other
-		// use of R22 (mips.REGCTXT, the closure pointer)
-		{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R22")}}, zeroWidth: true},
-
-		// LoweredGetCallerSP returns the SP of the caller of the current function.
-		{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
-
-		// LoweredGetCallerPC evaluates to the PC to which its "caller" will return.
-		// I.e., if f calls g "calls" getcallerpc,
-		// the result should be the PC within f that g will return to.
-		// See runtime/stubs.go for a more detailed discussion.
-		{name: "LoweredGetCallerPC", reg: gp01, rematerializeable: true},
-
-		// LoweredWB invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
-		// It saves all GP registers if necessary,
-		// but clobbers R31 (LR) because it's a call
-		// and R23 (REGTMP).
-		{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R20"), buildReg("R21")}, clobbers: (callerSave &^ gpg) | buildReg("R31")}, clobberFlags: true, aux: "Sym", symEffect: "None"},
-
-		// There are three of these functions so that they can have three different register inputs.
-		// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the
-		// default registers to match so we don't need to copy registers around unnecessarily.
-		{name: "LoweredPanicBoundsA", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r3, r4}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
-		{name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r2, r3}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
-		{name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r1, r2}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
-	}
-
-	blocks := []blockData{
-		{name: "EQ", controls: 1},
-		{name: "NE", controls: 1},
-		{name: "LTZ", controls: 1}, // < 0
-		{name: "LEZ", controls: 1}, // <= 0
-		{name: "GTZ", controls: 1}, // > 0
-		{name: "GEZ", controls: 1}, // >= 0
-		{name: "FPT", controls: 1}, // FP flag is true
-		{name: "FPF", controls: 1}, // FP flag is false
-	}
-
-	archs = append(archs, arch{
-		name:            "MIPS64",
-		pkg:             "cmd/internal/obj/mips",
-		genfile:         "../../mips64/ssa.go",
-		ops:             ops,
-		blocks:          blocks,
-		regnames:        regNamesMIPS64,
-		gpregmask:       gp,
-		fpregmask:       fp,
-		specialregmask:  hi | lo,
-		framepointerreg: -1, // not used
-		linkreg:         int8(num["R31"]),
-	})
-}
diff --git a/src/cmd/compile/internal/ssa/gen/MIPSOps.go b/src/cmd/compile/internal/ssa/gen/MIPSOps.go
deleted file mode 100644
index 523847b..0000000
--- a/src/cmd/compile/internal/ssa/gen/MIPSOps.go
+++ /dev/null
@@ -1,442 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build ignore
-// +build ignore
-
-package main
-
-import "strings"
-
-// Notes:
-//  - Integer types live in the low portion of registers. Upper portions are junk.
-//  - Boolean types use the low-order byte of a register. 0=false, 1=true.
-//    Upper bytes are junk.
-//  - Unused portions of AuxInt are filled by sign-extending the used portion.
-//  - *const instructions may use a constant larger than the instruction can encode.
-//    In this case the assembler expands to multiple instructions and uses tmp
-//    register (R23).
-
-// Suffixes encode the bit width of various instructions.
-// W (word)      = 32 bit
-// H (half word) = 16 bit
-// HU            = 16 bit unsigned
-// B (byte)      = 8 bit
-// BU            = 8 bit unsigned
-// F (float)     = 32 bit float
-// D (double)    = 64 bit float
-
-// Note: registers not used in regalloc are not included in this list,
-// so that regmask stays within int64
-// Be careful when hand coding regmasks.
-var regNamesMIPS = []string{
-	"R0", // constant 0
-	"R1",
-	"R2",
-	"R3",
-	"R4",
-	"R5",
-	"R6",
-	"R7",
-	"R8",
-	"R9",
-	"R10",
-	"R11",
-	"R12",
-	"R13",
-	"R14",
-	"R15",
-	"R16",
-	"R17",
-	"R18",
-	"R19",
-	"R20",
-	"R21",
-	"R22",
-	//REGTMP
-	"R24",
-	"R25",
-	// R26 reserved by kernel
-	// R27 reserved by kernel
-	"R28",
-	"SP",  // aka R29
-	"g",   // aka R30
-	"R31", // REGLINK
-
-	// odd FP registers contain high parts of 64-bit FP values
-	"F0",
-	"F2",
-	"F4",
-	"F6",
-	"F8",
-	"F10",
-	"F12",
-	"F14",
-	"F16",
-	"F18",
-	"F20",
-	"F22",
-	"F24",
-	"F26",
-	"F28",
-	"F30",
-
-	"HI", // high bits of multiplication
-	"LO", // low bits of multiplication
-
-	// If you add registers, update asyncPreempt in runtime.
-
-	// pseudo-registers
-	"SB",
-}
-
-func init() {
-	// Make map from reg names to reg integers.
-	if len(regNamesMIPS) > 64 {
-		panic("too many registers")
-	}
-	num := map[string]int{}
-	for i, name := range regNamesMIPS {
-		num[name] = i
-	}
-	buildReg := func(s string) regMask {
-		m := regMask(0)
-		for _, r := range strings.Split(s, " ") {
-			if n, ok := num[r]; ok {
-				m |= regMask(1) << uint(n)
-				continue
-			}
-			panic("register " + r + " not found")
-		}
-		return m
-	}
-
-	// Common individual register masks
-	var (
-		gp         = buildReg("R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R24 R25 R28 R31")
-		gpg        = gp | buildReg("g")
-		gpsp       = gp | buildReg("SP")
-		gpspg      = gpg | buildReg("SP")
-		gpspsbg    = gpspg | buildReg("SB")
-		fp         = buildReg("F0 F2 F4 F6 F8 F10 F12 F14 F16 F18 F20 F22 F24 F26 F28 F30")
-		lo         = buildReg("LO")
-		hi         = buildReg("HI")
-		callerSave = gp | fp | lo | hi | buildReg("g") // runtime.setg (and anything calling it) may clobber g
-		r1         = buildReg("R1")
-		r2         = buildReg("R2")
-		r3         = buildReg("R3")
-		r4         = buildReg("R4")
-		r5         = buildReg("R5")
-	)
-	// Common regInfo
-	var (
-		gp01      = regInfo{inputs: nil, outputs: []regMask{gp}}
-		gp11      = regInfo{inputs: []regMask{gpg}, outputs: []regMask{gp}}
-		gp11sp    = regInfo{inputs: []regMask{gpspg}, outputs: []regMask{gp}}
-		gp21      = regInfo{inputs: []regMask{gpg, gpg}, outputs: []regMask{gp}}
-		gp31      = regInfo{inputs: []regMask{gp, gp, gp}, outputs: []regMask{gp}}
-		gp2hilo   = regInfo{inputs: []regMask{gpg, gpg}, outputs: []regMask{hi, lo}}
-		gpload    = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{gp}}
-		gpstore   = regInfo{inputs: []regMask{gpspsbg, gpg}}
-		gpxchg    = regInfo{inputs: []regMask{gpspsbg, gpg}, outputs: []regMask{gp}}
-		gpcas     = regInfo{inputs: []regMask{gpspsbg, gpg, gpg}, outputs: []regMask{gp}}
-		gpstore0  = regInfo{inputs: []regMask{gpspsbg}}
-		fp01      = regInfo{inputs: nil, outputs: []regMask{fp}}
-		fp11      = regInfo{inputs: []regMask{fp}, outputs: []regMask{fp}}
-		fp21      = regInfo{inputs: []regMask{fp, fp}, outputs: []regMask{fp}}
-		fp2flags  = regInfo{inputs: []regMask{fp, fp}}
-		fpload    = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{fp}}
-		fpstore   = regInfo{inputs: []regMask{gpspsbg, fp}}
-		readflags = regInfo{inputs: nil, outputs: []regMask{gp}}
-	)
-	ops := []opData{
-		{name: "ADD", argLength: 2, reg: gp21, asm: "ADDU", commutative: true},                                                                           // arg0 + arg1
-		{name: "ADDconst", argLength: 1, reg: gp11sp, asm: "ADDU", aux: "Int32"},                                                                         // arg0 + auxInt
-		{name: "SUB", argLength: 2, reg: gp21, asm: "SUBU"},                                                                                              // arg0 - arg1
-		{name: "SUBconst", argLength: 1, reg: gp11, asm: "SUBU", aux: "Int32"},                                                                           // arg0 - auxInt
-		{name: "MUL", argLength: 2, reg: regInfo{inputs: []regMask{gpg, gpg}, outputs: []regMask{gp}, clobbers: hi | lo}, asm: "MUL", commutative: true}, // arg0 * arg1
-		{name: "MULT", argLength: 2, reg: gp2hilo, asm: "MUL", commutative: true, typ: "(Int32,Int32)"},                                                  // arg0 * arg1, signed, results hi,lo
-		{name: "MULTU", argLength: 2, reg: gp2hilo, asm: "MULU", commutative: true, typ: "(UInt32,UInt32)"},                                              // arg0 * arg1, unsigned, results hi,lo
-		{name: "DIV", argLength: 2, reg: gp2hilo, asm: "DIV", typ: "(Int32,Int32)"},                                                                      // arg0 / arg1, signed, results hi=arg0%arg1,lo=arg0/arg1
-		{name: "DIVU", argLength: 2, reg: gp2hilo, asm: "DIVU", typ: "(UInt32,UInt32)"},                                                                  // arg0 / arg1, signed, results hi=arg0%arg1,lo=arg0/arg1
-
-		{name: "ADDF", argLength: 2, reg: fp21, asm: "ADDF", commutative: true}, // arg0 + arg1
-		{name: "ADDD", argLength: 2, reg: fp21, asm: "ADDD", commutative: true}, // arg0 + arg1
-		{name: "SUBF", argLength: 2, reg: fp21, asm: "SUBF"},                    // arg0 - arg1
-		{name: "SUBD", argLength: 2, reg: fp21, asm: "SUBD"},                    // arg0 - arg1
-		{name: "MULF", argLength: 2, reg: fp21, asm: "MULF", commutative: true}, // arg0 * arg1
-		{name: "MULD", argLength: 2, reg: fp21, asm: "MULD", commutative: true}, // arg0 * arg1
-		{name: "DIVF", argLength: 2, reg: fp21, asm: "DIVF"},                    // arg0 / arg1
-		{name: "DIVD", argLength: 2, reg: fp21, asm: "DIVD"},                    // arg0 / arg1
-
-		{name: "AND", argLength: 2, reg: gp21, asm: "AND", commutative: true},                // arg0 & arg1
-		{name: "ANDconst", argLength: 1, reg: gp11, asm: "AND", aux: "Int32"},                // arg0 & auxInt
-		{name: "OR", argLength: 2, reg: gp21, asm: "OR", commutative: true},                  // arg0 | arg1
-		{name: "ORconst", argLength: 1, reg: gp11, asm: "OR", aux: "Int32"},                  // arg0 | auxInt
-		{name: "XOR", argLength: 2, reg: gp21, asm: "XOR", commutative: true, typ: "UInt32"}, // arg0 ^ arg1
-		{name: "XORconst", argLength: 1, reg: gp11, asm: "XOR", aux: "Int32", typ: "UInt32"}, // arg0 ^ auxInt
-		{name: "NOR", argLength: 2, reg: gp21, asm: "NOR", commutative: true},                // ^(arg0 | arg1)
-		{name: "NORconst", argLength: 1, reg: gp11, asm: "NOR", aux: "Int32"},                // ^(arg0 | auxInt)
-
-		{name: "NEG", argLength: 1, reg: gp11},                 // -arg0
-		{name: "NEGF", argLength: 1, reg: fp11, asm: "NEGF"},   // -arg0, float32
-		{name: "NEGD", argLength: 1, reg: fp11, asm: "NEGD"},   // -arg0, float64
-		{name: "SQRTD", argLength: 1, reg: fp11, asm: "SQRTD"}, // sqrt(arg0), float64
-		{name: "SQRTF", argLength: 1, reg: fp11, asm: "SQRTF"}, // sqrt(arg0), float32
-
-		// shifts
-		{name: "SLL", argLength: 2, reg: gp21, asm: "SLL"},                    // arg0 << arg1, shift amount is mod 32
-		{name: "SLLconst", argLength: 1, reg: gp11, asm: "SLL", aux: "Int32"}, // arg0 << auxInt, shift amount must be 0 through 31 inclusive
-		{name: "SRL", argLength: 2, reg: gp21, asm: "SRL"},                    // arg0 >> arg1, unsigned, shift amount is mod 32
-		{name: "SRLconst", argLength: 1, reg: gp11, asm: "SRL", aux: "Int32"}, // arg0 >> auxInt, shift amount must be 0 through 31 inclusive
-		{name: "SRA", argLength: 2, reg: gp21, asm: "SRA"},                    // arg0 >> arg1, signed, shift amount is mod 32
-		{name: "SRAconst", argLength: 1, reg: gp11, asm: "SRA", aux: "Int32"}, // arg0 >> auxInt, signed, shift amount must be 0 through 31 inclusive
-
-		{name: "CLZ", argLength: 1, reg: gp11, asm: "CLZ"},
-
-		// comparisons
-		{name: "SGT", argLength: 2, reg: gp21, asm: "SGT", typ: "Bool"},                      // 1 if arg0 > arg1 (signed), 0 otherwise
-		{name: "SGTconst", argLength: 1, reg: gp11, asm: "SGT", aux: "Int32", typ: "Bool"},   // 1 if auxInt > arg0 (signed), 0 otherwise
-		{name: "SGTzero", argLength: 1, reg: gp11, asm: "SGT", typ: "Bool"},                  // 1 if arg0 > 0 (signed), 0 otherwise
-		{name: "SGTU", argLength: 2, reg: gp21, asm: "SGTU", typ: "Bool"},                    // 1 if arg0 > arg1 (unsigned), 0 otherwise
-		{name: "SGTUconst", argLength: 1, reg: gp11, asm: "SGTU", aux: "Int32", typ: "Bool"}, // 1 if auxInt > arg0 (unsigned), 0 otherwise
-		{name: "SGTUzero", argLength: 1, reg: gp11, asm: "SGTU", typ: "Bool"},                // 1 if arg0 > 0 (unsigned), 0 otherwise
-
-		{name: "CMPEQF", argLength: 2, reg: fp2flags, asm: "CMPEQF", typ: "Flags"}, // flags=true if arg0 = arg1, float32
-		{name: "CMPEQD", argLength: 2, reg: fp2flags, asm: "CMPEQD", typ: "Flags"}, // flags=true if arg0 = arg1, float64
-		{name: "CMPGEF", argLength: 2, reg: fp2flags, asm: "CMPGEF", typ: "Flags"}, // flags=true if arg0 >= arg1, float32
-		{name: "CMPGED", argLength: 2, reg: fp2flags, asm: "CMPGED", typ: "Flags"}, // flags=true if arg0 >= arg1, float64
-		{name: "CMPGTF", argLength: 2, reg: fp2flags, asm: "CMPGTF", typ: "Flags"}, // flags=true if arg0 > arg1, float32
-		{name: "CMPGTD", argLength: 2, reg: fp2flags, asm: "CMPGTD", typ: "Flags"}, // flags=true if arg0 > arg1, float64
-
-		// moves
-		{name: "MOVWconst", argLength: 0, reg: gp01, aux: "Int32", asm: "MOVW", typ: "UInt32", rematerializeable: true},    // auxint
-		{name: "MOVFconst", argLength: 0, reg: fp01, aux: "Float32", asm: "MOVF", typ: "Float32", rematerializeable: true}, // auxint as 64-bit float, convert to 32-bit float
-		{name: "MOVDconst", argLength: 0, reg: fp01, aux: "Float64", asm: "MOVD", typ: "Float64", rematerializeable: true}, // auxint as 64-bit float
-
-		{name: "MOVWaddr", argLength: 1, reg: regInfo{inputs: []regMask{buildReg("SP") | buildReg("SB")}, outputs: []regMask{gp}}, aux: "SymOff", asm: "MOVW", rematerializeable: true, symEffect: "Addr"}, // arg0 + auxInt + aux.(*gc.Sym), arg0=SP/SB
-
-		{name: "MOVBload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVB", typ: "Int8", faultOnNilArg0: true, symEffect: "Read"},     // load from arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVBUload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVBU", typ: "UInt8", faultOnNilArg0: true, symEffect: "Read"},  // load from arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVHload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVH", typ: "Int16", faultOnNilArg0: true, symEffect: "Read"},    // load from arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVHUload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVHU", typ: "UInt16", faultOnNilArg0: true, symEffect: "Read"}, // load from arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVWload", argLength: 2, reg: gpload, aux: "SymOff", asm: "MOVW", typ: "UInt32", faultOnNilArg0: true, symEffect: "Read"},   // load from arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVFload", argLength: 2, reg: fpload, aux: "SymOff", asm: "MOVF", typ: "Float32", faultOnNilArg0: true, symEffect: "Read"},  // load from arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVDload", argLength: 2, reg: fpload, aux: "SymOff", asm: "MOVD", typ: "Float64", faultOnNilArg0: true, symEffect: "Read"},  // load from arg0 + auxInt + aux.  arg1=mem.
-
-		{name: "MOVBstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVB", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 1 byte of arg1 to arg0 + auxInt + aux.  arg2=mem.
-		{name: "MOVHstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVH", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 2 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
-		{name: "MOVWstore", argLength: 3, reg: gpstore, aux: "SymOff", asm: "MOVW", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
-		{name: "MOVFstore", argLength: 3, reg: fpstore, aux: "SymOff", asm: "MOVF", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
-		{name: "MOVDstore", argLength: 3, reg: fpstore, aux: "SymOff", asm: "MOVD", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes of arg1 to arg0 + auxInt + aux.  arg2=mem.
-
-		{name: "MOVBstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVB", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 1 byte of zero to arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVHstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVH", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 2 bytes of zero to arg0 + auxInt + aux.  arg1=mem.
-		{name: "MOVWstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVW", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes of zero to arg0 + auxInt + aux.  arg1=mem.
-
-		// conversions
-		{name: "MOVBreg", argLength: 1, reg: gp11, asm: "MOVB"},   // move from arg0, sign-extended from byte
-		{name: "MOVBUreg", argLength: 1, reg: gp11, asm: "MOVBU"}, // move from arg0, unsign-extended from byte
-		{name: "MOVHreg", argLength: 1, reg: gp11, asm: "MOVH"},   // move from arg0, sign-extended from half
-		{name: "MOVHUreg", argLength: 1, reg: gp11, asm: "MOVHU"}, // move from arg0, unsign-extended from half
-		{name: "MOVWreg", argLength: 1, reg: gp11, asm: "MOVW"},   // move from arg0
-
-		{name: "MOVWnop", argLength: 1, reg: regInfo{inputs: []regMask{gp}, outputs: []regMask{gp}}, resultInArg0: true}, // nop, return arg0 in same register
-
-		// conditional move on zero (returns arg1 if arg2 is 0, otherwise arg0)
-		// order of parameters is reversed so we can use resultInArg0 (OpCMOVZ result arg1 arg2-> CMOVZ arg2reg, arg1reg, resultReg)
-		{name: "CMOVZ", argLength: 3, reg: gp31, asm: "CMOVZ", resultInArg0: true},
-		{name: "CMOVZzero", argLength: 2, reg: regInfo{inputs: []regMask{gp, gpg}, outputs: []regMask{gp}}, asm: "CMOVZ", resultInArg0: true},
-
-		{name: "MOVWF", argLength: 1, reg: fp11, asm: "MOVWF"},     // int32 -> float32
-		{name: "MOVWD", argLength: 1, reg: fp11, asm: "MOVWD"},     // int32 -> float64
-		{name: "TRUNCFW", argLength: 1, reg: fp11, asm: "TRUNCFW"}, // float32 -> int32
-		{name: "TRUNCDW", argLength: 1, reg: fp11, asm: "TRUNCDW"}, // float64 -> int32
-		{name: "MOVFD", argLength: 1, reg: fp11, asm: "MOVFD"},     // float32 -> float64
-		{name: "MOVDF", argLength: 1, reg: fp11, asm: "MOVDF"},     // float64 -> float32
-
-		// function calls
-		{name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                                               // call static function aux.(*obj.LSym).  arg0=mem, auxint=argsize, returns mem
-		{name: "CALLtail", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true, tailCall: true},                                 //  tail call static function aux.(*obj.LSym).  arg0=mem, auxint=argsize, returns mem
-		{name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{gpsp, buildReg("R22"), 0}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call function via closure.  arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem
-		{name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                         // call fn by pointer.  arg0=codeptr, arg1=mem, auxint=argsize, returns mem
-
-		// atomic ops
-
-		// load from arg0. arg1=mem.
-		// returns <value,memory> so they can be properly ordered with other loads.
-		// SYNC
-		// MOV(B|W)	(Rarg0), Rout
-		// SYNC
-		{name: "LoweredAtomicLoad8", argLength: 2, reg: gpload, faultOnNilArg0: true},
-		{name: "LoweredAtomicLoad32", argLength: 2, reg: gpload, faultOnNilArg0: true},
-
-		// store arg1 to arg0. arg2=mem. returns memory.
-		// SYNC
-		// MOV(B|W)	Rarg1, (Rarg0)
-		// SYNC
-		{name: "LoweredAtomicStore8", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true},
-		{name: "LoweredAtomicStore32", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true},
-		{name: "LoweredAtomicStorezero", argLength: 2, reg: gpstore0, faultOnNilArg0: true, hasSideEffects: true},
-
-		// atomic exchange.
-		// store arg1 to arg0. arg2=mem. returns <old content of *arg0, memory>.
-		// SYNC
-		// LL	(Rarg0), Rout
-		// MOVW Rarg1, Rtmp
-		// SC	Rtmp, (Rarg0)
-		// BEQ	Rtmp, -3(PC)
-		// SYNC
-		{name: "LoweredAtomicExchange", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-
-		// atomic add.
-		// *arg0 += arg1. arg2=mem. returns <new content of *arg0, memory>.
-		// SYNC
-		// LL	(Rarg0), Rout
-		// ADDU Rarg1, Rout, Rtmp
-		// SC	Rtmp, (Rarg0)
-		// BEQ	Rtmp, -3(PC)
-		// SYNC
-		// ADDU Rarg1, Rout
-		{name: "LoweredAtomicAdd", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-		{name: "LoweredAtomicAddconst", argLength: 2, reg: regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{gp}}, aux: "Int32", resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-
-		// atomic compare and swap.
-		// arg0 = pointer, arg1 = old value, arg2 = new value, arg3 = memory.
-		// if *arg0 == arg1 {
-		//   *arg0 = arg2
-		//   return (true, memory)
-		// } else {
-		//   return (false, memory)
-		// }
-		// SYNC
-		// MOVW $0, Rout
-		// LL	(Rarg0), Rtmp
-		// BNE	Rtmp, Rarg1, 4(PC)
-		// MOVW Rarg2, Rout
-		// SC	Rout, (Rarg0)
-		// BEQ	Rout, -4(PC)
-		// SYNC
-		{name: "LoweredAtomicCas", argLength: 4, reg: gpcas, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-
-		// atomic and/or.
-		// *arg0 &= (|=) arg1. arg2=mem. returns memory.
-		// SYNC
-		// LL	(Rarg0), Rtmp
-		// AND	Rarg1, Rtmp
-		// SC	Rtmp, (Rarg0)
-		// BEQ	Rtmp, -3(PC)
-		// SYNC
-		{name: "LoweredAtomicAnd", argLength: 3, reg: gpstore, asm: "AND", faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-		{name: "LoweredAtomicOr", argLength: 3, reg: gpstore, asm: "OR", faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-
-		// large or unaligned zeroing
-		// arg0 = address of memory to zero (in R1, changed as side effect)
-		// arg1 = address of the last element to zero
-		// arg2 = mem
-		// auxint = alignment
-		// returns mem
-		//	SUBU	$4, R1
-		//	MOVW	R0, 4(R1)
-		//	ADDU	$4, R1
-		//	BNE	Rarg1, R1, -2(PC)
-		{
-			name:      "LoweredZero",
-			aux:       "Int32",
-			argLength: 3,
-			reg: regInfo{
-				inputs:   []regMask{buildReg("R1"), gp},
-				clobbers: buildReg("R1"),
-			},
-			faultOnNilArg0: true,
-		},
-
-		// large or unaligned move
-		// arg0 = address of dst memory (in R2, changed as side effect)
-		// arg1 = address of src memory (in R1, changed as side effect)
-		// arg2 = address of the last element of src
-		// arg3 = mem
-		// auxint = alignment
-		// returns mem
-		//	SUBU	$4, R1
-		//	MOVW	4(R1), Rtmp
-		//	MOVW	Rtmp, (R2)
-		//	ADDU	$4, R1
-		//	ADDU	$4, R2
-		//	BNE	Rarg2, R1, -4(PC)
-		{
-			name:      "LoweredMove",
-			aux:       "Int32",
-			argLength: 4,
-			reg: regInfo{
-				inputs:   []regMask{buildReg("R2"), buildReg("R1"), gp},
-				clobbers: buildReg("R1 R2"),
-			},
-			faultOnNilArg0: true,
-			faultOnNilArg1: true,
-		},
-
-		// pseudo-ops
-		{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpg}}, nilCheck: true, faultOnNilArg0: true}, // panic if arg0 is nil.  arg1=mem.
-
-		{name: "FPFlagTrue", argLength: 1, reg: readflags},  // bool, true if FP flag is true
-		{name: "FPFlagFalse", argLength: 1, reg: readflags}, // bool, true if FP flag is false
-
-		// Scheduler ensures LoweredGetClosurePtr occurs only in entry block,
-		// and sorts it to the very beginning of the block to prevent other
-		// use of R22 (mips.REGCTXT, the closure pointer)
-		{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R22")}}, zeroWidth: true},
-
-		// LoweredGetCallerSP returns the SP of the caller of the current function.
-		{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
-
-		// LoweredGetCallerPC evaluates to the PC to which its "caller" will return.
-		// I.e., if f calls g "calls" getcallerpc,
-		// the result should be the PC within f that g will return to.
-		// See runtime/stubs.go for a more detailed discussion.
-		{name: "LoweredGetCallerPC", reg: gp01, rematerializeable: true},
-
-		// LoweredWB invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
-		// It saves all GP registers if necessary,
-		// but clobbers R31 (LR) because it's a call
-		// and R23 (REGTMP).
-		{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R20"), buildReg("R21")}, clobbers: (callerSave &^ gpg) | buildReg("R31")}, clobberFlags: true, aux: "Sym", symEffect: "None"},
-
-		// There are three of these functions so that they can have three different register inputs.
-		// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the
-		// default registers to match so we don't need to copy registers around unnecessarily.
-		{name: "LoweredPanicBoundsA", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r3, r4}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
-		{name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r2, r3}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
-		{name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r1, r2}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
-		// Extend ops are the same as Bounds ops except the indexes are 64-bit.
-		{name: "LoweredPanicExtendA", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{r5, r3, r4}}, typ: "Mem", call: true}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
-		{name: "LoweredPanicExtendB", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{r5, r2, r3}}, typ: "Mem", call: true}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
-		{name: "LoweredPanicExtendC", argLength: 4, aux: "Int64", reg: regInfo{inputs: []regMask{r5, r1, r2}}, typ: "Mem", call: true}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory. AuxInt contains report code (see PanicExtend in genericOps.go).
-	}
-
-	blocks := []blockData{
-		{name: "EQ", controls: 1},
-		{name: "NE", controls: 1},
-		{name: "LTZ", controls: 1}, // < 0
-		{name: "LEZ", controls: 1}, // <= 0
-		{name: "GTZ", controls: 1}, // > 0
-		{name: "GEZ", controls: 1}, // >= 0
-		{name: "FPT", controls: 1}, // FP flag is true
-		{name: "FPF", controls: 1}, // FP flag is false
-	}
-
-	archs = append(archs, arch{
-		name:            "MIPS",
-		pkg:             "cmd/internal/obj/mips",
-		genfile:         "../../mips/ssa.go",
-		ops:             ops,
-		blocks:          blocks,
-		regnames:        regNamesMIPS,
-		gpregmask:       gp,
-		fpregmask:       fp,
-		specialregmask:  hi | lo,
-		framepointerreg: -1, // not used
-		linkreg:         int8(num["R31"]),
-	})
-}
diff --git a/src/cmd/compile/internal/ssa/gen/PPC64.rules b/src/cmd/compile/internal/ssa/gen/PPC64.rules
deleted file mode 100644
index 834bf4a..0000000
--- a/src/cmd/compile/internal/ssa/gen/PPC64.rules
+++ /dev/null
@@ -1,1508 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Lowering arithmetic
-(Add(Ptr|64|32|16|8) ...) => (ADD ...)
-(Add64F ...) => (FADD ...)
-(Add32F ...) => (FADDS ...)
-
-(Sub(Ptr|64|32|16|8) ...) => (SUB ...)
-(Sub32F ...) => (FSUBS ...)
-(Sub64F ...) => (FSUB ...)
-
-// Combine 64 bit integer multiply and adds
-(ADD l:(MULLD x y) z) && buildcfg.GOPPC64 >= 9 && l.Uses == 1 && clobber(l) => (MADDLD x y z)
-
-(Mod16 x y) => (Mod32 (SignExt16to32 x) (SignExt16to32 y))
-(Mod16u x y) => (Mod32u (ZeroExt16to32 x) (ZeroExt16to32 y))
-(Mod8 x y) => (Mod32 (SignExt8to32 x) (SignExt8to32 y))
-(Mod8u x y) => (Mod32u (ZeroExt8to32 x) (ZeroExt8to32 y))
-(Mod64 x y) && buildcfg.GOPPC64 >=9 => (MODSD x y)
-(Mod64 x y) && buildcfg.GOPPC64 <=8 => (SUB x (MULLD y (DIVD x y)))
-(Mod64u x y) && buildcfg.GOPPC64 >= 9 => (MODUD x y)
-(Mod64u x y) && buildcfg.GOPPC64 <= 8 => (SUB x (MULLD y (DIVDU x y)))
-(Mod32 x y) && buildcfg.GOPPC64 >= 9 => (MODSW x y)
-(Mod32 x y) && buildcfg.GOPPC64 <= 8 => (SUB x (MULLW y (DIVW x y)))
-(Mod32u x y) && buildcfg.GOPPC64 >= 9 => (MODUW x y)
-(Mod32u x y) && buildcfg.GOPPC64 <= 8 => (SUB x (MULLW y (DIVWU x y)))
-
-// (x + y) / 2 with x>=y => (x - y) / 2 + y
-(Avg64u <t> x y) => (ADD (SRDconst <t> (SUB <t> x y) [1]) y)
-
-(Mul64 ...) => (MULLD ...)
-(Mul(32|16|8) ...) => (MULLW ...)
-(Mul64uhilo ...) => (LoweredMuluhilo ...)
-
-(Div64 [false] x y) => (DIVD x y)
-(Div64u ...) => (DIVDU ...)
-(Div32 [false] x y) => (DIVW x y)
-(Div32u ...) => (DIVWU ...)
-(Div16 [false]  x y) => (DIVW  (SignExt16to32 x) (SignExt16to32 y))
-(Div16u x y) => (DIVWU (ZeroExt16to32 x) (ZeroExt16to32 y))
-(Div8 x y) => (DIVW  (SignExt8to32 x) (SignExt8to32 y))
-(Div8u x y) => (DIVWU (ZeroExt8to32 x) (ZeroExt8to32 y))
-
-(Hmul(64|64u|32|32u) ...) => (MULH(D|DU|W|WU) ...)
-
-(Mul32F ...) => (FMULS ...)
-(Mul64F ...) => (FMUL ...)
-
-(Div32F ...) => (FDIVS ...)
-(Div64F ...) => (FDIV ...)
-
-// Lowering float <=> int
-(Cvt32to32F x) => (FCFIDS (MTVSRD (SignExt32to64 x)))
-(Cvt32to64F x) => (FCFID (MTVSRD (SignExt32to64 x)))
-(Cvt64to32F x) => (FCFIDS (MTVSRD x))
-(Cvt64to64F x) => (FCFID (MTVSRD x))
-
-(Cvt32Fto32 x) => (MFVSRD (FCTIWZ x))
-(Cvt32Fto64 x) => (MFVSRD (FCTIDZ x))
-(Cvt64Fto32 x) => (MFVSRD (FCTIWZ x))
-(Cvt64Fto64 x) => (MFVSRD (FCTIDZ x))
-
-(Cvt32Fto64F ...) => (Copy ...) // Note v will have the wrong type for patterns dependent on Float32/Float64
-(Cvt64Fto32F ...) => (FRSP ...)
-
-(CvtBoolToUint8 ...) => (Copy ...)
-
-(Round(32|64)F ...) => (LoweredRound(32|64)F ...)
-
-(Sqrt ...) => (FSQRT ...)
-(Sqrt32 ...) => (FSQRTS ...)
-(Floor ...) => (FFLOOR ...)
-(Ceil ...) => (FCEIL ...)
-(Trunc ...) => (FTRUNC ...)
-(Round ...) => (FROUND ...)
-(Copysign x y) => (FCPSGN y x)
-(Abs ...) => (FABS ...)
-(FMA ...) => (FMADD ...)
-
-// Lowering extension
-// Note: we always extend to 64 bits even though some ops don't need that many result bits.
-(SignExt8to(16|32|64) ...) => (MOVBreg ...)
-(SignExt16to(32|64) ...) => (MOVHreg ...)
-(SignExt32to64 ...) => (MOVWreg ...)
-
-(ZeroExt8to(16|32|64) ...) => (MOVBZreg ...)
-(ZeroExt16to(32|64) ...) => (MOVHZreg ...)
-(ZeroExt32to64 ...) => (MOVWZreg ...)
-
-(Trunc(16|32|64)to8 <t> x) && isSigned(t) => (MOVBreg x)
-(Trunc(16|32|64)to8  x) => (MOVBZreg x)
-(Trunc(32|64)to16 <t> x) && isSigned(t) => (MOVHreg x)
-(Trunc(32|64)to16 x) => (MOVHZreg x)
-(Trunc64to32 <t> x) && isSigned(t) => (MOVWreg x)
-(Trunc64to32 x) => (MOVWZreg x)
-
-// Lowering constants
-(Const(64|32|16|8) [val]) => (MOVDconst [int64(val)])
-(Const(32|64)F ...) => (FMOV(S|D)const ...)
-(ConstNil) => (MOVDconst [0])
-(ConstBool [t]) => (MOVDconst [b2i(t)])
-
-// Carrying addition.
-(Select0 (Add64carry x y c)) =>            (Select0 <typ.UInt64> (ADDE x y (Select1 <typ.UInt64> (ADDCconst c [-1]))))
-(Select1 (Add64carry x y c)) => (ADDZEzero (Select1 <typ.UInt64> (ADDE x y (Select1 <typ.UInt64> (ADDCconst c [-1])))))
-// Fold initial carry bit if 0.
-(ADDE x y (Select1 <typ.UInt64> (ADDCconst (MOVDconst [0]) [-1]))) => (ADDC x y)
-// Fold transfer of CA -> GPR -> CA. Note 2 uses when feeding into a chained Add64carry.
-(Select1 (ADDCconst n:(ADDZEzero x) [-1])) && n.Uses <= 2 => x
-
-// Borrowing subtraction.
-(Select0 (Sub64borrow x y c)) =>                 (Select0 <typ.UInt64> (SUBE x y (Select1 <typ.UInt64> (SUBCconst c [0]))))
-(Select1 (Sub64borrow x y c)) => (NEG (SUBZEzero (Select1 <typ.UInt64> (SUBE x y (Select1 <typ.UInt64> (SUBCconst c [0]))))))
-// Fold initial borrow bit if 0.
-(SUBE x y (Select1 <typ.UInt64> (SUBCconst (MOVDconst [0]) [0]))) => (SUBC x y)
-// Fold transfer of CA -> GPR -> CA. Note 2 uses when feeding into a chained Sub64borrow.
-(Select1 (SUBCconst n:(NEG (SUBZEzero x)) [0])) && n.Uses <= 2 => x
-
-// Constant folding
-(FABS (FMOVDconst [x])) => (FMOVDconst [math.Abs(x)])
-(FSQRT (FMOVDconst [x])) && x >= 0 => (FMOVDconst [math.Sqrt(x)])
-(FFLOOR (FMOVDconst [x])) => (FMOVDconst [math.Floor(x)])
-(FCEIL (FMOVDconst [x])) => (FMOVDconst [math.Ceil(x)])
-(FTRUNC (FMOVDconst [x])) => (FMOVDconst [math.Trunc(x)])
-
-// Rotates
-(RotateLeft8 <t> x (MOVDconst [c])) => (Or8 (Lsh8x64 <t> x (MOVDconst [c&7])) (Rsh8Ux64 <t> x (MOVDconst [-c&7])))
-(RotateLeft16 <t> x (MOVDconst [c])) => (Or16 (Lsh16x64 <t> x (MOVDconst [c&15])) (Rsh16Ux64 <t> x (MOVDconst [-c&15])))
-(RotateLeft32 x (MOVDconst [c])) => (ROTLWconst [c&31] x)
-(RotateLeft64 x (MOVDconst [c])) => (ROTLconst [c&63] x)
-
-// Rotate generation with const shift
-(ADD (SLDconst x [c]) (SRDconst x [d])) && d == 64-c => (ROTLconst [c] x)
-( OR (SLDconst x [c]) (SRDconst x [d])) && d == 64-c => (ROTLconst [c] x)
-(XOR (SLDconst x [c]) (SRDconst x [d])) && d == 64-c => (ROTLconst [c] x)
-
-(ADD (SLWconst x [c]) (SRWconst x [d])) && d == 32-c => (ROTLWconst [c] x)
-( OR (SLWconst x [c]) (SRWconst x [d])) && d == 32-c => (ROTLWconst [c] x)
-(XOR (SLWconst x [c]) (SRWconst x [d])) && d == 32-c => (ROTLWconst [c] x)
-
-// Rotate generation with non-const shift
-// these match patterns from math/bits/RotateLeft[32|64], but there could be others
-(ADD (SLD x (ANDconst [63] y)) (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))) => (ROTL x y)
-(ADD (SLD x (ANDconst [63] y)) (SRD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y)))) => (ROTL x y)
-( OR (SLD x (ANDconst [63] y)) (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))) => (ROTL x y)
-( OR (SLD x (ANDconst [63] y)) (SRD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y)))) => (ROTL x y)
-(XOR (SLD x (ANDconst [63] y)) (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))) => (ROTL x y)
-(XOR (SLD x (ANDconst [63] y)) (SRD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y)))) => (ROTL x y)
-
-
-(ADD (SLW x (ANDconst [31] y)) (SRW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y)))) => (ROTLW x y)
-(ADD (SLW x (ANDconst [31] y)) (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))) => (ROTLW x y)
-( OR (SLW x (ANDconst [31] y)) (SRW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y)))) => (ROTLW x y)
-( OR (SLW x (ANDconst [31] y)) (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))) => (ROTLW x y)
-(XOR (SLW x (ANDconst [31] y)) (SRW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y)))) => (ROTLW x y)
-(XOR (SLW x (ANDconst [31] y)) (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))) => (ROTLW x y)
-
-
-// Lowering rotates
-(RotateLeft32 x y) => (ROTLW x y)
-(RotateLeft64 x y) => (ROTL x y)
-
-// Constant rotate generation
-(ROTLW  x (MOVDconst [c])) => (ROTLWconst  x [c&31])
-(ROTL   x (MOVDconst [c])) => (ROTLconst   x [c&63])
-
-// Combine rotate and mask operations
-(ANDconst [m] (ROTLWconst [r] x)) && isPPC64WordRotateMask(m) => (RLWINM [encodePPC64RotateMask(r,m,32)] x)
-(AND (MOVDconst [m]) (ROTLWconst [r] x)) && isPPC64WordRotateMask(m) => (RLWINM [encodePPC64RotateMask(r,m,32)] x)
-(ANDconst [m] (ROTLW x r)) && isPPC64WordRotateMask(m) => (RLWNM [encodePPC64RotateMask(0,m,32)] x r)
-(AND (MOVDconst [m]) (ROTLW x r)) && isPPC64WordRotateMask(m) => (RLWNM [encodePPC64RotateMask(0,m,32)] x r)
-
-// Note, any rotated word bitmask is still a valid word bitmask.
-(ROTLWconst [r] (AND (MOVDconst [m]) x)) && isPPC64WordRotateMask(m) => (RLWINM [encodePPC64RotateMask(r,rotateLeft32(m,r),32)] x)
-(ROTLWconst [r] (ANDconst [m] x)) && isPPC64WordRotateMask(m) => (RLWINM [encodePPC64RotateMask(r,rotateLeft32(m,r),32)] x)
-
-(ANDconst [m] (SRWconst x [s])) && mergePPC64RShiftMask(m,s,32) == 0 => (MOVDconst [0])
-(ANDconst [m] (SRWconst x [s])) && mergePPC64AndSrwi(m,s) != 0 => (RLWINM [mergePPC64AndSrwi(m,s)] x)
-(AND (MOVDconst [m]) (SRWconst x [s])) && mergePPC64RShiftMask(m,s,32) == 0 => (MOVDconst [0])
-(AND (MOVDconst [m]) (SRWconst x [s])) && mergePPC64AndSrwi(m,s) != 0 => (RLWINM [mergePPC64AndSrwi(m,s)] x)
-
-(SRWconst (ANDconst [m] x) [s]) && mergePPC64RShiftMask(m>>uint(s),s,32) == 0 => (MOVDconst [0])
-(SRWconst (ANDconst [m] x) [s]) && mergePPC64AndSrwi(m>>uint(s),s) != 0 => (RLWINM [mergePPC64AndSrwi(m>>uint(s),s)] x)
-(SRWconst (AND (MOVDconst [m]) x) [s]) && mergePPC64RShiftMask(m>>uint(s),s,32) == 0 => (MOVDconst [0])
-(SRWconst (AND (MOVDconst [m]) x) [s]) && mergePPC64AndSrwi(m>>uint(s),s) != 0 => (RLWINM [mergePPC64AndSrwi(m>>uint(s),s)] x)
-
-// Merge shift right + shift left and clear left (e.g for a table lookup)
-(CLRLSLDI [c] (SRWconst [s] x)) && mergePPC64ClrlsldiSrw(int64(c),s) != 0 => (RLWINM [mergePPC64ClrlsldiSrw(int64(c),s)] x)
-(SLDconst [l] (SRWconst [r] x)) && mergePPC64SldiSrw(l,r) != 0 => (RLWINM [mergePPC64SldiSrw(l,r)] x)
-// The following reduction shows up frequently too. e.g b[(x>>14)&0xFF]
-(CLRLSLDI [c] i:(RLWINM [s] x)) && mergePPC64ClrlsldiRlwinm(c,s) != 0 => (RLWINM [mergePPC64ClrlsldiRlwinm(c,s)] x)
-
-// large constant shifts
-(Lsh64x64  _ (MOVDconst [c])) && uint64(c) >= 64 => (MOVDconst [0])
-(Rsh64Ux64 _ (MOVDconst [c])) && uint64(c) >= 64 => (MOVDconst [0])
-(Lsh32x64  _ (MOVDconst [c])) && uint64(c) >= 32 => (MOVDconst [0])
-(Rsh32Ux64 _ (MOVDconst [c])) && uint64(c) >= 32 => (MOVDconst [0])
-(Lsh16x64  _ (MOVDconst [c])) && uint64(c) >= 16 => (MOVDconst [0])
-(Rsh16Ux64 _ (MOVDconst [c])) && uint64(c) >= 16 => (MOVDconst [0])
-(Lsh8x64   _ (MOVDconst [c])) && uint64(c) >= 8  => (MOVDconst [0])
-(Rsh8Ux64  _ (MOVDconst [c])) && uint64(c) >= 8  => (MOVDconst [0])
-
-// large constant signed right shift, we leave the sign bit
-(Rsh64x64 x (MOVDconst [c])) && uint64(c) >= 64 => (SRADconst x [63])
-(Rsh32x64 x (MOVDconst [c])) && uint64(c) >= 32 => (SRAWconst x [63])
-(Rsh16x64 x (MOVDconst [c])) && uint64(c) >= 16 => (SRAWconst (SignExt16to32 x) [63])
-(Rsh8x64  x (MOVDconst [c])) && uint64(c) >= 8  => (SRAWconst (SignExt8to32  x) [63])
-
-// constant shifts
-(Lsh64x64  x (MOVDconst [c])) && uint64(c) < 64 => (SLDconst x [c])
-(Rsh64x64  x (MOVDconst [c])) && uint64(c) < 64 => (SRADconst x [c])
-(Rsh64Ux64 x (MOVDconst [c])) && uint64(c) < 64 => (SRDconst x [c])
-(Lsh32x64  x (MOVDconst [c])) && uint64(c) < 32 => (SLWconst x [c])
-(Rsh32x64  x (MOVDconst [c])) && uint64(c) < 32 => (SRAWconst x [c])
-(Rsh32Ux64 x (MOVDconst [c])) && uint64(c) < 32 => (SRWconst x [c])
-(Lsh16x64  x (MOVDconst [c])) && uint64(c) < 16 => (SLWconst x [c])
-(Rsh16x64  x (MOVDconst [c])) && uint64(c) < 16 => (SRAWconst (SignExt16to32 x) [c])
-(Rsh16Ux64 x (MOVDconst [c])) && uint64(c) < 16 => (SRWconst (ZeroExt16to32 x) [c])
-(Lsh8x64   x (MOVDconst [c])) && uint64(c) < 8  => (SLWconst x [c])
-(Rsh8x64   x (MOVDconst [c])) && uint64(c) < 8  => (SRAWconst (SignExt8to32  x) [c])
-(Rsh8Ux64  x (MOVDconst [c])) && uint64(c) < 8  => (SRWconst (ZeroExt8to32  x) [c])
-
-(Lsh64x32  x (MOVDconst [c])) && uint32(c) < 64 => (SLDconst x [c&63])
-(Rsh64x32  x (MOVDconst [c])) && uint32(c) < 64 => (SRADconst x [c&63])
-(Rsh64Ux32 x (MOVDconst [c])) && uint32(c) < 64 => (SRDconst x [c&63])
-(Lsh32x32  x (MOVDconst [c])) && uint32(c) < 32 => (SLWconst x [c&31])
-(Rsh32x32  x (MOVDconst [c])) && uint32(c) < 32 => (SRAWconst x [c&31])
-(Rsh32Ux32 x (MOVDconst [c])) && uint32(c) < 32 => (SRWconst x [c&31])
-(Lsh16x32  x (MOVDconst [c])) && uint32(c) < 16 => (SLWconst x [c&31])
-(Rsh16x32  x (MOVDconst [c])) && uint32(c) < 16 => (SRAWconst (SignExt16to32 x) [c&15])
-(Rsh16Ux32 x (MOVDconst [c])) && uint32(c) < 16 => (SRWconst (ZeroExt16to32 x) [c&15])
-(Lsh8x32   x (MOVDconst [c])) && uint32(c) < 8  => (SLWconst x [c&7])
-(Rsh8x32   x (MOVDconst [c])) && uint32(c) < 8  => (SRAWconst (SignExt8to32  x) [c&7])
-(Rsh8Ux32  x (MOVDconst [c])) && uint32(c) < 8  => (SRWconst (ZeroExt8to32  x) [c&7])
-
-// Lower bounded shifts first. No need to check shift value.
-(Lsh64x(64|32|16|8)  x y) && shiftIsBounded(v) => (SLD x y)
-(Lsh32x(64|32|16|8)  x y) && shiftIsBounded(v) => (SLW x y)
-(Lsh16x(64|32|16|8)  x y) && shiftIsBounded(v) => (SLW x y)
-(Lsh8x(64|32|16|8)   x y) && shiftIsBounded(v) => (SLW x y)
-(Rsh64Ux(64|32|16|8) x y) && shiftIsBounded(v) => (SRD x y)
-(Rsh32Ux(64|32|16|8) x y) && shiftIsBounded(v) => (SRW x y)
-(Rsh16Ux(64|32|16|8) x y) && shiftIsBounded(v) => (SRW (MOVHZreg x) y)
-(Rsh8Ux(64|32|16|8)  x y) && shiftIsBounded(v) => (SRW (MOVBZreg x) y)
-(Rsh64x(64|32|16|8)  x y) && shiftIsBounded(v) => (SRAD x y)
-(Rsh32x(64|32|16|8)  x y) && shiftIsBounded(v) => (SRAW x y)
-(Rsh16x(64|32|16|8)  x y) && shiftIsBounded(v) => (SRAW (MOVHreg x) y)
-(Rsh8x(64|32|16|8)   x y) && shiftIsBounded(v) => (SRAW (MOVBreg x) y)
-
-// non-constant rotates
-// These are subexpressions found in statements that can become rotates
-// In these cases the shift count is known to be < 64 so the more complicated expressions
-// with Mask & Carry is not needed
-(Lsh64x64 x (AND y (MOVDconst [63]))) => (SLD x (ANDconst <typ.Int64> [63] y))
-(Lsh64x64 x (ANDconst <typ.Int64> [63] y)) => (SLD x (ANDconst <typ.Int64> [63] y))
-(Rsh64Ux64 x (AND y (MOVDconst [63]))) => (SRD x (ANDconst <typ.Int64> [63] y))
-(Rsh64Ux64 x (ANDconst <typ.UInt> [63] y)) => (SRD x (ANDconst <typ.UInt> [63] y))
-(Rsh64Ux64 x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y))) => (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))
-(Rsh64Ux64 x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y))) => (SRD x (SUBFCconst <typ.UInt> [64]  (ANDconst <typ.UInt> [63] y)))
-(Rsh64Ux64 x (SUB <typ.UInt> (MOVDconst [64]) (AND <typ.UInt> y (MOVDconst [63])))) => (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))
-(Rsh64Ux64 x (SUBFCconst <typ.UInt> [64] (AND <typ.UInt> y (MOVDconst [63])))) => (SRD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y)))
-(Rsh64x64 x (AND y (MOVDconst [63]))) => (SRAD x (ANDconst <typ.Int64> [63] y))
-(Rsh64x64 x (ANDconst <typ.UInt> [63] y)) => (SRAD x (ANDconst <typ.UInt> [63] y))
-(Rsh64x64 x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y))) => (SRAD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))
-(Rsh64x64 x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y))) => (SRAD x (SUBFCconst <typ.UInt> [64]  (ANDconst <typ.UInt> [63] y)))
-(Rsh64x64 x (SUB <typ.UInt> (MOVDconst [64]) (AND <typ.UInt> y (MOVDconst [63])))) => (SRAD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))
-(Rsh64x64 x (SUBFCconst <typ.UInt> [64] (AND <typ.UInt> y (MOVDconst [63])))) => (SRAD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y)))
-
-(Lsh64x64 x y)  => (SLD  x (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [64]))))
-(Rsh64x64 x y) => (SRAD x (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [64]))))
-(Rsh64Ux64 x y) => (SRD x (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [64]))))
-
-(Lsh32x64 x (AND y (MOVDconst [31]))) => (SLW x (ANDconst <typ.Int32> [31] y))
-(Lsh32x64 x (ANDconst <typ.Int32> [31] y)) => (SLW x (ANDconst <typ.Int32> [31] y))
-
-(Rsh32Ux64 x (AND y (MOVDconst [31]))) => (SRW x (ANDconst <typ.Int32> [31] y))
-(Rsh32Ux64 x (ANDconst <typ.UInt> [31] y)) => (SRW x (ANDconst <typ.UInt> [31] y))
-(Rsh32Ux64 x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y))) => (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))
-(Rsh32Ux64 x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y))) => (SRW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y)))
-(Rsh32Ux64 x (SUB <typ.UInt> (MOVDconst [32]) (AND <typ.UInt> y (MOVDconst [31])))) => (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))
-(Rsh32Ux64 x (SUBFCconst <typ.UInt> [32] (AND <typ.UInt> y (MOVDconst [31])))) => (SRW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y)))
-
-(Rsh32x64 x (AND y (MOVDconst [31]))) => (SRAW x (ANDconst <typ.Int32> [31] y))
-(Rsh32x64 x (ANDconst <typ.UInt> [31] y)) => (SRAW x (ANDconst <typ.UInt> [31] y))
-(Rsh32x64 x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y))) => (SRAW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))
-(Rsh32x64 x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y))) => (SRAW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y)))
-(Rsh32x64 x (SUB <typ.UInt> (MOVDconst [32]) (AND <typ.UInt> y (MOVDconst [31])))) => (SRAW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))
-(Rsh32x64 x (SUBFCconst <typ.UInt> [32] (AND <typ.UInt> y (MOVDconst [31])))) => (SRAW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y)))
-
-(Rsh32x64 x y)  => (SRAW x (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [32]))))
-(Rsh32Ux64 x y) => (SRW  x (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [32]))))
-(Lsh32x64 x y)  => (SLW  x (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [32]))))
-
-(Rsh16x64 x y)  => (SRAW (SignExt16to32 x) (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [16]))))
-(Rsh16Ux64 x y) => (SRW  (ZeroExt16to32 x) (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [16]))))
-(Lsh16x64 x y)  => (SLW  x                 (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [16]))))
-
-(Rsh8x64 x y)  => (SRAW (SignExt8to32 x) (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [8]))))
-(Rsh8Ux64 x y) => (SRW  (ZeroExt8to32 x) (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [8]))))
-(Lsh8x64 x y)  => (SLW  x                (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [8]))))
-
-(Rsh64x32 x y)  => (SRAD x (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [64]))))
-(Rsh64Ux32 x y) => (SRD x  (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [64]))))
-(Lsh64x32 x y)  => (SLD x  (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [64]))))
-(Rsh32x32 x y)  => (SRAW x (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [32]))))
-(Rsh32Ux32 x y) => (SRW x  (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [32]))))
-(Lsh32x32 x y)  => (SLW x  (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [32]))))
-
-(Rsh16x32 x y)  => (SRAW (SignExt16to32 x) (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [16]))))
-(Rsh16Ux32 x y) => (SRW  (ZeroExt16to32 x) (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [16]))))
-(Lsh16x32 x y)  => (SLW  x                 (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [16]))))
-
-(Rsh8x32 x y)  => (SRAW (SignExt8to32 x) (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [8]))))
-(Rsh8Ux32 x y) => (SRW  (ZeroExt8to32 x) (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [8]))))
-(Lsh8x32 x y)  => (SLW  x                (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [8]))))
-
-
-(Rsh64x16 x y)  => (SRAD x (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt16to64 y) (MOVDconst [64]))))
-(Rsh64Ux16 x y) => (SRD x  (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt16to64 y) (MOVDconst [64]))))
-(Lsh64x16 x y)  => (SLD x  (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt16to64 y) (MOVDconst [64]))))
-
-(Rsh32x16 x y)  => (SRAW x (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt16to64 y) (MOVDconst [32]))))
-(Rsh32Ux16 x y) => (SRW x  (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt16to64 y) (MOVDconst [32]))))
-(Lsh32x16 x y)  => (SLW x  (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt16to64 y) (MOVDconst [32]))))
-
-(Rsh16x16 x y)  => (SRAW (SignExt16to32 x) (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt16to64 y) (MOVDconst [16]))))
-(Rsh16Ux16 x y) => (SRW  (ZeroExt16to32 x) (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt16to64 y) (MOVDconst [16]))))
-(Lsh16x16 x y)  => (SLW  x                 (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt16to64 y) (MOVDconst [16]))))
-
-(Rsh8x16 x y)  => (SRAW (SignExt8to32 x) (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt16to64 y) (MOVDconst [8]))))
-(Rsh8Ux16 x y) => (SRW  (ZeroExt8to32 x) (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt16to64 y) (MOVDconst [8]))))
-(Lsh8x16 x y)  => (SLW  x                (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt16to64 y) (MOVDconst [8]))))
-
-
-(Rsh64x8 x y)  => (SRAD x (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt8to64 y) (MOVDconst [64]))))
-(Rsh64Ux8 x y) => (SRD x  (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt8to64 y) (MOVDconst [64]))))
-(Lsh64x8 x y)  => (SLD x  (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt8to64 y) (MOVDconst [64]))))
-
-(Rsh32x8 x y)  => (SRAW x (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt8to64 y) (MOVDconst [32]))))
-(Rsh32Ux8 x y) => (SRW x  (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt8to64 y) (MOVDconst [32]))))
-(Lsh32x8 x y)  => (SLW x  (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt8to64 y) (MOVDconst [32]))))
-
-(Rsh16x8 x y)  => (SRAW (SignExt16to32 x) (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt8to64 y) (MOVDconst [16]))))
-(Rsh16Ux8 x y) => (SRW  (ZeroExt16to32 x) (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt8to64 y) (MOVDconst [16]))))
-(Lsh16x8 x y)  => (SLW  x                 (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt8to64 y) (MOVDconst [16]))))
-
-(Rsh8x8 x y)  => (SRAW (SignExt8to32 x) (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt8to64 y) (MOVDconst [8]))))
-(Rsh8Ux8 x y) => (SRW  (ZeroExt8to32 x) (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt8to64 y) (MOVDconst [8]))))
-(Lsh8x8 x y)  => (SLW  x                (ISEL [0] y (MOVDconst [-1]) (CMPU (ZeroExt8to64 y) (MOVDconst [8]))))
-
-// Cleaning up shift ops
-(ISEL [0] (ANDconst [d] y) (MOVDconst [-1]) (CMPU (ANDconst [d] y) (MOVDconst [c]))) && c >= d => (ANDconst [d] y)
-(ISEL [0] (ANDconst [d] y) (MOVDconst [-1]) (CMPUconst [c] (ANDconst [d] y))) && c >= d => (ANDconst [d] y)
-(ORN x (MOVDconst [-1])) => x
-
-(S(RAD|RD|LD) x (MOVDconst [c])) => (S(RAD|RD|LD)const [c&63 | (c>>6&1*63)] x)
-(S(RAW|RW|LW) x (MOVDconst [c])) => (S(RAW|RW|LW)const [c&31 | (c>>5&1*31)] x)
-
-(Addr {sym} base) => (MOVDaddr {sym} [0] base)
-(LocalAddr {sym} base _) => (MOVDaddr {sym} base)
-(OffPtr [off] ptr) => (ADD (MOVDconst <typ.Int64> [off]) ptr)
-
-// TODO: optimize these cases?
-(Ctz32NonZero ...) => (Ctz32 ...)
-(Ctz64NonZero ...) => (Ctz64 ...)
-
-(Ctz64 x) && buildcfg.GOPPC64<=8 => (POPCNTD (ANDN <typ.Int64> (ADDconst <typ.Int64> [-1] x) x))
-(Ctz64 x) => (CNTTZD x)
-(Ctz32 x) && buildcfg.GOPPC64<=8 => (POPCNTW (MOVWZreg (ANDN <typ.Int> (ADDconst <typ.Int> [-1] x) x)))
-(Ctz32 x) => (CNTTZW (MOVWZreg x))
-(Ctz16 x) => (POPCNTW (MOVHZreg (ANDN <typ.Int16> (ADDconst <typ.Int16> [-1] x) x)))
-(Ctz8 x)  => (POPCNTB (MOVBZreg (ANDN <typ.UInt8> (ADDconst <typ.UInt8> [-1] x) x)))
-
-(BitLen64 x) => (SUBFCconst [64] (CNTLZD <typ.Int> x))
-(BitLen32 x) => (SUBFCconst [32] (CNTLZW <typ.Int> x))
-
-(PopCount64 ...) => (POPCNTD ...)
-(PopCount32 x) => (POPCNTW (MOVWZreg x))
-(PopCount16 x) => (POPCNTW (MOVHZreg x))
-(PopCount8 x) => (POPCNTB (MOVBZreg x))
-
-(And(64|32|16|8) ...) => (AND ...)
-(Or(64|32|16|8) ...) => (OR ...)
-(Xor(64|32|16|8) ...) => (XOR ...)
-
-(Neg(64|32|16|8) ...) => (NEG ...)
-(Neg64F ...) => (FNEG ...)
-(Neg32F ...) => (FNEG ...)
-
-(Com(64|32|16|8) x) => (NOR x x)
-
-// Lowering boolean ops
-(AndB ...) => (AND ...)
-(OrB ...) => (OR ...)
-(Not x) => (XORconst [1] x)
-
-// Merge logical operations
-(AND x (NOR y y)) => (ANDN x y)
-(OR x (NOR y y)) => (ORN x y)
-
-// Lowering comparisons
-(EqB x y)  => (ANDconst [1] (EQV x y))
-// Sign extension dependence on operand sign sets up for sign/zero-extension elision later
-(Eq8 x y) && isSigned(x.Type) && isSigned(y.Type) => (Equal (CMPW (SignExt8to32 x) (SignExt8to32 y)))
-(Eq16 x y) && isSigned(x.Type) && isSigned(y.Type) => (Equal (CMPW (SignExt16to32 x) (SignExt16to32 y)))
-(Eq8 x y) => (Equal (CMPW (ZeroExt8to32 x) (ZeroExt8to32 y)))
-(Eq16 x y) => (Equal (CMPW (ZeroExt16to32 x) (ZeroExt16to32 y)))
-(Eq32 x y) => (Equal (CMPW x y))
-(Eq64 x y) => (Equal (CMP x y))
-(Eq32F x y) => (Equal (FCMPU x y))
-(Eq64F x y) => (Equal (FCMPU x y))
-(EqPtr x y) => (Equal (CMP x y))
-
-(NeqB ...) => (XOR ...)
-// Like Eq8 and Eq16, prefer sign extension likely to enable later elision.
-(Neq8 x y) && isSigned(x.Type) && isSigned(y.Type) => (NotEqual (CMPW (SignExt8to32 x) (SignExt8to32 y)))
-(Neq16 x y) && isSigned(x.Type) && isSigned(y.Type) => (NotEqual (CMPW (SignExt16to32 x) (SignExt16to32 y)))
-(Neq8 x y)  => (NotEqual (CMPW (ZeroExt8to32 x) (ZeroExt8to32 y)))
-(Neq16 x y) => (NotEqual (CMPW (ZeroExt16to32 x) (ZeroExt16to32 y)))
-(Neq32 x y) => (NotEqual (CMPW x y))
-(Neq64 x y) => (NotEqual (CMP x y))
-(Neq32F x y) => (NotEqual (FCMPU x y))
-(Neq64F x y) => (NotEqual (FCMPU x y))
-(NeqPtr x y) => (NotEqual (CMP x y))
-
-(Less8 x y)  => (LessThan (CMPW (SignExt8to32 x) (SignExt8to32 y)))
-(Less16 x y) => (LessThan (CMPW (SignExt16to32 x) (SignExt16to32 y)))
-(Less32 x y) => (LessThan (CMPW x y))
-(Less64 x y) => (LessThan (CMP x y))
-(Less32F x y) => (FLessThan (FCMPU x y))
-(Less64F x y) => (FLessThan (FCMPU x y))
-
-(Less8U x y)  => (LessThan (CMPWU (ZeroExt8to32 x) (ZeroExt8to32 y)))
-(Less16U x y) => (LessThan (CMPWU (ZeroExt16to32 x) (ZeroExt16to32 y)))
-(Less32U x y) => (LessThan (CMPWU x y))
-(Less64U x y) => (LessThan (CMPU x y))
-
-(Leq8 x y)  => (LessEqual (CMPW (SignExt8to32 x) (SignExt8to32 y)))
-(Leq16 x y) => (LessEqual (CMPW (SignExt16to32 x) (SignExt16to32 y)))
-(Leq32 x y) => (LessEqual (CMPW x y))
-(Leq64 x y) => (LessEqual (CMP x y))
-(Leq32F x y) => (FLessEqual (FCMPU x y))
-(Leq64F x y) => (FLessEqual (FCMPU x y))
-
-(Leq8U x y)  => (LessEqual (CMPWU (ZeroExt8to32 x) (ZeroExt8to32 y)))
-(Leq16U x y) => (LessEqual (CMPWU (ZeroExt16to32 x) (ZeroExt16to32 y)))
-(Leq32U x y) => (LessEqual (CMPWU x y))
-(Leq64U x y) => (LessEqual (CMPU x y))
-
-// Absorb pseudo-ops into blocks.
-(If (Equal cc) yes no) => (EQ cc yes no)
-(If (NotEqual cc) yes no) => (NE cc yes no)
-(If (LessThan cc) yes no) => (LT cc yes no)
-(If (LessEqual cc) yes no) => (LE cc yes no)
-(If (GreaterThan cc) yes no) => (GT cc yes no)
-(If (GreaterEqual cc) yes no) => (GE cc yes no)
-(If (FLessThan cc) yes no) => (FLT cc yes no)
-(If (FLessEqual cc) yes no) => (FLE cc yes no)
-(If (FGreaterThan cc) yes no) => (FGT cc yes no)
-(If (FGreaterEqual cc) yes no) => (FGE cc yes no)
-
-(If cond yes no) => (NE (CMPWconst [0] (ANDconst <typ.UInt32> [1] cond)) yes no)
-
-// Absorb boolean tests into block
-(NE (CMPWconst [0] (ANDconst [1] (Equal cc))) yes no) => (EQ cc yes no)
-(NE (CMPWconst [0] (ANDconst [1] (NotEqual cc))) yes no) => (NE cc yes no)
-(NE (CMPWconst [0] (ANDconst [1] (LessThan cc))) yes no) => (LT cc yes no)
-(NE (CMPWconst [0] (ANDconst [1] (LessEqual cc))) yes no) => (LE cc yes no)
-(NE (CMPWconst [0] (ANDconst [1] (GreaterThan cc))) yes no) => (GT cc yes no)
-(NE (CMPWconst [0] (ANDconst [1] (GreaterEqual cc))) yes no) => (GE cc yes no)
-(NE (CMPWconst [0] (ANDconst [1] (FLessThan cc))) yes no) => (FLT cc yes no)
-(NE (CMPWconst [0] (ANDconst [1] (FLessEqual cc))) yes no) => (FLE cc yes no)
-(NE (CMPWconst [0] (ANDconst [1] (FGreaterThan cc))) yes no) => (FGT cc yes no)
-(NE (CMPWconst [0] (ANDconst [1] (FGreaterEqual cc))) yes no) => (FGE cc yes no)
-
-// Elide compares of bit tests // TODO need to make both CC and result of ANDCC available.
-(EQ (CMPconst [0] (ANDconst [c] x)) yes no) => (EQ (ANDCCconst [c] x) yes no)
-(NE (CMPconst [0] (ANDconst [c] x)) yes no) => (NE (ANDCCconst [c] x) yes no)
-(EQ (CMPWconst [0] (ANDconst [c] x)) yes no) => (EQ (ANDCCconst [c] x) yes no)
-(NE (CMPWconst [0] (ANDconst [c] x)) yes no) => (NE (ANDCCconst [c] x) yes no)
-
-// absorb flag constants into branches
-(EQ (FlagEQ) yes no) => (First yes no)
-(EQ (FlagLT) yes no) => (First no yes)
-(EQ (FlagGT) yes no) => (First no yes)
-
-(NE (FlagEQ) yes no) => (First no yes)
-(NE (FlagLT) yes no) => (First yes no)
-(NE (FlagGT) yes no) => (First yes no)
-
-(LT (FlagEQ) yes no) => (First no yes)
-(LT (FlagLT) yes no) => (First yes no)
-(LT (FlagGT) yes no) => (First no yes)
-
-(LE (FlagEQ) yes no) => (First yes no)
-(LE (FlagLT) yes no) => (First yes no)
-(LE (FlagGT) yes no) => (First no yes)
-
-(GT (FlagEQ) yes no) => (First no yes)
-(GT (FlagLT) yes no) => (First no yes)
-(GT (FlagGT) yes no) => (First yes no)
-
-(GE (FlagEQ) yes no) => (First yes no)
-(GE (FlagLT) yes no) => (First no yes)
-(GE (FlagGT) yes no) => (First yes no)
-
-// absorb InvertFlags into branches
-(LT (InvertFlags cmp) yes no) => (GT cmp yes no)
-(GT (InvertFlags cmp) yes no) => (LT cmp yes no)
-(LE (InvertFlags cmp) yes no) => (GE cmp yes no)
-(GE (InvertFlags cmp) yes no) => (LE cmp yes no)
-(EQ (InvertFlags cmp) yes no) => (EQ cmp yes no)
-(NE (InvertFlags cmp) yes no) => (NE cmp yes no)
-
-// constant comparisons
-(CMPWconst (MOVDconst [x]) [y]) && int32(x)==int32(y) => (FlagEQ)
-(CMPWconst (MOVDconst [x]) [y]) && int32(x)<int32(y)  => (FlagLT)
-(CMPWconst (MOVDconst [x]) [y]) && int32(x)>int32(y)  => (FlagGT)
-
-(CMPconst (MOVDconst [x]) [y]) && x==y => (FlagEQ)
-(CMPconst (MOVDconst [x]) [y]) && x<y  => (FlagLT)
-(CMPconst (MOVDconst [x]) [y]) && x>y  => (FlagGT)
-
-(CMPWUconst (MOVDconst [x]) [y]) && int32(x)==int32(y)  => (FlagEQ)
-(CMPWUconst (MOVDconst [x]) [y]) && uint32(x)<uint32(y) => (FlagLT)
-(CMPWUconst (MOVDconst [x]) [y]) && uint32(x)>uint32(y) => (FlagGT)
-
-(CMPUconst (MOVDconst [x]) [y]) && x==y  => (FlagEQ)
-(CMPUconst (MOVDconst [x]) [y]) && uint64(x)<uint64(y) => (FlagLT)
-(CMPUconst (MOVDconst [x]) [y]) && uint64(x)>uint64(y) => (FlagGT)
-
-// other known comparisons
-//(CMPconst (MOVBUreg _) [c]) && 0xff < c => (FlagLT)
-//(CMPconst (MOVHUreg _) [c]) && 0xffff < c => (FlagLT)
-//(CMPconst (ANDconst _ [m]) [n]) && 0 <= int32(m) && int32(m) < int32(n) => (FlagLT)
-//(CMPconst (SRLconst _ [c]) [n]) && 0 <= n && 0 < c && c <= 32 && (1<<uint32(32-c)) <= uint32(n) => (FlagLT)
-
-// absorb flag constants into boolean values
-(Equal (FlagEQ)) => (MOVDconst [1])
-(Equal (FlagLT)) => (MOVDconst [0])
-(Equal (FlagGT)) => (MOVDconst [0])
-
-(NotEqual (FlagEQ)) => (MOVDconst [0])
-(NotEqual (FlagLT)) => (MOVDconst [1])
-(NotEqual (FlagGT)) => (MOVDconst [1])
-
-(LessThan (FlagEQ)) => (MOVDconst [0])
-(LessThan (FlagLT)) => (MOVDconst [1])
-(LessThan (FlagGT)) => (MOVDconst [0])
-
-(LessEqual (FlagEQ)) => (MOVDconst [1])
-(LessEqual (FlagLT)) => (MOVDconst [1])
-(LessEqual (FlagGT)) => (MOVDconst [0])
-
-(GreaterThan (FlagEQ)) => (MOVDconst [0])
-(GreaterThan (FlagLT)) => (MOVDconst [0])
-(GreaterThan (FlagGT)) => (MOVDconst [1])
-
-(GreaterEqual (FlagEQ)) => (MOVDconst [1])
-(GreaterEqual (FlagLT)) => (MOVDconst [0])
-(GreaterEqual (FlagGT)) => (MOVDconst [1])
-
-// absorb InvertFlags into boolean values
-(Equal (InvertFlags x)) => (Equal x)
-(NotEqual (InvertFlags x)) => (NotEqual x)
-(LessThan (InvertFlags x)) => (GreaterThan x)
-(GreaterThan (InvertFlags x)) => (LessThan x)
-(LessEqual (InvertFlags x)) => (GreaterEqual x)
-(GreaterEqual (InvertFlags x)) => (LessEqual x)
-
-// Elide compares of bit tests // TODO need to make both CC and result of ANDCC available.
-((EQ|NE|LT|LE|GT|GE) (CMPconst [0] (ANDconst [c] x)) yes no) => ((EQ|NE|LT|LE|GT|GE) (ANDCCconst [c] x) yes no)
-((EQ|NE|LT|LE|GT|GE) (CMPWconst [0] (ANDconst [c] x)) yes no) => ((EQ|NE|LT|LE|GT|GE) (ANDCCconst [c] x) yes no)
-((EQ|NE|LT|LE|GT|GE) (CMPconst [0] z:(AND x y)) yes no) && z.Uses == 1 => ((EQ|NE|LT|LE|GT|GE) (ANDCC x y) yes no)
-((EQ|NE|LT|LE|GT|GE) (CMPconst [0] z:(OR x y)) yes no) && z.Uses == 1 => ((EQ|NE|LT|LE|GT|GE) (ORCC x y) yes no)
-((EQ|NE|LT|LE|GT|GE) (CMPconst [0] z:(XOR x y)) yes no) && z.Uses == 1 => ((EQ|NE|LT|LE|GT|GE) (XORCC x y) yes no)
-
-// Only lower after bool is lowered. It should always lower. This helps ensure the folding below happens reliably.
-(CondSelect x y bool) && flagArg(bool) == nil => (ISEL [6] x y (CMPWconst [0] bool))
-// Fold any CR -> GPR -> CR transfers when applying the above rule.
-(ISEL [6] x y (CMPWconst [0] (ISELB [c] one cmp))) => (ISEL [c] x y cmp)
-
-// Lowering loads
-(Load <t> ptr mem) && (is64BitInt(t) || isPtr(t)) => (MOVDload ptr mem)
-(Load <t> ptr mem) && is32BitInt(t) && isSigned(t) => (MOVWload ptr mem)
-(Load <t> ptr mem) && is32BitInt(t) && !isSigned(t) => (MOVWZload ptr mem)
-(Load <t> ptr mem) && is16BitInt(t) && isSigned(t) => (MOVHload ptr mem)
-(Load <t> ptr mem) && is16BitInt(t) && !isSigned(t) => (MOVHZload ptr mem)
-(Load <t> ptr mem) && t.IsBoolean() => (MOVBZload ptr mem)
-(Load <t> ptr mem) && is8BitInt(t) && isSigned(t) => (MOVBreg (MOVBZload ptr mem)) // PPC has no signed-byte load.
-(Load <t> ptr mem) && is8BitInt(t) && !isSigned(t) => (MOVBZload ptr mem)
-
-(Load <t> ptr mem) && is32BitFloat(t) => (FMOVSload ptr mem)
-(Load <t> ptr mem) && is64BitFloat(t) => (FMOVDload ptr mem)
-
-(Store {t} ptr val mem) && t.Size() == 8 && is64BitFloat(val.Type) => (FMOVDstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 8 && is32BitFloat(val.Type) => (FMOVDstore ptr val mem) // glitch from (Cvt32Fto64F x) => x -- type is wrong
-(Store {t} ptr val mem) && t.Size() == 4 && is32BitFloat(val.Type) => (FMOVSstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 8 && !is64BitFloat(val.Type) => (MOVDstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 4 && is32BitInt(val.Type) => (MOVWstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 2 => (MOVHstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 1 => (MOVBstore ptr val mem)
-
-// Using Zero instead of LoweredZero allows the
-// target address to be folded where possible.
-(Zero [0] _ mem) => mem
-(Zero [1] destptr mem) => (MOVBstorezero destptr mem)
-(Zero [2] destptr mem) =>
-	(MOVHstorezero destptr mem)
-(Zero [3] destptr mem) =>
-	(MOVBstorezero [2] destptr
-		(MOVHstorezero destptr mem))
-(Zero [4] destptr mem) =>
-	(MOVWstorezero destptr mem)
-(Zero [5] destptr mem) =>
-	(MOVBstorezero [4] destptr
-        	(MOVWstorezero destptr mem))
-(Zero [6] destptr mem) =>
-	(MOVHstorezero [4] destptr
-		(MOVWstorezero destptr mem))
-(Zero [7] destptr mem) =>
-	(MOVBstorezero [6] destptr
-		(MOVHstorezero [4] destptr
-			(MOVWstorezero destptr mem)))
-
-(Zero [8] {t} destptr mem) => (MOVDstorezero destptr mem)
-(Zero [12] {t} destptr mem) =>
-        (MOVWstorezero [8] destptr
-                (MOVDstorezero [0] destptr mem))
-(Zero [16] {t} destptr mem) =>
-       (MOVDstorezero [8] destptr
-                (MOVDstorezero [0] destptr mem))
-(Zero [24] {t} destptr mem) =>
-       (MOVDstorezero [16] destptr
-               (MOVDstorezero [8] destptr
-                       (MOVDstorezero [0] destptr mem)))
-(Zero [32] {t} destptr mem) =>
-       (MOVDstorezero [24] destptr
-               (MOVDstorezero [16] destptr
-                       (MOVDstorezero [8] destptr
-                               (MOVDstorezero [0] destptr mem))))
-
-// Handle cases not handled above
-// Lowered Short cases do not generate loops, and as a result don't clobber
-// the address registers or flags.
-(Zero [s] ptr mem) && buildcfg.GOPPC64 <= 8 && s < 64 => (LoweredZeroShort [s] ptr mem)
-(Zero [s] ptr mem) && buildcfg.GOPPC64 <= 8 => (LoweredZero [s] ptr mem)
-(Zero [s] ptr mem) && s < 128 && buildcfg.GOPPC64 >= 9 => (LoweredQuadZeroShort [s] ptr mem)
-(Zero [s] ptr mem) && buildcfg.GOPPC64 >= 9 => (LoweredQuadZero [s] ptr mem)
-
-// moves
-(Move [0] _ _ mem) => mem
-(Move [1] dst src mem) => (MOVBstore dst (MOVBZload src mem) mem)
-(Move [2] dst src mem) =>
-        (MOVHstore dst (MOVHZload src mem) mem)
-(Move [4] dst src mem) =>
-	(MOVWstore dst (MOVWZload src mem) mem)
-// MOVD for load and store must have offsets that are multiple of 4
-(Move [8] {t} dst src mem) =>
-	(MOVDstore dst (MOVDload src mem) mem)
-(Move [3] dst src mem) =>
-        (MOVBstore [2] dst (MOVBZload [2] src mem)
-                (MOVHstore dst (MOVHload src mem) mem))
-(Move [5] dst src mem) =>
-        (MOVBstore [4] dst (MOVBZload [4] src mem)
-                (MOVWstore dst (MOVWZload src mem) mem))
-(Move [6] dst src mem) =>
-        (MOVHstore [4] dst (MOVHZload [4] src mem)
-                (MOVWstore dst (MOVWZload src mem) mem))
-(Move [7] dst src mem) =>
-        (MOVBstore [6] dst (MOVBZload [6] src mem)
-                (MOVHstore [4] dst (MOVHZload [4] src mem)
-                        (MOVWstore dst (MOVWZload src mem) mem)))
-
-// Large move uses a loop. Since the address is computed and the
-// offset is zero, any alignment can be used.
-(Move [s] dst src mem) && s > 8 && buildcfg.GOPPC64 <= 8 && logLargeCopy(v, s) =>
-        (LoweredMove [s] dst src mem)
-(Move [s] dst src mem) && s > 8 && s <= 64 && buildcfg.GOPPC64 >= 9 =>
-        (LoweredQuadMoveShort [s] dst src mem)
-(Move [s] dst src mem) && s > 8 && buildcfg.GOPPC64 >= 9 && logLargeCopy(v, s) =>
-        (LoweredQuadMove [s] dst src mem)
-
-// Calls
-// Lowering calls
-(StaticCall ...) => (CALLstatic ...)
-(ClosureCall ...) => (CALLclosure ...)
-(InterCall ...) => (CALLinter ...)
-(TailCall ...) => (CALLtail ...)
-
-// Miscellaneous
-(GetClosurePtr ...) => (LoweredGetClosurePtr ...)
-(GetCallerSP ...) => (LoweredGetCallerSP ...)
-(GetCallerPC ...) => (LoweredGetCallerPC ...)
-(IsNonNil ptr) => (NotEqual (CMPconst [0] ptr))
-(IsInBounds idx len) => (LessThan (CMPU idx len))
-(IsSliceInBounds idx len) => (LessEqual (CMPU idx len))
-(NilCheck ...) => (LoweredNilCheck ...)
-
-// Write barrier.
-(WB ...) => (LoweredWB ...)
-
-// Publication barrier as intrinsic
-(PubBarrier ...) => (LoweredPubBarrier ...)
-
-(PanicBounds [kind] x y mem) && boundsABI(kind) == 0 => (LoweredPanicBoundsA [kind] x y mem)
-(PanicBounds [kind] x y mem) && boundsABI(kind) == 1 => (LoweredPanicBoundsB [kind] x y mem)
-(PanicBounds [kind] x y mem) && boundsABI(kind) == 2 => (LoweredPanicBoundsC [kind] x y mem)
-
-// Optimizations
-// Note that PPC "logical" immediates come in 0:15 and 16:31 unsigned immediate forms,
-// so ORconst, XORconst easily expand into a pair.
-
-// Include very-large constants in the const-const case.
-(AND (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [c&d])
-(OR (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [c|d])
-(XOR (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [c^d])
-(ORN (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [c|^d])
-(ANDN (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [c&^d])
-(NOR (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [^(c|d)])
-
-// Discover consts
-(AND x (MOVDconst [c])) && isU16Bit(c) => (ANDconst [c] x)
-(XOR x (MOVDconst [c])) && isU32Bit(c) => (XORconst [c] x)
-(OR x (MOVDconst [c])) && isU32Bit(c) => (ORconst [c] x)
-
-// Simplify consts
-(ANDconst [c] (ANDconst [d] x)) => (ANDconst [c&d] x)
-(ORconst [c] (ORconst [d] x)) => (ORconst [c|d] x)
-(XORconst [c] (XORconst [d] x)) => (XORconst [c^d] x)
-(ANDconst [-1] x) => x
-(ANDconst [0] _) => (MOVDconst [0])
-(XORconst [0] x) => x
-(ORconst [-1] _) => (MOVDconst [-1])
-(ORconst [0] x) => x
-
-// zero-extend of small and => small and
-(MOVBZreg y:(ANDconst [c] _)) && uint64(c) <= 0xFF => y
-(MOVHZreg y:(ANDconst [c] _)) && uint64(c) <= 0xFFFF => y
-(MOVWZreg y:(ANDconst [c] _)) && uint64(c) <= 0xFFFFFFFF => y
-(MOVWZreg y:(AND (MOVDconst [c]) _)) && uint64(c) <= 0xFFFFFFFF => y
-
-// sign extend of small-positive and => small-positive-and
-(MOVBreg y:(ANDconst [c] _)) && uint64(c) <= 0x7F => y
-(MOVHreg y:(ANDconst [c] _)) && uint64(c) <= 0x7FFF => y
-(MOVWreg y:(ANDconst [c] _)) && uint64(c) <= 0xFFFF => y // 0xFFFF is largest immediate constant, when regarded as 32-bit is > 0
-(MOVWreg y:(AND (MOVDconst [c]) _)) && uint64(c) <= 0x7FFFFFFF => y
-
-// small and of zero-extend => either zero-extend or small and
-(ANDconst [c] y:(MOVBZreg _)) && c&0xFF == 0xFF => y
-(ANDconst [0xFF] y:(MOVBreg _)) => y
-(ANDconst [c] y:(MOVHZreg _))  && c&0xFFFF == 0xFFFF => y
-(ANDconst [0xFFFF] y:(MOVHreg _)) => y
-
-(AND (MOVDconst [c]) y:(MOVWZreg _))  && c&0xFFFFFFFF == 0xFFFFFFFF => y
-(AND (MOVDconst [0xFFFFFFFF]) y:(MOVWreg x)) => (MOVWZreg x)
-// normal case
-(ANDconst [c] (MOV(B|BZ)reg x)) => (ANDconst [c&0xFF] x)
-(ANDconst [c] (MOV(H|HZ)reg x)) => (ANDconst [c&0xFFFF] x)
-(ANDconst [c] (MOV(W|WZ)reg x)) => (ANDconst [c&0xFFFFFFFF] x)
-
-// Eliminate unnecessary sign/zero extend following right shift
-(MOV(B|H|W)Zreg (SRWconst [c] (MOVBZreg x))) => (SRWconst [c] (MOVBZreg x))
-(MOV(H|W)Zreg (SRWconst [c] (MOVHZreg x))) => (SRWconst [c] (MOVHZreg x))
-(MOVWZreg (SRWconst [c] (MOVWZreg x))) => (SRWconst [c] (MOVWZreg x))
-(MOV(B|H|W)reg (SRAWconst [c] (MOVBreg x))) => (SRAWconst [c] (MOVBreg x))
-(MOV(H|W)reg (SRAWconst [c] (MOVHreg x))) => (SRAWconst [c] (MOVHreg x))
-(MOVWreg (SRAWconst [c] (MOVWreg x))) => (SRAWconst [c] (MOVWreg x))
-
-(MOVWZreg (SRWconst [c] x)) && sizeof(x.Type) <= 32 => (SRWconst [c] x)
-(MOVHZreg (SRWconst [c] x)) && sizeof(x.Type) <= 16 => (SRWconst [c] x)
-(MOVBZreg (SRWconst [c] x)) && sizeof(x.Type) == 8 => (SRWconst [c] x)
-(MOVWreg (SRAWconst [c] x)) && sizeof(x.Type) <= 32 => (SRAWconst [c] x)
-(MOVHreg (SRAWconst [c] x)) && sizeof(x.Type) <= 16 => (SRAWconst [c] x)
-(MOVBreg (SRAWconst [c] x)) && sizeof(x.Type) == 8 => (SRAWconst [c] x)
-
-// initial right shift will handle sign/zero extend
-(MOVBZreg (SRDconst [c] x)) && c>=56 => (SRDconst [c] x)
-(MOVBreg (SRDconst [c] x)) && c>56 => (SRDconst [c] x)
-(MOVBreg (SRDconst [c] x)) && c==56 => (SRADconst [c] x)
-(MOVBreg (SRADconst [c] x)) && c>=56 => (SRADconst [c] x)
-(MOVBZreg (SRWconst [c] x)) && c>=24 => (SRWconst [c] x)
-(MOVBreg (SRWconst [c] x)) && c>24 => (SRWconst [c] x)
-(MOVBreg (SRWconst [c] x)) && c==24 => (SRAWconst [c] x)
-(MOVBreg (SRAWconst [c] x)) && c>=24 => (SRAWconst [c] x)
-
-(MOVHZreg (SRDconst [c] x)) && c>=48 => (SRDconst [c] x)
-(MOVHreg (SRDconst [c] x)) && c>48 => (SRDconst [c] x)
-(MOVHreg (SRDconst [c] x)) && c==48 => (SRADconst [c] x)
-(MOVHreg (SRADconst [c] x)) && c>=48 => (SRADconst [c] x)
-(MOVHZreg (SRWconst [c] x)) && c>=16 => (SRWconst [c] x)
-(MOVHreg (SRWconst [c] x)) && c>16 => (SRWconst [c] x)
-(MOVHreg (SRAWconst [c] x)) && c>=16 => (SRAWconst [c] x)
-(MOVHreg (SRWconst [c] x)) && c==16 => (SRAWconst [c] x)
-
-(MOVWZreg (SRDconst [c] x)) && c>=32 => (SRDconst [c] x)
-(MOVWreg (SRDconst [c] x)) && c>32 => (SRDconst [c] x)
-(MOVWreg (SRADconst [c] x)) && c>=32 => (SRADconst [c] x)
-(MOVWreg (SRDconst [c] x)) && c==32 => (SRADconst [c] x)
-
-// Various redundant zero/sign extension combinations.
-(MOVBZreg y:(MOVBZreg _)) => y  // repeat
-(MOVBreg y:(MOVBreg _)) => y // repeat
-(MOVBreg (MOVBZreg x)) => (MOVBreg x)
-(MOVBZreg (MOVBreg x)) => (MOVBZreg x)
-
-// H - there are more combinations than these
-
-(MOVHZreg y:(MOVHZreg _)) => y // repeat
-(MOVHZreg y:(MOVBZreg _)) => y // wide of narrow
-(MOVHZreg y:(MOVHBRload _ _)) => y
-
-(MOVHreg y:(MOVHreg _)) => y // repeat
-(MOVHreg y:(MOVBreg _)) => y // wide of narrow
-
-(MOVHreg y:(MOVHZreg x)) => (MOVHreg x)
-(MOVHZreg y:(MOVHreg x)) => (MOVHZreg x)
-
-// W - there are more combinations than these
-
-(MOVWZreg y:(MOVWZreg _)) => y // repeat
-(MOVWZreg y:(MOVHZreg _)) => y // wide of narrow
-(MOVWZreg y:(MOVBZreg _)) => y // wide of narrow
-(MOVWZreg y:(MOVHBRload _ _)) => y
-(MOVWZreg y:(MOVWBRload _ _)) => y
-
-(MOVWreg y:(MOVWreg _)) => y // repeat
-(MOVWreg y:(MOVHreg _)) => y // wide of narrow
-(MOVWreg y:(MOVBreg _)) => y // wide of narrow
-
-(MOVWreg y:(MOVWZreg x)) => (MOVWreg x)
-(MOVWZreg y:(MOVWreg x)) => (MOVWZreg x)
-
-// Truncate then logical then truncate: omit first, lesser or equal truncate
-(MOVWZreg ((OR|XOR|AND) <t> x (MOVWZreg y))) => (MOVWZreg ((OR|XOR|AND) <t> x y))
-(MOVHZreg ((OR|XOR|AND) <t> x (MOVWZreg y))) => (MOVHZreg ((OR|XOR|AND) <t> x y))
-(MOVHZreg ((OR|XOR|AND) <t> x (MOVHZreg y))) => (MOVHZreg ((OR|XOR|AND) <t> x y))
-(MOVBZreg ((OR|XOR|AND) <t> x (MOVWZreg y))) => (MOVBZreg ((OR|XOR|AND) <t> x y))
-(MOVBZreg ((OR|XOR|AND) <t> x (MOVHZreg y))) => (MOVBZreg ((OR|XOR|AND) <t> x y))
-(MOVBZreg ((OR|XOR|AND) <t> x (MOVBZreg y))) => (MOVBZreg ((OR|XOR|AND) <t> x y))
-
-(MOV(B|H|W)Zreg z:(ANDconst [c] (MOVBZload ptr x))) => z
-(MOVBZreg z:(AND y (MOVBZload ptr x))) => z
-(MOV(H|W)Zreg z:(ANDconst [c] (MOVHZload ptr x))) => z
-(MOVHZreg z:(AND y (MOVHZload ptr x))) => z
-(MOVWZreg z:(ANDconst [c] (MOVWZload ptr x))) => z
-(MOVWZreg z:(AND y (MOVWZload ptr x))) => z
-
-// Arithmetic constant ops
-
-(ADD x (MOVDconst [c])) && is32Bit(c) => (ADDconst [c] x)
-(ADDconst [c] (ADDconst [d] x)) && is32Bit(c+d) => (ADDconst [c+d] x)
-(ADDconst [0] x) => x
-(SUB x (MOVDconst [c])) && is32Bit(-c) => (ADDconst [-c] x)
-
-(ADDconst [c] (MOVDaddr [d] {sym} x)) && is32Bit(c+int64(d)) => (MOVDaddr [int32(c+int64(d))] {sym} x)
-(ADDconst [c] x:(SP)) && is32Bit(c) => (MOVDaddr [int32(c)] x) // so it is rematerializeable
-
-(MULL(W|D) x (MOVDconst [c])) && is16Bit(c) => (MULL(W|D)const [int32(c)] x)
-
-// Subtract from (with carry, but ignored) constant.
-// Note, these clobber the carry bit.
-(SUB (MOVDconst [c]) x) && is32Bit(c) => (SUBFCconst [c] x)
-(SUBFCconst [c] (NEG x)) => (ADDconst [c] x)
-(SUBFCconst [c] (SUBFCconst [d] x)) && is32Bit(c-d) => (ADDconst [c-d] x)
-(SUBFCconst [0] x) => (NEG x)
-(ADDconst [c] (SUBFCconst [d] x)) && is32Bit(c+d) => (SUBFCconst [c+d] x)
-(NEG (ADDconst [c] x)) && is32Bit(-c) => (SUBFCconst [-c] x)
-(NEG (SUBFCconst [c] x)) && is32Bit(-c) => (ADDconst [-c] x)
-(NEG (SUB x y)) => (SUB y x)
-(NEG (NEG x)) => x
-
-// Use register moves instead of stores and loads to move int<=>float values
-// Common with math Float64bits, Float64frombits
-(MOVDload [off] {sym} ptr (FMOVDstore [off] {sym} ptr x _)) => (MFVSRD x)
-(FMOVDload [off] {sym} ptr (MOVDstore [off] {sym} ptr x _)) => (MTVSRD x)
-
-(FMOVDstore [off] {sym} ptr (MTVSRD x) mem) => (MOVDstore [off] {sym} ptr x mem)
-(MOVDstore [off] {sym} ptr (MFVSRD x) mem) => (FMOVDstore [off] {sym} ptr x mem)
-
-(MTVSRD (MOVDconst [c])) && !math.IsNaN(math.Float64frombits(uint64(c))) => (FMOVDconst [math.Float64frombits(uint64(c))])
-(MFVSRD (FMOVDconst [c])) => (MOVDconst [int64(math.Float64bits(c))])
-
-(MTVSRD x:(MOVDload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (FMOVDload [off] {sym} ptr mem)
-(MFVSRD x:(FMOVDload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVDload [off] {sym} ptr mem)
-
-// Fold offsets for stores.
-(MOVDstore [off1] {sym} (ADDconst [off2] x) val mem) && is16Bit(int64(off1)+off2) => (MOVDstore [off1+int32(off2)] {sym} x val mem)
-(MOVWstore [off1] {sym} (ADDconst [off2] x) val mem) && is16Bit(int64(off1)+off2) => (MOVWstore [off1+int32(off2)] {sym} x val mem)
-(MOVHstore [off1] {sym} (ADDconst [off2] x) val mem) && is16Bit(int64(off1)+off2) => (MOVHstore [off1+int32(off2)] {sym} x val mem)
-(MOVBstore [off1] {sym} (ADDconst [off2] x) val mem) && is16Bit(int64(off1)+off2) => (MOVBstore [off1+int32(off2)] {sym} x val mem)
-
-(FMOVSstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is16Bit(int64(off1)+off2) => (FMOVSstore [off1+int32(off2)] {sym} ptr val mem)
-(FMOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is16Bit(int64(off1)+off2) => (FMOVDstore [off1+int32(off2)] {sym} ptr val mem)
-
-// Fold address into load/store.
-// The assembler needs to generate several instructions and use
-// temp register for accessing global, and each time it will reload
-// the temp register. So don't fold address of global, unless there
-// is only one use.
-(MOVBstore [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2)
-	&& is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) =>
-        (MOVBstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
-(MOVHstore [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2)
-	&& is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) =>
-        (MOVHstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
-(MOVWstore [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2)
-	&& is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) =>
-        (MOVWstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
-(MOVDstore [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2)
-	&& is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) =>
-        (MOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
-
-(FMOVSstore [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2)
-	&& is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) =>
-        (FMOVSstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
-(FMOVDstore [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2)
-	&& is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) =>
-        (FMOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
-
-(MOVBZload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
-	&& is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) =>
-        (MOVBZload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-(MOVHload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
-	&& is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) =>
-        (MOVHload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-(MOVHZload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
-	&& is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) =>
-        (MOVHZload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-(MOVWload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
-	&& is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) =>
-        (MOVWload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-(MOVWZload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
-	&& is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) =>
-        (MOVWZload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-(MOVDload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
-	&& is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) =>
-        (MOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-(FMOVSload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
-	&& is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) =>
-        (FMOVSload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-(FMOVDload [off1] {sym1} p:(MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2)
-	&& is16Bit(int64(off1+off2)) && (ptr.Op != OpSB || p.Uses == 1) =>
-        (FMOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-
-// Fold offsets for loads.
-(FMOVSload [off1] {sym} (ADDconst [off2] ptr) mem) && is16Bit(int64(off1)+off2) => (FMOVSload [off1+int32(off2)] {sym} ptr mem)
-(FMOVDload [off1] {sym} (ADDconst [off2] ptr) mem) && is16Bit(int64(off1)+off2) => (FMOVDload [off1+int32(off2)] {sym} ptr mem)
-
-(MOVDload [off1] {sym} (ADDconst [off2] x) mem) && is16Bit(int64(off1)+off2) => (MOVDload [off1+int32(off2)] {sym} x mem)
-(MOVWload [off1] {sym} (ADDconst [off2] x) mem) && is16Bit(int64(off1)+off2) => (MOVWload [off1+int32(off2)] {sym} x mem)
-(MOVWZload [off1] {sym} (ADDconst [off2] x) mem) && is16Bit(int64(off1)+off2) => (MOVWZload [off1+int32(off2)] {sym} x mem)
-(MOVHload [off1] {sym} (ADDconst [off2] x) mem) && is16Bit(int64(off1)+off2) => (MOVHload [off1+int32(off2)] {sym} x mem)
-(MOVHZload [off1] {sym} (ADDconst [off2] x) mem) && is16Bit(int64(off1)+off2) => (MOVHZload [off1+int32(off2)] {sym} x mem)
-(MOVBZload [off1] {sym} (ADDconst [off2] x) mem) && is16Bit(int64(off1)+off2) => (MOVBZload [off1+int32(off2)] {sym} x mem)
-
-// Determine load + addressing that can be done as a register indexed load
-(MOV(D|W|WZ|H|HZ|BZ)load [0] {sym} p:(ADD ptr idx) mem) && sym == nil && p.Uses == 1 => (MOV(D|W|WZ|H|HZ|BZ)loadidx ptr idx mem)
-
-// Determine if there is benefit to using a non-indexed load, since that saves the load
-// of the index register. With MOVDload and MOVWload, there is no benefit if the offset
-// value is not a multiple of 4, since that results in an extra instruction in the base
-// register address computation.
-(MOV(D|W)loadidx ptr (MOVDconst [c]) mem) && is16Bit(c) && c%4 == 0 => (MOV(D|W)load [int32(c)] ptr mem)
-(MOV(WZ|H|HZ|BZ)loadidx ptr (MOVDconst [c]) mem) && is16Bit(c) => (MOV(WZ|H|HZ|BZ)load [int32(c)] ptr mem)
-(MOV(D|W)loadidx (MOVDconst [c]) ptr mem) && is16Bit(c) && c%4 == 0 => (MOV(D|W)load [int32(c)] ptr mem)
-(MOV(WZ|H|HZ|BZ)loadidx (MOVDconst [c]) ptr mem) && is16Bit(c) => (MOV(WZ|H|HZ|BZ)load [int32(c)] ptr mem)
-
-// Store of zero => storezero
-(MOVDstore [off] {sym} ptr (MOVDconst [0]) mem) => (MOVDstorezero [off] {sym} ptr mem)
-(MOVWstore [off] {sym} ptr (MOVDconst [0]) mem) => (MOVWstorezero [off] {sym} ptr mem)
-(MOVHstore [off] {sym} ptr (MOVDconst [0]) mem) => (MOVHstorezero [off] {sym} ptr mem)
-(MOVBstore [off] {sym} ptr (MOVDconst [0]) mem) => (MOVBstorezero [off] {sym} ptr mem)
-
-// Fold offsets for storezero
-(MOVDstorezero [off1] {sym} (ADDconst [off2] x) mem) && is16Bit(int64(off1)+off2) =>
-    (MOVDstorezero [off1+int32(off2)] {sym} x mem)
-(MOVWstorezero [off1] {sym} (ADDconst [off2] x) mem) && is16Bit(int64(off1)+off2) =>
-    (MOVWstorezero [off1+int32(off2)] {sym} x mem)
-(MOVHstorezero [off1] {sym} (ADDconst [off2] x) mem) && is16Bit(int64(off1)+off2) =>
-    (MOVHstorezero [off1+int32(off2)] {sym} x mem)
-(MOVBstorezero [off1] {sym} (ADDconst [off2] x) mem) && is16Bit(int64(off1)+off2) =>
-    (MOVBstorezero [off1+int32(off2)] {sym} x mem)
-
-// Stores with addressing that can be done as indexed stores
-(MOV(D|W|H|B)store [0] {sym} p:(ADD ptr idx) val mem) && sym == nil && p.Uses == 1 => (MOV(D|W|H|B)storeidx ptr idx val mem)
-
-// Stores with constant index values can be done without indexed instructions
-// No need to lower the idx cases if c%4 is not 0
-(MOVDstoreidx ptr (MOVDconst [c]) val mem) && is16Bit(c) && c%4 == 0 => (MOVDstore [int32(c)] ptr val mem)
-(MOV(W|H|B)storeidx ptr (MOVDconst [c]) val mem) && is16Bit(c) => (MOV(W|H|B)store [int32(c)] ptr val mem)
-(MOVDstoreidx (MOVDconst [c]) ptr val mem) && is16Bit(c) && c%4 == 0 => (MOVDstore [int32(c)] ptr val mem)
-(MOV(W|H|B)storeidx (MOVDconst [c]) ptr val mem) && is16Bit(c) => (MOV(W|H|B)store [int32(c)] ptr val mem)
-
-// Fold symbols into storezero
-(MOVDstorezero [off1] {sym1} p:(MOVDaddr [off2] {sym2} x) mem) && canMergeSym(sym1,sym2)
-	&& (x.Op != OpSB || p.Uses == 1) =>
-    (MOVDstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem)
-(MOVWstorezero [off1] {sym1} p:(MOVDaddr [off2] {sym2} x) mem) && canMergeSym(sym1,sym2)
-	&& (x.Op != OpSB || p.Uses == 1) =>
-    (MOVWstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem)
-(MOVHstorezero [off1] {sym1} p:(MOVDaddr [off2] {sym2} x) mem) && canMergeSym(sym1,sym2)
-	&& (x.Op != OpSB || p.Uses == 1) =>
-    (MOVHstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem)
-(MOVBstorezero [off1] {sym1} p:(MOVDaddr [off2] {sym2} x) mem) && canMergeSym(sym1,sym2)
-	&& (x.Op != OpSB || p.Uses == 1) =>
-    (MOVBstorezero [off1+off2] {mergeSym(sym1,sym2)} x mem)
-
-// atomic intrinsics
-(AtomicLoad(8|32|64|Ptr)  ptr mem) => (LoweredAtomicLoad(8|32|64|Ptr) [1] ptr mem)
-(AtomicLoadAcq(32|64)     ptr mem) => (LoweredAtomicLoad(32|64) [0] ptr mem)
-
-(AtomicStore(8|32|64)    ptr val mem) => (LoweredAtomicStore(8|32|64) [1] ptr val mem)
-(AtomicStoreRel(32|64)   ptr val mem) => (LoweredAtomicStore(32|64) [0] ptr val mem)
-//(AtomicStorePtrNoWB ptr val mem) => (STLR  ptr val mem)
-
-(AtomicExchange(32|64) ...) => (LoweredAtomicExchange(32|64) ...)
-
-(AtomicAdd(32|64) ...) => (LoweredAtomicAdd(32|64) ...)
-
-(AtomicCompareAndSwap(32|64) ptr old new_ mem) => (LoweredAtomicCas(32|64) [1] ptr old new_ mem)
-(AtomicCompareAndSwapRel32   ptr old new_ mem) => (LoweredAtomicCas32 [0] ptr old new_ mem)
-
-(AtomicAnd8  ...) => (LoweredAtomicAnd8  ...)
-(AtomicAnd32 ...) => (LoweredAtomicAnd32 ...)
-(AtomicOr8   ...) => (LoweredAtomicOr8   ...)
-(AtomicOr32  ...) => (LoweredAtomicOr32  ...)
-
-(Slicemask <t> x) => (SRADconst (NEG <t> x) [63])
-
-// Note that MOV??reg returns a 64-bit int, x is not necessarily that wide
-// This may interact with other patterns in the future. (Compare with arm64)
-(MOV(B|H|W)Zreg x:(MOVBZload _ _)) => x
-(MOV(B|H|W)Zreg x:(MOVBZloadidx _ _ _)) => x
-(MOV(H|W)Zreg x:(MOVHZload _ _)) => x
-(MOV(H|W)Zreg x:(MOVHZloadidx _ _ _)) => x
-(MOV(H|W)reg x:(MOVHload _ _)) => x
-(MOV(H|W)reg x:(MOVHloadidx _ _ _)) => x
-(MOVWZreg x:(MOVWZload _ _)) => x
-(MOVWZreg x:(MOVWZloadidx _ _ _)) => x
-(MOVWreg x:(MOVWload _ _)) => x
-(MOVWreg x:(MOVWloadidx _ _ _)) => x
-(MOVBZreg x:(Select0 (LoweredAtomicLoad8 _ _))) => x
-(MOVWZreg x:(Select0 (LoweredAtomicLoad32 _ _))) => x
-
-// don't extend if argument is already extended
-(MOVBreg x:(Arg <t>)) && is8BitInt(t) && isSigned(t) => x
-(MOVBZreg x:(Arg <t>)) && is8BitInt(t) && !isSigned(t) => x
-(MOVHreg x:(Arg <t>)) && (is8BitInt(t) || is16BitInt(t)) && isSigned(t) => x
-(MOVHZreg x:(Arg <t>)) && (is8BitInt(t) || is16BitInt(t)) && !isSigned(t) => x
-(MOVWreg x:(Arg <t>)) && (is8BitInt(t) || is16BitInt(t) || is32BitInt(t)) && isSigned(t) => x
-(MOVWZreg x:(Arg <t>)) && (is8BitInt(t) || is16BitInt(t) || is32BitInt(t)) && !isSigned(t) => x
-
-(MOVBZreg (MOVDconst [c]))  => (MOVDconst [int64(uint8(c))])
-(MOVBreg (MOVDconst [c]))  => (MOVDconst [int64(int8(c))])
-(MOVHZreg (MOVDconst [c]))  => (MOVDconst [int64(uint16(c))])
-(MOVHreg (MOVDconst [c]))  => (MOVDconst [int64(int16(c))])
-(MOVWreg (MOVDconst [c])) => (MOVDconst [int64(int32(c))])
-(MOVWZreg (MOVDconst [c])) => (MOVDconst [int64(uint32(c))])
-
-// Implement clrsldi and clrslwi extended mnemonics as described in
-// ISA 3.0 section C.8. AuxInt field contains values needed for
-// the instructions, packed together since there is only one available.
-(SLDconst [c] z:(MOVBZreg x)) && c < 8 && z.Uses == 1 => (CLRLSLDI [newPPC64ShiftAuxInt(c,56,63,64)] x)
-(SLDconst [c] z:(MOVHZreg x)) && c < 16 && z.Uses == 1 => (CLRLSLDI [newPPC64ShiftAuxInt(c,48,63,64)] x)
-(SLDconst [c] z:(MOVWZreg x)) && c < 32 && z.Uses == 1 => (CLRLSLDI [newPPC64ShiftAuxInt(c,32,63,64)] x)
-
-(SLDconst [c] z:(ANDconst [d] x)) && z.Uses == 1 && isPPC64ValidShiftMask(d) && c <= (64-getPPC64ShiftMaskLength(d)) => (CLRLSLDI [newPPC64ShiftAuxInt(c,64-getPPC64ShiftMaskLength(d),63,64)] x)
-(SLDconst [c] z:(AND (MOVDconst [d]) x)) && z.Uses == 1 && isPPC64ValidShiftMask(d) && c<=(64-getPPC64ShiftMaskLength(d)) => (CLRLSLDI [newPPC64ShiftAuxInt(c,64-getPPC64ShiftMaskLength(d),63,64)] x)
-(SLWconst [c] z:(MOVBZreg x)) && z.Uses == 1 && c < 8 => (CLRLSLWI [newPPC64ShiftAuxInt(c,24,31,32)] x)
-(SLWconst [c] z:(MOVHZreg x)) && z.Uses == 1 && c < 16 => (CLRLSLWI [newPPC64ShiftAuxInt(c,16,31,32)] x)
-(SLWconst [c] z:(ANDconst [d] x)) && z.Uses == 1 && isPPC64ValidShiftMask(d) && c<=(32-getPPC64ShiftMaskLength(d)) => (CLRLSLWI [newPPC64ShiftAuxInt(c,32-getPPC64ShiftMaskLength(d),31,32)] x)
-(SLWconst [c] z:(AND (MOVDconst [d]) x)) && z.Uses == 1 && isPPC64ValidShiftMask(d) && c<=(32-getPPC64ShiftMaskLength(d)) => (CLRLSLWI [newPPC64ShiftAuxInt(c,32-getPPC64ShiftMaskLength(d),31,32)] x)
-// special case for power9
-(SL(W|D)const [c] z:(MOVWreg x)) && c < 32 && buildcfg.GOPPC64 >= 9 => (EXTSWSLconst [c] x)
-
-// Lose widening ops fed to stores
-(MOVBstore [off] {sym} ptr (MOV(B|BZ|H|HZ|W|WZ)reg x) mem) => (MOVBstore [off] {sym} ptr x mem)
-(MOVHstore [off] {sym} ptr (MOV(H|HZ|W|WZ)reg x) mem) => (MOVHstore [off] {sym} ptr x mem)
-(MOVWstore [off] {sym} ptr (MOV(W|WZ)reg x) mem) => (MOVWstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr (SRWconst (MOV(H|HZ)reg x) [c]) mem) && c <= 8 => (MOVBstore [off] {sym} ptr (SRWconst <typ.UInt32> x [c]) mem)
-(MOVBstore [off] {sym} ptr (SRWconst (MOV(W|WZ)reg x) [c]) mem) && c <= 24 => (MOVBstore [off] {sym} ptr (SRWconst <typ.UInt32> x [c]) mem)
-(MOVBstoreidx ptr idx (MOV(B|BZ|H|HZ|W|WZ)reg x) mem) => (MOVBstoreidx ptr idx x mem)
-(MOVHstoreidx ptr idx (MOV(H|HZ|W|WZ)reg x) mem) => (MOVHstoreidx ptr idx x mem)
-(MOVWstoreidx ptr idx (MOV(W|WZ)reg x) mem) => (MOVWstoreidx ptr idx x mem)
-(MOVBstoreidx ptr idx (SRWconst (MOV(H|HZ)reg x) [c]) mem) && c <= 8 => (MOVBstoreidx ptr idx (SRWconst <typ.UInt32> x [c]) mem)
-(MOVBstoreidx ptr idx (SRWconst (MOV(W|WZ)reg x) [c]) mem) && c <= 24 => (MOVBstoreidx ptr idx (SRWconst <typ.UInt32> x [c]) mem)
-(MOVHBRstore {sym} ptr (MOV(H|HZ|W|WZ)reg x) mem) => (MOVHBRstore {sym} ptr x mem)
-(MOVWBRstore {sym} ptr (MOV(W|WZ)reg x) mem) => (MOVWBRstore {sym} ptr x mem)
-
-// Lose W-widening ops fed to compare-W
-(CMPW x (MOVWreg y)) => (CMPW x y)
-(CMPW (MOVWreg x) y) => (CMPW x y)
-(CMPWU x (MOVWZreg y)) => (CMPWU x y)
-(CMPWU (MOVWZreg x) y) => (CMPWU x y)
-
-(CMP x (MOVDconst [c])) && is16Bit(c) => (CMPconst x [c])
-(CMP (MOVDconst [c]) y) && is16Bit(c) => (InvertFlags (CMPconst y [c]))
-(CMPW x (MOVDconst [c])) && is16Bit(c) => (CMPWconst x [int32(c)])
-(CMPW (MOVDconst [c]) y) && is16Bit(c) => (InvertFlags (CMPWconst y [int32(c)]))
-
-(CMPU x (MOVDconst [c])) && isU16Bit(c) => (CMPUconst x [c])
-(CMPU (MOVDconst [c]) y) && isU16Bit(c) => (InvertFlags (CMPUconst y [c]))
-(CMPWU x (MOVDconst [c])) && isU16Bit(c) => (CMPWUconst x [int32(c)])
-(CMPWU (MOVDconst [c]) y) && isU16Bit(c) => (InvertFlags (CMPWUconst y [int32(c)]))
-
-// Canonicalize the order of arguments to comparisons - helps with CSE.
-((CMP|CMPW|CMPU|CMPWU) x y) && canonLessThan(x,y) => (InvertFlags ((CMP|CMPW|CMPU|CMPWU) y x))
-
-// ISEL auxInt values 0=LT 1=GT 2=EQ   arg2 ? arg0 : arg1
-// ISEL auxInt values 4=GE 5=LE 6=NE   !arg2 ? arg1 : arg0
-// ISELB special case where arg0, arg1 values are 0, 1
-
-(Equal cmp) => (ISELB [2] (MOVDconst [1]) cmp)
-(NotEqual cmp) => (ISELB [6] (MOVDconst [1]) cmp)
-(LessThan cmp) => (ISELB [0] (MOVDconst [1]) cmp)
-(FLessThan cmp) => (ISELB [0] (MOVDconst [1]) cmp)
-(FLessEqual cmp) => (ISEL [2] (MOVDconst [1]) (ISELB [0] (MOVDconst [1]) cmp) cmp)
-(GreaterEqual cmp) => (ISELB [4] (MOVDconst [1]) cmp)
-(GreaterThan cmp) => (ISELB [1] (MOVDconst [1]) cmp)
-(FGreaterThan cmp) => (ISELB [1] (MOVDconst [1]) cmp)
-(FGreaterEqual cmp) => (ISEL [2] (MOVDconst [1]) (ISELB [1] (MOVDconst [1]) cmp) cmp)
-(LessEqual cmp) => (ISELB [5] (MOVDconst [1]) cmp)
-
-(ISELB [0] _ (FlagLT)) => (MOVDconst [1])
-(ISELB [0] _ (Flag(GT|EQ))) => (MOVDconst [0])
-(ISELB [1] _ (FlagGT)) => (MOVDconst [1])
-(ISELB [1] _ (Flag(LT|EQ))) => (MOVDconst [0])
-(ISELB [2] _ (FlagEQ)) => (MOVDconst [1])
-(ISELB [2] _ (Flag(LT|GT))) => (MOVDconst [0])
-(ISELB [4] _ (FlagLT)) => (MOVDconst [0])
-(ISELB [4] _ (Flag(GT|EQ))) => (MOVDconst [1])
-(ISELB [5] _ (FlagGT)) => (MOVDconst [0])
-(ISELB [5] _ (Flag(LT|EQ))) => (MOVDconst [1])
-(ISELB [6] _ (FlagEQ)) => (MOVDconst [0])
-(ISELB [6] _ (Flag(LT|GT))) => (MOVDconst [1])
-
-(ISEL [2] x _ (FlagEQ)) => x
-(ISEL [2] _ y (Flag(LT|GT))) => y
-
-(ISEL [6] _ y (FlagEQ)) => y
-(ISEL [6] x _ (Flag(LT|GT))) => x
-
-(ISEL [0] _ y (Flag(EQ|GT))) => y
-(ISEL [0] x _ (FlagLT)) => x
-
-(ISEL [5] _ x (Flag(EQ|LT))) => x
-(ISEL [5] y _ (FlagGT)) => y
-
-(ISEL [1] _ y (Flag(EQ|LT))) => y
-(ISEL [1] x _ (FlagGT)) => x
-
-(ISEL [4] x _ (Flag(EQ|GT))) => x
-(ISEL [4] _ y (FlagLT)) => y
-
-(ISELB [n] (MOVDconst [1]) (InvertFlags bool)) && n%4 == 0 => (ISELB [n+1] (MOVDconst [1]) bool)
-(ISELB [n] (MOVDconst [1]) (InvertFlags bool)) && n%4 == 1 => (ISELB [n-1] (MOVDconst [1]) bool)
-(ISELB [n] (MOVDconst [1]) (InvertFlags bool)) && n%4 == 2 => (ISELB [n] (MOVDconst [1]) bool)
-(ISEL [n] x y (InvertFlags bool)) && n%4 == 0 => (ISEL [n+1] x y bool)
-(ISEL [n] x y (InvertFlags bool)) && n%4 == 1 => (ISEL [n-1] x y bool)
-(ISEL [n] x y (InvertFlags bool)) && n%4 == 2 => (ISEL [n] x y bool)
-(XORconst [1] (ISELB [6] (MOVDconst [1]) cmp)) => (ISELB [2] (MOVDconst [1]) cmp)
-(XORconst [1] (ISELB [5] (MOVDconst [1]) cmp)) => (ISELB [1] (MOVDconst [1]) cmp)
-(XORconst [1] (ISELB [4] (MOVDconst [1]) cmp)) => (ISELB [0] (MOVDconst [1]) cmp)
-
-// A particular pattern seen in cgo code:
-(AND (MOVDconst [c]) x:(MOVBZload _ _)) => (ANDconst [c&0xFF] x)
-
-// floating point negative abs
-(FNEG (FABS x)) => (FNABS x)
-(FNEG (FNABS x)) => (FABS x)
-
-// floating-point fused multiply-add/sub
-(FADD (FMUL x y) z) => (FMADD x y z)
-(FSUB (FMUL x y) z) => (FMSUB x y z)
-(FADDS (FMULS x y) z) => (FMADDS x y z)
-(FSUBS (FMULS x y) z) => (FMSUBS x y z)
-
-
-// The following statements are found in encoding/binary functions UintXX (load) and PutUintXX (store)
-// and convert the statements in these functions from multiple single byte loads or stores to
-// the single largest possible load or store.
-// Some are marked big or little endian based on the order in which the bytes are loaded or stored,
-// not on the ordering of the machine. These are intended for little endian machines.
-// To implement for big endian machines, most rules would have to be duplicated but the
-// resulting rule would be reversed, i. e., MOVHZload on little endian would be MOVHBRload on big endian
-// and vice versa.
-// b[0] | b[1]<<8 => load 16-bit Little endian
-(OR <t> x0:(MOVBZload [i0] {s} p mem)
-	o1:(SL(W|D)const x1:(MOVBZload [i1] {s} p mem) [8]))
-	&& !config.BigEndian
-	&& i1 == i0+1
-	&& x0.Uses ==1 && x1.Uses == 1
-	&& o1.Uses == 1
-	&& mergePoint(b, x0, x1) != nil
-	&& clobber(x0, x1, o1)
-	 => @mergePoint(b,x0,x1) (MOVHZload <t> {s} [i0] p mem)
-
-// b[0]<<8 | b[1] => load 16-bit Big endian on Little endian arch.
-// Use byte-reverse indexed load for 2 bytes.
-(OR <t> x0:(MOVBZload [i1] {s} p mem)
-	o1:(SL(W|D)const x1:(MOVBZload [i0] {s} p mem) [8]))
-	&& !config.BigEndian
-	&& i1 == i0+1
-	&& x0.Uses ==1 && x1.Uses == 1
-	&& o1.Uses == 1
-	&& mergePoint(b, x0, x1) != nil
-	&& clobber(x0, x1, o1)
-	  => @mergePoint(b,x0,x1) (MOVHBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem)
-
-// b[0]<<n+8 | b[1]<<n => load 16-bit Big endian (where n%8== 0)
-// Use byte-reverse indexed load for 2 bytes,
-// then shift left to the correct position. Used to match subrules
-// from longer rules.
-(OR <t> s0:(SL(W|D)const x0:(MOVBZload [i1] {s} p mem) [n1])
-	s1:(SL(W|D)const x1:(MOVBZload [i0] {s} p mem) [n2]))
-	&& !config.BigEndian
-	&& i1 == i0+1
-	&& n1%8 == 0
-	&& n2 == n1+8
-	&& x0.Uses == 1 && x1.Uses == 1
-	&& s0.Uses == 1 && s1.Uses == 1
-	&& mergePoint(b, x0, x1) != nil
-	&& clobber(x0, x1, s0, s1)
-	  => @mergePoint(b,x0,x1) (SLDconst <t> (MOVHBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem) [n1])
-
-// b[0] | b[1]<<8 | b[2]<<16 | b[3]<<24 => load 32-bit Little endian
-// Use byte-reverse indexed load for 4 bytes.
-(OR <t> s1:(SL(W|D)const x2:(MOVBZload [i3] {s} p mem) [24])
-	o0:(OR <t> s0:(SL(W|D)const x1:(MOVBZload [i2] {s} p mem) [16])
-	x0:(MOVHZload [i0] {s} p mem)))
-	&& !config.BigEndian
-	&& i2 == i0+2
-	&& i3 == i0+3
-	&& x0.Uses ==1 && x1.Uses == 1 && x2.Uses == 1
-	&& o0.Uses == 1
-	&& s0.Uses == 1 && s1.Uses == 1
-	&& mergePoint(b, x0, x1, x2) != nil
-	&& clobber(x0, x1, x2, s0, s1, o0)
-	 => @mergePoint(b,x0,x1,x2) (MOVWZload <t> {s} [i0] p mem)
-
-// b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3] => load 32-bit Big endian order on Little endian arch
-// Use byte-reverse indexed load for 4 bytes with computed address.
-// Could be used to match subrules of a longer rule.
-(OR <t> s1:(SL(W|D)const x2:(MOVBZload [i0] {s} p mem) [24])
-	o0:(OR <t> s0:(SL(W|D)const x1:(MOVBZload [i1] {s} p mem) [16])
-	x0:(MOVHBRload <t> (MOVDaddr <typ.Uintptr> [i2] {s} p) mem)))
-	&& !config.BigEndian
-	&& i1 == i0+1
-	&& i2 == i0+2
-	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1
-	&& o0.Uses == 1
-	&& s0.Uses == 1 && s1.Uses == 1
-	&& mergePoint(b, x0, x1, x2) != nil
-	&& clobber(x0, x1, x2, s0, s1, o0)
-	  => @mergePoint(b,x0,x1,x2) (MOVWBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem)
-
-// b[3] | b[2]<<8 | b[1]<<16 | b[0]<<24 => load 32-bit Big endian order on Little endian arch
-// Use byte-reverse indexed load for 4 bytes with computed address.
-// Could be used to match subrules of a longer rule.
-(OR <t> x0:(MOVBZload [i3] {s} p mem)
-	o0:(OR <t> s0:(SL(W|D)const x1:(MOVBZload [i2] {s} p mem) [8])
-	s1:(SL(W|D)const x2:(MOVHBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem) [16])))
-	&& !config.BigEndian
-	&& i2 == i0+2
-	&& i3 == i0+3
-	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1
-	&& o0.Uses == 1
-	&& s0.Uses == 1 && s1.Uses == 1
-	&& mergePoint(b, x0, x1, x2) != nil
-	&& clobber(x0, x1, x2, s0, s1, o0)
-	  => @mergePoint(b,x0,x1,x2) (MOVWBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem)
-
-// b[0]<<56 | b[1]<<48 | b[2]<<40 | b[3]<<32 => load 32-bit Big endian order on Little endian arch
-// Use byte-reverse indexed load to for 4 bytes with computed address.
-// Used to match longer rules.
-(OR <t> s2:(SLDconst x2:(MOVBZload [i3] {s} p mem) [32])
-	o0:(OR <t> s1:(SLDconst x1:(MOVBZload [i2] {s} p mem) [40])
-	s0:(SLDconst x0:(MOVHBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem) [48])))
-	&& !config.BigEndian
-	&& i2 == i0+2
-	&& i3 == i0+3
-	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1
-	&& o0.Uses == 1
-	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1
-	&& mergePoint(b, x0, x1, x2) != nil
-	&& clobber(x0, x1, x2, s0, s1, s2, o0)
-	  => @mergePoint(b,x0,x1,x2) (SLDconst <t> (MOVWBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem) [32])
-
-// b[3]<<32 | b[2]<<40 | b[1]<<48 | b[0]<<56 => load 32-bit Big endian order on Little endian arch
-// Use byte-reverse indexed load for 4 bytes with constant address.
-// Used to match longer rules.
-(OR <t> s2:(SLDconst x2:(MOVBZload [i0] {s} p mem) [56])
-        o0:(OR <t> s1:(SLDconst x1:(MOVBZload [i1] {s} p mem) [48])
-        s0:(SLDconst x0:(MOVHBRload <t> (MOVDaddr <typ.Uintptr> [i2] {s} p) mem) [32])))
-        && !config.BigEndian
-        && i1 == i0+1
-        && i2 == i0+2
-        && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1
-        && o0.Uses == 1
-        && s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1
-        && mergePoint(b, x0, x1, x2) != nil
-        && clobber(x0, x1, x2, s0, s1, s2, o0)
-          => @mergePoint(b,x0,x1,x2) (SLDconst <t> (MOVWBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem) [32])
-
-// b[0] | b[1]<<8 | b[2]<<16 | b[3]<<24 | b[4] <<32 | b[5]<<40 | b[6]<<48 | b[7]<<56 => load 64-bit Little endian
-// Rules with commutative ops and many operands will result in extremely large functions in rewritePPC64,
-// so matching shorter previously defined subrules is important.
-// Offset must be multiple of 4 for MOVD
-(OR <t> s6:(SLDconst x7:(MOVBZload [i7] {s} p mem) [56])
-	o5:(OR <t> s5:(SLDconst x6:(MOVBZload [i6] {s} p mem) [48])
-	o4:(OR <t> s4:(SLDconst x5:(MOVBZload [i5] {s} p mem) [40])
-	o3:(OR <t> s3:(SLDconst x4:(MOVBZload [i4] {s} p mem) [32])
-	x0:(MOVWZload {s} [i0] p mem)))))
-	&& !config.BigEndian
-	&& i4 == i0+4
-	&& i5 == i0+5
-	&& i6 == i0+6
-	&& i7 == i0+7
-	&& x0.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses ==1 && x7.Uses == 1
-	&& o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1
-	&& s3.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1
-	&& mergePoint(b, x0, x4, x5, x6, x7) != nil
-	&& clobber(x0, x4, x5, x6, x7, s3, s4, s5, s6, o3, o4, o5)
-	  => @mergePoint(b,x0,x4,x5,x6,x7) (MOVDload <t> {s} [i0] p mem)
-
-// b[7] | b[6]<<8 | b[5]<<16 | b[4]<<24 | b[3]<<32 | b[2]<<40 | b[1]<<48 | b[0]<<56 load 64-bit Big endian ordered bytes on Little endian arch
-// Use byte-reverse indexed load of 8 bytes.
-// Rules with commutative ops and many operands can result in extremely large functions in rewritePPC64,
-// so matching shorter previously defined subrules is important.
-(OR <t> s0:(SLDconst x0:(MOVBZload [i0] {s} p mem) [56])
-	o0:(OR <t> s1:(SLDconst x1:(MOVBZload [i1] {s} p mem) [48])
-	o1:(OR <t> s2:(SLDconst x2:(MOVBZload [i2] {s} p mem) [40])
-	o2:(OR <t> s3:(SLDconst x3:(MOVBZload [i3] {s} p mem) [32])
-	x4:(MOVWBRload <t> (MOVDaddr <typ.Uintptr> [i4] p) mem)))))
-	&& !config.BigEndian
-	&& i1 == i0+1
-	&& i2 == i0+2
-	&& i3 == i0+3
-	&& i4 == i0+4
-	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1
-	&& o0.Uses == 1 && o1.Uses == 1 && o2.Uses == 1
-	&& s0.Uses == 1 && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1
-	&& mergePoint(b, x0, x1, x2, x3, x4) != nil
-	&& clobber(x0, x1, x2, x3, x4, o0, o1, o2, s0, s1, s2, s3)
-	  => @mergePoint(b,x0,x1,x2,x3,x4) (MOVDBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem)
-
-// b[0]<<56 | b[1]<<48 | b[2]<<40 | b[3]<<32 | b[4]<<24 | b[5]<<16 | b[6]<<8 | b[7] => load 64-bit Big endian ordered bytes on Little endian arch
-// Use byte-reverse indexed load of 8 bytes.
-// Rules with commutative ops and many operands can result in extremely large functions in rewritePPC64,
-// so matching shorter previously defined subrules is important.
-(OR <t> x7:(MOVBZload [i7] {s} p mem)
-	o5:(OR <t> s6:(SLDconst x6:(MOVBZload [i6] {s} p mem) [8])
-	o4:(OR <t> s5:(SLDconst x5:(MOVBZload [i5] {s} p mem) [16])
-	o3:(OR <t> s4:(SLDconst x4:(MOVBZload [i4] {s} p mem) [24])
-	s0:(SL(W|D)const x3:(MOVWBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem) [32])))))
-	&& !config.BigEndian
-	&& i4 == i0+4
-	&& i5 == i0+5
-	&& i6 == i0+6
-	&& i7 == i0+7
-	&& x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1 && x7.Uses == 1
-	&& o3.Uses == 1 && o4.Uses == 1 && o5.Uses == 1
-	&& s0.Uses == 1 && s4.Uses == 1 && s5.Uses == 1 && s6.Uses == 1
-	&& mergePoint(b, x3, x4, x5, x6, x7) != nil
-	&& clobber(x3, x4, x5, x6, x7, o3, o4, o5, s0, s4, s5, s6)
-	=> @mergePoint(b,x3,x4,x5,x6,x7) (MOVDBRload <t> (MOVDaddr <typ.Uintptr> [i0] {s} p) mem)
-
-// 2 byte store Little endian as in:
-//      b[0] = byte(v >> 16)
-//      b[1] = byte(v >> 24)
-// Added for use in matching longer rules.
-(MOVBstore [i1] {s} p (SR(W|D)const w [24])
-        x0:(MOVBstore [i0] {s} p (SR(W|D)const w [16]) mem))
-        && !config.BigEndian
-        && x0.Uses == 1
-        && i1 == i0+1
-        && clobber(x0)
-          => (MOVHstore [i0] {s} p (SRWconst <typ.UInt16> w [16]) mem)
-
-// 2 byte store Little endian as in:
-//      b[0] = byte(v)
-//      b[1] = byte(v >> 8)
-(MOVBstore [i1] {s} p (SR(W|D)const w [8])
-	x0:(MOVBstore [i0] {s} p w mem))
-	&& !config.BigEndian
-	&& x0.Uses == 1
-	&& i1 == i0+1
-	&& clobber(x0)
-	  => (MOVHstore [i0] {s} p w mem)
-
-// 4 byte store Little endian as in:
-//     b[0:1] = uint16(v)
-//     b[2:3] = uint16(v >> 16)
-(MOVHstore [i1] {s} p (SR(W|D)const w [16])
-	x0:(MOVHstore [i0] {s} p w mem))
-	&& !config.BigEndian
-	&& x0.Uses == 1
-	&& i1 == i0+2
-	&& clobber(x0)
-	  => (MOVWstore [i0] {s} p w mem)
-
-// 4 byte store Big endian as in:
-//     b[0] = byte(v >> 24)
-//     b[1] = byte(v >> 16)
-//     b[2] = byte(v >> 8)
-//     b[3] = byte(v)
-// Use byte-reverse indexed 4 byte store.
-(MOVBstore [i3] {s} p w
-	x0:(MOVBstore [i2] {s} p (SRWconst w [8])
-	x1:(MOVBstore [i1] {s} p (SRWconst w [16])
-	x2:(MOVBstore [i0] {s} p (SRWconst w [24]) mem))))
-	&& !config.BigEndian
-	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1
-	&& i1 == i0+1 && i2 == i0+2 && i3 == i0+3
-	&& clobber(x0, x1, x2)
-	  => (MOVWBRstore (MOVDaddr <typ.Uintptr> [i0] {s} p) w mem)
-
-// The 2 byte store appears after the 4 byte store so that the
-// match for the 2 byte store is not done first.
-// If the 4 byte store is based on the 2 byte store then there are
-// variations on the MOVDaddr subrule that would require additional
-// rules to be written.
-
-// 2 byte store Big endian as in:
-//      b[0] = byte(v >> 8)
-//      b[1] = byte(v)
-(MOVBstore [i1] {s} p w x0:(MOVBstore [i0] {s} p (SRWconst w [8]) mem))
-	&& !config.BigEndian
-	&& x0.Uses == 1
-	&& i1 == i0+1
-	&& clobber(x0)
-	  => (MOVHBRstore (MOVDaddr <typ.Uintptr> [i0] {s} p) w mem)
-
-// 8 byte store Little endian as in:
-//	b[0] = byte(v)
-//	b[1] = byte(v >> 8)
-//	b[2] = byte(v >> 16)
-//	b[3] = byte(v >> 24)
-//	b[4] = byte(v >> 32)
-//	b[5] = byte(v >> 40)
-//	b[6] = byte(v >> 48)
-//	b[7] = byte(v >> 56)
-// Built on previously defined rules
-// Offset must be multiple of 4 for MOVDstore
-(MOVBstore [i7] {s} p (SRDconst w [56])
-	x0:(MOVBstore [i6] {s} p (SRDconst w [48])
-	x1:(MOVBstore [i5] {s} p (SRDconst w [40])
-	x2:(MOVBstore [i4] {s} p (SRDconst w [32])
-	x3:(MOVWstore [i0] {s} p w mem)))))
-	&& !config.BigEndian
-	&& x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1
-	&& i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7
-	&& clobber(x0, x1, x2, x3)
-	  => (MOVDstore [i0] {s} p w mem)
-
-// 8 byte store Big endian as in:
-//      b[0] = byte(v >> 56)
-//      b[1] = byte(v >> 48)
-//      b[2] = byte(v >> 40)
-//      b[3] = byte(v >> 32)
-//      b[4] = byte(v >> 24)
-//      b[5] = byte(v >> 16)
-//      b[6] = byte(v >> 8)
-//      b[7] = byte(v)
-// Use byte-reverse indexed 8 byte store.
-(MOVBstore [i7] {s} p w
-        x0:(MOVBstore [i6] {s} p (SRDconst w [8])
-        x1:(MOVBstore [i5] {s} p (SRDconst w [16])
-        x2:(MOVBstore [i4] {s} p (SRDconst w [24])
-        x3:(MOVBstore [i3] {s} p (SRDconst w [32])
-        x4:(MOVBstore [i2] {s} p (SRDconst w [40])
-        x5:(MOVBstore [i1] {s} p (SRDconst w [48])
-        x6:(MOVBstore [i0] {s} p (SRDconst w [56]) mem))))))))
-        && !config.BigEndian
-        && x0.Uses == 1 && x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && x4.Uses == 1 && x5.Uses == 1 && x6.Uses == 1
-        && i1 == i0+1 && i2 == i0+2 && i3 == i0+3 && i4 == i0+4 && i5 == i0+5 && i6 == i0+6 && i7 == i0+7
-        && clobber(x0, x1, x2, x3, x4, x5, x6)
-          => (MOVDBRstore (MOVDaddr <typ.Uintptr> [i0] {s} p) w mem)
-
-// Arch-specific inlining for small or disjoint runtime.memmove
-(SelectN [0] call:(CALLstatic {sym} s1:(MOVDstore _ (MOVDconst [sz]) s2:(MOVDstore  _ src s3:(MOVDstore {t} _ dst mem)))))
-        && sz >= 0
-        && isSameCall(sym, "runtime.memmove")
-        && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1
-        && isInlinableMemmove(dst, src, sz, config)
-        && clobber(s1, s2, s3, call)
-        => (Move [sz] dst src mem)
-
-// Match post-lowering calls, register version.
-(SelectN [0] call:(CALLstatic {sym} dst src (MOVDconst [sz]) mem))
-        && sz >= 0
-        && isSameCall(sym, "runtime.memmove")
-        && call.Uses == 1
-        && isInlinableMemmove(dst, src, sz, config)
-        && clobber(call)
-        => (Move [sz] dst src mem)
-
-// Prefetch instructions (TH specified using aux field)
-// For DCBT Ra,Rb,TH, A value of TH indicates:
-//     0, hint this cache line will be used soon. (PrefetchCache)
-//     16, hint this cache line will not be used for long. (PrefetchCacheStreamed)
-// See ISA 3.0 Book II 4.3.2 for more detail. https://openpower.foundation/specifications/isa/
-(PrefetchCache ptr mem)          => (DCBT ptr mem [0])
-(PrefetchCacheStreamed ptr mem)  => (DCBT ptr mem [16])
-
diff --git a/src/cmd/compile/internal/ssa/gen/PPC64Ops.go b/src/cmd/compile/internal/ssa/gen/PPC64Ops.go
deleted file mode 100644
index a4d906d..0000000
--- a/src/cmd/compile/internal/ssa/gen/PPC64Ops.go
+++ /dev/null
@@ -1,743 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build ignore
-// +build ignore
-
-package main
-
-import "strings"
-
-// Notes:
-//  - Less-than-64-bit integer types live in the low portion of registers.
-//    For now, the upper portion is junk; sign/zero-extension might be optimized in the future, but not yet.
-//  - Boolean types are zero or 1; stored in a byte, but loaded with AMOVBZ so the upper bytes of a register are zero.
-//  - *const instructions may use a constant larger than the instruction can encode.
-//    In this case the assembler expands to multiple instructions and uses tmp
-//    register (R31).
-
-var regNamesPPC64 = []string{
-	"R0", // REGZERO, not used, but simplifies counting in regalloc
-	"SP", // REGSP
-	"SB", // REGSB
-	"R3",
-	"R4",
-	"R5",
-	"R6",
-	"R7",
-	"R8",
-	"R9",
-	"R10",
-	"R11", // REGCTXT for closures
-	"R12",
-	"R13", // REGTLS
-	"R14",
-	"R15",
-	"R16",
-	"R17",
-	"R18",
-	"R19",
-	"R20",
-	"R21",
-	"R22",
-	"R23",
-	"R24",
-	"R25",
-	"R26",
-	"R27",
-	"R28",
-	"R29",
-	"g",   // REGG.  Using name "g" and setting Config.hasGReg makes it "just happen".
-	"R31", // REGTMP
-
-	"F0",
-	"F1",
-	"F2",
-	"F3",
-	"F4",
-	"F5",
-	"F6",
-	"F7",
-	"F8",
-	"F9",
-	"F10",
-	"F11",
-	"F12",
-	"F13",
-	"F14",
-	"F15",
-	"F16",
-	"F17",
-	"F18",
-	"F19",
-	"F20",
-	"F21",
-	"F22",
-	"F23",
-	"F24",
-	"F25",
-	"F26",
-	"F27",
-	"F28",
-	"F29",
-	"F30",
-	// "F31", the allocator is limited to 64 entries. We sacrifice this FPR to support XER.
-
-	"XER",
-
-	// If you add registers, update asyncPreempt in runtime.
-
-	// "CR0",
-	// "CR1",
-	// "CR2",
-	// "CR3",
-	// "CR4",
-	// "CR5",
-	// "CR6",
-	// "CR7",
-
-	// "CR",
-	// "LR",
-	// "CTR",
-}
-
-func init() {
-	// Make map from reg names to reg integers.
-	if len(regNamesPPC64) > 64 {
-		panic("too many registers")
-	}
-	num := map[string]int{}
-	for i, name := range regNamesPPC64 {
-		num[name] = i
-	}
-	buildReg := func(s string) regMask {
-		m := regMask(0)
-		for _, r := range strings.Split(s, " ") {
-			if n, ok := num[r]; ok {
-				m |= regMask(1) << uint(n)
-				continue
-			}
-			panic("register " + r + " not found")
-		}
-		return m
-	}
-
-	var (
-		gp  = buildReg("R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29")
-		fp  = buildReg("F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30")
-		sp  = buildReg("SP")
-		sb  = buildReg("SB")
-		gr  = buildReg("g")
-		xer = buildReg("XER")
-		// cr  = buildReg("CR")
-		// ctr = buildReg("CTR")
-		// lr  = buildReg("LR")
-		tmp     = buildReg("R31")
-		ctxt    = buildReg("R11")
-		callptr = buildReg("R12")
-		// tls = buildReg("R13")
-		gp01        = regInfo{inputs: nil, outputs: []regMask{gp}}
-		gp11        = regInfo{inputs: []regMask{gp | sp | sb}, outputs: []regMask{gp}}
-		xergp       = regInfo{inputs: []regMask{xer}, outputs: []regMask{gp}, clobbers: xer}
-		gp11cxer    = regInfo{inputs: []regMask{gp | sp | sb}, outputs: []regMask{gp}, clobbers: xer}
-		gp11xer     = regInfo{inputs: []regMask{gp | sp | sb}, outputs: []regMask{gp, xer}}
-		gp21        = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb}, outputs: []regMask{gp}}
-		gp21a0      = regInfo{inputs: []regMask{gp, gp | sp | sb}, outputs: []regMask{gp}}
-		gp21cxer    = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb}, outputs: []regMask{gp}, clobbers: xer}
-		gp21xer     = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb}, outputs: []regMask{gp, xer}, clobbers: xer}
-		gp2xer1xer  = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb, xer}, outputs: []regMask{gp, xer}, clobbers: xer}
-		gp31        = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb, gp | sp | sb}, outputs: []regMask{gp}}
-		gp22        = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb}, outputs: []regMask{gp, gp}}
-		gp1cr       = regInfo{inputs: []regMask{gp | sp | sb}}
-		gp2cr       = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb}}
-		crgp        = regInfo{inputs: nil, outputs: []regMask{gp}}
-		crgp11      = regInfo{inputs: []regMask{gp}, outputs: []regMask{gp}}
-		crgp21      = regInfo{inputs: []regMask{gp, gp}, outputs: []regMask{gp}}
-		gpload      = regInfo{inputs: []regMask{gp | sp | sb}, outputs: []regMask{gp}}
-		gploadidx   = regInfo{inputs: []regMask{gp | sp | sb, gp}, outputs: []regMask{gp}}
-		prefreg     = regInfo{inputs: []regMask{gp | sp | sb}}
-		gpstore     = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb}}
-		gpstoreidx  = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb, gp | sp | sb}}
-		gpstorezero = regInfo{inputs: []regMask{gp | sp | sb}} // ppc64.REGZERO is reserved zero value
-		gpxchg      = regInfo{inputs: []regMask{gp | sp | sb, gp}, outputs: []regMask{gp}}
-		gpcas       = regInfo{inputs: []regMask{gp | sp | sb, gp, gp}, outputs: []regMask{gp}}
-		fp01        = regInfo{inputs: nil, outputs: []regMask{fp}}
-		fp11        = regInfo{inputs: []regMask{fp}, outputs: []regMask{fp}}
-		fpgp        = regInfo{inputs: []regMask{fp}, outputs: []regMask{gp}}
-		gpfp        = regInfo{inputs: []regMask{gp}, outputs: []regMask{fp}}
-		fp21        = regInfo{inputs: []regMask{fp, fp}, outputs: []regMask{fp}}
-		fp31        = regInfo{inputs: []regMask{fp, fp, fp}, outputs: []regMask{fp}}
-		fp2cr       = regInfo{inputs: []regMask{fp, fp}}
-		fpload      = regInfo{inputs: []regMask{gp | sp | sb}, outputs: []regMask{fp}}
-		fploadidx   = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb}, outputs: []regMask{fp}}
-		fpstore     = regInfo{inputs: []regMask{gp | sp | sb, fp}}
-		fpstoreidx  = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb, fp}}
-		callerSave  = regMask(gp | fp | gr | xer)
-		r3          = buildReg("R3")
-		r4          = buildReg("R4")
-		r5          = buildReg("R5")
-		r6          = buildReg("R6")
-	)
-	ops := []opData{
-		{name: "ADD", argLength: 2, reg: gp21, asm: "ADD", commutative: true},        // arg0 + arg1
-		{name: "ADDconst", argLength: 1, reg: gp11, asm: "ADD", aux: "Int64"},        // arg0 + auxInt
-		{name: "FADD", argLength: 2, reg: fp21, asm: "FADD", commutative: true},      // arg0+arg1
-		{name: "FADDS", argLength: 2, reg: fp21, asm: "FADDS", commutative: true},    // arg0+arg1
-		{name: "SUB", argLength: 2, reg: gp21, asm: "SUB"},                           // arg0-arg1
-		{name: "SUBFCconst", argLength: 1, reg: gp11cxer, asm: "SUBC", aux: "Int64"}, // auxInt - arg0 (carry is ignored)
-		{name: "FSUB", argLength: 2, reg: fp21, asm: "FSUB"},                         // arg0-arg1
-		{name: "FSUBS", argLength: 2, reg: fp21, asm: "FSUBS"},                       // arg0-arg1
-
-		{name: "MULLD", argLength: 2, reg: gp21, asm: "MULLD", typ: "Int64", commutative: true}, // arg0*arg1 (signed 64-bit)
-		{name: "MULLW", argLength: 2, reg: gp21, asm: "MULLW", typ: "Int32", commutative: true}, // arg0*arg1 (signed 32-bit)
-		{name: "MULLDconst", argLength: 1, reg: gp11, asm: "MULLD", aux: "Int32", typ: "Int64"}, // arg0*auxInt (signed 64-bit)
-		{name: "MULLWconst", argLength: 1, reg: gp11, asm: "MULLW", aux: "Int32", typ: "Int64"}, // arg0*auxInt (signed 64-bit)
-		{name: "MADDLD", argLength: 3, reg: gp31, asm: "MADDLD", typ: "Int64"},                  // (arg0*arg1)+arg2 (signed 64-bit)
-
-		{name: "MULHD", argLength: 2, reg: gp21, asm: "MULHD", commutative: true},   // (arg0 * arg1) >> 64, signed
-		{name: "MULHW", argLength: 2, reg: gp21, asm: "MULHW", commutative: true},   // (arg0 * arg1) >> 32, signed
-		{name: "MULHDU", argLength: 2, reg: gp21, asm: "MULHDU", commutative: true}, // (arg0 * arg1) >> 64, unsigned
-		{name: "MULHWU", argLength: 2, reg: gp21, asm: "MULHWU", commutative: true}, // (arg0 * arg1) >> 32, unsigned
-		{name: "LoweredMuluhilo", argLength: 2, reg: gp22, resultNotInArgs: true},   // arg0 * arg1, returns (hi, lo)
-
-		{name: "FMUL", argLength: 2, reg: fp21, asm: "FMUL", commutative: true},   // arg0*arg1
-		{name: "FMULS", argLength: 2, reg: fp21, asm: "FMULS", commutative: true}, // arg0*arg1
-
-		{name: "FMADD", argLength: 3, reg: fp31, asm: "FMADD"},   // arg0*arg1 + arg2
-		{name: "FMADDS", argLength: 3, reg: fp31, asm: "FMADDS"}, // arg0*arg1 + arg2
-		{name: "FMSUB", argLength: 3, reg: fp31, asm: "FMSUB"},   // arg0*arg1 - arg2
-		{name: "FMSUBS", argLength: 3, reg: fp31, asm: "FMSUBS"}, // arg0*arg1 - arg2
-
-		{name: "SRAD", argLength: 2, reg: gp21cxer, asm: "SRAD"}, // signed arg0 >> (arg1&127), 64 bit width (note: 127, not 63!)
-		{name: "SRAW", argLength: 2, reg: gp21cxer, asm: "SRAW"}, // signed arg0 >> (arg1&63), 32 bit width
-		{name: "SRD", argLength: 2, reg: gp21, asm: "SRD"},       // unsigned arg0 >> (arg1&127), 64 bit width
-		{name: "SRW", argLength: 2, reg: gp21, asm: "SRW"},       // unsigned arg0 >> (arg1&63), 32 bit width
-		{name: "SLD", argLength: 2, reg: gp21, asm: "SLD"},       // arg0 << (arg1&127), 64 bit width
-		{name: "SLW", argLength: 2, reg: gp21, asm: "SLW"},       // arg0 << (arg1&63), 32 bit width
-
-		{name: "ROTL", argLength: 2, reg: gp21, asm: "ROTL"},   // arg0 rotate left by arg1 mod 64
-		{name: "ROTLW", argLength: 2, reg: gp21, asm: "ROTLW"}, // uint32(arg0) rotate left by arg1 mod 32
-		// The following are ops to implement the extended mnemonics for shifts as described in section C.8 of the ISA.
-		// The constant shift values are packed into the aux int32.
-		{name: "RLDICL", argLength: 1, reg: gp11, asm: "RLDICL", aux: "Int32"},     // arg0 extract bits identified by shift params"
-		{name: "CLRLSLWI", argLength: 1, reg: gp11, asm: "CLRLSLWI", aux: "Int32"}, //
-		{name: "CLRLSLDI", argLength: 1, reg: gp11, asm: "CLRLSLDI", aux: "Int32"}, //
-
-		// Operations which consume or generate the CA (xer)
-		{name: "ADDC", argLength: 2, reg: gp21xer, asm: "ADDC", commutative: true, typ: "(UInt64, UInt64)"},    // arg0 + arg1 -> out, CA
-		{name: "SUBC", argLength: 2, reg: gp21xer, asm: "SUBC", typ: "(UInt64, UInt64)"},                       // arg0 - arg1 -> out, CA
-		{name: "ADDCconst", argLength: 1, reg: gp11xer, asm: "ADDC", typ: "(UInt64, UInt64)", aux: "Int64"},    // arg0 + imm16 -> out, CA
-		{name: "SUBCconst", argLength: 1, reg: gp11xer, asm: "SUBC", typ: "(UInt64, UInt64)", aux: "Int64"},    // imm16 - arg0 -> out, CA
-		{name: "ADDE", argLength: 3, reg: gp2xer1xer, asm: "ADDE", typ: "(UInt64, UInt64)", commutative: true}, // arg0 + arg1 + CA (arg2) -> out, CA
-		{name: "SUBE", argLength: 3, reg: gp2xer1xer, asm: "SUBE", typ: "(UInt64, UInt64)"},                    // arg0 - arg1 - CA (arg2) -> out, CA
-		{name: "ADDZEzero", argLength: 1, reg: xergp, asm: "ADDZE", typ: "UInt64"},                             // CA (arg0) + $0 -> out
-		{name: "SUBZEzero", argLength: 1, reg: xergp, asm: "SUBZE", typ: "UInt64"},                             // $0 - CA (arg0) -> out
-
-		{name: "SRADconst", argLength: 1, reg: gp11cxer, asm: "SRAD", aux: "Int64"}, // signed arg0 >> auxInt, 0 <= auxInt < 64, 64 bit width
-		{name: "SRAWconst", argLength: 1, reg: gp11cxer, asm: "SRAW", aux: "Int64"}, // signed arg0 >> auxInt, 0 <= auxInt < 32, 32 bit width
-		{name: "SRDconst", argLength: 1, reg: gp11, asm: "SRD", aux: "Int64"},       // unsigned arg0 >> auxInt, 0 <= auxInt < 64, 64 bit width
-		{name: "SRWconst", argLength: 1, reg: gp11, asm: "SRW", aux: "Int64"},       // unsigned arg0 >> auxInt, 0 <= auxInt < 32, 32 bit width
-		{name: "SLDconst", argLength: 1, reg: gp11, asm: "SLD", aux: "Int64"},       // arg0 << auxInt, 0 <= auxInt < 64, 64 bit width
-		{name: "SLWconst", argLength: 1, reg: gp11, asm: "SLW", aux: "Int64"},       // arg0 << auxInt, 0 <= auxInt < 32, 32 bit width
-
-		{name: "ROTLconst", argLength: 1, reg: gp11, asm: "ROTL", aux: "Int64"},   // arg0 rotate left by auxInt bits
-		{name: "ROTLWconst", argLength: 1, reg: gp11, asm: "ROTLW", aux: "Int64"}, // uint32(arg0) rotate left by auxInt bits
-		{name: "EXTSWSLconst", argLength: 1, reg: gp11, asm: "EXTSWSLI", aux: "Int64"},
-
-		{name: "RLWINM", argLength: 1, reg: gp11, asm: "RLWNM", aux: "Int64"},                      // Rotate and mask by immediate "rlwinm". encodePPC64RotateMask describes aux
-		{name: "RLWNM", argLength: 2, reg: gp21, asm: "RLWNM", aux: "Int64"},                       // Rotate and mask by "rlwnm". encodePPC64RotateMask describes aux
-		{name: "RLWMI", argLength: 2, reg: gp21a0, asm: "RLWMI", aux: "Int64", resultInArg0: true}, // "rlwimi" similar aux encoding as above
-
-		{name: "CNTLZD", argLength: 1, reg: gp11, asm: "CNTLZD", clobberFlags: true}, // count leading zeros
-		{name: "CNTLZW", argLength: 1, reg: gp11, asm: "CNTLZW", clobberFlags: true}, // count leading zeros (32 bit)
-
-		{name: "CNTTZD", argLength: 1, reg: gp11, asm: "CNTTZD"}, // count trailing zeros
-		{name: "CNTTZW", argLength: 1, reg: gp11, asm: "CNTTZW"}, // count trailing zeros (32 bit)
-
-		{name: "POPCNTD", argLength: 1, reg: gp11, asm: "POPCNTD"}, // number of set bits in arg0
-		{name: "POPCNTW", argLength: 1, reg: gp11, asm: "POPCNTW"}, // number of set bits in each word of arg0 placed in corresponding word
-		{name: "POPCNTB", argLength: 1, reg: gp11, asm: "POPCNTB"}, // number of set bits in each byte of arg0 placed in corresponding byte
-
-		{name: "FDIV", argLength: 2, reg: fp21, asm: "FDIV"},   // arg0/arg1
-		{name: "FDIVS", argLength: 2, reg: fp21, asm: "FDIVS"}, // arg0/arg1
-
-		{name: "DIVD", argLength: 2, reg: gp21, asm: "DIVD", typ: "Int64"},   // arg0/arg1 (signed 64-bit)
-		{name: "DIVW", argLength: 2, reg: gp21, asm: "DIVW", typ: "Int32"},   // arg0/arg1 (signed 32-bit)
-		{name: "DIVDU", argLength: 2, reg: gp21, asm: "DIVDU", typ: "Int64"}, // arg0/arg1 (unsigned 64-bit)
-		{name: "DIVWU", argLength: 2, reg: gp21, asm: "DIVWU", typ: "Int32"}, // arg0/arg1 (unsigned 32-bit)
-
-		{name: "MODUD", argLength: 2, reg: gp21, asm: "MODUD", typ: "UInt64"}, // arg0 % arg1 (unsigned 64-bit)
-		{name: "MODSD", argLength: 2, reg: gp21, asm: "MODSD", typ: "Int64"},  // arg0 % arg1 (signed 64-bit)
-		{name: "MODUW", argLength: 2, reg: gp21, asm: "MODUW", typ: "UInt32"}, // arg0 % arg1 (unsigned 32-bit)
-		{name: "MODSW", argLength: 2, reg: gp21, asm: "MODSW", typ: "Int32"},  // arg0 % arg1 (signed 32-bit)
-		// MOD is implemented as rem := arg0 - (arg0/arg1) * arg1
-
-		// Conversions are all float-to-float register operations.  "Integer" refers to encoding in the FP register.
-		{name: "FCTIDZ", argLength: 1, reg: fp11, asm: "FCTIDZ", typ: "Float64"}, // convert float to 64-bit int round towards zero
-		{name: "FCTIWZ", argLength: 1, reg: fp11, asm: "FCTIWZ", typ: "Float64"}, // convert float to 32-bit int round towards zero
-		{name: "FCFID", argLength: 1, reg: fp11, asm: "FCFID", typ: "Float64"},   // convert 64-bit integer to float
-		{name: "FCFIDS", argLength: 1, reg: fp11, asm: "FCFIDS", typ: "Float32"}, // convert 32-bit integer to float
-		{name: "FRSP", argLength: 1, reg: fp11, asm: "FRSP", typ: "Float64"},     // round float to 32-bit value
-
-		// Movement between float and integer registers with no change in bits; accomplished with stores+loads on PPC.
-		// Because the 32-bit load-literal-bits instructions have impoverished addressability, always widen the
-		// data instead and use FMOVDload and FMOVDstore instead (this will also dodge endianess issues).
-		// There are optimizations that should apply -- (Xi2f64 (MOVWload (not-ADD-ptr+offset) ) ) could use
-		// the word-load instructions.  (Xi2f64 (MOVDload ptr )) can be (FMOVDload ptr)
-
-		{name: "MFVSRD", argLength: 1, reg: fpgp, asm: "MFVSRD", typ: "Int64"},   // move 64 bits of F register into G register
-		{name: "MTVSRD", argLength: 1, reg: gpfp, asm: "MTVSRD", typ: "Float64"}, // move 64 bits of G register into F register
-
-		{name: "AND", argLength: 2, reg: gp21, asm: "AND", commutative: true},                    // arg0&arg1
-		{name: "ANDN", argLength: 2, reg: gp21, asm: "ANDN"},                                     // arg0&^arg1
-		{name: "ANDCC", argLength: 2, reg: gp2cr, asm: "ANDCC", commutative: true, typ: "Flags"}, // arg0&arg1 sets CC
-		{name: "OR", argLength: 2, reg: gp21, asm: "OR", commutative: true},                      // arg0|arg1
-		{name: "ORN", argLength: 2, reg: gp21, asm: "ORN"},                                       // arg0|^arg1
-		{name: "ORCC", argLength: 2, reg: gp2cr, asm: "ORCC", commutative: true, typ: "Flags"},   // arg0|arg1 sets CC
-		{name: "NOR", argLength: 2, reg: gp21, asm: "NOR", commutative: true},                    // ^(arg0|arg1)
-		{name: "XOR", argLength: 2, reg: gp21, asm: "XOR", typ: "Int64", commutative: true},      // arg0^arg1
-		{name: "XORCC", argLength: 2, reg: gp2cr, asm: "XORCC", commutative: true, typ: "Flags"}, // arg0^arg1 sets CC
-		{name: "EQV", argLength: 2, reg: gp21, asm: "EQV", typ: "Int64", commutative: true},      // arg0^^arg1
-		{name: "NEG", argLength: 1, reg: gp11, asm: "NEG"},                                       // -arg0 (integer)
-		{name: "FNEG", argLength: 1, reg: fp11, asm: "FNEG"},                                     // -arg0 (floating point)
-		{name: "FSQRT", argLength: 1, reg: fp11, asm: "FSQRT"},                                   // sqrt(arg0) (floating point)
-		{name: "FSQRTS", argLength: 1, reg: fp11, asm: "FSQRTS"},                                 // sqrt(arg0) (floating point, single precision)
-		{name: "FFLOOR", argLength: 1, reg: fp11, asm: "FRIM"},                                   // floor(arg0), float64
-		{name: "FCEIL", argLength: 1, reg: fp11, asm: "FRIP"},                                    // ceil(arg0), float64
-		{name: "FTRUNC", argLength: 1, reg: fp11, asm: "FRIZ"},                                   // trunc(arg0), float64
-		{name: "FROUND", argLength: 1, reg: fp11, asm: "FRIN"},                                   // round(arg0), float64
-		{name: "FABS", argLength: 1, reg: fp11, asm: "FABS"},                                     // abs(arg0), float64
-		{name: "FNABS", argLength: 1, reg: fp11, asm: "FNABS"},                                   // -abs(arg0), float64
-		{name: "FCPSGN", argLength: 2, reg: fp21, asm: "FCPSGN"},                                 // copysign arg0 -> arg1, float64
-
-		{name: "ORconst", argLength: 1, reg: gp11, asm: "OR", aux: "Int64"},                                                                                     // arg0|aux
-		{name: "XORconst", argLength: 1, reg: gp11, asm: "XOR", aux: "Int64"},                                                                                   // arg0^aux
-		{name: "ANDconst", argLength: 1, reg: regInfo{inputs: []regMask{gp | sp | sb}, outputs: []regMask{gp}}, asm: "ANDCC", aux: "Int64", clobberFlags: true}, // arg0&aux // and-immediate sets CC on PPC, always.
-		{name: "ANDCCconst", argLength: 1, reg: regInfo{inputs: []regMask{gp | sp | sb}}, asm: "ANDCC", aux: "Int64", typ: "Flags"},                             // arg0&aux == 0 // and-immediate sets CC on PPC, always.
-
-		{name: "MOVBreg", argLength: 1, reg: gp11, asm: "MOVB", typ: "Int64"},   // sign extend int8 to int64
-		{name: "MOVBZreg", argLength: 1, reg: gp11, asm: "MOVBZ", typ: "Int64"}, // zero extend uint8 to uint64
-		{name: "MOVHreg", argLength: 1, reg: gp11, asm: "MOVH", typ: "Int64"},   // sign extend int16 to int64
-		{name: "MOVHZreg", argLength: 1, reg: gp11, asm: "MOVHZ", typ: "Int64"}, // zero extend uint16 to uint64
-		{name: "MOVWreg", argLength: 1, reg: gp11, asm: "MOVW", typ: "Int64"},   // sign extend int32 to int64
-		{name: "MOVWZreg", argLength: 1, reg: gp11, asm: "MOVWZ", typ: "Int64"}, // zero extend uint32 to uint64
-
-		// Load bytes in the endian order of the arch from arg0+aux+auxint into a 64 bit register.
-		{name: "MOVBZload", argLength: 2, reg: gpload, asm: "MOVBZ", aux: "SymOff", typ: "UInt8", faultOnNilArg0: true, symEffect: "Read"},  // load byte zero extend
-		{name: "MOVHload", argLength: 2, reg: gpload, asm: "MOVH", aux: "SymOff", typ: "Int16", faultOnNilArg0: true, symEffect: "Read"},    // load 2 bytes sign extend
-		{name: "MOVHZload", argLength: 2, reg: gpload, asm: "MOVHZ", aux: "SymOff", typ: "UInt16", faultOnNilArg0: true, symEffect: "Read"}, // load 2 bytes zero extend
-		{name: "MOVWload", argLength: 2, reg: gpload, asm: "MOVW", aux: "SymOff", typ: "Int32", faultOnNilArg0: true, symEffect: "Read"},    // load 4 bytes sign extend
-		{name: "MOVWZload", argLength: 2, reg: gpload, asm: "MOVWZ", aux: "SymOff", typ: "UInt32", faultOnNilArg0: true, symEffect: "Read"}, // load 4 bytes zero extend
-		{name: "MOVDload", argLength: 2, reg: gpload, asm: "MOVD", aux: "SymOff", typ: "Int64", faultOnNilArg0: true, symEffect: "Read"},    // load 8 bytes
-
-		// Load bytes in reverse endian order of the arch from arg0 into a 64 bit register, all zero extend.
-		// The generated instructions are indexed loads with no offset field in the instruction so the aux fields are not used.
-		// In these cases the index register field is set to 0 and the full address is in the base register.
-		{name: "MOVDBRload", argLength: 2, reg: gpload, asm: "MOVDBR", aux: "SymOff", typ: "Int64", faultOnNilArg0: true, symEffect: "Read"}, // load 8 bytes reverse order
-		{name: "MOVWBRload", argLength: 2, reg: gpload, asm: "MOVWBR", aux: "SymOff", typ: "Int32", faultOnNilArg0: true, symEffect: "Read"}, // load 4 bytes zero extend reverse order
-		{name: "MOVHBRload", argLength: 2, reg: gpload, asm: "MOVHBR", aux: "SymOff", typ: "Int16", faultOnNilArg0: true, symEffect: "Read"}, // load 2 bytes zero extend reverse order
-
-		// In these cases an index register is used in addition to a base register
-		// Loads from memory location arg[0] + arg[1].
-		{name: "MOVBZloadidx", argLength: 3, reg: gploadidx, asm: "MOVBZ", typ: "UInt8"},  // zero extend uint8 to uint64
-		{name: "MOVHloadidx", argLength: 3, reg: gploadidx, asm: "MOVH", typ: "Int16"},    // sign extend int16 to int64
-		{name: "MOVHZloadidx", argLength: 3, reg: gploadidx, asm: "MOVHZ", typ: "UInt16"}, // zero extend uint16 to uint64
-		{name: "MOVWloadidx", argLength: 3, reg: gploadidx, asm: "MOVW", typ: "Int32"},    // sign extend int32 to int64
-		{name: "MOVWZloadidx", argLength: 3, reg: gploadidx, asm: "MOVWZ", typ: "UInt32"}, // zero extend uint32 to uint64
-		{name: "MOVDloadidx", argLength: 3, reg: gploadidx, asm: "MOVD", typ: "Int64"},
-		{name: "MOVHBRloadidx", argLength: 3, reg: gploadidx, asm: "MOVHBR", typ: "Int16"}, // sign extend int16 to int64
-		{name: "MOVWBRloadidx", argLength: 3, reg: gploadidx, asm: "MOVWBR", typ: "Int32"}, // sign extend int32 to int64
-		{name: "MOVDBRloadidx", argLength: 3, reg: gploadidx, asm: "MOVDBR", typ: "Int64"},
-		{name: "FMOVDloadidx", argLength: 3, reg: fploadidx, asm: "FMOVD", typ: "Float64"},
-		{name: "FMOVSloadidx", argLength: 3, reg: fploadidx, asm: "FMOVS", typ: "Float32"},
-
-		// Prefetch instruction
-		// Do prefetch of address generated with arg0 and arg1 with option aux. arg0=addr,arg1=memory, aux=option.
-		{name: "DCBT", argLength: 2, aux: "Int64", reg: prefreg, asm: "DCBT", hasSideEffects: true},
-
-		// Store bytes in the reverse endian order of the arch into arg0.
-		// These are indexed stores with no offset field in the instruction so the auxint fields are not used.
-		{name: "MOVDBRstore", argLength: 3, reg: gpstore, asm: "MOVDBR", aux: "Sym", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes reverse order
-		{name: "MOVWBRstore", argLength: 3, reg: gpstore, asm: "MOVWBR", aux: "Sym", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes reverse order
-		{name: "MOVHBRstore", argLength: 3, reg: gpstore, asm: "MOVHBR", aux: "Sym", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 2 bytes reverse order
-
-		// Floating point loads from arg0+aux+auxint
-		{name: "FMOVDload", argLength: 2, reg: fpload, asm: "FMOVD", aux: "SymOff", typ: "Float64", faultOnNilArg0: true, symEffect: "Read"}, // load double float
-		{name: "FMOVSload", argLength: 2, reg: fpload, asm: "FMOVS", aux: "SymOff", typ: "Float32", faultOnNilArg0: true, symEffect: "Read"}, // load single float
-
-		// Store bytes in the endian order of the arch into arg0+aux+auxint
-		{name: "MOVBstore", argLength: 3, reg: gpstore, asm: "MOVB", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store byte
-		{name: "MOVHstore", argLength: 3, reg: gpstore, asm: "MOVH", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 2 bytes
-		{name: "MOVWstore", argLength: 3, reg: gpstore, asm: "MOVW", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes
-		{name: "MOVDstore", argLength: 3, reg: gpstore, asm: "MOVD", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes
-
-		// Store floating point value into arg0+aux+auxint
-		{name: "FMOVDstore", argLength: 3, reg: fpstore, asm: "FMOVD", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store double flot
-		{name: "FMOVSstore", argLength: 3, reg: fpstore, asm: "FMOVS", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store single float
-
-		// Stores using index and base registers
-		// Stores to arg[0] + arg[1]
-		{name: "MOVBstoreidx", argLength: 4, reg: gpstoreidx, asm: "MOVB", typ: "Mem"},     // store bye
-		{name: "MOVHstoreidx", argLength: 4, reg: gpstoreidx, asm: "MOVH", typ: "Mem"},     // store half word
-		{name: "MOVWstoreidx", argLength: 4, reg: gpstoreidx, asm: "MOVW", typ: "Mem"},     // store word
-		{name: "MOVDstoreidx", argLength: 4, reg: gpstoreidx, asm: "MOVD", typ: "Mem"},     // store double word
-		{name: "FMOVDstoreidx", argLength: 4, reg: fpstoreidx, asm: "FMOVD", typ: "Mem"},   // store double float
-		{name: "FMOVSstoreidx", argLength: 4, reg: fpstoreidx, asm: "FMOVS", typ: "Mem"},   // store single float
-		{name: "MOVHBRstoreidx", argLength: 4, reg: gpstoreidx, asm: "MOVHBR", typ: "Mem"}, // store half word reversed byte using index reg
-		{name: "MOVWBRstoreidx", argLength: 4, reg: gpstoreidx, asm: "MOVWBR", typ: "Mem"}, // store word reversed byte using index reg
-		{name: "MOVDBRstoreidx", argLength: 4, reg: gpstoreidx, asm: "MOVDBR", typ: "Mem"}, // store double word reversed byte using index reg
-
-		// The following ops store 0 into arg0+aux+auxint arg1=mem
-		{name: "MOVBstorezero", argLength: 2, reg: gpstorezero, asm: "MOVB", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store zero 1 byte
-		{name: "MOVHstorezero", argLength: 2, reg: gpstorezero, asm: "MOVH", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store zero 2 bytes
-		{name: "MOVWstorezero", argLength: 2, reg: gpstorezero, asm: "MOVW", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store zero 4 bytes
-		{name: "MOVDstorezero", argLength: 2, reg: gpstorezero, asm: "MOVD", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store zero 8 bytes
-
-		{name: "MOVDaddr", argLength: 1, reg: regInfo{inputs: []regMask{sp | sb | gp}, outputs: []regMask{gp}}, aux: "SymOff", asm: "MOVD", rematerializeable: true, symEffect: "Addr"}, // arg0 + auxInt + aux.(*gc.Sym), arg0=SP/SB/GP
-
-		{name: "MOVDconst", argLength: 0, reg: gp01, aux: "Int64", asm: "MOVD", typ: "Int64", rematerializeable: true}, //
-		{name: "FMOVDconst", argLength: 0, reg: fp01, aux: "Float64", asm: "FMOVD", rematerializeable: true},           //
-		{name: "FMOVSconst", argLength: 0, reg: fp01, aux: "Float32", asm: "FMOVS", rematerializeable: true},           //
-		{name: "FCMPU", argLength: 2, reg: fp2cr, asm: "FCMPU", typ: "Flags"},
-
-		{name: "CMP", argLength: 2, reg: gp2cr, asm: "CMP", typ: "Flags"},     // arg0 compare to arg1
-		{name: "CMPU", argLength: 2, reg: gp2cr, asm: "CMPU", typ: "Flags"},   // arg0 compare to arg1
-		{name: "CMPW", argLength: 2, reg: gp2cr, asm: "CMPW", typ: "Flags"},   // arg0 compare to arg1
-		{name: "CMPWU", argLength: 2, reg: gp2cr, asm: "CMPWU", typ: "Flags"}, // arg0 compare to arg1
-		{name: "CMPconst", argLength: 1, reg: gp1cr, asm: "CMP", aux: "Int64", typ: "Flags"},
-		{name: "CMPUconst", argLength: 1, reg: gp1cr, asm: "CMPU", aux: "Int64", typ: "Flags"},
-		{name: "CMPWconst", argLength: 1, reg: gp1cr, asm: "CMPW", aux: "Int32", typ: "Flags"},
-		{name: "CMPWUconst", argLength: 1, reg: gp1cr, asm: "CMPWU", aux: "Int32", typ: "Flags"},
-
-		// ISEL auxInt values 0=LT 1=GT 2=EQ   arg2 ? arg0 : arg1
-		// ISEL auxInt values 4=GE 5=LE 6=NE   !arg2 ? arg1 : arg0
-		// ISELB special case where arg0, arg1 values are 0, 1 for boolean result
-		{name: "ISEL", argLength: 3, reg: crgp21, asm: "ISEL", aux: "Int32", typ: "Int32"},  // see above
-		{name: "ISELB", argLength: 2, reg: crgp11, asm: "ISEL", aux: "Int32", typ: "Int32"}, // see above
-
-		// pseudo-ops
-		{name: "Equal", argLength: 1, reg: crgp},         // bool, true flags encode x==y false otherwise.
-		{name: "NotEqual", argLength: 1, reg: crgp},      // bool, true flags encode x!=y false otherwise.
-		{name: "LessThan", argLength: 1, reg: crgp},      // bool, true flags encode  x<y false otherwise.
-		{name: "FLessThan", argLength: 1, reg: crgp},     // bool, true flags encode  x<y false otherwise.
-		{name: "LessEqual", argLength: 1, reg: crgp},     // bool, true flags encode  x<=y false otherwise.
-		{name: "FLessEqual", argLength: 1, reg: crgp},    // bool, true flags encode  x<=y false otherwise; PPC <= === !> which is wrong for NaN
-		{name: "GreaterThan", argLength: 1, reg: crgp},   // bool, true flags encode  x>y false otherwise.
-		{name: "FGreaterThan", argLength: 1, reg: crgp},  // bool, true flags encode  x>y false otherwise.
-		{name: "GreaterEqual", argLength: 1, reg: crgp},  // bool, true flags encode  x>=y false otherwise.
-		{name: "FGreaterEqual", argLength: 1, reg: crgp}, // bool, true flags encode  x>=y false otherwise.; PPC >= === !< which is wrong for NaN
-
-		// Scheduler ensures LoweredGetClosurePtr occurs only in entry block,
-		// and sorts it to the very beginning of the block to prevent other
-		// use of the closure pointer.
-		{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{ctxt}}, zeroWidth: true},
-
-		// LoweredGetCallerSP returns the SP of the caller of the current function.
-		{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
-
-		// LoweredGetCallerPC evaluates to the PC to which its "caller" will return.
-		// I.e., if f calls g "calls" getcallerpc,
-		// the result should be the PC within f that g will return to.
-		// See runtime/stubs.go for a more detailed discussion.
-		{name: "LoweredGetCallerPC", reg: gp01, rematerializeable: true},
-
-		//arg0=ptr,arg1=mem, returns void.  Faults if ptr is nil.
-		{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gp | sp | sb}, clobbers: tmp}, clobberFlags: true, nilCheck: true, faultOnNilArg0: true},
-		// Round ops to block fused-multiply-add extraction.
-		{name: "LoweredRound32F", argLength: 1, reg: fp11, resultInArg0: true, zeroWidth: true},
-		{name: "LoweredRound64F", argLength: 1, reg: fp11, resultInArg0: true, zeroWidth: true},
-
-		{name: "CALLstatic", argLength: -1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                                       // call static function aux.(*obj.LSym).  arg0=mem, auxint=argsize, returns mem
-		{name: "CALLtail", argLength: -1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true, tailCall: true},                         // tail call static function aux.(*obj.LSym).  arg0=mem, auxint=argsize, returns mem
-		{name: "CALLclosure", argLength: -1, reg: regInfo{inputs: []regMask{callptr, ctxt, 0}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call function via closure.  arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem
-		{name: "CALLinter", argLength: -1, reg: regInfo{inputs: []regMask{callptr}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},            // call fn by pointer.  arg0=codeptr, arg1=mem, auxint=argsize, returns mem
-
-		// large or unaligned zeroing
-		// arg0 = address of memory to zero (in R3, changed as side effect)
-		// returns mem
-		//
-		// a loop is generated when there is more than one iteration
-		// needed to clear 4 doublewords
-		//
-		//	XXLXOR	VS32,VS32,VS32
-		// 	MOVD	$len/32,R31
-		//	MOVD	R31,CTR
-		//	MOVD	$16,R31
-		//	loop:
-		//	STXVD2X VS32,(R0)(R3)
-		//	STXVD2X	VS32,(R31),R3)
-		//	ADD	R3,32
-		//	BC	loop
-
-		// remaining doubleword clears generated as needed
-		//	MOVD	R0,(R3)
-		//	MOVD	R0,8(R3)
-		//	MOVD	R0,16(R3)
-		//	MOVD	R0,24(R3)
-
-		// one or more of these to clear remainder < 8 bytes
-		//	MOVW	R0,n1(R3)
-		//	MOVH	R0,n2(R3)
-		//	MOVB	R0,n3(R3)
-		{
-			name:      "LoweredZero",
-			aux:       "Int64",
-			argLength: 2,
-			reg: regInfo{
-				inputs:   []regMask{buildReg("R20")},
-				clobbers: buildReg("R20"),
-			},
-			clobberFlags:   true,
-			typ:            "Mem",
-			faultOnNilArg0: true,
-			unsafePoint:    true,
-		},
-		{
-			name:      "LoweredZeroShort",
-			aux:       "Int64",
-			argLength: 2,
-			reg: regInfo{
-				inputs: []regMask{gp}},
-			typ:            "Mem",
-			faultOnNilArg0: true,
-			unsafePoint:    true,
-		},
-		{
-			name:      "LoweredQuadZeroShort",
-			aux:       "Int64",
-			argLength: 2,
-			reg: regInfo{
-				inputs: []regMask{gp},
-			},
-			typ:            "Mem",
-			faultOnNilArg0: true,
-			unsafePoint:    true,
-		},
-		{
-			name:      "LoweredQuadZero",
-			aux:       "Int64",
-			argLength: 2,
-			reg: regInfo{
-				inputs:   []regMask{buildReg("R20")},
-				clobbers: buildReg("R20"),
-			},
-			clobberFlags:   true,
-			typ:            "Mem",
-			faultOnNilArg0: true,
-			unsafePoint:    true,
-		},
-
-		// R31 is temp register
-		// Loop code:
-		//	MOVD len/32,R31		set up loop ctr
-		//	MOVD R31,CTR
-		//	MOVD $16,R31		index register
-		// loop:
-		//	LXVD2X (R0)(R4),VS32
-		//	LXVD2X (R31)(R4),VS33
-		//	ADD  R4,$32          increment src
-		//	STXVD2X VS32,(R0)(R3)
-		//	STXVD2X VS33,(R31)(R3)
-		//	ADD  R3,$32          increment dst
-		//	BC 16,0,loop         branch ctr
-		// For this purpose, VS32 and VS33 are treated as
-		// scratch registers. Since regalloc does not
-		// track vector registers, even if it could be marked
-		// as clobbered it would have no effect.
-		// TODO: If vector registers are managed by regalloc
-		// mark these as clobbered.
-		//
-		// Bytes not moved by this loop are moved
-		// with a combination of the following instructions,
-		// starting with the largest sizes and generating as
-		// many as needed, using the appropriate offset value.
-		//	MOVD  n(R4),R14
-		//	MOVD  R14,n(R3)
-		//	MOVW  n1(R4),R14
-		//	MOVW  R14,n1(R3)
-		//	MOVH  n2(R4),R14
-		//	MOVH  R14,n2(R3)
-		//	MOVB  n3(R4),R14
-		//	MOVB  R14,n3(R3)
-
-		{
-			name:      "LoweredMove",
-			aux:       "Int64",
-			argLength: 3,
-			reg: regInfo{
-				inputs:   []regMask{buildReg("R20"), buildReg("R21")},
-				clobbers: buildReg("R20 R21"),
-			},
-			clobberFlags:   true,
-			typ:            "Mem",
-			faultOnNilArg0: true,
-			faultOnNilArg1: true,
-			unsafePoint:    true,
-		},
-		{
-			name:      "LoweredMoveShort",
-			aux:       "Int64",
-			argLength: 3,
-			reg: regInfo{
-				inputs: []regMask{gp, gp},
-			},
-			typ:            "Mem",
-			faultOnNilArg0: true,
-			faultOnNilArg1: true,
-			unsafePoint:    true,
-		},
-
-		// The following is similar to the LoweredMove, but uses
-		// LXV instead of LXVD2X, which does not require an index
-		// register and will do 4 in a loop instead of only.
-		{
-			name:      "LoweredQuadMove",
-			aux:       "Int64",
-			argLength: 3,
-			reg: regInfo{
-				inputs:   []regMask{buildReg("R20"), buildReg("R21")},
-				clobbers: buildReg("R20 R21"),
-			},
-			clobberFlags:   true,
-			typ:            "Mem",
-			faultOnNilArg0: true,
-			faultOnNilArg1: true,
-			unsafePoint:    true,
-		},
-
-		{
-			name:      "LoweredQuadMoveShort",
-			aux:       "Int64",
-			argLength: 3,
-			reg: regInfo{
-				inputs: []regMask{gp, gp},
-			},
-			typ:            "Mem",
-			faultOnNilArg0: true,
-			faultOnNilArg1: true,
-			unsafePoint:    true,
-		},
-
-		{name: "LoweredAtomicStore8", argLength: 3, reg: gpstore, typ: "Mem", aux: "Int64", faultOnNilArg0: true, hasSideEffects: true},
-		{name: "LoweredAtomicStore32", argLength: 3, reg: gpstore, typ: "Mem", aux: "Int64", faultOnNilArg0: true, hasSideEffects: true},
-		{name: "LoweredAtomicStore64", argLength: 3, reg: gpstore, typ: "Mem", aux: "Int64", faultOnNilArg0: true, hasSideEffects: true},
-
-		{name: "LoweredAtomicLoad8", argLength: 2, reg: gpload, typ: "UInt8", aux: "Int64", clobberFlags: true, faultOnNilArg0: true},
-		{name: "LoweredAtomicLoad32", argLength: 2, reg: gpload, typ: "UInt32", aux: "Int64", clobberFlags: true, faultOnNilArg0: true},
-		{name: "LoweredAtomicLoad64", argLength: 2, reg: gpload, typ: "Int64", aux: "Int64", clobberFlags: true, faultOnNilArg0: true},
-		{name: "LoweredAtomicLoadPtr", argLength: 2, reg: gpload, typ: "Int64", aux: "Int64", clobberFlags: true, faultOnNilArg0: true},
-
-		// atomic add32, 64
-		// LWSYNC
-		// LDAR         (Rarg0), Rout
-		// ADD		Rarg1, Rout
-		// STDCCC       Rout, (Rarg0)
-		// BNE          -3(PC)
-		// return new sum
-		{name: "LoweredAtomicAdd32", argLength: 3, reg: gpxchg, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true},
-		{name: "LoweredAtomicAdd64", argLength: 3, reg: gpxchg, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true},
-
-		// atomic exchange32, 64
-		// LWSYNC
-		// LDAR         (Rarg0), Rout
-		// STDCCC       Rarg1, (Rarg0)
-		// BNE          -2(PC)
-		// ISYNC
-		// return old val
-		{name: "LoweredAtomicExchange32", argLength: 3, reg: gpxchg, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true},
-		{name: "LoweredAtomicExchange64", argLength: 3, reg: gpxchg, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true},
-
-		// atomic compare and swap.
-		// arg0 = pointer, arg1 = old value, arg2 = new value, arg3 = memory. auxint must be zero.
-		// if *arg0 == arg1 {
-		//   *arg0 = arg2
-		//   return (true, memory)
-		// } else {
-		//   return (false, memory)
-		// }
-		// SYNC
-		// LDAR		(Rarg0), Rtmp
-		// CMP		Rarg1, Rtmp
-		// BNE		3(PC)
-		// STDCCC	Rarg2, (Rarg0)
-		// BNE		-4(PC)
-		// CBNZ         Rtmp, -4(PC)
-		// CSET         EQ, Rout
-		{name: "LoweredAtomicCas64", argLength: 4, reg: gpcas, resultNotInArgs: true, aux: "Int64", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true},
-		{name: "LoweredAtomicCas32", argLength: 4, reg: gpcas, resultNotInArgs: true, aux: "Int64", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true},
-
-		// atomic 8/32 and/or.
-		// *arg0 &= (|=) arg1. arg2=mem. returns memory. auxint must be zero.
-		// LBAR/LWAT	(Rarg0), Rtmp
-		// AND/OR	Rarg1, Rtmp
-		// STBCCC/STWCCC Rtmp, (Rarg0), Rtmp
-		// BNE		Rtmp, -3(PC)
-		{name: "LoweredAtomicAnd8", argLength: 3, reg: gpstore, asm: "AND", faultOnNilArg0: true, hasSideEffects: true},
-		{name: "LoweredAtomicAnd32", argLength: 3, reg: gpstore, asm: "AND", faultOnNilArg0: true, hasSideEffects: true},
-		{name: "LoweredAtomicOr8", argLength: 3, reg: gpstore, asm: "OR", faultOnNilArg0: true, hasSideEffects: true},
-		{name: "LoweredAtomicOr32", argLength: 3, reg: gpstore, asm: "OR", faultOnNilArg0: true, hasSideEffects: true},
-
-		// LoweredWB invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
-		// It preserves R0 through R17 (except special registers R1, R2, R11, R12, R13), g, and its arguments R20 and R21,
-		// but may clobber anything else, including R31 (REGTMP).
-		{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R20"), buildReg("R21")}, clobbers: (callerSave &^ buildReg("R0 R3 R4 R5 R6 R7 R8 R9 R10 R14 R15 R16 R17 R20 R21 g")) | buildReg("R31")}, clobberFlags: true, aux: "Sym", symEffect: "None"},
-
-		{name: "LoweredPubBarrier", argLength: 1, asm: "LWSYNC", hasSideEffects: true}, // Do data barrier. arg0=memory
-		// There are three of these functions so that they can have three different register inputs.
-		// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the
-		// default registers to match so we don't need to copy registers around unnecessarily.
-		{name: "LoweredPanicBoundsA", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r5, r6}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
-		{name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r4, r5}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
-		{name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r3, r4}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
-
-		// (InvertFlags (CMP a b)) == (CMP b a)
-		// So if we want (LessThan (CMP a b)) but we can't do that because a is a constant,
-		// then we do (LessThan (InvertFlags (CMP b a))) instead.
-		// Rewrites will convert this to (GreaterThan (CMP b a)).
-		// InvertFlags is a pseudo-op which can't appear in assembly output.
-		{name: "InvertFlags", argLength: 1}, // reverse direction of arg0
-
-		// Constant flag values. For any comparison, there are 3 possible
-		// outcomes: either the three from the signed total order (<,==,>)
-		// or the three from the unsigned total order, depending on which
-		// comparison operation was used (CMP or CMPU -- PPC is different from
-		// the other architectures, which have a single comparison producing
-		// both signed and unsigned comparison results.)
-
-		// These ops are for temporary use by rewrite rules. They
-		// cannot appear in the generated assembly.
-		{name: "FlagEQ"}, // equal
-		{name: "FlagLT"}, // signed < or unsigned <
-		{name: "FlagGT"}, // signed > or unsigned >
-	}
-
-	blocks := []blockData{
-		{name: "EQ", controls: 1},
-		{name: "NE", controls: 1},
-		{name: "LT", controls: 1},
-		{name: "LE", controls: 1},
-		{name: "GT", controls: 1},
-		{name: "GE", controls: 1},
-		{name: "FLT", controls: 1},
-		{name: "FLE", controls: 1},
-		{name: "FGT", controls: 1},
-		{name: "FGE", controls: 1},
-	}
-
-	archs = append(archs, arch{
-		name:               "PPC64",
-		pkg:                "cmd/internal/obj/ppc64",
-		genfile:            "../../ppc64/ssa.go",
-		ops:                ops,
-		blocks:             blocks,
-		regnames:           regNamesPPC64,
-		ParamIntRegNames:   "R3 R4 R5 R6 R7 R8 R9 R10 R14 R15 R16 R17",
-		ParamFloatRegNames: "F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12",
-		gpregmask:          gp,
-		fpregmask:          fp,
-		specialregmask:     xer,
-		framepointerreg:    -1,
-		linkreg:            -1, // not used
-	})
-}
diff --git a/src/cmd/compile/internal/ssa/gen/README b/src/cmd/compile/internal/ssa/gen/README
deleted file mode 100644
index 6d2c6bb..0000000
--- a/src/cmd/compile/internal/ssa/gen/README
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-This package generates opcode tables, rewrite rules, etc. for the ssa compiler.
-Run it with go-1.13 (or above):
-   go run *.go
diff --git a/src/cmd/compile/internal/ssa/gen/RISCV64.rules b/src/cmd/compile/internal/ssa/gen/RISCV64.rules
deleted file mode 100644
index dd20be2..0000000
--- a/src/cmd/compile/internal/ssa/gen/RISCV64.rules
+++ /dev/null
@@ -1,757 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Optimizations TODO:
-// * Use SLTI and SLTIU for comparisons to constants, instead of SLT/SLTU with constants in registers
-// * Use the zero register instead of moving 0 into a register.
-// * Add rules to avoid generating a temp bool value for (If (SLT[U] ...) ...).
-// * Arrange for non-trivial Zero and Move lowerings to use aligned loads and stores.
-// * Avoid using Neq32 for writeBarrier.enabled checks.
-
-// Lowering arithmetic
-(Add64 ...) => (ADD ...)
-(AddPtr ...) => (ADD ...)
-(Add32 ...) => (ADD ...)
-(Add16 ...) => (ADD ...)
-(Add8 ...) => (ADD ...)
-(Add32F ...) => (FADDS ...)
-(Add64F ...) => (FADDD ...)
-
-(Sub64 ...) => (SUB ...)
-(SubPtr ...) => (SUB ...)
-(Sub32 ...) => (SUB ...)
-(Sub16 ...) => (SUB ...)
-(Sub8 ...) => (SUB ...)
-(Sub32F ...) => (FSUBS ...)
-(Sub64F ...) => (FSUBD ...)
-
-(Mul64 ...) => (MUL  ...)
-(Mul64uhilo ...) => (LoweredMuluhilo ...)
-(Mul64uover ...) => (LoweredMuluover ...)
-(Mul32 ...) => (MULW ...)
-(Mul16 x y) => (MULW (SignExt16to32 x) (SignExt16to32 y))
-(Mul8 x y)  => (MULW (SignExt8to32 x)  (SignExt8to32 y))
-(Mul32F ...) => (FMULS ...)
-(Mul64F ...) => (FMULD ...)
-
-(Div32F ...) => (FDIVS ...)
-(Div64F ...) => (FDIVD ...)
-
-(Div64 x y [false])  => (DIV x y)
-(Div64u ...) => (DIVU ...)
-(Div32 x y [false])  => (DIVW x y)
-(Div32u ...) => (DIVUW ...)
-(Div16 x y [false])  => (DIVW  (SignExt16to32 x) (SignExt16to32 y))
-(Div16u x y) => (DIVUW (ZeroExt16to32 x) (ZeroExt16to32 y))
-(Div8 x y)   => (DIVW  (SignExt8to32 x)  (SignExt8to32 y))
-(Div8u x y)  => (DIVUW (ZeroExt8to32 x)  (ZeroExt8to32 y))
-
-(Hmul64 ...)  => (MULH  ...)
-(Hmul64u ...) => (MULHU ...)
-(Hmul32 x y)  => (SRAI [32] (MUL  (SignExt32to64 x) (SignExt32to64 y)))
-(Hmul32u x y) => (SRLI [32] (MUL  (ZeroExt32to64 x) (ZeroExt32to64 y)))
-
-// (x + y) / 2 => (x / 2) + (y / 2) + (x & y & 1)
-(Avg64u <t> x y) => (ADD (ADD <t> (SRLI <t> [1] x) (SRLI <t> [1] y)) (ANDI <t> [1] (AND <t> x y)))
-
-(Mod64 x y [false])  => (REM x y)
-(Mod64u ...) => (REMU  ...)
-(Mod32 x y [false])  => (REMW x y)
-(Mod32u ...) => (REMUW ...)
-(Mod16 x y [false])  => (REMW  (SignExt16to32 x) (SignExt16to32 y))
-(Mod16u x y) => (REMUW (ZeroExt16to32 x) (ZeroExt16to32 y))
-(Mod8 x y)   => (REMW  (SignExt8to32  x) (SignExt8to32  y))
-(Mod8u x y)  => (REMUW (ZeroExt8to32  x) (ZeroExt8to32  y))
-
-(And64 ...) => (AND ...)
-(And32 ...) => (AND ...)
-(And16 ...) => (AND ...)
-(And8  ...) => (AND ...)
-
-(Or64 ...) => (OR ...)
-(Or32 ...) => (OR ...)
-(Or16 ...) => (OR ...)
-(Or8  ...) => (OR ...)
-
-(Xor64 ...) => (XOR ...)
-(Xor32 ...) => (XOR ...)
-(Xor16 ...) => (XOR ...)
-(Xor8  ...) => (XOR ...)
-
-(Neg64  ...) => (NEG ...)
-(Neg32  ...) => (NEG ...)
-(Neg16  ...) => (NEG ...)
-(Neg8   ...) => (NEG ...)
-(Neg32F ...) => (FNEGS ...)
-(Neg64F ...) => (FNEGD ...)
-
-(Com64 ...) => (NOT ...)
-(Com32 ...) => (NOT ...)
-(Com16 ...) => (NOT ...)
-(Com8  ...) => (NOT ...)
-
-(Sqrt ...) => (FSQRTD ...)
-(Sqrt32 ...) => (FSQRTS ...)
-
-(Copysign ...) => (FSGNJD ...)
-
-(Abs ...) => (FABSD ...)
-
-(FMA ...) => (FMADDD ...)
-
-// Sign and zero extension.
-
-(SignExt8to16  ...) => (MOVBreg ...)
-(SignExt8to32  ...) => (MOVBreg ...)
-(SignExt8to64  ...) => (MOVBreg ...)
-(SignExt16to32 ...) => (MOVHreg ...)
-(SignExt16to64 ...) => (MOVHreg ...)
-(SignExt32to64 ...) => (MOVWreg ...)
-
-(ZeroExt8to16  ...) => (MOVBUreg ...)
-(ZeroExt8to32  ...) => (MOVBUreg ...)
-(ZeroExt8to64  ...) => (MOVBUreg ...)
-(ZeroExt16to32 ...) => (MOVHUreg ...)
-(ZeroExt16to64 ...) => (MOVHUreg ...)
-(ZeroExt32to64 ...) => (MOVWUreg ...)
-
-(Cvt32to32F ...) => (FCVTSW ...)
-(Cvt32to64F ...) => (FCVTDW ...)
-(Cvt64to32F ...) => (FCVTSL ...)
-(Cvt64to64F ...) => (FCVTDL ...)
-
-(Cvt32Fto32 ...) => (FCVTWS ...)
-(Cvt32Fto64 ...) => (FCVTLS ...)
-(Cvt64Fto32 ...) => (FCVTWD ...)
-(Cvt64Fto64 ...) => (FCVTLD ...)
-
-(Cvt32Fto64F ...) => (FCVTDS ...)
-(Cvt64Fto32F ...) => (FCVTSD ...)
-
-(CvtBoolToUint8 ...) => (Copy ...)
-
-(Round32F ...) => (Copy ...)
-(Round64F ...) => (Copy ...)
-
-// From genericOps.go:
-// "0 if arg0 == 0, -1 if arg0 > 0, undef if arg0<0"
-//
-// Like other arches, we compute ~((x-1) >> 63), with arithmetic right shift.
-// For positive x, bit 63 of x-1 is always 0, so the result is -1.
-// For zero x, bit 63 of x-1 is 1, so the result is 0.
-//
-(Slicemask <t> x) => (NOT (SRAI <t> [63] (ADDI <t> [-1] x)))
-
-// Truncations
-// We ignore the unused high parts of registers, so truncates are just copies.
-(Trunc16to8  ...) => (Copy ...)
-(Trunc32to8  ...) => (Copy ...)
-(Trunc32to16 ...) => (Copy ...)
-(Trunc64to8  ...) => (Copy ...)
-(Trunc64to16 ...) => (Copy ...)
-(Trunc64to32 ...) => (Copy ...)
-
-// Shifts
-
-// SLL only considers the bottom 6 bits of y. If y > 64, the result should
-// always be 0.
-//
-// Breaking down the operation:
-//
-// (SLL x y) generates x << (y & 63).
-//
-// If y < 64, this is the value we want. Otherwise, we want zero.
-//
-// So, we AND with -1 * uint64(y < 64), which is 0xfffff... if y < 64 and 0 otherwise.
-(Lsh8x8   <t> x y) => (AND (SLL <t> x y) (Neg8  <t> (SLTIU <t> [64] (ZeroExt8to64  y))))
-(Lsh8x16  <t> x y) => (AND (SLL <t> x y) (Neg8  <t> (SLTIU <t> [64] (ZeroExt16to64 y))))
-(Lsh8x32  <t> x y) => (AND (SLL <t> x y) (Neg8  <t> (SLTIU <t> [64] (ZeroExt32to64 y))))
-(Lsh8x64  <t> x y) => (AND (SLL <t> x y) (Neg8  <t> (SLTIU <t> [64] y)))
-(Lsh16x8  <t> x y) => (AND (SLL <t> x y) (Neg16 <t> (SLTIU <t> [64] (ZeroExt8to64  y))))
-(Lsh16x16 <t> x y) => (AND (SLL <t> x y) (Neg16 <t> (SLTIU <t> [64] (ZeroExt16to64 y))))
-(Lsh16x32 <t> x y) => (AND (SLL <t> x y) (Neg16 <t> (SLTIU <t> [64] (ZeroExt32to64 y))))
-(Lsh16x64 <t> x y) => (AND (SLL <t> x y) (Neg16 <t> (SLTIU <t> [64] y)))
-(Lsh32x8  <t> x y) => (AND (SLL <t> x y) (Neg32 <t> (SLTIU <t> [64] (ZeroExt8to64  y))))
-(Lsh32x16 <t> x y) => (AND (SLL <t> x y) (Neg32 <t> (SLTIU <t> [64] (ZeroExt16to64 y))))
-(Lsh32x32 <t> x y) => (AND (SLL <t> x y) (Neg32 <t> (SLTIU <t> [64] (ZeroExt32to64 y))))
-(Lsh32x64 <t> x y) => (AND (SLL <t> x y) (Neg32 <t> (SLTIU <t> [64] y)))
-(Lsh64x8  <t> x y) => (AND (SLL <t> x y) (Neg64 <t> (SLTIU <t> [64] (ZeroExt8to64  y))))
-(Lsh64x16 <t> x y) => (AND (SLL <t> x y) (Neg64 <t> (SLTIU <t> [64] (ZeroExt16to64 y))))
-(Lsh64x32 <t> x y) => (AND (SLL <t> x y) (Neg64 <t> (SLTIU <t> [64] (ZeroExt32to64 y))))
-(Lsh64x64 <t> x y) => (AND (SLL <t> x y) (Neg64 <t> (SLTIU <t> [64] y)))
-
-// SRL only considers the bottom 6 bits of y. If y > 64, the result should
-// always be 0. See Lsh above for a detailed description.
-(Rsh8Ux8   <t> x y) => (AND (SRL <t> (ZeroExt8to64  x) y) (Neg8  <t> (SLTIU <t> [64] (ZeroExt8to64  y))))
-(Rsh8Ux16  <t> x y) => (AND (SRL <t> (ZeroExt8to64  x) y) (Neg8  <t> (SLTIU <t> [64] (ZeroExt16to64 y))))
-(Rsh8Ux32  <t> x y) => (AND (SRL <t> (ZeroExt8to64  x) y) (Neg8  <t> (SLTIU <t> [64] (ZeroExt32to64 y))))
-(Rsh8Ux64  <t> x y) => (AND (SRL <t> (ZeroExt8to64  x) y) (Neg8  <t> (SLTIU <t> [64] y)))
-(Rsh16Ux8  <t> x y) => (AND (SRL <t> (ZeroExt16to64 x) y) (Neg16 <t> (SLTIU <t> [64] (ZeroExt8to64  y))))
-(Rsh16Ux16 <t> x y) => (AND (SRL <t> (ZeroExt16to64 x) y) (Neg16 <t> (SLTIU <t> [64] (ZeroExt16to64 y))))
-(Rsh16Ux32 <t> x y) => (AND (SRL <t> (ZeroExt16to64 x) y) (Neg16 <t> (SLTIU <t> [64] (ZeroExt32to64 y))))
-(Rsh16Ux64 <t> x y) => (AND (SRL <t> (ZeroExt16to64 x) y) (Neg16 <t> (SLTIU <t> [64] y)))
-(Rsh32Ux8  <t> x y) => (AND (SRL <t> (ZeroExt32to64 x) y) (Neg32 <t> (SLTIU <t> [64] (ZeroExt8to64  y))))
-(Rsh32Ux16 <t> x y) => (AND (SRL <t> (ZeroExt32to64 x) y) (Neg32 <t> (SLTIU <t> [64] (ZeroExt16to64 y))))
-(Rsh32Ux32 <t> x y) => (AND (SRL <t> (ZeroExt32to64 x) y) (Neg32 <t> (SLTIU <t> [64] (ZeroExt32to64 y))))
-(Rsh32Ux64 <t> x y) => (AND (SRL <t> (ZeroExt32to64 x) y) (Neg32 <t> (SLTIU <t> [64] y)))
-(Rsh64Ux8  <t> x y) => (AND (SRL <t> x                 y) (Neg64 <t> (SLTIU <t> [64] (ZeroExt8to64  y))))
-(Rsh64Ux16 <t> x y) => (AND (SRL <t> x                 y) (Neg64 <t> (SLTIU <t> [64] (ZeroExt16to64 y))))
-(Rsh64Ux32 <t> x y) => (AND (SRL <t> x                 y) (Neg64 <t> (SLTIU <t> [64] (ZeroExt32to64 y))))
-(Rsh64Ux64 <t> x y) => (AND (SRL <t> x                 y) (Neg64 <t> (SLTIU <t> [64] y)))
-
-// SRA only considers the bottom 6 bits of y. If y > 64, the result should
-// be either 0 or -1 based on the sign bit.
-//
-// We implement this by performing the max shift (-1) if y >= 64.
-//
-// We OR (uint64(y < 64) - 1) into y before passing it to SRA. This leaves
-// us with -1 (0xffff...) if y >= 64.
-//
-// We don't need to sign-extend the OR result, as it will be at minimum 8 bits,
-// more than the 6 bits SRA cares about.
-(Rsh8x8   <t> x y) => (SRA <t> (SignExt8to64  x) (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] (ZeroExt8to64  y)))))
-(Rsh8x16  <t> x y) => (SRA <t> (SignExt8to64  x) (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] (ZeroExt16to64 y)))))
-(Rsh8x32  <t> x y) => (SRA <t> (SignExt8to64  x) (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] (ZeroExt32to64 y)))))
-(Rsh8x64  <t> x y) => (SRA <t> (SignExt8to64  x) (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] y))))
-(Rsh16x8  <t> x y) => (SRA <t> (SignExt16to64 x) (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] (ZeroExt8to64  y)))))
-(Rsh16x16 <t> x y) => (SRA <t> (SignExt16to64 x) (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] (ZeroExt16to64 y)))))
-(Rsh16x32 <t> x y) => (SRA <t> (SignExt16to64 x) (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] (ZeroExt32to64 y)))))
-(Rsh16x64 <t> x y) => (SRA <t> (SignExt16to64 x) (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] y))))
-(Rsh32x8  <t> x y) => (SRA <t> (SignExt32to64 x) (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] (ZeroExt8to64  y)))))
-(Rsh32x16 <t> x y) => (SRA <t> (SignExt32to64 x) (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] (ZeroExt16to64 y)))))
-(Rsh32x32 <t> x y) => (SRA <t> (SignExt32to64 x) (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] (ZeroExt32to64 y)))))
-(Rsh32x64 <t> x y) => (SRA <t> (SignExt32to64 x) (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] y))))
-(Rsh64x8  <t> x y) => (SRA <t> x                 (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] (ZeroExt8to64  y)))))
-(Rsh64x16 <t> x y) => (SRA <t> x                 (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] (ZeroExt16to64 y)))))
-(Rsh64x32 <t> x y) => (SRA <t> x                 (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] (ZeroExt32to64 y)))))
-(Rsh64x64 <t> x y) => (SRA <t> x                 (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] y))))
-
-// Rotates.
-(RotateLeft8  <t> x (MOVDconst [c])) => (Or8  (Lsh8x64  <t> x (MOVDconst [c&7]))  (Rsh8Ux64  <t> x (MOVDconst [-c&7])))
-(RotateLeft16 <t> x (MOVDconst [c])) => (Or16 (Lsh16x64 <t> x (MOVDconst [c&15])) (Rsh16Ux64 <t> x (MOVDconst [-c&15])))
-(RotateLeft32 <t> x (MOVDconst [c])) => (Or32 (Lsh32x64 <t> x (MOVDconst [c&31])) (Rsh32Ux64 <t> x (MOVDconst [-c&31])))
-(RotateLeft64 <t> x (MOVDconst [c])) => (Or64 (Lsh64x64 <t> x (MOVDconst [c&63])) (Rsh64Ux64 <t> x (MOVDconst [-c&63])))
-
-(Less64  ...) => (SLT  ...)
-(Less32  x y) => (SLT  (SignExt32to64 x) (SignExt32to64 y))
-(Less16  x y) => (SLT  (SignExt16to64 x) (SignExt16to64 y))
-(Less8   x y) => (SLT  (SignExt8to64  x) (SignExt8to64  y))
-(Less64U ...) => (SLTU ...)
-(Less32U x y) => (SLTU (ZeroExt32to64 x) (ZeroExt32to64 y))
-(Less16U x y) => (SLTU (ZeroExt16to64 x) (ZeroExt16to64 y))
-(Less8U  x y) => (SLTU (ZeroExt8to64  x) (ZeroExt8to64  y))
-(Less64F ...) => (FLTD ...)
-(Less32F ...) => (FLTS ...)
-
-// Convert x <= y to !(y > x).
-(Leq64  x y) => (Not (Less64  y x))
-(Leq32  x y) => (Not (Less32  y x))
-(Leq16  x y) => (Not (Less16  y x))
-(Leq8   x y) => (Not (Less8   y x))
-(Leq64U x y) => (Not (Less64U y x))
-(Leq32U x y) => (Not (Less32U y x))
-(Leq16U x y) => (Not (Less16U y x))
-(Leq8U  x y) => (Not (Less8U  y x))
-(Leq64F ...) => (FLED ...)
-(Leq32F ...) => (FLES ...)
-
-(EqPtr x y) => (SEQZ (SUB <typ.Uintptr> x y))
-(Eq64  x y) => (SEQZ (SUB <x.Type> x y))
-(Eq32  x y) => (SEQZ (SUB <x.Type> (ZeroExt32to64 x) (ZeroExt32to64 y)))
-(Eq16  x y) => (SEQZ (SUB <x.Type> (ZeroExt16to64 x) (ZeroExt16to64 y)))
-(Eq8   x y) => (SEQZ (SUB <x.Type> (ZeroExt8to64  x) (ZeroExt8to64  y)))
-(Eq64F ...) => (FEQD ...)
-(Eq32F ...) => (FEQS ...)
-
-(NeqPtr x y) => (SNEZ (SUB <typ.Uintptr> x y))
-(Neq64  x y) => (SNEZ (SUB <x.Type> x y))
-(Neq32  x y) => (SNEZ (SUB <x.Type> (ZeroExt32to64 x) (ZeroExt32to64 y)))
-(Neq16  x y) => (SNEZ (SUB <x.Type> (ZeroExt16to64 x) (ZeroExt16to64 y)))
-(Neq8   x y) => (SNEZ (SUB <x.Type> (ZeroExt8to64  x) (ZeroExt8to64  y)))
-(Neq64F ...) => (FNED ...)
-(Neq32F ...) => (FNES ...)
-
-// Loads
-(Load <t> ptr mem) &&  t.IsBoolean()                  => (MOVBUload ptr mem)
-(Load <t> ptr mem) && ( is8BitInt(t) &&  isSigned(t)) => (MOVBload  ptr mem)
-(Load <t> ptr mem) && ( is8BitInt(t) && !isSigned(t)) => (MOVBUload ptr mem)
-(Load <t> ptr mem) && (is16BitInt(t) &&  isSigned(t)) => (MOVHload  ptr mem)
-(Load <t> ptr mem) && (is16BitInt(t) && !isSigned(t)) => (MOVHUload ptr mem)
-(Load <t> ptr mem) && (is32BitInt(t) &&  isSigned(t)) => (MOVWload  ptr mem)
-(Load <t> ptr mem) && (is32BitInt(t) && !isSigned(t)) => (MOVWUload ptr mem)
-(Load <t> ptr mem) && (is64BitInt(t) || isPtr(t))     => (MOVDload  ptr mem)
-(Load <t> ptr mem) &&  is32BitFloat(t)                => (FMOVWload ptr mem)
-(Load <t> ptr mem) &&  is64BitFloat(t)                => (FMOVDload ptr mem)
-
-// Stores
-(Store {t} ptr val mem) && t.Size() == 1 => (MOVBstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 2 => (MOVHstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 4 && !is32BitFloat(val.Type) => (MOVWstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 8 && !is64BitFloat(val.Type) => (MOVDstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 4 &&  is32BitFloat(val.Type) => (FMOVWstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 8 &&  is64BitFloat(val.Type) => (FMOVDstore ptr val mem)
-
-// We need to fold MOVaddr into the LD/MOVDstore ops so that the live variable analysis
-// knows what variables are being read/written by the ops.
-(MOVBUload [off1] {sym1} (MOVaddr [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-	(MOVBUload [off1+off2] {mergeSym(sym1,sym2)} base mem)
-(MOVBload  [off1] {sym1} (MOVaddr [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-	(MOVBload  [off1+off2] {mergeSym(sym1,sym2)} base mem)
-(MOVHUload [off1] {sym1} (MOVaddr [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-	(MOVHUload [off1+off2] {mergeSym(sym1,sym2)} base mem)
-(MOVHload  [off1] {sym1} (MOVaddr [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-	(MOVHload  [off1+off2] {mergeSym(sym1,sym2)} base mem)
-(MOVWUload [off1] {sym1} (MOVaddr [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-	(MOVWUload [off1+off2] {mergeSym(sym1,sym2)} base mem)
-(MOVWload  [off1] {sym1} (MOVaddr [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-	(MOVWload  [off1+off2] {mergeSym(sym1,sym2)} base mem)
-(MOVDload  [off1] {sym1} (MOVaddr [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-	(MOVDload  [off1+off2] {mergeSym(sym1,sym2)} base mem)
-
-(MOVBstore [off1] {sym1} (MOVaddr [off2] {sym2} base) val mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-	(MOVBstore [off1+off2] {mergeSym(sym1,sym2)} base val mem)
-(MOVHstore [off1] {sym1} (MOVaddr [off2] {sym2} base) val mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-	(MOVHstore [off1+off2] {mergeSym(sym1,sym2)} base val mem)
-(MOVWstore [off1] {sym1} (MOVaddr [off2] {sym2} base) val mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-	(MOVWstore [off1+off2] {mergeSym(sym1,sym2)} base val mem)
-(MOVDstore [off1] {sym1} (MOVaddr [off2] {sym2} base) val mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-	(MOVDstore [off1+off2] {mergeSym(sym1,sym2)} base val mem)
-(MOVBstorezero [off1] {sym1} (MOVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVBstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-(MOVHstorezero [off1] {sym1} (MOVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVHstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-(MOVWstorezero [off1] {sym1} (MOVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVWstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-(MOVDstorezero [off1] {sym1} (MOVaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) =>
-	(MOVDstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
-
-(MOVBUload [off1] {sym} (ADDI [off2] base) mem) && is32Bit(int64(off1)+off2) =>
-	(MOVBUload [off1+int32(off2)] {sym} base mem)
-(MOVBload  [off1] {sym} (ADDI [off2] base) mem) && is32Bit(int64(off1)+off2) =>
-	(MOVBload  [off1+int32(off2)] {sym} base mem)
-(MOVHUload [off1] {sym} (ADDI [off2] base) mem) && is32Bit(int64(off1)+off2) =>
-	(MOVHUload [off1+int32(off2)] {sym} base mem)
-(MOVHload  [off1] {sym} (ADDI [off2] base) mem) && is32Bit(int64(off1)+off2) =>
-	(MOVHload  [off1+int32(off2)] {sym} base mem)
-(MOVWUload [off1] {sym} (ADDI [off2] base) mem) && is32Bit(int64(off1)+off2) =>
-	(MOVWUload [off1+int32(off2)] {sym} base mem)
-(MOVWload  [off1] {sym} (ADDI [off2] base) mem) && is32Bit(int64(off1)+off2) =>
-	(MOVWload  [off1+int32(off2)] {sym} base mem)
-(MOVDload  [off1] {sym} (ADDI [off2] base) mem) && is32Bit(int64(off1)+off2) =>
-	(MOVDload  [off1+int32(off2)] {sym} base mem)
-
-(MOVBstore [off1] {sym} (ADDI [off2] base) val mem) && is32Bit(int64(off1)+off2) =>
-	(MOVBstore [off1+int32(off2)] {sym} base val mem)
-(MOVHstore [off1] {sym} (ADDI [off2] base) val mem) && is32Bit(int64(off1)+off2) =>
-	(MOVHstore [off1+int32(off2)] {sym} base val mem)
-(MOVWstore [off1] {sym} (ADDI [off2] base) val mem) && is32Bit(int64(off1)+off2) =>
-	(MOVWstore [off1+int32(off2)] {sym} base val mem)
-(MOVDstore [off1] {sym} (ADDI [off2] base) val mem) && is32Bit(int64(off1)+off2) =>
-	(MOVDstore [off1+int32(off2)] {sym} base val mem)
-(MOVBstorezero [off1] {sym} (ADDI [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVBstorezero [off1+int32(off2)] {sym} ptr mem)
-(MOVHstorezero [off1] {sym} (ADDI [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVHstorezero [off1+int32(off2)] {sym} ptr mem)
-(MOVWstorezero [off1] {sym} (ADDI [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVWstorezero [off1+int32(off2)] {sym} ptr mem)
-(MOVDstorezero [off1] {sym} (ADDI [off2] ptr) mem) && is32Bit(int64(off1)+off2) => (MOVDstorezero [off1+int32(off2)] {sym} ptr mem)
-
-// Similarly, fold ADDI into MOVaddr to avoid confusing live variable analysis
-// with OffPtr -> ADDI.
-(ADDI [c] (MOVaddr [d] {s} x)) && is32Bit(c+int64(d)) => (MOVaddr [int32(c)+d] {s} x)
-
-// Small zeroing
-(Zero [0] _ mem) => mem
-(Zero [1] ptr mem) => (MOVBstore ptr (MOVDconst [0]) mem)
-(Zero [2] {t} ptr mem) && t.Alignment()%2 == 0 =>
-	(MOVHstore ptr (MOVDconst [0]) mem)
-(Zero [2] ptr mem) =>
-	(MOVBstore [1] ptr (MOVDconst [0])
-		(MOVBstore ptr (MOVDconst [0]) mem))
-(Zero [4] {t} ptr mem) && t.Alignment()%4 == 0 =>
-	(MOVWstore ptr (MOVDconst [0]) mem)
-(Zero [4] {t} ptr mem) && t.Alignment()%2 == 0 =>
-	(MOVHstore [2] ptr (MOVDconst [0])
-		(MOVHstore ptr (MOVDconst [0]) mem))
-(Zero [4] ptr mem) =>
-	(MOVBstore [3] ptr (MOVDconst [0])
-		(MOVBstore [2] ptr (MOVDconst [0])
-			(MOVBstore [1] ptr (MOVDconst [0])
-				(MOVBstore ptr (MOVDconst [0]) mem))))
-(Zero [8] {t} ptr mem) && t.Alignment()%8 == 0 =>
-	(MOVDstore ptr (MOVDconst [0]) mem)
-(Zero [8] {t} ptr mem) && t.Alignment()%4 == 0 =>
-	(MOVWstore [4] ptr (MOVDconst [0])
-		(MOVWstore ptr (MOVDconst [0]) mem))
-(Zero [8] {t} ptr mem) && t.Alignment()%2 == 0 =>
-	(MOVHstore [6] ptr (MOVDconst [0])
-		(MOVHstore [4] ptr (MOVDconst [0])
-			(MOVHstore [2] ptr (MOVDconst [0])
-				(MOVHstore ptr (MOVDconst [0]) mem))))
-
-(Zero [3] ptr mem) =>
-	(MOVBstore [2] ptr (MOVDconst [0])
-		(MOVBstore [1] ptr (MOVDconst [0])
-			(MOVBstore ptr (MOVDconst [0]) mem)))
-(Zero [6] {t} ptr mem) && t.Alignment()%2 == 0 =>
-	(MOVHstore [4] ptr (MOVDconst [0])
-		(MOVHstore [2] ptr (MOVDconst [0])
-			(MOVHstore ptr (MOVDconst [0]) mem)))
-(Zero [12] {t} ptr mem) && t.Alignment()%4 == 0 =>
-	(MOVWstore [8] ptr (MOVDconst [0])
-		(MOVWstore [4] ptr (MOVDconst [0])
-			(MOVWstore ptr (MOVDconst [0]) mem)))
-(Zero [16] {t} ptr mem) && t.Alignment()%8 == 0 =>
-	(MOVDstore [8] ptr (MOVDconst [0])
-		(MOVDstore ptr (MOVDconst [0]) mem))
-(Zero [24] {t} ptr mem) && t.Alignment()%8 == 0 =>
-	(MOVDstore [16] ptr (MOVDconst [0])
-		(MOVDstore [8] ptr (MOVDconst [0])
-			(MOVDstore ptr (MOVDconst [0]) mem)))
-(Zero [32] {t} ptr mem) && t.Alignment()%8 == 0 =>
-	(MOVDstore [24] ptr (MOVDconst [0])
-		(MOVDstore [16] ptr (MOVDconst [0])
-			(MOVDstore [8] ptr (MOVDconst [0])
-				(MOVDstore ptr (MOVDconst [0]) mem))))
-
-// Medium 8-aligned zeroing uses a Duff's device
-// 8 and 128 are magic constants, see runtime/mkduff.go
-(Zero [s] {t} ptr mem)
-	&& s%8 == 0 && s <= 8*128
-	&& t.Alignment()%8 == 0 && !config.noDuffDevice =>
-	(DUFFZERO [8 * (128 - s/8)] ptr mem)
-
-// Generic zeroing uses a loop
-(Zero [s] {t} ptr mem) =>
-	(LoweredZero [t.Alignment()]
-		ptr
-		(ADD <ptr.Type> ptr (MOVDconst [s-moveSize(t.Alignment(), config)]))
-		mem)
-
-(Convert ...) => (MOVconvert ...)
-
-// Checks
-(IsNonNil ...) => (SNEZ ...)
-(IsInBounds ...) => (Less64U ...)
-(IsSliceInBounds ...) => (Leq64U ...)
-
-// Trivial lowering
-(NilCheck ...) => (LoweredNilCheck ...)
-(GetClosurePtr ...) => (LoweredGetClosurePtr ...)
-(GetCallerSP ...) => (LoweredGetCallerSP ...)
-(GetCallerPC ...) => (LoweredGetCallerPC ...)
-
-// Write barrier.
-(WB ...) => (LoweredWB ...)
-
-(PanicBounds [kind] x y mem) && boundsABI(kind) == 0 => (LoweredPanicBoundsA [kind] x y mem)
-(PanicBounds [kind] x y mem) && boundsABI(kind) == 1 => (LoweredPanicBoundsB [kind] x y mem)
-(PanicBounds [kind] x y mem) && boundsABI(kind) == 2 => (LoweredPanicBoundsC [kind] x y mem)
-
-// Small moves
-(Move [0] _ _ mem) => mem
-(Move [1] dst src mem) => (MOVBstore dst (MOVBload src mem) mem)
-(Move [2] {t} dst src mem) && t.Alignment()%2 == 0 =>
-	(MOVHstore dst (MOVHload src mem) mem)
-(Move [2] dst src mem) =>
-	(MOVBstore [1] dst (MOVBload [1] src mem)
-		(MOVBstore dst (MOVBload src mem) mem))
-(Move [4] {t} dst src mem) && t.Alignment()%4 == 0 =>
-	(MOVWstore dst (MOVWload src mem) mem)
-(Move [4] {t} dst src mem) && t.Alignment()%2 == 0 =>
-	(MOVHstore [2] dst (MOVHload [2] src mem)
-		(MOVHstore dst (MOVHload src mem) mem))
-(Move [4] dst src mem) =>
-	(MOVBstore [3] dst (MOVBload [3] src mem)
-		(MOVBstore [2] dst (MOVBload [2] src mem)
-			(MOVBstore [1] dst (MOVBload [1] src mem)
-				(MOVBstore dst (MOVBload src mem) mem))))
-(Move [8] {t} dst src mem) && t.Alignment()%8 == 0 =>
-	(MOVDstore dst (MOVDload src mem) mem)
-(Move [8] {t} dst src mem) && t.Alignment()%4 == 0 =>
-	(MOVWstore [4] dst (MOVWload [4] src mem)
-		(MOVWstore dst (MOVWload src mem) mem))
-(Move [8] {t} dst src mem) && t.Alignment()%2 == 0 =>
-	(MOVHstore [6] dst (MOVHload [6] src mem)
-		(MOVHstore [4] dst (MOVHload [4] src mem)
-			(MOVHstore [2] dst (MOVHload [2] src mem)
-				(MOVHstore dst (MOVHload src mem) mem))))
-
-(Move [3] dst src mem) =>
-	(MOVBstore [2] dst (MOVBload [2] src mem)
-		(MOVBstore [1] dst (MOVBload [1] src mem)
-			(MOVBstore dst (MOVBload src mem) mem)))
-(Move [6] {t} dst src mem) && t.Alignment()%2 == 0 =>
-	(MOVHstore [4] dst (MOVHload [4] src mem)
-		(MOVHstore [2] dst (MOVHload [2] src mem)
-			(MOVHstore dst (MOVHload src mem) mem)))
-(Move [12] {t} dst src mem) && t.Alignment()%4 == 0 =>
-	(MOVWstore [8] dst (MOVWload [8] src mem)
-		(MOVWstore [4] dst (MOVWload [4] src mem)
-			(MOVWstore dst (MOVWload src mem) mem)))
-(Move [16] {t} dst src mem) && t.Alignment()%8 == 0 =>
-	(MOVDstore [8] dst (MOVDload [8] src mem)
-		(MOVDstore dst (MOVDload src mem) mem))
-(Move [24] {t} dst src mem) && t.Alignment()%8 == 0 =>
-	(MOVDstore [16] dst (MOVDload [16] src mem)
-		(MOVDstore [8] dst (MOVDload [8] src mem)
-			(MOVDstore dst (MOVDload src mem) mem)))
-(Move [32] {t} dst src mem) && t.Alignment()%8 == 0 =>
-	(MOVDstore [24] dst (MOVDload [24] src mem)
-		(MOVDstore [16] dst (MOVDload [16] src mem)
-			(MOVDstore [8] dst (MOVDload [8] src mem)
-				(MOVDstore dst (MOVDload src mem) mem))))
-
-// Medium 8-aligned move uses a Duff's device
-// 16 and 128 are magic constants, see runtime/mkduff.go
-(Move [s] {t} dst src mem)
-	&& s%8 == 0 && s <= 8*128 && t.Alignment()%8 == 0
-	&& !config.noDuffDevice && logLargeCopy(v, s) =>
-	(DUFFCOPY [16 * (128 - s/8)] dst src mem)
-
-// Generic move uses a loop
-(Move [s] {t} dst src mem) && (s <= 16 || logLargeCopy(v, s)) =>
-	(LoweredMove [t.Alignment()]
-		dst
-		src
-		(ADDI <src.Type> [s-moveSize(t.Alignment(), config)] src)
-		mem)
-
-// Boolean ops; 0=false, 1=true
-(AndB ...) => (AND ...)
-(OrB  ...) => (OR  ...)
-(EqB  x y) => (SEQZ (XOR <typ.Bool> x y))
-(NeqB ...) => (XOR ...)
-(Not  ...) => (SEQZ ...)
-
-// Lowering pointer arithmetic
-// TODO: Special handling for SP offsets, like ARM
-(OffPtr [off] ptr:(SP)) && is32Bit(off) => (MOVaddr [int32(off)] ptr)
-(OffPtr [off] ptr) && is32Bit(off) => (ADDI [off] ptr)
-(OffPtr [off] ptr) => (ADD (MOVDconst [off]) ptr)
-
-(Const8  [val]) => (MOVDconst [int64(val)])
-(Const16 [val]) => (MOVDconst [int64(val)])
-(Const32 [val]) => (MOVDconst [int64(val)])
-(Const64 [val]) => (MOVDconst [int64(val)])
-(Const32F [val]) => (FMVSX (MOVDconst [int64(math.Float32bits(val))]))
-(Const64F [val]) => (FMVDX (MOVDconst [int64(math.Float64bits(val))]))
-(ConstNil) => (MOVDconst [0])
-(ConstBool [val]) => (MOVDconst [int64(b2i(val))])
-
-(Addr {sym} base) => (MOVaddr {sym} [0] base)
-(LocalAddr {sym} base _) => (MOVaddr {sym} base)
-
-// Calls
-(StaticCall  ...) => (CALLstatic  ...)
-(ClosureCall ...) => (CALLclosure ...)
-(InterCall   ...) => (CALLinter   ...)
-(TailCall ...) => (CALLtail ...)
-
-// Atomic Intrinsics
-(AtomicLoad8   ...) => (LoweredAtomicLoad8  ...)
-(AtomicLoad32  ...) => (LoweredAtomicLoad32 ...)
-(AtomicLoad64  ...) => (LoweredAtomicLoad64 ...)
-(AtomicLoadPtr ...) => (LoweredAtomicLoad64 ...)
-
-(AtomicStore8       ...) => (LoweredAtomicStore8  ...)
-(AtomicStore32      ...) => (LoweredAtomicStore32 ...)
-(AtomicStore64      ...) => (LoweredAtomicStore64 ...)
-(AtomicStorePtrNoWB ...) => (LoweredAtomicStore64 ...)
-
-(AtomicAdd32 ...) => (LoweredAtomicAdd32 ...)
-(AtomicAdd64 ...) => (LoweredAtomicAdd64 ...)
-
-// AtomicAnd8(ptr,val) => LoweredAtomicAnd32(ptr&^3, ^((uint8(val) ^ 0xff) << ((ptr & 3) * 8)))
-(AtomicAnd8 ptr val mem) =>
-	(LoweredAtomicAnd32 (ANDI <typ.Uintptr> [^3] ptr)
-		(NOT <typ.UInt32> (SLL <typ.UInt32> (XORI <typ.UInt32> [0xff] (ZeroExt8to32 val))
-			(SLLI <typ.UInt64> [3] (ANDI <typ.UInt64> [3] ptr)))) mem)
-
-(AtomicAnd32 ...) => (LoweredAtomicAnd32 ...)
-
-(AtomicCompareAndSwap32 ...) => (LoweredAtomicCas32 ...)
-(AtomicCompareAndSwap64 ...) => (LoweredAtomicCas64 ...)
-
-(AtomicExchange32 ...) => (LoweredAtomicExchange32 ...)
-(AtomicExchange64 ...) => (LoweredAtomicExchange64 ...)
-
-// AtomicOr8(ptr,val)  => LoweredAtomicOr32(ptr&^3, uint32(val)<<((ptr&3)*8))
-(AtomicOr8 ptr val mem) =>
-	(LoweredAtomicOr32 (ANDI <typ.Uintptr> [^3] ptr)
-		(SLL <typ.UInt32> (ZeroExt8to32 val)
-			(SLLI <typ.UInt64> [3] (ANDI <typ.UInt64> [3] ptr))) mem)
-
-(AtomicOr32  ...) => (LoweredAtomicOr32  ...)
-
-// Conditional branches
-(If cond yes no) => (BNEZ (MOVBUreg <typ.UInt64> cond) yes no)
-
-// Optimizations
-
-// Absorb SEQZ/SNEZ into branch.
-(BEQZ (SEQZ x) yes no) => (BNEZ x yes no)
-(BEQZ (SNEZ x) yes no) => (BEQZ x yes no)
-(BNEZ (SEQZ x) yes no) => (BEQZ x yes no)
-(BNEZ (SNEZ x) yes no) => (BNEZ x yes no)
-
-// Absorb NEG into branch when possible.
-(BEQZ x:(NEG y) yes no) && x.Uses == 1 => (BEQZ y yes no)
-(BNEZ x:(NEG y) yes no) && x.Uses == 1 => (BNEZ y yes no)
-
-// Convert BEQZ/BNEZ into more optimal branch conditions.
-(BEQZ (SUB x y) yes no) => (BEQ x y yes no)
-(BNEZ (SUB x y) yes no) => (BNE x y yes no)
-(BEQZ (SLT x y) yes no) => (BGE x y yes no)
-(BNEZ (SLT x y) yes no) => (BLT x y yes no)
-(BEQZ (SLTU x y) yes no) => (BGEU x y yes no)
-(BNEZ (SLTU x y) yes no) => (BLTU x y yes no)
-
-// Convert branch with zero to more optimal branch zero.
-(BEQ (MOVDconst [0]) cond yes no) => (BEQZ cond yes no)
-(BEQ cond (MOVDconst [0]) yes no) => (BEQZ cond yes no)
-(BNE (MOVDconst [0]) cond yes no) => (BNEZ cond yes no)
-(BNE cond (MOVDconst [0]) yes no) => (BNEZ cond yes no)
-(BLT (MOVDconst [0]) cond yes no) => (BGTZ cond yes no)
-(BLT cond (MOVDconst [0]) yes no) => (BLTZ cond yes no)
-(BGE (MOVDconst [0]) cond yes no) => (BLEZ cond yes no)
-(BGE cond (MOVDconst [0]) yes no) => (BGEZ cond yes no)
-
-// Store zero
-(MOVBstore [off] {sym} ptr (MOVDconst [0]) mem) => (MOVBstorezero [off] {sym} ptr mem)
-(MOVHstore [off] {sym} ptr (MOVDconst [0]) mem) => (MOVHstorezero [off] {sym} ptr mem)
-(MOVWstore [off] {sym} ptr (MOVDconst [0]) mem) => (MOVWstorezero [off] {sym} ptr mem)
-(MOVDstore [off] {sym} ptr (MOVDconst [0]) mem) => (MOVDstorezero [off] {sym} ptr mem)
-
-// Boolean ops are already extended.
-(MOVBUreg x:((SEQZ|SNEZ) _)) => x
-(MOVBUreg x:((SLT|SLTU) _ _)) => x
-
-// Avoid sign/zero extension for consts.
-(MOVBreg  (MOVDconst [c])) => (MOVDconst [int64(int8(c))])
-(MOVHreg  (MOVDconst [c])) => (MOVDconst [int64(int16(c))])
-(MOVWreg  (MOVDconst [c])) => (MOVDconst [int64(int32(c))])
-(MOVBUreg (MOVDconst [c])) => (MOVDconst [int64(uint8(c))])
-(MOVHUreg (MOVDconst [c])) => (MOVDconst [int64(uint16(c))])
-(MOVWUreg (MOVDconst [c])) => (MOVDconst [int64(uint32(c))])
-
-// Avoid sign/zero extension after properly typed load.
-(MOVBreg  x:(MOVBload  _ _)) => (MOVDreg x)
-(MOVHreg  x:(MOVBload  _ _)) => (MOVDreg x)
-(MOVHreg  x:(MOVBUload _ _)) => (MOVDreg x)
-(MOVHreg  x:(MOVHload  _ _)) => (MOVDreg x)
-(MOVWreg  x:(MOVBload  _ _)) => (MOVDreg x)
-(MOVWreg  x:(MOVBUload _ _)) => (MOVDreg x)
-(MOVWreg  x:(MOVHload  _ _)) => (MOVDreg x)
-(MOVWreg  x:(MOVHUload _ _)) => (MOVDreg x)
-(MOVWreg  x:(MOVWload  _ _)) => (MOVDreg x)
-(MOVBUreg x:(MOVBUload _ _)) => (MOVDreg x)
-(MOVHUreg x:(MOVBUload _ _)) => (MOVDreg x)
-(MOVHUreg x:(MOVHUload _ _)) => (MOVDreg x)
-(MOVWUreg x:(MOVBUload _ _)) => (MOVDreg x)
-(MOVWUreg x:(MOVHUload _ _)) => (MOVDreg x)
-(MOVWUreg x:(MOVWUload _ _)) => (MOVDreg x)
-
-// Fold double extensions.
-(MOVBreg  x:(MOVBreg  _)) => (MOVDreg x)
-(MOVHreg  x:(MOVBreg  _)) => (MOVDreg x)
-(MOVHreg  x:(MOVBUreg _)) => (MOVDreg x)
-(MOVHreg  x:(MOVHreg  _)) => (MOVDreg x)
-(MOVWreg  x:(MOVBreg  _)) => (MOVDreg x)
-(MOVWreg  x:(MOVBUreg _)) => (MOVDreg x)
-(MOVWreg  x:(MOVHreg  _)) => (MOVDreg x)
-(MOVWreg  x:(MOVWreg  _)) => (MOVDreg x)
-(MOVBUreg x:(MOVBUreg _)) => (MOVDreg x)
-(MOVHUreg x:(MOVBUreg _)) => (MOVDreg x)
-(MOVHUreg x:(MOVHUreg _)) => (MOVDreg x)
-(MOVWUreg x:(MOVBUreg _)) => (MOVDreg x)
-(MOVWUreg x:(MOVHUreg _)) => (MOVDreg x)
-(MOVWUreg x:(MOVWUreg _)) => (MOVDreg x)
-
-// Do not extend before store.
-(MOVBstore [off] {sym} ptr (MOVBreg  x) mem) => (MOVBstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr (MOVHreg  x) mem) => (MOVBstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr (MOVWreg  x) mem) => (MOVBstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr (MOVBUreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr (MOVHUreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr (MOVWUreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
-(MOVHstore [off] {sym} ptr (MOVHreg  x) mem) => (MOVHstore [off] {sym} ptr x mem)
-(MOVHstore [off] {sym} ptr (MOVWreg  x) mem) => (MOVHstore [off] {sym} ptr x mem)
-(MOVHstore [off] {sym} ptr (MOVHUreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
-(MOVHstore [off] {sym} ptr (MOVWUreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
-(MOVWstore [off] {sym} ptr (MOVWreg  x) mem) => (MOVWstore [off] {sym} ptr x mem)
-(MOVWstore [off] {sym} ptr (MOVWUreg x) mem) => (MOVWstore [off] {sym} ptr x mem)
-
-// Replace extend after load with alternate load where possible.
-(MOVBreg  <t> x:(MOVBUload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVBload  <t> [off] {sym} ptr mem)
-(MOVHreg  <t> x:(MOVHUload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVHload  <t> [off] {sym} ptr mem)
-(MOVWreg  <t> x:(MOVWUload [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVWload  <t> [off] {sym} ptr mem)
-(MOVBUreg <t> x:(MOVBload  [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVBUload <t> [off] {sym} ptr mem)
-(MOVHUreg <t> x:(MOVHload  [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVHUload <t> [off] {sym} ptr mem)
-(MOVWUreg <t> x:(MOVWload  [off] {sym} ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (MOVWUload <t> [off] {sym} ptr mem)
-
-// If a register move has only 1 use, just use the same register without emitting instruction
-// MOVnop does not emit an instruction, only for ensuring the type.
-(MOVDreg x) && x.Uses == 1 => (MOVDnop x)
-
-// TODO: we should be able to get rid of MOVDnop all together.
-// But for now, this is enough to get rid of lots of them.
-(MOVDnop (MOVDconst [c])) => (MOVDconst [c])
-
-// Fold constant into immediate instructions where possible.
-(ADD (MOVDconst [val]) x) && is32Bit(val) => (ADDI [val] x)
-(AND (MOVDconst [val]) x) && is32Bit(val) => (ANDI [val] x)
-(OR  (MOVDconst [val]) x) && is32Bit(val) => (ORI  [val] x)
-(XOR (MOVDconst [val]) x) && is32Bit(val) => (XORI [val] x)
-(SLL x (MOVDconst [val])) => (SLLI [int64(val&63)] x)
-(SRL x (MOVDconst [val])) => (SRLI [int64(val&63)] x)
-(SRA x (MOVDconst [val])) => (SRAI [int64(val&63)] x)
-
-// Convert subtraction of a const into ADDI with negative immediate, where possible.
-(SUB x (MOVDconst [val])) && is32Bit(-val) => (ADDI [-val] x)
-
-// Subtraction of zero.
-(SUB  x (MOVDconst [0])) => x
-(SUBW x (MOVDconst [0])) => (ADDIW [0] x)
-
-// Subtraction from zero.
-(SUB  (MOVDconst [0]) x) => (NEG x)
-(SUBW (MOVDconst [0]) x) => (NEGW x)
-
-// Addition of zero or two constants.
-(ADDI [0] x) => x
-(ADDI [x] (MOVDconst [y])) && is32Bit(x + y) => (MOVDconst [x + y])
-
-// ANDI with all zeros, all ones or two constants.
-(ANDI [0]  x) => (MOVDconst [0])
-(ANDI [-1] x) => x
-(ANDI [x] (MOVDconst [y])) => (MOVDconst [x & y])
-
-// ORI with all zeroes, all ones or two constants.
-(ORI [0]  x) => x
-(ORI [-1] x) => (MOVDconst [-1])
-(ORI [x] (MOVDconst [y])) => (MOVDconst [x | y])
-
-// Negation of a constant.
-(NEG  (MOVDconst [x])) => (MOVDconst [-x])
-(NEGW (MOVDconst [x])) => (MOVDconst [int64(int32(-x))])
-
-// Shift of a constant.
-(SLLI [x] (MOVDconst [y])) && is32Bit(y << uint32(x)) => (MOVDconst [y << uint32(x)])
-(SRLI [x] (MOVDconst [y])) => (MOVDconst [int64(uint64(y) >> uint32(x))])
-(SRAI [x] (MOVDconst [y])) => (MOVDconst [int64(y) >> uint32(x)])
-
-// SLTI/SLTIU with constants.
-(SLTI  [x] (MOVDconst [y])) => (MOVDconst [b2i(int64(y) < int64(x))])
-(SLTIU [x] (MOVDconst [y])) => (MOVDconst [b2i(uint64(y) < uint64(x))])
-
-// Merge negation into fused multiply-add and multiply-subtract.
-//
-// Key:
-//
-//   [+ -](x * y) [+ -] z.
-//    _ N          A S
-//                 D U
-//                 D B
-//
-// Note: multiplication commutativity handled by rule generator.
-(F(MADD|NMADD|MSUB|NMSUB)D neg:(FNEGD x) y z) && neg.Uses == 1 => (F(NMADD|MADD|NMSUB|MSUB)D x y z)
-(F(MADD|NMADD|MSUB|NMSUB)D x y neg:(FNEGD z)) && neg.Uses == 1 => (F(MSUB|NMSUB|MADD|NMADD)D x y z)
diff --git a/src/cmd/compile/internal/ssa/gen/RISCV64Ops.go b/src/cmd/compile/internal/ssa/gen/RISCV64Ops.go
deleted file mode 100644
index f099107..0000000
--- a/src/cmd/compile/internal/ssa/gen/RISCV64Ops.go
+++ /dev/null
@@ -1,485 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build ignore
-// +build ignore
-
-package main
-
-import (
-	"fmt"
-)
-
-// Notes:
-//  - Boolean types occupy the entire register. 0=false, 1=true.
-
-// Suffixes encode the bit width of various instructions:
-//
-// D (double word) = 64 bit int
-// W (word)        = 32 bit int
-// H (half word)   = 16 bit int
-// B (byte)        = 8 bit int
-// S (single)      = 32 bit float
-// D (double)      = 64 bit float
-// L               = 64 bit int, used when the opcode starts with F
-
-const (
-	riscv64REG_G    = 27
-	riscv64REG_CTXT = 26
-	riscv64REG_LR   = 1
-	riscv64REG_SP   = 2
-	riscv64REG_GP   = 3
-	riscv64REG_TP   = 4
-	riscv64REG_TMP  = 31
-	riscv64REG_ZERO = 0
-)
-
-func riscv64RegName(r int) string {
-	switch {
-	case r == riscv64REG_G:
-		return "g"
-	case r == riscv64REG_SP:
-		return "SP"
-	case 0 <= r && r <= 31:
-		return fmt.Sprintf("X%d", r)
-	case 32 <= r && r <= 63:
-		return fmt.Sprintf("F%d", r-32)
-	default:
-		panic(fmt.Sprintf("unknown register %d", r))
-	}
-}
-
-func init() {
-	var regNamesRISCV64 []string
-	var gpMask, fpMask, gpgMask, gpspMask, gpspsbMask, gpspsbgMask regMask
-	regNamed := make(map[string]regMask)
-
-	// Build the list of register names, creating an appropriately indexed
-	// regMask for the gp and fp registers as we go.
-	//
-	// If name is specified, use it rather than the riscv reg number.
-	addreg := func(r int, name string) regMask {
-		mask := regMask(1) << uint(len(regNamesRISCV64))
-		if name == "" {
-			name = riscv64RegName(r)
-		}
-		regNamesRISCV64 = append(regNamesRISCV64, name)
-		regNamed[name] = mask
-		return mask
-	}
-
-	// General purpose registers.
-	for r := 0; r <= 31; r++ {
-		if r == riscv64REG_LR {
-			// LR is not used by regalloc, so we skip it to leave
-			// room for pseudo-register SB.
-			continue
-		}
-
-		mask := addreg(r, "")
-
-		// Add general purpose registers to gpMask.
-		switch r {
-		// ZERO, GP, TP and TMP are not in any gp mask.
-		case riscv64REG_ZERO, riscv64REG_GP, riscv64REG_TP, riscv64REG_TMP:
-		case riscv64REG_G:
-			gpgMask |= mask
-			gpspsbgMask |= mask
-		case riscv64REG_SP:
-			gpspMask |= mask
-			gpspsbMask |= mask
-			gpspsbgMask |= mask
-		default:
-			gpMask |= mask
-			gpgMask |= mask
-			gpspMask |= mask
-			gpspsbMask |= mask
-			gpspsbgMask |= mask
-		}
-	}
-
-	// Floating pointer registers.
-	for r := 32; r <= 63; r++ {
-		mask := addreg(r, "")
-		fpMask |= mask
-	}
-
-	// Pseudo-register: SB
-	mask := addreg(-1, "SB")
-	gpspsbMask |= mask
-	gpspsbgMask |= mask
-
-	if len(regNamesRISCV64) > 64 {
-		// regMask is only 64 bits.
-		panic("Too many RISCV64 registers")
-	}
-
-	regCtxt := regNamed["X26"]
-	callerSave := gpMask | fpMask | regNamed["g"]
-
-	var (
-		gpstore  = regInfo{inputs: []regMask{gpspsbMask, gpspMask, 0}} // SB in first input so we can load from a global, but not in second to avoid using SB as a temporary register
-		gpstore0 = regInfo{inputs: []regMask{gpspsbMask}}
-		gp01     = regInfo{outputs: []regMask{gpMask}}
-		gp11     = regInfo{inputs: []regMask{gpMask}, outputs: []regMask{gpMask}}
-		gp21     = regInfo{inputs: []regMask{gpMask, gpMask}, outputs: []regMask{gpMask}}
-		gp22     = regInfo{inputs: []regMask{gpMask, gpMask}, outputs: []regMask{gpMask, gpMask}}
-		gpload   = regInfo{inputs: []regMask{gpspsbMask, 0}, outputs: []regMask{gpMask}}
-		gp11sb   = regInfo{inputs: []regMask{gpspsbMask}, outputs: []regMask{gpMask}}
-		gpxchg   = regInfo{inputs: []regMask{gpspsbgMask, gpgMask}, outputs: []regMask{gpMask}}
-		gpcas    = regInfo{inputs: []regMask{gpspsbgMask, gpgMask, gpgMask}, outputs: []regMask{gpMask}}
-		gpatomic = regInfo{inputs: []regMask{gpspsbgMask, gpgMask}}
-
-		fp11    = regInfo{inputs: []regMask{fpMask}, outputs: []regMask{fpMask}}
-		fp21    = regInfo{inputs: []regMask{fpMask, fpMask}, outputs: []regMask{fpMask}}
-		fp31    = regInfo{inputs: []regMask{fpMask, fpMask, fpMask}, outputs: []regMask{fpMask}}
-		gpfp    = regInfo{inputs: []regMask{gpMask}, outputs: []regMask{fpMask}}
-		fpgp    = regInfo{inputs: []regMask{fpMask}, outputs: []regMask{gpMask}}
-		fpstore = regInfo{inputs: []regMask{gpspsbMask, fpMask, 0}}
-		fpload  = regInfo{inputs: []regMask{gpspsbMask, 0}, outputs: []regMask{fpMask}}
-		fp2gp   = regInfo{inputs: []regMask{fpMask, fpMask}, outputs: []regMask{gpMask}}
-
-		call        = regInfo{clobbers: callerSave}
-		callClosure = regInfo{inputs: []regMask{gpspMask, regCtxt, 0}, clobbers: callerSave}
-		callInter   = regInfo{inputs: []regMask{gpMask}, clobbers: callerSave}
-	)
-
-	RISCV64ops := []opData{
-		{name: "ADD", argLength: 2, reg: gp21, asm: "ADD", commutative: true}, // arg0 + arg1
-		{name: "ADDI", argLength: 1, reg: gp11sb, asm: "ADDI", aux: "Int64"},  // arg0 + auxint
-		{name: "ADDIW", argLength: 1, reg: gp11, asm: "ADDIW", aux: "Int64"},  // 32 low bits of arg0 + auxint, sign extended to 64 bits
-		{name: "NEG", argLength: 1, reg: gp11, asm: "NEG"},                    // -arg0
-		{name: "NEGW", argLength: 1, reg: gp11, asm: "NEGW"},                  // -arg0 of 32 bits, sign extended to 64 bits
-		{name: "SUB", argLength: 2, reg: gp21, asm: "SUB"},                    // arg0 - arg1
-		{name: "SUBW", argLength: 2, reg: gp21, asm: "SUBW"},                  // 32 low bits of arg 0 - 32 low bits of arg 1, sign extended to 64 bits
-
-		// M extension. H means high (i.e., it returns the top bits of
-		// the result). U means unsigned. W means word (i.e., 32-bit).
-		{name: "MUL", argLength: 2, reg: gp21, asm: "MUL", commutative: true, typ: "Int64"}, // arg0 * arg1
-		{name: "MULW", argLength: 2, reg: gp21, asm: "MULW", commutative: true, typ: "Int32"},
-		{name: "MULH", argLength: 2, reg: gp21, asm: "MULH", commutative: true, typ: "Int64"},
-		{name: "MULHU", argLength: 2, reg: gp21, asm: "MULHU", commutative: true, typ: "UInt64"},
-		{name: "LoweredMuluhilo", argLength: 2, reg: gp22, resultNotInArgs: true}, // arg0 * arg1, return (hi, lo)
-		{name: "LoweredMuluover", argLength: 2, reg: gp22, resultNotInArgs: true}, // arg0 * arg1, return (64 bits of arg0*arg1, overflow)
-
-		{name: "DIV", argLength: 2, reg: gp21, asm: "DIV", typ: "Int64"}, // arg0 / arg1
-		{name: "DIVU", argLength: 2, reg: gp21, asm: "DIVU", typ: "UInt64"},
-		{name: "DIVW", argLength: 2, reg: gp21, asm: "DIVW", typ: "Int32"},
-		{name: "DIVUW", argLength: 2, reg: gp21, asm: "DIVUW", typ: "UInt32"},
-		{name: "REM", argLength: 2, reg: gp21, asm: "REM", typ: "Int64"}, // arg0 % arg1
-		{name: "REMU", argLength: 2, reg: gp21, asm: "REMU", typ: "UInt64"},
-		{name: "REMW", argLength: 2, reg: gp21, asm: "REMW", typ: "Int32"},
-		{name: "REMUW", argLength: 2, reg: gp21, asm: "REMUW", typ: "UInt32"},
-
-		{name: "MOVaddr", argLength: 1, reg: gp11sb, asm: "MOV", aux: "SymOff", rematerializeable: true, symEffect: "RdWr"}, // arg0 + auxint + offset encoded in aux
-		// auxint+aux == add auxint and the offset of the symbol in aux (if any) to the effective address
-
-		{name: "MOVDconst", reg: gp01, asm: "MOV", typ: "UInt64", aux: "Int64", rematerializeable: true}, // auxint
-
-		// Loads: load <size> bits from arg0+auxint+aux and extend to 64 bits; arg1=mem
-		{name: "MOVBload", argLength: 2, reg: gpload, asm: "MOVB", aux: "SymOff", typ: "Int8", faultOnNilArg0: true, symEffect: "Read"},     //  8 bits, sign extend
-		{name: "MOVHload", argLength: 2, reg: gpload, asm: "MOVH", aux: "SymOff", typ: "Int16", faultOnNilArg0: true, symEffect: "Read"},    // 16 bits, sign extend
-		{name: "MOVWload", argLength: 2, reg: gpload, asm: "MOVW", aux: "SymOff", typ: "Int32", faultOnNilArg0: true, symEffect: "Read"},    // 32 bits, sign extend
-		{name: "MOVDload", argLength: 2, reg: gpload, asm: "MOV", aux: "SymOff", typ: "Int64", faultOnNilArg0: true, symEffect: "Read"},     // 64 bits
-		{name: "MOVBUload", argLength: 2, reg: gpload, asm: "MOVBU", aux: "SymOff", typ: "UInt8", faultOnNilArg0: true, symEffect: "Read"},  //  8 bits, zero extend
-		{name: "MOVHUload", argLength: 2, reg: gpload, asm: "MOVHU", aux: "SymOff", typ: "UInt16", faultOnNilArg0: true, symEffect: "Read"}, // 16 bits, zero extend
-		{name: "MOVWUload", argLength: 2, reg: gpload, asm: "MOVWU", aux: "SymOff", typ: "UInt32", faultOnNilArg0: true, symEffect: "Read"}, // 32 bits, zero extend
-
-		// Stores: store <size> lowest bits in arg1 to arg0+auxint+aux; arg2=mem
-		{name: "MOVBstore", argLength: 3, reg: gpstore, asm: "MOVB", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, //  8 bits
-		{name: "MOVHstore", argLength: 3, reg: gpstore, asm: "MOVH", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // 16 bits
-		{name: "MOVWstore", argLength: 3, reg: gpstore, asm: "MOVW", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // 32 bits
-		{name: "MOVDstore", argLength: 3, reg: gpstore, asm: "MOV", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},  // 64 bits
-
-		// Stores: store <size> of zero in arg0+auxint+aux; arg1=mem
-		{name: "MOVBstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVB", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, //  8 bits
-		{name: "MOVHstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVH", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // 16 bits
-		{name: "MOVWstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOVW", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // 32 bits
-		{name: "MOVDstorezero", argLength: 2, reg: gpstore0, aux: "SymOff", asm: "MOV", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},  // 64 bits
-
-		// Conversions
-		{name: "MOVBreg", argLength: 1, reg: gp11, asm: "MOVB"},   // move from arg0, sign-extended from byte
-		{name: "MOVHreg", argLength: 1, reg: gp11, asm: "MOVH"},   // move from arg0, sign-extended from half
-		{name: "MOVWreg", argLength: 1, reg: gp11, asm: "MOVW"},   // move from arg0, sign-extended from word
-		{name: "MOVDreg", argLength: 1, reg: gp11, asm: "MOV"},    // move from arg0
-		{name: "MOVBUreg", argLength: 1, reg: gp11, asm: "MOVBU"}, // move from arg0, unsign-extended from byte
-		{name: "MOVHUreg", argLength: 1, reg: gp11, asm: "MOVHU"}, // move from arg0, unsign-extended from half
-		{name: "MOVWUreg", argLength: 1, reg: gp11, asm: "MOVWU"}, // move from arg0, unsign-extended from word
-
-		{name: "MOVDnop", argLength: 1, reg: regInfo{inputs: []regMask{gpMask}, outputs: []regMask{gpMask}}, resultInArg0: true}, // nop, return arg0 in same register
-
-		// Shift ops
-		{name: "SLL", argLength: 2, reg: gp21, asm: "SLL"},                 // arg0 << (aux1 & 63)
-		{name: "SRA", argLength: 2, reg: gp21, asm: "SRA"},                 // arg0 >> (aux1 & 63), signed
-		{name: "SRL", argLength: 2, reg: gp21, asm: "SRL"},                 // arg0 >> (aux1 & 63), unsigned
-		{name: "SLLI", argLength: 1, reg: gp11, asm: "SLLI", aux: "Int64"}, // arg0 << auxint, shift amount 0-63
-		{name: "SRAI", argLength: 1, reg: gp11, asm: "SRAI", aux: "Int64"}, // arg0 >> auxint, signed, shift amount 0-63
-		{name: "SRLI", argLength: 1, reg: gp11, asm: "SRLI", aux: "Int64"}, // arg0 >> auxint, unsigned, shift amount 0-63
-
-		// Bitwise ops
-		{name: "XOR", argLength: 2, reg: gp21, asm: "XOR", commutative: true}, // arg0 ^ arg1
-		{name: "XORI", argLength: 1, reg: gp11, asm: "XORI", aux: "Int64"},    // arg0 ^ auxint
-		{name: "OR", argLength: 2, reg: gp21, asm: "OR", commutative: true},   // arg0 | arg1
-		{name: "ORI", argLength: 1, reg: gp11, asm: "ORI", aux: "Int64"},      // arg0 | auxint
-		{name: "AND", argLength: 2, reg: gp21, asm: "AND", commutative: true}, // arg0 & arg1
-		{name: "ANDI", argLength: 1, reg: gp11, asm: "ANDI", aux: "Int64"},    // arg0 & auxint
-		{name: "NOT", argLength: 1, reg: gp11, asm: "NOT"},                    // ^arg0
-
-		// Generate boolean values
-		{name: "SEQZ", argLength: 1, reg: gp11, asm: "SEQZ"},                 // arg0 == 0, result is 0 or 1
-		{name: "SNEZ", argLength: 1, reg: gp11, asm: "SNEZ"},                 // arg0 != 0, result is 0 or 1
-		{name: "SLT", argLength: 2, reg: gp21, asm: "SLT"},                   // arg0 < arg1, result is 0 or 1
-		{name: "SLTI", argLength: 1, reg: gp11, asm: "SLTI", aux: "Int64"},   // arg0 < auxint, result is 0 or 1
-		{name: "SLTU", argLength: 2, reg: gp21, asm: "SLTU"},                 // arg0 < arg1, unsigned, result is 0 or 1
-		{name: "SLTIU", argLength: 1, reg: gp11, asm: "SLTIU", aux: "Int64"}, // arg0 < auxint, unsigned, result is 0 or 1
-
-		// MOVconvert converts between pointers and integers.
-		// We have a special op for this so as to not confuse GC
-		// (particularly stack maps). It takes a memory arg so it
-		// gets correctly ordered with respect to GC safepoints.
-		{name: "MOVconvert", argLength: 2, reg: gp11, asm: "MOV"}, // arg0, but converted to int/ptr as appropriate; arg1=mem
-
-		// Calls
-		{name: "CALLstatic", argLength: -1, reg: call, aux: "CallOff", call: true},               // call static function aux.(*gc.Sym). last arg=mem, auxint=argsize, returns mem
-		{name: "CALLtail", argLength: -1, reg: call, aux: "CallOff", call: true, tailCall: true}, // tail call static function aux.(*gc.Sym). last arg=mem, auxint=argsize, returns mem
-		{name: "CALLclosure", argLength: -1, reg: callClosure, aux: "CallOff", call: true},       // call function via closure. arg0=codeptr, arg1=closure, last arg=mem, auxint=argsize, returns mem
-		{name: "CALLinter", argLength: -1, reg: callInter, aux: "CallOff", call: true},           // call fn by pointer. arg0=codeptr, last arg=mem, auxint=argsize, returns mem
-
-		// duffzero
-		// arg0 = address of memory to zero (in X25, changed as side effect)
-		// arg1 = mem
-		// auxint = offset into duffzero code to start executing
-		// X1 (link register) changed because of function call
-		// returns mem
-		{
-			name:      "DUFFZERO",
-			aux:       "Int64",
-			argLength: 2,
-			reg: regInfo{
-				inputs:   []regMask{regNamed["X25"]},
-				clobbers: regNamed["X1"] | regNamed["X25"],
-			},
-			typ:            "Mem",
-			faultOnNilArg0: true,
-		},
-
-		// duffcopy
-		// arg0 = address of dst memory (in X25, changed as side effect)
-		// arg1 = address of src memory (in X24, changed as side effect)
-		// arg2 = mem
-		// auxint = offset into duffcopy code to start executing
-		// X1 (link register) changed because of function call
-		// returns mem
-		{
-			name:      "DUFFCOPY",
-			aux:       "Int64",
-			argLength: 3,
-			reg: regInfo{
-				inputs:   []regMask{regNamed["X25"], regNamed["X24"]},
-				clobbers: regNamed["X1"] | regNamed["X24"] | regNamed["X25"],
-			},
-			typ:            "Mem",
-			faultOnNilArg0: true,
-			faultOnNilArg1: true,
-		},
-
-		// Generic moves and zeros
-
-		// general unaligned zeroing
-		// arg0 = address of memory to zero (in X5, changed as side effect)
-		// arg1 = address of the last element to zero (inclusive)
-		// arg2 = mem
-		// auxint = element size
-		// returns mem
-		//	mov	ZERO, (X5)
-		//	ADD	$sz, X5
-		//	BGEU	Rarg1, X5, -2(PC)
-		{
-			name:      "LoweredZero",
-			aux:       "Int64",
-			argLength: 3,
-			reg: regInfo{
-				inputs:   []regMask{regNamed["X5"], gpMask},
-				clobbers: regNamed["X5"],
-			},
-			typ:            "Mem",
-			faultOnNilArg0: true,
-		},
-
-		// general unaligned move
-		// arg0 = address of dst memory (in X5, changed as side effect)
-		// arg1 = address of src memory (in X6, changed as side effect)
-		// arg2 = address of the last element of src (can't be X7 as we clobber it before using arg2)
-		// arg3 = mem
-		// auxint = alignment
-		// clobbers X7 as a tmp register.
-		// returns mem
-		//	mov	(X6), X7
-		//	mov	X7, (X5)
-		//	ADD	$sz, X5
-		//	ADD	$sz, X6
-		//	BGEU	Rarg2, X5, -4(PC)
-		{
-			name:      "LoweredMove",
-			aux:       "Int64",
-			argLength: 4,
-			reg: regInfo{
-				inputs:   []regMask{regNamed["X5"], regNamed["X6"], gpMask &^ regNamed["X7"]},
-				clobbers: regNamed["X5"] | regNamed["X6"] | regNamed["X7"],
-			},
-			typ:            "Mem",
-			faultOnNilArg0: true,
-			faultOnNilArg1: true,
-		},
-
-		// Atomic loads.
-		// load from arg0. arg1=mem.
-		// returns <value,memory> so they can be properly ordered with other loads.
-		{name: "LoweredAtomicLoad8", argLength: 2, reg: gpload, faultOnNilArg0: true},
-		{name: "LoweredAtomicLoad32", argLength: 2, reg: gpload, faultOnNilArg0: true},
-		{name: "LoweredAtomicLoad64", argLength: 2, reg: gpload, faultOnNilArg0: true},
-
-		// Atomic stores.
-		// store arg1 to *arg0. arg2=mem. returns memory.
-		{name: "LoweredAtomicStore8", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true},
-		{name: "LoweredAtomicStore32", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true},
-		{name: "LoweredAtomicStore64", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true},
-
-		// Atomic exchange.
-		// store arg1 to *arg0. arg2=mem. returns <old content of *arg0, memory>.
-		{name: "LoweredAtomicExchange32", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
-		{name: "LoweredAtomicExchange64", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true},
-
-		// Atomic add.
-		// *arg0 += arg1. arg2=mem. returns <new content of *arg0, memory>.
-		{name: "LoweredAtomicAdd32", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-		{name: "LoweredAtomicAdd64", argLength: 3, reg: gpxchg, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-
-		// Atomic compare and swap.
-		// arg0 = pointer, arg1 = old value, arg2 = new value, arg3 = memory.
-		// if *arg0 == arg1 {
-		//   *arg0 = arg2
-		//   return (true, memory)
-		// } else {
-		//   return (false, memory)
-		// }
-		// MOV  $0, Rout
-		// LR	(Rarg0), Rtmp
-		// BNE	Rtmp, Rarg1, 3(PC)
-		// SC	Rarg2, (Rarg0), Rtmp
-		// BNE	Rtmp, ZERO, -3(PC)
-		// MOV  $1, Rout
-		{name: "LoweredAtomicCas32", argLength: 4, reg: gpcas, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-		{name: "LoweredAtomicCas64", argLength: 4, reg: gpcas, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
-
-		// Atomic 32 bit AND/OR.
-		// *arg0 &= (|=) arg1. arg2=mem. returns nil.
-		{name: "LoweredAtomicAnd32", argLength: 3, reg: gpatomic, asm: "AMOANDW", faultOnNilArg0: true, hasSideEffects: true},
-		{name: "LoweredAtomicOr32", argLength: 3, reg: gpatomic, asm: "AMOORW", faultOnNilArg0: true, hasSideEffects: true},
-
-		// Lowering pass-throughs
-		{name: "LoweredNilCheck", argLength: 2, faultOnNilArg0: true, nilCheck: true, reg: regInfo{inputs: []regMask{gpspMask}}}, // arg0=ptr,arg1=mem, returns void.  Faults if ptr is nil.
-		{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{regCtxt}}},                                                // scheduler ensures only at beginning of entry block
-
-		// LoweredGetCallerSP returns the SP of the caller of the current function.
-		{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
-
-		// LoweredGetCallerPC evaluates to the PC to which its "caller" will return.
-		// I.e., if f calls g "calls" getcallerpc,
-		// the result should be the PC within f that g will return to.
-		// See runtime/stubs.go for a more detailed discussion.
-		{name: "LoweredGetCallerPC", reg: gp01, rematerializeable: true},
-
-		// LoweredWB invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
-		// It saves all GP registers if necessary,
-		// but clobbers RA (LR) because it's a call
-		// and T6 (REG_TMP).
-		{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{regNamed["X5"], regNamed["X6"]}, clobbers: (callerSave &^ (gpMask | regNamed["g"])) | regNamed["X1"]}, clobberFlags: true, aux: "Sym", symEffect: "None"},
-
-		// There are three of these functions so that they can have three different register inputs.
-		// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the
-		// default registers to match so we don't need to copy registers around unnecessarily.
-		{name: "LoweredPanicBoundsA", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{regNamed["X7"], regNamed["X28"]}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
-		{name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{regNamed["X6"], regNamed["X7"]}}, typ: "Mem", call: true},  // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
-		{name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{regNamed["X5"], regNamed["X6"]}}, typ: "Mem", call: true},  // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
-
-		// F extension.
-		{name: "FADDS", argLength: 2, reg: fp21, asm: "FADDS", commutative: true, typ: "Float32"},                                           // arg0 + arg1
-		{name: "FSUBS", argLength: 2, reg: fp21, asm: "FSUBS", commutative: false, typ: "Float32"},                                          // arg0 - arg1
-		{name: "FMULS", argLength: 2, reg: fp21, asm: "FMULS", commutative: true, typ: "Float32"},                                           // arg0 * arg1
-		{name: "FDIVS", argLength: 2, reg: fp21, asm: "FDIVS", commutative: false, typ: "Float32"},                                          // arg0 / arg1
-		{name: "FSQRTS", argLength: 1, reg: fp11, asm: "FSQRTS", typ: "Float32"},                                                            // sqrt(arg0)
-		{name: "FNEGS", argLength: 1, reg: fp11, asm: "FNEGS", typ: "Float32"},                                                              // -arg0
-		{name: "FMVSX", argLength: 1, reg: gpfp, asm: "FMVSX", typ: "Float32"},                                                              // reinterpret arg0 as float
-		{name: "FCVTSW", argLength: 1, reg: gpfp, asm: "FCVTSW", typ: "Float32"},                                                            // float32(low 32 bits of arg0)
-		{name: "FCVTSL", argLength: 1, reg: gpfp, asm: "FCVTSL", typ: "Float32"},                                                            // float32(arg0)
-		{name: "FCVTWS", argLength: 1, reg: fpgp, asm: "FCVTWS", typ: "Int32"},                                                              // int32(arg0)
-		{name: "FCVTLS", argLength: 1, reg: fpgp, asm: "FCVTLS", typ: "Int64"},                                                              // int64(arg0)
-		{name: "FMOVWload", argLength: 2, reg: fpload, asm: "MOVF", aux: "SymOff", typ: "Float32", faultOnNilArg0: true, symEffect: "Read"}, // load float32 from arg0+auxint+aux
-		{name: "FMOVWstore", argLength: 3, reg: fpstore, asm: "MOVF", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},  // store float32 to arg0+auxint+aux
-		{name: "FEQS", argLength: 2, reg: fp2gp, asm: "FEQS", commutative: true},                                                            // arg0 == arg1
-		{name: "FNES", argLength: 2, reg: fp2gp, asm: "FNES", commutative: true},                                                            // arg0 != arg1
-		{name: "FLTS", argLength: 2, reg: fp2gp, asm: "FLTS"},                                                                               // arg0 < arg1
-		{name: "FLES", argLength: 2, reg: fp2gp, asm: "FLES"},                                                                               // arg0 <= arg1
-
-		// D extension.
-		{name: "FADDD", argLength: 2, reg: fp21, asm: "FADDD", commutative: true, typ: "Float64"},                                           // arg0 + arg1
-		{name: "FSUBD", argLength: 2, reg: fp21, asm: "FSUBD", commutative: false, typ: "Float64"},                                          // arg0 - arg1
-		{name: "FMULD", argLength: 2, reg: fp21, asm: "FMULD", commutative: true, typ: "Float64"},                                           // arg0 * arg1
-		{name: "FDIVD", argLength: 2, reg: fp21, asm: "FDIVD", commutative: false, typ: "Float64"},                                          // arg0 / arg1
-		{name: "FMADDD", argLength: 3, reg: fp31, asm: "FMADDD", commutative: true, typ: "Float64"},                                         // (arg0 * arg1) + arg2
-		{name: "FMSUBD", argLength: 3, reg: fp31, asm: "FMSUBD", commutative: true, typ: "Float64"},                                         // (arg0 * arg1) - arg2
-		{name: "FNMADDD", argLength: 3, reg: fp31, asm: "FNMADDD", commutative: true, typ: "Float64"},                                       // -(arg0 * arg1) + arg2
-		{name: "FNMSUBD", argLength: 3, reg: fp31, asm: "FNMSUBD", commutative: true, typ: "Float64"},                                       // -(arg0 * arg1) - arg2
-		{name: "FSQRTD", argLength: 1, reg: fp11, asm: "FSQRTD", typ: "Float64"},                                                            // sqrt(arg0)
-		{name: "FNEGD", argLength: 1, reg: fp11, asm: "FNEGD", typ: "Float64"},                                                              // -arg0
-		{name: "FABSD", argLength: 1, reg: fp11, asm: "FABSD", typ: "Float64"},                                                              // abs(arg0)
-		{name: "FSGNJD", argLength: 2, reg: fp21, asm: "FSGNJD", typ: "Float64"},                                                            // copy sign of arg1 to arg0
-		{name: "FMVDX", argLength: 1, reg: gpfp, asm: "FMVDX", typ: "Float64"},                                                              // reinterpret arg0 as float
-		{name: "FCVTDW", argLength: 1, reg: gpfp, asm: "FCVTDW", typ: "Float64"},                                                            // float64(low 32 bits of arg0)
-		{name: "FCVTDL", argLength: 1, reg: gpfp, asm: "FCVTDL", typ: "Float64"},                                                            // float64(arg0)
-		{name: "FCVTWD", argLength: 1, reg: fpgp, asm: "FCVTWD", typ: "Int32"},                                                              // int32(arg0)
-		{name: "FCVTLD", argLength: 1, reg: fpgp, asm: "FCVTLD", typ: "Int64"},                                                              // int64(arg0)
-		{name: "FCVTDS", argLength: 1, reg: fp11, asm: "FCVTDS", typ: "Float64"},                                                            // float64(arg0)
-		{name: "FCVTSD", argLength: 1, reg: fp11, asm: "FCVTSD", typ: "Float32"},                                                            // float32(arg0)
-		{name: "FMOVDload", argLength: 2, reg: fpload, asm: "MOVD", aux: "SymOff", typ: "Float64", faultOnNilArg0: true, symEffect: "Read"}, // load float64 from arg0+auxint+aux
-		{name: "FMOVDstore", argLength: 3, reg: fpstore, asm: "MOVD", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},  // store float6 to arg0+auxint+aux
-		{name: "FEQD", argLength: 2, reg: fp2gp, asm: "FEQD", commutative: true},                                                            // arg0 == arg1
-		{name: "FNED", argLength: 2, reg: fp2gp, asm: "FNED", commutative: true},                                                            // arg0 != arg1
-		{name: "FLTD", argLength: 2, reg: fp2gp, asm: "FLTD"},                                                                               // arg0 < arg1
-		{name: "FLED", argLength: 2, reg: fp2gp, asm: "FLED"},                                                                               // arg0 <= arg1
-	}
-
-	RISCV64blocks := []blockData{
-		{name: "BEQ", controls: 2},
-		{name: "BNE", controls: 2},
-		{name: "BLT", controls: 2},
-		{name: "BGE", controls: 2},
-		{name: "BLTU", controls: 2},
-		{name: "BGEU", controls: 2},
-
-		{name: "BEQZ", controls: 1},
-		{name: "BNEZ", controls: 1},
-		{name: "BLEZ", controls: 1},
-		{name: "BGEZ", controls: 1},
-		{name: "BLTZ", controls: 1},
-		{name: "BGTZ", controls: 1},
-	}
-
-	archs = append(archs, arch{
-		name:            "RISCV64",
-		pkg:             "cmd/internal/obj/riscv",
-		genfile:         "../../riscv64/ssa.go",
-		ops:             RISCV64ops,
-		blocks:          RISCV64blocks,
-		regnames:        regNamesRISCV64,
-		gpregmask:       gpMask,
-		fpregmask:       fpMask,
-		framepointerreg: -1, // not used
-		// Integer parameters passed in register X10-X17, X8-X9, X18-X23
-		ParamIntRegNames: "X10 X11 X12 X13 X14 X15 X16 X17 X8 X9 X18 X19 X20 X21 X22 X23",
-		// Float parameters passed in register F10-F17, F8-F9, F18-F23
-		ParamFloatRegNames: "F10 F11 F12 F13 F14 F15 F16 F17 F8 F9 F18 F19 F20 F21 F22 F23",
-	})
-}
diff --git a/src/cmd/compile/internal/ssa/gen/S390X.rules b/src/cmd/compile/internal/ssa/gen/S390X.rules
deleted file mode 100644
index b3928c6..0000000
--- a/src/cmd/compile/internal/ssa/gen/S390X.rules
+++ /dev/null
@@ -1,1708 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Lowering arithmetic
-(Add(64|Ptr) ...) => (ADD ...)
-(Add(32|16|8) ...) => (ADDW ...)
-(Add32F x y) => (Select0 (FADDS x y))
-(Add64F x y) => (Select0 (FADD x y))
-
-(Sub(64|Ptr) ...) => (SUB ...)
-(Sub(32|16|8) ...) => (SUBW ...)
-(Sub32F x y) => (Select0 (FSUBS x y))
-(Sub64F x y) => (Select0 (FSUB x y))
-
-(Mul64 ...) => (MULLD ...)
-(Mul(32|16|8) ...) => (MULLW ...)
-(Mul32F ...) => (FMULS ...)
-(Mul64F ...) => (FMUL ...)
-(Mul64uhilo ...) => (MLGR ...)
-
-(Div32F ...) => (FDIVS ...)
-(Div64F ...) => (FDIV ...)
-
-(Div64 x y) => (DIVD x y)
-(Div64u ...) => (DIVDU ...)
-// DIVW/DIVWU has a 64-bit dividend and a 32-bit divisor,
-// so a sign/zero extension of the dividend is required.
-(Div32  x y) => (DIVW  (MOVWreg x) y)
-(Div32u x y) => (DIVWU (MOVWZreg x) y)
-(Div16  x y) => (DIVW  (MOVHreg x) (MOVHreg y))
-(Div16u x y) => (DIVWU (MOVHZreg x) (MOVHZreg y))
-(Div8   x y) => (DIVW  (MOVBreg x) (MOVBreg y))
-(Div8u  x y) => (DIVWU (MOVBZreg x) (MOVBZreg y))
-
-(Hmul(64|64u) ...) => (MULH(D|DU) ...)
-(Hmul32  x y) => (SRDconst [32] (MULLD (MOVWreg x) (MOVWreg y)))
-(Hmul32u x y) => (SRDconst [32] (MULLD (MOVWZreg x) (MOVWZreg y)))
-
-(Mod64 x y) => (MODD x y)
-(Mod64u ...) => (MODDU ...)
-// MODW/MODWU has a 64-bit dividend and a 32-bit divisor,
-// so a sign/zero extension of the dividend is required.
-(Mod32  x y) => (MODW  (MOVWreg x) y)
-(Mod32u x y) => (MODWU (MOVWZreg x) y)
-(Mod16  x y) => (MODW  (MOVHreg x) (MOVHreg y))
-(Mod16u x y) => (MODWU (MOVHZreg x) (MOVHZreg y))
-(Mod8   x y) => (MODW  (MOVBreg x) (MOVBreg y))
-(Mod8u  x y) => (MODWU (MOVBZreg x) (MOVBZreg y))
-
-// (x + y) / 2 with x>=y -> (x - y) / 2 + y
-(Avg64u <t> x y) => (ADD (SRDconst <t> (SUB <t> x y) [1]) y)
-
-(And64 ...) => (AND ...)
-(And(32|16|8) ...) => (ANDW ...)
-
-(Or64 ...) => (OR ...)
-(Or(32|16|8) ...) => (ORW ...)
-
-(Xor64 ...) => (XOR ...)
-(Xor(32|16|8) ...) => (XORW ...)
-
-(Neg64 ...) => (NEG ...)
-(Neg(32|16|8) ...) => (NEGW ...)
-(Neg32F ...) => (FNEGS ...)
-(Neg64F ...) => (FNEG ...)
-
-(Com64 ...) => (NOT ...)
-(Com(32|16|8) ...) => (NOTW ...)
-(NOT x) => (XOR (MOVDconst [-1]) x)
-(NOTW x) => (XORWconst [-1] x)
-
-// Lowering boolean ops
-(AndB ...) => (ANDW ...)
-(OrB ...) => (ORW ...)
-(Not x) => (XORWconst [1] x)
-
-// Lowering pointer arithmetic
-(OffPtr [off] ptr:(SP)) => (MOVDaddr [int32(off)] ptr)
-(OffPtr [off] ptr) && is32Bit(off) => (ADDconst [int32(off)] ptr)
-(OffPtr [off] ptr) => (ADD (MOVDconst [off]) ptr)
-
-// TODO: optimize these cases?
-(Ctz64NonZero ...) => (Ctz64 ...)
-(Ctz32NonZero ...) => (Ctz32 ...)
-
-// Ctz(x) = 64 - findLeftmostOne((x-1)&^x)
-(Ctz64 <t> x) => (SUB (MOVDconst [64]) (FLOGR (AND <t> (SUBconst <t> [1] x) (NOT <t> x))))
-(Ctz32 <t> x) => (SUB (MOVDconst [64]) (FLOGR (MOVWZreg (ANDW <t> (SUBWconst <t> [1] x) (NOTW <t> x)))))
-
-(BitLen64 x) => (SUB (MOVDconst [64]) (FLOGR x))
-
-// POPCNT treats the input register as a vector of 8 bytes, producing
-// a population count for each individual byte. For inputs larger than
-// a single byte we therefore need to sum the individual bytes produced
-// by the POPCNT instruction. For example, the following instruction
-// sequence could be used to calculate the population count of a 4-byte
-// value:
-//
-//     MOVD   $0x12345678, R1 // R1=0x12345678 <-- input
-//     POPCNT R1, R2          // R2=0x02030404
-//     SRW    $16, R2, R3     // R3=0x00000203
-//     ADDW   R2, R3, R4      // R4=0x02030607
-//     SRW    $8, R4, R5      // R5=0x00020306
-//     ADDW   R4, R5, R6      // R6=0x0205090d
-//     MOVBZ  R6, R7          // R7=0x0000000d <-- result is 13
-//
-(PopCount8  x) => (POPCNT (MOVBZreg x))
-(PopCount16 x) => (MOVBZreg (SumBytes2 (POPCNT <typ.UInt16> x)))
-(PopCount32 x) => (MOVBZreg (SumBytes4 (POPCNT <typ.UInt32> x)))
-(PopCount64 x) => (MOVBZreg (SumBytes8 (POPCNT <typ.UInt64> x)))
-
-// SumBytes{2,4,8} pseudo operations sum the values of the rightmost
-// 2, 4 or 8 bytes respectively. The result is a single byte however
-// other bytes might contain junk so a zero extension is required if
-// the desired output type is larger than 1 byte.
-(SumBytes2 x) => (ADDW (SRWconst <typ.UInt8> x [8]) x)
-(SumBytes4 x) => (SumBytes2 (ADDW <typ.UInt16> (SRWconst <typ.UInt16> x [16]) x))
-(SumBytes8 x) => (SumBytes4 (ADDW <typ.UInt32> (SRDconst <typ.UInt32> x [32]) x))
-
-(Bswap64 ...) => (MOVDBR ...)
-(Bswap32 ...) => (MOVWBR ...)
-
-// add with carry
-(Select0 (Add64carry x y c))
-  => (Select0 <typ.UInt64> (ADDE x y (Select1 <types.TypeFlags> (ADDCconst c [-1]))))
-(Select1 (Add64carry x y c))
-  => (Select0 <typ.UInt64> (ADDE (MOVDconst [0]) (MOVDconst [0]) (Select1 <types.TypeFlags> (ADDE x y (Select1 <types.TypeFlags> (ADDCconst c [-1]))))))
-
-// subtract with borrow
-(Select0 (Sub64borrow x y c))
-  => (Select0 <typ.UInt64> (SUBE x y (Select1 <types.TypeFlags> (SUBC (MOVDconst [0]) c))))
-(Select1 (Sub64borrow x y c))
-  => (NEG (Select0 <typ.UInt64> (SUBE (MOVDconst [0]) (MOVDconst [0]) (Select1 <types.TypeFlags> (SUBE x y (Select1 <types.TypeFlags> (SUBC (MOVDconst [0]) c)))))))
-
-// math package intrinsics
-(Sqrt      ...) => (FSQRT ...)
-(Floor       x) => (FIDBR [7] x)
-(Ceil        x) => (FIDBR [6] x)
-(Trunc       x) => (FIDBR [5] x)
-(RoundToEven x) => (FIDBR [4] x)
-(Round       x) => (FIDBR [1] x)
-(FMA     x y z) => (FMADD z x y)
-
-(Sqrt32    ...) => (FSQRTS ...)
-
-// Atomic loads and stores.
-// The SYNC instruction (fast-BCR-serialization) prevents store-load
-// reordering. Other sequences of memory operations (load-load,
-// store-store and load-store) are already guaranteed not to be reordered.
-(AtomicLoad(8|32|Acq32|64|Ptr) ptr mem) => (MOV(BZ|WZ|WZ|D|D)atomicload ptr mem)
-(AtomicStore(8|32|64|PtrNoWB) ptr val mem) => (SYNC (MOV(B|W|D|D)atomicstore ptr val mem))
-
-// Store-release doesn't require store-load ordering.
-(AtomicStoreRel32 ptr val mem) => (MOVWatomicstore ptr val mem)
-
-// Atomic adds.
-(AtomicAdd32 ptr val mem) => (AddTupleFirst32 val (LAA ptr val mem))
-(AtomicAdd64 ptr val mem) => (AddTupleFirst64 val (LAAG ptr val mem))
-(Select0 <t> (AddTupleFirst32 val tuple)) => (ADDW val (Select0 <t> tuple))
-(Select1     (AddTupleFirst32   _ tuple)) => (Select1 tuple)
-(Select0 <t> (AddTupleFirst64 val tuple)) => (ADD val (Select0 <t> tuple))
-(Select1     (AddTupleFirst64   _ tuple)) => (Select1 tuple)
-
-// Atomic exchanges.
-(AtomicExchange32 ptr val mem) => (LoweredAtomicExchange32 ptr val mem)
-(AtomicExchange64 ptr val mem) => (LoweredAtomicExchange64 ptr val mem)
-
-// Atomic compare and swap.
-(AtomicCompareAndSwap32 ptr old new_ mem) => (LoweredAtomicCas32 ptr old new_ mem)
-(AtomicCompareAndSwap64 ptr old new_ mem) => (LoweredAtomicCas64 ptr old new_ mem)
-
-// Atomic and: *(*uint8)(ptr) &= val
-//
-// Round pointer down to nearest word boundary and pad value with ones before
-// applying atomic AND operation to target word.
-//
-// *(*uint32)(ptr &^ 3) &= rotateleft(uint32(val) | 0xffffff00, ((3 << 3) ^ ((ptr & 3) << 3))
-//
-(AtomicAnd8 ptr val mem)
-  => (LANfloor
-       ptr
-       (RLL <typ.UInt32>
-         (ORWconst <typ.UInt32> val [-1<<8])
-         (RXSBG <typ.UInt32> {s390x.NewRotateParams(59, 60, 3)} (MOVDconst [3<<3]) ptr))
-       mem)
-
-// Atomic or: *(*uint8)(ptr) |= val
-//
-// Round pointer down to nearest word boundary and pad value with zeros before
-// applying atomic OR operation to target word.
-//
-// *(*uint32)(ptr &^ 3) |= uint32(val) << ((3 << 3) ^ ((ptr & 3) << 3))
-//
-(AtomicOr8  ptr val mem)
-  => (LAOfloor
-       ptr
-       (SLW <typ.UInt32>
-         (MOVBZreg <typ.UInt32> val)
-         (RXSBG <typ.UInt32> {s390x.NewRotateParams(59, 60, 3)} (MOVDconst [3<<3]) ptr))
-       mem)
-
-(AtomicAnd32 ...) => (LAN ...)
-(AtomicOr32  ...) => (LAO ...)
-
-// Lowering extension
-// Note: we always extend to 64 bits even though some ops don't need that many result bits.
-(SignExt8to(16|32|64) ...) => (MOVBreg ...)
-(SignExt16to(32|64) ...) => (MOVHreg ...)
-(SignExt32to64 ...) => (MOVWreg ...)
-
-(ZeroExt8to(16|32|64) ...) => (MOVBZreg ...)
-(ZeroExt16to(32|64) ...) => (MOVHZreg ...)
-(ZeroExt32to64 ...) => (MOVWZreg ...)
-
-(Slicemask <t> x) => (SRADconst (NEG <t> x) [63])
-
-// Lowering truncation
-// Because we ignore high parts of registers, truncates are just copies.
-(Trunc(16|32|64)to8 ...) => (Copy ...)
-(Trunc(32|64)to16 ...) => (Copy ...)
-(Trunc64to32 ...) => (Copy ...)
-
-// Lowering float <-> int
-(Cvt32to32F ...) => (CEFBRA ...)
-(Cvt32to64F ...) => (CDFBRA ...)
-(Cvt64to32F ...) => (CEGBRA ...)
-(Cvt64to64F ...) => (CDGBRA ...)
-
-(Cvt32Fto32 ...) => (CFEBRA ...)
-(Cvt32Fto64 ...) => (CGEBRA ...)
-(Cvt64Fto32 ...) => (CFDBRA ...)
-(Cvt64Fto64 ...) => (CGDBRA ...)
-
-// Lowering float <-> uint
-(Cvt32Uto32F ...) => (CELFBR ...)
-(Cvt32Uto64F ...) => (CDLFBR ...)
-(Cvt64Uto32F ...) => (CELGBR ...)
-(Cvt64Uto64F ...) => (CDLGBR ...)
-
-(Cvt32Fto32U ...) => (CLFEBR ...)
-(Cvt32Fto64U ...) => (CLGEBR ...)
-(Cvt64Fto32U ...) => (CLFDBR ...)
-(Cvt64Fto64U ...) => (CLGDBR ...)
-
-// Lowering float32 <-> float64
-(Cvt32Fto64F ...) => (LDEBR ...)
-(Cvt64Fto32F ...) => (LEDBR ...)
-
-(CvtBoolToUint8 ...) => (Copy ...)
-
-(Round(32|64)F ...) => (LoweredRound(32|64)F ...)
-
-// Lowering shifts
-
-// Lower bounded shifts first. No need to check shift value.
-(Lsh64x(64|32|16|8)  x y) && shiftIsBounded(v) => (SLD x y)
-(Lsh32x(64|32|16|8)  x y) && shiftIsBounded(v) => (SLW x y)
-(Lsh16x(64|32|16|8)  x y) && shiftIsBounded(v) => (SLW x y)
-(Lsh8x(64|32|16|8)   x y) && shiftIsBounded(v) => (SLW x y)
-(Rsh64Ux(64|32|16|8) x y) && shiftIsBounded(v) => (SRD x y)
-(Rsh32Ux(64|32|16|8) x y) && shiftIsBounded(v) => (SRW x y)
-(Rsh16Ux(64|32|16|8) x y) && shiftIsBounded(v) => (SRW (MOVHZreg x) y)
-(Rsh8Ux(64|32|16|8)  x y) && shiftIsBounded(v) => (SRW (MOVBZreg x) y)
-(Rsh64x(64|32|16|8)  x y) && shiftIsBounded(v) => (SRAD x y)
-(Rsh32x(64|32|16|8)  x y) && shiftIsBounded(v) => (SRAW x y)
-(Rsh16x(64|32|16|8)  x y) && shiftIsBounded(v) => (SRAW (MOVHreg x) y)
-(Rsh8x(64|32|16|8)   x y) && shiftIsBounded(v) => (SRAW (MOVBreg x) y)
-
-// Unsigned shifts need to return 0 if shift amount is >= width of shifted value.
-//   result = shift >= 64 ? 0 : arg << shift
-(Lsh(64|32|16|8)x64 <t> x y) => (LOCGR {s390x.GreaterOrEqual} <t> (SL(D|W|W|W) <t> x y) (MOVDconst [0]) (CMPUconst y [64]))
-(Lsh(64|32|16|8)x32 <t> x y) => (LOCGR {s390x.GreaterOrEqual} <t> (SL(D|W|W|W) <t> x y) (MOVDconst [0]) (CMPWUconst y [64]))
-(Lsh(64|32|16|8)x16 <t> x y) => (LOCGR {s390x.GreaterOrEqual} <t> (SL(D|W|W|W) <t> x y) (MOVDconst [0]) (CMPWUconst (MOVHZreg y) [64]))
-(Lsh(64|32|16|8)x8  <t> x y) => (LOCGR {s390x.GreaterOrEqual} <t> (SL(D|W|W|W) <t> x y) (MOVDconst [0]) (CMPWUconst (MOVBZreg y) [64]))
-
-(Rsh(64|32)Ux64 <t> x y) => (LOCGR {s390x.GreaterOrEqual} <t> (SR(D|W) <t> x y) (MOVDconst [0]) (CMPUconst y [64]))
-(Rsh(64|32)Ux32 <t> x y) => (LOCGR {s390x.GreaterOrEqual} <t> (SR(D|W) <t> x y) (MOVDconst [0]) (CMPWUconst y [64]))
-(Rsh(64|32)Ux16 <t> x y) => (LOCGR {s390x.GreaterOrEqual} <t> (SR(D|W) <t> x y) (MOVDconst [0]) (CMPWUconst (MOVHZreg y) [64]))
-(Rsh(64|32)Ux8  <t> x y) => (LOCGR {s390x.GreaterOrEqual} <t> (SR(D|W) <t> x y) (MOVDconst [0]) (CMPWUconst (MOVBZreg y) [64]))
-
-(Rsh(16|8)Ux64 <t> x y) => (LOCGR {s390x.GreaterOrEqual} <t> (SRW <t> (MOV(H|B)Zreg x) y) (MOVDconst [0]) (CMPUconst y [64]))
-(Rsh(16|8)Ux32 <t> x y) => (LOCGR {s390x.GreaterOrEqual} <t> (SRW <t> (MOV(H|B)Zreg x) y) (MOVDconst [0]) (CMPWUconst y [64]))
-(Rsh(16|8)Ux16 <t> x y) => (LOCGR {s390x.GreaterOrEqual} <t> (SRW <t> (MOV(H|B)Zreg x) y) (MOVDconst [0]) (CMPWUconst (MOVHZreg y) [64]))
-(Rsh(16|8)Ux8  <t> x y) => (LOCGR {s390x.GreaterOrEqual} <t> (SRW <t> (MOV(H|B)Zreg x) y) (MOVDconst [0]) (CMPWUconst (MOVBZreg y) [64]))
-
-// Signed right shift needs to return 0/-1 if shift amount is >= width of shifted value.
-// We implement this by setting the shift value to 63 (all ones) if the shift value is more than 63.
-//   result = arg >> (shift >= 64 ? 63 : shift)
-(Rsh(64|32)x64 x y) => (SRA(D|W) x (LOCGR {s390x.GreaterOrEqual} <y.Type> y (MOVDconst <y.Type> [63]) (CMPUconst  y [64])))
-(Rsh(64|32)x32 x y) => (SRA(D|W) x (LOCGR {s390x.GreaterOrEqual} <y.Type> y (MOVDconst <y.Type> [63]) (CMPWUconst y [64])))
-(Rsh(64|32)x16 x y) => (SRA(D|W) x (LOCGR {s390x.GreaterOrEqual} <y.Type> y (MOVDconst <y.Type> [63]) (CMPWUconst (MOVHZreg y) [64])))
-(Rsh(64|32)x8  x y) => (SRA(D|W) x (LOCGR {s390x.GreaterOrEqual} <y.Type> y (MOVDconst <y.Type> [63]) (CMPWUconst (MOVBZreg y) [64])))
-
-(Rsh(16|8)x64 x y) => (SRAW (MOV(H|B)reg x) (LOCGR {s390x.GreaterOrEqual} <y.Type> y (MOVDconst <y.Type> [63]) (CMPUconst  y [64])))
-(Rsh(16|8)x32 x y) => (SRAW (MOV(H|B)reg x) (LOCGR {s390x.GreaterOrEqual} <y.Type> y (MOVDconst <y.Type> [63]) (CMPWUconst y [64])))
-(Rsh(16|8)x16 x y) => (SRAW (MOV(H|B)reg x) (LOCGR {s390x.GreaterOrEqual} <y.Type> y (MOVDconst <y.Type> [63]) (CMPWUconst (MOVHZreg y) [64])))
-(Rsh(16|8)x8  x y) => (SRAW (MOV(H|B)reg x) (LOCGR {s390x.GreaterOrEqual} <y.Type> y (MOVDconst <y.Type> [63]) (CMPWUconst (MOVBZreg y) [64])))
-
-// Lowering rotates
-(RotateLeft8 <t> x (MOVDconst [c])) => (Or8 (Lsh8x64 <t> x (MOVDconst [c&7])) (Rsh8Ux64 <t> x (MOVDconst [-c&7])))
-(RotateLeft16 <t> x (MOVDconst [c])) => (Or16 (Lsh16x64 <t> x (MOVDconst [c&15])) (Rsh16Ux64 <t> x (MOVDconst [-c&15])))
-(RotateLeft32 ...) => (RLL  ...)
-(RotateLeft64 ...) => (RLLG ...)
-
-// Lowering comparisons
-(Less64      x y) => (LOCGR {s390x.Less} (MOVDconst [0]) (MOVDconst [1]) (CMP x y))
-(Less32      x y) => (LOCGR {s390x.Less} (MOVDconst [0]) (MOVDconst [1]) (CMPW x y))
-(Less(16|8)  x y) => (LOCGR {s390x.Less} (MOVDconst [0]) (MOVDconst [1]) (CMPW (MOV(H|B)reg x) (MOV(H|B)reg y)))
-(Less64U     x y) => (LOCGR {s390x.Less} (MOVDconst [0]) (MOVDconst [1]) (CMPU x y))
-(Less32U     x y) => (LOCGR {s390x.Less} (MOVDconst [0]) (MOVDconst [1]) (CMPWU x y))
-(Less(16|8)U x y) => (LOCGR {s390x.Less} (MOVDconst [0]) (MOVDconst [1]) (CMPWU (MOV(H|B)Zreg x) (MOV(H|B)Zreg y)))
-(Less64F     x y) => (LOCGR {s390x.Less} (MOVDconst [0]) (MOVDconst [1]) (FCMP x y))
-(Less32F     x y) => (LOCGR {s390x.Less} (MOVDconst [0]) (MOVDconst [1]) (FCMPS x y))
-
-(Leq64      x y) => (LOCGR {s390x.LessOrEqual} (MOVDconst [0]) (MOVDconst [1]) (CMP x y))
-(Leq32      x y) => (LOCGR {s390x.LessOrEqual} (MOVDconst [0]) (MOVDconst [1]) (CMPW x y))
-(Leq(16|8)  x y) => (LOCGR {s390x.LessOrEqual} (MOVDconst [0]) (MOVDconst [1]) (CMPW (MOV(H|B)reg x) (MOV(H|B)reg y)))
-(Leq64U     x y) => (LOCGR {s390x.LessOrEqual} (MOVDconst [0]) (MOVDconst [1]) (CMPU x y))
-(Leq32U     x y) => (LOCGR {s390x.LessOrEqual} (MOVDconst [0]) (MOVDconst [1]) (CMPWU x y))
-(Leq(16|8)U x y) => (LOCGR {s390x.LessOrEqual} (MOVDconst [0]) (MOVDconst [1]) (CMPWU (MOV(H|B)Zreg x) (MOV(H|B)Zreg y)))
-(Leq64F     x y) => (LOCGR {s390x.LessOrEqual} (MOVDconst [0]) (MOVDconst [1]) (FCMP x y))
-(Leq32F     x y) => (LOCGR {s390x.LessOrEqual} (MOVDconst [0]) (MOVDconst [1]) (FCMPS x y))
-
-(Eq(64|Ptr) x y) => (LOCGR {s390x.Equal} (MOVDconst [0]) (MOVDconst [1]) (CMP x y))
-(Eq32       x y) => (LOCGR {s390x.Equal} (MOVDconst [0]) (MOVDconst [1]) (CMPW x y))
-(Eq(16|8|B) x y) => (LOCGR {s390x.Equal} (MOVDconst [0]) (MOVDconst [1]) (CMPW (MOV(H|B|B)reg x) (MOV(H|B|B)reg y)))
-(Eq64F      x y) => (LOCGR {s390x.Equal} (MOVDconst [0]) (MOVDconst [1]) (FCMP x y))
-(Eq32F      x y) => (LOCGR {s390x.Equal} (MOVDconst [0]) (MOVDconst [1]) (FCMPS x y))
-
-(Neq(64|Ptr) x y) => (LOCGR {s390x.NotEqual} (MOVDconst [0]) (MOVDconst [1]) (CMP x y))
-(Neq32       x y) => (LOCGR {s390x.NotEqual} (MOVDconst [0]) (MOVDconst [1]) (CMPW x y))
-(Neq(16|8|B) x y) => (LOCGR {s390x.NotEqual} (MOVDconst [0]) (MOVDconst [1]) (CMPW (MOV(H|B|B)reg x) (MOV(H|B|B)reg y)))
-(Neq64F      x y) => (LOCGR {s390x.NotEqual} (MOVDconst [0]) (MOVDconst [1]) (FCMP x y))
-(Neq32F      x y) => (LOCGR {s390x.NotEqual} (MOVDconst [0]) (MOVDconst [1]) (FCMPS x y))
-
-// Lowering loads
-(Load <t> ptr mem) && (is64BitInt(t) || isPtr(t)) => (MOVDload ptr mem)
-(Load <t> ptr mem) && is32BitInt(t) && isSigned(t) => (MOVWload ptr mem)
-(Load <t> ptr mem) && is32BitInt(t) && !isSigned(t) => (MOVWZload ptr mem)
-(Load <t> ptr mem) && is16BitInt(t) && isSigned(t) => (MOVHload ptr mem)
-(Load <t> ptr mem) && is16BitInt(t) && !isSigned(t) => (MOVHZload ptr mem)
-(Load <t> ptr mem) && is8BitInt(t) && isSigned(t) => (MOVBload ptr mem)
-(Load <t> ptr mem) && (t.IsBoolean() || (is8BitInt(t) && !isSigned(t))) => (MOVBZload ptr mem)
-(Load <t> ptr mem) && is32BitFloat(t) => (FMOVSload ptr mem)
-(Load <t> ptr mem) && is64BitFloat(t) => (FMOVDload ptr mem)
-
-// Lowering stores
-// These more-specific FP versions of Store pattern should come first.
-(Store {t} ptr val mem) && t.Size() == 8 && is64BitFloat(val.Type) => (FMOVDstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 4 && is32BitFloat(val.Type) => (FMOVSstore ptr val mem)
-
-(Store {t} ptr val mem) && t.Size() == 8 => (MOVDstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 4 => (MOVWstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 2 => (MOVHstore ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 1 => (MOVBstore ptr val mem)
-
-// Lowering moves
-
-// Load and store for small copies.
-(Move [0] _ _ mem) => mem
-(Move [1] dst src mem) => (MOVBstore dst (MOVBZload src mem) mem)
-(Move [2] dst src mem) => (MOVHstore dst (MOVHZload src mem) mem)
-(Move [4] dst src mem) => (MOVWstore dst (MOVWZload src mem) mem)
-(Move [8] dst src mem) => (MOVDstore dst (MOVDload src mem) mem)
-(Move [16] dst src mem) =>
-	(MOVDstore [8] dst (MOVDload [8] src mem)
-		(MOVDstore dst (MOVDload src mem) mem))
-(Move [24] dst src mem) =>
-        (MOVDstore [16] dst (MOVDload [16] src mem)
-	        (MOVDstore [8] dst (MOVDload [8] src mem)
-                (MOVDstore dst (MOVDload src mem) mem)))
-(Move [3] dst src mem) =>
-	(MOVBstore [2] dst (MOVBZload [2] src mem)
-		(MOVHstore dst (MOVHZload src mem) mem))
-(Move [5] dst src mem) =>
-	(MOVBstore [4] dst (MOVBZload [4] src mem)
-		(MOVWstore dst (MOVWZload src mem) mem))
-(Move [6] dst src mem) =>
-	(MOVHstore [4] dst (MOVHZload [4] src mem)
-		(MOVWstore dst (MOVWZload src mem) mem))
-(Move [7] dst src mem) =>
-	(MOVBstore [6] dst (MOVBZload [6] src mem)
-		(MOVHstore [4] dst (MOVHZload [4] src mem)
-			(MOVWstore dst (MOVWZload src mem) mem)))
-
-// MVC for other moves. Use up to 4 instructions (sizes up to 1024 bytes).
-(Move [s] dst src mem) && s > 0 && s <= 256 && logLargeCopy(v, s) =>
-	(MVC [makeValAndOff(int32(s), 0)] dst src mem)
-(Move [s] dst src mem) && s > 256 && s <= 512 && logLargeCopy(v, s) =>
-	(MVC [makeValAndOff(int32(s)-256, 256)] dst src (MVC [makeValAndOff(256, 0)] dst src mem))
-(Move [s] dst src mem) && s > 512 && s <= 768 && logLargeCopy(v, s) =>
-	(MVC [makeValAndOff(int32(s)-512, 512)] dst src (MVC [makeValAndOff(256, 256)] dst src (MVC [makeValAndOff(256, 0)] dst src mem)))
-(Move [s] dst src mem) && s > 768 && s <= 1024 && logLargeCopy(v, s) =>
-	(MVC [makeValAndOff(int32(s)-768, 768)] dst src (MVC [makeValAndOff(256, 512)] dst src (MVC [makeValAndOff(256, 256)] dst src (MVC [makeValAndOff(256, 0)] dst src mem))))
-
-// Move more than 1024 bytes using a loop.
-(Move [s] dst src mem) && s > 1024 && logLargeCopy(v, s) =>
-	(LoweredMove [s%256] dst src (ADD <src.Type> src (MOVDconst [(s/256)*256])) mem)
-
-// Lowering Zero instructions
-(Zero [0] _ mem) => mem
-(Zero [1] destptr mem) => (MOVBstoreconst [0] destptr mem)
-(Zero [2] destptr mem) => (MOVHstoreconst [0] destptr mem)
-(Zero [4] destptr mem) => (MOVWstoreconst [0] destptr mem)
-(Zero [8] destptr mem) => (MOVDstoreconst [0] destptr mem)
-(Zero [3] destptr mem) =>
-	(MOVBstoreconst [makeValAndOff(0,2)] destptr
-		(MOVHstoreconst [0] destptr mem))
-(Zero [5] destptr mem) =>
-	(MOVBstoreconst [makeValAndOff(0,4)] destptr
-		(MOVWstoreconst [0] destptr mem))
-(Zero [6] destptr mem) =>
-	(MOVHstoreconst [makeValAndOff(0,4)] destptr
-		(MOVWstoreconst [0] destptr mem))
-(Zero [7] destptr mem) =>
-	(MOVWstoreconst [makeValAndOff(0,3)] destptr
-		(MOVWstoreconst [0] destptr mem))
-
-(Zero [s] destptr mem) && s > 0 && s <= 1024 =>
-	(CLEAR [makeValAndOff(int32(s), 0)] destptr mem)
-
-// Zero more than 1024 bytes using a loop.
-(Zero [s] destptr mem) && s > 1024 =>
-	(LoweredZero [s%256] destptr (ADDconst <destptr.Type> destptr [(int32(s)/256)*256]) mem)
-
-// Lowering constants
-(Const(64|32|16|8) [val]) => (MOVDconst [int64(val)])
-(Const(32|64)F ...) => (FMOV(S|D)const ...)
-(ConstNil) => (MOVDconst [0])
-(ConstBool [t]) => (MOVDconst [b2i(t)])
-
-// Lowering calls
-(StaticCall ...) => (CALLstatic ...)
-(ClosureCall ...) => (CALLclosure ...)
-(InterCall ...) => (CALLinter ...)
-(TailCall ...) => (CALLtail ...)
-
-// Miscellaneous
-(IsNonNil p) => (LOCGR {s390x.NotEqual} (MOVDconst [0]) (MOVDconst [1]) (CMPconst p [0]))
-(IsInBounds idx len) => (LOCGR {s390x.Less} (MOVDconst [0]) (MOVDconst [1]) (CMPU idx len))
-(IsSliceInBounds idx len) => (LOCGR {s390x.LessOrEqual} (MOVDconst [0]) (MOVDconst [1]) (CMPU idx len))
-(NilCheck ...) => (LoweredNilCheck ...)
-(GetG ...) => (LoweredGetG ...)
-(GetClosurePtr ...) => (LoweredGetClosurePtr ...)
-(GetCallerSP ...) => (LoweredGetCallerSP ...)
-(GetCallerPC ...) => (LoweredGetCallerPC ...)
-(Addr {sym} base) => (MOVDaddr {sym} base)
-(LocalAddr {sym} base _) => (MOVDaddr {sym} base)
-(ITab (Load ptr mem)) => (MOVDload ptr mem)
-
-// block rewrites
-(If cond yes no) => (CLIJ {s390x.LessOrGreater} (MOVBZreg <typ.Bool> cond) [0] yes no)
-
-// Write barrier.
-(WB ...) => (LoweredWB ...)
-
-(PanicBounds [kind] x y mem) && boundsABI(kind) == 0 => (LoweredPanicBoundsA [kind] x y mem)
-(PanicBounds [kind] x y mem) && boundsABI(kind) == 1 => (LoweredPanicBoundsB [kind] x y mem)
-(PanicBounds [kind] x y mem) && boundsABI(kind) == 2 => (LoweredPanicBoundsC [kind] x y mem)
-
-// ***************************
-// Above: lowering rules
-// Below: optimizations
-// ***************************
-// TODO: Should the optimizations be a separate pass?
-
-// Note: when removing unnecessary sign/zero extensions.
-//
-// After a value is spilled it is restored using a sign- or zero-extension
-// to register-width as appropriate for its type. For example, a uint8 will
-// be restored using a MOVBZ (llgc) instruction which will zero extend the
-// 8-bit value to 64-bits.
-//
-// This is a hazard when folding sign- and zero-extensions since we need to
-// ensure not only that the value in the argument register is correctly
-// extended but also that it will still be correctly extended if it is
-// spilled and restored.
-//
-// In general this means we need type checks when the RHS of a rule is an
-// OpCopy (i.e. "(... x:(...) ...) -> x").
-
-// Merge double extensions.
-(MOV(H|HZ)reg e:(MOV(B|BZ)reg x)) && clobberIfDead(e) => (MOV(B|BZ)reg x)
-(MOV(W|WZ)reg e:(MOV(B|BZ)reg x)) && clobberIfDead(e) => (MOV(B|BZ)reg x)
-(MOV(W|WZ)reg e:(MOV(H|HZ)reg x)) && clobberIfDead(e) => (MOV(H|HZ)reg x)
-
-// Bypass redundant sign extensions.
-(MOV(B|BZ)reg e:(MOVBreg x)) && clobberIfDead(e) => (MOV(B|BZ)reg x)
-(MOV(B|BZ)reg e:(MOVHreg x)) && clobberIfDead(e) => (MOV(B|BZ)reg x)
-(MOV(B|BZ)reg e:(MOVWreg x)) && clobberIfDead(e) => (MOV(B|BZ)reg x)
-(MOV(H|HZ)reg e:(MOVHreg x)) && clobberIfDead(e) => (MOV(H|HZ)reg x)
-(MOV(H|HZ)reg e:(MOVWreg x)) && clobberIfDead(e) => (MOV(H|HZ)reg x)
-(MOV(W|WZ)reg e:(MOVWreg x)) && clobberIfDead(e) => (MOV(W|WZ)reg x)
-
-// Bypass redundant zero extensions.
-(MOV(B|BZ)reg e:(MOVBZreg x)) && clobberIfDead(e) => (MOV(B|BZ)reg x)
-(MOV(B|BZ)reg e:(MOVHZreg x)) && clobberIfDead(e) => (MOV(B|BZ)reg x)
-(MOV(B|BZ)reg e:(MOVWZreg x)) && clobberIfDead(e) => (MOV(B|BZ)reg x)
-(MOV(H|HZ)reg e:(MOVHZreg x)) && clobberIfDead(e) => (MOV(H|HZ)reg x)
-(MOV(H|HZ)reg e:(MOVWZreg x)) && clobberIfDead(e) => (MOV(H|HZ)reg x)
-(MOV(W|WZ)reg e:(MOVWZreg x)) && clobberIfDead(e) => (MOV(W|WZ)reg x)
-
-// Remove zero extensions after zero extending load.
-// Note: take care that if x is spilled it is restored correctly.
-(MOV(B|H|W)Zreg x:(MOVBZload    _   _)) && (!x.Type.IsSigned() || x.Type.Size() > 1) => x
-(MOV(H|W)Zreg   x:(MOVHZload    _   _)) && (!x.Type.IsSigned() || x.Type.Size() > 2) => x
-(MOVWZreg       x:(MOVWZload    _   _)) && (!x.Type.IsSigned() || x.Type.Size() > 4) => x
-
-// Remove sign extensions after sign extending load.
-// Note: take care that if x is spilled it is restored correctly.
-(MOV(B|H|W)reg x:(MOVBload    _   _)) && (x.Type.IsSigned() || x.Type.Size() == 8) => x
-(MOV(H|W)reg   x:(MOVHload    _   _)) && (x.Type.IsSigned() || x.Type.Size() == 8) => x
-(MOVWreg       x:(MOVWload    _   _)) && (x.Type.IsSigned() || x.Type.Size() == 8) => x
-
-// Remove sign extensions after zero extending load.
-// These type checks are probably unnecessary but do them anyway just in case.
-(MOV(H|W)reg x:(MOVBZload    _   _)) && (!x.Type.IsSigned() || x.Type.Size() > 1) => x
-(MOVWreg     x:(MOVHZload    _   _)) && (!x.Type.IsSigned() || x.Type.Size() > 2) => x
-
-// Fold sign and zero extensions into loads.
-//
-// Note: The combined instruction must end up in the same block
-// as the original load. If not, we end up making a value with
-// memory type live in two different blocks, which can lead to
-// multiple memory values alive simultaneously.
-//
-// Make sure we don't combine these ops if the load has another use.
-// This prevents a single load from being split into multiple loads
-// which then might return different values.  See test/atomicload.go.
-(MOV(B|H|W)Zreg <t> x:(MOV(B|H|W)load [o] {s} p mem))
-  && x.Uses == 1
-  && clobber(x)
-  => @x.Block (MOV(B|H|W)Zload <t> [o] {s} p mem)
-(MOV(B|H|W)reg <t> x:(MOV(B|H|W)Zload [o] {s} p mem))
-  && x.Uses == 1
-  && clobber(x)
-  => @x.Block (MOV(B|H|W)load <t> [o] {s} p mem)
-
-// Remove zero extensions after argument load.
-(MOVBZreg x:(Arg <t>)) && !t.IsSigned() && t.Size() == 1 => x
-(MOVHZreg x:(Arg <t>)) && !t.IsSigned() && t.Size() <= 2 => x
-(MOVWZreg x:(Arg <t>)) && !t.IsSigned() && t.Size() <= 4 => x
-
-// Remove sign extensions after argument load.
-(MOVBreg x:(Arg <t>)) && t.IsSigned() && t.Size() == 1 => x
-(MOVHreg x:(Arg <t>)) && t.IsSigned() && t.Size() <= 2 => x
-(MOVWreg x:(Arg <t>)) && t.IsSigned() && t.Size() <= 4 => x
-
-// Fold zero extensions into constants.
-(MOVBZreg (MOVDconst [c])) => (MOVDconst [int64( uint8(c))])
-(MOVHZreg (MOVDconst [c])) => (MOVDconst [int64(uint16(c))])
-(MOVWZreg (MOVDconst [c])) => (MOVDconst [int64(uint32(c))])
-
-// Fold sign extensions into constants.
-(MOVBreg (MOVDconst [c])) => (MOVDconst [int64( int8(c))])
-(MOVHreg (MOVDconst [c])) => (MOVDconst [int64(int16(c))])
-(MOVWreg (MOVDconst [c])) => (MOVDconst [int64(int32(c))])
-
-// Remove zero extension of conditional move.
-// Note: only for MOVBZreg for now since it is added as part of 'if' statement lowering.
-(MOVBZreg x:(LOCGR (MOVDconst [c]) (MOVDconst [d]) _))
-  && int64(uint8(c)) == c
-  && int64(uint8(d)) == d
-  && (!x.Type.IsSigned() || x.Type.Size() > 1)
-  => x
-
-// Fold boolean tests into blocks.
-// Note: this must match If statement lowering.
-(CLIJ {s390x.LessOrGreater} (LOCGR {d} (MOVDconst [0]) (MOVDconst [x]) cmp) [0] yes no)
-  && int32(x) != 0
-  => (BRC {d} cmp yes no)
-
-// Canonicalize BRC condition code mask by removing impossible conditions.
-// Integer comparisons cannot generate the unordered condition.
-(BRC {c} x:((CMP|CMPW|CMPU|CMPWU)    _ _) yes no) && c&s390x.Unordered != 0 => (BRC {c&^s390x.Unordered} x yes no)
-(BRC {c} x:((CMP|CMPW|CMPU|CMPWU)const _) yes no) && c&s390x.Unordered != 0 => (BRC {c&^s390x.Unordered} x yes no)
-
-// Compare-and-branch.
-// Note: bit 3 (unordered) must not be set so we mask out s390x.Unordered.
-(BRC {c} (CMP   x y) yes no) => (CGRJ  {c&^s390x.Unordered} x y yes no)
-(BRC {c} (CMPW  x y) yes no) => (CRJ   {c&^s390x.Unordered} x y yes no)
-(BRC {c} (CMPU  x y) yes no) => (CLGRJ {c&^s390x.Unordered} x y yes no)
-(BRC {c} (CMPWU x y) yes no) => (CLRJ  {c&^s390x.Unordered} x y yes no)
-
-// Compare-and-branch (immediate).
-// Note: bit 3 (unordered) must not be set so we mask out s390x.Unordered.
-(BRC {c} (CMPconst   x [y]) yes no) && y == int32( int8(y)) => (CGIJ  {c&^s390x.Unordered} x [ int8(y)] yes no)
-(BRC {c} (CMPWconst  x [y]) yes no) && y == int32( int8(y)) => (CIJ   {c&^s390x.Unordered} x [ int8(y)] yes no)
-(BRC {c} (CMPUconst  x [y]) yes no) && y == int32(uint8(y)) => (CLGIJ {c&^s390x.Unordered} x [uint8(y)] yes no)
-(BRC {c} (CMPWUconst x [y]) yes no) && y == int32(uint8(y)) => (CLIJ  {c&^s390x.Unordered} x [uint8(y)] yes no)
-
-// Absorb immediate into compare-and-branch.
-(C(R|GR)J  {c} x (MOVDconst [y]) yes no) && is8Bit(y)  => (C(I|GI)J  {c} x [ int8(y)] yes no)
-(CL(R|GR)J {c} x (MOVDconst [y]) yes no) && isU8Bit(y) => (CL(I|GI)J {c} x [uint8(y)] yes no)
-(C(R|GR)J  {c} (MOVDconst [x]) y yes no) && is8Bit(x)  => (C(I|GI)J  {c.ReverseComparison()} y [ int8(x)] yes no)
-(CL(R|GR)J {c} (MOVDconst [x]) y yes no) && isU8Bit(x) => (CL(I|GI)J {c.ReverseComparison()} y [uint8(x)] yes no)
-
-// Prefer comparison with immediate to compare-and-branch.
-(CGRJ  {c} x (MOVDconst [y]) yes no) && !is8Bit(y)  && is32Bit(y)  => (BRC {c} (CMPconst   x [int32(y)]) yes no)
-(CRJ   {c} x (MOVDconst [y]) yes no) && !is8Bit(y)  && is32Bit(y)  => (BRC {c} (CMPWconst  x [int32(y)]) yes no)
-(CLGRJ {c} x (MOVDconst [y]) yes no) && !isU8Bit(y) && isU32Bit(y) => (BRC {c} (CMPUconst  x [int32(y)]) yes no)
-(CLRJ  {c} x (MOVDconst [y]) yes no) && !isU8Bit(y) && isU32Bit(y) => (BRC {c} (CMPWUconst x [int32(y)]) yes no)
-(CGRJ  {c} (MOVDconst [x]) y yes no) && !is8Bit(x)  && is32Bit(x)  => (BRC {c.ReverseComparison()} (CMPconst   y [int32(x)]) yes no)
-(CRJ   {c} (MOVDconst [x]) y yes no) && !is8Bit(x)  && is32Bit(x)  => (BRC {c.ReverseComparison()} (CMPWconst  y [int32(x)]) yes no)
-(CLGRJ {c} (MOVDconst [x]) y yes no) && !isU8Bit(x) && isU32Bit(x) => (BRC {c.ReverseComparison()} (CMPUconst  y [int32(x)]) yes no)
-(CLRJ  {c} (MOVDconst [x]) y yes no) && !isU8Bit(x) && isU32Bit(x) => (BRC {c.ReverseComparison()} (CMPWUconst y [int32(x)]) yes no)
-
-// Absorb sign/zero extensions into 32-bit compare-and-branch.
-(CIJ  {c} (MOV(W|WZ)reg x) [y] yes no) => (CIJ  {c} x [y] yes no)
-(CLIJ {c} (MOV(W|WZ)reg x) [y] yes no) => (CLIJ {c} x [y] yes no)
-
-// Bring out-of-range signed immediates into range by varying branch condition.
-(BRC {s390x.Less}           (CMPconst  x [ 128]) yes no) => (CGIJ {s390x.LessOrEqual}    x [ 127] yes no)
-(BRC {s390x.Less}           (CMPWconst x [ 128]) yes no) => (CIJ  {s390x.LessOrEqual}    x [ 127] yes no)
-(BRC {s390x.LessOrEqual}    (CMPconst  x [-129]) yes no) => (CGIJ {s390x.Less}           x [-128] yes no)
-(BRC {s390x.LessOrEqual}    (CMPWconst x [-129]) yes no) => (CIJ  {s390x.Less}           x [-128] yes no)
-(BRC {s390x.Greater}        (CMPconst  x [-129]) yes no) => (CGIJ {s390x.GreaterOrEqual} x [-128] yes no)
-(BRC {s390x.Greater}        (CMPWconst x [-129]) yes no) => (CIJ  {s390x.GreaterOrEqual} x [-128] yes no)
-(BRC {s390x.GreaterOrEqual} (CMPconst  x [ 128]) yes no) => (CGIJ {s390x.Greater}        x [ 127] yes no)
-(BRC {s390x.GreaterOrEqual} (CMPWconst x [ 128]) yes no) => (CIJ  {s390x.Greater}        x [ 127] yes no)
-
-// Bring out-of-range unsigned immediates into range by varying branch condition.
-(BRC {s390x.Less}           (CMP(WU|U)const  x [256]) yes no) => (C(L|LG)IJ {s390x.LessOrEqual} x [255] yes no)
-(BRC {s390x.GreaterOrEqual} (CMP(WU|U)const  x [256]) yes no) => (C(L|LG)IJ {s390x.Greater}     x [255] yes no)
-
-// Bring out-of-range immediates into range by switching signedness (only == and !=).
-(BRC {c} (CMPconst   x [y]) yes no) && y == int32(uint8(y)) && (c == s390x.Equal || c == s390x.LessOrGreater) => (CLGIJ {c} x [uint8(y)] yes no)
-(BRC {c} (CMPWconst  x [y]) yes no) && y == int32(uint8(y)) && (c == s390x.Equal || c == s390x.LessOrGreater) => (CLIJ  {c} x [uint8(y)] yes no)
-(BRC {c} (CMPUconst  x [y]) yes no) && y == int32( int8(y)) && (c == s390x.Equal || c == s390x.LessOrGreater) => (CGIJ  {c} x [ int8(y)] yes no)
-(BRC {c} (CMPWUconst x [y]) yes no) && y == int32( int8(y)) && (c == s390x.Equal || c == s390x.LessOrGreater) => (CIJ   {c} x [ int8(y)] yes no)
-
-// Fold constants into instructions.
-(ADD x (MOVDconst [c])) && is32Bit(c) => (ADDconst [int32(c)] x)
-(ADDW x (MOVDconst [c])) => (ADDWconst [int32(c)] x)
-
-(SUB x (MOVDconst [c])) && is32Bit(c) => (SUBconst x [int32(c)])
-(SUB (MOVDconst [c]) x) && is32Bit(c) => (NEG (SUBconst <v.Type> x [int32(c)]))
-(SUBW x (MOVDconst [c])) => (SUBWconst x [int32(c)])
-(SUBW (MOVDconst [c]) x) => (NEGW (SUBWconst <v.Type> x [int32(c)]))
-
-(MULLD x (MOVDconst [c])) && is32Bit(c) => (MULLDconst [int32(c)] x)
-(MULLW x (MOVDconst [c])) => (MULLWconst [int32(c)] x)
-
-// NILF instructions leave the high 32 bits unchanged which is
-// equivalent to the leftmost 32 bits being set.
-// TODO(mundaym): modify the assembler to accept 64-bit values
-// and use isU32Bit(^c).
-(AND x (MOVDconst [c]))
-  && s390x.NewRotateParams(0, 63, 0).OutMerge(uint64(c)) != nil
-  => (RISBGZ x {*s390x.NewRotateParams(0, 63, 0).OutMerge(uint64(c))})
-(AND x (MOVDconst [c]))
-  && is32Bit(c)
-  && c < 0
-  => (ANDconst [c] x)
-(AND x (MOVDconst [c]))
-  && is32Bit(c)
-  && c >= 0
-  => (MOVWZreg (ANDWconst <typ.UInt32> [int32(c)] x))
-
-(ANDW x (MOVDconst [c])) => (ANDWconst [int32(c)] x)
-
-((AND|ANDW)const [c] ((AND|ANDW)const [d] x)) => ((AND|ANDW)const [c&d] x)
-
-((OR|XOR) x (MOVDconst [c])) && isU32Bit(c) => ((OR|XOR)const [c] x)
-((OR|XOR)W x (MOVDconst [c])) => ((OR|XOR)Wconst [int32(c)] x)
-
-// Constant shifts.
-(S(LD|RD|RAD) x (MOVDconst [c])) => (S(LD|RD|RAD)const x [uint8(c&63)])
-(S(LW|RW|RAW) x (MOVDconst [c])) && c&32 == 0 => (S(LW|RW|RAW)const x [uint8(c&31)])
-(S(LW|RW)     _ (MOVDconst [c])) && c&32 != 0 => (MOVDconst [0])
-(SRAW         x (MOVDconst [c])) && c&32 != 0 => (SRAWconst x [31])
-
-// Shifts only use the rightmost 6 bits of the shift value.
-(S(LD|RD|RAD|LW|RW|RAW) x (RISBGZ y {r}))
-  && r.Amount == 0
-  && r.OutMask()&63 == 63
-  => (S(LD|RD|RAD|LW|RW|RAW) x y)
-(S(LD|RD|RAD|LW|RW|RAW) x (AND (MOVDconst [c]) y))
-  => (S(LD|RD|RAD|LW|RW|RAW) x (ANDWconst <typ.UInt32> [int32(c&63)] y))
-(S(LD|RD|RAD|LW|RW|RAW) x (ANDWconst [c] y)) && c&63 == 63
-  => (S(LD|RD|RAD|LW|RW|RAW) x y)
-(SLD  x (MOV(W|H|B|WZ|HZ|BZ)reg y)) => (SLD  x y)
-(SRD  x (MOV(W|H|B|WZ|HZ|BZ)reg y)) => (SRD  x y)
-(SRAD x (MOV(W|H|B|WZ|HZ|BZ)reg y)) => (SRAD x y)
-(SLW  x (MOV(W|H|B|WZ|HZ|BZ)reg y)) => (SLW  x y)
-(SRW  x (MOV(W|H|B|WZ|HZ|BZ)reg y)) => (SRW  x y)
-(SRAW x (MOV(W|H|B|WZ|HZ|BZ)reg y)) => (SRAW x y)
-
-// Match rotate by constant.
-(RLLG x (MOVDconst [c])) => (RISBGZ x {s390x.NewRotateParams(0, 63, uint8(c&63))})
-(RLL  x (MOVDconst [c])) => (RLLconst x [uint8(c&31)])
-
-// Match rotate by constant pattern.
-((ADD|OR|XOR)  (SLDconst x [c]) (SRDconst x [64-c])) => (RISBGZ x {s390x.NewRotateParams(0, 63, c)})
-((ADD|OR|XOR)W (SLWconst x [c]) (SRWconst x [32-c])) => (RLLconst x [c])
-
-// Signed 64-bit comparison with immediate.
-(CMP x (MOVDconst [c])) && is32Bit(c) => (CMPconst x [int32(c)])
-(CMP (MOVDconst [c]) x) && is32Bit(c) => (InvertFlags (CMPconst x [int32(c)]))
-
-// Unsigned 64-bit comparison with immediate.
-(CMPU x (MOVDconst [c])) && isU32Bit(c) => (CMPUconst x [int32(c)])
-(CMPU (MOVDconst [c]) x) && isU32Bit(c) => (InvertFlags (CMPUconst x [int32(c)]))
-
-// Signed and unsigned 32-bit comparison with immediate.
-(CMP(W|WU) x (MOVDconst [c])) => (CMP(W|WU)const x [int32(c)])
-(CMP(W|WU) (MOVDconst [c]) x) => (InvertFlags (CMP(W|WU)const x [int32(c)]))
-
-// Match (x >> c) << d to 'rotate then insert selected bits [into zero]'.
-(SLDconst (SRDconst x [c]) [d]) => (RISBGZ x {s390x.NewRotateParams(uint8(max8(0, int8(c-d))), 63-d, uint8(int8(d-c)&63))})
-
-// Match (x << c) >> d to 'rotate then insert selected bits [into zero]'.
-(SRDconst (SLDconst x [c]) [d]) => (RISBGZ x {s390x.NewRotateParams(d, uint8(min8(63, int8(63-c+d))), uint8(int8(c-d)&63))})
-
-// Absorb input zero extension into 'rotate then insert selected bits [into zero]'.
-(RISBGZ (MOVWZreg x) {r}) && r.InMerge(0xffffffff) != nil => (RISBGZ x {*r.InMerge(0xffffffff)})
-(RISBGZ (MOVHZreg x) {r}) && r.InMerge(0x0000ffff) != nil => (RISBGZ x {*r.InMerge(0x0000ffff)})
-(RISBGZ (MOVBZreg x) {r}) && r.InMerge(0x000000ff) != nil => (RISBGZ x {*r.InMerge(0x000000ff)})
-
-// Absorb 'rotate then insert selected bits [into zero]' into zero extension.
-(MOVWZreg (RISBGZ x {r})) && r.OutMerge(0xffffffff) != nil => (RISBGZ x {*r.OutMerge(0xffffffff)})
-(MOVHZreg (RISBGZ x {r})) && r.OutMerge(0x0000ffff) != nil => (RISBGZ x {*r.OutMerge(0x0000ffff)})
-(MOVBZreg (RISBGZ x {r})) && r.OutMerge(0x000000ff) != nil => (RISBGZ x {*r.OutMerge(0x000000ff)})
-
-// Absorb shift into 'rotate then insert selected bits [into zero]'.
-//
-// Any unsigned shift can be represented as a rotate and mask operation:
-//
-//   x << c => RotateLeft64(x, c) & (^uint64(0) << c)
-//   x >> c => RotateLeft64(x, -c) & (^uint64(0) >> c)
-//
-// Therefore when a shift is used as the input to a rotate then insert
-// selected bits instruction we can merge the two together. We just have
-// to be careful that the resultant mask is representable (non-zero and
-// contiguous). For example, assuming that x is variable and c, y and m
-// are constants, a shift followed by a rotate then insert selected bits
-// could be represented as:
-//
-//   RotateLeft64(RotateLeft64(x, c) & (^uint64(0) << c), y) & m
-//
-// We can split the rotation by y into two, one rotate for x and one for
-// the mask:
-//
-//   RotateLeft64(RotateLeft64(x, c), y) & (RotateLeft64(^uint64(0) << c, y)) & m
-//
-// The rotations of x by c followed by y can then be combined:
-//
-//   RotateLeft64(x, c+y) & (RotateLeft64(^uint64(0) << c, y)) & m
-//   ^^^^^^^^^^^^^^^^^^^^   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-//          rotate                          mask
-//
-// To perform this optimization we therefore just need to check that it
-// is valid to merge the shift mask (^(uint64(0)<<c)) into the selected
-// bits mask (i.e. that the resultant mask is non-zero and contiguous).
-//
-(RISBGZ (SLDconst x [c]) {r}) && r.InMerge(^uint64(0)<<c) != nil => (RISBGZ x {(*r.InMerge(^uint64(0)<<c)).RotateLeft(c)})
-(RISBGZ (SRDconst x [c]) {r}) && r.InMerge(^uint64(0)>>c) != nil => (RISBGZ x {(*r.InMerge(^uint64(0)>>c)).RotateLeft(-c)})
-
-// Absorb 'rotate then insert selected bits [into zero]' into left shift.
-(SLDconst (RISBGZ x {r}) [c])
-  && s390x.NewRotateParams(0, 63-c, c).InMerge(r.OutMask()) != nil
-  => (RISBGZ x {(*s390x.NewRotateParams(0, 63-c, c).InMerge(r.OutMask())).RotateLeft(r.Amount)})
-
-// Absorb 'rotate then insert selected bits [into zero]' into right shift.
-(SRDconst (RISBGZ x {r}) [c])
-  && s390x.NewRotateParams(c, 63, -c&63).InMerge(r.OutMask()) != nil
-  => (RISBGZ x {(*s390x.NewRotateParams(c, 63, -c&63).InMerge(r.OutMask())).RotateLeft(r.Amount)})
-
-// Merge 'rotate then insert selected bits [into zero]' instructions together.
-(RISBGZ (RISBGZ x {y}) {z})
-  && z.InMerge(y.OutMask()) != nil
-  => (RISBGZ x {(*z.InMerge(y.OutMask())).RotateLeft(y.Amount)})
-
-// Convert RISBGZ into 64-bit shift (helps CSE).
-(RISBGZ x {r}) && r.End == 63 && r.Start == -r.Amount&63 => (SRDconst x [-r.Amount&63])
-(RISBGZ x {r}) && r.Start == 0 && r.End == 63-r.Amount => (SLDconst x [r.Amount])
-
-// Optimize single bit isolation when it is known to be equivalent to
-// the most significant bit due to mask produced by arithmetic shift.
-// Simply isolate the most significant bit itself and place it in the
-// correct position.
-//
-// Example: (int64(x) >> 63) & 0x8 -> RISBGZ $60, $60, $4, Rsrc, Rdst
-(RISBGZ (SRADconst x [c]) {r})
-  && r.Start == r.End           // single bit selected
-  && (r.Start+r.Amount)&63 <= c // equivalent to most significant bit of x
-  => (RISBGZ x {s390x.NewRotateParams(r.Start, r.Start, -r.Start&63)})
-
-// Canonicalize the order of arguments to comparisons - helps with CSE.
-((CMP|CMPW|CMPU|CMPWU) x y) && canonLessThan(x,y) => (InvertFlags ((CMP|CMPW|CMPU|CMPWU) y x))
-
-// Use sign/zero extend instead of RISBGZ.
-(RISBGZ x {r}) && r == s390x.NewRotateParams(56, 63, 0) => (MOVBZreg x)
-(RISBGZ x {r}) && r == s390x.NewRotateParams(48, 63, 0) => (MOVHZreg x)
-(RISBGZ x {r}) && r == s390x.NewRotateParams(32, 63, 0) => (MOVWZreg x)
-
-// Use sign/zero extend instead of ANDW.
-(ANDWconst [0x00ff] x) => (MOVBZreg x)
-(ANDWconst [0xffff] x) => (MOVHZreg x)
-
-// Strength reduce multiplication to the sum (or difference) of two powers of two.
-//
-// Examples:
-//     5x -> 4x + 1x
-//    10x -> 8x + 2x
-//   120x -> 128x - 8x
-//  -120x -> 8x - 128x
-//
-// We know that the rightmost bit of any positive value, once isolated, must either
-// be a power of 2 (because it is a single bit) or 0 (if the original value is 0).
-// In all of these rules we use a rightmost bit calculation to determine one operand
-// for the addition or subtraction. We then just need to calculate if the other
-// operand is a valid power of 2 before we can match the rule.
-//
-// Notes:
-//   - the generic rules have already matched single powers of two so we ignore them here
-//   - isPowerOfTwo32 asserts that its argument is greater than 0
-//   - c&(c-1) = clear rightmost bit
-//   - c&^(c-1) = isolate rightmost bit
-
-// c = 2ˣ + 2ʸ => c - 2ˣ = 2ʸ
-(MULL(D|W)const <t> x [c]) && isPowerOfTwo32(c&(c-1))
-  => ((ADD|ADDW) (SL(D|W)const <t> x [uint8(log32(c&(c-1)))])
-                 (SL(D|W)const <t> x [uint8(log32(c&^(c-1)))]))
-
-// c = 2ʸ - 2ˣ => c + 2ˣ = 2ʸ
-(MULL(D|W)const <t> x [c]) && isPowerOfTwo32(c+(c&^(c-1)))
-  => ((SUB|SUBW) (SL(D|W)const <t> x [uint8(log32(c+(c&^(c-1))))])
-                 (SL(D|W)const <t> x [uint8(log32(c&^(c-1)))]))
-
-// c = 2ˣ - 2ʸ => -c + 2ˣ = 2ʸ
-(MULL(D|W)const <t> x [c]) && isPowerOfTwo32(-c+(-c&^(-c-1)))
-  => ((SUB|SUBW) (SL(D|W)const <t> x [uint8(log32(-c&^(-c-1)))])
-                 (SL(D|W)const <t> x [uint8(log32(-c+(-c&^(-c-1))))]))
-
-// Fold ADD into MOVDaddr. Odd offsets from SB shouldn't be folded (LARL can't handle them).
-(ADDconst [c] (MOVDaddr [d] {s} x:(SB))) && ((c+d)&1 == 0) && is32Bit(int64(c)+int64(d)) => (MOVDaddr [c+d] {s} x)
-(ADDconst [c] (MOVDaddr [d] {s} x)) && x.Op != OpSB && is20Bit(int64(c)+int64(d)) => (MOVDaddr [c+d] {s} x)
-(ADD idx (MOVDaddr [c] {s} ptr)) && ptr.Op != OpSB => (MOVDaddridx [c] {s} ptr idx)
-
-// fold ADDconst into MOVDaddrx
-(ADDconst [c] (MOVDaddridx [d] {s} x y)) && is20Bit(int64(c)+int64(d)) => (MOVDaddridx [c+d] {s} x y)
-(MOVDaddridx [c] {s} (ADDconst [d] x) y) && is20Bit(int64(c)+int64(d)) => (MOVDaddridx [c+d] {s} x y)
-(MOVDaddridx [c] {s} x (ADDconst [d] y)) && is20Bit(int64(c)+int64(d)) => (MOVDaddridx [c+d] {s} x y)
-
-// reverse ordering of compare instruction
-(LOCGR {c} x y (InvertFlags cmp)) => (LOCGR {c.ReverseComparison()} x y cmp)
-
-// replace load from same location as preceding store with copy
-(MOVDload  [off] {sym} ptr1 (MOVDstore  [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) => x
-(MOVWload  [off] {sym} ptr1 (MOVWstore  [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) => (MOVWreg x)
-(MOVHload  [off] {sym} ptr1 (MOVHstore  [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) => (MOVHreg x)
-(MOVBload  [off] {sym} ptr1 (MOVBstore  [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) => (MOVBreg x)
-(MOVWZload [off] {sym} ptr1 (MOVWstore  [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) => (MOVWZreg x)
-(MOVHZload [off] {sym} ptr1 (MOVHstore  [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) => (MOVHZreg x)
-(MOVBZload [off] {sym} ptr1 (MOVBstore  [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) => (MOVBZreg x)
-(MOVDload  [off] {sym} ptr1 (FMOVDstore [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) => (LGDR x)
-(FMOVDload [off] {sym} ptr1 (MOVDstore  [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) => (LDGR x)
-(FMOVDload [off] {sym} ptr1 (FMOVDstore [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) => x
-(FMOVSload [off] {sym} ptr1 (FMOVSstore [off] {sym} ptr2 x _)) && isSamePtr(ptr1, ptr2) => x
-
-// prefer FPR <-> GPR moves over combined load ops
-(MULLDload <t> [off] {sym} x ptr1 (FMOVDstore [off] {sym} ptr2 y _)) && isSamePtr(ptr1, ptr2) => (MULLD x (LGDR <t> y))
-(ADDload   <t> [off] {sym} x ptr1 (FMOVDstore [off] {sym} ptr2 y _)) && isSamePtr(ptr1, ptr2) => (ADD   x (LGDR <t> y))
-(SUBload   <t> [off] {sym} x ptr1 (FMOVDstore [off] {sym} ptr2 y _)) && isSamePtr(ptr1, ptr2) => (SUB   x (LGDR <t> y))
-(ORload    <t> [off] {sym} x ptr1 (FMOVDstore [off] {sym} ptr2 y _)) && isSamePtr(ptr1, ptr2) => (OR    x (LGDR <t> y))
-(ANDload   <t> [off] {sym} x ptr1 (FMOVDstore [off] {sym} ptr2 y _)) && isSamePtr(ptr1, ptr2) => (AND   x (LGDR <t> y))
-(XORload   <t> [off] {sym} x ptr1 (FMOVDstore [off] {sym} ptr2 y _)) && isSamePtr(ptr1, ptr2) => (XOR   x (LGDR <t> y))
-
-// detect attempts to set/clear the sign bit
-// may need to be reworked when NIHH/OIHH are added
-(RISBGZ (LGDR <t> x) {r}) && r == s390x.NewRotateParams(1, 63, 0) => (LGDR <t> (LPDFR <x.Type> x))
-(LDGR <t> (RISBGZ x {r})) && r == s390x.NewRotateParams(1, 63, 0) => (LPDFR (LDGR <t> x))
-(OR (MOVDconst [-1<<63]) (LGDR <t> x)) => (LGDR <t> (LNDFR <x.Type> x))
-(LDGR <t> (OR (MOVDconst [-1<<63]) x)) => (LNDFR (LDGR <t> x))
-
-// detect attempts to set the sign bit with load
-(LDGR <t> x:(ORload <t1> [off] {sym} (MOVDconst [-1<<63]) ptr mem)) && x.Uses == 1 && clobber(x) => @x.Block (LNDFR <t> (LDGR <t> (MOVDload <t1> [off] {sym} ptr mem)))
-
-// detect copysign
-(OR (RISBGZ (LGDR x) {r}) (LGDR (LPDFR <t> y)))
-  && r == s390x.NewRotateParams(0, 0, 0)
-  => (LGDR (CPSDR <t> y x))
-(OR (RISBGZ (LGDR x) {r}) (MOVDconst [c]))
-  && c >= 0
-  && r == s390x.NewRotateParams(0, 0, 0)
-  => (LGDR (CPSDR <x.Type> (FMOVDconst <x.Type> [math.Float64frombits(uint64(c))]) x))
-(CPSDR y (FMOVDconst [c])) && !math.Signbit(c) => (LPDFR y)
-(CPSDR y (FMOVDconst [c])) && math.Signbit(c)  => (LNDFR y)
-
-// absorb negations into set/clear sign bit
-(FNEG  (LPDFR x)) => (LNDFR x)
-(FNEG  (LNDFR x)) => (LPDFR x)
-(FNEGS (LPDFR x)) => (LNDFR x)
-(FNEGS (LNDFR x)) => (LPDFR x)
-
-// no need to convert float32 to float64 to set/clear sign bit
-(LEDBR (LPDFR (LDEBR x))) => (LPDFR x)
-(LEDBR (LNDFR (LDEBR x))) => (LNDFR x)
-
-// remove unnecessary FPR <-> GPR moves
-(LDGR (LGDR x)) => x
-(LGDR (LDGR x)) => x
-
-// Don't extend before storing
-(MOVWstore [off] {sym} ptr (MOVWreg x) mem) => (MOVWstore [off] {sym} ptr x mem)
-(MOVHstore [off] {sym} ptr (MOVHreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr (MOVBreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
-(MOVWstore [off] {sym} ptr (MOVWZreg x) mem) => (MOVWstore [off] {sym} ptr x mem)
-(MOVHstore [off] {sym} ptr (MOVHZreg x) mem) => (MOVHstore [off] {sym} ptr x mem)
-(MOVBstore [off] {sym} ptr (MOVBZreg x) mem) => (MOVBstore [off] {sym} ptr x mem)
-
-// Fold constants into memory operations.
-// Note that this is not always a good idea because if not all the uses of
-// the ADDconst get eliminated, we still have to compute the ADDconst and we now
-// have potentially two live values (ptr and (ADDconst [off] ptr)) instead of one.
-// Nevertheless, let's do it!
-(MOVDload   [off1] {sym} (ADDconst [off2] ptr) mem) && is20Bit(int64(off1)+int64(off2)) => (MOVDload  [off1+off2] {sym} ptr mem)
-(MOVWload   [off1] {sym} (ADDconst [off2] ptr) mem) && is20Bit(int64(off1)+int64(off2)) => (MOVWload  [off1+off2] {sym} ptr mem)
-(MOVHload   [off1] {sym} (ADDconst [off2] ptr) mem) && is20Bit(int64(off1)+int64(off2)) => (MOVHload  [off1+off2] {sym} ptr mem)
-(MOVBload   [off1] {sym} (ADDconst [off2] ptr) mem) && is20Bit(int64(off1)+int64(off2)) => (MOVBload  [off1+off2] {sym} ptr mem)
-(MOVWZload  [off1] {sym} (ADDconst [off2] ptr) mem) && is20Bit(int64(off1)+int64(off2)) => (MOVWZload [off1+off2] {sym} ptr mem)
-(MOVHZload  [off1] {sym} (ADDconst [off2] ptr) mem) && is20Bit(int64(off1)+int64(off2)) => (MOVHZload [off1+off2] {sym} ptr mem)
-(MOVBZload  [off1] {sym} (ADDconst [off2] ptr) mem) && is20Bit(int64(off1)+int64(off2)) => (MOVBZload [off1+off2] {sym} ptr mem)
-(FMOVSload  [off1] {sym} (ADDconst [off2] ptr) mem) && is20Bit(int64(off1)+int64(off2)) => (FMOVSload [off1+off2] {sym} ptr mem)
-(FMOVDload  [off1] {sym} (ADDconst [off2] ptr) mem) && is20Bit(int64(off1)+int64(off2)) => (FMOVDload [off1+off2] {sym} ptr mem)
-
-(MOVDstore  [off1] {sym} (ADDconst [off2] ptr) val mem) && is20Bit(int64(off1)+int64(off2)) => (MOVDstore  [off1+off2] {sym} ptr val mem)
-(MOVWstore  [off1] {sym} (ADDconst [off2] ptr) val mem) && is20Bit(int64(off1)+int64(off2)) => (MOVWstore  [off1+off2] {sym} ptr val mem)
-(MOVHstore  [off1] {sym} (ADDconst [off2] ptr) val mem) && is20Bit(int64(off1)+int64(off2)) => (MOVHstore  [off1+off2] {sym} ptr val mem)
-(MOVBstore  [off1] {sym} (ADDconst [off2] ptr) val mem) && is20Bit(int64(off1)+int64(off2)) => (MOVBstore  [off1+off2] {sym} ptr val mem)
-(FMOVSstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is20Bit(int64(off1)+int64(off2)) => (FMOVSstore [off1+off2] {sym} ptr val mem)
-(FMOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is20Bit(int64(off1)+int64(off2)) => (FMOVDstore [off1+off2] {sym} ptr val mem)
-
-(ADDload   [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2)) => (ADDload   [off1+off2] {sym} x ptr mem)
-(ADDWload  [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2)) => (ADDWload  [off1+off2] {sym} x ptr mem)
-(MULLDload [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2)) => (MULLDload [off1+off2] {sym} x ptr mem)
-(MULLWload [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2)) => (MULLWload [off1+off2] {sym} x ptr mem)
-(SUBload   [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2)) => (SUBload   [off1+off2] {sym} x ptr mem)
-(SUBWload  [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2)) => (SUBWload  [off1+off2] {sym} x ptr mem)
-
-(ANDload   [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2)) => (ANDload   [off1+off2] {sym} x ptr mem)
-(ANDWload  [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2)) => (ANDWload  [off1+off2] {sym} x ptr mem)
-(ORload    [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2)) => (ORload    [off1+off2] {sym} x ptr mem)
-(ORWload   [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2)) => (ORWload   [off1+off2] {sym} x ptr mem)
-(XORload   [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2)) => (XORload   [off1+off2] {sym} x ptr mem)
-(XORWload  [off1] {sym} x (ADDconst [off2] ptr) mem) && ptr.Op != OpSB && is20Bit(int64(off1)+int64(off2)) => (XORWload  [off1+off2] {sym} x ptr mem)
-
-// Fold constants into stores.
-(MOVDstore [off] {sym} ptr (MOVDconst [c]) mem) && is16Bit(c) && isU12Bit(int64(off)) && ptr.Op != OpSB =>
-	(MOVDstoreconst [makeValAndOff(int32(c),off)] {sym} ptr mem)
-(MOVWstore [off] {sym} ptr (MOVDconst [c]) mem) && is16Bit(c) && isU12Bit(int64(off)) && ptr.Op != OpSB =>
-	(MOVWstoreconst [makeValAndOff(int32(c),off)] {sym} ptr mem)
-(MOVHstore [off] {sym} ptr (MOVDconst [c]) mem) && isU12Bit(int64(off)) && ptr.Op != OpSB =>
-	(MOVHstoreconst [makeValAndOff(int32(int16(c)),off)] {sym} ptr mem)
-(MOVBstore [off] {sym} ptr (MOVDconst [c]) mem) && is20Bit(int64(off)) && ptr.Op != OpSB =>
-	(MOVBstoreconst [makeValAndOff(int32(int8(c)),off)] {sym} ptr mem)
-
-// Fold address offsets into constant stores.
-(MOVDstoreconst [sc] {s} (ADDconst [off] ptr) mem) && isU12Bit(sc.Off64()+int64(off)) =>
-	(MOVDstoreconst [sc.addOffset32(off)] {s} ptr mem)
-(MOVWstoreconst [sc] {s} (ADDconst [off] ptr) mem) && isU12Bit(sc.Off64()+int64(off)) =>
-	(MOVWstoreconst [sc.addOffset32(off)] {s} ptr mem)
-(MOVHstoreconst [sc] {s} (ADDconst [off] ptr) mem) && isU12Bit(sc.Off64()+int64(off)) =>
-	(MOVHstoreconst [sc.addOffset32(off)] {s} ptr mem)
-(MOVBstoreconst [sc] {s} (ADDconst [off] ptr) mem) && is20Bit(sc.Off64()+int64(off)) =>
-	(MOVBstoreconst [sc.addOffset32(off)] {s} ptr mem)
-
-// Merge address calculations into loads and stores.
-// Offsets from SB must not be merged into unaligned memory accesses because
-// loads/stores using PC-relative addressing directly must be aligned to the
-// size of the target.
-(MOVDload   [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%8 == 0 && (off1+off2)%8 == 0)) =>
-	(MOVDload  [off1+off2] {mergeSym(sym1,sym2)} base mem)
-(MOVWZload  [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%4 == 0 && (off1+off2)%4 == 0)) =>
-	(MOVWZload  [off1+off2] {mergeSym(sym1,sym2)} base mem)
-(MOVHZload  [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%2 == 0 && (off1+off2)%2 == 0)) =>
-	(MOVHZload  [off1+off2] {mergeSym(sym1,sym2)} base mem)
-(MOVBZload  [off1] {sym1} (MOVDaddr [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-	(MOVBZload  [off1+off2] {mergeSym(sym1,sym2)} base mem)
-(FMOVSload [off1] {sym1} (MOVDaddr [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-	(FMOVSload [off1+off2] {mergeSym(sym1,sym2)} base mem)
-(FMOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-	(FMOVDload [off1+off2] {mergeSym(sym1,sym2)} base mem)
-
-(MOVWload [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%4 == 0 && (off1+off2)%4 == 0)) =>
-	(MOVWload [off1+off2] {mergeSym(sym1,sym2)} base mem)
-(MOVHload [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%2 == 0 && (off1+off2)%2 == 0)) =>
-	(MOVHload [off1+off2] {mergeSym(sym1,sym2)} base mem)
-(MOVBload [off1] {sym1} (MOVDaddr [off2] {sym2} base) mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-	(MOVBload [off1+off2] {mergeSym(sym1,sym2)} base mem)
-
-(MOVDstore  [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) val mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%8 == 0 && (off1+off2)%8 == 0)) =>
-	(MOVDstore  [off1+off2] {mergeSym(sym1,sym2)} base val mem)
-(MOVWstore  [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) val mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%4 == 0 && (off1+off2)%4 == 0)) =>
-	(MOVWstore  [off1+off2] {mergeSym(sym1,sym2)} base val mem)
-(MOVHstore  [off1] {sym1} (MOVDaddr <t> [off2] {sym2} base) val mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && (base.Op != OpSB || (t.IsPtr() && t.Elem().Alignment()%2 == 0 && (off1+off2)%2 == 0)) =>
-	(MOVHstore  [off1+off2] {mergeSym(sym1,sym2)} base val mem)
-(MOVBstore  [off1] {sym1} (MOVDaddr [off2] {sym2} base) val mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-	(MOVBstore  [off1+off2] {mergeSym(sym1,sym2)} base val mem)
-(FMOVSstore [off1] {sym1} (MOVDaddr [off2] {sym2} base) val mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-	(FMOVSstore [off1+off2] {mergeSym(sym1,sym2)} base val mem)
-(FMOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} base) val mem) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) =>
-	(FMOVDstore [off1+off2] {mergeSym(sym1,sym2)} base val mem)
-
-(ADDload   [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (ADDload   [o1+o2] {mergeSym(s1, s2)} x ptr mem)
-(ADDWload  [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (ADDWload  [o1+o2] {mergeSym(s1, s2)} x ptr mem)
-(MULLDload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (MULLDload [o1+o2] {mergeSym(s1, s2)} x ptr mem)
-(MULLWload [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (MULLWload [o1+o2] {mergeSym(s1, s2)} x ptr mem)
-(SUBload   [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (SUBload   [o1+o2] {mergeSym(s1, s2)} x ptr mem)
-(SUBWload  [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (SUBWload  [o1+o2] {mergeSym(s1, s2)} x ptr mem)
-
-(ANDload   [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (ANDload   [o1+o2] {mergeSym(s1, s2)} x ptr mem)
-(ANDWload  [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (ANDWload  [o1+o2] {mergeSym(s1, s2)} x ptr mem)
-(ORload    [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (ORload    [o1+o2] {mergeSym(s1, s2)} x ptr mem)
-(ORWload   [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (ORWload   [o1+o2] {mergeSym(s1, s2)} x ptr mem)
-(XORload   [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (XORload   [o1+o2] {mergeSym(s1, s2)} x ptr mem)
-(XORWload  [o1] {s1} x (MOVDaddr [o2] {s2} ptr) mem) && ptr.Op != OpSB && is20Bit(int64(o1)+int64(o2)) && canMergeSym(s1, s2) => (XORWload  [o1+o2] {mergeSym(s1, s2)} x ptr mem)
-
-// Cannot store constant to SB directly (no 'move relative long immediate' instructions).
-(MOVDstoreconst [sc] {sym1} (MOVDaddr [off] {sym2} ptr) mem) && ptr.Op != OpSB && canMergeSym(sym1, sym2) && sc.canAdd32(off) =>
-	(MOVDstoreconst [sc.addOffset32(off)] {mergeSym(sym1, sym2)} ptr mem)
-(MOVWstoreconst [sc] {sym1} (MOVDaddr [off] {sym2} ptr) mem) && ptr.Op != OpSB && canMergeSym(sym1, sym2) && sc.canAdd32(off) =>
-	(MOVWstoreconst [sc.addOffset32(off)] {mergeSym(sym1, sym2)} ptr mem)
-(MOVHstoreconst [sc] {sym1} (MOVDaddr [off] {sym2} ptr) mem) && ptr.Op != OpSB && canMergeSym(sym1, sym2) && sc.canAdd32(off) =>
-	(MOVHstoreconst [sc.addOffset32(off)] {mergeSym(sym1, sym2)} ptr mem)
-(MOVBstoreconst [sc] {sym1} (MOVDaddr [off] {sym2} ptr) mem) && ptr.Op != OpSB && canMergeSym(sym1, sym2) && sc.canAdd32(off) =>
-	(MOVBstoreconst [sc.addOffset32(off)] {mergeSym(sym1, sym2)} ptr mem)
-
-// MOVDaddr into MOVDaddridx
-(MOVDaddridx [off1] {sym1} (MOVDaddr [off2] {sym2} x) y) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && x.Op != OpSB =>
-       (MOVDaddridx [off1+off2] {mergeSym(sym1,sym2)} x y)
-(MOVDaddridx [off1] {sym1} x (MOVDaddr [off2] {sym2} y)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) && y.Op != OpSB =>
-       (MOVDaddridx [off1+off2] {mergeSym(sym1,sym2)} x y)
-
-// Absorb InvertFlags into branches.
-(BRC {c} (InvertFlags cmp) yes no) => (BRC {c.ReverseComparison()} cmp yes no)
-
-// Constant comparisons.
-(CMPconst (MOVDconst [x]) [y]) && x==int64(y) => (FlagEQ)
-(CMPconst (MOVDconst [x]) [y]) && x<int64(y) => (FlagLT)
-(CMPconst (MOVDconst [x]) [y]) && x>int64(y) => (FlagGT)
-(CMPUconst (MOVDconst [x]) [y]) && uint64(x)==uint64(y) => (FlagEQ)
-(CMPUconst (MOVDconst [x]) [y]) && uint64(x)<uint64(y) => (FlagLT)
-(CMPUconst (MOVDconst [x]) [y]) && uint64(x)>uint64(y) => (FlagGT)
-
-(CMPWconst (MOVDconst [x]) [y]) && int32(x)==int32(y) => (FlagEQ)
-(CMPWconst (MOVDconst [x]) [y]) && int32(x)<int32(y) => (FlagLT)
-(CMPWconst (MOVDconst [x]) [y]) && int32(x)>int32(y) => (FlagGT)
-(CMPWUconst (MOVDconst [x]) [y]) && uint32(x)==uint32(y) => (FlagEQ)
-(CMPWUconst (MOVDconst [x]) [y]) && uint32(x)<uint32(y) => (FlagLT)
-(CMPWUconst (MOVDconst [x]) [y]) && uint32(x)>uint32(y) => (FlagGT)
-
-(CMP(W|WU)const (MOVBZreg _) [c]) &&   0xff < c => (FlagLT)
-(CMP(W|WU)const (MOVHZreg _) [c]) && 0xffff < c => (FlagLT)
-
-(CMPconst  (SRDconst _ [c]) [n]) && c > 0 && n < 0 => (FlagGT)
-(CMPWconst (SRWconst _ [c]) [n]) && c > 0 && n < 0 => (FlagGT)
-
-(CMPUconst  (SRDconst _ [c]) [n]) && c > 0 && c < 64 && (1<<uint(64-c)) <= uint64(n) => (FlagLT)
-(CMPWUconst (SRWconst _ [c]) [n]) && c > 0 && c < 32 && (1<<uint(32-c)) <= uint32(n) => (FlagLT)
-
-(CMPWconst  (ANDWconst _ [m]) [n]) && int32(m) >= 0 &&  int32(m) <  int32(n) => (FlagLT)
-(CMPWUconst (ANDWconst _ [m]) [n]) && uint32(m) < uint32(n) => (FlagLT)
-
-(CMPconst  (RISBGZ x {r}) [c]) && c > 0 && r.OutMask() < uint64(c) => (FlagLT)
-(CMPUconst (RISBGZ x {r}) [c]) && r.OutMask() < uint64(uint32(c)) => (FlagLT)
-
-// Constant compare-and-branch with immediate.
-(CGIJ  {c} (MOVDconst [x]) [y] yes no) && c&s390x.Equal   != 0 &&  int64(x) ==  int64(y) => (First yes no)
-(CGIJ  {c} (MOVDconst [x]) [y] yes no) && c&s390x.Less    != 0 &&  int64(x) <   int64(y) => (First yes no)
-(CGIJ  {c} (MOVDconst [x]) [y] yes no) && c&s390x.Greater != 0 &&  int64(x) >   int64(y) => (First yes no)
-(CIJ   {c} (MOVDconst [x]) [y] yes no) && c&s390x.Equal   != 0 &&  int32(x) ==  int32(y) => (First yes no)
-(CIJ   {c} (MOVDconst [x]) [y] yes no) && c&s390x.Less    != 0 &&  int32(x) <   int32(y) => (First yes no)
-(CIJ   {c} (MOVDconst [x]) [y] yes no) && c&s390x.Greater != 0 &&  int32(x) >   int32(y) => (First yes no)
-(CLGIJ {c} (MOVDconst [x]) [y] yes no) && c&s390x.Equal   != 0 && uint64(x) == uint64(y) => (First yes no)
-(CLGIJ {c} (MOVDconst [x]) [y] yes no) && c&s390x.Less    != 0 && uint64(x) <  uint64(y) => (First yes no)
-(CLGIJ {c} (MOVDconst [x]) [y] yes no) && c&s390x.Greater != 0 && uint64(x) >  uint64(y) => (First yes no)
-(CLIJ  {c} (MOVDconst [x]) [y] yes no) && c&s390x.Equal   != 0 && uint32(x) == uint32(y) => (First yes no)
-(CLIJ  {c} (MOVDconst [x]) [y] yes no) && c&s390x.Less    != 0 && uint32(x) <  uint32(y) => (First yes no)
-(CLIJ  {c} (MOVDconst [x]) [y] yes no) && c&s390x.Greater != 0 && uint32(x) >  uint32(y) => (First yes no)
-(CGIJ  {c} (MOVDconst [x]) [y] yes no) && c&s390x.Equal   == 0 &&  int64(x) ==  int64(y) => (First no yes)
-(CGIJ  {c} (MOVDconst [x]) [y] yes no) && c&s390x.Less    == 0 &&  int64(x) <   int64(y) => (First no yes)
-(CGIJ  {c} (MOVDconst [x]) [y] yes no) && c&s390x.Greater == 0 &&  int64(x) >   int64(y) => (First no yes)
-(CIJ   {c} (MOVDconst [x]) [y] yes no) && c&s390x.Equal   == 0 &&  int32(x) ==  int32(y) => (First no yes)
-(CIJ   {c} (MOVDconst [x]) [y] yes no) && c&s390x.Less    == 0 &&  int32(x) <   int32(y) => (First no yes)
-(CIJ   {c} (MOVDconst [x]) [y] yes no) && c&s390x.Greater == 0 &&  int32(x) >   int32(y) => (First no yes)
-(CLGIJ {c} (MOVDconst [x]) [y] yes no) && c&s390x.Equal   == 0 && uint64(x) == uint64(y) => (First no yes)
-(CLGIJ {c} (MOVDconst [x]) [y] yes no) && c&s390x.Less    == 0 && uint64(x) <  uint64(y) => (First no yes)
-(CLGIJ {c} (MOVDconst [x]) [y] yes no) && c&s390x.Greater == 0 && uint64(x) >  uint64(y) => (First no yes)
-(CLIJ  {c} (MOVDconst [x]) [y] yes no) && c&s390x.Equal   == 0 && uint32(x) == uint32(y) => (First no yes)
-(CLIJ  {c} (MOVDconst [x]) [y] yes no) && c&s390x.Less    == 0 && uint32(x) <  uint32(y) => (First no yes)
-(CLIJ  {c} (MOVDconst [x]) [y] yes no) && c&s390x.Greater == 0 && uint32(x) >  uint32(y) => (First no yes)
-
-// Constant compare-and-branch with immediate when unsigned comparison with zero.
-(C(L|LG)IJ {s390x.GreaterOrEqual} _ [0] yes no) => (First yes no)
-(C(L|LG)IJ {s390x.Less}           _ [0] yes no) => (First no yes)
-
-// Constant compare-and-branch when operands match.
-(C(GR|R|LGR|LR)J {c} x y yes no) && x == y && c&s390x.Equal != 0 => (First yes no)
-(C(GR|R|LGR|LR)J {c} x y yes no) && x == y && c&s390x.Equal == 0 => (First no yes)
-
-// Convert 64-bit comparisons to 32-bit comparisons and signed comparisons
-// to unsigned comparisons.
-// Helps simplify constant comparison detection.
-(CM(P|PU)const (MOV(W|WZ)reg x) [c]) => (CMP(W|WU)const x [c])
-(CM(P|P|PU|PU)const x:(MOV(H|HZ|H|HZ)reg _) [c]) => (CMP(W|W|WU|WU)const x [c])
-(CM(P|P|PU|PU)const x:(MOV(B|BZ|B|BZ)reg _) [c]) => (CMP(W|W|WU|WU)const x [c])
-(CMPconst  (MOV(WZ|W)reg x:(ANDWconst [m] _)) [c]) && int32(m) >= 0 && c >= 0 => (CMPWUconst x [c])
-(CMPUconst (MOV(WZ|W)reg x:(ANDWconst [m] _)) [c]) && int32(m) >= 0           => (CMPWUconst x [c])
-(CMPconst  x:(SRDconst _ [c]) [n]) && c > 0 && n >= 0 => (CMPUconst  x [n])
-(CMPWconst x:(SRWconst _ [c]) [n]) && c > 0 && n >= 0 => (CMPWUconst x [n])
-
-// Absorb sign and zero extensions into 32-bit comparisons.
-(CMP(W|W|WU|WU)      x (MOV(W|WZ|W|WZ)reg y))   => (CMP(W|W|WU|WU) x y)
-(CMP(W|W|WU|WU)      (MOV(W|WZ|W|WZ)reg x) y)   => (CMP(W|W|WU|WU) x y)
-(CMP(W|W|WU|WU)const (MOV(W|WZ|W|WZ)reg x) [c]) => (CMP(W|W|WU|WU)const x [c])
-
-// Absorb flag constants into branches.
-(BRC {c} (FlagEQ) yes no) && c&s390x.Equal     != 0 => (First yes no)
-(BRC {c} (FlagLT) yes no) && c&s390x.Less      != 0 => (First yes no)
-(BRC {c} (FlagGT) yes no) && c&s390x.Greater   != 0 => (First yes no)
-(BRC {c} (FlagOV) yes no) && c&s390x.Unordered != 0 => (First yes no)
-
-(BRC {c} (FlagEQ) yes no) && c&s390x.Equal     == 0 => (First no yes)
-(BRC {c} (FlagLT) yes no) && c&s390x.Less      == 0 => (First no yes)
-(BRC {c} (FlagGT) yes no) && c&s390x.Greater   == 0 => (First no yes)
-(BRC {c} (FlagOV) yes no) && c&s390x.Unordered == 0 => (First no yes)
-
-// Absorb flag constants into SETxx ops.
-(LOCGR {c} _ x (FlagEQ)) && c&s390x.Equal     != 0 => x
-(LOCGR {c} _ x (FlagLT)) && c&s390x.Less      != 0 => x
-(LOCGR {c} _ x (FlagGT)) && c&s390x.Greater   != 0 => x
-(LOCGR {c} _ x (FlagOV)) && c&s390x.Unordered != 0 => x
-
-(LOCGR {c} x _ (FlagEQ)) && c&s390x.Equal     == 0 => x
-(LOCGR {c} x _ (FlagLT)) && c&s390x.Less      == 0 => x
-(LOCGR {c} x _ (FlagGT)) && c&s390x.Greater   == 0 => x
-(LOCGR {c} x _ (FlagOV)) && c&s390x.Unordered == 0 => x
-
-// Remove redundant *const ops
-(ADDconst [0] x) => x
-(ADDWconst [c] x) && int32(c)==0 => x
-(SUBconst [0] x) => x
-(SUBWconst [c] x) && int32(c) == 0 => x
-(ANDconst [0] _)                 => (MOVDconst [0])
-(ANDWconst [c] _) && int32(c)==0  => (MOVDconst [0])
-(ANDconst [-1] x)                => x
-(ANDWconst [c] x) && int32(c)==-1 => x
-(ORconst [0] x)                  => x
-(ORWconst [c] x) && int32(c)==0   => x
-(ORconst [-1] _)                 => (MOVDconst [-1])
-(ORWconst [c] _) && int32(c)==-1  => (MOVDconst [-1])
-(XORconst [0] x)                  => x
-(XORWconst [c] x) && int32(c)==0   => x
-
-// Shifts by zero (may be inserted during multiplication strength reduction).
-((SLD|SLW|SRD|SRW|SRAD|SRAW)const x [0]) => x
-
-// Convert constant subtracts to constant adds.
-(SUBconst [c] x) && c != -(1<<31) => (ADDconst [-c] x)
-(SUBWconst [c] x) => (ADDWconst [-int32(c)] x)
-
-// generic constant folding
-// TODO: more of this
-(ADDconst [c] (MOVDconst [d])) => (MOVDconst [int64(c)+d])
-(ADDWconst [c] (MOVDconst [d])) => (MOVDconst [int64(c)+d])
-(ADDconst [c] (ADDconst [d] x)) && is32Bit(int64(c)+int64(d)) => (ADDconst [c+d] x)
-(ADDWconst [c] (ADDWconst [d] x)) => (ADDWconst [int32(c+d)] x)
-(SUBconst (MOVDconst [d]) [c]) => (MOVDconst [d-int64(c)])
-(SUBconst (SUBconst x [d]) [c]) && is32Bit(-int64(c)-int64(d)) => (ADDconst [-c-d] x)
-(SRADconst [c] (MOVDconst [d])) => (MOVDconst [d>>uint64(c)])
-(SRAWconst [c] (MOVDconst [d])) => (MOVDconst [int64(int32(d))>>uint64(c)])
-(NEG (MOVDconst [c])) => (MOVDconst [-c])
-(NEGW (MOVDconst [c])) => (MOVDconst [int64(int32(-c))])
-(MULLDconst [c] (MOVDconst [d])) => (MOVDconst [int64(c)*d])
-(MULLWconst [c] (MOVDconst [d])) => (MOVDconst [int64(c*int32(d))])
-(AND (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [c&d])
-(ANDconst [c] (MOVDconst [d])) => (MOVDconst [c&d])
-(ANDWconst [c] (MOVDconst [d])) => (MOVDconst [int64(c)&d])
-(OR (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [c|d])
-(ORconst [c] (MOVDconst [d])) => (MOVDconst [c|d])
-(ORWconst [c] (MOVDconst [d])) => (MOVDconst [int64(c)|d])
-(XOR (MOVDconst [c]) (MOVDconst [d])) => (MOVDconst [c^d])
-(XORconst [c] (MOVDconst [d])) => (MOVDconst [c^d])
-(XORWconst [c] (MOVDconst [d])) => (MOVDconst [int64(c)^d])
-(LoweredRound32F x:(FMOVSconst)) => x
-(LoweredRound64F x:(FMOVDconst)) => x
-
-// generic simplifications
-// TODO: more of this
-(ADD x (NEG y)) => (SUB x y)
-(ADDW x (NEGW y)) => (SUBW x y)
-(SUB x x) => (MOVDconst [0])
-(SUBW x x) => (MOVDconst [0])
-(AND x x) => x
-(ANDW x x) => x
-(OR x x) => x
-(ORW x x) => x
-(XOR x x) => (MOVDconst [0])
-(XORW x x) => (MOVDconst [0])
-(NEG (ADDconst [c] (NEG x))) && c != -(1<<31) => (ADDconst [-c] x)
-(MOVBZreg (ANDWconst [m] x)) => (MOVWZreg (ANDWconst <typ.UInt32> [int32( uint8(m))] x))
-(MOVHZreg (ANDWconst [m] x)) => (MOVWZreg (ANDWconst <typ.UInt32> [int32(uint16(m))] x))
-(MOVBreg  (ANDWconst [m] x)) &&  int8(m) >= 0 => (MOVWZreg (ANDWconst <typ.UInt32> [int32( uint8(m))] x))
-(MOVHreg  (ANDWconst [m] x)) && int16(m) >= 0 => (MOVWZreg (ANDWconst <typ.UInt32> [int32(uint16(m))] x))
-
-// carry flag generation
-// (only constant fold carry of zero)
-(Select1 (ADDCconst (MOVDconst [c]) [d]))
-  && uint64(c+int64(d)) >= uint64(c) && c+int64(d) == 0
-  => (FlagEQ)
-(Select1 (ADDCconst (MOVDconst [c]) [d]))
-  && uint64(c+int64(d)) >= uint64(c) && c+int64(d) != 0
-  => (FlagLT)
-
-// borrow flag generation
-// (only constant fold borrow of zero)
-(Select1 (SUBC (MOVDconst [c]) (MOVDconst [d])))
-  && uint64(d) <= uint64(c) && c-d == 0
-  => (FlagGT)
-(Select1 (SUBC (MOVDconst [c]) (MOVDconst [d])))
-  && uint64(d) <= uint64(c) && c-d != 0
-  => (FlagOV)
-
-// add with carry
-(ADDE x y (FlagEQ)) => (ADDC x y)
-(ADDE x y (FlagLT)) => (ADDC x y)
-(ADDC x (MOVDconst [c])) && is16Bit(c) => (ADDCconst x [int16(c)])
-(Select0 (ADDCconst (MOVDconst [c]) [d])) => (MOVDconst [c+int64(d)])
-
-// subtract with borrow
-(SUBE x y (FlagGT)) => (SUBC x y)
-(SUBE x y (FlagOV)) => (SUBC x y)
-(Select0 (SUBC (MOVDconst [c]) (MOVDconst [d]))) => (MOVDconst [c-d])
-
-// collapse carry chain
-(ADDE x y (Select1 (ADDCconst [-1] (Select0 (ADDE (MOVDconst [0]) (MOVDconst [0]) c)))))
-  => (ADDE x y c)
-
-// collapse borrow chain
-(SUBE x y (Select1 (SUBC (MOVDconst [0]) (NEG (Select0 (SUBE (MOVDconst [0]) (MOVDconst [0]) c))))))
-  => (SUBE x y c)
-
-// branch on carry
-(C(G|LG)IJ {s390x.Equal}         (Select0 (ADDE (MOVDconst [0]) (MOVDconst [0]) carry)) [0]) => (BRC {s390x.NoCarry} carry)
-(C(G|LG)IJ {s390x.Equal}         (Select0 (ADDE (MOVDconst [0]) (MOVDconst [0]) carry)) [1]) => (BRC {s390x.Carry}   carry)
-(C(G|LG)IJ {s390x.LessOrGreater} (Select0 (ADDE (MOVDconst [0]) (MOVDconst [0]) carry)) [0]) => (BRC {s390x.Carry}   carry)
-(C(G|LG)IJ {s390x.LessOrGreater} (Select0 (ADDE (MOVDconst [0]) (MOVDconst [0]) carry)) [1]) => (BRC {s390x.NoCarry} carry)
-(C(G|LG)IJ {s390x.Greater}       (Select0 (ADDE (MOVDconst [0]) (MOVDconst [0]) carry)) [0]) => (BRC {s390x.Carry}   carry)
-
-// branch on borrow
-(C(G|LG)IJ {s390x.Equal}         (NEG (Select0 (SUBE (MOVDconst [0]) (MOVDconst [0]) borrow))) [0]) => (BRC {s390x.NoBorrow} borrow)
-(C(G|LG)IJ {s390x.Equal}         (NEG (Select0 (SUBE (MOVDconst [0]) (MOVDconst [0]) borrow))) [1]) => (BRC {s390x.Borrow}   borrow)
-(C(G|LG)IJ {s390x.LessOrGreater} (NEG (Select0 (SUBE (MOVDconst [0]) (MOVDconst [0]) borrow))) [0]) => (BRC {s390x.Borrow}   borrow)
-(C(G|LG)IJ {s390x.LessOrGreater} (NEG (Select0 (SUBE (MOVDconst [0]) (MOVDconst [0]) borrow))) [1]) => (BRC {s390x.NoBorrow} borrow)
-(C(G|LG)IJ {s390x.Greater}       (NEG (Select0 (SUBE (MOVDconst [0]) (MOVDconst [0]) borrow))) [0]) => (BRC {s390x.Borrow}   borrow)
-
-// fused multiply-add
-(Select0 (F(ADD|SUB) (FMUL y z) x)) => (FM(ADD|SUB) x y z)
-(Select0 (F(ADDS|SUBS) (FMULS y z) x)) => (FM(ADDS|SUBS) x y z)
-
-// Convert floating point comparisons against zero into 'load and test' instructions.
-(F(CMP|CMPS) x (FMOV(D|S)const [0.0])) => (LT(D|E)BR x)
-(F(CMP|CMPS) (FMOV(D|S)const [0.0]) x) => (InvertFlags (LT(D|E)BR <v.Type> x))
-
-// FSUB, FSUBS, FADD, FADDS now produce a condition code representing the
-// comparison of the result with 0.0. If a compare with zero instruction
-// (e.g. LTDBR) is following one of those instructions, we can use the
-// generated flag and remove the comparison instruction.
-// Note: when inserting Select1 ops we need to ensure they are in the
-// same block as their argument. We could also use @x.Block for this
-// but moving the flag generating value to a different block seems to
-// increase the likelihood that the flags value will have to be regenerated
-// by flagalloc which is not what we want.
-(LTDBR (Select0 x:(F(ADD|SUB) _ _)))   && b == x.Block => (Select1 x)
-(LTEBR (Select0 x:(F(ADDS|SUBS) _ _))) && b == x.Block => (Select1 x)
-
-// Fold memory operations into operations.
-// Exclude global data (SB) because these instructions cannot handle relative addresses.
-// TODO(mundaym): indexed versions of these?
-((ADD|SUB|MULLD|AND|OR|XOR) <t> x g:(MOVDload [off] {sym} ptr mem))
-  && ptr.Op != OpSB
-  && is20Bit(int64(off))
-  && canMergeLoadClobber(v, g, x)
-  && clobber(g)
-  => ((ADD|SUB|MULLD|AND|OR|XOR)load <t> [off] {sym} x ptr mem)
-((ADD|SUB|MULL|AND|OR|XOR)W <t> x g:(MOVWload [off] {sym} ptr mem))
-  && ptr.Op != OpSB
-  && is20Bit(int64(off))
-  && canMergeLoadClobber(v, g, x)
-  && clobber(g)
-  => ((ADD|SUB|MULL|AND|OR|XOR)Wload <t> [off] {sym} x ptr mem)
-((ADD|SUB|MULL|AND|OR|XOR)W <t> x g:(MOVWZload [off] {sym} ptr mem))
-  && ptr.Op != OpSB
-  && is20Bit(int64(off))
-  && canMergeLoadClobber(v, g, x)
-  && clobber(g)
-  => ((ADD|SUB|MULL|AND|OR|XOR)Wload <t> [off] {sym} x ptr mem)
-
-// Combine constant stores into larger (unaligned) stores.
-// Avoid SB because constant stores to relative offsets are
-// emulated by the assembler and also can't handle unaligned offsets.
-(MOVBstoreconst [c] {s} p x:(MOVBstoreconst [a] {s} p mem))
-  && p.Op != OpSB
-  && x.Uses == 1
-  && a.Off() + 1 == c.Off()
-  && clobber(x)
-  => (MOVHstoreconst [makeValAndOff(c.Val()&0xff | a.Val()<<8, a.Off())] {s} p mem)
-(MOVHstoreconst [c] {s} p x:(MOVHstoreconst [a] {s} p mem))
-  && p.Op != OpSB
-  && x.Uses == 1
-  && a.Off() + 2 == c.Off()
-  && clobber(x)
-  => (MOVWstore [a.Off()] {s} p (MOVDconst [int64(c.Val()&0xffff | a.Val()<<16)]) mem)
-(MOVWstoreconst [c] {s} p x:(MOVWstoreconst [a] {s} p mem))
-  && p.Op != OpSB
-  && x.Uses == 1
-  && a.Off() + 4 == c.Off()
-  && clobber(x)
-  => (MOVDstore [a.Off()] {s} p (MOVDconst [c.Val64()&0xffffffff | a.Val64()<<32]) mem)
-
-// Combine stores into larger (unaligned) stores.
-// It doesn't work on global data (based on SB) because stores with relative addressing
-// require that the memory operand be aligned.
-(MOVBstore [i] {s} p w x:(MOVBstore [i-1] {s} p (SRDconst [8] w) mem))
-  && p.Op != OpSB
-  && x.Uses == 1
-  && clobber(x)
-  => (MOVHstore [i-1] {s} p w mem)
-(MOVBstore [i] {s} p w0:(SRDconst [j] w) x:(MOVBstore [i-1] {s} p (SRDconst [j+8] w) mem))
-  && p.Op != OpSB
-  && x.Uses == 1
-  && clobber(x)
-  => (MOVHstore [i-1] {s} p w0 mem)
-(MOVBstore [i] {s} p w x:(MOVBstore [i-1] {s} p (SRWconst [8] w) mem))
-  && p.Op != OpSB
-  && x.Uses == 1
-  && clobber(x)
-  => (MOVHstore [i-1] {s} p w mem)
-(MOVBstore [i] {s} p w0:(SRWconst [j] w) x:(MOVBstore [i-1] {s} p (SRWconst [j+8] w) mem))
-  && p.Op != OpSB
-  && x.Uses == 1
-  && clobber(x)
-  => (MOVHstore [i-1] {s} p w0 mem)
-(MOVHstore [i] {s} p w x:(MOVHstore [i-2] {s} p (SRDconst [16] w) mem))
-  && p.Op != OpSB
-  && x.Uses == 1
-  && clobber(x)
-  => (MOVWstore [i-2] {s} p w mem)
-(MOVHstore [i] {s} p w0:(SRDconst [j] w) x:(MOVHstore [i-2] {s} p (SRDconst [j+16] w) mem))
-  && p.Op != OpSB
-  && x.Uses == 1
-  && clobber(x)
-  => (MOVWstore [i-2] {s} p w0 mem)
-(MOVHstore [i] {s} p w x:(MOVHstore [i-2] {s} p (SRWconst [16] w) mem))
-  && p.Op != OpSB
-  && x.Uses == 1
-  && clobber(x)
-  => (MOVWstore [i-2] {s} p w mem)
-(MOVHstore [i] {s} p w0:(SRWconst [j] w) x:(MOVHstore [i-2] {s} p (SRWconst [j+16] w) mem))
-  && p.Op != OpSB
-  && x.Uses == 1
-  && clobber(x)
-  => (MOVWstore [i-2] {s} p w0 mem)
-(MOVWstore [i] {s} p (SRDconst [32] w) x:(MOVWstore [i-4] {s} p w mem))
-  && p.Op != OpSB
-  && x.Uses == 1
-  && clobber(x)
-  => (MOVDstore [i-4] {s} p w mem)
-(MOVWstore [i] {s} p w0:(SRDconst [j] w) x:(MOVWstore [i-4] {s} p (SRDconst [j+32] w) mem))
-  && p.Op != OpSB
-  && x.Uses == 1
-  && clobber(x)
-  => (MOVDstore [i-4] {s} p w0 mem)
-
-// Combine stores into larger (unaligned) stores with the bytes reversed (little endian).
-// Store-with-bytes-reversed instructions do not support relative memory addresses,
-// so these stores can't operate on global data (SB).
-(MOVBstore [i] {s} p (SRDconst [8] w) x:(MOVBstore [i-1] {s} p w mem))
-  && p.Op != OpSB
-  && x.Uses == 1
-  && clobber(x)
-  => (MOVHBRstore [i-1] {s} p w mem)
-(MOVBstore [i] {s} p (SRDconst [j] w) x:(MOVBstore [i-1] {s} p w0:(SRDconst [j-8] w) mem))
-  && p.Op != OpSB
-  && x.Uses == 1
-  && clobber(x)
-  => (MOVHBRstore [i-1] {s} p w0 mem)
-(MOVBstore [i] {s} p (SRWconst [8] w) x:(MOVBstore [i-1] {s} p w mem))
-  && p.Op != OpSB
-  && x.Uses == 1
-  && clobber(x)
-  => (MOVHBRstore [i-1] {s} p w mem)
-(MOVBstore [i] {s} p (SRWconst [j] w) x:(MOVBstore [i-1] {s} p w0:(SRWconst [j-8] w) mem))
-  && p.Op != OpSB
-  && x.Uses == 1
-  && clobber(x)
-  => (MOVHBRstore [i-1] {s} p w0 mem)
-(MOVHBRstore [i] {s} p (SRDconst [16] w) x:(MOVHBRstore [i-2] {s} p w mem))
-  && x.Uses == 1
-  && clobber(x)
-  => (MOVWBRstore [i-2] {s} p w mem)
-(MOVHBRstore [i] {s} p (SRDconst [j] w) x:(MOVHBRstore [i-2] {s} p w0:(SRDconst [j-16] w) mem))
-  && x.Uses == 1
-  && clobber(x)
-  => (MOVWBRstore [i-2] {s} p w0 mem)
-(MOVHBRstore [i] {s} p (SRWconst [16] w) x:(MOVHBRstore [i-2] {s} p w mem))
-  && x.Uses == 1
-  && clobber(x)
-  => (MOVWBRstore [i-2] {s} p w mem)
-(MOVHBRstore [i] {s} p (SRWconst [j] w) x:(MOVHBRstore [i-2] {s} p w0:(SRWconst [j-16] w) mem))
-  && x.Uses == 1
-  && clobber(x)
-  => (MOVWBRstore [i-2] {s} p w0 mem)
-(MOVWBRstore [i] {s} p (SRDconst [32] w) x:(MOVWBRstore [i-4] {s} p w mem))
-  && x.Uses == 1
-  && clobber(x)
-  => (MOVDBRstore [i-4] {s} p w mem)
-(MOVWBRstore [i] {s} p (SRDconst [j] w) x:(MOVWBRstore [i-4] {s} p w0:(SRDconst [j-32] w) mem))
-  && x.Uses == 1
-  && clobber(x)
-  => (MOVDBRstore [i-4] {s} p w0 mem)
-
-(MOVBstore [7] {s} p1 (SRDconst w)
-  x1:(MOVHBRstore [5] {s} p1 (SRDconst w)
-  x2:(MOVWBRstore [1] {s} p1 (SRDconst w)
-  x3:(MOVBstore [0] {s} p1 w mem))))
-  && x1.Uses == 1
-  && x2.Uses == 1
-  && x3.Uses == 1
-  && clobber(x1, x2, x3)
-  => (MOVDBRstore {s} p1 w mem)
-
-// Combining byte loads into larger (unaligned) loads.
-
-// Big-endian loads
-
-(ORW                 x1:(MOVBZload [i1] {s} p mem)
-    sh:(SLWconst [8] x0:(MOVBZload [i0] {s} p mem)))
-  && i1 == i0+1
-  && p.Op != OpSB
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && sh.Uses == 1
-  && mergePoint(b,x0,x1) != nil
-  && clobber(x0, x1, sh)
-  => @mergePoint(b,x0,x1) (MOVHZload [i0] {s} p mem)
-
-(OR                  x1:(MOVBZload [i1] {s} p mem)
-    sh:(SLDconst [8] x0:(MOVBZload [i0] {s} p mem)))
-  && i1 == i0+1
-  && p.Op != OpSB
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && sh.Uses == 1
-  && mergePoint(b,x0,x1) != nil
-  && clobber(x0, x1, sh)
-  => @mergePoint(b,x0,x1) (MOVHZload [i0] {s} p mem)
-
-(ORW                  x1:(MOVHZload [i1] {s} p mem)
-    sh:(SLWconst [16] x0:(MOVHZload [i0] {s} p mem)))
-  && i1 == i0+2
-  && p.Op != OpSB
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && sh.Uses == 1
-  && mergePoint(b,x0,x1) != nil
-  && clobber(x0, x1, sh)
-  => @mergePoint(b,x0,x1) (MOVWZload [i0] {s} p mem)
-
-(OR                   x1:(MOVHZload [i1] {s} p mem)
-    sh:(SLDconst [16] x0:(MOVHZload [i0] {s} p mem)))
-  && i1 == i0+2
-  && p.Op != OpSB
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && sh.Uses == 1
-  && mergePoint(b,x0,x1) != nil
-  && clobber(x0, x1, sh)
-  => @mergePoint(b,x0,x1) (MOVWZload [i0] {s} p mem)
-
-(OR                   x1:(MOVWZload [i1] {s} p mem)
-    sh:(SLDconst [32] x0:(MOVWZload [i0] {s} p mem)))
-  && i1 == i0+4
-  && p.Op != OpSB
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && sh.Uses == 1
-  && mergePoint(b,x0,x1) != nil
-  && clobber(x0, x1, sh)
-  => @mergePoint(b,x0,x1) (MOVDload [i0] {s} p mem)
-
-(ORW
-    s0:(SLWconst [j0] x0:(MOVBZload [i0] {s} p mem))
-    or:(ORW
-        s1:(SLWconst [j1] x1:(MOVBZload [i1] {s} p mem))
-	y))
-  && i1 == i0+1
-  && j1 == j0-8
-  && j1 % 16 == 0
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && s0.Uses == 1
-  && s1.Uses == 1
-  && or.Uses == 1
-  && mergePoint(b,x0,x1,y) != nil
-  && clobber(x0, x1, s0, s1, or)
-  => @mergePoint(b,x0,x1,y) (ORW <v.Type> (SLWconst <v.Type> [j1] (MOVHZload [i0] {s} p mem)) y)
-
-(OR
-    s0:(SLDconst [j0] x0:(MOVBZload [i0] {s} p mem))
-    or:(OR
-        s1:(SLDconst [j1] x1:(MOVBZload [i1] {s} p mem))
-	y))
-  && i1 == i0+1
-  && j1 == j0-8
-  && j1 % 16 == 0
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && s0.Uses == 1
-  && s1.Uses == 1
-  && or.Uses == 1
-  && mergePoint(b,x0,x1,y) != nil
-  && clobber(x0, x1, s0, s1, or)
-  => @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j1] (MOVHZload [i0] {s} p mem)) y)
-
-(OR
-    s0:(SLDconst [j0] x0:(MOVHZload [i0] {s} p mem))
-    or:(OR
-        s1:(SLDconst [j1] x1:(MOVHZload [i1] {s} p mem))
-	y))
-  && i1 == i0+2
-  && j1 == j0-16
-  && j1 % 32 == 0
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && s0.Uses == 1
-  && s1.Uses == 1
-  && or.Uses == 1
-  && mergePoint(b,x0,x1,y) != nil
-  && clobber(x0, x1, s0, s1, or)
-  => @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j1] (MOVWZload [i0] {s} p mem)) y)
-
-// Little-endian loads
-
-(ORW                 x0:(MOVBZload [i0] {s} p mem)
-    sh:(SLWconst [8] x1:(MOVBZload [i1] {s} p mem)))
-  && p.Op != OpSB
-  && i1 == i0+1
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && sh.Uses == 1
-  && mergePoint(b,x0,x1) != nil
-  && clobber(x0, x1, sh)
-  => @mergePoint(b,x0,x1) (MOVHZreg (MOVHBRload [i0] {s} p mem))
-
-(OR                  x0:(MOVBZload [i0] {s} p mem)
-    sh:(SLDconst [8] x1:(MOVBZload [i1] {s} p mem)))
-  && p.Op != OpSB
-  && i1 == i0+1
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && sh.Uses == 1
-  && mergePoint(b,x0,x1) != nil
-  && clobber(x0, x1, sh)
-  => @mergePoint(b,x0,x1) (MOVHZreg (MOVHBRload [i0] {s} p mem))
-
-(ORW                  r0:(MOVHZreg x0:(MOVHBRload [i0] {s} p mem))
-    sh:(SLWconst [16] r1:(MOVHZreg x1:(MOVHBRload [i1] {s} p mem))))
-  && i1 == i0+2
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && r0.Uses == 1
-  && r1.Uses == 1
-  && sh.Uses == 1
-  && mergePoint(b,x0,x1) != nil
-  && clobber(x0, x1, r0, r1, sh)
-  => @mergePoint(b,x0,x1) (MOVWBRload [i0] {s} p mem)
-
-(OR                   r0:(MOVHZreg x0:(MOVHBRload [i0] {s} p mem))
-    sh:(SLDconst [16] r1:(MOVHZreg x1:(MOVHBRload [i1] {s} p mem))))
-  && i1 == i0+2
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && r0.Uses == 1
-  && r1.Uses == 1
-  && sh.Uses == 1
-  && mergePoint(b,x0,x1) != nil
-  && clobber(x0, x1, r0, r1, sh)
-  => @mergePoint(b,x0,x1) (MOVWZreg (MOVWBRload [i0] {s} p mem))
-
-(OR                   r0:(MOVWZreg x0:(MOVWBRload [i0] {s} p mem))
-    sh:(SLDconst [32] r1:(MOVWZreg x1:(MOVWBRload [i1] {s} p mem))))
-  && i1 == i0+4
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && r0.Uses == 1
-  && r1.Uses == 1
-  && sh.Uses == 1
-  && mergePoint(b,x0,x1) != nil
-  && clobber(x0, x1, r0, r1, sh)
-  => @mergePoint(b,x0,x1) (MOVDBRload [i0] {s} p mem)
-
-(ORW
-    s1:(SLWconst [j1] x1:(MOVBZload [i1] {s} p mem))
-    or:(ORW
-        s0:(SLWconst [j0] x0:(MOVBZload [i0] {s} p mem))
-	y))
-  && p.Op != OpSB
-  && i1 == i0+1
-  && j1 == j0+8
-  && j0 % 16 == 0
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && s0.Uses == 1
-  && s1.Uses == 1
-  && or.Uses == 1
-  && mergePoint(b,x0,x1,y) != nil
-  && clobber(x0, x1, s0, s1, or)
-  => @mergePoint(b,x0,x1,y) (ORW <v.Type> (SLWconst <v.Type> [j0] (MOVHZreg (MOVHBRload [i0] {s} p mem))) y)
-
-(OR
-    s1:(SLDconst [j1] x1:(MOVBZload [i1] {s} p mem))
-    or:(OR
-        s0:(SLDconst [j0] x0:(MOVBZload [i0] {s} p mem))
-	y))
-  && p.Op != OpSB
-  && i1 == i0+1
-  && j1 == j0+8
-  && j0 % 16 == 0
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && s0.Uses == 1
-  && s1.Uses == 1
-  && or.Uses == 1
-  && mergePoint(b,x0,x1,y) != nil
-  && clobber(x0, x1, s0, s1, or)
-  => @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j0] (MOVHZreg (MOVHBRload [i0] {s} p mem))) y)
-
-(OR
-    s1:(SLDconst [j1] r1:(MOVHZreg x1:(MOVHBRload [i1] {s} p mem)))
-    or:(OR
-        s0:(SLDconst [j0] r0:(MOVHZreg x0:(MOVHBRload [i0] {s} p mem)))
-	y))
-  && i1 == i0+2
-  && j1 == j0+16
-  && j0 % 32 == 0
-  && x0.Uses == 1
-  && x1.Uses == 1
-  && r0.Uses == 1
-  && r1.Uses == 1
-  && s0.Uses == 1
-  && s1.Uses == 1
-  && or.Uses == 1
-  && mergePoint(b,x0,x1,y) != nil
-  && clobber(x0, x1, r0, r1, s0, s1, or)
-  => @mergePoint(b,x0,x1,y) (OR <v.Type> (SLDconst <v.Type> [j0] (MOVWZreg (MOVWBRload [i0] {s} p mem))) y)
-
-// Combine stores into store multiples.
-// 32-bit
-(MOVWstore [i] {s} p w1 x:(MOVWstore [i-4] {s} p w0 mem))
-  && p.Op != OpSB
-  && x.Uses == 1
-  && is20Bit(int64(i)-4)
-  && clobber(x)
-  => (STM2 [i-4] {s} p w0 w1 mem)
-(MOVWstore [i] {s} p w2 x:(STM2 [i-8] {s} p w0 w1 mem))
-  && x.Uses == 1
-  && is20Bit(int64(i)-8)
-  && clobber(x)
-  => (STM3 [i-8] {s} p w0 w1 w2 mem)
-(MOVWstore [i] {s} p w3 x:(STM3 [i-12] {s} p w0 w1 w2 mem))
-  && x.Uses == 1
-  && is20Bit(int64(i)-12)
-  && clobber(x)
-  => (STM4 [i-12] {s} p w0 w1 w2 w3 mem)
-(STM2 [i] {s} p w2 w3 x:(STM2 [i-8] {s} p w0 w1 mem))
-  && x.Uses == 1
-  && is20Bit(int64(i)-8)
-  && clobber(x)
-  => (STM4 [i-8] {s} p w0 w1 w2 w3 mem)
-// 64-bit
-(MOVDstore [i] {s} p w1 x:(MOVDstore [i-8] {s} p w0 mem))
-  && p.Op != OpSB
-  && x.Uses == 1
-  && is20Bit(int64(i)-8)
-  && clobber(x)
-  => (STMG2 [i-8] {s} p w0 w1 mem)
-(MOVDstore [i] {s} p w2 x:(STMG2 [i-16] {s} p w0 w1 mem))
-  && x.Uses == 1
-  && is20Bit(int64(i)-16)
-  && clobber(x)
-  => (STMG3 [i-16] {s} p w0 w1 w2 mem)
-(MOVDstore [i] {s} p w3 x:(STMG3 [i-24] {s} p w0 w1 w2 mem))
-  && x.Uses == 1
-  && is20Bit(int64(i)-24)
-  && clobber(x)
-  => (STMG4 [i-24] {s} p w0 w1 w2 w3 mem)
-(STMG2 [i] {s} p w2 w3 x:(STMG2 [i-16] {s} p w0 w1 mem))
-  && x.Uses == 1
-  && is20Bit(int64(i)-16)
-  && clobber(x)
-  => (STMG4 [i-16] {s} p w0 w1 w2 w3 mem)
-
-// Convert 32-bit store multiples into 64-bit stores.
-(STM2 [i] {s} p (SRDconst [32] x) x mem) => (MOVDstore [i] {s} p x mem)
diff --git a/src/cmd/compile/internal/ssa/gen/S390XOps.go b/src/cmd/compile/internal/ssa/gen/S390XOps.go
deleted file mode 100644
index eef8a25..0000000
--- a/src/cmd/compile/internal/ssa/gen/S390XOps.go
+++ /dev/null
@@ -1,820 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build ignore
-// +build ignore
-
-package main
-
-import "strings"
-
-// Notes:
-//  - Integer types live in the low portion of registers. Upper portions are junk.
-//  - Boolean types use the low-order byte of a register. 0=false, 1=true.
-//    Upper bytes are junk.
-//  - When doing sub-register operations, we try to write the whole
-//    destination register to avoid a partial-register write.
-//  - Unused portions of AuxInt (or the Val portion of ValAndOff) are
-//    filled by sign-extending the used portion. Users of AuxInt which interpret
-//    AuxInt as unsigned (e.g. shifts) must be careful.
-//  - The SB 'register' is implemented using instruction-relative addressing. This
-//    places some limitations on when and how memory operands that are addressed
-//    relative to SB can be used:
-//
-//     1. Pseudo-instructions do not always map to a single machine instruction when
-//        using the SB 'register' to address data. This is because many machine
-//        instructions do not have relative long (RL suffix) equivalents. For example,
-//        ADDload, which is assembled as AG.
-//
-//     2. Loads and stores using relative addressing require the data be aligned
-//        according to its size (8-bytes for double words, 4-bytes for words
-//        and so on).
-//
-//    We can always work around these by inserting LARL instructions (load address
-//    relative long) in the assembler, but typically this results in worse code
-//    generation because the address can't be re-used. Inserting instructions in the
-//    assembler also means clobbering the temp register and it is a long-term goal
-//    to prevent the compiler doing this so that it can be allocated as a normal
-//    register.
-//
-// For more information about the z/Architecture, the instruction set and the
-// addressing modes it supports take a look at the z/Architecture Principles of
-// Operation: http://publibfp.boulder.ibm.com/epubs/pdf/dz9zr010.pdf
-//
-// Suffixes encode the bit width of pseudo-instructions.
-// D (double word)  = 64 bit (frequently omitted)
-// W (word)         = 32 bit
-// H (half word)    = 16 bit
-// B (byte)         = 8 bit
-// S (single prec.) = 32 bit (double precision is omitted)
-
-// copied from ../../s390x/reg.go
-var regNamesS390X = []string{
-	"R0",
-	"R1",
-	"R2",
-	"R3",
-	"R4",
-	"R5",
-	"R6",
-	"R7",
-	"R8",
-	"R9",
-	"R10",
-	"R11",
-	"R12",
-	"g", // R13
-	"R14",
-	"SP", // R15
-	"F0",
-	"F1",
-	"F2",
-	"F3",
-	"F4",
-	"F5",
-	"F6",
-	"F7",
-	"F8",
-	"F9",
-	"F10",
-	"F11",
-	"F12",
-	"F13",
-	"F14",
-	"F15",
-
-	// If you add registers, update asyncPreempt in runtime.
-
-	//pseudo-registers
-	"SB",
-}
-
-func init() {
-	// Make map from reg names to reg integers.
-	if len(regNamesS390X) > 64 {
-		panic("too many registers")
-	}
-	num := map[string]int{}
-	for i, name := range regNamesS390X {
-		num[name] = i
-	}
-	buildReg := func(s string) regMask {
-		m := regMask(0)
-		for _, r := range strings.Split(s, " ") {
-			if n, ok := num[r]; ok {
-				m |= regMask(1) << uint(n)
-				continue
-			}
-			panic("register " + r + " not found")
-		}
-		return m
-	}
-
-	// Common individual register masks
-	var (
-		sp  = buildReg("SP")
-		sb  = buildReg("SB")
-		r0  = buildReg("R0")
-		tmp = buildReg("R11") // R11 is used as a temporary in a small number of instructions.
-
-		// R10 is reserved by the assembler.
-		gp   = buildReg("R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R11 R12 R14")
-		gpg  = gp | buildReg("g")
-		gpsp = gp | sp
-
-		// R0 is considered to contain the value 0 in address calculations.
-		ptr     = gp &^ r0
-		ptrsp   = ptr | sp
-		ptrspsb = ptrsp | sb
-
-		fp         = buildReg("F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15")
-		callerSave = gp | fp | buildReg("g") // runtime.setg (and anything calling it) may clobber g
-		r1         = buildReg("R1")
-		r2         = buildReg("R2")
-		r3         = buildReg("R3")
-	)
-	// Common slices of register masks
-	var (
-		gponly = []regMask{gp}
-		fponly = []regMask{fp}
-	)
-
-	// Common regInfo
-	var (
-		gp01    = regInfo{inputs: []regMask{}, outputs: gponly}
-		gp11    = regInfo{inputs: []regMask{gp}, outputs: gponly}
-		gp11sp  = regInfo{inputs: []regMask{gpsp}, outputs: gponly}
-		gp21    = regInfo{inputs: []regMask{gp, gp}, outputs: gponly}
-		gp21sp  = regInfo{inputs: []regMask{gpsp, gp}, outputs: gponly}
-		gp21tmp = regInfo{inputs: []regMask{gp &^ tmp, gp &^ tmp}, outputs: []regMask{gp &^ tmp}, clobbers: tmp}
-
-		// R0 evaluates to 0 when used as the number of bits to shift
-		// so we need to exclude it from that operand.
-		sh21 = regInfo{inputs: []regMask{gp, ptr}, outputs: gponly}
-
-		addr    = regInfo{inputs: []regMask{sp | sb}, outputs: gponly}
-		addridx = regInfo{inputs: []regMask{sp | sb, ptrsp}, outputs: gponly}
-
-		gp2flags       = regInfo{inputs: []regMask{gpsp, gpsp}}
-		gp1flags       = regInfo{inputs: []regMask{gpsp}}
-		gp2flags1      = regInfo{inputs: []regMask{gp, gp}, outputs: gponly}
-		gp11flags      = regInfo{inputs: []regMask{gp}, outputs: gponly}
-		gp21flags      = regInfo{inputs: []regMask{gp, gp}, outputs: gponly}
-		gp2flags1flags = regInfo{inputs: []regMask{gp, gp}, outputs: gponly}
-
-		gpload       = regInfo{inputs: []regMask{ptrspsb, 0}, outputs: gponly}
-		gploadidx    = regInfo{inputs: []regMask{ptrspsb, ptrsp, 0}, outputs: gponly}
-		gpopload     = regInfo{inputs: []regMask{gp, ptrsp, 0}, outputs: gponly}
-		gpstore      = regInfo{inputs: []regMask{ptrspsb, gpsp, 0}}
-		gpstoreconst = regInfo{inputs: []regMask{ptrspsb, 0}}
-		gpstoreidx   = regInfo{inputs: []regMask{ptrsp, ptrsp, gpsp, 0}}
-		gpstorebr    = regInfo{inputs: []regMask{ptrsp, gpsp, 0}}
-		gpstorelaa   = regInfo{inputs: []regMask{ptrspsb, gpsp, 0}, outputs: gponly}
-		gpstorelab   = regInfo{inputs: []regMask{r1, gpsp, 0}, clobbers: r1}
-
-		gpmvc = regInfo{inputs: []regMask{ptrsp, ptrsp, 0}}
-
-		fp01        = regInfo{inputs: []regMask{}, outputs: fponly}
-		fp21        = regInfo{inputs: []regMask{fp, fp}, outputs: fponly}
-		fp31        = regInfo{inputs: []regMask{fp, fp, fp}, outputs: fponly}
-		fp21clobber = regInfo{inputs: []regMask{fp, fp}, outputs: fponly}
-		fpgp        = regInfo{inputs: fponly, outputs: gponly}
-		gpfp        = regInfo{inputs: gponly, outputs: fponly}
-		fp11        = regInfo{inputs: fponly, outputs: fponly}
-		fp1flags    = regInfo{inputs: []regMask{fp}}
-		fp11clobber = regInfo{inputs: fponly, outputs: fponly}
-		fp2flags    = regInfo{inputs: []regMask{fp, fp}}
-
-		fpload    = regInfo{inputs: []regMask{ptrspsb, 0}, outputs: fponly}
-		fploadidx = regInfo{inputs: []regMask{ptrsp, ptrsp, 0}, outputs: fponly}
-
-		fpstore    = regInfo{inputs: []regMask{ptrspsb, fp, 0}}
-		fpstoreidx = regInfo{inputs: []regMask{ptrsp, ptrsp, fp, 0}}
-
-		sync = regInfo{inputs: []regMask{0}}
-
-		// LoweredAtomicCas may overwrite arg1, so force it to R0 for now.
-		cas = regInfo{inputs: []regMask{ptrsp, r0, gpsp, 0}, outputs: []regMask{gp, 0}, clobbers: r0}
-
-		// LoweredAtomicExchange overwrites the output before executing
-		// CS{,G}, so the output register must not be the same as the
-		// input register. For now we just force the output register to
-		// R0.
-		exchange = regInfo{inputs: []regMask{ptrsp, gpsp &^ r0, 0}, outputs: []regMask{r0, 0}}
-	)
-
-	var S390Xops = []opData{
-		// fp ops
-		{name: "FADDS", argLength: 2, reg: fp21clobber, typ: "(Float32,Flags)", asm: "FADDS", commutative: true, resultInArg0: true}, // fp32 arg0 + arg1
-		{name: "FADD", argLength: 2, reg: fp21clobber, typ: "(Float64,Flags)", asm: "FADD", commutative: true, resultInArg0: true},   // fp64 arg0 + arg1
-		{name: "FSUBS", argLength: 2, reg: fp21clobber, typ: "(Float32,Flags)", asm: "FSUBS", resultInArg0: true},                    // fp32 arg0 - arg1
-		{name: "FSUB", argLength: 2, reg: fp21clobber, typ: "(Float64,Flags)", asm: "FSUB", resultInArg0: true},                      // fp64 arg0 - arg1
-		{name: "FMULS", argLength: 2, reg: fp21, asm: "FMULS", commutative: true, resultInArg0: true},                                // fp32 arg0 * arg1
-		{name: "FMUL", argLength: 2, reg: fp21, asm: "FMUL", commutative: true, resultInArg0: true},                                  // fp64 arg0 * arg1
-		{name: "FDIVS", argLength: 2, reg: fp21, asm: "FDIVS", resultInArg0: true},                                                   // fp32 arg0 / arg1
-		{name: "FDIV", argLength: 2, reg: fp21, asm: "FDIV", resultInArg0: true},                                                     // fp64 arg0 / arg1
-		{name: "FNEGS", argLength: 1, reg: fp11clobber, asm: "FNEGS", clobberFlags: true},                                            // fp32 -arg0
-		{name: "FNEG", argLength: 1, reg: fp11clobber, asm: "FNEG", clobberFlags: true},                                              // fp64 -arg0
-		{name: "FMADDS", argLength: 3, reg: fp31, asm: "FMADDS", resultInArg0: true},                                                 // fp32 arg1 * arg2 + arg0
-		{name: "FMADD", argLength: 3, reg: fp31, asm: "FMADD", resultInArg0: true},                                                   // fp64 arg1 * arg2 + arg0
-		{name: "FMSUBS", argLength: 3, reg: fp31, asm: "FMSUBS", resultInArg0: true},                                                 // fp32 arg1 * arg2 - arg0
-		{name: "FMSUB", argLength: 3, reg: fp31, asm: "FMSUB", resultInArg0: true},                                                   // fp64 arg1 * arg2 - arg0
-		{name: "LPDFR", argLength: 1, reg: fp11, asm: "LPDFR"},                                                                       // fp64/fp32 set sign bit
-		{name: "LNDFR", argLength: 1, reg: fp11, asm: "LNDFR"},                                                                       // fp64/fp32 clear sign bit
-		{name: "CPSDR", argLength: 2, reg: fp21, asm: "CPSDR"},                                                                       // fp64/fp32 copy arg1 sign bit to arg0
-
-		// Round to integer, float64 only.
-		//
-		// aux | rounding mode
-		// ----+-----------------------------------
-		//   1 | round to nearest, ties away from 0
-		//   4 | round to nearest, ties to even
-		//   5 | round toward 0
-		//   6 | round toward +∞
-		//   7 | round toward -∞
-		{name: "FIDBR", argLength: 1, reg: fp11, asm: "FIDBR", aux: "Int8"},
-
-		{name: "FMOVSload", argLength: 2, reg: fpload, asm: "FMOVS", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"}, // fp32 load
-		{name: "FMOVDload", argLength: 2, reg: fpload, asm: "FMOVD", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"}, // fp64 load
-		{name: "FMOVSconst", reg: fp01, asm: "FMOVS", aux: "Float32", rematerializeable: true},                               // fp32 constant
-		{name: "FMOVDconst", reg: fp01, asm: "FMOVD", aux: "Float64", rematerializeable: true},                               // fp64 constant
-		{name: "FMOVSloadidx", argLength: 3, reg: fploadidx, asm: "FMOVS", aux: "SymOff", symEffect: "Read"},                 // fp32 load indexed by i
-		{name: "FMOVDloadidx", argLength: 3, reg: fploadidx, asm: "FMOVD", aux: "SymOff", symEffect: "Read"},                 // fp64 load indexed by i
-
-		{name: "FMOVSstore", argLength: 3, reg: fpstore, asm: "FMOVS", aux: "SymOff", faultOnNilArg0: true, symEffect: "Write"}, // fp32 store
-		{name: "FMOVDstore", argLength: 3, reg: fpstore, asm: "FMOVD", aux: "SymOff", faultOnNilArg0: true, symEffect: "Write"}, // fp64 store
-		{name: "FMOVSstoreidx", argLength: 4, reg: fpstoreidx, asm: "FMOVS", aux: "SymOff", symEffect: "Write"},                 // fp32 indexed by i store
-		{name: "FMOVDstoreidx", argLength: 4, reg: fpstoreidx, asm: "FMOVD", aux: "SymOff", symEffect: "Write"},                 // fp64 indexed by i store
-
-		// binary ops
-		{name: "ADD", argLength: 2, reg: gp21sp, asm: "ADD", commutative: true, clobberFlags: true},                                                                  // arg0 + arg1
-		{name: "ADDW", argLength: 2, reg: gp21sp, asm: "ADDW", commutative: true, clobberFlags: true},                                                                // arg0 + arg1
-		{name: "ADDconst", argLength: 1, reg: gp11sp, asm: "ADD", aux: "Int32", typ: "UInt64", clobberFlags: true},                                                   // arg0 + auxint
-		{name: "ADDWconst", argLength: 1, reg: gp11sp, asm: "ADDW", aux: "Int32", clobberFlags: true},                                                                // arg0 + auxint
-		{name: "ADDload", argLength: 3, reg: gpopload, asm: "ADD", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},   // arg0 + *arg1. arg2=mem
-		{name: "ADDWload", argLength: 3, reg: gpopload, asm: "ADDW", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"}, // arg0 + *arg1. arg2=mem
-
-		{name: "SUB", argLength: 2, reg: gp21, asm: "SUB", clobberFlags: true},                                                                                       // arg0 - arg1
-		{name: "SUBW", argLength: 2, reg: gp21, asm: "SUBW", clobberFlags: true},                                                                                     // arg0 - arg1
-		{name: "SUBconst", argLength: 1, reg: gp11, asm: "SUB", aux: "Int32", resultInArg0: true, clobberFlags: true},                                                // arg0 - auxint
-		{name: "SUBWconst", argLength: 1, reg: gp11, asm: "SUBW", aux: "Int32", resultInArg0: true, clobberFlags: true},                                              // arg0 - auxint
-		{name: "SUBload", argLength: 3, reg: gpopload, asm: "SUB", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},   // arg0 - *arg1. arg2=mem
-		{name: "SUBWload", argLength: 3, reg: gpopload, asm: "SUBW", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"}, // arg0 - *arg1. arg2=mem
-
-		{name: "MULLD", argLength: 2, reg: gp21, asm: "MULLD", typ: "Int64", commutative: true, resultInArg0: true, clobberFlags: true},                                // arg0 * arg1
-		{name: "MULLW", argLength: 2, reg: gp21, asm: "MULLW", typ: "Int32", commutative: true, resultInArg0: true, clobberFlags: true},                                // arg0 * arg1
-		{name: "MULLDconst", argLength: 1, reg: gp11, asm: "MULLD", aux: "Int32", typ: "Int64", resultInArg0: true, clobberFlags: true},                                // arg0 * auxint
-		{name: "MULLWconst", argLength: 1, reg: gp11, asm: "MULLW", aux: "Int32", typ: "Int32", resultInArg0: true, clobberFlags: true},                                // arg0 * auxint
-		{name: "MULLDload", argLength: 3, reg: gpopload, asm: "MULLD", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"}, // arg0 * *arg1. arg2=mem
-		{name: "MULLWload", argLength: 3, reg: gpopload, asm: "MULLW", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"}, // arg0 * *arg1. arg2=mem
-
-		{name: "MULHD", argLength: 2, reg: gp21tmp, asm: "MULHD", typ: "Int64", commutative: true, resultInArg0: true, clobberFlags: true},   // (arg0 * arg1) >> width
-		{name: "MULHDU", argLength: 2, reg: gp21tmp, asm: "MULHDU", typ: "Int64", commutative: true, resultInArg0: true, clobberFlags: true}, // (arg0 * arg1) >> width
-
-		{name: "DIVD", argLength: 2, reg: gp21tmp, asm: "DIVD", resultInArg0: true, clobberFlags: true},   // arg0 / arg1
-		{name: "DIVW", argLength: 2, reg: gp21tmp, asm: "DIVW", resultInArg0: true, clobberFlags: true},   // arg0 / arg1
-		{name: "DIVDU", argLength: 2, reg: gp21tmp, asm: "DIVDU", resultInArg0: true, clobberFlags: true}, // arg0 / arg1
-		{name: "DIVWU", argLength: 2, reg: gp21tmp, asm: "DIVWU", resultInArg0: true, clobberFlags: true}, // arg0 / arg1
-
-		{name: "MODD", argLength: 2, reg: gp21tmp, asm: "MODD", resultInArg0: true, clobberFlags: true}, // arg0 % arg1
-		{name: "MODW", argLength: 2, reg: gp21tmp, asm: "MODW", resultInArg0: true, clobberFlags: true}, // arg0 % arg1
-
-		{name: "MODDU", argLength: 2, reg: gp21tmp, asm: "MODDU", resultInArg0: true, clobberFlags: true}, // arg0 % arg1
-		{name: "MODWU", argLength: 2, reg: gp21tmp, asm: "MODWU", resultInArg0: true, clobberFlags: true}, // arg0 % arg1
-
-		{name: "AND", argLength: 2, reg: gp21, asm: "AND", commutative: true, clobberFlags: true},                                                                    // arg0 & arg1
-		{name: "ANDW", argLength: 2, reg: gp21, asm: "ANDW", commutative: true, clobberFlags: true},                                                                  // arg0 & arg1
-		{name: "ANDconst", argLength: 1, reg: gp11, asm: "AND", aux: "Int64", resultInArg0: true, clobberFlags: true},                                                // arg0 & auxint
-		{name: "ANDWconst", argLength: 1, reg: gp11, asm: "ANDW", aux: "Int32", resultInArg0: true, clobberFlags: true},                                              // arg0 & auxint
-		{name: "ANDload", argLength: 3, reg: gpopload, asm: "AND", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},   // arg0 & *arg1. arg2=mem
-		{name: "ANDWload", argLength: 3, reg: gpopload, asm: "ANDW", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"}, // arg0 & *arg1. arg2=mem
-
-		{name: "OR", argLength: 2, reg: gp21, asm: "OR", commutative: true, clobberFlags: true},                                                                    // arg0 | arg1
-		{name: "ORW", argLength: 2, reg: gp21, asm: "ORW", commutative: true, clobberFlags: true},                                                                  // arg0 | arg1
-		{name: "ORconst", argLength: 1, reg: gp11, asm: "OR", aux: "Int64", resultInArg0: true, clobberFlags: true},                                                // arg0 | auxint
-		{name: "ORWconst", argLength: 1, reg: gp11, asm: "ORW", aux: "Int32", resultInArg0: true, clobberFlags: true},                                              // arg0 | auxint
-		{name: "ORload", argLength: 3, reg: gpopload, asm: "OR", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},   // arg0 | *arg1. arg2=mem
-		{name: "ORWload", argLength: 3, reg: gpopload, asm: "ORW", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"}, // arg0 | *arg1. arg2=mem
-
-		{name: "XOR", argLength: 2, reg: gp21, asm: "XOR", commutative: true, clobberFlags: true},                                                                    // arg0 ^ arg1
-		{name: "XORW", argLength: 2, reg: gp21, asm: "XORW", commutative: true, clobberFlags: true},                                                                  // arg0 ^ arg1
-		{name: "XORconst", argLength: 1, reg: gp11, asm: "XOR", aux: "Int64", resultInArg0: true, clobberFlags: true},                                                // arg0 ^ auxint
-		{name: "XORWconst", argLength: 1, reg: gp11, asm: "XORW", aux: "Int32", resultInArg0: true, clobberFlags: true},                                              // arg0 ^ auxint
-		{name: "XORload", argLength: 3, reg: gpopload, asm: "XOR", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"},   // arg0 ^ *arg1. arg2=mem
-		{name: "XORWload", argLength: 3, reg: gpopload, asm: "XORW", aux: "SymOff", resultInArg0: true, clobberFlags: true, faultOnNilArg1: true, symEffect: "Read"}, // arg0 ^ *arg1. arg2=mem
-
-		// Arithmetic ops with carry/borrow chain.
-		//
-		// A carry is represented by a condition code of 2 or 3 (GT or OV).
-		// A borrow is represented by a condition code of 0 or 1 (EQ or LT).
-		{name: "ADDC", argLength: 2, reg: gp21flags, asm: "ADDC", typ: "(UInt64,Flags)", commutative: true},                          // (arg0 + arg1, carry out)
-		{name: "ADDCconst", argLength: 1, reg: gp11flags, asm: "ADDC", typ: "(UInt64,Flags)", aux: "Int16"},                          // (arg0 + auxint, carry out)
-		{name: "ADDE", argLength: 3, reg: gp2flags1flags, asm: "ADDE", typ: "(UInt64,Flags)", commutative: true, resultInArg0: true}, // (arg0 + arg1 + arg2 (carry in), carry out)
-		{name: "SUBC", argLength: 2, reg: gp21flags, asm: "SUBC", typ: "(UInt64,Flags)"},                                             // (arg0 - arg1, borrow out)
-		{name: "SUBE", argLength: 3, reg: gp2flags1flags, asm: "SUBE", typ: "(UInt64,Flags)", resultInArg0: true},                    // (arg0 - arg1 - arg2 (borrow in), borrow out)
-
-		// Comparisons.
-		{name: "CMP", argLength: 2, reg: gp2flags, asm: "CMP", typ: "Flags"},   // arg0 compare to arg1
-		{name: "CMPW", argLength: 2, reg: gp2flags, asm: "CMPW", typ: "Flags"}, // arg0 compare to arg1
-
-		{name: "CMPU", argLength: 2, reg: gp2flags, asm: "CMPU", typ: "Flags"},   // arg0 compare to arg1
-		{name: "CMPWU", argLength: 2, reg: gp2flags, asm: "CMPWU", typ: "Flags"}, // arg0 compare to arg1
-
-		{name: "CMPconst", argLength: 1, reg: gp1flags, asm: "CMP", typ: "Flags", aux: "Int32"},     // arg0 compare to auxint
-		{name: "CMPWconst", argLength: 1, reg: gp1flags, asm: "CMPW", typ: "Flags", aux: "Int32"},   // arg0 compare to auxint
-		{name: "CMPUconst", argLength: 1, reg: gp1flags, asm: "CMPU", typ: "Flags", aux: "Int32"},   // arg0 compare to auxint
-		{name: "CMPWUconst", argLength: 1, reg: gp1flags, asm: "CMPWU", typ: "Flags", aux: "Int32"}, // arg0 compare to auxint
-
-		{name: "FCMPS", argLength: 2, reg: fp2flags, asm: "CEBR", typ: "Flags"},  // arg0 compare to arg1, f32
-		{name: "FCMP", argLength: 2, reg: fp2flags, asm: "FCMPU", typ: "Flags"},  // arg0 compare to arg1, f64
-		{name: "LTDBR", argLength: 1, reg: fp1flags, asm: "LTDBR", typ: "Flags"}, // arg0 compare to 0, f64
-		{name: "LTEBR", argLength: 1, reg: fp1flags, asm: "LTEBR", typ: "Flags"}, // arg0 compare to 0, f32
-
-		{name: "SLD", argLength: 2, reg: sh21, asm: "SLD"},                    // arg0 << arg1, shift amount is mod 64
-		{name: "SLW", argLength: 2, reg: sh21, asm: "SLW"},                    // arg0 << arg1, shift amount is mod 64
-		{name: "SLDconst", argLength: 1, reg: gp11, asm: "SLD", aux: "UInt8"}, // arg0 << auxint, shift amount 0-63
-		{name: "SLWconst", argLength: 1, reg: gp11, asm: "SLW", aux: "UInt8"}, // arg0 << auxint, shift amount 0-31
-
-		{name: "SRD", argLength: 2, reg: sh21, asm: "SRD"},                    // unsigned arg0 >> arg1, shift amount is mod 64
-		{name: "SRW", argLength: 2, reg: sh21, asm: "SRW"},                    // unsigned uint32(arg0) >> arg1, shift amount is mod 64
-		{name: "SRDconst", argLength: 1, reg: gp11, asm: "SRD", aux: "UInt8"}, // unsigned arg0 >> auxint, shift amount 0-63
-		{name: "SRWconst", argLength: 1, reg: gp11, asm: "SRW", aux: "UInt8"}, // unsigned uint32(arg0) >> auxint, shift amount 0-31
-
-		// Arithmetic shifts clobber flags.
-		{name: "SRAD", argLength: 2, reg: sh21, asm: "SRAD", clobberFlags: true},                    // signed arg0 >> arg1, shift amount is mod 64
-		{name: "SRAW", argLength: 2, reg: sh21, asm: "SRAW", clobberFlags: true},                    // signed int32(arg0) >> arg1, shift amount is mod 64
-		{name: "SRADconst", argLength: 1, reg: gp11, asm: "SRAD", aux: "UInt8", clobberFlags: true}, // signed arg0 >> auxint, shift amount 0-63
-		{name: "SRAWconst", argLength: 1, reg: gp11, asm: "SRAW", aux: "UInt8", clobberFlags: true}, // signed int32(arg0) >> auxint, shift amount 0-31
-
-		// Rotate instructions.
-		// Note: no RLLGconst - use RISBGZ instead.
-		{name: "RLLG", argLength: 2, reg: sh21, asm: "RLLG"},                  // arg0 rotate left arg1, rotate amount 0-63
-		{name: "RLL", argLength: 2, reg: sh21, asm: "RLL"},                    // arg0 rotate left arg1, rotate amount 0-31
-		{name: "RLLconst", argLength: 1, reg: gp11, asm: "RLL", aux: "UInt8"}, // arg0 rotate left auxint, rotate amount 0-31
-
-		// Rotate then (and|or|xor|insert) selected bits instructions.
-		//
-		// Aux is an s390x.RotateParams struct containing Start, End and rotation
-		// Amount fields.
-		//
-		// arg1 is rotated left by the rotation amount then the bits from the start
-		// bit to the end bit (inclusive) are combined with arg0 using the logical
-		// operation specified. Bit indices are specified from left to right - the
-		// MSB is 0 and the LSB is 63.
-		//
-		// Examples:
-		//               |          aux         |
-		// | instruction | start | end | amount |          arg0         |          arg1         |         result        |
-		// +-------------+-------+-----+--------+-----------------------+-----------------------+-----------------------+
-		// | RXSBG (XOR) |     0 |   1 |      0 | 0xffff_ffff_ffff_ffff | 0xffff_ffff_ffff_ffff | 0x3fff_ffff_ffff_ffff |
-		// | RXSBG (XOR) |    62 |  63 |      0 | 0xffff_ffff_ffff_ffff | 0xffff_ffff_ffff_ffff | 0xffff_ffff_ffff_fffc |
-		// | RXSBG (XOR) |     0 |  47 |     16 | 0xffff_ffff_ffff_ffff | 0x0000_0000_0000_ffff | 0xffff_ffff_0000_ffff |
-		// +-------------+-------+-----+--------+-----------------------+-----------------------+-----------------------+
-		//
-		{name: "RXSBG", argLength: 2, reg: gp21, asm: "RXSBG", resultInArg0: true, aux: "S390XRotateParams", clobberFlags: true}, // rotate then xor selected bits
-		{name: "RISBGZ", argLength: 1, reg: gp11, asm: "RISBGZ", aux: "S390XRotateParams", clobberFlags: true},                   // rotate then insert selected bits [into zero]
-
-		// unary ops
-		{name: "NEG", argLength: 1, reg: gp11, asm: "NEG", clobberFlags: true},   // -arg0
-		{name: "NEGW", argLength: 1, reg: gp11, asm: "NEGW", clobberFlags: true}, // -arg0
-
-		{name: "NOT", argLength: 1, reg: gp11, resultInArg0: true, clobberFlags: true},  // ^arg0
-		{name: "NOTW", argLength: 1, reg: gp11, resultInArg0: true, clobberFlags: true}, // ^arg0
-
-		{name: "FSQRT", argLength: 1, reg: fp11, asm: "FSQRT"},   // sqrt(arg0)
-		{name: "FSQRTS", argLength: 1, reg: fp11, asm: "FSQRTS"}, // sqrt(arg0), float32
-
-		// Conditional register-register moves.
-		// The aux for these values is an s390x.CCMask value representing the condition code mask.
-		{name: "LOCGR", argLength: 3, reg: gp2flags1, resultInArg0: true, asm: "LOCGR", aux: "S390XCCMask"}, // load arg1 into arg0 if the condition code in arg2 matches a masked bit in aux.
-
-		{name: "MOVBreg", argLength: 1, reg: gp11sp, asm: "MOVB", typ: "Int64"},    // sign extend arg0 from int8 to int64
-		{name: "MOVBZreg", argLength: 1, reg: gp11sp, asm: "MOVBZ", typ: "UInt64"}, // zero extend arg0 from int8 to int64
-		{name: "MOVHreg", argLength: 1, reg: gp11sp, asm: "MOVH", typ: "Int64"},    // sign extend arg0 from int16 to int64
-		{name: "MOVHZreg", argLength: 1, reg: gp11sp, asm: "MOVHZ", typ: "UInt64"}, // zero extend arg0 from int16 to int64
-		{name: "MOVWreg", argLength: 1, reg: gp11sp, asm: "MOVW", typ: "Int64"},    // sign extend arg0 from int32 to int64
-		{name: "MOVWZreg", argLength: 1, reg: gp11sp, asm: "MOVWZ", typ: "UInt64"}, // zero extend arg0 from int32 to int64
-
-		{name: "MOVDconst", reg: gp01, asm: "MOVD", typ: "UInt64", aux: "Int64", rematerializeable: true}, // auxint
-
-		{name: "LDGR", argLength: 1, reg: gpfp, asm: "LDGR"}, // move int64 to float64 (no conversion)
-		{name: "LGDR", argLength: 1, reg: fpgp, asm: "LGDR"}, // move float64 to int64 (no conversion)
-
-		{name: "CFDBRA", argLength: 1, reg: fpgp, asm: "CFDBRA", clobberFlags: true}, // convert float64 to int32
-		{name: "CGDBRA", argLength: 1, reg: fpgp, asm: "CGDBRA", clobberFlags: true}, // convert float64 to int64
-		{name: "CFEBRA", argLength: 1, reg: fpgp, asm: "CFEBRA", clobberFlags: true}, // convert float32 to int32
-		{name: "CGEBRA", argLength: 1, reg: fpgp, asm: "CGEBRA", clobberFlags: true}, // convert float32 to int64
-		{name: "CEFBRA", argLength: 1, reg: gpfp, asm: "CEFBRA", clobberFlags: true}, // convert int32 to float32
-		{name: "CDFBRA", argLength: 1, reg: gpfp, asm: "CDFBRA", clobberFlags: true}, // convert int32 to float64
-		{name: "CEGBRA", argLength: 1, reg: gpfp, asm: "CEGBRA", clobberFlags: true}, // convert int64 to float32
-		{name: "CDGBRA", argLength: 1, reg: gpfp, asm: "CDGBRA", clobberFlags: true}, // convert int64 to float64
-		{name: "CLFEBR", argLength: 1, reg: fpgp, asm: "CLFEBR", clobberFlags: true}, // convert float32 to uint32
-		{name: "CLFDBR", argLength: 1, reg: fpgp, asm: "CLFDBR", clobberFlags: true}, // convert float64 to uint32
-		{name: "CLGEBR", argLength: 1, reg: fpgp, asm: "CLGEBR", clobberFlags: true}, // convert float32 to uint64
-		{name: "CLGDBR", argLength: 1, reg: fpgp, asm: "CLGDBR", clobberFlags: true}, // convert float64 to uint64
-		{name: "CELFBR", argLength: 1, reg: gpfp, asm: "CELFBR", clobberFlags: true}, // convert uint32 to float32
-		{name: "CDLFBR", argLength: 1, reg: gpfp, asm: "CDLFBR", clobberFlags: true}, // convert uint32 to float64
-		{name: "CELGBR", argLength: 1, reg: gpfp, asm: "CELGBR", clobberFlags: true}, // convert uint64 to float32
-		{name: "CDLGBR", argLength: 1, reg: gpfp, asm: "CDLGBR", clobberFlags: true}, // convert uint64 to float64
-
-		{name: "LEDBR", argLength: 1, reg: fp11, asm: "LEDBR"}, // convert float64 to float32
-		{name: "LDEBR", argLength: 1, reg: fp11, asm: "LDEBR"}, // convert float32 to float64
-
-		{name: "MOVDaddr", argLength: 1, reg: addr, aux: "SymOff", rematerializeable: true, symEffect: "Read"}, // arg0 + auxint + offset encoded in aux
-		{name: "MOVDaddridx", argLength: 2, reg: addridx, aux: "SymOff", symEffect: "Read"},                    // arg0 + arg1 + auxint + aux
-
-		// auxint+aux == add auxint and the offset of the symbol in aux (if any) to the effective address
-		{name: "MOVBZload", argLength: 2, reg: gpload, asm: "MOVBZ", aux: "SymOff", typ: "UInt8", faultOnNilArg0: true, symEffect: "Read"},  // load byte from arg0+auxint+aux. arg1=mem.  Zero extend.
-		{name: "MOVBload", argLength: 2, reg: gpload, asm: "MOVB", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},                  // ditto, sign extend to int64
-		{name: "MOVHZload", argLength: 2, reg: gpload, asm: "MOVHZ", aux: "SymOff", typ: "UInt16", faultOnNilArg0: true, symEffect: "Read"}, // load 2 bytes from arg0+auxint+aux. arg1=mem.  Zero extend.
-		{name: "MOVHload", argLength: 2, reg: gpload, asm: "MOVH", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},                  // ditto, sign extend to int64
-		{name: "MOVWZload", argLength: 2, reg: gpload, asm: "MOVWZ", aux: "SymOff", typ: "UInt32", faultOnNilArg0: true, symEffect: "Read"}, // load 4 bytes from arg0+auxint+aux. arg1=mem.  Zero extend.
-		{name: "MOVWload", argLength: 2, reg: gpload, asm: "MOVW", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},                  // ditto, sign extend to int64
-		{name: "MOVDload", argLength: 2, reg: gpload, asm: "MOVD", aux: "SymOff", typ: "UInt64", faultOnNilArg0: true, symEffect: "Read"},   // load 8 bytes from arg0+auxint+aux. arg1=mem
-
-		{name: "MOVWBR", argLength: 1, reg: gp11, asm: "MOVWBR"}, // arg0 swap bytes
-		{name: "MOVDBR", argLength: 1, reg: gp11, asm: "MOVDBR"}, // arg0 swap bytes
-
-		{name: "MOVHBRload", argLength: 2, reg: gpload, asm: "MOVHBR", aux: "SymOff", typ: "UInt16", faultOnNilArg0: true, symEffect: "Read"}, // load 2 bytes from arg0+auxint+aux. arg1=mem. Reverse bytes.
-		{name: "MOVWBRload", argLength: 2, reg: gpload, asm: "MOVWBR", aux: "SymOff", typ: "UInt32", faultOnNilArg0: true, symEffect: "Read"}, // load 4 bytes from arg0+auxint+aux. arg1=mem. Reverse bytes.
-		{name: "MOVDBRload", argLength: 2, reg: gpload, asm: "MOVDBR", aux: "SymOff", typ: "UInt64", faultOnNilArg0: true, symEffect: "Read"}, // load 8 bytes from arg0+auxint+aux. arg1=mem. Reverse bytes.
-
-		{name: "MOVBstore", argLength: 3, reg: gpstore, asm: "MOVB", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},       // store byte in arg1 to arg0+auxint+aux. arg2=mem
-		{name: "MOVHstore", argLength: 3, reg: gpstore, asm: "MOVH", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},       // store 2 bytes in arg1 to arg0+auxint+aux. arg2=mem
-		{name: "MOVWstore", argLength: 3, reg: gpstore, asm: "MOVW", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},       // store 4 bytes in arg1 to arg0+auxint+aux. arg2=mem
-		{name: "MOVDstore", argLength: 3, reg: gpstore, asm: "MOVD", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"},       // store 8 bytes in arg1 to arg0+auxint+aux. arg2=mem
-		{name: "MOVHBRstore", argLength: 3, reg: gpstorebr, asm: "MOVHBR", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 2 bytes in arg1 to arg0+auxint+aux. arg2=mem. Reverse bytes.
-		{name: "MOVWBRstore", argLength: 3, reg: gpstorebr, asm: "MOVWBR", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 4 bytes in arg1 to arg0+auxint+aux. arg2=mem. Reverse bytes.
-		{name: "MOVDBRstore", argLength: 3, reg: gpstorebr, asm: "MOVDBR", aux: "SymOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes in arg1 to arg0+auxint+aux. arg2=mem. Reverse bytes.
-
-		{name: "MVC", argLength: 3, reg: gpmvc, asm: "MVC", aux: "SymValAndOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, faultOnNilArg1: true, symEffect: "None"}, // arg0=destptr, arg1=srcptr, arg2=mem, auxint=size,off
-
-		// indexed loads/stores
-		{name: "MOVBZloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVBZ", aux: "SymOff", typ: "UInt8", symEffect: "Read"},   // load a byte from arg0+arg1+auxint+aux. arg2=mem. Zero extend.
-		{name: "MOVBloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVB", aux: "SymOff", typ: "Int8", symEffect: "Read"},      // load a byte from arg0+arg1+auxint+aux. arg2=mem. Sign extend.
-		{name: "MOVHZloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVHZ", aux: "SymOff", typ: "UInt16", symEffect: "Read"},  // load 2 bytes from arg0+arg1+auxint+aux. arg2=mem. Zero extend.
-		{name: "MOVHloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVH", aux: "SymOff", typ: "Int16", symEffect: "Read"},     // load 2 bytes from arg0+arg1+auxint+aux. arg2=mem. Sign extend.
-		{name: "MOVWZloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVWZ", aux: "SymOff", typ: "UInt32", symEffect: "Read"},  // load 4 bytes from arg0+arg1+auxint+aux. arg2=mem. Zero extend.
-		{name: "MOVWloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVW", aux: "SymOff", typ: "Int32", symEffect: "Read"},     // load 4 bytes from arg0+arg1+auxint+aux. arg2=mem. Sign extend.
-		{name: "MOVDloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVD", aux: "SymOff", typ: "UInt64", symEffect: "Read"},    // load 8 bytes from arg0+arg1+auxint+aux. arg2=mem
-		{name: "MOVHBRloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVHBR", aux: "SymOff", typ: "Int16", symEffect: "Read"}, // load 2 bytes from arg0+arg1+auxint+aux. arg2=mem. Reverse bytes.
-		{name: "MOVWBRloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVWBR", aux: "SymOff", typ: "Int32", symEffect: "Read"}, // load 4 bytes from arg0+arg1+auxint+aux. arg2=mem. Reverse bytes.
-		{name: "MOVDBRloadidx", argLength: 3, reg: gploadidx, commutative: true, asm: "MOVDBR", aux: "SymOff", typ: "Int64", symEffect: "Read"}, // load 8 bytes from arg0+arg1+auxint+aux. arg2=mem. Reverse bytes.
-		{name: "MOVBstoreidx", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVB", aux: "SymOff", symEffect: "Write"},                // store byte in arg2 to arg0+arg1+auxint+aux. arg3=mem
-		{name: "MOVHstoreidx", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVH", aux: "SymOff", symEffect: "Write"},                // store 2 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem
-		{name: "MOVWstoreidx", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVW", aux: "SymOff", symEffect: "Write"},                // store 4 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem
-		{name: "MOVDstoreidx", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVD", aux: "SymOff", symEffect: "Write"},                // store 8 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem
-		{name: "MOVHBRstoreidx", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVHBR", aux: "SymOff", symEffect: "Write"},            // store 2 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem. Reverse bytes.
-		{name: "MOVWBRstoreidx", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVWBR", aux: "SymOff", symEffect: "Write"},            // store 4 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem. Reverse bytes.
-		{name: "MOVDBRstoreidx", argLength: 4, reg: gpstoreidx, commutative: true, asm: "MOVDBR", aux: "SymOff", symEffect: "Write"},            // store 8 bytes in arg2 to arg0+arg1+auxint+aux. arg3=mem. Reverse bytes.
-
-		// For storeconst ops, the AuxInt field encodes both
-		// the value to store and an address offset of the store.
-		// Cast AuxInt to a ValAndOff to extract Val and Off fields.
-		{name: "MOVBstoreconst", argLength: 2, reg: gpstoreconst, asm: "MOVB", aux: "SymValAndOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store low byte of ValAndOff(AuxInt).Val() to arg0+ValAndOff(AuxInt).Off()+aux.  arg1=mem
-		{name: "MOVHstoreconst", argLength: 2, reg: gpstoreconst, asm: "MOVH", aux: "SymValAndOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store low 2 bytes of ...
-		{name: "MOVWstoreconst", argLength: 2, reg: gpstoreconst, asm: "MOVW", aux: "SymValAndOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store low 4 bytes of ...
-		{name: "MOVDstoreconst", argLength: 2, reg: gpstoreconst, asm: "MOVD", aux: "SymValAndOff", typ: "Mem", faultOnNilArg0: true, symEffect: "Write"}, // store 8 bytes of ...
-
-		{name: "CLEAR", argLength: 2, reg: regInfo{inputs: []regMask{ptr, 0}}, asm: "CLEAR", aux: "SymValAndOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, symEffect: "Write"},
-
-		{name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                                                // call static function aux.(*obj.LSym).  arg0=mem, auxint=argsize, returns mem
-		{name: "CALLtail", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true, tailCall: true},                                  // tail call static function aux.(*obj.LSym).  arg0=mem, auxint=argsize, returns mem
-		{name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{ptrsp, buildReg("R12"), 0}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true}, // call function via closure.  arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem
-		{name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{ptr}, clobbers: callerSave}, aux: "CallOff", clobberFlags: true, call: true},                         // call fn by pointer.  arg0=codeptr, arg1=mem, auxint=argsize, returns mem
-
-		// (InvertFlags (CMP a b)) == (CMP b a)
-		// InvertFlags is a pseudo-op which can't appear in assembly output.
-		{name: "InvertFlags", argLength: 1}, // reverse direction of arg0
-
-		// Pseudo-ops
-		{name: "LoweredGetG", argLength: 1, reg: gp01}, // arg0=mem
-		// Scheduler ensures LoweredGetClosurePtr occurs only in entry block,
-		// and sorts it to the very beginning of the block to prevent other
-		// use of R12 (the closure pointer)
-		{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R12")}}, zeroWidth: true},
-		// arg0=ptr,arg1=mem, returns void.  Faults if ptr is nil.
-		// LoweredGetCallerSP returns the SP of the caller of the current function.
-		{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
-		// LoweredGetCallerPC evaluates to the PC to which its "caller" will return.
-		// I.e., if f calls g "calls" getcallerpc,
-		// the result should be the PC within f that g will return to.
-		// See runtime/stubs.go for a more detailed discussion.
-		{name: "LoweredGetCallerPC", reg: gp01, rematerializeable: true},
-		{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{ptrsp}}, clobberFlags: true, nilCheck: true, faultOnNilArg0: true},
-		// Round ops to block fused-multiply-add extraction.
-		{name: "LoweredRound32F", argLength: 1, reg: fp11, resultInArg0: true, zeroWidth: true},
-		{name: "LoweredRound64F", argLength: 1, reg: fp11, resultInArg0: true, zeroWidth: true},
-
-		// LoweredWB invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
-		// It saves all GP registers if necessary,
-		// but clobbers R14 (LR) because it's a call,
-		// and also clobbers R1 as the PLT stub does.
-		{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R2"), buildReg("R3")}, clobbers: (callerSave &^ gpg) | buildReg("R14") | r1}, clobberFlags: true, aux: "Sym", symEffect: "None"},
-
-		// There are three of these functions so that they can have three different register inputs.
-		// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the
-		// default registers to match so we don't need to copy registers around unnecessarily.
-		{name: "LoweredPanicBoundsA", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r2, r3}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
-		{name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r1, r2}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
-		{name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r0, r1}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in generic.go).
-
-		// Constant condition code values. The condition code can be 0, 1, 2 or 3.
-		{name: "FlagEQ"}, // CC=0 (equal)
-		{name: "FlagLT"}, // CC=1 (less than)
-		{name: "FlagGT"}, // CC=2 (greater than)
-		{name: "FlagOV"}, // CC=3 (overflow)
-
-		// Fast-BCR-serialization to ensure store-load ordering.
-		{name: "SYNC", argLength: 1, reg: sync, asm: "SYNC", typ: "Mem"},
-
-		// Atomic loads. These are just normal loads but return <value,memory> tuples
-		// so they can be properly ordered with other loads.
-		// load from arg0+auxint+aux.  arg1=mem.
-		{name: "MOVBZatomicload", argLength: 2, reg: gpload, asm: "MOVBZ", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},
-		{name: "MOVWZatomicload", argLength: 2, reg: gpload, asm: "MOVWZ", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},
-		{name: "MOVDatomicload", argLength: 2, reg: gpload, asm: "MOVD", aux: "SymOff", faultOnNilArg0: true, symEffect: "Read"},
-
-		// Atomic stores. These are just normal stores.
-		// store arg1 to arg0+auxint+aux. arg2=mem.
-		{name: "MOVBatomicstore", argLength: 3, reg: gpstore, asm: "MOVB", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "Write"},
-		{name: "MOVWatomicstore", argLength: 3, reg: gpstore, asm: "MOVW", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "Write"},
-		{name: "MOVDatomicstore", argLength: 3, reg: gpstore, asm: "MOVD", aux: "SymOff", typ: "Mem", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "Write"},
-
-		// Atomic adds.
-		// *(arg0+auxint+aux) += arg1.  arg2=mem.
-		// Returns a tuple of <old contents of *(arg0+auxint+aux), memory>.
-		{name: "LAA", argLength: 3, reg: gpstorelaa, asm: "LAA", typ: "(UInt32,Mem)", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "RdWr"},
-		{name: "LAAG", argLength: 3, reg: gpstorelaa, asm: "LAAG", typ: "(UInt64,Mem)", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "RdWr"},
-		{name: "AddTupleFirst32", argLength: 2}, // arg1=tuple <x,y>.  Returns <x+arg0,y>.
-		{name: "AddTupleFirst64", argLength: 2}, // arg1=tuple <x,y>.  Returns <x+arg0,y>.
-
-		// Atomic bitwise operations.
-		// Note: 'floor' operations round the pointer down to the nearest word boundary
-		// which reflects how they are used in the runtime.
-		{name: "LAN", argLength: 3, reg: gpstore, asm: "LAN", typ: "Mem", clobberFlags: true, hasSideEffects: true},         // *arg0 &= arg1. arg2 = mem.
-		{name: "LANfloor", argLength: 3, reg: gpstorelab, asm: "LAN", typ: "Mem", clobberFlags: true, hasSideEffects: true}, // *(floor(arg0, 4)) &= arg1. arg2 = mem.
-		{name: "LAO", argLength: 3, reg: gpstore, asm: "LAO", typ: "Mem", clobberFlags: true, hasSideEffects: true},         // *arg0 |= arg1. arg2 = mem.
-		{name: "LAOfloor", argLength: 3, reg: gpstorelab, asm: "LAO", typ: "Mem", clobberFlags: true, hasSideEffects: true}, // *(floor(arg0, 4)) |= arg1. arg2 = mem.
-
-		// Compare and swap.
-		// arg0 = pointer, arg1 = old value, arg2 = new value, arg3 = memory.
-		// if *(arg0+auxint+aux) == arg1 {
-		//   *(arg0+auxint+aux) = arg2
-		//   return (true, memory)
-		// } else {
-		//   return (false, memory)
-		// }
-		// Note that these instructions also return the old value in arg1, but we ignore it.
-		// TODO: have these return flags instead of bool.  The current system generates:
-		//    CS ...
-		//    MOVD  $0, ret
-		//    BNE   2(PC)
-		//    MOVD  $1, ret
-		//    CMPW  ret, $0
-		//    BNE ...
-		// instead of just
-		//    CS ...
-		//    BEQ ...
-		// but we can't do that because memory-using ops can't generate flags yet
-		// (flagalloc wants to move flag-generating instructions around).
-		{name: "LoweredAtomicCas32", argLength: 4, reg: cas, asm: "CS", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "RdWr"},
-		{name: "LoweredAtomicCas64", argLength: 4, reg: cas, asm: "CSG", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "RdWr"},
-
-		// Lowered atomic swaps, emulated using compare-and-swap.
-		// store arg1 to arg0+auxint+aux, arg2=mem.
-		{name: "LoweredAtomicExchange32", argLength: 3, reg: exchange, asm: "CS", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "RdWr"},
-		{name: "LoweredAtomicExchange64", argLength: 3, reg: exchange, asm: "CSG", aux: "SymOff", clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true, symEffect: "RdWr"},
-
-		// find leftmost one
-		{
-			name:         "FLOGR",
-			argLength:    1,
-			reg:          regInfo{inputs: gponly, outputs: []regMask{buildReg("R0")}, clobbers: buildReg("R1")},
-			asm:          "FLOGR",
-			typ:          "UInt64",
-			clobberFlags: true,
-		},
-
-		// population count
-		//
-		// Counts the number of ones in each byte of arg0
-		// and places the result into the corresponding byte
-		// of the result.
-		{
-			name:         "POPCNT",
-			argLength:    1,
-			reg:          gp11,
-			asm:          "POPCNT",
-			typ:          "UInt64",
-			clobberFlags: true,
-		},
-
-		// unsigned multiplication (64x64 → 128)
-		//
-		// Multiply the two 64-bit input operands together and place the 128-bit result into
-		// an even-odd register pair. The second register in the target pair also contains
-		// one of the input operands. Since we don't currently have a way to specify an
-		// even-odd register pair we hardcode this register pair as R2:R3.
-		{
-			name:      "MLGR",
-			argLength: 2,
-			reg:       regInfo{inputs: []regMask{gp, r3}, outputs: []regMask{r2, r3}},
-			asm:       "MLGR",
-		},
-
-		// pseudo operations to sum the output of the POPCNT instruction
-		{name: "SumBytes2", argLength: 1, typ: "UInt8"}, // sum the rightmost 2 bytes in arg0 ignoring overflow
-		{name: "SumBytes4", argLength: 1, typ: "UInt8"}, // sum the rightmost 4 bytes in arg0 ignoring overflow
-		{name: "SumBytes8", argLength: 1, typ: "UInt8"}, // sum all the bytes in arg0 ignoring overflow
-
-		// store multiple
-		{
-			name:           "STMG2",
-			argLength:      4,
-			reg:            regInfo{inputs: []regMask{ptrsp, buildReg("R1"), buildReg("R2"), 0}},
-			aux:            "SymOff",
-			typ:            "Mem",
-			asm:            "STMG",
-			faultOnNilArg0: true,
-			symEffect:      "Write",
-			clobberFlags:   true, // TODO(mundaym): currently uses AGFI to handle large offsets
-		},
-		{
-			name:           "STMG3",
-			argLength:      5,
-			reg:            regInfo{inputs: []regMask{ptrsp, buildReg("R1"), buildReg("R2"), buildReg("R3"), 0}},
-			aux:            "SymOff",
-			typ:            "Mem",
-			asm:            "STMG",
-			faultOnNilArg0: true,
-			symEffect:      "Write",
-			clobberFlags:   true, // TODO(mundaym): currently uses AGFI to handle large offsets
-		},
-		{
-			name:      "STMG4",
-			argLength: 6,
-			reg: regInfo{inputs: []regMask{
-				ptrsp,
-				buildReg("R1"),
-				buildReg("R2"),
-				buildReg("R3"),
-				buildReg("R4"),
-				0,
-			}},
-			aux:            "SymOff",
-			typ:            "Mem",
-			asm:            "STMG",
-			faultOnNilArg0: true,
-			symEffect:      "Write",
-			clobberFlags:   true, // TODO(mundaym): currently uses AGFI to handle large offsets
-		},
-		{
-			name:           "STM2",
-			argLength:      4,
-			reg:            regInfo{inputs: []regMask{ptrsp, buildReg("R1"), buildReg("R2"), 0}},
-			aux:            "SymOff",
-			typ:            "Mem",
-			asm:            "STMY",
-			faultOnNilArg0: true,
-			symEffect:      "Write",
-			clobberFlags:   true, // TODO(mundaym): currently uses AGFI to handle large offsets
-		},
-		{
-			name:           "STM3",
-			argLength:      5,
-			reg:            regInfo{inputs: []regMask{ptrsp, buildReg("R1"), buildReg("R2"), buildReg("R3"), 0}},
-			aux:            "SymOff",
-			typ:            "Mem",
-			asm:            "STMY",
-			faultOnNilArg0: true,
-			symEffect:      "Write",
-			clobberFlags:   true, // TODO(mundaym): currently uses AGFI to handle large offsets
-		},
-		{
-			name:      "STM4",
-			argLength: 6,
-			reg: regInfo{inputs: []regMask{
-				ptrsp,
-				buildReg("R1"),
-				buildReg("R2"),
-				buildReg("R3"),
-				buildReg("R4"),
-				0,
-			}},
-			aux:            "SymOff",
-			typ:            "Mem",
-			asm:            "STMY",
-			faultOnNilArg0: true,
-			symEffect:      "Write",
-			clobberFlags:   true, // TODO(mundaym): currently uses AGFI to handle large offsets
-		},
-
-		// large move
-		// auxint = remaining bytes after loop (rem)
-		// arg0 = address of dst memory (in R1, changed as a side effect)
-		// arg1 = address of src memory (in R2, changed as a side effect)
-		// arg2 = pointer to last address to move in loop + 256
-		// arg3 = mem
-		// returns mem
-		//
-		// mvc: MVC  $256, 0(R2), 0(R1)
-		//      MOVD $256(R1), R1
-		//      MOVD $256(R2), R2
-		//      CMP  R2, Rarg2
-		//      BNE  mvc
-		//	MVC  $rem, 0(R2), 0(R1) // if rem > 0
-		{
-			name:      "LoweredMove",
-			aux:       "Int64",
-			argLength: 4,
-			reg: regInfo{
-				inputs:   []regMask{buildReg("R1"), buildReg("R2"), gpsp},
-				clobbers: buildReg("R1 R2"),
-			},
-			clobberFlags:   true,
-			typ:            "Mem",
-			faultOnNilArg0: true,
-			faultOnNilArg1: true,
-		},
-
-		// large clear
-		// auxint = remaining bytes after loop (rem)
-		// arg0 = address of dst memory (in R1, changed as a side effect)
-		// arg1 = pointer to last address to zero in loop + 256
-		// arg2 = mem
-		// returns mem
-		//
-		// clear: CLEAR $256, 0(R1)
-		//        MOVD  $256(R1), R1
-		//        CMP   R1, Rarg2
-		//        BNE   clear
-		//	  CLEAR $rem, 0(R1) // if rem > 0
-		{
-			name:      "LoweredZero",
-			aux:       "Int64",
-			argLength: 3,
-			reg: regInfo{
-				inputs:   []regMask{buildReg("R1"), gpsp},
-				clobbers: buildReg("R1"),
-			},
-			clobberFlags:   true,
-			typ:            "Mem",
-			faultOnNilArg0: true,
-		},
-	}
-
-	// All blocks on s390x have their condition code mask (s390x.CCMask) as the Aux value.
-	// The condition code mask is a 4-bit mask where each bit corresponds to a condition
-	// code value. If the value of the condition code matches a bit set in the condition
-	// code mask then the first successor is executed. Otherwise the second successor is
-	// executed.
-	//
-	// | condition code value |  mask bit  |
-	// +----------------------+------------+
-	// | 0 (equal)            | 0b1000 (8) |
-	// | 1 (less than)        | 0b0100 (4) |
-	// | 2 (greater than)     | 0b0010 (2) |
-	// | 3 (unordered)        | 0b0001 (1) |
-	//
-	// Note: that compare-and-branch instructions must not have bit 3 (0b0001) set.
-	var S390Xblocks = []blockData{
-		// branch on condition
-		{name: "BRC", controls: 1, aux: "S390XCCMask"}, // condition code value (flags) is Controls[0]
-
-		// compare-and-branch (register-register)
-		//  - integrates comparison of Controls[0] with Controls[1]
-		//  - both control values must be in general purpose registers
-		{name: "CRJ", controls: 2, aux: "S390XCCMask"},   // signed 32-bit integer comparison
-		{name: "CGRJ", controls: 2, aux: "S390XCCMask"},  // signed 64-bit integer comparison
-		{name: "CLRJ", controls: 2, aux: "S390XCCMask"},  // unsigned 32-bit integer comparison
-		{name: "CLGRJ", controls: 2, aux: "S390XCCMask"}, // unsigned 64-bit integer comparison
-
-		// compare-and-branch (register-immediate)
-		//  - integrates comparison of Controls[0] with AuxInt
-		//  - control value must be in a general purpose register
-		//  - the AuxInt value is sign-extended for signed comparisons
-		//    and zero-extended for unsigned comparisons
-		{name: "CIJ", controls: 1, aux: "S390XCCMaskInt8"},    // signed 32-bit integer comparison
-		{name: "CGIJ", controls: 1, aux: "S390XCCMaskInt8"},   // signed 64-bit integer comparison
-		{name: "CLIJ", controls: 1, aux: "S390XCCMaskUint8"},  // unsigned 32-bit integer comparison
-		{name: "CLGIJ", controls: 1, aux: "S390XCCMaskUint8"}, // unsigned 64-bit integer comparison
-	}
-
-	archs = append(archs, arch{
-		name:            "S390X",
-		pkg:             "cmd/internal/obj/s390x",
-		genfile:         "../../s390x/ssa.go",
-		ops:             S390Xops,
-		blocks:          S390Xblocks,
-		regnames:        regNamesS390X,
-		gpregmask:       gp,
-		fpregmask:       fp,
-		framepointerreg: -1, // not used
-		linkreg:         int8(num["R14"]),
-		imports: []string{
-			"cmd/internal/obj/s390x",
-		},
-	})
-}
diff --git a/src/cmd/compile/internal/ssa/gen/Wasm.rules b/src/cmd/compile/internal/ssa/gen/Wasm.rules
deleted file mode 100644
index 9e683b1..0000000
--- a/src/cmd/compile/internal/ssa/gen/Wasm.rules
+++ /dev/null
@@ -1,411 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Lowering arithmetic
-(Add(64|32|16|8|Ptr) ...) => (I64Add ...)
-(Add(64|32)F ...) => (F(64|32)Add ...)
-
-(Sub(64|32|16|8|Ptr) ...) => (I64Sub ...)
-(Sub(64|32)F ...) => (F(64|32)Sub ...)
-
-(Mul(64|32|16|8) ...) => (I64Mul ...)
-(Mul(64|32)F ...) => (F(64|32)Mul ...)
-
-(Div64 [false] x y) => (I64DivS x y)
-(Div32 [false] x y) => (I64DivS (SignExt32to64 x) (SignExt32to64 y))
-(Div16 [false] x y) => (I64DivS (SignExt16to64 x) (SignExt16to64 y))
-(Div8          x y) => (I64DivS (SignExt8to64 x) (SignExt8to64 y))
-(Div64u ...) => (I64DivU ...)
-(Div32u x y) => (I64DivU (ZeroExt32to64 x) (ZeroExt32to64 y))
-(Div16u x y) => (I64DivU (ZeroExt16to64 x) (ZeroExt16to64 y))
-(Div8u  x y) => (I64DivU (ZeroExt8to64 x) (ZeroExt8to64 y))
-(Div(64|32)F ...) => (F(64|32)Div ...)
-
-(Mod64 [false] x y) => (I64RemS x y)
-(Mod32 [false] x y) => (I64RemS (SignExt32to64 x) (SignExt32to64 y))
-(Mod16 [false] x y) => (I64RemS (SignExt16to64 x) (SignExt16to64 y))
-(Mod8          x y) => (I64RemS (SignExt8to64  x) (SignExt8to64  y))
-(Mod64u ...) => (I64RemU ...)
-(Mod32u x y) => (I64RemU (ZeroExt32to64 x) (ZeroExt32to64 y))
-(Mod16u x y) => (I64RemU (ZeroExt16to64 x) (ZeroExt16to64 y))
-(Mod8u  x y) => (I64RemU (ZeroExt8to64  x) (ZeroExt8to64  y))
-
-(And(64|32|16|8|B) ...) => (I64And ...)
-
-(Or(64|32|16|8|B) ...) => (I64Or ...)
-
-(Xor(64|32|16|8) ...) => (I64Xor ...)
-
-(Neg(64|32|16|8) x) => (I64Sub (I64Const [0]) x)
-(Neg(64|32)F ...) => (F(64|32)Neg ...)
-
-(Com(64|32|16|8) x) => (I64Xor x (I64Const [-1]))
-
-(Not ...) => (I64Eqz ...)
-
-// Lowering pointer arithmetic
-(OffPtr ...) => (I64AddConst ...)
-
-// Lowering extension
-// It is unnecessary to extend loads
-(SignExt32to64        x:(I64Load32S _ _)) => x
-(SignExt16to(64|32)   x:(I64Load16S _ _)) => x
-(SignExt8to(64|32|16) x:(I64Load8S  _ _)) => x
-(ZeroExt32to64        x:(I64Load32U _ _)) => x
-(ZeroExt16to(64|32)   x:(I64Load16U _ _)) => x
-(ZeroExt8to(64|32|16) x:(I64Load8U  _ _)) => x
-(SignExt32to64        x) && buildcfg.GOWASM.SignExt => (I64Extend32S x)
-(SignExt8to(64|32|16) x) && buildcfg.GOWASM.SignExt => (I64Extend8S x)
-(SignExt16to(64|32)   x) && buildcfg.GOWASM.SignExt => (I64Extend16S x)
-(SignExt32to64        x) => (I64ShrS (I64Shl x (I64Const [32])) (I64Const [32]))
-(SignExt16to(64|32)   x) => (I64ShrS (I64Shl x (I64Const [48])) (I64Const [48]))
-(SignExt8to(64|32|16) x) => (I64ShrS (I64Shl x (I64Const [56])) (I64Const [56]))
-(ZeroExt32to64        x) => (I64And x (I64Const [0xffffffff]))
-(ZeroExt16to(64|32)   x) => (I64And x (I64Const [0xffff]))
-(ZeroExt8to(64|32|16) x) => (I64And x (I64Const [0xff]))
-
-(Slicemask x) => (I64ShrS (I64Sub (I64Const [0]) x) (I64Const [63]))
-
-// Lowering truncation
-// Because we ignore the high parts, truncates are just copies.
-(Trunc64to(32|16|8) ...) => (Copy ...)
-(Trunc32to(16|8)    ...) => (Copy ...)
-(Trunc16to8         ...) => (Copy ...)
-
-// Lowering float <=> int
-(Cvt32to(64|32)F x) => (F(64|32)ConvertI64S (SignExt32to64 x))
-(Cvt64to(64|32)F ...) => (F(64|32)ConvertI64S ...)
-(Cvt32Uto(64|32)F x) => (F(64|32)ConvertI64U (ZeroExt32to64 x))
-(Cvt64Uto(64|32)F ...) => (F(64|32)ConvertI64U ...)
-
-(Cvt32Fto32 ...) => (I64TruncSatF32S ...)
-(Cvt32Fto64 ...) => (I64TruncSatF32S ...)
-(Cvt64Fto32 ...) => (I64TruncSatF64S ...)
-(Cvt64Fto64 ...) => (I64TruncSatF64S ...)
-(Cvt32Fto32U ...) => (I64TruncSatF32U ...)
-(Cvt32Fto64U ...) => (I64TruncSatF32U ...)
-(Cvt64Fto32U ...) => (I64TruncSatF64U ...)
-(Cvt64Fto64U ...) => (I64TruncSatF64U ...)
-
-(Cvt32Fto64F ...) => (F64PromoteF32 ...)
-(Cvt64Fto32F ...) => (F32DemoteF64 ...)
-
-(CvtBoolToUint8 ...) => (Copy ...)
-
-(Round32F ...) => (Copy ...)
-(Round64F ...) => (Copy ...)
-
-// Lowering shifts
-// Unsigned shifts need to return 0 if shift amount is >= width of shifted value.
-
-(Lsh64x64 x y) && shiftIsBounded(v) => (I64Shl x y)
-(Lsh64x64 x (I64Const [c])) && uint64(c) < 64 => (I64Shl x (I64Const [c]))
-(Lsh64x64 x (I64Const [c])) && uint64(c) >= 64 => (I64Const [0])
-(Lsh64x64 x y) => (Select (I64Shl x y) (I64Const [0]) (I64LtU y (I64Const [64])))
-(Lsh64x(32|16|8) [c] x y) => (Lsh64x64 [c] x (ZeroExt(32|16|8)to64 y))
-
-(Lsh32x64 ...) => (Lsh64x64 ...)
-(Lsh32x(32|16|8) [c] x y) => (Lsh64x64 [c] x (ZeroExt(32|16|8)to64 y))
-
-(Lsh16x64 ...) => (Lsh64x64 ...)
-(Lsh16x(32|16|8) [c] x y) => (Lsh64x64 [c] x (ZeroExt(32|16|8)to64 y))
-
-(Lsh8x64 ...) => (Lsh64x64 ...)
-(Lsh8x(32|16|8) [c] x y) => (Lsh64x64 [c] x (ZeroExt(32|16|8)to64 y))
-
-(Rsh64Ux64 x y) && shiftIsBounded(v) => (I64ShrU x y)
-(Rsh64Ux64 x (I64Const [c])) && uint64(c) < 64 => (I64ShrU x (I64Const [c]))
-(Rsh64Ux64 x (I64Const [c])) && uint64(c) >= 64 => (I64Const [0])
-(Rsh64Ux64 x y) => (Select (I64ShrU x y) (I64Const [0]) (I64LtU y (I64Const [64])))
-(Rsh64Ux(32|16|8) [c] x y) => (Rsh64Ux64 [c] x (ZeroExt(32|16|8)to64 y))
-
-(Rsh32Ux64 [c] x y) => (Rsh64Ux64 [c] (ZeroExt32to64 x) y)
-(Rsh32Ux(32|16|8) [c] x y) => (Rsh64Ux64 [c] (ZeroExt32to64 x) (ZeroExt(32|16|8)to64 y))
-
-(Rsh16Ux64 [c] x y) => (Rsh64Ux64 [c] (ZeroExt16to64 x) y)
-(Rsh16Ux(32|16|8) [c] x y) => (Rsh64Ux64 [c] (ZeroExt16to64 x) (ZeroExt(32|16|8)to64 y))
-
-(Rsh8Ux64 [c] x y) => (Rsh64Ux64 [c] (ZeroExt8to64 x) y)
-(Rsh8Ux(32|16|8) [c] x y) => (Rsh64Ux64 [c] (ZeroExt8to64 x) (ZeroExt(32|16|8)to64 y))
-
-// Signed right shift needs to return 0/-1 if shift amount is >= width of shifted value.
-// We implement this by setting the shift value to (width - 1) if the shift value is >= width.
-
-(Rsh64x64 x y) && shiftIsBounded(v) => (I64ShrS x y)
-(Rsh64x64 x (I64Const [c])) && uint64(c) < 64 => (I64ShrS x (I64Const [c]))
-(Rsh64x64 x (I64Const [c])) && uint64(c) >= 64 => (I64ShrS x (I64Const [63]))
-(Rsh64x64 x y) => (I64ShrS x (Select <typ.Int64> y (I64Const [63]) (I64LtU y (I64Const [64]))))
-(Rsh64x(32|16|8) [c] x y) => (Rsh64x64 [c] x (ZeroExt(32|16|8)to64 y))
-
-(Rsh32x64 [c] x y) => (Rsh64x64 [c] (SignExt32to64 x) y)
-(Rsh32x(32|16|8) [c] x y) => (Rsh64x64 [c] (SignExt32to64 x) (ZeroExt(32|16|8)to64 y))
-
-(Rsh16x64 [c] x y) => (Rsh64x64 [c] (SignExt16to64 x) y)
-(Rsh16x(32|16|8) [c] x y) => (Rsh64x64 [c] (SignExt16to64 x) (ZeroExt(32|16|8)to64 y))
-
-(Rsh8x64 [c] x y)  => (Rsh64x64 [c] (SignExt8to64 x) y)
-(Rsh8x(32|16|8) [c] x y)  => (Rsh64x64 [c] (SignExt8to64 x) (ZeroExt(32|16|8)to64 y))
-
-// Lowering rotates
-(RotateLeft8 <t> x (I64Const [c])) => (Or8 (Lsh8x64 <t> x (I64Const [c&7])) (Rsh8Ux64 <t> x (I64Const [-c&7])))
-(RotateLeft16 <t> x (I64Const [c])) => (Or16 (Lsh16x64 <t> x (I64Const [c&15])) (Rsh16Ux64 <t> x (I64Const [-c&15])))
-(RotateLeft32 ...) => (I32Rotl ...)
-(RotateLeft64 ...) => (I64Rotl ...)
-
-// Lowering comparisons
-(Less64  ...) => (I64LtS ...)
-(Less32  x y) => (I64LtS (SignExt32to64 x) (SignExt32to64 y))
-(Less16  x y) => (I64LtS (SignExt16to64 x) (SignExt16to64 y))
-(Less8   x y) => (I64LtS (SignExt8to64  x) (SignExt8to64  y))
-(Less64U ...) => (I64LtU ...)
-(Less32U x y) => (I64LtU (ZeroExt32to64 x) (ZeroExt32to64 y))
-(Less16U x y) => (I64LtU (ZeroExt16to64 x) (ZeroExt16to64 y))
-(Less8U  x y) => (I64LtU (ZeroExt8to64  x) (ZeroExt8to64  y))
-(Less(64|32)F ...) => (F(64|32)Lt ...)
-
-(Leq64  ...) => (I64LeS ...)
-(Leq32  x y) => (I64LeS (SignExt32to64 x) (SignExt32to64 y))
-(Leq16  x y) => (I64LeS (SignExt16to64 x) (SignExt16to64 y))
-(Leq8   x y) => (I64LeS (SignExt8to64  x) (SignExt8to64  y))
-(Leq64U ...) => (I64LeU ...)
-(Leq32U x y) => (I64LeU (ZeroExt32to64 x) (ZeroExt32to64 y))
-(Leq16U x y) => (I64LeU (ZeroExt16to64 x) (ZeroExt16to64 y))
-(Leq8U  x y) => (I64LeU (ZeroExt8to64  x) (ZeroExt8to64  y))
-(Leq(64|32)F ...) => (F(64|32)Le ...)
-
-(Eq64  ...) => (I64Eq ...)
-(Eq32  x y) => (I64Eq (ZeroExt32to64 x) (ZeroExt32to64 y))
-(Eq16  x y) => (I64Eq (ZeroExt16to64 x) (ZeroExt16to64 y))
-(Eq8   x y) => (I64Eq (ZeroExt8to64  x) (ZeroExt8to64  y))
-(EqB   ...) => (I64Eq ...)
-(EqPtr ...) => (I64Eq ...)
-(Eq(64|32)F ...) => (F(64|32)Eq ...)
-
-(Neq64  ...) => (I64Ne ...)
-(Neq32  x y) => (I64Ne (ZeroExt32to64 x) (ZeroExt32to64 y))
-(Neq16  x y) => (I64Ne (ZeroExt16to64 x) (ZeroExt16to64 y))
-(Neq8   x y) => (I64Ne (ZeroExt8to64  x) (ZeroExt8to64  y))
-(NeqB   ...) => (I64Ne ...)
-(NeqPtr ...) => (I64Ne ...)
-(Neq(64|32)F ...) => (F(64|32)Ne ...)
-
-// Lowering loads
-(Load <t> ptr mem) && is32BitFloat(t) => (F32Load ptr mem)
-(Load <t> ptr mem) && is64BitFloat(t) => (F64Load ptr mem)
-(Load <t> ptr mem) && t.Size() == 8 => (I64Load ptr mem)
-(Load <t> ptr mem) && t.Size() == 4 && !t.IsSigned() => (I64Load32U ptr mem)
-(Load <t> ptr mem) && t.Size() == 4 &&  t.IsSigned() => (I64Load32S ptr mem)
-(Load <t> ptr mem) && t.Size() == 2 && !t.IsSigned() => (I64Load16U ptr mem)
-(Load <t> ptr mem) && t.Size() == 2 &&  t.IsSigned() => (I64Load16S ptr mem)
-(Load <t> ptr mem) && t.Size() == 1 && !t.IsSigned() => (I64Load8U ptr mem)
-(Load <t> ptr mem) && t.Size() == 1 &&  t.IsSigned() => (I64Load8S ptr mem)
-
-// Lowering stores
-(Store {t} ptr val mem) && is64BitFloat(t) => (F64Store ptr val mem)
-(Store {t} ptr val mem) && is32BitFloat(t) => (F32Store ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 8 => (I64Store ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 4 => (I64Store32 ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 2 => (I64Store16 ptr val mem)
-(Store {t} ptr val mem) && t.Size() == 1 => (I64Store8 ptr val mem)
-
-// Lowering moves
-(Move [0] _ _ mem) => mem
-(Move [1] dst src mem) => (I64Store8 dst (I64Load8U src mem) mem)
-(Move [2] dst src mem) => (I64Store16 dst (I64Load16U src mem) mem)
-(Move [4] dst src mem) => (I64Store32 dst (I64Load32U src mem) mem)
-(Move [8] dst src mem) => (I64Store dst (I64Load src mem) mem)
-(Move [16] dst src mem) =>
-	(I64Store [8] dst (I64Load [8] src mem)
-		(I64Store dst (I64Load src mem) mem))
-(Move [3] dst src mem) =>
-	(I64Store8 [2] dst (I64Load8U [2] src mem)
-		(I64Store16 dst (I64Load16U src mem) mem))
-(Move [5] dst src mem) =>
-	(I64Store8 [4] dst (I64Load8U [4] src mem)
-		(I64Store32 dst (I64Load32U src mem) mem))
-(Move [6] dst src mem) =>
-	(I64Store16 [4] dst (I64Load16U [4] src mem)
-		(I64Store32 dst (I64Load32U src mem) mem))
-(Move [7] dst src mem) =>
-	(I64Store32 [3] dst (I64Load32U [3] src mem)
-		(I64Store32 dst (I64Load32U src mem) mem))
-(Move [s] dst src mem) && s > 8 && s < 16 =>
-	(I64Store [s-8] dst (I64Load [s-8] src mem)
-		(I64Store dst (I64Load src mem) mem))
-
-// Adjust moves to be a multiple of 16 bytes.
-(Move [s] dst src mem)
-	&& s > 16 && s%16 != 0 && s%16 <= 8 =>
-	(Move [s-s%16]
-		(OffPtr <dst.Type> dst [s%16])
-		(OffPtr <src.Type> src [s%16])
-		(I64Store dst (I64Load src mem) mem))
-(Move [s] dst src mem)
-	&& s > 16 && s%16 != 0 && s%16 > 8 =>
-	(Move [s-s%16]
-		(OffPtr <dst.Type> dst [s%16])
-		(OffPtr <src.Type> src [s%16])
-		(I64Store [8] dst (I64Load [8] src mem)
-			(I64Store dst (I64Load src mem) mem)))
-
-// Large copying uses helper.
-(Move [s] dst src mem) && s%8 == 0 && logLargeCopy(v, s) =>
-	(LoweredMove [s/8] dst src mem)
-
-// Lowering Zero instructions
-(Zero [0] _ mem) => mem
-(Zero [1] destptr mem) => (I64Store8 destptr (I64Const [0]) mem)
-(Zero [2] destptr mem) => (I64Store16 destptr (I64Const [0]) mem)
-(Zero [4] destptr mem) => (I64Store32 destptr (I64Const [0]) mem)
-(Zero [8] destptr mem) => (I64Store destptr (I64Const [0]) mem)
-
-(Zero [3] destptr mem) =>
-	(I64Store8 [2] destptr (I64Const [0])
-		(I64Store16 destptr (I64Const [0]) mem))
-(Zero [5] destptr mem) =>
-	(I64Store8 [4] destptr (I64Const [0])
-		(I64Store32 destptr (I64Const [0]) mem))
-(Zero [6] destptr mem) =>
-	(I64Store16 [4] destptr (I64Const [0])
-		(I64Store32 destptr (I64Const [0]) mem))
-(Zero [7] destptr mem) =>
-	(I64Store32 [3] destptr (I64Const [0])
-		(I64Store32 destptr (I64Const [0]) mem))
-
-// Strip off any fractional word zeroing.
-(Zero [s] destptr mem) && s%8 != 0 && s > 8 =>
-	(Zero [s-s%8] (OffPtr <destptr.Type> destptr [s%8])
-		(I64Store destptr (I64Const [0]) mem))
-
-// Zero small numbers of words directly.
-(Zero [16] destptr mem) =>
-	(I64Store [8] destptr (I64Const [0])
-		(I64Store destptr (I64Const [0]) mem))
-(Zero [24] destptr mem) =>
-	(I64Store [16] destptr (I64Const [0])
-		(I64Store [8] destptr (I64Const [0])
-			(I64Store destptr (I64Const [0]) mem)))
-(Zero [32] destptr mem) =>
-	(I64Store [24] destptr (I64Const [0])
-		(I64Store [16] destptr (I64Const [0])
-			(I64Store [8] destptr (I64Const [0])
-				(I64Store destptr (I64Const [0]) mem))))
-
-// Large zeroing uses helper.
-(Zero [s] destptr mem) && s%8 == 0 && s > 32 =>
-	(LoweredZero [s/8] destptr mem)
-
-// Lowering constants
-(Const64 ...) => (I64Const ...)
-(Const(32|16|8) [c]) => (I64Const [int64(c)])
-(Const(64|32)F ...) => (F(64|32)Const ...)
-(ConstNil) => (I64Const [0])
-(ConstBool [c]) => (I64Const [b2i(c)])
-
-// Lowering calls
-(StaticCall ...) => (LoweredStaticCall ...)
-(ClosureCall ...) => (LoweredClosureCall ...)
-(InterCall ...) => (LoweredInterCall ...)
-(TailCall ...) => (LoweredTailCall ...)
-
-// Miscellaneous
-(Convert ...) => (LoweredConvert ...)
-(IsNonNil p) => (I64Eqz (I64Eqz p))
-(IsInBounds ...) => (I64LtU ...)
-(IsSliceInBounds ...) => (I64LeU ...)
-(NilCheck ...) => (LoweredNilCheck ...)
-(GetClosurePtr ...) => (LoweredGetClosurePtr ...)
-(GetCallerPC ...) => (LoweredGetCallerPC ...)
-(GetCallerSP ...) => (LoweredGetCallerSP ...)
-(Addr {sym} base) => (LoweredAddr {sym} [0] base)
-(LocalAddr {sym} base _) => (LoweredAddr {sym} base)
-
-// Write barrier.
-(WB ...) => (LoweredWB ...)
-
-// --- Intrinsics ---
-(Sqrt ...) => (F64Sqrt ...)
-(Trunc ...) => (F64Trunc ...)
-(Ceil ...) => (F64Ceil ...)
-(Floor ...) => (F64Floor ...)
-(RoundToEven ...) => (F64Nearest ...)
-(Abs ...) => (F64Abs ...)
-(Copysign ...) => (F64Copysign ...)
-
-(Sqrt32 ...) => (F32Sqrt ...)
-
-(Ctz64 ...) => (I64Ctz ...)
-(Ctz32 x) => (I64Ctz (I64Or x (I64Const [0x100000000])))
-(Ctz16 x) => (I64Ctz (I64Or x (I64Const [0x10000])))
-(Ctz8  x) => (I64Ctz (I64Or x (I64Const [0x100])))
-
-(Ctz(64|32|16|8)NonZero ...) => (I64Ctz ...)
-
-(BitLen64 x) => (I64Sub (I64Const [64]) (I64Clz x))
-
-(PopCount64 ...) => (I64Popcnt ...)
-(PopCount32 x) => (I64Popcnt (ZeroExt32to64 x))
-(PopCount16 x) => (I64Popcnt (ZeroExt16to64 x))
-(PopCount8  x) => (I64Popcnt (ZeroExt8to64  x))
-
-(CondSelect ...) => (Select ...)
-
-// --- Optimizations ---
-(I64Add (I64Const [x]) (I64Const [y])) => (I64Const [x + y])
-(I64Mul (I64Const [x]) (I64Const [y])) => (I64Const [x * y])
-(I64And (I64Const [x]) (I64Const [y])) => (I64Const [x & y])
-(I64Or  (I64Const [x]) (I64Const [y])) => (I64Const [x | y])
-(I64Xor (I64Const [x]) (I64Const [y])) => (I64Const [x ^ y])
-(F64Add (F64Const [x]) (F64Const [y])) => (F64Const [x + y])
-(F64Mul (F64Const [x]) (F64Const [y])) && !math.IsNaN(x * y) => (F64Const [x * y])
-(I64Eq  (I64Const [x]) (I64Const [y])) && x == y => (I64Const [1])
-(I64Eq  (I64Const [x]) (I64Const [y])) && x != y => (I64Const [0])
-(I64Ne  (I64Const [x]) (I64Const [y])) && x == y => (I64Const [0])
-(I64Ne  (I64Const [x]) (I64Const [y])) && x != y => (I64Const [1])
-
-(I64Shl (I64Const [x]) (I64Const [y])) => (I64Const [x << uint64(y)])
-(I64ShrU (I64Const [x]) (I64Const [y])) => (I64Const [int64(uint64(x) >> uint64(y))])
-(I64ShrS (I64Const [x]) (I64Const [y])) => (I64Const [x >> uint64(y)])
-
-// TODO: declare these operations as commutative and get rid of these rules?
-(I64Add (I64Const [x]) y) && y.Op != OpWasmI64Const => (I64Add y (I64Const [x]))
-(I64Mul (I64Const [x]) y) && y.Op != OpWasmI64Const => (I64Mul y (I64Const [x]))
-(I64And (I64Const [x]) y) && y.Op != OpWasmI64Const => (I64And y (I64Const [x]))
-(I64Or  (I64Const [x]) y) && y.Op != OpWasmI64Const => (I64Or  y (I64Const [x]))
-(I64Xor (I64Const [x]) y) && y.Op != OpWasmI64Const => (I64Xor y (I64Const [x]))
-(F64Add (F64Const [x]) y) && y.Op != OpWasmF64Const => (F64Add y (F64Const [x]))
-(F64Mul (F64Const [x]) y) && y.Op != OpWasmF64Const => (F64Mul y (F64Const [x]))
-(I64Eq  (I64Const [x]) y) && y.Op != OpWasmI64Const => (I64Eq y  (I64Const [x]))
-(I64Ne  (I64Const [x]) y) && y.Op != OpWasmI64Const => (I64Ne y  (I64Const [x]))
-
-(I64Eq x (I64Const [0])) => (I64Eqz x)
-(I64LtU (I64Const [0]) x) => (I64Eqz (I64Eqz x))
-(I64LeU x (I64Const [0])) => (I64Eqz x)
-(I64LtU x (I64Const [1])) => (I64Eqz x)
-(I64LeU (I64Const [1]) x) => (I64Eqz (I64Eqz x))
-(I64Ne x (I64Const [0])) => (I64Eqz (I64Eqz x))
-
-(I64Add x (I64Const [y])) => (I64AddConst [y] x)
-(I64AddConst [0] x) => x
-(I64Eqz (I64Eqz (I64Eqz x))) => (I64Eqz x)
-
-// folding offset into load/store
-((I64Load|I64Load32U|I64Load32S|I64Load16U|I64Load16S|I64Load8U|I64Load8S) [off] (I64AddConst [off2] ptr) mem)
-	&& isU32Bit(off+off2) =>
-	((I64Load|I64Load32U|I64Load32S|I64Load16U|I64Load16S|I64Load8U|I64Load8S) [off+off2] ptr mem)
-
-((I64Store|I64Store32|I64Store16|I64Store8) [off] (I64AddConst [off2] ptr) val mem)
-	&& isU32Bit(off+off2) =>
-	((I64Store|I64Store32|I64Store16|I64Store8) [off+off2] ptr val mem)
-
-// folding offset into address
-(I64AddConst [off] (LoweredAddr {sym} [off2] base)) && isU32Bit(off+int64(off2)) =>
-	(LoweredAddr {sym} [int32(off)+off2] base)
-(I64AddConst [off] x:(SP)) && isU32Bit(off) => (LoweredAddr [int32(off)] x) // so it is rematerializeable
-
-// transforming readonly globals into constants
-(I64Load [off] (LoweredAddr {sym} [off2] (SB)) _) && symIsRO(sym) && isU32Bit(off+int64(off2)) => (I64Const [int64(read64(sym, off+int64(off2), config.ctxt.Arch.ByteOrder))])
-(I64Load32U [off] (LoweredAddr {sym} [off2] (SB)) _) && symIsRO(sym) && isU32Bit(off+int64(off2)) => (I64Const [int64(read32(sym, off+int64(off2), config.ctxt.Arch.ByteOrder))])
-(I64Load16U [off] (LoweredAddr {sym} [off2] (SB)) _) && symIsRO(sym) && isU32Bit(off+int64(off2)) => (I64Const [int64(read16(sym, off+int64(off2), config.ctxt.Arch.ByteOrder))])
-(I64Load8U [off] (LoweredAddr {sym} [off2] (SB)) _) && symIsRO(sym) && isU32Bit(off+int64(off2)) => (I64Const [int64(read8(sym, off+int64(off2)))])
diff --git a/src/cmd/compile/internal/ssa/gen/WasmOps.go b/src/cmd/compile/internal/ssa/gen/WasmOps.go
deleted file mode 100644
index edfba4e..0000000
--- a/src/cmd/compile/internal/ssa/gen/WasmOps.go
+++ /dev/null
@@ -1,280 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build ignore
-// +build ignore
-
-package main
-
-import "strings"
-
-var regNamesWasm = []string{
-	"R0",
-	"R1",
-	"R2",
-	"R3",
-	"R4",
-	"R5",
-	"R6",
-	"R7",
-	"R8",
-	"R9",
-	"R10",
-	"R11",
-	"R12",
-	"R13",
-	"R14",
-	"R15",
-
-	"F0",
-	"F1",
-	"F2",
-	"F3",
-	"F4",
-	"F5",
-	"F6",
-	"F7",
-	"F8",
-	"F9",
-	"F10",
-	"F11",
-	"F12",
-	"F13",
-	"F14",
-	"F15",
-
-	"F16",
-	"F17",
-	"F18",
-	"F19",
-	"F20",
-	"F21",
-	"F22",
-	"F23",
-	"F24",
-	"F25",
-	"F26",
-	"F27",
-	"F28",
-	"F29",
-	"F30",
-	"F31",
-
-	"SP",
-	"g",
-
-	// pseudo-registers
-	"SB",
-}
-
-func init() {
-	// Make map from reg names to reg integers.
-	if len(regNamesWasm) > 64 {
-		panic("too many registers")
-	}
-	num := map[string]int{}
-	for i, name := range regNamesWasm {
-		num[name] = i
-	}
-	buildReg := func(s string) regMask {
-		m := regMask(0)
-		for _, r := range strings.Split(s, " ") {
-			if n, ok := num[r]; ok {
-				m |= regMask(1) << uint(n)
-				continue
-			}
-			panic("register " + r + " not found")
-		}
-		return m
-	}
-
-	var (
-		gp     = buildReg("R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15")
-		fp32   = buildReg("F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15")
-		fp64   = buildReg("F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31")
-		gpsp   = gp | buildReg("SP")
-		gpspsb = gpsp | buildReg("SB")
-		// The "registers", which are actually local variables, can get clobbered
-		// if we're switching goroutines, because it unwinds the WebAssembly stack.
-		callerSave = gp | fp32 | fp64 | buildReg("g")
-	)
-
-	// Common regInfo
-	var (
-		gp01      = regInfo{inputs: nil, outputs: []regMask{gp}}
-		gp11      = regInfo{inputs: []regMask{gpsp}, outputs: []regMask{gp}}
-		gp21      = regInfo{inputs: []regMask{gpsp, gpsp}, outputs: []regMask{gp}}
-		gp31      = regInfo{inputs: []regMask{gpsp, gpsp, gpsp}, outputs: []regMask{gp}}
-		fp32_01   = regInfo{inputs: nil, outputs: []regMask{fp32}}
-		fp32_11   = regInfo{inputs: []regMask{fp32}, outputs: []regMask{fp32}}
-		fp32_21   = regInfo{inputs: []regMask{fp32, fp32}, outputs: []regMask{fp32}}
-		fp32_21gp = regInfo{inputs: []regMask{fp32, fp32}, outputs: []regMask{gp}}
-		fp64_01   = regInfo{inputs: nil, outputs: []regMask{fp64}}
-		fp64_11   = regInfo{inputs: []regMask{fp64}, outputs: []regMask{fp64}}
-		fp64_21   = regInfo{inputs: []regMask{fp64, fp64}, outputs: []regMask{fp64}}
-		fp64_21gp = regInfo{inputs: []regMask{fp64, fp64}, outputs: []regMask{gp}}
-		gpload    = regInfo{inputs: []regMask{gpspsb, 0}, outputs: []regMask{gp}}
-		gpstore   = regInfo{inputs: []regMask{gpspsb, gpsp, 0}}
-		fp32load  = regInfo{inputs: []regMask{gpspsb, 0}, outputs: []regMask{fp32}}
-		fp32store = regInfo{inputs: []regMask{gpspsb, fp32, 0}}
-		fp64load  = regInfo{inputs: []regMask{gpspsb, 0}, outputs: []regMask{fp64}}
-		fp64store = regInfo{inputs: []regMask{gpspsb, fp64, 0}}
-	)
-
-	var WasmOps = []opData{
-		{name: "LoweredStaticCall", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", call: true},                                // call static function aux.(*obj.LSym). arg0=mem, auxint=argsize, returns mem
-		{name: "LoweredTailCall", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "CallOff", call: true, tailCall: true},                  // tail call static function aux.(*obj.LSym). arg0=mem, auxint=argsize, returns mem
-		{name: "LoweredClosureCall", argLength: 3, reg: regInfo{inputs: []regMask{gp, gp, 0}, clobbers: callerSave}, aux: "CallOff", call: true}, // call function via closure. arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem
-		{name: "LoweredInterCall", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "CallOff", call: true},          // call fn by pointer. arg0=codeptr, arg1=mem, auxint=argsize, returns mem
-
-		{name: "LoweredAddr", argLength: 1, reg: gp11, aux: "SymOff", rematerializeable: true, symEffect: "Addr"}, // returns base+aux+auxint, arg0=base
-		{name: "LoweredMove", argLength: 3, reg: regInfo{inputs: []regMask{gp, gp}}, aux: "Int64"},                // large move. arg0=dst, arg1=src, arg2=mem, auxint=len/8, returns mem
-		{name: "LoweredZero", argLength: 2, reg: regInfo{inputs: []regMask{gp}}, aux: "Int64"},                    // large zeroing. arg0=start, arg1=mem, auxint=len/8, returns mem
-
-		{name: "LoweredGetClosurePtr", reg: gp01},                                                                          // returns wasm.REG_CTXT, the closure pointer
-		{name: "LoweredGetCallerPC", reg: gp01, rematerializeable: true},                                                   // returns the PC of the caller of the current function
-		{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},                                                   // returns the SP of the caller of the current function
-		{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gp}}, nilCheck: true, faultOnNilArg0: true}, // panic if arg0 is nil. arg1=mem
-		{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{gp, gp}}, aux: "Sym", symEffect: "None"},          // invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
-
-		// LoweredConvert converts between pointers and integers.
-		// We have a special op for this so as to not confuse GCCallOff
-		// (particularly stack maps). It takes a memory arg so it
-		// gets correctly ordered with respect to GC safepoints.
-		// arg0=ptr/int arg1=mem, output=int/ptr
-		//
-		// TODO(neelance): LoweredConvert should not be necessary any more, since OpConvert does not need to be lowered any more (CL 108496).
-		{name: "LoweredConvert", argLength: 2, reg: regInfo{inputs: []regMask{gp}, outputs: []regMask{gp}}},
-
-		// The following are native WebAssembly instructions, see https://webassembly.github.io/spec/core/syntax/instructions.html
-
-		{name: "Select", asm: "Select", argLength: 3, reg: gp31}, // returns arg0 if arg2 != 0, otherwise returns arg1
-
-		{name: "I64Load8U", asm: "I64Load8U", argLength: 2, reg: gpload, aux: "Int64", typ: "UInt8"},    // read unsigned 8-bit integer from address arg0+aux, arg1=mem
-		{name: "I64Load8S", asm: "I64Load8S", argLength: 2, reg: gpload, aux: "Int64", typ: "Int8"},     // read signed 8-bit integer from address arg0+aux, arg1=mem
-		{name: "I64Load16U", asm: "I64Load16U", argLength: 2, reg: gpload, aux: "Int64", typ: "UInt16"}, // read unsigned 16-bit integer from address arg0+aux, arg1=mem
-		{name: "I64Load16S", asm: "I64Load16S", argLength: 2, reg: gpload, aux: "Int64", typ: "Int16"},  // read signed 16-bit integer from address arg0+aux, arg1=mem
-		{name: "I64Load32U", asm: "I64Load32U", argLength: 2, reg: gpload, aux: "Int64", typ: "UInt32"}, // read unsigned 32-bit integer from address arg0+aux, arg1=mem
-		{name: "I64Load32S", asm: "I64Load32S", argLength: 2, reg: gpload, aux: "Int64", typ: "Int32"},  // read signed 32-bit integer from address arg0+aux, arg1=mem
-		{name: "I64Load", asm: "I64Load", argLength: 2, reg: gpload, aux: "Int64", typ: "UInt64"},       // read 64-bit integer from address arg0+aux, arg1=mem
-		{name: "I64Store8", asm: "I64Store8", argLength: 3, reg: gpstore, aux: "Int64", typ: "Mem"},     // store 8-bit integer arg1 at address arg0+aux, arg2=mem, returns mem
-		{name: "I64Store16", asm: "I64Store16", argLength: 3, reg: gpstore, aux: "Int64", typ: "Mem"},   // store 16-bit integer arg1 at address arg0+aux, arg2=mem, returns mem
-		{name: "I64Store32", asm: "I64Store32", argLength: 3, reg: gpstore, aux: "Int64", typ: "Mem"},   // store 32-bit integer arg1 at address arg0+aux, arg2=mem, returns mem
-		{name: "I64Store", asm: "I64Store", argLength: 3, reg: gpstore, aux: "Int64", typ: "Mem"},       // store 64-bit integer arg1 at address arg0+aux, arg2=mem, returns mem
-
-		{name: "F32Load", asm: "F32Load", argLength: 2, reg: fp32load, aux: "Int64", typ: "Float32"}, // read 32-bit float from address arg0+aux, arg1=mem
-		{name: "F64Load", asm: "F64Load", argLength: 2, reg: fp64load, aux: "Int64", typ: "Float64"}, // read 64-bit float from address arg0+aux, arg1=mem
-		{name: "F32Store", asm: "F32Store", argLength: 3, reg: fp32store, aux: "Int64", typ: "Mem"},  // store 32-bit float arg1 at address arg0+aux, arg2=mem, returns mem
-		{name: "F64Store", asm: "F64Store", argLength: 3, reg: fp64store, aux: "Int64", typ: "Mem"},  // store 64-bit float arg1 at address arg0+aux, arg2=mem, returns mem
-
-		{name: "I64Const", reg: gp01, aux: "Int64", rematerializeable: true, typ: "Int64"},        // returns the constant integer aux
-		{name: "F32Const", reg: fp32_01, aux: "Float32", rematerializeable: true, typ: "Float32"}, // returns the constant float aux
-		{name: "F64Const", reg: fp64_01, aux: "Float64", rematerializeable: true, typ: "Float64"}, // returns the constant float aux
-
-		{name: "I64Eqz", asm: "I64Eqz", argLength: 1, reg: gp11, typ: "Bool"}, // arg0 == 0
-		{name: "I64Eq", asm: "I64Eq", argLength: 2, reg: gp21, typ: "Bool"},   // arg0 == arg1
-		{name: "I64Ne", asm: "I64Ne", argLength: 2, reg: gp21, typ: "Bool"},   // arg0 != arg1
-		{name: "I64LtS", asm: "I64LtS", argLength: 2, reg: gp21, typ: "Bool"}, // arg0 < arg1 (signed)
-		{name: "I64LtU", asm: "I64LtU", argLength: 2, reg: gp21, typ: "Bool"}, // arg0 < arg1 (unsigned)
-		{name: "I64GtS", asm: "I64GtS", argLength: 2, reg: gp21, typ: "Bool"}, // arg0 > arg1 (signed)
-		{name: "I64GtU", asm: "I64GtU", argLength: 2, reg: gp21, typ: "Bool"}, // arg0 > arg1 (unsigned)
-		{name: "I64LeS", asm: "I64LeS", argLength: 2, reg: gp21, typ: "Bool"}, // arg0 <= arg1 (signed)
-		{name: "I64LeU", asm: "I64LeU", argLength: 2, reg: gp21, typ: "Bool"}, // arg0 <= arg1 (unsigned)
-		{name: "I64GeS", asm: "I64GeS", argLength: 2, reg: gp21, typ: "Bool"}, // arg0 >= arg1 (signed)
-		{name: "I64GeU", asm: "I64GeU", argLength: 2, reg: gp21, typ: "Bool"}, // arg0 >= arg1 (unsigned)
-
-		{name: "F32Eq", asm: "F32Eq", argLength: 2, reg: fp32_21gp, typ: "Bool"}, // arg0 == arg1
-		{name: "F32Ne", asm: "F32Ne", argLength: 2, reg: fp32_21gp, typ: "Bool"}, // arg0 != arg1
-		{name: "F32Lt", asm: "F32Lt", argLength: 2, reg: fp32_21gp, typ: "Bool"}, // arg0 < arg1
-		{name: "F32Gt", asm: "F32Gt", argLength: 2, reg: fp32_21gp, typ: "Bool"}, // arg0 > arg1
-		{name: "F32Le", asm: "F32Le", argLength: 2, reg: fp32_21gp, typ: "Bool"}, // arg0 <= arg1
-		{name: "F32Ge", asm: "F32Ge", argLength: 2, reg: fp32_21gp, typ: "Bool"}, // arg0 >= arg1
-
-		{name: "F64Eq", asm: "F64Eq", argLength: 2, reg: fp64_21gp, typ: "Bool"}, // arg0 == arg1
-		{name: "F64Ne", asm: "F64Ne", argLength: 2, reg: fp64_21gp, typ: "Bool"}, // arg0 != arg1
-		{name: "F64Lt", asm: "F64Lt", argLength: 2, reg: fp64_21gp, typ: "Bool"}, // arg0 < arg1
-		{name: "F64Gt", asm: "F64Gt", argLength: 2, reg: fp64_21gp, typ: "Bool"}, // arg0 > arg1
-		{name: "F64Le", asm: "F64Le", argLength: 2, reg: fp64_21gp, typ: "Bool"}, // arg0 <= arg1
-		{name: "F64Ge", asm: "F64Ge", argLength: 2, reg: fp64_21gp, typ: "Bool"}, // arg0 >= arg1
-
-		{name: "I64Add", asm: "I64Add", argLength: 2, reg: gp21, typ: "Int64"},                    // arg0 + arg1
-		{name: "I64AddConst", asm: "I64Add", argLength: 1, reg: gp11, aux: "Int64", typ: "Int64"}, // arg0 + aux
-		{name: "I64Sub", asm: "I64Sub", argLength: 2, reg: gp21, typ: "Int64"},                    // arg0 - arg1
-		{name: "I64Mul", asm: "I64Mul", argLength: 2, reg: gp21, typ: "Int64"},                    // arg0 * arg1
-		{name: "I64DivS", asm: "I64DivS", argLength: 2, reg: gp21, typ: "Int64"},                  // arg0 / arg1 (signed)
-		{name: "I64DivU", asm: "I64DivU", argLength: 2, reg: gp21, typ: "Int64"},                  // arg0 / arg1 (unsigned)
-		{name: "I64RemS", asm: "I64RemS", argLength: 2, reg: gp21, typ: "Int64"},                  // arg0 % arg1 (signed)
-		{name: "I64RemU", asm: "I64RemU", argLength: 2, reg: gp21, typ: "Int64"},                  // arg0 % arg1 (unsigned)
-		{name: "I64And", asm: "I64And", argLength: 2, reg: gp21, typ: "Int64"},                    // arg0 & arg1
-		{name: "I64Or", asm: "I64Or", argLength: 2, reg: gp21, typ: "Int64"},                      // arg0 | arg1
-		{name: "I64Xor", asm: "I64Xor", argLength: 2, reg: gp21, typ: "Int64"},                    // arg0 ^ arg1
-		{name: "I64Shl", asm: "I64Shl", argLength: 2, reg: gp21, typ: "Int64"},                    // arg0 << (arg1 % 64)
-		{name: "I64ShrS", asm: "I64ShrS", argLength: 2, reg: gp21, typ: "Int64"},                  // arg0 >> (arg1 % 64) (signed)
-		{name: "I64ShrU", asm: "I64ShrU", argLength: 2, reg: gp21, typ: "Int64"},                  // arg0 >> (arg1 % 64) (unsigned)
-
-		{name: "F32Neg", asm: "F32Neg", argLength: 1, reg: fp32_11, typ: "Float32"}, // -arg0
-		{name: "F32Add", asm: "F32Add", argLength: 2, reg: fp32_21, typ: "Float32"}, // arg0 + arg1
-		{name: "F32Sub", asm: "F32Sub", argLength: 2, reg: fp32_21, typ: "Float32"}, // arg0 - arg1
-		{name: "F32Mul", asm: "F32Mul", argLength: 2, reg: fp32_21, typ: "Float32"}, // arg0 * arg1
-		{name: "F32Div", asm: "F32Div", argLength: 2, reg: fp32_21, typ: "Float32"}, // arg0 / arg1
-
-		{name: "F64Neg", asm: "F64Neg", argLength: 1, reg: fp64_11, typ: "Float64"}, // -arg0
-		{name: "F64Add", asm: "F64Add", argLength: 2, reg: fp64_21, typ: "Float64"}, // arg0 + arg1
-		{name: "F64Sub", asm: "F64Sub", argLength: 2, reg: fp64_21, typ: "Float64"}, // arg0 - arg1
-		{name: "F64Mul", asm: "F64Mul", argLength: 2, reg: fp64_21, typ: "Float64"}, // arg0 * arg1
-		{name: "F64Div", asm: "F64Div", argLength: 2, reg: fp64_21, typ: "Float64"}, // arg0 / arg1
-
-		{name: "I64TruncSatF64S", asm: "I64TruncSatF64S", argLength: 1, reg: regInfo{inputs: []regMask{fp64}, outputs: []regMask{gp}}, typ: "Int64"}, // truncates the float arg0 to a signed integer (saturating)
-		{name: "I64TruncSatF64U", asm: "I64TruncSatF64U", argLength: 1, reg: regInfo{inputs: []regMask{fp64}, outputs: []regMask{gp}}, typ: "Int64"}, // truncates the float arg0 to an unsigned integer (saturating)
-		{name: "I64TruncSatF32S", asm: "I64TruncSatF32S", argLength: 1, reg: regInfo{inputs: []regMask{fp32}, outputs: []regMask{gp}}, typ: "Int64"}, // truncates the float arg0 to a signed integer (saturating)
-		{name: "I64TruncSatF32U", asm: "I64TruncSatF32U", argLength: 1, reg: regInfo{inputs: []regMask{fp32}, outputs: []regMask{gp}}, typ: "Int64"}, // truncates the float arg0 to an unsigned integer (saturating)
-		{name: "F32ConvertI64S", asm: "F32ConvertI64S", argLength: 1, reg: regInfo{inputs: []regMask{gp}, outputs: []regMask{fp32}}, typ: "Float32"}, // converts the signed integer arg0 to a float
-		{name: "F32ConvertI64U", asm: "F32ConvertI64U", argLength: 1, reg: regInfo{inputs: []regMask{gp}, outputs: []regMask{fp32}}, typ: "Float32"}, // converts the unsigned integer arg0 to a float
-		{name: "F64ConvertI64S", asm: "F64ConvertI64S", argLength: 1, reg: regInfo{inputs: []regMask{gp}, outputs: []regMask{fp64}}, typ: "Float64"}, // converts the signed integer arg0 to a float
-		{name: "F64ConvertI64U", asm: "F64ConvertI64U", argLength: 1, reg: regInfo{inputs: []regMask{gp}, outputs: []regMask{fp64}}, typ: "Float64"}, // converts the unsigned integer arg0 to a float
-		{name: "F32DemoteF64", asm: "F32DemoteF64", argLength: 1, reg: regInfo{inputs: []regMask{fp64}, outputs: []regMask{fp32}}, typ: "Float32"},
-		{name: "F64PromoteF32", asm: "F64PromoteF32", argLength: 1, reg: regInfo{inputs: []regMask{fp32}, outputs: []regMask{fp64}}, typ: "Float64"},
-
-		{name: "I64Extend8S", asm: "I64Extend8S", argLength: 1, reg: gp11, typ: "Int64"},   // sign-extend arg0 from 8 to 64 bit
-		{name: "I64Extend16S", asm: "I64Extend16S", argLength: 1, reg: gp11, typ: "Int64"}, // sign-extend arg0 from 16 to 64 bit
-		{name: "I64Extend32S", asm: "I64Extend32S", argLength: 1, reg: gp11, typ: "Int64"}, // sign-extend arg0 from 32 to 64 bit
-
-		{name: "F32Sqrt", asm: "F32Sqrt", argLength: 1, reg: fp32_11, typ: "Float32"},         // sqrt(arg0)
-		{name: "F32Trunc", asm: "F32Trunc", argLength: 1, reg: fp32_11, typ: "Float32"},       // trunc(arg0)
-		{name: "F32Ceil", asm: "F32Ceil", argLength: 1, reg: fp32_11, typ: "Float32"},         // ceil(arg0)
-		{name: "F32Floor", asm: "F32Floor", argLength: 1, reg: fp32_11, typ: "Float32"},       // floor(arg0)
-		{name: "F32Nearest", asm: "F32Nearest", argLength: 1, reg: fp32_11, typ: "Float32"},   // round(arg0)
-		{name: "F32Abs", asm: "F32Abs", argLength: 1, reg: fp32_11, typ: "Float32"},           // abs(arg0)
-		{name: "F32Copysign", asm: "F32Copysign", argLength: 2, reg: fp32_21, typ: "Float32"}, // copysign(arg0, arg1)
-
-		{name: "F64Sqrt", asm: "F64Sqrt", argLength: 1, reg: fp64_11, typ: "Float64"},         // sqrt(arg0)
-		{name: "F64Trunc", asm: "F64Trunc", argLength: 1, reg: fp64_11, typ: "Float64"},       // trunc(arg0)
-		{name: "F64Ceil", asm: "F64Ceil", argLength: 1, reg: fp64_11, typ: "Float64"},         // ceil(arg0)
-		{name: "F64Floor", asm: "F64Floor", argLength: 1, reg: fp64_11, typ: "Float64"},       // floor(arg0)
-		{name: "F64Nearest", asm: "F64Nearest", argLength: 1, reg: fp64_11, typ: "Float64"},   // round(arg0)
-		{name: "F64Abs", asm: "F64Abs", argLength: 1, reg: fp64_11, typ: "Float64"},           // abs(arg0)
-		{name: "F64Copysign", asm: "F64Copysign", argLength: 2, reg: fp64_21, typ: "Float64"}, // copysign(arg0, arg1)
-
-		{name: "I64Ctz", asm: "I64Ctz", argLength: 1, reg: gp11, typ: "Int64"},       // ctz(arg0)
-		{name: "I64Clz", asm: "I64Clz", argLength: 1, reg: gp11, typ: "Int64"},       // clz(arg0)
-		{name: "I32Rotl", asm: "I32Rotl", argLength: 2, reg: gp21, typ: "Int32"},     // rotl(arg0, arg1)
-		{name: "I64Rotl", asm: "I64Rotl", argLength: 2, reg: gp21, typ: "Int64"},     // rotl(arg0, arg1)
-		{name: "I64Popcnt", asm: "I64Popcnt", argLength: 1, reg: gp11, typ: "Int64"}, // popcnt(arg0)
-	}
-
-	archs = append(archs, arch{
-		name:            "Wasm",
-		pkg:             "cmd/internal/obj/wasm",
-		genfile:         "../../wasm/ssa.go",
-		ops:             WasmOps,
-		blocks:          nil,
-		regnames:        regNamesWasm,
-		gpregmask:       gp,
-		fpregmask:       fp32 | fp64,
-		fp32regmask:     fp32,
-		fp64regmask:     fp64,
-		framepointerreg: -1, // not used
-		linkreg:         -1, // not used
-	})
-}
diff --git a/src/cmd/compile/internal/ssa/gen/cover.bash b/src/cmd/compile/internal/ssa/gen/cover.bash
deleted file mode 100755
index 6c860fc..0000000
--- a/src/cmd/compile/internal/ssa/gen/cover.bash
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env bash 
-# Copyright 2020 The Go Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file.
-
-# A quick and dirty way to obtain code coverage from rulegen's main func. For
-# example:
-#
-#     ./cover.bash && go tool cover -html=cover.out
-#
-# This script is needed to set up a temporary test file, so that we don't break
-# regular 'go run *.go' usage to run the generator.
-
-cat >main_test.go <<-EOF
-	// +build ignore
-
-	package main
-
-	import "testing"
-
-	func TestCoverage(t *testing.T) { main() }
-EOF
-
-go test -run='^TestCoverage$' -coverprofile=cover.out "$@" *.go
-
-rm -f main_test.go
diff --git a/src/cmd/compile/internal/ssa/gen/dec64.rules b/src/cmd/compile/internal/ssa/gen/dec64.rules
deleted file mode 100644
index b0f10d0..0000000
--- a/src/cmd/compile/internal/ssa/gen/dec64.rules
+++ /dev/null
@@ -1,396 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file contains rules to decompose [u]int64 types on 32-bit
-// architectures. These rules work together with the decomposeBuiltIn
-// pass which handles phis of these typ.
-
-(Int64Hi (Int64Make hi _)) => hi
-(Int64Lo (Int64Make _ lo)) => lo
-
-(Load <t> ptr mem) && is64BitInt(t) && !config.BigEndian && t.IsSigned() =>
-	(Int64Make
-		(Load <typ.Int32> (OffPtr <typ.Int32Ptr> [4] ptr) mem)
-		(Load <typ.UInt32> ptr mem))
-
-(Load <t> ptr mem) && is64BitInt(t) && !config.BigEndian && !t.IsSigned() =>
-	(Int64Make
-		(Load <typ.UInt32> (OffPtr <typ.UInt32Ptr> [4] ptr) mem)
-		(Load <typ.UInt32> ptr mem))
-
-(Load <t> ptr mem) && is64BitInt(t) && config.BigEndian && t.IsSigned() =>
-	(Int64Make
-		(Load <typ.Int32> ptr mem)
-		(Load <typ.UInt32> (OffPtr <typ.UInt32Ptr> [4] ptr) mem))
-
-(Load <t> ptr mem) && is64BitInt(t) && config.BigEndian && !t.IsSigned() =>
-	(Int64Make
-		(Load <typ.UInt32> ptr mem)
-		(Load <typ.UInt32> (OffPtr <typ.UInt32Ptr> [4] ptr) mem))
-
-(Store {t} dst (Int64Make hi lo) mem) && t.Size() == 8 && !config.BigEndian =>
-	(Store {hi.Type}
-		(OffPtr <hi.Type.PtrTo()> [4] dst)
-		hi
-		(Store {lo.Type} dst lo mem))
-
-(Store {t} dst (Int64Make hi lo) mem) && t.Size() == 8 && config.BigEndian =>
-	(Store {lo.Type}
-		(OffPtr <lo.Type.PtrTo()> [4] dst)
-		lo
-		(Store {hi.Type} dst hi mem))
-
-// These are not enabled during decomposeBuiltin if late call expansion, but they are always enabled for softFloat
-(Arg {n} [off]) && is64BitInt(v.Type) && !config.BigEndian && v.Type.IsSigned() && !(b.Func.pass.name == "decompose builtin") =>
-  (Int64Make
-    (Arg <typ.Int32> {n} [off+4])
-    (Arg <typ.UInt32> {n} [off]))
-(Arg {n} [off]) && is64BitInt(v.Type) && !config.BigEndian && !v.Type.IsSigned() && !(b.Func.pass.name == "decompose builtin")  =>
-  (Int64Make
-    (Arg <typ.UInt32> {n} [off+4])
-    (Arg <typ.UInt32> {n} [off]))
-
-(Arg {n} [off]) && is64BitInt(v.Type) && config.BigEndian && v.Type.IsSigned() && !(b.Func.pass.name == "decompose builtin") =>
-  (Int64Make
-    (Arg <typ.Int32> {n} [off])
-    (Arg <typ.UInt32> {n} [off+4]))
-(Arg {n} [off]) && is64BitInt(v.Type) && config.BigEndian && !v.Type.IsSigned() && !(b.Func.pass.name == "decompose builtin") =>
-  (Int64Make
-    (Arg <typ.UInt32> {n} [off])
-    (Arg <typ.UInt32> {n} [off+4]))
-
-(Add64 x y) =>
-	(Int64Make
-		(Add32withcarry <typ.Int32>
-			(Int64Hi x)
-			(Int64Hi y)
-			(Select1 <types.TypeFlags> (Add32carry (Int64Lo x) (Int64Lo y))))
-		(Select0 <typ.UInt32> (Add32carry (Int64Lo x) (Int64Lo y))))
-
-(Sub64 x y) =>
-	(Int64Make
-		(Sub32withcarry <typ.Int32>
-			(Int64Hi x)
-			(Int64Hi y)
-			(Select1 <types.TypeFlags> (Sub32carry (Int64Lo x) (Int64Lo y))))
-		(Select0 <typ.UInt32> (Sub32carry (Int64Lo x) (Int64Lo y))))
-
-(Mul64 x y) =>
-	(Int64Make
-		(Add32 <typ.UInt32>
-			(Mul32 <typ.UInt32> (Int64Lo x) (Int64Hi y))
-			(Add32 <typ.UInt32>
-				(Mul32 <typ.UInt32> (Int64Hi x) (Int64Lo y))
-				(Select0 <typ.UInt32> (Mul32uhilo (Int64Lo x) (Int64Lo y)))))
-		(Select1 <typ.UInt32> (Mul32uhilo (Int64Lo x) (Int64Lo y))))
-
-(And64 x y) =>
-	(Int64Make
-		(And32 <typ.UInt32> (Int64Hi x) (Int64Hi y))
-		(And32 <typ.UInt32> (Int64Lo x) (Int64Lo y)))
-
-(Or64 x y) =>
-	(Int64Make
-		(Or32 <typ.UInt32> (Int64Hi x) (Int64Hi y))
-		(Or32 <typ.UInt32> (Int64Lo x) (Int64Lo y)))
-
-(Xor64 x y) =>
-	(Int64Make
-		(Xor32 <typ.UInt32> (Int64Hi x) (Int64Hi y))
-		(Xor32 <typ.UInt32> (Int64Lo x) (Int64Lo y)))
-
-(Neg64 <t> x) => (Sub64 (Const64 <t> [0]) x)
-
-(Com64 x) =>
-	(Int64Make
-		(Com32 <typ.UInt32> (Int64Hi x))
-		(Com32 <typ.UInt32> (Int64Lo x)))
-
-// Sadly, just because we know that x is non-zero,
-// we don't know whether either component is,
-// so just treat Ctz64NonZero the same as Ctz64.
-(Ctz64NonZero ...) => (Ctz64 ...)
-
-(Ctz64 x) =>
-	(Add32 <typ.UInt32>
-		(Ctz32 <typ.UInt32> (Int64Lo x))
-		(And32 <typ.UInt32>
-			(Com32 <typ.UInt32> (Zeromask (Int64Lo x)))
-			(Ctz32 <typ.UInt32> (Int64Hi x))))
-
-(BitLen64 x) =>
-	(Add32 <typ.Int>
-		(BitLen32 <typ.Int> (Int64Hi x))
-		(BitLen32 <typ.Int>
-			(Or32 <typ.UInt32>
-				(Int64Lo x)
-				(Zeromask (Int64Hi x)))))
-
-(Bswap64 x) =>
-	(Int64Make
-		(Bswap32 <typ.UInt32> (Int64Lo x))
-		(Bswap32 <typ.UInt32> (Int64Hi x)))
-
-(SignExt32to64 x) => (Int64Make (Signmask x) x)
-(SignExt16to64 x) => (SignExt32to64 (SignExt16to32 x))
-(SignExt8to64 x) => (SignExt32to64 (SignExt8to32 x))
-
-(ZeroExt32to64 x) => (Int64Make (Const32 <typ.UInt32> [0]) x)
-(ZeroExt16to64 x) => (ZeroExt32to64 (ZeroExt16to32 x))
-(ZeroExt8to64 x) => (ZeroExt32to64 (ZeroExt8to32 x))
-
-(Trunc64to32 (Int64Make _ lo)) => lo
-(Trunc64to16 (Int64Make _ lo)) => (Trunc32to16 lo)
-(Trunc64to8 (Int64Make _ lo)) => (Trunc32to8 lo)
-// Most general
-(Trunc64to32 x) => (Int64Lo x)
-(Trunc64to16 x) => (Trunc32to16 (Int64Lo x))
-(Trunc64to8 x) => (Trunc32to8 (Int64Lo x))
-
-(Lsh32x64 _ (Int64Make (Const32 [c]) _)) && c != 0 => (Const32 [0])
-(Rsh32x64 x (Int64Make (Const32 [c]) _)) && c != 0 => (Signmask x)
-(Rsh32Ux64 _ (Int64Make (Const32 [c]) _)) && c != 0 => (Const32 [0])
-(Lsh16x64 _ (Int64Make (Const32 [c]) _)) && c != 0 => (Const32 [0])
-(Rsh16x64 x (Int64Make (Const32 [c]) _)) && c != 0 => (Signmask (SignExt16to32 x))
-(Rsh16Ux64 _ (Int64Make (Const32 [c]) _)) && c != 0 => (Const32 [0])
-(Lsh8x64 _ (Int64Make (Const32 [c]) _)) && c != 0 => (Const32 [0])
-(Rsh8x64 x (Int64Make (Const32 [c]) _)) && c != 0 => (Signmask (SignExt8to32 x))
-(Rsh8Ux64 _ (Int64Make (Const32 [c]) _)) && c != 0 => (Const32 [0])
-
-(Lsh32x64 [c] x (Int64Make (Const32 [0]) lo)) => (Lsh32x32 [c] x lo)
-(Rsh32x64 [c] x (Int64Make (Const32 [0]) lo)) => (Rsh32x32 [c] x lo)
-(Rsh32Ux64 [c] x (Int64Make (Const32 [0]) lo)) => (Rsh32Ux32 [c] x lo)
-(Lsh16x64 [c] x (Int64Make (Const32 [0]) lo)) => (Lsh16x32 [c] x lo)
-(Rsh16x64 [c] x (Int64Make (Const32 [0]) lo)) => (Rsh16x32 [c] x lo)
-(Rsh16Ux64 [c] x (Int64Make (Const32 [0]) lo)) => (Rsh16Ux32 [c] x lo)
-(Lsh8x64 [c] x (Int64Make (Const32 [0]) lo)) => (Lsh8x32 [c] x lo)
-(Rsh8x64 [c] x (Int64Make (Const32 [0]) lo)) => (Rsh8x32 [c] x lo)
-(Rsh8Ux64 [c] x (Int64Make (Const32 [0]) lo)) => (Rsh8Ux32 [c] x lo)
-
-(Lsh64x64 _ (Int64Make (Const32 [c]) _)) && c != 0 => (Const64 [0])
-(Rsh64x64 x (Int64Make (Const32 [c]) _)) && c != 0 => (Int64Make (Signmask (Int64Hi x)) (Signmask (Int64Hi x)))
-(Rsh64Ux64 _ (Int64Make (Const32 [c]) _)) && c != 0 => (Const64 [0])
-
-(Lsh64x64 [c] x (Int64Make (Const32 [0]) lo)) => (Lsh64x32 [c] x lo)
-(Rsh64x64 [c] x (Int64Make (Const32 [0]) lo)) => (Rsh64x32 [c] x lo)
-(Rsh64Ux64 [c] x (Int64Make (Const32 [0]) lo)) => (Rsh64Ux32 [c] x lo)
-
-// turn x64 non-constant shifts to x32 shifts
-// if high 32-bit of the shift is nonzero, make a huge shift
-(Lsh64x64 x (Int64Make hi lo)) && hi.Op != OpConst32 =>
-       (Lsh64x32 x (Or32 <typ.UInt32> (Zeromask hi) lo))
-(Rsh64x64 x (Int64Make hi lo)) && hi.Op != OpConst32 =>
-       (Rsh64x32 x (Or32 <typ.UInt32> (Zeromask hi) lo))
-(Rsh64Ux64 x (Int64Make hi lo)) && hi.Op != OpConst32 =>
-       (Rsh64Ux32 x (Or32 <typ.UInt32> (Zeromask hi) lo))
-(Lsh32x64 x (Int64Make hi lo)) && hi.Op != OpConst32 =>
-       (Lsh32x32 x (Or32 <typ.UInt32> (Zeromask hi) lo))
-(Rsh32x64 x (Int64Make hi lo)) && hi.Op != OpConst32 =>
-       (Rsh32x32 x (Or32 <typ.UInt32> (Zeromask hi) lo))
-(Rsh32Ux64 x (Int64Make hi lo)) && hi.Op != OpConst32 =>
-       (Rsh32Ux32 x (Or32 <typ.UInt32> (Zeromask hi) lo))
-(Lsh16x64 x (Int64Make hi lo)) && hi.Op != OpConst32 =>
-       (Lsh16x32 x (Or32 <typ.UInt32> (Zeromask hi) lo))
-(Rsh16x64 x (Int64Make hi lo)) && hi.Op != OpConst32 =>
-       (Rsh16x32 x (Or32 <typ.UInt32> (Zeromask hi) lo))
-(Rsh16Ux64 x (Int64Make hi lo)) && hi.Op != OpConst32 =>
-       (Rsh16Ux32 x (Or32 <typ.UInt32> (Zeromask hi) lo))
-(Lsh8x64 x (Int64Make hi lo)) && hi.Op != OpConst32 =>
-       (Lsh8x32 x (Or32 <typ.UInt32> (Zeromask hi) lo))
-(Rsh8x64 x (Int64Make hi lo)) && hi.Op != OpConst32 =>
-       (Rsh8x32 x (Or32 <typ.UInt32> (Zeromask hi) lo))
-(Rsh8Ux64 x (Int64Make hi lo)) && hi.Op != OpConst32 =>
-       (Rsh8Ux32 x (Or32 <typ.UInt32> (Zeromask hi) lo))
-
-// Most general
-(Lsh64x64 x y)  => (Lsh64x32  x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y)))
-(Rsh64x64 x y)  => (Rsh64x32  x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y)))
-(Rsh64Ux64 x y) => (Rsh64Ux32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y)))
-(Lsh32x64 x y)  => (Lsh32x32  x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y)))
-(Rsh32x64 x y)  => (Rsh32x32  x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y)))
-(Rsh32Ux64 x y) => (Rsh32Ux32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y)))
-(Lsh16x64 x y)  => (Lsh16x32  x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y)))
-(Rsh16x64 x y)  => (Rsh16x32  x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y)))
-(Rsh16Ux64 x y) => (Rsh16Ux32 x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y)))
-(Lsh8x64 x y)   => (Lsh8x32   x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y)))
-(Rsh8x64 x y)   => (Rsh8x32   x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y)))
-(Rsh8Ux64 x y)  => (Rsh8Ux32  x (Or32 <typ.UInt32> (Zeromask (Int64Hi y)) (Int64Lo y)))
-
-// Clean up constants a little
-(Or32 <typ.UInt32> (Zeromask (Const32 [c])) y) && c == 0 => y
-(Or32 <typ.UInt32> (Zeromask (Const32 [c])) y) && c != 0 => (Const32 <typ.UInt32> [-1])
-
-// 64x left shift
-// result.hi = hi<<s | lo>>(32-s) | lo<<(s-32) // >> is unsigned, large shifts result 0
-// result.lo = lo<<s
-(Lsh64x32 x s) =>
-	(Int64Make
-		(Or32 <typ.UInt32>
-			(Or32 <typ.UInt32>
-				(Lsh32x32 <typ.UInt32> (Int64Hi x) s)
-				(Rsh32Ux32 <typ.UInt32>
-					(Int64Lo x)
-					(Sub32 <typ.UInt32> (Const32 <typ.UInt32> [32]) s)))
-			(Lsh32x32 <typ.UInt32>
-				(Int64Lo x)
-				(Sub32 <typ.UInt32> s (Const32 <typ.UInt32> [32]))))
-		(Lsh32x32 <typ.UInt32> (Int64Lo x) s))
-(Lsh64x16 x s) =>
-	(Int64Make
-		(Or32 <typ.UInt32>
-			(Or32 <typ.UInt32>
-				(Lsh32x16 <typ.UInt32> (Int64Hi x) s)
-				(Rsh32Ux16 <typ.UInt32>
-					(Int64Lo x)
-					(Sub16 <typ.UInt16> (Const16 <typ.UInt16> [32]) s)))
-			(Lsh32x16 <typ.UInt32>
-				(Int64Lo x)
-				(Sub16 <typ.UInt16> s (Const16 <typ.UInt16> [32]))))
-		(Lsh32x16 <typ.UInt32> (Int64Lo x) s))
-(Lsh64x8 x s) =>
-	(Int64Make
-		(Or32 <typ.UInt32>
-			(Or32 <typ.UInt32>
-				(Lsh32x8 <typ.UInt32> (Int64Hi x) s)
-				(Rsh32Ux8 <typ.UInt32>
-					(Int64Lo x)
-					(Sub8 <typ.UInt8> (Const8 <typ.UInt8> [32]) s)))
-			(Lsh32x8 <typ.UInt32>
-				(Int64Lo x)
-				(Sub8 <typ.UInt8> s (Const8 <typ.UInt8> [32]))))
-		(Lsh32x8 <typ.UInt32> (Int64Lo x) s))
-
-// 64x unsigned right shift
-// result.hi = hi>>s
-// result.lo = lo>>s | hi<<(32-s) | hi>>(s-32) // >> is unsigned, large shifts result 0
-(Rsh64Ux32 x s) =>
-	(Int64Make
-		(Rsh32Ux32 <typ.UInt32> (Int64Hi x) s)
-		(Or32 <typ.UInt32>
-			(Or32 <typ.UInt32>
-				(Rsh32Ux32 <typ.UInt32> (Int64Lo x) s)
-				(Lsh32x32 <typ.UInt32>
-					(Int64Hi x)
-					(Sub32 <typ.UInt32> (Const32 <typ.UInt32> [32]) s)))
-			(Rsh32Ux32 <typ.UInt32>
-				(Int64Hi x)
-				(Sub32 <typ.UInt32> s (Const32 <typ.UInt32> [32])))))
-(Rsh64Ux16 x s) =>
-	(Int64Make
-		(Rsh32Ux16 <typ.UInt32> (Int64Hi x) s)
-		(Or32 <typ.UInt32>
-			(Or32 <typ.UInt32>
-				(Rsh32Ux16 <typ.UInt32> (Int64Lo x) s)
-				(Lsh32x16 <typ.UInt32>
-					(Int64Hi x)
-					(Sub16 <typ.UInt16> (Const16 <typ.UInt16> [32]) s)))
-			(Rsh32Ux16 <typ.UInt32>
-				(Int64Hi x)
-				(Sub16 <typ.UInt16> s (Const16 <typ.UInt16> [32])))))
-(Rsh64Ux8 x s) =>
-	(Int64Make
-		(Rsh32Ux8 <typ.UInt32> (Int64Hi x) s)
-		(Or32 <typ.UInt32>
-			(Or32 <typ.UInt32>
-				(Rsh32Ux8 <typ.UInt32> (Int64Lo x) s)
-				(Lsh32x8 <typ.UInt32>
-					(Int64Hi x)
-					(Sub8 <typ.UInt8> (Const8 <typ.UInt8> [32]) s)))
-			(Rsh32Ux8 <typ.UInt32>
-				(Int64Hi x)
-				(Sub8 <typ.UInt8> s (Const8 <typ.UInt8> [32])))))
-
-// 64x signed right shift
-// result.hi = hi>>s
-// result.lo = lo>>s | hi<<(32-s) | (hi>>(s-32))&zeromask(s>>5) // hi>>(s-32) is signed, large shifts result 0/-1
-(Rsh64x32 x s) =>
-	(Int64Make
-		(Rsh32x32 <typ.UInt32> (Int64Hi x) s)
-		(Or32 <typ.UInt32>
-			(Or32 <typ.UInt32>
-				(Rsh32Ux32 <typ.UInt32> (Int64Lo x) s)
-				(Lsh32x32 <typ.UInt32>
-					(Int64Hi x)
-					(Sub32 <typ.UInt32> (Const32 <typ.UInt32> [32]) s)))
-			(And32 <typ.UInt32>
-				(Rsh32x32 <typ.UInt32>
-					(Int64Hi x)
-					(Sub32 <typ.UInt32> s (Const32 <typ.UInt32> [32])))
-				(Zeromask
-					(Rsh32Ux32 <typ.UInt32> s (Const32 <typ.UInt32> [5]))))))
-(Rsh64x16 x s) =>
-	(Int64Make
-		(Rsh32x16 <typ.UInt32> (Int64Hi x) s)
-		(Or32 <typ.UInt32>
-			(Or32 <typ.UInt32>
-				(Rsh32Ux16 <typ.UInt32> (Int64Lo x) s)
-				(Lsh32x16 <typ.UInt32>
-					(Int64Hi x)
-					(Sub16 <typ.UInt16> (Const16 <typ.UInt16> [32]) s)))
-			(And32 <typ.UInt32>
-				(Rsh32x16 <typ.UInt32>
-					(Int64Hi x)
-					(Sub16 <typ.UInt16> s (Const16 <typ.UInt16> [32])))
-				(Zeromask
-					(ZeroExt16to32
-						(Rsh16Ux32 <typ.UInt16> s (Const32 <typ.UInt32> [5])))))))
-(Rsh64x8 x s) =>
-	(Int64Make
-		(Rsh32x8 <typ.UInt32> (Int64Hi x) s)
-		(Or32 <typ.UInt32>
-			(Or32 <typ.UInt32>
-				(Rsh32Ux8 <typ.UInt32> (Int64Lo x) s)
-				(Lsh32x8 <typ.UInt32>
-					(Int64Hi x)
-					(Sub8 <typ.UInt8> (Const8 <typ.UInt8> [32]) s)))
-			(And32 <typ.UInt32>
-				(Rsh32x8 <typ.UInt32>
-					(Int64Hi x)
-					(Sub8 <typ.UInt8> s (Const8 <typ.UInt8> [32])))
-				(Zeromask
-					(ZeroExt8to32
-						(Rsh8Ux32 <typ.UInt8> s (Const32 <typ.UInt32> [5])))))))
-
-(Const64 <t> [c]) && t.IsSigned() =>
-	(Int64Make (Const32 <typ.Int32> [int32(c>>32)]) (Const32 <typ.UInt32> [int32(c)]))
-(Const64 <t> [c]) && !t.IsSigned() =>
-	(Int64Make (Const32 <typ.UInt32> [int32(c>>32)]) (Const32 <typ.UInt32> [int32(c)]))
-
-(Eq64 x y) =>
-	(AndB
-		(Eq32 (Int64Hi x) (Int64Hi y))
-		(Eq32 (Int64Lo x) (Int64Lo y)))
-
-(Neq64 x y) =>
-	(OrB
-		(Neq32 (Int64Hi x) (Int64Hi y))
-		(Neq32 (Int64Lo x) (Int64Lo y)))
-
-(Less64U x y) =>
-	(OrB
-		(Less32U (Int64Hi x) (Int64Hi y))
-		(AndB
-			(Eq32 (Int64Hi x) (Int64Hi y))
-			(Less32U (Int64Lo x) (Int64Lo y))))
-
-(Leq64U x y) =>
-	(OrB
-		(Less32U (Int64Hi x) (Int64Hi y))
-		(AndB
-			(Eq32 (Int64Hi x) (Int64Hi y))
-			(Leq32U (Int64Lo x) (Int64Lo y))))
-
-(Less64 x y) =>
-	(OrB
-		(Less32 (Int64Hi x) (Int64Hi y))
-		(AndB
-			(Eq32 (Int64Hi x) (Int64Hi y))
-			(Less32U (Int64Lo x) (Int64Lo y))))
-
-(Leq64 x y) =>
-	(OrB
-		(Less32 (Int64Hi x) (Int64Hi y))
-		(AndB
-			(Eq32 (Int64Hi x) (Int64Hi y))
-			(Leq32U (Int64Lo x) (Int64Lo y))))
diff --git a/src/cmd/compile/internal/ssa/gen/dec64Ops.go b/src/cmd/compile/internal/ssa/gen/dec64Ops.go
deleted file mode 100644
index 78fcea8..0000000
--- a/src/cmd/compile/internal/ssa/gen/dec64Ops.go
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build ignore
-// +build ignore
-
-package main
-
-var dec64Ops = []opData{}
-
-var dec64Blocks = []blockData{}
-
-func init() {
-	archs = append(archs, arch{
-		name:    "dec64",
-		ops:     dec64Ops,
-		blocks:  dec64Blocks,
-		generic: true,
-	})
-}
diff --git a/src/cmd/compile/internal/ssa/gen/decOps.go b/src/cmd/compile/internal/ssa/gen/decOps.go
deleted file mode 100644
index d5cd793..0000000
--- a/src/cmd/compile/internal/ssa/gen/decOps.go
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build ignore
-// +build ignore
-
-package main
-
-var decOps = []opData{}
-
-var decBlocks = []blockData{}
-
-func init() {
-	archs = append(archs, arch{
-		name:    "dec",
-		ops:     decOps,
-		blocks:  decBlocks,
-		generic: true,
-	})
-}
diff --git a/src/cmd/compile/internal/ssa/gen/generic.rules b/src/cmd/compile/internal/ssa/gen/generic.rules
deleted file mode 100644
index d5cc107..0000000
--- a/src/cmd/compile/internal/ssa/gen/generic.rules
+++ /dev/null
@@ -1,2549 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Simplifications that apply to all backend architectures. As an example, this
-// Go source code
-//
-// y := 0 * x
-//
-// can be translated into y := 0 without losing any information, which saves a
-// pointless multiplication instruction. Other .rules files in this directory
-// (for example AMD64.rules) contain rules specific to the architecture in the
-// filename. The rules here apply to every architecture.
-//
-// The code for parsing this file lives in rulegen.go; this file generates
-// ssa/rewritegeneric.go.
-
-// values are specified using the following format:
-// (op <type> [auxint] {aux} arg0 arg1 ...)
-// the type, aux, and auxint fields are optional
-// on the matching side
-//  - the type, aux, and auxint fields must match if they are specified.
-//  - the first occurrence of a variable defines that variable.  Subsequent
-//    uses must match (be == to) the first use.
-//  - v is defined to be the value matched.
-//  - an additional conditional can be provided after the match pattern with "&&".
-// on the generated side
-//  - the type of the top-level expression is the same as the one on the left-hand side.
-//  - the type of any subexpressions must be specified explicitly (or
-//    be specified in the op's type field).
-//  - auxint will be 0 if not specified.
-//  - aux will be nil if not specified.
-
-// blocks are specified using the following format:
-// (kind controlvalue succ0 succ1 ...)
-// controlvalue must be "nil" or a value expression
-// succ* fields must be variables
-// For now, the generated successors must be a permutation of the matched successors.
-
-// constant folding
-(Trunc16to8  (Const16  [c])) => (Const8   [int8(c)])
-(Trunc32to8  (Const32  [c])) => (Const8   [int8(c)])
-(Trunc32to16 (Const32  [c])) => (Const16  [int16(c)])
-(Trunc64to8  (Const64  [c])) => (Const8   [int8(c)])
-(Trunc64to16 (Const64  [c])) => (Const16  [int16(c)])
-(Trunc64to32 (Const64  [c])) => (Const32  [int32(c)])
-(Cvt64Fto32F (Const64F [c])) => (Const32F [float32(c)])
-(Cvt32Fto64F (Const32F [c])) => (Const64F [float64(c)])
-(Cvt32to32F  (Const32  [c])) => (Const32F [float32(c)])
-(Cvt32to64F  (Const32  [c])) => (Const64F [float64(c)])
-(Cvt64to32F  (Const64  [c])) => (Const32F [float32(c)])
-(Cvt64to64F  (Const64  [c])) => (Const64F [float64(c)])
-(Cvt32Fto32  (Const32F [c])) => (Const32  [int32(c)])
-(Cvt32Fto64  (Const32F [c])) => (Const64  [int64(c)])
-(Cvt64Fto32  (Const64F [c])) => (Const32  [int32(c)])
-(Cvt64Fto64  (Const64F [c])) => (Const64  [int64(c)])
-(Round32F x:(Const32F)) => x
-(Round64F x:(Const64F)) => x
-(CvtBoolToUint8 (ConstBool [false])) => (Const8 [0])
-(CvtBoolToUint8 (ConstBool [true])) => (Const8 [1])
-
-(Trunc16to8  (ZeroExt8to16  x)) => x
-(Trunc32to8  (ZeroExt8to32  x)) => x
-(Trunc32to16 (ZeroExt8to32  x)) => (ZeroExt8to16  x)
-(Trunc32to16 (ZeroExt16to32 x)) => x
-(Trunc64to8  (ZeroExt8to64  x)) => x
-(Trunc64to16 (ZeroExt8to64  x)) => (ZeroExt8to16  x)
-(Trunc64to16 (ZeroExt16to64 x)) => x
-(Trunc64to32 (ZeroExt8to64  x)) => (ZeroExt8to32  x)
-(Trunc64to32 (ZeroExt16to64 x)) => (ZeroExt16to32 x)
-(Trunc64to32 (ZeroExt32to64 x)) => x
-(Trunc16to8  (SignExt8to16  x)) => x
-(Trunc32to8  (SignExt8to32  x)) => x
-(Trunc32to16 (SignExt8to32  x)) => (SignExt8to16  x)
-(Trunc32to16 (SignExt16to32 x)) => x
-(Trunc64to8  (SignExt8to64  x)) => x
-(Trunc64to16 (SignExt8to64  x)) => (SignExt8to16  x)
-(Trunc64to16 (SignExt16to64 x)) => x
-(Trunc64to32 (SignExt8to64  x)) => (SignExt8to32  x)
-(Trunc64to32 (SignExt16to64 x)) => (SignExt16to32 x)
-(Trunc64to32 (SignExt32to64 x)) => x
-
-(ZeroExt8to16  (Const8  [c])) => (Const16 [int16( uint8(c))])
-(ZeroExt8to32  (Const8  [c])) => (Const32 [int32( uint8(c))])
-(ZeroExt8to64  (Const8  [c])) => (Const64 [int64( uint8(c))])
-(ZeroExt16to32 (Const16 [c])) => (Const32 [int32(uint16(c))])
-(ZeroExt16to64 (Const16 [c])) => (Const64 [int64(uint16(c))])
-(ZeroExt32to64 (Const32 [c])) => (Const64 [int64(uint32(c))])
-(SignExt8to16  (Const8  [c])) => (Const16 [int16(c)])
-(SignExt8to32  (Const8  [c])) => (Const32 [int32(c)])
-(SignExt8to64  (Const8  [c])) => (Const64 [int64(c)])
-(SignExt16to32 (Const16 [c])) => (Const32 [int32(c)])
-(SignExt16to64 (Const16 [c])) => (Const64 [int64(c)])
-(SignExt32to64 (Const32 [c])) => (Const64 [int64(c)])
-
-(Neg8   (Const8   [c])) => (Const8   [-c])
-(Neg16  (Const16  [c])) => (Const16  [-c])
-(Neg32  (Const32  [c])) => (Const32  [-c])
-(Neg64  (Const64  [c])) => (Const64  [-c])
-(Neg32F (Const32F [c])) && c != 0 => (Const32F [-c])
-(Neg64F (Const64F [c])) && c != 0 => (Const64F [-c])
-
-(Add8   (Const8 [c])   (Const8 [d]))   => (Const8  [c+d])
-(Add16  (Const16 [c])  (Const16 [d]))  => (Const16 [c+d])
-(Add32  (Const32 [c])  (Const32 [d]))  => (Const32 [c+d])
-(Add64  (Const64 [c])  (Const64 [d]))  => (Const64 [c+d])
-(Add32F (Const32F [c]) (Const32F [d])) && c+d == c+d => (Const32F [c+d])
-(Add64F (Const64F [c]) (Const64F [d])) && c+d == c+d => (Const64F [c+d])
-(AddPtr <t> x (Const64 [c])) => (OffPtr <t> x [c])
-(AddPtr <t> x (Const32 [c])) => (OffPtr <t> x [int64(c)])
-
-(Sub8   (Const8 [c]) (Const8 [d]))     => (Const8 [c-d])
-(Sub16  (Const16 [c]) (Const16 [d]))   => (Const16 [c-d])
-(Sub32  (Const32 [c]) (Const32 [d]))   => (Const32 [c-d])
-(Sub64  (Const64 [c]) (Const64 [d]))   => (Const64 [c-d])
-(Sub32F (Const32F [c]) (Const32F [d])) && c-d == c-d => (Const32F [c-d])
-(Sub64F (Const64F [c]) (Const64F [d])) && c-d == c-d => (Const64F [c-d])
-
-(Mul8   (Const8 [c])   (Const8 [d]))   => (Const8  [c*d])
-(Mul16  (Const16 [c])  (Const16 [d]))  => (Const16 [c*d])
-(Mul32  (Const32 [c])  (Const32 [d]))  => (Const32 [c*d])
-(Mul64  (Const64 [c])  (Const64 [d]))  => (Const64 [c*d])
-(Mul32F (Const32F [c]) (Const32F [d])) && c*d == c*d => (Const32F [c*d])
-(Mul64F (Const64F [c]) (Const64F [d])) && c*d == c*d => (Const64F [c*d])
-
-(And8   (Const8 [c])   (Const8 [d]))   => (Const8  [c&d])
-(And16  (Const16 [c])  (Const16 [d]))  => (Const16 [c&d])
-(And32  (Const32 [c])  (Const32 [d]))  => (Const32 [c&d])
-(And64  (Const64 [c])  (Const64 [d]))  => (Const64 [c&d])
-
-(Or8   (Const8 [c])   (Const8 [d]))   => (Const8  [c|d])
-(Or16  (Const16 [c])  (Const16 [d]))  => (Const16 [c|d])
-(Or32  (Const32 [c])  (Const32 [d]))  => (Const32 [c|d])
-(Or64  (Const64 [c])  (Const64 [d]))  => (Const64 [c|d])
-
-(Xor8   (Const8 [c])   (Const8 [d]))   => (Const8  [c^d])
-(Xor16  (Const16 [c])  (Const16 [d]))  => (Const16 [c^d])
-(Xor32  (Const32 [c])  (Const32 [d]))  => (Const32 [c^d])
-(Xor64  (Const64 [c])  (Const64 [d]))  => (Const64 [c^d])
-
-(Ctz64 (Const64 [c])) && config.PtrSize == 4 => (Const32 [int32(ntz64(c))])
-(Ctz32 (Const32 [c])) && config.PtrSize == 4 => (Const32 [int32(ntz32(c))])
-(Ctz16 (Const16 [c])) && config.PtrSize == 4 => (Const32 [int32(ntz16(c))])
-(Ctz8  (Const8  [c])) && config.PtrSize == 4 => (Const32 [int32(ntz8(c))])
-
-(Ctz64 (Const64 [c])) && config.PtrSize == 8 => (Const64 [int64(ntz64(c))])
-(Ctz32 (Const32 [c])) && config.PtrSize == 8 => (Const64 [int64(ntz32(c))])
-(Ctz16 (Const16 [c])) && config.PtrSize == 8 => (Const64 [int64(ntz16(c))])
-(Ctz8  (Const8  [c])) && config.PtrSize == 8 => (Const64 [int64(ntz8(c))])
-
-(Div8   (Const8  [c])  (Const8  [d])) && d != 0 => (Const8  [c/d])
-(Div16  (Const16 [c])  (Const16 [d])) && d != 0 => (Const16 [c/d])
-(Div32  (Const32 [c])  (Const32 [d])) && d != 0 => (Const32 [c/d])
-(Div64  (Const64 [c])  (Const64 [d])) && d != 0 => (Const64 [c/d])
-(Div8u  (Const8  [c])  (Const8  [d])) && d != 0 => (Const8  [int8(uint8(c)/uint8(d))])
-(Div16u (Const16 [c])  (Const16 [d])) && d != 0 => (Const16 [int16(uint16(c)/uint16(d))])
-(Div32u (Const32 [c])  (Const32 [d])) && d != 0 => (Const32 [int32(uint32(c)/uint32(d))])
-(Div64u (Const64 [c])  (Const64 [d])) && d != 0 => (Const64 [int64(uint64(c)/uint64(d))])
-(Div32F (Const32F [c]) (Const32F [d])) && c/d == c/d => (Const32F [c/d])
-(Div64F (Const64F [c]) (Const64F [d])) && c/d == c/d => (Const64F [c/d])
-(Select0 (Div128u (Const64 [0]) lo y)) => (Div64u lo y)
-(Select1 (Div128u (Const64 [0]) lo y)) => (Mod64u lo y)
-
-(Not (ConstBool [c])) => (ConstBool [!c])
-
-// Convert x * 1 to x.
-(Mul(8|16|32|64)  (Const(8|16|32|64)  [1]) x) => x
-
-// Convert x * -1 to -x.
-(Mul(8|16|32|64)  (Const(8|16|32|64)  [-1]) x) => (Neg(8|16|32|64)  x)
-
-// Convert multiplication by a power of two to a shift.
-(Mul8  <t> n (Const8  [c])) && isPowerOfTwo8(c) => (Lsh8x64  <t> n (Const64 <typ.UInt64> [log8(c)]))
-(Mul16 <t> n (Const16 [c])) && isPowerOfTwo16(c) => (Lsh16x64 <t> n (Const64 <typ.UInt64> [log16(c)]))
-(Mul32 <t> n (Const32 [c])) && isPowerOfTwo32(c) => (Lsh32x64 <t> n (Const64 <typ.UInt64> [log32(c)]))
-(Mul64 <t> n (Const64 [c])) && isPowerOfTwo64(c) => (Lsh64x64 <t> n (Const64 <typ.UInt64> [log64(c)]))
-(Mul8  <t> n (Const8  [c])) && t.IsSigned() && isPowerOfTwo8(-c)  => (Neg8  (Lsh8x64  <t> n (Const64 <typ.UInt64> [log8(-c)])))
-(Mul16 <t> n (Const16 [c])) && t.IsSigned() && isPowerOfTwo16(-c) => (Neg16 (Lsh16x64 <t> n (Const64 <typ.UInt64> [log16(-c)])))
-(Mul32 <t> n (Const32 [c])) && t.IsSigned() && isPowerOfTwo32(-c) => (Neg32 (Lsh32x64 <t> n (Const64 <typ.UInt64> [log32(-c)])))
-(Mul64 <t> n (Const64 [c])) && t.IsSigned() && isPowerOfTwo64(-c) => (Neg64 (Lsh64x64 <t> n (Const64 <typ.UInt64> [log64(-c)])))
-
-(Mod8  (Const8  [c]) (Const8  [d])) && d != 0 => (Const8  [c % d])
-(Mod16 (Const16 [c]) (Const16 [d])) && d != 0 => (Const16 [c % d])
-(Mod32 (Const32 [c]) (Const32 [d])) && d != 0 => (Const32 [c % d])
-(Mod64 (Const64 [c]) (Const64 [d])) && d != 0 => (Const64 [c % d])
-
-(Mod8u  (Const8 [c])  (Const8  [d])) && d != 0 => (Const8  [int8(uint8(c) % uint8(d))])
-(Mod16u (Const16 [c]) (Const16 [d])) && d != 0 => (Const16 [int16(uint16(c) % uint16(d))])
-(Mod32u (Const32 [c]) (Const32 [d])) && d != 0 => (Const32 [int32(uint32(c) % uint32(d))])
-(Mod64u (Const64 [c]) (Const64 [d])) && d != 0 => (Const64 [int64(uint64(c) % uint64(d))])
-
-(Lsh64x64  (Const64 [c]) (Const64 [d])) => (Const64 [c << uint64(d)])
-(Rsh64x64  (Const64 [c]) (Const64 [d])) => (Const64 [c >> uint64(d)])
-(Rsh64Ux64 (Const64 [c]) (Const64 [d])) => (Const64 [int64(uint64(c) >> uint64(d))])
-(Lsh32x64  (Const32 [c]) (Const64 [d])) => (Const32 [c << uint64(d)])
-(Rsh32x64  (Const32 [c]) (Const64 [d])) => (Const32 [c >> uint64(d)])
-(Rsh32Ux64 (Const32 [c]) (Const64 [d])) => (Const32 [int32(uint32(c) >> uint64(d))])
-(Lsh16x64  (Const16 [c]) (Const64 [d])) => (Const16 [c << uint64(d)])
-(Rsh16x64  (Const16 [c]) (Const64 [d])) => (Const16 [c >> uint64(d)])
-(Rsh16Ux64 (Const16 [c]) (Const64 [d])) => (Const16 [int16(uint16(c) >> uint64(d))])
-(Lsh8x64   (Const8  [c]) (Const64 [d])) => (Const8  [c << uint64(d)])
-(Rsh8x64   (Const8  [c]) (Const64 [d])) => (Const8  [c >> uint64(d)])
-(Rsh8Ux64  (Const8  [c]) (Const64 [d])) => (Const8  [int8(uint8(c) >> uint64(d))])
-
-// Fold IsInBounds when the range of the index cannot exceed the limit.
-(IsInBounds (ZeroExt8to32  _) (Const32 [c])) && (1 << 8)  <= c => (ConstBool [true])
-(IsInBounds (ZeroExt8to64  _) (Const64 [c])) && (1 << 8)  <= c => (ConstBool [true])
-(IsInBounds (ZeroExt16to32 _) (Const32 [c])) && (1 << 16) <= c => (ConstBool [true])
-(IsInBounds (ZeroExt16to64 _) (Const64 [c])) && (1 << 16) <= c => (ConstBool [true])
-(IsInBounds x x) => (ConstBool [false])
-(IsInBounds                (And8  (Const8  [c]) _)  (Const8  [d])) && 0 <= c && c < d => (ConstBool [true])
-(IsInBounds (ZeroExt8to16  (And8  (Const8  [c]) _)) (Const16 [d])) && 0 <= c && int16(c) < d => (ConstBool [true])
-(IsInBounds (ZeroExt8to32  (And8  (Const8  [c]) _)) (Const32 [d])) && 0 <= c && int32(c) < d => (ConstBool [true])
-(IsInBounds (ZeroExt8to64  (And8  (Const8  [c]) _)) (Const64 [d])) && 0 <= c && int64(c) < d => (ConstBool [true])
-(IsInBounds                (And16 (Const16 [c]) _)  (Const16 [d])) && 0 <= c && c < d => (ConstBool [true])
-(IsInBounds (ZeroExt16to32 (And16 (Const16 [c]) _)) (Const32 [d])) && 0 <= c && int32(c) < d => (ConstBool [true])
-(IsInBounds (ZeroExt16to64 (And16 (Const16 [c]) _)) (Const64 [d])) && 0 <= c && int64(c) < d => (ConstBool [true])
-(IsInBounds                (And32 (Const32 [c]) _)  (Const32 [d])) && 0 <= c && c < d => (ConstBool [true])
-(IsInBounds (ZeroExt32to64 (And32 (Const32 [c]) _)) (Const64 [d])) && 0 <= c && int64(c) < d => (ConstBool [true])
-(IsInBounds                (And64 (Const64 [c]) _)  (Const64 [d])) && 0 <= c && c < d => (ConstBool [true])
-(IsInBounds (Const32 [c]) (Const32 [d])) => (ConstBool [0 <= c && c < d])
-(IsInBounds (Const64 [c]) (Const64 [d])) => (ConstBool [0 <= c && c < d])
-// (Mod64u x y) is always between 0 (inclusive) and y (exclusive).
-(IsInBounds (Mod32u _ y) y) => (ConstBool [true])
-(IsInBounds (Mod64u _ y) y) => (ConstBool [true])
-// Right shifting an unsigned number limits its value.
-(IsInBounds (ZeroExt8to64  (Rsh8Ux64  _ (Const64 [c]))) (Const64 [d])) && 0 < c && c <  8 && 1<<uint( 8-c)-1 < d => (ConstBool [true])
-(IsInBounds (ZeroExt8to32  (Rsh8Ux64  _ (Const64 [c]))) (Const32 [d])) && 0 < c && c <  8 && 1<<uint( 8-c)-1 < d => (ConstBool [true])
-(IsInBounds (ZeroExt8to16  (Rsh8Ux64  _ (Const64 [c]))) (Const16 [d])) && 0 < c && c <  8 && 1<<uint( 8-c)-1 < d => (ConstBool [true])
-(IsInBounds                (Rsh8Ux64  _ (Const64 [c]))  (Const64 [d])) && 0 < c && c <  8 && 1<<uint( 8-c)-1 < d => (ConstBool [true])
-(IsInBounds (ZeroExt16to64 (Rsh16Ux64 _ (Const64 [c]))) (Const64 [d])) && 0 < c && c < 16 && 1<<uint(16-c)-1 < d => (ConstBool [true])
-(IsInBounds (ZeroExt16to32 (Rsh16Ux64 _ (Const64 [c]))) (Const64 [d])) && 0 < c && c < 16 && 1<<uint(16-c)-1 < d => (ConstBool [true])
-(IsInBounds                (Rsh16Ux64 _ (Const64 [c]))  (Const64 [d])) && 0 < c && c < 16 && 1<<uint(16-c)-1 < d => (ConstBool [true])
-(IsInBounds (ZeroExt32to64 (Rsh32Ux64 _ (Const64 [c]))) (Const64 [d])) && 0 < c && c < 32 && 1<<uint(32-c)-1 < d => (ConstBool [true])
-(IsInBounds                (Rsh32Ux64 _ (Const64 [c]))  (Const64 [d])) && 0 < c && c < 32 && 1<<uint(32-c)-1 < d => (ConstBool [true])
-(IsInBounds                (Rsh64Ux64 _ (Const64 [c]))  (Const64 [d])) && 0 < c && c < 64 && 1<<uint(64-c)-1 < d => (ConstBool [true])
-
-(IsSliceInBounds x x) => (ConstBool [true])
-(IsSliceInBounds (And32 (Const32 [c]) _) (Const32 [d])) && 0 <= c && c <= d => (ConstBool [true])
-(IsSliceInBounds (And64 (Const64 [c]) _) (Const64 [d])) && 0 <= c && c <= d => (ConstBool [true])
-(IsSliceInBounds (Const32 [0]) _) => (ConstBool [true])
-(IsSliceInBounds (Const64 [0]) _) => (ConstBool [true])
-(IsSliceInBounds (Const32 [c]) (Const32 [d])) => (ConstBool [0 <= c && c <= d])
-(IsSliceInBounds (Const64 [c]) (Const64 [d])) => (ConstBool [0 <= c && c <= d])
-(IsSliceInBounds (SliceLen x) (SliceCap x)) => (ConstBool [true])
-
-(Eq(64|32|16|8) x x) => (ConstBool [true])
-(EqB (ConstBool [c]) (ConstBool [d])) => (ConstBool [c == d])
-(EqB (ConstBool [false]) x) => (Not x)
-(EqB (ConstBool [true]) x) => x
-
-(Neq(64|32|16|8) x x) => (ConstBool [false])
-(NeqB (ConstBool [c]) (ConstBool [d])) => (ConstBool [c != d])
-(NeqB (ConstBool [false]) x) => x
-(NeqB (ConstBool [true]) x) => (Not x)
-(NeqB (Not x) (Not y)) => (NeqB x y)
-
-(Eq64 (Const64 <t> [c]) (Add64 (Const64 <t> [d]) x)) => (Eq64 (Const64 <t> [c-d]) x)
-(Eq32 (Const32 <t> [c]) (Add32 (Const32 <t> [d]) x)) => (Eq32 (Const32 <t> [c-d]) x)
-(Eq16 (Const16 <t> [c]) (Add16 (Const16 <t> [d]) x)) => (Eq16 (Const16 <t> [c-d]) x)
-(Eq8  (Const8  <t> [c]) (Add8  (Const8  <t> [d]) x)) => (Eq8  (Const8  <t> [c-d]) x)
-
-(Neq64 (Const64 <t> [c]) (Add64 (Const64 <t> [d]) x)) => (Neq64 (Const64 <t> [c-d]) x)
-(Neq32 (Const32 <t> [c]) (Add32 (Const32 <t> [d]) x)) => (Neq32 (Const32 <t> [c-d]) x)
-(Neq16 (Const16 <t> [c]) (Add16 (Const16 <t> [d]) x)) => (Neq16 (Const16 <t> [c-d]) x)
-(Neq8  (Const8  <t> [c]) (Add8  (Const8  <t> [d]) x)) => (Neq8  (Const8  <t> [c-d]) x)
-
-// signed integer range: ( c <= x && x (<|<=) d ) -> ( unsigned(x-c) (<|<=) unsigned(d-c) )
-(AndB (Leq64 (Const64 [c]) x) ((Less|Leq)64 x (Const64 [d]))) && d >= c => ((Less|Leq)64U (Sub64 <x.Type> x (Const64 <x.Type> [c])) (Const64 <x.Type> [d-c]))
-(AndB (Leq32 (Const32 [c]) x) ((Less|Leq)32 x (Const32 [d]))) && d >= c => ((Less|Leq)32U (Sub32 <x.Type> x (Const32 <x.Type> [c])) (Const32 <x.Type> [d-c]))
-(AndB (Leq16 (Const16 [c]) x) ((Less|Leq)16 x (Const16 [d]))) && d >= c => ((Less|Leq)16U (Sub16 <x.Type> x (Const16 <x.Type> [c])) (Const16 <x.Type> [d-c]))
-(AndB (Leq8  (Const8  [c]) x) ((Less|Leq)8  x (Const8  [d]))) && d >= c => ((Less|Leq)8U  (Sub8  <x.Type> x (Const8  <x.Type> [c])) (Const8  <x.Type> [d-c]))
-
-// signed integer range: ( c < x && x (<|<=) d ) -> ( unsigned(x-(c+1)) (<|<=) unsigned(d-(c+1)) )
-(AndB (Less64 (Const64 [c]) x) ((Less|Leq)64 x (Const64 [d]))) && d >= c+1 && c+1 > c => ((Less|Leq)64U (Sub64 <x.Type> x (Const64 <x.Type> [c+1])) (Const64 <x.Type> [d-c-1]))
-(AndB (Less32 (Const32 [c]) x) ((Less|Leq)32 x (Const32 [d]))) && d >= c+1 && c+1 > c => ((Less|Leq)32U (Sub32 <x.Type> x (Const32 <x.Type> [c+1])) (Const32 <x.Type> [d-c-1]))
-(AndB (Less16 (Const16 [c]) x) ((Less|Leq)16 x (Const16 [d]))) && d >= c+1 && c+1 > c => ((Less|Leq)16U (Sub16 <x.Type> x (Const16 <x.Type> [c+1])) (Const16 <x.Type> [d-c-1]))
-(AndB (Less8  (Const8  [c]) x) ((Less|Leq)8  x (Const8  [d]))) && d >= c+1 && c+1 > c => ((Less|Leq)8U  (Sub8  <x.Type> x (Const8  <x.Type> [c+1])) (Const8  <x.Type> [d-c-1]))
-
-// unsigned integer range: ( c <= x && x (<|<=) d ) -> ( x-c (<|<=) d-c )
-(AndB (Leq64U (Const64 [c]) x) ((Less|Leq)64U x (Const64 [d]))) && uint64(d) >= uint64(c) => ((Less|Leq)64U (Sub64 <x.Type> x (Const64 <x.Type> [c])) (Const64 <x.Type> [d-c]))
-(AndB (Leq32U (Const32 [c]) x) ((Less|Leq)32U x (Const32 [d]))) && uint32(d) >= uint32(c) => ((Less|Leq)32U (Sub32 <x.Type> x (Const32 <x.Type> [c])) (Const32 <x.Type> [d-c]))
-(AndB (Leq16U (Const16 [c]) x) ((Less|Leq)16U x (Const16 [d]))) && uint16(d) >= uint16(c) => ((Less|Leq)16U (Sub16 <x.Type> x (Const16 <x.Type> [c])) (Const16 <x.Type> [d-c]))
-(AndB (Leq8U  (Const8  [c]) x) ((Less|Leq)8U  x (Const8  [d]))) && uint8(d)  >= uint8(c)  => ((Less|Leq)8U  (Sub8  <x.Type> x (Const8  <x.Type> [c])) (Const8  <x.Type> [d-c]))
-
-// unsigned integer range: ( c < x && x (<|<=) d ) -> ( x-(c+1) (<|<=) d-(c+1) )
-(AndB (Less64U (Const64 [c]) x) ((Less|Leq)64U x (Const64 [d]))) && uint64(d) >= uint64(c+1) && uint64(c+1) > uint64(c) => ((Less|Leq)64U (Sub64 <x.Type> x (Const64 <x.Type> [c+1])) (Const64 <x.Type> [d-c-1]))
-(AndB (Less32U (Const32 [c]) x) ((Less|Leq)32U x (Const32 [d]))) && uint32(d) >= uint32(c+1) && uint32(c+1) > uint32(c) => ((Less|Leq)32U (Sub32 <x.Type> x (Const32 <x.Type> [c+1])) (Const32 <x.Type> [d-c-1]))
-(AndB (Less16U (Const16 [c]) x) ((Less|Leq)16U x (Const16 [d]))) && uint16(d) >= uint16(c+1) && uint16(c+1) > uint16(c) => ((Less|Leq)16U (Sub16 <x.Type> x (Const16 <x.Type> [c+1])) (Const16 <x.Type> [d-c-1]))
-(AndB (Less8U  (Const8  [c]) x) ((Less|Leq)8U  x (Const8  [d]))) && uint8(d)  >= uint8(c+1)  && uint8(c+1)  > uint8(c)  => ((Less|Leq)8U  (Sub8  <x.Type> x (Const8  <x.Type> [c+1]))  (Const8  <x.Type> [d-c-1]))
-
-// signed integer range: ( c (<|<=) x || x < d ) -> ( unsigned(c-d) (<|<=) unsigned(x-d) )
-(OrB ((Less|Leq)64 (Const64 [c]) x) (Less64 x (Const64 [d]))) && c >= d => ((Less|Leq)64U (Const64 <x.Type> [c-d]) (Sub64 <x.Type> x (Const64 <x.Type> [d])))
-(OrB ((Less|Leq)32 (Const32 [c]) x) (Less32 x (Const32 [d]))) && c >= d => ((Less|Leq)32U (Const32 <x.Type> [c-d]) (Sub32 <x.Type> x (Const32 <x.Type> [d])))
-(OrB ((Less|Leq)16 (Const16 [c]) x) (Less16 x (Const16 [d]))) && c >= d => ((Less|Leq)16U (Const16 <x.Type> [c-d]) (Sub16 <x.Type> x (Const16 <x.Type> [d])))
-(OrB ((Less|Leq)8  (Const8  [c]) x) (Less8  x (Const8  [d]))) && c >= d => ((Less|Leq)8U  (Const8  <x.Type> [c-d]) (Sub8  <x.Type> x (Const8  <x.Type> [d])))
-
-// signed integer range: ( c (<|<=) x || x <= d ) -> ( unsigned(c-(d+1)) (<|<=) unsigned(x-(d+1)) )
-(OrB ((Less|Leq)64 (Const64 [c]) x) (Leq64 x (Const64 [d]))) && c >= d+1 && d+1 > d => ((Less|Leq)64U (Const64 <x.Type> [c-d-1]) (Sub64 <x.Type> x (Const64 <x.Type> [d+1])))
-(OrB ((Less|Leq)32 (Const32 [c]) x) (Leq32 x (Const32 [d]))) && c >= d+1 && d+1 > d => ((Less|Leq)32U (Const32 <x.Type> [c-d-1]) (Sub32 <x.Type> x (Const32 <x.Type> [d+1])))
-(OrB ((Less|Leq)16 (Const16 [c]) x) (Leq16 x (Const16 [d]))) && c >= d+1 && d+1 > d => ((Less|Leq)16U (Const16 <x.Type> [c-d-1]) (Sub16 <x.Type> x (Const16 <x.Type> [d+1])))
-(OrB ((Less|Leq)8  (Const8  [c]) x) (Leq8  x (Const8  [d]))) && c >= d+1 && d+1 > d => ((Less|Leq)8U  (Const8  <x.Type> [c-d-1]) (Sub8  <x.Type> x (Const8  <x.Type> [d+1])))
-
-// unsigned integer range: ( c (<|<=) x || x < d ) -> ( c-d (<|<=) x-d )
-(OrB ((Less|Leq)64U (Const64 [c]) x) (Less64U x (Const64 [d]))) && uint64(c) >= uint64(d) => ((Less|Leq)64U (Const64 <x.Type> [c-d]) (Sub64 <x.Type> x (Const64 <x.Type> [d])))
-(OrB ((Less|Leq)32U (Const32 [c]) x) (Less32U x (Const32 [d]))) && uint32(c) >= uint32(d) => ((Less|Leq)32U (Const32 <x.Type> [c-d]) (Sub32 <x.Type> x (Const32 <x.Type> [d])))
-(OrB ((Less|Leq)16U (Const16 [c]) x) (Less16U x (Const16 [d]))) && uint16(c) >= uint16(d) => ((Less|Leq)16U (Const16 <x.Type> [c-d]) (Sub16 <x.Type> x (Const16 <x.Type> [d])))
-(OrB ((Less|Leq)8U  (Const8  [c]) x) (Less8U  x (Const8  [d]))) && uint8(c)  >= uint8(d)  => ((Less|Leq)8U  (Const8  <x.Type> [c-d]) (Sub8  <x.Type> x (Const8  <x.Type> [d])))
-
-// unsigned integer range: ( c (<|<=) x || x <= d ) -> ( c-(d+1) (<|<=) x-(d+1) )
-(OrB ((Less|Leq)64U (Const64 [c]) x) (Leq64U x (Const64 [d]))) && uint64(c) >= uint64(d+1) && uint64(d+1) > uint64(d) => ((Less|Leq)64U (Const64 <x.Type> [c-d-1]) (Sub64 <x.Type> x (Const64 <x.Type> [d+1])))
-(OrB ((Less|Leq)32U (Const32 [c]) x) (Leq32U x (Const32 [d]))) && uint32(c) >= uint32(d+1) && uint32(d+1) > uint32(d) => ((Less|Leq)32U (Const32 <x.Type> [c-d-1]) (Sub32 <x.Type> x (Const32 <x.Type> [d+1])))
-(OrB ((Less|Leq)16U (Const16 [c]) x) (Leq16U x (Const16 [d]))) && uint16(c) >= uint16(d+1) && uint16(d+1) > uint16(d) => ((Less|Leq)16U (Const16 <x.Type> [c-d-1]) (Sub16 <x.Type> x (Const16 <x.Type> [d+1])))
-(OrB ((Less|Leq)8U  (Const8  [c]) x) (Leq8U  x (Const8  [d]))) && uint8(c)  >= uint8(d+1)  && uint8(d+1)  > uint8(d)  => ((Less|Leq)8U  (Const8  <x.Type> [c-d-1]) (Sub8  <x.Type> x (Const8  <x.Type> [d+1])))
-
-// Canonicalize x-const to x+(-const)
-(Sub64 x (Const64 <t> [c])) && x.Op != OpConst64 => (Add64 (Const64 <t> [-c]) x)
-(Sub32 x (Const32 <t> [c])) && x.Op != OpConst32 => (Add32 (Const32 <t> [-c]) x)
-(Sub16 x (Const16 <t> [c])) && x.Op != OpConst16 => (Add16 (Const16 <t> [-c]) x)
-(Sub8  x (Const8  <t> [c])) && x.Op != OpConst8  => (Add8  (Const8  <t> [-c]) x)
-
-// fold negation into comparison operators
-(Not (Eq(64|32|16|8|B|Ptr|64F|32F) x y)) => (Neq(64|32|16|8|B|Ptr|64F|32F) x y)
-(Not (Neq(64|32|16|8|B|Ptr|64F|32F) x y)) => (Eq(64|32|16|8|B|Ptr|64F|32F) x y)
-
-(Not (Less(64|32|16|8) x y)) => (Leq(64|32|16|8) y x)
-(Not (Less(64|32|16|8)U x y)) => (Leq(64|32|16|8)U y x)
-(Not (Leq(64|32|16|8) x y)) => (Less(64|32|16|8) y x)
-(Not (Leq(64|32|16|8)U x y)) => (Less(64|32|16|8)U y x)
-
-// Distribute multiplication c * (d+x) -> c*d + c*x. Useful for:
-// a[i].b = ...; a[i+1].b = ...
-(Mul64 (Const64 <t> [c]) (Add64 <t> (Const64 <t> [d]) x)) =>
-  (Add64 (Const64 <t> [c*d]) (Mul64 <t> (Const64 <t> [c]) x))
-(Mul32 (Const32 <t> [c]) (Add32 <t> (Const32 <t> [d]) x)) =>
-  (Add32 (Const32 <t> [c*d]) (Mul32 <t> (Const32 <t> [c]) x))
-
-// Rewrite x*y ± x*z  to  x*(y±z)
-(Add(64|32|16|8) <t> (Mul(64|32|16|8) x y) (Mul(64|32|16|8) x z))
-	=> (Mul(64|32|16|8) x (Add(64|32|16|8) <t> y z))
-(Sub(64|32|16|8) <t> (Mul(64|32|16|8) x y) (Mul(64|32|16|8) x z))
-	=> (Mul(64|32|16|8) x (Sub(64|32|16|8) <t> y z))
-
-// rewrite shifts of 8/16/32 bit consts into 64 bit consts to reduce
-// the number of the other rewrite rules for const shifts
-(Lsh64x32  <t> x (Const32 [c])) => (Lsh64x64  x (Const64 <t> [int64(uint32(c))]))
-(Lsh64x16  <t> x (Const16 [c])) => (Lsh64x64  x (Const64 <t> [int64(uint16(c))]))
-(Lsh64x8   <t> x (Const8  [c])) => (Lsh64x64  x (Const64 <t> [int64(uint8(c))]))
-(Rsh64x32  <t> x (Const32 [c])) => (Rsh64x64  x (Const64 <t> [int64(uint32(c))]))
-(Rsh64x16  <t> x (Const16 [c])) => (Rsh64x64  x (Const64 <t> [int64(uint16(c))]))
-(Rsh64x8   <t> x (Const8  [c])) => (Rsh64x64  x (Const64 <t> [int64(uint8(c))]))
-(Rsh64Ux32 <t> x (Const32 [c])) => (Rsh64Ux64 x (Const64 <t> [int64(uint32(c))]))
-(Rsh64Ux16 <t> x (Const16 [c])) => (Rsh64Ux64 x (Const64 <t> [int64(uint16(c))]))
-(Rsh64Ux8  <t> x (Const8  [c])) => (Rsh64Ux64 x (Const64 <t> [int64(uint8(c))]))
-
-(Lsh32x32  <t> x (Const32 [c])) => (Lsh32x64  x (Const64 <t> [int64(uint32(c))]))
-(Lsh32x16  <t> x (Const16 [c])) => (Lsh32x64  x (Const64 <t> [int64(uint16(c))]))
-(Lsh32x8   <t> x (Const8  [c])) => (Lsh32x64  x (Const64 <t> [int64(uint8(c))]))
-(Rsh32x32  <t> x (Const32 [c])) => (Rsh32x64  x (Const64 <t> [int64(uint32(c))]))
-(Rsh32x16  <t> x (Const16 [c])) => (Rsh32x64  x (Const64 <t> [int64(uint16(c))]))
-(Rsh32x8   <t> x (Const8  [c])) => (Rsh32x64  x (Const64 <t> [int64(uint8(c))]))
-(Rsh32Ux32 <t> x (Const32 [c])) => (Rsh32Ux64 x (Const64 <t> [int64(uint32(c))]))
-(Rsh32Ux16 <t> x (Const16 [c])) => (Rsh32Ux64 x (Const64 <t> [int64(uint16(c))]))
-(Rsh32Ux8  <t> x (Const8  [c])) => (Rsh32Ux64 x (Const64 <t> [int64(uint8(c))]))
-
-(Lsh16x32  <t> x (Const32 [c])) => (Lsh16x64  x (Const64 <t> [int64(uint32(c))]))
-(Lsh16x16  <t> x (Const16 [c])) => (Lsh16x64  x (Const64 <t> [int64(uint16(c))]))
-(Lsh16x8   <t> x (Const8  [c])) => (Lsh16x64  x (Const64 <t> [int64(uint8(c))]))
-(Rsh16x32  <t> x (Const32 [c])) => (Rsh16x64  x (Const64 <t> [int64(uint32(c))]))
-(Rsh16x16  <t> x (Const16 [c])) => (Rsh16x64  x (Const64 <t> [int64(uint16(c))]))
-(Rsh16x8   <t> x (Const8  [c])) => (Rsh16x64  x (Const64 <t> [int64(uint8(c))]))
-(Rsh16Ux32 <t> x (Const32 [c])) => (Rsh16Ux64 x (Const64 <t> [int64(uint32(c))]))
-(Rsh16Ux16 <t> x (Const16 [c])) => (Rsh16Ux64 x (Const64 <t> [int64(uint16(c))]))
-(Rsh16Ux8  <t> x (Const8  [c])) => (Rsh16Ux64 x (Const64 <t> [int64(uint8(c))]))
-
-(Lsh8x32  <t> x (Const32 [c])) => (Lsh8x64  x (Const64 <t> [int64(uint32(c))]))
-(Lsh8x16  <t> x (Const16 [c])) => (Lsh8x64  x (Const64 <t> [int64(uint16(c))]))
-(Lsh8x8   <t> x (Const8  [c])) => (Lsh8x64  x (Const64 <t> [int64(uint8(c))]))
-(Rsh8x32  <t> x (Const32 [c])) => (Rsh8x64  x (Const64 <t> [int64(uint32(c))]))
-(Rsh8x16  <t> x (Const16 [c])) => (Rsh8x64  x (Const64 <t> [int64(uint16(c))]))
-(Rsh8x8   <t> x (Const8  [c])) => (Rsh8x64  x (Const64 <t> [int64(uint8(c))]))
-(Rsh8Ux32 <t> x (Const32 [c])) => (Rsh8Ux64 x (Const64 <t> [int64(uint32(c))]))
-(Rsh8Ux16 <t> x (Const16 [c])) => (Rsh8Ux64 x (Const64 <t> [int64(uint16(c))]))
-(Rsh8Ux8  <t> x (Const8  [c])) => (Rsh8Ux64 x (Const64 <t> [int64(uint8(c))]))
-
-// shifts by zero
-(Lsh(64|32|16|8)x64  x (Const64 [0])) => x
-(Rsh(64|32|16|8)x64  x (Const64 [0])) => x
-(Rsh(64|32|16|8)Ux64 x (Const64 [0])) => x
-
-// rotates by multiples of register width
-(RotateLeft64 x (Const64 [c])) && c%64 == 0 => x
-(RotateLeft32 x (Const32 [c])) && c%32 == 0 => x
-(RotateLeft16 x (Const16 [c])) && c%16 == 0 => x
-(RotateLeft8  x (Const8 [c]))  && c%8  == 0 => x
-
-// zero shifted
-(Lsh64x(64|32|16|8)  (Const64 [0]) _) => (Const64 [0])
-(Rsh64x(64|32|16|8)  (Const64 [0]) _) => (Const64 [0])
-(Rsh64Ux(64|32|16|8) (Const64 [0]) _) => (Const64 [0])
-(Lsh32x(64|32|16|8)  (Const32 [0]) _) => (Const32 [0])
-(Rsh32x(64|32|16|8)  (Const32 [0]) _) => (Const32 [0])
-(Rsh32Ux(64|32|16|8) (Const32 [0]) _) => (Const32 [0])
-(Lsh16x(64|32|16|8)  (Const16 [0]) _) => (Const16 [0])
-(Rsh16x(64|32|16|8)  (Const16 [0]) _) => (Const16 [0])
-(Rsh16Ux(64|32|16|8) (Const16 [0]) _) => (Const16 [0])
-(Lsh8x(64|32|16|8)   (Const8  [0]) _) => (Const8  [0])
-(Rsh8x(64|32|16|8)   (Const8  [0]) _) => (Const8  [0])
-(Rsh8Ux(64|32|16|8)  (Const8  [0]) _) => (Const8  [0])
-
-// large left shifts of all values, and right shifts of unsigned values
-((Lsh64|Rsh64U)x64  _ (Const64 [c])) && uint64(c) >= 64 => (Const64 [0])
-((Lsh32|Rsh32U)x64  _ (Const64 [c])) && uint64(c) >= 32 => (Const32 [0])
-((Lsh16|Rsh16U)x64  _ (Const64 [c])) && uint64(c) >= 16 => (Const16 [0])
-((Lsh8|Rsh8U)x64    _ (Const64 [c])) && uint64(c) >= 8  => (Const8  [0])
-
-// combine const shifts
-(Lsh64x64 <t> (Lsh64x64 x (Const64 [c])) (Const64 [d])) && !uaddOvf(c,d) => (Lsh64x64 x (Const64 <t> [c+d]))
-(Lsh32x64 <t> (Lsh32x64 x (Const64 [c])) (Const64 [d])) && !uaddOvf(c,d) => (Lsh32x64 x (Const64 <t> [c+d]))
-(Lsh16x64 <t> (Lsh16x64 x (Const64 [c])) (Const64 [d])) && !uaddOvf(c,d) => (Lsh16x64 x (Const64 <t> [c+d]))
-(Lsh8x64  <t> (Lsh8x64  x (Const64 [c])) (Const64 [d])) && !uaddOvf(c,d) => (Lsh8x64  x (Const64 <t> [c+d]))
-
-(Rsh64x64 <t> (Rsh64x64 x (Const64 [c])) (Const64 [d])) && !uaddOvf(c,d) => (Rsh64x64 x (Const64 <t> [c+d]))
-(Rsh32x64 <t> (Rsh32x64 x (Const64 [c])) (Const64 [d])) && !uaddOvf(c,d) => (Rsh32x64 x (Const64 <t> [c+d]))
-(Rsh16x64 <t> (Rsh16x64 x (Const64 [c])) (Const64 [d])) && !uaddOvf(c,d) => (Rsh16x64 x (Const64 <t> [c+d]))
-(Rsh8x64  <t> (Rsh8x64  x (Const64 [c])) (Const64 [d])) && !uaddOvf(c,d) => (Rsh8x64  x (Const64 <t> [c+d]))
-
-(Rsh64Ux64 <t> (Rsh64Ux64 x (Const64 [c])) (Const64 [d])) && !uaddOvf(c,d) => (Rsh64Ux64 x (Const64 <t> [c+d]))
-(Rsh32Ux64 <t> (Rsh32Ux64 x (Const64 [c])) (Const64 [d])) && !uaddOvf(c,d) => (Rsh32Ux64 x (Const64 <t> [c+d]))
-(Rsh16Ux64 <t> (Rsh16Ux64 x (Const64 [c])) (Const64 [d])) && !uaddOvf(c,d) => (Rsh16Ux64 x (Const64 <t> [c+d]))
-(Rsh8Ux64  <t> (Rsh8Ux64  x (Const64 [c])) (Const64 [d])) && !uaddOvf(c,d) => (Rsh8Ux64  x (Const64 <t> [c+d]))
-
-// Remove signed right shift before an unsigned right shift that extracts the sign bit.
-(Rsh8Ux64  (Rsh8x64  x _) (Const64 <t> [7] )) => (Rsh8Ux64  x (Const64 <t> [7] ))
-(Rsh16Ux64 (Rsh16x64 x _) (Const64 <t> [15])) => (Rsh16Ux64 x (Const64 <t> [15]))
-(Rsh32Ux64 (Rsh32x64 x _) (Const64 <t> [31])) => (Rsh32Ux64 x (Const64 <t> [31]))
-(Rsh64Ux64 (Rsh64x64 x _) (Const64 <t> [63])) => (Rsh64Ux64 x (Const64 <t> [63]))
-
-// ((x >> c1) << c2) >> c3
-(Rsh(64|32|16|8)Ux64 (Lsh(64|32|16|8)x64 (Rsh(64|32|16|8)Ux64 x (Const64 [c1])) (Const64 [c2])) (Const64 [c3]))
-  && uint64(c1) >= uint64(c2) && uint64(c3) >= uint64(c2) && !uaddOvf(c1-c2, c3)
-  => (Rsh(64|32|16|8)Ux64 x (Const64 <typ.UInt64> [c1-c2+c3]))
-
-// ((x << c1) >> c2) << c3
-(Lsh(64|32|16|8)x64 (Rsh(64|32|16|8)Ux64 (Lsh(64|32|16|8)x64 x (Const64 [c1])) (Const64 [c2])) (Const64 [c3]))
-  && uint64(c1) >= uint64(c2) && uint64(c3) >= uint64(c2) && !uaddOvf(c1-c2, c3)
-  => (Lsh(64|32|16|8)x64 x (Const64 <typ.UInt64> [c1-c2+c3]))
-
-// (x >> c) & uppermask = 0
-(And64 (Const64 [m]) (Rsh64Ux64 _ (Const64 [c]))) && c >= int64(64-ntz64(m)) => (Const64 [0])
-(And32 (Const32 [m]) (Rsh32Ux64 _ (Const64 [c]))) && c >= int64(32-ntz32(m)) => (Const32 [0])
-(And16 (Const16 [m]) (Rsh16Ux64 _ (Const64 [c]))) && c >= int64(16-ntz16(m)) => (Const16 [0])
-(And8  (Const8  [m]) (Rsh8Ux64  _ (Const64 [c]))) && c >= int64(8-ntz8(m))  => (Const8  [0])
-
-// (x << c) & lowermask = 0
-(And64 (Const64 [m]) (Lsh64x64  _ (Const64 [c]))) && c >= int64(64-nlz64(m)) => (Const64 [0])
-(And32 (Const32 [m]) (Lsh32x64  _ (Const64 [c]))) && c >= int64(32-nlz32(m)) => (Const32 [0])
-(And16 (Const16 [m]) (Lsh16x64  _ (Const64 [c]))) && c >= int64(16-nlz16(m)) => (Const16 [0])
-(And8  (Const8  [m]) (Lsh8x64   _ (Const64 [c]))) && c >= int64(8-nlz8(m))  => (Const8  [0])
-
-// replace shifts with zero extensions
-(Rsh16Ux64 (Lsh16x64 x (Const64  [8])) (Const64  [8])) => (ZeroExt8to16  (Trunc16to8  <typ.UInt8>  x))
-(Rsh32Ux64 (Lsh32x64 x (Const64 [24])) (Const64 [24])) => (ZeroExt8to32  (Trunc32to8  <typ.UInt8>  x))
-(Rsh64Ux64 (Lsh64x64 x (Const64 [56])) (Const64 [56])) => (ZeroExt8to64  (Trunc64to8  <typ.UInt8>  x))
-(Rsh32Ux64 (Lsh32x64 x (Const64 [16])) (Const64 [16])) => (ZeroExt16to32 (Trunc32to16 <typ.UInt16> x))
-(Rsh64Ux64 (Lsh64x64 x (Const64 [48])) (Const64 [48])) => (ZeroExt16to64 (Trunc64to16 <typ.UInt16> x))
-(Rsh64Ux64 (Lsh64x64 x (Const64 [32])) (Const64 [32])) => (ZeroExt32to64 (Trunc64to32 <typ.UInt32> x))
-
-// replace shifts with sign extensions
-(Rsh16x64 (Lsh16x64 x (Const64  [8])) (Const64  [8])) => (SignExt8to16  (Trunc16to8  <typ.Int8>  x))
-(Rsh32x64 (Lsh32x64 x (Const64 [24])) (Const64 [24])) => (SignExt8to32  (Trunc32to8  <typ.Int8>  x))
-(Rsh64x64 (Lsh64x64 x (Const64 [56])) (Const64 [56])) => (SignExt8to64  (Trunc64to8  <typ.Int8>  x))
-(Rsh32x64 (Lsh32x64 x (Const64 [16])) (Const64 [16])) => (SignExt16to32 (Trunc32to16 <typ.Int16> x))
-(Rsh64x64 (Lsh64x64 x (Const64 [48])) (Const64 [48])) => (SignExt16to64 (Trunc64to16 <typ.Int16> x))
-(Rsh64x64 (Lsh64x64 x (Const64 [32])) (Const64 [32])) => (SignExt32to64 (Trunc64to32 <typ.Int32> x))
-
-// constant comparisons
-(Eq(64|32|16|8)   (Const(64|32|16|8) [c]) (Const(64|32|16|8) [d])) => (ConstBool [c == d])
-(Neq(64|32|16|8)  (Const(64|32|16|8) [c]) (Const(64|32|16|8) [d])) => (ConstBool [c != d])
-(Less(64|32|16|8) (Const(64|32|16|8) [c]) (Const(64|32|16|8) [d])) => (ConstBool [c < d])
-(Leq(64|32|16|8)  (Const(64|32|16|8) [c]) (Const(64|32|16|8) [d])) => (ConstBool [c <= d])
-
-(Less64U (Const64 [c]) (Const64 [d])) => (ConstBool [uint64(c) < uint64(d)])
-(Less32U (Const32 [c]) (Const32 [d])) => (ConstBool [uint32(c) < uint32(d)])
-(Less16U (Const16 [c]) (Const16 [d])) => (ConstBool [uint16(c) < uint16(d)])
-(Less8U  (Const8  [c]) (Const8  [d])) => (ConstBool [ uint8(c) <  uint8(d)])
-
-(Leq64U (Const64 [c]) (Const64 [d])) => (ConstBool [uint64(c) <= uint64(d)])
-(Leq32U (Const32 [c]) (Const32 [d])) => (ConstBool [uint32(c) <= uint32(d)])
-(Leq16U (Const16 [c]) (Const16 [d])) => (ConstBool [uint16(c) <= uint16(d)])
-(Leq8U  (Const8  [c]) (Const8  [d])) => (ConstBool [ uint8(c) <=  uint8(d)])
-
-(Leq8  (Const8  [0]) (And8  _ (Const8  [c]))) && c >= 0 => (ConstBool [true])
-(Leq16 (Const16 [0]) (And16 _ (Const16 [c]))) && c >= 0 => (ConstBool [true])
-(Leq32 (Const32 [0]) (And32 _ (Const32 [c]))) && c >= 0 => (ConstBool [true])
-(Leq64 (Const64 [0]) (And64 _ (Const64 [c]))) && c >= 0 => (ConstBool [true])
-
-(Leq8  (Const8  [0]) (Rsh8Ux64  _ (Const64 [c]))) && c > 0 => (ConstBool [true])
-(Leq16 (Const16 [0]) (Rsh16Ux64 _ (Const64 [c]))) && c > 0 => (ConstBool [true])
-(Leq32 (Const32 [0]) (Rsh32Ux64 _ (Const64 [c]))) && c > 0 => (ConstBool [true])
-(Leq64 (Const64 [0]) (Rsh64Ux64 _ (Const64 [c]))) && c > 0 => (ConstBool [true])
-
-(Less(64|32|16|8) (Const(64|32|16|8) <t> [0]) x) && isNonNegative(x) => (Neq(64|32|16|8) (Const(64|32|16|8) <t> [0]) x)
-(Less(64|32|16|8) x (Const(64|32|16|8) <t> [1])) && isNonNegative(x) => (Eq(64|32|16|8) (Const(64|32|16|8) <t> [0]) x)
-
-// constant floating point comparisons
-(Eq32F   (Const32F [c]) (Const32F [d])) => (ConstBool [c == d])
-(Eq64F   (Const64F [c]) (Const64F [d])) => (ConstBool [c == d])
-(Neq32F  (Const32F [c]) (Const32F [d])) => (ConstBool [c != d])
-(Neq64F  (Const64F [c]) (Const64F [d])) => (ConstBool [c != d])
-(Less32F (Const32F [c]) (Const32F [d])) => (ConstBool [c < d])
-(Less64F (Const64F [c]) (Const64F [d])) => (ConstBool [c < d])
-(Leq32F  (Const32F [c]) (Const32F [d])) => (ConstBool [c <= d])
-(Leq64F  (Const64F [c]) (Const64F [d])) => (ConstBool [c <= d])
-
-// simplifications
-(Or(64|32|16|8) x x) => x
-(Or(64|32|16|8) (Const(64|32|16|8)  [0]) x) => x
-(Or(64|32|16|8) (Const(64|32|16|8) [-1]) _) => (Const(64|32|16|8) [-1])
-(Or(64|32|16|8) (Com(64|32|16|8)     x)  x) => (Const(64|32|16|8) [-1])
-
-(And(64|32|16|8) x x) => x
-(And(64|32|16|8) (Const(64|32|16|8) [-1]) x) => x
-(And(64|32|16|8) (Const(64|32|16|8)  [0]) _) => (Const(64|32|16|8) [0])
-(And(64|32|16|8) (Com(64|32|16|8)     x)  x) => (Const(64|32|16|8) [0])
-
-(Xor(64|32|16|8) x x) => (Const(64|32|16|8) [0])
-(Xor(64|32|16|8) (Const(64|32|16|8) [0]) x) => x
-(Xor(64|32|16|8) (Com(64|32|16|8)    x)  x) => (Const(64|32|16|8) [-1])
-
-(Add(64|32|16|8) (Const(64|32|16|8) [0]) x) => x
-(Sub(64|32|16|8) x x) => (Const(64|32|16|8) [0])
-(Mul(64|32|16|8) (Const(64|32|16|8) [0]) _) => (Const(64|32|16|8) [0])
-
-(Com(64|32|16|8) (Com(64|32|16|8)  x)) => x
-(Com(64|32|16|8) (Const(64|32|16|8) [c])) => (Const(64|32|16|8) [^c])
-
-(Neg(64|32|16|8) (Sub(64|32|16|8) x y)) => (Sub(64|32|16|8) y x)
-(Add(64|32|16|8) x (Neg(64|32|16|8) y)) => (Sub(64|32|16|8) x y)
-
-(Xor(64|32|16|8) (Const(64|32|16|8) [-1]) x) => (Com(64|32|16|8) x)
-
-(Sub(64|32|16|8) (Neg(64|32|16|8) x) (Com(64|32|16|8) x)) => (Const(64|32|16|8) [1])
-(Sub(64|32|16|8) (Com(64|32|16|8) x) (Neg(64|32|16|8) x)) => (Const(64|32|16|8) [-1])
-(Add(64|32|16|8) (Com(64|32|16|8) x)                  x)  => (Const(64|32|16|8) [-1])
-
-// ^(x-1) == ^x+1 == -x
-(Add(64|32|16|8) (Const(64|32|16|8) [1]) (Com(64|32|16|8) x)) => (Neg(64|32|16|8) x)
-(Com(64|32|16|8) (Add(64|32|16|8) (Const(64|32|16|8) [-1]) x)) => (Neg(64|32|16|8) x)
-
-// -(-x) == x
-(Neg(64|32|16|8) (Neg(64|32|16|8) x)) => x
-
-// -^x == x+1
-(Neg(64|32|16|8) <t> (Com(64|32|16|8) x)) => (Add(64|32|16|8) (Const(64|32|16|8) <t> [1]) x)
-
-(And(64|32|16|8) x (And(64|32|16|8) x y)) => (And(64|32|16|8) x y)
-(Or(64|32|16|8) x (Or(64|32|16|8) x y)) => (Or(64|32|16|8) x y)
-(Xor(64|32|16|8) x (Xor(64|32|16|8) x y)) => y
-
-// Unsigned comparisons to zero.
-(Less(64U|32U|16U|8U) _ (Const(64|32|16|8) [0])) => (ConstBool [false])
-(Leq(64U|32U|16U|8U) (Const(64|32|16|8) [0]) _)  => (ConstBool [true])
-
-// Ands clear bits. Ors set bits.
-// If a subsequent Or will set all the bits
-// that an And cleared, we can skip the And.
-// This happens in bitmasking code like:
-//   x &^= 3 << shift // clear two old bits
-//   x  |= v << shift // set two new bits
-// when shift is a small constant and v ends up a constant 3.
-(Or8  (And8  x (Const8  [c2])) (Const8  <t> [c1])) && ^(c1 | c2) == 0 => (Or8  (Const8  <t> [c1]) x)
-(Or16 (And16 x (Const16 [c2])) (Const16 <t> [c1])) && ^(c1 | c2) == 0 => (Or16 (Const16 <t> [c1]) x)
-(Or32 (And32 x (Const32 [c2])) (Const32 <t> [c1])) && ^(c1 | c2) == 0 => (Or32 (Const32 <t> [c1]) x)
-(Or64 (And64 x (Const64 [c2])) (Const64 <t> [c1])) && ^(c1 | c2) == 0 => (Or64 (Const64 <t> [c1]) x)
-
-(Trunc64to8  (And64 (Const64 [y]) x)) && y&0xFF == 0xFF => (Trunc64to8 x)
-(Trunc64to16 (And64 (Const64 [y]) x)) && y&0xFFFF == 0xFFFF => (Trunc64to16 x)
-(Trunc64to32 (And64 (Const64 [y]) x)) && y&0xFFFFFFFF == 0xFFFFFFFF => (Trunc64to32 x)
-(Trunc32to8  (And32 (Const32 [y]) x)) && y&0xFF == 0xFF => (Trunc32to8 x)
-(Trunc32to16 (And32 (Const32 [y]) x)) && y&0xFFFF == 0xFFFF => (Trunc32to16 x)
-(Trunc16to8  (And16 (Const16 [y]) x)) && y&0xFF == 0xFF => (Trunc16to8 x)
-
-(ZeroExt8to64  (Trunc64to8  x:(Rsh64Ux64 _ (Const64 [s])))) && s >= 56 => x
-(ZeroExt16to64 (Trunc64to16 x:(Rsh64Ux64 _ (Const64 [s])))) && s >= 48 => x
-(ZeroExt32to64 (Trunc64to32 x:(Rsh64Ux64 _ (Const64 [s])))) && s >= 32 => x
-(ZeroExt8to32  (Trunc32to8  x:(Rsh32Ux64 _ (Const64 [s])))) && s >= 24 => x
-(ZeroExt16to32 (Trunc32to16 x:(Rsh32Ux64 _ (Const64 [s])))) && s >= 16 => x
-(ZeroExt8to16  (Trunc16to8  x:(Rsh16Ux64 _ (Const64 [s])))) && s >= 8 => x
-
-(SignExt8to64  (Trunc64to8  x:(Rsh64x64 _ (Const64 [s])))) && s >= 56 => x
-(SignExt16to64 (Trunc64to16 x:(Rsh64x64 _ (Const64 [s])))) && s >= 48 => x
-(SignExt32to64 (Trunc64to32 x:(Rsh64x64 _ (Const64 [s])))) && s >= 32 => x
-(SignExt8to32  (Trunc32to8  x:(Rsh32x64 _ (Const64 [s])))) && s >= 24 => x
-(SignExt16to32 (Trunc32to16 x:(Rsh32x64 _ (Const64 [s])))) && s >= 16 => x
-(SignExt8to16  (Trunc16to8  x:(Rsh16x64 _ (Const64 [s])))) && s >= 8 => x
-
-(Slicemask (Const32 [x])) && x > 0 => (Const32 [-1])
-(Slicemask (Const32 [0]))          => (Const32 [0])
-(Slicemask (Const64 [x])) && x > 0 => (Const64 [-1])
-(Slicemask (Const64 [0]))          => (Const64 [0])
-
-// simplifications often used for lengths.  e.g. len(s[i:i+5])==5
-(Sub(64|32|16|8) (Add(64|32|16|8) x y) x) => y
-(Sub(64|32|16|8) (Add(64|32|16|8) x y) y) => x
-(Sub(64|32|16|8) (Sub(64|32|16|8) x y) x) => (Neg(64|32|16|8) y)
-(Sub(64|32|16|8) x (Add(64|32|16|8) x y)) => (Neg(64|32|16|8) y)
-(Add(64|32|16|8) x (Sub(64|32|16|8) y x)) => y
-(Add(64|32|16|8) x (Add(64|32|16|8) y (Sub(64|32|16|8) z x))) => (Add(64|32|16|8) y z)
-
-// basic phi simplifications
-(Phi (Const8  [c]) (Const8  [c])) => (Const8  [c])
-(Phi (Const16 [c]) (Const16 [c])) => (Const16 [c])
-(Phi (Const32 [c]) (Const32 [c])) => (Const32 [c])
-(Phi (Const64 [c]) (Const64 [c])) => (Const64 [c])
-
-// slice and interface comparisons
-// The frontend ensures that we can only compare against nil,
-// so we need only compare the first word (interface type or slice ptr).
-(EqInter x y)  => (EqPtr  (ITab x) (ITab y))
-(NeqInter x y) => (NeqPtr (ITab x) (ITab y))
-(EqSlice x y)  => (EqPtr  (SlicePtr x) (SlicePtr y))
-(NeqSlice x y) => (NeqPtr (SlicePtr x) (SlicePtr y))
-
-// Load of store of same address, with compatibly typed value and same size
-(Load <t1> p1 (Store {t2} p2 x _))
-	&& isSamePtr(p1, p2)
-	&& t1.Compare(x.Type) == types.CMPeq
-	&& t1.Size() == t2.Size()
-	=> x
-(Load <t1> p1 (Store {t2} p2 _ (Store {t3} p3 x _)))
-	&& isSamePtr(p1, p3)
-	&& t1.Compare(x.Type) == types.CMPeq
-	&& t1.Size() == t2.Size()
-	&& disjoint(p3, t3.Size(), p2, t2.Size())
-	=> x
-(Load <t1> p1 (Store {t2} p2 _ (Store {t3} p3 _ (Store {t4} p4 x _))))
-	&& isSamePtr(p1, p4)
-	&& t1.Compare(x.Type) == types.CMPeq
-	&& t1.Size() == t2.Size()
-	&& disjoint(p4, t4.Size(), p2, t2.Size())
-	&& disjoint(p4, t4.Size(), p3, t3.Size())
-	=> x
-(Load <t1> p1 (Store {t2} p2 _ (Store {t3} p3 _ (Store {t4} p4 _ (Store {t5} p5 x _)))))
-	&& isSamePtr(p1, p5)
-	&& t1.Compare(x.Type) == types.CMPeq
-	&& t1.Size() == t2.Size()
-	&& disjoint(p5, t5.Size(), p2, t2.Size())
-	&& disjoint(p5, t5.Size(), p3, t3.Size())
-	&& disjoint(p5, t5.Size(), p4, t4.Size())
-	=> x
-
-// Pass constants through math.Float{32,64}bits and math.Float{32,64}frombits
-        (Load <t1> p1 (Store {t2} p2 (Const64  [x]) _)) && isSamePtr(p1,p2) && sizeof(t2) == 8 && is64BitFloat(t1) && !math.IsNaN(math.Float64frombits(uint64(x))) => (Const64F [math.Float64frombits(uint64(x))])
-        (Load <t1> p1 (Store {t2} p2 (Const32  [x]) _)) && isSamePtr(p1,p2) && sizeof(t2) == 4 && is32BitFloat(t1) && !math.IsNaN(float64(math.Float32frombits(uint32(x)))) => (Const32F [math.Float32frombits(uint32(x))])
-(Load <t1> p1 (Store {t2} p2 (Const64F [x]) _)) && isSamePtr(p1,p2) && sizeof(t2) == 8 && is64BitInt(t1)   => (Const64  [int64(math.Float64bits(x))])
-(Load <t1> p1 (Store {t2} p2 (Const32F [x]) _)) && isSamePtr(p1,p2) && sizeof(t2) == 4 && is32BitInt(t1)   => (Const32  [int32(math.Float32bits(x))])
-
-// Float Loads up to Zeros so they can be constant folded.
-(Load <t1> op:(OffPtr [o1] p1)
-	(Store {t2} p2 _
-		mem:(Zero [n] p3 _)))
-	&& o1 >= 0 && o1+t1.Size() <= n && isSamePtr(p1, p3)
-	&& fe.CanSSA(t1)
-	&& disjoint(op, t1.Size(), p2, t2.Size())
-	=> @mem.Block (Load <t1> (OffPtr <op.Type> [o1] p3) mem)
-(Load <t1> op:(OffPtr [o1] p1)
-	(Store {t2} p2 _
-		(Store {t3} p3 _
-			mem:(Zero [n] p4 _))))
-	&& o1 >= 0 && o1+t1.Size() <= n && isSamePtr(p1, p4)
-	&& fe.CanSSA(t1)
-	&& disjoint(op, t1.Size(), p2, t2.Size())
-	&& disjoint(op, t1.Size(), p3, t3.Size())
-	=> @mem.Block (Load <t1> (OffPtr <op.Type> [o1] p4) mem)
-(Load <t1> op:(OffPtr [o1] p1)
-	(Store {t2} p2 _
-		(Store {t3} p3 _
-			(Store {t4} p4 _
-				mem:(Zero [n] p5 _)))))
-	&& o1 >= 0 && o1+t1.Size() <= n && isSamePtr(p1, p5)
-	&& fe.CanSSA(t1)
-	&& disjoint(op, t1.Size(), p2, t2.Size())
-	&& disjoint(op, t1.Size(), p3, t3.Size())
-	&& disjoint(op, t1.Size(), p4, t4.Size())
-	=> @mem.Block (Load <t1> (OffPtr <op.Type> [o1] p5) mem)
-(Load <t1> op:(OffPtr [o1] p1)
-	(Store {t2} p2 _
-		(Store {t3} p3 _
-			(Store {t4} p4 _
-				(Store {t5} p5 _
-					mem:(Zero [n] p6 _))))))
-	&& o1 >= 0 && o1+t1.Size() <= n && isSamePtr(p1, p6)
-	&& fe.CanSSA(t1)
-	&& disjoint(op, t1.Size(), p2, t2.Size())
-	&& disjoint(op, t1.Size(), p3, t3.Size())
-	&& disjoint(op, t1.Size(), p4, t4.Size())
-	&& disjoint(op, t1.Size(), p5, t5.Size())
-	=> @mem.Block (Load <t1> (OffPtr <op.Type> [o1] p6) mem)
-
-// Zero to Load forwarding.
-(Load <t1> (OffPtr [o] p1) (Zero [n] p2 _))
-	&& t1.IsBoolean()
-	&& isSamePtr(p1, p2)
-	&& n >= o + 1
-	=> (ConstBool [false])
-(Load <t1> (OffPtr [o] p1) (Zero [n] p2 _))
-	&& is8BitInt(t1)
-	&& isSamePtr(p1, p2)
-	&& n >= o + 1
-	=> (Const8 [0])
-(Load <t1> (OffPtr [o] p1) (Zero [n] p2 _))
-	&& is16BitInt(t1)
-	&& isSamePtr(p1, p2)
-	&& n >= o + 2
-	=> (Const16 [0])
-(Load <t1> (OffPtr [o] p1) (Zero [n] p2 _))
-	&& is32BitInt(t1)
-	&& isSamePtr(p1, p2)
-	&& n >= o + 4
-	=> (Const32 [0])
-(Load <t1> (OffPtr [o] p1) (Zero [n] p2 _))
-	&& is64BitInt(t1)
-	&& isSamePtr(p1, p2)
-	&& n >= o + 8
-	=> (Const64 [0])
-(Load <t1> (OffPtr [o] p1) (Zero [n] p2 _))
-	&& is32BitFloat(t1)
-	&& isSamePtr(p1, p2)
-	&& n >= o + 4
-	=> (Const32F [0])
-(Load <t1> (OffPtr [o] p1) (Zero [n] p2 _))
-	&& is64BitFloat(t1)
-	&& isSamePtr(p1, p2)
-	&& n >= o + 8
-	=> (Const64F [0])
-
-// Eliminate stores of values that have just been loaded from the same location.
-// We also handle the common case where there are some intermediate stores.
-(Store {t1} p1 (Load <t2> p2 mem) mem)
-	&& isSamePtr(p1, p2)
-	&& t2.Size() == t1.Size()
-	=> mem
-(Store {t1} p1 (Load <t2> p2 oldmem) mem:(Store {t3} p3 _ oldmem))
-	&& isSamePtr(p1, p2)
-	&& t2.Size() == t1.Size()
-	&& disjoint(p1, t1.Size(), p3, t3.Size())
-	=> mem
-(Store {t1} p1 (Load <t2> p2 oldmem) mem:(Store {t3} p3 _ (Store {t4} p4 _ oldmem)))
-	&& isSamePtr(p1, p2)
-	&& t2.Size() == t1.Size()
-	&& disjoint(p1, t1.Size(), p3, t3.Size())
-	&& disjoint(p1, t1.Size(), p4, t4.Size())
-	=> mem
-(Store {t1} p1 (Load <t2> p2 oldmem) mem:(Store {t3} p3 _ (Store {t4} p4 _ (Store {t5} p5 _ oldmem))))
-	&& isSamePtr(p1, p2)
-	&& t2.Size() == t1.Size()
-	&& disjoint(p1, t1.Size(), p3, t3.Size())
-	&& disjoint(p1, t1.Size(), p4, t4.Size())
-	&& disjoint(p1, t1.Size(), p5, t5.Size())
-	=> mem
-
-// Don't Store zeros to cleared variables.
-(Store {t} (OffPtr [o] p1) x mem:(Zero [n] p2 _))
-	&& isConstZero(x)
-	&& o >= 0 && t.Size() + o <= n && isSamePtr(p1, p2)
-	=> mem
-(Store {t1} op:(OffPtr [o1] p1) x mem:(Store {t2} p2 _ (Zero [n] p3 _)))
-	&& isConstZero(x)
-	&& o1 >= 0 && t1.Size() + o1 <= n && isSamePtr(p1, p3)
-	&& disjoint(op, t1.Size(), p2, t2.Size())
-	=> mem
-(Store {t1} op:(OffPtr [o1] p1) x mem:(Store {t2} p2 _ (Store {t3} p3 _ (Zero [n] p4 _))))
-	&& isConstZero(x)
-	&& o1 >= 0 && t1.Size() + o1 <= n && isSamePtr(p1, p4)
-	&& disjoint(op, t1.Size(), p2, t2.Size())
-	&& disjoint(op, t1.Size(), p3, t3.Size())
-	=> mem
-(Store {t1} op:(OffPtr [o1] p1) x mem:(Store {t2} p2 _ (Store {t3} p3 _ (Store {t4} p4 _ (Zero [n] p5 _)))))
-	&& isConstZero(x)
-	&& o1 >= 0 && t1.Size() + o1 <= n && isSamePtr(p1, p5)
-	&& disjoint(op, t1.Size(), p2, t2.Size())
-	&& disjoint(op, t1.Size(), p3, t3.Size())
-	&& disjoint(op, t1.Size(), p4, t4.Size())
-	=> mem
-
-// Collapse OffPtr
-(OffPtr (OffPtr p [y]) [x]) => (OffPtr p [x+y])
-(OffPtr p [0]) && v.Type.Compare(p.Type) == types.CMPeq => p
-
-// indexing operations
-// Note: bounds check has already been done
-(PtrIndex <t> ptr idx) && config.PtrSize == 4 && is32Bit(t.Elem().Size()) => (AddPtr ptr (Mul32 <typ.Int> idx (Const32 <typ.Int> [int32(t.Elem().Size())])))
-(PtrIndex <t> ptr idx) && config.PtrSize == 8 => (AddPtr ptr (Mul64 <typ.Int> idx (Const64 <typ.Int> [t.Elem().Size()])))
-
-// struct operations
-(StructSelect (StructMake1 x)) => x
-(StructSelect [0] (StructMake2 x _)) => x
-(StructSelect [1] (StructMake2 _ x)) => x
-(StructSelect [0] (StructMake3 x _ _)) => x
-(StructSelect [1] (StructMake3 _ x _)) => x
-(StructSelect [2] (StructMake3 _ _ x)) => x
-(StructSelect [0] (StructMake4 x _ _ _)) => x
-(StructSelect [1] (StructMake4 _ x _ _)) => x
-(StructSelect [2] (StructMake4 _ _ x _)) => x
-(StructSelect [3] (StructMake4 _ _ _ x)) => x
-
-(Load <t> _ _) && t.IsStruct() && t.NumFields() == 0 && fe.CanSSA(t) =>
-  (StructMake0)
-(Load <t> ptr mem) && t.IsStruct() && t.NumFields() == 1 && fe.CanSSA(t) =>
-  (StructMake1
-    (Load <t.FieldType(0)> (OffPtr <t.FieldType(0).PtrTo()> [0] ptr) mem))
-(Load <t> ptr mem) && t.IsStruct() && t.NumFields() == 2 && fe.CanSSA(t) =>
-  (StructMake2
-    (Load <t.FieldType(0)> (OffPtr <t.FieldType(0).PtrTo()> [0]             ptr) mem)
-    (Load <t.FieldType(1)> (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] ptr) mem))
-(Load <t> ptr mem) && t.IsStruct() && t.NumFields() == 3 && fe.CanSSA(t) =>
-  (StructMake3
-    (Load <t.FieldType(0)> (OffPtr <t.FieldType(0).PtrTo()> [0]             ptr) mem)
-    (Load <t.FieldType(1)> (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] ptr) mem)
-    (Load <t.FieldType(2)> (OffPtr <t.FieldType(2).PtrTo()> [t.FieldOff(2)] ptr) mem))
-(Load <t> ptr mem) && t.IsStruct() && t.NumFields() == 4 && fe.CanSSA(t) =>
-  (StructMake4
-    (Load <t.FieldType(0)> (OffPtr <t.FieldType(0).PtrTo()> [0]             ptr) mem)
-    (Load <t.FieldType(1)> (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] ptr) mem)
-    (Load <t.FieldType(2)> (OffPtr <t.FieldType(2).PtrTo()> [t.FieldOff(2)] ptr) mem)
-    (Load <t.FieldType(3)> (OffPtr <t.FieldType(3).PtrTo()> [t.FieldOff(3)] ptr) mem))
-
-(StructSelect [i] x:(Load <t> ptr mem)) && !fe.CanSSA(t) =>
-  @x.Block (Load <v.Type> (OffPtr <v.Type.PtrTo()> [t.FieldOff(int(i))] ptr) mem)
-
-(Store _ (StructMake0) mem) => mem
-(Store dst (StructMake1 <t> f0) mem) =>
-  (Store {t.FieldType(0)} (OffPtr <t.FieldType(0).PtrTo()> [0] dst) f0 mem)
-(Store dst (StructMake2 <t> f0 f1) mem) =>
-  (Store {t.FieldType(1)}
-    (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst)
-    f1
-    (Store {t.FieldType(0)}
-      (OffPtr <t.FieldType(0).PtrTo()> [0] dst)
-        f0 mem))
-(Store dst (StructMake3 <t> f0 f1 f2) mem) =>
-  (Store {t.FieldType(2)}
-    (OffPtr <t.FieldType(2).PtrTo()> [t.FieldOff(2)] dst)
-    f2
-    (Store {t.FieldType(1)}
-      (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst)
-      f1
-      (Store {t.FieldType(0)}
-        (OffPtr <t.FieldType(0).PtrTo()> [0] dst)
-          f0 mem)))
-(Store dst (StructMake4 <t> f0 f1 f2 f3) mem) =>
-  (Store {t.FieldType(3)}
-    (OffPtr <t.FieldType(3).PtrTo()> [t.FieldOff(3)] dst)
-    f3
-    (Store {t.FieldType(2)}
-      (OffPtr <t.FieldType(2).PtrTo()> [t.FieldOff(2)] dst)
-      f2
-      (Store {t.FieldType(1)}
-        (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst)
-        f1
-        (Store {t.FieldType(0)}
-          (OffPtr <t.FieldType(0).PtrTo()> [0] dst)
-            f0 mem))))
-
-// Putting struct{*byte} and similar into direct interfaces.
-(IMake _typ (StructMake1 val)) => (IMake _typ val)
-(StructSelect [0] (IData x)) => (IData x)
-
-// un-SSAable values use mem->mem copies
-(Store {t} dst (Load src mem) mem) && !fe.CanSSA(t) =>
-	(Move {t} [t.Size()] dst src mem)
-(Store {t} dst (Load src mem) (VarDef {x} mem)) && !fe.CanSSA(t) =>
-	(Move {t} [t.Size()] dst src (VarDef {x} mem))
-
-// array ops
-(ArraySelect (ArrayMake1 x)) => x
-
-(Load <t> _ _) && t.IsArray() && t.NumElem() == 0 =>
-  (ArrayMake0)
-
-(Load <t> ptr mem) && t.IsArray() && t.NumElem() == 1 && fe.CanSSA(t) =>
-  (ArrayMake1 (Load <t.Elem()> ptr mem))
-
-(Store _ (ArrayMake0) mem) => mem
-(Store dst (ArrayMake1 e) mem) => (Store {e.Type} dst e mem)
-
-// Putting [1]*byte and similar into direct interfaces.
-(IMake _typ (ArrayMake1 val)) => (IMake _typ val)
-(ArraySelect [0] (IData x)) => (IData x)
-
-// string ops
-// Decomposing StringMake and lowering of StringPtr and StringLen
-// happens in a later pass, dec, so that these operations are available
-// to other passes for optimizations.
-(StringPtr (StringMake (Addr <t> {s} base) _)) => (Addr <t> {s} base)
-(StringLen (StringMake _ (Const64 <t> [c]))) => (Const64 <t> [c])
-(ConstString {str}) && config.PtrSize == 4 && str == "" =>
-  (StringMake (ConstNil) (Const32 <typ.Int> [0]))
-(ConstString {str}) && config.PtrSize == 8 && str == "" =>
-  (StringMake (ConstNil) (Const64 <typ.Int> [0]))
-(ConstString {str}) && config.PtrSize == 4 && str != "" =>
-  (StringMake
-    (Addr <typ.BytePtr> {fe.StringData(str)}
-      (SB))
-    (Const32 <typ.Int> [int32(len(str))]))
-(ConstString {str}) && config.PtrSize == 8 && str != "" =>
-  (StringMake
-    (Addr <typ.BytePtr> {fe.StringData(str)}
-      (SB))
-    (Const64 <typ.Int> [int64(len(str))]))
-
-// slice ops
-// Only a few slice rules are provided here.  See dec.rules for
-// a more comprehensive set.
-(SliceLen (SliceMake _ (Const64 <t> [c]) _)) => (Const64 <t> [c])
-(SliceCap (SliceMake _ _ (Const64 <t> [c]))) => (Const64 <t> [c])
-(SliceLen (SliceMake _ (Const32 <t> [c]) _)) => (Const32 <t> [c])
-(SliceCap (SliceMake _ _ (Const32 <t> [c]))) => (Const32 <t> [c])
-(SlicePtr (SliceMake (SlicePtr x) _ _)) => (SlicePtr x)
-(SliceLen (SliceMake _ (SliceLen x) _)) => (SliceLen x)
-(SliceCap (SliceMake _ _ (SliceCap x))) => (SliceCap x)
-(SliceCap (SliceMake _ _ (SliceLen x))) => (SliceLen x)
-(ConstSlice) && config.PtrSize == 4 =>
-  (SliceMake
-    (ConstNil <v.Type.Elem().PtrTo()>)
-    (Const32 <typ.Int> [0])
-    (Const32 <typ.Int> [0]))
-(ConstSlice) && config.PtrSize == 8 =>
-  (SliceMake
-    (ConstNil <v.Type.Elem().PtrTo()>)
-    (Const64 <typ.Int> [0])
-    (Const64 <typ.Int> [0]))
-
-// interface ops
-(ConstInterface) =>
-  (IMake
-    (ConstNil <typ.Uintptr>)
-    (ConstNil <typ.BytePtr>))
-
-(NilCheck (GetG mem) mem) => mem
-
-(If (Not cond) yes no) => (If cond no yes)
-(If (ConstBool [c]) yes no) && c => (First yes no)
-(If (ConstBool [c]) yes no) && !c => (First no yes)
-
-// Get rid of Convert ops for pointer arithmetic on unsafe.Pointer.
-(Convert (Add(64|32) (Convert ptr mem) off) mem) => (AddPtr ptr off)
-(Convert (Convert ptr mem) mem) => ptr
-
-// strength reduction of divide by a constant.
-// See ../magic.go for a detailed description of these algorithms.
-
-// Unsigned divide by power of 2.  Strength reduce to a shift.
-(Div8u  n (Const8  [c])) && isPowerOfTwo8(c)  => (Rsh8Ux64  n (Const64 <typ.UInt64> [log8(c)]))
-(Div16u n (Const16 [c])) && isPowerOfTwo16(c) => (Rsh16Ux64 n (Const64 <typ.UInt64> [log16(c)]))
-(Div32u n (Const32 [c])) && isPowerOfTwo32(c) => (Rsh32Ux64 n (Const64 <typ.UInt64> [log32(c)]))
-(Div64u n (Const64 [c])) && isPowerOfTwo64(c) => (Rsh64Ux64 n (Const64 <typ.UInt64> [log64(c)]))
-(Div64u n (Const64 [-1<<63]))                 => (Rsh64Ux64 n (Const64 <typ.UInt64> [63]))
-
-// Signed non-negative divide by power of 2.
-(Div8  n (Const8  [c])) && isNonNegative(n) && isPowerOfTwo8(c)  => (Rsh8Ux64  n (Const64 <typ.UInt64> [log8(c)]))
-(Div16 n (Const16 [c])) && isNonNegative(n) && isPowerOfTwo16(c) => (Rsh16Ux64 n (Const64 <typ.UInt64> [log16(c)]))
-(Div32 n (Const32 [c])) && isNonNegative(n) && isPowerOfTwo32(c) => (Rsh32Ux64 n (Const64 <typ.UInt64> [log32(c)]))
-(Div64 n (Const64 [c])) && isNonNegative(n) && isPowerOfTwo64(c) => (Rsh64Ux64 n (Const64 <typ.UInt64> [log64(c)]))
-(Div64 n (Const64 [-1<<63])) && isNonNegative(n)                 => (Const64 [0])
-
-// Unsigned divide, not a power of 2.  Strength reduce to a multiply.
-// For 8-bit divides, we just do a direct 9-bit by 8-bit multiply.
-(Div8u x (Const8 [c])) && umagicOK8(c) =>
-  (Trunc32to8
-    (Rsh32Ux64 <typ.UInt32>
-      (Mul32 <typ.UInt32>
-        (Const32 <typ.UInt32> [int32(1<<8+umagic8(c).m)])
-        (ZeroExt8to32 x))
-      (Const64 <typ.UInt64> [8+umagic8(c).s])))
-
-// For 16-bit divides on 64-bit machines, we do a direct 17-bit by 16-bit multiply.
-(Div16u x (Const16 [c])) && umagicOK16(c) && config.RegSize == 8 =>
-  (Trunc64to16
-    (Rsh64Ux64 <typ.UInt64>
-      (Mul64 <typ.UInt64>
-        (Const64 <typ.UInt64> [int64(1<<16+umagic16(c).m)])
-        (ZeroExt16to64 x))
-      (Const64 <typ.UInt64> [16+umagic16(c).s])))
-
-// For 16-bit divides on 32-bit machines
-(Div16u x (Const16 [c])) && umagicOK16(c) && config.RegSize == 4 && umagic16(c).m&1 == 0 =>
-  (Trunc32to16
-    (Rsh32Ux64 <typ.UInt32>
-      (Mul32 <typ.UInt32>
-        (Const32 <typ.UInt32> [int32(1<<15+umagic16(c).m/2)])
-        (ZeroExt16to32 x))
-      (Const64 <typ.UInt64> [16+umagic16(c).s-1])))
-(Div16u x (Const16 [c])) && umagicOK16(c) && config.RegSize == 4 && c&1 == 0 =>
-  (Trunc32to16
-    (Rsh32Ux64 <typ.UInt32>
-      (Mul32 <typ.UInt32>
-        (Const32 <typ.UInt32> [int32(1<<15+(umagic16(c).m+1)/2)])
-        (Rsh32Ux64 <typ.UInt32> (ZeroExt16to32 x) (Const64 <typ.UInt64> [1])))
-      (Const64 <typ.UInt64> [16+umagic16(c).s-2])))
-(Div16u x (Const16 [c])) && umagicOK16(c) && config.RegSize == 4 && config.useAvg =>
-  (Trunc32to16
-    (Rsh32Ux64 <typ.UInt32>
-      (Avg32u
-        (Lsh32x64 <typ.UInt32> (ZeroExt16to32 x) (Const64 <typ.UInt64> [16]))
-        (Mul32 <typ.UInt32>
-          (Const32 <typ.UInt32> [int32(umagic16(c).m)])
-          (ZeroExt16to32 x)))
-      (Const64 <typ.UInt64> [16+umagic16(c).s-1])))
-
-// For 32-bit divides on 32-bit machines
-(Div32u x (Const32 [c])) && umagicOK32(c) && config.RegSize == 4 && umagic32(c).m&1 == 0 && config.useHmul =>
-  (Rsh32Ux64 <typ.UInt32>
-    (Hmul32u <typ.UInt32>
-      (Const32 <typ.UInt32> [int32(1<<31+umagic32(c).m/2)])
-      x)
-    (Const64 <typ.UInt64> [umagic32(c).s-1]))
-(Div32u x (Const32 [c])) && umagicOK32(c) && config.RegSize == 4 && c&1 == 0 && config.useHmul =>
-  (Rsh32Ux64 <typ.UInt32>
-    (Hmul32u <typ.UInt32>
-      (Const32 <typ.UInt32> [int32(1<<31+(umagic32(c).m+1)/2)])
-      (Rsh32Ux64 <typ.UInt32> x (Const64 <typ.UInt64> [1])))
-    (Const64 <typ.UInt64> [umagic32(c).s-2]))
-(Div32u x (Const32 [c])) && umagicOK32(c) && config.RegSize == 4 && config.useAvg && config.useHmul =>
-  (Rsh32Ux64 <typ.UInt32>
-    (Avg32u
-      x
-      (Hmul32u <typ.UInt32>
-        (Const32 <typ.UInt32> [int32(umagic32(c).m)])
-        x))
-    (Const64 <typ.UInt64> [umagic32(c).s-1]))
-
-// For 32-bit divides on 64-bit machines
-// We'll use a regular (non-hi) multiply for this case.
-(Div32u x (Const32 [c])) && umagicOK32(c) && config.RegSize == 8 && umagic32(c).m&1 == 0 =>
-  (Trunc64to32
-    (Rsh64Ux64 <typ.UInt64>
-      (Mul64 <typ.UInt64>
-        (Const64 <typ.UInt64> [int64(1<<31+umagic32(c).m/2)])
-        (ZeroExt32to64 x))
-      (Const64 <typ.UInt64> [32+umagic32(c).s-1])))
-(Div32u x (Const32 [c])) && umagicOK32(c) && config.RegSize == 8 && c&1 == 0 =>
-  (Trunc64to32
-    (Rsh64Ux64 <typ.UInt64>
-      (Mul64 <typ.UInt64>
-        (Const64 <typ.UInt64> [int64(1<<31+(umagic32(c).m+1)/2)])
-        (Rsh64Ux64 <typ.UInt64> (ZeroExt32to64 x) (Const64 <typ.UInt64> [1])))
-      (Const64 <typ.UInt64> [32+umagic32(c).s-2])))
-(Div32u x (Const32 [c])) && umagicOK32(c) && config.RegSize == 8 && config.useAvg =>
-  (Trunc64to32
-    (Rsh64Ux64 <typ.UInt64>
-      (Avg64u
-        (Lsh64x64 <typ.UInt64> (ZeroExt32to64 x) (Const64 <typ.UInt64> [32]))
-        (Mul64 <typ.UInt64>
-          (Const64 <typ.UInt32> [int64(umagic32(c).m)])
-          (ZeroExt32to64 x)))
-      (Const64 <typ.UInt64> [32+umagic32(c).s-1])))
-
-// For unsigned 64-bit divides on 32-bit machines,
-// if the constant fits in 16 bits (so that the last term
-// fits in 32 bits), convert to three 32-bit divides by a constant.
-//
-// If 1<<32 = Q * c + R
-// and    x = hi << 32 + lo
-//
-// Then x = (hi/c*c + hi%c) << 32 + lo
-//        = hi/c*c<<32 + hi%c<<32 + lo
-//        = hi/c*c<<32 + (hi%c)*(Q*c+R) + lo/c*c + lo%c
-//        = hi/c*c<<32 + (hi%c)*Q*c + lo/c*c + (hi%c*R+lo%c)
-// and x / c = (hi/c)<<32 + (hi%c)*Q + lo/c + (hi%c*R+lo%c)/c
-(Div64u x (Const64 [c])) && c > 0 && c <= 0xFFFF && umagicOK32(int32(c)) && config.RegSize == 4 && config.useHmul =>
-  (Add64
-    (Add64 <typ.UInt64>
-      (Add64 <typ.UInt64>
-        (Lsh64x64 <typ.UInt64>
-          (ZeroExt32to64
-            (Div32u <typ.UInt32>
-              (Trunc64to32 <typ.UInt32> (Rsh64Ux64 <typ.UInt64> x (Const64 <typ.UInt64> [32])))
-              (Const32 <typ.UInt32> [int32(c)])))
-          (Const64 <typ.UInt64> [32]))
-        (ZeroExt32to64 (Div32u <typ.UInt32> (Trunc64to32 <typ.UInt32> x) (Const32 <typ.UInt32> [int32(c)]))))
-      (Mul64 <typ.UInt64>
-        (ZeroExt32to64 <typ.UInt64>
-          (Mod32u <typ.UInt32>
-            (Trunc64to32 <typ.UInt32> (Rsh64Ux64 <typ.UInt64> x (Const64 <typ.UInt64> [32])))
-            (Const32 <typ.UInt32> [int32(c)])))
-        (Const64 <typ.UInt64> [int64((1<<32)/c)])))
-      (ZeroExt32to64
-        (Div32u <typ.UInt32>
-          (Add32 <typ.UInt32>
-            (Mod32u <typ.UInt32> (Trunc64to32 <typ.UInt32> x) (Const32 <typ.UInt32> [int32(c)]))
-            (Mul32 <typ.UInt32>
-              (Mod32u <typ.UInt32>
-                (Trunc64to32 <typ.UInt32> (Rsh64Ux64 <typ.UInt64> x (Const64 <typ.UInt64> [32])))
-                (Const32 <typ.UInt32> [int32(c)]))
-              (Const32 <typ.UInt32> [int32((1<<32)%c)])))
-          (Const32 <typ.UInt32> [int32(c)]))))
-
-// For 64-bit divides on 64-bit machines
-// (64-bit divides on 32-bit machines are lowered to a runtime call by the walk pass.)
-(Div64u x (Const64 [c])) && umagicOK64(c) && config.RegSize == 8 && umagic64(c).m&1 == 0 && config.useHmul =>
-  (Rsh64Ux64 <typ.UInt64>
-    (Hmul64u <typ.UInt64>
-      (Const64 <typ.UInt64> [int64(1<<63+umagic64(c).m/2)])
-      x)
-    (Const64 <typ.UInt64> [umagic64(c).s-1]))
-(Div64u x (Const64 [c])) && umagicOK64(c) && config.RegSize == 8 && c&1 == 0 && config.useHmul =>
-  (Rsh64Ux64 <typ.UInt64>
-    (Hmul64u <typ.UInt64>
-      (Const64 <typ.UInt64> [int64(1<<63+(umagic64(c).m+1)/2)])
-      (Rsh64Ux64 <typ.UInt64> x (Const64 <typ.UInt64> [1])))
-    (Const64 <typ.UInt64> [umagic64(c).s-2]))
-(Div64u x (Const64 [c])) && umagicOK64(c) && config.RegSize == 8 && config.useAvg && config.useHmul =>
-  (Rsh64Ux64 <typ.UInt64>
-    (Avg64u
-      x
-      (Hmul64u <typ.UInt64>
-        (Const64 <typ.UInt64> [int64(umagic64(c).m)])
-        x))
-    (Const64 <typ.UInt64> [umagic64(c).s-1]))
-
-// Signed divide by a negative constant.  Rewrite to divide by a positive constant.
-(Div8  <t> n (Const8  [c])) && c < 0 && c != -1<<7  => (Neg8  (Div8  <t> n (Const8  <t> [-c])))
-(Div16 <t> n (Const16 [c])) && c < 0 && c != -1<<15 => (Neg16 (Div16 <t> n (Const16 <t> [-c])))
-(Div32 <t> n (Const32 [c])) && c < 0 && c != -1<<31 => (Neg32 (Div32 <t> n (Const32 <t> [-c])))
-(Div64 <t> n (Const64 [c])) && c < 0 && c != -1<<63 => (Neg64 (Div64 <t> n (Const64 <t> [-c])))
-
-// Dividing by the most-negative number.  Result is always 0 except
-// if the input is also the most-negative number.
-// We can detect that using the sign bit of x & -x.
-(Div8  <t> x (Const8  [-1<<7 ])) => (Rsh8Ux64  (And8  <t> x (Neg8  <t> x)) (Const64 <typ.UInt64> [7 ]))
-(Div16 <t> x (Const16 [-1<<15])) => (Rsh16Ux64 (And16 <t> x (Neg16 <t> x)) (Const64 <typ.UInt64> [15]))
-(Div32 <t> x (Const32 [-1<<31])) => (Rsh32Ux64 (And32 <t> x (Neg32 <t> x)) (Const64 <typ.UInt64> [31]))
-(Div64 <t> x (Const64 [-1<<63])) => (Rsh64Ux64 (And64 <t> x (Neg64 <t> x)) (Const64 <typ.UInt64> [63]))
-
-// Signed divide by power of 2.
-// n / c =       n >> log(c) if n >= 0
-//       = (n+c-1) >> log(c) if n < 0
-// We conditionally add c-1 by adding n>>63>>(64-log(c)) (first shift signed, second shift unsigned).
-(Div8  <t> n (Const8  [c])) && isPowerOfTwo8(c) =>
-  (Rsh8x64
-    (Add8  <t> n (Rsh8Ux64  <t> (Rsh8x64  <t> n (Const64 <typ.UInt64> [ 7])) (Const64 <typ.UInt64> [int64( 8-log8(c))])))
-    (Const64 <typ.UInt64> [int64(log8(c))]))
-(Div16 <t> n (Const16 [c])) && isPowerOfTwo16(c) =>
-  (Rsh16x64
-    (Add16 <t> n (Rsh16Ux64 <t> (Rsh16x64 <t> n (Const64 <typ.UInt64> [15])) (Const64 <typ.UInt64> [int64(16-log16(c))])))
-    (Const64 <typ.UInt64> [int64(log16(c))]))
-(Div32 <t> n (Const32 [c])) && isPowerOfTwo32(c) =>
-  (Rsh32x64
-    (Add32 <t> n (Rsh32Ux64 <t> (Rsh32x64 <t> n (Const64 <typ.UInt64> [31])) (Const64 <typ.UInt64> [int64(32-log32(c))])))
-    (Const64 <typ.UInt64> [int64(log32(c))]))
-(Div64 <t> n (Const64 [c])) && isPowerOfTwo64(c) =>
-  (Rsh64x64
-    (Add64 <t> n (Rsh64Ux64 <t> (Rsh64x64 <t> n (Const64 <typ.UInt64> [63])) (Const64 <typ.UInt64> [int64(64-log64(c))])))
-    (Const64 <typ.UInt64> [int64(log64(c))]))
-
-// Signed divide, not a power of 2.  Strength reduce to a multiply.
-(Div8 <t> x (Const8 [c])) && smagicOK8(c) =>
-  (Sub8 <t>
-    (Rsh32x64 <t>
-      (Mul32 <typ.UInt32>
-        (Const32 <typ.UInt32> [int32(smagic8(c).m)])
-        (SignExt8to32 x))
-      (Const64 <typ.UInt64> [8+smagic8(c).s]))
-    (Rsh32x64 <t>
-      (SignExt8to32 x)
-      (Const64 <typ.UInt64> [31])))
-(Div16 <t> x (Const16 [c])) && smagicOK16(c) =>
-  (Sub16 <t>
-    (Rsh32x64 <t>
-      (Mul32 <typ.UInt32>
-        (Const32 <typ.UInt32> [int32(smagic16(c).m)])
-        (SignExt16to32 x))
-      (Const64 <typ.UInt64> [16+smagic16(c).s]))
-    (Rsh32x64 <t>
-      (SignExt16to32 x)
-      (Const64 <typ.UInt64> [31])))
-(Div32 <t> x (Const32 [c])) && smagicOK32(c) && config.RegSize == 8 =>
-  (Sub32 <t>
-    (Rsh64x64 <t>
-      (Mul64 <typ.UInt64>
-        (Const64 <typ.UInt64> [int64(smagic32(c).m)])
-        (SignExt32to64 x))
-      (Const64 <typ.UInt64> [32+smagic32(c).s]))
-    (Rsh64x64 <t>
-      (SignExt32to64 x)
-      (Const64 <typ.UInt64> [63])))
-(Div32 <t> x (Const32 [c])) && smagicOK32(c) && config.RegSize == 4 && smagic32(c).m&1 == 0 && config.useHmul =>
-  (Sub32 <t>
-    (Rsh32x64 <t>
-      (Hmul32 <t>
-        (Const32 <typ.UInt32> [int32(smagic32(c).m/2)])
-        x)
-      (Const64 <typ.UInt64> [smagic32(c).s-1]))
-    (Rsh32x64 <t>
-      x
-      (Const64 <typ.UInt64> [31])))
-(Div32 <t> x (Const32 [c])) && smagicOK32(c) && config.RegSize == 4 && smagic32(c).m&1 != 0 && config.useHmul =>
-  (Sub32 <t>
-    (Rsh32x64 <t>
-      (Add32 <t>
-        (Hmul32 <t>
-          (Const32 <typ.UInt32> [int32(smagic32(c).m)])
-          x)
-        x)
-      (Const64 <typ.UInt64> [smagic32(c).s]))
-    (Rsh32x64 <t>
-      x
-      (Const64 <typ.UInt64> [31])))
-(Div64 <t> x (Const64 [c])) && smagicOK64(c) && smagic64(c).m&1 == 0 && config.useHmul =>
-  (Sub64 <t>
-    (Rsh64x64 <t>
-      (Hmul64 <t>
-        (Const64 <typ.UInt64> [int64(smagic64(c).m/2)])
-        x)
-      (Const64 <typ.UInt64> [smagic64(c).s-1]))
-    (Rsh64x64 <t>
-      x
-      (Const64 <typ.UInt64> [63])))
-(Div64 <t> x (Const64 [c])) && smagicOK64(c) && smagic64(c).m&1 != 0 && config.useHmul =>
-  (Sub64 <t>
-    (Rsh64x64 <t>
-      (Add64 <t>
-        (Hmul64 <t>
-          (Const64 <typ.UInt64> [int64(smagic64(c).m)])
-          x)
-        x)
-      (Const64 <typ.UInt64> [smagic64(c).s]))
-    (Rsh64x64 <t>
-      x
-      (Const64 <typ.UInt64> [63])))
-
-// Unsigned mod by power of 2 constant.
-(Mod8u  <t> n (Const8  [c])) && isPowerOfTwo8(c)  => (And8  n (Const8  <t> [c-1]))
-(Mod16u <t> n (Const16 [c])) && isPowerOfTwo16(c) => (And16 n (Const16 <t> [c-1]))
-(Mod32u <t> n (Const32 [c])) && isPowerOfTwo32(c) => (And32 n (Const32 <t> [c-1]))
-(Mod64u <t> n (Const64 [c])) && isPowerOfTwo64(c) => (And64 n (Const64 <t> [c-1]))
-(Mod64u <t> n (Const64 [-1<<63]))                 => (And64 n (Const64 <t> [1<<63-1]))
-
-// Signed non-negative mod by power of 2 constant.
-(Mod8  <t> n (Const8  [c])) && isNonNegative(n) && isPowerOfTwo8(c)  => (And8  n (Const8  <t> [c-1]))
-(Mod16 <t> n (Const16 [c])) && isNonNegative(n) && isPowerOfTwo16(c) => (And16 n (Const16 <t> [c-1]))
-(Mod32 <t> n (Const32 [c])) && isNonNegative(n) && isPowerOfTwo32(c) => (And32 n (Const32 <t> [c-1]))
-(Mod64 <t> n (Const64 [c])) && isNonNegative(n) && isPowerOfTwo64(c) => (And64 n (Const64 <t> [c-1]))
-(Mod64 n (Const64 [-1<<63])) && isNonNegative(n)                   => n
-
-// Signed mod by negative constant.
-(Mod8  <t> n (Const8  [c])) && c < 0 && c != -1<<7  => (Mod8  <t> n (Const8  <t> [-c]))
-(Mod16 <t> n (Const16 [c])) && c < 0 && c != -1<<15 => (Mod16 <t> n (Const16 <t> [-c]))
-(Mod32 <t> n (Const32 [c])) && c < 0 && c != -1<<31 => (Mod32 <t> n (Const32 <t> [-c]))
-(Mod64 <t> n (Const64 [c])) && c < 0 && c != -1<<63 => (Mod64 <t> n (Const64 <t> [-c]))
-
-// All other mods by constants, do A%B = A-(A/B*B).
-// This implements % with two * and a bunch of ancillary ops.
-// One of the * is free if the user's code also computes A/B.
-(Mod8   <t> x (Const8  [c])) && x.Op != OpConst8  && (c > 0 || c == -1<<7)
-  => (Sub8  x (Mul8  <t> (Div8   <t> x (Const8  <t> [c])) (Const8  <t> [c])))
-(Mod16  <t> x (Const16 [c])) && x.Op != OpConst16 && (c > 0 || c == -1<<15)
-  => (Sub16 x (Mul16 <t> (Div16  <t> x (Const16 <t> [c])) (Const16 <t> [c])))
-(Mod32  <t> x (Const32 [c])) && x.Op != OpConst32 && (c > 0 || c == -1<<31)
-  => (Sub32 x (Mul32 <t> (Div32  <t> x (Const32 <t> [c])) (Const32 <t> [c])))
-(Mod64  <t> x (Const64 [c])) && x.Op != OpConst64 && (c > 0 || c == -1<<63)
-  => (Sub64 x (Mul64 <t> (Div64  <t> x (Const64 <t> [c])) (Const64 <t> [c])))
-(Mod8u  <t> x (Const8  [c])) && x.Op != OpConst8  && c > 0 && umagicOK8( c)
-  => (Sub8  x (Mul8  <t> (Div8u  <t> x (Const8  <t> [c])) (Const8  <t> [c])))
-(Mod16u <t> x (Const16 [c])) && x.Op != OpConst16 && c > 0 && umagicOK16(c)
-  => (Sub16 x (Mul16 <t> (Div16u <t> x (Const16 <t> [c])) (Const16 <t> [c])))
-(Mod32u <t> x (Const32 [c])) && x.Op != OpConst32 && c > 0 && umagicOK32(c)
-  => (Sub32 x (Mul32 <t> (Div32u <t> x (Const32 <t> [c])) (Const32 <t> [c])))
-(Mod64u <t> x (Const64 [c])) && x.Op != OpConst64 && c > 0 && umagicOK64(c)
-  => (Sub64 x (Mul64 <t> (Div64u <t> x (Const64 <t> [c])) (Const64 <t> [c])))
-
-// For architectures without rotates on less than 32-bits, promote these checks to 32-bit.
-(Eq8 (Mod8u x (Const8  [c])) (Const8 [0])) && x.Op != OpConst8 && udivisibleOK8(c) && !hasSmallRotate(config) =>
-	(Eq32 (Mod32u <typ.UInt32> (ZeroExt8to32 <typ.UInt32> x) (Const32 <typ.UInt32> [int32(uint8(c))])) (Const32 <typ.UInt32> [0]))
-(Eq16 (Mod16u x (Const16  [c])) (Const16 [0])) && x.Op != OpConst16 && udivisibleOK16(c) && !hasSmallRotate(config) =>
-	(Eq32 (Mod32u <typ.UInt32> (ZeroExt16to32 <typ.UInt32> x) (Const32 <typ.UInt32> [int32(uint16(c))])) (Const32 <typ.UInt32> [0]))
-(Eq8 (Mod8 x (Const8  [c])) (Const8 [0])) && x.Op != OpConst8 && sdivisibleOK8(c) && !hasSmallRotate(config) =>
-	(Eq32 (Mod32 <typ.Int32> (SignExt8to32 <typ.Int32> x) (Const32 <typ.Int32> [int32(c)])) (Const32 <typ.Int32> [0]))
-(Eq16 (Mod16 x (Const16  [c])) (Const16 [0])) && x.Op != OpConst16 && sdivisibleOK16(c) && !hasSmallRotate(config) =>
-	(Eq32 (Mod32 <typ.Int32> (SignExt16to32 <typ.Int32> x) (Const32 <typ.Int32> [int32(c)])) (Const32 <typ.Int32> [0]))
-
-// Divisibility checks x%c == 0 convert to multiply and rotate.
-// Note, x%c == 0 is rewritten as x == c*(x/c) during the opt pass
-// where (x/c) is performed using multiplication with magic constants.
-// To rewrite x%c == 0 requires pattern matching the rewritten expression
-// and checking that the division by the same constant wasn't already calculated.
-// This check is made by counting uses of the magic constant multiplication.
-// Note that if there were an intermediate opt pass, this rule could be applied
-// directly on the Div op and magic division rewrites could be delayed to late opt.
-
-// Unsigned divisibility checks convert to multiply and rotate.
-(Eq8 x (Mul8 (Const8 [c])
-  (Trunc32to8
-    (Rsh32Ux64
-      mul:(Mul32
-        (Const32 [m])
-        (ZeroExt8to32 x))
-      (Const64 [s])))
-	)
-)
-  && v.Block.Func.pass.name != "opt" && mul.Uses == 1
-  && m == int32(1<<8+umagic8(c).m) && s == 8+umagic8(c).s
-  && x.Op != OpConst8 && udivisibleOK8(c)
- => (Leq8U
-			(RotateLeft8 <typ.UInt8>
-				(Mul8 <typ.UInt8>
-					(Const8 <typ.UInt8> [int8(udivisible8(c).m)])
-					x)
-				(Const8 <typ.UInt8> [int8(8-udivisible8(c).k)])
-				)
-			(Const8 <typ.UInt8> [int8(udivisible8(c).max)])
-		)
-
-(Eq16 x (Mul16 (Const16 [c])
-  (Trunc64to16
-    (Rsh64Ux64
-      mul:(Mul64
-        (Const64 [m])
-        (ZeroExt16to64 x))
-      (Const64 [s])))
-	)
-)
-  && v.Block.Func.pass.name != "opt" && mul.Uses == 1
-  && m == int64(1<<16+umagic16(c).m) && s == 16+umagic16(c).s
-  && x.Op != OpConst16 && udivisibleOK16(c)
- => (Leq16U
-			(RotateLeft16 <typ.UInt16>
-				(Mul16 <typ.UInt16>
-					(Const16 <typ.UInt16> [int16(udivisible16(c).m)])
-					x)
-				(Const16 <typ.UInt16> [int16(16-udivisible16(c).k)])
-				)
-			(Const16 <typ.UInt16> [int16(udivisible16(c).max)])
-		)
-
-(Eq16 x (Mul16 (Const16 [c])
-  (Trunc32to16
-    (Rsh32Ux64
-      mul:(Mul32
-        (Const32 [m])
-        (ZeroExt16to32 x))
-      (Const64 [s])))
-	)
-)
-  && v.Block.Func.pass.name != "opt" && mul.Uses == 1
-  && m == int32(1<<15+umagic16(c).m/2) && s == 16+umagic16(c).s-1
-  && x.Op != OpConst16 && udivisibleOK16(c)
- => (Leq16U
-			(RotateLeft16 <typ.UInt16>
-				(Mul16 <typ.UInt16>
-					(Const16 <typ.UInt16> [int16(udivisible16(c).m)])
-					x)
-				(Const16 <typ.UInt16> [int16(16-udivisible16(c).k)])
-				)
-			(Const16 <typ.UInt16> [int16(udivisible16(c).max)])
-		)
-
-(Eq16 x (Mul16 (Const16 [c])
-  (Trunc32to16
-    (Rsh32Ux64
-      mul:(Mul32
-        (Const32 [m])
-        (Rsh32Ux64 (ZeroExt16to32 x) (Const64 [1])))
-      (Const64 [s])))
-	)
-)
-  && v.Block.Func.pass.name != "opt" && mul.Uses == 1
-  && m == int32(1<<15+(umagic16(c).m+1)/2) && s == 16+umagic16(c).s-2
-  && x.Op != OpConst16 && udivisibleOK16(c)
- => (Leq16U
-			(RotateLeft16 <typ.UInt16>
-				(Mul16 <typ.UInt16>
-					(Const16 <typ.UInt16> [int16(udivisible16(c).m)])
-					x)
-				(Const16 <typ.UInt16> [int16(16-udivisible16(c).k)])
-				)
-			(Const16 <typ.UInt16> [int16(udivisible16(c).max)])
-		)
-
-(Eq16 x (Mul16 (Const16 [c])
-  (Trunc32to16
-    (Rsh32Ux64
-      (Avg32u
-        (Lsh32x64 (ZeroExt16to32 x) (Const64 [16]))
-        mul:(Mul32
-          (Const32 [m])
-          (ZeroExt16to32 x)))
-      (Const64 [s])))
-	)
-)
-  && v.Block.Func.pass.name != "opt" && mul.Uses == 1
-  && m == int32(umagic16(c).m) && s == 16+umagic16(c).s-1
-  && x.Op != OpConst16 && udivisibleOK16(c)
- => (Leq16U
-			(RotateLeft16 <typ.UInt16>
-				(Mul16 <typ.UInt16>
-					(Const16 <typ.UInt16> [int16(udivisible16(c).m)])
-					x)
-				(Const16 <typ.UInt16> [int16(16-udivisible16(c).k)])
-				)
-			(Const16 <typ.UInt16> [int16(udivisible16(c).max)])
-		)
-
-(Eq32 x (Mul32 (Const32 [c])
-	(Rsh32Ux64
-		mul:(Hmul32u
-			(Const32 [m])
-			x)
-		(Const64 [s]))
-	)
-)
-  && v.Block.Func.pass.name != "opt" && mul.Uses == 1
-  && m == int32(1<<31+umagic32(c).m/2) && s == umagic32(c).s-1
-	&& x.Op != OpConst32 && udivisibleOK32(c)
- => (Leq32U
-			(RotateLeft32 <typ.UInt32>
-				(Mul32 <typ.UInt32>
-					(Const32 <typ.UInt32> [int32(udivisible32(c).m)])
-					x)
-				(Const32 <typ.UInt32> [int32(32-udivisible32(c).k)])
-				)
-			(Const32 <typ.UInt32> [int32(udivisible32(c).max)])
-		)
-
-(Eq32 x (Mul32 (Const32 [c])
-  (Rsh32Ux64
-    mul:(Hmul32u
-      (Const32 <typ.UInt32> [m])
-      (Rsh32Ux64 x (Const64 [1])))
-    (Const64 [s]))
-	)
-)
-  && v.Block.Func.pass.name != "opt" && mul.Uses == 1
-  && m == int32(1<<31+(umagic32(c).m+1)/2) && s == umagic32(c).s-2
-	&& x.Op != OpConst32 && udivisibleOK32(c)
- => (Leq32U
-			(RotateLeft32 <typ.UInt32>
-				(Mul32 <typ.UInt32>
-					(Const32 <typ.UInt32> [int32(udivisible32(c).m)])
-					x)
-				(Const32 <typ.UInt32> [int32(32-udivisible32(c).k)])
-				)
-			(Const32 <typ.UInt32> [int32(udivisible32(c).max)])
-		)
-
-(Eq32 x (Mul32 (Const32 [c])
-  (Rsh32Ux64
-    (Avg32u
-      x
-      mul:(Hmul32u
-        (Const32 [m])
-        x))
-    (Const64 [s]))
-	)
-)
-  && v.Block.Func.pass.name != "opt" && mul.Uses == 1
-  && m == int32(umagic32(c).m) && s == umagic32(c).s-1
-	&& x.Op != OpConst32 && udivisibleOK32(c)
- => (Leq32U
-			(RotateLeft32 <typ.UInt32>
-				(Mul32 <typ.UInt32>
-					(Const32 <typ.UInt32> [int32(udivisible32(c).m)])
-					x)
-				(Const32 <typ.UInt32> [int32(32-udivisible32(c).k)])
-				)
-			(Const32 <typ.UInt32> [int32(udivisible32(c).max)])
-		)
-
-(Eq32 x (Mul32 (Const32 [c])
-  (Trunc64to32
-    (Rsh64Ux64
-      mul:(Mul64
-        (Const64 [m])
-        (ZeroExt32to64 x))
-      (Const64 [s])))
-	)
-)
-  && v.Block.Func.pass.name != "opt" && mul.Uses == 1
-  && m == int64(1<<31+umagic32(c).m/2) && s == 32+umagic32(c).s-1
-	&& x.Op != OpConst32 && udivisibleOK32(c)
- => (Leq32U
-			(RotateLeft32 <typ.UInt32>
-				(Mul32 <typ.UInt32>
-					(Const32 <typ.UInt32> [int32(udivisible32(c).m)])
-					x)
-				(Const32 <typ.UInt32> [int32(32-udivisible32(c).k)])
-				)
-			(Const32 <typ.UInt32> [int32(udivisible32(c).max)])
-		)
-
-(Eq32 x (Mul32 (Const32 [c])
-  (Trunc64to32
-    (Rsh64Ux64
-      mul:(Mul64
-        (Const64 [m])
-        (Rsh64Ux64 (ZeroExt32to64 x) (Const64 [1])))
-      (Const64 [s])))
-	)
-)
-  && v.Block.Func.pass.name != "opt" && mul.Uses == 1
-  && m == int64(1<<31+(umagic32(c).m+1)/2) && s == 32+umagic32(c).s-2
-	&& x.Op != OpConst32 && udivisibleOK32(c)
- => (Leq32U
-			(RotateLeft32 <typ.UInt32>
-				(Mul32 <typ.UInt32>
-					(Const32 <typ.UInt32> [int32(udivisible32(c).m)])
-					x)
-				(Const32 <typ.UInt32> [int32(32-udivisible32(c).k)])
-				)
-			(Const32 <typ.UInt32> [int32(udivisible32(c).max)])
-		)
-
-(Eq32 x (Mul32 (Const32 [c])
-  (Trunc64to32
-    (Rsh64Ux64
-      (Avg64u
-        (Lsh64x64 (ZeroExt32to64 x) (Const64 [32]))
-        mul:(Mul64
-          (Const64 [m])
-          (ZeroExt32to64 x)))
-      (Const64 [s])))
-	)
-)
-  && v.Block.Func.pass.name != "opt" && mul.Uses == 1
-  && m == int64(umagic32(c).m) && s == 32+umagic32(c).s-1
-	&& x.Op != OpConst32 && udivisibleOK32(c)
- => (Leq32U
-			(RotateLeft32 <typ.UInt32>
-				(Mul32 <typ.UInt32>
-					(Const32 <typ.UInt32> [int32(udivisible32(c).m)])
-					x)
-				(Const32 <typ.UInt32> [int32(32-udivisible32(c).k)])
-				)
-			(Const32 <typ.UInt32> [int32(udivisible32(c).max)])
-		)
-
-(Eq64 x (Mul64 (Const64 [c])
-	(Rsh64Ux64
-		mul:(Hmul64u
-			(Const64 [m])
-			x)
-		(Const64 [s]))
-	)
-) && v.Block.Func.pass.name != "opt" && mul.Uses == 1
-  && m == int64(1<<63+umagic64(c).m/2) && s == umagic64(c).s-1
-  && x.Op != OpConst64 && udivisibleOK64(c)
- => (Leq64U
-			(RotateLeft64 <typ.UInt64>
-				(Mul64 <typ.UInt64>
-					(Const64 <typ.UInt64> [int64(udivisible64(c).m)])
-					x)
-				(Const64 <typ.UInt64> [64-udivisible64(c).k])
-				)
-			(Const64 <typ.UInt64> [int64(udivisible64(c).max)])
-		)
-(Eq64 x (Mul64 (Const64 [c])
-	(Rsh64Ux64
-		mul:(Hmul64u
-			(Const64 [m])
-			(Rsh64Ux64 x (Const64 [1])))
-		(Const64 [s]))
-	)
-) && v.Block.Func.pass.name != "opt" && mul.Uses == 1
-  && m == int64(1<<63+(umagic64(c).m+1)/2) && s == umagic64(c).s-2
-  && x.Op != OpConst64 && udivisibleOK64(c)
- => (Leq64U
-			(RotateLeft64 <typ.UInt64>
-				(Mul64 <typ.UInt64>
-					(Const64 <typ.UInt64> [int64(udivisible64(c).m)])
-					x)
-				(Const64 <typ.UInt64> [64-udivisible64(c).k])
-				)
-			(Const64 <typ.UInt64> [int64(udivisible64(c).max)])
-		)
-(Eq64 x (Mul64 (Const64 [c])
-	(Rsh64Ux64
-		(Avg64u
-			x
-			mul:(Hmul64u
-				(Const64 [m])
-				x))
-		(Const64 [s]))
-	)
-) && v.Block.Func.pass.name != "opt" && mul.Uses == 1
-  && m == int64(umagic64(c).m) && s == umagic64(c).s-1
-  && x.Op != OpConst64 && udivisibleOK64(c)
- => (Leq64U
-			(RotateLeft64 <typ.UInt64>
-				(Mul64 <typ.UInt64>
-					(Const64 <typ.UInt64> [int64(udivisible64(c).m)])
-					x)
-				(Const64 <typ.UInt64> [64-udivisible64(c).k])
-				)
-			(Const64 <typ.UInt64> [int64(udivisible64(c).max)])
-		)
-
-// Signed divisibility checks convert to multiply, add and rotate.
-(Eq8 x (Mul8 (Const8 [c])
-  (Sub8
-    (Rsh32x64
-      mul:(Mul32
-        (Const32 [m])
-        (SignExt8to32 x))
-      (Const64 [s]))
-    (Rsh32x64
-      (SignExt8to32 x)
-      (Const64 [31])))
-	)
-)
-  && v.Block.Func.pass.name != "opt" && mul.Uses == 1
-  && m == int32(smagic8(c).m) && s == 8+smagic8(c).s
-	&& x.Op != OpConst8 && sdivisibleOK8(c)
- => (Leq8U
-			(RotateLeft8 <typ.UInt8>
-				(Add8 <typ.UInt8>
-					(Mul8 <typ.UInt8>
-						(Const8 <typ.UInt8> [int8(sdivisible8(c).m)])
-						x)
-					(Const8 <typ.UInt8> [int8(sdivisible8(c).a)])
-				)
-				(Const8 <typ.UInt8> [int8(8-sdivisible8(c).k)])
-			)
-			(Const8 <typ.UInt8> [int8(sdivisible8(c).max)])
-		)
-
-(Eq16 x (Mul16 (Const16 [c])
-  (Sub16
-    (Rsh32x64
-      mul:(Mul32
-        (Const32 [m])
-        (SignExt16to32 x))
-      (Const64 [s]))
-    (Rsh32x64
-      (SignExt16to32 x)
-      (Const64 [31])))
-	)
-)
-  && v.Block.Func.pass.name != "opt" && mul.Uses == 1
-  && m == int32(smagic16(c).m) && s == 16+smagic16(c).s
-	&& x.Op != OpConst16 && sdivisibleOK16(c)
- => (Leq16U
-			(RotateLeft16 <typ.UInt16>
-				(Add16 <typ.UInt16>
-					(Mul16 <typ.UInt16>
-						(Const16 <typ.UInt16> [int16(sdivisible16(c).m)])
-						x)
-					(Const16 <typ.UInt16> [int16(sdivisible16(c).a)])
-				)
-				(Const16 <typ.UInt16> [int16(16-sdivisible16(c).k)])
-			)
-			(Const16 <typ.UInt16> [int16(sdivisible16(c).max)])
-		)
-
-(Eq32 x (Mul32 (Const32 [c])
-  (Sub32
-    (Rsh64x64
-      mul:(Mul64
-        (Const64 [m])
-        (SignExt32to64 x))
-      (Const64 [s]))
-    (Rsh64x64
-      (SignExt32to64 x)
-      (Const64 [63])))
-	)
-)
-  && v.Block.Func.pass.name != "opt" && mul.Uses == 1
-  && m == int64(smagic32(c).m) && s == 32+smagic32(c).s
-	&& x.Op != OpConst32 && sdivisibleOK32(c)
- => (Leq32U
-			(RotateLeft32 <typ.UInt32>
-				(Add32 <typ.UInt32>
-					(Mul32 <typ.UInt32>
-						(Const32 <typ.UInt32> [int32(sdivisible32(c).m)])
-						x)
-					(Const32 <typ.UInt32> [int32(sdivisible32(c).a)])
-				)
-				(Const32 <typ.UInt32> [int32(32-sdivisible32(c).k)])
-			)
-			(Const32 <typ.UInt32> [int32(sdivisible32(c).max)])
-		)
-
-(Eq32 x (Mul32 (Const32 [c])
-  (Sub32
-    (Rsh32x64
-      mul:(Hmul32
-        (Const32 [m])
-        x)
-      (Const64 [s]))
-    (Rsh32x64
-      x
-      (Const64 [31])))
-	)
-)
-  && v.Block.Func.pass.name != "opt" && mul.Uses == 1
-  && m == int32(smagic32(c).m/2) && s == smagic32(c).s-1
-	&& x.Op != OpConst32 && sdivisibleOK32(c)
- => (Leq32U
-			(RotateLeft32 <typ.UInt32>
-				(Add32 <typ.UInt32>
-					(Mul32 <typ.UInt32>
-						(Const32 <typ.UInt32> [int32(sdivisible32(c).m)])
-						x)
-					(Const32 <typ.UInt32> [int32(sdivisible32(c).a)])
-				)
-				(Const32 <typ.UInt32> [int32(32-sdivisible32(c).k)])
-			)
-			(Const32 <typ.UInt32> [int32(sdivisible32(c).max)])
-		)
-
-(Eq32 x (Mul32 (Const32 [c])
-  (Sub32
-    (Rsh32x64
-      (Add32
-        mul:(Hmul32
-          (Const32 [m])
-          x)
-        x)
-      (Const64 [s]))
-    (Rsh32x64
-      x
-      (Const64 [31])))
-	)
-)
-  && v.Block.Func.pass.name != "opt" && mul.Uses == 1
-  && m == int32(smagic32(c).m) && s == smagic32(c).s
-	&& x.Op != OpConst32 && sdivisibleOK32(c)
- => (Leq32U
-			(RotateLeft32 <typ.UInt32>
-				(Add32 <typ.UInt32>
-					(Mul32 <typ.UInt32>
-						(Const32 <typ.UInt32> [int32(sdivisible32(c).m)])
-						x)
-					(Const32 <typ.UInt32> [int32(sdivisible32(c).a)])
-				)
-				(Const32 <typ.UInt32> [int32(32-sdivisible32(c).k)])
-			)
-			(Const32 <typ.UInt32> [int32(sdivisible32(c).max)])
-		)
-
-(Eq64 x (Mul64 (Const64 [c])
-  (Sub64
-    (Rsh64x64
-      mul:(Hmul64
-        (Const64 [m])
-        x)
-      (Const64 [s]))
-    (Rsh64x64
-      x
-      (Const64 [63])))
-	)
-)
-  && v.Block.Func.pass.name != "opt" && mul.Uses == 1
-  && m == int64(smagic64(c).m/2) && s == smagic64(c).s-1
-	&& x.Op != OpConst64 && sdivisibleOK64(c)
- => (Leq64U
-			(RotateLeft64 <typ.UInt64>
-				(Add64 <typ.UInt64>
-					(Mul64 <typ.UInt64>
-						(Const64 <typ.UInt64> [int64(sdivisible64(c).m)])
-						x)
-					(Const64 <typ.UInt64> [int64(sdivisible64(c).a)])
-				)
-				(Const64 <typ.UInt64> [64-sdivisible64(c).k])
-			)
-			(Const64 <typ.UInt64> [int64(sdivisible64(c).max)])
-		)
-
-(Eq64 x (Mul64 (Const64 [c])
-  (Sub64
-    (Rsh64x64
-      (Add64
-        mul:(Hmul64
-          (Const64 [m])
-          x)
-        x)
-      (Const64 [s]))
-    (Rsh64x64
-      x
-      (Const64 [63])))
-	)
-)
-  && v.Block.Func.pass.name != "opt" && mul.Uses == 1
-  && m == int64(smagic64(c).m) && s == smagic64(c).s
-	&& x.Op != OpConst64 && sdivisibleOK64(c)
- => (Leq64U
-			(RotateLeft64 <typ.UInt64>
-				(Add64 <typ.UInt64>
-					(Mul64 <typ.UInt64>
-						(Const64 <typ.UInt64> [int64(sdivisible64(c).m)])
-						x)
-					(Const64 <typ.UInt64> [int64(sdivisible64(c).a)])
-				)
-				(Const64 <typ.UInt64> [64-sdivisible64(c).k])
-			)
-			(Const64 <typ.UInt64> [int64(sdivisible64(c).max)])
-		)
-
-// Divisibility check for signed integers for power of two constant are simple mask.
-// However, we must match against the rewritten n%c == 0 -> n - c*(n/c) == 0 -> n == c*(n/c)
-// where n/c contains fixup code to handle signed n.
-((Eq8|Neq8) n (Lsh8x64
-  (Rsh8x64
-    (Add8  <t> n (Rsh8Ux64  <t> (Rsh8x64  <t> n (Const64 <typ.UInt64> [ 7])) (Const64 <typ.UInt64> [kbar])))
-    (Const64 <typ.UInt64> [k]))
-	(Const64 <typ.UInt64> [k]))
-) && k > 0 && k < 7 && kbar == 8 - k
-  => ((Eq8|Neq8) (And8 <t> n (Const8 <t> [1<<uint(k)-1])) (Const8 <t> [0]))
-
-((Eq16|Neq16) n (Lsh16x64
-  (Rsh16x64
-    (Add16 <t> n (Rsh16Ux64 <t> (Rsh16x64 <t> n (Const64 <typ.UInt64> [15])) (Const64 <typ.UInt64> [kbar])))
-    (Const64 <typ.UInt64> [k]))
-	(Const64 <typ.UInt64> [k]))
-) && k > 0 && k < 15 && kbar == 16 - k
-  => ((Eq16|Neq16) (And16 <t> n (Const16 <t> [1<<uint(k)-1])) (Const16 <t> [0]))
-
-((Eq32|Neq32) n (Lsh32x64
-  (Rsh32x64
-    (Add32 <t> n (Rsh32Ux64 <t> (Rsh32x64 <t> n (Const64 <typ.UInt64> [31])) (Const64 <typ.UInt64> [kbar])))
-    (Const64 <typ.UInt64> [k]))
-	(Const64 <typ.UInt64> [k]))
-) && k > 0 && k < 31 && kbar == 32 - k
-  => ((Eq32|Neq32) (And32 <t> n (Const32 <t> [1<<uint(k)-1])) (Const32 <t> [0]))
-
-((Eq64|Neq64) n (Lsh64x64
-  (Rsh64x64
-    (Add64 <t> n (Rsh64Ux64 <t> (Rsh64x64 <t> n (Const64 <typ.UInt64> [63])) (Const64 <typ.UInt64> [kbar])))
-    (Const64 <typ.UInt64> [k]))
-	(Const64 <typ.UInt64> [k]))
-) && k > 0 && k < 63 && kbar == 64 - k
-  => ((Eq64|Neq64) (And64 <t> n (Const64 <t> [1<<uint(k)-1])) (Const64 <t> [0]))
-
-(Eq(8|16|32|64)  s:(Sub(8|16|32|64) x y) (Const(8|16|32|64) [0])) && s.Uses == 1 => (Eq(8|16|32|64)  x y)
-(Neq(8|16|32|64) s:(Sub(8|16|32|64) x y) (Const(8|16|32|64) [0])) && s.Uses == 1 => (Neq(8|16|32|64) x y)
-
-// Optimize bitsets
-(Eq8 (And8 <t> x (Const8 <t> [y])) (Const8 <t> [y])) && oneBit8(y)
-  => (Neq8 (And8 <t> x (Const8 <t> [y])) (Const8 <t> [0]))
-(Eq16 (And16 <t> x (Const16 <t> [y])) (Const16 <t> [y])) && oneBit16(y)
-  => (Neq16 (And16 <t> x (Const16 <t> [y])) (Const16 <t> [0]))
-(Eq32 (And32 <t> x (Const32 <t> [y])) (Const32 <t> [y])) && oneBit32(y)
-  => (Neq32 (And32 <t> x (Const32 <t> [y])) (Const32 <t> [0]))
-(Eq64 (And64 <t> x (Const64 <t> [y])) (Const64 <t> [y])) && oneBit64(y)
-  => (Neq64 (And64 <t> x (Const64 <t> [y])) (Const64 <t> [0]))
-(Neq8 (And8 <t> x (Const8 <t> [y])) (Const8 <t> [y])) && oneBit8(y)
-  => (Eq8 (And8 <t> x (Const8 <t> [y])) (Const8 <t> [0]))
-(Neq16 (And16 <t> x (Const16 <t> [y])) (Const16 <t> [y])) && oneBit16(y)
-  => (Eq16 (And16 <t> x (Const16 <t> [y])) (Const16 <t> [0]))
-(Neq32 (And32 <t> x (Const32 <t> [y])) (Const32 <t> [y])) && oneBit32(y)
-  => (Eq32 (And32 <t> x (Const32 <t> [y])) (Const32 <t> [0]))
-(Neq64 (And64 <t> x (Const64 <t> [y])) (Const64 <t> [y])) && oneBit64(y)
-  => (Eq64 (And64 <t> x (Const64 <t> [y])) (Const64 <t> [0]))
-
-// Reassociate expressions involving
-// constants such that constants come first,
-// exposing obvious constant-folding opportunities.
-// Reassociate (op (op y C) x) to (op C (op x y)) or similar, where C
-// is constant, which pushes constants to the outside
-// of the expression. At that point, any constant-folding
-// opportunities should be obvious.
-// Note: don't include AddPtr here! In order to maintain the
-// invariant that pointers must stay within the pointed-to object,
-// we can't pull part of a pointer computation above the AddPtr.
-// See issue 37881.
-// Note: we don't need to handle any (x-C) cases because we already rewrite
-// (x-C) to (x+(-C)).
-
-// x + (C + z) -> C + (x + z)
-(Add64 (Add64 i:(Const64 <t>) z) x) && (z.Op != OpConst64 && x.Op != OpConst64) => (Add64 i (Add64 <t> z x))
-(Add32 (Add32 i:(Const32 <t>) z) x) && (z.Op != OpConst32 && x.Op != OpConst32) => (Add32 i (Add32 <t> z x))
-(Add16 (Add16 i:(Const16 <t>) z) x) && (z.Op != OpConst16 && x.Op != OpConst16) => (Add16 i (Add16 <t> z x))
-(Add8  (Add8  i:(Const8  <t>) z) x) && (z.Op != OpConst8  && x.Op != OpConst8)  => (Add8  i (Add8  <t> z x))
-
-// x + (C - z) -> C + (x - z)
-(Add64 (Sub64 i:(Const64 <t>) z) x) && (z.Op != OpConst64 && x.Op != OpConst64) => (Add64 i (Sub64 <t> x z))
-(Add32 (Sub32 i:(Const32 <t>) z) x) && (z.Op != OpConst32 && x.Op != OpConst32) => (Add32 i (Sub32 <t> x z))
-(Add16 (Sub16 i:(Const16 <t>) z) x) && (z.Op != OpConst16 && x.Op != OpConst16) => (Add16 i (Sub16 <t> x z))
-(Add8  (Sub8  i:(Const8  <t>) z) x) && (z.Op != OpConst8  && x.Op != OpConst8)  => (Add8  i (Sub8  <t> x z))
-
-// x - (C - z) -> x + (z - C) -> (x + z) - C
-(Sub64 x (Sub64 i:(Const64 <t>) z)) && (z.Op != OpConst64 && x.Op != OpConst64) => (Sub64 (Add64 <t> x z) i)
-(Sub32 x (Sub32 i:(Const32 <t>) z)) && (z.Op != OpConst32 && x.Op != OpConst32) => (Sub32 (Add32 <t> x z) i)
-(Sub16 x (Sub16 i:(Const16 <t>) z)) && (z.Op != OpConst16 && x.Op != OpConst16) => (Sub16 (Add16 <t> x z) i)
-(Sub8  x (Sub8  i:(Const8  <t>) z)) && (z.Op != OpConst8  && x.Op != OpConst8)  => (Sub8  (Add8  <t> x z) i)
-
-// x - (z + C) -> x + (-z - C) -> (x - z) - C
-(Sub64 x (Add64 z i:(Const64 <t>))) && (z.Op != OpConst64 && x.Op != OpConst64) => (Sub64 (Sub64 <t> x z) i)
-(Sub32 x (Add32 z i:(Const32 <t>))) && (z.Op != OpConst32 && x.Op != OpConst32) => (Sub32 (Sub32 <t> x z) i)
-(Sub16 x (Add16 z i:(Const16 <t>))) && (z.Op != OpConst16 && x.Op != OpConst16) => (Sub16 (Sub16 <t> x z) i)
-(Sub8  x (Add8  z i:(Const8  <t>))) && (z.Op != OpConst8  && x.Op != OpConst8)  => (Sub8 (Sub8  <t> x z) i)
-
-// (C - z) - x -> C - (z + x)
-(Sub64 (Sub64 i:(Const64 <t>) z) x) && (z.Op != OpConst64 && x.Op != OpConst64) => (Sub64 i (Add64 <t> z x))
-(Sub32 (Sub32 i:(Const32 <t>) z) x) && (z.Op != OpConst32 && x.Op != OpConst32) => (Sub32 i (Add32 <t> z x))
-(Sub16 (Sub16 i:(Const16 <t>) z) x) && (z.Op != OpConst16 && x.Op != OpConst16) => (Sub16 i (Add16 <t> z x))
-(Sub8  (Sub8  i:(Const8  <t>) z) x) && (z.Op != OpConst8  && x.Op != OpConst8)  => (Sub8  i (Add8  <t> z x))
-
-// (z + C) -x -> C + (z - x)
-(Sub64 (Add64 z i:(Const64 <t>)) x) && (z.Op != OpConst64 && x.Op != OpConst64) => (Add64 i (Sub64 <t> z x))
-(Sub32 (Add32 z i:(Const32 <t>)) x) && (z.Op != OpConst32 && x.Op != OpConst32) => (Add32 i (Sub32 <t> z x))
-(Sub16 (Add16 z i:(Const16 <t>)) x) && (z.Op != OpConst16 && x.Op != OpConst16) => (Add16 i (Sub16 <t> z x))
-(Sub8  (Add8  z i:(Const8  <t>)) x) && (z.Op != OpConst8  && x.Op != OpConst8)  => (Add8  i (Sub8  <t> z x))
-
-// x & (C & z) -> C & (x & z)
-(And64 (And64 i:(Const64 <t>) z) x) && (z.Op != OpConst64 && x.Op != OpConst64) => (And64 i (And64 <t> z x))
-(And32 (And32 i:(Const32 <t>) z) x) && (z.Op != OpConst32 && x.Op != OpConst32) => (And32 i (And32 <t> z x))
-(And16 (And16 i:(Const16 <t>) z) x) && (z.Op != OpConst16 && x.Op != OpConst16) => (And16 i (And16 <t> z x))
-(And8  (And8  i:(Const8  <t>) z) x) && (z.Op != OpConst8  && x.Op != OpConst8)  => (And8  i (And8  <t> z x))
-
-// x | (C | z) -> C | (x | z)
-(Or64 (Or64 i:(Const64 <t>) z) x) && (z.Op != OpConst64 && x.Op != OpConst64) => (Or64 i (Or64 <t> z x))
-(Or32 (Or32 i:(Const32 <t>) z) x) && (z.Op != OpConst32 && x.Op != OpConst32) => (Or32 i (Or32 <t> z x))
-(Or16 (Or16 i:(Const16 <t>) z) x) && (z.Op != OpConst16 && x.Op != OpConst16) => (Or16 i (Or16 <t> z x))
-(Or8  (Or8  i:(Const8  <t>) z) x) && (z.Op != OpConst8  && x.Op != OpConst8)  => (Or8  i (Or8  <t> z x))
-
-// x ^ (C ^ z) -> C ^ (x ^ z)
-(Xor64 (Xor64 i:(Const64 <t>) z) x) && (z.Op != OpConst64 && x.Op != OpConst64) => (Xor64 i (Xor64 <t> z x))
-(Xor32 (Xor32 i:(Const32 <t>) z) x) && (z.Op != OpConst32 && x.Op != OpConst32) => (Xor32 i (Xor32 <t> z x))
-(Xor16 (Xor16 i:(Const16 <t>) z) x) && (z.Op != OpConst16 && x.Op != OpConst16) => (Xor16 i (Xor16 <t> z x))
-(Xor8  (Xor8  i:(Const8  <t>) z) x) && (z.Op != OpConst8  && x.Op != OpConst8)  => (Xor8  i (Xor8  <t> z x))
-
-// x * (D * z) = D * (x * z)
-(Mul64 (Mul64 i:(Const64 <t>) z) x) && (z.Op != OpConst64 && x.Op != OpConst64) => (Mul64 i (Mul64 <t> x z))
-(Mul32 (Mul32 i:(Const32 <t>) z) x) && (z.Op != OpConst32 && x.Op != OpConst32) => (Mul32 i (Mul32 <t> x z))
-(Mul16 (Mul16 i:(Const16 <t>) z) x) && (z.Op != OpConst16 && x.Op != OpConst16) => (Mul16 i (Mul16 <t> x z))
-(Mul8  (Mul8  i:(Const8  <t>) z) x) && (z.Op != OpConst8  && x.Op != OpConst8)  => (Mul8  i (Mul8  <t> x z))
-
-// C + (D + x) -> (C + D) + x
-(Add64 (Const64 <t> [c]) (Add64 (Const64 <t> [d]) x)) => (Add64 (Const64 <t> [c+d]) x)
-(Add32 (Const32 <t> [c]) (Add32 (Const32 <t> [d]) x)) => (Add32 (Const32 <t> [c+d]) x)
-(Add16 (Const16 <t> [c]) (Add16 (Const16 <t> [d]) x)) => (Add16 (Const16 <t> [c+d]) x)
-(Add8  (Const8  <t> [c]) (Add8  (Const8  <t> [d]) x)) => (Add8  (Const8  <t> [c+d]) x)
-
-// C + (D - x) -> (C + D) - x
-(Add64 (Const64 <t> [c]) (Sub64 (Const64 <t> [d]) x)) => (Sub64 (Const64 <t> [c+d]) x)
-(Add32 (Const32 <t> [c]) (Sub32 (Const32 <t> [d]) x)) => (Sub32 (Const32 <t> [c+d]) x)
-(Add16 (Const16 <t> [c]) (Sub16 (Const16 <t> [d]) x)) => (Sub16 (Const16 <t> [c+d]) x)
-(Add8  (Const8  <t> [c]) (Sub8  (Const8  <t> [d]) x)) => (Sub8  (Const8  <t> [c+d]) x)
-
-// C - (D - x) -> (C - D) + x
-(Sub64 (Const64 <t> [c]) (Sub64 (Const64 <t> [d]) x)) => (Add64 (Const64 <t> [c-d]) x)
-(Sub32 (Const32 <t> [c]) (Sub32 (Const32 <t> [d]) x)) => (Add32 (Const32 <t> [c-d]) x)
-(Sub16 (Const16 <t> [c]) (Sub16 (Const16 <t> [d]) x)) => (Add16 (Const16 <t> [c-d]) x)
-(Sub8  (Const8  <t> [c]) (Sub8  (Const8  <t> [d]) x)) => (Add8  (Const8  <t> [c-d]) x)
-
-// C - (D + x) -> (C - D) - x
-(Sub64 (Const64 <t> [c]) (Add64 (Const64 <t> [d]) x)) => (Sub64 (Const64 <t> [c-d]) x)
-(Sub32 (Const32 <t> [c]) (Add32 (Const32 <t> [d]) x)) => (Sub32 (Const32 <t> [c-d]) x)
-(Sub16 (Const16 <t> [c]) (Add16 (Const16 <t> [d]) x)) => (Sub16 (Const16 <t> [c-d]) x)
-(Sub8  (Const8  <t> [c]) (Add8  (Const8  <t> [d]) x)) => (Sub8  (Const8  <t> [c-d]) x)
-
-// C & (D & x) -> (C & D) & x
-(And64 (Const64 <t> [c]) (And64 (Const64 <t> [d]) x)) => (And64 (Const64 <t> [c&d]) x)
-(And32 (Const32 <t> [c]) (And32 (Const32 <t> [d]) x)) => (And32 (Const32 <t> [c&d]) x)
-(And16 (Const16 <t> [c]) (And16 (Const16 <t> [d]) x)) => (And16 (Const16 <t> [c&d]) x)
-(And8  (Const8  <t> [c]) (And8  (Const8  <t> [d]) x)) => (And8  (Const8  <t> [c&d]) x)
-
-// C | (D | x) -> (C | D) | x
-(Or64 (Const64 <t> [c]) (Or64 (Const64 <t> [d]) x)) => (Or64 (Const64 <t> [c|d]) x)
-(Or32 (Const32 <t> [c]) (Or32 (Const32 <t> [d]) x)) => (Or32 (Const32 <t> [c|d]) x)
-(Or16 (Const16 <t> [c]) (Or16 (Const16 <t> [d]) x)) => (Or16 (Const16 <t> [c|d]) x)
-(Or8  (Const8  <t> [c]) (Or8  (Const8  <t> [d]) x)) => (Or8  (Const8  <t> [c|d]) x)
-
-// C ^ (D ^ x) -> (C ^ D) ^ x
-(Xor64 (Const64 <t> [c]) (Xor64 (Const64 <t> [d]) x)) => (Xor64 (Const64 <t> [c^d]) x)
-(Xor32 (Const32 <t> [c]) (Xor32 (Const32 <t> [d]) x)) => (Xor32 (Const32 <t> [c^d]) x)
-(Xor16 (Const16 <t> [c]) (Xor16 (Const16 <t> [d]) x)) => (Xor16 (Const16 <t> [c^d]) x)
-(Xor8  (Const8  <t> [c]) (Xor8  (Const8  <t> [d]) x)) => (Xor8  (Const8  <t> [c^d]) x)
-
-// C * (D * x) = (C * D) * x
-(Mul64 (Const64 <t> [c]) (Mul64 (Const64 <t> [d]) x)) => (Mul64 (Const64 <t> [c*d]) x)
-(Mul32 (Const32 <t> [c]) (Mul32 (Const32 <t> [d]) x)) => (Mul32 (Const32 <t> [c*d]) x)
-(Mul16 (Const16 <t> [c]) (Mul16 (Const16 <t> [d]) x)) => (Mul16 (Const16 <t> [c*d]) x)
-(Mul8  (Const8  <t> [c]) (Mul8  (Const8  <t> [d]) x)) => (Mul8  (Const8  <t> [c*d]) x)
-
-// floating point optimizations
-(Mul(32|64)F x (Const(32|64)F [1])) => x
-(Mul32F x (Const32F [-1])) => (Neg32F x)
-(Mul64F x (Const64F [-1])) => (Neg64F x)
-(Mul32F x (Const32F [2])) => (Add32F x x)
-(Mul64F x (Const64F [2])) => (Add64F x x)
-
-(Div32F x (Const32F <t> [c])) && reciprocalExact32(c) => (Mul32F x (Const32F <t> [1/c]))
-(Div64F x (Const64F <t> [c])) && reciprocalExact64(c) => (Mul64F x (Const64F <t> [1/c]))
-
-// rewrite single-precision sqrt expression "float32(math.Sqrt(float64(x)))"
-(Cvt64Fto32F sqrt0:(Sqrt (Cvt32Fto64F x))) && sqrt0.Uses==1 => (Sqrt32 x)
-
-(Sqrt (Const64F [c])) && !math.IsNaN(math.Sqrt(c)) => (Const64F [math.Sqrt(c)])
-
-// for rewriting results of some late-expanded rewrites (below)
-(SelectN [0] (MakeResult x ___)) => x
-(SelectN [1] (MakeResult x y ___)) => y
-(SelectN [2] (MakeResult x y z ___)) => z
-
-// for late-expanded calls, recognize newobject and remove zeroing and nilchecks
-(Zero (SelectN [0] call:(StaticLECall _ _)) mem:(SelectN [1] call))
-	&& isSameCall(call.Aux, "runtime.newobject")
-	=> mem
-
-(Store (SelectN [0] call:(StaticLECall _ _)) x mem:(SelectN [1] call))
-	&& isConstZero(x)
-	&& isSameCall(call.Aux, "runtime.newobject")
-	=> mem
-
-(Store (OffPtr (SelectN [0] call:(StaticLECall _ _))) x mem:(SelectN [1] call))
-	&& isConstZero(x)
-	&& isSameCall(call.Aux, "runtime.newobject")
-	=> mem
-
-(NilCheck (SelectN [0] call:(StaticLECall _ _)) _)
-	&& isSameCall(call.Aux, "runtime.newobject")
-	&& warnRule(fe.Debug_checknil(), v, "removed nil check")
-	=> (Invalid)
-
-(NilCheck (OffPtr (SelectN [0] call:(StaticLECall _ _))) _)
-	&& isSameCall(call.Aux, "runtime.newobject")
-	&& warnRule(fe.Debug_checknil(), v, "removed nil check")
-	=> (Invalid)
-
-// for late-expanded calls, recognize memequal applied to a single constant byte
-// Support is limited by 1, 2, 4, 8 byte sizes
-(StaticLECall {callAux} sptr (Addr {scon} (SB)) (Const64 [1]) mem)
-  && isSameCall(callAux, "runtime.memequal")
-  && symIsRO(scon)
-  => (MakeResult (Eq8 (Load <typ.Int8> sptr mem) (Const8 <typ.Int8> [int8(read8(scon,0))])) mem)
-
-(StaticLECall {callAux} sptr (Addr {scon} (SB)) (Const64 [2]) mem)
-  && isSameCall(callAux, "runtime.memequal")
-  && symIsRO(scon)
-  && canLoadUnaligned(config)
-  => (MakeResult (Eq16 (Load <typ.Int16> sptr mem) (Const16 <typ.Int16> [int16(read16(scon,0,config.ctxt.Arch.ByteOrder))])) mem)
-
-(StaticLECall {callAux} sptr (Addr {scon} (SB)) (Const64 [4]) mem)
-  && isSameCall(callAux, "runtime.memequal")
-  && symIsRO(scon)
-  && canLoadUnaligned(config)
-  => (MakeResult (Eq32 (Load <typ.Int32> sptr mem) (Const32 <typ.Int32> [int32(read32(scon,0,config.ctxt.Arch.ByteOrder))])) mem)
-
-(StaticLECall {callAux} sptr (Addr {scon} (SB)) (Const64 [8]) mem)
-  && isSameCall(callAux, "runtime.memequal")
-  && symIsRO(scon)
-  && canLoadUnaligned(config) && config.PtrSize == 8
-  => (MakeResult (Eq64 (Load <typ.Int64> sptr mem) (Const64 <typ.Int64> [int64(read64(scon,0,config.ctxt.Arch.ByteOrder))])) mem)
-
-// Evaluate constant address comparisons.
-(EqPtr  x x) => (ConstBool [true])
-(NeqPtr x x) => (ConstBool [false])
-(EqPtr  (Addr {x} _) (Addr {y} _)) => (ConstBool [x == y])
-(EqPtr  (Addr {x} _) (OffPtr [o] (Addr {y} _))) => (ConstBool [x == y && o == 0])
-(EqPtr  (OffPtr [o1] (Addr {x} _)) (OffPtr [o2] (Addr {y} _))) => (ConstBool [x == y && o1 == o2])
-(NeqPtr (Addr {x} _) (Addr {y} _)) => (ConstBool [x != y])
-(NeqPtr (Addr {x} _) (OffPtr [o] (Addr {y} _))) => (ConstBool [x != y || o != 0])
-(NeqPtr (OffPtr [o1] (Addr {x} _)) (OffPtr [o2] (Addr {y} _))) => (ConstBool [x != y || o1 != o2])
-(EqPtr  (LocalAddr {x} _ _) (LocalAddr {y} _ _)) => (ConstBool [x == y])
-(EqPtr  (LocalAddr {x} _ _) (OffPtr [o] (LocalAddr {y} _ _))) => (ConstBool [x == y && o == 0])
-(EqPtr  (OffPtr [o1] (LocalAddr {x} _ _)) (OffPtr [o2] (LocalAddr {y} _ _))) => (ConstBool [x == y && o1 == o2])
-(NeqPtr (LocalAddr {x} _ _) (LocalAddr {y} _ _)) => (ConstBool [x != y])
-(NeqPtr (LocalAddr {x} _ _) (OffPtr [o] (LocalAddr {y} _ _))) => (ConstBool [x != y || o != 0])
-(NeqPtr (OffPtr [o1] (LocalAddr {x} _ _)) (OffPtr [o2] (LocalAddr {y} _ _))) => (ConstBool [x != y || o1 != o2])
-(EqPtr  (OffPtr [o1] p1) p2) && isSamePtr(p1, p2) => (ConstBool [o1 == 0])
-(NeqPtr (OffPtr [o1] p1) p2) && isSamePtr(p1, p2) => (ConstBool [o1 != 0])
-(EqPtr  (OffPtr [o1] p1) (OffPtr [o2] p2)) && isSamePtr(p1, p2) => (ConstBool [o1 == o2])
-(NeqPtr (OffPtr [o1] p1) (OffPtr [o2] p2)) && isSamePtr(p1, p2) => (ConstBool [o1 != o2])
-(EqPtr  (Const(32|64) [c]) (Const(32|64) [d])) => (ConstBool [c == d])
-(NeqPtr (Const(32|64) [c]) (Const(32|64) [d])) => (ConstBool [c != d])
-
-(EqPtr  (LocalAddr _ _) (Addr _)) => (ConstBool [false])
-(EqPtr  (OffPtr (LocalAddr _ _)) (Addr _)) => (ConstBool [false])
-(EqPtr  (LocalAddr _ _) (OffPtr (Addr _))) => (ConstBool [false])
-(EqPtr  (OffPtr (LocalAddr _ _)) (OffPtr (Addr _))) => (ConstBool [false])
-(NeqPtr (LocalAddr _ _) (Addr _)) => (ConstBool [true])
-(NeqPtr (OffPtr (LocalAddr _ _)) (Addr _)) => (ConstBool [true])
-(NeqPtr (LocalAddr _ _) (OffPtr (Addr _))) => (ConstBool [true])
-(NeqPtr (OffPtr (LocalAddr _ _)) (OffPtr (Addr _))) => (ConstBool [true])
-
-// Simplify address comparisons.
-(EqPtr  (AddPtr p1 o1) p2) && isSamePtr(p1, p2) => (Not (IsNonNil o1))
-(NeqPtr (AddPtr p1 o1) p2) && isSamePtr(p1, p2) => (IsNonNil o1)
-(EqPtr  (Const(32|64) [0]) p) => (Not (IsNonNil p))
-(NeqPtr (Const(32|64) [0]) p) => (IsNonNil p)
-(EqPtr  (ConstNil) p) => (Not (IsNonNil p))
-(NeqPtr (ConstNil) p) => (IsNonNil p)
-
-// Evaluate constant user nil checks.
-(IsNonNil (ConstNil)) => (ConstBool [false])
-(IsNonNil (Const(32|64) [c])) => (ConstBool [c != 0])
-(IsNonNil (Addr _)) => (ConstBool [true])
-(IsNonNil (LocalAddr _ _)) => (ConstBool [true])
-
-// Inline small or disjoint runtime.memmove calls with constant length.
-// See the comment in op Move in genericOps.go for discussion of the type.
-
-// Because expand calls runs after prove, constants useful to this pattern may not appear.
-// Both versions need to exist; the memory and register variants.
-//
-// Match post-expansion calls, memory version.
-(SelectN [0] call:(StaticCall {sym} s1:(Store _ (Const(64|32) [sz]) s2:(Store  _ src s3:(Store {t} _ dst mem)))))
-	&& sz >= 0
-	&& isSameCall(sym, "runtime.memmove")
-	&& t.IsPtr() // avoids TUNSAFEPTR, see issue 30061
-	&& s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1
-	&& isInlinableMemmove(dst, src, int64(sz), config)
-	&& clobber(s1, s2, s3, call)
-	=> (Move {t.Elem()} [int64(sz)] dst src mem)
-
-// Match post-expansion calls, register version.
-(SelectN [0] call:(StaticCall {sym} dst src (Const(64|32) [sz]) mem))
-	&& sz >= 0
-	&& call.Uses == 1 // this will exclude all calls with results
-	&& isSameCall(sym, "runtime.memmove")
-	&& dst.Type.IsPtr() // avoids TUNSAFEPTR, see issue 30061
-	&& isInlinableMemmove(dst, src, int64(sz), config)
-	&& clobber(call)
-	=> (Move {dst.Type.Elem()} [int64(sz)] dst src mem)
-
-// Match pre-expansion calls.
-(SelectN [0] call:(StaticLECall {sym} dst src (Const(64|32) [sz]) mem))
-	&& sz >= 0
-	&& call.Uses == 1 // this will exclude all calls with results
-	&& isSameCall(sym, "runtime.memmove")
-	&& dst.Type.IsPtr() // avoids TUNSAFEPTR, see issue 30061
-	&& isInlinableMemmove(dst, src, int64(sz), config)
-	&& clobber(call)
-	=> (Move {dst.Type.Elem()} [int64(sz)] dst src mem)
-
-// De-virtualize late-expanded interface calls into late-expanded static calls.
-// Note that (ITab (IMake)) doesn't get rewritten until after the first opt pass,
-// so this rule should trigger reliably.
-// devirtLECall removes the first argument, adds the devirtualized symbol to the AuxCall, and changes the opcode
-(InterLECall [argsize] {auxCall} (Load (OffPtr [off] (ITab (IMake (Addr {itab} (SB)) _))) _) ___) && devirtLESym(v, auxCall, itab, off) !=
-    nil => devirtLECall(v, devirtLESym(v, auxCall, itab, off))
-
-// Move and Zero optimizations.
-// Move source and destination may overlap.
-
-// Convert Moves into Zeros when the source is known to be zeros.
-(Move {t} [n] dst1 src mem:(Zero {t} [n] dst2 _)) && isSamePtr(src, dst2)
-	=> (Zero {t} [n] dst1 mem)
-(Move {t} [n] dst1 src mem:(VarDef (Zero {t} [n] dst0 _))) && isSamePtr(src, dst0)
-	=> (Zero {t} [n] dst1 mem)
-(Move {t} [n] dst (Addr {sym} (SB)) mem) && symIsROZero(sym) => (Zero {t} [n] dst mem)
-
-// Don't Store to variables that are about to be overwritten by Move/Zero.
-(Zero {t1} [n] p1 store:(Store {t2} (OffPtr [o2] p2) _ mem))
-	&& isSamePtr(p1, p2) && store.Uses == 1
-	&& n >= o2 + t2.Size()
-	&& clobber(store)
-	=> (Zero {t1} [n] p1 mem)
-(Move {t1} [n] dst1 src1 store:(Store {t2} op:(OffPtr [o2] dst2) _ mem))
-	&& isSamePtr(dst1, dst2) && store.Uses == 1
-	&& n >= o2 + t2.Size()
-	&& disjoint(src1, n, op, t2.Size())
-	&& clobber(store)
-	=> (Move {t1} [n] dst1 src1 mem)
-
-// Don't Move to variables that are immediately completely overwritten.
-(Zero {t} [n] dst1 move:(Move {t} [n] dst2 _ mem))
-	&& move.Uses == 1
-	&& isSamePtr(dst1, dst2)
-	&& clobber(move)
-	=> (Zero {t} [n] dst1 mem)
-(Move {t} [n] dst1 src1 move:(Move {t} [n] dst2 _ mem))
-	&& move.Uses == 1
-	&& isSamePtr(dst1, dst2) && disjoint(src1, n, dst2, n)
-	&& clobber(move)
-	=> (Move {t} [n] dst1 src1 mem)
-(Zero {t} [n] dst1 vardef:(VarDef {x} move:(Move {t} [n] dst2 _ mem)))
-	&& move.Uses == 1 && vardef.Uses == 1
-	&& isSamePtr(dst1, dst2)
-	&& clobber(move, vardef)
-	=> (Zero {t} [n] dst1 (VarDef {x} mem))
-(Move {t} [n] dst1 src1 vardef:(VarDef {x} move:(Move {t} [n] dst2 _ mem)))
-	&& move.Uses == 1 && vardef.Uses == 1
-	&& isSamePtr(dst1, dst2) && disjoint(src1, n, dst2, n)
-	&& clobber(move, vardef)
-	=> (Move {t} [n] dst1 src1 (VarDef {x} mem))
-(Store {t1} op1:(OffPtr [o1] p1) d1
-	m2:(Store {t2} op2:(OffPtr [0] p2) d2
-		m3:(Move [n] p3 _ mem)))
-	&& m2.Uses == 1 && m3.Uses == 1
-	&& o1 == t2.Size()
-	&& n == t2.Size() + t1.Size()
-	&& isSamePtr(p1, p2) && isSamePtr(p2, p3)
-	&& clobber(m2, m3)
-	=> (Store {t1} op1 d1 (Store {t2} op2 d2 mem))
-(Store {t1} op1:(OffPtr [o1] p1) d1
-	m2:(Store {t2} op2:(OffPtr [o2] p2) d2
-		m3:(Store {t3} op3:(OffPtr [0] p3) d3
-			m4:(Move [n] p4 _ mem))))
-	&& m2.Uses == 1 && m3.Uses == 1 && m4.Uses == 1
-	&& o2 == t3.Size()
-	&& o1-o2 == t2.Size()
-	&& n == t3.Size() + t2.Size() + t1.Size()
-	&& isSamePtr(p1, p2) && isSamePtr(p2, p3) && isSamePtr(p3, p4)
-	&& clobber(m2, m3, m4)
-	=> (Store {t1} op1 d1 (Store {t2} op2 d2 (Store {t3} op3 d3 mem)))
-(Store {t1} op1:(OffPtr [o1] p1) d1
-	m2:(Store {t2} op2:(OffPtr [o2] p2) d2
-		m3:(Store {t3} op3:(OffPtr [o3] p3) d3
-			m4:(Store {t4} op4:(OffPtr [0] p4) d4
-				m5:(Move [n] p5 _ mem)))))
-	&& m2.Uses == 1 && m3.Uses == 1 && m4.Uses == 1 && m5.Uses == 1
-	&& o3 == t4.Size()
-	&& o2-o3 == t3.Size()
-	&& o1-o2 == t2.Size()
-	&& n == t4.Size() + t3.Size() + t2.Size() + t1.Size()
-	&& isSamePtr(p1, p2) && isSamePtr(p2, p3) && isSamePtr(p3, p4) && isSamePtr(p4, p5)
-	&& clobber(m2, m3, m4, m5)
-	=> (Store {t1} op1 d1 (Store {t2} op2 d2 (Store {t3} op3 d3 (Store {t4} op4 d4 mem))))
-
-// Don't Zero variables that are immediately completely overwritten
-// before being accessed.
-(Move {t} [n] dst1 src1 zero:(Zero {t} [n] dst2 mem))
-	&& zero.Uses == 1
-	&& isSamePtr(dst1, dst2) && disjoint(src1, n, dst2, n)
-	&& clobber(zero)
-	=> (Move {t} [n] dst1 src1 mem)
-(Move {t} [n] dst1 src1 vardef:(VarDef {x} zero:(Zero {t} [n] dst2 mem)))
-	&& zero.Uses == 1 && vardef.Uses == 1
-	&& isSamePtr(dst1, dst2) && disjoint(src1, n, dst2, n)
-	&& clobber(zero, vardef)
-	=> (Move {t} [n] dst1 src1 (VarDef {x} mem))
-(Store {t1} op1:(OffPtr [o1] p1) d1
-	m2:(Store {t2} op2:(OffPtr [0] p2) d2
-		m3:(Zero [n] p3 mem)))
-	&& m2.Uses == 1 && m3.Uses == 1
-	&& o1 == t2.Size()
-	&& n == t2.Size() + t1.Size()
-	&& isSamePtr(p1, p2) && isSamePtr(p2, p3)
-	&& clobber(m2, m3)
-	=> (Store {t1} op1 d1 (Store {t2} op2 d2 mem))
-(Store {t1} op1:(OffPtr [o1] p1) d1
-	m2:(Store {t2} op2:(OffPtr [o2] p2) d2
-		m3:(Store {t3} op3:(OffPtr [0] p3) d3
-			m4:(Zero [n] p4 mem))))
-	&& m2.Uses == 1 && m3.Uses == 1 && m4.Uses == 1
-	&& o2 == t3.Size()
-	&& o1-o2 == t2.Size()
-	&& n == t3.Size() + t2.Size() + t1.Size()
-	&& isSamePtr(p1, p2) && isSamePtr(p2, p3) && isSamePtr(p3, p4)
-	&& clobber(m2, m3, m4)
-	=> (Store {t1} op1 d1 (Store {t2} op2 d2 (Store {t3} op3 d3 mem)))
-(Store {t1} op1:(OffPtr [o1] p1) d1
-	m2:(Store {t2} op2:(OffPtr [o2] p2) d2
-		m3:(Store {t3} op3:(OffPtr [o3] p3) d3
-			m4:(Store {t4} op4:(OffPtr [0] p4) d4
-				m5:(Zero [n] p5 mem)))))
-	&& m2.Uses == 1 && m3.Uses == 1 && m4.Uses == 1 && m5.Uses == 1
-	&& o3 == t4.Size()
-	&& o2-o3 == t3.Size()
-	&& o1-o2 == t2.Size()
-	&& n == t4.Size() + t3.Size() + t2.Size() + t1.Size()
-	&& isSamePtr(p1, p2) && isSamePtr(p2, p3) && isSamePtr(p3, p4) && isSamePtr(p4, p5)
-	&& clobber(m2, m3, m4, m5)
-	=> (Store {t1} op1 d1 (Store {t2} op2 d2 (Store {t3} op3 d3 (Store {t4} op4 d4 mem))))
-
-// Don't Move from memory if the values are likely to already be
-// in registers.
-(Move {t1} [n] dst p1
-	mem:(Store {t2} op2:(OffPtr <tt2> [o2] p2) d1
-		(Store {t3} op3:(OffPtr <tt3> [0] p3) d2 _)))
-	&& isSamePtr(p1, p2) && isSamePtr(p2, p3)
-	&& t2.Alignment() <= t1.Alignment()
-	&& t3.Alignment() <= t1.Alignment()
-	&& registerizable(b, t2)
-	&& registerizable(b, t3)
-	&& o2 == t3.Size()
-	&& n == t2.Size() + t3.Size()
-	=> (Store {t2} (OffPtr <tt2> [o2] dst) d1
-		(Store {t3} (OffPtr <tt3> [0] dst) d2 mem))
-(Move {t1} [n] dst p1
-	mem:(Store {t2} op2:(OffPtr <tt2> [o2] p2) d1
-		(Store {t3} op3:(OffPtr <tt3> [o3] p3) d2
-			(Store {t4} op4:(OffPtr <tt4> [0] p4) d3 _))))
-	&& isSamePtr(p1, p2) && isSamePtr(p2, p3) && isSamePtr(p3, p4)
-	&& t2.Alignment() <= t1.Alignment()
-	&& t3.Alignment() <= t1.Alignment()
-	&& t4.Alignment() <= t1.Alignment()
-	&& registerizable(b, t2)
-	&& registerizable(b, t3)
-	&& registerizable(b, t4)
-	&& o3 == t4.Size()
-	&& o2-o3 == t3.Size()
-	&& n == t2.Size() + t3.Size() + t4.Size()
-	=> (Store {t2} (OffPtr <tt2> [o2] dst) d1
-		(Store {t3} (OffPtr <tt3> [o3] dst) d2
-			(Store {t4} (OffPtr <tt4> [0] dst) d3 mem)))
-(Move {t1} [n] dst p1
-	mem:(Store {t2} op2:(OffPtr <tt2> [o2] p2) d1
-		(Store {t3} op3:(OffPtr <tt3> [o3] p3) d2
-			(Store {t4} op4:(OffPtr <tt4> [o4] p4) d3
-				(Store {t5} op5:(OffPtr <tt5> [0] p5) d4 _)))))
-	&& isSamePtr(p1, p2) && isSamePtr(p2, p3) && isSamePtr(p3, p4) && isSamePtr(p4, p5)
-	&& t2.Alignment() <= t1.Alignment()
-	&& t3.Alignment() <= t1.Alignment()
-	&& t4.Alignment() <= t1.Alignment()
-	&& t5.Alignment() <= t1.Alignment()
-	&& registerizable(b, t2)
-	&& registerizable(b, t3)
-	&& registerizable(b, t4)
-	&& registerizable(b, t5)
-	&& o4 == t5.Size()
-	&& o3-o4 == t4.Size()
-	&& o2-o3 == t3.Size()
-	&& n == t2.Size() + t3.Size() + t4.Size() + t5.Size()
-	=> (Store {t2} (OffPtr <tt2> [o2] dst) d1
-		(Store {t3} (OffPtr <tt3> [o3] dst) d2
-			(Store {t4} (OffPtr <tt4> [o4] dst) d3
-				(Store {t5} (OffPtr <tt5> [0] dst) d4 mem))))
-
-// Same thing but with VarDef in the middle.
-(Move {t1} [n] dst p1
-	mem:(VarDef
-		(Store {t2} op2:(OffPtr <tt2> [o2] p2) d1
-			(Store {t3} op3:(OffPtr <tt3> [0] p3) d2 _))))
-	&& isSamePtr(p1, p2) && isSamePtr(p2, p3)
-	&& t2.Alignment() <= t1.Alignment()
-	&& t3.Alignment() <= t1.Alignment()
-	&& registerizable(b, t2)
-	&& registerizable(b, t3)
-	&& o2 == t3.Size()
-	&& n == t2.Size() + t3.Size()
-	=> (Store {t2} (OffPtr <tt2> [o2] dst) d1
-		(Store {t3} (OffPtr <tt3> [0] dst) d2 mem))
-(Move {t1} [n] dst p1
-	mem:(VarDef
-		(Store {t2} op2:(OffPtr <tt2> [o2] p2) d1
-			(Store {t3} op3:(OffPtr <tt3> [o3] p3) d2
-				(Store {t4} op4:(OffPtr <tt4> [0] p4) d3 _)))))
-	&& isSamePtr(p1, p2) && isSamePtr(p2, p3) && isSamePtr(p3, p4)
-	&& t2.Alignment() <= t1.Alignment()
-	&& t3.Alignment() <= t1.Alignment()
-	&& t4.Alignment() <= t1.Alignment()
-	&& registerizable(b, t2)
-	&& registerizable(b, t3)
-	&& registerizable(b, t4)
-	&& o3 == t4.Size()
-	&& o2-o3 == t3.Size()
-	&& n == t2.Size() + t3.Size() + t4.Size()
-	=> (Store {t2} (OffPtr <tt2> [o2] dst) d1
-		(Store {t3} (OffPtr <tt3> [o3] dst) d2
-			(Store {t4} (OffPtr <tt4> [0] dst) d3 mem)))
-(Move {t1} [n] dst p1
-	mem:(VarDef
-		(Store {t2} op2:(OffPtr <tt2> [o2] p2) d1
-			(Store {t3} op3:(OffPtr <tt3> [o3] p3) d2
-				(Store {t4} op4:(OffPtr <tt4> [o4] p4) d3
-					(Store {t5} op5:(OffPtr <tt5> [0] p5) d4 _))))))
-	&& isSamePtr(p1, p2) && isSamePtr(p2, p3) && isSamePtr(p3, p4) && isSamePtr(p4, p5)
-	&& t2.Alignment() <= t1.Alignment()
-	&& t3.Alignment() <= t1.Alignment()
-	&& t4.Alignment() <= t1.Alignment()
-	&& t5.Alignment() <= t1.Alignment()
-	&& registerizable(b, t2)
-	&& registerizable(b, t3)
-	&& registerizable(b, t4)
-	&& registerizable(b, t5)
-	&& o4 == t5.Size()
-	&& o3-o4 == t4.Size()
-	&& o2-o3 == t3.Size()
-	&& n == t2.Size() + t3.Size() + t4.Size() + t5.Size()
-	=> (Store {t2} (OffPtr <tt2> [o2] dst) d1
-		(Store {t3} (OffPtr <tt3> [o3] dst) d2
-			(Store {t4} (OffPtr <tt4> [o4] dst) d3
-				(Store {t5} (OffPtr <tt5> [0] dst) d4 mem))))
-
-// Prefer to Zero and Store than to Move.
-(Move {t1} [n] dst p1
-	mem:(Store {t2} op2:(OffPtr <tt2> [o2] p2) d1
-		(Zero {t3} [n] p3 _)))
-	&& isSamePtr(p1, p2) && isSamePtr(p2, p3)
-	&& t2.Alignment() <= t1.Alignment()
-	&& t3.Alignment() <= t1.Alignment()
-	&& registerizable(b, t2)
-	&& n >= o2 + t2.Size()
-	=> (Store {t2} (OffPtr <tt2> [o2] dst) d1
-		(Zero {t1} [n] dst mem))
-(Move {t1} [n] dst p1
-	mem:(Store {t2} (OffPtr <tt2> [o2] p2) d1
-		(Store {t3} (OffPtr <tt3> [o3] p3) d2
-			(Zero {t4} [n] p4 _))))
-	&& isSamePtr(p1, p2) && isSamePtr(p2, p3) && isSamePtr(p3, p4)
-	&& t2.Alignment() <= t1.Alignment()
-	&& t3.Alignment() <= t1.Alignment()
-	&& t4.Alignment() <= t1.Alignment()
-	&& registerizable(b, t2)
-	&& registerizable(b, t3)
-	&& n >= o2 + t2.Size()
-	&& n >= o3 + t3.Size()
-	=> (Store {t2} (OffPtr <tt2> [o2] dst) d1
-		(Store {t3} (OffPtr <tt3> [o3] dst) d2
-			(Zero {t1} [n] dst mem)))
-(Move {t1} [n] dst p1
-	mem:(Store {t2} (OffPtr <tt2> [o2] p2) d1
-		(Store {t3} (OffPtr <tt3> [o3] p3) d2
-			(Store {t4} (OffPtr <tt4> [o4] p4) d3
-				(Zero {t5} [n] p5 _)))))
-	&& isSamePtr(p1, p2) && isSamePtr(p2, p3) && isSamePtr(p3, p4) && isSamePtr(p4, p5)
-	&& t2.Alignment() <= t1.Alignment()
-	&& t3.Alignment() <= t1.Alignment()
-	&& t4.Alignment() <= t1.Alignment()
-	&& t5.Alignment() <= t1.Alignment()
-	&& registerizable(b, t2)
-	&& registerizable(b, t3)
-	&& registerizable(b, t4)
-	&& n >= o2 + t2.Size()
-	&& n >= o3 + t3.Size()
-	&& n >= o4 + t4.Size()
-	=> (Store {t2} (OffPtr <tt2> [o2] dst) d1
-		(Store {t3} (OffPtr <tt3> [o3] dst) d2
-			(Store {t4} (OffPtr <tt4> [o4] dst) d3
-				(Zero {t1} [n] dst mem))))
-(Move {t1} [n] dst p1
-	mem:(Store {t2} (OffPtr <tt2> [o2] p2) d1
-		(Store {t3} (OffPtr <tt3> [o3] p3) d2
-			(Store {t4} (OffPtr <tt4> [o4] p4) d3
-				(Store {t5} (OffPtr <tt5> [o5] p5) d4
-					(Zero {t6} [n] p6 _))))))
-	&& isSamePtr(p1, p2) && isSamePtr(p2, p3) && isSamePtr(p3, p4) && isSamePtr(p4, p5) && isSamePtr(p5, p6)
-	&& t2.Alignment() <= t1.Alignment()
-	&& t3.Alignment() <= t1.Alignment()
-	&& t4.Alignment() <= t1.Alignment()
-	&& t5.Alignment() <= t1.Alignment()
-	&& t6.Alignment() <= t1.Alignment()
-	&& registerizable(b, t2)
-	&& registerizable(b, t3)
-	&& registerizable(b, t4)
-	&& registerizable(b, t5)
-	&& n >= o2 + t2.Size()
-	&& n >= o3 + t3.Size()
-	&& n >= o4 + t4.Size()
-	&& n >= o5 + t5.Size()
-	=> (Store {t2} (OffPtr <tt2> [o2] dst) d1
-		(Store {t3} (OffPtr <tt3> [o3] dst) d2
-			(Store {t4} (OffPtr <tt4> [o4] dst) d3
-				(Store {t5} (OffPtr <tt5> [o5] dst) d4
-					(Zero {t1} [n] dst mem)))))
-(Move {t1} [n] dst p1
-	mem:(VarDef
-		(Store {t2} op2:(OffPtr <tt2> [o2] p2) d1
-			(Zero {t3} [n] p3 _))))
-	&& isSamePtr(p1, p2) && isSamePtr(p2, p3)
-	&& t2.Alignment() <= t1.Alignment()
-	&& t3.Alignment() <= t1.Alignment()
-	&& registerizable(b, t2)
-	&& n >= o2 + t2.Size()
-	=> (Store {t2} (OffPtr <tt2> [o2] dst) d1
-		(Zero {t1} [n] dst mem))
-(Move {t1} [n] dst p1
-	mem:(VarDef
-		(Store {t2} (OffPtr <tt2> [o2] p2) d1
-			(Store {t3} (OffPtr <tt3> [o3] p3) d2
-				(Zero {t4} [n] p4 _)))))
-	&& isSamePtr(p1, p2) && isSamePtr(p2, p3) && isSamePtr(p3, p4)
-	&& t2.Alignment() <= t1.Alignment()
-	&& t3.Alignment() <= t1.Alignment()
-	&& t4.Alignment() <= t1.Alignment()
-	&& registerizable(b, t2)
-	&& registerizable(b, t3)
-	&& n >= o2 + t2.Size()
-	&& n >= o3 + t3.Size()
-	=> (Store {t2} (OffPtr <tt2> [o2] dst) d1
-		(Store {t3} (OffPtr <tt3> [o3] dst) d2
-			(Zero {t1} [n] dst mem)))
-(Move {t1} [n] dst p1
-	mem:(VarDef
-		(Store {t2} (OffPtr <tt2> [o2] p2) d1
-			(Store {t3} (OffPtr <tt3> [o3] p3) d2
-				(Store {t4} (OffPtr <tt4> [o4] p4) d3
-					(Zero {t5} [n] p5 _))))))
-	&& isSamePtr(p1, p2) && isSamePtr(p2, p3) && isSamePtr(p3, p4) && isSamePtr(p4, p5)
-	&& t2.Alignment() <= t1.Alignment()
-	&& t3.Alignment() <= t1.Alignment()
-	&& t4.Alignment() <= t1.Alignment()
-	&& t5.Alignment() <= t1.Alignment()
-	&& registerizable(b, t2)
-	&& registerizable(b, t3)
-	&& registerizable(b, t4)
-	&& n >= o2 + t2.Size()
-	&& n >= o3 + t3.Size()
-	&& n >= o4 + t4.Size()
-	=> (Store {t2} (OffPtr <tt2> [o2] dst) d1
-		(Store {t3} (OffPtr <tt3> [o3] dst) d2
-			(Store {t4} (OffPtr <tt4> [o4] dst) d3
-				(Zero {t1} [n] dst mem))))
-(Move {t1} [n] dst p1
-	mem:(VarDef
-		(Store {t2} (OffPtr <tt2> [o2] p2) d1
-			(Store {t3} (OffPtr <tt3> [o3] p3) d2
-				(Store {t4} (OffPtr <tt4> [o4] p4) d3
-					(Store {t5} (OffPtr <tt5> [o5] p5) d4
-						(Zero {t6} [n] p6 _)))))))
-	&& isSamePtr(p1, p2) && isSamePtr(p2, p3) && isSamePtr(p3, p4) && isSamePtr(p4, p5) && isSamePtr(p5, p6)
-	&& t2.Alignment() <= t1.Alignment()
-	&& t3.Alignment() <= t1.Alignment()
-	&& t4.Alignment() <= t1.Alignment()
-	&& t5.Alignment() <= t1.Alignment()
-	&& t6.Alignment() <= t1.Alignment()
-	&& registerizable(b, t2)
-	&& registerizable(b, t3)
-	&& registerizable(b, t4)
-	&& registerizable(b, t5)
-	&& n >= o2 + t2.Size()
-	&& n >= o3 + t3.Size()
-	&& n >= o4 + t4.Size()
-	&& n >= o5 + t5.Size()
-	=> (Store {t2} (OffPtr <tt2> [o2] dst) d1
-		(Store {t3} (OffPtr <tt3> [o3] dst) d2
-			(Store {t4} (OffPtr <tt4> [o4] dst) d3
-				(Store {t5} (OffPtr <tt5> [o5] dst) d4
-					(Zero {t1} [n] dst mem)))))
-
-(SelectN [0] call:(StaticLECall {sym} a x)) && needRaceCleanup(sym, call) && clobber(call) => x
-(SelectN [0] call:(StaticLECall {sym} x)) && needRaceCleanup(sym, call) && clobber(call) => x
-
-// Collapse moving A -> B -> C into just A -> C.
-// Later passes (deadstore, elim unread auto) will remove the A -> B move, if possible.
-// This happens most commonly when B is an autotmp inserted earlier
-// during compilation to ensure correctness.
-// Take care that overlapping moves are preserved.
-// Restrict this optimization to the stack, to avoid duplicating loads from the heap;
-// see CL 145208 for discussion.
-(Move {t1} [s] dst tmp1 midmem:(Move {t2} [s] tmp2 src _))
-	&& t1.Compare(t2) == types.CMPeq
-	&& isSamePtr(tmp1, tmp2)
-	&& isStackPtr(src) && !isVolatile(src)
-	&& disjoint(src, s, tmp2, s)
-	&& (disjoint(src, s, dst, s) || isInlinableMemmove(dst, src, s, config))
-	=> (Move {t1} [s] dst src midmem)
-
-// Same, but for large types that require VarDefs.
-(Move {t1} [s] dst tmp1 midmem:(VarDef (Move {t2} [s] tmp2 src _)))
-	&& t1.Compare(t2) == types.CMPeq
-	&& isSamePtr(tmp1, tmp2)
-	&& isStackPtr(src) && !isVolatile(src)
-	&& disjoint(src, s, tmp2, s)
-	&& (disjoint(src, s, dst, s) || isInlinableMemmove(dst, src, s, config))
-	=> (Move {t1} [s] dst src midmem)
-
-// Don't zero the same bits twice.
-(Zero {t} [s] dst1 zero:(Zero {t} [s] dst2 _)) && isSamePtr(dst1, dst2) => zero
-(Zero {t} [s] dst1 vardef:(VarDef (Zero {t} [s] dst2 _))) && isSamePtr(dst1, dst2) => vardef
-
-// Elide self-moves. This only happens rarely (e.g test/fixedbugs/bug277.go).
-// However, this rule is needed to prevent the previous rule from looping forever in such cases.
-(Move dst src mem) && isSamePtr(dst, src) => mem
diff --git a/src/cmd/compile/internal/ssa/gen/genericOps.go b/src/cmd/compile/internal/ssa/gen/genericOps.go
deleted file mode 100644
index e04b7db..0000000
--- a/src/cmd/compile/internal/ssa/gen/genericOps.go
+++ /dev/null
@@ -1,661 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build ignore
-// +build ignore
-
-package main
-
-// Generic opcodes typically specify a width. The inputs and outputs
-// of that op are the given number of bits wide. There is no notion of
-// "sign", so Add32 can be used both for signed and unsigned 32-bit
-// addition.
-
-// Signed/unsigned is explicit with the extension ops
-// (SignExt*/ZeroExt*) and implicit as the arg to some opcodes
-// (e.g. the second argument to shifts is unsigned). If not mentioned,
-// all args take signed inputs, or don't care whether their inputs
-// are signed or unsigned.
-
-var genericOps = []opData{
-	// 2-input arithmetic
-	// Types must be consistent with Go typing. Add, for example, must take two values
-	// of the same type and produces that same type.
-	{name: "Add8", argLength: 2, commutative: true}, // arg0 + arg1
-	{name: "Add16", argLength: 2, commutative: true},
-	{name: "Add32", argLength: 2, commutative: true},
-	{name: "Add64", argLength: 2, commutative: true},
-	{name: "AddPtr", argLength: 2}, // For address calculations.  arg0 is a pointer and arg1 is an int.
-	{name: "Add32F", argLength: 2, commutative: true},
-	{name: "Add64F", argLength: 2, commutative: true},
-
-	{name: "Sub8", argLength: 2}, // arg0 - arg1
-	{name: "Sub16", argLength: 2},
-	{name: "Sub32", argLength: 2},
-	{name: "Sub64", argLength: 2},
-	{name: "SubPtr", argLength: 2},
-	{name: "Sub32F", argLength: 2},
-	{name: "Sub64F", argLength: 2},
-
-	{name: "Mul8", argLength: 2, commutative: true}, // arg0 * arg1
-	{name: "Mul16", argLength: 2, commutative: true},
-	{name: "Mul32", argLength: 2, commutative: true},
-	{name: "Mul64", argLength: 2, commutative: true},
-	{name: "Mul32F", argLength: 2, commutative: true},
-	{name: "Mul64F", argLength: 2, commutative: true},
-
-	{name: "Div32F", argLength: 2}, // arg0 / arg1
-	{name: "Div64F", argLength: 2},
-
-	{name: "Hmul32", argLength: 2, commutative: true},
-	{name: "Hmul32u", argLength: 2, commutative: true},
-	{name: "Hmul64", argLength: 2, commutative: true},
-	{name: "Hmul64u", argLength: 2, commutative: true},
-
-	{name: "Mul32uhilo", argLength: 2, typ: "(UInt32,UInt32)", commutative: true}, // arg0 * arg1, returns (hi, lo)
-	{name: "Mul64uhilo", argLength: 2, typ: "(UInt64,UInt64)", commutative: true}, // arg0 * arg1, returns (hi, lo)
-
-	{name: "Mul32uover", argLength: 2, typ: "(UInt32,Bool)", commutative: true}, // Let x = arg0*arg1 (full 32x32-> 64 unsigned multiply), returns (uint32(x), (uint32(x) != x))
-	{name: "Mul64uover", argLength: 2, typ: "(UInt64,Bool)", commutative: true}, // Let x = arg0*arg1 (full 64x64->128 unsigned multiply), returns (uint64(x), (uint64(x) != x))
-
-	// Weird special instructions for use in the strength reduction of divides.
-	// These ops compute unsigned (arg0 + arg1) / 2, correct to all
-	// 32/64 bits, even when the intermediate result of the add has 33/65 bits.
-	// These ops can assume arg0 >= arg1.
-	// Note: these ops aren't commutative!
-	{name: "Avg32u", argLength: 2, typ: "UInt32"}, // 32-bit platforms only
-	{name: "Avg64u", argLength: 2, typ: "UInt64"}, // 64-bit platforms only
-
-	// For Div16, Div32 and Div64, AuxInt non-zero means that the divisor has been proved to be not -1
-	// or that the dividend is not the most negative value.
-	{name: "Div8", argLength: 2},  // arg0 / arg1, signed
-	{name: "Div8u", argLength: 2}, // arg0 / arg1, unsigned
-	{name: "Div16", argLength: 2, aux: "Bool"},
-	{name: "Div16u", argLength: 2},
-	{name: "Div32", argLength: 2, aux: "Bool"},
-	{name: "Div32u", argLength: 2},
-	{name: "Div64", argLength: 2, aux: "Bool"},
-	{name: "Div64u", argLength: 2},
-	{name: "Div128u", argLength: 3}, // arg0:arg1 / arg2 (128-bit divided by 64-bit), returns (q, r)
-
-	// For Mod16, Mod32 and Mod64, AuxInt non-zero means that the divisor has been proved to be not -1.
-	{name: "Mod8", argLength: 2},  // arg0 % arg1, signed
-	{name: "Mod8u", argLength: 2}, // arg0 % arg1, unsigned
-	{name: "Mod16", argLength: 2, aux: "Bool"},
-	{name: "Mod16u", argLength: 2},
-	{name: "Mod32", argLength: 2, aux: "Bool"},
-	{name: "Mod32u", argLength: 2},
-	{name: "Mod64", argLength: 2, aux: "Bool"},
-	{name: "Mod64u", argLength: 2},
-
-	{name: "And8", argLength: 2, commutative: true}, // arg0 & arg1
-	{name: "And16", argLength: 2, commutative: true},
-	{name: "And32", argLength: 2, commutative: true},
-	{name: "And64", argLength: 2, commutative: true},
-
-	{name: "Or8", argLength: 2, commutative: true}, // arg0 | arg1
-	{name: "Or16", argLength: 2, commutative: true},
-	{name: "Or32", argLength: 2, commutative: true},
-	{name: "Or64", argLength: 2, commutative: true},
-
-	{name: "Xor8", argLength: 2, commutative: true}, // arg0 ^ arg1
-	{name: "Xor16", argLength: 2, commutative: true},
-	{name: "Xor32", argLength: 2, commutative: true},
-	{name: "Xor64", argLength: 2, commutative: true},
-
-	// For shifts, AxB means the shifted value has A bits and the shift amount has B bits.
-	// Shift amounts are considered unsigned.
-	// If arg1 is known to be nonnegative and less than the number of bits in arg0,
-	// then auxInt may be set to 1.
-	// This enables better code generation on some platforms.
-	{name: "Lsh8x8", argLength: 2, aux: "Bool"}, // arg0 << arg1
-	{name: "Lsh8x16", argLength: 2, aux: "Bool"},
-	{name: "Lsh8x32", argLength: 2, aux: "Bool"},
-	{name: "Lsh8x64", argLength: 2, aux: "Bool"},
-	{name: "Lsh16x8", argLength: 2, aux: "Bool"},
-	{name: "Lsh16x16", argLength: 2, aux: "Bool"},
-	{name: "Lsh16x32", argLength: 2, aux: "Bool"},
-	{name: "Lsh16x64", argLength: 2, aux: "Bool"},
-	{name: "Lsh32x8", argLength: 2, aux: "Bool"},
-	{name: "Lsh32x16", argLength: 2, aux: "Bool"},
-	{name: "Lsh32x32", argLength: 2, aux: "Bool"},
-	{name: "Lsh32x64", argLength: 2, aux: "Bool"},
-	{name: "Lsh64x8", argLength: 2, aux: "Bool"},
-	{name: "Lsh64x16", argLength: 2, aux: "Bool"},
-	{name: "Lsh64x32", argLength: 2, aux: "Bool"},
-	{name: "Lsh64x64", argLength: 2, aux: "Bool"},
-
-	{name: "Rsh8x8", argLength: 2, aux: "Bool"}, // arg0 >> arg1, signed
-	{name: "Rsh8x16", argLength: 2, aux: "Bool"},
-	{name: "Rsh8x32", argLength: 2, aux: "Bool"},
-	{name: "Rsh8x64", argLength: 2, aux: "Bool"},
-	{name: "Rsh16x8", argLength: 2, aux: "Bool"},
-	{name: "Rsh16x16", argLength: 2, aux: "Bool"},
-	{name: "Rsh16x32", argLength: 2, aux: "Bool"},
-	{name: "Rsh16x64", argLength: 2, aux: "Bool"},
-	{name: "Rsh32x8", argLength: 2, aux: "Bool"},
-	{name: "Rsh32x16", argLength: 2, aux: "Bool"},
-	{name: "Rsh32x32", argLength: 2, aux: "Bool"},
-	{name: "Rsh32x64", argLength: 2, aux: "Bool"},
-	{name: "Rsh64x8", argLength: 2, aux: "Bool"},
-	{name: "Rsh64x16", argLength: 2, aux: "Bool"},
-	{name: "Rsh64x32", argLength: 2, aux: "Bool"},
-	{name: "Rsh64x64", argLength: 2, aux: "Bool"},
-
-	{name: "Rsh8Ux8", argLength: 2, aux: "Bool"}, // arg0 >> arg1, unsigned
-	{name: "Rsh8Ux16", argLength: 2, aux: "Bool"},
-	{name: "Rsh8Ux32", argLength: 2, aux: "Bool"},
-	{name: "Rsh8Ux64", argLength: 2, aux: "Bool"},
-	{name: "Rsh16Ux8", argLength: 2, aux: "Bool"},
-	{name: "Rsh16Ux16", argLength: 2, aux: "Bool"},
-	{name: "Rsh16Ux32", argLength: 2, aux: "Bool"},
-	{name: "Rsh16Ux64", argLength: 2, aux: "Bool"},
-	{name: "Rsh32Ux8", argLength: 2, aux: "Bool"},
-	{name: "Rsh32Ux16", argLength: 2, aux: "Bool"},
-	{name: "Rsh32Ux32", argLength: 2, aux: "Bool"},
-	{name: "Rsh32Ux64", argLength: 2, aux: "Bool"},
-	{name: "Rsh64Ux8", argLength: 2, aux: "Bool"},
-	{name: "Rsh64Ux16", argLength: 2, aux: "Bool"},
-	{name: "Rsh64Ux32", argLength: 2, aux: "Bool"},
-	{name: "Rsh64Ux64", argLength: 2, aux: "Bool"},
-
-	// 2-input comparisons
-	{name: "Eq8", argLength: 2, commutative: true, typ: "Bool"}, // arg0 == arg1
-	{name: "Eq16", argLength: 2, commutative: true, typ: "Bool"},
-	{name: "Eq32", argLength: 2, commutative: true, typ: "Bool"},
-	{name: "Eq64", argLength: 2, commutative: true, typ: "Bool"},
-	{name: "EqPtr", argLength: 2, commutative: true, typ: "Bool"},
-	{name: "EqInter", argLength: 2, typ: "Bool"}, // arg0 or arg1 is nil; other cases handled by frontend
-	{name: "EqSlice", argLength: 2, typ: "Bool"}, // arg0 or arg1 is nil; other cases handled by frontend
-	{name: "Eq32F", argLength: 2, commutative: true, typ: "Bool"},
-	{name: "Eq64F", argLength: 2, commutative: true, typ: "Bool"},
-
-	{name: "Neq8", argLength: 2, commutative: true, typ: "Bool"}, // arg0 != arg1
-	{name: "Neq16", argLength: 2, commutative: true, typ: "Bool"},
-	{name: "Neq32", argLength: 2, commutative: true, typ: "Bool"},
-	{name: "Neq64", argLength: 2, commutative: true, typ: "Bool"},
-	{name: "NeqPtr", argLength: 2, commutative: true, typ: "Bool"},
-	{name: "NeqInter", argLength: 2, typ: "Bool"}, // arg0 or arg1 is nil; other cases handled by frontend
-	{name: "NeqSlice", argLength: 2, typ: "Bool"}, // arg0 or arg1 is nil; other cases handled by frontend
-	{name: "Neq32F", argLength: 2, commutative: true, typ: "Bool"},
-	{name: "Neq64F", argLength: 2, commutative: true, typ: "Bool"},
-
-	{name: "Less8", argLength: 2, typ: "Bool"},  // arg0 < arg1, signed
-	{name: "Less8U", argLength: 2, typ: "Bool"}, // arg0 < arg1, unsigned
-	{name: "Less16", argLength: 2, typ: "Bool"},
-	{name: "Less16U", argLength: 2, typ: "Bool"},
-	{name: "Less32", argLength: 2, typ: "Bool"},
-	{name: "Less32U", argLength: 2, typ: "Bool"},
-	{name: "Less64", argLength: 2, typ: "Bool"},
-	{name: "Less64U", argLength: 2, typ: "Bool"},
-	{name: "Less32F", argLength: 2, typ: "Bool"},
-	{name: "Less64F", argLength: 2, typ: "Bool"},
-
-	{name: "Leq8", argLength: 2, typ: "Bool"},  // arg0 <= arg1, signed
-	{name: "Leq8U", argLength: 2, typ: "Bool"}, // arg0 <= arg1, unsigned
-	{name: "Leq16", argLength: 2, typ: "Bool"},
-	{name: "Leq16U", argLength: 2, typ: "Bool"},
-	{name: "Leq32", argLength: 2, typ: "Bool"},
-	{name: "Leq32U", argLength: 2, typ: "Bool"},
-	{name: "Leq64", argLength: 2, typ: "Bool"},
-	{name: "Leq64U", argLength: 2, typ: "Bool"},
-	{name: "Leq32F", argLength: 2, typ: "Bool"},
-	{name: "Leq64F", argLength: 2, typ: "Bool"},
-
-	// the type of a CondSelect is the same as the type of its first
-	// two arguments, which should be register-width scalars; the third
-	// argument should be a boolean
-	{name: "CondSelect", argLength: 3}, // arg2 ? arg0 : arg1
-
-	// boolean ops
-	{name: "AndB", argLength: 2, commutative: true, typ: "Bool"}, // arg0 && arg1 (not shortcircuited)
-	{name: "OrB", argLength: 2, commutative: true, typ: "Bool"},  // arg0 || arg1 (not shortcircuited)
-	{name: "EqB", argLength: 2, commutative: true, typ: "Bool"},  // arg0 == arg1
-	{name: "NeqB", argLength: 2, commutative: true, typ: "Bool"}, // arg0 != arg1
-	{name: "Not", argLength: 1, typ: "Bool"},                     // !arg0, boolean
-
-	// 1-input ops
-	{name: "Neg8", argLength: 1}, // -arg0
-	{name: "Neg16", argLength: 1},
-	{name: "Neg32", argLength: 1},
-	{name: "Neg64", argLength: 1},
-	{name: "Neg32F", argLength: 1},
-	{name: "Neg64F", argLength: 1},
-
-	{name: "Com8", argLength: 1}, // ^arg0
-	{name: "Com16", argLength: 1},
-	{name: "Com32", argLength: 1},
-	{name: "Com64", argLength: 1},
-
-	{name: "Ctz8", argLength: 1},         // Count trailing (low order) zeroes (returns 0-8)
-	{name: "Ctz16", argLength: 1},        // Count trailing (low order) zeroes (returns 0-16)
-	{name: "Ctz32", argLength: 1},        // Count trailing (low order) zeroes (returns 0-32)
-	{name: "Ctz64", argLength: 1},        // Count trailing (low order) zeroes (returns 0-64)
-	{name: "Ctz8NonZero", argLength: 1},  // same as above, but arg[0] known to be non-zero, returns 0-7
-	{name: "Ctz16NonZero", argLength: 1}, // same as above, but arg[0] known to be non-zero, returns 0-15
-	{name: "Ctz32NonZero", argLength: 1}, // same as above, but arg[0] known to be non-zero, returns 0-31
-	{name: "Ctz64NonZero", argLength: 1}, // same as above, but arg[0] known to be non-zero, returns 0-63
-	{name: "BitLen8", argLength: 1},      // Number of bits in arg[0] (returns 0-8)
-	{name: "BitLen16", argLength: 1},     // Number of bits in arg[0] (returns 0-16)
-	{name: "BitLen32", argLength: 1},     // Number of bits in arg[0] (returns 0-32)
-	{name: "BitLen64", argLength: 1},     // Number of bits in arg[0] (returns 0-64)
-
-	{name: "Bswap32", argLength: 1}, // Swap bytes
-	{name: "Bswap64", argLength: 1}, // Swap bytes
-
-	{name: "BitRev8", argLength: 1},  // Reverse the bits in arg[0]
-	{name: "BitRev16", argLength: 1}, // Reverse the bits in arg[0]
-	{name: "BitRev32", argLength: 1}, // Reverse the bits in arg[0]
-	{name: "BitRev64", argLength: 1}, // Reverse the bits in arg[0]
-
-	{name: "PopCount8", argLength: 1},    // Count bits in arg[0]
-	{name: "PopCount16", argLength: 1},   // Count bits in arg[0]
-	{name: "PopCount32", argLength: 1},   // Count bits in arg[0]
-	{name: "PopCount64", argLength: 1},   // Count bits in arg[0]
-	{name: "RotateLeft8", argLength: 2},  // Rotate bits in arg[0] left by arg[1]
-	{name: "RotateLeft16", argLength: 2}, // Rotate bits in arg[0] left by arg[1]
-	{name: "RotateLeft32", argLength: 2}, // Rotate bits in arg[0] left by arg[1]
-	{name: "RotateLeft64", argLength: 2}, // Rotate bits in arg[0] left by arg[1]
-
-	// Square root.
-	// Special cases:
-	//   +∞  → +∞
-	//   ±0  → ±0 (sign preserved)
-	//   x<0 → NaN
-	//   NaN → NaN
-	{name: "Sqrt", argLength: 1},   // √arg0 (floating point, double precision)
-	{name: "Sqrt32", argLength: 1}, // √arg0 (floating point, single precision)
-
-	// Round to integer, float64 only.
-	// Special cases:
-	//   ±∞  → ±∞ (sign preserved)
-	//   ±0  → ±0 (sign preserved)
-	//   NaN → NaN
-	{name: "Floor", argLength: 1},       // round arg0 toward -∞
-	{name: "Ceil", argLength: 1},        // round arg0 toward +∞
-	{name: "Trunc", argLength: 1},       // round arg0 toward 0
-	{name: "Round", argLength: 1},       // round arg0 to nearest, ties away from 0
-	{name: "RoundToEven", argLength: 1}, // round arg0 to nearest, ties to even
-
-	// Modify the sign bit
-	{name: "Abs", argLength: 1},      // absolute value arg0
-	{name: "Copysign", argLength: 2}, // copy sign from arg0 to arg1
-
-	// 3-input opcode.
-	// Fused-multiply-add, float64 only.
-	// When a*b+c is exactly zero (before rounding), then the result is +0 or -0.
-	// The 0's sign is determined according to the standard rules for the
-	// addition (-0 if both a*b and c are -0, +0 otherwise).
-	//
-	// Otherwise, when a*b+c rounds to zero, then the resulting 0's sign is
-	// determined by the sign of the exact result a*b+c.
-	// See section 6.3 in ieee754.
-	//
-	// When the multiply is an infinity times a zero, the result is NaN.
-	// See section 7.2 in ieee754.
-	{name: "FMA", argLength: 3}, // compute (a*b)+c without intermediate rounding
-
-	// Data movement. Max argument length for Phi is indefinite.
-	{name: "Phi", argLength: -1, zeroWidth: true}, // select an argument based on which predecessor block we came from
-	{name: "Copy", argLength: 1},                  // output = arg0
-	// Convert converts between pointers and integers.
-	// We have a special op for this so as to not confuse GC
-	// (particularly stack maps).  It takes a memory arg so it
-	// gets correctly ordered with respect to GC safepoints.
-	// It gets compiled to nothing, so its result must in the same
-	// register as its argument. regalloc knows it can use any
-	// allocatable integer register for OpConvert.
-	// arg0=ptr/int arg1=mem, output=int/ptr
-	{name: "Convert", argLength: 2, zeroWidth: true, resultInArg0: true},
-
-	// constants. Constant values are stored in the aux or
-	// auxint fields.
-	{name: "ConstBool", aux: "Bool"},     // auxint is 0 for false and 1 for true
-	{name: "ConstString", aux: "String"}, // value is aux.(string)
-	{name: "ConstNil", typ: "BytePtr"},   // nil pointer
-	{name: "Const8", aux: "Int8"},        // auxint is sign-extended 8 bits
-	{name: "Const16", aux: "Int16"},      // auxint is sign-extended 16 bits
-	{name: "Const32", aux: "Int32"},      // auxint is sign-extended 32 bits
-	// Note: ConstX are sign-extended even when the type of the value is unsigned.
-	// For instance, uint8(0xaa) is stored as auxint=0xffffffffffffffaa.
-	{name: "Const64", aux: "Int64"}, // value is auxint
-	// Note: for both Const32F and Const64F, we disallow encoding NaNs.
-	// Signaling NaNs are tricky because if you do anything with them, they become quiet.
-	// Particularly, converting a 32 bit sNaN to 64 bit and back converts it to a qNaN.
-	// See issue 36399 and 36400.
-	// Encodings of +inf, -inf, and -0 are fine.
-	{name: "Const32F", aux: "Float32"}, // value is math.Float64frombits(uint64(auxint)) and is exactly representable as float 32
-	{name: "Const64F", aux: "Float64"}, // value is math.Float64frombits(uint64(auxint))
-	{name: "ConstInterface"},           // nil interface
-	{name: "ConstSlice"},               // nil slice
-
-	// Constant-like things
-	{name: "InitMem", zeroWidth: true},                               // memory input to the function.
-	{name: "Arg", aux: "SymOff", symEffect: "Read", zeroWidth: true}, // argument to the function.  aux=GCNode of arg, off = offset in that arg.
-
-	// Like Arg, these are generic ops that survive lowering. AuxInt is a register index, and the actual output register for each index is defined by the architecture.
-	// AuxInt = integer argument index (not a register number). ABI-specified spill loc obtained from function
-	{name: "ArgIntReg", aux: "NameOffsetInt8", zeroWidth: true},   // argument to the function in an int reg.
-	{name: "ArgFloatReg", aux: "NameOffsetInt8", zeroWidth: true}, // argument to the function in a float reg.
-
-	// The address of a variable.  arg0 is the base pointer.
-	// If the variable is a global, the base pointer will be SB and
-	// the Aux field will be a *obj.LSym.
-	// If the variable is a local, the base pointer will be SP and
-	// the Aux field will be a *gc.Node.
-	{name: "Addr", argLength: 1, aux: "Sym", symEffect: "Addr"},      // Address of a variable.  Arg0=SB.  Aux identifies the variable.
-	{name: "LocalAddr", argLength: 2, aux: "Sym", symEffect: "Addr"}, // Address of a variable.  Arg0=SP. Arg1=mem. Aux identifies the variable.
-
-	{name: "SP", zeroWidth: true},                 // stack pointer
-	{name: "SB", typ: "Uintptr", zeroWidth: true}, // static base pointer (a.k.a. globals pointer)
-	{name: "Invalid"},                             // unused value
-
-	// Memory operations
-	{name: "Load", argLength: 2},                          // Load from arg0.  arg1=memory
-	{name: "Dereference", argLength: 2},                   // Load from arg0.  arg1=memory.  Helper op for arg/result passing, result is an otherwise not-SSA-able "value".
-	{name: "Store", argLength: 3, typ: "Mem", aux: "Typ"}, // Store arg1 to arg0.  arg2=memory, aux=type.  Returns memory.
-	// The source and destination of Move may overlap in some cases. See e.g.
-	// memmove inlining in generic.rules. When inlineablememmovesize (in ../rewrite.go)
-	// returns true, we must do all loads before all stores, when lowering Move.
-	// The type of Move is used for the write barrier pass to insert write barriers
-	// and for alignment on some architectures.
-	// For pointerless types, it is possible for the type to be inaccurate.
-	// For type alignment and pointer information, use the type in Aux;
-	// for type size, use the size in AuxInt.
-	// The "inline runtime.memmove" rewrite rule generates Moves with inaccurate types,
-	// such as type byte instead of the more accurate type [8]byte.
-	{name: "Move", argLength: 3, typ: "Mem", aux: "TypSize"}, // arg0=destptr, arg1=srcptr, arg2=mem, auxint=size, aux=type.  Returns memory.
-	{name: "Zero", argLength: 2, typ: "Mem", aux: "TypSize"}, // arg0=destptr, arg1=mem, auxint=size, aux=type. Returns memory.
-
-	// Memory operations with write barriers.
-	// Expand to runtime calls. Write barrier will be removed if write on stack.
-	{name: "StoreWB", argLength: 3, typ: "Mem", aux: "Typ"},    // Store arg1 to arg0. arg2=memory, aux=type.  Returns memory.
-	{name: "MoveWB", argLength: 3, typ: "Mem", aux: "TypSize"}, // arg0=destptr, arg1=srcptr, arg2=mem, auxint=size, aux=type.  Returns memory.
-	{name: "ZeroWB", argLength: 2, typ: "Mem", aux: "TypSize"}, // arg0=destptr, arg1=mem, auxint=size, aux=type. Returns memory.
-
-	// WB invokes runtime.gcWriteBarrier. This is not a normal
-	// call: it takes arguments in registers, doesn't clobber
-	// general-purpose registers (the exact clobber set is
-	// arch-dependent), and is not a safe-point.
-	{name: "WB", argLength: 3, typ: "Mem", aux: "Sym", symEffect: "None"}, // arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
-
-	{name: "HasCPUFeature", argLength: 0, typ: "bool", aux: "Sym", symEffect: "None"}, // aux=place that this feature flag can be loaded from
-
-	// PanicBounds and PanicExtend generate a runtime panic.
-	// Their arguments provide index values to use in panic messages.
-	// Both PanicBounds and PanicExtend have an AuxInt value from the BoundsKind type (in ../op.go).
-	// PanicBounds' index is int sized.
-	// PanicExtend's index is int64 sized. (PanicExtend is only used on 32-bit archs.)
-	{name: "PanicBounds", argLength: 3, aux: "Int64", typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory.
-	{name: "PanicExtend", argLength: 4, aux: "Int64", typ: "Mem", call: true}, // arg0=idxHi, arg1=idxLo, arg2=len, arg3=mem, returns memory.
-
-	// Function calls. Arguments to the call have already been written to the stack.
-	// Return values appear on the stack. The method receiver, if any, is treated
-	// as a phantom first argument.
-	// TODO(josharian): ClosureCall and InterCall should have Int32 aux
-	// to match StaticCall's 32 bit arg size limit.
-	// TODO(drchase,josharian): could the arg size limit be bundled into the rules for CallOff?
-
-	// Before lowering, LECalls receive their fixed inputs (first), memory (last),
-	// and a variable number of input values in the middle.
-	// They produce a variable number of result values.
-	// These values are not necessarily "SSA-able"; they can be too large,
-	// but in that case inputs are loaded immediately before with OpDereference,
-	// and outputs are stored immediately with OpStore.
-	//
-	// After call expansion, Calls have the same fixed-middle-memory arrangement of inputs,
-	// with the difference that the "middle" is only the register-resident inputs,
-	// and the non-register inputs are instead stored at ABI-defined offsets from SP
-	// (and the stores thread through the memory that is ultimately an input to the call).
-	// Outputs follow a similar pattern; register-resident outputs are the leading elements
-	// of a Result-typed output, with memory last, and any memory-resident outputs have been
-	// stored to ABI-defined locations.  Each non-memory input or output fits in a register.
-	//
-	// Subsequent architecture-specific lowering only changes the opcode.
-
-	{name: "ClosureCall", argLength: -1, aux: "CallOff", call: true}, // arg0=code pointer, arg1=context ptr, arg2..argN-1 are register inputs, argN=memory.  auxint=arg size.  Returns Result of register results, plus memory.
-	{name: "StaticCall", argLength: -1, aux: "CallOff", call: true},  // call function aux.(*obj.LSym), arg0..argN-1 are register inputs, argN=memory.  auxint=arg size.  Returns Result of register results, plus memory.
-	{name: "InterCall", argLength: -1, aux: "CallOff", call: true},   // interface call.  arg0=code pointer, arg1..argN-1 are register inputs, argN=memory, auxint=arg size.  Returns Result of register results, plus memory.
-	{name: "TailCall", argLength: -1, aux: "CallOff", call: true},    // tail call function aux.(*obj.LSym), arg0..argN-1 are register inputs, argN=memory.  auxint=arg size.  Returns Result of register results, plus memory.
-
-	{name: "ClosureLECall", argLength: -1, aux: "CallOff", call: true}, // late-expanded closure call. arg0=code pointer, arg1=context ptr,  arg2..argN-1 are inputs, argN is mem. auxint = arg size. Result is tuple of result(s), plus mem.
-	{name: "StaticLECall", argLength: -1, aux: "CallOff", call: true},  // late-expanded static call function aux.(*ssa.AuxCall.Fn). arg0..argN-1 are inputs, argN is mem. auxint = arg size. Result is tuple of result(s), plus mem.
-	{name: "InterLECall", argLength: -1, aux: "CallOff", call: true},   // late-expanded interface call. arg0=code pointer, arg1..argN-1 are inputs, argN is mem. auxint = arg size. Result is tuple of result(s), plus mem.
-	{name: "TailLECall", argLength: -1, aux: "CallOff", call: true},    // late-expanded static tail call function aux.(*ssa.AuxCall.Fn). arg0..argN-1 are inputs, argN is mem. auxint = arg size. Result is tuple of result(s), plus mem.
-
-	// Conversions: signed extensions, zero (unsigned) extensions, truncations
-	{name: "SignExt8to16", argLength: 1, typ: "Int16"},
-	{name: "SignExt8to32", argLength: 1, typ: "Int32"},
-	{name: "SignExt8to64", argLength: 1, typ: "Int64"},
-	{name: "SignExt16to32", argLength: 1, typ: "Int32"},
-	{name: "SignExt16to64", argLength: 1, typ: "Int64"},
-	{name: "SignExt32to64", argLength: 1, typ: "Int64"},
-	{name: "ZeroExt8to16", argLength: 1, typ: "UInt16"},
-	{name: "ZeroExt8to32", argLength: 1, typ: "UInt32"},
-	{name: "ZeroExt8to64", argLength: 1, typ: "UInt64"},
-	{name: "ZeroExt16to32", argLength: 1, typ: "UInt32"},
-	{name: "ZeroExt16to64", argLength: 1, typ: "UInt64"},
-	{name: "ZeroExt32to64", argLength: 1, typ: "UInt64"},
-	{name: "Trunc16to8", argLength: 1},
-	{name: "Trunc32to8", argLength: 1},
-	{name: "Trunc32to16", argLength: 1},
-	{name: "Trunc64to8", argLength: 1},
-	{name: "Trunc64to16", argLength: 1},
-	{name: "Trunc64to32", argLength: 1},
-
-	{name: "Cvt32to32F", argLength: 1},
-	{name: "Cvt32to64F", argLength: 1},
-	{name: "Cvt64to32F", argLength: 1},
-	{name: "Cvt64to64F", argLength: 1},
-	{name: "Cvt32Fto32", argLength: 1},
-	{name: "Cvt32Fto64", argLength: 1},
-	{name: "Cvt64Fto32", argLength: 1},
-	{name: "Cvt64Fto64", argLength: 1},
-	{name: "Cvt32Fto64F", argLength: 1},
-	{name: "Cvt64Fto32F", argLength: 1},
-	{name: "CvtBoolToUint8", argLength: 1},
-
-	// Force rounding to precision of type.
-	{name: "Round32F", argLength: 1},
-	{name: "Round64F", argLength: 1},
-
-	// Automatically inserted safety checks
-	{name: "IsNonNil", argLength: 1, typ: "Bool"},        // arg0 != nil
-	{name: "IsInBounds", argLength: 2, typ: "Bool"},      // 0 <= arg0 < arg1. arg1 is guaranteed >= 0.
-	{name: "IsSliceInBounds", argLength: 2, typ: "Bool"}, // 0 <= arg0 <= arg1. arg1 is guaranteed >= 0.
-	{name: "NilCheck", argLength: 2, typ: "Void"},        // arg0=ptr, arg1=mem. Panics if arg0 is nil. Returns void.
-
-	// Pseudo-ops
-	{name: "GetG", argLength: 1, zeroWidth: true}, // runtime.getg() (read g pointer). arg0=mem
-	{name: "GetClosurePtr"},                       // get closure pointer from dedicated register
-	{name: "GetCallerPC"},                         // for getcallerpc intrinsic
-	{name: "GetCallerSP"},                         // for getcallersp intrinsic
-
-	// Indexing operations
-	{name: "PtrIndex", argLength: 2},             // arg0=ptr, arg1=index. Computes ptr+sizeof(*v.type)*index, where index is extended to ptrwidth type
-	{name: "OffPtr", argLength: 1, aux: "Int64"}, // arg0 + auxint (arg0 and result are pointers)
-
-	// Slices
-	{name: "SliceMake", argLength: 3},                // arg0=ptr, arg1=len, arg2=cap
-	{name: "SlicePtr", argLength: 1, typ: "BytePtr"}, // ptr(arg0)
-	{name: "SliceLen", argLength: 1},                 // len(arg0)
-	{name: "SliceCap", argLength: 1},                 // cap(arg0)
-	// SlicePtrUnchecked, like SlicePtr, extracts the pointer from a slice.
-	// SlicePtr values are assumed non-nil, because they are guarded by bounds checks.
-	// SlicePtrUnchecked values can be nil.
-	{name: "SlicePtrUnchecked", argLength: 1},
-
-	// Complex (part/whole)
-	{name: "ComplexMake", argLength: 2}, // arg0=real, arg1=imag
-	{name: "ComplexReal", argLength: 1}, // real(arg0)
-	{name: "ComplexImag", argLength: 1}, // imag(arg0)
-
-	// Strings
-	{name: "StringMake", argLength: 2},                // arg0=ptr, arg1=len
-	{name: "StringPtr", argLength: 1, typ: "BytePtr"}, // ptr(arg0)
-	{name: "StringLen", argLength: 1, typ: "Int"},     // len(arg0)
-
-	// Interfaces
-	{name: "IMake", argLength: 2},                // arg0=itab, arg1=data
-	{name: "ITab", argLength: 1, typ: "Uintptr"}, // arg0=interface, returns itable field
-	{name: "IData", argLength: 1},                // arg0=interface, returns data field
-
-	// Structs
-	{name: "StructMake0"},                              // Returns struct with 0 fields.
-	{name: "StructMake1", argLength: 1},                // arg0=field0.  Returns struct.
-	{name: "StructMake2", argLength: 2},                // arg0,arg1=field0,field1.  Returns struct.
-	{name: "StructMake3", argLength: 3},                // arg0..2=field0..2.  Returns struct.
-	{name: "StructMake4", argLength: 4},                // arg0..3=field0..3.  Returns struct.
-	{name: "StructSelect", argLength: 1, aux: "Int64"}, // arg0=struct, auxint=field index.  Returns the auxint'th field.
-
-	// Arrays
-	{name: "ArrayMake0"},                              // Returns array with 0 elements
-	{name: "ArrayMake1", argLength: 1},                // Returns array with 1 element
-	{name: "ArraySelect", argLength: 1, aux: "Int64"}, // arg0=array, auxint=index. Returns a[i].
-
-	// Spill&restore ops for the register allocator. These are
-	// semantically identical to OpCopy; they do not take/return
-	// stores like regular memory ops do. We can get away without memory
-	// args because we know there is no aliasing of spill slots on the stack.
-	{name: "StoreReg", argLength: 1},
-	{name: "LoadReg", argLength: 1},
-
-	// Used during ssa construction. Like Copy, but the arg has not been specified yet.
-	{name: "FwdRef", aux: "Sym", symEffect: "None"},
-
-	// Unknown value. Used for Values whose values don't matter because they are dead code.
-	{name: "Unknown"},
-
-	{name: "VarDef", argLength: 1, aux: "Sym", typ: "Mem", symEffect: "None", zeroWidth: true}, // aux is a *gc.Node of a variable that is about to be initialized.  arg0=mem, returns mem
-	{name: "VarKill", argLength: 1, aux: "Sym", symEffect: "None"},                             // aux is a *gc.Node of a variable that is known to be dead.  arg0=mem, returns mem
-	// TODO: what's the difference between VarLive and KeepAlive?
-	{name: "VarLive", argLength: 1, aux: "Sym", symEffect: "Read", zeroWidth: true}, // aux is a *gc.Node of a variable that must be kept live.  arg0=mem, returns mem
-	{name: "KeepAlive", argLength: 2, typ: "Mem", zeroWidth: true},                  // arg[0] is a value that must be kept alive until this mark.  arg[1]=mem, returns mem
-
-	// InlMark marks the start of an inlined function body. Its AuxInt field
-	// distinguishes which entry in the local inline tree it is marking.
-	{name: "InlMark", argLength: 1, aux: "Int32", typ: "Void"}, // arg[0]=mem, returns void.
-
-	// Ops for breaking 64-bit operations on 32-bit architectures
-	{name: "Int64Make", argLength: 2, typ: "UInt64"}, // arg0=hi, arg1=lo
-	{name: "Int64Hi", argLength: 1, typ: "UInt32"},   // high 32-bit of arg0
-	{name: "Int64Lo", argLength: 1, typ: "UInt32"},   // low 32-bit of arg0
-
-	{name: "Add32carry", argLength: 2, commutative: true, typ: "(UInt32,Flags)"}, // arg0 + arg1, returns (value, carry)
-	{name: "Add32withcarry", argLength: 3, commutative: true},                    // arg0 + arg1 + arg2, arg2=carry (0 or 1)
-
-	{name: "Sub32carry", argLength: 2, typ: "(UInt32,Flags)"}, // arg0 - arg1, returns (value, carry)
-	{name: "Sub32withcarry", argLength: 3},                    // arg0 - arg1 - arg2, arg2=carry (0 or 1)
-
-	{name: "Add64carry", argLength: 3, commutative: true, typ: "(UInt64,UInt64)"}, // arg0 + arg1 + arg2, arg2 must be 0 or 1. returns (value, value>>64)
-	{name: "Sub64borrow", argLength: 3, typ: "(UInt64,UInt64)"},                   // arg0 - (arg1 + arg2), arg2 must be 0 or 1. returns (value, value>>64&1)
-
-	{name: "Signmask", argLength: 1, typ: "Int32"},  // 0 if arg0 >= 0, -1 if arg0 < 0
-	{name: "Zeromask", argLength: 1, typ: "UInt32"}, // 0 if arg0 == 0, 0xffffffff if arg0 != 0
-	{name: "Slicemask", argLength: 1},               // 0 if arg0 == 0, -1 if arg0 > 0, undef if arg0<0. Type is native int size.
-
-	{name: "SpectreIndex", argLength: 2},      // arg0 if 0 <= arg0 < arg1, 0 otherwise. Type is native int size.
-	{name: "SpectreSliceIndex", argLength: 2}, // arg0 if 0 <= arg0 <= arg1, 0 otherwise. Type is native int size.
-
-	{name: "Cvt32Uto32F", argLength: 1}, // uint32 -> float32, only used on 32-bit arch
-	{name: "Cvt32Uto64F", argLength: 1}, // uint32 -> float64, only used on 32-bit arch
-	{name: "Cvt32Fto32U", argLength: 1}, // float32 -> uint32, only used on 32-bit arch
-	{name: "Cvt64Fto32U", argLength: 1}, // float64 -> uint32, only used on 32-bit arch
-	{name: "Cvt64Uto32F", argLength: 1}, // uint64 -> float32, only used on archs that has the instruction
-	{name: "Cvt64Uto64F", argLength: 1}, // uint64 -> float64, only used on archs that has the instruction
-	{name: "Cvt32Fto64U", argLength: 1}, // float32 -> uint64, only used on archs that has the instruction
-	{name: "Cvt64Fto64U", argLength: 1}, // float64 -> uint64, only used on archs that has the instruction
-
-	// pseudo-ops for breaking Tuple
-	{name: "Select0", argLength: 1, zeroWidth: true},  // the first component of a tuple
-	{name: "Select1", argLength: 1, zeroWidth: true},  // the second component of a tuple
-	{name: "SelectN", argLength: 1, aux: "Int64"},     // arg0=result, auxint=field index.  Returns the auxint'th member.
-	{name: "SelectNAddr", argLength: 1, aux: "Int64"}, // arg0=result, auxint=field index.  Returns the address of auxint'th member. Used for un-SSA-able result types.
-	{name: "MakeResult", argLength: -1},               // arg0 .. are components of a "Result" (like the result from a Call). The last arg should be memory (like the result from a call).
-
-	// Atomic operations used for semantically inlining sync/atomic and
-	// runtime/internal/atomic. Atomic loads return a new memory so that
-	// the loads are properly ordered with respect to other loads and
-	// stores.
-	{name: "AtomicLoad8", argLength: 2, typ: "(UInt8,Mem)"},                                    // Load from arg0.  arg1=memory.  Returns loaded value and new memory.
-	{name: "AtomicLoad32", argLength: 2, typ: "(UInt32,Mem)"},                                  // Load from arg0.  arg1=memory.  Returns loaded value and new memory.
-	{name: "AtomicLoad64", argLength: 2, typ: "(UInt64,Mem)"},                                  // Load from arg0.  arg1=memory.  Returns loaded value and new memory.
-	{name: "AtomicLoadPtr", argLength: 2, typ: "(BytePtr,Mem)"},                                // Load from arg0.  arg1=memory.  Returns loaded value and new memory.
-	{name: "AtomicLoadAcq32", argLength: 2, typ: "(UInt32,Mem)"},                               // Load from arg0.  arg1=memory.  Lock acquisition, returns loaded value and new memory.
-	{name: "AtomicLoadAcq64", argLength: 2, typ: "(UInt64,Mem)"},                               // Load from arg0.  arg1=memory.  Lock acquisition, returns loaded value and new memory.
-	{name: "AtomicStore8", argLength: 3, typ: "Mem", hasSideEffects: true},                     // Store arg1 to *arg0.  arg2=memory.  Returns memory.
-	{name: "AtomicStore32", argLength: 3, typ: "Mem", hasSideEffects: true},                    // Store arg1 to *arg0.  arg2=memory.  Returns memory.
-	{name: "AtomicStore64", argLength: 3, typ: "Mem", hasSideEffects: true},                    // Store arg1 to *arg0.  arg2=memory.  Returns memory.
-	{name: "AtomicStorePtrNoWB", argLength: 3, typ: "Mem", hasSideEffects: true},               // Store arg1 to *arg0.  arg2=memory.  Returns memory.
-	{name: "AtomicStoreRel32", argLength: 3, typ: "Mem", hasSideEffects: true},                 // Store arg1 to *arg0.  arg2=memory.  Lock release, returns memory.
-	{name: "AtomicStoreRel64", argLength: 3, typ: "Mem", hasSideEffects: true},                 // Store arg1 to *arg0.  arg2=memory.  Lock release, returns memory.
-	{name: "AtomicExchange32", argLength: 3, typ: "(UInt32,Mem)", hasSideEffects: true},        // Store arg1 to *arg0.  arg2=memory.  Returns old contents of *arg0 and new memory.
-	{name: "AtomicExchange64", argLength: 3, typ: "(UInt64,Mem)", hasSideEffects: true},        // Store arg1 to *arg0.  arg2=memory.  Returns old contents of *arg0 and new memory.
-	{name: "AtomicAdd32", argLength: 3, typ: "(UInt32,Mem)", hasSideEffects: true},             // Do *arg0 += arg1.  arg2=memory.  Returns sum and new memory.
-	{name: "AtomicAdd64", argLength: 3, typ: "(UInt64,Mem)", hasSideEffects: true},             // Do *arg0 += arg1.  arg2=memory.  Returns sum and new memory.
-	{name: "AtomicCompareAndSwap32", argLength: 4, typ: "(Bool,Mem)", hasSideEffects: true},    // if *arg0==arg1, then set *arg0=arg2.  Returns true if store happens and new memory.
-	{name: "AtomicCompareAndSwap64", argLength: 4, typ: "(Bool,Mem)", hasSideEffects: true},    // if *arg0==arg1, then set *arg0=arg2.  Returns true if store happens and new memory.
-	{name: "AtomicCompareAndSwapRel32", argLength: 4, typ: "(Bool,Mem)", hasSideEffects: true}, // if *arg0==arg1, then set *arg0=arg2.  Lock release, reports whether store happens and new memory.
-	{name: "AtomicAnd8", argLength: 3, typ: "Mem", hasSideEffects: true},                       // *arg0 &= arg1.  arg2=memory.  Returns memory.
-	{name: "AtomicAnd32", argLength: 3, typ: "Mem", hasSideEffects: true},                      // *arg0 &= arg1.  arg2=memory.  Returns memory.
-	{name: "AtomicOr8", argLength: 3, typ: "Mem", hasSideEffects: true},                        // *arg0 |= arg1.  arg2=memory.  Returns memory.
-	{name: "AtomicOr32", argLength: 3, typ: "Mem", hasSideEffects: true},                       // *arg0 |= arg1.  arg2=memory.  Returns memory.
-
-	// Atomic operation variants
-	// These variants have the same semantics as above atomic operations.
-	// But they are used for generating more efficient code on certain modern machines, with run-time CPU feature detection.
-	// Currently, they are used on ARM64 only.
-	{name: "AtomicAdd32Variant", argLength: 3, typ: "(UInt32,Mem)", hasSideEffects: true},          // Do *arg0 += arg1.  arg2=memory.  Returns sum and new memory.
-	{name: "AtomicAdd64Variant", argLength: 3, typ: "(UInt64,Mem)", hasSideEffects: true},          // Do *arg0 += arg1.  arg2=memory.  Returns sum and new memory.
-	{name: "AtomicExchange32Variant", argLength: 3, typ: "(UInt32,Mem)", hasSideEffects: true},     // Store arg1 to *arg0.  arg2=memory.  Returns old contents of *arg0 and new memory.
-	{name: "AtomicExchange64Variant", argLength: 3, typ: "(UInt64,Mem)", hasSideEffects: true},     // Store arg1 to *arg0.  arg2=memory.  Returns old contents of *arg0 and new memory.
-	{name: "AtomicCompareAndSwap32Variant", argLength: 4, typ: "(Bool,Mem)", hasSideEffects: true}, // if *arg0==arg1, then set *arg0=arg2.  Returns true if store happens and new memory.
-	{name: "AtomicCompareAndSwap64Variant", argLength: 4, typ: "(Bool,Mem)", hasSideEffects: true}, // if *arg0==arg1, then set *arg0=arg2.  Returns true if store happens and new memory.
-	{name: "AtomicAnd8Variant", argLength: 3, typ: "Mem", hasSideEffects: true},                    // *arg0 &= arg1.  arg2=memory.  Returns memory.
-	{name: "AtomicAnd32Variant", argLength: 3, typ: "Mem", hasSideEffects: true},                   // *arg0 &= arg1.  arg2=memory.  Returns memory.
-	{name: "AtomicOr8Variant", argLength: 3, typ: "Mem", hasSideEffects: true},                     // *arg0 |= arg1.  arg2=memory.  Returns memory.
-	{name: "AtomicOr32Variant", argLength: 3, typ: "Mem", hasSideEffects: true},                    // *arg0 |= arg1.  arg2=memory.  Returns memory.
-
-	// Publication barrier
-	{name: "PubBarrier", argLength: 1, hasSideEffects: true}, // Do data barrier. arg0=memory.
-
-	// Clobber experiment op
-	{name: "Clobber", argLength: 0, typ: "Void", aux: "SymOff", symEffect: "None"}, // write an invalid pointer value to the given pointer slot of a stack variable
-	{name: "ClobberReg", argLength: 0, typ: "Void"},                                // clobber a register
-
-	// Prefetch instruction
-	{name: "PrefetchCache", argLength: 2, hasSideEffects: true},         // Do prefetch arg0 to cache. arg0=addr, arg1=memory.
-	{name: "PrefetchCacheStreamed", argLength: 2, hasSideEffects: true}, // Do non-temporal or streamed prefetch arg0 to cache. arg0=addr, arg1=memory.
-}
-
-//     kind          controls        successors   implicit exit
-//   ----------------------------------------------------------
-//     Exit      [return mem]                []             yes
-//      Ret      [return mem]                []             yes
-//   RetJmp      [return mem]                []             yes
-//    Plain                []            [next]
-//       If   [boolean Value]      [then, else]
-//    First                []   [always, never]
-
-var genericBlocks = []blockData{
-	{name: "Plain"},                  // a single successor
-	{name: "If", controls: 1},        // if Controls[0] goto Succs[0] else goto Succs[1]
-	{name: "Defer", controls: 1},     // Succs[0]=defer queued, Succs[1]=defer recovered. Controls[0] is call op (of memory type)
-	{name: "Ret", controls: 1},       // no successors, Controls[0] value is memory result
-	{name: "RetJmp", controls: 1},    // no successors, Controls[0] value is a tail call
-	{name: "Exit", controls: 1},      // no successors, Controls[0] value generates a panic
-	{name: "JumpTable", controls: 1}, // multiple successors, the integer Controls[0] selects which one
-
-	// transient block state used for dead code removal
-	{name: "First"}, // 2 successors, always takes the first one (second is dead)
-}
-
-func init() {
-	archs = append(archs, arch{
-		name:    "generic",
-		ops:     genericOps,
-		blocks:  genericBlocks,
-		generic: true,
-	})
-}
diff --git a/src/cmd/compile/internal/ssa/gen/main.go b/src/cmd/compile/internal/ssa/gen/main.go
deleted file mode 100644
index 2cf0a91..0000000
--- a/src/cmd/compile/internal/ssa/gen/main.go
+++ /dev/null
@@ -1,573 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build ignore
-// +build ignore
-
-// The gen command generates Go code (in the parent directory) for all
-// the architecture-specific opcodes, blocks, and rewrites.
-package main
-
-import (
-	"bytes"
-	"flag"
-	"fmt"
-	"go/format"
-	"io/ioutil"
-	"log"
-	"os"
-	"path"
-	"regexp"
-	"runtime"
-	"runtime/pprof"
-	"runtime/trace"
-	"sort"
-	"strings"
-	"sync"
-)
-
-// TODO: capitalize these types, so that we can more easily tell variable names
-// apart from type names, and avoid awkward func parameters like "arch arch".
-
-type arch struct {
-	name               string
-	pkg                string // obj package to import for this arch.
-	genfile            string // source file containing opcode code generation.
-	ops                []opData
-	blocks             []blockData
-	regnames           []string
-	ParamIntRegNames   string
-	ParamFloatRegNames string
-	gpregmask          regMask
-	fpregmask          regMask
-	fp32regmask        regMask
-	fp64regmask        regMask
-	specialregmask     regMask
-	framepointerreg    int8
-	linkreg            int8
-	generic            bool
-	imports            []string
-}
-
-type opData struct {
-	name              string
-	reg               regInfo
-	asm               string
-	typ               string // default result type
-	aux               string
-	rematerializeable bool
-	argLength         int32  // number of arguments, if -1, then this operation has a variable number of arguments
-	commutative       bool   // this operation is commutative on its first 2 arguments (e.g. addition)
-	resultInArg0      bool   // (first, if a tuple) output of v and v.Args[0] must be allocated to the same register
-	resultNotInArgs   bool   // outputs must not be allocated to the same registers as inputs
-	clobberFlags      bool   // this op clobbers flags register
-	call              bool   // is a function call
-	tailCall          bool   // is a tail call
-	nilCheck          bool   // this op is a nil check on arg0
-	faultOnNilArg0    bool   // this op will fault if arg0 is nil (and aux encodes a small offset)
-	faultOnNilArg1    bool   // this op will fault if arg1 is nil (and aux encodes a small offset)
-	hasSideEffects    bool   // for "reasons", not to be eliminated.  E.g., atomic store, #19182.
-	zeroWidth         bool   // op never translates into any machine code. example: copy, which may sometimes translate to machine code, is not zero-width.
-	unsafePoint       bool   // this op is an unsafe point, i.e. not safe for async preemption
-	symEffect         string // effect this op has on symbol in aux
-	scale             uint8  // amd64/386 indexed load scale
-}
-
-type blockData struct {
-	name     string // the suffix for this block ("EQ", "LT", etc.)
-	controls int    // the number of control values this type of block requires
-	aux      string // the type of the Aux/AuxInt value, if any
-}
-
-type regInfo struct {
-	// inputs[i] encodes the set of registers allowed for the i'th input.
-	// Inputs that don't use registers (flags, memory, etc.) should be 0.
-	inputs []regMask
-	// clobbers encodes the set of registers that are overwritten by
-	// the instruction (other than the output registers).
-	clobbers regMask
-	// outputs[i] encodes the set of registers allowed for the i'th output.
-	outputs []regMask
-}
-
-type regMask uint64
-
-func (a arch) regMaskComment(r regMask) string {
-	var buf bytes.Buffer
-	for i := uint64(0); r != 0; i++ {
-		if r&1 != 0 {
-			if buf.Len() == 0 {
-				buf.WriteString(" //")
-			}
-			buf.WriteString(" ")
-			buf.WriteString(a.regnames[i])
-		}
-		r >>= 1
-	}
-	return buf.String()
-}
-
-var archs []arch
-
-var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to `file`")
-var memprofile = flag.String("memprofile", "", "write memory profile to `file`")
-var tracefile = flag.String("trace", "", "write trace to `file`")
-
-func main() {
-	flag.Parse()
-	if *cpuprofile != "" {
-		f, err := os.Create(*cpuprofile)
-		if err != nil {
-			log.Fatal("could not create CPU profile: ", err)
-		}
-		defer f.Close()
-		if err := pprof.StartCPUProfile(f); err != nil {
-			log.Fatal("could not start CPU profile: ", err)
-		}
-		defer pprof.StopCPUProfile()
-	}
-	if *tracefile != "" {
-		f, err := os.Create(*tracefile)
-		if err != nil {
-			log.Fatalf("failed to create trace output file: %v", err)
-		}
-		defer func() {
-			if err := f.Close(); err != nil {
-				log.Fatalf("failed to close trace file: %v", err)
-			}
-		}()
-
-		if err := trace.Start(f); err != nil {
-			log.Fatalf("failed to start trace: %v", err)
-		}
-		defer trace.Stop()
-	}
-
-	sort.Sort(ArchsByName(archs))
-
-	// The generate tasks are run concurrently, since they are CPU-intensive
-	// that can easily make use of many cores on a machine.
-	//
-	// Note that there is no limit on the concurrency at the moment. On a
-	// four-core laptop at the time of writing, peak RSS usually reaches
-	// ~200MiB, which seems doable by practically any machine nowadays. If
-	// that stops being the case, we can cap this func to a fixed number of
-	// architectures being generated at once.
-
-	tasks := []func(){
-		genOp,
-	}
-	for _, a := range archs {
-		a := a // the funcs are ran concurrently at a later time
-		tasks = append(tasks, func() {
-			genRules(a)
-			genSplitLoadRules(a)
-		})
-	}
-	var wg sync.WaitGroup
-	for _, task := range tasks {
-		task := task
-		wg.Add(1)
-		go func() {
-			task()
-			wg.Done()
-		}()
-	}
-	wg.Wait()
-
-	if *memprofile != "" {
-		f, err := os.Create(*memprofile)
-		if err != nil {
-			log.Fatal("could not create memory profile: ", err)
-		}
-		defer f.Close()
-		runtime.GC() // get up-to-date statistics
-		if err := pprof.WriteHeapProfile(f); err != nil {
-			log.Fatal("could not write memory profile: ", err)
-		}
-	}
-}
-
-func genOp() {
-	w := new(bytes.Buffer)
-	fmt.Fprintf(w, "// Code generated from gen/*Ops.go; DO NOT EDIT.\n")
-	fmt.Fprintln(w)
-	fmt.Fprintln(w, "package ssa")
-
-	fmt.Fprintln(w, "import (")
-	fmt.Fprintln(w, "\"cmd/internal/obj\"")
-	for _, a := range archs {
-		if a.pkg != "" {
-			fmt.Fprintf(w, "%q\n", a.pkg)
-		}
-	}
-	fmt.Fprintln(w, ")")
-
-	// generate Block* declarations
-	fmt.Fprintln(w, "const (")
-	fmt.Fprintln(w, "BlockInvalid BlockKind = iota")
-	for _, a := range archs {
-		fmt.Fprintln(w)
-		for _, d := range a.blocks {
-			fmt.Fprintf(w, "Block%s%s\n", a.Name(), d.name)
-		}
-	}
-	fmt.Fprintln(w, ")")
-
-	// generate block kind string method
-	fmt.Fprintln(w, "var blockString = [...]string{")
-	fmt.Fprintln(w, "BlockInvalid:\"BlockInvalid\",")
-	for _, a := range archs {
-		fmt.Fprintln(w)
-		for _, b := range a.blocks {
-			fmt.Fprintf(w, "Block%s%s:\"%s\",\n", a.Name(), b.name, b.name)
-		}
-	}
-	fmt.Fprintln(w, "}")
-	fmt.Fprintln(w, "func (k BlockKind) String() string {return blockString[k]}")
-
-	// generate block kind auxint method
-	fmt.Fprintln(w, "func (k BlockKind) AuxIntType() string {")
-	fmt.Fprintln(w, "switch k {")
-	for _, a := range archs {
-		for _, b := range a.blocks {
-			if b.auxIntType() == "invalid" {
-				continue
-			}
-			fmt.Fprintf(w, "case Block%s%s: return \"%s\"\n", a.Name(), b.name, b.auxIntType())
-		}
-	}
-	fmt.Fprintln(w, "}")
-	fmt.Fprintln(w, "return \"\"")
-	fmt.Fprintln(w, "}")
-
-	// generate Op* declarations
-	fmt.Fprintln(w, "const (")
-	fmt.Fprintln(w, "OpInvalid Op = iota") // make sure OpInvalid is 0.
-	for _, a := range archs {
-		fmt.Fprintln(w)
-		for _, v := range a.ops {
-			if v.name == "Invalid" {
-				continue
-			}
-			fmt.Fprintf(w, "Op%s%s\n", a.Name(), v.name)
-		}
-	}
-	fmt.Fprintln(w, ")")
-
-	// generate OpInfo table
-	fmt.Fprintln(w, "var opcodeTable = [...]opInfo{")
-	fmt.Fprintln(w, " { name: \"OpInvalid\" },")
-	for _, a := range archs {
-		fmt.Fprintln(w)
-
-		pkg := path.Base(a.pkg)
-		for _, v := range a.ops {
-			if v.name == "Invalid" {
-				continue
-			}
-			fmt.Fprintln(w, "{")
-			fmt.Fprintf(w, "name:\"%s\",\n", v.name)
-
-			// flags
-			if v.aux != "" {
-				fmt.Fprintf(w, "auxType: aux%s,\n", v.aux)
-			}
-			fmt.Fprintf(w, "argLen: %d,\n", v.argLength)
-
-			if v.rematerializeable {
-				if v.reg.clobbers != 0 {
-					log.Fatalf("%s is rematerializeable and clobbers registers", v.name)
-				}
-				if v.clobberFlags {
-					log.Fatalf("%s is rematerializeable and clobbers flags", v.name)
-				}
-				fmt.Fprintln(w, "rematerializeable: true,")
-			}
-			if v.commutative {
-				fmt.Fprintln(w, "commutative: true,")
-			}
-			if v.resultInArg0 {
-				fmt.Fprintln(w, "resultInArg0: true,")
-				// OpConvert's register mask is selected dynamically,
-				// so don't try to check it in the static table.
-				if v.name != "Convert" && v.reg.inputs[0] != v.reg.outputs[0] {
-					log.Fatalf("%s: input[0] and output[0] must use the same registers for %s", a.name, v.name)
-				}
-				if v.name != "Convert" && v.commutative && v.reg.inputs[1] != v.reg.outputs[0] {
-					log.Fatalf("%s: input[1] and output[0] must use the same registers for %s", a.name, v.name)
-				}
-			}
-			if v.resultNotInArgs {
-				fmt.Fprintln(w, "resultNotInArgs: true,")
-			}
-			if v.clobberFlags {
-				fmt.Fprintln(w, "clobberFlags: true,")
-			}
-			if v.call {
-				fmt.Fprintln(w, "call: true,")
-			}
-			if v.tailCall {
-				fmt.Fprintln(w, "tailCall: true,")
-			}
-			if v.nilCheck {
-				fmt.Fprintln(w, "nilCheck: true,")
-			}
-			if v.faultOnNilArg0 {
-				fmt.Fprintln(w, "faultOnNilArg0: true,")
-				if v.aux != "Sym" && v.aux != "SymOff" && v.aux != "SymValAndOff" && v.aux != "Int64" && v.aux != "Int32" && v.aux != "" {
-					log.Fatalf("faultOnNilArg0 with aux %s not allowed", v.aux)
-				}
-			}
-			if v.faultOnNilArg1 {
-				fmt.Fprintln(w, "faultOnNilArg1: true,")
-				if v.aux != "Sym" && v.aux != "SymOff" && v.aux != "SymValAndOff" && v.aux != "Int64" && v.aux != "Int32" && v.aux != "" {
-					log.Fatalf("faultOnNilArg1 with aux %s not allowed", v.aux)
-				}
-			}
-			if v.hasSideEffects {
-				fmt.Fprintln(w, "hasSideEffects: true,")
-			}
-			if v.zeroWidth {
-				fmt.Fprintln(w, "zeroWidth: true,")
-			}
-			if v.unsafePoint {
-				fmt.Fprintln(w, "unsafePoint: true,")
-			}
-			needEffect := strings.HasPrefix(v.aux, "Sym")
-			if v.symEffect != "" {
-				if !needEffect {
-					log.Fatalf("symEffect with aux %s not allowed", v.aux)
-				}
-				fmt.Fprintf(w, "symEffect: Sym%s,\n", strings.Replace(v.symEffect, ",", "|Sym", -1))
-			} else if needEffect {
-				log.Fatalf("symEffect needed for aux %s", v.aux)
-			}
-			if a.name == "generic" {
-				fmt.Fprintln(w, "generic:true,")
-				fmt.Fprintln(w, "},") // close op
-				// generic ops have no reg info or asm
-				continue
-			}
-			if v.asm != "" {
-				fmt.Fprintf(w, "asm: %s.A%s,\n", pkg, v.asm)
-			}
-			if v.scale != 0 {
-				fmt.Fprintf(w, "scale: %d,\n", v.scale)
-			}
-			fmt.Fprintln(w, "reg:regInfo{")
-
-			// Compute input allocation order. We allocate from the
-			// most to the least constrained input. This order guarantees
-			// that we will always be able to find a register.
-			var s []intPair
-			for i, r := range v.reg.inputs {
-				if r != 0 {
-					s = append(s, intPair{countRegs(r), i})
-				}
-			}
-			if len(s) > 0 {
-				sort.Sort(byKey(s))
-				fmt.Fprintln(w, "inputs: []inputInfo{")
-				for _, p := range s {
-					r := v.reg.inputs[p.val]
-					fmt.Fprintf(w, "{%d,%d},%s\n", p.val, r, a.regMaskComment(r))
-				}
-				fmt.Fprintln(w, "},")
-			}
-
-			if v.reg.clobbers > 0 {
-				fmt.Fprintf(w, "clobbers: %d,%s\n", v.reg.clobbers, a.regMaskComment(v.reg.clobbers))
-			}
-
-			// reg outputs
-			s = s[:0]
-			for i, r := range v.reg.outputs {
-				s = append(s, intPair{countRegs(r), i})
-			}
-			if len(s) > 0 {
-				sort.Sort(byKey(s))
-				fmt.Fprintln(w, "outputs: []outputInfo{")
-				for _, p := range s {
-					r := v.reg.outputs[p.val]
-					fmt.Fprintf(w, "{%d,%d},%s\n", p.val, r, a.regMaskComment(r))
-				}
-				fmt.Fprintln(w, "},")
-			}
-			fmt.Fprintln(w, "},") // close reg info
-			fmt.Fprintln(w, "},") // close op
-		}
-	}
-	fmt.Fprintln(w, "}")
-
-	fmt.Fprintln(w, "func (o Op) Asm() obj.As {return opcodeTable[o].asm}")
-	fmt.Fprintln(w, "func (o Op) Scale() int16 {return int16(opcodeTable[o].scale)}")
-
-	// generate op string method
-	fmt.Fprintln(w, "func (o Op) String() string {return opcodeTable[o].name }")
-
-	fmt.Fprintln(w, "func (o Op) SymEffect() SymEffect { return opcodeTable[o].symEffect }")
-	fmt.Fprintln(w, "func (o Op) IsCall() bool { return opcodeTable[o].call }")
-	fmt.Fprintln(w, "func (o Op) IsTailCall() bool { return opcodeTable[o].tailCall }")
-	fmt.Fprintln(w, "func (o Op) HasSideEffects() bool { return opcodeTable[o].hasSideEffects }")
-	fmt.Fprintln(w, "func (o Op) UnsafePoint() bool { return opcodeTable[o].unsafePoint }")
-	fmt.Fprintln(w, "func (o Op) ResultInArg0() bool { return opcodeTable[o].resultInArg0 }")
-
-	// generate registers
-	for _, a := range archs {
-		if a.generic {
-			continue
-		}
-		fmt.Fprintf(w, "var registers%s = [...]Register {\n", a.name)
-		var gcRegN int
-		num := map[string]int8{}
-		for i, r := range a.regnames {
-			num[r] = int8(i)
-			pkg := a.pkg[len("cmd/internal/obj/"):]
-			var objname string // name in cmd/internal/obj/$ARCH
-			switch r {
-			case "SB":
-				// SB isn't a real register.  cmd/internal/obj expects 0 in this case.
-				objname = "0"
-			case "SP":
-				objname = pkg + ".REGSP"
-			case "g":
-				objname = pkg + ".REGG"
-			default:
-				objname = pkg + ".REG_" + r
-			}
-			// Assign a GC register map index to registers
-			// that may contain pointers.
-			gcRegIdx := -1
-			if a.gpregmask&(1<<uint(i)) != 0 {
-				gcRegIdx = gcRegN
-				gcRegN++
-			}
-			fmt.Fprintf(w, "  {%d, %s, %d, \"%s\"},\n", i, objname, gcRegIdx, r)
-		}
-		parameterRegisterList := func(paramNamesString string) []int8 {
-			paramNamesString = strings.TrimSpace(paramNamesString)
-			if paramNamesString == "" {
-				return nil
-			}
-			paramNames := strings.Split(paramNamesString, " ")
-			var paramRegs []int8
-			for _, regName := range paramNames {
-				if regName == "" {
-					// forgive extra spaces
-					continue
-				}
-				if regNum, ok := num[regName]; ok {
-					paramRegs = append(paramRegs, regNum)
-					delete(num, regName)
-				} else {
-					log.Fatalf("parameter register %s for architecture %s not a register name (or repeated in parameter list)", regName, a.name)
-				}
-			}
-			return paramRegs
-		}
-
-		paramIntRegs := parameterRegisterList(a.ParamIntRegNames)
-		paramFloatRegs := parameterRegisterList(a.ParamFloatRegNames)
-
-		if gcRegN > 32 {
-			// Won't fit in a uint32 mask.
-			log.Fatalf("too many GC registers (%d > 32) on %s", gcRegN, a.name)
-		}
-		fmt.Fprintln(w, "}")
-		fmt.Fprintf(w, "var paramIntReg%s = %#v\n", a.name, paramIntRegs)
-		fmt.Fprintf(w, "var paramFloatReg%s = %#v\n", a.name, paramFloatRegs)
-		fmt.Fprintf(w, "var gpRegMask%s = regMask(%d)\n", a.name, a.gpregmask)
-		fmt.Fprintf(w, "var fpRegMask%s = regMask(%d)\n", a.name, a.fpregmask)
-		if a.fp32regmask != 0 {
-			fmt.Fprintf(w, "var fp32RegMask%s = regMask(%d)\n", a.name, a.fp32regmask)
-		}
-		if a.fp64regmask != 0 {
-			fmt.Fprintf(w, "var fp64RegMask%s = regMask(%d)\n", a.name, a.fp64regmask)
-		}
-		fmt.Fprintf(w, "var specialRegMask%s = regMask(%d)\n", a.name, a.specialregmask)
-		fmt.Fprintf(w, "var framepointerReg%s = int8(%d)\n", a.name, a.framepointerreg)
-		fmt.Fprintf(w, "var linkReg%s = int8(%d)\n", a.name, a.linkreg)
-	}
-
-	// gofmt result
-	b := w.Bytes()
-	var err error
-	b, err = format.Source(b)
-	if err != nil {
-		fmt.Printf("%s\n", w.Bytes())
-		panic(err)
-	}
-
-	if err := ioutil.WriteFile("../opGen.go", b, 0666); err != nil {
-		log.Fatalf("can't write output: %v\n", err)
-	}
-
-	// Check that the arch genfile handles all the arch-specific opcodes.
-	// This is very much a hack, but it is better than nothing.
-	//
-	// Do a single regexp pass to record all ops being handled in a map, and
-	// then compare that with the ops list. This is much faster than one
-	// regexp pass per opcode.
-	for _, a := range archs {
-		if a.genfile == "" {
-			continue
-		}
-
-		pattern := fmt.Sprintf(`\Wssa\.Op%s([a-zA-Z0-9_]+)\W`, a.name)
-		rxOp, err := regexp.Compile(pattern)
-		if err != nil {
-			log.Fatalf("bad opcode regexp %s: %v", pattern, err)
-		}
-
-		src, err := ioutil.ReadFile(a.genfile)
-		if err != nil {
-			log.Fatalf("can't read %s: %v", a.genfile, err)
-		}
-		seen := make(map[string]bool, len(a.ops))
-		for _, m := range rxOp.FindAllSubmatch(src, -1) {
-			seen[string(m[1])] = true
-		}
-		for _, op := range a.ops {
-			if !seen[op.name] {
-				log.Fatalf("Op%s%s has no code generation in %s", a.name, op.name, a.genfile)
-			}
-		}
-	}
-}
-
-// Name returns the name of the architecture for use in Op* and Block* enumerations.
-func (a arch) Name() string {
-	s := a.name
-	if s == "generic" {
-		s = ""
-	}
-	return s
-}
-
-// countRegs returns the number of set bits in the register mask.
-func countRegs(r regMask) int {
-	n := 0
-	for r != 0 {
-		n += int(r & 1)
-		r >>= 1
-	}
-	return n
-}
-
-// for sorting a pair of integers by key
-type intPair struct {
-	key, val int
-}
-type byKey []intPair
-
-func (a byKey) Len() int           { return len(a) }
-func (a byKey) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
-func (a byKey) Less(i, j int) bool { return a[i].key < a[j].key }
-
-type ArchsByName []arch
-
-func (x ArchsByName) Len() int           { return len(x) }
-func (x ArchsByName) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
-func (x ArchsByName) Less(i, j int) bool { return x[i].name < x[j].name }
diff --git a/src/cmd/compile/internal/ssa/gen/rulegen.go b/src/cmd/compile/internal/ssa/gen/rulegen.go
deleted file mode 100644
index 0f7e970..0000000
--- a/src/cmd/compile/internal/ssa/gen/rulegen.go
+++ /dev/null
@@ -1,1888 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build gen
-// +build gen
-
-// This program generates Go code that applies rewrite rules to a Value.
-// The generated code implements a function of type func (v *Value) bool
-// which reports whether if did something.
-// Ideas stolen from Swift: http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-2000-2.html
-
-package main
-
-import (
-	"bufio"
-	"bytes"
-	"flag"
-	"fmt"
-	"go/ast"
-	"go/format"
-	"go/parser"
-	"go/printer"
-	"go/token"
-	"io"
-	"io/ioutil"
-	"log"
-	"os"
-	"path"
-	"regexp"
-	"sort"
-	"strconv"
-	"strings"
-
-	"golang.org/x/tools/go/ast/astutil"
-)
-
-// rule syntax:
-//  sexpr [&& extra conditions] => [@block] sexpr
-//
-// sexpr are s-expressions (lisp-like parenthesized groupings)
-// sexpr ::= [variable:](opcode sexpr*)
-//         | variable
-//         | <type>
-//         | [auxint]
-//         | {aux}
-//
-// aux      ::= variable | {code}
-// type     ::= variable | {code}
-// variable ::= some token
-// opcode   ::= one of the opcodes from the *Ops.go files
-
-// special rules: trailing ellipsis "..." (in the outermost sexpr?) must match on both sides of a rule.
-//                trailing three underscore "___" in the outermost match sexpr indicate the presence of
-//                   extra ignored args that need not appear in the replacement
-
-// extra conditions is just a chunk of Go that evaluates to a boolean. It may use
-// variables declared in the matching tsexpr. The variable "v" is predefined to be
-// the value matched by the entire rule.
-
-// If multiple rules match, the first one in file order is selected.
-
-var (
-	genLog  = flag.Bool("log", false, "generate code that logs; for debugging only")
-	addLine = flag.Bool("line", false, "add line number comment to generated rules; for debugging only")
-)
-
-type Rule struct {
-	Rule string
-	Loc  string // file name & line number
-}
-
-func (r Rule) String() string {
-	return fmt.Sprintf("rule %q at %s", r.Rule, r.Loc)
-}
-
-func normalizeSpaces(s string) string {
-	return strings.Join(strings.Fields(strings.TrimSpace(s)), " ")
-}
-
-// parse returns the matching part of the rule, additional conditions, and the result.
-func (r Rule) parse() (match, cond, result string) {
-	s := strings.Split(r.Rule, "=>")
-	match = normalizeSpaces(s[0])
-	result = normalizeSpaces(s[1])
-	cond = ""
-	if i := strings.Index(match, "&&"); i >= 0 {
-		cond = normalizeSpaces(match[i+2:])
-		match = normalizeSpaces(match[:i])
-	}
-	return match, cond, result
-}
-
-func genRules(arch arch)          { genRulesSuffix(arch, "") }
-func genSplitLoadRules(arch arch) { genRulesSuffix(arch, "splitload") }
-
-func genRulesSuffix(arch arch, suff string) {
-	// Open input file.
-	text, err := os.Open(arch.name + suff + ".rules")
-	if err != nil {
-		if suff == "" {
-			// All architectures must have a plain rules file.
-			log.Fatalf("can't read rule file: %v", err)
-		}
-		// Some architectures have bonus rules files that others don't share. That's fine.
-		return
-	}
-
-	// oprules contains a list of rules for each block and opcode
-	blockrules := map[string][]Rule{}
-	oprules := map[string][]Rule{}
-
-	// read rule file
-	scanner := bufio.NewScanner(text)
-	rule := ""
-	var lineno int
-	var ruleLineno int // line number of "=>"
-	for scanner.Scan() {
-		lineno++
-		line := scanner.Text()
-		if i := strings.Index(line, "//"); i >= 0 {
-			// Remove comments. Note that this isn't string safe, so
-			// it will truncate lines with // inside strings. Oh well.
-			line = line[:i]
-		}
-		rule += " " + line
-		rule = strings.TrimSpace(rule)
-		if rule == "" {
-			continue
-		}
-		if !strings.Contains(rule, "=>") {
-			continue
-		}
-		if ruleLineno == 0 {
-			ruleLineno = lineno
-		}
-		if strings.HasSuffix(rule, "=>") {
-			continue // continue on the next line
-		}
-		if n := balance(rule); n > 0 {
-			continue // open parentheses remain, continue on the next line
-		} else if n < 0 {
-			break // continuing the line can't help, and it will only make errors worse
-		}
-
-		loc := fmt.Sprintf("%s%s.rules:%d", arch.name, suff, ruleLineno)
-		for _, rule2 := range expandOr(rule) {
-			r := Rule{Rule: rule2, Loc: loc}
-			if rawop := strings.Split(rule2, " ")[0][1:]; isBlock(rawop, arch) {
-				blockrules[rawop] = append(blockrules[rawop], r)
-				continue
-			}
-			// Do fancier value op matching.
-			match, _, _ := r.parse()
-			op, oparch, _, _, _, _ := parseValue(match, arch, loc)
-			opname := fmt.Sprintf("Op%s%s", oparch, op.name)
-			oprules[opname] = append(oprules[opname], r)
-		}
-		rule = ""
-		ruleLineno = 0
-	}
-	if err := scanner.Err(); err != nil {
-		log.Fatalf("scanner failed: %v\n", err)
-	}
-	if balance(rule) != 0 {
-		log.Fatalf("%s.rules:%d: unbalanced rule: %v\n", arch.name, lineno, rule)
-	}
-
-	// Order all the ops.
-	var ops []string
-	for op := range oprules {
-		ops = append(ops, op)
-	}
-	sort.Strings(ops)
-
-	genFile := &File{Arch: arch, Suffix: suff}
-	// Main rewrite routine is a switch on v.Op.
-	fn := &Func{Kind: "Value", ArgLen: -1}
-
-	sw := &Switch{Expr: exprf("v.Op")}
-	for _, op := range ops {
-		eop, ok := parseEllipsisRules(oprules[op], arch)
-		if ok {
-			if strings.Contains(oprules[op][0].Rule, "=>") && opByName(arch, op).aux != opByName(arch, eop).aux {
-				panic(fmt.Sprintf("can't use ... for ops that have different aux types: %s and %s", op, eop))
-			}
-			swc := &Case{Expr: exprf("%s", op)}
-			swc.add(stmtf("v.Op = %s", eop))
-			swc.add(stmtf("return true"))
-			sw.add(swc)
-			continue
-		}
-
-		swc := &Case{Expr: exprf("%s", op)}
-		swc.add(stmtf("return rewriteValue%s%s_%s(v)", arch.name, suff, op))
-		sw.add(swc)
-	}
-	if len(sw.List) > 0 { // skip if empty
-		fn.add(sw)
-	}
-	fn.add(stmtf("return false"))
-	genFile.add(fn)
-
-	// Generate a routine per op. Note that we don't make one giant routine
-	// because it is too big for some compilers.
-	for _, op := range ops {
-		rules := oprules[op]
-		_, ok := parseEllipsisRules(oprules[op], arch)
-		if ok {
-			continue
-		}
-
-		// rr is kept between iterations, so that each rule can check
-		// that the previous rule wasn't unconditional.
-		var rr *RuleRewrite
-		fn := &Func{
-			Kind:   "Value",
-			Suffix: fmt.Sprintf("_%s", op),
-			ArgLen: opByName(arch, op).argLength,
-		}
-		fn.add(declReserved("b", "v.Block"))
-		fn.add(declReserved("config", "b.Func.Config"))
-		fn.add(declReserved("fe", "b.Func.fe"))
-		fn.add(declReserved("typ", "&b.Func.Config.Types"))
-		for _, rule := range rules {
-			if rr != nil && !rr.CanFail {
-				log.Fatalf("unconditional rule %s is followed by other rules", rr.Match)
-			}
-			rr = &RuleRewrite{Loc: rule.Loc}
-			rr.Match, rr.Cond, rr.Result = rule.parse()
-			pos, _ := genMatch(rr, arch, rr.Match, fn.ArgLen >= 0)
-			if pos == "" {
-				pos = "v.Pos"
-			}
-			if rr.Cond != "" {
-				rr.add(breakf("!(%s)", rr.Cond))
-			}
-			genResult(rr, arch, rr.Result, pos)
-			if *genLog {
-				rr.add(stmtf("logRule(%q)", rule.Loc))
-			}
-			fn.add(rr)
-		}
-		if rr.CanFail {
-			fn.add(stmtf("return false"))
-		}
-		genFile.add(fn)
-	}
-
-	// Generate block rewrite function. There are only a few block types
-	// so we can make this one function with a switch.
-	fn = &Func{Kind: "Block"}
-	fn.add(declReserved("config", "b.Func.Config"))
-	fn.add(declReserved("typ", "&b.Func.Config.Types"))
-
-	sw = &Switch{Expr: exprf("b.Kind")}
-	ops = ops[:0]
-	for op := range blockrules {
-		ops = append(ops, op)
-	}
-	sort.Strings(ops)
-	for _, op := range ops {
-		name, data := getBlockInfo(op, arch)
-		swc := &Case{Expr: exprf("%s", name)}
-		for _, rule := range blockrules[op] {
-			swc.add(genBlockRewrite(rule, arch, data))
-		}
-		sw.add(swc)
-	}
-	if len(sw.List) > 0 { // skip if empty
-		fn.add(sw)
-	}
-	fn.add(stmtf("return false"))
-	genFile.add(fn)
-
-	// Remove unused imports and variables.
-	buf := new(bytes.Buffer)
-	fprint(buf, genFile)
-	fset := token.NewFileSet()
-	file, err := parser.ParseFile(fset, "", buf, parser.ParseComments)
-	if err != nil {
-		filename := fmt.Sprintf("%s_broken.go", arch.name)
-		if err := ioutil.WriteFile(filename, buf.Bytes(), 0644); err != nil {
-			log.Printf("failed to dump broken code to %s: %v", filename, err)
-		} else {
-			log.Printf("dumped broken code to %s", filename)
-		}
-		log.Fatalf("failed to parse generated code for arch %s: %v", arch.name, err)
-	}
-	tfile := fset.File(file.Pos())
-
-	// First, use unusedInspector to find the unused declarations by their
-	// start position.
-	u := unusedInspector{unused: make(map[token.Pos]bool)}
-	u.node(file)
-
-	// Then, delete said nodes via astutil.Apply.
-	pre := func(c *astutil.Cursor) bool {
-		node := c.Node()
-		if node == nil {
-			return true
-		}
-		if u.unused[node.Pos()] {
-			c.Delete()
-			// Unused imports and declarations use exactly
-			// one line. Prevent leaving an empty line.
-			tfile.MergeLine(tfile.Position(node.Pos()).Line)
-			return false
-		}
-		return true
-	}
-	post := func(c *astutil.Cursor) bool {
-		switch node := c.Node().(type) {
-		case *ast.GenDecl:
-			if len(node.Specs) == 0 {
-				// Don't leave a broken or empty GenDecl behind,
-				// such as "import ()".
-				c.Delete()
-			}
-		}
-		return true
-	}
-	file = astutil.Apply(file, pre, post).(*ast.File)
-
-	// Write the well-formatted source to file
-	f, err := os.Create("../rewrite" + arch.name + suff + ".go")
-	if err != nil {
-		log.Fatalf("can't write output: %v", err)
-	}
-	defer f.Close()
-	// gofmt result; use a buffered writer, as otherwise go/format spends
-	// far too much time in syscalls.
-	bw := bufio.NewWriter(f)
-	if err := format.Node(bw, fset, file); err != nil {
-		log.Fatalf("can't format output: %v", err)
-	}
-	if err := bw.Flush(); err != nil {
-		log.Fatalf("can't write output: %v", err)
-	}
-	if err := f.Close(); err != nil {
-		log.Fatalf("can't write output: %v", err)
-	}
-}
-
-// unusedInspector can be used to detect unused variables and imports in an
-// ast.Node via its node method. The result is available in the "unused" map.
-//
-// note that unusedInspector is lazy and best-effort; it only supports the node
-// types and patterns used by the rulegen program.
-type unusedInspector struct {
-	// scope is the current scope, which can never be nil when a declaration
-	// is encountered. That is, the unusedInspector.node entrypoint should
-	// generally be an entire file or block.
-	scope *scope
-
-	// unused is the resulting set of unused declared names, indexed by the
-	// starting position of the node that declared the name.
-	unused map[token.Pos]bool
-
-	// defining is the object currently being defined; this is useful so
-	// that if "foo := bar" is unused and removed, we can then detect if
-	// "bar" becomes unused as well.
-	defining *object
-}
-
-// scoped opens a new scope when called, and returns a function which closes
-// that same scope. When a scope is closed, unused variables are recorded.
-func (u *unusedInspector) scoped() func() {
-	outer := u.scope
-	u.scope = &scope{outer: outer, objects: map[string]*object{}}
-	return func() {
-		for anyUnused := true; anyUnused; {
-			anyUnused = false
-			for _, obj := range u.scope.objects {
-				if obj.numUses > 0 {
-					continue
-				}
-				u.unused[obj.pos] = true
-				for _, used := range obj.used {
-					if used.numUses--; used.numUses == 0 {
-						anyUnused = true
-					}
-				}
-				// We've decremented numUses for each of the
-				// objects in used. Zero this slice too, to keep
-				// everything consistent.
-				obj.used = nil
-			}
-		}
-		u.scope = outer
-	}
-}
-
-func (u *unusedInspector) exprs(list []ast.Expr) {
-	for _, x := range list {
-		u.node(x)
-	}
-}
-
-func (u *unusedInspector) node(node ast.Node) {
-	switch node := node.(type) {
-	case *ast.File:
-		defer u.scoped()()
-		for _, decl := range node.Decls {
-			u.node(decl)
-		}
-	case *ast.GenDecl:
-		for _, spec := range node.Specs {
-			u.node(spec)
-		}
-	case *ast.ImportSpec:
-		impPath, _ := strconv.Unquote(node.Path.Value)
-		name := path.Base(impPath)
-		u.scope.objects[name] = &object{
-			name: name,
-			pos:  node.Pos(),
-		}
-	case *ast.FuncDecl:
-		u.node(node.Type)
-		if node.Body != nil {
-			u.node(node.Body)
-		}
-	case *ast.FuncType:
-		if node.Params != nil {
-			u.node(node.Params)
-		}
-		if node.Results != nil {
-			u.node(node.Results)
-		}
-	case *ast.FieldList:
-		for _, field := range node.List {
-			u.node(field)
-		}
-	case *ast.Field:
-		u.node(node.Type)
-
-	// statements
-
-	case *ast.BlockStmt:
-		defer u.scoped()()
-		for _, stmt := range node.List {
-			u.node(stmt)
-		}
-	case *ast.DeclStmt:
-		u.node(node.Decl)
-	case *ast.IfStmt:
-		if node.Init != nil {
-			u.node(node.Init)
-		}
-		u.node(node.Cond)
-		u.node(node.Body)
-		if node.Else != nil {
-			u.node(node.Else)
-		}
-	case *ast.ForStmt:
-		if node.Init != nil {
-			u.node(node.Init)
-		}
-		if node.Cond != nil {
-			u.node(node.Cond)
-		}
-		if node.Post != nil {
-			u.node(node.Post)
-		}
-		u.node(node.Body)
-	case *ast.SwitchStmt:
-		if node.Init != nil {
-			u.node(node.Init)
-		}
-		if node.Tag != nil {
-			u.node(node.Tag)
-		}
-		u.node(node.Body)
-	case *ast.CaseClause:
-		u.exprs(node.List)
-		defer u.scoped()()
-		for _, stmt := range node.Body {
-			u.node(stmt)
-		}
-	case *ast.BranchStmt:
-	case *ast.ExprStmt:
-		u.node(node.X)
-	case *ast.AssignStmt:
-		if node.Tok != token.DEFINE {
-			u.exprs(node.Rhs)
-			u.exprs(node.Lhs)
-			break
-		}
-		lhs := node.Lhs
-		if len(lhs) == 2 && lhs[1].(*ast.Ident).Name == "_" {
-			lhs = lhs[:1]
-		}
-		if len(lhs) != 1 {
-			panic("no support for := with multiple names")
-		}
-
-		name := lhs[0].(*ast.Ident)
-		obj := &object{
-			name: name.Name,
-			pos:  name.NamePos,
-		}
-
-		old := u.defining
-		u.defining = obj
-		u.exprs(node.Rhs)
-		u.defining = old
-
-		u.scope.objects[name.Name] = obj
-	case *ast.ReturnStmt:
-		u.exprs(node.Results)
-	case *ast.IncDecStmt:
-		u.node(node.X)
-
-	// expressions
-
-	case *ast.CallExpr:
-		u.node(node.Fun)
-		u.exprs(node.Args)
-	case *ast.SelectorExpr:
-		u.node(node.X)
-	case *ast.UnaryExpr:
-		u.node(node.X)
-	case *ast.BinaryExpr:
-		u.node(node.X)
-		u.node(node.Y)
-	case *ast.StarExpr:
-		u.node(node.X)
-	case *ast.ParenExpr:
-		u.node(node.X)
-	case *ast.IndexExpr:
-		u.node(node.X)
-		u.node(node.Index)
-	case *ast.TypeAssertExpr:
-		u.node(node.X)
-		u.node(node.Type)
-	case *ast.Ident:
-		if obj := u.scope.Lookup(node.Name); obj != nil {
-			obj.numUses++
-			if u.defining != nil {
-				u.defining.used = append(u.defining.used, obj)
-			}
-		}
-	case *ast.BasicLit:
-	case *ast.ValueSpec:
-		u.exprs(node.Values)
-	default:
-		panic(fmt.Sprintf("unhandled node: %T", node))
-	}
-}
-
-// scope keeps track of a certain scope and its declared names, as well as the
-// outer (parent) scope.
-type scope struct {
-	outer   *scope             // can be nil, if this is the top-level scope
-	objects map[string]*object // indexed by each declared name
-}
-
-func (s *scope) Lookup(name string) *object {
-	if obj := s.objects[name]; obj != nil {
-		return obj
-	}
-	if s.outer == nil {
-		return nil
-	}
-	return s.outer.Lookup(name)
-}
-
-// object keeps track of a declared name, such as a variable or import.
-type object struct {
-	name string
-	pos  token.Pos // start position of the node declaring the object
-
-	numUses int       // number of times this object is used
-	used    []*object // objects that its declaration makes use of
-}
-
-func fprint(w io.Writer, n Node) {
-	switch n := n.(type) {
-	case *File:
-		file := n
-		seenRewrite := make(map[[3]string]string)
-		fmt.Fprintf(w, "// Code generated from gen/%s%s.rules; DO NOT EDIT.\n", n.Arch.name, n.Suffix)
-		fmt.Fprintf(w, "// generated with: cd gen; go run *.go\n")
-		fmt.Fprintf(w, "\npackage ssa\n")
-		for _, path := range append([]string{
-			"fmt",
-			"internal/buildcfg",
-			"math",
-			"cmd/internal/obj",
-			"cmd/compile/internal/base",
-			"cmd/compile/internal/types",
-		}, n.Arch.imports...) {
-			fmt.Fprintf(w, "import %q\n", path)
-		}
-		for _, f := range n.List {
-			f := f.(*Func)
-			fmt.Fprintf(w, "func rewrite%s%s%s%s(", f.Kind, n.Arch.name, n.Suffix, f.Suffix)
-			fmt.Fprintf(w, "%c *%s) bool {\n", strings.ToLower(f.Kind)[0], f.Kind)
-			if f.Kind == "Value" && f.ArgLen > 0 {
-				for i := f.ArgLen - 1; i >= 0; i-- {
-					fmt.Fprintf(w, "v_%d := v.Args[%d]\n", i, i)
-				}
-			}
-			for _, n := range f.List {
-				fprint(w, n)
-
-				if rr, ok := n.(*RuleRewrite); ok {
-					k := [3]string{
-						normalizeMatch(rr.Match, file.Arch),
-						normalizeWhitespace(rr.Cond),
-						normalizeWhitespace(rr.Result),
-					}
-					if prev, ok := seenRewrite[k]; ok {
-						log.Fatalf("duplicate rule %s, previously seen at %s\n", rr.Loc, prev)
-					}
-					seenRewrite[k] = rr.Loc
-				}
-			}
-			fmt.Fprintf(w, "}\n")
-		}
-	case *Switch:
-		fmt.Fprintf(w, "switch ")
-		fprint(w, n.Expr)
-		fmt.Fprintf(w, " {\n")
-		for _, n := range n.List {
-			fprint(w, n)
-		}
-		fmt.Fprintf(w, "}\n")
-	case *Case:
-		fmt.Fprintf(w, "case ")
-		fprint(w, n.Expr)
-		fmt.Fprintf(w, ":\n")
-		for _, n := range n.List {
-			fprint(w, n)
-		}
-	case *RuleRewrite:
-		if *addLine {
-			fmt.Fprintf(w, "// %s\n", n.Loc)
-		}
-		fmt.Fprintf(w, "// match: %s\n", n.Match)
-		if n.Cond != "" {
-			fmt.Fprintf(w, "// cond: %s\n", n.Cond)
-		}
-		fmt.Fprintf(w, "// result: %s\n", n.Result)
-		fmt.Fprintf(w, "for %s {\n", n.Check)
-		nCommutative := 0
-		for _, n := range n.List {
-			if b, ok := n.(*CondBreak); ok {
-				b.InsideCommuteLoop = nCommutative > 0
-			}
-			fprint(w, n)
-			if loop, ok := n.(StartCommuteLoop); ok {
-				if nCommutative != loop.Depth {
-					panic("mismatch commute loop depth")
-				}
-				nCommutative++
-			}
-		}
-		fmt.Fprintf(w, "return true\n")
-		for i := 0; i < nCommutative; i++ {
-			fmt.Fprintln(w, "}")
-		}
-		if n.CommuteDepth > 0 && n.CanFail {
-			fmt.Fprint(w, "break\n")
-		}
-		fmt.Fprintf(w, "}\n")
-	case *Declare:
-		fmt.Fprintf(w, "%s := ", n.Name)
-		fprint(w, n.Value)
-		fmt.Fprintln(w)
-	case *CondBreak:
-		fmt.Fprintf(w, "if ")
-		fprint(w, n.Cond)
-		fmt.Fprintf(w, " {\n")
-		if n.InsideCommuteLoop {
-			fmt.Fprintf(w, "continue")
-		} else {
-			fmt.Fprintf(w, "break")
-		}
-		fmt.Fprintf(w, "\n}\n")
-	case ast.Node:
-		printConfig.Fprint(w, emptyFset, n)
-		if _, ok := n.(ast.Stmt); ok {
-			fmt.Fprintln(w)
-		}
-	case StartCommuteLoop:
-		fmt.Fprintf(w, "for _i%[1]d := 0; _i%[1]d <= 1; _i%[1]d, %[2]s_0, %[2]s_1 = _i%[1]d + 1, %[2]s_1, %[2]s_0 {\n", n.Depth, n.V)
-	default:
-		log.Fatalf("cannot print %T", n)
-	}
-}
-
-var printConfig = printer.Config{
-	Mode: printer.RawFormat, // we use go/format later, so skip work here
-}
-
-var emptyFset = token.NewFileSet()
-
-// Node can be a Statement or an ast.Expr.
-type Node interface{}
-
-// Statement can be one of our high-level statement struct types, or an
-// ast.Stmt under some limited circumstances.
-type Statement interface{}
-
-// BodyBase is shared by all of our statement pseudo-node types which can
-// contain other statements.
-type BodyBase struct {
-	List    []Statement
-	CanFail bool
-}
-
-func (w *BodyBase) add(node Statement) {
-	var last Statement
-	if len(w.List) > 0 {
-		last = w.List[len(w.List)-1]
-	}
-	if node, ok := node.(*CondBreak); ok {
-		w.CanFail = true
-		if last, ok := last.(*CondBreak); ok {
-			// Add to the previous "if <cond> { break }" via a
-			// logical OR, which will save verbosity.
-			last.Cond = &ast.BinaryExpr{
-				Op: token.LOR,
-				X:  last.Cond,
-				Y:  node.Cond,
-			}
-			return
-		}
-	}
-
-	w.List = append(w.List, node)
-}
-
-// predeclared contains globally known tokens that should not be redefined.
-var predeclared = map[string]bool{
-	"nil":   true,
-	"false": true,
-	"true":  true,
-}
-
-// declared reports if the body contains a Declare with the given name.
-func (w *BodyBase) declared(name string) bool {
-	if predeclared[name] {
-		// Treat predeclared names as having already been declared.
-		// This lets us use nil to match an aux field or
-		// true and false to match an auxint field.
-		return true
-	}
-	for _, s := range w.List {
-		if decl, ok := s.(*Declare); ok && decl.Name == name {
-			return true
-		}
-	}
-	return false
-}
-
-// These types define some high-level statement struct types, which can be used
-// as a Statement. This allows us to keep some node structs simpler, and have
-// higher-level nodes such as an entire rule rewrite.
-//
-// Note that ast.Expr is always used as-is; we don't declare our own expression
-// nodes.
-type (
-	File struct {
-		BodyBase // []*Func
-		Arch     arch
-		Suffix   string
-	}
-	Func struct {
-		BodyBase
-		Kind   string // "Value" or "Block"
-		Suffix string
-		ArgLen int32 // if kind == "Value", number of args for this op
-	}
-	Switch struct {
-		BodyBase // []*Case
-		Expr     ast.Expr
-	}
-	Case struct {
-		BodyBase
-		Expr ast.Expr
-	}
-	RuleRewrite struct {
-		BodyBase
-		Match, Cond, Result string // top comments
-		Check               string // top-level boolean expression
-
-		Alloc        int    // for unique var names
-		Loc          string // file name & line number of the original rule
-		CommuteDepth int    // used to track depth of commute loops
-	}
-	Declare struct {
-		Name  string
-		Value ast.Expr
-	}
-	CondBreak struct {
-		Cond              ast.Expr
-		InsideCommuteLoop bool
-	}
-	StartCommuteLoop struct {
-		Depth int
-		V     string
-	}
-)
-
-// exprf parses a Go expression generated from fmt.Sprintf, panicking if an
-// error occurs.
-func exprf(format string, a ...interface{}) ast.Expr {
-	src := fmt.Sprintf(format, a...)
-	expr, err := parser.ParseExpr(src)
-	if err != nil {
-		log.Fatalf("expr parse error on %q: %v", src, err)
-	}
-	return expr
-}
-
-// stmtf parses a Go statement generated from fmt.Sprintf. This function is only
-// meant for simple statements that don't have a custom Statement node declared
-// in this package, such as ast.ReturnStmt or ast.ExprStmt.
-func stmtf(format string, a ...interface{}) Statement {
-	src := fmt.Sprintf(format, a...)
-	fsrc := "package p\nfunc _() {\n" + src + "\n}\n"
-	file, err := parser.ParseFile(token.NewFileSet(), "", fsrc, 0)
-	if err != nil {
-		log.Fatalf("stmt parse error on %q: %v", src, err)
-	}
-	return file.Decls[0].(*ast.FuncDecl).Body.List[0]
-}
-
-var reservedNames = map[string]bool{
-	"v":      true, // Values[i], etc
-	"b":      true, // v.Block
-	"config": true, // b.Func.Config
-	"fe":     true, // b.Func.fe
-	"typ":    true, // &b.Func.Config.Types
-}
-
-// declf constructs a simple "name := value" declaration,
-// using exprf for its value.
-//
-// name must not be one of reservedNames.
-// This helps prevent unintended shadowing and name clashes.
-// To declare a reserved name, use declReserved.
-func declf(loc, name, format string, a ...interface{}) *Declare {
-	if reservedNames[name] {
-		log.Fatalf("rule %s uses the reserved name %s", loc, name)
-	}
-	return &Declare{name, exprf(format, a...)}
-}
-
-// declReserved is like declf, but the name must be one of reservedNames.
-// Calls to declReserved should generally be static and top-level.
-func declReserved(name, value string) *Declare {
-	if !reservedNames[name] {
-		panic(fmt.Sprintf("declReserved call does not use a reserved name: %q", name))
-	}
-	return &Declare{name, exprf(value)}
-}
-
-// breakf constructs a simple "if cond { break }" statement, using exprf for its
-// condition.
-func breakf(format string, a ...interface{}) *CondBreak {
-	return &CondBreak{Cond: exprf(format, a...)}
-}
-
-func genBlockRewrite(rule Rule, arch arch, data blockData) *RuleRewrite {
-	rr := &RuleRewrite{Loc: rule.Loc}
-	rr.Match, rr.Cond, rr.Result = rule.parse()
-	_, _, auxint, aux, s := extract(rr.Match) // remove parens, then split
-
-	// check match of control values
-	if len(s) < data.controls {
-		log.Fatalf("incorrect number of arguments in %s, got %v wanted at least %v", rule, len(s), data.controls)
-	}
-	controls := s[:data.controls]
-	pos := make([]string, data.controls)
-	for i, arg := range controls {
-		cname := fmt.Sprintf("b.Controls[%v]", i)
-		if strings.Contains(arg, "(") {
-			vname, expr := splitNameExpr(arg)
-			if vname == "" {
-				vname = fmt.Sprintf("v_%v", i)
-			}
-			rr.add(declf(rr.Loc, vname, cname))
-			p, op := genMatch0(rr, arch, expr, vname, nil, false) // TODO: pass non-nil cnt?
-			if op != "" {
-				check := fmt.Sprintf("%s.Op == %s", cname, op)
-				if rr.Check == "" {
-					rr.Check = check
-				} else {
-					rr.Check += " && " + check
-				}
-			}
-			if p == "" {
-				p = vname + ".Pos"
-			}
-			pos[i] = p
-		} else {
-			rr.add(declf(rr.Loc, arg, cname))
-			pos[i] = arg + ".Pos"
-		}
-	}
-	for _, e := range []struct {
-		name, field, dclType string
-	}{
-		{auxint, "AuxInt", data.auxIntType()},
-		{aux, "Aux", data.auxType()},
-	} {
-		if e.name == "" {
-			continue
-		}
-
-		if e.dclType == "" {
-			log.Fatalf("op %s has no declared type for %s", data.name, e.field)
-		}
-		if !token.IsIdentifier(e.name) || rr.declared(e.name) {
-			rr.add(breakf("%sTo%s(b.%s) != %s", unTitle(e.field), title(e.dclType), e.field, e.name))
-		} else {
-			rr.add(declf(rr.Loc, e.name, "%sTo%s(b.%s)", unTitle(e.field), title(e.dclType), e.field))
-		}
-	}
-	if rr.Cond != "" {
-		rr.add(breakf("!(%s)", rr.Cond))
-	}
-
-	// Rule matches. Generate result.
-	outop, _, auxint, aux, t := extract(rr.Result) // remove parens, then split
-	blockName, outdata := getBlockInfo(outop, arch)
-	if len(t) < outdata.controls {
-		log.Fatalf("incorrect number of output arguments in %s, got %v wanted at least %v", rule, len(s), outdata.controls)
-	}
-
-	// Check if newsuccs is the same set as succs.
-	succs := s[data.controls:]
-	newsuccs := t[outdata.controls:]
-	m := map[string]bool{}
-	for _, succ := range succs {
-		if m[succ] {
-			log.Fatalf("can't have a repeat successor name %s in %s", succ, rule)
-		}
-		m[succ] = true
-	}
-	for _, succ := range newsuccs {
-		if !m[succ] {
-			log.Fatalf("unknown successor %s in %s", succ, rule)
-		}
-		delete(m, succ)
-	}
-	if len(m) != 0 {
-		log.Fatalf("unmatched successors %v in %s", m, rule)
-	}
-
-	var genControls [2]string
-	for i, control := range t[:outdata.controls] {
-		// Select a source position for any new control values.
-		// TODO: does it always make sense to use the source position
-		// of the original control values or should we be using the
-		// block's source position in some cases?
-		newpos := "b.Pos" // default to block's source position
-		if i < len(pos) && pos[i] != "" {
-			// Use the previous control value's source position.
-			newpos = pos[i]
-		}
-
-		// Generate a new control value (or copy an existing value).
-		genControls[i] = genResult0(rr, arch, control, false, false, newpos, nil)
-	}
-	switch outdata.controls {
-	case 0:
-		rr.add(stmtf("b.Reset(%s)", blockName))
-	case 1:
-		rr.add(stmtf("b.resetWithControl(%s, %s)", blockName, genControls[0]))
-	case 2:
-		rr.add(stmtf("b.resetWithControl2(%s, %s, %s)", blockName, genControls[0], genControls[1]))
-	default:
-		log.Fatalf("too many controls: %d", outdata.controls)
-	}
-
-	if auxint != "" {
-		// Make sure auxint value has the right type.
-		rr.add(stmtf("b.AuxInt = %sToAuxInt(%s)", unTitle(outdata.auxIntType()), auxint))
-	}
-	if aux != "" {
-		// Make sure aux value has the right type.
-		rr.add(stmtf("b.Aux = %sToAux(%s)", unTitle(outdata.auxType()), aux))
-	}
-
-	succChanged := false
-	for i := 0; i < len(succs); i++ {
-		if succs[i] != newsuccs[i] {
-			succChanged = true
-		}
-	}
-	if succChanged {
-		if len(succs) != 2 {
-			log.Fatalf("changed successors, len!=2 in %s", rule)
-		}
-		if succs[0] != newsuccs[1] || succs[1] != newsuccs[0] {
-			log.Fatalf("can only handle swapped successors in %s", rule)
-		}
-		rr.add(stmtf("b.swapSuccessors()"))
-	}
-
-	if *genLog {
-		rr.add(stmtf("logRule(%q)", rule.Loc))
-	}
-	return rr
-}
-
-// genMatch returns the variable whose source position should be used for the
-// result (or "" if no opinion), and a boolean that reports whether the match can fail.
-func genMatch(rr *RuleRewrite, arch arch, match string, pregenTop bool) (pos, checkOp string) {
-	cnt := varCount(rr)
-	return genMatch0(rr, arch, match, "v", cnt, pregenTop)
-}
-
-func genMatch0(rr *RuleRewrite, arch arch, match, v string, cnt map[string]int, pregenTop bool) (pos, checkOp string) {
-	if match[0] != '(' || match[len(match)-1] != ')' {
-		log.Fatalf("%s: non-compound expr in genMatch0: %q", rr.Loc, match)
-	}
-	op, oparch, typ, auxint, aux, args := parseValue(match, arch, rr.Loc)
-
-	checkOp = fmt.Sprintf("Op%s%s", oparch, op.name)
-
-	if op.faultOnNilArg0 || op.faultOnNilArg1 {
-		// Prefer the position of an instruction which could fault.
-		pos = v + ".Pos"
-	}
-
-	// If the last argument is ___, it means "don't care about trailing arguments, really"
-	// The likely/intended use is for rewrites that are too tricky to express in the existing pattern language
-	// Do a length check early because long patterns fed short (ultimately not-matching) inputs will
-	// do an indexing error in pattern-matching.
-	if op.argLength == -1 {
-		l := len(args)
-		if l == 0 || args[l-1] != "___" {
-			rr.add(breakf("len(%s.Args) != %d", v, l))
-		} else if l > 1 && args[l-1] == "___" {
-			rr.add(breakf("len(%s.Args) < %d", v, l-1))
-		}
-	}
-
-	for _, e := range []struct {
-		name, field, dclType string
-	}{
-		{typ, "Type", "*types.Type"},
-		{auxint, "AuxInt", op.auxIntType()},
-		{aux, "Aux", op.auxType()},
-	} {
-		if e.name == "" {
-			continue
-		}
-
-		if e.dclType == "" {
-			log.Fatalf("op %s has no declared type for %s", op.name, e.field)
-		}
-		if !token.IsIdentifier(e.name) || rr.declared(e.name) {
-			switch e.field {
-			case "Aux":
-				rr.add(breakf("auxTo%s(%s.%s) != %s", title(e.dclType), v, e.field, e.name))
-			case "AuxInt":
-				rr.add(breakf("auxIntTo%s(%s.%s) != %s", title(e.dclType), v, e.field, e.name))
-			case "Type":
-				rr.add(breakf("%s.%s != %s", v, e.field, e.name))
-			}
-		} else {
-			switch e.field {
-			case "Aux":
-				rr.add(declf(rr.Loc, e.name, "auxTo%s(%s.%s)", title(e.dclType), v, e.field))
-			case "AuxInt":
-				rr.add(declf(rr.Loc, e.name, "auxIntTo%s(%s.%s)", title(e.dclType), v, e.field))
-			case "Type":
-				rr.add(declf(rr.Loc, e.name, "%s.%s", v, e.field))
-			}
-		}
-	}
-
-	commutative := op.commutative
-	if commutative {
-		if args[0] == args[1] {
-			// When we have (Add x x), for any x,
-			// even if there are other uses of x besides these two,
-			// and even if x is not a variable,
-			// we can skip the commutative match.
-			commutative = false
-		}
-		if cnt[args[0]] == 1 && cnt[args[1]] == 1 {
-			// When we have (Add x y) with no other uses
-			// of x and y in the matching rule and condition,
-			// then we can skip the commutative match (Add y x).
-			commutative = false
-		}
-	}
-
-	if !pregenTop {
-		// Access last argument first to minimize bounds checks.
-		for n := len(args) - 1; n > 0; n-- {
-			a := args[n]
-			if a == "_" {
-				continue
-			}
-			if !rr.declared(a) && token.IsIdentifier(a) && !(commutative && len(args) == 2) {
-				rr.add(declf(rr.Loc, a, "%s.Args[%d]", v, n))
-				// delete the last argument so it is not reprocessed
-				args = args[:n]
-			} else {
-				rr.add(stmtf("_ = %s.Args[%d]", v, n))
-			}
-			break
-		}
-	}
-	if commutative && !pregenTop {
-		for i := 0; i <= 1; i++ {
-			vname := fmt.Sprintf("%s_%d", v, i)
-			rr.add(declf(rr.Loc, vname, "%s.Args[%d]", v, i))
-		}
-	}
-	if commutative {
-		rr.add(StartCommuteLoop{rr.CommuteDepth, v})
-		rr.CommuteDepth++
-	}
-	for i, arg := range args {
-		if arg == "_" {
-			continue
-		}
-		var rhs string
-		if (commutative && i < 2) || pregenTop {
-			rhs = fmt.Sprintf("%s_%d", v, i)
-		} else {
-			rhs = fmt.Sprintf("%s.Args[%d]", v, i)
-		}
-		if !strings.Contains(arg, "(") {
-			// leaf variable
-			if rr.declared(arg) {
-				// variable already has a definition. Check whether
-				// the old definition and the new definition match.
-				// For example, (add x x).  Equality is just pointer equality
-				// on Values (so cse is important to do before lowering).
-				rr.add(breakf("%s != %s", arg, rhs))
-			} else {
-				if arg != rhs {
-					rr.add(declf(rr.Loc, arg, "%s", rhs))
-				}
-			}
-			continue
-		}
-		// compound sexpr
-		argname, expr := splitNameExpr(arg)
-		if argname == "" {
-			argname = fmt.Sprintf("%s_%d", v, i)
-		}
-		if argname == "b" {
-			log.Fatalf("don't name args 'b', it is ambiguous with blocks")
-		}
-
-		if argname != rhs {
-			rr.add(declf(rr.Loc, argname, "%s", rhs))
-		}
-		bexpr := exprf("%s.Op != addLater", argname)
-		rr.add(&CondBreak{Cond: bexpr})
-		argPos, argCheckOp := genMatch0(rr, arch, expr, argname, cnt, false)
-		bexpr.(*ast.BinaryExpr).Y.(*ast.Ident).Name = argCheckOp
-
-		if argPos != "" {
-			// Keep the argument in preference to the parent, as the
-			// argument is normally earlier in program flow.
-			// Keep the argument in preference to an earlier argument,
-			// as that prefers the memory argument which is also earlier
-			// in the program flow.
-			pos = argPos
-		}
-	}
-
-	return pos, checkOp
-}
-
-func genResult(rr *RuleRewrite, arch arch, result, pos string) {
-	move := result[0] == '@'
-	if move {
-		// parse @block directive
-		s := strings.SplitN(result[1:], " ", 2)
-		rr.add(stmtf("b = %s", s[0]))
-		result = s[1]
-	}
-	cse := make(map[string]string)
-	genResult0(rr, arch, result, true, move, pos, cse)
-}
-
-func genResult0(rr *RuleRewrite, arch arch, result string, top, move bool, pos string, cse map[string]string) string {
-	resname, expr := splitNameExpr(result)
-	result = expr
-	// TODO: when generating a constant result, use f.constVal to avoid
-	// introducing copies just to clean them up again.
-	if result[0] != '(' {
-		// variable
-		if top {
-			// It in not safe in general to move a variable between blocks
-			// (and particularly not a phi node).
-			// Introduce a copy.
-			rr.add(stmtf("v.copyOf(%s)", result))
-		}
-		return result
-	}
-
-	w := normalizeWhitespace(result)
-	if prev := cse[w]; prev != "" {
-		return prev
-	}
-
-	op, oparch, typ, auxint, aux, args := parseValue(result, arch, rr.Loc)
-
-	// Find the type of the variable.
-	typeOverride := typ != ""
-	if typ == "" && op.typ != "" {
-		typ = typeName(op.typ)
-	}
-
-	v := "v"
-	if top && !move {
-		rr.add(stmtf("v.reset(Op%s%s)", oparch, op.name))
-		if typeOverride {
-			rr.add(stmtf("v.Type = %s", typ))
-		}
-	} else {
-		if typ == "" {
-			log.Fatalf("sub-expression %s (op=Op%s%s) at %s must have a type", result, oparch, op.name, rr.Loc)
-		}
-		if resname == "" {
-			v = fmt.Sprintf("v%d", rr.Alloc)
-		} else {
-			v = resname
-		}
-		rr.Alloc++
-		rr.add(declf(rr.Loc, v, "b.NewValue0(%s, Op%s%s, %s)", pos, oparch, op.name, typ))
-		if move && top {
-			// Rewrite original into a copy
-			rr.add(stmtf("v.copyOf(%s)", v))
-		}
-	}
-
-	if auxint != "" {
-		// Make sure auxint value has the right type.
-		rr.add(stmtf("%s.AuxInt = %sToAuxInt(%s)", v, unTitle(op.auxIntType()), auxint))
-	}
-	if aux != "" {
-		// Make sure aux value has the right type.
-		rr.add(stmtf("%s.Aux = %sToAux(%s)", v, unTitle(op.auxType()), aux))
-	}
-	all := new(strings.Builder)
-	for i, arg := range args {
-		x := genResult0(rr, arch, arg, false, move, pos, cse)
-		if i > 0 {
-			all.WriteString(", ")
-		}
-		all.WriteString(x)
-	}
-	switch len(args) {
-	case 0:
-	case 1:
-		rr.add(stmtf("%s.AddArg(%s)", v, all.String()))
-	default:
-		rr.add(stmtf("%s.AddArg%d(%s)", v, len(args), all.String()))
-	}
-
-	if cse != nil {
-		cse[w] = v
-	}
-	return v
-}
-
-func split(s string) []string {
-	var r []string
-
-outer:
-	for s != "" {
-		d := 0               // depth of ({[<
-		var open, close byte // opening and closing markers ({[< or )}]>
-		nonsp := false       // found a non-space char so far
-		for i := 0; i < len(s); i++ {
-			switch {
-			case d == 0 && s[i] == '(':
-				open, close = '(', ')'
-				d++
-			case d == 0 && s[i] == '<':
-				open, close = '<', '>'
-				d++
-			case d == 0 && s[i] == '[':
-				open, close = '[', ']'
-				d++
-			case d == 0 && s[i] == '{':
-				open, close = '{', '}'
-				d++
-			case d == 0 && (s[i] == ' ' || s[i] == '\t'):
-				if nonsp {
-					r = append(r, strings.TrimSpace(s[:i]))
-					s = s[i:]
-					continue outer
-				}
-			case d > 0 && s[i] == open:
-				d++
-			case d > 0 && s[i] == close:
-				d--
-			default:
-				nonsp = true
-			}
-		}
-		if d != 0 {
-			log.Fatalf("imbalanced expression: %q", s)
-		}
-		if nonsp {
-			r = append(r, strings.TrimSpace(s))
-		}
-		break
-	}
-	return r
-}
-
-// isBlock reports whether this op is a block opcode.
-func isBlock(name string, arch arch) bool {
-	for _, b := range genericBlocks {
-		if b.name == name {
-			return true
-		}
-	}
-	for _, b := range arch.blocks {
-		if b.name == name {
-			return true
-		}
-	}
-	return false
-}
-
-func extract(val string) (op, typ, auxint, aux string, args []string) {
-	val = val[1 : len(val)-1] // remove ()
-
-	// Split val up into regions.
-	// Split by spaces/tabs, except those contained in (), {}, [], or <>.
-	s := split(val)
-
-	// Extract restrictions and args.
-	op = s[0]
-	for _, a := range s[1:] {
-		switch a[0] {
-		case '<':
-			typ = a[1 : len(a)-1] // remove <>
-		case '[':
-			auxint = a[1 : len(a)-1] // remove []
-		case '{':
-			aux = a[1 : len(a)-1] // remove {}
-		default:
-			args = append(args, a)
-		}
-	}
-	return
-}
-
-// parseValue parses a parenthesized value from a rule.
-// The value can be from the match or the result side.
-// It returns the op and unparsed strings for typ, auxint, and aux restrictions and for all args.
-// oparch is the architecture that op is located in, or "" for generic.
-func parseValue(val string, arch arch, loc string) (op opData, oparch, typ, auxint, aux string, args []string) {
-	// Resolve the op.
-	var s string
-	s, typ, auxint, aux, args = extract(val)
-
-	// match reports whether x is a good op to select.
-	// If strict is true, rule generation might succeed.
-	// If strict is false, rule generation has failed,
-	// but we're trying to generate a useful error.
-	// Doing strict=true then strict=false allows
-	// precise op matching while retaining good error messages.
-	match := func(x opData, strict bool, archname string) bool {
-		if x.name != s {
-			return false
-		}
-		if x.argLength != -1 && int(x.argLength) != len(args) && (len(args) != 1 || args[0] != "...") {
-			if strict {
-				return false
-			}
-			log.Printf("%s: op %s (%s) should have %d args, has %d", loc, s, archname, x.argLength, len(args))
-		}
-		return true
-	}
-
-	for _, x := range genericOps {
-		if match(x, true, "generic") {
-			op = x
-			break
-		}
-	}
-	for _, x := range arch.ops {
-		if arch.name != "generic" && match(x, true, arch.name) {
-			if op.name != "" {
-				log.Fatalf("%s: matches for op %s found in both generic and %s", loc, op.name, arch.name)
-			}
-			op = x
-			oparch = arch.name
-			break
-		}
-	}
-
-	if op.name == "" {
-		// Failed to find the op.
-		// Run through everything again with strict=false
-		// to generate useful diagnosic messages before failing.
-		for _, x := range genericOps {
-			match(x, false, "generic")
-		}
-		for _, x := range arch.ops {
-			match(x, false, arch.name)
-		}
-		log.Fatalf("%s: unknown op %s", loc, s)
-	}
-
-	// Sanity check aux, auxint.
-	if auxint != "" && !opHasAuxInt(op) {
-		log.Fatalf("%s: op %s %s can't have auxint", loc, op.name, op.aux)
-	}
-	if aux != "" && !opHasAux(op) {
-		log.Fatalf("%s: op %s %s can't have aux", loc, op.name, op.aux)
-	}
-	return
-}
-
-func opHasAuxInt(op opData) bool {
-	switch op.aux {
-	case "Bool", "Int8", "Int16", "Int32", "Int64", "Int128", "UInt8", "Float32", "Float64",
-		"SymOff", "CallOff", "SymValAndOff", "TypSize", "ARM64BitField", "FlagConstant", "CCop":
-		return true
-	}
-	return false
-}
-
-func opHasAux(op opData) bool {
-	switch op.aux {
-	case "String", "Sym", "SymOff", "Call", "CallOff", "SymValAndOff", "Typ", "TypSize",
-		"S390XCCMask", "S390XRotateParams":
-		return true
-	}
-	return false
-}
-
-// splitNameExpr splits s-expr arg, possibly prefixed by "name:",
-// into name and the unprefixed expression.
-// For example, "x:(Foo)" yields "x", "(Foo)",
-// and "(Foo)" yields "", "(Foo)".
-func splitNameExpr(arg string) (name, expr string) {
-	colon := strings.Index(arg, ":")
-	if colon < 0 {
-		return "", arg
-	}
-	openparen := strings.Index(arg, "(")
-	if openparen < 0 {
-		log.Fatalf("splitNameExpr(%q): colon but no open parens", arg)
-	}
-	if colon > openparen {
-		// colon is inside the parens, such as in "(Foo x:(Bar))".
-		return "", arg
-	}
-	return arg[:colon], arg[colon+1:]
-}
-
-func getBlockInfo(op string, arch arch) (name string, data blockData) {
-	for _, b := range genericBlocks {
-		if b.name == op {
-			return "Block" + op, b
-		}
-	}
-	for _, b := range arch.blocks {
-		if b.name == op {
-			return "Block" + arch.name + op, b
-		}
-	}
-	log.Fatalf("could not find block data for %s", op)
-	panic("unreachable")
-}
-
-// typeName returns the string to use to generate a type.
-func typeName(typ string) string {
-	if typ[0] == '(' {
-		ts := strings.Split(typ[1:len(typ)-1], ",")
-		if len(ts) != 2 {
-			log.Fatalf("Tuple expect 2 arguments")
-		}
-		return "types.NewTuple(" + typeName(ts[0]) + ", " + typeName(ts[1]) + ")"
-	}
-	switch typ {
-	case "Flags", "Mem", "Void", "Int128":
-		return "types.Type" + typ
-	default:
-		return "typ." + typ
-	}
-}
-
-// balance returns the number of unclosed '(' characters in s.
-// If a ')' appears without a corresponding '(', balance returns -1.
-func balance(s string) int {
-	balance := 0
-	for _, c := range s {
-		switch c {
-		case '(':
-			balance++
-		case ')':
-			balance--
-			if balance < 0 {
-				// don't allow ")(" to return 0
-				return -1
-			}
-		}
-	}
-	return balance
-}
-
-// findAllOpcode is a function to find the opcode portion of s-expressions.
-var findAllOpcode = regexp.MustCompile(`[(](\w+[|])+\w+[)]`).FindAllStringIndex
-
-// excludeFromExpansion reports whether the substring s[idx[0]:idx[1]] in a rule
-// should be disregarded as a candidate for | expansion.
-// It uses simple syntactic checks to see whether the substring
-// is inside an AuxInt expression or inside the && conditions.
-func excludeFromExpansion(s string, idx []int) bool {
-	left := s[:idx[0]]
-	if strings.LastIndexByte(left, '[') > strings.LastIndexByte(left, ']') {
-		// Inside an AuxInt expression.
-		return true
-	}
-	right := s[idx[1]:]
-	if strings.Contains(left, "&&") && strings.Contains(right, "=>") {
-		// Inside && conditions.
-		return true
-	}
-	return false
-}
-
-// expandOr converts a rule into multiple rules by expanding | ops.
-func expandOr(r string) []string {
-	// Find every occurrence of |-separated things.
-	// They look like MOV(B|W|L|Q|SS|SD)load or MOV(Q|L)loadidx(1|8).
-	// Generate rules selecting one case from each |-form.
-
-	// Count width of |-forms.  They must match.
-	n := 1
-	for _, idx := range findAllOpcode(r, -1) {
-		if excludeFromExpansion(r, idx) {
-			continue
-		}
-		s := r[idx[0]:idx[1]]
-		c := strings.Count(s, "|") + 1
-		if c == 1 {
-			continue
-		}
-		if n > 1 && n != c {
-			log.Fatalf("'|' count doesn't match in %s: both %d and %d\n", r, n, c)
-		}
-		n = c
-	}
-	if n == 1 {
-		// No |-form in this rule.
-		return []string{r}
-	}
-	// Build each new rule.
-	res := make([]string, n)
-	for i := 0; i < n; i++ {
-		buf := new(strings.Builder)
-		x := 0
-		for _, idx := range findAllOpcode(r, -1) {
-			if excludeFromExpansion(r, idx) {
-				continue
-			}
-			buf.WriteString(r[x:idx[0]])              // write bytes we've skipped over so far
-			s := r[idx[0]+1 : idx[1]-1]               // remove leading "(" and trailing ")"
-			buf.WriteString(strings.Split(s, "|")[i]) // write the op component for this rule
-			x = idx[1]                                // note that we've written more bytes
-		}
-		buf.WriteString(r[x:])
-		res[i] = buf.String()
-	}
-	return res
-}
-
-// varCount returns a map which counts the number of occurrences of
-// Value variables in the s-expression rr.Match and the Go expression rr.Cond.
-func varCount(rr *RuleRewrite) map[string]int {
-	cnt := map[string]int{}
-	varCount1(rr.Loc, rr.Match, cnt)
-	if rr.Cond != "" {
-		expr, err := parser.ParseExpr(rr.Cond)
-		if err != nil {
-			log.Fatalf("%s: failed to parse cond %q: %v", rr.Loc, rr.Cond, err)
-		}
-		ast.Inspect(expr, func(n ast.Node) bool {
-			if id, ok := n.(*ast.Ident); ok {
-				cnt[id.Name]++
-			}
-			return true
-		})
-	}
-	return cnt
-}
-
-func varCount1(loc, m string, cnt map[string]int) {
-	if m[0] == '<' || m[0] == '[' || m[0] == '{' {
-		return
-	}
-	if token.IsIdentifier(m) {
-		cnt[m]++
-		return
-	}
-	// Split up input.
-	name, expr := splitNameExpr(m)
-	if name != "" {
-		cnt[name]++
-	}
-	if expr[0] != '(' || expr[len(expr)-1] != ')' {
-		log.Fatalf("%s: non-compound expr in varCount1: %q", loc, expr)
-	}
-	s := split(expr[1 : len(expr)-1])
-	for _, arg := range s[1:] {
-		varCount1(loc, arg, cnt)
-	}
-}
-
-// normalizeWhitespace replaces 2+ whitespace sequences with a single space.
-func normalizeWhitespace(x string) string {
-	x = strings.Join(strings.Fields(x), " ")
-	x = strings.Replace(x, "( ", "(", -1)
-	x = strings.Replace(x, " )", ")", -1)
-	x = strings.Replace(x, "[ ", "[", -1)
-	x = strings.Replace(x, " ]", "]", -1)
-	x = strings.Replace(x, ")=>", ") =>", -1)
-	return x
-}
-
-// opIsCommutative reports whether op s is commutative.
-func opIsCommutative(op string, arch arch) bool {
-	for _, x := range genericOps {
-		if op == x.name {
-			if x.commutative {
-				return true
-			}
-			break
-		}
-	}
-	if arch.name != "generic" {
-		for _, x := range arch.ops {
-			if op == x.name {
-				if x.commutative {
-					return true
-				}
-				break
-			}
-		}
-	}
-	return false
-}
-
-func normalizeMatch(m string, arch arch) string {
-	if token.IsIdentifier(m) {
-		return m
-	}
-	op, typ, auxint, aux, args := extract(m)
-	if opIsCommutative(op, arch) {
-		if args[1] < args[0] {
-			args[0], args[1] = args[1], args[0]
-		}
-	}
-	s := new(strings.Builder)
-	fmt.Fprintf(s, "%s <%s> [%s] {%s}", op, typ, auxint, aux)
-	for _, arg := range args {
-		prefix, expr := splitNameExpr(arg)
-		fmt.Fprint(s, " ", prefix, normalizeMatch(expr, arch))
-	}
-	return s.String()
-}
-
-func parseEllipsisRules(rules []Rule, arch arch) (newop string, ok bool) {
-	if len(rules) != 1 {
-		for _, r := range rules {
-			if strings.Contains(r.Rule, "...") {
-				log.Fatalf("%s: found ellipsis in rule, but there are other rules with the same op", r.Loc)
-			}
-		}
-		return "", false
-	}
-	rule := rules[0]
-	match, cond, result := rule.parse()
-	if cond != "" || !isEllipsisValue(match) || !isEllipsisValue(result) {
-		if strings.Contains(rule.Rule, "...") {
-			log.Fatalf("%s: found ellipsis in non-ellipsis rule", rule.Loc)
-		}
-		checkEllipsisRuleCandidate(rule, arch)
-		return "", false
-	}
-	op, oparch, _, _, _, _ := parseValue(result, arch, rule.Loc)
-	return fmt.Sprintf("Op%s%s", oparch, op.name), true
-}
-
-// isEllipsisValue reports whether s is of the form (OpX ...).
-func isEllipsisValue(s string) bool {
-	if len(s) < 2 || s[0] != '(' || s[len(s)-1] != ')' {
-		return false
-	}
-	c := split(s[1 : len(s)-1])
-	if len(c) != 2 || c[1] != "..." {
-		return false
-	}
-	return true
-}
-
-func checkEllipsisRuleCandidate(rule Rule, arch arch) {
-	match, cond, result := rule.parse()
-	if cond != "" {
-		return
-	}
-	op, _, _, auxint, aux, args := parseValue(match, arch, rule.Loc)
-	var auxint2, aux2 string
-	var args2 []string
-	var usingCopy string
-	var eop opData
-	if result[0] != '(' {
-		// Check for (Foo x) => x, which can be converted to (Foo ...) => (Copy ...).
-		args2 = []string{result}
-		usingCopy = " using Copy"
-	} else {
-		eop, _, _, auxint2, aux2, args2 = parseValue(result, arch, rule.Loc)
-	}
-	// Check that all restrictions in match are reproduced exactly in result.
-	if aux != aux2 || auxint != auxint2 || len(args) != len(args2) {
-		return
-	}
-	if strings.Contains(rule.Rule, "=>") && op.aux != eop.aux {
-		return
-	}
-	for i := range args {
-		if args[i] != args2[i] {
-			return
-		}
-	}
-	switch {
-	case opHasAux(op) && aux == "" && aux2 == "":
-		fmt.Printf("%s: rule silently zeros aux, either copy aux or explicitly zero\n", rule.Loc)
-	case opHasAuxInt(op) && auxint == "" && auxint2 == "":
-		fmt.Printf("%s: rule silently zeros auxint, either copy auxint or explicitly zero\n", rule.Loc)
-	default:
-		fmt.Printf("%s: possible ellipsis rule candidate%s: %q\n", rule.Loc, usingCopy, rule.Rule)
-	}
-}
-
-func opByName(arch arch, name string) opData {
-	name = name[2:]
-	for _, x := range genericOps {
-		if name == x.name {
-			return x
-		}
-	}
-	if arch.name != "generic" {
-		name = name[len(arch.name):]
-		for _, x := range arch.ops {
-			if name == x.name {
-				return x
-			}
-		}
-	}
-	log.Fatalf("failed to find op named %s in arch %s", name, arch.name)
-	panic("unreachable")
-}
-
-// auxType returns the Go type that this operation should store in its aux field.
-func (op opData) auxType() string {
-	switch op.aux {
-	case "String":
-		return "string"
-	case "Sym":
-		// Note: a Sym can be an *obj.LSym, a *gc.Node, or nil.
-		return "Sym"
-	case "SymOff":
-		return "Sym"
-	case "Call":
-		return "Call"
-	case "CallOff":
-		return "Call"
-	case "SymValAndOff":
-		return "Sym"
-	case "Typ":
-		return "*types.Type"
-	case "TypSize":
-		return "*types.Type"
-	case "S390XCCMask":
-		return "s390x.CCMask"
-	case "S390XRotateParams":
-		return "s390x.RotateParams"
-	default:
-		return "invalid"
-	}
-}
-
-// auxIntType returns the Go type that this operation should store in its auxInt field.
-func (op opData) auxIntType() string {
-	switch op.aux {
-	case "Bool":
-		return "bool"
-	case "Int8":
-		return "int8"
-	case "Int16":
-		return "int16"
-	case "Int32":
-		return "int32"
-	case "Int64":
-		return "int64"
-	case "Int128":
-		return "int128"
-	case "UInt8":
-		return "uint8"
-	case "Float32":
-		return "float32"
-	case "Float64":
-		return "float64"
-	case "CallOff":
-		return "int32"
-	case "SymOff":
-		return "int32"
-	case "SymValAndOff":
-		return "ValAndOff"
-	case "TypSize":
-		return "int64"
-	case "CCop":
-		return "Op"
-	case "FlagConstant":
-		return "flagConstant"
-	case "ARM64BitField":
-		return "arm64BitField"
-	default:
-		return "invalid"
-	}
-}
-
-// auxType returns the Go type that this block should store in its aux field.
-func (b blockData) auxType() string {
-	switch b.aux {
-	case "Sym":
-		return "Sym"
-	case "S390XCCMask", "S390XCCMaskInt8", "S390XCCMaskUint8":
-		return "s390x.CCMask"
-	case "S390XRotateParams":
-		return "s390x.RotateParams"
-	default:
-		return "invalid"
-	}
-}
-
-// auxIntType returns the Go type that this block should store in its auxInt field.
-func (b blockData) auxIntType() string {
-	switch b.aux {
-	case "S390XCCMaskInt8":
-		return "int8"
-	case "S390XCCMaskUint8":
-		return "uint8"
-	case "Int64":
-		return "int64"
-	default:
-		return "invalid"
-	}
-}
-
-func title(s string) string {
-	if i := strings.Index(s, "."); i >= 0 {
-		switch strings.ToLower(s[:i]) {
-		case "s390x": // keep arch prefix for clarity
-			s = s[:i] + s[i+1:]
-		default:
-			s = s[i+1:]
-		}
-	}
-	return strings.Title(s)
-}
-
-func unTitle(s string) string {
-	if i := strings.Index(s, "."); i >= 0 {
-		switch strings.ToLower(s[:i]) {
-		case "s390x": // keep arch prefix for clarity
-			s = s[:i] + s[i+1:]
-		default:
-			s = s[i+1:]
-		}
-	}
-	return strings.ToLower(s[:1]) + s[1:]
-}
diff --git a/src/cmd/compile/internal/ssa/html.go b/src/cmd/compile/internal/ssa/html.go
index 1e6060a..7e5a097 100644
--- a/src/cmd/compile/internal/ssa/html.go
+++ b/src/cmd/compile/internal/ssa/html.go
@@ -848,7 +848,7 @@
 	if w == nil {
 		return // avoid generating HTML just to discard it
 	}
-	var buf bytes.Buffer
+	var buf strings.Builder
 	fmt.Fprint(&buf, "<div class=\"lines\" style=\"width: 8%\">")
 	filename := ""
 	for _, fl := range all {
@@ -890,7 +890,7 @@
 		return // avoid generating HTML just to discard it
 	}
 	lines := strings.Split(buf.String(), "\n")
-	var out bytes.Buffer
+	var out strings.Builder
 
 	fmt.Fprint(&out, "<div>")
 	for _, l := range lines {
@@ -994,6 +994,9 @@
 	if int(v.ID) < len(r) && r[v.ID] != nil {
 		s += " : " + html.EscapeString(r[v.ID].String())
 	}
+	if reg := v.Block.Func.tempRegs[v.ID]; reg != nil {
+		s += " tmp=" + reg.String()
+	}
 	var names []string
 	for name, values := range v.Block.Func.NamedValues {
 		for _, value := range values {
@@ -1053,7 +1056,7 @@
 }
 
 func (f *Func) HTML(phase string, dot *dotWriter) string {
-	buf := new(bytes.Buffer)
+	buf := new(strings.Builder)
 	if dot != nil {
 		dot.writeFuncSVG(buf, phase, f)
 	}
@@ -1082,7 +1085,7 @@
 	}
 	buf := new(bytes.Buffer)
 	cmd.Stdout = buf
-	bufErr := new(bytes.Buffer)
+	bufErr := new(strings.Builder)
 	cmd.Stderr = bufErr
 	err = cmd.Start()
 	if err != nil {
diff --git a/src/cmd/compile/internal/ssa/layout.go b/src/cmd/compile/internal/ssa/layout.go
index 6abdb0d..e4a8c6f 100644
--- a/src/cmd/compile/internal/ssa/layout.go
+++ b/src/cmd/compile/internal/ssa/layout.go
@@ -20,9 +20,12 @@
 
 func layoutOrder(f *Func) []*Block {
 	order := make([]*Block, 0, f.NumBlocks())
-	scheduled := make([]bool, f.NumBlocks())
-	idToBlock := make([]*Block, f.NumBlocks())
-	indegree := make([]int, f.NumBlocks())
+	scheduled := f.Cache.allocBoolSlice(f.NumBlocks())
+	defer f.Cache.freeBoolSlice(scheduled)
+	idToBlock := f.Cache.allocBlockSlice(f.NumBlocks())
+	defer f.Cache.freeBlockSlice(idToBlock)
+	indegree := f.Cache.allocIntSlice(f.NumBlocks())
+	defer f.Cache.freeIntSlice(indegree)
 	posdegree := f.newSparseSet(f.NumBlocks()) // blocks with positive remaining degree
 	defer f.retSparseSet(posdegree)
 	// blocks with zero remaining degree. Use slice to simulate a LIFO queue to implement
diff --git a/src/cmd/compile/internal/ssa/likelyadjust.go b/src/cmd/compile/internal/ssa/likelyadjust.go
index f462bf2..1d0e53c 100644
--- a/src/cmd/compile/internal/ssa/likelyadjust.go
+++ b/src/cmd/compile/internal/ssa/likelyadjust.go
@@ -117,8 +117,10 @@
 	// in their rank order.  0 is default, more positive
 	// is less likely. It's possible to assign a negative
 	// unlikeliness (though not currently the case).
-	certain := make([]int8, f.NumBlocks()) // In the long run, all outcomes are at least this bad. Mainly for Exit
-	local := make([]int8, f.NumBlocks())   // for our immediate predecessors.
+	certain := f.Cache.allocInt8Slice(f.NumBlocks()) // In the long run, all outcomes are at least this bad. Mainly for Exit
+	defer f.Cache.freeInt8Slice(certain)
+	local := f.Cache.allocInt8Slice(f.NumBlocks()) // for our immediate predecessors.
+	defer f.Cache.freeInt8Slice(local)
 
 	po := f.postorder()
 	nest := f.loopnest()
@@ -277,7 +279,8 @@
 	sdom := f.Sdom()
 	b2l := make([]*loop, f.NumBlocks())
 	loops := make([]*loop, 0)
-	visited := make([]bool, f.NumBlocks())
+	visited := f.Cache.allocBoolSlice(f.NumBlocks())
+	defer f.Cache.freeBoolSlice(visited)
 	sawIrred := false
 
 	if f.pass.debug > 2 {
@@ -369,7 +372,8 @@
 	ln := &loopnest{f: f, b2l: b2l, po: po, sdom: sdom, loops: loops, hasIrreducible: sawIrred}
 
 	// Calculate containsUnavoidableCall for regalloc
-	dominatedByCall := make([]bool, f.NumBlocks())
+	dominatedByCall := f.Cache.allocBoolSlice(f.NumBlocks())
+	defer f.Cache.freeBoolSlice(dominatedByCall)
 	for _, b := range po {
 		if checkContainsCall(b) {
 			dominatedByCall[b.ID] = true
diff --git a/src/cmd/compile/internal/ssa/loopbce.go b/src/cmd/compile/internal/ssa/loopbce.go
index 22fb511..d92566f 100644
--- a/src/cmd/compile/internal/ssa/loopbce.go
+++ b/src/cmd/compile/internal/ssa/loopbce.go
@@ -200,8 +200,15 @@
 						}
 						v = addU(init.AuxInt, diff(v, init.AuxInt)/uint64(step)*uint64(step))
 					}
-					// It is ok if we can't overflow when incrementing from the largest value.
-					return !addWillOverflow(v, step)
+					if addWillOverflow(v, step) {
+						return false
+					}
+					if inclusive && v != limit.AuxInt || !inclusive && v+1 != limit.AuxInt {
+						// We know a better limit than the programmer did. Use our limit instead.
+						limit = f.ConstInt64(f.Config.Types.Int64, v)
+						inclusive = true
+					}
+					return true
 				}
 				if step == 1 && !inclusive {
 					// Can't overflow because maxint is never a possible value.
@@ -238,8 +245,15 @@
 						}
 						v = subU(init.AuxInt, diff(init.AuxInt, v)/uint64(-step)*uint64(-step))
 					}
-					// It is ok if we can't underflow when decrementing from the smallest value.
-					return !subWillUnderflow(v, -step)
+					if subWillUnderflow(v, -step) {
+						return false
+					}
+					if inclusive && v != limit.AuxInt || !inclusive && v-1 != limit.AuxInt {
+						// We know a better limit than the programmer did. Use our limit instead.
+						limit = f.ConstInt64(f.Config.Types.Int64, v)
+						inclusive = true
+					}
+					return true
 				}
 				if step == -1 && !inclusive {
 					// Can't underflow because minint is never a possible value.
diff --git a/src/cmd/compile/internal/ssa/loopreschedchecks.go b/src/cmd/compile/internal/ssa/loopreschedchecks.go
index 1326fa5..7c56523 100644
--- a/src/cmd/compile/internal/ssa/loopreschedchecks.go
+++ b/src/cmd/compile/internal/ssa/loopreschedchecks.go
@@ -94,7 +94,8 @@
 		lastMems[f.Entry.ID] = f.Entry.NewValue0(f.Entry.Pos, OpInitMem, types.TypeMem)
 	}
 
-	memDefsAtBlockEnds := make([]*Value, f.NumBlocks()) // For each block, the mem def seen at its bottom. Could be from earlier block.
+	memDefsAtBlockEnds := f.Cache.allocValueSlice(f.NumBlocks()) // For each block, the mem def seen at its bottom. Could be from earlier block.
+	defer f.Cache.freeValueSlice(memDefsAtBlockEnds)
 
 	// Propagate last mem definitions forward through successor blocks.
 	for i := len(po) - 1; i >= 0; i-- {
@@ -400,11 +401,12 @@
 	}
 }
 
-// findLastMems maps block ids to last memory-output op in a block, if any
+// findLastMems maps block ids to last memory-output op in a block, if any.
 func findLastMems(f *Func) []*Value {
 
 	var stores []*Value
-	lastMems := make([]*Value, f.NumBlocks())
+	lastMems := f.Cache.allocValueSlice(f.NumBlocks())
+	defer f.Cache.freeValueSlice(lastMems)
 	storeUse := f.newSparseSet(f.NumValues())
 	defer f.retSparseSet(storeUse)
 	for _, b := range f.Blocks {
diff --git a/src/cmd/compile/internal/ssa/looprotate.go b/src/cmd/compile/internal/ssa/looprotate.go
index 2eefda1..844a8f7 100644
--- a/src/cmd/compile/internal/ssa/looprotate.go
+++ b/src/cmd/compile/internal/ssa/looprotate.go
@@ -30,7 +30,8 @@
 		return
 	}
 
-	idToIdx := make([]int, f.NumBlocks())
+	idToIdx := f.Cache.allocIntSlice(f.NumBlocks())
+	defer f.Cache.freeIntSlice(idToIdx)
 	for i, b := range f.Blocks {
 		idToIdx[b.ID] = i
 	}
@@ -92,20 +93,21 @@
 	// Some blocks that are not part of a loop may be placed
 	// between loop blocks. In order to avoid these blocks from
 	// being overwritten, use a temporary slice.
-	newOrder := make([]*Block, 0, f.NumBlocks())
-	for _, b := range f.Blocks {
+	oldOrder := f.Cache.allocBlockSlice(len(f.Blocks))
+	defer f.Cache.freeBlockSlice(oldOrder)
+	copy(oldOrder, f.Blocks)
+	for _, b := range oldOrder {
 		if _, ok := move[b.ID]; ok {
 			continue
 		}
-		newOrder = append(newOrder, b)
+		f.Blocks[j] = b
 		j++
 		for _, a := range after[b.ID] {
-			newOrder = append(newOrder, a)
+			f.Blocks[j] = a
 			j++
 		}
 	}
-	if j != len(f.Blocks) {
+	if j != len(oldOrder) {
 		f.Fatalf("bad reordering in looprotate")
 	}
-	f.Blocks = newOrder
 }
diff --git a/src/cmd/compile/internal/ssa/lower.go b/src/cmd/compile/internal/ssa/lower.go
index 5760c35..0b79d77 100644
--- a/src/cmd/compile/internal/ssa/lower.go
+++ b/src/cmd/compile/internal/ssa/lower.go
@@ -4,12 +4,20 @@
 
 package ssa
 
-// convert to machine-dependent ops
+// convert to machine-dependent ops.
 func lower(f *Func) {
 	// repeat rewrites until we find no more rewrites
 	applyRewrite(f, f.Config.lowerBlock, f.Config.lowerValue, removeDeadValues)
 }
 
+// lateLower applies those rules that need to be run after the general lower rules.
+func lateLower(f *Func) {
+	// repeat rewrites until we find no more rewrites
+	if f.Config.lateLowerValue != nil {
+		applyRewrite(f, f.Config.lateLowerBlock, f.Config.lateLowerValue, removeDeadValues)
+	}
+}
+
 // checkLower checks for unlowered opcodes and fails if we find one.
 func checkLower(f *Func) {
 	// Needs to be a separate phase because it must run after both
@@ -21,7 +29,7 @@
 				continue // lowered
 			}
 			switch v.Op {
-			case OpSP, OpSB, OpInitMem, OpArg, OpArgIntReg, OpArgFloatReg, OpPhi, OpVarDef, OpVarKill, OpVarLive, OpKeepAlive, OpSelect0, OpSelect1, OpSelectN, OpConvert, OpInlMark:
+			case OpSP, OpSB, OpInitMem, OpArg, OpArgIntReg, OpArgFloatReg, OpPhi, OpVarDef, OpVarLive, OpKeepAlive, OpSelect0, OpSelect1, OpSelectN, OpConvert, OpInlMark:
 				continue // ok not to lower
 			case OpMakeResult:
 				if b.Controls[0] == v {
diff --git a/src/cmd/compile/internal/ssa/magic.go b/src/cmd/compile/internal/ssa/magic.go
index e903d92..df4b568 100644
--- a/src/cmd/compile/internal/ssa/magic.go
+++ b/src/cmd/compile/internal/ssa/magic.go
@@ -181,7 +181,7 @@
 	m uint64 // ⎡2^(n+s)/c⎤
 }
 
-// magic computes the constants needed to strength reduce signed n-bit divides by the constant c.
+// smagic computes the constants needed to strength reduce signed n-bit divides by the constant c.
 // Must have c>0.
 // The return values satisfy for all -2^(n-1) <= x < 2^(n-1)
 //
diff --git a/src/cmd/compile/internal/ssa/nilcheck.go b/src/cmd/compile/internal/ssa/nilcheck.go
index 14f511a..4f797a4 100644
--- a/src/cmd/compile/internal/ssa/nilcheck.go
+++ b/src/cmd/compile/internal/ssa/nilcheck.go
@@ -41,7 +41,8 @@
 	// map from value ID to bool indicating if value is known to be non-nil
 	// in the current dominator path being walked. This slice is updated by
 	// walkStates to maintain the known non-nil values.
-	nonNilValues := make([]bool, f.NumValues())
+	nonNilValues := f.Cache.allocBoolSlice(f.NumValues())
+	defer f.Cache.freeBoolSlice(nonNilValues)
 
 	// make an initial pass identifying any non-nil values
 	for _, b := range f.Blocks {
@@ -86,7 +87,8 @@
 	// allocate auxiliary date structures for computing store order
 	sset := f.newSparseSet(f.NumValues())
 	defer f.retSparseSet(sset)
-	storeNumber := make([]int32, f.NumValues())
+	storeNumber := f.Cache.allocInt32Slice(f.NumValues())
+	defer f.Cache.freeInt32Slice(storeNumber)
 
 	// perform a depth first walk of the dominee tree
 	for len(work) > 0 {
@@ -236,7 +238,7 @@
 				continue
 			}
 			if v.Type.IsMemory() || v.Type.IsTuple() && v.Type.FieldType(1).IsMemory() {
-				if v.Op == OpVarKill || v.Op == OpVarLive || (v.Op == OpVarDef && !v.Aux.(*ir.Name).Type().HasPointers()) {
+				if v.Op == OpVarLive || (v.Op == OpVarDef && !v.Aux.(*ir.Name).Type().HasPointers()) {
 					// These ops don't really change memory.
 					continue
 					// Note: OpVarDef requires that the defined variable not have pointers.
@@ -308,7 +310,7 @@
 				}
 				// This instruction is guaranteed to fault if ptr is nil.
 				// Any previous nil check op is unnecessary.
-				unnecessary.set(ptr.ID, int32(i), src.NoXPos)
+				unnecessary.set(ptr.ID, int32(i))
 			}
 		}
 		// Remove values we've clobbered with OpUnknown.
diff --git a/src/cmd/compile/internal/ssa/numberlines.go b/src/cmd/compile/internal/ssa/numberlines.go
index 9d6aeca..4cbc491 100644
--- a/src/cmd/compile/internal/ssa/numberlines.go
+++ b/src/cmd/compile/internal/ssa/numberlines.go
@@ -62,7 +62,7 @@
 // statement boundary.
 func notStmtBoundary(op Op) bool {
 	switch op {
-	case OpCopy, OpPhi, OpVarKill, OpVarDef, OpVarLive, OpUnknown, OpFwdRef, OpArg, OpArgIntReg, OpArgFloatReg:
+	case OpCopy, OpPhi, OpVarDef, OpVarLive, OpUnknown, OpFwdRef, OpArg, OpArgIntReg, OpArgFloatReg:
 		return true
 	}
 	return false
diff --git a/src/cmd/compile/internal/ssa/op.go b/src/cmd/compile/internal/ssa/op.go
index a3e8dcd..9434c0e 100644
--- a/src/cmd/compile/internal/ssa/op.go
+++ b/src/cmd/compile/internal/ssa/op.go
@@ -16,7 +16,7 @@
 // An Op encodes the specific operation that a Value performs.
 // Opcodes' semantics can be modified by the type and aux fields of the Value.
 // For instance, OpAdd can be 32 or 64 bit, signed or unsigned, float or complex, depending on Value.Type.
-// Semantics of each op are described in the opcode files in gen/*Ops.go.
+// Semantics of each op are described in the opcode files in _gen/*Ops.go.
 // There is one file for generic (architecture-independent) ops and one file
 // for each architecture.
 type Op int32
@@ -33,6 +33,7 @@
 	resultInArg0      bool      // (first, if a tuple) output of v and v.Args[0] must be allocated to the same register
 	resultNotInArgs   bool      // outputs must not be allocated to the same registers as inputs
 	clobberFlags      bool      // this op clobbers flags register
+	needIntTemp       bool      // need a temporary free integer register
 	call              bool      // is a function call
 	tailCall          bool      // is a tail call
 	nilCheck          bool      // this op is a nil check on arg0
@@ -268,7 +269,7 @@
 	return a.TypeOfArg(which).Size()
 }
 
-// NResults returns the number of results
+// NResults returns the number of results.
 func (a *AuxCall) NResults() int64 {
 	return int64(len(a.abiInfo.OutParams()))
 }
@@ -334,7 +335,7 @@
 
 func (*AuxCall) CanBeAnSSAAux() {}
 
-// OwnAuxCall returns a function's own AuxCall
+// OwnAuxCall returns a function's own AuxCall.
 func OwnAuxCall(fn *obj.LSym, paramResultInfo *abi.ABIParamResultInfo) *AuxCall {
 	// TODO if this remains identical to ClosureAuxCall above after new ABI is done, should deduplicate.
 	var reg *regInfo
@@ -478,7 +479,7 @@
 	BoundsKindCount
 )
 
-// boundsAPI determines which register arguments a bounds check call should use. For an [a:b:c] slice, we do:
+// boundsABI determines which register arguments a bounds check call should use. For an [a:b:c] slice, we do:
 //
 //	CMPQ c, cap
 //	JA   fail1
@@ -525,7 +526,7 @@
 	}
 }
 
-// arm64BitFileld is the GO type of ARM64BitField auxInt.
+// arm64BitField is the GO type of ARM64BitField auxInt.
 // if x is an ARM64BitField, then width=x&0xff, lsb=(x>>8)&0xff, and
 // width+lsb<64 for 64-bit variant, width+lsb<32 for 32-bit variant.
 // the meaning of width and lsb are instruction-dependent.
diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go
index 12fed42..407ecbb 100644
--- a/src/cmd/compile/internal/ssa/opGen.go
+++ b/src/cmd/compile/internal/ssa/opGen.go
@@ -1,4 +1,4 @@
-// Code generated from gen/*Ops.go; DO NOT EDIT.
+// Code generated from _gen/*Ops.go; DO NOT EDIT.
 
 package ssa
 
@@ -434,6 +434,9 @@
 	Op386SARLconst
 	Op386SARWconst
 	Op386SARBconst
+	Op386ROLL
+	Op386ROLW
+	Op386ROLB
 	Op386ROLLconst
 	Op386ROLWconst
 	Op386ROLBconst
@@ -1428,7 +1431,6 @@
 	OpARM64BIC
 	OpARM64EON
 	OpARM64ORN
-	OpARM64LoweredMuluhilo
 	OpARM64MVN
 	OpARM64NEG
 	OpARM64NEGSflags
@@ -1554,6 +1556,7 @@
 	OpARM64MOVWload
 	OpARM64MOVWUload
 	OpARM64MOVDload
+	OpARM64LDP
 	OpARM64FMOVSload
 	OpARM64FMOVDload
 	OpARM64MOVDloadidx
@@ -1737,12 +1740,18 @@
 	OpLOONG64NEGD
 	OpLOONG64SQRTD
 	OpLOONG64SQRTF
+	OpLOONG64MASKEQZ
+	OpLOONG64MASKNEZ
 	OpLOONG64SLLV
 	OpLOONG64SLLVconst
 	OpLOONG64SRLV
 	OpLOONG64SRLVconst
 	OpLOONG64SRAV
 	OpLOONG64SRAVconst
+	OpLOONG64ROTR
+	OpLOONG64ROTRV
+	OpLOONG64ROTRconst
+	OpLOONG64ROTRVconst
 	OpLOONG64SGT
 	OpLOONG64SGTconst
 	OpLOONG64SGTU
@@ -2080,7 +2089,6 @@
 	OpPPC64MULHW
 	OpPPC64MULHDU
 	OpPPC64MULHWU
-	OpPPC64LoweredMuluhilo
 	OpPPC64FMUL
 	OpPPC64FMULS
 	OpPPC64FMADD
@@ -2165,7 +2173,6 @@
 	OpPPC64FCPSGN
 	OpPPC64ORconst
 	OpPPC64XORconst
-	OpPPC64ANDconst
 	OpPPC64ANDCCconst
 	OpPPC64MOVBreg
 	OpPPC64MOVBZreg
@@ -2233,6 +2240,7 @@
 	OpPPC64CMPWUconst
 	OpPPC64ISEL
 	OpPPC64ISELB
+	OpPPC64ISELZ
 	OpPPC64Equal
 	OpPPC64NotEqual
 	OpPPC64LessThan
@@ -2964,10 +2972,10 @@
 	OpPopCount16
 	OpPopCount32
 	OpPopCount64
-	OpRotateLeft8
-	OpRotateLeft16
-	OpRotateLeft32
 	OpRotateLeft64
+	OpRotateLeft32
+	OpRotateLeft16
+	OpRotateLeft8
 	OpSqrt
 	OpSqrt32
 	OpFloor
@@ -3089,7 +3097,6 @@
 	OpFwdRef
 	OpUnknown
 	OpVarDef
-	OpVarKill
 	OpVarLive
 	OpKeepAlive
 	OpInlMark
@@ -4639,6 +4646,54 @@
 		},
 	},
 	{
+		name:         "ROLL",
+		argLen:       2,
+		resultInArg0: true,
+		clobberFlags: true,
+		asm:          x86.AROLL,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{1, 2},   // CX
+				{0, 239}, // AX CX DX BX BP SI DI
+			},
+			outputs: []outputInfo{
+				{0, 239}, // AX CX DX BX BP SI DI
+			},
+		},
+	},
+	{
+		name:         "ROLW",
+		argLen:       2,
+		resultInArg0: true,
+		clobberFlags: true,
+		asm:          x86.AROLW,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{1, 2},   // CX
+				{0, 239}, // AX CX DX BX BP SI DI
+			},
+			outputs: []outputInfo{
+				{0, 239}, // AX CX DX BX BP SI DI
+			},
+		},
+	},
+	{
+		name:         "ROLB",
+		argLen:       2,
+		resultInArg0: true,
+		clobberFlags: true,
+		asm:          x86.AROLB,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{1, 2},   // CX
+				{0, 239}, // AX CX DX BX BP SI DI
+			},
+			outputs: []outputInfo{
+				{0, 239}, // AX CX DX BX BP SI DI
+			},
+		},
+	},
+	{
 		name:         "ROLLconst",
 		auxType:      auxInt32,
 		argLen:       1,
@@ -11510,15 +11565,15 @@
 		name:         "CMOVQEQF",
 		argLen:       3,
 		resultInArg0: true,
+		needIntTemp:  true,
 		asm:          x86.ACMOVQNE,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 49134}, // CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
-			clobbers: 1, // AX
 			outputs: []outputInfo{
-				{0, 49134}, // CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11571,15 +11626,15 @@
 		name:         "CMOVLEQF",
 		argLen:       3,
 		resultInArg0: true,
+		needIntTemp:  true,
 		asm:          x86.ACMOVLNE,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 49134}, // CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
-			clobbers: 1, // AX
 			outputs: []outputInfo{
-				{0, 49134}, // CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -11632,15 +11687,15 @@
 		name:         "CMOVWEQF",
 		argLen:       3,
 		resultInArg0: true,
+		needIntTemp:  true,
 		asm:          x86.ACMOVWNE,
 		reg: regInfo{
 			inputs: []inputInfo{
-				{0, 49134}, // CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 				{1, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
-			clobbers: 1, // AX
 			outputs: []outputInfo{
-				{0, 49134}, // CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12065,11 +12120,11 @@
 		name:         "SETEQF",
 		argLen:       1,
 		clobberFlags: true,
+		needIntTemp:  true,
 		asm:          x86.ASETEQ,
 		reg: regInfo{
-			clobbers: 1, // AX
 			outputs: []outputInfo{
-				{0, 49134}, // CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -12077,11 +12132,11 @@
 		name:         "SETNEF",
 		argLen:       1,
 		clobberFlags: true,
+		needIntTemp:  true,
 		asm:          x86.ASETNE,
 		reg: regInfo{
-			clobbers: 1, // AX
 			outputs: []outputInfo{
-				{0, 49134}, // CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
+				{0, 49135}, // AX CX DX BX BP SI DI R8 R9 R10 R11 R12 R13 R15
 			},
 		},
 	},
@@ -19078,21 +19133,6 @@
 		},
 	},
 	{
-		name:            "LoweredMuluhilo",
-		argLen:          2,
-		resultNotInArgs: true,
-		reg: regInfo{
-			inputs: []inputInfo{
-				{0, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
-				{1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
-			},
-			outputs: []outputInfo{
-				{0, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30
-				{1, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30
-			},
-		},
-	},
-	{
 		name:   "MVN",
 		argLen: 1,
 		asm:    arm64.AMVN,
@@ -20814,6 +20854,23 @@
 		},
 	},
 	{
+		name:           "LDP",
+		auxType:        auxSymOff,
+		argLen:         2,
+		faultOnNilArg0: true,
+		symEffect:      SymRead,
+		asm:            arm64.ALDP,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 9223372038733561855}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30 SP SB
+			},
+			outputs: []outputInfo{
+				{0, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
+				{1, 805044223}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 g R30
+			},
+		},
+	},
+	{
 		name:           "FMOVSload",
 		auxType:        auxSymOff,
 		argLen:         2,
@@ -22254,9 +22311,9 @@
 			inputs: []inputInfo{
 				{0, 131072},    // R17
 				{1, 65536},     // R16
-				{2, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30
+				{2, 637272063}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R26 R30
 			},
-			clobbers: 196608, // R16 R17
+			clobbers: 33751040, // R16 R17 R25
 		},
 	},
 	{
@@ -22856,60 +22913,64 @@
 		},
 	},
 	{
-		name:        "MULV",
-		argLen:      2,
-		commutative: true,
+		name:            "MULV",
+		argLen:          2,
+		commutative:     true,
+		resultNotInArgs: true,
 		reg: regInfo{
 			inputs: []inputInfo{
 				{0, 1072496632}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31
 				{1, 1072496632}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31
 			},
 			outputs: []outputInfo{
-				{0, 65536},  // R17
-				{1, 131072}, // R18
+				{0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31
+				{1, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31
 			},
 		},
 	},
 	{
-		name:        "MULVU",
-		argLen:      2,
-		commutative: true,
+		name:            "MULVU",
+		argLen:          2,
+		commutative:     true,
+		resultNotInArgs: true,
 		reg: regInfo{
 			inputs: []inputInfo{
 				{0, 1072496632}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31
 				{1, 1072496632}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31
 			},
 			outputs: []outputInfo{
-				{0, 65536},  // R17
-				{1, 131072}, // R18
+				{0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31
+				{1, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31
 			},
 		},
 	},
 	{
-		name:   "DIVV",
-		argLen: 2,
+		name:            "DIVV",
+		argLen:          2,
+		resultNotInArgs: true,
 		reg: regInfo{
 			inputs: []inputInfo{
 				{0, 1072496632}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31
 				{1, 1072496632}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31
 			},
 			outputs: []outputInfo{
-				{0, 65536},  // R17
-				{1, 131072}, // R18
+				{0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31
+				{1, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31
 			},
 		},
 	},
 	{
-		name:   "DIVVU",
-		argLen: 2,
+		name:            "DIVVU",
+		argLen:          2,
+		resultNotInArgs: true,
 		reg: regInfo{
 			inputs: []inputInfo{
 				{0, 1072496632}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31
 				{1, 1072496632}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31
 			},
 			outputs: []outputInfo{
-				{0, 65536},  // R17
-				{1, 131072}, // R18
+				{0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31
+				{1, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31
 			},
 		},
 	},
@@ -23210,6 +23271,34 @@
 		},
 	},
 	{
+		name:   "MASKEQZ",
+		argLen: 2,
+		asm:    loong64.AMASKEQZ,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31
+				{1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31
+			},
+			outputs: []outputInfo{
+				{0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31
+			},
+		},
+	},
+	{
+		name:   "MASKNEZ",
+		argLen: 2,
+		asm:    loong64.AMASKNEZ,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31
+				{1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31
+			},
+			outputs: []outputInfo{
+				{0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31
+			},
+		},
+	},
+	{
 		name:   "SLLV",
 		argLen: 2,
 		asm:    loong64.ASLLV,
@@ -23294,6 +23383,62 @@
 		},
 	},
 	{
+		name:   "ROTR",
+		argLen: 2,
+		asm:    loong64.AROTR,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31
+				{1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31
+			},
+			outputs: []outputInfo{
+				{0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31
+			},
+		},
+	},
+	{
+		name:   "ROTRV",
+		argLen: 2,
+		asm:    loong64.AROTRV,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31
+				{1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31
+			},
+			outputs: []outputInfo{
+				{0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31
+			},
+		},
+	},
+	{
+		name:    "ROTRconst",
+		auxType: auxInt64,
+		argLen:  1,
+		asm:     loong64.AROTR,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31
+			},
+			outputs: []outputInfo{
+				{0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31
+			},
+		},
+	},
+	{
+		name:    "ROTRVconst",
+		auxType: auxInt64,
+		argLen:  1,
+		asm:     loong64.AROTRV,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31
+			},
+			outputs: []outputInfo{
+				{0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31
+			},
+		},
+	},
+	{
 		name:   "SGT",
 		argLen: 2,
 		asm:    loong64.ASGT,
@@ -23997,6 +24142,7 @@
 		argLen:       1,
 		clobberFlags: true,
 		call:         true,
+		tailCall:     true,
 		reg: regInfo{
 			clobbers: 4611686018426339320, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26 F27 F28 F29 F30 F31
 		},
@@ -27834,21 +27980,6 @@
 		},
 	},
 	{
-		name:            "LoweredMuluhilo",
-		argLen:          2,
-		resultNotInArgs: true,
-		reg: regInfo{
-			inputs: []inputInfo{
-				{0, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
-				{1, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
-			},
-			outputs: []outputInfo{
-				{0, 1073733624}, // R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
-				{1, 1073733624}, // R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
-			},
-		},
-	},
-	{
 		name:        "FMUL",
 		argLen:      2,
 		commutative: true,
@@ -28747,15 +28878,19 @@
 		},
 	},
 	{
-		name:        "ANDCC",
-		argLen:      2,
-		commutative: true,
-		asm:         ppc64.AANDCC,
+		name:         "ANDCC",
+		argLen:       2,
+		commutative:  true,
+		clobberFlags: true,
+		asm:          ppc64.AANDCC,
 		reg: regInfo{
 			inputs: []inputInfo{
 				{0, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
 				{1, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
 			},
+			outputs: []outputInfo{
+				{0, 1073733624}, // R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
+			},
 		},
 	},
 	{
@@ -28788,15 +28923,19 @@
 		},
 	},
 	{
-		name:        "ORCC",
-		argLen:      2,
-		commutative: true,
-		asm:         ppc64.AORCC,
+		name:         "ORCC",
+		argLen:       2,
+		commutative:  true,
+		clobberFlags: true,
+		asm:          ppc64.AORCC,
 		reg: regInfo{
 			inputs: []inputInfo{
 				{0, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
 				{1, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
 			},
+			outputs: []outputInfo{
+				{0, 1073733624}, // R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
+			},
 		},
 	},
 	{
@@ -28830,15 +28969,19 @@
 		},
 	},
 	{
-		name:        "XORCC",
-		argLen:      2,
-		commutative: true,
-		asm:         ppc64.AXORCC,
+		name:         "XORCC",
+		argLen:       2,
+		commutative:  true,
+		clobberFlags: true,
+		asm:          ppc64.AXORCC,
 		reg: regInfo{
 			inputs: []inputInfo{
 				{0, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
 				{1, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
 			},
+			outputs: []outputInfo{
+				{0, 1073733624}, // R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
+			},
 		},
 	},
 	{
@@ -29029,7 +29172,7 @@
 		},
 	},
 	{
-		name:         "ANDconst",
+		name:         "ANDCCconst",
 		auxType:      auxInt64,
 		argLen:       1,
 		clobberFlags: true,
@@ -29044,17 +29187,6 @@
 		},
 	},
 	{
-		name:    "ANDCCconst",
-		auxType: auxInt64,
-		argLen:  1,
-		asm:     ppc64.AANDCC,
-		reg: regInfo{
-			inputs: []inputInfo{
-				{0, 1073733630}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
-			},
-		},
-	},
-	{
 		name:   "MOVBreg",
 		argLen: 1,
 		asm:    ppc64.AMOVB,
@@ -29941,6 +30073,20 @@
 		},
 	},
 	{
+		name:    "ISELZ",
+		auxType: auxInt32,
+		argLen:  2,
+		asm:     ppc64.AISEL,
+		reg: regInfo{
+			inputs: []inputInfo{
+				{0, 1073733624}, // R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
+			},
+			outputs: []outputInfo{
+				{0, 1073733624}, // R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
+			},
+		},
+	},
+	{
 		name:   "Equal",
 		argLen: 1,
 		reg: regInfo{
@@ -38468,12 +38614,7 @@
 		generic: true,
 	},
 	{
-		name:    "RotateLeft8",
-		argLen:  2,
-		generic: true,
-	},
-	{
-		name:    "RotateLeft16",
+		name:    "RotateLeft64",
 		argLen:  2,
 		generic: true,
 	},
@@ -38483,7 +38624,12 @@
 		generic: true,
 	},
 	{
-		name:    "RotateLeft64",
+		name:    "RotateLeft16",
+		argLen:  2,
+		generic: true,
+	},
+	{
+		name:    "RotateLeft8",
 		argLen:  2,
 		generic: true,
 	},
@@ -39157,13 +39303,6 @@
 		generic:   true,
 	},
 	{
-		name:      "VarKill",
-		auxType:   auxSym,
-		argLen:    1,
-		symEffect: SymNone,
-		generic:   true,
-	},
-	{
 		name:      "VarLive",
 		auxType:   auxSym,
 		argLen:    1,
diff --git a/src/cmd/compile/internal/ssa/opt.go b/src/cmd/compile/internal/ssa/opt.go
index 128e614..0f15c3d 100644
--- a/src/cmd/compile/internal/ssa/opt.go
+++ b/src/cmd/compile/internal/ssa/opt.go
@@ -4,7 +4,7 @@
 
 package ssa
 
-// machine-independent optimization
+// machine-independent optimization.
 func opt(f *Func) {
 	applyRewrite(f, rewriteBlockgeneric, rewriteValuegeneric, removeDeadValues)
 }
diff --git a/src/cmd/compile/internal/ssa/print.go b/src/cmd/compile/internal/ssa/print.go
index aea9ce9..0d3b5d9 100644
--- a/src/cmd/compile/internal/ssa/print.go
+++ b/src/cmd/compile/internal/ssa/print.go
@@ -5,9 +5,9 @@
 package ssa
 
 import (
-	"bytes"
 	"fmt"
 	"io"
+	"strings"
 
 	"cmd/internal/notsha256"
 	"cmd/internal/src"
@@ -25,7 +25,7 @@
 }
 
 func (f *Func) String() string {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	p := stringFuncPrinter{w: &buf, printDead: true}
 	fprintFunc(p, f)
 	return buf.String()
@@ -124,7 +124,7 @@
 
 func fprintFunc(p funcPrinter, f *Func) {
 	reachable, live := findlive(f)
-	defer f.retDeadcodeLive(live)
+	defer f.Cache.freeBoolSlice(live)
 	p.header(f)
 	printed := make([]bool, f.NumValues())
 	for _, b := range f.Blocks {
diff --git a/src/cmd/compile/internal/ssa/prove.go b/src/cmd/compile/internal/ssa/prove.go
index a6cd687..9ecd335 100644
--- a/src/cmd/compile/internal/ssa/prove.go
+++ b/src/cmd/compile/internal/ssa/prove.go
@@ -463,15 +463,23 @@
 			if parent.Func.pass.debug > 1 {
 				parent.Func.Warnl(parent.Pos, "x+d %s w; x:%v %v delta:%v w:%v d:%v", r, x, parent.String(), delta, w.AuxInt, d)
 			}
+			underflow := true
+			if l, has := ft.limits[x.ID]; has && delta < 0 {
+				if (x.Type.Size() == 8 && l.min >= math.MinInt64-delta) ||
+					(x.Type.Size() == 4 && l.min >= math.MinInt32-delta) {
+					underflow = false
+				}
+			}
+			if delta < 0 && !underflow {
+				// If delta < 0 and x+delta cannot underflow then x > x+delta (that is, x > v)
+				ft.update(parent, x, v, signed, gt)
+			}
 			if !w.isGenericIntConst() {
 				// If we know that x+delta > w but w is not constant, we can derive:
-				//    if delta < 0 and x > MinInt - delta, then x > w (because x+delta cannot underflow)
+				//    if delta < 0 and x+delta cannot underflow, then x > w
 				// This is useful for loops with bounds "len(slice)-K" (delta = -K)
-				if l, has := ft.limits[x.ID]; has && delta < 0 {
-					if (x.Type.Size() == 8 && l.min >= math.MinInt64-delta) ||
-						(x.Type.Size() == 4 && l.min >= math.MinInt32-delta) {
-						ft.update(parent, x, w, signed, r)
-					}
+				if delta < 0 && !underflow {
+					ft.update(parent, x, w, signed, r)
 				}
 			} else {
 				// With w,delta constants, we want to derive: x+delta > w  ⇒  x > w-delta
@@ -508,6 +516,20 @@
 					vmin = parent.NewValue0I(parent.Pos, OpConst32, parent.Func.Config.Types.Int32, min)
 					vmax = parent.NewValue0I(parent.Pos, OpConst32, parent.Func.Config.Types.Int32, max)
 
+				case 2:
+					min = int64(int16(w.AuxInt) - int16(delta))
+					max = int64(int16(^uint16(0)>>1) - int16(delta))
+
+					vmin = parent.NewValue0I(parent.Pos, OpConst16, parent.Func.Config.Types.Int16, min)
+					vmax = parent.NewValue0I(parent.Pos, OpConst16, parent.Func.Config.Types.Int16, max)
+
+				case 1:
+					min = int64(int8(w.AuxInt) - int8(delta))
+					max = int64(int8(^uint8(0)>>1) - int8(delta))
+
+					vmin = parent.NewValue0I(parent.Pos, OpConst8, parent.Func.Config.Types.Int8, min)
+					vmax = parent.NewValue0I(parent.Pos, OpConst8, parent.Func.Config.Types.Int8, max)
+
 				default:
 					panic("unimplemented")
 				}
@@ -834,10 +856,55 @@
 			case OpAnd64, OpAnd32, OpAnd16, OpAnd8:
 				ft.update(b, v, v.Args[1], unsigned, lt|eq)
 				ft.update(b, v, v.Args[0], unsigned, lt|eq)
+			case OpPhi:
+				// Determine the min and max value of OpPhi composed entirely of integer constants.
+				//
+				// For example, for an OpPhi:
+				//
+				// v1 = OpConst64 [13]
+				// v2 = OpConst64 [7]
+				// v3 = OpConst64 [42]
+				//
+				// v4 = OpPhi(v1, v2, v3)
+				//
+				// We can prove:
+				//
+				// v4 >= 7 && v4 <= 42
+				//
+				// TODO(jake-ciolek): Handle nested constant OpPhi's
+				sameConstOp := true
+				min := 0
+				max := 0
+
+				if !v.Args[min].isGenericIntConst() {
+					break
+				}
+
+				for k := range v.Args {
+					if v.Args[k].Op != v.Args[min].Op {
+						sameConstOp = false
+						break
+					}
+					if v.Args[k].AuxInt < v.Args[min].AuxInt {
+						min = k
+					}
+					if v.Args[k].AuxInt > v.Args[max].AuxInt {
+						max = k
+					}
+				}
+
+				if sameConstOp {
+					ft.update(b, v, v.Args[min], signed, gt|eq)
+					ft.update(b, v, v.Args[max], signed, lt|eq)
+				}
+				// One might be tempted to create a v >= ft.zero relation for
+				// all OpPhi's composed of only provably-positive values
+				// but that bloats up the facts table for a very neglible gain.
+				// In Go itself, very few functions get improved (< 5) at a cost of 5-7% total increase
+				// of compile time.
 			}
 		}
 	}
-
 	// Find induction variables. Currently, findIndVars
 	// is limited to one induction variable per block.
 	var indVars map[*Block]indVar
@@ -1099,8 +1166,7 @@
 // addLocalInductiveFacts adds inductive facts when visiting b, where
 // b is a join point in a loop. In contrast with findIndVar, this
 // depends on facts established for b, which is why it happens when
-// visiting b. addLocalInductiveFacts specifically targets the pattern
-// created by OFORUNTIL, which isn't detected by findIndVar.
+// visiting b.
 //
 // TODO: It would be nice to combine this with findIndVar.
 func addLocalInductiveFacts(ft *factsTable, b *Block) {
@@ -1510,16 +1576,20 @@
 	switch v.Op {
 	case OpAdd32, OpSub32:
 		cop = OpConst32
+	case OpAdd16, OpSub16:
+		cop = OpConst16
+	case OpAdd8, OpSub8:
+		cop = OpConst8
 	}
 	switch v.Op {
-	case OpAdd64, OpAdd32:
+	case OpAdd64, OpAdd32, OpAdd16, OpAdd8:
 		if v.Args[0].Op == cop {
 			return v.Args[1], v.Args[0].AuxInt
 		}
 		if v.Args[1].Op == cop {
 			return v.Args[0], v.Args[1].AuxInt
 		}
-	case OpSub64, OpSub32:
+	case OpSub64, OpSub32, OpSub16, OpSub8:
 		if v.Args[1].Op == cop {
 			aux := v.Args[1].AuxInt
 			if aux != -aux { // Overflow; too bad
@@ -1531,7 +1601,7 @@
 }
 
 // isCleanExt reports whether v is the result of a value-preserving
-// sign or zero extension
+// sign or zero extension.
 func isCleanExt(v *Value) bool {
 	switch v.Op {
 	case OpSignExt8to16, OpSignExt8to32, OpSignExt8to64,
diff --git a/src/cmd/compile/internal/ssa/regalloc.go b/src/cmd/compile/internal/ssa/regalloc.go
index 02faf8a..294c522 100644
--- a/src/cmd/compile/internal/ssa/regalloc.go
+++ b/src/cmd/compile/internal/ssa/regalloc.go
@@ -146,6 +146,7 @@
 	var s regAllocState
 	s.init(f)
 	s.regalloc(f)
+	s.close()
 }
 
 type register uint8
@@ -357,6 +358,12 @@
 // setOrig records that c's original value is the same as
 // v's original value.
 func (s *regAllocState) setOrig(c *Value, v *Value) {
+	if int(c.ID) >= cap(s.orig) {
+		x := s.f.Cache.allocValueSlice(int(c.ID) + 1)
+		copy(x, s.orig)
+		s.f.Cache.freeValueSlice(s.orig)
+		s.orig = x
+	}
 	for int(c.ID) >= len(s.orig) {
 		s.orig = append(s.orig, nil)
 	}
@@ -626,7 +633,7 @@
 			// Note that for Flag_shared (position independent code)
 			// we do need to be careful, but that carefulness is hidden
 			// in the rewrite rules so we always have a free register
-			// available for global load/stores. See gen/386.rules (search for Flag_shared).
+			// available for global load/stores. See _gen/386.rules (search for Flag_shared).
 		case "amd64":
 			s.allocatable &^= 1 << 15 // R15
 		case "arm":
@@ -664,7 +671,7 @@
 		s.f.Cache.regallocValues = make([]valState, nv)
 	}
 	s.values = s.f.Cache.regallocValues
-	s.orig = make([]*Value, nv)
+	s.orig = s.f.Cache.allocValueSlice(nv)
 	s.copies = make(map[*Value]bool)
 	for _, b := range s.visitOrder {
 		for _, v := range b.Values {
@@ -728,6 +735,10 @@
 	}
 }
 
+func (s *regAllocState) close() {
+	s.f.Cache.freeValueSlice(s.orig)
+}
+
 // Adds a use record for id at distance dist from the start of the block.
 // All calls to addUse must happen with nonincreasing dist.
 func (s *regAllocState) addUse(id ID, dist int32, pos src.XPos) {
@@ -841,6 +852,9 @@
 	return s.f.Config.hasGReg && s.GReg == r
 }
 
+// Dummy value used to represent the value being held in a temporary register.
+var tmpVal Value
+
 func (s *regAllocState) regalloc(f *Func) {
 	regValLiveSet := f.newSparseSet(f.NumValues()) // set of values that may be live in register
 	defer f.retSparseSet(regValLiveSet)
@@ -1255,6 +1269,7 @@
 
 		// Process all the non-phi values.
 		for idx, v := range oldSched {
+			tmpReg := noRegister
 			if s.f.pass.debug > regDebug {
 				fmt.Printf("  processing %s\n", v.LongString())
 			}
@@ -1290,7 +1305,7 @@
 				}
 				b.Values = append(b.Values, v)
 				s.advanceUses(v)
-				goto issueSpill
+				continue
 			}
 			if v.Op == OpGetG && s.f.Config.hasGReg {
 				// use hardware g register
@@ -1300,7 +1315,7 @@
 				s.assignReg(s.GReg, v, v)
 				b.Values = append(b.Values, v)
 				s.advanceUses(v)
-				goto issueSpill
+				continue
 			}
 			if v.Op == OpArg {
 				// Args are "pre-spilled" values. We don't allocate
@@ -1539,6 +1554,20 @@
 			}
 
 		ok:
+			// Pick a temporary register if needed.
+			// It should be distinct from all the input registers, so we
+			// allocate it after all the input registers, but before
+			// the input registers are freed via advanceUses below.
+			// (Not all instructions need that distinct part, but it is conservative.)
+			if opcodeTable[v.Op].needIntTemp {
+				m := s.allocatable & s.f.Config.gpRegMask
+				if m&^desired.avoid&^s.nospill != 0 {
+					m &^= desired.avoid
+				}
+				tmpReg = s.allocReg(m, &tmpVal)
+				s.nospill |= regMask(1) << tmpReg
+			}
+
 			// Now that all args are in regs, we're ready to issue the value itself.
 			// Before we pick a register for the output value, allow input registers
 			// to be deallocated. We do this here so that the output can use the
@@ -1563,6 +1592,11 @@
 				outRegs := noRegisters // TODO if this is costly, hoist and clear incrementally below.
 				maxOutIdx := -1
 				var used regMask
+				if tmpReg != noRegister {
+					// Ensure output registers are distinct from the temporary register.
+					// (Not all instructions need that distinct part, but it is conservative.)
+					used |= regMask(1) << tmpReg
+				}
 				for _, out := range regspec.outputs {
 					mask := out.regs & s.allocatable &^ used
 					if mask == 0 {
@@ -1644,6 +1678,13 @@
 						s.assignReg(r, v, v)
 					}
 				}
+				if tmpReg != noRegister {
+					// Remember the temp register allocation, if any.
+					if s.f.tempRegs == nil {
+						s.f.tempRegs = map[ID]*Register{}
+					}
+					s.f.tempRegs[v.ID] = &s.registers[tmpReg]
+				}
 			}
 
 			// deallocate dead args, if we have not done so
@@ -1658,8 +1699,6 @@
 				v.SetArg(i, a) // use register version of arguments
 			}
 			b.Values = append(b.Values, v)
-
-		issueSpill:
 		}
 
 		// Copy the control values - we need this so we can reduce the
@@ -2498,10 +2537,10 @@
 	s.desired = make([]desiredState, f.NumBlocks())
 	var phis []*Value
 
-	live := f.newSparseMap(f.NumValues())
-	defer f.retSparseMap(live)
-	t := f.newSparseMap(f.NumValues())
-	defer f.retSparseMap(t)
+	live := f.newSparseMapPos(f.NumValues())
+	defer f.retSparseMapPos(live)
+	t := f.newSparseMapPos(f.NumValues())
+	defer f.retSparseMapPos(t)
 
 	// Keep track of which value we want in each register.
 	var desired desiredState
@@ -2630,7 +2669,7 @@
 					d := e.val + delta
 					if !t.contains(e.key) || d < t.get(e.key) {
 						update = true
-						t.set(e.key, d, e.aux)
+						t.set(e.key, d, e.pos)
 					}
 				}
 				// Also add the correct arg from the saved phi values.
@@ -2653,7 +2692,7 @@
 					l = make([]liveInfo, 0, t.size())
 				}
 				for _, e := range t.contents() {
-					l = append(l, liveInfo{e.key, e.val, e.aux})
+					l = append(l, liveInfo{e.key, e.val, e.pos})
 				}
 				s.live[p.ID] = l
 				changed = true
diff --git a/src/cmd/compile/internal/ssa/rewrite.go b/src/cmd/compile/internal/ssa/rewrite.go
index 05fb2f2..f4ac97c 100644
--- a/src/cmd/compile/internal/ssa/rewrite.go
+++ b/src/cmd/compile/internal/ssa/rewrite.go
@@ -412,18 +412,18 @@
 	return true
 }
 
-// isSameCall reports whether sym is the same as the given named symbol
+// isSameCall reports whether sym is the same as the given named symbol.
 func isSameCall(sym interface{}, name string) bool {
 	fn := sym.(*AuxCall).Fn
 	return fn != nil && fn.String() == name
 }
 
-// canLoadUnaligned reports if the architecture supports unaligned load operations
+// canLoadUnaligned reports if the architecture supports unaligned load operations.
 func canLoadUnaligned(c *Config) bool {
 	return c.ctxt.Arch.Alignment == 1
 }
 
-// nlz returns the number of leading zeros.
+// nlzX returns the number of leading zeros.
 func nlz64(x int64) int { return bits.LeadingZeros64(uint64(x)) }
 func nlz32(x int32) int { return bits.LeadingZeros32(uint32(x)) }
 func nlz16(x int16) int { return bits.LeadingZeros16(uint16(x)) }
@@ -467,7 +467,7 @@
 	return int64(bits.Len32(uint32(n))) - 1
 }
 
-// isPowerOfTwo functions report whether n is a power of 2.
+// isPowerOfTwoX functions report whether n is a power of 2.
 func isPowerOfTwo8(n int8) bool {
 	return n > 0 && n&(n-1) == 0
 }
@@ -797,7 +797,7 @@
 }
 
 // de-virtualize an InterLECall
-// 'sym' is the symbol for the itab
+// 'sym' is the symbol for the itab.
 func devirtLESym(v *Value, aux Aux, sym Sym, offset int64) *obj.LSym {
 	n, ok := sym.(*obj.LSym)
 	if !ok {
@@ -898,7 +898,7 @@
 	return false
 }
 
-// moveSize returns the number of bytes an aligned MOV instruction moves
+// moveSize returns the number of bytes an aligned MOV instruction moves.
 func moveSize(align int64, c *Config) int64 {
 	switch {
 	case align%8 == 0 && c.PtrSize == 8:
@@ -1019,7 +1019,7 @@
 	return true
 }
 
-// for a pseudo-op like (LessThan x), extract x
+// for a pseudo-op like (LessThan x), extract x.
 func flagArg(v *Value) *Value {
 	if len(v.Args) != 1 || !v.Args[0].Type.IsFlags() {
 		return nil
@@ -1165,7 +1165,7 @@
 }
 
 // logRule logs the use of the rule s. This will only be enabled if
-// rewrite rules were generated with the -log option, see gen/rulegen.go.
+// rewrite rules were generated with the -log option, see _gen/rulegen.go.
 func logRule(s string) {
 	if ruleFile == nil {
 		// Open a log file to write log to. We open in append
@@ -1250,7 +1250,7 @@
 	}
 }
 
-// check if an immediate can be directly encoded into an ARM's instruction
+// check if an immediate can be directly encoded into an ARM's instruction.
 func isARMImmRot(v uint32) bool {
 	for i := 0; i < 16; i++ {
 		if v&^0xff == 0 {
@@ -1312,7 +1312,7 @@
 	return false
 }
 
-// zeroUpper48Bits is similar to zeroUpper32Bits, but for upper 48 bits
+// zeroUpper48Bits is similar to zeroUpper32Bits, but for upper 48 bits.
 func zeroUpper48Bits(x *Value, depth int) bool {
 	switch x.Op {
 	case OpAMD64MOVWQZX, OpAMD64MOVWload, OpAMD64MOVWloadidx1, OpAMD64MOVWloadidx2:
@@ -1336,7 +1336,7 @@
 	return false
 }
 
-// zeroUpper56Bits is similar to zeroUpper32Bits, but for upper 56 bits
+// zeroUpper56Bits is similar to zeroUpper32Bits, but for upper 56 bits.
 func zeroUpper56Bits(x *Value, depth int) bool {
 	switch x.Op {
 	case OpAMD64MOVBQZX, OpAMD64MOVBload, OpAMD64MOVBloadidx1:
@@ -1362,7 +1362,8 @@
 
 // isInlinableMemmove reports whether the given arch performs a Move of the given size
 // faster than memmove. It will only return true if replacing the memmove with a Move is
-// safe, either because Move is small or because the arguments are disjoint.
+// safe, either because Move will do all of its loads before any of its stores, or
+// because the arguments are known to be disjoint.
 // This is used as a check for replacing memmove with Move ops.
 func isInlinableMemmove(dst, src *Value, sz int64, c *Config) bool {
 	// It is always safe to convert memmove into Move when its arguments are disjoint.
@@ -1381,6 +1382,9 @@
 	}
 	return false
 }
+func IsInlinableMemmove(dst, src *Value, sz int64, c *Config) bool {
+	return isInlinableMemmove(dst, src, sz, c)
+}
 
 // logLargeCopy logs the occurrence of a large copy.
 // The best place to do this is in the rewrite rules where the size of the move is easy to find.
@@ -1394,6 +1398,14 @@
 	}
 	return true
 }
+func LogLargeCopy(funcName string, pos src.XPos, s int64) {
+	if s < 128 {
+		return
+	}
+	if logopt.Enabled() {
+		logopt.LogOpt(pos, "copy", "lower", funcName, fmt.Sprintf("%d bytes", s))
+	}
+}
 
 // hasSmallRotate reports whether the architecture has rotate instructions
 // for sizes < 32-bit.  This is used to decide whether to promote some rotations.
@@ -1474,7 +1486,7 @@
 	return int64(me) | int64(mb<<8) | int64(rotate<<16) | int64(nbits<<24)
 }
 
-// The inverse operation of encodePPC64RotateMask.  The values returned as
+// DecodePPC64RotateMask is the inverse operation of encodePPC64RotateMask.  The values returned as
 // mb and me satisfy the POWER ISA definition of MASK(x,y) where MASK(mb,me) = mask.
 func DecodePPC64RotateMask(sauxint int64) (rotate, mb, me int64, mask uint64) {
 	auxint := uint64(sauxint)
@@ -1613,7 +1625,7 @@
 	return shiftedMask != 0 && isPowerOfTwo64(shiftedMask+1) && nto(shiftedMask)+lsb < 64
 }
 
-// returns the bitfield width of mask >> rshift for arm64 bitfield ops
+// returns the bitfield width of mask >> rshift for arm64 bitfield ops.
 func arm64BFWidth(mask, rshift int64) int64 {
 	shiftedMask := int64(uint64(mask) >> uint64(rshift))
 	if shiftedMask == 0 {
@@ -1632,7 +1644,7 @@
 // a register. It assumes float64 values will always fit into registers
 // even if that isn't strictly true.
 func registerizable(b *Block, typ *types.Type) bool {
-	if typ.IsPtrShaped() || typ.IsFloat() {
+	if typ.IsPtrShaped() || typ.IsFloat() || typ.IsBoolean() {
 		return true
 	}
 	if typ.IsInteger() {
@@ -1764,6 +1776,9 @@
 
 // sequentialAddresses reports true if it can prove that x + n == y
 func sequentialAddresses(x, y *Value, n int64) bool {
+	if x == y && n == 0 {
+		return true
+	}
 	if x.Op == Op386ADDL && y.Op == Op386LEAL1 && y.AuxInt == n && y.Aux == nil &&
 		(x.Args[0] == y.Args[0] && x.Args[1] == y.Args[1] ||
 			x.Args[0] == y.Args[1] && x.Args[1] == y.Args[0]) {
@@ -1962,3 +1977,69 @@
 	s.Set(obj.AttrLocal, true)
 	return s
 }
+
+// canRotate reports whether the architecture supports
+// rotates of integer registers with the given number of bits.
+func canRotate(c *Config, bits int64) bool {
+	if bits > c.PtrSize*8 {
+		// Don't rewrite to rotates bigger than the machine word.
+		return false
+	}
+	switch c.arch {
+	case "386", "amd64", "arm64":
+		return true
+	case "arm", "s390x", "ppc64", "ppc64le", "wasm", "loong64":
+		return bits >= 32
+	default:
+		return false
+	}
+}
+
+// isARM64bitcon reports whether a constant can be encoded into a logical instruction.
+func isARM64bitcon(x uint64) bool {
+	if x == 1<<64-1 || x == 0 {
+		return false
+	}
+	// determine the period and sign-extend a unit to 64 bits
+	switch {
+	case x != x>>32|x<<32:
+		// period is 64
+		// nothing to do
+	case x != x>>16|x<<48:
+		// period is 32
+		x = uint64(int64(int32(x)))
+	case x != x>>8|x<<56:
+		// period is 16
+		x = uint64(int64(int16(x)))
+	case x != x>>4|x<<60:
+		// period is 8
+		x = uint64(int64(int8(x)))
+	default:
+		// period is 4 or 2, always true
+		// 0001, 0010, 0100, 1000 -- 0001 rotate
+		// 0011, 0110, 1100, 1001 -- 0011 rotate
+		// 0111, 1011, 1101, 1110 -- 0111 rotate
+		// 0101, 1010             -- 01   rotate, repeat
+		return true
+	}
+	return sequenceOfOnes(x) || sequenceOfOnes(^x)
+}
+
+// sequenceOfOnes tests whether a constant is a sequence of ones in binary, with leading and trailing zeros.
+func sequenceOfOnes(x uint64) bool {
+	y := x & -x // lowest set bit of x. x is good iff x+y is a power of 2
+	y += x
+	return (y-1)&y == 0
+}
+
+// isARM64addcon reports whether x can be encoded as the immediate value in an ADD or SUB instruction.
+func isARM64addcon(v int64) bool {
+	/* uimm12 or uimm24? */
+	if v < 0 {
+		return false
+	}
+	if (v & 0xFFF) == 0 {
+		v >>= 12
+	}
+	return v <= 0xFFF
+}
diff --git a/src/cmd/compile/internal/ssa/rewrite386.go b/src/cmd/compile/internal/ssa/rewrite386.go
index 34f3786..0cacfe3 100644
--- a/src/cmd/compile/internal/ssa/rewrite386.go
+++ b/src/cmd/compile/internal/ssa/rewrite386.go
@@ -1,5 +1,5 @@
-// Code generated from gen/386.rules; DO NOT EDIT.
-// generated with: cd gen; go run *.go
+// Code generated from _gen/386.rules; DO NOT EDIT.
+// generated with: cd _gen; go run .
 
 package ssa
 
@@ -146,10 +146,16 @@
 		return rewriteValue386_Op386ORLload(v)
 	case Op386ORLmodify:
 		return rewriteValue386_Op386ORLmodify(v)
+	case Op386ROLB:
+		return rewriteValue386_Op386ROLB(v)
 	case Op386ROLBconst:
 		return rewriteValue386_Op386ROLBconst(v)
+	case Op386ROLL:
+		return rewriteValue386_Op386ROLL(v)
 	case Op386ROLLconst:
 		return rewriteValue386_Op386ROLLconst(v)
+	case Op386ROLW:
+		return rewriteValue386_Op386ROLW(v)
 	case Op386ROLWconst:
 		return rewriteValue386_Op386ROLWconst(v)
 	case Op386SARB:
@@ -541,11 +547,14 @@
 	case OpPanicExtend:
 		return rewriteValue386_OpPanicExtend(v)
 	case OpRotateLeft16:
-		return rewriteValue386_OpRotateLeft16(v)
+		v.Op = Op386ROLW
+		return true
 	case OpRotateLeft32:
-		return rewriteValue386_OpRotateLeft32(v)
+		v.Op = Op386ROLL
+		return true
 	case OpRotateLeft8:
-		return rewriteValue386_OpRotateLeft8(v)
+		v.Op = Op386ROLB
+		return true
 	case OpRound32F:
 		v.Op = OpCopy
 		return true
@@ -734,80 +743,6 @@
 		}
 		break
 	}
-	// match: (ADDL (SHLLconst [c] x) (SHRLconst [d] x))
-	// cond: d == 32-c
-	// result: (ROLLconst [c] x)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != Op386SHLLconst {
-				continue
-			}
-			c := auxIntToInt32(v_0.AuxInt)
-			x := v_0.Args[0]
-			if v_1.Op != Op386SHRLconst {
-				continue
-			}
-			d := auxIntToInt32(v_1.AuxInt)
-			if x != v_1.Args[0] || !(d == 32-c) {
-				continue
-			}
-			v.reset(Op386ROLLconst)
-			v.AuxInt = int32ToAuxInt(c)
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
-	// match: (ADDL <t> (SHLLconst x [c]) (SHRWconst x [d]))
-	// cond: c < 16 && d == int16(16-c) && t.Size() == 2
-	// result: (ROLWconst x [int16(c)])
-	for {
-		t := v.Type
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != Op386SHLLconst {
-				continue
-			}
-			c := auxIntToInt32(v_0.AuxInt)
-			x := v_0.Args[0]
-			if v_1.Op != Op386SHRWconst {
-				continue
-			}
-			d := auxIntToInt16(v_1.AuxInt)
-			if x != v_1.Args[0] || !(c < 16 && d == int16(16-c) && t.Size() == 2) {
-				continue
-			}
-			v.reset(Op386ROLWconst)
-			v.AuxInt = int16ToAuxInt(int16(c))
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
-	// match: (ADDL <t> (SHLLconst x [c]) (SHRBconst x [d]))
-	// cond: c < 8 && d == int8(8-c) && t.Size() == 1
-	// result: (ROLBconst x [int8(c)])
-	for {
-		t := v.Type
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != Op386SHLLconst {
-				continue
-			}
-			c := auxIntToInt32(v_0.AuxInt)
-			x := v_0.Args[0]
-			if v_1.Op != Op386SHRBconst {
-				continue
-			}
-			d := auxIntToInt8(v_1.AuxInt)
-			if x != v_1.Args[0] || !(c < 8 && d == int8(8-c) && t.Size() == 1) {
-				continue
-			}
-			v.reset(Op386ROLBconst)
-			v.AuxInt = int8ToAuxInt(int8(c))
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
 	// match: (ADDL x (SHLLconst [3] y))
 	// result: (LEAL8 x y)
 	for {
@@ -6305,80 +6240,6 @@
 		}
 		break
 	}
-	// match: ( ORL (SHLLconst [c] x) (SHRLconst [d] x))
-	// cond: d == 32-c
-	// result: (ROLLconst [c] x)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != Op386SHLLconst {
-				continue
-			}
-			c := auxIntToInt32(v_0.AuxInt)
-			x := v_0.Args[0]
-			if v_1.Op != Op386SHRLconst {
-				continue
-			}
-			d := auxIntToInt32(v_1.AuxInt)
-			if x != v_1.Args[0] || !(d == 32-c) {
-				continue
-			}
-			v.reset(Op386ROLLconst)
-			v.AuxInt = int32ToAuxInt(c)
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
-	// match: ( ORL <t> (SHLLconst x [c]) (SHRWconst x [d]))
-	// cond: c < 16 && d == int16(16-c) && t.Size() == 2
-	// result: (ROLWconst x [int16(c)])
-	for {
-		t := v.Type
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != Op386SHLLconst {
-				continue
-			}
-			c := auxIntToInt32(v_0.AuxInt)
-			x := v_0.Args[0]
-			if v_1.Op != Op386SHRWconst {
-				continue
-			}
-			d := auxIntToInt16(v_1.AuxInt)
-			if x != v_1.Args[0] || !(c < 16 && d == int16(16-c) && t.Size() == 2) {
-				continue
-			}
-			v.reset(Op386ROLWconst)
-			v.AuxInt = int16ToAuxInt(int16(c))
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
-	// match: ( ORL <t> (SHLLconst x [c]) (SHRBconst x [d]))
-	// cond: c < 8 && d == int8(8-c) && t.Size() == 1
-	// result: (ROLBconst x [int8(c)])
-	for {
-		t := v.Type
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != Op386SHLLconst {
-				continue
-			}
-			c := auxIntToInt32(v_0.AuxInt)
-			x := v_0.Args[0]
-			if v_1.Op != Op386SHRBconst {
-				continue
-			}
-			d := auxIntToInt8(v_1.AuxInt)
-			if x != v_1.Args[0] || !(c < 8 && d == int8(8-c) && t.Size() == 1) {
-				continue
-			}
-			v.reset(Op386ROLBconst)
-			v.AuxInt = int8ToAuxInt(int8(c))
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
 	// match: (ORL x l:(MOVLload [off] {sym} ptr mem))
 	// cond: canMergeLoadClobber(v, l, x) && clobber(l)
 	// result: (ORLload x [off] {sym} ptr mem)
@@ -6809,22 +6670,26 @@
 	}
 	return false
 }
-func rewriteValue386_Op386ROLBconst(v *Value) bool {
+func rewriteValue386_Op386ROLB(v *Value) bool {
+	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	// match: (ROLBconst [c] (ROLBconst [d] x))
-	// result: (ROLBconst [(c+d)& 7] x)
+	// match: (ROLB x (MOVLconst [c]))
+	// result: (ROLBconst [int8(c&7)] x)
 	for {
-		c := auxIntToInt8(v.AuxInt)
-		if v_0.Op != Op386ROLBconst {
+		x := v_0
+		if v_1.Op != Op386MOVLconst {
 			break
 		}
-		d := auxIntToInt8(v_0.AuxInt)
-		x := v_0.Args[0]
+		c := auxIntToInt32(v_1.AuxInt)
 		v.reset(Op386ROLBconst)
-		v.AuxInt = int8ToAuxInt((c + d) & 7)
+		v.AuxInt = int8ToAuxInt(int8(c & 7))
 		v.AddArg(x)
 		return true
 	}
+	return false
+}
+func rewriteValue386_Op386ROLBconst(v *Value) bool {
+	v_0 := v.Args[0]
 	// match: (ROLBconst [0] x)
 	// result: x
 	for {
@@ -6837,22 +6702,26 @@
 	}
 	return false
 }
-func rewriteValue386_Op386ROLLconst(v *Value) bool {
+func rewriteValue386_Op386ROLL(v *Value) bool {
+	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	// match: (ROLLconst [c] (ROLLconst [d] x))
-	// result: (ROLLconst [(c+d)&31] x)
+	// match: (ROLL x (MOVLconst [c]))
+	// result: (ROLLconst [c&31] x)
 	for {
-		c := auxIntToInt32(v.AuxInt)
-		if v_0.Op != Op386ROLLconst {
+		x := v_0
+		if v_1.Op != Op386MOVLconst {
 			break
 		}
-		d := auxIntToInt32(v_0.AuxInt)
-		x := v_0.Args[0]
+		c := auxIntToInt32(v_1.AuxInt)
 		v.reset(Op386ROLLconst)
-		v.AuxInt = int32ToAuxInt((c + d) & 31)
+		v.AuxInt = int32ToAuxInt(c & 31)
 		v.AddArg(x)
 		return true
 	}
+	return false
+}
+func rewriteValue386_Op386ROLLconst(v *Value) bool {
+	v_0 := v.Args[0]
 	// match: (ROLLconst [0] x)
 	// result: x
 	for {
@@ -6865,22 +6734,26 @@
 	}
 	return false
 }
-func rewriteValue386_Op386ROLWconst(v *Value) bool {
+func rewriteValue386_Op386ROLW(v *Value) bool {
+	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	// match: (ROLWconst [c] (ROLWconst [d] x))
-	// result: (ROLWconst [(c+d)&15] x)
+	// match: (ROLW x (MOVLconst [c]))
+	// result: (ROLWconst [int16(c&15)] x)
 	for {
-		c := auxIntToInt16(v.AuxInt)
-		if v_0.Op != Op386ROLWconst {
+		x := v_0
+		if v_1.Op != Op386MOVLconst {
 			break
 		}
-		d := auxIntToInt16(v_0.AuxInt)
-		x := v_0.Args[0]
+		c := auxIntToInt32(v_1.AuxInt)
 		v.reset(Op386ROLWconst)
-		v.AuxInt = int16ToAuxInt((c + d) & 15)
+		v.AuxInt = int16ToAuxInt(int16(c & 15))
 		v.AddArg(x)
 		return true
 	}
+	return false
+}
+func rewriteValue386_Op386ROLWconst(v *Value) bool {
+	v_0 := v.Args[0]
 	// match: (ROLWconst [0] x)
 	// result: x
 	for {
@@ -8346,80 +8219,6 @@
 		}
 		break
 	}
-	// match: (XORL (SHLLconst [c] x) (SHRLconst [d] x))
-	// cond: d == 32-c
-	// result: (ROLLconst [c] x)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != Op386SHLLconst {
-				continue
-			}
-			c := auxIntToInt32(v_0.AuxInt)
-			x := v_0.Args[0]
-			if v_1.Op != Op386SHRLconst {
-				continue
-			}
-			d := auxIntToInt32(v_1.AuxInt)
-			if x != v_1.Args[0] || !(d == 32-c) {
-				continue
-			}
-			v.reset(Op386ROLLconst)
-			v.AuxInt = int32ToAuxInt(c)
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
-	// match: (XORL <t> (SHLLconst x [c]) (SHRWconst x [d]))
-	// cond: c < 16 && d == int16(16-c) && t.Size() == 2
-	// result: (ROLWconst x [int16(c)])
-	for {
-		t := v.Type
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != Op386SHLLconst {
-				continue
-			}
-			c := auxIntToInt32(v_0.AuxInt)
-			x := v_0.Args[0]
-			if v_1.Op != Op386SHRWconst {
-				continue
-			}
-			d := auxIntToInt16(v_1.AuxInt)
-			if x != v_1.Args[0] || !(c < 16 && d == int16(16-c) && t.Size() == 2) {
-				continue
-			}
-			v.reset(Op386ROLWconst)
-			v.AuxInt = int16ToAuxInt(int16(c))
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
-	// match: (XORL <t> (SHLLconst x [c]) (SHRBconst x [d]))
-	// cond: c < 8 && d == int8(8-c) && t.Size() == 1
-	// result: (ROLBconst x [int8(c)])
-	for {
-		t := v.Type
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != Op386SHLLconst {
-				continue
-			}
-			c := auxIntToInt32(v_0.AuxInt)
-			x := v_0.Args[0]
-			if v_1.Op != Op386SHRBconst {
-				continue
-			}
-			d := auxIntToInt8(v_1.AuxInt)
-			if x != v_1.Args[0] || !(c < 8 && d == int8(8-c) && t.Size() == 1) {
-				continue
-			}
-			v.reset(Op386ROLBconst)
-			v.AuxInt = int8ToAuxInt(int8(c))
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
 	// match: (XORL x l:(MOVLload [off] {sym} ptr mem))
 	// cond: canMergeLoadClobber(v, l, x) && clobber(l)
 	// result: (XORLload x [off] {sym} ptr mem)
@@ -10298,60 +10097,6 @@
 	}
 	return false
 }
-func rewriteValue386_OpRotateLeft16(v *Value) bool {
-	v_1 := v.Args[1]
-	v_0 := v.Args[0]
-	// match: (RotateLeft16 x (MOVLconst [c]))
-	// result: (ROLWconst [int16(c&15)] x)
-	for {
-		x := v_0
-		if v_1.Op != Op386MOVLconst {
-			break
-		}
-		c := auxIntToInt32(v_1.AuxInt)
-		v.reset(Op386ROLWconst)
-		v.AuxInt = int16ToAuxInt(int16(c & 15))
-		v.AddArg(x)
-		return true
-	}
-	return false
-}
-func rewriteValue386_OpRotateLeft32(v *Value) bool {
-	v_1 := v.Args[1]
-	v_0 := v.Args[0]
-	// match: (RotateLeft32 x (MOVLconst [c]))
-	// result: (ROLLconst [c&31] x)
-	for {
-		x := v_0
-		if v_1.Op != Op386MOVLconst {
-			break
-		}
-		c := auxIntToInt32(v_1.AuxInt)
-		v.reset(Op386ROLLconst)
-		v.AuxInt = int32ToAuxInt(c & 31)
-		v.AddArg(x)
-		return true
-	}
-	return false
-}
-func rewriteValue386_OpRotateLeft8(v *Value) bool {
-	v_1 := v.Args[1]
-	v_0 := v.Args[0]
-	// match: (RotateLeft8 x (MOVLconst [c]))
-	// result: (ROLBconst [int8(c&7)] x)
-	for {
-		x := v_0
-		if v_1.Op != Op386MOVLconst {
-			break
-		}
-		c := auxIntToInt32(v_1.AuxInt)
-		v.reset(Op386ROLBconst)
-		v.AuxInt = int8ToAuxInt(int8(c & 7))
-		v.AddArg(x)
-		return true
-	}
-	return false
-}
 func rewriteValue386_OpRsh16Ux16(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
diff --git a/src/cmd/compile/internal/ssa/rewrite386splitload.go b/src/cmd/compile/internal/ssa/rewrite386splitload.go
index 670e7f4..ef3bf26 100644
--- a/src/cmd/compile/internal/ssa/rewrite386splitload.go
+++ b/src/cmd/compile/internal/ssa/rewrite386splitload.go
@@ -1,5 +1,5 @@
-// Code generated from gen/386splitload.rules; DO NOT EDIT.
-// generated with: cd gen; go run *.go
+// Code generated from _gen/386splitload.rules; DO NOT EDIT.
+// generated with: cd _gen; go run .
 
 package ssa
 
diff --git a/src/cmd/compile/internal/ssa/rewriteAMD64.go b/src/cmd/compile/internal/ssa/rewriteAMD64.go
index 341fcc2..cad37d4 100644
--- a/src/cmd/compile/internal/ssa/rewriteAMD64.go
+++ b/src/cmd/compile/internal/ssa/rewriteAMD64.go
@@ -1,5 +1,5 @@
-// Code generated from gen/AMD64.rules; DO NOT EDIT.
-// generated with: cd gen; go run *.go
+// Code generated from _gen/AMD64.rules; DO NOT EDIT.
+// generated with: cd _gen; go run .
 
 package ssa
 
@@ -382,12 +382,8 @@
 		return rewriteValueAMD64_OpAMD64SARW(v)
 	case OpAMD64SARWconst:
 		return rewriteValueAMD64_OpAMD64SARWconst(v)
-	case OpAMD64SARXL:
-		return rewriteValueAMD64_OpAMD64SARXL(v)
 	case OpAMD64SARXLload:
 		return rewriteValueAMD64_OpAMD64SARXLload(v)
-	case OpAMD64SARXQ:
-		return rewriteValueAMD64_OpAMD64SARXQ(v)
 	case OpAMD64SARXQload:
 		return rewriteValueAMD64_OpAMD64SARXQload(v)
 	case OpAMD64SBBLcarrymask:
@@ -446,12 +442,8 @@
 		return rewriteValueAMD64_OpAMD64SHLQ(v)
 	case OpAMD64SHLQconst:
 		return rewriteValueAMD64_OpAMD64SHLQconst(v)
-	case OpAMD64SHLXL:
-		return rewriteValueAMD64_OpAMD64SHLXL(v)
 	case OpAMD64SHLXLload:
 		return rewriteValueAMD64_OpAMD64SHLXLload(v)
-	case OpAMD64SHLXQ:
-		return rewriteValueAMD64_OpAMD64SHLXQ(v)
 	case OpAMD64SHLXQload:
 		return rewriteValueAMD64_OpAMD64SHLXQload(v)
 	case OpAMD64SHRB:
@@ -470,12 +462,8 @@
 		return rewriteValueAMD64_OpAMD64SHRW(v)
 	case OpAMD64SHRWconst:
 		return rewriteValueAMD64_OpAMD64SHRWconst(v)
-	case OpAMD64SHRXL:
-		return rewriteValueAMD64_OpAMD64SHRXL(v)
 	case OpAMD64SHRXLload:
 		return rewriteValueAMD64_OpAMD64SHRXLload(v)
-	case OpAMD64SHRXQ:
-		return rewriteValueAMD64_OpAMD64SHRXQ(v)
 	case OpAMD64SHRXQload:
 		return rewriteValueAMD64_OpAMD64SHRXQload(v)
 	case OpAMD64SUBL:
@@ -1276,80 +1264,6 @@
 		}
 		break
 	}
-	// match: (ADDL (SHLLconst x [c]) (SHRLconst x [d]))
-	// cond: d==32-c
-	// result: (ROLLconst x [c])
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHLLconst {
-				continue
-			}
-			c := auxIntToInt8(v_0.AuxInt)
-			x := v_0.Args[0]
-			if v_1.Op != OpAMD64SHRLconst {
-				continue
-			}
-			d := auxIntToInt8(v_1.AuxInt)
-			if x != v_1.Args[0] || !(d == 32-c) {
-				continue
-			}
-			v.reset(OpAMD64ROLLconst)
-			v.AuxInt = int8ToAuxInt(c)
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
-	// match: (ADDL <t> (SHLLconst x [c]) (SHRWconst x [d]))
-	// cond: d==16-c && c < 16 && t.Size() == 2
-	// result: (ROLWconst x [c])
-	for {
-		t := v.Type
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHLLconst {
-				continue
-			}
-			c := auxIntToInt8(v_0.AuxInt)
-			x := v_0.Args[0]
-			if v_1.Op != OpAMD64SHRWconst {
-				continue
-			}
-			d := auxIntToInt8(v_1.AuxInt)
-			if x != v_1.Args[0] || !(d == 16-c && c < 16 && t.Size() == 2) {
-				continue
-			}
-			v.reset(OpAMD64ROLWconst)
-			v.AuxInt = int8ToAuxInt(c)
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
-	// match: (ADDL <t> (SHLLconst x [c]) (SHRBconst x [d]))
-	// cond: d==8-c && c < 8 && t.Size() == 1
-	// result: (ROLBconst x [c])
-	for {
-		t := v.Type
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHLLconst {
-				continue
-			}
-			c := auxIntToInt8(v_0.AuxInt)
-			x := v_0.Args[0]
-			if v_1.Op != OpAMD64SHRBconst {
-				continue
-			}
-			d := auxIntToInt8(v_1.AuxInt)
-			if x != v_1.Args[0] || !(d == 8-c && c < 8 && t.Size() == 1) {
-				continue
-			}
-			v.reset(OpAMD64ROLBconst)
-			v.AuxInt = int8ToAuxInt(c)
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
 	// match: (ADDL x (SHLLconst [3] y))
 	// result: (LEAL8 x y)
 	for {
@@ -1915,30 +1829,6 @@
 		}
 		break
 	}
-	// match: (ADDQ (SHLQconst x [c]) (SHRQconst x [d]))
-	// cond: d==64-c
-	// result: (ROLQconst x [c])
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHLQconst {
-				continue
-			}
-			c := auxIntToInt8(v_0.AuxInt)
-			x := v_0.Args[0]
-			if v_1.Op != OpAMD64SHRQconst {
-				continue
-			}
-			d := auxIntToInt8(v_1.AuxInt)
-			if x != v_1.Args[0] || !(d == 64-c) {
-				continue
-			}
-			v.reset(OpAMD64ROLQconst)
-			v.AuxInt = int8ToAuxInt(c)
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
 	// match: (ADDQ x (SHLQconst [3] y))
 	// result: (LEAQ8 x y)
 	for {
@@ -2724,29 +2614,6 @@
 		}
 		break
 	}
-	// match: (ANDL (NOTL (SHLXL (MOVLconst [1]) y)) x)
-	// result: (BTRL x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64NOTL {
-				continue
-			}
-			v_0_0 := v_0.Args[0]
-			if v_0_0.Op != OpAMD64SHLXL {
-				continue
-			}
-			y := v_0_0.Args[1]
-			v_0_0_0 := v_0_0.Args[0]
-			if v_0_0_0.Op != OpAMD64MOVLconst || auxIntToInt32(v_0_0_0.AuxInt) != 1 {
-				continue
-			}
-			x := v_1
-			v.reset(OpAMD64BTRL)
-			v.AddArg2(x, y)
-			return true
-		}
-		break
-	}
 	// match: (ANDL (MOVLconst [c]) x)
 	// cond: isUint32PowerOfTwo(int64(^c)) && uint64(^c) >= 128
 	// result: (BTRLconst [int8(log32(^c))] x)
@@ -3164,22 +3031,6 @@
 		v.AddArg2(x, y)
 		return true
 	}
-	// match: (ANDNL x (SHLXL (MOVLconst [1]) y))
-	// result: (BTRL x y)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64SHLXL {
-			break
-		}
-		y := v_1.Args[1]
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpAMD64MOVLconst || auxIntToInt32(v_1_0.AuxInt) != 1 {
-			break
-		}
-		v.reset(OpAMD64BTRL)
-		v.AddArg2(x, y)
-		return true
-	}
 	return false
 }
 func rewriteValueAMD64_OpAMD64ANDNQ(v *Value) bool {
@@ -3201,22 +3052,6 @@
 		v.AddArg2(x, y)
 		return true
 	}
-	// match: (ANDNQ x (SHLXQ (MOVQconst [1]) y))
-	// result: (BTRQ x y)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64SHLXQ {
-			break
-		}
-		y := v_1.Args[1]
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpAMD64MOVQconst || auxIntToInt64(v_1_0.AuxInt) != 1 {
-			break
-		}
-		v.reset(OpAMD64BTRQ)
-		v.AddArg2(x, y)
-		return true
-	}
 	return false
 }
 func rewriteValueAMD64_OpAMD64ANDQ(v *Value) bool {
@@ -3245,29 +3080,6 @@
 		}
 		break
 	}
-	// match: (ANDQ (NOTQ (SHLXQ (MOVQconst [1]) y)) x)
-	// result: (BTRQ x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64NOTQ {
-				continue
-			}
-			v_0_0 := v_0.Args[0]
-			if v_0_0.Op != OpAMD64SHLXQ {
-				continue
-			}
-			y := v_0_0.Args[1]
-			v_0_0_0 := v_0_0.Args[0]
-			if v_0_0_0.Op != OpAMD64MOVQconst || auxIntToInt64(v_0_0_0.AuxInt) != 1 {
-				continue
-			}
-			x := v_1
-			v.reset(OpAMD64BTRQ)
-			v.AddArg2(x, y)
-			return true
-		}
-		break
-	}
 	// match: (ANDQ (MOVQconst [c]) x)
 	// cond: isUint64PowerOfTwo(^c) && uint64(^c) >= 128
 	// result: (BTRQconst [int8(log64(^c))] x)
@@ -3971,22 +3783,6 @@
 		v.AddArg2(y, x)
 		return true
 	}
-	// match: (BTLconst [0] s:(SHRXQ x y))
-	// result: (BTQ y x)
-	for {
-		if auxIntToInt8(v.AuxInt) != 0 {
-			break
-		}
-		s := v_0
-		if s.Op != OpAMD64SHRXQ {
-			break
-		}
-		y := s.Args[1]
-		x := s.Args[0]
-		v.reset(OpAMD64BTQ)
-		v.AddArg2(y, x)
-		return true
-	}
 	// match: (BTLconst [c] (SHRLconst [d] x))
 	// cond: (c+d)<32
 	// result: (BTLconst [c+d] x)
@@ -4111,22 +3907,6 @@
 		v.AddArg2(y, x)
 		return true
 	}
-	// match: (BTQconst [0] s:(SHRXQ x y))
-	// result: (BTQ y x)
-	for {
-		if auxIntToInt8(v.AuxInt) != 0 {
-			break
-		}
-		s := v_0
-		if s.Op != OpAMD64SHRXQ {
-			break
-		}
-		y := s.Args[1]
-		x := s.Args[0]
-		v.reset(OpAMD64BTQ)
-		v.AddArg2(y, x)
-		return true
-	}
 	return false
 }
 func rewriteValueAMD64_OpAMD64BTRLconst(v *Value) bool {
@@ -7516,40 +7296,6 @@
 func rewriteValueAMD64_OpAMD64CMPQconst(v *Value) bool {
 	v_0 := v.Args[0]
 	b := v.Block
-	// match: (CMPQconst (NEGQ (ADDQconst [-16] (ANDQconst [15] _))) [32])
-	// result: (FlagLT_ULT)
-	for {
-		if auxIntToInt32(v.AuxInt) != 32 || v_0.Op != OpAMD64NEGQ {
-			break
-		}
-		v_0_0 := v_0.Args[0]
-		if v_0_0.Op != OpAMD64ADDQconst || auxIntToInt32(v_0_0.AuxInt) != -16 {
-			break
-		}
-		v_0_0_0 := v_0_0.Args[0]
-		if v_0_0_0.Op != OpAMD64ANDQconst || auxIntToInt32(v_0_0_0.AuxInt) != 15 {
-			break
-		}
-		v.reset(OpAMD64FlagLT_ULT)
-		return true
-	}
-	// match: (CMPQconst (NEGQ (ADDQconst [ -8] (ANDQconst [7] _))) [32])
-	// result: (FlagLT_ULT)
-	for {
-		if auxIntToInt32(v.AuxInt) != 32 || v_0.Op != OpAMD64NEGQ {
-			break
-		}
-		v_0_0 := v_0.Args[0]
-		if v_0_0.Op != OpAMD64ADDQconst || auxIntToInt32(v_0_0.AuxInt) != -8 {
-			break
-		}
-		v_0_0_0 := v_0_0.Args[0]
-		if v_0_0_0.Op != OpAMD64ANDQconst || auxIntToInt32(v_0_0_0.AuxInt) != 7 {
-			break
-		}
-		v.reset(OpAMD64FlagLT_ULT)
-		return true
-	}
 	// match: (CMPQconst (MOVQconst [x]) [y])
 	// cond: x==int64(y)
 	// result: (FlagEQ)
@@ -11255,54 +11001,62 @@
 		v.AddArg3(p0, w0, mem)
 		return true
 	}
-	// match: (MOVBstore [7] {s} p1 (SHRQconst [56] w) x1:(MOVWstore [5] {s} p1 (SHRQconst [40] w) x2:(MOVLstore [1] {s} p1 (SHRQconst [8] w) x3:(MOVBstore [0] {s} p1 w mem))))
-	// cond: x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && clobber(x1, x2, x3)
-	// result: (MOVQstore {s} p1 w mem)
+	// match: (MOVBstore [c3] {s} p3 (SHRQconst [56] w) x1:(MOVWstore [c2] {s} p2 (SHRQconst [40] w) x2:(MOVLstore [c1] {s} p1 (SHRQconst [8] w) x3:(MOVBstore [c0] {s} p0 w mem))))
+	// cond: x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && sequentialAddresses(p0, p1, int64(1 + c0 - c1)) && sequentialAddresses(p0, p2, int64(5 + c0 - c2)) && sequentialAddresses(p0, p3, int64(7 + c0 - c3)) && clobber(x1, x2, x3)
+	// result: (MOVQstore [c0] {s} p0 w mem)
 	for {
-		if auxIntToInt32(v.AuxInt) != 7 {
-			break
-		}
+		c3 := auxIntToInt32(v.AuxInt)
 		s := auxToSym(v.Aux)
-		p1 := v_0
+		p3 := v_0
 		if v_1.Op != OpAMD64SHRQconst || auxIntToInt8(v_1.AuxInt) != 56 {
 			break
 		}
 		w := v_1.Args[0]
 		x1 := v_2
-		if x1.Op != OpAMD64MOVWstore || auxIntToInt32(x1.AuxInt) != 5 || auxToSym(x1.Aux) != s {
+		if x1.Op != OpAMD64MOVWstore {
+			break
+		}
+		c2 := auxIntToInt32(x1.AuxInt)
+		if auxToSym(x1.Aux) != s {
 			break
 		}
 		_ = x1.Args[2]
-		if p1 != x1.Args[0] {
-			break
-		}
+		p2 := x1.Args[0]
 		x1_1 := x1.Args[1]
 		if x1_1.Op != OpAMD64SHRQconst || auxIntToInt8(x1_1.AuxInt) != 40 || w != x1_1.Args[0] {
 			break
 		}
 		x2 := x1.Args[2]
-		if x2.Op != OpAMD64MOVLstore || auxIntToInt32(x2.AuxInt) != 1 || auxToSym(x2.Aux) != s {
+		if x2.Op != OpAMD64MOVLstore {
+			break
+		}
+		c1 := auxIntToInt32(x2.AuxInt)
+		if auxToSym(x2.Aux) != s {
 			break
 		}
 		_ = x2.Args[2]
-		if p1 != x2.Args[0] {
-			break
-		}
+		p1 := x2.Args[0]
 		x2_1 := x2.Args[1]
 		if x2_1.Op != OpAMD64SHRQconst || auxIntToInt8(x2_1.AuxInt) != 8 || w != x2_1.Args[0] {
 			break
 		}
 		x3 := x2.Args[2]
-		if x3.Op != OpAMD64MOVBstore || auxIntToInt32(x3.AuxInt) != 0 || auxToSym(x3.Aux) != s {
+		if x3.Op != OpAMD64MOVBstore {
+			break
+		}
+		c0 := auxIntToInt32(x3.AuxInt)
+		if auxToSym(x3.Aux) != s {
 			break
 		}
 		mem := x3.Args[2]
-		if p1 != x3.Args[0] || w != x3.Args[1] || !(x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && clobber(x1, x2, x3)) {
+		p0 := x3.Args[0]
+		if w != x3.Args[1] || !(x1.Uses == 1 && x2.Uses == 1 && x3.Uses == 1 && sequentialAddresses(p0, p1, int64(1+c0-c1)) && sequentialAddresses(p0, p2, int64(5+c0-c2)) && sequentialAddresses(p0, p3, int64(7+c0-c3)) && clobber(x1, x2, x3)) {
 			break
 		}
 		v.reset(OpAMD64MOVQstore)
+		v.AuxInt = int32ToAuxInt(c0)
 		v.Aux = symToAux(s)
-		v.AddArg3(p1, w, mem)
+		v.AddArg3(p0, w, mem)
 		return true
 	}
 	// match: (MOVBstore [i] {s} p x1:(MOVBload [j] {s2} p2 mem) mem2:(MOVBstore [i-1] {s} p x2:(MOVBload [j-1] {s2} p2 mem) mem))
@@ -11394,13 +11148,13 @@
 		v.AddArg2(ptr, mem)
 		return true
 	}
-	// match: (MOVBstoreconst [c] {s} p x:(MOVBstoreconst [a] {s} p mem))
-	// cond: x.Uses == 1 && a.Off() + 1 == c.Off() && clobber(x)
-	// result: (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p mem)
+	// match: (MOVBstoreconst [c] {s} p1 x:(MOVBstoreconst [a] {s} p0 mem))
+	// cond: x.Uses == 1 && sequentialAddresses(p0, p1, int64(a.Off()+1-c.Off())) && clobber(x)
+	// result: (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p0 mem)
 	for {
 		c := auxIntToValAndOff(v.AuxInt)
 		s := auxToSym(v.Aux)
-		p := v_0
+		p1 := v_0
 		x := v_1
 		if x.Op != OpAMD64MOVBstoreconst {
 			break
@@ -11410,22 +11164,23 @@
 			break
 		}
 		mem := x.Args[1]
-		if p != x.Args[0] || !(x.Uses == 1 && a.Off()+1 == c.Off() && clobber(x)) {
+		p0 := x.Args[0]
+		if !(x.Uses == 1 && sequentialAddresses(p0, p1, int64(a.Off()+1-c.Off())) && clobber(x)) {
 			break
 		}
 		v.reset(OpAMD64MOVWstoreconst)
 		v.AuxInt = valAndOffToAuxInt(makeValAndOff(a.Val()&0xff|c.Val()<<8, a.Off()))
 		v.Aux = symToAux(s)
-		v.AddArg2(p, mem)
+		v.AddArg2(p0, mem)
 		return true
 	}
-	// match: (MOVBstoreconst [a] {s} p x:(MOVBstoreconst [c] {s} p mem))
-	// cond: x.Uses == 1 && a.Off() + 1 == c.Off() && clobber(x)
-	// result: (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p mem)
+	// match: (MOVBstoreconst [a] {s} p0 x:(MOVBstoreconst [c] {s} p1 mem))
+	// cond: x.Uses == 1 && sequentialAddresses(p0, p1, int64(a.Off()+1-c.Off())) && clobber(x)
+	// result: (MOVWstoreconst [makeValAndOff(a.Val()&0xff | c.Val()<<8, a.Off())] {s} p0 mem)
 	for {
 		a := auxIntToValAndOff(v.AuxInt)
 		s := auxToSym(v.Aux)
-		p := v_0
+		p0 := v_0
 		x := v_1
 		if x.Op != OpAMD64MOVBstoreconst {
 			break
@@ -11435,13 +11190,14 @@
 			break
 		}
 		mem := x.Args[1]
-		if p != x.Args[0] || !(x.Uses == 1 && a.Off()+1 == c.Off() && clobber(x)) {
+		p1 := x.Args[0]
+		if !(x.Uses == 1 && sequentialAddresses(p0, p1, int64(a.Off()+1-c.Off())) && clobber(x)) {
 			break
 		}
 		v.reset(OpAMD64MOVWstoreconst)
 		v.AuxInt = valAndOffToAuxInt(makeValAndOff(a.Val()&0xff|c.Val()<<8, a.Off()))
 		v.Aux = symToAux(s)
-		v.AddArg2(p, mem)
+		v.AddArg2(p0, mem)
 		return true
 	}
 	return false
@@ -12624,13 +12380,13 @@
 		v.AddArg2(ptr, mem)
 		return true
 	}
-	// match: (MOVLstoreconst [c] {s} p x:(MOVLstoreconst [a] {s} p mem))
-	// cond: x.Uses == 1 && a.Off() + 4 == c.Off() && clobber(x)
-	// result: (MOVQstore [a.Off()] {s} p (MOVQconst [a.Val64()&0xffffffff | c.Val64()<<32]) mem)
+	// match: (MOVLstoreconst [c] {s} p1 x:(MOVLstoreconst [a] {s} p0 mem))
+	// cond: x.Uses == 1 && sequentialAddresses(p0, p1, int64(a.Off()+4-c.Off())) && clobber(x)
+	// result: (MOVQstore [a.Off()] {s} p0 (MOVQconst [a.Val64()&0xffffffff | c.Val64()<<32]) mem)
 	for {
 		c := auxIntToValAndOff(v.AuxInt)
 		s := auxToSym(v.Aux)
-		p := v_0
+		p1 := v_0
 		x := v_1
 		if x.Op != OpAMD64MOVLstoreconst {
 			break
@@ -12640,7 +12396,8 @@
 			break
 		}
 		mem := x.Args[1]
-		if p != x.Args[0] || !(x.Uses == 1 && a.Off()+4 == c.Off() && clobber(x)) {
+		p0 := x.Args[0]
+		if !(x.Uses == 1 && sequentialAddresses(p0, p1, int64(a.Off()+4-c.Off())) && clobber(x)) {
 			break
 		}
 		v.reset(OpAMD64MOVQstore)
@@ -12648,16 +12405,16 @@
 		v.Aux = symToAux(s)
 		v0 := b.NewValue0(x.Pos, OpAMD64MOVQconst, typ.UInt64)
 		v0.AuxInt = int64ToAuxInt(a.Val64()&0xffffffff | c.Val64()<<32)
-		v.AddArg3(p, v0, mem)
+		v.AddArg3(p0, v0, mem)
 		return true
 	}
-	// match: (MOVLstoreconst [a] {s} p x:(MOVLstoreconst [c] {s} p mem))
-	// cond: x.Uses == 1 && a.Off() + 4 == c.Off() && clobber(x)
-	// result: (MOVQstore [a.Off()] {s} p (MOVQconst [a.Val64()&0xffffffff | c.Val64()<<32]) mem)
+	// match: (MOVLstoreconst [a] {s} p0 x:(MOVLstoreconst [c] {s} p1 mem))
+	// cond: x.Uses == 1 && sequentialAddresses(p0, p1, int64(a.Off()+4-c.Off())) && clobber(x)
+	// result: (MOVQstore [a.Off()] {s} p0 (MOVQconst [a.Val64()&0xffffffff | c.Val64()<<32]) mem)
 	for {
 		a := auxIntToValAndOff(v.AuxInt)
 		s := auxToSym(v.Aux)
-		p := v_0
+		p0 := v_0
 		x := v_1
 		if x.Op != OpAMD64MOVLstoreconst {
 			break
@@ -12667,7 +12424,8 @@
 			break
 		}
 		mem := x.Args[1]
-		if p != x.Args[0] || !(x.Uses == 1 && a.Off()+4 == c.Off() && clobber(x)) {
+		p1 := x.Args[0]
+		if !(x.Uses == 1 && sequentialAddresses(p0, p1, int64(a.Off()+4-c.Off())) && clobber(x)) {
 			break
 		}
 		v.reset(OpAMD64MOVQstore)
@@ -12675,7 +12433,7 @@
 		v.Aux = symToAux(s)
 		v0 := b.NewValue0(x.Pos, OpAMD64MOVQconst, typ.UInt64)
 		v0.AuxInt = int64ToAuxInt(a.Val64()&0xffffffff | c.Val64()<<32)
-		v.AddArg3(p, v0, mem)
+		v.AddArg3(p0, v0, mem)
 		return true
 	}
 	return false
@@ -13585,13 +13343,13 @@
 		v.AddArg2(ptr, mem)
 		return true
 	}
-	// match: (MOVQstoreconst [c] {s} p x:(MOVQstoreconst [a] {s} p mem))
-	// cond: config.useSSE && x.Uses == 1 && a.Off() + 8 == c.Off() && a.Val() == 0 && c.Val() == 0 && clobber(x)
-	// result: (MOVOstoreconst [makeValAndOff(0,a.Off())] {s} p mem)
+	// match: (MOVQstoreconst [c] {s} p1 x:(MOVQstoreconst [a] {s} p0 mem))
+	// cond: config.useSSE && x.Uses == 1 && sequentialAddresses(p0, p1, int64(a.Off()+8-c.Off())) && a.Val() == 0 && c.Val() == 0 && clobber(x)
+	// result: (MOVOstoreconst [makeValAndOff(0,a.Off())] {s} p0 mem)
 	for {
 		c := auxIntToValAndOff(v.AuxInt)
 		s := auxToSym(v.Aux)
-		p := v_0
+		p1 := v_0
 		x := v_1
 		if x.Op != OpAMD64MOVQstoreconst {
 			break
@@ -13601,22 +13359,23 @@
 			break
 		}
 		mem := x.Args[1]
-		if p != x.Args[0] || !(config.useSSE && x.Uses == 1 && a.Off()+8 == c.Off() && a.Val() == 0 && c.Val() == 0 && clobber(x)) {
+		p0 := x.Args[0]
+		if !(config.useSSE && x.Uses == 1 && sequentialAddresses(p0, p1, int64(a.Off()+8-c.Off())) && a.Val() == 0 && c.Val() == 0 && clobber(x)) {
 			break
 		}
 		v.reset(OpAMD64MOVOstoreconst)
 		v.AuxInt = valAndOffToAuxInt(makeValAndOff(0, a.Off()))
 		v.Aux = symToAux(s)
-		v.AddArg2(p, mem)
+		v.AddArg2(p0, mem)
 		return true
 	}
-	// match: (MOVQstoreconst [a] {s} p x:(MOVQstoreconst [c] {s} p mem))
-	// cond: config.useSSE && x.Uses == 1 && a.Off() + 8 == c.Off() && a.Val() == 0 && c.Val() == 0 && clobber(x)
-	// result: (MOVOstoreconst [makeValAndOff(0,a.Off())] {s} p mem)
+	// match: (MOVQstoreconst [a] {s} p0 x:(MOVQstoreconst [c] {s} p1 mem))
+	// cond: config.useSSE && x.Uses == 1 && sequentialAddresses(p0, p1, int64(a.Off()+8-c.Off())) && a.Val() == 0 && c.Val() == 0 && clobber(x)
+	// result: (MOVOstoreconst [makeValAndOff(0,a.Off())] {s} p0 mem)
 	for {
 		a := auxIntToValAndOff(v.AuxInt)
 		s := auxToSym(v.Aux)
-		p := v_0
+		p0 := v_0
 		x := v_1
 		if x.Op != OpAMD64MOVQstoreconst {
 			break
@@ -13626,13 +13385,14 @@
 			break
 		}
 		mem := x.Args[1]
-		if p != x.Args[0] || !(config.useSSE && x.Uses == 1 && a.Off()+8 == c.Off() && a.Val() == 0 && c.Val() == 0 && clobber(x)) {
+		p1 := x.Args[0]
+		if !(config.useSSE && x.Uses == 1 && sequentialAddresses(p0, p1, int64(a.Off()+8-c.Off())) && a.Val() == 0 && c.Val() == 0 && clobber(x)) {
 			break
 		}
 		v.reset(OpAMD64MOVOstoreconst)
 		v.AuxInt = valAndOffToAuxInt(makeValAndOff(0, a.Off()))
 		v.Aux = symToAux(s)
-		v.AddArg2(p, mem)
+		v.AddArg2(p0, mem)
 		return true
 	}
 	return false
@@ -14716,13 +14476,13 @@
 		v.AddArg2(ptr, mem)
 		return true
 	}
-	// match: (MOVWstoreconst [c] {s} p x:(MOVWstoreconst [a] {s} p mem))
-	// cond: x.Uses == 1 && a.Off() + 2 == c.Off() && clobber(x)
-	// result: (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p mem)
+	// match: (MOVWstoreconst [c] {s} p1 x:(MOVWstoreconst [a] {s} p0 mem))
+	// cond: x.Uses == 1 && sequentialAddresses(p0, p1, int64(a.Off()+2-c.Off())) && clobber(x)
+	// result: (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p0 mem)
 	for {
 		c := auxIntToValAndOff(v.AuxInt)
 		s := auxToSym(v.Aux)
-		p := v_0
+		p1 := v_0
 		x := v_1
 		if x.Op != OpAMD64MOVWstoreconst {
 			break
@@ -14732,22 +14492,23 @@
 			break
 		}
 		mem := x.Args[1]
-		if p != x.Args[0] || !(x.Uses == 1 && a.Off()+2 == c.Off() && clobber(x)) {
+		p0 := x.Args[0]
+		if !(x.Uses == 1 && sequentialAddresses(p0, p1, int64(a.Off()+2-c.Off())) && clobber(x)) {
 			break
 		}
 		v.reset(OpAMD64MOVLstoreconst)
 		v.AuxInt = valAndOffToAuxInt(makeValAndOff(a.Val()&0xffff|c.Val()<<16, a.Off()))
 		v.Aux = symToAux(s)
-		v.AddArg2(p, mem)
+		v.AddArg2(p0, mem)
 		return true
 	}
-	// match: (MOVWstoreconst [a] {s} p x:(MOVWstoreconst [c] {s} p mem))
-	// cond: x.Uses == 1 && a.Off() + 2 == c.Off() && clobber(x)
-	// result: (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p mem)
+	// match: (MOVWstoreconst [a] {s} p0 x:(MOVWstoreconst [c] {s} p1 mem))
+	// cond: x.Uses == 1 && sequentialAddresses(p0, p1, int64(a.Off()+2-c.Off())) && clobber(x)
+	// result: (MOVLstoreconst [makeValAndOff(a.Val()&0xffff | c.Val()<<16, a.Off())] {s} p0 mem)
 	for {
 		a := auxIntToValAndOff(v.AuxInt)
 		s := auxToSym(v.Aux)
-		p := v_0
+		p0 := v_0
 		x := v_1
 		if x.Op != OpAMD64MOVWstoreconst {
 			break
@@ -14757,13 +14518,14 @@
 			break
 		}
 		mem := x.Args[1]
-		if p != x.Args[0] || !(x.Uses == 1 && a.Off()+2 == c.Off() && clobber(x)) {
+		p1 := x.Args[0]
+		if !(x.Uses == 1 && sequentialAddresses(p0, p1, int64(a.Off()+2-c.Off())) && clobber(x)) {
 			break
 		}
 		v.reset(OpAMD64MOVLstoreconst)
 		v.AuxInt = valAndOffToAuxInt(makeValAndOff(a.Val()&0xffff|c.Val()<<16, a.Off()))
 		v.Aux = symToAux(s)
-		v.AddArg2(p, mem)
+		v.AddArg2(p0, mem)
 		return true
 	}
 	return false
@@ -16036,25 +15798,6 @@
 		}
 		break
 	}
-	// match: (ORL (SHLXL (MOVLconst [1]) y) x)
-	// result: (BTSL x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHLXL {
-				continue
-			}
-			y := v_0.Args[1]
-			v_0_0 := v_0.Args[0]
-			if v_0_0.Op != OpAMD64MOVLconst || auxIntToInt32(v_0_0.AuxInt) != 1 {
-				continue
-			}
-			x := v_1
-			v.reset(OpAMD64BTSL)
-			v.AddArg2(x, y)
-			return true
-		}
-		break
-	}
 	// match: (ORL (MOVLconst [c]) x)
 	// cond: isUint32PowerOfTwo(int64(c)) && uint64(c) >= 128
 	// result: (BTSLconst [int8(log32(c))] x)
@@ -16091,1312 +15834,6 @@
 		}
 		break
 	}
-	// match: (ORL (SHLLconst x [c]) (SHRLconst x [d]))
-	// cond: d==32-c
-	// result: (ROLLconst x [c])
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHLLconst {
-				continue
-			}
-			c := auxIntToInt8(v_0.AuxInt)
-			x := v_0.Args[0]
-			if v_1.Op != OpAMD64SHRLconst {
-				continue
-			}
-			d := auxIntToInt8(v_1.AuxInt)
-			if x != v_1.Args[0] || !(d == 32-c) {
-				continue
-			}
-			v.reset(OpAMD64ROLLconst)
-			v.AuxInt = int8ToAuxInt(c)
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
-	// match: (ORL <t> (SHLLconst x [c]) (SHRWconst x [d]))
-	// cond: d==16-c && c < 16 && t.Size() == 2
-	// result: (ROLWconst x [c])
-	for {
-		t := v.Type
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHLLconst {
-				continue
-			}
-			c := auxIntToInt8(v_0.AuxInt)
-			x := v_0.Args[0]
-			if v_1.Op != OpAMD64SHRWconst {
-				continue
-			}
-			d := auxIntToInt8(v_1.AuxInt)
-			if x != v_1.Args[0] || !(d == 16-c && c < 16 && t.Size() == 2) {
-				continue
-			}
-			v.reset(OpAMD64ROLWconst)
-			v.AuxInt = int8ToAuxInt(c)
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
-	// match: (ORL <t> (SHLLconst x [c]) (SHRBconst x [d]))
-	// cond: d==8-c && c < 8 && t.Size() == 1
-	// result: (ROLBconst x [c])
-	for {
-		t := v.Type
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHLLconst {
-				continue
-			}
-			c := auxIntToInt8(v_0.AuxInt)
-			x := v_0.Args[0]
-			if v_1.Op != OpAMD64SHRBconst {
-				continue
-			}
-			d := auxIntToInt8(v_1.AuxInt)
-			if x != v_1.Args[0] || !(d == 8-c && c < 8 && t.Size() == 1) {
-				continue
-			}
-			v.reset(OpAMD64ROLBconst)
-			v.AuxInt = int8ToAuxInt(c)
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
-	// match: (ORL (SHLL x y) (ANDL (SHRL x (NEGQ y)) (SBBLcarrymask (CMPQconst (NEGQ (ADDQconst (ANDQconst y [31]) [-32])) [32]))))
-	// result: (ROLL x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHLL {
-				continue
-			}
-			y := v_0.Args[1]
-			x := v_0.Args[0]
-			if v_1.Op != OpAMD64ANDL {
-				continue
-			}
-			_ = v_1.Args[1]
-			v_1_0 := v_1.Args[0]
-			v_1_1 := v_1.Args[1]
-			for _i1 := 0; _i1 <= 1; _i1, v_1_0, v_1_1 = _i1+1, v_1_1, v_1_0 {
-				if v_1_0.Op != OpAMD64SHRL {
-					continue
-				}
-				_ = v_1_0.Args[1]
-				if x != v_1_0.Args[0] {
-					continue
-				}
-				v_1_0_1 := v_1_0.Args[1]
-				if v_1_0_1.Op != OpAMD64NEGQ || y != v_1_0_1.Args[0] || v_1_1.Op != OpAMD64SBBLcarrymask {
-					continue
-				}
-				v_1_1_0 := v_1_1.Args[0]
-				if v_1_1_0.Op != OpAMD64CMPQconst || auxIntToInt32(v_1_1_0.AuxInt) != 32 {
-					continue
-				}
-				v_1_1_0_0 := v_1_1_0.Args[0]
-				if v_1_1_0_0.Op != OpAMD64NEGQ {
-					continue
-				}
-				v_1_1_0_0_0 := v_1_1_0_0.Args[0]
-				if v_1_1_0_0_0.Op != OpAMD64ADDQconst || auxIntToInt32(v_1_1_0_0_0.AuxInt) != -32 {
-					continue
-				}
-				v_1_1_0_0_0_0 := v_1_1_0_0_0.Args[0]
-				if v_1_1_0_0_0_0.Op != OpAMD64ANDQconst || auxIntToInt32(v_1_1_0_0_0_0.AuxInt) != 31 || y != v_1_1_0_0_0_0.Args[0] {
-					continue
-				}
-				v.reset(OpAMD64ROLL)
-				v.AddArg2(x, y)
-				return true
-			}
-		}
-		break
-	}
-	// match: (ORL (SHLL x y) (ANDL (SHRL x (NEGL y)) (SBBLcarrymask (CMPLconst (NEGL (ADDLconst (ANDLconst y [31]) [-32])) [32]))))
-	// result: (ROLL x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHLL {
-				continue
-			}
-			y := v_0.Args[1]
-			x := v_0.Args[0]
-			if v_1.Op != OpAMD64ANDL {
-				continue
-			}
-			_ = v_1.Args[1]
-			v_1_0 := v_1.Args[0]
-			v_1_1 := v_1.Args[1]
-			for _i1 := 0; _i1 <= 1; _i1, v_1_0, v_1_1 = _i1+1, v_1_1, v_1_0 {
-				if v_1_0.Op != OpAMD64SHRL {
-					continue
-				}
-				_ = v_1_0.Args[1]
-				if x != v_1_0.Args[0] {
-					continue
-				}
-				v_1_0_1 := v_1_0.Args[1]
-				if v_1_0_1.Op != OpAMD64NEGL || y != v_1_0_1.Args[0] || v_1_1.Op != OpAMD64SBBLcarrymask {
-					continue
-				}
-				v_1_1_0 := v_1_1.Args[0]
-				if v_1_1_0.Op != OpAMD64CMPLconst || auxIntToInt32(v_1_1_0.AuxInt) != 32 {
-					continue
-				}
-				v_1_1_0_0 := v_1_1_0.Args[0]
-				if v_1_1_0_0.Op != OpAMD64NEGL {
-					continue
-				}
-				v_1_1_0_0_0 := v_1_1_0_0.Args[0]
-				if v_1_1_0_0_0.Op != OpAMD64ADDLconst || auxIntToInt32(v_1_1_0_0_0.AuxInt) != -32 {
-					continue
-				}
-				v_1_1_0_0_0_0 := v_1_1_0_0_0.Args[0]
-				if v_1_1_0_0_0_0.Op != OpAMD64ANDLconst || auxIntToInt32(v_1_1_0_0_0_0.AuxInt) != 31 || y != v_1_1_0_0_0_0.Args[0] {
-					continue
-				}
-				v.reset(OpAMD64ROLL)
-				v.AddArg2(x, y)
-				return true
-			}
-		}
-		break
-	}
-	// match: (ORL (SHRL x y) (ANDL (SHLL x (NEGQ y)) (SBBLcarrymask (CMPQconst (NEGQ (ADDQconst (ANDQconst y [31]) [-32])) [32]))))
-	// result: (RORL x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHRL {
-				continue
-			}
-			y := v_0.Args[1]
-			x := v_0.Args[0]
-			if v_1.Op != OpAMD64ANDL {
-				continue
-			}
-			_ = v_1.Args[1]
-			v_1_0 := v_1.Args[0]
-			v_1_1 := v_1.Args[1]
-			for _i1 := 0; _i1 <= 1; _i1, v_1_0, v_1_1 = _i1+1, v_1_1, v_1_0 {
-				if v_1_0.Op != OpAMD64SHLL {
-					continue
-				}
-				_ = v_1_0.Args[1]
-				if x != v_1_0.Args[0] {
-					continue
-				}
-				v_1_0_1 := v_1_0.Args[1]
-				if v_1_0_1.Op != OpAMD64NEGQ || y != v_1_0_1.Args[0] || v_1_1.Op != OpAMD64SBBLcarrymask {
-					continue
-				}
-				v_1_1_0 := v_1_1.Args[0]
-				if v_1_1_0.Op != OpAMD64CMPQconst || auxIntToInt32(v_1_1_0.AuxInt) != 32 {
-					continue
-				}
-				v_1_1_0_0 := v_1_1_0.Args[0]
-				if v_1_1_0_0.Op != OpAMD64NEGQ {
-					continue
-				}
-				v_1_1_0_0_0 := v_1_1_0_0.Args[0]
-				if v_1_1_0_0_0.Op != OpAMD64ADDQconst || auxIntToInt32(v_1_1_0_0_0.AuxInt) != -32 {
-					continue
-				}
-				v_1_1_0_0_0_0 := v_1_1_0_0_0.Args[0]
-				if v_1_1_0_0_0_0.Op != OpAMD64ANDQconst || auxIntToInt32(v_1_1_0_0_0_0.AuxInt) != 31 || y != v_1_1_0_0_0_0.Args[0] {
-					continue
-				}
-				v.reset(OpAMD64RORL)
-				v.AddArg2(x, y)
-				return true
-			}
-		}
-		break
-	}
-	// match: (ORL (SHRL x y) (ANDL (SHLL x (NEGL y)) (SBBLcarrymask (CMPLconst (NEGL (ADDLconst (ANDLconst y [31]) [-32])) [32]))))
-	// result: (RORL x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHRL {
-				continue
-			}
-			y := v_0.Args[1]
-			x := v_0.Args[0]
-			if v_1.Op != OpAMD64ANDL {
-				continue
-			}
-			_ = v_1.Args[1]
-			v_1_0 := v_1.Args[0]
-			v_1_1 := v_1.Args[1]
-			for _i1 := 0; _i1 <= 1; _i1, v_1_0, v_1_1 = _i1+1, v_1_1, v_1_0 {
-				if v_1_0.Op != OpAMD64SHLL {
-					continue
-				}
-				_ = v_1_0.Args[1]
-				if x != v_1_0.Args[0] {
-					continue
-				}
-				v_1_0_1 := v_1_0.Args[1]
-				if v_1_0_1.Op != OpAMD64NEGL || y != v_1_0_1.Args[0] || v_1_1.Op != OpAMD64SBBLcarrymask {
-					continue
-				}
-				v_1_1_0 := v_1_1.Args[0]
-				if v_1_1_0.Op != OpAMD64CMPLconst || auxIntToInt32(v_1_1_0.AuxInt) != 32 {
-					continue
-				}
-				v_1_1_0_0 := v_1_1_0.Args[0]
-				if v_1_1_0_0.Op != OpAMD64NEGL {
-					continue
-				}
-				v_1_1_0_0_0 := v_1_1_0_0.Args[0]
-				if v_1_1_0_0_0.Op != OpAMD64ADDLconst || auxIntToInt32(v_1_1_0_0_0.AuxInt) != -32 {
-					continue
-				}
-				v_1_1_0_0_0_0 := v_1_1_0_0_0.Args[0]
-				if v_1_1_0_0_0_0.Op != OpAMD64ANDLconst || auxIntToInt32(v_1_1_0_0_0_0.AuxInt) != 31 || y != v_1_1_0_0_0_0.Args[0] {
-					continue
-				}
-				v.reset(OpAMD64RORL)
-				v.AddArg2(x, y)
-				return true
-			}
-		}
-		break
-	}
-	// match: (ORL (SHLXL x y) (ANDL (SHRXL x (NEGQ y)) (SBBLcarrymask (CMPQconst (NEGQ (ADDQconst (ANDQconst y [31]) [-32])) [32]))))
-	// result: (ROLL x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHLXL {
-				continue
-			}
-			y := v_0.Args[1]
-			x := v_0.Args[0]
-			if v_1.Op != OpAMD64ANDL {
-				continue
-			}
-			_ = v_1.Args[1]
-			v_1_0 := v_1.Args[0]
-			v_1_1 := v_1.Args[1]
-			for _i1 := 0; _i1 <= 1; _i1, v_1_0, v_1_1 = _i1+1, v_1_1, v_1_0 {
-				if v_1_0.Op != OpAMD64SHRXL {
-					continue
-				}
-				_ = v_1_0.Args[1]
-				if x != v_1_0.Args[0] {
-					continue
-				}
-				v_1_0_1 := v_1_0.Args[1]
-				if v_1_0_1.Op != OpAMD64NEGQ || y != v_1_0_1.Args[0] || v_1_1.Op != OpAMD64SBBLcarrymask {
-					continue
-				}
-				v_1_1_0 := v_1_1.Args[0]
-				if v_1_1_0.Op != OpAMD64CMPQconst || auxIntToInt32(v_1_1_0.AuxInt) != 32 {
-					continue
-				}
-				v_1_1_0_0 := v_1_1_0.Args[0]
-				if v_1_1_0_0.Op != OpAMD64NEGQ {
-					continue
-				}
-				v_1_1_0_0_0 := v_1_1_0_0.Args[0]
-				if v_1_1_0_0_0.Op != OpAMD64ADDQconst || auxIntToInt32(v_1_1_0_0_0.AuxInt) != -32 {
-					continue
-				}
-				v_1_1_0_0_0_0 := v_1_1_0_0_0.Args[0]
-				if v_1_1_0_0_0_0.Op != OpAMD64ANDQconst || auxIntToInt32(v_1_1_0_0_0_0.AuxInt) != 31 || y != v_1_1_0_0_0_0.Args[0] {
-					continue
-				}
-				v.reset(OpAMD64ROLL)
-				v.AddArg2(x, y)
-				return true
-			}
-		}
-		break
-	}
-	// match: (ORL (SHLXL x y) (ANDL (SHRXL x (NEGL y)) (SBBLcarrymask (CMPLconst (NEGL (ADDLconst (ANDLconst y [31]) [-32])) [32]))))
-	// result: (ROLL x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHLXL {
-				continue
-			}
-			y := v_0.Args[1]
-			x := v_0.Args[0]
-			if v_1.Op != OpAMD64ANDL {
-				continue
-			}
-			_ = v_1.Args[1]
-			v_1_0 := v_1.Args[0]
-			v_1_1 := v_1.Args[1]
-			for _i1 := 0; _i1 <= 1; _i1, v_1_0, v_1_1 = _i1+1, v_1_1, v_1_0 {
-				if v_1_0.Op != OpAMD64SHRXL {
-					continue
-				}
-				_ = v_1_0.Args[1]
-				if x != v_1_0.Args[0] {
-					continue
-				}
-				v_1_0_1 := v_1_0.Args[1]
-				if v_1_0_1.Op != OpAMD64NEGL || y != v_1_0_1.Args[0] || v_1_1.Op != OpAMD64SBBLcarrymask {
-					continue
-				}
-				v_1_1_0 := v_1_1.Args[0]
-				if v_1_1_0.Op != OpAMD64CMPLconst || auxIntToInt32(v_1_1_0.AuxInt) != 32 {
-					continue
-				}
-				v_1_1_0_0 := v_1_1_0.Args[0]
-				if v_1_1_0_0.Op != OpAMD64NEGL {
-					continue
-				}
-				v_1_1_0_0_0 := v_1_1_0_0.Args[0]
-				if v_1_1_0_0_0.Op != OpAMD64ADDLconst || auxIntToInt32(v_1_1_0_0_0.AuxInt) != -32 {
-					continue
-				}
-				v_1_1_0_0_0_0 := v_1_1_0_0_0.Args[0]
-				if v_1_1_0_0_0_0.Op != OpAMD64ANDLconst || auxIntToInt32(v_1_1_0_0_0_0.AuxInt) != 31 || y != v_1_1_0_0_0_0.Args[0] {
-					continue
-				}
-				v.reset(OpAMD64ROLL)
-				v.AddArg2(x, y)
-				return true
-			}
-		}
-		break
-	}
-	// match: (ORL (SHRXL x y) (ANDL (SHLXL x (NEGQ y)) (SBBLcarrymask (CMPQconst (NEGQ (ADDQconst (ANDQconst y [31]) [-32])) [32]))))
-	// result: (RORL x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHRXL {
-				continue
-			}
-			y := v_0.Args[1]
-			x := v_0.Args[0]
-			if v_1.Op != OpAMD64ANDL {
-				continue
-			}
-			_ = v_1.Args[1]
-			v_1_0 := v_1.Args[0]
-			v_1_1 := v_1.Args[1]
-			for _i1 := 0; _i1 <= 1; _i1, v_1_0, v_1_1 = _i1+1, v_1_1, v_1_0 {
-				if v_1_0.Op != OpAMD64SHLXL {
-					continue
-				}
-				_ = v_1_0.Args[1]
-				if x != v_1_0.Args[0] {
-					continue
-				}
-				v_1_0_1 := v_1_0.Args[1]
-				if v_1_0_1.Op != OpAMD64NEGQ || y != v_1_0_1.Args[0] || v_1_1.Op != OpAMD64SBBLcarrymask {
-					continue
-				}
-				v_1_1_0 := v_1_1.Args[0]
-				if v_1_1_0.Op != OpAMD64CMPQconst || auxIntToInt32(v_1_1_0.AuxInt) != 32 {
-					continue
-				}
-				v_1_1_0_0 := v_1_1_0.Args[0]
-				if v_1_1_0_0.Op != OpAMD64NEGQ {
-					continue
-				}
-				v_1_1_0_0_0 := v_1_1_0_0.Args[0]
-				if v_1_1_0_0_0.Op != OpAMD64ADDQconst || auxIntToInt32(v_1_1_0_0_0.AuxInt) != -32 {
-					continue
-				}
-				v_1_1_0_0_0_0 := v_1_1_0_0_0.Args[0]
-				if v_1_1_0_0_0_0.Op != OpAMD64ANDQconst || auxIntToInt32(v_1_1_0_0_0_0.AuxInt) != 31 || y != v_1_1_0_0_0_0.Args[0] {
-					continue
-				}
-				v.reset(OpAMD64RORL)
-				v.AddArg2(x, y)
-				return true
-			}
-		}
-		break
-	}
-	// match: (ORL (SHRXL x y) (ANDL (SHLXL x (NEGL y)) (SBBLcarrymask (CMPLconst (NEGL (ADDLconst (ANDLconst y [31]) [-32])) [32]))))
-	// result: (RORL x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHRXL {
-				continue
-			}
-			y := v_0.Args[1]
-			x := v_0.Args[0]
-			if v_1.Op != OpAMD64ANDL {
-				continue
-			}
-			_ = v_1.Args[1]
-			v_1_0 := v_1.Args[0]
-			v_1_1 := v_1.Args[1]
-			for _i1 := 0; _i1 <= 1; _i1, v_1_0, v_1_1 = _i1+1, v_1_1, v_1_0 {
-				if v_1_0.Op != OpAMD64SHLXL {
-					continue
-				}
-				_ = v_1_0.Args[1]
-				if x != v_1_0.Args[0] {
-					continue
-				}
-				v_1_0_1 := v_1_0.Args[1]
-				if v_1_0_1.Op != OpAMD64NEGL || y != v_1_0_1.Args[0] || v_1_1.Op != OpAMD64SBBLcarrymask {
-					continue
-				}
-				v_1_1_0 := v_1_1.Args[0]
-				if v_1_1_0.Op != OpAMD64CMPLconst || auxIntToInt32(v_1_1_0.AuxInt) != 32 {
-					continue
-				}
-				v_1_1_0_0 := v_1_1_0.Args[0]
-				if v_1_1_0_0.Op != OpAMD64NEGL {
-					continue
-				}
-				v_1_1_0_0_0 := v_1_1_0_0.Args[0]
-				if v_1_1_0_0_0.Op != OpAMD64ADDLconst || auxIntToInt32(v_1_1_0_0_0.AuxInt) != -32 {
-					continue
-				}
-				v_1_1_0_0_0_0 := v_1_1_0_0_0.Args[0]
-				if v_1_1_0_0_0_0.Op != OpAMD64ANDLconst || auxIntToInt32(v_1_1_0_0_0_0.AuxInt) != 31 || y != v_1_1_0_0_0_0.Args[0] {
-					continue
-				}
-				v.reset(OpAMD64RORL)
-				v.AddArg2(x, y)
-				return true
-			}
-		}
-		break
-	}
-	// match: (ORL (SHLL x (ANDQconst y [15])) (ANDL (SHRW x (NEGQ (ADDQconst (ANDQconst y [15]) [-16]))) (SBBLcarrymask (CMPQconst (NEGQ (ADDQconst (ANDQconst y [15]) [-16])) [16]))))
-	// cond: v.Type.Size() == 2
-	// result: (ROLW x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHLL {
-				continue
-			}
-			_ = v_0.Args[1]
-			x := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpAMD64ANDQconst || auxIntToInt32(v_0_1.AuxInt) != 15 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpAMD64ANDL {
-				continue
-			}
-			_ = v_1.Args[1]
-			v_1_0 := v_1.Args[0]
-			v_1_1 := v_1.Args[1]
-			for _i1 := 0; _i1 <= 1; _i1, v_1_0, v_1_1 = _i1+1, v_1_1, v_1_0 {
-				if v_1_0.Op != OpAMD64SHRW {
-					continue
-				}
-				_ = v_1_0.Args[1]
-				if x != v_1_0.Args[0] {
-					continue
-				}
-				v_1_0_1 := v_1_0.Args[1]
-				if v_1_0_1.Op != OpAMD64NEGQ {
-					continue
-				}
-				v_1_0_1_0 := v_1_0_1.Args[0]
-				if v_1_0_1_0.Op != OpAMD64ADDQconst || auxIntToInt32(v_1_0_1_0.AuxInt) != -16 {
-					continue
-				}
-				v_1_0_1_0_0 := v_1_0_1_0.Args[0]
-				if v_1_0_1_0_0.Op != OpAMD64ANDQconst || auxIntToInt32(v_1_0_1_0_0.AuxInt) != 15 || y != v_1_0_1_0_0.Args[0] || v_1_1.Op != OpAMD64SBBLcarrymask {
-					continue
-				}
-				v_1_1_0 := v_1_1.Args[0]
-				if v_1_1_0.Op != OpAMD64CMPQconst || auxIntToInt32(v_1_1_0.AuxInt) != 16 {
-					continue
-				}
-				v_1_1_0_0 := v_1_1_0.Args[0]
-				if v_1_1_0_0.Op != OpAMD64NEGQ {
-					continue
-				}
-				v_1_1_0_0_0 := v_1_1_0_0.Args[0]
-				if v_1_1_0_0_0.Op != OpAMD64ADDQconst || auxIntToInt32(v_1_1_0_0_0.AuxInt) != -16 {
-					continue
-				}
-				v_1_1_0_0_0_0 := v_1_1_0_0_0.Args[0]
-				if v_1_1_0_0_0_0.Op != OpAMD64ANDQconst || auxIntToInt32(v_1_1_0_0_0_0.AuxInt) != 15 || y != v_1_1_0_0_0_0.Args[0] || !(v.Type.Size() == 2) {
-					continue
-				}
-				v.reset(OpAMD64ROLW)
-				v.AddArg2(x, y)
-				return true
-			}
-		}
-		break
-	}
-	// match: (ORL (SHLL x (ANDLconst y [15])) (ANDL (SHRW x (NEGL (ADDLconst (ANDLconst y [15]) [-16]))) (SBBLcarrymask (CMPLconst (NEGL (ADDLconst (ANDLconst y [15]) [-16])) [16]))))
-	// cond: v.Type.Size() == 2
-	// result: (ROLW x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHLL {
-				continue
-			}
-			_ = v_0.Args[1]
-			x := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpAMD64ANDLconst || auxIntToInt32(v_0_1.AuxInt) != 15 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpAMD64ANDL {
-				continue
-			}
-			_ = v_1.Args[1]
-			v_1_0 := v_1.Args[0]
-			v_1_1 := v_1.Args[1]
-			for _i1 := 0; _i1 <= 1; _i1, v_1_0, v_1_1 = _i1+1, v_1_1, v_1_0 {
-				if v_1_0.Op != OpAMD64SHRW {
-					continue
-				}
-				_ = v_1_0.Args[1]
-				if x != v_1_0.Args[0] {
-					continue
-				}
-				v_1_0_1 := v_1_0.Args[1]
-				if v_1_0_1.Op != OpAMD64NEGL {
-					continue
-				}
-				v_1_0_1_0 := v_1_0_1.Args[0]
-				if v_1_0_1_0.Op != OpAMD64ADDLconst || auxIntToInt32(v_1_0_1_0.AuxInt) != -16 {
-					continue
-				}
-				v_1_0_1_0_0 := v_1_0_1_0.Args[0]
-				if v_1_0_1_0_0.Op != OpAMD64ANDLconst || auxIntToInt32(v_1_0_1_0_0.AuxInt) != 15 || y != v_1_0_1_0_0.Args[0] || v_1_1.Op != OpAMD64SBBLcarrymask {
-					continue
-				}
-				v_1_1_0 := v_1_1.Args[0]
-				if v_1_1_0.Op != OpAMD64CMPLconst || auxIntToInt32(v_1_1_0.AuxInt) != 16 {
-					continue
-				}
-				v_1_1_0_0 := v_1_1_0.Args[0]
-				if v_1_1_0_0.Op != OpAMD64NEGL {
-					continue
-				}
-				v_1_1_0_0_0 := v_1_1_0_0.Args[0]
-				if v_1_1_0_0_0.Op != OpAMD64ADDLconst || auxIntToInt32(v_1_1_0_0_0.AuxInt) != -16 {
-					continue
-				}
-				v_1_1_0_0_0_0 := v_1_1_0_0_0.Args[0]
-				if v_1_1_0_0_0_0.Op != OpAMD64ANDLconst || auxIntToInt32(v_1_1_0_0_0_0.AuxInt) != 15 || y != v_1_1_0_0_0_0.Args[0] || !(v.Type.Size() == 2) {
-					continue
-				}
-				v.reset(OpAMD64ROLW)
-				v.AddArg2(x, y)
-				return true
-			}
-		}
-		break
-	}
-	// match: (ORL (SHRW x (ANDQconst y [15])) (SHLL x (NEGQ (ADDQconst (ANDQconst y [15]) [-16]))))
-	// cond: v.Type.Size() == 2
-	// result: (RORW x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHRW {
-				continue
-			}
-			_ = v_0.Args[1]
-			x := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpAMD64ANDQconst || auxIntToInt32(v_0_1.AuxInt) != 15 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpAMD64SHLL {
-				continue
-			}
-			_ = v_1.Args[1]
-			if x != v_1.Args[0] {
-				continue
-			}
-			v_1_1 := v_1.Args[1]
-			if v_1_1.Op != OpAMD64NEGQ {
-				continue
-			}
-			v_1_1_0 := v_1_1.Args[0]
-			if v_1_1_0.Op != OpAMD64ADDQconst || auxIntToInt32(v_1_1_0.AuxInt) != -16 {
-				continue
-			}
-			v_1_1_0_0 := v_1_1_0.Args[0]
-			if v_1_1_0_0.Op != OpAMD64ANDQconst || auxIntToInt32(v_1_1_0_0.AuxInt) != 15 || y != v_1_1_0_0.Args[0] || !(v.Type.Size() == 2) {
-				continue
-			}
-			v.reset(OpAMD64RORW)
-			v.AddArg2(x, y)
-			return true
-		}
-		break
-	}
-	// match: (ORL (SHRW x (ANDLconst y [15])) (SHLL x (NEGL (ADDLconst (ANDLconst y [15]) [-16]))))
-	// cond: v.Type.Size() == 2
-	// result: (RORW x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHRW {
-				continue
-			}
-			_ = v_0.Args[1]
-			x := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpAMD64ANDLconst || auxIntToInt32(v_0_1.AuxInt) != 15 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpAMD64SHLL {
-				continue
-			}
-			_ = v_1.Args[1]
-			if x != v_1.Args[0] {
-				continue
-			}
-			v_1_1 := v_1.Args[1]
-			if v_1_1.Op != OpAMD64NEGL {
-				continue
-			}
-			v_1_1_0 := v_1_1.Args[0]
-			if v_1_1_0.Op != OpAMD64ADDLconst || auxIntToInt32(v_1_1_0.AuxInt) != -16 {
-				continue
-			}
-			v_1_1_0_0 := v_1_1_0.Args[0]
-			if v_1_1_0_0.Op != OpAMD64ANDLconst || auxIntToInt32(v_1_1_0_0.AuxInt) != 15 || y != v_1_1_0_0.Args[0] || !(v.Type.Size() == 2) {
-				continue
-			}
-			v.reset(OpAMD64RORW)
-			v.AddArg2(x, y)
-			return true
-		}
-		break
-	}
-	// match: (ORL (SHLXL x (ANDQconst y [15])) (ANDL (SHRW x (NEGQ (ADDQconst (ANDQconst y [15]) [-16]))) (SBBLcarrymask (CMPQconst (NEGQ (ADDQconst (ANDQconst y [15]) [-16])) [16]))))
-	// cond: v.Type.Size() == 2
-	// result: (ROLW x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHLXL {
-				continue
-			}
-			_ = v_0.Args[1]
-			x := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpAMD64ANDQconst || auxIntToInt32(v_0_1.AuxInt) != 15 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpAMD64ANDL {
-				continue
-			}
-			_ = v_1.Args[1]
-			v_1_0 := v_1.Args[0]
-			v_1_1 := v_1.Args[1]
-			for _i1 := 0; _i1 <= 1; _i1, v_1_0, v_1_1 = _i1+1, v_1_1, v_1_0 {
-				if v_1_0.Op != OpAMD64SHRW {
-					continue
-				}
-				_ = v_1_0.Args[1]
-				if x != v_1_0.Args[0] {
-					continue
-				}
-				v_1_0_1 := v_1_0.Args[1]
-				if v_1_0_1.Op != OpAMD64NEGQ {
-					continue
-				}
-				v_1_0_1_0 := v_1_0_1.Args[0]
-				if v_1_0_1_0.Op != OpAMD64ADDQconst || auxIntToInt32(v_1_0_1_0.AuxInt) != -16 {
-					continue
-				}
-				v_1_0_1_0_0 := v_1_0_1_0.Args[0]
-				if v_1_0_1_0_0.Op != OpAMD64ANDQconst || auxIntToInt32(v_1_0_1_0_0.AuxInt) != 15 || y != v_1_0_1_0_0.Args[0] || v_1_1.Op != OpAMD64SBBLcarrymask {
-					continue
-				}
-				v_1_1_0 := v_1_1.Args[0]
-				if v_1_1_0.Op != OpAMD64CMPQconst || auxIntToInt32(v_1_1_0.AuxInt) != 16 {
-					continue
-				}
-				v_1_1_0_0 := v_1_1_0.Args[0]
-				if v_1_1_0_0.Op != OpAMD64NEGQ {
-					continue
-				}
-				v_1_1_0_0_0 := v_1_1_0_0.Args[0]
-				if v_1_1_0_0_0.Op != OpAMD64ADDQconst || auxIntToInt32(v_1_1_0_0_0.AuxInt) != -16 {
-					continue
-				}
-				v_1_1_0_0_0_0 := v_1_1_0_0_0.Args[0]
-				if v_1_1_0_0_0_0.Op != OpAMD64ANDQconst || auxIntToInt32(v_1_1_0_0_0_0.AuxInt) != 15 || y != v_1_1_0_0_0_0.Args[0] || !(v.Type.Size() == 2) {
-					continue
-				}
-				v.reset(OpAMD64ROLW)
-				v.AddArg2(x, y)
-				return true
-			}
-		}
-		break
-	}
-	// match: (ORL (SHLXL x (ANDLconst y [15])) (ANDL (SHRW x (NEGL (ADDLconst (ANDLconst y [15]) [-16]))) (SBBLcarrymask (CMPLconst (NEGL (ADDLconst (ANDLconst y [15]) [-16])) [16]))))
-	// cond: v.Type.Size() == 2
-	// result: (ROLW x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHLXL {
-				continue
-			}
-			_ = v_0.Args[1]
-			x := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpAMD64ANDLconst || auxIntToInt32(v_0_1.AuxInt) != 15 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpAMD64ANDL {
-				continue
-			}
-			_ = v_1.Args[1]
-			v_1_0 := v_1.Args[0]
-			v_1_1 := v_1.Args[1]
-			for _i1 := 0; _i1 <= 1; _i1, v_1_0, v_1_1 = _i1+1, v_1_1, v_1_0 {
-				if v_1_0.Op != OpAMD64SHRW {
-					continue
-				}
-				_ = v_1_0.Args[1]
-				if x != v_1_0.Args[0] {
-					continue
-				}
-				v_1_0_1 := v_1_0.Args[1]
-				if v_1_0_1.Op != OpAMD64NEGL {
-					continue
-				}
-				v_1_0_1_0 := v_1_0_1.Args[0]
-				if v_1_0_1_0.Op != OpAMD64ADDLconst || auxIntToInt32(v_1_0_1_0.AuxInt) != -16 {
-					continue
-				}
-				v_1_0_1_0_0 := v_1_0_1_0.Args[0]
-				if v_1_0_1_0_0.Op != OpAMD64ANDLconst || auxIntToInt32(v_1_0_1_0_0.AuxInt) != 15 || y != v_1_0_1_0_0.Args[0] || v_1_1.Op != OpAMD64SBBLcarrymask {
-					continue
-				}
-				v_1_1_0 := v_1_1.Args[0]
-				if v_1_1_0.Op != OpAMD64CMPLconst || auxIntToInt32(v_1_1_0.AuxInt) != 16 {
-					continue
-				}
-				v_1_1_0_0 := v_1_1_0.Args[0]
-				if v_1_1_0_0.Op != OpAMD64NEGL {
-					continue
-				}
-				v_1_1_0_0_0 := v_1_1_0_0.Args[0]
-				if v_1_1_0_0_0.Op != OpAMD64ADDLconst || auxIntToInt32(v_1_1_0_0_0.AuxInt) != -16 {
-					continue
-				}
-				v_1_1_0_0_0_0 := v_1_1_0_0_0.Args[0]
-				if v_1_1_0_0_0_0.Op != OpAMD64ANDLconst || auxIntToInt32(v_1_1_0_0_0_0.AuxInt) != 15 || y != v_1_1_0_0_0_0.Args[0] || !(v.Type.Size() == 2) {
-					continue
-				}
-				v.reset(OpAMD64ROLW)
-				v.AddArg2(x, y)
-				return true
-			}
-		}
-		break
-	}
-	// match: (ORL (SHRW x (ANDQconst y [15])) (SHLXL x (NEGQ (ADDQconst (ANDQconst y [15]) [-16]))))
-	// cond: v.Type.Size() == 2
-	// result: (RORW x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHRW {
-				continue
-			}
-			_ = v_0.Args[1]
-			x := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpAMD64ANDQconst || auxIntToInt32(v_0_1.AuxInt) != 15 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpAMD64SHLXL {
-				continue
-			}
-			_ = v_1.Args[1]
-			if x != v_1.Args[0] {
-				continue
-			}
-			v_1_1 := v_1.Args[1]
-			if v_1_1.Op != OpAMD64NEGQ {
-				continue
-			}
-			v_1_1_0 := v_1_1.Args[0]
-			if v_1_1_0.Op != OpAMD64ADDQconst || auxIntToInt32(v_1_1_0.AuxInt) != -16 {
-				continue
-			}
-			v_1_1_0_0 := v_1_1_0.Args[0]
-			if v_1_1_0_0.Op != OpAMD64ANDQconst || auxIntToInt32(v_1_1_0_0.AuxInt) != 15 || y != v_1_1_0_0.Args[0] || !(v.Type.Size() == 2) {
-				continue
-			}
-			v.reset(OpAMD64RORW)
-			v.AddArg2(x, y)
-			return true
-		}
-		break
-	}
-	// match: (ORL (SHRW x (ANDLconst y [15])) (SHLXL x (NEGL (ADDLconst (ANDLconst y [15]) [-16]))))
-	// cond: v.Type.Size() == 2
-	// result: (RORW x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHRW {
-				continue
-			}
-			_ = v_0.Args[1]
-			x := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpAMD64ANDLconst || auxIntToInt32(v_0_1.AuxInt) != 15 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpAMD64SHLXL {
-				continue
-			}
-			_ = v_1.Args[1]
-			if x != v_1.Args[0] {
-				continue
-			}
-			v_1_1 := v_1.Args[1]
-			if v_1_1.Op != OpAMD64NEGL {
-				continue
-			}
-			v_1_1_0 := v_1_1.Args[0]
-			if v_1_1_0.Op != OpAMD64ADDLconst || auxIntToInt32(v_1_1_0.AuxInt) != -16 {
-				continue
-			}
-			v_1_1_0_0 := v_1_1_0.Args[0]
-			if v_1_1_0_0.Op != OpAMD64ANDLconst || auxIntToInt32(v_1_1_0_0.AuxInt) != 15 || y != v_1_1_0_0.Args[0] || !(v.Type.Size() == 2) {
-				continue
-			}
-			v.reset(OpAMD64RORW)
-			v.AddArg2(x, y)
-			return true
-		}
-		break
-	}
-	// match: (ORL (SHLL x (ANDQconst y [ 7])) (ANDL (SHRB x (NEGQ (ADDQconst (ANDQconst y [ 7]) [ -8]))) (SBBLcarrymask (CMPQconst (NEGQ (ADDQconst (ANDQconst y [ 7]) [ -8])) [ 8]))))
-	// cond: v.Type.Size() == 1
-	// result: (ROLB x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHLL {
-				continue
-			}
-			_ = v_0.Args[1]
-			x := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpAMD64ANDQconst || auxIntToInt32(v_0_1.AuxInt) != 7 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpAMD64ANDL {
-				continue
-			}
-			_ = v_1.Args[1]
-			v_1_0 := v_1.Args[0]
-			v_1_1 := v_1.Args[1]
-			for _i1 := 0; _i1 <= 1; _i1, v_1_0, v_1_1 = _i1+1, v_1_1, v_1_0 {
-				if v_1_0.Op != OpAMD64SHRB {
-					continue
-				}
-				_ = v_1_0.Args[1]
-				if x != v_1_0.Args[0] {
-					continue
-				}
-				v_1_0_1 := v_1_0.Args[1]
-				if v_1_0_1.Op != OpAMD64NEGQ {
-					continue
-				}
-				v_1_0_1_0 := v_1_0_1.Args[0]
-				if v_1_0_1_0.Op != OpAMD64ADDQconst || auxIntToInt32(v_1_0_1_0.AuxInt) != -8 {
-					continue
-				}
-				v_1_0_1_0_0 := v_1_0_1_0.Args[0]
-				if v_1_0_1_0_0.Op != OpAMD64ANDQconst || auxIntToInt32(v_1_0_1_0_0.AuxInt) != 7 || y != v_1_0_1_0_0.Args[0] || v_1_1.Op != OpAMD64SBBLcarrymask {
-					continue
-				}
-				v_1_1_0 := v_1_1.Args[0]
-				if v_1_1_0.Op != OpAMD64CMPQconst || auxIntToInt32(v_1_1_0.AuxInt) != 8 {
-					continue
-				}
-				v_1_1_0_0 := v_1_1_0.Args[0]
-				if v_1_1_0_0.Op != OpAMD64NEGQ {
-					continue
-				}
-				v_1_1_0_0_0 := v_1_1_0_0.Args[0]
-				if v_1_1_0_0_0.Op != OpAMD64ADDQconst || auxIntToInt32(v_1_1_0_0_0.AuxInt) != -8 {
-					continue
-				}
-				v_1_1_0_0_0_0 := v_1_1_0_0_0.Args[0]
-				if v_1_1_0_0_0_0.Op != OpAMD64ANDQconst || auxIntToInt32(v_1_1_0_0_0_0.AuxInt) != 7 || y != v_1_1_0_0_0_0.Args[0] || !(v.Type.Size() == 1) {
-					continue
-				}
-				v.reset(OpAMD64ROLB)
-				v.AddArg2(x, y)
-				return true
-			}
-		}
-		break
-	}
-	// match: (ORL (SHLL x (ANDLconst y [ 7])) (ANDL (SHRB x (NEGL (ADDLconst (ANDLconst y [ 7]) [ -8]))) (SBBLcarrymask (CMPLconst (NEGL (ADDLconst (ANDLconst y [ 7]) [ -8])) [ 8]))))
-	// cond: v.Type.Size() == 1
-	// result: (ROLB x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHLL {
-				continue
-			}
-			_ = v_0.Args[1]
-			x := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpAMD64ANDLconst || auxIntToInt32(v_0_1.AuxInt) != 7 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpAMD64ANDL {
-				continue
-			}
-			_ = v_1.Args[1]
-			v_1_0 := v_1.Args[0]
-			v_1_1 := v_1.Args[1]
-			for _i1 := 0; _i1 <= 1; _i1, v_1_0, v_1_1 = _i1+1, v_1_1, v_1_0 {
-				if v_1_0.Op != OpAMD64SHRB {
-					continue
-				}
-				_ = v_1_0.Args[1]
-				if x != v_1_0.Args[0] {
-					continue
-				}
-				v_1_0_1 := v_1_0.Args[1]
-				if v_1_0_1.Op != OpAMD64NEGL {
-					continue
-				}
-				v_1_0_1_0 := v_1_0_1.Args[0]
-				if v_1_0_1_0.Op != OpAMD64ADDLconst || auxIntToInt32(v_1_0_1_0.AuxInt) != -8 {
-					continue
-				}
-				v_1_0_1_0_0 := v_1_0_1_0.Args[0]
-				if v_1_0_1_0_0.Op != OpAMD64ANDLconst || auxIntToInt32(v_1_0_1_0_0.AuxInt) != 7 || y != v_1_0_1_0_0.Args[0] || v_1_1.Op != OpAMD64SBBLcarrymask {
-					continue
-				}
-				v_1_1_0 := v_1_1.Args[0]
-				if v_1_1_0.Op != OpAMD64CMPLconst || auxIntToInt32(v_1_1_0.AuxInt) != 8 {
-					continue
-				}
-				v_1_1_0_0 := v_1_1_0.Args[0]
-				if v_1_1_0_0.Op != OpAMD64NEGL {
-					continue
-				}
-				v_1_1_0_0_0 := v_1_1_0_0.Args[0]
-				if v_1_1_0_0_0.Op != OpAMD64ADDLconst || auxIntToInt32(v_1_1_0_0_0.AuxInt) != -8 {
-					continue
-				}
-				v_1_1_0_0_0_0 := v_1_1_0_0_0.Args[0]
-				if v_1_1_0_0_0_0.Op != OpAMD64ANDLconst || auxIntToInt32(v_1_1_0_0_0_0.AuxInt) != 7 || y != v_1_1_0_0_0_0.Args[0] || !(v.Type.Size() == 1) {
-					continue
-				}
-				v.reset(OpAMD64ROLB)
-				v.AddArg2(x, y)
-				return true
-			}
-		}
-		break
-	}
-	// match: (ORL (SHRB x (ANDQconst y [ 7])) (SHLL x (NEGQ (ADDQconst (ANDQconst y [ 7]) [ -8]))))
-	// cond: v.Type.Size() == 1
-	// result: (RORB x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHRB {
-				continue
-			}
-			_ = v_0.Args[1]
-			x := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpAMD64ANDQconst || auxIntToInt32(v_0_1.AuxInt) != 7 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpAMD64SHLL {
-				continue
-			}
-			_ = v_1.Args[1]
-			if x != v_1.Args[0] {
-				continue
-			}
-			v_1_1 := v_1.Args[1]
-			if v_1_1.Op != OpAMD64NEGQ {
-				continue
-			}
-			v_1_1_0 := v_1_1.Args[0]
-			if v_1_1_0.Op != OpAMD64ADDQconst || auxIntToInt32(v_1_1_0.AuxInt) != -8 {
-				continue
-			}
-			v_1_1_0_0 := v_1_1_0.Args[0]
-			if v_1_1_0_0.Op != OpAMD64ANDQconst || auxIntToInt32(v_1_1_0_0.AuxInt) != 7 || y != v_1_1_0_0.Args[0] || !(v.Type.Size() == 1) {
-				continue
-			}
-			v.reset(OpAMD64RORB)
-			v.AddArg2(x, y)
-			return true
-		}
-		break
-	}
-	// match: (ORL (SHRB x (ANDLconst y [ 7])) (SHLL x (NEGL (ADDLconst (ANDLconst y [ 7]) [ -8]))))
-	// cond: v.Type.Size() == 1
-	// result: (RORB x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHRB {
-				continue
-			}
-			_ = v_0.Args[1]
-			x := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpAMD64ANDLconst || auxIntToInt32(v_0_1.AuxInt) != 7 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpAMD64SHLL {
-				continue
-			}
-			_ = v_1.Args[1]
-			if x != v_1.Args[0] {
-				continue
-			}
-			v_1_1 := v_1.Args[1]
-			if v_1_1.Op != OpAMD64NEGL {
-				continue
-			}
-			v_1_1_0 := v_1_1.Args[0]
-			if v_1_1_0.Op != OpAMD64ADDLconst || auxIntToInt32(v_1_1_0.AuxInt) != -8 {
-				continue
-			}
-			v_1_1_0_0 := v_1_1_0.Args[0]
-			if v_1_1_0_0.Op != OpAMD64ANDLconst || auxIntToInt32(v_1_1_0_0.AuxInt) != 7 || y != v_1_1_0_0.Args[0] || !(v.Type.Size() == 1) {
-				continue
-			}
-			v.reset(OpAMD64RORB)
-			v.AddArg2(x, y)
-			return true
-		}
-		break
-	}
-	// match: (ORL (SHLXL x (ANDQconst y [ 7])) (ANDL (SHRB x (NEGQ (ADDQconst (ANDQconst y [ 7]) [ -8]))) (SBBLcarrymask (CMPQconst (NEGQ (ADDQconst (ANDQconst y [ 7]) [ -8])) [ 8]))))
-	// cond: v.Type.Size() == 1
-	// result: (ROLB x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHLXL {
-				continue
-			}
-			_ = v_0.Args[1]
-			x := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpAMD64ANDQconst || auxIntToInt32(v_0_1.AuxInt) != 7 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpAMD64ANDL {
-				continue
-			}
-			_ = v_1.Args[1]
-			v_1_0 := v_1.Args[0]
-			v_1_1 := v_1.Args[1]
-			for _i1 := 0; _i1 <= 1; _i1, v_1_0, v_1_1 = _i1+1, v_1_1, v_1_0 {
-				if v_1_0.Op != OpAMD64SHRB {
-					continue
-				}
-				_ = v_1_0.Args[1]
-				if x != v_1_0.Args[0] {
-					continue
-				}
-				v_1_0_1 := v_1_0.Args[1]
-				if v_1_0_1.Op != OpAMD64NEGQ {
-					continue
-				}
-				v_1_0_1_0 := v_1_0_1.Args[0]
-				if v_1_0_1_0.Op != OpAMD64ADDQconst || auxIntToInt32(v_1_0_1_0.AuxInt) != -8 {
-					continue
-				}
-				v_1_0_1_0_0 := v_1_0_1_0.Args[0]
-				if v_1_0_1_0_0.Op != OpAMD64ANDQconst || auxIntToInt32(v_1_0_1_0_0.AuxInt) != 7 || y != v_1_0_1_0_0.Args[0] || v_1_1.Op != OpAMD64SBBLcarrymask {
-					continue
-				}
-				v_1_1_0 := v_1_1.Args[0]
-				if v_1_1_0.Op != OpAMD64CMPQconst || auxIntToInt32(v_1_1_0.AuxInt) != 8 {
-					continue
-				}
-				v_1_1_0_0 := v_1_1_0.Args[0]
-				if v_1_1_0_0.Op != OpAMD64NEGQ {
-					continue
-				}
-				v_1_1_0_0_0 := v_1_1_0_0.Args[0]
-				if v_1_1_0_0_0.Op != OpAMD64ADDQconst || auxIntToInt32(v_1_1_0_0_0.AuxInt) != -8 {
-					continue
-				}
-				v_1_1_0_0_0_0 := v_1_1_0_0_0.Args[0]
-				if v_1_1_0_0_0_0.Op != OpAMD64ANDQconst || auxIntToInt32(v_1_1_0_0_0_0.AuxInt) != 7 || y != v_1_1_0_0_0_0.Args[0] || !(v.Type.Size() == 1) {
-					continue
-				}
-				v.reset(OpAMD64ROLB)
-				v.AddArg2(x, y)
-				return true
-			}
-		}
-		break
-	}
-	// match: (ORL (SHLXL x (ANDLconst y [ 7])) (ANDL (SHRB x (NEGL (ADDLconst (ANDLconst y [ 7]) [ -8]))) (SBBLcarrymask (CMPLconst (NEGL (ADDLconst (ANDLconst y [ 7]) [ -8])) [ 8]))))
-	// cond: v.Type.Size() == 1
-	// result: (ROLB x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHLXL {
-				continue
-			}
-			_ = v_0.Args[1]
-			x := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpAMD64ANDLconst || auxIntToInt32(v_0_1.AuxInt) != 7 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpAMD64ANDL {
-				continue
-			}
-			_ = v_1.Args[1]
-			v_1_0 := v_1.Args[0]
-			v_1_1 := v_1.Args[1]
-			for _i1 := 0; _i1 <= 1; _i1, v_1_0, v_1_1 = _i1+1, v_1_1, v_1_0 {
-				if v_1_0.Op != OpAMD64SHRB {
-					continue
-				}
-				_ = v_1_0.Args[1]
-				if x != v_1_0.Args[0] {
-					continue
-				}
-				v_1_0_1 := v_1_0.Args[1]
-				if v_1_0_1.Op != OpAMD64NEGL {
-					continue
-				}
-				v_1_0_1_0 := v_1_0_1.Args[0]
-				if v_1_0_1_0.Op != OpAMD64ADDLconst || auxIntToInt32(v_1_0_1_0.AuxInt) != -8 {
-					continue
-				}
-				v_1_0_1_0_0 := v_1_0_1_0.Args[0]
-				if v_1_0_1_0_0.Op != OpAMD64ANDLconst || auxIntToInt32(v_1_0_1_0_0.AuxInt) != 7 || y != v_1_0_1_0_0.Args[0] || v_1_1.Op != OpAMD64SBBLcarrymask {
-					continue
-				}
-				v_1_1_0 := v_1_1.Args[0]
-				if v_1_1_0.Op != OpAMD64CMPLconst || auxIntToInt32(v_1_1_0.AuxInt) != 8 {
-					continue
-				}
-				v_1_1_0_0 := v_1_1_0.Args[0]
-				if v_1_1_0_0.Op != OpAMD64NEGL {
-					continue
-				}
-				v_1_1_0_0_0 := v_1_1_0_0.Args[0]
-				if v_1_1_0_0_0.Op != OpAMD64ADDLconst || auxIntToInt32(v_1_1_0_0_0.AuxInt) != -8 {
-					continue
-				}
-				v_1_1_0_0_0_0 := v_1_1_0_0_0.Args[0]
-				if v_1_1_0_0_0_0.Op != OpAMD64ANDLconst || auxIntToInt32(v_1_1_0_0_0_0.AuxInt) != 7 || y != v_1_1_0_0_0_0.Args[0] || !(v.Type.Size() == 1) {
-					continue
-				}
-				v.reset(OpAMD64ROLB)
-				v.AddArg2(x, y)
-				return true
-			}
-		}
-		break
-	}
-	// match: (ORL (SHRB x (ANDQconst y [ 7])) (SHLXL x (NEGQ (ADDQconst (ANDQconst y [ 7]) [ -8]))))
-	// cond: v.Type.Size() == 1
-	// result: (RORB x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHRB {
-				continue
-			}
-			_ = v_0.Args[1]
-			x := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpAMD64ANDQconst || auxIntToInt32(v_0_1.AuxInt) != 7 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpAMD64SHLXL {
-				continue
-			}
-			_ = v_1.Args[1]
-			if x != v_1.Args[0] {
-				continue
-			}
-			v_1_1 := v_1.Args[1]
-			if v_1_1.Op != OpAMD64NEGQ {
-				continue
-			}
-			v_1_1_0 := v_1_1.Args[0]
-			if v_1_1_0.Op != OpAMD64ADDQconst || auxIntToInt32(v_1_1_0.AuxInt) != -8 {
-				continue
-			}
-			v_1_1_0_0 := v_1_1_0.Args[0]
-			if v_1_1_0_0.Op != OpAMD64ANDQconst || auxIntToInt32(v_1_1_0_0.AuxInt) != 7 || y != v_1_1_0_0.Args[0] || !(v.Type.Size() == 1) {
-				continue
-			}
-			v.reset(OpAMD64RORB)
-			v.AddArg2(x, y)
-			return true
-		}
-		break
-	}
-	// match: (ORL (SHRB x (ANDLconst y [ 7])) (SHLXL x (NEGL (ADDLconst (ANDLconst y [ 7]) [ -8]))))
-	// cond: v.Type.Size() == 1
-	// result: (RORB x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHRB {
-				continue
-			}
-			_ = v_0.Args[1]
-			x := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpAMD64ANDLconst || auxIntToInt32(v_0_1.AuxInt) != 7 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpAMD64SHLXL {
-				continue
-			}
-			_ = v_1.Args[1]
-			if x != v_1.Args[0] {
-				continue
-			}
-			v_1_1 := v_1.Args[1]
-			if v_1_1.Op != OpAMD64NEGL {
-				continue
-			}
-			v_1_1_0 := v_1_1.Args[0]
-			if v_1_1_0.Op != OpAMD64ADDLconst || auxIntToInt32(v_1_1_0.AuxInt) != -8 {
-				continue
-			}
-			v_1_1_0_0 := v_1_1_0.Args[0]
-			if v_1_1_0_0.Op != OpAMD64ANDLconst || auxIntToInt32(v_1_1_0_0.AuxInt) != 7 || y != v_1_1_0_0.Args[0] || !(v.Type.Size() == 1) {
-				continue
-			}
-			v.reset(OpAMD64RORB)
-			v.AddArg2(x, y)
-			return true
-		}
-		break
-	}
 	// match: (ORL x x)
 	// result: x
 	for {
@@ -18290,25 +16727,6 @@
 		}
 		break
 	}
-	// match: (ORQ (SHLXQ (MOVQconst [1]) y) x)
-	// result: (BTSQ x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHLXQ {
-				continue
-			}
-			y := v_0.Args[1]
-			v_0_0 := v_0.Args[0]
-			if v_0_0.Op != OpAMD64MOVQconst || auxIntToInt64(v_0_0.AuxInt) != 1 {
-				continue
-			}
-			x := v_1
-			v.reset(OpAMD64BTSQ)
-			v.AddArg2(x, y)
-			return true
-		}
-		break
-	}
 	// match: (ORQ (MOVQconst [c]) x)
 	// cond: isUint64PowerOfTwo(c) && uint64(c) >= 128
 	// result: (BTSQconst [int8(log64(c))] x)
@@ -18365,430 +16783,6 @@
 		}
 		break
 	}
-	// match: (ORQ (SHLQconst x [c]) (SHRQconst x [d]))
-	// cond: d==64-c
-	// result: (ROLQconst x [c])
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHLQconst {
-				continue
-			}
-			c := auxIntToInt8(v_0.AuxInt)
-			x := v_0.Args[0]
-			if v_1.Op != OpAMD64SHRQconst {
-				continue
-			}
-			d := auxIntToInt8(v_1.AuxInt)
-			if x != v_1.Args[0] || !(d == 64-c) {
-				continue
-			}
-			v.reset(OpAMD64ROLQconst)
-			v.AuxInt = int8ToAuxInt(c)
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
-	// match: (ORQ (SHLQ x y) (ANDQ (SHRQ x (NEGQ y)) (SBBQcarrymask (CMPQconst (NEGQ (ADDQconst (ANDQconst y [63]) [-64])) [64]))))
-	// result: (ROLQ x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHLQ {
-				continue
-			}
-			y := v_0.Args[1]
-			x := v_0.Args[0]
-			if v_1.Op != OpAMD64ANDQ {
-				continue
-			}
-			_ = v_1.Args[1]
-			v_1_0 := v_1.Args[0]
-			v_1_1 := v_1.Args[1]
-			for _i1 := 0; _i1 <= 1; _i1, v_1_0, v_1_1 = _i1+1, v_1_1, v_1_0 {
-				if v_1_0.Op != OpAMD64SHRQ {
-					continue
-				}
-				_ = v_1_0.Args[1]
-				if x != v_1_0.Args[0] {
-					continue
-				}
-				v_1_0_1 := v_1_0.Args[1]
-				if v_1_0_1.Op != OpAMD64NEGQ || y != v_1_0_1.Args[0] || v_1_1.Op != OpAMD64SBBQcarrymask {
-					continue
-				}
-				v_1_1_0 := v_1_1.Args[0]
-				if v_1_1_0.Op != OpAMD64CMPQconst || auxIntToInt32(v_1_1_0.AuxInt) != 64 {
-					continue
-				}
-				v_1_1_0_0 := v_1_1_0.Args[0]
-				if v_1_1_0_0.Op != OpAMD64NEGQ {
-					continue
-				}
-				v_1_1_0_0_0 := v_1_1_0_0.Args[0]
-				if v_1_1_0_0_0.Op != OpAMD64ADDQconst || auxIntToInt32(v_1_1_0_0_0.AuxInt) != -64 {
-					continue
-				}
-				v_1_1_0_0_0_0 := v_1_1_0_0_0.Args[0]
-				if v_1_1_0_0_0_0.Op != OpAMD64ANDQconst || auxIntToInt32(v_1_1_0_0_0_0.AuxInt) != 63 || y != v_1_1_0_0_0_0.Args[0] {
-					continue
-				}
-				v.reset(OpAMD64ROLQ)
-				v.AddArg2(x, y)
-				return true
-			}
-		}
-		break
-	}
-	// match: (ORQ (SHLQ x y) (ANDQ (SHRQ x (NEGL y)) (SBBQcarrymask (CMPLconst (NEGL (ADDLconst (ANDLconst y [63]) [-64])) [64]))))
-	// result: (ROLQ x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHLQ {
-				continue
-			}
-			y := v_0.Args[1]
-			x := v_0.Args[0]
-			if v_1.Op != OpAMD64ANDQ {
-				continue
-			}
-			_ = v_1.Args[1]
-			v_1_0 := v_1.Args[0]
-			v_1_1 := v_1.Args[1]
-			for _i1 := 0; _i1 <= 1; _i1, v_1_0, v_1_1 = _i1+1, v_1_1, v_1_0 {
-				if v_1_0.Op != OpAMD64SHRQ {
-					continue
-				}
-				_ = v_1_0.Args[1]
-				if x != v_1_0.Args[0] {
-					continue
-				}
-				v_1_0_1 := v_1_0.Args[1]
-				if v_1_0_1.Op != OpAMD64NEGL || y != v_1_0_1.Args[0] || v_1_1.Op != OpAMD64SBBQcarrymask {
-					continue
-				}
-				v_1_1_0 := v_1_1.Args[0]
-				if v_1_1_0.Op != OpAMD64CMPLconst || auxIntToInt32(v_1_1_0.AuxInt) != 64 {
-					continue
-				}
-				v_1_1_0_0 := v_1_1_0.Args[0]
-				if v_1_1_0_0.Op != OpAMD64NEGL {
-					continue
-				}
-				v_1_1_0_0_0 := v_1_1_0_0.Args[0]
-				if v_1_1_0_0_0.Op != OpAMD64ADDLconst || auxIntToInt32(v_1_1_0_0_0.AuxInt) != -64 {
-					continue
-				}
-				v_1_1_0_0_0_0 := v_1_1_0_0_0.Args[0]
-				if v_1_1_0_0_0_0.Op != OpAMD64ANDLconst || auxIntToInt32(v_1_1_0_0_0_0.AuxInt) != 63 || y != v_1_1_0_0_0_0.Args[0] {
-					continue
-				}
-				v.reset(OpAMD64ROLQ)
-				v.AddArg2(x, y)
-				return true
-			}
-		}
-		break
-	}
-	// match: (ORQ (SHRQ x y) (ANDQ (SHLQ x (NEGQ y)) (SBBQcarrymask (CMPQconst (NEGQ (ADDQconst (ANDQconst y [63]) [-64])) [64]))))
-	// result: (RORQ x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHRQ {
-				continue
-			}
-			y := v_0.Args[1]
-			x := v_0.Args[0]
-			if v_1.Op != OpAMD64ANDQ {
-				continue
-			}
-			_ = v_1.Args[1]
-			v_1_0 := v_1.Args[0]
-			v_1_1 := v_1.Args[1]
-			for _i1 := 0; _i1 <= 1; _i1, v_1_0, v_1_1 = _i1+1, v_1_1, v_1_0 {
-				if v_1_0.Op != OpAMD64SHLQ {
-					continue
-				}
-				_ = v_1_0.Args[1]
-				if x != v_1_0.Args[0] {
-					continue
-				}
-				v_1_0_1 := v_1_0.Args[1]
-				if v_1_0_1.Op != OpAMD64NEGQ || y != v_1_0_1.Args[0] || v_1_1.Op != OpAMD64SBBQcarrymask {
-					continue
-				}
-				v_1_1_0 := v_1_1.Args[0]
-				if v_1_1_0.Op != OpAMD64CMPQconst || auxIntToInt32(v_1_1_0.AuxInt) != 64 {
-					continue
-				}
-				v_1_1_0_0 := v_1_1_0.Args[0]
-				if v_1_1_0_0.Op != OpAMD64NEGQ {
-					continue
-				}
-				v_1_1_0_0_0 := v_1_1_0_0.Args[0]
-				if v_1_1_0_0_0.Op != OpAMD64ADDQconst || auxIntToInt32(v_1_1_0_0_0.AuxInt) != -64 {
-					continue
-				}
-				v_1_1_0_0_0_0 := v_1_1_0_0_0.Args[0]
-				if v_1_1_0_0_0_0.Op != OpAMD64ANDQconst || auxIntToInt32(v_1_1_0_0_0_0.AuxInt) != 63 || y != v_1_1_0_0_0_0.Args[0] {
-					continue
-				}
-				v.reset(OpAMD64RORQ)
-				v.AddArg2(x, y)
-				return true
-			}
-		}
-		break
-	}
-	// match: (ORQ (SHRQ x y) (ANDQ (SHLQ x (NEGL y)) (SBBQcarrymask (CMPLconst (NEGL (ADDLconst (ANDLconst y [63]) [-64])) [64]))))
-	// result: (RORQ x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHRQ {
-				continue
-			}
-			y := v_0.Args[1]
-			x := v_0.Args[0]
-			if v_1.Op != OpAMD64ANDQ {
-				continue
-			}
-			_ = v_1.Args[1]
-			v_1_0 := v_1.Args[0]
-			v_1_1 := v_1.Args[1]
-			for _i1 := 0; _i1 <= 1; _i1, v_1_0, v_1_1 = _i1+1, v_1_1, v_1_0 {
-				if v_1_0.Op != OpAMD64SHLQ {
-					continue
-				}
-				_ = v_1_0.Args[1]
-				if x != v_1_0.Args[0] {
-					continue
-				}
-				v_1_0_1 := v_1_0.Args[1]
-				if v_1_0_1.Op != OpAMD64NEGL || y != v_1_0_1.Args[0] || v_1_1.Op != OpAMD64SBBQcarrymask {
-					continue
-				}
-				v_1_1_0 := v_1_1.Args[0]
-				if v_1_1_0.Op != OpAMD64CMPLconst || auxIntToInt32(v_1_1_0.AuxInt) != 64 {
-					continue
-				}
-				v_1_1_0_0 := v_1_1_0.Args[0]
-				if v_1_1_0_0.Op != OpAMD64NEGL {
-					continue
-				}
-				v_1_1_0_0_0 := v_1_1_0_0.Args[0]
-				if v_1_1_0_0_0.Op != OpAMD64ADDLconst || auxIntToInt32(v_1_1_0_0_0.AuxInt) != -64 {
-					continue
-				}
-				v_1_1_0_0_0_0 := v_1_1_0_0_0.Args[0]
-				if v_1_1_0_0_0_0.Op != OpAMD64ANDLconst || auxIntToInt32(v_1_1_0_0_0_0.AuxInt) != 63 || y != v_1_1_0_0_0_0.Args[0] {
-					continue
-				}
-				v.reset(OpAMD64RORQ)
-				v.AddArg2(x, y)
-				return true
-			}
-		}
-		break
-	}
-	// match: (ORQ (SHLXQ x y) (ANDQ (SHRXQ x (NEGQ y)) (SBBQcarrymask (CMPQconst (NEGQ (ADDQconst (ANDQconst y [63]) [-64])) [64]))))
-	// result: (ROLQ x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHLXQ {
-				continue
-			}
-			y := v_0.Args[1]
-			x := v_0.Args[0]
-			if v_1.Op != OpAMD64ANDQ {
-				continue
-			}
-			_ = v_1.Args[1]
-			v_1_0 := v_1.Args[0]
-			v_1_1 := v_1.Args[1]
-			for _i1 := 0; _i1 <= 1; _i1, v_1_0, v_1_1 = _i1+1, v_1_1, v_1_0 {
-				if v_1_0.Op != OpAMD64SHRXQ {
-					continue
-				}
-				_ = v_1_0.Args[1]
-				if x != v_1_0.Args[0] {
-					continue
-				}
-				v_1_0_1 := v_1_0.Args[1]
-				if v_1_0_1.Op != OpAMD64NEGQ || y != v_1_0_1.Args[0] || v_1_1.Op != OpAMD64SBBQcarrymask {
-					continue
-				}
-				v_1_1_0 := v_1_1.Args[0]
-				if v_1_1_0.Op != OpAMD64CMPQconst || auxIntToInt32(v_1_1_0.AuxInt) != 64 {
-					continue
-				}
-				v_1_1_0_0 := v_1_1_0.Args[0]
-				if v_1_1_0_0.Op != OpAMD64NEGQ {
-					continue
-				}
-				v_1_1_0_0_0 := v_1_1_0_0.Args[0]
-				if v_1_1_0_0_0.Op != OpAMD64ADDQconst || auxIntToInt32(v_1_1_0_0_0.AuxInt) != -64 {
-					continue
-				}
-				v_1_1_0_0_0_0 := v_1_1_0_0_0.Args[0]
-				if v_1_1_0_0_0_0.Op != OpAMD64ANDQconst || auxIntToInt32(v_1_1_0_0_0_0.AuxInt) != 63 || y != v_1_1_0_0_0_0.Args[0] {
-					continue
-				}
-				v.reset(OpAMD64ROLQ)
-				v.AddArg2(x, y)
-				return true
-			}
-		}
-		break
-	}
-	// match: (ORQ (SHLXQ x y) (ANDQ (SHRXQ x (NEGL y)) (SBBQcarrymask (CMPLconst (NEGL (ADDLconst (ANDLconst y [63]) [-64])) [64]))))
-	// result: (ROLQ x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHLXQ {
-				continue
-			}
-			y := v_0.Args[1]
-			x := v_0.Args[0]
-			if v_1.Op != OpAMD64ANDQ {
-				continue
-			}
-			_ = v_1.Args[1]
-			v_1_0 := v_1.Args[0]
-			v_1_1 := v_1.Args[1]
-			for _i1 := 0; _i1 <= 1; _i1, v_1_0, v_1_1 = _i1+1, v_1_1, v_1_0 {
-				if v_1_0.Op != OpAMD64SHRXQ {
-					continue
-				}
-				_ = v_1_0.Args[1]
-				if x != v_1_0.Args[0] {
-					continue
-				}
-				v_1_0_1 := v_1_0.Args[1]
-				if v_1_0_1.Op != OpAMD64NEGL || y != v_1_0_1.Args[0] || v_1_1.Op != OpAMD64SBBQcarrymask {
-					continue
-				}
-				v_1_1_0 := v_1_1.Args[0]
-				if v_1_1_0.Op != OpAMD64CMPLconst || auxIntToInt32(v_1_1_0.AuxInt) != 64 {
-					continue
-				}
-				v_1_1_0_0 := v_1_1_0.Args[0]
-				if v_1_1_0_0.Op != OpAMD64NEGL {
-					continue
-				}
-				v_1_1_0_0_0 := v_1_1_0_0.Args[0]
-				if v_1_1_0_0_0.Op != OpAMD64ADDLconst || auxIntToInt32(v_1_1_0_0_0.AuxInt) != -64 {
-					continue
-				}
-				v_1_1_0_0_0_0 := v_1_1_0_0_0.Args[0]
-				if v_1_1_0_0_0_0.Op != OpAMD64ANDLconst || auxIntToInt32(v_1_1_0_0_0_0.AuxInt) != 63 || y != v_1_1_0_0_0_0.Args[0] {
-					continue
-				}
-				v.reset(OpAMD64ROLQ)
-				v.AddArg2(x, y)
-				return true
-			}
-		}
-		break
-	}
-	// match: (ORQ (SHRXQ x y) (ANDQ (SHLXQ x (NEGQ y)) (SBBQcarrymask (CMPQconst (NEGQ (ADDQconst (ANDQconst y [63]) [-64])) [64]))))
-	// result: (RORQ x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHRXQ {
-				continue
-			}
-			y := v_0.Args[1]
-			x := v_0.Args[0]
-			if v_1.Op != OpAMD64ANDQ {
-				continue
-			}
-			_ = v_1.Args[1]
-			v_1_0 := v_1.Args[0]
-			v_1_1 := v_1.Args[1]
-			for _i1 := 0; _i1 <= 1; _i1, v_1_0, v_1_1 = _i1+1, v_1_1, v_1_0 {
-				if v_1_0.Op != OpAMD64SHLXQ {
-					continue
-				}
-				_ = v_1_0.Args[1]
-				if x != v_1_0.Args[0] {
-					continue
-				}
-				v_1_0_1 := v_1_0.Args[1]
-				if v_1_0_1.Op != OpAMD64NEGQ || y != v_1_0_1.Args[0] || v_1_1.Op != OpAMD64SBBQcarrymask {
-					continue
-				}
-				v_1_1_0 := v_1_1.Args[0]
-				if v_1_1_0.Op != OpAMD64CMPQconst || auxIntToInt32(v_1_1_0.AuxInt) != 64 {
-					continue
-				}
-				v_1_1_0_0 := v_1_1_0.Args[0]
-				if v_1_1_0_0.Op != OpAMD64NEGQ {
-					continue
-				}
-				v_1_1_0_0_0 := v_1_1_0_0.Args[0]
-				if v_1_1_0_0_0.Op != OpAMD64ADDQconst || auxIntToInt32(v_1_1_0_0_0.AuxInt) != -64 {
-					continue
-				}
-				v_1_1_0_0_0_0 := v_1_1_0_0_0.Args[0]
-				if v_1_1_0_0_0_0.Op != OpAMD64ANDQconst || auxIntToInt32(v_1_1_0_0_0_0.AuxInt) != 63 || y != v_1_1_0_0_0_0.Args[0] {
-					continue
-				}
-				v.reset(OpAMD64RORQ)
-				v.AddArg2(x, y)
-				return true
-			}
-		}
-		break
-	}
-	// match: (ORQ (SHRXQ x y) (ANDQ (SHLXQ x (NEGL y)) (SBBQcarrymask (CMPLconst (NEGL (ADDLconst (ANDLconst y [63]) [-64])) [64]))))
-	// result: (RORQ x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHRXQ {
-				continue
-			}
-			y := v_0.Args[1]
-			x := v_0.Args[0]
-			if v_1.Op != OpAMD64ANDQ {
-				continue
-			}
-			_ = v_1.Args[1]
-			v_1_0 := v_1.Args[0]
-			v_1_1 := v_1.Args[1]
-			for _i1 := 0; _i1 <= 1; _i1, v_1_0, v_1_1 = _i1+1, v_1_1, v_1_0 {
-				if v_1_0.Op != OpAMD64SHLXQ {
-					continue
-				}
-				_ = v_1_0.Args[1]
-				if x != v_1_0.Args[0] {
-					continue
-				}
-				v_1_0_1 := v_1_0.Args[1]
-				if v_1_0_1.Op != OpAMD64NEGL || y != v_1_0_1.Args[0] || v_1_1.Op != OpAMD64SBBQcarrymask {
-					continue
-				}
-				v_1_1_0 := v_1_1.Args[0]
-				if v_1_1_0.Op != OpAMD64CMPLconst || auxIntToInt32(v_1_1_0.AuxInt) != 64 {
-					continue
-				}
-				v_1_1_0_0 := v_1_1_0.Args[0]
-				if v_1_1_0_0.Op != OpAMD64NEGL {
-					continue
-				}
-				v_1_1_0_0_0 := v_1_1_0_0.Args[0]
-				if v_1_1_0_0_0.Op != OpAMD64ADDLconst || auxIntToInt32(v_1_1_0_0_0.AuxInt) != -64 {
-					continue
-				}
-				v_1_1_0_0_0_0 := v_1_1_0_0_0.Args[0]
-				if v_1_1_0_0_0_0.Op != OpAMD64ANDLconst || auxIntToInt32(v_1_1_0_0_0_0.AuxInt) != 63 || y != v_1_1_0_0_0_0.Args[0] {
-					continue
-				}
-				v.reset(OpAMD64RORQ)
-				v.AddArg2(x, y)
-				return true
-			}
-		}
-		break
-	}
 	// match: (ORQ (SHRQ lo bits) (SHLQ hi (NEGQ bits)))
 	// result: (SHRDQ lo hi bits)
 	for {
@@ -20340,20 +18334,6 @@
 }
 func rewriteValueAMD64_OpAMD64ROLBconst(v *Value) bool {
 	v_0 := v.Args[0]
-	// match: (ROLBconst [c] (ROLBconst [d] x))
-	// result: (ROLBconst [(c+d)& 7] x)
-	for {
-		c := auxIntToInt8(v.AuxInt)
-		if v_0.Op != OpAMD64ROLBconst {
-			break
-		}
-		d := auxIntToInt8(v_0.AuxInt)
-		x := v_0.Args[0]
-		v.reset(OpAMD64ROLBconst)
-		v.AuxInt = int8ToAuxInt((c + d) & 7)
-		v.AddArg(x)
-		return true
-	}
 	// match: (ROLBconst x [0])
 	// result: x
 	for {
@@ -20423,20 +18403,6 @@
 }
 func rewriteValueAMD64_OpAMD64ROLLconst(v *Value) bool {
 	v_0 := v.Args[0]
-	// match: (ROLLconst [c] (ROLLconst [d] x))
-	// result: (ROLLconst [(c+d)&31] x)
-	for {
-		c := auxIntToInt8(v.AuxInt)
-		if v_0.Op != OpAMD64ROLLconst {
-			break
-		}
-		d := auxIntToInt8(v_0.AuxInt)
-		x := v_0.Args[0]
-		v.reset(OpAMD64ROLLconst)
-		v.AuxInt = int8ToAuxInt((c + d) & 31)
-		v.AddArg(x)
-		return true
-	}
 	// match: (ROLLconst x [0])
 	// result: x
 	for {
@@ -20506,20 +18472,6 @@
 }
 func rewriteValueAMD64_OpAMD64ROLQconst(v *Value) bool {
 	v_0 := v.Args[0]
-	// match: (ROLQconst [c] (ROLQconst [d] x))
-	// result: (ROLQconst [(c+d)&63] x)
-	for {
-		c := auxIntToInt8(v.AuxInt)
-		if v_0.Op != OpAMD64ROLQconst {
-			break
-		}
-		d := auxIntToInt8(v_0.AuxInt)
-		x := v_0.Args[0]
-		v.reset(OpAMD64ROLQconst)
-		v.AuxInt = int8ToAuxInt((c + d) & 63)
-		v.AddArg(x)
-		return true
-	}
 	// match: (ROLQconst x [0])
 	// result: x
 	for {
@@ -20589,20 +18541,6 @@
 }
 func rewriteValueAMD64_OpAMD64ROLWconst(v *Value) bool {
 	v_0 := v.Args[0]
-	// match: (ROLWconst [c] (ROLWconst [d] x))
-	// result: (ROLWconst [(c+d)&15] x)
-	for {
-		c := auxIntToInt8(v.AuxInt)
-		if v_0.Op != OpAMD64ROLWconst {
-			break
-		}
-		d := auxIntToInt8(v_0.AuxInt)
-		x := v_0.Args[0]
-		v.reset(OpAMD64ROLWconst)
-		v.AuxInt = int8ToAuxInt((c + d) & 15)
-		v.AddArg(x)
-		return true
-	}
 	// match: (ROLWconst x [0])
 	// result: x
 	for {
@@ -20896,19 +18834,6 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
-	// match: (SARL x y)
-	// cond: buildcfg.GOAMD64 >= 3
-	// result: (SARXL x y)
-	for {
-		x := v_0
-		y := v_1
-		if !(buildcfg.GOAMD64 >= 3) {
-			break
-		}
-		v.reset(OpAMD64SARXL)
-		v.AddArg2(x, y)
-		return true
-	}
 	// match: (SARL x (MOVQconst [c]))
 	// result: (SARLconst [int8(c&31)] x)
 	for {
@@ -21099,6 +19024,28 @@
 		v.AddArg2(x, v0)
 		return true
 	}
+	// match: (SARL l:(MOVLload [off] {sym} ptr mem) x)
+	// cond: buildcfg.GOAMD64 >= 3 && canMergeLoad(v, l) && clobber(l)
+	// result: (SARXLload [off] {sym} ptr x mem)
+	for {
+		l := v_0
+		if l.Op != OpAMD64MOVLload {
+			break
+		}
+		off := auxIntToInt32(l.AuxInt)
+		sym := auxToSym(l.Aux)
+		mem := l.Args[1]
+		ptr := l.Args[0]
+		x := v_1
+		if !(buildcfg.GOAMD64 >= 3 && canMergeLoad(v, l) && clobber(l)) {
+			break
+		}
+		v.reset(OpAMD64SARXLload)
+		v.AuxInt = int32ToAuxInt(off)
+		v.Aux = symToAux(sym)
+		v.AddArg3(ptr, x, mem)
+		return true
+	}
 	return false
 }
 func rewriteValueAMD64_OpAMD64SARLconst(v *Value) bool {
@@ -21131,19 +19078,6 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
-	// match: (SARQ x y)
-	// cond: buildcfg.GOAMD64 >= 3
-	// result: (SARXQ x y)
-	for {
-		x := v_0
-		y := v_1
-		if !(buildcfg.GOAMD64 >= 3) {
-			break
-		}
-		v.reset(OpAMD64SARXQ)
-		v.AddArg2(x, y)
-		return true
-	}
 	// match: (SARQ x (MOVQconst [c]))
 	// result: (SARQconst [int8(c&63)] x)
 	for {
@@ -21334,6 +19268,28 @@
 		v.AddArg2(x, v0)
 		return true
 	}
+	// match: (SARQ l:(MOVQload [off] {sym} ptr mem) x)
+	// cond: buildcfg.GOAMD64 >= 3 && canMergeLoad(v, l) && clobber(l)
+	// result: (SARXQload [off] {sym} ptr x mem)
+	for {
+		l := v_0
+		if l.Op != OpAMD64MOVQload {
+			break
+		}
+		off := auxIntToInt32(l.AuxInt)
+		sym := auxToSym(l.Aux)
+		mem := l.Args[1]
+		ptr := l.Args[0]
+		x := v_1
+		if !(buildcfg.GOAMD64 >= 3 && canMergeLoad(v, l) && clobber(l)) {
+			break
+		}
+		v.reset(OpAMD64SARXQload)
+		v.AuxInt = int32ToAuxInt(off)
+		v.Aux = symToAux(sym)
+		v.AddArg3(ptr, x, mem)
+		return true
+	}
 	return false
 }
 func rewriteValueAMD64_OpAMD64SARQconst(v *Value) bool {
@@ -21419,224 +19375,6 @@
 	}
 	return false
 }
-func rewriteValueAMD64_OpAMD64SARXL(v *Value) bool {
-	v_1 := v.Args[1]
-	v_0 := v.Args[0]
-	b := v.Block
-	// match: (SARXL x (MOVQconst [c]))
-	// result: (SARLconst [int8(c&31)] x)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64MOVQconst {
-			break
-		}
-		c := auxIntToInt64(v_1.AuxInt)
-		v.reset(OpAMD64SARLconst)
-		v.AuxInt = int8ToAuxInt(int8(c & 31))
-		v.AddArg(x)
-		return true
-	}
-	// match: (SARXL x (MOVLconst [c]))
-	// result: (SARLconst [int8(c&31)] x)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64MOVLconst {
-			break
-		}
-		c := auxIntToInt32(v_1.AuxInt)
-		v.reset(OpAMD64SARLconst)
-		v.AuxInt = int8ToAuxInt(int8(c & 31))
-		v.AddArg(x)
-		return true
-	}
-	// match: (SARXL x (ADDQconst [c] y))
-	// cond: c & 31 == 0
-	// result: (SARXL x y)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64ADDQconst {
-			break
-		}
-		c := auxIntToInt32(v_1.AuxInt)
-		y := v_1.Args[0]
-		if !(c&31 == 0) {
-			break
-		}
-		v.reset(OpAMD64SARXL)
-		v.AddArg2(x, y)
-		return true
-	}
-	// match: (SARXL x (NEGQ <t> (ADDQconst [c] y)))
-	// cond: c & 31 == 0
-	// result: (SARXL x (NEGQ <t> y))
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64NEGQ {
-			break
-		}
-		t := v_1.Type
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpAMD64ADDQconst {
-			break
-		}
-		c := auxIntToInt32(v_1_0.AuxInt)
-		y := v_1_0.Args[0]
-		if !(c&31 == 0) {
-			break
-		}
-		v.reset(OpAMD64SARXL)
-		v0 := b.NewValue0(v.Pos, OpAMD64NEGQ, t)
-		v0.AddArg(y)
-		v.AddArg2(x, v0)
-		return true
-	}
-	// match: (SARXL x (ANDQconst [c] y))
-	// cond: c & 31 == 31
-	// result: (SARXL x y)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64ANDQconst {
-			break
-		}
-		c := auxIntToInt32(v_1.AuxInt)
-		y := v_1.Args[0]
-		if !(c&31 == 31) {
-			break
-		}
-		v.reset(OpAMD64SARXL)
-		v.AddArg2(x, y)
-		return true
-	}
-	// match: (SARXL x (NEGQ <t> (ANDQconst [c] y)))
-	// cond: c & 31 == 31
-	// result: (SARXL x (NEGQ <t> y))
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64NEGQ {
-			break
-		}
-		t := v_1.Type
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpAMD64ANDQconst {
-			break
-		}
-		c := auxIntToInt32(v_1_0.AuxInt)
-		y := v_1_0.Args[0]
-		if !(c&31 == 31) {
-			break
-		}
-		v.reset(OpAMD64SARXL)
-		v0 := b.NewValue0(v.Pos, OpAMD64NEGQ, t)
-		v0.AddArg(y)
-		v.AddArg2(x, v0)
-		return true
-	}
-	// match: (SARXL x (ADDLconst [c] y))
-	// cond: c & 31 == 0
-	// result: (SARXL x y)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64ADDLconst {
-			break
-		}
-		c := auxIntToInt32(v_1.AuxInt)
-		y := v_1.Args[0]
-		if !(c&31 == 0) {
-			break
-		}
-		v.reset(OpAMD64SARXL)
-		v.AddArg2(x, y)
-		return true
-	}
-	// match: (SARXL x (NEGL <t> (ADDLconst [c] y)))
-	// cond: c & 31 == 0
-	// result: (SARXL x (NEGL <t> y))
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64NEGL {
-			break
-		}
-		t := v_1.Type
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpAMD64ADDLconst {
-			break
-		}
-		c := auxIntToInt32(v_1_0.AuxInt)
-		y := v_1_0.Args[0]
-		if !(c&31 == 0) {
-			break
-		}
-		v.reset(OpAMD64SARXL)
-		v0 := b.NewValue0(v.Pos, OpAMD64NEGL, t)
-		v0.AddArg(y)
-		v.AddArg2(x, v0)
-		return true
-	}
-	// match: (SARXL x (ANDLconst [c] y))
-	// cond: c & 31 == 31
-	// result: (SARXL x y)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64ANDLconst {
-			break
-		}
-		c := auxIntToInt32(v_1.AuxInt)
-		y := v_1.Args[0]
-		if !(c&31 == 31) {
-			break
-		}
-		v.reset(OpAMD64SARXL)
-		v.AddArg2(x, y)
-		return true
-	}
-	// match: (SARXL x (NEGL <t> (ANDLconst [c] y)))
-	// cond: c & 31 == 31
-	// result: (SARXL x (NEGL <t> y))
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64NEGL {
-			break
-		}
-		t := v_1.Type
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpAMD64ANDLconst {
-			break
-		}
-		c := auxIntToInt32(v_1_0.AuxInt)
-		y := v_1_0.Args[0]
-		if !(c&31 == 31) {
-			break
-		}
-		v.reset(OpAMD64SARXL)
-		v0 := b.NewValue0(v.Pos, OpAMD64NEGL, t)
-		v0.AddArg(y)
-		v.AddArg2(x, v0)
-		return true
-	}
-	// match: (SARXL l:(MOVLload [off] {sym} ptr mem) x)
-	// cond: canMergeLoad(v, l) && clobber(l)
-	// result: (SARXLload [off] {sym} ptr x mem)
-	for {
-		l := v_0
-		if l.Op != OpAMD64MOVLload {
-			break
-		}
-		off := auxIntToInt32(l.AuxInt)
-		sym := auxToSym(l.Aux)
-		mem := l.Args[1]
-		ptr := l.Args[0]
-		x := v_1
-		if !(canMergeLoad(v, l) && clobber(l)) {
-			break
-		}
-		v.reset(OpAMD64SARXLload)
-		v.AuxInt = int32ToAuxInt(off)
-		v.Aux = symToAux(sym)
-		v.AddArg3(ptr, x, mem)
-		return true
-	}
-	return false
-}
 func rewriteValueAMD64_OpAMD64SARXLload(v *Value) bool {
 	v_2 := v.Args[2]
 	v_1 := v.Args[1]
@@ -21665,224 +19403,6 @@
 	}
 	return false
 }
-func rewriteValueAMD64_OpAMD64SARXQ(v *Value) bool {
-	v_1 := v.Args[1]
-	v_0 := v.Args[0]
-	b := v.Block
-	// match: (SARXQ x (MOVQconst [c]))
-	// result: (SARQconst [int8(c&63)] x)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64MOVQconst {
-			break
-		}
-		c := auxIntToInt64(v_1.AuxInt)
-		v.reset(OpAMD64SARQconst)
-		v.AuxInt = int8ToAuxInt(int8(c & 63))
-		v.AddArg(x)
-		return true
-	}
-	// match: (SARXQ x (MOVLconst [c]))
-	// result: (SARQconst [int8(c&63)] x)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64MOVLconst {
-			break
-		}
-		c := auxIntToInt32(v_1.AuxInt)
-		v.reset(OpAMD64SARQconst)
-		v.AuxInt = int8ToAuxInt(int8(c & 63))
-		v.AddArg(x)
-		return true
-	}
-	// match: (SARXQ x (ADDQconst [c] y))
-	// cond: c & 63 == 0
-	// result: (SARXQ x y)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64ADDQconst {
-			break
-		}
-		c := auxIntToInt32(v_1.AuxInt)
-		y := v_1.Args[0]
-		if !(c&63 == 0) {
-			break
-		}
-		v.reset(OpAMD64SARXQ)
-		v.AddArg2(x, y)
-		return true
-	}
-	// match: (SARXQ x (NEGQ <t> (ADDQconst [c] y)))
-	// cond: c & 63 == 0
-	// result: (SARXQ x (NEGQ <t> y))
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64NEGQ {
-			break
-		}
-		t := v_1.Type
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpAMD64ADDQconst {
-			break
-		}
-		c := auxIntToInt32(v_1_0.AuxInt)
-		y := v_1_0.Args[0]
-		if !(c&63 == 0) {
-			break
-		}
-		v.reset(OpAMD64SARXQ)
-		v0 := b.NewValue0(v.Pos, OpAMD64NEGQ, t)
-		v0.AddArg(y)
-		v.AddArg2(x, v0)
-		return true
-	}
-	// match: (SARXQ x (ANDQconst [c] y))
-	// cond: c & 63 == 63
-	// result: (SARXQ x y)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64ANDQconst {
-			break
-		}
-		c := auxIntToInt32(v_1.AuxInt)
-		y := v_1.Args[0]
-		if !(c&63 == 63) {
-			break
-		}
-		v.reset(OpAMD64SARXQ)
-		v.AddArg2(x, y)
-		return true
-	}
-	// match: (SARXQ x (NEGQ <t> (ANDQconst [c] y)))
-	// cond: c & 63 == 63
-	// result: (SARXQ x (NEGQ <t> y))
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64NEGQ {
-			break
-		}
-		t := v_1.Type
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpAMD64ANDQconst {
-			break
-		}
-		c := auxIntToInt32(v_1_0.AuxInt)
-		y := v_1_0.Args[0]
-		if !(c&63 == 63) {
-			break
-		}
-		v.reset(OpAMD64SARXQ)
-		v0 := b.NewValue0(v.Pos, OpAMD64NEGQ, t)
-		v0.AddArg(y)
-		v.AddArg2(x, v0)
-		return true
-	}
-	// match: (SARXQ x (ADDLconst [c] y))
-	// cond: c & 63 == 0
-	// result: (SARXQ x y)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64ADDLconst {
-			break
-		}
-		c := auxIntToInt32(v_1.AuxInt)
-		y := v_1.Args[0]
-		if !(c&63 == 0) {
-			break
-		}
-		v.reset(OpAMD64SARXQ)
-		v.AddArg2(x, y)
-		return true
-	}
-	// match: (SARXQ x (NEGL <t> (ADDLconst [c] y)))
-	// cond: c & 63 == 0
-	// result: (SARXQ x (NEGL <t> y))
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64NEGL {
-			break
-		}
-		t := v_1.Type
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpAMD64ADDLconst {
-			break
-		}
-		c := auxIntToInt32(v_1_0.AuxInt)
-		y := v_1_0.Args[0]
-		if !(c&63 == 0) {
-			break
-		}
-		v.reset(OpAMD64SARXQ)
-		v0 := b.NewValue0(v.Pos, OpAMD64NEGL, t)
-		v0.AddArg(y)
-		v.AddArg2(x, v0)
-		return true
-	}
-	// match: (SARXQ x (ANDLconst [c] y))
-	// cond: c & 63 == 63
-	// result: (SARXQ x y)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64ANDLconst {
-			break
-		}
-		c := auxIntToInt32(v_1.AuxInt)
-		y := v_1.Args[0]
-		if !(c&63 == 63) {
-			break
-		}
-		v.reset(OpAMD64SARXQ)
-		v.AddArg2(x, y)
-		return true
-	}
-	// match: (SARXQ x (NEGL <t> (ANDLconst [c] y)))
-	// cond: c & 63 == 63
-	// result: (SARXQ x (NEGL <t> y))
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64NEGL {
-			break
-		}
-		t := v_1.Type
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpAMD64ANDLconst {
-			break
-		}
-		c := auxIntToInt32(v_1_0.AuxInt)
-		y := v_1_0.Args[0]
-		if !(c&63 == 63) {
-			break
-		}
-		v.reset(OpAMD64SARXQ)
-		v0 := b.NewValue0(v.Pos, OpAMD64NEGL, t)
-		v0.AddArg(y)
-		v.AddArg2(x, v0)
-		return true
-	}
-	// match: (SARXQ l:(MOVQload [off] {sym} ptr mem) x)
-	// cond: canMergeLoad(v, l) && clobber(l)
-	// result: (SARXQload [off] {sym} ptr x mem)
-	for {
-		l := v_0
-		if l.Op != OpAMD64MOVQload {
-			break
-		}
-		off := auxIntToInt32(l.AuxInt)
-		sym := auxToSym(l.Aux)
-		mem := l.Args[1]
-		ptr := l.Args[0]
-		x := v_1
-		if !(canMergeLoad(v, l) && clobber(l)) {
-			break
-		}
-		v.reset(OpAMD64SARXQload)
-		v.AuxInt = int32ToAuxInt(off)
-		v.Aux = symToAux(sym)
-		v.AddArg3(ptr, x, mem)
-		return true
-	}
-	return false
-}
 func rewriteValueAMD64_OpAMD64SARXQload(v *Value) bool {
 	v_2 := v.Args[2]
 	v_1 := v.Args[1]
@@ -23186,60 +20706,6 @@
 		}
 		break
 	}
-	// match: (SETEQ (TESTL (SHLXL (MOVLconst [1]) x) y))
-	// result: (SETAE (BTL x y))
-	for {
-		if v_0.Op != OpAMD64TESTL {
-			break
-		}
-		_ = v_0.Args[1]
-		v_0_0 := v_0.Args[0]
-		v_0_1 := v_0.Args[1]
-		for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
-			if v_0_0.Op != OpAMD64SHLXL {
-				continue
-			}
-			x := v_0_0.Args[1]
-			v_0_0_0 := v_0_0.Args[0]
-			if v_0_0_0.Op != OpAMD64MOVLconst || auxIntToInt32(v_0_0_0.AuxInt) != 1 {
-				continue
-			}
-			y := v_0_1
-			v.reset(OpAMD64SETAE)
-			v0 := b.NewValue0(v.Pos, OpAMD64BTL, types.TypeFlags)
-			v0.AddArg2(x, y)
-			v.AddArg(v0)
-			return true
-		}
-		break
-	}
-	// match: (SETEQ (TESTQ (SHLXQ (MOVQconst [1]) x) y))
-	// result: (SETAE (BTQ x y))
-	for {
-		if v_0.Op != OpAMD64TESTQ {
-			break
-		}
-		_ = v_0.Args[1]
-		v_0_0 := v_0.Args[0]
-		v_0_1 := v_0.Args[1]
-		for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
-			if v_0_0.Op != OpAMD64SHLXQ {
-				continue
-			}
-			x := v_0_0.Args[1]
-			v_0_0_0 := v_0_0.Args[0]
-			if v_0_0_0.Op != OpAMD64MOVQconst || auxIntToInt64(v_0_0_0.AuxInt) != 1 {
-				continue
-			}
-			y := v_0_1
-			v.reset(OpAMD64SETAE)
-			v0 := b.NewValue0(v.Pos, OpAMD64BTQ, types.TypeFlags)
-			v0.AddArg2(x, y)
-			v.AddArg(v0)
-			return true
-		}
-		break
-	}
 	// match: (SETEQ (TESTLconst [c] x))
 	// cond: isUint32PowerOfTwo(int64(c))
 	// result: (SETAE (BTLconst [int8(log32(c))] x))
@@ -23665,72 +21131,6 @@
 		}
 		break
 	}
-	// match: (SETEQstore [off] {sym} ptr (TESTL (SHLXL (MOVLconst [1]) x) y) mem)
-	// result: (SETAEstore [off] {sym} ptr (BTL x y) mem)
-	for {
-		off := auxIntToInt32(v.AuxInt)
-		sym := auxToSym(v.Aux)
-		ptr := v_0
-		if v_1.Op != OpAMD64TESTL {
-			break
-		}
-		_ = v_1.Args[1]
-		v_1_0 := v_1.Args[0]
-		v_1_1 := v_1.Args[1]
-		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
-			if v_1_0.Op != OpAMD64SHLXL {
-				continue
-			}
-			x := v_1_0.Args[1]
-			v_1_0_0 := v_1_0.Args[0]
-			if v_1_0_0.Op != OpAMD64MOVLconst || auxIntToInt32(v_1_0_0.AuxInt) != 1 {
-				continue
-			}
-			y := v_1_1
-			mem := v_2
-			v.reset(OpAMD64SETAEstore)
-			v.AuxInt = int32ToAuxInt(off)
-			v.Aux = symToAux(sym)
-			v0 := b.NewValue0(v.Pos, OpAMD64BTL, types.TypeFlags)
-			v0.AddArg2(x, y)
-			v.AddArg3(ptr, v0, mem)
-			return true
-		}
-		break
-	}
-	// match: (SETEQstore [off] {sym} ptr (TESTQ (SHLXQ (MOVQconst [1]) x) y) mem)
-	// result: (SETAEstore [off] {sym} ptr (BTQ x y) mem)
-	for {
-		off := auxIntToInt32(v.AuxInt)
-		sym := auxToSym(v.Aux)
-		ptr := v_0
-		if v_1.Op != OpAMD64TESTQ {
-			break
-		}
-		_ = v_1.Args[1]
-		v_1_0 := v_1.Args[0]
-		v_1_1 := v_1.Args[1]
-		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
-			if v_1_0.Op != OpAMD64SHLXQ {
-				continue
-			}
-			x := v_1_0.Args[1]
-			v_1_0_0 := v_1_0.Args[0]
-			if v_1_0_0.Op != OpAMD64MOVQconst || auxIntToInt64(v_1_0_0.AuxInt) != 1 {
-				continue
-			}
-			y := v_1_1
-			mem := v_2
-			v.reset(OpAMD64SETAEstore)
-			v.AuxInt = int32ToAuxInt(off)
-			v.Aux = symToAux(sym)
-			v0 := b.NewValue0(v.Pos, OpAMD64BTQ, types.TypeFlags)
-			v0.AddArg2(x, y)
-			v.AddArg3(ptr, v0, mem)
-			return true
-		}
-		break
-	}
 	// match: (SETEQstore [off] {sym} ptr (TESTLconst [c] x) mem)
 	// cond: isUint32PowerOfTwo(int64(c))
 	// result: (SETAEstore [off] {sym} ptr (BTLconst [int8(log32(c))] x) mem)
@@ -25222,60 +22622,6 @@
 		}
 		break
 	}
-	// match: (SETNE (TESTL (SHLXL (MOVLconst [1]) x) y))
-	// result: (SETB (BTL x y))
-	for {
-		if v_0.Op != OpAMD64TESTL {
-			break
-		}
-		_ = v_0.Args[1]
-		v_0_0 := v_0.Args[0]
-		v_0_1 := v_0.Args[1]
-		for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
-			if v_0_0.Op != OpAMD64SHLXL {
-				continue
-			}
-			x := v_0_0.Args[1]
-			v_0_0_0 := v_0_0.Args[0]
-			if v_0_0_0.Op != OpAMD64MOVLconst || auxIntToInt32(v_0_0_0.AuxInt) != 1 {
-				continue
-			}
-			y := v_0_1
-			v.reset(OpAMD64SETB)
-			v0 := b.NewValue0(v.Pos, OpAMD64BTL, types.TypeFlags)
-			v0.AddArg2(x, y)
-			v.AddArg(v0)
-			return true
-		}
-		break
-	}
-	// match: (SETNE (TESTQ (SHLXQ (MOVQconst [1]) x) y))
-	// result: (SETB (BTQ x y))
-	for {
-		if v_0.Op != OpAMD64TESTQ {
-			break
-		}
-		_ = v_0.Args[1]
-		v_0_0 := v_0.Args[0]
-		v_0_1 := v_0.Args[1]
-		for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
-			if v_0_0.Op != OpAMD64SHLXQ {
-				continue
-			}
-			x := v_0_0.Args[1]
-			v_0_0_0 := v_0_0.Args[0]
-			if v_0_0_0.Op != OpAMD64MOVQconst || auxIntToInt64(v_0_0_0.AuxInt) != 1 {
-				continue
-			}
-			y := v_0_1
-			v.reset(OpAMD64SETB)
-			v0 := b.NewValue0(v.Pos, OpAMD64BTQ, types.TypeFlags)
-			v0.AddArg2(x, y)
-			v.AddArg(v0)
-			return true
-		}
-		break
-	}
 	// match: (SETNE (TESTLconst [c] x))
 	// cond: isUint32PowerOfTwo(int64(c))
 	// result: (SETB (BTLconst [int8(log32(c))] x))
@@ -25701,72 +23047,6 @@
 		}
 		break
 	}
-	// match: (SETNEstore [off] {sym} ptr (TESTL (SHLXL (MOVLconst [1]) x) y) mem)
-	// result: (SETBstore [off] {sym} ptr (BTL x y) mem)
-	for {
-		off := auxIntToInt32(v.AuxInt)
-		sym := auxToSym(v.Aux)
-		ptr := v_0
-		if v_1.Op != OpAMD64TESTL {
-			break
-		}
-		_ = v_1.Args[1]
-		v_1_0 := v_1.Args[0]
-		v_1_1 := v_1.Args[1]
-		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
-			if v_1_0.Op != OpAMD64SHLXL {
-				continue
-			}
-			x := v_1_0.Args[1]
-			v_1_0_0 := v_1_0.Args[0]
-			if v_1_0_0.Op != OpAMD64MOVLconst || auxIntToInt32(v_1_0_0.AuxInt) != 1 {
-				continue
-			}
-			y := v_1_1
-			mem := v_2
-			v.reset(OpAMD64SETBstore)
-			v.AuxInt = int32ToAuxInt(off)
-			v.Aux = symToAux(sym)
-			v0 := b.NewValue0(v.Pos, OpAMD64BTL, types.TypeFlags)
-			v0.AddArg2(x, y)
-			v.AddArg3(ptr, v0, mem)
-			return true
-		}
-		break
-	}
-	// match: (SETNEstore [off] {sym} ptr (TESTQ (SHLXQ (MOVQconst [1]) x) y) mem)
-	// result: (SETBstore [off] {sym} ptr (BTQ x y) mem)
-	for {
-		off := auxIntToInt32(v.AuxInt)
-		sym := auxToSym(v.Aux)
-		ptr := v_0
-		if v_1.Op != OpAMD64TESTQ {
-			break
-		}
-		_ = v_1.Args[1]
-		v_1_0 := v_1.Args[0]
-		v_1_1 := v_1.Args[1]
-		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
-			if v_1_0.Op != OpAMD64SHLXQ {
-				continue
-			}
-			x := v_1_0.Args[1]
-			v_1_0_0 := v_1_0.Args[0]
-			if v_1_0_0.Op != OpAMD64MOVQconst || auxIntToInt64(v_1_0_0.AuxInt) != 1 {
-				continue
-			}
-			y := v_1_1
-			mem := v_2
-			v.reset(OpAMD64SETBstore)
-			v.AuxInt = int32ToAuxInt(off)
-			v.Aux = symToAux(sym)
-			v0 := b.NewValue0(v.Pos, OpAMD64BTQ, types.TypeFlags)
-			v0.AddArg2(x, y)
-			v.AddArg3(ptr, v0, mem)
-			return true
-		}
-		break
-	}
 	// match: (SETNEstore [off] {sym} ptr (TESTLconst [c] x) mem)
 	// cond: isUint32PowerOfTwo(int64(c))
 	// result: (SETBstore [off] {sym} ptr (BTLconst [int8(log32(c))] x) mem)
@@ -26281,19 +23561,6 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
-	// match: (SHLL x y)
-	// cond: buildcfg.GOAMD64 >= 3
-	// result: (SHLXL x y)
-	for {
-		x := v_0
-		y := v_1
-		if !(buildcfg.GOAMD64 >= 3) {
-			break
-		}
-		v.reset(OpAMD64SHLXL)
-		v.AddArg2(x, y)
-		return true
-	}
 	// match: (SHLL x (MOVQconst [c]))
 	// result: (SHLLconst [int8(c&31)] x)
 	for {
@@ -26484,6 +23751,28 @@
 		v.AddArg2(x, v0)
 		return true
 	}
+	// match: (SHLL l:(MOVLload [off] {sym} ptr mem) x)
+	// cond: buildcfg.GOAMD64 >= 3 && canMergeLoad(v, l) && clobber(l)
+	// result: (SHLXLload [off] {sym} ptr x mem)
+	for {
+		l := v_0
+		if l.Op != OpAMD64MOVLload {
+			break
+		}
+		off := auxIntToInt32(l.AuxInt)
+		sym := auxToSym(l.Aux)
+		mem := l.Args[1]
+		ptr := l.Args[0]
+		x := v_1
+		if !(buildcfg.GOAMD64 >= 3 && canMergeLoad(v, l) && clobber(l)) {
+			break
+		}
+		v.reset(OpAMD64SHLXLload)
+		v.AuxInt = int32ToAuxInt(off)
+		v.Aux = symToAux(sym)
+		v.AddArg3(ptr, x, mem)
+		return true
+	}
 	return false
 }
 func rewriteValueAMD64_OpAMD64SHLLconst(v *Value) bool {
@@ -26528,19 +23817,6 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
-	// match: (SHLQ x y)
-	// cond: buildcfg.GOAMD64 >= 3
-	// result: (SHLXQ x y)
-	for {
-		x := v_0
-		y := v_1
-		if !(buildcfg.GOAMD64 >= 3) {
-			break
-		}
-		v.reset(OpAMD64SHLXQ)
-		v.AddArg2(x, y)
-		return true
-	}
 	// match: (SHLQ x (MOVQconst [c]))
 	// result: (SHLQconst [int8(c&63)] x)
 	for {
@@ -26731,6 +24007,28 @@
 		v.AddArg2(x, v0)
 		return true
 	}
+	// match: (SHLQ l:(MOVQload [off] {sym} ptr mem) x)
+	// cond: buildcfg.GOAMD64 >= 3 && canMergeLoad(v, l) && clobber(l)
+	// result: (SHLXQload [off] {sym} ptr x mem)
+	for {
+		l := v_0
+		if l.Op != OpAMD64MOVQload {
+			break
+		}
+		off := auxIntToInt32(l.AuxInt)
+		sym := auxToSym(l.Aux)
+		mem := l.Args[1]
+		ptr := l.Args[0]
+		x := v_1
+		if !(buildcfg.GOAMD64 >= 3 && canMergeLoad(v, l) && clobber(l)) {
+			break
+		}
+		v.reset(OpAMD64SHLXQload)
+		v.AuxInt = int32ToAuxInt(off)
+		v.Aux = symToAux(sym)
+		v.AddArg3(ptr, x, mem)
+		return true
+	}
 	return false
 }
 func rewriteValueAMD64_OpAMD64SHLQconst(v *Value) bool {
@@ -26783,224 +24081,6 @@
 	}
 	return false
 }
-func rewriteValueAMD64_OpAMD64SHLXL(v *Value) bool {
-	v_1 := v.Args[1]
-	v_0 := v.Args[0]
-	b := v.Block
-	// match: (SHLXL x (MOVQconst [c]))
-	// result: (SHLLconst [int8(c&31)] x)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64MOVQconst {
-			break
-		}
-		c := auxIntToInt64(v_1.AuxInt)
-		v.reset(OpAMD64SHLLconst)
-		v.AuxInt = int8ToAuxInt(int8(c & 31))
-		v.AddArg(x)
-		return true
-	}
-	// match: (SHLXL x (MOVLconst [c]))
-	// result: (SHLLconst [int8(c&31)] x)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64MOVLconst {
-			break
-		}
-		c := auxIntToInt32(v_1.AuxInt)
-		v.reset(OpAMD64SHLLconst)
-		v.AuxInt = int8ToAuxInt(int8(c & 31))
-		v.AddArg(x)
-		return true
-	}
-	// match: (SHLXL x (ADDQconst [c] y))
-	// cond: c & 31 == 0
-	// result: (SHLXL x y)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64ADDQconst {
-			break
-		}
-		c := auxIntToInt32(v_1.AuxInt)
-		y := v_1.Args[0]
-		if !(c&31 == 0) {
-			break
-		}
-		v.reset(OpAMD64SHLXL)
-		v.AddArg2(x, y)
-		return true
-	}
-	// match: (SHLXL x (NEGQ <t> (ADDQconst [c] y)))
-	// cond: c & 31 == 0
-	// result: (SHLXL x (NEGQ <t> y))
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64NEGQ {
-			break
-		}
-		t := v_1.Type
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpAMD64ADDQconst {
-			break
-		}
-		c := auxIntToInt32(v_1_0.AuxInt)
-		y := v_1_0.Args[0]
-		if !(c&31 == 0) {
-			break
-		}
-		v.reset(OpAMD64SHLXL)
-		v0 := b.NewValue0(v.Pos, OpAMD64NEGQ, t)
-		v0.AddArg(y)
-		v.AddArg2(x, v0)
-		return true
-	}
-	// match: (SHLXL x (ANDQconst [c] y))
-	// cond: c & 31 == 31
-	// result: (SHLXL x y)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64ANDQconst {
-			break
-		}
-		c := auxIntToInt32(v_1.AuxInt)
-		y := v_1.Args[0]
-		if !(c&31 == 31) {
-			break
-		}
-		v.reset(OpAMD64SHLXL)
-		v.AddArg2(x, y)
-		return true
-	}
-	// match: (SHLXL x (NEGQ <t> (ANDQconst [c] y)))
-	// cond: c & 31 == 31
-	// result: (SHLXL x (NEGQ <t> y))
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64NEGQ {
-			break
-		}
-		t := v_1.Type
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpAMD64ANDQconst {
-			break
-		}
-		c := auxIntToInt32(v_1_0.AuxInt)
-		y := v_1_0.Args[0]
-		if !(c&31 == 31) {
-			break
-		}
-		v.reset(OpAMD64SHLXL)
-		v0 := b.NewValue0(v.Pos, OpAMD64NEGQ, t)
-		v0.AddArg(y)
-		v.AddArg2(x, v0)
-		return true
-	}
-	// match: (SHLXL x (ADDLconst [c] y))
-	// cond: c & 31 == 0
-	// result: (SHLXL x y)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64ADDLconst {
-			break
-		}
-		c := auxIntToInt32(v_1.AuxInt)
-		y := v_1.Args[0]
-		if !(c&31 == 0) {
-			break
-		}
-		v.reset(OpAMD64SHLXL)
-		v.AddArg2(x, y)
-		return true
-	}
-	// match: (SHLXL x (NEGL <t> (ADDLconst [c] y)))
-	// cond: c & 31 == 0
-	// result: (SHLXL x (NEGL <t> y))
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64NEGL {
-			break
-		}
-		t := v_1.Type
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpAMD64ADDLconst {
-			break
-		}
-		c := auxIntToInt32(v_1_0.AuxInt)
-		y := v_1_0.Args[0]
-		if !(c&31 == 0) {
-			break
-		}
-		v.reset(OpAMD64SHLXL)
-		v0 := b.NewValue0(v.Pos, OpAMD64NEGL, t)
-		v0.AddArg(y)
-		v.AddArg2(x, v0)
-		return true
-	}
-	// match: (SHLXL x (ANDLconst [c] y))
-	// cond: c & 31 == 31
-	// result: (SHLXL x y)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64ANDLconst {
-			break
-		}
-		c := auxIntToInt32(v_1.AuxInt)
-		y := v_1.Args[0]
-		if !(c&31 == 31) {
-			break
-		}
-		v.reset(OpAMD64SHLXL)
-		v.AddArg2(x, y)
-		return true
-	}
-	// match: (SHLXL x (NEGL <t> (ANDLconst [c] y)))
-	// cond: c & 31 == 31
-	// result: (SHLXL x (NEGL <t> y))
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64NEGL {
-			break
-		}
-		t := v_1.Type
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpAMD64ANDLconst {
-			break
-		}
-		c := auxIntToInt32(v_1_0.AuxInt)
-		y := v_1_0.Args[0]
-		if !(c&31 == 31) {
-			break
-		}
-		v.reset(OpAMD64SHLXL)
-		v0 := b.NewValue0(v.Pos, OpAMD64NEGL, t)
-		v0.AddArg(y)
-		v.AddArg2(x, v0)
-		return true
-	}
-	// match: (SHLXL l:(MOVLload [off] {sym} ptr mem) x)
-	// cond: canMergeLoad(v, l) && clobber(l)
-	// result: (SHLXLload [off] {sym} ptr x mem)
-	for {
-		l := v_0
-		if l.Op != OpAMD64MOVLload {
-			break
-		}
-		off := auxIntToInt32(l.AuxInt)
-		sym := auxToSym(l.Aux)
-		mem := l.Args[1]
-		ptr := l.Args[0]
-		x := v_1
-		if !(canMergeLoad(v, l) && clobber(l)) {
-			break
-		}
-		v.reset(OpAMD64SHLXLload)
-		v.AuxInt = int32ToAuxInt(off)
-		v.Aux = symToAux(sym)
-		v.AddArg3(ptr, x, mem)
-		return true
-	}
-	return false
-}
 func rewriteValueAMD64_OpAMD64SHLXLload(v *Value) bool {
 	v_2 := v.Args[2]
 	v_1 := v.Args[1]
@@ -27029,224 +24109,6 @@
 	}
 	return false
 }
-func rewriteValueAMD64_OpAMD64SHLXQ(v *Value) bool {
-	v_1 := v.Args[1]
-	v_0 := v.Args[0]
-	b := v.Block
-	// match: (SHLXQ x (MOVQconst [c]))
-	// result: (SHLQconst [int8(c&63)] x)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64MOVQconst {
-			break
-		}
-		c := auxIntToInt64(v_1.AuxInt)
-		v.reset(OpAMD64SHLQconst)
-		v.AuxInt = int8ToAuxInt(int8(c & 63))
-		v.AddArg(x)
-		return true
-	}
-	// match: (SHLXQ x (MOVLconst [c]))
-	// result: (SHLQconst [int8(c&63)] x)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64MOVLconst {
-			break
-		}
-		c := auxIntToInt32(v_1.AuxInt)
-		v.reset(OpAMD64SHLQconst)
-		v.AuxInt = int8ToAuxInt(int8(c & 63))
-		v.AddArg(x)
-		return true
-	}
-	// match: (SHLXQ x (ADDQconst [c] y))
-	// cond: c & 63 == 0
-	// result: (SHLXQ x y)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64ADDQconst {
-			break
-		}
-		c := auxIntToInt32(v_1.AuxInt)
-		y := v_1.Args[0]
-		if !(c&63 == 0) {
-			break
-		}
-		v.reset(OpAMD64SHLXQ)
-		v.AddArg2(x, y)
-		return true
-	}
-	// match: (SHLXQ x (NEGQ <t> (ADDQconst [c] y)))
-	// cond: c & 63 == 0
-	// result: (SHLXQ x (NEGQ <t> y))
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64NEGQ {
-			break
-		}
-		t := v_1.Type
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpAMD64ADDQconst {
-			break
-		}
-		c := auxIntToInt32(v_1_0.AuxInt)
-		y := v_1_0.Args[0]
-		if !(c&63 == 0) {
-			break
-		}
-		v.reset(OpAMD64SHLXQ)
-		v0 := b.NewValue0(v.Pos, OpAMD64NEGQ, t)
-		v0.AddArg(y)
-		v.AddArg2(x, v0)
-		return true
-	}
-	// match: (SHLXQ x (ANDQconst [c] y))
-	// cond: c & 63 == 63
-	// result: (SHLXQ x y)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64ANDQconst {
-			break
-		}
-		c := auxIntToInt32(v_1.AuxInt)
-		y := v_1.Args[0]
-		if !(c&63 == 63) {
-			break
-		}
-		v.reset(OpAMD64SHLXQ)
-		v.AddArg2(x, y)
-		return true
-	}
-	// match: (SHLXQ x (NEGQ <t> (ANDQconst [c] y)))
-	// cond: c & 63 == 63
-	// result: (SHLXQ x (NEGQ <t> y))
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64NEGQ {
-			break
-		}
-		t := v_1.Type
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpAMD64ANDQconst {
-			break
-		}
-		c := auxIntToInt32(v_1_0.AuxInt)
-		y := v_1_0.Args[0]
-		if !(c&63 == 63) {
-			break
-		}
-		v.reset(OpAMD64SHLXQ)
-		v0 := b.NewValue0(v.Pos, OpAMD64NEGQ, t)
-		v0.AddArg(y)
-		v.AddArg2(x, v0)
-		return true
-	}
-	// match: (SHLXQ x (ADDLconst [c] y))
-	// cond: c & 63 == 0
-	// result: (SHLXQ x y)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64ADDLconst {
-			break
-		}
-		c := auxIntToInt32(v_1.AuxInt)
-		y := v_1.Args[0]
-		if !(c&63 == 0) {
-			break
-		}
-		v.reset(OpAMD64SHLXQ)
-		v.AddArg2(x, y)
-		return true
-	}
-	// match: (SHLXQ x (NEGL <t> (ADDLconst [c] y)))
-	// cond: c & 63 == 0
-	// result: (SHLXQ x (NEGL <t> y))
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64NEGL {
-			break
-		}
-		t := v_1.Type
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpAMD64ADDLconst {
-			break
-		}
-		c := auxIntToInt32(v_1_0.AuxInt)
-		y := v_1_0.Args[0]
-		if !(c&63 == 0) {
-			break
-		}
-		v.reset(OpAMD64SHLXQ)
-		v0 := b.NewValue0(v.Pos, OpAMD64NEGL, t)
-		v0.AddArg(y)
-		v.AddArg2(x, v0)
-		return true
-	}
-	// match: (SHLXQ x (ANDLconst [c] y))
-	// cond: c & 63 == 63
-	// result: (SHLXQ x y)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64ANDLconst {
-			break
-		}
-		c := auxIntToInt32(v_1.AuxInt)
-		y := v_1.Args[0]
-		if !(c&63 == 63) {
-			break
-		}
-		v.reset(OpAMD64SHLXQ)
-		v.AddArg2(x, y)
-		return true
-	}
-	// match: (SHLXQ x (NEGL <t> (ANDLconst [c] y)))
-	// cond: c & 63 == 63
-	// result: (SHLXQ x (NEGL <t> y))
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64NEGL {
-			break
-		}
-		t := v_1.Type
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpAMD64ANDLconst {
-			break
-		}
-		c := auxIntToInt32(v_1_0.AuxInt)
-		y := v_1_0.Args[0]
-		if !(c&63 == 63) {
-			break
-		}
-		v.reset(OpAMD64SHLXQ)
-		v0 := b.NewValue0(v.Pos, OpAMD64NEGL, t)
-		v0.AddArg(y)
-		v.AddArg2(x, v0)
-		return true
-	}
-	// match: (SHLXQ l:(MOVQload [off] {sym} ptr mem) x)
-	// cond: canMergeLoad(v, l) && clobber(l)
-	// result: (SHLXQload [off] {sym} ptr x mem)
-	for {
-		l := v_0
-		if l.Op != OpAMD64MOVQload {
-			break
-		}
-		off := auxIntToInt32(l.AuxInt)
-		sym := auxToSym(l.Aux)
-		mem := l.Args[1]
-		ptr := l.Args[0]
-		x := v_1
-		if !(canMergeLoad(v, l) && clobber(l)) {
-			break
-		}
-		v.reset(OpAMD64SHLXQload)
-		v.AuxInt = int32ToAuxInt(off)
-		v.Aux = symToAux(sym)
-		v.AddArg3(ptr, x, mem)
-		return true
-	}
-	return false
-}
 func rewriteValueAMD64_OpAMD64SHLXQload(v *Value) bool {
 	v_2 := v.Args[2]
 	v_1 := v.Args[1]
@@ -27382,19 +24244,6 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
-	// match: (SHRL x y)
-	// cond: buildcfg.GOAMD64 >= 3
-	// result: (SHRXL x y)
-	for {
-		x := v_0
-		y := v_1
-		if !(buildcfg.GOAMD64 >= 3) {
-			break
-		}
-		v.reset(OpAMD64SHRXL)
-		v.AddArg2(x, y)
-		return true
-	}
 	// match: (SHRL x (MOVQconst [c]))
 	// result: (SHRLconst [int8(c&31)] x)
 	for {
@@ -27585,6 +24434,28 @@
 		v.AddArg2(x, v0)
 		return true
 	}
+	// match: (SHRL l:(MOVLload [off] {sym} ptr mem) x)
+	// cond: buildcfg.GOAMD64 >= 3 && canMergeLoad(v, l) && clobber(l)
+	// result: (SHRXLload [off] {sym} ptr x mem)
+	for {
+		l := v_0
+		if l.Op != OpAMD64MOVLload {
+			break
+		}
+		off := auxIntToInt32(l.AuxInt)
+		sym := auxToSym(l.Aux)
+		mem := l.Args[1]
+		ptr := l.Args[0]
+		x := v_1
+		if !(buildcfg.GOAMD64 >= 3 && canMergeLoad(v, l) && clobber(l)) {
+			break
+		}
+		v.reset(OpAMD64SHRXLload)
+		v.AuxInt = int32ToAuxInt(off)
+		v.Aux = symToAux(sym)
+		v.AddArg3(ptr, x, mem)
+		return true
+	}
 	return false
 }
 func rewriteValueAMD64_OpAMD64SHRLconst(v *Value) bool {
@@ -27617,19 +24488,6 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
-	// match: (SHRQ x y)
-	// cond: buildcfg.GOAMD64 >= 3
-	// result: (SHRXQ x y)
-	for {
-		x := v_0
-		y := v_1
-		if !(buildcfg.GOAMD64 >= 3) {
-			break
-		}
-		v.reset(OpAMD64SHRXQ)
-		v.AddArg2(x, y)
-		return true
-	}
 	// match: (SHRQ x (MOVQconst [c]))
 	// result: (SHRQconst [int8(c&63)] x)
 	for {
@@ -27820,6 +24678,28 @@
 		v.AddArg2(x, v0)
 		return true
 	}
+	// match: (SHRQ l:(MOVQload [off] {sym} ptr mem) x)
+	// cond: buildcfg.GOAMD64 >= 3 && canMergeLoad(v, l) && clobber(l)
+	// result: (SHRXQload [off] {sym} ptr x mem)
+	for {
+		l := v_0
+		if l.Op != OpAMD64MOVQload {
+			break
+		}
+		off := auxIntToInt32(l.AuxInt)
+		sym := auxToSym(l.Aux)
+		mem := l.Args[1]
+		ptr := l.Args[0]
+		x := v_1
+		if !(buildcfg.GOAMD64 >= 3 && canMergeLoad(v, l) && clobber(l)) {
+			break
+		}
+		v.reset(OpAMD64SHRXQload)
+		v.AuxInt = int32ToAuxInt(off)
+		v.Aux = symToAux(sym)
+		v.AddArg3(ptr, x, mem)
+		return true
+	}
 	return false
 }
 func rewriteValueAMD64_OpAMD64SHRQconst(v *Value) bool {
@@ -27931,224 +24811,6 @@
 	}
 	return false
 }
-func rewriteValueAMD64_OpAMD64SHRXL(v *Value) bool {
-	v_1 := v.Args[1]
-	v_0 := v.Args[0]
-	b := v.Block
-	// match: (SHRXL x (MOVQconst [c]))
-	// result: (SHRLconst [int8(c&31)] x)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64MOVQconst {
-			break
-		}
-		c := auxIntToInt64(v_1.AuxInt)
-		v.reset(OpAMD64SHRLconst)
-		v.AuxInt = int8ToAuxInt(int8(c & 31))
-		v.AddArg(x)
-		return true
-	}
-	// match: (SHRXL x (MOVLconst [c]))
-	// result: (SHRLconst [int8(c&31)] x)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64MOVLconst {
-			break
-		}
-		c := auxIntToInt32(v_1.AuxInt)
-		v.reset(OpAMD64SHRLconst)
-		v.AuxInt = int8ToAuxInt(int8(c & 31))
-		v.AddArg(x)
-		return true
-	}
-	// match: (SHRXL x (ADDQconst [c] y))
-	// cond: c & 31 == 0
-	// result: (SHRXL x y)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64ADDQconst {
-			break
-		}
-		c := auxIntToInt32(v_1.AuxInt)
-		y := v_1.Args[0]
-		if !(c&31 == 0) {
-			break
-		}
-		v.reset(OpAMD64SHRXL)
-		v.AddArg2(x, y)
-		return true
-	}
-	// match: (SHRXL x (NEGQ <t> (ADDQconst [c] y)))
-	// cond: c & 31 == 0
-	// result: (SHRXL x (NEGQ <t> y))
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64NEGQ {
-			break
-		}
-		t := v_1.Type
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpAMD64ADDQconst {
-			break
-		}
-		c := auxIntToInt32(v_1_0.AuxInt)
-		y := v_1_0.Args[0]
-		if !(c&31 == 0) {
-			break
-		}
-		v.reset(OpAMD64SHRXL)
-		v0 := b.NewValue0(v.Pos, OpAMD64NEGQ, t)
-		v0.AddArg(y)
-		v.AddArg2(x, v0)
-		return true
-	}
-	// match: (SHRXL x (ANDQconst [c] y))
-	// cond: c & 31 == 31
-	// result: (SHRXL x y)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64ANDQconst {
-			break
-		}
-		c := auxIntToInt32(v_1.AuxInt)
-		y := v_1.Args[0]
-		if !(c&31 == 31) {
-			break
-		}
-		v.reset(OpAMD64SHRXL)
-		v.AddArg2(x, y)
-		return true
-	}
-	// match: (SHRXL x (NEGQ <t> (ANDQconst [c] y)))
-	// cond: c & 31 == 31
-	// result: (SHRXL x (NEGQ <t> y))
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64NEGQ {
-			break
-		}
-		t := v_1.Type
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpAMD64ANDQconst {
-			break
-		}
-		c := auxIntToInt32(v_1_0.AuxInt)
-		y := v_1_0.Args[0]
-		if !(c&31 == 31) {
-			break
-		}
-		v.reset(OpAMD64SHRXL)
-		v0 := b.NewValue0(v.Pos, OpAMD64NEGQ, t)
-		v0.AddArg(y)
-		v.AddArg2(x, v0)
-		return true
-	}
-	// match: (SHRXL x (ADDLconst [c] y))
-	// cond: c & 31 == 0
-	// result: (SHRXL x y)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64ADDLconst {
-			break
-		}
-		c := auxIntToInt32(v_1.AuxInt)
-		y := v_1.Args[0]
-		if !(c&31 == 0) {
-			break
-		}
-		v.reset(OpAMD64SHRXL)
-		v.AddArg2(x, y)
-		return true
-	}
-	// match: (SHRXL x (NEGL <t> (ADDLconst [c] y)))
-	// cond: c & 31 == 0
-	// result: (SHRXL x (NEGL <t> y))
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64NEGL {
-			break
-		}
-		t := v_1.Type
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpAMD64ADDLconst {
-			break
-		}
-		c := auxIntToInt32(v_1_0.AuxInt)
-		y := v_1_0.Args[0]
-		if !(c&31 == 0) {
-			break
-		}
-		v.reset(OpAMD64SHRXL)
-		v0 := b.NewValue0(v.Pos, OpAMD64NEGL, t)
-		v0.AddArg(y)
-		v.AddArg2(x, v0)
-		return true
-	}
-	// match: (SHRXL x (ANDLconst [c] y))
-	// cond: c & 31 == 31
-	// result: (SHRXL x y)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64ANDLconst {
-			break
-		}
-		c := auxIntToInt32(v_1.AuxInt)
-		y := v_1.Args[0]
-		if !(c&31 == 31) {
-			break
-		}
-		v.reset(OpAMD64SHRXL)
-		v.AddArg2(x, y)
-		return true
-	}
-	// match: (SHRXL x (NEGL <t> (ANDLconst [c] y)))
-	// cond: c & 31 == 31
-	// result: (SHRXL x (NEGL <t> y))
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64NEGL {
-			break
-		}
-		t := v_1.Type
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpAMD64ANDLconst {
-			break
-		}
-		c := auxIntToInt32(v_1_0.AuxInt)
-		y := v_1_0.Args[0]
-		if !(c&31 == 31) {
-			break
-		}
-		v.reset(OpAMD64SHRXL)
-		v0 := b.NewValue0(v.Pos, OpAMD64NEGL, t)
-		v0.AddArg(y)
-		v.AddArg2(x, v0)
-		return true
-	}
-	// match: (SHRXL l:(MOVLload [off] {sym} ptr mem) x)
-	// cond: canMergeLoad(v, l) && clobber(l)
-	// result: (SHRXLload [off] {sym} ptr x mem)
-	for {
-		l := v_0
-		if l.Op != OpAMD64MOVLload {
-			break
-		}
-		off := auxIntToInt32(l.AuxInt)
-		sym := auxToSym(l.Aux)
-		mem := l.Args[1]
-		ptr := l.Args[0]
-		x := v_1
-		if !(canMergeLoad(v, l) && clobber(l)) {
-			break
-		}
-		v.reset(OpAMD64SHRXLload)
-		v.AuxInt = int32ToAuxInt(off)
-		v.Aux = symToAux(sym)
-		v.AddArg3(ptr, x, mem)
-		return true
-	}
-	return false
-}
 func rewriteValueAMD64_OpAMD64SHRXLload(v *Value) bool {
 	v_2 := v.Args[2]
 	v_1 := v.Args[1]
@@ -28177,224 +24839,6 @@
 	}
 	return false
 }
-func rewriteValueAMD64_OpAMD64SHRXQ(v *Value) bool {
-	v_1 := v.Args[1]
-	v_0 := v.Args[0]
-	b := v.Block
-	// match: (SHRXQ x (MOVQconst [c]))
-	// result: (SHRQconst [int8(c&63)] x)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64MOVQconst {
-			break
-		}
-		c := auxIntToInt64(v_1.AuxInt)
-		v.reset(OpAMD64SHRQconst)
-		v.AuxInt = int8ToAuxInt(int8(c & 63))
-		v.AddArg(x)
-		return true
-	}
-	// match: (SHRXQ x (MOVLconst [c]))
-	// result: (SHRQconst [int8(c&63)] x)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64MOVLconst {
-			break
-		}
-		c := auxIntToInt32(v_1.AuxInt)
-		v.reset(OpAMD64SHRQconst)
-		v.AuxInt = int8ToAuxInt(int8(c & 63))
-		v.AddArg(x)
-		return true
-	}
-	// match: (SHRXQ x (ADDQconst [c] y))
-	// cond: c & 63 == 0
-	// result: (SHRXQ x y)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64ADDQconst {
-			break
-		}
-		c := auxIntToInt32(v_1.AuxInt)
-		y := v_1.Args[0]
-		if !(c&63 == 0) {
-			break
-		}
-		v.reset(OpAMD64SHRXQ)
-		v.AddArg2(x, y)
-		return true
-	}
-	// match: (SHRXQ x (NEGQ <t> (ADDQconst [c] y)))
-	// cond: c & 63 == 0
-	// result: (SHRXQ x (NEGQ <t> y))
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64NEGQ {
-			break
-		}
-		t := v_1.Type
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpAMD64ADDQconst {
-			break
-		}
-		c := auxIntToInt32(v_1_0.AuxInt)
-		y := v_1_0.Args[0]
-		if !(c&63 == 0) {
-			break
-		}
-		v.reset(OpAMD64SHRXQ)
-		v0 := b.NewValue0(v.Pos, OpAMD64NEGQ, t)
-		v0.AddArg(y)
-		v.AddArg2(x, v0)
-		return true
-	}
-	// match: (SHRXQ x (ANDQconst [c] y))
-	// cond: c & 63 == 63
-	// result: (SHRXQ x y)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64ANDQconst {
-			break
-		}
-		c := auxIntToInt32(v_1.AuxInt)
-		y := v_1.Args[0]
-		if !(c&63 == 63) {
-			break
-		}
-		v.reset(OpAMD64SHRXQ)
-		v.AddArg2(x, y)
-		return true
-	}
-	// match: (SHRXQ x (NEGQ <t> (ANDQconst [c] y)))
-	// cond: c & 63 == 63
-	// result: (SHRXQ x (NEGQ <t> y))
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64NEGQ {
-			break
-		}
-		t := v_1.Type
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpAMD64ANDQconst {
-			break
-		}
-		c := auxIntToInt32(v_1_0.AuxInt)
-		y := v_1_0.Args[0]
-		if !(c&63 == 63) {
-			break
-		}
-		v.reset(OpAMD64SHRXQ)
-		v0 := b.NewValue0(v.Pos, OpAMD64NEGQ, t)
-		v0.AddArg(y)
-		v.AddArg2(x, v0)
-		return true
-	}
-	// match: (SHRXQ x (ADDLconst [c] y))
-	// cond: c & 63 == 0
-	// result: (SHRXQ x y)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64ADDLconst {
-			break
-		}
-		c := auxIntToInt32(v_1.AuxInt)
-		y := v_1.Args[0]
-		if !(c&63 == 0) {
-			break
-		}
-		v.reset(OpAMD64SHRXQ)
-		v.AddArg2(x, y)
-		return true
-	}
-	// match: (SHRXQ x (NEGL <t> (ADDLconst [c] y)))
-	// cond: c & 63 == 0
-	// result: (SHRXQ x (NEGL <t> y))
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64NEGL {
-			break
-		}
-		t := v_1.Type
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpAMD64ADDLconst {
-			break
-		}
-		c := auxIntToInt32(v_1_0.AuxInt)
-		y := v_1_0.Args[0]
-		if !(c&63 == 0) {
-			break
-		}
-		v.reset(OpAMD64SHRXQ)
-		v0 := b.NewValue0(v.Pos, OpAMD64NEGL, t)
-		v0.AddArg(y)
-		v.AddArg2(x, v0)
-		return true
-	}
-	// match: (SHRXQ x (ANDLconst [c] y))
-	// cond: c & 63 == 63
-	// result: (SHRXQ x y)
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64ANDLconst {
-			break
-		}
-		c := auxIntToInt32(v_1.AuxInt)
-		y := v_1.Args[0]
-		if !(c&63 == 63) {
-			break
-		}
-		v.reset(OpAMD64SHRXQ)
-		v.AddArg2(x, y)
-		return true
-	}
-	// match: (SHRXQ x (NEGL <t> (ANDLconst [c] y)))
-	// cond: c & 63 == 63
-	// result: (SHRXQ x (NEGL <t> y))
-	for {
-		x := v_0
-		if v_1.Op != OpAMD64NEGL {
-			break
-		}
-		t := v_1.Type
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpAMD64ANDLconst {
-			break
-		}
-		c := auxIntToInt32(v_1_0.AuxInt)
-		y := v_1_0.Args[0]
-		if !(c&63 == 63) {
-			break
-		}
-		v.reset(OpAMD64SHRXQ)
-		v0 := b.NewValue0(v.Pos, OpAMD64NEGL, t)
-		v0.AddArg(y)
-		v.AddArg2(x, v0)
-		return true
-	}
-	// match: (SHRXQ l:(MOVQload [off] {sym} ptr mem) x)
-	// cond: canMergeLoad(v, l) && clobber(l)
-	// result: (SHRXQload [off] {sym} ptr x mem)
-	for {
-		l := v_0
-		if l.Op != OpAMD64MOVQload {
-			break
-		}
-		off := auxIntToInt32(l.AuxInt)
-		sym := auxToSym(l.Aux)
-		mem := l.Args[1]
-		ptr := l.Args[0]
-		x := v_1
-		if !(canMergeLoad(v, l) && clobber(l)) {
-			break
-		}
-		v.reset(OpAMD64SHRXQload)
-		v.AuxInt = int32ToAuxInt(off)
-		v.Aux = symToAux(sym)
-		v.AddArg3(ptr, x, mem)
-		return true
-	}
-	return false
-}
 func rewriteValueAMD64_OpAMD64SHRXQload(v *Value) bool {
 	v_2 := v.Args[2]
 	v_1 := v.Args[1]
@@ -29726,25 +26170,6 @@
 		}
 		break
 	}
-	// match: (XORL (SHLXL (MOVLconst [1]) y) x)
-	// result: (BTCL x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHLXL {
-				continue
-			}
-			y := v_0.Args[1]
-			v_0_0 := v_0.Args[0]
-			if v_0_0.Op != OpAMD64MOVLconst || auxIntToInt32(v_0_0.AuxInt) != 1 {
-				continue
-			}
-			x := v_1
-			v.reset(OpAMD64BTCL)
-			v.AddArg2(x, y)
-			return true
-		}
-		break
-	}
 	// match: (XORL (MOVLconst [c]) x)
 	// cond: isUint32PowerOfTwo(int64(c)) && uint64(c) >= 128
 	// result: (BTCLconst [int8(log32(c))] x)
@@ -29781,80 +26206,6 @@
 		}
 		break
 	}
-	// match: (XORL (SHLLconst x [c]) (SHRLconst x [d]))
-	// cond: d==32-c
-	// result: (ROLLconst x [c])
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHLLconst {
-				continue
-			}
-			c := auxIntToInt8(v_0.AuxInt)
-			x := v_0.Args[0]
-			if v_1.Op != OpAMD64SHRLconst {
-				continue
-			}
-			d := auxIntToInt8(v_1.AuxInt)
-			if x != v_1.Args[0] || !(d == 32-c) {
-				continue
-			}
-			v.reset(OpAMD64ROLLconst)
-			v.AuxInt = int8ToAuxInt(c)
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
-	// match: (XORL <t> (SHLLconst x [c]) (SHRWconst x [d]))
-	// cond: d==16-c && c < 16 && t.Size() == 2
-	// result: (ROLWconst x [c])
-	for {
-		t := v.Type
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHLLconst {
-				continue
-			}
-			c := auxIntToInt8(v_0.AuxInt)
-			x := v_0.Args[0]
-			if v_1.Op != OpAMD64SHRWconst {
-				continue
-			}
-			d := auxIntToInt8(v_1.AuxInt)
-			if x != v_1.Args[0] || !(d == 16-c && c < 16 && t.Size() == 2) {
-				continue
-			}
-			v.reset(OpAMD64ROLWconst)
-			v.AuxInt = int8ToAuxInt(c)
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
-	// match: (XORL <t> (SHLLconst x [c]) (SHRBconst x [d]))
-	// cond: d==8-c && c < 8 && t.Size() == 1
-	// result: (ROLBconst x [c])
-	for {
-		t := v.Type
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHLLconst {
-				continue
-			}
-			c := auxIntToInt8(v_0.AuxInt)
-			x := v_0.Args[0]
-			if v_1.Op != OpAMD64SHRBconst {
-				continue
-			}
-			d := auxIntToInt8(v_1.AuxInt)
-			if x != v_1.Args[0] || !(d == 8-c && c < 8 && t.Size() == 1) {
-				continue
-			}
-			v.reset(OpAMD64ROLBconst)
-			v.AuxInt = int8ToAuxInt(c)
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
 	// match: (XORL x x)
 	// result: (MOVLconst [0])
 	for {
@@ -30282,25 +26633,6 @@
 		}
 		break
 	}
-	// match: (XORQ (SHLXQ (MOVQconst [1]) y) x)
-	// result: (BTCQ x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHLXQ {
-				continue
-			}
-			y := v_0.Args[1]
-			v_0_0 := v_0.Args[0]
-			if v_0_0.Op != OpAMD64MOVQconst || auxIntToInt64(v_0_0.AuxInt) != 1 {
-				continue
-			}
-			x := v_1
-			v.reset(OpAMD64BTCQ)
-			v.AddArg2(x, y)
-			return true
-		}
-		break
-	}
 	// match: (XORQ (MOVQconst [c]) x)
 	// cond: isUint64PowerOfTwo(c) && uint64(c) >= 128
 	// result: (BTCQconst [int8(log64(c))] x)
@@ -30341,30 +26673,6 @@
 		}
 		break
 	}
-	// match: (XORQ (SHLQconst x [c]) (SHRQconst x [d]))
-	// cond: d==64-c
-	// result: (ROLQconst x [c])
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpAMD64SHLQconst {
-				continue
-			}
-			c := auxIntToInt8(v_0.AuxInt)
-			x := v_0.Args[0]
-			if v_1.Op != OpAMD64SHRQconst {
-				continue
-			}
-			d := auxIntToInt8(v_1.AuxInt)
-			if x != v_1.Args[0] || !(d == 64-c) {
-				continue
-			}
-			v.reset(OpAMD64ROLQconst)
-			v.AuxInt = int8ToAuxInt(c)
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
 	// match: (XORQ x x)
 	// result: (MOVQconst [0])
 	for {
@@ -36928,54 +33236,6 @@
 			}
 			break
 		}
-		// match: (EQ (TESTL (SHLXL (MOVLconst [1]) x) y))
-		// result: (UGE (BTL x y))
-		for b.Controls[0].Op == OpAMD64TESTL {
-			v_0 := b.Controls[0]
-			_ = v_0.Args[1]
-			v_0_0 := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
-				if v_0_0.Op != OpAMD64SHLXL {
-					continue
-				}
-				x := v_0_0.Args[1]
-				v_0_0_0 := v_0_0.Args[0]
-				if v_0_0_0.Op != OpAMD64MOVLconst || auxIntToInt32(v_0_0_0.AuxInt) != 1 {
-					continue
-				}
-				y := v_0_1
-				v0 := b.NewValue0(v_0.Pos, OpAMD64BTL, types.TypeFlags)
-				v0.AddArg2(x, y)
-				b.resetWithControl(BlockAMD64UGE, v0)
-				return true
-			}
-			break
-		}
-		// match: (EQ (TESTQ (SHLXQ (MOVQconst [1]) x) y))
-		// result: (UGE (BTQ x y))
-		for b.Controls[0].Op == OpAMD64TESTQ {
-			v_0 := b.Controls[0]
-			_ = v_0.Args[1]
-			v_0_0 := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
-				if v_0_0.Op != OpAMD64SHLXQ {
-					continue
-				}
-				x := v_0_0.Args[1]
-				v_0_0_0 := v_0_0.Args[0]
-				if v_0_0_0.Op != OpAMD64MOVQconst || auxIntToInt64(v_0_0_0.AuxInt) != 1 {
-					continue
-				}
-				y := v_0_1
-				v0 := b.NewValue0(v_0.Pos, OpAMD64BTQ, types.TypeFlags)
-				v0.AddArg2(x, y)
-				b.resetWithControl(BlockAMD64UGE, v0)
-				return true
-			}
-			break
-		}
 		// match: (EQ (TESTLconst [c] x))
 		// cond: isUint32PowerOfTwo(int64(c))
 		// result: (UGE (BTLconst [int8(log32(c))] x))
@@ -37792,54 +34052,6 @@
 			}
 			break
 		}
-		// match: (NE (TESTL (SHLXL (MOVLconst [1]) x) y))
-		// result: (ULT (BTL x y))
-		for b.Controls[0].Op == OpAMD64TESTL {
-			v_0 := b.Controls[0]
-			_ = v_0.Args[1]
-			v_0_0 := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
-				if v_0_0.Op != OpAMD64SHLXL {
-					continue
-				}
-				x := v_0_0.Args[1]
-				v_0_0_0 := v_0_0.Args[0]
-				if v_0_0_0.Op != OpAMD64MOVLconst || auxIntToInt32(v_0_0_0.AuxInt) != 1 {
-					continue
-				}
-				y := v_0_1
-				v0 := b.NewValue0(v_0.Pos, OpAMD64BTL, types.TypeFlags)
-				v0.AddArg2(x, y)
-				b.resetWithControl(BlockAMD64ULT, v0)
-				return true
-			}
-			break
-		}
-		// match: (NE (TESTQ (SHLXQ (MOVQconst [1]) x) y))
-		// result: (ULT (BTQ x y))
-		for b.Controls[0].Op == OpAMD64TESTQ {
-			v_0 := b.Controls[0]
-			_ = v_0.Args[1]
-			v_0_0 := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
-				if v_0_0.Op != OpAMD64SHLXQ {
-					continue
-				}
-				x := v_0_0.Args[1]
-				v_0_0_0 := v_0_0.Args[0]
-				if v_0_0_0.Op != OpAMD64MOVQconst || auxIntToInt64(v_0_0_0.AuxInt) != 1 {
-					continue
-				}
-				y := v_0_1
-				v0 := b.NewValue0(v_0.Pos, OpAMD64BTQ, types.TypeFlags)
-				v0.AddArg2(x, y)
-				b.resetWithControl(BlockAMD64ULT, v0)
-				return true
-			}
-			break
-		}
 		// match: (NE (TESTLconst [c] x))
 		// cond: isUint32PowerOfTwo(int64(c))
 		// result: (ULT (BTLconst [int8(log32(c))] x))
diff --git a/src/cmd/compile/internal/ssa/rewriteAMD64latelower.go b/src/cmd/compile/internal/ssa/rewriteAMD64latelower.go
new file mode 100644
index 0000000..792cddd
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/rewriteAMD64latelower.go
@@ -0,0 +1,528 @@
+// Code generated from _gen/AMD64latelower.rules; DO NOT EDIT.
+// generated with: cd _gen; go run .
+
+package ssa
+
+import "internal/buildcfg"
+
+func rewriteValueAMD64latelower(v *Value) bool {
+	switch v.Op {
+	case OpAMD64LEAL1:
+		return rewriteValueAMD64latelower_OpAMD64LEAL1(v)
+	case OpAMD64LEAL2:
+		return rewriteValueAMD64latelower_OpAMD64LEAL2(v)
+	case OpAMD64LEAL4:
+		return rewriteValueAMD64latelower_OpAMD64LEAL4(v)
+	case OpAMD64LEAL8:
+		return rewriteValueAMD64latelower_OpAMD64LEAL8(v)
+	case OpAMD64LEAQ1:
+		return rewriteValueAMD64latelower_OpAMD64LEAQ1(v)
+	case OpAMD64LEAQ2:
+		return rewriteValueAMD64latelower_OpAMD64LEAQ2(v)
+	case OpAMD64LEAQ4:
+		return rewriteValueAMD64latelower_OpAMD64LEAQ4(v)
+	case OpAMD64LEAQ8:
+		return rewriteValueAMD64latelower_OpAMD64LEAQ8(v)
+	case OpAMD64LEAW1:
+		return rewriteValueAMD64latelower_OpAMD64LEAW1(v)
+	case OpAMD64LEAW2:
+		return rewriteValueAMD64latelower_OpAMD64LEAW2(v)
+	case OpAMD64LEAW4:
+		return rewriteValueAMD64latelower_OpAMD64LEAW4(v)
+	case OpAMD64LEAW8:
+		return rewriteValueAMD64latelower_OpAMD64LEAW8(v)
+	case OpAMD64SARL:
+		return rewriteValueAMD64latelower_OpAMD64SARL(v)
+	case OpAMD64SARQ:
+		return rewriteValueAMD64latelower_OpAMD64SARQ(v)
+	case OpAMD64SHLL:
+		return rewriteValueAMD64latelower_OpAMD64SHLL(v)
+	case OpAMD64SHLQ:
+		return rewriteValueAMD64latelower_OpAMD64SHLQ(v)
+	case OpAMD64SHRL:
+		return rewriteValueAMD64latelower_OpAMD64SHRL(v)
+	case OpAMD64SHRQ:
+		return rewriteValueAMD64latelower_OpAMD64SHRQ(v)
+	}
+	return false
+}
+func rewriteValueAMD64latelower_OpAMD64LEAL1(v *Value) bool {
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	b := v.Block
+	// match: (LEAL1 <t> [c] {s} x y)
+	// cond: isPtr(x.Type) && c != 0 && s == nil
+	// result: (ADDL x (ADDLconst <y.Type> [c] y))
+	for {
+		c := auxIntToInt32(v.AuxInt)
+		s := auxToSym(v.Aux)
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			x := v_0
+			y := v_1
+			if !(isPtr(x.Type) && c != 0 && s == nil) {
+				continue
+			}
+			v.reset(OpAMD64ADDL)
+			v0 := b.NewValue0(v.Pos, OpAMD64ADDLconst, y.Type)
+			v0.AuxInt = int32ToAuxInt(c)
+			v0.AddArg(y)
+			v.AddArg2(x, v0)
+			return true
+		}
+		break
+	}
+	// match: (LEAL1 <t> [c] {s} x y)
+	// cond: !isPtr(x.Type) && c != 0 && s == nil
+	// result: (ADDL y (ADDLconst <x.Type> [c] x))
+	for {
+		c := auxIntToInt32(v.AuxInt)
+		s := auxToSym(v.Aux)
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			x := v_0
+			y := v_1
+			if !(!isPtr(x.Type) && c != 0 && s == nil) {
+				continue
+			}
+			v.reset(OpAMD64ADDL)
+			v0 := b.NewValue0(v.Pos, OpAMD64ADDLconst, x.Type)
+			v0.AuxInt = int32ToAuxInt(c)
+			v0.AddArg(x)
+			v.AddArg2(y, v0)
+			return true
+		}
+		break
+	}
+	return false
+}
+func rewriteValueAMD64latelower_OpAMD64LEAL2(v *Value) bool {
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	b := v.Block
+	// match: (LEAL2 <t> [c] {s} x y)
+	// cond: !isPtr(t) && c != 0 && s == nil
+	// result: (ADDLconst [c] (LEAL2 <x.Type> x y))
+	for {
+		t := v.Type
+		c := auxIntToInt32(v.AuxInt)
+		s := auxToSym(v.Aux)
+		x := v_0
+		y := v_1
+		if !(!isPtr(t) && c != 0 && s == nil) {
+			break
+		}
+		v.reset(OpAMD64ADDLconst)
+		v.AuxInt = int32ToAuxInt(c)
+		v0 := b.NewValue0(v.Pos, OpAMD64LEAL2, x.Type)
+		v0.AddArg2(x, y)
+		v.AddArg(v0)
+		return true
+	}
+	return false
+}
+func rewriteValueAMD64latelower_OpAMD64LEAL4(v *Value) bool {
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	b := v.Block
+	// match: (LEAL4 <t> [c] {s} x y)
+	// cond: !isPtr(t) && c != 0 && s == nil
+	// result: (ADDLconst [c] (LEAL4 <x.Type> x y))
+	for {
+		t := v.Type
+		c := auxIntToInt32(v.AuxInt)
+		s := auxToSym(v.Aux)
+		x := v_0
+		y := v_1
+		if !(!isPtr(t) && c != 0 && s == nil) {
+			break
+		}
+		v.reset(OpAMD64ADDLconst)
+		v.AuxInt = int32ToAuxInt(c)
+		v0 := b.NewValue0(v.Pos, OpAMD64LEAL4, x.Type)
+		v0.AddArg2(x, y)
+		v.AddArg(v0)
+		return true
+	}
+	return false
+}
+func rewriteValueAMD64latelower_OpAMD64LEAL8(v *Value) bool {
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	b := v.Block
+	// match: (LEAL8 <t> [c] {s} x y)
+	// cond: !isPtr(t) && c != 0 && s == nil
+	// result: (ADDLconst [c] (LEAL8 <x.Type> x y))
+	for {
+		t := v.Type
+		c := auxIntToInt32(v.AuxInt)
+		s := auxToSym(v.Aux)
+		x := v_0
+		y := v_1
+		if !(!isPtr(t) && c != 0 && s == nil) {
+			break
+		}
+		v.reset(OpAMD64ADDLconst)
+		v.AuxInt = int32ToAuxInt(c)
+		v0 := b.NewValue0(v.Pos, OpAMD64LEAL8, x.Type)
+		v0.AddArg2(x, y)
+		v.AddArg(v0)
+		return true
+	}
+	return false
+}
+func rewriteValueAMD64latelower_OpAMD64LEAQ1(v *Value) bool {
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	b := v.Block
+	// match: (LEAQ1 <t> [c] {s} x y)
+	// cond: isPtr(x.Type) && c != 0 && s == nil
+	// result: (ADDQ x (ADDQconst <y.Type> [c] y))
+	for {
+		c := auxIntToInt32(v.AuxInt)
+		s := auxToSym(v.Aux)
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			x := v_0
+			y := v_1
+			if !(isPtr(x.Type) && c != 0 && s == nil) {
+				continue
+			}
+			v.reset(OpAMD64ADDQ)
+			v0 := b.NewValue0(v.Pos, OpAMD64ADDQconst, y.Type)
+			v0.AuxInt = int32ToAuxInt(c)
+			v0.AddArg(y)
+			v.AddArg2(x, v0)
+			return true
+		}
+		break
+	}
+	// match: (LEAQ1 <t> [c] {s} x y)
+	// cond: !isPtr(x.Type) && c != 0 && s == nil
+	// result: (ADDQ y (ADDQconst <x.Type> [c] x))
+	for {
+		c := auxIntToInt32(v.AuxInt)
+		s := auxToSym(v.Aux)
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			x := v_0
+			y := v_1
+			if !(!isPtr(x.Type) && c != 0 && s == nil) {
+				continue
+			}
+			v.reset(OpAMD64ADDQ)
+			v0 := b.NewValue0(v.Pos, OpAMD64ADDQconst, x.Type)
+			v0.AuxInt = int32ToAuxInt(c)
+			v0.AddArg(x)
+			v.AddArg2(y, v0)
+			return true
+		}
+		break
+	}
+	return false
+}
+func rewriteValueAMD64latelower_OpAMD64LEAQ2(v *Value) bool {
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	b := v.Block
+	// match: (LEAQ2 <t> [c] {s} x y)
+	// cond: !isPtr(t) && c != 0 && s == nil
+	// result: (ADDQconst [c] (LEAQ2 <x.Type> x y))
+	for {
+		t := v.Type
+		c := auxIntToInt32(v.AuxInt)
+		s := auxToSym(v.Aux)
+		x := v_0
+		y := v_1
+		if !(!isPtr(t) && c != 0 && s == nil) {
+			break
+		}
+		v.reset(OpAMD64ADDQconst)
+		v.AuxInt = int32ToAuxInt(c)
+		v0 := b.NewValue0(v.Pos, OpAMD64LEAQ2, x.Type)
+		v0.AddArg2(x, y)
+		v.AddArg(v0)
+		return true
+	}
+	return false
+}
+func rewriteValueAMD64latelower_OpAMD64LEAQ4(v *Value) bool {
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	b := v.Block
+	// match: (LEAQ4 <t> [c] {s} x y)
+	// cond: !isPtr(t) && c != 0 && s == nil
+	// result: (ADDQconst [c] (LEAQ4 <x.Type> x y))
+	for {
+		t := v.Type
+		c := auxIntToInt32(v.AuxInt)
+		s := auxToSym(v.Aux)
+		x := v_0
+		y := v_1
+		if !(!isPtr(t) && c != 0 && s == nil) {
+			break
+		}
+		v.reset(OpAMD64ADDQconst)
+		v.AuxInt = int32ToAuxInt(c)
+		v0 := b.NewValue0(v.Pos, OpAMD64LEAQ4, x.Type)
+		v0.AddArg2(x, y)
+		v.AddArg(v0)
+		return true
+	}
+	return false
+}
+func rewriteValueAMD64latelower_OpAMD64LEAQ8(v *Value) bool {
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	b := v.Block
+	// match: (LEAQ8 <t> [c] {s} x y)
+	// cond: !isPtr(t) && c != 0 && s == nil
+	// result: (ADDQconst [c] (LEAQ8 <x.Type> x y))
+	for {
+		t := v.Type
+		c := auxIntToInt32(v.AuxInt)
+		s := auxToSym(v.Aux)
+		x := v_0
+		y := v_1
+		if !(!isPtr(t) && c != 0 && s == nil) {
+			break
+		}
+		v.reset(OpAMD64ADDQconst)
+		v.AuxInt = int32ToAuxInt(c)
+		v0 := b.NewValue0(v.Pos, OpAMD64LEAQ8, x.Type)
+		v0.AddArg2(x, y)
+		v.AddArg(v0)
+		return true
+	}
+	return false
+}
+func rewriteValueAMD64latelower_OpAMD64LEAW1(v *Value) bool {
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	b := v.Block
+	// match: (LEAW1 <t> [c] {s} x y)
+	// cond: isPtr(x.Type) && c != 0 && s == nil
+	// result: (ADDL x (ADDLconst <y.Type> [c] y))
+	for {
+		c := auxIntToInt32(v.AuxInt)
+		s := auxToSym(v.Aux)
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			x := v_0
+			y := v_1
+			if !(isPtr(x.Type) && c != 0 && s == nil) {
+				continue
+			}
+			v.reset(OpAMD64ADDL)
+			v0 := b.NewValue0(v.Pos, OpAMD64ADDLconst, y.Type)
+			v0.AuxInt = int32ToAuxInt(c)
+			v0.AddArg(y)
+			v.AddArg2(x, v0)
+			return true
+		}
+		break
+	}
+	// match: (LEAW1 <t> [c] {s} x y)
+	// cond: !isPtr(x.Type) && c != 0 && s == nil
+	// result: (ADDL y (ADDLconst <x.Type> [c] x))
+	for {
+		c := auxIntToInt32(v.AuxInt)
+		s := auxToSym(v.Aux)
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			x := v_0
+			y := v_1
+			if !(!isPtr(x.Type) && c != 0 && s == nil) {
+				continue
+			}
+			v.reset(OpAMD64ADDL)
+			v0 := b.NewValue0(v.Pos, OpAMD64ADDLconst, x.Type)
+			v0.AuxInt = int32ToAuxInt(c)
+			v0.AddArg(x)
+			v.AddArg2(y, v0)
+			return true
+		}
+		break
+	}
+	return false
+}
+func rewriteValueAMD64latelower_OpAMD64LEAW2(v *Value) bool {
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	b := v.Block
+	// match: (LEAW2 <t> [c] {s} x y)
+	// cond: !isPtr(t) && c != 0 && s == nil
+	// result: (ADDLconst [c] (LEAW2 <x.Type> x y))
+	for {
+		t := v.Type
+		c := auxIntToInt32(v.AuxInt)
+		s := auxToSym(v.Aux)
+		x := v_0
+		y := v_1
+		if !(!isPtr(t) && c != 0 && s == nil) {
+			break
+		}
+		v.reset(OpAMD64ADDLconst)
+		v.AuxInt = int32ToAuxInt(c)
+		v0 := b.NewValue0(v.Pos, OpAMD64LEAW2, x.Type)
+		v0.AddArg2(x, y)
+		v.AddArg(v0)
+		return true
+	}
+	return false
+}
+func rewriteValueAMD64latelower_OpAMD64LEAW4(v *Value) bool {
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	b := v.Block
+	// match: (LEAW4 <t> [c] {s} x y)
+	// cond: !isPtr(t) && c != 0 && s == nil
+	// result: (ADDLconst [c] (LEAW4 <x.Type> x y))
+	for {
+		t := v.Type
+		c := auxIntToInt32(v.AuxInt)
+		s := auxToSym(v.Aux)
+		x := v_0
+		y := v_1
+		if !(!isPtr(t) && c != 0 && s == nil) {
+			break
+		}
+		v.reset(OpAMD64ADDLconst)
+		v.AuxInt = int32ToAuxInt(c)
+		v0 := b.NewValue0(v.Pos, OpAMD64LEAW4, x.Type)
+		v0.AddArg2(x, y)
+		v.AddArg(v0)
+		return true
+	}
+	return false
+}
+func rewriteValueAMD64latelower_OpAMD64LEAW8(v *Value) bool {
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	b := v.Block
+	// match: (LEAW8 <t> [c] {s} x y)
+	// cond: !isPtr(t) && c != 0 && s == nil
+	// result: (ADDLconst [c] (LEAW8 <x.Type> x y))
+	for {
+		t := v.Type
+		c := auxIntToInt32(v.AuxInt)
+		s := auxToSym(v.Aux)
+		x := v_0
+		y := v_1
+		if !(!isPtr(t) && c != 0 && s == nil) {
+			break
+		}
+		v.reset(OpAMD64ADDLconst)
+		v.AuxInt = int32ToAuxInt(c)
+		v0 := b.NewValue0(v.Pos, OpAMD64LEAW8, x.Type)
+		v0.AddArg2(x, y)
+		v.AddArg(v0)
+		return true
+	}
+	return false
+}
+func rewriteValueAMD64latelower_OpAMD64SARL(v *Value) bool {
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	// match: (SARL x y)
+	// cond: buildcfg.GOAMD64 >= 3
+	// result: (SARXL x y)
+	for {
+		x := v_0
+		y := v_1
+		if !(buildcfg.GOAMD64 >= 3) {
+			break
+		}
+		v.reset(OpAMD64SARXL)
+		v.AddArg2(x, y)
+		return true
+	}
+	return false
+}
+func rewriteValueAMD64latelower_OpAMD64SARQ(v *Value) bool {
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	// match: (SARQ x y)
+	// cond: buildcfg.GOAMD64 >= 3
+	// result: (SARXQ x y)
+	for {
+		x := v_0
+		y := v_1
+		if !(buildcfg.GOAMD64 >= 3) {
+			break
+		}
+		v.reset(OpAMD64SARXQ)
+		v.AddArg2(x, y)
+		return true
+	}
+	return false
+}
+func rewriteValueAMD64latelower_OpAMD64SHLL(v *Value) bool {
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	// match: (SHLL x y)
+	// cond: buildcfg.GOAMD64 >= 3
+	// result: (SHLXL x y)
+	for {
+		x := v_0
+		y := v_1
+		if !(buildcfg.GOAMD64 >= 3) {
+			break
+		}
+		v.reset(OpAMD64SHLXL)
+		v.AddArg2(x, y)
+		return true
+	}
+	return false
+}
+func rewriteValueAMD64latelower_OpAMD64SHLQ(v *Value) bool {
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	// match: (SHLQ x y)
+	// cond: buildcfg.GOAMD64 >= 3
+	// result: (SHLXQ x y)
+	for {
+		x := v_0
+		y := v_1
+		if !(buildcfg.GOAMD64 >= 3) {
+			break
+		}
+		v.reset(OpAMD64SHLXQ)
+		v.AddArg2(x, y)
+		return true
+	}
+	return false
+}
+func rewriteValueAMD64latelower_OpAMD64SHRL(v *Value) bool {
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	// match: (SHRL x y)
+	// cond: buildcfg.GOAMD64 >= 3
+	// result: (SHRXL x y)
+	for {
+		x := v_0
+		y := v_1
+		if !(buildcfg.GOAMD64 >= 3) {
+			break
+		}
+		v.reset(OpAMD64SHRXL)
+		v.AddArg2(x, y)
+		return true
+	}
+	return false
+}
+func rewriteValueAMD64latelower_OpAMD64SHRQ(v *Value) bool {
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	// match: (SHRQ x y)
+	// cond: buildcfg.GOAMD64 >= 3
+	// result: (SHRXQ x y)
+	for {
+		x := v_0
+		y := v_1
+		if !(buildcfg.GOAMD64 >= 3) {
+			break
+		}
+		v.reset(OpAMD64SHRXQ)
+		v.AddArg2(x, y)
+		return true
+	}
+	return false
+}
+func rewriteBlockAMD64latelower(b *Block) bool {
+	return false
+}
diff --git a/src/cmd/compile/internal/ssa/rewriteAMD64splitload.go b/src/cmd/compile/internal/ssa/rewriteAMD64splitload.go
index ae50aaa..b443f16 100644
--- a/src/cmd/compile/internal/ssa/rewriteAMD64splitload.go
+++ b/src/cmd/compile/internal/ssa/rewriteAMD64splitload.go
@@ -1,5 +1,5 @@
-// Code generated from gen/AMD64splitload.rules; DO NOT EDIT.
-// generated with: cd gen; go run *.go
+// Code generated from _gen/AMD64splitload.rules; DO NOT EDIT.
+// generated with: cd _gen; go run .
 
 package ssa
 
diff --git a/src/cmd/compile/internal/ssa/rewriteARM.go b/src/cmd/compile/internal/ssa/rewriteARM.go
index 1b50bf9..8fa2a6a 100644
--- a/src/cmd/compile/internal/ssa/rewriteARM.go
+++ b/src/cmd/compile/internal/ssa/rewriteARM.go
@@ -1,5 +1,5 @@
-// Code generated from gen/ARM.rules; DO NOT EDIT.
-// generated with: cd gen; go run *.go
+// Code generated from _gen/ARM.rules; DO NOT EDIT.
+// generated with: cd _gen; go run .
 
 package ssa
 
@@ -2080,22 +2080,6 @@
 		v.AddArg(x)
 		return true
 	}
-	// match: (ADDshiftLL [c] (SRLconst x [32-c]) x)
-	// result: (SRRconst [32-c] x)
-	for {
-		c := auxIntToInt32(v.AuxInt)
-		if v_0.Op != OpARMSRLconst || auxIntToInt32(v_0.AuxInt) != 32-c {
-			break
-		}
-		x := v_0.Args[0]
-		if x != v_1 {
-			break
-		}
-		v.reset(OpARMSRRconst)
-		v.AuxInt = int32ToAuxInt(32 - c)
-		v.AddArg(x)
-		return true
-	}
 	// match: (ADDshiftLL <typ.UInt16> [8] (BFXU <typ.UInt16> [int32(armBFAuxInt(8, 8))] x) x)
 	// result: (REV16 x)
 	for {
@@ -2285,22 +2269,6 @@
 		v.AddArg(x)
 		return true
 	}
-	// match: (ADDshiftRL [c] (SLLconst x [32-c]) x)
-	// result: (SRRconst [ c] x)
-	for {
-		c := auxIntToInt32(v.AuxInt)
-		if v_0.Op != OpARMSLLconst || auxIntToInt32(v_0.AuxInt) != 32-c {
-			break
-		}
-		x := v_0.Args[0]
-		if x != v_1 {
-			break
-		}
-		v.reset(OpARMSRRconst)
-		v.AuxInt = int32ToAuxInt(c)
-		v.AddArg(x)
-		return true
-	}
 	return false
 }
 func rewriteValueARM_OpARMADDshiftRLreg(v *Value) bool {
@@ -8596,22 +8564,6 @@
 		v.AddArg(x)
 		return true
 	}
-	// match: ( ORshiftLL [c] (SRLconst x [32-c]) x)
-	// result: (SRRconst [32-c] x)
-	for {
-		c := auxIntToInt32(v.AuxInt)
-		if v_0.Op != OpARMSRLconst || auxIntToInt32(v_0.AuxInt) != 32-c {
-			break
-		}
-		x := v_0.Args[0]
-		if x != v_1 {
-			break
-		}
-		v.reset(OpARMSRRconst)
-		v.AuxInt = int32ToAuxInt(32 - c)
-		v.AddArg(x)
-		return true
-	}
 	// match: (ORshiftLL <typ.UInt16> [8] (BFXU <typ.UInt16> [int32(armBFAuxInt(8, 8))] x) x)
 	// result: (REV16 x)
 	for {
@@ -8831,22 +8783,6 @@
 		v.AddArg(x)
 		return true
 	}
-	// match: ( ORshiftRL [c] (SLLconst x [32-c]) x)
-	// result: (SRRconst [ c] x)
-	for {
-		c := auxIntToInt32(v.AuxInt)
-		if v_0.Op != OpARMSLLconst || auxIntToInt32(v_0.AuxInt) != 32-c {
-			break
-		}
-		x := v_0.Args[0]
-		if x != v_1 {
-			break
-		}
-		v.reset(OpARMSRRconst)
-		v.AuxInt = int32ToAuxInt(c)
-		v.AddArg(x)
-		return true
-	}
 	// match: (ORshiftRL y:(SRLconst x [c]) x [c])
 	// result: y
 	for {
@@ -12755,22 +12691,6 @@
 		v.AddArg(x)
 		return true
 	}
-	// match: (XORshiftLL [c] (SRLconst x [32-c]) x)
-	// result: (SRRconst [32-c] x)
-	for {
-		c := auxIntToInt32(v.AuxInt)
-		if v_0.Op != OpARMSRLconst || auxIntToInt32(v_0.AuxInt) != 32-c {
-			break
-		}
-		x := v_0.Args[0]
-		if x != v_1 {
-			break
-		}
-		v.reset(OpARMSRRconst)
-		v.AuxInt = int32ToAuxInt(32 - c)
-		v.AddArg(x)
-		return true
-	}
 	// match: (XORshiftLL <typ.UInt16> [8] (BFXU <typ.UInt16> [int32(armBFAuxInt(8, 8))] x) x)
 	// result: (REV16 x)
 	for {
@@ -12990,22 +12910,6 @@
 		v.AddArg(x)
 		return true
 	}
-	// match: (XORshiftRL [c] (SLLconst x [32-c]) x)
-	// result: (SRRconst [ c] x)
-	for {
-		c := auxIntToInt32(v.AuxInt)
-		if v_0.Op != OpARMSLLconst || auxIntToInt32(v_0.AuxInt) != 32-c {
-			break
-		}
-		x := v_0.Args[0]
-		if x != v_1 {
-			break
-		}
-		v.reset(OpARMSRRconst)
-		v.AuxInt = int32ToAuxInt(c)
-		v.AddArg(x)
-		return true
-	}
 	// match: (XORshiftRL (SRLconst x [c]) x [c])
 	// result: (MOVWconst [0])
 	for {
diff --git a/src/cmd/compile/internal/ssa/rewriteARM64.go b/src/cmd/compile/internal/ssa/rewriteARM64.go
index efeadf6..e82a49c 100644
--- a/src/cmd/compile/internal/ssa/rewriteARM64.go
+++ b/src/cmd/compile/internal/ssa/rewriteARM64.go
@@ -1,5 +1,5 @@
-// Code generated from gen/ARM64.rules; DO NOT EDIT.
-// generated with: cd gen; go run *.go
+// Code generated from _gen/ARM64.rules; DO NOT EDIT.
+// generated with: cd _gen; go run .
 
 package ssa
 
@@ -11,6 +11,8 @@
 		return rewriteValueARM64_OpARM64ADCSflags(v)
 	case OpARM64ADD:
 		return rewriteValueARM64_OpARM64ADD(v)
+	case OpARM64ADDSflags:
+		return rewriteValueARM64_OpARM64ADDSflags(v)
 	case OpARM64ADDconst:
 		return rewriteValueARM64_OpARM64ADDconst(v)
 	case OpARM64ADDshiftLL:
@@ -161,6 +163,8 @@
 		return rewriteValueARM64_OpARM64GreaterThanF(v)
 	case OpARM64GreaterThanU:
 		return rewriteValueARM64_OpARM64GreaterThanU(v)
+	case OpARM64LDP:
+		return rewriteValueARM64_OpARM64LDP(v)
 	case OpARM64LessEqual:
 		return rewriteValueARM64_OpARM64LessEqual(v)
 	case OpARM64LessEqualF:
@@ -343,10 +347,6 @@
 		return rewriteValueARM64_OpARM64ROR(v)
 	case OpARM64RORW:
 		return rewriteValueARM64_OpARM64RORW(v)
-	case OpARM64RORWconst:
-		return rewriteValueARM64_OpARM64RORWconst(v)
-	case OpARM64RORconst:
-		return rewriteValueARM64_OpARM64RORconst(v)
 	case OpARM64SBCSflags:
 		return rewriteValueARM64_OpARM64SBCSflags(v)
 	case OpARM64SLL:
@@ -849,9 +849,6 @@
 	case OpMul64F:
 		v.Op = OpARM64FMULD
 		return true
-	case OpMul64uhilo:
-		v.Op = OpARM64LoweredMuluhilo
-		return true
 	case OpMul8:
 		v.Op = OpARM64MULW
 		return true
@@ -1182,8 +1179,6 @@
 func rewriteValueARM64_OpARM64ADD(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	b := v.Block
-	typ := &b.Func.Config.Types
 	// match: (ADD x (MOVDconst [c]))
 	// result: (ADDconst [c] x)
 	for {
@@ -1365,283 +1360,23 @@
 		}
 		break
 	}
-	// match: (ADD (SLL x (ANDconst <t> [63] y)) (CSEL0 <typ.UInt64> [cc] (SRL <typ.UInt64> x (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y))) (CMPconst [64] (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y)))))
-	// cond: cc == OpARM64LessThanU
-	// result: (ROR x (NEG <t> y))
+	return false
+}
+func rewriteValueARM64_OpARM64ADDSflags(v *Value) bool {
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	// match: (ADDSflags x (MOVDconst [c]))
+	// result: (ADDSconstflags [c] x)
 	for {
 		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpARM64SLL {
+			x := v_0
+			if v_1.Op != OpARM64MOVDconst {
 				continue
 			}
-			_ = v_0.Args[1]
-			x := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpARM64ANDconst {
-				continue
-			}
-			t := v_0_1.Type
-			if auxIntToInt64(v_0_1.AuxInt) != 63 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpARM64CSEL0 || v_1.Type != typ.UInt64 {
-				continue
-			}
-			cc := auxIntToOp(v_1.AuxInt)
-			_ = v_1.Args[1]
-			v_1_0 := v_1.Args[0]
-			if v_1_0.Op != OpARM64SRL || v_1_0.Type != typ.UInt64 {
-				continue
-			}
-			_ = v_1_0.Args[1]
-			if x != v_1_0.Args[0] {
-				continue
-			}
-			v_1_0_1 := v_1_0.Args[1]
-			if v_1_0_1.Op != OpARM64SUB || v_1_0_1.Type != t {
-				continue
-			}
-			_ = v_1_0_1.Args[1]
-			v_1_0_1_0 := v_1_0_1.Args[0]
-			if v_1_0_1_0.Op != OpARM64MOVDconst || auxIntToInt64(v_1_0_1_0.AuxInt) != 64 {
-				continue
-			}
-			v_1_0_1_1 := v_1_0_1.Args[1]
-			if v_1_0_1_1.Op != OpARM64ANDconst || v_1_0_1_1.Type != t || auxIntToInt64(v_1_0_1_1.AuxInt) != 63 || y != v_1_0_1_1.Args[0] {
-				continue
-			}
-			v_1_1 := v_1.Args[1]
-			if v_1_1.Op != OpARM64CMPconst || auxIntToInt64(v_1_1.AuxInt) != 64 {
-				continue
-			}
-			v_1_1_0 := v_1_1.Args[0]
-			if v_1_1_0.Op != OpARM64SUB || v_1_1_0.Type != t {
-				continue
-			}
-			_ = v_1_1_0.Args[1]
-			v_1_1_0_0 := v_1_1_0.Args[0]
-			if v_1_1_0_0.Op != OpARM64MOVDconst || auxIntToInt64(v_1_1_0_0.AuxInt) != 64 {
-				continue
-			}
-			v_1_1_0_1 := v_1_1_0.Args[1]
-			if v_1_1_0_1.Op != OpARM64ANDconst || v_1_1_0_1.Type != t || auxIntToInt64(v_1_1_0_1.AuxInt) != 63 || y != v_1_1_0_1.Args[0] || !(cc == OpARM64LessThanU) {
-				continue
-			}
-			v.reset(OpARM64ROR)
-			v0 := b.NewValue0(v.Pos, OpARM64NEG, t)
-			v0.AddArg(y)
-			v.AddArg2(x, v0)
-			return true
-		}
-		break
-	}
-	// match: (ADD (SRL <typ.UInt64> x (ANDconst <t> [63] y)) (CSEL0 <typ.UInt64> [cc] (SLL x (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y))) (CMPconst [64] (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y)))))
-	// cond: cc == OpARM64LessThanU
-	// result: (ROR x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpARM64SRL || v_0.Type != typ.UInt64 {
-				continue
-			}
-			_ = v_0.Args[1]
-			x := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpARM64ANDconst {
-				continue
-			}
-			t := v_0_1.Type
-			if auxIntToInt64(v_0_1.AuxInt) != 63 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpARM64CSEL0 || v_1.Type != typ.UInt64 {
-				continue
-			}
-			cc := auxIntToOp(v_1.AuxInt)
-			_ = v_1.Args[1]
-			v_1_0 := v_1.Args[0]
-			if v_1_0.Op != OpARM64SLL {
-				continue
-			}
-			_ = v_1_0.Args[1]
-			if x != v_1_0.Args[0] {
-				continue
-			}
-			v_1_0_1 := v_1_0.Args[1]
-			if v_1_0_1.Op != OpARM64SUB || v_1_0_1.Type != t {
-				continue
-			}
-			_ = v_1_0_1.Args[1]
-			v_1_0_1_0 := v_1_0_1.Args[0]
-			if v_1_0_1_0.Op != OpARM64MOVDconst || auxIntToInt64(v_1_0_1_0.AuxInt) != 64 {
-				continue
-			}
-			v_1_0_1_1 := v_1_0_1.Args[1]
-			if v_1_0_1_1.Op != OpARM64ANDconst || v_1_0_1_1.Type != t || auxIntToInt64(v_1_0_1_1.AuxInt) != 63 || y != v_1_0_1_1.Args[0] {
-				continue
-			}
-			v_1_1 := v_1.Args[1]
-			if v_1_1.Op != OpARM64CMPconst || auxIntToInt64(v_1_1.AuxInt) != 64 {
-				continue
-			}
-			v_1_1_0 := v_1_1.Args[0]
-			if v_1_1_0.Op != OpARM64SUB || v_1_1_0.Type != t {
-				continue
-			}
-			_ = v_1_1_0.Args[1]
-			v_1_1_0_0 := v_1_1_0.Args[0]
-			if v_1_1_0_0.Op != OpARM64MOVDconst || auxIntToInt64(v_1_1_0_0.AuxInt) != 64 {
-				continue
-			}
-			v_1_1_0_1 := v_1_1_0.Args[1]
-			if v_1_1_0_1.Op != OpARM64ANDconst || v_1_1_0_1.Type != t || auxIntToInt64(v_1_1_0_1.AuxInt) != 63 || y != v_1_1_0_1.Args[0] || !(cc == OpARM64LessThanU) {
-				continue
-			}
-			v.reset(OpARM64ROR)
-			v.AddArg2(x, y)
-			return true
-		}
-		break
-	}
-	// match: (ADD (SLL x (ANDconst <t> [31] y)) (CSEL0 <typ.UInt32> [cc] (SRL <typ.UInt32> (MOVWUreg x) (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y))) (CMPconst [64] (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y)))))
-	// cond: cc == OpARM64LessThanU
-	// result: (RORW x (NEG <t> y))
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpARM64SLL {
-				continue
-			}
-			_ = v_0.Args[1]
-			x := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpARM64ANDconst {
-				continue
-			}
-			t := v_0_1.Type
-			if auxIntToInt64(v_0_1.AuxInt) != 31 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpARM64CSEL0 || v_1.Type != typ.UInt32 {
-				continue
-			}
-			cc := auxIntToOp(v_1.AuxInt)
-			_ = v_1.Args[1]
-			v_1_0 := v_1.Args[0]
-			if v_1_0.Op != OpARM64SRL || v_1_0.Type != typ.UInt32 {
-				continue
-			}
-			_ = v_1_0.Args[1]
-			v_1_0_0 := v_1_0.Args[0]
-			if v_1_0_0.Op != OpARM64MOVWUreg || x != v_1_0_0.Args[0] {
-				continue
-			}
-			v_1_0_1 := v_1_0.Args[1]
-			if v_1_0_1.Op != OpARM64SUB || v_1_0_1.Type != t {
-				continue
-			}
-			_ = v_1_0_1.Args[1]
-			v_1_0_1_0 := v_1_0_1.Args[0]
-			if v_1_0_1_0.Op != OpARM64MOVDconst || auxIntToInt64(v_1_0_1_0.AuxInt) != 32 {
-				continue
-			}
-			v_1_0_1_1 := v_1_0_1.Args[1]
-			if v_1_0_1_1.Op != OpARM64ANDconst || v_1_0_1_1.Type != t || auxIntToInt64(v_1_0_1_1.AuxInt) != 31 || y != v_1_0_1_1.Args[0] {
-				continue
-			}
-			v_1_1 := v_1.Args[1]
-			if v_1_1.Op != OpARM64CMPconst || auxIntToInt64(v_1_1.AuxInt) != 64 {
-				continue
-			}
-			v_1_1_0 := v_1_1.Args[0]
-			if v_1_1_0.Op != OpARM64SUB || v_1_1_0.Type != t {
-				continue
-			}
-			_ = v_1_1_0.Args[1]
-			v_1_1_0_0 := v_1_1_0.Args[0]
-			if v_1_1_0_0.Op != OpARM64MOVDconst || auxIntToInt64(v_1_1_0_0.AuxInt) != 32 {
-				continue
-			}
-			v_1_1_0_1 := v_1_1_0.Args[1]
-			if v_1_1_0_1.Op != OpARM64ANDconst || v_1_1_0_1.Type != t || auxIntToInt64(v_1_1_0_1.AuxInt) != 31 || y != v_1_1_0_1.Args[0] || !(cc == OpARM64LessThanU) {
-				continue
-			}
-			v.reset(OpARM64RORW)
-			v0 := b.NewValue0(v.Pos, OpARM64NEG, t)
-			v0.AddArg(y)
-			v.AddArg2(x, v0)
-			return true
-		}
-		break
-	}
-	// match: (ADD (SRL <typ.UInt32> (MOVWUreg x) (ANDconst <t> [31] y)) (CSEL0 <typ.UInt32> [cc] (SLL x (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y))) (CMPconst [64] (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y)))))
-	// cond: cc == OpARM64LessThanU
-	// result: (RORW x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpARM64SRL || v_0.Type != typ.UInt32 {
-				continue
-			}
-			_ = v_0.Args[1]
-			v_0_0 := v_0.Args[0]
-			if v_0_0.Op != OpARM64MOVWUreg {
-				continue
-			}
-			x := v_0_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpARM64ANDconst {
-				continue
-			}
-			t := v_0_1.Type
-			if auxIntToInt64(v_0_1.AuxInt) != 31 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpARM64CSEL0 || v_1.Type != typ.UInt32 {
-				continue
-			}
-			cc := auxIntToOp(v_1.AuxInt)
-			_ = v_1.Args[1]
-			v_1_0 := v_1.Args[0]
-			if v_1_0.Op != OpARM64SLL {
-				continue
-			}
-			_ = v_1_0.Args[1]
-			if x != v_1_0.Args[0] {
-				continue
-			}
-			v_1_0_1 := v_1_0.Args[1]
-			if v_1_0_1.Op != OpARM64SUB || v_1_0_1.Type != t {
-				continue
-			}
-			_ = v_1_0_1.Args[1]
-			v_1_0_1_0 := v_1_0_1.Args[0]
-			if v_1_0_1_0.Op != OpARM64MOVDconst || auxIntToInt64(v_1_0_1_0.AuxInt) != 32 {
-				continue
-			}
-			v_1_0_1_1 := v_1_0_1.Args[1]
-			if v_1_0_1_1.Op != OpARM64ANDconst || v_1_0_1_1.Type != t || auxIntToInt64(v_1_0_1_1.AuxInt) != 31 || y != v_1_0_1_1.Args[0] {
-				continue
-			}
-			v_1_1 := v_1.Args[1]
-			if v_1_1.Op != OpARM64CMPconst || auxIntToInt64(v_1_1.AuxInt) != 64 {
-				continue
-			}
-			v_1_1_0 := v_1_1.Args[0]
-			if v_1_1_0.Op != OpARM64SUB || v_1_1_0.Type != t {
-				continue
-			}
-			_ = v_1_1_0.Args[1]
-			v_1_1_0_0 := v_1_1_0.Args[0]
-			if v_1_1_0_0.Op != OpARM64MOVDconst || auxIntToInt64(v_1_1_0_0.AuxInt) != 32 {
-				continue
-			}
-			v_1_1_0_1 := v_1_1_0.Args[1]
-			if v_1_1_0_1.Op != OpARM64ANDconst || v_1_1_0_1.Type != t || auxIntToInt64(v_1_1_0_1.AuxInt) != 31 || y != v_1_1_0_1.Args[0] || !(cc == OpARM64LessThanU) {
-				continue
-			}
-			v.reset(OpARM64RORW)
-			v.AddArg2(x, y)
+			c := auxIntToInt64(v_1.AuxInt)
+			v.reset(OpARM64ADDSconstflags)
+			v.AuxInt = int64ToAuxInt(c)
+			v.AddArg(x)
 			return true
 		}
 		break
@@ -1670,6 +1405,20 @@
 		v.AddArg(ptr)
 		return true
 	}
+	// match: (ADDconst [c] y)
+	// cond: c < 0
+	// result: (SUBconst [-c] y)
+	for {
+		c := auxIntToInt64(v.AuxInt)
+		y := v_0
+		if !(c < 0) {
+			break
+		}
+		v.reset(OpARM64SUBconst)
+		v.AuxInt = int64ToAuxInt(-c)
+		v.AddArg(y)
+		return true
+	}
 	// match: (ADDconst [0] x)
 	// result: x
 	for {
@@ -1758,41 +1507,6 @@
 		v.AddArg(x)
 		return true
 	}
-	// match: (ADDshiftLL [c] (SRLconst x [64-c]) x)
-	// result: (RORconst [64-c] x)
-	for {
-		c := auxIntToInt64(v.AuxInt)
-		if v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != 64-c {
-			break
-		}
-		x := v_0.Args[0]
-		if x != v_1 {
-			break
-		}
-		v.reset(OpARM64RORconst)
-		v.AuxInt = int64ToAuxInt(64 - c)
-		v.AddArg(x)
-		return true
-	}
-	// match: (ADDshiftLL <t> [c] (UBFX [bfc] x) x)
-	// cond: c < 32 && t.Size() == 4 && bfc == armBFAuxInt(32-c, c)
-	// result: (RORWconst [32-c] x)
-	for {
-		t := v.Type
-		c := auxIntToInt64(v.AuxInt)
-		if v_0.Op != OpARM64UBFX {
-			break
-		}
-		bfc := auxIntToArm64BitField(v_0.AuxInt)
-		x := v_0.Args[0]
-		if x != v_1 || !(c < 32 && t.Size() == 4 && bfc == armBFAuxInt(32-c, c)) {
-			break
-		}
-		v.reset(OpARM64RORWconst)
-		v.AuxInt = int64ToAuxInt(32 - c)
-		v.AddArg(x)
-		return true
-	}
 	// match: (ADDshiftLL <typ.UInt16> [8] (UBFX <typ.UInt16> [armBFAuxInt(8, 8)] x) x)
 	// result: (REV16W x)
 	for {
@@ -1990,40 +1704,6 @@
 		v.AddArg(x)
 		return true
 	}
-	// match: (ADDshiftRL [c] (SLLconst x [64-c]) x)
-	// result: (RORconst [ c] x)
-	for {
-		c := auxIntToInt64(v.AuxInt)
-		if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != 64-c {
-			break
-		}
-		x := v_0.Args[0]
-		if x != v_1 {
-			break
-		}
-		v.reset(OpARM64RORconst)
-		v.AuxInt = int64ToAuxInt(c)
-		v.AddArg(x)
-		return true
-	}
-	// match: (ADDshiftRL <t> [c] (SLLconst x [32-c]) (MOVWUreg x))
-	// cond: c < 32 && t.Size() == 4
-	// result: (RORWconst [c] x)
-	for {
-		t := v.Type
-		c := auxIntToInt64(v.AuxInt)
-		if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != 32-c {
-			break
-		}
-		x := v_0.Args[0]
-		if v_1.Op != OpARM64MOVWUreg || x != v_1.Args[0] || !(c < 32 && t.Size() == 4) {
-			break
-		}
-		v.reset(OpARM64RORWconst)
-		v.AuxInt = int64ToAuxInt(c)
-		v.AddArg(x)
-		return true
-	}
 	return false
 }
 func rewriteValueARM64_OpARM64AND(v *Value) bool {
@@ -2862,6 +2542,20 @@
 }
 func rewriteValueARM64_OpARM64CMNWconst(v *Value) bool {
 	v_0 := v.Args[0]
+	// match: (CMNWconst [c] y)
+	// cond: c < 0 && c != -1<<31
+	// result: (CMPWconst [-c] y)
+	for {
+		c := auxIntToInt32(v.AuxInt)
+		y := v_0
+		if !(c < 0 && c != -1<<31) {
+			break
+		}
+		v.reset(OpARM64CMPWconst)
+		v.AuxInt = int32ToAuxInt(-c)
+		v.AddArg(y)
+		return true
+	}
 	// match: (CMNWconst (MOVDconst [x]) [y])
 	// result: (FlagConstant [addFlags32(int32(x),y)])
 	for {
@@ -2878,6 +2572,20 @@
 }
 func rewriteValueARM64_OpARM64CMNconst(v *Value) bool {
 	v_0 := v.Args[0]
+	// match: (CMNconst [c] y)
+	// cond: c < 0 && c != -1<<63
+	// result: (CMPconst [-c] y)
+	for {
+		c := auxIntToInt64(v.AuxInt)
+		y := v_0
+		if !(c < 0 && c != -1<<63) {
+			break
+		}
+		v.reset(OpARM64CMPconst)
+		v.AuxInt = int64ToAuxInt(-c)
+		v.AddArg(y)
+		return true
+	}
 	// match: (CMNconst (MOVDconst [x]) [y])
 	// result: (FlagConstant [addFlags64(x,y)])
 	for {
@@ -3223,6 +2931,20 @@
 }
 func rewriteValueARM64_OpARM64CMPWconst(v *Value) bool {
 	v_0 := v.Args[0]
+	// match: (CMPWconst [c] y)
+	// cond: c < 0 && c != -1<<31
+	// result: (CMNWconst [-c] y)
+	for {
+		c := auxIntToInt32(v.AuxInt)
+		y := v_0
+		if !(c < 0 && c != -1<<31) {
+			break
+		}
+		v.reset(OpARM64CMNWconst)
+		v.AuxInt = int32ToAuxInt(-c)
+		v.AddArg(y)
+		return true
+	}
 	// match: (CMPWconst (MOVDconst [x]) [y])
 	// result: (FlagConstant [subFlags32(int32(x),y)])
 	for {
@@ -3263,6 +2985,20 @@
 }
 func rewriteValueARM64_OpARM64CMPconst(v *Value) bool {
 	v_0 := v.Args[0]
+	// match: (CMPconst [c] y)
+	// cond: c < 0 && c != -1<<63
+	// result: (CMNconst [-c] y)
+	for {
+		c := auxIntToInt64(v.AuxInt)
+		y := v_0
+		if !(c < 0 && c != -1<<63) {
+			break
+		}
+		v.reset(OpARM64CMNconst)
+		v.AuxInt = int64ToAuxInt(-c)
+		v.AddArg(y)
+		return true
+	}
 	// match: (CMPconst (MOVDconst [x]) [y])
 	// result: (FlagConstant [subFlags64(x,y)])
 	for {
@@ -4251,6 +3987,333 @@
 }
 func rewriteValueARM64_OpARM64Equal(v *Value) bool {
 	v_0 := v.Args[0]
+	b := v.Block
+	// match: (Equal (CMPconst [0] z:(AND x y)))
+	// cond: z.Uses == 1
+	// result: (Equal (TST x y))
+	for {
+		if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
+			break
+		}
+		z := v_0.Args[0]
+		if z.Op != OpARM64AND {
+			break
+		}
+		y := z.Args[1]
+		x := z.Args[0]
+		if !(z.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64Equal)
+		v0 := b.NewValue0(v.Pos, OpARM64TST, types.TypeFlags)
+		v0.AddArg2(x, y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Equal (CMPWconst [0] x:(ANDconst [c] y)))
+	// cond: x.Uses == 1
+	// result: (Equal (TSTWconst [int32(c)] y))
+	for {
+		if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
+			break
+		}
+		x := v_0.Args[0]
+		if x.Op != OpARM64ANDconst {
+			break
+		}
+		c := auxIntToInt64(x.AuxInt)
+		y := x.Args[0]
+		if !(x.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64Equal)
+		v0 := b.NewValue0(v.Pos, OpARM64TSTWconst, types.TypeFlags)
+		v0.AuxInt = int32ToAuxInt(int32(c))
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Equal (CMPWconst [0] z:(AND x y)))
+	// cond: z.Uses == 1
+	// result: (Equal (TSTW x y))
+	for {
+		if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
+			break
+		}
+		z := v_0.Args[0]
+		if z.Op != OpARM64AND {
+			break
+		}
+		y := z.Args[1]
+		x := z.Args[0]
+		if !(z.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64Equal)
+		v0 := b.NewValue0(v.Pos, OpARM64TSTW, types.TypeFlags)
+		v0.AddArg2(x, y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Equal (CMPconst [0] x:(ANDconst [c] y)))
+	// cond: x.Uses == 1
+	// result: (Equal (TSTconst [c] y))
+	for {
+		if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
+			break
+		}
+		x := v_0.Args[0]
+		if x.Op != OpARM64ANDconst {
+			break
+		}
+		c := auxIntToInt64(x.AuxInt)
+		y := x.Args[0]
+		if !(x.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64Equal)
+		v0 := b.NewValue0(v.Pos, OpARM64TSTconst, types.TypeFlags)
+		v0.AuxInt = int64ToAuxInt(c)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Equal (CMP x z:(NEG y)))
+	// cond: z.Uses == 1
+	// result: (Equal (CMN x y))
+	for {
+		if v_0.Op != OpARM64CMP {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		z := v_0.Args[1]
+		if z.Op != OpARM64NEG {
+			break
+		}
+		y := z.Args[0]
+		if !(z.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64Equal)
+		v0 := b.NewValue0(v.Pos, OpARM64CMN, types.TypeFlags)
+		v0.AddArg2(x, y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Equal (CMPW x z:(NEG y)))
+	// cond: z.Uses == 1
+	// result: (Equal (CMNW x y))
+	for {
+		if v_0.Op != OpARM64CMPW {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		z := v_0.Args[1]
+		if z.Op != OpARM64NEG {
+			break
+		}
+		y := z.Args[0]
+		if !(z.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64Equal)
+		v0 := b.NewValue0(v.Pos, OpARM64CMNW, types.TypeFlags)
+		v0.AddArg2(x, y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Equal (CMPconst [0] x:(ADDconst [c] y)))
+	// cond: x.Uses == 1
+	// result: (Equal (CMNconst [c] y))
+	for {
+		if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
+			break
+		}
+		x := v_0.Args[0]
+		if x.Op != OpARM64ADDconst {
+			break
+		}
+		c := auxIntToInt64(x.AuxInt)
+		y := x.Args[0]
+		if !(x.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64Equal)
+		v0 := b.NewValue0(v.Pos, OpARM64CMNconst, types.TypeFlags)
+		v0.AuxInt = int64ToAuxInt(c)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Equal (CMPWconst [0] x:(ADDconst [c] y)))
+	// cond: x.Uses == 1
+	// result: (Equal (CMNWconst [int32(c)] y))
+	for {
+		if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
+			break
+		}
+		x := v_0.Args[0]
+		if x.Op != OpARM64ADDconst {
+			break
+		}
+		c := auxIntToInt64(x.AuxInt)
+		y := x.Args[0]
+		if !(x.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64Equal)
+		v0 := b.NewValue0(v.Pos, OpARM64CMNWconst, types.TypeFlags)
+		v0.AuxInt = int32ToAuxInt(int32(c))
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Equal (CMPconst [0] z:(ADD x y)))
+	// cond: z.Uses == 1
+	// result: (Equal (CMN x y))
+	for {
+		if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
+			break
+		}
+		z := v_0.Args[0]
+		if z.Op != OpARM64ADD {
+			break
+		}
+		y := z.Args[1]
+		x := z.Args[0]
+		if !(z.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64Equal)
+		v0 := b.NewValue0(v.Pos, OpARM64CMN, types.TypeFlags)
+		v0.AddArg2(x, y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Equal (CMPWconst [0] z:(ADD x y)))
+	// cond: z.Uses == 1
+	// result: (Equal (CMNW x y))
+	for {
+		if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
+			break
+		}
+		z := v_0.Args[0]
+		if z.Op != OpARM64ADD {
+			break
+		}
+		y := z.Args[1]
+		x := z.Args[0]
+		if !(z.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64Equal)
+		v0 := b.NewValue0(v.Pos, OpARM64CMNW, types.TypeFlags)
+		v0.AddArg2(x, y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Equal (CMPconst [0] z:(MADD a x y)))
+	// cond: z.Uses==1
+	// result: (Equal (CMN a (MUL <x.Type> x y)))
+	for {
+		if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
+			break
+		}
+		z := v_0.Args[0]
+		if z.Op != OpARM64MADD {
+			break
+		}
+		y := z.Args[2]
+		a := z.Args[0]
+		x := z.Args[1]
+		if !(z.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64Equal)
+		v0 := b.NewValue0(v.Pos, OpARM64CMN, types.TypeFlags)
+		v1 := b.NewValue0(v.Pos, OpARM64MUL, x.Type)
+		v1.AddArg2(x, y)
+		v0.AddArg2(a, v1)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Equal (CMPconst [0] z:(MSUB a x y)))
+	// cond: z.Uses==1
+	// result: (Equal (CMP a (MUL <x.Type> x y)))
+	for {
+		if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
+			break
+		}
+		z := v_0.Args[0]
+		if z.Op != OpARM64MSUB {
+			break
+		}
+		y := z.Args[2]
+		a := z.Args[0]
+		x := z.Args[1]
+		if !(z.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64Equal)
+		v0 := b.NewValue0(v.Pos, OpARM64CMP, types.TypeFlags)
+		v1 := b.NewValue0(v.Pos, OpARM64MUL, x.Type)
+		v1.AddArg2(x, y)
+		v0.AddArg2(a, v1)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Equal (CMPWconst [0] z:(MADDW a x y)))
+	// cond: z.Uses==1
+	// result: (Equal (CMNW a (MULW <x.Type> x y)))
+	for {
+		if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
+			break
+		}
+		z := v_0.Args[0]
+		if z.Op != OpARM64MADDW {
+			break
+		}
+		y := z.Args[2]
+		a := z.Args[0]
+		x := z.Args[1]
+		if !(z.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64Equal)
+		v0 := b.NewValue0(v.Pos, OpARM64CMNW, types.TypeFlags)
+		v1 := b.NewValue0(v.Pos, OpARM64MULW, x.Type)
+		v1.AddArg2(x, y)
+		v0.AddArg2(a, v1)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Equal (CMPWconst [0] z:(MSUBW a x y)))
+	// cond: z.Uses==1
+	// result: (Equal (CMPW a (MULW <x.Type> x y)))
+	for {
+		if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
+			break
+		}
+		z := v_0.Args[0]
+		if z.Op != OpARM64MSUBW {
+			break
+		}
+		y := z.Args[2]
+		a := z.Args[0]
+		x := z.Args[1]
+		if !(z.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64Equal)
+		v0 := b.NewValue0(v.Pos, OpARM64CMPW, types.TypeFlags)
+		v1 := b.NewValue0(v.Pos, OpARM64MULW, x.Type)
+		v1.AddArg2(x, y)
+		v0.AddArg2(a, v1)
+		v.AddArg(v0)
+		return true
+	}
 	// match: (Equal (FlagConstant [fc]))
 	// result: (MOVDconst [b2i(fc.eq())])
 	for {
@@ -4279,6 +4342,7 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	// match: (FADDD a (FMULD x y))
+	// cond: a.Block.Func.useFMA(v)
 	// result: (FMADDD a x y)
 	for {
 		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
@@ -4288,6 +4352,9 @@
 			}
 			y := v_1.Args[1]
 			x := v_1.Args[0]
+			if !(a.Block.Func.useFMA(v)) {
+				continue
+			}
 			v.reset(OpARM64FMADDD)
 			v.AddArg3(a, x, y)
 			return true
@@ -4295,6 +4362,7 @@
 		break
 	}
 	// match: (FADDD a (FNMULD x y))
+	// cond: a.Block.Func.useFMA(v)
 	// result: (FMSUBD a x y)
 	for {
 		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
@@ -4304,6 +4372,9 @@
 			}
 			y := v_1.Args[1]
 			x := v_1.Args[0]
+			if !(a.Block.Func.useFMA(v)) {
+				continue
+			}
 			v.reset(OpARM64FMSUBD)
 			v.AddArg3(a, x, y)
 			return true
@@ -4316,6 +4387,7 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	// match: (FADDS a (FMULS x y))
+	// cond: a.Block.Func.useFMA(v)
 	// result: (FMADDS a x y)
 	for {
 		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
@@ -4325,6 +4397,9 @@
 			}
 			y := v_1.Args[1]
 			x := v_1.Args[0]
+			if !(a.Block.Func.useFMA(v)) {
+				continue
+			}
 			v.reset(OpARM64FMADDS)
 			v.AddArg3(a, x, y)
 			return true
@@ -4332,6 +4407,7 @@
 		break
 	}
 	// match: (FADDS a (FNMULS x y))
+	// cond: a.Block.Func.useFMA(v)
 	// result: (FMSUBS a x y)
 	for {
 		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
@@ -4341,6 +4417,9 @@
 			}
 			y := v_1.Args[1]
 			x := v_1.Args[0]
+			if !(a.Block.Func.useFMA(v)) {
+				continue
+			}
 			v.reset(OpARM64FMSUBS)
 			v.AddArg3(a, x, y)
 			return true
@@ -4454,8 +4533,6 @@
 func rewriteValueARM64_OpARM64FMOVDload(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	b := v.Block
-	config := b.Func.Config
 	// match: (FMOVDload [off] {sym} ptr (MOVDstore [off] {sym} ptr val _))
 	// result: (FMOVDgpfp val)
 	for {
@@ -4474,7 +4551,7 @@
 		return true
 	}
 	// match: (FMOVDload [off1] {sym} (ADDconst [off2] ptr) mem)
-	// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: is32Bit(int64(off1)+off2)
 	// result: (FMOVDload [off1+int32(off2)] {sym} ptr mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -4485,7 +4562,7 @@
 		off2 := auxIntToInt64(v_0.AuxInt)
 		ptr := v_0.Args[0]
 		mem := v_1
-		if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(is32Bit(int64(off1) + off2)) {
 			break
 		}
 		v.reset(OpARM64FMOVDload)
@@ -4533,7 +4610,7 @@
 		return true
 	}
 	// match: (FMOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
 	// result: (FMOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -4545,7 +4622,7 @@
 		sym2 := auxToSym(v_0.Aux)
 		ptr := v_0.Args[0]
 		mem := v_1
-		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) {
 			break
 		}
 		v.reset(OpARM64FMOVDload)
@@ -4652,8 +4729,6 @@
 	v_2 := v.Args[2]
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	b := v.Block
-	config := b.Func.Config
 	// match: (FMOVDstore [off] {sym} ptr (FMOVDgpfp val) mem)
 	// result: (MOVDstore [off] {sym} ptr val mem)
 	for {
@@ -4672,7 +4747,7 @@
 		return true
 	}
 	// match: (FMOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem)
-	// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: is32Bit(int64(off1)+off2)
 	// result: (FMOVDstore [off1+int32(off2)] {sym} ptr val mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -4684,7 +4759,7 @@
 		ptr := v_0.Args[0]
 		val := v_1
 		mem := v_2
-		if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(is32Bit(int64(off1) + off2)) {
 			break
 		}
 		v.reset(OpARM64FMOVDstore)
@@ -4734,7 +4809,7 @@
 		return true
 	}
 	// match: (FMOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
-	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
 	// result: (FMOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -4747,7 +4822,7 @@
 		ptr := v_0.Args[0]
 		val := v_1
 		mem := v_2
-		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) {
 			break
 		}
 		v.reset(OpARM64FMOVDstore)
@@ -4860,8 +4935,6 @@
 func rewriteValueARM64_OpARM64FMOVSload(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	b := v.Block
-	config := b.Func.Config
 	// match: (FMOVSload [off] {sym} ptr (MOVWstore [off] {sym} ptr val _))
 	// result: (FMOVSgpfp val)
 	for {
@@ -4880,7 +4953,7 @@
 		return true
 	}
 	// match: (FMOVSload [off1] {sym} (ADDconst [off2] ptr) mem)
-	// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: is32Bit(int64(off1)+off2)
 	// result: (FMOVSload [off1+int32(off2)] {sym} ptr mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -4891,7 +4964,7 @@
 		off2 := auxIntToInt64(v_0.AuxInt)
 		ptr := v_0.Args[0]
 		mem := v_1
-		if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(is32Bit(int64(off1) + off2)) {
 			break
 		}
 		v.reset(OpARM64FMOVSload)
@@ -4939,7 +5012,7 @@
 		return true
 	}
 	// match: (FMOVSload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
 	// result: (FMOVSload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -4951,7 +5024,7 @@
 		sym2 := auxToSym(v_0.Aux)
 		ptr := v_0.Args[0]
 		mem := v_1
-		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) {
 			break
 		}
 		v.reset(OpARM64FMOVSload)
@@ -5058,8 +5131,6 @@
 	v_2 := v.Args[2]
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	b := v.Block
-	config := b.Func.Config
 	// match: (FMOVSstore [off] {sym} ptr (FMOVSgpfp val) mem)
 	// result: (MOVWstore [off] {sym} ptr val mem)
 	for {
@@ -5078,7 +5149,7 @@
 		return true
 	}
 	// match: (FMOVSstore [off1] {sym} (ADDconst [off2] ptr) val mem)
-	// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: is32Bit(int64(off1)+off2)
 	// result: (FMOVSstore [off1+int32(off2)] {sym} ptr val mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -5090,7 +5161,7 @@
 		ptr := v_0.Args[0]
 		val := v_1
 		mem := v_2
-		if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(is32Bit(int64(off1) + off2)) {
 			break
 		}
 		v.reset(OpARM64FMOVSstore)
@@ -5140,7 +5211,7 @@
 		return true
 	}
 	// match: (FMOVSstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
-	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
 	// result: (FMOVSstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -5153,7 +5224,7 @@
 		ptr := v_0.Args[0]
 		val := v_1
 		mem := v_2
-		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) {
 			break
 		}
 		v.reset(OpARM64FMOVSstore)
@@ -5403,6 +5474,7 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	// match: (FSUBD a (FMULD x y))
+	// cond: a.Block.Func.useFMA(v)
 	// result: (FMSUBD a x y)
 	for {
 		a := v_0
@@ -5411,11 +5483,15 @@
 		}
 		y := v_1.Args[1]
 		x := v_1.Args[0]
+		if !(a.Block.Func.useFMA(v)) {
+			break
+		}
 		v.reset(OpARM64FMSUBD)
 		v.AddArg3(a, x, y)
 		return true
 	}
 	// match: (FSUBD (FMULD x y) a)
+	// cond: a.Block.Func.useFMA(v)
 	// result: (FNMSUBD a x y)
 	for {
 		if v_0.Op != OpARM64FMULD {
@@ -5424,11 +5500,15 @@
 		y := v_0.Args[1]
 		x := v_0.Args[0]
 		a := v_1
+		if !(a.Block.Func.useFMA(v)) {
+			break
+		}
 		v.reset(OpARM64FNMSUBD)
 		v.AddArg3(a, x, y)
 		return true
 	}
 	// match: (FSUBD a (FNMULD x y))
+	// cond: a.Block.Func.useFMA(v)
 	// result: (FMADDD a x y)
 	for {
 		a := v_0
@@ -5437,11 +5517,15 @@
 		}
 		y := v_1.Args[1]
 		x := v_1.Args[0]
+		if !(a.Block.Func.useFMA(v)) {
+			break
+		}
 		v.reset(OpARM64FMADDD)
 		v.AddArg3(a, x, y)
 		return true
 	}
 	// match: (FSUBD (FNMULD x y) a)
+	// cond: a.Block.Func.useFMA(v)
 	// result: (FNMADDD a x y)
 	for {
 		if v_0.Op != OpARM64FNMULD {
@@ -5450,6 +5534,9 @@
 		y := v_0.Args[1]
 		x := v_0.Args[0]
 		a := v_1
+		if !(a.Block.Func.useFMA(v)) {
+			break
+		}
 		v.reset(OpARM64FNMADDD)
 		v.AddArg3(a, x, y)
 		return true
@@ -5460,6 +5547,7 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	// match: (FSUBS a (FMULS x y))
+	// cond: a.Block.Func.useFMA(v)
 	// result: (FMSUBS a x y)
 	for {
 		a := v_0
@@ -5468,11 +5556,15 @@
 		}
 		y := v_1.Args[1]
 		x := v_1.Args[0]
+		if !(a.Block.Func.useFMA(v)) {
+			break
+		}
 		v.reset(OpARM64FMSUBS)
 		v.AddArg3(a, x, y)
 		return true
 	}
 	// match: (FSUBS (FMULS x y) a)
+	// cond: a.Block.Func.useFMA(v)
 	// result: (FNMSUBS a x y)
 	for {
 		if v_0.Op != OpARM64FMULS {
@@ -5481,11 +5573,15 @@
 		y := v_0.Args[1]
 		x := v_0.Args[0]
 		a := v_1
+		if !(a.Block.Func.useFMA(v)) {
+			break
+		}
 		v.reset(OpARM64FNMSUBS)
 		v.AddArg3(a, x, y)
 		return true
 	}
 	// match: (FSUBS a (FNMULS x y))
+	// cond: a.Block.Func.useFMA(v)
 	// result: (FMADDS a x y)
 	for {
 		a := v_0
@@ -5494,11 +5590,15 @@
 		}
 		y := v_1.Args[1]
 		x := v_1.Args[0]
+		if !(a.Block.Func.useFMA(v)) {
+			break
+		}
 		v.reset(OpARM64FMADDS)
 		v.AddArg3(a, x, y)
 		return true
 	}
 	// match: (FSUBS (FNMULS x y) a)
+	// cond: a.Block.Func.useFMA(v)
 	// result: (FNMADDS a x y)
 	for {
 		if v_0.Op != OpARM64FNMULS {
@@ -5507,6 +5607,9 @@
 		y := v_0.Args[1]
 		x := v_0.Args[0]
 		a := v_1
+		if !(a.Block.Func.useFMA(v)) {
+			break
+		}
 		v.reset(OpARM64FNMADDS)
 		v.AddArg3(a, x, y)
 		return true
@@ -5515,6 +5618,97 @@
 }
 func rewriteValueARM64_OpARM64GreaterEqual(v *Value) bool {
 	v_0 := v.Args[0]
+	b := v.Block
+	// match: (GreaterEqual (CMPconst [0] z:(AND x y)))
+	// cond: z.Uses == 1
+	// result: (GreaterEqual (TST x y))
+	for {
+		if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
+			break
+		}
+		z := v_0.Args[0]
+		if z.Op != OpARM64AND {
+			break
+		}
+		y := z.Args[1]
+		x := z.Args[0]
+		if !(z.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64GreaterEqual)
+		v0 := b.NewValue0(v.Pos, OpARM64TST, types.TypeFlags)
+		v0.AddArg2(x, y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (GreaterEqual (CMPWconst [0] x:(ANDconst [c] y)))
+	// cond: x.Uses == 1
+	// result: (GreaterEqual (TSTWconst [int32(c)] y))
+	for {
+		if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
+			break
+		}
+		x := v_0.Args[0]
+		if x.Op != OpARM64ANDconst {
+			break
+		}
+		c := auxIntToInt64(x.AuxInt)
+		y := x.Args[0]
+		if !(x.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64GreaterEqual)
+		v0 := b.NewValue0(v.Pos, OpARM64TSTWconst, types.TypeFlags)
+		v0.AuxInt = int32ToAuxInt(int32(c))
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (GreaterEqual (CMPWconst [0] z:(AND x y)))
+	// cond: z.Uses == 1
+	// result: (GreaterEqual (TSTW x y))
+	for {
+		if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
+			break
+		}
+		z := v_0.Args[0]
+		if z.Op != OpARM64AND {
+			break
+		}
+		y := z.Args[1]
+		x := z.Args[0]
+		if !(z.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64GreaterEqual)
+		v0 := b.NewValue0(v.Pos, OpARM64TSTW, types.TypeFlags)
+		v0.AddArg2(x, y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (GreaterEqual (CMPWconst [0] x:(ANDconst [c] y)))
+	// cond: x.Uses == 1
+	// result: (GreaterEqual (TSTconst [c] y))
+	for {
+		if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
+			break
+		}
+		x := v_0.Args[0]
+		if x.Op != OpARM64ANDconst {
+			break
+		}
+		c := auxIntToInt64(x.AuxInt)
+		y := x.Args[0]
+		if !(x.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64GreaterEqual)
+		v0 := b.NewValue0(v.Pos, OpARM64TSTconst, types.TypeFlags)
+		v0.AuxInt = int64ToAuxInt(c)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
 	// match: (GreaterEqual (FlagConstant [fc]))
 	// result: (MOVDconst [b2i(fc.ge())])
 	for {
@@ -5582,6 +5776,97 @@
 }
 func rewriteValueARM64_OpARM64GreaterThan(v *Value) bool {
 	v_0 := v.Args[0]
+	b := v.Block
+	// match: (GreaterThan (CMPconst [0] z:(AND x y)))
+	// cond: z.Uses == 1
+	// result: (GreaterThan (TST x y))
+	for {
+		if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
+			break
+		}
+		z := v_0.Args[0]
+		if z.Op != OpARM64AND {
+			break
+		}
+		y := z.Args[1]
+		x := z.Args[0]
+		if !(z.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64GreaterThan)
+		v0 := b.NewValue0(v.Pos, OpARM64TST, types.TypeFlags)
+		v0.AddArg2(x, y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (GreaterThan (CMPWconst [0] x:(ANDconst [c] y)))
+	// cond: x.Uses == 1
+	// result: (GreaterThan (TSTWconst [int32(c)] y))
+	for {
+		if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
+			break
+		}
+		x := v_0.Args[0]
+		if x.Op != OpARM64ANDconst {
+			break
+		}
+		c := auxIntToInt64(x.AuxInt)
+		y := x.Args[0]
+		if !(x.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64GreaterThan)
+		v0 := b.NewValue0(v.Pos, OpARM64TSTWconst, types.TypeFlags)
+		v0.AuxInt = int32ToAuxInt(int32(c))
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (GreaterThan (CMPWconst [0] z:(AND x y)))
+	// cond: z.Uses == 1
+	// result: (GreaterThan (TSTW x y))
+	for {
+		if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
+			break
+		}
+		z := v_0.Args[0]
+		if z.Op != OpARM64AND {
+			break
+		}
+		y := z.Args[1]
+		x := z.Args[0]
+		if !(z.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64GreaterThan)
+		v0 := b.NewValue0(v.Pos, OpARM64TSTW, types.TypeFlags)
+		v0.AddArg2(x, y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (GreaterThan (CMPWconst [0] x:(ANDconst [c] y)))
+	// cond: x.Uses == 1
+	// result: (GreaterThan (TSTconst [c] y))
+	for {
+		if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
+			break
+		}
+		x := v_0.Args[0]
+		if x.Op != OpARM64ANDconst {
+			break
+		}
+		c := auxIntToInt64(x.AuxInt)
+		y := x.Args[0]
+		if !(x.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64GreaterThan)
+		v0 := b.NewValue0(v.Pos, OpARM64TSTconst, types.TypeFlags)
+		v0.AuxInt = int64ToAuxInt(c)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
 	// match: (GreaterThan (FlagConstant [fc]))
 	// result: (MOVDconst [b2i(fc.gt())])
 	for {
@@ -5647,8 +5932,147 @@
 	}
 	return false
 }
+func rewriteValueARM64_OpARM64LDP(v *Value) bool {
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	// match: (LDP [off1] {sym} (ADDconst [off2] ptr) mem)
+	// cond: is32Bit(int64(off1)+off2)
+	// result: (LDP [off1+int32(off2)] {sym} ptr mem)
+	for {
+		off1 := auxIntToInt32(v.AuxInt)
+		sym := auxToSym(v.Aux)
+		if v_0.Op != OpARM64ADDconst {
+			break
+		}
+		off2 := auxIntToInt64(v_0.AuxInt)
+		ptr := v_0.Args[0]
+		mem := v_1
+		if !(is32Bit(int64(off1) + off2)) {
+			break
+		}
+		v.reset(OpARM64LDP)
+		v.AuxInt = int32ToAuxInt(off1 + int32(off2))
+		v.Aux = symToAux(sym)
+		v.AddArg2(ptr, mem)
+		return true
+	}
+	// match: (LDP [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
+	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
+	// result: (LDP [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+	for {
+		off1 := auxIntToInt32(v.AuxInt)
+		sym1 := auxToSym(v.Aux)
+		if v_0.Op != OpARM64MOVDaddr {
+			break
+		}
+		off2 := auxIntToInt32(v_0.AuxInt)
+		sym2 := auxToSym(v_0.Aux)
+		ptr := v_0.Args[0]
+		mem := v_1
+		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) {
+			break
+		}
+		v.reset(OpARM64LDP)
+		v.AuxInt = int32ToAuxInt(off1 + off2)
+		v.Aux = symToAux(mergeSym(sym1, sym2))
+		v.AddArg2(ptr, mem)
+		return true
+	}
+	return false
+}
 func rewriteValueARM64_OpARM64LessEqual(v *Value) bool {
 	v_0 := v.Args[0]
+	b := v.Block
+	// match: (LessEqual (CMPconst [0] z:(AND x y)))
+	// cond: z.Uses == 1
+	// result: (LessEqual (TST x y))
+	for {
+		if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
+			break
+		}
+		z := v_0.Args[0]
+		if z.Op != OpARM64AND {
+			break
+		}
+		y := z.Args[1]
+		x := z.Args[0]
+		if !(z.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64LessEqual)
+		v0 := b.NewValue0(v.Pos, OpARM64TST, types.TypeFlags)
+		v0.AddArg2(x, y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (LessEqual (CMPWconst [0] x:(ANDconst [c] y)))
+	// cond: x.Uses == 1
+	// result: (LessEqual (TSTWconst [int32(c)] y))
+	for {
+		if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
+			break
+		}
+		x := v_0.Args[0]
+		if x.Op != OpARM64ANDconst {
+			break
+		}
+		c := auxIntToInt64(x.AuxInt)
+		y := x.Args[0]
+		if !(x.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64LessEqual)
+		v0 := b.NewValue0(v.Pos, OpARM64TSTWconst, types.TypeFlags)
+		v0.AuxInt = int32ToAuxInt(int32(c))
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (LessEqual (CMPWconst [0] z:(AND x y)))
+	// cond: z.Uses == 1
+	// result: (LessEqual (TSTW x y))
+	for {
+		if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
+			break
+		}
+		z := v_0.Args[0]
+		if z.Op != OpARM64AND {
+			break
+		}
+		y := z.Args[1]
+		x := z.Args[0]
+		if !(z.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64LessEqual)
+		v0 := b.NewValue0(v.Pos, OpARM64TSTW, types.TypeFlags)
+		v0.AddArg2(x, y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (LessEqual (CMPWconst [0] x:(ANDconst [c] y)))
+	// cond: x.Uses == 1
+	// result: (LessEqual (TSTconst [c] y))
+	for {
+		if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
+			break
+		}
+		x := v_0.Args[0]
+		if x.Op != OpARM64ANDconst {
+			break
+		}
+		c := auxIntToInt64(x.AuxInt)
+		y := x.Args[0]
+		if !(x.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64LessEqual)
+		v0 := b.NewValue0(v.Pos, OpARM64TSTconst, types.TypeFlags)
+		v0.AuxInt = int64ToAuxInt(c)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
 	// match: (LessEqual (FlagConstant [fc]))
 	// result: (MOVDconst [b2i(fc.le())])
 	for {
@@ -5716,6 +6140,97 @@
 }
 func rewriteValueARM64_OpARM64LessThan(v *Value) bool {
 	v_0 := v.Args[0]
+	b := v.Block
+	// match: (LessThan (CMPconst [0] z:(AND x y)))
+	// cond: z.Uses == 1
+	// result: (LessThan (TST x y))
+	for {
+		if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
+			break
+		}
+		z := v_0.Args[0]
+		if z.Op != OpARM64AND {
+			break
+		}
+		y := z.Args[1]
+		x := z.Args[0]
+		if !(z.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64LessThan)
+		v0 := b.NewValue0(v.Pos, OpARM64TST, types.TypeFlags)
+		v0.AddArg2(x, y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (LessThan (CMPWconst [0] x:(ANDconst [c] y)))
+	// cond: x.Uses == 1
+	// result: (LessThan (TSTWconst [int32(c)] y))
+	for {
+		if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
+			break
+		}
+		x := v_0.Args[0]
+		if x.Op != OpARM64ANDconst {
+			break
+		}
+		c := auxIntToInt64(x.AuxInt)
+		y := x.Args[0]
+		if !(x.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64LessThan)
+		v0 := b.NewValue0(v.Pos, OpARM64TSTWconst, types.TypeFlags)
+		v0.AuxInt = int32ToAuxInt(int32(c))
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (LessThan (CMPWconst [0] z:(AND x y)))
+	// cond: z.Uses == 1
+	// result: (LessThan (TSTW x y))
+	for {
+		if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
+			break
+		}
+		z := v_0.Args[0]
+		if z.Op != OpARM64AND {
+			break
+		}
+		y := z.Args[1]
+		x := z.Args[0]
+		if !(z.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64LessThan)
+		v0 := b.NewValue0(v.Pos, OpARM64TSTW, types.TypeFlags)
+		v0.AddArg2(x, y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (LessThan (CMPWconst [0] x:(ANDconst [c] y)))
+	// cond: x.Uses == 1
+	// result: (LessThan (TSTconst [c] y))
+	for {
+		if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
+			break
+		}
+		x := v_0.Args[0]
+		if x.Op != OpARM64ANDconst {
+			break
+		}
+		c := auxIntToInt64(x.AuxInt)
+		y := x.Args[0]
+		if !(x.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64LessThan)
+		v0 := b.NewValue0(v.Pos, OpARM64TSTconst, types.TypeFlags)
+		v0.AuxInt = int64ToAuxInt(c)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
 	// match: (LessThan (FlagConstant [fc]))
 	// result: (MOVDconst [b2i(fc.lt())])
 	for {
@@ -7121,10 +7636,8 @@
 func rewriteValueARM64_OpARM64MOVBUload(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	b := v.Block
-	config := b.Func.Config
 	// match: (MOVBUload [off1] {sym} (ADDconst [off2] ptr) mem)
-	// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: is32Bit(int64(off1)+off2)
 	// result: (MOVBUload [off1+int32(off2)] {sym} ptr mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -7135,7 +7648,7 @@
 		off2 := auxIntToInt64(v_0.AuxInt)
 		ptr := v_0.Args[0]
 		mem := v_1
-		if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(is32Bit(int64(off1) + off2)) {
 			break
 		}
 		v.reset(OpARM64MOVBUload)
@@ -7164,7 +7677,7 @@
 		return true
 	}
 	// match: (MOVBUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
 	// result: (MOVBUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -7176,7 +7689,7 @@
 		sym2 := auxToSym(v_0.Aux)
 		ptr := v_0.Args[0]
 		mem := v_1
-		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) {
 			break
 		}
 		v.reset(OpARM64MOVBUload)
@@ -7564,10 +8077,8 @@
 func rewriteValueARM64_OpARM64MOVBload(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	b := v.Block
-	config := b.Func.Config
 	// match: (MOVBload [off1] {sym} (ADDconst [off2] ptr) mem)
-	// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: is32Bit(int64(off1)+off2)
 	// result: (MOVBload [off1+int32(off2)] {sym} ptr mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -7578,7 +8089,7 @@
 		off2 := auxIntToInt64(v_0.AuxInt)
 		ptr := v_0.Args[0]
 		mem := v_1
-		if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(is32Bit(int64(off1) + off2)) {
 			break
 		}
 		v.reset(OpARM64MOVBload)
@@ -7607,7 +8118,7 @@
 		return true
 	}
 	// match: (MOVBload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
 	// result: (MOVBload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -7619,7 +8130,7 @@
 		sym2 := auxToSym(v_0.Aux)
 		ptr := v_0.Args[0]
 		mem := v_1
-		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) {
 			break
 		}
 		v.reset(OpARM64MOVBload)
@@ -7797,9 +8308,8 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
-	config := b.Func.Config
 	// match: (MOVBstore [off1] {sym} (ADDconst [off2] ptr) val mem)
-	// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: is32Bit(int64(off1)+off2)
 	// result: (MOVBstore [off1+int32(off2)] {sym} ptr val mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -7811,7 +8321,7 @@
 		ptr := v_0.Args[0]
 		val := v_1
 		mem := v_2
-		if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(is32Bit(int64(off1) + off2)) {
 			break
 		}
 		v.reset(OpARM64MOVBstore)
@@ -7841,7 +8351,7 @@
 		return true
 	}
 	// match: (MOVBstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
-	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
 	// result: (MOVBstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -7854,7 +8364,7 @@
 		ptr := v_0.Args[0]
 		val := v_1
 		mem := v_2
-		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) {
 			break
 		}
 		v.reset(OpARM64MOVBstore)
@@ -9649,10 +10159,8 @@
 func rewriteValueARM64_OpARM64MOVBstorezero(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	b := v.Block
-	config := b.Func.Config
 	// match: (MOVBstorezero [off1] {sym} (ADDconst [off2] ptr) mem)
-	// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: is32Bit(int64(off1)+off2)
 	// result: (MOVBstorezero [off1+int32(off2)] {sym} ptr mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -9663,7 +10171,7 @@
 		off2 := auxIntToInt64(v_0.AuxInt)
 		ptr := v_0.Args[0]
 		mem := v_1
-		if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(is32Bit(int64(off1) + off2)) {
 			break
 		}
 		v.reset(OpARM64MOVBstorezero)
@@ -9673,7 +10181,7 @@
 		return true
 	}
 	// match: (MOVBstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
 	// result: (MOVBstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -9685,7 +10193,7 @@
 		sym2 := auxToSym(v_0.Aux)
 		ptr := v_0.Args[0]
 		mem := v_1
-		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) {
 			break
 		}
 		v.reset(OpARM64MOVBstorezero)
@@ -9860,7 +10368,7 @@
 		return true
 	}
 	// match: (MOVDload [off1] {sym} (ADDconst [off2] ptr) mem)
-	// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: is32Bit(int64(off1)+off2)
 	// result: (MOVDload [off1+int32(off2)] {sym} ptr mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -9871,7 +10379,7 @@
 		off2 := auxIntToInt64(v_0.AuxInt)
 		ptr := v_0.Args[0]
 		mem := v_1
-		if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(is32Bit(int64(off1) + off2)) {
 			break
 		}
 		v.reset(OpARM64MOVDload)
@@ -9919,7 +10427,7 @@
 		return true
 	}
 	// match: (MOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
 	// result: (MOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -9931,7 +10439,7 @@
 		sym2 := auxToSym(v_0.Aux)
 		ptr := v_0.Args[0]
 		mem := v_1
-		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) {
 			break
 		}
 		v.reset(OpARM64MOVDload)
@@ -10149,8 +10657,6 @@
 	v_2 := v.Args[2]
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	b := v.Block
-	config := b.Func.Config
 	// match: (MOVDstore [off] {sym} ptr (FMOVDfpgp val) mem)
 	// result: (FMOVDstore [off] {sym} ptr val mem)
 	for {
@@ -10169,7 +10675,7 @@
 		return true
 	}
 	// match: (MOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem)
-	// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: is32Bit(int64(off1)+off2)
 	// result: (MOVDstore [off1+int32(off2)] {sym} ptr val mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -10181,7 +10687,7 @@
 		ptr := v_0.Args[0]
 		val := v_1
 		mem := v_2
-		if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(is32Bit(int64(off1) + off2)) {
 			break
 		}
 		v.reset(OpARM64MOVDstore)
@@ -10231,7 +10737,7 @@
 		return true
 	}
 	// match: (MOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
-	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
 	// result: (MOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -10244,7 +10750,7 @@
 		ptr := v_0.Args[0]
 		val := v_1
 		mem := v_2
-		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) {
 			break
 		}
 		v.reset(OpARM64MOVDstore)
@@ -10399,10 +10905,8 @@
 func rewriteValueARM64_OpARM64MOVDstorezero(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	b := v.Block
-	config := b.Func.Config
 	// match: (MOVDstorezero [off1] {sym} (ADDconst [off2] ptr) mem)
-	// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: is32Bit(int64(off1)+off2)
 	// result: (MOVDstorezero [off1+int32(off2)] {sym} ptr mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -10413,7 +10917,7 @@
 		off2 := auxIntToInt64(v_0.AuxInt)
 		ptr := v_0.Args[0]
 		mem := v_1
-		if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(is32Bit(int64(off1) + off2)) {
 			break
 		}
 		v.reset(OpARM64MOVDstorezero)
@@ -10423,7 +10927,7 @@
 		return true
 	}
 	// match: (MOVDstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
 	// result: (MOVDstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -10435,7 +10939,7 @@
 		sym2 := auxToSym(v_0.Aux)
 		ptr := v_0.Args[0]
 		mem := v_1
-		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) {
 			break
 		}
 		v.reset(OpARM64MOVDstorezero)
@@ -10674,7 +11178,7 @@
 	b := v.Block
 	config := b.Func.Config
 	// match: (MOVHUload [off1] {sym} (ADDconst [off2] ptr) mem)
-	// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: is32Bit(int64(off1)+off2)
 	// result: (MOVHUload [off1+int32(off2)] {sym} ptr mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -10685,7 +11189,7 @@
 		off2 := auxIntToInt64(v_0.AuxInt)
 		ptr := v_0.Args[0]
 		mem := v_1
-		if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(is32Bit(int64(off1) + off2)) {
 			break
 		}
 		v.reset(OpARM64MOVHUload)
@@ -10733,7 +11237,7 @@
 		return true
 	}
 	// match: (MOVHUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
 	// result: (MOVHUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -10745,7 +11249,7 @@
 		sym2 := auxToSym(v_0.Aux)
 		ptr := v_0.Args[0]
 		mem := v_1
-		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) {
 			break
 		}
 		v.reset(OpARM64MOVHUload)
@@ -11110,10 +11614,8 @@
 func rewriteValueARM64_OpARM64MOVHload(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	b := v.Block
-	config := b.Func.Config
 	// match: (MOVHload [off1] {sym} (ADDconst [off2] ptr) mem)
-	// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: is32Bit(int64(off1)+off2)
 	// result: (MOVHload [off1+int32(off2)] {sym} ptr mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -11124,7 +11626,7 @@
 		off2 := auxIntToInt64(v_0.AuxInt)
 		ptr := v_0.Args[0]
 		mem := v_1
-		if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(is32Bit(int64(off1) + off2)) {
 			break
 		}
 		v.reset(OpARM64MOVHload)
@@ -11172,7 +11674,7 @@
 		return true
 	}
 	// match: (MOVHload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
 	// result: (MOVHload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -11184,7 +11686,7 @@
 		sym2 := auxToSym(v_0.Aux)
 		ptr := v_0.Args[0]
 		mem := v_1
-		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) {
 			break
 		}
 		v.reset(OpARM64MOVHload)
@@ -11526,9 +12028,8 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
-	config := b.Func.Config
 	// match: (MOVHstore [off1] {sym} (ADDconst [off2] ptr) val mem)
-	// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: is32Bit(int64(off1)+off2)
 	// result: (MOVHstore [off1+int32(off2)] {sym} ptr val mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -11540,7 +12041,7 @@
 		ptr := v_0.Args[0]
 		val := v_1
 		mem := v_2
-		if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(is32Bit(int64(off1) + off2)) {
 			break
 		}
 		v.reset(OpARM64MOVHstore)
@@ -11590,7 +12091,7 @@
 		return true
 	}
 	// match: (MOVHstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
-	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
 	// result: (MOVHstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -11603,7 +12104,7 @@
 		ptr := v_0.Args[0]
 		val := v_1
 		mem := v_2
-		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) {
 			break
 		}
 		v.reset(OpARM64MOVHstore)
@@ -12404,9 +12905,8 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
-	config := b.Func.Config
 	// match: (MOVHstorezero [off1] {sym} (ADDconst [off2] ptr) mem)
-	// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: is32Bit(int64(off1)+off2)
 	// result: (MOVHstorezero [off1+int32(off2)] {sym} ptr mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -12417,7 +12917,7 @@
 		off2 := auxIntToInt64(v_0.AuxInt)
 		ptr := v_0.Args[0]
 		mem := v_1
-		if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(is32Bit(int64(off1) + off2)) {
 			break
 		}
 		v.reset(OpARM64MOVHstorezero)
@@ -12427,7 +12927,7 @@
 		return true
 	}
 	// match: (MOVHstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
 	// result: (MOVHstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -12439,7 +12939,7 @@
 		sym2 := auxToSym(v_0.Aux)
 		ptr := v_0.Args[0]
 		mem := v_1
-		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) {
 			break
 		}
 		v.reset(OpARM64MOVHstorezero)
@@ -12725,10 +13225,8 @@
 func rewriteValueARM64_OpARM64MOVQstorezero(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	b := v.Block
-	config := b.Func.Config
 	// match: (MOVQstorezero [off1] {sym} (ADDconst [off2] ptr) mem)
-	// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: is32Bit(int64(off1)+off2)
 	// result: (MOVQstorezero [off1+int32(off2)] {sym} ptr mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -12739,7 +13237,7 @@
 		off2 := auxIntToInt64(v_0.AuxInt)
 		ptr := v_0.Args[0]
 		mem := v_1
-		if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(is32Bit(int64(off1) + off2)) {
 			break
 		}
 		v.reset(OpARM64MOVQstorezero)
@@ -12749,7 +13247,7 @@
 		return true
 	}
 	// match: (MOVQstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
 	// result: (MOVQstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -12761,7 +13259,7 @@
 		sym2 := auxToSym(v_0.Aux)
 		ptr := v_0.Args[0]
 		mem := v_1
-		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) {
 			break
 		}
 		v.reset(OpARM64MOVQstorezero)
@@ -12795,7 +13293,7 @@
 		return true
 	}
 	// match: (MOVWUload [off1] {sym} (ADDconst [off2] ptr) mem)
-	// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: is32Bit(int64(off1)+off2)
 	// result: (MOVWUload [off1+int32(off2)] {sym} ptr mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -12806,7 +13304,7 @@
 		off2 := auxIntToInt64(v_0.AuxInt)
 		ptr := v_0.Args[0]
 		mem := v_1
-		if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(is32Bit(int64(off1) + off2)) {
 			break
 		}
 		v.reset(OpARM64MOVWUload)
@@ -12854,7 +13352,7 @@
 		return true
 	}
 	// match: (MOVWUload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
 	// result: (MOVWUload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -12866,7 +13364,7 @@
 		sym2 := auxToSym(v_0.Aux)
 		ptr := v_0.Args[0]
 		mem := v_1
-		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) {
 			break
 		}
 		v.reset(OpARM64MOVWUload)
@@ -13256,10 +13754,8 @@
 func rewriteValueARM64_OpARM64MOVWload(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	b := v.Block
-	config := b.Func.Config
 	// match: (MOVWload [off1] {sym} (ADDconst [off2] ptr) mem)
-	// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: is32Bit(int64(off1)+off2)
 	// result: (MOVWload [off1+int32(off2)] {sym} ptr mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -13270,7 +13766,7 @@
 		off2 := auxIntToInt64(v_0.AuxInt)
 		ptr := v_0.Args[0]
 		mem := v_1
-		if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(is32Bit(int64(off1) + off2)) {
 			break
 		}
 		v.reset(OpARM64MOVWload)
@@ -13318,7 +13814,7 @@
 		return true
 	}
 	// match: (MOVWload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
 	// result: (MOVWload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -13330,7 +13826,7 @@
 		sym2 := auxToSym(v_0.Aux)
 		ptr := v_0.Args[0]
 		mem := v_1
-		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) {
 			break
 		}
 		v.reset(OpARM64MOVWload)
@@ -13730,7 +14226,6 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
-	config := b.Func.Config
 	// match: (MOVWstore [off] {sym} ptr (FMOVSfpgp val) mem)
 	// result: (FMOVSstore [off] {sym} ptr val mem)
 	for {
@@ -13749,7 +14244,7 @@
 		return true
 	}
 	// match: (MOVWstore [off1] {sym} (ADDconst [off2] ptr) val mem)
-	// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: is32Bit(int64(off1)+off2)
 	// result: (MOVWstore [off1+int32(off2)] {sym} ptr val mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -13761,7 +14256,7 @@
 		ptr := v_0.Args[0]
 		val := v_1
 		mem := v_2
-		if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(is32Bit(int64(off1) + off2)) {
 			break
 		}
 		v.reset(OpARM64MOVWstore)
@@ -13811,7 +14306,7 @@
 		return true
 	}
 	// match: (MOVWstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
-	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
 	// result: (MOVWstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -13824,7 +14319,7 @@
 		ptr := v_0.Args[0]
 		val := v_1
 		mem := v_2
-		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) {
 			break
 		}
 		v.reset(OpARM64MOVWstore)
@@ -14295,9 +14790,8 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
-	config := b.Func.Config
 	// match: (MOVWstorezero [off1] {sym} (ADDconst [off2] ptr) mem)
-	// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: is32Bit(int64(off1)+off2)
 	// result: (MOVWstorezero [off1+int32(off2)] {sym} ptr mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -14308,7 +14802,7 @@
 		off2 := auxIntToInt64(v_0.AuxInt)
 		ptr := v_0.Args[0]
 		mem := v_1
-		if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(is32Bit(int64(off1) + off2)) {
 			break
 		}
 		v.reset(OpARM64MOVWstorezero)
@@ -14318,7 +14812,7 @@
 		return true
 	}
 	// match: (MOVWstorezero [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
-	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
 	// result: (MOVWstorezero [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -14330,7 +14824,7 @@
 		sym2 := auxToSym(v_0.Aux)
 		ptr := v_0.Args[0]
 		mem := v_1
-		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) {
 			break
 		}
 		v.reset(OpARM64MOVWstorezero)
@@ -16196,6 +16690,333 @@
 }
 func rewriteValueARM64_OpARM64NotEqual(v *Value) bool {
 	v_0 := v.Args[0]
+	b := v.Block
+	// match: (NotEqual (CMPconst [0] z:(AND x y)))
+	// cond: z.Uses == 1
+	// result: (NotEqual (TST x y))
+	for {
+		if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
+			break
+		}
+		z := v_0.Args[0]
+		if z.Op != OpARM64AND {
+			break
+		}
+		y := z.Args[1]
+		x := z.Args[0]
+		if !(z.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64NotEqual)
+		v0 := b.NewValue0(v.Pos, OpARM64TST, types.TypeFlags)
+		v0.AddArg2(x, y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (NotEqual (CMPWconst [0] x:(ANDconst [c] y)))
+	// cond: x.Uses == 1
+	// result: (NotEqual (TSTWconst [int32(c)] y))
+	for {
+		if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
+			break
+		}
+		x := v_0.Args[0]
+		if x.Op != OpARM64ANDconst {
+			break
+		}
+		c := auxIntToInt64(x.AuxInt)
+		y := x.Args[0]
+		if !(x.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64NotEqual)
+		v0 := b.NewValue0(v.Pos, OpARM64TSTWconst, types.TypeFlags)
+		v0.AuxInt = int32ToAuxInt(int32(c))
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (NotEqual (CMPWconst [0] z:(AND x y)))
+	// cond: z.Uses == 1
+	// result: (NotEqual (TSTW x y))
+	for {
+		if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
+			break
+		}
+		z := v_0.Args[0]
+		if z.Op != OpARM64AND {
+			break
+		}
+		y := z.Args[1]
+		x := z.Args[0]
+		if !(z.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64NotEqual)
+		v0 := b.NewValue0(v.Pos, OpARM64TSTW, types.TypeFlags)
+		v0.AddArg2(x, y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (NotEqual (CMPconst [0] x:(ANDconst [c] y)))
+	// cond: x.Uses == 1
+	// result: (NotEqual (TSTconst [c] y))
+	for {
+		if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
+			break
+		}
+		x := v_0.Args[0]
+		if x.Op != OpARM64ANDconst {
+			break
+		}
+		c := auxIntToInt64(x.AuxInt)
+		y := x.Args[0]
+		if !(x.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64NotEqual)
+		v0 := b.NewValue0(v.Pos, OpARM64TSTconst, types.TypeFlags)
+		v0.AuxInt = int64ToAuxInt(c)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (NotEqual (CMP x z:(NEG y)))
+	// cond: z.Uses == 1
+	// result: (NotEqual (CMN x y))
+	for {
+		if v_0.Op != OpARM64CMP {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		z := v_0.Args[1]
+		if z.Op != OpARM64NEG {
+			break
+		}
+		y := z.Args[0]
+		if !(z.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64NotEqual)
+		v0 := b.NewValue0(v.Pos, OpARM64CMN, types.TypeFlags)
+		v0.AddArg2(x, y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (NotEqual (CMPW x z:(NEG y)))
+	// cond: z.Uses == 1
+	// result: (NotEqual (CMNW x y))
+	for {
+		if v_0.Op != OpARM64CMPW {
+			break
+		}
+		_ = v_0.Args[1]
+		x := v_0.Args[0]
+		z := v_0.Args[1]
+		if z.Op != OpARM64NEG {
+			break
+		}
+		y := z.Args[0]
+		if !(z.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64NotEqual)
+		v0 := b.NewValue0(v.Pos, OpARM64CMNW, types.TypeFlags)
+		v0.AddArg2(x, y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (NotEqual (CMPconst [0] x:(ADDconst [c] y)))
+	// cond: x.Uses == 1
+	// result: (NotEqual (CMNconst [c] y))
+	for {
+		if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
+			break
+		}
+		x := v_0.Args[0]
+		if x.Op != OpARM64ADDconst {
+			break
+		}
+		c := auxIntToInt64(x.AuxInt)
+		y := x.Args[0]
+		if !(x.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64NotEqual)
+		v0 := b.NewValue0(v.Pos, OpARM64CMNconst, types.TypeFlags)
+		v0.AuxInt = int64ToAuxInt(c)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (NotEqual (CMPWconst [0] x:(ADDconst [c] y)))
+	// cond: x.Uses == 1
+	// result: (NotEqual (CMNWconst [int32(c)] y))
+	for {
+		if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
+			break
+		}
+		x := v_0.Args[0]
+		if x.Op != OpARM64ADDconst {
+			break
+		}
+		c := auxIntToInt64(x.AuxInt)
+		y := x.Args[0]
+		if !(x.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64NotEqual)
+		v0 := b.NewValue0(v.Pos, OpARM64CMNWconst, types.TypeFlags)
+		v0.AuxInt = int32ToAuxInt(int32(c))
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (NotEqual (CMPconst [0] z:(ADD x y)))
+	// cond: z.Uses == 1
+	// result: (NotEqual (CMN x y))
+	for {
+		if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
+			break
+		}
+		z := v_0.Args[0]
+		if z.Op != OpARM64ADD {
+			break
+		}
+		y := z.Args[1]
+		x := z.Args[0]
+		if !(z.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64NotEqual)
+		v0 := b.NewValue0(v.Pos, OpARM64CMN, types.TypeFlags)
+		v0.AddArg2(x, y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (NotEqual (CMPWconst [0] z:(ADD x y)))
+	// cond: z.Uses == 1
+	// result: (NotEqual (CMNW x y))
+	for {
+		if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
+			break
+		}
+		z := v_0.Args[0]
+		if z.Op != OpARM64ADD {
+			break
+		}
+		y := z.Args[1]
+		x := z.Args[0]
+		if !(z.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64NotEqual)
+		v0 := b.NewValue0(v.Pos, OpARM64CMNW, types.TypeFlags)
+		v0.AddArg2(x, y)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (NotEqual (CMPconst [0] z:(MADD a x y)))
+	// cond: z.Uses==1
+	// result: (NotEqual (CMN a (MUL <x.Type> x y)))
+	for {
+		if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
+			break
+		}
+		z := v_0.Args[0]
+		if z.Op != OpARM64MADD {
+			break
+		}
+		y := z.Args[2]
+		a := z.Args[0]
+		x := z.Args[1]
+		if !(z.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64NotEqual)
+		v0 := b.NewValue0(v.Pos, OpARM64CMN, types.TypeFlags)
+		v1 := b.NewValue0(v.Pos, OpARM64MUL, x.Type)
+		v1.AddArg2(x, y)
+		v0.AddArg2(a, v1)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (NotEqual (CMPconst [0] z:(MSUB a x y)))
+	// cond: z.Uses==1
+	// result: (NotEqual (CMP a (MUL <x.Type> x y)))
+	for {
+		if v_0.Op != OpARM64CMPconst || auxIntToInt64(v_0.AuxInt) != 0 {
+			break
+		}
+		z := v_0.Args[0]
+		if z.Op != OpARM64MSUB {
+			break
+		}
+		y := z.Args[2]
+		a := z.Args[0]
+		x := z.Args[1]
+		if !(z.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64NotEqual)
+		v0 := b.NewValue0(v.Pos, OpARM64CMP, types.TypeFlags)
+		v1 := b.NewValue0(v.Pos, OpARM64MUL, x.Type)
+		v1.AddArg2(x, y)
+		v0.AddArg2(a, v1)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (NotEqual (CMPWconst [0] z:(MADDW a x y)))
+	// cond: z.Uses==1
+	// result: (NotEqual (CMNW a (MULW <x.Type> x y)))
+	for {
+		if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
+			break
+		}
+		z := v_0.Args[0]
+		if z.Op != OpARM64MADDW {
+			break
+		}
+		y := z.Args[2]
+		a := z.Args[0]
+		x := z.Args[1]
+		if !(z.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64NotEqual)
+		v0 := b.NewValue0(v.Pos, OpARM64CMNW, types.TypeFlags)
+		v1 := b.NewValue0(v.Pos, OpARM64MULW, x.Type)
+		v1.AddArg2(x, y)
+		v0.AddArg2(a, v1)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (NotEqual (CMPWconst [0] z:(MSUBW a x y)))
+	// cond: z.Uses==1
+	// result: (NotEqual (CMPW a (MULW <x.Type> x y)))
+	for {
+		if v_0.Op != OpARM64CMPWconst || auxIntToInt32(v_0.AuxInt) != 0 {
+			break
+		}
+		z := v_0.Args[0]
+		if z.Op != OpARM64MSUBW {
+			break
+		}
+		y := z.Args[2]
+		a := z.Args[0]
+		x := z.Args[1]
+		if !(z.Uses == 1) {
+			break
+		}
+		v.reset(OpARM64NotEqual)
+		v0 := b.NewValue0(v.Pos, OpARM64CMPW, types.TypeFlags)
+		v1 := b.NewValue0(v.Pos, OpARM64MULW, x.Type)
+		v1.AddArg2(x, y)
+		v0.AddArg2(a, v1)
+		v.AddArg(v0)
+		return true
+	}
 	// match: (NotEqual (FlagConstant [fc]))
 	// result: (MOVDconst [b2i(fc.ne())])
 	for {
@@ -16224,7 +17045,6 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
-	typ := &b.Func.Config.Types
 	// match: (OR x (MOVDconst [c]))
 	// result: (ORconst [c] x)
 	for {
@@ -16354,287 +17174,6 @@
 		}
 		break
 	}
-	// match: (OR (SLL x (ANDconst <t> [63] y)) (CSEL0 <typ.UInt64> [cc] (SRL <typ.UInt64> x (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y))) (CMPconst [64] (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y)))))
-	// cond: cc == OpARM64LessThanU
-	// result: (ROR x (NEG <t> y))
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpARM64SLL {
-				continue
-			}
-			_ = v_0.Args[1]
-			x := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpARM64ANDconst {
-				continue
-			}
-			t := v_0_1.Type
-			if auxIntToInt64(v_0_1.AuxInt) != 63 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpARM64CSEL0 || v_1.Type != typ.UInt64 {
-				continue
-			}
-			cc := auxIntToOp(v_1.AuxInt)
-			_ = v_1.Args[1]
-			v_1_0 := v_1.Args[0]
-			if v_1_0.Op != OpARM64SRL || v_1_0.Type != typ.UInt64 {
-				continue
-			}
-			_ = v_1_0.Args[1]
-			if x != v_1_0.Args[0] {
-				continue
-			}
-			v_1_0_1 := v_1_0.Args[1]
-			if v_1_0_1.Op != OpARM64SUB || v_1_0_1.Type != t {
-				continue
-			}
-			_ = v_1_0_1.Args[1]
-			v_1_0_1_0 := v_1_0_1.Args[0]
-			if v_1_0_1_0.Op != OpARM64MOVDconst || auxIntToInt64(v_1_0_1_0.AuxInt) != 64 {
-				continue
-			}
-			v_1_0_1_1 := v_1_0_1.Args[1]
-			if v_1_0_1_1.Op != OpARM64ANDconst || v_1_0_1_1.Type != t || auxIntToInt64(v_1_0_1_1.AuxInt) != 63 || y != v_1_0_1_1.Args[0] {
-				continue
-			}
-			v_1_1 := v_1.Args[1]
-			if v_1_1.Op != OpARM64CMPconst || auxIntToInt64(v_1_1.AuxInt) != 64 {
-				continue
-			}
-			v_1_1_0 := v_1_1.Args[0]
-			if v_1_1_0.Op != OpARM64SUB || v_1_1_0.Type != t {
-				continue
-			}
-			_ = v_1_1_0.Args[1]
-			v_1_1_0_0 := v_1_1_0.Args[0]
-			if v_1_1_0_0.Op != OpARM64MOVDconst || auxIntToInt64(v_1_1_0_0.AuxInt) != 64 {
-				continue
-			}
-			v_1_1_0_1 := v_1_1_0.Args[1]
-			if v_1_1_0_1.Op != OpARM64ANDconst || v_1_1_0_1.Type != t || auxIntToInt64(v_1_1_0_1.AuxInt) != 63 || y != v_1_1_0_1.Args[0] || !(cc == OpARM64LessThanU) {
-				continue
-			}
-			v.reset(OpARM64ROR)
-			v0 := b.NewValue0(v.Pos, OpARM64NEG, t)
-			v0.AddArg(y)
-			v.AddArg2(x, v0)
-			return true
-		}
-		break
-	}
-	// match: (OR (SRL <typ.UInt64> x (ANDconst <t> [63] y)) (CSEL0 <typ.UInt64> [cc] (SLL x (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y))) (CMPconst [64] (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y)))))
-	// cond: cc == OpARM64LessThanU
-	// result: (ROR x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpARM64SRL || v_0.Type != typ.UInt64 {
-				continue
-			}
-			_ = v_0.Args[1]
-			x := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpARM64ANDconst {
-				continue
-			}
-			t := v_0_1.Type
-			if auxIntToInt64(v_0_1.AuxInt) != 63 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpARM64CSEL0 || v_1.Type != typ.UInt64 {
-				continue
-			}
-			cc := auxIntToOp(v_1.AuxInt)
-			_ = v_1.Args[1]
-			v_1_0 := v_1.Args[0]
-			if v_1_0.Op != OpARM64SLL {
-				continue
-			}
-			_ = v_1_0.Args[1]
-			if x != v_1_0.Args[0] {
-				continue
-			}
-			v_1_0_1 := v_1_0.Args[1]
-			if v_1_0_1.Op != OpARM64SUB || v_1_0_1.Type != t {
-				continue
-			}
-			_ = v_1_0_1.Args[1]
-			v_1_0_1_0 := v_1_0_1.Args[0]
-			if v_1_0_1_0.Op != OpARM64MOVDconst || auxIntToInt64(v_1_0_1_0.AuxInt) != 64 {
-				continue
-			}
-			v_1_0_1_1 := v_1_0_1.Args[1]
-			if v_1_0_1_1.Op != OpARM64ANDconst || v_1_0_1_1.Type != t || auxIntToInt64(v_1_0_1_1.AuxInt) != 63 || y != v_1_0_1_1.Args[0] {
-				continue
-			}
-			v_1_1 := v_1.Args[1]
-			if v_1_1.Op != OpARM64CMPconst || auxIntToInt64(v_1_1.AuxInt) != 64 {
-				continue
-			}
-			v_1_1_0 := v_1_1.Args[0]
-			if v_1_1_0.Op != OpARM64SUB || v_1_1_0.Type != t {
-				continue
-			}
-			_ = v_1_1_0.Args[1]
-			v_1_1_0_0 := v_1_1_0.Args[0]
-			if v_1_1_0_0.Op != OpARM64MOVDconst || auxIntToInt64(v_1_1_0_0.AuxInt) != 64 {
-				continue
-			}
-			v_1_1_0_1 := v_1_1_0.Args[1]
-			if v_1_1_0_1.Op != OpARM64ANDconst || v_1_1_0_1.Type != t || auxIntToInt64(v_1_1_0_1.AuxInt) != 63 || y != v_1_1_0_1.Args[0] || !(cc == OpARM64LessThanU) {
-				continue
-			}
-			v.reset(OpARM64ROR)
-			v.AddArg2(x, y)
-			return true
-		}
-		break
-	}
-	// match: (OR (SLL x (ANDconst <t> [31] y)) (CSEL0 <typ.UInt32> [cc] (SRL <typ.UInt32> (MOVWUreg x) (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y))) (CMPconst [64] (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y)))))
-	// cond: cc == OpARM64LessThanU
-	// result: (RORW x (NEG <t> y))
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpARM64SLL {
-				continue
-			}
-			_ = v_0.Args[1]
-			x := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpARM64ANDconst {
-				continue
-			}
-			t := v_0_1.Type
-			if auxIntToInt64(v_0_1.AuxInt) != 31 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpARM64CSEL0 || v_1.Type != typ.UInt32 {
-				continue
-			}
-			cc := auxIntToOp(v_1.AuxInt)
-			_ = v_1.Args[1]
-			v_1_0 := v_1.Args[0]
-			if v_1_0.Op != OpARM64SRL || v_1_0.Type != typ.UInt32 {
-				continue
-			}
-			_ = v_1_0.Args[1]
-			v_1_0_0 := v_1_0.Args[0]
-			if v_1_0_0.Op != OpARM64MOVWUreg || x != v_1_0_0.Args[0] {
-				continue
-			}
-			v_1_0_1 := v_1_0.Args[1]
-			if v_1_0_1.Op != OpARM64SUB || v_1_0_1.Type != t {
-				continue
-			}
-			_ = v_1_0_1.Args[1]
-			v_1_0_1_0 := v_1_0_1.Args[0]
-			if v_1_0_1_0.Op != OpARM64MOVDconst || auxIntToInt64(v_1_0_1_0.AuxInt) != 32 {
-				continue
-			}
-			v_1_0_1_1 := v_1_0_1.Args[1]
-			if v_1_0_1_1.Op != OpARM64ANDconst || v_1_0_1_1.Type != t || auxIntToInt64(v_1_0_1_1.AuxInt) != 31 || y != v_1_0_1_1.Args[0] {
-				continue
-			}
-			v_1_1 := v_1.Args[1]
-			if v_1_1.Op != OpARM64CMPconst || auxIntToInt64(v_1_1.AuxInt) != 64 {
-				continue
-			}
-			v_1_1_0 := v_1_1.Args[0]
-			if v_1_1_0.Op != OpARM64SUB || v_1_1_0.Type != t {
-				continue
-			}
-			_ = v_1_1_0.Args[1]
-			v_1_1_0_0 := v_1_1_0.Args[0]
-			if v_1_1_0_0.Op != OpARM64MOVDconst || auxIntToInt64(v_1_1_0_0.AuxInt) != 32 {
-				continue
-			}
-			v_1_1_0_1 := v_1_1_0.Args[1]
-			if v_1_1_0_1.Op != OpARM64ANDconst || v_1_1_0_1.Type != t || auxIntToInt64(v_1_1_0_1.AuxInt) != 31 || y != v_1_1_0_1.Args[0] || !(cc == OpARM64LessThanU) {
-				continue
-			}
-			v.reset(OpARM64RORW)
-			v0 := b.NewValue0(v.Pos, OpARM64NEG, t)
-			v0.AddArg(y)
-			v.AddArg2(x, v0)
-			return true
-		}
-		break
-	}
-	// match: (OR (SRL <typ.UInt32> (MOVWUreg x) (ANDconst <t> [31] y)) (CSEL0 <typ.UInt32> [cc] (SLL x (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y))) (CMPconst [64] (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y)))))
-	// cond: cc == OpARM64LessThanU
-	// result: (RORW x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpARM64SRL || v_0.Type != typ.UInt32 {
-				continue
-			}
-			_ = v_0.Args[1]
-			v_0_0 := v_0.Args[0]
-			if v_0_0.Op != OpARM64MOVWUreg {
-				continue
-			}
-			x := v_0_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpARM64ANDconst {
-				continue
-			}
-			t := v_0_1.Type
-			if auxIntToInt64(v_0_1.AuxInt) != 31 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpARM64CSEL0 || v_1.Type != typ.UInt32 {
-				continue
-			}
-			cc := auxIntToOp(v_1.AuxInt)
-			_ = v_1.Args[1]
-			v_1_0 := v_1.Args[0]
-			if v_1_0.Op != OpARM64SLL {
-				continue
-			}
-			_ = v_1_0.Args[1]
-			if x != v_1_0.Args[0] {
-				continue
-			}
-			v_1_0_1 := v_1_0.Args[1]
-			if v_1_0_1.Op != OpARM64SUB || v_1_0_1.Type != t {
-				continue
-			}
-			_ = v_1_0_1.Args[1]
-			v_1_0_1_0 := v_1_0_1.Args[0]
-			if v_1_0_1_0.Op != OpARM64MOVDconst || auxIntToInt64(v_1_0_1_0.AuxInt) != 32 {
-				continue
-			}
-			v_1_0_1_1 := v_1_0_1.Args[1]
-			if v_1_0_1_1.Op != OpARM64ANDconst || v_1_0_1_1.Type != t || auxIntToInt64(v_1_0_1_1.AuxInt) != 31 || y != v_1_0_1_1.Args[0] {
-				continue
-			}
-			v_1_1 := v_1.Args[1]
-			if v_1_1.Op != OpARM64CMPconst || auxIntToInt64(v_1_1.AuxInt) != 64 {
-				continue
-			}
-			v_1_1_0 := v_1_1.Args[0]
-			if v_1_1_0.Op != OpARM64SUB || v_1_1_0.Type != t {
-				continue
-			}
-			_ = v_1_1_0.Args[1]
-			v_1_1_0_0 := v_1_1_0.Args[0]
-			if v_1_1_0_0.Op != OpARM64MOVDconst || auxIntToInt64(v_1_1_0_0.AuxInt) != 32 {
-				continue
-			}
-			v_1_1_0_1 := v_1_1_0.Args[1]
-			if v_1_1_0_1.Op != OpARM64ANDconst || v_1_1_0_1.Type != t || auxIntToInt64(v_1_1_0_1.AuxInt) != 31 || y != v_1_1_0_1.Args[0] || !(cc == OpARM64LessThanU) {
-				continue
-			}
-			v.reset(OpARM64RORW)
-			v.AddArg2(x, y)
-			return true
-		}
-		break
-	}
 	// match: (OR (UBFIZ [bfc] x) (ANDconst [ac] y))
 	// cond: ac == ^((1<<uint(bfc.getARM64BFwidth())-1) << uint(bfc.getARM64BFlsb()))
 	// result: (BFI [bfc] y x)
@@ -18599,41 +19138,6 @@
 		v.copyOf(y)
 		return true
 	}
-	// match: ( ORshiftLL [c] (SRLconst x [64-c]) x)
-	// result: (RORconst [64-c] x)
-	for {
-		c := auxIntToInt64(v.AuxInt)
-		if v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != 64-c {
-			break
-		}
-		x := v_0.Args[0]
-		if x != v_1 {
-			break
-		}
-		v.reset(OpARM64RORconst)
-		v.AuxInt = int64ToAuxInt(64 - c)
-		v.AddArg(x)
-		return true
-	}
-	// match: ( ORshiftLL <t> [c] (UBFX [bfc] x) x)
-	// cond: c < 32 && t.Size() == 4 && bfc == armBFAuxInt(32-c, c)
-	// result: (RORWconst [32-c] x)
-	for {
-		t := v.Type
-		c := auxIntToInt64(v.AuxInt)
-		if v_0.Op != OpARM64UBFX {
-			break
-		}
-		bfc := auxIntToArm64BitField(v_0.AuxInt)
-		x := v_0.Args[0]
-		if x != v_1 || !(c < 32 && t.Size() == 4 && bfc == armBFAuxInt(32-c, c)) {
-			break
-		}
-		v.reset(OpARM64RORWconst)
-		v.AuxInt = int64ToAuxInt(32 - c)
-		v.AddArg(x)
-		return true
-	}
 	// match: (ORshiftLL <typ.UInt16> [8] (UBFX <typ.UInt16> [armBFAuxInt(8, 8)] x) x)
 	// result: (REV16W x)
 	for {
@@ -20329,40 +20833,6 @@
 		v.copyOf(y)
 		return true
 	}
-	// match: ( ORshiftRL [c] (SLLconst x [64-c]) x)
-	// result: (RORconst [ c] x)
-	for {
-		c := auxIntToInt64(v.AuxInt)
-		if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != 64-c {
-			break
-		}
-		x := v_0.Args[0]
-		if x != v_1 {
-			break
-		}
-		v.reset(OpARM64RORconst)
-		v.AuxInt = int64ToAuxInt(c)
-		v.AddArg(x)
-		return true
-	}
-	// match: ( ORshiftRL <t> [c] (SLLconst x [32-c]) (MOVWUreg x))
-	// cond: c < 32 && t.Size() == 4
-	// result: (RORWconst [c] x)
-	for {
-		t := v.Type
-		c := auxIntToInt64(v.AuxInt)
-		if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != 32-c {
-			break
-		}
-		x := v_0.Args[0]
-		if v_1.Op != OpARM64MOVWUreg || x != v_1.Args[0] || !(c < 32 && t.Size() == 4) {
-			break
-		}
-		v.reset(OpARM64RORWconst)
-		v.AuxInt = int64ToAuxInt(c)
-		v.AddArg(x)
-		return true
-	}
 	// match: (ORshiftRL [rc] (ANDconst [ac] x) (SLLconst [lc] y))
 	// cond: lc > rc && ac == ^((1<<uint(64-lc)-1) << uint64(lc-rc))
 	// result: (BFI [armBFAuxInt(lc-rc, 64-lc)] x y)
@@ -20527,42 +20997,6 @@
 	}
 	return false
 }
-func rewriteValueARM64_OpARM64RORWconst(v *Value) bool {
-	v_0 := v.Args[0]
-	// match: (RORWconst [c] (RORWconst [d] x))
-	// result: (RORWconst [(c+d)&31] x)
-	for {
-		c := auxIntToInt64(v.AuxInt)
-		if v_0.Op != OpARM64RORWconst {
-			break
-		}
-		d := auxIntToInt64(v_0.AuxInt)
-		x := v_0.Args[0]
-		v.reset(OpARM64RORWconst)
-		v.AuxInt = int64ToAuxInt((c + d) & 31)
-		v.AddArg(x)
-		return true
-	}
-	return false
-}
-func rewriteValueARM64_OpARM64RORconst(v *Value) bool {
-	v_0 := v.Args[0]
-	// match: (RORconst [c] (RORconst [d] x))
-	// result: (RORconst [(c+d)&63] x)
-	for {
-		c := auxIntToInt64(v.AuxInt)
-		if v_0.Op != OpARM64RORconst {
-			break
-		}
-		d := auxIntToInt64(v_0.AuxInt)
-		x := v_0.Args[0]
-		v.reset(OpARM64RORconst)
-		v.AuxInt = int64ToAuxInt((c + d) & 63)
-		v.AddArg(x)
-		return true
-	}
-	return false
-}
 func rewriteValueARM64_OpARM64SBCSflags(v *Value) bool {
 	v_2 := v.Args[2]
 	v_1 := v.Args[1]
@@ -20632,6 +21066,18 @@
 		v.AddArg(x)
 		return true
 	}
+	// match: (SLL x (ANDconst [63] y))
+	// result: (SLL x y)
+	for {
+		x := v_0
+		if v_1.Op != OpARM64ANDconst || auxIntToInt64(v_1.AuxInt) != 63 {
+			break
+		}
+		y := v_1.Args[0]
+		v.reset(OpARM64SLL)
+		v.AddArg2(x, y)
+		return true
+	}
 	return false
 }
 func rewriteValueARM64_OpARM64SLLconst(v *Value) bool {
@@ -20797,6 +21243,18 @@
 		v.AddArg(x)
 		return true
 	}
+	// match: (SRA x (ANDconst [63] y))
+	// result: (SRA x y)
+	for {
+		x := v_0
+		if v_1.Op != OpARM64ANDconst || auxIntToInt64(v_1.AuxInt) != 63 {
+			break
+		}
+		y := v_1.Args[0]
+		v.reset(OpARM64SRA)
+		v.AddArg2(x, y)
+		return true
+	}
 	return false
 }
 func rewriteValueARM64_OpARM64SRAconst(v *Value) bool {
@@ -20954,6 +21412,18 @@
 		v.AddArg(x)
 		return true
 	}
+	// match: (SRL x (ANDconst [63] y))
+	// result: (SRL x y)
+	for {
+		x := v_0
+		if v_1.Op != OpARM64ANDconst || auxIntToInt64(v_1.AuxInt) != 63 {
+			break
+		}
+		y := v_1.Args[0]
+		v.reset(OpARM64SRL)
+		v.AddArg2(x, y)
+		return true
+	}
 	return false
 }
 func rewriteValueARM64_OpARM64SRLconst(v *Value) bool {
@@ -21216,10 +21686,8 @@
 	v_2 := v.Args[2]
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	b := v.Block
-	config := b.Func.Config
 	// match: (STP [off1] {sym} (ADDconst [off2] ptr) val1 val2 mem)
-	// cond: is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: is32Bit(int64(off1)+off2)
 	// result: (STP [off1+int32(off2)] {sym} ptr val1 val2 mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -21232,7 +21700,7 @@
 		val1 := v_1
 		val2 := v_2
 		mem := v_3
-		if !(is32Bit(int64(off1)+off2) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(is32Bit(int64(off1) + off2)) {
 			break
 		}
 		v.reset(OpARM64STP)
@@ -21242,7 +21710,7 @@
 		return true
 	}
 	// match: (STP [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val1 val2 mem)
-	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)
+	// cond: canMergeSym(sym1,sym2) && is32Bit(int64(off1)+int64(off2))
 	// result: (STP [off1+off2] {mergeSym(sym1,sym2)} ptr val1 val2 mem)
 	for {
 		off1 := auxIntToInt32(v.AuxInt)
@@ -21256,7 +21724,7 @@
 		val1 := v_1
 		val2 := v_2
 		mem := v_3
-		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2)) && (ptr.Op != OpSB || !config.ctxt.Flag_shared)) {
+		if !(canMergeSym(sym1, sym2) && is32Bit(int64(off1)+int64(off2))) {
 			break
 		}
 		v.reset(OpARM64STP)
@@ -22305,8 +22773,6 @@
 func rewriteValueARM64_OpARM64XOR(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	b := v.Block
-	typ := &b.Func.Config.Types
 	// match: (XOR x (MOVDconst [c]))
 	// result: (XORconst [c] x)
 	for {
@@ -22437,287 +22903,6 @@
 		}
 		break
 	}
-	// match: (XOR (SLL x (ANDconst <t> [63] y)) (CSEL0 <typ.UInt64> [cc] (SRL <typ.UInt64> x (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y))) (CMPconst [64] (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y)))))
-	// cond: cc == OpARM64LessThanU
-	// result: (ROR x (NEG <t> y))
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpARM64SLL {
-				continue
-			}
-			_ = v_0.Args[1]
-			x := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpARM64ANDconst {
-				continue
-			}
-			t := v_0_1.Type
-			if auxIntToInt64(v_0_1.AuxInt) != 63 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpARM64CSEL0 || v_1.Type != typ.UInt64 {
-				continue
-			}
-			cc := auxIntToOp(v_1.AuxInt)
-			_ = v_1.Args[1]
-			v_1_0 := v_1.Args[0]
-			if v_1_0.Op != OpARM64SRL || v_1_0.Type != typ.UInt64 {
-				continue
-			}
-			_ = v_1_0.Args[1]
-			if x != v_1_0.Args[0] {
-				continue
-			}
-			v_1_0_1 := v_1_0.Args[1]
-			if v_1_0_1.Op != OpARM64SUB || v_1_0_1.Type != t {
-				continue
-			}
-			_ = v_1_0_1.Args[1]
-			v_1_0_1_0 := v_1_0_1.Args[0]
-			if v_1_0_1_0.Op != OpARM64MOVDconst || auxIntToInt64(v_1_0_1_0.AuxInt) != 64 {
-				continue
-			}
-			v_1_0_1_1 := v_1_0_1.Args[1]
-			if v_1_0_1_1.Op != OpARM64ANDconst || v_1_0_1_1.Type != t || auxIntToInt64(v_1_0_1_1.AuxInt) != 63 || y != v_1_0_1_1.Args[0] {
-				continue
-			}
-			v_1_1 := v_1.Args[1]
-			if v_1_1.Op != OpARM64CMPconst || auxIntToInt64(v_1_1.AuxInt) != 64 {
-				continue
-			}
-			v_1_1_0 := v_1_1.Args[0]
-			if v_1_1_0.Op != OpARM64SUB || v_1_1_0.Type != t {
-				continue
-			}
-			_ = v_1_1_0.Args[1]
-			v_1_1_0_0 := v_1_1_0.Args[0]
-			if v_1_1_0_0.Op != OpARM64MOVDconst || auxIntToInt64(v_1_1_0_0.AuxInt) != 64 {
-				continue
-			}
-			v_1_1_0_1 := v_1_1_0.Args[1]
-			if v_1_1_0_1.Op != OpARM64ANDconst || v_1_1_0_1.Type != t || auxIntToInt64(v_1_1_0_1.AuxInt) != 63 || y != v_1_1_0_1.Args[0] || !(cc == OpARM64LessThanU) {
-				continue
-			}
-			v.reset(OpARM64ROR)
-			v0 := b.NewValue0(v.Pos, OpARM64NEG, t)
-			v0.AddArg(y)
-			v.AddArg2(x, v0)
-			return true
-		}
-		break
-	}
-	// match: (XOR (SRL <typ.UInt64> x (ANDconst <t> [63] y)) (CSEL0 <typ.UInt64> [cc] (SLL x (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y))) (CMPconst [64] (SUB <t> (MOVDconst [64]) (ANDconst <t> [63] y)))))
-	// cond: cc == OpARM64LessThanU
-	// result: (ROR x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpARM64SRL || v_0.Type != typ.UInt64 {
-				continue
-			}
-			_ = v_0.Args[1]
-			x := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpARM64ANDconst {
-				continue
-			}
-			t := v_0_1.Type
-			if auxIntToInt64(v_0_1.AuxInt) != 63 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpARM64CSEL0 || v_1.Type != typ.UInt64 {
-				continue
-			}
-			cc := auxIntToOp(v_1.AuxInt)
-			_ = v_1.Args[1]
-			v_1_0 := v_1.Args[0]
-			if v_1_0.Op != OpARM64SLL {
-				continue
-			}
-			_ = v_1_0.Args[1]
-			if x != v_1_0.Args[0] {
-				continue
-			}
-			v_1_0_1 := v_1_0.Args[1]
-			if v_1_0_1.Op != OpARM64SUB || v_1_0_1.Type != t {
-				continue
-			}
-			_ = v_1_0_1.Args[1]
-			v_1_0_1_0 := v_1_0_1.Args[0]
-			if v_1_0_1_0.Op != OpARM64MOVDconst || auxIntToInt64(v_1_0_1_0.AuxInt) != 64 {
-				continue
-			}
-			v_1_0_1_1 := v_1_0_1.Args[1]
-			if v_1_0_1_1.Op != OpARM64ANDconst || v_1_0_1_1.Type != t || auxIntToInt64(v_1_0_1_1.AuxInt) != 63 || y != v_1_0_1_1.Args[0] {
-				continue
-			}
-			v_1_1 := v_1.Args[1]
-			if v_1_1.Op != OpARM64CMPconst || auxIntToInt64(v_1_1.AuxInt) != 64 {
-				continue
-			}
-			v_1_1_0 := v_1_1.Args[0]
-			if v_1_1_0.Op != OpARM64SUB || v_1_1_0.Type != t {
-				continue
-			}
-			_ = v_1_1_0.Args[1]
-			v_1_1_0_0 := v_1_1_0.Args[0]
-			if v_1_1_0_0.Op != OpARM64MOVDconst || auxIntToInt64(v_1_1_0_0.AuxInt) != 64 {
-				continue
-			}
-			v_1_1_0_1 := v_1_1_0.Args[1]
-			if v_1_1_0_1.Op != OpARM64ANDconst || v_1_1_0_1.Type != t || auxIntToInt64(v_1_1_0_1.AuxInt) != 63 || y != v_1_1_0_1.Args[0] || !(cc == OpARM64LessThanU) {
-				continue
-			}
-			v.reset(OpARM64ROR)
-			v.AddArg2(x, y)
-			return true
-		}
-		break
-	}
-	// match: (XOR (SLL x (ANDconst <t> [31] y)) (CSEL0 <typ.UInt32> [cc] (SRL <typ.UInt32> (MOVWUreg x) (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y))) (CMPconst [64] (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y)))))
-	// cond: cc == OpARM64LessThanU
-	// result: (RORW x (NEG <t> y))
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpARM64SLL {
-				continue
-			}
-			_ = v_0.Args[1]
-			x := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpARM64ANDconst {
-				continue
-			}
-			t := v_0_1.Type
-			if auxIntToInt64(v_0_1.AuxInt) != 31 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpARM64CSEL0 || v_1.Type != typ.UInt32 {
-				continue
-			}
-			cc := auxIntToOp(v_1.AuxInt)
-			_ = v_1.Args[1]
-			v_1_0 := v_1.Args[0]
-			if v_1_0.Op != OpARM64SRL || v_1_0.Type != typ.UInt32 {
-				continue
-			}
-			_ = v_1_0.Args[1]
-			v_1_0_0 := v_1_0.Args[0]
-			if v_1_0_0.Op != OpARM64MOVWUreg || x != v_1_0_0.Args[0] {
-				continue
-			}
-			v_1_0_1 := v_1_0.Args[1]
-			if v_1_0_1.Op != OpARM64SUB || v_1_0_1.Type != t {
-				continue
-			}
-			_ = v_1_0_1.Args[1]
-			v_1_0_1_0 := v_1_0_1.Args[0]
-			if v_1_0_1_0.Op != OpARM64MOVDconst || auxIntToInt64(v_1_0_1_0.AuxInt) != 32 {
-				continue
-			}
-			v_1_0_1_1 := v_1_0_1.Args[1]
-			if v_1_0_1_1.Op != OpARM64ANDconst || v_1_0_1_1.Type != t || auxIntToInt64(v_1_0_1_1.AuxInt) != 31 || y != v_1_0_1_1.Args[0] {
-				continue
-			}
-			v_1_1 := v_1.Args[1]
-			if v_1_1.Op != OpARM64CMPconst || auxIntToInt64(v_1_1.AuxInt) != 64 {
-				continue
-			}
-			v_1_1_0 := v_1_1.Args[0]
-			if v_1_1_0.Op != OpARM64SUB || v_1_1_0.Type != t {
-				continue
-			}
-			_ = v_1_1_0.Args[1]
-			v_1_1_0_0 := v_1_1_0.Args[0]
-			if v_1_1_0_0.Op != OpARM64MOVDconst || auxIntToInt64(v_1_1_0_0.AuxInt) != 32 {
-				continue
-			}
-			v_1_1_0_1 := v_1_1_0.Args[1]
-			if v_1_1_0_1.Op != OpARM64ANDconst || v_1_1_0_1.Type != t || auxIntToInt64(v_1_1_0_1.AuxInt) != 31 || y != v_1_1_0_1.Args[0] || !(cc == OpARM64LessThanU) {
-				continue
-			}
-			v.reset(OpARM64RORW)
-			v0 := b.NewValue0(v.Pos, OpARM64NEG, t)
-			v0.AddArg(y)
-			v.AddArg2(x, v0)
-			return true
-		}
-		break
-	}
-	// match: (XOR (SRL <typ.UInt32> (MOVWUreg x) (ANDconst <t> [31] y)) (CSEL0 <typ.UInt32> [cc] (SLL x (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y))) (CMPconst [64] (SUB <t> (MOVDconst [32]) (ANDconst <t> [31] y)))))
-	// cond: cc == OpARM64LessThanU
-	// result: (RORW x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpARM64SRL || v_0.Type != typ.UInt32 {
-				continue
-			}
-			_ = v_0.Args[1]
-			v_0_0 := v_0.Args[0]
-			if v_0_0.Op != OpARM64MOVWUreg {
-				continue
-			}
-			x := v_0_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpARM64ANDconst {
-				continue
-			}
-			t := v_0_1.Type
-			if auxIntToInt64(v_0_1.AuxInt) != 31 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpARM64CSEL0 || v_1.Type != typ.UInt32 {
-				continue
-			}
-			cc := auxIntToOp(v_1.AuxInt)
-			_ = v_1.Args[1]
-			v_1_0 := v_1.Args[0]
-			if v_1_0.Op != OpARM64SLL {
-				continue
-			}
-			_ = v_1_0.Args[1]
-			if x != v_1_0.Args[0] {
-				continue
-			}
-			v_1_0_1 := v_1_0.Args[1]
-			if v_1_0_1.Op != OpARM64SUB || v_1_0_1.Type != t {
-				continue
-			}
-			_ = v_1_0_1.Args[1]
-			v_1_0_1_0 := v_1_0_1.Args[0]
-			if v_1_0_1_0.Op != OpARM64MOVDconst || auxIntToInt64(v_1_0_1_0.AuxInt) != 32 {
-				continue
-			}
-			v_1_0_1_1 := v_1_0_1.Args[1]
-			if v_1_0_1_1.Op != OpARM64ANDconst || v_1_0_1_1.Type != t || auxIntToInt64(v_1_0_1_1.AuxInt) != 31 || y != v_1_0_1_1.Args[0] {
-				continue
-			}
-			v_1_1 := v_1.Args[1]
-			if v_1_1.Op != OpARM64CMPconst || auxIntToInt64(v_1_1.AuxInt) != 64 {
-				continue
-			}
-			v_1_1_0 := v_1_1.Args[0]
-			if v_1_1_0.Op != OpARM64SUB || v_1_1_0.Type != t {
-				continue
-			}
-			_ = v_1_1_0.Args[1]
-			v_1_1_0_0 := v_1_1_0.Args[0]
-			if v_1_1_0_0.Op != OpARM64MOVDconst || auxIntToInt64(v_1_1_0_0.AuxInt) != 32 {
-				continue
-			}
-			v_1_1_0_1 := v_1_1_0.Args[1]
-			if v_1_1_0_1.Op != OpARM64ANDconst || v_1_1_0_1.Type != t || auxIntToInt64(v_1_1_0_1.AuxInt) != 31 || y != v_1_1_0_1.Args[0] || !(cc == OpARM64LessThanU) {
-				continue
-			}
-			v.reset(OpARM64RORW)
-			v.AddArg2(x, y)
-			return true
-		}
-		break
-	}
 	return false
 }
 func rewriteValueARM64_OpARM64XORconst(v *Value) bool {
@@ -22822,41 +23007,6 @@
 		v.AuxInt = int64ToAuxInt(0)
 		return true
 	}
-	// match: (XORshiftLL [c] (SRLconst x [64-c]) x)
-	// result: (RORconst [64-c] x)
-	for {
-		c := auxIntToInt64(v.AuxInt)
-		if v_0.Op != OpARM64SRLconst || auxIntToInt64(v_0.AuxInt) != 64-c {
-			break
-		}
-		x := v_0.Args[0]
-		if x != v_1 {
-			break
-		}
-		v.reset(OpARM64RORconst)
-		v.AuxInt = int64ToAuxInt(64 - c)
-		v.AddArg(x)
-		return true
-	}
-	// match: (XORshiftLL <t> [c] (UBFX [bfc] x) x)
-	// cond: c < 32 && t.Size() == 4 && bfc == armBFAuxInt(32-c, c)
-	// result: (RORWconst [32-c] x)
-	for {
-		t := v.Type
-		c := auxIntToInt64(v.AuxInt)
-		if v_0.Op != OpARM64UBFX {
-			break
-		}
-		bfc := auxIntToArm64BitField(v_0.AuxInt)
-		x := v_0.Args[0]
-		if x != v_1 || !(c < 32 && t.Size() == 4 && bfc == armBFAuxInt(32-c, c)) {
-			break
-		}
-		v.reset(OpARM64RORWconst)
-		v.AuxInt = int64ToAuxInt(32 - c)
-		v.AddArg(x)
-		return true
-	}
 	// match: (XORshiftLL <typ.UInt16> [8] (UBFX <typ.UInt16> [armBFAuxInt(8, 8)] x) x)
 	// result: (REV16W x)
 	for {
@@ -23084,40 +23234,6 @@
 		v.AuxInt = int64ToAuxInt(0)
 		return true
 	}
-	// match: (XORshiftRL [c] (SLLconst x [64-c]) x)
-	// result: (RORconst [ c] x)
-	for {
-		c := auxIntToInt64(v.AuxInt)
-		if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != 64-c {
-			break
-		}
-		x := v_0.Args[0]
-		if x != v_1 {
-			break
-		}
-		v.reset(OpARM64RORconst)
-		v.AuxInt = int64ToAuxInt(c)
-		v.AddArg(x)
-		return true
-	}
-	// match: (XORshiftRL <t> [c] (SLLconst x [32-c]) (MOVWUreg x))
-	// cond: c < 32 && t.Size() == 4
-	// result: (RORWconst [c] x)
-	for {
-		t := v.Type
-		c := auxIntToInt64(v.AuxInt)
-		if v_0.Op != OpARM64SLLconst || auxIntToInt64(v_0.AuxInt) != 32-c {
-			break
-		}
-		x := v_0.Args[0]
-		if v_1.Op != OpARM64MOVWUreg || x != v_1.Args[0] || !(c < 32 && t.Size() == 4) {
-			break
-		}
-		v.reset(OpARM64RORWconst)
-		v.AuxInt = int64ToAuxInt(c)
-		v.AddArg(x)
-		return true
-	}
 	return false
 }
 func rewriteValueARM64_OpARM64XORshiftRO(v *Value) bool {
@@ -23445,7 +23561,7 @@
 	}
 	// match: (CondSelect x y boolval)
 	// cond: flagArg(boolval) == nil
-	// result: (CSEL [OpARM64NotEqual] x y (CMPWconst [0] boolval))
+	// result: (CSEL [OpARM64NotEqual] x y (TSTWconst [1] boolval))
 	for {
 		x := v_0
 		y := v_1
@@ -23455,8 +23571,8 @@
 		}
 		v.reset(OpARM64CSEL)
 		v.AuxInt = opToAuxInt(OpARM64NotEqual)
-		v0 := b.NewValue0(v.Pos, OpARM64CMPWconst, types.TypeFlags)
-		v0.AuxInt = int32ToAuxInt(0)
+		v0 := b.NewValue0(v.Pos, OpARM64TSTWconst, types.TypeFlags)
+		v0.AuxInt = int32ToAuxInt(1)
 		v0.AddArg(boolval)
 		v.AddArg3(x, y, v0)
 		return true
@@ -24693,25 +24809,45 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Lsh16x16 <t> x y)
-	// result: (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+	// cond: shiftIsBounded(v)
+	// result: (SLL <t> x y)
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SLL)
+		v.Type = t
+		v.AddArg2(x, y)
+		return true
+	}
+	// match: (Lsh16x16 <t> x y)
+	// cond: !shiftIsBounded(v)
+	// result: (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64CSEL)
 		v.AuxInt = opToAuxInt(OpARM64LessThanU)
 		v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
-		v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
-		v1.AddArg(y)
-		v0.AddArg2(x, v1)
-		v2 := b.NewValue0(v.Pos, OpConst64, t)
-		v2.AuxInt = int64ToAuxInt(0)
-		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
-		v3.AuxInt = int64ToAuxInt(64)
-		v3.AddArg(v1)
-		v.AddArg3(v0, v2, v3)
+		v0.AddArg2(x, y)
+		v1 := b.NewValue0(v.Pos, OpConst64, t)
+		v1.AuxInt = int64ToAuxInt(0)
+		v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
+		v2.AuxInt = int64ToAuxInt(64)
+		v3 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
+		v3.AddArg(y)
+		v2.AddArg(v3)
+		v.AddArg3(v0, v1, v2)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpLsh16x32(v *Value) bool {
 	v_1 := v.Args[1]
@@ -24719,36 +24855,75 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Lsh16x32 <t> x y)
-	// result: (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+	// cond: shiftIsBounded(v)
+	// result: (SLL <t> x y)
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SLL)
+		v.Type = t
+		v.AddArg2(x, y)
+		return true
+	}
+	// match: (Lsh16x32 <t> x y)
+	// cond: !shiftIsBounded(v)
+	// result: (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64CSEL)
 		v.AuxInt = opToAuxInt(OpARM64LessThanU)
 		v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
-		v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
-		v1.AddArg(y)
-		v0.AddArg2(x, v1)
-		v2 := b.NewValue0(v.Pos, OpConst64, t)
-		v2.AuxInt = int64ToAuxInt(0)
-		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
-		v3.AuxInt = int64ToAuxInt(64)
-		v3.AddArg(v1)
-		v.AddArg3(v0, v2, v3)
+		v0.AddArg2(x, y)
+		v1 := b.NewValue0(v.Pos, OpConst64, t)
+		v1.AuxInt = int64ToAuxInt(0)
+		v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
+		v2.AuxInt = int64ToAuxInt(64)
+		v3 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
+		v3.AddArg(y)
+		v2.AddArg(v3)
+		v.AddArg3(v0, v1, v2)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpLsh16x64(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
 	// match: (Lsh16x64 <t> x y)
+	// cond: shiftIsBounded(v)
+	// result: (SLL <t> x y)
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SLL)
+		v.Type = t
+		v.AddArg2(x, y)
+		return true
+	}
+	// match: (Lsh16x64 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64CSEL)
 		v.AuxInt = opToAuxInt(OpARM64LessThanU)
 		v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
@@ -24761,6 +24936,7 @@
 		v.AddArg3(v0, v1, v2)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpLsh16x8(v *Value) bool {
 	v_1 := v.Args[1]
@@ -24768,25 +24944,45 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Lsh16x8 <t> x y)
-	// result: (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
+	// cond: shiftIsBounded(v)
+	// result: (SLL <t> x y)
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SLL)
+		v.Type = t
+		v.AddArg2(x, y)
+		return true
+	}
+	// match: (Lsh16x8 <t> x y)
+	// cond: !shiftIsBounded(v)
+	// result: (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64CSEL)
 		v.AuxInt = opToAuxInt(OpARM64LessThanU)
 		v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
-		v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
-		v1.AddArg(y)
-		v0.AddArg2(x, v1)
-		v2 := b.NewValue0(v.Pos, OpConst64, t)
-		v2.AuxInt = int64ToAuxInt(0)
-		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
-		v3.AuxInt = int64ToAuxInt(64)
-		v3.AddArg(v1)
-		v.AddArg3(v0, v2, v3)
+		v0.AddArg2(x, y)
+		v1 := b.NewValue0(v.Pos, OpConst64, t)
+		v1.AuxInt = int64ToAuxInt(0)
+		v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
+		v2.AuxInt = int64ToAuxInt(64)
+		v3 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
+		v3.AddArg(y)
+		v2.AddArg(v3)
+		v.AddArg3(v0, v1, v2)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpLsh32x16(v *Value) bool {
 	v_1 := v.Args[1]
@@ -24794,25 +24990,45 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Lsh32x16 <t> x y)
-	// result: (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+	// cond: shiftIsBounded(v)
+	// result: (SLL <t> x y)
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SLL)
+		v.Type = t
+		v.AddArg2(x, y)
+		return true
+	}
+	// match: (Lsh32x16 <t> x y)
+	// cond: !shiftIsBounded(v)
+	// result: (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64CSEL)
 		v.AuxInt = opToAuxInt(OpARM64LessThanU)
 		v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
-		v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
-		v1.AddArg(y)
-		v0.AddArg2(x, v1)
-		v2 := b.NewValue0(v.Pos, OpConst64, t)
-		v2.AuxInt = int64ToAuxInt(0)
-		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
-		v3.AuxInt = int64ToAuxInt(64)
-		v3.AddArg(v1)
-		v.AddArg3(v0, v2, v3)
+		v0.AddArg2(x, y)
+		v1 := b.NewValue0(v.Pos, OpConst64, t)
+		v1.AuxInt = int64ToAuxInt(0)
+		v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
+		v2.AuxInt = int64ToAuxInt(64)
+		v3 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
+		v3.AddArg(y)
+		v2.AddArg(v3)
+		v.AddArg3(v0, v1, v2)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpLsh32x32(v *Value) bool {
 	v_1 := v.Args[1]
@@ -24820,36 +25036,75 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Lsh32x32 <t> x y)
-	// result: (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+	// cond: shiftIsBounded(v)
+	// result: (SLL <t> x y)
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SLL)
+		v.Type = t
+		v.AddArg2(x, y)
+		return true
+	}
+	// match: (Lsh32x32 <t> x y)
+	// cond: !shiftIsBounded(v)
+	// result: (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64CSEL)
 		v.AuxInt = opToAuxInt(OpARM64LessThanU)
 		v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
-		v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
-		v1.AddArg(y)
-		v0.AddArg2(x, v1)
-		v2 := b.NewValue0(v.Pos, OpConst64, t)
-		v2.AuxInt = int64ToAuxInt(0)
-		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
-		v3.AuxInt = int64ToAuxInt(64)
-		v3.AddArg(v1)
-		v.AddArg3(v0, v2, v3)
+		v0.AddArg2(x, y)
+		v1 := b.NewValue0(v.Pos, OpConst64, t)
+		v1.AuxInt = int64ToAuxInt(0)
+		v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
+		v2.AuxInt = int64ToAuxInt(64)
+		v3 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
+		v3.AddArg(y)
+		v2.AddArg(v3)
+		v.AddArg3(v0, v1, v2)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpLsh32x64(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
 	// match: (Lsh32x64 <t> x y)
+	// cond: shiftIsBounded(v)
+	// result: (SLL <t> x y)
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SLL)
+		v.Type = t
+		v.AddArg2(x, y)
+		return true
+	}
+	// match: (Lsh32x64 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64CSEL)
 		v.AuxInt = opToAuxInt(OpARM64LessThanU)
 		v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
@@ -24862,6 +25117,7 @@
 		v.AddArg3(v0, v1, v2)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpLsh32x8(v *Value) bool {
 	v_1 := v.Args[1]
@@ -24869,25 +25125,45 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Lsh32x8 <t> x y)
-	// result: (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
+	// cond: shiftIsBounded(v)
+	// result: (SLL <t> x y)
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SLL)
+		v.Type = t
+		v.AddArg2(x, y)
+		return true
+	}
+	// match: (Lsh32x8 <t> x y)
+	// cond: !shiftIsBounded(v)
+	// result: (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64CSEL)
 		v.AuxInt = opToAuxInt(OpARM64LessThanU)
 		v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
-		v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
-		v1.AddArg(y)
-		v0.AddArg2(x, v1)
-		v2 := b.NewValue0(v.Pos, OpConst64, t)
-		v2.AuxInt = int64ToAuxInt(0)
-		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
-		v3.AuxInt = int64ToAuxInt(64)
-		v3.AddArg(v1)
-		v.AddArg3(v0, v2, v3)
+		v0.AddArg2(x, y)
+		v1 := b.NewValue0(v.Pos, OpConst64, t)
+		v1.AuxInt = int64ToAuxInt(0)
+		v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
+		v2.AuxInt = int64ToAuxInt(64)
+		v3 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
+		v3.AddArg(y)
+		v2.AddArg(v3)
+		v.AddArg3(v0, v1, v2)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpLsh64x16(v *Value) bool {
 	v_1 := v.Args[1]
@@ -24895,25 +25171,45 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Lsh64x16 <t> x y)
-	// result: (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+	// cond: shiftIsBounded(v)
+	// result: (SLL <t> x y)
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SLL)
+		v.Type = t
+		v.AddArg2(x, y)
+		return true
+	}
+	// match: (Lsh64x16 <t> x y)
+	// cond: !shiftIsBounded(v)
+	// result: (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64CSEL)
 		v.AuxInt = opToAuxInt(OpARM64LessThanU)
 		v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
-		v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
-		v1.AddArg(y)
-		v0.AddArg2(x, v1)
-		v2 := b.NewValue0(v.Pos, OpConst64, t)
-		v2.AuxInt = int64ToAuxInt(0)
-		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
-		v3.AuxInt = int64ToAuxInt(64)
-		v3.AddArg(v1)
-		v.AddArg3(v0, v2, v3)
+		v0.AddArg2(x, y)
+		v1 := b.NewValue0(v.Pos, OpConst64, t)
+		v1.AuxInt = int64ToAuxInt(0)
+		v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
+		v2.AuxInt = int64ToAuxInt(64)
+		v3 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
+		v3.AddArg(y)
+		v2.AddArg(v3)
+		v.AddArg3(v0, v1, v2)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpLsh64x32(v *Value) bool {
 	v_1 := v.Args[1]
@@ -24921,36 +25217,75 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Lsh64x32 <t> x y)
-	// result: (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+	// cond: shiftIsBounded(v)
+	// result: (SLL <t> x y)
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SLL)
+		v.Type = t
+		v.AddArg2(x, y)
+		return true
+	}
+	// match: (Lsh64x32 <t> x y)
+	// cond: !shiftIsBounded(v)
+	// result: (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64CSEL)
 		v.AuxInt = opToAuxInt(OpARM64LessThanU)
 		v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
-		v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
-		v1.AddArg(y)
-		v0.AddArg2(x, v1)
-		v2 := b.NewValue0(v.Pos, OpConst64, t)
-		v2.AuxInt = int64ToAuxInt(0)
-		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
-		v3.AuxInt = int64ToAuxInt(64)
-		v3.AddArg(v1)
-		v.AddArg3(v0, v2, v3)
+		v0.AddArg2(x, y)
+		v1 := b.NewValue0(v.Pos, OpConst64, t)
+		v1.AuxInt = int64ToAuxInt(0)
+		v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
+		v2.AuxInt = int64ToAuxInt(64)
+		v3 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
+		v3.AddArg(y)
+		v2.AddArg(v3)
+		v.AddArg3(v0, v1, v2)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpLsh64x64(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
 	// match: (Lsh64x64 <t> x y)
+	// cond: shiftIsBounded(v)
+	// result: (SLL <t> x y)
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SLL)
+		v.Type = t
+		v.AddArg2(x, y)
+		return true
+	}
+	// match: (Lsh64x64 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64CSEL)
 		v.AuxInt = opToAuxInt(OpARM64LessThanU)
 		v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
@@ -24963,6 +25298,7 @@
 		v.AddArg3(v0, v1, v2)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpLsh64x8(v *Value) bool {
 	v_1 := v.Args[1]
@@ -24970,25 +25306,45 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Lsh64x8 <t> x y)
-	// result: (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
+	// cond: shiftIsBounded(v)
+	// result: (SLL <t> x y)
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SLL)
+		v.Type = t
+		v.AddArg2(x, y)
+		return true
+	}
+	// match: (Lsh64x8 <t> x y)
+	// cond: !shiftIsBounded(v)
+	// result: (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64CSEL)
 		v.AuxInt = opToAuxInt(OpARM64LessThanU)
 		v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
-		v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
-		v1.AddArg(y)
-		v0.AddArg2(x, v1)
-		v2 := b.NewValue0(v.Pos, OpConst64, t)
-		v2.AuxInt = int64ToAuxInt(0)
-		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
-		v3.AuxInt = int64ToAuxInt(64)
-		v3.AddArg(v1)
-		v.AddArg3(v0, v2, v3)
+		v0.AddArg2(x, y)
+		v1 := b.NewValue0(v.Pos, OpConst64, t)
+		v1.AuxInt = int64ToAuxInt(0)
+		v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
+		v2.AuxInt = int64ToAuxInt(64)
+		v3 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
+		v3.AddArg(y)
+		v2.AddArg(v3)
+		v.AddArg3(v0, v1, v2)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpLsh8x16(v *Value) bool {
 	v_1 := v.Args[1]
@@ -24996,25 +25352,45 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Lsh8x16 <t> x y)
-	// result: (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+	// cond: shiftIsBounded(v)
+	// result: (SLL <t> x y)
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SLL)
+		v.Type = t
+		v.AddArg2(x, y)
+		return true
+	}
+	// match: (Lsh8x16 <t> x y)
+	// cond: !shiftIsBounded(v)
+	// result: (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64CSEL)
 		v.AuxInt = opToAuxInt(OpARM64LessThanU)
 		v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
-		v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
-		v1.AddArg(y)
-		v0.AddArg2(x, v1)
-		v2 := b.NewValue0(v.Pos, OpConst64, t)
-		v2.AuxInt = int64ToAuxInt(0)
-		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
-		v3.AuxInt = int64ToAuxInt(64)
-		v3.AddArg(v1)
-		v.AddArg3(v0, v2, v3)
+		v0.AddArg2(x, y)
+		v1 := b.NewValue0(v.Pos, OpConst64, t)
+		v1.AuxInt = int64ToAuxInt(0)
+		v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
+		v2.AuxInt = int64ToAuxInt(64)
+		v3 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
+		v3.AddArg(y)
+		v2.AddArg(v3)
+		v.AddArg3(v0, v1, v2)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpLsh8x32(v *Value) bool {
 	v_1 := v.Args[1]
@@ -25022,36 +25398,75 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Lsh8x32 <t> x y)
-	// result: (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+	// cond: shiftIsBounded(v)
+	// result: (SLL <t> x y)
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SLL)
+		v.Type = t
+		v.AddArg2(x, y)
+		return true
+	}
+	// match: (Lsh8x32 <t> x y)
+	// cond: !shiftIsBounded(v)
+	// result: (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64CSEL)
 		v.AuxInt = opToAuxInt(OpARM64LessThanU)
 		v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
-		v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
-		v1.AddArg(y)
-		v0.AddArg2(x, v1)
-		v2 := b.NewValue0(v.Pos, OpConst64, t)
-		v2.AuxInt = int64ToAuxInt(0)
-		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
-		v3.AuxInt = int64ToAuxInt(64)
-		v3.AddArg(v1)
-		v.AddArg3(v0, v2, v3)
+		v0.AddArg2(x, y)
+		v1 := b.NewValue0(v.Pos, OpConst64, t)
+		v1.AuxInt = int64ToAuxInt(0)
+		v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
+		v2.AuxInt = int64ToAuxInt(64)
+		v3 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
+		v3.AddArg(y)
+		v2.AddArg(v3)
+		v.AddArg3(v0, v1, v2)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpLsh8x64(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
 	// match: (Lsh8x64 <t> x y)
+	// cond: shiftIsBounded(v)
+	// result: (SLL <t> x y)
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SLL)
+		v.Type = t
+		v.AddArg2(x, y)
+		return true
+	}
+	// match: (Lsh8x64 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64CSEL)
 		v.AuxInt = opToAuxInt(OpARM64LessThanU)
 		v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
@@ -25064,6 +25479,7 @@
 		v.AddArg3(v0, v1, v2)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpLsh8x8(v *Value) bool {
 	v_1 := v.Args[1]
@@ -25071,25 +25487,45 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Lsh8x8 <t> x y)
-	// result: (CSEL [OpARM64LessThanU] (SLL <t> x (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
+	// cond: shiftIsBounded(v)
+	// result: (SLL <t> x y)
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SLL)
+		v.Type = t
+		v.AddArg2(x, y)
+		return true
+	}
+	// match: (Lsh8x8 <t> x y)
+	// cond: !shiftIsBounded(v)
+	// result: (CSEL [OpARM64LessThanU] (SLL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64CSEL)
 		v.AuxInt = opToAuxInt(OpARM64LessThanU)
 		v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
-		v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
-		v1.AddArg(y)
-		v0.AddArg2(x, v1)
-		v2 := b.NewValue0(v.Pos, OpConst64, t)
-		v2.AuxInt = int64ToAuxInt(0)
-		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
-		v3.AuxInt = int64ToAuxInt(64)
-		v3.AddArg(v1)
-		v.AddArg3(v0, v2, v3)
+		v0.AddArg2(x, y)
+		v1 := b.NewValue0(v.Pos, OpConst64, t)
+		v1.AuxInt = int64ToAuxInt(0)
+		v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
+		v2.AuxInt = int64ToAuxInt(64)
+		v3 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
+		v3.AddArg(y)
+		v2.AddArg(v3)
+		v.AddArg3(v0, v1, v2)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpMod16(v *Value) bool {
 	v_1 := v.Args[1]
@@ -25240,36 +25676,6 @@
 		v.AddArg3(dst, v0, mem)
 		return true
 	}
-	// match: (Move [4] dst src mem)
-	// result: (MOVWstore dst (MOVWUload src mem) mem)
-	for {
-		if auxIntToInt64(v.AuxInt) != 4 {
-			break
-		}
-		dst := v_0
-		src := v_1
-		mem := v_2
-		v.reset(OpARM64MOVWstore)
-		v0 := b.NewValue0(v.Pos, OpARM64MOVWUload, typ.UInt32)
-		v0.AddArg2(src, mem)
-		v.AddArg3(dst, v0, mem)
-		return true
-	}
-	// match: (Move [8] dst src mem)
-	// result: (MOVDstore dst (MOVDload src mem) mem)
-	for {
-		if auxIntToInt64(v.AuxInt) != 8 {
-			break
-		}
-		dst := v_0
-		src := v_1
-		mem := v_2
-		v.reset(OpARM64MOVDstore)
-		v0 := b.NewValue0(v.Pos, OpARM64MOVDload, typ.UInt64)
-		v0.AddArg2(src, mem)
-		v.AddArg3(dst, v0, mem)
-		return true
-	}
 	// match: (Move [3] dst src mem)
 	// result: (MOVBstore [2] dst (MOVBUload [2] src mem) (MOVHstore dst (MOVHUload src mem) mem))
 	for {
@@ -25291,6 +25697,21 @@
 		v.AddArg3(dst, v0, v1)
 		return true
 	}
+	// match: (Move [4] dst src mem)
+	// result: (MOVWstore dst (MOVWUload src mem) mem)
+	for {
+		if auxIntToInt64(v.AuxInt) != 4 {
+			break
+		}
+		dst := v_0
+		src := v_1
+		mem := v_2
+		v.reset(OpARM64MOVWstore)
+		v0 := b.NewValue0(v.Pos, OpARM64MOVWUload, typ.UInt32)
+		v0.AddArg2(src, mem)
+		v.AddArg3(dst, v0, mem)
+		return true
+	}
 	// match: (Move [5] dst src mem)
 	// result: (MOVBstore [4] dst (MOVBUload [4] src mem) (MOVWstore dst (MOVWUload src mem) mem))
 	for {
@@ -25334,7 +25755,7 @@
 		return true
 	}
 	// match: (Move [7] dst src mem)
-	// result: (MOVBstore [6] dst (MOVBUload [6] src mem) (MOVHstore [4] dst (MOVHUload [4] src mem) (MOVWstore dst (MOVWUload src mem) mem)))
+	// result: (MOVWstore [3] dst (MOVWUload [3] src mem) (MOVWstore dst (MOVWUload src mem) mem))
 	for {
 		if auxIntToInt64(v.AuxInt) != 7 {
 			break
@@ -25342,21 +25763,93 @@
 		dst := v_0
 		src := v_1
 		mem := v_2
-		v.reset(OpARM64MOVBstore)
-		v.AuxInt = int32ToAuxInt(6)
-		v0 := b.NewValue0(v.Pos, OpARM64MOVBUload, typ.UInt8)
-		v0.AuxInt = int32ToAuxInt(6)
+		v.reset(OpARM64MOVWstore)
+		v.AuxInt = int32ToAuxInt(3)
+		v0 := b.NewValue0(v.Pos, OpARM64MOVWUload, typ.UInt32)
+		v0.AuxInt = int32ToAuxInt(3)
 		v0.AddArg2(src, mem)
-		v1 := b.NewValue0(v.Pos, OpARM64MOVHstore, types.TypeMem)
-		v1.AuxInt = int32ToAuxInt(4)
-		v2 := b.NewValue0(v.Pos, OpARM64MOVHUload, typ.UInt16)
-		v2.AuxInt = int32ToAuxInt(4)
+		v1 := b.NewValue0(v.Pos, OpARM64MOVWstore, types.TypeMem)
+		v2 := b.NewValue0(v.Pos, OpARM64MOVWUload, typ.UInt32)
 		v2.AddArg2(src, mem)
-		v3 := b.NewValue0(v.Pos, OpARM64MOVWstore, types.TypeMem)
-		v4 := b.NewValue0(v.Pos, OpARM64MOVWUload, typ.UInt32)
-		v4.AddArg2(src, mem)
-		v3.AddArg3(dst, v4, mem)
-		v1.AddArg3(dst, v2, v3)
+		v1.AddArg3(dst, v2, mem)
+		v.AddArg3(dst, v0, v1)
+		return true
+	}
+	// match: (Move [8] dst src mem)
+	// result: (MOVDstore dst (MOVDload src mem) mem)
+	for {
+		if auxIntToInt64(v.AuxInt) != 8 {
+			break
+		}
+		dst := v_0
+		src := v_1
+		mem := v_2
+		v.reset(OpARM64MOVDstore)
+		v0 := b.NewValue0(v.Pos, OpARM64MOVDload, typ.UInt64)
+		v0.AddArg2(src, mem)
+		v.AddArg3(dst, v0, mem)
+		return true
+	}
+	// match: (Move [9] dst src mem)
+	// result: (MOVBstore [8] dst (MOVBUload [8] src mem) (MOVDstore dst (MOVDload src mem) mem))
+	for {
+		if auxIntToInt64(v.AuxInt) != 9 {
+			break
+		}
+		dst := v_0
+		src := v_1
+		mem := v_2
+		v.reset(OpARM64MOVBstore)
+		v.AuxInt = int32ToAuxInt(8)
+		v0 := b.NewValue0(v.Pos, OpARM64MOVBUload, typ.UInt8)
+		v0.AuxInt = int32ToAuxInt(8)
+		v0.AddArg2(src, mem)
+		v1 := b.NewValue0(v.Pos, OpARM64MOVDstore, types.TypeMem)
+		v2 := b.NewValue0(v.Pos, OpARM64MOVDload, typ.UInt64)
+		v2.AddArg2(src, mem)
+		v1.AddArg3(dst, v2, mem)
+		v.AddArg3(dst, v0, v1)
+		return true
+	}
+	// match: (Move [10] dst src mem)
+	// result: (MOVHstore [8] dst (MOVHUload [8] src mem) (MOVDstore dst (MOVDload src mem) mem))
+	for {
+		if auxIntToInt64(v.AuxInt) != 10 {
+			break
+		}
+		dst := v_0
+		src := v_1
+		mem := v_2
+		v.reset(OpARM64MOVHstore)
+		v.AuxInt = int32ToAuxInt(8)
+		v0 := b.NewValue0(v.Pos, OpARM64MOVHUload, typ.UInt16)
+		v0.AuxInt = int32ToAuxInt(8)
+		v0.AddArg2(src, mem)
+		v1 := b.NewValue0(v.Pos, OpARM64MOVDstore, types.TypeMem)
+		v2 := b.NewValue0(v.Pos, OpARM64MOVDload, typ.UInt64)
+		v2.AddArg2(src, mem)
+		v1.AddArg3(dst, v2, mem)
+		v.AddArg3(dst, v0, v1)
+		return true
+	}
+	// match: (Move [11] dst src mem)
+	// result: (MOVDstore [3] dst (MOVDload [3] src mem) (MOVDstore dst (MOVDload src mem) mem))
+	for {
+		if auxIntToInt64(v.AuxInt) != 11 {
+			break
+		}
+		dst := v_0
+		src := v_1
+		mem := v_2
+		v.reset(OpARM64MOVDstore)
+		v.AuxInt = int32ToAuxInt(3)
+		v0 := b.NewValue0(v.Pos, OpARM64MOVDload, typ.UInt64)
+		v0.AuxInt = int32ToAuxInt(3)
+		v0.AddArg2(src, mem)
+		v1 := b.NewValue0(v.Pos, OpARM64MOVDstore, types.TypeMem)
+		v2 := b.NewValue0(v.Pos, OpARM64MOVDload, typ.UInt64)
+		v2.AddArg2(src, mem)
+		v1.AddArg3(dst, v2, mem)
 		v.AddArg3(dst, v0, v1)
 		return true
 	}
@@ -25381,19 +25874,19 @@
 		v.AddArg3(dst, v0, v1)
 		return true
 	}
-	// match: (Move [16] dst src mem)
-	// result: (MOVDstore [8] dst (MOVDload [8] src mem) (MOVDstore dst (MOVDload src mem) mem))
+	// match: (Move [13] dst src mem)
+	// result: (MOVDstore [5] dst (MOVDload [5] src mem) (MOVDstore dst (MOVDload src mem) mem))
 	for {
-		if auxIntToInt64(v.AuxInt) != 16 {
+		if auxIntToInt64(v.AuxInt) != 13 {
 			break
 		}
 		dst := v_0
 		src := v_1
 		mem := v_2
 		v.reset(OpARM64MOVDstore)
-		v.AuxInt = int32ToAuxInt(8)
+		v.AuxInt = int32ToAuxInt(5)
 		v0 := b.NewValue0(v.Pos, OpARM64MOVDload, typ.UInt64)
-		v0.AuxInt = int32ToAuxInt(8)
+		v0.AuxInt = int32ToAuxInt(5)
 		v0.AddArg2(src, mem)
 		v1 := b.NewValue0(v.Pos, OpARM64MOVDstore, types.TypeMem)
 		v2 := b.NewValue0(v.Pos, OpARM64MOVDload, typ.UInt64)
@@ -25402,89 +25895,243 @@
 		v.AddArg3(dst, v0, v1)
 		return true
 	}
-	// match: (Move [24] dst src mem)
-	// result: (MOVDstore [16] dst (MOVDload [16] src mem) (MOVDstore [8] dst (MOVDload [8] src mem) (MOVDstore dst (MOVDload src mem) mem)))
+	// match: (Move [14] dst src mem)
+	// result: (MOVDstore [6] dst (MOVDload [6] src mem) (MOVDstore dst (MOVDload src mem) mem))
 	for {
-		if auxIntToInt64(v.AuxInt) != 24 {
+		if auxIntToInt64(v.AuxInt) != 14 {
 			break
 		}
 		dst := v_0
 		src := v_1
 		mem := v_2
 		v.reset(OpARM64MOVDstore)
-		v.AuxInt = int32ToAuxInt(16)
+		v.AuxInt = int32ToAuxInt(6)
 		v0 := b.NewValue0(v.Pos, OpARM64MOVDload, typ.UInt64)
-		v0.AuxInt = int32ToAuxInt(16)
+		v0.AuxInt = int32ToAuxInt(6)
 		v0.AddArg2(src, mem)
 		v1 := b.NewValue0(v.Pos, OpARM64MOVDstore, types.TypeMem)
-		v1.AuxInt = int32ToAuxInt(8)
 		v2 := b.NewValue0(v.Pos, OpARM64MOVDload, typ.UInt64)
-		v2.AuxInt = int32ToAuxInt(8)
 		v2.AddArg2(src, mem)
-		v3 := b.NewValue0(v.Pos, OpARM64MOVDstore, types.TypeMem)
-		v4 := b.NewValue0(v.Pos, OpARM64MOVDload, typ.UInt64)
-		v4.AddArg2(src, mem)
-		v3.AddArg3(dst, v4, mem)
-		v1.AddArg3(dst, v2, v3)
+		v1.AddArg3(dst, v2, mem)
 		v.AddArg3(dst, v0, v1)
 		return true
 	}
+	// match: (Move [15] dst src mem)
+	// result: (MOVDstore [7] dst (MOVDload [7] src mem) (MOVDstore dst (MOVDload src mem) mem))
+	for {
+		if auxIntToInt64(v.AuxInt) != 15 {
+			break
+		}
+		dst := v_0
+		src := v_1
+		mem := v_2
+		v.reset(OpARM64MOVDstore)
+		v.AuxInt = int32ToAuxInt(7)
+		v0 := b.NewValue0(v.Pos, OpARM64MOVDload, typ.UInt64)
+		v0.AuxInt = int32ToAuxInt(7)
+		v0.AddArg2(src, mem)
+		v1 := b.NewValue0(v.Pos, OpARM64MOVDstore, types.TypeMem)
+		v2 := b.NewValue0(v.Pos, OpARM64MOVDload, typ.UInt64)
+		v2.AddArg2(src, mem)
+		v1.AddArg3(dst, v2, mem)
+		v.AddArg3(dst, v0, v1)
+		return true
+	}
+	// match: (Move [16] dst src mem)
+	// result: (STP dst (Select0 <typ.UInt64> (LDP src mem)) (Select1 <typ.UInt64> (LDP src mem)) mem)
+	for {
+		if auxIntToInt64(v.AuxInt) != 16 {
+			break
+		}
+		dst := v_0
+		src := v_1
+		mem := v_2
+		v.reset(OpARM64STP)
+		v0 := b.NewValue0(v.Pos, OpSelect0, typ.UInt64)
+		v1 := b.NewValue0(v.Pos, OpARM64LDP, types.NewTuple(typ.UInt64, typ.UInt64))
+		v1.AddArg2(src, mem)
+		v0.AddArg(v1)
+		v2 := b.NewValue0(v.Pos, OpSelect1, typ.UInt64)
+		v2.AddArg(v1)
+		v.AddArg4(dst, v0, v2, mem)
+		return true
+	}
+	// match: (Move [32] dst src mem)
+	// result: (STP [16] dst (Select0 <typ.UInt64> (LDP [16] src mem)) (Select1 <typ.UInt64> (LDP [16] src mem)) (STP dst (Select0 <typ.UInt64> (LDP src mem)) (Select1 <typ.UInt64> (LDP src mem)) mem))
+	for {
+		if auxIntToInt64(v.AuxInt) != 32 {
+			break
+		}
+		dst := v_0
+		src := v_1
+		mem := v_2
+		v.reset(OpARM64STP)
+		v.AuxInt = int32ToAuxInt(16)
+		v0 := b.NewValue0(v.Pos, OpSelect0, typ.UInt64)
+		v1 := b.NewValue0(v.Pos, OpARM64LDP, types.NewTuple(typ.UInt64, typ.UInt64))
+		v1.AuxInt = int32ToAuxInt(16)
+		v1.AddArg2(src, mem)
+		v0.AddArg(v1)
+		v2 := b.NewValue0(v.Pos, OpSelect1, typ.UInt64)
+		v2.AddArg(v1)
+		v3 := b.NewValue0(v.Pos, OpARM64STP, types.TypeMem)
+		v4 := b.NewValue0(v.Pos, OpSelect0, typ.UInt64)
+		v5 := b.NewValue0(v.Pos, OpARM64LDP, types.NewTuple(typ.UInt64, typ.UInt64))
+		v5.AddArg2(src, mem)
+		v4.AddArg(v5)
+		v6 := b.NewValue0(v.Pos, OpSelect1, typ.UInt64)
+		v6.AddArg(v5)
+		v3.AddArg4(dst, v4, v6, mem)
+		v.AddArg4(dst, v0, v2, v3)
+		return true
+	}
+	// match: (Move [48] dst src mem)
+	// result: (STP [32] dst (Select0 <typ.UInt64> (LDP [32] src mem)) (Select1 <typ.UInt64> (LDP [32] src mem)) (STP [16] dst (Select0 <typ.UInt64> (LDP [16] src mem)) (Select1 <typ.UInt64> (LDP [16] src mem)) (STP dst (Select0 <typ.UInt64> (LDP src mem)) (Select1 <typ.UInt64> (LDP src mem)) mem)))
+	for {
+		if auxIntToInt64(v.AuxInt) != 48 {
+			break
+		}
+		dst := v_0
+		src := v_1
+		mem := v_2
+		v.reset(OpARM64STP)
+		v.AuxInt = int32ToAuxInt(32)
+		v0 := b.NewValue0(v.Pos, OpSelect0, typ.UInt64)
+		v1 := b.NewValue0(v.Pos, OpARM64LDP, types.NewTuple(typ.UInt64, typ.UInt64))
+		v1.AuxInt = int32ToAuxInt(32)
+		v1.AddArg2(src, mem)
+		v0.AddArg(v1)
+		v2 := b.NewValue0(v.Pos, OpSelect1, typ.UInt64)
+		v2.AddArg(v1)
+		v3 := b.NewValue0(v.Pos, OpARM64STP, types.TypeMem)
+		v3.AuxInt = int32ToAuxInt(16)
+		v4 := b.NewValue0(v.Pos, OpSelect0, typ.UInt64)
+		v5 := b.NewValue0(v.Pos, OpARM64LDP, types.NewTuple(typ.UInt64, typ.UInt64))
+		v5.AuxInt = int32ToAuxInt(16)
+		v5.AddArg2(src, mem)
+		v4.AddArg(v5)
+		v6 := b.NewValue0(v.Pos, OpSelect1, typ.UInt64)
+		v6.AddArg(v5)
+		v7 := b.NewValue0(v.Pos, OpARM64STP, types.TypeMem)
+		v8 := b.NewValue0(v.Pos, OpSelect0, typ.UInt64)
+		v9 := b.NewValue0(v.Pos, OpARM64LDP, types.NewTuple(typ.UInt64, typ.UInt64))
+		v9.AddArg2(src, mem)
+		v8.AddArg(v9)
+		v10 := b.NewValue0(v.Pos, OpSelect1, typ.UInt64)
+		v10.AddArg(v9)
+		v7.AddArg4(dst, v8, v10, mem)
+		v3.AddArg4(dst, v4, v6, v7)
+		v.AddArg4(dst, v0, v2, v3)
+		return true
+	}
+	// match: (Move [64] dst src mem)
+	// result: (STP [48] dst (Select0 <typ.UInt64> (LDP [48] src mem)) (Select1 <typ.UInt64> (LDP [48] src mem)) (STP [32] dst (Select0 <typ.UInt64> (LDP [32] src mem)) (Select1 <typ.UInt64> (LDP [32] src mem)) (STP [16] dst (Select0 <typ.UInt64> (LDP [16] src mem)) (Select1 <typ.UInt64> (LDP [16] src mem)) (STP dst (Select0 <typ.UInt64> (LDP src mem)) (Select1 <typ.UInt64> (LDP src mem)) mem))))
+	for {
+		if auxIntToInt64(v.AuxInt) != 64 {
+			break
+		}
+		dst := v_0
+		src := v_1
+		mem := v_2
+		v.reset(OpARM64STP)
+		v.AuxInt = int32ToAuxInt(48)
+		v0 := b.NewValue0(v.Pos, OpSelect0, typ.UInt64)
+		v1 := b.NewValue0(v.Pos, OpARM64LDP, types.NewTuple(typ.UInt64, typ.UInt64))
+		v1.AuxInt = int32ToAuxInt(48)
+		v1.AddArg2(src, mem)
+		v0.AddArg(v1)
+		v2 := b.NewValue0(v.Pos, OpSelect1, typ.UInt64)
+		v2.AddArg(v1)
+		v3 := b.NewValue0(v.Pos, OpARM64STP, types.TypeMem)
+		v3.AuxInt = int32ToAuxInt(32)
+		v4 := b.NewValue0(v.Pos, OpSelect0, typ.UInt64)
+		v5 := b.NewValue0(v.Pos, OpARM64LDP, types.NewTuple(typ.UInt64, typ.UInt64))
+		v5.AuxInt = int32ToAuxInt(32)
+		v5.AddArg2(src, mem)
+		v4.AddArg(v5)
+		v6 := b.NewValue0(v.Pos, OpSelect1, typ.UInt64)
+		v6.AddArg(v5)
+		v7 := b.NewValue0(v.Pos, OpARM64STP, types.TypeMem)
+		v7.AuxInt = int32ToAuxInt(16)
+		v8 := b.NewValue0(v.Pos, OpSelect0, typ.UInt64)
+		v9 := b.NewValue0(v.Pos, OpARM64LDP, types.NewTuple(typ.UInt64, typ.UInt64))
+		v9.AuxInt = int32ToAuxInt(16)
+		v9.AddArg2(src, mem)
+		v8.AddArg(v9)
+		v10 := b.NewValue0(v.Pos, OpSelect1, typ.UInt64)
+		v10.AddArg(v9)
+		v11 := b.NewValue0(v.Pos, OpARM64STP, types.TypeMem)
+		v12 := b.NewValue0(v.Pos, OpSelect0, typ.UInt64)
+		v13 := b.NewValue0(v.Pos, OpARM64LDP, types.NewTuple(typ.UInt64, typ.UInt64))
+		v13.AddArg2(src, mem)
+		v12.AddArg(v13)
+		v14 := b.NewValue0(v.Pos, OpSelect1, typ.UInt64)
+		v14.AddArg(v13)
+		v11.AddArg4(dst, v12, v14, mem)
+		v7.AddArg4(dst, v8, v10, v11)
+		v3.AddArg4(dst, v4, v6, v7)
+		v.AddArg4(dst, v0, v2, v3)
+		return true
+	}
 	// match: (Move [s] dst src mem)
-	// cond: s%8 != 0 && s > 8
-	// result: (Move [s%8] (OffPtr <dst.Type> dst [s-s%8]) (OffPtr <src.Type> src [s-s%8]) (Move [s-s%8] dst src mem))
+	// cond: s%16 != 0 && s%16 <= 8 && s > 16
+	// result: (Move [8] (OffPtr <dst.Type> dst [s-8]) (OffPtr <src.Type> src [s-8]) (Move [s-s%16] dst src mem))
 	for {
 		s := auxIntToInt64(v.AuxInt)
 		dst := v_0
 		src := v_1
 		mem := v_2
-		if !(s%8 != 0 && s > 8) {
+		if !(s%16 != 0 && s%16 <= 8 && s > 16) {
 			break
 		}
 		v.reset(OpMove)
-		v.AuxInt = int64ToAuxInt(s % 8)
+		v.AuxInt = int64ToAuxInt(8)
 		v0 := b.NewValue0(v.Pos, OpOffPtr, dst.Type)
-		v0.AuxInt = int64ToAuxInt(s - s%8)
+		v0.AuxInt = int64ToAuxInt(s - 8)
 		v0.AddArg(dst)
 		v1 := b.NewValue0(v.Pos, OpOffPtr, src.Type)
-		v1.AuxInt = int64ToAuxInt(s - s%8)
+		v1.AuxInt = int64ToAuxInt(s - 8)
 		v1.AddArg(src)
 		v2 := b.NewValue0(v.Pos, OpMove, types.TypeMem)
-		v2.AuxInt = int64ToAuxInt(s - s%8)
+		v2.AuxInt = int64ToAuxInt(s - s%16)
 		v2.AddArg3(dst, src, mem)
 		v.AddArg3(v0, v1, v2)
 		return true
 	}
 	// match: (Move [s] dst src mem)
-	// cond: s > 32 && s <= 16*64 && s%16 == 8 && !config.noDuffDevice && logLargeCopy(v, s)
-	// result: (MOVDstore [int32(s-8)] dst (MOVDload [int32(s-8)] src mem) (DUFFCOPY <types.TypeMem> [8*(64-(s-8)/16)] dst src mem))
+	// cond: s%16 != 0 && s%16 > 8 && s > 16
+	// result: (Move [16] (OffPtr <dst.Type> dst [s-16]) (OffPtr <src.Type> src [s-16]) (Move [s-s%16] dst src mem))
 	for {
 		s := auxIntToInt64(v.AuxInt)
 		dst := v_0
 		src := v_1
 		mem := v_2
-		if !(s > 32 && s <= 16*64 && s%16 == 8 && !config.noDuffDevice && logLargeCopy(v, s)) {
+		if !(s%16 != 0 && s%16 > 8 && s > 16) {
 			break
 		}
-		v.reset(OpARM64MOVDstore)
-		v.AuxInt = int32ToAuxInt(int32(s - 8))
-		v0 := b.NewValue0(v.Pos, OpARM64MOVDload, typ.UInt64)
-		v0.AuxInt = int32ToAuxInt(int32(s - 8))
-		v0.AddArg2(src, mem)
-		v1 := b.NewValue0(v.Pos, OpARM64DUFFCOPY, types.TypeMem)
-		v1.AuxInt = int64ToAuxInt(8 * (64 - (s-8)/16))
-		v1.AddArg3(dst, src, mem)
-		v.AddArg3(dst, v0, v1)
+		v.reset(OpMove)
+		v.AuxInt = int64ToAuxInt(16)
+		v0 := b.NewValue0(v.Pos, OpOffPtr, dst.Type)
+		v0.AuxInt = int64ToAuxInt(s - 16)
+		v0.AddArg(dst)
+		v1 := b.NewValue0(v.Pos, OpOffPtr, src.Type)
+		v1.AuxInt = int64ToAuxInt(s - 16)
+		v1.AddArg(src)
+		v2 := b.NewValue0(v.Pos, OpMove, types.TypeMem)
+		v2.AuxInt = int64ToAuxInt(s - s%16)
+		v2.AddArg3(dst, src, mem)
+		v.AddArg3(v0, v1, v2)
 		return true
 	}
 	// match: (Move [s] dst src mem)
-	// cond: s > 32 && s <= 16*64 && s%16 == 0 && !config.noDuffDevice && logLargeCopy(v, s)
+	// cond: s > 64 && s <= 16*64 && s%16 == 0 && !config.noDuffDevice && logLargeCopy(v, s)
 	// result: (DUFFCOPY [8 * (64 - s/16)] dst src mem)
 	for {
 		s := auxIntToInt64(v.AuxInt)
 		dst := v_0
 		src := v_1
 		mem := v_2
-		if !(s > 32 && s <= 16*64 && s%16 == 0 && !config.noDuffDevice && logLargeCopy(v, s)) {
+		if !(s > 64 && s <= 16*64 && s%16 == 0 && !config.noDuffDevice && logLargeCopy(v, s)) {
 			break
 		}
 		v.reset(OpARM64DUFFCOPY)
@@ -25493,19 +26140,19 @@
 		return true
 	}
 	// match: (Move [s] dst src mem)
-	// cond: s > 24 && s%8 == 0 && logLargeCopy(v, s)
-	// result: (LoweredMove dst src (ADDconst <src.Type> src [s-8]) mem)
+	// cond: s%16 == 0 && (s > 16*64 || config.noDuffDevice) && logLargeCopy(v, s)
+	// result: (LoweredMove dst src (ADDconst <src.Type> src [s-16]) mem)
 	for {
 		s := auxIntToInt64(v.AuxInt)
 		dst := v_0
 		src := v_1
 		mem := v_2
-		if !(s > 24 && s%8 == 0 && logLargeCopy(v, s)) {
+		if !(s%16 == 0 && (s > 16*64 || config.noDuffDevice) && logLargeCopy(v, s)) {
 			break
 		}
 		v.reset(OpARM64LoweredMove)
 		v0 := b.NewValue0(v.Pos, OpARM64ADDconst, src.Type)
-		v0.AuxInt = int64ToAuxInt(s - 8)
+		v0.AuxInt = int64ToAuxInt(s - 16)
 		v0.AddArg(src)
 		v.AddArg4(dst, src, v0, mem)
 		return true
@@ -25863,7 +26510,24 @@
 		v.AddArg2(v0, v2)
 		return true
 	}
-	return false
+	// match: (RotateLeft16 <t> x y)
+	// result: (RORW <t> (ORshiftLL <typ.UInt32> (ZeroExt16to32 x) (ZeroExt16to32 x) [16]) (NEG <typ.Int64> y))
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		v.reset(OpARM64RORW)
+		v.Type = t
+		v0 := b.NewValue0(v.Pos, OpARM64ORshiftLL, typ.UInt32)
+		v0.AuxInt = int64ToAuxInt(16)
+		v1 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
+		v1.AddArg(x)
+		v0.AddArg2(v1, v1)
+		v2 := b.NewValue0(v.Pos, OpARM64NEG, typ.Int64)
+		v2.AddArg(y)
+		v.AddArg2(v0, v2)
+		return true
+	}
 }
 func rewriteValueARM64_OpRotateLeft32(v *Value) bool {
 	v_1 := v.Args[1]
@@ -25923,7 +26587,31 @@
 		v.AddArg2(v0, v2)
 		return true
 	}
-	return false
+	// match: (RotateLeft8 <t> x y)
+	// result: (OR <t> (SLL <t> x (ANDconst <typ.Int64> [7] y)) (SRL <t> (ZeroExt8to64 x) (ANDconst <typ.Int64> [7] (NEG <typ.Int64> y))))
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		v.reset(OpARM64OR)
+		v.Type = t
+		v0 := b.NewValue0(v.Pos, OpARM64SLL, t)
+		v1 := b.NewValue0(v.Pos, OpARM64ANDconst, typ.Int64)
+		v1.AuxInt = int64ToAuxInt(7)
+		v1.AddArg(y)
+		v0.AddArg2(x, v1)
+		v2 := b.NewValue0(v.Pos, OpARM64SRL, t)
+		v3 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
+		v3.AddArg(x)
+		v4 := b.NewValue0(v.Pos, OpARM64ANDconst, typ.Int64)
+		v4.AuxInt = int64ToAuxInt(7)
+		v5 := b.NewValue0(v.Pos, OpARM64NEG, typ.Int64)
+		v5.AddArg(y)
+		v4.AddArg(v5)
+		v2.AddArg2(v3, v4)
+		v.AddArg2(v0, v2)
+		return true
+	}
 }
 func rewriteValueARM64_OpRsh16Ux16(v *Value) bool {
 	v_1 := v.Args[1]
@@ -25931,27 +26619,49 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh16Ux16 <t> x y)
-	// result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt16to64 x) (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+	// cond: shiftIsBounded(v)
+	// result: (SRL <t> (ZeroExt16to64 x) y)
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SRL)
+		v.Type = t
+		v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
+	// match: (Rsh16Ux16 <t> x y)
+	// cond: !shiftIsBounded(v)
+	// result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt16to64 x) y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64CSEL)
 		v.AuxInt = opToAuxInt(OpARM64LessThanU)
 		v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
 		v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
 		v1.AddArg(x)
-		v2 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
-		v2.AddArg(y)
-		v0.AddArg2(v1, v2)
-		v3 := b.NewValue0(v.Pos, OpConst64, t)
-		v3.AuxInt = int64ToAuxInt(0)
-		v4 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
-		v4.AuxInt = int64ToAuxInt(64)
-		v4.AddArg(v2)
-		v.AddArg3(v0, v3, v4)
+		v0.AddArg2(v1, y)
+		v2 := b.NewValue0(v.Pos, OpConst64, t)
+		v2.AuxInt = int64ToAuxInt(0)
+		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
+		v3.AuxInt = int64ToAuxInt(64)
+		v4 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
+		v4.AddArg(y)
+		v3.AddArg(v4)
+		v.AddArg3(v0, v2, v3)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpRsh16Ux32(v *Value) bool {
 	v_1 := v.Args[1]
@@ -25959,27 +26669,49 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh16Ux32 <t> x y)
-	// result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt16to64 x) (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+	// cond: shiftIsBounded(v)
+	// result: (SRL <t> (ZeroExt16to64 x) y)
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SRL)
+		v.Type = t
+		v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
+	// match: (Rsh16Ux32 <t> x y)
+	// cond: !shiftIsBounded(v)
+	// result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt16to64 x) y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64CSEL)
 		v.AuxInt = opToAuxInt(OpARM64LessThanU)
 		v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
 		v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
 		v1.AddArg(x)
-		v2 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
-		v2.AddArg(y)
-		v0.AddArg2(v1, v2)
-		v3 := b.NewValue0(v.Pos, OpConst64, t)
-		v3.AuxInt = int64ToAuxInt(0)
-		v4 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
-		v4.AuxInt = int64ToAuxInt(64)
-		v4.AddArg(v2)
-		v.AddArg3(v0, v3, v4)
+		v0.AddArg2(v1, y)
+		v2 := b.NewValue0(v.Pos, OpConst64, t)
+		v2.AuxInt = int64ToAuxInt(0)
+		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
+		v3.AuxInt = int64ToAuxInt(64)
+		v4 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
+		v4.AddArg(y)
+		v3.AddArg(v4)
+		v.AddArg3(v0, v2, v3)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpRsh16Ux64(v *Value) bool {
 	v_1 := v.Args[1]
@@ -25987,11 +26719,32 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh16Ux64 <t> x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRL <t> (ZeroExt16to64 x) y)
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SRL)
+		v.Type = t
+		v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
+	// match: (Rsh16Ux64 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt16to64 x) y) (Const64 <t> [0]) (CMPconst [64] y))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64CSEL)
 		v.AuxInt = opToAuxInt(OpARM64LessThanU)
 		v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
@@ -26006,6 +26759,7 @@
 		v.AddArg3(v0, v2, v3)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpRsh16Ux8(v *Value) bool {
 	v_1 := v.Args[1]
@@ -26013,92 +26767,179 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh16Ux8 <t> x y)
-	// result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt16to64 x) (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
+	// cond: shiftIsBounded(v)
+	// result: (SRL <t> (ZeroExt16to64 x) y)
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SRL)
+		v.Type = t
+		v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
+	// match: (Rsh16Ux8 <t> x y)
+	// cond: !shiftIsBounded(v)
+	// result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt16to64 x) y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64CSEL)
 		v.AuxInt = opToAuxInt(OpARM64LessThanU)
 		v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
 		v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
 		v1.AddArg(x)
-		v2 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
-		v2.AddArg(y)
-		v0.AddArg2(v1, v2)
-		v3 := b.NewValue0(v.Pos, OpConst64, t)
-		v3.AuxInt = int64ToAuxInt(0)
-		v4 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
-		v4.AuxInt = int64ToAuxInt(64)
-		v4.AddArg(v2)
-		v.AddArg3(v0, v3, v4)
+		v0.AddArg2(v1, y)
+		v2 := b.NewValue0(v.Pos, OpConst64, t)
+		v2.AuxInt = int64ToAuxInt(0)
+		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
+		v3.AuxInt = int64ToAuxInt(64)
+		v4 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
+		v4.AddArg(y)
+		v3.AddArg(v4)
+		v.AddArg3(v0, v2, v3)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpRsh16x16(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
+	// match: (Rsh16x16 <t> x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRA <t> (SignExt16to64 x) y)
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SRA)
+		v.Type = t
+		v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
 	// match: (Rsh16x16 x y)
-	// result: (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt16to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
+	// cond: !shiftIsBounded(v)
+	// result: (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
 	for {
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64SRA)
 		v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64)
 		v0.AddArg(x)
 		v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
 		v1.AuxInt = opToAuxInt(OpARM64LessThanU)
-		v2 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
-		v2.AddArg(y)
-		v3 := b.NewValue0(v.Pos, OpConst64, y.Type)
-		v3.AuxInt = int64ToAuxInt(63)
-		v4 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
-		v4.AuxInt = int64ToAuxInt(64)
-		v4.AddArg(v2)
-		v1.AddArg3(v2, v3, v4)
+		v2 := b.NewValue0(v.Pos, OpConst64, y.Type)
+		v2.AuxInt = int64ToAuxInt(63)
+		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
+		v3.AuxInt = int64ToAuxInt(64)
+		v4 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
+		v4.AddArg(y)
+		v3.AddArg(v4)
+		v1.AddArg3(y, v2, v3)
 		v.AddArg2(v0, v1)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpRsh16x32(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
+	// match: (Rsh16x32 <t> x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRA <t> (SignExt16to64 x) y)
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SRA)
+		v.Type = t
+		v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
 	// match: (Rsh16x32 x y)
-	// result: (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt32to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
+	// cond: !shiftIsBounded(v)
+	// result: (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
 	for {
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64SRA)
 		v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64)
 		v0.AddArg(x)
 		v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
 		v1.AuxInt = opToAuxInt(OpARM64LessThanU)
-		v2 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
-		v2.AddArg(y)
-		v3 := b.NewValue0(v.Pos, OpConst64, y.Type)
-		v3.AuxInt = int64ToAuxInt(63)
-		v4 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
-		v4.AuxInt = int64ToAuxInt(64)
-		v4.AddArg(v2)
-		v1.AddArg3(v2, v3, v4)
+		v2 := b.NewValue0(v.Pos, OpConst64, y.Type)
+		v2.AuxInt = int64ToAuxInt(63)
+		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
+		v3.AuxInt = int64ToAuxInt(64)
+		v4 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
+		v4.AddArg(y)
+		v3.AddArg(v4)
+		v1.AddArg3(y, v2, v3)
 		v.AddArg2(v0, v1)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpRsh16x64(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
+	// match: (Rsh16x64 <t> x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRA <t> (SignExt16to64 x) y)
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SRA)
+		v.Type = t
+		v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
 	// match: (Rsh16x64 x y)
+	// cond: !shiftIsBounded(v)
 	// result: (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
 	for {
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64SRA)
 		v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64)
 		v0.AddArg(x)
@@ -26113,33 +26954,56 @@
 		v.AddArg2(v0, v1)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpRsh16x8(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
+	// match: (Rsh16x8 <t> x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRA <t> (SignExt16to64 x) y)
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SRA)
+		v.Type = t
+		v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
 	// match: (Rsh16x8 x y)
-	// result: (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt8to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64 y))))
+	// cond: !shiftIsBounded(v)
+	// result: (SRA (SignExt16to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64 y))))
 	for {
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64SRA)
 		v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64)
 		v0.AddArg(x)
 		v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
 		v1.AuxInt = opToAuxInt(OpARM64LessThanU)
-		v2 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
-		v2.AddArg(y)
-		v3 := b.NewValue0(v.Pos, OpConst64, y.Type)
-		v3.AuxInt = int64ToAuxInt(63)
-		v4 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
-		v4.AuxInt = int64ToAuxInt(64)
-		v4.AddArg(v2)
-		v1.AddArg3(v2, v3, v4)
+		v2 := b.NewValue0(v.Pos, OpConst64, y.Type)
+		v2.AuxInt = int64ToAuxInt(63)
+		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
+		v3.AuxInt = int64ToAuxInt(64)
+		v4 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
+		v4.AddArg(y)
+		v3.AddArg(v4)
+		v1.AddArg3(y, v2, v3)
 		v.AddArg2(v0, v1)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpRsh32Ux16(v *Value) bool {
 	v_1 := v.Args[1]
@@ -26147,27 +27011,49 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh32Ux16 <t> x y)
-	// result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt32to64 x) (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+	// cond: shiftIsBounded(v)
+	// result: (SRL <t> (ZeroExt32to64 x) y)
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SRL)
+		v.Type = t
+		v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
+	// match: (Rsh32Ux16 <t> x y)
+	// cond: !shiftIsBounded(v)
+	// result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt32to64 x) y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64CSEL)
 		v.AuxInt = opToAuxInt(OpARM64LessThanU)
 		v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
 		v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
 		v1.AddArg(x)
-		v2 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
-		v2.AddArg(y)
-		v0.AddArg2(v1, v2)
-		v3 := b.NewValue0(v.Pos, OpConst64, t)
-		v3.AuxInt = int64ToAuxInt(0)
-		v4 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
-		v4.AuxInt = int64ToAuxInt(64)
-		v4.AddArg(v2)
-		v.AddArg3(v0, v3, v4)
+		v0.AddArg2(v1, y)
+		v2 := b.NewValue0(v.Pos, OpConst64, t)
+		v2.AuxInt = int64ToAuxInt(0)
+		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
+		v3.AuxInt = int64ToAuxInt(64)
+		v4 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
+		v4.AddArg(y)
+		v3.AddArg(v4)
+		v.AddArg3(v0, v2, v3)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpRsh32Ux32(v *Value) bool {
 	v_1 := v.Args[1]
@@ -26175,27 +27061,49 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh32Ux32 <t> x y)
-	// result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt32to64 x) (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+	// cond: shiftIsBounded(v)
+	// result: (SRL <t> (ZeroExt32to64 x) y)
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SRL)
+		v.Type = t
+		v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
+	// match: (Rsh32Ux32 <t> x y)
+	// cond: !shiftIsBounded(v)
+	// result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt32to64 x) y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64CSEL)
 		v.AuxInt = opToAuxInt(OpARM64LessThanU)
 		v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
 		v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
 		v1.AddArg(x)
-		v2 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
-		v2.AddArg(y)
-		v0.AddArg2(v1, v2)
-		v3 := b.NewValue0(v.Pos, OpConst64, t)
-		v3.AuxInt = int64ToAuxInt(0)
-		v4 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
-		v4.AuxInt = int64ToAuxInt(64)
-		v4.AddArg(v2)
-		v.AddArg3(v0, v3, v4)
+		v0.AddArg2(v1, y)
+		v2 := b.NewValue0(v.Pos, OpConst64, t)
+		v2.AuxInt = int64ToAuxInt(0)
+		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
+		v3.AuxInt = int64ToAuxInt(64)
+		v4 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
+		v4.AddArg(y)
+		v3.AddArg(v4)
+		v.AddArg3(v0, v2, v3)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpRsh32Ux64(v *Value) bool {
 	v_1 := v.Args[1]
@@ -26203,11 +27111,32 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh32Ux64 <t> x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRL <t> (ZeroExt32to64 x) y)
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SRL)
+		v.Type = t
+		v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
+	// match: (Rsh32Ux64 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt32to64 x) y) (Const64 <t> [0]) (CMPconst [64] y))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64CSEL)
 		v.AuxInt = opToAuxInt(OpARM64LessThanU)
 		v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
@@ -26222,6 +27151,7 @@
 		v.AddArg3(v0, v2, v3)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpRsh32Ux8(v *Value) bool {
 	v_1 := v.Args[1]
@@ -26229,92 +27159,179 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh32Ux8 <t> x y)
-	// result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt32to64 x) (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
+	// cond: shiftIsBounded(v)
+	// result: (SRL <t> (ZeroExt32to64 x) y)
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SRL)
+		v.Type = t
+		v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
+	// match: (Rsh32Ux8 <t> x y)
+	// cond: !shiftIsBounded(v)
+	// result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt32to64 x) y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64CSEL)
 		v.AuxInt = opToAuxInt(OpARM64LessThanU)
 		v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
 		v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
 		v1.AddArg(x)
-		v2 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
-		v2.AddArg(y)
-		v0.AddArg2(v1, v2)
-		v3 := b.NewValue0(v.Pos, OpConst64, t)
-		v3.AuxInt = int64ToAuxInt(0)
-		v4 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
-		v4.AuxInt = int64ToAuxInt(64)
-		v4.AddArg(v2)
-		v.AddArg3(v0, v3, v4)
+		v0.AddArg2(v1, y)
+		v2 := b.NewValue0(v.Pos, OpConst64, t)
+		v2.AuxInt = int64ToAuxInt(0)
+		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
+		v3.AuxInt = int64ToAuxInt(64)
+		v4 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
+		v4.AddArg(y)
+		v3.AddArg(v4)
+		v.AddArg3(v0, v2, v3)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpRsh32x16(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
+	// match: (Rsh32x16 <t> x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRA <t> (SignExt32to64 x) y)
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SRA)
+		v.Type = t
+		v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
 	// match: (Rsh32x16 x y)
-	// result: (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt16to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
+	// cond: !shiftIsBounded(v)
+	// result: (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
 	for {
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64SRA)
 		v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
 		v0.AddArg(x)
 		v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
 		v1.AuxInt = opToAuxInt(OpARM64LessThanU)
-		v2 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
-		v2.AddArg(y)
-		v3 := b.NewValue0(v.Pos, OpConst64, y.Type)
-		v3.AuxInt = int64ToAuxInt(63)
-		v4 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
-		v4.AuxInt = int64ToAuxInt(64)
-		v4.AddArg(v2)
-		v1.AddArg3(v2, v3, v4)
+		v2 := b.NewValue0(v.Pos, OpConst64, y.Type)
+		v2.AuxInt = int64ToAuxInt(63)
+		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
+		v3.AuxInt = int64ToAuxInt(64)
+		v4 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
+		v4.AddArg(y)
+		v3.AddArg(v4)
+		v1.AddArg3(y, v2, v3)
 		v.AddArg2(v0, v1)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpRsh32x32(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
+	// match: (Rsh32x32 <t> x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRA <t> (SignExt32to64 x) y)
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SRA)
+		v.Type = t
+		v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
 	// match: (Rsh32x32 x y)
-	// result: (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt32to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
+	// cond: !shiftIsBounded(v)
+	// result: (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
 	for {
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64SRA)
 		v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
 		v0.AddArg(x)
 		v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
 		v1.AuxInt = opToAuxInt(OpARM64LessThanU)
-		v2 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
-		v2.AddArg(y)
-		v3 := b.NewValue0(v.Pos, OpConst64, y.Type)
-		v3.AuxInt = int64ToAuxInt(63)
-		v4 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
-		v4.AuxInt = int64ToAuxInt(64)
-		v4.AddArg(v2)
-		v1.AddArg3(v2, v3, v4)
+		v2 := b.NewValue0(v.Pos, OpConst64, y.Type)
+		v2.AuxInt = int64ToAuxInt(63)
+		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
+		v3.AuxInt = int64ToAuxInt(64)
+		v4 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
+		v4.AddArg(y)
+		v3.AddArg(v4)
+		v1.AddArg3(y, v2, v3)
 		v.AddArg2(v0, v1)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpRsh32x64(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
+	// match: (Rsh32x64 <t> x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRA <t> (SignExt32to64 x) y)
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SRA)
+		v.Type = t
+		v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
 	// match: (Rsh32x64 x y)
+	// cond: !shiftIsBounded(v)
 	// result: (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
 	for {
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64SRA)
 		v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
 		v0.AddArg(x)
@@ -26329,33 +27346,56 @@
 		v.AddArg2(v0, v1)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpRsh32x8(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
+	// match: (Rsh32x8 <t> x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRA <t> (SignExt32to64 x) y)
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SRA)
+		v.Type = t
+		v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
 	// match: (Rsh32x8 x y)
-	// result: (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt8to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64 y))))
+	// cond: !shiftIsBounded(v)
+	// result: (SRA (SignExt32to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64 y))))
 	for {
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64SRA)
 		v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
 		v0.AddArg(x)
 		v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
 		v1.AuxInt = opToAuxInt(OpARM64LessThanU)
-		v2 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
-		v2.AddArg(y)
-		v3 := b.NewValue0(v.Pos, OpConst64, y.Type)
-		v3.AuxInt = int64ToAuxInt(63)
-		v4 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
-		v4.AuxInt = int64ToAuxInt(64)
-		v4.AddArg(v2)
-		v1.AddArg3(v2, v3, v4)
+		v2 := b.NewValue0(v.Pos, OpConst64, y.Type)
+		v2.AuxInt = int64ToAuxInt(63)
+		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
+		v3.AuxInt = int64ToAuxInt(64)
+		v4 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
+		v4.AddArg(y)
+		v3.AddArg(v4)
+		v1.AddArg3(y, v2, v3)
 		v.AddArg2(v0, v1)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpRsh64Ux16(v *Value) bool {
 	v_1 := v.Args[1]
@@ -26363,25 +27403,45 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh64Ux16 <t> x y)
-	// result: (CSEL [OpARM64LessThanU] (SRL <t> x (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+	// cond: shiftIsBounded(v)
+	// result: (SRL <t> x y)
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SRL)
+		v.Type = t
+		v.AddArg2(x, y)
+		return true
+	}
+	// match: (Rsh64Ux16 <t> x y)
+	// cond: !shiftIsBounded(v)
+	// result: (CSEL [OpARM64LessThanU] (SRL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64CSEL)
 		v.AuxInt = opToAuxInt(OpARM64LessThanU)
 		v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
-		v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
-		v1.AddArg(y)
-		v0.AddArg2(x, v1)
-		v2 := b.NewValue0(v.Pos, OpConst64, t)
-		v2.AuxInt = int64ToAuxInt(0)
-		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
-		v3.AuxInt = int64ToAuxInt(64)
-		v3.AddArg(v1)
-		v.AddArg3(v0, v2, v3)
+		v0.AddArg2(x, y)
+		v1 := b.NewValue0(v.Pos, OpConst64, t)
+		v1.AuxInt = int64ToAuxInt(0)
+		v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
+		v2.AuxInt = int64ToAuxInt(64)
+		v3 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
+		v3.AddArg(y)
+		v2.AddArg(v3)
+		v.AddArg3(v0, v1, v2)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpRsh64Ux32(v *Value) bool {
 	v_1 := v.Args[1]
@@ -26389,36 +27449,75 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh64Ux32 <t> x y)
-	// result: (CSEL [OpARM64LessThanU] (SRL <t> x (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+	// cond: shiftIsBounded(v)
+	// result: (SRL <t> x y)
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SRL)
+		v.Type = t
+		v.AddArg2(x, y)
+		return true
+	}
+	// match: (Rsh64Ux32 <t> x y)
+	// cond: !shiftIsBounded(v)
+	// result: (CSEL [OpARM64LessThanU] (SRL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64CSEL)
 		v.AuxInt = opToAuxInt(OpARM64LessThanU)
 		v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
-		v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
-		v1.AddArg(y)
-		v0.AddArg2(x, v1)
-		v2 := b.NewValue0(v.Pos, OpConst64, t)
-		v2.AuxInt = int64ToAuxInt(0)
-		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
-		v3.AuxInt = int64ToAuxInt(64)
-		v3.AddArg(v1)
-		v.AddArg3(v0, v2, v3)
+		v0.AddArg2(x, y)
+		v1 := b.NewValue0(v.Pos, OpConst64, t)
+		v1.AuxInt = int64ToAuxInt(0)
+		v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
+		v2.AuxInt = int64ToAuxInt(64)
+		v3 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
+		v3.AddArg(y)
+		v2.AddArg(v3)
+		v.AddArg3(v0, v1, v2)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpRsh64Ux64(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
 	// match: (Rsh64Ux64 <t> x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRL <t> x y)
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SRL)
+		v.Type = t
+		v.AddArg2(x, y)
+		return true
+	}
+	// match: (Rsh64Ux64 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (CSEL [OpARM64LessThanU] (SRL <t> x y) (Const64 <t> [0]) (CMPconst [64] y))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64CSEL)
 		v.AuxInt = opToAuxInt(OpARM64LessThanU)
 		v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
@@ -26431,6 +27530,7 @@
 		v.AddArg3(v0, v1, v2)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpRsh64Ux8(v *Value) bool {
 	v_1 := v.Args[1]
@@ -26438,85 +27538,164 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh64Ux8 <t> x y)
-	// result: (CSEL [OpARM64LessThanU] (SRL <t> x (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
+	// cond: shiftIsBounded(v)
+	// result: (SRL <t> x y)
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SRL)
+		v.Type = t
+		v.AddArg2(x, y)
+		return true
+	}
+	// match: (Rsh64Ux8 <t> x y)
+	// cond: !shiftIsBounded(v)
+	// result: (CSEL [OpARM64LessThanU] (SRL <t> x y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64CSEL)
 		v.AuxInt = opToAuxInt(OpARM64LessThanU)
 		v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
-		v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
-		v1.AddArg(y)
-		v0.AddArg2(x, v1)
-		v2 := b.NewValue0(v.Pos, OpConst64, t)
-		v2.AuxInt = int64ToAuxInt(0)
-		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
-		v3.AuxInt = int64ToAuxInt(64)
-		v3.AddArg(v1)
-		v.AddArg3(v0, v2, v3)
+		v0.AddArg2(x, y)
+		v1 := b.NewValue0(v.Pos, OpConst64, t)
+		v1.AuxInt = int64ToAuxInt(0)
+		v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
+		v2.AuxInt = int64ToAuxInt(64)
+		v3 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
+		v3.AddArg(y)
+		v2.AddArg(v3)
+		v.AddArg3(v0, v1, v2)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpRsh64x16(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
+	// match: (Rsh64x16 <t> x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRA <t> x y)
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SRA)
+		v.Type = t
+		v.AddArg2(x, y)
+		return true
+	}
 	// match: (Rsh64x16 x y)
-	// result: (SRA x (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt16to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
+	// cond: !shiftIsBounded(v)
+	// result: (SRA x (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
 	for {
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64SRA)
 		v0 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
 		v0.AuxInt = opToAuxInt(OpARM64LessThanU)
-		v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
-		v1.AddArg(y)
-		v2 := b.NewValue0(v.Pos, OpConst64, y.Type)
-		v2.AuxInt = int64ToAuxInt(63)
-		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
-		v3.AuxInt = int64ToAuxInt(64)
-		v3.AddArg(v1)
-		v0.AddArg3(v1, v2, v3)
+		v1 := b.NewValue0(v.Pos, OpConst64, y.Type)
+		v1.AuxInt = int64ToAuxInt(63)
+		v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
+		v2.AuxInt = int64ToAuxInt(64)
+		v3 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
+		v3.AddArg(y)
+		v2.AddArg(v3)
+		v0.AddArg3(y, v1, v2)
 		v.AddArg2(x, v0)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpRsh64x32(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
+	// match: (Rsh64x32 <t> x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRA <t> x y)
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SRA)
+		v.Type = t
+		v.AddArg2(x, y)
+		return true
+	}
 	// match: (Rsh64x32 x y)
-	// result: (SRA x (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt32to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
+	// cond: !shiftIsBounded(v)
+	// result: (SRA x (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
 	for {
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64SRA)
 		v0 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
 		v0.AuxInt = opToAuxInt(OpARM64LessThanU)
-		v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
-		v1.AddArg(y)
-		v2 := b.NewValue0(v.Pos, OpConst64, y.Type)
-		v2.AuxInt = int64ToAuxInt(63)
-		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
-		v3.AuxInt = int64ToAuxInt(64)
-		v3.AddArg(v1)
-		v0.AddArg3(v1, v2, v3)
+		v1 := b.NewValue0(v.Pos, OpConst64, y.Type)
+		v1.AuxInt = int64ToAuxInt(63)
+		v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
+		v2.AuxInt = int64ToAuxInt(64)
+		v3 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
+		v3.AddArg(y)
+		v2.AddArg(v3)
+		v0.AddArg3(y, v1, v2)
 		v.AddArg2(x, v0)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpRsh64x64(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
+	// match: (Rsh64x64 <t> x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRA <t> x y)
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SRA)
+		v.Type = t
+		v.AddArg2(x, y)
+		return true
+	}
 	// match: (Rsh64x64 x y)
+	// cond: !shiftIsBounded(v)
 	// result: (SRA x (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
 	for {
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64SRA)
 		v0 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
 		v0.AuxInt = opToAuxInt(OpARM64LessThanU)
@@ -26529,31 +27708,52 @@
 		v.AddArg2(x, v0)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpRsh64x8(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
+	// match: (Rsh64x8 <t> x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRA <t> x y)
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SRA)
+		v.Type = t
+		v.AddArg2(x, y)
+		return true
+	}
 	// match: (Rsh64x8 x y)
-	// result: (SRA x (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt8to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64 y))))
+	// cond: !shiftIsBounded(v)
+	// result: (SRA x (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64 y))))
 	for {
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64SRA)
 		v0 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
 		v0.AuxInt = opToAuxInt(OpARM64LessThanU)
-		v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
-		v1.AddArg(y)
-		v2 := b.NewValue0(v.Pos, OpConst64, y.Type)
-		v2.AuxInt = int64ToAuxInt(63)
-		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
-		v3.AuxInt = int64ToAuxInt(64)
-		v3.AddArg(v1)
-		v0.AddArg3(v1, v2, v3)
+		v1 := b.NewValue0(v.Pos, OpConst64, y.Type)
+		v1.AuxInt = int64ToAuxInt(63)
+		v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
+		v2.AuxInt = int64ToAuxInt(64)
+		v3 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
+		v3.AddArg(y)
+		v2.AddArg(v3)
+		v0.AddArg3(y, v1, v2)
 		v.AddArg2(x, v0)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpRsh8Ux16(v *Value) bool {
 	v_1 := v.Args[1]
@@ -26561,27 +27761,49 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh8Ux16 <t> x y)
-	// result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt8to64 x) (ZeroExt16to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+	// cond: shiftIsBounded(v)
+	// result: (SRL <t> (ZeroExt8to64 x) y)
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SRL)
+		v.Type = t
+		v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
+	// match: (Rsh8Ux16 <t> x y)
+	// cond: !shiftIsBounded(v)
+	// result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt8to64 x) y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt16to64 y)))
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64CSEL)
 		v.AuxInt = opToAuxInt(OpARM64LessThanU)
 		v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
 		v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
 		v1.AddArg(x)
-		v2 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
-		v2.AddArg(y)
-		v0.AddArg2(v1, v2)
-		v3 := b.NewValue0(v.Pos, OpConst64, t)
-		v3.AuxInt = int64ToAuxInt(0)
-		v4 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
-		v4.AuxInt = int64ToAuxInt(64)
-		v4.AddArg(v2)
-		v.AddArg3(v0, v3, v4)
+		v0.AddArg2(v1, y)
+		v2 := b.NewValue0(v.Pos, OpConst64, t)
+		v2.AuxInt = int64ToAuxInt(0)
+		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
+		v3.AuxInt = int64ToAuxInt(64)
+		v4 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
+		v4.AddArg(y)
+		v3.AddArg(v4)
+		v.AddArg3(v0, v2, v3)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpRsh8Ux32(v *Value) bool {
 	v_1 := v.Args[1]
@@ -26589,27 +27811,49 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh8Ux32 <t> x y)
-	// result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt8to64 x) (ZeroExt32to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+	// cond: shiftIsBounded(v)
+	// result: (SRL <t> (ZeroExt8to64 x) y)
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SRL)
+		v.Type = t
+		v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
+	// match: (Rsh8Ux32 <t> x y)
+	// cond: !shiftIsBounded(v)
+	// result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt8to64 x) y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt32to64 y)))
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64CSEL)
 		v.AuxInt = opToAuxInt(OpARM64LessThanU)
 		v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
 		v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
 		v1.AddArg(x)
-		v2 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
-		v2.AddArg(y)
-		v0.AddArg2(v1, v2)
-		v3 := b.NewValue0(v.Pos, OpConst64, t)
-		v3.AuxInt = int64ToAuxInt(0)
-		v4 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
-		v4.AuxInt = int64ToAuxInt(64)
-		v4.AddArg(v2)
-		v.AddArg3(v0, v3, v4)
+		v0.AddArg2(v1, y)
+		v2 := b.NewValue0(v.Pos, OpConst64, t)
+		v2.AuxInt = int64ToAuxInt(0)
+		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
+		v3.AuxInt = int64ToAuxInt(64)
+		v4 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
+		v4.AddArg(y)
+		v3.AddArg(v4)
+		v.AddArg3(v0, v2, v3)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpRsh8Ux64(v *Value) bool {
 	v_1 := v.Args[1]
@@ -26617,11 +27861,32 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh8Ux64 <t> x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRL <t> (ZeroExt8to64 x) y)
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SRL)
+		v.Type = t
+		v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
+	// match: (Rsh8Ux64 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt8to64 x) y) (Const64 <t> [0]) (CMPconst [64] y))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64CSEL)
 		v.AuxInt = opToAuxInt(OpARM64LessThanU)
 		v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
@@ -26636,6 +27901,7 @@
 		v.AddArg3(v0, v2, v3)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpRsh8Ux8(v *Value) bool {
 	v_1 := v.Args[1]
@@ -26643,92 +27909,179 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh8Ux8 <t> x y)
-	// result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt8to64 x) (ZeroExt8to64 y)) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
+	// cond: shiftIsBounded(v)
+	// result: (SRL <t> (ZeroExt8to64 x) y)
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SRL)
+		v.Type = t
+		v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
+	// match: (Rsh8Ux8 <t> x y)
+	// cond: !shiftIsBounded(v)
+	// result: (CSEL [OpARM64LessThanU] (SRL <t> (ZeroExt8to64 x) y) (Const64 <t> [0]) (CMPconst [64] (ZeroExt8to64 y)))
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64CSEL)
 		v.AuxInt = opToAuxInt(OpARM64LessThanU)
 		v0 := b.NewValue0(v.Pos, OpARM64SRL, t)
 		v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
 		v1.AddArg(x)
-		v2 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
-		v2.AddArg(y)
-		v0.AddArg2(v1, v2)
-		v3 := b.NewValue0(v.Pos, OpConst64, t)
-		v3.AuxInt = int64ToAuxInt(0)
-		v4 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
-		v4.AuxInt = int64ToAuxInt(64)
-		v4.AddArg(v2)
-		v.AddArg3(v0, v3, v4)
+		v0.AddArg2(v1, y)
+		v2 := b.NewValue0(v.Pos, OpConst64, t)
+		v2.AuxInt = int64ToAuxInt(0)
+		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
+		v3.AuxInt = int64ToAuxInt(64)
+		v4 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
+		v4.AddArg(y)
+		v3.AddArg(v4)
+		v.AddArg3(v0, v2, v3)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpRsh8x16(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
+	// match: (Rsh8x16 <t> x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRA <t> (SignExt8to64 x) y)
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SRA)
+		v.Type = t
+		v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
 	// match: (Rsh8x16 x y)
-	// result: (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt16to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
+	// cond: !shiftIsBounded(v)
+	// result: (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt16to64 y))))
 	for {
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64SRA)
 		v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64)
 		v0.AddArg(x)
 		v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
 		v1.AuxInt = opToAuxInt(OpARM64LessThanU)
-		v2 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
-		v2.AddArg(y)
-		v3 := b.NewValue0(v.Pos, OpConst64, y.Type)
-		v3.AuxInt = int64ToAuxInt(63)
-		v4 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
-		v4.AuxInt = int64ToAuxInt(64)
-		v4.AddArg(v2)
-		v1.AddArg3(v2, v3, v4)
+		v2 := b.NewValue0(v.Pos, OpConst64, y.Type)
+		v2.AuxInt = int64ToAuxInt(63)
+		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
+		v3.AuxInt = int64ToAuxInt(64)
+		v4 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
+		v4.AddArg(y)
+		v3.AddArg(v4)
+		v1.AddArg3(y, v2, v3)
 		v.AddArg2(v0, v1)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpRsh8x32(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
+	// match: (Rsh8x32 <t> x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRA <t> (SignExt8to64 x) y)
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SRA)
+		v.Type = t
+		v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
 	// match: (Rsh8x32 x y)
-	// result: (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt32to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
+	// cond: !shiftIsBounded(v)
+	// result: (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt32to64 y))))
 	for {
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64SRA)
 		v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64)
 		v0.AddArg(x)
 		v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
 		v1.AuxInt = opToAuxInt(OpARM64LessThanU)
-		v2 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
-		v2.AddArg(y)
-		v3 := b.NewValue0(v.Pos, OpConst64, y.Type)
-		v3.AuxInt = int64ToAuxInt(63)
-		v4 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
-		v4.AuxInt = int64ToAuxInt(64)
-		v4.AddArg(v2)
-		v1.AddArg3(v2, v3, v4)
+		v2 := b.NewValue0(v.Pos, OpConst64, y.Type)
+		v2.AuxInt = int64ToAuxInt(63)
+		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
+		v3.AuxInt = int64ToAuxInt(64)
+		v4 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
+		v4.AddArg(y)
+		v3.AddArg(v4)
+		v1.AddArg3(y, v2, v3)
 		v.AddArg2(v0, v1)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpRsh8x64(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
+	// match: (Rsh8x64 <t> x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRA <t> (SignExt8to64 x) y)
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SRA)
+		v.Type = t
+		v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
 	// match: (Rsh8x64 x y)
+	// cond: !shiftIsBounded(v)
 	// result: (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y)))
 	for {
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64SRA)
 		v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64)
 		v0.AddArg(x)
@@ -26743,38 +28096,73 @@
 		v.AddArg2(v0, v1)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpRsh8x8(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
+	// match: (Rsh8x8 <t> x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRA <t> (SignExt8to64 x) y)
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpARM64SRA)
+		v.Type = t
+		v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
 	// match: (Rsh8x8 x y)
-	// result: (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] <y.Type> (ZeroExt8to64 y) (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64 y))))
+	// cond: !shiftIsBounded(v)
+	// result: (SRA (SignExt8to64 x) (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] (ZeroExt8to64 y))))
 	for {
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpARM64SRA)
 		v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64)
 		v0.AddArg(x)
 		v1 := b.NewValue0(v.Pos, OpARM64CSEL, y.Type)
 		v1.AuxInt = opToAuxInt(OpARM64LessThanU)
-		v2 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
-		v2.AddArg(y)
-		v3 := b.NewValue0(v.Pos, OpConst64, y.Type)
-		v3.AuxInt = int64ToAuxInt(63)
-		v4 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
-		v4.AuxInt = int64ToAuxInt(64)
-		v4.AddArg(v2)
-		v1.AddArg3(v2, v3, v4)
+		v2 := b.NewValue0(v.Pos, OpConst64, y.Type)
+		v2.AuxInt = int64ToAuxInt(63)
+		v3 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
+		v3.AuxInt = int64ToAuxInt(64)
+		v4 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
+		v4.AddArg(y)
+		v3.AddArg(v4)
+		v1.AddArg3(y, v2, v3)
 		v.AddArg2(v0, v1)
 		return true
 	}
+	return false
 }
 func rewriteValueARM64_OpSelect0(v *Value) bool {
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
+	// match: (Select0 (Mul64uhilo x y))
+	// result: (UMULH x y)
+	for {
+		if v_0.Op != OpMul64uhilo {
+			break
+		}
+		y := v_0.Args[1]
+		x := v_0.Args[0]
+		v.reset(OpARM64UMULH)
+		v.AddArg2(x, y)
+		return true
+	}
 	// match: (Select0 (Add64carry x y c))
 	// result: (Select0 <typ.UInt64> (ADCSflags x y (Select1 <types.TypeFlags> (ADDSconstflags [-1] c))))
 	for {
@@ -26816,12 +28204,36 @@
 		v.AddArg(v0)
 		return true
 	}
+	// match: (Select0 (Mul64uover x y))
+	// result: (MUL x y)
+	for {
+		if v_0.Op != OpMul64uover {
+			break
+		}
+		y := v_0.Args[1]
+		x := v_0.Args[0]
+		v.reset(OpARM64MUL)
+		v.AddArg2(x, y)
+		return true
+	}
 	return false
 }
 func rewriteValueARM64_OpSelect1(v *Value) bool {
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
+	// match: (Select1 (Mul64uhilo x y))
+	// result: (MUL x y)
+	for {
+		if v_0.Op != OpMul64uhilo {
+			break
+		}
+		y := v_0.Args[1]
+		x := v_0.Args[0]
+		v.reset(OpARM64MUL)
+		v.AddArg2(x, y)
+		return true
+	}
 	// match: (Select1 (Add64carry x y c))
 	// result: (ADCzerocarry <typ.UInt64> (Select1 <types.TypeFlags> (ADCSflags x y (Select1 <types.TypeFlags> (ADDSconstflags [-1] c)))))
 	for {
@@ -26869,6 +28281,23 @@
 		v.AddArg(v0)
 		return true
 	}
+	// match: (Select1 (Mul64uover x y))
+	// result: (NotEqual (CMPconst (UMULH <typ.UInt64> x y) [0]))
+	for {
+		if v_0.Op != OpMul64uover {
+			break
+		}
+		y := v_0.Args[1]
+		x := v_0.Args[0]
+		v.reset(OpARM64NotEqual)
+		v0 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags)
+		v0.AuxInt = int64ToAuxInt(0)
+		v1 := b.NewValue0(v.Pos, OpARM64UMULH, typ.UInt64)
+		v1.AddArg2(x, y)
+		v0.AddArg(v1)
+		v.AddArg(v0)
+		return true
+	}
 	return false
 }
 func rewriteValueARM64_OpSelectN(v *Value) bool {
@@ -27117,20 +28546,6 @@
 		v.AddArg3(ptr, v0, mem)
 		return true
 	}
-	// match: (Zero [8] ptr mem)
-	// result: (MOVDstore ptr (MOVDconst [0]) mem)
-	for {
-		if auxIntToInt64(v.AuxInt) != 8 {
-			break
-		}
-		ptr := v_0
-		mem := v_1
-		v.reset(OpARM64MOVDstore)
-		v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
-		v0.AuxInt = int64ToAuxInt(0)
-		v.AddArg3(ptr, v0, mem)
-		return true
-	}
 	// match: (Zero [3] ptr mem)
 	// result: (MOVBstore [2] ptr (MOVDconst [0]) (MOVHstore ptr (MOVDconst [0]) mem))
 	for {
@@ -27183,25 +28598,36 @@
 		return true
 	}
 	// match: (Zero [7] ptr mem)
-	// result: (MOVBstore [6] ptr (MOVDconst [0]) (MOVHstore [4] ptr (MOVDconst [0]) (MOVWstore ptr (MOVDconst [0]) mem)))
+	// result: (MOVWstore [3] ptr (MOVDconst [0]) (MOVWstore ptr (MOVDconst [0]) mem))
 	for {
 		if auxIntToInt64(v.AuxInt) != 7 {
 			break
 		}
 		ptr := v_0
 		mem := v_1
-		v.reset(OpARM64MOVBstore)
-		v.AuxInt = int32ToAuxInt(6)
+		v.reset(OpARM64MOVWstore)
+		v.AuxInt = int32ToAuxInt(3)
 		v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
 		v0.AuxInt = int64ToAuxInt(0)
-		v1 := b.NewValue0(v.Pos, OpARM64MOVHstore, types.TypeMem)
-		v1.AuxInt = int32ToAuxInt(4)
-		v2 := b.NewValue0(v.Pos, OpARM64MOVWstore, types.TypeMem)
-		v2.AddArg3(ptr, v0, mem)
-		v1.AddArg3(ptr, v0, v2)
+		v1 := b.NewValue0(v.Pos, OpARM64MOVWstore, types.TypeMem)
+		v1.AddArg3(ptr, v0, mem)
 		v.AddArg3(ptr, v0, v1)
 		return true
 	}
+	// match: (Zero [8] ptr mem)
+	// result: (MOVDstore ptr (MOVDconst [0]) mem)
+	for {
+		if auxIntToInt64(v.AuxInt) != 8 {
+			break
+		}
+		ptr := v_0
+		mem := v_1
+		v.reset(OpARM64MOVDstore)
+		v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v0.AuxInt = int64ToAuxInt(0)
+		v.AddArg3(ptr, v0, mem)
+		return true
+	}
 	// match: (Zero [9] ptr mem)
 	// result: (MOVBstore [8] ptr (MOVDconst [0]) (MOVDstore ptr (MOVDconst [0]) mem))
 	for {
@@ -27237,22 +28663,19 @@
 		return true
 	}
 	// match: (Zero [11] ptr mem)
-	// result: (MOVBstore [10] ptr (MOVDconst [0]) (MOVHstore [8] ptr (MOVDconst [0]) (MOVDstore ptr (MOVDconst [0]) mem)))
+	// result: (MOVDstore [3] ptr (MOVDconst [0]) (MOVDstore ptr (MOVDconst [0]) mem))
 	for {
 		if auxIntToInt64(v.AuxInt) != 11 {
 			break
 		}
 		ptr := v_0
 		mem := v_1
-		v.reset(OpARM64MOVBstore)
-		v.AuxInt = int32ToAuxInt(10)
+		v.reset(OpARM64MOVDstore)
+		v.AuxInt = int32ToAuxInt(3)
 		v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
 		v0.AuxInt = int64ToAuxInt(0)
-		v1 := b.NewValue0(v.Pos, OpARM64MOVHstore, types.TypeMem)
-		v1.AuxInt = int32ToAuxInt(8)
-		v2 := b.NewValue0(v.Pos, OpARM64MOVDstore, types.TypeMem)
-		v2.AddArg3(ptr, v0, mem)
-		v1.AddArg3(ptr, v0, v2)
+		v1 := b.NewValue0(v.Pos, OpARM64MOVDstore, types.TypeMem)
+		v1.AddArg3(ptr, v0, mem)
 		v.AddArg3(ptr, v0, v1)
 		return true
 	}
@@ -27274,65 +28697,53 @@
 		return true
 	}
 	// match: (Zero [13] ptr mem)
-	// result: (MOVBstore [12] ptr (MOVDconst [0]) (MOVWstore [8] ptr (MOVDconst [0]) (MOVDstore ptr (MOVDconst [0]) mem)))
+	// result: (MOVDstore [5] ptr (MOVDconst [0]) (MOVDstore ptr (MOVDconst [0]) mem))
 	for {
 		if auxIntToInt64(v.AuxInt) != 13 {
 			break
 		}
 		ptr := v_0
 		mem := v_1
-		v.reset(OpARM64MOVBstore)
-		v.AuxInt = int32ToAuxInt(12)
+		v.reset(OpARM64MOVDstore)
+		v.AuxInt = int32ToAuxInt(5)
 		v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
 		v0.AuxInt = int64ToAuxInt(0)
-		v1 := b.NewValue0(v.Pos, OpARM64MOVWstore, types.TypeMem)
-		v1.AuxInt = int32ToAuxInt(8)
-		v2 := b.NewValue0(v.Pos, OpARM64MOVDstore, types.TypeMem)
-		v2.AddArg3(ptr, v0, mem)
-		v1.AddArg3(ptr, v0, v2)
+		v1 := b.NewValue0(v.Pos, OpARM64MOVDstore, types.TypeMem)
+		v1.AddArg3(ptr, v0, mem)
 		v.AddArg3(ptr, v0, v1)
 		return true
 	}
 	// match: (Zero [14] ptr mem)
-	// result: (MOVHstore [12] ptr (MOVDconst [0]) (MOVWstore [8] ptr (MOVDconst [0]) (MOVDstore ptr (MOVDconst [0]) mem)))
+	// result: (MOVDstore [6] ptr (MOVDconst [0]) (MOVDstore ptr (MOVDconst [0]) mem))
 	for {
 		if auxIntToInt64(v.AuxInt) != 14 {
 			break
 		}
 		ptr := v_0
 		mem := v_1
-		v.reset(OpARM64MOVHstore)
-		v.AuxInt = int32ToAuxInt(12)
+		v.reset(OpARM64MOVDstore)
+		v.AuxInt = int32ToAuxInt(6)
 		v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
 		v0.AuxInt = int64ToAuxInt(0)
-		v1 := b.NewValue0(v.Pos, OpARM64MOVWstore, types.TypeMem)
-		v1.AuxInt = int32ToAuxInt(8)
-		v2 := b.NewValue0(v.Pos, OpARM64MOVDstore, types.TypeMem)
-		v2.AddArg3(ptr, v0, mem)
-		v1.AddArg3(ptr, v0, v2)
+		v1 := b.NewValue0(v.Pos, OpARM64MOVDstore, types.TypeMem)
+		v1.AddArg3(ptr, v0, mem)
 		v.AddArg3(ptr, v0, v1)
 		return true
 	}
 	// match: (Zero [15] ptr mem)
-	// result: (MOVBstore [14] ptr (MOVDconst [0]) (MOVHstore [12] ptr (MOVDconst [0]) (MOVWstore [8] ptr (MOVDconst [0]) (MOVDstore ptr (MOVDconst [0]) mem))))
+	// result: (MOVDstore [7] ptr (MOVDconst [0]) (MOVDstore ptr (MOVDconst [0]) mem))
 	for {
 		if auxIntToInt64(v.AuxInt) != 15 {
 			break
 		}
 		ptr := v_0
 		mem := v_1
-		v.reset(OpARM64MOVBstore)
-		v.AuxInt = int32ToAuxInt(14)
+		v.reset(OpARM64MOVDstore)
+		v.AuxInt = int32ToAuxInt(7)
 		v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
 		v0.AuxInt = int64ToAuxInt(0)
-		v1 := b.NewValue0(v.Pos, OpARM64MOVHstore, types.TypeMem)
-		v1.AuxInt = int32ToAuxInt(12)
-		v2 := b.NewValue0(v.Pos, OpARM64MOVWstore, types.TypeMem)
-		v2.AuxInt = int32ToAuxInt(8)
-		v3 := b.NewValue0(v.Pos, OpARM64MOVDstore, types.TypeMem)
-		v3.AddArg3(ptr, v0, mem)
-		v2.AddArg3(ptr, v0, v3)
-		v1.AddArg3(ptr, v0, v2)
+		v1 := b.NewValue0(v.Pos, OpARM64MOVDstore, types.TypeMem)
+		v1.AddArg3(ptr, v0, mem)
 		v.AddArg3(ptr, v0, v1)
 		return true
 	}
@@ -27494,29 +28905,6 @@
 	typ := &b.Func.Config.Types
 	switch b.Kind {
 	case BlockARM64EQ:
-		// match: (EQ (CMPWconst [0] x:(ANDconst [c] y)) yes no)
-		// cond: x.Uses == 1
-		// result: (EQ (TSTWconst [int32(c)] y) yes no)
-		for b.Controls[0].Op == OpARM64CMPWconst {
-			v_0 := b.Controls[0]
-			if auxIntToInt32(v_0.AuxInt) != 0 {
-				break
-			}
-			x := v_0.Args[0]
-			if x.Op != OpARM64ANDconst {
-				break
-			}
-			c := auxIntToInt64(x.AuxInt)
-			y := x.Args[0]
-			if !(x.Uses == 1) {
-				break
-			}
-			v0 := b.NewValue0(v_0.Pos, OpARM64TSTWconst, types.TypeFlags)
-			v0.AuxInt = int32ToAuxInt(int32(c))
-			v0.AddArg(y)
-			b.resetWithControl(BlockARM64EQ, v0)
-			return true
-		}
 		// match: (EQ (CMPconst [0] z:(AND x y)) yes no)
 		// cond: z.Uses == 1
 		// result: (EQ (TST x y) yes no)
@@ -27545,6 +28933,29 @@
 			}
 			break
 		}
+		// match: (EQ (CMPconst [0] x:(ANDconst [c] y)) yes no)
+		// cond: x.Uses == 1
+		// result: (EQ (TSTconst [c] y) yes no)
+		for b.Controls[0].Op == OpARM64CMPconst {
+			v_0 := b.Controls[0]
+			if auxIntToInt64(v_0.AuxInt) != 0 {
+				break
+			}
+			x := v_0.Args[0]
+			if x.Op != OpARM64ANDconst {
+				break
+			}
+			c := auxIntToInt64(x.AuxInt)
+			y := x.Args[0]
+			if !(x.Uses == 1) {
+				break
+			}
+			v0 := b.NewValue0(v_0.Pos, OpARM64TSTconst, types.TypeFlags)
+			v0.AuxInt = int64ToAuxInt(c)
+			v0.AddArg(y)
+			b.resetWithControl(BlockARM64EQ, v0)
+			return true
+		}
 		// match: (EQ (CMPWconst [0] z:(AND x y)) yes no)
 		// cond: z.Uses == 1
 		// result: (EQ (TSTW x y) yes no)
@@ -27573,12 +28984,12 @@
 			}
 			break
 		}
-		// match: (EQ (CMPconst [0] x:(ANDconst [c] y)) yes no)
+		// match: (EQ (CMPWconst [0] x:(ANDconst [c] y)) yes no)
 		// cond: x.Uses == 1
-		// result: (EQ (TSTconst [c] y) yes no)
-		for b.Controls[0].Op == OpARM64CMPconst {
+		// result: (EQ (TSTWconst [int32(c)] y) yes no)
+		for b.Controls[0].Op == OpARM64CMPWconst {
 			v_0 := b.Controls[0]
-			if auxIntToInt64(v_0.AuxInt) != 0 {
+			if auxIntToInt32(v_0.AuxInt) != 0 {
 				break
 			}
 			x := v_0.Args[0]
@@ -27590,8 +29001,8 @@
 			if !(x.Uses == 1) {
 				break
 			}
-			v0 := b.NewValue0(v_0.Pos, OpARM64TSTconst, types.TypeFlags)
-			v0.AuxInt = int64ToAuxInt(c)
+			v0 := b.NewValue0(v_0.Pos, OpARM64TSTWconst, types.TypeFlags)
+			v0.AuxInt = int32ToAuxInt(int32(c))
 			v0.AddArg(y)
 			b.resetWithControl(BlockARM64EQ, v0)
 			return true
@@ -27958,29 +29369,6 @@
 			return true
 		}
 	case BlockARM64GE:
-		// match: (GE (CMPWconst [0] x:(ANDconst [c] y)) yes no)
-		// cond: x.Uses == 1
-		// result: (GE (TSTWconst [int32(c)] y) yes no)
-		for b.Controls[0].Op == OpARM64CMPWconst {
-			v_0 := b.Controls[0]
-			if auxIntToInt32(v_0.AuxInt) != 0 {
-				break
-			}
-			x := v_0.Args[0]
-			if x.Op != OpARM64ANDconst {
-				break
-			}
-			c := auxIntToInt64(x.AuxInt)
-			y := x.Args[0]
-			if !(x.Uses == 1) {
-				break
-			}
-			v0 := b.NewValue0(v_0.Pos, OpARM64TSTWconst, types.TypeFlags)
-			v0.AuxInt = int32ToAuxInt(int32(c))
-			v0.AddArg(y)
-			b.resetWithControl(BlockARM64GE, v0)
-			return true
-		}
 		// match: (GE (CMPconst [0] z:(AND x y)) yes no)
 		// cond: z.Uses == 1
 		// result: (GE (TST x y) yes no)
@@ -28009,6 +29397,29 @@
 			}
 			break
 		}
+		// match: (GE (CMPconst [0] x:(ANDconst [c] y)) yes no)
+		// cond: x.Uses == 1
+		// result: (GE (TSTconst [c] y) yes no)
+		for b.Controls[0].Op == OpARM64CMPconst {
+			v_0 := b.Controls[0]
+			if auxIntToInt64(v_0.AuxInt) != 0 {
+				break
+			}
+			x := v_0.Args[0]
+			if x.Op != OpARM64ANDconst {
+				break
+			}
+			c := auxIntToInt64(x.AuxInt)
+			y := x.Args[0]
+			if !(x.Uses == 1) {
+				break
+			}
+			v0 := b.NewValue0(v_0.Pos, OpARM64TSTconst, types.TypeFlags)
+			v0.AuxInt = int64ToAuxInt(c)
+			v0.AddArg(y)
+			b.resetWithControl(BlockARM64GE, v0)
+			return true
+		}
 		// match: (GE (CMPWconst [0] z:(AND x y)) yes no)
 		// cond: z.Uses == 1
 		// result: (GE (TSTW x y) yes no)
@@ -28037,12 +29448,12 @@
 			}
 			break
 		}
-		// match: (GE (CMPconst [0] x:(ANDconst [c] y)) yes no)
+		// match: (GE (CMPWconst [0] x:(ANDconst [c] y)) yes no)
 		// cond: x.Uses == 1
-		// result: (GE (TSTconst [c] y) yes no)
-		for b.Controls[0].Op == OpARM64CMPconst {
+		// result: (GE (TSTWconst [int32(c)] y) yes no)
+		for b.Controls[0].Op == OpARM64CMPWconst {
 			v_0 := b.Controls[0]
-			if auxIntToInt64(v_0.AuxInt) != 0 {
+			if auxIntToInt32(v_0.AuxInt) != 0 {
 				break
 			}
 			x := v_0.Args[0]
@@ -28054,8 +29465,8 @@
 			if !(x.Uses == 1) {
 				break
 			}
-			v0 := b.NewValue0(v_0.Pos, OpARM64TSTconst, types.TypeFlags)
-			v0.AuxInt = int64ToAuxInt(c)
+			v0 := b.NewValue0(v_0.Pos, OpARM64TSTWconst, types.TypeFlags)
+			v0.AuxInt = int32ToAuxInt(int32(c))
 			v0.AddArg(y)
 			b.resetWithControl(BlockARM64GE, v0)
 			return true
@@ -28354,29 +29765,6 @@
 			return true
 		}
 	case BlockARM64GT:
-		// match: (GT (CMPWconst [0] x:(ANDconst [c] y)) yes no)
-		// cond: x.Uses == 1
-		// result: (GT (TSTWconst [int32(c)] y) yes no)
-		for b.Controls[0].Op == OpARM64CMPWconst {
-			v_0 := b.Controls[0]
-			if auxIntToInt32(v_0.AuxInt) != 0 {
-				break
-			}
-			x := v_0.Args[0]
-			if x.Op != OpARM64ANDconst {
-				break
-			}
-			c := auxIntToInt64(x.AuxInt)
-			y := x.Args[0]
-			if !(x.Uses == 1) {
-				break
-			}
-			v0 := b.NewValue0(v_0.Pos, OpARM64TSTWconst, types.TypeFlags)
-			v0.AuxInt = int32ToAuxInt(int32(c))
-			v0.AddArg(y)
-			b.resetWithControl(BlockARM64GT, v0)
-			return true
-		}
 		// match: (GT (CMPconst [0] z:(AND x y)) yes no)
 		// cond: z.Uses == 1
 		// result: (GT (TST x y) yes no)
@@ -28405,6 +29793,29 @@
 			}
 			break
 		}
+		// match: (GT (CMPconst [0] x:(ANDconst [c] y)) yes no)
+		// cond: x.Uses == 1
+		// result: (GT (TSTconst [c] y) yes no)
+		for b.Controls[0].Op == OpARM64CMPconst {
+			v_0 := b.Controls[0]
+			if auxIntToInt64(v_0.AuxInt) != 0 {
+				break
+			}
+			x := v_0.Args[0]
+			if x.Op != OpARM64ANDconst {
+				break
+			}
+			c := auxIntToInt64(x.AuxInt)
+			y := x.Args[0]
+			if !(x.Uses == 1) {
+				break
+			}
+			v0 := b.NewValue0(v_0.Pos, OpARM64TSTconst, types.TypeFlags)
+			v0.AuxInt = int64ToAuxInt(c)
+			v0.AddArg(y)
+			b.resetWithControl(BlockARM64GT, v0)
+			return true
+		}
 		// match: (GT (CMPWconst [0] z:(AND x y)) yes no)
 		// cond: z.Uses == 1
 		// result: (GT (TSTW x y) yes no)
@@ -28433,12 +29844,12 @@
 			}
 			break
 		}
-		// match: (GT (CMPconst [0] x:(ANDconst [c] y)) yes no)
+		// match: (GT (CMPWconst [0] x:(ANDconst [c] y)) yes no)
 		// cond: x.Uses == 1
-		// result: (GT (TSTconst [c] y) yes no)
-		for b.Controls[0].Op == OpARM64CMPconst {
+		// result: (GT (TSTWconst [int32(c)] y) yes no)
+		for b.Controls[0].Op == OpARM64CMPWconst {
 			v_0 := b.Controls[0]
-			if auxIntToInt64(v_0.AuxInt) != 0 {
+			if auxIntToInt32(v_0.AuxInt) != 0 {
 				break
 			}
 			x := v_0.Args[0]
@@ -28450,8 +29861,8 @@
 			if !(x.Uses == 1) {
 				break
 			}
-			v0 := b.NewValue0(v_0.Pos, OpARM64TSTconst, types.TypeFlags)
-			v0.AuxInt = int64ToAuxInt(c)
+			v0 := b.NewValue0(v_0.Pos, OpARM64TSTWconst, types.TypeFlags)
+			v0.AuxInt = int32ToAuxInt(int32(c))
 			v0.AddArg(y)
 			b.resetWithControl(BlockARM64GT, v0)
 			return true
@@ -28860,29 +30271,6 @@
 			return true
 		}
 	case BlockARM64LE:
-		// match: (LE (CMPWconst [0] x:(ANDconst [c] y)) yes no)
-		// cond: x.Uses == 1
-		// result: (LE (TSTWconst [int32(c)] y) yes no)
-		for b.Controls[0].Op == OpARM64CMPWconst {
-			v_0 := b.Controls[0]
-			if auxIntToInt32(v_0.AuxInt) != 0 {
-				break
-			}
-			x := v_0.Args[0]
-			if x.Op != OpARM64ANDconst {
-				break
-			}
-			c := auxIntToInt64(x.AuxInt)
-			y := x.Args[0]
-			if !(x.Uses == 1) {
-				break
-			}
-			v0 := b.NewValue0(v_0.Pos, OpARM64TSTWconst, types.TypeFlags)
-			v0.AuxInt = int32ToAuxInt(int32(c))
-			v0.AddArg(y)
-			b.resetWithControl(BlockARM64LE, v0)
-			return true
-		}
 		// match: (LE (CMPconst [0] z:(AND x y)) yes no)
 		// cond: z.Uses == 1
 		// result: (LE (TST x y) yes no)
@@ -28911,6 +30299,29 @@
 			}
 			break
 		}
+		// match: (LE (CMPconst [0] x:(ANDconst [c] y)) yes no)
+		// cond: x.Uses == 1
+		// result: (LE (TSTconst [c] y) yes no)
+		for b.Controls[0].Op == OpARM64CMPconst {
+			v_0 := b.Controls[0]
+			if auxIntToInt64(v_0.AuxInt) != 0 {
+				break
+			}
+			x := v_0.Args[0]
+			if x.Op != OpARM64ANDconst {
+				break
+			}
+			c := auxIntToInt64(x.AuxInt)
+			y := x.Args[0]
+			if !(x.Uses == 1) {
+				break
+			}
+			v0 := b.NewValue0(v_0.Pos, OpARM64TSTconst, types.TypeFlags)
+			v0.AuxInt = int64ToAuxInt(c)
+			v0.AddArg(y)
+			b.resetWithControl(BlockARM64LE, v0)
+			return true
+		}
 		// match: (LE (CMPWconst [0] z:(AND x y)) yes no)
 		// cond: z.Uses == 1
 		// result: (LE (TSTW x y) yes no)
@@ -28939,12 +30350,12 @@
 			}
 			break
 		}
-		// match: (LE (CMPconst [0] x:(ANDconst [c] y)) yes no)
+		// match: (LE (CMPWconst [0] x:(ANDconst [c] y)) yes no)
 		// cond: x.Uses == 1
-		// result: (LE (TSTconst [c] y) yes no)
-		for b.Controls[0].Op == OpARM64CMPconst {
+		// result: (LE (TSTWconst [int32(c)] y) yes no)
+		for b.Controls[0].Op == OpARM64CMPWconst {
 			v_0 := b.Controls[0]
-			if auxIntToInt64(v_0.AuxInt) != 0 {
+			if auxIntToInt32(v_0.AuxInt) != 0 {
 				break
 			}
 			x := v_0.Args[0]
@@ -28956,8 +30367,8 @@
 			if !(x.Uses == 1) {
 				break
 			}
-			v0 := b.NewValue0(v_0.Pos, OpARM64TSTconst, types.TypeFlags)
-			v0.AuxInt = int64ToAuxInt(c)
+			v0 := b.NewValue0(v_0.Pos, OpARM64TSTWconst, types.TypeFlags)
+			v0.AuxInt = int32ToAuxInt(int32(c))
 			v0.AddArg(y)
 			b.resetWithControl(BlockARM64LE, v0)
 			return true
@@ -29232,29 +30643,6 @@
 			return true
 		}
 	case BlockARM64LT:
-		// match: (LT (CMPWconst [0] x:(ANDconst [c] y)) yes no)
-		// cond: x.Uses == 1
-		// result: (LT (TSTWconst [int32(c)] y) yes no)
-		for b.Controls[0].Op == OpARM64CMPWconst {
-			v_0 := b.Controls[0]
-			if auxIntToInt32(v_0.AuxInt) != 0 {
-				break
-			}
-			x := v_0.Args[0]
-			if x.Op != OpARM64ANDconst {
-				break
-			}
-			c := auxIntToInt64(x.AuxInt)
-			y := x.Args[0]
-			if !(x.Uses == 1) {
-				break
-			}
-			v0 := b.NewValue0(v_0.Pos, OpARM64TSTWconst, types.TypeFlags)
-			v0.AuxInt = int32ToAuxInt(int32(c))
-			v0.AddArg(y)
-			b.resetWithControl(BlockARM64LT, v0)
-			return true
-		}
 		// match: (LT (CMPconst [0] z:(AND x y)) yes no)
 		// cond: z.Uses == 1
 		// result: (LT (TST x y) yes no)
@@ -29283,6 +30671,29 @@
 			}
 			break
 		}
+		// match: (LT (CMPconst [0] x:(ANDconst [c] y)) yes no)
+		// cond: x.Uses == 1
+		// result: (LT (TSTconst [c] y) yes no)
+		for b.Controls[0].Op == OpARM64CMPconst {
+			v_0 := b.Controls[0]
+			if auxIntToInt64(v_0.AuxInt) != 0 {
+				break
+			}
+			x := v_0.Args[0]
+			if x.Op != OpARM64ANDconst {
+				break
+			}
+			c := auxIntToInt64(x.AuxInt)
+			y := x.Args[0]
+			if !(x.Uses == 1) {
+				break
+			}
+			v0 := b.NewValue0(v_0.Pos, OpARM64TSTconst, types.TypeFlags)
+			v0.AuxInt = int64ToAuxInt(c)
+			v0.AddArg(y)
+			b.resetWithControl(BlockARM64LT, v0)
+			return true
+		}
 		// match: (LT (CMPWconst [0] z:(AND x y)) yes no)
 		// cond: z.Uses == 1
 		// result: (LT (TSTW x y) yes no)
@@ -29311,12 +30722,12 @@
 			}
 			break
 		}
-		// match: (LT (CMPconst [0] x:(ANDconst [c] y)) yes no)
+		// match: (LT (CMPWconst [0] x:(ANDconst [c] y)) yes no)
 		// cond: x.Uses == 1
-		// result: (LT (TSTconst [c] y) yes no)
-		for b.Controls[0].Op == OpARM64CMPconst {
+		// result: (LT (TSTWconst [int32(c)] y) yes no)
+		for b.Controls[0].Op == OpARM64CMPWconst {
 			v_0 := b.Controls[0]
-			if auxIntToInt64(v_0.AuxInt) != 0 {
+			if auxIntToInt32(v_0.AuxInt) != 0 {
 				break
 			}
 			x := v_0.Args[0]
@@ -29328,8 +30739,8 @@
 			if !(x.Uses == 1) {
 				break
 			}
-			v0 := b.NewValue0(v_0.Pos, OpARM64TSTconst, types.TypeFlags)
-			v0.AuxInt = int64ToAuxInt(c)
+			v0 := b.NewValue0(v_0.Pos, OpARM64TSTWconst, types.TypeFlags)
+			v0.AuxInt = int32ToAuxInt(int32(c))
 			v0.AddArg(y)
 			b.resetWithControl(BlockARM64LT, v0)
 			return true
@@ -29628,29 +31039,6 @@
 			return true
 		}
 	case BlockARM64NE:
-		// match: (NE (CMPWconst [0] x:(ANDconst [c] y)) yes no)
-		// cond: x.Uses == 1
-		// result: (NE (TSTWconst [int32(c)] y) yes no)
-		for b.Controls[0].Op == OpARM64CMPWconst {
-			v_0 := b.Controls[0]
-			if auxIntToInt32(v_0.AuxInt) != 0 {
-				break
-			}
-			x := v_0.Args[0]
-			if x.Op != OpARM64ANDconst {
-				break
-			}
-			c := auxIntToInt64(x.AuxInt)
-			y := x.Args[0]
-			if !(x.Uses == 1) {
-				break
-			}
-			v0 := b.NewValue0(v_0.Pos, OpARM64TSTWconst, types.TypeFlags)
-			v0.AuxInt = int32ToAuxInt(int32(c))
-			v0.AddArg(y)
-			b.resetWithControl(BlockARM64NE, v0)
-			return true
-		}
 		// match: (NE (CMPconst [0] z:(AND x y)) yes no)
 		// cond: z.Uses == 1
 		// result: (NE (TST x y) yes no)
@@ -29679,6 +31067,29 @@
 			}
 			break
 		}
+		// match: (NE (CMPconst [0] x:(ANDconst [c] y)) yes no)
+		// cond: x.Uses == 1
+		// result: (NE (TSTconst [c] y) yes no)
+		for b.Controls[0].Op == OpARM64CMPconst {
+			v_0 := b.Controls[0]
+			if auxIntToInt64(v_0.AuxInt) != 0 {
+				break
+			}
+			x := v_0.Args[0]
+			if x.Op != OpARM64ANDconst {
+				break
+			}
+			c := auxIntToInt64(x.AuxInt)
+			y := x.Args[0]
+			if !(x.Uses == 1) {
+				break
+			}
+			v0 := b.NewValue0(v_0.Pos, OpARM64TSTconst, types.TypeFlags)
+			v0.AuxInt = int64ToAuxInt(c)
+			v0.AddArg(y)
+			b.resetWithControl(BlockARM64NE, v0)
+			return true
+		}
 		// match: (NE (CMPWconst [0] z:(AND x y)) yes no)
 		// cond: z.Uses == 1
 		// result: (NE (TSTW x y) yes no)
@@ -29707,12 +31118,12 @@
 			}
 			break
 		}
-		// match: (NE (CMPconst [0] x:(ANDconst [c] y)) yes no)
+		// match: (NE (CMPWconst [0] x:(ANDconst [c] y)) yes no)
 		// cond: x.Uses == 1
-		// result: (NE (TSTconst [c] y) yes no)
-		for b.Controls[0].Op == OpARM64CMPconst {
+		// result: (NE (TSTWconst [int32(c)] y) yes no)
+		for b.Controls[0].Op == OpARM64CMPWconst {
 			v_0 := b.Controls[0]
-			if auxIntToInt64(v_0.AuxInt) != 0 {
+			if auxIntToInt32(v_0.AuxInt) != 0 {
 				break
 			}
 			x := v_0.Args[0]
@@ -29724,8 +31135,8 @@
 			if !(x.Uses == 1) {
 				break
 			}
-			v0 := b.NewValue0(v_0.Pos, OpARM64TSTconst, types.TypeFlags)
-			v0.AuxInt = int64ToAuxInt(c)
+			v0 := b.NewValue0(v_0.Pos, OpARM64TSTWconst, types.TypeFlags)
+			v0.AuxInt = int32ToAuxInt(int32(c))
 			v0.AddArg(y)
 			b.resetWithControl(BlockARM64NE, v0)
 			return true
diff --git a/src/cmd/compile/internal/ssa/rewriteARM64latelower.go b/src/cmd/compile/internal/ssa/rewriteARM64latelower.go
new file mode 100644
index 0000000..49e1548
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/rewriteARM64latelower.go
@@ -0,0 +1,289 @@
+// Code generated from _gen/ARM64latelower.rules; DO NOT EDIT.
+// generated with: cd _gen; go run .
+
+package ssa
+
+func rewriteValueARM64latelower(v *Value) bool {
+	switch v.Op {
+	case OpARM64ADDSconstflags:
+		return rewriteValueARM64latelower_OpARM64ADDSconstflags(v)
+	case OpARM64ADDconst:
+		return rewriteValueARM64latelower_OpARM64ADDconst(v)
+	case OpARM64ANDconst:
+		return rewriteValueARM64latelower_OpARM64ANDconst(v)
+	case OpARM64CMNWconst:
+		return rewriteValueARM64latelower_OpARM64CMNWconst(v)
+	case OpARM64CMNconst:
+		return rewriteValueARM64latelower_OpARM64CMNconst(v)
+	case OpARM64CMPWconst:
+		return rewriteValueARM64latelower_OpARM64CMPWconst(v)
+	case OpARM64CMPconst:
+		return rewriteValueARM64latelower_OpARM64CMPconst(v)
+	case OpARM64ORconst:
+		return rewriteValueARM64latelower_OpARM64ORconst(v)
+	case OpARM64SUBconst:
+		return rewriteValueARM64latelower_OpARM64SUBconst(v)
+	case OpARM64TSTWconst:
+		return rewriteValueARM64latelower_OpARM64TSTWconst(v)
+	case OpARM64TSTconst:
+		return rewriteValueARM64latelower_OpARM64TSTconst(v)
+	case OpARM64XORconst:
+		return rewriteValueARM64latelower_OpARM64XORconst(v)
+	}
+	return false
+}
+func rewriteValueARM64latelower_OpARM64ADDSconstflags(v *Value) bool {
+	v_0 := v.Args[0]
+	b := v.Block
+	typ := &b.Func.Config.Types
+	// match: (ADDSconstflags [c] x)
+	// cond: !isARM64addcon(c)
+	// result: (ADDSflags x (MOVDconst [c]))
+	for {
+		c := auxIntToInt64(v.AuxInt)
+		x := v_0
+		if !(!isARM64addcon(c)) {
+			break
+		}
+		v.reset(OpARM64ADDSflags)
+		v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v0.AuxInt = int64ToAuxInt(c)
+		v.AddArg2(x, v0)
+		return true
+	}
+	return false
+}
+func rewriteValueARM64latelower_OpARM64ADDconst(v *Value) bool {
+	v_0 := v.Args[0]
+	b := v.Block
+	typ := &b.Func.Config.Types
+	// match: (ADDconst [c] x)
+	// cond: !isARM64addcon(c)
+	// result: (ADD x (MOVDconst [c]))
+	for {
+		c := auxIntToInt64(v.AuxInt)
+		x := v_0
+		if !(!isARM64addcon(c)) {
+			break
+		}
+		v.reset(OpARM64ADD)
+		v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v0.AuxInt = int64ToAuxInt(c)
+		v.AddArg2(x, v0)
+		return true
+	}
+	return false
+}
+func rewriteValueARM64latelower_OpARM64ANDconst(v *Value) bool {
+	v_0 := v.Args[0]
+	b := v.Block
+	typ := &b.Func.Config.Types
+	// match: (ANDconst [c] x)
+	// cond: !isARM64bitcon(uint64(c))
+	// result: (AND x (MOVDconst [c]))
+	for {
+		c := auxIntToInt64(v.AuxInt)
+		x := v_0
+		if !(!isARM64bitcon(uint64(c))) {
+			break
+		}
+		v.reset(OpARM64AND)
+		v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v0.AuxInt = int64ToAuxInt(c)
+		v.AddArg2(x, v0)
+		return true
+	}
+	return false
+}
+func rewriteValueARM64latelower_OpARM64CMNWconst(v *Value) bool {
+	v_0 := v.Args[0]
+	b := v.Block
+	typ := &b.Func.Config.Types
+	// match: (CMNWconst [c] x)
+	// cond: !isARM64addcon(int64(c))
+	// result: (CMNW x (MOVDconst [int64(c)]))
+	for {
+		c := auxIntToInt32(v.AuxInt)
+		x := v_0
+		if !(!isARM64addcon(int64(c))) {
+			break
+		}
+		v.reset(OpARM64CMNW)
+		v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v0.AuxInt = int64ToAuxInt(int64(c))
+		v.AddArg2(x, v0)
+		return true
+	}
+	return false
+}
+func rewriteValueARM64latelower_OpARM64CMNconst(v *Value) bool {
+	v_0 := v.Args[0]
+	b := v.Block
+	typ := &b.Func.Config.Types
+	// match: (CMNconst [c] x)
+	// cond: !isARM64addcon(c)
+	// result: (CMN x (MOVDconst [c]))
+	for {
+		c := auxIntToInt64(v.AuxInt)
+		x := v_0
+		if !(!isARM64addcon(c)) {
+			break
+		}
+		v.reset(OpARM64CMN)
+		v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v0.AuxInt = int64ToAuxInt(c)
+		v.AddArg2(x, v0)
+		return true
+	}
+	return false
+}
+func rewriteValueARM64latelower_OpARM64CMPWconst(v *Value) bool {
+	v_0 := v.Args[0]
+	b := v.Block
+	typ := &b.Func.Config.Types
+	// match: (CMPWconst [c] x)
+	// cond: !isARM64addcon(int64(c))
+	// result: (CMPW x (MOVDconst [int64(c)]))
+	for {
+		c := auxIntToInt32(v.AuxInt)
+		x := v_0
+		if !(!isARM64addcon(int64(c))) {
+			break
+		}
+		v.reset(OpARM64CMPW)
+		v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v0.AuxInt = int64ToAuxInt(int64(c))
+		v.AddArg2(x, v0)
+		return true
+	}
+	return false
+}
+func rewriteValueARM64latelower_OpARM64CMPconst(v *Value) bool {
+	v_0 := v.Args[0]
+	b := v.Block
+	typ := &b.Func.Config.Types
+	// match: (CMPconst [c] x)
+	// cond: !isARM64addcon(c)
+	// result: (CMP x (MOVDconst [c]))
+	for {
+		c := auxIntToInt64(v.AuxInt)
+		x := v_0
+		if !(!isARM64addcon(c)) {
+			break
+		}
+		v.reset(OpARM64CMP)
+		v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v0.AuxInt = int64ToAuxInt(c)
+		v.AddArg2(x, v0)
+		return true
+	}
+	return false
+}
+func rewriteValueARM64latelower_OpARM64ORconst(v *Value) bool {
+	v_0 := v.Args[0]
+	b := v.Block
+	typ := &b.Func.Config.Types
+	// match: (ORconst [c] x)
+	// cond: !isARM64bitcon(uint64(c))
+	// result: (OR x (MOVDconst [c]))
+	for {
+		c := auxIntToInt64(v.AuxInt)
+		x := v_0
+		if !(!isARM64bitcon(uint64(c))) {
+			break
+		}
+		v.reset(OpARM64OR)
+		v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v0.AuxInt = int64ToAuxInt(c)
+		v.AddArg2(x, v0)
+		return true
+	}
+	return false
+}
+func rewriteValueARM64latelower_OpARM64SUBconst(v *Value) bool {
+	v_0 := v.Args[0]
+	b := v.Block
+	typ := &b.Func.Config.Types
+	// match: (SUBconst [c] x)
+	// cond: !isARM64addcon(c)
+	// result: (SUB x (MOVDconst [c]))
+	for {
+		c := auxIntToInt64(v.AuxInt)
+		x := v_0
+		if !(!isARM64addcon(c)) {
+			break
+		}
+		v.reset(OpARM64SUB)
+		v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v0.AuxInt = int64ToAuxInt(c)
+		v.AddArg2(x, v0)
+		return true
+	}
+	return false
+}
+func rewriteValueARM64latelower_OpARM64TSTWconst(v *Value) bool {
+	v_0 := v.Args[0]
+	b := v.Block
+	typ := &b.Func.Config.Types
+	// match: (TSTWconst [c] x)
+	// cond: !isARM64bitcon(uint64(c)|uint64(c)<<32)
+	// result: (TSTW x (MOVDconst [int64(c)]))
+	for {
+		c := auxIntToInt32(v.AuxInt)
+		x := v_0
+		if !(!isARM64bitcon(uint64(c) | uint64(c)<<32)) {
+			break
+		}
+		v.reset(OpARM64TSTW)
+		v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v0.AuxInt = int64ToAuxInt(int64(c))
+		v.AddArg2(x, v0)
+		return true
+	}
+	return false
+}
+func rewriteValueARM64latelower_OpARM64TSTconst(v *Value) bool {
+	v_0 := v.Args[0]
+	b := v.Block
+	typ := &b.Func.Config.Types
+	// match: (TSTconst [c] x)
+	// cond: !isARM64bitcon(uint64(c))
+	// result: (TST x (MOVDconst [c]))
+	for {
+		c := auxIntToInt64(v.AuxInt)
+		x := v_0
+		if !(!isARM64bitcon(uint64(c))) {
+			break
+		}
+		v.reset(OpARM64TST)
+		v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v0.AuxInt = int64ToAuxInt(c)
+		v.AddArg2(x, v0)
+		return true
+	}
+	return false
+}
+func rewriteValueARM64latelower_OpARM64XORconst(v *Value) bool {
+	v_0 := v.Args[0]
+	b := v.Block
+	typ := &b.Func.Config.Types
+	// match: (XORconst [c] x)
+	// cond: !isARM64bitcon(uint64(c))
+	// result: (XOR x (MOVDconst [c]))
+	for {
+		c := auxIntToInt64(v.AuxInt)
+		x := v_0
+		if !(!isARM64bitcon(uint64(c))) {
+			break
+		}
+		v.reset(OpARM64XOR)
+		v0 := b.NewValue0(v.Pos, OpARM64MOVDconst, typ.UInt64)
+		v0.AuxInt = int64ToAuxInt(c)
+		v.AddArg2(x, v0)
+		return true
+	}
+	return false
+}
+func rewriteBlockARM64latelower(b *Block) bool {
+	return false
+}
diff --git a/src/cmd/compile/internal/ssa/rewriteLOONG64.go b/src/cmd/compile/internal/ssa/rewriteLOONG64.go
index 3fc1010..f6da0b7 100644
--- a/src/cmd/compile/internal/ssa/rewriteLOONG64.go
+++ b/src/cmd/compile/internal/ssa/rewriteLOONG64.go
@@ -1,5 +1,5 @@
-// Code generated from gen/LOONG64.rules; DO NOT EDIT.
-// generated with: cd gen; go run *.go
+// Code generated from _gen/LOONG64.rules; DO NOT EDIT.
+// generated with: cd _gen; go run .
 
 package ssa
 
@@ -52,8 +52,7 @@
 		v.Op = OpLOONG64LoweredAtomicAdd64
 		return true
 	case OpAtomicCompareAndSwap32:
-		v.Op = OpLOONG64LoweredAtomicCas32
-		return true
+		return rewriteValueLOONG64_OpAtomicCompareAndSwap32(v)
 	case OpAtomicCompareAndSwap64:
 		v.Op = OpLOONG64LoweredAtomicCas64
 		return true
@@ -100,6 +99,8 @@
 		return rewriteValueLOONG64_OpCom64(v)
 	case OpCom8:
 		return rewriteValueLOONG64_OpCom8(v)
+	case OpCondSelect:
+		return rewriteValueLOONG64_OpCondSelect(v)
 	case OpConst16:
 		return rewriteValueLOONG64_OpConst16(v)
 	case OpConst32:
@@ -229,6 +230,10 @@
 		return rewriteValueLOONG64_OpLOONG64LoweredAtomicStore32(v)
 	case OpLOONG64LoweredAtomicStore64:
 		return rewriteValueLOONG64_OpLOONG64LoweredAtomicStore64(v)
+	case OpLOONG64MASKEQZ:
+		return rewriteValueLOONG64_OpLOONG64MASKEQZ(v)
+	case OpLOONG64MASKNEZ:
+		return rewriteValueLOONG64_OpLOONG64MASKNEZ(v)
 	case OpLOONG64MOVBUload:
 		return rewriteValueLOONG64_OpLOONG64MOVBUload(v)
 	case OpLOONG64MOVBUreg:
@@ -291,6 +296,10 @@
 		return rewriteValueLOONG64_OpLOONG64OR(v)
 	case OpLOONG64ORconst:
 		return rewriteValueLOONG64_OpLOONG64ORconst(v)
+	case OpLOONG64ROTR:
+		return rewriteValueLOONG64_OpLOONG64ROTR(v)
+	case OpLOONG64ROTRV:
+		return rewriteValueLOONG64_OpLOONG64ROTRV(v)
 	case OpLOONG64SGT:
 		return rewriteValueLOONG64_OpLOONG64SGT(v)
 	case OpLOONG64SGTU:
@@ -695,6 +704,27 @@
 		return true
 	}
 }
+func rewriteValueLOONG64_OpAtomicCompareAndSwap32(v *Value) bool {
+	v_3 := v.Args[3]
+	v_2 := v.Args[2]
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	b := v.Block
+	typ := &b.Func.Config.Types
+	// match: (AtomicCompareAndSwap32 ptr old new mem)
+	// result: (LoweredAtomicCas32 ptr (SignExt32to64 old) new mem)
+	for {
+		ptr := v_0
+		old := v_1
+		new := v_2
+		mem := v_3
+		v.reset(OpLOONG64LoweredAtomicCas32)
+		v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
+		v0.AddArg(old)
+		v.AddArg4(ptr, v0, new, mem)
+		return true
+	}
+}
 func rewriteValueLOONG64_OpAvg64u(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
@@ -775,6 +805,27 @@
 		return true
 	}
 }
+func rewriteValueLOONG64_OpCondSelect(v *Value) bool {
+	v_2 := v.Args[2]
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	b := v.Block
+	// match: (CondSelect <t> x y cond)
+	// result: (OR (MASKEQZ <t> x cond) (MASKNEZ <t> y cond))
+	for {
+		t := v.Type
+		x := v_0
+		y := v_1
+		cond := v_2
+		v.reset(OpLOONG64OR)
+		v0 := b.NewValue0(v.Pos, OpLOONG64MASKEQZ, t)
+		v0.AddArg2(x, cond)
+		v1 := b.NewValue0(v.Pos, OpLOONG64MASKNEZ, t)
+		v1.AddArg2(y, cond)
+		v.AddArg2(v0, v1)
+		return true
+	}
+}
 func rewriteValueLOONG64_OpConst16(v *Value) bool {
 	// match: (Const16 [val])
 	// result: (MOVVconst [int64(val)])
@@ -1592,6 +1643,34 @@
 	}
 	return false
 }
+func rewriteValueLOONG64_OpLOONG64MASKEQZ(v *Value) bool {
+	v_0 := v.Args[0]
+	// match: (MASKEQZ (MOVVconst [0]) cond)
+	// result: (MOVVconst [0])
+	for {
+		if v_0.Op != OpLOONG64MOVVconst || auxIntToInt64(v_0.AuxInt) != 0 {
+			break
+		}
+		v.reset(OpLOONG64MOVVconst)
+		v.AuxInt = int64ToAuxInt(0)
+		return true
+	}
+	return false
+}
+func rewriteValueLOONG64_OpLOONG64MASKNEZ(v *Value) bool {
+	v_0 := v.Args[0]
+	// match: (MASKNEZ (MOVVconst [0]) cond)
+	// result: (MOVVconst [0])
+	for {
+		if v_0.Op != OpLOONG64MOVVconst || auxIntToInt64(v_0.AuxInt) != 0 {
+			break
+		}
+		v.reset(OpLOONG64MOVVconst)
+		v.AuxInt = int64ToAuxInt(0)
+		return true
+	}
+	return false
+}
 func rewriteValueLOONG64_OpLOONG64MOVBUload(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
@@ -3307,6 +3386,42 @@
 	}
 	return false
 }
+func rewriteValueLOONG64_OpLOONG64ROTR(v *Value) bool {
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	// match: (ROTR x (MOVVconst [c]))
+	// result: (ROTRconst x [c&31])
+	for {
+		x := v_0
+		if v_1.Op != OpLOONG64MOVVconst {
+			break
+		}
+		c := auxIntToInt64(v_1.AuxInt)
+		v.reset(OpLOONG64ROTRconst)
+		v.AuxInt = int64ToAuxInt(c & 31)
+		v.AddArg(x)
+		return true
+	}
+	return false
+}
+func rewriteValueLOONG64_OpLOONG64ROTRV(v *Value) bool {
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	// match: (ROTRV x (MOVVconst [c]))
+	// result: (ROTRVconst x [c&63])
+	for {
+		x := v_0
+		if v_1.Op != OpLOONG64MOVVconst {
+			break
+		}
+		c := auxIntToInt64(v_1.AuxInt)
+		v.reset(OpLOONG64ROTRVconst)
+		v.AuxInt = int64ToAuxInt(c & 63)
+		v.AddArg(x)
+		return true
+	}
+	return false
+}
 func rewriteValueLOONG64_OpLOONG64SGT(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
@@ -3327,6 +3442,17 @@
 		v.AddArg(x)
 		return true
 	}
+	// match: (SGT x x)
+	// result: (MOVVconst [0])
+	for {
+		x := v_0
+		if x != v_1 {
+			break
+		}
+		v.reset(OpLOONG64MOVVconst)
+		v.AuxInt = int64ToAuxInt(0)
+		return true
+	}
 	return false
 }
 func rewriteValueLOONG64_OpLOONG64SGTU(v *Value) bool {
@@ -3349,6 +3475,17 @@
 		v.AddArg(x)
 		return true
 	}
+	// match: (SGTU x x)
+	// result: (MOVVconst [0])
+	for {
+		x := v_0
+		if x != v_1 {
+			break
+		}
+		v.reset(OpLOONG64MOVVconst)
+		v.AuxInt = int64ToAuxInt(0)
+		return true
+	}
 	return false
 }
 func rewriteValueLOONG64_OpLOONG64SGTUconst(v *Value) bool {
@@ -5827,57 +5964,33 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
-	typ := &b.Func.Config.Types
-	// match: (RotateLeft32 <t> x (MOVVconst [c]))
-	// result: (Or32 (Lsh32x64 <t> x (MOVVconst [c&31])) (Rsh32Ux64 <t> x (MOVVconst [-c&31])))
+	// match: (RotateLeft32 x y)
+	// result: (ROTR x (NEGV <y.Type> y))
 	for {
-		t := v.Type
 		x := v_0
-		if v_1.Op != OpLOONG64MOVVconst {
-			break
-		}
-		c := auxIntToInt64(v_1.AuxInt)
-		v.reset(OpOr32)
-		v0 := b.NewValue0(v.Pos, OpLsh32x64, t)
-		v1 := b.NewValue0(v.Pos, OpLOONG64MOVVconst, typ.UInt64)
-		v1.AuxInt = int64ToAuxInt(c & 31)
-		v0.AddArg2(x, v1)
-		v2 := b.NewValue0(v.Pos, OpRsh32Ux64, t)
-		v3 := b.NewValue0(v.Pos, OpLOONG64MOVVconst, typ.UInt64)
-		v3.AuxInt = int64ToAuxInt(-c & 31)
-		v2.AddArg2(x, v3)
-		v.AddArg2(v0, v2)
+		y := v_1
+		v.reset(OpLOONG64ROTR)
+		v0 := b.NewValue0(v.Pos, OpLOONG64NEGV, y.Type)
+		v0.AddArg(y)
+		v.AddArg2(x, v0)
 		return true
 	}
-	return false
 }
 func rewriteValueLOONG64_OpRotateLeft64(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
-	typ := &b.Func.Config.Types
-	// match: (RotateLeft64 <t> x (MOVVconst [c]))
-	// result: (Or64 (Lsh64x64 <t> x (MOVVconst [c&63])) (Rsh64Ux64 <t> x (MOVVconst [-c&63])))
+	// match: (RotateLeft64 x y)
+	// result: (ROTRV x (NEGV <y.Type> y))
 	for {
-		t := v.Type
 		x := v_0
-		if v_1.Op != OpLOONG64MOVVconst {
-			break
-		}
-		c := auxIntToInt64(v_1.AuxInt)
-		v.reset(OpOr64)
-		v0 := b.NewValue0(v.Pos, OpLsh64x64, t)
-		v1 := b.NewValue0(v.Pos, OpLOONG64MOVVconst, typ.UInt64)
-		v1.AuxInt = int64ToAuxInt(c & 63)
-		v0.AddArg2(x, v1)
-		v2 := b.NewValue0(v.Pos, OpRsh64Ux64, t)
-		v3 := b.NewValue0(v.Pos, OpLOONG64MOVVconst, typ.UInt64)
-		v3.AuxInt = int64ToAuxInt(-c & 63)
-		v2.AddArg2(x, v3)
-		v.AddArg2(v0, v2)
+		y := v_1
+		v.reset(OpLOONG64ROTRV)
+		v0 := b.NewValue0(v.Pos, OpLOONG64NEGV, y.Type)
+		v0.AddArg(y)
+		v.AddArg2(x, v0)
 		return true
 	}
-	return false
 }
 func rewriteValueLOONG64_OpRotateLeft8(v *Value) bool {
 	v_1 := v.Args[1]
@@ -6790,6 +6903,38 @@
 		v.AddArg(v0)
 		return true
 	}
+	// match: (Select0 <t> (Add64carry x y c))
+	// result: (ADDV (ADDV <t> x y) c)
+	for {
+		t := v.Type
+		if v_0.Op != OpAdd64carry {
+			break
+		}
+		c := v_0.Args[2]
+		x := v_0.Args[0]
+		y := v_0.Args[1]
+		v.reset(OpLOONG64ADDV)
+		v0 := b.NewValue0(v.Pos, OpLOONG64ADDV, t)
+		v0.AddArg2(x, y)
+		v.AddArg2(v0, c)
+		return true
+	}
+	// match: (Select0 <t> (Sub64borrow x y c))
+	// result: (SUBV (SUBV <t> x y) c)
+	for {
+		t := v.Type
+		if v_0.Op != OpSub64borrow {
+			break
+		}
+		c := v_0.Args[2]
+		x := v_0.Args[0]
+		y := v_0.Args[1]
+		v.reset(OpLOONG64SUBV)
+		v0 := b.NewValue0(v.Pos, OpLOONG64SUBV, t)
+		v0.AddArg2(x, y)
+		v.AddArg2(v0, c)
+		return true
+	}
 	// match: (Select0 (DIVVU _ (MOVVconst [1])))
 	// result: (MOVVconst [0])
 	for {
@@ -6902,6 +7047,50 @@
 		v.AddArg2(v0, v2)
 		return true
 	}
+	// match: (Select1 <t> (Add64carry x y c))
+	// result: (OR (SGTU <t> x s:(ADDV <t> x y)) (SGTU <t> s (ADDV <t> s c)))
+	for {
+		t := v.Type
+		if v_0.Op != OpAdd64carry {
+			break
+		}
+		c := v_0.Args[2]
+		x := v_0.Args[0]
+		y := v_0.Args[1]
+		v.reset(OpLOONG64OR)
+		v0 := b.NewValue0(v.Pos, OpLOONG64SGTU, t)
+		s := b.NewValue0(v.Pos, OpLOONG64ADDV, t)
+		s.AddArg2(x, y)
+		v0.AddArg2(x, s)
+		v2 := b.NewValue0(v.Pos, OpLOONG64SGTU, t)
+		v3 := b.NewValue0(v.Pos, OpLOONG64ADDV, t)
+		v3.AddArg2(s, c)
+		v2.AddArg2(s, v3)
+		v.AddArg2(v0, v2)
+		return true
+	}
+	// match: (Select1 <t> (Sub64borrow x y c))
+	// result: (OR (SGTU <t> s:(SUBV <t> x y) x) (SGTU <t> (SUBV <t> s c) s))
+	for {
+		t := v.Type
+		if v_0.Op != OpSub64borrow {
+			break
+		}
+		c := v_0.Args[2]
+		x := v_0.Args[0]
+		y := v_0.Args[1]
+		v.reset(OpLOONG64OR)
+		v0 := b.NewValue0(v.Pos, OpLOONG64SGTU, t)
+		s := b.NewValue0(v.Pos, OpLOONG64SUBV, t)
+		s.AddArg2(x, y)
+		v0.AddArg2(s, x)
+		v2 := b.NewValue0(v.Pos, OpLOONG64SGTU, t)
+		v3 := b.NewValue0(v.Pos, OpLOONG64SUBV, t)
+		v3.AddArg2(s, c)
+		v2.AddArg2(v3, s)
+		v.AddArg2(v0, v2)
+		return true
+	}
 	// match: (Select1 (MULVU x (MOVVconst [-1])))
 	// result: (NEGV x)
 	for {
diff --git a/src/cmd/compile/internal/ssa/rewriteMIPS.go b/src/cmd/compile/internal/ssa/rewriteMIPS.go
index 811ea9d..1c8d90a 100644
--- a/src/cmd/compile/internal/ssa/rewriteMIPS.go
+++ b/src/cmd/compile/internal/ssa/rewriteMIPS.go
@@ -1,5 +1,5 @@
-// Code generated from gen/MIPS.rules; DO NOT EDIT.
-// generated with: cd gen; go run *.go
+// Code generated from _gen/MIPS.rules; DO NOT EDIT.
+// generated with: cd _gen; go run .
 
 package ssa
 
diff --git a/src/cmd/compile/internal/ssa/rewriteMIPS64.go b/src/cmd/compile/internal/ssa/rewriteMIPS64.go
index 1fbd556..c0d42b5 100644
--- a/src/cmd/compile/internal/ssa/rewriteMIPS64.go
+++ b/src/cmd/compile/internal/ssa/rewriteMIPS64.go
@@ -1,5 +1,5 @@
-// Code generated from gen/MIPS64.rules; DO NOT EDIT.
-// generated with: cd gen; go run *.go
+// Code generated from _gen/MIPS64.rules; DO NOT EDIT.
+// generated with: cd _gen; go run .
 
 package ssa
 
@@ -52,8 +52,7 @@
 		v.Op = OpMIPS64LoweredAtomicAdd64
 		return true
 	case OpAtomicCompareAndSwap32:
-		v.Op = OpMIPS64LoweredAtomicCas32
-		return true
+		return rewriteValueMIPS64_OpAtomicCompareAndSwap32(v)
 	case OpAtomicCompareAndSwap64:
 		v.Op = OpMIPS64LoweredAtomicCas64
 		return true
@@ -697,6 +696,27 @@
 		return true
 	}
 }
+func rewriteValueMIPS64_OpAtomicCompareAndSwap32(v *Value) bool {
+	v_3 := v.Args[3]
+	v_2 := v.Args[2]
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	b := v.Block
+	typ := &b.Func.Config.Types
+	// match: (AtomicCompareAndSwap32 ptr old new mem)
+	// result: (LoweredAtomicCas32 ptr (SignExt32to64 old) new mem)
+	for {
+		ptr := v_0
+		old := v_1
+		new := v_2
+		mem := v_3
+		v.reset(OpMIPS64LoweredAtomicCas32)
+		v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
+		v0.AddArg(old)
+		v.AddArg4(ptr, v0, new, mem)
+		return true
+	}
+}
 func rewriteValueMIPS64_OpAvg64u(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
diff --git a/src/cmd/compile/internal/ssa/rewritePPC64.go b/src/cmd/compile/internal/ssa/rewritePPC64.go
index 8d6f976..bc59312 100644
--- a/src/cmd/compile/internal/ssa/rewritePPC64.go
+++ b/src/cmd/compile/internal/ssa/rewritePPC64.go
@@ -1,5 +1,5 @@
-// Code generated from gen/PPC64.rules; DO NOT EDIT.
-// generated with: cd gen; go run *.go
+// Code generated from _gen/PPC64.rules; DO NOT EDIT.
+// generated with: cd _gen; go run .
 
 package ssa
 
@@ -368,9 +368,6 @@
 	case OpMul64F:
 		v.Op = OpPPC64FMUL
 		return true
-	case OpMul64uhilo:
-		v.Op = OpPPC64LoweredMuluhilo
-		return true
 	case OpMul8:
 		v.Op = OpPPC64MULLW
 		return true
@@ -441,8 +438,6 @@
 		return rewriteValuePPC64_OpPPC64AND(v)
 	case OpPPC64ANDN:
 		return rewriteValuePPC64_OpPPC64ANDN(v)
-	case OpPPC64ANDconst:
-		return rewriteValuePPC64_OpPPC64ANDconst(v)
 	case OpPPC64CLRLSLDI:
 		return rewriteValuePPC64_OpPPC64CLRLSLDI(v)
 	case OpPPC64CMP:
@@ -650,9 +645,11 @@
 	case OpRotateLeft16:
 		return rewriteValuePPC64_OpRotateLeft16(v)
 	case OpRotateLeft32:
-		return rewriteValuePPC64_OpRotateLeft32(v)
+		v.Op = OpPPC64ROTLW
+		return true
 	case OpRotateLeft64:
-		return rewriteValuePPC64_OpRotateLeft64(v)
+		v.Op = OpPPC64ROTL
+		return true
 	case OpRotateLeft8:
 		return rewriteValuePPC64_OpRotateLeft8(v)
 	case OpRound:
@@ -1175,9 +1172,10 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
+	typ := &b.Func.Config.Types
 	// match: (CondSelect x y bool)
 	// cond: flagArg(bool) == nil
-	// result: (ISEL [6] x y (CMPWconst [0] bool))
+	// result: (ISEL [6] x y (Select1 <types.TypeFlags> (ANDCCconst [1] bool)))
 	for {
 		x := v_0
 		y := v_1
@@ -1187,9 +1185,11 @@
 		}
 		v.reset(OpPPC64ISEL)
 		v.AuxInt = int32ToAuxInt(6)
-		v0 := b.NewValue0(v.Pos, OpPPC64CMPWconst, types.TypeFlags)
-		v0.AuxInt = int32ToAuxInt(0)
-		v0.AddArg(bool)
+		v0 := b.NewValue0(v.Pos, OpSelect1, types.TypeFlags)
+		v1 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+		v1.AuxInt = int64ToAuxInt(1)
+		v1.AddArg(bool)
+		v0.AddArg(v1)
 		v.AddArg3(x, y, v0)
 		return true
 	}
@@ -1765,14 +1765,17 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (EqB x y)
-	// result: (ANDconst [1] (EQV x y))
+	// result: (Select0 <typ.Int> (ANDCCconst [1] (EQV x y)))
 	for {
 		x := v_0
 		y := v_1
-		v.reset(OpPPC64ANDconst)
-		v.AuxInt = int64ToAuxInt(1)
-		v0 := b.NewValue0(v.Pos, OpPPC64EQV, typ.Int64)
-		v0.AddArg2(x, y)
+		v.reset(OpSelect0)
+		v.Type = typ.Int
+		v0 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+		v0.AuxInt = int64ToAuxInt(1)
+		v1 := b.NewValue0(v.Pos, OpPPC64EQV, typ.Int64)
+		v1.AddArg2(x, y)
+		v0.AddArg(v1)
 		v.AddArg(v0)
 		return true
 	}
@@ -2406,23 +2409,6 @@
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
-	// match: (Lsh16x32 x (MOVDconst [c]))
-	// cond: uint32(c) < 16
-	// result: (SLWconst x [c&31])
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64MOVDconst {
-			break
-		}
-		c := auxIntToInt64(v_1.AuxInt)
-		if !(uint32(c) < 16) {
-			break
-		}
-		v.reset(OpPPC64SLWconst)
-		v.AuxInt = int64ToAuxInt(c & 31)
-		v.AddArg(x)
-		return true
-	}
 	// match: (Lsh16x32 x y)
 	// cond: shiftIsBounded(v)
 	// result: (SLW x y)
@@ -2460,21 +2446,6 @@
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
-	// match: (Lsh16x64 _ (MOVDconst [c]))
-	// cond: uint64(c) >= 16
-	// result: (MOVDconst [0])
-	for {
-		if v_1.Op != OpPPC64MOVDconst {
-			break
-		}
-		c := auxIntToInt64(v_1.AuxInt)
-		if !(uint64(c) >= 16) {
-			break
-		}
-		v.reset(OpPPC64MOVDconst)
-		v.AuxInt = int64ToAuxInt(0)
-		return true
-	}
 	// match: (Lsh16x64 x (MOVDconst [c]))
 	// cond: uint64(c) < 16
 	// result: (SLWconst x [c])
@@ -2607,23 +2578,6 @@
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
-	// match: (Lsh32x32 x (MOVDconst [c]))
-	// cond: uint32(c) < 32
-	// result: (SLWconst x [c&31])
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64MOVDconst {
-			break
-		}
-		c := auxIntToInt64(v_1.AuxInt)
-		if !(uint32(c) < 32) {
-			break
-		}
-		v.reset(OpPPC64SLWconst)
-		v.AuxInt = int64ToAuxInt(c & 31)
-		v.AddArg(x)
-		return true
-	}
 	// match: (Lsh32x32 x y)
 	// cond: shiftIsBounded(v)
 	// result: (SLW x y)
@@ -2661,21 +2615,6 @@
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
-	// match: (Lsh32x64 _ (MOVDconst [c]))
-	// cond: uint64(c) >= 32
-	// result: (MOVDconst [0])
-	for {
-		if v_1.Op != OpPPC64MOVDconst {
-			break
-		}
-		c := auxIntToInt64(v_1.AuxInt)
-		if !(uint64(c) >= 32) {
-			break
-		}
-		v.reset(OpPPC64MOVDconst)
-		v.AuxInt = int64ToAuxInt(0)
-		return true
-	}
 	// match: (Lsh32x64 x (MOVDconst [c]))
 	// cond: uint64(c) < 32
 	// result: (SLWconst x [c])
@@ -2706,45 +2645,6 @@
 		v.AddArg2(x, y)
 		return true
 	}
-	// match: (Lsh32x64 x (AND y (MOVDconst [31])))
-	// result: (SLW x (ANDconst <typ.Int32> [31] y))
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64AND {
-			break
-		}
-		_ = v_1.Args[1]
-		v_1_0 := v_1.Args[0]
-		v_1_1 := v_1.Args[1]
-		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
-			y := v_1_0
-			if v_1_1.Op != OpPPC64MOVDconst || auxIntToInt64(v_1_1.AuxInt) != 31 {
-				continue
-			}
-			v.reset(OpPPC64SLW)
-			v0 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.Int32)
-			v0.AuxInt = int64ToAuxInt(31)
-			v0.AddArg(y)
-			v.AddArg2(x, v0)
-			return true
-		}
-		break
-	}
-	// match: (Lsh32x64 x (ANDconst <typ.Int32> [31] y))
-	// result: (SLW x (ANDconst <typ.Int32> [31] y))
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64ANDconst || v_1.Type != typ.Int32 || auxIntToInt64(v_1.AuxInt) != 31 {
-			break
-		}
-		y := v_1.Args[0]
-		v.reset(OpPPC64SLW)
-		v0 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.Int32)
-		v0.AuxInt = int64ToAuxInt(31)
-		v0.AddArg(y)
-		v.AddArg2(x, v0)
-		return true
-	}
 	// match: (Lsh32x64 x y)
 	// result: (SLW x (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [32]))))
 	for {
@@ -2847,23 +2747,6 @@
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
-	// match: (Lsh64x32 x (MOVDconst [c]))
-	// cond: uint32(c) < 64
-	// result: (SLDconst x [c&63])
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64MOVDconst {
-			break
-		}
-		c := auxIntToInt64(v_1.AuxInt)
-		if !(uint32(c) < 64) {
-			break
-		}
-		v.reset(OpPPC64SLDconst)
-		v.AuxInt = int64ToAuxInt(c & 63)
-		v.AddArg(x)
-		return true
-	}
 	// match: (Lsh64x32 x y)
 	// cond: shiftIsBounded(v)
 	// result: (SLD x y)
@@ -2901,21 +2784,6 @@
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
-	// match: (Lsh64x64 _ (MOVDconst [c]))
-	// cond: uint64(c) >= 64
-	// result: (MOVDconst [0])
-	for {
-		if v_1.Op != OpPPC64MOVDconst {
-			break
-		}
-		c := auxIntToInt64(v_1.AuxInt)
-		if !(uint64(c) >= 64) {
-			break
-		}
-		v.reset(OpPPC64MOVDconst)
-		v.AuxInt = int64ToAuxInt(0)
-		return true
-	}
 	// match: (Lsh64x64 x (MOVDconst [c]))
 	// cond: uint64(c) < 64
 	// result: (SLDconst x [c])
@@ -2946,45 +2814,6 @@
 		v.AddArg2(x, y)
 		return true
 	}
-	// match: (Lsh64x64 x (AND y (MOVDconst [63])))
-	// result: (SLD x (ANDconst <typ.Int64> [63] y))
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64AND {
-			break
-		}
-		_ = v_1.Args[1]
-		v_1_0 := v_1.Args[0]
-		v_1_1 := v_1.Args[1]
-		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
-			y := v_1_0
-			if v_1_1.Op != OpPPC64MOVDconst || auxIntToInt64(v_1_1.AuxInt) != 63 {
-				continue
-			}
-			v.reset(OpPPC64SLD)
-			v0 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.Int64)
-			v0.AuxInt = int64ToAuxInt(63)
-			v0.AddArg(y)
-			v.AddArg2(x, v0)
-			return true
-		}
-		break
-	}
-	// match: (Lsh64x64 x (ANDconst <typ.Int64> [63] y))
-	// result: (SLD x (ANDconst <typ.Int64> [63] y))
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64ANDconst || v_1.Type != typ.Int64 || auxIntToInt64(v_1.AuxInt) != 63 {
-			break
-		}
-		y := v_1.Args[0]
-		v.reset(OpPPC64SLD)
-		v0 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.Int64)
-		v0.AuxInt = int64ToAuxInt(63)
-		v0.AddArg(y)
-		v.AddArg2(x, v0)
-		return true
-	}
 	// match: (Lsh64x64 x y)
 	// result: (SLD x (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [64]))))
 	for {
@@ -3087,23 +2916,6 @@
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
-	// match: (Lsh8x32 x (MOVDconst [c]))
-	// cond: uint32(c) < 8
-	// result: (SLWconst x [c&7])
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64MOVDconst {
-			break
-		}
-		c := auxIntToInt64(v_1.AuxInt)
-		if !(uint32(c) < 8) {
-			break
-		}
-		v.reset(OpPPC64SLWconst)
-		v.AuxInt = int64ToAuxInt(c & 7)
-		v.AddArg(x)
-		return true
-	}
 	// match: (Lsh8x32 x y)
 	// cond: shiftIsBounded(v)
 	// result: (SLW x y)
@@ -3141,21 +2953,6 @@
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
-	// match: (Lsh8x64 _ (MOVDconst [c]))
-	// cond: uint64(c) >= 8
-	// result: (MOVDconst [0])
-	for {
-		if v_1.Op != OpPPC64MOVDconst {
-			break
-		}
-		c := auxIntToInt64(v_1.AuxInt)
-		if !(uint64(c) >= 8) {
-			break
-		}
-		v.reset(OpPPC64MOVDconst)
-		v.AuxInt = int64ToAuxInt(0)
-		return true
-	}
 	// match: (Lsh8x64 x (MOVDconst [c]))
 	// cond: uint64(c) < 8
 	// result: (SLWconst x [c])
@@ -3881,8 +3678,6 @@
 func rewriteValuePPC64_OpPPC64ADD(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	b := v.Block
-	typ := &b.Func.Config.Types
 	// match: (ADD l:(MULLD x y) z)
 	// cond: buildcfg.GOPPC64 >= 9 && l.Uses == 1 && clobber(l)
 	// result: (MADDLD x y z)
@@ -3904,204 +3699,6 @@
 		}
 		break
 	}
-	// match: (ADD (SLDconst x [c]) (SRDconst x [d]))
-	// cond: d == 64-c
-	// result: (ROTLconst [c] x)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpPPC64SLDconst {
-				continue
-			}
-			c := auxIntToInt64(v_0.AuxInt)
-			x := v_0.Args[0]
-			if v_1.Op != OpPPC64SRDconst {
-				continue
-			}
-			d := auxIntToInt64(v_1.AuxInt)
-			if x != v_1.Args[0] || !(d == 64-c) {
-				continue
-			}
-			v.reset(OpPPC64ROTLconst)
-			v.AuxInt = int64ToAuxInt(c)
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
-	// match: (ADD (SLWconst x [c]) (SRWconst x [d]))
-	// cond: d == 32-c
-	// result: (ROTLWconst [c] x)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpPPC64SLWconst {
-				continue
-			}
-			c := auxIntToInt64(v_0.AuxInt)
-			x := v_0.Args[0]
-			if v_1.Op != OpPPC64SRWconst {
-				continue
-			}
-			d := auxIntToInt64(v_1.AuxInt)
-			if x != v_1.Args[0] || !(d == 32-c) {
-				continue
-			}
-			v.reset(OpPPC64ROTLWconst)
-			v.AuxInt = int64ToAuxInt(c)
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
-	// match: (ADD (SLD x (ANDconst [63] y)) (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y))))
-	// result: (ROTL x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpPPC64SLD {
-				continue
-			}
-			_ = v_0.Args[1]
-			x := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpPPC64ANDconst || auxIntToInt64(v_0_1.AuxInt) != 63 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpPPC64SRD {
-				continue
-			}
-			_ = v_1.Args[1]
-			if x != v_1.Args[0] {
-				continue
-			}
-			v_1_1 := v_1.Args[1]
-			if v_1_1.Op != OpPPC64SUB || v_1_1.Type != typ.UInt {
-				continue
-			}
-			_ = v_1_1.Args[1]
-			v_1_1_0 := v_1_1.Args[0]
-			if v_1_1_0.Op != OpPPC64MOVDconst || auxIntToInt64(v_1_1_0.AuxInt) != 64 {
-				continue
-			}
-			v_1_1_1 := v_1_1.Args[1]
-			if v_1_1_1.Op != OpPPC64ANDconst || v_1_1_1.Type != typ.UInt || auxIntToInt64(v_1_1_1.AuxInt) != 63 || y != v_1_1_1.Args[0] {
-				continue
-			}
-			v.reset(OpPPC64ROTL)
-			v.AddArg2(x, y)
-			return true
-		}
-		break
-	}
-	// match: (ADD (SLD x (ANDconst [63] y)) (SRD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y))))
-	// result: (ROTL x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpPPC64SLD {
-				continue
-			}
-			_ = v_0.Args[1]
-			x := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpPPC64ANDconst || auxIntToInt64(v_0_1.AuxInt) != 63 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpPPC64SRD {
-				continue
-			}
-			_ = v_1.Args[1]
-			if x != v_1.Args[0] {
-				continue
-			}
-			v_1_1 := v_1.Args[1]
-			if v_1_1.Op != OpPPC64SUBFCconst || v_1_1.Type != typ.UInt || auxIntToInt64(v_1_1.AuxInt) != 64 {
-				continue
-			}
-			v_1_1_0 := v_1_1.Args[0]
-			if v_1_1_0.Op != OpPPC64ANDconst || v_1_1_0.Type != typ.UInt || auxIntToInt64(v_1_1_0.AuxInt) != 63 || y != v_1_1_0.Args[0] {
-				continue
-			}
-			v.reset(OpPPC64ROTL)
-			v.AddArg2(x, y)
-			return true
-		}
-		break
-	}
-	// match: (ADD (SLW x (ANDconst [31] y)) (SRW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y))))
-	// result: (ROTLW x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpPPC64SLW {
-				continue
-			}
-			_ = v_0.Args[1]
-			x := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpPPC64ANDconst || auxIntToInt64(v_0_1.AuxInt) != 31 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpPPC64SRW {
-				continue
-			}
-			_ = v_1.Args[1]
-			if x != v_1.Args[0] {
-				continue
-			}
-			v_1_1 := v_1.Args[1]
-			if v_1_1.Op != OpPPC64SUBFCconst || v_1_1.Type != typ.UInt || auxIntToInt64(v_1_1.AuxInt) != 32 {
-				continue
-			}
-			v_1_1_0 := v_1_1.Args[0]
-			if v_1_1_0.Op != OpPPC64ANDconst || v_1_1_0.Type != typ.UInt || auxIntToInt64(v_1_1_0.AuxInt) != 31 || y != v_1_1_0.Args[0] {
-				continue
-			}
-			v.reset(OpPPC64ROTLW)
-			v.AddArg2(x, y)
-			return true
-		}
-		break
-	}
-	// match: (ADD (SLW x (ANDconst [31] y)) (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y))))
-	// result: (ROTLW x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpPPC64SLW {
-				continue
-			}
-			_ = v_0.Args[1]
-			x := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpPPC64ANDconst || auxIntToInt64(v_0_1.AuxInt) != 31 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpPPC64SRW {
-				continue
-			}
-			_ = v_1.Args[1]
-			if x != v_1.Args[0] {
-				continue
-			}
-			v_1_1 := v_1.Args[1]
-			if v_1_1.Op != OpPPC64SUB || v_1_1.Type != typ.UInt {
-				continue
-			}
-			_ = v_1_1.Args[1]
-			v_1_1_0 := v_1_1.Args[0]
-			if v_1_1_0.Op != OpPPC64MOVDconst || auxIntToInt64(v_1_1_0.AuxInt) != 32 {
-				continue
-			}
-			v_1_1_1 := v_1_1.Args[1]
-			if v_1_1_1.Op != OpPPC64ANDconst || v_1_1_1.Type != typ.UInt || auxIntToInt64(v_1_1_1.AuxInt) != 31 || y != v_1_1_1.Args[0] {
-				continue
-			}
-			v.reset(OpPPC64ROTLW)
-			v.AddArg2(x, y)
-			return true
-		}
-		break
-	}
 	// match: (ADD x (MOVDconst [c]))
 	// cond: is32Bit(c)
 	// result: (ADDconst [c] x)
@@ -4239,6 +3836,8 @@
 func rewriteValuePPC64_OpPPC64AND(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
+	b := v.Block
+	typ := &b.Func.Config.Types
 	// match: (AND (MOVDconst [m]) (ROTLWconst [r] x))
 	// cond: isPPC64WordRotateMask(m)
 	// result: (RLWINM [encodePPC64RotateMask(r,m,32)] x)
@@ -4371,7 +3970,7 @@
 	}
 	// match: (AND x (MOVDconst [c]))
 	// cond: isU16Bit(c)
-	// result: (ANDconst [c] x)
+	// result: (Select0 (ANDCCconst [c] x))
 	for {
 		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
 			x := v_0
@@ -4382,9 +3981,11 @@
 			if !(isU16Bit(c)) {
 				continue
 			}
-			v.reset(OpPPC64ANDconst)
-			v.AuxInt = int64ToAuxInt(c)
-			v.AddArg(x)
+			v.reset(OpSelect0)
+			v0 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+			v0.AuxInt = int64ToAuxInt(c)
+			v0.AddArg(x)
+			v.AddArg(v0)
 			return true
 		}
 		break
@@ -4426,7 +4027,7 @@
 		break
 	}
 	// match: (AND (MOVDconst [c]) x:(MOVBZload _ _))
-	// result: (ANDconst [c&0xFF] x)
+	// result: (Select0 (ANDCCconst [c&0xFF] x))
 	for {
 		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
 			if v_0.Op != OpPPC64MOVDconst {
@@ -4437,9 +4038,11 @@
 			if x.Op != OpPPC64MOVBZload {
 				continue
 			}
-			v.reset(OpPPC64ANDconst)
-			v.AuxInt = int64ToAuxInt(c & 0xFF)
-			v.AddArg(x)
+			v.reset(OpSelect0)
+			v0 := b.NewValue0(x.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+			v0.AuxInt = int64ToAuxInt(c & 0xFF)
+			v0.AddArg(x)
+			v.AddArg(v0)
 			return true
 		}
 		break
@@ -4466,242 +4069,6 @@
 	}
 	return false
 }
-func rewriteValuePPC64_OpPPC64ANDconst(v *Value) bool {
-	v_0 := v.Args[0]
-	// match: (ANDconst [m] (ROTLWconst [r] x))
-	// cond: isPPC64WordRotateMask(m)
-	// result: (RLWINM [encodePPC64RotateMask(r,m,32)] x)
-	for {
-		m := auxIntToInt64(v.AuxInt)
-		if v_0.Op != OpPPC64ROTLWconst {
-			break
-		}
-		r := auxIntToInt64(v_0.AuxInt)
-		x := v_0.Args[0]
-		if !(isPPC64WordRotateMask(m)) {
-			break
-		}
-		v.reset(OpPPC64RLWINM)
-		v.AuxInt = int64ToAuxInt(encodePPC64RotateMask(r, m, 32))
-		v.AddArg(x)
-		return true
-	}
-	// match: (ANDconst [m] (ROTLW x r))
-	// cond: isPPC64WordRotateMask(m)
-	// result: (RLWNM [encodePPC64RotateMask(0,m,32)] x r)
-	for {
-		m := auxIntToInt64(v.AuxInt)
-		if v_0.Op != OpPPC64ROTLW {
-			break
-		}
-		r := v_0.Args[1]
-		x := v_0.Args[0]
-		if !(isPPC64WordRotateMask(m)) {
-			break
-		}
-		v.reset(OpPPC64RLWNM)
-		v.AuxInt = int64ToAuxInt(encodePPC64RotateMask(0, m, 32))
-		v.AddArg2(x, r)
-		return true
-	}
-	// match: (ANDconst [m] (SRWconst x [s]))
-	// cond: mergePPC64RShiftMask(m,s,32) == 0
-	// result: (MOVDconst [0])
-	for {
-		m := auxIntToInt64(v.AuxInt)
-		if v_0.Op != OpPPC64SRWconst {
-			break
-		}
-		s := auxIntToInt64(v_0.AuxInt)
-		if !(mergePPC64RShiftMask(m, s, 32) == 0) {
-			break
-		}
-		v.reset(OpPPC64MOVDconst)
-		v.AuxInt = int64ToAuxInt(0)
-		return true
-	}
-	// match: (ANDconst [m] (SRWconst x [s]))
-	// cond: mergePPC64AndSrwi(m,s) != 0
-	// result: (RLWINM [mergePPC64AndSrwi(m,s)] x)
-	for {
-		m := auxIntToInt64(v.AuxInt)
-		if v_0.Op != OpPPC64SRWconst {
-			break
-		}
-		s := auxIntToInt64(v_0.AuxInt)
-		x := v_0.Args[0]
-		if !(mergePPC64AndSrwi(m, s) != 0) {
-			break
-		}
-		v.reset(OpPPC64RLWINM)
-		v.AuxInt = int64ToAuxInt(mergePPC64AndSrwi(m, s))
-		v.AddArg(x)
-		return true
-	}
-	// match: (ANDconst [c] (ANDconst [d] x))
-	// result: (ANDconst [c&d] x)
-	for {
-		c := auxIntToInt64(v.AuxInt)
-		if v_0.Op != OpPPC64ANDconst {
-			break
-		}
-		d := auxIntToInt64(v_0.AuxInt)
-		x := v_0.Args[0]
-		v.reset(OpPPC64ANDconst)
-		v.AuxInt = int64ToAuxInt(c & d)
-		v.AddArg(x)
-		return true
-	}
-	// match: (ANDconst [-1] x)
-	// result: x
-	for {
-		if auxIntToInt64(v.AuxInt) != -1 {
-			break
-		}
-		x := v_0
-		v.copyOf(x)
-		return true
-	}
-	// match: (ANDconst [0] _)
-	// result: (MOVDconst [0])
-	for {
-		if auxIntToInt64(v.AuxInt) != 0 {
-			break
-		}
-		v.reset(OpPPC64MOVDconst)
-		v.AuxInt = int64ToAuxInt(0)
-		return true
-	}
-	// match: (ANDconst [c] y:(MOVBZreg _))
-	// cond: c&0xFF == 0xFF
-	// result: y
-	for {
-		c := auxIntToInt64(v.AuxInt)
-		y := v_0
-		if y.Op != OpPPC64MOVBZreg || !(c&0xFF == 0xFF) {
-			break
-		}
-		v.copyOf(y)
-		return true
-	}
-	// match: (ANDconst [0xFF] y:(MOVBreg _))
-	// result: y
-	for {
-		if auxIntToInt64(v.AuxInt) != 0xFF {
-			break
-		}
-		y := v_0
-		if y.Op != OpPPC64MOVBreg {
-			break
-		}
-		v.copyOf(y)
-		return true
-	}
-	// match: (ANDconst [c] y:(MOVHZreg _))
-	// cond: c&0xFFFF == 0xFFFF
-	// result: y
-	for {
-		c := auxIntToInt64(v.AuxInt)
-		y := v_0
-		if y.Op != OpPPC64MOVHZreg || !(c&0xFFFF == 0xFFFF) {
-			break
-		}
-		v.copyOf(y)
-		return true
-	}
-	// match: (ANDconst [0xFFFF] y:(MOVHreg _))
-	// result: y
-	for {
-		if auxIntToInt64(v.AuxInt) != 0xFFFF {
-			break
-		}
-		y := v_0
-		if y.Op != OpPPC64MOVHreg {
-			break
-		}
-		v.copyOf(y)
-		return true
-	}
-	// match: (ANDconst [c] (MOVBreg x))
-	// result: (ANDconst [c&0xFF] x)
-	for {
-		c := auxIntToInt64(v.AuxInt)
-		if v_0.Op != OpPPC64MOVBreg {
-			break
-		}
-		x := v_0.Args[0]
-		v.reset(OpPPC64ANDconst)
-		v.AuxInt = int64ToAuxInt(c & 0xFF)
-		v.AddArg(x)
-		return true
-	}
-	// match: (ANDconst [c] (MOVBZreg x))
-	// result: (ANDconst [c&0xFF] x)
-	for {
-		c := auxIntToInt64(v.AuxInt)
-		if v_0.Op != OpPPC64MOVBZreg {
-			break
-		}
-		x := v_0.Args[0]
-		v.reset(OpPPC64ANDconst)
-		v.AuxInt = int64ToAuxInt(c & 0xFF)
-		v.AddArg(x)
-		return true
-	}
-	// match: (ANDconst [c] (MOVHreg x))
-	// result: (ANDconst [c&0xFFFF] x)
-	for {
-		c := auxIntToInt64(v.AuxInt)
-		if v_0.Op != OpPPC64MOVHreg {
-			break
-		}
-		x := v_0.Args[0]
-		v.reset(OpPPC64ANDconst)
-		v.AuxInt = int64ToAuxInt(c & 0xFFFF)
-		v.AddArg(x)
-		return true
-	}
-	// match: (ANDconst [c] (MOVHZreg x))
-	// result: (ANDconst [c&0xFFFF] x)
-	for {
-		c := auxIntToInt64(v.AuxInt)
-		if v_0.Op != OpPPC64MOVHZreg {
-			break
-		}
-		x := v_0.Args[0]
-		v.reset(OpPPC64ANDconst)
-		v.AuxInt = int64ToAuxInt(c & 0xFFFF)
-		v.AddArg(x)
-		return true
-	}
-	// match: (ANDconst [c] (MOVWreg x))
-	// result: (ANDconst [c&0xFFFFFFFF] x)
-	for {
-		c := auxIntToInt64(v.AuxInt)
-		if v_0.Op != OpPPC64MOVWreg {
-			break
-		}
-		x := v_0.Args[0]
-		v.reset(OpPPC64ANDconst)
-		v.AuxInt = int64ToAuxInt(c & 0xFFFFFFFF)
-		v.AddArg(x)
-		return true
-	}
-	// match: (ANDconst [c] (MOVWZreg x))
-	// result: (ANDconst [c&0xFFFFFFFF] x)
-	for {
-		c := auxIntToInt64(v.AuxInt)
-		if v_0.Op != OpPPC64MOVWZreg {
-			break
-		}
-		x := v_0.Args[0]
-		v.reset(OpPPC64ANDconst)
-		v.AuxInt = int64ToAuxInt(c & 0xFFFFFFFF)
-		v.AddArg(x)
-		return true
-	}
-	return false
-}
 func rewriteValuePPC64_OpPPC64CLRLSLDI(v *Value) bool {
 	v_0 := v.Args[0]
 	// match: (CLRLSLDI [c] (SRWconst [s] x))
@@ -5291,18 +4658,27 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	// match: (FADD (FMUL x y) z)
+	// cond: x.Block.Func.useFMA(v)
 	// result: (FMADD x y z)
 	for {
 		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
 			if v_0.Op != OpPPC64FMUL {
 				continue
 			}
-			y := v_0.Args[1]
-			x := v_0.Args[0]
-			z := v_1
-			v.reset(OpPPC64FMADD)
-			v.AddArg3(x, y, z)
-			return true
+			_ = v_0.Args[1]
+			v_0_0 := v_0.Args[0]
+			v_0_1 := v_0.Args[1]
+			for _i1 := 0; _i1 <= 1; _i1, v_0_0, v_0_1 = _i1+1, v_0_1, v_0_0 {
+				x := v_0_0
+				y := v_0_1
+				z := v_1
+				if !(x.Block.Func.useFMA(v)) {
+					continue
+				}
+				v.reset(OpPPC64FMADD)
+				v.AddArg3(x, y, z)
+				return true
+			}
 		}
 		break
 	}
@@ -5312,18 +4688,27 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	// match: (FADDS (FMULS x y) z)
+	// cond: x.Block.Func.useFMA(v)
 	// result: (FMADDS x y z)
 	for {
 		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
 			if v_0.Op != OpPPC64FMULS {
 				continue
 			}
-			y := v_0.Args[1]
-			x := v_0.Args[0]
-			z := v_1
-			v.reset(OpPPC64FMADDS)
-			v.AddArg3(x, y, z)
-			return true
+			_ = v_0.Args[1]
+			v_0_0 := v_0.Args[0]
+			v_0_1 := v_0.Args[1]
+			for _i1 := 0; _i1 <= 1; _i1, v_0_0, v_0_1 = _i1+1, v_0_1, v_0_0 {
+				x := v_0_0
+				y := v_0_1
+				z := v_1
+				if !(x.Block.Func.useFMA(v)) {
+					continue
+				}
+				v.reset(OpPPC64FMADDS)
+				v.AddArg3(x, y, z)
+				return true
+			}
 		}
 		break
 	}
@@ -5714,17 +5099,27 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	// match: (FSUB (FMUL x y) z)
+	// cond: x.Block.Func.useFMA(v)
 	// result: (FMSUB x y z)
 	for {
 		if v_0.Op != OpPPC64FMUL {
 			break
 		}
-		y := v_0.Args[1]
-		x := v_0.Args[0]
-		z := v_1
-		v.reset(OpPPC64FMSUB)
-		v.AddArg3(x, y, z)
-		return true
+		_ = v_0.Args[1]
+		v_0_0 := v_0.Args[0]
+		v_0_1 := v_0.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
+			x := v_0_0
+			y := v_0_1
+			z := v_1
+			if !(x.Block.Func.useFMA(v)) {
+				continue
+			}
+			v.reset(OpPPC64FMSUB)
+			v.AddArg3(x, y, z)
+			return true
+		}
+		break
 	}
 	return false
 }
@@ -5732,17 +5127,27 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	// match: (FSUBS (FMULS x y) z)
+	// cond: x.Block.Func.useFMA(v)
 	// result: (FMSUBS x y z)
 	for {
 		if v_0.Op != OpPPC64FMULS {
 			break
 		}
-		y := v_0.Args[1]
-		x := v_0.Args[0]
-		z := v_1
-		v.reset(OpPPC64FMSUBS)
-		v.AddArg3(x, y, z)
-		return true
+		_ = v_0.Args[1]
+		v_0_0 := v_0.Args[0]
+		v_0_1 := v_0.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
+			x := v_0_0
+			y := v_0_1
+			z := v_1
+			if !(x.Block.Func.useFMA(v)) {
+				continue
+			}
+			v.reset(OpPPC64FMSUBS)
+			v.AddArg3(x, y, z)
+			return true
+		}
+		break
 	}
 	return false
 }
@@ -5879,21 +5284,31 @@
 	v_2 := v.Args[2]
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	// match: (ISEL [0] (ANDconst [d] y) (MOVDconst [-1]) (CMPU (ANDconst [d] y) (MOVDconst [c])))
+	b := v.Block
+	typ := &b.Func.Config.Types
+	// match: (ISEL [0] (Select0 (ANDCCconst [d] y)) (MOVDconst [-1]) (CMPU (Select0 (ANDCCconst [d] y)) (MOVDconst [c])))
 	// cond: c >= d
-	// result: (ANDconst [d] y)
+	// result: (Select0 (ANDCCconst [d] y))
 	for {
-		if auxIntToInt32(v.AuxInt) != 0 || v_0.Op != OpPPC64ANDconst {
+		if auxIntToInt32(v.AuxInt) != 0 || v_0.Op != OpSelect0 {
 			break
 		}
-		d := auxIntToInt64(v_0.AuxInt)
-		y := v_0.Args[0]
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpPPC64ANDCCconst {
+			break
+		}
+		d := auxIntToInt64(v_0_0.AuxInt)
+		y := v_0_0.Args[0]
 		if v_1.Op != OpPPC64MOVDconst || auxIntToInt64(v_1.AuxInt) != -1 || v_2.Op != OpPPC64CMPU {
 			break
 		}
 		_ = v_2.Args[1]
 		v_2_0 := v_2.Args[0]
-		if v_2_0.Op != OpPPC64ANDconst || auxIntToInt64(v_2_0.AuxInt) != d || y != v_2_0.Args[0] {
+		if v_2_0.Op != OpSelect0 {
+			break
+		}
+		v_2_0_0 := v_2_0.Args[0]
+		if v_2_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_2_0_0.AuxInt) != d || y != v_2_0_0.Args[0] {
 			break
 		}
 		v_2_1 := v_2.Args[1]
@@ -5904,34 +5319,46 @@
 		if !(c >= d) {
 			break
 		}
-		v.reset(OpPPC64ANDconst)
-		v.AuxInt = int64ToAuxInt(d)
-		v.AddArg(y)
+		v.reset(OpSelect0)
+		v0 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+		v0.AuxInt = int64ToAuxInt(d)
+		v0.AddArg(y)
+		v.AddArg(v0)
 		return true
 	}
-	// match: (ISEL [0] (ANDconst [d] y) (MOVDconst [-1]) (CMPUconst [c] (ANDconst [d] y)))
+	// match: (ISEL [0] (Select0 (ANDCCconst [d] y)) (MOVDconst [-1]) (CMPUconst [c] (Select0 (ANDCCconst [d] y))))
 	// cond: c >= d
-	// result: (ANDconst [d] y)
+	// result: (Select0 (ANDCCconst [d] y))
 	for {
-		if auxIntToInt32(v.AuxInt) != 0 || v_0.Op != OpPPC64ANDconst {
+		if auxIntToInt32(v.AuxInt) != 0 || v_0.Op != OpSelect0 {
 			break
 		}
-		d := auxIntToInt64(v_0.AuxInt)
-		y := v_0.Args[0]
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpPPC64ANDCCconst {
+			break
+		}
+		d := auxIntToInt64(v_0_0.AuxInt)
+		y := v_0_0.Args[0]
 		if v_1.Op != OpPPC64MOVDconst || auxIntToInt64(v_1.AuxInt) != -1 || v_2.Op != OpPPC64CMPUconst {
 			break
 		}
 		c := auxIntToInt64(v_2.AuxInt)
 		v_2_0 := v_2.Args[0]
-		if v_2_0.Op != OpPPC64ANDconst || auxIntToInt64(v_2_0.AuxInt) != d || y != v_2_0.Args[0] || !(c >= d) {
+		if v_2_0.Op != OpSelect0 {
 			break
 		}
-		v.reset(OpPPC64ANDconst)
-		v.AuxInt = int64ToAuxInt(d)
-		v.AddArg(y)
+		v_2_0_0 := v_2_0.Args[0]
+		if v_2_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_2_0_0.AuxInt) != d || y != v_2_0_0.Args[0] || !(c >= d) {
+			break
+		}
+		v.reset(OpSelect0)
+		v0 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+		v0.AuxInt = int64ToAuxInt(d)
+		v0.AddArg(y)
+		v.AddArg(v0)
 		return true
 	}
-	// match: (ISEL [6] x y (CMPWconst [0] (ISELB [c] one cmp)))
+	// match: (ISEL [6] x y (Select1 (ANDCCconst [1] (ISELB [c] one cmp))))
 	// result: (ISEL [c] x y cmp)
 	for {
 		if auxIntToInt32(v.AuxInt) != 6 {
@@ -5939,15 +5366,19 @@
 		}
 		x := v_0
 		y := v_1
-		if v_2.Op != OpPPC64CMPWconst || auxIntToInt32(v_2.AuxInt) != 0 {
+		if v_2.Op != OpSelect1 {
 			break
 		}
 		v_2_0 := v_2.Args[0]
-		if v_2_0.Op != OpPPC64ISELB {
+		if v_2_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_2_0.AuxInt) != 1 {
 			break
 		}
-		c := auxIntToInt32(v_2_0.AuxInt)
-		cmp := v_2_0.Args[1]
+		v_2_0_0 := v_2_0.Args[0]
+		if v_2_0_0.Op != OpPPC64ISELB {
+			break
+		}
+		c := auxIntToInt32(v_2_0_0.AuxInt)
+		cmp := v_2_0_0.Args[1]
 		v.reset(OpPPC64ISEL)
 		v.AuxInt = int32ToAuxInt(c)
 		v.AddArg3(x, y, cmp)
@@ -6187,6 +5618,130 @@
 		v.copyOf(y)
 		return true
 	}
+	// match: (ISEL [2] x y (CMPconst [0] (Select0 (ANDCCconst [n] z))))
+	// result: (ISEL [2] x y (Select1 <types.TypeFlags> (ANDCCconst [n] z )))
+	for {
+		if auxIntToInt32(v.AuxInt) != 2 {
+			break
+		}
+		x := v_0
+		y := v_1
+		if v_2.Op != OpPPC64CMPconst || auxIntToInt64(v_2.AuxInt) != 0 {
+			break
+		}
+		v_2_0 := v_2.Args[0]
+		if v_2_0.Op != OpSelect0 {
+			break
+		}
+		v_2_0_0 := v_2_0.Args[0]
+		if v_2_0_0.Op != OpPPC64ANDCCconst {
+			break
+		}
+		n := auxIntToInt64(v_2_0_0.AuxInt)
+		z := v_2_0_0.Args[0]
+		v.reset(OpPPC64ISEL)
+		v.AuxInt = int32ToAuxInt(2)
+		v0 := b.NewValue0(v.Pos, OpSelect1, types.TypeFlags)
+		v1 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+		v1.AuxInt = int64ToAuxInt(n)
+		v1.AddArg(z)
+		v0.AddArg(v1)
+		v.AddArg3(x, y, v0)
+		return true
+	}
+	// match: (ISEL [2] x y (CMPWconst [0] (Select0 (ANDCCconst [n] z))))
+	// result: (ISEL [2] x y (Select1 <types.TypeFlags> (ANDCCconst [n] z )))
+	for {
+		if auxIntToInt32(v.AuxInt) != 2 {
+			break
+		}
+		x := v_0
+		y := v_1
+		if v_2.Op != OpPPC64CMPWconst || auxIntToInt32(v_2.AuxInt) != 0 {
+			break
+		}
+		v_2_0 := v_2.Args[0]
+		if v_2_0.Op != OpSelect0 {
+			break
+		}
+		v_2_0_0 := v_2_0.Args[0]
+		if v_2_0_0.Op != OpPPC64ANDCCconst {
+			break
+		}
+		n := auxIntToInt64(v_2_0_0.AuxInt)
+		z := v_2_0_0.Args[0]
+		v.reset(OpPPC64ISEL)
+		v.AuxInt = int32ToAuxInt(2)
+		v0 := b.NewValue0(v.Pos, OpSelect1, types.TypeFlags)
+		v1 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+		v1.AuxInt = int64ToAuxInt(n)
+		v1.AddArg(z)
+		v0.AddArg(v1)
+		v.AddArg3(x, y, v0)
+		return true
+	}
+	// match: (ISEL [6] x y (CMPconst [0] (Select0 (ANDCCconst [n] z))))
+	// result: (ISEL [6] x y (Select1 <types.TypeFlags> (ANDCCconst [n] z )))
+	for {
+		if auxIntToInt32(v.AuxInt) != 6 {
+			break
+		}
+		x := v_0
+		y := v_1
+		if v_2.Op != OpPPC64CMPconst || auxIntToInt64(v_2.AuxInt) != 0 {
+			break
+		}
+		v_2_0 := v_2.Args[0]
+		if v_2_0.Op != OpSelect0 {
+			break
+		}
+		v_2_0_0 := v_2_0.Args[0]
+		if v_2_0_0.Op != OpPPC64ANDCCconst {
+			break
+		}
+		n := auxIntToInt64(v_2_0_0.AuxInt)
+		z := v_2_0_0.Args[0]
+		v.reset(OpPPC64ISEL)
+		v.AuxInt = int32ToAuxInt(6)
+		v0 := b.NewValue0(v.Pos, OpSelect1, types.TypeFlags)
+		v1 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+		v1.AuxInt = int64ToAuxInt(n)
+		v1.AddArg(z)
+		v0.AddArg(v1)
+		v.AddArg3(x, y, v0)
+		return true
+	}
+	// match: (ISEL [6] x y (CMPWconst [0] (Select0 (ANDCCconst [n] z))))
+	// result: (ISEL [6] x y (Select1 <types.TypeFlags> (ANDCCconst [n] z )))
+	for {
+		if auxIntToInt32(v.AuxInt) != 6 {
+			break
+		}
+		x := v_0
+		y := v_1
+		if v_2.Op != OpPPC64CMPWconst || auxIntToInt32(v_2.AuxInt) != 0 {
+			break
+		}
+		v_2_0 := v_2.Args[0]
+		if v_2_0.Op != OpSelect0 {
+			break
+		}
+		v_2_0_0 := v_2_0.Args[0]
+		if v_2_0_0.Op != OpPPC64ANDCCconst {
+			break
+		}
+		n := auxIntToInt64(v_2_0_0.AuxInt)
+		z := v_2_0_0.Args[0]
+		v.reset(OpPPC64ISEL)
+		v.AuxInt = int32ToAuxInt(6)
+		v0 := b.NewValue0(v.Pos, OpSelect1, types.TypeFlags)
+		v1 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+		v1.AuxInt = int64ToAuxInt(n)
+		v1.AddArg(z)
+		v0.AddArg(v1)
+		v.AddArg3(x, y, v0)
+		return true
+	}
 	// match: (ISEL [n] x y (InvertFlags bool))
 	// cond: n%4 == 0
 	// result: (ISEL [n+1] x y bool)
@@ -6431,6 +5986,348 @@
 		v.AuxInt = int64ToAuxInt(1)
 		return true
 	}
+	// match: (ISELB [2] x (CMPconst [0] (Select0 (ANDCCconst [1] z))))
+	// result: (XORconst [1] (Select0 <typ.UInt64> (ANDCCconst [1] z )))
+	for {
+		if auxIntToInt32(v.AuxInt) != 2 {
+			break
+		}
+		if v_1.Op != OpPPC64CMPconst || auxIntToInt64(v_1.AuxInt) != 0 {
+			break
+		}
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpSelect0 {
+			break
+		}
+		v_1_0_0 := v_1_0.Args[0]
+		if v_1_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_1_0_0.AuxInt) != 1 {
+			break
+		}
+		z := v_1_0_0.Args[0]
+		v.reset(OpPPC64XORconst)
+		v.AuxInt = int64ToAuxInt(1)
+		v0 := b.NewValue0(v.Pos, OpSelect0, typ.UInt64)
+		v1 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+		v1.AuxInt = int64ToAuxInt(1)
+		v1.AddArg(z)
+		v0.AddArg(v1)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (ISELB [2] x (CMPWconst [0] (Select0 (ANDCCconst [1] z))))
+	// result: (XORconst [1] (Select0 <typ.UInt64> (ANDCCconst [1] z )))
+	for {
+		if auxIntToInt32(v.AuxInt) != 2 {
+			break
+		}
+		if v_1.Op != OpPPC64CMPWconst || auxIntToInt32(v_1.AuxInt) != 0 {
+			break
+		}
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpSelect0 {
+			break
+		}
+		v_1_0_0 := v_1_0.Args[0]
+		if v_1_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_1_0_0.AuxInt) != 1 {
+			break
+		}
+		z := v_1_0_0.Args[0]
+		v.reset(OpPPC64XORconst)
+		v.AuxInt = int64ToAuxInt(1)
+		v0 := b.NewValue0(v.Pos, OpSelect0, typ.UInt64)
+		v1 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+		v1.AuxInt = int64ToAuxInt(1)
+		v1.AddArg(z)
+		v0.AddArg(v1)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (ISELB [6] x (CMPconst [0] (Select0 (ANDCCconst [1] z))))
+	// result: (Select0 <typ.UInt64> (ANDCCconst [1] z ))
+	for {
+		if auxIntToInt32(v.AuxInt) != 6 {
+			break
+		}
+		if v_1.Op != OpPPC64CMPconst || auxIntToInt64(v_1.AuxInt) != 0 {
+			break
+		}
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpSelect0 {
+			break
+		}
+		v_1_0_0 := v_1_0.Args[0]
+		if v_1_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_1_0_0.AuxInt) != 1 {
+			break
+		}
+		z := v_1_0_0.Args[0]
+		v.reset(OpSelect0)
+		v.Type = typ.UInt64
+		v0 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+		v0.AuxInt = int64ToAuxInt(1)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (ISELB [6] x (CMPWconst [0] (Select0 (ANDCCconst [1] z))))
+	// result: (Select0 <typ.UInt64> (ANDCCconst [1] z ))
+	for {
+		if auxIntToInt32(v.AuxInt) != 6 {
+			break
+		}
+		if v_1.Op != OpPPC64CMPWconst || auxIntToInt32(v_1.AuxInt) != 0 {
+			break
+		}
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpSelect0 {
+			break
+		}
+		v_1_0_0 := v_1_0.Args[0]
+		if v_1_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_1_0_0.AuxInt) != 1 {
+			break
+		}
+		z := v_1_0_0.Args[0]
+		v.reset(OpSelect0)
+		v.Type = typ.UInt64
+		v0 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+		v0.AuxInt = int64ToAuxInt(1)
+		v0.AddArg(z)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (ISELB [2] x (CMPWconst [0] (Select0 (ANDCCconst [n] z))))
+	// result: (ISELB [2] x (Select1 <types.TypeFlags> (ANDCCconst [n] z )))
+	for {
+		if auxIntToInt32(v.AuxInt) != 2 {
+			break
+		}
+		x := v_0
+		if v_1.Op != OpPPC64CMPWconst || auxIntToInt32(v_1.AuxInt) != 0 {
+			break
+		}
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpSelect0 {
+			break
+		}
+		v_1_0_0 := v_1_0.Args[0]
+		if v_1_0_0.Op != OpPPC64ANDCCconst {
+			break
+		}
+		n := auxIntToInt64(v_1_0_0.AuxInt)
+		z := v_1_0_0.Args[0]
+		v.reset(OpPPC64ISELB)
+		v.AuxInt = int32ToAuxInt(2)
+		v0 := b.NewValue0(v.Pos, OpSelect1, types.TypeFlags)
+		v1 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+		v1.AuxInt = int64ToAuxInt(n)
+		v1.AddArg(z)
+		v0.AddArg(v1)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (ISELB [6] x (CMPWconst [0] (Select0 (ANDCCconst [n] z))))
+	// result: (ISELB [6] x (Select1 <types.TypeFlags> (ANDCCconst [n] z )))
+	for {
+		if auxIntToInt32(v.AuxInt) != 6 {
+			break
+		}
+		x := v_0
+		if v_1.Op != OpPPC64CMPWconst || auxIntToInt32(v_1.AuxInt) != 0 {
+			break
+		}
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpSelect0 {
+			break
+		}
+		v_1_0_0 := v_1_0.Args[0]
+		if v_1_0_0.Op != OpPPC64ANDCCconst {
+			break
+		}
+		n := auxIntToInt64(v_1_0_0.AuxInt)
+		z := v_1_0_0.Args[0]
+		v.reset(OpPPC64ISELB)
+		v.AuxInt = int32ToAuxInt(6)
+		v0 := b.NewValue0(v.Pos, OpSelect1, types.TypeFlags)
+		v1 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+		v1.AuxInt = int64ToAuxInt(n)
+		v1.AddArg(z)
+		v0.AddArg(v1)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (ISELB [2] x (CMPconst [0] a:(AND y z)))
+	// cond: a.Uses == 1
+	// result: (ISELB [2] x (Select1 <types.TypeFlags> (ANDCC y z )))
+	for {
+		if auxIntToInt32(v.AuxInt) != 2 {
+			break
+		}
+		x := v_0
+		if v_1.Op != OpPPC64CMPconst || auxIntToInt64(v_1.AuxInt) != 0 {
+			break
+		}
+		a := v_1.Args[0]
+		if a.Op != OpPPC64AND {
+			break
+		}
+		z := a.Args[1]
+		y := a.Args[0]
+		if !(a.Uses == 1) {
+			break
+		}
+		v.reset(OpPPC64ISELB)
+		v.AuxInt = int32ToAuxInt(2)
+		v0 := b.NewValue0(v.Pos, OpSelect1, types.TypeFlags)
+		v1 := b.NewValue0(v.Pos, OpPPC64ANDCC, types.NewTuple(typ.Int64, types.TypeFlags))
+		v1.AddArg2(y, z)
+		v0.AddArg(v1)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (ISELB [6] x (CMPconst [0] a:(AND y z)))
+	// cond: a.Uses == 1
+	// result: (ISELB [6] x (Select1 <types.TypeFlags> (ANDCC y z )))
+	for {
+		if auxIntToInt32(v.AuxInt) != 6 {
+			break
+		}
+		x := v_0
+		if v_1.Op != OpPPC64CMPconst || auxIntToInt64(v_1.AuxInt) != 0 {
+			break
+		}
+		a := v_1.Args[0]
+		if a.Op != OpPPC64AND {
+			break
+		}
+		z := a.Args[1]
+		y := a.Args[0]
+		if !(a.Uses == 1) {
+			break
+		}
+		v.reset(OpPPC64ISELB)
+		v.AuxInt = int32ToAuxInt(6)
+		v0 := b.NewValue0(v.Pos, OpSelect1, types.TypeFlags)
+		v1 := b.NewValue0(v.Pos, OpPPC64ANDCC, types.NewTuple(typ.Int64, types.TypeFlags))
+		v1.AddArg2(y, z)
+		v0.AddArg(v1)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (ISELB [2] x (CMPconst [0] o:(OR y z)))
+	// cond: o.Uses == 1
+	// result: (ISELB [2] x (Select1 <types.TypeFlags> (ORCC y z )))
+	for {
+		if auxIntToInt32(v.AuxInt) != 2 {
+			break
+		}
+		x := v_0
+		if v_1.Op != OpPPC64CMPconst || auxIntToInt64(v_1.AuxInt) != 0 {
+			break
+		}
+		o := v_1.Args[0]
+		if o.Op != OpPPC64OR {
+			break
+		}
+		z := o.Args[1]
+		y := o.Args[0]
+		if !(o.Uses == 1) {
+			break
+		}
+		v.reset(OpPPC64ISELB)
+		v.AuxInt = int32ToAuxInt(2)
+		v0 := b.NewValue0(v.Pos, OpSelect1, types.TypeFlags)
+		v1 := b.NewValue0(v.Pos, OpPPC64ORCC, types.NewTuple(typ.Int, types.TypeFlags))
+		v1.AddArg2(y, z)
+		v0.AddArg(v1)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (ISELB [6] x (CMPconst [0] o:(OR y z)))
+	// cond: o.Uses == 1
+	// result: (ISELB [6] x (Select1 <types.TypeFlags> (ORCC y z )))
+	for {
+		if auxIntToInt32(v.AuxInt) != 6 {
+			break
+		}
+		x := v_0
+		if v_1.Op != OpPPC64CMPconst || auxIntToInt64(v_1.AuxInt) != 0 {
+			break
+		}
+		o := v_1.Args[0]
+		if o.Op != OpPPC64OR {
+			break
+		}
+		z := o.Args[1]
+		y := o.Args[0]
+		if !(o.Uses == 1) {
+			break
+		}
+		v.reset(OpPPC64ISELB)
+		v.AuxInt = int32ToAuxInt(6)
+		v0 := b.NewValue0(v.Pos, OpSelect1, types.TypeFlags)
+		v1 := b.NewValue0(v.Pos, OpPPC64ORCC, types.NewTuple(typ.Int, types.TypeFlags))
+		v1.AddArg2(y, z)
+		v0.AddArg(v1)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (ISELB [2] x (CMPconst [0] a:(XOR y z)))
+	// cond: a.Uses == 1
+	// result: (ISELB [2] x (Select1 <types.TypeFlags> (XORCC y z )))
+	for {
+		if auxIntToInt32(v.AuxInt) != 2 {
+			break
+		}
+		x := v_0
+		if v_1.Op != OpPPC64CMPconst || auxIntToInt64(v_1.AuxInt) != 0 {
+			break
+		}
+		a := v_1.Args[0]
+		if a.Op != OpPPC64XOR {
+			break
+		}
+		z := a.Args[1]
+		y := a.Args[0]
+		if !(a.Uses == 1) {
+			break
+		}
+		v.reset(OpPPC64ISELB)
+		v.AuxInt = int32ToAuxInt(2)
+		v0 := b.NewValue0(v.Pos, OpSelect1, types.TypeFlags)
+		v1 := b.NewValue0(v.Pos, OpPPC64XORCC, types.NewTuple(typ.Int, types.TypeFlags))
+		v1.AddArg2(y, z)
+		v0.AddArg(v1)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (ISELB [6] x (CMPconst [0] a:(XOR y z)))
+	// cond: a.Uses == 1
+	// result: (ISELB [6] x (Select1 <types.TypeFlags> (XORCC y z )))
+	for {
+		if auxIntToInt32(v.AuxInt) != 6 {
+			break
+		}
+		x := v_0
+		if v_1.Op != OpPPC64CMPconst || auxIntToInt64(v_1.AuxInt) != 0 {
+			break
+		}
+		a := v_1.Args[0]
+		if a.Op != OpPPC64XOR {
+			break
+		}
+		z := a.Args[1]
+		y := a.Args[0]
+		if !(a.Uses == 1) {
+			break
+		}
+		v.reset(OpPPC64ISELB)
+		v.AuxInt = int32ToAuxInt(6)
+		v0 := b.NewValue0(v.Pos, OpSelect1, types.TypeFlags)
+		v1 := b.NewValue0(v.Pos, OpPPC64XORCC, types.NewTuple(typ.Int, types.TypeFlags))
+		v1.AddArg2(y, z)
+		v0.AddArg(v1)
+		v.AddArg2(x, v0)
+		return true
+	}
 	// match: (ISELB [n] (MOVDconst [1]) (InvertFlags bool))
 	// cond: n%4 == 0
 	// result: (ISELB [n+1] (MOVDconst [1]) bool)
@@ -6761,15 +6658,19 @@
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
-	// match: (MOVBZreg y:(ANDconst [c] _))
+	// match: (MOVBZreg y:(Select0 (ANDCCconst [c] _)))
 	// cond: uint64(c) <= 0xFF
 	// result: y
 	for {
 		y := v_0
-		if y.Op != OpPPC64ANDconst {
+		if y.Op != OpSelect0 {
 			break
 		}
-		c := auxIntToInt64(y.AuxInt)
+		y_0 := y.Args[0]
+		if y_0.Op != OpPPC64ANDCCconst {
+			break
+		}
+		c := auxIntToInt64(y_0.AuxInt)
 		if !(uint64(c) <= 0xFF) {
 			break
 		}
@@ -7083,15 +6984,19 @@
 		}
 		break
 	}
-	// match: (MOVBZreg z:(ANDconst [c] (MOVBZload ptr x)))
+	// match: (MOVBZreg z:(Select0 (ANDCCconst [c] (MOVBZload ptr x))))
 	// result: z
 	for {
 		z := v_0
-		if z.Op != OpPPC64ANDconst {
+		if z.Op != OpSelect0 {
 			break
 		}
 		z_0 := z.Args[0]
-		if z_0.Op != OpPPC64MOVBZload {
+		if z_0.Op != OpPPC64ANDCCconst {
+			break
+		}
+		z_0_0 := z_0.Args[0]
+		if z_0_0.Op != OpPPC64MOVBZload {
 			break
 		}
 		v.copyOf(z)
@@ -7182,15 +7087,19 @@
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
-	// match: (MOVBreg y:(ANDconst [c] _))
+	// match: (MOVBreg y:(Select0 (ANDCCconst [c] _)))
 	// cond: uint64(c) <= 0x7F
 	// result: y
 	for {
 		y := v_0
-		if y.Op != OpPPC64ANDconst {
+		if y.Op != OpSelect0 {
 			break
 		}
-		c := auxIntToInt64(y.AuxInt)
+		y_0 := y.Args[0]
+		if y_0.Op != OpPPC64ANDCCconst {
+			break
+		}
+		c := auxIntToInt64(y_0.AuxInt)
 		if !(uint64(c) <= 0x7F) {
 			break
 		}
@@ -8926,15 +8835,19 @@
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
-	// match: (MOVHZreg y:(ANDconst [c] _))
+	// match: (MOVHZreg y:(Select0 (ANDCCconst [c] _)))
 	// cond: uint64(c) <= 0xFFFF
 	// result: y
 	for {
 		y := v_0
-		if y.Op != OpPPC64ANDconst {
+		if y.Op != OpSelect0 {
 			break
 		}
-		c := auxIntToInt64(y.AuxInt)
+		y_0 := y.Args[0]
+		if y_0.Op != OpPPC64ANDCCconst {
+			break
+		}
+		c := auxIntToInt64(y_0.AuxInt)
 		if !(uint64(c) <= 0xFFFF) {
 			break
 		}
@@ -9216,29 +9129,19 @@
 		}
 		break
 	}
-	// match: (MOVHZreg z:(ANDconst [c] (MOVBZload ptr x)))
+	// match: (MOVHZreg z:(Select0 (ANDCCconst [c] (MOVBZload ptr x))))
 	// result: z
 	for {
 		z := v_0
-		if z.Op != OpPPC64ANDconst {
+		if z.Op != OpSelect0 {
 			break
 		}
 		z_0 := z.Args[0]
-		if z_0.Op != OpPPC64MOVBZload {
+		if z_0.Op != OpPPC64ANDCCconst {
 			break
 		}
-		v.copyOf(z)
-		return true
-	}
-	// match: (MOVHZreg z:(ANDconst [c] (MOVHZload ptr x)))
-	// result: z
-	for {
-		z := v_0
-		if z.Op != OpPPC64ANDconst {
-			break
-		}
-		z_0 := z.Args[0]
-		if z_0.Op != OpPPC64MOVHZload {
+		z_0_0 := z_0.Args[0]
+		if z_0_0.Op != OpPPC64MOVBZload {
 			break
 		}
 		v.copyOf(z)
@@ -9263,6 +9166,24 @@
 		}
 		break
 	}
+	// match: (MOVHZreg z:(Select0 (ANDCCconst [c] (MOVHZload ptr x))))
+	// result: z
+	for {
+		z := v_0
+		if z.Op != OpSelect0 {
+			break
+		}
+		z_0 := z.Args[0]
+		if z_0.Op != OpPPC64ANDCCconst {
+			break
+		}
+		z_0_0 := z_0.Args[0]
+		if z_0_0.Op != OpPPC64MOVHZload {
+			break
+		}
+		v.copyOf(z)
+		return true
+	}
 	// match: (MOVHZreg x:(MOVBZload _ _))
 	// result: x
 	for {
@@ -9448,15 +9369,19 @@
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
-	// match: (MOVHreg y:(ANDconst [c] _))
+	// match: (MOVHreg y:(Select0 (ANDCCconst [c] _)))
 	// cond: uint64(c) <= 0x7FFF
 	// result: y
 	for {
 		y := v_0
-		if y.Op != OpPPC64ANDconst {
+		if y.Op != OpSelect0 {
 			break
 		}
-		c := auxIntToInt64(y.AuxInt)
+		y_0 := y.Args[0]
+		if y_0.Op != OpPPC64ANDCCconst {
+			break
+		}
+		c := auxIntToInt64(y_0.AuxInt)
 		if !(uint64(c) <= 0x7FFF) {
 			break
 		}
@@ -10222,15 +10147,19 @@
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
-	// match: (MOVWZreg y:(ANDconst [c] _))
+	// match: (MOVWZreg y:(Select0 (ANDCCconst [c] _)))
 	// cond: uint64(c) <= 0xFFFFFFFF
 	// result: y
 	for {
 		y := v_0
-		if y.Op != OpPPC64ANDconst {
+		if y.Op != OpSelect0 {
 			break
 		}
-		c := auxIntToInt64(y.AuxInt)
+		y_0 := y.Args[0]
+		if y_0.Op != OpPPC64ANDCCconst {
+			break
+		}
+		c := auxIntToInt64(y_0.AuxInt)
 		if !(uint64(c) <= 0xFFFFFFFF) {
 			break
 		}
@@ -10485,43 +10414,19 @@
 		}
 		break
 	}
-	// match: (MOVWZreg z:(ANDconst [c] (MOVBZload ptr x)))
+	// match: (MOVWZreg z:(Select0 (ANDCCconst [c] (MOVBZload ptr x))))
 	// result: z
 	for {
 		z := v_0
-		if z.Op != OpPPC64ANDconst {
+		if z.Op != OpSelect0 {
 			break
 		}
 		z_0 := z.Args[0]
-		if z_0.Op != OpPPC64MOVBZload {
+		if z_0.Op != OpPPC64ANDCCconst {
 			break
 		}
-		v.copyOf(z)
-		return true
-	}
-	// match: (MOVWZreg z:(ANDconst [c] (MOVHZload ptr x)))
-	// result: z
-	for {
-		z := v_0
-		if z.Op != OpPPC64ANDconst {
-			break
-		}
-		z_0 := z.Args[0]
-		if z_0.Op != OpPPC64MOVHZload {
-			break
-		}
-		v.copyOf(z)
-		return true
-	}
-	// match: (MOVWZreg z:(ANDconst [c] (MOVWZload ptr x)))
-	// result: z
-	for {
-		z := v_0
-		if z.Op != OpPPC64ANDconst {
-			break
-		}
-		z_0 := z.Args[0]
-		if z_0.Op != OpPPC64MOVWZload {
+		z_0_0 := z_0.Args[0]
+		if z_0_0.Op != OpPPC64MOVBZload {
 			break
 		}
 		v.copyOf(z)
@@ -10546,6 +10451,42 @@
 		}
 		break
 	}
+	// match: (MOVWZreg z:(Select0 (ANDCCconst [c] (MOVHZload ptr x))))
+	// result: z
+	for {
+		z := v_0
+		if z.Op != OpSelect0 {
+			break
+		}
+		z_0 := z.Args[0]
+		if z_0.Op != OpPPC64ANDCCconst {
+			break
+		}
+		z_0_0 := z_0.Args[0]
+		if z_0_0.Op != OpPPC64MOVHZload {
+			break
+		}
+		v.copyOf(z)
+		return true
+	}
+	// match: (MOVWZreg z:(Select0 (ANDCCconst [c] (MOVWZload ptr x))))
+	// result: z
+	for {
+		z := v_0
+		if z.Op != OpSelect0 {
+			break
+		}
+		z_0 := z.Args[0]
+		if z_0.Op != OpPPC64ANDCCconst {
+			break
+		}
+		z_0_0 := z_0.Args[0]
+		if z_0_0.Op != OpPPC64MOVWZload {
+			break
+		}
+		v.copyOf(z)
+		return true
+	}
 	// match: (MOVWZreg x:(MOVBZload _ _))
 	// result: x
 	for {
@@ -10765,15 +10706,19 @@
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
-	// match: (MOVWreg y:(ANDconst [c] _))
+	// match: (MOVWreg y:(Select0 (ANDCCconst [c] _)))
 	// cond: uint64(c) <= 0xFFFF
 	// result: y
 	for {
 		y := v_0
-		if y.Op != OpPPC64ANDconst {
+		if y.Op != OpSelect0 {
 			break
 		}
-		c := auxIntToInt64(y.AuxInt)
+		y_0 := y.Args[0]
+		if y_0.Op != OpPPC64ANDCCconst {
+			break
+		}
+		c := auxIntToInt64(y_0.AuxInt)
 		if !(uint64(c) <= 0xFFFF) {
 			break
 		}
@@ -11525,204 +11470,6 @@
 	b := v.Block
 	config := b.Func.Config
 	typ := &b.Func.Config.Types
-	// match: ( OR (SLDconst x [c]) (SRDconst x [d]))
-	// cond: d == 64-c
-	// result: (ROTLconst [c] x)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpPPC64SLDconst {
-				continue
-			}
-			c := auxIntToInt64(v_0.AuxInt)
-			x := v_0.Args[0]
-			if v_1.Op != OpPPC64SRDconst {
-				continue
-			}
-			d := auxIntToInt64(v_1.AuxInt)
-			if x != v_1.Args[0] || !(d == 64-c) {
-				continue
-			}
-			v.reset(OpPPC64ROTLconst)
-			v.AuxInt = int64ToAuxInt(c)
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
-	// match: ( OR (SLWconst x [c]) (SRWconst x [d]))
-	// cond: d == 32-c
-	// result: (ROTLWconst [c] x)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpPPC64SLWconst {
-				continue
-			}
-			c := auxIntToInt64(v_0.AuxInt)
-			x := v_0.Args[0]
-			if v_1.Op != OpPPC64SRWconst {
-				continue
-			}
-			d := auxIntToInt64(v_1.AuxInt)
-			if x != v_1.Args[0] || !(d == 32-c) {
-				continue
-			}
-			v.reset(OpPPC64ROTLWconst)
-			v.AuxInt = int64ToAuxInt(c)
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
-	// match: ( OR (SLD x (ANDconst [63] y)) (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y))))
-	// result: (ROTL x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpPPC64SLD {
-				continue
-			}
-			_ = v_0.Args[1]
-			x := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpPPC64ANDconst || auxIntToInt64(v_0_1.AuxInt) != 63 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpPPC64SRD {
-				continue
-			}
-			_ = v_1.Args[1]
-			if x != v_1.Args[0] {
-				continue
-			}
-			v_1_1 := v_1.Args[1]
-			if v_1_1.Op != OpPPC64SUB || v_1_1.Type != typ.UInt {
-				continue
-			}
-			_ = v_1_1.Args[1]
-			v_1_1_0 := v_1_1.Args[0]
-			if v_1_1_0.Op != OpPPC64MOVDconst || auxIntToInt64(v_1_1_0.AuxInt) != 64 {
-				continue
-			}
-			v_1_1_1 := v_1_1.Args[1]
-			if v_1_1_1.Op != OpPPC64ANDconst || v_1_1_1.Type != typ.UInt || auxIntToInt64(v_1_1_1.AuxInt) != 63 || y != v_1_1_1.Args[0] {
-				continue
-			}
-			v.reset(OpPPC64ROTL)
-			v.AddArg2(x, y)
-			return true
-		}
-		break
-	}
-	// match: ( OR (SLD x (ANDconst [63] y)) (SRD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y))))
-	// result: (ROTL x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpPPC64SLD {
-				continue
-			}
-			_ = v_0.Args[1]
-			x := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpPPC64ANDconst || auxIntToInt64(v_0_1.AuxInt) != 63 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpPPC64SRD {
-				continue
-			}
-			_ = v_1.Args[1]
-			if x != v_1.Args[0] {
-				continue
-			}
-			v_1_1 := v_1.Args[1]
-			if v_1_1.Op != OpPPC64SUBFCconst || v_1_1.Type != typ.UInt || auxIntToInt64(v_1_1.AuxInt) != 64 {
-				continue
-			}
-			v_1_1_0 := v_1_1.Args[0]
-			if v_1_1_0.Op != OpPPC64ANDconst || v_1_1_0.Type != typ.UInt || auxIntToInt64(v_1_1_0.AuxInt) != 63 || y != v_1_1_0.Args[0] {
-				continue
-			}
-			v.reset(OpPPC64ROTL)
-			v.AddArg2(x, y)
-			return true
-		}
-		break
-	}
-	// match: ( OR (SLW x (ANDconst [31] y)) (SRW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y))))
-	// result: (ROTLW x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpPPC64SLW {
-				continue
-			}
-			_ = v_0.Args[1]
-			x := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpPPC64ANDconst || auxIntToInt64(v_0_1.AuxInt) != 31 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpPPC64SRW {
-				continue
-			}
-			_ = v_1.Args[1]
-			if x != v_1.Args[0] {
-				continue
-			}
-			v_1_1 := v_1.Args[1]
-			if v_1_1.Op != OpPPC64SUBFCconst || v_1_1.Type != typ.UInt || auxIntToInt64(v_1_1.AuxInt) != 32 {
-				continue
-			}
-			v_1_1_0 := v_1_1.Args[0]
-			if v_1_1_0.Op != OpPPC64ANDconst || v_1_1_0.Type != typ.UInt || auxIntToInt64(v_1_1_0.AuxInt) != 31 || y != v_1_1_0.Args[0] {
-				continue
-			}
-			v.reset(OpPPC64ROTLW)
-			v.AddArg2(x, y)
-			return true
-		}
-		break
-	}
-	// match: ( OR (SLW x (ANDconst [31] y)) (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y))))
-	// result: (ROTLW x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpPPC64SLW {
-				continue
-			}
-			_ = v_0.Args[1]
-			x := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpPPC64ANDconst || auxIntToInt64(v_0_1.AuxInt) != 31 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpPPC64SRW {
-				continue
-			}
-			_ = v_1.Args[1]
-			if x != v_1.Args[0] {
-				continue
-			}
-			v_1_1 := v_1.Args[1]
-			if v_1_1.Op != OpPPC64SUB || v_1_1.Type != typ.UInt {
-				continue
-			}
-			_ = v_1_1.Args[1]
-			v_1_1_0 := v_1_1.Args[0]
-			if v_1_1_0.Op != OpPPC64MOVDconst || auxIntToInt64(v_1_1_0.AuxInt) != 32 {
-				continue
-			}
-			v_1_1_1 := v_1_1.Args[1]
-			if v_1_1_1.Op != OpPPC64ANDconst || v_1_1_1.Type != typ.UInt || auxIntToInt64(v_1_1_1.AuxInt) != 31 || y != v_1_1_1.Args[0] {
-				continue
-			}
-			v.reset(OpPPC64ROTLW)
-			v.AddArg2(x, y)
-			return true
-		}
-		break
-	}
 	// match: (OR x (NOR y y))
 	// result: (ORN x y)
 	for {
@@ -13201,16 +12948,20 @@
 		}
 		break
 	}
-	// match: (ROTLWconst [r] (ANDconst [m] x))
+	// match: (ROTLWconst [r] (Select0 (ANDCCconst [m] x)))
 	// cond: isPPC64WordRotateMask(m)
 	// result: (RLWINM [encodePPC64RotateMask(r,rotateLeft32(m,r),32)] x)
 	for {
 		r := auxIntToInt64(v.AuxInt)
-		if v_0.Op != OpPPC64ANDconst {
+		if v_0.Op != OpSelect0 {
 			break
 		}
-		m := auxIntToInt64(v_0.AuxInt)
-		x := v_0.Args[0]
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpPPC64ANDCCconst {
+			break
+		}
+		m := auxIntToInt64(v_0_0.AuxInt)
+		x := v_0_0.Args[0]
 		if !(isPPC64WordRotateMask(m)) {
 			break
 		}
@@ -13313,17 +13064,21 @@
 		v.AddArg(x)
 		return true
 	}
-	// match: (SLDconst [c] z:(ANDconst [d] x))
+	// match: (SLDconst [c] z:(Select0 (ANDCCconst [d] x)))
 	// cond: z.Uses == 1 && isPPC64ValidShiftMask(d) && c <= (64-getPPC64ShiftMaskLength(d))
 	// result: (CLRLSLDI [newPPC64ShiftAuxInt(c,64-getPPC64ShiftMaskLength(d),63,64)] x)
 	for {
 		c := auxIntToInt64(v.AuxInt)
 		z := v_0
-		if z.Op != OpPPC64ANDconst {
+		if z.Op != OpSelect0 {
 			break
 		}
-		d := auxIntToInt64(z.AuxInt)
-		x := z.Args[0]
+		z_0 := z.Args[0]
+		if z_0.Op != OpPPC64ANDCCconst {
+			break
+		}
+		d := auxIntToInt64(z_0.AuxInt)
+		x := z_0.Args[0]
 		if !(z.Uses == 1 && isPPC64ValidShiftMask(d) && c <= (64-getPPC64ShiftMaskLength(d))) {
 			break
 		}
@@ -13436,17 +13191,21 @@
 		v.AddArg(x)
 		return true
 	}
-	// match: (SLWconst [c] z:(ANDconst [d] x))
+	// match: (SLWconst [c] z:(Select0 (ANDCCconst [d] x)))
 	// cond: z.Uses == 1 && isPPC64ValidShiftMask(d) && c<=(32-getPPC64ShiftMaskLength(d))
 	// result: (CLRLSLWI [newPPC64ShiftAuxInt(c,32-getPPC64ShiftMaskLength(d),31,32)] x)
 	for {
 		c := auxIntToInt64(v.AuxInt)
 		z := v_0
-		if z.Op != OpPPC64ANDconst {
+		if z.Op != OpSelect0 {
 			break
 		}
-		d := auxIntToInt64(z.AuxInt)
-		x := z.Args[0]
+		z_0 := z.Args[0]
+		if z_0.Op != OpPPC64ANDCCconst {
+			break
+		}
+		d := auxIntToInt64(z_0.AuxInt)
+		x := z_0.Args[0]
 		if !(z.Uses == 1 && isPPC64ValidShiftMask(d) && c <= (32-getPPC64ShiftMaskLength(d))) {
 			break
 		}
@@ -13577,15 +13336,19 @@
 }
 func rewriteValuePPC64_OpPPC64SRWconst(v *Value) bool {
 	v_0 := v.Args[0]
-	// match: (SRWconst (ANDconst [m] x) [s])
+	// match: (SRWconst (Select0 (ANDCCconst [m] x)) [s])
 	// cond: mergePPC64RShiftMask(m>>uint(s),s,32) == 0
 	// result: (MOVDconst [0])
 	for {
 		s := auxIntToInt64(v.AuxInt)
-		if v_0.Op != OpPPC64ANDconst {
+		if v_0.Op != OpSelect0 {
 			break
 		}
-		m := auxIntToInt64(v_0.AuxInt)
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpPPC64ANDCCconst {
+			break
+		}
+		m := auxIntToInt64(v_0_0.AuxInt)
 		if !(mergePPC64RShiftMask(m>>uint(s), s, 32) == 0) {
 			break
 		}
@@ -13593,16 +13356,20 @@
 		v.AuxInt = int64ToAuxInt(0)
 		return true
 	}
-	// match: (SRWconst (ANDconst [m] x) [s])
+	// match: (SRWconst (Select0 (ANDCCconst [m] x)) [s])
 	// cond: mergePPC64AndSrwi(m>>uint(s),s) != 0
 	// result: (RLWINM [mergePPC64AndSrwi(m>>uint(s),s)] x)
 	for {
 		s := auxIntToInt64(v.AuxInt)
-		if v_0.Op != OpPPC64ANDconst {
+		if v_0.Op != OpSelect0 {
 			break
 		}
-		m := auxIntToInt64(v_0.AuxInt)
-		x := v_0.Args[0]
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpPPC64ANDCCconst {
+			break
+		}
+		m := auxIntToInt64(v_0_0.AuxInt)
+		x := v_0_0.Args[0]
 		if !(mergePPC64AndSrwi(m>>uint(s), s) != 0) {
 			break
 		}
@@ -13781,206 +13548,6 @@
 func rewriteValuePPC64_OpPPC64XOR(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
-	b := v.Block
-	typ := &b.Func.Config.Types
-	// match: (XOR (SLDconst x [c]) (SRDconst x [d]))
-	// cond: d == 64-c
-	// result: (ROTLconst [c] x)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpPPC64SLDconst {
-				continue
-			}
-			c := auxIntToInt64(v_0.AuxInt)
-			x := v_0.Args[0]
-			if v_1.Op != OpPPC64SRDconst {
-				continue
-			}
-			d := auxIntToInt64(v_1.AuxInt)
-			if x != v_1.Args[0] || !(d == 64-c) {
-				continue
-			}
-			v.reset(OpPPC64ROTLconst)
-			v.AuxInt = int64ToAuxInt(c)
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
-	// match: (XOR (SLWconst x [c]) (SRWconst x [d]))
-	// cond: d == 32-c
-	// result: (ROTLWconst [c] x)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpPPC64SLWconst {
-				continue
-			}
-			c := auxIntToInt64(v_0.AuxInt)
-			x := v_0.Args[0]
-			if v_1.Op != OpPPC64SRWconst {
-				continue
-			}
-			d := auxIntToInt64(v_1.AuxInt)
-			if x != v_1.Args[0] || !(d == 32-c) {
-				continue
-			}
-			v.reset(OpPPC64ROTLWconst)
-			v.AuxInt = int64ToAuxInt(c)
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
-	// match: (XOR (SLD x (ANDconst [63] y)) (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y))))
-	// result: (ROTL x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpPPC64SLD {
-				continue
-			}
-			_ = v_0.Args[1]
-			x := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpPPC64ANDconst || auxIntToInt64(v_0_1.AuxInt) != 63 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpPPC64SRD {
-				continue
-			}
-			_ = v_1.Args[1]
-			if x != v_1.Args[0] {
-				continue
-			}
-			v_1_1 := v_1.Args[1]
-			if v_1_1.Op != OpPPC64SUB || v_1_1.Type != typ.UInt {
-				continue
-			}
-			_ = v_1_1.Args[1]
-			v_1_1_0 := v_1_1.Args[0]
-			if v_1_1_0.Op != OpPPC64MOVDconst || auxIntToInt64(v_1_1_0.AuxInt) != 64 {
-				continue
-			}
-			v_1_1_1 := v_1_1.Args[1]
-			if v_1_1_1.Op != OpPPC64ANDconst || v_1_1_1.Type != typ.UInt || auxIntToInt64(v_1_1_1.AuxInt) != 63 || y != v_1_1_1.Args[0] {
-				continue
-			}
-			v.reset(OpPPC64ROTL)
-			v.AddArg2(x, y)
-			return true
-		}
-		break
-	}
-	// match: (XOR (SLD x (ANDconst [63] y)) (SRD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y))))
-	// result: (ROTL x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpPPC64SLD {
-				continue
-			}
-			_ = v_0.Args[1]
-			x := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpPPC64ANDconst || auxIntToInt64(v_0_1.AuxInt) != 63 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpPPC64SRD {
-				continue
-			}
-			_ = v_1.Args[1]
-			if x != v_1.Args[0] {
-				continue
-			}
-			v_1_1 := v_1.Args[1]
-			if v_1_1.Op != OpPPC64SUBFCconst || v_1_1.Type != typ.UInt || auxIntToInt64(v_1_1.AuxInt) != 64 {
-				continue
-			}
-			v_1_1_0 := v_1_1.Args[0]
-			if v_1_1_0.Op != OpPPC64ANDconst || v_1_1_0.Type != typ.UInt || auxIntToInt64(v_1_1_0.AuxInt) != 63 || y != v_1_1_0.Args[0] {
-				continue
-			}
-			v.reset(OpPPC64ROTL)
-			v.AddArg2(x, y)
-			return true
-		}
-		break
-	}
-	// match: (XOR (SLW x (ANDconst [31] y)) (SRW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y))))
-	// result: (ROTLW x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpPPC64SLW {
-				continue
-			}
-			_ = v_0.Args[1]
-			x := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpPPC64ANDconst || auxIntToInt64(v_0_1.AuxInt) != 31 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpPPC64SRW {
-				continue
-			}
-			_ = v_1.Args[1]
-			if x != v_1.Args[0] {
-				continue
-			}
-			v_1_1 := v_1.Args[1]
-			if v_1_1.Op != OpPPC64SUBFCconst || v_1_1.Type != typ.UInt || auxIntToInt64(v_1_1.AuxInt) != 32 {
-				continue
-			}
-			v_1_1_0 := v_1_1.Args[0]
-			if v_1_1_0.Op != OpPPC64ANDconst || v_1_1_0.Type != typ.UInt || auxIntToInt64(v_1_1_0.AuxInt) != 31 || y != v_1_1_0.Args[0] {
-				continue
-			}
-			v.reset(OpPPC64ROTLW)
-			v.AddArg2(x, y)
-			return true
-		}
-		break
-	}
-	// match: (XOR (SLW x (ANDconst [31] y)) (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y))))
-	// result: (ROTLW x y)
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpPPC64SLW {
-				continue
-			}
-			_ = v_0.Args[1]
-			x := v_0.Args[0]
-			v_0_1 := v_0.Args[1]
-			if v_0_1.Op != OpPPC64ANDconst || auxIntToInt64(v_0_1.AuxInt) != 31 {
-				continue
-			}
-			y := v_0_1.Args[0]
-			if v_1.Op != OpPPC64SRW {
-				continue
-			}
-			_ = v_1.Args[1]
-			if x != v_1.Args[0] {
-				continue
-			}
-			v_1_1 := v_1.Args[1]
-			if v_1_1.Op != OpPPC64SUB || v_1_1.Type != typ.UInt {
-				continue
-			}
-			_ = v_1_1.Args[1]
-			v_1_1_0 := v_1_1.Args[0]
-			if v_1_1_0.Op != OpPPC64MOVDconst || auxIntToInt64(v_1_1_0.AuxInt) != 32 {
-				continue
-			}
-			v_1_1_1 := v_1_1.Args[1]
-			if v_1_1_1.Op != OpPPC64ANDconst || v_1_1_1.Type != typ.UInt || auxIntToInt64(v_1_1_1.AuxInt) != 31 || y != v_1_1_1.Args[0] {
-				continue
-			}
-			v.reset(OpPPC64ROTLW)
-			v.AddArg2(x, y)
-			return true
-		}
-		break
-	}
 	// match: (XOR (MOVDconst [c]) (MOVDconst [d]))
 	// result: (MOVDconst [c^d])
 	for {
@@ -14260,58 +13827,6 @@
 	}
 	return false
 }
-func rewriteValuePPC64_OpRotateLeft32(v *Value) bool {
-	v_1 := v.Args[1]
-	v_0 := v.Args[0]
-	// match: (RotateLeft32 x (MOVDconst [c]))
-	// result: (ROTLWconst [c&31] x)
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64MOVDconst {
-			break
-		}
-		c := auxIntToInt64(v_1.AuxInt)
-		v.reset(OpPPC64ROTLWconst)
-		v.AuxInt = int64ToAuxInt(c & 31)
-		v.AddArg(x)
-		return true
-	}
-	// match: (RotateLeft32 x y)
-	// result: (ROTLW x y)
-	for {
-		x := v_0
-		y := v_1
-		v.reset(OpPPC64ROTLW)
-		v.AddArg2(x, y)
-		return true
-	}
-}
-func rewriteValuePPC64_OpRotateLeft64(v *Value) bool {
-	v_1 := v.Args[1]
-	v_0 := v.Args[0]
-	// match: (RotateLeft64 x (MOVDconst [c]))
-	// result: (ROTLconst [c&63] x)
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64MOVDconst {
-			break
-		}
-		c := auxIntToInt64(v_1.AuxInt)
-		v.reset(OpPPC64ROTLconst)
-		v.AuxInt = int64ToAuxInt(c & 63)
-		v.AddArg(x)
-		return true
-	}
-	// match: (RotateLeft64 x y)
-	// result: (ROTL x y)
-	for {
-		x := v_0
-		y := v_1
-		v.reset(OpPPC64ROTL)
-		v.AddArg2(x, y)
-		return true
-	}
-}
 func rewriteValuePPC64_OpRotateLeft8(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
@@ -14388,25 +13903,6 @@
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
-	// match: (Rsh16Ux32 x (MOVDconst [c]))
-	// cond: uint32(c) < 16
-	// result: (SRWconst (ZeroExt16to32 x) [c&15])
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64MOVDconst {
-			break
-		}
-		c := auxIntToInt64(v_1.AuxInt)
-		if !(uint32(c) < 16) {
-			break
-		}
-		v.reset(OpPPC64SRWconst)
-		v.AuxInt = int64ToAuxInt(c & 15)
-		v0 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
-		v0.AddArg(x)
-		v.AddArg(v0)
-		return true
-	}
 	// match: (Rsh16Ux32 x y)
 	// cond: shiftIsBounded(v)
 	// result: (SRW (MOVHZreg x) y)
@@ -14448,21 +13944,6 @@
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
-	// match: (Rsh16Ux64 _ (MOVDconst [c]))
-	// cond: uint64(c) >= 16
-	// result: (MOVDconst [0])
-	for {
-		if v_1.Op != OpPPC64MOVDconst {
-			break
-		}
-		c := auxIntToInt64(v_1.AuxInt)
-		if !(uint64(c) >= 16) {
-			break
-		}
-		v.reset(OpPPC64MOVDconst)
-		v.AuxInt = int64ToAuxInt(0)
-		return true
-	}
 	// match: (Rsh16Ux64 x (MOVDconst [c]))
 	// cond: uint64(c) < 16
 	// result: (SRWconst (ZeroExt16to32 x) [c])
@@ -14609,25 +14090,6 @@
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
-	// match: (Rsh16x32 x (MOVDconst [c]))
-	// cond: uint32(c) < 16
-	// result: (SRAWconst (SignExt16to32 x) [c&15])
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64MOVDconst {
-			break
-		}
-		c := auxIntToInt64(v_1.AuxInt)
-		if !(uint32(c) < 16) {
-			break
-		}
-		v.reset(OpPPC64SRAWconst)
-		v.AuxInt = int64ToAuxInt(c & 15)
-		v0 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
-		v0.AddArg(x)
-		v.AddArg(v0)
-		return true
-	}
 	// match: (Rsh16x32 x y)
 	// cond: shiftIsBounded(v)
 	// result: (SRAW (MOVHreg x) y)
@@ -14830,23 +14292,6 @@
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
-	// match: (Rsh32Ux32 x (MOVDconst [c]))
-	// cond: uint32(c) < 32
-	// result: (SRWconst x [c&31])
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64MOVDconst {
-			break
-		}
-		c := auxIntToInt64(v_1.AuxInt)
-		if !(uint32(c) < 32) {
-			break
-		}
-		v.reset(OpPPC64SRWconst)
-		v.AuxInt = int64ToAuxInt(c & 31)
-		v.AddArg(x)
-		return true
-	}
 	// match: (Rsh32Ux32 x y)
 	// cond: shiftIsBounded(v)
 	// result: (SRW x y)
@@ -14884,21 +14329,6 @@
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
-	// match: (Rsh32Ux64 _ (MOVDconst [c]))
-	// cond: uint64(c) >= 32
-	// result: (MOVDconst [0])
-	for {
-		if v_1.Op != OpPPC64MOVDconst {
-			break
-		}
-		c := auxIntToInt64(v_1.AuxInt)
-		if !(uint64(c) >= 32) {
-			break
-		}
-		v.reset(OpPPC64MOVDconst)
-		v.AuxInt = int64ToAuxInt(0)
-		return true
-	}
 	// match: (Rsh32Ux64 x (MOVDconst [c]))
 	// cond: uint64(c) < 32
 	// result: (SRWconst x [c])
@@ -14929,163 +14359,6 @@
 		v.AddArg2(x, y)
 		return true
 	}
-	// match: (Rsh32Ux64 x (AND y (MOVDconst [31])))
-	// result: (SRW x (ANDconst <typ.Int32> [31] y))
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64AND {
-			break
-		}
-		_ = v_1.Args[1]
-		v_1_0 := v_1.Args[0]
-		v_1_1 := v_1.Args[1]
-		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
-			y := v_1_0
-			if v_1_1.Op != OpPPC64MOVDconst || auxIntToInt64(v_1_1.AuxInt) != 31 {
-				continue
-			}
-			v.reset(OpPPC64SRW)
-			v0 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.Int32)
-			v0.AuxInt = int64ToAuxInt(31)
-			v0.AddArg(y)
-			v.AddArg2(x, v0)
-			return true
-		}
-		break
-	}
-	// match: (Rsh32Ux64 x (ANDconst <typ.UInt> [31] y))
-	// result: (SRW x (ANDconst <typ.UInt> [31] y))
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64ANDconst || v_1.Type != typ.UInt || auxIntToInt64(v_1.AuxInt) != 31 {
-			break
-		}
-		y := v_1.Args[0]
-		v.reset(OpPPC64SRW)
-		v0 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
-		v0.AuxInt = int64ToAuxInt(31)
-		v0.AddArg(y)
-		v.AddArg2(x, v0)
-		return true
-	}
-	// match: (Rsh32Ux64 x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))
-	// result: (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64SUB || v_1.Type != typ.UInt {
-			break
-		}
-		_ = v_1.Args[1]
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpPPC64MOVDconst || auxIntToInt64(v_1_0.AuxInt) != 32 {
-			break
-		}
-		v_1_1 := v_1.Args[1]
-		if v_1_1.Op != OpPPC64ANDconst || v_1_1.Type != typ.UInt || auxIntToInt64(v_1_1.AuxInt) != 31 {
-			break
-		}
-		y := v_1_1.Args[0]
-		v.reset(OpPPC64SRW)
-		v0 := b.NewValue0(v.Pos, OpPPC64SUB, typ.UInt)
-		v1 := b.NewValue0(v.Pos, OpPPC64MOVDconst, typ.Int64)
-		v1.AuxInt = int64ToAuxInt(32)
-		v2 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
-		v2.AuxInt = int64ToAuxInt(31)
-		v2.AddArg(y)
-		v0.AddArg2(v1, v2)
-		v.AddArg2(x, v0)
-		return true
-	}
-	// match: (Rsh32Ux64 x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y)))
-	// result: (SRW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y)))
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64SUBFCconst || v_1.Type != typ.UInt || auxIntToInt64(v_1.AuxInt) != 32 {
-			break
-		}
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpPPC64ANDconst || v_1_0.Type != typ.UInt || auxIntToInt64(v_1_0.AuxInt) != 31 {
-			break
-		}
-		y := v_1_0.Args[0]
-		v.reset(OpPPC64SRW)
-		v0 := b.NewValue0(v.Pos, OpPPC64SUBFCconst, typ.UInt)
-		v0.AuxInt = int64ToAuxInt(32)
-		v1 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
-		v1.AuxInt = int64ToAuxInt(31)
-		v1.AddArg(y)
-		v0.AddArg(v1)
-		v.AddArg2(x, v0)
-		return true
-	}
-	// match: (Rsh32Ux64 x (SUB <typ.UInt> (MOVDconst [32]) (AND <typ.UInt> y (MOVDconst [31]))))
-	// result: (SRW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64SUB || v_1.Type != typ.UInt {
-			break
-		}
-		_ = v_1.Args[1]
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpPPC64MOVDconst || auxIntToInt64(v_1_0.AuxInt) != 32 {
-			break
-		}
-		v_1_1 := v_1.Args[1]
-		if v_1_1.Op != OpPPC64AND || v_1_1.Type != typ.UInt {
-			break
-		}
-		_ = v_1_1.Args[1]
-		v_1_1_0 := v_1_1.Args[0]
-		v_1_1_1 := v_1_1.Args[1]
-		for _i0 := 0; _i0 <= 1; _i0, v_1_1_0, v_1_1_1 = _i0+1, v_1_1_1, v_1_1_0 {
-			y := v_1_1_0
-			if v_1_1_1.Op != OpPPC64MOVDconst || auxIntToInt64(v_1_1_1.AuxInt) != 31 {
-				continue
-			}
-			v.reset(OpPPC64SRW)
-			v0 := b.NewValue0(v.Pos, OpPPC64SUB, typ.UInt)
-			v1 := b.NewValue0(v.Pos, OpPPC64MOVDconst, typ.Int64)
-			v1.AuxInt = int64ToAuxInt(32)
-			v2 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
-			v2.AuxInt = int64ToAuxInt(31)
-			v2.AddArg(y)
-			v0.AddArg2(v1, v2)
-			v.AddArg2(x, v0)
-			return true
-		}
-		break
-	}
-	// match: (Rsh32Ux64 x (SUBFCconst <typ.UInt> [32] (AND <typ.UInt> y (MOVDconst [31]))))
-	// result: (SRW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y)))
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64SUBFCconst || v_1.Type != typ.UInt || auxIntToInt64(v_1.AuxInt) != 32 {
-			break
-		}
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpPPC64AND || v_1_0.Type != typ.UInt {
-			break
-		}
-		_ = v_1_0.Args[1]
-		v_1_0_0 := v_1_0.Args[0]
-		v_1_0_1 := v_1_0.Args[1]
-		for _i0 := 0; _i0 <= 1; _i0, v_1_0_0, v_1_0_1 = _i0+1, v_1_0_1, v_1_0_0 {
-			y := v_1_0_0
-			if v_1_0_1.Op != OpPPC64MOVDconst || auxIntToInt64(v_1_0_1.AuxInt) != 31 {
-				continue
-			}
-			v.reset(OpPPC64SRW)
-			v0 := b.NewValue0(v.Pos, OpPPC64SUBFCconst, typ.UInt)
-			v0.AuxInt = int64ToAuxInt(32)
-			v1 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
-			v1.AuxInt = int64ToAuxInt(31)
-			v1.AddArg(y)
-			v0.AddArg(v1)
-			v.AddArg2(x, v0)
-			return true
-		}
-		break
-	}
 	// match: (Rsh32Ux64 x y)
 	// result: (SRW x (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [32]))))
 	for {
@@ -15188,23 +14461,6 @@
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
-	// match: (Rsh32x32 x (MOVDconst [c]))
-	// cond: uint32(c) < 32
-	// result: (SRAWconst x [c&31])
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64MOVDconst {
-			break
-		}
-		c := auxIntToInt64(v_1.AuxInt)
-		if !(uint32(c) < 32) {
-			break
-		}
-		v.reset(OpPPC64SRAWconst)
-		v.AuxInt = int64ToAuxInt(c & 31)
-		v.AddArg(x)
-		return true
-	}
 	// match: (Rsh32x32 x y)
 	// cond: shiftIsBounded(v)
 	// result: (SRAW x y)
@@ -15289,163 +14545,6 @@
 		v.AddArg2(x, y)
 		return true
 	}
-	// match: (Rsh32x64 x (AND y (MOVDconst [31])))
-	// result: (SRAW x (ANDconst <typ.Int32> [31] y))
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64AND {
-			break
-		}
-		_ = v_1.Args[1]
-		v_1_0 := v_1.Args[0]
-		v_1_1 := v_1.Args[1]
-		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
-			y := v_1_0
-			if v_1_1.Op != OpPPC64MOVDconst || auxIntToInt64(v_1_1.AuxInt) != 31 {
-				continue
-			}
-			v.reset(OpPPC64SRAW)
-			v0 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.Int32)
-			v0.AuxInt = int64ToAuxInt(31)
-			v0.AddArg(y)
-			v.AddArg2(x, v0)
-			return true
-		}
-		break
-	}
-	// match: (Rsh32x64 x (ANDconst <typ.UInt> [31] y))
-	// result: (SRAW x (ANDconst <typ.UInt> [31] y))
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64ANDconst || v_1.Type != typ.UInt || auxIntToInt64(v_1.AuxInt) != 31 {
-			break
-		}
-		y := v_1.Args[0]
-		v.reset(OpPPC64SRAW)
-		v0 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
-		v0.AuxInt = int64ToAuxInt(31)
-		v0.AddArg(y)
-		v.AddArg2(x, v0)
-		return true
-	}
-	// match: (Rsh32x64 x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))
-	// result: (SRAW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64SUB || v_1.Type != typ.UInt {
-			break
-		}
-		_ = v_1.Args[1]
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpPPC64MOVDconst || auxIntToInt64(v_1_0.AuxInt) != 32 {
-			break
-		}
-		v_1_1 := v_1.Args[1]
-		if v_1_1.Op != OpPPC64ANDconst || v_1_1.Type != typ.UInt || auxIntToInt64(v_1_1.AuxInt) != 31 {
-			break
-		}
-		y := v_1_1.Args[0]
-		v.reset(OpPPC64SRAW)
-		v0 := b.NewValue0(v.Pos, OpPPC64SUB, typ.UInt)
-		v1 := b.NewValue0(v.Pos, OpPPC64MOVDconst, typ.Int64)
-		v1.AuxInt = int64ToAuxInt(32)
-		v2 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
-		v2.AuxInt = int64ToAuxInt(31)
-		v2.AddArg(y)
-		v0.AddArg2(v1, v2)
-		v.AddArg2(x, v0)
-		return true
-	}
-	// match: (Rsh32x64 x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y)))
-	// result: (SRAW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y)))
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64SUBFCconst || v_1.Type != typ.UInt || auxIntToInt64(v_1.AuxInt) != 32 {
-			break
-		}
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpPPC64ANDconst || v_1_0.Type != typ.UInt || auxIntToInt64(v_1_0.AuxInt) != 31 {
-			break
-		}
-		y := v_1_0.Args[0]
-		v.reset(OpPPC64SRAW)
-		v0 := b.NewValue0(v.Pos, OpPPC64SUBFCconst, typ.UInt)
-		v0.AuxInt = int64ToAuxInt(32)
-		v1 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
-		v1.AuxInt = int64ToAuxInt(31)
-		v1.AddArg(y)
-		v0.AddArg(v1)
-		v.AddArg2(x, v0)
-		return true
-	}
-	// match: (Rsh32x64 x (SUB <typ.UInt> (MOVDconst [32]) (AND <typ.UInt> y (MOVDconst [31]))))
-	// result: (SRAW x (SUB <typ.UInt> (MOVDconst [32]) (ANDconst <typ.UInt> [31] y)))
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64SUB || v_1.Type != typ.UInt {
-			break
-		}
-		_ = v_1.Args[1]
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpPPC64MOVDconst || auxIntToInt64(v_1_0.AuxInt) != 32 {
-			break
-		}
-		v_1_1 := v_1.Args[1]
-		if v_1_1.Op != OpPPC64AND || v_1_1.Type != typ.UInt {
-			break
-		}
-		_ = v_1_1.Args[1]
-		v_1_1_0 := v_1_1.Args[0]
-		v_1_1_1 := v_1_1.Args[1]
-		for _i0 := 0; _i0 <= 1; _i0, v_1_1_0, v_1_1_1 = _i0+1, v_1_1_1, v_1_1_0 {
-			y := v_1_1_0
-			if v_1_1_1.Op != OpPPC64MOVDconst || auxIntToInt64(v_1_1_1.AuxInt) != 31 {
-				continue
-			}
-			v.reset(OpPPC64SRAW)
-			v0 := b.NewValue0(v.Pos, OpPPC64SUB, typ.UInt)
-			v1 := b.NewValue0(v.Pos, OpPPC64MOVDconst, typ.Int64)
-			v1.AuxInt = int64ToAuxInt(32)
-			v2 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
-			v2.AuxInt = int64ToAuxInt(31)
-			v2.AddArg(y)
-			v0.AddArg2(v1, v2)
-			v.AddArg2(x, v0)
-			return true
-		}
-		break
-	}
-	// match: (Rsh32x64 x (SUBFCconst <typ.UInt> [32] (AND <typ.UInt> y (MOVDconst [31]))))
-	// result: (SRAW x (SUBFCconst <typ.UInt> [32] (ANDconst <typ.UInt> [31] y)))
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64SUBFCconst || v_1.Type != typ.UInt || auxIntToInt64(v_1.AuxInt) != 32 {
-			break
-		}
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpPPC64AND || v_1_0.Type != typ.UInt {
-			break
-		}
-		_ = v_1_0.Args[1]
-		v_1_0_0 := v_1_0.Args[0]
-		v_1_0_1 := v_1_0.Args[1]
-		for _i0 := 0; _i0 <= 1; _i0, v_1_0_0, v_1_0_1 = _i0+1, v_1_0_1, v_1_0_0 {
-			y := v_1_0_0
-			if v_1_0_1.Op != OpPPC64MOVDconst || auxIntToInt64(v_1_0_1.AuxInt) != 31 {
-				continue
-			}
-			v.reset(OpPPC64SRAW)
-			v0 := b.NewValue0(v.Pos, OpPPC64SUBFCconst, typ.UInt)
-			v0.AuxInt = int64ToAuxInt(32)
-			v1 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
-			v1.AuxInt = int64ToAuxInt(31)
-			v1.AddArg(y)
-			v0.AddArg(v1)
-			v.AddArg2(x, v0)
-			return true
-		}
-		break
-	}
 	// match: (Rsh32x64 x y)
 	// result: (SRAW x (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [32]))))
 	for {
@@ -15548,23 +14647,6 @@
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
-	// match: (Rsh64Ux32 x (MOVDconst [c]))
-	// cond: uint32(c) < 64
-	// result: (SRDconst x [c&63])
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64MOVDconst {
-			break
-		}
-		c := auxIntToInt64(v_1.AuxInt)
-		if !(uint32(c) < 64) {
-			break
-		}
-		v.reset(OpPPC64SRDconst)
-		v.AuxInt = int64ToAuxInt(c & 63)
-		v.AddArg(x)
-		return true
-	}
 	// match: (Rsh64Ux32 x y)
 	// cond: shiftIsBounded(v)
 	// result: (SRD x y)
@@ -15602,21 +14684,6 @@
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
-	// match: (Rsh64Ux64 _ (MOVDconst [c]))
-	// cond: uint64(c) >= 64
-	// result: (MOVDconst [0])
-	for {
-		if v_1.Op != OpPPC64MOVDconst {
-			break
-		}
-		c := auxIntToInt64(v_1.AuxInt)
-		if !(uint64(c) >= 64) {
-			break
-		}
-		v.reset(OpPPC64MOVDconst)
-		v.AuxInt = int64ToAuxInt(0)
-		return true
-	}
 	// match: (Rsh64Ux64 x (MOVDconst [c]))
 	// cond: uint64(c) < 64
 	// result: (SRDconst x [c])
@@ -15647,163 +14714,6 @@
 		v.AddArg2(x, y)
 		return true
 	}
-	// match: (Rsh64Ux64 x (AND y (MOVDconst [63])))
-	// result: (SRD x (ANDconst <typ.Int64> [63] y))
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64AND {
-			break
-		}
-		_ = v_1.Args[1]
-		v_1_0 := v_1.Args[0]
-		v_1_1 := v_1.Args[1]
-		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
-			y := v_1_0
-			if v_1_1.Op != OpPPC64MOVDconst || auxIntToInt64(v_1_1.AuxInt) != 63 {
-				continue
-			}
-			v.reset(OpPPC64SRD)
-			v0 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.Int64)
-			v0.AuxInt = int64ToAuxInt(63)
-			v0.AddArg(y)
-			v.AddArg2(x, v0)
-			return true
-		}
-		break
-	}
-	// match: (Rsh64Ux64 x (ANDconst <typ.UInt> [63] y))
-	// result: (SRD x (ANDconst <typ.UInt> [63] y))
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64ANDconst || v_1.Type != typ.UInt || auxIntToInt64(v_1.AuxInt) != 63 {
-			break
-		}
-		y := v_1.Args[0]
-		v.reset(OpPPC64SRD)
-		v0 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
-		v0.AuxInt = int64ToAuxInt(63)
-		v0.AddArg(y)
-		v.AddArg2(x, v0)
-		return true
-	}
-	// match: (Rsh64Ux64 x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))
-	// result: (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64SUB || v_1.Type != typ.UInt {
-			break
-		}
-		_ = v_1.Args[1]
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpPPC64MOVDconst || auxIntToInt64(v_1_0.AuxInt) != 64 {
-			break
-		}
-		v_1_1 := v_1.Args[1]
-		if v_1_1.Op != OpPPC64ANDconst || v_1_1.Type != typ.UInt || auxIntToInt64(v_1_1.AuxInt) != 63 {
-			break
-		}
-		y := v_1_1.Args[0]
-		v.reset(OpPPC64SRD)
-		v0 := b.NewValue0(v.Pos, OpPPC64SUB, typ.UInt)
-		v1 := b.NewValue0(v.Pos, OpPPC64MOVDconst, typ.Int64)
-		v1.AuxInt = int64ToAuxInt(64)
-		v2 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
-		v2.AuxInt = int64ToAuxInt(63)
-		v2.AddArg(y)
-		v0.AddArg2(v1, v2)
-		v.AddArg2(x, v0)
-		return true
-	}
-	// match: (Rsh64Ux64 x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y)))
-	// result: (SRD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y)))
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64SUBFCconst || v_1.Type != typ.UInt || auxIntToInt64(v_1.AuxInt) != 64 {
-			break
-		}
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpPPC64ANDconst || v_1_0.Type != typ.UInt || auxIntToInt64(v_1_0.AuxInt) != 63 {
-			break
-		}
-		y := v_1_0.Args[0]
-		v.reset(OpPPC64SRD)
-		v0 := b.NewValue0(v.Pos, OpPPC64SUBFCconst, typ.UInt)
-		v0.AuxInt = int64ToAuxInt(64)
-		v1 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
-		v1.AuxInt = int64ToAuxInt(63)
-		v1.AddArg(y)
-		v0.AddArg(v1)
-		v.AddArg2(x, v0)
-		return true
-	}
-	// match: (Rsh64Ux64 x (SUB <typ.UInt> (MOVDconst [64]) (AND <typ.UInt> y (MOVDconst [63]))))
-	// result: (SRD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64SUB || v_1.Type != typ.UInt {
-			break
-		}
-		_ = v_1.Args[1]
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpPPC64MOVDconst || auxIntToInt64(v_1_0.AuxInt) != 64 {
-			break
-		}
-		v_1_1 := v_1.Args[1]
-		if v_1_1.Op != OpPPC64AND || v_1_1.Type != typ.UInt {
-			break
-		}
-		_ = v_1_1.Args[1]
-		v_1_1_0 := v_1_1.Args[0]
-		v_1_1_1 := v_1_1.Args[1]
-		for _i0 := 0; _i0 <= 1; _i0, v_1_1_0, v_1_1_1 = _i0+1, v_1_1_1, v_1_1_0 {
-			y := v_1_1_0
-			if v_1_1_1.Op != OpPPC64MOVDconst || auxIntToInt64(v_1_1_1.AuxInt) != 63 {
-				continue
-			}
-			v.reset(OpPPC64SRD)
-			v0 := b.NewValue0(v.Pos, OpPPC64SUB, typ.UInt)
-			v1 := b.NewValue0(v.Pos, OpPPC64MOVDconst, typ.Int64)
-			v1.AuxInt = int64ToAuxInt(64)
-			v2 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
-			v2.AuxInt = int64ToAuxInt(63)
-			v2.AddArg(y)
-			v0.AddArg2(v1, v2)
-			v.AddArg2(x, v0)
-			return true
-		}
-		break
-	}
-	// match: (Rsh64Ux64 x (SUBFCconst <typ.UInt> [64] (AND <typ.UInt> y (MOVDconst [63]))))
-	// result: (SRD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y)))
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64SUBFCconst || v_1.Type != typ.UInt || auxIntToInt64(v_1.AuxInt) != 64 {
-			break
-		}
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpPPC64AND || v_1_0.Type != typ.UInt {
-			break
-		}
-		_ = v_1_0.Args[1]
-		v_1_0_0 := v_1_0.Args[0]
-		v_1_0_1 := v_1_0.Args[1]
-		for _i0 := 0; _i0 <= 1; _i0, v_1_0_0, v_1_0_1 = _i0+1, v_1_0_1, v_1_0_0 {
-			y := v_1_0_0
-			if v_1_0_1.Op != OpPPC64MOVDconst || auxIntToInt64(v_1_0_1.AuxInt) != 63 {
-				continue
-			}
-			v.reset(OpPPC64SRD)
-			v0 := b.NewValue0(v.Pos, OpPPC64SUBFCconst, typ.UInt)
-			v0.AuxInt = int64ToAuxInt(64)
-			v1 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
-			v1.AuxInt = int64ToAuxInt(63)
-			v1.AddArg(y)
-			v0.AddArg(v1)
-			v.AddArg2(x, v0)
-			return true
-		}
-		break
-	}
 	// match: (Rsh64Ux64 x y)
 	// result: (SRD x (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [64]))))
 	for {
@@ -15906,23 +14816,6 @@
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
-	// match: (Rsh64x32 x (MOVDconst [c]))
-	// cond: uint32(c) < 64
-	// result: (SRADconst x [c&63])
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64MOVDconst {
-			break
-		}
-		c := auxIntToInt64(v_1.AuxInt)
-		if !(uint32(c) < 64) {
-			break
-		}
-		v.reset(OpPPC64SRADconst)
-		v.AuxInt = int64ToAuxInt(c & 63)
-		v.AddArg(x)
-		return true
-	}
 	// match: (Rsh64x32 x y)
 	// cond: shiftIsBounded(v)
 	// result: (SRAD x y)
@@ -16007,163 +14900,6 @@
 		v.AddArg2(x, y)
 		return true
 	}
-	// match: (Rsh64x64 x (AND y (MOVDconst [63])))
-	// result: (SRAD x (ANDconst <typ.Int64> [63] y))
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64AND {
-			break
-		}
-		_ = v_1.Args[1]
-		v_1_0 := v_1.Args[0]
-		v_1_1 := v_1.Args[1]
-		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
-			y := v_1_0
-			if v_1_1.Op != OpPPC64MOVDconst || auxIntToInt64(v_1_1.AuxInt) != 63 {
-				continue
-			}
-			v.reset(OpPPC64SRAD)
-			v0 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.Int64)
-			v0.AuxInt = int64ToAuxInt(63)
-			v0.AddArg(y)
-			v.AddArg2(x, v0)
-			return true
-		}
-		break
-	}
-	// match: (Rsh64x64 x (ANDconst <typ.UInt> [63] y))
-	// result: (SRAD x (ANDconst <typ.UInt> [63] y))
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64ANDconst || v_1.Type != typ.UInt || auxIntToInt64(v_1.AuxInt) != 63 {
-			break
-		}
-		y := v_1.Args[0]
-		v.reset(OpPPC64SRAD)
-		v0 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
-		v0.AuxInt = int64ToAuxInt(63)
-		v0.AddArg(y)
-		v.AddArg2(x, v0)
-		return true
-	}
-	// match: (Rsh64x64 x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))
-	// result: (SRAD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64SUB || v_1.Type != typ.UInt {
-			break
-		}
-		_ = v_1.Args[1]
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpPPC64MOVDconst || auxIntToInt64(v_1_0.AuxInt) != 64 {
-			break
-		}
-		v_1_1 := v_1.Args[1]
-		if v_1_1.Op != OpPPC64ANDconst || v_1_1.Type != typ.UInt || auxIntToInt64(v_1_1.AuxInt) != 63 {
-			break
-		}
-		y := v_1_1.Args[0]
-		v.reset(OpPPC64SRAD)
-		v0 := b.NewValue0(v.Pos, OpPPC64SUB, typ.UInt)
-		v1 := b.NewValue0(v.Pos, OpPPC64MOVDconst, typ.Int64)
-		v1.AuxInt = int64ToAuxInt(64)
-		v2 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
-		v2.AuxInt = int64ToAuxInt(63)
-		v2.AddArg(y)
-		v0.AddArg2(v1, v2)
-		v.AddArg2(x, v0)
-		return true
-	}
-	// match: (Rsh64x64 x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y)))
-	// result: (SRAD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y)))
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64SUBFCconst || v_1.Type != typ.UInt || auxIntToInt64(v_1.AuxInt) != 64 {
-			break
-		}
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpPPC64ANDconst || v_1_0.Type != typ.UInt || auxIntToInt64(v_1_0.AuxInt) != 63 {
-			break
-		}
-		y := v_1_0.Args[0]
-		v.reset(OpPPC64SRAD)
-		v0 := b.NewValue0(v.Pos, OpPPC64SUBFCconst, typ.UInt)
-		v0.AuxInt = int64ToAuxInt(64)
-		v1 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
-		v1.AuxInt = int64ToAuxInt(63)
-		v1.AddArg(y)
-		v0.AddArg(v1)
-		v.AddArg2(x, v0)
-		return true
-	}
-	// match: (Rsh64x64 x (SUB <typ.UInt> (MOVDconst [64]) (AND <typ.UInt> y (MOVDconst [63]))))
-	// result: (SRAD x (SUB <typ.UInt> (MOVDconst [64]) (ANDconst <typ.UInt> [63] y)))
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64SUB || v_1.Type != typ.UInt {
-			break
-		}
-		_ = v_1.Args[1]
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpPPC64MOVDconst || auxIntToInt64(v_1_0.AuxInt) != 64 {
-			break
-		}
-		v_1_1 := v_1.Args[1]
-		if v_1_1.Op != OpPPC64AND || v_1_1.Type != typ.UInt {
-			break
-		}
-		_ = v_1_1.Args[1]
-		v_1_1_0 := v_1_1.Args[0]
-		v_1_1_1 := v_1_1.Args[1]
-		for _i0 := 0; _i0 <= 1; _i0, v_1_1_0, v_1_1_1 = _i0+1, v_1_1_1, v_1_1_0 {
-			y := v_1_1_0
-			if v_1_1_1.Op != OpPPC64MOVDconst || auxIntToInt64(v_1_1_1.AuxInt) != 63 {
-				continue
-			}
-			v.reset(OpPPC64SRAD)
-			v0 := b.NewValue0(v.Pos, OpPPC64SUB, typ.UInt)
-			v1 := b.NewValue0(v.Pos, OpPPC64MOVDconst, typ.Int64)
-			v1.AuxInt = int64ToAuxInt(64)
-			v2 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
-			v2.AuxInt = int64ToAuxInt(63)
-			v2.AddArg(y)
-			v0.AddArg2(v1, v2)
-			v.AddArg2(x, v0)
-			return true
-		}
-		break
-	}
-	// match: (Rsh64x64 x (SUBFCconst <typ.UInt> [64] (AND <typ.UInt> y (MOVDconst [63]))))
-	// result: (SRAD x (SUBFCconst <typ.UInt> [64] (ANDconst <typ.UInt> [63] y)))
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64SUBFCconst || v_1.Type != typ.UInt || auxIntToInt64(v_1.AuxInt) != 64 {
-			break
-		}
-		v_1_0 := v_1.Args[0]
-		if v_1_0.Op != OpPPC64AND || v_1_0.Type != typ.UInt {
-			break
-		}
-		_ = v_1_0.Args[1]
-		v_1_0_0 := v_1_0.Args[0]
-		v_1_0_1 := v_1_0.Args[1]
-		for _i0 := 0; _i0 <= 1; _i0, v_1_0_0, v_1_0_1 = _i0+1, v_1_0_1, v_1_0_0 {
-			y := v_1_0_0
-			if v_1_0_1.Op != OpPPC64MOVDconst || auxIntToInt64(v_1_0_1.AuxInt) != 63 {
-				continue
-			}
-			v.reset(OpPPC64SRAD)
-			v0 := b.NewValue0(v.Pos, OpPPC64SUBFCconst, typ.UInt)
-			v0.AuxInt = int64ToAuxInt(64)
-			v1 := b.NewValue0(v.Pos, OpPPC64ANDconst, typ.UInt)
-			v1.AuxInt = int64ToAuxInt(63)
-			v1.AddArg(y)
-			v0.AddArg(v1)
-			v.AddArg2(x, v0)
-			return true
-		}
-		break
-	}
 	// match: (Rsh64x64 x y)
 	// result: (SRAD x (ISEL [0] y (MOVDconst [-1]) (CMPU y (MOVDconst [64]))))
 	for {
@@ -16270,25 +15006,6 @@
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
-	// match: (Rsh8Ux32 x (MOVDconst [c]))
-	// cond: uint32(c) < 8
-	// result: (SRWconst (ZeroExt8to32 x) [c&7])
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64MOVDconst {
-			break
-		}
-		c := auxIntToInt64(v_1.AuxInt)
-		if !(uint32(c) < 8) {
-			break
-		}
-		v.reset(OpPPC64SRWconst)
-		v.AuxInt = int64ToAuxInt(c & 7)
-		v0 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
-		v0.AddArg(x)
-		v.AddArg(v0)
-		return true
-	}
 	// match: (Rsh8Ux32 x y)
 	// cond: shiftIsBounded(v)
 	// result: (SRW (MOVBZreg x) y)
@@ -16330,21 +15047,6 @@
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
-	// match: (Rsh8Ux64 _ (MOVDconst [c]))
-	// cond: uint64(c) >= 8
-	// result: (MOVDconst [0])
-	for {
-		if v_1.Op != OpPPC64MOVDconst {
-			break
-		}
-		c := auxIntToInt64(v_1.AuxInt)
-		if !(uint64(c) >= 8) {
-			break
-		}
-		v.reset(OpPPC64MOVDconst)
-		v.AuxInt = int64ToAuxInt(0)
-		return true
-	}
 	// match: (Rsh8Ux64 x (MOVDconst [c]))
 	// cond: uint64(c) < 8
 	// result: (SRWconst (ZeroExt8to32 x) [c])
@@ -16491,25 +15193,6 @@
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
-	// match: (Rsh8x32 x (MOVDconst [c]))
-	// cond: uint32(c) < 8
-	// result: (SRAWconst (SignExt8to32 x) [c&7])
-	for {
-		x := v_0
-		if v_1.Op != OpPPC64MOVDconst {
-			break
-		}
-		c := auxIntToInt64(v_1.AuxInt)
-		if !(uint32(c) < 8) {
-			break
-		}
-		v.reset(OpPPC64SRAWconst)
-		v.AuxInt = int64ToAuxInt(c & 7)
-		v0 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
-		v0.AddArg(x)
-		v.AddArg(v0)
-		return true
-	}
 	// match: (Rsh8x32 x y)
 	// cond: shiftIsBounded(v)
 	// result: (SRAW (MOVBreg x) y)
@@ -16672,6 +15355,18 @@
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
+	// match: (Select0 (Mul64uhilo x y))
+	// result: (MULHDU x y)
+	for {
+		if v_0.Op != OpMul64uhilo {
+			break
+		}
+		y := v_0.Args[1]
+		x := v_0.Args[0]
+		v.reset(OpPPC64MULHDU)
+		v.AddArg2(x, y)
+		return true
+	}
 	// match: (Select0 (Add64carry x y c))
 	// result: (Select0 <typ.UInt64> (ADDE x y (Select1 <typ.UInt64> (ADDCconst c [-1]))))
 	for {
@@ -16714,12 +15409,324 @@
 		v.AddArg(v0)
 		return true
 	}
+	// match: (Select0 (ANDCCconst [m] (ROTLWconst [r] x)))
+	// cond: isPPC64WordRotateMask(m)
+	// result: (RLWINM [encodePPC64RotateMask(r,m,32)] x)
+	for {
+		if v_0.Op != OpPPC64ANDCCconst {
+			break
+		}
+		m := auxIntToInt64(v_0.AuxInt)
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpPPC64ROTLWconst {
+			break
+		}
+		r := auxIntToInt64(v_0_0.AuxInt)
+		x := v_0_0.Args[0]
+		if !(isPPC64WordRotateMask(m)) {
+			break
+		}
+		v.reset(OpPPC64RLWINM)
+		v.AuxInt = int64ToAuxInt(encodePPC64RotateMask(r, m, 32))
+		v.AddArg(x)
+		return true
+	}
+	// match: (Select0 (ANDCCconst [m] (ROTLW x r)))
+	// cond: isPPC64WordRotateMask(m)
+	// result: (RLWNM [encodePPC64RotateMask(0,m,32)] x r)
+	for {
+		if v_0.Op != OpPPC64ANDCCconst {
+			break
+		}
+		m := auxIntToInt64(v_0.AuxInt)
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpPPC64ROTLW {
+			break
+		}
+		r := v_0_0.Args[1]
+		x := v_0_0.Args[0]
+		if !(isPPC64WordRotateMask(m)) {
+			break
+		}
+		v.reset(OpPPC64RLWNM)
+		v.AuxInt = int64ToAuxInt(encodePPC64RotateMask(0, m, 32))
+		v.AddArg2(x, r)
+		return true
+	}
+	// match: (Select0 (ANDCCconst [m] (SRWconst x [s])))
+	// cond: mergePPC64RShiftMask(m,s,32) == 0
+	// result: (MOVDconst [0])
+	for {
+		if v_0.Op != OpPPC64ANDCCconst {
+			break
+		}
+		m := auxIntToInt64(v_0.AuxInt)
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpPPC64SRWconst {
+			break
+		}
+		s := auxIntToInt64(v_0_0.AuxInt)
+		if !(mergePPC64RShiftMask(m, s, 32) == 0) {
+			break
+		}
+		v.reset(OpPPC64MOVDconst)
+		v.AuxInt = int64ToAuxInt(0)
+		return true
+	}
+	// match: (Select0 (ANDCCconst [m] (SRWconst x [s])))
+	// cond: mergePPC64AndSrwi(m,s) != 0
+	// result: (RLWINM [mergePPC64AndSrwi(m,s)] x)
+	for {
+		if v_0.Op != OpPPC64ANDCCconst {
+			break
+		}
+		m := auxIntToInt64(v_0.AuxInt)
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpPPC64SRWconst {
+			break
+		}
+		s := auxIntToInt64(v_0_0.AuxInt)
+		x := v_0_0.Args[0]
+		if !(mergePPC64AndSrwi(m, s) != 0) {
+			break
+		}
+		v.reset(OpPPC64RLWINM)
+		v.AuxInt = int64ToAuxInt(mergePPC64AndSrwi(m, s))
+		v.AddArg(x)
+		return true
+	}
+	// match: (Select0 (ANDCCconst [c] (Select0 (ANDCCconst [d] x))))
+	// result: (Select0 (ANDCCconst [c&d] x))
+	for {
+		if v_0.Op != OpPPC64ANDCCconst {
+			break
+		}
+		c := auxIntToInt64(v_0.AuxInt)
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpSelect0 {
+			break
+		}
+		v_0_0_0 := v_0_0.Args[0]
+		if v_0_0_0.Op != OpPPC64ANDCCconst {
+			break
+		}
+		d := auxIntToInt64(v_0_0_0.AuxInt)
+		x := v_0_0_0.Args[0]
+		v.reset(OpSelect0)
+		v0 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+		v0.AuxInt = int64ToAuxInt(c & d)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Select0 (ANDCCconst [-1] x))
+	// result: x
+	for {
+		if v_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0.AuxInt) != -1 {
+			break
+		}
+		x := v_0.Args[0]
+		v.copyOf(x)
+		return true
+	}
+	// match: (Select0 (ANDCCconst [0] _))
+	// result: (MOVDconst [0])
+	for {
+		if v_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0.AuxInt) != 0 {
+			break
+		}
+		v.reset(OpPPC64MOVDconst)
+		v.AuxInt = int64ToAuxInt(0)
+		return true
+	}
+	// match: (Select0 (ANDCCconst [c] y:(MOVBZreg _)))
+	// cond: c&0xFF == 0xFF
+	// result: y
+	for {
+		if v_0.Op != OpPPC64ANDCCconst {
+			break
+		}
+		c := auxIntToInt64(v_0.AuxInt)
+		y := v_0.Args[0]
+		if y.Op != OpPPC64MOVBZreg || !(c&0xFF == 0xFF) {
+			break
+		}
+		v.copyOf(y)
+		return true
+	}
+	// match: (Select0 (ANDCCconst [0xFF] y:(MOVBreg _)))
+	// result: y
+	for {
+		if v_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0.AuxInt) != 0xFF {
+			break
+		}
+		y := v_0.Args[0]
+		if y.Op != OpPPC64MOVBreg {
+			break
+		}
+		v.copyOf(y)
+		return true
+	}
+	// match: (Select0 (ANDCCconst [c] y:(MOVHZreg _)))
+	// cond: c&0xFFFF == 0xFFFF
+	// result: y
+	for {
+		if v_0.Op != OpPPC64ANDCCconst {
+			break
+		}
+		c := auxIntToInt64(v_0.AuxInt)
+		y := v_0.Args[0]
+		if y.Op != OpPPC64MOVHZreg || !(c&0xFFFF == 0xFFFF) {
+			break
+		}
+		v.copyOf(y)
+		return true
+	}
+	// match: (Select0 (ANDCCconst [0xFFFF] y:(MOVHreg _)))
+	// result: y
+	for {
+		if v_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0.AuxInt) != 0xFFFF {
+			break
+		}
+		y := v_0.Args[0]
+		if y.Op != OpPPC64MOVHreg {
+			break
+		}
+		v.copyOf(y)
+		return true
+	}
+	// match: (Select0 (ANDCCconst [c] (MOVBreg x)))
+	// result: (Select0 (ANDCCconst [c&0xFF] x))
+	for {
+		if v_0.Op != OpPPC64ANDCCconst {
+			break
+		}
+		c := auxIntToInt64(v_0.AuxInt)
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpPPC64MOVBreg {
+			break
+		}
+		x := v_0_0.Args[0]
+		v.reset(OpSelect0)
+		v0 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+		v0.AuxInt = int64ToAuxInt(c & 0xFF)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Select0 (ANDCCconst [c] (MOVBZreg x)))
+	// result: (Select0 (ANDCCconst [c&0xFF] x))
+	for {
+		if v_0.Op != OpPPC64ANDCCconst {
+			break
+		}
+		c := auxIntToInt64(v_0.AuxInt)
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpPPC64MOVBZreg {
+			break
+		}
+		x := v_0_0.Args[0]
+		v.reset(OpSelect0)
+		v0 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+		v0.AuxInt = int64ToAuxInt(c & 0xFF)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Select0 (ANDCCconst [c] (MOVHreg x)))
+	// result: (Select0 (ANDCCconst [c&0xFFFF] x))
+	for {
+		if v_0.Op != OpPPC64ANDCCconst {
+			break
+		}
+		c := auxIntToInt64(v_0.AuxInt)
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpPPC64MOVHreg {
+			break
+		}
+		x := v_0_0.Args[0]
+		v.reset(OpSelect0)
+		v0 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+		v0.AuxInt = int64ToAuxInt(c & 0xFFFF)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Select0 (ANDCCconst [c] (MOVHZreg x)))
+	// result: (Select0 (ANDCCconst [c&0xFFFF] x))
+	for {
+		if v_0.Op != OpPPC64ANDCCconst {
+			break
+		}
+		c := auxIntToInt64(v_0.AuxInt)
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpPPC64MOVHZreg {
+			break
+		}
+		x := v_0_0.Args[0]
+		v.reset(OpSelect0)
+		v0 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+		v0.AuxInt = int64ToAuxInt(c & 0xFFFF)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Select0 (ANDCCconst [c] (MOVWreg x)))
+	// result: (Select0 (ANDCCconst [c&0xFFFFFFFF] x))
+	for {
+		if v_0.Op != OpPPC64ANDCCconst {
+			break
+		}
+		c := auxIntToInt64(v_0.AuxInt)
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpPPC64MOVWreg {
+			break
+		}
+		x := v_0_0.Args[0]
+		v.reset(OpSelect0)
+		v0 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+		v0.AuxInt = int64ToAuxInt(c & 0xFFFFFFFF)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (Select0 (ANDCCconst [c] (MOVWZreg x)))
+	// result: (Select0 (ANDCCconst [c&0xFFFFFFFF] x))
+	for {
+		if v_0.Op != OpPPC64ANDCCconst {
+			break
+		}
+		c := auxIntToInt64(v_0.AuxInt)
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpPPC64MOVWZreg {
+			break
+		}
+		x := v_0_0.Args[0]
+		v.reset(OpSelect0)
+		v0 := b.NewValue0(v.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+		v0.AuxInt = int64ToAuxInt(c & 0xFFFFFFFF)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
 	return false
 }
 func rewriteValuePPC64_OpSelect1(v *Value) bool {
 	v_0 := v.Args[0]
 	b := v.Block
 	typ := &b.Func.Config.Types
+	// match: (Select1 (Mul64uhilo x y))
+	// result: (MULLD x y)
+	for {
+		if v_0.Op != OpMul64uhilo {
+			break
+		}
+		y := v_0.Args[1]
+		x := v_0.Args[0]
+		v.reset(OpPPC64MULLD)
+		v.AddArg2(x, y)
+		return true
+	}
 	// match: (Select1 (Add64carry x y c))
 	// result: (ADDZEzero (Select1 <typ.UInt64> (ADDE x y (Select1 <typ.UInt64> (ADDCconst c [-1])))))
 	for {
@@ -17419,41 +16426,53 @@
 	typ := &b.Func.Config.Types
 	switch b.Kind {
 	case BlockPPC64EQ:
-		// match: (EQ (CMPconst [0] (ANDconst [c] x)) yes no)
-		// result: (EQ (ANDCCconst [c] x) yes no)
+		// match: (EQ (CMPconst [0] (Select0 (ANDCCconst [c] x))) yes no)
+		// result: (EQ (Select1 <types.TypeFlags> (ANDCCconst [c] x)) yes no)
 		for b.Controls[0].Op == OpPPC64CMPconst {
 			v_0 := b.Controls[0]
 			if auxIntToInt64(v_0.AuxInt) != 0 {
 				break
 			}
 			v_0_0 := v_0.Args[0]
-			if v_0_0.Op != OpPPC64ANDconst {
+			if v_0_0.Op != OpSelect0 {
 				break
 			}
-			c := auxIntToInt64(v_0_0.AuxInt)
-			x := v_0_0.Args[0]
-			v0 := b.NewValue0(v_0.Pos, OpPPC64ANDCCconst, types.TypeFlags)
-			v0.AuxInt = int64ToAuxInt(c)
-			v0.AddArg(x)
+			v_0_0_0 := v_0_0.Args[0]
+			if v_0_0_0.Op != OpPPC64ANDCCconst {
+				break
+			}
+			c := auxIntToInt64(v_0_0_0.AuxInt)
+			x := v_0_0_0.Args[0]
+			v0 := b.NewValue0(v_0.Pos, OpSelect1, types.TypeFlags)
+			v1 := b.NewValue0(v_0.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+			v1.AuxInt = int64ToAuxInt(c)
+			v1.AddArg(x)
+			v0.AddArg(v1)
 			b.resetWithControl(BlockPPC64EQ, v0)
 			return true
 		}
-		// match: (EQ (CMPWconst [0] (ANDconst [c] x)) yes no)
-		// result: (EQ (ANDCCconst [c] x) yes no)
+		// match: (EQ (CMPWconst [0] (Select0 (ANDCCconst [c] x))) yes no)
+		// result: (EQ (Select1 <types.TypeFlags> (ANDCCconst [c] x)) yes no)
 		for b.Controls[0].Op == OpPPC64CMPWconst {
 			v_0 := b.Controls[0]
 			if auxIntToInt32(v_0.AuxInt) != 0 {
 				break
 			}
 			v_0_0 := v_0.Args[0]
-			if v_0_0.Op != OpPPC64ANDconst {
+			if v_0_0.Op != OpSelect0 {
 				break
 			}
-			c := auxIntToInt64(v_0_0.AuxInt)
-			x := v_0_0.Args[0]
-			v0 := b.NewValue0(v_0.Pos, OpPPC64ANDCCconst, types.TypeFlags)
-			v0.AuxInt = int64ToAuxInt(c)
-			v0.AddArg(x)
+			v_0_0_0 := v_0_0.Args[0]
+			if v_0_0_0.Op != OpPPC64ANDCCconst {
+				break
+			}
+			c := auxIntToInt64(v_0_0_0.AuxInt)
+			x := v_0_0_0.Args[0]
+			v0 := b.NewValue0(v_0.Pos, OpSelect1, types.TypeFlags)
+			v1 := b.NewValue0(v_0.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+			v1.AuxInt = int64ToAuxInt(c)
+			v1.AddArg(x)
+			v0.AddArg(v1)
 			b.resetWithControl(BlockPPC64EQ, v0)
 			return true
 		}
@@ -17485,47 +16504,59 @@
 			b.resetWithControl(BlockPPC64EQ, cmp)
 			return true
 		}
-		// match: (EQ (CMPconst [0] (ANDconst [c] x)) yes no)
-		// result: (EQ (ANDCCconst [c] x) yes no)
+		// match: (EQ (CMPconst [0] (Select0 (ANDCCconst [c] x))) yes no)
+		// result: (EQ (Select1 <types.TypeFlags> (ANDCCconst [c] x)) yes no)
 		for b.Controls[0].Op == OpPPC64CMPconst {
 			v_0 := b.Controls[0]
 			if auxIntToInt64(v_0.AuxInt) != 0 {
 				break
 			}
 			v_0_0 := v_0.Args[0]
-			if v_0_0.Op != OpPPC64ANDconst {
+			if v_0_0.Op != OpSelect0 {
 				break
 			}
-			c := auxIntToInt64(v_0_0.AuxInt)
-			x := v_0_0.Args[0]
-			v0 := b.NewValue0(v_0.Pos, OpPPC64ANDCCconst, types.TypeFlags)
-			v0.AuxInt = int64ToAuxInt(c)
-			v0.AddArg(x)
+			v_0_0_0 := v_0_0.Args[0]
+			if v_0_0_0.Op != OpPPC64ANDCCconst {
+				break
+			}
+			c := auxIntToInt64(v_0_0_0.AuxInt)
+			x := v_0_0_0.Args[0]
+			v0 := b.NewValue0(v_0.Pos, OpSelect1, types.TypeFlags)
+			v1 := b.NewValue0(v_0.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+			v1.AuxInt = int64ToAuxInt(c)
+			v1.AddArg(x)
+			v0.AddArg(v1)
 			b.resetWithControl(BlockPPC64EQ, v0)
 			return true
 		}
-		// match: (EQ (CMPWconst [0] (ANDconst [c] x)) yes no)
-		// result: (EQ (ANDCCconst [c] x) yes no)
+		// match: (EQ (CMPWconst [0] (Select0 (ANDCCconst [c] x))) yes no)
+		// result: (EQ (Select1 <types.TypeFlags> (ANDCCconst [c] x)) yes no)
 		for b.Controls[0].Op == OpPPC64CMPWconst {
 			v_0 := b.Controls[0]
 			if auxIntToInt32(v_0.AuxInt) != 0 {
 				break
 			}
 			v_0_0 := v_0.Args[0]
-			if v_0_0.Op != OpPPC64ANDconst {
+			if v_0_0.Op != OpSelect0 {
 				break
 			}
-			c := auxIntToInt64(v_0_0.AuxInt)
-			x := v_0_0.Args[0]
-			v0 := b.NewValue0(v_0.Pos, OpPPC64ANDCCconst, types.TypeFlags)
-			v0.AuxInt = int64ToAuxInt(c)
-			v0.AddArg(x)
+			v_0_0_0 := v_0_0.Args[0]
+			if v_0_0_0.Op != OpPPC64ANDCCconst {
+				break
+			}
+			c := auxIntToInt64(v_0_0_0.AuxInt)
+			x := v_0_0_0.Args[0]
+			v0 := b.NewValue0(v_0.Pos, OpSelect1, types.TypeFlags)
+			v1 := b.NewValue0(v_0.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+			v1.AuxInt = int64ToAuxInt(c)
+			v1.AddArg(x)
+			v0.AddArg(v1)
 			b.resetWithControl(BlockPPC64EQ, v0)
 			return true
 		}
 		// match: (EQ (CMPconst [0] z:(AND x y)) yes no)
 		// cond: z.Uses == 1
-		// result: (EQ (ANDCC x y) yes no)
+		// result: (EQ (Select1 <types.TypeFlags> (ANDCC x y)) yes no)
 		for b.Controls[0].Op == OpPPC64CMPconst {
 			v_0 := b.Controls[0]
 			if auxIntToInt64(v_0.AuxInt) != 0 {
@@ -17544,8 +16575,10 @@
 				if !(z.Uses == 1) {
 					continue
 				}
-				v0 := b.NewValue0(v_0.Pos, OpPPC64ANDCC, types.TypeFlags)
-				v0.AddArg2(x, y)
+				v0 := b.NewValue0(v_0.Pos, OpSelect1, types.TypeFlags)
+				v1 := b.NewValue0(v_0.Pos, OpPPC64ANDCC, types.NewTuple(typ.Int64, types.TypeFlags))
+				v1.AddArg2(x, y)
+				v0.AddArg(v1)
 				b.resetWithControl(BlockPPC64EQ, v0)
 				return true
 			}
@@ -17553,7 +16586,7 @@
 		}
 		// match: (EQ (CMPconst [0] z:(OR x y)) yes no)
 		// cond: z.Uses == 1
-		// result: (EQ (ORCC x y) yes no)
+		// result: (EQ (Select1 <types.TypeFlags> (ORCC x y)) yes no)
 		for b.Controls[0].Op == OpPPC64CMPconst {
 			v_0 := b.Controls[0]
 			if auxIntToInt64(v_0.AuxInt) != 0 {
@@ -17572,8 +16605,10 @@
 				if !(z.Uses == 1) {
 					continue
 				}
-				v0 := b.NewValue0(v_0.Pos, OpPPC64ORCC, types.TypeFlags)
-				v0.AddArg2(x, y)
+				v0 := b.NewValue0(v_0.Pos, OpSelect1, types.TypeFlags)
+				v1 := b.NewValue0(v_0.Pos, OpPPC64ORCC, types.NewTuple(typ.Int, types.TypeFlags))
+				v1.AddArg2(x, y)
+				v0.AddArg(v1)
 				b.resetWithControl(BlockPPC64EQ, v0)
 				return true
 			}
@@ -17581,7 +16616,7 @@
 		}
 		// match: (EQ (CMPconst [0] z:(XOR x y)) yes no)
 		// cond: z.Uses == 1
-		// result: (EQ (XORCC x y) yes no)
+		// result: (EQ (Select1 <types.TypeFlags> (XORCC x y)) yes no)
 		for b.Controls[0].Op == OpPPC64CMPconst {
 			v_0 := b.Controls[0]
 			if auxIntToInt64(v_0.AuxInt) != 0 {
@@ -17600,8 +16635,10 @@
 				if !(z.Uses == 1) {
 					continue
 				}
-				v0 := b.NewValue0(v_0.Pos, OpPPC64XORCC, types.TypeFlags)
-				v0.AddArg2(x, y)
+				v0 := b.NewValue0(v_0.Pos, OpSelect1, types.TypeFlags)
+				v1 := b.NewValue0(v_0.Pos, OpPPC64XORCC, types.NewTuple(typ.Int, types.TypeFlags))
+				v1.AddArg2(x, y)
+				v0.AddArg(v1)
 				b.resetWithControl(BlockPPC64EQ, v0)
 				return true
 			}
@@ -17635,47 +16672,59 @@
 			b.resetWithControl(BlockPPC64LE, cmp)
 			return true
 		}
-		// match: (GE (CMPconst [0] (ANDconst [c] x)) yes no)
-		// result: (GE (ANDCCconst [c] x) yes no)
+		// match: (GE (CMPconst [0] (Select0 (ANDCCconst [c] x))) yes no)
+		// result: (GE (Select1 <types.TypeFlags> (ANDCCconst [c] x)) yes no)
 		for b.Controls[0].Op == OpPPC64CMPconst {
 			v_0 := b.Controls[0]
 			if auxIntToInt64(v_0.AuxInt) != 0 {
 				break
 			}
 			v_0_0 := v_0.Args[0]
-			if v_0_0.Op != OpPPC64ANDconst {
+			if v_0_0.Op != OpSelect0 {
 				break
 			}
-			c := auxIntToInt64(v_0_0.AuxInt)
-			x := v_0_0.Args[0]
-			v0 := b.NewValue0(v_0.Pos, OpPPC64ANDCCconst, types.TypeFlags)
-			v0.AuxInt = int64ToAuxInt(c)
-			v0.AddArg(x)
+			v_0_0_0 := v_0_0.Args[0]
+			if v_0_0_0.Op != OpPPC64ANDCCconst {
+				break
+			}
+			c := auxIntToInt64(v_0_0_0.AuxInt)
+			x := v_0_0_0.Args[0]
+			v0 := b.NewValue0(v_0.Pos, OpSelect1, types.TypeFlags)
+			v1 := b.NewValue0(v_0.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+			v1.AuxInt = int64ToAuxInt(c)
+			v1.AddArg(x)
+			v0.AddArg(v1)
 			b.resetWithControl(BlockPPC64GE, v0)
 			return true
 		}
-		// match: (GE (CMPWconst [0] (ANDconst [c] x)) yes no)
-		// result: (GE (ANDCCconst [c] x) yes no)
+		// match: (GE (CMPWconst [0] (Select0 (ANDCCconst [c] x))) yes no)
+		// result: (GE (Select1 <types.TypeFlags> (ANDCCconst [c] x)) yes no)
 		for b.Controls[0].Op == OpPPC64CMPWconst {
 			v_0 := b.Controls[0]
 			if auxIntToInt32(v_0.AuxInt) != 0 {
 				break
 			}
 			v_0_0 := v_0.Args[0]
-			if v_0_0.Op != OpPPC64ANDconst {
+			if v_0_0.Op != OpSelect0 {
 				break
 			}
-			c := auxIntToInt64(v_0_0.AuxInt)
-			x := v_0_0.Args[0]
-			v0 := b.NewValue0(v_0.Pos, OpPPC64ANDCCconst, types.TypeFlags)
-			v0.AuxInt = int64ToAuxInt(c)
-			v0.AddArg(x)
+			v_0_0_0 := v_0_0.Args[0]
+			if v_0_0_0.Op != OpPPC64ANDCCconst {
+				break
+			}
+			c := auxIntToInt64(v_0_0_0.AuxInt)
+			x := v_0_0_0.Args[0]
+			v0 := b.NewValue0(v_0.Pos, OpSelect1, types.TypeFlags)
+			v1 := b.NewValue0(v_0.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+			v1.AuxInt = int64ToAuxInt(c)
+			v1.AddArg(x)
+			v0.AddArg(v1)
 			b.resetWithControl(BlockPPC64GE, v0)
 			return true
 		}
 		// match: (GE (CMPconst [0] z:(AND x y)) yes no)
 		// cond: z.Uses == 1
-		// result: (GE (ANDCC x y) yes no)
+		// result: (GE (Select1 <types.TypeFlags> (ANDCC x y)) yes no)
 		for b.Controls[0].Op == OpPPC64CMPconst {
 			v_0 := b.Controls[0]
 			if auxIntToInt64(v_0.AuxInt) != 0 {
@@ -17694,8 +16743,10 @@
 				if !(z.Uses == 1) {
 					continue
 				}
-				v0 := b.NewValue0(v_0.Pos, OpPPC64ANDCC, types.TypeFlags)
-				v0.AddArg2(x, y)
+				v0 := b.NewValue0(v_0.Pos, OpSelect1, types.TypeFlags)
+				v1 := b.NewValue0(v_0.Pos, OpPPC64ANDCC, types.NewTuple(typ.Int64, types.TypeFlags))
+				v1.AddArg2(x, y)
+				v0.AddArg(v1)
 				b.resetWithControl(BlockPPC64GE, v0)
 				return true
 			}
@@ -17703,7 +16754,7 @@
 		}
 		// match: (GE (CMPconst [0] z:(OR x y)) yes no)
 		// cond: z.Uses == 1
-		// result: (GE (ORCC x y) yes no)
+		// result: (GE (Select1 <types.TypeFlags> (ORCC x y)) yes no)
 		for b.Controls[0].Op == OpPPC64CMPconst {
 			v_0 := b.Controls[0]
 			if auxIntToInt64(v_0.AuxInt) != 0 {
@@ -17722,8 +16773,10 @@
 				if !(z.Uses == 1) {
 					continue
 				}
-				v0 := b.NewValue0(v_0.Pos, OpPPC64ORCC, types.TypeFlags)
-				v0.AddArg2(x, y)
+				v0 := b.NewValue0(v_0.Pos, OpSelect1, types.TypeFlags)
+				v1 := b.NewValue0(v_0.Pos, OpPPC64ORCC, types.NewTuple(typ.Int, types.TypeFlags))
+				v1.AddArg2(x, y)
+				v0.AddArg(v1)
 				b.resetWithControl(BlockPPC64GE, v0)
 				return true
 			}
@@ -17731,7 +16784,7 @@
 		}
 		// match: (GE (CMPconst [0] z:(XOR x y)) yes no)
 		// cond: z.Uses == 1
-		// result: (GE (XORCC x y) yes no)
+		// result: (GE (Select1 <types.TypeFlags> (XORCC x y)) yes no)
 		for b.Controls[0].Op == OpPPC64CMPconst {
 			v_0 := b.Controls[0]
 			if auxIntToInt64(v_0.AuxInt) != 0 {
@@ -17750,8 +16803,10 @@
 				if !(z.Uses == 1) {
 					continue
 				}
-				v0 := b.NewValue0(v_0.Pos, OpPPC64XORCC, types.TypeFlags)
-				v0.AddArg2(x, y)
+				v0 := b.NewValue0(v_0.Pos, OpSelect1, types.TypeFlags)
+				v1 := b.NewValue0(v_0.Pos, OpPPC64XORCC, types.NewTuple(typ.Int, types.TypeFlags))
+				v1.AddArg2(x, y)
+				v0.AddArg(v1)
 				b.resetWithControl(BlockPPC64GE, v0)
 				return true
 			}
@@ -17786,47 +16841,59 @@
 			b.resetWithControl(BlockPPC64LT, cmp)
 			return true
 		}
-		// match: (GT (CMPconst [0] (ANDconst [c] x)) yes no)
-		// result: (GT (ANDCCconst [c] x) yes no)
+		// match: (GT (CMPconst [0] (Select0 (ANDCCconst [c] x))) yes no)
+		// result: (GT (Select1 <types.TypeFlags> (ANDCCconst [c] x)) yes no)
 		for b.Controls[0].Op == OpPPC64CMPconst {
 			v_0 := b.Controls[0]
 			if auxIntToInt64(v_0.AuxInt) != 0 {
 				break
 			}
 			v_0_0 := v_0.Args[0]
-			if v_0_0.Op != OpPPC64ANDconst {
+			if v_0_0.Op != OpSelect0 {
 				break
 			}
-			c := auxIntToInt64(v_0_0.AuxInt)
-			x := v_0_0.Args[0]
-			v0 := b.NewValue0(v_0.Pos, OpPPC64ANDCCconst, types.TypeFlags)
-			v0.AuxInt = int64ToAuxInt(c)
-			v0.AddArg(x)
+			v_0_0_0 := v_0_0.Args[0]
+			if v_0_0_0.Op != OpPPC64ANDCCconst {
+				break
+			}
+			c := auxIntToInt64(v_0_0_0.AuxInt)
+			x := v_0_0_0.Args[0]
+			v0 := b.NewValue0(v_0.Pos, OpSelect1, types.TypeFlags)
+			v1 := b.NewValue0(v_0.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+			v1.AuxInt = int64ToAuxInt(c)
+			v1.AddArg(x)
+			v0.AddArg(v1)
 			b.resetWithControl(BlockPPC64GT, v0)
 			return true
 		}
-		// match: (GT (CMPWconst [0] (ANDconst [c] x)) yes no)
-		// result: (GT (ANDCCconst [c] x) yes no)
+		// match: (GT (CMPWconst [0] (Select0 (ANDCCconst [c] x))) yes no)
+		// result: (GT (Select1 <types.TypeFlags> (ANDCCconst [c] x)) yes no)
 		for b.Controls[0].Op == OpPPC64CMPWconst {
 			v_0 := b.Controls[0]
 			if auxIntToInt32(v_0.AuxInt) != 0 {
 				break
 			}
 			v_0_0 := v_0.Args[0]
-			if v_0_0.Op != OpPPC64ANDconst {
+			if v_0_0.Op != OpSelect0 {
 				break
 			}
-			c := auxIntToInt64(v_0_0.AuxInt)
-			x := v_0_0.Args[0]
-			v0 := b.NewValue0(v_0.Pos, OpPPC64ANDCCconst, types.TypeFlags)
-			v0.AuxInt = int64ToAuxInt(c)
-			v0.AddArg(x)
+			v_0_0_0 := v_0_0.Args[0]
+			if v_0_0_0.Op != OpPPC64ANDCCconst {
+				break
+			}
+			c := auxIntToInt64(v_0_0_0.AuxInt)
+			x := v_0_0_0.Args[0]
+			v0 := b.NewValue0(v_0.Pos, OpSelect1, types.TypeFlags)
+			v1 := b.NewValue0(v_0.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+			v1.AuxInt = int64ToAuxInt(c)
+			v1.AddArg(x)
+			v0.AddArg(v1)
 			b.resetWithControl(BlockPPC64GT, v0)
 			return true
 		}
 		// match: (GT (CMPconst [0] z:(AND x y)) yes no)
 		// cond: z.Uses == 1
-		// result: (GT (ANDCC x y) yes no)
+		// result: (GT (Select1 <types.TypeFlags> (ANDCC x y)) yes no)
 		for b.Controls[0].Op == OpPPC64CMPconst {
 			v_0 := b.Controls[0]
 			if auxIntToInt64(v_0.AuxInt) != 0 {
@@ -17845,8 +16912,10 @@
 				if !(z.Uses == 1) {
 					continue
 				}
-				v0 := b.NewValue0(v_0.Pos, OpPPC64ANDCC, types.TypeFlags)
-				v0.AddArg2(x, y)
+				v0 := b.NewValue0(v_0.Pos, OpSelect1, types.TypeFlags)
+				v1 := b.NewValue0(v_0.Pos, OpPPC64ANDCC, types.NewTuple(typ.Int64, types.TypeFlags))
+				v1.AddArg2(x, y)
+				v0.AddArg(v1)
 				b.resetWithControl(BlockPPC64GT, v0)
 				return true
 			}
@@ -17854,7 +16923,7 @@
 		}
 		// match: (GT (CMPconst [0] z:(OR x y)) yes no)
 		// cond: z.Uses == 1
-		// result: (GT (ORCC x y) yes no)
+		// result: (GT (Select1 <types.TypeFlags> (ORCC x y)) yes no)
 		for b.Controls[0].Op == OpPPC64CMPconst {
 			v_0 := b.Controls[0]
 			if auxIntToInt64(v_0.AuxInt) != 0 {
@@ -17873,8 +16942,10 @@
 				if !(z.Uses == 1) {
 					continue
 				}
-				v0 := b.NewValue0(v_0.Pos, OpPPC64ORCC, types.TypeFlags)
-				v0.AddArg2(x, y)
+				v0 := b.NewValue0(v_0.Pos, OpSelect1, types.TypeFlags)
+				v1 := b.NewValue0(v_0.Pos, OpPPC64ORCC, types.NewTuple(typ.Int, types.TypeFlags))
+				v1.AddArg2(x, y)
+				v0.AddArg(v1)
 				b.resetWithControl(BlockPPC64GT, v0)
 				return true
 			}
@@ -17882,7 +16953,7 @@
 		}
 		// match: (GT (CMPconst [0] z:(XOR x y)) yes no)
 		// cond: z.Uses == 1
-		// result: (GT (XORCC x y) yes no)
+		// result: (GT (Select1 <types.TypeFlags> (XORCC x y)) yes no)
 		for b.Controls[0].Op == OpPPC64CMPconst {
 			v_0 := b.Controls[0]
 			if auxIntToInt64(v_0.AuxInt) != 0 {
@@ -17901,8 +16972,10 @@
 				if !(z.Uses == 1) {
 					continue
 				}
-				v0 := b.NewValue0(v_0.Pos, OpPPC64XORCC, types.TypeFlags)
-				v0.AddArg2(x, y)
+				v0 := b.NewValue0(v_0.Pos, OpSelect1, types.TypeFlags)
+				v1 := b.NewValue0(v_0.Pos, OpPPC64XORCC, types.NewTuple(typ.Int, types.TypeFlags))
+				v1.AddArg2(x, y)
+				v0.AddArg(v1)
 				b.resetWithControl(BlockPPC64GT, v0)
 				return true
 			}
@@ -17990,14 +17063,16 @@
 			return true
 		}
 		// match: (If cond yes no)
-		// result: (NE (CMPWconst [0] (ANDconst <typ.UInt32> [1] cond)) yes no)
+		// result: (NE (CMPWconst [0] (Select0 <typ.UInt32> (ANDCCconst [1] cond))) yes no)
 		for {
 			cond := b.Controls[0]
 			v0 := b.NewValue0(cond.Pos, OpPPC64CMPWconst, types.TypeFlags)
 			v0.AuxInt = int32ToAuxInt(0)
-			v1 := b.NewValue0(cond.Pos, OpPPC64ANDconst, typ.UInt32)
-			v1.AuxInt = int64ToAuxInt(1)
-			v1.AddArg(cond)
+			v1 := b.NewValue0(cond.Pos, OpSelect0, typ.UInt32)
+			v2 := b.NewValue0(cond.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+			v2.AuxInt = int64ToAuxInt(1)
+			v2.AddArg(cond)
+			v1.AddArg(v2)
 			v0.AddArg(v1)
 			b.resetWithControl(BlockPPC64NE, v0)
 			return true
@@ -18030,47 +17105,59 @@
 			b.resetWithControl(BlockPPC64GE, cmp)
 			return true
 		}
-		// match: (LE (CMPconst [0] (ANDconst [c] x)) yes no)
-		// result: (LE (ANDCCconst [c] x) yes no)
+		// match: (LE (CMPconst [0] (Select0 (ANDCCconst [c] x))) yes no)
+		// result: (LE (Select1 <types.TypeFlags> (ANDCCconst [c] x)) yes no)
 		for b.Controls[0].Op == OpPPC64CMPconst {
 			v_0 := b.Controls[0]
 			if auxIntToInt64(v_0.AuxInt) != 0 {
 				break
 			}
 			v_0_0 := v_0.Args[0]
-			if v_0_0.Op != OpPPC64ANDconst {
+			if v_0_0.Op != OpSelect0 {
 				break
 			}
-			c := auxIntToInt64(v_0_0.AuxInt)
-			x := v_0_0.Args[0]
-			v0 := b.NewValue0(v_0.Pos, OpPPC64ANDCCconst, types.TypeFlags)
-			v0.AuxInt = int64ToAuxInt(c)
-			v0.AddArg(x)
+			v_0_0_0 := v_0_0.Args[0]
+			if v_0_0_0.Op != OpPPC64ANDCCconst {
+				break
+			}
+			c := auxIntToInt64(v_0_0_0.AuxInt)
+			x := v_0_0_0.Args[0]
+			v0 := b.NewValue0(v_0.Pos, OpSelect1, types.TypeFlags)
+			v1 := b.NewValue0(v_0.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+			v1.AuxInt = int64ToAuxInt(c)
+			v1.AddArg(x)
+			v0.AddArg(v1)
 			b.resetWithControl(BlockPPC64LE, v0)
 			return true
 		}
-		// match: (LE (CMPWconst [0] (ANDconst [c] x)) yes no)
-		// result: (LE (ANDCCconst [c] x) yes no)
+		// match: (LE (CMPWconst [0] (Select0 (ANDCCconst [c] x))) yes no)
+		// result: (LE (Select1 <types.TypeFlags> (ANDCCconst [c] x)) yes no)
 		for b.Controls[0].Op == OpPPC64CMPWconst {
 			v_0 := b.Controls[0]
 			if auxIntToInt32(v_0.AuxInt) != 0 {
 				break
 			}
 			v_0_0 := v_0.Args[0]
-			if v_0_0.Op != OpPPC64ANDconst {
+			if v_0_0.Op != OpSelect0 {
 				break
 			}
-			c := auxIntToInt64(v_0_0.AuxInt)
-			x := v_0_0.Args[0]
-			v0 := b.NewValue0(v_0.Pos, OpPPC64ANDCCconst, types.TypeFlags)
-			v0.AuxInt = int64ToAuxInt(c)
-			v0.AddArg(x)
+			v_0_0_0 := v_0_0.Args[0]
+			if v_0_0_0.Op != OpPPC64ANDCCconst {
+				break
+			}
+			c := auxIntToInt64(v_0_0_0.AuxInt)
+			x := v_0_0_0.Args[0]
+			v0 := b.NewValue0(v_0.Pos, OpSelect1, types.TypeFlags)
+			v1 := b.NewValue0(v_0.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+			v1.AuxInt = int64ToAuxInt(c)
+			v1.AddArg(x)
+			v0.AddArg(v1)
 			b.resetWithControl(BlockPPC64LE, v0)
 			return true
 		}
 		// match: (LE (CMPconst [0] z:(AND x y)) yes no)
 		// cond: z.Uses == 1
-		// result: (LE (ANDCC x y) yes no)
+		// result: (LE (Select1 <types.TypeFlags> (ANDCC x y)) yes no)
 		for b.Controls[0].Op == OpPPC64CMPconst {
 			v_0 := b.Controls[0]
 			if auxIntToInt64(v_0.AuxInt) != 0 {
@@ -18089,8 +17176,10 @@
 				if !(z.Uses == 1) {
 					continue
 				}
-				v0 := b.NewValue0(v_0.Pos, OpPPC64ANDCC, types.TypeFlags)
-				v0.AddArg2(x, y)
+				v0 := b.NewValue0(v_0.Pos, OpSelect1, types.TypeFlags)
+				v1 := b.NewValue0(v_0.Pos, OpPPC64ANDCC, types.NewTuple(typ.Int64, types.TypeFlags))
+				v1.AddArg2(x, y)
+				v0.AddArg(v1)
 				b.resetWithControl(BlockPPC64LE, v0)
 				return true
 			}
@@ -18098,7 +17187,7 @@
 		}
 		// match: (LE (CMPconst [0] z:(OR x y)) yes no)
 		// cond: z.Uses == 1
-		// result: (LE (ORCC x y) yes no)
+		// result: (LE (Select1 <types.TypeFlags> (ORCC x y)) yes no)
 		for b.Controls[0].Op == OpPPC64CMPconst {
 			v_0 := b.Controls[0]
 			if auxIntToInt64(v_0.AuxInt) != 0 {
@@ -18117,8 +17206,10 @@
 				if !(z.Uses == 1) {
 					continue
 				}
-				v0 := b.NewValue0(v_0.Pos, OpPPC64ORCC, types.TypeFlags)
-				v0.AddArg2(x, y)
+				v0 := b.NewValue0(v_0.Pos, OpSelect1, types.TypeFlags)
+				v1 := b.NewValue0(v_0.Pos, OpPPC64ORCC, types.NewTuple(typ.Int, types.TypeFlags))
+				v1.AddArg2(x, y)
+				v0.AddArg(v1)
 				b.resetWithControl(BlockPPC64LE, v0)
 				return true
 			}
@@ -18126,7 +17217,7 @@
 		}
 		// match: (LE (CMPconst [0] z:(XOR x y)) yes no)
 		// cond: z.Uses == 1
-		// result: (LE (XORCC x y) yes no)
+		// result: (LE (Select1 <types.TypeFlags> (XORCC x y)) yes no)
 		for b.Controls[0].Op == OpPPC64CMPconst {
 			v_0 := b.Controls[0]
 			if auxIntToInt64(v_0.AuxInt) != 0 {
@@ -18145,8 +17236,10 @@
 				if !(z.Uses == 1) {
 					continue
 				}
-				v0 := b.NewValue0(v_0.Pos, OpPPC64XORCC, types.TypeFlags)
-				v0.AddArg2(x, y)
+				v0 := b.NewValue0(v_0.Pos, OpSelect1, types.TypeFlags)
+				v1 := b.NewValue0(v_0.Pos, OpPPC64XORCC, types.NewTuple(typ.Int, types.TypeFlags))
+				v1.AddArg2(x, y)
+				v0.AddArg(v1)
 				b.resetWithControl(BlockPPC64LE, v0)
 				return true
 			}
@@ -18181,47 +17274,59 @@
 			b.resetWithControl(BlockPPC64GT, cmp)
 			return true
 		}
-		// match: (LT (CMPconst [0] (ANDconst [c] x)) yes no)
-		// result: (LT (ANDCCconst [c] x) yes no)
+		// match: (LT (CMPconst [0] (Select0 (ANDCCconst [c] x))) yes no)
+		// result: (LT (Select1 <types.TypeFlags> (ANDCCconst [c] x)) yes no)
 		for b.Controls[0].Op == OpPPC64CMPconst {
 			v_0 := b.Controls[0]
 			if auxIntToInt64(v_0.AuxInt) != 0 {
 				break
 			}
 			v_0_0 := v_0.Args[0]
-			if v_0_0.Op != OpPPC64ANDconst {
+			if v_0_0.Op != OpSelect0 {
 				break
 			}
-			c := auxIntToInt64(v_0_0.AuxInt)
-			x := v_0_0.Args[0]
-			v0 := b.NewValue0(v_0.Pos, OpPPC64ANDCCconst, types.TypeFlags)
-			v0.AuxInt = int64ToAuxInt(c)
-			v0.AddArg(x)
+			v_0_0_0 := v_0_0.Args[0]
+			if v_0_0_0.Op != OpPPC64ANDCCconst {
+				break
+			}
+			c := auxIntToInt64(v_0_0_0.AuxInt)
+			x := v_0_0_0.Args[0]
+			v0 := b.NewValue0(v_0.Pos, OpSelect1, types.TypeFlags)
+			v1 := b.NewValue0(v_0.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+			v1.AuxInt = int64ToAuxInt(c)
+			v1.AddArg(x)
+			v0.AddArg(v1)
 			b.resetWithControl(BlockPPC64LT, v0)
 			return true
 		}
-		// match: (LT (CMPWconst [0] (ANDconst [c] x)) yes no)
-		// result: (LT (ANDCCconst [c] x) yes no)
+		// match: (LT (CMPWconst [0] (Select0 (ANDCCconst [c] x))) yes no)
+		// result: (LT (Select1 <types.TypeFlags> (ANDCCconst [c] x)) yes no)
 		for b.Controls[0].Op == OpPPC64CMPWconst {
 			v_0 := b.Controls[0]
 			if auxIntToInt32(v_0.AuxInt) != 0 {
 				break
 			}
 			v_0_0 := v_0.Args[0]
-			if v_0_0.Op != OpPPC64ANDconst {
+			if v_0_0.Op != OpSelect0 {
 				break
 			}
-			c := auxIntToInt64(v_0_0.AuxInt)
-			x := v_0_0.Args[0]
-			v0 := b.NewValue0(v_0.Pos, OpPPC64ANDCCconst, types.TypeFlags)
-			v0.AuxInt = int64ToAuxInt(c)
-			v0.AddArg(x)
+			v_0_0_0 := v_0_0.Args[0]
+			if v_0_0_0.Op != OpPPC64ANDCCconst {
+				break
+			}
+			c := auxIntToInt64(v_0_0_0.AuxInt)
+			x := v_0_0_0.Args[0]
+			v0 := b.NewValue0(v_0.Pos, OpSelect1, types.TypeFlags)
+			v1 := b.NewValue0(v_0.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+			v1.AuxInt = int64ToAuxInt(c)
+			v1.AddArg(x)
+			v0.AddArg(v1)
 			b.resetWithControl(BlockPPC64LT, v0)
 			return true
 		}
 		// match: (LT (CMPconst [0] z:(AND x y)) yes no)
 		// cond: z.Uses == 1
-		// result: (LT (ANDCC x y) yes no)
+		// result: (LT (Select1 <types.TypeFlags> (ANDCC x y)) yes no)
 		for b.Controls[0].Op == OpPPC64CMPconst {
 			v_0 := b.Controls[0]
 			if auxIntToInt64(v_0.AuxInt) != 0 {
@@ -18240,8 +17345,10 @@
 				if !(z.Uses == 1) {
 					continue
 				}
-				v0 := b.NewValue0(v_0.Pos, OpPPC64ANDCC, types.TypeFlags)
-				v0.AddArg2(x, y)
+				v0 := b.NewValue0(v_0.Pos, OpSelect1, types.TypeFlags)
+				v1 := b.NewValue0(v_0.Pos, OpPPC64ANDCC, types.NewTuple(typ.Int64, types.TypeFlags))
+				v1.AddArg2(x, y)
+				v0.AddArg(v1)
 				b.resetWithControl(BlockPPC64LT, v0)
 				return true
 			}
@@ -18249,7 +17356,7 @@
 		}
 		// match: (LT (CMPconst [0] z:(OR x y)) yes no)
 		// cond: z.Uses == 1
-		// result: (LT (ORCC x y) yes no)
+		// result: (LT (Select1 <types.TypeFlags> (ORCC x y)) yes no)
 		for b.Controls[0].Op == OpPPC64CMPconst {
 			v_0 := b.Controls[0]
 			if auxIntToInt64(v_0.AuxInt) != 0 {
@@ -18268,8 +17375,10 @@
 				if !(z.Uses == 1) {
 					continue
 				}
-				v0 := b.NewValue0(v_0.Pos, OpPPC64ORCC, types.TypeFlags)
-				v0.AddArg2(x, y)
+				v0 := b.NewValue0(v_0.Pos, OpSelect1, types.TypeFlags)
+				v1 := b.NewValue0(v_0.Pos, OpPPC64ORCC, types.NewTuple(typ.Int, types.TypeFlags))
+				v1.AddArg2(x, y)
+				v0.AddArg(v1)
 				b.resetWithControl(BlockPPC64LT, v0)
 				return true
 			}
@@ -18277,7 +17386,7 @@
 		}
 		// match: (LT (CMPconst [0] z:(XOR x y)) yes no)
 		// cond: z.Uses == 1
-		// result: (LT (XORCC x y) yes no)
+		// result: (LT (Select1 <types.TypeFlags> (XORCC x y)) yes no)
 		for b.Controls[0].Op == OpPPC64CMPconst {
 			v_0 := b.Controls[0]
 			if auxIntToInt64(v_0.AuxInt) != 0 {
@@ -18296,15 +17405,17 @@
 				if !(z.Uses == 1) {
 					continue
 				}
-				v0 := b.NewValue0(v_0.Pos, OpPPC64XORCC, types.TypeFlags)
-				v0.AddArg2(x, y)
+				v0 := b.NewValue0(v_0.Pos, OpSelect1, types.TypeFlags)
+				v1 := b.NewValue0(v_0.Pos, OpPPC64XORCC, types.NewTuple(typ.Int, types.TypeFlags))
+				v1.AddArg2(x, y)
+				v0.AddArg(v1)
 				b.resetWithControl(BlockPPC64LT, v0)
 				return true
 			}
 			break
 		}
 	case BlockPPC64NE:
-		// match: (NE (CMPWconst [0] (ANDconst [1] (Equal cc))) yes no)
+		// match: (NE (CMPWconst [0] (Select0 (ANDCCconst [1] (Equal cc)))) yes no)
 		// result: (EQ cc yes no)
 		for b.Controls[0].Op == OpPPC64CMPWconst {
 			v_0 := b.Controls[0]
@@ -18312,18 +17423,22 @@
 				break
 			}
 			v_0_0 := v_0.Args[0]
-			if v_0_0.Op != OpPPC64ANDconst || auxIntToInt64(v_0_0.AuxInt) != 1 {
+			if v_0_0.Op != OpSelect0 {
 				break
 			}
 			v_0_0_0 := v_0_0.Args[0]
-			if v_0_0_0.Op != OpPPC64Equal {
+			if v_0_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0_0_0.AuxInt) != 1 {
 				break
 			}
-			cc := v_0_0_0.Args[0]
+			v_0_0_0_0 := v_0_0_0.Args[0]
+			if v_0_0_0_0.Op != OpPPC64Equal {
+				break
+			}
+			cc := v_0_0_0_0.Args[0]
 			b.resetWithControl(BlockPPC64EQ, cc)
 			return true
 		}
-		// match: (NE (CMPWconst [0] (ANDconst [1] (NotEqual cc))) yes no)
+		// match: (NE (CMPWconst [0] (Select0 (ANDCCconst [1] (NotEqual cc)))) yes no)
 		// result: (NE cc yes no)
 		for b.Controls[0].Op == OpPPC64CMPWconst {
 			v_0 := b.Controls[0]
@@ -18331,18 +17446,22 @@
 				break
 			}
 			v_0_0 := v_0.Args[0]
-			if v_0_0.Op != OpPPC64ANDconst || auxIntToInt64(v_0_0.AuxInt) != 1 {
+			if v_0_0.Op != OpSelect0 {
 				break
 			}
 			v_0_0_0 := v_0_0.Args[0]
-			if v_0_0_0.Op != OpPPC64NotEqual {
+			if v_0_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0_0_0.AuxInt) != 1 {
 				break
 			}
-			cc := v_0_0_0.Args[0]
+			v_0_0_0_0 := v_0_0_0.Args[0]
+			if v_0_0_0_0.Op != OpPPC64NotEqual {
+				break
+			}
+			cc := v_0_0_0_0.Args[0]
 			b.resetWithControl(BlockPPC64NE, cc)
 			return true
 		}
-		// match: (NE (CMPWconst [0] (ANDconst [1] (LessThan cc))) yes no)
+		// match: (NE (CMPWconst [0] (Select0 (ANDCCconst [1] (LessThan cc)))) yes no)
 		// result: (LT cc yes no)
 		for b.Controls[0].Op == OpPPC64CMPWconst {
 			v_0 := b.Controls[0]
@@ -18350,18 +17469,22 @@
 				break
 			}
 			v_0_0 := v_0.Args[0]
-			if v_0_0.Op != OpPPC64ANDconst || auxIntToInt64(v_0_0.AuxInt) != 1 {
+			if v_0_0.Op != OpSelect0 {
 				break
 			}
 			v_0_0_0 := v_0_0.Args[0]
-			if v_0_0_0.Op != OpPPC64LessThan {
+			if v_0_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0_0_0.AuxInt) != 1 {
 				break
 			}
-			cc := v_0_0_0.Args[0]
+			v_0_0_0_0 := v_0_0_0.Args[0]
+			if v_0_0_0_0.Op != OpPPC64LessThan {
+				break
+			}
+			cc := v_0_0_0_0.Args[0]
 			b.resetWithControl(BlockPPC64LT, cc)
 			return true
 		}
-		// match: (NE (CMPWconst [0] (ANDconst [1] (LessEqual cc))) yes no)
+		// match: (NE (CMPWconst [0] (Select0 (ANDCCconst [1] (LessEqual cc)))) yes no)
 		// result: (LE cc yes no)
 		for b.Controls[0].Op == OpPPC64CMPWconst {
 			v_0 := b.Controls[0]
@@ -18369,18 +17492,22 @@
 				break
 			}
 			v_0_0 := v_0.Args[0]
-			if v_0_0.Op != OpPPC64ANDconst || auxIntToInt64(v_0_0.AuxInt) != 1 {
+			if v_0_0.Op != OpSelect0 {
 				break
 			}
 			v_0_0_0 := v_0_0.Args[0]
-			if v_0_0_0.Op != OpPPC64LessEqual {
+			if v_0_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0_0_0.AuxInt) != 1 {
 				break
 			}
-			cc := v_0_0_0.Args[0]
+			v_0_0_0_0 := v_0_0_0.Args[0]
+			if v_0_0_0_0.Op != OpPPC64LessEqual {
+				break
+			}
+			cc := v_0_0_0_0.Args[0]
 			b.resetWithControl(BlockPPC64LE, cc)
 			return true
 		}
-		// match: (NE (CMPWconst [0] (ANDconst [1] (GreaterThan cc))) yes no)
+		// match: (NE (CMPWconst [0] (Select0 (ANDCCconst [1] (GreaterThan cc)))) yes no)
 		// result: (GT cc yes no)
 		for b.Controls[0].Op == OpPPC64CMPWconst {
 			v_0 := b.Controls[0]
@@ -18388,18 +17515,22 @@
 				break
 			}
 			v_0_0 := v_0.Args[0]
-			if v_0_0.Op != OpPPC64ANDconst || auxIntToInt64(v_0_0.AuxInt) != 1 {
+			if v_0_0.Op != OpSelect0 {
 				break
 			}
 			v_0_0_0 := v_0_0.Args[0]
-			if v_0_0_0.Op != OpPPC64GreaterThan {
+			if v_0_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0_0_0.AuxInt) != 1 {
 				break
 			}
-			cc := v_0_0_0.Args[0]
+			v_0_0_0_0 := v_0_0_0.Args[0]
+			if v_0_0_0_0.Op != OpPPC64GreaterThan {
+				break
+			}
+			cc := v_0_0_0_0.Args[0]
 			b.resetWithControl(BlockPPC64GT, cc)
 			return true
 		}
-		// match: (NE (CMPWconst [0] (ANDconst [1] (GreaterEqual cc))) yes no)
+		// match: (NE (CMPWconst [0] (Select0 (ANDCCconst [1] (GreaterEqual cc)))) yes no)
 		// result: (GE cc yes no)
 		for b.Controls[0].Op == OpPPC64CMPWconst {
 			v_0 := b.Controls[0]
@@ -18407,18 +17538,22 @@
 				break
 			}
 			v_0_0 := v_0.Args[0]
-			if v_0_0.Op != OpPPC64ANDconst || auxIntToInt64(v_0_0.AuxInt) != 1 {
+			if v_0_0.Op != OpSelect0 {
 				break
 			}
 			v_0_0_0 := v_0_0.Args[0]
-			if v_0_0_0.Op != OpPPC64GreaterEqual {
+			if v_0_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0_0_0.AuxInt) != 1 {
 				break
 			}
-			cc := v_0_0_0.Args[0]
+			v_0_0_0_0 := v_0_0_0.Args[0]
+			if v_0_0_0_0.Op != OpPPC64GreaterEqual {
+				break
+			}
+			cc := v_0_0_0_0.Args[0]
 			b.resetWithControl(BlockPPC64GE, cc)
 			return true
 		}
-		// match: (NE (CMPWconst [0] (ANDconst [1] (FLessThan cc))) yes no)
+		// match: (NE (CMPWconst [0] (Select0 (ANDCCconst [1] (FLessThan cc)))) yes no)
 		// result: (FLT cc yes no)
 		for b.Controls[0].Op == OpPPC64CMPWconst {
 			v_0 := b.Controls[0]
@@ -18426,18 +17561,22 @@
 				break
 			}
 			v_0_0 := v_0.Args[0]
-			if v_0_0.Op != OpPPC64ANDconst || auxIntToInt64(v_0_0.AuxInt) != 1 {
+			if v_0_0.Op != OpSelect0 {
 				break
 			}
 			v_0_0_0 := v_0_0.Args[0]
-			if v_0_0_0.Op != OpPPC64FLessThan {
+			if v_0_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0_0_0.AuxInt) != 1 {
 				break
 			}
-			cc := v_0_0_0.Args[0]
+			v_0_0_0_0 := v_0_0_0.Args[0]
+			if v_0_0_0_0.Op != OpPPC64FLessThan {
+				break
+			}
+			cc := v_0_0_0_0.Args[0]
 			b.resetWithControl(BlockPPC64FLT, cc)
 			return true
 		}
-		// match: (NE (CMPWconst [0] (ANDconst [1] (FLessEqual cc))) yes no)
+		// match: (NE (CMPWconst [0] (Select0 (ANDCCconst [1] (FLessEqual cc)))) yes no)
 		// result: (FLE cc yes no)
 		for b.Controls[0].Op == OpPPC64CMPWconst {
 			v_0 := b.Controls[0]
@@ -18445,18 +17584,22 @@
 				break
 			}
 			v_0_0 := v_0.Args[0]
-			if v_0_0.Op != OpPPC64ANDconst || auxIntToInt64(v_0_0.AuxInt) != 1 {
+			if v_0_0.Op != OpSelect0 {
 				break
 			}
 			v_0_0_0 := v_0_0.Args[0]
-			if v_0_0_0.Op != OpPPC64FLessEqual {
+			if v_0_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0_0_0.AuxInt) != 1 {
 				break
 			}
-			cc := v_0_0_0.Args[0]
+			v_0_0_0_0 := v_0_0_0.Args[0]
+			if v_0_0_0_0.Op != OpPPC64FLessEqual {
+				break
+			}
+			cc := v_0_0_0_0.Args[0]
 			b.resetWithControl(BlockPPC64FLE, cc)
 			return true
 		}
-		// match: (NE (CMPWconst [0] (ANDconst [1] (FGreaterThan cc))) yes no)
+		// match: (NE (CMPWconst [0] (Select0 (ANDCCconst [1] (FGreaterThan cc)))) yes no)
 		// result: (FGT cc yes no)
 		for b.Controls[0].Op == OpPPC64CMPWconst {
 			v_0 := b.Controls[0]
@@ -18464,18 +17607,22 @@
 				break
 			}
 			v_0_0 := v_0.Args[0]
-			if v_0_0.Op != OpPPC64ANDconst || auxIntToInt64(v_0_0.AuxInt) != 1 {
+			if v_0_0.Op != OpSelect0 {
 				break
 			}
 			v_0_0_0 := v_0_0.Args[0]
-			if v_0_0_0.Op != OpPPC64FGreaterThan {
+			if v_0_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0_0_0.AuxInt) != 1 {
 				break
 			}
-			cc := v_0_0_0.Args[0]
+			v_0_0_0_0 := v_0_0_0.Args[0]
+			if v_0_0_0_0.Op != OpPPC64FGreaterThan {
+				break
+			}
+			cc := v_0_0_0_0.Args[0]
 			b.resetWithControl(BlockPPC64FGT, cc)
 			return true
 		}
-		// match: (NE (CMPWconst [0] (ANDconst [1] (FGreaterEqual cc))) yes no)
+		// match: (NE (CMPWconst [0] (Select0 (ANDCCconst [1] (FGreaterEqual cc)))) yes no)
 		// result: (FGE cc yes no)
 		for b.Controls[0].Op == OpPPC64CMPWconst {
 			v_0 := b.Controls[0]
@@ -18483,52 +17630,68 @@
 				break
 			}
 			v_0_0 := v_0.Args[0]
-			if v_0_0.Op != OpPPC64ANDconst || auxIntToInt64(v_0_0.AuxInt) != 1 {
+			if v_0_0.Op != OpSelect0 {
 				break
 			}
 			v_0_0_0 := v_0_0.Args[0]
-			if v_0_0_0.Op != OpPPC64FGreaterEqual {
+			if v_0_0_0.Op != OpPPC64ANDCCconst || auxIntToInt64(v_0_0_0.AuxInt) != 1 {
 				break
 			}
-			cc := v_0_0_0.Args[0]
+			v_0_0_0_0 := v_0_0_0.Args[0]
+			if v_0_0_0_0.Op != OpPPC64FGreaterEqual {
+				break
+			}
+			cc := v_0_0_0_0.Args[0]
 			b.resetWithControl(BlockPPC64FGE, cc)
 			return true
 		}
-		// match: (NE (CMPconst [0] (ANDconst [c] x)) yes no)
-		// result: (NE (ANDCCconst [c] x) yes no)
+		// match: (NE (CMPconst [0] (Select0 (ANDCCconst [c] x))) yes no)
+		// result: (NE (Select1 <types.TypeFlags> (ANDCCconst [c] x)) yes no)
 		for b.Controls[0].Op == OpPPC64CMPconst {
 			v_0 := b.Controls[0]
 			if auxIntToInt64(v_0.AuxInt) != 0 {
 				break
 			}
 			v_0_0 := v_0.Args[0]
-			if v_0_0.Op != OpPPC64ANDconst {
+			if v_0_0.Op != OpSelect0 {
 				break
 			}
-			c := auxIntToInt64(v_0_0.AuxInt)
-			x := v_0_0.Args[0]
-			v0 := b.NewValue0(v_0.Pos, OpPPC64ANDCCconst, types.TypeFlags)
-			v0.AuxInt = int64ToAuxInt(c)
-			v0.AddArg(x)
+			v_0_0_0 := v_0_0.Args[0]
+			if v_0_0_0.Op != OpPPC64ANDCCconst {
+				break
+			}
+			c := auxIntToInt64(v_0_0_0.AuxInt)
+			x := v_0_0_0.Args[0]
+			v0 := b.NewValue0(v_0.Pos, OpSelect1, types.TypeFlags)
+			v1 := b.NewValue0(v_0.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+			v1.AuxInt = int64ToAuxInt(c)
+			v1.AddArg(x)
+			v0.AddArg(v1)
 			b.resetWithControl(BlockPPC64NE, v0)
 			return true
 		}
-		// match: (NE (CMPWconst [0] (ANDconst [c] x)) yes no)
-		// result: (NE (ANDCCconst [c] x) yes no)
+		// match: (NE (CMPWconst [0] (Select0 (ANDCCconst [c] x))) yes no)
+		// result: (NE (Select1 <types.TypeFlags> (ANDCCconst [c] x)) yes no)
 		for b.Controls[0].Op == OpPPC64CMPWconst {
 			v_0 := b.Controls[0]
 			if auxIntToInt32(v_0.AuxInt) != 0 {
 				break
 			}
 			v_0_0 := v_0.Args[0]
-			if v_0_0.Op != OpPPC64ANDconst {
+			if v_0_0.Op != OpSelect0 {
 				break
 			}
-			c := auxIntToInt64(v_0_0.AuxInt)
-			x := v_0_0.Args[0]
-			v0 := b.NewValue0(v_0.Pos, OpPPC64ANDCCconst, types.TypeFlags)
-			v0.AuxInt = int64ToAuxInt(c)
-			v0.AddArg(x)
+			v_0_0_0 := v_0_0.Args[0]
+			if v_0_0_0.Op != OpPPC64ANDCCconst {
+				break
+			}
+			c := auxIntToInt64(v_0_0_0.AuxInt)
+			x := v_0_0_0.Args[0]
+			v0 := b.NewValue0(v_0.Pos, OpSelect1, types.TypeFlags)
+			v1 := b.NewValue0(v_0.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+			v1.AuxInt = int64ToAuxInt(c)
+			v1.AddArg(x)
+			v0.AddArg(v1)
 			b.resetWithControl(BlockPPC64NE, v0)
 			return true
 		}
@@ -18559,47 +17722,59 @@
 			b.resetWithControl(BlockPPC64NE, cmp)
 			return true
 		}
-		// match: (NE (CMPconst [0] (ANDconst [c] x)) yes no)
-		// result: (NE (ANDCCconst [c] x) yes no)
+		// match: (NE (CMPconst [0] (Select0 (ANDCCconst [c] x))) yes no)
+		// result: (NE (Select1 <types.TypeFlags> (ANDCCconst [c] x)) yes no)
 		for b.Controls[0].Op == OpPPC64CMPconst {
 			v_0 := b.Controls[0]
 			if auxIntToInt64(v_0.AuxInt) != 0 {
 				break
 			}
 			v_0_0 := v_0.Args[0]
-			if v_0_0.Op != OpPPC64ANDconst {
+			if v_0_0.Op != OpSelect0 {
 				break
 			}
-			c := auxIntToInt64(v_0_0.AuxInt)
-			x := v_0_0.Args[0]
-			v0 := b.NewValue0(v_0.Pos, OpPPC64ANDCCconst, types.TypeFlags)
-			v0.AuxInt = int64ToAuxInt(c)
-			v0.AddArg(x)
+			v_0_0_0 := v_0_0.Args[0]
+			if v_0_0_0.Op != OpPPC64ANDCCconst {
+				break
+			}
+			c := auxIntToInt64(v_0_0_0.AuxInt)
+			x := v_0_0_0.Args[0]
+			v0 := b.NewValue0(v_0.Pos, OpSelect1, types.TypeFlags)
+			v1 := b.NewValue0(v_0.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+			v1.AuxInt = int64ToAuxInt(c)
+			v1.AddArg(x)
+			v0.AddArg(v1)
 			b.resetWithControl(BlockPPC64NE, v0)
 			return true
 		}
-		// match: (NE (CMPWconst [0] (ANDconst [c] x)) yes no)
-		// result: (NE (ANDCCconst [c] x) yes no)
+		// match: (NE (CMPWconst [0] (Select0 (ANDCCconst [c] x))) yes no)
+		// result: (NE (Select1 <types.TypeFlags> (ANDCCconst [c] x)) yes no)
 		for b.Controls[0].Op == OpPPC64CMPWconst {
 			v_0 := b.Controls[0]
 			if auxIntToInt32(v_0.AuxInt) != 0 {
 				break
 			}
 			v_0_0 := v_0.Args[0]
-			if v_0_0.Op != OpPPC64ANDconst {
+			if v_0_0.Op != OpSelect0 {
 				break
 			}
-			c := auxIntToInt64(v_0_0.AuxInt)
-			x := v_0_0.Args[0]
-			v0 := b.NewValue0(v_0.Pos, OpPPC64ANDCCconst, types.TypeFlags)
-			v0.AuxInt = int64ToAuxInt(c)
-			v0.AddArg(x)
+			v_0_0_0 := v_0_0.Args[0]
+			if v_0_0_0.Op != OpPPC64ANDCCconst {
+				break
+			}
+			c := auxIntToInt64(v_0_0_0.AuxInt)
+			x := v_0_0_0.Args[0]
+			v0 := b.NewValue0(v_0.Pos, OpSelect1, types.TypeFlags)
+			v1 := b.NewValue0(v_0.Pos, OpPPC64ANDCCconst, types.NewTuple(typ.Int, types.TypeFlags))
+			v1.AuxInt = int64ToAuxInt(c)
+			v1.AddArg(x)
+			v0.AddArg(v1)
 			b.resetWithControl(BlockPPC64NE, v0)
 			return true
 		}
 		// match: (NE (CMPconst [0] z:(AND x y)) yes no)
 		// cond: z.Uses == 1
-		// result: (NE (ANDCC x y) yes no)
+		// result: (NE (Select1 <types.TypeFlags> (ANDCC x y)) yes no)
 		for b.Controls[0].Op == OpPPC64CMPconst {
 			v_0 := b.Controls[0]
 			if auxIntToInt64(v_0.AuxInt) != 0 {
@@ -18618,8 +17793,10 @@
 				if !(z.Uses == 1) {
 					continue
 				}
-				v0 := b.NewValue0(v_0.Pos, OpPPC64ANDCC, types.TypeFlags)
-				v0.AddArg2(x, y)
+				v0 := b.NewValue0(v_0.Pos, OpSelect1, types.TypeFlags)
+				v1 := b.NewValue0(v_0.Pos, OpPPC64ANDCC, types.NewTuple(typ.Int64, types.TypeFlags))
+				v1.AddArg2(x, y)
+				v0.AddArg(v1)
 				b.resetWithControl(BlockPPC64NE, v0)
 				return true
 			}
@@ -18627,7 +17804,7 @@
 		}
 		// match: (NE (CMPconst [0] z:(OR x y)) yes no)
 		// cond: z.Uses == 1
-		// result: (NE (ORCC x y) yes no)
+		// result: (NE (Select1 <types.TypeFlags> (ORCC x y)) yes no)
 		for b.Controls[0].Op == OpPPC64CMPconst {
 			v_0 := b.Controls[0]
 			if auxIntToInt64(v_0.AuxInt) != 0 {
@@ -18646,8 +17823,10 @@
 				if !(z.Uses == 1) {
 					continue
 				}
-				v0 := b.NewValue0(v_0.Pos, OpPPC64ORCC, types.TypeFlags)
-				v0.AddArg2(x, y)
+				v0 := b.NewValue0(v_0.Pos, OpSelect1, types.TypeFlags)
+				v1 := b.NewValue0(v_0.Pos, OpPPC64ORCC, types.NewTuple(typ.Int, types.TypeFlags))
+				v1.AddArg2(x, y)
+				v0.AddArg(v1)
 				b.resetWithControl(BlockPPC64NE, v0)
 				return true
 			}
@@ -18655,7 +17834,7 @@
 		}
 		// match: (NE (CMPconst [0] z:(XOR x y)) yes no)
 		// cond: z.Uses == 1
-		// result: (NE (XORCC x y) yes no)
+		// result: (NE (Select1 <types.TypeFlags> (XORCC x y)) yes no)
 		for b.Controls[0].Op == OpPPC64CMPconst {
 			v_0 := b.Controls[0]
 			if auxIntToInt64(v_0.AuxInt) != 0 {
@@ -18674,8 +17853,10 @@
 				if !(z.Uses == 1) {
 					continue
 				}
-				v0 := b.NewValue0(v_0.Pos, OpPPC64XORCC, types.TypeFlags)
-				v0.AddArg2(x, y)
+				v0 := b.NewValue0(v_0.Pos, OpSelect1, types.TypeFlags)
+				v1 := b.NewValue0(v_0.Pos, OpPPC64XORCC, types.NewTuple(typ.Int, types.TypeFlags))
+				v1.AddArg2(x, y)
+				v0.AddArg(v1)
 				b.resetWithControl(BlockPPC64NE, v0)
 				return true
 			}
diff --git a/src/cmd/compile/internal/ssa/rewritePPC64latelower.go b/src/cmd/compile/internal/ssa/rewritePPC64latelower.go
new file mode 100644
index 0000000..d687f59
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/rewritePPC64latelower.go
@@ -0,0 +1,49 @@
+// Code generated from _gen/PPC64latelower.rules; DO NOT EDIT.
+// generated with: cd _gen; go run .
+
+package ssa
+
+func rewriteValuePPC64latelower(v *Value) bool {
+	switch v.Op {
+	case OpPPC64ISEL:
+		return rewriteValuePPC64latelower_OpPPC64ISEL(v)
+	}
+	return false
+}
+func rewriteValuePPC64latelower_OpPPC64ISEL(v *Value) bool {
+	v_2 := v.Args[2]
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	// match: (ISEL [a] x (MOVDconst [0]) z)
+	// result: (ISELZ [a] x z)
+	for {
+		a := auxIntToInt32(v.AuxInt)
+		x := v_0
+		if v_1.Op != OpPPC64MOVDconst || auxIntToInt64(v_1.AuxInt) != 0 {
+			break
+		}
+		z := v_2
+		v.reset(OpPPC64ISELZ)
+		v.AuxInt = int32ToAuxInt(a)
+		v.AddArg2(x, z)
+		return true
+	}
+	// match: (ISEL [a] (MOVDconst [0]) y z)
+	// result: (ISELZ [a^0x4] y z)
+	for {
+		a := auxIntToInt32(v.AuxInt)
+		if v_0.Op != OpPPC64MOVDconst || auxIntToInt64(v_0.AuxInt) != 0 {
+			break
+		}
+		y := v_1
+		z := v_2
+		v.reset(OpPPC64ISELZ)
+		v.AuxInt = int32ToAuxInt(a ^ 0x4)
+		v.AddArg2(y, z)
+		return true
+	}
+	return false
+}
+func rewriteBlockPPC64latelower(b *Block) bool {
+	return false
+}
diff --git a/src/cmd/compile/internal/ssa/rewriteRISCV64.go b/src/cmd/compile/internal/ssa/rewriteRISCV64.go
index 2677e99..961230d 100644
--- a/src/cmd/compile/internal/ssa/rewriteRISCV64.go
+++ b/src/cmd/compile/internal/ssa/rewriteRISCV64.go
@@ -1,5 +1,5 @@
-// Code generated from gen/RISCV64.rules; DO NOT EDIT.
-// generated with: cd gen; go run *.go
+// Code generated from _gen/RISCV64.rules; DO NOT EDIT.
+// generated with: cd _gen; go run .
 
 package ssa
 
@@ -61,8 +61,7 @@
 	case OpAtomicAnd8:
 		return rewriteValueRISCV64_OpAtomicAnd8(v)
 	case OpAtomicCompareAndSwap32:
-		v.Op = OpRISCV64LoweredAtomicCas32
-		return true
+		return rewriteValueRISCV64_OpAtomicCompareAndSwap32(v)
 	case OpAtomicCompareAndSwap64:
 		v.Op = OpRISCV64LoweredAtomicCas64
 		return true
@@ -406,8 +405,7 @@
 	case OpNeq8:
 		return rewriteValueRISCV64_OpNeq8(v)
 	case OpNeqB:
-		v.Op = OpRISCV64XOR
-		return true
+		return rewriteValueRISCV64_OpNeqB(v)
 	case OpNeqPtr:
 		return rewriteValueRISCV64_OpNeqPtr(v)
 	case OpNilCheck:
@@ -505,14 +503,22 @@
 		return rewriteValueRISCV64_OpRISCV64OR(v)
 	case OpRISCV64ORI:
 		return rewriteValueRISCV64_OpRISCV64ORI(v)
+	case OpRISCV64SEQZ:
+		return rewriteValueRISCV64_OpRISCV64SEQZ(v)
 	case OpRISCV64SLL:
 		return rewriteValueRISCV64_OpRISCV64SLL(v)
 	case OpRISCV64SLLI:
 		return rewriteValueRISCV64_OpRISCV64SLLI(v)
+	case OpRISCV64SLT:
+		return rewriteValueRISCV64_OpRISCV64SLT(v)
 	case OpRISCV64SLTI:
 		return rewriteValueRISCV64_OpRISCV64SLTI(v)
 	case OpRISCV64SLTIU:
 		return rewriteValueRISCV64_OpRISCV64SLTIU(v)
+	case OpRISCV64SLTU:
+		return rewriteValueRISCV64_OpRISCV64SLTU(v)
+	case OpRISCV64SNEZ:
+		return rewriteValueRISCV64_OpRISCV64SNEZ(v)
 	case OpRISCV64SRA:
 		return rewriteValueRISCV64_OpRISCV64SRA(v)
 	case OpRISCV64SRAI:
@@ -605,6 +611,10 @@
 		return rewriteValueRISCV64_OpRsh8x64(v)
 	case OpRsh8x8:
 		return rewriteValueRISCV64_OpRsh8x8(v)
+	case OpSelect0:
+		return rewriteValueRISCV64_OpSelect0(v)
+	case OpSelect1:
+		return rewriteValueRISCV64_OpSelect1(v)
 	case OpSignExt16to32:
 		v.Op = OpRISCV64MOVHreg
 		return true
@@ -765,6 +775,27 @@
 		return true
 	}
 }
+func rewriteValueRISCV64_OpAtomicCompareAndSwap32(v *Value) bool {
+	v_3 := v.Args[3]
+	v_2 := v.Args[2]
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	b := v.Block
+	typ := &b.Func.Config.Types
+	// match: (AtomicCompareAndSwap32 ptr old new mem)
+	// result: (LoweredAtomicCas32 ptr (SignExt32to64 old) new mem)
+	for {
+		ptr := v_0
+		old := v_1
+		new := v_2
+		mem := v_3
+		v.reset(OpRISCV64LoweredAtomicCas32)
+		v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
+		v0.AddArg(old)
+		v.AddArg4(ptr, v0, new, mem)
+		return true
+	}
+}
 func rewriteValueRISCV64_OpAtomicOr8(v *Value) bool {
 	v_2 := v.Args[2]
 	v_1 := v.Args[1]
@@ -1109,12 +1140,12 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (EqB x y)
-	// result: (SEQZ (XOR <typ.Bool> x y))
+	// result: (SEQZ (SUB <typ.Bool> x y))
 	for {
 		x := v_0
 		y := v_1
 		v.reset(OpRISCV64SEQZ)
-		v0 := b.NewValue0(v.Pos, OpRISCV64XOR, typ.Bool)
+		v0 := b.NewValue0(v.Pos, OpRISCV64SUB, typ.Bool)
 		v0.AddArg2(x, y)
 		v.AddArg(v0)
 		return true
@@ -1595,11 +1626,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Lsh16x16 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (AND (SLL <t> x y) (Neg16 <t> (SLTIU <t> [64] (ZeroExt16to64 y))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64AND)
 		v0 := b.NewValue0(v.Pos, OpRISCV64SLL, t)
 		v0.AddArg2(x, y)
@@ -1613,6 +1648,20 @@
 		v.AddArg2(v0, v1)
 		return true
 	}
+	// match: (Lsh16x16 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SLL x y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SLL)
+		v.AddArg2(x, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpLsh16x32(v *Value) bool {
 	v_1 := v.Args[1]
@@ -1620,11 +1669,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Lsh16x32 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (AND (SLL <t> x y) (Neg16 <t> (SLTIU <t> [64] (ZeroExt32to64 y))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64AND)
 		v0 := b.NewValue0(v.Pos, OpRISCV64SLL, t)
 		v0.AddArg2(x, y)
@@ -1638,17 +1691,35 @@
 		v.AddArg2(v0, v1)
 		return true
 	}
+	// match: (Lsh16x32 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SLL x y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SLL)
+		v.AddArg2(x, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpLsh16x64(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
 	// match: (Lsh16x64 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (AND (SLL <t> x y) (Neg16 <t> (SLTIU <t> [64] y)))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64AND)
 		v0 := b.NewValue0(v.Pos, OpRISCV64SLL, t)
 		v0.AddArg2(x, y)
@@ -1660,6 +1731,20 @@
 		v.AddArg2(v0, v1)
 		return true
 	}
+	// match: (Lsh16x64 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SLL x y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SLL)
+		v.AddArg2(x, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpLsh16x8(v *Value) bool {
 	v_1 := v.Args[1]
@@ -1667,11 +1752,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Lsh16x8 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (AND (SLL <t> x y) (Neg16 <t> (SLTIU <t> [64] (ZeroExt8to64 y))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64AND)
 		v0 := b.NewValue0(v.Pos, OpRISCV64SLL, t)
 		v0.AddArg2(x, y)
@@ -1685,6 +1774,20 @@
 		v.AddArg2(v0, v1)
 		return true
 	}
+	// match: (Lsh16x8 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SLL x y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SLL)
+		v.AddArg2(x, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpLsh32x16(v *Value) bool {
 	v_1 := v.Args[1]
@@ -1692,11 +1795,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Lsh32x16 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (AND (SLL <t> x y) (Neg32 <t> (SLTIU <t> [64] (ZeroExt16to64 y))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64AND)
 		v0 := b.NewValue0(v.Pos, OpRISCV64SLL, t)
 		v0.AddArg2(x, y)
@@ -1710,6 +1817,20 @@
 		v.AddArg2(v0, v1)
 		return true
 	}
+	// match: (Lsh32x16 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SLL x y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SLL)
+		v.AddArg2(x, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpLsh32x32(v *Value) bool {
 	v_1 := v.Args[1]
@@ -1717,11 +1838,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Lsh32x32 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (AND (SLL <t> x y) (Neg32 <t> (SLTIU <t> [64] (ZeroExt32to64 y))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64AND)
 		v0 := b.NewValue0(v.Pos, OpRISCV64SLL, t)
 		v0.AddArg2(x, y)
@@ -1735,17 +1860,35 @@
 		v.AddArg2(v0, v1)
 		return true
 	}
+	// match: (Lsh32x32 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SLL x y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SLL)
+		v.AddArg2(x, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpLsh32x64(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
 	// match: (Lsh32x64 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (AND (SLL <t> x y) (Neg32 <t> (SLTIU <t> [64] y)))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64AND)
 		v0 := b.NewValue0(v.Pos, OpRISCV64SLL, t)
 		v0.AddArg2(x, y)
@@ -1757,6 +1900,20 @@
 		v.AddArg2(v0, v1)
 		return true
 	}
+	// match: (Lsh32x64 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SLL x y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SLL)
+		v.AddArg2(x, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpLsh32x8(v *Value) bool {
 	v_1 := v.Args[1]
@@ -1764,11 +1921,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Lsh32x8 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (AND (SLL <t> x y) (Neg32 <t> (SLTIU <t> [64] (ZeroExt8to64 y))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64AND)
 		v0 := b.NewValue0(v.Pos, OpRISCV64SLL, t)
 		v0.AddArg2(x, y)
@@ -1782,6 +1943,20 @@
 		v.AddArg2(v0, v1)
 		return true
 	}
+	// match: (Lsh32x8 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SLL x y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SLL)
+		v.AddArg2(x, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpLsh64x16(v *Value) bool {
 	v_1 := v.Args[1]
@@ -1789,11 +1964,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Lsh64x16 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (AND (SLL <t> x y) (Neg64 <t> (SLTIU <t> [64] (ZeroExt16to64 y))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64AND)
 		v0 := b.NewValue0(v.Pos, OpRISCV64SLL, t)
 		v0.AddArg2(x, y)
@@ -1807,6 +1986,20 @@
 		v.AddArg2(v0, v1)
 		return true
 	}
+	// match: (Lsh64x16 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SLL x y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SLL)
+		v.AddArg2(x, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpLsh64x32(v *Value) bool {
 	v_1 := v.Args[1]
@@ -1814,11 +2007,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Lsh64x32 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (AND (SLL <t> x y) (Neg64 <t> (SLTIU <t> [64] (ZeroExt32to64 y))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64AND)
 		v0 := b.NewValue0(v.Pos, OpRISCV64SLL, t)
 		v0.AddArg2(x, y)
@@ -1832,17 +2029,35 @@
 		v.AddArg2(v0, v1)
 		return true
 	}
+	// match: (Lsh64x32 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SLL x y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SLL)
+		v.AddArg2(x, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpLsh64x64(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
 	// match: (Lsh64x64 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (AND (SLL <t> x y) (Neg64 <t> (SLTIU <t> [64] y)))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64AND)
 		v0 := b.NewValue0(v.Pos, OpRISCV64SLL, t)
 		v0.AddArg2(x, y)
@@ -1854,6 +2069,20 @@
 		v.AddArg2(v0, v1)
 		return true
 	}
+	// match: (Lsh64x64 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SLL x y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SLL)
+		v.AddArg2(x, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpLsh64x8(v *Value) bool {
 	v_1 := v.Args[1]
@@ -1861,11 +2090,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Lsh64x8 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (AND (SLL <t> x y) (Neg64 <t> (SLTIU <t> [64] (ZeroExt8to64 y))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64AND)
 		v0 := b.NewValue0(v.Pos, OpRISCV64SLL, t)
 		v0.AddArg2(x, y)
@@ -1879,6 +2112,20 @@
 		v.AddArg2(v0, v1)
 		return true
 	}
+	// match: (Lsh64x8 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SLL x y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SLL)
+		v.AddArg2(x, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpLsh8x16(v *Value) bool {
 	v_1 := v.Args[1]
@@ -1886,11 +2133,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Lsh8x16 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (AND (SLL <t> x y) (Neg8 <t> (SLTIU <t> [64] (ZeroExt16to64 y))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64AND)
 		v0 := b.NewValue0(v.Pos, OpRISCV64SLL, t)
 		v0.AddArg2(x, y)
@@ -1904,6 +2155,20 @@
 		v.AddArg2(v0, v1)
 		return true
 	}
+	// match: (Lsh8x16 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SLL x y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SLL)
+		v.AddArg2(x, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpLsh8x32(v *Value) bool {
 	v_1 := v.Args[1]
@@ -1911,11 +2176,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Lsh8x32 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (AND (SLL <t> x y) (Neg8 <t> (SLTIU <t> [64] (ZeroExt32to64 y))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64AND)
 		v0 := b.NewValue0(v.Pos, OpRISCV64SLL, t)
 		v0.AddArg2(x, y)
@@ -1929,17 +2198,35 @@
 		v.AddArg2(v0, v1)
 		return true
 	}
+	// match: (Lsh8x32 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SLL x y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SLL)
+		v.AddArg2(x, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpLsh8x64(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
 	// match: (Lsh8x64 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (AND (SLL <t> x y) (Neg8 <t> (SLTIU <t> [64] y)))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64AND)
 		v0 := b.NewValue0(v.Pos, OpRISCV64SLL, t)
 		v0.AddArg2(x, y)
@@ -1951,6 +2238,20 @@
 		v.AddArg2(v0, v1)
 		return true
 	}
+	// match: (Lsh8x64 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SLL x y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SLL)
+		v.AddArg2(x, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpLsh8x8(v *Value) bool {
 	v_1 := v.Args[1]
@@ -1958,11 +2259,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Lsh8x8 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (AND (SLL <t> x y) (Neg8 <t> (SLTIU <t> [64] (ZeroExt8to64 y))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64AND)
 		v0 := b.NewValue0(v.Pos, OpRISCV64SLL, t)
 		v0.AddArg2(x, y)
@@ -1976,6 +2281,20 @@
 		v.AddArg2(v0, v1)
 		return true
 	}
+	// match: (Lsh8x8 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SLL x y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SLL)
+		v.AddArg2(x, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpMod16(v *Value) bool {
 	v_1 := v.Args[1]
@@ -2670,6 +2989,23 @@
 		return true
 	}
 }
+func rewriteValueRISCV64_OpNeqB(v *Value) bool {
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	b := v.Block
+	typ := &b.Func.Config.Types
+	// match: (NeqB x y)
+	// result: (SNEZ (SUB <typ.Bool> x y))
+	for {
+		x := v_0
+		y := v_1
+		v.reset(OpRISCV64SNEZ)
+		v0 := b.NewValue0(v.Pos, OpRISCV64SUB, typ.Bool)
+		v0.AddArg2(x, y)
+		v.AddArg(v0)
+		return true
+	}
+}
 func rewriteValueRISCV64_OpNeqPtr(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
@@ -2858,6 +3194,24 @@
 		v.AuxInt = int64ToAuxInt(x + y)
 		return true
 	}
+	// match: (ADDI [x] (ADDI [y] z))
+	// cond: is32Bit(x + y)
+	// result: (ADDI [x + y] z)
+	for {
+		x := auxIntToInt64(v.AuxInt)
+		if v_0.Op != OpRISCV64ADDI {
+			break
+		}
+		y := auxIntToInt64(v_0.AuxInt)
+		z := v_0.Args[0]
+		if !(is32Bit(x + y)) {
+			break
+		}
+		v.reset(OpRISCV64ADDI)
+		v.AuxInt = int64ToAuxInt(x + y)
+		v.AddArg(z)
+		return true
+	}
 	return false
 }
 func rewriteValueRISCV64_OpRISCV64AND(v *Value) bool {
@@ -2919,6 +3273,20 @@
 		v.AuxInt = int64ToAuxInt(x & y)
 		return true
 	}
+	// match: (ANDI [x] (ANDI [y] z))
+	// result: (ANDI [x & y] z)
+	for {
+		x := auxIntToInt64(v.AuxInt)
+		if v_0.Op != OpRISCV64ANDI {
+			break
+		}
+		y := auxIntToInt64(v_0.AuxInt)
+		z := v_0.Args[0]
+		v.reset(OpRISCV64ANDI)
+		v.AuxInt = int64ToAuxInt(x & y)
+		v.AddArg(z)
+		return true
+	}
 	return false
 }
 func rewriteValueRISCV64_OpRISCV64FMADDD(v *Value) bool {
@@ -3152,6 +3520,86 @@
 func rewriteValueRISCV64_OpRISCV64MOVBUreg(v *Value) bool {
 	v_0 := v.Args[0]
 	b := v.Block
+	// match: (MOVBUreg x:(FLES _ _))
+	// result: x
+	for {
+		x := v_0
+		if x.Op != OpRISCV64FLES {
+			break
+		}
+		v.copyOf(x)
+		return true
+	}
+	// match: (MOVBUreg x:(FLTS _ _))
+	// result: x
+	for {
+		x := v_0
+		if x.Op != OpRISCV64FLTS {
+			break
+		}
+		v.copyOf(x)
+		return true
+	}
+	// match: (MOVBUreg x:(FEQS _ _))
+	// result: x
+	for {
+		x := v_0
+		if x.Op != OpRISCV64FEQS {
+			break
+		}
+		v.copyOf(x)
+		return true
+	}
+	// match: (MOVBUreg x:(FNES _ _))
+	// result: x
+	for {
+		x := v_0
+		if x.Op != OpRISCV64FNES {
+			break
+		}
+		v.copyOf(x)
+		return true
+	}
+	// match: (MOVBUreg x:(FLED _ _))
+	// result: x
+	for {
+		x := v_0
+		if x.Op != OpRISCV64FLED {
+			break
+		}
+		v.copyOf(x)
+		return true
+	}
+	// match: (MOVBUreg x:(FLTD _ _))
+	// result: x
+	for {
+		x := v_0
+		if x.Op != OpRISCV64FLTD {
+			break
+		}
+		v.copyOf(x)
+		return true
+	}
+	// match: (MOVBUreg x:(FEQD _ _))
+	// result: x
+	for {
+		x := v_0
+		if x.Op != OpRISCV64FEQD {
+			break
+		}
+		v.copyOf(x)
+		return true
+	}
+	// match: (MOVBUreg x:(FNED _ _))
+	// result: x
+	for {
+		x := v_0
+		if x.Op != OpRISCV64FNED {
+			break
+		}
+		v.copyOf(x)
+		return true
+	}
 	// match: (MOVBUreg x:(SEQZ _))
 	// result: x
 	for {
@@ -3192,6 +3640,38 @@
 		v.copyOf(x)
 		return true
 	}
+	// match: (MOVBUreg x:(ANDI [c] y))
+	// cond: c >= 0 && int64(uint8(c)) == c
+	// result: x
+	for {
+		x := v_0
+		if x.Op != OpRISCV64ANDI {
+			break
+		}
+		c := auxIntToInt64(x.AuxInt)
+		if !(c >= 0 && int64(uint8(c)) == c) {
+			break
+		}
+		v.copyOf(x)
+		return true
+	}
+	// match: (MOVBUreg (ANDI [c] x))
+	// cond: c < 0
+	// result: (ANDI [int64(uint8(c))] x)
+	for {
+		if v_0.Op != OpRISCV64ANDI {
+			break
+		}
+		c := auxIntToInt64(v_0.AuxInt)
+		x := v_0.Args[0]
+		if !(c < 0) {
+			break
+		}
+		v.reset(OpRISCV64ANDI)
+		v.AuxInt = int64ToAuxInt(int64(uint8(c)))
+		v.AddArg(x)
+		return true
+	}
 	// match: (MOVBUreg (MOVDconst [c]))
 	// result: (MOVDconst [int64(uint8(c))])
 	for {
@@ -3214,6 +3694,51 @@
 		v.AddArg(x)
 		return true
 	}
+	// match: (MOVBUreg x:(Select0 (LoweredAtomicLoad8 _ _)))
+	// result: (MOVDreg x)
+	for {
+		x := v_0
+		if x.Op != OpSelect0 {
+			break
+		}
+		x_0 := x.Args[0]
+		if x_0.Op != OpRISCV64LoweredAtomicLoad8 {
+			break
+		}
+		v.reset(OpRISCV64MOVDreg)
+		v.AddArg(x)
+		return true
+	}
+	// match: (MOVBUreg x:(Select0 (LoweredAtomicCas32 _ _ _ _)))
+	// result: (MOVDreg x)
+	for {
+		x := v_0
+		if x.Op != OpSelect0 {
+			break
+		}
+		x_0 := x.Args[0]
+		if x_0.Op != OpRISCV64LoweredAtomicCas32 {
+			break
+		}
+		v.reset(OpRISCV64MOVDreg)
+		v.AddArg(x)
+		return true
+	}
+	// match: (MOVBUreg x:(Select0 (LoweredAtomicCas64 _ _ _ _)))
+	// result: (MOVDreg x)
+	for {
+		x := v_0
+		if x.Op != OpSelect0 {
+			break
+		}
+		x_0 := x.Args[0]
+		if x_0.Op != OpRISCV64LoweredAtomicCas64 {
+			break
+		}
+		v.reset(OpRISCV64MOVDreg)
+		v.AddArg(x)
+		return true
+	}
 	// match: (MOVBUreg x:(MOVBUreg _))
 	// result: (MOVDreg x)
 	for {
@@ -3302,6 +3827,21 @@
 func rewriteValueRISCV64_OpRISCV64MOVBreg(v *Value) bool {
 	v_0 := v.Args[0]
 	b := v.Block
+	// match: (MOVBreg x:(ANDI [c] y))
+	// cond: c >= 0 && int64(int8(c)) == c
+	// result: x
+	for {
+		x := v_0
+		if x.Op != OpRISCV64ANDI {
+			break
+		}
+		c := auxIntToInt64(x.AuxInt)
+		if !(c >= 0 && int64(int8(c)) == c) {
+			break
+		}
+		v.copyOf(x)
+		return true
+	}
 	// match: (MOVBreg (MOVDconst [c]))
 	// result: (MOVDconst [int64(int8(c))])
 	for {
@@ -3823,6 +4363,38 @@
 func rewriteValueRISCV64_OpRISCV64MOVHUreg(v *Value) bool {
 	v_0 := v.Args[0]
 	b := v.Block
+	// match: (MOVHUreg x:(ANDI [c] y))
+	// cond: c >= 0 && int64(uint16(c)) == c
+	// result: x
+	for {
+		x := v_0
+		if x.Op != OpRISCV64ANDI {
+			break
+		}
+		c := auxIntToInt64(x.AuxInt)
+		if !(c >= 0 && int64(uint16(c)) == c) {
+			break
+		}
+		v.copyOf(x)
+		return true
+	}
+	// match: (MOVHUreg (ANDI [c] x))
+	// cond: c < 0
+	// result: (ANDI [int64(uint16(c))] x)
+	for {
+		if v_0.Op != OpRISCV64ANDI {
+			break
+		}
+		c := auxIntToInt64(v_0.AuxInt)
+		x := v_0.Args[0]
+		if !(c < 0) {
+			break
+		}
+		v.reset(OpRISCV64ANDI)
+		v.AuxInt = int64ToAuxInt(int64(uint16(c)))
+		v.AddArg(x)
+		return true
+	}
 	// match: (MOVHUreg (MOVDconst [c]))
 	// result: (MOVDconst [int64(uint16(c))])
 	for {
@@ -3955,6 +4527,21 @@
 func rewriteValueRISCV64_OpRISCV64MOVHreg(v *Value) bool {
 	v_0 := v.Args[0]
 	b := v.Block
+	// match: (MOVHreg x:(ANDI [c] y))
+	// cond: c >= 0 && int64(int16(c)) == c
+	// result: x
+	for {
+		x := v_0
+		if x.Op != OpRISCV64ANDI {
+			break
+		}
+		c := auxIntToInt64(x.AuxInt)
+		if !(c >= 0 && int64(int16(c)) == c) {
+			break
+		}
+		v.copyOf(x)
+		return true
+	}
 	// match: (MOVHreg (MOVDconst [c]))
 	// result: (MOVDconst [int64(int16(c))])
 	for {
@@ -4292,6 +4879,40 @@
 func rewriteValueRISCV64_OpRISCV64MOVWUreg(v *Value) bool {
 	v_0 := v.Args[0]
 	b := v.Block
+	typ := &b.Func.Config.Types
+	// match: (MOVWUreg x:(ANDI [c] y))
+	// cond: c >= 0 && int64(uint32(c)) == c
+	// result: x
+	for {
+		x := v_0
+		if x.Op != OpRISCV64ANDI {
+			break
+		}
+		c := auxIntToInt64(x.AuxInt)
+		if !(c >= 0 && int64(uint32(c)) == c) {
+			break
+		}
+		v.copyOf(x)
+		return true
+	}
+	// match: (MOVWUreg (ANDI [c] x))
+	// cond: c < 0
+	// result: (AND (MOVDconst [int64(uint32(c))]) x)
+	for {
+		if v_0.Op != OpRISCV64ANDI {
+			break
+		}
+		c := auxIntToInt64(v_0.AuxInt)
+		x := v_0.Args[0]
+		if !(c < 0) {
+			break
+		}
+		v.reset(OpRISCV64AND)
+		v0 := b.NewValue0(v.Pos, OpRISCV64MOVDconst, typ.UInt64)
+		v0.AuxInt = int64ToAuxInt(int64(uint32(c)))
+		v.AddArg2(v0, x)
+		return true
+	}
 	// match: (MOVWUreg (MOVDconst [c]))
 	// result: (MOVDconst [int64(uint32(c))])
 	for {
@@ -4446,6 +5067,21 @@
 func rewriteValueRISCV64_OpRISCV64MOVWreg(v *Value) bool {
 	v_0 := v.Args[0]
 	b := v.Block
+	// match: (MOVWreg x:(ANDI [c] y))
+	// cond: c >= 0 && int64(int32(c)) == c
+	// result: x
+	for {
+		x := v_0
+		if x.Op != OpRISCV64ANDI {
+			break
+		}
+		c := auxIntToInt64(x.AuxInt)
+		if !(c >= 0 && int64(int32(c)) == c) {
+			break
+		}
+		v.copyOf(x)
+		return true
+	}
 	// match: (MOVWreg (MOVDconst [c]))
 	// result: (MOVDconst [int64(int32(c))])
 	for {
@@ -4512,6 +5148,94 @@
 		v.AddArg(x)
 		return true
 	}
+	// match: (MOVWreg x:(ADDIW _))
+	// result: (MOVDreg x)
+	for {
+		x := v_0
+		if x.Op != OpRISCV64ADDIW {
+			break
+		}
+		v.reset(OpRISCV64MOVDreg)
+		v.AddArg(x)
+		return true
+	}
+	// match: (MOVWreg x:(SUBW _ _))
+	// result: (MOVDreg x)
+	for {
+		x := v_0
+		if x.Op != OpRISCV64SUBW {
+			break
+		}
+		v.reset(OpRISCV64MOVDreg)
+		v.AddArg(x)
+		return true
+	}
+	// match: (MOVWreg x:(NEGW _))
+	// result: (MOVDreg x)
+	for {
+		x := v_0
+		if x.Op != OpRISCV64NEGW {
+			break
+		}
+		v.reset(OpRISCV64MOVDreg)
+		v.AddArg(x)
+		return true
+	}
+	// match: (MOVWreg x:(MULW _ _))
+	// result: (MOVDreg x)
+	for {
+		x := v_0
+		if x.Op != OpRISCV64MULW {
+			break
+		}
+		v.reset(OpRISCV64MOVDreg)
+		v.AddArg(x)
+		return true
+	}
+	// match: (MOVWreg x:(DIVW _ _))
+	// result: (MOVDreg x)
+	for {
+		x := v_0
+		if x.Op != OpRISCV64DIVW {
+			break
+		}
+		v.reset(OpRISCV64MOVDreg)
+		v.AddArg(x)
+		return true
+	}
+	// match: (MOVWreg x:(DIVUW _ _))
+	// result: (MOVDreg x)
+	for {
+		x := v_0
+		if x.Op != OpRISCV64DIVUW {
+			break
+		}
+		v.reset(OpRISCV64MOVDreg)
+		v.AddArg(x)
+		return true
+	}
+	// match: (MOVWreg x:(REMW _ _))
+	// result: (MOVDreg x)
+	for {
+		x := v_0
+		if x.Op != OpRISCV64REMW {
+			break
+		}
+		v.reset(OpRISCV64MOVDreg)
+		v.AddArg(x)
+		return true
+	}
+	// match: (MOVWreg x:(REMUW _ _))
+	// result: (MOVDreg x)
+	for {
+		x := v_0
+		if x.Op != OpRISCV64REMUW {
+			break
+		}
+		v.reset(OpRISCV64MOVDreg)
+		v.AddArg(x)
+		return true
+	}
 	// match: (MOVWreg x:(MOVBreg _))
 	// result: (MOVDreg x)
 	for {
@@ -4733,6 +5457,55 @@
 }
 func rewriteValueRISCV64_OpRISCV64NEG(v *Value) bool {
 	v_0 := v.Args[0]
+	b := v.Block
+	// match: (NEG (SUB x y))
+	// result: (SUB y x)
+	for {
+		if v_0.Op != OpRISCV64SUB {
+			break
+		}
+		y := v_0.Args[1]
+		x := v_0.Args[0]
+		v.reset(OpRISCV64SUB)
+		v.AddArg2(y, x)
+		return true
+	}
+	// match: (NEG <t> s:(ADDI [val] (SUB x y)))
+	// cond: s.Uses == 1 && is32Bit(-val)
+	// result: (ADDI [-val] (SUB <t> y x))
+	for {
+		t := v.Type
+		s := v_0
+		if s.Op != OpRISCV64ADDI {
+			break
+		}
+		val := auxIntToInt64(s.AuxInt)
+		s_0 := s.Args[0]
+		if s_0.Op != OpRISCV64SUB {
+			break
+		}
+		y := s_0.Args[1]
+		x := s_0.Args[0]
+		if !(s.Uses == 1 && is32Bit(-val)) {
+			break
+		}
+		v.reset(OpRISCV64ADDI)
+		v.AuxInt = int64ToAuxInt(-val)
+		v0 := b.NewValue0(v.Pos, OpRISCV64SUB, t)
+		v0.AddArg2(y, x)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (NEG (NEG x))
+	// result: x
+	for {
+		if v_0.Op != OpRISCV64NEG {
+			break
+		}
+		x := v_0.Args[0]
+		v.copyOf(x)
+		return true
+	}
 	// match: (NEG (MOVDconst [x]))
 	// result: (MOVDconst [-x])
 	for {
@@ -4820,6 +5593,57 @@
 		v.AuxInt = int64ToAuxInt(x | y)
 		return true
 	}
+	// match: (ORI [x] (ORI [y] z))
+	// result: (ORI [x | y] z)
+	for {
+		x := auxIntToInt64(v.AuxInt)
+		if v_0.Op != OpRISCV64ORI {
+			break
+		}
+		y := auxIntToInt64(v_0.AuxInt)
+		z := v_0.Args[0]
+		v.reset(OpRISCV64ORI)
+		v.AuxInt = int64ToAuxInt(x | y)
+		v.AddArg(z)
+		return true
+	}
+	return false
+}
+func rewriteValueRISCV64_OpRISCV64SEQZ(v *Value) bool {
+	v_0 := v.Args[0]
+	// match: (SEQZ (NEG x))
+	// result: (SEQZ x)
+	for {
+		if v_0.Op != OpRISCV64NEG {
+			break
+		}
+		x := v_0.Args[0]
+		v.reset(OpRISCV64SEQZ)
+		v.AddArg(x)
+		return true
+	}
+	// match: (SEQZ (SEQZ x))
+	// result: (SNEZ x)
+	for {
+		if v_0.Op != OpRISCV64SEQZ {
+			break
+		}
+		x := v_0.Args[0]
+		v.reset(OpRISCV64SNEZ)
+		v.AddArg(x)
+		return true
+	}
+	// match: (SEQZ (SNEZ x))
+	// result: (SEQZ x)
+	for {
+		if v_0.Op != OpRISCV64SNEZ {
+			break
+		}
+		x := v_0.Args[0]
+		v.reset(OpRISCV64SEQZ)
+		v.AddArg(x)
+		return true
+	}
 	return false
 }
 func rewriteValueRISCV64_OpRISCV64SLL(v *Value) bool {
@@ -4860,6 +5684,39 @@
 	}
 	return false
 }
+func rewriteValueRISCV64_OpRISCV64SLT(v *Value) bool {
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	// match: (SLT x (MOVDconst [val]))
+	// cond: val >= -2048 && val <= 2047
+	// result: (SLTI [val] x)
+	for {
+		x := v_0
+		if v_1.Op != OpRISCV64MOVDconst {
+			break
+		}
+		val := auxIntToInt64(v_1.AuxInt)
+		if !(val >= -2048 && val <= 2047) {
+			break
+		}
+		v.reset(OpRISCV64SLTI)
+		v.AuxInt = int64ToAuxInt(val)
+		v.AddArg(x)
+		return true
+	}
+	// match: (SLT x x)
+	// result: (MOVDconst [0])
+	for {
+		x := v_0
+		if x != v_1 {
+			break
+		}
+		v.reset(OpRISCV64MOVDconst)
+		v.AuxInt = int64ToAuxInt(0)
+		return true
+	}
+	return false
+}
 func rewriteValueRISCV64_OpRISCV64SLTI(v *Value) bool {
 	v_0 := v.Args[0]
 	// match: (SLTI [x] (MOVDconst [y]))
@@ -4874,6 +5731,38 @@
 		v.AuxInt = int64ToAuxInt(b2i(int64(y) < int64(x)))
 		return true
 	}
+	// match: (SLTI [x] (ANDI [y] _))
+	// cond: y >= 0 && int64(y) < int64(x)
+	// result: (MOVDconst [1])
+	for {
+		x := auxIntToInt64(v.AuxInt)
+		if v_0.Op != OpRISCV64ANDI {
+			break
+		}
+		y := auxIntToInt64(v_0.AuxInt)
+		if !(y >= 0 && int64(y) < int64(x)) {
+			break
+		}
+		v.reset(OpRISCV64MOVDconst)
+		v.AuxInt = int64ToAuxInt(1)
+		return true
+	}
+	// match: (SLTI [x] (ORI [y] _))
+	// cond: y >= 0 && int64(y) >= int64(x)
+	// result: (MOVDconst [0])
+	for {
+		x := auxIntToInt64(v.AuxInt)
+		if v_0.Op != OpRISCV64ORI {
+			break
+		}
+		y := auxIntToInt64(v_0.AuxInt)
+		if !(y >= 0 && int64(y) >= int64(x)) {
+			break
+		}
+		v.reset(OpRISCV64MOVDconst)
+		v.AuxInt = int64ToAuxInt(0)
+		return true
+	}
 	return false
 }
 func rewriteValueRISCV64_OpRISCV64SLTIU(v *Value) bool {
@@ -4890,6 +5779,108 @@
 		v.AuxInt = int64ToAuxInt(b2i(uint64(y) < uint64(x)))
 		return true
 	}
+	// match: (SLTIU [x] (ANDI [y] _))
+	// cond: y >= 0 && uint64(y) < uint64(x)
+	// result: (MOVDconst [1])
+	for {
+		x := auxIntToInt64(v.AuxInt)
+		if v_0.Op != OpRISCV64ANDI {
+			break
+		}
+		y := auxIntToInt64(v_0.AuxInt)
+		if !(y >= 0 && uint64(y) < uint64(x)) {
+			break
+		}
+		v.reset(OpRISCV64MOVDconst)
+		v.AuxInt = int64ToAuxInt(1)
+		return true
+	}
+	// match: (SLTIU [x] (ORI [y] _))
+	// cond: y >= 0 && uint64(y) >= uint64(x)
+	// result: (MOVDconst [0])
+	for {
+		x := auxIntToInt64(v.AuxInt)
+		if v_0.Op != OpRISCV64ORI {
+			break
+		}
+		y := auxIntToInt64(v_0.AuxInt)
+		if !(y >= 0 && uint64(y) >= uint64(x)) {
+			break
+		}
+		v.reset(OpRISCV64MOVDconst)
+		v.AuxInt = int64ToAuxInt(0)
+		return true
+	}
+	return false
+}
+func rewriteValueRISCV64_OpRISCV64SLTU(v *Value) bool {
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	// match: (SLTU x (MOVDconst [val]))
+	// cond: val >= -2048 && val <= 2047
+	// result: (SLTIU [val] x)
+	for {
+		x := v_0
+		if v_1.Op != OpRISCV64MOVDconst {
+			break
+		}
+		val := auxIntToInt64(v_1.AuxInt)
+		if !(val >= -2048 && val <= 2047) {
+			break
+		}
+		v.reset(OpRISCV64SLTIU)
+		v.AuxInt = int64ToAuxInt(val)
+		v.AddArg(x)
+		return true
+	}
+	// match: (SLTU x x)
+	// result: (MOVDconst [0])
+	for {
+		x := v_0
+		if x != v_1 {
+			break
+		}
+		v.reset(OpRISCV64MOVDconst)
+		v.AuxInt = int64ToAuxInt(0)
+		return true
+	}
+	return false
+}
+func rewriteValueRISCV64_OpRISCV64SNEZ(v *Value) bool {
+	v_0 := v.Args[0]
+	// match: (SNEZ (NEG x))
+	// result: (SNEZ x)
+	for {
+		if v_0.Op != OpRISCV64NEG {
+			break
+		}
+		x := v_0.Args[0]
+		v.reset(OpRISCV64SNEZ)
+		v.AddArg(x)
+		return true
+	}
+	// match: (SNEZ (SEQZ x))
+	// result: (SEQZ x)
+	for {
+		if v_0.Op != OpRISCV64SEQZ {
+			break
+		}
+		x := v_0.Args[0]
+		v.reset(OpRISCV64SEQZ)
+		v.AddArg(x)
+		return true
+	}
+	// match: (SNEZ (SNEZ x))
+	// result: (SNEZ x)
+	for {
+		if v_0.Op != OpRISCV64SNEZ {
+			break
+		}
+		x := v_0.Args[0]
+		v.reset(OpRISCV64SNEZ)
+		v.AddArg(x)
+		return true
+	}
 	return false
 }
 func rewriteValueRISCV64_OpRISCV64SRA(v *Value) bool {
@@ -4963,6 +5954,7 @@
 func rewriteValueRISCV64_OpRISCV64SUB(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
+	b := v.Block
 	// match: (SUB x (MOVDconst [val]))
 	// cond: is32Bit(-val)
 	// result: (ADDI [-val] x)
@@ -4980,6 +5972,26 @@
 		v.AddArg(x)
 		return true
 	}
+	// match: (SUB <t> (MOVDconst [val]) y)
+	// cond: is32Bit(-val)
+	// result: (NEG (ADDI <t> [-val] y))
+	for {
+		t := v.Type
+		if v_0.Op != OpRISCV64MOVDconst {
+			break
+		}
+		val := auxIntToInt64(v_0.AuxInt)
+		y := v_1
+		if !(is32Bit(-val)) {
+			break
+		}
+		v.reset(OpRISCV64NEG)
+		v0 := b.NewValue0(v.Pos, OpRISCV64ADDI, t)
+		v0.AuxInt = int64ToAuxInt(-val)
+		v0.AddArg(y)
+		v.AddArg(v0)
+		return true
+	}
 	// match: (SUB x (MOVDconst [0]))
 	// result: x
 	for {
@@ -5174,11 +6186,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh16Ux16 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (AND (SRL <t> (ZeroExt16to64 x) y) (Neg16 <t> (SLTIU <t> [64] (ZeroExt16to64 y))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64AND)
 		v0 := b.NewValue0(v.Pos, OpRISCV64SRL, t)
 		v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
@@ -5194,6 +6210,22 @@
 		v.AddArg2(v0, v2)
 		return true
 	}
+	// match: (Rsh16Ux16 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRL (ZeroExt16to64 x) y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SRL)
+		v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpRsh16Ux32(v *Value) bool {
 	v_1 := v.Args[1]
@@ -5201,11 +6233,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh16Ux32 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (AND (SRL <t> (ZeroExt16to64 x) y) (Neg16 <t> (SLTIU <t> [64] (ZeroExt32to64 y))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64AND)
 		v0 := b.NewValue0(v.Pos, OpRISCV64SRL, t)
 		v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
@@ -5221,6 +6257,22 @@
 		v.AddArg2(v0, v2)
 		return true
 	}
+	// match: (Rsh16Ux32 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRL (ZeroExt16to64 x) y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SRL)
+		v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpRsh16Ux64(v *Value) bool {
 	v_1 := v.Args[1]
@@ -5228,11 +6280,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh16Ux64 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (AND (SRL <t> (ZeroExt16to64 x) y) (Neg16 <t> (SLTIU <t> [64] y)))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64AND)
 		v0 := b.NewValue0(v.Pos, OpRISCV64SRL, t)
 		v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
@@ -5246,6 +6302,22 @@
 		v.AddArg2(v0, v2)
 		return true
 	}
+	// match: (Rsh16Ux64 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRL (ZeroExt16to64 x) y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SRL)
+		v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpRsh16Ux8(v *Value) bool {
 	v_1 := v.Args[1]
@@ -5253,11 +6325,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh16Ux8 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (AND (SRL <t> (ZeroExt16to64 x) y) (Neg16 <t> (SLTIU <t> [64] (ZeroExt8to64 y))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64AND)
 		v0 := b.NewValue0(v.Pos, OpRISCV64SRL, t)
 		v1 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
@@ -5273,6 +6349,22 @@
 		v.AddArg2(v0, v2)
 		return true
 	}
+	// match: (Rsh16Ux8 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRL (ZeroExt16to64 x) y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SRL)
+		v0 := b.NewValue0(v.Pos, OpZeroExt16to64, typ.UInt64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpRsh16x16(v *Value) bool {
 	v_1 := v.Args[1]
@@ -5280,11 +6372,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh16x16 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (SRA <t> (SignExt16to64 x) (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] (ZeroExt16to64 y)))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64SRA)
 		v.Type = t
 		v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64)
@@ -5302,6 +6398,22 @@
 		v.AddArg2(v0, v1)
 		return true
 	}
+	// match: (Rsh16x16 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRA (SignExt16to64 x) y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SRA)
+		v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpRsh16x32(v *Value) bool {
 	v_1 := v.Args[1]
@@ -5309,11 +6421,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh16x32 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (SRA <t> (SignExt16to64 x) (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] (ZeroExt32to64 y)))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64SRA)
 		v.Type = t
 		v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64)
@@ -5331,6 +6447,22 @@
 		v.AddArg2(v0, v1)
 		return true
 	}
+	// match: (Rsh16x32 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRA (SignExt16to64 x) y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SRA)
+		v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpRsh16x64(v *Value) bool {
 	v_1 := v.Args[1]
@@ -5338,11 +6470,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh16x64 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (SRA <t> (SignExt16to64 x) (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] y))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64SRA)
 		v.Type = t
 		v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64)
@@ -5358,6 +6494,22 @@
 		v.AddArg2(v0, v1)
 		return true
 	}
+	// match: (Rsh16x64 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRA (SignExt16to64 x) y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SRA)
+		v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpRsh16x8(v *Value) bool {
 	v_1 := v.Args[1]
@@ -5365,11 +6517,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh16x8 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (SRA <t> (SignExt16to64 x) (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] (ZeroExt8to64 y)))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64SRA)
 		v.Type = t
 		v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64)
@@ -5387,6 +6543,22 @@
 		v.AddArg2(v0, v1)
 		return true
 	}
+	// match: (Rsh16x8 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRA (SignExt16to64 x) y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SRA)
+		v0 := b.NewValue0(v.Pos, OpSignExt16to64, typ.Int64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpRsh32Ux16(v *Value) bool {
 	v_1 := v.Args[1]
@@ -5394,11 +6566,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh32Ux16 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (AND (SRL <t> (ZeroExt32to64 x) y) (Neg32 <t> (SLTIU <t> [64] (ZeroExt16to64 y))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64AND)
 		v0 := b.NewValue0(v.Pos, OpRISCV64SRL, t)
 		v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
@@ -5414,6 +6590,22 @@
 		v.AddArg2(v0, v2)
 		return true
 	}
+	// match: (Rsh32Ux16 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRL (ZeroExt32to64 x) y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SRL)
+		v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpRsh32Ux32(v *Value) bool {
 	v_1 := v.Args[1]
@@ -5421,11 +6613,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh32Ux32 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (AND (SRL <t> (ZeroExt32to64 x) y) (Neg32 <t> (SLTIU <t> [64] (ZeroExt32to64 y))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64AND)
 		v0 := b.NewValue0(v.Pos, OpRISCV64SRL, t)
 		v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
@@ -5441,6 +6637,22 @@
 		v.AddArg2(v0, v2)
 		return true
 	}
+	// match: (Rsh32Ux32 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRL (ZeroExt32to64 x) y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SRL)
+		v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpRsh32Ux64(v *Value) bool {
 	v_1 := v.Args[1]
@@ -5448,11 +6660,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh32Ux64 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (AND (SRL <t> (ZeroExt32to64 x) y) (Neg32 <t> (SLTIU <t> [64] y)))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64AND)
 		v0 := b.NewValue0(v.Pos, OpRISCV64SRL, t)
 		v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
@@ -5466,6 +6682,22 @@
 		v.AddArg2(v0, v2)
 		return true
 	}
+	// match: (Rsh32Ux64 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRL (ZeroExt32to64 x) y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SRL)
+		v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpRsh32Ux8(v *Value) bool {
 	v_1 := v.Args[1]
@@ -5473,11 +6705,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh32Ux8 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (AND (SRL <t> (ZeroExt32to64 x) y) (Neg32 <t> (SLTIU <t> [64] (ZeroExt8to64 y))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64AND)
 		v0 := b.NewValue0(v.Pos, OpRISCV64SRL, t)
 		v1 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
@@ -5493,6 +6729,22 @@
 		v.AddArg2(v0, v2)
 		return true
 	}
+	// match: (Rsh32Ux8 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRL (ZeroExt32to64 x) y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SRL)
+		v0 := b.NewValue0(v.Pos, OpZeroExt32to64, typ.UInt64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpRsh32x16(v *Value) bool {
 	v_1 := v.Args[1]
@@ -5500,11 +6752,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh32x16 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (SRA <t> (SignExt32to64 x) (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] (ZeroExt16to64 y)))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64SRA)
 		v.Type = t
 		v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
@@ -5522,6 +6778,22 @@
 		v.AddArg2(v0, v1)
 		return true
 	}
+	// match: (Rsh32x16 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRA (SignExt32to64 x) y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SRA)
+		v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpRsh32x32(v *Value) bool {
 	v_1 := v.Args[1]
@@ -5529,11 +6801,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh32x32 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (SRA <t> (SignExt32to64 x) (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] (ZeroExt32to64 y)))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64SRA)
 		v.Type = t
 		v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
@@ -5551,6 +6827,22 @@
 		v.AddArg2(v0, v1)
 		return true
 	}
+	// match: (Rsh32x32 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRA (SignExt32to64 x) y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SRA)
+		v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpRsh32x64(v *Value) bool {
 	v_1 := v.Args[1]
@@ -5558,11 +6850,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh32x64 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (SRA <t> (SignExt32to64 x) (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] y))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64SRA)
 		v.Type = t
 		v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
@@ -5578,6 +6874,22 @@
 		v.AddArg2(v0, v1)
 		return true
 	}
+	// match: (Rsh32x64 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRA (SignExt32to64 x) y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SRA)
+		v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpRsh32x8(v *Value) bool {
 	v_1 := v.Args[1]
@@ -5585,11 +6897,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh32x8 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (SRA <t> (SignExt32to64 x) (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] (ZeroExt8to64 y)))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64SRA)
 		v.Type = t
 		v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
@@ -5607,6 +6923,22 @@
 		v.AddArg2(v0, v1)
 		return true
 	}
+	// match: (Rsh32x8 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRA (SignExt32to64 x) y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SRA)
+		v0 := b.NewValue0(v.Pos, OpSignExt32to64, typ.Int64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpRsh64Ux16(v *Value) bool {
 	v_1 := v.Args[1]
@@ -5614,11 +6946,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh64Ux16 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (AND (SRL <t> x y) (Neg64 <t> (SLTIU <t> [64] (ZeroExt16to64 y))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64AND)
 		v0 := b.NewValue0(v.Pos, OpRISCV64SRL, t)
 		v0.AddArg2(x, y)
@@ -5632,6 +6968,20 @@
 		v.AddArg2(v0, v1)
 		return true
 	}
+	// match: (Rsh64Ux16 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRL x y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SRL)
+		v.AddArg2(x, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpRsh64Ux32(v *Value) bool {
 	v_1 := v.Args[1]
@@ -5639,11 +6989,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh64Ux32 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (AND (SRL <t> x y) (Neg64 <t> (SLTIU <t> [64] (ZeroExt32to64 y))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64AND)
 		v0 := b.NewValue0(v.Pos, OpRISCV64SRL, t)
 		v0.AddArg2(x, y)
@@ -5657,17 +7011,35 @@
 		v.AddArg2(v0, v1)
 		return true
 	}
+	// match: (Rsh64Ux32 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRL x y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SRL)
+		v.AddArg2(x, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpRsh64Ux64(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
 	// match: (Rsh64Ux64 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (AND (SRL <t> x y) (Neg64 <t> (SLTIU <t> [64] y)))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64AND)
 		v0 := b.NewValue0(v.Pos, OpRISCV64SRL, t)
 		v0.AddArg2(x, y)
@@ -5679,6 +7051,20 @@
 		v.AddArg2(v0, v1)
 		return true
 	}
+	// match: (Rsh64Ux64 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRL x y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SRL)
+		v.AddArg2(x, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpRsh64Ux8(v *Value) bool {
 	v_1 := v.Args[1]
@@ -5686,11 +7072,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh64Ux8 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (AND (SRL <t> x y) (Neg64 <t> (SLTIU <t> [64] (ZeroExt8to64 y))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64AND)
 		v0 := b.NewValue0(v.Pos, OpRISCV64SRL, t)
 		v0.AddArg2(x, y)
@@ -5704,6 +7094,20 @@
 		v.AddArg2(v0, v1)
 		return true
 	}
+	// match: (Rsh64Ux8 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRL x y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SRL)
+		v.AddArg2(x, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpRsh64x16(v *Value) bool {
 	v_1 := v.Args[1]
@@ -5711,11 +7115,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh64x16 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (SRA <t> x (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] (ZeroExt16to64 y)))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64SRA)
 		v.Type = t
 		v0 := b.NewValue0(v.Pos, OpRISCV64OR, y.Type)
@@ -5731,6 +7139,20 @@
 		v.AddArg2(x, v0)
 		return true
 	}
+	// match: (Rsh64x16 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRA x y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SRA)
+		v.AddArg2(x, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpRsh64x32(v *Value) bool {
 	v_1 := v.Args[1]
@@ -5738,11 +7160,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh64x32 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (SRA <t> x (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] (ZeroExt32to64 y)))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64SRA)
 		v.Type = t
 		v0 := b.NewValue0(v.Pos, OpRISCV64OR, y.Type)
@@ -5758,17 +7184,35 @@
 		v.AddArg2(x, v0)
 		return true
 	}
+	// match: (Rsh64x32 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRA x y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SRA)
+		v.AddArg2(x, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpRsh64x64(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
 	// match: (Rsh64x64 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (SRA <t> x (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] y))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64SRA)
 		v.Type = t
 		v0 := b.NewValue0(v.Pos, OpRISCV64OR, y.Type)
@@ -5782,6 +7226,20 @@
 		v.AddArg2(x, v0)
 		return true
 	}
+	// match: (Rsh64x64 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRA x y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SRA)
+		v.AddArg2(x, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpRsh64x8(v *Value) bool {
 	v_1 := v.Args[1]
@@ -5789,11 +7247,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh64x8 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (SRA <t> x (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] (ZeroExt8to64 y)))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64SRA)
 		v.Type = t
 		v0 := b.NewValue0(v.Pos, OpRISCV64OR, y.Type)
@@ -5809,6 +7271,20 @@
 		v.AddArg2(x, v0)
 		return true
 	}
+	// match: (Rsh64x8 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRA x y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SRA)
+		v.AddArg2(x, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpRsh8Ux16(v *Value) bool {
 	v_1 := v.Args[1]
@@ -5816,11 +7292,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh8Ux16 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (AND (SRL <t> (ZeroExt8to64 x) y) (Neg8 <t> (SLTIU <t> [64] (ZeroExt16to64 y))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64AND)
 		v0 := b.NewValue0(v.Pos, OpRISCV64SRL, t)
 		v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
@@ -5836,6 +7316,22 @@
 		v.AddArg2(v0, v2)
 		return true
 	}
+	// match: (Rsh8Ux16 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRL (ZeroExt8to64 x) y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SRL)
+		v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpRsh8Ux32(v *Value) bool {
 	v_1 := v.Args[1]
@@ -5843,11 +7339,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh8Ux32 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (AND (SRL <t> (ZeroExt8to64 x) y) (Neg8 <t> (SLTIU <t> [64] (ZeroExt32to64 y))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64AND)
 		v0 := b.NewValue0(v.Pos, OpRISCV64SRL, t)
 		v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
@@ -5863,6 +7363,22 @@
 		v.AddArg2(v0, v2)
 		return true
 	}
+	// match: (Rsh8Ux32 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRL (ZeroExt8to64 x) y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SRL)
+		v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpRsh8Ux64(v *Value) bool {
 	v_1 := v.Args[1]
@@ -5870,11 +7386,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh8Ux64 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (AND (SRL <t> (ZeroExt8to64 x) y) (Neg8 <t> (SLTIU <t> [64] y)))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64AND)
 		v0 := b.NewValue0(v.Pos, OpRISCV64SRL, t)
 		v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
@@ -5888,6 +7408,22 @@
 		v.AddArg2(v0, v2)
 		return true
 	}
+	// match: (Rsh8Ux64 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRL (ZeroExt8to64 x) y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SRL)
+		v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpRsh8Ux8(v *Value) bool {
 	v_1 := v.Args[1]
@@ -5895,11 +7431,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh8Ux8 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (AND (SRL <t> (ZeroExt8to64 x) y) (Neg8 <t> (SLTIU <t> [64] (ZeroExt8to64 y))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64AND)
 		v0 := b.NewValue0(v.Pos, OpRISCV64SRL, t)
 		v1 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
@@ -5915,6 +7455,22 @@
 		v.AddArg2(v0, v2)
 		return true
 	}
+	// match: (Rsh8Ux8 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRL (ZeroExt8to64 x) y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SRL)
+		v0 := b.NewValue0(v.Pos, OpZeroExt8to64, typ.UInt64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpRsh8x16(v *Value) bool {
 	v_1 := v.Args[1]
@@ -5922,11 +7478,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh8x16 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (SRA <t> (SignExt8to64 x) (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] (ZeroExt16to64 y)))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64SRA)
 		v.Type = t
 		v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64)
@@ -5944,6 +7504,22 @@
 		v.AddArg2(v0, v1)
 		return true
 	}
+	// match: (Rsh8x16 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRA (SignExt8to64 x) y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SRA)
+		v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpRsh8x32(v *Value) bool {
 	v_1 := v.Args[1]
@@ -5951,11 +7527,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh8x32 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (SRA <t> (SignExt8to64 x) (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] (ZeroExt32to64 y)))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64SRA)
 		v.Type = t
 		v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64)
@@ -5973,6 +7553,22 @@
 		v.AddArg2(v0, v1)
 		return true
 	}
+	// match: (Rsh8x32 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRA (SignExt8to64 x) y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SRA)
+		v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpRsh8x64(v *Value) bool {
 	v_1 := v.Args[1]
@@ -5980,11 +7576,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh8x64 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (SRA <t> (SignExt8to64 x) (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] y))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64SRA)
 		v.Type = t
 		v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64)
@@ -6000,6 +7600,22 @@
 		v.AddArg2(v0, v1)
 		return true
 	}
+	// match: (Rsh8x64 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRA (SignExt8to64 x) y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SRA)
+		v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpRsh8x8(v *Value) bool {
 	v_1 := v.Args[1]
@@ -6007,11 +7623,15 @@
 	b := v.Block
 	typ := &b.Func.Config.Types
 	// match: (Rsh8x8 <t> x y)
+	// cond: !shiftIsBounded(v)
 	// result: (SRA <t> (SignExt8to64 x) (OR <y.Type> y (ADDI <y.Type> [-1] (SLTIU <y.Type> [64] (ZeroExt8to64 y)))))
 	for {
 		t := v.Type
 		x := v_0
 		y := v_1
+		if !(!shiftIsBounded(v)) {
+			break
+		}
 		v.reset(OpRISCV64SRA)
 		v.Type = t
 		v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64)
@@ -6029,22 +7649,153 @@
 		v.AddArg2(v0, v1)
 		return true
 	}
+	// match: (Rsh8x8 x y)
+	// cond: shiftIsBounded(v)
+	// result: (SRA (SignExt8to64 x) y)
+	for {
+		x := v_0
+		y := v_1
+		if !(shiftIsBounded(v)) {
+			break
+		}
+		v.reset(OpRISCV64SRA)
+		v0 := b.NewValue0(v.Pos, OpSignExt8to64, typ.Int64)
+		v0.AddArg(x)
+		v.AddArg2(v0, y)
+		return true
+	}
+	return false
+}
+func rewriteValueRISCV64_OpSelect0(v *Value) bool {
+	v_0 := v.Args[0]
+	b := v.Block
+	typ := &b.Func.Config.Types
+	// match: (Select0 (Add64carry x y c))
+	// result: (ADD (ADD <typ.UInt64> x y) c)
+	for {
+		if v_0.Op != OpAdd64carry {
+			break
+		}
+		c := v_0.Args[2]
+		x := v_0.Args[0]
+		y := v_0.Args[1]
+		v.reset(OpRISCV64ADD)
+		v0 := b.NewValue0(v.Pos, OpRISCV64ADD, typ.UInt64)
+		v0.AddArg2(x, y)
+		v.AddArg2(v0, c)
+		return true
+	}
+	// match: (Select0 (Sub64borrow x y c))
+	// result: (SUB (SUB <typ.UInt64> x y) c)
+	for {
+		if v_0.Op != OpSub64borrow {
+			break
+		}
+		c := v_0.Args[2]
+		x := v_0.Args[0]
+		y := v_0.Args[1]
+		v.reset(OpRISCV64SUB)
+		v0 := b.NewValue0(v.Pos, OpRISCV64SUB, typ.UInt64)
+		v0.AddArg2(x, y)
+		v.AddArg2(v0, c)
+		return true
+	}
+	// match: (Select0 m:(LoweredMuluhilo x y))
+	// cond: m.Uses == 1
+	// result: (MULHU x y)
+	for {
+		m := v_0
+		if m.Op != OpRISCV64LoweredMuluhilo {
+			break
+		}
+		y := m.Args[1]
+		x := m.Args[0]
+		if !(m.Uses == 1) {
+			break
+		}
+		v.reset(OpRISCV64MULHU)
+		v.AddArg2(x, y)
+		return true
+	}
+	return false
+}
+func rewriteValueRISCV64_OpSelect1(v *Value) bool {
+	v_0 := v.Args[0]
+	b := v.Block
+	typ := &b.Func.Config.Types
+	// match: (Select1 (Add64carry x y c))
+	// result: (OR (SLTU <typ.UInt64> s:(ADD <typ.UInt64> x y) x) (SLTU <typ.UInt64> (ADD <typ.UInt64> s c) s))
+	for {
+		if v_0.Op != OpAdd64carry {
+			break
+		}
+		c := v_0.Args[2]
+		x := v_0.Args[0]
+		y := v_0.Args[1]
+		v.reset(OpRISCV64OR)
+		v0 := b.NewValue0(v.Pos, OpRISCV64SLTU, typ.UInt64)
+		s := b.NewValue0(v.Pos, OpRISCV64ADD, typ.UInt64)
+		s.AddArg2(x, y)
+		v0.AddArg2(s, x)
+		v2 := b.NewValue0(v.Pos, OpRISCV64SLTU, typ.UInt64)
+		v3 := b.NewValue0(v.Pos, OpRISCV64ADD, typ.UInt64)
+		v3.AddArg2(s, c)
+		v2.AddArg2(v3, s)
+		v.AddArg2(v0, v2)
+		return true
+	}
+	// match: (Select1 (Sub64borrow x y c))
+	// result: (OR (SLTU <typ.UInt64> x s:(SUB <typ.UInt64> x y)) (SLTU <typ.UInt64> s (SUB <typ.UInt64> s c)))
+	for {
+		if v_0.Op != OpSub64borrow {
+			break
+		}
+		c := v_0.Args[2]
+		x := v_0.Args[0]
+		y := v_0.Args[1]
+		v.reset(OpRISCV64OR)
+		v0 := b.NewValue0(v.Pos, OpRISCV64SLTU, typ.UInt64)
+		s := b.NewValue0(v.Pos, OpRISCV64SUB, typ.UInt64)
+		s.AddArg2(x, y)
+		v0.AddArg2(x, s)
+		v2 := b.NewValue0(v.Pos, OpRISCV64SLTU, typ.UInt64)
+		v3 := b.NewValue0(v.Pos, OpRISCV64SUB, typ.UInt64)
+		v3.AddArg2(s, c)
+		v2.AddArg2(s, v3)
+		v.AddArg2(v0, v2)
+		return true
+	}
+	// match: (Select1 m:(LoweredMuluhilo x y))
+	// cond: m.Uses == 1
+	// result: (MUL x y)
+	for {
+		m := v_0
+		if m.Op != OpRISCV64LoweredMuluhilo {
+			break
+		}
+		y := m.Args[1]
+		x := m.Args[0]
+		if !(m.Uses == 1) {
+			break
+		}
+		v.reset(OpRISCV64MUL)
+		v.AddArg2(x, y)
+		return true
+	}
+	return false
 }
 func rewriteValueRISCV64_OpSlicemask(v *Value) bool {
 	v_0 := v.Args[0]
 	b := v.Block
 	// match: (Slicemask <t> x)
-	// result: (NOT (SRAI <t> [63] (ADDI <t> [-1] x)))
+	// result: (SRAI [63] (NEG <t> x))
 	for {
 		t := v.Type
 		x := v_0
-		v.reset(OpRISCV64NOT)
-		v0 := b.NewValue0(v.Pos, OpRISCV64SRAI, t)
-		v0.AuxInt = int64ToAuxInt(63)
-		v1 := b.NewValue0(v.Pos, OpRISCV64ADDI, t)
-		v1.AuxInt = int64ToAuxInt(-1)
-		v1.AddArg(x)
-		v0.AddArg(v1)
+		v.reset(OpRISCV64SRAI)
+		v.AuxInt = int64ToAuxInt(63)
+		v0 := b.NewValue0(v.Pos, OpRISCV64NEG, t)
+		v0.AddArg(x)
 		v.AddArg(v0)
 		return true
 	}
@@ -6565,18 +8316,48 @@
 			b.resetWithControl(BlockRISCV64BEQZ, x)
 			return true
 		}
-		// match: (BEQZ x:(NEG y) yes no)
-		// cond: x.Uses == 1
-		// result: (BEQZ y yes no)
+		// match: (BEQZ (NEG x) yes no)
+		// result: (BEQZ x yes no)
 		for b.Controls[0].Op == OpRISCV64NEG {
-			x := b.Controls[0]
-			y := x.Args[0]
-			if !(x.Uses == 1) {
-				break
-			}
-			b.resetWithControl(BlockRISCV64BEQZ, y)
+			v_0 := b.Controls[0]
+			x := v_0.Args[0]
+			b.resetWithControl(BlockRISCV64BEQZ, x)
 			return true
 		}
+		// match: (BEQZ (FNES <t> x y) yes no)
+		// result: (BNEZ (FEQS <t> x y) yes no)
+		for b.Controls[0].Op == OpRISCV64FNES {
+			v_0 := b.Controls[0]
+			t := v_0.Type
+			_ = v_0.Args[1]
+			v_0_0 := v_0.Args[0]
+			v_0_1 := v_0.Args[1]
+			for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
+				x := v_0_0
+				y := v_0_1
+				v0 := b.NewValue0(v_0.Pos, OpRISCV64FEQS, t)
+				v0.AddArg2(x, y)
+				b.resetWithControl(BlockRISCV64BNEZ, v0)
+				return true
+			}
+		}
+		// match: (BEQZ (FNED <t> x y) yes no)
+		// result: (BNEZ (FEQD <t> x y) yes no)
+		for b.Controls[0].Op == OpRISCV64FNED {
+			v_0 := b.Controls[0]
+			t := v_0.Type
+			_ = v_0.Args[1]
+			v_0_0 := v_0.Args[0]
+			v_0_1 := v_0.Args[1]
+			for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
+				x := v_0_0
+				y := v_0_1
+				v0 := b.NewValue0(v_0.Pos, OpRISCV64FEQD, t)
+				v0.AddArg2(x, y)
+				b.resetWithControl(BlockRISCV64BNEZ, v0)
+				return true
+			}
+		}
 		// match: (BEQZ (SUB x y) yes no)
 		// result: (BEQ x y yes no)
 		for b.Controls[0].Op == OpRISCV64SUB {
@@ -6604,6 +8385,28 @@
 			b.resetWithControl2(BlockRISCV64BGEU, x, y)
 			return true
 		}
+		// match: (BEQZ (SLTI [x] y) yes no)
+		// result: (BGE y (MOVDconst [x]) yes no)
+		for b.Controls[0].Op == OpRISCV64SLTI {
+			v_0 := b.Controls[0]
+			x := auxIntToInt64(v_0.AuxInt)
+			y := v_0.Args[0]
+			v0 := b.NewValue0(b.Pos, OpRISCV64MOVDconst, typ.UInt64)
+			v0.AuxInt = int64ToAuxInt(x)
+			b.resetWithControl2(BlockRISCV64BGE, y, v0)
+			return true
+		}
+		// match: (BEQZ (SLTIU [x] y) yes no)
+		// result: (BGEU y (MOVDconst [x]) yes no)
+		for b.Controls[0].Op == OpRISCV64SLTIU {
+			v_0 := b.Controls[0]
+			x := auxIntToInt64(v_0.AuxInt)
+			y := v_0.Args[0]
+			v0 := b.NewValue0(b.Pos, OpRISCV64MOVDconst, typ.UInt64)
+			v0.AuxInt = int64ToAuxInt(x)
+			b.resetWithControl2(BlockRISCV64BGEU, y, v0)
+			return true
+		}
 	case BlockRISCV64BGE:
 		// match: (BGE (MOVDconst [0]) cond yes no)
 		// result: (BLEZ cond yes no)
@@ -6690,18 +8493,48 @@
 			b.resetWithControl(BlockRISCV64BNEZ, x)
 			return true
 		}
-		// match: (BNEZ x:(NEG y) yes no)
-		// cond: x.Uses == 1
-		// result: (BNEZ y yes no)
+		// match: (BNEZ (NEG x) yes no)
+		// result: (BNEZ x yes no)
 		for b.Controls[0].Op == OpRISCV64NEG {
-			x := b.Controls[0]
-			y := x.Args[0]
-			if !(x.Uses == 1) {
-				break
-			}
-			b.resetWithControl(BlockRISCV64BNEZ, y)
+			v_0 := b.Controls[0]
+			x := v_0.Args[0]
+			b.resetWithControl(BlockRISCV64BNEZ, x)
 			return true
 		}
+		// match: (BNEZ (FNES <t> x y) yes no)
+		// result: (BEQZ (FEQS <t> x y) yes no)
+		for b.Controls[0].Op == OpRISCV64FNES {
+			v_0 := b.Controls[0]
+			t := v_0.Type
+			_ = v_0.Args[1]
+			v_0_0 := v_0.Args[0]
+			v_0_1 := v_0.Args[1]
+			for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
+				x := v_0_0
+				y := v_0_1
+				v0 := b.NewValue0(v_0.Pos, OpRISCV64FEQS, t)
+				v0.AddArg2(x, y)
+				b.resetWithControl(BlockRISCV64BEQZ, v0)
+				return true
+			}
+		}
+		// match: (BNEZ (FNED <t> x y) yes no)
+		// result: (BEQZ (FEQD <t> x y) yes no)
+		for b.Controls[0].Op == OpRISCV64FNED {
+			v_0 := b.Controls[0]
+			t := v_0.Type
+			_ = v_0.Args[1]
+			v_0_0 := v_0.Args[0]
+			v_0_1 := v_0.Args[1]
+			for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
+				x := v_0_0
+				y := v_0_1
+				v0 := b.NewValue0(v_0.Pos, OpRISCV64FEQD, t)
+				v0.AddArg2(x, y)
+				b.resetWithControl(BlockRISCV64BEQZ, v0)
+				return true
+			}
+		}
 		// match: (BNEZ (SUB x y) yes no)
 		// result: (BNE x y yes no)
 		for b.Controls[0].Op == OpRISCV64SUB {
@@ -6729,6 +8562,28 @@
 			b.resetWithControl2(BlockRISCV64BLTU, x, y)
 			return true
 		}
+		// match: (BNEZ (SLTI [x] y) yes no)
+		// result: (BLT y (MOVDconst [x]) yes no)
+		for b.Controls[0].Op == OpRISCV64SLTI {
+			v_0 := b.Controls[0]
+			x := auxIntToInt64(v_0.AuxInt)
+			y := v_0.Args[0]
+			v0 := b.NewValue0(b.Pos, OpRISCV64MOVDconst, typ.UInt64)
+			v0.AuxInt = int64ToAuxInt(x)
+			b.resetWithControl2(BlockRISCV64BLT, y, v0)
+			return true
+		}
+		// match: (BNEZ (SLTIU [x] y) yes no)
+		// result: (BLTU y (MOVDconst [x]) yes no)
+		for b.Controls[0].Op == OpRISCV64SLTIU {
+			v_0 := b.Controls[0]
+			x := auxIntToInt64(v_0.AuxInt)
+			y := v_0.Args[0]
+			v0 := b.NewValue0(b.Pos, OpRISCV64MOVDconst, typ.UInt64)
+			v0.AuxInt = int64ToAuxInt(x)
+			b.resetWithControl2(BlockRISCV64BLTU, y, v0)
+			return true
+		}
 	case BlockIf:
 		// match: (If cond yes no)
 		// result: (BNEZ (MOVBUreg <typ.UInt64> cond) yes no)
diff --git a/src/cmd/compile/internal/ssa/rewriteRISCV64latelower.go b/src/cmd/compile/internal/ssa/rewriteRISCV64latelower.go
new file mode 100644
index 0000000..04a9691
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/rewriteRISCV64latelower.go
@@ -0,0 +1,247 @@
+// Code generated from _gen/RISCV64latelower.rules; DO NOT EDIT.
+// generated with: cd _gen; go run .
+
+package ssa
+
+func rewriteValueRISCV64latelower(v *Value) bool {
+	switch v.Op {
+	case OpRISCV64SLLI:
+		return rewriteValueRISCV64latelower_OpRISCV64SLLI(v)
+	case OpRISCV64SRAI:
+		return rewriteValueRISCV64latelower_OpRISCV64SRAI(v)
+	case OpRISCV64SRLI:
+		return rewriteValueRISCV64latelower_OpRISCV64SRLI(v)
+	}
+	return false
+}
+func rewriteValueRISCV64latelower_OpRISCV64SLLI(v *Value) bool {
+	v_0 := v.Args[0]
+	b := v.Block
+	typ := &b.Func.Config.Types
+	// match: (SLLI [c] (MOVBUreg x))
+	// cond: c <= 56
+	// result: (SRLI [56-c] (SLLI <typ.UInt64> [56] x))
+	for {
+		c := auxIntToInt64(v.AuxInt)
+		if v_0.Op != OpRISCV64MOVBUreg {
+			break
+		}
+		x := v_0.Args[0]
+		if !(c <= 56) {
+			break
+		}
+		v.reset(OpRISCV64SRLI)
+		v.AuxInt = int64ToAuxInt(56 - c)
+		v0 := b.NewValue0(v.Pos, OpRISCV64SLLI, typ.UInt64)
+		v0.AuxInt = int64ToAuxInt(56)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (SLLI [c] (MOVHUreg x))
+	// cond: c <= 48
+	// result: (SRLI [48-c] (SLLI <typ.UInt64> [48] x))
+	for {
+		c := auxIntToInt64(v.AuxInt)
+		if v_0.Op != OpRISCV64MOVHUreg {
+			break
+		}
+		x := v_0.Args[0]
+		if !(c <= 48) {
+			break
+		}
+		v.reset(OpRISCV64SRLI)
+		v.AuxInt = int64ToAuxInt(48 - c)
+		v0 := b.NewValue0(v.Pos, OpRISCV64SLLI, typ.UInt64)
+		v0.AuxInt = int64ToAuxInt(48)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (SLLI [c] (MOVWUreg x))
+	// cond: c <= 32
+	// result: (SRLI [32-c] (SLLI <typ.UInt64> [32] x))
+	for {
+		c := auxIntToInt64(v.AuxInt)
+		if v_0.Op != OpRISCV64MOVWUreg {
+			break
+		}
+		x := v_0.Args[0]
+		if !(c <= 32) {
+			break
+		}
+		v.reset(OpRISCV64SRLI)
+		v.AuxInt = int64ToAuxInt(32 - c)
+		v0 := b.NewValue0(v.Pos, OpRISCV64SLLI, typ.UInt64)
+		v0.AuxInt = int64ToAuxInt(32)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (SLLI [0] x)
+	// result: x
+	for {
+		if auxIntToInt64(v.AuxInt) != 0 {
+			break
+		}
+		x := v_0
+		v.copyOf(x)
+		return true
+	}
+	return false
+}
+func rewriteValueRISCV64latelower_OpRISCV64SRAI(v *Value) bool {
+	v_0 := v.Args[0]
+	b := v.Block
+	typ := &b.Func.Config.Types
+	// match: (SRAI [c] (MOVBreg x))
+	// cond: c < 8
+	// result: (SRAI [56+c] (SLLI <typ.Int64> [56] x))
+	for {
+		c := auxIntToInt64(v.AuxInt)
+		if v_0.Op != OpRISCV64MOVBreg {
+			break
+		}
+		x := v_0.Args[0]
+		if !(c < 8) {
+			break
+		}
+		v.reset(OpRISCV64SRAI)
+		v.AuxInt = int64ToAuxInt(56 + c)
+		v0 := b.NewValue0(v.Pos, OpRISCV64SLLI, typ.Int64)
+		v0.AuxInt = int64ToAuxInt(56)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (SRAI [c] (MOVHreg x))
+	// cond: c < 16
+	// result: (SRAI [48+c] (SLLI <typ.Int64> [48] x))
+	for {
+		c := auxIntToInt64(v.AuxInt)
+		if v_0.Op != OpRISCV64MOVHreg {
+			break
+		}
+		x := v_0.Args[0]
+		if !(c < 16) {
+			break
+		}
+		v.reset(OpRISCV64SRAI)
+		v.AuxInt = int64ToAuxInt(48 + c)
+		v0 := b.NewValue0(v.Pos, OpRISCV64SLLI, typ.Int64)
+		v0.AuxInt = int64ToAuxInt(48)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (SRAI [c] (MOVWreg x))
+	// cond: c < 32
+	// result: (SRAI [32+c] (SLLI <typ.Int64> [32] x))
+	for {
+		c := auxIntToInt64(v.AuxInt)
+		if v_0.Op != OpRISCV64MOVWreg {
+			break
+		}
+		x := v_0.Args[0]
+		if !(c < 32) {
+			break
+		}
+		v.reset(OpRISCV64SRAI)
+		v.AuxInt = int64ToAuxInt(32 + c)
+		v0 := b.NewValue0(v.Pos, OpRISCV64SLLI, typ.Int64)
+		v0.AuxInt = int64ToAuxInt(32)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (SRAI [0] x)
+	// result: x
+	for {
+		if auxIntToInt64(v.AuxInt) != 0 {
+			break
+		}
+		x := v_0
+		v.copyOf(x)
+		return true
+	}
+	return false
+}
+func rewriteValueRISCV64latelower_OpRISCV64SRLI(v *Value) bool {
+	v_0 := v.Args[0]
+	b := v.Block
+	typ := &b.Func.Config.Types
+	// match: (SRLI [c] (MOVBUreg x))
+	// cond: c < 8
+	// result: (SRLI [56+c] (SLLI <typ.UInt64> [56] x))
+	for {
+		c := auxIntToInt64(v.AuxInt)
+		if v_0.Op != OpRISCV64MOVBUreg {
+			break
+		}
+		x := v_0.Args[0]
+		if !(c < 8) {
+			break
+		}
+		v.reset(OpRISCV64SRLI)
+		v.AuxInt = int64ToAuxInt(56 + c)
+		v0 := b.NewValue0(v.Pos, OpRISCV64SLLI, typ.UInt64)
+		v0.AuxInt = int64ToAuxInt(56)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (SRLI [c] (MOVHUreg x))
+	// cond: c < 16
+	// result: (SRLI [48+c] (SLLI <typ.UInt64> [48] x))
+	for {
+		c := auxIntToInt64(v.AuxInt)
+		if v_0.Op != OpRISCV64MOVHUreg {
+			break
+		}
+		x := v_0.Args[0]
+		if !(c < 16) {
+			break
+		}
+		v.reset(OpRISCV64SRLI)
+		v.AuxInt = int64ToAuxInt(48 + c)
+		v0 := b.NewValue0(v.Pos, OpRISCV64SLLI, typ.UInt64)
+		v0.AuxInt = int64ToAuxInt(48)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (SRLI [c] (MOVWUreg x))
+	// cond: c < 32
+	// result: (SRLI [32+c] (SLLI <typ.UInt64> [32] x))
+	for {
+		c := auxIntToInt64(v.AuxInt)
+		if v_0.Op != OpRISCV64MOVWUreg {
+			break
+		}
+		x := v_0.Args[0]
+		if !(c < 32) {
+			break
+		}
+		v.reset(OpRISCV64SRLI)
+		v.AuxInt = int64ToAuxInt(32 + c)
+		v0 := b.NewValue0(v.Pos, OpRISCV64SLLI, typ.UInt64)
+		v0.AuxInt = int64ToAuxInt(32)
+		v0.AddArg(x)
+		v.AddArg(v0)
+		return true
+	}
+	// match: (SRLI [0] x)
+	// result: x
+	for {
+		if auxIntToInt64(v.AuxInt) != 0 {
+			break
+		}
+		x := v_0
+		v.copyOf(x)
+		return true
+	}
+	return false
+}
+func rewriteBlockRISCV64latelower(b *Block) bool {
+	return false
+}
diff --git a/src/cmd/compile/internal/ssa/rewriteS390X.go b/src/cmd/compile/internal/ssa/rewriteS390X.go
index 0d63586..8f40ecd 100644
--- a/src/cmd/compile/internal/ssa/rewriteS390X.go
+++ b/src/cmd/compile/internal/ssa/rewriteS390X.go
@@ -1,5 +1,5 @@
-// Code generated from gen/S390X.rules; DO NOT EDIT.
-// generated with: cd gen; go run *.go
+// Code generated from _gen/S390X.rules; DO NOT EDIT.
+// generated with: cd _gen; go run .
 
 package ssa
 
@@ -5280,25 +5280,6 @@
 		}
 		break
 	}
-	// match: (ADD (SLDconst x [c]) (SRDconst x [64-c]))
-	// result: (RISBGZ x {s390x.NewRotateParams(0, 63, c)})
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpS390XSLDconst {
-				continue
-			}
-			c := auxIntToUint8(v_0.AuxInt)
-			x := v_0.Args[0]
-			if v_1.Op != OpS390XSRDconst || auxIntToUint8(v_1.AuxInt) != 64-c || x != v_1.Args[0] {
-				continue
-			}
-			v.reset(OpS390XRISBGZ)
-			v.Aux = s390xRotateParamsToAux(s390x.NewRotateParams(0, 63, c))
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
 	// match: (ADD idx (MOVDaddr [c] {s} ptr))
 	// cond: ptr.Op != OpSB
 	// result: (MOVDaddridx [c] {s} ptr idx)
@@ -5473,25 +5454,6 @@
 		}
 		break
 	}
-	// match: (ADDW (SLWconst x [c]) (SRWconst x [32-c]))
-	// result: (RLLconst x [c])
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpS390XSLWconst {
-				continue
-			}
-			c := auxIntToUint8(v_0.AuxInt)
-			x := v_0.Args[0]
-			if v_1.Op != OpS390XSRWconst || auxIntToUint8(v_1.AuxInt) != 32-c || x != v_1.Args[0] {
-				continue
-			}
-			v.reset(OpS390XRLLconst)
-			v.AuxInt = uint8ToAuxInt(c)
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
 	// match: (ADDW x (NEGW y))
 	// result: (SUBW x y)
 	for {
@@ -11689,25 +11651,6 @@
 		}
 		break
 	}
-	// match: (OR (SLDconst x [c]) (SRDconst x [64-c]))
-	// result: (RISBGZ x {s390x.NewRotateParams(0, 63, c)})
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpS390XSLDconst {
-				continue
-			}
-			c := auxIntToUint8(v_0.AuxInt)
-			x := v_0.Args[0]
-			if v_1.Op != OpS390XSRDconst || auxIntToUint8(v_1.AuxInt) != 64-c || x != v_1.Args[0] {
-				continue
-			}
-			v.reset(OpS390XRISBGZ)
-			v.Aux = s390xRotateParamsToAux(s390x.NewRotateParams(0, 63, c))
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
 	// match: (OR (MOVDconst [-1<<63]) (LGDR <t> x))
 	// result: (LGDR <t> (LNDFR <x.Type> x))
 	for {
@@ -12387,25 +12330,6 @@
 		}
 		break
 	}
-	// match: (ORW (SLWconst x [c]) (SRWconst x [32-c]))
-	// result: (RLLconst x [c])
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpS390XSLWconst {
-				continue
-			}
-			c := auxIntToUint8(v_0.AuxInt)
-			x := v_0.Args[0]
-			if v_1.Op != OpS390XSRWconst || auxIntToUint8(v_1.AuxInt) != 32-c || x != v_1.Args[0] {
-				continue
-			}
-			v.reset(OpS390XRLLconst)
-			v.AuxInt = uint8ToAuxInt(c)
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
 	// match: (ORW x x)
 	// result: x
 	for {
@@ -14972,25 +14896,6 @@
 		}
 		break
 	}
-	// match: (XOR (SLDconst x [c]) (SRDconst x [64-c]))
-	// result: (RISBGZ x {s390x.NewRotateParams(0, 63, c)})
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpS390XSLDconst {
-				continue
-			}
-			c := auxIntToUint8(v_0.AuxInt)
-			x := v_0.Args[0]
-			if v_1.Op != OpS390XSRDconst || auxIntToUint8(v_1.AuxInt) != 64-c || x != v_1.Args[0] {
-				continue
-			}
-			v.reset(OpS390XRISBGZ)
-			v.Aux = s390xRotateParamsToAux(s390x.NewRotateParams(0, 63, c))
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
 	// match: (XOR (MOVDconst [c]) (MOVDconst [d]))
 	// result: (MOVDconst [c^d])
 	for {
@@ -15068,25 +14973,6 @@
 		}
 		break
 	}
-	// match: (XORW (SLWconst x [c]) (SRWconst x [32-c]))
-	// result: (RLLconst x [c])
-	for {
-		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
-			if v_0.Op != OpS390XSLWconst {
-				continue
-			}
-			c := auxIntToUint8(v_0.AuxInt)
-			x := v_0.Args[0]
-			if v_1.Op != OpS390XSRWconst || auxIntToUint8(v_1.AuxInt) != 32-c || x != v_1.Args[0] {
-				continue
-			}
-			v.reset(OpS390XRLLconst)
-			v.AuxInt = uint8ToAuxInt(c)
-			v.AddArg(x)
-			return true
-		}
-		break
-	}
 	// match: (XORW x x)
 	// result: (MOVDconst [0])
 	for {
@@ -15449,6 +15335,7 @@
 		return true
 	}
 	// match: (Select0 (FADD (FMUL y z) x))
+	// cond: x.Block.Func.useFMA(v)
 	// result: (FMADD x y z)
 	for {
 		if v_0.Op != OpS390XFADD {
@@ -15464,6 +15351,9 @@
 			z := v_0_0.Args[1]
 			y := v_0_0.Args[0]
 			x := v_0_1
+			if !(x.Block.Func.useFMA(v)) {
+				continue
+			}
 			v.reset(OpS390XFMADD)
 			v.AddArg3(x, y, z)
 			return true
@@ -15471,6 +15361,7 @@
 		break
 	}
 	// match: (Select0 (FSUB (FMUL y z) x))
+	// cond: x.Block.Func.useFMA(v)
 	// result: (FMSUB x y z)
 	for {
 		if v_0.Op != OpS390XFSUB {
@@ -15483,11 +15374,15 @@
 		}
 		z := v_0_0.Args[1]
 		y := v_0_0.Args[0]
+		if !(x.Block.Func.useFMA(v)) {
+			break
+		}
 		v.reset(OpS390XFMSUB)
 		v.AddArg3(x, y, z)
 		return true
 	}
 	// match: (Select0 (FADDS (FMULS y z) x))
+	// cond: x.Block.Func.useFMA(v)
 	// result: (FMADDS x y z)
 	for {
 		if v_0.Op != OpS390XFADDS {
@@ -15503,6 +15398,9 @@
 			z := v_0_0.Args[1]
 			y := v_0_0.Args[0]
 			x := v_0_1
+			if !(x.Block.Func.useFMA(v)) {
+				continue
+			}
 			v.reset(OpS390XFMADDS)
 			v.AddArg3(x, y, z)
 			return true
@@ -15510,6 +15408,7 @@
 		break
 	}
 	// match: (Select0 (FSUBS (FMULS y z) x))
+	// cond: x.Block.Func.useFMA(v)
 	// result: (FMSUBS x y z)
 	for {
 		if v_0.Op != OpS390XFSUBS {
@@ -15522,6 +15421,9 @@
 		}
 		z := v_0_0.Args[1]
 		y := v_0_0.Args[0]
+		if !(x.Block.Func.useFMA(v)) {
+			break
+		}
 		v.reset(OpS390XFMSUBS)
 		v.AddArg3(x, y, z)
 		return true
diff --git a/src/cmd/compile/internal/ssa/rewriteWasm.go b/src/cmd/compile/internal/ssa/rewriteWasm.go
index defd40d..a5be792 100644
--- a/src/cmd/compile/internal/ssa/rewriteWasm.go
+++ b/src/cmd/compile/internal/ssa/rewriteWasm.go
@@ -1,5 +1,5 @@
-// Code generated from gen/Wasm.rules; DO NOT EDIT.
-// generated with: cd gen; go run *.go
+// Code generated from _gen/Wasm.rules; DO NOT EDIT.
+// generated with: cd _gen; go run .
 
 package ssa
 
@@ -2141,76 +2141,18 @@
 		return true
 	}
 	// match: (Move [s] dst src mem)
-	// cond: s > 16 && s%16 != 0 && s%16 <= 8
-	// result: (Move [s-s%16] (OffPtr <dst.Type> dst [s%16]) (OffPtr <src.Type> src [s%16]) (I64Store dst (I64Load src mem) mem))
+	// cond: logLargeCopy(v, s)
+	// result: (LoweredMove [s] dst src mem)
 	for {
 		s := auxIntToInt64(v.AuxInt)
 		dst := v_0
 		src := v_1
 		mem := v_2
-		if !(s > 16 && s%16 != 0 && s%16 <= 8) {
-			break
-		}
-		v.reset(OpMove)
-		v.AuxInt = int64ToAuxInt(s - s%16)
-		v0 := b.NewValue0(v.Pos, OpOffPtr, dst.Type)
-		v0.AuxInt = int64ToAuxInt(s % 16)
-		v0.AddArg(dst)
-		v1 := b.NewValue0(v.Pos, OpOffPtr, src.Type)
-		v1.AuxInt = int64ToAuxInt(s % 16)
-		v1.AddArg(src)
-		v2 := b.NewValue0(v.Pos, OpWasmI64Store, types.TypeMem)
-		v3 := b.NewValue0(v.Pos, OpWasmI64Load, typ.UInt64)
-		v3.AddArg2(src, mem)
-		v2.AddArg3(dst, v3, mem)
-		v.AddArg3(v0, v1, v2)
-		return true
-	}
-	// match: (Move [s] dst src mem)
-	// cond: s > 16 && s%16 != 0 && s%16 > 8
-	// result: (Move [s-s%16] (OffPtr <dst.Type> dst [s%16]) (OffPtr <src.Type> src [s%16]) (I64Store [8] dst (I64Load [8] src mem) (I64Store dst (I64Load src mem) mem)))
-	for {
-		s := auxIntToInt64(v.AuxInt)
-		dst := v_0
-		src := v_1
-		mem := v_2
-		if !(s > 16 && s%16 != 0 && s%16 > 8) {
-			break
-		}
-		v.reset(OpMove)
-		v.AuxInt = int64ToAuxInt(s - s%16)
-		v0 := b.NewValue0(v.Pos, OpOffPtr, dst.Type)
-		v0.AuxInt = int64ToAuxInt(s % 16)
-		v0.AddArg(dst)
-		v1 := b.NewValue0(v.Pos, OpOffPtr, src.Type)
-		v1.AuxInt = int64ToAuxInt(s % 16)
-		v1.AddArg(src)
-		v2 := b.NewValue0(v.Pos, OpWasmI64Store, types.TypeMem)
-		v2.AuxInt = int64ToAuxInt(8)
-		v3 := b.NewValue0(v.Pos, OpWasmI64Load, typ.UInt64)
-		v3.AuxInt = int64ToAuxInt(8)
-		v3.AddArg2(src, mem)
-		v4 := b.NewValue0(v.Pos, OpWasmI64Store, types.TypeMem)
-		v5 := b.NewValue0(v.Pos, OpWasmI64Load, typ.UInt64)
-		v5.AddArg2(src, mem)
-		v4.AddArg3(dst, v5, mem)
-		v2.AddArg3(dst, v3, v4)
-		v.AddArg3(v0, v1, v2)
-		return true
-	}
-	// match: (Move [s] dst src mem)
-	// cond: s%8 == 0 && logLargeCopy(v, s)
-	// result: (LoweredMove [s/8] dst src mem)
-	for {
-		s := auxIntToInt64(v.AuxInt)
-		dst := v_0
-		src := v_1
-		mem := v_2
-		if !(s%8 == 0 && logLargeCopy(v, s)) {
+		if !(logLargeCopy(v, s)) {
 			break
 		}
 		v.reset(OpWasmLoweredMove)
-		v.AuxInt = int64ToAuxInt(s / 8)
+		v.AuxInt = int64ToAuxInt(s)
 		v.AddArg3(dst, src, mem)
 		return true
 	}
@@ -4656,13 +4598,13 @@
 		return true
 	}
 	// match: (Zero [s] destptr mem)
-	// cond: s%8 != 0 && s > 8
+	// cond: s%8 != 0 && s > 8 && s < 32
 	// result: (Zero [s-s%8] (OffPtr <destptr.Type> destptr [s%8]) (I64Store destptr (I64Const [0]) mem))
 	for {
 		s := auxIntToInt64(v.AuxInt)
 		destptr := v_0
 		mem := v_1
-		if !(s%8 != 0 && s > 8) {
+		if !(s%8 != 0 && s > 8 && s < 32) {
 			break
 		}
 		v.reset(OpZero)
@@ -4738,21 +4680,16 @@
 		return true
 	}
 	// match: (Zero [s] destptr mem)
-	// cond: s%8 == 0 && s > 32
-	// result: (LoweredZero [s/8] destptr mem)
+	// result: (LoweredZero [s] destptr mem)
 	for {
 		s := auxIntToInt64(v.AuxInt)
 		destptr := v_0
 		mem := v_1
-		if !(s%8 == 0 && s > 32) {
-			break
-		}
 		v.reset(OpWasmLoweredZero)
-		v.AuxInt = int64ToAuxInt(s / 8)
+		v.AuxInt = int64ToAuxInt(s)
 		v.AddArg2(destptr, mem)
 		return true
 	}
-	return false
 }
 func rewriteValueWasm_OpZeroExt16to32(v *Value) bool {
 	v_0 := v.Args[0]
diff --git a/src/cmd/compile/internal/ssa/rewritedec.go b/src/cmd/compile/internal/ssa/rewritedec.go
index 2a73a5d..1b92fb8 100644
--- a/src/cmd/compile/internal/ssa/rewritedec.go
+++ b/src/cmd/compile/internal/ssa/rewritedec.go
@@ -1,5 +1,5 @@
-// Code generated from gen/dec.rules; DO NOT EDIT.
-// generated with: cd gen; go run *.go
+// Code generated from _gen/dec.rules; DO NOT EDIT.
+// generated with: cd _gen; go run .
 
 package ssa
 
diff --git a/src/cmd/compile/internal/ssa/rewritedec64.go b/src/cmd/compile/internal/ssa/rewritedec64.go
index 7d9656a..26036b2 100644
--- a/src/cmd/compile/internal/ssa/rewritedec64.go
+++ b/src/cmd/compile/internal/ssa/rewritedec64.go
@@ -1,5 +1,5 @@
-// Code generated from gen/dec64.rules; DO NOT EDIT.
-// generated with: cd gen; go run *.go
+// Code generated from _gen/dec64.rules; DO NOT EDIT.
+// generated with: cd _gen; go run .
 
 package ssa
 
@@ -66,6 +66,14 @@
 		return rewriteValuedec64_OpOr32(v)
 	case OpOr64:
 		return rewriteValuedec64_OpOr64(v)
+	case OpRotateLeft16:
+		return rewriteValuedec64_OpRotateLeft16(v)
+	case OpRotateLeft32:
+		return rewriteValuedec64_OpRotateLeft32(v)
+	case OpRotateLeft64:
+		return rewriteValuedec64_OpRotateLeft64(v)
+	case OpRotateLeft8:
+		return rewriteValuedec64_OpRotateLeft8(v)
 	case OpRsh16Ux64:
 		return rewriteValuedec64_OpRsh16Ux64(v)
 	case OpRsh16x64:
@@ -1266,6 +1274,74 @@
 		return true
 	}
 }
+func rewriteValuedec64_OpRotateLeft16(v *Value) bool {
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	// match: (RotateLeft16 x (Int64Make hi lo))
+	// result: (RotateLeft16 x lo)
+	for {
+		x := v_0
+		if v_1.Op != OpInt64Make {
+			break
+		}
+		lo := v_1.Args[1]
+		v.reset(OpRotateLeft16)
+		v.AddArg2(x, lo)
+		return true
+	}
+	return false
+}
+func rewriteValuedec64_OpRotateLeft32(v *Value) bool {
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	// match: (RotateLeft32 x (Int64Make hi lo))
+	// result: (RotateLeft32 x lo)
+	for {
+		x := v_0
+		if v_1.Op != OpInt64Make {
+			break
+		}
+		lo := v_1.Args[1]
+		v.reset(OpRotateLeft32)
+		v.AddArg2(x, lo)
+		return true
+	}
+	return false
+}
+func rewriteValuedec64_OpRotateLeft64(v *Value) bool {
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	// match: (RotateLeft64 x (Int64Make hi lo))
+	// result: (RotateLeft64 x lo)
+	for {
+		x := v_0
+		if v_1.Op != OpInt64Make {
+			break
+		}
+		lo := v_1.Args[1]
+		v.reset(OpRotateLeft64)
+		v.AddArg2(x, lo)
+		return true
+	}
+	return false
+}
+func rewriteValuedec64_OpRotateLeft8(v *Value) bool {
+	v_1 := v.Args[1]
+	v_0 := v.Args[0]
+	// match: (RotateLeft8 x (Int64Make hi lo))
+	// result: (RotateLeft8 x lo)
+	for {
+		x := v_0
+		if v_1.Op != OpInt64Make {
+			break
+		}
+		lo := v_1.Args[1]
+		v.reset(OpRotateLeft8)
+		v.AddArg2(x, lo)
+		return true
+	}
+	return false
+}
 func rewriteValuedec64_OpRsh16Ux64(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
diff --git a/src/cmd/compile/internal/ssa/rewritegeneric.go b/src/cmd/compile/internal/ssa/rewritegeneric.go
index f61b6ca..f8c64e6 100644
--- a/src/cmd/compile/internal/ssa/rewritegeneric.go
+++ b/src/cmd/compile/internal/ssa/rewritegeneric.go
@@ -1,5 +1,5 @@
-// Code generated from gen/generic.rules; DO NOT EDIT.
-// generated with: cd gen; go run *.go
+// Code generated from _gen/generic.rules; DO NOT EDIT.
+// generated with: cd _gen; go run .
 
 package ssa
 
@@ -34,6 +34,8 @@
 		return rewriteValuegeneric_OpAndB(v)
 	case OpArraySelect:
 		return rewriteValuegeneric_OpArraySelect(v)
+	case OpCeil:
+		return rewriteValuegeneric_OpCeil(v)
 	case OpCom16:
 		return rewriteValuegeneric_OpCom16(v)
 	case OpCom32:
@@ -120,6 +122,8 @@
 		return rewriteValuegeneric_OpEqPtr(v)
 	case OpEqSlice:
 		return rewriteValuegeneric_OpEqSlice(v)
+	case OpFloor:
+		return rewriteValuegeneric_OpFloor(v)
 	case OpIMake:
 		return rewriteValuegeneric_OpIMake(v)
 	case OpInterLECall:
@@ -298,6 +302,8 @@
 		return rewriteValuegeneric_OpRound32F(v)
 	case OpRound64F:
 		return rewriteValuegeneric_OpRound64F(v)
+	case OpRoundToEven:
+		return rewriteValuegeneric_OpRoundToEven(v)
 	case OpRsh16Ux16:
 		return rewriteValuegeneric_OpRsh16Ux16(v)
 	case OpRsh16Ux32:
@@ -412,6 +418,8 @@
 		return rewriteValuegeneric_OpSub64F(v)
 	case OpSub8:
 		return rewriteValuegeneric_OpSub8(v)
+	case OpTrunc:
+		return rewriteValuegeneric_OpTrunc(v)
 	case OpTrunc16to8:
 		return rewriteValuegeneric_OpTrunc16to8(v)
 	case OpTrunc32to16:
@@ -453,6 +461,7 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
+	config := b.Func.Config
 	// match: (Add16 (Const16 [c]) (Const16 [d]))
 	// result: (Const16 [c+d])
 	for {
@@ -724,12 +733,321 @@
 		}
 		break
 	}
+	// match: (Add16 (Lsh16x64 x z:(Const64 <t> [c])) (Rsh16Ux64 x (Const64 [d])))
+	// cond: c < 16 && d == 16-c && canRotate(config, 16)
+	// result: (RotateLeft16 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			if v_0.Op != OpLsh16x64 {
+				continue
+			}
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			z := v_0.Args[1]
+			if z.Op != OpConst64 {
+				continue
+			}
+			c := auxIntToInt64(z.AuxInt)
+			if v_1.Op != OpRsh16Ux64 {
+				continue
+			}
+			_ = v_1.Args[1]
+			if x != v_1.Args[0] {
+				continue
+			}
+			v_1_1 := v_1.Args[1]
+			if v_1_1.Op != OpConst64 {
+				continue
+			}
+			d := auxIntToInt64(v_1_1.AuxInt)
+			if !(c < 16 && d == 16-c && canRotate(config, 16)) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Add16 left:(Lsh16x64 x y) right:(Rsh16Ux64 x (Sub64 (Const64 [16]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)
+	// result: (RotateLeft16 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh16x64 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh16Ux64 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub64 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst64 || auxIntToInt64(right_1_0.AuxInt) != 16 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Add16 left:(Lsh16x32 x y) right:(Rsh16Ux32 x (Sub32 (Const32 [16]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)
+	// result: (RotateLeft16 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh16x32 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh16Ux32 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub32 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst32 || auxIntToInt32(right_1_0.AuxInt) != 16 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Add16 left:(Lsh16x16 x y) right:(Rsh16Ux16 x (Sub16 (Const16 [16]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)
+	// result: (RotateLeft16 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh16x16 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh16Ux16 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub16 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst16 || auxIntToInt16(right_1_0.AuxInt) != 16 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Add16 left:(Lsh16x8 x y) right:(Rsh16Ux8 x (Sub8 (Const8 [16]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)
+	// result: (RotateLeft16 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh16x8 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh16Ux8 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub8 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst8 || auxIntToInt8(right_1_0.AuxInt) != 16 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Add16 right:(Rsh16Ux64 x y) left:(Lsh16x64 x z:(Sub64 (Const64 [16]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)
+	// result: (RotateLeft16 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh16Ux64 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh16x64 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub64 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst64 || auxIntToInt64(z_0.AuxInt) != 16 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Add16 right:(Rsh16Ux32 x y) left:(Lsh16x32 x z:(Sub32 (Const32 [16]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)
+	// result: (RotateLeft16 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh16Ux32 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh16x32 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub32 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst32 || auxIntToInt32(z_0.AuxInt) != 16 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Add16 right:(Rsh16Ux16 x y) left:(Lsh16x16 x z:(Sub16 (Const16 [16]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)
+	// result: (RotateLeft16 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh16Ux16 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh16x16 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub16 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst16 || auxIntToInt16(z_0.AuxInt) != 16 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Add16 right:(Rsh16Ux8 x y) left:(Lsh16x8 x z:(Sub8 (Const8 [16]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)
+	// result: (RotateLeft16 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh16Ux8 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh16x8 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub8 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst8 || auxIntToInt8(z_0.AuxInt) != 16 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
 	return false
 }
 func rewriteValuegeneric_OpAdd32(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
+	config := b.Func.Config
 	// match: (Add32 (Const32 [c]) (Const32 [d]))
 	// result: (Const32 [c+d])
 	for {
@@ -1001,6 +1319,314 @@
 		}
 		break
 	}
+	// match: (Add32 (Lsh32x64 x z:(Const64 <t> [c])) (Rsh32Ux64 x (Const64 [d])))
+	// cond: c < 32 && d == 32-c && canRotate(config, 32)
+	// result: (RotateLeft32 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			if v_0.Op != OpLsh32x64 {
+				continue
+			}
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			z := v_0.Args[1]
+			if z.Op != OpConst64 {
+				continue
+			}
+			c := auxIntToInt64(z.AuxInt)
+			if v_1.Op != OpRsh32Ux64 {
+				continue
+			}
+			_ = v_1.Args[1]
+			if x != v_1.Args[0] {
+				continue
+			}
+			v_1_1 := v_1.Args[1]
+			if v_1_1.Op != OpConst64 {
+				continue
+			}
+			d := auxIntToInt64(v_1_1.AuxInt)
+			if !(c < 32 && d == 32-c && canRotate(config, 32)) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Add32 left:(Lsh32x64 x y) right:(Rsh32Ux64 x (Sub64 (Const64 [32]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)
+	// result: (RotateLeft32 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh32x64 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh32Ux64 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub64 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst64 || auxIntToInt64(right_1_0.AuxInt) != 32 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Add32 left:(Lsh32x32 x y) right:(Rsh32Ux32 x (Sub32 (Const32 [32]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)
+	// result: (RotateLeft32 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh32x32 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh32Ux32 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub32 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst32 || auxIntToInt32(right_1_0.AuxInt) != 32 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Add32 left:(Lsh32x16 x y) right:(Rsh32Ux16 x (Sub16 (Const16 [32]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)
+	// result: (RotateLeft32 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh32x16 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh32Ux16 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub16 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst16 || auxIntToInt16(right_1_0.AuxInt) != 32 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Add32 left:(Lsh32x8 x y) right:(Rsh32Ux8 x (Sub8 (Const8 [32]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)
+	// result: (RotateLeft32 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh32x8 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh32Ux8 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub8 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst8 || auxIntToInt8(right_1_0.AuxInt) != 32 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Add32 right:(Rsh32Ux64 x y) left:(Lsh32x64 x z:(Sub64 (Const64 [32]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)
+	// result: (RotateLeft32 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh32Ux64 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh32x64 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub64 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst64 || auxIntToInt64(z_0.AuxInt) != 32 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Add32 right:(Rsh32Ux32 x y) left:(Lsh32x32 x z:(Sub32 (Const32 [32]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)
+	// result: (RotateLeft32 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh32Ux32 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh32x32 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub32 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst32 || auxIntToInt32(z_0.AuxInt) != 32 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Add32 right:(Rsh32Ux16 x y) left:(Lsh32x16 x z:(Sub16 (Const16 [32]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)
+	// result: (RotateLeft32 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh32Ux16 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh32x16 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub16 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst16 || auxIntToInt16(z_0.AuxInt) != 32 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Add32 right:(Rsh32Ux8 x y) left:(Lsh32x8 x z:(Sub8 (Const8 [32]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)
+	// result: (RotateLeft32 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh32Ux8 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh32x8 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub8 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst8 || auxIntToInt8(z_0.AuxInt) != 32 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
 	return false
 }
 func rewriteValuegeneric_OpAdd32F(v *Value) bool {
@@ -1034,6 +1660,7 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
+	config := b.Func.Config
 	// match: (Add64 (Const64 [c]) (Const64 [d]))
 	// result: (Const64 [c+d])
 	for {
@@ -1305,6 +1932,314 @@
 		}
 		break
 	}
+	// match: (Add64 (Lsh64x64 x z:(Const64 <t> [c])) (Rsh64Ux64 x (Const64 [d])))
+	// cond: c < 64 && d == 64-c && canRotate(config, 64)
+	// result: (RotateLeft64 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			if v_0.Op != OpLsh64x64 {
+				continue
+			}
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			z := v_0.Args[1]
+			if z.Op != OpConst64 {
+				continue
+			}
+			c := auxIntToInt64(z.AuxInt)
+			if v_1.Op != OpRsh64Ux64 {
+				continue
+			}
+			_ = v_1.Args[1]
+			if x != v_1.Args[0] {
+				continue
+			}
+			v_1_1 := v_1.Args[1]
+			if v_1_1.Op != OpConst64 {
+				continue
+			}
+			d := auxIntToInt64(v_1_1.AuxInt)
+			if !(c < 64 && d == 64-c && canRotate(config, 64)) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Add64 left:(Lsh64x64 x y) right:(Rsh64Ux64 x (Sub64 (Const64 [64]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)
+	// result: (RotateLeft64 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh64x64 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh64Ux64 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub64 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst64 || auxIntToInt64(right_1_0.AuxInt) != 64 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Add64 left:(Lsh64x32 x y) right:(Rsh64Ux32 x (Sub32 (Const32 [64]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)
+	// result: (RotateLeft64 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh64x32 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh64Ux32 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub32 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst32 || auxIntToInt32(right_1_0.AuxInt) != 64 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Add64 left:(Lsh64x16 x y) right:(Rsh64Ux16 x (Sub16 (Const16 [64]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)
+	// result: (RotateLeft64 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh64x16 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh64Ux16 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub16 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst16 || auxIntToInt16(right_1_0.AuxInt) != 64 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Add64 left:(Lsh64x8 x y) right:(Rsh64Ux8 x (Sub8 (Const8 [64]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)
+	// result: (RotateLeft64 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh64x8 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh64Ux8 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub8 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst8 || auxIntToInt8(right_1_0.AuxInt) != 64 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Add64 right:(Rsh64Ux64 x y) left:(Lsh64x64 x z:(Sub64 (Const64 [64]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)
+	// result: (RotateLeft64 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh64Ux64 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh64x64 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub64 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst64 || auxIntToInt64(z_0.AuxInt) != 64 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Add64 right:(Rsh64Ux32 x y) left:(Lsh64x32 x z:(Sub32 (Const32 [64]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)
+	// result: (RotateLeft64 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh64Ux32 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh64x32 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub32 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst32 || auxIntToInt32(z_0.AuxInt) != 64 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Add64 right:(Rsh64Ux16 x y) left:(Lsh64x16 x z:(Sub16 (Const16 [64]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)
+	// result: (RotateLeft64 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh64Ux16 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh64x16 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub16 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst16 || auxIntToInt16(z_0.AuxInt) != 64 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Add64 right:(Rsh64Ux8 x y) left:(Lsh64x8 x z:(Sub8 (Const8 [64]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)
+	// result: (RotateLeft64 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh64Ux8 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh64x8 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub8 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst8 || auxIntToInt8(z_0.AuxInt) != 64 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
 	return false
 }
 func rewriteValuegeneric_OpAdd64F(v *Value) bool {
@@ -1338,6 +2273,7 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
+	config := b.Func.Config
 	// match: (Add8 (Const8 [c]) (Const8 [d]))
 	// result: (Const8 [c+d])
 	for {
@@ -1609,6 +2545,314 @@
 		}
 		break
 	}
+	// match: (Add8 (Lsh8x64 x z:(Const64 <t> [c])) (Rsh8Ux64 x (Const64 [d])))
+	// cond: c < 8 && d == 8-c && canRotate(config, 8)
+	// result: (RotateLeft8 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			if v_0.Op != OpLsh8x64 {
+				continue
+			}
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			z := v_0.Args[1]
+			if z.Op != OpConst64 {
+				continue
+			}
+			c := auxIntToInt64(z.AuxInt)
+			if v_1.Op != OpRsh8Ux64 {
+				continue
+			}
+			_ = v_1.Args[1]
+			if x != v_1.Args[0] {
+				continue
+			}
+			v_1_1 := v_1.Args[1]
+			if v_1_1.Op != OpConst64 {
+				continue
+			}
+			d := auxIntToInt64(v_1_1.AuxInt)
+			if !(c < 8 && d == 8-c && canRotate(config, 8)) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Add8 left:(Lsh8x64 x y) right:(Rsh8Ux64 x (Sub64 (Const64 [8]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)
+	// result: (RotateLeft8 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh8x64 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh8Ux64 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub64 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst64 || auxIntToInt64(right_1_0.AuxInt) != 8 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Add8 left:(Lsh8x32 x y) right:(Rsh8Ux32 x (Sub32 (Const32 [8]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)
+	// result: (RotateLeft8 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh8x32 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh8Ux32 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub32 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst32 || auxIntToInt32(right_1_0.AuxInt) != 8 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Add8 left:(Lsh8x16 x y) right:(Rsh8Ux16 x (Sub16 (Const16 [8]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)
+	// result: (RotateLeft8 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh8x16 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh8Ux16 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub16 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst16 || auxIntToInt16(right_1_0.AuxInt) != 8 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Add8 left:(Lsh8x8 x y) right:(Rsh8Ux8 x (Sub8 (Const8 [8]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)
+	// result: (RotateLeft8 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh8x8 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh8Ux8 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub8 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst8 || auxIntToInt8(right_1_0.AuxInt) != 8 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Add8 right:(Rsh8Ux64 x y) left:(Lsh8x64 x z:(Sub64 (Const64 [8]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)
+	// result: (RotateLeft8 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh8Ux64 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh8x64 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub64 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst64 || auxIntToInt64(z_0.AuxInt) != 8 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Add8 right:(Rsh8Ux32 x y) left:(Lsh8x32 x z:(Sub32 (Const32 [8]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)
+	// result: (RotateLeft8 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh8Ux32 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh8x32 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub32 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst32 || auxIntToInt32(z_0.AuxInt) != 8 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Add8 right:(Rsh8Ux16 x y) left:(Lsh8x16 x z:(Sub16 (Const16 [8]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)
+	// result: (RotateLeft8 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh8Ux16 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh8x16 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub16 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst16 || auxIntToInt16(z_0.AuxInt) != 8 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Add8 right:(Rsh8Ux8 x y) left:(Lsh8x8 x z:(Sub8 (Const8 [8]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)
+	// result: (RotateLeft8 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh8Ux8 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh8x8 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub8 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst8 || auxIntToInt8(z_0.AuxInt) != 8 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
 	return false
 }
 func rewriteValuegeneric_OpAddPtr(v *Value) bool {
@@ -3849,6 +5093,21 @@
 	}
 	return false
 }
+func rewriteValuegeneric_OpCeil(v *Value) bool {
+	v_0 := v.Args[0]
+	// match: (Ceil (Const64F [c]))
+	// result: (Const64F [math.Ceil(c)])
+	for {
+		if v_0.Op != OpConst64F {
+			break
+		}
+		c := auxIntToFloat64(v_0.AuxInt)
+		v.reset(OpConst64F)
+		v.AuxInt = float64ToAuxInt(math.Ceil(c))
+		return true
+	}
+	return false
+}
 func rewriteValuegeneric_OpCom16(v *Value) bool {
 	v_0 := v.Args[0]
 	// match: (Com16 (Com16 x))
@@ -8909,6 +10168,21 @@
 		return true
 	}
 }
+func rewriteValuegeneric_OpFloor(v *Value) bool {
+	v_0 := v.Args[0]
+	// match: (Floor (Const64F [c]))
+	// result: (Const64F [math.Floor(c)])
+	for {
+		if v_0.Op != OpConst64F {
+			break
+		}
+		c := auxIntToFloat64(v_0.AuxInt)
+		v.reset(OpConst64F)
+		v.AuxInt = float64ToAuxInt(math.Floor(c))
+		return true
+	}
+	return false
+}
 func rewriteValuegeneric_OpIMake(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
@@ -11518,6 +12792,54 @@
 		v.AddArg2(x, v0)
 		return true
 	}
+	// match: (Lsh16x64 i:(Rsh16x64 x (Const64 [c])) (Const64 [c]))
+	// cond: c >= 0 && c < 16 && i.Uses == 1
+	// result: (And16 x (Const16 <v.Type> [int16(-1) << c]))
+	for {
+		i := v_0
+		if i.Op != OpRsh16x64 {
+			break
+		}
+		_ = i.Args[1]
+		x := i.Args[0]
+		i_1 := i.Args[1]
+		if i_1.Op != OpConst64 {
+			break
+		}
+		c := auxIntToInt64(i_1.AuxInt)
+		if v_1.Op != OpConst64 || auxIntToInt64(v_1.AuxInt) != c || !(c >= 0 && c < 16 && i.Uses == 1) {
+			break
+		}
+		v.reset(OpAnd16)
+		v0 := b.NewValue0(v.Pos, OpConst16, v.Type)
+		v0.AuxInt = int16ToAuxInt(int16(-1) << c)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (Lsh16x64 i:(Rsh16Ux64 x (Const64 [c])) (Const64 [c]))
+	// cond: c >= 0 && c < 16 && i.Uses == 1
+	// result: (And16 x (Const16 <v.Type> [int16(-1) << c]))
+	for {
+		i := v_0
+		if i.Op != OpRsh16Ux64 {
+			break
+		}
+		_ = i.Args[1]
+		x := i.Args[0]
+		i_1 := i.Args[1]
+		if i_1.Op != OpConst64 {
+			break
+		}
+		c := auxIntToInt64(i_1.AuxInt)
+		if v_1.Op != OpConst64 || auxIntToInt64(v_1.AuxInt) != c || !(c >= 0 && c < 16 && i.Uses == 1) {
+			break
+		}
+		v.reset(OpAnd16)
+		v0 := b.NewValue0(v.Pos, OpConst16, v.Type)
+		v0.AuxInt = int16ToAuxInt(int16(-1) << c)
+		v.AddArg2(x, v0)
+		return true
+	}
 	// match: (Lsh16x64 (Rsh16Ux64 (Lsh16x64 x (Const64 [c1])) (Const64 [c2])) (Const64 [c3]))
 	// cond: uint64(c1) >= uint64(c2) && uint64(c3) >= uint64(c2) && !uaddOvf(c1-c2, c3)
 	// result: (Lsh16x64 x (Const64 <typ.UInt64> [c1-c2+c3]))
@@ -11733,6 +13055,54 @@
 		v.AddArg2(x, v0)
 		return true
 	}
+	// match: (Lsh32x64 i:(Rsh32x64 x (Const64 [c])) (Const64 [c]))
+	// cond: c >= 0 && c < 32 && i.Uses == 1
+	// result: (And32 x (Const32 <v.Type> [int32(-1) << c]))
+	for {
+		i := v_0
+		if i.Op != OpRsh32x64 {
+			break
+		}
+		_ = i.Args[1]
+		x := i.Args[0]
+		i_1 := i.Args[1]
+		if i_1.Op != OpConst64 {
+			break
+		}
+		c := auxIntToInt64(i_1.AuxInt)
+		if v_1.Op != OpConst64 || auxIntToInt64(v_1.AuxInt) != c || !(c >= 0 && c < 32 && i.Uses == 1) {
+			break
+		}
+		v.reset(OpAnd32)
+		v0 := b.NewValue0(v.Pos, OpConst32, v.Type)
+		v0.AuxInt = int32ToAuxInt(int32(-1) << c)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (Lsh32x64 i:(Rsh32Ux64 x (Const64 [c])) (Const64 [c]))
+	// cond: c >= 0 && c < 32 && i.Uses == 1
+	// result: (And32 x (Const32 <v.Type> [int32(-1) << c]))
+	for {
+		i := v_0
+		if i.Op != OpRsh32Ux64 {
+			break
+		}
+		_ = i.Args[1]
+		x := i.Args[0]
+		i_1 := i.Args[1]
+		if i_1.Op != OpConst64 {
+			break
+		}
+		c := auxIntToInt64(i_1.AuxInt)
+		if v_1.Op != OpConst64 || auxIntToInt64(v_1.AuxInt) != c || !(c >= 0 && c < 32 && i.Uses == 1) {
+			break
+		}
+		v.reset(OpAnd32)
+		v0 := b.NewValue0(v.Pos, OpConst32, v.Type)
+		v0.AuxInt = int32ToAuxInt(int32(-1) << c)
+		v.AddArg2(x, v0)
+		return true
+	}
 	// match: (Lsh32x64 (Rsh32Ux64 (Lsh32x64 x (Const64 [c1])) (Const64 [c2])) (Const64 [c3]))
 	// cond: uint64(c1) >= uint64(c2) && uint64(c3) >= uint64(c2) && !uaddOvf(c1-c2, c3)
 	// result: (Lsh32x64 x (Const64 <typ.UInt64> [c1-c2+c3]))
@@ -11948,6 +13318,54 @@
 		v.AddArg2(x, v0)
 		return true
 	}
+	// match: (Lsh64x64 i:(Rsh64x64 x (Const64 [c])) (Const64 [c]))
+	// cond: c >= 0 && c < 64 && i.Uses == 1
+	// result: (And64 x (Const64 <v.Type> [int64(-1) << c]))
+	for {
+		i := v_0
+		if i.Op != OpRsh64x64 {
+			break
+		}
+		_ = i.Args[1]
+		x := i.Args[0]
+		i_1 := i.Args[1]
+		if i_1.Op != OpConst64 {
+			break
+		}
+		c := auxIntToInt64(i_1.AuxInt)
+		if v_1.Op != OpConst64 || auxIntToInt64(v_1.AuxInt) != c || !(c >= 0 && c < 64 && i.Uses == 1) {
+			break
+		}
+		v.reset(OpAnd64)
+		v0 := b.NewValue0(v.Pos, OpConst64, v.Type)
+		v0.AuxInt = int64ToAuxInt(int64(-1) << c)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (Lsh64x64 i:(Rsh64Ux64 x (Const64 [c])) (Const64 [c]))
+	// cond: c >= 0 && c < 64 && i.Uses == 1
+	// result: (And64 x (Const64 <v.Type> [int64(-1) << c]))
+	for {
+		i := v_0
+		if i.Op != OpRsh64Ux64 {
+			break
+		}
+		_ = i.Args[1]
+		x := i.Args[0]
+		i_1 := i.Args[1]
+		if i_1.Op != OpConst64 {
+			break
+		}
+		c := auxIntToInt64(i_1.AuxInt)
+		if v_1.Op != OpConst64 || auxIntToInt64(v_1.AuxInt) != c || !(c >= 0 && c < 64 && i.Uses == 1) {
+			break
+		}
+		v.reset(OpAnd64)
+		v0 := b.NewValue0(v.Pos, OpConst64, v.Type)
+		v0.AuxInt = int64ToAuxInt(int64(-1) << c)
+		v.AddArg2(x, v0)
+		return true
+	}
 	// match: (Lsh64x64 (Rsh64Ux64 (Lsh64x64 x (Const64 [c1])) (Const64 [c2])) (Const64 [c3]))
 	// cond: uint64(c1) >= uint64(c2) && uint64(c3) >= uint64(c2) && !uaddOvf(c1-c2, c3)
 	// result: (Lsh64x64 x (Const64 <typ.UInt64> [c1-c2+c3]))
@@ -12163,6 +13581,54 @@
 		v.AddArg2(x, v0)
 		return true
 	}
+	// match: (Lsh8x64 i:(Rsh8x64 x (Const64 [c])) (Const64 [c]))
+	// cond: c >= 0 && c < 8 && i.Uses == 1
+	// result: (And8 x (Const8 <v.Type> [int8(-1) << c]))
+	for {
+		i := v_0
+		if i.Op != OpRsh8x64 {
+			break
+		}
+		_ = i.Args[1]
+		x := i.Args[0]
+		i_1 := i.Args[1]
+		if i_1.Op != OpConst64 {
+			break
+		}
+		c := auxIntToInt64(i_1.AuxInt)
+		if v_1.Op != OpConst64 || auxIntToInt64(v_1.AuxInt) != c || !(c >= 0 && c < 8 && i.Uses == 1) {
+			break
+		}
+		v.reset(OpAnd8)
+		v0 := b.NewValue0(v.Pos, OpConst8, v.Type)
+		v0.AuxInt = int8ToAuxInt(int8(-1) << c)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (Lsh8x64 i:(Rsh8Ux64 x (Const64 [c])) (Const64 [c]))
+	// cond: c >= 0 && c < 8 && i.Uses == 1
+	// result: (And8 x (Const8 <v.Type> [int8(-1) << c]))
+	for {
+		i := v_0
+		if i.Op != OpRsh8Ux64 {
+			break
+		}
+		_ = i.Args[1]
+		x := i.Args[0]
+		i_1 := i.Args[1]
+		if i_1.Op != OpConst64 {
+			break
+		}
+		c := auxIntToInt64(i_1.AuxInt)
+		if v_1.Op != OpConst64 || auxIntToInt64(v_1.AuxInt) != c || !(c >= 0 && c < 8 && i.Uses == 1) {
+			break
+		}
+		v.reset(OpAnd8)
+		v0 := b.NewValue0(v.Pos, OpConst8, v.Type)
+		v0.AuxInt = int8ToAuxInt(int8(-1) << c)
+		v.AddArg2(x, v0)
+		return true
+	}
 	// match: (Lsh8x64 (Rsh8Ux64 (Lsh8x64 x (Const64 [c1])) (Const64 [c2])) (Const64 [c3]))
 	// cond: uint64(c1) >= uint64(c2) && uint64(c3) >= uint64(c2) && !uaddOvf(c1-c2, c3)
 	// result: (Lsh8x64 x (Const64 <typ.UInt64> [c1-c2+c3]))
@@ -17106,6 +18572,7 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
+	config := b.Func.Config
 	// match: (Or16 (Const16 [c]) (Const16 [d]))
 	// result: (Const16 [c|d])
 	for {
@@ -17295,12 +18762,321 @@
 		}
 		break
 	}
+	// match: (Or16 (Lsh16x64 x z:(Const64 <t> [c])) (Rsh16Ux64 x (Const64 [d])))
+	// cond: c < 16 && d == 16-c && canRotate(config, 16)
+	// result: (RotateLeft16 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			if v_0.Op != OpLsh16x64 {
+				continue
+			}
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			z := v_0.Args[1]
+			if z.Op != OpConst64 {
+				continue
+			}
+			c := auxIntToInt64(z.AuxInt)
+			if v_1.Op != OpRsh16Ux64 {
+				continue
+			}
+			_ = v_1.Args[1]
+			if x != v_1.Args[0] {
+				continue
+			}
+			v_1_1 := v_1.Args[1]
+			if v_1_1.Op != OpConst64 {
+				continue
+			}
+			d := auxIntToInt64(v_1_1.AuxInt)
+			if !(c < 16 && d == 16-c && canRotate(config, 16)) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Or16 left:(Lsh16x64 x y) right:(Rsh16Ux64 x (Sub64 (Const64 [16]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)
+	// result: (RotateLeft16 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh16x64 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh16Ux64 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub64 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst64 || auxIntToInt64(right_1_0.AuxInt) != 16 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Or16 left:(Lsh16x32 x y) right:(Rsh16Ux32 x (Sub32 (Const32 [16]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)
+	// result: (RotateLeft16 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh16x32 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh16Ux32 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub32 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst32 || auxIntToInt32(right_1_0.AuxInt) != 16 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Or16 left:(Lsh16x16 x y) right:(Rsh16Ux16 x (Sub16 (Const16 [16]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)
+	// result: (RotateLeft16 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh16x16 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh16Ux16 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub16 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst16 || auxIntToInt16(right_1_0.AuxInt) != 16 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Or16 left:(Lsh16x8 x y) right:(Rsh16Ux8 x (Sub8 (Const8 [16]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)
+	// result: (RotateLeft16 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh16x8 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh16Ux8 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub8 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst8 || auxIntToInt8(right_1_0.AuxInt) != 16 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Or16 right:(Rsh16Ux64 x y) left:(Lsh16x64 x z:(Sub64 (Const64 [16]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)
+	// result: (RotateLeft16 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh16Ux64 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh16x64 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub64 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst64 || auxIntToInt64(z_0.AuxInt) != 16 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Or16 right:(Rsh16Ux32 x y) left:(Lsh16x32 x z:(Sub32 (Const32 [16]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)
+	// result: (RotateLeft16 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh16Ux32 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh16x32 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub32 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst32 || auxIntToInt32(z_0.AuxInt) != 16 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Or16 right:(Rsh16Ux16 x y) left:(Lsh16x16 x z:(Sub16 (Const16 [16]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)
+	// result: (RotateLeft16 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh16Ux16 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh16x16 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub16 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst16 || auxIntToInt16(z_0.AuxInt) != 16 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Or16 right:(Rsh16Ux8 x y) left:(Lsh16x8 x z:(Sub8 (Const8 [16]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)
+	// result: (RotateLeft16 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh16Ux8 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh16x8 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub8 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst8 || auxIntToInt8(z_0.AuxInt) != 16 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
 	return false
 }
 func rewriteValuegeneric_OpOr32(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
+	config := b.Func.Config
 	// match: (Or32 (Const32 [c]) (Const32 [d]))
 	// result: (Const32 [c|d])
 	for {
@@ -17490,12 +19266,321 @@
 		}
 		break
 	}
+	// match: (Or32 (Lsh32x64 x z:(Const64 <t> [c])) (Rsh32Ux64 x (Const64 [d])))
+	// cond: c < 32 && d == 32-c && canRotate(config, 32)
+	// result: (RotateLeft32 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			if v_0.Op != OpLsh32x64 {
+				continue
+			}
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			z := v_0.Args[1]
+			if z.Op != OpConst64 {
+				continue
+			}
+			c := auxIntToInt64(z.AuxInt)
+			if v_1.Op != OpRsh32Ux64 {
+				continue
+			}
+			_ = v_1.Args[1]
+			if x != v_1.Args[0] {
+				continue
+			}
+			v_1_1 := v_1.Args[1]
+			if v_1_1.Op != OpConst64 {
+				continue
+			}
+			d := auxIntToInt64(v_1_1.AuxInt)
+			if !(c < 32 && d == 32-c && canRotate(config, 32)) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Or32 left:(Lsh32x64 x y) right:(Rsh32Ux64 x (Sub64 (Const64 [32]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)
+	// result: (RotateLeft32 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh32x64 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh32Ux64 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub64 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst64 || auxIntToInt64(right_1_0.AuxInt) != 32 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Or32 left:(Lsh32x32 x y) right:(Rsh32Ux32 x (Sub32 (Const32 [32]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)
+	// result: (RotateLeft32 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh32x32 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh32Ux32 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub32 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst32 || auxIntToInt32(right_1_0.AuxInt) != 32 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Or32 left:(Lsh32x16 x y) right:(Rsh32Ux16 x (Sub16 (Const16 [32]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)
+	// result: (RotateLeft32 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh32x16 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh32Ux16 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub16 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst16 || auxIntToInt16(right_1_0.AuxInt) != 32 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Or32 left:(Lsh32x8 x y) right:(Rsh32Ux8 x (Sub8 (Const8 [32]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)
+	// result: (RotateLeft32 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh32x8 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh32Ux8 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub8 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst8 || auxIntToInt8(right_1_0.AuxInt) != 32 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Or32 right:(Rsh32Ux64 x y) left:(Lsh32x64 x z:(Sub64 (Const64 [32]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)
+	// result: (RotateLeft32 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh32Ux64 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh32x64 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub64 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst64 || auxIntToInt64(z_0.AuxInt) != 32 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Or32 right:(Rsh32Ux32 x y) left:(Lsh32x32 x z:(Sub32 (Const32 [32]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)
+	// result: (RotateLeft32 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh32Ux32 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh32x32 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub32 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst32 || auxIntToInt32(z_0.AuxInt) != 32 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Or32 right:(Rsh32Ux16 x y) left:(Lsh32x16 x z:(Sub16 (Const16 [32]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)
+	// result: (RotateLeft32 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh32Ux16 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh32x16 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub16 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst16 || auxIntToInt16(z_0.AuxInt) != 32 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Or32 right:(Rsh32Ux8 x y) left:(Lsh32x8 x z:(Sub8 (Const8 [32]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)
+	// result: (RotateLeft32 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh32Ux8 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh32x8 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub8 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst8 || auxIntToInt8(z_0.AuxInt) != 32 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
 	return false
 }
 func rewriteValuegeneric_OpOr64(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
+	config := b.Func.Config
 	// match: (Or64 (Const64 [c]) (Const64 [d]))
 	// result: (Const64 [c|d])
 	for {
@@ -17685,12 +19770,321 @@
 		}
 		break
 	}
+	// match: (Or64 (Lsh64x64 x z:(Const64 <t> [c])) (Rsh64Ux64 x (Const64 [d])))
+	// cond: c < 64 && d == 64-c && canRotate(config, 64)
+	// result: (RotateLeft64 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			if v_0.Op != OpLsh64x64 {
+				continue
+			}
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			z := v_0.Args[1]
+			if z.Op != OpConst64 {
+				continue
+			}
+			c := auxIntToInt64(z.AuxInt)
+			if v_1.Op != OpRsh64Ux64 {
+				continue
+			}
+			_ = v_1.Args[1]
+			if x != v_1.Args[0] {
+				continue
+			}
+			v_1_1 := v_1.Args[1]
+			if v_1_1.Op != OpConst64 {
+				continue
+			}
+			d := auxIntToInt64(v_1_1.AuxInt)
+			if !(c < 64 && d == 64-c && canRotate(config, 64)) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Or64 left:(Lsh64x64 x y) right:(Rsh64Ux64 x (Sub64 (Const64 [64]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)
+	// result: (RotateLeft64 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh64x64 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh64Ux64 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub64 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst64 || auxIntToInt64(right_1_0.AuxInt) != 64 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Or64 left:(Lsh64x32 x y) right:(Rsh64Ux32 x (Sub32 (Const32 [64]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)
+	// result: (RotateLeft64 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh64x32 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh64Ux32 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub32 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst32 || auxIntToInt32(right_1_0.AuxInt) != 64 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Or64 left:(Lsh64x16 x y) right:(Rsh64Ux16 x (Sub16 (Const16 [64]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)
+	// result: (RotateLeft64 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh64x16 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh64Ux16 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub16 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst16 || auxIntToInt16(right_1_0.AuxInt) != 64 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Or64 left:(Lsh64x8 x y) right:(Rsh64Ux8 x (Sub8 (Const8 [64]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)
+	// result: (RotateLeft64 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh64x8 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh64Ux8 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub8 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst8 || auxIntToInt8(right_1_0.AuxInt) != 64 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Or64 right:(Rsh64Ux64 x y) left:(Lsh64x64 x z:(Sub64 (Const64 [64]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)
+	// result: (RotateLeft64 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh64Ux64 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh64x64 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub64 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst64 || auxIntToInt64(z_0.AuxInt) != 64 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Or64 right:(Rsh64Ux32 x y) left:(Lsh64x32 x z:(Sub32 (Const32 [64]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)
+	// result: (RotateLeft64 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh64Ux32 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh64x32 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub32 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst32 || auxIntToInt32(z_0.AuxInt) != 64 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Or64 right:(Rsh64Ux16 x y) left:(Lsh64x16 x z:(Sub16 (Const16 [64]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)
+	// result: (RotateLeft64 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh64Ux16 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh64x16 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub16 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst16 || auxIntToInt16(z_0.AuxInt) != 64 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Or64 right:(Rsh64Ux8 x y) left:(Lsh64x8 x z:(Sub8 (Const8 [64]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)
+	// result: (RotateLeft64 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh64Ux8 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh64x8 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub8 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst8 || auxIntToInt8(z_0.AuxInt) != 64 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
 	return false
 }
 func rewriteValuegeneric_OpOr8(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
+	config := b.Func.Config
 	// match: (Or8 (Const8 [c]) (Const8 [d]))
 	// result: (Const8 [c|d])
 	for {
@@ -17880,6 +20274,314 @@
 		}
 		break
 	}
+	// match: (Or8 (Lsh8x64 x z:(Const64 <t> [c])) (Rsh8Ux64 x (Const64 [d])))
+	// cond: c < 8 && d == 8-c && canRotate(config, 8)
+	// result: (RotateLeft8 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			if v_0.Op != OpLsh8x64 {
+				continue
+			}
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			z := v_0.Args[1]
+			if z.Op != OpConst64 {
+				continue
+			}
+			c := auxIntToInt64(z.AuxInt)
+			if v_1.Op != OpRsh8Ux64 {
+				continue
+			}
+			_ = v_1.Args[1]
+			if x != v_1.Args[0] {
+				continue
+			}
+			v_1_1 := v_1.Args[1]
+			if v_1_1.Op != OpConst64 {
+				continue
+			}
+			d := auxIntToInt64(v_1_1.AuxInt)
+			if !(c < 8 && d == 8-c && canRotate(config, 8)) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Or8 left:(Lsh8x64 x y) right:(Rsh8Ux64 x (Sub64 (Const64 [8]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)
+	// result: (RotateLeft8 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh8x64 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh8Ux64 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub64 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst64 || auxIntToInt64(right_1_0.AuxInt) != 8 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Or8 left:(Lsh8x32 x y) right:(Rsh8Ux32 x (Sub32 (Const32 [8]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)
+	// result: (RotateLeft8 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh8x32 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh8Ux32 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub32 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst32 || auxIntToInt32(right_1_0.AuxInt) != 8 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Or8 left:(Lsh8x16 x y) right:(Rsh8Ux16 x (Sub16 (Const16 [8]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)
+	// result: (RotateLeft8 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh8x16 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh8Ux16 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub16 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst16 || auxIntToInt16(right_1_0.AuxInt) != 8 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Or8 left:(Lsh8x8 x y) right:(Rsh8Ux8 x (Sub8 (Const8 [8]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)
+	// result: (RotateLeft8 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh8x8 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh8Ux8 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub8 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst8 || auxIntToInt8(right_1_0.AuxInt) != 8 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Or8 right:(Rsh8Ux64 x y) left:(Lsh8x64 x z:(Sub64 (Const64 [8]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)
+	// result: (RotateLeft8 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh8Ux64 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh8x64 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub64 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst64 || auxIntToInt64(z_0.AuxInt) != 8 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Or8 right:(Rsh8Ux32 x y) left:(Lsh8x32 x z:(Sub32 (Const32 [8]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)
+	// result: (RotateLeft8 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh8Ux32 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh8x32 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub32 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst32 || auxIntToInt32(z_0.AuxInt) != 8 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Or8 right:(Rsh8Ux16 x y) left:(Lsh8x16 x z:(Sub16 (Const16 [8]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)
+	// result: (RotateLeft8 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh8Ux16 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh8x16 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub16 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst16 || auxIntToInt16(z_0.AuxInt) != 8 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Or8 right:(Rsh8Ux8 x y) left:(Lsh8x8 x z:(Sub8 (Const8 [8]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)
+	// result: (RotateLeft8 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh8Ux8 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh8x8 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub8 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst8 || auxIntToInt8(z_0.AuxInt) != 8 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
 	return false
 }
 func rewriteValuegeneric_OpOrB(v *Value) bool {
@@ -19201,6 +21903,7 @@
 	return false
 }
 func rewriteValuegeneric_OpPhi(v *Value) bool {
+	b := v.Block
 	// match: (Phi (Const8 [c]) (Const8 [c]))
 	// result: (Const8 [c])
 	for {
@@ -19281,6 +21984,34 @@
 		v.AuxInt = int64ToAuxInt(c)
 		return true
 	}
+	// match: (Phi <t> nx:(Not x) ny:(Not y))
+	// cond: nx.Uses == 1 && ny.Uses == 1
+	// result: (Not (Phi <t> x y))
+	for {
+		if len(v.Args) != 2 {
+			break
+		}
+		t := v.Type
+		_ = v.Args[1]
+		nx := v.Args[0]
+		if nx.Op != OpNot {
+			break
+		}
+		x := nx.Args[0]
+		ny := v.Args[1]
+		if ny.Op != OpNot {
+			break
+		}
+		y := ny.Args[0]
+		if !(nx.Uses == 1 && ny.Uses == 1) {
+			break
+		}
+		v.reset(OpNot)
+		v0 := b.NewValue0(v.Pos, OpPhi, t)
+		v0.AddArg2(x, y)
+		v.AddArg(v0)
+		return true
+	}
 	return false
 }
 func rewriteValuegeneric_OpPtrIndex(v *Value) bool {
@@ -19330,6 +22061,8 @@
 func rewriteValuegeneric_OpRotateLeft16(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
+	b := v.Block
+	config := b.Func.Config
 	// match: (RotateLeft16 x (Const16 [c]))
 	// cond: c%16 == 0
 	// result: x
@@ -19345,11 +22078,536 @@
 		v.copyOf(x)
 		return true
 	}
+	// match: (RotateLeft16 x (And64 y (Const64 [c])))
+	// cond: c&15 == 15
+	// result: (RotateLeft16 x y)
+	for {
+		x := v_0
+		if v_1.Op != OpAnd64 {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+			y := v_1_0
+			if v_1_1.Op != OpConst64 {
+				continue
+			}
+			c := auxIntToInt64(v_1_1.AuxInt)
+			if !(c&15 == 15) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft16 x (And32 y (Const32 [c])))
+	// cond: c&15 == 15
+	// result: (RotateLeft16 x y)
+	for {
+		x := v_0
+		if v_1.Op != OpAnd32 {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+			y := v_1_0
+			if v_1_1.Op != OpConst32 {
+				continue
+			}
+			c := auxIntToInt32(v_1_1.AuxInt)
+			if !(c&15 == 15) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft16 x (And16 y (Const16 [c])))
+	// cond: c&15 == 15
+	// result: (RotateLeft16 x y)
+	for {
+		x := v_0
+		if v_1.Op != OpAnd16 {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+			y := v_1_0
+			if v_1_1.Op != OpConst16 {
+				continue
+			}
+			c := auxIntToInt16(v_1_1.AuxInt)
+			if !(c&15 == 15) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft16 x (And8 y (Const8 [c])))
+	// cond: c&15 == 15
+	// result: (RotateLeft16 x y)
+	for {
+		x := v_0
+		if v_1.Op != OpAnd8 {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+			y := v_1_0
+			if v_1_1.Op != OpConst8 {
+				continue
+			}
+			c := auxIntToInt8(v_1_1.AuxInt)
+			if !(c&15 == 15) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft16 x (Neg64 (And64 y (Const64 [c]))))
+	// cond: c&15 == 15
+	// result: (RotateLeft16 x (Neg64 <y.Type> y))
+	for {
+		x := v_0
+		if v_1.Op != OpNeg64 {
+			break
+		}
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpAnd64 {
+			break
+		}
+		_ = v_1_0.Args[1]
+		v_1_0_0 := v_1_0.Args[0]
+		v_1_0_1 := v_1_0.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0_0, v_1_0_1 = _i0+1, v_1_0_1, v_1_0_0 {
+			y := v_1_0_0
+			if v_1_0_1.Op != OpConst64 {
+				continue
+			}
+			c := auxIntToInt64(v_1_0_1.AuxInt)
+			if !(c&15 == 15) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v0 := b.NewValue0(v.Pos, OpNeg64, y.Type)
+			v0.AddArg(y)
+			v.AddArg2(x, v0)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft16 x (Neg32 (And32 y (Const32 [c]))))
+	// cond: c&15 == 15
+	// result: (RotateLeft16 x (Neg32 <y.Type> y))
+	for {
+		x := v_0
+		if v_1.Op != OpNeg32 {
+			break
+		}
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpAnd32 {
+			break
+		}
+		_ = v_1_0.Args[1]
+		v_1_0_0 := v_1_0.Args[0]
+		v_1_0_1 := v_1_0.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0_0, v_1_0_1 = _i0+1, v_1_0_1, v_1_0_0 {
+			y := v_1_0_0
+			if v_1_0_1.Op != OpConst32 {
+				continue
+			}
+			c := auxIntToInt32(v_1_0_1.AuxInt)
+			if !(c&15 == 15) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v0 := b.NewValue0(v.Pos, OpNeg32, y.Type)
+			v0.AddArg(y)
+			v.AddArg2(x, v0)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft16 x (Neg16 (And16 y (Const16 [c]))))
+	// cond: c&15 == 15
+	// result: (RotateLeft16 x (Neg16 <y.Type> y))
+	for {
+		x := v_0
+		if v_1.Op != OpNeg16 {
+			break
+		}
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpAnd16 {
+			break
+		}
+		_ = v_1_0.Args[1]
+		v_1_0_0 := v_1_0.Args[0]
+		v_1_0_1 := v_1_0.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0_0, v_1_0_1 = _i0+1, v_1_0_1, v_1_0_0 {
+			y := v_1_0_0
+			if v_1_0_1.Op != OpConst16 {
+				continue
+			}
+			c := auxIntToInt16(v_1_0_1.AuxInt)
+			if !(c&15 == 15) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v0 := b.NewValue0(v.Pos, OpNeg16, y.Type)
+			v0.AddArg(y)
+			v.AddArg2(x, v0)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft16 x (Neg8 (And8 y (Const8 [c]))))
+	// cond: c&15 == 15
+	// result: (RotateLeft16 x (Neg8 <y.Type> y))
+	for {
+		x := v_0
+		if v_1.Op != OpNeg8 {
+			break
+		}
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpAnd8 {
+			break
+		}
+		_ = v_1_0.Args[1]
+		v_1_0_0 := v_1_0.Args[0]
+		v_1_0_1 := v_1_0.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0_0, v_1_0_1 = _i0+1, v_1_0_1, v_1_0_0 {
+			y := v_1_0_0
+			if v_1_0_1.Op != OpConst8 {
+				continue
+			}
+			c := auxIntToInt8(v_1_0_1.AuxInt)
+			if !(c&15 == 15) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v0 := b.NewValue0(v.Pos, OpNeg8, y.Type)
+			v0.AddArg(y)
+			v.AddArg2(x, v0)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft16 x (Add64 y (Const64 [c])))
+	// cond: c&15 == 0
+	// result: (RotateLeft16 x y)
+	for {
+		x := v_0
+		if v_1.Op != OpAdd64 {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+			y := v_1_0
+			if v_1_1.Op != OpConst64 {
+				continue
+			}
+			c := auxIntToInt64(v_1_1.AuxInt)
+			if !(c&15 == 0) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft16 x (Add32 y (Const32 [c])))
+	// cond: c&15 == 0
+	// result: (RotateLeft16 x y)
+	for {
+		x := v_0
+		if v_1.Op != OpAdd32 {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+			y := v_1_0
+			if v_1_1.Op != OpConst32 {
+				continue
+			}
+			c := auxIntToInt32(v_1_1.AuxInt)
+			if !(c&15 == 0) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft16 x (Add16 y (Const16 [c])))
+	// cond: c&15 == 0
+	// result: (RotateLeft16 x y)
+	for {
+		x := v_0
+		if v_1.Op != OpAdd16 {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+			y := v_1_0
+			if v_1_1.Op != OpConst16 {
+				continue
+			}
+			c := auxIntToInt16(v_1_1.AuxInt)
+			if !(c&15 == 0) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft16 x (Add8 y (Const8 [c])))
+	// cond: c&15 == 0
+	// result: (RotateLeft16 x y)
+	for {
+		x := v_0
+		if v_1.Op != OpAdd8 {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+			y := v_1_0
+			if v_1_1.Op != OpConst8 {
+				continue
+			}
+			c := auxIntToInt8(v_1_1.AuxInt)
+			if !(c&15 == 0) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft16 x (Sub64 (Const64 [c]) y))
+	// cond: c&15 == 0
+	// result: (RotateLeft16 x (Neg64 <y.Type> y))
+	for {
+		x := v_0
+		if v_1.Op != OpSub64 {
+			break
+		}
+		y := v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpConst64 {
+			break
+		}
+		c := auxIntToInt64(v_1_0.AuxInt)
+		if !(c&15 == 0) {
+			break
+		}
+		v.reset(OpRotateLeft16)
+		v0 := b.NewValue0(v.Pos, OpNeg64, y.Type)
+		v0.AddArg(y)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (RotateLeft16 x (Sub32 (Const32 [c]) y))
+	// cond: c&15 == 0
+	// result: (RotateLeft16 x (Neg32 <y.Type> y))
+	for {
+		x := v_0
+		if v_1.Op != OpSub32 {
+			break
+		}
+		y := v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpConst32 {
+			break
+		}
+		c := auxIntToInt32(v_1_0.AuxInt)
+		if !(c&15 == 0) {
+			break
+		}
+		v.reset(OpRotateLeft16)
+		v0 := b.NewValue0(v.Pos, OpNeg32, y.Type)
+		v0.AddArg(y)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (RotateLeft16 x (Sub16 (Const16 [c]) y))
+	// cond: c&15 == 0
+	// result: (RotateLeft16 x (Neg16 <y.Type> y))
+	for {
+		x := v_0
+		if v_1.Op != OpSub16 {
+			break
+		}
+		y := v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpConst16 {
+			break
+		}
+		c := auxIntToInt16(v_1_0.AuxInt)
+		if !(c&15 == 0) {
+			break
+		}
+		v.reset(OpRotateLeft16)
+		v0 := b.NewValue0(v.Pos, OpNeg16, y.Type)
+		v0.AddArg(y)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (RotateLeft16 x (Sub8 (Const8 [c]) y))
+	// cond: c&15 == 0
+	// result: (RotateLeft16 x (Neg8 <y.Type> y))
+	for {
+		x := v_0
+		if v_1.Op != OpSub8 {
+			break
+		}
+		y := v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpConst8 {
+			break
+		}
+		c := auxIntToInt8(v_1_0.AuxInt)
+		if !(c&15 == 0) {
+			break
+		}
+		v.reset(OpRotateLeft16)
+		v0 := b.NewValue0(v.Pos, OpNeg8, y.Type)
+		v0.AddArg(y)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (RotateLeft16 x (Const64 <t> [c]))
+	// cond: config.PtrSize == 4
+	// result: (RotateLeft16 x (Const32 <t> [int32(c)]))
+	for {
+		x := v_0
+		if v_1.Op != OpConst64 {
+			break
+		}
+		t := v_1.Type
+		c := auxIntToInt64(v_1.AuxInt)
+		if !(config.PtrSize == 4) {
+			break
+		}
+		v.reset(OpRotateLeft16)
+		v0 := b.NewValue0(v.Pos, OpConst32, t)
+		v0.AuxInt = int32ToAuxInt(int32(c))
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (RotateLeft16 (RotateLeft16 x c) d)
+	// cond: c.Type.Size() == 8 && d.Type.Size() == 8
+	// result: (RotateLeft16 x (Add64 <c.Type> c d))
+	for {
+		if v_0.Op != OpRotateLeft16 {
+			break
+		}
+		c := v_0.Args[1]
+		x := v_0.Args[0]
+		d := v_1
+		if !(c.Type.Size() == 8 && d.Type.Size() == 8) {
+			break
+		}
+		v.reset(OpRotateLeft16)
+		v0 := b.NewValue0(v.Pos, OpAdd64, c.Type)
+		v0.AddArg2(c, d)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (RotateLeft16 (RotateLeft16 x c) d)
+	// cond: c.Type.Size() == 4 && d.Type.Size() == 4
+	// result: (RotateLeft16 x (Add32 <c.Type> c d))
+	for {
+		if v_0.Op != OpRotateLeft16 {
+			break
+		}
+		c := v_0.Args[1]
+		x := v_0.Args[0]
+		d := v_1
+		if !(c.Type.Size() == 4 && d.Type.Size() == 4) {
+			break
+		}
+		v.reset(OpRotateLeft16)
+		v0 := b.NewValue0(v.Pos, OpAdd32, c.Type)
+		v0.AddArg2(c, d)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (RotateLeft16 (RotateLeft16 x c) d)
+	// cond: c.Type.Size() == 2 && d.Type.Size() == 2
+	// result: (RotateLeft16 x (Add16 <c.Type> c d))
+	for {
+		if v_0.Op != OpRotateLeft16 {
+			break
+		}
+		c := v_0.Args[1]
+		x := v_0.Args[0]
+		d := v_1
+		if !(c.Type.Size() == 2 && d.Type.Size() == 2) {
+			break
+		}
+		v.reset(OpRotateLeft16)
+		v0 := b.NewValue0(v.Pos, OpAdd16, c.Type)
+		v0.AddArg2(c, d)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (RotateLeft16 (RotateLeft16 x c) d)
+	// cond: c.Type.Size() == 1 && d.Type.Size() == 1
+	// result: (RotateLeft16 x (Add8 <c.Type> c d))
+	for {
+		if v_0.Op != OpRotateLeft16 {
+			break
+		}
+		c := v_0.Args[1]
+		x := v_0.Args[0]
+		d := v_1
+		if !(c.Type.Size() == 1 && d.Type.Size() == 1) {
+			break
+		}
+		v.reset(OpRotateLeft16)
+		v0 := b.NewValue0(v.Pos, OpAdd8, c.Type)
+		v0.AddArg2(c, d)
+		v.AddArg2(x, v0)
+		return true
+	}
 	return false
 }
 func rewriteValuegeneric_OpRotateLeft32(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
+	b := v.Block
+	config := b.Func.Config
 	// match: (RotateLeft32 x (Const32 [c]))
 	// cond: c%32 == 0
 	// result: x
@@ -19365,11 +22623,536 @@
 		v.copyOf(x)
 		return true
 	}
+	// match: (RotateLeft32 x (And64 y (Const64 [c])))
+	// cond: c&31 == 31
+	// result: (RotateLeft32 x y)
+	for {
+		x := v_0
+		if v_1.Op != OpAnd64 {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+			y := v_1_0
+			if v_1_1.Op != OpConst64 {
+				continue
+			}
+			c := auxIntToInt64(v_1_1.AuxInt)
+			if !(c&31 == 31) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft32 x (And32 y (Const32 [c])))
+	// cond: c&31 == 31
+	// result: (RotateLeft32 x y)
+	for {
+		x := v_0
+		if v_1.Op != OpAnd32 {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+			y := v_1_0
+			if v_1_1.Op != OpConst32 {
+				continue
+			}
+			c := auxIntToInt32(v_1_1.AuxInt)
+			if !(c&31 == 31) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft32 x (And16 y (Const16 [c])))
+	// cond: c&31 == 31
+	// result: (RotateLeft32 x y)
+	for {
+		x := v_0
+		if v_1.Op != OpAnd16 {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+			y := v_1_0
+			if v_1_1.Op != OpConst16 {
+				continue
+			}
+			c := auxIntToInt16(v_1_1.AuxInt)
+			if !(c&31 == 31) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft32 x (And8 y (Const8 [c])))
+	// cond: c&31 == 31
+	// result: (RotateLeft32 x y)
+	for {
+		x := v_0
+		if v_1.Op != OpAnd8 {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+			y := v_1_0
+			if v_1_1.Op != OpConst8 {
+				continue
+			}
+			c := auxIntToInt8(v_1_1.AuxInt)
+			if !(c&31 == 31) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft32 x (Neg64 (And64 y (Const64 [c]))))
+	// cond: c&31 == 31
+	// result: (RotateLeft32 x (Neg64 <y.Type> y))
+	for {
+		x := v_0
+		if v_1.Op != OpNeg64 {
+			break
+		}
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpAnd64 {
+			break
+		}
+		_ = v_1_0.Args[1]
+		v_1_0_0 := v_1_0.Args[0]
+		v_1_0_1 := v_1_0.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0_0, v_1_0_1 = _i0+1, v_1_0_1, v_1_0_0 {
+			y := v_1_0_0
+			if v_1_0_1.Op != OpConst64 {
+				continue
+			}
+			c := auxIntToInt64(v_1_0_1.AuxInt)
+			if !(c&31 == 31) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v0 := b.NewValue0(v.Pos, OpNeg64, y.Type)
+			v0.AddArg(y)
+			v.AddArg2(x, v0)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft32 x (Neg32 (And32 y (Const32 [c]))))
+	// cond: c&31 == 31
+	// result: (RotateLeft32 x (Neg32 <y.Type> y))
+	for {
+		x := v_0
+		if v_1.Op != OpNeg32 {
+			break
+		}
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpAnd32 {
+			break
+		}
+		_ = v_1_0.Args[1]
+		v_1_0_0 := v_1_0.Args[0]
+		v_1_0_1 := v_1_0.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0_0, v_1_0_1 = _i0+1, v_1_0_1, v_1_0_0 {
+			y := v_1_0_0
+			if v_1_0_1.Op != OpConst32 {
+				continue
+			}
+			c := auxIntToInt32(v_1_0_1.AuxInt)
+			if !(c&31 == 31) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v0 := b.NewValue0(v.Pos, OpNeg32, y.Type)
+			v0.AddArg(y)
+			v.AddArg2(x, v0)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft32 x (Neg16 (And16 y (Const16 [c]))))
+	// cond: c&31 == 31
+	// result: (RotateLeft32 x (Neg16 <y.Type> y))
+	for {
+		x := v_0
+		if v_1.Op != OpNeg16 {
+			break
+		}
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpAnd16 {
+			break
+		}
+		_ = v_1_0.Args[1]
+		v_1_0_0 := v_1_0.Args[0]
+		v_1_0_1 := v_1_0.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0_0, v_1_0_1 = _i0+1, v_1_0_1, v_1_0_0 {
+			y := v_1_0_0
+			if v_1_0_1.Op != OpConst16 {
+				continue
+			}
+			c := auxIntToInt16(v_1_0_1.AuxInt)
+			if !(c&31 == 31) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v0 := b.NewValue0(v.Pos, OpNeg16, y.Type)
+			v0.AddArg(y)
+			v.AddArg2(x, v0)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft32 x (Neg8 (And8 y (Const8 [c]))))
+	// cond: c&31 == 31
+	// result: (RotateLeft32 x (Neg8 <y.Type> y))
+	for {
+		x := v_0
+		if v_1.Op != OpNeg8 {
+			break
+		}
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpAnd8 {
+			break
+		}
+		_ = v_1_0.Args[1]
+		v_1_0_0 := v_1_0.Args[0]
+		v_1_0_1 := v_1_0.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0_0, v_1_0_1 = _i0+1, v_1_0_1, v_1_0_0 {
+			y := v_1_0_0
+			if v_1_0_1.Op != OpConst8 {
+				continue
+			}
+			c := auxIntToInt8(v_1_0_1.AuxInt)
+			if !(c&31 == 31) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v0 := b.NewValue0(v.Pos, OpNeg8, y.Type)
+			v0.AddArg(y)
+			v.AddArg2(x, v0)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft32 x (Add64 y (Const64 [c])))
+	// cond: c&31 == 0
+	// result: (RotateLeft32 x y)
+	for {
+		x := v_0
+		if v_1.Op != OpAdd64 {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+			y := v_1_0
+			if v_1_1.Op != OpConst64 {
+				continue
+			}
+			c := auxIntToInt64(v_1_1.AuxInt)
+			if !(c&31 == 0) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft32 x (Add32 y (Const32 [c])))
+	// cond: c&31 == 0
+	// result: (RotateLeft32 x y)
+	for {
+		x := v_0
+		if v_1.Op != OpAdd32 {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+			y := v_1_0
+			if v_1_1.Op != OpConst32 {
+				continue
+			}
+			c := auxIntToInt32(v_1_1.AuxInt)
+			if !(c&31 == 0) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft32 x (Add16 y (Const16 [c])))
+	// cond: c&31 == 0
+	// result: (RotateLeft32 x y)
+	for {
+		x := v_0
+		if v_1.Op != OpAdd16 {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+			y := v_1_0
+			if v_1_1.Op != OpConst16 {
+				continue
+			}
+			c := auxIntToInt16(v_1_1.AuxInt)
+			if !(c&31 == 0) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft32 x (Add8 y (Const8 [c])))
+	// cond: c&31 == 0
+	// result: (RotateLeft32 x y)
+	for {
+		x := v_0
+		if v_1.Op != OpAdd8 {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+			y := v_1_0
+			if v_1_1.Op != OpConst8 {
+				continue
+			}
+			c := auxIntToInt8(v_1_1.AuxInt)
+			if !(c&31 == 0) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft32 x (Sub64 (Const64 [c]) y))
+	// cond: c&31 == 0
+	// result: (RotateLeft32 x (Neg64 <y.Type> y))
+	for {
+		x := v_0
+		if v_1.Op != OpSub64 {
+			break
+		}
+		y := v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpConst64 {
+			break
+		}
+		c := auxIntToInt64(v_1_0.AuxInt)
+		if !(c&31 == 0) {
+			break
+		}
+		v.reset(OpRotateLeft32)
+		v0 := b.NewValue0(v.Pos, OpNeg64, y.Type)
+		v0.AddArg(y)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (RotateLeft32 x (Sub32 (Const32 [c]) y))
+	// cond: c&31 == 0
+	// result: (RotateLeft32 x (Neg32 <y.Type> y))
+	for {
+		x := v_0
+		if v_1.Op != OpSub32 {
+			break
+		}
+		y := v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpConst32 {
+			break
+		}
+		c := auxIntToInt32(v_1_0.AuxInt)
+		if !(c&31 == 0) {
+			break
+		}
+		v.reset(OpRotateLeft32)
+		v0 := b.NewValue0(v.Pos, OpNeg32, y.Type)
+		v0.AddArg(y)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (RotateLeft32 x (Sub16 (Const16 [c]) y))
+	// cond: c&31 == 0
+	// result: (RotateLeft32 x (Neg16 <y.Type> y))
+	for {
+		x := v_0
+		if v_1.Op != OpSub16 {
+			break
+		}
+		y := v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpConst16 {
+			break
+		}
+		c := auxIntToInt16(v_1_0.AuxInt)
+		if !(c&31 == 0) {
+			break
+		}
+		v.reset(OpRotateLeft32)
+		v0 := b.NewValue0(v.Pos, OpNeg16, y.Type)
+		v0.AddArg(y)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (RotateLeft32 x (Sub8 (Const8 [c]) y))
+	// cond: c&31 == 0
+	// result: (RotateLeft32 x (Neg8 <y.Type> y))
+	for {
+		x := v_0
+		if v_1.Op != OpSub8 {
+			break
+		}
+		y := v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpConst8 {
+			break
+		}
+		c := auxIntToInt8(v_1_0.AuxInt)
+		if !(c&31 == 0) {
+			break
+		}
+		v.reset(OpRotateLeft32)
+		v0 := b.NewValue0(v.Pos, OpNeg8, y.Type)
+		v0.AddArg(y)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (RotateLeft32 x (Const64 <t> [c]))
+	// cond: config.PtrSize == 4
+	// result: (RotateLeft32 x (Const32 <t> [int32(c)]))
+	for {
+		x := v_0
+		if v_1.Op != OpConst64 {
+			break
+		}
+		t := v_1.Type
+		c := auxIntToInt64(v_1.AuxInt)
+		if !(config.PtrSize == 4) {
+			break
+		}
+		v.reset(OpRotateLeft32)
+		v0 := b.NewValue0(v.Pos, OpConst32, t)
+		v0.AuxInt = int32ToAuxInt(int32(c))
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (RotateLeft32 (RotateLeft32 x c) d)
+	// cond: c.Type.Size() == 8 && d.Type.Size() == 8
+	// result: (RotateLeft32 x (Add64 <c.Type> c d))
+	for {
+		if v_0.Op != OpRotateLeft32 {
+			break
+		}
+		c := v_0.Args[1]
+		x := v_0.Args[0]
+		d := v_1
+		if !(c.Type.Size() == 8 && d.Type.Size() == 8) {
+			break
+		}
+		v.reset(OpRotateLeft32)
+		v0 := b.NewValue0(v.Pos, OpAdd64, c.Type)
+		v0.AddArg2(c, d)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (RotateLeft32 (RotateLeft32 x c) d)
+	// cond: c.Type.Size() == 4 && d.Type.Size() == 4
+	// result: (RotateLeft32 x (Add32 <c.Type> c d))
+	for {
+		if v_0.Op != OpRotateLeft32 {
+			break
+		}
+		c := v_0.Args[1]
+		x := v_0.Args[0]
+		d := v_1
+		if !(c.Type.Size() == 4 && d.Type.Size() == 4) {
+			break
+		}
+		v.reset(OpRotateLeft32)
+		v0 := b.NewValue0(v.Pos, OpAdd32, c.Type)
+		v0.AddArg2(c, d)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (RotateLeft32 (RotateLeft32 x c) d)
+	// cond: c.Type.Size() == 2 && d.Type.Size() == 2
+	// result: (RotateLeft32 x (Add16 <c.Type> c d))
+	for {
+		if v_0.Op != OpRotateLeft32 {
+			break
+		}
+		c := v_0.Args[1]
+		x := v_0.Args[0]
+		d := v_1
+		if !(c.Type.Size() == 2 && d.Type.Size() == 2) {
+			break
+		}
+		v.reset(OpRotateLeft32)
+		v0 := b.NewValue0(v.Pos, OpAdd16, c.Type)
+		v0.AddArg2(c, d)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (RotateLeft32 (RotateLeft32 x c) d)
+	// cond: c.Type.Size() == 1 && d.Type.Size() == 1
+	// result: (RotateLeft32 x (Add8 <c.Type> c d))
+	for {
+		if v_0.Op != OpRotateLeft32 {
+			break
+		}
+		c := v_0.Args[1]
+		x := v_0.Args[0]
+		d := v_1
+		if !(c.Type.Size() == 1 && d.Type.Size() == 1) {
+			break
+		}
+		v.reset(OpRotateLeft32)
+		v0 := b.NewValue0(v.Pos, OpAdd8, c.Type)
+		v0.AddArg2(c, d)
+		v.AddArg2(x, v0)
+		return true
+	}
 	return false
 }
 func rewriteValuegeneric_OpRotateLeft64(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
+	b := v.Block
+	config := b.Func.Config
 	// match: (RotateLeft64 x (Const64 [c]))
 	// cond: c%64 == 0
 	// result: x
@@ -19385,11 +23168,536 @@
 		v.copyOf(x)
 		return true
 	}
+	// match: (RotateLeft64 x (And64 y (Const64 [c])))
+	// cond: c&63 == 63
+	// result: (RotateLeft64 x y)
+	for {
+		x := v_0
+		if v_1.Op != OpAnd64 {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+			y := v_1_0
+			if v_1_1.Op != OpConst64 {
+				continue
+			}
+			c := auxIntToInt64(v_1_1.AuxInt)
+			if !(c&63 == 63) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft64 x (And32 y (Const32 [c])))
+	// cond: c&63 == 63
+	// result: (RotateLeft64 x y)
+	for {
+		x := v_0
+		if v_1.Op != OpAnd32 {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+			y := v_1_0
+			if v_1_1.Op != OpConst32 {
+				continue
+			}
+			c := auxIntToInt32(v_1_1.AuxInt)
+			if !(c&63 == 63) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft64 x (And16 y (Const16 [c])))
+	// cond: c&63 == 63
+	// result: (RotateLeft64 x y)
+	for {
+		x := v_0
+		if v_1.Op != OpAnd16 {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+			y := v_1_0
+			if v_1_1.Op != OpConst16 {
+				continue
+			}
+			c := auxIntToInt16(v_1_1.AuxInt)
+			if !(c&63 == 63) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft64 x (And8 y (Const8 [c])))
+	// cond: c&63 == 63
+	// result: (RotateLeft64 x y)
+	for {
+		x := v_0
+		if v_1.Op != OpAnd8 {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+			y := v_1_0
+			if v_1_1.Op != OpConst8 {
+				continue
+			}
+			c := auxIntToInt8(v_1_1.AuxInt)
+			if !(c&63 == 63) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft64 x (Neg64 (And64 y (Const64 [c]))))
+	// cond: c&63 == 63
+	// result: (RotateLeft64 x (Neg64 <y.Type> y))
+	for {
+		x := v_0
+		if v_1.Op != OpNeg64 {
+			break
+		}
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpAnd64 {
+			break
+		}
+		_ = v_1_0.Args[1]
+		v_1_0_0 := v_1_0.Args[0]
+		v_1_0_1 := v_1_0.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0_0, v_1_0_1 = _i0+1, v_1_0_1, v_1_0_0 {
+			y := v_1_0_0
+			if v_1_0_1.Op != OpConst64 {
+				continue
+			}
+			c := auxIntToInt64(v_1_0_1.AuxInt)
+			if !(c&63 == 63) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v0 := b.NewValue0(v.Pos, OpNeg64, y.Type)
+			v0.AddArg(y)
+			v.AddArg2(x, v0)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft64 x (Neg32 (And32 y (Const32 [c]))))
+	// cond: c&63 == 63
+	// result: (RotateLeft64 x (Neg32 <y.Type> y))
+	for {
+		x := v_0
+		if v_1.Op != OpNeg32 {
+			break
+		}
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpAnd32 {
+			break
+		}
+		_ = v_1_0.Args[1]
+		v_1_0_0 := v_1_0.Args[0]
+		v_1_0_1 := v_1_0.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0_0, v_1_0_1 = _i0+1, v_1_0_1, v_1_0_0 {
+			y := v_1_0_0
+			if v_1_0_1.Op != OpConst32 {
+				continue
+			}
+			c := auxIntToInt32(v_1_0_1.AuxInt)
+			if !(c&63 == 63) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v0 := b.NewValue0(v.Pos, OpNeg32, y.Type)
+			v0.AddArg(y)
+			v.AddArg2(x, v0)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft64 x (Neg16 (And16 y (Const16 [c]))))
+	// cond: c&63 == 63
+	// result: (RotateLeft64 x (Neg16 <y.Type> y))
+	for {
+		x := v_0
+		if v_1.Op != OpNeg16 {
+			break
+		}
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpAnd16 {
+			break
+		}
+		_ = v_1_0.Args[1]
+		v_1_0_0 := v_1_0.Args[0]
+		v_1_0_1 := v_1_0.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0_0, v_1_0_1 = _i0+1, v_1_0_1, v_1_0_0 {
+			y := v_1_0_0
+			if v_1_0_1.Op != OpConst16 {
+				continue
+			}
+			c := auxIntToInt16(v_1_0_1.AuxInt)
+			if !(c&63 == 63) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v0 := b.NewValue0(v.Pos, OpNeg16, y.Type)
+			v0.AddArg(y)
+			v.AddArg2(x, v0)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft64 x (Neg8 (And8 y (Const8 [c]))))
+	// cond: c&63 == 63
+	// result: (RotateLeft64 x (Neg8 <y.Type> y))
+	for {
+		x := v_0
+		if v_1.Op != OpNeg8 {
+			break
+		}
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpAnd8 {
+			break
+		}
+		_ = v_1_0.Args[1]
+		v_1_0_0 := v_1_0.Args[0]
+		v_1_0_1 := v_1_0.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0_0, v_1_0_1 = _i0+1, v_1_0_1, v_1_0_0 {
+			y := v_1_0_0
+			if v_1_0_1.Op != OpConst8 {
+				continue
+			}
+			c := auxIntToInt8(v_1_0_1.AuxInt)
+			if !(c&63 == 63) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v0 := b.NewValue0(v.Pos, OpNeg8, y.Type)
+			v0.AddArg(y)
+			v.AddArg2(x, v0)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft64 x (Add64 y (Const64 [c])))
+	// cond: c&63 == 0
+	// result: (RotateLeft64 x y)
+	for {
+		x := v_0
+		if v_1.Op != OpAdd64 {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+			y := v_1_0
+			if v_1_1.Op != OpConst64 {
+				continue
+			}
+			c := auxIntToInt64(v_1_1.AuxInt)
+			if !(c&63 == 0) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft64 x (Add32 y (Const32 [c])))
+	// cond: c&63 == 0
+	// result: (RotateLeft64 x y)
+	for {
+		x := v_0
+		if v_1.Op != OpAdd32 {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+			y := v_1_0
+			if v_1_1.Op != OpConst32 {
+				continue
+			}
+			c := auxIntToInt32(v_1_1.AuxInt)
+			if !(c&63 == 0) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft64 x (Add16 y (Const16 [c])))
+	// cond: c&63 == 0
+	// result: (RotateLeft64 x y)
+	for {
+		x := v_0
+		if v_1.Op != OpAdd16 {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+			y := v_1_0
+			if v_1_1.Op != OpConst16 {
+				continue
+			}
+			c := auxIntToInt16(v_1_1.AuxInt)
+			if !(c&63 == 0) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft64 x (Add8 y (Const8 [c])))
+	// cond: c&63 == 0
+	// result: (RotateLeft64 x y)
+	for {
+		x := v_0
+		if v_1.Op != OpAdd8 {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+			y := v_1_0
+			if v_1_1.Op != OpConst8 {
+				continue
+			}
+			c := auxIntToInt8(v_1_1.AuxInt)
+			if !(c&63 == 0) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft64 x (Sub64 (Const64 [c]) y))
+	// cond: c&63 == 0
+	// result: (RotateLeft64 x (Neg64 <y.Type> y))
+	for {
+		x := v_0
+		if v_1.Op != OpSub64 {
+			break
+		}
+		y := v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpConst64 {
+			break
+		}
+		c := auxIntToInt64(v_1_0.AuxInt)
+		if !(c&63 == 0) {
+			break
+		}
+		v.reset(OpRotateLeft64)
+		v0 := b.NewValue0(v.Pos, OpNeg64, y.Type)
+		v0.AddArg(y)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (RotateLeft64 x (Sub32 (Const32 [c]) y))
+	// cond: c&63 == 0
+	// result: (RotateLeft64 x (Neg32 <y.Type> y))
+	for {
+		x := v_0
+		if v_1.Op != OpSub32 {
+			break
+		}
+		y := v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpConst32 {
+			break
+		}
+		c := auxIntToInt32(v_1_0.AuxInt)
+		if !(c&63 == 0) {
+			break
+		}
+		v.reset(OpRotateLeft64)
+		v0 := b.NewValue0(v.Pos, OpNeg32, y.Type)
+		v0.AddArg(y)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (RotateLeft64 x (Sub16 (Const16 [c]) y))
+	// cond: c&63 == 0
+	// result: (RotateLeft64 x (Neg16 <y.Type> y))
+	for {
+		x := v_0
+		if v_1.Op != OpSub16 {
+			break
+		}
+		y := v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpConst16 {
+			break
+		}
+		c := auxIntToInt16(v_1_0.AuxInt)
+		if !(c&63 == 0) {
+			break
+		}
+		v.reset(OpRotateLeft64)
+		v0 := b.NewValue0(v.Pos, OpNeg16, y.Type)
+		v0.AddArg(y)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (RotateLeft64 x (Sub8 (Const8 [c]) y))
+	// cond: c&63 == 0
+	// result: (RotateLeft64 x (Neg8 <y.Type> y))
+	for {
+		x := v_0
+		if v_1.Op != OpSub8 {
+			break
+		}
+		y := v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpConst8 {
+			break
+		}
+		c := auxIntToInt8(v_1_0.AuxInt)
+		if !(c&63 == 0) {
+			break
+		}
+		v.reset(OpRotateLeft64)
+		v0 := b.NewValue0(v.Pos, OpNeg8, y.Type)
+		v0.AddArg(y)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (RotateLeft64 x (Const64 <t> [c]))
+	// cond: config.PtrSize == 4
+	// result: (RotateLeft64 x (Const32 <t> [int32(c)]))
+	for {
+		x := v_0
+		if v_1.Op != OpConst64 {
+			break
+		}
+		t := v_1.Type
+		c := auxIntToInt64(v_1.AuxInt)
+		if !(config.PtrSize == 4) {
+			break
+		}
+		v.reset(OpRotateLeft64)
+		v0 := b.NewValue0(v.Pos, OpConst32, t)
+		v0.AuxInt = int32ToAuxInt(int32(c))
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (RotateLeft64 (RotateLeft64 x c) d)
+	// cond: c.Type.Size() == 8 && d.Type.Size() == 8
+	// result: (RotateLeft64 x (Add64 <c.Type> c d))
+	for {
+		if v_0.Op != OpRotateLeft64 {
+			break
+		}
+		c := v_0.Args[1]
+		x := v_0.Args[0]
+		d := v_1
+		if !(c.Type.Size() == 8 && d.Type.Size() == 8) {
+			break
+		}
+		v.reset(OpRotateLeft64)
+		v0 := b.NewValue0(v.Pos, OpAdd64, c.Type)
+		v0.AddArg2(c, d)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (RotateLeft64 (RotateLeft64 x c) d)
+	// cond: c.Type.Size() == 4 && d.Type.Size() == 4
+	// result: (RotateLeft64 x (Add32 <c.Type> c d))
+	for {
+		if v_0.Op != OpRotateLeft64 {
+			break
+		}
+		c := v_0.Args[1]
+		x := v_0.Args[0]
+		d := v_1
+		if !(c.Type.Size() == 4 && d.Type.Size() == 4) {
+			break
+		}
+		v.reset(OpRotateLeft64)
+		v0 := b.NewValue0(v.Pos, OpAdd32, c.Type)
+		v0.AddArg2(c, d)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (RotateLeft64 (RotateLeft64 x c) d)
+	// cond: c.Type.Size() == 2 && d.Type.Size() == 2
+	// result: (RotateLeft64 x (Add16 <c.Type> c d))
+	for {
+		if v_0.Op != OpRotateLeft64 {
+			break
+		}
+		c := v_0.Args[1]
+		x := v_0.Args[0]
+		d := v_1
+		if !(c.Type.Size() == 2 && d.Type.Size() == 2) {
+			break
+		}
+		v.reset(OpRotateLeft64)
+		v0 := b.NewValue0(v.Pos, OpAdd16, c.Type)
+		v0.AddArg2(c, d)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (RotateLeft64 (RotateLeft64 x c) d)
+	// cond: c.Type.Size() == 1 && d.Type.Size() == 1
+	// result: (RotateLeft64 x (Add8 <c.Type> c d))
+	for {
+		if v_0.Op != OpRotateLeft64 {
+			break
+		}
+		c := v_0.Args[1]
+		x := v_0.Args[0]
+		d := v_1
+		if !(c.Type.Size() == 1 && d.Type.Size() == 1) {
+			break
+		}
+		v.reset(OpRotateLeft64)
+		v0 := b.NewValue0(v.Pos, OpAdd8, c.Type)
+		v0.AddArg2(c, d)
+		v.AddArg2(x, v0)
+		return true
+	}
 	return false
 }
 func rewriteValuegeneric_OpRotateLeft8(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
+	b := v.Block
+	config := b.Func.Config
 	// match: (RotateLeft8 x (Const8 [c]))
 	// cond: c%8 == 0
 	// result: x
@@ -19405,6 +23713,529 @@
 		v.copyOf(x)
 		return true
 	}
+	// match: (RotateLeft8 x (And64 y (Const64 [c])))
+	// cond: c&7 == 7
+	// result: (RotateLeft8 x y)
+	for {
+		x := v_0
+		if v_1.Op != OpAnd64 {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+			y := v_1_0
+			if v_1_1.Op != OpConst64 {
+				continue
+			}
+			c := auxIntToInt64(v_1_1.AuxInt)
+			if !(c&7 == 7) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft8 x (And32 y (Const32 [c])))
+	// cond: c&7 == 7
+	// result: (RotateLeft8 x y)
+	for {
+		x := v_0
+		if v_1.Op != OpAnd32 {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+			y := v_1_0
+			if v_1_1.Op != OpConst32 {
+				continue
+			}
+			c := auxIntToInt32(v_1_1.AuxInt)
+			if !(c&7 == 7) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft8 x (And16 y (Const16 [c])))
+	// cond: c&7 == 7
+	// result: (RotateLeft8 x y)
+	for {
+		x := v_0
+		if v_1.Op != OpAnd16 {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+			y := v_1_0
+			if v_1_1.Op != OpConst16 {
+				continue
+			}
+			c := auxIntToInt16(v_1_1.AuxInt)
+			if !(c&7 == 7) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft8 x (And8 y (Const8 [c])))
+	// cond: c&7 == 7
+	// result: (RotateLeft8 x y)
+	for {
+		x := v_0
+		if v_1.Op != OpAnd8 {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+			y := v_1_0
+			if v_1_1.Op != OpConst8 {
+				continue
+			}
+			c := auxIntToInt8(v_1_1.AuxInt)
+			if !(c&7 == 7) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft8 x (Neg64 (And64 y (Const64 [c]))))
+	// cond: c&7 == 7
+	// result: (RotateLeft8 x (Neg64 <y.Type> y))
+	for {
+		x := v_0
+		if v_1.Op != OpNeg64 {
+			break
+		}
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpAnd64 {
+			break
+		}
+		_ = v_1_0.Args[1]
+		v_1_0_0 := v_1_0.Args[0]
+		v_1_0_1 := v_1_0.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0_0, v_1_0_1 = _i0+1, v_1_0_1, v_1_0_0 {
+			y := v_1_0_0
+			if v_1_0_1.Op != OpConst64 {
+				continue
+			}
+			c := auxIntToInt64(v_1_0_1.AuxInt)
+			if !(c&7 == 7) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v0 := b.NewValue0(v.Pos, OpNeg64, y.Type)
+			v0.AddArg(y)
+			v.AddArg2(x, v0)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft8 x (Neg32 (And32 y (Const32 [c]))))
+	// cond: c&7 == 7
+	// result: (RotateLeft8 x (Neg32 <y.Type> y))
+	for {
+		x := v_0
+		if v_1.Op != OpNeg32 {
+			break
+		}
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpAnd32 {
+			break
+		}
+		_ = v_1_0.Args[1]
+		v_1_0_0 := v_1_0.Args[0]
+		v_1_0_1 := v_1_0.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0_0, v_1_0_1 = _i0+1, v_1_0_1, v_1_0_0 {
+			y := v_1_0_0
+			if v_1_0_1.Op != OpConst32 {
+				continue
+			}
+			c := auxIntToInt32(v_1_0_1.AuxInt)
+			if !(c&7 == 7) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v0 := b.NewValue0(v.Pos, OpNeg32, y.Type)
+			v0.AddArg(y)
+			v.AddArg2(x, v0)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft8 x (Neg16 (And16 y (Const16 [c]))))
+	// cond: c&7 == 7
+	// result: (RotateLeft8 x (Neg16 <y.Type> y))
+	for {
+		x := v_0
+		if v_1.Op != OpNeg16 {
+			break
+		}
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpAnd16 {
+			break
+		}
+		_ = v_1_0.Args[1]
+		v_1_0_0 := v_1_0.Args[0]
+		v_1_0_1 := v_1_0.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0_0, v_1_0_1 = _i0+1, v_1_0_1, v_1_0_0 {
+			y := v_1_0_0
+			if v_1_0_1.Op != OpConst16 {
+				continue
+			}
+			c := auxIntToInt16(v_1_0_1.AuxInt)
+			if !(c&7 == 7) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v0 := b.NewValue0(v.Pos, OpNeg16, y.Type)
+			v0.AddArg(y)
+			v.AddArg2(x, v0)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft8 x (Neg8 (And8 y (Const8 [c]))))
+	// cond: c&7 == 7
+	// result: (RotateLeft8 x (Neg8 <y.Type> y))
+	for {
+		x := v_0
+		if v_1.Op != OpNeg8 {
+			break
+		}
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpAnd8 {
+			break
+		}
+		_ = v_1_0.Args[1]
+		v_1_0_0 := v_1_0.Args[0]
+		v_1_0_1 := v_1_0.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0_0, v_1_0_1 = _i0+1, v_1_0_1, v_1_0_0 {
+			y := v_1_0_0
+			if v_1_0_1.Op != OpConst8 {
+				continue
+			}
+			c := auxIntToInt8(v_1_0_1.AuxInt)
+			if !(c&7 == 7) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v0 := b.NewValue0(v.Pos, OpNeg8, y.Type)
+			v0.AddArg(y)
+			v.AddArg2(x, v0)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft8 x (Add64 y (Const64 [c])))
+	// cond: c&7 == 0
+	// result: (RotateLeft8 x y)
+	for {
+		x := v_0
+		if v_1.Op != OpAdd64 {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+			y := v_1_0
+			if v_1_1.Op != OpConst64 {
+				continue
+			}
+			c := auxIntToInt64(v_1_1.AuxInt)
+			if !(c&7 == 0) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft8 x (Add32 y (Const32 [c])))
+	// cond: c&7 == 0
+	// result: (RotateLeft8 x y)
+	for {
+		x := v_0
+		if v_1.Op != OpAdd32 {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+			y := v_1_0
+			if v_1_1.Op != OpConst32 {
+				continue
+			}
+			c := auxIntToInt32(v_1_1.AuxInt)
+			if !(c&7 == 0) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft8 x (Add16 y (Const16 [c])))
+	// cond: c&7 == 0
+	// result: (RotateLeft8 x y)
+	for {
+		x := v_0
+		if v_1.Op != OpAdd16 {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+			y := v_1_0
+			if v_1_1.Op != OpConst16 {
+				continue
+			}
+			c := auxIntToInt16(v_1_1.AuxInt)
+			if !(c&7 == 0) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft8 x (Add8 y (Const8 [c])))
+	// cond: c&7 == 0
+	// result: (RotateLeft8 x y)
+	for {
+		x := v_0
+		if v_1.Op != OpAdd8 {
+			break
+		}
+		_ = v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		v_1_1 := v_1.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_1_0, v_1_1 = _i0+1, v_1_1, v_1_0 {
+			y := v_1_0
+			if v_1_1.Op != OpConst8 {
+				continue
+			}
+			c := auxIntToInt8(v_1_1.AuxInt)
+			if !(c&7 == 0) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (RotateLeft8 x (Sub64 (Const64 [c]) y))
+	// cond: c&7 == 0
+	// result: (RotateLeft8 x (Neg64 <y.Type> y))
+	for {
+		x := v_0
+		if v_1.Op != OpSub64 {
+			break
+		}
+		y := v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpConst64 {
+			break
+		}
+		c := auxIntToInt64(v_1_0.AuxInt)
+		if !(c&7 == 0) {
+			break
+		}
+		v.reset(OpRotateLeft8)
+		v0 := b.NewValue0(v.Pos, OpNeg64, y.Type)
+		v0.AddArg(y)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (RotateLeft8 x (Sub32 (Const32 [c]) y))
+	// cond: c&7 == 0
+	// result: (RotateLeft8 x (Neg32 <y.Type> y))
+	for {
+		x := v_0
+		if v_1.Op != OpSub32 {
+			break
+		}
+		y := v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpConst32 {
+			break
+		}
+		c := auxIntToInt32(v_1_0.AuxInt)
+		if !(c&7 == 0) {
+			break
+		}
+		v.reset(OpRotateLeft8)
+		v0 := b.NewValue0(v.Pos, OpNeg32, y.Type)
+		v0.AddArg(y)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (RotateLeft8 x (Sub16 (Const16 [c]) y))
+	// cond: c&7 == 0
+	// result: (RotateLeft8 x (Neg16 <y.Type> y))
+	for {
+		x := v_0
+		if v_1.Op != OpSub16 {
+			break
+		}
+		y := v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpConst16 {
+			break
+		}
+		c := auxIntToInt16(v_1_0.AuxInt)
+		if !(c&7 == 0) {
+			break
+		}
+		v.reset(OpRotateLeft8)
+		v0 := b.NewValue0(v.Pos, OpNeg16, y.Type)
+		v0.AddArg(y)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (RotateLeft8 x (Sub8 (Const8 [c]) y))
+	// cond: c&7 == 0
+	// result: (RotateLeft8 x (Neg8 <y.Type> y))
+	for {
+		x := v_0
+		if v_1.Op != OpSub8 {
+			break
+		}
+		y := v_1.Args[1]
+		v_1_0 := v_1.Args[0]
+		if v_1_0.Op != OpConst8 {
+			break
+		}
+		c := auxIntToInt8(v_1_0.AuxInt)
+		if !(c&7 == 0) {
+			break
+		}
+		v.reset(OpRotateLeft8)
+		v0 := b.NewValue0(v.Pos, OpNeg8, y.Type)
+		v0.AddArg(y)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (RotateLeft8 x (Const64 <t> [c]))
+	// cond: config.PtrSize == 4
+	// result: (RotateLeft8 x (Const32 <t> [int32(c)]))
+	for {
+		x := v_0
+		if v_1.Op != OpConst64 {
+			break
+		}
+		t := v_1.Type
+		c := auxIntToInt64(v_1.AuxInt)
+		if !(config.PtrSize == 4) {
+			break
+		}
+		v.reset(OpRotateLeft8)
+		v0 := b.NewValue0(v.Pos, OpConst32, t)
+		v0.AuxInt = int32ToAuxInt(int32(c))
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (RotateLeft8 (RotateLeft8 x c) d)
+	// cond: c.Type.Size() == 8 && d.Type.Size() == 8
+	// result: (RotateLeft8 x (Add64 <c.Type> c d))
+	for {
+		if v_0.Op != OpRotateLeft8 {
+			break
+		}
+		c := v_0.Args[1]
+		x := v_0.Args[0]
+		d := v_1
+		if !(c.Type.Size() == 8 && d.Type.Size() == 8) {
+			break
+		}
+		v.reset(OpRotateLeft8)
+		v0 := b.NewValue0(v.Pos, OpAdd64, c.Type)
+		v0.AddArg2(c, d)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (RotateLeft8 (RotateLeft8 x c) d)
+	// cond: c.Type.Size() == 4 && d.Type.Size() == 4
+	// result: (RotateLeft8 x (Add32 <c.Type> c d))
+	for {
+		if v_0.Op != OpRotateLeft8 {
+			break
+		}
+		c := v_0.Args[1]
+		x := v_0.Args[0]
+		d := v_1
+		if !(c.Type.Size() == 4 && d.Type.Size() == 4) {
+			break
+		}
+		v.reset(OpRotateLeft8)
+		v0 := b.NewValue0(v.Pos, OpAdd32, c.Type)
+		v0.AddArg2(c, d)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (RotateLeft8 (RotateLeft8 x c) d)
+	// cond: c.Type.Size() == 2 && d.Type.Size() == 2
+	// result: (RotateLeft8 x (Add16 <c.Type> c d))
+	for {
+		if v_0.Op != OpRotateLeft8 {
+			break
+		}
+		c := v_0.Args[1]
+		x := v_0.Args[0]
+		d := v_1
+		if !(c.Type.Size() == 2 && d.Type.Size() == 2) {
+			break
+		}
+		v.reset(OpRotateLeft8)
+		v0 := b.NewValue0(v.Pos, OpAdd16, c.Type)
+		v0.AddArg2(c, d)
+		v.AddArg2(x, v0)
+		return true
+	}
+	// match: (RotateLeft8 (RotateLeft8 x c) d)
+	// cond: c.Type.Size() == 1 && d.Type.Size() == 1
+	// result: (RotateLeft8 x (Add8 <c.Type> c d))
+	for {
+		if v_0.Op != OpRotateLeft8 {
+			break
+		}
+		c := v_0.Args[1]
+		x := v_0.Args[0]
+		d := v_1
+		if !(c.Type.Size() == 1 && d.Type.Size() == 1) {
+			break
+		}
+		v.reset(OpRotateLeft8)
+		v0 := b.NewValue0(v.Pos, OpAdd8, c.Type)
+		v0.AddArg2(c, d)
+		v.AddArg2(x, v0)
+		return true
+	}
 	return false
 }
 func rewriteValuegeneric_OpRound32F(v *Value) bool {
@@ -19435,6 +24266,21 @@
 	}
 	return false
 }
+func rewriteValuegeneric_OpRoundToEven(v *Value) bool {
+	v_0 := v.Args[0]
+	// match: (RoundToEven (Const64F [c]))
+	// result: (Const64F [math.RoundToEven(c)])
+	for {
+		if v_0.Op != OpConst64F {
+			break
+		}
+		c := auxIntToFloat64(v_0.AuxInt)
+		v.reset(OpConst64F)
+		v.AuxInt = float64ToAuxInt(math.RoundToEven(c))
+		return true
+	}
+	return false
+}
 func rewriteValuegeneric_OpRsh16Ux16(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
@@ -19600,6 +24446,30 @@
 		v.AddArg2(x, v0)
 		return true
 	}
+	// match: (Rsh16Ux64 i:(Lsh16x64 x (Const64 [c])) (Const64 [c]))
+	// cond: c >= 0 && c < 16 && i.Uses == 1
+	// result: (And16 x (Const16 <v.Type> [int16(^uint16(0)>>c)]))
+	for {
+		i := v_0
+		if i.Op != OpLsh16x64 {
+			break
+		}
+		_ = i.Args[1]
+		x := i.Args[0]
+		i_1 := i.Args[1]
+		if i_1.Op != OpConst64 {
+			break
+		}
+		c := auxIntToInt64(i_1.AuxInt)
+		if v_1.Op != OpConst64 || auxIntToInt64(v_1.AuxInt) != c || !(c >= 0 && c < 16 && i.Uses == 1) {
+			break
+		}
+		v.reset(OpAnd16)
+		v0 := b.NewValue0(v.Pos, OpConst16, v.Type)
+		v0.AuxInt = int16ToAuxInt(int16(^uint16(0) >> c))
+		v.AddArg2(x, v0)
+		return true
+	}
 	// match: (Rsh16Ux64 (Lsh16x64 (Rsh16Ux64 x (Const64 [c1])) (Const64 [c2])) (Const64 [c3]))
 	// cond: uint64(c1) >= uint64(c2) && uint64(c3) >= uint64(c2) && !uaddOvf(c1-c2, c3)
 	// result: (Rsh16Ux64 x (Const64 <typ.UInt64> [c1-c2+c3]))
@@ -20034,6 +24904,30 @@
 		v.AddArg2(x, v0)
 		return true
 	}
+	// match: (Rsh32Ux64 i:(Lsh32x64 x (Const64 [c])) (Const64 [c]))
+	// cond: c >= 0 && c < 32 && i.Uses == 1
+	// result: (And32 x (Const32 <v.Type> [int32(^uint32(0)>>c)]))
+	for {
+		i := v_0
+		if i.Op != OpLsh32x64 {
+			break
+		}
+		_ = i.Args[1]
+		x := i.Args[0]
+		i_1 := i.Args[1]
+		if i_1.Op != OpConst64 {
+			break
+		}
+		c := auxIntToInt64(i_1.AuxInt)
+		if v_1.Op != OpConst64 || auxIntToInt64(v_1.AuxInt) != c || !(c >= 0 && c < 32 && i.Uses == 1) {
+			break
+		}
+		v.reset(OpAnd32)
+		v0 := b.NewValue0(v.Pos, OpConst32, v.Type)
+		v0.AuxInt = int32ToAuxInt(int32(^uint32(0) >> c))
+		v.AddArg2(x, v0)
+		return true
+	}
 	// match: (Rsh32Ux64 (Lsh32x64 (Rsh32Ux64 x (Const64 [c1])) (Const64 [c2])) (Const64 [c3]))
 	// cond: uint64(c1) >= uint64(c2) && uint64(c3) >= uint64(c2) && !uaddOvf(c1-c2, c3)
 	// result: (Rsh32Ux64 x (Const64 <typ.UInt64> [c1-c2+c3]))
@@ -20504,6 +25398,30 @@
 		v.AddArg2(x, v0)
 		return true
 	}
+	// match: (Rsh64Ux64 i:(Lsh64x64 x (Const64 [c])) (Const64 [c]))
+	// cond: c >= 0 && c < 64 && i.Uses == 1
+	// result: (And64 x (Const64 <v.Type> [int64(^uint64(0)>>c)]))
+	for {
+		i := v_0
+		if i.Op != OpLsh64x64 {
+			break
+		}
+		_ = i.Args[1]
+		x := i.Args[0]
+		i_1 := i.Args[1]
+		if i_1.Op != OpConst64 {
+			break
+		}
+		c := auxIntToInt64(i_1.AuxInt)
+		if v_1.Op != OpConst64 || auxIntToInt64(v_1.AuxInt) != c || !(c >= 0 && c < 64 && i.Uses == 1) {
+			break
+		}
+		v.reset(OpAnd64)
+		v0 := b.NewValue0(v.Pos, OpConst64, v.Type)
+		v0.AuxInt = int64ToAuxInt(int64(^uint64(0) >> c))
+		v.AddArg2(x, v0)
+		return true
+	}
 	// match: (Rsh64Ux64 (Lsh64x64 (Rsh64Ux64 x (Const64 [c1])) (Const64 [c2])) (Const64 [c3]))
 	// cond: uint64(c1) >= uint64(c2) && uint64(c3) >= uint64(c2) && !uaddOvf(c1-c2, c3)
 	// result: (Rsh64Ux64 x (Const64 <typ.UInt64> [c1-c2+c3]))
@@ -21010,6 +25928,30 @@
 		v.AddArg2(x, v0)
 		return true
 	}
+	// match: (Rsh8Ux64 i:(Lsh8x64 x (Const64 [c])) (Const64 [c]))
+	// cond: c >= 0 && c < 8 && i.Uses == 1
+	// result: (And8 x (Const8 <v.Type> [int8 (^uint8 (0)>>c)]))
+	for {
+		i := v_0
+		if i.Op != OpLsh8x64 {
+			break
+		}
+		_ = i.Args[1]
+		x := i.Args[0]
+		i_1 := i.Args[1]
+		if i_1.Op != OpConst64 {
+			break
+		}
+		c := auxIntToInt64(i_1.AuxInt)
+		if v_1.Op != OpConst64 || auxIntToInt64(v_1.AuxInt) != c || !(c >= 0 && c < 8 && i.Uses == 1) {
+			break
+		}
+		v.reset(OpAnd8)
+		v0 := b.NewValue0(v.Pos, OpConst8, v.Type)
+		v0.AuxInt = int8ToAuxInt(int8(^uint8(0) >> c))
+		v.AddArg2(x, v0)
+		return true
+	}
 	// match: (Rsh8Ux64 (Lsh8x64 (Rsh8Ux64 x (Const64 [c1])) (Const64 [c2])) (Const64 [c3]))
 	// cond: uint64(c1) >= uint64(c2) && uint64(c3) >= uint64(c2) && !uaddOvf(c1-c2, c3)
 	// result: (Rsh8Ux64 x (Const64 <typ.UInt64> [c1-c2+c3]))
@@ -21260,6 +26202,82 @@
 		v.AddArg2(lo, y)
 		return true
 	}
+	// match: (Select0 (Mul32uover (Const32 [1]) x))
+	// result: x
+	for {
+		if v_0.Op != OpMul32uover {
+			break
+		}
+		_ = v_0.Args[1]
+		v_0_0 := v_0.Args[0]
+		v_0_1 := v_0.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
+			if v_0_0.Op != OpConst32 || auxIntToInt32(v_0_0.AuxInt) != 1 {
+				continue
+			}
+			x := v_0_1
+			v.copyOf(x)
+			return true
+		}
+		break
+	}
+	// match: (Select0 (Mul64uover (Const64 [1]) x))
+	// result: x
+	for {
+		if v_0.Op != OpMul64uover {
+			break
+		}
+		_ = v_0.Args[1]
+		v_0_0 := v_0.Args[0]
+		v_0_1 := v_0.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
+			if v_0_0.Op != OpConst64 || auxIntToInt64(v_0_0.AuxInt) != 1 {
+				continue
+			}
+			x := v_0_1
+			v.copyOf(x)
+			return true
+		}
+		break
+	}
+	// match: (Select0 (Mul64uover (Const64 [0]) x))
+	// result: (Const64 [0])
+	for {
+		if v_0.Op != OpMul64uover {
+			break
+		}
+		_ = v_0.Args[1]
+		v_0_0 := v_0.Args[0]
+		v_0_1 := v_0.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
+			if v_0_0.Op != OpConst64 || auxIntToInt64(v_0_0.AuxInt) != 0 {
+				continue
+			}
+			v.reset(OpConst64)
+			v.AuxInt = int64ToAuxInt(0)
+			return true
+		}
+		break
+	}
+	// match: (Select0 (Mul32uover (Const32 [0]) x))
+	// result: (Const32 [0])
+	for {
+		if v_0.Op != OpMul32uover {
+			break
+		}
+		_ = v_0.Args[1]
+		v_0_0 := v_0.Args[0]
+		v_0_1 := v_0.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
+			if v_0_0.Op != OpConst32 || auxIntToInt32(v_0_0.AuxInt) != 0 {
+				continue
+			}
+			v.reset(OpConst32)
+			v.AuxInt = int32ToAuxInt(0)
+			return true
+		}
+		break
+	}
 	return false
 }
 func rewriteValuegeneric_OpSelect1(v *Value) bool {
@@ -21280,6 +26298,82 @@
 		v.AddArg2(lo, y)
 		return true
 	}
+	// match: (Select1 (Mul32uover (Const32 [1]) x))
+	// result: (ConstBool [false])
+	for {
+		if v_0.Op != OpMul32uover {
+			break
+		}
+		_ = v_0.Args[1]
+		v_0_0 := v_0.Args[0]
+		v_0_1 := v_0.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
+			if v_0_0.Op != OpConst32 || auxIntToInt32(v_0_0.AuxInt) != 1 {
+				continue
+			}
+			v.reset(OpConstBool)
+			v.AuxInt = boolToAuxInt(false)
+			return true
+		}
+		break
+	}
+	// match: (Select1 (Mul64uover (Const64 [1]) x))
+	// result: (ConstBool [false])
+	for {
+		if v_0.Op != OpMul64uover {
+			break
+		}
+		_ = v_0.Args[1]
+		v_0_0 := v_0.Args[0]
+		v_0_1 := v_0.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
+			if v_0_0.Op != OpConst64 || auxIntToInt64(v_0_0.AuxInt) != 1 {
+				continue
+			}
+			v.reset(OpConstBool)
+			v.AuxInt = boolToAuxInt(false)
+			return true
+		}
+		break
+	}
+	// match: (Select1 (Mul64uover (Const64 [0]) x))
+	// result: (ConstBool [false])
+	for {
+		if v_0.Op != OpMul64uover {
+			break
+		}
+		_ = v_0.Args[1]
+		v_0_0 := v_0.Args[0]
+		v_0_1 := v_0.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
+			if v_0_0.Op != OpConst64 || auxIntToInt64(v_0_0.AuxInt) != 0 {
+				continue
+			}
+			v.reset(OpConstBool)
+			v.AuxInt = boolToAuxInt(false)
+			return true
+		}
+		break
+	}
+	// match: (Select1 (Mul32uover (Const32 [0]) x))
+	// result: (ConstBool [false])
+	for {
+		if v_0.Op != OpMul32uover {
+			break
+		}
+		_ = v_0.Args[1]
+		v_0_0 := v_0.Args[0]
+		v_0_1 := v_0.Args[1]
+		for _i0 := 0; _i0 <= 1; _i0, v_0_0, v_0_1 = _i0+1, v_0_1, v_0_0 {
+			if v_0_0.Op != OpConst32 || auxIntToInt32(v_0_0.AuxInt) != 0 {
+				continue
+			}
+			v.reset(OpConstBool)
+			v.AuxInt = boolToAuxInt(false)
+			return true
+		}
+		break
+	}
 	return false
 }
 func rewriteValuegeneric_OpSelectN(v *Value) bool {
@@ -21317,8 +26411,8 @@
 		return true
 	}
 	// match: (SelectN [0] call:(StaticCall {sym} s1:(Store _ (Const64 [sz]) s2:(Store _ src s3:(Store {t} _ dst mem)))))
-	// cond: sz >= 0 && isSameCall(sym, "runtime.memmove") && t.IsPtr() && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, int64(sz), config) && clobber(s1, s2, s3, call)
-	// result: (Move {t.Elem()} [int64(sz)] dst src mem)
+	// cond: sz >= 0 && isSameCall(sym, "runtime.memmove") && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, int64(sz), config) && clobber(s1, s2, s3, call)
+	// result: (Move {types.Types[types.TUINT8]} [int64(sz)] dst src mem)
 	for {
 		if auxIntToInt64(v.AuxInt) != 0 {
 			break
@@ -21348,21 +26442,20 @@
 		if s3.Op != OpStore {
 			break
 		}
-		t := auxToType(s3.Aux)
 		mem := s3.Args[2]
 		dst := s3.Args[1]
-		if !(sz >= 0 && isSameCall(sym, "runtime.memmove") && t.IsPtr() && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, int64(sz), config) && clobber(s1, s2, s3, call)) {
+		if !(sz >= 0 && isSameCall(sym, "runtime.memmove") && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, int64(sz), config) && clobber(s1, s2, s3, call)) {
 			break
 		}
 		v.reset(OpMove)
 		v.AuxInt = int64ToAuxInt(int64(sz))
-		v.Aux = typeToAux(t.Elem())
+		v.Aux = typeToAux(types.Types[types.TUINT8])
 		v.AddArg3(dst, src, mem)
 		return true
 	}
 	// match: (SelectN [0] call:(StaticCall {sym} s1:(Store _ (Const32 [sz]) s2:(Store _ src s3:(Store {t} _ dst mem)))))
-	// cond: sz >= 0 && isSameCall(sym, "runtime.memmove") && t.IsPtr() && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, int64(sz), config) && clobber(s1, s2, s3, call)
-	// result: (Move {t.Elem()} [int64(sz)] dst src mem)
+	// cond: sz >= 0 && isSameCall(sym, "runtime.memmove") && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, int64(sz), config) && clobber(s1, s2, s3, call)
+	// result: (Move {types.Types[types.TUINT8]} [int64(sz)] dst src mem)
 	for {
 		if auxIntToInt64(v.AuxInt) != 0 {
 			break
@@ -21392,21 +26485,20 @@
 		if s3.Op != OpStore {
 			break
 		}
-		t := auxToType(s3.Aux)
 		mem := s3.Args[2]
 		dst := s3.Args[1]
-		if !(sz >= 0 && isSameCall(sym, "runtime.memmove") && t.IsPtr() && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, int64(sz), config) && clobber(s1, s2, s3, call)) {
+		if !(sz >= 0 && isSameCall(sym, "runtime.memmove") && s1.Uses == 1 && s2.Uses == 1 && s3.Uses == 1 && isInlinableMemmove(dst, src, int64(sz), config) && clobber(s1, s2, s3, call)) {
 			break
 		}
 		v.reset(OpMove)
 		v.AuxInt = int64ToAuxInt(int64(sz))
-		v.Aux = typeToAux(t.Elem())
+		v.Aux = typeToAux(types.Types[types.TUINT8])
 		v.AddArg3(dst, src, mem)
 		return true
 	}
 	// match: (SelectN [0] call:(StaticCall {sym} dst src (Const64 [sz]) mem))
-	// cond: sz >= 0 && call.Uses == 1 && isSameCall(sym, "runtime.memmove") && dst.Type.IsPtr() && isInlinableMemmove(dst, src, int64(sz), config) && clobber(call)
-	// result: (Move {dst.Type.Elem()} [int64(sz)] dst src mem)
+	// cond: sz >= 0 && call.Uses == 1 && isSameCall(sym, "runtime.memmove") && isInlinableMemmove(dst, src, int64(sz), config) && clobber(call)
+	// result: (Move {types.Types[types.TUINT8]} [int64(sz)] dst src mem)
 	for {
 		if auxIntToInt64(v.AuxInt) != 0 {
 			break
@@ -21424,18 +26516,18 @@
 			break
 		}
 		sz := auxIntToInt64(call_2.AuxInt)
-		if !(sz >= 0 && call.Uses == 1 && isSameCall(sym, "runtime.memmove") && dst.Type.IsPtr() && isInlinableMemmove(dst, src, int64(sz), config) && clobber(call)) {
+		if !(sz >= 0 && call.Uses == 1 && isSameCall(sym, "runtime.memmove") && isInlinableMemmove(dst, src, int64(sz), config) && clobber(call)) {
 			break
 		}
 		v.reset(OpMove)
 		v.AuxInt = int64ToAuxInt(int64(sz))
-		v.Aux = typeToAux(dst.Type.Elem())
+		v.Aux = typeToAux(types.Types[types.TUINT8])
 		v.AddArg3(dst, src, mem)
 		return true
 	}
 	// match: (SelectN [0] call:(StaticCall {sym} dst src (Const32 [sz]) mem))
-	// cond: sz >= 0 && call.Uses == 1 && isSameCall(sym, "runtime.memmove") && dst.Type.IsPtr() && isInlinableMemmove(dst, src, int64(sz), config) && clobber(call)
-	// result: (Move {dst.Type.Elem()} [int64(sz)] dst src mem)
+	// cond: sz >= 0 && call.Uses == 1 && isSameCall(sym, "runtime.memmove") && isInlinableMemmove(dst, src, int64(sz), config) && clobber(call)
+	// result: (Move {types.Types[types.TUINT8]} [int64(sz)] dst src mem)
 	for {
 		if auxIntToInt64(v.AuxInt) != 0 {
 			break
@@ -21453,18 +26545,18 @@
 			break
 		}
 		sz := auxIntToInt32(call_2.AuxInt)
-		if !(sz >= 0 && call.Uses == 1 && isSameCall(sym, "runtime.memmove") && dst.Type.IsPtr() && isInlinableMemmove(dst, src, int64(sz), config) && clobber(call)) {
+		if !(sz >= 0 && call.Uses == 1 && isSameCall(sym, "runtime.memmove") && isInlinableMemmove(dst, src, int64(sz), config) && clobber(call)) {
 			break
 		}
 		v.reset(OpMove)
 		v.AuxInt = int64ToAuxInt(int64(sz))
-		v.Aux = typeToAux(dst.Type.Elem())
+		v.Aux = typeToAux(types.Types[types.TUINT8])
 		v.AddArg3(dst, src, mem)
 		return true
 	}
 	// match: (SelectN [0] call:(StaticLECall {sym} dst src (Const64 [sz]) mem))
-	// cond: sz >= 0 && call.Uses == 1 && isSameCall(sym, "runtime.memmove") && dst.Type.IsPtr() && isInlinableMemmove(dst, src, int64(sz), config) && clobber(call)
-	// result: (Move {dst.Type.Elem()} [int64(sz)] dst src mem)
+	// cond: sz >= 0 && call.Uses == 1 && isSameCall(sym, "runtime.memmove") && isInlinableMemmove(dst, src, int64(sz), config) && clobber(call)
+	// result: (Move {types.Types[types.TUINT8]} [int64(sz)] dst src mem)
 	for {
 		if auxIntToInt64(v.AuxInt) != 0 {
 			break
@@ -21482,18 +26574,18 @@
 			break
 		}
 		sz := auxIntToInt64(call_2.AuxInt)
-		if !(sz >= 0 && call.Uses == 1 && isSameCall(sym, "runtime.memmove") && dst.Type.IsPtr() && isInlinableMemmove(dst, src, int64(sz), config) && clobber(call)) {
+		if !(sz >= 0 && call.Uses == 1 && isSameCall(sym, "runtime.memmove") && isInlinableMemmove(dst, src, int64(sz), config) && clobber(call)) {
 			break
 		}
 		v.reset(OpMove)
 		v.AuxInt = int64ToAuxInt(int64(sz))
-		v.Aux = typeToAux(dst.Type.Elem())
+		v.Aux = typeToAux(types.Types[types.TUINT8])
 		v.AddArg3(dst, src, mem)
 		return true
 	}
 	// match: (SelectN [0] call:(StaticLECall {sym} dst src (Const32 [sz]) mem))
-	// cond: sz >= 0 && call.Uses == 1 && isSameCall(sym, "runtime.memmove") && dst.Type.IsPtr() && isInlinableMemmove(dst, src, int64(sz), config) && clobber(call)
-	// result: (Move {dst.Type.Elem()} [int64(sz)] dst src mem)
+	// cond: sz >= 0 && call.Uses == 1 && isSameCall(sym, "runtime.memmove") && isInlinableMemmove(dst, src, int64(sz), config) && clobber(call)
+	// result: (Move {types.Types[types.TUINT8]} [int64(sz)] dst src mem)
 	for {
 		if auxIntToInt64(v.AuxInt) != 0 {
 			break
@@ -21511,12 +26603,12 @@
 			break
 		}
 		sz := auxIntToInt32(call_2.AuxInt)
-		if !(sz >= 0 && call.Uses == 1 && isSameCall(sym, "runtime.memmove") && dst.Type.IsPtr() && isInlinableMemmove(dst, src, int64(sz), config) && clobber(call)) {
+		if !(sz >= 0 && call.Uses == 1 && isSameCall(sym, "runtime.memmove") && isInlinableMemmove(dst, src, int64(sz), config) && clobber(call)) {
 			break
 		}
 		v.reset(OpMove)
 		v.AuxInt = int64ToAuxInt(int64(sz))
-		v.Aux = typeToAux(dst.Type.Elem())
+		v.Aux = typeToAux(types.Types[types.TUINT8])
 		v.AddArg3(dst, src, mem)
 		return true
 	}
@@ -21558,6 +26650,38 @@
 		v.copyOf(x)
 		return true
 	}
+	// match: (SelectN [1] (StaticCall {sym} _ newLen:(Const64) _ _ _ _))
+	// cond: v.Type.IsInteger() && isSameCall(sym, "runtime.growslice")
+	// result: newLen
+	for {
+		if auxIntToInt64(v.AuxInt) != 1 || v_0.Op != OpStaticCall || len(v_0.Args) != 6 {
+			break
+		}
+		sym := auxToCall(v_0.Aux)
+		_ = v_0.Args[1]
+		newLen := v_0.Args[1]
+		if newLen.Op != OpConst64 || !(v.Type.IsInteger() && isSameCall(sym, "runtime.growslice")) {
+			break
+		}
+		v.copyOf(newLen)
+		return true
+	}
+	// match: (SelectN [1] (StaticCall {sym} _ newLen:(Const32) _ _ _ _))
+	// cond: v.Type.IsInteger() && isSameCall(sym, "runtime.growslice")
+	// result: newLen
+	for {
+		if auxIntToInt64(v.AuxInt) != 1 || v_0.Op != OpStaticCall || len(v_0.Args) != 6 {
+			break
+		}
+		sym := auxToCall(v_0.Aux)
+		_ = v_0.Args[1]
+		newLen := v_0.Args[1]
+		if newLen.Op != OpConst32 || !(v.Type.IsInteger() && isSameCall(sym, "runtime.growslice")) {
+			break
+		}
+		v.copyOf(newLen)
+		return true
+	}
 	return false
 }
 func rewriteValuegeneric_OpSignExt16to32(v *Value) bool {
@@ -21914,6 +27038,46 @@
 		v.AddArg(x)
 		return true
 	}
+	// match: (SliceLen (SelectN [0] (StaticLECall {sym} _ newLen:(Const64) _ _ _ _)))
+	// cond: isSameCall(sym, "runtime.growslice")
+	// result: newLen
+	for {
+		if v_0.Op != OpSelectN || auxIntToInt64(v_0.AuxInt) != 0 {
+			break
+		}
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpStaticLECall || len(v_0_0.Args) != 6 {
+			break
+		}
+		sym := auxToCall(v_0_0.Aux)
+		_ = v_0_0.Args[1]
+		newLen := v_0_0.Args[1]
+		if newLen.Op != OpConst64 || !(isSameCall(sym, "runtime.growslice")) {
+			break
+		}
+		v.copyOf(newLen)
+		return true
+	}
+	// match: (SliceLen (SelectN [0] (StaticLECall {sym} _ newLen:(Const32) _ _ _ _)))
+	// cond: isSameCall(sym, "runtime.growslice")
+	// result: newLen
+	for {
+		if v_0.Op != OpSelectN || auxIntToInt64(v_0.AuxInt) != 0 {
+			break
+		}
+		v_0_0 := v_0.Args[0]
+		if v_0_0.Op != OpStaticLECall || len(v_0_0.Args) != 6 {
+			break
+		}
+		sym := auxToCall(v_0_0.Aux)
+		_ = v_0_0.Args[1]
+		newLen := v_0_0.Args[1]
+		if newLen.Op != OpConst32 || !(isSameCall(sym, "runtime.growslice")) {
+			break
+		}
+		v.copyOf(newLen)
+		return true
+	}
 	return false
 }
 func rewriteValuegeneric_OpSlicePtr(v *Value) bool {
@@ -24596,6 +29760,21 @@
 	}
 	return false
 }
+func rewriteValuegeneric_OpTrunc(v *Value) bool {
+	v_0 := v.Args[0]
+	// match: (Trunc (Const64F [c]))
+	// result: (Const64F [math.Trunc(c)])
+	for {
+		if v_0.Op != OpConst64F {
+			break
+		}
+		c := auxIntToFloat64(v_0.AuxInt)
+		v.reset(OpConst64F)
+		v.AuxInt = float64ToAuxInt(math.Trunc(c))
+		return true
+	}
+	return false
+}
 func rewriteValuegeneric_OpTrunc16to8(v *Value) bool {
 	v_0 := v.Args[0]
 	// match: (Trunc16to8 (Const16 [c]))
@@ -25048,6 +30227,7 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
+	config := b.Func.Config
 	// match: (Xor16 (Const16 [c]) (Const16 [d]))
 	// result: (Const16 [c^d])
 	for {
@@ -25204,12 +30384,321 @@
 		}
 		break
 	}
+	// match: (Xor16 (Lsh16x64 x z:(Const64 <t> [c])) (Rsh16Ux64 x (Const64 [d])))
+	// cond: c < 16 && d == 16-c && canRotate(config, 16)
+	// result: (RotateLeft16 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			if v_0.Op != OpLsh16x64 {
+				continue
+			}
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			z := v_0.Args[1]
+			if z.Op != OpConst64 {
+				continue
+			}
+			c := auxIntToInt64(z.AuxInt)
+			if v_1.Op != OpRsh16Ux64 {
+				continue
+			}
+			_ = v_1.Args[1]
+			if x != v_1.Args[0] {
+				continue
+			}
+			v_1_1 := v_1.Args[1]
+			if v_1_1.Op != OpConst64 {
+				continue
+			}
+			d := auxIntToInt64(v_1_1.AuxInt)
+			if !(c < 16 && d == 16-c && canRotate(config, 16)) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Xor16 left:(Lsh16x64 x y) right:(Rsh16Ux64 x (Sub64 (Const64 [16]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)
+	// result: (RotateLeft16 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh16x64 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh16Ux64 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub64 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst64 || auxIntToInt64(right_1_0.AuxInt) != 16 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Xor16 left:(Lsh16x32 x y) right:(Rsh16Ux32 x (Sub32 (Const32 [16]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)
+	// result: (RotateLeft16 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh16x32 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh16Ux32 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub32 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst32 || auxIntToInt32(right_1_0.AuxInt) != 16 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Xor16 left:(Lsh16x16 x y) right:(Rsh16Ux16 x (Sub16 (Const16 [16]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)
+	// result: (RotateLeft16 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh16x16 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh16Ux16 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub16 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst16 || auxIntToInt16(right_1_0.AuxInt) != 16 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Xor16 left:(Lsh16x8 x y) right:(Rsh16Ux8 x (Sub8 (Const8 [16]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)
+	// result: (RotateLeft16 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh16x8 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh16Ux8 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub8 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst8 || auxIntToInt8(right_1_0.AuxInt) != 16 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Xor16 right:(Rsh16Ux64 x y) left:(Lsh16x64 x z:(Sub64 (Const64 [16]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)
+	// result: (RotateLeft16 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh16Ux64 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh16x64 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub64 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst64 || auxIntToInt64(z_0.AuxInt) != 16 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Xor16 right:(Rsh16Ux32 x y) left:(Lsh16x32 x z:(Sub32 (Const32 [16]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)
+	// result: (RotateLeft16 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh16Ux32 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh16x32 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub32 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst32 || auxIntToInt32(z_0.AuxInt) != 16 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Xor16 right:(Rsh16Ux16 x y) left:(Lsh16x16 x z:(Sub16 (Const16 [16]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)
+	// result: (RotateLeft16 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh16Ux16 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh16x16 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub16 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst16 || auxIntToInt16(z_0.AuxInt) != 16 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Xor16 right:(Rsh16Ux8 x y) left:(Lsh16x8 x z:(Sub8 (Const8 [16]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)
+	// result: (RotateLeft16 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh16Ux8 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh16x8 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub8 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst8 || auxIntToInt8(z_0.AuxInt) != 16 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 16)) {
+				continue
+			}
+			v.reset(OpRotateLeft16)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
 	return false
 }
 func rewriteValuegeneric_OpXor32(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
+	config := b.Func.Config
 	// match: (Xor32 (Const32 [c]) (Const32 [d]))
 	// result: (Const32 [c^d])
 	for {
@@ -25366,12 +30855,321 @@
 		}
 		break
 	}
+	// match: (Xor32 (Lsh32x64 x z:(Const64 <t> [c])) (Rsh32Ux64 x (Const64 [d])))
+	// cond: c < 32 && d == 32-c && canRotate(config, 32)
+	// result: (RotateLeft32 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			if v_0.Op != OpLsh32x64 {
+				continue
+			}
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			z := v_0.Args[1]
+			if z.Op != OpConst64 {
+				continue
+			}
+			c := auxIntToInt64(z.AuxInt)
+			if v_1.Op != OpRsh32Ux64 {
+				continue
+			}
+			_ = v_1.Args[1]
+			if x != v_1.Args[0] {
+				continue
+			}
+			v_1_1 := v_1.Args[1]
+			if v_1_1.Op != OpConst64 {
+				continue
+			}
+			d := auxIntToInt64(v_1_1.AuxInt)
+			if !(c < 32 && d == 32-c && canRotate(config, 32)) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Xor32 left:(Lsh32x64 x y) right:(Rsh32Ux64 x (Sub64 (Const64 [32]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)
+	// result: (RotateLeft32 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh32x64 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh32Ux64 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub64 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst64 || auxIntToInt64(right_1_0.AuxInt) != 32 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Xor32 left:(Lsh32x32 x y) right:(Rsh32Ux32 x (Sub32 (Const32 [32]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)
+	// result: (RotateLeft32 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh32x32 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh32Ux32 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub32 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst32 || auxIntToInt32(right_1_0.AuxInt) != 32 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Xor32 left:(Lsh32x16 x y) right:(Rsh32Ux16 x (Sub16 (Const16 [32]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)
+	// result: (RotateLeft32 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh32x16 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh32Ux16 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub16 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst16 || auxIntToInt16(right_1_0.AuxInt) != 32 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Xor32 left:(Lsh32x8 x y) right:(Rsh32Ux8 x (Sub8 (Const8 [32]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)
+	// result: (RotateLeft32 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh32x8 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh32Ux8 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub8 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst8 || auxIntToInt8(right_1_0.AuxInt) != 32 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Xor32 right:(Rsh32Ux64 x y) left:(Lsh32x64 x z:(Sub64 (Const64 [32]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)
+	// result: (RotateLeft32 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh32Ux64 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh32x64 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub64 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst64 || auxIntToInt64(z_0.AuxInt) != 32 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Xor32 right:(Rsh32Ux32 x y) left:(Lsh32x32 x z:(Sub32 (Const32 [32]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)
+	// result: (RotateLeft32 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh32Ux32 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh32x32 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub32 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst32 || auxIntToInt32(z_0.AuxInt) != 32 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Xor32 right:(Rsh32Ux16 x y) left:(Lsh32x16 x z:(Sub16 (Const16 [32]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)
+	// result: (RotateLeft32 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh32Ux16 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh32x16 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub16 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst16 || auxIntToInt16(z_0.AuxInt) != 32 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Xor32 right:(Rsh32Ux8 x y) left:(Lsh32x8 x z:(Sub8 (Const8 [32]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)
+	// result: (RotateLeft32 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh32Ux8 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh32x8 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub8 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst8 || auxIntToInt8(z_0.AuxInt) != 32 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 32)) {
+				continue
+			}
+			v.reset(OpRotateLeft32)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
 	return false
 }
 func rewriteValuegeneric_OpXor64(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
+	config := b.Func.Config
 	// match: (Xor64 (Const64 [c]) (Const64 [d]))
 	// result: (Const64 [c^d])
 	for {
@@ -25528,12 +31326,321 @@
 		}
 		break
 	}
+	// match: (Xor64 (Lsh64x64 x z:(Const64 <t> [c])) (Rsh64Ux64 x (Const64 [d])))
+	// cond: c < 64 && d == 64-c && canRotate(config, 64)
+	// result: (RotateLeft64 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			if v_0.Op != OpLsh64x64 {
+				continue
+			}
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			z := v_0.Args[1]
+			if z.Op != OpConst64 {
+				continue
+			}
+			c := auxIntToInt64(z.AuxInt)
+			if v_1.Op != OpRsh64Ux64 {
+				continue
+			}
+			_ = v_1.Args[1]
+			if x != v_1.Args[0] {
+				continue
+			}
+			v_1_1 := v_1.Args[1]
+			if v_1_1.Op != OpConst64 {
+				continue
+			}
+			d := auxIntToInt64(v_1_1.AuxInt)
+			if !(c < 64 && d == 64-c && canRotate(config, 64)) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Xor64 left:(Lsh64x64 x y) right:(Rsh64Ux64 x (Sub64 (Const64 [64]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)
+	// result: (RotateLeft64 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh64x64 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh64Ux64 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub64 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst64 || auxIntToInt64(right_1_0.AuxInt) != 64 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Xor64 left:(Lsh64x32 x y) right:(Rsh64Ux32 x (Sub32 (Const32 [64]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)
+	// result: (RotateLeft64 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh64x32 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh64Ux32 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub32 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst32 || auxIntToInt32(right_1_0.AuxInt) != 64 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Xor64 left:(Lsh64x16 x y) right:(Rsh64Ux16 x (Sub16 (Const16 [64]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)
+	// result: (RotateLeft64 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh64x16 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh64Ux16 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub16 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst16 || auxIntToInt16(right_1_0.AuxInt) != 64 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Xor64 left:(Lsh64x8 x y) right:(Rsh64Ux8 x (Sub8 (Const8 [64]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)
+	// result: (RotateLeft64 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh64x8 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh64Ux8 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub8 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst8 || auxIntToInt8(right_1_0.AuxInt) != 64 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Xor64 right:(Rsh64Ux64 x y) left:(Lsh64x64 x z:(Sub64 (Const64 [64]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)
+	// result: (RotateLeft64 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh64Ux64 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh64x64 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub64 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst64 || auxIntToInt64(z_0.AuxInt) != 64 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Xor64 right:(Rsh64Ux32 x y) left:(Lsh64x32 x z:(Sub32 (Const32 [64]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)
+	// result: (RotateLeft64 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh64Ux32 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh64x32 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub32 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst32 || auxIntToInt32(z_0.AuxInt) != 64 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Xor64 right:(Rsh64Ux16 x y) left:(Lsh64x16 x z:(Sub16 (Const16 [64]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)
+	// result: (RotateLeft64 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh64Ux16 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh64x16 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub16 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst16 || auxIntToInt16(z_0.AuxInt) != 64 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Xor64 right:(Rsh64Ux8 x y) left:(Lsh64x8 x z:(Sub8 (Const8 [64]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)
+	// result: (RotateLeft64 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh64Ux8 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh64x8 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub8 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst8 || auxIntToInt8(z_0.AuxInt) != 64 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 64)) {
+				continue
+			}
+			v.reset(OpRotateLeft64)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
 	return false
 }
 func rewriteValuegeneric_OpXor8(v *Value) bool {
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	b := v.Block
+	config := b.Func.Config
 	// match: (Xor8 (Const8 [c]) (Const8 [d]))
 	// result: (Const8 [c^d])
 	for {
@@ -25690,6 +31797,314 @@
 		}
 		break
 	}
+	// match: (Xor8 (Lsh8x64 x z:(Const64 <t> [c])) (Rsh8Ux64 x (Const64 [d])))
+	// cond: c < 8 && d == 8-c && canRotate(config, 8)
+	// result: (RotateLeft8 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			if v_0.Op != OpLsh8x64 {
+				continue
+			}
+			_ = v_0.Args[1]
+			x := v_0.Args[0]
+			z := v_0.Args[1]
+			if z.Op != OpConst64 {
+				continue
+			}
+			c := auxIntToInt64(z.AuxInt)
+			if v_1.Op != OpRsh8Ux64 {
+				continue
+			}
+			_ = v_1.Args[1]
+			if x != v_1.Args[0] {
+				continue
+			}
+			v_1_1 := v_1.Args[1]
+			if v_1_1.Op != OpConst64 {
+				continue
+			}
+			d := auxIntToInt64(v_1_1.AuxInt)
+			if !(c < 8 && d == 8-c && canRotate(config, 8)) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Xor8 left:(Lsh8x64 x y) right:(Rsh8Ux64 x (Sub64 (Const64 [8]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)
+	// result: (RotateLeft8 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh8x64 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh8Ux64 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub64 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst64 || auxIntToInt64(right_1_0.AuxInt) != 8 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Xor8 left:(Lsh8x32 x y) right:(Rsh8Ux32 x (Sub32 (Const32 [8]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)
+	// result: (RotateLeft8 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh8x32 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh8Ux32 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub32 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst32 || auxIntToInt32(right_1_0.AuxInt) != 8 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Xor8 left:(Lsh8x16 x y) right:(Rsh8Ux16 x (Sub16 (Const16 [8]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)
+	// result: (RotateLeft8 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh8x16 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh8Ux16 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub16 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst16 || auxIntToInt16(right_1_0.AuxInt) != 8 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Xor8 left:(Lsh8x8 x y) right:(Rsh8Ux8 x (Sub8 (Const8 [8]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)
+	// result: (RotateLeft8 x y)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			left := v_0
+			if left.Op != OpLsh8x8 {
+				continue
+			}
+			y := left.Args[1]
+			x := left.Args[0]
+			right := v_1
+			if right.Op != OpRsh8Ux8 {
+				continue
+			}
+			_ = right.Args[1]
+			if x != right.Args[0] {
+				continue
+			}
+			right_1 := right.Args[1]
+			if right_1.Op != OpSub8 {
+				continue
+			}
+			_ = right_1.Args[1]
+			right_1_0 := right_1.Args[0]
+			if right_1_0.Op != OpConst8 || auxIntToInt8(right_1_0.AuxInt) != 8 || y != right_1.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v.AddArg2(x, y)
+			return true
+		}
+		break
+	}
+	// match: (Xor8 right:(Rsh8Ux64 x y) left:(Lsh8x64 x z:(Sub64 (Const64 [8]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)
+	// result: (RotateLeft8 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh8Ux64 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh8x64 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub64 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst64 || auxIntToInt64(z_0.AuxInt) != 8 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Xor8 right:(Rsh8Ux32 x y) left:(Lsh8x32 x z:(Sub32 (Const32 [8]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)
+	// result: (RotateLeft8 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh8Ux32 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh8x32 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub32 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst32 || auxIntToInt32(z_0.AuxInt) != 8 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Xor8 right:(Rsh8Ux16 x y) left:(Lsh8x16 x z:(Sub16 (Const16 [8]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)
+	// result: (RotateLeft8 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh8Ux16 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh8x16 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub16 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst16 || auxIntToInt16(z_0.AuxInt) != 8 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
+	// match: (Xor8 right:(Rsh8Ux8 x y) left:(Lsh8x8 x z:(Sub8 (Const8 [8]) y)))
+	// cond: (shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)
+	// result: (RotateLeft8 x z)
+	for {
+		for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
+			right := v_0
+			if right.Op != OpRsh8Ux8 {
+				continue
+			}
+			y := right.Args[1]
+			x := right.Args[0]
+			left := v_1
+			if left.Op != OpLsh8x8 {
+				continue
+			}
+			_ = left.Args[1]
+			if x != left.Args[0] {
+				continue
+			}
+			z := left.Args[1]
+			if z.Op != OpSub8 {
+				continue
+			}
+			_ = z.Args[1]
+			z_0 := z.Args[0]
+			if z_0.Op != OpConst8 || auxIntToInt8(z_0.AuxInt) != 8 || y != z.Args[1] || !((shiftIsBounded(left) || shiftIsBounded(right)) && canRotate(config, 8)) {
+				continue
+			}
+			v.reset(OpRotateLeft8)
+			v.AddArg2(x, z)
+			return true
+		}
+		break
+	}
 	return false
 }
 func rewriteValuegeneric_OpZero(v *Value) bool {
diff --git a/src/cmd/compile/internal/ssa/schedule.go b/src/cmd/compile/internal/ssa/schedule.go
index 2b74c9e..4e762f7 100644
--- a/src/cmd/compile/internal/ssa/schedule.go
+++ b/src/cmd/compile/internal/ssa/schedule.go
@@ -14,9 +14,9 @@
 	ScorePhi = iota // towards top of block
 	ScoreArg
 	ScoreNilCheck
-	ScoreCarryChainTail
 	ScoreReadTuple
 	ScoreVarDef
+	ScoreCarryChainTail
 	ScoreMemory
 	ScoreReadFlags
 	ScoreDefault
@@ -94,13 +94,15 @@
 func schedule(f *Func) {
 	// For each value, the number of times it is used in the block
 	// by values that have not been scheduled yet.
-	uses := make([]int32, f.NumValues())
+	uses := f.Cache.allocInt32Slice(f.NumValues())
+	defer f.Cache.freeInt32Slice(uses)
 
 	// reusable priority queue
 	priq := new(ValHeap)
 
 	// "priority" for a value
-	score := make([]int8, f.NumValues())
+	score := f.Cache.allocInt8Slice(f.NumValues())
+	defer f.Cache.freeInt8Slice(score)
 
 	// scheduling order. We queue values in this list in reverse order.
 	// A constant bound allows this to be stack-allocated. 64 is
@@ -108,7 +110,8 @@
 	order := make([]*Value, 0, 64)
 
 	// maps mem values to the next live memory value
-	nextMem := make([]*Value, f.NumValues())
+	nextMem := f.Cache.allocValueSlice(f.NumValues())
+	defer f.Cache.freeValueSlice(nextMem)
 	// additional pretend arguments for each Value. Used to enforce load/store ordering.
 	additionalArgs := make([][]*Value, f.NumValues())
 
@@ -155,22 +158,16 @@
 				// VARDEF ops are scheduled before the corresponding LEA.
 				score[v.ID] = ScoreMemory
 			case v.Op == OpSelect0 || v.Op == OpSelect1 || v.Op == OpSelectN:
-				// Schedule the pseudo-op of reading part of a tuple
-				// immediately after the tuple-generating op, since
-				// this value is already live. This also removes its
-				// false dependency on the other part of the tuple.
-				// Also ensures tuple is never spilled.
-				if (v.Op == OpSelect1 || v.Op == OpSelect0) && v.Args[0].Op.isCarry() {
-					// Score tuple ops of carry ops later to ensure they do not
-					// delay scheduling the tuple-generating op. If such tuple ops
-					// are not placed more readily, unrelated carry clobbering ops
-					// may be placed inbetween two carry-dependent operations.
+				if (v.Op == OpSelect1 || v.Op == OpSelect0) && (v.Args[0].isCarry() || v.Type.IsFlags()) {
+					// When the Select pseudo op is being used for a carry or flag from
+					// a tuple then score it as ScoreFlags so it happens later. This
+					// prevents the bit from being clobbered before it is used.
 					score[v.ID] = ScoreFlags
 				} else {
 					score[v.ID] = ScoreReadTuple
 				}
-			case v.Op.isCarry():
-				if w := v.getCarryProducer(); w != nil {
+			case v.isCarry():
+				if w := v.getCarryInput(); w != nil && w.Block == b {
 					// The producing op is not the final user of the carry bit. Its
 					// current score is one of unscored, Flags, or CarryChainTail.
 					// These occur if the producer has not been scored, another user
@@ -179,7 +176,7 @@
 					// scored CarryChainTail (and prove w is not a tail).
 					score[w.ID] = ScoreFlags
 				}
-				// Verify v has not been scored. If v has not been visited, v may be the
+				// Verify v has not been scored. If v has not been visited, v may be
 				// the final (tail) operation in a carry chain. If v is not, v will be
 				// rescored above when v's carry-using op is scored. When scoring is done,
 				// only tail operations will retain the CarryChainTail score.
@@ -189,7 +186,7 @@
 					// one chain to be scheduled, if possible.
 					score[v.ID] = ScoreCarryChainTail
 				}
-			case v.Type.IsFlags() || v.Type.IsTuple() && v.Type.FieldType(1).IsFlags():
+			case v.isFlagOp():
 				// Schedule flag register generation as late as possible.
 				// This makes sure that we only have one live flags
 				// value at a time.
@@ -198,7 +195,7 @@
 				score[v.ID] = ScoreDefault
 				// If we're reading flags, schedule earlier to keep flag lifetime short.
 				for _, a := range v.Args {
-					if a.Type.IsFlags() {
+					if a.isFlagOp() {
 						score[v.ID] = ScoreReadFlags
 					}
 				}
@@ -269,7 +266,6 @@
 					}
 				}
 			}
-
 		}
 
 		// To put things into a priority queue
@@ -293,7 +289,7 @@
 
 			v := heap.Pop(priq).(*Value)
 
-			if f.pass.debug > 1 && score[v.ID] == ScoreCarryChainTail && v.Op.isCarry() {
+			if f.pass.debug > 1 && score[v.ID] == ScoreCarryChainTail && v.isCarry() {
 				// Add some debugging noise if the chain of carrying ops will not
 				// likely be scheduled without potential carry flag clobbers.
 				if !isCarryChainReady(v, uses) {
@@ -557,42 +553,74 @@
 	return order
 }
 
-// Return whether all dependent carry ops can be scheduled after this.
+// isFlagOp reports if v is an OP with the flag type.
+func (v *Value) isFlagOp() bool {
+	return v.Type.IsFlags() || v.Type.IsTuple() && v.Type.FieldType(1).IsFlags()
+}
+
+// isCarryChainReady reports whether all dependent carry ops can be scheduled after this.
 func isCarryChainReady(v *Value, uses []int32) bool {
 	// A chain can be scheduled in it's entirety if
 	// the use count of each dependent op is 1. If none,
 	// schedule the first.
 	j := 1 // The first op uses[k.ID] == 0. Dependent ops are always >= 1.
-	for k := v; k != nil; k = k.getCarryProducer() {
+	for k := v; k != nil; k = k.getCarryInput() {
 		j += int(uses[k.ID]) - 1
 	}
 	return j == 0
 }
 
-// Return whether op is an operation which produces a carry bit value, but does not consume it.
-func (op Op) isCarryCreator() bool {
-	switch op {
-	case OpPPC64SUBC, OpPPC64ADDC, OpPPC64SUBCconst, OpPPC64ADDCconst:
-		return true
-	}
-	return false
+// isCarryInput reports whether v accepts a carry value as input.
+func (v *Value) isCarryInput() bool {
+	return v.getCarryInput() != nil
 }
 
-// Return whether op consumes or creates a carry a bit value.
-func (op Op) isCarry() bool {
-	switch op {
-	case OpPPC64SUBE, OpPPC64ADDE, OpPPC64SUBZEzero, OpPPC64ADDZEzero:
-		return true
+// isCarryOutput reports whether v generates a carry as output.
+func (v *Value) isCarryOutput() bool {
+	// special cases for PPC64 which put their carry values in XER instead of flags
+	switch v.Block.Func.Config.arch {
+	case "ppc64", "ppc64le":
+		switch v.Op {
+		case OpPPC64SUBC, OpPPC64ADDC, OpPPC64SUBCconst, OpPPC64ADDCconst:
+			return true
+		}
+		return false
 	}
-	return op.isCarryCreator()
+	return v.isFlagOp() && v.Op != OpSelect1
 }
 
-// Return the producing *Value of the carry bit of this op, or nil if none.
-func (v *Value) getCarryProducer() *Value {
-	if v.Op.isCarry() && !v.Op.isCarryCreator() {
-		// PPC64 carry dependencies are conveyed through their final argument.
-		// Likewise, there is always an OpSelect1 between them.
-		return v.Args[len(v.Args)-1].Args[0]
+// isCarryCreator reports whether op is an operation which produces a carry bit value,
+// but does not consume it.
+func (v *Value) isCarryCreator() bool {
+	return v.isCarryOutput() && !v.isCarryInput()
+}
+
+// isCarry reports whether op consumes or creates a carry a bit value.
+func (v *Value) isCarry() bool {
+	return v.isCarryOutput() || v.isCarryInput()
+}
+
+// getCarryInput returns the producing *Value of the carry bit of this op, or nil if none.
+func (v *Value) getCarryInput() *Value {
+	// special cases for PPC64 which put their carry values in XER instead of flags
+	switch v.Block.Func.Config.arch {
+	case "ppc64", "ppc64le":
+		switch v.Op {
+		case OpPPC64SUBE, OpPPC64ADDE, OpPPC64SUBZEzero, OpPPC64ADDZEzero:
+			// PPC64 carry dependencies are conveyed through their final argument.
+			// Likewise, there is always an OpSelect1 between them.
+			return v.Args[len(v.Args)-1].Args[0]
+		}
+		return nil
+	}
+	for _, a := range v.Args {
+		if !a.isFlagOp() {
+			continue
+		}
+		if a.Op == OpSelect1 {
+			a = a.Args[0]
+		}
+		return a
 	}
 	return nil
 }
diff --git a/src/cmd/compile/internal/ssa/schedule_test.go b/src/cmd/compile/internal/ssa/schedule_test.go
index f7177dd..6cf5105 100644
--- a/src/cmd/compile/internal/ssa/schedule_test.go
+++ b/src/cmd/compile/internal/ssa/schedule_test.go
@@ -99,3 +99,62 @@
 		t.Errorf("store order is wrong: got %v, want v2 v3 v4 after v5", order)
 	}
 }
+
+func TestCarryChainOrder(t *testing.T) {
+	// In the function below, there are two carry chains that have no dependencies on each other,
+	// one is A1 -> A1carry -> A1Carryvalue, the other is A2 -> A2carry -> A2Carryvalue. If they
+	// are not scheduled properly, the carry will be clobbered, causing the carry to be regenerated.
+	c := testConfigARM64(t)
+	fun := c.Fun("entry",
+		Bloc("entry",
+			Valu("mem0", OpInitMem, types.TypeMem, 0, nil),
+			Valu("x", OpARM64MOVDconst, c.config.Types.UInt64, 5, nil),
+			Valu("y", OpARM64MOVDconst, c.config.Types.UInt64, 6, nil),
+			Valu("z", OpARM64MOVDconst, c.config.Types.UInt64, 7, nil),
+			Valu("A1", OpARM64ADDSflags, types.NewTuple(c.config.Types.UInt64, types.TypeFlags), 0, nil, "x", "z"), // x+z, set flags
+			Valu("A1carry", OpSelect1, types.TypeFlags, 0, nil, "A1"),
+			Valu("A2", OpARM64ADDSflags, types.NewTuple(c.config.Types.UInt64, types.TypeFlags), 0, nil, "y", "z"), // y+z, set flags
+			Valu("A2carry", OpSelect1, types.TypeFlags, 0, nil, "A2"),
+			Valu("A1value", OpSelect0, c.config.Types.UInt64, 0, nil, "A1"),
+			Valu("A1Carryvalue", OpARM64ADCzerocarry, c.config.Types.UInt64, 0, nil, "A1carry"), // 0+0+A1carry
+			Valu("A2value", OpSelect0, c.config.Types.UInt64, 0, nil, "A2"),
+			Valu("A2Carryvalue", OpARM64ADCzerocarry, c.config.Types.UInt64, 0, nil, "A2carry"), // 0+0+A2carry
+			Valu("ValueSum", OpARM64ADD, c.config.Types.UInt64, 0, nil, "A1value", "A2value"),
+			Valu("CarrySum", OpARM64ADD, c.config.Types.UInt64, 0, nil, "A1Carryvalue", "A2Carryvalue"),
+			Valu("Sum", OpARM64AND, c.config.Types.UInt64, 0, nil, "ValueSum", "CarrySum"),
+			Goto("exit")),
+		Bloc("exit",
+			Exit("mem0")),
+	)
+
+	CheckFunc(fun.f)
+	schedule(fun.f)
+
+	// The expected order is A1 < A1carry < A1Carryvalue < A2 < A2carry < A2Carryvalue.
+	// There is no dependency between the two carry chains, so it doesn't matter which
+	// comes first and which comes after, but the unsorted position of A1 is before A2,
+	// so A1Carryvalue < A2.
+	var ai, bi, ci, di, ei, fi int
+	for i, v := range fun.f.Blocks[0].Values {
+		switch {
+		case fun.values["A1"] == v:
+			ai = i
+		case fun.values["A1carry"] == v:
+			bi = i
+		case fun.values["A1Carryvalue"] == v:
+			ci = i
+		case fun.values["A2"] == v:
+			di = i
+		case fun.values["A2carry"] == v:
+			ei = i
+		case fun.values["A2Carryvalue"] == v:
+			fi = i
+		}
+	}
+	if !(ai < bi && bi < ci && ci < di && di < ei && ei < fi) {
+		t.Logf("Func: %s", fun.f)
+		t.Errorf("carry chain order is wrong: got %v, want V%d after V%d after V%d after V%d after V%d after V%d,",
+			fun.f.Blocks[0], fun.values["A1"].ID, fun.values["A1carry"].ID, fun.values["A1Carryvalue"].ID,
+			fun.values["A2"].ID, fun.values["A2carry"].ID, fun.values["A2Carryvalue"].ID)
+	}
+}
diff --git a/src/cmd/compile/internal/ssa/shortcircuit.go b/src/cmd/compile/internal/ssa/shortcircuit.go
index 5f1f892..d7d0b6f 100644
--- a/src/cmd/compile/internal/ssa/shortcircuit.go
+++ b/src/cmd/compile/internal/ssa/shortcircuit.go
@@ -4,7 +4,7 @@
 
 package ssa
 
-// Shortcircuit finds situations where branch directions
+// shortcircuit finds situations where branch directions
 // are always correlated and rewrites the CFG to take
 // advantage of that fact.
 // This optimization is useful for compiling && and || expressions.
diff --git a/src/cmd/compile/internal/ssa/sparsemap.go b/src/cmd/compile/internal/ssa/sparsemap.go
index f55db54..9443c8b 100644
--- a/src/cmd/compile/internal/ssa/sparsemap.go
+++ b/src/cmd/compile/internal/ssa/sparsemap.go
@@ -4,15 +4,12 @@
 
 package ssa
 
-import "cmd/internal/src"
-
 // from https://research.swtch.com/sparse
 // in turn, from Briggs and Torczon
 
 type sparseEntry struct {
 	key ID
 	val int32
-	aux src.XPos
 }
 
 type sparseMap struct {
@@ -49,14 +46,13 @@
 	return -1
 }
 
-func (s *sparseMap) set(k ID, v int32, a src.XPos) {
+func (s *sparseMap) set(k ID, v int32) {
 	i := s.sparse[k]
 	if i < int32(len(s.dense)) && s.dense[i].key == k {
 		s.dense[i].val = v
-		s.dense[i].aux = a
 		return
 	}
-	s.dense = append(s.dense, sparseEntry{k, v, a})
+	s.dense = append(s.dense, sparseEntry{k, v})
 	s.sparse[k] = int32(len(s.dense)) - 1
 }
 
@@ -70,7 +66,7 @@
 		s.dense[i].val |= 1 << v
 		return
 	}
-	s.dense = append(s.dense, sparseEntry{k, 1 << v, src.NoXPos})
+	s.dense = append(s.dense, sparseEntry{k, 1 << v})
 	s.sparse[k] = int32(len(s.dense)) - 1
 }
 
diff --git a/src/cmd/compile/internal/ssa/sparsemappos.go b/src/cmd/compile/internal/ssa/sparsemappos.go
new file mode 100644
index 0000000..60bad82
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/sparsemappos.go
@@ -0,0 +1,79 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssa
+
+import "cmd/internal/src"
+
+// from https://research.swtch.com/sparse
+// in turn, from Briggs and Torczon
+
+type sparseEntryPos struct {
+	key ID
+	val int32
+	pos src.XPos
+}
+
+type sparseMapPos struct {
+	dense  []sparseEntryPos
+	sparse []int32
+}
+
+// newSparseMapPos returns a sparseMapPos that can map
+// integers between 0 and n-1 to the pair <int32,src.XPos>.
+func newSparseMapPos(n int) *sparseMapPos {
+	return &sparseMapPos{dense: nil, sparse: make([]int32, n)}
+}
+
+func (s *sparseMapPos) cap() int {
+	return len(s.sparse)
+}
+
+func (s *sparseMapPos) size() int {
+	return len(s.dense)
+}
+
+func (s *sparseMapPos) contains(k ID) bool {
+	i := s.sparse[k]
+	return i < int32(len(s.dense)) && s.dense[i].key == k
+}
+
+// get returns the value for key k, or -1 if k does
+// not appear in the map.
+func (s *sparseMapPos) get(k ID) int32 {
+	i := s.sparse[k]
+	if i < int32(len(s.dense)) && s.dense[i].key == k {
+		return s.dense[i].val
+	}
+	return -1
+}
+
+func (s *sparseMapPos) set(k ID, v int32, a src.XPos) {
+	i := s.sparse[k]
+	if i < int32(len(s.dense)) && s.dense[i].key == k {
+		s.dense[i].val = v
+		s.dense[i].pos = a
+		return
+	}
+	s.dense = append(s.dense, sparseEntryPos{k, v, a})
+	s.sparse[k] = int32(len(s.dense)) - 1
+}
+
+func (s *sparseMapPos) remove(k ID) {
+	i := s.sparse[k]
+	if i < int32(len(s.dense)) && s.dense[i].key == k {
+		y := s.dense[len(s.dense)-1]
+		s.dense[i] = y
+		s.sparse[y.key] = i
+		s.dense = s.dense[:len(s.dense)-1]
+	}
+}
+
+func (s *sparseMapPos) clear() {
+	s.dense = s.dense[:0]
+}
+
+func (s *sparseMapPos) contents() []sparseEntryPos {
+	return s.dense
+}
diff --git a/src/cmd/compile/internal/ssa/sparseset.go b/src/cmd/compile/internal/ssa/sparseset.go
index 395931d..07d40dc 100644
--- a/src/cmd/compile/internal/ssa/sparseset.go
+++ b/src/cmd/compile/internal/ssa/sparseset.go
@@ -13,7 +13,7 @@
 }
 
 // newSparseSet returns a sparseSet that can represent
-// integers between 0 and n-1
+// integers between 0 and n-1.
 func newSparseSet(n int) *sparseSet {
 	return &sparseSet{dense: nil, sparse: make([]int32, n)}
 }
diff --git a/src/cmd/compile/internal/ssa/sparsetree.go b/src/cmd/compile/internal/ssa/sparsetree.go
index 9f4e000..6f2bd04 100644
--- a/src/cmd/compile/internal/ssa/sparsetree.go
+++ b/src/cmd/compile/internal/ssa/sparsetree.go
@@ -55,7 +55,7 @@
 // such as whether one block dominates another.
 type SparseTree []SparseTreeNode
 
-// newSparseTree creates a SparseTree from a block-to-parent map (array indexed by Block.ID)
+// newSparseTree creates a SparseTree from a block-to-parent map (array indexed by Block.ID).
 func newSparseTree(f *Func, parentOf []*Block) SparseTree {
 	t := make(SparseTree, f.NumBlocks())
 	for _, b := range f.Blocks {
@@ -184,7 +184,7 @@
 	return t[x.ID].parent
 }
 
-// isAncestorEq reports whether x is an ancestor of or equal to y.
+// IsAncestorEq reports whether x is an ancestor of or equal to y.
 func (t SparseTree) IsAncestorEq(x, y *Block) bool {
 	if x == y {
 		return true
diff --git a/src/cmd/compile/internal/ssa/stackalloc.go b/src/cmd/compile/internal/ssa/stackalloc.go
index d41f399..3e24b48 100644
--- a/src/cmd/compile/internal/ssa/stackalloc.go
+++ b/src/cmd/compile/internal/ssa/stackalloc.go
@@ -25,8 +25,6 @@
 	values    []stackValState
 	interfere [][]ID // interfere[v.id] = values that interfere with v.
 	names     []LocalSlot
-	slots     []int
-	used      []bool
 
 	nArgSlot, // Number of Values sourced to arg slot
 	nNotNeed, // Number of Values not needing a stack slot
@@ -57,12 +55,6 @@
 	for i := range s.names {
 		s.names[i] = LocalSlot{}
 	}
-	for i := range s.slots {
-		s.slots[i] = 0
-	}
-	for i := range s.used {
-		s.used[i] = false
-	}
 	s.f.Cache.stackAllocState = s
 	s.f = nil
 	s.live = nil
@@ -218,25 +210,15 @@
 
 	// Each time we assign a stack slot to a value v, we remember
 	// the slot we used via an index into locations[v.Type].
-	slots := s.slots
-	if n := f.NumValues(); cap(slots) >= n {
-		slots = slots[:n]
-	} else {
-		slots = make([]int, n)
-		s.slots = slots
-	}
+	slots := f.Cache.allocIntSlice(f.NumValues())
+	defer f.Cache.freeIntSlice(slots)
 	for i := range slots {
 		slots[i] = -1
 	}
 
 	// Pick a stack slot for each value needing one.
-	var used []bool
-	if n := f.NumValues(); cap(s.used) >= n {
-		used = s.used[:n]
-	} else {
-		used = make([]bool, n)
-		s.used = used
-	}
+	used := f.Cache.allocBoolSlice(f.NumValues())
+	defer f.Cache.freeBoolSlice(used)
 	for _, b := range f.Blocks {
 		for _, v := range b.Values {
 			if !s.values[v.ID].needSlot {
diff --git a/src/cmd/compile/internal/ssa/stmtlines_test.go b/src/cmd/compile/internal/ssa/stmtlines_test.go
index 673c88a..4dadfe8 100644
--- a/src/cmd/compile/internal/ssa/stmtlines_test.go
+++ b/src/cmd/compile/internal/ssa/stmtlines_test.go
@@ -1,3 +1,7 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
 package ssa_test
 
 import (
diff --git a/src/cmd/compile/internal/ssa/testdata/b53456.go b/src/cmd/compile/internal/ssa/testdata/b53456.go
new file mode 100644
index 0000000..8104d3e
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/testdata/b53456.go
@@ -0,0 +1,19 @@
+package main
+
+type T struct {
+	m map[int]int
+}
+
+func main() {
+	t := T{
+		m: make(map[int]int),
+	}
+	t.Inc(5)
+	t.Inc(7)
+}
+
+func (s *T) Inc(key int) {
+	v := s.m[key] // break, line 16
+	v++
+	s.m[key] = v // also here
+}
diff --git a/src/cmd/compile/internal/ssa/testdata/fma.go b/src/cmd/compile/internal/ssa/testdata/fma.go
new file mode 100644
index 0000000..13a7ff1
--- /dev/null
+++ b/src/cmd/compile/internal/ssa/testdata/fma.go
@@ -0,0 +1,37 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"fmt"
+	"os"
+)
+
+//go:noinline
+func f(x float64) float64 {
+	return x
+}
+
+func inlineFma(x, y, z float64) float64 {
+	return x + y*z
+}
+
+func main() {
+	w, x, y := 1.0, 1.0, 1.0
+	x = f(x + x/(1<<52))
+	w = f(w / (1 << 27))
+	y = f(y + y/(1<<52))
+	w0 := f(2 * w * (1 - w))
+	w1 := f(w * (1 + w))
+	x = x + w0*w1
+	x = inlineFma(x, w0, w1)
+	y = y + f(w0*w1)
+	y = y + f(w0*w1)
+	fmt.Println(x, y, x-y)
+
+	if x != y {
+		os.Exit(1)
+	}
+}
diff --git a/src/cmd/compile/internal/ssa/tighten.go b/src/cmd/compile/internal/ssa/tighten.go
index 214bf62..edae6a1 100644
--- a/src/cmd/compile/internal/ssa/tighten.go
+++ b/src/cmd/compile/internal/ssa/tighten.go
@@ -10,7 +10,8 @@
 // A Value can be moved to any block that
 // dominates all blocks in which it is used.
 func tighten(f *Func) {
-	canMove := make([]bool, f.NumValues())
+	canMove := f.Cache.allocBoolSlice(f.NumValues())
+	defer f.Cache.freeBoolSlice(canMove)
 	for _, b := range f.Blocks {
 		for _, v := range b.Values {
 			if v.Op.isLoweredGetClosurePtr() {
@@ -52,7 +53,8 @@
 	lca := makeLCArange(f)
 
 	// For each moveable value, record the block that dominates all uses found so far.
-	target := make([]*Block, f.NumValues())
+	target := f.Cache.allocBlockSlice(f.NumValues())
+	defer f.Cache.freeBlockSlice(target)
 
 	// Grab loop information.
 	// We use this to make sure we don't tighten a value into a (deeper) loop.
diff --git a/src/cmd/compile/internal/ssa/trim.go b/src/cmd/compile/internal/ssa/trim.go
index 1fd7b33..13798c6 100644
--- a/src/cmd/compile/internal/ssa/trim.go
+++ b/src/cmd/compile/internal/ssa/trim.go
@@ -118,7 +118,7 @@
 }
 
 // emptyBlock reports whether the block does not contain actual
-// instructions
+// instructions.
 func emptyBlock(b *Block) bool {
 	for _, v := range b.Values {
 		if v.Op != OpPhi {
@@ -130,11 +130,11 @@
 
 // trimmableBlock reports whether the block can be trimmed from the CFG,
 // subject to the following criteria:
-//   - it should not be the first block
-//   - it should be BlockPlain
-//   - it should not loop back to itself
+//   - it should not be the first block.
+//   - it should be BlockPlain.
+//   - it should not loop back to itself.
 //   - it either is the single predecessor of the successor block or
-//     contains no actual instructions
+//     contains no actual instructions.
 func trimmableBlock(b *Block) bool {
 	if b.Kind != BlockPlain || b == b.Func.Entry {
 		return false
diff --git a/src/cmd/compile/internal/ssa/value.go b/src/cmd/compile/internal/ssa/value.go
index 8f125ce..643fa36 100644
--- a/src/cmd/compile/internal/ssa/value.go
+++ b/src/cmd/compile/internal/ssa/value.go
@@ -148,21 +148,22 @@
 	for _, a := range v.Args {
 		s += fmt.Sprintf(" %v", a)
 	}
-	var r []Location
-	if v.Block != nil {
-		r = v.Block.Func.RegAlloc
+	if v.Block == nil {
+		return s
 	}
+	r := v.Block.Func.RegAlloc
 	if int(v.ID) < len(r) && r[v.ID] != nil {
 		s += " : " + r[v.ID].String()
 	}
+	if reg := v.Block.Func.tempRegs[v.ID]; reg != nil {
+		s += " tmp=" + reg.String()
+	}
 	var names []string
-	if v.Block != nil {
-		for name, values := range v.Block.Func.NamedValues {
-			for _, value := range values {
-				if value == v {
-					names = append(names, name.String())
-					break // drop duplicates.
-				}
+	for name, values := range v.Block.Func.NamedValues {
+		for _, value := range values {
+			if value == v {
+				names = append(names, name.String())
+				break // drop duplicates.
 			}
 		}
 	}
@@ -488,6 +489,15 @@
 	return reg.(*Register).objNum
 }
 
+// RegTmp returns the temporary register assigned to v, in cmd/internal/obj/$ARCH numbering.
+func (v *Value) RegTmp() int16 {
+	reg := v.Block.Func.tempRegs[v.ID]
+	if reg == nil {
+		v.Fatalf("nil tmp register for value: %s\n%s\n", v.LongString(), v.Block.Func)
+	}
+	return reg.objNum
+}
+
 func (v *Value) RegName() string {
 	reg := v.Block.Func.RegAlloc[v.ID]
 	if reg == nil {
@@ -520,7 +530,7 @@
 	// The exact definition of LackingPos is somewhat heuristically defined and may change
 	// in the future, for example if some of these operations are generated more carefully
 	// with respect to their source position.
-	return v.Op == OpVarDef || v.Op == OpVarKill || v.Op == OpVarLive || v.Op == OpPhi ||
+	return v.Op == OpVarDef || v.Op == OpVarLive || v.Op == OpPhi ||
 		(v.Op == OpFwdRef || v.Op == OpCopy) && v.Type == types.TypeMem
 }
 
diff --git a/src/cmd/compile/internal/ssa/writebarrier.go b/src/cmd/compile/internal/ssa/writebarrier.go
index 42ecde1..1676a93 100644
--- a/src/cmd/compile/internal/ssa/writebarrier.go
+++ b/src/cmd/compile/internal/ssa/writebarrier.go
@@ -27,7 +27,7 @@
 // needwb reports whether we need write barrier for store op v.
 // v must be Store/Move/Zero.
 // zeroes provides known zero information (keyed by ID of memory-type values).
-func needwb(v *Value, zeroes map[ID]ZeroRegion) bool {
+func needwb(v *Value, zeroes map[ID]ZeroRegion, select1 []*Value) bool {
 	t, ok := v.Aux.(*types.Type)
 	if !ok {
 		v.Fatalf("store aux is not a type: %s", v.LongString())
@@ -39,7 +39,7 @@
 		return false // write on stack doesn't need write barrier
 	}
 	if v.Op == OpMove && IsReadOnlyGlobalAddr(v.Args[1]) {
-		if mem, ok := IsNewObject(v.Args[0]); ok && mem == v.MemoryArg() {
+		if mem, ok := IsNewObject(v.Args[0], select1); ok && mem == v.MemoryArg() {
 			// Copying data from readonly memory into a fresh object doesn't need a write barrier.
 			return false
 		}
@@ -99,7 +99,22 @@
 	var sset *sparseSet
 	var storeNumber []int32
 
-	zeroes := f.computeZeroMap()
+	// Compute map from a value to the SelectN [1] value that uses it.
+	select1 := f.Cache.allocValueSlice(f.NumValues())
+	defer func() { f.Cache.freeValueSlice(select1) }()
+	for _, b := range f.Blocks {
+		for _, v := range b.Values {
+			if v.Op != OpSelectN {
+				continue
+			}
+			if v.AuxInt != 1 {
+				continue
+			}
+			select1[v.Args[0].ID] = v
+		}
+	}
+
+	zeroes := f.computeZeroMap(select1)
 	for _, b := range f.Blocks { // range loop is safe since the blocks we added contain no stores to expand
 		// first, identify all the stores that need to insert a write barrier.
 		// mark them with WB ops temporarily. record presence of WB ops.
@@ -107,7 +122,7 @@
 		for _, v := range b.Values {
 			switch v.Op {
 			case OpStore, OpMove, OpZero:
-				if needwb(v, zeroes) {
+				if needwb(v, zeroes, select1) {
 					switch v.Op {
 					case OpStore:
 						v.Op = OpStoreWB
@@ -139,7 +154,8 @@
 			// allocate auxiliary data structures for computing store order
 			sset = f.newSparseSet(f.NumValues())
 			defer f.retSparseSet(sset)
-			storeNumber = make([]int32, f.NumValues())
+			storeNumber = f.Cache.allocInt32Slice(f.NumValues())
+			defer f.Cache.freeInt32Slice(storeNumber)
 		}
 
 		// order values in store order
@@ -163,7 +179,7 @@
 					last = w
 					end = i + 1
 				}
-			case OpVarDef, OpVarLive, OpVarKill:
+			case OpVarDef, OpVarLive:
 				continue
 			default:
 				if last == nil {
@@ -279,7 +295,7 @@
 				fn = typedmemclr
 				typ = reflectdata.TypeLinksym(w.Aux.(*types.Type))
 				nWBops--
-			case OpVarDef, OpVarLive, OpVarKill:
+			case OpVarDef, OpVarLive:
 			}
 
 			// then block: emit write barrier call
@@ -301,7 +317,7 @@
 				}
 				// Note that we set up a writebarrier function call.
 				f.fe.SetWBPos(pos)
-			case OpVarDef, OpVarLive, OpVarKill:
+			case OpVarDef, OpVarLive:
 				memThen = bThen.NewValue1A(pos, w.Op, types.TypeMem, w.Aux, memThen)
 			}
 
@@ -315,17 +331,11 @@
 			case OpZeroWB:
 				memElse = bElse.NewValue2I(pos, OpZero, types.TypeMem, w.AuxInt, ptr, memElse)
 				memElse.Aux = w.Aux
-			case OpVarDef, OpVarLive, OpVarKill:
+			case OpVarDef, OpVarLive:
 				memElse = bElse.NewValue1A(pos, w.Op, types.TypeMem, w.Aux, memElse)
 			}
 		}
 
-		// mark volatile temps dead
-		for _, c := range volatiles {
-			tmpNode := c.tmp.Aux
-			memThen = bThen.NewValue1A(memThen.Pos, OpVarKill, types.TypeMem, tmpNode, memThen)
-		}
-
 		// merge memory
 		// Splice memory Phi into the last memory of the original sequence,
 		// which may be used in subsequent blocks. Other memories in the
@@ -381,7 +391,8 @@
 
 // computeZeroMap returns a map from an ID of a memory value to
 // a set of locations that are known to be zeroed at that memory value.
-func (f *Func) computeZeroMap() map[ID]ZeroRegion {
+func (f *Func) computeZeroMap(select1 []*Value) map[ID]ZeroRegion {
+
 	ptrSize := f.Config.PtrSize
 	// Keep track of which parts of memory are known to be zero.
 	// This helps with removing write barriers for various initialization patterns.
@@ -391,7 +402,7 @@
 	// Find new objects.
 	for _, b := range f.Blocks {
 		for _, v := range b.Values {
-			if mem, ok := IsNewObject(v); ok {
+			if mem, ok := IsNewObject(v, select1); ok {
 				// While compiling package runtime itself, we might see user
 				// calls to newobject, which will have result type
 				// unsafe.Pointer instead. We can't easily infer how large the
@@ -541,7 +552,7 @@
 	return b.NewValue1I(pos, OpSelectN, types.TypeMem, 0, call)
 }
 
-// round to a multiple of r, r is a power of 2
+// round to a multiple of r, r is a power of 2.
 func round(o int64, r int64) int64 {
 	return (o + r - 1) &^ (r - 1)
 }
@@ -589,20 +600,14 @@
 
 // IsNewObject reports whether v is a pointer to a freshly allocated & zeroed object,
 // if so, also returns the memory state mem at which v is zero.
-func IsNewObject(v *Value) (mem *Value, ok bool) {
+func IsNewObject(v *Value, select1 []*Value) (mem *Value, ok bool) {
 	f := v.Block.Func
 	c := f.Config
 	if f.ABIDefault == f.ABI1 && len(c.intParamRegs) >= 1 {
 		if v.Op != OpSelectN || v.AuxInt != 0 {
 			return nil, false
 		}
-		// Find the memory
-		for _, w := range v.Block.Values {
-			if w.Op == OpSelectN && w.AuxInt == 1 && w.Args[0] == v.Args[0] {
-				mem = w
-				break
-			}
-		}
+		mem = select1[v.Args[0].ID]
 		if mem == nil {
 			return nil, false
 		}
@@ -658,7 +663,8 @@
 		// read-only once initialized.
 		return true
 	case OpAddr:
-		return v.Aux.(*obj.LSym).Type == objabi.SRODATA || v.Aux.(*obj.LSym).Type == objabi.SLIBFUZZER_8BIT_COUNTER
+		vt := v.Aux.(*obj.LSym).Type
+		return vt == objabi.SRODATA || vt == objabi.SLIBFUZZER_8BIT_COUNTER || vt == objabi.SCOVERAGE_COUNTER || vt == objabi.SCOVERAGE_AUXVAR
 	}
 	return false
 }
diff --git a/src/cmd/compile/internal/ssagen/abi.go b/src/cmd/compile/internal/ssagen/abi.go
index 50ea86d..84d5b59 100644
--- a/src/cmd/compile/internal/ssagen/abi.go
+++ b/src/cmd/compile/internal/ssagen/abi.go
@@ -7,7 +7,6 @@
 import (
 	"fmt"
 	"internal/buildcfg"
-	"io/ioutil"
 	"log"
 	"os"
 	"strings"
@@ -59,7 +58,7 @@
 // the symbol name and the third field is the ABI name, as one of the
 // named cmd/internal/obj.ABI constants.
 func (s *SymABIs) ReadSymABIs(file string) {
-	data, err := ioutil.ReadFile(file)
+	data, err := os.ReadFile(file)
 	if err != nil {
 		log.Fatalf("-symabis: %v", err)
 	}
@@ -205,7 +204,7 @@
 		// Double check that cgo-exported symbols don't get
 		// any wrappers.
 		if len(cgoExport) > 0 && fn.ABIRefs&^obj.ABISetOf(fn.ABI) != 0 {
-			base.Fatalf("cgo exported function %s cannot have ABI wrappers", fn)
+			base.Fatalf("cgo exported function %v cannot have ABI wrappers", fn)
 		}
 
 		if !buildcfg.Experiment.RegabiWrappers {
@@ -216,30 +215,6 @@
 	}
 }
 
-// InitLSym defines f's obj.LSym and initializes it based on the
-// properties of f. This includes setting the symbol flags and ABI and
-// creating and initializing related DWARF symbols.
-//
-// InitLSym must be called exactly once per function and must be
-// called for both functions with bodies and functions without bodies.
-// For body-less functions, we only create the LSym; for functions
-// with bodies call a helper to setup up / populate the LSym.
-func InitLSym(f *ir.Func, hasBody bool) {
-	if f.LSym != nil {
-		base.FatalfAt(f.Pos(), "InitLSym called twice on %v", f)
-	}
-
-	if nam := f.Nname; !ir.IsBlank(nam) {
-		f.LSym = nam.LinksymABI(f.ABI)
-		if f.Pragma&ir.Systemstack != 0 {
-			f.LSym.Set(obj.AttrCFunc, true)
-		}
-	}
-	if hasBody {
-		setupTextLSym(f, 0)
-	}
-}
-
 func forEachWrapperABI(fn *ir.Func, cb func(fn *ir.Func, wrapperABI obj.ABI)) {
 	need := fn.ABIRefs &^ obj.ABISetOf(fn.ABI)
 	if need == 0 {
@@ -364,47 +339,3 @@
 	typecheck.DeclContext = savedclcontext
 	ir.CurFunc = savedcurfn
 }
-
-// setupTextLsym initializes the LSym for a with-body text symbol.
-func setupTextLSym(f *ir.Func, flag int) {
-	if f.Dupok() {
-		flag |= obj.DUPOK
-	}
-	if f.Wrapper() {
-		flag |= obj.WRAPPER
-	}
-	if f.ABIWrapper() {
-		flag |= obj.ABIWRAPPER
-	}
-	if f.Needctxt() {
-		flag |= obj.NEEDCTXT
-	}
-	if f.Pragma&ir.Nosplit != 0 {
-		flag |= obj.NOSPLIT
-	}
-	if f.ReflectMethod() {
-		flag |= obj.REFLECTMETHOD
-	}
-
-	// Clumsy but important.
-	// For functions that could be on the path of invoking a deferred
-	// function that can recover (runtime.reflectcall, reflect.callReflect,
-	// and reflect.callMethod), we want the panic+recover special handling.
-	// See test/recover.go for test cases and src/reflect/value.go
-	// for the actual functions being considered.
-	//
-	// runtime.reflectcall is an assembly function which tailcalls
-	// WRAPPER functions (runtime.callNN). Its ABI wrapper needs WRAPPER
-	// flag as well.
-	fnname := f.Sym().Name
-	if base.Ctxt.Pkgpath == "runtime" && fnname == "reflectcall" {
-		flag |= obj.WRAPPER
-	} else if base.Ctxt.Pkgpath == "reflect" {
-		switch fnname {
-		case "callReflect", "callMethod":
-			flag |= obj.WRAPPER
-		}
-	}
-
-	base.Ctxt.InitTextSym(f.LSym, flag)
-}
diff --git a/src/cmd/compile/internal/ssagen/nowb.go b/src/cmd/compile/internal/ssagen/nowb.go
index 1fbc6a8..909319d 100644
--- a/src/cmd/compile/internal/ssagen/nowb.go
+++ b/src/cmd/compile/internal/ssagen/nowb.go
@@ -5,8 +5,8 @@
 package ssagen
 
 import (
-	"bytes"
 	"fmt"
+	"strings"
 
 	"cmd/compile/internal/base"
 	"cmd/compile/internal/ir"
@@ -45,7 +45,7 @@
 }
 
 // newNowritebarrierrecChecker creates a nowritebarrierrecChecker. It
-// must be called before walk
+// must be called before walk.
 func newNowritebarrierrecChecker() *nowritebarrierrecChecker {
 	c := &nowritebarrierrecChecker{
 		extraCalls: make(map[*ir.Func][]nowritebarrierrecCall),
@@ -179,7 +179,7 @@
 
 		// Check fn.
 		if fn.WBPos.IsKnown() {
-			var err bytes.Buffer
+			var err strings.Builder
 			call := funcs[fn]
 			for call.target != nil {
 				fmt.Fprintf(&err, "\n\t%v: called by %v", base.FmtPos(call.lineno), call.target.Nname)
diff --git a/src/cmd/compile/internal/ssagen/pgen.go b/src/cmd/compile/internal/ssagen/pgen.go
index 825b32a..ffd51f1 100644
--- a/src/cmd/compile/internal/ssagen/pgen.go
+++ b/src/cmd/compile/internal/ssagen/pgen.go
@@ -6,11 +6,8 @@
 
 import (
 	"internal/buildcfg"
-	"internal/race"
-	"math/rand"
 	"sort"
 	"sync"
-	"time"
 
 	"cmd/compile/internal/base"
 	"cmd/compile/internal/ir"
@@ -64,7 +61,7 @@
 	return a.Sym().Name < b.Sym().Name
 }
 
-// byStackvar implements sort.Interface for []*Node using cmpstackvarlt.
+// byStackVar implements sort.Interface for []*Node using cmpstackvarlt.
 type byStackVar []*ir.Name
 
 func (s byStackVar) Len() int           { return len(s) }
@@ -96,6 +93,7 @@
 func (s *ssafn) AllocFrame(f *ssa.Func) {
 	s.stksize = 0
 	s.stkptrsize = 0
+	s.stkalign = int64(types.RegSize)
 	fn := s.curfn
 
 	// Mark the PAUTO's unused.
@@ -142,6 +140,7 @@
 			continue
 		}
 		if !n.Used() {
+			fn.DebugInfo.(*ssa.FuncDebug).OptDcl = fn.Dcl[i:]
 			fn.Dcl = fn.Dcl[:i]
 			break
 		}
@@ -159,7 +158,10 @@
 			w = 1
 		}
 		s.stksize += w
-		s.stksize = types.Rnd(s.stksize, n.Type().Alignment())
+		s.stksize = types.RoundUp(s.stksize, n.Type().Alignment())
+		if n.Type().Alignment() > int64(types.RegSize) {
+			s.stkalign = n.Type().Alignment()
+		}
 		if n.Type().HasPointers() {
 			s.stkptrsize = s.stksize
 			lastHasPtr = true
@@ -169,8 +171,8 @@
 		n.SetFrameOffset(-s.stksize)
 	}
 
-	s.stksize = types.Rnd(s.stksize, int64(types.RegSize))
-	s.stkptrsize = types.Rnd(s.stkptrsize, int64(types.RegSize))
+	s.stksize = types.RoundUp(s.stksize, s.stkalign)
+	s.stkptrsize = types.RoundUp(s.stkptrsize, s.stkalign)
 }
 
 const maxStackSize = 1 << 30
@@ -210,12 +212,6 @@
 	fieldtrack(pp.Text.From.Sym, fn.FieldTrack)
 }
 
-func init() {
-	if race.Enabled {
-		rand.Seed(time.Now().UnixNano())
-	}
-}
-
 // StackOffset returns the stack location of a LocalSlot relative to the
 // stack pointer, suitable for use in a DWARF location entry. This has nothing
 // to do with its offset in the user variable.
diff --git a/src/cmd/compile/internal/ssagen/phi.go b/src/cmd/compile/internal/ssagen/phi.go
index 01ad211..19b6920 100644
--- a/src/cmd/compile/internal/ssagen/phi.go
+++ b/src/cmd/compile/internal/ssagen/phi.go
@@ -424,7 +424,7 @@
 }
 
 // newSparseSet returns a sparseSet that can represent
-// integers between 0 and n-1
+// integers between 0 and n-1.
 func newSparseSet(n int) *sparseSet {
 	return &sparseSet{dense: nil, sparse: make([]int32, n)}
 }
@@ -483,7 +483,7 @@
 		var_ := v.Aux.(fwdRefAux).N
 		if b == s.f.Entry {
 			// No variable should be live at entry.
-			s.s.Fatalf("Value live at entry. It shouldn't be. func %s, node %v, value %v", s.f.Name, var_, v)
+			s.s.Fatalf("value %v (%v) incorrectly live at entry", var_, v)
 		}
 		if !s.reachable[b.ID] {
 			// This block is dead.
diff --git a/src/cmd/compile/internal/ssagen/ssa.go b/src/cmd/compile/internal/ssagen/ssa.go
index 2ee0270..52f9403 100644
--- a/src/cmd/compile/internal/ssagen/ssa.go
+++ b/src/cmd/compile/internal/ssagen/ssa.go
@@ -105,6 +105,7 @@
 	ir.Syms.GCWriteBarrier = typecheck.LookupRuntimeFunc("gcWriteBarrier")
 	ir.Syms.Goschedguarded = typecheck.LookupRuntimeFunc("goschedguarded")
 	ir.Syms.Growslice = typecheck.LookupRuntimeFunc("growslice")
+	ir.Syms.Memmove = typecheck.LookupRuntimeFunc("memmove")
 	ir.Syms.Msanread = typecheck.LookupRuntimeFunc("msanread")
 	ir.Syms.Msanwrite = typecheck.LookupRuntimeFunc("msanwrite")
 	ir.Syms.Msanmove = typecheck.LookupRuntimeFunc("msanmove")
@@ -205,8 +206,6 @@
 	}
 
 	// Wasm (all asm funcs with special ABIs)
-	ir.Syms.WasmMove = typecheck.LookupRuntimeVar("wasmMove")
-	ir.Syms.WasmZero = typecheck.LookupRuntimeVar("wasmZero")
 	ir.Syms.WasmDiv = typecheck.LookupRuntimeVar("wasmDiv")
 	ir.Syms.WasmTruncS = typecheck.LookupRuntimeVar("wasmTruncS")
 	ir.Syms.WasmTruncU = typecheck.LookupRuntimeVar("wasmTruncU")
@@ -253,7 +252,7 @@
 	return a
 }
 
-// dvarint writes a varint v to the funcdata in symbol x and returns the new offset
+// dvarint writes a varint v to the funcdata in symbol x and returns the new offset.
 func dvarint(x *obj.LSym, off int, v int64) int {
 	if v < 0 || v > 1e9 {
 		panic(fmt.Sprintf("dvarint: bad offset for funcdata - %v", v))
@@ -357,7 +356,6 @@
 	s.f.Cache = &ssaCaches[worker]
 	s.f.Cache.Reset()
 	s.f.Name = name
-	s.f.DebugTest = s.f.DebugHashMatch("GOSSAHASH")
 	s.f.PrintOrHtmlSSA = printssa
 	if fn.Pragma&ir.Nosplit != 0 {
 		s.f.NoSplit = true
@@ -521,7 +519,7 @@
 				typ = types.NewPtr(typ)
 			}
 
-			offset = types.Rnd(offset, typ.Alignment())
+			offset = types.RoundUp(offset, typ.Alignment())
 			ptr := s.newValue1I(ssa.OpOffPtr, types.NewPtr(typ), offset, clo)
 			offset += typ.Size()
 
@@ -631,7 +629,9 @@
 		if typ := n.Type(); TypeOK(typ) {
 			s.assign(n, s.zeroVal(typ), false, 0)
 		} else {
-			s.vars[memVar] = s.newValue1A(ssa.OpVarDef, types.TypeMem, n, s.mem())
+			if typ.HasPointers() {
+				s.vars[memVar] = s.newValue1A(ssa.OpVarDef, types.TypeMem, n, s.mem())
+			}
 			s.zero(n.Type(), s.decladdrs[n])
 		}
 	}
@@ -664,7 +664,7 @@
 
 // newHeapaddr allocates heap memory for n and sets its heap address.
 func (s *state) newHeapaddr(n *ir.Name) {
-	s.setHeapaddr(n.Pos(), n, s.newObject(n.Type()))
+	s.setHeapaddr(n.Pos(), n, s.newObject(n.Type(), nil))
 }
 
 // setHeapaddr allocates a new PAUTO variable to store ptr (which must be non-nil)
@@ -692,23 +692,26 @@
 }
 
 // newObject returns an SSA value denoting new(typ).
-func (s *state) newObject(typ *types.Type) *ssa.Value {
+func (s *state) newObject(typ *types.Type, rtype *ssa.Value) *ssa.Value {
 	if typ.Size() == 0 {
 		return s.newValue1A(ssa.OpAddr, types.NewPtr(typ), ir.Syms.Zerobase, s.sb)
 	}
-	return s.rtcall(ir.Syms.Newobject, true, []*types.Type{types.NewPtr(typ)}, s.reflectType(typ))[0]
+	if rtype == nil {
+		rtype = s.reflectType(typ)
+	}
+	return s.rtcall(ir.Syms.Newobject, true, []*types.Type{types.NewPtr(typ)}, rtype)[0]
 }
 
 func (s *state) checkPtrAlignment(n *ir.ConvExpr, v *ssa.Value, count *ssa.Value) {
 	if !n.Type().IsPtr() {
 		s.Fatalf("expected pointer type: %v", n.Type())
 	}
-	elem := n.Type().Elem()
+	elem, rtypeExpr := n.Type().Elem(), n.ElemRType
 	if count != nil {
 		if !elem.IsArray() {
 			s.Fatalf("expected array type: %v", elem)
 		}
-		elem = elem.Elem()
+		elem, rtypeExpr = elem.Elem(), n.ElemElemRType
 	}
 	size := elem.Size()
 	// Casting from larger type to smaller one is ok, so for smallest type, do nothing.
@@ -721,12 +724,20 @@
 	if count.Type.Size() != s.config.PtrSize {
 		s.Fatalf("expected count fit to an uintptr size, have: %d, want: %d", count.Type.Size(), s.config.PtrSize)
 	}
-	s.rtcall(ir.Syms.CheckPtrAlignment, true, nil, v, s.reflectType(elem), count)
+	var rtype *ssa.Value
+	if rtypeExpr != nil {
+		rtype = s.expr(rtypeExpr)
+	} else {
+		rtype = s.reflectType(elem)
+	}
+	s.rtcall(ir.Syms.CheckPtrAlignment, true, nil, v, rtype, count)
 }
 
 // reflectType returns an SSA value representing a pointer to typ's
 // reflection type descriptor.
 func (s *state) reflectType(typ *types.Type) *ssa.Value {
+	// TODO(mdempsky): Make this Fatalf under Unified IR; frontend needs
+	// to supply RType expressions.
 	lsym := reflectdata.TypeLinksym(typ)
 	return s.entryNewValue1A(ssa.OpAddr, types.NewPtr(types.Types[types.TUINT8]), lsym, s.sb)
 }
@@ -938,7 +949,6 @@
 	// marker nodes for temporary variables
 	ptrVar       = ssaMarker("ptr")
 	lenVar       = ssaMarker("len")
-	newlenVar    = ssaMarker("newlen")
 	capVar       = ssaMarker("cap")
 	typVar       = ssaMarker("typ")
 	okVar        = ssaMarker("ok")
@@ -1103,7 +1113,7 @@
 	return s.curBlock.NewValue4(s.peekPos(), op, t, arg0, arg1, arg2, arg3)
 }
 
-// newValue4 adds a new value with four arguments and an auxint value to the current block.
+// newValue4I adds a new value with four arguments and an auxint value to the current block.
 func (s *state) newValue4I(op ssa.Op, t *types.Type, aux int64, arg0, arg1, arg2, arg3 *ssa.Value) *ssa.Value {
 	return s.curBlock.NewValue4I(s.peekPos(), op, t, aux, arg0, arg1, arg2, arg3)
 }
@@ -1135,7 +1145,7 @@
 	return s.entryBlock().NewValue1(src.NoXPos, op, t, arg)
 }
 
-// entryNewValue1 adds a new value with one argument and an auxint value to the entry block.
+// entryNewValue1I adds a new value with one argument and an auxint value to the entry block.
 func (s *state) entryNewValue1I(op ssa.Op, t *types.Type, auxint int64, arg *ssa.Value) *ssa.Value {
 	return s.entryBlock().NewValue1I(src.NoXPos, op, t, auxint, arg)
 }
@@ -1359,7 +1369,47 @@
 }
 
 func (s *state) move(t *types.Type, dst, src *ssa.Value) {
+	s.moveWhichMayOverlap(t, dst, src, false)
+}
+func (s *state) moveWhichMayOverlap(t *types.Type, dst, src *ssa.Value, mayOverlap bool) {
 	s.instrumentMove(t, dst, src)
+	if mayOverlap && t.IsArray() && t.NumElem() > 1 && !ssa.IsInlinableMemmove(dst, src, t.Size(), s.f.Config) {
+		// Normally, when moving Go values of type T from one location to another,
+		// we don't need to worry about partial overlaps. The two Ts must either be
+		// in disjoint (nonoverlapping) memory or in exactly the same location.
+		// There are 2 cases where this isn't true:
+		//  1) Using unsafe you can arrange partial overlaps.
+		//  2) Since Go 1.17, you can use a cast from a slice to a ptr-to-array.
+		//     https://go.dev/ref/spec#Conversions_from_slice_to_array_pointer
+		//     This feature can be used to construct partial overlaps of array types.
+		//       var a [3]int
+		//       p := (*[2]int)(a[:])
+		//       q := (*[2]int)(a[1:])
+		//       *p = *q
+		// We don't care about solving 1. Or at least, we haven't historically
+		// and no one has complained.
+		// For 2, we need to ensure that if there might be partial overlap,
+		// then we can't use OpMove; we must use memmove instead.
+		// (memmove handles partial overlap by copying in the correct
+		// direction. OpMove does not.)
+		//
+		// Note that we have to be careful here not to introduce a call when
+		// we're marshaling arguments to a call or unmarshaling results from a call.
+		// Cases where this is happening must pass mayOverlap to false.
+		// (Currently this only happens when unmarshaling results of a call.)
+		if t.HasPointers() {
+			s.rtcall(ir.Syms.Typedmemmove, true, nil, s.reflectType(t), dst, src)
+			// We would have otherwise implemented this move with straightline code,
+			// including a write barrier. Pretend we issue a write barrier here,
+			// so that the write barrier tests work. (Otherwise they'd need to know
+			// the details of IsInlineableMemmove.)
+			s.curfn.SetWBPos(s.peekPos())
+		} else {
+			s.rtcall(ir.Syms.Memmove, true, nil, dst, src, s.constInt(types.Types[types.TUINTPTR], t.Size()))
+		}
+		ssa.LogLargeCopy(s.f.Name, s.peekPos(), t.Size())
+		return
+	}
 	store := s.newValue3I(ssa.OpMove, types.TypeMem, t.Size(), dst, src, s.mem())
 	store.Aux = t
 	s.vars[memVar] = store
@@ -1374,11 +1424,8 @@
 
 // stmt converts the statement n to SSA and adds it to s.
 func (s *state) stmt(n ir.Node) {
-	if !(n.Op() == ir.OVARKILL || n.Op() == ir.OVARLIVE || n.Op() == ir.OVARDEF) {
-		// OVARKILL, OVARLIVE, and OVARDEF are invisible to the programmer, so we don't use their line numbers to avoid confusion in debugging.
-		s.pushLine(n.Pos())
-		defer s.popLine()
-	}
+	s.pushLine(n.Pos())
+	defer s.popLine()
 
 	// If s.curBlock is nil, and n isn't a label (which might have an associated goto somewhere),
 	// then this code is dead. Stop here.
@@ -1410,7 +1457,7 @@
 		s.callResult(n, callNormal)
 		if n.Op() == ir.OCALLFUNC && n.X.Op() == ir.ONAME && n.X.(*ir.Name).Class == ir.PFUNC {
 			if fn := n.X.Sym().Name; base.Flag.CompilingRuntime && fn == "throw" ||
-				n.X.Sym().Pkg == ir.Pkgs.Runtime && (fn == "throwinit" || fn == "gopanic" || fn == "panicwrap" || fn == "block" || fn == "panicmakeslicelen" || fn == "panicmakeslicecap") {
+				n.X.Sym().Pkg == ir.Pkgs.Runtime && (fn == "throwinit" || fn == "gopanic" || fn == "panicwrap" || fn == "block" || fn == "panicmakeslicelen" || fn == "panicmakeslicecap" || fn == "panicunsafeslicelen" || fn == "panicunsafeslicenilptr" || fn == "panicunsafestringlen" || fn == "panicunsafestringnilptr") {
 				m := s.mem()
 				b := s.endBlock()
 				b.Kind = ssa.BlockExit
@@ -1460,9 +1507,6 @@
 				s.Fatalf("dottype of non-load")
 			}
 			mem := s.mem()
-			if mem.Op == ssa.OpVarKill {
-				mem = mem.Args[0]
-			}
 			if res.Args[1] != mem {
 				s.Fatalf("memory no longer live from 2-result dottype load")
 			}
@@ -1541,6 +1585,28 @@
 			return
 		}
 
+		// mayOverlap keeps track of whether the LHS and RHS might
+		// refer to partially overlapping memory. Partial overlapping can
+		// only happen for arrays, see the comment in moveWhichMayOverlap.
+		//
+		// If both sides of the assignment are not dereferences, then partial
+		// overlap can't happen. Partial overlap can only occur only when the
+		// arrays referenced are strictly smaller parts of the same base array.
+		// If one side of the assignment is a full array, then partial overlap
+		// can't happen. (The arrays are either disjoint or identical.)
+		mayOverlap := n.X.Op() == ir.ODEREF && (n.Y != nil && n.Y.Op() == ir.ODEREF)
+		if n.Y != nil && n.Y.Op() == ir.ODEREF {
+			p := n.Y.(*ir.StarExpr).X
+			for p.Op() == ir.OCONVNOP {
+				p = p.(*ir.ConvExpr).X
+			}
+			if p.Op() == ir.OSPTR && p.(*ir.UnaryExpr).X.Type().IsString() {
+				// Pointer fields of strings point to unmodifiable memory.
+				// That memory can't overlap with the memory being written.
+				mayOverlap = false
+			}
+		}
+
 		// Evaluate RHS.
 		rhs := n.Y
 		if rhs != nil {
@@ -1624,12 +1690,12 @@
 			// Currently doesn't really work because (*p)[:len(*p)] appears here as:
 			//    tmp = len(*p)
 			//    (*p)[:tmp]
-			//if j != nil && (j.Op == OLEN && SameSafeExpr(j.Left, n.Left)) {
+			// if j != nil && (j.Op == OLEN && SameSafeExpr(j.Left, n.Left)) {
 			//      j = nil
-			//}
-			//if k != nil && (k.Op == OCAP && SameSafeExpr(k.Left, n.Left)) {
+			// }
+			// if k != nil && (k.Op == OCAP && SameSafeExpr(k.Left, n.Left)) {
 			//      k = nil
-			//}
+			// }
 			if i == nil {
 				skip |= skipPtr
 				if j == nil {
@@ -1641,7 +1707,7 @@
 			}
 		}
 
-		s.assign(n.X, r, deref, skip)
+		s.assignWhichMayOverlap(n.X, r, deref, skip, mayOverlap)
 
 	case ir.OIF:
 		n := n.(*ir.IfStmt)
@@ -1731,12 +1797,9 @@
 		b.Pos = s.lastPos.WithIsStmt() // Do this even if b is an empty block.
 		b.AddEdgeTo(to)
 
-	case ir.OFOR, ir.OFORUNTIL:
+	case ir.OFOR:
 		// OFOR: for Ninit; Left; Right { Nbody }
 		// cond (Left); body (Nbody); incr (Right)
-		//
-		// OFORUNTIL: for Ninit; Left; Right; List { Nbody }
-		// => body: { Nbody }; incr: Right; if Left { lateincr: List; goto body }; end:
 		n := n.(*ir.ForStmt)
 		bCond := s.f.NewBlock(ssa.BlockPlain)
 		bBody := s.f.NewBlock(ssa.BlockPlain)
@@ -1746,21 +1809,17 @@
 		// ensure empty for loops have correct position; issue #30167
 		bBody.Pos = n.Pos()
 
-		// first, jump to condition test (OFOR) or body (OFORUNTIL)
+		// first, jump to condition test
 		b := s.endBlock()
-		if n.Op() == ir.OFOR {
-			b.AddEdgeTo(bCond)
-			// generate code to test condition
-			s.startBlock(bCond)
-			if n.Cond != nil {
-				s.condBranch(n.Cond, bBody, bEnd, 1)
-			} else {
-				b := s.endBlock()
-				b.Kind = ssa.BlockPlain
-				b.AddEdgeTo(bBody)
-			}
+		b.AddEdgeTo(bCond)
 
+		// generate code to test condition
+		s.startBlock(bCond)
+		if n.Cond != nil {
+			s.condBranch(n.Cond, bBody, bEnd, 1)
 		} else {
+			b := s.endBlock()
+			b.Kind = ssa.BlockPlain
 			b.AddEdgeTo(bBody)
 		}
 
@@ -1794,29 +1853,18 @@
 			b.AddEdgeTo(bIncr)
 		}
 
-		// generate incr (and, for OFORUNTIL, condition)
+		// generate incr
 		s.startBlock(bIncr)
 		if n.Post != nil {
 			s.stmt(n.Post)
 		}
-		if n.Op() == ir.OFOR {
-			if b := s.endBlock(); b != nil {
-				b.AddEdgeTo(bCond)
-				// It can happen that bIncr ends in a block containing only VARKILL,
-				// and that muddles the debugging experience.
-				if b.Pos == src.NoXPos {
-					b.Pos = bCond.Pos
-				}
+		if b := s.endBlock(); b != nil {
+			b.AddEdgeTo(bCond)
+			// It can happen that bIncr ends in a block containing only VARKILL,
+			// and that muddles the debugging experience.
+			if b.Pos == src.NoXPos {
+				b.Pos = bCond.Pos
 			}
-		} else {
-			// bCond is unused in OFORUNTIL, so repurpose it.
-			bLateIncr := bCond
-			// test condition
-			s.condBranch(n.Cond, bLateIncr, bEnd, 1)
-			// generate late increment
-			s.startBlock(bLateIncr)
-			s.stmtList(n.Late)
-			s.endBlock().AddEdgeTo(bBody)
 		}
 
 		s.startBlock(bEnd)
@@ -1943,35 +1991,6 @@
 
 		s.startBlock(bEnd)
 
-	case ir.OVARDEF:
-		n := n.(*ir.UnaryExpr)
-		if !s.canSSA(n.X) {
-			s.vars[memVar] = s.newValue1Apos(ssa.OpVarDef, types.TypeMem, n.X.(*ir.Name), s.mem(), false)
-		}
-	case ir.OVARKILL:
-		// Insert a varkill op to record that a variable is no longer live.
-		// We only care about liveness info at call sites, so putting the
-		// varkill in the store chain is enough to keep it correctly ordered
-		// with respect to call ops.
-		n := n.(*ir.UnaryExpr)
-		if !s.canSSA(n.X) {
-			s.vars[memVar] = s.newValue1Apos(ssa.OpVarKill, types.TypeMem, n.X.(*ir.Name), s.mem(), false)
-		}
-
-	case ir.OVARLIVE:
-		// Insert a varlive op to record that a variable is still live.
-		n := n.(*ir.UnaryExpr)
-		v := n.X.(*ir.Name)
-		if !v.Addrtaken() {
-			s.Fatalf("VARLIVE variable %v must have Addrtaken set", v)
-		}
-		switch v.Class {
-		case ir.PAUTO, ir.PPARAM, ir.PPARAMOUT:
-		default:
-			s.Fatalf("VARLIVE variable %v must be Auto or Arg", v)
-		}
-		s.vars[memVar] = s.newValue1A(ssa.OpVarLive, types.TypeMem, v, s.mem())
-
 	case ir.OCHECKNIL:
 		n := n.(*ir.UnaryExpr)
 		p := s.expr(n.X)
@@ -2021,14 +2040,16 @@
 	for i, f := range resultFields {
 		n := f.Nname.(*ir.Name)
 		if s.canSSA(n) { // result is in some SSA variable
-			if !n.IsOutputParamInRegisters() {
+			if !n.IsOutputParamInRegisters() && n.Type().HasPointers() {
 				// We are about to store to the result slot.
 				s.vars[memVar] = s.newValue1A(ssa.OpVarDef, types.TypeMem, n, s.mem())
 			}
 			results[i] = s.variable(n, n.Type())
 		} else if !n.OnStack() { // result is actually heap allocated
 			// We are about to copy the in-heap result to the result slot.
-			s.vars[memVar] = s.newValue1A(ssa.OpVarDef, types.TypeMem, n, s.mem())
+			if n.Type().HasPointers() {
+				s.vars[memVar] = s.newValue1A(ssa.OpVarDef, types.TypeMem, n, s.mem())
+			}
 			ha := s.expr(n.Heapaddr)
 			s.instrumentFields(n.Type(), ha, instrumentRead)
 			results[i] = s.newValue2(ssa.OpDereference, n.Type(), ha, s.mem())
@@ -2063,175 +2084,175 @@
 }
 
 var opToSSA = map[opAndType]ssa.Op{
-	opAndType{ir.OADD, types.TINT8}:    ssa.OpAdd8,
-	opAndType{ir.OADD, types.TUINT8}:   ssa.OpAdd8,
-	opAndType{ir.OADD, types.TINT16}:   ssa.OpAdd16,
-	opAndType{ir.OADD, types.TUINT16}:  ssa.OpAdd16,
-	opAndType{ir.OADD, types.TINT32}:   ssa.OpAdd32,
-	opAndType{ir.OADD, types.TUINT32}:  ssa.OpAdd32,
-	opAndType{ir.OADD, types.TINT64}:   ssa.OpAdd64,
-	opAndType{ir.OADD, types.TUINT64}:  ssa.OpAdd64,
-	opAndType{ir.OADD, types.TFLOAT32}: ssa.OpAdd32F,
-	opAndType{ir.OADD, types.TFLOAT64}: ssa.OpAdd64F,
+	{ir.OADD, types.TINT8}:    ssa.OpAdd8,
+	{ir.OADD, types.TUINT8}:   ssa.OpAdd8,
+	{ir.OADD, types.TINT16}:   ssa.OpAdd16,
+	{ir.OADD, types.TUINT16}:  ssa.OpAdd16,
+	{ir.OADD, types.TINT32}:   ssa.OpAdd32,
+	{ir.OADD, types.TUINT32}:  ssa.OpAdd32,
+	{ir.OADD, types.TINT64}:   ssa.OpAdd64,
+	{ir.OADD, types.TUINT64}:  ssa.OpAdd64,
+	{ir.OADD, types.TFLOAT32}: ssa.OpAdd32F,
+	{ir.OADD, types.TFLOAT64}: ssa.OpAdd64F,
 
-	opAndType{ir.OSUB, types.TINT8}:    ssa.OpSub8,
-	opAndType{ir.OSUB, types.TUINT8}:   ssa.OpSub8,
-	opAndType{ir.OSUB, types.TINT16}:   ssa.OpSub16,
-	opAndType{ir.OSUB, types.TUINT16}:  ssa.OpSub16,
-	opAndType{ir.OSUB, types.TINT32}:   ssa.OpSub32,
-	opAndType{ir.OSUB, types.TUINT32}:  ssa.OpSub32,
-	opAndType{ir.OSUB, types.TINT64}:   ssa.OpSub64,
-	opAndType{ir.OSUB, types.TUINT64}:  ssa.OpSub64,
-	opAndType{ir.OSUB, types.TFLOAT32}: ssa.OpSub32F,
-	opAndType{ir.OSUB, types.TFLOAT64}: ssa.OpSub64F,
+	{ir.OSUB, types.TINT8}:    ssa.OpSub8,
+	{ir.OSUB, types.TUINT8}:   ssa.OpSub8,
+	{ir.OSUB, types.TINT16}:   ssa.OpSub16,
+	{ir.OSUB, types.TUINT16}:  ssa.OpSub16,
+	{ir.OSUB, types.TINT32}:   ssa.OpSub32,
+	{ir.OSUB, types.TUINT32}:  ssa.OpSub32,
+	{ir.OSUB, types.TINT64}:   ssa.OpSub64,
+	{ir.OSUB, types.TUINT64}:  ssa.OpSub64,
+	{ir.OSUB, types.TFLOAT32}: ssa.OpSub32F,
+	{ir.OSUB, types.TFLOAT64}: ssa.OpSub64F,
 
-	opAndType{ir.ONOT, types.TBOOL}: ssa.OpNot,
+	{ir.ONOT, types.TBOOL}: ssa.OpNot,
 
-	opAndType{ir.ONEG, types.TINT8}:    ssa.OpNeg8,
-	opAndType{ir.ONEG, types.TUINT8}:   ssa.OpNeg8,
-	opAndType{ir.ONEG, types.TINT16}:   ssa.OpNeg16,
-	opAndType{ir.ONEG, types.TUINT16}:  ssa.OpNeg16,
-	opAndType{ir.ONEG, types.TINT32}:   ssa.OpNeg32,
-	opAndType{ir.ONEG, types.TUINT32}:  ssa.OpNeg32,
-	opAndType{ir.ONEG, types.TINT64}:   ssa.OpNeg64,
-	opAndType{ir.ONEG, types.TUINT64}:  ssa.OpNeg64,
-	opAndType{ir.ONEG, types.TFLOAT32}: ssa.OpNeg32F,
-	opAndType{ir.ONEG, types.TFLOAT64}: ssa.OpNeg64F,
+	{ir.ONEG, types.TINT8}:    ssa.OpNeg8,
+	{ir.ONEG, types.TUINT8}:   ssa.OpNeg8,
+	{ir.ONEG, types.TINT16}:   ssa.OpNeg16,
+	{ir.ONEG, types.TUINT16}:  ssa.OpNeg16,
+	{ir.ONEG, types.TINT32}:   ssa.OpNeg32,
+	{ir.ONEG, types.TUINT32}:  ssa.OpNeg32,
+	{ir.ONEG, types.TINT64}:   ssa.OpNeg64,
+	{ir.ONEG, types.TUINT64}:  ssa.OpNeg64,
+	{ir.ONEG, types.TFLOAT32}: ssa.OpNeg32F,
+	{ir.ONEG, types.TFLOAT64}: ssa.OpNeg64F,
 
-	opAndType{ir.OBITNOT, types.TINT8}:   ssa.OpCom8,
-	opAndType{ir.OBITNOT, types.TUINT8}:  ssa.OpCom8,
-	opAndType{ir.OBITNOT, types.TINT16}:  ssa.OpCom16,
-	opAndType{ir.OBITNOT, types.TUINT16}: ssa.OpCom16,
-	opAndType{ir.OBITNOT, types.TINT32}:  ssa.OpCom32,
-	opAndType{ir.OBITNOT, types.TUINT32}: ssa.OpCom32,
-	opAndType{ir.OBITNOT, types.TINT64}:  ssa.OpCom64,
-	opAndType{ir.OBITNOT, types.TUINT64}: ssa.OpCom64,
+	{ir.OBITNOT, types.TINT8}:   ssa.OpCom8,
+	{ir.OBITNOT, types.TUINT8}:  ssa.OpCom8,
+	{ir.OBITNOT, types.TINT16}:  ssa.OpCom16,
+	{ir.OBITNOT, types.TUINT16}: ssa.OpCom16,
+	{ir.OBITNOT, types.TINT32}:  ssa.OpCom32,
+	{ir.OBITNOT, types.TUINT32}: ssa.OpCom32,
+	{ir.OBITNOT, types.TINT64}:  ssa.OpCom64,
+	{ir.OBITNOT, types.TUINT64}: ssa.OpCom64,
 
-	opAndType{ir.OIMAG, types.TCOMPLEX64}:  ssa.OpComplexImag,
-	opAndType{ir.OIMAG, types.TCOMPLEX128}: ssa.OpComplexImag,
-	opAndType{ir.OREAL, types.TCOMPLEX64}:  ssa.OpComplexReal,
-	opAndType{ir.OREAL, types.TCOMPLEX128}: ssa.OpComplexReal,
+	{ir.OIMAG, types.TCOMPLEX64}:  ssa.OpComplexImag,
+	{ir.OIMAG, types.TCOMPLEX128}: ssa.OpComplexImag,
+	{ir.OREAL, types.TCOMPLEX64}:  ssa.OpComplexReal,
+	{ir.OREAL, types.TCOMPLEX128}: ssa.OpComplexReal,
 
-	opAndType{ir.OMUL, types.TINT8}:    ssa.OpMul8,
-	opAndType{ir.OMUL, types.TUINT8}:   ssa.OpMul8,
-	opAndType{ir.OMUL, types.TINT16}:   ssa.OpMul16,
-	opAndType{ir.OMUL, types.TUINT16}:  ssa.OpMul16,
-	opAndType{ir.OMUL, types.TINT32}:   ssa.OpMul32,
-	opAndType{ir.OMUL, types.TUINT32}:  ssa.OpMul32,
-	opAndType{ir.OMUL, types.TINT64}:   ssa.OpMul64,
-	opAndType{ir.OMUL, types.TUINT64}:  ssa.OpMul64,
-	opAndType{ir.OMUL, types.TFLOAT32}: ssa.OpMul32F,
-	opAndType{ir.OMUL, types.TFLOAT64}: ssa.OpMul64F,
+	{ir.OMUL, types.TINT8}:    ssa.OpMul8,
+	{ir.OMUL, types.TUINT8}:   ssa.OpMul8,
+	{ir.OMUL, types.TINT16}:   ssa.OpMul16,
+	{ir.OMUL, types.TUINT16}:  ssa.OpMul16,
+	{ir.OMUL, types.TINT32}:   ssa.OpMul32,
+	{ir.OMUL, types.TUINT32}:  ssa.OpMul32,
+	{ir.OMUL, types.TINT64}:   ssa.OpMul64,
+	{ir.OMUL, types.TUINT64}:  ssa.OpMul64,
+	{ir.OMUL, types.TFLOAT32}: ssa.OpMul32F,
+	{ir.OMUL, types.TFLOAT64}: ssa.OpMul64F,
 
-	opAndType{ir.ODIV, types.TFLOAT32}: ssa.OpDiv32F,
-	opAndType{ir.ODIV, types.TFLOAT64}: ssa.OpDiv64F,
+	{ir.ODIV, types.TFLOAT32}: ssa.OpDiv32F,
+	{ir.ODIV, types.TFLOAT64}: ssa.OpDiv64F,
 
-	opAndType{ir.ODIV, types.TINT8}:   ssa.OpDiv8,
-	opAndType{ir.ODIV, types.TUINT8}:  ssa.OpDiv8u,
-	opAndType{ir.ODIV, types.TINT16}:  ssa.OpDiv16,
-	opAndType{ir.ODIV, types.TUINT16}: ssa.OpDiv16u,
-	opAndType{ir.ODIV, types.TINT32}:  ssa.OpDiv32,
-	opAndType{ir.ODIV, types.TUINT32}: ssa.OpDiv32u,
-	opAndType{ir.ODIV, types.TINT64}:  ssa.OpDiv64,
-	opAndType{ir.ODIV, types.TUINT64}: ssa.OpDiv64u,
+	{ir.ODIV, types.TINT8}:   ssa.OpDiv8,
+	{ir.ODIV, types.TUINT8}:  ssa.OpDiv8u,
+	{ir.ODIV, types.TINT16}:  ssa.OpDiv16,
+	{ir.ODIV, types.TUINT16}: ssa.OpDiv16u,
+	{ir.ODIV, types.TINT32}:  ssa.OpDiv32,
+	{ir.ODIV, types.TUINT32}: ssa.OpDiv32u,
+	{ir.ODIV, types.TINT64}:  ssa.OpDiv64,
+	{ir.ODIV, types.TUINT64}: ssa.OpDiv64u,
 
-	opAndType{ir.OMOD, types.TINT8}:   ssa.OpMod8,
-	opAndType{ir.OMOD, types.TUINT8}:  ssa.OpMod8u,
-	opAndType{ir.OMOD, types.TINT16}:  ssa.OpMod16,
-	opAndType{ir.OMOD, types.TUINT16}: ssa.OpMod16u,
-	opAndType{ir.OMOD, types.TINT32}:  ssa.OpMod32,
-	opAndType{ir.OMOD, types.TUINT32}: ssa.OpMod32u,
-	opAndType{ir.OMOD, types.TINT64}:  ssa.OpMod64,
-	opAndType{ir.OMOD, types.TUINT64}: ssa.OpMod64u,
+	{ir.OMOD, types.TINT8}:   ssa.OpMod8,
+	{ir.OMOD, types.TUINT8}:  ssa.OpMod8u,
+	{ir.OMOD, types.TINT16}:  ssa.OpMod16,
+	{ir.OMOD, types.TUINT16}: ssa.OpMod16u,
+	{ir.OMOD, types.TINT32}:  ssa.OpMod32,
+	{ir.OMOD, types.TUINT32}: ssa.OpMod32u,
+	{ir.OMOD, types.TINT64}:  ssa.OpMod64,
+	{ir.OMOD, types.TUINT64}: ssa.OpMod64u,
 
-	opAndType{ir.OAND, types.TINT8}:   ssa.OpAnd8,
-	opAndType{ir.OAND, types.TUINT8}:  ssa.OpAnd8,
-	opAndType{ir.OAND, types.TINT16}:  ssa.OpAnd16,
-	opAndType{ir.OAND, types.TUINT16}: ssa.OpAnd16,
-	opAndType{ir.OAND, types.TINT32}:  ssa.OpAnd32,
-	opAndType{ir.OAND, types.TUINT32}: ssa.OpAnd32,
-	opAndType{ir.OAND, types.TINT64}:  ssa.OpAnd64,
-	opAndType{ir.OAND, types.TUINT64}: ssa.OpAnd64,
+	{ir.OAND, types.TINT8}:   ssa.OpAnd8,
+	{ir.OAND, types.TUINT8}:  ssa.OpAnd8,
+	{ir.OAND, types.TINT16}:  ssa.OpAnd16,
+	{ir.OAND, types.TUINT16}: ssa.OpAnd16,
+	{ir.OAND, types.TINT32}:  ssa.OpAnd32,
+	{ir.OAND, types.TUINT32}: ssa.OpAnd32,
+	{ir.OAND, types.TINT64}:  ssa.OpAnd64,
+	{ir.OAND, types.TUINT64}: ssa.OpAnd64,
 
-	opAndType{ir.OOR, types.TINT8}:   ssa.OpOr8,
-	opAndType{ir.OOR, types.TUINT8}:  ssa.OpOr8,
-	opAndType{ir.OOR, types.TINT16}:  ssa.OpOr16,
-	opAndType{ir.OOR, types.TUINT16}: ssa.OpOr16,
-	opAndType{ir.OOR, types.TINT32}:  ssa.OpOr32,
-	opAndType{ir.OOR, types.TUINT32}: ssa.OpOr32,
-	opAndType{ir.OOR, types.TINT64}:  ssa.OpOr64,
-	opAndType{ir.OOR, types.TUINT64}: ssa.OpOr64,
+	{ir.OOR, types.TINT8}:   ssa.OpOr8,
+	{ir.OOR, types.TUINT8}:  ssa.OpOr8,
+	{ir.OOR, types.TINT16}:  ssa.OpOr16,
+	{ir.OOR, types.TUINT16}: ssa.OpOr16,
+	{ir.OOR, types.TINT32}:  ssa.OpOr32,
+	{ir.OOR, types.TUINT32}: ssa.OpOr32,
+	{ir.OOR, types.TINT64}:  ssa.OpOr64,
+	{ir.OOR, types.TUINT64}: ssa.OpOr64,
 
-	opAndType{ir.OXOR, types.TINT8}:   ssa.OpXor8,
-	opAndType{ir.OXOR, types.TUINT8}:  ssa.OpXor8,
-	opAndType{ir.OXOR, types.TINT16}:  ssa.OpXor16,
-	opAndType{ir.OXOR, types.TUINT16}: ssa.OpXor16,
-	opAndType{ir.OXOR, types.TINT32}:  ssa.OpXor32,
-	opAndType{ir.OXOR, types.TUINT32}: ssa.OpXor32,
-	opAndType{ir.OXOR, types.TINT64}:  ssa.OpXor64,
-	opAndType{ir.OXOR, types.TUINT64}: ssa.OpXor64,
+	{ir.OXOR, types.TINT8}:   ssa.OpXor8,
+	{ir.OXOR, types.TUINT8}:  ssa.OpXor8,
+	{ir.OXOR, types.TINT16}:  ssa.OpXor16,
+	{ir.OXOR, types.TUINT16}: ssa.OpXor16,
+	{ir.OXOR, types.TINT32}:  ssa.OpXor32,
+	{ir.OXOR, types.TUINT32}: ssa.OpXor32,
+	{ir.OXOR, types.TINT64}:  ssa.OpXor64,
+	{ir.OXOR, types.TUINT64}: ssa.OpXor64,
 
-	opAndType{ir.OEQ, types.TBOOL}:      ssa.OpEqB,
-	opAndType{ir.OEQ, types.TINT8}:      ssa.OpEq8,
-	opAndType{ir.OEQ, types.TUINT8}:     ssa.OpEq8,
-	opAndType{ir.OEQ, types.TINT16}:     ssa.OpEq16,
-	opAndType{ir.OEQ, types.TUINT16}:    ssa.OpEq16,
-	opAndType{ir.OEQ, types.TINT32}:     ssa.OpEq32,
-	opAndType{ir.OEQ, types.TUINT32}:    ssa.OpEq32,
-	opAndType{ir.OEQ, types.TINT64}:     ssa.OpEq64,
-	opAndType{ir.OEQ, types.TUINT64}:    ssa.OpEq64,
-	opAndType{ir.OEQ, types.TINTER}:     ssa.OpEqInter,
-	opAndType{ir.OEQ, types.TSLICE}:     ssa.OpEqSlice,
-	opAndType{ir.OEQ, types.TFUNC}:      ssa.OpEqPtr,
-	opAndType{ir.OEQ, types.TMAP}:       ssa.OpEqPtr,
-	opAndType{ir.OEQ, types.TCHAN}:      ssa.OpEqPtr,
-	opAndType{ir.OEQ, types.TPTR}:       ssa.OpEqPtr,
-	opAndType{ir.OEQ, types.TUINTPTR}:   ssa.OpEqPtr,
-	opAndType{ir.OEQ, types.TUNSAFEPTR}: ssa.OpEqPtr,
-	opAndType{ir.OEQ, types.TFLOAT64}:   ssa.OpEq64F,
-	opAndType{ir.OEQ, types.TFLOAT32}:   ssa.OpEq32F,
+	{ir.OEQ, types.TBOOL}:      ssa.OpEqB,
+	{ir.OEQ, types.TINT8}:      ssa.OpEq8,
+	{ir.OEQ, types.TUINT8}:     ssa.OpEq8,
+	{ir.OEQ, types.TINT16}:     ssa.OpEq16,
+	{ir.OEQ, types.TUINT16}:    ssa.OpEq16,
+	{ir.OEQ, types.TINT32}:     ssa.OpEq32,
+	{ir.OEQ, types.TUINT32}:    ssa.OpEq32,
+	{ir.OEQ, types.TINT64}:     ssa.OpEq64,
+	{ir.OEQ, types.TUINT64}:    ssa.OpEq64,
+	{ir.OEQ, types.TINTER}:     ssa.OpEqInter,
+	{ir.OEQ, types.TSLICE}:     ssa.OpEqSlice,
+	{ir.OEQ, types.TFUNC}:      ssa.OpEqPtr,
+	{ir.OEQ, types.TMAP}:       ssa.OpEqPtr,
+	{ir.OEQ, types.TCHAN}:      ssa.OpEqPtr,
+	{ir.OEQ, types.TPTR}:       ssa.OpEqPtr,
+	{ir.OEQ, types.TUINTPTR}:   ssa.OpEqPtr,
+	{ir.OEQ, types.TUNSAFEPTR}: ssa.OpEqPtr,
+	{ir.OEQ, types.TFLOAT64}:   ssa.OpEq64F,
+	{ir.OEQ, types.TFLOAT32}:   ssa.OpEq32F,
 
-	opAndType{ir.ONE, types.TBOOL}:      ssa.OpNeqB,
-	opAndType{ir.ONE, types.TINT8}:      ssa.OpNeq8,
-	opAndType{ir.ONE, types.TUINT8}:     ssa.OpNeq8,
-	opAndType{ir.ONE, types.TINT16}:     ssa.OpNeq16,
-	opAndType{ir.ONE, types.TUINT16}:    ssa.OpNeq16,
-	opAndType{ir.ONE, types.TINT32}:     ssa.OpNeq32,
-	opAndType{ir.ONE, types.TUINT32}:    ssa.OpNeq32,
-	opAndType{ir.ONE, types.TINT64}:     ssa.OpNeq64,
-	opAndType{ir.ONE, types.TUINT64}:    ssa.OpNeq64,
-	opAndType{ir.ONE, types.TINTER}:     ssa.OpNeqInter,
-	opAndType{ir.ONE, types.TSLICE}:     ssa.OpNeqSlice,
-	opAndType{ir.ONE, types.TFUNC}:      ssa.OpNeqPtr,
-	opAndType{ir.ONE, types.TMAP}:       ssa.OpNeqPtr,
-	opAndType{ir.ONE, types.TCHAN}:      ssa.OpNeqPtr,
-	opAndType{ir.ONE, types.TPTR}:       ssa.OpNeqPtr,
-	opAndType{ir.ONE, types.TUINTPTR}:   ssa.OpNeqPtr,
-	opAndType{ir.ONE, types.TUNSAFEPTR}: ssa.OpNeqPtr,
-	opAndType{ir.ONE, types.TFLOAT64}:   ssa.OpNeq64F,
-	opAndType{ir.ONE, types.TFLOAT32}:   ssa.OpNeq32F,
+	{ir.ONE, types.TBOOL}:      ssa.OpNeqB,
+	{ir.ONE, types.TINT8}:      ssa.OpNeq8,
+	{ir.ONE, types.TUINT8}:     ssa.OpNeq8,
+	{ir.ONE, types.TINT16}:     ssa.OpNeq16,
+	{ir.ONE, types.TUINT16}:    ssa.OpNeq16,
+	{ir.ONE, types.TINT32}:     ssa.OpNeq32,
+	{ir.ONE, types.TUINT32}:    ssa.OpNeq32,
+	{ir.ONE, types.TINT64}:     ssa.OpNeq64,
+	{ir.ONE, types.TUINT64}:    ssa.OpNeq64,
+	{ir.ONE, types.TINTER}:     ssa.OpNeqInter,
+	{ir.ONE, types.TSLICE}:     ssa.OpNeqSlice,
+	{ir.ONE, types.TFUNC}:      ssa.OpNeqPtr,
+	{ir.ONE, types.TMAP}:       ssa.OpNeqPtr,
+	{ir.ONE, types.TCHAN}:      ssa.OpNeqPtr,
+	{ir.ONE, types.TPTR}:       ssa.OpNeqPtr,
+	{ir.ONE, types.TUINTPTR}:   ssa.OpNeqPtr,
+	{ir.ONE, types.TUNSAFEPTR}: ssa.OpNeqPtr,
+	{ir.ONE, types.TFLOAT64}:   ssa.OpNeq64F,
+	{ir.ONE, types.TFLOAT32}:   ssa.OpNeq32F,
 
-	opAndType{ir.OLT, types.TINT8}:    ssa.OpLess8,
-	opAndType{ir.OLT, types.TUINT8}:   ssa.OpLess8U,
-	opAndType{ir.OLT, types.TINT16}:   ssa.OpLess16,
-	opAndType{ir.OLT, types.TUINT16}:  ssa.OpLess16U,
-	opAndType{ir.OLT, types.TINT32}:   ssa.OpLess32,
-	opAndType{ir.OLT, types.TUINT32}:  ssa.OpLess32U,
-	opAndType{ir.OLT, types.TINT64}:   ssa.OpLess64,
-	opAndType{ir.OLT, types.TUINT64}:  ssa.OpLess64U,
-	opAndType{ir.OLT, types.TFLOAT64}: ssa.OpLess64F,
-	opAndType{ir.OLT, types.TFLOAT32}: ssa.OpLess32F,
+	{ir.OLT, types.TINT8}:    ssa.OpLess8,
+	{ir.OLT, types.TUINT8}:   ssa.OpLess8U,
+	{ir.OLT, types.TINT16}:   ssa.OpLess16,
+	{ir.OLT, types.TUINT16}:  ssa.OpLess16U,
+	{ir.OLT, types.TINT32}:   ssa.OpLess32,
+	{ir.OLT, types.TUINT32}:  ssa.OpLess32U,
+	{ir.OLT, types.TINT64}:   ssa.OpLess64,
+	{ir.OLT, types.TUINT64}:  ssa.OpLess64U,
+	{ir.OLT, types.TFLOAT64}: ssa.OpLess64F,
+	{ir.OLT, types.TFLOAT32}: ssa.OpLess32F,
 
-	opAndType{ir.OLE, types.TINT8}:    ssa.OpLeq8,
-	opAndType{ir.OLE, types.TUINT8}:   ssa.OpLeq8U,
-	opAndType{ir.OLE, types.TINT16}:   ssa.OpLeq16,
-	opAndType{ir.OLE, types.TUINT16}:  ssa.OpLeq16U,
-	opAndType{ir.OLE, types.TINT32}:   ssa.OpLeq32,
-	opAndType{ir.OLE, types.TUINT32}:  ssa.OpLeq32U,
-	opAndType{ir.OLE, types.TINT64}:   ssa.OpLeq64,
-	opAndType{ir.OLE, types.TUINT64}:  ssa.OpLeq64U,
-	opAndType{ir.OLE, types.TFLOAT64}: ssa.OpLeq64F,
-	opAndType{ir.OLE, types.TFLOAT32}: ssa.OpLeq32F,
+	{ir.OLE, types.TINT8}:    ssa.OpLeq8,
+	{ir.OLE, types.TUINT8}:   ssa.OpLeq8U,
+	{ir.OLE, types.TINT16}:   ssa.OpLeq16,
+	{ir.OLE, types.TUINT16}:  ssa.OpLeq16U,
+	{ir.OLE, types.TINT32}:   ssa.OpLeq32,
+	{ir.OLE, types.TUINT32}:  ssa.OpLeq32U,
+	{ir.OLE, types.TINT64}:   ssa.OpLeq64,
+	{ir.OLE, types.TUINT64}:  ssa.OpLeq64U,
+	{ir.OLE, types.TFLOAT64}: ssa.OpLeq64F,
+	{ir.OLE, types.TFLOAT32}: ssa.OpLeq32F,
 }
 
 func (s *state) concreteEtype(t *types.Type) types.Kind {
@@ -2285,142 +2306,142 @@
 
 var fpConvOpToSSA = map[twoTypes]twoOpsAndType{
 
-	twoTypes{types.TINT8, types.TFLOAT32}:  twoOpsAndType{ssa.OpSignExt8to32, ssa.OpCvt32to32F, types.TINT32},
-	twoTypes{types.TINT16, types.TFLOAT32}: twoOpsAndType{ssa.OpSignExt16to32, ssa.OpCvt32to32F, types.TINT32},
-	twoTypes{types.TINT32, types.TFLOAT32}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt32to32F, types.TINT32},
-	twoTypes{types.TINT64, types.TFLOAT32}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt64to32F, types.TINT64},
+	{types.TINT8, types.TFLOAT32}:  {ssa.OpSignExt8to32, ssa.OpCvt32to32F, types.TINT32},
+	{types.TINT16, types.TFLOAT32}: {ssa.OpSignExt16to32, ssa.OpCvt32to32F, types.TINT32},
+	{types.TINT32, types.TFLOAT32}: {ssa.OpCopy, ssa.OpCvt32to32F, types.TINT32},
+	{types.TINT64, types.TFLOAT32}: {ssa.OpCopy, ssa.OpCvt64to32F, types.TINT64},
 
-	twoTypes{types.TINT8, types.TFLOAT64}:  twoOpsAndType{ssa.OpSignExt8to32, ssa.OpCvt32to64F, types.TINT32},
-	twoTypes{types.TINT16, types.TFLOAT64}: twoOpsAndType{ssa.OpSignExt16to32, ssa.OpCvt32to64F, types.TINT32},
-	twoTypes{types.TINT32, types.TFLOAT64}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt32to64F, types.TINT32},
-	twoTypes{types.TINT64, types.TFLOAT64}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt64to64F, types.TINT64},
+	{types.TINT8, types.TFLOAT64}:  {ssa.OpSignExt8to32, ssa.OpCvt32to64F, types.TINT32},
+	{types.TINT16, types.TFLOAT64}: {ssa.OpSignExt16to32, ssa.OpCvt32to64F, types.TINT32},
+	{types.TINT32, types.TFLOAT64}: {ssa.OpCopy, ssa.OpCvt32to64F, types.TINT32},
+	{types.TINT64, types.TFLOAT64}: {ssa.OpCopy, ssa.OpCvt64to64F, types.TINT64},
 
-	twoTypes{types.TFLOAT32, types.TINT8}:  twoOpsAndType{ssa.OpCvt32Fto32, ssa.OpTrunc32to8, types.TINT32},
-	twoTypes{types.TFLOAT32, types.TINT16}: twoOpsAndType{ssa.OpCvt32Fto32, ssa.OpTrunc32to16, types.TINT32},
-	twoTypes{types.TFLOAT32, types.TINT32}: twoOpsAndType{ssa.OpCvt32Fto32, ssa.OpCopy, types.TINT32},
-	twoTypes{types.TFLOAT32, types.TINT64}: twoOpsAndType{ssa.OpCvt32Fto64, ssa.OpCopy, types.TINT64},
+	{types.TFLOAT32, types.TINT8}:  {ssa.OpCvt32Fto32, ssa.OpTrunc32to8, types.TINT32},
+	{types.TFLOAT32, types.TINT16}: {ssa.OpCvt32Fto32, ssa.OpTrunc32to16, types.TINT32},
+	{types.TFLOAT32, types.TINT32}: {ssa.OpCvt32Fto32, ssa.OpCopy, types.TINT32},
+	{types.TFLOAT32, types.TINT64}: {ssa.OpCvt32Fto64, ssa.OpCopy, types.TINT64},
 
-	twoTypes{types.TFLOAT64, types.TINT8}:  twoOpsAndType{ssa.OpCvt64Fto32, ssa.OpTrunc32to8, types.TINT32},
-	twoTypes{types.TFLOAT64, types.TINT16}: twoOpsAndType{ssa.OpCvt64Fto32, ssa.OpTrunc32to16, types.TINT32},
-	twoTypes{types.TFLOAT64, types.TINT32}: twoOpsAndType{ssa.OpCvt64Fto32, ssa.OpCopy, types.TINT32},
-	twoTypes{types.TFLOAT64, types.TINT64}: twoOpsAndType{ssa.OpCvt64Fto64, ssa.OpCopy, types.TINT64},
+	{types.TFLOAT64, types.TINT8}:  {ssa.OpCvt64Fto32, ssa.OpTrunc32to8, types.TINT32},
+	{types.TFLOAT64, types.TINT16}: {ssa.OpCvt64Fto32, ssa.OpTrunc32to16, types.TINT32},
+	{types.TFLOAT64, types.TINT32}: {ssa.OpCvt64Fto32, ssa.OpCopy, types.TINT32},
+	{types.TFLOAT64, types.TINT64}: {ssa.OpCvt64Fto64, ssa.OpCopy, types.TINT64},
 	// unsigned
-	twoTypes{types.TUINT8, types.TFLOAT32}:  twoOpsAndType{ssa.OpZeroExt8to32, ssa.OpCvt32to32F, types.TINT32},
-	twoTypes{types.TUINT16, types.TFLOAT32}: twoOpsAndType{ssa.OpZeroExt16to32, ssa.OpCvt32to32F, types.TINT32},
-	twoTypes{types.TUINT32, types.TFLOAT32}: twoOpsAndType{ssa.OpZeroExt32to64, ssa.OpCvt64to32F, types.TINT64}, // go wide to dodge unsigned
-	twoTypes{types.TUINT64, types.TFLOAT32}: twoOpsAndType{ssa.OpCopy, ssa.OpInvalid, types.TUINT64},            // Cvt64Uto32F, branchy code expansion instead
+	{types.TUINT8, types.TFLOAT32}:  {ssa.OpZeroExt8to32, ssa.OpCvt32to32F, types.TINT32},
+	{types.TUINT16, types.TFLOAT32}: {ssa.OpZeroExt16to32, ssa.OpCvt32to32F, types.TINT32},
+	{types.TUINT32, types.TFLOAT32}: {ssa.OpZeroExt32to64, ssa.OpCvt64to32F, types.TINT64}, // go wide to dodge unsigned
+	{types.TUINT64, types.TFLOAT32}: {ssa.OpCopy, ssa.OpInvalid, types.TUINT64},            // Cvt64Uto32F, branchy code expansion instead
 
-	twoTypes{types.TUINT8, types.TFLOAT64}:  twoOpsAndType{ssa.OpZeroExt8to32, ssa.OpCvt32to64F, types.TINT32},
-	twoTypes{types.TUINT16, types.TFLOAT64}: twoOpsAndType{ssa.OpZeroExt16to32, ssa.OpCvt32to64F, types.TINT32},
-	twoTypes{types.TUINT32, types.TFLOAT64}: twoOpsAndType{ssa.OpZeroExt32to64, ssa.OpCvt64to64F, types.TINT64}, // go wide to dodge unsigned
-	twoTypes{types.TUINT64, types.TFLOAT64}: twoOpsAndType{ssa.OpCopy, ssa.OpInvalid, types.TUINT64},            // Cvt64Uto64F, branchy code expansion instead
+	{types.TUINT8, types.TFLOAT64}:  {ssa.OpZeroExt8to32, ssa.OpCvt32to64F, types.TINT32},
+	{types.TUINT16, types.TFLOAT64}: {ssa.OpZeroExt16to32, ssa.OpCvt32to64F, types.TINT32},
+	{types.TUINT32, types.TFLOAT64}: {ssa.OpZeroExt32to64, ssa.OpCvt64to64F, types.TINT64}, // go wide to dodge unsigned
+	{types.TUINT64, types.TFLOAT64}: {ssa.OpCopy, ssa.OpInvalid, types.TUINT64},            // Cvt64Uto64F, branchy code expansion instead
 
-	twoTypes{types.TFLOAT32, types.TUINT8}:  twoOpsAndType{ssa.OpCvt32Fto32, ssa.OpTrunc32to8, types.TINT32},
-	twoTypes{types.TFLOAT32, types.TUINT16}: twoOpsAndType{ssa.OpCvt32Fto32, ssa.OpTrunc32to16, types.TINT32},
-	twoTypes{types.TFLOAT32, types.TUINT32}: twoOpsAndType{ssa.OpCvt32Fto64, ssa.OpTrunc64to32, types.TINT64}, // go wide to dodge unsigned
-	twoTypes{types.TFLOAT32, types.TUINT64}: twoOpsAndType{ssa.OpInvalid, ssa.OpCopy, types.TUINT64},          // Cvt32Fto64U, branchy code expansion instead
+	{types.TFLOAT32, types.TUINT8}:  {ssa.OpCvt32Fto32, ssa.OpTrunc32to8, types.TINT32},
+	{types.TFLOAT32, types.TUINT16}: {ssa.OpCvt32Fto32, ssa.OpTrunc32to16, types.TINT32},
+	{types.TFLOAT32, types.TUINT32}: {ssa.OpCvt32Fto64, ssa.OpTrunc64to32, types.TINT64}, // go wide to dodge unsigned
+	{types.TFLOAT32, types.TUINT64}: {ssa.OpInvalid, ssa.OpCopy, types.TUINT64},          // Cvt32Fto64U, branchy code expansion instead
 
-	twoTypes{types.TFLOAT64, types.TUINT8}:  twoOpsAndType{ssa.OpCvt64Fto32, ssa.OpTrunc32to8, types.TINT32},
-	twoTypes{types.TFLOAT64, types.TUINT16}: twoOpsAndType{ssa.OpCvt64Fto32, ssa.OpTrunc32to16, types.TINT32},
-	twoTypes{types.TFLOAT64, types.TUINT32}: twoOpsAndType{ssa.OpCvt64Fto64, ssa.OpTrunc64to32, types.TINT64}, // go wide to dodge unsigned
-	twoTypes{types.TFLOAT64, types.TUINT64}: twoOpsAndType{ssa.OpInvalid, ssa.OpCopy, types.TUINT64},          // Cvt64Fto64U, branchy code expansion instead
+	{types.TFLOAT64, types.TUINT8}:  {ssa.OpCvt64Fto32, ssa.OpTrunc32to8, types.TINT32},
+	{types.TFLOAT64, types.TUINT16}: {ssa.OpCvt64Fto32, ssa.OpTrunc32to16, types.TINT32},
+	{types.TFLOAT64, types.TUINT32}: {ssa.OpCvt64Fto64, ssa.OpTrunc64to32, types.TINT64}, // go wide to dodge unsigned
+	{types.TFLOAT64, types.TUINT64}: {ssa.OpInvalid, ssa.OpCopy, types.TUINT64},          // Cvt64Fto64U, branchy code expansion instead
 
 	// float
-	twoTypes{types.TFLOAT64, types.TFLOAT32}: twoOpsAndType{ssa.OpCvt64Fto32F, ssa.OpCopy, types.TFLOAT32},
-	twoTypes{types.TFLOAT64, types.TFLOAT64}: twoOpsAndType{ssa.OpRound64F, ssa.OpCopy, types.TFLOAT64},
-	twoTypes{types.TFLOAT32, types.TFLOAT32}: twoOpsAndType{ssa.OpRound32F, ssa.OpCopy, types.TFLOAT32},
-	twoTypes{types.TFLOAT32, types.TFLOAT64}: twoOpsAndType{ssa.OpCvt32Fto64F, ssa.OpCopy, types.TFLOAT64},
+	{types.TFLOAT64, types.TFLOAT32}: {ssa.OpCvt64Fto32F, ssa.OpCopy, types.TFLOAT32},
+	{types.TFLOAT64, types.TFLOAT64}: {ssa.OpRound64F, ssa.OpCopy, types.TFLOAT64},
+	{types.TFLOAT32, types.TFLOAT32}: {ssa.OpRound32F, ssa.OpCopy, types.TFLOAT32},
+	{types.TFLOAT32, types.TFLOAT64}: {ssa.OpCvt32Fto64F, ssa.OpCopy, types.TFLOAT64},
 }
 
 // this map is used only for 32-bit arch, and only includes the difference
 // on 32-bit arch, don't use int64<->float conversion for uint32
 var fpConvOpToSSA32 = map[twoTypes]twoOpsAndType{
-	twoTypes{types.TUINT32, types.TFLOAT32}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt32Uto32F, types.TUINT32},
-	twoTypes{types.TUINT32, types.TFLOAT64}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt32Uto64F, types.TUINT32},
-	twoTypes{types.TFLOAT32, types.TUINT32}: twoOpsAndType{ssa.OpCvt32Fto32U, ssa.OpCopy, types.TUINT32},
-	twoTypes{types.TFLOAT64, types.TUINT32}: twoOpsAndType{ssa.OpCvt64Fto32U, ssa.OpCopy, types.TUINT32},
+	{types.TUINT32, types.TFLOAT32}: {ssa.OpCopy, ssa.OpCvt32Uto32F, types.TUINT32},
+	{types.TUINT32, types.TFLOAT64}: {ssa.OpCopy, ssa.OpCvt32Uto64F, types.TUINT32},
+	{types.TFLOAT32, types.TUINT32}: {ssa.OpCvt32Fto32U, ssa.OpCopy, types.TUINT32},
+	{types.TFLOAT64, types.TUINT32}: {ssa.OpCvt64Fto32U, ssa.OpCopy, types.TUINT32},
 }
 
 // uint64<->float conversions, only on machines that have instructions for that
 var uint64fpConvOpToSSA = map[twoTypes]twoOpsAndType{
-	twoTypes{types.TUINT64, types.TFLOAT32}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt64Uto32F, types.TUINT64},
-	twoTypes{types.TUINT64, types.TFLOAT64}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt64Uto64F, types.TUINT64},
-	twoTypes{types.TFLOAT32, types.TUINT64}: twoOpsAndType{ssa.OpCvt32Fto64U, ssa.OpCopy, types.TUINT64},
-	twoTypes{types.TFLOAT64, types.TUINT64}: twoOpsAndType{ssa.OpCvt64Fto64U, ssa.OpCopy, types.TUINT64},
+	{types.TUINT64, types.TFLOAT32}: {ssa.OpCopy, ssa.OpCvt64Uto32F, types.TUINT64},
+	{types.TUINT64, types.TFLOAT64}: {ssa.OpCopy, ssa.OpCvt64Uto64F, types.TUINT64},
+	{types.TFLOAT32, types.TUINT64}: {ssa.OpCvt32Fto64U, ssa.OpCopy, types.TUINT64},
+	{types.TFLOAT64, types.TUINT64}: {ssa.OpCvt64Fto64U, ssa.OpCopy, types.TUINT64},
 }
 
 var shiftOpToSSA = map[opAndTwoTypes]ssa.Op{
-	opAndTwoTypes{ir.OLSH, types.TINT8, types.TUINT8}:   ssa.OpLsh8x8,
-	opAndTwoTypes{ir.OLSH, types.TUINT8, types.TUINT8}:  ssa.OpLsh8x8,
-	opAndTwoTypes{ir.OLSH, types.TINT8, types.TUINT16}:  ssa.OpLsh8x16,
-	opAndTwoTypes{ir.OLSH, types.TUINT8, types.TUINT16}: ssa.OpLsh8x16,
-	opAndTwoTypes{ir.OLSH, types.TINT8, types.TUINT32}:  ssa.OpLsh8x32,
-	opAndTwoTypes{ir.OLSH, types.TUINT8, types.TUINT32}: ssa.OpLsh8x32,
-	opAndTwoTypes{ir.OLSH, types.TINT8, types.TUINT64}:  ssa.OpLsh8x64,
-	opAndTwoTypes{ir.OLSH, types.TUINT8, types.TUINT64}: ssa.OpLsh8x64,
+	{ir.OLSH, types.TINT8, types.TUINT8}:   ssa.OpLsh8x8,
+	{ir.OLSH, types.TUINT8, types.TUINT8}:  ssa.OpLsh8x8,
+	{ir.OLSH, types.TINT8, types.TUINT16}:  ssa.OpLsh8x16,
+	{ir.OLSH, types.TUINT8, types.TUINT16}: ssa.OpLsh8x16,
+	{ir.OLSH, types.TINT8, types.TUINT32}:  ssa.OpLsh8x32,
+	{ir.OLSH, types.TUINT8, types.TUINT32}: ssa.OpLsh8x32,
+	{ir.OLSH, types.TINT8, types.TUINT64}:  ssa.OpLsh8x64,
+	{ir.OLSH, types.TUINT8, types.TUINT64}: ssa.OpLsh8x64,
 
-	opAndTwoTypes{ir.OLSH, types.TINT16, types.TUINT8}:   ssa.OpLsh16x8,
-	opAndTwoTypes{ir.OLSH, types.TUINT16, types.TUINT8}:  ssa.OpLsh16x8,
-	opAndTwoTypes{ir.OLSH, types.TINT16, types.TUINT16}:  ssa.OpLsh16x16,
-	opAndTwoTypes{ir.OLSH, types.TUINT16, types.TUINT16}: ssa.OpLsh16x16,
-	opAndTwoTypes{ir.OLSH, types.TINT16, types.TUINT32}:  ssa.OpLsh16x32,
-	opAndTwoTypes{ir.OLSH, types.TUINT16, types.TUINT32}: ssa.OpLsh16x32,
-	opAndTwoTypes{ir.OLSH, types.TINT16, types.TUINT64}:  ssa.OpLsh16x64,
-	opAndTwoTypes{ir.OLSH, types.TUINT16, types.TUINT64}: ssa.OpLsh16x64,
+	{ir.OLSH, types.TINT16, types.TUINT8}:   ssa.OpLsh16x8,
+	{ir.OLSH, types.TUINT16, types.TUINT8}:  ssa.OpLsh16x8,
+	{ir.OLSH, types.TINT16, types.TUINT16}:  ssa.OpLsh16x16,
+	{ir.OLSH, types.TUINT16, types.TUINT16}: ssa.OpLsh16x16,
+	{ir.OLSH, types.TINT16, types.TUINT32}:  ssa.OpLsh16x32,
+	{ir.OLSH, types.TUINT16, types.TUINT32}: ssa.OpLsh16x32,
+	{ir.OLSH, types.TINT16, types.TUINT64}:  ssa.OpLsh16x64,
+	{ir.OLSH, types.TUINT16, types.TUINT64}: ssa.OpLsh16x64,
 
-	opAndTwoTypes{ir.OLSH, types.TINT32, types.TUINT8}:   ssa.OpLsh32x8,
-	opAndTwoTypes{ir.OLSH, types.TUINT32, types.TUINT8}:  ssa.OpLsh32x8,
-	opAndTwoTypes{ir.OLSH, types.TINT32, types.TUINT16}:  ssa.OpLsh32x16,
-	opAndTwoTypes{ir.OLSH, types.TUINT32, types.TUINT16}: ssa.OpLsh32x16,
-	opAndTwoTypes{ir.OLSH, types.TINT32, types.TUINT32}:  ssa.OpLsh32x32,
-	opAndTwoTypes{ir.OLSH, types.TUINT32, types.TUINT32}: ssa.OpLsh32x32,
-	opAndTwoTypes{ir.OLSH, types.TINT32, types.TUINT64}:  ssa.OpLsh32x64,
-	opAndTwoTypes{ir.OLSH, types.TUINT32, types.TUINT64}: ssa.OpLsh32x64,
+	{ir.OLSH, types.TINT32, types.TUINT8}:   ssa.OpLsh32x8,
+	{ir.OLSH, types.TUINT32, types.TUINT8}:  ssa.OpLsh32x8,
+	{ir.OLSH, types.TINT32, types.TUINT16}:  ssa.OpLsh32x16,
+	{ir.OLSH, types.TUINT32, types.TUINT16}: ssa.OpLsh32x16,
+	{ir.OLSH, types.TINT32, types.TUINT32}:  ssa.OpLsh32x32,
+	{ir.OLSH, types.TUINT32, types.TUINT32}: ssa.OpLsh32x32,
+	{ir.OLSH, types.TINT32, types.TUINT64}:  ssa.OpLsh32x64,
+	{ir.OLSH, types.TUINT32, types.TUINT64}: ssa.OpLsh32x64,
 
-	opAndTwoTypes{ir.OLSH, types.TINT64, types.TUINT8}:   ssa.OpLsh64x8,
-	opAndTwoTypes{ir.OLSH, types.TUINT64, types.TUINT8}:  ssa.OpLsh64x8,
-	opAndTwoTypes{ir.OLSH, types.TINT64, types.TUINT16}:  ssa.OpLsh64x16,
-	opAndTwoTypes{ir.OLSH, types.TUINT64, types.TUINT16}: ssa.OpLsh64x16,
-	opAndTwoTypes{ir.OLSH, types.TINT64, types.TUINT32}:  ssa.OpLsh64x32,
-	opAndTwoTypes{ir.OLSH, types.TUINT64, types.TUINT32}: ssa.OpLsh64x32,
-	opAndTwoTypes{ir.OLSH, types.TINT64, types.TUINT64}:  ssa.OpLsh64x64,
-	opAndTwoTypes{ir.OLSH, types.TUINT64, types.TUINT64}: ssa.OpLsh64x64,
+	{ir.OLSH, types.TINT64, types.TUINT8}:   ssa.OpLsh64x8,
+	{ir.OLSH, types.TUINT64, types.TUINT8}:  ssa.OpLsh64x8,
+	{ir.OLSH, types.TINT64, types.TUINT16}:  ssa.OpLsh64x16,
+	{ir.OLSH, types.TUINT64, types.TUINT16}: ssa.OpLsh64x16,
+	{ir.OLSH, types.TINT64, types.TUINT32}:  ssa.OpLsh64x32,
+	{ir.OLSH, types.TUINT64, types.TUINT32}: ssa.OpLsh64x32,
+	{ir.OLSH, types.TINT64, types.TUINT64}:  ssa.OpLsh64x64,
+	{ir.OLSH, types.TUINT64, types.TUINT64}: ssa.OpLsh64x64,
 
-	opAndTwoTypes{ir.ORSH, types.TINT8, types.TUINT8}:   ssa.OpRsh8x8,
-	opAndTwoTypes{ir.ORSH, types.TUINT8, types.TUINT8}:  ssa.OpRsh8Ux8,
-	opAndTwoTypes{ir.ORSH, types.TINT8, types.TUINT16}:  ssa.OpRsh8x16,
-	opAndTwoTypes{ir.ORSH, types.TUINT8, types.TUINT16}: ssa.OpRsh8Ux16,
-	opAndTwoTypes{ir.ORSH, types.TINT8, types.TUINT32}:  ssa.OpRsh8x32,
-	opAndTwoTypes{ir.ORSH, types.TUINT8, types.TUINT32}: ssa.OpRsh8Ux32,
-	opAndTwoTypes{ir.ORSH, types.TINT8, types.TUINT64}:  ssa.OpRsh8x64,
-	opAndTwoTypes{ir.ORSH, types.TUINT8, types.TUINT64}: ssa.OpRsh8Ux64,
+	{ir.ORSH, types.TINT8, types.TUINT8}:   ssa.OpRsh8x8,
+	{ir.ORSH, types.TUINT8, types.TUINT8}:  ssa.OpRsh8Ux8,
+	{ir.ORSH, types.TINT8, types.TUINT16}:  ssa.OpRsh8x16,
+	{ir.ORSH, types.TUINT8, types.TUINT16}: ssa.OpRsh8Ux16,
+	{ir.ORSH, types.TINT8, types.TUINT32}:  ssa.OpRsh8x32,
+	{ir.ORSH, types.TUINT8, types.TUINT32}: ssa.OpRsh8Ux32,
+	{ir.ORSH, types.TINT8, types.TUINT64}:  ssa.OpRsh8x64,
+	{ir.ORSH, types.TUINT8, types.TUINT64}: ssa.OpRsh8Ux64,
 
-	opAndTwoTypes{ir.ORSH, types.TINT16, types.TUINT8}:   ssa.OpRsh16x8,
-	opAndTwoTypes{ir.ORSH, types.TUINT16, types.TUINT8}:  ssa.OpRsh16Ux8,
-	opAndTwoTypes{ir.ORSH, types.TINT16, types.TUINT16}:  ssa.OpRsh16x16,
-	opAndTwoTypes{ir.ORSH, types.TUINT16, types.TUINT16}: ssa.OpRsh16Ux16,
-	opAndTwoTypes{ir.ORSH, types.TINT16, types.TUINT32}:  ssa.OpRsh16x32,
-	opAndTwoTypes{ir.ORSH, types.TUINT16, types.TUINT32}: ssa.OpRsh16Ux32,
-	opAndTwoTypes{ir.ORSH, types.TINT16, types.TUINT64}:  ssa.OpRsh16x64,
-	opAndTwoTypes{ir.ORSH, types.TUINT16, types.TUINT64}: ssa.OpRsh16Ux64,
+	{ir.ORSH, types.TINT16, types.TUINT8}:   ssa.OpRsh16x8,
+	{ir.ORSH, types.TUINT16, types.TUINT8}:  ssa.OpRsh16Ux8,
+	{ir.ORSH, types.TINT16, types.TUINT16}:  ssa.OpRsh16x16,
+	{ir.ORSH, types.TUINT16, types.TUINT16}: ssa.OpRsh16Ux16,
+	{ir.ORSH, types.TINT16, types.TUINT32}:  ssa.OpRsh16x32,
+	{ir.ORSH, types.TUINT16, types.TUINT32}: ssa.OpRsh16Ux32,
+	{ir.ORSH, types.TINT16, types.TUINT64}:  ssa.OpRsh16x64,
+	{ir.ORSH, types.TUINT16, types.TUINT64}: ssa.OpRsh16Ux64,
 
-	opAndTwoTypes{ir.ORSH, types.TINT32, types.TUINT8}:   ssa.OpRsh32x8,
-	opAndTwoTypes{ir.ORSH, types.TUINT32, types.TUINT8}:  ssa.OpRsh32Ux8,
-	opAndTwoTypes{ir.ORSH, types.TINT32, types.TUINT16}:  ssa.OpRsh32x16,
-	opAndTwoTypes{ir.ORSH, types.TUINT32, types.TUINT16}: ssa.OpRsh32Ux16,
-	opAndTwoTypes{ir.ORSH, types.TINT32, types.TUINT32}:  ssa.OpRsh32x32,
-	opAndTwoTypes{ir.ORSH, types.TUINT32, types.TUINT32}: ssa.OpRsh32Ux32,
-	opAndTwoTypes{ir.ORSH, types.TINT32, types.TUINT64}:  ssa.OpRsh32x64,
-	opAndTwoTypes{ir.ORSH, types.TUINT32, types.TUINT64}: ssa.OpRsh32Ux64,
+	{ir.ORSH, types.TINT32, types.TUINT8}:   ssa.OpRsh32x8,
+	{ir.ORSH, types.TUINT32, types.TUINT8}:  ssa.OpRsh32Ux8,
+	{ir.ORSH, types.TINT32, types.TUINT16}:  ssa.OpRsh32x16,
+	{ir.ORSH, types.TUINT32, types.TUINT16}: ssa.OpRsh32Ux16,
+	{ir.ORSH, types.TINT32, types.TUINT32}:  ssa.OpRsh32x32,
+	{ir.ORSH, types.TUINT32, types.TUINT32}: ssa.OpRsh32Ux32,
+	{ir.ORSH, types.TINT32, types.TUINT64}:  ssa.OpRsh32x64,
+	{ir.ORSH, types.TUINT32, types.TUINT64}: ssa.OpRsh32Ux64,
 
-	opAndTwoTypes{ir.ORSH, types.TINT64, types.TUINT8}:   ssa.OpRsh64x8,
-	opAndTwoTypes{ir.ORSH, types.TUINT64, types.TUINT8}:  ssa.OpRsh64Ux8,
-	opAndTwoTypes{ir.ORSH, types.TINT64, types.TUINT16}:  ssa.OpRsh64x16,
-	opAndTwoTypes{ir.ORSH, types.TUINT64, types.TUINT16}: ssa.OpRsh64Ux16,
-	opAndTwoTypes{ir.ORSH, types.TINT64, types.TUINT32}:  ssa.OpRsh64x32,
-	opAndTwoTypes{ir.ORSH, types.TUINT64, types.TUINT32}: ssa.OpRsh64Ux32,
-	opAndTwoTypes{ir.ORSH, types.TINT64, types.TUINT64}:  ssa.OpRsh64x64,
-	opAndTwoTypes{ir.ORSH, types.TUINT64, types.TUINT64}: ssa.OpRsh64Ux64,
+	{ir.ORSH, types.TINT64, types.TUINT8}:   ssa.OpRsh64x8,
+	{ir.ORSH, types.TUINT64, types.TUINT8}:  ssa.OpRsh64Ux8,
+	{ir.ORSH, types.TINT64, types.TUINT16}:  ssa.OpRsh64x16,
+	{ir.ORSH, types.TUINT64, types.TUINT16}: ssa.OpRsh64Ux16,
+	{ir.ORSH, types.TINT64, types.TUINT32}:  ssa.OpRsh64x32,
+	{ir.ORSH, types.TUINT64, types.TUINT32}: ssa.OpRsh64Ux32,
+	{ir.ORSH, types.TINT64, types.TUINT64}:  ssa.OpRsh64x64,
+	{ir.ORSH, types.TUINT64, types.TUINT64}: ssa.OpRsh64Ux64,
 }
 
 func (s *state) ssaShiftOp(op ir.Op, t *types.Type, u *types.Type) ssa.Op {
@@ -3210,6 +3231,12 @@
 		c := s.expr(n.Cap)
 		return s.newValue3(ssa.OpSliceMake, n.Type(), p, l, c)
 
+	case ir.OSTRINGHEADER:
+		n := n.(*ir.StringHeaderExpr)
+		p := s.expr(n.Ptr)
+		l := s.expr(n.Len)
+		return s.newValue2(ssa.OpStringMake, n.Type(), p, l)
+
 	case ir.OSLICE, ir.OSLICEARR, ir.OSLICE3, ir.OSLICE3ARR:
 		n := n.(*ir.SliceExpr)
 		check := s.checkPtrEnabled && n.Op() == ir.OSLICE3ARR && n.X.Op() == ir.OCONVNOP && n.X.(*ir.ConvExpr).X.Type().IsUnsafePtr()
@@ -3294,7 +3321,11 @@
 
 	case ir.ONEW:
 		n := n.(*ir.UnaryExpr)
-		return s.newObject(n.Type().Elem())
+		var rtype *ssa.Value
+		if x, ok := n.X.(*ir.DynamicType); ok && x.Op() == ir.ODYNAMICTYPE {
+			rtype = s.expr(x.RType)
+		}
+		return s.newObject(n.Type().Elem(), rtype)
 
 	case ir.OUNSAFEADD:
 		n := n.(*ir.BinaryExpr)
@@ -3343,46 +3374,46 @@
 // If inplace is true, it writes the result of the OAPPEND expression n
 // back to the slice being appended to, and returns nil.
 // inplace MUST be set to false if the slice can be SSA'd.
+// Note: this code only handles fixed-count appends. Dotdotdot appends
+// have already been rewritten at this point (by walk).
 func (s *state) append(n *ir.CallExpr, inplace bool) *ssa.Value {
 	// If inplace is false, process as expression "append(s, e1, e2, e3)":
 	//
 	// ptr, len, cap := s
-	// newlen := len + 3
-	// if newlen > cap {
-	//     ptr, len, cap = growslice(s, newlen)
-	//     newlen = len + 3 // recalculate to avoid a spill
+	// len += 3
+	// if uint(len) > uint(cap) {
+	//     ptr, len, cap = growslice(ptr, len, cap, 3, typ)
+	//     Note that len is unmodified by growslice.
 	// }
 	// // with write barriers, if needed:
-	// *(ptr+len) = e1
-	// *(ptr+len+1) = e2
-	// *(ptr+len+2) = e3
-	// return makeslice(ptr, newlen, cap)
+	// *(ptr+(len-3)) = e1
+	// *(ptr+(len-2)) = e2
+	// *(ptr+(len-1)) = e3
+	// return makeslice(ptr, len, cap)
 	//
 	//
 	// If inplace is true, process as statement "s = append(s, e1, e2, e3)":
 	//
 	// a := &s
 	// ptr, len, cap := s
-	// newlen := len + 3
-	// if uint(newlen) > uint(cap) {
-	//    newptr, len, newcap = growslice(ptr, len, cap, newlen)
-	//    vardef(a)       // if necessary, advise liveness we are writing a new a
-	//    *a.cap = newcap // write before ptr to avoid a spill
-	//    *a.ptr = newptr // with write barrier
+	// len += 3
+	// if uint(len) > uint(cap) {
+	//    ptr, len, cap = growslice(ptr, len, cap, 3, typ)
+	//    vardef(a)    // if necessary, advise liveness we are writing a new a
+	//    *a.cap = cap // write before ptr to avoid a spill
+	//    *a.ptr = ptr // with write barrier
 	// }
-	// newlen = len + 3 // recalculate to avoid a spill
-	// *a.len = newlen
+	// *a.len = len
 	// // with write barriers, if needed:
-	// *(ptr+len) = e1
-	// *(ptr+len+1) = e2
-	// *(ptr+len+2) = e3
+	// *(ptr+(len-3)) = e1
+	// *(ptr+(len-2)) = e2
+	// *(ptr+(len-1)) = e3
 
 	et := n.Type().Elem()
 	pt := types.NewPtr(et)
 
 	// Evaluate slice
 	sn := n.Args[0] // the slice node is the first in the list
-
 	var slice, addr *ssa.Value
 	if inplace {
 		addr = s.addr(sn)
@@ -3395,21 +3426,23 @@
 	grow := s.f.NewBlock(ssa.BlockPlain)
 	assign := s.f.NewBlock(ssa.BlockPlain)
 
-	// Decide if we need to grow
-	nargs := int64(len(n.Args) - 1)
+	// Decomposse input slice.
 	p := s.newValue1(ssa.OpSlicePtr, pt, slice)
 	l := s.newValue1(ssa.OpSliceLen, types.Types[types.TINT], slice)
 	c := s.newValue1(ssa.OpSliceCap, types.Types[types.TINT], slice)
-	nl := s.newValue2(s.ssaOp(ir.OADD, types.Types[types.TINT]), types.Types[types.TINT], l, s.constInt(types.Types[types.TINT], nargs))
 
-	cmp := s.newValue2(s.ssaOp(ir.OLT, types.Types[types.TUINT]), types.Types[types.TBOOL], c, nl)
+	// Add number of new elements to length.
+	nargs := s.constInt(types.Types[types.TINT], int64(len(n.Args)-1))
+	l = s.newValue2(s.ssaOp(ir.OADD, types.Types[types.TINT]), types.Types[types.TINT], l, nargs)
+
+	// Decide if we need to grow
+	cmp := s.newValue2(s.ssaOp(ir.OLT, types.Types[types.TUINT]), types.Types[types.TBOOL], c, l)
+
+	// Record values of ptr/len/cap before branch.
 	s.vars[ptrVar] = p
-
+	s.vars[lenVar] = l
 	if !inplace {
-		s.vars[newlenVar] = nl
 		s.vars[capVar] = c
-	} else {
-		s.vars[lenVar] = l
 	}
 
 	b := s.endBlock()
@@ -3422,8 +3455,16 @@
 	// Call growslice
 	s.startBlock(grow)
 	taddr := s.expr(n.X)
-	r := s.rtcall(ir.Syms.Growslice, true, []*types.Type{pt, types.Types[types.TINT], types.Types[types.TINT]}, taddr, p, l, c, nl)
+	r := s.rtcall(ir.Syms.Growslice, true, []*types.Type{n.Type()}, p, l, c, nargs, taddr)
 
+	// Decompose output slice
+	p = s.newValue1(ssa.OpSlicePtr, pt, r[0])
+	l = s.newValue1(ssa.OpSliceLen, types.Types[types.TINT], r[0])
+	c = s.newValue1(ssa.OpSliceCap, types.Types[types.TINT], r[0])
+
+	s.vars[ptrVar] = p
+	s.vars[lenVar] = l
+	s.vars[capVar] = c
 	if inplace {
 		if sn.Op() == ir.ONAME {
 			sn := sn.(*ir.Name)
@@ -3433,15 +3474,8 @@
 			}
 		}
 		capaddr := s.newValue1I(ssa.OpOffPtr, s.f.Config.Types.IntPtr, types.SliceCapOffset, addr)
-		s.store(types.Types[types.TINT], capaddr, r[2])
-		s.store(pt, addr, r[0])
-		// load the value we just stored to avoid having to spill it
-		s.vars[ptrVar] = s.load(pt, addr)
-		s.vars[lenVar] = r[1] // avoid a spill in the fast path
-	} else {
-		s.vars[ptrVar] = r[0]
-		s.vars[newlenVar] = s.newValue2(s.ssaOp(ir.OADD, types.Types[types.TINT]), types.Types[types.TINT], r[1], s.constInt(types.Types[types.TINT], nargs))
-		s.vars[capVar] = r[2]
+		s.store(types.Types[types.TINT], capaddr, c)
+		s.store(pt, addr, p)
 	}
 
 	b = s.endBlock()
@@ -3449,12 +3483,17 @@
 
 	// assign new elements to slots
 	s.startBlock(assign)
+	p = s.variable(ptrVar, pt)                      // generates phi for ptr
+	l = s.variable(lenVar, types.Types[types.TINT]) // generates phi for len
+	if !inplace {
+		c = s.variable(capVar, types.Types[types.TINT]) // generates phi for cap
+	}
 
 	if inplace {
-		l = s.variable(lenVar, types.Types[types.TINT]) // generates phi for len
-		nl = s.newValue2(s.ssaOp(ir.OADD, types.Types[types.TINT]), types.Types[types.TINT], l, s.constInt(types.Types[types.TINT], nargs))
+		// Update length in place.
+		// We have to wait until here to make sure growslice succeeded.
 		lenaddr := s.newValue1I(ssa.OpOffPtr, s.f.Config.Types.IntPtr, types.SliceLenOffset, addr)
-		s.store(types.Types[types.TINT], lenaddr, nl)
+		s.store(types.Types[types.TINT], lenaddr, l)
 	}
 
 	// Evaluate args
@@ -3464,7 +3503,7 @@
 		v     *ssa.Value
 		store bool
 	}
-	args := make([]argRec, 0, nargs)
+	args := make([]argRec, 0, len(n.Args[1:]))
 	for _, n := range n.Args[1:] {
 		if TypeOK(n.Type()) {
 			args = append(args, argRec{v: s.expr(n), store: true})
@@ -3474,12 +3513,9 @@
 		}
 	}
 
-	p = s.variable(ptrVar, pt) // generates phi for ptr
-	if !inplace {
-		nl = s.variable(newlenVar, types.Types[types.TINT]) // generates phi for nl
-		c = s.variable(capVar, types.Types[types.TINT])     // generates phi for cap
-	}
-	p2 := s.newValue2(ssa.OpPtrIndex, pt, p, l)
+	// Write args into slice.
+	oldLen := s.newValue2(s.ssaOp(ir.OSUB, types.Types[types.TINT]), types.Types[types.TINT], l, nargs)
+	p2 := s.newValue2(ssa.OpPtrIndex, pt, p, oldLen)
 	for i, arg := range args {
 		addr := s.newValue2(ssa.OpPtrIndex, pt, p2, s.constInt(types.Types[types.TINT], int64(i)))
 		if arg.store {
@@ -3490,14 +3526,16 @@
 	}
 
 	delete(s.vars, ptrVar)
+	delete(s.vars, lenVar)
+	if !inplace {
+		delete(s.vars, capVar)
+	}
+
+	// make result
 	if inplace {
-		delete(s.vars, lenVar)
 		return nil
 	}
-	delete(s.vars, newlenVar)
-	delete(s.vars, capVar)
-	// make result
-	return s.newValue3(ssa.OpSliceMake, n.Type(), p, nl, c)
+	return s.newValue3(ssa.OpSliceMake, n.Type(), p, l, c)
 }
 
 // condBranch evaluates the boolean expression cond and branches to yes
@@ -3564,7 +3602,11 @@
 // If deref is true, then we do left = *right instead (and right has already been nil-checked).
 // If deref is true and right == nil, just do left = 0.
 // skip indicates assignments (at the top level) that can be avoided.
+// mayOverlap indicates whether left&right might partially overlap in memory. Default is false.
 func (s *state) assign(left ir.Node, right *ssa.Value, deref bool, skip skipMask) {
+	s.assignWhichMayOverlap(left, right, deref, skip, false)
+}
+func (s *state) assignWhichMayOverlap(left ir.Node, right *ssa.Value, deref bool, skip skipMask, mayOverlap bool) {
 	if left.Op() == ir.ONAME && ir.IsBlank(left) {
 		return
 	}
@@ -3646,7 +3688,7 @@
 
 	// If this assignment clobbers an entire local variable, then emit
 	// OpVarDef so liveness analysis knows the variable is redefined.
-	if base, ok := clobberBase(left).(*ir.Name); ok && base.OnStack() && skip == 0 {
+	if base, ok := clobberBase(left).(*ir.Name); ok && base.OnStack() && skip == 0 && t.HasPointers() {
 		s.vars[memVar] = s.newValue1Apos(ssa.OpVarDef, types.TypeMem, base, s.mem(), !ir.IsAutoTmp(base))
 	}
 
@@ -3665,7 +3707,7 @@
 		if right == nil {
 			s.zero(t, addr)
 		} else {
-			s.move(t, addr, right)
+			s.moveWhichMayOverlap(t, addr, right, mayOverlap)
 		}
 		return
 	}
@@ -3759,38 +3801,38 @@
 func softfloatInit() {
 	// Some of these operations get transformed by sfcall.
 	softFloatOps = map[ssa.Op]sfRtCallDef{
-		ssa.OpAdd32F: sfRtCallDef{typecheck.LookupRuntimeFunc("fadd32"), types.TFLOAT32},
-		ssa.OpAdd64F: sfRtCallDef{typecheck.LookupRuntimeFunc("fadd64"), types.TFLOAT64},
-		ssa.OpSub32F: sfRtCallDef{typecheck.LookupRuntimeFunc("fadd32"), types.TFLOAT32},
-		ssa.OpSub64F: sfRtCallDef{typecheck.LookupRuntimeFunc("fadd64"), types.TFLOAT64},
-		ssa.OpMul32F: sfRtCallDef{typecheck.LookupRuntimeFunc("fmul32"), types.TFLOAT32},
-		ssa.OpMul64F: sfRtCallDef{typecheck.LookupRuntimeFunc("fmul64"), types.TFLOAT64},
-		ssa.OpDiv32F: sfRtCallDef{typecheck.LookupRuntimeFunc("fdiv32"), types.TFLOAT32},
-		ssa.OpDiv64F: sfRtCallDef{typecheck.LookupRuntimeFunc("fdiv64"), types.TFLOAT64},
+		ssa.OpAdd32F: {typecheck.LookupRuntimeFunc("fadd32"), types.TFLOAT32},
+		ssa.OpAdd64F: {typecheck.LookupRuntimeFunc("fadd64"), types.TFLOAT64},
+		ssa.OpSub32F: {typecheck.LookupRuntimeFunc("fadd32"), types.TFLOAT32},
+		ssa.OpSub64F: {typecheck.LookupRuntimeFunc("fadd64"), types.TFLOAT64},
+		ssa.OpMul32F: {typecheck.LookupRuntimeFunc("fmul32"), types.TFLOAT32},
+		ssa.OpMul64F: {typecheck.LookupRuntimeFunc("fmul64"), types.TFLOAT64},
+		ssa.OpDiv32F: {typecheck.LookupRuntimeFunc("fdiv32"), types.TFLOAT32},
+		ssa.OpDiv64F: {typecheck.LookupRuntimeFunc("fdiv64"), types.TFLOAT64},
 
-		ssa.OpEq64F:   sfRtCallDef{typecheck.LookupRuntimeFunc("feq64"), types.TBOOL},
-		ssa.OpEq32F:   sfRtCallDef{typecheck.LookupRuntimeFunc("feq32"), types.TBOOL},
-		ssa.OpNeq64F:  sfRtCallDef{typecheck.LookupRuntimeFunc("feq64"), types.TBOOL},
-		ssa.OpNeq32F:  sfRtCallDef{typecheck.LookupRuntimeFunc("feq32"), types.TBOOL},
-		ssa.OpLess64F: sfRtCallDef{typecheck.LookupRuntimeFunc("fgt64"), types.TBOOL},
-		ssa.OpLess32F: sfRtCallDef{typecheck.LookupRuntimeFunc("fgt32"), types.TBOOL},
-		ssa.OpLeq64F:  sfRtCallDef{typecheck.LookupRuntimeFunc("fge64"), types.TBOOL},
-		ssa.OpLeq32F:  sfRtCallDef{typecheck.LookupRuntimeFunc("fge32"), types.TBOOL},
+		ssa.OpEq64F:   {typecheck.LookupRuntimeFunc("feq64"), types.TBOOL},
+		ssa.OpEq32F:   {typecheck.LookupRuntimeFunc("feq32"), types.TBOOL},
+		ssa.OpNeq64F:  {typecheck.LookupRuntimeFunc("feq64"), types.TBOOL},
+		ssa.OpNeq32F:  {typecheck.LookupRuntimeFunc("feq32"), types.TBOOL},
+		ssa.OpLess64F: {typecheck.LookupRuntimeFunc("fgt64"), types.TBOOL},
+		ssa.OpLess32F: {typecheck.LookupRuntimeFunc("fgt32"), types.TBOOL},
+		ssa.OpLeq64F:  {typecheck.LookupRuntimeFunc("fge64"), types.TBOOL},
+		ssa.OpLeq32F:  {typecheck.LookupRuntimeFunc("fge32"), types.TBOOL},
 
-		ssa.OpCvt32to32F:  sfRtCallDef{typecheck.LookupRuntimeFunc("fint32to32"), types.TFLOAT32},
-		ssa.OpCvt32Fto32:  sfRtCallDef{typecheck.LookupRuntimeFunc("f32toint32"), types.TINT32},
-		ssa.OpCvt64to32F:  sfRtCallDef{typecheck.LookupRuntimeFunc("fint64to32"), types.TFLOAT32},
-		ssa.OpCvt32Fto64:  sfRtCallDef{typecheck.LookupRuntimeFunc("f32toint64"), types.TINT64},
-		ssa.OpCvt64Uto32F: sfRtCallDef{typecheck.LookupRuntimeFunc("fuint64to32"), types.TFLOAT32},
-		ssa.OpCvt32Fto64U: sfRtCallDef{typecheck.LookupRuntimeFunc("f32touint64"), types.TUINT64},
-		ssa.OpCvt32to64F:  sfRtCallDef{typecheck.LookupRuntimeFunc("fint32to64"), types.TFLOAT64},
-		ssa.OpCvt64Fto32:  sfRtCallDef{typecheck.LookupRuntimeFunc("f64toint32"), types.TINT32},
-		ssa.OpCvt64to64F:  sfRtCallDef{typecheck.LookupRuntimeFunc("fint64to64"), types.TFLOAT64},
-		ssa.OpCvt64Fto64:  sfRtCallDef{typecheck.LookupRuntimeFunc("f64toint64"), types.TINT64},
-		ssa.OpCvt64Uto64F: sfRtCallDef{typecheck.LookupRuntimeFunc("fuint64to64"), types.TFLOAT64},
-		ssa.OpCvt64Fto64U: sfRtCallDef{typecheck.LookupRuntimeFunc("f64touint64"), types.TUINT64},
-		ssa.OpCvt32Fto64F: sfRtCallDef{typecheck.LookupRuntimeFunc("f32to64"), types.TFLOAT64},
-		ssa.OpCvt64Fto32F: sfRtCallDef{typecheck.LookupRuntimeFunc("f64to32"), types.TFLOAT32},
+		ssa.OpCvt32to32F:  {typecheck.LookupRuntimeFunc("fint32to32"), types.TFLOAT32},
+		ssa.OpCvt32Fto32:  {typecheck.LookupRuntimeFunc("f32toint32"), types.TINT32},
+		ssa.OpCvt64to32F:  {typecheck.LookupRuntimeFunc("fint64to32"), types.TFLOAT32},
+		ssa.OpCvt32Fto64:  {typecheck.LookupRuntimeFunc("f32toint64"), types.TINT64},
+		ssa.OpCvt64Uto32F: {typecheck.LookupRuntimeFunc("fuint64to32"), types.TFLOAT32},
+		ssa.OpCvt32Fto64U: {typecheck.LookupRuntimeFunc("f32touint64"), types.TUINT64},
+		ssa.OpCvt32to64F:  {typecheck.LookupRuntimeFunc("fint32to64"), types.TFLOAT64},
+		ssa.OpCvt64Fto32:  {typecheck.LookupRuntimeFunc("f64toint32"), types.TINT32},
+		ssa.OpCvt64to64F:  {typecheck.LookupRuntimeFunc("fint64to64"), types.TFLOAT64},
+		ssa.OpCvt64Fto64:  {typecheck.LookupRuntimeFunc("f64toint64"), types.TINT64},
+		ssa.OpCvt64Uto64F: {typecheck.LookupRuntimeFunc("fuint64to64"), types.TFLOAT64},
+		ssa.OpCvt64Fto64U: {typecheck.LookupRuntimeFunc("f64touint64"), types.TUINT64},
+		ssa.OpCvt32Fto64F: {typecheck.LookupRuntimeFunc("f32to64"), types.TFLOAT64},
+		ssa.OpCvt64Fto32F: {typecheck.LookupRuntimeFunc("f64to32"), types.TFLOAT32},
 	}
 }
 
@@ -3924,7 +3966,7 @@
 			}
 			return s.newValue2(ssa.OpMul64uover, types.NewTuple(types.Types[types.TUINT], types.Types[types.TUINT]), args[0], args[1])
 		},
-		sys.AMD64, sys.I386, sys.Loong64, sys.MIPS64, sys.RISCV64)
+		sys.AMD64, sys.I386, sys.Loong64, sys.MIPS64, sys.RISCV64, sys.ARM64)
 	alias("runtime", "mulUintptr", "runtime/internal/math", "MulUintptr", all...)
 	add("runtime", "KeepAlive",
 		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
@@ -3959,16 +4001,6 @@
 		sys.ARM64, sys.PPC64)
 
 	/******** runtime/internal/sys ********/
-	addF("runtime/internal/sys", "Ctz32",
-		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
-			return s.newValue1(ssa.OpCtz32, types.Types[types.TINT], args[0])
-		},
-		sys.AMD64, sys.ARM64, sys.ARM, sys.S390X, sys.MIPS, sys.PPC64)
-	addF("runtime/internal/sys", "Ctz64",
-		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
-			return s.newValue1(ssa.OpCtz64, types.Types[types.TINT], args[0])
-		},
-		sys.AMD64, sys.ARM64, sys.ARM, sys.S390X, sys.MIPS, sys.PPC64)
 	addF("runtime/internal/sys", "Bswap32",
 		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
 			return s.newValue1(ssa.OpBswap32, types.Types[types.TUINT32], args[0])
@@ -4288,7 +4320,7 @@
 	alias("runtime/internal/atomic", "CasRel", "runtime/internal/atomic", "Cas", lwatomics...)
 
 	/******** math ********/
-	addF("math", "Sqrt",
+	addF("math", "sqrt",
 		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
 			return s.newValue1(ssa.OpSqrt, types.Types[types.TFLOAT64], args[0])
 		},
@@ -4603,12 +4635,12 @@
 		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
 			return s.newValue2(ssa.OpRotateLeft32, types.Types[types.TUINT32], args[0], args[1])
 		},
-		sys.AMD64, sys.ARM, sys.ARM64, sys.S390X, sys.PPC64, sys.Wasm)
+		sys.AMD64, sys.ARM, sys.ARM64, sys.S390X, sys.PPC64, sys.Wasm, sys.Loong64)
 	addF("math/bits", "RotateLeft64",
 		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
 			return s.newValue2(ssa.OpRotateLeft64, types.Types[types.TUINT64], args[0], args[1])
 		},
-		sys.AMD64, sys.ARM64, sys.S390X, sys.PPC64, sys.Wasm)
+		sys.AMD64, sys.ARM64, sys.S390X, sys.PPC64, sys.Wasm, sys.Loong64)
 	alias("math/bits", "RotateLeft", "math/bits", "RotateLeft64", p8...)
 
 	makeOnesCountAMD64 := func(op ssa.Op) func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
@@ -4686,14 +4718,14 @@
 		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
 			return s.newValue3(ssa.OpAdd64carry, types.NewTuple(types.Types[types.TUINT64], types.Types[types.TUINT64]), args[0], args[1], args[2])
 		},
-		sys.AMD64, sys.ARM64, sys.PPC64, sys.S390X)
-	alias("math/bits", "Add", "math/bits", "Add64", sys.ArchAMD64, sys.ArchARM64, sys.ArchPPC64, sys.ArchPPC64LE, sys.ArchS390X)
+		sys.AMD64, sys.ARM64, sys.PPC64, sys.S390X, sys.RISCV64, sys.Loong64)
+	alias("math/bits", "Add", "math/bits", "Add64", p8...)
 	addF("math/bits", "Sub64",
 		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
 			return s.newValue3(ssa.OpSub64borrow, types.NewTuple(types.Types[types.TUINT64], types.Types[types.TUINT64]), args[0], args[1], args[2])
 		},
-		sys.AMD64, sys.ARM64, sys.PPC64, sys.S390X)
-	alias("math/bits", "Sub", "math/bits", "Sub64", sys.ArchAMD64, sys.ArchARM64, sys.ArchS390X)
+		sys.AMD64, sys.ARM64, sys.PPC64, sys.S390X, sys.RISCV64, sys.Loong64)
+	alias("math/bits", "Sub", "math/bits", "Sub64", p8...)
 	addF("math/bits", "Div64",
 		func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
 			// check for divide-by-zero/overflow and panic with appropriate message
@@ -4706,8 +4738,8 @@
 		sys.AMD64)
 	alias("math/bits", "Div", "math/bits", "Div64", sys.ArchAMD64)
 
-	alias("runtime/internal/sys", "Ctz8", "math/bits", "TrailingZeros8", all...)
 	alias("runtime/internal/sys", "TrailingZeros8", "math/bits", "TrailingZeros8", all...)
+	alias("runtime/internal/sys", "TrailingZeros32", "math/bits", "TrailingZeros32", all...)
 	alias("runtime/internal/sys", "TrailingZeros64", "math/bits", "TrailingZeros64", all...)
 	alias("runtime/internal/sys", "Len8", "math/bits", "Len8", all...)
 	alias("runtime/internal/sys", "Len64", "math/bits", "Len64", all...)
@@ -4882,14 +4914,18 @@
 		// Force the tmp storing this defer function to be declared in the entry
 		// block, so that it will be live for the defer exit code (which will
 		// actually access it only if the associated defer call has been activated).
-		s.defvars[s.f.Entry.ID][memVar] = s.f.Entry.NewValue1A(src.NoXPos, ssa.OpVarDef, types.TypeMem, temp, s.defvars[s.f.Entry.ID][memVar])
+		if t.HasPointers() {
+			s.defvars[s.f.Entry.ID][memVar] = s.f.Entry.NewValue1A(src.NoXPos, ssa.OpVarDef, types.TypeMem, temp, s.defvars[s.f.Entry.ID][memVar])
+		}
 		s.defvars[s.f.Entry.ID][memVar] = s.f.Entry.NewValue1A(src.NoXPos, ssa.OpVarLive, types.TypeMem, temp, s.defvars[s.f.Entry.ID][memVar])
 		addrTemp = s.f.Entry.NewValue2A(src.NoXPos, ssa.OpLocalAddr, types.NewPtr(temp.Type()), temp, s.sp, s.defvars[s.f.Entry.ID][memVar])
 	} else {
 		// Special case if we're still in the entry block. We can't use
 		// the above code, since s.defvars[s.f.Entry.ID] isn't defined
 		// until we end the entry block with s.endBlock().
-		s.vars[memVar] = s.newValue1Apos(ssa.OpVarDef, types.TypeMem, temp, s.mem(), false)
+		if t.HasPointers() {
+			s.vars[memVar] = s.newValue1Apos(ssa.OpVarDef, types.TypeMem, temp, s.mem(), false)
+		}
 		s.vars[memVar] = s.newValue1Apos(ssa.OpVarLive, types.TypeMem, temp, s.mem(), false)
 		addrTemp = s.newValue2Apos(ssa.OpLocalAddr, types.NewPtr(temp.Type()), temp, s.sp, s.mem(), false)
 	}
@@ -5071,7 +5107,9 @@
 		t := deferstruct()
 		d := typecheck.TempAt(n.Pos(), s.curfn, t)
 
-		s.vars[memVar] = s.newValue1A(ssa.OpVarDef, types.TypeMem, d, s.mem())
+		if t.HasPointers() {
+			s.vars[memVar] = s.newValue1A(ssa.OpVarDef, types.TypeMem, d, s.mem())
+		}
 		addr := s.addr(d)
 
 		// Must match deferstruct() below and src/runtime/runtime2.go:_defer.
@@ -5176,9 +5214,17 @@
 	}
 	s.prevCall = call
 	s.vars[memVar] = s.newValue1I(ssa.OpSelectN, types.TypeMem, int64(len(ACResults)), call)
-	// Insert OVARLIVE nodes
-	for _, name := range n.KeepAlive {
-		s.stmt(ir.NewUnaryExpr(n.Pos(), ir.OVARLIVE, name))
+	// Insert VarLive opcodes.
+	for _, v := range n.KeepAlive {
+		if !v.Addrtaken() {
+			s.Fatalf("KeepAlive variable %v must have Addrtaken set", v)
+		}
+		switch v.Class {
+		case ir.PAUTO, ir.PPARAM, ir.PPARAMOUT:
+		default:
+			s.Fatalf("KeepAlive variable %v must be Auto or Arg", v)
+		}
+		s.vars[memVar] = s.newValue1A(ssa.OpVarLive, types.TypeMem, v, s.mem())
 	}
 
 	// Finish block for defers
@@ -5610,13 +5656,13 @@
 
 	for _, arg := range args {
 		t := arg.Type
-		off = types.Rnd(off, t.Alignment())
+		off = types.RoundUp(off, t.Alignment())
 		size := t.Size()
 		callArgs = append(callArgs, arg)
 		callArgTypes = append(callArgTypes, t)
 		off += size
 	}
-	off = types.Rnd(off, int64(types.RegSize))
+	off = types.RoundUp(off, int64(types.RegSize))
 
 	// Issue call
 	var call *ssa.Value
@@ -5641,11 +5687,11 @@
 	// Load results
 	res := make([]*ssa.Value, len(results))
 	for i, t := range results {
-		off = types.Rnd(off, t.Alignment())
+		off = types.RoundUp(off, t.Alignment())
 		res[i] = s.resultOfCall(call, int64(i), t)
 		off += t.Size()
 	}
-	off = types.Rnd(off, int64(types.PtrSize))
+	off = types.RoundUp(off, int64(types.PtrSize))
 
 	// Remember how much callee stack space we needed.
 	call.AuxInt = off
@@ -6226,12 +6272,15 @@
 	if n.ITab != nil {
 		targetItab = s.expr(n.ITab)
 	}
-	return s.dottype1(n.Pos(), n.X.Type(), n.Type(), iface, target, targetItab, commaok)
+	return s.dottype1(n.Pos(), n.X.Type(), n.Type(), iface, nil, target, targetItab, commaok)
 }
 
 func (s *state) dynamicDottype(n *ir.DynamicTypeAssertExpr, commaok bool) (res, resok *ssa.Value) {
 	iface := s.expr(n.X)
-	var target, targetItab *ssa.Value
+	var source, target, targetItab *ssa.Value
+	if n.SrcRType != nil {
+		source = s.expr(n.SrcRType)
+	}
 	if !n.X.Type().IsEmptyInterface() && !n.Type().IsInterface() {
 		byteptr := s.f.Config.Types.BytePtr
 		targetItab = s.expr(n.ITab)
@@ -6241,15 +6290,16 @@
 	} else {
 		target = s.expr(n.RType)
 	}
-	return s.dottype1(n.Pos(), n.X.Type(), n.Type(), iface, target, targetItab, commaok)
+	return s.dottype1(n.Pos(), n.X.Type(), n.Type(), iface, source, target, targetItab, commaok)
 }
 
 // dottype1 implements a x.(T) operation. iface is the argument (x), dst is the type we're asserting to (T)
 // and src is the type we're asserting from.
+// source is the *runtime._type of src
 // target is the *runtime._type of dst.
 // If src is a nonempty interface and dst is not an interface, targetItab is an itab representing (dst, src). Otherwise it is nil.
 // commaok is true if the caller wants a boolean success value. Otherwise, the generated code panics if the conversion fails.
-func (s *state) dottype1(pos src.XPos, src, dst *types.Type, iface, target, targetItab *ssa.Value, commaok bool) (res, resok *ssa.Value) {
+func (s *state) dottype1(pos src.XPos, src, dst *types.Type, iface, source, target, targetItab *ssa.Value, commaok bool) (res, resok *ssa.Value) {
 	byteptr := s.f.Config.Types.BytePtr
 	if dst.IsInterface() {
 		if dst.IsEmptyInterface() {
@@ -6385,7 +6435,10 @@
 	if !commaok {
 		// on failure, panic by calling panicdottype
 		s.startBlock(bFail)
-		taddr := s.reflectType(src)
+		taddr := source
+		if taddr == nil {
+			taddr = s.reflectType(src)
+		}
 		if src.IsEmptyInterface() {
 			s.rtcall(ir.Syms.PanicdottypeE, false, nil, itab, target, taddr)
 		} else {
@@ -6443,7 +6496,6 @@
 		delete(s.vars, valVar)
 	} else {
 		res = s.load(dst, addr)
-		s.vars[memVar] = s.newValue1A(ssa.OpVarKill, types.TypeMem, tmp.(*ir.Name), s.mem())
 	}
 	resok = s.variable(okVar, types.Types[types.TBOOL])
 	delete(s.vars, okVar)
@@ -6453,7 +6505,9 @@
 // temp allocates a temp of type t at position pos
 func (s *state) temp(pos src.XPos, t *types.Type) (*ir.Name, *ssa.Value) {
 	tmp := typecheck.TempAt(pos, s.curfn, t)
-	s.vars[memVar] = s.newValue1A(ssa.OpVarDef, types.TypeMem, tmp, s.mem())
+	if t.HasPointers() {
+		s.vars[memVar] = s.newValue1A(ssa.OpVarDef, types.TypeMem, tmp, s.mem())
+	}
 	addr := s.addr(tmp)
 	return tmp, addr
 }
@@ -6471,7 +6525,7 @@
 
 	if s.curBlock == s.f.Entry {
 		// No variable should be live at entry.
-		s.Fatalf("Value live at entry. It shouldn't be. func %s, node %v, value %v", s.f.Name, n, v)
+		s.f.Fatalf("value %v (%v) incorrectly live at entry", n, v)
 	}
 	// Make a FwdRef, which records a value that's live on block input.
 	// We'll find the matching definition as part of insertPhis.
@@ -6936,7 +6990,7 @@
 			case ssa.OpGetG:
 				// nothing to do when there's a g register,
 				// and checkLower complains if there's not
-			case ssa.OpVarDef, ssa.OpVarLive, ssa.OpKeepAlive, ssa.OpVarKill:
+			case ssa.OpVarDef, ssa.OpVarLive, ssa.OpKeepAlive:
 				// nothing to do; already used by liveness
 			case ssa.OpPhi:
 				CheckLoweredPhi(v)
@@ -7175,7 +7229,7 @@
 		}
 	}
 	if f.HTMLWriter != nil { // spew to ssa.html
-		var buf bytes.Buffer
+		var buf strings.Builder
 		buf.WriteString("<code>")
 		buf.WriteString("<dl class=\"ssa-gen\">")
 		filename := ""
@@ -7197,7 +7251,7 @@
 			}
 			buf.WriteString("</dt>")
 			buf.WriteString("<dd class=\"ssa-prog\">")
-			buf.WriteString(fmt.Sprintf("%.5d <span class=\"l%v line-number\">(%s)</span> %s", p.Pc, p.InnermostLineNumber(), p.InnermostLineNumberHTML(), html.EscapeString(p.InstructionString())))
+			fmt.Fprintf(&buf, "%.5d <span class=\"l%v line-number\">(%s)</span> %s", p.Pc, p.InnermostLineNumber(), p.InnermostLineNumberHTML(), html.EscapeString(p.InstructionString()))
 			buf.WriteString("</dd>")
 		}
 		buf.WriteString("</dl>")
@@ -7262,14 +7316,15 @@
 func defframe(s *State, e *ssafn, f *ssa.Func) {
 	pp := s.pp
 
-	frame := types.Rnd(s.maxarg+e.stksize, int64(types.RegSize))
+	s.maxarg = types.RoundUp(s.maxarg, e.stkalign)
+	frame := s.maxarg + e.stksize
 	if Arch.PadFrame != nil {
 		frame = Arch.PadFrame(frame)
 	}
 
 	// Fill in argument and frame size.
 	pp.Text.To.Type = obj.TYPE_TEXTSIZE
-	pp.Text.To.Val = int32(types.Rnd(f.OwnAux.ArgWidth(), int64(types.RegSize)))
+	pp.Text.To.Val = int32(types.RoundUp(f.OwnAux.ArgWidth(), int64(types.RegSize)))
 	pp.Text.To.Offset = frame
 
 	p := pp.Text
@@ -7700,7 +7755,14 @@
 	strings    map[string]*obj.LSym // map from constant string to data symbols
 	stksize    int64                // stack size for current frame
 	stkptrsize int64                // prefix of stack containing pointers
-	log        bool                 // print ssa debug to the stdout
+
+	// alignment for current frame.
+	// NOTE: when stkalign > PtrSize, currently this only ensures the offsets of
+	// objects in the stack frame are aligned. The stack pointer is still aligned
+	// only PtrSize.
+	stkalign int64
+
+	log bool // print ssa debug to the stdout
 }
 
 // StringData returns a symbol which
@@ -7751,7 +7813,7 @@
 	return base.FmtPos(pos)
 }
 
-// Log logs a message from the compiler.
+// Logf logs a message from the compiler.
 func (e *ssafn) Logf(msg string, args ...interface{}) {
 	if e.log {
 		fmt.Printf(msg, args...)
@@ -7762,7 +7824,7 @@
 	return e.log
 }
 
-// Fatal reports a compiler error and exits.
+// Fatalf reports a compiler error and exits.
 func (e *ssafn) Fatalf(pos src.XPos, msg string, args ...interface{}) {
 	base.Pos = pos
 	nargs := append([]interface{}{ir.FuncName(e.curfn)}, args...)
@@ -7890,7 +7952,7 @@
 	return s
 }
 
-// SlotAddr uses LocalSlot information to initialize an obj.Addr
+// SpillSlotAddr uses LocalSlot information to initialize an obj.Addr
 // The resulting addr is used in a non-standard context -- in the prologue
 // of a function, before the frame has been constructed, so the standard
 // addressing for the parameters will be wrong.
diff --git a/src/cmd/compile/internal/staticdata/data.go b/src/cmd/compile/internal/staticdata/data.go
index 621da9c..662580f 100644
--- a/src/cmd/compile/internal/staticdata/data.go
+++ b/src/cmd/compile/internal/staticdata/data.go
@@ -9,7 +9,6 @@
 	"fmt"
 	"go/constant"
 	"io"
-	"io/ioutil"
 	"os"
 	"sort"
 	"strconv"
@@ -61,7 +60,7 @@
 }
 
 const (
-	stringSymPrefix  = "go.string."
+	stringSymPrefix  = "go:string."
 	stringSymPattern = ".gostring.%d.%s"
 )
 
@@ -124,7 +123,7 @@
 	}
 	size := info.Size()
 	if size <= 1*1024 {
-		data, err := ioutil.ReadAll(f)
+		data, err := io.ReadAll(f)
 		if err != nil {
 			return nil, 0, err
 		}
diff --git a/src/cmd/compile/internal/staticinit/sched.go b/src/cmd/compile/internal/staticinit/sched.go
index e9b97e6..2bfb5d7 100644
--- a/src/cmd/compile/internal/staticinit/sched.go
+++ b/src/cmd/compile/internal/staticinit/sched.go
@@ -7,6 +7,7 @@
 import (
 	"fmt"
 	"go/constant"
+	"go/token"
 
 	"cmd/compile/internal/base"
 	"cmd/compile/internal/ir"
@@ -48,7 +49,7 @@
 func (s *Schedule) StaticInit(n ir.Node) {
 	if !s.tryStaticInit(n) {
 		if base.Flag.Percent != 0 {
-			ir.Dump("nonstatic", n)
+			ir.Dump("StaticInit failed", n)
 		}
 		s.append(n)
 	}
@@ -332,6 +333,11 @@
 			return val.Op() == ir.ONIL
 		}
 
+		if base.Debug.Unified != 0 && val.Type().HasShape() {
+			// See comment in cmd/compile/internal/walk/convert.go:walkConvInterface
+			return false
+		}
+
 		reflectdata.MarkTypeUsedInInterface(val.Type(), l.Linksym())
 
 		var itab *ir.AddrExpr
@@ -364,9 +370,15 @@
 		}
 
 		return true
+
+	case ir.OINLCALL:
+		r := r.(*ir.InlinedCallExpr)
+		return s.staticAssignInlinedCall(l, loff, r, typ)
 	}
 
-	//dump("not static", r);
+	if base.Flag.Percent != 0 {
+		ir.Dump("not static", r)
+	}
 	return false
 }
 
@@ -443,6 +455,185 @@
 	p.E = append(p.E, Entry{Xoffset: xoffset, Expr: n})
 }
 
+func (s *Schedule) staticAssignInlinedCall(l *ir.Name, loff int64, call *ir.InlinedCallExpr, typ *types.Type) bool {
+	if base.Debug.InlStaticInit == 0 {
+		return false
+	}
+
+	// Handle the special case of an inlined call of
+	// a function body with a single return statement,
+	// which turns into a single assignment plus a goto.
+	//
+	// For example code like this:
+	//
+	//	type T struct{ x int }
+	//	func F(x int) *T { return &T{x} }
+	//	var Global = F(400)
+	//
+	// turns into IR like this:
+	//
+	// 	INLCALL-init
+	// 	.   AS2-init
+	// 	.   .   DCL # x.go:18:13
+	// 	.   .   .   NAME-p.x Class:PAUTO Offset:0 InlFormal OnStack Used int tc(1) # x.go:14:9,x.go:18:13
+	// 	.   AS2 Def tc(1) # x.go:18:13
+	// 	.   AS2-Lhs
+	// 	.   .   NAME-p.x Class:PAUTO Offset:0 InlFormal OnStack Used int tc(1) # x.go:14:9,x.go:18:13
+	// 	.   AS2-Rhs
+	// 	.   .   LITERAL-400 int tc(1) # x.go:18:14
+	// 	.   INLMARK Index:1 # +x.go:18:13
+	// 	INLCALL PTR-*T tc(1) # x.go:18:13
+	// 	INLCALL-Body
+	// 	.   BLOCK tc(1) # x.go:18:13
+	// 	.   BLOCK-List
+	// 	.   .   DCL tc(1) # x.go:18:13
+	// 	.   .   .   NAME-p.~R0 Class:PAUTO Offset:0 OnStack Used PTR-*T tc(1) # x.go:18:13
+	// 	.   .   AS2 tc(1) # x.go:18:13
+	// 	.   .   AS2-Lhs
+	// 	.   .   .   NAME-p.~R0 Class:PAUTO Offset:0 OnStack Used PTR-*T tc(1) # x.go:18:13
+	// 	.   .   AS2-Rhs
+	// 	.   .   .   INLINED RETURN ARGUMENT HERE
+	// 	.   .   GOTO p..i1 tc(1) # x.go:18:13
+	// 	.   LABEL p..i1 # x.go:18:13
+	// 	INLCALL-ReturnVars
+	// 	.   NAME-p.~R0 Class:PAUTO Offset:0 OnStack Used PTR-*T tc(1) # x.go:18:13
+	//
+	// In non-unified IR, the tree is slightly different:
+	//  - if there are no arguments to the inlined function,
+	//    the INLCALL-init omits the AS2.
+	//  - the DCL inside BLOCK is on the AS2's init list,
+	//    not its own statement in the top level of the BLOCK.
+	//
+	// If the init values are side-effect-free and each either only
+	// appears once in the function body or is safely repeatable,
+	// then we inline the value expressions into the return argument
+	// and then call StaticAssign to handle that copy.
+	//
+	// This handles simple cases like
+	//
+	//	var myError = errors.New("mine")
+	//
+	// where errors.New is
+	//
+	//	func New(text string) error {
+	//		return &errorString{text}
+	//	}
+	//
+	// We could make things more sophisticated but this kind of initializer
+	// is the most important case for us to get right.
+
+	init := call.Init()
+	var as2init *ir.AssignListStmt
+	if len(init) == 2 && init[0].Op() == ir.OAS2 && init[1].Op() == ir.OINLMARK {
+		as2init = init[0].(*ir.AssignListStmt)
+	} else if len(init) == 1 && init[0].Op() == ir.OINLMARK {
+		as2init = new(ir.AssignListStmt)
+	} else {
+		return false
+	}
+	if len(call.Body) != 2 || call.Body[0].Op() != ir.OBLOCK || call.Body[1].Op() != ir.OLABEL {
+		return false
+	}
+	label := call.Body[1].(*ir.LabelStmt).Label
+	block := call.Body[0].(*ir.BlockStmt)
+	list := block.List
+	var dcl *ir.Decl
+	if len(list) == 3 && list[0].Op() == ir.ODCL {
+		dcl = list[0].(*ir.Decl)
+		list = list[1:]
+	}
+	if len(list) != 2 ||
+		list[0].Op() != ir.OAS2 ||
+		list[1].Op() != ir.OGOTO ||
+		list[1].(*ir.BranchStmt).Label != label {
+		return false
+	}
+	as2body := list[0].(*ir.AssignListStmt)
+	if dcl == nil {
+		ainit := as2body.Init()
+		if len(ainit) != 1 || ainit[0].Op() != ir.ODCL {
+			return false
+		}
+		dcl = ainit[0].(*ir.Decl)
+	}
+	if len(as2body.Lhs) != 1 || as2body.Lhs[0] != dcl.X {
+		return false
+	}
+
+	// Can't remove the parameter variables if an address is taken.
+	for _, v := range as2init.Lhs {
+		if v.(*ir.Name).Addrtaken() {
+			return false
+		}
+	}
+	// Can't move the computation of the args if they have side effects.
+	for _, r := range as2init.Rhs {
+		if AnySideEffects(r) {
+			return false
+		}
+	}
+
+	// Can only substitute arg for param if param is used
+	// at most once or is repeatable.
+	count := make(map[*ir.Name]int)
+	for _, x := range as2init.Lhs {
+		count[x.(*ir.Name)] = 0
+	}
+
+	hasNonTrivialClosure := false
+	ir.Visit(as2body.Rhs[0], func(n ir.Node) {
+		if name, ok := n.(*ir.Name); ok {
+			if c, ok := count[name]; ok {
+				count[name] = c + 1
+			}
+		}
+		if clo, ok := n.(*ir.ClosureExpr); ok {
+			hasNonTrivialClosure = hasNonTrivialClosure || !ir.IsTrivialClosure(clo)
+		}
+	})
+
+	// If there's a non-trivial closure, it has captured the param,
+	// so we can't substitute arg for param.
+	if hasNonTrivialClosure {
+		return false
+	}
+
+	for name, c := range count {
+		if c > 1 {
+			// Check whether corresponding initializer can be repeated.
+			// Something like 1 can be; make(chan int) or &T{} cannot,
+			// because they need to evaluate to the same result in each use.
+			for i, n := range as2init.Lhs {
+				if n == name && !canRepeat(as2init.Rhs[i]) {
+					return false
+				}
+			}
+		}
+	}
+
+	// Possible static init.
+	// Build tree with args substituted for params and try it.
+	args := make(map[*ir.Name]ir.Node)
+	for i, v := range as2init.Lhs {
+		if ir.IsBlank(v) {
+			continue
+		}
+		args[v.(*ir.Name)] = as2init.Rhs[i]
+	}
+	r, ok := subst(as2body.Rhs[0], args)
+	if !ok {
+		return false
+	}
+	ok = s.StaticAssign(l, loff, r, typ)
+
+	if ok && base.Flag.Percent != 0 {
+		ir.Dump("static inlined-LEFT", l)
+		ir.Dump("static inlined-ORIG", call)
+		ir.Dump("static inlined-RIGHT", r)
+	}
+	return ok
+}
+
 // from here down is the walk analysis
 // of composite literals.
 // most of the work is to generate
@@ -510,91 +701,118 @@
 	return nil, 0, false
 }
 
+func isSideEffect(n ir.Node) bool {
+	switch n.Op() {
+	// Assume side effects unless we know otherwise.
+	default:
+		return true
+
+	// No side effects here (arguments are checked separately).
+	case ir.ONAME,
+		ir.ONONAME,
+		ir.OTYPE,
+		ir.OLITERAL,
+		ir.ONIL,
+		ir.OADD,
+		ir.OSUB,
+		ir.OOR,
+		ir.OXOR,
+		ir.OADDSTR,
+		ir.OADDR,
+		ir.OANDAND,
+		ir.OBYTES2STR,
+		ir.ORUNES2STR,
+		ir.OSTR2BYTES,
+		ir.OSTR2RUNES,
+		ir.OCAP,
+		ir.OCOMPLIT,
+		ir.OMAPLIT,
+		ir.OSTRUCTLIT,
+		ir.OARRAYLIT,
+		ir.OSLICELIT,
+		ir.OPTRLIT,
+		ir.OCONV,
+		ir.OCONVIFACE,
+		ir.OCONVNOP,
+		ir.ODOT,
+		ir.OEQ,
+		ir.ONE,
+		ir.OLT,
+		ir.OLE,
+		ir.OGT,
+		ir.OGE,
+		ir.OKEY,
+		ir.OSTRUCTKEY,
+		ir.OLEN,
+		ir.OMUL,
+		ir.OLSH,
+		ir.ORSH,
+		ir.OAND,
+		ir.OANDNOT,
+		ir.ONEW,
+		ir.ONOT,
+		ir.OBITNOT,
+		ir.OPLUS,
+		ir.ONEG,
+		ir.OOROR,
+		ir.OPAREN,
+		ir.ORUNESTR,
+		ir.OREAL,
+		ir.OIMAG,
+		ir.OCOMPLEX:
+		return false
+
+	// Only possible side effect is division by zero.
+	case ir.ODIV, ir.OMOD:
+		n := n.(*ir.BinaryExpr)
+		if n.Y.Op() != ir.OLITERAL || constant.Sign(n.Y.Val()) == 0 {
+			return true
+		}
+
+	// Only possible side effect is panic on invalid size,
+	// but many makechan and makemap use size zero, which is definitely OK.
+	case ir.OMAKECHAN, ir.OMAKEMAP:
+		n := n.(*ir.MakeExpr)
+		if !ir.IsConst(n.Len, constant.Int) || constant.Sign(n.Len.Val()) != 0 {
+			return true
+		}
+
+	// Only possible side effect is panic on invalid size.
+	// TODO(rsc): Merge with previous case (probably breaks toolstash -cmp).
+	case ir.OMAKESLICE, ir.OMAKESLICECOPY:
+		return true
+	}
+	return false
+}
+
 // AnySideEffects reports whether n contains any operations that could have observable side effects.
 func AnySideEffects(n ir.Node) bool {
-	return ir.Any(n, func(n ir.Node) bool {
-		switch n.Op() {
-		// Assume side effects unless we know otherwise.
-		default:
+	return ir.Any(n, isSideEffect)
+}
+
+// canRepeat reports whether executing n multiple times has the same effect as
+// assigning n to a single variable and using that variable multiple times.
+func canRepeat(n ir.Node) bool {
+	bad := func(n ir.Node) bool {
+		if isSideEffect(n) {
 			return true
-
-		// No side effects here (arguments are checked separately).
-		case ir.ONAME,
-			ir.ONONAME,
-			ir.OTYPE,
-			ir.OLITERAL,
-			ir.ONIL,
-			ir.OADD,
-			ir.OSUB,
-			ir.OOR,
-			ir.OXOR,
-			ir.OADDSTR,
-			ir.OADDR,
-			ir.OANDAND,
-			ir.OBYTES2STR,
-			ir.ORUNES2STR,
-			ir.OSTR2BYTES,
-			ir.OSTR2RUNES,
-			ir.OCAP,
-			ir.OCOMPLIT,
+		}
+		switch n.Op() {
+		case ir.OMAKECHAN,
+			ir.OMAKEMAP,
+			ir.OMAKESLICE,
+			ir.OMAKESLICECOPY,
 			ir.OMAPLIT,
-			ir.OSTRUCTLIT,
-			ir.OARRAYLIT,
-			ir.OSLICELIT,
-			ir.OPTRLIT,
-			ir.OCONV,
-			ir.OCONVIFACE,
-			ir.OCONVNOP,
-			ir.ODOT,
-			ir.OEQ,
-			ir.ONE,
-			ir.OLT,
-			ir.OLE,
-			ir.OGT,
-			ir.OGE,
-			ir.OKEY,
-			ir.OSTRUCTKEY,
-			ir.OLEN,
-			ir.OMUL,
-			ir.OLSH,
-			ir.ORSH,
-			ir.OAND,
-			ir.OANDNOT,
 			ir.ONEW,
-			ir.ONOT,
-			ir.OBITNOT,
-			ir.OPLUS,
-			ir.ONEG,
-			ir.OOROR,
-			ir.OPAREN,
-			ir.ORUNESTR,
-			ir.OREAL,
-			ir.OIMAG,
-			ir.OCOMPLEX:
-			return false
-
-		// Only possible side effect is division by zero.
-		case ir.ODIV, ir.OMOD:
-			n := n.(*ir.BinaryExpr)
-			if n.Y.Op() != ir.OLITERAL || constant.Sign(n.Y.Val()) == 0 {
-				return true
-			}
-
-		// Only possible side effect is panic on invalid size,
-		// but many makechan and makemap use size zero, which is definitely OK.
-		case ir.OMAKECHAN, ir.OMAKEMAP:
-			n := n.(*ir.MakeExpr)
-			if !ir.IsConst(n.Len, constant.Int) || constant.Sign(n.Len.Val()) != 0 {
-				return true
-			}
-
-		// Only possible side effect is panic on invalid size.
-		// TODO(rsc): Merge with previous case (probably breaks toolstash -cmp).
-		case ir.OMAKESLICE, ir.OMAKESLICECOPY:
+			ir.OPTRLIT,
+			ir.OSLICELIT,
+			ir.OSTR2BYTES,
+			ir.OSTR2RUNES:
 			return true
 		}
 		return false
-	})
+	}
+	return !ir.Any(n, bad)
 }
 
 func getlit(lit ir.Node) int {
@@ -607,3 +825,68 @@
 func isvaluelit(n ir.Node) bool {
 	return n.Op() == ir.OARRAYLIT || n.Op() == ir.OSTRUCTLIT
 }
+
+func subst(n ir.Node, m map[*ir.Name]ir.Node) (ir.Node, bool) {
+	valid := true
+	var edit func(ir.Node) ir.Node
+	edit = func(x ir.Node) ir.Node {
+		switch x.Op() {
+		case ir.ONAME:
+			x := x.(*ir.Name)
+			if v, ok := m[x]; ok {
+				return ir.DeepCopy(v.Pos(), v)
+			}
+			return x
+		case ir.ONONAME, ir.OLITERAL, ir.ONIL, ir.OTYPE:
+			return x
+		}
+		x = ir.Copy(x)
+		ir.EditChildrenWithHidden(x, edit)
+		if x, ok := x.(*ir.ConvExpr); ok && x.X.Op() == ir.OLITERAL {
+			// A conversion of variable or expression involving variables
+			// may become a conversion of constant after inlining the parameters
+			// and doing constant evaluation. Truncations that were valid
+			// on variables are not valid on constants, so we might have
+			// generated invalid code that will trip up the rest of the compiler.
+			// Fix those by truncating the constants.
+			if x, ok := truncate(x.X.(*ir.ConstExpr), x.Type()); ok {
+				return x
+			}
+			valid = false
+			return x
+		}
+		return typecheck.EvalConst(x)
+	}
+	n = edit(n)
+	return n, valid
+}
+
+// truncate returns the result of force converting c to type t,
+// truncating its value as needed, like a conversion of a variable.
+// If the conversion is too difficult, truncate returns nil, false.
+func truncate(c *ir.ConstExpr, t *types.Type) (*ir.ConstExpr, bool) {
+	ct := c.Type()
+	cv := c.Val()
+	if ct.Kind() != t.Kind() {
+		switch {
+		default:
+			// Note: float -> float/integer and complex -> complex are valid but subtle.
+			// For example a float32(float64 1e300) evaluates to +Inf at runtime
+			// and the compiler doesn't have any concept of +Inf, so that would
+			// have to be left for runtime code evaluation.
+			// For now
+			return nil, false
+
+		case ct.IsInteger() && t.IsInteger():
+			// truncate or sign extend
+			bits := t.Size() * 8
+			cv = constant.BinaryOp(cv, token.AND, constant.MakeUint64(1<<bits-1))
+			if t.IsSigned() && constant.Compare(cv, token.GEQ, constant.MakeUint64(1<<(bits-1))) {
+				cv = constant.BinaryOp(cv, token.OR, constant.MakeInt64(-1<<(bits-1)))
+			}
+		}
+	}
+	c = ir.NewConstExpr(cv, c).(*ir.ConstExpr)
+	c.SetType(t)
+	return c, true
+}
diff --git a/src/cmd/compile/internal/syntax/error_test.go b/src/cmd/compile/internal/syntax/error_test.go
index 2f70b52..55ea634 100644
--- a/src/cmd/compile/internal/syntax/error_test.go
+++ b/src/cmd/compile/internal/syntax/error_test.go
@@ -32,7 +32,6 @@
 	"flag"
 	"fmt"
 	"internal/testenv"
-	"io/ioutil"
 	"os"
 	"path/filepath"
 	"regexp"
@@ -178,7 +177,7 @@
 func TestSyntaxErrors(t *testing.T) {
 	testenv.MustHaveGoBuild(t) // we need access to source (testdata)
 
-	list, err := ioutil.ReadDir(testdata)
+	list, err := os.ReadDir(testdata)
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/src/cmd/compile/internal/syntax/nodes.go b/src/cmd/compile/internal/syntax/nodes.go
index b0a0918..e943a9a 100644
--- a/src/cmd/compile/internal/syntax/nodes.go
+++ b/src/cmd/compile/internal/syntax/nodes.go
@@ -132,6 +132,7 @@
 type (
 	Expr interface {
 		Node
+		typeInfo
 		aExpr()
 	}
 
@@ -308,7 +309,10 @@
 	}
 )
 
-type expr struct{ node }
+type expr struct {
+	node
+	typeAndValue // After typechecking, contains the results of typechecking this expression.
+}
 
 func (*expr) aExpr() {}
 
@@ -385,7 +389,7 @@
 
 	CallStmt struct {
 		Tok  token // Go or Defer
-		Call *CallExpr
+		Call Expr
 		stmt
 	}
 
diff --git a/src/cmd/compile/internal/syntax/parser.go b/src/cmd/compile/internal/syntax/parser.go
index 22b1816..ee9761e 100644
--- a/src/cmd/compile/internal/syntax/parser.go
+++ b/src/cmd/compile/internal/syntax/parser.go
@@ -190,7 +190,7 @@
 
 func (p *parser) want(tok token) {
 	if !p.got(tok) {
-		p.syntaxError("expecting " + tokstring(tok))
+		p.syntaxError("expected " + tokstring(tok))
 		p.advance()
 	}
 }
@@ -200,7 +200,7 @@
 func (p *parser) gotAssign() bool {
 	switch p.tok {
 	case _Define:
-		p.syntaxError("expecting =")
+		p.syntaxError("expected =")
 		fallthrough
 	case _Assign:
 		p.next()
@@ -217,7 +217,7 @@
 	return MakePos(p.base, line, col)
 }
 
-// error reports an error at the given position.
+// errorAt reports an error at the given position.
 func (p *parser) errorAt(pos Pos, msg string) {
 	err := Error{pos, msg}
 	if p.first == nil {
@@ -246,7 +246,7 @@
 		// nothing to do
 	case strings.HasPrefix(msg, "in "), strings.HasPrefix(msg, "at "), strings.HasPrefix(msg, "after "):
 		msg = " " + msg
-	case strings.HasPrefix(msg, "expecting "):
+	case strings.HasPrefix(msg, "expected "):
 		msg = ", " + msg
 	default:
 		// plain error - we don't care about current token
@@ -272,6 +272,8 @@
 		tok = tokstring(p.tok)
 	}
 
+	// TODO(gri) This may print "unexpected X, expected Y".
+	//           Consider "got X, expected Y" in this case.
 	p.errorAt(pos, "syntax error: unexpected "+tok+msg)
 }
 
@@ -312,7 +314,7 @@
 	1<<_Type |
 	1<<_Var
 
-// Advance consumes tokens until it finds a token of the stopset or followlist.
+// advance consumes tokens until it finds a token of the stopset or followlist.
 // The stopset is only considered if we are inside a function (p.fnest > 0).
 // The followlist is the list of valid tokens that can follow a production;
 // if it is empty, exactly one (non-EOF) token is consumed to ensure progress.
@@ -399,15 +401,20 @@
 		return nil
 	}
 
-	// { ImportDecl ";" }
-	for p.got(_Import) {
-		f.DeclList = p.appendGroup(f.DeclList, p.importDecl)
-		p.want(_Semi)
-	}
-
-	// { TopLevelDecl ";" }
+	// Accept import declarations anywhere for error tolerance, but complain.
+	// { ( ImportDecl | TopLevelDecl ) ";" }
+	prev := _Import
 	for p.tok != _EOF {
+		if p.tok == _Import && prev != _Import {
+			p.syntaxError("imports must appear before other declarations")
+		}
+		prev = p.tok
+
 		switch p.tok {
+		case _Import:
+			p.next()
+			f.DeclList = p.appendGroup(f.DeclList, p.importDecl)
+
 		case _Const:
 			p.next()
 			f.DeclList = p.appendGroup(f.DeclList, p.constDecl)
@@ -433,7 +440,7 @@
 			} else {
 				p.syntaxError("non-declaration statement outside function body")
 			}
-			p.advance(_Const, _Type, _Var, _Func)
+			p.advance(_Import, _Const, _Type, _Var, _Func)
 			continue
 		}
 
@@ -443,7 +450,7 @@
 
 		if p.tok != _EOF && !p.got(_Semi) {
 			p.syntaxError("after top level declaration")
-			p.advance(_Const, _Type, _Var, _Func)
+			p.advance(_Import, _Const, _Type, _Var, _Func)
 		}
 	}
 	// p.tok == _EOF
@@ -541,7 +548,7 @@
 		return d
 	}
 	if !d.Path.Bad && d.Path.Kind != StringLit {
-		p.syntaxError("import path must be a string")
+		p.syntaxErrorAt(d.Path.Pos(), "import path must be a string")
 		d.Path.Bad = true
 	}
 	// d.Path.Bad || d.Path.Kind == StringLit
@@ -760,7 +767,9 @@
 	f.pos = p.pos()
 	f.Pragma = p.takePragma()
 
+	var context string
 	if p.got(_Lparen) {
+		context = "method"
 		rcvr := p.paramList(nil, nil, _Rparen, false)
 		switch len(rcvr) {
 		case 0:
@@ -773,20 +782,18 @@
 		}
 	}
 
-	if p.tok != _Name {
-		p.syntaxError("expecting name or (")
+	if p.tok == _Name {
+		f.Name = p.name()
+		f.TParamList, f.Type = p.funcType(context)
+	} else {
+		msg := "expected name or ("
+		if context != "" {
+			msg = "expected name"
+		}
+		p.syntaxError(msg)
 		p.advance(_Lbrace, _Semi)
-		return nil
 	}
 
-	f.Name = p.name()
-
-	context := ""
-	if f.Recv != nil {
-		context = "method" // don't permit (method) type parameters in funcType
-	}
-	f.TParamList, f.Type = p.funcType(context)
-
 	if p.tok == _Lbrace {
 		f.Body = p.funcBody()
 	}
@@ -904,7 +911,7 @@
 				if dir == RecvOnly {
 					// t is type <-chan E but <-<-chan E is not permitted
 					// (report same error as for "type _ <-<-chan E")
-					p.syntaxError("unexpected <-, expecting chan")
+					p.syntaxError("unexpected <-, expected chan")
 					// already progressed, no need to advance
 				}
 				c.Dir = RecvOnly
@@ -913,7 +920,7 @@
 			if dir == SendOnly {
 				// channel dir is <- but channel element E is not a channel
 				// (report same error as for "type _ <-chan<-E")
-				p.syntaxError(fmt.Sprintf("unexpected %s, expecting chan", String(t)))
+				p.syntaxError(fmt.Sprintf("unexpected %s, expected chan", String(t)))
 				// already progressed, no need to advance
 			}
 			return x
@@ -951,16 +958,7 @@
 		x = t
 	}
 
-	cx, ok := x.(*CallExpr)
-	if !ok {
-		p.errorAt(x.Pos(), fmt.Sprintf("expression in %s must be function call", s.Tok))
-		// already progressed, no need to advance
-		cx = new(CallExpr)
-		cx.pos = x.Pos()
-		cx.Fun = x // assume common error of missing parentheses (function invocation)
-	}
-
-	s.Call = cx
+	s.Call = x
 	return s
 }
 
@@ -1033,7 +1031,7 @@
 
 	default:
 		x := p.badExpr()
-		p.syntaxError("expecting expression")
+		p.syntaxError("expected expression")
 		p.advance(_Rparen, _Rbrack, _Rbrace)
 		return x
 	}
@@ -1104,27 +1102,26 @@
 				p.want(_Rparen)
 
 			default:
-				p.syntaxError("expecting name or (")
+				p.syntaxError("expected name or (")
 				p.advance(_Semi, _Rparen)
 			}
 
 		case _Lbrack:
 			p.next()
 
-			if p.tok == _Rbrack {
-				// invalid empty instance, slice or index expression; accept but complain
-				p.syntaxError("expecting operand")
-				p.next()
-				break
-			}
-
 			var i Expr
 			if p.tok != _Colon {
 				var comma bool
-				i, comma = p.typeList()
+				if p.tok == _Rbrack {
+					// invalid empty instance, slice or index expression; accept but complain
+					p.syntaxError("expected operand")
+					i = p.badExpr()
+				} else {
+					i, comma = p.typeList(false)
+				}
 				if comma || p.tok == _Rbrack {
 					p.want(_Rbrack)
-					// x[i,] or x[i, j, ...]
+					// x[], x[i,] or x[i, j, ...]
 					t := new(IndexExpr)
 					t.pos = pos
 					t.X = x
@@ -1137,7 +1134,7 @@
 			// x[i:...
 			// For better error message, don't simply use p.want(_Colon) here (issue #47704).
 			if !p.got(_Colon) {
-				p.syntaxError("expecting comma, : or ]")
+				p.syntaxError("expected comma, : or ]")
 				p.advance(_Comma, _Colon, _Rbrack)
 			}
 			p.xnest++
@@ -1289,7 +1286,7 @@
 	typ := p.typeOrNil()
 	if typ == nil {
 		typ = p.badExpr()
-		p.syntaxError("expecting type")
+		p.syntaxError("expected type")
 		p.advance(_Comma, _Colon, _Semi, _Rparen, _Rbrack, _Rbrace)
 	}
 
@@ -1401,10 +1398,10 @@
 	x.pos = pos
 	x.X = typ
 	if p.tok == _Rbrack {
-		p.syntaxError("expecting type")
+		p.syntaxError("expected type argument list")
 		x.Index = p.badExpr()
 	} else {
-		x.Index, _ = p.typeList()
+		x.Index, _ = p.typeList(true)
 	}
 	p.want(_Rbrack)
 	return x
@@ -1456,7 +1453,7 @@
 		// Trailing commas are accepted in type parameter
 		// lists but not in array type declarations.
 		// Accept for better error handling but complain.
-		p.syntaxError("unexpected comma; expecting ]")
+		p.syntaxError("unexpected comma; expected ]")
 		p.next()
 	}
 	p.want(_Rbrack)
@@ -1509,8 +1506,7 @@
 	return typ
 }
 
-// InterfaceType = "interface" "{" { ( MethodDecl | EmbeddedElem | TypeList ) ";" } "}" .
-// TypeList      = "type" Type { "," Type } .
+// InterfaceType = "interface" "{" { ( MethodDecl | EmbeddedElem ) ";" } "}" .
 func (p *parser) interfaceType() *InterfaceType {
 	if trace {
 		defer p.trace("interfaceType")()
@@ -1656,7 +1652,7 @@
 		p.addField(styp, pos, nil, typ, tag)
 
 	default:
-		p.syntaxError("expecting field name or embedded type")
+		p.syntaxError("expected field name or embedded type")
 		p.advance(_Semi, _Rbrace)
 	}
 }
@@ -1673,7 +1669,7 @@
 	}
 
 	// x [n]E or x[n,], x[n1, n2], ...
-	n, comma := p.typeList()
+	n, comma := p.typeList(false)
 	p.want(_Rbrack)
 	if !comma {
 		if elem := p.typeOrNil(); elem != nil {
@@ -1846,7 +1842,7 @@
 	t := p.typeOrNil()
 	if t == nil {
 		t = p.badExpr()
-		p.syntaxError("expecting ~ term or type")
+		p.syntaxError("expected ~ term or type")
 		p.advance(_Operator, _Semi, _Rparen, _Rbrack, _Rbrace)
 	}
 
@@ -1945,7 +1941,7 @@
 		return f
 	}
 
-	p.syntaxError("expecting " + tokstring(follow))
+	p.syntaxError("expected " + tokstring(follow))
 	p.advance(_Comma, follow)
 	return nil
 }
@@ -2151,7 +2147,7 @@
 		return p.newAssignStmt(pos, op, lhs, rhs)
 
 	default:
-		p.syntaxError("expecting := or = or comma")
+		p.syntaxError("expected := or = or comma")
 		p.advance(_Semi, _Rbrace)
 		// make the best of what we have
 		if x, ok := lhs.(*ListExpr); ok {
@@ -2226,7 +2222,7 @@
 
 	// people coming from C may forget that braces are mandatory in Go
 	if !p.got(_Lbrace) {
-		p.syntaxError("expecting { after " + context)
+		p.syntaxError("expected { after " + context)
 		p.advance(_Name, _Rbrace)
 		s.Rbrace = p.pos() // in case we found "}"
 		if p.got(_Rbrace) {
@@ -2317,7 +2313,7 @@
 		if keyword == _For {
 			if p.tok != _Semi {
 				if p.tok == _Lbrace {
-					p.syntaxError("expecting for loop condition")
+					p.syntaxError("expected for loop condition")
 					goto done
 				}
 				condStmt = p.simpleStmt(nil, 0 /* range not permitted */)
@@ -2343,7 +2339,7 @@
 	case nil:
 		if keyword == _If && semi.pos.IsKnown() {
 			if semi.lit != "semicolon" {
-				p.syntaxErrorAt(semi.pos, fmt.Sprintf("unexpected %s, expecting { after if clause", semi.lit))
+				p.syntaxErrorAt(semi.pos, fmt.Sprintf("unexpected %s, expected { after if clause", semi.lit))
 			} else {
 				p.syntaxErrorAt(semi.pos, "missing condition in if statement")
 			}
@@ -2462,7 +2458,7 @@
 		p.next()
 
 	default:
-		p.syntaxError("expecting case or default or }")
+		p.syntaxError("expected case or default or }")
 		p.advance(_Colon, _Case, _Default, _Rbrace)
 	}
 
@@ -2495,14 +2491,12 @@
 		//
 		// All these (and more) are recognized by simpleStmt and invalid
 		// syntax trees are flagged later, during type checking.
-		// TODO(gri) eventually may want to restrict valid syntax trees
-		// here.
 
 	case _Default:
 		p.next()
 
 	default:
-		p.syntaxError("expecting case or default or }")
+		p.syntaxError("expected case or default or }")
 		p.advance(_Colon, _Case, _Default, _Rbrace)
 	}
 
@@ -2679,7 +2673,7 @@
 	}
 
 	n := NewName(p.pos(), "_")
-	p.syntaxError("expecting name")
+	p.syntaxError("expected name")
 	p.advance()
 	return n
 }
@@ -2717,7 +2711,7 @@
 		x = p.name()
 	default:
 		x = NewName(p.pos(), "_")
-		p.syntaxError("expecting name")
+		p.syntaxError("expected name")
 		p.advance(_Dot, _Semi, _Rbrace)
 	}
 
@@ -2757,21 +2751,25 @@
 	return x
 }
 
-// typeList parses a non-empty, comma-separated list of expressions,
-// optionally followed by a comma. The first list element may be any
-// expression, all other list elements must be type expressions.
+// typeList parses a non-empty, comma-separated list of types,
+// optionally followed by a comma. If strict is set to false,
+// the first element may also be a (non-type) expression.
 // If there is more than one argument, the result is a *ListExpr.
 // The comma result indicates whether there was a (separating or
 // trailing) comma.
 //
 // typeList = arg { "," arg } [ "," ] .
-func (p *parser) typeList() (x Expr, comma bool) {
+func (p *parser) typeList(strict bool) (x Expr, comma bool) {
 	if trace {
 		defer p.trace("typeList")()
 	}
 
 	p.xnest++
-	x = p.expr()
+	if strict {
+		x = p.type_()
+	} else {
+		x = p.expr()
+	}
 	if p.got(_Comma) {
 		comma = true
 		if t := p.typeOrNil(); t != nil {
diff --git a/src/cmd/compile/internal/syntax/parser_test.go b/src/cmd/compile/internal/syntax/parser_test.go
index b3d4573..74583ca 100644
--- a/src/cmd/compile/internal/syntax/parser_test.go
+++ b/src/cmd/compile/internal/syntax/parser_test.go
@@ -9,7 +9,7 @@
 	"flag"
 	"fmt"
 	"internal/testenv"
-	"io/ioutil"
+	"os"
 	"path/filepath"
 	"regexp"
 	"runtime"
@@ -112,21 +112,21 @@
 }
 
 func walkDirs(t *testing.T, dir string, action func(string)) {
-	fis, err := ioutil.ReadDir(dir)
+	entries, err := os.ReadDir(dir)
 	if err != nil {
 		t.Error(err)
 		return
 	}
 
 	var files, dirs []string
-	for _, fi := range fis {
-		if fi.Mode().IsRegular() {
-			if strings.HasSuffix(fi.Name(), ".go") {
-				path := filepath.Join(dir, fi.Name())
+	for _, entry := range entries {
+		if entry.Type().IsRegular() {
+			if strings.HasSuffix(entry.Name(), ".go") {
+				path := filepath.Join(dir, entry.Name())
 				files = append(files, path)
 			}
-		} else if fi.IsDir() && fi.Name() != "testdata" {
-			path := filepath.Join(dir, fi.Name())
+		} else if entry.IsDir() && entry.Name() != "testdata" {
+			path := filepath.Join(dir, entry.Name())
 			if !strings.HasSuffix(path, string(filepath.Separator)+"test") {
 				dirs = append(dirs, path)
 			}
diff --git a/src/cmd/compile/internal/syntax/printer.go b/src/cmd/compile/internal/syntax/printer.go
index 9cf2cc8..62de68e 100644
--- a/src/cmd/compile/internal/syntax/printer.go
+++ b/src/cmd/compile/internal/syntax/printer.go
@@ -7,7 +7,6 @@
 package syntax
 
 import (
-	"bytes"
 	"fmt"
 	"io"
 	"strings"
@@ -47,7 +46,7 @@
 // String is a convenience function that prints n in ShortForm
 // and returns the printed string.
 func String(n Node) string {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	_, err := Fprint(&buf, n, ShortForm)
 	if err != nil {
 		fmt.Fprintf(&buf, "<<< ERROR: %s", err)
diff --git a/src/cmd/compile/internal/syntax/printer_test.go b/src/cmd/compile/internal/syntax/printer_test.go
index 863713c..ceb512e 100644
--- a/src/cmd/compile/internal/syntax/printer_test.go
+++ b/src/cmd/compile/internal/syntax/printer_test.go
@@ -7,7 +7,6 @@
 import (
 	"fmt"
 	"io"
-	"io/ioutil"
 	"os"
 	"strings"
 	"testing"
@@ -155,7 +154,7 @@
 	if testing.Verbose() {
 		return os.Stdout
 	}
-	return ioutil.Discard
+	return io.Discard
 }
 
 func dup(s string) [2]string { return [2]string{s, s} }
diff --git a/src/cmd/compile/internal/syntax/scanner_test.go b/src/cmd/compile/internal/syntax/scanner_test.go
index 2deb3bb..450ec1f 100644
--- a/src/cmd/compile/internal/syntax/scanner_test.go
+++ b/src/cmd/compile/internal/syntax/scanner_test.go
@@ -88,10 +88,10 @@
 	// make source
 	var buf bytes.Buffer
 	for i, s := range sampleTokens {
-		buf.WriteString("\t\t\t\t"[:i&3])                            // leading indentation
-		buf.WriteString(s.src)                                       // token
-		buf.WriteString("        "[:i&7])                            // trailing spaces
-		buf.WriteString(fmt.Sprintf("/*line foo:%d */ // bar\n", i)) // comments + newline (don't crash w/o directive handler)
+		buf.WriteString("\t\t\t\t"[:i&3])                 // leading indentation
+		buf.WriteString(s.src)                            // token
+		buf.WriteString("        "[:i&7])                 // trailing spaces
+		fmt.Fprintf(&buf, "/*line foo:%d */ // bar\n", i) // comments + newline (don't crash w/o directive handler)
 	}
 
 	// scan source
diff --git a/src/cmd/compile/internal/syntax/testdata/issue20789.go b/src/cmd/compile/internal/syntax/testdata/issue20789.go
index 5f150db..0d5988b 100644
--- a/src/cmd/compile/internal/syntax/testdata/issue20789.go
+++ b/src/cmd/compile/internal/syntax/testdata/issue20789.go
@@ -6,4 +6,4 @@
 // Line 9 must end in EOF for this test (no newline).
 
 package e
-func([<-chan<-[func /* ERROR unexpected u */ u){go /* ERROR must be function call */
\ No newline at end of file
+func([<-chan<-[func /* ERROR unexpected u */ u){go
\ No newline at end of file
diff --git a/src/cmd/compile/internal/syntax/testdata/issue47704.go b/src/cmd/compile/internal/syntax/testdata/issue47704.go
index 2f2e29b..e4cdad1 100644
--- a/src/cmd/compile/internal/syntax/testdata/issue47704.go
+++ b/src/cmd/compile/internal/syntax/testdata/issue47704.go
@@ -5,13 +5,13 @@
 package p
 
 func _() {
-	_ = m[] // ERROR expecting operand
+	_ = m[] // ERROR expected operand
 	_ = m[x,]
 	_ = m[x /* ERROR unexpected a */ a b c d]
 }
 
 // test case from the issue
 func f(m map[int]int) int {
-	return m[0 // ERROR expecting comma, \: or \]
+	return m[0 // ERROR expected comma, \: or \]
 		]
 }
diff --git a/src/cmd/compile/internal/syntax/testdata/issue56022.go b/src/cmd/compile/internal/syntax/testdata/issue56022.go
new file mode 100644
index 0000000..d28d35c
--- /dev/null
+++ b/src/cmd/compile/internal/syntax/testdata/issue56022.go
@@ -0,0 +1,10 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func /* ERROR unexpected {, expected name or \($ */ {}
+func (T) /* ERROR unexpected {, expected name$ */ {}
+func (T) /* ERROR unexpected \(, expected name$ */ () {}
+func (T) /* ERROR unexpected \(, expected name$ */ ()
diff --git a/src/cmd/compile/internal/syntax/testdata/tparams.go b/src/cmd/compile/internal/syntax/testdata/tparams.go
index 671833f..646fbbe 100644
--- a/src/cmd/compile/internal/syntax/testdata/tparams.go
+++ b/src/cmd/compile/internal/syntax/testdata/tparams.go
@@ -21,7 +21,7 @@
 func f[a, b /* ERROR missing type constraint */ ]()
 func f[a t, b t, c /* ERROR missing type constraint */ ]()
 
-func f[a b,  /* ERROR expecting ] */ 0] ()
+func f[a b,  /* ERROR expected ] */ 0] ()
 
 // issue #49482
 type (
diff --git a/src/cmd/compile/internal/syntax/type.go b/src/cmd/compile/internal/syntax/type.go
new file mode 100644
index 0000000..01eab7a
--- /dev/null
+++ b/src/cmd/compile/internal/syntax/type.go
@@ -0,0 +1,73 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package syntax
+
+import "go/constant"
+
+// A Type represents a type of Go.
+// All types implement the Type interface.
+// (This type originally lived in types2. We moved it here
+// so we could depend on it from other packages without
+// introducing a circularity.)
+type Type interface {
+	// Underlying returns the underlying type of a type.
+	Underlying() Type
+
+	// String returns a string representation of a type.
+	String() string
+}
+
+// Expressions in the syntax package provide storage for
+// the typechecker to record its results. This interface
+// is the mechanism the typechecker uses to record results,
+// and clients use to retrieve those results.
+type typeInfo interface {
+	SetTypeInfo(TypeAndValue)
+	GetTypeInfo() TypeAndValue
+}
+
+// A TypeAndValue records the type information, constant
+// value if known, and various other flags associated with
+// an expression.
+// This type is similar to types2.TypeAndValue, but exposes
+// none of types2's internals.
+type TypeAndValue struct {
+	Type  Type
+	Value constant.Value
+	exprFlags
+}
+
+type exprFlags uint8
+
+func (f exprFlags) IsVoid() bool      { return f&1 != 0 }
+func (f exprFlags) IsType() bool      { return f&2 != 0 }
+func (f exprFlags) IsBuiltin() bool   { return f&4 != 0 }
+func (f exprFlags) IsValue() bool     { return f&8 != 0 }
+func (f exprFlags) IsNil() bool       { return f&16 != 0 }
+func (f exprFlags) Addressable() bool { return f&32 != 0 }
+func (f exprFlags) Assignable() bool  { return f&64 != 0 }
+func (f exprFlags) HasOk() bool       { return f&128 != 0 }
+
+func (f *exprFlags) SetIsVoid()      { *f |= 1 }
+func (f *exprFlags) SetIsType()      { *f |= 2 }
+func (f *exprFlags) SetIsBuiltin()   { *f |= 4 }
+func (f *exprFlags) SetIsValue()     { *f |= 8 }
+func (f *exprFlags) SetIsNil()       { *f |= 16 }
+func (f *exprFlags) SetAddressable() { *f |= 32 }
+func (f *exprFlags) SetAssignable()  { *f |= 64 }
+func (f *exprFlags) SetHasOk()       { *f |= 128 }
+
+// a typeAndValue contains the results of typechecking an expression.
+// It is embedded in expression nodes.
+type typeAndValue struct {
+	tv TypeAndValue
+}
+
+func (x *typeAndValue) SetTypeInfo(tv TypeAndValue) {
+	x.tv = tv
+}
+func (x *typeAndValue) GetTypeInfo() TypeAndValue {
+	return x.tv
+}
diff --git a/src/cmd/compile/internal/test/clobberdead_test.go b/src/cmd/compile/internal/test/clobberdead_test.go
index 88b7d34..80d9678 100644
--- a/src/cmd/compile/internal/test/clobberdead_test.go
+++ b/src/cmd/compile/internal/test/clobberdead_test.go
@@ -6,8 +6,7 @@
 
 import (
 	"internal/testenv"
-	"io/ioutil"
-	"os/exec"
+	"os"
 	"path/filepath"
 	"testing"
 )
@@ -39,12 +38,12 @@
 
 	tmpdir := t.TempDir()
 	src := filepath.Join(tmpdir, "x.go")
-	err := ioutil.WriteFile(src, []byte(helloSrc), 0644)
+	err := os.WriteFile(src, []byte(helloSrc), 0644)
 	if err != nil {
 		t.Fatalf("write file failed: %v", err)
 	}
 
-	cmd := exec.Command(testenv.GoToolPath(t), "run", "-gcflags=all="+flag, src)
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "run", "-gcflags=all="+flag, src)
 	out, err := cmd.CombinedOutput()
 	if err != nil {
 		t.Fatalf("go run failed: %v\n%s", err, out)
diff --git a/src/cmd/compile/internal/test/dep_test.go b/src/cmd/compile/internal/test/dep_test.go
index 698a848..d141f10 100644
--- a/src/cmd/compile/internal/test/dep_test.go
+++ b/src/cmd/compile/internal/test/dep_test.go
@@ -6,13 +6,12 @@
 
 import (
 	"internal/testenv"
-	"os/exec"
 	"strings"
 	"testing"
 )
 
 func TestDeps(t *testing.T) {
-	out, err := exec.Command(testenv.GoToolPath(t), "list", "-f", "{{.Deps}}", "cmd/compile/internal/gc").Output()
+	out, err := testenv.Command(t, testenv.GoToolPath(t), "list", "-f", "{{.Deps}}", "cmd/compile/internal/gc").Output()
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/src/cmd/compile/internal/test/fixedbugs_test.go b/src/cmd/compile/internal/test/fixedbugs_test.go
index cd0d5fc..cf607b7 100644
--- a/src/cmd/compile/internal/test/fixedbugs_test.go
+++ b/src/cmd/compile/internal/test/fixedbugs_test.go
@@ -6,9 +6,7 @@
 
 import (
 	"internal/testenv"
-	"io/ioutil"
 	"os"
-	"os/exec"
 	"path/filepath"
 	"strings"
 	"testing"
@@ -60,19 +58,19 @@
 // Test that the generated assembly has line numbers (Issue #16214).
 func TestIssue16214(t *testing.T) {
 	testenv.MustHaveGoBuild(t)
-	dir, err := ioutil.TempDir("", "TestLineNumber")
+	dir, err := os.MkdirTemp("", "TestLineNumber")
 	if err != nil {
 		t.Fatalf("could not create directory: %v", err)
 	}
 	defer os.RemoveAll(dir)
 
 	src := filepath.Join(dir, "x.go")
-	err = ioutil.WriteFile(src, []byte(issue16214src), 0644)
+	err = os.WriteFile(src, []byte(issue16214src), 0644)
 	if err != nil {
 		t.Fatalf("could not write file: %v", err)
 	}
 
-	cmd := exec.Command(testenv.GoToolPath(t), "tool", "compile", "-p=main", "-S", "-o", filepath.Join(dir, "out.o"), src)
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "tool", "compile", "-p=main", "-S", "-o", filepath.Join(dir, "out.o"), src)
 	out, err := cmd.CombinedOutput()
 	if err != nil {
 		t.Fatalf("go tool compile: %v\n%s", err, out)
diff --git a/src/cmd/compile/internal/test/global_test.go b/src/cmd/compile/internal/test/global_test.go
index 93de894..2cf93dc 100644
--- a/src/cmd/compile/internal/test/global_test.go
+++ b/src/cmd/compile/internal/test/global_test.go
@@ -7,9 +7,7 @@
 import (
 	"bytes"
 	"internal/testenv"
-	"io/ioutil"
 	"os"
-	"os/exec"
 	"path/filepath"
 	"strings"
 	"testing"
@@ -22,7 +20,7 @@
 	t.Parallel()
 
 	// Make a directory to work in.
-	dir, err := ioutil.TempDir("", "issue6853a-")
+	dir, err := os.MkdirTemp("", "issue6853a-")
 	if err != nil {
 		t.Fatalf("could not create directory: %v", err)
 	}
@@ -47,14 +45,14 @@
 	dst := filepath.Join(dir, "test")
 
 	// Compile source.
-	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", dst, src)
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-o", dst, src)
 	out, err := cmd.CombinedOutput()
 	if err != nil {
 		t.Fatalf("could not build target: %v\n%s", err, out)
 	}
 
 	// Check destination to see if scanf code was included.
-	cmd = exec.Command(testenv.GoToolPath(t), "tool", "nm", dst)
+	cmd = testenv.Command(t, testenv.GoToolPath(t), "tool", "nm", dst)
 	out, err = cmd.CombinedOutput()
 	if err != nil {
 		t.Fatalf("could not read target: %v", err)
@@ -70,7 +68,7 @@
 	t.Parallel()
 
 	// Make a directory to work in.
-	dir, err := ioutil.TempDir("", "issue14515-")
+	dir, err := os.MkdirTemp("", "issue14515-")
 	if err != nil {
 		t.Fatalf("could not create directory: %v", err)
 	}
@@ -92,7 +90,7 @@
 	f.Close()
 
 	// Compile source.
-	cmd := exec.Command(testenv.GoToolPath(t), "build", "-gcflags", "-S", "-o", filepath.Join(dir, "test"), src)
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-gcflags", "-S", "-o", filepath.Join(dir, "test"), src)
 	out, err := cmd.CombinedOutput()
 	if err != nil {
 		t.Fatalf("could not build target: %v\n%s", err, out)
diff --git a/src/cmd/compile/internal/test/inl_test.go b/src/cmd/compile/internal/test/inl_test.go
index 49ee88e..201f577 100644
--- a/src/cmd/compile/internal/test/inl_test.go
+++ b/src/cmd/compile/internal/test/inl_test.go
@@ -6,10 +6,11 @@
 
 import (
 	"bufio"
+	"internal/buildcfg"
+	"internal/goexperiment"
 	"internal/testenv"
 	"io"
 	"math/bits"
-	"os/exec"
 	"regexp"
 	"runtime"
 	"strings"
@@ -47,7 +48,6 @@
 			"fastrand",
 			"float64bits",
 			"funcspdelta",
-			"getArgInfoFast",
 			"getm",
 			"getMCache",
 			"isDirectIface",
@@ -72,11 +72,7 @@
 			"cgoInRange",
 			"gclinkptr.ptr",
 			"guintptr.ptr",
-			"heapBits.bits",
-			"heapBits.isPointer",
-			"heapBits.morePointers",
-			"heapBits.next",
-			"heapBitsForAddr",
+			"writeHeapBitsForAddr",
 			"markBits.isMarked",
 			"muintptr.ptr",
 			"puintptr.ptr",
@@ -210,26 +206,24 @@
 			"(*Uintptr).Load",
 			"(*Uintptr).Store",
 			"(*Uintptr).Swap",
-			// TODO(rsc): Why are these not reported as inlined?
-			// "(*Pointer[T]).CompareAndSwap",
-			// "(*Pointer[T]).Load",
-			// "(*Pointer[T]).Store",
-			// "(*Pointer[T]).Swap",
+			// (*Pointer[T])'s methods' handled below.
 		},
 	}
 
 	if runtime.GOARCH != "386" && runtime.GOARCH != "loong64" && runtime.GOARCH != "mips64" && runtime.GOARCH != "mips64le" && runtime.GOARCH != "riscv64" {
-		// nextFreeFast calls sys.Ctz64, which on 386 is implemented in asm and is not inlinable.
+		// nextFreeFast calls sys.TrailingZeros64, which on 386 is implemented in asm and is not inlinable.
 		// We currently don't have midstack inlining so nextFreeFast is also not inlinable on 386.
-		// On loong64, mips64x and riscv64, Ctz64 is not intrinsified and causes nextFreeFast too expensive
-		// to inline (Issue 22239).
+		// On loong64, mips64x and riscv64, TrailingZeros64 is not intrinsified and causes nextFreeFast
+		// too expensive to inline (Issue 22239).
 		want["runtime"] = append(want["runtime"], "nextFreeFast")
+		// Same behavior for heapBits.nextFast.
+		want["runtime"] = append(want["runtime"], "heapBits.nextFast")
 	}
 	if runtime.GOARCH != "386" {
-		// As explained above, Ctz64 and Ctz32 are not Go code on 386.
+		// As explained above, TrailingZeros64 and TrailingZeros32 are not Go code on 386.
 		// The same applies to Bswap32.
-		want["runtime/internal/sys"] = append(want["runtime/internal/sys"], "Ctz64")
-		want["runtime/internal/sys"] = append(want["runtime/internal/sys"], "Ctz32")
+		want["runtime/internal/sys"] = append(want["runtime/internal/sys"], "TrailingZeros64")
+		want["runtime/internal/sys"] = append(want["runtime/internal/sys"], "TrailingZeros32")
 		want["runtime/internal/sys"] = append(want["runtime/internal/sys"], "Bswap32")
 	}
 	if bits.UintSize == 64 {
@@ -238,6 +232,14 @@
 		// (*Bool).CompareAndSwap is just over budget on 32-bit systems (386, arm).
 		want["sync/atomic"] = append(want["sync/atomic"], "(*Bool).CompareAndSwap")
 	}
+	if buildcfg.Experiment.Unified {
+		// Non-unified IR does not report "inlining call ..." for atomic.Pointer[T]'s methods.
+		// TODO(cuonglm): remove once non-unified IR frontend gone.
+		want["sync/atomic"] = append(want["sync/atomic"], "(*Pointer[go.shape.int]).CompareAndSwap")
+		want["sync/atomic"] = append(want["sync/atomic"], "(*Pointer[go.shape.int]).Load")
+		want["sync/atomic"] = append(want["sync/atomic"], "(*Pointer[go.shape.int]).Store")
+		want["sync/atomic"] = append(want["sync/atomic"], "(*Pointer[go.shape.int]).Swap")
+	}
 
 	switch runtime.GOARCH {
 	case "386", "wasm", "arm":
@@ -276,7 +278,7 @@
 	}
 
 	args := append([]string{"build", "-gcflags=-m -m", "-tags=math_big_pure_go"}, pkgs...)
-	cmd := testenv.CleanCmdEnv(exec.Command(testenv.GoToolPath(t), args...))
+	cmd := testenv.CleanCmdEnv(testenv.Command(t, testenv.GoToolPath(t), args...))
 	pr, pw := io.Pipe()
 	cmd.Stdout = pw
 	cmd.Stderr = pw
@@ -330,3 +332,57 @@
 		t.Errorf("%s was not inlined: %s", fullName, reason)
 	}
 }
+
+func collectInlCands(msgs string) map[string]struct{} {
+	rv := make(map[string]struct{})
+	lines := strings.Split(msgs, "\n")
+	re := regexp.MustCompile(`^\S+\s+can\s+inline\s+(\S+)`)
+	for _, line := range lines {
+		m := re.FindStringSubmatch(line)
+		if m != nil {
+			rv[m[1]] = struct{}{}
+		}
+	}
+	return rv
+}
+
+func TestIssue56044(t *testing.T) {
+	if testing.Short() {
+		t.Skipf("skipping test: too long for short mode")
+	}
+	if !goexperiment.CoverageRedesign {
+		t.Skipf("skipping new coverage tests (experiment not enabled)")
+	}
+
+	testenv.MustHaveGoBuild(t)
+
+	modes := []string{"-covermode=set", "-covermode=atomic"}
+
+	for _, mode := range modes {
+		// Build the Go runtime with "-m", capturing output.
+		args := []string{"build", "-gcflags=runtime=-m", "runtime"}
+		cmd := testenv.Command(t, testenv.GoToolPath(t), args...)
+		b, err := cmd.CombinedOutput()
+		if err != nil {
+			t.Fatalf("build failed (%v): %s", err, b)
+		}
+		mbase := collectInlCands(string(b))
+
+		// Redo the build with -cover, also with "-m".
+		args = []string{"build", "-gcflags=runtime=-m", mode, "runtime"}
+		cmd = testenv.Command(t, testenv.GoToolPath(t), args...)
+		b, err = cmd.CombinedOutput()
+		if err != nil {
+			t.Fatalf("build failed (%v): %s", err, b)
+		}
+		mcov := collectInlCands(string(b))
+
+		// Make sure that there aren't any functions that are marked
+		// as inline candidates at base but not with coverage.
+		for k := range mbase {
+			if _, ok := mcov[k]; !ok {
+				t.Errorf("error: did not find %s in coverage -m output", k)
+			}
+		}
+	}
+}
diff --git a/src/cmd/compile/internal/test/inst_test.go b/src/cmd/compile/internal/test/inst_test.go
index 951f6a0..de435de 100644
--- a/src/cmd/compile/internal/test/inst_test.go
+++ b/src/cmd/compile/internal/test/inst_test.go
@@ -5,11 +5,8 @@
 package test
 
 import (
-	"internal/goexperiment"
 	"internal/testenv"
-	"io/ioutil"
 	"os"
-	"os/exec"
 	"path/filepath"
 	"regexp"
 	"testing"
@@ -18,15 +15,12 @@
 // TestInst tests that only one instantiation of Sort is created, even though generic
 // Sort is used for multiple pointer types across two packages.
 func TestInst(t *testing.T) {
-	if goexperiment.Unified {
-		t.Skip("unified currently does stenciling, not dictionaries")
-	}
 	testenv.MustHaveGoBuild(t)
 	testenv.MustHaveGoRun(t)
 
 	var tmpdir string
 	var err error
-	tmpdir, err = ioutil.TempDir("", "TestDict")
+	tmpdir, err = os.MkdirTemp("", "TestDict")
 	if err != nil {
 		t.Fatalf("Failed to create temporary directory: %v", err)
 	}
@@ -39,14 +33,14 @@
 	outname := "ptrsort.out"
 	gotool := testenv.GoToolPath(t)
 	dest := filepath.Join(tmpdir, exename)
-	cmd := exec.Command(gotool, "build", "-o", dest, filepath.Join("testdata", filename))
+	cmd := testenv.Command(t, gotool, "build", "-o", dest, filepath.Join("testdata", filename))
 	if output, err = cmd.CombinedOutput(); err != nil {
 		t.Fatalf("Failed: %v:\nOutput: %s\n", err, output)
 	}
 
 	// Test that there is exactly one shape-based instantiation of Sort in
 	// the executable.
-	cmd = exec.Command(gotool, "tool", "nm", dest)
+	cmd = testenv.Command(t, gotool, "tool", "nm", dest)
 	if output, err = cmd.CombinedOutput(); err != nil {
 		t.Fatalf("Failed: %v:\nOut: %s\n", err, output)
 	}
@@ -59,11 +53,11 @@
 	}
 
 	// Actually run the test and make sure output is correct.
-	cmd = exec.Command(gotool, "run", filepath.Join("testdata", filename))
+	cmd = testenv.Command(t, gotool, "run", filepath.Join("testdata", filename))
 	if output, err = cmd.CombinedOutput(); err != nil {
 		t.Fatalf("Failed: %v:\nOut: %s\n", err, output)
 	}
-	out, err := ioutil.ReadFile(filepath.Join("testdata", outname))
+	out, err := os.ReadFile(filepath.Join("testdata", outname))
 	if err != nil {
 		t.Fatalf("Could not find %s\n", outname)
 	}
diff --git a/src/cmd/compile/internal/test/issue53888_test.go b/src/cmd/compile/internal/test/issue53888_test.go
new file mode 100644
index 0000000..0d5b13b
--- /dev/null
+++ b/src/cmd/compile/internal/test/issue53888_test.go
@@ -0,0 +1,46 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !race
+
+package test
+
+import (
+	"internal/testenv"
+	"testing"
+)
+
+func TestAppendOfMake(t *testing.T) {
+	testenv.SkipIfOptimizationOff(t)
+	for n := 32; n < 33; n++ { // avoid stack allocation of make()
+		b := make([]byte, n)
+		f := func() {
+			b = append(b[:0], make([]byte, n)...)
+		}
+		if n := testing.AllocsPerRun(10, f); n > 0 {
+			t.Errorf("got %f allocs, want 0", n)
+		}
+		type S []byte
+
+		s := make(S, n)
+		g := func() {
+			s = append(s[:0], make(S, n)...)
+		}
+		if n := testing.AllocsPerRun(10, g); n > 0 {
+			t.Errorf("got %f allocs, want 0", n)
+		}
+		h := func() {
+			s = append(s[:0], make([]byte, n)...)
+		}
+		if n := testing.AllocsPerRun(10, h); n > 0 {
+			t.Errorf("got %f allocs, want 0", n)
+		}
+		i := func() {
+			b = append(b[:0], make(S, n)...)
+		}
+		if n := testing.AllocsPerRun(10, i); n > 0 {
+			t.Errorf("got %f allocs, want 0", n)
+		}
+	}
+}
diff --git a/src/cmd/compile/internal/test/lang_test.go b/src/cmd/compile/internal/test/lang_test.go
index 66ab840..0b957dc 100644
--- a/src/cmd/compile/internal/test/lang_test.go
+++ b/src/cmd/compile/internal/test/lang_test.go
@@ -6,9 +6,7 @@
 
 import (
 	"internal/testenv"
-	"io/ioutil"
 	"os"
-	"os/exec"
 	"path/filepath"
 	"testing"
 )
@@ -24,14 +22,14 @@
 
 	testenv.MustHaveGoBuild(t)
 
-	dir, err := ioutil.TempDir("", "TestInvalidLang")
+	dir, err := os.MkdirTemp("", "TestInvalidLang")
 	if err != nil {
 		t.Fatal(err)
 	}
 	defer os.RemoveAll(dir)
 
 	src := filepath.Join(dir, "alias.go")
-	if err := ioutil.WriteFile(src, []byte(aliasSrc), 0644); err != nil {
+	if err := os.WriteFile(src, []byte(aliasSrc), 0644); err != nil {
 		t.Fatal(err)
 	}
 
@@ -58,7 +56,7 @@
 func testLang(t *testing.T, lang, src, outfile string) error {
 	run := []string{testenv.GoToolPath(t), "tool", "compile", "-p=p", "-lang", lang, "-o", outfile, src}
 	t.Log(run)
-	out, err := exec.Command(run[0], run[1:]...).CombinedOutput()
+	out, err := testenv.Command(t, run[0], run[1:]...).CombinedOutput()
 	t.Logf("%s", out)
 	return err
 }
diff --git a/src/cmd/compile/internal/test/pgo_inl_test.go b/src/cmd/compile/internal/test/pgo_inl_test.go
new file mode 100644
index 0000000..4d6b5a1
--- /dev/null
+++ b/src/cmd/compile/internal/test/pgo_inl_test.go
@@ -0,0 +1,299 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package test
+
+import (
+	"bufio"
+	"fmt"
+	"internal/profile"
+	"internal/testenv"
+	"io"
+	"os"
+	"path/filepath"
+	"regexp"
+	"strings"
+	"testing"
+)
+
+// testPGOIntendedInlining tests that specific functions are inlined.
+func testPGOIntendedInlining(t *testing.T, dir string) {
+	testenv.MustHaveGoRun(t)
+	t.Parallel()
+
+	const pkg = "example.com/pgo/inline"
+
+	// Add a go.mod so we have a consistent symbol names in this temp dir.
+	goMod := fmt.Sprintf(`module %s
+go 1.19
+`, pkg)
+	if err := os.WriteFile(filepath.Join(dir, "go.mod"), []byte(goMod), 0644); err != nil {
+		t.Fatalf("error writing go.mod: %v", err)
+	}
+
+	want := []string{
+		"(*BS).NS",
+	}
+
+	// The functions which are not expected to be inlined are as follows.
+	wantNot := []string{
+		// The calling edge main->A is hot and the cost of A is large
+		// than inlineHotCalleeMaxBudget.
+		"A",
+		// The calling edge BenchmarkA" -> benchmarkB is cold and the
+		// cost of A is large than inlineMaxBudget.
+		"benchmarkB",
+	}
+
+	must := map[string]bool{
+		"(*BS).NS": true,
+	}
+
+	notInlinedReason := make(map[string]string)
+	for _, fname := range want {
+		fullName := pkg + "." + fname
+		if _, ok := notInlinedReason[fullName]; ok {
+			t.Errorf("duplicate func: %s", fullName)
+		}
+		notInlinedReason[fullName] = "unknown reason"
+	}
+
+	// If the compiler emit "cannot inline for function A", the entry A
+	// in expectedNotInlinedList will be removed.
+	expectedNotInlinedList := make(map[string]struct{})
+	for _, fname := range wantNot {
+		fullName := pkg + "." + fname
+		expectedNotInlinedList[fullName] = struct{}{}
+	}
+
+	// Build the test with the profile. Use a smaller threshold to test.
+	// TODO: maybe adjust the test to work with default threshold.
+	pprof := filepath.Join(dir, "inline_hot.pprof")
+	gcflag := fmt.Sprintf("-gcflags=-m -m -pgoprofile=%s -d=pgoinlinebudget=160,pgoinlinecdfthreshold=90", pprof)
+	out := filepath.Join(dir, "test.exe")
+	cmd := testenv.CleanCmdEnv(testenv.Command(t, testenv.GoToolPath(t), "test", "-c", "-o", out, gcflag, "."))
+	cmd.Dir = dir
+
+	pr, pw, err := os.Pipe()
+	if err != nil {
+		t.Fatalf("error creating pipe: %v", err)
+	}
+	defer pr.Close()
+	cmd.Stdout = pw
+	cmd.Stderr = pw
+
+	err = cmd.Start()
+	pw.Close()
+	if err != nil {
+		t.Fatalf("error starting go test: %v", err)
+	}
+
+	scanner := bufio.NewScanner(pr)
+	curPkg := ""
+	canInline := regexp.MustCompile(`: can inline ([^ ]*)`)
+	haveInlined := regexp.MustCompile(`: inlining call to ([^ ]*)`)
+	cannotInline := regexp.MustCompile(`: cannot inline ([^ ]*): (.*)`)
+	for scanner.Scan() {
+		line := scanner.Text()
+		t.Logf("child: %s", line)
+		if strings.HasPrefix(line, "# ") {
+			curPkg = line[2:]
+			splits := strings.Split(curPkg, " ")
+			curPkg = splits[0]
+			continue
+		}
+		if m := haveInlined.FindStringSubmatch(line); m != nil {
+			fname := m[1]
+			delete(notInlinedReason, curPkg+"."+fname)
+			continue
+		}
+		if m := canInline.FindStringSubmatch(line); m != nil {
+			fname := m[1]
+			fullname := curPkg + "." + fname
+			// If function must be inlined somewhere, being inlinable is not enough
+			if _, ok := must[fullname]; !ok {
+				delete(notInlinedReason, fullname)
+				continue
+			}
+		}
+		if m := cannotInline.FindStringSubmatch(line); m != nil {
+			fname, reason := m[1], m[2]
+			fullName := curPkg + "." + fname
+			if _, ok := notInlinedReason[fullName]; ok {
+				// cmd/compile gave us a reason why
+				notInlinedReason[fullName] = reason
+			}
+			delete(expectedNotInlinedList, fullName)
+			continue
+		}
+	}
+	if err := cmd.Wait(); err != nil {
+		t.Fatalf("error running go test: %v", err)
+	}
+	if err := scanner.Err(); err != nil {
+		t.Fatalf("error reading go test output: %v", err)
+	}
+	for fullName, reason := range notInlinedReason {
+		t.Errorf("%s was not inlined: %s", fullName, reason)
+	}
+
+	// If the list expectedNotInlinedList is not empty, it indicates
+	// the functions in the expectedNotInlinedList are marked with caninline.
+	for fullName, _ := range expectedNotInlinedList {
+		t.Errorf("%s was expected not inlined", fullName)
+	}
+}
+
+// TestPGOIntendedInlining tests that specific functions are inlined when PGO
+// is applied to the exact source that was profiled.
+func TestPGOIntendedInlining(t *testing.T) {
+	wd, err := os.Getwd()
+	if err != nil {
+		t.Fatalf("error getting wd: %v", err)
+	}
+	srcDir := filepath.Join(wd, "testdata/pgo/inline")
+
+	// Copy the module to a scratch location so we can add a go.mod.
+	dir := t.TempDir()
+
+	for _, file := range []string{"inline_hot.go", "inline_hot_test.go", "inline_hot.pprof"} {
+		if err := copyFile(filepath.Join(dir, file), filepath.Join(srcDir, file)); err != nil {
+			t.Fatalf("error copying %s: %v", file, err)
+		}
+	}
+
+	testPGOIntendedInlining(t, dir)
+}
+
+// TestPGOIntendedInlining tests that specific functions are inlined when PGO
+// is applied to the modified source.
+func TestPGOIntendedInliningShiftedLines(t *testing.T) {
+	wd, err := os.Getwd()
+	if err != nil {
+		t.Fatalf("error getting wd: %v", err)
+	}
+	srcDir := filepath.Join(wd, "testdata/pgo/inline")
+
+	// Copy the module to a scratch location so we can modify the source.
+	dir := t.TempDir()
+
+	// Copy most of the files unmodified.
+	for _, file := range []string{"inline_hot_test.go", "inline_hot.pprof"} {
+		if err := copyFile(filepath.Join(dir, file), filepath.Join(srcDir, file)); err != nil {
+			t.Fatalf("error copying %s : %v", file, err)
+		}
+	}
+
+	// Add some comments to the top of inline_hot.go. This adjusts the line
+	// numbers of all of the functions without changing the semantics.
+	src, err := os.Open(filepath.Join(srcDir, "inline_hot.go"))
+	if err != nil {
+		t.Fatalf("error opening src inline_hot.go: %v", err)
+	}
+	defer src.Close()
+
+	dst, err := os.Create(filepath.Join(dir, "inline_hot.go"))
+	if err != nil {
+		t.Fatalf("error creating dst inline_hot.go: %v", err)
+	}
+	defer dst.Close()
+
+	if _, err := io.WriteString(dst, `// Autogenerated
+// Lines
+`); err != nil {
+		t.Fatalf("error writing comments to dst: %v", err)
+	}
+
+	if _, err := io.Copy(dst, src); err != nil {
+		t.Fatalf("error copying inline_hot.go: %v", err)
+	}
+
+	dst.Close()
+
+	testPGOIntendedInlining(t, dir)
+}
+
+// TestPGOSingleIndex tests that the sample index can not be 1 and compilation
+// will not fail. All it should care about is that the sample type is either
+// CPU nanoseconds or samples count, whichever it finds first.
+func TestPGOSingleIndex(t *testing.T) {
+	for _, tc := range []struct {
+		originalIndex int
+	}{{
+		// The `testdata/pgo/inline/inline_hot.pprof` file is a standard CPU
+		// profile as the runtime would generate. The 0 index contains the
+		// value-type samples and value-unit count. The 1 index contains the
+		// value-type cpu and value-unit nanoseconds. These tests ensure that
+		// the compiler can work with profiles that only have a single index,
+		// but are either samples count or CPU nanoseconds.
+		originalIndex: 0,
+	}, {
+		originalIndex: 1,
+	}} {
+		t.Run(fmt.Sprintf("originalIndex=%d", tc.originalIndex), func(t *testing.T) {
+			wd, err := os.Getwd()
+			if err != nil {
+				t.Fatalf("error getting wd: %v", err)
+			}
+			srcDir := filepath.Join(wd, "testdata/pgo/inline")
+
+			// Copy the module to a scratch location so we can add a go.mod.
+			dir := t.TempDir()
+
+			originalPprofFile, err := os.Open(filepath.Join(srcDir, "inline_hot.pprof"))
+			if err != nil {
+				t.Fatalf("error opening inline_hot.pprof: %v", err)
+			}
+			defer originalPprofFile.Close()
+
+			p, err := profile.Parse(originalPprofFile)
+			if err != nil {
+				t.Fatalf("error parsing inline_hot.pprof: %v", err)
+			}
+
+			// Move the samples count value-type to the 0 index.
+			p.SampleType = []*profile.ValueType{p.SampleType[tc.originalIndex]}
+
+			// Ensure we only have a single set of sample values.
+			for _, s := range p.Sample {
+				s.Value = []int64{s.Value[tc.originalIndex]}
+			}
+
+			modifiedPprofFile, err := os.Create(filepath.Join(dir, "inline_hot.pprof"))
+			if err != nil {
+				t.Fatalf("error creating inline_hot.pprof: %v", err)
+			}
+			defer modifiedPprofFile.Close()
+
+			if err := p.Write(modifiedPprofFile); err != nil {
+				t.Fatalf("error writing inline_hot.pprof: %v", err)
+			}
+
+			for _, file := range []string{"inline_hot.go", "inline_hot_test.go"} {
+				if err := copyFile(filepath.Join(dir, file), filepath.Join(srcDir, file)); err != nil {
+					t.Fatalf("error copying %s: %v", file, err)
+				}
+			}
+
+			testPGOIntendedInlining(t, dir)
+		})
+	}
+}
+
+func copyFile(dst, src string) error {
+	s, err := os.Open(src)
+	if err != nil {
+		return err
+	}
+	defer s.Close()
+
+	d, err := os.Create(dst)
+	if err != nil {
+		return err
+	}
+	defer d.Close()
+
+	_, err = io.Copy(d, s)
+	return err
+}
diff --git a/src/cmd/compile/internal/test/race.go b/src/cmd/compile/internal/test/race.go
new file mode 100644
index 0000000..b721538
--- /dev/null
+++ b/src/cmd/compile/internal/test/race.go
@@ -0,0 +1,64 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !compiler_bootstrap
+
+package test
+
+// The racecompile builder only builds packages, but does not build
+// or run tests. This is a non-test file to hold cases that (used
+// to) trigger compiler data races, so they will be exercised on
+// the racecompile builder.
+//
+// This package is not imported so functions here are not included
+// in the actual compiler.
+
+// Issue 55357: data race when building multiple instantiations of
+// generic closures with _ parameters.
+func Issue55357() {
+	type U struct {
+		A int
+		B string
+		C string
+	}
+	var q T55357[U]
+	q.Count()
+	q.List()
+
+	type M struct {
+		A int64
+		B uint32
+		C uint32
+	}
+	var q2 T55357[M]
+	q2.Count()
+	q2.List()
+}
+
+type T55357[T any] struct{}
+
+//go:noinline
+func (q *T55357[T]) do(w, v bool, fn func(bk []byte, v T) error) error {
+	return nil
+}
+
+func (q *T55357[T]) Count() (n int, rerr error) {
+	err := q.do(false, false, func(kb []byte, _ T) error {
+		n++
+		return nil
+	})
+	return n, err
+}
+
+func (q *T55357[T]) List() (list []T, rerr error) {
+	var l []T
+	err := q.do(false, true, func(_ []byte, v T) error {
+		l = append(l, v)
+		return nil
+	})
+	if err != nil {
+		return nil, err
+	}
+	return l, nil
+}
diff --git a/src/cmd/compile/internal/test/reproduciblebuilds_test.go b/src/cmd/compile/internal/test/reproduciblebuilds_test.go
index 10913ae..a803e74 100644
--- a/src/cmd/compile/internal/test/reproduciblebuilds_test.go
+++ b/src/cmd/compile/internal/test/reproduciblebuilds_test.go
@@ -7,9 +7,7 @@
 import (
 	"bytes"
 	"internal/testenv"
-	"io/ioutil"
 	"os"
-	"os/exec"
 	"path/filepath"
 	"testing"
 )
@@ -32,7 +30,7 @@
 		t.Run(test, func(t *testing.T) {
 			t.Parallel()
 			var want []byte
-			tmp, err := ioutil.TempFile("", "")
+			tmp, err := os.CreateTemp("", "")
 			if err != nil {
 				t.Fatalf("temp file creation failed: %v", err)
 			}
@@ -41,11 +39,11 @@
 			for i := 0; i < iters; i++ {
 				// Note: use -c 2 to expose any nondeterminism which is the result
 				// of the runtime scheduler.
-				out, err := exec.Command(testenv.GoToolPath(t), "tool", "compile", "-p=p", "-c", "2", "-o", tmp.Name(), filepath.Join("testdata", "reproducible", test)).CombinedOutput()
+				out, err := testenv.Command(t, testenv.GoToolPath(t), "tool", "compile", "-p=p", "-c", "2", "-o", tmp.Name(), filepath.Join("testdata", "reproducible", test)).CombinedOutput()
 				if err != nil {
 					t.Fatalf("failed to compile: %v\n%s", err, out)
 				}
-				obj, err := ioutil.ReadFile(tmp.Name())
+				obj, err := os.ReadFile(tmp.Name())
 				if err != nil {
 					t.Fatalf("failed to read object file: %v", err)
 				}
@@ -78,7 +76,7 @@
 		{tag: "serial", args: "-c=1"},
 		{tag: "concurrent", args: "-c=2"}}
 
-	tmpdir, err := ioutil.TempDir("", "TestIssue38068")
+	tmpdir, err := os.MkdirTemp("", "TestIssue38068")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -89,7 +87,7 @@
 		s := &scenarios[i]
 		s.libpath = filepath.Join(tmpdir, s.tag+".a")
 		// Note: use of "-p" required in order for DWARF to be generated.
-		cmd := exec.Command(testenv.GoToolPath(t), "tool", "compile", "-p=issue38068", "-buildid=", s.args, "-o", s.libpath, src)
+		cmd := testenv.Command(t, testenv.GoToolPath(t), "tool", "compile", "-p=issue38068", "-buildid=", s.args, "-o", s.libpath, src)
 		out, err := cmd.CombinedOutput()
 		if err != nil {
 			t.Fatalf("%v: %v:\n%s", cmd.Args, err, out)
@@ -97,7 +95,7 @@
 	}
 
 	readBytes := func(fn string) []byte {
-		payload, err := ioutil.ReadFile(fn)
+		payload, err := os.ReadFile(fn)
 		if err != nil {
 			t.Fatalf("failed to read executable '%s': %v", fn, err)
 		}
diff --git a/src/cmd/compile/internal/test/shift_test.go b/src/cmd/compile/internal/test/shift_test.go
index 58c8dde..278a47d 100644
--- a/src/cmd/compile/internal/test/shift_test.go
+++ b/src/cmd/compile/internal/test/shift_test.go
@@ -1039,3 +1039,25 @@
 	}
 	shiftSink64 = x
 }
+
+//go:noinline
+func incorrectRotate1(x, c uint64) uint64 {
+	// This should not compile to a rotate instruction.
+	return x<<c | x>>(64-c)
+}
+
+//go:noinline
+func incorrectRotate2(x uint64) uint64 {
+	var c uint64 = 66
+	// This should not compile to a rotate instruction.
+	return x<<c | x>>(64-c)
+}
+
+func TestIncorrectRotate(t *testing.T) {
+	if got := incorrectRotate1(1, 66); got != 0 {
+		t.Errorf("got %x want 0", got)
+	}
+	if got := incorrectRotate2(1); got != 0 {
+		t.Errorf("got %x want 0", got)
+	}
+}
diff --git a/src/cmd/compile/internal/test/ssa_test.go b/src/cmd/compile/internal/test/ssa_test.go
index af7d962..0b6a675 100644
--- a/src/cmd/compile/internal/test/ssa_test.go
+++ b/src/cmd/compile/internal/test/ssa_test.go
@@ -11,9 +11,7 @@
 	"go/parser"
 	"go/token"
 	"internal/testenv"
-	"io/ioutil"
 	"os"
-	"os/exec"
 	"path/filepath"
 	"runtime"
 	"strings"
@@ -28,28 +26,28 @@
 	testenv.MustHaveGoRun(t)
 	gotool := testenv.GoToolPath(t)
 	var stdout, stderr bytes.Buffer
-	cmd := exec.Command(gotool, "run", filepath.Join("testdata", filename))
+	cmd := testenv.Command(t, gotool, "run", filepath.Join("testdata", filename))
 	cmd.Stdout = &stdout
 	cmd.Stderr = &stderr
 	if err := cmd.Run(); err != nil {
 		t.Fatalf("Failed: %v:\nOut: %s\nStderr: %s\n", err, &stdout, &stderr)
 	}
 	// Write stdout into a temporary file
-	tmpdir, ok := ioutil.TempDir("", tmpname)
+	tmpdir, ok := os.MkdirTemp("", tmpname)
 	if ok != nil {
 		t.Fatalf("Failed to create temporary directory")
 	}
 	defer os.RemoveAll(tmpdir)
 
 	rungo := filepath.Join(tmpdir, "run.go")
-	ok = ioutil.WriteFile(rungo, stdout.Bytes(), 0600)
+	ok = os.WriteFile(rungo, stdout.Bytes(), 0600)
 	if ok != nil {
 		t.Fatalf("Failed to create temporary file " + rungo)
 	}
 
 	stdout.Reset()
 	stderr.Reset()
-	cmd = exec.Command(gotool, "run", "-gcflags=-d=ssa/check/on", rungo)
+	cmd = testenv.Command(t, gotool, "run", "-gcflags=-d=ssa/check/on", rungo)
 	cmd.Stdout = &stdout
 	cmd.Stderr = &stderr
 	cmd.Env = append(cmd.Env, ev...)
@@ -81,7 +79,7 @@
 	gotool := testenv.GoToolPath(t)
 
 	// Make a temporary directory to work in.
-	tmpdir, err := ioutil.TempDir("", "TestCode")
+	tmpdir, err := os.MkdirTemp("", "TestCode")
 	if err != nil {
 		t.Fatalf("Failed to create temporary directory: %v", err)
 	}
@@ -94,7 +92,7 @@
 		usesFloat bool   // might use float operations
 	}
 	var tests []test
-	files, err := ioutil.ReadDir("testdata")
+	files, err := os.ReadDir("testdata")
 	if err != nil {
 		t.Fatalf("can't read testdata directory: %v", err)
 	}
@@ -102,7 +100,7 @@
 		if !strings.HasSuffix(f.Name(), "_test.go") {
 			continue
 		}
-		text, err := ioutil.ReadFile(filepath.Join("testdata", f.Name()))
+		text, err := os.ReadFile(filepath.Join("testdata", f.Name()))
 		if err != nil {
 			t.Fatalf("can't read testdata/%s: %v", f.Name(), err)
 		}
@@ -168,7 +166,7 @@
 	for _, flag := range flags {
 		args := []string{"test", "-c", "-gcflags=-d=ssa/check/on" + flag, "-o", filepath.Join(tmpdir, "code.test")}
 		args = append(args, srcs...)
-		out, err := exec.Command(gotool, args...).CombinedOutput()
+		out, err := testenv.Command(t, gotool, args...).CombinedOutput()
 		if err != nil || len(out) != 0 {
 			t.Fatalf("Build failed: %v\n%s\n", err, out)
 		}
@@ -181,7 +179,7 @@
 				continue
 			}
 			t.Run(fmt.Sprintf("%s%s", test.name[4:], flag), func(t *testing.T) {
-				out, err := exec.Command(filepath.Join(tmpdir, "code.test"), "-test.run="+test.name).CombinedOutput()
+				out, err := testenv.Command(t, filepath.Join(tmpdir, "code.test"), "-test.run="+test.name).CombinedOutput()
 				if err != nil || string(out) != "PASS\n" {
 					t.Errorf("Failed:\n%s\n", out)
 				}
diff --git a/src/cmd/compile/internal/test/testdata/gen/arithBoundaryGen.go b/src/cmd/compile/internal/test/testdata/gen/arithBoundaryGen.go
index 21ad27e..b03c105 100644
--- a/src/cmd/compile/internal/test/testdata/gen/arithBoundaryGen.go
+++ b/src/cmd/compile/internal/test/testdata/gen/arithBoundaryGen.go
@@ -14,7 +14,6 @@
 	"bytes"
 	"fmt"
 	"go/format"
-	"io/ioutil"
 	"log"
 	"text/template"
 )
@@ -202,7 +201,7 @@
 	}
 
 	// write to file
-	err = ioutil.WriteFile("../arithBoundary_test.go", src, 0666)
+	err = os.WriteFile("../arithBoundary_test.go", src, 0666)
 	if err != nil {
 		log.Fatalf("can't write output: %v\n", err)
 	}
diff --git a/src/cmd/compile/internal/test/testdata/gen/arithConstGen.go b/src/cmd/compile/internal/test/testdata/gen/arithConstGen.go
index 41b2946..1649f46 100644
--- a/src/cmd/compile/internal/test/testdata/gen/arithConstGen.go
+++ b/src/cmd/compile/internal/test/testdata/gen/arithConstGen.go
@@ -14,7 +14,6 @@
 	"bytes"
 	"fmt"
 	"go/format"
-	"io/ioutil"
 	"log"
 	"strings"
 	"text/template"
@@ -339,7 +338,7 @@
 	}
 
 	// write to file
-	err = ioutil.WriteFile("../arithConst_test.go", src, 0666)
+	err = os.WriteFile("../arithConst_test.go", src, 0666)
 	if err != nil {
 		log.Fatalf("can't write output: %v\n", err)
 	}
diff --git a/src/cmd/compile/internal/test/testdata/gen/cmpConstGen.go b/src/cmd/compile/internal/test/testdata/gen/cmpConstGen.go
index 5508e76..dcdafc0 100644
--- a/src/cmd/compile/internal/test/testdata/gen/cmpConstGen.go
+++ b/src/cmd/compile/internal/test/testdata/gen/cmpConstGen.go
@@ -14,7 +14,6 @@
 	"bytes"
 	"fmt"
 	"go/format"
-	"io/ioutil"
 	"log"
 	"math/big"
 	"sort"
@@ -240,7 +239,7 @@
 	}
 
 	// write to file
-	err = ioutil.WriteFile("../cmpConst_test.go", src, 0666)
+	err = os.WriteFile("../cmpConst_test.go", src, 0666)
 	if err != nil {
 		log.Fatalf("can't write output: %v\n", err)
 	}
diff --git a/src/cmd/compile/internal/test/testdata/gen/constFoldGen.go b/src/cmd/compile/internal/test/testdata/gen/constFoldGen.go
index 2b8a331..7079422 100644
--- a/src/cmd/compile/internal/test/testdata/gen/constFoldGen.go
+++ b/src/cmd/compile/internal/test/testdata/gen/constFoldGen.go
@@ -14,8 +14,8 @@
 	"bytes"
 	"fmt"
 	"go/format"
-	"io/ioutil"
 	"log"
+	"os"
 )
 
 type op struct {
@@ -300,7 +300,7 @@
 	}
 
 	// write to file
-	err = ioutil.WriteFile("../../constFold_test.go", src, 0666)
+	err = os.WriteFile("../../constFold_test.go", src, 0666)
 	if err != nil {
 		log.Fatalf("can't write output: %v\n", err)
 	}
diff --git a/src/cmd/compile/internal/test/testdata/gen/copyGen.go b/src/cmd/compile/internal/test/testdata/gen/copyGen.go
index 4567f2f..dd09b3b 100644
--- a/src/cmd/compile/internal/test/testdata/gen/copyGen.go
+++ b/src/cmd/compile/internal/test/testdata/gen/copyGen.go
@@ -8,8 +8,8 @@
 	"bytes"
 	"fmt"
 	"go/format"
-	"io/ioutil"
 	"log"
+	"os"
 )
 
 // This program generates tests to verify that copying operations
@@ -114,7 +114,7 @@
 	}
 
 	// write to file
-	err = ioutil.WriteFile("../copy_test.go", src, 0666)
+	err = os.WriteFile("../copy_test.go", src, 0666)
 	if err != nil {
 		log.Fatalf("can't write output: %v\n", err)
 	}
diff --git a/src/cmd/compile/internal/test/testdata/gen/zeroGen.go b/src/cmd/compile/internal/test/testdata/gen/zeroGen.go
index 7056730..f3dcaa1 100644
--- a/src/cmd/compile/internal/test/testdata/gen/zeroGen.go
+++ b/src/cmd/compile/internal/test/testdata/gen/zeroGen.go
@@ -8,8 +8,8 @@
 	"bytes"
 	"fmt"
 	"go/format"
-	"io/ioutil"
 	"log"
+	"os"
 )
 
 // This program generates tests to verify that zeroing operations
@@ -136,7 +136,7 @@
 	}
 
 	// write to file
-	err = ioutil.WriteFile("../zero_test.go", src, 0666)
+	err = os.WriteFile("../zero_test.go", src, 0666)
 	if err != nil {
 		log.Fatalf("can't write output: %v\n", err)
 	}
diff --git a/src/cmd/compile/internal/test/testdata/pgo/inline/inline_hot.go b/src/cmd/compile/internal/test/testdata/pgo/inline/inline_hot.go
new file mode 100644
index 0000000..9a462fd
--- /dev/null
+++ b/src/cmd/compile/internal/test/testdata/pgo/inline/inline_hot.go
@@ -0,0 +1,90 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// WARNING: Please avoid updating this file. If this file needs to be updated,
+// then a new inline_hot.pprof file should be generated:
+//
+//  $ cd $GOROOT/src/cmd/compile/internal/test/testdata/pgo/inline/
+//  $ go test -bench=. -cpuprofile ./inline_hot.pprof
+package main
+
+import (
+	"time"
+)
+
+type BS struct {
+	length uint
+	s      []uint64
+}
+
+const wSize = uint(64)
+const lWSize = uint(6)
+
+func D(i uint) int {
+	return int((i + (wSize - 1)) >> lWSize)
+}
+
+func N(length uint) (bs *BS) {
+	bs = &BS{
+		length,
+		make([]uint64, D(length)),
+	}
+
+	return bs
+}
+
+func (b *BS) S(i uint) *BS {
+	b.s[i>>lWSize] |= 1 << (i & (wSize - 1))
+	return b
+}
+
+var jn = [...]byte{
+	0, 1, 56, 2, 57, 49, 28, 3, 61, 58, 42, 50, 38, 29, 17, 4,
+	62, 47, 59, 36, 45, 43, 51, 22, 53, 39, 33, 30, 24, 18, 12, 5,
+	63, 55, 48, 27, 60, 41, 37, 16, 46, 35, 44, 21, 52, 32, 23, 11,
+	54, 26, 40, 15, 34, 20, 31, 10, 25, 14, 19, 9, 13, 8, 7, 6,
+}
+
+func T(v uint64) uint {
+	return uint(jn[((v&-v)*0x03f79d71b4ca8b09)>>58])
+}
+
+func (b *BS) NS(i uint) (uint, bool) {
+	x := int(i >> lWSize)
+	if x >= len(b.s) {
+		return 0, false
+	}
+	w := b.s[x]
+	w = w >> (i & (wSize - 1))
+	if w != 0 {
+		return i + T(w), true
+	}
+	x = x + 1
+	for x < len(b.s) {
+		if b.s[x] != 0 {
+			return uint(x)*wSize + T(b.s[x]), true
+		}
+		x = x + 1
+
+	}
+	return 0, false
+}
+
+func A() {
+	s := N(100000)
+	for i := 0; i < 1000; i += 30 {
+		s.S(uint(i))
+	}
+	for j := 0; j < 1000; j++ {
+		c := uint(0)
+		for i, e := s.NS(0); e; i, e = s.NS(i + 1) {
+			c++
+		}
+	}
+}
+
+func main() {
+	time.Sleep(time.Second)
+	A()
+}
diff --git a/src/cmd/compile/internal/test/testdata/pgo/inline/inline_hot.pprof b/src/cmd/compile/internal/test/testdata/pgo/inline/inline_hot.pprof
new file mode 100644
index 0000000..1b55ed1
--- /dev/null
+++ b/src/cmd/compile/internal/test/testdata/pgo/inline/inline_hot.pprof
Binary files differ
diff --git a/src/cmd/compile/internal/test/testdata/pgo/inline/inline_hot_test.go b/src/cmd/compile/internal/test/testdata/pgo/inline/inline_hot_test.go
new file mode 100644
index 0000000..2725c57
--- /dev/null
+++ b/src/cmd/compile/internal/test/testdata/pgo/inline/inline_hot_test.go
@@ -0,0 +1,51 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// WARNING: Please avoid updating this file. If this file needs to be updated,
+// then a new inline_hot.pprof file should be generated:
+//
+//  $ cd $GOROOT/src/cmd/compile/internal/test/testdata/pgo/inline/
+//  $ go test -bench=. -cpuprofile ./inline_hot.pprof
+package main
+
+import "testing"
+
+func BenchmarkA(b *testing.B) {
+	benchmarkB(b)
+}
+func benchmarkB(b *testing.B) {
+
+	for i := 0; true; {
+		A()
+		i = i + 1
+		if i >= b.N {
+			break
+		}
+		A()
+		i = i + 1
+		if i >= b.N {
+			break
+		}
+		A()
+		i = i + 1
+		if i >= b.N {
+			break
+		}
+		A()
+		i = i + 1
+		if i >= b.N {
+			break
+		}
+		A()
+		i = i + 1
+		if i >= b.N {
+			break
+		}
+		A()
+		i = i + 1
+		if i >= b.N {
+			break
+		}
+	}
+}
diff --git a/src/cmd/compile/internal/typebits/typebits.go b/src/cmd/compile/internal/typebits/typebits.go
index fddad6e..b533212 100644
--- a/src/cmd/compile/internal/typebits/typebits.go
+++ b/src/cmd/compile/internal/typebits/typebits.go
@@ -14,11 +14,20 @@
 // the first run and then simply copied into bv at the correct offset
 // on future calls with the same type t.
 func Set(t *types.Type, off int64, bv bitvec.BitVec) {
-	if uint8(t.Alignment()) > 0 && off&int64(uint8(t.Alignment())-1) != 0 {
+	set(t, off, bv, false)
+}
+
+// SetNoCheck is like Set, but do not check for alignment.
+func SetNoCheck(t *types.Type, off int64, bv bitvec.BitVec) {
+	set(t, off, bv, true)
+}
+
+func set(t *types.Type, off int64, bv bitvec.BitVec, skip bool) {
+	if !skip && uint8(t.Alignment()) > 0 && off&int64(uint8(t.Alignment())-1) != 0 {
 		base.Fatalf("typebits.Set: invalid initial alignment: type %v has alignment %d, but offset is %v", t, uint8(t.Alignment()), off)
 	}
 	if !t.HasPointers() {
-		// Note: this case ensures that pointers to go:notinheap types
+		// Note: this case ensures that pointers to not-in-heap types
 		// are not considered pointers by garbage collection and stack copying.
 		return
 	}
@@ -72,13 +81,13 @@
 			break
 		}
 		for i := int64(0); i < t.NumElem(); i++ {
-			Set(elt, off, bv)
+			set(elt, off, bv, skip)
 			off += elt.Size()
 		}
 
 	case types.TSTRUCT:
 		for _, f := range t.Fields().Slice() {
-			Set(f.Type, off+f.Offset, bv)
+			set(f.Type, off+f.Offset, bv, skip)
 		}
 
 	default:
diff --git a/src/cmd/compile/internal/typecheck/_builtin/coverage.go b/src/cmd/compile/internal/typecheck/_builtin/coverage.go
new file mode 100644
index 0000000..ea4462d
--- /dev/null
+++ b/src/cmd/compile/internal/typecheck/_builtin/coverage.go
@@ -0,0 +1,14 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// NOTE: If you change this file you must run "go generate"
+// to update builtin.go. This is not done automatically
+// to avoid depending on having a working compiler binary.
+
+//go:build ignore
+// +build ignore
+
+package coverage
+
+func initHook(istest bool)
diff --git a/src/cmd/compile/internal/typecheck/_builtin/runtime.go b/src/cmd/compile/internal/typecheck/_builtin/runtime.go
new file mode 100644
index 0000000..69c456a
--- /dev/null
+++ b/src/cmd/compile/internal/typecheck/_builtin/runtime.go
@@ -0,0 +1,282 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// NOTE: If you change this file you must run "go generate"
+// to update builtin.go. This is not done automatically
+// to avoid depending on having a working compiler binary.
+
+//go:build ignore
+
+package runtime
+
+// emitted by compiler, not referred to by go programs
+
+import "unsafe"
+
+func newobject(typ *byte) *any
+func mallocgc(size uintptr, typ *byte, needszero bool) unsafe.Pointer
+func panicdivide()
+func panicshift()
+func panicmakeslicelen()
+func panicmakeslicecap()
+func throwinit()
+func panicwrap()
+
+func gopanic(interface{})
+func gorecover(*int32) interface{}
+func goschedguarded()
+
+// Note: these declarations are just for wasm port.
+// Other ports call assembly stubs instead.
+func goPanicIndex(x int, y int)
+func goPanicIndexU(x uint, y int)
+func goPanicSliceAlen(x int, y int)
+func goPanicSliceAlenU(x uint, y int)
+func goPanicSliceAcap(x int, y int)
+func goPanicSliceAcapU(x uint, y int)
+func goPanicSliceB(x int, y int)
+func goPanicSliceBU(x uint, y int)
+func goPanicSlice3Alen(x int, y int)
+func goPanicSlice3AlenU(x uint, y int)
+func goPanicSlice3Acap(x int, y int)
+func goPanicSlice3AcapU(x uint, y int)
+func goPanicSlice3B(x int, y int)
+func goPanicSlice3BU(x uint, y int)
+func goPanicSlice3C(x int, y int)
+func goPanicSlice3CU(x uint, y int)
+func goPanicSliceConvert(x int, y int)
+
+func printbool(bool)
+func printfloat(float64)
+func printint(int64)
+func printhex(uint64)
+func printuint(uint64)
+func printcomplex(complex128)
+func printstring(string)
+func printpointer(any)
+func printuintptr(uintptr)
+func printiface(any)
+func printeface(any)
+func printslice(any)
+func printnl()
+func printsp()
+func printlock()
+func printunlock()
+
+func concatstring2(*[32]byte, string, string) string
+func concatstring3(*[32]byte, string, string, string) string
+func concatstring4(*[32]byte, string, string, string, string) string
+func concatstring5(*[32]byte, string, string, string, string, string) string
+func concatstrings(*[32]byte, []string) string
+
+func cmpstring(string, string) int
+func intstring(*[4]byte, int64) string
+func slicebytetostring(buf *[32]byte, ptr *byte, n int) string
+func slicebytetostringtmp(ptr *byte, n int) string
+func slicerunetostring(*[32]byte, []rune) string
+func stringtoslicebyte(*[32]byte, string) []byte
+func stringtoslicerune(*[32]rune, string) []rune
+func slicecopy(toPtr *any, toLen int, fromPtr *any, fromLen int, wid uintptr) int
+
+func decoderune(string, int) (retv rune, retk int)
+func countrunes(string) int
+
+// Non-empty-interface to non-empty-interface conversion.
+func convI2I(typ *byte, itab *uintptr) (ret *uintptr)
+
+// Convert non-interface type to the data word of a (empty or nonempty) interface.
+func convT(typ *byte, elem *any) unsafe.Pointer
+
+// Same as convT, for types with no pointers in them.
+func convTnoptr(typ *byte, elem *any) unsafe.Pointer
+
+// Specialized versions of convT for specific types.
+// These functions take concrete types in the runtime. But they may
+// be used for a wider range of types, which have the same memory
+// layout as the parameter type. The compiler converts the
+// to-be-converted type to the parameter type before calling the
+// runtime function. This way, the call is ABI-insensitive.
+func convT16(val uint16) unsafe.Pointer
+func convT32(val uint32) unsafe.Pointer
+func convT64(val uint64) unsafe.Pointer
+func convTstring(val string) unsafe.Pointer
+func convTslice(val []uint8) unsafe.Pointer
+
+// interface type assertions x.(T)
+func assertE2I(inter *byte, typ *byte) *byte
+func assertE2I2(inter *byte, eface any) (ret any)
+func assertI2I(inter *byte, tab *byte) *byte
+func assertI2I2(inter *byte, iface any) (ret any)
+func panicdottypeE(have, want, iface *byte)
+func panicdottypeI(have, want, iface *byte)
+func panicnildottype(want *byte)
+
+// interface equality. Type/itab pointers are already known to be equal, so
+// we only need to pass one.
+func ifaceeq(tab *uintptr, x, y unsafe.Pointer) (ret bool)
+func efaceeq(typ *uintptr, x, y unsafe.Pointer) (ret bool)
+
+func fastrand() uint32
+
+// *byte is really *runtime.Type
+func makemap64(mapType *byte, hint int64, mapbuf *any) (hmap map[any]any)
+func makemap(mapType *byte, hint int, mapbuf *any) (hmap map[any]any)
+func makemap_small() (hmap map[any]any)
+func mapaccess1(mapType *byte, hmap map[any]any, key *any) (val *any)
+func mapaccess1_fast32(mapType *byte, hmap map[any]any, key uint32) (val *any)
+func mapaccess1_fast64(mapType *byte, hmap map[any]any, key uint64) (val *any)
+func mapaccess1_faststr(mapType *byte, hmap map[any]any, key string) (val *any)
+func mapaccess1_fat(mapType *byte, hmap map[any]any, key *any, zero *byte) (val *any)
+func mapaccess2(mapType *byte, hmap map[any]any, key *any) (val *any, pres bool)
+func mapaccess2_fast32(mapType *byte, hmap map[any]any, key uint32) (val *any, pres bool)
+func mapaccess2_fast64(mapType *byte, hmap map[any]any, key uint64) (val *any, pres bool)
+func mapaccess2_faststr(mapType *byte, hmap map[any]any, key string) (val *any, pres bool)
+func mapaccess2_fat(mapType *byte, hmap map[any]any, key *any, zero *byte) (val *any, pres bool)
+func mapassign(mapType *byte, hmap map[any]any, key *any) (val *any)
+func mapassign_fast32(mapType *byte, hmap map[any]any, key uint32) (val *any)
+func mapassign_fast32ptr(mapType *byte, hmap map[any]any, key unsafe.Pointer) (val *any)
+func mapassign_fast64(mapType *byte, hmap map[any]any, key uint64) (val *any)
+func mapassign_fast64ptr(mapType *byte, hmap map[any]any, key unsafe.Pointer) (val *any)
+func mapassign_faststr(mapType *byte, hmap map[any]any, key string) (val *any)
+func mapiterinit(mapType *byte, hmap map[any]any, hiter *any)
+func mapdelete(mapType *byte, hmap map[any]any, key *any)
+func mapdelete_fast32(mapType *byte, hmap map[any]any, key uint32)
+func mapdelete_fast64(mapType *byte, hmap map[any]any, key uint64)
+func mapdelete_faststr(mapType *byte, hmap map[any]any, key string)
+func mapiternext(hiter *any)
+func mapclear(mapType *byte, hmap map[any]any)
+
+// *byte is really *runtime.Type
+func makechan64(chanType *byte, size int64) (hchan chan any)
+func makechan(chanType *byte, size int) (hchan chan any)
+func chanrecv1(hchan <-chan any, elem *any)
+func chanrecv2(hchan <-chan any, elem *any) bool
+func chansend1(hchan chan<- any, elem *any)
+func closechan(hchan any)
+
+var writeBarrier struct {
+	enabled bool
+	pad     [3]byte
+	needed  bool
+	cgo     bool
+	alignme uint64
+}
+
+// *byte is really *runtime.Type
+func typedmemmove(typ *byte, dst *any, src *any)
+func typedmemclr(typ *byte, dst *any)
+func typedslicecopy(typ *byte, dstPtr *any, dstLen int, srcPtr *any, srcLen int) int
+
+func selectnbsend(hchan chan<- any, elem *any) bool
+func selectnbrecv(elem *any, hchan <-chan any) (bool, bool)
+
+func selectsetpc(pc *uintptr)
+func selectgo(cas0 *byte, order0 *byte, pc0 *uintptr, nsends int, nrecvs int, block bool) (int, bool)
+func block()
+
+func makeslice(typ *byte, len int, cap int) unsafe.Pointer
+func makeslice64(typ *byte, len int64, cap int64) unsafe.Pointer
+func makeslicecopy(typ *byte, tolen int, fromlen int, from unsafe.Pointer) unsafe.Pointer
+func growslice(oldPtr *any, newLen, oldCap, num int, et *byte) (ary []any)
+func unsafeslicecheckptr(typ *byte, ptr unsafe.Pointer, len int64)
+func panicunsafeslicelen()
+func panicunsafeslicenilptr()
+func unsafestringcheckptr(ptr unsafe.Pointer, len int64)
+func panicunsafestringlen()
+func panicunsafestringnilptr()
+
+func mulUintptr(x, y uintptr) (uintptr, bool)
+
+func memmove(to *any, frm *any, length uintptr)
+func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr)
+func memclrHasPointers(ptr unsafe.Pointer, n uintptr)
+
+func memequal(x, y *any, size uintptr) bool
+func memequal0(x, y *any) bool
+func memequal8(x, y *any) bool
+func memequal16(x, y *any) bool
+func memequal32(x, y *any) bool
+func memequal64(x, y *any) bool
+func memequal128(x, y *any) bool
+func f32equal(p, q unsafe.Pointer) bool
+func f64equal(p, q unsafe.Pointer) bool
+func c64equal(p, q unsafe.Pointer) bool
+func c128equal(p, q unsafe.Pointer) bool
+func strequal(p, q unsafe.Pointer) bool
+func interequal(p, q unsafe.Pointer) bool
+func nilinterequal(p, q unsafe.Pointer) bool
+
+func memhash(p unsafe.Pointer, h uintptr, size uintptr) uintptr
+func memhash0(p unsafe.Pointer, h uintptr) uintptr
+func memhash8(p unsafe.Pointer, h uintptr) uintptr
+func memhash16(p unsafe.Pointer, h uintptr) uintptr
+func memhash32(p unsafe.Pointer, h uintptr) uintptr
+func memhash64(p unsafe.Pointer, h uintptr) uintptr
+func memhash128(p unsafe.Pointer, h uintptr) uintptr
+func f32hash(p unsafe.Pointer, h uintptr) uintptr
+func f64hash(p unsafe.Pointer, h uintptr) uintptr
+func c64hash(p unsafe.Pointer, h uintptr) uintptr
+func c128hash(p unsafe.Pointer, h uintptr) uintptr
+func strhash(a unsafe.Pointer, h uintptr) uintptr
+func interhash(p unsafe.Pointer, h uintptr) uintptr
+func nilinterhash(p unsafe.Pointer, h uintptr) uintptr
+
+// only used on 32-bit
+func int64div(int64, int64) int64
+func uint64div(uint64, uint64) uint64
+func int64mod(int64, int64) int64
+func uint64mod(uint64, uint64) uint64
+func float64toint64(float64) int64
+func float64touint64(float64) uint64
+func float64touint32(float64) uint32
+func int64tofloat64(int64) float64
+func int64tofloat32(int64) float32
+func uint64tofloat64(uint64) float64
+func uint64tofloat32(uint64) float32
+func uint32tofloat64(uint32) float64
+
+func complex128div(num complex128, den complex128) (quo complex128)
+
+func getcallerpc() uintptr
+func getcallersp() uintptr
+
+// race detection
+func racefuncenter(uintptr)
+func racefuncexit()
+func raceread(uintptr)
+func racewrite(uintptr)
+func racereadrange(addr, size uintptr)
+func racewriterange(addr, size uintptr)
+
+// memory sanitizer
+func msanread(addr, size uintptr)
+func msanwrite(addr, size uintptr)
+func msanmove(dst, src, size uintptr)
+
+// address sanitizer
+func asanread(addr, size uintptr)
+func asanwrite(addr, size uintptr)
+
+func checkptrAlignment(unsafe.Pointer, *byte, uintptr)
+func checkptrArithmetic(unsafe.Pointer, []unsafe.Pointer)
+
+func libfuzzerTraceCmp1(uint8, uint8, uint)
+func libfuzzerTraceCmp2(uint16, uint16, uint)
+func libfuzzerTraceCmp4(uint32, uint32, uint)
+func libfuzzerTraceCmp8(uint64, uint64, uint)
+func libfuzzerTraceConstCmp1(uint8, uint8, uint)
+func libfuzzerTraceConstCmp2(uint16, uint16, uint)
+func libfuzzerTraceConstCmp4(uint32, uint32, uint)
+func libfuzzerTraceConstCmp8(uint64, uint64, uint)
+func libfuzzerHookStrCmp(string, string, uint)
+func libfuzzerHookEqualFold(string, string, uint)
+
+func addCovMeta(p unsafe.Pointer, len uint32, hash [16]byte, pkpath string, pkgId int, cmode uint8, cgran uint8) uint32
+
+// architecture variants
+var x86HasPOPCNT bool
+var x86HasSSE41 bool
+var x86HasFMA bool
+var armHasVFPv4 bool
+var arm64HasATOMICS bool
diff --git a/src/cmd/compile/internal/typecheck/builtin.go b/src/cmd/compile/internal/typecheck/builtin.go
index b2c8b57..7de24ad 100644
--- a/src/cmd/compile/internal/typecheck/builtin.go
+++ b/src/cmd/compile/internal/typecheck/builtin.go
@@ -7,6 +7,21 @@
 	"cmd/internal/src"
 )
 
+// Not inlining this function removes a significant chunk of init code.
+//
+//go:noinline
+func newSig(params, results []*types.Field) *types.Type {
+	return types.NewSignature(types.NoPkg, nil, nil, params, results)
+}
+
+func params(tlist ...*types.Type) []*types.Field {
+	flist := make([]*types.Field, len(tlist))
+	for i, typ := range tlist {
+		flist[i] = types.NewField(src.NoXPos, nil, typ)
+	}
+	return flist
+}
+
 var runtimeDecls = [...]struct {
 	name string
 	tag  int
@@ -137,76 +152,80 @@
 	{"unsafeslicecheckptr", funcTag, 118},
 	{"panicunsafeslicelen", funcTag, 9},
 	{"panicunsafeslicenilptr", funcTag, 9},
-	{"mulUintptr", funcTag, 119},
-	{"memmove", funcTag, 120},
-	{"memclrNoHeapPointers", funcTag, 121},
-	{"memclrHasPointers", funcTag, 121},
-	{"memequal", funcTag, 122},
-	{"memequal0", funcTag, 123},
-	{"memequal8", funcTag, 123},
-	{"memequal16", funcTag, 123},
-	{"memequal32", funcTag, 123},
-	{"memequal64", funcTag, 123},
-	{"memequal128", funcTag, 123},
-	{"f32equal", funcTag, 124},
-	{"f64equal", funcTag, 124},
-	{"c64equal", funcTag, 124},
-	{"c128equal", funcTag, 124},
-	{"strequal", funcTag, 124},
-	{"interequal", funcTag, 124},
-	{"nilinterequal", funcTag, 124},
-	{"memhash", funcTag, 125},
-	{"memhash0", funcTag, 126},
-	{"memhash8", funcTag, 126},
-	{"memhash16", funcTag, 126},
-	{"memhash32", funcTag, 126},
-	{"memhash64", funcTag, 126},
-	{"memhash128", funcTag, 126},
-	{"f32hash", funcTag, 126},
-	{"f64hash", funcTag, 126},
-	{"c64hash", funcTag, 126},
-	{"c128hash", funcTag, 126},
-	{"strhash", funcTag, 126},
-	{"interhash", funcTag, 126},
-	{"nilinterhash", funcTag, 126},
-	{"int64div", funcTag, 127},
-	{"uint64div", funcTag, 128},
-	{"int64mod", funcTag, 127},
-	{"uint64mod", funcTag, 128},
-	{"float64toint64", funcTag, 129},
-	{"float64touint64", funcTag, 130},
-	{"float64touint32", funcTag, 131},
-	{"int64tofloat64", funcTag, 132},
-	{"int64tofloat32", funcTag, 134},
-	{"uint64tofloat64", funcTag, 135},
-	{"uint64tofloat32", funcTag, 136},
-	{"uint32tofloat64", funcTag, 137},
-	{"complex128div", funcTag, 138},
-	{"getcallerpc", funcTag, 139},
-	{"getcallersp", funcTag, 139},
+	{"unsafestringcheckptr", funcTag, 119},
+	{"panicunsafestringlen", funcTag, 9},
+	{"panicunsafestringnilptr", funcTag, 9},
+	{"mulUintptr", funcTag, 120},
+	{"memmove", funcTag, 121},
+	{"memclrNoHeapPointers", funcTag, 122},
+	{"memclrHasPointers", funcTag, 122},
+	{"memequal", funcTag, 123},
+	{"memequal0", funcTag, 124},
+	{"memequal8", funcTag, 124},
+	{"memequal16", funcTag, 124},
+	{"memequal32", funcTag, 124},
+	{"memequal64", funcTag, 124},
+	{"memequal128", funcTag, 124},
+	{"f32equal", funcTag, 125},
+	{"f64equal", funcTag, 125},
+	{"c64equal", funcTag, 125},
+	{"c128equal", funcTag, 125},
+	{"strequal", funcTag, 125},
+	{"interequal", funcTag, 125},
+	{"nilinterequal", funcTag, 125},
+	{"memhash", funcTag, 126},
+	{"memhash0", funcTag, 127},
+	{"memhash8", funcTag, 127},
+	{"memhash16", funcTag, 127},
+	{"memhash32", funcTag, 127},
+	{"memhash64", funcTag, 127},
+	{"memhash128", funcTag, 127},
+	{"f32hash", funcTag, 127},
+	{"f64hash", funcTag, 127},
+	{"c64hash", funcTag, 127},
+	{"c128hash", funcTag, 127},
+	{"strhash", funcTag, 127},
+	{"interhash", funcTag, 127},
+	{"nilinterhash", funcTag, 127},
+	{"int64div", funcTag, 128},
+	{"uint64div", funcTag, 129},
+	{"int64mod", funcTag, 128},
+	{"uint64mod", funcTag, 129},
+	{"float64toint64", funcTag, 130},
+	{"float64touint64", funcTag, 131},
+	{"float64touint32", funcTag, 132},
+	{"int64tofloat64", funcTag, 133},
+	{"int64tofloat32", funcTag, 135},
+	{"uint64tofloat64", funcTag, 136},
+	{"uint64tofloat32", funcTag, 137},
+	{"uint32tofloat64", funcTag, 138},
+	{"complex128div", funcTag, 139},
+	{"getcallerpc", funcTag, 140},
+	{"getcallersp", funcTag, 140},
 	{"racefuncenter", funcTag, 31},
 	{"racefuncexit", funcTag, 9},
 	{"raceread", funcTag, 31},
 	{"racewrite", funcTag, 31},
-	{"racereadrange", funcTag, 140},
-	{"racewriterange", funcTag, 140},
-	{"msanread", funcTag, 140},
-	{"msanwrite", funcTag, 140},
-	{"msanmove", funcTag, 141},
-	{"asanread", funcTag, 140},
-	{"asanwrite", funcTag, 140},
-	{"checkptrAlignment", funcTag, 142},
-	{"checkptrArithmetic", funcTag, 144},
-	{"libfuzzerTraceCmp1", funcTag, 145},
-	{"libfuzzerTraceCmp2", funcTag, 146},
-	{"libfuzzerTraceCmp4", funcTag, 147},
-	{"libfuzzerTraceCmp8", funcTag, 148},
-	{"libfuzzerTraceConstCmp1", funcTag, 145},
-	{"libfuzzerTraceConstCmp2", funcTag, 146},
-	{"libfuzzerTraceConstCmp4", funcTag, 147},
-	{"libfuzzerTraceConstCmp8", funcTag, 148},
-	{"libfuzzerHookStrCmp", funcTag, 149},
-	{"libfuzzerHookEqualFold", funcTag, 149},
+	{"racereadrange", funcTag, 141},
+	{"racewriterange", funcTag, 141},
+	{"msanread", funcTag, 141},
+	{"msanwrite", funcTag, 141},
+	{"msanmove", funcTag, 142},
+	{"asanread", funcTag, 141},
+	{"asanwrite", funcTag, 141},
+	{"checkptrAlignment", funcTag, 143},
+	{"checkptrArithmetic", funcTag, 145},
+	{"libfuzzerTraceCmp1", funcTag, 146},
+	{"libfuzzerTraceCmp2", funcTag, 147},
+	{"libfuzzerTraceCmp4", funcTag, 148},
+	{"libfuzzerTraceCmp8", funcTag, 149},
+	{"libfuzzerTraceConstCmp1", funcTag, 146},
+	{"libfuzzerTraceConstCmp2", funcTag, 147},
+	{"libfuzzerTraceConstCmp4", funcTag, 148},
+	{"libfuzzerTraceConstCmp8", funcTag, 149},
+	{"libfuzzerHookStrCmp", funcTag, 150},
+	{"libfuzzerHookEqualFold", funcTag, 150},
+	{"addCovMeta", funcTag, 152},
 	{"x86HasPOPCNT", varTag, 6},
 	{"x86HasSSE41", varTag, 6},
 	{"x86HasFMA", varTag, 6},
@@ -214,23 +233,8 @@
 	{"arm64HasATOMICS", varTag, 6},
 }
 
-// Not inlining this function removes a significant chunk of init code.
-//
-//go:noinline
-func newSig(params, results []*types.Field) *types.Type {
-	return types.NewSignature(types.NoPkg, nil, nil, params, results)
-}
-
-func params(tlist ...*types.Type) []*types.Field {
-	flist := make([]*types.Field, len(tlist))
-	for i, typ := range tlist {
-		flist[i] = types.NewField(src.NoXPos, nil, typ)
-	}
-	return flist
-}
-
 func runtimeTypes() []*types.Type {
-	var typs [150]*types.Type
+	var typs [153]*types.Type
 	typs[0] = types.ByteType
 	typs[1] = types.NewPtr(typs[0])
 	typs[2] = types.Types[types.TANY]
@@ -348,38 +352,56 @@
 	typs[114] = newSig(params(typs[1], typs[22], typs[22]), params(typs[7]))
 	typs[115] = newSig(params(typs[1], typs[15], typs[15], typs[7]), params(typs[7]))
 	typs[116] = types.NewSlice(typs[2])
-	typs[117] = newSig(params(typs[1], typs[116], typs[15]), params(typs[116]))
+	typs[117] = newSig(params(typs[3], typs[15], typs[15], typs[15], typs[1]), params(typs[116]))
 	typs[118] = newSig(params(typs[1], typs[7], typs[22]), nil)
-	typs[119] = newSig(params(typs[5], typs[5]), params(typs[5], typs[6]))
-	typs[120] = newSig(params(typs[3], typs[3], typs[5]), nil)
-	typs[121] = newSig(params(typs[7], typs[5]), nil)
-	typs[122] = newSig(params(typs[3], typs[3], typs[5]), params(typs[6]))
-	typs[123] = newSig(params(typs[3], typs[3]), params(typs[6]))
-	typs[124] = newSig(params(typs[7], typs[7]), params(typs[6]))
-	typs[125] = newSig(params(typs[7], typs[5], typs[5]), params(typs[5]))
-	typs[126] = newSig(params(typs[7], typs[5]), params(typs[5]))
-	typs[127] = newSig(params(typs[22], typs[22]), params(typs[22]))
-	typs[128] = newSig(params(typs[24], typs[24]), params(typs[24]))
-	typs[129] = newSig(params(typs[20]), params(typs[22]))
-	typs[130] = newSig(params(typs[20]), params(typs[24]))
-	typs[131] = newSig(params(typs[20]), params(typs[62]))
-	typs[132] = newSig(params(typs[22]), params(typs[20]))
-	typs[133] = types.Types[types.TFLOAT32]
-	typs[134] = newSig(params(typs[22]), params(typs[133]))
-	typs[135] = newSig(params(typs[24]), params(typs[20]))
-	typs[136] = newSig(params(typs[24]), params(typs[133]))
-	typs[137] = newSig(params(typs[62]), params(typs[20]))
-	typs[138] = newSig(params(typs[26], typs[26]), params(typs[26]))
-	typs[139] = newSig(nil, params(typs[5]))
-	typs[140] = newSig(params(typs[5], typs[5]), nil)
-	typs[141] = newSig(params(typs[5], typs[5], typs[5]), nil)
-	typs[142] = newSig(params(typs[7], typs[1], typs[5]), nil)
-	typs[143] = types.NewSlice(typs[7])
-	typs[144] = newSig(params(typs[7], typs[143]), nil)
-	typs[145] = newSig(params(typs[66], typs[66], typs[15]), nil)
-	typs[146] = newSig(params(typs[60], typs[60], typs[15]), nil)
-	typs[147] = newSig(params(typs[62], typs[62], typs[15]), nil)
-	typs[148] = newSig(params(typs[24], typs[24], typs[15]), nil)
-	typs[149] = newSig(params(typs[28], typs[28], typs[15]), nil)
+	typs[119] = newSig(params(typs[7], typs[22]), nil)
+	typs[120] = newSig(params(typs[5], typs[5]), params(typs[5], typs[6]))
+	typs[121] = newSig(params(typs[3], typs[3], typs[5]), nil)
+	typs[122] = newSig(params(typs[7], typs[5]), nil)
+	typs[123] = newSig(params(typs[3], typs[3], typs[5]), params(typs[6]))
+	typs[124] = newSig(params(typs[3], typs[3]), params(typs[6]))
+	typs[125] = newSig(params(typs[7], typs[7]), params(typs[6]))
+	typs[126] = newSig(params(typs[7], typs[5], typs[5]), params(typs[5]))
+	typs[127] = newSig(params(typs[7], typs[5]), params(typs[5]))
+	typs[128] = newSig(params(typs[22], typs[22]), params(typs[22]))
+	typs[129] = newSig(params(typs[24], typs[24]), params(typs[24]))
+	typs[130] = newSig(params(typs[20]), params(typs[22]))
+	typs[131] = newSig(params(typs[20]), params(typs[24]))
+	typs[132] = newSig(params(typs[20]), params(typs[62]))
+	typs[133] = newSig(params(typs[22]), params(typs[20]))
+	typs[134] = types.Types[types.TFLOAT32]
+	typs[135] = newSig(params(typs[22]), params(typs[134]))
+	typs[136] = newSig(params(typs[24]), params(typs[20]))
+	typs[137] = newSig(params(typs[24]), params(typs[134]))
+	typs[138] = newSig(params(typs[62]), params(typs[20]))
+	typs[139] = newSig(params(typs[26], typs[26]), params(typs[26]))
+	typs[140] = newSig(nil, params(typs[5]))
+	typs[141] = newSig(params(typs[5], typs[5]), nil)
+	typs[142] = newSig(params(typs[5], typs[5], typs[5]), nil)
+	typs[143] = newSig(params(typs[7], typs[1], typs[5]), nil)
+	typs[144] = types.NewSlice(typs[7])
+	typs[145] = newSig(params(typs[7], typs[144]), nil)
+	typs[146] = newSig(params(typs[66], typs[66], typs[17]), nil)
+	typs[147] = newSig(params(typs[60], typs[60], typs[17]), nil)
+	typs[148] = newSig(params(typs[62], typs[62], typs[17]), nil)
+	typs[149] = newSig(params(typs[24], typs[24], typs[17]), nil)
+	typs[150] = newSig(params(typs[28], typs[28], typs[17]), nil)
+	typs[151] = types.NewArray(typs[0], 16)
+	typs[152] = newSig(params(typs[7], typs[62], typs[151], typs[28], typs[15], typs[66], typs[66]), params(typs[62]))
+	return typs[:]
+}
+
+var coverageDecls = [...]struct {
+	name string
+	tag  int
+	typ  int
+}{
+	{"initHook", funcTag, 1},
+}
+
+func coverageTypes() []*types.Type {
+	var typs [2]*types.Type
+	typs[0] = types.Types[types.TBOOL]
+	typs[1] = newSig(params(typs[0]), nil)
 	return typs[:]
 }
diff --git a/src/cmd/compile/internal/typecheck/builtin/runtime.go b/src/cmd/compile/internal/typecheck/builtin/runtime.go
deleted file mode 100644
index 2a07ea1..0000000
--- a/src/cmd/compile/internal/typecheck/builtin/runtime.go
+++ /dev/null
@@ -1,278 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// NOTE: If you change this file you must run "go generate"
-// to update builtin.go. This is not done automatically
-// to avoid depending on having a working compiler binary.
-
-//go:build ignore
-// +build ignore
-
-package runtime
-
-// emitted by compiler, not referred to by go programs
-
-import "unsafe"
-
-func newobject(typ *byte) *any
-func mallocgc(size uintptr, typ *byte, needszero bool) unsafe.Pointer
-func panicdivide()
-func panicshift()
-func panicmakeslicelen()
-func panicmakeslicecap()
-func throwinit()
-func panicwrap()
-
-func gopanic(interface{})
-func gorecover(*int32) interface{}
-func goschedguarded()
-
-// Note: these declarations are just for wasm port.
-// Other ports call assembly stubs instead.
-func goPanicIndex(x int, y int)
-func goPanicIndexU(x uint, y int)
-func goPanicSliceAlen(x int, y int)
-func goPanicSliceAlenU(x uint, y int)
-func goPanicSliceAcap(x int, y int)
-func goPanicSliceAcapU(x uint, y int)
-func goPanicSliceB(x int, y int)
-func goPanicSliceBU(x uint, y int)
-func goPanicSlice3Alen(x int, y int)
-func goPanicSlice3AlenU(x uint, y int)
-func goPanicSlice3Acap(x int, y int)
-func goPanicSlice3AcapU(x uint, y int)
-func goPanicSlice3B(x int, y int)
-func goPanicSlice3BU(x uint, y int)
-func goPanicSlice3C(x int, y int)
-func goPanicSlice3CU(x uint, y int)
-func goPanicSliceConvert(x int, y int)
-
-func printbool(bool)
-func printfloat(float64)
-func printint(int64)
-func printhex(uint64)
-func printuint(uint64)
-func printcomplex(complex128)
-func printstring(string)
-func printpointer(any)
-func printuintptr(uintptr)
-func printiface(any)
-func printeface(any)
-func printslice(any)
-func printnl()
-func printsp()
-func printlock()
-func printunlock()
-
-func concatstring2(*[32]byte, string, string) string
-func concatstring3(*[32]byte, string, string, string) string
-func concatstring4(*[32]byte, string, string, string, string) string
-func concatstring5(*[32]byte, string, string, string, string, string) string
-func concatstrings(*[32]byte, []string) string
-
-func cmpstring(string, string) int
-func intstring(*[4]byte, int64) string
-func slicebytetostring(buf *[32]byte, ptr *byte, n int) string
-func slicebytetostringtmp(ptr *byte, n int) string
-func slicerunetostring(*[32]byte, []rune) string
-func stringtoslicebyte(*[32]byte, string) []byte
-func stringtoslicerune(*[32]rune, string) []rune
-func slicecopy(toPtr *any, toLen int, fromPtr *any, fromLen int, wid uintptr) int
-
-func decoderune(string, int) (retv rune, retk int)
-func countrunes(string) int
-
-// Non-empty-interface to non-empty-interface conversion.
-func convI2I(typ *byte, itab *uintptr) (ret *uintptr)
-
-// Convert non-interface type to the data word of a (empty or nonempty) interface.
-func convT(typ *byte, elem *any) unsafe.Pointer
-
-// Same as convT, for types with no pointers in them.
-func convTnoptr(typ *byte, elem *any) unsafe.Pointer
-
-// Specialized versions of convT for specific types.
-// These functions take concrete types in the runtime. But they may
-// be used for a wider range of types, which have the same memory
-// layout as the parameter type. The compiler converts the
-// to-be-converted type to the parameter type before calling the
-// runtime function. This way, the call is ABI-insensitive.
-func convT16(val uint16) unsafe.Pointer
-func convT32(val uint32) unsafe.Pointer
-func convT64(val uint64) unsafe.Pointer
-func convTstring(val string) unsafe.Pointer
-func convTslice(val []uint8) unsafe.Pointer
-
-// interface type assertions x.(T)
-func assertE2I(inter *byte, typ *byte) *byte
-func assertE2I2(inter *byte, eface any) (ret any)
-func assertI2I(inter *byte, tab *byte) *byte
-func assertI2I2(inter *byte, iface any) (ret any)
-func panicdottypeE(have, want, iface *byte)
-func panicdottypeI(have, want, iface *byte)
-func panicnildottype(want *byte)
-
-// interface equality. Type/itab pointers are already known to be equal, so
-// we only need to pass one.
-func ifaceeq(tab *uintptr, x, y unsafe.Pointer) (ret bool)
-func efaceeq(typ *uintptr, x, y unsafe.Pointer) (ret bool)
-
-func fastrand() uint32
-
-// *byte is really *runtime.Type
-func makemap64(mapType *byte, hint int64, mapbuf *any) (hmap map[any]any)
-func makemap(mapType *byte, hint int, mapbuf *any) (hmap map[any]any)
-func makemap_small() (hmap map[any]any)
-func mapaccess1(mapType *byte, hmap map[any]any, key *any) (val *any)
-func mapaccess1_fast32(mapType *byte, hmap map[any]any, key uint32) (val *any)
-func mapaccess1_fast64(mapType *byte, hmap map[any]any, key uint64) (val *any)
-func mapaccess1_faststr(mapType *byte, hmap map[any]any, key string) (val *any)
-func mapaccess1_fat(mapType *byte, hmap map[any]any, key *any, zero *byte) (val *any)
-func mapaccess2(mapType *byte, hmap map[any]any, key *any) (val *any, pres bool)
-func mapaccess2_fast32(mapType *byte, hmap map[any]any, key uint32) (val *any, pres bool)
-func mapaccess2_fast64(mapType *byte, hmap map[any]any, key uint64) (val *any, pres bool)
-func mapaccess2_faststr(mapType *byte, hmap map[any]any, key string) (val *any, pres bool)
-func mapaccess2_fat(mapType *byte, hmap map[any]any, key *any, zero *byte) (val *any, pres bool)
-func mapassign(mapType *byte, hmap map[any]any, key *any) (val *any)
-func mapassign_fast32(mapType *byte, hmap map[any]any, key uint32) (val *any)
-func mapassign_fast32ptr(mapType *byte, hmap map[any]any, key unsafe.Pointer) (val *any)
-func mapassign_fast64(mapType *byte, hmap map[any]any, key uint64) (val *any)
-func mapassign_fast64ptr(mapType *byte, hmap map[any]any, key unsafe.Pointer) (val *any)
-func mapassign_faststr(mapType *byte, hmap map[any]any, key string) (val *any)
-func mapiterinit(mapType *byte, hmap map[any]any, hiter *any)
-func mapdelete(mapType *byte, hmap map[any]any, key *any)
-func mapdelete_fast32(mapType *byte, hmap map[any]any, key uint32)
-func mapdelete_fast64(mapType *byte, hmap map[any]any, key uint64)
-func mapdelete_faststr(mapType *byte, hmap map[any]any, key string)
-func mapiternext(hiter *any)
-func mapclear(mapType *byte, hmap map[any]any)
-
-// *byte is really *runtime.Type
-func makechan64(chanType *byte, size int64) (hchan chan any)
-func makechan(chanType *byte, size int) (hchan chan any)
-func chanrecv1(hchan <-chan any, elem *any)
-func chanrecv2(hchan <-chan any, elem *any) bool
-func chansend1(hchan chan<- any, elem *any)
-func closechan(hchan any)
-
-var writeBarrier struct {
-	enabled bool
-	pad     [3]byte
-	needed  bool
-	cgo     bool
-	alignme uint64
-}
-
-// *byte is really *runtime.Type
-func typedmemmove(typ *byte, dst *any, src *any)
-func typedmemclr(typ *byte, dst *any)
-func typedslicecopy(typ *byte, dstPtr *any, dstLen int, srcPtr *any, srcLen int) int
-
-func selectnbsend(hchan chan<- any, elem *any) bool
-func selectnbrecv(elem *any, hchan <-chan any) (bool, bool)
-
-func selectsetpc(pc *uintptr)
-func selectgo(cas0 *byte, order0 *byte, pc0 *uintptr, nsends int, nrecvs int, block bool) (int, bool)
-func block()
-
-func makeslice(typ *byte, len int, cap int) unsafe.Pointer
-func makeslice64(typ *byte, len int64, cap int64) unsafe.Pointer
-func makeslicecopy(typ *byte, tolen int, fromlen int, from unsafe.Pointer) unsafe.Pointer
-func growslice(typ *byte, old []any, cap int) (ary []any)
-func unsafeslicecheckptr(typ *byte, ptr unsafe.Pointer, len int64)
-func panicunsafeslicelen()
-func panicunsafeslicenilptr()
-
-func mulUintptr(x, y uintptr) (uintptr, bool)
-
-func memmove(to *any, frm *any, length uintptr)
-func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr)
-func memclrHasPointers(ptr unsafe.Pointer, n uintptr)
-
-func memequal(x, y *any, size uintptr) bool
-func memequal0(x, y *any) bool
-func memequal8(x, y *any) bool
-func memequal16(x, y *any) bool
-func memequal32(x, y *any) bool
-func memequal64(x, y *any) bool
-func memequal128(x, y *any) bool
-func f32equal(p, q unsafe.Pointer) bool
-func f64equal(p, q unsafe.Pointer) bool
-func c64equal(p, q unsafe.Pointer) bool
-func c128equal(p, q unsafe.Pointer) bool
-func strequal(p, q unsafe.Pointer) bool
-func interequal(p, q unsafe.Pointer) bool
-func nilinterequal(p, q unsafe.Pointer) bool
-
-func memhash(p unsafe.Pointer, h uintptr, size uintptr) uintptr
-func memhash0(p unsafe.Pointer, h uintptr) uintptr
-func memhash8(p unsafe.Pointer, h uintptr) uintptr
-func memhash16(p unsafe.Pointer, h uintptr) uintptr
-func memhash32(p unsafe.Pointer, h uintptr) uintptr
-func memhash64(p unsafe.Pointer, h uintptr) uintptr
-func memhash128(p unsafe.Pointer, h uintptr) uintptr
-func f32hash(p unsafe.Pointer, h uintptr) uintptr
-func f64hash(p unsafe.Pointer, h uintptr) uintptr
-func c64hash(p unsafe.Pointer, h uintptr) uintptr
-func c128hash(p unsafe.Pointer, h uintptr) uintptr
-func strhash(a unsafe.Pointer, h uintptr) uintptr
-func interhash(p unsafe.Pointer, h uintptr) uintptr
-func nilinterhash(p unsafe.Pointer, h uintptr) uintptr
-
-// only used on 32-bit
-func int64div(int64, int64) int64
-func uint64div(uint64, uint64) uint64
-func int64mod(int64, int64) int64
-func uint64mod(uint64, uint64) uint64
-func float64toint64(float64) int64
-func float64touint64(float64) uint64
-func float64touint32(float64) uint32
-func int64tofloat64(int64) float64
-func int64tofloat32(int64) float32
-func uint64tofloat64(uint64) float64
-func uint64tofloat32(uint64) float32
-func uint32tofloat64(uint32) float64
-
-func complex128div(num complex128, den complex128) (quo complex128)
-
-func getcallerpc() uintptr
-func getcallersp() uintptr
-
-// race detection
-func racefuncenter(uintptr)
-func racefuncexit()
-func raceread(uintptr)
-func racewrite(uintptr)
-func racereadrange(addr, size uintptr)
-func racewriterange(addr, size uintptr)
-
-// memory sanitizer
-func msanread(addr, size uintptr)
-func msanwrite(addr, size uintptr)
-func msanmove(dst, src, size uintptr)
-
-// address sanitizer
-func asanread(addr, size uintptr)
-func asanwrite(addr, size uintptr)
-
-func checkptrAlignment(unsafe.Pointer, *byte, uintptr)
-func checkptrArithmetic(unsafe.Pointer, []unsafe.Pointer)
-
-func libfuzzerTraceCmp1(uint8, uint8, int)
-func libfuzzerTraceCmp2(uint16, uint16, int)
-func libfuzzerTraceCmp4(uint32, uint32, int)
-func libfuzzerTraceCmp8(uint64, uint64, int)
-func libfuzzerTraceConstCmp1(uint8, uint8, int)
-func libfuzzerTraceConstCmp2(uint16, uint16, int)
-func libfuzzerTraceConstCmp4(uint32, uint32, int)
-func libfuzzerTraceConstCmp8(uint64, uint64, int)
-func libfuzzerHookStrCmp(string, string, int)
-func libfuzzerHookEqualFold(string, string, int)
-
-// architecture variants
-var x86HasPOPCNT bool
-var x86HasSSE41 bool
-var x86HasFMA bool
-var armHasVFPv4 bool
-var arm64HasATOMICS bool
diff --git a/src/cmd/compile/internal/typecheck/builtin_test.go b/src/cmd/compile/internal/typecheck/builtin_test.go
index fb9d3e3..3c0d6b8 100644
--- a/src/cmd/compile/internal/typecheck/builtin_test.go
+++ b/src/cmd/compile/internal/typecheck/builtin_test.go
@@ -7,8 +7,7 @@
 import (
 	"bytes"
 	"internal/testenv"
-	"io/ioutil"
-	"os/exec"
+	"os"
 	"testing"
 )
 
@@ -16,12 +15,12 @@
 	testenv.MustHaveGoRun(t)
 	t.Parallel()
 
-	old, err := ioutil.ReadFile("builtin.go")
+	old, err := os.ReadFile("builtin.go")
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	new, err := exec.Command(testenv.GoToolPath(t), "run", "mkbuiltin.go", "-stdout").Output()
+	new, err := testenv.Command(t, testenv.GoToolPath(t), "run", "mkbuiltin.go", "-stdout").Output()
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/src/cmd/compile/internal/typecheck/const.go b/src/cmd/compile/internal/typecheck/const.go
index 6109850..6855f05 100644
--- a/src/cmd/compile/internal/typecheck/const.go
+++ b/src/cmd/compile/internal/typecheck/const.go
@@ -34,10 +34,7 @@
 // truncate float literal fv to 32-bit or 64-bit precision
 // according to type; return truncated value.
 func truncfltlit(v constant.Value, t *types.Type) constant.Value {
-	if t.IsUntyped() || overflow(v, t) {
-		// If there was overflow, simply continuing would set the
-		// value to Inf which in turn would lead to spurious follow-on
-		// errors. Avoid this by returning the existing value.
+	if t.IsUntyped() {
 		return v
 	}
 
@@ -48,10 +45,7 @@
 // precision, according to type; return truncated value. In case of
 // overflow, calls Errorf but does not truncate the input value.
 func trunccmplxlit(v constant.Value, t *types.Type) constant.Value {
-	if t.IsUntyped() || overflow(v, t) {
-		// If there was overflow, simply continuing would set the
-		// value to Inf which in turn would lead to spurious follow-on
-		// errors. Avoid this by returning the existing value.
+	if t.IsUntyped() {
 		return v
 	}
 
@@ -251,7 +245,6 @@
 		switch {
 		case t.IsInteger():
 			v = toint(v)
-			overflow(v, t)
 			return v
 		case t.IsFloat():
 			v = toflt(v)
@@ -273,9 +266,6 @@
 
 func toflt(v constant.Value) constant.Value {
 	if v.Kind() == constant.Complex {
-		if constant.Sign(constant.Imag(v)) != 0 {
-			base.Errorf("constant %v truncated to real", v)
-		}
 		v = constant.Real(v)
 	}
 
@@ -284,9 +274,6 @@
 
 func toint(v constant.Value) constant.Value {
 	if v.Kind() == constant.Complex {
-		if constant.Sign(constant.Imag(v)) != 0 {
-			base.Errorf("constant %v truncated to integer", v)
-		}
 		v = constant.Real(v)
 	}
 
@@ -321,25 +308,6 @@
 	return constant.MakeInt64(1)
 }
 
-// overflow reports whether constant value v is too large
-// to represent with type t, and emits an error message if so.
-func overflow(v constant.Value, t *types.Type) bool {
-	// v has already been converted
-	// to appropriate form for t.
-	if t.IsUntyped() {
-		return false
-	}
-	if v.Kind() == constant.Int && constant.BitLen(v) > ir.ConstPrec {
-		base.Errorf("integer too large")
-		return true
-	}
-	if ir.ConstOverflow(v, t) {
-		base.Errorf("constant %v overflows %v", types.FmtConst(v, false), t)
-		return true
-	}
-	return false
-}
-
 func tostr(v constant.Value) constant.Value {
 	if v.Kind() == constant.Int {
 		r := unicode.ReplacementChar
@@ -758,7 +726,10 @@
 		ir.ORECOVER,
 		ir.ORECV,
 		ir.OUNSAFEADD,
-		ir.OUNSAFESLICE:
+		ir.OUNSAFESLICE,
+		ir.OUNSAFESLICEDATA,
+		ir.OUNSAFESTRING,
+		ir.OUNSAFESTRINGDATA:
 		return true
 	}
 	return false
diff --git a/src/cmd/compile/internal/typecheck/dcl.go b/src/cmd/compile/internal/typecheck/dcl.go
index 4001fa5..fce7d3d 100644
--- a/src/cmd/compile/internal/typecheck/dcl.go
+++ b/src/cmd/compile/internal/typecheck/dcl.go
@@ -238,7 +238,7 @@
 	return TempAt(base.Pos, ir.CurFunc, t)
 }
 
-// make a new Node off the books
+// make a new Node off the books.
 func TempAt(pos src.XPos, curfn *ir.Func, t *types.Type) *ir.Name {
 	if curfn == nil {
 		base.Fatalf("no curfn for TempAt")
diff --git a/src/cmd/compile/internal/typecheck/export.go b/src/cmd/compile/internal/typecheck/export.go
index 30726d4..af56ea8 100644
--- a/src/cmd/compile/internal/typecheck/export.go
+++ b/src/cmd/compile/internal/typecheck/export.go
@@ -14,13 +14,13 @@
 )
 
 // importalias declares symbol s as an imported type alias with type t.
-// ipkg is the package being imported
+// ipkg is the package being imported.
 func importalias(pos src.XPos, s *types.Sym, t *types.Type) *ir.Name {
 	return importobj(pos, s, ir.OTYPE, ir.PEXTERN, t)
 }
 
 // importconst declares symbol s as an imported constant with type t and value val.
-// ipkg is the package being imported
+// ipkg is the package being imported.
 func importconst(pos src.XPos, s *types.Sym, t *types.Type, val constant.Value) *ir.Name {
 	n := importobj(pos, s, ir.OLITERAL, ir.PEXTERN, t)
 	n.SetVal(val)
@@ -28,7 +28,7 @@
 }
 
 // importfunc declares symbol s as an imported function with type t.
-// ipkg is the package being imported
+// ipkg is the package being imported.
 func importfunc(pos src.XPos, s *types.Sym, t *types.Type) *ir.Name {
 	n := importobj(pos, s, ir.ONAME, ir.PFUNC, t)
 	n.Func = ir.NewFunc(pos)
@@ -37,7 +37,7 @@
 }
 
 // importobj declares symbol s as an imported object representable by op.
-// ipkg is the package being imported
+// ipkg is the package being imported.
 func importobj(pos src.XPos, s *types.Sym, op ir.Op, ctxt ir.Class, t *types.Type) *ir.Name {
 	n := importsym(pos, s, op, ctxt)
 	n.SetType(t)
@@ -60,7 +60,7 @@
 
 // importtype returns the named type declared by symbol s.
 // If no such type has been declared yet, a forward declaration is returned.
-// ipkg is the package being imported
+// ipkg is the package being imported.
 func importtype(pos src.XPos, s *types.Sym) *ir.Name {
 	n := importsym(pos, s, ir.OTYPE, ir.PEXTERN)
 	n.SetType(types.NewNamed(n))
@@ -68,7 +68,7 @@
 }
 
 // importvar declares symbol s as an imported variable with type t.
-// ipkg is the package being imported
+// ipkg is the package being imported.
 func importvar(pos src.XPos, s *types.Sym, t *types.Type) *ir.Name {
 	return importobj(pos, s, ir.ONAME, ir.PEXTERN, t)
 }
diff --git a/src/cmd/compile/internal/typecheck/expr.go b/src/cmd/compile/internal/typecheck/expr.go
index b69fc2d..0cd69ab 100644
--- a/src/cmd/compile/internal/typecheck/expr.go
+++ b/src/cmd/compile/internal/typecheck/expr.go
@@ -516,6 +516,18 @@
 	return n
 }
 
+func wrongTypeFor(haveSym *types.Sym, haveType *types.Type, wantSym *types.Sym, wantType *types.Type) string {
+	haveT := fmt.Sprintf("%S", haveType)
+	wantT := fmt.Sprintf("%S", wantType)
+	if haveT == wantT {
+		// Add packages instead of reporting "got Foo but wanted Foo", see #54258.
+		haveT = haveType.Pkg().Path + "." + haveT
+		wantT = wantType.Pkg().Path + "." + wantT
+	}
+	return fmt.Sprintf("(wrong type for %v method)\n"+
+		"\t\thave %v%s\n\t\twant %v%s", wantSym, haveSym, haveT, wantSym, wantT)
+}
+
 // tcDotType typechecks an ODOTTYPE node.
 func tcDotType(n *ir.TypeAssertExpr) ir.Node {
 	n.X = Expr(n.X)
@@ -539,8 +551,8 @@
 		var ptr int
 		if !implements(n.Type(), t, &missing, &have, &ptr) {
 			if have != nil && have.Sym == missing.Sym {
-				base.Errorf("impossible type assertion:\n\t%v does not implement %v (wrong type for %v method)\n"+
-					"\t\thave %v%S\n\t\twant %v%S", n.Type(), t, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
+				base.Errorf("impossible type assertion:\n\t%v does not implement %v %s", n.Type(), t,
+					wrongTypeFor(have.Sym, have.Type, missing.Sym, missing.Type))
 			} else if ptr != 0 {
 				base.Errorf("impossible type assertion:\n\t%v does not implement %v (%v method has pointer receiver)", n.Type(), t, missing.Sym)
 			} else if have != nil {
@@ -659,6 +671,40 @@
 	return n
 }
 
+// tcUnsafeData typechecks an OUNSAFESLICEDATA or OUNSAFESTRINGDATA node.
+func tcUnsafeData(n *ir.UnaryExpr) ir.Node {
+	n.X = Expr(n.X)
+	n.X = DefaultLit(n.X, nil)
+	l := n.X
+	t := l.Type()
+	if t == nil {
+		n.SetType(nil)
+		return n
+	}
+
+	var kind types.Kind
+	if n.Op() == ir.OUNSAFESLICEDATA {
+		kind = types.TSLICE
+	} else {
+		/* kind is string */
+		kind = types.TSTRING
+	}
+
+	if t.Kind() != kind {
+		base.Errorf("invalid argument %L for %v", l, n.Op())
+		n.SetType(nil)
+		return n
+	}
+
+	if kind == types.TSTRING {
+		t = types.ByteType
+	} else {
+		t = t.Elem()
+	}
+	n.SetType(types.NewPtr(t))
+	return n
+}
+
 // tcRecv typechecks an ORECV node.
 func tcRecv(n *ir.UnaryExpr) ir.Node {
 	n.X = Expr(n.X)
@@ -812,6 +858,31 @@
 	return n
 }
 
+// tcStringHeader typechecks an OSTRINGHEADER node.
+func tcStringHeader(n *ir.StringHeaderExpr) ir.Node {
+	t := n.Type()
+	if t == nil {
+		base.Fatalf("no type specified for OSTRINGHEADER")
+	}
+
+	if !t.IsString() {
+		base.Fatalf("invalid type %v for OSTRINGHEADER", n.Type())
+	}
+
+	if n.Ptr == nil || n.Ptr.Type() == nil || !n.Ptr.Type().IsUnsafePtr() {
+		base.Fatalf("need unsafe.Pointer for OSTRINGHEADER")
+	}
+
+	n.Ptr = Expr(n.Ptr)
+	n.Len = DefaultLit(Expr(n.Len), types.Types[types.TINT])
+
+	if ir.IsConst(n.Len, constant.Int) && ir.Int64Val(n.Len) < 0 {
+		base.Fatalf("len for OSTRINGHEADER must be non-negative")
+	}
+
+	return n
+}
+
 // tcStar typechecks an ODEREF node, which may be an expression or a type.
 func tcStar(n *ir.StarExpr, top int) ir.Node {
 	n.X = typecheck(n.X, ctxExpr|ctxType)
diff --git a/src/cmd/compile/internal/typecheck/func.go b/src/cmd/compile/internal/typecheck/func.go
index 0988ce8..7cf9d5c 100644
--- a/src/cmd/compile/internal/typecheck/func.go
+++ b/src/cmd/compile/internal/typecheck/func.go
@@ -105,7 +105,7 @@
 			if pkg == nil {
 				pkg = v.Sym().Pkg
 			} else if pkg != v.Sym().Pkg {
-				base.Fatalf("Closure variables from multiple packages")
+				base.Fatalf("Closure variables from multiple packages: %+v", clo)
 			}
 		}
 	}
@@ -299,7 +299,7 @@
 			n.SetTypecheck(0) // re-typechecking new op is OK, not a loop
 			return typecheck(n, top)
 
-		case ir.OCAP, ir.OCLOSE, ir.OIMAG, ir.OLEN, ir.OPANIC, ir.OREAL:
+		case ir.OCAP, ir.OCLOSE, ir.OIMAG, ir.OLEN, ir.OPANIC, ir.OREAL, ir.OUNSAFESTRINGDATA, ir.OUNSAFESLICEDATA:
 			typecheckargs(n)
 			fallthrough
 		case ir.ONEW, ir.OALIGNOF, ir.OOFFSETOF, ir.OSIZEOF:
@@ -311,7 +311,7 @@
 			u := ir.NewUnaryExpr(n.Pos(), l.BuiltinOp, arg)
 			return typecheck(ir.InitExpr(n.Init(), u), top) // typecheckargs can add to old.Init
 
-		case ir.OCOMPLEX, ir.OCOPY, ir.OUNSAFEADD, ir.OUNSAFESLICE:
+		case ir.OCOMPLEX, ir.OCOPY, ir.OUNSAFEADD, ir.OUNSAFESLICE, ir.OUNSAFESTRING:
 			typecheckargs(n)
 			arg1, arg2, ok := needTwoArgs(n)
 			if !ok {
@@ -460,12 +460,11 @@
 			return n
 		}
 
-		if t.Elem().IsKind(types.TUINT8) && args[1].Type().IsString() {
-			args[1] = DefaultLit(args[1], types.Types[types.TSTRING])
-			return n
-		}
-
-		args[1] = AssignConv(args[1], t.Underlying(), "append")
+		// AssignConv is of args[1] not required here, as the
+		// types of args[0] and args[1] don't need to match
+		// (They will both have an underlying type which are
+		// slices of identical base types, or be []byte and string.)
+		// See issue 53888.
 		return n
 	}
 
@@ -902,16 +901,37 @@
 		base.Errorf("first argument to unsafe.Slice must be pointer; have %L", t)
 	} else if t.Elem().NotInHeap() {
 		// TODO(mdempsky): This can be relaxed, but should only affect the
-		// Go runtime itself. End users should only see //go:notinheap
+		// Go runtime itself. End users should only see not-in-heap
 		// types due to incomplete C structs in cgo, and those types don't
 		// have a meaningful size anyway.
 		base.Errorf("unsafe.Slice of incomplete (or unallocatable) type not allowed")
 	}
 
-	if !checkunsafeslice(&n.Y) {
+	if !checkunsafesliceorstring(n.Op(), &n.Y) {
 		n.SetType(nil)
 		return n
 	}
 	n.SetType(types.NewSlice(t.Elem()))
 	return n
 }
+
+// tcUnsafeString typechecks an OUNSAFESTRING node.
+func tcUnsafeString(n *ir.BinaryExpr) *ir.BinaryExpr {
+	n.X = Expr(n.X)
+	n.Y = Expr(n.Y)
+	if n.X.Type() == nil || n.Y.Type() == nil {
+		n.SetType(nil)
+		return n
+	}
+	t := n.X.Type()
+	if !t.IsPtr() || !types.Identical(t.Elem(), types.Types[types.TUINT8]) {
+		base.Errorf("first argument to unsafe.String must be *byte; have %L", t)
+	}
+
+	if !checkunsafesliceorstring(n.Op(), &n.Y) {
+		n.SetType(nil)
+		return n
+	}
+	n.SetType(types.Types[types.TSTRING])
+	return n
+}
diff --git a/src/cmd/compile/internal/typecheck/iexport.go b/src/cmd/compile/internal/typecheck/iexport.go
index d5c4b8e..3e65425 100644
--- a/src/cmd/compile/internal/typecheck/iexport.go
+++ b/src/cmd/compile/internal/typecheck/iexport.go
@@ -405,7 +405,7 @@
 		w.string(exportPath(pkg))
 		if mainIndex {
 			w.string(pkg.Name)
-			w.uint64(uint64(pkg.Height))
+			w.uint64(0) // was package height, but not necessary anymore.
 		}
 
 		// Sort symbols within a package by name.
@@ -1928,7 +1928,9 @@
 		w.op(n.Op())
 		w.pos(n.Pos())
 		w.expr(n.X)
-		w.expr(n.RType)
+		if w.bool(n.RType != nil) {
+			w.expr(n.RType)
+		}
 		if w.bool(n.ITab != nil) {
 			w.expr(n.ITab)
 		}
@@ -1962,7 +1964,7 @@
 		w.expr(n.Max)
 		w.typ(n.Type())
 
-	case ir.OCOPY, ir.OCOMPLEX, ir.OUNSAFEADD, ir.OUNSAFESLICE:
+	case ir.OCOPY, ir.OCOMPLEX, ir.OUNSAFEADD, ir.OUNSAFESLICE, ir.OUNSAFESTRING:
 		// treated like other builtin calls (see e.g., OREAL)
 		n := n.(*ir.BinaryExpr)
 		w.op(n.Op())
@@ -1972,14 +1974,15 @@
 		w.expr(n.Y)
 		w.typ(n.Type())
 
-	case ir.OCONV, ir.OCONVIFACE, ir.OCONVIDATA, ir.OCONVNOP, ir.OBYTES2STR, ir.ORUNES2STR, ir.OSTR2BYTES, ir.OSTR2RUNES, ir.ORUNESTR, ir.OSLICE2ARRPTR:
+	case ir.OCONV, ir.OCONVIFACE, ir.OCONVIDATA, ir.OCONVNOP, ir.OBYTES2STR, ir.ORUNES2STR, ir.OSTR2BYTES, ir.OSTR2RUNES, ir.ORUNESTR, ir.OSLICE2ARR, ir.OSLICE2ARRPTR:
 		n := n.(*ir.ConvExpr)
 		w.op(n.Op())
 		w.pos(n.Pos())
 		w.typ(n.Type())
 		w.expr(n.X)
+		w.bool(n.Implicit())
 
-	case ir.OREAL, ir.OIMAG, ir.OCAP, ir.OCLOSE, ir.OLEN, ir.ONEW, ir.OPANIC:
+	case ir.OREAL, ir.OIMAG, ir.OCAP, ir.OCLOSE, ir.OLEN, ir.ONEW, ir.OPANIC, ir.OUNSAFESTRINGDATA, ir.OUNSAFESLICEDATA:
 		n := n.(*ir.UnaryExpr)
 		w.op(n.Op())
 		w.pos(n.Pos())
diff --git a/src/cmd/compile/internal/typecheck/iimport.go b/src/cmd/compile/internal/typecheck/iimport.go
index 3a51f78..c55b409 100644
--- a/src/cmd/compile/internal/typecheck/iimport.go
+++ b/src/cmd/compile/internal/typecheck/iimport.go
@@ -11,8 +11,8 @@
 	"encoding/binary"
 	"fmt"
 	"go/constant"
+	"io"
 	"math/big"
-	"os"
 	"strings"
 
 	"cmd/compile/internal/base"
@@ -83,17 +83,14 @@
 
 // HaveInlineBody reports whether we have fn's inline body available
 // for inlining.
-func HaveInlineBody(fn *ir.Func) bool {
+//
+// It's a function literal so that it can be overridden for
+// GOEXPERIMENT=unified.
+var HaveInlineBody = func(fn *ir.Func) bool {
 	if fn.Inl == nil {
 		return false
 	}
 
-	// Unified IR is much more conservative about pruning unreachable
-	// methods (at the cost of increased build artifact size).
-	if base.Debug.Unified != 0 {
-		return true
-	}
-
 	if fn.Inl.Body != nil {
 		return true
 	}
@@ -148,12 +145,10 @@
 	sLen := int64(ird.uint64())
 	dLen := int64(ird.uint64())
 
-	// TODO(mdempsky): Replace os.SEEK_CUR with io.SeekCurrent after
-	// #44505 is fixed.
-	whence, _ := ird.Seek(0, os.SEEK_CUR)
+	whence, _ := ird.Seek(0, io.SeekCurrent)
 	stringData := data[whence : whence+sLen]
 	declData := data[whence+sLen : whence+sLen+dLen]
-	ird.Seek(sLen+dLen, os.SEEK_CUR)
+	ird.Seek(sLen+dLen, io.SeekCurrent)
 
 	p := &iimporter{
 		exportVersion: version,
@@ -175,10 +170,9 @@
 	for nPkgs := ird.uint64(); nPkgs > 0; nPkgs-- {
 		pkg := p.pkgAt(ird.uint64())
 		pkgName := p.stringAt(ird.uint64())
-		pkgHeight := int(ird.uint64())
+		_ = int(ird.uint64()) // was package height, but not necessary anymore.
 		if pkg.Name == "" {
 			pkg.Name = pkgName
-			pkg.Height = pkgHeight
 			types.NumImport[pkgName]++
 
 			// TODO(mdempsky): This belongs somewhere else.
@@ -187,9 +181,6 @@
 			if pkg.Name != pkgName {
 				base.Fatalf("conflicting package names %v and %v for path %q", pkg.Name, pkgName, pkg.Path)
 			}
-			if pkg.Height != pkgHeight {
-				base.Fatalf("conflicting package heights %v and %v for path %q", pkg.Height, pkgHeight, pkg.Path)
-			}
 		}
 
 		for nSyms := ird.uint64(); nSyms > 0; nSyms-- {
@@ -289,9 +280,7 @@
 		p:       p,
 		currPkg: pkg,
 	}
-	// (*strings.Reader).Reset wasn't added until Go 1.7, and we
-	// need to build with Go 1.4.
-	r.Reader = *strings.NewReader(p.declData[off:])
+	r.Reader.Reset(p.declData[off:])
 	return r
 }
 
@@ -1465,7 +1454,10 @@
 		return n
 
 	case ir.ODYNAMICDOTTYPE, ir.ODYNAMICDOTTYPE2:
-		n := ir.NewDynamicTypeAssertExpr(r.pos(), op, r.expr(), r.expr())
+		n := ir.NewDynamicTypeAssertExpr(r.pos(), op, r.expr(), nil)
+		if r.bool() {
+			n.RType = r.expr()
+		}
 		if r.bool() {
 			n.ITab = r.expr()
 		}
@@ -1492,19 +1484,23 @@
 		n.SetType(r.typ())
 		return n
 
-	case ir.OCONV, ir.OCONVIFACE, ir.OCONVIDATA, ir.OCONVNOP, ir.OBYTES2STR, ir.ORUNES2STR, ir.OSTR2BYTES, ir.OSTR2RUNES, ir.ORUNESTR, ir.OSLICE2ARRPTR:
-		return ir.NewConvExpr(r.pos(), op, r.typ(), r.expr())
+	case ir.OCONV, ir.OCONVIFACE, ir.OCONVIDATA, ir.OCONVNOP, ir.OBYTES2STR, ir.ORUNES2STR, ir.OSTR2BYTES, ir.OSTR2RUNES, ir.ORUNESTR, ir.OSLICE2ARR, ir.OSLICE2ARRPTR:
+		n := ir.NewConvExpr(r.pos(), op, r.typ(), r.expr())
+		n.SetImplicit(r.bool())
+		return n
 
-	case ir.OCOPY, ir.OCOMPLEX, ir.OREAL, ir.OIMAG, ir.OAPPEND, ir.OCAP, ir.OCLOSE, ir.ODELETE, ir.OLEN, ir.OMAKE, ir.ONEW, ir.OPANIC, ir.ORECOVER, ir.OPRINT, ir.OPRINTN, ir.OUNSAFEADD, ir.OUNSAFESLICE:
+	case ir.OCOPY, ir.OCOMPLEX, ir.OREAL, ir.OIMAG, ir.OAPPEND, ir.OCAP, ir.OCLOSE, ir.ODELETE, ir.OLEN, ir.OMAKE,
+		ir.ONEW, ir.OPANIC, ir.ORECOVER, ir.OPRINT, ir.OPRINTN,
+		ir.OUNSAFEADD, ir.OUNSAFESLICE, ir.OUNSAFESLICEDATA, ir.OUNSAFESTRING, ir.OUNSAFESTRINGDATA:
 		pos := r.pos()
 		switch op {
-		case ir.OCOPY, ir.OCOMPLEX, ir.OUNSAFEADD, ir.OUNSAFESLICE:
+		case ir.OCOPY, ir.OCOMPLEX, ir.OUNSAFEADD, ir.OUNSAFESLICE, ir.OUNSAFESTRING:
 			init := r.stmtList()
 			n := ir.NewBinaryExpr(pos, op, r.expr(), r.expr())
 			n.SetInit(init)
 			n.SetType(r.typ())
 			return n
-		case ir.OREAL, ir.OIMAG, ir.OCAP, ir.OCLOSE, ir.OLEN, ir.ONEW, ir.OPANIC:
+		case ir.OREAL, ir.OIMAG, ir.OCAP, ir.OCLOSE, ir.OLEN, ir.ONEW, ir.OPANIC, ir.OUNSAFESTRINGDATA, ir.OUNSAFESLICEDATA:
 			n := ir.NewUnaryExpr(pos, op, r.expr())
 			if op != ir.OPANIC {
 				n.SetType(r.typ())
diff --git a/src/cmd/compile/internal/typecheck/mkbuiltin.go b/src/cmd/compile/internal/typecheck/mkbuiltin.go
index 9b27557..0ac3e47 100644
--- a/src/cmd/compile/internal/typecheck/mkbuiltin.go
+++ b/src/cmd/compile/internal/typecheck/mkbuiltin.go
@@ -3,7 +3,6 @@
 // license that can be found in the LICENSE file.
 
 //go:build ignore
-// +build ignore
 
 // Generate builtin.go from builtin/runtime.go.
 
@@ -18,7 +17,6 @@
 	"go/parser"
 	"go/token"
 	"io"
-	"io/ioutil"
 	"log"
 	"os"
 	"path/filepath"
@@ -27,6 +25,7 @@
 )
 
 var stdout = flag.Bool("stdout", false, "write to stdout instead of builtin.go")
+var nofmt = flag.Bool("nofmt", false, "skip formatting builtin.go")
 
 func main() {
 	flag.Parse()
@@ -41,16 +40,37 @@
 	fmt.Fprintln(&b, `      "cmd/internal/src"`)
 	fmt.Fprintln(&b, `)`)
 
-	mkbuiltin(&b, "runtime")
+	fmt.Fprintln(&b, `
+// Not inlining this function removes a significant chunk of init code.
+//go:noinline
+func newSig(params, results []*types.Field) *types.Type {
+	return types.NewSignature(types.NoPkg, nil, nil, params, results)
+}
 
-	out, err := format.Source(b.Bytes())
-	if err != nil {
-		log.Fatal(err)
+func params(tlist ...*types.Type) []*types.Field {
+	flist := make([]*types.Field, len(tlist))
+	for i, typ := range tlist {
+		flist[i] = types.NewField(src.NoXPos, nil, typ)
+	}
+	return flist
+}
+`)
+
+	mkbuiltin(&b, "runtime")
+	mkbuiltin(&b, "coverage")
+
+	var err error
+	out := b.Bytes()
+	if !*nofmt {
+		out, err = format.Source(out)
+		if err != nil {
+			log.Fatal(err)
+		}
 	}
 	if *stdout {
 		_, err = os.Stdout.Write(out)
 	} else {
-		err = ioutil.WriteFile("builtin.go", out, 0666)
+		err = os.WriteFile("builtin.go", out, 0666)
 	}
 	if err != nil {
 		log.Fatal(err)
@@ -59,7 +79,7 @@
 
 func mkbuiltin(w io.Writer, name string) {
 	fset := token.NewFileSet()
-	f, err := parser.ParseFile(fset, filepath.Join("builtin", name+".go"), nil, 0)
+	f, err := parser.ParseFile(fset, filepath.Join("_builtin", name+".go"), nil, 0)
 	if err != nil {
 		log.Fatal(err)
 	}
@@ -103,22 +123,6 @@
 	}
 	fmt.Fprintln(w, "}")
 
-	fmt.Fprintln(w, `
-// Not inlining this function removes a significant chunk of init code.
-//
-//go:noinline
-func newSig(params, results []*types.Field) *types.Type {
-	return types.NewSignature(types.NoPkg, nil, nil, params, results)
-}
-
-func params(tlist ...*types.Type) []*types.Field {
-	flist := make([]*types.Field, len(tlist))
-	for i, typ := range tlist {
-		flist[i] = types.NewField(src.NoXPos, nil, typ)
-	}
-	return flist
-}`)
-
 	fmt.Fprintln(w)
 	fmt.Fprintf(w, "func %sTypes() []*types.Type {\n", name)
 	fmt.Fprintf(w, "var typs [%d]*types.Type\n", len(interner.typs))
diff --git a/src/cmd/compile/internal/typecheck/stmt.go b/src/cmd/compile/internal/typecheck/stmt.go
index 370e324..9d57edb 100644
--- a/src/cmd/compile/internal/typecheck/stmt.go
+++ b/src/cmd/compile/internal/typecheck/stmt.go
@@ -258,9 +258,6 @@
 		}
 	}
 	n.Post = Stmt(n.Post)
-	if n.Op() == ir.OFORUNTIL {
-		Stmts(n.Late)
-	}
 	Stmts(n.Body)
 	return n
 }
@@ -607,8 +604,8 @@
 			}
 			if !n1.Type().IsInterface() && !implements(n1.Type(), t, &missing, &have, &ptr) {
 				if have != nil {
-					base.ErrorfAt(ncase.Pos(), "impossible type switch case: %L cannot have dynamic type %v"+
-						" (wrong type for %v method)\n\thave %v%S\n\twant %v%S", guard.X, n1.Type(), missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
+					base.ErrorfAt(ncase.Pos(), "impossible type switch case: %L cannot have dynamic type %v %s", guard.X, n1.Type(),
+						wrongTypeFor(have.Sym, have.Type, missing.Sym, missing.Type))
 				} else if ptr != 0 {
 					base.ErrorfAt(ncase.Pos(), "impossible type switch case: %L cannot have dynamic type %v"+
 						" (%v method has pointer receiver)", guard.X, n1.Type(), missing.Sym)
diff --git a/src/cmd/compile/internal/typecheck/subr.go b/src/cmd/compile/internal/typecheck/subr.go
index ffd00ec..9760e36 100644
--- a/src/cmd/compile/internal/typecheck/subr.go
+++ b/src/cmd/compile/internal/typecheck/subr.go
@@ -13,6 +13,7 @@
 	"cmd/compile/internal/base"
 	"cmd/compile/internal/ir"
 	"cmd/compile/internal/types"
+	"cmd/internal/obj"
 	"cmd/internal/objabi"
 	"cmd/internal/src"
 )
@@ -49,7 +50,7 @@
 	return args
 }
 
-// newname returns a new ONAME Node associated with symbol s.
+// NewName returns a new ONAME Node associated with symbol s.
 func NewName(s *types.Sym) *ir.Name {
 	n := ir.NewNameAt(base.Pos, s)
 	n.Curfn = ir.CurFunc
@@ -61,7 +62,7 @@
 	return NodAddrAt(base.Pos, n)
 }
 
-// nodAddrPos returns a node representing &n at position pos.
+// NodAddrAt returns a node representing &n at position pos.
 func NodAddrAt(pos src.XPos, n ir.Node) *ir.AddrExpr {
 	n = markAddrOf(n)
 	return ir.NewAddrExpr(pos, n)
@@ -119,6 +120,13 @@
 	}
 }
 
+// LinksymAddr returns a new expression that evaluates to the address
+// of lsym. typ specifies the type of the addressed memory.
+func LinksymAddr(pos src.XPos, lsym *obj.LSym, typ *types.Type) *ir.AddrExpr {
+	n := ir.NewLinksymExpr(pos, lsym, typ)
+	return Expr(NodAddrAt(pos, n)).(*ir.AddrExpr)
+}
+
 func NodNil() ir.Node {
 	n := ir.NewNilExpr(base.Pos)
 	n.SetType(types.Types[types.TNIL])
@@ -293,24 +301,14 @@
 
 	n = convlit1(n, t, false, context)
 	if n.Type() == nil {
-		return n
+		base.Fatalf("cannot assign %v to %v", n, t)
+	}
+	if n.Type().IsUntyped() {
+		base.Fatalf("%L has untyped type", n)
 	}
 	if t.Kind() == types.TBLANK {
 		return n
 	}
-
-	// Convert ideal bool from comparison to plain bool
-	// if the next step is non-bool (like interface{}).
-	if n.Type() == types.UntypedBool && !t.IsBoolean() {
-		if n.Op() == ir.ONAME || n.Op() == ir.OLITERAL {
-			r := ir.NewConvExpr(base.Pos, ir.OCONVNOP, nil, n)
-			r.SetType(types.Types[types.TBOOL])
-			r.SetTypecheck(1)
-			r.SetImplicit(true)
-			n = r
-		}
-	}
-
 	if types.Identical(n.Type(), t) {
 		return n
 	}
@@ -384,6 +382,11 @@
 			// don't have the methods for them.
 			return ir.OCONVIFACE, ""
 		}
+		if base.Debug.Unified != 0 && src.HasShape() {
+			// Unified IR uses OCONVIFACE for converting all derived types
+			// to interface type, not just type arguments themselves.
+			return ir.OCONVIFACE, ""
+		}
 		if implements(src, dst, &missing, &have, &ptr) {
 			return ir.OCONVIFACE, ""
 		}
@@ -394,8 +397,7 @@
 		} else if have != nil && have.Sym == missing.Sym && have.Nointerface() {
 			why = fmt.Sprintf(":\n\t%v does not implement %v (%v method is marked 'nointerface')", src, dst, missing.Sym)
 		} else if have != nil && have.Sym == missing.Sym {
-			why = fmt.Sprintf(":\n\t%v does not implement %v (wrong type for %v method)\n"+
-				"\t\thave %v%S\n\t\twant %v%S", src, dst, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
+			why = fmt.Sprintf(":\n\t%v does not implement %v %s", src, dst, wrongTypeFor(have.Sym, have.Type, missing.Sym, missing.Type))
 		} else if ptr != 0 {
 			why = fmt.Sprintf(":\n\t%v does not implement %v (%v method has pointer receiver)", src, dst, missing.Sym)
 		} else if have != nil {
@@ -468,15 +470,15 @@
 		return ir.OXXX, ""
 	}
 
-	// Conversions from regular to go:notinheap are not allowed
+	// Conversions from regular to not-in-heap are not allowed
 	// (unless it's unsafe.Pointer). These are runtime-specific
 	// rules.
-	// (a) Disallow (*T) to (*U) where T is go:notinheap but U isn't.
+	// (a) Disallow (*T) to (*U) where T is not-in-heap but U isn't.
 	if src.IsPtr() && dst.IsPtr() && dst.Elem().NotInHeap() && !src.Elem().NotInHeap() {
 		why := fmt.Sprintf(":\n\t%v is incomplete (or unallocatable), but %v is not", dst.Elem(), src.Elem())
 		return ir.OXXX, why
 	}
-	// (b) Disallow string to []T where T is go:notinheap.
+	// (b) Disallow string to []T where T is not-in-heap.
 	if src.IsString() && dst.IsSlice() && dst.Elem().NotInHeap() && (dst.Elem().Kind() == types.ByteType.Kind() || dst.Elem().Kind() == types.RuneType.Kind()) {
 		why := fmt.Sprintf(":\n\t%v is incomplete (or unallocatable)", dst.Elem())
 		return ir.OXXX, why
@@ -576,11 +578,16 @@
 		return ir.OCONVNOP, ""
 	}
 
-	// 11. src is a slice and dst is a pointer-to-array.
+	// 11. src is a slice and dst is an array or pointer-to-array.
 	// They must have same element type.
-	if src.IsSlice() && dst.IsPtr() && dst.Elem().IsArray() &&
-		types.Identical(src.Elem(), dst.Elem().Elem()) {
-		return ir.OSLICE2ARRPTR, ""
+	if src.IsSlice() {
+		if dst.IsArray() && types.Identical(src.Elem(), dst.Elem()) {
+			return ir.OSLICE2ARR, ""
+		}
+		if dst.IsPtr() && dst.Elem().IsArray() &&
+			types.Identical(src.Elem(), dst.Elem().Elem()) {
+			return ir.OSLICE2ARRPTR, ""
+		}
 	}
 
 	return ir.OXXX, ""
@@ -1350,7 +1357,8 @@
 				newfields[i].SetNointerface(true)
 			}
 			if f.Nname != nil && ts.Vars != nil {
-				v := ts.Vars[f.Nname.(*ir.Name)]
+				n := f.Nname.(*ir.Name)
+				v := ts.Vars[n]
 				if v != nil {
 					// This is the case where we are
 					// translating the type of the function we
@@ -1358,6 +1366,13 @@
 					// the subst.ts.vars table, and we want to
 					// change to reference the new dcl.
 					newfields[i].Nname = v
+				} else if ir.IsBlank(n) {
+					// Blank variable is not dcl list. Make a
+					// new one to not share.
+					m := ir.NewNameAt(n.Pos(), ir.BlankNode.Sym())
+					m.SetType(n.Type())
+					m.SetTypecheck(1)
+					newfields[i].Nname = m
 				} else {
 					// This is the case where we are
 					// translating the type of a function
@@ -1411,7 +1426,7 @@
 	return t
 }
 
-// genericSym returns the name of the base generic type for the type named by
+// genericTypeName returns the name of the base generic type for the type named by
 // sym. It simply returns the name obtained by removing everything after the
 // first bracket ("[").
 func genericTypeName(sym *types.Sym) string {
diff --git a/src/cmd/compile/internal/typecheck/syms.go b/src/cmd/compile/internal/typecheck/syms.go
index 1f60f31..7fe649f 100644
--- a/src/cmd/compile/internal/typecheck/syms.go
+++ b/src/cmd/compile/internal/typecheck/syms.go
@@ -101,3 +101,32 @@
 func LookupRuntimeABI(name string, abi obj.ABI) *obj.LSym {
 	return base.PkgLinksym("runtime", name, abi)
 }
+
+// InitCoverage loads the definitions for routines called
+// by code coverage instrumentation (similar to InitRuntime above).
+func InitCoverage() {
+	typs := coverageTypes()
+	for _, d := range &coverageDecls {
+		sym := ir.Pkgs.Coverage.Lookup(d.name)
+		typ := typs[d.typ]
+		switch d.tag {
+		case funcTag:
+			importfunc(src.NoXPos, sym, typ)
+		case varTag:
+			importvar(src.NoXPos, sym, typ)
+		default:
+			base.Fatalf("unhandled declaration tag %v", d.tag)
+		}
+	}
+}
+
+// LookupCoverage looks up the Go function 'name' in package
+// runtime/coverage. This function must follow the internal calling
+// convention.
+func LookupCoverage(name string) *ir.Name {
+	sym := ir.Pkgs.Coverage.Lookup(name)
+	if sym == nil {
+		base.Fatalf("LookupCoverage: can't find runtime/coverage.%s", name)
+	}
+	return ir.AsNode(sym.Def).(*ir.Name)
+}
diff --git a/src/cmd/compile/internal/typecheck/typecheck.go b/src/cmd/compile/internal/typecheck/typecheck.go
index 3b0c1f7..1857994 100644
--- a/src/cmd/compile/internal/typecheck/typecheck.go
+++ b/src/cmd/compile/internal/typecheck/typecheck.go
@@ -359,7 +359,7 @@
 	case ir.OAPPEND:
 		// Must be used (and not BinaryExpr/UnaryExpr).
 		isStmt = false
-	case ir.OCLOSE, ir.ODELETE, ir.OPANIC, ir.OPRINT, ir.OPRINTN, ir.OVARKILL, ir.OVARLIVE:
+	case ir.OCLOSE, ir.ODELETE, ir.OPANIC, ir.OPRINT, ir.OPRINTN:
 		// Must not be used.
 		isExpr = false
 		isStmt = true
@@ -610,6 +610,10 @@
 		n := n.(*ir.SliceHeaderExpr)
 		return tcSliceHeader(n)
 
+	case ir.OSTRINGHEADER:
+		n := n.(*ir.StringHeaderExpr)
+		return tcStringHeader(n)
+
 	case ir.OMAKESLICECOPY:
 		n := n.(*ir.MakeExpr)
 		return tcMakeSliceCopy(n)
@@ -692,6 +696,18 @@
 		n := n.(*ir.BinaryExpr)
 		return tcUnsafeSlice(n)
 
+	case ir.OUNSAFESLICEDATA:
+		n := n.(*ir.UnaryExpr)
+		return tcUnsafeData(n)
+
+	case ir.OUNSAFESTRING:
+		n := n.(*ir.BinaryExpr)
+		return tcUnsafeString(n)
+
+	case ir.OUNSAFESTRINGDATA:
+		n := n.(*ir.UnaryExpr)
+		return tcUnsafeData(n)
+
 	case ir.OCLOSURE:
 		n := n.(*ir.ClosureExpr)
 		return tcClosure(n, top)
@@ -749,9 +765,7 @@
 		ir.OCONTINUE,
 		ir.ODCL,
 		ir.OGOTO,
-		ir.OFALL,
-		ir.OVARKILL,
-		ir.OVARLIVE:
+		ir.OFALL:
 		return n
 
 	case ir.OBLOCK:
@@ -774,7 +788,7 @@
 		tcGoDefer(n)
 		return n
 
-	case ir.OFOR, ir.OFORUNTIL:
+	case ir.OFOR:
 		n := n.(*ir.ForStmt)
 		return tcFor(n)
 
@@ -1470,7 +1484,7 @@
 	return fmt.Sprintf("(%s)", strings.Join(typeStrings, ", "))
 }
 
-// type check composite
+// type check composite.
 func fielddup(name string, hash map[string]bool) {
 	if hash[name] {
 		base.Errorf("duplicate field name in struct literal: %s", name)
@@ -1649,11 +1663,11 @@
 	return true
 }
 
-// checkunsafeslice is like checkmake but for unsafe.Slice.
-func checkunsafeslice(np *ir.Node) bool {
+// checkunsafesliceorstring is like checkmake but for unsafe.{Slice,String}.
+func checkunsafesliceorstring(op ir.Op, np *ir.Node) bool {
 	n := *np
 	if !n.Type().IsInteger() && n.Type().Kind() != types.TIDEAL {
-		base.Errorf("non-integer len argument in unsafe.Slice - %v", n.Type())
+		base.Errorf("non-integer len argument in %v - %v", op, n.Type())
 		return false
 	}
 
@@ -1662,11 +1676,11 @@
 	if n.Op() == ir.OLITERAL {
 		v := toint(n.Val())
 		if constant.Sign(v) < 0 {
-			base.Errorf("negative len argument in unsafe.Slice")
+			base.Errorf("negative len argument in %v", op)
 			return false
 		}
 		if ir.ConstOverflow(v, types.Types[types.TINT]) {
-			base.Errorf("len argument too large in unsafe.Slice")
+			base.Errorf("len argument too large in %v", op)
 			return false
 		}
 	}
@@ -1697,7 +1711,7 @@
 				setHasBreak(labels[n.Label])
 			}
 
-		case ir.OFOR, ir.OFORUNTIL, ir.OSWITCH, ir.OSELECT, ir.ORANGE:
+		case ir.OFOR, ir.OSWITCH, ir.OSELECT, ir.ORANGE:
 			old := implicit
 			implicit = n
 			var sym *types.Sym
@@ -1773,7 +1787,7 @@
 	case ir.OGOTO, ir.ORETURN, ir.OTAILCALL, ir.OPANIC, ir.OFALL:
 		return true
 
-	case ir.OFOR, ir.OFORUNTIL:
+	case ir.OFOR:
 		n := n.(*ir.ForStmt)
 		if n.Cond != nil {
 			return false
@@ -1820,7 +1834,7 @@
 }
 
 func Conv(n ir.Node, t *types.Type) ir.Node {
-	if types.Identical(n.Type(), t) {
+	if types.IdenticalStrict(n.Type(), t) {
 		return n
 	}
 	n = ir.NewConvExpr(base.Pos, ir.OCONV, nil, n)
@@ -1832,7 +1846,7 @@
 // ConvNop converts node n to type t using the OCONVNOP op
 // and typechecks the result with ctxExpr.
 func ConvNop(n ir.Node, t *types.Type) ir.Node {
-	if types.Identical(n.Type(), t) {
+	if types.IdenticalStrict(n.Type(), t) {
 		return n
 	}
 	n = ir.NewConvExpr(base.Pos, ir.OCONVNOP, nil, n)
diff --git a/src/cmd/compile/internal/typecheck/universe.go b/src/cmd/compile/internal/typecheck/universe.go
index 19cb244..828a8db 100644
--- a/src/cmd/compile/internal/typecheck/universe.go
+++ b/src/cmd/compile/internal/typecheck/universe.go
@@ -58,6 +58,9 @@
 	{"Offsetof", ir.OOFFSETOF},
 	{"Sizeof", ir.OSIZEOF},
 	{"Slice", ir.OUNSAFESLICE},
+	{"SliceData", ir.OUNSAFESLICEDATA},
+	{"String", ir.OUNSAFESTRING},
+	{"StringData", ir.OUNSAFESTRINGDATA},
 }
 
 // InitUniverse initializes the universe block.
diff --git a/src/cmd/compile/internal/types/fmt.go b/src/cmd/compile/internal/types/fmt.go
index c113864..990f2e5 100644
--- a/src/cmd/compile/internal/types/fmt.go
+++ b/src/cmd/compile/internal/types/fmt.go
@@ -340,13 +340,9 @@
 		// non-fmtTypeID modes.
 		sym := t.Sym()
 		if mode != fmtTypeID {
-			i := len(sym.Name)
-			for i > 0 && sym.Name[i-1] >= '0' && sym.Name[i-1] <= '9' {
-				i--
-			}
-			const dot = "·"
-			if i >= len(dot) && sym.Name[i-len(dot):i] == dot {
-				sym = &Sym{Pkg: sym.Pkg, Name: sym.Name[:i-len(dot)]}
+			base, _ := SplitVargenSuffix(sym.Name)
+			if len(base) < len(sym.Name) {
+				sym = &Sym{Pkg: sym.Pkg, Name: base}
 			}
 		}
 		sconv2(b, sym, verb, mode)
@@ -581,7 +577,7 @@
 		} else {
 			b.WriteString("tp")
 			// Print out the pointer value for now to disambiguate type params
-			b.WriteString(fmt.Sprintf("%p", t))
+			fmt.Fprintf(b, "%p", t)
 		}
 
 	case TUNION:
@@ -704,6 +700,21 @@
 	}
 }
 
+// SplitVargenSuffix returns name split into a base string and a ·N
+// suffix, if any.
+func SplitVargenSuffix(name string) (base, suffix string) {
+	i := len(name)
+	for i > 0 && name[i-1] >= '0' && name[i-1] <= '9' {
+		i--
+	}
+	const dot = "·"
+	if i >= len(dot) && name[i-len(dot):i] == dot {
+		i -= len(dot)
+		return name[:i], name[i:]
+	}
+	return name, ""
+}
+
 // Val
 
 func FmtConst(v constant.Value, sharp bool) string {
diff --git a/src/cmd/compile/internal/types/goversion.go b/src/cmd/compile/internal/types/goversion.go
index ceb2ed3..3ece95b 100644
--- a/src/cmd/compile/internal/types/goversion.go
+++ b/src/cmd/compile/internal/types/goversion.go
@@ -81,4 +81,4 @@
 
 // goVersionRE is a regular expression that matches the valid
 // arguments to the -lang flag.
-var goVersionRE = regexp.MustCompile(`^go([1-9][0-9]*)\.(0|[1-9][0-9]*)$`)
+var goVersionRE = regexp.MustCompile(`^go([1-9]\d*)\.(0|[1-9]\d*)$`)
diff --git a/src/cmd/compile/internal/types/pkg.go b/src/cmd/compile/internal/types/pkg.go
index 4bf39a5..9a21494 100644
--- a/src/cmd/compile/internal/types/pkg.go
+++ b/src/cmd/compile/internal/types/pkg.go
@@ -16,9 +16,6 @@
 // pkgMap maps a package path to a package.
 var pkgMap = make(map[string]*Pkg)
 
-// MaxPkgHeight is a height greater than any likely package height.
-const MaxPkgHeight = 1e9
-
 type Pkg struct {
 	Path    string // string literal used in import statement, e.g. "runtime/internal/sys"
 	Name    string // package name, e.g. "sys"
@@ -26,12 +23,6 @@
 	Syms    map[string]*Sym
 	Pathsym *obj.LSym
 
-	// Height is the package's height in the import graph. Leaf
-	// packages (i.e., packages with no imports) have height 0,
-	// and all other packages have height 1 plus the maximum
-	// height of their imported packages.
-	Height int
-
 	Direct bool // imported directly
 }
 
diff --git a/src/cmd/compile/internal/types/size.go b/src/cmd/compile/internal/types/size.go
index d034808..e655a36 100644
--- a/src/cmd/compile/internal/types/size.go
+++ b/src/cmd/compile/internal/types/size.go
@@ -63,9 +63,10 @@
 // the size of a pointer, set in gc.Main (see ../gc/main.go).
 var defercalc int
 
-func Rnd(o int64, r int64) int64 {
+// RoundUp rounds o to a multiple of r, r is a power of 2.
+func RoundUp(o int64, r int64) int64 {
 	if r < 1 || r > 8 || r&(r-1) != 0 {
-		base.Fatalf("rnd %d", r)
+		base.Fatalf("Round %d", r)
 	}
 	return (o + r - 1) &^ (r - 1)
 }
@@ -183,11 +184,18 @@
 		}
 
 		CalcSize(f.Type)
+		// If type T contains a field F marked as not-in-heap,
+		// then T must also be a not-in-heap type. Otherwise,
+		// you could heap allocate T and then get a pointer F,
+		// which would be a heap pointer to a not-in-heap type.
+		if f.Type.NotInHeap() {
+			t.SetNotInHeap(true)
+		}
 		if int32(f.Type.align) > maxalign {
 			maxalign = int32(f.Type.align)
 		}
 		if f.Type.align > 0 {
-			o = Rnd(o, int64(f.Type.align))
+			o = RoundUp(o, int64(f.Type.align))
 		}
 		if isStruct { // For receiver/args/results, do not set, it depends on ABI
 			f.Offset = o
@@ -223,7 +231,7 @@
 
 	// final width is rounded
 	if flag != 0 {
-		o = Rnd(o, int64(maxalign))
+		o = RoundUp(o, int64(maxalign))
 	}
 	t.align = uint8(maxalign)
 
@@ -390,6 +398,7 @@
 		}
 
 		CalcSize(t.Elem())
+		t.SetNotInHeap(t.Elem().NotInHeap())
 		if t.Elem().width != 0 {
 			cap := (uint64(MaxWidth) - 1) / uint64(t.Elem().width)
 			if uint64(t.NumElem()) > cap {
@@ -411,6 +420,10 @@
 		if t.IsFuncArgStruct() {
 			base.Fatalf("CalcSize fn struct %v", t)
 		}
+		// Recognize and mark runtime/internal/sys.nih as not-in-heap.
+		if sym := t.Sym(); sym != nil && sym.Pkg.Path == "runtime/internal/sys" && sym.Name == "nih" {
+			t.SetNotInHeap(true)
+		}
 		w = calcStructOffset(t, t, 0, 1)
 
 	// make fake type to check later to
diff --git a/src/cmd/compile/internal/types/sym.go b/src/cmd/compile/internal/types/sym.go
index 927ebc4..9d8707b 100644
--- a/src/cmd/compile/internal/types/sym.go
+++ b/src/cmd/compile/internal/types/sym.go
@@ -97,14 +97,7 @@
 // Less reports whether symbol a is ordered before symbol b.
 //
 // Symbols are ordered exported before non-exported, then by name, and
-// finally (for non-exported symbols) by package height and path.
-//
-// Ordering by package height is necessary to establish a consistent
-// ordering for non-exported names with the same spelling but from
-// different packages. We don't necessarily know the path for the
-// package being compiled, but by definition it will have a height
-// greater than any other packages seen within the compilation unit.
-// For more background, see issue #24693.
+// finally (for non-exported symbols) by package path.
 func (a *Sym) Less(b *Sym) bool {
 	if a == b {
 		return false
@@ -131,9 +124,6 @@
 		return a.Name < b.Name
 	}
 	if !ea {
-		if a.Pkg.Height != b.Pkg.Height {
-			return a.Pkg.Height < b.Pkg.Height
-		}
 		return a.Pkg.Path < b.Pkg.Path
 	}
 	return false
diff --git a/src/cmd/compile/internal/types/type.go b/src/cmd/compile/internal/types/type.go
index 9e229a5..4bdbc3d 100644
--- a/src/cmd/compile/internal/types/type.go
+++ b/src/cmd/compile/internal/types/type.go
@@ -394,7 +394,7 @@
 	Funarg Funarg // type of function arguments for arg struct
 }
 
-// Fnstruct records the kind of function argument
+// Funarg records the kind of function argument
 type Funarg uint8
 
 const (
@@ -625,7 +625,6 @@
 	}
 	t := newType(TARRAY)
 	t.extra = &Array{Elem: elem, Bound: bound}
-	t.SetNotInHeap(elem.NotInHeap())
 	if elem.HasTParam() {
 		t.SetHasTParam(true)
 	}
@@ -1061,17 +1060,6 @@
 		base.Fatalf("SetFields of %v: width previously calculated", t)
 	}
 	t.wantEtype(TSTRUCT)
-	for _, f := range fields {
-		// If type T contains a field F with a go:notinheap
-		// type, then T must also be go:notinheap. Otherwise,
-		// you could heap allocate T and then get a pointer F,
-		// which would be a heap pointer to a go:notinheap
-		// type.
-		if f.Type != nil && f.Type.NotInHeap() {
-			t.SetNotInHeap(true)
-			break
-		}
-	}
 	t.Fields().Set(fields)
 }
 
@@ -1676,7 +1664,7 @@
 }
 
 // HasPointers reports whether t contains a heap pointer.
-// Note that this function ignores pointers to go:notinheap types.
+// Note that this function ignores pointers to not-in-heap types.
 func (t *Type) HasPointers() bool {
 	return PtrDataSize(t) > 0
 }
@@ -1692,7 +1680,7 @@
 }
 
 func FakeRecv() *Field {
-	return NewField(src.NoXPos, nil, FakeRecvType())
+	return NewField(base.AutogeneratedPos, nil, FakeRecvType())
 }
 
 var (
@@ -1817,7 +1805,7 @@
 	return false
 }
 
-// NewBasic returns a new basic type of the given kind.
+// newBasic returns a new basic type of the given kind.
 func newBasic(kind Kind, obj Object) *Type {
 	t := newType(kind)
 	t.obj = obj
diff --git a/src/cmd/compile/internal/types/universe.go b/src/cmd/compile/internal/types/universe.go
index 765a9f1..4733110 100644
--- a/src/cmd/compile/internal/types/universe.go
+++ b/src/cmd/compile/internal/types/universe.go
@@ -46,12 +46,12 @@
 	}
 
 	SlicePtrOffset = 0
-	SliceLenOffset = Rnd(SlicePtrOffset+int64(PtrSize), int64(PtrSize))
-	SliceCapOffset = Rnd(SliceLenOffset+int64(PtrSize), int64(PtrSize))
-	SliceSize = Rnd(SliceCapOffset+int64(PtrSize), int64(PtrSize))
+	SliceLenOffset = RoundUp(SlicePtrOffset+int64(PtrSize), int64(PtrSize))
+	SliceCapOffset = RoundUp(SliceLenOffset+int64(PtrSize), int64(PtrSize))
+	SliceSize = RoundUp(SliceCapOffset+int64(PtrSize), int64(PtrSize))
 
 	// string is same as slice wo the cap
-	StringSize = Rnd(SliceLenOffset+int64(PtrSize), int64(PtrSize))
+	StringSize = RoundUp(SliceLenOffset+int64(PtrSize), int64(PtrSize))
 
 	for et := Kind(0); et < NTYPE; et++ {
 		SimType[et] = et
diff --git a/src/cmd/compile/internal/types2/api.go b/src/cmd/compile/internal/types2/api.go
index 94c290b..47075c4 100644
--- a/src/cmd/compile/internal/types2/api.go
+++ b/src/cmd/compile/internal/types2/api.go
@@ -24,10 +24,10 @@
 package types2
 
 import (
-	"bytes"
 	"cmd/compile/internal/syntax"
 	"fmt"
 	"go/constant"
+	"strings"
 )
 
 // An Error describes a type-checking error; it implements the error interface.
@@ -131,11 +131,6 @@
 	// If IgnoreBranchErrors is set, branch/label errors are ignored.
 	IgnoreBranchErrors bool
 
-	// If CompilerErrorMessages is set, errors are reported using
-	// cmd/compile error strings to match $GOROOT/test errors.
-	// TODO(gri) Consolidate error messages and remove this flag.
-	CompilerErrorMessages bool
-
 	// If go115UsesCgo is set, the type checker expects the
 	// _cgo_gotypes.go file generated by running cmd/cgo to be
 	// provided as a package source file. Qualified identifiers
@@ -172,6 +167,11 @@
 	// If DisableUnusedImportCheck is set, packages are not checked
 	// for unused imports.
 	DisableUnusedImportCheck bool
+
+	// If OldComparableSemantics is set, ordinary (non-type parameter)
+	// interfaces do not satisfy the comparable constraint.
+	// TODO(gri) remove this flag for Go 1.21
+	OldComparableSemantics bool
 }
 
 func srcimporter_setUsesCgo(conf *Config) {
@@ -202,6 +202,12 @@
 	// qualified identifiers are collected in the Uses map.
 	Types map[syntax.Expr]TypeAndValue
 
+	// If StoreTypesInSyntax is set, type information identical to
+	// that which would be put in the Types map, will be set in
+	// syntax.Expr.TypeAndValue (independently of whether Types
+	// is nil or not).
+	StoreTypesInSyntax bool
+
 	// Instances maps identifiers denoting generic types or functions to their
 	// type arguments and instantiated type.
 	//
@@ -281,12 +287,24 @@
 	InitOrder []*Initializer
 }
 
+func (info *Info) recordTypes() bool {
+	return info.Types != nil || info.StoreTypesInSyntax
+}
+
 // TypeOf returns the type of expression e, or nil if not found.
-// Precondition: the Types, Uses and Defs maps are populated.
+// Precondition 1: the Types map is populated or StoreTypesInSynax is set.
+// Precondition 2: Uses and Defs maps are populated.
 func (info *Info) TypeOf(e syntax.Expr) Type {
-	if t, ok := info.Types[e]; ok {
-		return t.Type
+	if info.Types != nil {
+		if t, ok := info.Types[e]; ok {
+			return t.Type
+		}
+	} else if info.StoreTypesInSyntax {
+		if tv := e.GetTypeInfo(); tv.Type != nil {
+			return tv.Type
+		}
 	}
+
 	if id, _ := e.(*syntax.Name); id != nil {
 		if obj := info.ObjectOf(id); obj != nil {
 			return obj.Type()
@@ -388,7 +406,7 @@
 }
 
 func (init *Initializer) String() string {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	for i, lhs := range init.Lhs {
 		if i > 0 {
 			buf.WriteString(", ")
@@ -429,7 +447,7 @@
 	if T.Underlying() == Typ[Invalid] {
 		return false
 	}
-	return (*Checker)(nil).newAssertableTo(V, T) == nil
+	return (*Checker)(nil).newAssertableTo(V, T)
 }
 
 // AssignableTo reports whether a value of type V is assignable to a variable
@@ -467,7 +485,15 @@
 	if V.Underlying() == Typ[Invalid] {
 		return false
 	}
-	return (*Checker)(nil).implements(V, T) == nil
+	return (*Checker)(nil).implements(V, T, false, nil)
+}
+
+// Satisfies reports whether type V satisfies the constraint T.
+//
+// The behavior of Satisfies is unspecified if V is Typ[Invalid] or an uninstantiated
+// generic type.
+func Satisfies(V Type, T *Interface) bool {
+	return (*Checker)(nil).implements(V, T, true, nil)
 }
 
 // Identical reports whether x and y are identical types.
diff --git a/src/cmd/compile/internal/types2/api_test.go b/src/cmd/compile/internal/types2/api_test.go
index f5526bb..fe84720 100644
--- a/src/cmd/compile/internal/types2/api_test.go
+++ b/src/cmd/compile/internal/types2/api_test.go
@@ -5,7 +5,6 @@
 package types2_test
 
 import (
-	"bytes"
 	"cmd/compile/internal/syntax"
 	"errors"
 	"fmt"
@@ -19,48 +18,37 @@
 	. "cmd/compile/internal/types2"
 )
 
-// brokenPkg is a source prefix for packages that are not expected to parse
-// or type-check cleanly. They are always parsed assuming that they contain
-// generic code.
-const brokenPkg = "package broken_"
-
-func parseSrc(path, src string) (*syntax.File, error) {
+func parse(path, src string) (*syntax.File, error) {
 	errh := func(error) {} // dummy error handler so that parsing continues in presence of errors
 	return syntax.Parse(syntax.NewFileBase(path), strings.NewReader(src), errh, nil, 0)
 }
 
-func pkgFor(path, source string, info *Info) (*Package, error) {
-	f, err := parseSrc(path, source)
+func mustParse(path, src string) *syntax.File {
+	f, err := parse(path, src)
 	if err != nil {
+		panic(err) // so we don't need to pass *testing.T
+	}
+	return f
+}
+
+func typecheck(path, src string, info *Info) (*Package, error) {
+	f, err := parse(path, src)
+	if f == nil { // ignore errors unless f is nil
 		return nil, err
 	}
-	conf := Config{Importer: defaultImporter()}
+	conf := Config{
+		Error:    func(err error) {}, // collect all errors
+		Importer: defaultImporter(),
+	}
 	return conf.Check(f.PkgName.Value, []*syntax.File{f}, info)
 }
 
-func mustTypecheck(t testing.TB, path, source string, info *Info) string {
-	pkg, err := pkgFor(path, source, info)
+func mustTypecheck(path, src string, info *Info) *Package {
+	pkg, err := typecheck(path, src, info)
 	if err != nil {
-		name := path
-		if pkg != nil {
-			name = "package " + pkg.Name()
-		}
-		t.Fatalf("%s: didn't type-check (%s)", name, err)
+		panic(err) // so we don't need to pass *testing.T
 	}
-	return pkg.Name()
-}
-
-func mayTypecheck(t *testing.T, path, source string, info *Info) (string, error) {
-	f, err := parseSrc(path, source)
-	if f == nil { // ignore errors unless f is nil
-		t.Fatalf("%s: unable to parse: %s", path, err)
-	}
-	conf := Config{
-		Error:    func(err error) {},
-		Importer: defaultImporter(),
-	}
-	pkg, err := conf.Check(f.PkgName.Value, []*syntax.File{f}, info)
-	return pkg.Name(), err
+	return pkg
 }
 
 func TestValuesInfo(t *testing.T) {
@@ -146,7 +134,7 @@
 		info := Info{
 			Types: make(map[syntax.Expr]TypeAndValue),
 		}
-		name := mustTypecheck(t, "ValuesInfo", test.src, &info)
+		name := mustTypecheck("ValuesInfo", test.src, &info).Name()
 
 		// look for expression
 		var expr syntax.Expr
@@ -182,6 +170,9 @@
 }
 
 func TestTypesInfo(t *testing.T) {
+	// Test sources that are not expected to typecheck must start with the broken prefix.
+	const brokenPkg = "package broken_"
+
 	var tests = []struct {
 		src  string
 		expr string // expression
@@ -358,41 +349,43 @@
 		// issue 50093
 		{`package u0a; func _[_ interface{int}]() {}`, `int`, `int`},
 		{`package u1a; func _[_ interface{~int}]() {}`, `~int`, `~int`},
-		{`package u2a; func _[_ interface{int|string}]() {}`, `int | string`, `int|string`},
-		{`package u3a; func _[_ interface{int|string|~bool}]() {}`, `int | string | ~bool`, `int|string|~bool`},
-		{`package u3a; func _[_ interface{int|string|~bool}]() {}`, `int | string`, `int|string`},
-		{`package u3a; func _[_ interface{int|string|~bool}]() {}`, `~bool`, `~bool`},
-		{`package u3a; func _[_ interface{int|string|~float64|~bool}]() {}`, `int | string | ~float64`, `int|string|~float64`},
+		{`package u2a; func _[_ interface{int | string}]() {}`, `int | string`, `int | string`},
+		{`package u3a; func _[_ interface{int | string | ~bool}]() {}`, `int | string | ~bool`, `int | string | ~bool`},
+		{`package u3a; func _[_ interface{int | string | ~bool}]() {}`, `int | string`, `int | string`},
+		{`package u3a; func _[_ interface{int | string | ~bool}]() {}`, `~bool`, `~bool`},
+		{`package u3a; func _[_ interface{int | string | ~float64|~bool}]() {}`, `int | string | ~float64`, `int | string | ~float64`},
 
 		{`package u0b; func _[_ int]() {}`, `int`, `int`},
 		{`package u1b; func _[_ ~int]() {}`, `~int`, `~int`},
-		{`package u2b; func _[_ int|string]() {}`, `int | string`, `int|string`},
-		{`package u3b; func _[_ int|string|~bool]() {}`, `int | string | ~bool`, `int|string|~bool`},
-		{`package u3b; func _[_ int|string|~bool]() {}`, `int | string`, `int|string`},
-		{`package u3b; func _[_ int|string|~bool]() {}`, `~bool`, `~bool`},
-		{`package u3b; func _[_ int|string|~float64|~bool]() {}`, `int | string | ~float64`, `int|string|~float64`},
+		{`package u2b; func _[_ int | string]() {}`, `int | string`, `int | string`},
+		{`package u3b; func _[_ int | string | ~bool]() {}`, `int | string | ~bool`, `int | string | ~bool`},
+		{`package u3b; func _[_ int | string | ~bool]() {}`, `int | string`, `int | string`},
+		{`package u3b; func _[_ int | string | ~bool]() {}`, `~bool`, `~bool`},
+		{`package u3b; func _[_ int | string | ~float64|~bool]() {}`, `int | string | ~float64`, `int | string | ~float64`},
 
 		{`package u0c; type _ interface{int}`, `int`, `int`},
 		{`package u1c; type _ interface{~int}`, `~int`, `~int`},
-		{`package u2c; type _ interface{int|string}`, `int | string`, `int|string`},
-		{`package u3c; type _ interface{int|string|~bool}`, `int | string | ~bool`, `int|string|~bool`},
-		{`package u3c; type _ interface{int|string|~bool}`, `int | string`, `int|string`},
-		{`package u3c; type _ interface{int|string|~bool}`, `~bool`, `~bool`},
-		{`package u3c; type _ interface{int|string|~float64|~bool}`, `int | string | ~float64`, `int|string|~float64`},
+		{`package u2c; type _ interface{int | string}`, `int | string`, `int | string`},
+		{`package u3c; type _ interface{int | string | ~bool}`, `int | string | ~bool`, `int | string | ~bool`},
+		{`package u3c; type _ interface{int | string | ~bool}`, `int | string`, `int | string`},
+		{`package u3c; type _ interface{int | string | ~bool}`, `~bool`, `~bool`},
+		{`package u3c; type _ interface{int | string | ~float64|~bool}`, `int | string | ~float64`, `int | string | ~float64`},
 	}
 
 	for _, test := range tests {
 		info := Info{Types: make(map[syntax.Expr]TypeAndValue)}
 		var name string
 		if strings.HasPrefix(test.src, brokenPkg) {
-			var err error
-			name, err = mayTypecheck(t, "TypesInfo", test.src, &info)
+			pkg, err := typecheck("TypesInfo", test.src, &info)
 			if err == nil {
-				t.Errorf("package %s: expected to fail but passed", name)
+				t.Errorf("package %s: expected to fail but passed", pkg.Name())
 				continue
 			}
+			if pkg != nil {
+				name = pkg.Name()
+			}
 		} else {
-			name = mustTypecheck(t, "TypesInfo", test.src, &info)
+			name = mustTypecheck("TypesInfo", test.src, &info).Name()
 		}
 
 		// look for expression type
@@ -543,22 +536,22 @@
 				{`T`, []string{`string`}, `[]string`},
 			},
 		},
+		{`package issue51803; func foo[T any](T) {}; func _() { foo[int]( /* leave arg away on purpose */ ) }`,
+			[]testInst{{`foo`, []string{`int`}, `func(int)`}},
+		},
 	}
 
 	for _, test := range tests {
 		imports := make(testImporter)
-		conf := Config{Importer: imports}
+		conf := Config{
+			Importer: imports,
+			Error:    func(error) {}, // ignore errors
+		}
 		instMap := make(map[*syntax.Name]Instance)
 		useMap := make(map[*syntax.Name]Object)
 		makePkg := func(src string) *Package {
-			f, err := parseSrc("p.go", src)
-			if err != nil {
-				t.Fatal(err)
-			}
-			pkg, err := conf.Check("", []*syntax.File{f}, &Info{Instances: instMap, Uses: useMap})
-			if err != nil {
-				t.Fatal(err)
-			}
+			f := mustParse("p.go", src)
+			pkg, _ := conf.Check("", []*syntax.File{f}, &Info{Instances: instMap, Uses: useMap})
 			imports[pkg.Name()] = pkg
 			return pkg
 		}
@@ -654,7 +647,7 @@
 		info := Info{
 			Defs: make(map[*syntax.Name]Object),
 		}
-		name := mustTypecheck(t, "DefsInfo", test.src, &info)
+		name := mustTypecheck("DefsInfo", test.src, &info).Name()
 
 		// find object
 		var def Object
@@ -719,7 +712,7 @@
 		info := Info{
 			Uses: make(map[*syntax.Name]Object),
 		}
-		name := mustTypecheck(t, "UsesInfo", test.src, &info)
+		name := mustTypecheck("UsesInfo", test.src, &info).Name()
 
 		// find object
 		var use Object
@@ -751,10 +744,7 @@
 
 func (r *N[C]) n() {  }
 `
-	f, err := parseSrc("p.go", src)
-	if err != nil {
-		t.Fatal(err)
-	}
+	f := mustParse("p.go", src)
 	info := Info{
 		Defs:       make(map[*syntax.Name]Object),
 		Uses:       make(map[*syntax.Name]Object),
@@ -862,7 +852,7 @@
 		info := Info{
 			Implicits: make(map[syntax.Node]Object),
 		}
-		name := mustTypecheck(t, "ImplicitsInfo", test.src, &info)
+		name := mustTypecheck("ImplicitsInfo", test.src, &info).Name()
 
 		// the test cases expect at most one Implicits entry
 		if len(info.Implicits) > 1 {
@@ -894,7 +884,7 @@
 }
 
 func predString(tv TypeAndValue) string {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	pred := func(b bool, s string) {
 		if b {
 			if buf.Len() > 0 {
@@ -990,7 +980,7 @@
 
 	for _, test := range tests {
 		info := Info{Types: make(map[syntax.Expr]TypeAndValue)}
-		name := mustTypecheck(t, "PredicatesInfo", test.src, &info)
+		name := mustTypecheck("PredicatesInfo", test.src, &info).Name()
 
 		// look for expression predicates
 		got := "<missing>"
@@ -1082,7 +1072,7 @@
 
 	for _, test := range tests {
 		info := Info{Scopes: make(map[syntax.Node]*Scope)}
-		name := mustTypecheck(t, "ScopesInfo", test.src, &info)
+		name := mustTypecheck("ScopesInfo", test.src, &info).Name()
 
 		// number of scopes must match
 		if len(info.Scopes) != len(test.scopes) {
@@ -1270,7 +1260,7 @@
 
 	for _, test := range tests {
 		info := Info{}
-		name := mustTypecheck(t, "InitOrderInfo", test.src, &info)
+		name := mustTypecheck("InitOrderInfo", test.src, &info).Name()
 
 		// number of initializers must match
 		if len(info.InitOrder) != len(test.inits) {
@@ -1290,16 +1280,8 @@
 }
 
 func TestMultiFileInitOrder(t *testing.T) {
-	mustParse := func(src string) *syntax.File {
-		f, err := parseSrc("main", src)
-		if err != nil {
-			t.Fatal(err)
-		}
-		return f
-	}
-
-	fileA := mustParse(`package main; var a = 1`)
-	fileB := mustParse(`package main; var b = 2`)
+	fileA := mustParse("", `package main; var a = 1`)
+	fileB := mustParse("", `package main; var b = 2`)
 
 	// The initialization order must not depend on the parse
 	// order of the files, only on the presentation order to
@@ -1336,10 +1318,7 @@
 
 	for i, src := range sources {
 		filename := fmt.Sprintf("sources%d", i)
-		f, err := parseSrc(filename, src)
-		if err != nil {
-			t.Fatal(err)
-		}
+		f := mustParse(filename, src)
 		if err := check.Files([]*syntax.File{f}); err != nil {
 			t.Error(err)
 		}
@@ -1372,10 +1351,7 @@
 	imports := make(testImporter)
 	conf := Config{Importer: imports}
 	makePkg := func(path, src string) {
-		f, err := parseSrc(path+".go", src)
-		if err != nil {
-			t.Fatal(err)
-		}
+		f := mustParse(path+".go", src)
 		pkg, err := conf.Check(path, []*syntax.File{f}, &Info{Selections: selections})
 		if err != nil {
 			t.Fatal(err)
@@ -1565,10 +1541,7 @@
 		Importer: imports,
 	}
 	makePkg := func(path, src string) {
-		f, err := parseSrc(path, src)
-		if err != nil {
-			t.Fatal(err)
-		}
+		f := mustParse(path, src)
 		pkg, _ := conf.Check(path, []*syntax.File{f}, nil) // errors logged via conf.Error
 		imports[path] = pkg
 	}
@@ -1656,11 +1629,7 @@
 	}
 
 	for _, test := range tests {
-		pkg, err := pkgFor("test", "package p;"+test.src, nil)
-		if err != nil {
-			t.Errorf("%s: incorrect test case: %s", test.src, err)
-			continue
-		}
+		pkg := mustTypecheck("test", "package p;"+test.src, nil)
 
 		obj := pkg.Scope().Lookup("a")
 		if obj == nil {
@@ -1705,10 +1674,7 @@
 type Instance = *Tree[int]
 `
 
-	f, err := parseSrc("foo.go", src)
-	if err != nil {
-		panic(err)
-	}
+	f := mustParse("foo.go", src)
 	pkg := NewPackage("pkg", f.PkgName.Value)
 	if err := NewChecker(nil, pkg, nil).Files([]*syntax.File{f}); err != nil {
 		panic(err)
@@ -1737,10 +1703,8 @@
 	conf := Config{Importer: imports}
 	var info Info
 	makePkg := func(path, src string) {
-		f, err := parseSrc(path, src)
-		if err != nil {
-			t.Fatal(err)
-		}
+		f := mustParse(path, src)
+		var err error
 		imports[path], err = conf.Check(path, []*syntax.File{f}, &info)
 		if err != nil {
 			t.Fatal(err)
@@ -1877,8 +1841,9 @@
 		{newDefined(new(Struct)), new(Struct), true},
 		{newDefined(Typ[Int]), new(Struct), false},
 		{Typ[UntypedInt], Typ[Int], true},
+		{NewSlice(Typ[Int]), NewArray(Typ[Int], 10), true},
+		{NewSlice(Typ[Int]), NewArray(Typ[Uint], 10), false},
 		{NewSlice(Typ[Int]), NewPointer(NewArray(Typ[Int], 10)), true},
-		{NewSlice(Typ[Int]), NewArray(Typ[Int], 10), false},
 		{NewSlice(Typ[Int]), NewPointer(NewArray(Typ[Uint], 10)), false},
 		// Untyped string values are not permitted by the spec, so the behavior below is undefined.
 		{Typ[UntypedString], Typ[String], true},
@@ -1946,11 +1911,7 @@
 	}
 
 	for _, test := range tests {
-		pkg, err := pkgFor("test", "package p;"+test.src, nil)
-		if err != nil {
-			t.Errorf("%s: incorrect test case: %s", test.src, err)
-			continue
-		}
+		pkg := mustTypecheck("test", "package p;"+test.src, nil)
 		X := pkg.Scope().Lookup("X")
 		Y := pkg.Scope().Lookup("Y")
 		if X == nil || Y == nil {
@@ -2023,10 +1984,7 @@
 
 func TestIssue15305(t *testing.T) {
 	const src = "package p; func f() int16; var _ = f(undef)"
-	f, err := parseSrc("issue15305.go", src)
-	if err != nil {
-		t.Fatal(err)
-	}
+	f := mustParse("issue15305.go", src)
 	conf := Config{
 		Error: func(err error) {}, // allow errors
 	}
@@ -2061,20 +2019,14 @@
 		{`struct{}{}`, `struct{}`},
 		{`struct{x, y int; z complex128}{}`, `struct{x int; y int; z complex128}`},
 	} {
-		f, err := parseSrc(test.lit, "package p; var _ = "+test.lit)
-		if err != nil {
-			t.Fatalf("%s: %v", test.lit, err)
-		}
-
-		info := &Info{
-			Types: make(map[syntax.Expr]TypeAndValue),
-		}
-		if _, err = new(Config).Check("p", []*syntax.File{f}, info); err != nil {
+		f := mustParse(test.lit, "package p; var _ = "+test.lit)
+		types := make(map[syntax.Expr]TypeAndValue)
+		if _, err := new(Config).Check("p", []*syntax.File{f}, &Info{Types: types}); err != nil {
 			t.Fatalf("%s: %v", test.lit, err)
 		}
 
 		cmptype := func(x syntax.Expr, want string) {
-			tv, ok := info.Types[x]
+			tv, ok := types[x]
 			if !ok {
 				t.Errorf("%s: no Types entry found", test.lit)
 				return
@@ -2121,15 +2073,12 @@
 func f(x int) { y := x; print(y) }
 `
 
-	f, err := parseSrc("src", src)
-	if err != nil {
-		t.Fatal(err)
-	}
+	f := mustParse("src", src)
 
 	info := &Info{
 		Defs: make(map[*syntax.Name]Object),
 	}
-	if _, err = new(Config).Check("p", []*syntax.File{f}, info); err != nil {
+	if _, err := new(Config).Check("p", []*syntax.File{f}, info); err != nil {
 		t.Fatal(err)
 	}
 
@@ -2182,10 +2131,7 @@
 var v T = c
 func f(x T) T { return foo.F(x) }
 `
-	f, err := parseSrc("src", src)
-	if err != nil {
-		t.Fatal(err)
-	}
+	f := mustParse("src", src)
 	files := []*syntax.File{f}
 
 	// type-check using all possible importers
@@ -2240,10 +2186,7 @@
 func TestInstantiate(t *testing.T) {
 	// eventually we like more tests but this is a start
 	const src = "package p; type T[P any] *T[P]"
-	pkg, err := pkgFor(".", src, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
+	pkg := mustTypecheck(".", src, nil)
 
 	// type T should have one type parameter
 	T := pkg.Scope().Lookup("T").Type().(*Named)
@@ -2278,14 +2221,11 @@
 
 	for _, test := range tests {
 		src := "package p; " + test.src
-		pkg, err := pkgFor(".", src, nil)
-		if err != nil {
-			t.Fatal(err)
-		}
+		pkg := mustTypecheck(".", src, nil)
 
 		T := pkg.Scope().Lookup("T").Type().(*Named)
 
-		_, err = Instantiate(nil, T, test.targs, true)
+		_, err := Instantiate(nil, T, test.targs, true)
 		if err == nil {
 			t.Fatalf("Instantiate(%v, %v) returned nil error, want non-nil", T, test.targs)
 		}
@@ -2319,10 +2259,7 @@
 	imports := make(testImporter)
 	conf := Config{Importer: imports}
 	makePkg := func(src string) {
-		f, err := parseSrc("", src)
-		if err != nil {
-			t.Fatal(err)
-		}
+		f := mustParse("", src)
 		name := f.PkgName.Value
 		pkg, err := conf.Check(name, []*syntax.File{f}, nil)
 		if err != nil {
@@ -2378,10 +2315,7 @@
 	info := &Info{
 		Defs: make(map[*syntax.Name]Object),
 	}
-	f, err := parseSrc("p.go", src)
-	if err != nil {
-		t.Fatal(err)
-	}
+	f := mustParse("p.go", src)
 	conf := Config{}
 	pkg, err := conf.Check(f.PkgName.Value, []*syntax.File{f}, info)
 	if err != nil {
@@ -2512,10 +2446,7 @@
 type Bad Bad // invalid type
 `
 
-	f, err := parseSrc("p.go", src)
-	if err != nil {
-		t.Fatal(err)
-	}
+	f := mustParse("p.go", src)
 	conf := Config{Error: func(error) {}}
 	pkg, _ := conf.Check(f.PkgName.Value, []*syntax.File{f}, nil)
 
@@ -2610,10 +2541,7 @@
 func (V4) M()
 `
 
-	pkg, err := pkgFor("p.go", src, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
+	pkg := mustTypecheck("p.go", src, nil)
 
 	T := pkg.Scope().Lookup("T").Type().Underlying().(*Interface)
 	lookup := func(name string) (*Func, bool) {
diff --git a/src/cmd/compile/internal/types2/assignments.go b/src/cmd/compile/internal/types2/assignments.go
index f766c0b..73c126c 100644
--- a/src/cmd/compile/internal/types2/assignments.go
+++ b/src/cmd/compile/internal/types2/assignments.go
@@ -9,6 +9,7 @@
 import (
 	"cmd/compile/internal/syntax"
 	"fmt"
+	. "internal/types/errors"
 	"strings"
 )
 
@@ -27,7 +28,8 @@
 		// ok
 	default:
 		// we may get here because of other problems (issue #39634, crash 12)
-		check.errorf(x, "cannot assign %s to %s in %s", x, T, context)
+		// TODO(gri) do we need a new "generic" error code here?
+		check.errorf(x, IncompatibleAssign, "cannot assign %s to %s in %s", x, T, context)
 		return
 	}
 
@@ -40,7 +42,7 @@
 		// complex, or string constant."
 		if x.isNil() {
 			if T == nil {
-				check.errorf(x, "use of untyped nil in %s", context)
+				check.errorf(x, UntypedNilUse, "use of untyped nil in %s", context)
 				x.mode = invalid
 				return
 			}
@@ -51,12 +53,14 @@
 		if code != 0 {
 			msg := check.sprintf("cannot use %s as %s value in %s", x, target, context)
 			switch code {
-			case _TruncatedFloat:
+			case TruncatedFloat:
 				msg += " (truncated)"
-			case _NumericOverflow:
+			case NumericOverflow:
 				msg += " (overflows)"
+			default:
+				code = IncompatibleAssign
 			}
-			check.error(x, msg)
+			check.error(x, code, msg)
 			x.mode = invalid
 			return
 		}
@@ -73,7 +77,7 @@
 
 	// A generic (non-instantiated) function value cannot be assigned to a variable.
 	if sig, _ := under(x.typ).(*Signature); sig != nil && sig.TypeParams().Len() > 0 {
-		check.errorf(x, "cannot use generic function %s without instantiation in %s", x, context)
+		check.errorf(x, WrongTypeArgCount, "cannot use generic function %s without instantiation in %s", x, context)
 	}
 
 	// spec: "If a left-hand side is the blank identifier, any typed or
@@ -83,20 +87,12 @@
 		return
 	}
 
-	reason := ""
-	if ok, _ := x.assignableTo(check, T, &reason); !ok {
-		if check.conf.CompilerErrorMessages {
-			if reason != "" {
-				check.errorf(x, "cannot use %s as type %s in %s:\n\t%s", x, T, context, reason)
-			} else {
-				check.errorf(x, "cannot use %s as type %s in %s", x, T, context)
-			}
+	cause := ""
+	if ok, code := x.assignableTo(check, T, &cause); !ok {
+		if cause != "" {
+			check.errorf(x, code, "cannot use %s as %s value in %s: %s", x, T, context, cause)
 		} else {
-			if reason != "" {
-				check.errorf(x, "cannot use %s as %s value in %s: %s", x, T, context, reason)
-			} else {
-				check.errorf(x, "cannot use %s as %s value in %s", x, T, context)
-			}
+			check.errorf(x, code, "cannot use %s as %s value in %s", x, T, context)
 		}
 		x.mode = invalid
 	}
@@ -112,7 +108,7 @@
 
 	// rhs must be a constant
 	if x.mode != constant_ {
-		check.errorf(x, "%s is not constant", x)
+		check.errorf(x, InvalidConstInit, "%s is not constant", x)
 		if lhs.typ == nil {
 			lhs.typ = Typ[Invalid]
 		}
@@ -140,7 +136,7 @@
 		}
 		// Note: This was reverted in go/types (https://golang.org/cl/292751).
 		// TODO(gri): decide what to do (also affects test/run.go exclusion list)
-		lhs.used = true // avoid follow-on "declared but not used" errors
+		lhs.used = true // avoid follow-on "declared and not used" errors
 		return nil
 	}
 
@@ -150,7 +146,7 @@
 		if isUntyped(typ) {
 			// convert untyped types to default types
 			if typ == Typ[UntypedNil] {
-				check.errorf(x, "use of untyped nil in %s", context)
+				check.errorf(x, UntypedNilUse, "use of untyped nil in %s", context)
 				lhs.typ = Typ[Invalid]
 				return nil
 			}
@@ -161,7 +157,7 @@
 
 	check.assignment(x, lhs.typ, context)
 	if x.mode == invalid {
-		lhs.used = true // avoid follow-on "declared but not used" errors
+		lhs.used = true // avoid follow-on "declared and not used" errors
 		return nil
 	}
 
@@ -226,11 +222,11 @@
 			var op operand
 			check.expr(&op, sel.X)
 			if op.mode == mapindex {
-				check.errorf(&z, "cannot assign to struct field %s in map", syntax.String(z.expr))
+				check.errorf(&z, UnaddressableFieldAssign, "cannot assign to struct field %s in map", syntax.String(z.expr))
 				return nil
 			}
 		}
-		check.errorf(&z, "cannot assign to %s", &z)
+		check.errorf(&z, UnassignableOperand, "cannot assign to %s", &z)
 		return nil
 	}
 
@@ -308,11 +304,11 @@
 
 	if len(rhs) == 1 {
 		if call, _ := unparen(rhs0).(*syntax.CallExpr); call != nil {
-			check.errorf(rhs0, "assignment mismatch: %s but %s returns %s", vars, call.Fun, vals)
+			check.errorf(rhs0, WrongAssignCount, "assignment mismatch: %s but %s returns %s", vars, call.Fun, vals)
 			return
 		}
 	}
-	check.errorf(rhs0, "assignment mismatch: %s but %s", vars, vals)
+	check.errorf(rhs0, WrongAssignCount, "assignment mismatch: %s but %s", vars, vals)
 }
 
 // If returnStmt != nil, initVars is called to type-check the assignment
@@ -323,7 +319,7 @@
 	if len(lhs) != len(rhs) {
 		// invalidate lhs
 		for _, obj := range lhs {
-			obj.used = true // avoid declared but not used errors
+			obj.used = true // avoid declared and not used errors
 			if obj.typ == nil {
 				obj.typ = Typ[Invalid]
 			}
@@ -344,17 +340,14 @@
 				at = rhs[len(rhs)-1].expr // report at last value
 			}
 			var err error_
+			err.code = WrongResultCount
 			err.errorf(at, "%s return values", qualifier)
 			err.errorf(nopos, "have %s", check.typesSummary(operandTypes(rhs), false))
 			err.errorf(nopos, "want %s", check.typesSummary(varTypes(lhs), false))
 			check.report(&err)
 			return
 		}
-		if check.conf.CompilerErrorMessages {
-			check.assignError(orig_rhs, len(lhs), len(rhs))
-		} else {
-			check.errorf(rhs[0], "cannot initialize %d variables with %d values", len(lhs), len(rhs))
-		}
+		check.assignError(orig_rhs, len(lhs), len(rhs))
 		return
 	}
 
@@ -379,7 +372,7 @@
 		}
 	}
 
-	// avoid follow-on "declared but not used" errors if any initialization failed
+	// avoid follow-on "declared and not used" errors if any initialization failed
 	if !ok {
 		for _, lhs := range lhs {
 			lhs.used = true
@@ -398,11 +391,7 @@
 				return
 			}
 		}
-		if check.conf.CompilerErrorMessages {
-			check.assignError(orig_rhs, len(lhs), len(rhs))
-		} else {
-			check.errorf(rhs[0], "cannot assign %d values to %d variables", len(rhs), len(lhs))
-		}
+		check.assignError(orig_rhs, len(lhs), len(rhs))
 		return
 	}
 
@@ -422,7 +411,7 @@
 		}
 	}
 
-	// avoid follow-on "declared but not used" errors if any assignment failed
+	// avoid follow-on "declared and not used" errors if any assignment failed
 	if !ok {
 		// don't call check.use to avoid re-evaluation of the lhs expressions
 		for _, lhs := range lhs {
@@ -466,7 +455,7 @@
 		ident, _ := lhs.(*syntax.Name)
 		if ident == nil {
 			check.use(lhs)
-			check.errorf(lhs, "non-name %s on left side of :=", lhs)
+			check.errorf(lhs, BadDecl, "non-name %s on left side of :=", lhs)
 			hasErr = true
 			continue
 		}
@@ -474,7 +463,7 @@
 		name := ident.Value
 		if name != "_" {
 			if seen[name] {
-				check.errorf(lhs, "%s repeated on left side of :=", lhs)
+				check.errorf(lhs, RepeatedDecl, "%s repeated on left side of :=", lhs)
 				hasErr = true
 				continue
 			}
@@ -491,7 +480,7 @@
 			if obj, _ := alt.(*Var); obj != nil {
 				lhsVars[i] = obj
 			} else {
-				check.errorf(lhs, "cannot assign to %s", lhs)
+				check.errorf(lhs, UnassignableOperand, "cannot assign to %s", lhs)
 				hasErr = true
 			}
 			continue
@@ -519,7 +508,7 @@
 	check.processDelayed(top)
 
 	if len(newVars) == 0 && !hasErr {
-		check.softErrorf(pos, "no new variables on left side of :=")
+		check.softErrorf(pos, NoNewVar, "no new variables on left side of :=")
 		return
 	}
 
diff --git a/src/cmd/compile/internal/types2/builtins.go b/src/cmd/compile/internal/types2/builtins.go
index b504c2b..531e41d 100644
--- a/src/cmd/compile/internal/types2/builtins.go
+++ b/src/cmd/compile/internal/types2/builtins.go
@@ -10,6 +10,7 @@
 	"cmd/compile/internal/syntax"
 	"go/constant"
 	"go/token"
+	. "internal/types/errors"
 )
 
 // builtin type-checks a call to the built-in specified by id and
@@ -21,7 +22,7 @@
 	bin := predeclaredFuncs[id]
 	if call.HasDots && id != _Append {
 		//check.errorf(call.Ellipsis, invalidOp + "invalid use of ... with built-in %s", bin.name)
-		check.errorf(call, invalidOp+"invalid use of ... with built-in %s", bin.name)
+		check.errorf(call, InvalidDotDotDot, invalidOp+"invalid use of ... with built-in %s", bin.name)
 		check.use(call.ArgList...)
 		return
 	}
@@ -67,7 +68,7 @@
 			msg = "too many"
 		}
 		if msg != "" {
-			check.errorf(call, invalidOp+"%s arguments for %v (expected %d, found %d)", msg, call, bin.nargs, nargs)
+			check.errorf(call, WrongArgCount, invalidOp+"%s arguments for %v (expected %d, found %d)", msg, call, bin.nargs, nargs)
 			return
 		}
 	}
@@ -98,7 +99,7 @@
 				cause = check.sprintf("have %s", x)
 			}
 			// don't use invalidArg prefix here as it would repeat "argument" in the error message
-			check.errorf(x, "first argument to append must be a slice; %s", cause)
+			check.errorf(x, InvalidAppend, "first argument to append must be a slice; %s", cause)
 			return
 		}
 
@@ -115,7 +116,7 @@
 					return
 				}
 				if t := coreString(x.typ); t != nil && isString(t) {
-					if check.Types != nil {
+					if check.recordTypes() {
 						sig := makeSig(S, S, x.typ)
 						sig.variadic = true
 						check.recordBuiltinType(call.Fun, sig)
@@ -147,7 +148,7 @@
 
 		x.mode = value
 		x.typ = S
-		if check.Types != nil {
+		if check.recordTypes() {
 			check.recordBuiltinType(call.Fun, sig)
 		}
 
@@ -214,12 +215,16 @@
 		}
 
 		if mode == invalid && under(x.typ) != Typ[Invalid] {
-			check.errorf(x, invalidArg+"%s for %s", x, bin.name)
+			code := InvalidCap
+			if id == _Len {
+				code = InvalidLen
+			}
+			check.errorf(x, code, invalidArg+"%s for %s", x, bin.name)
 			return
 		}
 
 		// record the signature before changing x.typ
-		if check.Types != nil && mode != constant_ {
+		if check.recordTypes() && mode != constant_ {
 			check.recordBuiltinType(call.Fun, makeSig(Typ[Int], x.typ))
 		}
 
@@ -227,16 +232,43 @@
 		x.typ = Typ[Int]
 		x.val = val
 
+	case _Clear:
+		// clear(m)
+		if !check.allowVersion(check.pkg, 1, 21) {
+			check.versionErrorf(call.Fun, "go1.21", "clear")
+			return
+		}
+
+		if !underIs(x.typ, func(u Type) bool {
+			switch u := u.(type) {
+			case *Map, *Slice:
+				return true
+			case *Pointer:
+				if _, ok := under(u.base).(*Array); ok {
+					return true
+				}
+			}
+			check.errorf(x, InvalidClear, invalidArg+"cannot clear %s: argument must be (or constrained by) map, slice, or array pointer", x)
+			return false
+		}) {
+			return
+		}
+
+		x.mode = novalue
+		if check.recordTypes() {
+			check.recordBuiltinType(call.Fun, makeSig(nil, x.typ))
+		}
+
 	case _Close:
 		// close(c)
 		if !underIs(x.typ, func(u Type) bool {
 			uch, _ := u.(*Chan)
 			if uch == nil {
-				check.errorf(x, invalidOp+"cannot close non-channel %s", x)
+				check.errorf(x, InvalidClose, invalidOp+"cannot close non-channel %s", x)
 				return false
 			}
 			if uch.dir == RecvOnly {
-				check.errorf(x, invalidOp+"cannot close receive-only channel %s", x)
+				check.errorf(x, InvalidClose, invalidOp+"cannot close receive-only channel %s", x)
 				return false
 			}
 			return true
@@ -244,7 +276,7 @@
 			return
 		}
 		x.mode = novalue
-		if check.Types != nil {
+		if check.recordTypes() {
 			check.recordBuiltinType(call.Fun, makeSig(nil, x.typ))
 		}
 
@@ -303,7 +335,7 @@
 
 		// both argument types must be identical
 		if !Identical(x.typ, y.typ) {
-			check.errorf(x, invalidOp+"%v (mismatched types %s and %s)", call, x.typ, y.typ)
+			check.errorf(x, InvalidComplex, invalidOp+"%v (mismatched types %s and %s)", call, x.typ, y.typ)
 			return
 		}
 
@@ -325,7 +357,7 @@
 		}
 		resTyp := check.applyTypeFunc(f, x, id)
 		if resTyp == nil {
-			check.errorf(x, invalidArg+"arguments have type %s, expected floating-point", x.typ)
+			check.errorf(x, InvalidComplex, invalidArg+"arguments have type %s, expected floating-point", x.typ)
 			return
 		}
 
@@ -336,7 +368,7 @@
 			x.mode = value
 		}
 
-		if check.Types != nil && x.mode != constant_ {
+		if check.recordTypes() && x.mode != constant_ {
 			check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ, x.typ))
 		}
 
@@ -358,16 +390,16 @@
 		src, _ := src0.(*Slice)
 
 		if dst == nil || src == nil {
-			check.errorf(x, invalidArg+"copy expects slice arguments; found %s and %s", x, &y)
+			check.errorf(x, InvalidCopy, invalidArg+"copy expects slice arguments; found %s and %s", x, &y)
 			return
 		}
 
 		if !Identical(dst.elem, src.elem) {
-			check.errorf(x, invalidArg+"arguments to copy %s and %s have different element types %s and %s", x, &y, dst.elem, src.elem)
+			check.errorf(x, InvalidCopy, invalidArg+"arguments to copy %s and %s have different element types %s and %s", x, &y, dst.elem, src.elem)
 			return
 		}
 
-		if check.Types != nil {
+		if check.recordTypes() {
 			check.recordBuiltinType(call.Fun, makeSig(Typ[Int], x.typ, y.typ))
 		}
 		x.mode = value
@@ -382,11 +414,11 @@
 		if !underIs(map_, func(u Type) bool {
 			map_, _ := u.(*Map)
 			if map_ == nil {
-				check.errorf(x, invalidArg+"%s is not a map", x)
+				check.errorf(x, InvalidDelete, invalidArg+"%s is not a map", x)
 				return false
 			}
 			if key != nil && !Identical(map_.key, key) {
-				check.errorf(x, invalidArg+"maps of %s must have identical key types", x)
+				check.errorf(x, InvalidDelete, invalidArg+"maps of %s must have identical key types", x)
 				return false
 			}
 			key = map_.key
@@ -406,7 +438,7 @@
 		}
 
 		x.mode = novalue
-		if check.Types != nil {
+		if check.recordTypes() {
 			check.recordBuiltinType(call.Fun, makeSig(nil, map_, key))
 		}
 
@@ -453,7 +485,11 @@
 		}
 		resTyp := check.applyTypeFunc(f, x, id)
 		if resTyp == nil {
-			check.errorf(x, invalidArg+"argument has type %s, expected complex type", x.typ)
+			code := InvalidImag
+			if id == _Real {
+				code = InvalidReal
+			}
+			check.errorf(x, code, invalidArg+"argument has type %s, expected complex type", x.typ)
 			return
 		}
 
@@ -468,7 +504,7 @@
 			x.mode = value
 		}
 
-		if check.Types != nil && x.mode != constant_ {
+		if check.recordTypes() && x.mode != constant_ {
 			check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ))
 		}
 
@@ -491,14 +527,14 @@
 		case *Map, *Chan:
 			min = 1
 		case nil:
-			check.errorf(arg0, invalidArg+"cannot make %s: no core type", arg0)
+			check.errorf(arg0, InvalidMake, invalidArg+"cannot make %s: no core type", arg0)
 			return
 		default:
-			check.errorf(arg0, invalidArg+"cannot make %s; type must be slice, map, or channel", arg0)
+			check.errorf(arg0, InvalidMake, invalidArg+"cannot make %s; type must be slice, map, or channel", arg0)
 			return
 		}
 		if nargs < min || min+1 < nargs {
-			check.errorf(call, invalidOp+"%v expects %d or %d arguments; found %d", call, min, min+1, nargs)
+			check.errorf(call, WrongArgCount, invalidOp+"%v expects %d or %d arguments; found %d", call, min, min+1, nargs)
 			return
 		}
 
@@ -512,12 +548,12 @@
 			}
 		}
 		if len(sizes) == 2 && sizes[0] > sizes[1] {
-			check.error(call.ArgList[1], invalidArg+"length and capacity swapped")
+			check.error(call.ArgList[1], SwappedMakeArgs, invalidArg+"length and capacity swapped")
 			// safe to continue
 		}
 		x.mode = value
 		x.typ = T
-		if check.Types != nil {
+		if check.recordTypes() {
 			check.recordBuiltinType(call.Fun, makeSig(x.typ, types...))
 		}
 
@@ -531,7 +567,7 @@
 
 		x.mode = value
 		x.typ = &Pointer{base: T}
-		if check.Types != nil {
+		if check.recordTypes() {
 			check.recordBuiltinType(call.Fun, makeSig(x.typ, T))
 		}
 
@@ -556,7 +592,7 @@
 		}
 
 		x.mode = novalue
-		if check.Types != nil {
+		if check.recordTypes() {
 			check.recordBuiltinType(call.Fun, makeSig(nil, &emptyInterface))
 		}
 
@@ -580,7 +616,7 @@
 		}
 
 		x.mode = novalue
-		if check.Types != nil {
+		if check.recordTypes() {
 			check.recordBuiltinType(call.Fun, makeSig(nil, params...))
 		}
 
@@ -588,7 +624,7 @@
 		// recover() interface{}
 		x.mode = value
 		x.typ = &emptyInterface
-		if check.Types != nil {
+		if check.recordTypes() {
 			check.recordBuiltinType(call.Fun, makeSig(x.typ))
 		}
 
@@ -606,13 +642,13 @@
 
 		var y operand
 		arg(&y, 1)
-		if !check.isValidIndex(&y, "length", true) {
+		if !check.isValidIndex(&y, InvalidUnsafeAdd, "length", true) {
 			return
 		}
 
 		x.mode = value
 		x.typ = Typ[UnsafePointer]
-		if check.Types != nil {
+		if check.recordTypes() {
 			check.recordBuiltinType(call.Fun, makeSig(x.typ, x.typ, y.typ))
 		}
 
@@ -625,7 +661,7 @@
 
 		if hasVarSize(x.typ, nil) {
 			x.mode = value
-			if check.Types != nil {
+			if check.recordTypes() {
 				check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], x.typ))
 			}
 		} else {
@@ -641,7 +677,7 @@
 		arg0 := call.ArgList[0]
 		selx, _ := unparen(arg0).(*syntax.SelectorExpr)
 		if selx == nil {
-			check.errorf(arg0, invalidArg+"%s is not a selector expression", arg0)
+			check.errorf(arg0, BadOffsetofSyntax, invalidArg+"%s is not a selector expression", arg0)
 			check.use(arg0)
 			return
 		}
@@ -656,18 +692,18 @@
 		obj, index, indirect := LookupFieldOrMethod(base, false, check.pkg, sel)
 		switch obj.(type) {
 		case nil:
-			check.errorf(x, invalidArg+"%s has no single field %s", base, sel)
+			check.errorf(x, MissingFieldOrMethod, invalidArg+"%s has no single field %s", base, sel)
 			return
 		case *Func:
 			// TODO(gri) Using derefStructPtr may result in methods being found
 			// that don't actually exist. An error either way, but the error
 			// message is confusing. See: https://play.golang.org/p/al75v23kUy ,
 			// but go/types reports: "invalid argument: x.m is a method value".
-			check.errorf(arg0, invalidArg+"%s is a method value", arg0)
+			check.errorf(arg0, InvalidOffsetof, invalidArg+"%s is a method value", arg0)
 			return
 		}
 		if indirect {
-			check.errorf(x, invalidArg+"field %s is embedded via a pointer in %s", sel, base)
+			check.errorf(x, InvalidOffsetof, invalidArg+"field %s is embedded via a pointer in %s", sel, base)
 			return
 		}
 
@@ -689,7 +725,7 @@
 		// arranging struct fields if it wanted to.
 		if hasVarSize(base, nil) {
 			x.mode = value
-			if check.Types != nil {
+			if check.recordTypes() {
 				check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], obj.Type()))
 			}
 		} else {
@@ -708,7 +744,7 @@
 
 		if hasVarSize(x.typ, nil) {
 			x.mode = value
-			if check.Types != nil {
+			if check.recordTypes() {
 				check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], x.typ))
 			}
 		} else {
@@ -725,22 +761,83 @@
 			return
 		}
 
-		typ, _ := under(x.typ).(*Pointer)
-		if typ == nil {
-			check.errorf(x, invalidArg+"%s is not a pointer", x)
+		ptr, _ := under(x.typ).(*Pointer) // TODO(gri) should this be coreType rather than under?
+		if ptr == nil {
+			check.errorf(x, InvalidUnsafeSlice, invalidArg+"%s is not a pointer", x)
 			return
 		}
 
 		var y operand
 		arg(&y, 1)
-		if !check.isValidIndex(&y, "length", false) {
+		if !check.isValidIndex(&y, InvalidUnsafeSlice, "length", false) {
 			return
 		}
 
 		x.mode = value
-		x.typ = NewSlice(typ.base)
-		if check.Types != nil {
-			check.recordBuiltinType(call.Fun, makeSig(x.typ, typ, y.typ))
+		x.typ = NewSlice(ptr.base)
+		if check.recordTypes() {
+			check.recordBuiltinType(call.Fun, makeSig(x.typ, ptr, y.typ))
+		}
+
+	case _SliceData:
+		// unsafe.SliceData(slice []T) *T
+		if !check.allowVersion(check.pkg, 1, 20) {
+			check.versionErrorf(call.Fun, "go1.20", "unsafe.SliceData")
+			return
+		}
+
+		slice, _ := under(x.typ).(*Slice) // TODO(gri) should this be coreType rather than under?
+		if slice == nil {
+			check.errorf(x, InvalidUnsafeSliceData, invalidArg+"%s is not a slice", x)
+			return
+		}
+
+		x.mode = value
+		x.typ = NewPointer(slice.elem)
+		if check.recordTypes() {
+			check.recordBuiltinType(call.Fun, makeSig(x.typ, slice))
+		}
+
+	case _String:
+		// unsafe.String(ptr *byte, len IntegerType) string
+		if !check.allowVersion(check.pkg, 1, 20) {
+			check.versionErrorf(call.Fun, "go1.20", "unsafe.String")
+			return
+		}
+
+		check.assignment(x, NewPointer(universeByte), "argument to unsafe.String")
+		if x.mode == invalid {
+			return
+		}
+
+		var y operand
+		arg(&y, 1)
+		if !check.isValidIndex(&y, InvalidUnsafeString, "length", false) {
+			return
+		}
+
+		x.mode = value
+		x.typ = Typ[String]
+		if check.recordTypes() {
+			check.recordBuiltinType(call.Fun, makeSig(x.typ, NewPointer(universeByte), y.typ))
+		}
+
+	case _StringData:
+		// unsafe.StringData(str string) *byte
+		if !check.allowVersion(check.pkg, 1, 20) {
+			check.versionErrorf(call.Fun, "go1.20", "unsafe.StringData")
+			return
+		}
+
+		check.assignment(x, Typ[String], "argument to unsafe.StringData")
+		if x.mode == invalid {
+			return
+		}
+
+		x.mode = value
+		x.typ = NewPointer(universeByte)
+		if check.recordTypes() {
+			check.recordBuiltinType(call.Fun, makeSig(x.typ, Typ[String]))
 		}
 
 	case _Assert:
@@ -748,15 +845,15 @@
 		// The result of assert is the value of pred if there is no error.
 		// Note: assert is only available in self-test mode.
 		if x.mode != constant_ || !isBoolean(x.typ) {
-			check.errorf(x, invalidArg+"%s is not a boolean constant", x)
+			check.errorf(x, Test, invalidArg+"%s is not a boolean constant", x)
 			return
 		}
 		if x.val.Kind() != constant.Bool {
-			check.errorf(x, "internal error: value of %s should be a boolean constant", x)
+			check.errorf(x, Test, "internal error: value of %s should be a boolean constant", x)
 			return
 		}
 		if !constant.BoolVal(x.val) {
-			check.errorf(call, "%v failed", call)
+			check.errorf(call, Test, "%v failed", call)
 			// compile-time assertion failure - safe to continue
 		}
 		// result is constant - no need to record signature
@@ -854,7 +951,18 @@
 		// type parameter for the result. It's not clear what the API
 		// implications are here. Report an error for 1.18 but continue
 		// type-checking.
-		check.softErrorf(x, "%s not supported as argument to %s for go1.18 (see issue #50937)", x, predeclaredFuncs[id].name)
+		var code Code
+		switch id {
+		case _Real:
+			code = InvalidReal
+		case _Imag:
+			code = InvalidImag
+		case _Complex:
+			code = InvalidComplex
+		default:
+			unreachable()
+		}
+		check.softErrorf(x, code, "%s not supported as argument to %s for go1.18 (see issue #50937)", x, predeclaredFuncs[id].name)
 
 		// Construct a suitable new type parameter for the result type.
 		// The type parameter is placed in the current package so export/import
diff --git a/src/cmd/compile/internal/types2/builtins_test.go b/src/cmd/compile/internal/types2/builtins_test.go
index ad8873a..12c139f 100644
--- a/src/cmd/compile/internal/types2/builtins_test.go
+++ b/src/cmd/compile/internal/types2/builtins_test.go
@@ -41,6 +41,11 @@
 	{"len", `type S []byte; var s S; _ = len(s)`, `func(p.S) int`},
 	{"len", `var s P; _ = len(s)`, `func(P) int`},
 
+	{"clear", `var m map[float64]int; clear(m)`, `func(map[float64]int)`},
+	{"clear", `var s []byte; clear(s)`, `func([]byte)`},
+	{"clear", `var p *[10]int; clear(p)`, `func(*[10]int)`},
+	{"clear", `var s P; clear(s)`, `func(P)`},
+
 	{"close", `var c chan int; close(c)`, `func(chan int)`},
 	{"close", `var c chan<- chan string; close(c)`, `func(chan<- chan string)`},
 
@@ -128,6 +133,16 @@
 
 	{"Slice", `var p *int; _ = unsafe.Slice(p, 1)`, `func(*int, int) []int`},
 	{"Slice", `var p *byte; var n uintptr; _ = unsafe.Slice(p, n)`, `func(*byte, uintptr) []byte`},
+	{"Slice", `type B *byte; var b B; _ = unsafe.Slice(b, 0)`, `func(*byte, int) []byte`},
+
+	{"SliceData", "var s []int; _ = unsafe.SliceData(s)", `func([]int) *int`},
+	{"SliceData", "type S []int; var s S; _ = unsafe.SliceData(s)", `func([]int) *int`},
+
+	{"String", `var p *byte; _ = unsafe.String(p, 1)`, `func(*byte, int) string`},
+	{"String", `type B *byte; var b B; _ = unsafe.String(b, 0)`, `func(*byte, int) string`},
+
+	{"StringData", `var s string; _ = unsafe.StringData(s)`, `func(string) *byte`},
+	{"StringData", `_ = unsafe.StringData("foo")`, `func(string) *byte`},
 
 	{"assert", `assert(true)`, `invalid type`},                                    // constant
 	{"assert", `type B bool; const pred B = 1 < 2; assert(pred)`, `invalid type`}, // constant
diff --git a/src/cmd/compile/internal/types2/call.go b/src/cmd/compile/internal/types2/call.go
index b1ea691..7d660ca 100644
--- a/src/cmd/compile/internal/types2/call.go
+++ b/src/cmd/compile/internal/types2/call.go
@@ -8,6 +8,7 @@
 
 import (
 	"cmd/compile/internal/syntax"
+	. "internal/types/errors"
 	"strings"
 	"unicode"
 )
@@ -32,7 +33,7 @@
 	sig := x.typ.(*Signature)
 	got, want := len(targs), sig.TypeParams().Len()
 	if !useConstraintTypeInference && got != want || got > want {
-		check.errorf(xlist[got-1], "got %d type arguments but want %d", got, want)
+		check.errorf(xlist[got-1], WrongTypeArgCount, "got %d type arguments but want %d", got, want)
 		x.mode = invalid
 		x.expr = inst
 		return
@@ -51,10 +52,10 @@
 	assert(got == want)
 
 	// instantiate function signature
-	res := check.instantiateSignature(x.Pos(), sig, targs, xlist)
-	assert(res.TypeParams().Len() == 0) // signature is not generic anymore
-	check.recordInstance(inst.X, targs, res)
-	x.typ = res
+	sig = check.instantiateSignature(x.Pos(), sig, targs, xlist)
+	assert(sig.TypeParams().Len() == 0) // signature is not generic anymore
+	check.recordInstance(inst.X, targs, sig)
+	x.typ = sig
 	x.mode = value
 	x.expr = inst
 }
@@ -84,7 +85,7 @@
 			if i < len(xlist) {
 				pos = syntax.StartPos(xlist[i])
 			}
-			check.softErrorf(pos, "%s", err)
+			check.softErrorf(pos, InvalidTypeArg, "%s", err)
 		} else {
 			check.mono.recordInstance(check.pkg, pos, tparams, targs, xlist)
 		}
@@ -126,25 +127,25 @@
 		x.mode = invalid
 		switch n := len(call.ArgList); n {
 		case 0:
-			check.errorf(call, "missing argument in conversion to %s", T)
+			check.errorf(call, WrongArgCount, "missing argument in conversion to %s", T)
 		case 1:
 			check.expr(x, call.ArgList[0])
 			if x.mode != invalid {
 				if t, _ := under(T).(*Interface); t != nil && !isTypeParam(T) {
 					if !t.IsMethodSet() {
-						check.errorf(call, "cannot use interface %s in conversion (contains specific type constraints or is comparable)", T)
+						check.errorf(call, MisplacedConstraintIface, "cannot use interface %s in conversion (contains specific type constraints or is comparable)", T)
 						break
 					}
 				}
 				if call.HasDots {
-					check.errorf(call.ArgList[0], "invalid use of ... in type conversion to %s", T)
+					check.errorf(call.ArgList[0], BadDotDotDotSyntax, "invalid use of ... in conversion to %s", T)
 					break
 				}
 				check.conversion(x, T)
 			}
 		default:
 			check.use(call.ArgList...)
-			check.errorf(call.ArgList[n-1], "too many arguments in conversion to %s", T)
+			check.errorf(call.ArgList[n-1], WrongArgCount, "too many arguments in conversion to %s", T)
 		}
 		x.expr = call
 		return conversion
@@ -170,12 +171,15 @@
 	// a type parameter may be "called" if all types have the same signature
 	sig, _ := coreType(x.typ).(*Signature)
 	if sig == nil {
-		check.errorf(x, invalidOp+"cannot call non-function %s", x)
+		check.errorf(x, InvalidCall, invalidOp+"cannot call non-function %s", x)
 		x.mode = invalid
 		x.expr = call
 		return statement
 	}
 
+	// Capture wasGeneric before sig is potentially instantiated below.
+	wasGeneric := sig.TypeParams().Len() > 0
+
 	// evaluate type arguments, if any
 	var xlist []syntax.Expr
 	var targs []Type
@@ -193,20 +197,39 @@
 		// check number of type arguments (got) vs number of type parameters (want)
 		got, want := len(targs), sig.TypeParams().Len()
 		if got > want {
-			check.errorf(xlist[want], "got %d type arguments but want %d", got, want)
+			check.errorf(xlist[want], WrongTypeArgCount, "got %d type arguments but want %d", got, want)
 			check.use(call.ArgList...)
 			x.mode = invalid
 			x.expr = call
 			return statement
 		}
+
+		// If sig is generic and all type arguments are provided, preempt function
+		// argument type inference by explicitly instantiating the signature. This
+		// ensures that we record accurate type information for sig, even if there
+		// is an error checking its arguments (for example, if an incorrect number
+		// of arguments is supplied).
+		if got == want && want > 0 {
+			if !check.allowVersion(check.pkg, 1, 18) {
+				check.versionErrorf(inst.Pos(), "go1.18", "function instantiation")
+			}
+
+			sig = check.instantiateSignature(inst.Pos(), sig, targs, xlist)
+			assert(sig.TypeParams().Len() == 0) // signature is not generic anymore
+			check.recordInstance(inst, targs, sig)
+
+			// targs have been consumed; proceed with checking arguments of the
+			// non-generic signature.
+			targs = nil
+			xlist = nil
+		}
 	}
 
 	// evaluate arguments
 	args, _ := check.exprList(call.ArgList, false)
-	isGeneric := sig.TypeParams().Len() > 0
 	sig = check.arguments(call, sig, targs, args, xlist)
 
-	if isGeneric && sig.TypeParams().Len() == 0 {
+	if wasGeneric && sig.TypeParams().Len() == 0 {
 		// update the recorded type of call.Fun to its instantiated type
 		check.recordTypeAndValue(call.Fun, value, sig, nil)
 	}
@@ -286,7 +309,7 @@
 	for _, a := range args {
 		switch a.mode {
 		case typexpr:
-			check.errorf(a, "%s used as value", a)
+			check.errorf(a, NotAnExpr, "%s used as value", a)
 			return
 		case invalid:
 			return
@@ -315,7 +338,7 @@
 			if len(call.ArgList) == 1 && nargs > 1 {
 				// f()... is not permitted if f() is multi-valued
 				//check.errorf(call.Ellipsis, "cannot use ... with %d-valued %s", nargs, call.ArgList[0])
-				check.errorf(call, "cannot use ... with %d-valued %s", nargs, call.ArgList[0])
+				check.errorf(call, InvalidDotDotDot, "cannot use ... with %d-valued %s", nargs, call.ArgList[0])
 				return
 			}
 		} else {
@@ -343,7 +366,7 @@
 		if ddd {
 			// standard_func(a, b, c...)
 			//check.errorf(call.Ellipsis, "cannot use ... in call to non-variadic %s", call.Fun)
-			check.errorf(call, "cannot use ... in call to non-variadic %s", call.Fun)
+			check.errorf(call, NonVariadicDotDotDot, "cannot use ... in call to non-variadic %s", call.Fun)
 			return
 		}
 		// standard_func(a, b, c)
@@ -365,6 +388,7 @@
 			params = sig.params.vars
 		}
 		var err error_
+		err.code = WrongArgCount
 		err.errorf(at, "%s arguments in call to %s", qualifier, call.Fun)
 		err.errorf(nopos, "have %s", check.typesSummary(operandTypes(args), false))
 		err.errorf(nopos, "want %s", check.typesSummary(varTypes(params), sig.variadic))
@@ -423,7 +447,7 @@
 	"_Cmacro_", // function to evaluate the expanded expression
 }
 
-func (check *Checker) selector(x *operand, e *syntax.SelectorExpr, def *Named) {
+func (check *Checker) selector(x *operand, e *syntax.SelectorExpr, def *Named, wantType bool) {
 	// these must be declared before the "goto Error" statements
 	var (
 		obj      Object
@@ -464,7 +488,7 @@
 					}
 				}
 				if exp == nil {
-					check.errorf(e.Sel, "%s not declared by package C", sel)
+					check.errorf(e.Sel, UndeclaredImportedName, "undefined: %s", syntax.Expr(e)) // cast to syntax.Expr to silence vet
 					goto Error
 				}
 				check.objDecl(exp, nil)
@@ -472,16 +496,12 @@
 				exp = pkg.scope.Lookup(sel)
 				if exp == nil {
 					if !pkg.fake {
-						if check.conf.CompilerErrorMessages {
-							check.errorf(e.Sel, "undefined: %s.%s", pkg.name, sel)
-						} else {
-							check.errorf(e.Sel, "%s not declared by package %s", sel, pkg.name)
-						}
+						check.errorf(e.Sel, UndeclaredImportedName, "undefined: %s", syntax.Expr(e))
 					}
 					goto Error
 				}
 				if !exp.Exported() {
-					check.errorf(e.Sel, "%s not exported by package %s", sel, pkg.name)
+					check.errorf(e.Sel, UnexportedName, "%s not exported by package %s", sel, pkg.name)
 					// ok to continue
 				}
 			}
@@ -533,12 +553,31 @@
 			goto Error
 		}
 	case builtin:
-		check.errorf(e.Pos(), "cannot select on %s", x)
+		check.errorf(e.Pos(), UncalledBuiltin, "cannot select on %s", x)
 		goto Error
 	case invalid:
 		goto Error
 	}
 
+	// Avoid crashing when checking an invalid selector in a method declaration
+	// (i.e., where def is not set):
+	//
+	//   type S[T any] struct{}
+	//   type V = S[any]
+	//   func (fs *S[T]) M(x V.M) {}
+	//
+	// All codepaths below return a non-type expression. If we get here while
+	// expecting a type expression, it is an error.
+	//
+	// See issue #57522 for more details.
+	//
+	// TODO(rfindley): We should do better by refusing to check selectors in all cases where
+	// x.typ is incomplete.
+	if wantType {
+		check.errorf(e.Sel, NotAType, "%s is not a type", syntax.Expr(e))
+		goto Error
+	}
+
 	obj, index, indirect = LookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, sel)
 	if obj == nil {
 		// Don't report another error if the underlying type was invalid (issue #49541).
@@ -548,12 +587,16 @@
 
 		if index != nil {
 			// TODO(gri) should provide actual type where the conflict happens
-			check.errorf(e.Sel, "ambiguous selector %s.%s", x.expr, sel)
+			check.errorf(e.Sel, AmbiguousSelector, "ambiguous selector %s.%s", x.expr, sel)
 			goto Error
 		}
 
 		if indirect {
-			check.errorf(e.Sel, "cannot call pointer method %s on %s", sel, x.typ)
+			if x.mode == typexpr {
+				check.errorf(e.Sel, InvalidMethodExpr, "invalid method expression %s.%s (needs pointer receiver (*%s).%s)", x.typ, sel, x.typ, sel)
+			} else {
+				check.errorf(e.Sel, InvalidMethodExpr, "cannot call pointer method %s on %s", sel, x.typ)
+			}
 			goto Error
 		}
 
@@ -577,7 +620,7 @@
 				}
 			}
 		}
-		check.errorf(e.Sel, "%s.%s undefined (%s)", x.expr, sel, why)
+		check.errorf(e.Sel, MissingFieldOrMethod, "%s.%s undefined (%s)", x.expr, sel, why)
 		goto Error
 	}
 
@@ -591,7 +634,7 @@
 		m, _ := obj.(*Func)
 		if m == nil {
 			// TODO(gri) should check if capitalization of sel matters and provide better error message in that case
-			check.errorf(e.Sel, "%s.%s undefined (type %s has no method %s)", x.expr, sel, x.typ, sel)
+			check.errorf(e.Sel, MissingFieldOrMethod, "%s.%s undefined (type %s has no method %s)", x.expr, sel, x.typ, sel)
 			goto Error
 		}
 
@@ -599,7 +642,7 @@
 
 		sig := m.typ.(*Signature)
 		if sig.recv == nil {
-			check.error(e, "illegal cycle in method declaration")
+			check.error(e, InvalidDeclCycle, "illegal cycle in method declaration")
 			goto Error
 		}
 
diff --git a/src/cmd/compile/internal/types2/check.go b/src/cmd/compile/internal/types2/check.go
index ff8ae3b..c495293 100644
--- a/src/cmd/compile/internal/types2/check.go
+++ b/src/cmd/compile/internal/types2/check.go
@@ -11,6 +11,7 @@
 	"errors"
 	"fmt"
 	"go/constant"
+	. "internal/types/errors"
 )
 
 var nopos syntax.Pos
@@ -267,7 +268,7 @@
 			if name != "_" {
 				pkg.name = name
 			} else {
-				check.error(file.PkgName, "invalid package name _")
+				check.error(file.PkgName, BlankPkgName, "invalid package name _")
 			}
 			fallthrough
 
@@ -275,7 +276,7 @@
 			check.files = append(check.files, file)
 
 		default:
-			check.errorf(file, "package %s; expected %s", name, pkg.name)
+			check.errorf(file, MismatchedPkgName, "package %s; expected %s", name, pkg.name)
 			// ignore this file
 		}
 	}
@@ -425,7 +426,7 @@
 }
 
 func (check *Checker) recordUntyped() {
-	if !debug && check.Types == nil {
+	if !debug && !check.recordTypes() {
 		return // nothing to do
 	}
 
@@ -453,6 +454,35 @@
 	if m := check.Types; m != nil {
 		m[x] = TypeAndValue{mode, typ, val}
 	}
+	if check.StoreTypesInSyntax {
+		tv := TypeAndValue{mode, typ, val}
+		stv := syntax.TypeAndValue{Type: typ, Value: val}
+		if tv.IsVoid() {
+			stv.SetIsVoid()
+		}
+		if tv.IsType() {
+			stv.SetIsType()
+		}
+		if tv.IsBuiltin() {
+			stv.SetIsBuiltin()
+		}
+		if tv.IsValue() {
+			stv.SetIsValue()
+		}
+		if tv.IsNil() {
+			stv.SetIsNil()
+		}
+		if tv.Addressable() {
+			stv.SetAddressable()
+		}
+		if tv.Assignable() {
+			stv.SetAssignable()
+		}
+		if tv.HasOk() {
+			stv.SetHasOk()
+		}
+		x.SetTypeInfo(stv)
+	}
 }
 
 func (check *Checker) recordBuiltinType(f syntax.Expr, sig *Signature) {
@@ -489,7 +519,25 @@
 				NewVar(pos, check.pkg, "", a[1]),
 			)
 			m[x] = tv
-			// if x is a parenthesized expression (p.X), update p.X
+			p, _ := x.(*syntax.ParenExpr)
+			if p == nil {
+				break
+			}
+			x = p.X
+		}
+	}
+	if check.StoreTypesInSyntax {
+		// Note: this loop is duplicated because the type of tv is different.
+		// Above it is types2.TypeAndValue, here it is syntax.TypeAndValue.
+		for {
+			tv := x.GetTypeInfo()
+			assert(tv.Type != nil) // should have been recorded already
+			pos := x.Pos()
+			tv.Type = NewTuple(
+				NewVar(pos, check.pkg, "", a[0]),
+				NewVar(pos, check.pkg, "", a[1]),
+			)
+			x.SetTypeInfo(tv)
 			p, _ := x.(*syntax.ParenExpr)
 			if p == nil {
 				break
diff --git a/src/cmd/compile/internal/types2/check_test.go b/src/cmd/compile/internal/types2/check_test.go
index 67540dc..c4c28cc 100644
--- a/src/cmd/compile/internal/types2/check_test.go
+++ b/src/cmd/compile/internal/types2/check_test.go
@@ -41,7 +41,6 @@
 var (
 	haltOnError  = flag.Bool("halt", false, "halt on error")
 	verifyErrors = flag.Bool("verify", false, "verify errors (rather than list them) in TestManual")
-	goVersion    = flag.String("lang", "", "Go language version (e.g. \"go1.12\")")
 )
 
 func parseFiles(t *testing.T, filenames []string, mode syntax.Mode) ([]*syntax.File, []error) {
@@ -86,7 +85,7 @@
 
 // parseFlags parses flags from the first line of the given source
 // (from src if present, or by reading from the file) if the line
-// starts with "//" (line comment) followed by "-" (possiby with
+// starts with "//" (line comment) followed by "-" (possibly with
 // spaces between). Otherwise the line is ignored.
 func parseFlags(filename string, src []byte, flags *flag.FlagSet) error {
 	// If there is no src, read from the file.
@@ -131,6 +130,7 @@
 	flags := flag.NewFlagSet("", flag.PanicOnError)
 	flags.StringVar(&conf.GoVersion, "lang", "", "")
 	flags.BoolVar(&conf.FakeImportC, "fakeImportC", false, "")
+	flags.BoolVar(&conf.OldComparableSemantics, "oldComparableSemantics", false, "")
 	if err := parseFlags(filenames[0], nil, flags); err != nil {
 		t.Fatal(err)
 	}
@@ -297,10 +297,18 @@
 
 // TODO(gri) go/types has extra TestLongConstants and TestIndexRepresentability tests
 
-func TestCheck(t *testing.T)     { DefPredeclaredTestFuncs(); testDirFiles(t, "testdata/check", 55, false) } // TODO(gri) narrow column tolerance
-func TestSpec(t *testing.T)      { testDirFiles(t, "testdata/spec", 0, false) }
-func TestExamples(t *testing.T)  { testDirFiles(t, "testdata/examples", 0, false) }
-func TestFixedbugs(t *testing.T) { testDirFiles(t, "testdata/fixedbugs", 0, false) }
+func TestCheck(t *testing.T) {
+	DefPredeclaredTestFuncs()
+	testDirFiles(t, "../../../../internal/types/testdata/check", 50, false) // TODO(gri) narrow column tolerance
+}
+func TestSpec(t *testing.T) { testDirFiles(t, "../../../../internal/types/testdata/spec", 0, false) }
+func TestExamples(t *testing.T) {
+	testDirFiles(t, "../../../../internal/types/testdata/examples", 45, false)
+} // TODO(gri) narrow column tolerance
+func TestFixedbugs(t *testing.T) {
+	testDirFiles(t, "../../../../internal/types/testdata/fixedbugs", 100, false)
+}                            // TODO(gri) narrow column tolerance
+func TestLocal(t *testing.T) { testDirFiles(t, "testdata/local", 0, false) }
 
 func testDirFiles(t *testing.T, dir string, colDelta uint, manual bool) {
 	testenv.MustHaveGoBuild(t)
diff --git a/src/cmd/compile/internal/types2/conversions.go b/src/cmd/compile/internal/types2/conversions.go
index a86645a..865b49c 100644
--- a/src/cmd/compile/internal/types2/conversions.go
+++ b/src/cmd/compile/internal/types2/conversions.go
@@ -7,8 +7,8 @@
 package types2
 
 import (
-	"fmt"
 	"go/constant"
+	. "internal/types/errors"
 	"unicode"
 )
 
@@ -58,7 +58,7 @@
 				return true
 			}
 			if !constConvertibleTo(u, nil) {
-				cause = check.sprintf("cannot convert %s to %s (in %s)", x, u, T)
+				cause = check.sprintf("cannot convert %s to type %s (in %s)", x, u, T)
 				return false
 			}
 			return true
@@ -71,22 +71,11 @@
 	}
 
 	if !ok {
-		var err error_
-		if check.conf.CompilerErrorMessages {
-			if cause != "" {
-				// Add colon at end of line if we have a following cause.
-				err.errorf(x, "cannot convert %s to type %s:", x, T)
-				err.errorf(nopos, cause)
-			} else {
-				err.errorf(x, "cannot convert %s to type %s", x, T)
-			}
+		if cause != "" {
+			check.errorf(x, InvalidConversion, "cannot convert %s to type %s: %s", x, T, cause)
 		} else {
-			err.errorf(x, "cannot convert %s to %s", x, T)
-			if cause != "" {
-				err.errorf(nopos, cause)
-			}
+			check.errorf(x, InvalidConversion, "cannot convert %s to type %s", x, T)
 		}
-		check.report(&err)
 		x.mode = invalid
 		return
 	}
@@ -188,11 +177,24 @@
 		return true
 	}
 
-	// "V a slice, T is a pointer-to-array type,
+	// "V is a slice, T is an array or pointer-to-array type,
 	// and the slice and array types have identical element types."
 	if s, _ := Vu.(*Slice); s != nil {
-		if p, _ := Tu.(*Pointer); p != nil {
-			if a, _ := under(p.Elem()).(*Array); a != nil {
+		switch a := Tu.(type) {
+		case *Array:
+			if Identical(s.Elem(), a.Elem()) {
+				if check == nil || check.allowVersion(check.pkg, 1, 20) {
+					return true
+				}
+				// check != nil
+				if cause != nil {
+					// TODO(gri) consider restructuring versionErrorf so we can use it here and below
+					*cause = "conversion of slices to arrays requires go1.20 or later"
+				}
+				return false
+			}
+		case *Pointer:
+			if a, _ := under(a.Elem()).(*Array); a != nil {
 				if Identical(s.Elem(), a.Elem()) {
 					if check == nil || check.allowVersion(check.pkg, 1, 17) {
 						return true
@@ -200,9 +202,6 @@
 					// check != nil
 					if cause != nil {
 						*cause = "conversion of slices to array pointers requires go1.17 or later"
-						if check.conf.CompilerErrorMessages {
-							*cause += fmt.Sprintf(" (-lang was set to %s; check go.mod)", check.conf.GoVersion)
-						}
 					}
 					return false
 				}
@@ -240,7 +239,7 @@
 					return false // no specific types
 				}
 				if !x.convertibleTo(check, T.typ, cause) {
-					errorf("cannot convert %s (in %s) to %s (in %s)", V.typ, Vp, T.typ, Tp)
+					errorf("cannot convert %s (in %s) to type %s (in %s)", V.typ, Vp, T.typ, Tp)
 					return false
 				}
 				return true
@@ -254,7 +253,7 @@
 			}
 			x.typ = V.typ
 			if !x.convertibleTo(check, T, cause) {
-				errorf("cannot convert %s (in %s) to %s", V.typ, Vp, T)
+				errorf("cannot convert %s (in %s) to type %s", V.typ, Vp, T)
 				return false
 			}
 			return true
@@ -265,7 +264,7 @@
 				return false // no specific types
 			}
 			if !x.convertibleTo(check, T.typ, cause) {
-				errorf("cannot convert %s to %s (in %s)", x.typ, T.typ, Tp)
+				errorf("cannot convert %s to type %s (in %s)", x.typ, T.typ, Tp)
 				return false
 			}
 			return true
diff --git a/src/cmd/compile/internal/types2/decl.go b/src/cmd/compile/internal/types2/decl.go
index 1db28fc..530a8f5 100644
--- a/src/cmd/compile/internal/types2/decl.go
+++ b/src/cmd/compile/internal/types2/decl.go
@@ -5,10 +5,10 @@
 package types2
 
 import (
-	"bytes"
 	"cmd/compile/internal/syntax"
 	"fmt"
 	"go/constant"
+	. "internal/types/errors"
 )
 
 func (err *error_) recordAltDecl(obj Object) {
@@ -28,6 +28,7 @@
 	if obj.Name() != "_" {
 		if alt := scope.Insert(obj); alt != nil {
 			var err error_
+			err.code = DuplicateDecl
 			err.errorf(obj, "%s redeclared in this block", obj.Name())
 			err.recordAltDecl(alt)
 			check.report(&err)
@@ -307,12 +308,9 @@
 	// name returns the (possibly qualified) object name.
 	// This is needed because with generic types, cycles
 	// may refer to imported types. See issue #50788.
-	// TODO(gri) Thus functionality is used elsewhere. Factor it out.
+	// TODO(gri) This functionality is used elsewhere. Factor it out.
 	name := func(obj Object) string {
-		var buf bytes.Buffer
-		writePackage(&buf, obj.Pkg(), check.qualifier)
-		buf.WriteString(obj.Name())
-		return buf.String()
+		return packagePrefix(obj.Pkg(), check.qualifier) + obj.Name()
 	}
 
 	// TODO(gri) Should we start with the last (rather than the first) object in the cycle
@@ -326,11 +324,23 @@
 	if tname != nil && tname.IsAlias() {
 		check.validAlias(tname, Typ[Invalid])
 	}
+
+	// report a more concise error for self references
+	if len(cycle) == 1 {
+		if tname != nil {
+			check.errorf(obj, InvalidDeclCycle, "invalid recursive type: %s refers to itself", objName)
+		} else {
+			check.errorf(obj, InvalidDeclCycle, "invalid cycle in declaration: %s refers to itself", objName)
+		}
+		return
+	}
+
 	var err error_
-	if tname != nil && check.conf.CompilerErrorMessages {
+	err.code = InvalidDeclCycle
+	if tname != nil {
 		err.errorf(obj, "invalid recursive type %s", objName)
 	} else {
-		err.errorf(obj, "illegal cycle in declaration of %s", objName)
+		err.errorf(obj, "invalid cycle in declaration of %s", objName)
 	}
 	for range cycle {
 		err.errorf(obj, "%s refers to", objName)
@@ -378,7 +388,7 @@
 			// don't report an error if the type is an invalid C (defined) type
 			// (issue #22090)
 			if under(t) != Typ[Invalid] {
-				check.errorf(typ, "invalid constant type %s", t)
+				check.errorf(typ, InvalidConstType, "invalid constant type %s", t)
 			}
 			obj.typ = Typ[Invalid]
 			return
@@ -505,7 +515,7 @@
 	if alias && tdecl.TParamList != nil {
 		// The parser will ensure this but we may still get an invalid AST.
 		// Complain and continue as regular type definition.
-		check.error(tdecl, "generic type cannot be alias")
+		check.error(tdecl, BadDecl, "generic type cannot be alias")
 		alias = false
 	}
 
@@ -548,7 +558,7 @@
 	// use its underlying type (like we do for any RHS in a type declaration), and its
 	// underlying type is an interface and the type declaration is well defined.
 	if isTypeParam(rhs) {
-		check.error(tdecl.Type, "cannot use a type parameter as RHS in type declaration")
+		check.error(tdecl.Type, MisplacedTypeParam, "cannot use a type parameter as RHS in type declaration")
 		named.underlying = Typ[Invalid]
 	}
 }
@@ -594,7 +604,7 @@
 				// the underlying type and thus type set of a type parameter is.
 				// But we may need some additional form of cycle detection within
 				// type parameter lists.
-				check.error(f.Type, "cannot use a type parameter as constraint")
+				check.error(f.Type, MisplacedTypeParam, "cannot use a type parameter as constraint")
 				bound = Typ[Invalid]
 			}
 		}
@@ -673,14 +683,11 @@
 		// to it must be unique."
 		assert(m.name != "_")
 		if alt := mset.insert(m); alt != nil {
-			var err error_
-			if check.conf.CompilerErrorMessages {
-				err.errorf(m.pos, "%s.%s redeclared in this block", obj.Name(), m.name)
+			if alt.Pos().IsKnown() {
+				check.errorf(m.pos, DuplicateMethod, "method %s.%s already declared at %s", obj.Name(), m.name, alt.Pos())
 			} else {
-				err.errorf(m.pos, "method %s already declared for %s", m.name, obj)
+				check.errorf(m.pos, DuplicateMethod, "method %s.%s already declared", obj.Name(), m.name)
 			}
-			err.recordAltDecl(alt)
-			check.report(&err)
 			continue
 		}
 
@@ -711,6 +718,7 @@
 					// For historical consistency, we report the primary error on the
 					// method, and the alt decl on the field.
 					var err error_
+					err.code = DuplicateFieldAndMethod
 					err.errorf(alt, "field and method with the same name %s", fld.name)
 					err.recordAltDecl(fld)
 					check.report(&err)
@@ -742,7 +750,7 @@
 	obj.color_ = saved
 
 	if len(fdecl.TParamList) > 0 && fdecl.Body == nil {
-		check.softErrorf(fdecl, "parameterized function is missing function body")
+		check.softErrorf(fdecl, BadDecl, "generic function is missing function body")
 	}
 
 	// function body must be type-checked after global declarations
@@ -887,7 +895,7 @@
 			check.pop().setColor(black)
 
 		default:
-			check.errorf(s, invalidAST+"unknown syntax.Decl node %T", s)
+			check.errorf(s, InvalidSyntaxTree, "unknown syntax.Decl node %T", s)
 		}
 	}
 }
diff --git a/src/cmd/compile/internal/types2/errorcalls_test.go b/src/cmd/compile/internal/types2/errorcalls_test.go
index 80b05f9..edf2a51 100644
--- a/src/cmd/compile/internal/types2/errorcalls_test.go
+++ b/src/cmd/compile/internal/types2/errorcalls_test.go
@@ -9,8 +9,10 @@
 	"testing"
 )
 
-// TestErrorCalls makes sure that check.errorf calls have at
-// least 3 arguments (otherwise we should be using check.error).
+const errorfMinArgCount = 4
+
+// TestErrorCalls makes sure that check.errorf calls have at least
+// errorfMinArgCount arguments (otherwise we should use check.error).
 func TestErrorCalls(t *testing.T) {
 	files, err := pkgFiles(".")
 	if err != nil {
@@ -30,11 +32,11 @@
 			if !(isName(selx.X, "check") && isName(selx.Sel, "errorf")) {
 				return false
 			}
-			// check.errorf calls should have more than 2 arguments:
-			// position, format string, and arguments to format
-			if n := len(call.ArgList); n <= 2 {
-				t.Errorf("%s: got %d arguments, want > 2", call.Pos(), n)
-				return true
+			// check.errorf calls should have at least errorfMinArgCount arguments:
+			// position, code, format string, and arguments to format
+			if n := len(call.ArgList); n < errorfMinArgCount {
+				t.Errorf("%s: got %d arguments, want at least %d", call.Pos(), n, errorfMinArgCount)
+				return false
 			}
 			return false
 		})
diff --git a/src/cmd/compile/internal/types2/errors.go b/src/cmd/compile/internal/types2/errors.go
index 2a3e88a..8bbd719 100644
--- a/src/cmd/compile/internal/types2/errors.go
+++ b/src/cmd/compile/internal/types2/errors.go
@@ -10,15 +10,12 @@
 	"bytes"
 	"cmd/compile/internal/syntax"
 	"fmt"
+	. "internal/types/errors"
 	"runtime"
 	"strconv"
 	"strings"
 )
 
-func unimplemented() {
-	panic("unimplemented")
-}
-
 func assert(p bool) {
 	if !p {
 		msg := "assertion failed"
@@ -39,6 +36,7 @@
 // To report an error_, call Checker.report.
 type error_ struct {
 	desc []errorDesc
+	code Code
 	soft bool // TODO(gri) eventually determine this from an error code
 }
 
@@ -64,7 +62,7 @@
 	if err.empty() {
 		return "no error"
 	}
-	var buf bytes.Buffer
+	var buf strings.Builder
 	for i := range err.desc {
 		p := &err.desc[i]
 		if i > 0 {
@@ -92,7 +90,7 @@
 	err.desc = append(err.desc, errorDesc{posFor(at), format, args})
 }
 
-func sprintf(qf Qualifier, debug bool, format string, args ...interface{}) string {
+func sprintf(qf Qualifier, tpSubscripts bool, format string, args ...interface{}) string {
 	for i, arg := range args {
 		switch a := arg.(type) {
 		case nil:
@@ -106,7 +104,7 @@
 		case syntax.Expr:
 			arg = syntax.String(a)
 		case []syntax.Expr:
-			var buf bytes.Buffer
+			var buf strings.Builder
 			buf.WriteByte('[')
 			for i, x := range a {
 				if i > 0 {
@@ -119,26 +117,34 @@
 		case Object:
 			arg = ObjectString(a, qf)
 		case Type:
-			arg = typeString(a, qf, debug)
+			var buf bytes.Buffer
+			w := newTypeWriter(&buf, qf)
+			w.tpSubscripts = tpSubscripts
+			w.typ(a)
+			arg = buf.String()
 		case []Type:
 			var buf bytes.Buffer
+			w := newTypeWriter(&buf, qf)
+			w.tpSubscripts = tpSubscripts
 			buf.WriteByte('[')
 			for i, x := range a {
 				if i > 0 {
 					buf.WriteString(", ")
 				}
-				buf.WriteString(typeString(x, qf, debug))
+				w.typ(x)
 			}
 			buf.WriteByte(']')
 			arg = buf.String()
 		case []*TypeParam:
 			var buf bytes.Buffer
+			w := newTypeWriter(&buf, qf)
+			w.tpSubscripts = tpSubscripts
 			buf.WriteByte('[')
 			for i, x := range a {
 				if i > 0 {
 					buf.WriteString(", ")
 				}
-				buf.WriteString(typeString(x, qf, debug)) // use typeString so we get subscripts when debugging
+				w.typ(x)
 			}
 			buf.WriteByte(']')
 			arg = buf.String()
@@ -198,7 +204,7 @@
 	if err.empty() {
 		panic("no error to report")
 	}
-	check.err(err.pos(), err.msg(check.qualifier), err.soft)
+	check.err(err.pos(), err.code, err.msg(check.qualifier), err.soft)
 }
 
 func (check *Checker) trace(pos syntax.Pos, format string, args ...interface{}) {
@@ -214,7 +220,14 @@
 	fmt.Println(sprintf(check.qualifier, true, format, args...))
 }
 
-func (check *Checker) err(at poser, msg string, soft bool) {
+func (check *Checker) err(at poser, code Code, msg string, soft bool) {
+	switch code {
+	case InvalidSyntaxTree:
+		msg = "invalid syntax tree: " + msg
+	case 0:
+		panic("no error code provided")
+	}
+
 	// Cheap trick: Don't report errors with messages containing
 	// "invalid operand" or "invalid type" as those tend to be
 	// follow-on errors which don't add useful information. Only
@@ -254,7 +267,6 @@
 }
 
 const (
-	invalidAST = "invalid AST: "
 	invalidArg = "invalid argument: "
 	invalidOp  = "invalid operation: "
 )
@@ -263,26 +275,22 @@
 	Pos() syntax.Pos
 }
 
-func (check *Checker) error(at poser, msg string) {
-	check.err(at, msg, false)
+func (check *Checker) error(at poser, code Code, msg string) {
+	check.err(at, code, msg, false)
 }
 
-func (check *Checker) errorf(at poser, format string, args ...interface{}) {
-	check.err(at, check.sprintf(format, args...), false)
+func (check *Checker) errorf(at poser, code Code, format string, args ...interface{}) {
+	check.err(at, code, check.sprintf(format, args...), false)
 }
 
-func (check *Checker) softErrorf(at poser, format string, args ...interface{}) {
-	check.err(at, check.sprintf(format, args...), true)
+func (check *Checker) softErrorf(at poser, code Code, format string, args ...interface{}) {
+	check.err(at, code, check.sprintf(format, args...), true)
 }
 
 func (check *Checker) versionErrorf(at poser, goVersion string, format string, args ...interface{}) {
 	msg := check.sprintf(format, args...)
-	if check.conf.CompilerErrorMessages {
-		msg = fmt.Sprintf("%s requires %s or later (-lang was set to %s; check go.mod)", msg, goVersion, check.conf.GoVersion)
-	} else {
-		msg = fmt.Sprintf("%s requires %s or later", msg, goVersion)
-	}
-	check.err(at, msg, true)
+	msg = fmt.Sprintf("%s requires %s or later", msg, goVersion)
+	check.err(at, UnsupportedFeature, msg, true)
 }
 
 // posFor reports the left (= start) position of at.
@@ -300,16 +308,15 @@
 
 // stripAnnotations removes internal (type) annotations from s.
 func stripAnnotations(s string) string {
-	// Would like to use strings.Builder but it's not available in Go 1.4.
-	var b bytes.Buffer
+	var buf strings.Builder
 	for _, r := range s {
 		// strip #'s and subscript digits
 		if r < '₀' || '₀'+10 <= r { // '₀' == U+2080
-			b.WriteRune(r)
+			buf.WriteRune(r)
 		}
 	}
-	if b.Len() < len(s) {
-		return b.String()
+	if buf.Len() < len(s) {
+		return buf.String()
 	}
 	return s
 }
diff --git a/src/cmd/compile/internal/types2/example_test.go b/src/cmd/compile/internal/types2/example_test.go
index 4edaad5..b89cadf 100644
--- a/src/cmd/compile/internal/types2/example_test.go
+++ b/src/cmd/compile/internal/types2/example_test.go
@@ -5,8 +5,7 @@
 // Only run where builders (build.golang.org) have
 // access to compiled packages for import.
 //
-//go:build !arm && !arm64
-// +build !arm,!arm64
+//go:build !android && !ios && !js
 
 package types2_test
 
@@ -17,7 +16,6 @@
 // from source, use golang.org/x/tools/go/loader.
 
 import (
-	"bytes"
 	"cmd/compile/internal/syntax"
 	"cmd/compile/internal/types2"
 	"fmt"
@@ -50,11 +48,7 @@
 func Unused() { {}; {{ var x int; _ = x }} } // make sure empty block scopes get printed
 `},
 	} {
-		f, err := parseSrc(file.name, file.input)
-		if err != nil {
-			log.Fatal(err)
-		}
-		files = append(files, f)
+		files = append(files, mustParse(file.name, file.input))
 	}
 
 	// Type-check a package consisting of these files.
@@ -68,7 +62,7 @@
 
 	// Print the tree of scopes.
 	// For determinism, we redact addresses.
-	var buf bytes.Buffer
+	var buf strings.Builder
 	pkg.Scope().WriteTo(&buf, 0, true)
 	rx := regexp.MustCompile(` 0x[a-fA-F0-9]*`)
 	fmt.Println(rx.ReplaceAllString(buf.String(), ""))
@@ -125,10 +119,7 @@
 	}
 	return fib(x-1) - fib(x-2)
 }`
-	f, err := parseSrc("fib.go", input)
-	if err != nil {
-		log.Fatal(err)
-	}
+	f := mustParse("fib.go", input)
 
 	// Type-check the package.
 	// We create an empty map for each kind of input
@@ -173,7 +164,7 @@
 	// fmt.Println("Types and Values of each expression:")
 	// items = nil
 	// for expr, tv := range info.Types {
-	// 	var buf bytes.Buffer
+	// 	var buf strings.Builder
 	// 	posn := expr.Pos()
 	// 	tvstr := tv.Type.String()
 	// 	if tv.Value != nil {
diff --git a/src/cmd/compile/internal/types2/expr.go b/src/cmd/compile/internal/types2/expr.go
index b11cd1e..a3abbb9 100644
--- a/src/cmd/compile/internal/types2/expr.go
+++ b/src/cmd/compile/internal/types2/expr.go
@@ -11,6 +11,7 @@
 	"fmt"
 	"go/constant"
 	"go/token"
+	. "internal/types/errors"
 	"math"
 )
 
@@ -73,11 +74,11 @@
 func (check *Checker) op(m opPredicates, x *operand, op syntax.Operator) bool {
 	if pred := m[op]; pred != nil {
 		if !pred(x.typ) {
-			check.errorf(x, invalidOp+"operator %s not defined on %s", op, x)
+			check.errorf(x, UndefinedOp, invalidOp+"operator %s not defined on %s", op, x)
 			return false
 		}
 	} else {
-		check.errorf(x, invalidAST+"unknown operator %s", op)
+		check.errorf(x, InvalidSyntaxTree, "unknown operator %s", op)
 		return false
 	}
 	return true
@@ -93,7 +94,7 @@
 		// TODO(gri) We should report exactly what went wrong. At the
 		//           moment we don't have the (go/constant) API for that.
 		//           See also TODO in go/constant/value.go.
-		check.error(opPos(x.expr), "constant result is not representable")
+		check.error(opPos(x.expr), InvalidConstVal, "constant result is not representable")
 		return
 	}
 
@@ -109,7 +110,11 @@
 	// Untyped integer values must not grow arbitrarily.
 	const prec = 512 // 512 is the constant precision
 	if x.val.Kind() == constant.Int && constant.BitLen(x.val) > prec {
-		check.errorf(opPos(x.expr), "constant %s overflow", opName(x.expr))
+		op := opName(x.expr)
+		if op != "" {
+			op += " "
+		}
+		check.errorf(opPos(x.expr), InvalidConstVal, "constant %soverflow", op)
 		x.val = constant.MakeUnknown()
 	}
 }
@@ -178,7 +183,7 @@
 		// spec: "As an exception to the addressability
 		// requirement x may also be a composite literal."
 		if _, ok := unparen(e.X).(*syntax.CompositeLit); !ok && x.mode != variable {
-			check.errorf(x, invalidOp+"cannot take address of %s", x)
+			check.errorf(x, UnaddressableOperand, invalidOp+"cannot take address of %s", x)
 			x.mode = invalid
 			return
 		}
@@ -189,18 +194,18 @@
 	case syntax.Recv:
 		u := coreType(x.typ)
 		if u == nil {
-			check.errorf(x, invalidOp+"cannot receive from %s: no core type", x)
+			check.errorf(x, InvalidReceive, invalidOp+"cannot receive from %s (no core type)", x)
 			x.mode = invalid
 			return
 		}
 		ch, _ := u.(*Chan)
 		if ch == nil {
-			check.errorf(x, invalidOp+"cannot receive from non-channel %s", x)
+			check.errorf(x, InvalidReceive, invalidOp+"cannot receive from non-channel %s", x)
 			x.mode = invalid
 			return
 		}
 		if ch.dir == SendOnly {
-			check.errorf(x, invalidOp+"cannot receive from send-only channel %s", x)
+			check.errorf(x, InvalidReceive, invalidOp+"cannot receive from send-only channel %s", x)
 			x.mode = invalid
 			return
 		}
@@ -211,7 +216,7 @@
 
 	case syntax.Tilde:
 		// Provide a better error position and message than what check.op below could do.
-		check.error(e, "cannot use ~ outside of interface or type constraint")
+		check.error(e, UndefinedOp, "cannot use ~ outside of interface or type constraint")
 		x.mode = invalid
 		return
 	}
@@ -431,30 +436,6 @@
 	return false
 }
 
-// An errorCode is a (constant) value uniquely identifing a specific error.
-type errorCode int
-
-// The following error codes are "borrowed" from go/types which codes for
-// all errors. Here we list the few codes currently needed by the various
-// conversion checking functions.
-// Eventually we will switch to reporting codes for all errors, using a
-// an error code table shared between types2 and go/types.
-const (
-	_ = errorCode(iota)
-	_TruncatedFloat
-	_NumericOverflow
-	_InvalidConstVal
-	_InvalidUntypedConversion
-
-	// The following error codes are only returned by operand.assignableTo
-	// and none of its callers use the error. Still, we keep returning the
-	// error codes to make the transition to reporting error codes all the
-	// time easier in the future.
-	_IncompatibleAssign
-	_InvalidIfaceAssign
-	_InvalidChanAssign
-)
-
 // representable checks that a constant operand is representable in the given
 // basic type.
 func (check *Checker) representable(x *operand, typ *Basic) {
@@ -472,7 +453,7 @@
 // basic type typ.
 //
 // If no such representation is possible, it returns a non-zero error code.
-func (check *Checker) representation(x *operand, typ *Basic) (constant.Value, errorCode) {
+func (check *Checker) representation(x *operand, typ *Basic) (constant.Value, Code) {
 	assert(x.mode == constant_)
 	v := x.val
 	if !representableConst(x.val, check, typ, &v) {
@@ -485,25 +466,25 @@
 			// float   -> float   : overflows
 			//
 			if !isInteger(x.typ) && isInteger(typ) {
-				return nil, _TruncatedFloat
+				return nil, TruncatedFloat
 			} else {
-				return nil, _NumericOverflow
+				return nil, NumericOverflow
 			}
 		}
-		return nil, _InvalidConstVal
+		return nil, InvalidConstVal
 	}
 	return v, 0
 }
 
-func (check *Checker) invalidConversion(code errorCode, x *operand, target Type) {
-	msg := "cannot convert %s to %s"
+func (check *Checker) invalidConversion(code Code, x *operand, target Type) {
+	msg := "cannot convert %s to type %s"
 	switch code {
-	case _TruncatedFloat:
+	case TruncatedFloat:
 		msg = "%s truncated to %s"
-	case _NumericOverflow:
+	case NumericOverflow:
 		msg = "%s overflows %s"
 	}
-	check.errorf(x, msg, x, target)
+	check.errorf(x, code, msg, x, target)
 }
 
 // updateExprType updates the type of x to typ and invokes itself
@@ -582,7 +563,7 @@
 				// see commented out code for StarExpr above
 				// TODO(gri) needs cleanup
 				if debug {
-					unimplemented()
+					panic("unimplemented")
 				}
 				return
 			}
@@ -636,11 +617,7 @@
 		// We already know from the shift check that it is representable
 		// as an integer if it is a constant.
 		if !allInteger(typ) {
-			if check.conf.CompilerErrorMessages {
-				check.errorf(x, invalidOp+"%s (shift of type %s)", parent, typ)
-			} else {
-				check.errorf(x, invalidOp+"shifted operand %s (type %s) must be integer", x, typ)
-			}
+			check.errorf(x, InvalidShiftOperand, invalidOp+"shifted operand %s (type %s) must be integer", x, typ)
 			return
 		}
 		// Even if we have an integer, if the value is a constant we
@@ -696,7 +673,7 @@
 //
 // If x is a constant operand, the returned constant.Value will be the
 // representation of x in this context.
-func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, constant.Value, errorCode) {
+func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, constant.Value, Code) {
 	if x.mode == invalid || isTyped(x.typ) || target == Typ[Invalid] {
 		return x.typ, nil, 0
 	}
@@ -710,7 +687,7 @@
 				return target, nil, 0
 			}
 		} else if xkind != tkind {
-			return nil, nil, _InvalidUntypedConversion
+			return nil, nil, InvalidUntypedConversion
 		}
 		return x.typ, nil, 0
 	}
@@ -720,7 +697,7 @@
 		if hasNil(target) {
 			return target, nil, 0
 		}
-		return nil, nil, _InvalidUntypedConversion
+		return nil, nil, InvalidUntypedConversion
 	}
 
 	switch u := under(target).(type) {
@@ -739,21 +716,21 @@
 		switch x.typ.(*Basic).kind {
 		case UntypedBool:
 			if !isBoolean(target) {
-				return nil, nil, _InvalidUntypedConversion
+				return nil, nil, InvalidUntypedConversion
 			}
 		case UntypedInt, UntypedRune, UntypedFloat, UntypedComplex:
 			if !isNumeric(target) {
-				return nil, nil, _InvalidUntypedConversion
+				return nil, nil, InvalidUntypedConversion
 			}
 		case UntypedString:
 			// Non-constant untyped string values are not permitted by the spec and
 			// should not occur during normal typechecking passes, but this path is
 			// reachable via the AssignableTo API.
 			if !isString(target) {
-				return nil, nil, _InvalidUntypedConversion
+				return nil, nil, InvalidUntypedConversion
 			}
 		default:
-			return nil, nil, _InvalidUntypedConversion
+			return nil, nil, InvalidUntypedConversion
 		}
 	case *Interface:
 		if isTypeParam(target) {
@@ -764,7 +741,7 @@
 				t, _, _ := check.implicitTypeAndValue(x, u)
 				return t != nil
 			}) {
-				return nil, nil, _InvalidUntypedConversion
+				return nil, nil, InvalidUntypedConversion
 			}
 			break
 		}
@@ -772,17 +749,23 @@
 		// (interface) type: values must have concrete dynamic types.
 		// Untyped nil was handled upfront.
 		if !u.Empty() {
-			return nil, nil, _InvalidUntypedConversion // cannot assign untyped values to non-empty interfaces
+			return nil, nil, InvalidUntypedConversion // cannot assign untyped values to non-empty interfaces
 		}
 		return Default(x.typ), nil, 0 // default type for nil is nil
 	default:
-		return nil, nil, _InvalidUntypedConversion
+		return nil, nil, InvalidUntypedConversion
 	}
 	return target, nil, 0
 }
 
 // If switchCase is true, the operator op is ignored.
 func (check *Checker) comparison(x, y *operand, op syntax.Operator, switchCase bool) {
+	// Avoid spurious errors if any of the operands has an invalid type (issue #54405).
+	if x.typ == Typ[Invalid] || y.typ == Typ[Invalid] {
+		x.mode = invalid
+		return
+	}
+
 	if switchCase {
 		op = syntax.Eql
 	}
@@ -792,6 +775,7 @@
 
 	// spec: "In any comparison, the first operand must be assignable
 	// to the type of the second operand, or vice versa."
+	code := MismatchedTypes
 	ok, _ := x.assignableTo(check, y.typ, nil)
 	if !ok {
 		ok, _ = y.assignableTo(check, x.typ, nil)
@@ -801,16 +785,12 @@
 		// know after seeing the 2nd operand whether we have
 		// a type mismatch.
 		errOp = y
-		// For now, if we're not running the compiler, use the
-		// position of x to minimize changes to existing tests.
-		if !check.conf.CompilerErrorMessages {
-			errOp = x
-		}
 		cause = check.sprintf("mismatched types %s and %s", x.typ, y.typ)
 		goto Error
 	}
 
 	// check if comparison is defined for operands
+	code = UndefinedOp
 	switch op {
 	case syntax.Eql, syntax.Neq:
 		// spec: "The equality operators == and != apply to operands that are comparable."
@@ -890,13 +870,9 @@
 		}
 	}
 	if switchCase {
-		check.errorf(x, "invalid case %s in switch on %s (%s)", x.expr, y.expr, cause) // error position always at 1st operand
+		check.errorf(x, code, "invalid case %s in switch on %s (%s)", x.expr, y.expr, cause) // error position always at 1st operand
 	} else {
-		if check.conf.CompilerErrorMessages {
-			check.errorf(errOp, invalidOp+"%s %s %s (%s)", x.expr, op, y.expr, cause)
-		} else {
-			check.errorf(errOp, invalidOp+"cannot compare %s %s %s (%s)", x.expr, op, y.expr, cause)
-		}
+		check.errorf(errOp, code, invalidOp+"%s %s %s (%s)", x.expr, op, y.expr, cause)
 	}
 	x.mode = invalid
 }
@@ -957,7 +933,7 @@
 		// as an integer. Nothing to do.
 	} else {
 		// shift has no chance
-		check.errorf(x, invalidOp+"shifted operand %s must be integer", x)
+		check.errorf(x, InvalidShiftOperand, invalidOp+"shifted operand %s must be integer", x)
 		x.mode = invalid
 		return
 	}
@@ -967,11 +943,12 @@
 
 	// Check that constants are representable by uint, but do not convert them
 	// (see also issue #47243).
+	var yval constant.Value
 	if y.mode == constant_ {
 		// Provide a good error message for negative shift counts.
-		yval := constant.ToInt(y.val) // consider -1, 1.0, but not -1.1
+		yval = constant.ToInt(y.val) // consider -1, 1.0, but not -1.1
 		if yval.Kind() == constant.Int && constant.Sign(yval) < 0 {
-			check.errorf(y, invalidOp+"negative shift count %s", y)
+			check.errorf(y, InvalidShiftCount, invalidOp+"negative shift count %s", y)
 			x.mode = invalid
 			return
 		}
@@ -990,7 +967,7 @@
 		switch {
 		case allInteger(y.typ):
 			if !allUnsigned(y.typ) && !check.allowVersion(check.pkg, 1, 13) {
-				check.errorf(y, invalidOp+"signed shift count %s requires go1.13 or later", y)
+				check.versionErrorf(y, "go1.13", invalidOp+"signed shift count %s", y)
 				x.mode = invalid
 				return
 			}
@@ -1003,7 +980,7 @@
 				return
 			}
 		default:
-			check.errorf(y, invalidOp+"shift count %s must be integer", y)
+			check.errorf(y, InvalidShiftCount, invalidOp+"shift count %s must be integer", y)
 			x.mode = invalid
 			return
 		}
@@ -1022,9 +999,9 @@
 			}
 			// rhs must be within reasonable bounds in constant shifts
 			const shiftBound = 1023 - 1 + 52 // so we can express smallestFloat64 (see issue #44057)
-			s, ok := constant.Uint64Val(y.val)
+			s, ok := constant.Uint64Val(yval)
 			if !ok || s > shiftBound {
-				check.errorf(y, invalidOp+"invalid shift count %s", y)
+				check.errorf(y, InvalidShiftCount, invalidOp+"invalid shift count %s", y)
 				x.mode = invalid
 				return
 			}
@@ -1075,7 +1052,7 @@
 
 	// non-constant shift - lhs must be an integer
 	if !allInteger(x.typ) {
-		check.errorf(x, invalidOp+"shifted operand %s must be integer", x)
+		check.errorf(x, InvalidShiftOperand, invalidOp+"shifted operand %s must be integer", x)
 		x.mode = invalid
 		return
 	}
@@ -1126,26 +1103,50 @@
 		return
 	}
 
-	// TODO(gri) make canMix more efficient - called for each binary operation
-	canMix := func(x, y *operand) bool {
+	// mayConvert reports whether the operands x and y may
+	// possibly have matching types after converting one
+	// untyped operand to the type of the other.
+	// If mayConvert returns true, we try to convert the
+	// operands to each other's types, and if that fails
+	// we report a conversion failure.
+	// If mayConvert returns false, we continue without an
+	// attempt at conversion, and if the operand types are
+	// not compatible, we report a type mismatch error.
+	mayConvert := func(x, y *operand) bool {
+		// If both operands are typed, there's no need for an implicit conversion.
+		if isTyped(x.typ) && isTyped(y.typ) {
+			return false
+		}
+		// An untyped operand may convert to its default type when paired with an empty interface
+		// TODO(gri) This should only matter for comparisons (the only binary operation that is
+		//           valid with interfaces), but in that case the assignability check should take
+		//           care of the conversion. Verify and possibly eliminate this extra test.
 		if isNonTypeParamInterface(x.typ) || isNonTypeParamInterface(y.typ) {
 			return true
 		}
+		// A boolean type can only convert to another boolean type.
 		if allBoolean(x.typ) != allBoolean(y.typ) {
 			return false
 		}
+		// A string type can only convert to another string type.
 		if allString(x.typ) != allString(y.typ) {
 			return false
 		}
-		if x.isNil() && !hasNil(y.typ) {
-			return false
+		// Untyped nil can only convert to a type that has a nil.
+		if x.isNil() {
+			return hasNil(y.typ)
 		}
-		if y.isNil() && !hasNil(x.typ) {
+		if y.isNil() {
+			return hasNil(x.typ)
+		}
+		// An untyped operand cannot convert to a pointer.
+		// TODO(gri) generalize to type parameters
+		if isPointer(x.typ) || isPointer(y.typ) {
 			return false
 		}
 		return true
 	}
-	if canMix(x, &y) {
+	if mayConvert(x, &y) {
 		check.convertUntyped(x, y.typ)
 		if x.mode == invalid {
 			return
@@ -1167,9 +1168,9 @@
 		// (otherwise we had an error reported elsewhere already)
 		if x.typ != Typ[Invalid] && y.typ != Typ[Invalid] {
 			if e != nil {
-				check.errorf(x, invalidOp+"%s (mismatched types %s and %s)", e, x.typ, y.typ)
+				check.errorf(x, MismatchedTypes, invalidOp+"%s (mismatched types %s and %s)", e, x.typ, y.typ)
 			} else {
-				check.errorf(x, invalidOp+"%s %s= %s (mismatched types %s and %s)", lhs, op, rhs, x.typ, y.typ)
+				check.errorf(x, MismatchedTypes, invalidOp+"%s %s= %s (mismatched types %s and %s)", lhs, op, rhs, x.typ, y.typ)
 			}
 		}
 		x.mode = invalid
@@ -1184,7 +1185,7 @@
 	if op == syntax.Div || op == syntax.Rem {
 		// check for zero divisor
 		if (x.mode == constant_ || allInteger(x.typ)) && y.mode == constant_ && constant.Sign(y.val) == 0 {
-			check.error(&y, invalidOp+"division by zero")
+			check.error(&y, DivByZero, invalidOp+"division by zero")
 			x.mode = invalid
 			return
 		}
@@ -1194,7 +1195,7 @@
 			re, im := constant.Real(y.val), constant.Imag(y.val)
 			re2, im2 := constant.BinaryOp(re, token.MUL, re), constant.BinaryOp(im, token.MUL, im)
 			if constant.Sign(re2) == 0 && constant.Sign(im2) == 0 {
-				check.error(&y, invalidOp+"division by zero")
+				check.error(&y, DivByZero, invalidOp+"division by zero")
 				x.mode = invalid
 				return
 			}
@@ -1277,7 +1278,7 @@
 		}
 	}
 	if what != "" {
-		check.errorf(x.expr, "cannot use generic %s %s without instantiation", what, x.expr)
+		check.errorf(x.expr, WrongTypeArgCount, "cannot use generic %s %s without instantiation", what, x.expr)
 		x.mode = invalid
 		x.typ = Typ[Invalid]
 	}
@@ -1304,7 +1305,7 @@
 	case *syntax.DotsType:
 		// dots are handled explicitly where they are legal
 		// (array composite literals and parameter lists)
-		check.error(e, "invalid use of '...'")
+		check.error(e, BadDotDotDotSyntax, "invalid use of '...'")
 		goto Error
 
 	case *syntax.BasicLit:
@@ -1325,7 +1326,7 @@
 			// allows for separators between all digits.
 			const limit = 10000
 			if len(e.Value) > limit {
-				check.errorf(e, "excessively long constant: %s... (%d chars)", e.Value[:10], len(e.Value))
+				check.errorf(e, InvalidConstVal, "excessively long constant: %s... (%d chars)", e.Value[:10], len(e.Value))
 				goto Error
 			}
 		}
@@ -1335,9 +1336,12 @@
 			// If we reach here it's because of number under-/overflow.
 			// TODO(gri) setConst (and in turn the go/constant package)
 			// should return an error describing the issue.
-			check.errorf(e, "malformed constant: %s", e.Value)
+			check.errorf(e, InvalidConstVal, "malformed constant: %s", e.Value)
 			goto Error
 		}
+		// Ensure that integer values don't overflow (issue #54280).
+		x.expr = e // make sure that check.overflow below has an error position
+		check.overflow(x)
 
 	case *syntax.FuncLit:
 		if sig, ok := check.typ(e.Type).(*Signature); ok {
@@ -1358,7 +1362,7 @@
 			x.mode = value
 			x.typ = sig
 		} else {
-			check.errorf(e, invalidAST+"invalid function literal %v", e)
+			check.errorf(e, InvalidSyntaxTree, "invalid function literal %v", e)
 			goto Error
 		}
 
@@ -1386,13 +1390,13 @@
 			typ = hint
 			base, _ = deref(coreType(typ)) // *T implies &T{}
 			if base == nil {
-				check.errorf(e, "invalid composite literal element type %s: no core type", typ)
+				check.errorf(e, InvalidLit, "invalid composite literal element type %s (no core type)", typ)
 				goto Error
 			}
 
 		default:
 			// TODO(gri) provide better error messages depending on context
-			check.error(e, "missing type in composite literal")
+			check.error(e, UntypedLit, "missing type in composite literal")
 			goto Error
 		}
 
@@ -1401,12 +1405,15 @@
 			// Prevent crash if the struct referred to is not yet set up.
 			// See analogous comment for *Array.
 			if utyp.fields == nil {
-				check.error(e, "illegal cycle in type declaration")
+				check.error(e, InvalidTypeCycle, "invalid recursive type")
 				goto Error
 			}
 			if len(e.ElemList) == 0 {
 				break
 			}
+			// Convention for error messages on invalid struct literals:
+			// we mention the struct type only if it clarifies the error
+			// (e.g., a duplicate field error doesn't need the struct type).
 			fields := utyp.fields
 			if _, ok := e.ElemList[0].(*syntax.KeyValueExpr); ok {
 				// all elements must have keys
@@ -1414,7 +1421,7 @@
 				for _, e := range e.ElemList {
 					kv, _ := e.(*syntax.KeyValueExpr)
 					if kv == nil {
-						check.error(e, "mixture of field:value and value elements in struct literal")
+						check.error(e, MixedStructLit, "mixture of field:value and value elements in struct literal")
 						continue
 					}
 					key, _ := kv.Key.(*syntax.Name)
@@ -1422,16 +1429,12 @@
 					// so we don't drop information on the floor
 					check.expr(x, kv.Value)
 					if key == nil {
-						check.errorf(kv, "invalid field name %s in struct literal", kv.Key)
+						check.errorf(kv, InvalidLitField, "invalid field name %s in struct literal", kv.Key)
 						continue
 					}
 					i := fieldIndex(utyp.fields, check.pkg, key.Value)
 					if i < 0 {
-						if check.conf.CompilerErrorMessages {
-							check.errorf(kv.Key, "unknown field '%s' in struct literal of type %s", key.Value, base)
-						} else {
-							check.errorf(kv.Key, "unknown field %s in struct literal", key.Value)
-						}
+						check.errorf(kv.Key, MissingLitField, "unknown field %s in struct literal of type %s", key.Value, base)
 						continue
 					}
 					fld := fields[i]
@@ -1440,7 +1443,7 @@
 					check.assignment(x, etyp, "struct literal")
 					// 0 <= i < len(fields)
 					if visited[i] {
-						check.errorf(kv, "duplicate field name %s in struct literal", key.Value)
+						check.errorf(kv, DuplicateLitField, "duplicate field name %s in struct literal", key.Value)
 						continue
 					}
 					visited[i] = true
@@ -1449,25 +1452,25 @@
 				// no element must have a key
 				for i, e := range e.ElemList {
 					if kv, _ := e.(*syntax.KeyValueExpr); kv != nil {
-						check.error(kv, "mixture of field:value and value elements in struct literal")
+						check.error(kv, MixedStructLit, "mixture of field:value and value elements in struct literal")
 						continue
 					}
 					check.expr(x, e)
 					if i >= len(fields) {
-						check.errorf(x, "too many values in %s{…}", base)
+						check.errorf(x, InvalidStructLit, "too many values in struct literal of type %s", base)
 						break // cannot continue
 					}
 					// i < len(fields)
 					fld := fields[i]
 					if !fld.Exported() && fld.pkg != check.pkg {
-						check.errorf(x, "implicit assignment to unexported field %s in %s literal", fld.name, typ)
+						check.errorf(x, UnexportedLitField, "implicit assignment to unexported field %s in struct literal of type %s", fld.name, base)
 						continue
 					}
 					etyp := fld.typ
 					check.assignment(x, etyp, "struct literal")
 				}
 				if len(e.ElemList) < len(fields) {
-					check.errorf(e.Rbrace, "too few values in %s{…}", base)
+					check.errorf(e.Rbrace, InvalidStructLit, "too few values in struct literal of type %s", base)
 					// ok to continue
 				}
 			}
@@ -1477,7 +1480,7 @@
 			// This is a stop-gap solution. Should use Checker.objPath to report entire
 			// path starting with earliest declaration in the source. TODO(gri) fix this.
 			if utyp.elem == nil {
-				check.error(e, "illegal cycle in type declaration")
+				check.error(e, InvalidTypeCycle, "invalid recursive type")
 				goto Error
 			}
 			n := check.indexedElts(e.ElemList, utyp.elem, utyp.len)
@@ -1504,7 +1507,7 @@
 			// Prevent crash if the slice referred to is not yet set up.
 			// See analogous comment for *Array.
 			if utyp.elem == nil {
-				check.error(e, "illegal cycle in type declaration")
+				check.error(e, InvalidTypeCycle, "invalid recursive type")
 				goto Error
 			}
 			check.indexedElts(e.ElemList, utyp.elem, -1)
@@ -1513,7 +1516,7 @@
 			// Prevent crash if the map referred to is not yet set up.
 			// See analogous comment for *Array.
 			if utyp.key == nil || utyp.elem == nil {
-				check.error(e, "illegal cycle in type declaration")
+				check.error(e, InvalidTypeCycle, "invalid recursive type")
 				goto Error
 			}
 			// If the map key type is an interface (but not a type parameter),
@@ -1524,7 +1527,7 @@
 			for _, e := range e.ElemList {
 				kv, _ := e.(*syntax.KeyValueExpr)
 				if kv == nil {
-					check.error(e, "missing key in map literal")
+					check.error(e, MissingLitKey, "missing key in map literal")
 					continue
 				}
 				check.exprWithHint(x, kv.Key, utyp.key)
@@ -1548,7 +1551,7 @@
 						visited[xkey] = nil
 					}
 					if duplicate {
-						check.errorf(x, "duplicate key %s in map literal", x.val)
+						check.errorf(x, DuplicateLitKey, "duplicate key %s in map literal", x.val)
 						continue
 					}
 				}
@@ -1570,7 +1573,7 @@
 			}
 			// if utyp is invalid, an error was reported before
 			if utyp != Typ[Invalid] {
-				check.errorf(e, "invalid composite literal type %s", typ)
+				check.errorf(e, InvalidLit, "invalid composite literal type %s", typ)
 				goto Error
 			}
 		}
@@ -1584,7 +1587,7 @@
 		return kind
 
 	case *syntax.SelectorExpr:
-		check.selector(x, e, nil)
+		check.selector(x, e, nil, false)
 
 	case *syntax.IndexExpr:
 		if check.indexExpr(x, e) {
@@ -1607,16 +1610,16 @@
 		}
 		// TODO(gri) we may want to permit type assertions on type parameter values at some point
 		if isTypeParam(x.typ) {
-			check.errorf(x, invalidOp+"cannot use type assertion on type parameter value %s", x)
+			check.errorf(x, InvalidAssert, invalidOp+"cannot use type assertion on type parameter value %s", x)
 			goto Error
 		}
 		if _, ok := under(x.typ).(*Interface); !ok {
-			check.errorf(x, invalidOp+"%s is not an interface", x)
+			check.errorf(x, InvalidAssert, invalidOp+"%s is not an interface", x)
 			goto Error
 		}
 		// x.(type) expressions are encoded via TypeSwitchGuards
 		if e.Type == nil {
-			check.error(e, invalidAST+"invalid use of AssertExpr")
+			check.error(e, InvalidSyntaxTree, "invalid use of AssertExpr")
 			goto Error
 		}
 		T := check.varType(e.Type)
@@ -1629,7 +1632,7 @@
 
 	case *syntax.TypeSwitchGuard:
 		// x.(type) expressions are handled explicitly in type switches
-		check.error(e, invalidAST+"use of .(type) outside type switch")
+		check.error(e, InvalidSyntaxTree, "use of .(type) outside type switch")
 		goto Error
 
 	case *syntax.CallExpr:
@@ -1637,7 +1640,7 @@
 
 	case *syntax.ListExpr:
 		// catch-all for unexpected expression lists
-		check.error(e, "unexpected list of expressions")
+		check.error(e, InvalidSyntaxTree, "unexpected list of expressions")
 		goto Error
 
 	// case *syntax.UnaryExpr:
@@ -1677,11 +1680,11 @@
 					if !underIs(x.typ, func(u Type) bool {
 						p, _ := u.(*Pointer)
 						if p == nil {
-							check.errorf(x, invalidOp+"cannot indirect %s", x)
+							check.errorf(x, InvalidIndirection, invalidOp+"cannot indirect %s", x)
 							return false
 						}
 						if base != nil && !Identical(p.base, base) {
-							check.errorf(x, invalidOp+"pointers of %s must have identical base types", x)
+							check.errorf(x, InvalidIndirection, invalidOp+"pointers of %s must have identical base types", x)
 							return false
 						}
 						base = p.base
@@ -1714,7 +1717,7 @@
 
 	case *syntax.KeyValueExpr:
 		// key:value expressions are handled in composite literals
-		check.error(e, invalidAST+"no key:value expected")
+		check.error(e, InvalidSyntaxTree, "no key:value expected")
 		goto Error
 
 	case *syntax.ArrayType, *syntax.SliceType, *syntax.StructType, *syntax.FuncType,
@@ -1790,14 +1793,14 @@
 		return // success
 	}
 
-	cause := check.missingMethodReason(T, x.typ, method, alt)
+	cause := check.missingMethodCause(T, x.typ, method, alt)
 
 	if typeSwitch {
-		check.errorf(e, "impossible type switch case: %s\n\t%s cannot have dynamic type %s %s", e, x, T, cause)
+		check.errorf(e, ImpossibleAssert, "impossible type switch case: %s\n\t%s cannot have dynamic type %s %s", e, x, T, cause)
 		return
 	}
 
-	check.errorf(e, "impossible type assertion: %s\n\t%s does not implement %s %s", e, T, x.typ, cause)
+	check.errorf(e, ImpossibleAssert, "impossible type assertion: %s\n\t%s does not implement %s %s", e, T, x.typ, cause)
 }
 
 // expr typechecks expression e and initializes x with the expression value.
@@ -1840,6 +1843,7 @@
 func (check *Checker) exclude(x *operand, modeset uint) {
 	if modeset&(1<<x.mode) != 0 {
 		var msg string
+		var code Code
 		switch x.mode {
 		case novalue:
 			if modeset&(1<<typexpr) != 0 {
@@ -1847,14 +1851,17 @@
 			} else {
 				msg = "%s used as value or type"
 			}
+			code = TooManyValues
 		case builtin:
 			msg = "%s must be called"
+			code = UncalledBuiltin
 		case typexpr:
 			msg = "%s is not an expression"
+			code = NotAnExpr
 		default:
 			unreachable()
 		}
-		check.errorf(x, msg, x)
+		check.errorf(x, code, msg, x)
 		x.mode = invalid
 	}
 }
@@ -1865,11 +1872,7 @@
 		// tuple types are never named - no need for underlying type below
 		if t, ok := x.typ.(*Tuple); ok {
 			assert(t.Len() != 1)
-			if check.conf.CompilerErrorMessages {
-				check.errorf(x, "multiple-value %s in single-value context", x)
-			} else {
-				check.errorf(x, "%d-valued %s where single value is expected", t.Len(), x)
-			}
+			check.errorf(x, TooManyValues, "multiple-value %s in single-value context", x)
 			x.mode = invalid
 		}
 	}
diff --git a/src/cmd/compile/internal/types2/hilbert_test.go b/src/cmd/compile/internal/types2/hilbert_test.go
index 03fea4f..391a498 100644
--- a/src/cmd/compile/internal/types2/hilbert_test.go
+++ b/src/cmd/compile/internal/types2/hilbert_test.go
@@ -6,12 +6,12 @@
 
 import (
 	"bytes"
-	"cmd/compile/internal/syntax"
 	"flag"
 	"fmt"
-	"io/ioutil"
+	"os"
 	"testing"
 
+	"cmd/compile/internal/syntax"
 	. "cmd/compile/internal/types2"
 )
 
@@ -24,7 +24,7 @@
 	// generate source
 	src := program(*H, *out)
 	if *out != "" {
-		ioutil.WriteFile(*out, src, 0666)
+		os.WriteFile(*out, src, 0666)
 		return
 	}
 
diff --git a/src/cmd/compile/internal/types2/index.go b/src/cmd/compile/internal/types2/index.go
index 37db503..9e5c4d8 100644
--- a/src/cmd/compile/internal/types2/index.go
+++ b/src/cmd/compile/internal/types2/index.go
@@ -9,6 +9,7 @@
 import (
 	"cmd/compile/internal/syntax"
 	"go/constant"
+	. "internal/types/errors"
 )
 
 // If e is a valid function instantiation, indexExpr returns true.
@@ -182,7 +183,7 @@
 	}
 
 	if !valid {
-		check.errorf(e.Pos(), invalidOp+"cannot index %s", x)
+		check.errorf(e.Pos(), NonSliceableOperand, invalidOp+"cannot index %s", x)
 		x.mode = invalid
 		return false
 	}
@@ -215,7 +216,7 @@
 	length := int64(-1) // valid if >= 0
 	switch u := coreString(x.typ).(type) {
 	case nil:
-		check.errorf(x, invalidOp+"cannot slice %s: %s has no core type", x, x.typ)
+		check.errorf(x, NonSliceableOperand, invalidOp+"cannot slice %s: %s has no core type", x, x.typ)
 		x.mode = invalid
 		return
 
@@ -226,7 +227,7 @@
 				if at == nil {
 					at = e // e.Index[2] should be present but be careful
 				}
-				check.error(at, invalidOp+"3-index slice of string")
+				check.error(at, InvalidSliceExpr, invalidOp+"3-index slice of string")
 				x.mode = invalid
 				return
 			}
@@ -245,7 +246,7 @@
 		valid = true
 		length = u.len
 		if x.mode != variable {
-			check.errorf(x, invalidOp+"%s (slice of unaddressable value)", x)
+			check.errorf(x, NonSliceableOperand, invalidOp+"%s (slice of unaddressable value)", x)
 			x.mode = invalid
 			return
 		}
@@ -264,7 +265,7 @@
 	}
 
 	if !valid {
-		check.errorf(x, invalidOp+"cannot slice %s", x)
+		check.errorf(x, NonSliceableOperand, invalidOp+"cannot slice %s", x)
 		x.mode = invalid
 		return
 	}
@@ -273,7 +274,7 @@
 
 	// spec: "Only the first index may be omitted; it defaults to 0."
 	if e.Full && (e.Index[1] == nil || e.Index[2] == nil) {
-		check.error(e, invalidAST+"2nd and 3rd index required in 3-index slice")
+		check.error(e, InvalidSyntaxTree, "2nd and 3rd index required in 3-index slice")
 		x.mode = invalid
 		return
 	}
@@ -314,7 +315,7 @@
 					// The value y corresponds to the expression e.Index[i+1+j].
 					// Because y >= 0, it must have been set from the expression
 					// when checking indices and thus e.Index[i+1+j] is not nil.
-					check.errorf(e.Index[i+1+j], "invalid slice indices: %d < %d", y, x)
+					check.errorf(e.Index[i+1+j], SwappedSliceIndices, "invalid slice indices: %d < %d", y, x)
 					break L // only report one error, ok to continue
 				}
 			}
@@ -328,16 +329,16 @@
 func (check *Checker) singleIndex(e *syntax.IndexExpr) syntax.Expr {
 	index := e.Index
 	if index == nil {
-		check.errorf(e, invalidAST+"missing index for %s", e.X)
+		check.errorf(e, InvalidSyntaxTree, "missing index for %s", e.X)
 		return nil
 	}
 	if l, _ := index.(*syntax.ListExpr); l != nil {
 		if n := len(l.ElemList); n <= 1 {
-			check.errorf(e, invalidAST+"invalid use of ListExpr for index expression %v with %d indices", e, n)
+			check.errorf(e, InvalidSyntaxTree, "invalid use of ListExpr for index expression %v with %d indices", e, n)
 			return nil
 		}
 		// len(l.ElemList) > 1
-		check.error(l.ElemList[1], invalidOp+"more than one index")
+		check.error(l.ElemList[1], InvalidIndex, invalidOp+"more than one index")
 		index = l.ElemList[0] // continue with first index
 	}
 	return index
@@ -353,7 +354,7 @@
 
 	var x operand
 	check.expr(&x, index)
-	if !check.isValidIndex(&x, "index", false) {
+	if !check.isValidIndex(&x, InvalidIndex, "index", false) {
 		return
 	}
 
@@ -368,7 +369,7 @@
 	v, ok := constant.Int64Val(x.val)
 	assert(ok)
 	if max >= 0 && v >= max {
-		check.errorf(&x, invalidArg+"index %s out of bounds [0:%d]", x.val.String(), max)
+		check.errorf(&x, InvalidIndex, invalidArg+"index %s out of bounds [0:%d]", x.val.String(), max)
 		return
 	}
 
@@ -380,7 +381,7 @@
 // index values. If allowNegative is set, a constant operand may be negative.
 // If the operand is not valid, an error is reported (using what as context)
 // and the result is false.
-func (check *Checker) isValidIndex(x *operand, what string, allowNegative bool) bool {
+func (check *Checker) isValidIndex(x *operand, code Code, what string, allowNegative bool) bool {
 	if x.mode == invalid {
 		return false
 	}
@@ -393,20 +394,20 @@
 
 	// spec: "the index x must be of integer type or an untyped constant"
 	if !allInteger(x.typ) {
-		check.errorf(x, invalidArg+"%s %s must be integer", what, x)
+		check.errorf(x, code, invalidArg+"%s %s must be integer", what, x)
 		return false
 	}
 
 	if x.mode == constant_ {
 		// spec: "a constant index must be non-negative ..."
 		if !allowNegative && constant.Sign(x.val) < 0 {
-			check.errorf(x, invalidArg+"%s %s must not be negative", what, x)
+			check.errorf(x, code, invalidArg+"%s %s must not be negative", what, x)
 			return false
 		}
 
 		// spec: "... and representable by a value of type int"
 		if !representableConst(x.val, check, Typ[Int], &x.val) {
-			check.errorf(x, invalidArg+"%s %s overflows int", what, x)
+			check.errorf(x, code, invalidArg+"%s %s overflows int", what, x)
 			return false
 		}
 	}
@@ -431,12 +432,12 @@
 					index = i
 					validIndex = true
 				} else {
-					check.errorf(e, "index %s must be integer constant", kv.Key)
+					check.errorf(e, InvalidLitIndex, "index %s must be integer constant", kv.Key)
 				}
 			}
 			eval = kv.Value
 		} else if length >= 0 && index >= length {
-			check.errorf(e, "index %d is out of bounds (>= %d)", index, length)
+			check.errorf(e, OversizeArrayLit, "index %d is out of bounds (>= %d)", index, length)
 		} else {
 			validIndex = true
 		}
@@ -444,7 +445,7 @@
 		// if we have a valid index, check for duplicate entries
 		if validIndex {
 			if visited[index] {
-				check.errorf(e, "duplicate index %d in array or slice literal", index)
+				check.errorf(e, DuplicateLitKey, "duplicate index %d in array or slice literal", index)
 			}
 			visited[index] = true
 		}
diff --git a/src/cmd/compile/internal/types2/infer.go b/src/cmd/compile/internal/types2/infer.go
index 8425cd6..5750ece 100644
--- a/src/cmd/compile/internal/types2/infer.go
+++ b/src/cmd/compile/internal/types2/infer.go
@@ -7,9 +7,10 @@
 package types2
 
 import (
-	"bytes"
 	"cmd/compile/internal/syntax"
 	"fmt"
+	. "internal/types/errors"
+	"strings"
 )
 
 const useConstraintTypeInference = true
@@ -88,34 +89,22 @@
 		//    f(p)
 		//  }
 		//
-		// We can turn the first example into the second example by renaming type
-		// parameters in the original signature to give them a new identity. As an
-		// optimization, we do this only for self-recursive calls.
-
-		// We can detect if we are in a self-recursive call by comparing the
-		// identity of the first type parameter in the current function with the
-		// first type parameter in tparams. This works because type parameters are
-		// unique to their type parameter list.
-		selfRecursive := check.sig != nil && check.sig.tparams.Len() > 0 && tparams[0] == check.sig.tparams.At(0)
-
-		if selfRecursive {
-			// In self-recursive inference, rename the type parameters with new type
-			// parameters that are the same but for their pointer identity.
-			tparams2 := make([]*TypeParam, len(tparams))
-			for i, tparam := range tparams {
-				tname := NewTypeName(tparam.Obj().Pos(), tparam.Obj().Pkg(), tparam.Obj().Name(), nil)
-				tparams2[i] = NewTypeParam(tname, nil)
-				tparams2[i].index = tparam.index // == i
-			}
-
-			renameMap := makeRenameMap(tparams, tparams2)
-			for i, tparam := range tparams {
-				tparams2[i].bound = check.subst(pos, tparam.bound, renameMap, nil, check.context())
-			}
-
-			tparams = tparams2
-			params = check.subst(pos, params, renameMap, nil, check.context()).(*Tuple)
+		// We turn the first example into the second example by renaming type
+		// parameters in the original signature to give them a new identity.
+		tparams2 := make([]*TypeParam, len(tparams))
+		for i, tparam := range tparams {
+			tname := NewTypeName(tparam.Obj().Pos(), tparam.Obj().Pkg(), tparam.Obj().Name(), nil)
+			tparams2[i] = NewTypeParam(tname, nil)
+			tparams2[i].index = tparam.index // == i
 		}
+
+		renameMap := makeRenameMap(tparams, tparams2)
+		for i, tparam := range tparams {
+			tparams2[i].bound = check.subst(pos, tparam.bound, renameMap, nil, check.context())
+		}
+
+		tparams = tparams2
+		params = check.subst(pos, params, renameMap, nil, check.context()).(*Tuple)
 	}
 
 	// If we have more than 2 arguments, we may have arguments with named and unnamed types.
@@ -216,16 +205,20 @@
 				}
 			}
 			if allFailed {
-				check.errorf(arg, "%s %s of %s does not match %s (cannot infer %s)", kind, targ, arg.expr, tpar, typeParamsString(tparams))
+				check.errorf(arg, CannotInferTypeArgs, "%s %s of %s does not match %s (cannot infer %s)", kind, targ, arg.expr, tpar, typeParamsString(tparams))
 				return
 			}
 		}
 		smap := makeSubstMap(tparams, targs)
 		inferred := check.subst(arg.Pos(), tpar, smap, nil, check.context())
+		// _CannotInferTypeArgs indicates a failure of inference, though the actual
+		// error may be better attributed to a user-provided type argument (hence
+		// _InvalidTypeArg). We can't differentiate these cases, so fall back on
+		// the more general _CannotInferTypeArgs.
 		if inferred != tpar {
-			check.errorf(arg, "%s %s of %s does not match inferred type %s for %s", kind, targ, arg.expr, inferred, tpar)
+			check.errorf(arg, CannotInferTypeArgs, "%s %s of %s does not match inferred type %s for %s", kind, targ, arg.expr, inferred, tpar)
 		} else {
-			check.errorf(arg, "%s %s of %s does not match %s", kind, targ, arg.expr, tpar)
+			check.errorf(arg, CannotInferTypeArgs, "%s %s of %s does not match %s", kind, targ, arg.expr, tpar)
 		}
 	}
 
@@ -319,7 +312,7 @@
 	// At least one type argument couldn't be inferred.
 	assert(targs != nil && index >= 0 && targs[index] == nil)
 	tpar := tparams[index]
-	check.errorf(pos, "cannot infer %s (%s)", tpar.obj.name, tpar.obj.pos)
+	check.errorf(pos, CannotInferTypeArgs, "cannot infer %s (%s)", tpar.obj.name, tpar.obj.pos)
 	return nil
 }
 
@@ -338,17 +331,16 @@
 	}
 
 	// general case (n > 2)
-	// Would like to use strings.Builder but it's not available in Go 1.4.
-	var b bytes.Buffer
+	var buf strings.Builder
 	for i, tname := range list[:n-1] {
 		if i > 0 {
-			b.WriteString(", ")
+			buf.WriteString(", ")
 		}
-		b.WriteString(tname.obj.name)
+		buf.WriteString(tname.obj.name)
 	}
-	b.WriteString(", and ")
-	b.WriteString(list[n-1].obj.name)
-	return b.String()
+	buf.WriteString(", and ")
+	buf.WriteString(list[n-1].obj.name)
+	return buf.String()
 }
 
 // isParameterized reports whether typ contains any of the type parameters of tparams.
@@ -533,7 +525,7 @@
 						if core.tilde {
 							tilde = "~"
 						}
-						check.errorf(pos, "%s does not match %s%s", tpar, tilde, core.typ)
+						check.errorf(pos, InvalidTypeArg, "%s does not match %s%s", tx, tilde, core.typ)
 						return nil, 0
 					}
 
diff --git a/src/cmd/compile/internal/types2/initorder.go b/src/cmd/compile/internal/types2/initorder.go
index cf6110b..6e04172 100644
--- a/src/cmd/compile/internal/types2/initorder.go
+++ b/src/cmd/compile/internal/types2/initorder.go
@@ -7,6 +7,7 @@
 import (
 	"container/heap"
 	"fmt"
+	. "internal/types/errors"
 	"sort"
 )
 
@@ -152,12 +153,16 @@
 // reportCycle reports an error for the given cycle.
 func (check *Checker) reportCycle(cycle []Object) {
 	obj := cycle[0]
-	var err error_
-	if check.conf.CompilerErrorMessages {
-		err.errorf(obj, "initialization loop for %s", obj.Name())
-	} else {
-		err.errorf(obj, "initialization cycle for %s", obj.Name())
+
+	// report a more concise error for self references
+	if len(cycle) == 1 {
+		check.errorf(obj, InvalidInitCycle, "initialization cycle: %s refers to itself", obj.Name())
+		return
 	}
+
+	var err error_
+	err.code = InvalidInitCycle
+	err.errorf(obj, "initialization cycle for %s", obj.Name())
 	// subtle loop: print cycle[i] for i = 0, n-1, n-2, ... 1 for len(cycle) = n
 	for i := len(cycle) - 1; i >= 0; i-- {
 		err.errorf(obj, "%s refers to", obj.Name())
diff --git a/src/cmd/compile/internal/types2/instantiate.go b/src/cmd/compile/internal/types2/instantiate.go
index 5833f8d..8193682 100644
--- a/src/cmd/compile/internal/types2/instantiate.go
+++ b/src/cmd/compile/internal/types2/instantiate.go
@@ -11,6 +11,7 @@
 	"cmd/compile/internal/syntax"
 	"errors"
 	"fmt"
+	. "internal/types/errors"
 )
 
 // Instantiate instantiates the type orig with the given type arguments targs.
@@ -156,7 +157,7 @@
 	if ntargs != ntparams {
 		// TODO(gri) provide better error message
 		if check != nil {
-			check.errorf(pos, "got %d arguments but %d type parameters", ntargs, ntparams)
+			check.errorf(pos, WrongTypeArgCount, "got %d arguments but %d type parameters", ntargs, ntparams)
 			return false
 		}
 		panic(fmt.Sprintf("%v: got %d arguments but %d type parameters", pos, ntargs, ntparams))
@@ -174,44 +175,52 @@
 		// need to instantiate it with the type arguments with which we instantiated
 		// the parameterized type.
 		bound := check.subst(pos, tpar.bound, smap, nil, ctxt)
-		if err := check.implements(targs[i], bound); err != nil {
-			return i, err
+		var cause string
+		if !check.implements(targs[i], bound, true, &cause) {
+			return i, errors.New(cause)
 		}
 	}
 	return -1, nil
 }
 
-// implements checks if V implements T and reports an error if it doesn't.
-// The receiver may be nil if implements is called through an exported
-// API call such as AssignableTo.
-func (check *Checker) implements(V, T Type) error {
+// implements checks if V implements T. The receiver may be nil if implements
+// is called through an exported API call such as AssignableTo. If constraint
+// is set, T is a type constraint.
+//
+// If the provided cause is non-nil, it may be set to an error string
+// explaining why V does not implement (or satisfy, for constraints) T.
+func (check *Checker) implements(V, T Type, constraint bool, cause *string) bool {
 	Vu := under(V)
 	Tu := under(T)
 	if Vu == Typ[Invalid] || Tu == Typ[Invalid] {
-		return nil // avoid follow-on errors
+		return true // avoid follow-on errors
 	}
 	if p, _ := Vu.(*Pointer); p != nil && under(p.base) == Typ[Invalid] {
-		return nil // avoid follow-on errors (see issue #49541 for an example)
+		return true // avoid follow-on errors (see issue #49541 for an example)
 	}
 
-	errorf := func(format string, args ...interface{}) error {
-		return errors.New(check.sprintf(format, args...))
+	verb := "implement"
+	if constraint {
+		verb = "satisfy"
 	}
 
 	Ti, _ := Tu.(*Interface)
 	if Ti == nil {
-		var cause string
-		if isInterfacePtr(Tu) {
-			cause = check.sprintf("type %s is pointer to interface, not interface", T)
-		} else {
-			cause = check.sprintf("%s is not an interface", T)
+		if cause != nil {
+			var detail string
+			if isInterfacePtr(Tu) {
+				detail = check.sprintf("type %s is pointer to interface, not interface", T)
+			} else {
+				detail = check.sprintf("%s is not an interface", T)
+			}
+			*cause = check.sprintf("%s does not %s %s (%s)", V, verb, T, detail)
 		}
-		return errorf("%s does not implement %s (%s)", V, T, cause)
+		return false
 	}
 
 	// Every type satisfies the empty interface.
 	if Ti.Empty() {
-		return nil
+		return true
 	}
 	// T is not the empty interface (i.e., the type set of T is restricted)
 
@@ -219,31 +228,67 @@
 	// (The empty set is a subset of any set.)
 	Vi, _ := Vu.(*Interface)
 	if Vi != nil && Vi.typeSet().IsEmpty() {
-		return nil
+		return true
 	}
 	// type set of V is not empty
 
 	// No type with non-empty type set satisfies the empty type set.
 	if Ti.typeSet().IsEmpty() {
-		return errorf("cannot implement %s (empty type set)", T)
+		if cause != nil {
+			*cause = check.sprintf("cannot %s %s (empty type set)", verb, T)
+		}
+		return false
 	}
 
 	// V must implement T's methods, if any.
 	if m, wrong := check.missingMethod(V, Ti, true); m != nil /* !Implements(V, Ti) */ {
-		return errorf("%s does not implement %s %s", V, T, check.missingMethodReason(V, T, m, wrong))
+		if cause != nil {
+			*cause = check.sprintf("%s does not %s %s %s", V, verb, T, check.missingMethodCause(V, T, m, wrong))
+		}
+		return false
 	}
 
-	// If T is comparable, V must be comparable.
-	// Remember as a pending error and report only if we don't have a more specific error.
-	var pending error
-	if Ti.IsComparable() && !comparable(V, false, nil, nil) {
-		pending = errorf("%s does not implement comparable", V)
+	// Only check comparability if we don't have a more specific error.
+	checkComparability := func() bool {
+		if !Ti.IsComparable() {
+			return true
+		}
+		// If T is comparable, V must be comparable.
+		// If V is strictly comparable, we're done.
+		if comparable(V, false /* strict comparability */, nil, nil) {
+			return true
+		}
+		// If check.conf.OldComparableSemantics is set (by the compiler or
+		// a test), we only consider strict comparability and we're done.
+		// TODO(gri) remove this check for Go 1.21
+		if check != nil && check.conf.OldComparableSemantics {
+			if cause != nil {
+				*cause = check.sprintf("%s does not %s comparable", V, verb)
+			}
+			return false
+		}
+		// For constraint satisfaction, use dynamic (spec) comparability
+		// so that ordinary, non-type parameter interfaces implement comparable.
+		if constraint && comparable(V, true /* spec comparability */, nil, nil) {
+			// V is comparable if we are at Go 1.20 or higher.
+			if check == nil || check.allowVersion(check.pkg, 1, 20) {
+				return true
+			}
+			if cause != nil {
+				*cause = check.sprintf("%s to %s comparable requires go1.20 or later", V, verb)
+			}
+			return false
+		}
+		if cause != nil {
+			*cause = check.sprintf("%s does not %s comparable", V, verb)
+		}
+		return false
 	}
 
 	// V must also be in the set of types of T, if any.
 	// Constraints with empty type sets were already excluded above.
 	if !Ti.typeSet().hasTerms() {
-		return pending // nothing to do
+		return checkComparability() // nothing to do
 	}
 
 	// If V is itself an interface, each of its possible types must be in the set
@@ -252,9 +297,12 @@
 	if Vi != nil {
 		if !Vi.typeSet().subsetOf(Ti.typeSet()) {
 			// TODO(gri) report which type is missing
-			return errorf("%s does not implement %s", V, T)
+			if cause != nil {
+				*cause = check.sprintf("%s does not %s %s", V, verb, T)
+			}
+			return false
 		}
-		return pending
+		return checkComparability()
 	}
 
 	// Otherwise, V's type must be included in the iface type set.
@@ -275,12 +323,44 @@
 		}
 		return false
 	}) {
-		if alt != nil {
-			return errorf("%s does not implement %s (possibly missing ~ for %s in constraint %s)", V, T, alt, T)
-		} else {
-			return errorf("%s does not implement %s (%s missing in %s)", V, T, V, Ti.typeSet().terms)
+		if cause != nil {
+			var detail string
+			switch {
+			case alt != nil:
+				detail = check.sprintf("possibly missing ~ for %s in %s", alt, T)
+			case mentions(Ti, V):
+				detail = check.sprintf("%s mentions %s, but %s is not in the type set of %s", T, V, V, T)
+			default:
+				detail = check.sprintf("%s missing in %s", V, Ti.typeSet().terms)
+			}
+			*cause = check.sprintf("%s does not %s %s (%s)", V, verb, T, detail)
 		}
+		return false
 	}
 
-	return pending
+	return checkComparability()
+}
+
+// mentions reports whether type T "mentions" typ in an (embedded) element or term
+// of T (whether typ is in the type set of T or not). For better error messages.
+func mentions(T, typ Type) bool {
+	switch T := T.(type) {
+	case *Interface:
+		for _, e := range T.embeddeds {
+			if mentions(e, typ) {
+				return true
+			}
+		}
+	case *Union:
+		for _, t := range T.terms {
+			if mentions(t.typ, typ) {
+				return true
+			}
+		}
+	default:
+		if Identical(T, typ) {
+			return true
+		}
+	}
+	return false
 }
diff --git a/src/cmd/compile/internal/types2/instantiate_test.go b/src/cmd/compile/internal/types2/instantiate_test.go
index 591b467..33a34d7 100644
--- a/src/cmd/compile/internal/types2/instantiate_test.go
+++ b/src/cmd/compile/internal/types2/instantiate_test.go
@@ -107,10 +107,7 @@
 	}
 
 	for _, test := range tests {
-		pkg, err := pkgFor(".", test.src, nil)
-		if err != nil {
-			t.Fatal(err)
-		}
+		pkg := mustTypecheck(".", test.src, nil)
 
 		t.Run(pkg.Name(), func(t *testing.T) {
 			ctxt := NewContext()
@@ -136,14 +133,8 @@
 
 func TestInstantiateNonEquality(t *testing.T) {
 	const src = "package p; type T[P any] int"
-	pkg1, err := pkgFor(".", src, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-	pkg2, err := pkgFor(".", src, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
+	pkg1 := mustTypecheck(".", src, nil)
+	pkg2 := mustTypecheck(".", src, nil)
 	// We consider T1 and T2 to be distinct types, so their instances should not
 	// be deduplicated by the context.
 	T1 := pkg1.Scope().Lookup("T").Type().(*Named)
@@ -188,10 +179,7 @@
 
 	for _, test := range tests {
 		src := prefix + test.decl
-		pkg, err := pkgFor(".", src, nil)
-		if err != nil {
-			t.Fatal(err)
-		}
+		pkg := mustTypecheck(".", src, nil)
 		typ := NewPointer(pkg.Scope().Lookup("X").Type())
 		obj, _, _ := LookupFieldOrMethod(typ, false, pkg, "m")
 		m, _ := obj.(*Func)
@@ -213,10 +201,7 @@
 
 var _ T[int]
 `
-	pkg, err := pkgFor(".", src, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
+	pkg := mustTypecheck(".", src, nil)
 	typ := pkg.Scope().Lookup("T").Type().(*Named)
 	obj, _, _ := LookupFieldOrMethod(typ, false, pkg, "m")
 	if obj == nil {
@@ -233,15 +218,15 @@
 
 // Copied from errors.go.
 func stripAnnotations(s string) string {
-	var b strings.Builder
+	var buf strings.Builder
 	for _, r := range s {
 		// strip #'s and subscript digits
 		if r < '₀' || '₀'+10 <= r { // '₀' == U+2080
-			b.WriteRune(r)
+			buf.WriteRune(r)
 		}
 	}
-	if b.Len() < len(s) {
-		return b.String()
+	if buf.Len() < len(s) {
+		return buf.String()
 	}
 	return s
 }
diff --git a/src/cmd/compile/internal/types2/interface.go b/src/cmd/compile/internal/types2/interface.go
index 431b91f..0978989 100644
--- a/src/cmd/compile/internal/types2/interface.go
+++ b/src/cmd/compile/internal/types2/interface.go
@@ -4,7 +4,10 @@
 
 package types2
 
-import "cmd/compile/internal/syntax"
+import (
+	"cmd/compile/internal/syntax"
+	. "internal/types/errors"
+)
 
 // ----------------------------------------------------------------------------
 // API
@@ -132,7 +135,7 @@
 		// We have a method with name f.Name.
 		name := f.Name.Value
 		if name == "_" {
-			check.error(f.Name, "methods must have a unique non-blank name")
+			check.error(f.Name, BlankIfaceMethod, "methods must have a unique non-blank name")
 			continue // ignore
 		}
 
@@ -140,7 +143,7 @@
 		sig, _ := typ.(*Signature)
 		if sig == nil {
 			if typ != Typ[Invalid] {
-				check.errorf(f.Type, invalidAST+"%s is not a method signature", typ)
+				check.errorf(f.Type, InvalidSyntaxTree, "%s is not a method signature", typ)
 			}
 			continue // ignore
 		}
diff --git a/src/cmd/compile/internal/types2/issues_test.go b/src/cmd/compile/internal/types2/issues_test.go
index 697a735..5278420 100644
--- a/src/cmd/compile/internal/types2/issues_test.go
+++ b/src/cmd/compile/internal/types2/issues_test.go
@@ -7,10 +7,10 @@
 package types2_test
 
 import (
-	"bytes"
 	"cmd/compile/internal/syntax"
 	"fmt"
 	"internal/testenv"
+	"regexp"
 	"sort"
 	"strings"
 	"testing"
@@ -18,18 +18,11 @@
 	. "cmd/compile/internal/types2"
 )
 
-func mustParse(t *testing.T, src string) *syntax.File {
-	f, err := parseSrc("", src)
-	if err != nil {
-		t.Fatal(err)
-	}
-	return f
-}
 func TestIssue5770(t *testing.T) {
-	f := mustParse(t, `package p; type S struct{T}`)
+	f := mustParse("", `package p; type S struct{T}`)
 	var conf Config
 	_, err := conf.Check(f.PkgName.Value, []*syntax.File{f}, nil) // do not crash
-	want := "undeclared name: T"
+	const want = "undefined: T"
 	if err == nil || !strings.Contains(err.Error(), want) {
 		t.Errorf("got: %v; want: %s", err, want)
 	}
@@ -47,14 +40,8 @@
 	_ = (interface{})("foo")
 	_ = (interface{})(nil)
 )`
-	f := mustParse(t, src)
-
-	var conf Config
 	types := make(map[syntax.Expr]TypeAndValue)
-	_, err := conf.Check(f.PkgName.Value, []*syntax.File{f}, &Info{Types: types})
-	if err != nil {
-		t.Fatal(err)
-	}
+	mustTypecheck("p", src, &Info{Types: types})
 
 	for x, tv := range types {
 		var want Type
@@ -92,14 +79,8 @@
 	return 0
 }
 `
-	f := mustParse(t, src)
-
-	var conf Config
 	types := make(map[syntax.Expr]TypeAndValue)
-	_, err := conf.Check(f.PkgName.Value, []*syntax.File{f}, &Info{Types: types})
-	if err != nil {
-		t.Fatal(err)
-	}
+	mustTypecheck("p", src, &Info{Types: types})
 
 	want := Typ[Int]
 	n := 0
@@ -123,7 +104,7 @@
 func (T) m() (res bool) { return }
 type T struct{} // receiver type after method declaration
 `
-	f := mustParse(t, src)
+	f := mustParse("", src)
 
 	var conf Config
 	defs := make(map[*syntax.Name]Object)
@@ -154,7 +135,7 @@
         _, _, _ = x, y, z  // uses x, y, z
 }
 `
-	f := mustParse(t, src)
+	f := mustParse("", src)
 
 	const want = `L3 defs func p._()
 L4 defs const w untyped int
@@ -250,7 +231,7 @@
 }
 `
 	f := func(test, src string) {
-		f := mustParse(t, src)
+		f := mustParse("", src)
 		conf := Config{Importer: defaultImporter()}
 		info := Info{Uses: make(map[*syntax.Name]Object)}
 		_, err := conf.Check("main", []*syntax.File{f}, &info)
@@ -280,17 +261,17 @@
 }
 
 func TestIssue22525(t *testing.T) {
-	f := mustParse(t, `package p; func f() { var a, b, c, d, e int }`)
+	f := mustParse("", `package p; func f() { var a, b, c, d, e int }`)
 
 	got := "\n"
 	conf := Config{Error: func(err error) { got += err.Error() + "\n" }}
 	conf.Check(f.PkgName.Value, []*syntax.File{f}, nil) // do not crash
 	want := `
-:1:27: a declared but not used
-:1:30: b declared but not used
-:1:33: c declared but not used
-:1:36: d declared but not used
-:1:39: e declared but not used
+:1:27: a declared and not used
+:1:30: b declared and not used
+:1:33: c declared and not used
+:1:36: d declared and not used
+:1:39: e declared and not used
 `
 	if got != want {
 		t.Errorf("got: %swant: %s", got, want)
@@ -310,7 +291,7 @@
 		`struct { *I }`,
 		`struct { a int; b Missing; *Missing }`,
 	} {
-		f := mustParse(t, prefix+src)
+		f := mustParse("", prefix+src)
 
 		conf := Config{Importer: defaultImporter(), Error: func(err error) {}}
 		info := &Info{Types: make(map[syntax.Expr]TypeAndValue)}
@@ -347,7 +328,7 @@
 	// compute original file ASTs
 	var orig [len(sources)]*syntax.File
 	for i, src := range sources {
-		orig[i] = mustParse(t, src)
+		orig[i] = mustParse("", src)
 	}
 
 	// run the test for all order permutations of the incoming files
@@ -422,12 +403,12 @@
 }
 
 func TestIssue29029(t *testing.T) {
-	f1 := mustParse(t, `package p; type A interface { M() }`)
-	f2 := mustParse(t, `package p; var B interface { A }`)
+	f1 := mustParse("", `package p; type A interface { M() }`)
+	f2 := mustParse("", `package p; var B interface { A }`)
 
 	// printInfo prints the *Func definitions recorded in info, one *Func per line.
 	printInfo := func(info *Info) string {
-		var buf bytes.Buffer
+		var buf strings.Builder
 		for _, obj := range info.Defs {
 			if fn, ok := obj.(*Func); ok {
 				fmt.Fprintln(&buf, fn)
@@ -469,12 +450,9 @@
 	const asrc = `package a; type I interface{ M() }; type T struct { F interface { I } }`
 	const bsrc = `package b; import "a"; type T struct { F interface { a.I } }; var _ = a.T(T{})`
 
-	a, err := pkgFor("a", asrc, nil)
-	if err != nil {
-		t.Fatalf("package %s failed to typecheck: %v", a.Name(), err)
-	}
+	a := mustTypecheck("a", asrc, nil)
 
-	bast := mustParse(t, bsrc)
+	bast := mustParse("", bsrc)
 	conf := Config{Importer: importHelper{pkg: a}}
 	b, err := conf.Check(bast.PkgName.Value, []*syntax.File{bast}, nil)
 	if err != nil {
@@ -517,7 +495,7 @@
 
 	var pkg *Package
 	for _, src := range sources {
-		f := mustParse(t, src)
+		f := mustParse("", src)
 		conf := Config{Importer: importHelper{pkg: pkg}}
 		res, err := conf.Check(f.PkgName.Value, []*syntax.File{f}, nil)
 		if err != nil {
@@ -575,6 +553,8 @@
 }
 
 func TestIssue43124(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
 	// All involved packages have the same name (template). Error messages should
 	// disambiguate between text/template and html/template by printing the full
 	// path.
@@ -584,16 +564,13 @@
 		csrc = `package c; import ("a"; "html/template"); func _() { a.G(template.Template{}) }`
 	)
 
-	a, err := pkgFor("a", asrc, nil)
-	if err != nil {
-		t.Fatalf("package a failed to typecheck: %v", err)
-	}
+	a := mustTypecheck("a", asrc, nil)
 	conf := Config{Importer: importHelper{pkg: a, fallback: defaultImporter()}}
 
 	// Packages should be fully qualified when there is ambiguity within the
 	// error string itself.
-	bast := mustParse(t, bsrc)
-	_, err = conf.Check(bast.PkgName.Value, []*syntax.File{bast}, nil)
+	bast := mustParse("", bsrc)
+	_, err := conf.Check(bast.PkgName.Value, []*syntax.File{bast}, nil)
 	if err == nil {
 		t.Fatal("package b had no errors")
 	}
@@ -602,7 +579,7 @@
 	}
 
 	// ...and also when there is any ambiguity in reachable packages.
-	cast := mustParse(t, csrc)
+	cast := mustParse("", csrc)
 	_, err = conf.Check(cast.PkgName.Value, []*syntax.File{cast}, nil)
 	if err == nil {
 		t.Fatal("package c had no errors")
@@ -617,23 +594,233 @@
 	comparableType := Universe.Lookup("comparable").Type()
 
 	if !Comparable(anyType) {
-		t.Errorf("any is not a comparable type")
+		t.Error("any is not a comparable type")
 	}
 	if !Comparable(comparableType) {
-		t.Errorf("comparable is not a comparable type")
+		t.Error("comparable is not a comparable type")
 	}
 
 	if Implements(anyType, comparableType.Underlying().(*Interface)) {
-		t.Errorf("any implements comparable")
+		t.Error("any implements comparable")
 	}
 	if !Implements(comparableType, anyType.(*Interface)) {
-		t.Errorf("comparable does not implement any")
+		t.Error("comparable does not implement any")
 	}
 
 	if AssignableTo(anyType, comparableType) {
-		t.Errorf("any assignable to comparable")
+		t.Error("any assignable to comparable")
 	}
 	if !AssignableTo(comparableType, anyType) {
-		t.Errorf("comparable not assignable to any")
+		t.Error("comparable not assignable to any")
+	}
+}
+
+func TestIssue55030(t *testing.T) {
+	// makeSig makes the signature func(typ...)
+	makeSig := func(typ Type) {
+		par := NewVar(nopos, nil, "", typ)
+		params := NewTuple(par)
+		NewSignatureType(nil, nil, nil, params, nil, true)
+	}
+
+	// makeSig must not panic for the following (example) types:
+	// []int
+	makeSig(NewSlice(Typ[Int]))
+
+	// string
+	makeSig(Typ[String])
+
+	// P where P's core type is string
+	{
+		P := NewTypeName(nopos, nil, "P", nil) // [P string]
+		makeSig(NewTypeParam(P, NewInterfaceType(nil, []Type{Typ[String]})))
+	}
+
+	// P where P's core type is an (unnamed) slice
+	{
+		P := NewTypeName(nopos, nil, "P", nil) // [P []int]
+		makeSig(NewTypeParam(P, NewInterfaceType(nil, []Type{NewSlice(Typ[Int])})))
+	}
+
+	// P where P's core type is bytestring (i.e., string or []byte)
+	{
+		t1 := NewTerm(true, Typ[String])          // ~string
+		t2 := NewTerm(false, NewSlice(Typ[Byte])) // []byte
+		u := NewUnion([]*Term{t1, t2})            // ~string | []byte
+		P := NewTypeName(nopos, nil, "P", nil)    // [P ~string | []byte]
+		makeSig(NewTypeParam(P, NewInterfaceType(nil, []Type{u})))
+	}
+}
+
+func TestIssue51093(t *testing.T) {
+	// Each test stands for a conversion of the form P(val)
+	// where P is a type parameter with typ as constraint.
+	// The test ensures that P(val) has the correct type P
+	// and is not a constant.
+	var tests = []struct {
+		typ string
+		val string
+	}{
+		{"bool", "false"},
+		{"int", "-1"},
+		{"uint", "1.0"},
+		{"rune", "'a'"},
+		{"float64", "3.5"},
+		{"complex64", "1.25"},
+		{"string", "\"foo\""},
+
+		// some more complex constraints
+		{"~byte", "1"},
+		{"~int | ~float64 | complex128", "1"},
+		{"~uint64 | ~rune", "'X'"},
+	}
+
+	for _, test := range tests {
+		src := fmt.Sprintf("package p; func _[P %s]() { _ = P(%s) }", test.typ, test.val)
+		types := make(map[syntax.Expr]TypeAndValue)
+		mustTypecheck("p", src, &Info{Types: types})
+
+		var n int
+		for x, tv := range types {
+			if x, _ := x.(*syntax.CallExpr); x != nil {
+				// there must be exactly one CallExpr which is the P(val) conversion
+				n++
+				tpar, _ := tv.Type.(*TypeParam)
+				if tpar == nil {
+					t.Fatalf("%s: got type %s, want type parameter", syntax.String(x), tv.Type)
+				}
+				if name := tpar.Obj().Name(); name != "P" {
+					t.Fatalf("%s: got type parameter name %s, want P", syntax.String(x), name)
+				}
+				// P(val) must not be constant
+				if tv.Value != nil {
+					t.Errorf("%s: got constant value %s (%s), want no constant", syntax.String(x), tv.Value, tv.Value.String())
+				}
+			}
+		}
+
+		if n != 1 {
+			t.Fatalf("%s: got %d CallExpr nodes; want 1", src, 1)
+		}
+	}
+}
+
+func TestIssue54258(t *testing.T) {
+	tests := []struct{ main, b, want string }{
+		{ //---------------------------------------------------------------
+			`package main
+import "b"
+type I0 interface {
+	M0(w struct{ f string })
+}
+var _ I0 = b.S{}
+`,
+			`package b
+type S struct{}
+func (S) M0(struct{ f string }) {}
+`,
+			`6:12: cannot use b[.]S{} [(]value of type b[.]S[)] as I0 value in variable declaration: b[.]S does not implement I0 [(]wrong type for method M0[)]
+.*have M0[(]struct{f string /[*] package b [*]/ }[)]
+.*want M0[(]struct{f string /[*] package main [*]/ }[)]`},
+
+		{ //---------------------------------------------------------------
+			`package main
+import "b"
+type I1 interface {
+	M1(struct{ string })
+}
+var _ I1 = b.S{}
+`,
+			`package b
+type S struct{}
+func (S) M1(struct{ string }) {}
+`,
+			`6:12: cannot use b[.]S{} [(]value of type b[.]S[)] as I1 value in variable declaration: b[.]S does not implement I1 [(]wrong type for method M1[)]
+.*have M1[(]struct{string /[*] package b [*]/ }[)]
+.*want M1[(]struct{string /[*] package main [*]/ }[)]`},
+
+		{ //---------------------------------------------------------------
+			`package main
+import "b"
+type I2 interface {
+	M2(y struct{ f struct{ f string } })
+}
+var _ I2 = b.S{}
+`,
+			`package b
+type S struct{}
+func (S) M2(struct{ f struct{ f string } }) {}
+`,
+			`6:12: cannot use b[.]S{} [(]value of type b[.]S[)] as I2 value in variable declaration: b[.]S does not implement I2 [(]wrong type for method M2[)]
+.*have M2[(]struct{f struct{f string} /[*] package b [*]/ }[)]
+.*want M2[(]struct{f struct{f string} /[*] package main [*]/ }[)]`},
+
+		{ //---------------------------------------------------------------
+			`package main
+import "b"
+type I3 interface {
+	M3(z struct{ F struct{ f string } })
+}
+var _ I3 = b.S{}
+`,
+			`package b
+type S struct{}
+func (S) M3(struct{ F struct{ f string } }) {}
+`,
+			`6:12: cannot use b[.]S{} [(]value of type b[.]S[)] as I3 value in variable declaration: b[.]S does not implement I3 [(]wrong type for method M3[)]
+.*have M3[(]struct{F struct{f string /[*] package b [*]/ }}[)]
+.*want M3[(]struct{F struct{f string /[*] package main [*]/ }}[)]`},
+
+		{ //---------------------------------------------------------------
+			`package main
+import "b"
+type I4 interface {
+	M4(_ struct { *string })
+}
+var _ I4 = b.S{}
+`,
+			`package b
+type S struct{}
+func (S) M4(struct { *string }) {}
+`,
+			`6:12: cannot use b[.]S{} [(]value of type b[.]S[)] as I4 value in variable declaration: b[.]S does not implement I4 [(]wrong type for method M4[)]
+.*have M4[(]struct{[*]string /[*] package b [*]/ }[)]
+.*want M4[(]struct{[*]string /[*] package main [*]/ }[)]`},
+
+		{ //---------------------------------------------------------------
+			`package main
+import "b"
+type t struct{ A int }
+type I5 interface {
+	M5(_ struct {b.S;t})
+}
+var _ I5 = b.S{}
+`,
+			`package b
+type S struct{}
+type t struct{ A int }
+func (S) M5(struct {S;t}) {}
+`,
+			`7:12: cannot use b[.]S{} [(]value of type b[.]S[)] as I5 value in variable declaration: b[.]S does not implement I5 [(]wrong type for method M5[)]
+.*have M5[(]struct{b[.]S; b[.]t}[)]
+.*want M5[(]struct{b[.]S; t}[)]`},
+	}
+
+	test := func(main, b, want string) {
+		re := regexp.MustCompile(want)
+		bpkg := mustTypecheck("b", b, nil)
+		mast := mustParse("main.go", main)
+		conf := Config{Importer: importHelper{pkg: bpkg}}
+		_, err := conf.Check(mast.PkgName.Value, []*syntax.File{mast}, nil)
+		if err == nil {
+			t.Error("Expected failure, but it did not")
+		} else if got := err.Error(); !re.MatchString(got) {
+			t.Errorf("Wanted match for\n\t%s\n but got\n\t%s", want, got)
+		} else if testing.Verbose() {
+			t.Logf("Saw expected\n\t%s", err.Error())
+		}
+	}
+	for _, t := range tests {
+		test(t.main, t.b, t.want)
 	}
 }
diff --git a/src/cmd/compile/internal/types2/labels.go b/src/cmd/compile/internal/types2/labels.go
index 6f02e2f..ffb3700 100644
--- a/src/cmd/compile/internal/types2/labels.go
+++ b/src/cmd/compile/internal/types2/labels.go
@@ -6,6 +6,7 @@
 
 import (
 	"cmd/compile/internal/syntax"
+	. "internal/types/errors"
 )
 
 // labels checks correct label use in body.
@@ -21,21 +22,24 @@
 	// for the respective gotos.
 	for _, jmp := range fwdJumps {
 		var msg string
+		var code Code
 		name := jmp.Label.Value
 		if alt := all.Lookup(name); alt != nil {
 			msg = "goto %s jumps into block"
 			alt.(*Label).used = true // avoid another error
+			code = JumpIntoBlock
 		} else {
 			msg = "label %s not declared"
+			code = UndeclaredLabel
 		}
-		check.errorf(jmp.Label, msg, name)
+		check.errorf(jmp.Label, code, msg, name)
 	}
 
 	// spec: "It is illegal to define a label that is never used."
 	for name, obj := range all.elems {
 		obj = resolve(name, obj)
 		if lbl := obj.(*Label); !lbl.used {
-			check.softErrorf(lbl.pos, "label %s declared but not used", lbl.name)
+			check.softErrorf(lbl.pos, UnusedLabel, "label %s declared and not used", lbl.name)
 		}
 	}
 }
@@ -130,6 +134,7 @@
 				lbl := NewLabel(s.Label.Pos(), check.pkg, name)
 				if alt := all.Insert(lbl); alt != nil {
 					var err error_
+					err.code = DuplicateLabel
 					err.soft = true
 					err.errorf(lbl.pos, "label %s already declared", name)
 					err.recordAltDecl(alt)
@@ -149,6 +154,7 @@
 						if jumpsOverVarDecl(jmp) {
 							check.softErrorf(
 								jmp.Label,
+								JumpOverDecl,
 								"goto %s jumps over variable declaration at line %d",
 								name,
 								varDeclPos.Line(),
@@ -186,7 +192,7 @@
 					}
 				}
 				if !valid {
-					check.errorf(s.Label, "invalid break label %s", name)
+					check.errorf(s.Label, MisplacedLabel, "invalid break label %s", name)
 					return
 				}
 
@@ -201,7 +207,7 @@
 					}
 				}
 				if !valid {
-					check.errorf(s.Label, "invalid continue label %s", name)
+					check.errorf(s.Label, MisplacedLabel, "invalid continue label %s", name)
 					return
 				}
 
@@ -213,7 +219,7 @@
 				}
 
 			default:
-				check.errorf(s, invalidAST+"branch statement: %s %s", s.Tok, name)
+				check.errorf(s, InvalidSyntaxTree, "branch statement: %s %s", s.Tok, name)
 				return
 			}
 
diff --git a/src/cmd/compile/internal/types2/lookup.go b/src/cmd/compile/internal/types2/lookup.go
index 42cd338..f66f2ef 100644
--- a/src/cmd/compile/internal/types2/lookup.go
+++ b/src/cmd/compile/internal/types2/lookup.go
@@ -261,10 +261,18 @@
 }
 
 type instanceLookup struct {
-	m map[*Named][]*Named
+	// buf is used to avoid allocating the map m in the common case of a small
+	// number of instances.
+	buf [3]*Named
+	m   map[*Named][]*Named
 }
 
 func (l *instanceLookup) lookup(inst *Named) *Named {
+	for _, t := range l.buf {
+		if t != nil && Identical(inst, t) {
+			return t
+		}
+	}
 	for _, t := range l.m[inst.Origin()] {
 		if Identical(inst, t) {
 			return t
@@ -274,6 +282,12 @@
 }
 
 func (l *instanceLookup) add(inst *Named) {
+	for i, t := range l.buf {
+		if t == nil {
+			l.buf[i] = inst
+			return
+		}
+	}
 	if l.m == nil {
 		l.m = make(map[*Named][]*Named)
 	}
@@ -364,32 +378,33 @@
 	return
 }
 
-// missingMethodReason returns a string giving the detailed reason for a missing method m,
-// where m is missing from V, but required by T. It puts the reason in parentheses,
+// missingMethodCause returns a string giving the detailed cause for a missing method m,
+// where m is missing from V, but required by T. It puts the cause in parentheses,
 // and may include more have/want info after that. If non-nil, alt is a relevant
 // method that matches in some way. It may have the correct name, but wrong type, or
 // it may have a pointer receiver, or it may have the correct name except wrong case.
 // check may be nil.
-func (check *Checker) missingMethodReason(V, T Type, m, alt *Func) string {
-	var mname string
-	if check != nil && check.conf.CompilerErrorMessages {
-		mname = m.Name() + " method"
-	} else {
-		mname = "method " + m.Name()
-	}
+func (check *Checker) missingMethodCause(V, T Type, m, alt *Func) string {
+	mname := "method " + m.Name()
 
 	if alt != nil {
 		if m.Name() != alt.Name() {
 			return check.sprintf("(missing %s)\n\t\thave %s\n\t\twant %s",
-				mname, check.funcString(alt), check.funcString(m))
+				mname, check.funcString(alt, false), check.funcString(m, false))
 		}
 
 		if Identical(m.typ, alt.typ) {
 			return check.sprintf("(%s has pointer receiver)", mname)
 		}
 
+		altS, mS := check.funcString(alt, false), check.funcString(m, false)
+		if altS == mS {
+			// Would tell the user that Foo isn't a Foo, add package information to disambiguate.  See #54258.
+			altS, mS = check.funcString(alt, true), check.funcString(m, true)
+		}
+
 		return check.sprintf("(wrong type for %s)\n\t\thave %s\n\t\twant %s",
-			mname, check.funcString(alt), check.funcString(m))
+			mname, altS, mS)
 	}
 
 	if isInterfacePtr(V) {
@@ -400,6 +415,11 @@
 		return "(" + check.interfacePtrError(T) + ")"
 	}
 
+	obj, _, _ := lookupFieldOrMethod(V, true /* auto-deref */, m.pkg, m.name, false)
+	if fld, _ := obj.(*Var); fld != nil {
+		return check.sprintf("(%s.%s is a field, not a method)", V, fld.Name())
+	}
+
 	return check.sprintf("(missing %s)", mname)
 }
 
@@ -419,13 +439,16 @@
 
 // funcString returns a string of the form name + signature for f.
 // check may be nil.
-func (check *Checker) funcString(f *Func) string {
+func (check *Checker) funcString(f *Func, pkgInfo bool) string {
 	buf := bytes.NewBufferString(f.name)
 	var qf Qualifier
-	if check != nil {
+	if check != nil && !pkgInfo {
 		qf = check.qualifier
 	}
-	WriteSignature(buf, f.typ.(*Signature), qf)
+	w := newTypeWriter(buf, qf)
+	w.pkgInfo = pkgInfo
+	w.paramNames = false
+	w.signature(f.typ.(*Signature))
 	return buf.String()
 }
 
@@ -449,14 +472,14 @@
 // newAssertableTo reports whether a value of type V can be asserted to have type T.
 // It also implements behavior for interfaces that currently are only permitted
 // in constraint position (we have not yet defined that behavior in the spec).
-func (check *Checker) newAssertableTo(V *Interface, T Type) error {
+func (check *Checker) newAssertableTo(V *Interface, T Type) bool {
 	// no static check is required if T is an interface
 	// spec: "If T is an interface type, x.(T) asserts that the
 	//        dynamic type of x implements the interface T."
 	if IsInterface(T) {
-		return nil
+		return true
 	}
-	return check.implements(T, V)
+	return check.implements(T, V, false, nil)
 }
 
 // deref dereferences typ if it is a *Pointer and returns its base and true.
diff --git a/src/cmd/compile/internal/types2/lookup_test.go b/src/cmd/compile/internal/types2/lookup_test.go
new file mode 100644
index 0000000..56fe48c
--- /dev/null
+++ b/src/cmd/compile/internal/types2/lookup_test.go
@@ -0,0 +1,55 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types2_test
+
+import (
+	"path/filepath"
+	"runtime"
+	"testing"
+
+	. "cmd/compile/internal/types2"
+)
+
+// BenchmarkLookupFieldOrMethod measures types.LookupFieldOrMethod performance.
+// LookupFieldOrMethod is a performance hotspot for both type-checking and
+// external API calls.
+func BenchmarkLookupFieldOrMethod(b *testing.B) {
+	// Choose an arbitrary, large package.
+	path := filepath.Join(runtime.GOROOT(), "src", "net", "http")
+
+	files, err := pkgFiles(path)
+	if err != nil {
+		b.Fatal(err)
+	}
+
+	conf := Config{
+		Importer: defaultImporter(),
+	}
+
+	pkg, err := conf.Check("http", files, nil)
+	if err != nil {
+		b.Fatal(err)
+	}
+
+	scope := pkg.Scope()
+	names := scope.Names()
+
+	// Look up an arbitrary name for each type referenced in the package scope.
+	lookup := func() {
+		for _, name := range names {
+			typ := scope.Lookup(name).Type()
+			LookupFieldOrMethod(typ, true, pkg, "m")
+		}
+	}
+
+	// Perform a lookup once, to ensure that any lazily-evaluated state is
+	// complete.
+	lookup()
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		lookup()
+	}
+}
diff --git a/src/cmd/compile/internal/types2/mono.go b/src/cmd/compile/internal/types2/mono.go
index 7bd79f4..eb1d5e7 100644
--- a/src/cmd/compile/internal/types2/mono.go
+++ b/src/cmd/compile/internal/types2/mono.go
@@ -6,6 +6,7 @@
 
 import (
 	"cmd/compile/internal/syntax"
+	. "internal/types/errors"
 )
 
 // This file implements a check to validate that a Go package doesn't
@@ -137,6 +138,7 @@
 	// TODO(mdempsky): Pivot stack so we report the cycle from the top?
 
 	var err error_
+	err.code = InvalidInstanceCycle
 	obj0 := check.mono.vertices[v].obj
 	err.errorf(obj0, "instantiation cycle:")
 
diff --git a/src/cmd/compile/internal/types2/mono_test.go b/src/cmd/compile/internal/types2/mono_test.go
index 4511110..8900992 100644
--- a/src/cmd/compile/internal/types2/mono_test.go
+++ b/src/cmd/compile/internal/types2/mono_test.go
@@ -5,7 +5,6 @@
 package types2_test
 
 import (
-	"bytes"
 	"cmd/compile/internal/syntax"
 	"cmd/compile/internal/types2"
 	"errors"
@@ -22,7 +21,7 @@
 	}
 	files := []*syntax.File{file}
 
-	var buf bytes.Buffer
+	var buf strings.Builder
 	conf := types2.Config{
 		Error:    func(err error) { fmt.Fprintln(&buf, err) },
 		Importer: defaultImporter(),
diff --git a/src/cmd/compile/internal/types2/named_test.go b/src/cmd/compile/internal/types2/named_test.go
index e5e8edd..4140bca 100644
--- a/src/cmd/compile/internal/types2/named_test.go
+++ b/src/cmd/compile/internal/types2/named_test.go
@@ -31,10 +31,7 @@
 
 type Inst = G[int]
 	`
-	pkg, err := pkgFor("p", src, nil)
-	if err != nil {
-		b.Fatal(err)
-	}
+	pkg := mustTypecheck("p", src, nil)
 
 	var (
 		T        = pkg.Scope().Lookup("T").Type()
@@ -95,10 +92,7 @@
 type Inst = *Tree[int]
 `
 
-	f, err := parseSrc("foo.go", src)
-	if err != nil {
-		t.Fatal(err)
-	}
+	f := mustParse("foo.go", src)
 	pkg := NewPackage("p", f.PkgName.Value)
 	if err := NewChecker(nil, pkg, nil).Files([]*syntax.File{f}); err != nil {
 		t.Fatal(err)
diff --git a/src/cmd/compile/internal/types2/object.go b/src/cmd/compile/internal/types2/object.go
index df080f0..5c0ea8c 100644
--- a/src/cmd/compile/internal/types2/object.go
+++ b/src/cmd/compile/internal/types2/object.go
@@ -189,7 +189,7 @@
 //
 // Objects are ordered nil before non-nil, exported before
 // non-exported, then by name, and finally (for non-exported
-// functions) by package height and path.
+// functions) by package path.
 func (a *object) less(b *object) bool {
 	if a == b {
 		return false
@@ -215,9 +215,6 @@
 		return a.name < b.name
 	}
 	if !ea {
-		if a.pkg.height != b.pkg.height {
-			return a.pkg.height < b.pkg.height
-		}
 		return a.pkg.path < b.pkg.path
 	}
 
@@ -515,7 +512,7 @@
 
 	// For package-level objects, qualify the name.
 	if obj.Pkg() != nil && obj.Pkg().scope.Lookup(obj.Name()) == obj {
-		writePackage(buf, obj.Pkg(), qf)
+		buf.WriteString(packagePrefix(obj.Pkg(), qf))
 	}
 	buf.WriteString(obj.Name())
 
@@ -556,9 +553,9 @@
 	WriteType(buf, typ, qf)
 }
 
-func writePackage(buf *bytes.Buffer, pkg *Package, qf Qualifier) {
+func packagePrefix(pkg *Package, qf Qualifier) string {
 	if pkg == nil {
-		return
+		return ""
 	}
 	var s string
 	if qf != nil {
@@ -567,9 +564,9 @@
 		s = pkg.Path()
 	}
 	if s != "" {
-		buf.WriteString(s)
-		buf.WriteByte('.')
+		s += "."
 	}
+	return s
 }
 
 // ObjectString returns the string form of obj.
@@ -607,7 +604,7 @@
 			buf.WriteByte(')')
 			buf.WriteByte('.')
 		} else if f.pkg != nil {
-			writePackage(buf, f.pkg, qf)
+			buf.WriteString(packagePrefix(f.pkg, qf))
 		}
 	}
 	buf.WriteString(f.name)
diff --git a/src/cmd/compile/internal/types2/object_test.go b/src/cmd/compile/internal/types2/object_test.go
index 8f0303d..fa036ec 100644
--- a/src/cmd/compile/internal/types2/object_test.go
+++ b/src/cmd/compile/internal/types2/object_test.go
@@ -59,10 +59,7 @@
 	const src = `package p; type I interface { error }`
 
 	// type-check src
-	f, err := parseSrc("", src)
-	if err != nil {
-		t.Fatalf("parse failed: %s", err)
-	}
+	f := mustParse("", src)
 	var conf Config
 	pkg, err := conf.Check(f.PkgName.Value, []*syntax.File{f}, nil)
 	if err != nil {
@@ -121,7 +118,7 @@
 
 	for _, test := range testObjects {
 		src := "package p; " + test.src
-		pkg, err := makePkg(src)
+		pkg, err := typecheck(filename, src, nil)
 		if err != nil {
 			t.Errorf("%s: %s", src, err)
 			continue
diff --git a/src/cmd/compile/internal/types2/operand.go b/src/cmd/compile/internal/types2/operand.go
index 548244e..e49afee 100644
--- a/src/cmd/compile/internal/types2/operand.go
+++ b/src/cmd/compile/internal/types2/operand.go
@@ -12,6 +12,7 @@
 	"fmt"
 	"go/constant"
 	"go/token"
+	. "internal/types/errors"
 )
 
 // An operandMode specifies the (addressing) mode of an operand.
@@ -174,7 +175,7 @@
 		if x.typ != Typ[Invalid] {
 			var intro string
 			if isGeneric(x.typ) {
-				intro = " of parameterized type "
+				intro = " of generic type "
 			} else {
 				intro = " of type "
 			}
@@ -183,6 +184,10 @@
 			if tpar, _ := x.typ.(*TypeParam); tpar != nil {
 				buf.WriteString(" constrained by ")
 				WriteType(&buf, tpar.bound, qf) // do not compute interface type sets here
+				// If we have the type set and it's empty, say so for better error messages.
+				if hasEmptyTypeset(tpar) {
+					buf.WriteString(" with empty type set")
+				}
 			}
 		} else {
 			buf.WriteString(" with invalid type")
@@ -234,12 +239,12 @@
 func (x *operand) isNil() bool { return x.mode == nilvalue }
 
 // assignableTo reports whether x is assignable to a variable of type T. If the
-// result is false and a non-nil reason is provided, it may be set to a more
+// result is false and a non-nil cause is provided, it may be set to a more
 // detailed explanation of the failure (result != ""). The returned error code
 // is only valid if the (first) result is false. The check parameter may be nil
 // if assignableTo is invoked through an exported API call, i.e., when all
 // methods have been type-checked.
-func (x *operand) assignableTo(check *Checker, T Type, reason *string) (bool, errorCode) {
+func (x *operand) assignableTo(check *Checker, T Type, cause *string) (bool, Code) {
 	if x.mode == invalid || T == Typ[Invalid] {
 		return true, 0 // avoid spurious errors
 	}
@@ -271,10 +276,10 @@
 				// don't need to do anything special.
 				newType, _, _ := check.implicitTypeAndValue(x, t.typ)
 				return newType != nil
-			}), _IncompatibleAssign
+			}), IncompatibleAssign
 		}
 		newType, _, _ := check.implicitTypeAndValue(x, T)
-		return newType != nil, _IncompatibleAssign
+		return newType != nil, IncompatibleAssign
 	}
 	// Vu is typed
 
@@ -288,23 +293,20 @@
 	// T is an interface type and x implements T and T is not a type parameter.
 	// Also handle the case where T is a pointer to an interface.
 	if _, ok := Tu.(*Interface); ok && Tp == nil || isInterfacePtr(Tu) {
-		if err := check.implements(V, T); err != nil {
-			if reason != nil {
-				*reason = err.Error()
-			}
-			return false, _InvalidIfaceAssign
+		if !check.implements(V, T, false, cause) {
+			return false, InvalidIfaceAssign
 		}
 		return true, 0
 	}
 
 	// If V is an interface, check if a missing type assertion is the problem.
 	if Vi, _ := Vu.(*Interface); Vi != nil && Vp == nil {
-		if check.implements(T, V) == nil {
+		if check.implements(T, V, false, nil) {
 			// T implements V, so give hint about type assertion.
-			if reason != nil {
-				*reason = "need type assertion"
+			if cause != nil {
+				*cause = "need type assertion"
 			}
-			return false, _IncompatibleAssign
+			return false, IncompatibleAssign
 		}
 	}
 
@@ -313,22 +315,22 @@
 	// and at least one of V or T is not a named type.
 	if Vc, ok := Vu.(*Chan); ok && Vc.dir == SendRecv {
 		if Tc, ok := Tu.(*Chan); ok && Identical(Vc.elem, Tc.elem) {
-			return !hasName(V) || !hasName(T), _InvalidChanAssign
+			return !hasName(V) || !hasName(T), InvalidChanAssign
 		}
 	}
 
 	// optimization: if we don't have type parameters, we're done
 	if Vp == nil && Tp == nil {
-		return false, _IncompatibleAssign
+		return false, IncompatibleAssign
 	}
 
 	errorf := func(format string, args ...interface{}) {
-		if check != nil && reason != nil {
+		if check != nil && cause != nil {
 			msg := check.sprintf(format, args...)
-			if *reason != "" {
-				msg += "\n\t" + *reason
+			if *cause != "" {
+				msg += "\n\t" + *cause
 			}
-			*reason = msg
+			*cause = msg
 		}
 	}
 
@@ -336,12 +338,12 @@
 	// x is assignable to each specific type in T's type set.
 	if !hasName(V) && Tp != nil {
 		ok := false
-		code := _IncompatibleAssign
+		code := IncompatibleAssign
 		Tp.is(func(T *term) bool {
 			if T == nil {
 				return false // no specific types
 			}
-			ok, code = x.assignableTo(check, T.typ, reason)
+			ok, code = x.assignableTo(check, T.typ, cause)
 			if !ok {
 				errorf("cannot assign %s to %s (in %s)", x.typ, T.typ, Tp)
 				return false
@@ -357,13 +359,13 @@
 	if Vp != nil && !hasName(T) {
 		x := *x // don't clobber outer x
 		ok := false
-		code := _IncompatibleAssign
+		code := IncompatibleAssign
 		Vp.is(func(V *term) bool {
 			if V == nil {
 				return false // no specific types
 			}
 			x.typ = V.typ
-			ok, code = x.assignableTo(check, T, reason)
+			ok, code = x.assignableTo(check, T, cause)
 			if !ok {
 				errorf("cannot assign %s (in %s) to %s", V.typ, Vp, T)
 				return false
@@ -373,7 +375,7 @@
 		return ok, code
 	}
 
-	return false, _IncompatibleAssign
+	return false, IncompatibleAssign
 }
 
 // kind2tok translates syntax.LitKinds into token.Tokens.
diff --git a/src/cmd/compile/internal/types2/package.go b/src/cmd/compile/internal/types2/package.go
index 8044e7e..61670f6 100644
--- a/src/cmd/compile/internal/types2/package.go
+++ b/src/cmd/compile/internal/types2/package.go
@@ -14,7 +14,6 @@
 	name     string
 	scope    *Scope
 	imports  []*Package
-	height   int
 	complete bool
 	fake     bool // scope lookup errors are silently dropped if package is fake (internal use only)
 	cgo      bool // uses of this package will be rewritten into uses of declarations from _cgo_gotypes.go
@@ -23,14 +22,8 @@
 // NewPackage returns a new Package for the given package path and name.
 // The package is not complete and contains no explicit imports.
 func NewPackage(path, name string) *Package {
-	return NewPackageHeight(path, name, 0)
-}
-
-// NewPackageHeight is like NewPackage, but allows specifying the
-// package's height.
-func NewPackageHeight(path, name string, height int) *Package {
 	scope := NewScope(Universe, nopos, nopos, fmt.Sprintf("package %q", path))
-	return &Package{path: path, name: name, scope: scope, height: height}
+	return &Package{path: path, name: name, scope: scope}
 }
 
 // Path returns the package path.
@@ -39,9 +32,6 @@
 // Name returns the package name.
 func (pkg *Package) Name() string { return pkg.name }
 
-// Height returns the package height.
-func (pkg *Package) Height() int { return pkg.height }
-
 // SetName sets the package name.
 func (pkg *Package) SetName(name string) { pkg.name = name }
 
@@ -69,6 +59,9 @@
 // If pkg was loaded from export data, Imports includes packages that
 // provide package-level objects referenced by pkg. This may be more or
 // less than the set of packages directly imported by pkg's source code.
+//
+// If pkg uses cgo and the FakeImportC configuration option
+// was enabled, the imports list may contain a fake "C" package.
 func (pkg *Package) Imports() []*Package { return pkg.imports }
 
 // SetImports sets the list of explicitly imported packages to list.
diff --git a/src/cmd/compile/internal/types2/predicates.go b/src/cmd/compile/internal/types2/predicates.go
index c4d11dc..acc1549 100644
--- a/src/cmd/compile/internal/types2/predicates.go
+++ b/src/cmd/compile/internal/types2/predicates.go
@@ -96,6 +96,18 @@
 	return ok
 }
 
+// hasEmptyTypeset reports whether t is a type parameter with an empty type set.
+// The function does not force the computation of the type set and so is safe to
+// use anywhere, but it may report a false negative if the type set has not been
+// computed yet.
+func hasEmptyTypeset(t Type) bool {
+	if tpar, _ := t.(*TypeParam); tpar != nil && tpar.bound != nil {
+		iface, _ := safeUnderlying(tpar.bound).(*Interface)
+		return iface != nil && iface.tset != nil && iface.tset.IsEmpty()
+	}
+	return false
+}
+
 // isGeneric reports whether a type is a generic, uninstantiated type
 // (generic signatures are not included).
 // TODO(gri) should we include signatures or assert that they are not present?
diff --git a/src/cmd/compile/internal/types2/resolver.go b/src/cmd/compile/internal/types2/resolver.go
index 5d498b6..cb29f72 100644
--- a/src/cmd/compile/internal/types2/resolver.go
+++ b/src/cmd/compile/internal/types2/resolver.go
@@ -8,6 +8,7 @@
 	"cmd/compile/internal/syntax"
 	"fmt"
 	"go/constant"
+	. "internal/types/errors"
 	"sort"
 	"strconv"
 	"strings"
@@ -52,17 +53,18 @@
 	l := len(names)
 	r := len(inits)
 
+	const code = WrongAssignCount
 	switch {
 	case l < r:
 		n := inits[l]
 		if inherited {
-			check.errorf(pos, "extra init expr at %s", n.Pos())
+			check.errorf(pos, code, "extra init expr at %s", n.Pos())
 		} else {
-			check.errorf(n, "extra init expr %s", n)
+			check.errorf(n, code, "extra init expr %s", n)
 		}
 	case l > r && (constDecl || r != 1): // if r == 1 it may be a multi-valued function and we can't say anything yet
 		n := names[r]
-		check.errorf(n, "missing init expr for %s", n.Value)
+		check.errorf(n, code, "missing init expr for %s", n.Value)
 	}
 }
 
@@ -91,14 +93,14 @@
 	// spec: "A package-scope or file-scope identifier with name init
 	// may only be declared to be a function with this (func()) signature."
 	if ident.Value == "init" {
-		check.error(ident, "cannot declare init - must be func")
+		check.error(ident, InvalidInitDecl, "cannot declare init - must be func")
 		return
 	}
 
 	// spec: "The main package must have package name main and declare
 	// a function main that takes no arguments and returns no value."
 	if ident.Value == "main" && check.pkg.name == "main" {
-		check.error(ident, "cannot declare main - must be func")
+		check.error(ident, InvalidMainDecl, "cannot declare main - must be func")
 		return
 	}
 
@@ -158,7 +160,7 @@
 			imp = nil // create fake package below
 		}
 		if err != nil {
-			check.errorf(pos, "could not import %s (%s)", path, err)
+			check.errorf(pos, BrokenImport, "could not import %s (%s)", path, err)
 			if imp == nil {
 				// create a new fake package
 				// come up with a sensible package name (heuristic)
@@ -197,7 +199,6 @@
 // methods with receiver base type names.
 func (check *Checker) collectObjects() {
 	pkg := check.pkg
-	pkg.height = 0
 
 	// pkgImports is the set of packages already imported by any package file seen
 	// so far. Used to avoid duplicate entries in pkg.imports. Allocate and populate
@@ -246,7 +247,7 @@
 				}
 				path, err := validatedImportPath(s.Path.Value)
 				if err != nil {
-					check.errorf(s.Path, "invalid import path (%s)", err)
+					check.errorf(s.Path, BadImportPath, "invalid import path (%s)", err)
 					continue
 				}
 
@@ -255,28 +256,19 @@
 					continue
 				}
 
-				if imp == Unsafe {
-					// typecheck ignores imports of package unsafe for
-					// calculating height.
-					// TODO(mdempsky): Revisit this. This seems fine, but I
-					// don't remember explicitly considering this case.
-				} else if h := imp.height + 1; h > pkg.height {
-					pkg.height = h
-				}
-
 				// local name overrides imported package name
 				name := imp.name
 				if s.LocalPkgName != nil {
 					name = s.LocalPkgName.Value
 					if path == "C" {
 						// match 1.17 cmd/compile (not prescribed by spec)
-						check.error(s.LocalPkgName, `cannot rename import "C"`)
+						check.error(s.LocalPkgName, ImportCRenamed, `cannot rename import "C"`)
 						continue
 					}
 				}
 
 				if name == "init" {
-					check.error(s, "cannot import package as init - init must be a func")
+					check.error(s, InvalidInitDecl, "cannot import package as init - init must be a func")
 					continue
 				}
 
@@ -323,6 +315,7 @@
 							// concurrently. See issue #32154.)
 							if alt := fileScope.Lookup(name); alt != nil {
 								var err error_
+								err.code = DuplicateDecl
 								err.errorf(s.LocalPkgName, "%s redeclared in this block", alt.Name())
 								err.recordAltDecl(alt)
 								check.report(&err)
@@ -426,12 +419,16 @@
 				if s.Recv == nil {
 					// regular function
 					if name == "init" || name == "main" && pkg.name == "main" {
+						code := InvalidInitDecl
+						if name == "main" {
+							code = InvalidMainDecl
+						}
 						if len(s.TParamList) != 0 {
-							check.softErrorf(s.TParamList[0], "func %s must have no type parameters", name)
+							check.softErrorf(s.TParamList[0], code, "func %s must have no type parameters", name)
 							hasTParamError = true
 						}
 						if t := s.Type; len(t.ParamList) != 0 || len(t.ResultList) != 0 {
-							check.softErrorf(s, "func %s must have no arguments and no return values", name)
+							check.softErrorf(s.Name, code, "func %s must have no arguments and no return values", name)
 						}
 					}
 					// don't declare init functions in the package scope - they are invisible
@@ -441,7 +438,7 @@
 						// init functions must have a body
 						if s.Body == nil {
 							// TODO(gri) make this error message consistent with the others above
-							check.softErrorf(obj.pos, "missing function body")
+							check.softErrorf(obj.pos, MissingInitBody, "missing function body")
 						}
 					} else {
 						check.declare(pkg.scope, s.Name, obj, nopos)
@@ -470,7 +467,7 @@
 				obj.setOrder(uint32(len(check.objMap)))
 
 			default:
-				check.errorf(s, invalidAST+"unknown syntax.Decl node %T", s)
+				check.errorf(s, InvalidSyntaxTree, "unknown syntax.Decl node %T", s)
 			}
 		}
 	}
@@ -481,6 +478,7 @@
 			if alt := pkg.scope.Lookup(name); alt != nil {
 				obj = resolve(name, obj)
 				var err error_
+				err.code = DuplicateDecl
 				if pkg, ok := obj.(*PkgName); ok {
 					err.errorf(alt, "%s already declared through import of %s", alt.Name(), pkg.Imported())
 					err.recordAltDecl(pkg)
@@ -552,9 +550,9 @@
 				case *syntax.BadExpr:
 					// ignore - error already reported by parser
 				case nil:
-					check.error(ptyp, invalidAST+"parameterized receiver contains nil parameters")
+					check.error(ptyp, InvalidSyntaxTree, "parameterized receiver contains nil parameters")
 				default:
-					check.errorf(arg, "receiver type parameter %s must be an identifier", arg)
+					check.errorf(arg, BadDecl, "receiver type parameter %s must be an identifier", arg)
 				}
 				if par == nil {
 					par = syntax.NewName(arg.Pos(), "_")
@@ -730,17 +728,9 @@
 		elem = elem[i+1:]
 	}
 	if obj.name == "" || obj.name == "." || obj.name == elem {
-		if check.conf.CompilerErrorMessages {
-			check.softErrorf(obj, "imported and not used: %q", path)
-		} else {
-			check.softErrorf(obj, "%q imported but not used", path)
-		}
+		check.softErrorf(obj, UnusedImport, "%q imported and not used", path)
 	} else {
-		if check.conf.CompilerErrorMessages {
-			check.softErrorf(obj, "imported and not used: %q as %s", path, obj.name)
-		} else {
-			check.softErrorf(obj, "%q imported but not used as %s", path, obj.name)
-		}
+		check.softErrorf(obj, UnusedImport, "%q imported as %s and not used", path, obj.name)
 	}
 }
 
diff --git a/src/cmd/compile/internal/types2/resolver_test.go b/src/cmd/compile/internal/types2/resolver_test.go
index a02abce..e303d34 100644
--- a/src/cmd/compile/internal/types2/resolver_test.go
+++ b/src/cmd/compile/internal/types2/resolver_test.go
@@ -117,11 +117,7 @@
 	// parse package files
 	var files []*syntax.File
 	for i, src := range sources {
-		f, err := parseSrc(fmt.Sprintf("sources[%d]", i), src)
-		if err != nil {
-			t.Fatal(err)
-		}
-		files = append(files, f)
+		files = append(files, mustParse(fmt.Sprintf("sources[%d]", i), src))
 	}
 
 	// resolve and type-check package AST
diff --git a/src/cmd/compile/internal/types2/scope.go b/src/cmd/compile/internal/types2/scope.go
index 095875d..a679a3d 100644
--- a/src/cmd/compile/internal/types2/scope.go
+++ b/src/cmd/compile/internal/types2/scope.go
@@ -7,7 +7,6 @@
 package types2
 
 import (
-	"bytes"
 	"cmd/compile/internal/syntax"
 	"fmt"
 	"io"
@@ -233,7 +232,7 @@
 
 // String returns a string representation of the scope, for debugging.
 func (s *Scope) String() string {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	s.WriteTo(&buf, 0, false)
 	return buf.String()
 }
diff --git a/src/cmd/compile/internal/types2/self_test.go b/src/cmd/compile/internal/types2/self_test.go
index 9a01ccd..e68d52d 100644
--- a/src/cmd/compile/internal/types2/self_test.go
+++ b/src/cmd/compile/internal/types2/self_test.go
@@ -6,6 +6,7 @@
 
 import (
 	"cmd/compile/internal/syntax"
+	"internal/testenv"
 	"path"
 	"path/filepath"
 	"runtime"
@@ -16,6 +17,8 @@
 )
 
 func TestSelf(t *testing.T) {
+	testenv.MustHaveGoBuild(t) // The Go command is needed for the importer to determine the locations of stdlib .a files.
+
 	files, err := pkgFiles(".")
 	if err != nil {
 		t.Fatal(err)
@@ -29,6 +32,8 @@
 }
 
 func BenchmarkCheck(b *testing.B) {
+	testenv.MustHaveGoBuild(b) // The Go command is needed for the importer to determine the locations of stdlib .a files.
+
 	for _, p := range []string{
 		filepath.Join("src", "net", "http"),
 		filepath.Join("src", "go", "parser"),
diff --git a/src/cmd/compile/internal/types2/signature.go b/src/cmd/compile/internal/types2/signature.go
index 1b61b36..61c6721 100644
--- a/src/cmd/compile/internal/types2/signature.go
+++ b/src/cmd/compile/internal/types2/signature.go
@@ -4,7 +4,11 @@
 
 package types2
 
-import "cmd/compile/internal/syntax"
+import (
+	"cmd/compile/internal/syntax"
+	"fmt"
+	. "internal/types/errors"
+)
 
 // ----------------------------------------------------------------------------
 // API
@@ -28,16 +32,18 @@
 // NewSignatureType creates a new function type for the given receiver,
 // receiver type parameters, type parameters, parameters, and results. If
 // variadic is set, params must hold at least one parameter and the last
-// parameter must be of unnamed slice type. If recv is non-nil, typeParams must
-// be empty. If recvTypeParams is non-empty, recv must be non-nil.
+// parameter's core type must be of unnamed slice or bytestring type.
+// If recv is non-nil, typeParams must be empty. If recvTypeParams is
+// non-empty, recv must be non-nil.
 func NewSignatureType(recv *Var, recvTypeParams, typeParams []*TypeParam, params, results *Tuple, variadic bool) *Signature {
 	if variadic {
 		n := params.Len()
 		if n == 0 {
 			panic("variadic function must have at least one parameter")
 		}
-		if _, ok := params.At(n - 1).typ.(*Slice); !ok {
-			panic("variadic parameter must be of unnamed slice type")
+		core := coreString(params.At(n - 1).typ)
+		if _, ok := core.(*Slice); !ok && !isString(core) {
+			panic(fmt.Sprintf("got %s, want variadic parameter with unnamed slice type or string as core type", core.String()))
 		}
 	}
 	sig := &Signature{recv: recv, params: params, results: results, variadic: variadic}
@@ -130,7 +136,7 @@
 				// Also: Don't report an error via genericType since it will be reported
 				//       again when we type-check the signature.
 				// TODO(gri) maybe the receiver should be marked as invalid instead?
-				if recv, _ := check.genericType(rname, false).(*Named); recv != nil {
+				if recv, _ := check.genericType(rname, nil).(*Named); recv != nil {
 					recvTParams = recv.TypeParams().list()
 				}
 			}
@@ -151,7 +157,7 @@
 				// may lead to follow-on errors (see issues #51339, #51343).
 				// TODO(gri) find a better solution
 				got := measure(len(tparams), "type parameter")
-				check.errorf(recvPar, "got %s, but receiver base type declares %d", got, len(recvTParams))
+				check.errorf(recvPar, BadRecv, "got %s, but receiver base type declares %d", got, len(recvTParams))
 			}
 		}
 	}
@@ -173,6 +179,7 @@
 	results, _ := check.collectParams(scope, ftyp.ResultList, false)
 	scope.Squash(func(obj, alt Object) {
 		var err error_
+		err.code = DuplicateDecl
 		err.errorf(obj, "%s redeclared in this block", obj.Name())
 		err.recordAltDecl(alt)
 		check.report(&err)
@@ -189,7 +196,7 @@
 			recv = NewParam(nopos, nil, "", Typ[Invalid]) // ignore recv below
 		default:
 			// more than one receiver
-			check.error(recvList[len(recvList)-1].Pos(), "method must have exactly one receiver")
+			check.error(recvList[len(recvList)-1].Pos(), InvalidRecv, "method must have exactly one receiver")
 			fallthrough // continue with first receiver
 		case 1:
 			recv = recvList[0]
@@ -212,11 +219,11 @@
 				// The receiver type may be an instantiated type referred to
 				// by an alias (which cannot have receiver parameters for now).
 				if T.TypeArgs() != nil && sig.RecvTypeParams() == nil {
-					check.errorf(recv, "cannot define new methods on instantiated type %s", rtyp)
+					check.errorf(recv, InvalidRecv, "cannot define new methods on instantiated type %s", rtyp)
 					break
 				}
 				if T.obj.pkg != check.pkg {
-					check.errorf(recv, "cannot define new methods on non-local type %s", rtyp)
+					check.errorf(recv, InvalidRecv, "cannot define new methods on non-local type %s", rtyp)
 					break
 				}
 				var cause string
@@ -234,12 +241,12 @@
 					unreachable()
 				}
 				if cause != "" {
-					check.errorf(recv, "invalid receiver type %s (%s)", rtyp, cause)
+					check.errorf(recv, InvalidRecv, "invalid receiver type %s (%s)", rtyp, cause)
 				}
 			case *Basic:
-				check.errorf(recv, "cannot define new methods on non-local type %s", rtyp)
+				check.errorf(recv, InvalidRecv, "cannot define new methods on non-local type %s", rtyp)
 			default:
-				check.errorf(recv, "invalid receiver type %s", recv.typ)
+				check.errorf(recv, InvalidRecv, "invalid receiver type %s", recv.typ)
 			}
 		}).describef(recv, "validate receiver %s", recv)
 	}
@@ -270,7 +277,7 @@
 				if variadicOk && i == len(list)-1 {
 					variadic = true
 				} else {
-					check.softErrorf(t, "can only use ... with final parameter in list")
+					check.softErrorf(t, MisplacedDotDotDot, "can only use ... with final parameter in list")
 					// ignore ... and continue
 				}
 			}
@@ -282,7 +289,7 @@
 			// named parameter
 			name := field.Name.Value
 			if name == "" {
-				check.error(field.Name, invalidAST+"anonymous parameter")
+				check.error(field.Name, InvalidSyntaxTree, "anonymous parameter")
 				// ok to continue
 			}
 			par := NewParam(field.Name.Pos(), check.pkg, name, typ)
@@ -299,7 +306,7 @@
 	}
 
 	if named && anonymous {
-		check.error(list[0], invalidAST+"list contains both named and anonymous parameters")
+		check.error(list[0], InvalidSyntaxTree, "list contains both named and anonymous parameters")
 		// ok to continue
 	}
 
diff --git a/src/cmd/compile/internal/types2/sizeof_test.go b/src/cmd/compile/internal/types2/sizeof_test.go
index 17876d1..af82b3f 100644
--- a/src/cmd/compile/internal/types2/sizeof_test.go
+++ b/src/cmd/compile/internal/types2/sizeof_test.go
@@ -47,7 +47,7 @@
 
 		// Misc
 		{Scope{}, 60, 104},
-		{Package{}, 40, 80},
+		{Package{}, 36, 72},
 		{_TypeSet{}, 28, 56},
 	}
 
diff --git a/src/cmd/compile/internal/types2/sizes.go b/src/cmd/compile/internal/types2/sizes.go
index 4da3094..c99a12b 100644
--- a/src/cmd/compile/internal/types2/sizes.go
+++ b/src/cmd/compile/internal/types2/sizes.go
@@ -53,7 +53,7 @@
 		// is the same as unsafe.Alignof(x[0]), but at least 1."
 		return s.Alignof(t.elem)
 	case *Struct:
-		if len(t.fields) == 0 && isSyncAtomicAlign64(T) {
+		if len(t.fields) == 0 && IsSyncAtomicAlign64(T) {
 			// Special case: sync/atomic.align64 is an
 			// empty struct we recognize as a signal that
 			// the struct it contains must be
@@ -104,7 +104,7 @@
 	return a
 }
 
-func isSyncAtomicAlign64(T Type) bool {
+func IsSyncAtomicAlign64(T Type) bool {
 	named, ok := T.(*Named)
 	if !ok {
 		return false
diff --git a/src/cmd/compile/internal/types2/sizes_test.go b/src/cmd/compile/internal/types2/sizes_test.go
index 824ec83..e548c2d 100644
--- a/src/cmd/compile/internal/types2/sizes_test.go
+++ b/src/cmd/compile/internal/types2/sizes_test.go
@@ -9,6 +9,7 @@
 import (
 	"cmd/compile/internal/syntax"
 	"cmd/compile/internal/types2"
+	"internal/testenv"
 	"testing"
 )
 
@@ -18,16 +19,9 @@
 }
 
 func findStructTypeConfig(t *testing.T, src string, conf *types2.Config) *types2.Struct {
-	f, err := parseSrc("x.go", src)
-	if err != nil {
-		t.Fatal(err)
-	}
-	info := types2.Info{Types: make(map[syntax.Expr]types2.TypeAndValue)}
-	_, err = conf.Check("x", []*syntax.File{f}, &info)
-	if err != nil {
-		t.Fatal(err)
-	}
-	for _, tv := range info.Types {
+	types := make(map[syntax.Expr]types2.TypeAndValue)
+	mustTypecheck("x", src, &types2.Info{Types: types})
+	for _, tv := range types {
 		if ts, ok := tv.Type.(*types2.Struct); ok {
 			return ts
 		}
@@ -90,16 +84,13 @@
 
 const _ = unsafe.Offsetof(struct{ x int64 }{}.x)
 `
-	f, err := parseSrc("x.go", src)
-	if err != nil {
-		t.Fatal(err)
-	}
+	f := mustParse("x.go", src)
 	info := types2.Info{Types: make(map[syntax.Expr]types2.TypeAndValue)}
 	conf := types2.Config{
 		Importer: defaultImporter(),
 		Sizes:    &types2.StdSizes{WordSize: 8, MaxAlign: 8},
 	}
-	_, err = conf.Check("x", []*syntax.File{f}, &info)
+	_, err := conf.Check("x", []*syntax.File{f}, &info)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -111,6 +102,8 @@
 
 // Issue #53884.
 func TestAtomicAlign(t *testing.T) {
+	testenv.MustHaveGoBuild(t) // The Go command is needed for the importer to determine the locations of stdlib .a files.
+
 	const src = `
 package main
 
diff --git a/src/cmd/compile/internal/types2/stdlib_test.go b/src/cmd/compile/internal/types2/stdlib_test.go
index fc541a4..28df06c 100644
--- a/src/cmd/compile/internal/types2/stdlib_test.go
+++ b/src/cmd/compile/internal/types2/stdlib_test.go
@@ -29,7 +29,7 @@
 
 	pkgCount := 0
 	duration := walkPkgDirs(filepath.Join(testenv.GOROOT(t), "src"), func(dir string, filenames []string) {
-		typecheck(t, dir, filenames)
+		typecheckFiles(t, dir, filenames)
 		pkgCount++
 	}, t.Error)
 
@@ -197,6 +197,18 @@
 		"issue48230.go",  // go/types doesn't check validity of //go:xxx directives
 		"issue49767.go",  // go/types does not have constraints on channel element size
 		"issue49814.go",  // go/types does not have constraints on array size
+		"issue56103.go",  // anonymous interface cycles; will be a type checker error in 1.22
+
+		// These tests requires runtime/cgo.Incomplete, which is only available on some platforms.
+		// However, types2 does not know about build constraints.
+		"bug514.go",
+		"issue40954.go",
+		"issue42032.go",
+		"issue42076.go",
+		"issue46903.go",
+		"issue51733.go",
+		"notinheap2.go",
+		"notinheap3.go",
 	)
 }
 
@@ -212,10 +224,11 @@
 
 	// See #46027: some imports are missing for this submodule.
 	"crypto/internal/edwards25519/field/_asm": true,
+	"crypto/internal/bigmod/_asm":             true,
 }
 
-// typecheck typechecks the given package files.
-func typecheck(t *testing.T, path string, filenames []string) {
+// typecheckFiles typechecks the given package files.
+func typecheckFiles(t *testing.T, path string, filenames []string) {
 	// parse package files
 	var files []*syntax.File
 	for _, filename := range filenames {
diff --git a/src/cmd/compile/internal/types2/stmt.go b/src/cmd/compile/internal/types2/stmt.go
index 74d4164..9edcaa1 100644
--- a/src/cmd/compile/internal/types2/stmt.go
+++ b/src/cmd/compile/internal/types2/stmt.go
@@ -9,6 +9,7 @@
 import (
 	"cmd/compile/internal/syntax"
 	"go/constant"
+	. "internal/types/errors"
 	"sort"
 )
 
@@ -46,7 +47,7 @@
 	}
 
 	if sig.results.Len() > 0 && !check.isTerminating(body, "") {
-		check.error(body.Rbrace, "missing return")
+		check.error(body.Rbrace, MissingReturn, "missing return")
 	}
 
 	// spec: "Implementation restriction: A compiler may make it illegal to
@@ -66,7 +67,7 @@
 		return unused[i].pos.Cmp(unused[j].pos) < 0
 	})
 	for _, v := range unused {
-		check.softErrorf(v.pos, "%s declared but not used", v.name)
+		check.softErrorf(v.pos, UnusedVar, "%s declared and not used", v.name)
 	}
 
 	for _, scope := range scope.children {
@@ -128,7 +129,7 @@
 	for _, c := range list {
 		if c.Cases == nil {
 			if first != nil {
-				check.errorf(c, "multiple defaults (first at %s)", first.Pos())
+				check.errorf(c, DuplicateDefault, "multiple defaults (first at %s)", first.Pos())
 				// TODO(gri) probably ok to bail out after first error (and simplify this code)
 			} else {
 				first = c
@@ -142,7 +143,7 @@
 	for _, c := range list {
 		if c.Comm == nil {
 			if first != nil {
-				check.errorf(c, "multiple defaults (first at %s)", first.Pos())
+				check.errorf(c, DuplicateDefault, "multiple defaults (first at %s)", first.Pos())
 				// TODO(gri) probably ok to bail out after first error (and simplify this code)
 			} else {
 				first = c
@@ -165,7 +166,18 @@
 	check.scope = check.scope.Parent()
 }
 
-func (check *Checker) suspendedCall(keyword string, call *syntax.CallExpr) {
+func (check *Checker) suspendedCall(keyword string, call syntax.Expr) {
+	code := InvalidDefer
+	if keyword == "go" {
+		code = InvalidGo
+	}
+
+	if _, ok := call.(*syntax.CallExpr); !ok {
+		check.errorf(call, code, "expression in %s must be function call", keyword)
+		check.use(call)
+		return
+	}
+
 	var x operand
 	var msg string
 	switch check.rawExpr(&x, call, nil, false) {
@@ -173,12 +185,13 @@
 		msg = "requires function call, not conversion"
 	case expression:
 		msg = "discards result of"
+		code = UnusedResults
 	case statement:
 		return
 	default:
 		unreachable()
 	}
-	check.errorf(&x, "%s %s %s", keyword, msg, &x)
+	check.errorf(&x, code, "%s %s %s", keyword, msg, &x)
 }
 
 // goVal returns the Go value for val, or nil.
@@ -251,6 +264,7 @@
 			for _, vt := range seen[val] {
 				if Identical(v.typ, vt.typ) {
 					var err error_
+					err.code = DuplicateCase
 					err.errorf(&v, "duplicate case %s in expression switch", &v)
 					err.errorf(vt.pos, "previous case")
 					check.report(&err)
@@ -297,6 +311,7 @@
 					Ts = TypeString(T, check.qualifier)
 				}
 				var err error_
+				err.code = DuplicateCase
 				err.errorf(e, "duplicate case %s in type switch", Ts)
 				err.errorf(other, "previous case")
 				check.report(&err)
@@ -339,6 +354,7 @@
 // 				Ts = TypeString(T, check.qualifier)
 // 			}
 // 			var err error_
+//			err.code = _DuplicateCase
 // 			err.errorf(e, "duplicate case %s in type switch", Ts)
 // 			err.errorf(other, "previous case")
 // 			check.report(&err)
@@ -389,18 +405,22 @@
 		var x operand
 		kind := check.rawExpr(&x, s.X, nil, false)
 		var msg string
+		var code Code
 		switch x.mode {
 		default:
 			if kind == statement {
 				return
 			}
 			msg = "is not used"
+			code = UnusedExpr
 		case builtin:
 			msg = "must be called"
+			code = UncalledBuiltin
 		case typexpr:
 			msg = "is not an expression"
+			code = NotAnExpr
 		}
-		check.errorf(&x, "%s %s", &x, msg)
+		check.errorf(&x, code, "%s %s", &x, msg)
 
 	case *syntax.SendStmt:
 		var ch, val operand
@@ -411,16 +431,16 @@
 		}
 		u := coreType(ch.typ)
 		if u == nil {
-			check.errorf(s, invalidOp+"cannot send to %s: no core type", &ch)
+			check.errorf(s, InvalidSend, invalidOp+"cannot send to %s: no core type", &ch)
 			return
 		}
 		uch, _ := u.(*Chan)
 		if uch == nil {
-			check.errorf(s, invalidOp+"cannot send to non-channel %s", &ch)
+			check.errorf(s, InvalidSend, invalidOp+"cannot send to non-channel %s", &ch)
 			return
 		}
 		if uch.dir == RecvOnly {
-			check.errorf(s, invalidOp+"cannot send to receive-only channel %s", &ch)
+			check.errorf(s, InvalidSend, invalidOp+"cannot send to receive-only channel %s", &ch)
 			return
 		}
 		check.assignment(&val, uch.elem, "send")
@@ -430,7 +450,7 @@
 		if s.Rhs == nil {
 			// x++ or x--
 			if len(lhs) != 1 {
-				check.errorf(s, invalidAST+"%s%s requires one operand", s.Op, s.Op)
+				check.errorf(s, InvalidSyntaxTree, "%s%s requires one operand", s.Op, s.Op)
 				return
 			}
 			var x operand
@@ -439,7 +459,7 @@
 				return
 			}
 			if !allNumeric(x.typ) {
-				check.errorf(lhs[0], invalidOp+"%s%s%s (non-numeric type %s)", lhs[0], s.Op, s.Op, x.typ)
+				check.errorf(lhs[0], NonNumericIncDec, invalidOp+"%s%s%s (non-numeric type %s)", lhs[0], s.Op, s.Op, x.typ)
 				return
 			}
 			check.assignVar(lhs[0], &x)
@@ -458,7 +478,7 @@
 
 		// assignment operations
 		if len(lhs) != 1 || len(rhs) != 1 {
-			check.errorf(s, "assignment operation %s requires single-valued expressions", s.Op)
+			check.errorf(s, MultiValAssignOp, "assignment operation %s requires single-valued expressions", s.Op)
 			return
 		}
 
@@ -485,6 +505,7 @@
 			for _, obj := range res.vars {
 				if alt := check.lookup(obj.name); alt != nil && alt != obj {
 					var err error_
+					err.code = OutOfScopeResult
 					err.errorf(s, "result parameter %s not in scope at return", obj.name)
 					err.errorf(alt, "inner declaration of %s", obj)
 					check.report(&err)
@@ -510,11 +531,11 @@
 		switch s.Tok {
 		case syntax.Break:
 			if ctxt&breakOk == 0 {
-				check.error(s, "break not in for, switch, or select statement")
+				check.error(s, MisplacedBreak, "break not in for, switch, or select statement")
 			}
 		case syntax.Continue:
 			if ctxt&continueOk == 0 {
-				check.error(s, "continue not in for statement")
+				check.error(s, MisplacedContinue, "continue not in for statement")
 			}
 		case syntax.Fallthrough:
 			if ctxt&fallthroughOk == 0 {
@@ -527,13 +548,13 @@
 				default:
 					msg = "fallthrough statement out of place"
 				}
-				check.error(s, msg)
+				check.error(s, MisplacedFallthrough, msg)
 			}
 		case syntax.Goto:
 			// goto's must have labels, should have been caught above
 			fallthrough
 		default:
-			check.errorf(s, invalidAST+"branch statement: %s", s.Tok)
+			check.errorf(s, InvalidSyntaxTree, "branch statement: %s", s.Tok)
 		}
 
 	case *syntax.BlockStmt:
@@ -550,7 +571,7 @@
 		var x operand
 		check.expr(&x, s.Cond)
 		if x.mode != invalid && !allBoolean(x.typ) {
-			check.error(s.Cond, "non-boolean condition in if statement")
+			check.error(s.Cond, InvalidCond, "non-boolean condition in if statement")
 		}
 		check.stmt(inner, s.Then)
 		// The parser produces a correct AST but if it was modified
@@ -561,7 +582,7 @@
 		case *syntax.IfStmt, *syntax.BlockStmt:
 			check.stmt(inner, s.Else)
 		default:
-			check.error(s.Else, "invalid else branch in if statement")
+			check.error(s.Else, InvalidSyntaxTree, "invalid else branch in if statement")
 		}
 
 	case *syntax.SwitchStmt:
@@ -609,7 +630,7 @@
 			}
 
 			if !valid {
-				check.error(clause.Comm, "select case must be send or receive (possibly with assignment)")
+				check.error(clause.Comm, InvalidSelectCase, "select case must be send or receive (possibly with assignment)")
 				continue
 			}
 			end := s.Rbrace
@@ -640,7 +661,7 @@
 			var x operand
 			check.expr(&x, s.Cond)
 			if x.mode != invalid && !allBoolean(x.typ) {
-				check.error(s.Cond, "non-boolean condition in for statement")
+				check.error(s.Cond, InvalidCond, "non-boolean condition in for statement")
 			}
 		}
 		check.simpleStmt(s.Post)
@@ -653,7 +674,7 @@
 		check.stmt(inner, s.Body)
 
 	default:
-		check.error(s, "invalid statement")
+		check.error(s, InvalidSyntaxTree, "invalid statement")
 	}
 }
 
@@ -667,7 +688,7 @@
 		// (as a compiler would), we get all the relevant checks.
 		check.assignment(&x, nil, "switch expression")
 		if x.mode != invalid && !Comparable(x.typ) && !hasNil(x.typ) {
-			check.errorf(&x, "cannot switch on %s (%s is not comparable)", &x, x.typ)
+			check.errorf(&x, InvalidExprSwitch, "cannot switch on %s (%s is not comparable)", &x, x.typ)
 			x.mode = invalid
 		}
 	} else {
@@ -689,7 +710,7 @@
 	seen := make(valueMap) // map of seen case values to positions and types
 	for i, clause := range s.Body {
 		if clause == nil {
-			check.error(clause, invalidAST+"incorrect expression switch case")
+			check.error(clause, InvalidSyntaxTree, "incorrect expression switch case")
 			continue
 		}
 		end := s.Rbrace
@@ -720,8 +741,8 @@
 	if lhs != nil {
 		if lhs.Value == "_" {
 			// _ := x.(type) is an invalid short variable declaration
-			check.softErrorf(lhs, "no new variable on left side of :=")
-			lhs = nil // avoid declared but not used error below
+			check.softErrorf(lhs, NoNewVar, "no new variable on left side of :=")
+			lhs = nil // avoid declared and not used error below
 		} else {
 			check.recordDef(lhs, nil) // lhs variable is implicitly declared in each cause clause
 		}
@@ -737,12 +758,12 @@
 	// TODO(gri) we may want to permit type switches on type parameter values at some point
 	var sx *operand // switch expression against which cases are compared against; nil if invalid
 	if isTypeParam(x.typ) {
-		check.errorf(&x, "cannot use type switch on type parameter value %s", &x)
+		check.errorf(&x, InvalidTypeSwitch, "cannot use type switch on type parameter value %s", &x)
 	} else {
 		if _, ok := under(x.typ).(*Interface); ok {
 			sx = &x
 		} else {
-			check.errorf(&x, "%s is not an interface", &x)
+			check.errorf(&x, InvalidTypeSwitch, "%s is not an interface", &x)
 		}
 	}
 
@@ -752,7 +773,7 @@
 	seen := make(map[Type]syntax.Expr) // map of seen types to positions
 	for i, clause := range s.Body {
 		if clause == nil {
-			check.error(s, invalidAST+"incorrect type switch case")
+			check.error(s, InvalidSyntaxTree, "incorrect type switch case")
 			continue
 		}
 		end := s.Rbrace
@@ -782,7 +803,7 @@
 			}
 			check.declare(check.scope, nil, obj, scopePos)
 			check.recordImplicit(clause, obj)
-			// For the "declared but not used" error, all lhs variables act as
+			// For the "declared and not used" error, all lhs variables act as
 			// one; i.e., if any one of them is 'used', all of them are 'used'.
 			// Collect them for later analysis.
 			lhsVars = append(lhsVars, obj)
@@ -804,7 +825,7 @@
 			v.used = true // avoid usage error when checking entire function
 		}
 		if !used {
-			check.softErrorf(lhs, "%s declared but not used", lhs.Value)
+			check.softErrorf(lhs, UnusedVar, "%s declared and not used", lhs.Value)
 		}
 	}
 }
@@ -815,7 +836,7 @@
 	var sValue, sExtra syntax.Expr
 	if p, _ := sKey.(*syntax.ListExpr); p != nil {
 		if len(p.ElemList) < 2 {
-			check.error(s, invalidAST+"invalid lhs in range clause")
+			check.error(s, InvalidSyntaxTree, "invalid lhs in range clause")
 			return
 		}
 		// len(p.ElemList) >= 2
@@ -839,7 +860,7 @@
 		u := coreType(x.typ)
 		if t, _ := u.(*Chan); t != nil {
 			if sValue != nil {
-				check.softErrorf(sValue, "range over %s permits only one iteration variable", &x)
+				check.softErrorf(sValue, InvalidIterVar, "range over %s permits only one iteration variable", &x)
 				// ok to continue
 			}
 			if t.dir == SendOnly {
@@ -847,7 +868,7 @@
 			}
 		} else {
 			if sExtra != nil {
-				check.softErrorf(sExtra, "range clause permits at most two iteration variables")
+				check.softErrorf(sExtra, InvalidIterVar, "range clause permits at most two iteration variables")
 				// ok to continue
 			}
 			if u == nil {
@@ -857,9 +878,9 @@
 		key, val = rangeKeyVal(u)
 		if key == nil || cause != "" {
 			if cause == "" {
-				check.softErrorf(&x, "cannot range over %s", &x)
+				check.softErrorf(&x, InvalidRangeExpr, "cannot range over %s", &x)
 			} else {
-				check.softErrorf(&x, "cannot range over %s (%s)", &x, cause)
+				check.softErrorf(&x, InvalidRangeExpr, "cannot range over %s (%s)", &x, cause)
 			}
 			// ok to continue
 		}
@@ -897,7 +918,7 @@
 					vars = append(vars, obj)
 				}
 			} else {
-				check.errorf(lhs, "cannot declare %s", lhs)
+				check.errorf(lhs, InvalidSyntaxTree, "cannot declare %s", lhs)
 				obj = NewVar(lhs.Pos(), check.pkg, "_", nil) // dummy variable
 			}
 
@@ -920,7 +941,7 @@
 				check.declare(check.scope, nil /* recordDef already called */, obj, scopePos)
 			}
 		} else {
-			check.error(s, "no new variables on left side of :=")
+			check.error(s, NoNewVar, "no new variables on left side of :=")
 		}
 	} else {
 		// ordinary assignment
diff --git a/src/cmd/compile/internal/types2/struct.go b/src/cmd/compile/internal/types2/struct.go
index 31a3b1a..5e93cb9 100644
--- a/src/cmd/compile/internal/types2/struct.go
+++ b/src/cmd/compile/internal/types2/struct.go
@@ -6,6 +6,7 @@
 
 import (
 	"cmd/compile/internal/syntax"
+	. "internal/types/errors"
 	"strconv"
 )
 
@@ -129,7 +130,7 @@
 			pos := syntax.StartPos(f.Type)
 			name := embeddedFieldIdent(f.Type)
 			if name == nil {
-				check.errorf(pos, "invalid embedded field type %s", f.Type)
+				check.errorf(pos, InvalidSyntaxTree, "invalid embedded field type %s", f.Type)
 				name = &syntax.Name{Value: "_"} // TODO(gri) need to set position to pos
 				addInvalid(name, pos)
 				continue
@@ -152,17 +153,20 @@
 					}
 					// unsafe.Pointer is treated like a regular pointer
 					if u.kind == UnsafePointer {
-						check.error(embeddedPos, "embedded field type cannot be unsafe.Pointer")
+						check.error(embeddedPos, InvalidPtrEmbed, "embedded field type cannot be unsafe.Pointer")
 					}
 				case *Pointer:
-					check.error(embeddedPos, "embedded field type cannot be a pointer")
+					check.error(embeddedPos, InvalidPtrEmbed, "embedded field type cannot be a pointer")
 				case *Interface:
 					if isTypeParam(t) {
-						check.error(embeddedPos, "embedded field type cannot be a (pointer to a) type parameter")
+						// The error code here is inconsistent with other error codes for
+						// invalid embedding, because this restriction may be relaxed in the
+						// future, and so it did not warrant a new error code.
+						check.error(embeddedPos, MisplacedTypeParam, "embedded field type cannot be a (pointer to a) type parameter")
 						break
 					}
 					if isPtr {
-						check.error(embeddedPos, "embedded field type cannot be a pointer to an interface")
+						check.error(embeddedPos, InvalidPtrEmbed, "embedded field type cannot be a pointer to an interface")
 					}
 				}
 			}).describef(embeddedPos, "check embedded type %s", embeddedTyp)
@@ -196,6 +200,7 @@
 func (check *Checker) declareInSet(oset *objset, pos syntax.Pos, obj Object) bool {
 	if alt := oset.insert(obj); alt != nil {
 		var err error_
+		err.code = DuplicateDecl
 		err.errorf(pos, "%s redeclared", obj.Name())
 		err.recordAltDecl(alt)
 		check.report(&err)
@@ -212,7 +217,7 @@
 				return val
 			}
 		}
-		check.errorf(t, invalidAST+"incorrect tag syntax: %q", t.Value)
+		check.errorf(t, InvalidSyntaxTree, "incorrect tag syntax: %q", t.Value)
 	}
 	return ""
 }
diff --git a/src/cmd/compile/internal/types2/subst.go b/src/cmd/compile/internal/types2/subst.go
index d5a48c6..74d6294 100644
--- a/src/cmd/compile/internal/types2/subst.go
+++ b/src/cmd/compile/internal/types2/subst.go
@@ -6,7 +6,9 @@
 
 package types2
 
-import "cmd/compile/internal/syntax"
+import (
+	"cmd/compile/internal/syntax"
+)
 
 type substMap map[*TypeParam]Type
 
@@ -262,7 +264,7 @@
 		return subst.smap.lookup(t)
 
 	default:
-		unimplemented()
+		unreachable()
 	}
 
 	return typ
diff --git a/src/cmd/compile/internal/types2/termlist.go b/src/cmd/compile/internal/types2/termlist.go
index 43e43ce..196f8ab 100644
--- a/src/cmd/compile/internal/types2/termlist.go
+++ b/src/cmd/compile/internal/types2/termlist.go
@@ -4,7 +4,7 @@
 
 package types2
 
-import "bytes"
+import "strings"
 
 // A termlist represents the type set represented by the union
 // t1 ∪ y2 ∪ ... tn of the type sets of the terms t1 to tn.
@@ -17,15 +17,18 @@
 // It is in normal form.
 var allTermlist = termlist{new(term)}
 
+// termSep is the separator used between individual terms.
+const termSep = " | "
+
 // String prints the termlist exactly (without normalization).
 func (xl termlist) String() string {
 	if len(xl) == 0 {
 		return "∅"
 	}
-	var buf bytes.Buffer
+	var buf strings.Builder
 	for i, x := range xl {
 		if i > 0 {
-			buf.WriteString(" | ")
+			buf.WriteString(termSep)
 		}
 		buf.WriteString(x.String())
 	}
diff --git a/src/cmd/compile/internal/types2/testdata/check/blank.go b/src/cmd/compile/internal/types2/testdata/check/blank.go
deleted file mode 100644
index 6a2507f..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/blank.go
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package _ /* ERROR invalid package name */
diff --git a/src/cmd/compile/internal/types2/testdata/check/builtins0.go b/src/cmd/compile/internal/types2/testdata/check/builtins0.go
deleted file mode 100644
index 358e9c5..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/builtins0.go
+++ /dev/null
@@ -1,902 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// builtin calls
-
-package builtins
-
-import "unsafe"
-
-func f0() {}
-
-func append1() {
-	var b byte
-	var x int
-	var s []byte
-	_ = append() // ERROR not enough arguments
-	_ = append("foo" /* ERROR must be a slice */ )
-	_ = append(nil /* ERROR must be a slice */ , s)
-	_ = append(x /* ERROR must be a slice */ , s)
-	_ = append(s)
-	_ = append(s, nil...)
-	append /* ERROR not used */ (s)
-
-	_ = append(s, b)
-	_ = append(s, x /* ERROR cannot use x */ )
-	_ = append(s, s /* ERROR cannot use s */ )
-	_ = append(s /* ERROR not enough arguments */ ...)
-	_ = append(s, b, s /* ERROR too many arguments */ ... )
-	_ = append(s, 1, 2, 3)
-	_ = append(s, 1, 2, 3, x /* ERROR cannot use x */ , 5, 6, 6)
-	_ = append(s, 1, 2 /* ERROR too many arguments */ , s... )
-	_ = append([]interface{}(nil), 1, 2, "foo", x, 3.1425, false)
-
-	type S []byte
-	type T string
-	var t T
-	_ = append(s, "foo" /* ERROR cannot use .* in argument to append */ )
-	_ = append(s, "foo"...)
-	_ = append(S(s), "foo" /* ERROR cannot use .* in argument to append */ )
-	_ = append(S(s), "foo"...)
-	_ = append(s, t /* ERROR cannot use t */ )
-	_ = append(s, t...)
-	_ = append(s, T("foo")...)
-	_ = append(S(s), t /* ERROR cannot use t */ )
-	_ = append(S(s), t...)
-	_ = append(S(s), T("foo")...)
-	_ = append([]string{}, t /* ERROR cannot use t */ , "foo")
-	_ = append([]T{}, t, "foo")
-}
-
-// from the spec
-func append2() {
-	s0 := []int{0, 0}
-	s1 := append(s0, 2)                // append a single element     s1 == []int{0, 0, 2}
-	s2 := append(s1, 3, 5, 7)          // append multiple elements    s2 == []int{0, 0, 2, 3, 5, 7}
-	s3 := append(s2, s0...)            // append a slice              s3 == []int{0, 0, 2, 3, 5, 7, 0, 0}
-	s4 := append(s3[3:6], s3[2:]...)   // append overlapping slice    s4 == []int{3, 5, 7, 2, 3, 5, 7, 0, 0}
-
-	var t []interface{}
-	t = append(t, 42, 3.1415, "foo")   //                             t == []interface{}{42, 3.1415, "foo"}
-
-	var b []byte
-	b = append(b, "bar"...)            // append string contents      b == []byte{'b', 'a', 'r' }
-
-	_ = s4
-}
-
-func append3() {
-	f1 := func() (s []int) { return }
-	f2 := func() (s []int, x int) { return }
-	f3 := func() (s []int, x, y int) { return }
-	f5 := func() (s []interface{}, x int, y float32, z string, b bool) { return }
-	ff := func() (int, float32) { return 0, 0 }
-	_ = append(f0 /* ERROR used as value */ ())
-	_ = append(f1())
-	_ = append(f2())
-	_ = append(f3())
-	_ = append(f5())
-	_ = append(ff /* ERROR must be a slice */ ()) // TODO(gri) better error message
-}
-
-func cap1() {
-	var a [10]bool
-	var p *[20]int
-	var c chan string
-	_ = cap() // ERROR not enough arguments
-	_ = cap(1, 2) // ERROR too many arguments
-	_ = cap(42 /* ERROR invalid */)
-	const _3 = cap(a)
-	assert(_3 == 10)
-	const _4 = cap(p)
-	assert(_4 == 20)
-	_ = cap(c)
-	cap /* ERROR not used */ (c)
-
-	// issue 4744
-	type T struct{ a [10]int }
-	const _ = cap(((*T)(nil)).a)
-
-	var s [][]byte
-	_ = cap(s)
-	_ = cap(s... /* ERROR invalid use of \.\.\. */ )
-}
-
-func cap2() {
-	f1a := func() (a [10]int) { return }
-	f1s := func() (s []int) { return }
-	f2 := func() (s []int, x int) { return }
-	_ = cap(f0 /* ERROR used as value */ ())
-	_ = cap(f1a())
-	_ = cap(f1s())
-	_ = cap(f2()) // ERROR too many arguments
-}
-
-// test cases for issue 7387
-func cap3() {
-	var f = func() int { return 0 }
-	var x = f()
-	const (
-		_ = cap([4]int{})
-		_ = cap([4]int{x})
-		_ = cap /* ERROR not constant */ ([4]int{f()})
-		_ = cap /* ERROR not constant */ ([4]int{cap([]int{})})
-		_ = cap([4]int{cap([4]int{})})
-	)
-	var y float64
-	var z complex128
-	const (
-		_ = cap([4]float64{})
-		_ = cap([4]float64{y})
-		_ = cap([4]float64{real(2i)})
-		_ = cap /* ERROR not constant */ ([4]float64{real(z)})
-	)
-	var ch chan [10]int
-	const (
-		_ = cap /* ERROR not constant */ (<-ch)
-		_ = cap /* ERROR not constant */ ([4]int{(<-ch)[0]})
-	)
-}
-
-func close1() {
-	var c chan int
-	var r <-chan int
-	close() // ERROR not enough arguments
-	close(1, 2) // ERROR too many arguments
-	close(42 /* ERROR cannot close non-channel */)
-	close(r /* ERROR receive-only channel */)
-	close(c)
-	_ = close /* ERROR used as value */ (c)
-
-	var s []chan int
-	close(s... /* ERROR invalid use of \.\.\. */ )
-}
-
-func close2() {
-	f1 := func() (ch chan int) { return }
-	f2 := func() (ch chan int, x int) { return }
-	close(f0 /* ERROR used as value */ ())
-	close(f1())
-	close(f2()) // ERROR too many arguments
-}
-
-func complex1() {
-	var i32 int32
-	var f32 float32
-	var f64 float64
-	var c64 complex64
-	var c128 complex128
-	_ = complex() // ERROR not enough arguments
-	_ = complex(1) // ERROR not enough arguments
-	_ = complex(true /* ERROR mismatched types */ , 0)
-	_ = complex(i32 /* ERROR expected floating-point */ , 0)
-	_ = complex("foo" /* ERROR mismatched types */ , 0)
-	_ = complex(c64 /* ERROR expected floating-point */ , 0)
-	_ = complex(0 /* ERROR mismatched types */ , true)
-	_ = complex(0 /* ERROR expected floating-point */ , i32)
-	_ = complex(0 /* ERROR mismatched types */ , "foo")
-	_ = complex(0 /* ERROR expected floating-point */ , c64)
-	_ = complex(f32, f32)
-	_ = complex(f32, 1)
-	_ = complex(f32, 1.0)
-	_ = complex(f32, 'a')
-	_ = complex(f64, f64)
-	_ = complex(f64, 1)
-	_ = complex(f64, 1.0)
-	_ = complex(f64, 'a')
-	_ = complex(f32 /* ERROR mismatched types */ , f64)
-	_ = complex(f64 /* ERROR mismatched types */ , f32)
-	_ = complex(1, 1)
-	_ = complex(1, 1.1)
-	_ = complex(1, 'a')
-	complex /* ERROR not used */ (1, 2)
-
-	var _ complex64 = complex(f32, f32)
-	var _ complex64 = complex /* ERROR cannot use .* in variable declaration */ (f64, f64)
-
-	var _ complex128 = complex /* ERROR cannot use .* in variable declaration */ (f32, f32)
-	var _ complex128 = complex(f64, f64)
-
-	// untyped constants
-	const _ int = complex(1, 0)
-	const _ float32 = complex(1, 0)
-	const _ complex64 = complex(1, 0)
-	const _ complex128 = complex(1, 0)
-	const _ = complex(0i, 0i)
-	const _ = complex(0i, 0)
-	const _ int = 1.0 + complex(1, 0i)
-
-	const _ int = complex /* ERROR int */ (1.1, 0)
-	const _ float32 = complex /* ERROR float32 */ (1, 2)
-
-	// untyped values
-	var s uint
-	_ = complex(1 /* ERROR integer */ <<s, 0)
-	const _ = complex /* ERROR not constant */ (1 /* ERROR integer */ <<s, 0)
-	var _ int = complex /* ERROR cannot use .* in variable declaration */ (1 /* ERROR integer */ <<s, 0)
-
-	// floating-point argument types must be identical
-	type F32 float32
-	type F64 float64
-	var x32 F32
-	var x64 F64
-	c64 = complex(x32, x32)
-	_ = complex(x32 /* ERROR mismatched types */ , f32)
-	_ = complex(f32 /* ERROR mismatched types */ , x32)
-	c128 = complex(x64, x64)
-	_ = c128
-	_ = complex(x64 /* ERROR mismatched types */ , f64)
-	_ = complex(f64 /* ERROR mismatched types */ , x64)
-
-	var t []float32
-	_ = complex(t... /* ERROR invalid use of \.\.\. */ )
-}
-
-func complex2() {
-	f1 := func() (x float32) { return }
-	f2 := func() (x, y float32) { return }
-	f3 := func() (x, y, z float32) { return }
-	_ = complex(f0 /* ERROR used as value */ ())
-	_ = complex(f1()) // ERROR not enough arguments
-	_ = complex(f2())
-	_ = complex(f3()) // ERROR too many arguments
-}
-
-func copy1() {
-	copy() // ERROR not enough arguments
-	copy("foo") // ERROR not enough arguments
-	copy([ /* ERROR copy expects slice arguments */ ...]int{}, []int{})
-	copy([ /* ERROR copy expects slice arguments */ ]int{}, [...]int{})
-	copy([ /* ERROR different element types */ ]int8{}, "foo")
-
-	// spec examples
-	var a = [...]int{0, 1, 2, 3, 4, 5, 6, 7}
-	var s = make([]int, 6)
-	var b = make([]byte, 5)
-	n1 := copy(s, a[0:])            // n1 == 6, s == []int{0, 1, 2, 3, 4, 5}
-	n2 := copy(s, s[2:])            // n2 == 4, s == []int{2, 3, 4, 5, 4, 5}
-	n3 := copy(b, "Hello, World!")  // n3 == 5, b == []byte("Hello")
-	_, _, _ = n1, n2, n3
-
-	var t [][]int
-	copy(t, t)
-	copy(t /* ERROR copy expects slice arguments */ , nil)
-	copy(nil /* ERROR copy expects slice arguments */ , t)
-	copy(nil /* ERROR copy expects slice arguments */ , nil)
-	copy(t... /* ERROR invalid use of \.\.\. */ )
-}
-
-func copy2() {
-	f1 := func() (a []int) { return }
-	f2 := func() (a, b []int) { return }
-	f3 := func() (a, b, c []int) { return }
-	copy(f0 /* ERROR used as value */ ())
-	copy(f1()) // ERROR not enough arguments
-	copy(f2())
-	copy(f3()) // ERROR too many arguments
-}
-
-func delete1() {
-	var m map[string]int
-	var s string
-	delete() // ERROR not enough arguments
-	delete(1) // ERROR not enough arguments
-	delete(1, 2, 3) // ERROR too many arguments
-	delete(m, 0 /* ERROR cannot use */)
-	delete(m, s)
-	_ = delete /* ERROR used as value */ (m, s)
-
-	var t []map[string]string
-	delete(t... /* ERROR invalid use of \.\.\. */ )
-}
-
-func delete2() {
-	f1 := func() (m map[string]int) { return }
-	f2 := func() (m map[string]int, k string) { return }
-	f3 := func() (m map[string]int, k string, x float32) { return }
-	delete(f0 /* ERROR used as value */ ())
-	delete(f1()) // ERROR not enough arguments
-	delete(f2())
-	delete(f3()) // ERROR too many arguments
-}
-
-func imag1() {
-	var f32 float32
-	var f64 float64
-	var c64 complex64
-	var c128 complex128
-	_ = imag() // ERROR not enough arguments
-	_ = imag(1, 2) // ERROR too many arguments
-	_ = imag(10)
-	_ = imag(2.7182818)
-	_ = imag("foo" /* ERROR expected complex */)
-	_ = imag('a')
-	const _5 = imag(1 + 2i)
-	assert(_5 == 2)
-	f32 = _5
-	f64 = _5
-	const _6 = imag(0i)
-	assert(_6 == 0)
-	f32 = imag(c64)
-	f64 = imag(c128)
-	f32 = imag /* ERROR cannot use .* in assignment */ (c128)
-	f64 = imag /* ERROR cannot use .* in assignment */ (c64)
-	imag /* ERROR not used */ (c64)
-	_, _ = f32, f64
-
-	// complex type may not be predeclared
-	type C64 complex64
-	type C128 complex128
-	var x64 C64
-	var x128 C128
-	f32 = imag(x64)
-	f64 = imag(x128)
-
-	var a []complex64
-	_ = imag(a... /* ERROR invalid use of \.\.\. */ )
-
-	// if argument is untyped, result is untyped
-	const _ byte = imag(1.2 + 3i)
-	const _ complex128 = imag(1.2 + 3i)
-
-	// lhs constant shift operands are typed as complex128
-	var s uint
-	_ = imag(1 /* ERROR must be integer */ << s)
-}
-
-func imag2() {
-	f1 := func() (x complex128) { return }
-	f2 := func() (x, y complex128) { return }
-	_ = imag(f0 /* ERROR used as value */ ())
-	_ = imag(f1())
-	_ = imag(f2()) // ERROR too many arguments
-}
-
-func len1() {
-	const c = "foobar"
-	var a [10]bool
-	var p *[20]int
-	var m map[string]complex128
-	_ = len() // ERROR not enough arguments
-	_ = len(1, 2) // ERROR too many arguments
-	_ = len(42 /* ERROR invalid */)
-	const _3 = len(c)
-	assert(_3 == 6)
-	const _4 = len(a)
-	assert(_4 == 10)
-	const _5 = len(p)
-	assert(_5 == 20)
-	_ = len(m)
-	len /* ERROR not used */ (c)
-
-	// esoteric case
-	var t string
-	var hash map[interface{}][]*[10]int
-	const n = len /* ERROR not constant */ (hash[recover()][len(t)])
-	assert(n == 10) // ok because n has unknown value and no error is reported
-	var ch <-chan int
-	const nn = len /* ERROR not constant */ (hash[<-ch][len(t)])
-
-	// issue 4744
-	type T struct{ a [10]int }
-	const _ = len(((*T)(nil)).a)
-
-	var s [][]byte
-	_ = len(s)
-	_ = len(s... /* ERROR invalid use of \.\.\. */ )
-}
-
-func len2() {
-	f1 := func() (x []int) { return }
-	f2 := func() (x, y []int) { return }
-	_ = len(f0 /* ERROR used as value */ ())
-	_ = len(f1())
-	_ = len(f2()) // ERROR too many arguments
-}
-
-// test cases for issue 7387
-func len3() {
-	var f = func() int { return 0 }
-	var x = f()
-	const (
-		_ = len([4]int{})
-		_ = len([4]int{x})
-		_ = len /* ERROR not constant */ ([4]int{f()})
-		_ = len /* ERROR not constant */ ([4]int{len([]int{})})
-		_ = len([4]int{len([4]int{})})
-	)
-	var y float64
-	var z complex128
-	const (
-		_ = len([4]float64{})
-		_ = len([4]float64{y})
-		_ = len([4]float64{real(2i)})
-		_ = len /* ERROR not constant */ ([4]float64{real(z)})
-	)
-	var ch chan [10]int
-	const (
-		_ = len /* ERROR not constant */ (<-ch)
-		_ = len /* ERROR not constant */ ([4]int{(<-ch)[0]})
-	)
-}
-
-func make1() {
-	var n int
-	var m float32
-	var s uint
-
-	_ = make() // ERROR not enough arguments
-	_ = make(1 /* ERROR not a type */)
-	_ = make(int /* ERROR cannot make */)
-
-	// slices
-	_ = make/* ERROR arguments */ ([]int)
-	_ = make/* ERROR arguments */ ([]int, 2, 3, 4)
-	_ = make([]int, int /* ERROR not an expression */)
-	_ = make([]int, 10, float32 /* ERROR not an expression */)
-	_ = make([]int, "foo" /* ERROR cannot convert */)
-	_ = make([]int, 10, 2.3 /* ERROR truncated */)
-	_ = make([]int, 5, 10.0)
-	_ = make([]int, 0i)
-	_ = make([]int, 1.0)
-	_ = make([]int, 1.0<<s)
-	_ = make([]int, 1.1 /* ERROR int */ <<s)
-	_ = make([]int, - /* ERROR must not be negative */ 1, 10)
-	_ = make([]int, 0, - /* ERROR must not be negative */ 1)
-	_ = make([]int, - /* ERROR must not be negative */ 1, - /* ERROR must not be negative */ 1)
-	_ = make([]int, 1 /* ERROR overflows */ <<100, 1 /* ERROR overflows */ <<100)
-	_ = make([]int, 10 /* ERROR length and capacity swapped */ , 9)
-	_ = make([]int, 1 /* ERROR overflows */ <<100, 12345)
-	_ = make([]int, m /* ERROR must be integer */ )
-        _ = &make /* ERROR cannot take address */ ([]int, 0)
-
-	// maps
-	_ = make /* ERROR arguments */ (map[int]string, 10, 20)
-	_ = make(map[int]float32, int /* ERROR not an expression */)
-	_ = make(map[int]float32, "foo" /* ERROR cannot convert */)
-	_ = make(map[int]float32, 10)
-	_ = make(map[int]float32, n)
-	_ = make(map[int]float32, int64(n))
-	_ = make(map[string]bool, 10.0)
-	_ = make(map[string]bool, 10.0<<s)
-        _ = &make /* ERROR cannot take address */ (map[string]bool)
-
-	// channels
-	_ = make /* ERROR arguments */ (chan int, 10, 20)
-	_ = make(chan int, int /* ERROR not an expression */)
-	_ = make(chan<- int, "foo" /* ERROR cannot convert */)
-	_ = make(chan int, - /* ERROR must not be negative */ 10)
-	_ = make(<-chan float64, 10)
-	_ = make(chan chan int, n)
-	_ = make(chan string, int64(n))
-	_ = make(chan bool, 10.0)
-	_ = make(chan bool, 10.0<<s)
-        _ = &make /* ERROR cannot take address */ (chan bool)
-
-	make /* ERROR not used */ ([]int, 10)
-
-	var t []int
-	_ = make([]int, t[0], t[1])
-	_ = make([]int, t... /* ERROR invalid use of \.\.\. */ )
-}
-
-func make2() {
-	f1 := func() (x []int) { return }
-	_ = make(f0 /* ERROR not a type */ ())
-	_ = make(f1 /* ERROR not a type */ ())
-}
-
-func new1() {
-	_ = new() // ERROR not enough arguments
-	_ = new(1, 2) // ERROR too many arguments
-	_ = new("foo" /* ERROR not a type */)
-	p := new(float64)
-	_ = new(struct{ x, y int })
-	q := new(*float64)
-	_ = *p == **q
-	new /* ERROR not used */ (int)
-        _ = &new /* ERROR cannot take address */ (int)
-
-	_ = new(int... /* ERROR invalid use of \.\.\. */ )
-}
-
-func new2() {
-	f1 := func() (x []int) { return }
-	_ = new(f0 /* ERROR not a type */ ())
-	_ = new(f1 /* ERROR not a type */ ())
-}
-
-func panic1() {
-	panic() // ERROR not enough arguments
-	panic(1, 2) // ERROR too many arguments
-	panic(0)
-	panic("foo")
-	panic(false)
-	panic(1<<10)
-	panic(1 << /* ERROR constant shift overflow */ 1000)
-	_ = panic /* ERROR used as value */ (0)
-
-	var s []byte
-	panic(s)
-	panic(s... /* ERROR invalid use of \.\.\. */ )
-}
-
-func panic2() {
-	f1 := func() (x int) { return }
-	f2 := func() (x, y int) { return }
-	panic(f0 /* ERROR used as value */ ())
-	panic(f1())
-	panic(f2()) // ERROR too many arguments
-}
-
-func print1() {
-	print()
-	print(1)
-	print(1, 2)
-	print("foo")
-	print(2.718281828)
-	print(false)
-	print(1<<10)
-	print(1 << /* ERROR constant shift overflow */ 1000)
-	println(nil /* ERROR untyped nil */ )
-
-	var s []int
-	print(s... /* ERROR invalid use of \.\.\. */ )
-	_ = print /* ERROR used as value */ ()
-}
-
-func print2() {
-	f1 := func() (x int) { return }
-	f2 := func() (x, y int) { return }
-	f3 := func() (x int, y float32, z string) { return }
-	print(f0 /* ERROR used as value */ ())
-	print(f1())
-	print(f2())
-	print(f3())
-}
-
-func println1() {
-	println()
-	println(1)
-	println(1, 2)
-	println("foo")
-	println(2.718281828)
-	println(false)
-	println(1<<10)
-	println(1 << /* ERROR constant shift overflow */ 1000)
-	println(nil /* ERROR untyped nil */ )
-
-	var s []int
-	println(s... /* ERROR invalid use of \.\.\. */ )
-	_ = println /* ERROR used as value */ ()
-}
-
-func println2() {
-	f1 := func() (x int) { return }
-	f2 := func() (x, y int) { return }
-	f3 := func() (x int, y float32, z string) { return }
-	println(f0 /* ERROR used as value */ ())
-	println(f1())
-	println(f2())
-	println(f3())
-}
-
-func real1() {
-	var f32 float32
-	var f64 float64
-	var c64 complex64
-	var c128 complex128
-	_ = real() // ERROR not enough arguments
-	_ = real(1, 2) // ERROR too many arguments
-	_ = real(10)
-	_ = real(2.7182818)
-	_ = real("foo" /* ERROR expected complex */)
-	const _5 = real(1 + 2i)
-	assert(_5 == 1)
-	f32 = _5
-	f64 = _5
-	const _6 = real(0i)
-	assert(_6 == 0)
-	f32 = real(c64)
-	f64 = real(c128)
-	f32 = real /* ERROR cannot use .* in assignment */ (c128)
-	f64 = real /* ERROR cannot use .* in assignment */ (c64)
-	real /* ERROR not used */ (c64)
-
-	// complex type may not be predeclared
-	type C64 complex64
-	type C128 complex128
-	var x64 C64
-	var x128 C128
-	f32 = imag(x64)
-	f64 = imag(x128)
-	_, _ = f32, f64
-
-	var a []complex64
-	_ = real(a... /* ERROR invalid use of \.\.\. */ )
-
-	// if argument is untyped, result is untyped
-	const _ byte = real(1 + 2.3i)
-	const _ complex128 = real(1 + 2.3i)
-
-	// lhs constant shift operands are typed as complex128
-	var s uint
-	_ = real(1 /* ERROR must be integer */ << s)
-}
-
-func real2() {
-	f1 := func() (x complex128) { return }
-	f2 := func() (x, y complex128) { return }
-	_ = real(f0 /* ERROR used as value */ ())
-	_ = real(f1())
-	_ = real(f2()) // ERROR too many arguments
-}
-
-func recover1() {
-	_ = recover()
-	_ = recover(10) // ERROR too many arguments
-	recover()
-
-	var s []int
-	recover(s... /* ERROR invalid use of \.\.\. */ )
-}
-
-func recover2() {
-	f1 := func() (x int) { return }
-	f2 := func() (x, y int) { return }
-	_ = recover(f0 /* ERROR used as value */ ())
-	_ = recover(f1()) // ERROR too many arguments
-	_ = recover(f2()) // ERROR too many arguments
-}
-
-// assuming types.DefaultPtrSize == 8
-type S0 struct{      // offset
-	a bool       //  0
-	b rune       //  4
-	c *int       //  8
-	d bool       // 16
-	e complex128 // 24
-}                    // 40
-
-type S1 struct{   // offset
-	x float32 //  0
-	y string  //  8
-	z *S1     // 24
-	S0        // 32
-}                 // 72
-
-type S2 struct{ // offset
-	*S1     //  0
-}               //  8
-
-type S3 struct { // offset
-	a int64  //  0
-	b int32  //  8
-}                // 12
-
-type S4 struct { // offset
-	S3       //  0
-	int32    // 12
-}                // 16
-
-type S5 struct {   // offset
-	a [3]int32 //  0
-	b int32    // 12
-}                  // 16
-
-func (S2) m() {}
-
-func Alignof1() {
-	var x int
-	_ = unsafe.Alignof() // ERROR not enough arguments
-	_ = unsafe.Alignof(1, 2) // ERROR too many arguments
-	_ = unsafe.Alignof(int /* ERROR not an expression */)
-	_ = unsafe.Alignof(42)
-	_ = unsafe.Alignof(new(struct{}))
-	_ = unsafe.Alignof(1<<10)
-	_ = unsafe.Alignof(1 << /* ERROR constant shift overflow */ 1000)
-	_ = unsafe.Alignof(nil /* ERROR "untyped nil */ )
-	unsafe /* ERROR not used */ .Alignof(x)
-
-	var y S0
-	assert(unsafe.Alignof(y.a) == 1)
-	assert(unsafe.Alignof(y.b) == 4)
-	assert(unsafe.Alignof(y.c) == 8)
-	assert(unsafe.Alignof(y.d) == 1)
-	assert(unsafe.Alignof(y.e) == 8)
-
-	var s []byte
-	_ = unsafe.Alignof(s)
-	_ = unsafe.Alignof(s... /* ERROR invalid use of \.\.\. */ )
-}
-
-func Alignof2() {
-	f1 := func() (x int32) { return }
-	f2 := func() (x, y int32) { return }
-	_ = unsafe.Alignof(f0 /* ERROR used as value */ ())
-	assert(unsafe.Alignof(f1()) == 4)
-	_ = unsafe.Alignof(f2()) // ERROR too many arguments
-}
-
-func Offsetof1() {
-	var x struct{ f int }
-	_ = unsafe.Offsetof() // ERROR not enough arguments
-	_ = unsafe.Offsetof(1, 2) // ERROR too many arguments
-	_ = unsafe.Offsetof(int /* ERROR not a selector expression */ )
-	_ = unsafe.Offsetof(x /* ERROR not a selector expression */ )
-	_ = unsafe.Offsetof(nil /* ERROR not a selector expression */ )
-	_ = unsafe.Offsetof(x.f)
-	_ = unsafe.Offsetof((x.f))
-	_ = unsafe.Offsetof((((((((x))).f)))))
-	unsafe /* ERROR not used */ .Offsetof(x.f)
-
-	var y0 S0
-	assert(unsafe.Offsetof(y0.a) == 0)
-	assert(unsafe.Offsetof(y0.b) == 4)
-	assert(unsafe.Offsetof(y0.c) == 8)
-	assert(unsafe.Offsetof(y0.d) == 16)
-	assert(unsafe.Offsetof(y0.e) == 24)
-
-	var y1 S1
-	assert(unsafe.Offsetof(y1.x) == 0)
-	assert(unsafe.Offsetof(y1.y) == 8)
-	assert(unsafe.Offsetof(y1.z) == 24)
-	assert(unsafe.Offsetof(y1.S0) == 32)
-
-	assert(unsafe.Offsetof(y1.S0.a) == 0) // relative to S0
-	assert(unsafe.Offsetof(y1.a) == 32)   // relative to S1
-	assert(unsafe.Offsetof(y1.b) == 36)   // relative to S1
-	assert(unsafe.Offsetof(y1.c) == 40)   // relative to S1
-	assert(unsafe.Offsetof(y1.d) == 48)   // relative to S1
-	assert(unsafe.Offsetof(y1.e) == 56)   // relative to S1
-
-	var y1p *S1
-	assert(unsafe.Offsetof(y1p.S0) == 32)
-
-	type P *S1
-	var p P = y1p
-	assert(unsafe.Offsetof(p.S0) == 32)
-
-	var y2 S2
-	assert(unsafe.Offsetof(y2.S1) == 0)
-	_ = unsafe.Offsetof(y2 /* ERROR embedded via a pointer */ .x)
-	_ = unsafe.Offsetof(y2 /* ERROR method value */ .m)
-
-	var s []byte
-	_ = unsafe.Offsetof(s... /* ERROR invalid use of \.\.\. */ )
-}
-
-func Offsetof2() {
-	f1 := func() (x int32) { return }
-	f2 := func() (x, y int32) { return }
-	_ = unsafe.Offsetof(f0 /* ERROR not a selector expression */ ())
-	_ = unsafe.Offsetof(f1 /* ERROR not a selector expression */ ())
-	_ = unsafe.Offsetof(f2 /* ERROR not a selector expression */ ())
-}
-
-func Sizeof1() {
-	var x int
-	_ = unsafe.Sizeof() // ERROR not enough arguments
-	_ = unsafe.Sizeof(1, 2) // ERROR too many arguments
-	_ = unsafe.Sizeof(int /* ERROR not an expression */)
-	_ = unsafe.Sizeof(42)
-	_ = unsafe.Sizeof(new(complex128))
-	_ = unsafe.Sizeof(1<<10)
-	_ = unsafe.Sizeof(1 << /* ERROR constant shift overflow */ 1000)
-	_ = unsafe.Sizeof(nil /* ERROR untyped nil */ )
-	unsafe /* ERROR not used */ .Sizeof(x)
-
-	// basic types have size guarantees
-	assert(unsafe.Sizeof(byte(0)) == 1)
-	assert(unsafe.Sizeof(uint8(0)) == 1)
-	assert(unsafe.Sizeof(int8(0)) == 1)
-	assert(unsafe.Sizeof(uint16(0)) == 2)
-	assert(unsafe.Sizeof(int16(0)) == 2)
-	assert(unsafe.Sizeof(uint32(0)) == 4)
-	assert(unsafe.Sizeof(int32(0)) == 4)
-	assert(unsafe.Sizeof(float32(0)) == 4)
-	assert(unsafe.Sizeof(uint64(0)) == 8)
-	assert(unsafe.Sizeof(int64(0)) == 8)
-	assert(unsafe.Sizeof(float64(0)) == 8)
-	assert(unsafe.Sizeof(complex64(0)) == 8)
-	assert(unsafe.Sizeof(complex128(0)) == 16)
-
-	var y0 S0
-	assert(unsafe.Sizeof(y0.a) == 1)
-	assert(unsafe.Sizeof(y0.b) == 4)
-	assert(unsafe.Sizeof(y0.c) == 8)
-	assert(unsafe.Sizeof(y0.d) == 1)
-	assert(unsafe.Sizeof(y0.e) == 16)
-	assert(unsafe.Sizeof(y0) == 40)
-
-	var y1 S1
-	assert(unsafe.Sizeof(y1) == 72)
-
-	var y2 S2
-	assert(unsafe.Sizeof(y2) == 8)
-
-	var y3 S3
-	assert(unsafe.Sizeof(y3) == 12)
-
-	var y4 S4
-	assert(unsafe.Sizeof(y4) == 16)
-
-	var y5 S5
-	assert(unsafe.Sizeof(y5) == 16)
-
-	var a3 [10]S3
-	assert(unsafe.Sizeof(a3) == 156)
-
-	// test case for issue 5670
-	type T struct {
-		a int32
-		_ int32
-		c int32
-	}
-	assert(unsafe.Sizeof(T{}) == 12)
-
-	var s []byte
-	_ = unsafe.Sizeof(s)
-	_ = unsafe.Sizeof(s... /* ERROR invalid use of \.\.\. */ )
-}
-
-func Sizeof2() {
-	f1 := func() (x int64) { return }
-	f2 := func() (x, y int64) { return }
-	_ = unsafe.Sizeof(f0 /* ERROR used as value */ ())
-	assert(unsafe.Sizeof(f1()) == 8)
-	_ = unsafe.Sizeof(f2()) // ERROR too many arguments
-}
-
-// self-testing only
-func assert1() {
-	var x int
-	assert() /* ERROR not enough arguments */
-	assert(1, 2) /* ERROR too many arguments */
-	assert("foo" /* ERROR boolean constant */ )
-	assert(x /* ERROR boolean constant */)
-	assert(true)
-	assert /* ERROR failed */ (false)
-	_ = assert(true)
-
-	var s []byte
-	assert(s... /* ERROR invalid use of \.\.\. */ )
-}
-
-func assert2() {
-	f1 := func() (x bool) { return }
-	f2 := func() (x bool) { return }
-	assert(f0 /* ERROR used as value */ ())
-	assert(f1 /* ERROR boolean constant */ ())
-	assert(f2 /* ERROR boolean constant */ ())
-}
-
-// self-testing only
-func trace1() {
-	// Uncomment the code below to test trace - will produce console output
-	// _ = trace /* ERROR no value */ ()
-	// _ = trace(1)
-	// _ = trace(true, 1.2, '\'', "foo", 42i, "foo" <= "bar")
-
-	var s []byte
-	trace(s... /* ERROR invalid use of \.\.\. */ )
-}
-
-func trace2() {
-	f1 := func() (x int) { return }
-	f2 := func() (x int, y string) { return }
-	f3 := func() (x int, y string, z []int) { return }
-	_ = f1
-	_ = f2
-	_ = f3
-	// Uncomment the code below to test trace - will produce console output
-	// trace(f0())
-	// trace(f1())
-	// trace(f2())
-	// trace(f3())
-	// trace(f0(), 1)
-	// trace(f1(), 1, 2)
-	// trace(f2(), 1, 2, 3)
-	// trace(f3(), 1, 2, 3, 4)
-}
diff --git a/src/cmd/compile/internal/types2/testdata/check/builtins1.go b/src/cmd/compile/internal/types2/testdata/check/builtins1.go
deleted file mode 100644
index 7c3f0c9..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/builtins1.go
+++ /dev/null
@@ -1,274 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file tests built-in calls on generic types.
-
-package builtins
-
-import "unsafe"
-
-// close
-
-type C0 interface{ int }
-type C1 interface{ chan int }
-type C2 interface{ chan int | <-chan int }
-type C3 interface{ chan int | chan float32 }
-type C4 interface{ chan int | chan<- int }
-type C5[T any] interface{ ~chan T | chan<- T }
-
-func _[T any](ch T) {
-	close(ch /* ERROR cannot close non-channel */)
-}
-
-func _[T C0](ch T) {
-	close(ch /* ERROR cannot close non-channel */)
-}
-
-func _[T C1](ch T) {
-	close(ch)
-}
-
-func _[T C2](ch T) {
-	close(ch /* ERROR cannot close receive-only channel */)
-}
-
-func _[T C3](ch T) {
-	close(ch)
-}
-
-func _[T C4](ch T) {
-	close(ch)
-}
-
-func _[T C5[X], X any](ch T) {
-	close(ch)
-}
-
-// copy
-
-func _[T any](x, y T) {
-	copy(x /* ERROR copy expects slice arguments */ , y)
-}
-
-func _[T ~[]byte](x, y T) {
-	copy(x, y)
-	copy(x, "foo")
-	copy("foo" /* ERROR expects slice arguments */ , y)
-
-	var x2 []byte
-	copy(x2, y) // element types are identical
-	copy(y, x2) // element types are identical
-
-	type myByte byte
-	var x3 []myByte
-	copy(x3 /* ERROR different element types */ , y)
-	copy(y, x3 /* ERROR different element types */ )
-}
-
-func _[T ~[]E, E any](x T, y []E) {
-	copy(x, y)
-	copy(x /* ERROR different element types */ , "foo")
-}
-
-func _[T ~string](x []byte, y T) {
-	copy(x, y)
-	copy(y /* ERROR expects slice arguments */ , x)
-}
-
-func _[T ~[]byte|~string](x T, y []byte) {
-	copy(x /* ERROR expects slice arguments */ , y)
-	copy(y, x)
-}
-
-type L0 []int
-type L1 []int
-
-func _[T L0 | L1](x, y T) {
-	copy(x, y)
-}
-
-// delete
-
-type M0 interface{ int }
-type M1 interface{ map[string]int }
-type M2 interface { map[string]int | map[string]float64 }
-type M3 interface{ map[string]int | map[rune]int }
-type M4[K comparable, V any] interface{ map[K]V | map[rune]V }
-
-func _[T any](m T) {
-	delete(m /* ERROR not a map */, "foo")
-}
-
-func _[T M0](m T) {
-	delete(m /* ERROR not a map */, "foo")
-}
-
-func _[T M1](m T) {
-	delete(m, "foo")
-}
-
-func _[T M2](m T) {
-	delete(m, "foo")
-	delete(m, 0 /* ERROR cannot use .* as string */)
-}
-
-func _[T M3](m T) {
-	delete(m /* ERROR must have identical key types */, "foo")
-}
-
-func _[T M4[rune, V], V any](m T) {
-	delete(m, 'k')
-}
-
-func _[T M4[K, V], K comparable, V any](m T) {
-	delete(m /* ERROR must have identical key types */, "foo")
-}
-
-// make
-
-type myChan chan int
-
-func _[
-	S1 ~[]int,
-	S2 ~[]int | ~chan int,
-
-	M1 ~map[string]int,
-	M2 ~map[string]int | ~chan int,
-
-	C1 ~chan int,
-	C2 ~chan int | ~chan string,
-	C3 chan int | myChan, // single underlying type
-]() {
-	type S0 []int
-	_ = make([]int, 10)
-	_ = make(S0, 10)
-	_ = make(S1, 10)
-	_ = make /* ERROR not enough arguments */ ()
-	_ = make /* ERROR expects 2 or 3 arguments */ (S1)
-	_ = make(S1, 10, 20)
-	_ = make /* ERROR expects 2 or 3 arguments */ (S1, 10, 20, 30)
-	_ = make(S2 /* ERROR cannot make S2: no core type */ , 10)
-
-	type M0 map[string]int
-	_ = make(map[string]int)
-	_ = make(M0)
-	_ = make(M1)
-	_ = make(M1, 10)
-	_ = make/* ERROR expects 1 or 2 arguments */(M1, 10, 20)
-	_ = make(M2 /* ERROR cannot make M2: no core type */ )
-
-	type C0 chan int
-	_ = make(chan int)
-	_ = make(C0)
-	_ = make(C1)
-	_ = make(C1, 10)
-	_ = make/* ERROR expects 1 or 2 arguments */(C1, 10, 20)
-	_ = make(C2 /* ERROR cannot make C2: no core type */ )
-	_ = make(C3)
-}
-
-// unsafe.Alignof
-
-func _[T comparable]() {
-	var (
-		b int64
-		a [10]T
-		s struct{ f T }
-		p *T
-		l []T
-		f func(T)
-		i interface{ m() T }
-		c chan T
-		m map[T]T
-		t T
-	)
-
-	const bb = unsafe.Alignof(b)
-	assert(bb == 8)
-	const _ = unsafe /* ERROR not constant */ .Alignof(a)
-	const _ = unsafe /* ERROR not constant */ .Alignof(s)
-	const pp = unsafe.Alignof(p)
-	assert(pp == 8)
-	const ll = unsafe.Alignof(l)
-	assert(ll == 8)
-	const ff = unsafe.Alignof(f)
-	assert(ff == 8)
-	const ii = unsafe.Alignof(i)
-	assert(ii == 8)
-	const cc = unsafe.Alignof(c)
-	assert(cc == 8)
-	const mm = unsafe.Alignof(m)
-	assert(mm == 8)
-	const _ = unsafe /* ERROR not constant */ .Alignof(t)
-}
-
-// unsafe.Offsetof
-
-func _[T comparable]() {
-	var (
-		b struct{ _, f int64 }
-		a struct{ _, f [10]T }
-		s struct{ _, f struct{ f T } }
-		p struct{ _, f *T }
-		l struct{ _, f []T }
-		f struct{ _, f func(T) }
-		i struct{ _, f interface{ m() T } }
-		c struct{ _, f chan T }
-		m struct{ _, f map[T]T }
-		t struct{ _, f T }
-	)
-
-	const bb = unsafe.Offsetof(b.f)
-	assert(bb == 8)
-	const _ = unsafe /* ERROR not constant */ .Alignof(a)
-	const _ = unsafe /* ERROR not constant */ .Alignof(s)
-	const pp = unsafe.Offsetof(p.f)
-	assert(pp == 8)
-	const ll = unsafe.Offsetof(l.f)
-	assert(ll == 24)
-	const ff = unsafe.Offsetof(f.f)
-	assert(ff == 8)
-	const ii = unsafe.Offsetof(i.f)
-	assert(ii == 16)
-	const cc = unsafe.Offsetof(c.f)
-	assert(cc == 8)
-	const mm = unsafe.Offsetof(m.f)
-	assert(mm == 8)
-	const _ = unsafe /* ERROR not constant */ .Alignof(t)
-}
-
-// unsafe.Sizeof
-
-func _[T comparable]() {
-	var (
-		b int64
-		a [10]T
-		s struct{ f T }
-		p *T
-		l []T
-		f func(T)
-		i interface{ m() T }
-		c chan T
-		m map[T]T
-		t T
-	)
-
-	const bb = unsafe.Sizeof(b)
-	assert(bb == 8)
-	const _ = unsafe /* ERROR not constant */ .Alignof(a)
-	const _ = unsafe /* ERROR not constant */ .Alignof(s)
-	const pp = unsafe.Sizeof(p)
-	assert(pp == 8)
-	const ll = unsafe.Sizeof(l)
-	assert(ll == 24)
-	const ff = unsafe.Sizeof(f)
-	assert(ff == 8)
-	const ii = unsafe.Sizeof(i)
-	assert(ii == 16)
-	const cc = unsafe.Sizeof(c)
-	assert(cc == 8)
-	const mm = unsafe.Sizeof(m)
-	assert(mm == 8)
-	const _ = unsafe /* ERROR not constant */ .Alignof(t)
-}
diff --git a/src/cmd/compile/internal/types2/testdata/check/chans.go b/src/cmd/compile/internal/types2/testdata/check/chans.go
deleted file mode 100644
index fad2bce..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/chans.go
+++ /dev/null
@@ -1,62 +0,0 @@
-package chans
-
-import "runtime"
-
-// Ranger returns a Sender and a Receiver. The Receiver provides a
-// Next method to retrieve values. The Sender provides a Send method
-// to send values and a Close method to stop sending values. The Next
-// method indicates when the Sender has been closed, and the Send
-// method indicates when the Receiver has been freed.
-//
-// This is a convenient way to exit a goroutine sending values when
-// the receiver stops reading them.
-func Ranger[T any]() (*Sender[T], *Receiver[T]) {
-	c := make(chan T)
-	d := make(chan bool)
-	s := &Sender[T]{values: c, done: d}
-	r := &Receiver[T]{values: c, done: d}
-	runtime.SetFinalizer(r, r.finalize)
-	return s, r
-}
-
-// A sender is used to send values to a Receiver.
-type Sender[T any] struct {
-	values chan<- T
-	done <-chan bool
-}
-
-// Send sends a value to the receiver. It returns whether any more
-// values may be sent; if it returns false the value was not sent.
-func (s *Sender[T]) Send(v T) bool {
-	select {
-	case s.values <- v:
-		return true
-	case <-s.done:
-		return false
-	}
-}
-
-// Close tells the receiver that no more values will arrive.
-// After Close is called, the Sender may no longer be used.
-func (s *Sender[T]) Close() {
-	close(s.values)
-}
-
-// A Receiver receives values from a Sender.
-type Receiver[T any] struct {
-	values <-chan T
-	done chan<- bool
-}
-
-// Next returns the next value from the channel. The bool result
-// indicates whether the value is valid, or whether the Sender has
-// been closed and no more values will be received.
-func (r *Receiver[T]) Next() (T, bool) {
-	v, ok := <-r.values
-	return v, ok
-}
-
-// finalize is a finalizer for the receiver.
-func (r *Receiver[T]) finalize() {
-	close(r.done)
-}
diff --git a/src/cmd/compile/internal/types2/testdata/check/compliterals.go b/src/cmd/compile/internal/types2/testdata/check/compliterals.go
deleted file mode 100644
index 60eac97..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/compliterals.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Composite literals with parameterized types
-
-package comp_literals
-
-type myStruct struct {
-	f int
-}
-
-type slice[E any] []E
-
-func struct_literals[S struct{f int}|myStruct]() {
-	_ = S{}
-	_ = S{0}
-	_ = S{f: 0}
-
-        _ = slice[int]{1, 2, 3}
-        _ = slice[S]{{}, {0}, {f:0}}
-}
diff --git a/src/cmd/compile/internal/types2/testdata/check/const0.go b/src/cmd/compile/internal/types2/testdata/check/const0.go
deleted file mode 100644
index 229c248..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/const0.go
+++ /dev/null
@@ -1,382 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// constant declarations
-
-package const0
-
-import "unsafe"
-
-// constants declarations must be initialized by constants
-var x = 0
-const c0 = x /* ERROR "not constant" */
-
-// typed constants must have constant types
-const _ interface /* ERROR invalid constant type */ {} = 0
-
-func _ () {
-	const _ interface /* ERROR invalid constant type */ {} = 0
-	for i := 0; i < 10; i++ {} // don't crash with non-nil iota here
-}
-
-// untyped constants
-const (
-	// boolean values
-	ub0 = false
-	ub1 = true
-	ub2 = 2 < 1
-	ub3 = ui1 == uf1
-	ub4 = true /* ERROR "mismatched types untyped bool and untyped int" */ == 0
-
-	// integer values
-	ui0 = 0
-	ui1 = 1
-	ui2 = 42
-	ui3 = 3141592653589793238462643383279502884197169399375105820974944592307816406286
-	ui4 = -10
-
-	ui5 = ui0 + ui1
-	ui6 = ui1 - ui1
-	ui7 = ui2 * ui1
-	ui8 = ui3 / ui3
-	ui9 = ui3 % ui3
-
-	ui10 = 1 / 0 /* ERROR "division by zero" */
-	ui11 = ui1 / 0 /* ERROR "division by zero" */
-	ui12 = ui3 / ui0 /* ERROR "division by zero" */
-	ui13 = 1 % 0 /* ERROR "division by zero" */
-	ui14 = ui1 % 0 /* ERROR "division by zero" */
-	ui15 = ui3 % ui0 /* ERROR "division by zero" */
-
-	ui16 = ui2 & ui3
-	ui17 = ui2 | ui3
-	ui18 = ui2 ^ ui3
-	ui19 = 1 /* ERROR "invalid operation" */ % 1.0
-
-	// floating point values
-	uf0 = 0.
-	uf1 = 1.
-	uf2 = 4.2e1
-	uf3 = 3.141592653589793238462643383279502884197169399375105820974944592307816406286
-	uf4 = 1e-1
-
-	uf5 = uf0 + uf1
-	uf6 = uf1 - uf1
-	uf7 = uf2 * uf1
-	uf8 = uf3 / uf3
-	uf9 = uf3 /* ERROR "not defined" */ % uf3
-
-	uf10 = 1 / 0 /* ERROR "division by zero" */
-	uf11 = uf1 / 0 /* ERROR "division by zero" */
-	uf12 = uf3 / uf0 /* ERROR "division by zero" */
-
-	uf16 = uf2 /* ERROR "not defined" */ & uf3
-	uf17 = uf2 /* ERROR "not defined" */ | uf3
-	uf18 = uf2 /* ERROR "not defined" */ ^ uf3
-
-	// complex values
-	uc0 = 0.i
-	uc1 = 1.i
-	uc2 = 4.2e1i
-	uc3 = 3.141592653589793238462643383279502884197169399375105820974944592307816406286i
-	uc4 = 1e-1i
-
-	uc5 = uc0 + uc1
-	uc6 = uc1 - uc1
-	uc7 = uc2 * uc1
-	uc8 = uc3 / uc3
-	uc9 = uc3 /* ERROR "not defined" */ % uc3
-
-	uc10 = 1 / 0 /* ERROR "division by zero" */
-	uc11 = uc1 / 0 /* ERROR "division by zero" */
-	uc12 = uc3 / uc0 /* ERROR "division by zero" */
-
-	uc16 = uc2 /* ERROR "not defined" */ & uc3
-	uc17 = uc2 /* ERROR "not defined" */ | uc3
-	uc18 = uc2 /* ERROR "not defined" */ ^ uc3
-)
-
-type (
-	mybool bool
-	myint int
-	myfloat float64
-	mycomplex complex128
-)
-
-// typed constants
-const (
-	// boolean values
-	tb0 bool = false
-	tb1 bool = true
-	tb2 mybool = 2 < 1
-	tb3 mybool = ti1 /* ERROR "mismatched types" */ == tf1
-
-	// integer values
-	ti0 int8 = ui0
-	ti1 int32 = ui1
-	ti2 int64 = ui2
-	ti3 myint = ui3 /* ERROR "overflows" */
-	ti4 myint = ui4
-
-	ti5 = ti0 /* ERROR "mismatched types" */ + ti1
-	ti6 = ti1 - ti1
-	ti7 = ti2 /* ERROR "mismatched types" */ * ti1
-	ti8 = ti3 / ti3
-	ti9 = ti3 % ti3
-
-	ti10 = 1 / 0 /* ERROR "division by zero" */
-	ti11 = ti1 / 0 /* ERROR "division by zero" */
-	ti12 = ti3 /* ERROR "mismatched types" */ / ti0
-	ti13 = 1 % 0 /* ERROR "division by zero" */
-	ti14 = ti1 % 0 /* ERROR "division by zero" */
-	ti15 = ti3 /* ERROR "mismatched types" */ % ti0
-
-	ti16 = ti2 /* ERROR "mismatched types" */ & ti3
-	ti17 = ti2 /* ERROR "mismatched types" */ | ti4
-	ti18 = ti2 ^ ti5 // no mismatched types error because the type of ti5 is unknown
-
-	// floating point values
-	tf0 float32 = 0.
-	tf1 float32 = 1.
-	tf2 float64 = 4.2e1
-	tf3 myfloat = 3.141592653589793238462643383279502884197169399375105820974944592307816406286
-	tf4 myfloat = 1e-1
-
-	tf5 = tf0 + tf1
-	tf6 = tf1 - tf1
-	tf7 = tf2 /* ERROR "mismatched types" */ * tf1
-	tf8 = tf3 / tf3
-	tf9 = tf3 /* ERROR "not defined" */ % tf3
-
-	tf10 = 1 / 0 /* ERROR "division by zero" */
-	tf11 = tf1 / 0 /* ERROR "division by zero" */
-	tf12 = tf3 /* ERROR "mismatched types" */ / tf0
-
-	tf16 = tf2 /* ERROR "mismatched types" */ & tf3
-	tf17 = tf2 /* ERROR "mismatched types" */ | tf3
-	tf18 = tf2 /* ERROR "mismatched types" */ ^ tf3
-
-	// complex values
-	tc0 = 0.i
-	tc1 = 1.i
-	tc2 = 4.2e1i
-	tc3 = 3.141592653589793238462643383279502884197169399375105820974944592307816406286i
-	tc4 = 1e-1i
-
-	tc5 = tc0 + tc1
-	tc6 = tc1 - tc1
-	tc7 = tc2 * tc1
-	tc8 = tc3 / tc3
-	tc9 = tc3 /* ERROR "not defined" */ % tc3
-
-	tc10 = 1 / 0 /* ERROR "division by zero" */
-	tc11 = tc1 / 0 /* ERROR "division by zero" */
-	tc12 = tc3 / tc0 /* ERROR "division by zero" */
-
-	tc16 = tc2 /* ERROR "not defined" */ & tc3
-	tc17 = tc2 /* ERROR "not defined" */ | tc3
-	tc18 = tc2 /* ERROR "not defined" */ ^ tc3
-)
-
-// initialization cycles
-const (
-	a /* ERROR "initialization cycle" */ = a
-	b /* ERROR "initialization cycle" */ , c /* ERROR "initialization cycle" */, d, e = e, d, c, b // TODO(gri) should only have one cycle error
-	f float64 = d
-)
-
-// multiple initialization
-const (
-	a1, a2, a3 = 7, 3.1415926, "foo"
-	b1, b2, b3 = b3, b1, 42
-	c1, c2, c3  /* ERROR "missing init expr for c3" */ = 1, 2
-	d1, d2, d3 = 1, 2, 3, 4 /* ERROR "extra init expr 4" */
-	_p0 = assert(a1 == 7)
-	_p1 = assert(a2 == 3.1415926)
-	_p2 = assert(a3 == "foo")
-	_p3 = assert(b1 == 42)
-	_p4 = assert(b2 == 42)
-	_p5 = assert(b3 == 42)
-)
-
-func _() {
-	const (
-		a1, a2, a3 = 7, 3.1415926, "foo"
-		b1, b2, b3 = b3, b1, 42
-		c1, c2, c3  /* ERROR "missing init expr for c3" */ = 1, 2
-		d1, d2, d3 = 1, 2, 3, 4 /* ERROR "extra init expr 4" */
-		_p0 = assert(a1 == 7)
-		_p1 = assert(a2 == 3.1415926)
-		_p2 = assert(a3 == "foo")
-		_p3 = assert(b1 == 42)
-		_p4 = assert(b2 == 42)
-		_p5 = assert(b3 == 42)
-	)
-}
-
-// iota
-const (
-	iota0 = iota
-	iota1 = iota
-	iota2 = iota*2
-	_a0 = assert(iota0 == 0)
-	_a1 = assert(iota1 == 1)
-	_a2 = assert(iota2 == 4)
-	iota6 = iota*3
-
-	iota7
-	iota8
-	_a3 = assert(iota7 == 21)
-	_a4 = assert(iota8 == 24)
-)
-
-const (
-	_b0 = iota
-	_b1 = assert(iota + iota2 == 5)
-	_b2 = len([iota]int{}) // iota may appear in a type!
-	_b3 = assert(_b2 == 2)
-	_b4 = len(A{})
-)
-
-type A [iota /* ERROR "cannot use iota" */ ]int
-
-// constant expressions with operands across different
-// constant declarations must use the right iota values
-const (
-	_c0 = iota
-	_c1
-	_c2
-	_x = _c2 + _d1 + _e0 // 3
-)
-
-const (
-	_d0 = iota
-	_d1
-)
-
-const (
-	_e0 = iota
-)
-
-var _ = assert(_x == 3)
-
-// special cases
-const (
-	_n0 = nil /* ERROR "not constant" */
-	_n1 = [ /* ERROR "not constant" */ ]int{}
-)
-
-// iotas must not be usable in expressions outside constant declarations
-type _ [iota /* ERROR "iota outside constant decl" */ ]byte
-var _ = iota /* ERROR "iota outside constant decl" */
-func _() {
-	_ = iota /* ERROR "iota outside constant decl" */
-	const _ = iota
-	_ = iota /* ERROR "iota outside constant decl" */
-}
-
-func _() {
-	iota := 123
-	const x = iota /* ERROR "is not constant" */
-	var y = iota
-	_ = y
-}
-
-// iotas are usable inside closures in constant declarations (#22345)
-const (
-	_ = iota
-	_ = len([iota]byte{})
-	_ = unsafe.Sizeof(iota)
-	_ = unsafe.Sizeof(func() { _ = iota })
-	_ = unsafe.Sizeof(func() { var _ = iota })
-	_ = unsafe.Sizeof(func() { const _ = iota })
-	_ = unsafe.Sizeof(func() { type _ [iota]byte })
-	_ = unsafe.Sizeof(func() { func() int { return iota }() })
-)
-
-// verify inner and outer const declarations have distinct iotas
-const (
-	zero = iota
-	one  = iota
-	_    = unsafe.Sizeof(func() {
-		var x [iota]int // [2]int
-		const (
-			Zero = iota
-			One
-			Two
-			_ = unsafe.Sizeof([iota-1]int{} == x) // assert types are equal
-			_ = unsafe.Sizeof([Two]int{} == x)    // assert types are equal
-		)
-		var z [iota]int                           // [2]int
-		_ = unsafe.Sizeof([2]int{} == z)          // assert types are equal
-	})
-	three = iota // the sequence continues
-)
-var _ [three]int = [3]int{} // assert 'three' has correct value
-
-var (
-	_ = iota /* ERROR "iota outside constant decl" */
-	_ = unsafe.Sizeof(iota  /* ERROR "iota outside constant decl" */ )
-	_ = unsafe.Sizeof(func() { _ = iota /* ERROR "iota outside constant decl" */ })
-	_ = unsafe.Sizeof(func() { var _ = iota /* ERROR "iota outside constant decl" */ })
-	_ = unsafe.Sizeof(func() { type _ [iota /* ERROR "iota outside constant decl" */ ]byte })
-	_ = unsafe.Sizeof(func() { func() int { return iota /* ERROR "iota outside constant decl" */ }() })
-)
-
-// constant arithmetic precision and rounding must lead to expected (integer) results
-var _ = []int64{
-	0.0005 * 1e9,
-	0.001 * 1e9,
-	0.005 * 1e9,
-	0.01 * 1e9,
-	0.05 * 1e9,
-	0.1 * 1e9,
-	0.5 * 1e9,
-	1 * 1e9,
-	5 * 1e9,
-}
-
-const _ = unsafe.Sizeof(func() {
-	const _ = 0
-	_ = iota
-
-	const (
-	   zero = iota
-	   one
-	)
-	assert(one == 1)
-	assert(iota == 0)
-})
-
-// issue #52438
-const i1 = iota
-const i2 = iota
-const i3 = iota
-
-func _() {
-	assert(i1 == 0)
-	assert(i2 == 0)
-	assert(i3 == 0)
-
-	const i4 = iota
-	const i5 = iota
-	const i6 = iota
-
-	assert(i4 == 0)
-	assert(i5 == 0)
-	assert(i6 == 0)
-}
-
-// untyped constants must not get arbitrarily large
-const prec = 512 // internal maximum precision for integers
-const maxInt = (1<<(prec/2) - 1) * (1<<(prec/2) + 1) // == 1<<prec - 1
-
-const _ = maxInt + /* ERROR constant addition overflow */ 1
-const _ = -maxInt - /* ERROR constant subtraction overflow */ 1
-const _ = maxInt ^ /* ERROR constant bitwise XOR overflow */ -1
-const _ = maxInt * /* ERROR constant multiplication overflow */ 2
-const _ = maxInt << /* ERROR constant shift overflow */ 2
-const _ = 1 << /* ERROR constant shift overflow */ prec
-
-const _ = ^ /* ERROR constant bitwise complement overflow */ maxInt
diff --git a/src/cmd/compile/internal/types2/testdata/check/const1.go b/src/cmd/compile/internal/types2/testdata/check/const1.go
deleted file mode 100644
index c912801..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/const1.go
+++ /dev/null
@@ -1,334 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// constant conversions
-
-package const1
-
-import "math"
-
-const(
-	mi = ^int(0)
-	mu = ^uint(0)
-	mp = ^uintptr(0)
-
-	logSizeofInt     = uint(mi>>8&1 + mi>>16&1 + mi>>32&1)
-	logSizeofUint    = uint(mu>>8&1 + mu>>16&1 + mu>>32&1)
-	logSizeofUintptr = uint(mp>>8&1 + mp>>16&1 + mp>>32&1)
-)
-
-const (
-	minInt8 = -1<<(8<<iota - 1)
-	minInt16
-	minInt32
-	minInt64
-	minInt = -1<<(8<<logSizeofInt - 1)
-)
-
-const (
-	maxInt8 = 1<<(8<<iota - 1) - 1
-	maxInt16
-	maxInt32
-	maxInt64
-	maxInt = 1<<(8<<logSizeofInt - 1) - 1
-)
-
-const (
-	maxUint8 = 1<<(8<<iota) - 1
-	maxUint16
-	maxUint32
-	maxUint64
-	maxUint    = 1<<(8<<logSizeofUint) - 1
-	maxUintptr = 1<<(8<<logSizeofUintptr) - 1
-)
-
-const (
-	smallestFloat32 = 1.0 / (1<<(127 - 1 + 23))
-	// TODO(gri) The compiler limits integers to 512 bit and thus
-	//           we cannot compute the value (1<<(1023 - 1 + 52))
-	//           without overflow. For now we match the compiler.
-	//           See also issue #44057.
-	// smallestFloat64 = 1.0 / (1<<(1023 - 1 + 52))
-	smallestFloat64 = math.SmallestNonzeroFloat64
-)
-
-const (
-	_ = assert(smallestFloat32 > 0)
-	_ = assert(smallestFloat64 > 0)
-)
-
-const (
-	maxFloat32 = 1<<127 * (1<<24 - 1) / (1.0<<23)
-	// TODO(gri) The compiler limits integers to 512 bit and thus
-	//           we cannot compute the value 1<<1023
-	//           without overflow. For now we match the compiler.
-	//           See also issue #44057.
-	// maxFloat64 = 1<<1023 * (1<<53 - 1) / (1.0<<52)
-	maxFloat64 = math.MaxFloat64
-)
-
-const (
-	_ int8 = minInt8 /* ERROR "overflows" */ - 1
-	_ int8 = minInt8
-	_ int8 = maxInt8
-	_ int8 = maxInt8 /* ERROR "overflows" */ + 1
-	_ int8 = smallestFloat64 /* ERROR "truncated" */
-
-	_ = int8(minInt8 /* ERROR "cannot convert" */ - 1)
-	_ = int8(minInt8)
-	_ = int8(maxInt8)
-	_ = int8(maxInt8 /* ERROR "cannot convert" */ + 1)
-	_ = int8(smallestFloat64 /* ERROR "cannot convert" */)
-)
-
-const (
-	_ int16 = minInt16 /* ERROR "overflows" */ - 1
-	_ int16 = minInt16
-	_ int16 = maxInt16
-	_ int16 = maxInt16 /* ERROR "overflows" */ + 1
-	_ int16 = smallestFloat64 /* ERROR "truncated" */
-
-	_ = int16(minInt16 /* ERROR "cannot convert" */ - 1)
-	_ = int16(minInt16)
-	_ = int16(maxInt16)
-	_ = int16(maxInt16 /* ERROR "cannot convert" */ + 1)
-	_ = int16(smallestFloat64 /* ERROR "cannot convert" */)
-)
-
-const (
-	_ int32 = minInt32 /* ERROR "overflows" */ - 1
-	_ int32 = minInt32
-	_ int32 = maxInt32
-	_ int32 = maxInt32 /* ERROR "overflows" */ + 1
-	_ int32 = smallestFloat64 /* ERROR "truncated" */
-
-	_ = int32(minInt32 /* ERROR "cannot convert" */ - 1)
-	_ = int32(minInt32)
-	_ = int32(maxInt32)
-	_ = int32(maxInt32 /* ERROR "cannot convert" */ + 1)
-	_ = int32(smallestFloat64 /* ERROR "cannot convert" */)
-)
-
-const (
-	_ int64 = minInt64 /* ERROR "overflows" */ - 1
-	_ int64 = minInt64
-	_ int64 = maxInt64
-	_ int64 = maxInt64 /* ERROR "overflows" */ + 1
-	_ int64 = smallestFloat64 /* ERROR "truncated" */
-
-	_ = int64(minInt64 /* ERROR "cannot convert" */ - 1)
-	_ = int64(minInt64)
-	_ = int64(maxInt64)
-	_ = int64(maxInt64 /* ERROR "cannot convert" */ + 1)
-	_ = int64(smallestFloat64 /* ERROR "cannot convert" */)
-)
-
-const (
-	_ int = minInt /* ERROR "overflows" */ - 1
-	_ int = minInt
-	_ int = maxInt
-	_ int = maxInt /* ERROR "overflows" */ + 1
-	_ int = smallestFloat64 /* ERROR "truncated" */
-
-	_ = int(minInt /* ERROR "cannot convert" */ - 1)
-	_ = int(minInt)
-	_ = int(maxInt)
-	_ = int(maxInt /* ERROR "cannot convert" */ + 1)
-	_ = int(smallestFloat64 /* ERROR "cannot convert" */)
-)
-
-const (
-	_ uint8 = 0 /* ERROR "overflows" */ - 1
-	_ uint8 = 0
-	_ uint8 = maxUint8
-	_ uint8 = maxUint8 /* ERROR "overflows" */ + 1
-	_ uint8 = smallestFloat64 /* ERROR "truncated" */
-
-	_ = uint8(0 /* ERROR "cannot convert" */ - 1)
-	_ = uint8(0)
-	_ = uint8(maxUint8)
-	_ = uint8(maxUint8 /* ERROR "cannot convert" */ + 1)
-	_ = uint8(smallestFloat64 /* ERROR "cannot convert" */)
-)
-
-const (
-	_ uint16 = 0 /* ERROR "overflows" */ - 1
-	_ uint16 = 0
-	_ uint16 = maxUint16
-	_ uint16 = maxUint16 /* ERROR "overflows" */ + 1
-	_ uint16 = smallestFloat64 /* ERROR "truncated" */
-
-	_ = uint16(0 /* ERROR "cannot convert" */ - 1)
-	_ = uint16(0)
-	_ = uint16(maxUint16)
-	_ = uint16(maxUint16 /* ERROR "cannot convert" */ + 1)
-	_ = uint16(smallestFloat64 /* ERROR "cannot convert" */)
-)
-
-const (
-	_ uint32 = 0 /* ERROR "overflows" */ - 1
-	_ uint32 = 0
-	_ uint32 = maxUint32
-	_ uint32 = maxUint32 /* ERROR "overflows" */ + 1
-	_ uint32 = smallestFloat64 /* ERROR "truncated" */
-
-	_ = uint32(0 /* ERROR "cannot convert" */ - 1)
-	_ = uint32(0)
-	_ = uint32(maxUint32)
-	_ = uint32(maxUint32 /* ERROR "cannot convert" */ + 1)
-	_ = uint32(smallestFloat64 /* ERROR "cannot convert" */)
-)
-
-const (
-	_ uint64 = 0 /* ERROR "overflows" */ - 1
-	_ uint64 = 0
-	_ uint64 = maxUint64
-	_ uint64 = maxUint64 /* ERROR "overflows" */ + 1
-	_ uint64 = smallestFloat64 /* ERROR "truncated" */
-
-	_ = uint64(0 /* ERROR "cannot convert" */ - 1)
-	_ = uint64(0)
-	_ = uint64(maxUint64)
-	_ = uint64(maxUint64 /* ERROR "cannot convert" */ + 1)
-	_ = uint64(smallestFloat64 /* ERROR "cannot convert" */)
-)
-
-const (
-	_ uint = 0 /* ERROR "overflows" */ - 1
-	_ uint = 0
-	_ uint = maxUint
-	_ uint = maxUint /* ERROR "overflows" */ + 1
-	_ uint = smallestFloat64 /* ERROR "truncated" */
-
-	_ = uint(0 /* ERROR "cannot convert" */ - 1)
-	_ = uint(0)
-	_ = uint(maxUint)
-	_ = uint(maxUint /* ERROR "cannot convert" */ + 1)
-	_ = uint(smallestFloat64 /* ERROR "cannot convert" */)
-)
-
-const (
-	_ uintptr = 0 /* ERROR "overflows" */ - 1
-	_ uintptr = 0
-	_ uintptr = maxUintptr
-	_ uintptr = maxUintptr /* ERROR "overflows" */ + 1
-	_ uintptr = smallestFloat64 /* ERROR "truncated" */
-
-	_ = uintptr(0 /* ERROR "cannot convert" */ - 1)
-	_ = uintptr(0)
-	_ = uintptr(maxUintptr)
-	_ = uintptr(maxUintptr /* ERROR "cannot convert" */ + 1)
-	_ = uintptr(smallestFloat64 /* ERROR "cannot convert" */)
-)
-
-const (
-	_ float32 = minInt64
-	_ float64 = minInt64
-	_ complex64 = minInt64
-	_ complex128 = minInt64
-
-	_ = float32(minInt64)
-	_ = float64(minInt64)
-	_ = complex64(minInt64)
-	_ = complex128(minInt64)
-)
-
-const (
-	_ float32 = maxUint64
-	_ float64 = maxUint64
-	_ complex64 = maxUint64
-	_ complex128 = maxUint64
-
-	_ = float32(maxUint64)
-	_ = float64(maxUint64)
-	_ = complex64(maxUint64)
-	_ = complex128(maxUint64)
-)
-
-// TODO(gri) find smaller deltas below
-
-const delta32 = maxFloat32/(1 << 23)
-
-const (
-	_ float32 = - /* ERROR "overflow" */ (maxFloat32 + delta32)
-	_ float32 = -maxFloat32
-	_ float32 = maxFloat32
-	_ float32 = maxFloat32 /* ERROR "overflow" */ + delta32
-
-	_ = float32(- /* ERROR "cannot convert" */ (maxFloat32 + delta32))
-	_ = float32(-maxFloat32)
-	_ = float32(maxFloat32)
-	_ = float32(maxFloat32 /* ERROR "cannot convert" */ + delta32)
-
-	_ = assert(float32(smallestFloat32) == smallestFloat32)
-	_ = assert(float32(smallestFloat32/2) == 0)
-	_ = assert(float32(smallestFloat64) == 0)
-	_ = assert(float32(smallestFloat64/2) == 0)
-)
-
-const delta64 = maxFloat64/(1 << 52)
-
-const (
-	_ float64 = - /* ERROR "overflow" */ (maxFloat64 + delta64)
-	_ float64 = -maxFloat64
-	_ float64 = maxFloat64
-	_ float64 = maxFloat64 /* ERROR "overflow" */ + delta64
-
-	_ = float64(- /* ERROR "cannot convert" */ (maxFloat64 + delta64))
-	_ = float64(-maxFloat64)
-	_ = float64(maxFloat64)
-	_ = float64(maxFloat64 /* ERROR "cannot convert" */ + delta64)
-
-	_ = assert(float64(smallestFloat32) == smallestFloat32)
-	_ = assert(float64(smallestFloat32/2) == smallestFloat32/2)
-	_ = assert(float64(smallestFloat64) == smallestFloat64)
-	_ = assert(float64(smallestFloat64/2) == 0)
-)
-
-const (
-	_ complex64 = - /* ERROR "overflow" */ (maxFloat32 + delta32)
-	_ complex64 = -maxFloat32
-	_ complex64 = maxFloat32
-	_ complex64 = maxFloat32 /* ERROR "overflow" */ + delta32
-
-	_ = complex64(- /* ERROR "cannot convert" */ (maxFloat32 + delta32))
-	_ = complex64(-maxFloat32)
-	_ = complex64(maxFloat32)
-	_ = complex64(maxFloat32 /* ERROR "cannot convert" */ + delta32)
-)
-
-const (
-	_ complex128 = - /* ERROR "overflow" */ (maxFloat64 + delta64)
-	_ complex128 = -maxFloat64
-	_ complex128 = maxFloat64
-	_ complex128 = maxFloat64 /* ERROR "overflow" */ + delta64
-
-	_ = complex128(- /* ERROR "cannot convert" */ (maxFloat64 + delta64))
-	_ = complex128(-maxFloat64)
-	_ = complex128(maxFloat64)
-	_ = complex128(maxFloat64 /* ERROR "cannot convert" */ + delta64)
-)
-
-// Initialization of typed constant and conversion are the same:
-const (
-	f32 = 1 + smallestFloat32
-	x32 float32 = f32
-	y32 = float32(f32)
-	_ = assert(x32 - y32 == 0)
-)
-
-const (
-	f64 = 1 + smallestFloat64
-	x64 float64 = f64
-	y64 = float64(f64)
-	_ = assert(x64 - y64 == 0)
-)
-
-const (
-	_ = int8(-1) << 7
-	_ = int8 /* ERROR "overflows" */ (-1) << 8
-
-	_ = uint32(1) << 31
-	_ = uint32 /* ERROR "overflows" */ (1) << 32
-)
diff --git a/src/cmd/compile/internal/types2/testdata/check/constdecl.go b/src/cmd/compile/internal/types2/testdata/check/constdecl.go
deleted file mode 100644
index bb07a36..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/constdecl.go
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package constdecl
-
-import "math"
-import "unsafe"
-
-var v int
-
-// Const decls must be initialized by constants.
-const _ = v /* ERROR "not constant" */
-const _ = math /* ERROR "not constant" */ .Sin(0)
-const _ = int /* ERROR "not an expression" */
-
-func _() {
-	const _ = v /* ERROR "not constant" */
-	const _ = math /* ERROR "not constant" */ .Sin(0)
-	const _ = int /* ERROR "not an expression" */
-}
-
-// Identifier and expression arity must match.
-const _ /* ERROR "missing init expr for _" */
-const _ = 1, 2 /* ERROR "extra init expr 2" */
-
-const _ /* ERROR "missing init expr for _" */ int
-const _ int = 1, 2 /* ERROR "extra init expr 2" */
-
-const (
-	_ /* ERROR "missing init expr for _" */
-	_ = 1, 2 /* ERROR "extra init expr 2" */
-
-	_ /* ERROR "missing init expr for _" */ int
-	_ int = 1, 2 /* ERROR "extra init expr 2" */
-)
-
-const (
-	_ = 1
-	_
-	_, _ /* ERROR "missing init expr for _" */
-	_
-)
-
-const (
-	_, _ = 1, 2
-	_, _
-	_ /* ERROR "extra init expr at" */
-	_, _
-	_, _, _ /* ERROR "missing init expr for _" */
-	_, _
-)
-
-func _() {
-	const _ /* ERROR "missing init expr for _" */
-	const _ = 1, 2 /* ERROR "extra init expr 2" */
-
-	const _ /* ERROR "missing init expr for _" */ int
-	const _ int = 1, 2 /* ERROR "extra init expr 2" */
-
-	const (
-		_ /* ERROR "missing init expr for _" */
-		_ = 1, 2 /* ERROR "extra init expr 2" */
-
-		_ /* ERROR "missing init expr for _" */ int
-		_ int = 1, 2 /* ERROR "extra init expr 2" */
-	)
-
-	const (
-		_ = 1
-		_
-		_, _ /* ERROR "missing init expr for _" */
-		_
-	)
-
-	const (
-		_, _ = 1, 2
-		_, _
-		_ /* ERROR "extra init expr at" */
-		_, _
-		_, _, _ /* ERROR "missing init expr for _" */
-		_, _
-	)
-}
-
-// Test case for constant with invalid initialization.
-// Caused panic because the constant value was not set up (gri - 7/8/2014).
-func _() {
-	const (
-	    x string = missing /* ERROR "undeclared name" */
-	    y = x + ""
-	)
-}
-
-// Test case for constants depending on function literals (see also #22992).
-const A /* ERROR initialization cycle */ = unsafe.Sizeof(func() { _ = A })
-
-func _() {
-	// The function literal below must not see a.
-	const a = unsafe.Sizeof(func() { _ = a /* ERROR "undeclared name" */ })
-	const b = unsafe.Sizeof(func() { _ = a })
-
-	// The function literal below must not see x, y, or z.
-	const x, y, z = 0, 1, unsafe.Sizeof(func() { _ = x /* ERROR "undeclared name" */ + y /* ERROR "undeclared name" */ + z /* ERROR "undeclared name" */ })
-}
-
-// Test cases for errors in inherited constant initialization expressions.
-// Errors related to inherited initialization expressions must appear at
-// the constant identifier being declared, not at the original expression
-// (issues #42991, #42992).
-const (
-	_ byte = 255 + iota
-	/* some gap */
-	_ // ERROR overflows
-	/* some gap */
-	/* some gap */ _ /* ERROR overflows */; _ /* ERROR overflows */
-	/* some gap */
-	_ = 255 + iota
-	_ = byte /* ERROR overflows */ (255) + iota
-	_ /* ERROR overflows */
-)
-
-// Test cases from issue.
-const (
-	ok = byte(iota + 253)
-	bad
-	barn
-	bard // ERROR cannot convert
-)
-
-const (
-	c = len([1 - iota]int{})
-	d
-	e // ERROR invalid array length
-	f // ERROR invalid array length
-)
-
-// Test that identifiers in implicit (omitted) RHS
-// expressions of constant declarations are resolved
-// in the correct context; see issues #49157, #53585.
-const X = 2
-
-func _() {
-	const (
-		A    = iota // 0
-		iota = iota // 1
-		B           // 1 (iota is declared locally on prev. line)
-		C           // 1
-	)
-	assert(A == 0 && B == 1 && C == 1)
-
-	const (
-		X = X + X
-		Y
-		Z = iota
-	)
-	assert(X == 4 && Y == 8 && Z == 1)
-}
-
-// TODO(gri) move extra tests from testdata/const0.src into here
diff --git a/src/cmd/compile/internal/types2/testdata/check/conversions0.go b/src/cmd/compile/internal/types2/testdata/check/conversions0.go
deleted file mode 100644
index e1336c0..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/conversions0.go
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// conversions
-
-package conversions
-
-import "unsafe"
-
-// argument count
-var (
-	_ = int() /* ERROR "missing argument" */
-	_ = int(1, 2 /* ERROR "too many arguments" */ )
-)
-
-// numeric constant conversions are in const1.src.
-
-func string_conversions() {
-	const A = string(65)
-	assert(A == "A")
-	const E = string(-1)
-	assert(E == "\uFFFD")
-	assert(E == string(1234567890))
-
-	type myint int
-	assert(A == string(myint(65)))
-
-	type mystring string
-	const _ mystring = mystring("foo")
-
-	const _ = string(true /* ERROR "cannot convert" */ )
-	const _ = string(1.2 /* ERROR "cannot convert" */ )
-	const _ = string(nil /* ERROR "cannot convert" */ )
-
-	// issues 11357, 11353: argument must be of integer type
-	_ = string(0.0 /* ERROR "cannot convert" */ )
-	_ = string(0i /* ERROR "cannot convert" */ )
-	_ = string(1 /* ERROR "cannot convert" */ + 2i)
-}
-
-func interface_conversions() {
-	type E interface{}
-
-	type I1 interface{
-		m1()
-	}
-
-	type I2 interface{
-		m1()
-		m2(x int)
-	}
-
-	type I3 interface{
-		m1()
-		m2() int
-	}
-
-	var e E
-	var i1 I1
-	var i2 I2
-	var i3 I3
-
-	_ = E(0)
-	_ = E(nil)
-	_ = E(e)
-	_ = E(i1)
-	_ = E(i2)
-
-	_ = I1(0 /* ERROR "cannot convert" */ )
-	_ = I1(nil)
-	_ = I1(i1)
-	_ = I1(e /* ERROR "cannot convert" */ )
-	_ = I1(i2)
-
-	_ = I2(nil)
-	_ = I2(i1 /* ERROR "cannot convert" */ )
-	_ = I2(i2)
-	_ = I2(i3 /* ERROR "cannot convert" */ )
-
-	_ = I3(nil)
-	_ = I3(i1 /* ERROR "cannot convert" */ )
-	_ = I3(i2 /* ERROR "cannot convert" */ )
-	_ = I3(i3)
-
-	// TODO(gri) add more tests, improve error message
-}
-
-func issue6326() {
-	type T unsafe.Pointer
-	var x T
-	_ = uintptr(x) // see issue 6326
-}
diff --git a/src/cmd/compile/internal/types2/testdata/check/conversions1.go b/src/cmd/compile/internal/types2/testdata/check/conversions1.go
deleted file mode 100644
index 93a5f18..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/conversions1.go
+++ /dev/null
@@ -1,313 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Test various valid and invalid struct assignments and conversions.
-// Does not compile.
-
-package conversions2
-
-type I interface {
-	m()
-}
-
-// conversions between structs
-
-func _() {
-	type S struct{}
-	type T struct{}
-	var s S
-	var t T
-	var u struct{}
-	s = s
-	s = t // ERROR "cannot use .* in assignment"
-	s = u
-	s = S(s)
-	s = S(t)
-	s = S(u)
-	t = u
-	t = T(u)
-}
-
-func _() {
-	type S struct{ x int }
-	type T struct {
-		x int "foo"
-	}
-	var s S
-	var t T
-	var u struct {
-		x int "bar"
-	}
-	s = s
-	s = t // ERROR "cannot use .* in assignment"
-	s = u // ERROR "cannot use .* in assignment"
-	s = S(s)
-	s = S(t)
-	s = S(u)
-	t = u // ERROR "cannot use .* in assignment"
-	t = T(u)
-}
-
-func _() {
-	type E struct{ x int }
-	type S struct{ x E }
-	type T struct {
-		x E "foo"
-	}
-	var s S
-	var t T
-	var u struct {
-		x E "bar"
-	}
-	s = s
-	s = t // ERROR "cannot use .* in assignment"
-	s = u // ERROR "cannot use .* in assignment"
-	s = S(s)
-	s = S(t)
-	s = S(u)
-	t = u // ERROR "cannot use .* in assignment"
-	t = T(u)
-}
-
-func _() {
-	type S struct {
-		x struct {
-			x int "foo"
-		}
-	}
-	type T struct {
-		x struct {
-			x int "bar"
-		} "foo"
-	}
-	var s S
-	var t T
-	var u struct {
-		x struct {
-			x int "bar"
-		} "bar"
-	}
-	s = s
-	s = t // ERROR "cannot use .* in assignment"
-	s = u // ERROR "cannot use .* in assignment"
-	s = S(s)
-	s = S(t)
-	s = S(u)
-	t = u // ERROR "cannot use .* in assignment"
-	t = T(u)
-}
-
-func _() {
-	type E1 struct {
-		x int "foo"
-	}
-	type E2 struct {
-		x int "bar"
-	}
-	type S struct{ x E1 }
-	type T struct {
-		x E2 "foo"
-	}
-	var s S
-	var t T
-	var u struct {
-		x E2 "bar"
-	}
-	s = s
-	s = t // ERROR "cannot use .* in assignment"
-	s = u // ERROR "cannot use .* in assignment"
-	s = S(s)
-	s = S(t /* ERROR "cannot convert" */ )
-	s = S(u /* ERROR "cannot convert" */ )
-	t = u   // ERROR "cannot use .* in assignment"
-	t = T(u)
-}
-
-func _() {
-	type E struct{ x int }
-	type S struct {
-		f func(struct {
-			x int "foo"
-		})
-	}
-	type T struct {
-		f func(struct {
-			x int "bar"
-		})
-	}
-	var s S
-	var t T
-	var u struct{ f func(E) }
-	s = s
-	s = t // ERROR "cannot use .* in assignment"
-	s = u // ERROR "cannot use .* in assignment"
-	s = S(s)
-	s = S(t)
-	s = S(u /* ERROR "cannot convert" */ )
-	t = u   // ERROR "cannot use .* in assignment"
-	t = T(u /* ERROR "cannot convert" */ )
-}
-
-// conversions between pointers to structs
-
-func _() {
-	type S struct{}
-	type T struct{}
-	var s *S
-	var t *T
-	var u *struct{}
-	s = s
-	s = t // ERROR "cannot use .* in assignment"
-	s = u // ERROR "cannot use .* in assignment"
-	s = (*S)(s)
-	s = (*S)(t)
-	s = (*S)(u)
-	t = u // ERROR "cannot use .* in assignment"
-	t = (*T)(u)
-}
-
-func _() {
-	type S struct{ x int }
-	type T struct {
-		x int "foo"
-	}
-	var s *S
-	var t *T
-	var u *struct {
-		x int "bar"
-	}
-	s = s
-	s = t // ERROR "cannot use .* in assignment"
-	s = u // ERROR "cannot use .* in assignment"
-	s = (*S)(s)
-	s = (*S)(t)
-	s = (*S)(u)
-	t = u // ERROR "cannot use .* in assignment"
-	t = (*T)(u)
-}
-
-func _() {
-	type E struct{ x int }
-	type S struct{ x E }
-	type T struct {
-		x E "foo"
-	}
-	var s *S
-	var t *T
-	var u *struct {
-		x E "bar"
-	}
-	s = s
-	s = t // ERROR "cannot use .* in assignment"
-	s = u // ERROR "cannot use .* in assignment"
-	s = (*S)(s)
-	s = (*S)(t)
-	s = (*S)(u)
-	t = u // ERROR "cannot use .* in assignment"
-	t = (*T)(u)
-}
-
-func _() {
-	type S struct {
-		x struct {
-			x int "foo"
-		}
-	}
-	type T struct {
-		x struct {
-			x int "bar"
-		} "foo"
-	}
-	var s *S
-	var t *T
-	var u *struct {
-		x struct {
-			x int "bar"
-		} "bar"
-	}
-	s = s
-	s = t // ERROR "cannot use .* in assignment"
-	s = u // ERROR "cannot use .* in assignment"
-	s = (*S)(s)
-	s = (*S)(t)
-	s = (*S)(u)
-	t = u // ERROR "cannot use .* in assignment"
-	t = (*T)(u)
-}
-
-func _() {
-	type E1 struct {
-		x int "foo"
-	}
-	type E2 struct {
-		x int "bar"
-	}
-	type S struct{ x E1 }
-	type T struct {
-		x E2 "foo"
-	}
-	var s *S
-	var t *T
-	var u *struct {
-		x E2 "bar"
-	}
-	s = s
-	s = t // ERROR "cannot use .* in assignment"
-	s = u // ERROR "cannot use .* in assignment"
-	s = (*S)(s)
-	s = (*S)(t /* ERROR "cannot convert" */ )
-	s = (*S)(u /* ERROR "cannot convert" */ )
-	t = u      // ERROR "cannot use .* in assignment"
-	t = (*T)(u)
-}
-
-func _() {
-	type E struct{ x int }
-	type S struct {
-		f func(struct {
-			x int "foo"
-		})
-	}
-	type T struct {
-		f func(struct {
-			x int "bar"
-		})
-	}
-	var s *S
-	var t *T
-	var u *struct{ f func(E) }
-	s = s
-	s = t // ERROR "cannot use .* in assignment"
-	s = u // ERROR "cannot use .* in assignment"
-	s = (*S)(s)
-	s = (*S)(t)
-	s = (*S)(u /* ERROR "cannot convert" */ )
-	t = u      // ERROR "cannot use .* in assignment"
-	t = (*T)(u /* ERROR "cannot convert" */ )
-}
-
-func _() {
-	type E struct{ x int }
-	type S struct {
-		f func(*struct {
-			x int "foo"
-		})
-	}
-	type T struct {
-		f func(*struct {
-			x int "bar"
-		})
-	}
-	var s *S
-	var t *T
-	var u *struct{ f func(E) }
-	s = s
-	s = t // ERROR "cannot use .* in assignment"
-	s = u // ERROR "cannot use .* in assignment"
-	s = (*S)(s)
-	s = (*S)(t)
-	s = (*S)(u /* ERROR "cannot convert" */ )
-	t = u      // ERROR "cannot use .* in assignment"
-	t = (*T)(u /* ERROR "cannot convert" */ )
-}
diff --git a/src/cmd/compile/internal/types2/testdata/check/cycles0.go b/src/cmd/compile/internal/types2/testdata/check/cycles0.go
deleted file mode 100644
index 998f9f7..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/cycles0.go
+++ /dev/null
@@ -1,175 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package cycles
-
-import "unsafe"
-
-type (
-	T0 int
-	T1 /* ERROR cycle */ T1
-	T2 *T2
-
-	T3 /* ERROR cycle */ T4
-	T4 T5
-	T5 T3
-
-	T6 T7
-	T7 *T8
-	T8 T6
-
-	// arrays
-	A0 /* ERROR cycle */ [10]A0
-	A1 [10]*A1
-
-	A2 /* ERROR cycle */ [10]A3
-	A3 [10]A4
-	A4 A2
-
-	A5 [10]A6
-	A6 *A5
-
-	// slices
-	L0 []L0
-
-	// structs
-	S0 /* ERROR cycle */ struct{ _ S0 }
-	S1 /* ERROR cycle */ struct{ S1 }
-	S2 struct{ _ *S2 }
-	S3 struct{ *S3 }
-
-	S4 /* ERROR cycle */ struct{ S5 }
-	S5 struct{ S6 }
-	S6 S4
-
-	// pointers
-	P0 *P0
-	PP *struct{ PP.f /* ERROR no field or method f */ }
-
-	// functions
-	F0 func(F0)
-	F1 func() F1
-	F2 func(F2) F2
-
-	// interfaces
-	I0 /* ERROR cycle */ interface{ I0 }
-
-	I1 /* ERROR cycle */ interface{ I2 }
-	I2 interface{ I3 }
-	I3 interface{ I1 }
-
-	I4 interface{ f(I4) }
-
-	// testcase for issue 5090
-	I5 interface{ f(I6) }
-	I6 interface{ I5 }
-
-	// maps
-	M0 map[M0 /* ERROR invalid map key */ ]M0
-
-	// channels
-	C0 chan C0
-)
-
-// test case for issue #34771
-type (
-	AA /* ERROR cycle */ B
-	B C
-	C [10]D
-	D E
-	E AA
-)
-
-func _() {
-	type (
-		t1 /* ERROR cycle */ t1
-		t2 *t2
-
-		t3 t4 /* ERROR undeclared */
-		t4 t5 /* ERROR undeclared */
-		t5 t3
-
-		// arrays
-		a0 /* ERROR cycle */ [10]a0
-		a1 [10]*a1
-
-		// slices
-		l0 []l0
-
-		// structs
-		s0 /* ERROR cycle */ struct{ _ s0 }
-		s1 /* ERROR cycle */ struct{ s1 }
-		s2 struct{ _ *s2 }
-		s3 struct{ *s3 }
-
-		// pointers
-		p0 *p0
-
-		// functions
-		f0 func(f0)
-		f1 func() f1
-		f2 func(f2) f2
-
-		// interfaces
-		i0 /* ERROR cycle */ interface{ i0 }
-
-		// maps
-		m0 map[m0 /* ERROR invalid map key */ ]m0
-
-		// channels
-		c0 chan c0
-	)
-}
-
-// test cases for issue 6667
-
-type A [10]map[A /* ERROR invalid map key */ ]bool
-
-type S struct {
-	m map[S /* ERROR invalid map key */ ]bool
-}
-
-// test cases for issue 7236
-// (cycle detection must not be dependent on starting point of resolution)
-
-type (
-	P1 *T9
-	T9 /* ERROR cycle */ T9
-
-	T10 /* ERROR cycle */ T10
-	P2 *T10
-)
-
-func (T11) m() {}
-
-type T11 /* ERROR cycle */ struct{ T11 }
-
-type T12 /* ERROR cycle */ struct{ T12 }
-
-func (*T12) m() {}
-
-type (
-	P3 *T13
-	T13 /* ERROR cycle */ T13
-)
-
-// test cases for issue 18643
-// (type cycle detection when non-type expressions are involved)
-type (
-	T14 [len(T14 /* ERROR cycle */ {})]int
-	T15 [][len(T15 /* ERROR cycle */ {})]int
-	T16 map[[len(T16 /* ERROR cycle */ {1:2})]int]int
-	T17 map[int][len(T17 /* ERROR cycle */ {1:2})]int
-)
-
-// Test case for types depending on function literals (see also #22992).
-type T20 chan [unsafe.Sizeof(func(ch T20){ _ = <-ch })]byte
-type T22 = chan [unsafe.Sizeof(func(ch T20){ _ = <-ch })]byte
-
-func _() {
-	type T0 func(T0)
-	type T1 /* ERROR cycle */ = func(T1)
-	type T2 chan [unsafe.Sizeof(func(ch T2){ _ = <-ch })]byte
-	type T3 /* ERROR cycle */ = chan [unsafe.Sizeof(func(ch T3){ _ = <-ch })]byte
-}
diff --git a/src/cmd/compile/internal/types2/testdata/check/cycles1.go b/src/cmd/compile/internal/types2/testdata/check/cycles1.go
deleted file mode 100644
index ae2b38e..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/cycles1.go
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type (
-	A interface {
-		a() interface {
-			ABC1
-		}
-	}
-	B interface {
-		b() interface {
-			ABC2
-		}
-	}
-	C interface {
-		c() interface {
-			ABC3
-		}
-	}
-
-	AB interface {
-		A
-		B
-	}
-	BC interface {
-		B
-		C
-	}
-
-	ABC1 interface {
-		A
-		B
-		C
-	}
-	ABC2 interface {
-		AB
-		C
-	}
-	ABC3 interface {
-		A
-		BC
-	}
-)
-
-var (
-	x1 ABC1
-	x2 ABC2
-	x3 ABC3
-)
-
-func _() {
-	// all types have the same method set
-	x1 = x2
-	x2 = x1
-
-	x1 = x3
-	x3 = x1
-
-	x2 = x3
-	x3 = x2
-
-	// all methods return the same type again
-	x1 = x1.a()
-	x1 = x1.b()
-	x1 = x1.c()
-
-	x2 = x2.a()
-	x2 = x2.b()
-	x2 = x2.c()
-
-	x3 = x3.a()
-	x3 = x3.b()
-	x3 = x3.c()
-}
diff --git a/src/cmd/compile/internal/types2/testdata/check/cycles2.go b/src/cmd/compile/internal/types2/testdata/check/cycles2.go
deleted file mode 100644
index 1a7f40a..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/cycles2.go
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-import "unsafe"
-
-// Test case for issue 5090
-
-type t interface {
-	f(u)
-}
-
-type u interface {
-	t
-}
-
-func _() {
-	var t t
-	var u u
-
-	t.f(t)
-	t.f(u)
-
-	u.f(t)
-	u.f(u)
-}
-
-
-// Test case for issues #6589, #33656.
-
-type A interface {
-	a() interface {
-		AB
-	}
-}
-
-type B interface {
-	b() interface {
-		AB
-	}
-}
-
-type AB interface {
-	a() interface {
-		A
-		B
-	}
-	b() interface {
-		A
-		B
-	}
-}
-
-var x AB
-var y interface {
-	A
-	B
-}
-
-var _ = x == y
-
-
-// Test case for issue 6638.
-
-type T interface {
-	m() [T(nil).m /* ERROR undefined */ ()[0]]int
-}
-
-// Variations of this test case.
-
-type T1 /* ERROR cycle */ interface {
-	m() [x1.m()[0]]int
-}
-
-var x1 T1
-
-type T2 /* ERROR cycle */ interface {
-	m() [len(x2.m())]int
-}
-
-var x2 T2
-
-type T3 /* ERROR cycle */ interface {
-	m() [unsafe.Sizeof(x3.m)]int
-}
-
-var x3 T3
-
-type T4 /* ERROR cycle */ interface {
-	m() [unsafe.Sizeof(cast4(x4.m))]int // cast is invalid but we have a cycle, so all bets are off
-}
-
-var x4 T4
-var _ = cast4(x4.m)
-
-type cast4 func()
diff --git a/src/cmd/compile/internal/types2/testdata/check/cycles3.go b/src/cmd/compile/internal/types2/testdata/check/cycles3.go
deleted file mode 100644
index 5e89b62..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/cycles3.go
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-import "unsafe"
-
-var (
-	_ A = A(nil).a().b().c().d().e().f()
-	_ A = A(nil).b().c().d().e().f()
-	_ A = A(nil).c().d().e().f()
-	_ A = A(nil).d().e().f()
-	_ A = A(nil).e().f()
-	_ A = A(nil).f()
-	_ A = A(nil)
-)
-
-type (
-	A interface {
-		a() B
-		B
-	}
-
-	B interface {
-		b() C
-		C
-	}
-
-	C interface {
-		c() D
-		D
-	}
-
-	D interface {
-		d() E
-		E
-	}
-
-	E interface {
-		e() F
-		F
-	}
-
-	F interface {
-		f() A
-	}
-)
-
-type (
-	U /* ERROR cycle */ interface {
-		V
-	}
-
-	V interface {
-		v() [unsafe.Sizeof(u)]int
-	}
-)
-
-var u U
diff --git a/src/cmd/compile/internal/types2/testdata/check/cycles4.go b/src/cmd/compile/internal/types2/testdata/check/cycles4.go
deleted file mode 100644
index 924aabf..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/cycles4.go
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-import "unsafe"
-
-// Check that all methods of T are collected before
-// determining the result type of m (which embeds
-// all methods of T).
-
-type T interface {
-	m() interface {T}
-	E
-}
-
-var _ int = T.m(nil).m().e()
-
-type E interface {
-	e() int
-}
-
-// Check that unresolved forward chains are followed
-// (see also comment in resolver.go, checker.typeDecl).
-
-var _ int = C.m(nil).m().e()
-
-type A B
-
-type B interface {
-	m() interface{C}
-	E
-}
-
-type C A
-
-// Check that interface type comparison for identity
-// does not recur endlessly.
-
-type T1 interface {
-	m() interface{T1}
-}
-
-type T2 interface {
-	m() interface{T2}
-}
-
-func _(x T1, y T2) {
-	// Checking for assignability of interfaces must check
-	// if all methods of x are present in y, and that they
-	// have identical signatures. The signatures recur via
-	// the result type, which is an interface that embeds
-	// a single method m that refers to the very interface
-	// that contains it. This requires cycle detection in
-	// identity checks for interface types.
-	x = y
-}
-
-type T3 interface {
-	m() interface{T4}
-}
-
-type T4 interface {
-	m() interface{T3}
-}
-
-func _(x T1, y T3) {
-	x = y
-}
-
-// Check that interfaces are type-checked in order of
-// (embedded interface) dependencies (was issue 7158).
-
-var x1 T5 = T7(nil)
-
-type T5 interface {
-	T6
-}
-
-type T6 interface {
-	m() T7
-}
-type T7 interface {
-	T5
-}
-
-// Actual test case from issue 7158.
-
-func wrapNode() Node {
-	return wrapElement()
-}
-
-func wrapElement() Element {
-	return nil
-}
-
-type EventTarget interface {
-	AddEventListener(Event)
-}
-
-type Node interface {
-	EventTarget
-}
-
-type Element interface {
-	Node
-}
-
-type Event interface {
-	Target() Element
-}
-
-// Check that accessing an interface method too early doesn't lead
-// to follow-on errors due to an incorrectly computed type set.
-
-type T8 interface {
-	m() [unsafe.Sizeof(T8.m /* ERROR undefined */ )]int
-}
-
-var _ = T8.m // no error expected here
diff --git a/src/cmd/compile/internal/types2/testdata/check/cycles5.go b/src/cmd/compile/internal/types2/testdata/check/cycles5.go
deleted file mode 100644
index c932ef9..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/cycles5.go
+++ /dev/null
@@ -1,200 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-import "unsafe"
-
-// test case from issue #18395
-
-type (
-	A interface { B }
-	B interface { C }
-	C interface { D; F() A }
-	D interface { G() B }
-)
-
-var _ = A(nil).G // G must be found
-
-
-// test case from issue #21804
-
-type sourceBridge interface {
-	listVersions() ([]Version, error)
-}
-
-type Constraint interface {
-	copyTo(*ConstraintMsg)
-}
-
-type ConstraintMsg struct{}
-
-func (m *ConstraintMsg) asUnpairedVersion() UnpairedVersion {
-	return nil
-}
-
-type Version interface {
-	Constraint
-}
-
-type UnpairedVersion interface {
-	Version
-}
-
-var _ Constraint = UnpairedVersion(nil)
-
-
-// derived test case from issue #21804
-
-type (
-	_ interface{ m(B1) }
-	A1 interface{ a(D1) }
-	B1 interface{ A1 }
-	C1 interface{ B1 }
-	D1 interface{ C1 }
-)
-
-var _ A1 = C1(nil)
-
-
-// derived test case from issue #22701
-
-func F(x I4) interface{} {
-	return x.Method()
-}
-
-type Unused interface {
-	RefersToI1(a I1)
-}
-
-type I1 interface {
-	I2
-	I3
-}
-
-type I2 interface {
-	RefersToI4() I4
-}
-
-type I3 interface {
-	Method() interface{}
-}
-
-type I4 interface {
-	I1
-}
-
-
-// check embedding of error interface
-
-type Error interface{ error }
-
-var err Error
-var _ = err.Error()
-
-
-// more esoteric cases
-
-type (
-	T1 interface { T2 }
-	T2 /* ERROR cycle */ T2
-)
-
-type (
-	T3 interface { T4 }
-	T4 /* ERROR cycle */ T5
-	T5 = T6
-	T6 = T7
-	T7 = T4
-)
-
-
-// arbitrary code may appear inside an interface
-
-const n = unsafe.Sizeof(func(){})
-
-type I interface {
-	m([unsafe.Sizeof(func() { I.m(nil, [n]byte{}) })]byte)
-}
-
-
-// test cases for varias alias cycles
-
-type T10 /* ERROR cycle */ = *T10                 // issue #25141
-type T11 /* ERROR cycle */ = interface{ f(T11) }  // issue #23139
-
-// issue #18640
-type (
-	aa = bb
-	bb struct {
-		*aa
-	}
-)
-
-type (
-	a struct{ *b }
-	b = c
-	c struct{ *b /* ERROR invalid use of type alias */ }
-)
-
-// issue #24939
-type (
-	_ interface {
-		M(P)
-	}
-
-	M interface {
-		F() P // ERROR invalid use of type alias
-	}
-
-	P = interface {
-		I() M
-	}
-)
-
-// issue #8699
-type T12 /* ERROR cycle */ [len(a12)]int
-var a12 = makeArray()
-func makeArray() (res T12) { return }
-
-// issue #20770
-var r /* ERROR cycle */ = newReader()
-func newReader() r
-
-// variations of the theme of #8699 and #20770
-var arr /* ERROR cycle */ = f()
-func f() [len(arr)]int
-
-// issue #25790
-func ff(ff /* ERROR not a type */ )
-func gg((gg /* ERROR not a type */ ))
-
-type T13 /* ERROR cycle */ [len(b13)]int
-var b13 T13
-
-func g1() [unsafe.Sizeof(g1)]int
-func g2() [unsafe.Sizeof(x2)]int
-var x2 = g2
-
-// verify that we get the correct sizes for the functions above
-// (note: assert is statically evaluated in go/types test mode)
-func init() {
-	assert(unsafe.Sizeof(g1) == 8)
-	assert(unsafe.Sizeof(x2) == 8)
-}
-
-func h() [h /* ERROR no value */ ()[0]]int { panic(0) }
-
-var c14 /* ERROR cycle */ T14
-type T14 [uintptr(unsafe.Sizeof(&c14))]byte
-
-// issue #34333
-type T15 /* ERROR cycle */ struct {
-	f func() T16
-	b T16
-}
-
-type T16 struct {
-	T15
-}
\ No newline at end of file
diff --git a/src/cmd/compile/internal/types2/testdata/check/decls0.go b/src/cmd/compile/internal/types2/testdata/check/decls0.go
deleted file mode 100644
index 927c2d3..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/decls0.go
+++ /dev/null
@@ -1,208 +0,0 @@
-// -lang=go1.17
-
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// type declarations
-
-package p // don't permit non-interface elements in interfaces
-
-import "unsafe"
-
-const pi = 3.1415
-
-type (
-	N undeclared /* ERROR "undeclared" */
-	B bool
-	I int32
-	A [10]P
-	T struct {
-		x, y P
-	}
-	P *T
-	R (*R)
-	F func(A) I
-	Y interface {
-		f(A) I
-	}
-	S [](((P)))
-	M map[I]F
-	C chan<- I
-
-	// blank types must be typechecked
-	_ pi /* ERROR "not a type" */
-	_ struct{}
-	_ struct{ pi /* ERROR "not a type" */ }
-)
-
-
-// declarations of init
-const _, init /* ERROR "cannot declare init" */ , _ = 0, 1, 2
-type init /* ERROR "cannot declare init" */ struct{}
-var _, init /* ERROR "cannot declare init" */ int
-
-func init() {}
-func init /* ERROR "missing function body" */ ()
-
-func _() { const init = 0 }
-func _() { type init int }
-func _() { var init int; _ = init }
-
-// invalid array types
-type (
-	iA0 [... /* ERROR "invalid use of \[...\] array" */ ]byte
-	// The error message below could be better. At the moment
-	// we believe an integer that is too large is not an integer.
-	// But at least we get an error.
-	iA1 [1 /* ERROR "must be integer" */ <<100]int
-	iA2 [- /* ERROR "invalid array length" */ 1]complex128
-	iA3 ["foo" /* ERROR "must be integer" */ ]string
-	iA4 [float64 /* ERROR "must be integer" */ (0)]int
-)
-
-
-type (
-	p1 pi.foo /* ERROR "no field or method foo" */
-	p2 unsafe.Pointer
-)
-
-
-type (
-	Pi pi /* ERROR "not a type" */
-
-	a /* ERROR "illegal cycle" */ a
-	a /* ERROR "redeclared" */ int
-
-	b /* ERROR "illegal cycle" */ c
-	c d
-	d e
-	e b
-
-	t *t
-
-	U V
-	V *W
-	W U
-
-	P1 *S2
-	P2 P1
-
-	S0 struct {
-	}
-	S1 struct {
-		a, b, c int
-		u, v, a /* ERROR "redeclared" */ float32
-	}
-	S2 struct {
-		S0 // embedded field
-		S0 /* ERROR "redeclared" */ int
-	}
-	S3 struct {
-		x S2
-	}
-	S4/* ERROR "illegal cycle" */ struct {
-		S4
-	}
-	S5 /* ERROR "illegal cycle" */ struct {
-		S6
-	}
-	S6 struct {
-		field S7
-	}
-	S7 struct {
-		S5
-	}
-
-	L1 []L1
-	L2 []int
-
-	A1 [10.0]int
-	A2 /* ERROR "illegal cycle" */ [10]A2
-	A3 /* ERROR "illegal cycle" */ [10]struct {
-		x A4
-	}
-	A4 [10]A3
-
-	F1 func()
-	F2 func(x, y, z float32)
-	F3 func(x, y, x /* ERROR "redeclared" */ float32)
-	F4 func() (x, y, x /* ERROR "redeclared" */ float32)
-	F5 func(x int) (x /* ERROR "redeclared" */ float32)
-	F6 func(x ...int)
-
-	I1 interface{}
-	I2 interface {
-		m1()
-	}
-	I3 interface {
-		m1()
-		m1 /* ERROR "duplicate method" */ ()
-	}
-	I4 interface {
-		m1(x, y, x /* ERROR "redeclared" */ float32)
-		m2() (x, y, x /* ERROR "redeclared" */ float32)
-		m3(x int) (x /* ERROR "redeclared" */ float32)
-	}
-	I5 interface {
-		m1(I5)
-	}
-	I6 interface {
-		S0 /* ERROR "non-interface type S0" */
-	}
-	I7 interface {
-		I1
-		I1
-	}
-	I8 /* ERROR "illegal cycle" */ interface {
-		I8
-	}
-	I9 /* ERROR "illegal cycle" */ interface {
-		I10
-	}
-	I10 interface {
-		I11
-	}
-	I11 interface {
-		I9
-	}
-
-	C1 chan int
-	C2 <-chan int
-	C3 chan<- C3
-	C4 chan C5
-	C5 chan C6
-	C6 chan C4
-
-	M1 map[Last]string
-	M2 map[string]M2
-
-	Last int
-)
-
-// cycles in function/method declarations
-// (test cases for issues #5217, #25790 and variants)
-func f1(x f1 /* ERROR "not a type" */ ) {}
-func f2(x *f2 /* ERROR "not a type" */ ) {}
-func f3() (x f3 /* ERROR "not a type" */ ) { return }
-func f4() (x *f4 /* ERROR "not a type" */ ) { return }
-
-func (S0) m1(x S0 /* ERROR illegal cycle in method declaration */ .m1) {}
-func (S0) m2(x *S0 /* ERROR illegal cycle in method declaration */ .m2) {}
-func (S0) m3() (x S0 /* ERROR illegal cycle in method declaration */ .m3) { return }
-func (S0) m4() (x *S0 /* ERROR illegal cycle in method declaration */ .m4) { return }
-
-// interfaces may not have any blank methods
-type BlankI interface {
-	_ /* ERROR "methods must have a unique non-blank name" */ ()
-	_ /* ERROR "methods must have a unique non-blank name" */ (float32) int
-	m()
-}
-
-// non-interface types may have multiple blank methods
-type BlankT struct{}
-
-func (BlankT) _() {}
-func (BlankT) _(int) {}
-func (BlankT) _() int { return 0 }
-func (BlankT) _(int) int { return 0}
diff --git a/src/cmd/compile/internal/types2/testdata/check/decls1.go b/src/cmd/compile/internal/types2/testdata/check/decls1.go
deleted file mode 100644
index 1167ced..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/decls1.go
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// variable declarations
-
-package decls1
-
-import (
-	"math"
-)
-
-// Global variables without initialization
-var (
-	a, b bool
-	c byte
-	d uint8
-	r rune
-	i int
-	j, k, l int
-	x, y float32
-	xx, yy float64
-	u, v complex64
-	uu, vv complex128
-	s, t string
-	array []byte
-	iface interface{}
-
-	blank _ /* ERROR "cannot use _" */
-)
-
-// Global variables with initialization
-var (
-	s1 = i + j
-	s2 = i /* ERROR "mismatched types" */ + x
-	s3 = c + d
-	s4 = s + t
-	s5 = s /* ERROR "invalid operation" */ / t
-	s6 = array[t1]
-	s7 = array[x /* ERROR "integer" */]
-	s8 = &a
-	s10 = &42 /* ERROR "cannot take address" */
-	s11 = &v
-	s12 = -(u + *t11) / *&v
-	s13 = a /* ERROR "shifted operand" */ << d
-	s14 = i << j
-	s18 = math.Pi * 10.0
-	s19 = s1 /* ERROR "cannot call" */ ()
- 	s20 = f0 /* ERROR "no value" */ ()
-	s21 = f6(1, s1, i)
-	s22 = f6(1, s1, uu /* ERROR "cannot use .* in argument" */ )
-
-	t1 int = i + j
-	t2 int = i /* ERROR "mismatched types" */ + x
-	t3 int = c /* ERROR "cannot use .* variable declaration" */ + d
-	t4 string = s + t
-	t5 string = s /* ERROR "invalid operation" */ / t
-	t6 byte = array[t1]
-	t7 byte = array[x /* ERROR "must be integer" */]
-	t8 *int = & /* ERROR "cannot use .* variable declaration" */ a
-	t10 *int = &42 /* ERROR "cannot take address" */
-	t11 *complex64 = &v
-	t12 complex64 = -(u + *t11) / *&v
-	t13 int = a /* ERROR "shifted operand" */ << d
-	t14 int = i << j
-	t15 math /* ERROR "not in selector" */
-	t16 math.xxx /* ERROR "not declared" */
-	t17 math /* ERROR "not a type" */ .Pi
-	t18 float64 = math.Pi * 10.0
-	t19 int = t1 /* ERROR "cannot call" */ ()
-	t20 int = f0 /* ERROR "no value" */ ()
-	t21 int = a /* ERROR "cannot use .* variable declaration" */
-)
-
-// Various more complex expressions
-var (
-	u1 = x /* ERROR "not an interface" */ .(int)
-	u2 = iface.([]int)
-	u3 = iface.(a /* ERROR "not a type" */ )
-	u4, ok = iface.(int)
-	u5, ok2, ok3 = iface /* ERROR "cannot initialize" */ .(int)
-)
-
-// Constant expression initializations
-var (
-	v1 = 1 /* ERROR "mismatched types untyped int and untyped string" */ + "foo"
-	v2 = c + 255
-	v3 = c + 256 /* ERROR "overflows" */
-	v4 = r + 2147483647
-	v5 = r + 2147483648 /* ERROR "overflows" */
-	v6 = 42
-	v7 = v6 + 9223372036854775807
-	v8 = v6 + 9223372036854775808 /* ERROR "overflows" */
-	v9 = i + 1 << 10
-	v10 byte = 1024 /* ERROR "overflows" */
-	v11 = xx/yy*yy - xx
-	v12 = true && false
-	v13 = nil /* ERROR "use of untyped nil" */
-)
-
-// Multiple assignment expressions
-var (
-	m1a, m1b = 1, 2
-	m2a, m2b, m2c /* ERROR "missing init expr for m2c" */ = 1, 2
-	m3a, m3b = 1, 2, 3 /* ERROR "extra init expr 3" */
-)
-
-func _() {
-	var (
-		m1a, m1b = 1, 2
-		m2a, m2b, m2c /* ERROR "missing init expr for m2c" */ = 1, 2
-		m3a, m3b = 1, 2, 3 /* ERROR "extra init expr 3" */
-	)
-
-	_, _ = m1a, m1b
-	_, _, _ = m2a, m2b, m2c
-	_, _ = m3a, m3b
-}
-
-// Declaration of parameters and results
-func f0() {}
-func f1(a /* ERROR "not a type" */) {}
-func f2(a, b, c d /* ERROR "not a type" */) {}
-
-func f3() int { return 0 }
-func f4() a /* ERROR "not a type" */ { return 0 }
-func f5() (a, b, c d /* ERROR "not a type" */) { return }
-
-func f6(a, b, c int) complex128 { return 0 }
-
-// Declaration of receivers
-type T struct{}
-
-func (T) m0() {}
-func (*T) m1() {}
-func (x T) m2() {}
-func (x *T) m3() {}
-
-// Initialization functions
-func init() {}
-func /* ERROR "no arguments and no return values" */ init(int) {}
-func /* ERROR "no arguments and no return values" */ init() int { return 0 }
-func /* ERROR "no arguments and no return values" */ init(int) int { return 0 }
-func (T) init(int) int { return 0 }
diff --git a/src/cmd/compile/internal/types2/testdata/check/decls2/decls2a.go b/src/cmd/compile/internal/types2/testdata/check/decls2/decls2a.go
deleted file mode 100644
index 66ca6ee..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/decls2/decls2a.go
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// method declarations
-
-package decls2
-
-import "time"
-import "unsafe"
-
-// T1 declared before its methods.
-type T1 struct{
-	f int
-}
-
-func (T1) m() {}
-func (T1) m /* ERROR "already declared" */ () {}
-func (x *T1) f /* ERROR "field and method" */ () {}
-
-// Conflict between embedded field and method name,
-// with the embedded field being a basic type.
-type T1b struct {
-	int
-}
-
-func (T1b) int /* ERROR "field and method" */ () {}
-
-type T1c struct {
-	time.Time
-}
-
-func (T1c) Time /* ERROR "field and method" */ () int { return 0 }
-
-// Disabled for now: LookupFieldOrMethod will find Pointer even though
-// it's double-declared (it would cost extra in the common case to verify
-// this). But the MethodSet computation will not find it due to the name
-// collision caused by the double-declaration, leading to an internal
-// inconsistency while we are verifying one computation against the other.
-// var _ = T1c{}.Pointer
-
-// T2's method declared before the type.
-func (*T2) f /* ERROR "field and method" */ () {}
-
-type T2 struct {
-	f int
-}
-
-// Methods declared without a declared type.
-func (undeclared /* ERROR "undeclared" */) m() {}
-func (x *undeclared /* ERROR "undeclared" */) m() {}
-
-func (pi /* ERROR "not a type" */) m1() {}
-func (x pi /* ERROR "not a type" */) m2() {}
-func (x *pi /* ERROR "not a type" */ ) m3() {}
-
-// Blank types.
-type _ struct { m int }
-type _ struct { m int }
-
-func (_ /* ERROR "cannot use _" */) m() {}
-func m(_ /* ERROR "cannot use _" */) {}
-
-// Methods with receiver base type declared in another file.
-func (T3) m1() {}
-func (*T3) m2() {}
-func (x T3) m3() {}
-func (x *T3) f /* ERROR "field and method" */ () {}
-
-// Methods of non-struct type.
-type T4 func()
-
-func (self T4) m() func() { return self }
-
-// Methods associated with an interface.
-type T5 interface {
-	m() int
-}
-
-func (T5 /* ERROR "invalid receiver" */ ) m1() {}
-func (T5 /* ERROR "invalid receiver" */ ) m2() {}
-
-// Methods associated with a named pointer type.
-type ptr *int
-func (ptr /* ERROR "invalid receiver" */ ) _() {}
-func (* /* ERROR "invalid receiver" */ ptr) _() {}
-
-// Methods with zero or multiple receivers.
-func ( /* ERROR "no receiver" */ ) _() {}
-func (T3, * /* ERROR "multiple receivers" */ T3) _() {}
-func (T3, T3, T3 /* ERROR "multiple receivers" */ ) _() {}
-func (a, b /* ERROR "multiple receivers" */ T3) _() {}
-func (a, b, c /* ERROR "multiple receivers" */ T3) _() {}
-
-// Methods associated with non-local or unnamed types.
-func (int /* ERROR "cannot define new methods on non-local type int" */ ) m() {}
-func ([ /* ERROR "invalid receiver" */ ]int) m() {}
-func (time /* ERROR "cannot define new methods on non-local type time\.Time" */ .Time) m() {}
-func (* /* ERROR "cannot define new methods on non-local type time\.Time" */ time.Time) m() {}
-func (x /* ERROR "invalid receiver" */ interface{}) m() {}
-
-// Unsafe.Pointer is treated like a pointer when used as receiver type.
-type UP unsafe.Pointer
-func (UP /* ERROR "invalid" */ ) m1() {}
-func (* /* ERROR "invalid" */ UP) m2() {}
-
-// Double declarations across package files
-const c_double = 0
-type t_double int
-var v_double int
-func f_double() {}
diff --git a/src/cmd/compile/internal/types2/testdata/check/decls2/decls2b.go b/src/cmd/compile/internal/types2/testdata/check/decls2/decls2b.go
deleted file mode 100644
index 7b3229c..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/decls2/decls2b.go
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// method declarations
-
-package decls2
-
-import "io"
-
-const pi = 3.1415
-
-func (T1) m /* ERROR "already declared" */ () {}
-func (T2) m(io.Writer) {}
-
-type T3 struct {
-	f *T3
-}
-
-type T6 struct {
-	x int
-}
-
-func (t *T6) m1() int {
-	return t.x
-}
-
-func f() {
-	var t *T6
-	t.m1()
-}
-
-// Double declarations across package files
-const c_double /* ERROR "redeclared" */ = 0
-type t_double  /* ERROR "redeclared" */ int
-var v_double /* ERROR "redeclared" */ int
-func f_double /* ERROR "redeclared" */ () {}
-
-// Blank methods need to be type-checked.
-// Verify by checking that errors are reported.
-func (T /* ERROR "undeclared" */ ) _() {}
-func (T1) _(undeclared /* ERROR "undeclared" */ ) {}
-func (T1) _() int { return "foo" /* ERROR "cannot use .* in return statement" */ }
-
-// Methods with undeclared receiver type can still be checked.
-// Verify by checking that errors are reported.
-func (Foo /* ERROR "undeclared" */ ) m() {}
-func (Foo /* ERROR "undeclared" */ ) m(undeclared /* ERROR "undeclared" */ ) {}
-func (Foo /* ERROR "undeclared" */ ) m() int { return "foo" /* ERROR "cannot use .* in return statement" */ }
-
-func (Foo /* ERROR "undeclared" */ ) _() {}
-func (Foo /* ERROR "undeclared" */ ) _(undeclared /* ERROR "undeclared" */ ) {}
-func (Foo /* ERROR "undeclared" */ ) _() int { return "foo" /* ERROR "cannot use .* in return statement" */ }
-
-// Receiver declarations are regular parameter lists;
-// receiver types may use parentheses, and the list
-// may have a trailing comma.
-type T7 struct {}
-
-func (T7) m1() {}
-func ((T7)) m2() {}
-func ((*T7)) m3() {}
-func (x *(T7),) m4() {}
-func (x (*(T7)),) m5() {}
-func (x ((*((T7)))),) m6() {}
-
-// Check that methods with parenthesized receiver are actually present (issue #23130).
-var (
-	_ = T7.m1
-	_ = T7.m2
-	_ = (*T7).m3
-	_ = (*T7).m4
-	_ = (*T7).m5
-	_ = (*T7).m6
-)
\ No newline at end of file
diff --git a/src/cmd/compile/internal/types2/testdata/check/decls3.go b/src/cmd/compile/internal/types2/testdata/check/decls3.go
deleted file mode 100644
index d7a0c44..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/decls3.go
+++ /dev/null
@@ -1,309 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// embedded types
-
-package decls3
-
-import "unsafe"
-import "fmt"
-
-// fields with the same name at the same level cancel each other out
-
-func _() {
-	type (
-		T1 struct { X int }
-		T2 struct { X int }
-		T3 struct { T1; T2 } // X is embedded twice at the same level via T1->X, T2->X
-	)
-
-	var t T3
-	_ = t.X /* ERROR "ambiguous selector t.X" */
-}
-
-func _() {
-	type (
-		T1 struct { X int }
-		T2 struct { T1 }
-		T3 struct { T1 }
-		T4 struct { T2; T3 } // X is embedded twice at the same level via T2->T1->X, T3->T1->X
-	)
-
-	var t T4
-	_ = t.X /* ERROR "ambiguous selector t.X" */
-}
-
-func issue4355() {
-	type (
-	    T1 struct {X int}
-	    T2 struct {T1}
-	    T3 struct {T2}
-	    T4 struct {T2}
-	    T5 struct {T3; T4} // X is embedded twice at the same level via T3->T2->T1->X, T4->T2->T1->X
-	)
-
-	var t T5
-	_ = t.X /* ERROR "ambiguous selector t.X" */
-}
-
-func _() {
-	type State int
-	type A struct{ State }
-	type B struct{ fmt.State }
-	type T struct{ A; B }
-
-	var t T
-	_ = t.State /* ERROR "ambiguous selector t.State" */
-}
-
-// Embedded fields can be predeclared types.
-
-func _() {
-	type T0 struct{
-		int
-		float32
-		f int
-	}
-	var x T0
-	_ = x.int
-	_ = x.float32
-	_ = x.f
-
-	type T1 struct{
-		T0
-	}
-	var y T1
-	_ = y.int
-	_ = y.float32
-	_ = y.f
-}
-
-// Restrictions on embedded field types.
-
-func _() {
-	type I1 interface{}
-	type I2 interface{}
-	type P1 *int
-	type P2 *int
-	type UP unsafe.Pointer
-
-	type T1 struct {
-		I1
-		* /* ERROR "cannot be a pointer to an interface" */ I2
-		* /* ERROR "cannot be a pointer to an interface" */ error
-		P1 /* ERROR "cannot be a pointer" */
-		* /* ERROR "cannot be a pointer" */ P2
-	}
-
-	// unsafe.Pointers are treated like regular pointers when embedded
-	type T2 struct {
-		unsafe /* ERROR "cannot be unsafe.Pointer" */ .Pointer
-		*/* ERROR "cannot be unsafe.Pointer" */ /* ERROR "Pointer redeclared" */ unsafe.Pointer
-		UP /* ERROR "cannot be unsafe.Pointer" */
-		* /* ERROR "cannot be unsafe.Pointer" */  /* ERROR "UP redeclared" */ UP
-	}
-}
-
-// Named types that are pointers.
-
-type S struct{ x int }
-func (*S) m() {}
-type P *S
-
-func _() {
-	var s *S
-	_ = s.x
-	_ = s.m
-
-	var p P
-	_ = p.x
-	_ = p.m /* ERROR "no field or method" */
-	_ = P.m /* ERROR "no field or method" */
-}
-
-// Borrowed from the FieldByName test cases in reflect/all_test.go.
-
-type D1 struct {
-	d int
-}
-type D2 struct {
-	d int
-}
-
-type S0 struct {
-	A, B, C int
-	D1
-	D2
-}
-
-type S1 struct {
-	B int
-	S0
-}
-
-type S2 struct {
-	A int
-	*S1
-}
-
-type S1x struct {
-	S1
-}
-
-type S1y struct {
-	S1
-}
-
-type S3 struct {
-	S1x
-	S2
-	D, E int
-	*S1y
-}
-
-type S4 struct {
-	*S4
-	A int
-}
-
-// The X in S6 and S7 annihilate, but they also block the X in S8.S9.
-type S5 struct {
-	S6
-	S7
-	S8
-}
-
-type S6 struct {
-	X int
-}
-
-type S7 S6
-
-type S8 struct {
-	S9
-}
-
-type S9 struct {
-	X int
-	Y int
-}
-
-// The X in S11.S6 and S12.S6 annihilate, but they also block the X in S13.S8.S9.
-type S10 struct {
-	S11
-	S12
-	S13
-}
-
-type S11 struct {
-	S6
-}
-
-type S12 struct {
-	S6
-}
-
-type S13 struct {
-	S8
-}
-
-func _() {
-	_ = struct{}{}.Foo /* ERROR "no field or method" */
-	_ = S0{}.A
-	_ = S0{}.D /* ERROR "no field or method" */
-	_ = S1{}.A
-	_ = S1{}.B
-	_ = S1{}.S0
-	_ = S1{}.C
-	_ = S2{}.A
-	_ = S2{}.S1
-	_ = S2{}.B
-	_ = S2{}.C
-	_ = S2{}.D /* ERROR "no field or method" */
-	_ = S3{}.S1 /* ERROR "ambiguous selector S3\{\}.S1" */
-	_ = S3{}.A
-	_ = S3{}.B /* ERROR "ambiguous selector" S3\{\}.B */
-	_ = S3{}.D
-	_ = S3{}.E
-	_ = S4{}.A
-	_ = S4{}.B /* ERROR "no field or method" */
-	_ = S5{}.X /* ERROR "ambiguous selector S5\{\}.X" */
-	_ = S5{}.Y
-	_ = S10{}.X /* ERROR "ambiguous selector S10\{\}.X" */
-	_ = S10{}.Y
-}
-
-// Borrowed from the FieldByName benchmark in reflect/all_test.go.
-
-type R0 struct {
-	*R1
-	*R2
-	*R3
-	*R4
-}
-
-type R1 struct {
-	*R5
-	*R6
-	*R7
-	*R8
-}
-
-type R2 R1
-type R3 R1
-type R4 R1
-
-type R5 struct {
-	*R9
-	*R10
-	*R11
-	*R12
-}
-
-type R6 R5
-type R7 R5
-type R8 R5
-
-type R9 struct {
-	*R13
-	*R14
-	*R15
-	*R16
-}
-
-type R10 R9
-type R11 R9
-type R12 R9
-
-type R13 struct {
-	*R17
-	*R18
-	*R19
-	*R20
-}
-
-type R14 R13
-type R15 R13
-type R16 R13
-
-type R17 struct {
-	*R21
-	*R22
-	*R23
-	*R24
-}
-
-type R18 R17
-type R19 R17
-type R20 R17
-
-type R21 struct {
-	X int
-}
-
-type R22 R21
-type R23 R21
-type R24 R21
-
-var _ = R0{}.X /* ERROR "ambiguous selector R0\{\}.X" */
\ No newline at end of file
diff --git a/src/cmd/compile/internal/types2/testdata/check/decls4.go b/src/cmd/compile/internal/types2/testdata/check/decls4.go
deleted file mode 100644
index 384bcd9..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/decls4.go
+++ /dev/null
@@ -1,199 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// type aliases
-
-package decls4
-
-type (
-	T0 [10]int
-	T1 []byte
-	T2 struct {
-		x int
-	}
-	T3 interface{
-		m() T2
-	}
-	T4 func(int, T0) chan T2
-)
-
-type (
-	Ai = int
-	A0 = T0
-	A1 = T1
-	A2 = T2
-	A3 = T3
-	A4 = T4
-
-	A10 = [10]int
-	A11 = []byte
-	A12 = struct {
-		x int
-	}
-	A13 = interface{
-		m() A2
-	}
-	A14 = func(int, A0) chan A2
-)
-
-// check assignment compatibility due to equality of types
-var (
-	xi_ int
-	ai Ai = xi_
-
-	x0 T0
-	a0 A0 = x0
-
-	x1 T1
-	a1 A1 = x1
-
-	x2 T2
-	a2 A2 = x2
-
-	x3 T3
-	a3 A3 = x3
-
-	x4 T4
-	a4 A4 = x4
-)
-
-// alias receiver types
-func (Ai /* ERROR "cannot define new methods on non-local type int" */) m1() {}
-func (T0) m1() {}
-func (A0) m1 /* ERROR already declared */ () {}
-func (A0) m2 () {}
-func (A3 /* ERROR invalid receiver */ ) m1 () {}
-func (A10 /* ERROR invalid receiver */ ) m1() {}
-
-// x0 has methods m1, m2 declared via receiver type names T0 and A0
-var _ interface{ m1(); m2() } = x0
-
-// alias receiver types (test case for issue #23042)
-type T struct{}
-
-var (
-	_ = T.m
-	_ = T{}.m
-	_ interface{m()} = T{}
-)
-
-var (
-	_ = T.n
-	_ = T{}.n
-	_ interface{m(); n()} = T{}
-)
-
-type U = T
-func (U) m() {}
-
-// alias receiver types (long type declaration chains)
-type (
-	V0 = V1
-	V1 = (V2)
-	V2 = ((V3))
-	V3 = T
-)
-
-func (V0) m /* ERROR already declared */ () {}
-func (V1) n() {}
-
-// alias receiver types (invalid due to cycles)
-type (
-	W0 /* ERROR illegal cycle */ = W1
-	W1 = (W2)
-	W2 = ((W0))
-)
-
-func (W0) m() {} // no error expected (due to above cycle error)
-func (W1) n() {}
-
-// alias receiver types (invalid due to builtin underlying type)
-type (
-	B0 = B1
-	B1 = B2
-	B2 = int
-)
-
-func (B0 /* ERROR cannot define new methods on non-local type int */ ) m() {}
-func (B1 /* ERROR cannot define new methods on non-local type int */ ) n() {}
-
-// cycles
-type (
-	C2 /* ERROR illegal cycle */ = C2
-	C3 /* ERROR illegal cycle */ = C4
-	C4 = C3
-	C5 struct {
-		f *C6
-	}
-	C6 = C5
-	C7 /* ERROR illegal cycle */  struct {
-		f C8
-	}
-	C8 = C7
-)
-
-// embedded fields
-var (
-	s0 struct { T0 }
-	s1 struct { A0 } = s0 /* ERROR cannot use */ // embedded field names are different
-)
-
-// embedding and lookup of fields and methods
-func _(s struct{A0}) { s.A0 = x0 }
-
-type eX struct{xf int}
-
-func (eX) xm()
-
-type eY = struct{eX} // field/method set of eY includes xf, xm
-
-type eZ = *struct{eX} // field/method set of eZ includes xf, xm
-
-type eA struct {
-	eX // eX contributes xf, xm to eA
-}
-
-type eA2 struct {
-	*eX // *eX contributes xf, xm to eA
-}
-
-type eB struct {
-	eY // eY contributes xf, xm to eB
-}
-
-type eB2 struct {
-	*eY // *eY contributes xf, xm to eB
-}
-
-type eC struct {
-	eZ // eZ contributes xf, xm to eC
-}
-
-var (
-	_ = eA{}.xf
-	_ = eA{}.xm
-	_ = eA2{}.xf
-	_ = eA2{}.xm
-	_ = eB{}.xf
-	_ = eB{}.xm
-	_ = eB2{}.xf
-	_ = eB2{}.xm
-	_ = eC{}.xf
-	_ = eC{}.xm
-)
-
-// ambiguous selectors due to embedding via type aliases
-type eD struct {
-	eY
-	eZ
-}
-
-var (
-	_ = eD{}.xf /* ERROR ambiguous selector eD\{\}.xf */
-	_ = eD{}.xm /* ERROR ambiguous selector eD\{\}.xm */
-)
-
-var (
-	_ interface{ xm() } = eD /* ERROR missing method xm */ {}
-)
\ No newline at end of file
diff --git a/src/cmd/compile/internal/types2/testdata/check/decls5.go b/src/cmd/compile/internal/types2/testdata/check/decls5.go
deleted file mode 100644
index 88d3194..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/decls5.go
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-// declarations of main
-const _, main /* ERROR "cannot declare main" */ , _ = 0, 1, 2
-type main /* ERROR "cannot declare main" */ struct{}
-var _, main /* ERROR "cannot declare main" */ int
diff --git a/src/cmd/compile/internal/types2/testdata/check/errors.go b/src/cmd/compile/internal/types2/testdata/check/errors.go
deleted file mode 100644
index 5f09197..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/errors.go
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package errors
-
-// Testing precise operand formatting in error messages
-// (matching messages are regular expressions, hence the \'s).
-func f(x int, m map[string]int) {
-	// no values
-	_ = f /* ERROR f\(0, m\) \(no value\) used as value */ (0, m)
-
-	// built-ins
-	_ = println // ERROR println \(built-in\) must be called
-
-	// types
-	_ = complex128 // ERROR complex128 \(type\) is not an expression
-
-	// constants
-	const c1 = 991
-	const c2 float32 = 0.5
-	const c3 = "foo"
-	0 // ERROR 0 \(untyped int constant\) is not used
-	0.5 // ERROR 0.5 \(untyped float constant\) is not used
-	"foo" // ERROR "foo" \(untyped string constant\) is not used
-	c1 // ERROR c1 \(untyped int constant 991\) is not used
-	c2 // ERROR c2 \(constant 0.5 of type float32\) is not used
-	c1 /* ERROR c1 \+ c2 \(constant 991.5 of type float32\) is not used */ + c2
-	c3 // ERROR c3 \(untyped string constant "foo"\) is not used
-
-	// variables
-	x // ERROR x \(variable of type int\) is not used
-
-	// values
-	nil // ERROR nil is not used
-	(*int)(nil) // ERROR \(\*int\)\(nil\) \(value of type \*int\) is not used
-	x /* ERROR x != x \(untyped bool value\) is not used */ != x
-	x /* ERROR x \+ x \(value of type int\) is not used */ + x
-
-	// value, ok's
-	const s = "foo"
-	m /* ERROR m\[s\] \(map index expression of type int\) is not used */ [s]
-}
-
-// Valid ERROR comments can have a variety of forms.
-func _() {
-	0 /* ERROR "0 .* is not used" */
-	0 /* ERROR 0 .* is not used */
-	0 // ERROR "0 .* is not used"
-	0 // ERROR 0 .* is not used
-}
-
-// Don't report spurious errors as a consequence of earlier errors.
-// Add more tests as needed.
-func _() {
-	if err := foo /* ERROR undeclared */ (); err != nil /* no error here */ {}
-}
-
-// Use unqualified names for package-local objects.
-type T struct{}
-var _ int = T /* ERROR value of type T */ {} // use T in error message rather then errors.T
-
-// Don't report errors containing "invalid type" (issue #24182).
-func _(x *missing /* ERROR undeclared name: missing */ ) {
-	x.m() // there shouldn't be an error here referring to *invalid type
-}
diff --git a/src/cmd/compile/internal/types2/testdata/check/expr0.go b/src/cmd/compile/internal/types2/testdata/check/expr0.go
deleted file mode 100644
index 821b07f..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/expr0.go
+++ /dev/null
@@ -1,187 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// unary expressions
-
-package expr0 
-
-type mybool bool
-
-var (
-	// bool
-	b0 = true
-	b1 bool = b0
-	b2 = !true
-	b3 = !b1
-	b4 bool = !true
-	b5 bool = !b4
-	b6 = +b0 /* ERROR "not defined" */
-	b7 = -b0 /* ERROR "not defined" */
-	b8 = ^b0 /* ERROR "not defined" */
-	b9 = *b0 /* ERROR "cannot indirect" */
-	b10 = &true /* ERROR "cannot take address" */
-	b11 = &b0
-	b12 = <-b0 /* ERROR "cannot receive" */
-	b13 = & & /* ERROR "cannot take address" */ b0
-
-	// byte
-	_ = byte(0)
-	_ = byte(- /* ERROR "cannot convert" */ 1)
-	_ = - /* ERROR "-byte\(1\) \(constant -1 of type byte\) overflows byte" */ byte(1) // test for issue 11367
-	_ = byte /* ERROR "overflows byte" */ (0) - byte(1)
-
-	// int
-	i0 = 1
-	i1 int = i0
-	i2 = +1
-	i3 = +i0
-	i4 int = +1
-	i5 int = +i4
-	i6 = -1
-	i7 = -i0
-	i8 int = -1
-	i9 int = -i4
-	i10 = !i0 /* ERROR "not defined" */
-	i11 = ^1
-	i12 = ^i0
-	i13 int = ^1
-	i14 int = ^i4
-	i15 = *i0 /* ERROR "cannot indirect" */
-	i16 = &i0
-	i17 = *i16
-	i18 = <-i16 /* ERROR "cannot receive" */
-
-	// uint
-	u0 = uint(1)
-	u1 uint = u0
-	u2 = +1
-	u3 = +u0
-	u4 uint = +1
-	u5 uint = +u4
-	u6 = -1
-	u7 = -u0
-	u8 uint = - /* ERROR "overflows" */ 1
-	u9 uint = -u4
-	u10 = !u0 /* ERROR "not defined" */
-	u11 = ^1
-	u12 = ^i0
-	u13 uint = ^ /* ERROR "overflows" */ 1
-	u14 uint = ^u4
-	u15 = *u0 /* ERROR "cannot indirect" */
-	u16 = &u0
-	u17 = *u16
-	u18 = <-u16 /* ERROR "cannot receive" */
-	u19 = ^uint(0)
-
-	// float64
-	f0 = float64(1)
-	f1 float64 = f0
-	f2 = +1
-	f3 = +f0
-	f4 float64 = +1
-	f5 float64 = +f4
-	f6 = -1
-	f7 = -f0
-	f8 float64 = -1
-	f9 float64 = -f4
-	f10 = !f0 /* ERROR "not defined" */
-	f11 = ^1
-	f12 = ^i0
-	f13 float64 = ^1
-	f14 float64 = ^f4 /* ERROR "not defined" */
-	f15 = *f0 /* ERROR "cannot indirect" */
-	f16 = &f0
-	f17 = *u16
-	f18 = <-u16 /* ERROR "cannot receive" */
-
-	// complex128
-	c0 = complex128(1)
-	c1 complex128 = c0
-	c2 = +1
-	c3 = +c0
-	c4 complex128 = +1
-	c5 complex128 = +c4
-	c6 = -1
-	c7 = -c0
-	c8 complex128 = -1
-	c9 complex128 = -c4
-	c10 = !c0 /* ERROR "not defined" */
-	c11 = ^1
-	c12 = ^i0
-	c13 complex128 = ^1
-	c14 complex128 = ^c4 /* ERROR "not defined" */
-	c15 = *c0 /* ERROR "cannot indirect" */
-	c16 = &c0
-	c17 = *u16
-	c18 = <-u16 /* ERROR "cannot receive" */
-
-	// string
-	s0 = "foo"
-	s1 = +"foo" /* ERROR "not defined" */
-	s2 = -s0 /* ERROR "not defined" */
-	s3 = !s0 /* ERROR "not defined" */
-	s4 = ^s0 /* ERROR "not defined" */
-	s5 = *s4
-	s6 = &s4
-	s7 = *s6
-	s8 = <-s7
-
-	// channel
-	ch chan int
-	rc <-chan float64
-	sc chan <- string
-	ch0 = +ch /* ERROR "not defined" */
-	ch1 = -ch /* ERROR "not defined" */
-	ch2 = !ch /* ERROR "not defined" */
-	ch3 = ^ch /* ERROR "not defined" */
-	ch4 = *ch /* ERROR "cannot indirect" */
-	ch5 = &ch
-	ch6 = *ch5
-	ch7 = <-ch
-	ch8 = <-rc
-	ch9 = <-sc /* ERROR "cannot receive" */
-	ch10, ok = <-ch
-	// ok is of type bool
-	ch11, myok = <-ch
-	_ mybool = myok /* ERROR "cannot use .* in variable declaration" */
-)
-
-// address of composite literals
-type T struct{x, y int}
-
-func f() T { return T{} }
-
-var (
-	_ = &T{1, 2}
-	_ = &[...]int{}
-	_ = &[]int{}
-	_ = &[]int{}
-	_ = &map[string]T{}
-	_ = &(T{1, 2})
-	_ = &((((T{1, 2}))))
-	_ = &f /* ERROR "cannot take address" */ ()
-)
-
-// recursive pointer types
-type P *P
-
-var (
-	p1 P = new(P)
-	p2 P = *p1
-	p3 P = &p2
-)
-
-func g() (a, b int) { return }
-
-func _() {
-	_ = -g /* ERROR 2-valued g */ ()
-	_ = <-g /* ERROR 2-valued g */ ()
-}
-
-// ~ is accepted as unary operator only permitted in interface type elements
-var (
-	_ = ~ /* ERROR cannot use ~ outside of interface or type constraint */ 0
-	_ = ~ /* ERROR cannot use ~ outside of interface or type constraint */ "foo"
-	_ = ~ /* ERROR cannot use ~ outside of interface or type constraint */ i0
-)
\ No newline at end of file
diff --git a/src/cmd/compile/internal/types2/testdata/check/expr1.go b/src/cmd/compile/internal/types2/testdata/check/expr1.go
deleted file mode 100644
index 85ad234..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/expr1.go
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// binary expressions
-
-package expr1
-
-type mybool bool
-
-func _(x, y bool, z mybool) {
-	x = x || y
-	x = x || true
-	x = x || false
-	x = x && y
-	x = x && true
-	x = x && false
-
-	z = z /* ERROR mismatched types */ || y
-	z = z || true
-	z = z || false
-	z = z /* ERROR mismatched types */ && y
-	z = z && true
-	z = z && false
-}
-
-type myint int
-
-func _(x, y int, z myint) {
-	x = x + 1
-	x = x + 1.0
-	x = x + 1.1 // ERROR truncated to int
-	x = x + y
-	x = x - y
-	x = x * y
-	x = x / y
-	x = x % y
-	x = x << y
-	x = x >> y
-
-	z = z + 1
-	z = z + 1.0
-	z = z + 1.1 // ERROR truncated to int
-	z = z /* ERROR mismatched types */ + y
-	z = z /* ERROR mismatched types */ - y
-	z = z /* ERROR mismatched types */ * y
-	z = z /* ERROR mismatched types */ / y
-	z = z /* ERROR mismatched types */ % y
-	z = z << y
-	z = z >> y
-}
-
-type myuint uint
-
-func _(x, y uint, z myuint) {
-	x = x + 1
-	x = x + - /* ERROR overflows uint */ 1
-	x = x + 1.0
-	x = x + 1.1 // ERROR truncated to uint
-	x = x + y
-	x = x - y
-	x = x * y
-	x = x / y
-	x = x % y
-	x = x << y
-	x = x >> y
-
-	z = z + 1
-	z = x + - /* ERROR overflows uint */ 1
-	z = z + 1.0
-	z = z + 1.1 // ERROR truncated to uint
-	z = z /* ERROR mismatched types */ + y
-	z = z /* ERROR mismatched types */ - y
-	z = z /* ERROR mismatched types */ * y
-	z = z /* ERROR mismatched types */ / y
-	z = z /* ERROR mismatched types */ % y
-	z = z << y
-	z = z >> y
-}
-
-type myfloat64 float64
-
-func _(x, y float64, z myfloat64) {
-	x = x + 1
-	x = x + -1
-	x = x + 1.0
-	x = x + 1.1
-	x = x + y
-	x = x - y
-	x = x * y
-	x = x / y
-	x = x /* ERROR not defined */ % y
-	x = x /* ERROR operand x .* must be integer */ << y
-	x = x /* ERROR operand x .* must be integer */ >> y
-
-	z = z + 1
-	z = z + -1
-	z = z + 1.0
-	z = z + 1.1
-	z = z /* ERROR mismatched types */ + y
-	z = z /* ERROR mismatched types */ - y
-	z = z /* ERROR mismatched types */ * y
-	z = z /* ERROR mismatched types */ / y
-	z = z /* ERROR mismatched types */ % y
-	z = z /* ERROR operand z .* must be integer */ << y
-	z = z /* ERROR operand z .* must be integer */ >> y
-}
-
-type mystring string
-
-func _(x, y string, z mystring) {
-	x = x + "foo"
-	x = x /* ERROR not defined */ - "foo"
-	x = x + 1 // ERROR mismatched types string and untyped int
-	x = x + y
-	x = x /* ERROR not defined */ - y
-	x = x * 10 // ERROR mismatched types string and untyped int
-}
-
-func f() (a, b int) { return }
-
-func _(x int) {
-	_ = f /* ERROR 2-valued f */ () + 1
-	_ = x + f /* ERROR 2-valued f */ ()
-	_ = f /* ERROR 2-valued f */ () + f
-	_ = f /* ERROR 2-valued f */ () + f /* ERROR 2-valued f */ ()
-}
diff --git a/src/cmd/compile/internal/types2/testdata/check/expr2.go b/src/cmd/compile/internal/types2/testdata/check/expr2.go
deleted file mode 100644
index 88781f1..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/expr2.go
+++ /dev/null
@@ -1,260 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// comparisons
-
-package expr2
-
-func _bool() {
-	const t = true == true
-	const f = true == false
-	_ = t /* ERROR cannot compare */ < f
-	_ = 0 /* ERROR mismatched types untyped int and untyped bool */ == t
-	var b bool
-	var x, y float32
-	b = x < y
-	_ = b
-	_ = struct{b bool}{x < y}
-}
-
-// corner cases
-var (
-	v0 = nil == nil // ERROR operator == not defined on untyped nil
-)
-
-func arrays() {
-	// basics
-	var a, b [10]int
-	_ = a == b
-	_ = a != b
-	_ = a /* ERROR < not defined */ < b
-	_ = a == nil /* ERROR invalid operation.*mismatched types */
-
-	type C [10]int
-	var c C
-	_ = a == c
-
-	type D [10]int
-	var d D
-	_ = c /* ERROR mismatched types */ == d
-
-	var e [10]func() int
-	_ = e /* ERROR \[10\]func\(\) int cannot be compared */ == e
-}
-
-func structs() {
-	// basics
-	var s, t struct {
-		x int
-		a [10]float32
-		_ bool
-	}
-	_ = s == t
-	_ = s != t
-	_ = s /* ERROR < not defined */ < t
-	_ = s == nil /* ERROR invalid operation.*mismatched types */
-
-	type S struct {
-		x int
-		a [10]float32
-		_ bool
-	}
-	type T struct {
-		x int
-		a [10]float32
-		_ bool
-	}
-	var ss S
-	var tt T
-	_ = s == ss
-	_ = ss /* ERROR mismatched types */ == tt
-
-	var u struct {
-		x int
-		a [10]map[string]int
-	}
-	_ = u /* ERROR cannot compare */ == u
-}
-
-func pointers() {
-	// nil
-	_ = nil == nil // ERROR operator == not defined on untyped nil
-	_ = nil != nil // ERROR operator != not defined on untyped nil
-	_ = nil /* ERROR < not defined */ < nil
-	_ = nil /* ERROR <= not defined */ <= nil
-	_ = nil /* ERROR > not defined */ > nil
-	_ = nil /* ERROR >= not defined */ >= nil
-
-	// basics
-	var p, q *int
-	_ = p == q
-	_ = p != q
-
-	_ = p == nil
-	_ = p != nil
-	_ = nil == q
-	_ = nil != q
-
-	_ = p /* ERROR < not defined */ < q
-	_ = p /* ERROR <= not defined */ <= q
-	_ = p /* ERROR > not defined */ > q
-	_ = p /* ERROR >= not defined */ >= q
-
-	// various element types
-	type (
-		S1 struct{}
-		S2 struct{}
-		P1 *S1
-		P2 *S2
-	)
-	var (
-		ps1 *S1
-		ps2 *S2
-		p1 P1
-		p2 P2
-	)
-	_ = ps1 == ps1
-	_ = ps1 /* ERROR mismatched types */ == ps2
-	_ = ps2 /* ERROR mismatched types */ == ps1
-
-	_ = p1 == p1
-	_ = p1 /* ERROR mismatched types */ == p2
-
-	_ = p1 == ps1
-}
-
-func channels() {
-	// basics
-	var c, d chan int
-	_ = c == d
-	_ = c != d
-	_ = c == nil
-	_ = c /* ERROR < not defined */ < d
-
-	// various element types (named types)
-	type (
-		C1 chan int
-		C1r <-chan int
-		C1s chan<- int
-		C2 chan float32
-	)
-	var (
-		c1 C1
-		c1r C1r
-		c1s C1s
-		c1a chan int
-		c2 C2
-	)
-	_ = c1 == c1
-	_ = c1 /* ERROR mismatched types */ == c1r
-	_ = c1 /* ERROR mismatched types */ == c1s
-	_ = c1r /* ERROR mismatched types */ == c1s
-	_ = c1 == c1a
-	_ = c1a == c1
-	_ = c1 /* ERROR mismatched types */ == c2
-	_ = c1a /* ERROR mismatched types */ == c2
-
-	// various element types (unnamed types)
-	var (
-		d1 chan int
-		d1r <-chan int
-		d1s chan<- int
-		d1a chan<- int
-		d2 chan float32
-	)
-	_ = d1 == d1
-	_ = d1 == d1r
-	_ = d1 == d1s
-	_ = d1r /* ERROR mismatched types */ == d1s
-	_ = d1 == d1a
-	_ = d1a == d1
-	_ = d1 /* ERROR mismatched types */ == d2
-	_ = d1a /* ERROR mismatched types */ == d2
-}
-
-// for interfaces test
-type S1 struct{}
-type S11 struct{}
-type S2 struct{}
-func (*S1) m() int
-func (*S11) m() int
-func (*S11) n()
-func (*S2) m() float32
-
-func interfaces() {
-	// basics
-	var i, j interface{ m() int }
-	_ = i == j
-	_ = i != j
-	_ = i == nil
-	_ = i /* ERROR < not defined */ < j
-
-	// various interfaces
-	var ii interface { m() int; n() }
-	var k interface { m() float32 }
-	_ = i == ii
-	_ = i /* ERROR mismatched types */ == k
-
-	// interfaces vs values
-	var s1 S1
-	var s11 S11
-	var s2 S2
-
-	_ = i == 0 /* ERROR cannot convert */
-	_ = i /* ERROR mismatched types */ == s1
-	_ = i == &s1
-	_ = i == &s11
-
-	_ = i /* ERROR mismatched types */ == s2
-	_ = i /* ERROR mismatched types */ == &s2
-
-	// issue #28164
-	// testcase from issue
-	_ = interface{}(nil) == [ /* ERROR slice can only be compared to nil */ ]int(nil)
-
-	// related cases
-	var e interface{}
-	var s []int
-	var x int
-	_ = e == s // ERROR slice can only be compared to nil
-	_ = s /* ERROR slice can only be compared to nil */ == e
-	_ = e /* ERROR operator < not defined on interface */ < x
-	_ = x < e // ERROR operator < not defined on interface
-}
-
-func slices() {
-	// basics
-	var s []int
-	_ = s == nil
-	_ = s != nil
-	_ = s /* ERROR < not defined */ < nil
-
-	// slices are not otherwise comparable
-	_ = s /* ERROR slice can only be compared to nil */ == s
-	_ = s /* ERROR < not defined */ < s
-}
-
-func maps() {
-	// basics
-	var m map[string]int
-	_ = m == nil
-	_ = m != nil
-	_ = m /* ERROR < not defined */ < nil
-
-	// maps are not otherwise comparable
-	_ = m /* ERROR map can only be compared to nil */ == m
-	_ = m /* ERROR < not defined */ < m
-}
-
-func funcs() {
-	// basics
-	var f func(int) float32
-	_ = f == nil
-	_ = f != nil
-	_ = f /* ERROR < not defined */ < nil
-
-	// funcs are not otherwise comparable
-	_ = f /* ERROR func can only be compared to nil */ == f
-	_ = f /* ERROR < not defined */ < f
-}
diff --git a/src/cmd/compile/internal/types2/testdata/check/expr3.go b/src/cmd/compile/internal/types2/testdata/check/expr3.go
deleted file mode 100644
index 646319e..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/expr3.go
+++ /dev/null
@@ -1,565 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package expr3
-
-import "time"
-
-func indexes() {
-	var x int
-	_ = 1 /* ERROR "cannot index" */ [0]
-	_ = x /* ERROR "cannot index" */ [0]
-	_ = ( /* ERROR "cannot slice" */ 12 + 3)[1:2]
-
-	var a [10]int
-	_ = a[true /* ERROR "cannot convert" */ ]
-	_ = a["foo" /* ERROR "cannot convert" */ ]
-	_ = a[1.1 /* ERROR "truncated" */ ]
-	_ = a[1.0]
-	_ = a[- /* ERROR "negative" */ 1]
-	_ = a[- /* ERROR "negative" */ 1 :]
-	_ = a[: - /* ERROR "negative" */ 1]
-	_ = a[: /* ERROR "middle index required" */ : /* ERROR "final index required" */ ]
-	_ = a[0: /* ERROR "middle index required" */ : /* ERROR "final index required" */ ]
-	_ = a[0: /* ERROR "middle index required" */ :10]
-	_ = a[:10:10]
-
-	var a0 int
-	a0 = a[0]
-	_ = a0
-	var a1 int32
-	a1 = a /* ERROR "cannot use .* in assignment" */ [1]
-	_ = a1
-
-	_ = a[9]
-	_ = a[10 /* ERROR "index .* out of bounds" */ ]
-	_ = a[1 /* ERROR "overflows" */ <<100]
-	_ = a[1<< /* ERROR "constant shift overflow" */ 1000] // no out-of-bounds follow-on error
-	_ = a[10:]
-	_ = a[:10]
-	_ = a[10:10]
-	_ = a[11 /* ERROR "index .* out of bounds" */ :]
-	_ = a[: 11 /* ERROR "index .* out of bounds" */ ]
-	_ = a[: 1 /* ERROR "overflows" */ <<100]
-	_ = a[:10:10]
-	_ = a[:11 /* ERROR "index .* out of bounds" */ :10]
-	_ = a[:10:11 /* ERROR "index .* out of bounds" */ ]
-	_ = a[10:0 /* ERROR "invalid slice indices" */ :10]
-	_ = a[0:10:0 /* ERROR "invalid slice indices" */ ]
-	_ = a[10:0 /* ERROR "invalid slice indices" */:0]
-	_ = &a /* ERROR "cannot take address" */ [:10]
-
-	pa := &a
-	_ = pa[9]
-	_ = pa[10 /* ERROR "index .* out of bounds" */ ]
-	_ = pa[1 /* ERROR "overflows" */ <<100]
-	_ = pa[10:]
-	_ = pa[:10]
-	_ = pa[10:10]
-	_ = pa[11 /* ERROR "index .* out of bounds" */ :]
-	_ = pa[: 11 /* ERROR "index .* out of bounds" */ ]
-	_ = pa[: 1 /* ERROR "overflows" */ <<100]
-	_ = pa[:10:10]
-	_ = pa[:11 /* ERROR "index .* out of bounds" */ :10]
-	_ = pa[:10:11 /* ERROR "index .* out of bounds" */ ]
-	_ = pa[10:0 /* ERROR "invalid slice indices" */ :10]
-	_ = pa[0:10:0 /* ERROR "invalid slice indices" */ ]
-	_ = pa[10:0 /* ERROR "invalid slice indices" */ :0]
-	_ = &pa /* ERROR "cannot take address" */ [:10]
-
-	var b [0]int
-	_ = b[0 /* ERROR "index .* out of bounds" */ ]
-	_ = b[:]
-	_ = b[0:]
-	_ = b[:0]
-	_ = b[0:0]
-	_ = b[0:0:0]
-	_ = b[1 /* ERROR "index .* out of bounds" */ :0:0]
-
-	var s []int
-	_ = s[- /* ERROR "negative" */ 1]
-	_ = s[- /* ERROR "negative" */ 1 :]
-	_ = s[: - /* ERROR "negative" */ 1]
-	_ = s[0]
-	_ = s[1:2]
-	_ = s[2:1] /* ERROR "invalid slice indices" */
-	_ = s[2:]
-	_ = s[: 1 /* ERROR "overflows" */ <<100]
-	_ = s[1 /* ERROR "overflows" */ <<100 :]
-	_ = s[1 /* ERROR "overflows" */ <<100 : 1 /* ERROR "overflows" */ <<100]
-	_ = s[: /* ERROR "middle index required" */ :  /* ERROR "final index required" */ ]
-	_ = s[:10:10]
-	_ = s[10:0 /* ERROR "invalid slice indices" */ :10]
-	_ = s[0:10:0 /* ERROR "invalid slice indices" */ ]
-	_ = s[10:0 /* ERROR "invalid slice indices" */ :0]
-	_ = &s /* ERROR "cannot take address" */ [:10]
-
-	var m map[string]int
-	_ = m[0 /* ERROR "cannot use .* in map index" */ ]
-	_ = m /* ERROR "cannot slice" */ ["foo" : "bar"]
-	_ = m["foo"]
-	// ok is of type bool
-	type mybool bool
-	var ok mybool
-	_, ok = m["bar"]
-	_ = ok
-	_ = m[0 /* ERROR "cannot use 0" */ ] + "foo" // ERROR "mismatched types int and untyped string"
-
-	var t string
-	_ = t[- /* ERROR "negative" */ 1]
-	_ = t[- /* ERROR "negative" */ 1 :]
-	_ = t[: - /* ERROR "negative" */ 1]
-	_ = t[1:2:3 /* ERROR "3-index slice of string" */ ]
-	_ = "foo"[1:2:3 /* ERROR "3-index slice of string" */ ]
-	var t0 byte
-	t0 = t[0]
-	_ = t0
-	var t1 rune
-	t1 = t /* ERROR "cannot use .* in assignment" */ [2]
-	_ = t1
-	_ = ("foo" + "bar")[5]
-	_ = ("foo" + "bar")[6 /* ERROR "index .* out of bounds" */ ]
-
-	const c = "foo"
-	_ = c[- /* ERROR "negative" */ 1]
-	_ = c[- /* ERROR "negative" */ 1 :]
-	_ = c[: - /* ERROR "negative" */ 1]
-	var c0 byte
-	c0 = c[0]
-	_ = c0
-	var c2 float32
-	c2 = c /* ERROR "cannot use .* in assignment" */ [2]
-	_ = c[3 /* ERROR "index .* out of bounds" */ ]
-	_ = ""[0 /* ERROR "index .* out of bounds" */ ]
-	_ = c2
-
-	_ = s[1<<30] // no compile-time error here
-
-	// issue 4913
-	type mystring string
-	var ss string
-	var ms mystring
-	var i, j int
-	ss = "foo"[1:2]
-	ss = "foo"[i:j]
-	ms = "foo" /* ERROR "cannot use .* in assignment" */ [1:2]
-	ms = "foo" /* ERROR "cannot use .* in assignment" */ [i:j]
-	_, _ = ss, ms
-}
-
-type T struct {
-	x int
-	y func()
-}
-
-func (*T) m() {}
-
-func method_expressions() {
-	_ = T.a /* ERROR "no field or method" */
-	_ = T.x /* ERROR "has no method" */
-	_ = T.m /* ERROR "cannot call pointer method m on T" */
-	_ = (*T).m
-
-	var f func(*T) = T.m /* ERROR "cannot call pointer method m on T" */
-	var g func(*T) = (*T).m
-	_, _ = f, g
-
-	_ = T.y /* ERROR "has no method" */
-	_ = (*T).y /* ERROR "has no method" */
-}
-
-func struct_literals() {
-	type T0 struct {
-		a, b, c int
-	}
-
-	type T1 struct {
-		T0
-		a, b int
-		u float64
-		s string
-	}
-
-	// keyed elements
-	_ = T1{}
-	_ = T1{a: 0, 1 /* ERROR "mixture of .* elements" */ }
-	_ = T1{aa /* ERROR "unknown field" */ : 0}
-	_ = T1{1 /* ERROR "invalid field name" */ : 0}
-	_ = T1{a: 0, s: "foo", u: 0, a /* ERROR "duplicate field" */: 10}
-	_ = T1{a: "foo" /* ERROR "cannot use .* in struct literal" */ }
-	_ = T1{c /* ERROR "unknown field" */ : 0}
-	_ = T1{T0: { /* ERROR "missing type" */ }} // struct literal element type may not be elided
-	_ = T1{T0: T0{}}
-	_ = T1{T0 /* ERROR "invalid field name" */ .a: 0}
-
-	// unkeyed elements
-	_ = T0{1, 2, 3}
-	_ = T0{1, b /* ERROR "mixture" */ : 2, 3}
-	_ = T0{1, 2} /* ERROR "too few values" */
-	_ = T0{1, 2, 3, 4  /* ERROR "too many values" */ }
-	_ = T0{1, "foo" /* ERROR "cannot use .* in struct literal" */, 3.4  /* ERROR "cannot use .*\(truncated\)" */}
-
-	// invalid type
-	type P *struct{
-		x int
-	}
-	_ = P /* ERROR "invalid composite literal type" */ {}
-
-	// unexported fields
-	_ = time.Time{}
-	_ = time.Time{sec /* ERROR "unknown field" */ : 0}
-	_ = time.Time{
-		0 /* ERROR implicit assignment to unexported field wall in time.Time literal */,
-		0 /* ERROR implicit assignment */ ,
-		nil /* ERROR implicit assignment */ ,
-	}
-}
-
-func array_literals() {
-	type A0 [0]int
-	_ = A0{}
-	_ = A0{0 /* ERROR "index .* out of bounds" */}
-	_ = A0{0 /* ERROR "index .* out of bounds" */ : 0}
-
-	type A1 [10]int
-	_ = A1{}
-	_ = A1{0, 1, 2}
-	_ = A1{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
-	_ = A1{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 /* ERROR "index .* out of bounds" */ }
-	_ = A1{- /* ERROR "negative" */ 1: 0}
-	_ = A1{8: 8, 9}
-	_ = A1{8: 8, 9, 10 /* ERROR "index .* out of bounds" */ }
-	_ = A1{0, 1, 2, 0 /* ERROR "duplicate index" */ : 0, 3: 3, 4}
-	_ = A1{5: 5, 6, 7, 3: 3, 4}
-	_ = A1{5: 5, 6, 7, 3: 3, 4, 5 /* ERROR "duplicate index" */ }
-	_ = A1{10 /* ERROR "index .* out of bounds" */ : 10, 10 /* ERROR "index .* out of bounds" */ : 10}
-	_ = A1{5: 5, 6, 7, 3: 3, 1 /* ERROR "overflows" */ <<100: 4, 5 /* ERROR "duplicate index" */ }
-	_ = A1{5: 5, 6, 7, 4: 4, 1 /* ERROR "overflows" */ <<100: 4}
-	_ = A1{2.0}
-	_ = A1{2.1 /* ERROR "truncated" */ }
-	_ = A1{"foo" /* ERROR "cannot use .* in array or slice literal" */ }
-
-	// indices must be integer constants
-	i := 1
-	const f = 2.1
-	const s = "foo"
-	_ = A1{i /* ERROR "index i must be integer constant" */ : 0}
-	_ = A1{f /* ERROR "truncated" */ : 0}
-	_ = A1{s /* ERROR "cannot convert" */ : 0}
-
-	a0 := [...]int{}
-	assert(len(a0) == 0)
-
-	a1 := [...]int{0, 1, 2}
-	assert(len(a1) == 3)
-	var a13 [3]int
-	var a14 [4]int
-	a13 = a1
-	a14 = a1 /* ERROR "cannot use .* in assignment" */
-	_, _ = a13, a14
-
-	a2 := [...]int{- /* ERROR "negative" */ 1: 0}
-	_ = a2
-
-	a3 := [...]int{0, 1, 2, 0 /* ERROR "duplicate index" */ : 0, 3: 3, 4}
-	assert(len(a3) == 5) // somewhat arbitrary
-
-	a4 := [...]complex128{0, 1, 2, 1<<10-2: -1i, 1i, 400: 10, 12, 14}
-	assert(len(a4) == 1024)
-
-	// composite literal element types may be elided
-	type T []int
-	_ = [10]T{T{}, {}, 5: T{1, 2, 3}, 7: {1, 2, 3}}
-	a6 := [...]T{T{}, {}, 5: T{1, 2, 3}, 7: {1, 2, 3}}
-	assert(len(a6) == 8)
-
-	// recursively so
-	_ = [10][10]T{{}, [10]T{{}}, {{1, 2, 3}}}
-
-	// from the spec
-	type Point struct { x, y float32 }
-	_ = [...]Point{Point{1.5, -3.5}, Point{0, 0}}
-	_ = [...]Point{{1.5, -3.5}, {0, 0}}
-	_ = [][]int{[]int{1, 2, 3}, []int{4, 5}}
-	_ = [][]int{{1, 2, 3}, {4, 5}}
-	_ = [...]*Point{&Point{1.5, -3.5}, &Point{0, 0}}
-	_ = [...]*Point{{1.5, -3.5}, {0, 0}}
-}
-
-func slice_literals() {
-	type S0 []int
-	_ = S0{}
-	_ = S0{0, 1, 2}
-	_ = S0{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
-	_ = S0{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
-	_ = S0{- /* ERROR "negative" */ 1: 0}
-	_ = S0{8: 8, 9}
-	_ = S0{8: 8, 9, 10}
-	_ = S0{0, 1, 2, 0 /* ERROR "duplicate index" */ : 0, 3: 3, 4}
-	_ = S0{5: 5, 6, 7, 3: 3, 4}
-	_ = S0{5: 5, 6, 7, 3: 3, 4, 5 /* ERROR "duplicate index" */ }
-	_ = S0{10: 10, 10 /* ERROR "duplicate index" */ : 10}
-	_ = S0{5: 5, 6, 7, 3: 3, 1 /* ERROR "overflows" */ <<100: 4, 5 /* ERROR "duplicate index" */ }
-	_ = S0{5: 5, 6, 7, 4: 4, 1 /* ERROR "overflows" */ <<100: 4}
-	_ = S0{2.0}
-	_ = S0{2.1 /* ERROR "truncated" */ }
-	_ = S0{"foo" /* ERROR "cannot use .* in array or slice literal" */ }
-
-	// indices must be resolved correctly
-	const index1 = 1
-	_ = S0{index1: 1}
-	_ = S0{index2: 2}
-	_ = S0{index3 /* ERROR "undeclared name" */ : 3}
-
-	// indices must be integer constants
-	i := 1
-	const f = 2.1
-	const s = "foo"
-	_ = S0{i /* ERROR "index i must be integer constant" */ : 0}
-	_ = S0{f /* ERROR "truncated" */ : 0}
-	_ = S0{s /* ERROR "cannot convert" */ : 0}
-
-	// composite literal element types may be elided
-	type T []int
-	_ = []T{T{}, {}, 5: T{1, 2, 3}, 7: {1, 2, 3}}
-	_ = [][]int{{1, 2, 3}, {4, 5}}
-
-	// recursively so
-	_ = [][]T{{}, []T{{}}, {{1, 2, 3}}}
-
-	// issue 17954
-	type T0 *struct { s string }
-	_ = []T0{{}}
-	_ = []T0{{"foo"}}
-
-	type T1 *struct{ int }
-	_ = []T1{}
-	_ = []T1{{0}, {1}, {2}}
-
-	type T2 T1
-	_ = []T2{}
-	_ = []T2{{0}, {1}, {2}}
-
-	_ = map[T0]T2{}
-	_ = map[T0]T2{{}: {}}
-}
-
-const index2 int = 2
-
-type N int
-func (N) f() {}
-
-func map_literals() {
-	type M0 map[string]int
-	type M1 map[bool]int
-	type M2 map[*int]int
-
-	_ = M0{}
-	_ = M0{1 /* ERROR "missing key" */ }
-	_ = M0{1 /* ERROR "cannot use .* in map literal" */ : 2}
-	_ = M0{"foo": "bar" /* ERROR "cannot use .* in map literal" */ }
-	_ = M0{"foo": 1, "bar": 2, "foo" /* ERROR "duplicate key" */ : 3 }
-
-	_ = map[interface{}]int{2: 1, 2 /* ERROR "duplicate key" */ : 1}
-	_ = map[interface{}]int{int(2): 1, int16(2): 1}
-	_ = map[interface{}]int{int16(2): 1, int16 /* ERROR "duplicate key" */ (2): 1}
-
-	type S string
-
-	_ = map[interface{}]int{"a": 1, "a" /* ERROR "duplicate key" */ : 1}
-	_ = map[interface{}]int{"a": 1, S("a"): 1}
-	_ = map[interface{}]int{S("a"): 1, S /* ERROR "duplicate key" */ ("a"): 1}
-	_ = map[interface{}]int{1.0: 1, 1.0 /* ERROR "duplicate key" */: 1}
-	_ = map[interface{}]int{int64(-1): 1, int64 /* ERROR "duplicate key" */ (-1) : 1}
-	_ = map[interface{}]int{^uint64(0): 1, ^ /* ERROR "duplicate key" */ uint64(0): 1}
-	_ = map[interface{}]int{complex(1,2): 1, complex /* ERROR "duplicate key" */ (1,2) : 1}
-
-	type I interface {
-		f()
-	}
-
-	_ = map[I]int{N(0): 1, N(2): 1}
-	_ = map[I]int{N(2): 1, N /* ERROR "duplicate key" */ (2): 1}
-
-	// map keys must be resolved correctly
-	key1 := "foo"
-	_ = M0{key1: 1}
-	_ = M0{key2: 2}
-	_ = M0{key3 /* ERROR "undeclared name" */ : 2}
-
-	var value int
-	_ = M1{true: 1, false: 0}
-	_ = M2{nil: 0, &value: 1}
-
-	// composite literal element types may be elided
-	type T [2]int
-	_ = map[int]T{0: T{3, 4}, 1: {5, 6}}
-
-	// recursively so
-	_ = map[int][]T{0: {}, 1: {{}, T{1, 2}}}
-
-	// composite literal key types may be elided
-	_ = map[T]int{T{3, 4}: 0, {5, 6}: 1}
-
-	// recursively so
-	_ = map[[2]T]int{{}: 0, {{}}: 1, [2]T{{}}: 2, {T{1, 2}}: 3}
-
-	// composite literal element and key types may be elided
-	_ = map[T]T{{}: {}, {1, 2}: T{3, 4}, T{4, 5}: {}}
-	_ = map[T]M0{{} : {}, T{1, 2}: M0{"foo": 0}, {1, 3}: {"foo": 1}}
-
-	// recursively so
-	_ = map[[2]T][]T{{}: {}, {{}}: {{}, T{1, 2}}, [2]T{{}}: nil, {T{1, 2}}: {{}, {}}}
-
-	// from the spec
-	type Point struct { x, y float32 }
-	_ = map[string]Point{"orig": {0, 0}}
-	_ = map[*Point]string{{0, 0}: "orig"}
-
-	// issue 17954
-	type T0 *struct{ s string }
-	type T1 *struct{ int }
-	type T2 T1
-
-	_ = map[T0]T2{}
-	_ = map[T0]T2{{}: {}}
-}
-
-var key2 string = "bar"
-
-type I interface {
-	m()
-}
-
-type I2 interface {
-	m(int)
-}
-
-type T1 struct{}
-type T2 struct{}
-
-func (T2) m(int) {}
-
-type mybool bool
-
-func type_asserts() {
-	var x int
-	_ = x /* ERROR "not an interface" */ .(int)
-
-	var e interface{}
-	var ok bool
-	x, ok = e.(int)
-	_ = ok
-
-	// ok value is of type bool
-	var myok mybool
-	_, myok = e.(int)
-	_ = myok
-
-	var t I
-	_ = t /* ERROR "use of .* outside type switch" */ .(type)
-	_ = t /* ERROR "method m has pointer receiver" */ .(T)
-	_ = t.(*T)
-	_ = t /* ERROR "missing method m" */ .(T1)
-	_ = t /* ERROR "wrong type for method m" */ .(T2)
-	_ = t /* STRICT "wrong type for method m" */ .(I2) // only an error in strict mode (issue 8561)
-
-	// e doesn't statically have an m, but may have one dynamically.
-	_ = e.(I2)
-}
-
-func f0() {}
-func f1(x int) {}
-func f2(u float32, s string) {}
-func fs(s []byte) {}
-func fv(x ...int) {}
-func fi(x ... interface{}) {}
-func (T) fm(x ...int)
-
-func g0() {}
-func g1() int { return 0}
-func g2() (u float32, s string) { return }
-func gs() []byte { return nil }
-
-func _calls() {
-	var x int
-	var y float32
-	var s []int
-
-	f0()
-	_ = f0 /* ERROR "used as value" */ ()
-	f0(g0 /* ERROR "too many arguments" */ )
-
-	f1(0)
-	f1(x)
-	f1(10.0)
-	f1 /* ERROR "not enough arguments in call to f1\n\thave \(\)\n\twant \(int\)" */ ()
-	f1(x, y /* ERROR "too many arguments in call to f1\n\thave \(int, float32\)\n\twant \(int\)" */ )
-	f1(s /* ERROR "cannot use .* in argument" */ )
-	f1(x ... /* ERROR "cannot use ..." */ )
-	f1(g0 /* ERROR "used as value" */ ())
-	f1(g1())
-	f1(g2 /* ERROR "too many arguments in call to f1\n\thave \(float32, string\)\n\twant \(int\)" */ ())
-
-	f2 /* ERROR "not enough arguments in call to f2\n\thave \(\)\n\twant \(float32, string\)" */ ()
-	f2(3.14 /* ERROR "not enough arguments in call to f2\n\thave \(number\)\n\twant \(float32, string\)" */ )
-	f2(3.14, "foo")
-	f2(x /* ERROR "cannot use .* in argument" */ , "foo")
-	f2(g0 /* ERROR "used as value" */ ())
-	f2(g1 /* ERROR "not enough arguments in call to f2\n\thave \(int\)\n\twant \(float32, string\)" */ ())
-	f2(g2())
-
-	fs /* ERROR "not enough arguments" */ ()
-	fs(g0 /* ERROR "used as value" */ ())
-	fs(g1 /* ERROR "cannot use .* in argument" */ ())
-	fs(g2 /* ERROR "too many arguments" */ ())
-	fs(gs())
-
-	fv()
-	fv(1, 2.0, x)
-	fv(s /* ERROR "cannot use .* in argument" */ )
-	fv(s...)
-	fv(x /* ERROR "cannot use" */ ...)
-	fv(1, s /* ERROR "too many arguments" */ ... )
-	fv(gs /* ERROR "cannot use .* in argument" */ ())
-	fv(gs /* ERROR "cannot use .* in argument" */ ()...)
-
-	var t T
-	t.fm()
-	t.fm(1, 2.0, x)
-	t.fm(s /* ERROR "cannot use .* in argument" */ )
-	t.fm(g1())
-	t.fm(1, s /* ERROR "too many arguments" */ ... )
-	t.fm(gs /* ERROR "cannot use .* in argument" */ ())
-	t.fm(gs /* ERROR "cannot use .* in argument" */ ()...)
-
-	T.fm(t, )
-	T.fm(t, 1, 2.0, x)
-	T.fm(t, s /* ERROR "cannot use .* in argument" */ )
-	T.fm(t, g1())
-	T.fm(t, 1, s /* ERROR "too many arguments" */ ... )
-	T.fm(t, gs /* ERROR "cannot use .* in argument" */ ())
-	T.fm(t, gs /* ERROR "cannot use .* in argument" */ ()...)
-
-	var i interface{ fm(x ...int) } = t
-	i.fm()
-	i.fm(1, 2.0, x)
-	i.fm(s /* ERROR "cannot use .* in argument" */ )
-	i.fm(g1())
-	i.fm(1, s /* ERROR "too many arguments" */ ... )
-	i.fm(gs /* ERROR "cannot use .* in argument" */ ())
-	i.fm(gs /* ERROR "cannot use .* in argument" */ ()...)
-
-	fi()
-	fi(1, 2.0, x, 3.14, "foo")
-	fi(g2())
-	fi(0, g2)
-	fi(0, g2 /* ERROR "2-valued g2" */ ())
-}
-
-func issue6344() {
-	type T []interface{}
-	var x T
-	fi(x...) // ... applies also to named slices
-}
diff --git a/src/cmd/compile/internal/types2/testdata/check/funcinference.go b/src/cmd/compile/internal/types2/testdata/check/funcinference.go
deleted file mode 100644
index fedf199..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/funcinference.go
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package funcInference
-
-import "strconv"
-
-type any interface{}
-
-func f0[A any, B interface{*C}, C interface{*D}, D interface{*A}](A, B, C, D) {}
-func _() {
-	f := f0[string]
-	f("a", nil, nil, nil)
-	f0("a", nil, nil, nil)
-}
-
-func f1[A any, B interface{*A}](A, B) {}
-func _() {
-	f := f1[int]
-	f(int(0), new(int))
-	f1(int(0), new(int))
-}
-
-func f2[A any, B interface{[]A}](A, B) {}
-func _() {
-	f := f2[byte]
-	f(byte(0), []byte{})
-	f2(byte(0), []byte{})
-}
-
-// Embedding stand-alone type parameters is not permitted for now. Disabled.
-// func f3[A any, B interface{~C}, C interface{~*A}](A, B, C)
-// func _() {
-// 	f := f3[int]
-// 	var x int
-// 	f(x, &x, &x)
-// 	f3(x, &x, &x)
-// }
-
-func f4[A any, B interface{[]C}, C interface{*A}](A, B, C) {}
-func _() {
-	f := f4[int]
-	var x int
-	f(x, []*int{}, &x)
-	f4(x, []*int{}, &x)
-}
-
-func f5[A interface{struct{b B; c C}}, B any, C interface{*B}](x B) A { panic(0) }
-func _() {
-	x := f5(1.2)
-	var _ float64 = x.b
-	var _ float64 = *x.c
-}
-
-func f6[A any, B interface{~struct{f []A}}](B) A { panic(0) }
-func _() {
-	x := f6(struct{f []string}{})
-	var _ string = x
-}
-
-func f7[A interface{*B}, B interface{~*A}]() {}
-
-// More realistic examples
-
-func Double[S interface{ ~[]E }, E interface{ ~int | ~int8 | ~int16 | ~int32 | ~int64 }](s S) S {
-	r := make(S, len(s))
-	for i, v := range s {
-		r[i] = v + v
-	}
-	return r
-}
-
-type MySlice []int
-
-var _ = Double(MySlice{1})
-
-// From the draft design.
-
-type Setter[B any] interface {
-	Set(string)
-	*B
-}
-
-func FromStrings[T interface{}, PT Setter[T]](s []string) []T {
-	result := make([]T, len(s))
-	for i, v := range s {
-		// The type of &result[i] is *T which is in the type set
-		// of Setter, so we can convert it to PT.
-		p := PT(&result[i])
-		// PT has a Set method.
-		p.Set(v)
-	}
-	return result
-}
-
-type Settable int
-
-func (p *Settable) Set(s string) {
-	i, _ := strconv.Atoi(s) // real code should not ignore the error
-	*p = Settable(i)
-}
-
-var _ = FromStrings[Settable]([]string{"1", "2"})
diff --git a/src/cmd/compile/internal/types2/testdata/check/go1_16.go b/src/cmd/compile/internal/types2/testdata/check/go1_16.go
deleted file mode 100644
index 81b5290..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/go1_16.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// -lang=go1.16
-
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Check Go language version-specific errors.
-
-package p
-
-type Slice []byte
-type Array [8]byte
-
-var s Slice
-var p = (*Array)(s /* ERROR requires go1.17 or later */ )
diff --git a/src/cmd/compile/internal/types2/testdata/check/go1_8.go b/src/cmd/compile/internal/types2/testdata/check/go1_8.go
deleted file mode 100644
index 15462ab..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/go1_8.go
+++ /dev/null
@@ -1,12 +0,0 @@
-// -lang=go1.8
-
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Check Go language version-specific errors.
-
-package p
-
-// type alias declarations
-type any /* ERROR type aliases requires go1.9 or later */ = interface{}
diff --git a/src/cmd/compile/internal/types2/testdata/check/gotos.go b/src/cmd/compile/internal/types2/testdata/check/gotos.go
deleted file mode 100644
index 069a94b..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/gotos.go
+++ /dev/null
@@ -1,560 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file is a modified copy of $GOROOT/test/goto.go.
-
-package gotos
-
-var (
-	i, n int
-	x    []int
-	c    chan int
-	m    map[int]int
-	s    string
-)
-
-// goto after declaration okay
-func _() {
-	x := 1
-	goto L
-L:
-	_ = x
-}
-
-// goto before declaration okay
-func _() {
-	goto L
-L:
-	x := 1
-	_ = x
-}
-
-// goto across declaration not okay
-func _() {
-	goto L /* ERROR "goto L jumps over variable declaration at line 36" */
-	x := 1
-	_ = x
-L:
-}
-
-// goto across declaration in inner scope okay
-func _() {
-	goto L
-	{
-		x := 1
-		_ = x
-	}
-L:
-}
-
-// goto across declaration after inner scope not okay
-func _() {
-	goto L /* ERROR "goto L jumps over variable declaration at line 58" */
-	{
-		x := 1
-		_ = x
-	}
-	x := 1
-	_ = x
-L:
-}
-
-// goto across declaration in reverse okay
-func _() {
-L:
-	x := 1
-	_ = x
-	goto L
-}
-
-func _() {
-L: L1:
-	x := 1
-	_ = x
-	goto L
-	goto L1
-}
-
-// error shows first offending variable
-func _() {
-	goto L /* ERROR "goto L jumps over variable declaration at line 84" */
-	x := 1
-	_ = x
-	y := 1
-	_ = y
-L:
-}
-
-// goto not okay even if code path is dead
-func _() {
-	goto L /* ERROR "goto L jumps over variable declaration" */
-	x := 1
-	_ = x
-	y := 1
-	_ = y
-	return
-L:
-}
-
-// goto into outer block okay
-func _() {
-	{
-		goto L
-	}
-L:
-}
-
-func _() {
-	{
-		goto L
-		goto L1
-	}
-L: L1:
-}
-
-// goto backward into outer block okay
-func _() {
-L:
-	{
-		goto L
-	}
-}
-
-func _() {
-L: L1:
-	{
-		goto L
-		goto L1
-	}
-}
-
-// goto into inner block not okay
-func _() {
-	goto L /* ERROR "goto L jumps into block" */
-	{
-	L:
-	}
-}
-
-func _() {
-	goto L /* ERROR "goto L jumps into block" */
-	goto L1 /* ERROR "goto L1 jumps into block" */
-	{
-	L: L1:
-	}
-}
-
-// goto backward into inner block still not okay
-func _() {
-	{
-	L:
-	}
-	goto L /* ERROR "goto L jumps into block" */
-}
-
-func _() {
-	{
-	L: L1:
-	}
-	goto L /* ERROR "goto L jumps into block" */
-	goto L1 /* ERROR "goto L1 jumps into block" */
-}
-
-// error shows first (outermost) offending block
-func _() {
-	goto L /* ERROR "goto L jumps into block" */
-	{
-		{
-			{
-			L:
-			}
-		}
-	}
-}
-
-// error prefers block diagnostic over declaration diagnostic
-func _() {
-	goto L /* ERROR "goto L jumps into block" */
-	x := 1
-	_ = x
-	{
-	L:
-	}
-}
-
-// many kinds of blocks, all invalid to jump into or among,
-// but valid to jump out of
-
-// if
-
-func _() {
-L:
-	if true {
-		goto L
-	}
-}
-
-func _() {
-L:
-	if true {
-		goto L
-	} else {
-	}
-}
-
-func _() {
-L:
-	if false {
-	} else {
-		goto L
-	}
-}
-
-func _() {
-	goto L /* ERROR "goto L jumps into block" */
-	if true {
-	L:
-	}
-}
-
-func _() {
-	goto L /* ERROR "goto L jumps into block" */
-	if true {
-	L:
-	} else {
-	}
-}
-
-func _() {
-	goto L /* ERROR "goto L jumps into block" */
-	if true {
-	} else {
-	L:
-	}
-}
-
-func _() {
-	if false {
-	L:
-	} else {
-		goto L /* ERROR "goto L jumps into block" */
-	}
-}
-
-func _() {
-	if true {
-		goto L /* ERROR "goto L jumps into block" */
-	} else {
-	L:
-	}
-}
-
-func _() {
-	if true {
-		goto L /* ERROR "goto L jumps into block" */
-	} else if false {
-	L:
-	}
-}
-
-func _() {
-	if true {
-		goto L /* ERROR "goto L jumps into block" */
-	} else if false {
-	L:
-	} else {
-	}
-}
-
-func _() {
-	if true {
-		goto L /* ERROR "goto L jumps into block" */
-	} else if false {
-	} else {
-	L:
-	}
-}
-
-func _() {
-	if true {
-		goto L /* ERROR "goto L jumps into block" */
-	} else {
-		L:
-	}
-}
-
-func _() {
-	if true {
-		L:
-	} else {
-		goto L /* ERROR "goto L jumps into block" */
-	}
-}
-
-// for
-
-func _() {
-	for {
-		goto L
-	}
-L:
-}
-
-func _() {
-	for {
-		goto L
-	L:
-	}
-}
-
-func _() {
-	for {
-	L:
-	}
-	goto L /* ERROR "goto L jumps into block" */
-}
-
-func _() {
-	for {
-		goto L
-	L1:
-	}
-L:
-	goto L1 /* ERROR "goto L1 jumps into block" */
-}
-
-func _() {
-	for i < n {
-	L:
-	}
-	goto L /* ERROR "goto L jumps into block" */
-}
-
-func _() {
-	for i = 0; i < n; i++ {
-	L:
-	}
-	goto L /* ERROR "goto L jumps into block" */
-}
-
-func _() {
-	for i = range x {
-	L:
-	}
-	goto L /* ERROR "goto L jumps into block" */
-}
-
-func _() {
-	for i = range c {
-	L:
-	}
-	goto L /* ERROR "goto L jumps into block" */
-}
-
-func _() {
-	for i = range m {
-	L:
-	}
-	goto L /* ERROR "goto L jumps into block" */
-}
-
-func _() {
-	for i = range s {
-	L:
-	}
-	goto L /* ERROR "goto L jumps into block" */
-}
-
-// switch
-
-func _() {
-L:
-	switch i {
-	case 0:
-		goto L
-	}
-}
-
-func _() {
-L:
-	switch i {
-	case 0:
-
-	default:
-		goto L
-	}
-}
-
-func _() {
-	switch i {
-	case 0:
-
-	default:
-	L:
-		goto L
-	}
-}
-
-func _() {
-	switch i {
-	case 0:
-
-	default:
-		goto L
-	L:
-	}
-}
-
-func _() {
-	switch i {
-	case 0:
-		goto L
-	L:
-		;
-	default:
-	}
-}
-
-func _() {
-	goto L /* ERROR "goto L jumps into block" */
-	switch i {
-	case 0:
-	L:
-	}
-}
-
-func _() {
-	goto L /* ERROR "goto L jumps into block" */
-	switch i {
-	case 0:
-	L:
-		;
-	default:
-	}
-}
-
-func _() {
-	goto L /* ERROR "goto L jumps into block" */
-	switch i {
-	case 0:
-	default:
-	L:
-	}
-}
-
-func _() {
-	switch i {
-	default:
-		goto L /* ERROR "goto L jumps into block" */
-	case 0:
-	L:
-	}
-}
-
-func _() {
-	switch i {
-	case 0:
-	L:
-		;
-	default:
-		goto L /* ERROR "goto L jumps into block" */
-	}
-}
-
-// select
-// different from switch.  the statement has no implicit block around it.
-
-func _() {
-L:
-	select {
-	case <-c:
-		goto L
-	}
-}
-
-func _() {
-L:
-	select {
-	case c <- 1:
-
-	default:
-		goto L
-	}
-}
-
-func _() {
-	select {
-	case <-c:
-
-	default:
-	L:
-		goto L
-	}
-}
-
-func _() {
-	select {
-	case c <- 1:
-
-	default:
-		goto L
-	L:
-	}
-}
-
-func _() {
-	select {
-	case <-c:
-		goto L
-	L:
-		;
-	default:
-	}
-}
-
-func _() {
-	goto L /* ERROR "goto L jumps into block" */
-	select {
-	case c <- 1:
-	L:
-	}
-}
-
-func _() {
-	goto L /* ERROR "goto L jumps into block" */
-	select {
-	case c <- 1:
-	L:
-		;
-	default:
-	}
-}
-
-func _() {
-	goto L /* ERROR "goto L jumps into block" */
-	select {
-	case <-c:
-	default:
-	L:
-	}
-}
-
-func _() {
-	select {
-	default:
-		goto L /* ERROR "goto L jumps into block" */
-	case <-c:
-	L:
-	}
-}
-
-func _() {
-	select {
-	case <-c:
-	L:
-		;
-	default:
-		goto L /* ERROR "goto L jumps into block" */
-	}
-}
diff --git a/src/cmd/compile/internal/types2/testdata/check/importC.go b/src/cmd/compile/internal/types2/testdata/check/importC.go
deleted file mode 100644
index 8078021..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/importC.go
+++ /dev/null
@@ -1,56 +0,0 @@
-// -fakeImportC
-
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package importC
-
-import "C"
-import _ /* ERROR cannot rename import "C" */ "C"
-import foo /* ERROR cannot rename import "C" */ "C"
-import . /* ERROR cannot rename import "C" */ "C"
-
-// Test cases extracted from issue #22090.
-
-import "unsafe"
-
-const _ C.int = 0xff // no error due to invalid constant type
-
-type T struct {
-	Name    string
-	Ordinal int
-}
-
-func _(args []T) {
-	var s string
-	for i, v := range args {
-		cname := C.CString(v.Name)
-		args[i].Ordinal = int(C.sqlite3_bind_parameter_index(s, cname)) // no error due to i not being "used"
-		C.free(unsafe.Pointer(cname))
-	}
-}
-
-type CType C.Type
-
-const _ CType = C.X // no error due to invalid constant type
-const _ = C.X
-
-// Test cases extracted from issue #23712.
-
-func _() {
-	var a [C.ArrayLength]byte
-	_ = a[0] // no index out of bounds error here
-}
-
-// Additional tests to verify fix for #23712.
-
-func _() {
-	var a [C.ArrayLength1]byte
-	_ = 1 / len(a) // no division by zero error here and below
-	_ = 1 / cap(a)
-	_ = uint(unsafe.Sizeof(a)) // must not be negative
-
-	var b [C.ArrayLength2]byte
-	a = b // should be valid
-}
diff --git a/src/cmd/compile/internal/types2/testdata/check/importdecl0/importdecl0a.go b/src/cmd/compile/internal/types2/testdata/check/importdecl0/importdecl0a.go
deleted file mode 100644
index 5ceb96e..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/importdecl0/importdecl0a.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package importdecl0
-
-import ()
-
-import (
-	// we can have multiple blank imports (was bug)
-	_ "math"
-	_ "net/rpc"
-	init /* ERROR "cannot import package as init" */ "fmt"
-	// reflect defines a type "flag" which shows up in the gc export data
-	"reflect"
-	. /* ERROR "imported but not used" */ "reflect"
-)
-
-import "math" /* ERROR "imported but not used" */
-import m /* ERROR "imported but not used as m" */ "math"
-import _ "math"
-
-import (
-	"math/big" /* ERROR "imported but not used" */
-	b /* ERROR "imported but not used" */ "math/big"
-	_ "math/big"
-)
-
-import "fmt"
-import f1 "fmt"
-import f2 "fmt"
-
-// reflect.flag must not be visible in this package
-type flag int
-type _ reflect.flag /* ERROR "not exported" */
-
-// imported package name may conflict with local objects
-type reflect /* ERROR "reflect already declared" */ int
-
-// dot-imported exported objects may conflict with local objects
-type Value /* ERROR "Value already declared through dot-import of package reflect" */ struct{}
-
-var _ = fmt.Println // use "fmt"
-
-func _() {
-	f1.Println() // use "fmt"
-}
-
-func _() {
-	_ = func() {
-		f2.Println() // use "fmt"
-	}
-}
diff --git a/src/cmd/compile/internal/types2/testdata/check/importdecl0/importdecl0b.go b/src/cmd/compile/internal/types2/testdata/check/importdecl0/importdecl0b.go
deleted file mode 100644
index 19b55af..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/importdecl0/importdecl0b.go
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package importdecl0
-
-import "math"
-import m "math"
-
-import . "testing" // declares T in file scope
-import . /* ERROR .unsafe. imported but not used */ "unsafe"
-import . "fmt"     // declares Println in file scope
-
-import (
-	"" /* ERROR invalid import path */
-	"a!b" /* ERROR invalid import path */
-	"abc\xffdef" /* ERROR invalid import path */
-)
-
-// using "math" in this file doesn't affect its use in other files
-const Pi0 = math.Pi
-const Pi1 = m.Pi
-
-type _ T // use "testing"
-
-func _() func() interface{} {
-	return func() interface{} {
-		return Println // use "fmt"
-	}
-}
diff --git a/src/cmd/compile/internal/types2/testdata/check/importdecl1/importdecl1a.go b/src/cmd/compile/internal/types2/testdata/check/importdecl1/importdecl1a.go
deleted file mode 100644
index d377c01..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/importdecl1/importdecl1a.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Test case for issue 8969.
-
-package importdecl1
-
-import "go/ast"
-import . "unsafe"
-
-var _ Pointer // use dot-imported package unsafe
-
-// Test cases for issue 23914.
-
-type A interface {
-	// Methods m1, m2 must be type-checked in this file scope
-	// even when embedded in an interface in a different
-	// file of the same package.
-	m1() ast.Node
-	m2() Pointer
-}
diff --git a/src/cmd/compile/internal/types2/testdata/check/importdecl1/importdecl1b.go b/src/cmd/compile/internal/types2/testdata/check/importdecl1/importdecl1b.go
deleted file mode 100644
index 43a7bcd..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/importdecl1/importdecl1b.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package importdecl1
-
-import . /* ERROR .unsafe. imported but not used */ "unsafe"
-
-type B interface {
-	A
-}
diff --git a/src/cmd/compile/internal/types2/testdata/check/init0.go b/src/cmd/compile/internal/types2/testdata/check/init0.go
deleted file mode 100644
index 6e8746a..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/init0.go
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// initialization cycles
-
-package init0
-
-// initialization cycles (we don't know the types)
-const (
-	s0 /* ERROR initialization cycle */ = s0
-
-	x0 /* ERROR initialization cycle */ = y0
-	y0 = x0
-
-	a0 = b0
-	b0 /* ERROR initialization cycle */ = c0
-	c0 = d0
-	d0 = b0
-)
-
-var (
-	s1 /* ERROR initialization cycle */ = s1
-
-	x1 /* ERROR initialization cycle */ = y1
-	y1 = x1
-
-	a1 = b1
-	b1 /* ERROR initialization cycle */ = c1
-	c1 = d1
-	d1 = b1
-)
-
-// initialization cycles (we know the types)
-const (
-	s2 /* ERROR initialization cycle */ int = s2
-
-	x2 /* ERROR initialization cycle */ int = y2
-	y2 = x2
-
-	a2 = b2
-	b2 /* ERROR initialization cycle */ int = c2
-	c2 = d2
-	d2 = b2
-)
-
-var (
-	s3 /* ERROR initialization cycle */ int = s3
-
-	x3 /* ERROR initialization cycle */ int = y3
-	y3 = x3
-
-	a3 = b3
-	b3 /* ERROR initialization cycle */ int = c3
-	c3 = d3
-	d3 = b3
-)
-
-// cycles via struct fields
-
-type S1 struct {
-	f int
-}
-const cx3 S1 /* ERROR invalid constant type */ = S1{cx3.f}
-var vx3 /* ERROR initialization cycle */ S1 = S1{vx3.f}
-
-// cycles via functions
-
-var x4 = x5
-var x5 /* ERROR initialization cycle */ = f1()
-func f1() int { return x5*10 }
-
-var x6, x7 /* ERROR initialization cycle */ = f2()
-var x8 = x7
-func f2() (int, int) { return f3() + f3(), 0 }
-func f3() int { return x8 }
-
-// cycles via function literals
-
-var x9 /* ERROR initialization cycle */ = func() int { return x9 }()
-
-var x10 /* ERROR initialization cycle */ = f4()
-
-func f4() int {
-	_ = func() {
-		_ = x10
-	}
-	return 0
-}
-
-// cycles via method expressions
-
-type T1 struct{}
-
-func (T1) m() bool { _ = x11; return false }
-
-var x11 /* ERROR initialization cycle */ = T1.m(T1{})
-
-// cycles via method values
-
-type T2 struct{}
-
-func (T2) m() bool { _ = x12; return false }
-
-var t1 T2
-var x12 /* ERROR initialization cycle */ = t1.m
diff --git a/src/cmd/compile/internal/types2/testdata/check/init1.go b/src/cmd/compile/internal/types2/testdata/check/init1.go
deleted file mode 100644
index 39ca314..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/init1.go
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// initialization cycles
-
-package init1
-
-// issue 6683 (marked as WorkingAsIntended)
-
-type T0 struct{}
-
-func (T0) m() int { return y0 }
-
-var x0 = T0{}
-
-var y0 /* ERROR initialization cycle */ = x0.m()
-
-type T1 struct{}
-
-func (T1) m() int { return y1 }
-
-var x1 interface {
-	m() int
-} = T1{}
-
-var y1 = x1.m() // no cycle reported, x1 is of interface type
-
-// issue 6703 (modified)
-
-var x2 /* ERROR initialization cycle */ = T2.m
-
-var y2 = x2
-
-type T2 struct{}
-
-func (T2) m() int {
-	_ = y2
-	return 0
-}
-
-var x3 /* ERROR initialization cycle */ = T3.m(T3{}) // <<<< added (T3{})
-
-var y3 = x3
-
-type T3 struct{}
-
-func (T3) m() int {
-	_ = y3
-	return 0
-}
-
-var x4 /* ERROR initialization cycle */ = T4{}.m // <<<< added {}
-
-var y4 = x4
-
-type T4 struct{}
-
-func (T4) m() int {
-	_ = y4
-	return 0
-}
-
-var x5 /* ERROR initialization cycle */ = T5{}.m() // <<<< added ()
-
-var y5 = x5
-
-type T5 struct{}
-
-func (T5) m() int {
-	_ = y5
-	return 0
-}
-
-// issue 4847
-// simplified test case
-
-var x6 = f6
-var y6 /* ERROR initialization cycle */ = f6
-func f6() { _ = y6 }
-
-// full test case
-
-type (
-      E int
-      S int
-)
-
-type matcher func(s *S) E
-
-func matchList(s *S) E { return matcher(matchAnyFn)(s) }
-
-var foo = matcher(matchList)
-
-var matchAny /* ERROR initialization cycle */ = matcher(matchList)
-
-func matchAnyFn(s *S) (err E) { return matchAny(s) }
\ No newline at end of file
diff --git a/src/cmd/compile/internal/types2/testdata/check/init2.go b/src/cmd/compile/internal/types2/testdata/check/init2.go
deleted file mode 100644
index 614db6c..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/init2.go
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// initialization cycles
-
-package init2
-
-// cycles through functions
-
-func f1() int { _ = x1; return 0 }
-var x1 /* ERROR initialization cycle */ = f1
-
-func f2() int { _ = x2; return 0 }
-var x2 /* ERROR initialization cycle */ = f2()
-
-// cycles through method expressions
-
-type T3 int
-func (T3) m() int { _ = x3; return 0 }
-var x3 /* ERROR initialization cycle */ = T3.m
-
-type T4 int
-func (T4) m() int { _ = x4; return 0 }
-var x4 /* ERROR initialization cycle */ = T4.m(0)
-
-type T3p int
-func (*T3p) m() int { _ = x3p; return 0 }
-var x3p /* ERROR initialization cycle */ = (*T3p).m
-
-type T4p int
-func (*T4p) m() int { _ = x4p; return 0 }
-var x4p /* ERROR initialization cycle */ = (*T4p).m(nil)
-
-// cycles through method expressions of embedded methods
-
-type T5 struct { E5 }
-type E5 int
-func (E5) m() int { _ = x5; return 0 }
-var x5 /* ERROR initialization cycle */ = T5.m
-
-type T6 struct { E6 }
-type E6 int
-func (E6) m() int { _ = x6; return 0 }
-var x6 /* ERROR initialization cycle */ = T6.m(T6{0})
-
-type T5p struct { E5p }
-type E5p int
-func (*E5p) m() int { _ = x5p; return 0 }
-var x5p /* ERROR initialization cycle */ = (*T5p).m
-
-type T6p struct { E6p }
-type E6p int
-func (*E6p) m() int { _ = x6p; return 0 }
-var x6p /* ERROR initialization cycle */ = (*T6p).m(nil)
-
-// cycles through method values
-
-type T7 int
-func (T7) m() int { _ = x7; return 0 }
-var x7 /* ERROR initialization cycle */ = T7(0).m
-
-type T8 int
-func (T8) m() int { _ = x8; return 0 }
-var x8 /* ERROR initialization cycle */ = T8(0).m()
-
-type T7p int
-func (*T7p) m() int { _ = x7p; return 0 }
-var x7p /* ERROR initialization cycle */ = new(T7p).m
-
-type T8p int
-func (*T8p) m() int { _ = x8p; return 0 }
-var x8p /* ERROR initialization cycle */ = new(T8p).m()
-
-type T7v int
-func (T7v) m() int { _ = x7v; return 0 }
-var x7var T7v
-var x7v /* ERROR initialization cycle */ = x7var.m
-
-type T8v int
-func (T8v) m() int { _ = x8v; return 0 }
-var x8var T8v
-var x8v /* ERROR initialization cycle */ = x8var.m()
-
-type T7pv int
-func (*T7pv) m() int { _ = x7pv; return 0 }
-var x7pvar *T7pv
-var x7pv /* ERROR initialization cycle */ = x7pvar.m
-
-type T8pv int
-func (*T8pv) m() int { _ = x8pv; return 0 }
-var x8pvar *T8pv
-var x8pv /* ERROR initialization cycle */ = x8pvar.m()
-
-// cycles through method values of embedded methods
-
-type T9 struct { E9 }
-type E9 int
-func (E9) m() int { _ = x9; return 0 }
-var x9 /* ERROR initialization cycle */ = T9{0}.m
-
-type T10 struct { E10 }
-type E10 int
-func (E10) m() int { _ = x10; return 0 }
-var x10 /* ERROR initialization cycle */ = T10{0}.m()
-
-type T9p struct { E9p }
-type E9p int
-func (*E9p) m() int { _ = x9p; return 0 }
-var x9p /* ERROR initialization cycle */ = new(T9p).m
-
-type T10p struct { E10p }
-type E10p int
-func (*E10p) m() int { _ = x10p; return 0 }
-var x10p /* ERROR initialization cycle */ = new(T10p).m()
-
-type T9v struct { E9v }
-type E9v int
-func (E9v) m() int { _ = x9v; return 0 }
-var x9var T9v
-var x9v /* ERROR initialization cycle */ = x9var.m
-
-type T10v struct { E10v }
-type E10v int
-func (E10v) m() int { _ = x10v; return 0 }
-var x10var T10v
-var x10v /* ERROR initialization cycle */ = x10var.m()
-
-type T9pv struct { E9pv }
-type E9pv int
-func (*E9pv) m() int { _ = x9pv; return 0 }
-var x9pvar *T9pv
-var x9pv /* ERROR initialization cycle */ = x9pvar.m
-
-type T10pv struct { E10pv }
-type E10pv int
-func (*E10pv) m() int { _ = x10pv; return 0 }
-var x10pvar *T10pv
-var x10pv /* ERROR initialization cycle */ = x10pvar.m()
diff --git a/src/cmd/compile/internal/types2/testdata/check/issue25008/issue25008a.go b/src/cmd/compile/internal/types2/testdata/check/issue25008/issue25008a.go
deleted file mode 100644
index cf71ca1..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/issue25008/issue25008a.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-import "io"
-
-type A interface {
-        io.Reader
-}
-
-func f(a A) {
-        a.Read(nil)
-}
diff --git a/src/cmd/compile/internal/types2/testdata/check/issue25008/issue25008b.go b/src/cmd/compile/internal/types2/testdata/check/issue25008/issue25008b.go
deleted file mode 100644
index f132b7f..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/issue25008/issue25008b.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type B interface {
-    A
-}
diff --git a/src/cmd/compile/internal/types2/testdata/check/issues0.go b/src/cmd/compile/internal/types2/testdata/check/issues0.go
deleted file mode 100644
index 4ac3fc2..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/issues0.go
+++ /dev/null
@@ -1,373 +0,0 @@
-// -lang=go1.17
-
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p // don't permit non-interface elements in interfaces
-
-import (
-	"fmt"
-	syn "regexp/syntax"
-	t1 "text/template"
-	t2 "html/template"
-)
-
-func issue7035() {
-	type T struct{ X int }
-	_ = func() {
-		fmt.Println() // must refer to imported fmt rather than the fmt below
-	}
-	fmt := new(T)
-	_ = fmt.X
-}
-
-func issue8066() {
-	const (
-		_ = float32(340282356779733661637539395458142568447)
-		_ = float32(340282356779733661637539395458142568448 /* ERROR cannot convert */ )
-	)
-}
-
-// Check that a missing identifier doesn't lead to a spurious error cascade.
-func issue8799a() {
-	x, ok := missing /* ERROR undeclared */ ()
-	_ = !ok
-	_ = x
-}
-
-func issue8799b(x int, ok bool) {
-	x, ok = missing /* ERROR undeclared */ ()
-	_ = !ok
-	_ = x
-}
-
-func issue9182() {
-	type Point C /* ERROR undeclared */ .Point
-	// no error for composite literal based on unknown type
-	_ = Point{x: 1, y: 2}
-}
-
-func f0() (a []int)         { return }
-func f1() (a []int, b int)  { return }
-func f2() (a, b []int)      { return }
-
-func append_([]int, ...int) {}
-
-func issue9473(a []int, b ...int) {
-	// variadic builtin function
-	_ = append(f0())
-	_ = append(f0(), f0()...)
-	_ = append(f1())
-	_ = append(f2 /* ERROR cannot use .* in argument */ ())
-	_ = append(f2()... /* ERROR cannot use ... */ )
-	_ = append(f0(), f1 /* ERROR 2-valued f1 */ ())
-	_ = append(f0(), f2 /* ERROR 2-valued f2 */ ())
-	_ = append(f0(), f1 /* ERROR 2-valued f1 */ ()...)
-	_ = append(f0(), f2 /* ERROR 2-valued f2 */ ()...)
-
-	// variadic user-defined function
-	append_(f0())
-	append_(f0(), f0()...)
-	append_(f1())
-	append_(f2 /* ERROR cannot use .* in argument */ ())
-	append_(f2()... /* ERROR cannot use ... */ )
-	append_(f0(), f1 /* ERROR 2-valued f1 */ ())
-	append_(f0(), f2 /* ERROR 2-valued f2 */ ())
-	append_(f0(), f1 /* ERROR 2-valued f1 */ ()...)
-	append_(f0(), f2 /* ERROR 2-valued f2 */ ()...)
-}
-
-// Check that embedding a non-interface type in an interface results in a good error message.
-func issue10979() {
-	type _ interface {
-		int /* ERROR non-interface type int */
-	}
-	type T struct{}
-	type _ interface {
-		T /* ERROR non-interface type T */
-	}
-	type _ interface {
-		nosuchtype /* ERROR undeclared name: nosuchtype */
-	}
-	type _ interface {
-		fmt.Nosuchtype /* ERROR Nosuchtype not declared by package fmt */
-	}
-	type _ interface {
-		nosuchpkg /* ERROR undeclared name: nosuchpkg */ .Nosuchtype
-	}
-	type I interface {
-		I.m /* ERROR no field or method m */
-		m()
-	}
-}
-
-// issue11347
-// These should not crash.
-var a1, b1 /* ERROR cycle */ , c1 /* ERROR cycle */ b1 = 0 > 0<<""[""[c1]]>c1
-var a2, b2 /* ERROR cycle */ = 0 /* ERROR cannot initialize */ /* ERROR cannot initialize */ > 0<<""[b2]
-var a3, b3 /* ERROR cycle */ = int /* ERROR cannot initialize */ /* ERROR cannot initialize */ (1<<""[b3])
-
-// issue10260
-// Check that error messages explain reason for interface assignment failures.
-type (
-	I0 interface{}
-	I1 interface{ foo() }
-	I2 interface{ foo(x int) }
-	T0 struct{}
-	T1 struct{}
-	T2 struct{}
-)
-
-func (*T1) foo() {}
-func (*T2) foo(x int) {}
-
-func issue10260() {
-	var (
-		i0 I0
-		i1 I1
-		i2 I2
-		t0 *T0
-		t1 *T1
-		t2 *T2
-	)
-
-	var x I1
-	x = T1 /* ERROR cannot use T1{} .* as I1 value in assignment: T1 does not implement I1 \(method foo has pointer receiver\) */ {}
-	_ = x /* ERROR impossible type assertion: x\.\(T1\)\n\tT1 does not implement I1 \(method foo has pointer receiver\) */ .(T1)
-
-	T1{}.foo /* ERROR cannot call pointer method foo on T1 */ ()
-	x.Foo /* ERROR "x.Foo undefined \(type I1 has no field or method Foo, but does have foo\)" */ ()
-
-	_ = i2 /* ERROR impossible type assertion: i2\.\(\*T1\)\n\t\*T1 does not implement I2 \(wrong type for method foo\)\n\t\thave foo\(\)\n\t\twant foo\(x int\) */ .(*T1)
-
-	i1 = i0 /* ERROR cannot use i0 .* as I1 value in assignment: I0 does not implement I1 \(missing method foo\) */
-	i1 = t0 /* ERROR .* t0 .* as I1 .*: \*T0 does not implement I1 \(missing method foo\) */
-	i1 = i2 /* ERROR .* i2 .* as I1 .*: I2 does not implement I1 \(wrong type for method foo\)\n\t\thave foo\(x int\)\n\t\twant foo\(\) */
-	i1 = t2 /* ERROR .* t2 .* as I1 .*: \*T2 does not implement I1 \(wrong type for method foo\)\n\t\thave foo\(x int\)\n\t\twant foo\(\) */
-	i2 = i1 /* ERROR .* i1 .* as I2 .*: I1 does not implement I2 \(wrong type for method foo\)\n\t\thave foo\(\)\n\t\twant foo\(x int\) */
-	i2 = t1 /* ERROR .* t1 .* as I2 .*: \*T1 does not implement I2 \(wrong type for method foo\)\n\t\thave foo\(\)\n\t\twant foo\(x int\) */
-
-	_ = func() I1 { return i0 /* ERROR cannot use i0 .* as I1 value in return statement: I0 does not implement I1 \(missing method foo\) */ }
-	_ = func() I1 { return t0 /* ERROR .* t0 .* as I1 .*: \*T0 does not implement I1 \(missing method foo\) */ }
-	_ = func() I1 { return i2 /* ERROR .* i2 .* as I1 .*: I2 does not implement I1 \(wrong type for method foo\)\n\t\thave foo\(x int\)\n\t\twant foo\(\) */ }
-	_ = func() I1 { return t2 /* ERROR .* t2 .* as I1 .*: \*T2 does not implement I1 \(wrong type for method foo\)\n\t\thave foo\(x int\)\n\t\twant foo\(\) */ }
-	_ = func() I2 { return i1 /* ERROR .* i1 .* as I2 .*: I1 does not implement I2 \(wrong type for method foo\)\n\t\thave foo\(\)\n\t\twant foo\(x int\) */ }
-	_ = func() I2 { return t1 /* ERROR .* t1 .* as I2 .*: \*T1 does not implement I2 \(wrong type for method foo\)\n\t\thave foo\(\)\n\t\twant foo\(x int\) */ }
-
-	// a few more - less exhaustive now
-
-	f := func(I1, I2){}
-	f(i0 /* ERROR missing method foo */ , i1 /* ERROR wrong type for method foo */ )
-
-	_ = [...]I1{i0 /* ERROR cannot use i0 .* as I1 value in array or slice literal: I0 does not implement I1 \(missing method foo\) */ }
-	_ = [...]I1{i2 /* ERROR cannot use i2 .* as I1 value in array or slice literal: I2 does not implement I1 \(wrong type for method foo\)\n\t\thave foo\(x int\)\n\t\twant foo\(\) */ }
-	_ = []I1{i0 /* ERROR missing method foo */ }
-	_ = []I1{i2 /* ERROR wrong type for method foo */ }
-	_ = map[int]I1{0: i0 /* ERROR missing method foo */ }
-	_ = map[int]I1{0: i2 /* ERROR wrong type for method foo */ }
-
-	make(chan I1) <- i0 /* ERROR missing method foo */
-	make(chan I1) <- i2 /* ERROR wrong type for method foo */
-}
-
-// Check that constants representable as integers are in integer form
-// before being used in operations that are only defined on integers.
-func issue14229() {
-	// from the issue
-	const _ = int64(-1<<63) % 1e6
-
-	// related
-	const (
-		a int = 3
-		b = 4.0
-		_ = a / b
-		_ = a % b
-		_ = b / a
-		_ = b % a
-	)
-}
-
-// Check that in a n:1 variable declaration with type and initialization
-// expression the type is distributed to all variables of the lhs before
-// the initialization expression assignment is checked.
-func issue15755() {
-	// from issue
-	var i interface{}
-	type b bool
-	var x, y b = i.(b)
-	_ = x == y
-
-	// related: we should see an error since the result of f1 is ([]int, int)
-	var u, v []int = f1 /* ERROR cannot use f1 */ ()
-	_ = u
-	_ = v
-}
-
-// Test that we don't get "declared but not used"
-// errors in the context of invalid/C objects.
-func issue20358() {
-	var F C /* ERROR "undeclared" */ .F
-	var A C /* ERROR "undeclared" */ .A
-	var S C /* ERROR "undeclared" */ .S
-	type T C /* ERROR "undeclared" */ .T
-	type P C /* ERROR "undeclared" */ .P
-
-	// these variables must be "used" even though
-	// the LHS expressions/types below in which
-	// context they are used are unknown/invalid
-	var f, a, s1, s2, s3, t, p int
-
-	_ = F(f)
-	_ = A[a]
-	_ = S[s1:s2:s3]
-	_ = T{t}
-	_ = P{f: p}
-}
-
-// Test that we don't declare lhs variables in short variable
-// declarations before we type-check function literals on the
-// rhs.
-func issue24026() {
-	f := func() int { f(0) /* must refer to outer f */; return 0 }
-	_ = f
-
-	_ = func() {
-		f := func() { _ = f() /* must refer to outer f */ }
-		_ = f
-	}
-
-	// b and c must not be visible inside function literal
-	a := 0
-	a, b, c := func() (int, int, int) {
-		return a, b /* ERROR undeclared */ , c /* ERROR undeclared */
-	}()
-	_, _ = b, c
-}
-
-func f(int) {} // for issue24026
-
-// Test that we don't report a "missing return statement" error
-// (due to incorrect context when type-checking interfaces).
-func issue24140(x interface{}) int {
-        switch x.(type) {
-        case interface{}:
-                return 0
-        default:
-                panic(0)
-        }
-}
-
-// Test that we don't crash when the 'if' condition is missing.
-func issue25438() {
-	if { /* ERROR missing condition */ }
-	if x := 0; /* ERROR missing condition */ { _ = x }
-	if
-	{ /* ERROR missing condition */ }
-}
-
-// Test that we can embed alias type names in interfaces.
-type issue25301 interface {
-	E
-}
-
-type E = interface {
-	m()
-}
-
-// Test case from issue.
-// cmd/compile reports a cycle as well.
-type issue25301b /* ERROR cycle */ = interface {
-	m() interface{ issue25301b }
-}
-
-type issue25301c interface {
-	notE // ERROR non-interface type struct\{\}
-}
-
-type notE = struct{}
-
-// Test that method declarations don't introduce artificial cycles
-// (issue #26124).
-const CC TT = 1
-type TT int
-func (TT) MM() [CC]TT
-
-// Reduced test case from issue #26124.
-const preloadLimit LNumber = 128
-type LNumber float64
-func (LNumber) assertFunction() *LFunction
-type LFunction struct {
-	GFunction LGFunction
-}
-type LGFunction func(*LState)
-type LState struct {
-	reg *registry
-}
-type registry struct {
-	alloc *allocator
-}
-type allocator struct {
-	_ [int(preloadLimit)]int
-}
-
-// Test that we don't crash when type-checking composite literals
-// containing errors in the type.
-var issue27346 = [][n /* ERROR undeclared */ ]int{
-	0: {},
-}
-
-var issue22467 = map[int][... /* ERROR invalid use of ... */ ]int{0: {}}
-
-// Test that invalid use of ... in parameter lists is recognized
-// (issue #28281).
-func issue28281a(int, int, ...int)
-func issue28281b(a, b int, c ...int)
-func issue28281c(a, b, c ... /* ERROR can only use ... with final parameter */ int)
-func issue28281d(... /* ERROR can only use ... with final parameter */ int, int)
-func issue28281e(a, b, c  ... /* ERROR can only use ... with final parameter */ int, d int)
-func issue28281f(... /* ERROR can only use ... with final parameter */ int, ... /* ERROR can only use ... with final parameter */ int, int)
-func (... /* ERROR can only use ... with final parameter in list */ TT) f()
-func issue28281g() (... /* ERROR can only use ... with final parameter in list */ TT)
-
-// Issue #26234: Make various field/method lookup errors easier to read by matching cmd/compile's output
-func issue26234a(f *syn.Prog) {
-	// The error message below should refer to the actual package name (syntax)
-	// not the local package name (syn).
-	f.foo /* ERROR f\.foo undefined \(type \*syntax\.Prog has no field or method foo\) */
-}
-
-type T struct {
-	x int
-	E1
-	E2
-}
-
-type E1 struct{ f int }
-type E2 struct{ f int }
-
-func issue26234b(x T) {
-	_ = x.f /* ERROR ambiguous selector x.f */
-}
-
-func issue26234c() {
-	T.x /* ERROR T.x undefined \(type T has no method x\) */ ()
-}
-
-func issue35895() {
-	// T is defined in this package, don't qualify its name with the package name.
-	var _ T = 0 // ERROR cannot use 0 \(untyped int constant\) as T
-
-	// There is only one package with name syntax imported, only use the (global) package name in error messages.
-	var _ *syn.Prog = 0 // ERROR cannot use 0 \(untyped int constant\) as \*syntax.Prog
-
-	// Because both t1 and t2 have the same global package name (template),
-	// qualify packages with full path name in this case.
-	var _ t1.Template = t2 /* ERROR cannot use .* \(value of type .html/template.\.Template\) as .text/template.\.Template */ .Template{}
-}
-
-func issue42989(s uint) {
-	var m map[int]string
-	delete(m, 1<<s)
-	delete(m, 1.<<s)
-}
diff --git a/src/cmd/compile/internal/types2/testdata/check/issues1.go b/src/cmd/compile/internal/types2/testdata/check/issues1.go
deleted file mode 100644
index 41a19ad..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/issues1.go
+++ /dev/null
@@ -1,250 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file contains regression tests for bugs found.
-
-package p
-
-import "io"
-import "context"
-
-func eql[T comparable](x, y T) bool {
-	return x == y
-}
-
-func _[X comparable, Y interface{comparable; m()}]() {
-	var x X
-	var y Y
-	eql(x, y /* ERROR does not match */ ) // interfaces of different types
-	eql(x, x)
-	eql(y, y)
-	eql(y, nil /* ERROR cannot use nil as Y value in argument to eql */ )
-	eql[io /* ERROR does not implement comparable */ .Reader](nil, nil)
-}
-
-// If we have a receiver of pointer to type parameter type (below: *T)
-// we don't have any methods, like for interfaces.
-type C[T any] interface {
-    m()
-}
-
-// using type bound C
-func _[T C[T]](x *T) {
-	x.m /* ERROR x\.m undefined */ ()
-}
-
-// using an interface literal as bound
-func _[T interface{ m() }](x *T) {
-	x.m /* ERROR x\.m undefined */ ()
-}
-
-func f2[_ interface{ m1(); m2() }]() {}
-
-type T struct{}
-func (T) m1()
-func (*T) m2()
-
-func _() {
-	f2[T /* ERROR m2 has pointer receiver */ ]()
-	f2[*T]()
-}
-
-// When a type parameter is used as an argument to instantiate a parameterized
-// type, the type argument's type set must be a subset of the instantiated type
-// parameter's type set.
-type T1[P interface{~uint}] struct{}
-
-func _[P any]() {
-    _ = T1[P /* ERROR P does not implement interface{~uint} */ ]{}
-}
-
-// This is the original (simplified) program causing the same issue.
-type Unsigned interface {
-	~uint
-}
-
-type T2[U Unsigned] struct {
-    s U
-}
-
-func (u T2[U]) Add1() U {
-    return u.s + 1
-}
-
-func NewT2[U any]() T2[U /* ERROR U does not implement Unsigned */ ] {
-    return T2[U /* ERROR U does not implement Unsigned */ ]{}
-}
-
-func _() {
-    u := NewT2[string]()
-    _ = u.Add1()
-}
-
-// When we encounter an instantiated type such as Elem[T] we must
-// not "expand" the instantiation when the type to be instantiated
-// (Elem in this case) is not yet fully set up.
-type Elem[T any] struct {
-	next *Elem[T]
-	list *List[T]
-}
-
-type List[T any] struct {
-	root Elem[T]
-}
-
-func (l *List[T]) Init() {
-	l.root.next = &l.root
-}
-
-// This is the original program causing the same issue.
-type Element2[TElem any] struct {
-	next, prev *Element2[TElem]
-	list *List2[TElem]
-	Value TElem
-}
-
-type List2[TElem any] struct {
-	root Element2[TElem]
-	len  int
-}
-
-func (l *List2[TElem]) Init() *List2[TElem] {
-	l.root.next = &l.root
-	l.root.prev = &l.root
-	l.len = 0
-	return l
-}
-
-// Self-recursive instantiations must work correctly.
-type A[P any] struct { _ *A[P] }
-
-type AB[P any] struct { _ *BA[P] }
-type BA[P any] struct { _ *AB[P] }
-
-// And a variation that also caused a problem with an
-// unresolved underlying type.
-type Element3[TElem any] struct {
-	next, prev *Element3[TElem]
-	list *List3[TElem]
-	Value TElem
-}
-
-func (e *Element3[TElem]) Next() *Element3[TElem] {
-	if p := e.next; e.list != nil && p != &e.list.root {
-		return p
-	}
-	return nil
-}
-
-type List3[TElem any] struct {
-	root Element3[TElem]
-	len  int
-}
-
-// Infinite generic type declarations must lead to an error.
-type inf1[T any] struct{ _ inf1 /* ERROR illegal cycle */ [T] }
-type inf2[T any] struct{ inf2 /* ERROR illegal cycle */ [T] }
-
-// The implementation of conversions T(x) between integers and floating-point
-// numbers checks that both T and x have either integer or floating-point
-// type. When the type of T or x is a type parameter, the respective simple
-// predicate disjunction in the implementation was wrong because if a type set
-// contains both an integer and a floating-point type, the type parameter is
-// neither an integer or a floating-point number.
-func convert[T1, T2 interface{~int | ~uint | ~float32}](v T1) T2 {
-	return T2(v)
-}
-
-func _() {
-	convert[int, uint](5)
-}
-
-// When testing binary operators, for +, the operand types must either be
-// both numeric, or both strings. The implementation had the same problem
-// with this check as the conversion issue above (issue #39623).
-
-func issue39623[T interface{~int | ~string}](x, y T) T {
-	return x + y
-}
-
-// Simplified, from https://go2goplay.golang.org/p/efS6x6s-9NI:
-func Sum[T interface{~int | ~string}](s []T) (sum T) {
-	for _, v := range s {
-		sum += v
-	}
-	return
-}
-
-// Assignability of an unnamed pointer type to a type parameter that
-// has a matching underlying type.
-func _[T interface{}, PT interface{~*T}] (x T) PT {
-    return &x
-}
-
-// Indexing of type parameters containing type parameters in their constraint terms:
-func at[T interface{ ~[]E }, E interface{}](x T, i int) E {
-        return x[i]
-}
-
-// Conversion of a local type to a type parameter.
-func _[T interface{~int}](x T) {
-	type myint int
-	var _ int = int(x)
-	var _ T = 42
-	var _ T = T(myint(42))
-}
-
-// Indexing a type parameter with an array type bound checks length.
-// (Example by mdempsky@.)
-func _[T interface { ~[10]int }](x T) {
-	_ = x[9] // ok
-	_ = x[20 /* ERROR out of bounds */ ]
-}
-
-// Pointer indirection of a type parameter.
-func _[T interface{ ~*int }](p T) int {
-	return *p
-}
-
-// Channel sends and receives on type parameters.
-func _[T interface{ ~chan int }](ch T) int {
-	ch <- 0
-	return <- ch
-}
-
-// Calling of a generic variable.
-func _[T interface{ ~func() }](f T) {
-	f()
-	go f()
-}
-
-type F1 func()
-type F2 func()
-func _[T interface{ func()|F1|F2 }](f T) {
-	f()
-	go f()
-}
-
-// We must compare against the (possibly underlying) types of term list
-// elements when checking if a constraint is satisfied by a type.
-// The underlying type of each term must be computed after the
-// interface has been instantiated as its constraint may contain
-// a type parameter that was substituted with a defined type.
-// Test case from an (originally) failing example.
-
-type sliceOf[E any] interface{ ~[]E }
-
-func append[T interface{}, S sliceOf[T], T2 interface{}](s S, t ...T2) S { panic(0) }
-
-var f           func()
-var cancelSlice []context.CancelFunc
-var _ = append[context.CancelFunc, []context.CancelFunc, context.CancelFunc](cancelSlice, f)
-
-// A generic function must be instantiated with a type, not a value.
-
-func g[T any](T) T { panic(0) }
-
-var _ = g[int]
-var _ = g[nil /* ERROR is not a type */ ]
-var _ = g(0)
diff --git a/src/cmd/compile/internal/types2/testdata/check/labels.go b/src/cmd/compile/internal/types2/testdata/check/labels.go
deleted file mode 100644
index 9f42406..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/labels.go
+++ /dev/null
@@ -1,207 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file is a modified concatenation of the files
-// $GOROOT/test/label.go and $GOROOT/test/label1.go.
-
-package labels
-
-var x int
-
-func f0() {
-L1 /* ERROR "label L1 declared but not used" */ :
-	for {
-	}
-L2 /* ERROR "label L2 declared but not used" */ :
-	select {
-	}
-L3 /* ERROR "label L3 declared but not used" */ :
-	switch {
-	}
-L4 /* ERROR "label L4 declared but not used" */ :
-	if true {
-	}
-L5 /* ERROR "label L5 declared but not used" */ :
-	f0()
-L6:
-	f0()
-L6 /* ERROR "label L6 already declared" */ :
-	f0()
-	if x == 20 {
-		goto L6
-	}
-
-L7:
-	for {
-		break L7
-		break L8 /* ERROR "invalid break label L8" */
-	}
-
-// A label must be directly associated with a switch, select, or
-// for statement; it cannot be the label of a labeled statement.
-
-L7a /* ERROR "declared but not used" */ : L7b:
-	for {
-		break L7a /* ERROR "invalid break label L7a" */
-		continue L7a /* ERROR "invalid continue label L7a" */
-		continue L7b
-	}
-
-L8:
-	for {
-		if x == 21 {
-			continue L8
-			continue L7 /* ERROR "invalid continue label L7" */
-		}
-	}
-
-L9:
-	switch {
-	case true:
-		break L9
-	defalt /* ERROR "label defalt declared but not used" */ :
-	}
-
-L10:
-	select {
-	default:
-		break L10
-		break L9 /* ERROR "invalid break label L9" */
-	}
-
-	goto L10a
-L10a: L10b:
-	select {
-	default:
-		break L10a /* ERROR "invalid break label L10a" */
-		break L10b
-		continue L10b /* ERROR "invalid continue label L10b" */
-	}
-}
-
-func f1() {
-L1:
-	for {
-		if x == 0 {
-			break L1
-		}
-		if x == 1 {
-			continue L1
-		}
-		goto L1
-	}
-
-L2:
-	select {
-	default:
-		if x == 0 {
-			break L2
-		}
-		if x == 1 {
-			continue L2 /* ERROR "invalid continue label L2" */
-		}
-		goto L2
-	}
-
-L3:
-	switch {
-	case x > 10:
-		if x == 11 {
-			break L3
-		}
-		if x == 12 {
-			continue L3 /* ERROR "invalid continue label L3" */
-		}
-		goto L3
-	}
-
-L4:
-	if true {
-		if x == 13 {
-			break L4 /* ERROR "invalid break label L4" */
-		}
-		if x == 14 {
-			continue L4 /* ERROR "invalid continue label L4" */
-		}
-		if x == 15 {
-			goto L4
-		}
-	}
-
-L5:
-	f1()
-	if x == 16 {
-		break L5 /* ERROR "invalid break label L5" */
-	}
-	if x == 17 {
-		continue L5 /* ERROR "invalid continue label L5" */
-	}
-	if x == 18 {
-		goto L5
-	}
-
-	for {
-		if x == 19 {
-			break L1 /* ERROR "invalid break label L1" */
-		}
-		if x == 20 {
-			continue L1 /* ERROR "invalid continue label L1" */
-		}
-		if x == 21 {
-			goto L1
-		}
-	}
-}
-
-// Additional tests not in the original files.
-
-func f2() {
-L1 /* ERROR "label L1 declared but not used" */ :
-	if x == 0 {
-		for {
-			continue L1 /* ERROR "invalid continue label L1" */
-		}
-	}
-}
-
-func f3() {
-L1:
-L2:
-L3:
-	for {
-		break L1 /* ERROR "invalid break label L1" */
-		break L2 /* ERROR "invalid break label L2" */
-		break L3
-		continue L1 /* ERROR "invalid continue label L1" */
-		continue L2 /* ERROR "invalid continue label L2" */
-		continue L3
-		goto L1
-		goto L2
-		goto L3
-	}
-}
-
-// Blank labels are never declared.
-
-func f4() {
-_:
-_: // multiple blank labels are ok
-	goto _ /* ERROR "label _ not declared" */
-}
-
-func f5() {
-_:
-	for {
-		break _ /* ERROR "invalid break label _" */
-		continue _ /* ERROR "invalid continue label _" */
-	}
-}
-
-func f6() {
-_:
-	switch {
-	default:
-		break _ /* ERROR "invalid break label _" */
-	}
-}
diff --git a/src/cmd/compile/internal/types2/testdata/check/linalg.go b/src/cmd/compile/internal/types2/testdata/check/linalg.go
deleted file mode 100644
index f02e773..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/linalg.go
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package linalg
-
-// Numeric is type bound that matches any numeric type.
-// It would likely be in a constraints package in the standard library.
-type Numeric interface {
-	~int | ~int8 | ~int16 | ~int32 | ~int64 |
-		~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
-		~float32 | ~float64 |
-		~complex64 | ~complex128
-}
-
-func DotProduct[T Numeric](s1, s2 []T) T {
-	if len(s1) != len(s2) {
-		panic("DotProduct: slices of unequal length")
-	}
-	var r T
-	for i := range s1 {
-		r += s1[i] * s2[i]
-	}
-	return r
-}
-
-// NumericAbs matches numeric types with an Abs method.
-type NumericAbs[T any] interface {
-	Numeric
-
-	Abs() T
-}
-
-// AbsDifference computes the absolute value of the difference of
-// a and b, where the absolute value is determined by the Abs method.
-func AbsDifference[T NumericAbs[T]](a, b T) T {
-	d := a - b
-	return d.Abs()
-}
-
-// OrderedNumeric is a type bound that matches numeric types that support the < operator.
-type OrderedNumeric interface {
-	~int | ~int8 | ~int16 | ~int32 | ~int64 |
-		~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
-		~float32 | ~float64
-}
-
-// Complex is a type bound that matches the two complex types, which do not have a < operator.
-type Complex interface {
-	~complex64 | ~complex128
-}
-
-// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
-// // OrderedAbs is a helper type that defines an Abs method for
-// // ordered numeric types.
-// type OrderedAbs[T OrderedNumeric] T
-// 
-// func (a OrderedAbs[T]) Abs() OrderedAbs[T] {
-// 	if a < 0 {
-// 		return -a
-// 	}
-// 	return a
-// }
-// 
-// // ComplexAbs is a helper type that defines an Abs method for
-// // complex types.
-// type ComplexAbs[T Complex] T
-// 
-// func (a ComplexAbs[T]) Abs() ComplexAbs[T] {
-// 	r := float64(real(a))
-// 	i := float64(imag(a))
-// 	d := math.Sqrt(r * r + i * i)
-// 	return ComplexAbs[T](complex(d, 0))
-// }
-// 
-// func OrderedAbsDifference[T OrderedNumeric](a, b T) T {
-// 	return T(AbsDifference(OrderedAbs[T](a), OrderedAbs[T](b)))
-// }
-// 
-// func ComplexAbsDifference[T Complex](a, b T) T {
-// 	return T(AbsDifference(ComplexAbs[T](a), ComplexAbs[T](b)))
-// }
diff --git a/src/cmd/compile/internal/types2/testdata/check/literals.go b/src/cmd/compile/internal/types2/testdata/check/literals.go
deleted file mode 100644
index 494a465..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/literals.go
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file tests various representations of literals
-// and compares them with literals or constant expressions
-// of equal values.
-
-package literals
-
-func _() {
-	// 0-octals
-	assert(0_123 == 0123)
-	assert(0123_456 == 0123456)
-
-	// decimals
-	assert(1_234 == 1234)
-	assert(1_234_567 == 1234567)
-
-	// hexadecimals
-	assert(0X_0 == 0)
-	assert(0X_1234 == 0x1234)
-	assert(0X_CAFE_f00d == 0xcafef00d)
-
-	// octals
-	assert(0o0 == 0)
-	assert(0o1234 == 01234)
-	assert(0o01234567 == 01234567)
-
-	assert(0O0 == 0)
-	assert(0O1234 == 01234)
-	assert(0O01234567 == 01234567)
-
-	assert(0o_0 == 0)
-	assert(0o_1234 == 01234)
-	assert(0o0123_4567 == 01234567)
-
-	assert(0O_0 == 0)
-	assert(0O_1234 == 01234)
-	assert(0O0123_4567 == 01234567)
-
-	// binaries
-	assert(0b0 == 0)
-	assert(0b1011 == 0xb)
-	assert(0b00101101 == 0x2d)
-
-	assert(0B0 == 0)
-	assert(0B1011 == 0xb)
-	assert(0B00101101 == 0x2d)
-
-	assert(0b_0 == 0)
-	assert(0b10_11 == 0xb)
-	assert(0b_0010_1101 == 0x2d)
-
-	// decimal floats
-	assert(1_2_3. == 123.)
-	assert(0_123. == 123.)
-
-	assert(0_0e0 == 0.)
-	assert(1_2_3e0 == 123.)
-	assert(0_123e0 == 123.)
-
-	assert(0e-0_0 == 0.)
-	assert(1_2_3E+0 == 123.)
-	assert(0123E1_2_3 == 123e123)
-
-	assert(0.e+1 == 0.)
-	assert(123.E-1_0 == 123e-10)
-	assert(01_23.e123 == 123e123)
-
-	assert(.0e-1 == .0)
-	assert(.123E+10 == .123e10)
-	assert(.0123E123 == .0123e123)
-
-	assert(1_2_3.123 == 123.123)
-	assert(0123.01_23 == 123.0123)
-
-	// hexadecimal floats
-	assert(0x0.p+0 == 0.)
-	assert(0Xdeadcafe.p-10 == 0xdeadcafe/1024.0)
-	assert(0x1234.P84 == 0x1234000000000000000000000)
-
-	assert(0x.1p-0 == 1./16)
-	assert(0X.deadcafep4 == 1.0*0xdeadcafe/0x10000000)
-	assert(0x.1234P+12 == 1.0*0x1234/0x10)
-
-	assert(0x0p0 == 0.)
-	assert(0Xdeadcafep+1 == 0x1bd5b95fc)
-	assert(0x1234P-10 == 0x1234/1024.0)
-
-	assert(0x0.0p0 == 0.)
-	assert(0Xdead.cafep+1 == 1.0*0x1bd5b95fc/0x10000)
-	assert(0x12.34P-10 == 1.0*0x1234/0x40000)
-
-	assert(0Xdead_cafep+1 == 0xdeadcafep+1)
-	assert(0x_1234P-10 == 0x1234p-10)
-
-	assert(0X_dead_cafe.p-10 == 0xdeadcafe.p-10)
-	assert(0x12_34.P1_2_3 == 0x1234.p123)
-
-	assert(1_234i == 1234i)
-	assert(1_234_567i == 1234567i)
-
-	assert(0.i == 0i)
-	assert(123.i == 123i)
-	assert(0123.i == 123i)
-
-	assert(0.e+1i == 0i)
-	assert(123.E-1_0i == 123e-10i)
-	assert(01_23.e123i == 123e123i)
-}
diff --git a/src/cmd/compile/internal/types2/testdata/check/main0.go b/src/cmd/compile/internal/types2/testdata/check/main0.go
deleted file mode 100644
index f892938..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/main0.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-func main()
-func /* ERROR "no arguments and no return values" */ main /* ERROR redeclared */ (int)
-func /* ERROR "no arguments and no return values" */ main /* ERROR redeclared */ () int
diff --git a/src/cmd/compile/internal/types2/testdata/check/main1.go b/src/cmd/compile/internal/types2/testdata/check/main1.go
deleted file mode 100644
index 395e3bf..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/main1.go
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-func main [T /* ERROR "func main must have no type parameters" */ any]() {}
diff --git a/src/cmd/compile/internal/types2/testdata/check/map0.go b/src/cmd/compile/internal/types2/testdata/check/map0.go
deleted file mode 100644
index 814d953..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/map0.go
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package orderedmap provides an ordered map, implemented as a binary tree.
-package orderedmap
-
-// TODO(gri) fix imports for tests
-import "chans" // ERROR could not import
-
-// Map is an ordered map.
-type Map[K, V any] struct {
-	root    *node[K, V]
-	compare func(K, K) int
-}
-
-// node is the type of a node in the binary tree.
-type node[K, V any] struct {
-	key         K
-	val         V
-	left, right *node[K, V]
-}
-
-// New returns a new map.
-func New[K, V any](compare func(K, K) int) *Map[K, V] {
-        return &Map[K, V]{compare: compare}
-}
-
-// find looks up key in the map, and returns either a pointer
-// to the node holding key, or a pointer to the location where
-// such a node would go.
-func (m *Map[K, V]) find(key K) **node[K, V] {
-	pn := &m.root
-	for *pn != nil {
-		switch cmp := m.compare(key, (*pn).key); {
-		case cmp < 0:
-			pn = &(*pn).left
-		case cmp > 0:
-			pn = &(*pn).right
-		default:
-			return pn
-		}
-	}
-	return pn
-}
-
-// Insert inserts a new key/value into the map.
-// If the key is already present, the value is replaced.
-// Returns true if this is a new key, false if already present.
-func (m *Map[K, V]) Insert(key K, val V) bool {
-	pn := m.find(key)
-	if *pn != nil {
-		(*pn).val = val
-		return false
-	}
-        *pn = &node[K, V]{key: key, val: val}
-	return true
-}
-
-// Find returns the value associated with a key, or zero if not present.
-// The found result reports whether the key was found.
-func (m *Map[K, V]) Find(key K) (V, bool) {
-	pn := m.find(key)
-	if *pn == nil {
-		var zero V // see the discussion of zero values, above
-		return zero, false
-	}
-	return (*pn).val, true
-}
-
-// keyValue is a pair of key and value used when iterating.
-type keyValue[K, V any] struct {
-	key K
-	val V
-}
-
-// InOrder returns an iterator that does an in-order traversal of the map.
-func (m *Map[K, V]) InOrder() *Iterator[K, V] {
-	sender, receiver := chans.Ranger[keyValue[K, V]]()
-	var f func(*node[K, V]) bool
-	f = func(n *node[K, V]) bool {
-		if n == nil {
-			return true
-		}
-		// Stop sending values if sender.Send returns false,
-		// meaning that nothing is listening at the receiver end.
-		return f(n.left) &&
-                        sender.Send(keyValue[K, V]{n.key, n.val}) &&
-			f(n.right)
-	}
-	go func() {
-		f(m.root)
-		sender.Close()
-	}()
-	return &Iterator[K, V]{receiver}
-}
-
-// Iterator is used to iterate over the map.
-type Iterator[K, V any] struct {
-	r *chans.Receiver[keyValue[K, V]]
-}
-
-// Next returns the next key and value pair, and a boolean indicating
-// whether they are valid or whether we have reached the end.
-func (it *Iterator[K, V]) Next() (K, V, bool) {
-	keyval, ok := it.r.Next()
-	if !ok {
-		var zerok K
-		var zerov V
-		return zerok, zerov, false
-	}
-	return keyval.key, keyval.val, true
-}
diff --git a/src/cmd/compile/internal/types2/testdata/check/map1.go b/src/cmd/compile/internal/types2/testdata/check/map1.go
deleted file mode 100644
index be2c49f..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/map1.go
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file is like map.go2, but instead if importing chans, it contains
-// the necessary functionality at the end of the file.
-
-// Package orderedmap provides an ordered map, implemented as a binary tree.
-package orderedmap
-
-// Map is an ordered map.
-type Map[K, V any] struct {
-	root    *node[K, V]
-	compare func(K, K) int
-}
-
-// node is the type of a node in the binary tree.
-type node[K, V any] struct {
-	key         K
-	val         V
-	left, right *node[K, V]
-}
-
-// New returns a new map.
-func New[K, V any](compare func(K, K) int) *Map[K, V] {
-        return &Map[K, V]{compare: compare}
-}
-
-// find looks up key in the map, and returns either a pointer
-// to the node holding key, or a pointer to the location where
-// such a node would go.
-func (m *Map[K, V]) find(key K) **node[K, V] {
-	pn := &m.root
-	for *pn != nil {
-		switch cmp := m.compare(key, (*pn).key); {
-		case cmp < 0:
-			pn = &(*pn).left
-		case cmp > 0:
-			pn = &(*pn).right
-		default:
-			return pn
-		}
-	}
-	return pn
-}
-
-// Insert inserts a new key/value into the map.
-// If the key is already present, the value is replaced.
-// Returns true if this is a new key, false if already present.
-func (m *Map[K, V]) Insert(key K, val V) bool {
-	pn := m.find(key)
-	if *pn != nil {
-		(*pn).val = val
-		return false
-	}
-	*pn = &node[K, V]{key: key, val: val}
-	return true
-}
-
-// Find returns the value associated with a key, or zero if not present.
-// The found result reports whether the key was found.
-func (m *Map[K, V]) Find(key K) (V, bool) {
-	pn := m.find(key)
-	if *pn == nil {
-		var zero V // see the discussion of zero values, above
-		return zero, false
-	}
-	return (*pn).val, true
-}
-
-// keyValue is a pair of key and value used when iterating.
-type keyValue[K, V any] struct {
-	key K
-	val V
-}
-
-// InOrder returns an iterator that does an in-order traversal of the map.
-func (m *Map[K, V]) InOrder() *Iterator[K, V] {
-	sender, receiver := chans_Ranger[keyValue[K, V]]()
-	var f func(*node[K, V]) bool
-	f = func(n *node[K, V]) bool {
-		if n == nil {
-			return true
-		}
-		// Stop sending values if sender.Send returns false,
-		// meaning that nothing is listening at the receiver end.
-		return f(n.left) &&
-                        sender.Send(keyValue[K, V]{n.key, n.val}) &&
-			f(n.right)
-	}
-	go func() {
-		f(m.root)
-		sender.Close()
-	}()
-	return &Iterator[K, V]{receiver}
-}
-
-// Iterator is used to iterate over the map.
-type Iterator[K, V any] struct {
-	r *chans_Receiver[keyValue[K, V]]
-}
-
-// Next returns the next key and value pair, and a boolean indicating
-// whether they are valid or whether we have reached the end.
-func (it *Iterator[K, V]) Next() (K, V, bool) {
-	keyval, ok := it.r.Next()
-	if !ok {
-		var zerok K
-		var zerov V
-		return zerok, zerov, false
-	}
-	return keyval.key, keyval.val, true
-}
-
-// chans
-
-func chans_Ranger[T any]() (*chans_Sender[T], *chans_Receiver[T]) { panic(0) }
-
-// A sender is used to send values to a Receiver.
-type chans_Sender[T any] struct {
-	values chan<- T
-	done <-chan bool
-}
-
-func (s *chans_Sender[T]) Send(v T) bool {
-	select {
-	case s.values <- v:
-		return true
-	case <-s.done:
-		return false
-	}
-}
-
-func (s *chans_Sender[T]) Close() {
-	close(s.values)
-}
-
-type chans_Receiver[T any] struct {
-	values <-chan T
-	done chan<- bool
-}
-
-func (r *chans_Receiver[T]) Next() (T, bool) {
-	v, ok := <-r.values
-	return v, ok
-}
\ No newline at end of file
diff --git a/src/cmd/compile/internal/types2/testdata/check/methodsets.go b/src/cmd/compile/internal/types2/testdata/check/methodsets.go
deleted file mode 100644
index b0eb14c..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/methodsets.go
+++ /dev/null
@@ -1,214 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package methodsets
-
-type T0 struct {}
-
-func (T0) v0() {}
-func (*T0) p0() {}
-
-type T1 struct {} // like T0 with different method names
-
-func (T1) v1() {}
-func (*T1) p1() {}
-
-type T2 interface {
-	v2()
-	p2()
-}
-
-type T3 struct {
-	T0
-	*T1
-	T2
-}
-
-// Method expressions
-func _() {
-	var (
-		_ func(T0) = T0.v0
-		_ = T0.p0 /* ERROR "cannot call pointer method p0 on T0" */
-
-		_ func (*T0) = (*T0).v0
-		_ func (*T0) = (*T0).p0
-
-		// T1 is like T0
-
-		_ func(T2) = T2.v2
-		_ func(T2) = T2.p2
-
-		_ func(T3) = T3.v0
-		_ func(T3) = T3.p0 /* ERROR "cannot call pointer method p0 on T3" */
-		_ func(T3) = T3.v1
-		_ func(T3) = T3.p1
-		_ func(T3) = T3.v2
-		_ func(T3) = T3.p2
-
-		_ func(*T3) = (*T3).v0
-		_ func(*T3) = (*T3).p0
-		_ func(*T3) = (*T3).v1
-		_ func(*T3) = (*T3).p1
-		_ func(*T3) = (*T3).v2
-		_ func(*T3) = (*T3).p2
-	)
-}
-
-// Method values with addressable receivers
-func _() {
-	var (
-		v0 T0
-		_ func() = v0.v0
-		_ func() = v0.p0
-	)
-
-	var (
-		p0 *T0
-		_ func() = p0.v0
-		_ func() = p0.p0
-	)
-
-	// T1 is like T0
-
-	var (
-		v2 T2
-		_ func() = v2.v2
-		_ func() = v2.p2
-	)
-
-	var (
-		v4 T3
-		_ func() = v4.v0
-		_ func() = v4.p0
-		_ func() = v4.v1
-		_ func() = v4.p1
-		_ func() = v4.v2
-		_ func() = v4.p2
-	)
-
-	var (
-		p4 *T3
-		_ func() = p4.v0
-		_ func() = p4.p0
-		_ func() = p4.v1
-		_ func() = p4.p1
-		_ func() = p4.v2
-		_ func() = p4.p2
-	)
-}
-
-// Method calls with addressable receivers
-func _() {
-	var v0 T0
-	v0.v0()
-	v0.p0()
-
-	var p0 *T0
-	p0.v0()
-	p0.p0()
-
-	// T1 is like T0
-
-	var v2 T2
-	v2.v2()
-	v2.p2()
-
-	var v4 T3
-	v4.v0()
-	v4.p0()
-	v4.v1()
-	v4.p1()
-	v4.v2()
-	v4.p2()
-
-	var p4 *T3
-	p4.v0()
-	p4.p0()
-	p4.v1()
-	p4.p1()
-	p4.v2()
-	p4.p2()
-}
-
-// Method values with value receivers
-func _() {
-	var (
-		_ func() = T0{}.v0
-		_ func() = T0{}.p0 /* ERROR "cannot call pointer method p0 on T0" */
-
-		_ func() = (&T0{}).v0
-		_ func() = (&T0{}).p0
-
-		// T1 is like T0
-
-		// no values for T2
-
-		_ func() = T3{}.v0
-		_ func() = T3{}.p0 /* ERROR "cannot call pointer method p0 on T3" */
-		_ func() = T3{}.v1
-		_ func() = T3{}.p1
-		_ func() = T3{}.v2
-		_ func() = T3{}.p2
-
-		_ func() = (&T3{}).v0
-		_ func() = (&T3{}).p0
-		_ func() = (&T3{}).v1
-		_ func() = (&T3{}).p1
-		_ func() = (&T3{}).v2
-		_ func() = (&T3{}).p2
-	)
-}
-
-// Method calls with value receivers
-func _() {
-	T0{}.v0()
-	T0{}.p0 /* ERROR "cannot call pointer method p0 on T0" */ ()
-
-	(&T0{}).v0()
-	(&T0{}).p0()
-
-	// T1 is like T0
-
-	// no values for T2
-
-	T3{}.v0()
-	T3{}.p0 /* ERROR "cannot call pointer method p0 on T3" */ ()
-	T3{}.v1()
-	T3{}.p1()
-	T3{}.v2()
-	T3{}.p2()
-
-	(&T3{}).v0()
-	(&T3{}).p0()
-	(&T3{}).v1()
-	(&T3{}).p1()
-	(&T3{}).v2()
-	(&T3{}).p2()
-}
-
-// *T has no methods if T is an interface type
-func issue5918() {
-	var (
-		err error
-		_ = err.Error()
-		_ func() string = err.Error
-		_ func(error) string = error.Error
-
-		perr = &err
-		_ = perr.Error /* ERROR "type \*error is pointer to interface, not interface" */ ()
-		_ func() string = perr.Error /* ERROR "type \*error is pointer to interface, not interface" */
-		_ func(*error) string = (*error).Error /* ERROR "type \*error is pointer to interface, not interface" */
-	)
-
-	type T *interface{ m() int }
-	var (
-		x T
-		_ = (*x).m()
-		_ = (*x).m
-
-		_ = x.m /* ERROR "type T is pointer to interface, not interface" */ ()
-		_ = x.m /* ERROR "type T is pointer to interface, not interface" */
-		_ = T.m /* ERROR "type T is pointer to interface, not interface" */
-	)
-}
diff --git a/src/cmd/compile/internal/types2/testdata/check/shifts.go b/src/cmd/compile/internal/types2/testdata/check/shifts.go
deleted file mode 100644
index 37bc84c..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/shifts.go
+++ /dev/null
@@ -1,398 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package shifts
-
-func shifts0() {
-	// basic constant shifts
-	const (
-		s = 10
-		_ = 0<<0
-		_ = 1<<s
-		_ = 1<<- /* ERROR "negative shift count" */ 1
-		// For the test below we may decide to convert to int
-		// rather than uint and then report a negative shift
-		// count instead, which might be a better error. The
-		// (minor) difference is that this would restrict the
-		// shift count range by half (from all uint values to
-		// the positive int values).
-		// This depends on the exact spec wording which is not
-		// done yet.
-		// TODO(gri) revisit and adjust when spec change is done
-		_ = 1<<- /* ERROR "negative shift count" */ 1.0
-		_ = 1<<1075 /* ERROR "invalid shift" */
-		_ = 2.0<<1
-		_ = 1<<1.0
-		_ = 1<<(1+0i)
-
-		_ int = 2<<s
-		_ float32 = 2<<s
-		_ complex64 = 2<<s
-
-		_ int = 2.0<<s
-		_ float32 = 2.0<<s
-		_ complex64 = 2.0<<s
-
-		_ int = 'a'<<s
-		_ float32 = 'a'<<s
-		_ complex64 = 'a'<<s
-	)
-}
-
-func shifts1() {
-	// basic non-constant shifts
-	var (
-		i int
-		u uint
-
-		_ = 1<<0
-		_ = 1<<i
-		_ = 1<<u
-		_ = 1<<"foo" /* ERROR "cannot convert" */
-		_ = i<<0
-		_ = i<<- /* ERROR "negative shift count" */ 1
-		_ = i<<1.0
-		_ = 1<<(1+0i)
-		_ = 1 /* ERROR "overflows" */ <<100
-
-		_ uint = 1 << 0
-		_ uint = 1 << u
-		_ float32 = 1 /* ERROR "must be integer" */ << u
-
-		// issue #14822
-		_ = 1<<( /* ERROR "overflows uint" */ 1<<64)
-		_ = 1<<( /* ERROR "invalid shift count" */ 1<<64-1)
-
-		// issue #43697
-		_ = u<<( /* ERROR "overflows uint" */ 1<<64)
-		_ = u<<(1<<64-1)
-	)
-}
-
-func shifts2() {
-	// from the spec
-	var (
-		s uint = 33
-		i = 1<<s           // 1 has type int
-		j int32 = 1<<s     // 1 has type int32; j == 0
-		k = uint64(1<<s)   // 1 has type uint64; k == 1<<33
-		m int = 1.0<<s     // 1.0 has type int
-		n = 1.0<<s != i    // 1.0 has type int; n == false if ints are 32bits in size
-		o = 1<<s == 2<<s   // 1 and 2 have type int; o == true if ints are 32bits in size
-		p = 1<<s == 1<<33  // illegal if ints are 32bits in size: 1 has type int, but 1<<33 overflows int
-		u = 1.0 /* ERROR "must be integer" */ <<s         // illegal: 1.0 has type float64, cannot shift
-		u1 = 1.0 /* ERROR "must be integer" */ <<s != 0   // illegal: 1.0 has type float64, cannot shift
-		u2 = 1 /* ERROR "must be integer" */ <<s != 1.0   // illegal: 1 has type float64, cannot shift
-		v float32 = 1 /* ERROR "must be integer" */ <<s   // illegal: 1 has type float32, cannot shift
-		w int64 = 1.0<<33  // 1.0<<33 is a constant shift expression
-	)
-	_, _, _, _, _, _, _, _, _, _, _, _ = i, j, k, m, n, o, p, u, u1, u2, v, w
-}
-
-func shifts3(a int16, b float32) {
-	// random tests
-	var (
-		s uint = 11
-		u = 1 /* ERROR "must be integer" */ <<s + 1.0
-		v complex128 = 1 /* ERROR "must be integer" */ << s + 1.0 /* ERROR "must be integer" */ << s + 1
-	)
-	x := 1.0 /* ERROR "must be integer" */ <<s + 1
-	shifts3(1.0 << s, 1 /* ERROR "must be integer" */ >> s)
-	_, _, _ = u, v, x
-}
-
-func shifts4() {
-	// shifts in comparisons w/ untyped operands
-	var s uint
-
-	_ = 1<<s == 1
-	_ = 1 /* ERROR "integer" */ <<s == 1.
-	_ = 1. /* ERROR "integer" */ <<s == 1
-	_ = 1. /* ERROR "integer" */ <<s == 1.
-
-	_ = 1<<s + 1 == 1
-	_ = 1 /* ERROR "integer" */ <<s + 1 == 1.
-	_ = 1 /* ERROR "integer" */ <<s + 1. == 1
-	_ = 1 /* ERROR "integer" */ <<s + 1. == 1.
-	_ = 1. /* ERROR "integer" */ <<s + 1 == 1
-	_ = 1. /* ERROR "integer" */ <<s + 1 == 1.
-	_ = 1. /* ERROR "integer" */ <<s + 1. == 1
-	_ = 1. /* ERROR "integer" */ <<s + 1. == 1.
-
-	_ = 1<<s == 1<<s
-	_ = 1 /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s
-	_ = 1. /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s
-	_ = 1. /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s
-
-	_ = 1<<s + 1<<s == 1
-	_ = 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1.
-	_ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1
-	_ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1.
-	_ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1
-	_ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1.
-	_ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1
-	_ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1.
-
-	_ = 1<<s + 1<<s == 1<<s + 1<<s
-	_ = 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
-	_ = 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
-	_ = 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
-	_ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
-	_ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
-	_ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
-	_ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
-	_ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
-	_ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
-	_ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
-	_ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
-	_ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
-	_ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
-	_ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
-	_ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
-}
-
-func shifts5() {
-	// shifts in comparisons w/ typed operands
-	var s uint
-	var x int
-
-	_ = 1<<s == x
-	_ = 1.<<s == x
-	_ = 1.1 /* ERROR "int" */ <<s == x
-
-	_ = 1<<s + x == 1
-	_ = 1<<s + x == 1.
-	_ = 1<<s + x == 1.1 /* ERROR "int" */
-	_ = 1.<<s + x == 1
-	_ = 1.<<s + x == 1.
-	_ = 1.<<s + x == 1.1 /* ERROR "int" */
-	_ = 1.1 /* ERROR "int" */ <<s + x == 1
-	_ = 1.1 /* ERROR "int" */ <<s + x == 1.
-	_ = 1.1 /* ERROR "int" */ <<s + x == 1.1
-
-	_ = 1<<s == x<<s
-	_ = 1.<<s == x<<s
-	_ = 1.1  /* ERROR "int" */ <<s == x<<s
-}
-
-func shifts6() {
-	// shifts as operands in non-arithmetic operations and as arguments
-	var a [10]int
-	var s uint
-
-	_ = a[1<<s]
-	_ = a[1.0]
-	_ = a[1.0<<s]
-
-	_ = make([]int, 1.0)
-	_ = make([]int, 1.0<<s)
-	_ = make([]int, 1.1 /* ERROR "must be integer" */ <<s)
-
-	_ = float32(1)
-	_ = float32(1 /* ERROR "must be integer" */ <<s)
-	_ = float32(1.0)
-	_ = float32(1.0 /* ERROR "must be integer" */ <<s)
-	_ = float32(1.1 /* ERROR "must be integer" */ <<s)
-
-	// TODO(gri) port fixes from go/types
-	// _ = int32(0x80000000 /* ERROR "overflows int32" */ << s)
-	// TODO(rfindley) Eliminate the redundant error here.
-	// _ = int32(( /* ERROR "truncated to int32" */ 0x80000000 /* ERROR "truncated to int32" */ + 0i) << s)
-
-	_ = int(1+0i<<0)
-	// _ = int((1+0i)<<s)
-	// _ = int(1.0<<s)
-	// _ = int(complex(1, 0)<<s)
-	_ = int(float32/* ERROR "must be integer" */(1.0) <<s)
-	_ = int(1.1 /* ERROR must be integer */ <<s)
-	_ = int(( /* ERROR "must be integer" */ 1+1i)  <<s)
-
-	_ = complex(1 /* ERROR "must be integer" */ <<s, 0)
-
-	var b []int
-	_ = append(b, 1<<s)
-	_ = append(b, 1.0<<s)
-	_ = append(b, (1+0i)<<s)
-	_ = append(b, 1.1 /* ERROR "must be integer" */ <<s)
-	_ = append(b, (1 + 0i) <<s)
-	_ = append(b, ( /* ERROR "must be integer" */ 1 + 1i)  <<s)
-
-	_ = complex(1.0 /* ERROR "must be integer" */ <<s, 0)
-	_ = complex(1.1 /* ERROR "must be integer" */ <<s, 0)
-	_ = complex(0, 1.0 /* ERROR "must be integer" */ <<s)
-	_ = complex(0, 1.1 /* ERROR "must be integer" */ <<s)
-
-	// TODO(gri) The delete below is not type-checked correctly yet.
-	// var m1 map[int]string
-	// delete(m1, 1<<s)
-}
-
-func shifts7() {
-	// shifts of shifts
-	var s uint
-	var x int
-	_ = x
-
-	_ = 1<<(1<<s)
-	_ = 1<<(1.<<s)
-	_ = 1. /* ERROR "integer" */ <<(1<<s)
-	_ = 1. /* ERROR "integer" */ <<(1.<<s)
-
-	x = 1<<(1<<s)
-	x = 1<<(1.<<s)
-	x = 1.<<(1<<s)
-	x = 1.<<(1.<<s)
-
-	_ = (1<<s)<<(1<<s)
-	_ = (1<<s)<<(1.<<s)
-	_ = ( /* ERROR "integer" */ 1.<<s)<<(1<<s)
-	_ = ( /* ERROR "integer" */ 1.<<s)<<(1.<<s)
-
-	x = (1<<s)<<(1<<s)
-	x = (1<<s)<<(1.<<s)
-	x = ( /* ERROR "integer" */ 1.<<s)<<(1<<s)
-	x = ( /* ERROR "integer" */ 1.<<s)<<(1.<<s)
-}
-
-func shifts8() {
-	// shift examples from shift discussion: better error messages
-	var s uint
-	_ = 1.0 /* ERROR "shifted operand 1.0 \(type float64\) must be integer" */ <<s == 1
-	_ = 1.0 /* ERROR "shifted operand 1.0 \(type float64\) must be integer" */ <<s == 1.0
-	_ = 1 /* ERROR "shifted operand 1 \(type float64\) must be integer" */ <<s == 1.0
-	_ = 1 /* ERROR "shifted operand 1 \(type float64\) must be integer" */ <<s + 1.0 == 1
-	_ = 1 /* ERROR "shifted operand 1 \(type float64\) must be integer" */ <<s + 1.1 == 1
-	_ = 1 /* ERROR "shifted operand 1 \(type float64\) must be integer" */ <<s + 1 == 1.0
-
-	// additional cases
-	_ = complex(1.0 /* ERROR "shifted operand 1.0 \(type float64\) must be integer" */ <<s, 1)
-	_ = complex(1.0, 1 /* ERROR "shifted operand 1 \(type float64\) must be integer" */ <<s)
-
-	_ = int(1.<<s)
-	_ = int(1.1 /* ERROR "shifted operand .* must be integer" */ <<s)
-	_ = float32(1 /* ERROR "shifted operand .* must be integer" */ <<s)
-	_ = float32(1. /* ERROR "shifted operand .* must be integer" */ <<s)
-	_ = float32(1.1 /* ERROR "shifted operand .* must be integer" */ <<s)
-	// TODO(gri) the error messages for these two are incorrect - disabled for now
-	// _ = complex64(1<<s)
-	// _ = complex64(1.<<s)
-	_ = complex64(1.1 /* ERROR "shifted operand .* must be integer" */ <<s)
-}
-
-func shifts9() {
-	// various originally failing snippets of code from the std library
-	// from src/compress/lzw/reader.go:90
-	{
-		var d struct {
-			bits     uint32
-			width    uint
-		}
-		_ = uint16(d.bits & (1<<d.width - 1))
-	}
-
-	// from src/debug/dwarf/buf.go:116
-	{
-		var ux uint64
-		var bits uint
-		x := int64(ux)
-		if x&(1<<(bits-1)) != 0 {}
-	}
-
-	// from src/encoding/asn1/asn1.go:160
-	{
-		var bytes []byte
-		if bytes[len(bytes)-1]&((1<<bytes[0])-1) != 0 {}
-	}
-
-	// from src/math/big/rat.go:140
-	{
-		var exp int
-		var mantissa uint64
-		shift := uint64(-1022 - (exp - 1)) // [1..53)
-		_ = mantissa & (1<<shift - 1)
-	}
-
-	// from src/net/interface.go:51
-	{
-		type Flags uint
-		var f Flags
-		var i int
-		if f&(1<<uint(i)) != 0 {}
-	}
-
-	// from src/runtime/softfloat64.go:234
-	{
-		var gm uint64
-		var shift uint
-		_ = gm & (1<<shift - 1)
-	}
-
-	// from src/strconv/atof.go:326
-	{
-		var mant uint64
-		var mantbits uint
-		if mant == 2<<mantbits {}
-	}
-
-	// from src/route_bsd.go:82
-	{
-		var Addrs int32
-		const rtaRtMask = 1
-		var i uint
-		if Addrs&rtaRtMask&(1<<i) == 0 {}
-	}
-
-	// from src/text/scanner/scanner.go:540
-	{
-		var s struct { Whitespace uint64 }
-		var ch rune
-		for s.Whitespace&(1<<uint(ch)) != 0 {}
-	}
-}
-
-func issue5895() {
-	var x = 'a' << 1 // type of x must be rune
-	var _ rune = x
-}
-
-func issue11325() {
-	var _ = 0 >> 1.1 /* ERROR "truncated to uint" */ // example from issue 11325
-	_ = 0 >> 1.1 /* ERROR "truncated to uint" */
-	_ = 0 << 1.1 /* ERROR "truncated to uint" */
-	_ = 0 >> 1.
-	_ = 1 >> 1.1 /* ERROR "truncated to uint" */
-	_ = 1 >> 1.
-	_ = 1. >> 1
-	_ = 1. >> 1.
-	_ = 1.1 /* ERROR "must be integer" */ >> 1
-}
-
-func issue11594() {
-	var _ = complex64 /* ERROR "must be integer" */ (1) << 2 // example from issue 11594
-	_ = float32 /* ERROR "must be integer" */ (0) << 1
-	_ = float64 /* ERROR "must be integer" */ (0) >> 2
-	_ = complex64 /* ERROR "must be integer" */ (0) << 3
-	_ = complex64 /* ERROR "must be integer" */ (0) >> 4
-}
-
-func issue21727() {
-	var s uint
-	var a = make([]int, 1<<s + 1.2 /* ERROR "truncated to int" */ )
-	var _ = a[1<<s - 2.3 /* ERROR "truncated to int" */ ]
-	var _ int = 1<<s + 3.4 /* ERROR "truncated to int" */
-	var _ = string(1 /* ERROR shifted operand 1 .* must be integer */ << s)
-	var _ = string(1.0 /* ERROR "cannot convert" */ << s)
-}
-
-func issue22969() {
-	var s uint
-	var a []byte
-	_ = a[0xffffffffffffffff /* ERROR "overflows int" */ <<s] // example from issue 22969
-	_ = make([]int, 0xffffffffffffffff /* ERROR "overflows int" */ << s)
-	_ = make([]int, 0, 0xffffffffffffffff /* ERROR "overflows int" */ << s)
-	var _ byte = 0x100 /* ERROR "overflows byte" */ << s
-	var _ int8 = 0xff /* ERROR "overflows int8" */ << s
-	var _ int16 = 0xffff /* ERROR "overflows int16" */ << s
-	var _ int32 = 0x80000000 /* ERROR "overflows int32" */ << s
-}
diff --git a/src/cmd/compile/internal/types2/testdata/check/slices.go b/src/cmd/compile/internal/types2/testdata/check/slices.go
deleted file mode 100644
index 2bacd1c..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/slices.go
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package slices implements various slice algorithms.
-package slices
-
-// Map turns a []T1 to a []T2 using a mapping function.
-func Map[T1, T2 any](s []T1, f func(T1) T2) []T2 {
-	r := make([]T2, len(s))
-	for i, v := range s {
-		r[i] = f(v)
-	}
-	return r
-}
-
-// Reduce reduces a []T1 to a single value using a reduction function.
-func Reduce[T1, T2 any](s []T1, initializer T2, f func(T2, T1) T2) T2 {
-	r := initializer
-	for _, v := range s {
-		r = f(r, v)
-	}
-	return r
-}
-
-// Filter filters values from a slice using a filter function.
-func Filter[T any](s []T, f func(T) bool) []T {
-	var r []T
-	for _, v := range s {
-		if f(v) {
-			r = append(r, v)
-		}
-	}
-	return r
-}
-
-// Example uses
-
-func limiter(x int) byte {
-	switch {
-	case x < 0:
-		return 0
-	default:
-		return byte(x)
-	case x > 255:
-		return 255
-	}
-}
-
-var input = []int{-4, 68954, 7, 44, 0, -555, 6945}
-var limited1 = Map[int, byte](input, limiter)
-var limited2 = Map(input, limiter) // using type inference
-
-func reducer(x float64, y int) float64 {
-	return x + float64(y)
-}
-
-var reduced1 = Reduce[int, float64](input, 0, reducer)
-var reduced2 = Reduce(input, 1i /* ERROR overflows */, reducer) // using type inference
-var reduced3 = Reduce(input, 1, reducer) // using type inference
-
-func filter(x int) bool {
-	return x&1 != 0
-}
-
-var filtered1 = Filter[int](input, filter)
-var filtered2 = Filter(input, filter) // using type inference
-
diff --git a/src/cmd/compile/internal/types2/testdata/check/stmt0.go b/src/cmd/compile/internal/types2/testdata/check/stmt0.go
deleted file mode 100644
index e5b6f5d..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/stmt0.go
+++ /dev/null
@@ -1,992 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// statements
-
-package stmt0
-
-func assignments0() (int, int) {
-	var a, b, c int
-	var ch chan int
-	f0 := func() {}
-	f1 := func() int { return 1 }
-	f2 := func() (int, int) { return 1, 2 }
-	f3 := func() (int, int, int) { return 1, 2, 3 }
-
-	a, b, c = 1, 2, 3
-	a, b, c = 1 /* ERROR "cannot assign [1-9]+ values to [1-9]+ variables" */ , 2
-	a, b, c = 1 /* ERROR "cannot assign [1-9]+ values to [1-9]+ variables" */ , 2, 3, 4
-	_, _, _ = a, b, c
-
-	a = f0 /* ERROR "used as value" */ ()
-	a = f1()
-	a = f2 /* ERROR "cannot assign [1-9]+ values to [1-9]+ variables" */ ()
-	a, b = f2()
-	a, b, c = f2 /* ERROR "cannot assign [1-9]+ values to [1-9]+ variables" */ ()
-	a, b, c = f3()
-	a, b = f3 /* ERROR "cannot assign [1-9]+ values to [1-9]+ variables" */ ()
-
-	a, b, c = <- /* ERROR "cannot assign [1-9]+ values to [1-9]+ variables" */ ch
-
-	return /* ERROR "not enough return values\n\thave \(\)\n\twant \(int, int\)" */
-	return 1 /* ERROR "not enough return values\n\thave \(number\)\n\twant \(int, int\)" */
-	return 1, 2
-	return 1, 2, 3 /* ERROR "too many return values\n\thave \(number, number, number\)\n\twant \(int, int\)" */
-}
-
-func assignments1() {
-	b, i, f, c, s := false, 1, 1.0, 1i, "foo"
-	b = i /* ERROR "cannot use .* in assignment" */
-	i = f /* ERROR "cannot use .* in assignment" */
-	f = c /* ERROR "cannot use .* in assignment" */
-	c = s /* ERROR "cannot use .* in assignment" */
-	s = b /* ERROR "cannot use .* in assignment" */
-
-	v0, v1, v2 := 1 /* ERROR "cannot initialize" */ , 2, 3, 4
-	_, _, _ = v0, v1, v2
-
-	b = true
-
-	i += 1
-	i += "foo" /* ERROR "mismatched types int and untyped string" */
-
-	f -= 1
-	f /= 0
-	f = float32(0)/0 /* ERROR "division by zero" */
-	f -= "foo" /* ERROR "mismatched types float64 and untyped string" */
-
-	c *= 1
-	c /= 0
-
-	s += "bar"
-	s += 1 /* ERROR "mismatched types string and untyped int" */
-
-	var u64 uint64
-	u64 += 1<<u64
-
-	undeclared /* ERROR "undeclared" */ = 991
-
-	// test cases for issue 5800
-	var (
-		_ int = nil /* ERROR "cannot use nil as int value in variable declaration" */
-		_ [10]int = nil /* ERROR "cannot use nil as \[10\]int value in variable declaration" */
-		_ []byte = nil
-		_ struct{} = nil /* ERROR "cannot use nil as struct{} value in variable declaration" */
-		_ func() = nil
-		_ map[int]string = nil
-		_ chan int = nil
-	)
-
-	// test cases for issue 5500
-	_ = func() (int, bool) {
-		var m map[int]int
-		return m /* ERROR "not enough return values" */ [0]
-	}
-
-	g := func(int, bool){}
-	var m map[int]int
-	g(m /* ERROR "not enough arguments" */ [0])
-
-	// assignments to _
-	_ = nil /* ERROR "use of untyped nil" */
-	_ = 1 /* ERROR overflow */ <<1000
-	(_) = 0
-}
-
-func assignments2() {
-	type mybool bool
-	var m map[string][]bool
-	var s []bool
-	var b bool
-	var d mybool
-	_ = s
-	_ = b
-	_ = d
-
-	// assignments to map index expressions are ok
-	s, b = m["foo"]
-	_, d = m["bar"]
-	m["foo"] = nil
-	m["foo"] = nil /* ERROR cannot assign [1-9]+ values to [1-9]+ variables */ , false
-	_ = append(m["foo"])
-	_ = append(m["foo"], true)
-
-	var c chan int
-	_, b = <-c
-	_, d = <-c
-	<- /* ERROR cannot assign */ c = 0
-	<-c = 0 /* ERROR cannot assign [1-9]+ values to [1-9]+ variables */ , false
-
-	var x interface{}
-	_, b = x.(int)
-	x /* ERROR cannot assign */ .(int) = 0
-	x.(int) = 0 /* ERROR cannot assign [1-9]+ values to [1-9]+ variables */ , false
-
-	assignments2 /* ERROR used as value */ () = nil
-	int /* ERROR not an expression */ = 0
-}
-
-func issue6487() {
-	type S struct{x int}
-	_ = &S /* ERROR "cannot take address" */ {}.x
-	_ = &( /* ERROR "cannot take address" */ S{}.x)
-	_ = (&S{}).x
-	S /* ERROR "cannot assign" */ {}.x = 0
-	(&S{}).x = 0
-
-	type M map[string]S
-	var m M
-	m /* ERROR "cannot assign to struct field" */ ["foo"].x = 0
-	_ = &( /* ERROR "cannot take address" */ m["foo"].x)
-	_ = &m /* ERROR "cannot take address" */ ["foo"].x
-}
-
-func issue6766a() {
-	a, a /* ERROR a repeated on left side of := */ := 1, 2
-	_ = a
-	a, b, b /* ERROR b repeated on left side of := */ := 1, 2, 3
-	_ = b
-	c, c /* ERROR c repeated on left side of := */, b := 1, 2, 3
-	_ = c
-	a, b := /* ERROR no new variables */ 1, 2
-}
-
-func shortVarDecls1() {
-	const c = 0
-	type d int
-	a, b, c /* ERROR "cannot assign" */ , d /* ERROR "cannot assign" */  := 1, "zwei", 3.0, 4
-	var _ int = a // a is of type int
-	var _ string = b // b is of type string
-}
-
-func incdecs() {
-	const c = 3.14
-	c /* ERROR "cannot assign" */ ++
-	s := "foo"
-	s /* ERROR "invalid operation" */ --
-	3.14 /* ERROR "cannot assign" */ ++
-	var (
-		x int
-		y float32
-		z complex128
-	)
-	x++
-	y--
-	z++
-}
-
-func sends() {
-	var ch chan int
-	var rch <-chan int
-	var x int
-	x <- /* ERROR "cannot send" */ x
-	rch <- /* ERROR "cannot send" */ x
-	ch <- "foo" /* ERROR "cannot use .* in send" */
-	ch <- x
-}
-
-func selects() {
-	select {}
-	var (
-		ch chan int
-		sc chan <- bool
-	)
-	select {
-	case <-ch:
-	case (<-ch):
-	case t := <-ch:
-		_ = t
-	case t := (<-ch):
-		_ = t
-	case t, ok := <-ch:
-		_, _ = t, ok
-	case t, ok := (<-ch):
-		_, _ = t, ok
-	case <-sc /* ERROR "cannot receive from send-only channel" */ :
-	}
-	select {
-	default:
-	default /* ERROR "multiple defaults" */ :
-	}
-	select {
-	case a, b := <-ch:
-		_, b = a, b
-	case x /* ERROR send or receive */ :
-	case a /* ERROR send or receive */ := ch:
-	}
-
-	// test for issue 9570: ch2 in second case falsely resolved to
-	// ch2 declared in body of first case
-	ch1 := make(chan int)
-	ch2 := make(chan int)
-	select {
-	case <-ch1:
-		var ch2 /* ERROR ch2 declared but not used */ chan bool
-	case i := <-ch2:
-		print(i + 1)
-	}
-}
-
-func gos() {
-	go 1 /* ERROR must be function call */ /* ERROR cannot call non-function */
-	go int /* ERROR "go requires function call, not conversion" */ (0)
-	go gos()
-	var c chan int
-	go close(c)
-	go len /* ERROR "go discards result" */ (c)
-}
-
-func defers() {
-	defer 1 /* ERROR must be function call */ /* ERROR cannot call non-function */
-	defer int /* ERROR "defer requires function call, not conversion" */ (0)
-	defer defers()
-	var c chan int
-	defer close(c)
-	defer len /* ERROR "defer discards result" */ (c)
-}
-
-func breaks() {
-	var x, y int
-
-	break /* ERROR "break" */
-	{
-		break /* ERROR "break" */
-	}
-	if x < y {
-		break /* ERROR "break" */
-	}
-
-	switch x {
-	case 0:
-		break
-	case 1:
-		if x == y {
-			break
-		}
-	default:
-		break
-		break
-	}
-
-	var z interface{}
-	switch z.(type) {
-	case int:
-		break
-	}
-
-	for {
-		break
-	}
-
-	var a []int
-	for _ = range a {
-		break
-	}
-
-	for {
-		if x == y {
-			break
-		}
-	}
-
-	var ch chan int
-	select {
-	case <-ch:
-		break
-	}
-
-	select {
-	case <-ch:
-		if x == y {
-			break
-		}
-	default:
-		break
-	}
-}
-
-func continues() {
-	var x, y int
-
-	continue /* ERROR "continue" */
-	{
-		continue /* ERROR "continue" */
-	}
-
-	if x < y {
-		continue /* ERROR "continue" */
-	}
-
-	switch x {
-	case 0:
-		continue /* ERROR "continue" */
-	}
-
-	var z interface{}
-	switch z.(type) {
-	case int:
-		continue /* ERROR "continue" */
-	}
-
-	var ch chan int
-	select {
-	case <-ch:
-		continue /* ERROR "continue" */
-	}
-
-	for i := 0; i < 10; i++ {
-		continue
-		if x < y {
-			continue
-			break
-		}
-		switch x {
-		case y:
-			continue
-		default:
-			break
-		}
-		select {
-		case <-ch:
-			continue
-		}
-	}
-
-	var a []int
-	for _ = range a {
-		continue
-		if x < y {
-			continue
-			break
-		}
-		switch x {
-		case y:
-			continue
-		default:
-			break
-		}
-		select {
-		case <-ch:
-			continue
-		}
-	}
-}
-
-func returns0() {
-	return
-	return 0 /* ERROR too many return values */
-}
-
-func returns1(x float64) (int, *float64) {
-	return 0, &x
-	return /* ERROR not enough return values */
-	return "foo" /* ERROR "cannot .* in return statement" */, x /* ERROR "cannot use .* in return statement" */
-	return 0, &x, 1 /* ERROR too many return values */
-}
-
-func returns2() (a, b int) {
-	return
-	return 1, "foo" /* ERROR cannot use .* in return statement */
-	return 1, 2, 3 /* ERROR too many return values */
-	{
-		type a int
-		return 1, 2
-		return /* ERROR a not in scope at return */
-	}
-}
-
-func returns3() (_ int) {
-	return
-	{
-		var _ int // blank (_) identifiers never shadow since they are in no scope
-		return
-	}
-}
-
-func switches0() {
-	var x int
-
-	switch x {
-	}
-
-	switch x {
-	default:
-	default /* ERROR "multiple defaults" */ :
-	}
-
-	switch {
-	case 1  /* ERROR "cannot convert" */ :
-	}
-
-	true := "false"
-	_ = true
-	// A tagless switch is equivalent to the bool
-        // constant true, not the identifier 'true'.
-	switch {
-	case "false" /* ERROR "cannot convert" */:
-	}
-
-	switch int32(x) {
-	case 1, 2:
-	case x /* ERROR "invalid case x in switch on int32\(x\) \(mismatched types int and int32\)" */ :
-	}
-
-	switch x {
-	case 1 /* ERROR "overflows" */ << 100:
-	}
-
-	switch x {
-	case 1:
-	case 1 /* ERROR "duplicate case" */ :
-	case ( /* ERROR "duplicate case" */ 1):
-	case 2, 3, 4:
-	case 5, 1 /* ERROR "duplicate case" */ :
-	}
-
-	switch uint64(x) {
-	case 1<<64 - 1:
-	case 1 /* ERROR duplicate case */ <<64 - 1:
-	case 2, 3, 4:
-	case 5, 1 /* ERROR duplicate case */ <<64 - 1:
-	}
-
-	var y32 float32
-	switch y32 {
-	case 1.1:
-	case 11/10: // integer division!
-	case 11. /* ERROR duplicate case */ /10:
-	case 2, 3.0, 4.1:
-	case 5.2, 1.10 /* ERROR duplicate case */ :
-	}
-
-	var y64 float64
-	switch y64 {
-	case 1.1:
-	case 11/10: // integer division!
-	case 11. /* ERROR duplicate case */ /10:
-	case 2, 3.0, 4.1:
-	case 5.2, 1.10 /* ERROR duplicate case */ :
-	}
-
-	var s string
-	switch s {
-	case "foo":
-	case "foo" /* ERROR duplicate case */ :
-	case "f" /* ERROR duplicate case */ + "oo":
-	case "abc", "def", "ghi":
-	case "jkl", "foo" /* ERROR duplicate case */ :
-	}
-
-	type T int
-	type F float64
-	type S string
-	type B bool
-	var i interface{}
-	switch i {
-	case nil:
-	case nil: // no duplicate detection
-	case (*int)(nil):
-	case (*int)(nil): // do duplicate detection
-	case 1:
-	case byte(1):
-	case int /* ERROR duplicate case */ (1):
-	case T(1):
-	case 1.0:
-	case F(1.0):
-	case F /* ERROR duplicate case */ (1.0):
-	case "hello":
-	case S("hello"):
-	case S /* ERROR duplicate case */ ("hello"):
-	case 1==1, B(false):
-	case false, B(2==2):
-	}
-
-	// switch on array
-	var a [3]int
-	switch a {
-	case [3]int{1, 2, 3}:
-	case [3]int{1, 2, 3}: // no duplicate detection
-	case [ /* ERROR "mismatched types */ 4]int{4, 5, 6}:
-	}
-
-	// switch on channel
-	var c1, c2 chan int
-	switch c1 {
-	case nil:
-	case c1:
-	case c2:
-	case c1, c2: // no duplicate detection
-	}
-}
-
-func switches1() {
-	fallthrough /* ERROR "fallthrough statement out of place" */
-
-	var x int
-	switch x {
-	case 0:
-		fallthrough /* ERROR "fallthrough statement out of place" */
-		break
-	case 1:
-		fallthrough
-	case 2:
-		fallthrough; ; ; // trailing empty statements are ok
-	case 3:
-	default:
-		fallthrough; ;
-	case 4:
-		fallthrough /* ERROR "cannot fallthrough final case in switch" */
-	}
-
-	var y interface{}
-	switch y.(type) {
-	case int:
-		fallthrough /* ERROR "cannot fallthrough in type switch" */ ; ; ;
-	default:
-	}
-
-	switch x {
-	case 0:
-		if x == 0 {
-			fallthrough /* ERROR "fallthrough statement out of place" */
-		}
-	}
-
-	switch x {
-	case 0:
-		goto L1
-		L1: fallthrough; ;
-	case 1:
-		goto L2
-		goto L3
-		goto L4
-		L2: L3: L4: fallthrough
-	default:
-	}
-
-	switch x {
-	case 0:
-		goto L5
-		L5: fallthrough
-	default:
-		goto L6
-		goto L7
-		goto L8
-		L6: L7: L8: fallthrough /* ERROR "cannot fallthrough final case in switch" */
-	}
-
-	switch x {
-	case 0:
-		fallthrough; ;
-	case 1:
-		{
-			fallthrough /* ERROR "fallthrough statement out of place" */
-		}
-	case 2:
-		fallthrough
-	case 3:
-		fallthrough /* ERROR "fallthrough statement out of place" */
-		{ /* empty block is not an empty statement */ }; ;
-	default:
-		fallthrough /* ERROR "cannot fallthrough final case in switch" */
-	}
-
-	switch x {
-	case 0:
-		{
-			fallthrough /* ERROR "fallthrough statement out of place" */
-		}
-	}
-}
-
-func switches2() {
-	// untyped nil is not permitted as switch expression
-	switch nil /* ERROR "use of untyped nil" */ {
-	case 1, 2, "foo": // don't report additional errors here
-	}
-
-	// untyped constants are converted to default types
-	switch 1<<63-1 {
-	}
-	switch 1 /* ERROR "cannot use .* as int value.*\(overflows\)" */ << 63 {
-	}
-	var x int
-	switch 1.0 {
-	case 1.0, 2.0, x /* ERROR "mismatched types int and float64" */ :
-	}
-	switch x {
-	case 1.0:
-	}
-
-	// untyped bools become of type bool
-	type B bool
-	var b B = true
-	switch x == x {
-	case b /* ERROR "mismatched types B and bool" */ :
-	}
-	switch {
-	case b /* ERROR "mismatched types B and bool" */ :
-	}
-}
-
-func issue11667() {
-	switch 9223372036854775808 /* ERROR "cannot use .* as int value.*\(overflows\)" */ {
-	}
-	switch 9223372036854775808 /* ERROR "cannot use .* as int value.*\(overflows\)" */ {
-	case 9223372036854775808:
-	}
-	var x int
-	switch x {
-	case 9223372036854775808 /* ERROR "overflows int" */ :
-	}
-	var y float64
-	switch y {
-	case 9223372036854775808:
-	}
-}
-
-func issue11687() {
-	f := func() (_, _ int) { return }
-	switch f /* ERROR "2-valued f" */ () {
-	}
-	var x int
-	switch f /* ERROR "2-valued f" */ () {
-	case x:
-	}
-	switch x {
-	case f /* ERROR "2-valued f" */ ():
-	}
-}
-
-type I interface {
-	m()
-}
-
-type I2 interface {
-	m(int)
-}
-
-type T struct{}
-type T1 struct{}
-type T2 struct{}
-
-func (T) m() {}
-func (T2) m(int) {}
-
-func typeswitches() {
-	var i int
-	var x interface{}
-
-	switch x.(type) {}
-	switch (x /* ERROR "outside type switch" */ .(type)) {}
-
-	switch x.(type) {
-	default:
-	default /* ERROR "multiple defaults" */ :
-	}
-
-	switch x /* ERROR "declared but not used" */ := x.(type) {}
-	switch _ /* ERROR "no new variable on left side of :=" */ := x.(type) {}
-
-	switch x := x.(type) {
-	case int:
-		var y int = x
-		_ = y
-	}
-
-	switch /* ERROR "x declared but not used" */ x := i /* ERROR "not an interface" */ .(type) {}
-
-	switch t := x.(type) {
-	case nil:
-		var v bool = t /* ERROR "cannot use .* in variable declaration" */
-		_ = v
-	case int:
-		var v int = t
-		_ = v
-	case float32, complex64:
-		var v float32 = t /* ERROR "cannot use .* in variable declaration" */
-		_ = v
-	default:
-		var v float32 = t /* ERROR "cannot use .* in variable declaration" */
-		_ = v
-	}
-
-	var t I
-	switch t.(type) {
-	case T:
-	case T1 /* ERROR "missing method m" */ :
-	case T2 /* ERROR "wrong type for method m" */ :
-	case I2 /* STRICT "wrong type for method m" */ : // only an error in strict mode (issue 8561)
-	}
-
-
-	{
-		x := 1
-		v := 2
-		switch v /* ERROR "v [(]variable of type int[)] is not an interface" */ .(type) {
-		case int:
-			println(x)
-			println(x / /* ERROR "invalid operation: division by zero" */ 0)
-		case /* ERROR "1 is not a type" */ 1:
-		}
-	}
-}
-
-// Test that each case clause uses the correct type of the variable
-// declared by the type switch (issue 5504).
-func typeswitch0() {
-	switch y := interface{}(nil).(type) {
-	case int:
-		func() int { return y + 0 }()
-	case float32:
-		func() float32 { return y }()
-	}
-}
-
-// Test correct scope setup.
-// (no redeclaration errors expected in the type switch)
-func typeswitch1() {
-	var t I
-	switch t := t; t := t.(type) {
-	case nil:
-		var _ I = t
-	case T:
-		var _ T = t
-	default:
-		var _ I = t
-	}
-}
-
-// Test correct typeswitch against interface types.
-type A interface { a() }
-type B interface { b() }
-type C interface { a(int) }
-
-func typeswitch2() {
-	switch A(nil).(type) {
-	case A:
-	case B:
-	case C /* STRICT "cannot have dynamic type" */: // only an error in strict mode (issue 8561)
-	}
-}
-
-func typeswitch3(x interface{}) {
-	switch x.(type) {
-	case int:
-	case float64:
-	case int /* ERROR duplicate case */ :
-	}
-
-	switch x.(type) {
-	case nil:
-	case int:
-	case nil /* ERROR duplicate case */ , nil /* ERROR duplicate case */ :
-	}
-
-	type F func(int)
-	switch x.(type) {
-	case nil:
-	case int, func(int):
-	case float32, func /* ERROR duplicate case */ (x int):
-	case F:
-	}
-}
-
-func fors1() {
-	for {}
-	var i string
-	_ = i
-	for i := 0; i < 10; i++ {}
-	for i := 0; i < 10; j /* ERROR cannot declare */ := 0 {}
-}
-
-func rangeloops1() {
-	var (
-		x int
-		a [10]float32
-		b []string
-		p *[10]complex128
-		pp **[10]complex128
-		s string
-		m map[int]bool
-		c chan int
-		sc chan<- int
-		rc <-chan int
-	)
-
-	for range x /* ERROR "cannot range over" */ {}
-	for _ = range x /* ERROR "cannot range over" */ {}
-	for i := range x /* ERROR "cannot range over" */ {}
-
-	for range a {}
-	for i := range a {
-		var ii int
-		ii = i
-		_ = ii
-	}
-	for i, x := range a {
-		var ii int
-		ii = i
-		_ = ii
-		var xx float64
-		xx = x /* ERROR "cannot use .* in assignment" */
-		_ = xx
-	}
-	var ii int
-	var xx float32
-	for ii, xx = range a {}
-	_, _ = ii, xx
-
-	for range b {}
-	for i := range b {
-		var ii int
-		ii = i
-		_ = ii
-	}
-	for i, x := range b {
-		var ii int
-		ii = i
-		_ = ii
-		var xx string
-		xx = x
-		_ = xx
-	}
-
-	for range s {}
-	for i := range s {
-		var ii int
-		ii = i
-		_ = ii
-	}
-	for i, x := range s {
-		var ii int
-		ii = i
-		_ = ii
-		var xx rune
-		xx = x
-		_ = xx
-	}
-
-	for range p {}
-	for _, x := range p {
-		var xx complex128
-		xx = x
-		_ = xx
-	}
-
-	for range pp /* ERROR "cannot range over" */ {}
-	for _, x := range pp /* ERROR "cannot range over" */ {}
-
-	for range m {}
-	for k := range m {
-		var kk int32
-		kk = k /* ERROR "cannot use .* in assignment" */
-		_ = kk
-	}
-	for k, v := range m {
-		var kk int
-		kk = k
-		_ = kk
-		if v {}
-	}
-
-	for range c {}
-	for _, _ /* ERROR "only one iteration variable" */ = range c {}
-	for e := range c {
-		var ee int
-		ee = e
-		_ = ee
-	}
-	for _ = range sc /* ERROR "send-only channel" */ {}
-	for _ = range rc {}
-
-	// constant strings
-	const cs = "foo"
-	for range cs {}
-	for range "" {}
-	for i, x := range cs { _, _ = i, x }
-	for i, x := range "" {
-		var ii int
-		ii = i
-		_ = ii
-		var xx rune
-		xx = x
-		_ = xx
-	}
-}
-
-func rangeloops2() {
-	type I int
-	type R rune
-
-	var a [10]int
-	var i I
-	_ = i
-	for i /* ERROR cannot use .* in assignment */ = range a {}
-	for i /* ERROR cannot use .* in assignment */ = range &a {}
-	for i /* ERROR cannot use .* in assignment */ = range a[:] {}
-
-	var s string
-	var r R
-	_ = r
-	for i /* ERROR cannot use .* in assignment */ = range s {}
-	for i /* ERROR cannot use .* in assignment */ = range "foo" {}
-	for _, r /* ERROR cannot use .* in assignment */ = range s {}
-	for _, r /* ERROR cannot use .* in assignment */ = range "foo" {}
-}
-
-func issue6766b() {
-	for _ := /* ERROR no new variables */ range "" {}
-	for a, a /* ERROR redeclared */ := range "" { _ = a }
-	var a int
-	_ = a
-	for a, a /* ERROR redeclared */ := range []int{1, 2, 3} { _ = a }
-}
-
-// Test that despite errors in the range clause,
-// the loop body is still type-checked (and thus
-// errors reported).
-func issue10148() {
-	for y /* ERROR declared but not used */ := range "" {
-		_ = "" /* ERROR mismatched types untyped string and untyped int*/ + 1
-	}
-	for range 1 /* ERROR cannot range over 1 */ {
-		_ = "" /* ERROR mismatched types untyped string and untyped int*/ + 1
-	}
-	for y := range 1 /* ERROR cannot range over 1 */ {
-		_ = "" /* ERROR mismatched types untyped string and untyped int*/ + 1
-	}
-}
-
-func labels0() {
-	goto L0
-	goto L1
-	L0:
-	L1:
-	L1 /* ERROR "already declared" */ :
-	if true {
-		goto L2
-		L2:
-		L0 /* ERROR "already declared" */ :
-	}
-	_ = func() {
-		goto L0
-		goto L1
-		goto L2
-		L0:
-		L1:
-		L2:
-	}
-}
-
-func expression_statements(ch chan int) {
-	expression_statements(ch)
-	<-ch
-	println()
-
-	0 /* ERROR "not used" */
-	1 /* ERROR "not used" */ +2
-	cap /* ERROR "not used" */ (ch)
-	println /* ERROR "must be called" */
-}
diff --git a/src/cmd/compile/internal/types2/testdata/check/stmt1.go b/src/cmd/compile/internal/types2/testdata/check/stmt1.go
deleted file mode 100644
index f79f920..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/stmt1.go
+++ /dev/null
@@ -1,259 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// terminating statements
-
-package stmt1
-
-func _() {}
-
-func _() int {} /* ERROR "missing return" */
-
-func _() int { panic(0) }
-func _() int { (panic(0)) }
-
-// block statements
-func _(x, y int) (z int) {
-	{
-		return
-	}
-}
-
-func _(x, y int) (z int) {
-	{
-		return; ; ; // trailing empty statements are ok
-	}
-	; ; ;
-}
-
-func _(x, y int) (z int) {
-	{
-	}
-} /* ERROR "missing return" */
-
-func _(x, y int) (z int) {
-	{
-		; ; ;
-	}
-	; ; ;
-} /* ERROR "missing return" */
-
-// if statements
-func _(x, y int) (z int) {
-	if x < y { return }
-	return 1
-}
-
-func _(x, y int) (z int) {
-	if x < y { return; ; ; ; }
-	return 1
-}
-
-func _(x, y int) (z int) {
-	if x < y { return }
-	return 1; ;
-}
-
-func _(x, y int) (z int) {
-	if x < y { return }
-} /* ERROR "missing return" */
-
-func _(x, y int) (z int) {
-	if x < y {
-	} else { return 1
-	}
-} /* ERROR "missing return" */
-
-func _(x, y int) (z int) {
-	if x < y { return
-	} else { return
-	}
-}
-
-// for statements
-func _(x, y int) (z int) {
-	for x < y {
-		return
-	}
-} /* ERROR "missing return" */
-
-func _(x, y int) (z int) {
-	for {
-		return
-	}
-}
-
-func _(x, y int) (z int) {
-	for {
-		return; ; ; ;
-	}
-}
-
-func _(x, y int) (z int) {
-	for {
-		return
-		break
-	}
-	; ; ;
-} /* ERROR "missing return" */
-
-func _(x, y int) (z int) {
-	for {
-		for { break }
-		return
-	}
-}
-
-func _(x, y int) (z int) {
-	for {
-		for { break }
-		return ; ;
-	}
-	;
-}
-
-func _(x, y int) (z int) {
-L:	for {
-		for { break L }
-		return
-	}
-} /* ERROR "missing return" */
-
-// switch statements
-func _(x, y int) (z int) {
-	switch x {
-	case 0: return
-	default: return
-	}
-}
-
-func _(x, y int) (z int) {
-	switch x {
-	case 0: return;
-	default: return; ; ;
-	}
-}
-
-func _(x, y int) (z int) {
-	switch x {
-	case 0: return
-	}
-} /* ERROR "missing return" */
-
-func _(x, y int) (z int) {
-	switch x {
-	case 0: return
-	case 1: break
-	}
-} /* ERROR "missing return" */
-
-func _(x, y int) (z int) {
-	switch x {
-	case 0: return
-	default:
-		switch y {
-		case 0: break
-		}
-		panic(0)
-	}
-}
-
-func _(x, y int) (z int) {
-	switch x {
-	case 0: return
-	default:
-		switch y {
-		case 0: break
-		}
-		panic(0); ; ;
-	}
-	;
-}
-
-func _(x, y int) (z int) {
-L:	switch x {
-	case 0: return
-	default:
-		switch y {
-		case 0: break L
-		}
-		panic(0)
-	}
-} /* ERROR "missing return" */
-
-// select statements
-func _(ch chan int) (z int) {
-	select {}
-} // nice!
-
-func _(ch chan int) (z int) {
-	select {}
-	; ;
-}
-
-func _(ch chan int) (z int) {
-	select {
-	default: break
-	}
-} /* ERROR "missing return" */
-
-func _(ch chan int) (z int) {
-	select {
-	case <-ch: return
-	default: break
-	}
-} /* ERROR "missing return" */
-
-func _(ch chan int) (z int) {
-	select {
-	case <-ch: return
-	default:
-		for i := 0; i < 10; i++ {
-			break
-		}
-		return
-	}
-}
-
-func _(ch chan int) (z int) {
-	select {
-	case <-ch: return; ; ;
-	default:
-		for i := 0; i < 10; i++ {
-			break
-		}
-		return; ; ;
-	}
-	; ; ;
-}
-
-func _(ch chan int) (z int) {
-L:	select {
-	case <-ch: return
-	default:
-		for i := 0; i < 10; i++ {
-			break L
-		}
-		return
-	}
-	; ; ;
-} /* ERROR "missing return" */
-
-func parenPanic() int {
-	((((((panic)))(0))))
-}
-
-func issue23218a() int {
-	{
-		panic := func(interface{}){}
-		panic(0)
-	}
-} /* ERROR "missing return" */
-
-func issue23218b() int {
-	{
-		panic := func(interface{}){}
-		((((panic))))(0)
-	}
-} /* ERROR "missing return" */
diff --git a/src/cmd/compile/internal/types2/testdata/check/typeinference.go b/src/cmd/compile/internal/types2/testdata/check/typeinference.go
deleted file mode 100644
index 28f3e28..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/typeinference.go
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package typeInference
-
-// As of issue #51527, type-type inference has been disabled.
-
-// basic inference
-type Tb[P ~*Q, Q any] int
-func _() {
-	var x Tb /* ERROR got 1 arguments */ [*int]
-	var y Tb[*int, int]
-	x = y /* ERROR cannot use y .* in assignment */
-	_ = x
-}
-
-// recursive inference
-type Tr[A any, B *C, C *D, D *A] int
-func _() {
-	var x Tr /* ERROR got 1 arguments */ [string]
-	var y Tr[string, ***string, **string, *string]
-	var z Tr[int, ***int, **int, *int]
-	x = y /* ERROR cannot use y .* in assignment */
-	x = z // ERROR cannot use z .* as Tr
-	_ = x
-}
-
-// other patterns of inference
-type To0[A any, B []A] int
-type To1[A any, B struct{a A}] int
-type To2[A any, B [][]A] int
-type To3[A any, B [3]*A] int
-type To4[A any, B any, C struct{a A; b B}] int
-func _() {
-	var _ To0 /* ERROR got 1 arguments */ [int]
-	var _ To1 /* ERROR got 1 arguments */ [int]
-	var _ To2 /* ERROR got 1 arguments */ [int]
-	var _ To3 /* ERROR got 1 arguments */ [int]
-	var _ To4 /* ERROR got 2 arguments */ [int, string]
-}
-
-// failed inference
-type Tf0[A, B any] int
-type Tf1[A any, B ~struct{a A; c C}, C any] int
-func _() {
-	var _ Tf0 /* ERROR got 1 arguments but 2 type parameters */ [int]
-	var _ Tf1 /* ERROR got 1 arguments but 3 type parameters */ [int]
-}
diff --git a/src/cmd/compile/internal/types2/testdata/check/typeinst0.go b/src/cmd/compile/internal/types2/testdata/check/typeinst0.go
deleted file mode 100644
index 0e6dc0a..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/typeinst0.go
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type myInt int
-
-// Parameterized type declarations
-
-// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
-type T1[P any] P // ERROR cannot use a type parameter as RHS in type declaration
-
-type T2[P any] struct {
-        f P
-        g int // int should still be in scope chain
-}
-
-type List[P any] []P
-
-// Alias type declarations cannot have type parameters.
-// Issue #46477 proposses to change that.
-type A1[P any] = /* ERROR cannot be alias */ struct{}
-
-// Pending clarification of #46477 we disallow aliases
-// of generic types.
-type A2 = List // ERROR cannot use generic type
-var _ A2[int]
-var _ A2
-
-type A3 = List[int]
-var _ A3
-
-// Parameterized type instantiations
-
-var x int
-type _ x /* ERROR not a type */ [int]
-
-type _ int /* ERROR not a generic type */ [] // ERROR expecting type
-type _ myInt /* ERROR not a generic type */ [] // ERROR expecting type
-
-// TODO(gri) better error messages
-type _ T1[] // ERROR expecting type
-type _ T1[x /* ERROR not a type */ ]
-type _ T1 /* ERROR got 2 arguments but 1 type parameters */ [int, float32]
-
-var _ T2[int] = T2[int]{}
-
-var _ List[int] = []int{1, 2, 3}
-var _ List[[]int] = [][]int{{1, 2, 3}}
-var _ List[List[List[int]]]
-
-// Parameterized types containing parameterized types
-
-type T3[P any] List[P]
-
-var _ T3[int] = T3[int](List[int]{1, 2, 3})
-
-// Self-recursive generic types are not permitted
-
-type self1[P any] self1 /* ERROR illegal cycle */ [P]
-type self2[P any] *self2[P] // this is ok
diff --git a/src/cmd/compile/internal/types2/testdata/check/typeinst1.go b/src/cmd/compile/internal/types2/testdata/check/typeinst1.go
deleted file mode 100644
index eb0708f..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/typeinst1.go
+++ /dev/null
@@ -1,282 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type List[E any] []E
-var _ List[List[List[int]]]
-var _ List[List[List[int]]] = []List[List[int]]{}
-
-type (
-	T1[P1 any] struct {
-		f1 T2[P1, float32]
-	}
-
-	T2[P2, P3 any] struct {
-		f2 P2
-		f3 P3
-	}
-)
-
-func _() {
-	var x1 T1[int]
-	var x2 T2[int, float32]
-
-	x1.f1.f2 = 0
-	x1.f1 = x2
-}
-
-type T3[P any] T1[T2[P, P]]
-
-func _() {
-	var x1 T3[int]
-	var x2 T2[int, int]
-	x1.f1.f2 = x2
-}
-
-func f[P any] (x P) List[P] {
-	return List[P]{x}
-}
-
-var (
-	_ []int = f(0)
-	_ []float32 = f[float32](10)
-	_ List[complex128] = f(1i)
-	_ []List[int] = f(List[int]{})
-        _ List[List[int]] = []List[int]{}
-        _ = []List[int]{}
-)
-
-// Parameterized types with methods
-
-func (l List[E]) Head() (_ E, _ bool) {
-	if len(l) > 0 {
-		return l[0], true
-	}
-	return
-}
-
-// A test case for instantiating types with other types (extracted from map.go2)
-
-type Pair[K any] struct {
-	key K
-}
-
-type Receiver[T any] struct {
-	values T
-}
-
-type Iterator[K any] struct {
-	r Receiver[Pair[K]]
-}
-
-func Values [T any] (r Receiver[T]) T {
-        return r.values
-}
-
-func (it Iterator[K]) Next() K {
-        return Values[Pair[K]](it.r).key
-}
-
-// A more complex test case testing type bounds (extracted from linalg.go2 and reduced to essence)
-
-type NumericAbs[T any] interface {
-	Abs() T
-}
-
-func AbsDifference[T NumericAbs[T]](x T) { panic(0) }
-
-// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
-// type OrderedAbs[T any] T
-// 
-// func (a OrderedAbs[T]) Abs() OrderedAbs[T]
-// 
-// func OrderedAbsDifference[T any](x T) {
-// 	AbsDifference(OrderedAbs[T](x))
-// }
-
-// same code, reduced to essence
-
-func g[P interface{ m() P }](x P) { panic(0) }
-
-// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
-// type T4[P any] P
-// 
-// func (_ T4[P]) m() T4[P]
-// 
-// func _[Q any](x Q) {
-// 	g(T4[Q](x))
-// }
-
-// Another test case that caused  problems in the past
-
-type T5[_ interface { a() }, _ interface{}] struct{}
-
-type A[P any] struct{ x P }
-
-func (_ A[P]) a() {}
-
-var _ T5[A[int], int]
-
-// Invoking methods with parameterized receiver types uses
-// type inference to determine the actual type arguments matching
-// the receiver type parameters from the actual receiver argument.
-// Go does implicit address-taking and dereferenciation depending
-// on the actual receiver and the method's receiver type. To make
-// type inference work, the type-checker matches "pointer-ness"
-// of the actual receiver and the method's receiver type.
-// The following code tests this mechanism.
-
-type R1[A any] struct{}
-func (_ R1[A]) vm()
-func (_ *R1[A]) pm()
-
-func _[T any](r R1[T], p *R1[T]) {
-	r.vm()
-	r.pm()
-	p.vm()
-	p.pm()
-}
-
-type R2[A, B any] struct{}
-func (_ R2[A, B]) vm()
-func (_ *R2[A, B]) pm()
-
-func _[T any](r R2[T, int], p *R2[string, T]) {
-	r.vm()
-	r.pm()
-	p.vm()
-	p.pm()
-}
-
-// It is ok to have multiple embedded unions.
-type _ interface {
-	m0()
-	~int | ~string | ~bool
-	~float32 | ~float64
-	m1()
-	m2()
-	~complex64 | ~complex128
-	~rune
-}
-
-// Type sets may contain each type at most once.
-type _ interface {
-	~int|~int /* ERROR overlapping terms ~int */
-	~int|int /* ERROR overlapping terms int */
-	int|int /* ERROR overlapping terms int */
-}
-
-type _ interface {
-	~struct{f int} | ~struct{g int} | ~struct /* ERROR overlapping terms */ {f int}
-}
-
-// Interface term lists can contain any type, incl. *Named types.
-// Verify that we use the underlying type(s) of the type(s) in the
-// term list when determining if an operation is permitted.
-
-type MyInt int
-func add1[T interface{MyInt}](x T) T {
-	return x + 1
-}
-
-type MyString string
-func double[T interface{MyInt|MyString}](x T) T {
-	return x + x
-}
-
-// Embedding of interfaces with term lists leads to interfaces
-// with term lists that are the intersection of the embedded
-// term lists.
-
-type E0 interface {
-	~int | ~bool | ~string
-}
-
-type E1 interface {
-	~int | ~float64 | ~string
-}
-
-type E2 interface {
-	~float64
-}
-
-type I0 interface {
-	E0
-}
-
-func f0[T I0]() {}
-var _ = f0[int]
-var _ = f0[bool]
-var _ = f0[string]
-var _ = f0[float64 /* ERROR does not implement I0 */ ]
-
-type I01 interface {
-	E0
-	E1
-}
-
-func f01[T I01]() {}
-var _ = f01[int]
-var _ = f01[bool /* ERROR does not implement I0 */ ]
-var _ = f01[string]
-var _ = f01[float64 /* ERROR does not implement I0 */ ]
-
-type I012 interface {
-	E0
-	E1
-	E2
-}
-
-func f012[T I012]() {}
-var _ = f012[int /* ERROR cannot implement I012.*empty type set */ ]
-var _ = f012[bool /* ERROR cannot implement I012.*empty type set */ ]
-var _ = f012[string /* ERROR cannot implement I012.*empty type set */ ]
-var _ = f012[float64 /* ERROR cannot implement I012.*empty type set */ ]
-
-type I12 interface {
-	E1
-	E2
-}
-
-func f12[T I12]() {}
-var _ = f12[int /* ERROR does not implement I12 */ ]
-var _ = f12[bool /* ERROR does not implement I12 */ ]
-var _ = f12[string /* ERROR does not implement I12 */ ]
-var _ = f12[float64]
-
-type I0_ interface {
-	E0
-	~int
-}
-
-func f0_[T I0_]() {}
-var _ = f0_[int]
-var _ = f0_[bool /* ERROR does not implement I0_ */ ]
-var _ = f0_[string /* ERROR does not implement I0_ */ ]
-var _ = f0_[float64 /* ERROR does not implement I0_ */ ]
-
-// Using a function instance as a type is an error.
-var _ f0 // ERROR not a type
-var _ f0 /* ERROR not a type */ [int]
-
-// Empty type sets can only be satisfied by empty type sets.
-type none interface {
-	// force an empty type set
-        int
-        string
-}
-
-func ff[T none]() {}
-func gg[T any]() {}
-func hh[T ~int]() {}
-
-func _[T none]() {
-	_ = ff[int /* ERROR cannot implement none \(empty type set\) */ ]
-	_ = ff[T]  // pathological but ok because T's type set is empty, too
-	_ = gg[int]
-	_ = gg[T]
-	_ = hh[int]
-	_ = hh[T]
-}
diff --git a/src/cmd/compile/internal/types2/testdata/check/typeinstcycles.go b/src/cmd/compile/internal/types2/testdata/check/typeinstcycles.go
deleted file mode 100644
index 74fe191..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/typeinstcycles.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-import "unsafe"
-
-func F1[T any](_ [unsafe.Sizeof(F1[int])]T) (res T)      { return }
-func F2[T any](_ T) (res [unsafe.Sizeof(F2[string])]int) { return }
-func F3[T any](_ [unsafe.Sizeof(F1[string])]int)         {}
diff --git a/src/cmd/compile/internal/types2/testdata/check/typeparams.go b/src/cmd/compile/internal/types2/testdata/check/typeparams.go
deleted file mode 100644
index 498d6f2..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/typeparams.go
+++ /dev/null
@@ -1,508 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-// import "io" // for type assertion tests
-
-var _ any // ok to use any anywhere
-func _[_ any, _ interface{any}](any) {
-        var _ any
-}
-
-func identity[T any](x T) T { return x }
-
-func _[_ any](x int) int { panic(0) }
-func _[T any](T /* ERROR redeclared */ T)() {}
-func _[T, T /* ERROR redeclared */ any]() {}
-
-// Constraints (incl. any) may be parenthesized.
-func _[_ (any)]() {}
-func _[_ (interface{})]() {}
-
-func reverse[T any](list []T) []T {
-        rlist := make([]T, len(list))
-        i := len(list)
-        for _, x := range list {
-                i--
-                rlist[i] = x
-        }
-        return rlist
-}
-
-var _ = reverse /* ERROR cannot use generic function reverse */
-var _ = reverse[int, float32 /* ERROR got 2 type arguments */ ] ([]int{1, 2, 3})
-var _ = reverse[int]([ /* ERROR cannot use */ ]float32{1, 2, 3})
-var f = reverse[chan int]
-var _ = f(0 /* ERROR cannot use 0 .* as \[\]chan int */ )
-
-func swap[A, B any](a A, b B) (B, A) { return b, a }
-
-var _ = swap /* ERROR single value is expected */ [int, float32](1, 2)
-var f32, i = swap[int, float32](swap[float32, int](1, 2))
-var _ float32 = f32
-var _ int = i
-
-func swapswap[A, B any](a A, b B) (A, B) {
-        return swap[B, A](b, a)
-}
-
-type F[A, B any] func(A, B) (B, A)
-
-func min[T interface{ ~int }](x, y T) T {
-        if x < y {
-                return x
-        }
-        return y
-}
-
-func _[T interface{~int | ~float32}](x, y T) bool { return x < y }
-func _[T any](x, y T) bool { return x /* ERROR cannot compare */ < y }
-func _[T interface{~int | ~float32 | ~bool}](x, y T) bool { return x /* ERROR cannot compare */ < y }
-
-func _[T C1[T]](x, y T) bool { return x /* ERROR cannot compare */ < y }
-func _[T C2[T]](x, y T) bool { return x < y }
-
-type C1[T any] interface{}
-type C2[T any] interface{ ~int | ~float32 }
-
-func new[T any]() *T {
-        var x T
-        return &x
-}
-
-var _ = new /* ERROR cannot use generic function new */
-var _ *int = new[int]()
-
-func _[T any](map[T /* ERROR invalid map key type T \(missing comparable constraint\) */]int) {} // w/o constraint we don't know if T is comparable
-
-func f1[T1 any](struct{T1 /* ERROR cannot be a .* type parameter */ }) int { panic(0) }
-var _ = f1[int](struct{T1}{})
-type T1 = int
-
-func f2[t1 any](struct{t1 /* ERROR cannot be a .* type parameter */ ; x float32}) int { panic(0) }
-var _ = f2[t1](struct{t1; x float32}{})
-type t1 = int
-
-
-func f3[A, B, C any](A, struct{x B}, func(A, struct{x B}, *C)) int { panic(0) }
-
-var _ = f3[int, rune, bool](1, struct{x rune}{}, nil)
-
-// indexing
-
-func _[T any] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
-func _[T interface{ ~int }] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
-func _[T interface{ ~string }] (x T, i int) { _ = x[i] }
-func _[T interface{ ~[]int }] (x T, i int) { _ = x[i] }
-func _[T interface{ ~[10]int | ~*[20]int | ~map[int]int }] (x T, i int) { _ = x /* ERROR cannot index */ [i] } // map and non-map types
-func _[T interface{ ~string | ~[]byte }] (x T, i int) { _ = x[i] }
-func _[T interface{ ~[]int | ~[1]rune }] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
-func _[T interface{ ~string | ~[]rune }] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
-
-// indexing with various combinations of map types in type sets (see issue #42616)
-func _[T interface{ ~[]E | ~map[int]E }, E any](x T, i int) { _ = x /* ERROR cannot index */ [i] } // map and non-map types
-func _[T interface{ ~[]E }, E any](x T, i int) { _ = &x[i] }
-func _[T interface{ ~map[int]E }, E any](x T, i int) { _, _ = x[i] } // comma-ok permitted
-func _[T interface{ ~map[int]E }, E any](x T, i int) { _ = &x /* ERROR cannot take address */ [i] }
-func _[T interface{ ~map[int]E | ~map[uint]E }, E any](x T, i int) { _ = x /* ERROR cannot index */ [i] } // different map element types
-func _[T interface{ ~[]E | ~map[string]E }, E any](x T, i int) { _ = x /* ERROR cannot index */ [i] } // map and non-map types
-
-// indexing with various combinations of array and other types in type sets
-func _[T interface{ [10]int }](x T, i int) { _ = x[i]; _ = x[9]; _ = x[10 /* ERROR out of bounds */ ] }
-func _[T interface{ [10]byte | string }](x T, i int) { _ = x[i]; _ = x[9]; _ = x[10 /* ERROR out of bounds */ ] }
-func _[T interface{ [10]int | *[20]int | []int }](x T, i int) { _ = x[i]; _ = x[9]; _ = x[10 /* ERROR out of bounds */ ] }
-
-// indexing with strings and non-variable arrays (assignment not permitted)
-func _[T string](x T) { _ = x[0]; x /* ERROR cannot assign */ [0] = 0 }
-func _[T []byte | string](x T) { x /* ERROR cannot assign */ [0] = 0 }
-func _[T [10]byte]() { f := func() (x T) { return }; f /* ERROR cannot assign */ ()[0] = 0 }
-func _[T [10]byte]() { f := func() (x *T) { return }; f /* ERROR cannot index */ ()[0] = 0 }
-func _[T [10]byte]() { f := func() (x *T) { return }; (*f())[0] = 0 }
-func _[T *[10]byte]() { f := func() (x T) { return }; f()[0] = 0 }
-
-// slicing
-
-func _[T interface{ ~[10]E }, E any] (x T, i, j, k int) { var _ []E = x[i:j] }
-func _[T interface{ ~[10]E }, E any] (x T, i, j, k int) { var _ []E = x[i:j:k] }
-func _[T interface{ ~[]byte }] (x T, i, j, k int) { var _ T = x[i:j] }
-func _[T interface{ ~[]byte }] (x T, i, j, k int) { var _ T = x[i:j:k] }
-func _[T interface{ ~string }] (x T, i, j, k int) { var _ T = x[i:j] }
-func _[T interface{ ~string }] (x T, i, j, k int) { var _ T = x[i:j:k /* ERROR 3-index slice of string */ ] }
-
-type myByte1 []byte
-type myByte2 []byte
-func _[T interface{ []byte | myByte1 | myByte2 }] (x T, i, j, k int) { var _ T = x[i:j:k] }
-func _[T interface{ []byte | myByte1 | []int }] (x T, i, j, k int) { var _ T = x[ /* ERROR no core type */ i:j:k] }
-
-func _[T interface{ []byte | myByte1 | myByte2 | string }] (x T, i, j, k int) { var _ T = x[i:j] }
-func _[T interface{ []byte | myByte1 | myByte2 | string }] (x T, i, j, k int) { var _ T = x[i:j:k /* ERROR 3-index slice of string */ ] }
-func _[T interface{ []byte | myByte1 | []int | string }] (x T, i, j, k int) { var _ T = x[ /* ERROR no core type */ i:j] }
-
-// len/cap built-ins
-
-func _[T any](x T) { _ = len(x /* ERROR invalid argument */ ) }
-func _[T interface{ ~int }](x T) { _ = len(x /* ERROR invalid argument */ ) }
-func _[T interface{ ~string | ~[]byte | ~int }](x T) { _ = len(x /* ERROR invalid argument */ ) }
-func _[T interface{ ~string }](x T) { _ = len(x) }
-func _[T interface{ ~[10]int }](x T) { _ = len(x) }
-func _[T interface{ ~[]byte }](x T) { _ = len(x) }
-func _[T interface{ ~map[int]int }](x T) { _ = len(x) }
-func _[T interface{ ~chan int }](x T) { _ = len(x) }
-func _[T interface{ ~string | ~[]byte | ~chan int }](x T) { _ = len(x) }
-
-func _[T any](x T) { _ = cap(x /* ERROR invalid argument */ ) }
-func _[T interface{ ~int }](x T) { _ = cap(x /* ERROR invalid argument */ ) }
-func _[T interface{ ~string | ~[]byte | ~int }](x T) { _ = cap(x /* ERROR invalid argument */ ) }
-func _[T interface{ ~string }](x T) { _ = cap(x /* ERROR invalid argument */ ) }
-func _[T interface{ ~[10]int }](x T) { _ = cap(x) }
-func _[T interface{ ~[]byte }](x T) { _ = cap(x) }
-func _[T interface{ ~map[int]int }](x T) { _ = cap(x /* ERROR invalid argument */ ) }
-func _[T interface{ ~chan int }](x T) { _ = cap(x) }
-func _[T interface{ ~[]byte | ~chan int }](x T) { _ = cap(x) }
-
-// range iteration
-
-func _[T interface{}](x T) {
-        for range x /* ERROR cannot range */ {}
-}
-
-type myString string
-
-func _[
-        B1 interface{ string },
-        B2 interface{ string | myString },
-
-        C1 interface{ chan int },
-        C2 interface{ chan int | <-chan int },
-        C3 interface{ chan<- int },
-
-        S1 interface{ []int },
-        S2 interface{ []int | [10]int },
-
-        A1 interface{ [10]int },
-        A2 interface{ [10]int | []int },
-
-        P1 interface{ *[10]int },
-        P2 interface{ *[10]int | *[]int },
-
-        M1 interface{ map[string]int },
-        M2 interface{ map[string]int | map[string]string },
-]() {
-        var b0 string
-        for range b0 {}
-        for _ = range b0 {}
-        for _, _ = range b0 {}
-
-        var b1 B1
-        for range b1 {}
-        for _ = range b1 {}
-        for _, _ = range b1 {}
-
-        var b2 B2
-        for range b2 {}
-
-        var c0 chan int
-        for range c0 {}
-        for _ = range c0 {}
-        for _, _ /* ERROR permits only one iteration variable */ = range c0 {}
-
-        var c1 C1
-        for range c1 {}
-        for _ = range c1 {}
-        for _, _ /* ERROR permits only one iteration variable */ = range c1 {}
-
-        var c2 C2
-        for range c2 {}
-
-        var c3 C3
-        for range c3 /* ERROR receive from send-only channel */ {}
-
-        var s0 []int
-        for range s0 {}
-        for _ = range s0 {}
-        for _, _ = range s0 {}
-
-        var s1 S1
-        for range s1 {}
-        for _ = range s1 {}
-        for _, _ = range s1 {}
-
-        var s2 S2
-        for range s2 /* ERROR cannot range over s2.*no core type */ {}
-
-        var a0 []int
-        for range a0 {}
-        for _ = range a0 {}
-        for _, _ = range a0 {}
-
-        var a1 A1
-        for range a1 {}
-        for _ = range a1 {}
-        for _, _ = range a1 {}
-
-        var a2 A2
-        for range a2 /* ERROR cannot range over a2.*no core type */ {}
-
-        var p0 *[10]int
-        for range p0 {}
-        for _ = range p0 {}
-        for _, _ = range p0 {}
-
-        var p1 P1
-        for range p1 {}
-        for _ = range p1 {}
-        for _, _ = range p1 {}
-
-        var p2 P2
-        for range p2 /* ERROR cannot range over p2.*no core type */ {}
-
-        var m0 map[string]int
-        for range m0 {}
-        for _ = range m0 {}
-        for _, _ = range m0 {}
-
-        var m1 M1
-        for range m1 {}
-        for _ = range m1 {}
-        for _, _ = range m1 {}
-
-        var m2 M2
-        for range m2 /* ERROR cannot range over m2.*no core type */ {}
-}
-
-// type inference checks
-
-var _ = new() /* ERROR cannot infer T */
-
-func f4[A, B, C any](A, B) C { panic(0) }
-
-var _ = f4(1, 2) /* ERROR cannot infer C */
-var _ = f4[int, float32, complex128](1, 2)
-
-func f5[A, B, C any](A, []*B, struct{f []C}) int { panic(0) }
-
-var _ = f5[int, float32, complex128](0, nil, struct{f []complex128}{})
-var _ = f5(0, nil, struct{f []complex128}{}) // ERROR cannot infer
-var _ = f5(0, []*float32{new[float32]()}, struct{f []complex128}{})
-
-func f6[A any](A, []A) int { panic(0) }
-
-var _ = f6(0, nil)
-
-func f6nil[A any](A) int { panic(0) }
-
-var _ = f6nil(nil) // ERROR cannot infer
-
-// type inference with variadic functions
-
-func f7[T any](...T) T { panic(0) }
-
-var _ int = f7() /* ERROR cannot infer T */
-var _ int = f7(1)
-var _ int = f7(1, 2)
-var _ int = f7([]int{}...)
-var _ int = f7 /* ERROR cannot use */ ([]float64{}...)
-var _ float64 = f7([]float64{}...)
-var _ = f7[float64](1, 2.3)
-var _ = f7(float64(1), 2.3)
-var _ = f7(1, 2.3 /* ERROR does not match */ )
-var _ = f7(1.2, 3 /* ERROR does not match */ )
-
-func f8[A, B any](A, B, ...B) int { panic(0) }
-
-var _ = f8(1 /* ERROR not enough arguments */ )
-var _ = f8(1, 2.3)
-var _ = f8(1, 2.3, 3.4, 4.5)
-var _ = f8(1, 2.3, 3.4, 4 /* ERROR does not match */ )
-var _ = f8[int, float64](1, 2.3, 3.4, 4)
-
-var _ = f8[int, float64](0, 0, nil...) // test case for #18268
-
-// init functions cannot have type parameters
-
-func init() {}
-func init[_ /* ERROR func init must have no type parameters */ any]() {}
-func init[P /* ERROR func init must have no type parameters */ any]() {}
-
-type T struct {}
-
-func (T) m1() {}
-func (T) m2[ /* ERROR method must have no type parameters */ _ any]() {}
-func (T) m3[ /* ERROR method must have no type parameters */ P any]() {}
-
-// type inference across parameterized types
-
-type S1[P any] struct { f P }
-
-func f9[P any](x S1[P]) {}
-
-func _() {
-        f9[int](S1[int]{42})
-	f9(S1[int]{42})
-}
-
-type S2[A, B, C any] struct{}
-
-func f10[X, Y, Z any](a S2[X, int, Z], b S2[X, Y, bool]) {}
-
-func _[P any]() {
-        f10[int, float32, string](S2[int, int, string]{}, S2[int, float32, bool]{})
-        f10(S2[int, int, string]{}, S2[int, float32, bool]{})
-        f10(S2[P, int, P]{}, S2[P, float32, bool]{})
-}
-
-// corner case for type inference
-// (was bug: after instanting f11, the type-checker didn't mark f11 as non-generic)
-
-func f11[T any]() {}
-
-func _() {
-	f11[int]()
-}
-
-// the previous example was extracted from
-
-// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
-// func f12[T interface{m() T}]() {}
-// 
-// type A[T any] T
-// 
-// func (a A[T]) m() A[T]
-// 
-// func _[T any]() {
-// 	f12[A[T]]()
-// }
-
-// method expressions
-
-func (_ S1[P]) m()
-
-func _() {
-	m := S1[int].m
-	m(struct { f int }{42})
-}
-
-func _[T any] (x T) {
-        m := S1[T].m
-        m(S1[T]{x})
-}
-
-type I1[A any] interface {
-        m1(A)
-}
-
-var _ I1[int] = r1[int]{}
-
-type r1[T any] struct{}
-
-func (_ r1[T]) m1(T)
-
-type I2[A, B any] interface {
-        m1(A)
-        m2(A) B
-}
-
-var _ I2[int, float32] = R2[int, float32]{}
-
-type R2[P, Q any] struct{}
-
-func (_ R2[X, Y]) m1(X)
-func (_ R2[X, Y]) m2(X) Y
-
-// type assertions and type switches over generic types
-// NOTE: These are currently disabled because it's unclear what the correct
-// approach is, and one can always work around by assigning the variable to
-// an interface first.
-
-// // ReadByte1 corresponds to the ReadByte example in the draft design.
-// func ReadByte1[T io.Reader](r T) (byte, error) {
-// 	if br, ok := r.(io.ByteReader); ok {
-// 		return br.ReadByte()
-// 	}
-// 	var b [1]byte
-// 	_, err := r.Read(b[:])
-// 	return b[0], err
-// }
-//
-// // ReadBytes2 is like ReadByte1 but uses a type switch instead.
-// func ReadByte2[T io.Reader](r T) (byte, error) {
-//         switch br := r.(type) {
-//         case io.ByteReader:
-//                 return br.ReadByte()
-//         }
-// 	var b [1]byte
-// 	_, err := r.Read(b[:])
-// 	return b[0], err
-// }
-//
-// // type assertions and type switches over generic types are strict
-// type I3 interface {
-//         m(int)
-// }
-//
-// type I4 interface {
-//         m() int // different signature from I3.m
-// }
-//
-// func _[T I3](x I3, p T) {
-//         // type assertions and type switches over interfaces are not strict
-//         _ = x.(I4)
-//         switch x.(type) {
-//         case I4:
-//         }
-//
-//         // type assertions and type switches over generic types are strict
-//         _ = p /* ERROR cannot have dynamic type I4 */.(I4)
-//         switch p.(type) {
-//         case I4 /* ERROR cannot have dynamic type I4 */ :
-//         }
-// }
-
-// type assertions and type switches over generic types lead to errors for now
-
-func _[T any](x T) {
-	_ = x /* ERROR cannot use type assertion */ .(int)
-	switch x /* ERROR cannot use type switch */ .(type) {
-	}
-
-	// work-around
-	var t interface{} = x
-	_ = t.(int)
-	switch t.(type) {
-	}
-}
-
-func _[T interface{~int}](x T) {
-	_ = x /* ERROR cannot use type assertion */ .(int)
-	switch x /* ERROR cannot use type switch */ .(type) {
-	}
-
-	// work-around
-	var t interface{} = x
-	_ = t.(int)
-	switch t.(type) {
-	}
-}
-
-// error messages related to type bounds mention those bounds
-type C[P any] interface{}
-
-func _[P C[P]] (x P) {
-	x.m /* ERROR x.m undefined */ ()
-}
-
-type I interface {}
-
-func _[P I] (x P) {
-	x.m /* ERROR type P has no field or method m */ ()
-}
-
-func _[P interface{}] (x P) {
-	x.m /* ERROR type P has no field or method m */ ()
-}
-
-func _[P any] (x P) {
-	x.m /* ERROR type P has no field or method m */ ()
-}
diff --git a/src/cmd/compile/internal/types2/testdata/check/unions.go b/src/cmd/compile/internal/types2/testdata/check/unions.go
deleted file mode 100644
index bcd7de6..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/unions.go
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Check that overlong unions don't bog down type checking.
-// Disallow them for now.
-
-package p
-
-type t int
-
-type (
-	t00 t; t01 t; t02 t; t03 t; t04 t; t05 t; t06 t; t07 t; t08 t; t09 t
-	t10 t; t11 t; t12 t; t13 t; t14 t; t15 t; t16 t; t17 t; t18 t; t19 t
-	t20 t; t21 t; t22 t; t23 t; t24 t; t25 t; t26 t; t27 t; t28 t; t29 t
-	t30 t; t31 t; t32 t; t33 t; t34 t; t35 t; t36 t; t37 t; t38 t; t39 t
-	t40 t; t41 t; t42 t; t43 t; t44 t; t45 t; t46 t; t47 t; t48 t; t49 t
-	t50 t; t51 t; t52 t; t53 t; t54 t; t55 t; t56 t; t57 t; t58 t; t59 t
-	t60 t; t61 t; t62 t; t63 t; t64 t; t65 t; t66 t; t67 t; t68 t; t69 t
-	t70 t; t71 t; t72 t; t73 t; t74 t; t75 t; t76 t; t77 t; t78 t; t79 t
-	t80 t; t81 t; t82 t; t83 t; t84 t; t85 t; t86 t; t87 t; t88 t; t89 t
-	t90 t; t91 t; t92 t; t93 t; t94 t; t95 t; t96 t; t97 t; t98 t; t99 t
-)
-
-type u99 interface {
-	t00|t01|t02|t03|t04|t05|t06|t07|t08|t09|
-	t10|t11|t12|t13|t14|t15|t16|t17|t18|t19|
-	t20|t21|t22|t23|t24|t25|t26|t27|t28|t29|
-	t30|t31|t32|t33|t34|t35|t36|t37|t38|t39|
-	t40|t41|t42|t43|t44|t45|t46|t47|t48|t49|
-	t50|t51|t52|t53|t54|t55|t56|t57|t58|t59|
-	t60|t61|t62|t63|t64|t65|t66|t67|t68|t69|
-	t70|t71|t72|t73|t74|t75|t76|t77|t78|t79|
-	t80|t81|t82|t83|t84|t85|t86|t87|t88|t89|
-	t90|t91|t92|t93|t94|t95|t96|t97|t98
-}
-
-type u100a interface {
-	u99|float32
-}
-
-type u100b interface {
-	u99|float64
-}
-
-type u101 interface {
-	t00|t01|t02|t03|t04|t05|t06|t07|t08|t09|
-	t10|t11|t12|t13|t14|t15|t16|t17|t18|t19|
-	t20|t21|t22|t23|t24|t25|t26|t27|t28|t29|
-	t30|t31|t32|t33|t34|t35|t36|t37|t38|t39|
-	t40|t41|t42|t43|t44|t45|t46|t47|t48|t49|
-	t50|t51|t52|t53|t54|t55|t56|t57|t58|t59|
-	t60|t61|t62|t63|t64|t65|t66|t67|t68|t69|
-	t70|t71|t72|t73|t74|t75|t76|t77|t78|t79|
-	t80|t81|t82|t83|t84|t85|t86|t87|t88|t89|
-	t90|t91|t92|t93|t94|t95|t96|t97|t98|t99|
-        int // ERROR cannot handle more than 100 union terms
-}
-
-type u102 interface {
-        int /* ERROR cannot handle more than 100 union terms */ |string|u100a
-}
-
-type u200 interface {
-        u100a /* ERROR cannot handle more than 100 union terms */ |u100b
-}
diff --git a/src/cmd/compile/internal/types2/testdata/check/vardecl.go b/src/cmd/compile/internal/types2/testdata/check/vardecl.go
deleted file mode 100644
index c3fe61c..0000000
--- a/src/cmd/compile/internal/types2/testdata/check/vardecl.go
+++ /dev/null
@@ -1,214 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package vardecl
-
-// Prerequisites.
-import "math"
-func f() {}
-func g() (x, y int) { return }
-var m map[string]int
-
-// Var decls must have a type or an initializer.
-var _ int
-var _, _ int
-
-var _ /* ERROR "expecting type" */
-var _, _ /* ERROR "expecting type" */
-var _, _, _ /* ERROR "expecting type" */
-
-// The initializer must be an expression.
-var _ = int /* ERROR "not an expression" */
-var _ = f /* ERROR "used as value" */ ()
-
-// Identifier and expression arity must match.
-var _, _ = 1, 2
-var _ = 1, 2 /* ERROR "extra init expr 2" */
-var _, _ = 1 /* ERROR "cannot initialize [0-9]+ variables with [0-9]+ values" */
-var _, _, _ /* ERROR "missing init expr for _" */ = 1, 2
-
-var _ = g /* ERROR "2-valued g" */ ()
-var _, _ = g()
-var _, _, _ = g /* ERROR "cannot initialize [0-9]+ variables with [0-9]+ values" */ ()
-
-var _ = m["foo"]
-var _, _ = m["foo"]
-var _, _, _ = m  /* ERROR "cannot initialize [0-9]+ variables with [0-9]+ values" */ ["foo"]
-
-var _, _ int = 1, 2
-var _ int = 1, 2 /* ERROR "extra init expr 2" */
-var _, _ int = 1 /* ERROR "cannot initialize [0-9]+ variables with [0-9]+ values" */
-var _, _, _ /* ERROR "missing init expr for _" */ int = 1, 2
-
-var (
-	_, _ = 1, 2
-	_ = 1, 2 /* ERROR "extra init expr 2" */
-	_, _ = 1 /* ERROR "cannot initialize [0-9]+ variables with [0-9]+ values" */
-	_, _, _ /* ERROR "missing init expr for _" */ = 1, 2
-
-	_ = g /* ERROR "2-valued g" */ ()
-	_, _ = g()
-	_, _, _ = g /* ERROR "cannot initialize [0-9]+ variables with [0-9]+ values" */ ()
-
-	_ = m["foo"]
-	_, _ = m["foo"]
-	_, _, _ = m /* ERROR "cannot initialize [0-9]+ variables with [0-9]+ values" */ ["foo"]
-
-	_, _ int = 1, 2
-	_ int = 1, 2 /* ERROR "extra init expr 2" */
-	_, _ int = 1 /* ERROR "cannot initialize [0-9]+ variables with [0-9]+ values" */
-	_, _, _ /* ERROR "missing init expr for _" */ int = 1, 2
-)
-
-// Variables declared in function bodies must be 'used'.
-type T struct{}
-func (r T) _(a, b, c int) (u, v, w int) {
-	var x1 /* ERROR "declared but not used" */ int
-	var x2 /* ERROR "declared but not used" */ int
-	x1 = 1
-	(x2) = 2
-
-	y1 /* ERROR "declared but not used" */ := 1
-	y2 /* ERROR "declared but not used" */ := 2
-	y1 = 1
-	(y1) = 2
-
-	{
-		var x1 /* ERROR "declared but not used" */ int
-		var x2 /* ERROR "declared but not used" */ int
-		x1 = 1
-		(x2) = 2
-
-		y1 /* ERROR "declared but not used" */ := 1
-		y2 /* ERROR "declared but not used" */ := 2
-		y1 = 1
-		(y1) = 2
-	}
-
-	if x /* ERROR "declared but not used" */ := 0; a < b {}
-
-	switch x /* ERROR "declared but not used" */, y := 0, 1; a {
-	case 0:
-		_ = y
-	case 1:
-		x /* ERROR "declared but not used" */ := 0
-	}
-
-	var t interface{}
-	switch t /* ERROR "declared but not used" */ := t.(type) {}
-
-	switch t /* ERROR "declared but not used" */ := t.(type) {
-	case int:
-	}
-
-	switch t /* ERROR "declared but not used" */ := t.(type) {
-	case int:
-	case float32, complex64:
-		t = nil
-	}
-
-	switch t := t.(type) {
-	case int:
-	case float32, complex64:
-		_ = t
-	}
-
-	switch t := t.(type) {
-	case int:
-	case float32:
-	case string:
-		_ = func() string {
-			return t
-		}
-	}
-
-	switch t := t; t /* ERROR "declared but not used" */ := t.(type) {}
-
-	var z1 /* ERROR "declared but not used" */ int
-	var z2 int
-	_ = func(a, b, c int) (u, v, w int) {
-		z1 = a
-		(z1) = b
-		a = z2
-		return
-	}
-
-	var s []int
-	var i /* ERROR "declared but not used" */ , j int
-	for i, j = range s {
-		_ = j
-	}
-
-	for i, j /* ERROR "declared but not used" */ := range s {
-		_ = func() int {
-			return i
-		}
-	}
-	return
-}
-
-// Unused variables in function literals must lead to only one error (issue #22524).
-func _() {
-	_ = func() {
-		var x /* ERROR declared but not used */ int
-	}
-}
-
-// Invalid variable declarations must not lead to "declared but not used errors".
-func _() {
-	var a x                        // ERROR undeclared name: x
-	var b = x                      // ERROR undeclared name: x
-	var c int = x                  // ERROR undeclared name: x
-	var d, e, f x                  /* ERROR x */ /* ERROR x */ /* ERROR x */
-	var g, h, i = x, x, x          /* ERROR x */ /* ERROR x */ /* ERROR x */
-	var j, k, l float32 = x, x, x  /* ERROR x */ /* ERROR x */ /* ERROR x */
-	// but no "declared but not used" errors
-}
-
-// Invalid (unused) expressions must not lead to spurious "declared but not used errors".
-func _() {
-	var a, b, c int
-	var x, y int
-	x, y = a /* ERROR cannot assign [0-9]+ values to [0-9]+ variables */ , b, c
-	_ = x
-	_ = y
-}
-
-func _() {
-	var x int
-	return x /* ERROR too many return values */
-	return math /* ERROR too many return values */ .Sin(0)
-}
-
-func _() int {
-	var x, y int
-	return x, y /* ERROR too many return values */
-}
-
-// Short variable declarations must declare at least one new non-blank variable.
-func _() {
-	_ := /* ERROR no new variables */ 0
-	_, a := 0, 1
-	_, a := /* ERROR no new variables */ 0, 1
-	_, a, b := 0, 1, 2
-	_, _, _ := /* ERROR no new variables */ 0, 1, 2
-
-	_ = a
-	_ = b
-}
-
-// Test case for variables depending on function literals (see also #22992).
-var A /* ERROR initialization cycle */ = func() int { return A }()
-
-func _() {
-	// The function literal below must not see a.
-	var a = func() int { return a /* ERROR "undeclared name" */ }()
-	var _ = func() int { return a }()
-
-	// The function literal below must not see x, y, or z.
-	var x, y, z = 0, 1, func() int { return x /* ERROR "undeclared name" */ + y /* ERROR "undeclared name" */ + z /* ERROR "undeclared name" */ }()
-	_, _, _ = x, y, z
-}
-
-// TODO(gri) consolidate other var decl checks in this file
\ No newline at end of file
diff --git a/src/cmd/compile/internal/types2/testdata/examples/constraints.go b/src/cmd/compile/internal/types2/testdata/examples/constraints.go
deleted file mode 100644
index 5b14489..0000000
--- a/src/cmd/compile/internal/types2/testdata/examples/constraints.go
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file shows some examples of generic constraint interfaces.
-
-package p
-
-type MyInt int
-
-type (
-	// Arbitrary types may be embedded like interfaces.
-	_ interface{int}
-	_ interface{~int}
-
-	// Types may be combined into a union.
-	union interface{int|~string}
-
-	// Union terms must describe disjoint (non-overlapping) type sets.
-	_ interface{int|int /* ERROR overlapping terms int */ }
-	_ interface{int|~ /* ERROR overlapping terms ~int */ int }
-	_ interface{~int|~ /* ERROR overlapping terms ~int */ int }
-	_ interface{~int|MyInt /* ERROR overlapping terms p.MyInt and ~int */ }
-	_ interface{int|any}
-	_ interface{int|~string|union}
-	_ interface{int|~string|interface{int}}
-	_ interface{union|int}   // interfaces (here: union) are ignored when checking for overlap
-	_ interface{union|union} // ditto
-
-	// For now we do not permit interfaces with methods in unions.
-	_ interface{~ /* ERROR invalid use of ~ */ any}
-	_ interface{int|interface /* ERROR cannot use .* in union */ { m() }}
-)
-
-type (
-	// Tilde is not permitted on defined types or interfaces.
-	foo int
-	bar any
-	_ interface{foo}
-	_ interface{~ /* ERROR invalid use of ~ */ foo }
-	_ interface{~ /* ERROR invalid use of ~ */ bar }
-)
-
-// Stand-alone type parameters are not permitted as elements or terms in unions.
-type (
-	_[T interface{ *T } ] struct{}        // ok
-	_[T interface{ int | *T } ] struct{}  // ok
-	_[T interface{ T /* ERROR term cannot be a type parameter */ } ] struct{}
-	_[T interface{ ~T /* ERROR type in term ~T cannot be a type parameter */ } ] struct{}
-	_[T interface{ int|T /* ERROR term cannot be a type parameter */ }] struct{}
-)
-
-// Multiple embedded union elements are intersected. The order in which they
-// appear in the interface doesn't matter since intersection is a symmetric
-// operation.
-
-type myInt1 int
-type myInt2 int
-
-func _[T interface{ myInt1|myInt2; ~int }]() T { return T(0) }
-func _[T interface{ ~int; myInt1|myInt2 }]() T { return T(0) }
-
-// Here the intersections are empty - there's no type that's in the type set of T.
-func _[T interface{ myInt1|myInt2; int }]() T { return T(0 /* ERROR cannot convert */ ) }
-func _[T interface{ int; myInt1|myInt2 }]() T { return T(0 /* ERROR cannot convert */ ) }
-
-// Union elements may be interfaces as long as they don't define
-// any methods or embed comparable.
-
-type (
-	Integer interface{ ~int|~int8|~int16|~int32|~int64 }
-	Unsigned interface{ ~uint|~uint8|~uint16|~uint32|~uint64 }
-	Floats interface{ ~float32|~float64 }
-	Complex interface{ ~complex64|~complex128 }
-	Number interface{ Integer|Unsigned|Floats|Complex }
-	Ordered interface{ Integer|Unsigned|Floats|~string }
-
-	_ interface{ Number | error /* ERROR cannot use error in union */ }
-	_ interface{ Ordered | comparable /* ERROR cannot use comparable in union */ }
-)
diff --git a/src/cmd/compile/internal/types2/testdata/examples/functions.go b/src/cmd/compile/internal/types2/testdata/examples/functions.go
deleted file mode 100644
index d50f79d..0000000
--- a/src/cmd/compile/internal/types2/testdata/examples/functions.go
+++ /dev/null
@@ -1,219 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file shows some examples of type-parameterized functions.
-
-package p
-
-// Reverse is a generic function that takes a []T argument and
-// reverses that slice in place.
-func Reverse[T any](list []T) {
-	i := 0
-	j := len(list)-1
-	for i < j {
-		list[i], list[j] = list[j], list[i]
-		i++
-		j--
-	}
-}
-
-func _() {
-	// Reverse can be called with an explicit type argument.
-	Reverse[int](nil)
-	Reverse[string]([]string{"foo", "bar"})
-	Reverse[struct{x, y int}]([]struct{x, y int}{{1, 2}, {2, 3}, {3, 4}})
-
-	// Since the type parameter is used for an incoming argument,
-	// it can be inferred from the provided argument's type.
-	Reverse([]string{"foo", "bar"})
-	Reverse([]struct{x, y int}{{1, 2}, {2, 3}, {3, 4}})
-
-	// But the incoming argument must have a type, even if it's a
-	// default type. An untyped nil won't work.
-	// Reverse(nil) // this won't type-check
-
-	// A typed nil will work, though.
-	Reverse([]int(nil))
-}
-
-// Certain functions, such as the built-in `new` could be written using
-// type parameters.
-func new[T any]() *T {
-	var x T
-	return &x
-}
-
-// When calling our own `new`, we need to pass the type parameter
-// explicitly since there is no (value) argument from which the
-// result type could be inferred. We don't try to infer the
-// result type from the assignment to keep things simple and
-// easy to understand.
-var _ = new[int]()
-var _ *float64 = new[float64]() // the result type is indeed *float64
-
-// A function may have multiple type parameters, of course.
-func foo[A, B, C any](a A, b []B, c *C) B {
-	// do something here
-	return b[0]
-}
-
-// As before, we can pass type parameters explicitly.
-var s = foo[int, string, float64](1, []string{"first"}, new[float64]())
-
-// Or we can use type inference.
-var _ float64 = foo(42, []float64{1.0}, &s)
-
-// Type inference works in a straight-forward manner even
-// for variadic functions.
-func variadic[A, B any](A, B, ...B) int { panic(0) }
-
-// var _ = variadic(1) // ERROR not enough arguments
-var _ = variadic(1, 2.3)
-var _ = variadic(1, 2.3, 3.4, 4.5)
-var _ = variadic[int, float64](1, 2.3, 3.4, 4)
-
-// Type inference also works in recursive function calls where
-// the inferred type is the type parameter of the caller.
-func f1[T any](x T) {
-	f1(x)
-}
-
-func f2a[T any](x, y T) {
-	f2a(x, y)
-}
-
-func f2b[T any](x, y T) {
-	f2b(y, x)
-}
-
-func g2a[P, Q any](x P, y Q) {
-	g2a(x, y)
-}
-
-func g2b[P, Q any](x P, y Q) {
-	g2b(y, x)
-}
-
-// Here's an example of a recursive function call with variadic
-// arguments and type inference inferring the type parameter of
-// the caller (i.e., itself).
-func max[T interface{ ~int }](x ...T) T {
-	var x0 T
-	if len(x) > 0 {
-		x0 = x[0]
-	}
-	if len(x) > 1 {
-		x1 := max(x[1:]...)
-		if x1 > x0 {
-			return x1
-		}
-	}
-	return x0
-}
-
-// When inferring channel types, the channel direction is ignored
-// for the purpose of type inference. Once the type has been in-
-// fered, the usual parameter passing rules are applied.
-// Thus even if a type can be inferred successfully, the function
-// call may not be valid.
-
-func fboth[T any](chan T) {}
-func frecv[T any](<-chan T) {}
-func fsend[T any](chan<- T) {}
-
-func _() {
-	var both chan int
-	var recv <-chan int
-	var send chan<-int
-
-	fboth(both)
-	fboth(recv /* ERROR cannot use */ )
-	fboth(send /* ERROR cannot use */ )
-
-	frecv(both)
-	frecv(recv)
-	frecv(send /* ERROR cannot use */ )
-
-	fsend(both)
-	fsend(recv /* ERROR cannot use */)
-	fsend(send)
-}
-
-func ffboth[T any](func(chan T)) {}
-func ffrecv[T any](func(<-chan T)) {}
-func ffsend[T any](func(chan<- T)) {}
-
-func _() {
-	var both func(chan int)
-	var recv func(<-chan int)
-	var send func(chan<- int)
-
-	ffboth(both)
-	ffboth(recv /* ERROR cannot use */ )
-	ffboth(send /* ERROR cannot use */ )
-
-	ffrecv(both /* ERROR cannot use */ )
-	ffrecv(recv)
-	ffrecv(send /* ERROR cannot use */ )
-
-	ffsend(both /* ERROR cannot use */ )
-	ffsend(recv /* ERROR cannot use */ )
-	ffsend(send)
-}
-
-// When inferring elements of unnamed composite parameter types,
-// if the arguments are defined types, use their underlying types.
-// Even though the matching types are not exactly structurally the
-// same (one is a type literal, the other a named type), because
-// assignment is permitted, parameter passing is permitted as well,
-// so type inference should be able to handle these cases well.
-
-func g1[T any]([]T) {}
-func g2[T any]([]T, T) {}
-func g3[T any](*T, ...T) {}
-
-func _() {
-	type intSlize []int
-	g1([]int{})
-	g1(intSlize{})
-	g2(nil, 0)
-
-	type myString string
-	var s1 string
-	g3(nil, "1", myString("2"), "3")
-	g3(& /* ERROR does not match */ s1, "1", myString("2"), "3")
-	_ = s1
-
-	type myStruct struct{x int}
-	var s2 myStruct
-	g3(nil, struct{x int}{}, myStruct{})
-	g3(&s2, struct{x int}{}, myStruct{})
-	g3(nil, myStruct{}, struct{x int}{})
-	g3(&s2, myStruct{}, struct{x int}{})
-}
-
-// Here's a realistic example.
-
-func append[T any](s []T, t ...T) []T { panic(0) }
-
-func _() {
-	var f func()
-	type Funcs []func()
-	var funcs Funcs
-	_ = append(funcs, f)
-}
-
-// Generic type declarations cannot have empty type parameter lists
-// (that would indicate a slice type). Thus, generic functions cannot
-// have empty type parameter lists, either. This is a syntax error.
-
-func h[] /* ERROR empty type parameter list */ () {}
-
-func _() {
-	h[] /* ERROR operand */ ()
-}
-
-// Parameterized functions must have a function body.
-
-func _ /* ERROR missing function body */ [P any]()
diff --git a/src/cmd/compile/internal/types2/testdata/examples/inference.go b/src/cmd/compile/internal/types2/testdata/examples/inference.go
deleted file mode 100644
index e3d6bfb..0000000
--- a/src/cmd/compile/internal/types2/testdata/examples/inference.go
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file shows some examples of type inference.
-
-package p
-
-type Ordered interface {
-	~int|~float64|~string
-}
-
-func min[T Ordered](x, y T) T { panic(0) }
-
-func _() {
-	// min can be called with explicit instantiation.
-	_ = min[int](1, 2)
-
-	// Alternatively, the type argument can be inferred from
-	// one of the arguments. Untyped arguments will be considered
-	// last.
-	var x int
-	_ = min(x, x)
-	_ = min(x, 1)
-	_ = min(x, 1.0)
-	_ = min(1, 2)
-	_ = min(1, 2.3 /* ERROR default type float64 .* does not match */ )
-
-	var y float64
-	_ = min(1, y)
-	_ = min(1.2, y)
-	_ = min(1.2, 3.4)
-	_ = min(1.2, 3 /* ERROR default type int .* does not match */ )
-
-	var s string
-	_ = min(s, "foo")
-	_ = min("foo", "bar")
-}
-
-func mixed[T1, T2, T3 any](T1, T2, T3) {}
-
-func _() {
-	// mixed can be called with explicit instantiation.
-	mixed[int, string, bool](0, "", false)
-
-	// Alternatively, partial type arguments may be provided
-	// (from left to right), and the other may be inferred.
-	mixed[int, string](0, "", false)
-	mixed[int](0, "", false)
-	mixed(0, "", false)
-
-	// Provided type arguments always take precedence over
-	// inferred types.
-	mixed[int, string](1.1 /* ERROR cannot use 1.1 */ , "", false)
-}
-
-func related1[Slice interface{~[]Elem}, Elem any](s Slice, e Elem) {}
-
-func _() {
-	// related1 can be called with explicit instantiation.
-	var si []int
-	related1[[]int, int](si, 0)
-
-	// Alternatively, the 2nd type argument can be inferred
-	// from the first one through constraint type inference.
-	var ss []string
-	_ = related1[[]string]
-	related1[[]string](ss, "foo")
-
-	// A type argument inferred from another explicitly provided
-	// type argument overrides whatever value argument type is given.
-	related1[[]string](ss, 0 /* ERROR cannot use 0 */ )
-
-	// A type argument may be inferred from a value argument
-	// and then help infer another type argument via constraint
-	// type inference.
-	related1(si, 0)
-	related1(si, "foo" /* ERROR cannot use "foo" */ )
-}
-
-func related2[Elem any, Slice interface{[]Elem}](e Elem, s Slice) {}
-
-func _() {
-	// related2 can be called with explicit instantiation.
-	var si []int
-	related2[int, []int](0, si)
-
-	// Alternatively, the 2nd type argument can be inferred
-	// from the first one through constraint type inference.
-	var ss []string
-	_ = related2[string]
-	related2[string]("foo", ss)
-
-	// A type argument may be inferred from a value argument
-	// and then help infer another type argument via constraint
-	// type inference. Untyped arguments are always considered
-	// last.
-	related2(1.2, []float64{})
-	related2(1.0, []int{})
-	related2( /* ERROR does not implement */ float64(1.0), []int{}) // TODO(gri) fix error position
-}
-
-type List[P any] []P
-
-func related3[Elem any, Slice []Elem | List[Elem]]() Slice { return nil }
-
-func _() {
-	// related3 can be instantiated explicitly
-	related3[int, []int]()
-	related3[byte, List[byte]]()
-
-	// The 2nd type argument cannot be inferred from the first
-	// one because there's two possible choices: []Elem and
-	// List[Elem].
-	related3[int]( /* ERROR cannot infer Slice */ )
-}
diff --git a/src/cmd/compile/internal/types2/testdata/examples/methods.go b/src/cmd/compile/internal/types2/testdata/examples/methods.go
deleted file mode 100644
index a46f789..0000000
--- a/src/cmd/compile/internal/types2/testdata/examples/methods.go
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file shows some examples of methods on type-parameterized types.
-
-package p
-
-// Parameterized types may have methods.
-type T1[A any] struct{ a A }
-
-// When declaring a method for a parameterized type, the "instantiated"
-// receiver type acts as an implicit declaration of the type parameters
-// for the receiver type. In the example below, method m1 on type T1 has
-// the receiver type T1[A] which declares the type parameter A for use
-// with this method. That is, within the method m1, A stands for the
-// actual type argument provided to an instantiated T1.
-func (t T1[A]) m1() A { return t.a }
-
-// For instance, if T1 is instantiated with the type int, the type
-// parameter A in m1 assumes that type (int) as well and we can write
-// code like this:
-var x T1[int]
-var _ int = x.m1()
-
-// Because the type parameter provided to a parameterized receiver type
-// is declared through that receiver declaration, it must be an identifier.
-// It cannot possibly be some other type because the receiver type is not
-// instantiated with concrete types, it is standing for the parameterized
-// receiver type.
-func (t T1[[ /* ERROR must be an identifier */ ]int]) m2() {}
-
-// Note that using what looks like a predeclared identifier, say int,
-// as type parameter in this situation is deceptive and considered bad
-// style. In m3 below, int is the name of the local receiver type parameter
-// and it shadows the predeclared identifier int which then cannot be used
-// anymore as expected.
-// This is no different from locally re-declaring a predeclared identifier
-// and usually should be avoided. There are some notable exceptions; e.g.,
-// sometimes it makes sense to use the identifier "copy" which happens to
-// also be the name of a predeclared built-in function.
-func (t T1[int]) m3() { var _ int = 42 /* ERROR cannot use 42 .* as int */ }
-
-// The names of the type parameters used in a parameterized receiver
-// type don't have to match the type parameter names in the declaration
-// of the type used for the receiver. In our example, even though T1 is
-// declared with type parameter named A, methods using that receiver type
-// are free to use their own name for that type parameter. That is, the
-// name of type parameters is always local to the declaration where they
-// are introduced. In our example we can write a method m2 and use the
-// name X instead of A for the type parameter w/o any difference.
-func (t T1[X]) m4() X { return t.a }
-
-// If the receiver type is parameterized, type parameters must always be
-// provided: this simply follows from the general rule that a parameterized
-// type must be instantiated before it can be used. A method receiver
-// declaration using a parameterized receiver type is no exception. It is
-// simply that such receiver type expressions perform two tasks simultaneously:
-// they declare the (local) type parameters and then use them to instantiate
-// the receiver type. Forgetting to provide a type parameter leads to an error.
-func (t T1 /* ERROR generic type .* without instantiation */ ) m5() {}
-
-// However, sometimes we don't need the type parameter, and thus it is
-// inconvenient to have to choose a name. Since the receiver type expression
-// serves as a declaration for its type parameters, we are free to choose the
-// blank identifier:
-func (t T1[_]) m6() {}
-
-// Naturally, these rules apply to any number of type parameters on the receiver
-// type. Here are some more complex examples.
-type T2[A, B, C any] struct {
-        a A
-        b B
-        c C
-}
-
-// Naming of the type parameters is local and has no semantic impact:
-func (t T2[A, B, C]) m1() (A, B, C) { return t.a, t.b, t.c }
-func (t T2[C, B, A]) m2() (C, B, A) { return t.a, t.b, t.c }
-func (t T2[X, Y, Z]) m3() (X, Y, Z) { return t.a, t.b, t.c }
-
-// Type parameters may be left blank if they are not needed:
-func (t T2[A, _, C]) m4() (A, C) { return t.a, t.c }
-func (t T2[_, _, X]) m5() X { return t.c }
-func (t T2[_, _, _]) m6() {}
-
-// As usual, blank names may be used for any object which we don't care about
-// using later. For instance, we may write an unnamed method with a receiver
-// that cannot be accessed:
-func (_ T2[_, _, _]) _() int { return 42 }
-
-// Because a receiver parameter list is simply a parameter list, we can
-// leave the receiver argument away for receiver types.
-type T0 struct{}
-func (T0) _() {}
-func (T1[A]) _() {}
-
-// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
-// // A generic receiver type may constrain its type parameter such
-// // that it must be a pointer type. Such receiver types are not
-// // permitted.
-// type T3a[P interface{ ~int | ~string | ~float64 }] P
-// 
-// func (T3a[_]) m() {} // this is ok
-// 
-// type T3b[P interface{ ~unsafe.Pointer }] P
-// 
-// func (T3b /* ERROR invalid receiver */ [_]) m() {}
-// 
-// type T3c[P interface{ *int | *string }] P
-// 
-// func (T3c /* ERROR invalid receiver */ [_]) m() {}
diff --git a/src/cmd/compile/internal/types2/testdata/examples/operations.go b/src/cmd/compile/internal/types2/testdata/examples/operations.go
deleted file mode 100644
index 18e4d60..0000000
--- a/src/cmd/compile/internal/types2/testdata/examples/operations.go
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-// indirection
-
-func _[P any](p P) {
-        _ = *p // ERROR cannot indirect p
-}
-
-func _[P interface{ int }](p P) {
-        _ = *p // ERROR cannot indirect p
-}
-
-func _[P interface{ *int }](p P) {
-        _ = *p
-}
-
-func _[P interface{ *int | *string }](p P) {
-        _ = *p // ERROR must have identical base types
-}
-
-type intPtr *int
-
-func _[P interface{ *int | intPtr } ](p P) {
-        var _ int = *p
-}
diff --git a/src/cmd/compile/internal/types2/testdata/examples/types.go b/src/cmd/compile/internal/types2/testdata/examples/types.go
deleted file mode 100644
index ae9c015..0000000
--- a/src/cmd/compile/internal/types2/testdata/examples/types.go
+++ /dev/null
@@ -1,315 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file shows some examples of generic types.
-
-package p
-
-// List is just what it says - a slice of E elements.
-type List[E any] []E
-
-// A generic (parameterized) type must always be instantiated
-// before it can be used to designate the type of a variable
-// (including a struct field, or function parameter); though
-// for the latter cases, the provided type may be another type
-// parameter. So:
-var _ List[byte] = []byte{}
-
-// A generic binary tree might be declared as follows.
-type Tree[E any] struct {
-	left, right *Tree[E]
-	payload E
-}
-
-// A simple instantiation of Tree:
-var root1 Tree[int]
-
-// The actual type parameter provided may be a generic type itself:
-var root2 Tree[List[int]]
-
-// A couple of more complex examples.
-// We don't need extra parentheses around the element type of the slices on
-// the right (unlike when we use ()'s rather than []'s for type parameters).
-var _ List[List[int]] = []List[int]{}
-var _ List[List[List[Tree[int]]]] = []List[List[Tree[int]]]{}
-
-// Type parameters act like type aliases when used in generic types
-// in the sense that we can "emulate" a specific type instantiation
-// with type aliases.
-type T1[P any] struct {
-	f P
-}
-
-type T2[P any] struct {
-	f struct {
-		g P
-	}
-}
-
-var x1 T1[struct{ g int }]
-var x2 T2[int]
-
-func _() {
-	// This assignment is invalid because the types of x1, x2 are T1(...)
-	// and T2(...) respectively, which are two different defined types.
-	x1 = x2 // ERROR assignment
-
-	// This assignment is valid because the types of x1.f and x2.f are
-	// both struct { g int }; the type parameters act like type aliases
-	// and their actual names don't come into play here.
-	x1.f = x2.f
-}
-
-// We can verify this behavior using type aliases instead:
-type T1a struct {
-	f A1
-}
-type A1 = struct { g int }
-
-type T2a struct {
-	f struct {
-		g A2
-	}
-}
-type A2 = int
-
-var x1a T1a
-var x2a T2a
-
-func _() {
-	x1a = x2a // ERROR assignment
-	x1a.f = x2a.f
-}
-
-// Another interesting corner case are generic types that don't use
-// their type arguments. For instance:
-type T[P any] struct{}
-
-var xint T[int]
-var xbool T[bool]
-
-// Are these two variables of the same type? After all, their underlying
-// types are identical. We consider them to be different because each type
-// instantiation creates a new named type, in this case T<int> and T<bool>
-// even if their underlying types are identical. This is sensible because
-// we might still have methods that have different signatures or behave
-// differently depending on the type arguments, and thus we can't possibly
-// consider such types identical. Consequently:
-func _() {
-	xint = xbool // ERROR assignment
-}
-
-// Generic types cannot be used without instantiation.
-var _ T // ERROR cannot use generic type T
-var _ = T /* ERROR cannot use generic type T */ (0)
-
-// In type context, generic (parameterized) types cannot be parenthesized before
-// being instantiated. See also NOTES entry from 12/4/2019.
-var _ (T /* ERROR cannot use generic type T */ )[ /* ERROR unexpected \[ */ int]
-
-// All types may be parameterized, including interfaces.
-type I1[T any] interface{
-	m1(T)
-}
-
-// There is no such thing as a variadic generic type.
-type _[T ... /* ERROR invalid use of ... */ any] struct{}
-
-// Generic interfaces may be embedded as one would expect.
-type I2 interface {
-	I1(int)     // method!
-	I1[string]  // embedded I1
-}
-
-func _() {
-	var x I2
-	x.I1(0)
-	x.m1("foo")
-}
-
-type I0 interface {
-	m0()
-}
-
-type I3 interface {
-	I0
-	I1[bool]
-	m(string)
-}
-
-func _() {
-	var x I3
-	x.m0()
-	x.m1(true)
-	x.m("foo")
-}
-
-type _ struct {
-	( /* ERROR cannot parenthesize */ int8)
-	( /* ERROR cannot parenthesize */ *int16)
-	*( /* ERROR cannot parenthesize */ int32)
-	List[int]
-
-	int8 /* ERROR int8 redeclared */
-	* /* ERROR int16 redeclared */ int16
-	List /* ERROR List redeclared */ [int]
-}
-
-// Issue #45639: We don't allow this anymore. Keep this code
-//               in case we decide to revisit this decision.
-//
-// It's possible to declare local types whose underlying types
-// are type parameters. As with ordinary type definitions, the
-// types underlying properties are "inherited" but the methods
-// are not.
-// func _[T interface{ m(); ~int }]() {
-// 	type L T
-// 	var x L
-// 
-// 	// m is not defined on L (it is not "inherited" from
-// 	// its underlying type).
-// 	x.m /* ERROR x.m undefined */ ()
-// 
-// 	// But the properties of T, such that as that it supports
-// 	// the operations of the types given by its type bound,
-// 	// are also the properties of L.
-// 	x++
-// 	_ = x - x
-// 
-// 	// On the other hand, if we define a local alias for T,
-// 	// that alias stands for T as expected.
-// 	type A = T
-// 	var y A
-// 	y.m()
-// 	_ = y < 0
-// }
-
-// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
-// // It is not permitted to declare a local type whose underlying
-// // type is a type parameter not declared by that type declaration.
-// func _[T any]() {
-// 	type _ T         // ERROR cannot use function type parameter T as RHS in type declaration
-// 	type _ [_ any] T // ERROR cannot use function type parameter T as RHS in type declaration
-// }
-
-// As a special case, an explicit type argument may be omitted
-// from a type parameter bound if the type bound expects exactly
-// one type argument. In that case, the type argument is the
-// respective type parameter to which the type bound applies.
-// Note: We may not permit this syntactic sugar at first.
-// Note: This is now disabled. All examples below are adjusted.
-type Adder[T any] interface {
-	Add(T) T
-}
-
-// We don't need to explicitly instantiate the Adder bound
-// if we have exactly one type parameter.
-func Sum[T Adder[T]](list []T) T {
-	var sum T
-	for _, x := range list {
-		sum = sum.Add(x)
-	}
-	return sum
-}
-
-// Valid and invalid variations.
-type B0 any
-type B1[_ any] any
-type B2[_, _ any] any
-
-func _[T1 B0]() {}
-func _[T1 B1[T1]]() {}
-func _[T1 B2 /* ERROR cannot use generic type .* without instantiation */ ]() {}
-
-func _[T1, T2 B0]() {}
-func _[T1 B1[T1], T2 B1[T2]]() {}
-func _[T1, T2 B2 /* ERROR cannot use generic type .* without instantiation */ ]() {}
-
-func _[T1 B0, T2 B1[T2]]() {} // here B1 applies to T2
-
-// When the type argument is left away, the type bound is
-// instantiated for each type parameter with that type
-// parameter.
-// Note: We may not permit this syntactic sugar at first.
-func _[A Adder[A], B Adder[B], C Adder[A]]() {
-	var a A // A's type bound is Adder[A]
-	a = a.Add(a)
-	var b B // B's type bound is Adder[B]
-	b = b.Add(b)
-	var c C // C's type bound is Adder[A]
-	a = c.Add(a)
-}
-
-// The type of variables (incl. parameters and return values) cannot
-// be an interface with type constraints or be/embed comparable.
-type I interface {
-	~int
-}
-
-var (
-	_ interface /* ERROR contains type constraints */ {~int}
-	_ I /* ERROR contains type constraints */
-)
-
-func _(I /* ERROR contains type constraints */ )
-func _(x, y, z I /* ERROR contains type constraints */ )
-func _() I /* ERROR contains type constraints */
-
-func _() {
-	var _ I /* ERROR contains type constraints */
-}
-
-type C interface {
-	comparable
-}
-
-var _ comparable /* ERROR comparable */
-var _ C /* ERROR comparable */
-
-func _(_ comparable /* ERROR comparable */ , _ C /* ERROR comparable */ )
-
-func _() {
-	var _ comparable /* ERROR comparable */
-	var _ C /* ERROR comparable */
-}
-
-// Type parameters are never const types, i.e., it's
-// not possible to declare a constant of type parameter type.
-// (If a type set contains just a single const type, we could
-// allow it, but such type sets don't make much sense in the
-// first place.)
-func _[T interface{~int|~float64}]() {
-	// not valid
-	const _ = T /* ERROR not constant */ (0)
-	const _ T /* ERROR invalid constant type T */ = 1
-
-	// valid
-	var _ = T(0)
-	var _ T = 1
-	_ = T(0)
-}
-
-// It is possible to create composite literals of type parameter
-// type as long as it's possible to create a composite literal
-// of the core type of the type parameter's constraint.
-func _[P interface{ ~[]int }]() P {
-	return P{}
-	return P{1, 2, 3}
-}
-
-func _[P interface{ ~[]E }, E interface{ map[string]P } ]() P {
-	x := P{}
-	return P{{}}
-	return P{E{}}
-	return P{E{"foo": x}}
-	return P{{"foo": x}, {}}
-}
-
-// This is a degenerate case with a singleton type set, but we can create
-// composite literals even if the core type is a defined type.
-type MyInts []int
-
-func _[P MyInts]() P {
-	return P{}
-}
diff --git a/src/cmd/compile/internal/types2/testdata/examples/typesets.go b/src/cmd/compile/internal/types2/testdata/examples/typesets.go
deleted file mode 100644
index 55ef022..0000000
--- a/src/cmd/compile/internal/types2/testdata/examples/typesets.go
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file shows some examples of constraint literals with elided interfaces.
-// These examples are permitted if proposal issue #48424 is accepted.
-
-package p
-
-// Constraint type sets of the form T, ~T, or A|B may omit the interface.
-type (
-	_[T int] struct{}
-	_[T ~int] struct{}
-	_[T int|string] struct{}
-	_[T ~int|~string] struct{}
-)
-
-func min[T int|string](x, y T) T {
-	if x < y {
-		return x
-	}
-	return y
-}
-
-func lookup[M ~map[K]V, K comparable, V any](m M, k K) V {
-	return m[k]
-}
-
-func deref[P ~*E, E any](p P) E {
-	return *p
-}
-
-func _() int {
-	p := new(int)
-	return deref(p)
-}
-
-func addrOfCopy[V any, P *V](v V) P {
-	return &v
-}
-
-func _() *int {
-	return addrOfCopy(0)
-}
-
-// A type parameter may not be embedded in an interface;
-// so it can also not be used as a constraint.
-func _[A any, B A /* ERROR cannot use a type parameter as constraint */ ]() {}
-func _[A any, B, C A /* ERROR cannot use a type parameter as constraint */ ]() {}
-
-
-// Error messages refer to the type constraint as it appears in the source.
-// (No implicit interface should be exposed.)
-func _[T string](x T) T {
-	return x /* ERROR constrained by string */ * x
-}
-
-func _[T int|string](x T) T {
-	return x /* ERROR constrained by int|string */ * x
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue20583.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue20583.go
deleted file mode 100644
index 85f11ec..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue20583.go
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package issue20583
-const (
-	_ = 6e886451608 /* ERROR malformed constant */ /2
-	_ = 6e886451608i /* ERROR malformed constant */ /2
-	_ = 0 * 1e+1000000000 // ERROR malformed constant
-	x = 1e100000000
-	_ = x*x*x*x*x*x* /* ERROR not representable */ x
-)
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue23203a.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue23203a.go
deleted file mode 100644
index 48cb588..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue23203a.go
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import "unsafe"
-
-type T struct{}
-
-func (T) m1()                         {}
-func (T) m2([unsafe.Sizeof(T.m1)]int) {}
-
-func main() {}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue23203b.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue23203b.go
deleted file mode 100644
index 638ec6c..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue23203b.go
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import "unsafe"
-
-type T struct{}
-
-func (T) m2([unsafe.Sizeof(T.m1)]int) {}
-func (T) m1()                         {}
-
-func main() {}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue25838.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue25838.go
deleted file mode 100644
index adbd138..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue25838.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-// examples from the issue
-
-type (
-	e = f
-	f = g
-	g = []h
-	h i
-	i = j
-	j = e
-)
-
-type (
-	e1 = []h1
-	h1 e1
-)
-
-type (
-	P = *T
-	T P
-)
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue26390.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue26390.go
deleted file mode 100644
index b8e67e9..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue26390.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package issue26390
-
-type A = T
-
-func (t *T) m() *A { return t }
-
-type T struct{}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue28251.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue28251.go
deleted file mode 100644
index ef5e61d..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue28251.go
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file contains test cases for various forms of
-// method receiver declarations, per the spec clarification
-// https://golang.org/cl/142757.
-
-package issue28251
-
-// test case from issue28251
-type T struct{}
-
-type T0 = *T
-
-func (T0) m() {}
-
-func _() { (&T{}).m() }
-
-// various alternative forms
-type (
-        T1 = (((T)))
-)
-
-func ((*(T1))) m1() {}
-func _() { (T{}).m2() }
-func _() { (&T{}).m2() }
-
-type (
-        T2 = (((T3)))
-        T3 = T
-)
-
-func (T2) m2() {}
-func _() { (T{}).m2() }
-func _() { (&T{}).m2() }
-
-type (
-        T4 = ((*(T5)))
-        T5 = T
-)
-
-func (T4) m4() {}
-func _() { (T{}).m4 /* ERROR "cannot call pointer method m4 on T" */ () }
-func _() { (&T{}).m4() }
-
-type (
-        T6 = (((T7)))
-        T7 = (*(T8))
-        T8 = T
-)
-
-func (T6) m6() {}
-func _() { (T{}).m6 /* ERROR "cannot call pointer method m6 on T" */ () }
-func _() { (&T{}).m6() }
-
-type (
-        T9 = *T10
-        T10 = *T11
-        T11 = T
-)
-
-func (T9 /* ERROR invalid receiver type \*\*T */ ) m9() {}
-func _() { (T{}).m9 /* ERROR has no field or method m9 */ () }
-func _() { (&T{}).m9 /* ERROR has no field or method m9 */ () }
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39634.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39634.go
deleted file mode 100644
index b7d99f9..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39634.go
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Examples adjusted to match new [T any] syntax for type parameters.
-// Also, previously permitted empty type parameter lists and instantiations
-// are now syntax errors.
-
-package p
-
-// crash 1
-type nt1[_ any]interface{g /* ERROR undeclared name */ }
-type ph1[e nt1[e],g(d /* ERROR undeclared name */ )]s /* ERROR undeclared name */
-func(*ph1[e,e /* ERROR redeclared */ ])h(d /* ERROR undeclared name */ )
-
-// crash 2
-// Disabled: empty []'s are now syntax errors. This example leads to too many follow-on errors.
-// type Numeric2 interface{t2 /* ERROR not a type */ }
-// func t2[T Numeric2](s[]T){0 /* ERROR not a type */ []{s /* ERROR cannot index */ [0][0]}}
-
-// crash 3
-type t3 *interface{ t3.p /* ERROR no field or method p */ }
-
-// crash 4
-type Numeric4 interface{t4 /* ERROR not a type */ }
-func t4[T Numeric4](s[]T){if( /* ERROR non-boolean */ 0){*s /* ERROR cannot indirect */ [0]}}
-
-// crash 7
-type foo7 interface { bar() }
-type x7[A any] struct{ foo7 }
-func main7() { var _ foo7 = x7[int]{} }
-
-// crash 8
-type foo8[A any] interface { ~A /* ERROR cannot be a type parameter */ }
-func bar8[A foo8[A]](a A) {}
-
-// crash 9
-type foo9[A any] interface { foo9 /* ERROR illegal cycle */ [A] }
-func _() { var _ = new(foo9[int]) }
-
-// crash 12
-var u /* ERROR cycle */ , i [func /* ERROR used as value */ /* ERROR used as value */ (u, c /* ERROR undeclared */ /* ERROR undeclared */ ) {}(0, len /* ERROR must be called */ /* ERROR must be called */ )]c /* ERROR undeclared */ /* ERROR undeclared */
-
-// crash 15
-func y15() { var a /* ERROR declared but not used */ interface{ p() } = G15[string]{} }
-type G15[X any] s /* ERROR undeclared name */
-func (G15 /* ERROR generic type .* without instantiation */ ) p()
-
-// crash 16
-type Foo16[T any] r16 /* ERROR not a type */
-func r16[T any]() Foo16[Foo16[T]] { panic(0) }
-
-// crash 17
-type Y17 interface{ c() }
-type Z17 interface {
-	c() Y17
-	Y17 /* ERROR duplicate method */
-}
-func F17[T Z17](T) {}
-
-// crash 18
-type o18[T any] []func(_ o18[[]_ /* ERROR cannot use _ */ ])
-
-// crash 19
-type Z19 [][[]Z19{}[0][0]]c19 /* ERROR undeclared */
-
-// crash 20
-type Z20 /* ERROR illegal cycle */ interface{ Z20 }
-func F20[t Z20]() { F20(t /* ERROR invalid composite literal type */ {}) }
-
-// crash 21
-type Z21 /* ERROR illegal cycle */ interface{ Z21 }
-func F21[T Z21]() { ( /* ERROR not used */ F21[Z21]) }
-
-// crash 24
-type T24[P any] P // ERROR cannot use a type parameter as RHS in type declaration
-func (r T24[P]) m() { T24 /* ERROR without instantiation */ .m() }
-
-// crash 25
-type T25[A any] int
-func (t T25[A]) m1() {}
-var x T25 /* ERROR without instantiation */ .m1
-
-// crash 26
-type T26 = interface{ F26[ /* ERROR interface method must have no type parameters */ Z any]() }
-func F26[Z any]() T26 { return F26 /* ERROR without instantiation */ [] /* ERROR operand */ }
-
-// crash 27
-func e27[T any]() interface{ x27 /* ERROR not a type */ } { panic(0) }
-func x27() { e27( /* ERROR cannot infer T */ ) }
\ No newline at end of file
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39664.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39664.go
deleted file mode 100644
index 3b3ec56..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39664.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type T[_ any] struct {}
-
-func (T /* ERROR instantiation */ ) m()
-
-func _() {
-	var x interface { m() }
-	x = T[int]{}
-	_ = x
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39680.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39680.go
deleted file mode 100644
index e56bc35..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39680.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-// Embedding stand-alone type parameters is not permitted for now. Disabled.
-
-/*
-import "fmt"
-
-// Minimal test case.
-func _[T interface{~T}](x T) T{
-	return x
-}
-
-// Test case from issue.
-type constr[T any] interface {
-	~T
-}
-
-func Print[T constr[T]](s []T) {
-	for _, v := range s {
-		fmt.Print(v)
-	}
-}
-
-func f() {
-	Print([]string{"Hello, ", "playground\n"})
-}
-*/
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39693.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39693.go
deleted file mode 100644
index 301c13b..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39693.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type Number1 interface {
-	// embedding non-interface types is permitted
-	int
-	float64
-}
-
-func Add1[T Number1](a, b T) T {
-	return a /* ERROR not defined */ + b
-}
-
-type Number2 interface {
-	int|float64
-}
-
-func Add2[T Number2](a, b T) T {
-	return a + b
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39699.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39699.go
deleted file mode 100644
index 72f8399..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39699.go
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type T0 interface{
-}
-
-type T1 interface{
-	~int
-}
-
-type T2 interface{
-	comparable
-}
-
-type T3 interface {
-	T0
-	T1
-	T2
-}
-
-func _() {
-	_ = T0(0)
-	_ = T1 /* ERROR cannot use interface T1 in conversion */ (1)
-	_ = T2 /* ERROR cannot use interface T2 in conversion */ (2)
-	_ = T3 /* ERROR cannot use interface T3 in conversion */ (3)
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39711.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39711.go
deleted file mode 100644
index 8f31012..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39711.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-// Do not report a duplicate type error for this term list.
-// (Check types after interfaces have been completed.)
-type _ interface {
-	// TODO(gri) Once we have full type sets we can enable this again.
-	// Fow now we don't permit interfaces in term lists.
-	// type interface{ Error() string }, interface{ String() string }
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39723.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39723.go
deleted file mode 100644
index 0088523..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39723.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-// A constraint must be an interface; it cannot
-// be a type parameter, for instance.
-func _[A interface{ ~int }, B A /* ERROR cannot use a type parameter as constraint */ ]() {}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39725.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39725.go
deleted file mode 100644
index 62dc45a..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39725.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func f1[T1, T2 any](T1, T2, struct{a T1; b T2}) {}
-func _() {
-	f1(42, string("foo"), struct /* ERROR does not match inferred type struct\{a int; b string\} */ {a, b int}{})
-}
-
-// simplified test case from issue
-func f2[T any](_ []T, _ func(T)) {}
-func _() {
-	f2([]string{}, func /* ERROR does not match inferred type func\(string\) */ (f []byte) {})
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39754.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39754.go
deleted file mode 100644
index 9edd239..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39754.go
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style

-// license that can be found in the LICENSE file.

-

-package p

-

-type Optional[T any] struct {}

-

-func (_ Optional[T]) Val() (T, bool)

-

-type Box[T any] interface {

-	Val() (T, bool)

-}

-

-func f[V interface{}, A, B Box[V]]() {}

-

-func _() {

-	f[int, Optional[int], Optional[int]]()

-	_ = f[int, Optional[int], Optional /* ERROR does not implement Box */ [string]]

-	_ = f[int, Optional[int], Optional /* ERROR Optional.* does not implement Box.* */ [string]]

-}

diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39755.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39755.go
deleted file mode 100644
index 257b73a..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39755.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func _[T interface{~map[string]int}](x T) {
-	_ = x == nil
-}
-
-// simplified test case from issue
-
-type PathParamsConstraint interface {
-        ~map[string]string | ~[]struct{key, value string}
-}
-
-type PathParams[T PathParamsConstraint] struct {
-	t T
-}
-
-func (pp *PathParams[T]) IsNil() bool {
-	return pp.t == nil // this must succeed
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39768.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39768.go
deleted file mode 100644
index 696d9d9..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39768.go
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
-// type T[P any] P
-// type A = T  // ERROR cannot use generic type
-// var x A[int]
-// var _ A
-//
-// type B = T[int]
-// var y B = x
-// var _ B /* ERROR not a generic type */ [int]
-
-// test case from issue
-
-type Vector[T any] []T
-type VectorAlias = Vector // ERROR cannot use generic type
-var v Vector[int]
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39938.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39938.go
deleted file mode 100644
index 6bc9284..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39938.go
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-// All but E2 and E5 provide an "indirection" and break infinite expansion of a type.
-type E0[P any] []P
-type E1[P any] *P
-type E2[P any] struct{ _ P }
-type E3[P any] struct{ _ *P }
-type E5[P any] struct{ _ [10]P }
-
-type T0 struct {
-        _ E0[T0]
-}
-
-type T0_ struct {
-        E0[T0_]
-}
-
-type T1 struct {
-        _ E1[T1]
-}
-
-type T2 /* ERROR illegal cycle */ struct {
-        _ E2[T2]
-}
-
-type T3 struct {
-        _ E3[T3]
-}
-
-type T4 /* ERROR illegal cycle */ [10]E5[T4]
-
-type T5 struct {
-	_ E0[E2[T5]]
-}
-
-type T6 struct {
-	_ E0[E2[E0[E1[E2[[10]T6]]]]]
-}
-
-type T7 struct {
-	_ E0[[10]E2[E0[E2[E2[T7]]]]]
-}
-
-type T8 struct {
-	_ E0[[]E2[E0[E2[E2[T8]]]]]
-}
-
-type T9 /* ERROR illegal cycle */ [10]E2[E5[E2[T9]]]
-
-type T10 [10]E2[E5[E2[func(T10)]]]
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39948.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39948.go
deleted file mode 100644
index c893cc0..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39948.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type T[P any] interface{
-	P // ERROR term cannot be a type parameter
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39976.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39976.go
deleted file mode 100644
index d703da9..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39976.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type policy[K, V any] interface{}
-type LRU[K, V any] struct{}
-
-func NewCache[K, V any](p policy[K, V]) {}
-
-func _() {
-	var lru LRU[int, string]
-	NewCache[int, string](&lru)
-	NewCache(& /* ERROR does not match policy\[K, V\] \(cannot infer K and V\) */ lru)
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39982.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39982.go
deleted file mode 100644
index 9810b63..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue39982.go
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type (
-	T[_ any] struct{}
-	S[_ any] struct {
-		data T[*T[int]]
-	}
-)
-
-func _() {
-	_ = S[int]{
-		data: T[*T[int]]{},
-	}
-}
-
-// full test case from issue
-
-type (
-	Element[TElem any] struct{}
-
-	entry[K comparable] struct{}
-
-	Cache[K comparable] struct {
-		data map[K]*Element[*entry[K]]
-	}
-)
-
-func _() {
-	_ = Cache[int]{
-		data: make(map[int](*Element[*entry[int]])),
-	}
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue40038.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue40038.go
deleted file mode 100644
index 0981a33..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue40038.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type A[T any] int
-
-func (A[T]) m(A[T])
-
-func f[P interface{m(P)}]() {}
-
-func _() {
-	_ = f[A[int]]
-}
\ No newline at end of file
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue40056.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue40056.go
deleted file mode 100644
index a3f3eec..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue40056.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func _() {
-	NewS( /* ERROR cannot infer T */ ) .M()
-}
-
-type S struct {}
-
-func NewS[T any]() *S { panic(0) }
-
-func (_ *S /* ERROR S is not a generic type */ [T]) M()
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue40057.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue40057.go
deleted file mode 100644
index fdc8fb1..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue40057.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func _() {
-	var x interface{}
-	switch t := x.(type) {
-	case S /* ERROR cannot use generic type */ :
-		t.m()
-	}
-}
-
-type S[T any] struct {}
-
-func (_ S[T]) m()
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue40301.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue40301.go
deleted file mode 100644
index c78f9a1..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue40301.go
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-import "unsafe"
-
-func _[T any](x T) {
-	_ = unsafe.Alignof(x)
-	_ = unsafe.Sizeof(x)
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue40350.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue40350.go
deleted file mode 100644
index 7ffd551..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue40350.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type number interface {
-	~float64 | ~int | ~int32
-	float64 | ~int32
-}
-
-func f[T number]() {}
-
-func _() {
-	_ = f[int /* ERROR int does not implement number \(int missing in float64 | ~int32\)*/]
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue40684.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue40684.go
deleted file mode 100644
index 58d0f69..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue40684.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type T[_ any] int
-
-func f[_ any]() {}
-func g[_, _ any]() {}
-
-func _() {
-	_ = f[T /* ERROR without instantiation */ ]
-	_ = g[T /* ERROR without instantiation */ , T /* ERROR without instantiation */ ]
-}
\ No newline at end of file
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue40789.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue40789.go
deleted file mode 100644
index 9eea4ad..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue40789.go
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import "fmt"
-
-func main() {
-	m := map[string]int{
-		"a": 6,
-		"b": 7,
-	}
-	fmt.Println(copyMap[map[string]int, string, int](m))
-}
-
-type Map[K comparable, V any] interface {
-	map[K] V
-}
-
-func copyMap[M Map[K, V], K comparable, V any](m M) M {
-	m1 := make(M)
-	for k, v := range m {
-		m1[k] = v
-	}
-	return m1
-}
-
-// simpler test case from the same issue
-
-type A[X comparable] interface {
-	[]X
-}
-
-func f[B A[X], X comparable]() B {
-	return nil
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue41124.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue41124.go
deleted file mode 100644
index 4550dd7..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue41124.go
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-// Test case from issue.
-
-type Nat /* ERROR cycle */ interface {
-	Zero|Succ
-}
-
-type Zero struct{}
-type Succ struct{
-	Nat // Nat contains type constraints but is invalid, so no error
-}
-
-// Struct tests.
-
-type I1 interface {
-	comparable
-}
-
-type I2 interface {
-	~int
-}
-
-type I3 interface {
-	I1
-	I2
-}
-
-type _ struct {
-	f I1 // ERROR interface is .* comparable
-}
-
-type _ struct {
-	comparable // ERROR interface is .* comparable
-}
-
-type _ struct{
-	I1 // ERROR interface is .* comparable
-}
-
-type _ struct{
-	I2 // ERROR interface contains type constraints
-}
-
-type _ struct{
-	I3 // ERROR interface contains type constraints
-}
-
-// General composite types.
-
-type (
-	_ [10]I1 // ERROR interface is .* comparable
-	_ [10]I2 // ERROR interface contains type constraints
-
-	_ []I1 // ERROR interface is .* comparable
-	_ []I2 // ERROR interface contains type constraints
-
-	_ *I3 // ERROR interface contains type constraints
-	_ map[I1 /* ERROR interface is .* comparable */ ]I2 // ERROR interface contains type constraints
-	_ chan I3 // ERROR interface contains type constraints
-	_ func(I1 /* ERROR interface is .* comparable */ )
-	_ func() I2 // ERROR interface contains type constraints
-)
-
-// Other cases.
-
-var _ = [...]I3 /* ERROR interface contains type constraints */ {}
-
-func _(x interface{}) {
-	_ = x.(I3 /* ERROR interface contains type constraints */ )
-}
-
-type T1[_ any] struct{}
-type T3[_, _, _ any] struct{}
-var _ T1[I2 /* ERROR interface contains type constraints */ ]
-var _ T3[int, I2 /* ERROR interface contains type constraints */ , float32]
-
-func f1[_ any]() int { panic(0) }
-var _ = f1[I2 /* ERROR interface contains type constraints */ ]()
-func f3[_, _, _ any]() int { panic(0) }
-var _ = f3[int, I2 /* ERROR interface contains type constraints */ , float32]()
-
-func _(x interface{}) {
-	switch x.(type) {
-	case I2 /* ERROR interface contains type constraints */ :
-	}
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue42695.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue42695.go
deleted file mode 100644
index d0d6200..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue42695.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package issue42695
-
-const _ = 6e5518446744 // ERROR malformed constant
-const _ uint8 = 6e5518446744 // ERROR malformed constant
-
-var _ = 6e5518446744 // ERROR malformed constant
-var _ uint8 = 6e5518446744 // ERROR malformed constant
-
-func f(x int) int {
-        return x + 6e5518446744 // ERROR malformed constant
-}
-
-var _ = f(6e5518446744 /* ERROR malformed constant */ )
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue42758.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue42758.go
deleted file mode 100644
index 6d75b10..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue42758.go
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func _[T any](x interface{}){
-	switch x.(type) {
-	case T: // ok to use a type parameter
-	case int:
-	}
-
-	switch x.(type) {
-	case T:
-	case T /* ERROR duplicate case */ :
-	}
-}
-
-type constraint interface {
-	~int
-}
-
-func _[T constraint](x interface{}){
-	switch x.(type) {
-	case T: // ok to use a type parameter even if type set contains int
-	case int:
-	}
-}
-
-func _(x constraint /* ERROR contains type constraints */ ) {
-	switch x.(type) { // no need to report another error
-	}
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue42881.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue42881.go
deleted file mode 100644
index 7122d1c..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue42881.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type (
-	T1 interface{ comparable }
-	T2 interface{ int }
-)
-
-var (
-	_ comparable // ERROR cannot use type comparable outside a type constraint: interface is \(or embeds\) comparable
-	_ T1         // ERROR cannot use type T1 outside a type constraint: interface is \(or embeds\) comparable
-	_ T2         // ERROR cannot use type T2 outside a type constraint: interface contains type constraints
-)
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue42987.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue42987.go
deleted file mode 100644
index 8aa3544..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue42987.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Check that there is only one error (no follow-on errors).
-
-package p
-var _ = [ /* ERROR invalid use of .* array */ ...]byte("foo")
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43056.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43056.go
deleted file mode 100644
index 8ff4e7f..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43056.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-// simplified example
-func f[T ~func(T)](a, b T) {}
-
-type F func(F)
-
-func _() {
-	var i F
-	var j func(F)
-
-	f(i, j)
-	f(j, i)
-}
-
-// example from issue
-func g[T interface{ Equal(T) bool }](a, b T) {}
-
-type I interface{ Equal(I) bool }
-
-func _() {
-	var i I
-	var j interface{ Equal(I) bool }
-
-	g(i, j)
-	g(j, i)
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43109.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43109.go
deleted file mode 100644
index a4533c9..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43109.go
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Ensure there is no "imported but not used" error
-// if a package wasn't imported in the first place.
-
-package p
-
-import . "/foo" // ERROR could not import \/foo
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43110.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43110.go
deleted file mode 100644
index 8d5c983..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43110.go
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type P *struct{}
-
-func _() {
-	// want an error even if the switch is empty
-	var a struct{ _ func() }
-	switch a /* ERROR cannot switch on a */ {
-	}
-
-	switch a /* ERROR cannot switch on a */ {
-	case a: // no follow-on error here
-	}
-
-	// this is ok because f can be compared to nil
-	var f func()
-	switch f {
-	}
-
-	switch f {
-	case nil:
-	}
-
-	switch (func())(nil) {
-	case nil:
-	}
-
-	switch (func())(nil) {
-	case f /* ERROR invalid case f in switch on .* \(func can only be compared to nil\) */ :
-	}
-
-	switch nil /* ERROR use of untyped nil in switch expression */ {
-	}
-
-	// this is ok
-	switch P(nil) {
-	case P(nil):
-	}
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43124.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43124.go
deleted file mode 100644
index 7e48c22..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43124.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-var _ = int(0 /* ERROR invalid use of \.\.\. in type conversion */ ...)
-
-// test case from issue
-
-type M []string
-
-var (
-	x = []string{"a", "b"}
-	_ = M(x /* ERROR invalid use of \.\.\. in type conversion */ ...)
-)
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43125.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43125.go
deleted file mode 100644
index c2bd970..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43125.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-var _ = new(- /* ERROR not a type */ 1)
-var _ = new(1 /* ERROR not a type */ + 1)
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43190.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43190.go
deleted file mode 100644
index ae42719..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43190.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-import ; // ERROR missing import path
-import
-var /* ERROR missing import path */ _ int
-import .; // ERROR missing import path
-
-import ()
-import (.) // ERROR missing import path
-import (
-	"fmt"
-	.
-) // ERROR missing import path
-
-var _ = fmt.Println // avoid imported but not used error
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43527.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43527.go
deleted file mode 100644
index 2955c26..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43527.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-const L = 10
-
-type (
-	_        [L]struct{}
-	_        [A /* ERROR undeclared name A for array length */ ]struct{}
-	_        [B /* ERROR invalid array length B */ ]struct{}
-	_[A any] struct{}
-
-	B int
-)
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43671.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43671.go
deleted file mode 100644
index 3c78f85..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43671.go
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type C0 interface{ int }
-type C1 interface{ chan int }
-type C2 interface{ chan int | <-chan int }
-type C3 interface{ chan int | chan float32 }
-type C4 interface{ chan int | chan<- int }
-type C5[T any] interface{ ~chan T | <-chan T }
-
-func _[T any](ch T) {
-	<-ch // ERROR cannot receive from ch .* no core type
-}
-
-func _[T C0](ch T) {
-	<-ch // ERROR cannot receive from non-channel ch
-}
-
-func _[T C1](ch T) {
-	<-ch
-}
-
-func _[T C2](ch T) {
-	<-ch
-}
-
-func _[T C3](ch T) {
-	<-ch // ERROR cannot receive from ch .* no core type
-}
-
-func _[T C4](ch T) {
-	<-ch // ERROR cannot receive from send-only channel
-}
-
-func _[T C5[X], X any](ch T, x X) {
-	x = <-ch
-}
-
-// test case from issue, slightly modified
-type RecvChan[T any] interface {
-	~chan T | ~<-chan T
-}
-
-func _[T any, C RecvChan[T]](ch C) T {
-	return <-ch
-}
-
-func f[T any, C interface{ chan T }](ch C) T {
-	return <-ch
-}
-
-func _(ch chan int) {
-	var x int = f(ch) // test constraint type inference for this case
-	_ = x
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue44688.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue44688.go
deleted file mode 100644
index 512bfcc..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue44688.go
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package P
-
-type A1[T any] struct{}
-
-func (*A1[T]) m1(T) {}
-
-type A2[T any] interface {
-	m2(T)
-}
-
-type B1[T any] struct {
-	filler int
-	*A1[T]
-	A2[T]
-}
-
-type B2[T any] interface {
-	A2[T]
-}
-
-type C[T any] struct {
-	filler1 int
-	filler2 int
-	B1[T]
-}
-
-type D[T any] struct {
-	filler1 int
-	filler2 int
-	filler3 int
-	C[T]
-}
-
-func _() {
-	// calling embedded methods
-	var b1 B1[string]
-
-	b1.A1.m1("")
-	b1.m1("")
-
-	b1.A2.m2("")
-	b1.m2("")
-
-	var b2 B2[string]
-	b2.m2("")
-
-	// a deeper nesting
-	var d D[string]
-	d.m1("")
-	d.m2("")
-
-	// calling method expressions
-	m1x := B1[string].m1
-	m1x(b1, "")
-	m2x := B2[string].m2
-	m2x(b2, "")
-
-	// calling method values
-	m1v := b1.m1
-	m1v("")
-	m2v := b1.m2
-	m2v("")
-	b2v := b2.m2
-	b2v("")
-}
-
-// actual test case from issue
-
-type A[T any] struct{}
-
-func (*A[T]) f(T) {}
-
-type B[T any] struct{ A[T] }
-
-func _() {
-	var b B[string]
-	b.A.f("")
-	b.f("")
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue44799.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue44799.go
deleted file mode 100644
index 9e528a7..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue44799.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-func Map[F, T any](s []F, f func(F) T) []T { return nil }
-
-func Reduce[Elem1, Elem2 any](s []Elem1, initializer Elem2, f func(Elem2, Elem1) Elem2) Elem2 { var x Elem2; return x }
-
-func main() {
-	var s []int
-	var f1 func(int) float64
-	var f2 func(float64, int) float64
-	_ = Map[int](s, f1)
-	_ = Map(s, f1)
-	_ = Reduce[int](s, 0, f2)
-	_ = Reduce(s, 0, f2)
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue45114.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue45114.go
deleted file mode 100644
index 0093660..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue45114.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-var s uint
-var _ = string(1 /* ERROR shifted operand 1 .* must be integer */ << s)
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue45548.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue45548.go
deleted file mode 100644
index 01c9672..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue45548.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func f[F interface{*Q}, G interface{*R}, Q, R any](q Q, r R) {}
-
-func _() {
-	f[*float64, *int](1, 2)
-	f[*float64](1, 2)
-	f(1, 2)
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue45550.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue45550.go
deleted file mode 100644
index 3eeaca0..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue45550.go
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type Builder /* ERROR illegal cycle */ [T interface{ struct{ Builder[T] } }] struct{}
-type myBuilder struct {
-	Builder[myBuilder]
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue45635.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue45635.go
deleted file mode 100644
index 2937959..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue45635.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-func main() {
-	some /* ERROR "undeclared name" */ [int, int]()
-}
-
-type N[T any] struct{}
-
-var _ N[] /* ERROR expecting type */
-
-type I interface {
-	~[]int
-}
-
-func _[T I](i, j int) {
-	var m map[int]int
-	_ = m[i, j /* ERROR more than one index */ ]
-
-	var a [3]int
-	_ = a[i, j /* ERROR more than one index */ ]
-
-	var s []int
-	_ = s[i, j /* ERROR more than one index */ ]
-
-	var t T
-	_ = t[i, j /* ERROR more than one index */ ]
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue45639.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue45639.go
deleted file mode 100644
index 80148fe..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue45639.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package P
-
-// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
-// // It is not permitted to declare a local type whose underlying
-// // type is a type parameters not declared by that type declaration.
-// func _[T any]() {
-// 	type _ T         // ERROR cannot use function type parameter T as RHS in type declaration
-// 	type _ [_ any] T // ERROR cannot use function type parameter T as RHS in type declaration
-// }
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue45920.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue45920.go
deleted file mode 100644
index b113e10..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue45920.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func f1[T any, C chan T | <-chan T](ch C) {}
-
-func _(ch chan int)   { f1(ch) }
-func _(ch <-chan int) { f1(ch) }
-func _(ch chan<- int) { f1( /* ERROR chan<- int does not implement chan int\|<-chan int */ ch) }
-
-func f2[T any, C chan T | chan<- T](ch C) {}
-
-func _(ch chan int)   { f2(ch) }
-func _(ch <-chan int) { f2( /* ERROR <-chan int does not implement chan int\|chan<- int */ ch) }
-func _(ch chan<- int) { f2(ch) }
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue45985.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue45985.go
deleted file mode 100644
index cea8c14..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue45985.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package issue45985
-
-func app[S interface{ ~[]T }, T any](s S, e T) S {
-    return append(s, e)
-}
-
-func _() {
-	_ = app[/* ERROR "S does not match" */int]
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue46090.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue46090.go
deleted file mode 100644
index 07f0101..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue46090.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// -lang=go1.17
-
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// The predeclared type comparable is not visible before Go 1.18.
-
-package p
-
-type _ comparable // ERROR predeclared comparable
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue46275.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue46275.go
deleted file mode 100644
index f41ae26..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue46275.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package issue46275
-
-type N[T any] struct {
-        *N[T]
-        t T
-}
-
-func (n *N[T]) Elem() T {
-        return n.t
-}
-
-type I interface {
-        Elem() string
-}
-
-func _() {
-        var n1 *N[string]
-        var _ I = n1
-        type NS N[string]
-        var n2 *NS
-        var _ I = n2
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue46461.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue46461.go
deleted file mode 100644
index 4432402..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue46461.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-// test case 1
-type T /* ERROR illegal cycle */ [U interface{ M() T[U] }] int
-
-type X int
-
-func (X) M() T[X] { return 0 }
-
-// test case 2
-type A /* ERROR illegal cycle */ [T interface{ A[T] }] interface{}
-
-// test case 3
-type A2 /* ERROR illegal cycle */ [U interface{ A2[U] }] interface{ M() A2[U] }
-
-type I interface{ A2[I]; M() A2[I] }
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47031.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47031.go
deleted file mode 100644
index b184f9b..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47031.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type Mer interface { M() }
-
-func F[T Mer](p *T) {
-	p.M /* ERROR p\.M undefined */ ()
-}
-
-type MyMer int
-
-func (MyMer) M() {}
-
-func _() {
-	F(new(MyMer))
-	F[Mer](nil)
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47115.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47115.go
deleted file mode 100644
index 5c1fa80..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47115.go
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type C0 interface{ int }
-type C1 interface{ chan int }
-type C2 interface{ chan int | <-chan int }
-type C3 interface{ chan int | chan float32 }
-type C4 interface{ chan int | chan<- int }
-type C5[T any] interface{ ~chan T | chan<- T }
-
-func _[T any](ch T) {
-	ch /* ERROR cannot send to ch .* no core type */ <- 0
-}
-
-func _[T C0](ch T) {
-	ch /* ERROR cannot send to non-channel */ <- 0
-}
-
-func _[T C1](ch T) {
-	ch <- 0
-}
-
-func _[T C2](ch T) {
-	ch /* ERROR cannot send to receive-only channel */ <- 0
-}
-
-func _[T C3](ch T) {
-	ch /* ERROR cannot send to ch .* no core type */ <- 0
-}
-
-func _[T C4](ch T) {
-	ch <- 0
-}
-
-func _[T C5[X], X any](ch T, x X) {
-	ch <- x
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47127.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47127.go
deleted file mode 100644
index bb4b487..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47127.go
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Embedding of stand-alone type parameters is not permitted.
-
-package p
-
-type (
-        _[P any] interface{ *P | []P | chan P | map[string]P }
-        _[P any] interface{ P /* ERROR term cannot be a type parameter */ }
-        _[P any] interface{ ~P /* ERROR type in term ~P cannot be a type parameter */ }
-        _[P any] interface{ int | P /* ERROR term cannot be a type parameter */ }
-        _[P any] interface{ int | ~P /* ERROR type in term ~P cannot be a type parameter */ }
-)
-
-func _[P any]() {
-        type (
-                _[P any] interface{ *P | []P | chan P | map[string]P }
-                _[P any] interface{ P /* ERROR term cannot be a type parameter */ }
-                _[P any] interface{ ~P /* ERROR type in term ~P cannot be a type parameter */ }
-                _[P any] interface{ int | P /* ERROR term cannot be a type parameter */ }
-                _[P any] interface{ int | ~P /* ERROR type in term ~P cannot be a type parameter */ }
-
-                _ interface{ *P | []P | chan P | map[string]P }
-                _ interface{ P /* ERROR term cannot be a type parameter */ }
-                _ interface{ ~P /* ERROR type in term ~P cannot be a type parameter */ }
-                _ interface{ int | P /* ERROR term cannot be a type parameter */ }
-                _ interface{ int | ~P /* ERROR type in term ~P cannot be a type parameter */ }
-        )
-}
-
-func _[P any, Q interface{ *P | []P | chan P | map[string]P }]() {}
-func _[P any, Q interface{ P /* ERROR term cannot be a type parameter */ }]() {}
-func _[P any, Q interface{ ~P /* ERROR type in term ~P cannot be a type parameter */ }]() {}
-func _[P any, Q interface{ int | P /* ERROR term cannot be a type parameter */ }]() {}
-func _[P any, Q interface{ int | ~P /* ERROR type in term ~P cannot be a type parameter */ }]() {}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47411.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47411.go
deleted file mode 100644
index 3f405ba..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47411.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func f[_ comparable]() {}
-func g[_ interface{interface{comparable; ~int|~string}}]() {}
-
-func _[P comparable,
-        Q interface{ comparable; ~int|~string },
-        R any,                               // not comparable
-        S interface{ comparable; ~func() },  // not comparable
-]() {
-        _ = f[int]
-        _ = f[P]
-        _ = f[Q]
-        _ = f[func( /* ERROR does not implement comparable */ )]
-        _ = f[R /* ERROR R does not implement comparable */ ]
-
-        _ = g[int]
-        _ = g[P /* ERROR P does not implement interface{interface{comparable; ~int\|~string} */ ]
-        _ = g[Q]
-        _ = g[func( /* ERROR func\(\) does not implement interface{interface{comparable; ~int\|~string}} */ )]
-        _ = g[R /* ERROR R does not implement interface{interface{comparable; ~int\|~string} */ ]
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47747.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47747.go
deleted file mode 100644
index 6f09fc2..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47747.go
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
-// type T1[P any] P
-// 
-// func (T1[_]) m() {}
-// 
-// func _[P any](x *T1[P]) {
-//         // x.m exists because x is of type *T1 where T1 is a defined type
-//         // (even though under(T1) is a type parameter)
-//         x.m()
-// }
-
-
-func _[P interface{ m() }](x P) {
-        x.m()
-        // (&x).m doesn't exist because &x is of type *P
-        // and pointers to type parameters don't have methods
-        (&x).m /* ERROR type \*P is pointer to type parameter, not type parameter */ ()
-}
-
-
-type T2 interface{ m() }
-
-func _(x *T2) {
-        // x.m doesn't exists because x is of type *T2
-        // and pointers to interfaces don't have methods
-        x.m /* ERROR type \*T2 is pointer to interface, not interface */()
-}
-
-// Test case 1 from issue
-
-type Fooer1[t any] interface {
-	Foo(Barer[t])
-}
-type Barer[t any] interface {
-	Bar(t)
-}
-
-// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
-// type Foo1[t any] t
-// type Bar[t any] t
-// 
-// func (l Foo1[t]) Foo(v Barer[t]) { v.Bar(t(l)) }
-// func (b *Bar[t]) Bar(l t)        { *b = Bar[t](l) }
-// 
-// func _[t any](f Fooer1[t]) t {
-// 	var b Bar[t]
-// 	f.Foo(&b)
-// 	return t(b)
-// }
-
-// Test case 2 from issue
-
-// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
-// type Fooer2[t any] interface {
-// 	Foo()
-// }
-// 
-// type Foo2[t any] t
-// 
-// func (f *Foo2[t]) Foo() {}
-// 
-// func _[t any](v t) {
-// 	var f = Foo2[t](v)
-// 	_ = Fooer2[t](&f)
-// }
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47796.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47796.go
deleted file mode 100644
index 6667ba4..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47796.go
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-// parameterized types with self-recursive constraints
-type (
-	T1 /* ERROR illegal cycle */ [P T1[P]]                            interface{}
-	T2 /* ERROR illegal cycle */ [P, Q T2[P, Q]]                      interface{}
-	T3[P T2[P, Q], Q interface{ ~string }] interface{}
-
-	T4a /* ERROR illegal cycle */ [P T4a[P]]                                                        interface{ ~int }
-	T4b /* ERROR illegal cycle */ [P T4b[int]]                                                      interface{ ~int }
-	T4c /* ERROR illegal cycle */ [P T4c[string]] interface{ ~int }
-
-	// mutually recursive constraints
-	T5 /* ERROR illegal cycle */ [P T6[P]] interface{ int }
-	T6[P T5[P]] interface{ int }
-)
-
-// verify that constraints are checked as expected
-var (
-	_ T1[int]
-	_ T2[int, string]
-	_ T3[int, string]
-)
-
-// test case from issue
-
-type Eq /* ERROR illegal cycle */ [a Eq[a]] interface {
-	Equal(that a) bool
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47818.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47818.go
deleted file mode 100644
index 5aa3b82..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47818.go
+++ /dev/null
@@ -1,61 +0,0 @@
-// -lang=go1.17
-
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Parser accepts type parameters but the type checker
-// needs to report any operations that are not permitted
-// before Go 1.18.
-
-package p
-
-type T[P /* ERROR type parameter requires go1\.18 or later */ any /* ERROR predeclared any requires go1\.18 or later */] struct{}
-
-// for init (and main, but we're not in package main) we should only get one error
-func init[P /* ERROR func init must have no type parameters */ any /* ERROR predeclared any requires go1\.18 or later */]() {
-}
-func main[P /* ERROR type parameter requires go1\.18 or later */ any /* ERROR predeclared any requires go1\.18 or later */]() {
-}
-
-func f[P /* ERROR type parameter requires go1\.18 or later */ any /* ERROR predeclared any requires go1\.18 or later */](x P) {
-	var _ T[ /* ERROR type instantiation requires go1\.18 or later */ int]
-	var _ (T[ /* ERROR type instantiation requires go1\.18 or later */ int])
-	_ = T[ /* ERROR type instantiation requires go1\.18 or later */ int]{}
-	_ = T[ /* ERROR type instantiation requires go1\.18 or later */ int](struct{}{})
-}
-
-func (T[ /* ERROR type instantiation requires go1\.18 or later */ P]) g(x int) {
-	f[ /* ERROR function instantiation requires go1\.18 or later */ int](0)     // explicit instantiation
-	(f[ /* ERROR function instantiation requires go1\.18 or later */ int])(0)   // parentheses (different code path)
-	f( /* ERROR implicit function instantiation requires go1\.18 or later */ x) // implicit instantiation
-}
-
-type C1 interface {
-	comparable // ERROR predeclared comparable requires go1\.18 or later
-}
-
-type C2 interface {
-	comparable // ERROR predeclared comparable requires go1\.18 or later
-	int        // ERROR embedding non-interface type int requires go1\.18 or later
-	~ /* ERROR embedding interface element ~int requires go1\.18 or later */ int
-	int /* ERROR embedding interface element int\|~string requires go1\.18 or later */ | ~string
-}
-
-type _ interface {
-	// errors for these were reported with their declaration
-	C1
-	C2
-}
-
-type (
-	_ comparable // ERROR predeclared comparable requires go1\.18 or later
-	// errors for these were reported with their declaration
-	_ C1
-	_ C2
-
-	_ = comparable // ERROR predeclared comparable requires go1\.18 or later
-	// errors for these were reported with their declaration
-	_ = C1
-	_ = C2
-)
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47887.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47887.go
deleted file mode 100644
index 4c4fc2f..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47887.go
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type Fooer[t any] interface {
-	foo(Barer[t])
-}
-type Barer[t any] interface {
-	bar(Bazer[t])
-}
-type Bazer[t any] interface {
-	Fooer[t]
-	baz(t)
-}
-
-type Int int
-
-func (n Int) baz(int) {}
-func (n Int) foo(b Barer[int]) { b.bar(n) }
-
-type F[t any] interface { f(G[t]) }
-type G[t any] interface { g(H[t]) }
-type H[t any] interface { F[t] }
-
-type T struct{}
-func (n T) f(b G[T]) { b.g(n) }
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47968.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47968.go
deleted file mode 100644
index 3dd3039..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47968.go
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type T[P any] struct{}
-
-func (T[P]) m1()
-
-type A1 = T // ERROR cannot use generic type
-
-func (A1[P]) m2() {}
-
-type A2 = T[int]
-
-func (A2 /* ERROR cannot define new methods on instantiated type T\[int\] */) m3()   {}
-func (_ /* ERROR cannot define new methods on instantiated type T\[int\] */ A2) m4() {}
-
-func (T[int]) m5()                                     {} // int is the type parameter name, not an instantiation
-func (T[* /* ERROR must be an identifier */ int]) m6() {} // syntax error
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48008.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48008.go
deleted file mode 100644
index 6c14c78..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48008.go
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type T[P any] struct{}
-
-func _(x interface{}) {
-	switch x.(type) {
-	case nil:
-	case int:
-
-	case T[int]:
-	case []T[int]:
-	case [10]T[int]:
-	case struct{T[int]}:
-	case *T[int]:
-	case func(T[int]):
-	case interface{m(T[int])}:
-	case map[T[int]] string:
-	case chan T[int]:
-
-	case T /* ERROR cannot use generic type T\[P any\] without instantiation */ :
-	case []T /* ERROR cannot use generic type */ :
-	case [10]T /* ERROR cannot use generic type */ :
-	case struct{T /* ERROR cannot use generic type */ }:
-	case *T /* ERROR cannot use generic type */ :
-	case func(T /* ERROR cannot use generic type */ ):
-	case interface{m(T /* ERROR cannot use generic type */ )}:
-	case map[T /* ERROR cannot use generic type */ ] string:
-	case chan T /* ERROR cannot use generic type */ :
-
-	case T /* ERROR cannot use generic type */ , *T /* ERROR cannot use generic type */ :
-	}
-}
-
-// Make sure a parenthesized nil is ok.
-
-func _(x interface{}) {
-	switch x.(type) {
-	case ((nil)), int:
-	}
-}
-
-// Make sure we look for the predeclared nil.
-
-func _(x interface{}) {
-	type nil int
-	switch x.(type) {
-	case nil: // ok - this is the type nil
-	}
-}
-
-func _(x interface{}) {
-	var nil int
-	switch x.(type) {
-	case nil /* ERROR not a type */ : // not ok - this is the variable nil
-	}
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48018.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48018.go
deleted file mode 100644
index e6ccc6b..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48018.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-type Box[A any] struct {
-	value A
-}
-
-func Nest[A /* ERROR instantiation cycle */ any](b Box[A], n int) interface{} {
-	if n == 0 {
-		return b
-	}
-	return Nest(Box[Box[A]]{b}, n-1)
-}
-
-func main() {
-	Nest(Box[int]{0}, 10)
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48048.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48048.go
deleted file mode 100644
index f401330..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48048.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type T[P any] struct{}
-
-func (T[_]) A() {}
-
-var _ = (T[int]).A
-var _ = (*T[int]).A
-
-var _ = (T /* ERROR cannot use generic type */).A
-var _ = (*T /* ERROR cannot use generic type */).A
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48082.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48082.go
deleted file mode 100644
index 5395154..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48082.go
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package issue48082
-
-import "init" /* ERROR init must be a func */ /* ERROR could not import init */
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48083.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48083.go
deleted file mode 100644
index 3dae514..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48083.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type T[P any] struct{}
-
-type _ interface{ int | T /* ERROR cannot use generic type */ }
\ No newline at end of file
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48136.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48136.go
deleted file mode 100644
index 0ab92df..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48136.go
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func f1[P interface{ *P }]() {}
-func f2[P interface{ func(P) }]() {}
-func f3[P, Q interface{ func(Q) P }]() {}
-func f4[P interface{ *Q }, Q interface{ func(P) }]() {}
-func f5[P interface{ func(P) }]() {}
-func f6[P interface { *Tree[P] }, Q any ]() {}
-
-func _() {
-        f1( /* ERROR cannot infer P */ )
-        f2( /* ERROR cannot infer P */ )
-        f3( /* ERROR cannot infer P */ )
-        f4( /* ERROR cannot infer P */ )
-        f5( /* ERROR cannot infer P */ )
-        f6( /* ERROR cannot infer P */ )
-}
-
-type Tree[P any] struct {
-        left, right *Tree[P]
-        data P
-}
-
-// test case from issue
-
-func foo[Src interface { func() Src }]() Src {
-        return foo[Src]
-}
-
-func _() {
-        foo( /* ERROR cannot infer Src */ )
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48234.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48234.go
deleted file mode 100644
index e069930..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48234.go
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-var _ = interface{
-	m()
-	m /* ERROR "duplicate method" */ ()
-}(nil)
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48312.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48312.go
deleted file mode 100644
index 2fdb7ca..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48312.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type T interface{ m() }
-type P *T
-
-func _(p *T) {
-	p.m /* ERROR type \*T is pointer to interface, not interface */ ()
-}
-
-func _(p P) {
-	p.m /* ERROR type P is pointer to interface, not interface */ ()
-}
-
-func _[P T](p *P) {
-	p.m /* ERROR type \*P is pointer to type parameter, not type parameter */ ()
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48472.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48472.go
deleted file mode 100644
index 2d908f4..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48472.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func g() {
-	var s string
-	var i int
-	_ = s /* ERROR invalid operation: s \+ i \(mismatched types string and int\) */ + i
-}
-
-func f(i int) int {
-        i /* ERROR invalid operation: i \+= "1" \(mismatched types int and untyped string\) */ += "1"
-        return i
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48529.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48529.go
deleted file mode 100644
index a3653fa..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48529.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type T /* ERROR illegal cycle */ [U interface{ M() T[U, int] }] int
-
-type X int
-
-func (X) M() T[X] { return 0 }
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48582.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48582.go
deleted file mode 100644
index c12091b..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48582.go
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type N /* ERROR cycle */ interface {
-	int | N
-}
-
-type A /* ERROR cycle */ interface {
-	int | B
-}
-
-type B interface {
-	int | A
-}
-
-type S /* ERROR cycle */ struct {
-	I // ERROR interface contains type constraints
-}
-
-type I interface {
-	int | S
-}
-
-type P interface {
-	*P // ERROR interface contains type constraints
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48619.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48619.go
deleted file mode 100644
index 72eea1e..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48619.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func f[P any](a, _ P) {
-	var x int
-	// TODO(gri) these error messages, while correct, could be better
-	f(a, x /* ERROR type int of x does not match inferred type P for P */)
-	f(x, a /* ERROR type P of a does not match inferred type int for P */)
-}
-
-func g[P any](a, b P) {
-	g(a, b)
-	g(&a, &b)
-	g([]P{}, []P{})
-
-	// work-around: provide type argument explicitly
-	g[*P](&a, &b)
-	g[[]P]([]P{}, []P{})
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48656.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48656.go
deleted file mode 100644
index 0f60f47..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48656.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func f[P *Q, Q any](P, Q) {
-	_ = f[P]
-}
-
-func f2[P /* ERROR instantiation cycle */ *Q, Q any](P, Q) {
-	_ = f2[*P]
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48703.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48703.go
deleted file mode 100644
index 8a32c1e..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48703.go
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-import "unsafe"
-
-// The actual example from the issue.
-type List[P any] struct{}
-
-func (_ List[P]) m() (_ List[List[P]]) { return }
-
-// Other types of recursion through methods.
-type R[P any] int
-
-func (*R[R /* ERROR must be an identifier */ [int]]) m0() {}
-func (R[P]) m1(R[R[P]])                                   {}
-func (R[P]) m2(R[*P])                                     {}
-func (R[P]) m3([unsafe.Sizeof(new(R[P]))]int)             {}
-func (R[P]) m4([unsafe.Sizeof(new(R[R[P]]))]int)          {}
-
-// Mutual recursion
-type M[P any] int
-
-func (R[P]) m5(M[M[P]]) {}
-func (M[P]) m(R[R[P]])  {}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48712.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48712.go
deleted file mode 100644
index 63ce7bc..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48712.go
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func _[P comparable](x, y P) {
-	_ = x == x
-	_ = x == y
-	_ = y == x
-	_ = y == y
-
-	_ = x /* ERROR type parameter P is not comparable with < */ < y
-}
-
-func _[P comparable](x P, y any) {
-	_ = x == x
-	_ = x == y
-	_ = y == x
-	_ = y == y
-
-	_ = x /* ERROR type parameter P is not comparable with < */ < y
-}
-
-func _[P any](x, y P) {
-	_ = x /* ERROR incomparable types in type set */ == x
-	_ = x /* ERROR incomparable types in type set */ == y
-	_ = y /* ERROR incomparable types in type set */ == x
-	_ = y /* ERROR incomparable types in type set */ == y
-
-	_ = x /* ERROR type parameter P is not comparable with < */ < y
-}
-
-func _[P any](x P, y any) {
-	_ = x /* ERROR incomparable types in type set */ == x
-	_ = x /* ERROR incomparable types in type set */ == y
-	_ = y == x // ERROR incomparable types in type set
-	_ = y == y
-
-	_ = x /* ERROR type parameter P is not comparable with < */ < y
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48819.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48819.go
deleted file mode 100644
index 9262110..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48819.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-import "unsafe"
-
-type T /* ERROR illegal cycle in declaration of T */ struct {
-	T
-}
-
-func _(t T) {
-	_ = unsafe.Sizeof(t) // should not go into infinite recursion here
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48951.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48951.go
deleted file mode 100644
index a936528..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48951.go
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type (
-        A1[P any] [10]A1 /* ERROR illegal cycle */ [P]
-        A2[P any] [10]A2 /* ERROR illegal cycle */ [*P]
-        A3[P any] [10]*A3[P]
-
-        L1[P any] []L1[P]
-
-        S1[P any] struct{ f S1 /* ERROR illegal cycle */ [P] }
-        S2[P any] struct{ f S2 /* ERROR illegal cycle */ [*P] } // like example in issue
-        S3[P any] struct{ f *S3[P] }
-
-        I1[P any] interface{ I1 /* ERROR illegal cycle */ [P] }
-        I2[P any] interface{ I2 /* ERROR illegal cycle */ [*P] }
-        I3[P any] interface{ *I3 /* ERROR interface contains type constraints */ [P] }
-)
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48962.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48962.go
deleted file mode 100644
index 4270da1..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48962.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type T0[P any] struct {
-	f P
-}
-
-type T1 /* ERROR illegal cycle */ struct {
-	_ T0[T1]
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48974.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48974.go
deleted file mode 100644
index d8ff7c8..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48974.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type Fooer interface {
-	Foo()
-}
-
-type Fooable[F /* ERROR instantiation cycle */ Fooer] struct {
-	ptr F
-}
-
-func (f *Fooable[F]) Adapter() *Fooable[*FooerImpl[F]] {
-	return &Fooable[*FooerImpl[F]]{&FooerImpl[F]{}}
-}
-
-type FooerImpl[F Fooer] struct {
-}
-
-func (fi *FooerImpl[F]) Foo() {}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49003.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49003.go
deleted file mode 100644
index ece1a27..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49003.go
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func f(s string) int {
-	for range s {
-	}
-} // ERROR missing return
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49005.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49005.go
deleted file mode 100644
index 7083dc9..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49005.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type T1 interface{ M() }
-
-func F1() T1
-
-var _ = F1().(*X1 /* ERROR undeclared name: X1 */)
-
-func _() {
-	switch F1().(type) {
-	case *X1 /* ERROR undeclared name: X1 */ :
-	}
-}
-
-type T2 interface{ M() }
-
-func F2() T2
-
-var _ = F2 /* ERROR impossible type assertion: F2\(\)\.\(\*X2\)\n\t\*X2 does not implement T2 \(missing method M\) */ ().(*X2)
-
-type X2 struct{}
-
-func _() {
-	switch F2().(type) {
-	case * /* ERROR impossible type switch case: \*X2\n\tF2\(\) \(value of type T2\) cannot have dynamic type \*X2 \(missing method M\) */ X2:
-	}
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49043.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49043.go
deleted file mode 100644
index a360457..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49043.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-// The example from the issue.
-type (
-	N[P any] M /* ERROR illegal cycle */ [P]
-	M[P any] N /* ERROR illegal cycle */ [P]
-)
-
-// A slightly more complicated case.
-type (
-	A[P any] B /* ERROR illegal cycle */ [P]
-	B[P any] C[P]
-	C[P any] A[P]
-)
-
-// Confusing but valid (note that `type T *T` is valid).
-type (
-	N1[P any] *M1[P]
-	M1[P any] *N1[P]
-)
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49112.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49112.go
deleted file mode 100644
index 0efc906..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49112.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func f[P int](P) {}
-
-func _() {
-        _ = f[int]
-        _ = f[[ /* ERROR \[\]int does not implement int */ ]int]
-
-        f(0)
-        f( /* ERROR \[\]int does not implement int */ []int{})
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49179.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49179.go
deleted file mode 100644
index 75bea18..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49179.go
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func f1[P int | string]()            {}
-func f2[P ~int | string | float64]() {}
-func f3[P int](x P)                  {}
-
-type myInt int
-type myFloat float64
-
-func _() {
-	_ = f1[int]
-	_ = f1[myInt /* ERROR possibly missing ~ for int in constraint int\|string */]
-	_ = f2[myInt]
-	_ = f2[myFloat /* ERROR possibly missing ~ for float64 in constraint int\|string|float64 */]
-	var x myInt
-	f3( /* ERROR myInt does not implement int \(possibly missing ~ for int in constraint int\) */ x)
-}
-
-// test case from the issue
-
-type SliceConstraint[T any] interface {
-	[]T
-}
-
-func Map[S SliceConstraint[E], E any](s S, f func(E) E) S {
-	return s
-}
-
-type MySlice []int
-
-func f(s MySlice) {
-	Map[MySlice /* ERROR MySlice does not implement SliceConstraint\[int\] \(possibly missing ~ for \[\]int in constraint SliceConstraint\[int\]\) */, int](s, nil)
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49242.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49242.go
deleted file mode 100644
index 524a0cb..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49242.go
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func _[P int](x P) int {
-	return x // ERROR cannot use x .* as int value in return statement
-}
-
-func _[P int]() int {
-	return P /* ERROR cannot use P\(1\) .* as int value in return statement */ (1)
-}
-
-func _[P int](x int) P {
-        return x // ERROR cannot use x .* as P value in return statement
-}
-
-func _[P, Q any](x P) Q {
-        return x // ERROR cannot use x .* as Q value in return statement
-}
-
-// test case from issue
-func F[G interface{ uint }]() int {
-	f := func(uint) int { return 0 }
-	return f(G /* ERROR cannot use G\(1\) .* as uint value in argument to f */ (1))
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49247.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49247.go
deleted file mode 100644
index 3f25e0e..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49247.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type integer interface {
-	~int | ~int8 | ~int16 | ~int32 | ~int64 |
-		~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
-}
-
-func Add1024[T integer](s []T) {
-	for i, v := range s {
-		s[i] = v + 1024 // ERROR cannot convert 1024 \(untyped int constant\) to T
-	}
-}
-
-func f[T interface{ int8 }]() {
-	println(T(1024 /* ERROR cannot convert 1024 \(untyped int value\) to T */))
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49276.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49276.go
deleted file mode 100644
index 8839087..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49276.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-import "unsafe"
-
-type S /* ERROR illegal cycle in declaration of S */ struct {
-	_ [unsafe.Sizeof(s)]byte
-}
-
-var s S
-
-// Since f is a pointer, this case could be valid.
-// But it's pathological and not worth the expense.
-type T struct {
-	f *[unsafe.Sizeof(T /* ERROR illegal cycle in type declaration */ {})]int
-}
-
-// a mutually recursive case using unsafe.Sizeof
-type (
-	A1 struct {
-		_ [unsafe.Sizeof(B1{})]int
-	}
-
-	B1 struct {
-		_ [unsafe.Sizeof(A1 /* ERROR illegal cycle in type declaration */ {})]int
-	}
-)
-
-// a mutually recursive case using len
-type (
-	A2 struct {
-		f [len(B2{}.f)]int
-	}
-
-	B2 struct {
-		f [len(A2 /* ERROR illegal cycle in type declaration */ {}.f)]int
-	}
-)
-
-// test case from issue
-type a struct {
-	_ [42 - unsafe.Sizeof(a /* ERROR illegal cycle in type declaration */ {})]byte
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49296.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49296.go
deleted file mode 100644
index eaa8e4d..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49296.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func _[
-        T0 any,
-        T1 []int,
-        T2 ~float64 | ~complex128 | chan int,
-]() {
-        _ = T0(nil /* ERROR cannot convert nil to T0 */ )
-        _ = T1(1 /* ERROR cannot convert 1 .* to T1 */ )
-        _ = T2(2 /* ERROR cannot convert 2 .* to T2 */ )
-}
-
-// test case from issue
-func f[T interface{[]int}]() {
-	_ = T(1 /* ERROR cannot convert */ )
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49439.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49439.go
deleted file mode 100644
index 6cc838b..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49439.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-import "unsafe"
-
-type T0 /* ERROR illegal cycle */ [P T0[P]] struct{}
-
-type T1 /* ERROR illegal cycle */ [P T2[P]] struct{}
-type T2[P T1[P]] struct{}
-
-type T3 /* ERROR illegal cycle */ [P interface{ ~struct{ f T3[int] } }] struct{}
-
-// valid cycle in M
-type N[P M[P]] struct{}
-type M[Q any] struct { F *M[Q] }
-
-// "crazy" case
-type TC[P [unsafe.Sizeof(func() {
-        type T [P [unsafe.Sizeof(func(){})]byte] struct{}
-})]byte] struct{}
-
-// test case from issue
-type X /* ERROR illegal cycle */ [T any, PT X[T]] interface{}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49482.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49482.go
deleted file mode 100644
index d5c52dc..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49482.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-// The following is OK, per the special handling for type literals discussed in issue #49482.
-type _[P *struct{}] struct{}
-type _[P *int,] int
-type _[P (*int),] int
-
-const P = 2 // declare P to avoid noisy 'undeclared name' errors below.
-
-// The following parse as invalid array types due to parsing ambiguitiues.
-type _ [P *int /* ERROR "int \(type\) is not an expression" */ ]int
-type _ [P /* ERROR non-function P */ (*int)]int
-
-// Adding a trailing comma or an enclosing interface resolves the ambiguity.
-type _[P *int,] int
-type _[P (*int),] int
-type _[P interface{*int}] int
-type _[P interface{(*int)}] int
-
-// The following parse correctly as valid generic types.
-type _[P *struct{} | int] struct{}
-type _[P *struct{} | ~int] struct{}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49541.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49541.go
deleted file mode 100644
index c8499c1..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49541.go
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type S[A, B any] struct {
-	f int
-}
-
-func (S[A, B]) m() {}
-
-// TODO(gri): with type-type inference enabled we should only report one error
-// below. See issue #50588.
-
-func _[A any](s S /* ERROR got 1 arguments but 2 type parameters */ [A]) {
-	// we should see no follow-on errors below
-	s.f = 1
-	s.m()
-}
-
-// another test case from the issue
-
-func _() {
-	X(Interface[*F /* ERROR got 1 arguments but 2 type parameters */ [string]](Impl{}))
-}
-
-func X[Q Qer](fs Interface[Q]) {
-}
-
-type Impl struct{}
-
-func (Impl) M() {}
-
-type Interface[Q Qer] interface {
-	M()
-}
-
-type Qer interface {
-	Q()
-}
-
-type F[A, B any] struct{}
-
-func (f *F[A, B]) Q() {}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49592.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49592.go
deleted file mode 100644
index 846deaa..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49592.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func _() {
-	var x *interface{}
-	var y interface{}
-	_ = x == y
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49602.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49602.go
deleted file mode 100644
index 9edbf14..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49602.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type M interface {
-        m()
-}
-
-type C interface {
-        comparable
-}
-
-type _ interface{
-        int | M // ERROR cannot use p\.M in union \(p\.M contains methods\)
-        int | comparable // ERROR cannot use comparable in union
-        int | C // ERROR cannot use p\.C in union \(p\.C embeds comparable\)
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49705.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49705.go
deleted file mode 100644
index 5b5fba2..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49705.go
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type Integer interface {
-	~int | ~int8 | ~int16 | ~int32 | ~int64 |
-	~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
-}
-
-func shl[I Integer](n int) I {
-	return 1 << n
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49735.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49735.go
deleted file mode 100644
index 5087022..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49735.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func _[P1 any, P2 ~byte](s1 P1, s2 P2) {
-        _ = append(nil /* ERROR first argument to append must be a slice; have untyped nil */ , 0)
-        _ = append(s1 /* ERROR s1 .* has no core type */ , 0)
-        _ = append(s2 /* ERROR s2 .* has core type byte */ , 0)
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49739.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49739.go
deleted file mode 100644
index 46b1e71..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49739.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Verify that we get an empty type set (not just an error)
-// when using an invalid ~A.
-
-package p
-
-type A int
-type C interface {
-	~ /* ERROR invalid use of ~ */ A
-}
-
-func f[_ C]()              {}
-func g[_ interface{ C }]() {}
-func h[_ C | int]()        {}
-
-func _() {
-	_ = f[int /* ERROR cannot implement C \(empty type set\) */]
-	_ = g[int /* ERROR cannot implement interface{C} \(empty type set\) */]
-	_ = h[int]
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49864.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49864.go
deleted file mode 100644
index 0437e74..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49864.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func _[P ~int, Q any](p P) {
-	_ = Q(p /* ERROR cannot convert */ )
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50259.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50259.go
deleted file mode 100644
index 6df8c64..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50259.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-var x T[B]
-
-type T[_ any] struct{}
-type A T[B]
-type B = T[A]
-
-// test case from issue
-
-var v Box[Step]
-type Box[T any] struct{}
-type Step = Box[StepBox]
-type StepBox Box[Step]
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50276.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50276.go
deleted file mode 100644
index 97e477e..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50276.go
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-// simplified test case
-
-type transform[T any] struct{}
-type pair[S any] struct {}
-
-var _ transform[step]
-
-type box transform[step]
-type step = pair[box]
-
-// test case from issue
-
-type Transform[T any] struct{ hold T }
-type Pair[S, T any] struct {
-	First  S
-	Second T
-}
-
-var first Transform[Step]
-
-// This line doesn't use the Step alias, and it compiles fine if you uncomment it.
-var second Transform[Pair[Box, interface{}]]
-
-type Box *Transform[Step]
-
-// This line is the same as the `first` line, but it comes after the Box declaration and
-// does not break the compile.
-var third Transform[Step]
-
-type Step = Pair[Box, interface{}]
-
-// This line also does not break the compile
-var fourth Transform[Step]
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50281.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50281.go
deleted file mode 100644
index f333e81..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50281.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func _[S string | []byte](s S) {
-	var buf []byte
-	_ = append(buf, s...)
-}
-
-func _[S ~string | ~[]byte](s S) {
-	var buf []byte
-	_ = append(buf, s...)
-}
-
-// test case from issue
-
-type byteseq interface {
-	string | []byte
-}
-
-// This should allow to eliminate the two functions above.
-func AppendByteString[source byteseq](buf []byte, s source) []byte {
-	return append(buf, s[1:6]...)
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50321.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50321.go
deleted file mode 100644
index 199e66e..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50321.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func Ln[A A /* ERROR cannot use a type parameter as constraint */ ](p A) {
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50372.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50372.go
deleted file mode 100644
index 0f15dc0..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50372.go
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func _(s []int) {
-        var i, j, k, l int
-        _, _, _, _ = i, j, k, l
-
-        for range s {}
-        for i = range s {}
-        for i, j = range s {}
-        for i, j, k /* ERROR range clause permits at most two iteration variables */ = range s {}
-        for i, j, k /* ERROR range clause permits at most two iteration variables */, l = range s {}
-}
-
-func _(s chan int) {
-        var i, j, k, l int
-        _, _, _, _ = i, j, k, l
-
-        for range s {}
-        for i = range s {}
-        for i, j /* ERROR range over .* permits only one iteration variable */ = range s {}
-        for i, j /* ERROR range over .* permits only one iteration variable */, k = range s {}
-        for i, j /* ERROR range over .* permits only one iteration variable */, k, l = range s {}
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50417.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50417.go
deleted file mode 100644
index 2caef1b..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50417.go
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Field accesses through type parameters are disabled
-// until we have a more thorough understanding of the
-// implications on the spec. See issue #51576.
-
-package p
-
-type Sf struct {
-        f int
-}
-
-func f0[P Sf](p P) {
-        _ = p.f // ERROR p\.f undefined
-        p.f /* ERROR p\.f undefined */ = 0
-}
-
-func f0t[P ~struct{f int}](p P) {
-        _ = p.f // ERROR p\.f undefined
-        p.f /* ERROR p\.f undefined */ = 0
-}
-
-var _ = f0[Sf]
-var _ = f0t[Sf]
-
-var _ = f0[Sm /* ERROR does not implement */ ]
-var _ = f0t[Sm /* ERROR does not implement */ ]
-
-func f1[P interface{ Sf; m() }](p P) {
-        _ = p.f // ERROR p\.f undefined
-        p.f /* ERROR p\.f undefined */ = 0
-        p.m()
-}
-
-var _ = f1[Sf /* ERROR missing method m */ ]
-var _ = f1[Sm /* ERROR does not implement */ ]
-
-type Sm struct {}
-
-func (Sm) m() {}
-
-type Sfm struct {
-        f int
-}
-
-func (Sfm) m() {}
-
-func f2[P interface{ Sfm; m() }](p P) {
-        _ = p.f // ERROR p\.f undefined
-        p.f /* ERROR p\.f undefined */ = 0
-        p.m()
-}
-
-var _ = f2[Sfm]
-
-// special case: core type is a named pointer type
-
-type PSfm *Sfm
-
-func f3[P interface{ PSfm }](p P) {
-        _ = p.f // ERROR p\.f undefined
-        p.f /* ERROR p\.f undefined */ = 0
-        p.m /* ERROR type P has no field or method m */ ()
-}
-
-var _ = f3[PSfm]
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50426.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50426.go
deleted file mode 100644
index 17ec0ce..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50426.go
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type A1 [2]uint64
-type A2 [2]uint64
-
-func (a A1) m() A1 { return a }
-func (a A2) m() A2 { return a }
-
-func f[B any, T interface {
-	A1 | A2
-	m() T
-}](v T) {
-}
-
-func _() {
-	var v A2
-	// Use function type inference to infer type A2 for T.
-	// Don't use constraint type inference before function
-	// type inference for typed arguments, otherwise it would
-	// infer type [2]uint64 for T which doesn't have method m
-	// (was the bug).
-	f[int](v)
-}
-
-// Keep using constraint type inference before function type
-// inference for untyped arguments so we infer type float64
-// for E below, and not int (which would not work).
-func g[S ~[]E, E any](S, E) {}
-
-func _() {
-	var s []float64
-	g[[]float64](s, 0)
-}
-
-// Keep using constraint type inference after function
-// type inference for untyped arguments so we infer
-// missing type arguments for which we only have the
-// untyped arguments as starting point.
-func h[E any, R []E](v E) R { return R{v} }
-func _() []int              { return h(0) }
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50450.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50450.go
deleted file mode 100644
index bae3111..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50450.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type S struct{}
-
-func f[P S]() {}
-
-var _ = f[S]
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50516.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50516.go
deleted file mode 100644
index f73015e..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50516.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func _[P struct{ f int }](x P) {
-	_ = x.g // ERROR type P has no field or method g
-}
-
-func _[P struct{ f int } | struct{ g int }](x P) {
-	_ = x.g // ERROR type P has no field or method g
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50646.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50646.go
deleted file mode 100644
index 3bdba11..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50646.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func f1[_ comparable]()              {}
-func f2[_ interface{ comparable }]() {}
-
-type T interface{ m() }
-
-func _[P comparable, Q ~int, R any]() {
-	_ = f1[int]
-	_ = f1[T /* ERROR T does not implement comparable */ ]
-	_ = f1[any /* ERROR any does not implement comparable */ ]
-	_ = f1[P]
-	_ = f1[Q]
-	_ = f1[R /* ERROR R does not implement comparable */]
-
-	_ = f2[int]
-	_ = f2[T /* ERROR T does not implement comparable */ ]
-	_ = f2[any /* ERROR any does not implement comparable */ ]
-	_ = f2[P]
-	_ = f2[Q]
-	_ = f2[R /* ERROR R does not implement comparable */]
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50729.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50729.go
deleted file mode 100644
index fe19fdf..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50729.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-// version 1
-var x1 T1[B1]
-
-type T1[_ any] struct{}
-type A1 T1[B1]
-type B1 = T1[A1]
-
-// version 2
-type T2[_ any] struct{}
-type A2 T2[B2]
-type B2 = T2[A2]
-
-var x2 T2[B2]
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50755.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50755.go
deleted file mode 100644
index afc7b24..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50755.go
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-// The core type of M2 unifies with the type of m1
-// during function argument type inference.
-// M2's constraint is unnamed.
-func f1[K1 comparable, E1 any](m1 map[K1]E1) {}
-
-func f2[M2 map[string]int](m2 M2) {
-	f1(m2)
-}
-
-// The core type of M3 unifies with the type of m1
-// during function argument type inference.
-// M3's constraint is named.
-type Map3 map[string]int
-
-func f3[M3 Map3](m3 M3) {
-	f1(m3)
-}
-
-// The core type of M5 unifies with the core type of M4
-// during constraint type inference.
-func f4[M4 map[K4]int, K4 comparable](m4 M4) {}
-
-func f5[M5 map[K5]int, K5 comparable](m5 M5) {
-	f4(m5)
-}
-
-// test case from issue
-
-func Copy[MC ~map[KC]VC, KC comparable, VC any](dst, src MC) {
-	for k, v := range src {
-		dst[k] = v
-	}
-}
-
-func Merge[MM ~map[KM]VM, KM comparable, VM any](ms ...MM) MM {
-	result := MM{}
-	for _, m := range ms {
-		Copy(result, m)
-	}
-	return result
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50779.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50779.go
deleted file mode 100644
index fe68c28..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50779.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type AC interface {
-	C
-}
-
-type ST []int
-
-type R[S any, P any] struct{}
-
-type SR = R[SS, ST]
-
-type SS interface {
-	NSR(any) *SR // ERROR invalid use of type alias SR in recursive type
-}
-
-type C interface {
-	NSR(any) *SR
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50782.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50782.go
deleted file mode 100644
index fd1ab11..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50782.go
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Field accesses through type parameters are disabled
-// until we have a more thorough understanding of the
-// implications on the spec. See issue #51576.
-
-package p
-
-// The first example from the issue.
-type Numeric interface {
-	~int | ~int8 | ~int16 | ~int32 | ~int64
-}
-
-// numericAbs matches numeric types with an Abs method.
-type numericAbs[T Numeric] interface {
-	~struct{ Value T }
-	Abs() T
-}
-
-// AbsDifference computes the absolute value of the difference of
-// a and b, where the absolute value is determined by the Abs method.
-func absDifference[T numericAbs[T /* ERROR T does not implement Numeric */]](a, b T) T {
-	// Field accesses are not permitted for now. Keep an error so
-	// we can find and fix this code once the situation changes.
-	return a.Value // ERROR a\.Value undefined
-	// TODO: The error below should probably be positioned on the '-'.
-	// d := a /* ERROR "invalid operation: operator - not defined" */ .Value - b.Value
-	// return d.Abs()
-}
-
-// The second example from the issue.
-type T[P int] struct{ f P }
-
-func _[P T[P /* ERROR "P does not implement int" */ ]]() {}
-
-// Additional tests
-func _[P T[T /* ERROR "T\[P\] does not implement int" */ [P /* ERROR "P does not implement int" */ ]]]() {}
-func _[P T[Q /* ERROR "Q does not implement int" */ ], Q T[P /* ERROR "P does not implement int" */ ]]() {}
-func _[P T[Q], Q int]() {}
-
-type C[P comparable] struct{ f P }
-func _[P C[C[P]]]() {}
-func _[P C[C /* ERROR "C\[Q\] does not implement comparable" */ [Q /* ERROR "Q does not implement comparable" */]], Q func()]() {}
-func _[P [10]C[P]]() {}
-func _[P struct{ f C[C[P]]}]() {}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50816.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50816.go
deleted file mode 100644
index e7e31d9..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50816.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package pkg
-
-type I interface {
-	Foo()
-}
-
-type T1 struct{}
-
-func (T1) foo() {}
-
-type T2 struct{}
-
-func (T2) foo() string { return "" }
-
-func _() {
-	var i I
-	_ = i /* ERROR impossible type assertion: i\.\(T1\)\n\tT1 does not implement I \(missing method Foo\)\n\t\thave foo\(\)\n\t\twant Foo\(\) */ .(T1)
-	_ = i /* ERROR impossible type assertion: i\.\(T2\)\n\tT2 does not implement I \(missing method Foo\)\n\t\thave foo\(\) string\n\t\twant Foo\(\) */ .(T2)
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50833.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50833.go
deleted file mode 100644
index e912e4d..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50833.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type (
-	S  struct{ f int }
-	PS *S
-)
-
-func a() []*S { return []*S{{f: 1}} }
-func b() []PS { return []PS{{f: 1}} }
-
-func c[P *S]() []P { return []P{{f: 1}} }
-func d[P PS]() []P { return []P{{f: 1}} }
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50912.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50912.go
deleted file mode 100644
index f161925..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50912.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func Real[P ~complex128](x P) {
-	_ = real(x /* ERROR not supported */ )
-}
-
-func Imag[P ~complex128](x P) {
-	_ = imag(x /* ERROR not supported */ )
-}
-
-func Complex[P ~float64](x P) {
-	_ = complex(x /* ERROR not supported */ , 0)
-	_ = complex(0 /* ERROR not supported */ , x)
-	_ = complex(x /* ERROR not supported */ , x)
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50918.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50918.go
deleted file mode 100644
index 41604b8..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50918.go
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type thing1 struct {
-	things []string
-}
-
-type thing2 struct {
-	things []thing1
-}
-
-func _() {
-	var a1, b1 thing1
-	_ = a1 /* ERROR struct containing \[\]string cannot be compared */ == b1
-
-	var a2, b2 thing2
-	_ = a2 /* ERROR struct containing \[\]thing1 cannot be compared */ == b2
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50929.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50929.go
deleted file mode 100644
index 3629ecf..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50929.go
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file is tested when running "go test -run Manual"
-// without source arguments. Use for one-off debugging.
-
-package p
-
-import "fmt"
-
-type F[A, B any] int
-
-func G[A, B any](F[A, B]) {
-}
-
-func _() {
-	// TODO(gri) only report one error below (issue #50932)
-	var x F /* ERROR got 1 arguments but 2 type parameters */ [int]
-	G(x /* ERROR does not match */)
-}
-
-// test case from issue
-// (lots of errors but doesn't crash anymore)
-
-type RC[G any, RG any] interface {
-	~[]RG
-}
-
-type RG[G any] struct{}
-
-type RSC[G any] []*RG[G]
-
-type M[Rc RC[G, RG], G any, RG any] struct {
-	Fn func(Rc)
-}
-
-type NFn[Rc RC[G, RG], G any, RG any] func(Rc)
-
-func NC[Rc RC[G, RG], G any, RG any](nFn NFn[Rc, G, RG]) {
-	var empty Rc
-	nFn(empty)
-}
-
-func NSG[G any](c RSC[G]) {
-	fmt.Println(c)
-}
-
-func MMD[Rc RC /* ERROR got 1 arguments */ [RG], RG any, G any]() M /* ERROR got 2 arguments */ [Rc, RG] {
-
-	var nFn NFn /* ERROR got 2 arguments */ [Rc, RG]
-
-	var empty Rc
-	switch any(empty).(type) {
-	case BC /* ERROR undeclared name: BC */ :
-
-	case RSC[G]:
-		nFn = NSG /* ERROR cannot use NSG\[G\] */ [G]
-	}
-
-	return M /* ERROR got 2 arguments */ [Rc, RG]{
-		Fn: func(rc Rc) {
-			NC(nFn /* ERROR does not match */ )
-		},
-	}
-
-	return M /* ERROR got 2 arguments */ [Rc, RG]{}
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50965.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50965.go
deleted file mode 100644
index bf2dcc9..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue50965.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func _(x int, c string) {
-	switch x {
-	case c /* ERROR invalid case c in switch on x \(mismatched types string and int\) */ :
-	}
-}
-
-func _(x, c []int) {
-	switch x {
-	case c /* ERROR invalid case c in switch on x \(slice can only be compared to nil\) */ :
-	}
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51048.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51048.go
deleted file mode 100644
index 5830837..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51048.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func _[P int]() {
-	_ = f[P]
-}
-
-func f[T int]() {}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51145.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51145.go
deleted file mode 100644
index b84391d..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51145.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-import "fmt"
-
-type (
-	_ [fmt /* ERROR invalid array length fmt */ ]int
-	_ [float64 /* ERROR invalid array length float64 */ ]int
-	_ [f /* ERROR invalid array length f */ ]int
-	_ [nil /* ERROR invalid array length nil */ ]int
-)
-
-func f()
-
-var _ fmt.Stringer // use fmt
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51158.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51158.go
deleted file mode 100644
index 3edc505..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51158.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-// Type checking the following code should not cause an infinite recursion.
-func f[M map[K]int, K comparable](m M) {
-        f(m)
-}
-
-// Equivalent code using mutual recursion.
-func f1[M map[K]int, K comparable](m M) {
-        f2(m)
-}
-func f2[M map[K]int, K comparable](m M) {
-        f1(m)
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51229.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51229.go
deleted file mode 100644
index ef873e6..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51229.go
+++ /dev/null
@@ -1,164 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-// Constraint type inference should be independent of the
-// ordering of the type parameter declarations. Try all
-// permutations in the test case below.
-// Permutations produced by https://go.dev/play/p/PHcZNGJTEBZ.
-
-func f00[S1 ~[]E1, S2 ~[]E2, E1 ~byte, E2 ~byte](S1, S2) {}
-func f01[S2 ~[]E2, S1 ~[]E1, E1 ~byte, E2 ~byte](S1, S2) {}
-func f02[E1 ~byte, S1 ~[]E1, S2 ~[]E2, E2 ~byte](S1, S2) {}
-func f03[S1 ~[]E1, E1 ~byte, S2 ~[]E2, E2 ~byte](S1, S2) {}
-func f04[S2 ~[]E2, E1 ~byte, S1 ~[]E1, E2 ~byte](S1, S2) {}
-func f05[E1 ~byte, S2 ~[]E2, S1 ~[]E1, E2 ~byte](S1, S2) {}
-func f06[E2 ~byte, S2 ~[]E2, S1 ~[]E1, E1 ~byte](S1, S2) {}
-func f07[S2 ~[]E2, E2 ~byte, S1 ~[]E1, E1 ~byte](S1, S2) {}
-func f08[S1 ~[]E1, E2 ~byte, S2 ~[]E2, E1 ~byte](S1, S2) {}
-func f09[E2 ~byte, S1 ~[]E1, S2 ~[]E2, E1 ~byte](S1, S2) {}
-func f10[S2 ~[]E2, S1 ~[]E1, E2 ~byte, E1 ~byte](S1, S2) {}
-func f11[S1 ~[]E1, S2 ~[]E2, E2 ~byte, E1 ~byte](S1, S2) {}
-func f12[S1 ~[]E1, E1 ~byte, E2 ~byte, S2 ~[]E2](S1, S2) {}
-func f13[E1 ~byte, S1 ~[]E1, E2 ~byte, S2 ~[]E2](S1, S2) {}
-func f14[E2 ~byte, S1 ~[]E1, E1 ~byte, S2 ~[]E2](S1, S2) {}
-func f15[S1 ~[]E1, E2 ~byte, E1 ~byte, S2 ~[]E2](S1, S2) {}
-func f16[E1 ~byte, E2 ~byte, S1 ~[]E1, S2 ~[]E2](S1, S2) {}
-func f17[E2 ~byte, E1 ~byte, S1 ~[]E1, S2 ~[]E2](S1, S2) {}
-func f18[E2 ~byte, E1 ~byte, S2 ~[]E2, S1 ~[]E1](S1, S2) {}
-func f19[E1 ~byte, E2 ~byte, S2 ~[]E2, S1 ~[]E1](S1, S2) {}
-func f20[S2 ~[]E2, E2 ~byte, E1 ~byte, S1 ~[]E1](S1, S2) {}
-func f21[E2 ~byte, S2 ~[]E2, E1 ~byte, S1 ~[]E1](S1, S2) {}
-func f22[E1 ~byte, S2 ~[]E2, E2 ~byte, S1 ~[]E1](S1, S2) {}
-func f23[S2 ~[]E2, E1 ~byte, E2 ~byte, S1 ~[]E1](S1, S2) {}
-
-type myByte byte
-
-func _(a []byte, b []myByte) {
-	f00(a, b)
-	f01(a, b)
-	f02(a, b)
-	f03(a, b)
-	f04(a, b)
-	f05(a, b)
-	f06(a, b)
-	f07(a, b)
-	f08(a, b)
-	f09(a, b)
-	f10(a, b)
-	f11(a, b)
-	f12(a, b)
-	f13(a, b)
-	f14(a, b)
-	f15(a, b)
-	f16(a, b)
-	f17(a, b)
-	f18(a, b)
-	f19(a, b)
-	f20(a, b)
-	f21(a, b)
-	f22(a, b)
-	f23(a, b)
-}
-
-// Constraint type inference may have to iterate.
-// Again, the order of the type parameters shouldn't matter.
-
-func g0[S ~[]E, M ~map[string]S, E any](m M) {}
-func g1[M ~map[string]S, S ~[]E, E any](m M) {}
-func g2[E any, S ~[]E, M ~map[string]S](m M) {}
-func g3[S ~[]E, E any, M ~map[string]S](m M) {}
-func g4[M ~map[string]S, E any, S ~[]E](m M) {}
-func g5[E any, M ~map[string]S, S ~[]E](m M) {}
-
-func _(m map[string][]byte) {
-	g0(m)
-	g1(m)
-	g2(m)
-	g3(m)
-	g4(m)
-	g5(m)
-}
-
-// Worst-case scenario.
-// There are 10 unknown type parameters. In each iteration of
-// constraint type inference we infer one more, from right to left.
-// Each iteration looks repeatedly at all 11 type parameters,
-// requiring a total of 10*11 = 110 iterations with the current
-// implementation. Pathological case.
-
-func h[K any, J ~*K, I ~*J, H ~*I, G ~*H, F ~*G, E ~*F, D ~*E, C ~*D, B ~*C, A ~*B](x A) {}
-
-func _(x **********int) {
-	h(x)
-}
-
-// Examples with channel constraints and tilde.
-
-func ch1[P chan<- int]() (_ P)           { return } // core(P) == chan<- int   (single type, no tilde)
-func ch2[P ~chan int]()                  { return } // core(P) == ~chan<- int  (tilde)
-func ch3[P chan E, E any](E)             { return } // core(P) == chan<- E     (single type, no tilde)
-func ch4[P chan E | ~chan<- E, E any](E) { return } // core(P) == ~chan<- E    (tilde)
-func ch5[P chan int | chan<- int]()      { return } // core(P) == chan<- int   (not a single type)
-
-func _() {
-	// P can be inferred as there's a single specific type and no tilde.
-	var _ chan int = ch1 /* ERROR cannot use ch1.*value of type chan<- int */ ()
-	var _ chan<- int = ch1()
-
-	// P cannot be inferred as there's a tilde.
-	ch2( /* ERROR cannot infer P */ )
-	type myChan chan int
-	ch2[myChan]()
-
-	// P can be inferred as there's a single specific type and no tilde.
-	var e int
-	ch3(e)
-
-	// P cannot be inferred as there's more than one specific type and a tilde.
-	ch4( /* ERROR cannot infer P */ e)
-	_ = ch4[chan int]
-
-	// P cannot be inferred as there's more than one specific type.
-	ch5( /* ERROR cannot infer P */ )
-	ch5[chan<- int]()
-}
-
-// test case from issue
-
-func equal[M1 ~map[K1]V1, M2 ~map[K2]V2, K1, K2 ~uint32, V1, V2 ~string](m1 M1, m2 M2) bool {
-	if len(m1) != len(m2) {
-		return false
-	}
-	for k, v1 := range m1 {
-		if v2, ok := m2[K2(k)]; !ok || V2(v1) != v2 {
-			return false
-		}
-	}
-	return true
-}
-
-func equalFixed[K1, K2 ~uint32, V1, V2 ~string](m1 map[K1]V1, m2 map[K2]V2) bool {
-	if len(m1) != len(m2) {
-		return false
-	}
-	for k, v1 := range m1 {
-		if v2, ok := m2[K2(k)]; !ok || v1 != V1(v2) {
-			return false
-		}
-	}
-	return true
-}
-
-type (
-	someNumericID uint32
-	someStringID  string
-)
-
-func _() {
-	foo := map[uint32]string{10: "bar"}
-	bar := map[someNumericID]someStringID{10: "bar"}
-	equal(foo, bar)
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51232.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51232.go
deleted file mode 100644
index 3fa6a05..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51232.go
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type RC[RG any] interface {
-	~[]RG
-}
-
-type Fn[RCT RC[RG], RG any] func(RCT)
-
-type F[RCT RC[RG], RG any] interface {
-	Fn() Fn /* ERROR got 1 arguments */ [RCT]
-}
-
-type concreteF[RCT RC[RG], RG any] struct {
-	makeFn func() Fn /* ERROR got 1 arguments */ [RCT]
-}
-
-func (c *concreteF[RCT, RG]) Fn() Fn /* ERROR got 1 arguments */ [RCT] {
-	return c.makeFn()
-}
-
-func NewConcrete[RCT RC[RG], RG any](Rc RCT) F /* ERROR got 1 arguments */ [RCT] {
-	// TODO(rfindley): eliminate the duplicate error below.
-	return & /* ERROR cannot use .* as F\[RCT\] */ concreteF /* ERROR got 1 arguments */ [RCT]{
-		makeFn: nil,
-	}
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51233.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51233.go
deleted file mode 100644
index 9c15028..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51233.go
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-// As of issue #51527, type-type inference has been disabled.
-
-type RC[RG any] interface {
-	~[]RG
-}
-
-type Fn[RCT RC[RG], RG any] func(RCT)
-
-type FFn[RCT RC[RG], RG any] func() Fn /* ERROR got 1 arguments */ [RCT]
-
-type F[RCT RC[RG], RG any] interface {
-	Fn() Fn /* ERROR got 1 arguments */ [RCT]
-}
-
-type concreteF[RCT RC[RG], RG any] struct {
-	makeFn FFn /* ERROR got 1 arguments */ [RCT]
-}
-
-func (c *concreteF[RCT, RG]) Fn() Fn /* ERROR got 1 arguments */ [RCT] {
-	return c.makeFn()
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51257.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51257.go
deleted file mode 100644
index bc4208e..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51257.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func f[_ comparable]() {}
-
-type S1 struct{ x int }
-type S2 struct{ x any }
-type S3 struct{ x [10]interface{ m() } }
-
-func _[P1 comparable, P2 S2]() {
-	_ = f[S1]
-	_ = f[S2 /* ERROR S2 does not implement comparable */ ]
-	_ = f[S3 /* ERROR S3 does not implement comparable */ ]
-
-	type L1 struct { x P1 }
-	type L2 struct { x P2 }
-	_ = f[L1]
-	_ = f[L2 /* ERROR L2 does not implement comparable */ ]
-}
-
-
-// example from issue
-
-type Set[T comparable] map[T]struct{}
-
-func NewSetFromSlice[T comparable](items []T) *Set[T] {
-	s := Set[T]{}
-
-	for _, item := range items {
-		s[item] = struct{}{}
-	}
-
-	return &s
-}
-
-type T struct{ x any }
-
-func main() {
-	NewSetFromSlice( /* ERROR T does not implement comparable */ []T{
-		{"foo"},
-		{5},
-	})
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51335.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51335.go
deleted file mode 100644
index 0b5a1af..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51335.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type S1 struct{}
-type S2 struct{}
-
-func _[P *S1|*S2]() {
-	_= []P{{ /* ERROR invalid composite literal element type P: no core type */ }}
-}
-
-func _[P *S1|S1]() {
-	_= []P{{ /* ERROR invalid composite literal element type P: no core type */ }}
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51339.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51339.go
deleted file mode 100644
index 84e551d..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51339.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file is tested when running "go test -run Manual"
-// without source arguments. Use for one-off debugging.
-
-package p
-
-type T[P any, B *P] struct{}
-
-func (T /* ERROR cannot use generic type */ ) m0() {}
-
-// TODO(rfindley): eliminate the duplicate errors here.
-func (T /* ERROR got 1 type parameter, but receiver base type declares 2 */ /* ERROR got 1 arguments but 2 type parameters */ [_]) m1() {}
-func (T[_, _]) m2() {}
-// TODO(gri) this error is unfortunate (issue #51343)
-func (T /* ERROR got 3 arguments but 2 type parameters */ [_, _, _]) m3() {}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51360.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51360.go
deleted file mode 100644
index 447ce03..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51360.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func _() {
-	len. /* ERROR cannot select on len */ Println
-	len. /* ERROR cannot select on len */ Println()
-	_ = len. /* ERROR cannot select on len */ Println
-	_ = len[ /* ERROR cannot index len */ 0]
-	_ = *len /* ERROR cannot indirect len */
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51376.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51376.go
deleted file mode 100644
index 4eba071..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51376.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type Map map[string]int
-
-func f[M ~map[K]V, K comparable, V any](M) {}
-func g[M map[K]V, K comparable, V any](M) {}
-
-func _[M1 ~map[K]V, M2 map[K]V, K comparable, V any]() {
-        var m1 M1
-        f(m1)
-        g( /* ERROR M1 does not implement map\[K\]V */ m1) // M1 has tilde
-
-        var m2 M2
-        f(m2)
-        g(m2) // M1 does not have tilde
-
-        var m3 Map
-        f(m3)
-        g( /* ERROR Map does not implement map\[string\]int */ m3) // M in g does not have tilde
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51386.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51386.go
deleted file mode 100644
index ef62239..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51386.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type myString string
-
-func _[P ~string | ~[]byte | ~[]rune]() {
-	_ = P("")
-	const s myString = ""
-	_ = P(s)
-}
-
-func _[P myString]() {
-	_ = P("")
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51437.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51437.go
deleted file mode 100644
index 3762615..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51437.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type T struct{}
-
-func (T) m() []int { return nil }
-
-func f(x T) {
-	for _, x := range func() []int {
-		return x.m() // x declared in parameter list of f
-	}() {
-		_ = x // x declared by range clause
-	}
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51472.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51472.go
deleted file mode 100644
index f19d906..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51472.go
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func _[T comparable](x T) {
-        _ = x == x
-}
-
-func _[T interface{interface{comparable}}](x T) {
-        _ = x == x
-}
-
-func _[T interface{comparable; interface{comparable}}](x T) {
-        _ = x == x
-}
-
-func _[T interface{comparable; ~int}](x T) {
-        _ = x == x
-}
-
-func _[T interface{comparable; ~[]byte}](x T) {
-        _ = x /* ERROR cannot compare */ == x
-}
-
-// TODO(gri) The error message here should be better. See issue #51525.
-func _[T interface{comparable; ~int; ~string}](x T) {
-        _ = x /* ERROR cannot compare */ == x
-}
-
-// TODO(gri) The error message here should be better. See issue #51525.
-func _[T interface{~int; ~string}](x T) {
-        _ = x /* ERROR cannot compare */ == x
-}
-
-func _[T interface{comparable; interface{~int}; interface{int|float64}}](x T) {
-        _ = x == x
-}
-
-func _[T interface{interface{comparable; ~int}; interface{~float64; comparable; m()}}](x T) {
-        _ = x /* ERROR cannot compare */ == x
-}
-
-// test case from issue
-
-func f[T interface{comparable; []byte|string}](x T) {
-        _ = x == x
-}
-
-func _(s []byte) {
-	f( /* ERROR \[\]byte does not implement interface{comparable; \[\]byte\|string} */ s)
-        _ = f[[ /* ERROR does not implement */ ]byte]
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51509.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51509.go
deleted file mode 100644
index 5ae4717..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51509.go
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type T /* ERROR illegal cycle */ T.x
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51525.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51525.go
deleted file mode 100644
index af1d1e6..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51525.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func _[T interface {
-	int
-	string
-}](x T) {
-	_ = x /* ERROR empty type set */ == x
-}
-
-func _[T interface{ int | []byte }](x T) {
-	_ = x /* ERROR incomparable types in type set */ == x
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51533.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51533.go
deleted file mode 100644
index bf46f75..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51533.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func _(x any) {
-	switch x {
-	case 0:
-		fallthrough // ERROR fallthrough statement out of place
-		_ = x
-	default:
-	}
-
-	switch x.(type) {
-	case int:
-		fallthrough // ERROR cannot fallthrough in type switch
-	default:
-	}
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51578.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51578.go
deleted file mode 100644
index 5c204ba..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51578.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-var _ = (*interface /* ERROR interface contains type constraints */ {int})(nil)
-
-// abbreviated test case from issue
-
-type TypeSet interface{ int | string }
-
-func _() {
-	f((*TypeSet /* ERROR interface contains type constraints */)(nil))
-}
-
-func f(any) {}
\ No newline at end of file
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51593.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51593.go
deleted file mode 100644
index d323618..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51593.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func f[P interface{ m(R) }, R any]() {}
-
-type T = interface { m(int) }
-
-func _() {
-	_ = f[ /* ERROR cannot infer R */ T] // don't crash in type inference
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51607.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51607.go
deleted file mode 100644
index d8df143..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51607.go
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-// Interface types must be ignored during overlap test.
-
-type (
-	T1 interface{int}
-	T2 interface{~int}
-	T3 interface{T1 | bool | string}
-	T4 interface{T2 | ~bool | ~string}
-)
-
-type (
-	// overlap errors for non-interface terms
-	// (like the interface terms, but explicitly inlined)
-	_ interface{int | int /* ERROR overlapping terms int and int */ }
-	_ interface{int | ~ /* ERROR overlapping terms ~int and int */ int}
-	_ interface{~int | int /* ERROR overlapping terms int and ~int */ }
-	_ interface{~int | ~ /* ERROR overlapping terms ~int and ~int */ int}
-
-	_ interface{T1 | bool | string | T1 | bool /* ERROR overlapping terms bool and bool */ | string /* ERROR overlapping terms string and string */ }
-	_ interface{T1 | bool | string | T2 | ~ /* ERROR overlapping terms ~bool and bool */ bool | ~ /* ERROR overlapping terms ~string and string */ string}
-
-	// no errors for interface terms
-	_ interface{T1 | T1}
-	_ interface{T1 | T2}
-	_ interface{T2 | T1}
-	_ interface{T2 | T2}
-
-	_ interface{T3 | T3 | int}
-	_ interface{T3 | T4 | bool }
-	_ interface{T4 | T3 | string }
-	_ interface{T4 | T4 | float64 }
-)
-
-func _[_ T1 | bool | string | T1 | bool /* ERROR overlapping terms */ ]() {}
-func _[_ T1 | bool | string | T2 | ~ /* ERROR overlapping terms */ bool ]() {}
-func _[_ T2 | ~bool | ~string | T1 | bool /* ERROR overlapping terms */ ]() {}
-func _[_ T2 | ~bool | ~string | T2 | ~ /* ERROR overlapping terms */ bool ]() {}
-
-func _[_ T3 | T3 | int]() {}
-func _[_ T3 | T4 | bool]() {}
-func _[_ T4 | T3 | string]() {}
-func _[_ T4 | T4 | float64]() {}
-
-// test cases from issue
-
-type _ interface {
-	interface {bool | int} | interface {bool | string}
-}
-
-type _ interface {
-	interface {bool | int} ; interface {bool | string}
-}
-
-type _ interface {
-	interface {bool; int} ; interface {bool; string}
-}
-
-type _ interface {
-	interface {bool; int} | interface {bool; string}
-}
\ No newline at end of file
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51610.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51610.go
deleted file mode 100644
index d10c788..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51610.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func _[P int | float64 | complex128]() {
-	_ = map[P]int{1: 1, 1.0 /* ERROR duplicate key 1 */ : 2, 1 /* ERROR duplicate key \(1 \+ 0i\) */ + 0i: 3}
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51616.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51616.go
deleted file mode 100644
index e0efc9e..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51616.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type (
-        C[T any] interface{~int; M() T}
-
-        _ C[bool]
-        _ comparable
-        _ interface {~[]byte | ~string}
-
-        // Alias type declarations may refer to "constraint" types
-        // like ordinary type declarations.
-        _ = C[bool]
-        _ = comparable
-        _ = interface {~[]byte | ~string}
-)
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51658.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51658.go
deleted file mode 100644
index c437c92..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51658.go
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type F { // ERROR syntax error
-	float64
-} // ERROR syntax error
-
-func _[T F | int](x T) {
-	_ = x == 0 // don't crash when recording type of 0
-}
-
-// test case from issue
-
-type FloatType { // ERROR syntax error
-	float32 | float64
-} // ERROR syntax error
-
-type IntegerType interface {
-	int8 | int16 | int32 | int64 | int |
-		uint8 | uint16 | uint32 | uint64 | uint
-}
-
-type ComplexType interface {
-	complex64 | complex128
-}
-
-type Number interface {
-	FloatType | IntegerType | ComplexType
-}
-
-func GetDefaultNumber[T Number](value, defaultValue T) T {
-	if value == 0 {
-		return defaultValue
-	}
-	return value
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51877.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51877.go
deleted file mode 100644
index 06f054b..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51877.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type S struct {
-	f1 int
-	f2 bool
-}
-
-var (
-	_ = S{0}                    /* ERROR too few values in S{…} */
-	_ = struct{ f1, f2 int }{0} /* ERROR too few values in struct{f1 int; f2 int}{…} */
-
-	_ = S{0, true, "foo" /* ERROR too many values in S{…} */}
-	_ = struct{ f1, f2 int }{0, 1, 2 /* ERROR too many values in struct{f1 int; f2 int}{…} */}
-)
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue52031.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue52031.go
deleted file mode 100644
index 448a550..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue52031.go
+++ /dev/null
@@ -1,33 +0,0 @@
-// -lang=go1.12
-
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type resultFlags uint
-
-// Example from #52031.
-//
-// The following shifts should not produce errors on Go < 1.13, as their
-// untyped constant operands are representable by type uint.
-const (
-	_ resultFlags = (1 << iota) / 2
-
-	reportEqual
-	reportUnequal
-	reportByIgnore
-	reportByMethod
-	reportByFunc
-	reportByCycle
-)
-
-// Invalid cases.
-var x int = 1
-var _ = (8 << x /* ERROR "signed shift count .* requires go1.13 or later" */)
-
-const _ = (1 << 1.2 /* ERROR "truncated to uint" */)
-
-var y float64
-var _ = (1 << y /* ERROR "must be integer" */)
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue52401.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue52401.go
deleted file mode 100644
index c7efd8c..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue52401.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func _() {
-	const x = 0
-	x /* ERROR cannot assign to x */ += 1
-	x /* ERROR cannot assign to x */ ++
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue52529.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue52529.go
deleted file mode 100644
index de7b296..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue52529.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type Foo[P any] struct {
-	_ *Bar[P]
-}
-
-type Bar[Q any] Foo[Q]
-
-func (v *Bar[R]) M() {
-	_ = (*Foo[R])(v)
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue52698.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue52698.go
deleted file mode 100644
index d1b06a2..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue52698.go
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-// correctness check: ensure that cycles through generic instantiations are detected
-type T[P any] struct {
-	_ P
-}
-
-type S /* ERROR illegal cycle */ struct {
-	_ T[S]
-}
-
-// simplified test 1
-
-var _ A1[A1[string]]
-
-type A1[P any] struct {
-	_ B1[P]
-}
-
-type B1[P any] struct {
-	_ P
-}
-
-// simplified test 2
-var _ B2[A2]
-
-type A2 struct {
-	_ B2[string]
-}
-
-type B2[P any] struct {
-	_ C2[P]
-}
-
-type C2[P any] struct {
-	_ P
-}
-
-// test case from issue
-type T23 interface {
-	~struct {
-		Field0 T13[T15]
-	}
-}
-
-type T1[P1 interface {
-}] struct {
-	Field2 P1
-}
-
-type T13[P2 interface {
-}] struct {
-	Field2 T1[P2]
-}
-
-type T15 struct {
-	Field0 T13[string]
-}
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue52915.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue52915.go
deleted file mode 100644
index 2c38e5b..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue52915.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-import "unsafe"
-
-type T[P any] struct {
-	T /* ERROR illegal cycle */ [P]
-}
-
-func _[P any]() {
-	_ = unsafe.Sizeof(T[int]{})
-	_ = unsafe.Sizeof(struct{ T[int] }{})
-
-	_ = unsafe.Sizeof(T[P]{})
-	_ = unsafe.Sizeof(struct{ T[P] }{})
-}
-
-// TODO(gri) This is a follow-on error due to T[int] being invalid.
-//           We should try to avoid it.
-const _ = unsafe /* ERROR not constant */ .Sizeof(T[int]{})
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue6977.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue6977.go
deleted file mode 100644
index 8f4e9ba..0000000
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue6977.go
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-import "io"
-
-// Alan's initial report.
-
-type I interface { f(); String() string }
-type J interface { g(); String() string }
-
-type IJ1 = interface { I; J }
-type IJ2 = interface { f(); g(); String() string }
-
-var _ = (*IJ1)(nil) == (*IJ2)(nil) // static assert that IJ1 and IJ2 are identical types
-
-// The canonical example.
-
-type ReadWriteCloser interface { io.ReadCloser; io.WriteCloser }
-
-// Some more cases.
-
-type M interface { m() }
-type M32 interface { m() int32 }
-type M64 interface { m() int64 }
-
-type U1 interface { m() }
-type U2 interface { m(); M }
-type U3 interface { M; m() }
-type U4 interface { M; M; M }
-type U5 interface { U1; U2; U3; U4 }
-
-type U6 interface { m(); m /* ERROR duplicate method */ () }
-type U7 interface { M32 /* ERROR duplicate method */ ; m() }
-type U8 interface { m(); M32 /* ERROR duplicate method */ }
-type U9 interface { M32; M64 /* ERROR duplicate method */ }
-
-// Verify that repeated embedding of the same interface(s)
-// eliminates duplicate methods early (rather than at the
-// end) to prevent exponential memory and time use.
-// Without early elimination, computing T29 may take dozens
-// of minutes.
-type (
-        T0 interface { m() }
-        T1 interface { T0; T0 }
-        T2 interface { T1; T1 }
-        T3 interface { T2; T2 }
-        T4 interface { T3; T3 }
-        T5 interface { T4; T4 }
-        T6 interface { T5; T5 }
-        T7 interface { T6; T6 }
-        T8 interface { T7; T7 }
-        T9 interface { T8; T8 }
-
-        T10 interface { T9; T9 }
-        T11 interface { T10; T10 }
-        T12 interface { T11; T11 }
-        T13 interface { T12; T12 }
-        T14 interface { T13; T13 }
-        T15 interface { T14; T14 }
-        T16 interface { T15; T15 }
-        T17 interface { T16; T16 }
-        T18 interface { T17; T17 }
-        T19 interface { T18; T18 }
-
-        T20 interface { T19; T19 }
-        T21 interface { T20; T20 }
-        T22 interface { T21; T21 }
-        T23 interface { T22; T22 }
-        T24 interface { T23; T23 }
-        T25 interface { T24; T24 }
-        T26 interface { T25; T25 }
-        T27 interface { T26; T26 }
-        T28 interface { T27; T27 }
-        T29 interface { T28; T28 }
-)
-
-// Verify that m is present.
-var x T29
-var _ = x.m
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue47996.go b/src/cmd/compile/internal/types2/testdata/local/issue47996.go
similarity index 100%
rename from src/cmd/compile/internal/types2/testdata/fixedbugs/issue47996.go
rename to src/cmd/compile/internal/types2/testdata/local/issue47996.go
diff --git a/src/cmd/compile/internal/types2/testdata/spec/assignability.go b/src/cmd/compile/internal/types2/testdata/spec/assignability.go
deleted file mode 100644
index 507fe6d..0000000
--- a/src/cmd/compile/internal/types2/testdata/spec/assignability.go
+++ /dev/null
@@ -1,264 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package assignability
-
-// See the end of this package for the declarations
-// of the types and variables used in these tests.
-
-// "x's type is identical to T"
-func _[TP any](X TP) {
-	b = b
-	a = a
-	l = l
-	s = s
-	p = p
-	f = f
-	i = i
-	m = m
-	c = c
-	d = d
-
-	B = B
-	A = A
-	L = L
-	S = S
-	P = P
-	F = F
-	I = I
-	M = M
-	C = C
-	D = D
-	X = X
-}
-
-// "x's type V and T have identical underlying types
-// and at least one of V or T is not a named type."
-// (here a named type is a type with a name)
-func _[TP1, TP2 Interface](X1 TP1, X2 TP2) {
-	b = B // ERROR cannot use B .* as int value
-	a = A
-	l = L
-	s = S
-	p = P
-	f = F
-	i = I
-	m = M
-	c = C
-	d = D
-
-	B = b // ERROR cannot use b .* as Basic value
-	A = a
-	L = l
-	S = s
-	P = p
-	F = f
-	I = i
-	M = m
-	C = c
-	D = d
-	X1 = i  // ERROR cannot use i .* as TP1 value
-	X1 = X2 // ERROR cannot use X2 .* as TP1 value
-}
-
-// "T is an interface type and x implements T and T is not a type parameter"
-func _[TP Interface](X TP) {
-	i = d // ERROR missing method m
-	i = D
-	i = X
-	X = i // ERROR cannot use i .* as TP value
-}
-
-// "x is a bidirectional channel value, T is a channel type, x's type V and T have identical element types, and at least one of V or T is not a named type"
-// (here a named type is a type with a name)
-type (
-	_SendChan = chan<- int
-	_RecvChan = <-chan int
-
-	SendChan _SendChan
-	RecvChan _RecvChan
-)
-
-func _[
-	_CC ~_Chan,
-	_SC ~_SendChan,
-	_RC ~_RecvChan,
-
-	CC Chan,
-	SC SendChan,
-	RC RecvChan,
-]() {
-	var (
-		_ _SendChan = c
-		_ _RecvChan = c
-		_ _Chan = c
-
-		_ _SendChan = C
-		_ _RecvChan = C
-		_ _Chan = C
-
-		_ SendChan = c
-		_ RecvChan = c
-		_ Chan = c
-
-		_ SendChan = C // ERROR cannot use C .* as SendChan value
-		_ RecvChan = C // ERROR cannot use C .* as RecvChan value
-		_ Chan = C
-		_ Chan = make /* ERROR cannot use make\(chan Basic\) .* as Chan value */ (chan Basic)
-	)
-
-	var (
-		_ _CC = C // ERROR cannot use C .* as _CC value
-		_ _SC = C // ERROR cannot use C .* as _SC value
-		_ _RC = C // ERROR cannot use C .* as _RC value
-
-		_ CC = _CC /* ERROR cannot use _CC\(nil\) .* as CC value */ (nil)
-		_ SC = _CC /* ERROR cannot use _CC\(nil\) .* as SC value */ (nil)
-		_ RC = _CC /* ERROR cannot use _CC\(nil\) .* as RC value */ (nil)
-
-		_ CC = C // ERROR cannot use C .* as CC value
-		_ SC = C // ERROR cannot use C .* as SC value
-		_ RC = C // ERROR cannot use C .* as RC value
-	)
-}
-
-// "x's type V is not a named type and T is a type parameter, and x is assignable to each specific type in T's type set."
-func _[
-	TP0 any,
-	TP1 ~_Chan,
-	TP2 ~chan int | ~chan byte,
-]() {
-	var (
-		_ TP0 = c // ERROR cannot use c .* as TP0 value
-		_ TP0 = C // ERROR cannot use C .* as TP0 value
-		_ TP1 = c
-		_ TP1 = C // ERROR cannot use C .* as TP1 value
-		_ TP2 = c // ERROR .* cannot assign chan int to chan byte
-	)
-}
-
-// "x's type V is a type parameter and T is not a named type, and values x' of each specific type in V's type set are assignable to T."
-func _[
-	TP0 Interface,
-	TP1 ~_Chan,
-	TP2 ~chan int | ~chan byte,
-](X0 TP0, X1 TP1, X2 TP2) {
-	i = X0
-	I = X0
-	c = X1
-	C = X1 // ERROR cannot use X1 .* as Chan value
-	c = X2 // ERROR .* cannot assign chan byte \(in TP2\) to chan int
-}
-
-// "x is the predeclared identifier nil and T is a pointer, function, slice, map, channel, or interface type"
-func _[TP Interface](X TP) {
-	b = nil // ERROR cannot use nil
-	a = nil // ERROR cannot use nil
-	l = nil
-	s = nil // ERROR cannot use nil
-	p = nil
-	f = nil
-	i = nil
-	m = nil
-	c = nil
-	d = nil // ERROR cannot use nil
-
-	B = nil // ERROR cannot use nil
-	A = nil // ERROR cannot use nil
-	L = nil
-	S = nil // ERROR cannot use nil
-	P = nil
-	F = nil
-	I = nil
-	M = nil
-	C = nil
-	D = nil // ERROR cannot use nil
-	X = nil // ERROR cannot use nil
-}
-
-// "x is an untyped constant representable by a value of type T"
-func _[
-	Int8 ~int8,
-	Int16 ~int16,
-	Int32 ~int32,
-	Int64 ~int64,
-        Int8_16 ~int8 | ~int16,
-](
-	i8 Int8,
-	i16 Int16,
-	i32 Int32,
-	i64 Int64,
-        i8_16 Int8_16,
-) {
-	b = 42
-	b = 42.0
-	// etc.
-
-	i8 = -1 << 7
-	i8 = 1<<7 - 1
-	i16 = -1 << 15
-	i16 = 1<<15 - 1
-	i32 = -1 << 31
-	i32 = 1<<31 - 1
-	i64 = -1 << 63
-	i64 = 1<<63 - 1
-
-	i8_16 = -1 << 7
-	i8_16 = 1<<7 - 1
-	i8_16 = - /* ERROR cannot use .* as Int8_16 */ 1 << 15
-	i8_16 = 1 /* ERROR cannot use .* as Int8_16 */ <<15 - 1
-}
-
-// proto-types for tests
-
-type (
-	_Basic     = int
-	_Array     = [10]int
-	_Slice     = []int
-	_Struct    = struct{ f int }
-	_Pointer   = *int
-	_Func      = func(x int) string
-	_Interface = interface{ m() int }
-	_Map       = map[string]int
-	_Chan      = chan int
-
-	Basic     _Basic
-	Array     _Array
-	Slice     _Slice
-	Struct    _Struct
-	Pointer   _Pointer
-	Func      _Func
-	Interface _Interface
-	Map       _Map
-	Chan      _Chan
-	Defined   _Struct
-)
-
-func (Defined) m() int
-
-// proto-variables for tests
-
-var (
-	b _Basic
-	a _Array
-	l _Slice
-	s _Struct
-	p _Pointer
-	f _Func
-	i _Interface
-	m _Map
-	c _Chan
-	d _Struct
-
-	B Basic
-	A Array
-	L Slice
-	S Struct
-	P Pointer
-	F Func
-	I Interface
-	M Map
-	C Chan
-	D Defined
-)
diff --git a/src/cmd/compile/internal/types2/testdata/spec/comparisons.go b/src/cmd/compile/internal/types2/testdata/spec/comparisons.go
deleted file mode 100644
index 2a7598a..0000000
--- a/src/cmd/compile/internal/types2/testdata/spec/comparisons.go
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package comparisons
-
-type (
-	B int // basic type representative
-	A [10]func()
-	L []byte
-	S struct{ f []byte }
-	P *S
-	F func()
-	I interface{}
-	M map[string]int
-	C chan int
-)
-
-var (
-	b B
-	a A
-	l L
-	s S
-	p P
-	f F
-	i I
-	m M
-	c C
-)
-
-func _() {
-	_ = nil == nil // ERROR operator == not defined on untyped nil
-	_ = b == b
-	_ = a /* ERROR \[10\]func\(\) cannot be compared */ == a
-	_ = l /* ERROR slice can only be compared to nil */ == l
-	_ = s /* ERROR struct containing \[\]byte cannot be compared */ == s
-	_ = p == p
-	_ = f /* ERROR func can only be compared to nil */ == f
-	_ = i == i
-	_ = m /* ERROR map can only be compared to nil */ == m
-	_ = c == c
-
-	_ = b /* ERROR mismatched types */ == nil
-	_ = a /* ERROR mismatched types */ == nil
-	_ = l == nil
-	_ = s /* ERROR mismatched types */ == nil
-	_ = p == nil
-	_ = f == nil
-	_ = i == nil
-	_ = m == nil
-	_ = c == nil
-
-	_ = nil /* ERROR operator < not defined on untyped nil */ < nil
-	_ = b < b
-	_ = a /* ERROR operator < not defined on array */ < a
-	_ = l /* ERROR operator < not defined on slice */ < l
-	_ = s /* ERROR operator < not defined on struct */ < s
-	_ = p /* ERROR operator < not defined on pointer */ < p
-	_ = f /* ERROR operator < not defined on func */ < f
-	_ = i /* ERROR operator < not defined on interface */ < i
-	_ = m /* ERROR operator < not defined on map */ < m
-	_ = c /* ERROR operator < not defined on chan */ < c
-}
-
-func _[
-	B int,
-	A [10]func(),
-	L []byte,
-	S struct{ f []byte },
-	P *S,
-	F func(),
-	I interface{},
-	J comparable,
-	M map[string]int,
-	C chan int,
-](
-	b B,
-	a A,
-	l L,
-	s S,
-	p P,
-	f F,
-	i I,
-	j J,
-	m M,
-	c C,
-) {
-	_ = b == b
-	_ = a /* ERROR incomparable types in type set */ == a
-	_ = l /* ERROR incomparable types in type set */ == l
-	_ = s /* ERROR incomparable types in type set */ == s
-	_ = p == p
-	_ = f /* ERROR incomparable types in type set */ == f
-	_ = i /* ERROR incomparable types in type set */ == i
-	_ = j == j
-	_ = m /* ERROR incomparable types in type set */ == m
-	_ = c == c
-
-	_ = b /* ERROR mismatched types */ == nil
-	_ = a /* ERROR mismatched types */ == nil
-	_ = l == nil
-	_ = s /* ERROR mismatched types */ == nil
-	_ = p == nil
-	_ = f == nil
-	_ = i /* ERROR mismatched types */ == nil
-	_ = j /* ERROR mismatched types */ == nil
-	_ = m == nil
-	_ = c == nil
-
-	_ = b < b
-	_ = a /* ERROR type parameter A is not comparable with < */ < a
-	_ = l /* ERROR type parameter L is not comparable with < */ < l
-	_ = s /* ERROR type parameter S is not comparable with < */ < s
-	_ = p /* ERROR type parameter P is not comparable with < */ < p
-	_ = f /* ERROR type parameter F is not comparable with < */ < f
-	_ = i /* ERROR type parameter I is not comparable with < */ < i
-	_ = j /* ERROR type parameter J is not comparable with < */ < j
-	_ = m /* ERROR type parameter M is not comparable with < */ < m
-	_ = c /* ERROR type parameter C is not comparable with < */ < c
-}
diff --git a/src/cmd/compile/internal/types2/testdata/spec/conversions.go b/src/cmd/compile/internal/types2/testdata/spec/conversions.go
deleted file mode 100644
index fde332f..0000000
--- a/src/cmd/compile/internal/types2/testdata/spec/conversions.go
+++ /dev/null
@@ -1,178 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package conversions
-
-import "unsafe"
-
-// constant conversions
-
-func _[T ~byte]() T { return 255 }
-func _[T ~byte]() T { return 256 /* ERROR cannot use 256 .* as T value */ }
-
-func _[T ~byte]() {
-	const _ = T /* ERROR T\(0\) .* is not constant */ (0)
-	var _ T = 255
-	var _ T = 256 // ERROR cannot use 256 .* as T value
-}
-
-func _[T ~string]() T { return T('a') }
-func _[T ~int | ~string]() T { return T('a') }
-func _[T ~byte | ~int | ~string]() T { return T(256 /* ERROR cannot convert 256 .* to T */ ) }
-
-// implicit conversions never convert to string
-func _[T ~string]() {
-	var _ string = 0 // ERROR cannot use .* as string value
-	var _ T = 0 // ERROR cannot use .* as T value
-}
-
-// failing const conversions of constants to type parameters report a cause
-func _[
-	T1 any,
-	T2 interface{ m() },
-	T3 ~int | ~float64 | ~bool,
-	T4 ~int | ~string,
-]() {
-	_ = T1(0 /* ERROR cannot convert 0 .* to T1\n\tT1 does not contain specific types */ )
-	_ = T2(1 /* ERROR cannot convert 1 .* to T2\n\tT2 does not contain specific types */ )
-	_ = T3(2 /* ERROR cannot convert 2 .* to T3\n\tcannot convert 2 .* to bool \(in T3\) */ )
-	_ = T4(3.14 /* ERROR cannot convert 3.14 .* to T4\n\tcannot convert 3.14 .* to int \(in T4\) */ )
-}
-
-// "x is assignable to T"
-// - tested via assignability tests
-
-// "x's type and T have identical underlying types if tags are ignored"
-
-func _[X ~int, T ~int](x X) T { return T(x) }
-func _[X struct{f int "foo"}, T struct{f int "bar"}](x X) T { return T(x) }
-
-type Foo struct{f int "foo"}
-type Bar struct{f int "bar"}
-type Far struct{f float64 }
-
-func _[X Foo, T Bar](x X) T { return T(x) }
-func _[X Foo|Bar, T Bar](x X) T { return T(x) }
-func _[X Foo, T Foo|Bar](x X) T { return T(x) }
-func _[X Foo, T Far](x X) T { return T(x /* ERROR cannot convert x \(variable of type X constrained by Foo\) to T\n\tcannot convert Foo \(in X\) to Far \(in T\) */ ) }
-
-// "x's type and T are unnamed pointer types and their pointer base types
-// have identical underlying types if tags are ignored"
-
-func _[X ~*Foo, T ~*Bar](x X) T { return T(x) }
-func _[X ~*Foo|~*Bar, T ~*Bar](x X) T { return T(x) }
-func _[X ~*Foo, T ~*Foo|~*Bar](x X) T { return T(x) }
-func _[X ~*Foo, T ~*Far](x X) T { return T(x /* ERROR cannot convert x \(variable of type X constrained by ~\*Foo\) to T\n\tcannot convert \*Foo \(in X\) to \*Far \(in T\) */ ) }
-
-// Verify that the defined types in constraints are considered for the rule above.
-
-type (
-	B int
-	C int
-	X0 *B
-	T0 *C
-)
-
-func _(x X0) T0 { return T0(x /* ERROR cannot convert */ ) } // non-generic reference
-func _[X X0, T T0](x X) T { return T(x /* ERROR cannot convert */ ) }
-func _[T T0](x X0) T { return T(x /* ERROR cannot convert */ ) }
-func _[X X0](x X) T0 { return T0(x /* ERROR cannot convert */ ) }
-
-// "x's type and T are both integer or floating point types"
-
-func _[X Integer, T Integer](x X) T { return T(x) }
-func _[X Unsigned, T Integer](x X) T { return T(x) }
-func _[X Float, T Integer](x X) T { return T(x) }
-
-func _[X Integer, T Unsigned](x X) T { return T(x) }
-func _[X Unsigned, T Unsigned](x X) T { return T(x) }
-func _[X Float, T Unsigned](x X) T { return T(x) }
-
-func _[X Integer, T Float](x X) T { return T(x) }
-func _[X Unsigned, T Float](x X) T { return T(x) }
-func _[X Float, T Float](x X) T { return T(x) }
-
-func _[X, T Integer|Unsigned|Float](x X) T { return T(x) }
-func _[X, T Integer|~string](x X) T { return T(x /* ERROR cannot convert x \(variable of type X constrained by Integer\|~string\) to T\n\tcannot convert string \(in X\) to int \(in T\) */ ) }
-
-// "x's type and T are both complex types"
-
-func _[X, T Complex](x X) T { return T(x) }
-func _[X, T Float|Complex](x X) T { return T(x /* ERROR cannot convert x \(variable of type X constrained by Float\|Complex\) to T\n\tcannot convert float32 \(in X\) to complex64 \(in T\) */ ) }
-
-// "x is an integer or a slice of bytes or runes and T is a string type"
-
-type myInt int
-type myString string
-
-func _[T ~string](x int) T { return T(x) }
-func _[T ~string](x myInt) T { return T(x) }
-func _[X Integer](x X) string { return string(x) }
-func _[X Integer](x X) myString { return myString(x) }
-func _[X Integer](x X) *string { return (*string)(x /* ERROR cannot convert x \(variable of type X constrained by Integer\) to \*string\n\tcannot convert int \(in X\) to \*string */ ) }
-
-func _[T ~string](x []byte) T { return T(x) }
-func _[T ~string](x []rune) T { return T(x) }
-func _[X ~[]byte, T ~string](x X) T { return T(x) }
-func _[X ~[]rune, T ~string](x X) T { return T(x) }
-func _[X Integer|~[]byte|~[]rune, T ~string](x X) T { return T(x) }
-func _[X Integer|~[]byte|~[]rune, T ~*string](x X) T { return T(x /* ERROR cannot convert x \(variable of type X constrained by Integer\|~\[\]byte\|~\[\]rune\) to T\n\tcannot convert int \(in X\) to \*string \(in T\) */ ) }
-
-// "x is a string and T is a slice of bytes or runes"
-
-func _[T ~[]byte](x string) T { return T(x) }
-func _[T ~[]rune](x string) T { return T(x) }
-func _[T ~[]rune](x *string) T { return T(x /* ERROR cannot convert x \(variable of type \*string\) to T\n\tcannot convert \*string to \[\]rune \(in T\) */ ) }
-
-func _[X ~string, T ~[]byte](x X) T { return T(x) }
-func _[X ~string, T ~[]rune](x X) T { return T(x) }
-func _[X ~string, T ~[]byte|~[]rune](x X) T { return T(x) }
-func _[X ~*string, T ~[]byte|~[]rune](x X) T { return T(x /* ERROR cannot convert x \(variable of type X constrained by ~\*string\) to T\n\tcannot convert \*string \(in X\) to \[\]byte \(in T\) */ ) }
-
-// package unsafe:
-// "any pointer or value of underlying type uintptr can be converted into a unsafe.Pointer"
-
-type myUintptr uintptr
-
-func _[X ~uintptr](x X) unsafe.Pointer { return unsafe.Pointer(x) }
-func _[T unsafe.Pointer](x myUintptr) T { return T(x) }
-func _[T unsafe.Pointer](x int64) T { return T(x /* ERROR cannot convert x \(variable of type int64\) to T\n\tcannot convert int64 to unsafe\.Pointer \(in T\) */ ) }
-
-// "and vice versa"
-
-func _[T ~uintptr](x unsafe.Pointer) T { return T(x) }
-func _[X unsafe.Pointer](x X) uintptr { return uintptr(x) }
-func _[X unsafe.Pointer](x X) myUintptr { return myUintptr(x) }
-func _[X unsafe.Pointer](x X) int64 { return int64(x /* ERROR cannot convert x \(variable of type X constrained by unsafe\.Pointer\) to int64\n\tcannot convert unsafe\.Pointer \(in X\) to int64 */ ) }
-
-// "x is a slice, T is a pointer-to-array type,
-// and the slice and array types have identical element types."
-
-func _[X ~[]E, T ~*[10]E, E any](x X) T { return T(x) }
-func _[X ~[]E, T ~[10]E, E any](x X) T { return T(x /* ERROR cannot convert x \(variable of type X constrained by ~\[\]E\) to T\n\tcannot convert \[\]E \(in X\) to \[10\]E \(in T\) */ ) }
-
-// ----------------------------------------------------------------------------
-// The following declarations can be replaced by the exported types of the
-// constraints package once all builders support importing interfaces with
-// type constraints.
-
-type Signed interface {
-	~int | ~int8 | ~int16 | ~int32 | ~int64
-}
-
-type Unsigned interface {
-	~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
-}
-
-type Integer interface {
-	Signed | Unsigned
-}
-
-type Float interface {
-	~float32 | ~float64
-}
-
-type Complex interface {
-	~complex64 | ~complex128
-}
diff --git a/src/cmd/compile/internal/types2/type.go b/src/cmd/compile/internal/types2/type.go
index 0fe39db..92ecf11 100644
--- a/src/cmd/compile/internal/types2/type.go
+++ b/src/cmd/compile/internal/types2/type.go
@@ -4,15 +4,11 @@
 
 package types2
 
+import "cmd/compile/internal/syntax"
+
 // A Type represents a type of Go.
 // All types implement the Type interface.
-type Type interface {
-	// Underlying returns the underlying type of a type.
-	Underlying() Type
-
-	// String returns a string representation of a type.
-	String() string
-}
+type Type = syntax.Type
 
 // under returns the true expanded underlying type.
 // If it doesn't exist, the result is Typ[Invalid].
diff --git a/src/cmd/compile/internal/types2/typeset.go b/src/cmd/compile/internal/types2/typeset.go
index 328c502..673cadc 100644
--- a/src/cmd/compile/internal/types2/typeset.go
+++ b/src/cmd/compile/internal/types2/typeset.go
@@ -5,10 +5,11 @@
 package types2
 
 import (
-	"bytes"
 	"cmd/compile/internal/syntax"
 	"fmt"
+	. "internal/types/errors"
 	"sort"
+	"strings"
 )
 
 // ----------------------------------------------------------------------------
@@ -71,7 +72,7 @@
 	hasMethods := len(s.methods) > 0
 	hasTerms := s.hasTerms()
 
-	var buf bytes.Buffer
+	var buf strings.Builder
 	buf.WriteByte('{')
 	if s.comparable {
 		buf.WriteString("comparable")
@@ -226,6 +227,7 @@
 			}
 			// check != nil
 			var err error_
+			err.code = DuplicateDecl
 			err.errorf(pos, "duplicate method %s", m.name)
 			err.errorf(mpos[other.(*Func)], "other declaration of %s", m.name)
 			check.report(&err)
@@ -244,6 +246,7 @@
 			check.later(func() {
 				if !check.allowVersion(m.pkg, 1, 14) || !Identical(m.typ, other.Type()) {
 					var err error_
+					err.code = DuplicateDecl
 					err.errorf(pos, "duplicate method %s", m.name)
 					err.errorf(mpos[other.(*Func)], "other declaration of %s", m.name)
 					check.report(&err)
@@ -349,7 +352,7 @@
 		i := 0
 		for _, t := range terms {
 			assert(t.typ != nil)
-			if Comparable(t.typ) {
+			if comparable(t.typ, false /* strictly comparable */, nil, nil) {
 				terms[i] = t
 				i++
 			}
@@ -421,7 +424,7 @@
 		allTerms = allTerms.union(terms)
 		if len(allTerms) > maxTermCount {
 			if check != nil {
-				check.errorf(pos, "cannot handle more than %d union terms (implementation limitation)", maxTermCount)
+				check.errorf(pos, InvalidUnion, "cannot handle more than %d union terms (implementation limitation)", maxTermCount)
 			}
 			unionSets[utyp] = &invalidTypeSet
 			return unionSets[utyp]
diff --git a/src/cmd/compile/internal/types2/typestring.go b/src/cmd/compile/internal/types2/typestring.go
index c10c2d8..2307b61 100644
--- a/src/cmd/compile/internal/types2/typestring.go
+++ b/src/cmd/compile/internal/types2/typestring.go
@@ -45,14 +45,8 @@
 // The Qualifier controls the printing of
 // package-level objects, and may be nil.
 func TypeString(typ Type, qf Qualifier) string {
-	return typeString(typ, qf, false)
-}
-
-func typeString(typ Type, qf Qualifier, debug bool) string {
 	var buf bytes.Buffer
-	w := newTypeWriter(&buf, qf)
-	w.debug = debug
-	w.typ(typ)
+	WriteType(&buf, typ, qf)
 	return buf.String()
 }
 
@@ -64,29 +58,30 @@
 }
 
 // WriteSignature writes the representation of the signature sig to buf,
-// without a leading "func" keyword.
-// The Qualifier controls the printing of
-// package-level objects, and may be nil.
+// without a leading "func" keyword. The Qualifier controls the printing
+// of package-level objects, and may be nil.
 func WriteSignature(buf *bytes.Buffer, sig *Signature, qf Qualifier) {
 	newTypeWriter(buf, qf).signature(sig)
 }
 
 type typeWriter struct {
-	buf     *bytes.Buffer
-	seen    map[Type]bool
-	qf      Qualifier
-	ctxt    *Context       // if non-nil, we are type hashing
-	tparams *TypeParamList // local type parameters
-	debug   bool           // if true, write debug annotations
+	buf          *bytes.Buffer
+	seen         map[Type]bool
+	qf           Qualifier
+	ctxt         *Context       // if non-nil, we are type hashing
+	tparams      *TypeParamList // local type parameters
+	paramNames   bool           // if set, write function parameter names, otherwise, write types only
+	tpSubscripts bool           // if set, write type parameter indices as subscripts
+	pkgInfo      bool           // package-annotate first unexported-type field to avoid confusing type description
 }
 
 func newTypeWriter(buf *bytes.Buffer, qf Qualifier) *typeWriter {
-	return &typeWriter{buf, make(map[Type]bool), qf, nil, nil, false}
+	return &typeWriter{buf, make(map[Type]bool), qf, nil, nil, true, false, false}
 }
 
 func newTypeHasher(buf *bytes.Buffer, ctxt *Context) *typeWriter {
 	assert(ctxt != nil)
-	return &typeWriter{buf, make(map[Type]bool), nil, ctxt, nil, false}
+	return &typeWriter{buf, make(map[Type]bool), nil, ctxt, nil, false, false, false}
 }
 
 func (w *typeWriter) byte(b byte) {
@@ -153,6 +148,16 @@
 			if i > 0 {
 				w.byte(';')
 			}
+
+			// If disambiguating one struct for another, look for the first unexported field.
+			// Do this first in case of nested structs; tag the first-outermost field.
+			pkgAnnotate := false
+			if w.qf == nil && w.pkgInfo && !isExported(f.name) {
+				// note for embedded types, type name is field name, and "string" etc are lower case hence unexported.
+				pkgAnnotate = true
+				w.pkgInfo = false // only tag once
+			}
+
 			// This doesn't do the right thing for embedded type
 			// aliases where we should print the alias name, not
 			// the aliased type (see issue #44410).
@@ -161,6 +166,11 @@
 				w.byte(' ')
 			}
 			w.typ(f.typ)
+			if pkgAnnotate {
+				w.string(" /* package ")
+				w.string(f.pkg.Path())
+				w.string(" */ ")
+			}
 			if tag := t.Tag(i); tag != "" {
 				w.byte(' ')
 				// TODO(gri) If tag contains blanks, replacing them with '#'
@@ -191,7 +201,7 @@
 		}
 		for i, t := range t.terms {
 			if i > 0 {
-				w.byte('|')
+				w.string(termSep)
 			}
 			if t.tilde {
 				w.byte('~')
@@ -304,7 +314,7 @@
 			w.string(fmt.Sprintf("$%d", i))
 		} else {
 			w.string(t.obj.name)
-			if w.debug || w.ctxt != nil {
+			if w.tpSubscripts || w.ctxt != nil {
 				w.string(subscript(t.id))
 			}
 		}
@@ -393,9 +403,7 @@
 }
 
 func (w *typeWriter) typeName(obj *TypeName) {
-	if obj.pkg != nil {
-		writePackage(w.buf, obj.pkg, w.qf)
-	}
+	w.string(packagePrefix(obj.pkg, w.qf))
 	w.string(obj.name)
 }
 
@@ -407,7 +415,7 @@
 				w.byte(',')
 			}
 			// parameter names are ignored for type identity and thus type hashes
-			if w.ctxt == nil && v.name != "" {
+			if w.ctxt == nil && v.name != "" && w.paramNames {
 				w.string(v.name)
 				w.byte(' ')
 			}
diff --git a/src/cmd/compile/internal/types2/typestring_test.go b/src/cmd/compile/internal/types2/typestring_test.go
index c0689e8..7dd9b35 100644
--- a/src/cmd/compile/internal/types2/typestring_test.go
+++ b/src/cmd/compile/internal/types2/typestring_test.go
@@ -8,22 +8,11 @@
 	"internal/testenv"
 	"testing"
 
-	"cmd/compile/internal/syntax"
 	. "cmd/compile/internal/types2"
 )
 
 const filename = "<src>"
 
-func makePkg(src string) (*Package, error) {
-	file, err := parseSrc(filename, src)
-	if err != nil {
-		return nil, err
-	}
-	// use the package name as package path
-	conf := Config{Importer: defaultImporter()}
-	return conf.Check(file.PkgName.Value, []*syntax.File{file}, nil)
-}
-
 type testEntry struct {
 	src, str string
 }
@@ -91,8 +80,8 @@
 	dup("interface{}"),
 	dup("interface{m()}"),
 	dup(`interface{String() string; m(int) float32}`),
-	dup("interface{int|float32|complex128}"),
-	dup("interface{int|~float32|~complex128}"),
+	dup("interface{int | float32 | complex128}"),
+	dup("interface{int | ~float32 | ~complex128}"),
 	dup("any"),
 	dup("interface{comparable}"),
 	{"comparable", "interface{comparable}"},
@@ -120,6 +109,7 @@
 }
 
 func TestTypeString(t *testing.T) {
+	// The Go command is needed for the importer to determine the locations of stdlib .a files.
 	testenv.MustHaveGoBuild(t)
 
 	var tests []testEntry
@@ -128,7 +118,7 @@
 
 	for _, test := range tests {
 		src := `package generic_p; import "io"; type _ io.Writer; type T ` + test.src
-		pkg, err := makePkg(src)
+		pkg, err := typecheck(filename, src, nil)
 		if err != nil {
 			t.Errorf("%s: %s", src, err)
 			continue
@@ -146,8 +136,8 @@
 }
 
 func TestQualifiedTypeString(t *testing.T) {
-	p, _ := pkgFor("p.go", "package p; type T int", nil)
-	q, _ := pkgFor("q.go", "package q", nil)
+	p := mustTypecheck("p.go", "package p; type T int", nil)
+	q := mustTypecheck("q.go", "package q", nil)
 
 	pT := p.Scope().Lookup("T").Type()
 	for _, test := range []struct {
diff --git a/src/cmd/compile/internal/types2/typexpr.go b/src/cmd/compile/internal/types2/typexpr.go
index 692feb9..0f3106d 100644
--- a/src/cmd/compile/internal/types2/typexpr.go
+++ b/src/cmd/compile/internal/types2/typexpr.go
@@ -10,6 +10,7 @@
 	"cmd/compile/internal/syntax"
 	"fmt"
 	"go/constant"
+	. "internal/types/errors"
 	"strings"
 )
 
@@ -34,14 +35,10 @@
 				x.mode = typexpr
 				x.typ = tpar
 			} else {
-				check.error(e, "cannot use _ as value or type")
+				check.error(e, InvalidBlank, "cannot use _ as value or type")
 			}
 		} else {
-			if check.conf.CompilerErrorMessages {
-				check.errorf(e, "undefined: %s", e.Value)
-			} else {
-				check.errorf(e, "undeclared name: %s", e.Value)
-			}
+			check.errorf(e, UndeclaredName, "undefined: %s", e.Value)
 		}
 		return
 	case universeAny, universeComparable:
@@ -77,7 +74,7 @@
 
 	switch obj := obj.(type) {
 	case *PkgName:
-		check.errorf(e, "use of package %s not in selector", obj.name)
+		check.errorf(e, InvalidPkgUse, "use of package %s not in selector", obj.name)
 		return
 
 	case *Const:
@@ -87,7 +84,7 @@
 		}
 		if obj == universeIota {
 			if check.iota == nil {
-				check.error(e, "cannot use iota outside constant declaration")
+				check.error(e, InvalidIota, "cannot use iota outside constant declaration")
 				return
 			}
 			x.val = check.iota
@@ -99,7 +96,7 @@
 
 	case *TypeName:
 		if check.isBrokenAlias(obj) {
-			check.errorf(e, "invalid use of type alias %s in recursive type (see issue #50729)", obj.name)
+			check.errorf(e, InvalidDeclCycle, "invalid use of type alias %s in recursive type (see issue #50729)", obj.name)
 			return
 		}
 		x.mode = typexpr
@@ -167,9 +164,9 @@
 			tset := computeInterfaceTypeSet(check, pos, t) // TODO(gri) is this the correct position?
 			if !tset.IsMethodSet() {
 				if tset.comparable {
-					check.softErrorf(pos, "cannot use type %s outside a type constraint: interface is (or embeds) comparable", typ)
+					check.softErrorf(pos, MisplacedConstraintIface, "cannot use type %s outside a type constraint: interface is (or embeds) comparable", typ)
 				} else {
-					check.softErrorf(pos, "cannot use type %s outside a type constraint: interface contains type constraints", typ)
+					check.softErrorf(pos, MisplacedConstraintIface, "cannot use type %s outside a type constraint: interface contains type constraints", typ)
 				}
 			}
 		}
@@ -184,20 +181,22 @@
 	typ := check.typInternal(e, def)
 	assert(isTyped(typ))
 	if isGeneric(typ) {
-		check.errorf(e, "cannot use generic type %s without instantiation", typ)
+		check.errorf(e, WrongTypeArgCount, "cannot use generic type %s without instantiation", typ)
 		typ = Typ[Invalid]
 	}
 	check.recordTypeAndValue(e, typexpr, typ, nil)
 	return typ
 }
 
-// genericType is like typ but the type must be an (uninstantiated) generic type.
-func (check *Checker) genericType(e syntax.Expr, reportErr bool) Type {
+// genericType is like typ but the type must be an (uninstantiated) generic
+// type. If cause is non-nil and the type expression was a valid type but not
+// generic, cause will be populated with a message describing the error.
+func (check *Checker) genericType(e syntax.Expr, cause *string) Type {
 	typ := check.typInternal(e, nil)
 	assert(isTyped(typ))
 	if typ != Typ[Invalid] && !isGeneric(typ) {
-		if reportErr {
-			check.errorf(e, "%s is not a generic type", typ)
+		if cause != nil {
+			*cause = check.sprintf("%s is not a generic type", typ)
 		}
 		typ = Typ[Invalid]
 	}
@@ -250,14 +249,14 @@
 		case invalid:
 			// ignore - error reported before
 		case novalue:
-			check.errorf(&x, "%s used as type", &x)
+			check.errorf(&x, NotAType, "%s used as type", &x)
 		default:
-			check.errorf(&x, "%s is not a type", &x)
+			check.errorf(&x, NotAType, "%s is not a type", &x)
 		}
 
 	case *syntax.SelectorExpr:
 		var x operand
-		check.selector(&x, e, def)
+		check.selector(&x, e, def, true)
 
 		switch x.mode {
 		case typexpr:
@@ -267,9 +266,9 @@
 		case invalid:
 			// ignore - error reported before
 		case novalue:
-			check.errorf(&x, "%s used as type", &x)
+			check.errorf(&x, NotAType, "%s used as type", &x)
 		default:
-			check.errorf(&x, "%s is not a type", &x)
+			check.errorf(&x, NotAType, "%s is not a type", &x)
 		}
 
 	case *syntax.IndexExpr:
@@ -290,7 +289,7 @@
 			typ.len = check.arrayLength(e.Len)
 		} else {
 			// [...]array
-			check.error(e, "invalid use of [...] array (outside a composite literal)")
+			check.error(e, BadDotDotDotSyntax, "invalid use of [...] array (outside a composite literal)")
 			typ.len = -1
 		}
 		typ.elem = check.varType(e.Elem)
@@ -308,7 +307,7 @@
 	case *syntax.DotsType:
 		// dots are handled explicitly where they are legal
 		// (array composite literals and parameter lists)
-		check.error(e, "invalid use of '...'")
+		check.error(e, InvalidDotDotDot, "invalid use of '...'")
 		check.use(e.Elem)
 
 	case *syntax.StructType:
@@ -333,7 +332,7 @@
 			return typ
 		}
 
-		check.errorf(e0, "%s is not a type", e0)
+		check.errorf(e0, NotAType, "%s is not a type", e0)
 		check.use(e0)
 
 	case *syntax.FuncType:
@@ -367,7 +366,7 @@
 				if isTypeParam(typ.key) {
 					why = " (missing comparable constraint)"
 				}
-				check.errorf(e.Key, "invalid map key type %s%s", typ.key, why)
+				check.errorf(e.Key, IncomparableMapKey, "invalid map key type %s%s", typ.key, why)
 			}
 		}).describef(e.Key, "check map key %s", typ.key)
 
@@ -386,7 +385,7 @@
 		case syntax.RecvOnly:
 			dir = RecvOnly
 		default:
-			check.errorf(e, invalidAST+"unknown channel direction %d", e.Dir)
+			check.errorf(e, InvalidSyntaxTree, "unknown channel direction %d", e.Dir)
 			// ok to continue
 		}
 
@@ -395,7 +394,7 @@
 		return typ
 
 	default:
-		check.errorf(e0, "%s is not a type", e0)
+		check.errorf(e0, NotAType, "%s is not a type", e0)
 		check.use(e0)
 	}
 
@@ -415,7 +414,11 @@
 		}()
 	}
 
-	gtyp := check.genericType(x, true)
+	var cause string
+	gtyp := check.genericType(x, &cause)
+	if cause != "" {
+		check.errorf(x, NotAGenericType, invalidOp+"%s%s (%s)", x, xlist, cause)
+	}
 	if gtyp == Typ[Invalid] {
 		return gtyp // error already reported
 	}
@@ -450,7 +453,7 @@
 				if i < len(xlist) {
 					pos = syntax.StartPos(xlist[i])
 				}
-				check.softErrorf(pos, "%s", err)
+				check.softErrorf(pos, InvalidTypeArg, "%s", err)
 			} else {
 				check.mono.recordInstance(check.pkg, x.Pos(), inst.TypeParams().list(), inst.TypeArgs().list(), xlist)
 			}
@@ -476,11 +479,11 @@
 	if name, _ := e.(*syntax.Name); name != nil {
 		obj := check.lookup(name.Value)
 		if obj == nil {
-			check.errorf(name, "undeclared name %s for array length", name.Value)
+			check.errorf(name, InvalidArrayLen, "undefined array length %s or missing type constraint", name.Value)
 			return -1
 		}
 		if _, ok := obj.(*Const); !ok {
-			check.errorf(name, "invalid array length %s", name.Value)
+			check.errorf(name, InvalidArrayLen, "invalid array length %s", name.Value)
 			return -1
 		}
 	}
@@ -489,7 +492,7 @@
 	check.expr(&x, e)
 	if x.mode != constant_ {
 		if x.mode != invalid {
-			check.errorf(&x, "array length %s must be constant", &x)
+			check.errorf(&x, InvalidArrayLen, "array length %s must be constant", &x)
 		}
 		return -1
 	}
@@ -500,13 +503,13 @@
 				if n, ok := constant.Int64Val(val); ok && n >= 0 {
 					return n
 				}
-				check.errorf(&x, "invalid array length %s", &x)
+				check.errorf(&x, InvalidArrayLen, "invalid array length %s", &x)
 				return -1
 			}
 		}
 	}
 
-	check.errorf(&x, "array length %s must be integer", &x)
+	check.errorf(&x, InvalidArrayLen, "array length %s must be integer", &x)
 	return -1
 }
 
diff --git a/src/cmd/compile/internal/types2/union.go b/src/cmd/compile/internal/types2/union.go
index 0ed125f..1fafb05 100644
--- a/src/cmd/compile/internal/types2/union.go
+++ b/src/cmd/compile/internal/types2/union.go
@@ -4,7 +4,10 @@
 
 package types2
 
-import "cmd/compile/internal/syntax"
+import (
+	"cmd/compile/internal/syntax"
+	. "internal/types/errors"
+)
 
 // ----------------------------------------------------------------------------
 // API
@@ -64,7 +67,7 @@
 		}
 		if len(terms) >= maxTermCount {
 			if u != Typ[Invalid] {
-				check.errorf(x, "cannot handle more than %d union terms (implementation limitation)", maxTermCount)
+				check.errorf(x, InvalidUnion, "cannot handle more than %d union terms (implementation limitation)", maxTermCount)
 				u = Typ[Invalid]
 			}
 		} else {
@@ -94,12 +97,12 @@
 			f, _ := u.(*Interface)
 			if t.tilde {
 				if f != nil {
-					check.errorf(tlist[i], "invalid use of ~ (%s is an interface)", t.typ)
+					check.errorf(tlist[i], InvalidUnion, "invalid use of ~ (%s is an interface)", t.typ)
 					continue // don't report another error for t
 				}
 
 				if !Identical(u, t.typ) {
-					check.errorf(tlist[i], "invalid use of ~ (underlying type of %s is %s)", t.typ, u)
+					check.errorf(tlist[i], InvalidUnion, "invalid use of ~ (underlying type of %s is %s)", t.typ, u)
 					continue
 				}
 			}
@@ -112,11 +115,11 @@
 				tset := f.typeSet()
 				switch {
 				case tset.NumMethods() != 0:
-					check.errorf(tlist[i], "cannot use %s in union (%s contains methods)", t, t)
+					check.errorf(tlist[i], InvalidUnion, "cannot use %s in union (%s contains methods)", t, t)
 				case t.typ == universeComparable.Type():
-					check.error(tlist[i], "cannot use comparable in union")
+					check.error(tlist[i], InvalidUnion, "cannot use comparable in union")
 				case tset.comparable:
-					check.errorf(tlist[i], "cannot use %s in union (%s embeds comparable)", t, t)
+					check.errorf(tlist[i], InvalidUnion, "cannot use %s in union (%s embeds comparable)", t, t)
 				}
 				continue // terms with interface types are not subject to the no-overlap rule
 			}
@@ -124,7 +127,7 @@
 			// Report overlapping (non-disjoint) terms such as
 			// a|a, a|~a, ~a|~a, and ~a|A (where under(A) == a).
 			if j := overlappingTerm(terms[:i], t); j >= 0 {
-				check.softErrorf(tlist[i], "overlapping terms %s and %s", t, terms[j])
+				check.softErrorf(tlist[i], InvalidUnion, "overlapping terms %s and %s", t, terms[j])
 			}
 		}
 	}).describef(uexpr, "check term validity %s", uexpr)
@@ -147,9 +150,9 @@
 	// and since the underlying type is an interface the embedding is well defined.
 	if isTypeParam(typ) {
 		if tilde {
-			check.errorf(x, "type in term %s cannot be a type parameter", tx)
+			check.errorf(x, MisplacedTypeParam, "type in term %s cannot be a type parameter", tx)
 		} else {
-			check.error(x, "term cannot be a type parameter")
+			check.error(x, MisplacedTypeParam, "term cannot be a type parameter")
 		}
 		typ = Typ[Invalid]
 	}
diff --git a/src/cmd/compile/internal/types2/universe.go b/src/cmd/compile/internal/types2/universe.go
index 9292924..3fe849e 100644
--- a/src/cmd/compile/internal/types2/universe.go
+++ b/src/cmd/compile/internal/types2/universe.go
@@ -145,6 +145,7 @@
 	// universe scope
 	_Append builtinId = iota
 	_Cap
+	_Clear
 	_Close
 	_Complex
 	_Copy
@@ -165,6 +166,9 @@
 	_Offsetof
 	_Sizeof
 	_Slice
+	_SliceData
+	_String
+	_StringData
 
 	// testing support
 	_Assert
@@ -179,6 +183,7 @@
 }{
 	_Append:  {"append", 1, true, expression},
 	_Cap:     {"cap", 1, false, expression},
+	_Clear:   {"clear", 1, false, statement},
 	_Close:   {"close", 1, false, statement},
 	_Complex: {"complex", 2, false, expression},
 	_Copy:    {"copy", 2, false, statement},
@@ -193,11 +198,14 @@
 	_Real:    {"real", 1, false, expression},
 	_Recover: {"recover", 0, false, statement},
 
-	_Add:      {"Add", 2, false, expression},
-	_Alignof:  {"Alignof", 1, false, expression},
-	_Offsetof: {"Offsetof", 1, false, expression},
-	_Sizeof:   {"Sizeof", 1, false, expression},
-	_Slice:    {"Slice", 2, false, expression},
+	_Add:        {"Add", 2, false, expression},
+	_Alignof:    {"Alignof", 1, false, expression},
+	_Offsetof:   {"Offsetof", 1, false, expression},
+	_Sizeof:     {"Sizeof", 1, false, expression},
+	_Slice:      {"Slice", 2, false, expression},
+	_SliceData:  {"SliceData", 1, false, expression},
+	_String:     {"String", 2, false, expression},
+	_StringData: {"StringData", 1, false, expression},
 
 	_Assert: {"assert", 1, false, statement},
 	_Trace:  {"trace", 0, true, statement},
diff --git a/src/cmd/compile/internal/types2/validtype.go b/src/cmd/compile/internal/types2/validtype.go
index 99fdebc9..b0ebc02 100644
--- a/src/cmd/compile/internal/types2/validtype.go
+++ b/src/cmd/compile/internal/types2/validtype.go
@@ -76,11 +76,32 @@
 		// embedded in itself, indicating an invalid recursive type.
 		for _, e := range nest {
 			if Identical(e, t) {
-				// t cannot be in an imported package otherwise that package
-				// would have reported a type cycle and couldn't have been
-				// imported in the first place.
+				// We have a cycle. If t != t.Origin() then t is an instance of
+				// the generic type t.Origin(). Because t is in the nest, t must
+				// occur within the definition (RHS) of the generic type t.Origin(),
+				// directly or indirectly, after expansion of the RHS.
+				// Therefore t.Origin() must be invalid, no matter how it is
+				// instantiated since the instantiation t of t.Origin() happens
+				// inside t.Origin()'s RHS and thus is always the same and always
+				// present.
+				// Therefore we can mark the underlying of both t and t.Origin()
+				// as invalid. If t is not an instance of a generic type, t and
+				// t.Origin() are the same.
+				// Furthermore, because we check all types in a package for validity
+				// before type checking is complete, any exported type that is invalid
+				// will have an invalid underlying type and we can't reach here with
+				// such a type (invalid types are excluded above).
+				// Thus, if we reach here with a type t, both t and t.Origin() (if
+				// different in the first place) must be from the current package;
+				// they cannot have been imported.
+				// Therefore it is safe to change their underlying types; there is
+				// no chance for a race condition (the types of the current package
+				// are not yet available to other goroutines).
 				assert(t.obj.pkg == check.pkg)
-				t.underlying = Typ[Invalid] // t is in the current package (no race possibility)
+				assert(t.Origin().obj.pkg == check.pkg)
+				t.underlying = Typ[Invalid]
+				t.Origin().underlying = Typ[Invalid]
+
 				// Find the starting point of the cycle and report it.
 				// Because each type in nest must also appear in path (see invariant below),
 				// type t must be in path since it was found in nest. But not every type in path
diff --git a/src/cmd/compile/internal/walk/assign.go b/src/cmd/compile/internal/walk/assign.go
index c44d934..1450ec6 100644
--- a/src/cmd/compile/internal/walk/assign.go
+++ b/src/cmd/compile/internal/walk/assign.go
@@ -99,10 +99,11 @@
 		}
 		as.Y = r
 		if r.Op() == ir.OAPPEND {
+			r := r.(*ir.CallExpr)
 			// Left in place for back end.
 			// Do not add a new write barrier.
 			// Set up address of type for back end.
-			r.(*ir.CallExpr).X = reflectdata.TypePtr(r.Type().Elem())
+			r.X = reflectdata.AppendElemRType(base.Pos, r)
 			return as
 		}
 		// Otherwise, lowered for race detector.
@@ -169,11 +170,11 @@
 	var call *ir.CallExpr
 	if w := t.Elem().Size(); w <= zeroValSize {
 		fn := mapfn(mapaccess2[fast], t, false)
-		call = mkcall1(fn, fn.Type().Results(), init, reflectdata.TypePtr(t), r.X, key)
+		call = mkcall1(fn, fn.Type().Results(), init, reflectdata.IndexMapRType(base.Pos, r), r.X, key)
 	} else {
 		fn := mapfn("mapaccess2_fat", t, true)
 		z := reflectdata.ZeroAddr(w)
-		call = mkcall1(fn, fn.Type().Results(), init, reflectdata.TypePtr(t), r.X, key, z)
+		call = mkcall1(fn, fn.Type().Results(), init, reflectdata.IndexMapRType(base.Pos, r), r.X, key, z)
 	}
 
 	// mapaccess2* returns a typed bool, but due to spec changes,
@@ -460,13 +461,14 @@
 //
 //	init {
 //	  s := l1
-//	  n := len(s) + len(l2)
+//	  newLen := s.len + l2.len
 //	  // Compare as uint so growslice can panic on overflow.
-//	  if uint(n) > uint(cap(s)) {
-//	    s = growslice(s, n)
+//	  if uint(newLen) <= uint(s.cap) {
+//	    s = s[:newLen]
+//	  } else {
+//	    s = growslice(s.ptr, s.len, s.cap, l2.len, T)
 //	  }
-//	  s = s[:n]
-//	  memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T))
+//	  memmove(&s[s.len-l2.len], &l2[0], l2.len*sizeof(T))
 //	}
 //	s
 //
@@ -487,34 +489,54 @@
 
 	elemtype := s.Type().Elem()
 
-	// n := len(s) + len(l2)
-	nn := typecheck.Temp(types.Types[types.TINT])
-	nodes.Append(ir.NewAssignStmt(base.Pos, nn, ir.NewBinaryExpr(base.Pos, ir.OADD, ir.NewUnaryExpr(base.Pos, ir.OLEN, s), ir.NewUnaryExpr(base.Pos, ir.OLEN, l2))))
+	// Decompose slice.
+	oldPtr := ir.NewUnaryExpr(base.Pos, ir.OSPTR, s)
+	oldLen := ir.NewUnaryExpr(base.Pos, ir.OLEN, s)
+	oldCap := ir.NewUnaryExpr(base.Pos, ir.OCAP, s)
 
-	// if uint(n) > uint(cap(s))
+	// Number of elements we are adding
+	num := ir.NewUnaryExpr(base.Pos, ir.OLEN, l2)
+
+	// newLen := oldLen + num
+	newLen := typecheck.Temp(types.Types[types.TINT])
+	nodes.Append(ir.NewAssignStmt(base.Pos, newLen, ir.NewBinaryExpr(base.Pos, ir.OADD, oldLen, num)))
+
+	// if uint(newLen) <= uint(oldCap)
 	nif := ir.NewIfStmt(base.Pos, nil, nil, nil)
-	nuint := typecheck.Conv(nn, types.Types[types.TUINT])
-	scapuint := typecheck.Conv(ir.NewUnaryExpr(base.Pos, ir.OCAP, s), types.Types[types.TUINT])
-	nif.Cond = ir.NewBinaryExpr(base.Pos, ir.OGT, nuint, scapuint)
+	nuint := typecheck.Conv(newLen, types.Types[types.TUINT])
+	scapuint := typecheck.Conv(oldCap, types.Types[types.TUINT])
+	nif.Cond = ir.NewBinaryExpr(base.Pos, ir.OLE, nuint, scapuint)
+	nif.Likely = true
 
-	// instantiate growslice(typ *type, []any, int) []any
+	// then { s = s[:newLen] }
+	slice := ir.NewSliceExpr(base.Pos, ir.OSLICE, s, nil, newLen, nil)
+	slice.SetBounded(true)
+	nif.Body = []ir.Node{ir.NewAssignStmt(base.Pos, s, slice)}
+
+	// func growslice(oldPtr unsafe.Pointer, newLen, oldCap, num int, et *_type) []T
 	fn := typecheck.LookupRuntime("growslice")
 	fn = typecheck.SubstArgTypes(fn, elemtype, elemtype)
 
-	// s = growslice(T, s, n)
-	nif.Body = []ir.Node{ir.NewAssignStmt(base.Pos, s, mkcall1(fn, s.Type(), nif.PtrInit(), reflectdata.TypePtr(elemtype), s, nn))}
+	// else { s = growslice(oldPtr, newLen, oldCap, num, T) }
+	call := mkcall1(fn, s.Type(), nif.PtrInit(), oldPtr, newLen, oldCap, num, reflectdata.TypePtr(elemtype))
+	nif.Else = []ir.Node{ir.NewAssignStmt(base.Pos, s, call)}
+
 	nodes.Append(nif)
 
-	// s = s[:n]
-	nt := ir.NewSliceExpr(base.Pos, ir.OSLICE, s, nil, nn, nil)
-	nt.SetBounded(true)
-	nodes.Append(ir.NewAssignStmt(base.Pos, s, nt))
+	// Index to start copying into s.
+	//   idx = newLen - len(l2)
+	// We use this expression instead of oldLen because it avoids
+	// a spill/restore of oldLen.
+	// Note: this doesn't work optimally currently because
+	// the compiler optimizer undoes this arithmetic.
+	idx := ir.NewBinaryExpr(base.Pos, ir.OSUB, newLen, ir.NewUnaryExpr(base.Pos, ir.OLEN, l2))
 
 	var ncopy ir.Node
 	if elemtype.HasPointers() {
-		// copy(s[len(l1):], l2)
-		slice := ir.NewSliceExpr(base.Pos, ir.OSLICE, s, ir.NewUnaryExpr(base.Pos, ir.OLEN, l1), nil, nil)
+		// copy(s[idx:], l2)
+		slice := ir.NewSliceExpr(base.Pos, ir.OSLICE, s, idx, nil, nil)
 		slice.SetType(s.Type())
+		slice.SetBounded(true)
 
 		ir.CurFunc.SetWBPos(n.Pos())
 
@@ -523,13 +545,14 @@
 		fn = typecheck.SubstArgTypes(fn, l1.Type().Elem(), l2.Type().Elem())
 		ptr1, len1 := backingArrayPtrLen(cheapExpr(slice, &nodes))
 		ptr2, len2 := backingArrayPtrLen(l2)
-		ncopy = mkcall1(fn, types.Types[types.TINT], &nodes, reflectdata.TypePtr(elemtype), ptr1, len1, ptr2, len2)
+		ncopy = mkcall1(fn, types.Types[types.TINT], &nodes, reflectdata.AppendElemRType(base.Pos, n), ptr1, len1, ptr2, len2)
 	} else if base.Flag.Cfg.Instrumenting && !base.Flag.CompilingRuntime {
 		// rely on runtime to instrument:
-		//  copy(s[len(l1):], l2)
+		//  copy(s[idx:], l2)
 		// l2 can be a slice or string.
-		slice := ir.NewSliceExpr(base.Pos, ir.OSLICE, s, ir.NewUnaryExpr(base.Pos, ir.OLEN, l1), nil, nil)
+		slice := ir.NewSliceExpr(base.Pos, ir.OSLICE, s, idx, nil, nil)
 		slice.SetType(s.Type())
+		slice.SetBounded(true)
 
 		ptr1, len1 := backingArrayPtrLen(cheapExpr(slice, &nodes))
 		ptr2, len2 := backingArrayPtrLen(l2)
@@ -538,8 +561,8 @@
 		fn = typecheck.SubstArgTypes(fn, ptr1.Type().Elem(), ptr2.Type().Elem())
 		ncopy = mkcall1(fn, types.Types[types.TINT], &nodes, ptr1, len1, ptr2, len2, ir.NewInt(elemtype.Size()))
 	} else {
-		// memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T))
-		ix := ir.NewIndexExpr(base.Pos, s, ir.NewUnaryExpr(base.Pos, ir.OLEN, l1))
+		// memmove(&s[idx], &l2[0], len(l2)*sizeof(T))
+		ix := ir.NewIndexExpr(base.Pos, s, idx)
 		ix.SetBounded(true)
 		addr := typecheck.NodAddr(ix)
 
@@ -613,20 +636,21 @@
 //	  // overflows int. Interpreting n when negative as uint makes it larger
 //	  // than cap(s). growslice will check the int n arg and panic if n is
 //	  // negative. This prevents the overflow from being undetected.
-//	  if uint(n) > uint(cap(s)) {
-//	    s = growslice(T, s, n)
+//	  if uint(n) <= uint(cap(s)) {
+//	    s = s[:n]
+//	  } else {
+//	    s = growslice(T, s.ptr, n, s.cap, l2, T)
 //	  }
-//	  s = s[:n]
-//	  lptr := &l1[0]
-//	  sptr := &s[0]
-//	  if lptr == sptr || !T.HasPointers() {
-//	    // growslice did not clear the whole underlying array (or did not get called)
-//	    hp := &s[len(l1)]
-//	    hn := l2 * sizeof(T)
-//	    memclr(hp, hn)
-//	  }
+//	  // clear the new portion of the underlying array.
+//	  hp := &s[len(s)-l2]
+//	  hn := l2 * sizeof(T)
+//	  memclr(hp, hn)
 //	}
 //	s
+//
+//	if T has pointers, the final memclr can go inside the "then" branch, as
+//	growslice will have done the clearing for us.
+
 func extendSlice(n *ir.CallExpr, init *ir.Nodes) ir.Node {
 	// isAppendOfMake made sure all possible positive values of l2 fit into an uint.
 	// The case of l2 overflow when converting from e.g. uint to int is handled by an explicit
@@ -656,40 +680,40 @@
 
 	elemtype := s.Type().Elem()
 
-	// n := len(s) + l2
+	// n := s.len + l2
 	nn := typecheck.Temp(types.Types[types.TINT])
 	nodes = append(nodes, ir.NewAssignStmt(base.Pos, nn, ir.NewBinaryExpr(base.Pos, ir.OADD, ir.NewUnaryExpr(base.Pos, ir.OLEN, s), l2)))
 
-	// if uint(n) > uint(cap(s))
+	// if uint(n) <= uint(s.cap)
 	nuint := typecheck.Conv(nn, types.Types[types.TUINT])
 	capuint := typecheck.Conv(ir.NewUnaryExpr(base.Pos, ir.OCAP, s), types.Types[types.TUINT])
-	nif := ir.NewIfStmt(base.Pos, ir.NewBinaryExpr(base.Pos, ir.OGT, nuint, capuint), nil, nil)
+	nif := ir.NewIfStmt(base.Pos, ir.NewBinaryExpr(base.Pos, ir.OLE, nuint, capuint), nil, nil)
+	nif.Likely = true
 
-	// instantiate growslice(typ *type, old []any, newcap int) []any
+	// then { s = s[:n] }
+	nt := ir.NewSliceExpr(base.Pos, ir.OSLICE, s, nil, nn, nil)
+	nt.SetBounded(true)
+	nif.Body = []ir.Node{ir.NewAssignStmt(base.Pos, s, nt)}
+
+	// instantiate growslice(oldPtr *any, newLen, oldCap, num int, typ *type) []any
 	fn := typecheck.LookupRuntime("growslice")
 	fn = typecheck.SubstArgTypes(fn, elemtype, elemtype)
 
-	// s = growslice(T, s, n)
-	nif.Body = []ir.Node{ir.NewAssignStmt(base.Pos, s, mkcall1(fn, s.Type(), nif.PtrInit(), reflectdata.TypePtr(elemtype), s, nn))}
+	// else { s = growslice(s.ptr, n, s.cap, l2, T) }
+	nif.Else = []ir.Node{
+		ir.NewAssignStmt(base.Pos, s, mkcall1(fn, s.Type(), nif.PtrInit(),
+			ir.NewUnaryExpr(base.Pos, ir.OSPTR, s),
+			nn,
+			ir.NewUnaryExpr(base.Pos, ir.OCAP, s),
+			l2,
+			reflectdata.TypePtr(elemtype))),
+	}
+
 	nodes = append(nodes, nif)
 
-	// s = s[:n]
-	nt := ir.NewSliceExpr(base.Pos, ir.OSLICE, s, nil, nn, nil)
-	nt.SetBounded(true)
-	nodes = append(nodes, ir.NewAssignStmt(base.Pos, s, nt))
-
-	// lptr := &l1[0]
-	l1ptr := typecheck.Temp(l1.Type().Elem().PtrTo())
-	tmp := ir.NewUnaryExpr(base.Pos, ir.OSPTR, l1)
-	nodes = append(nodes, ir.NewAssignStmt(base.Pos, l1ptr, tmp))
-
-	// sptr := &s[0]
-	sptr := typecheck.Temp(elemtype.PtrTo())
-	tmp = ir.NewUnaryExpr(base.Pos, ir.OSPTR, s)
-	nodes = append(nodes, ir.NewAssignStmt(base.Pos, sptr, tmp))
-
-	// hp := &s[len(l1)]
-	ix := ir.NewIndexExpr(base.Pos, s, ir.NewUnaryExpr(base.Pos, ir.OLEN, l1))
+	// hp := &s[s.len - l2]
+	// TODO: &s[s.len] - hn?
+	ix := ir.NewIndexExpr(base.Pos, s, ir.NewBinaryExpr(base.Pos, ir.OSUB, ir.NewUnaryExpr(base.Pos, ir.OLEN, s), l2))
 	ix.SetBounded(true)
 	hp := typecheck.ConvNop(typecheck.NodAddr(ix), types.Types[types.TUNSAFEPTR])
 
@@ -706,12 +730,10 @@
 	var clr ir.Nodes
 	clrfn := mkcall(clrname, nil, &clr, hp, hn)
 	clr.Append(clrfn)
-
 	if hasPointers {
-		// if l1ptr == sptr
-		nifclr := ir.NewIfStmt(base.Pos, ir.NewBinaryExpr(base.Pos, ir.OEQ, l1ptr, sptr), nil, nil)
-		nifclr.Body = clr
-		nodes = append(nodes, nifclr)
+		// growslice will have cleared the new entries, so only
+		// if growslice isn't called do we need to do the zeroing ourselves.
+		nif.Body = append(nif.Body, clr...)
 	} else {
 		nodes = append(nodes, clr...)
 	}
diff --git a/src/cmd/compile/internal/walk/builtin.go b/src/cmd/compile/internal/walk/builtin.go
index a11031b..31c4b06 100644
--- a/src/cmd/compile/internal/walk/builtin.go
+++ b/src/cmd/compile/internal/walk/builtin.go
@@ -22,23 +22,24 @@
 // x, y, z (including runtime panics) are evaluated in
 // initialization statements before the append.
 // For normal code generation, stop there and leave the
-// rest to cgen_append.
+// rest to ssagen.
 //
 // For race detector, expand append(src, a [, b]* ) to
 //
-//	  init {
-//	    s := src
-//	    const argc = len(args) - 1
-//	    if cap(s) - len(s) < argc {
-//		    s = growslice(s, len(s)+argc)
-//	    }
-//	    n := len(s)
-//	    s = s[:n+argc]
-//	    s[n] = a
-//	    s[n+1] = b
-//	    ...
+//	init {
+//	  s := src
+//	  const argc = len(args) - 1
+//	  newLen := s.len + argc
+//	  if uint(newLen) <= uint(s.cap) {
+//	    s = s[:newLen]
+//	  } else {
+//	    s = growslice(s.ptr, newLen, s.cap, argc, elemType)
 //	  }
-//	  s
+//	  s[s.len - argc] = a
+//	  s[s.len - argc + 1] = b
+//	  ...
+//	}
+//	s
 func walkAppend(n *ir.CallExpr, init *ir.Nodes, dst ir.Node) ir.Node {
 	if !ir.SameSafeExpr(dst, n.Args[0]) {
 		n.Args[0] = safeExpr(n.Args[0], init)
@@ -70,49 +71,63 @@
 	}
 
 	// General case, with no function calls left as arguments.
-	// Leave for gen, except that instrumentation requires old form.
+	// Leave for ssagen, except that instrumentation requires the old form.
 	if !base.Flag.Cfg.Instrumenting || base.Flag.CompilingRuntime {
 		return n
 	}
 
 	var l []ir.Node
 
-	ns := typecheck.Temp(nsrc.Type())
-	l = append(l, ir.NewAssignStmt(base.Pos, ns, nsrc)) // s = src
+	// s = slice to append to
+	s := typecheck.Temp(nsrc.Type())
+	l = append(l, ir.NewAssignStmt(base.Pos, s, nsrc))
 
-	na := ir.NewInt(int64(argc))                 // const argc
-	nif := ir.NewIfStmt(base.Pos, nil, nil, nil) // if cap(s) - len(s) < argc
-	nif.Cond = ir.NewBinaryExpr(base.Pos, ir.OLT, ir.NewBinaryExpr(base.Pos, ir.OSUB, ir.NewUnaryExpr(base.Pos, ir.OCAP, ns), ir.NewUnaryExpr(base.Pos, ir.OLEN, ns)), na)
+	// num = number of things to append
+	num := ir.NewInt(int64(argc))
 
-	fn := typecheck.LookupRuntime("growslice") //   growslice(<type>, old []T, mincap int) (ret []T)
-	fn = typecheck.SubstArgTypes(fn, ns.Type().Elem(), ns.Type().Elem())
+	// newLen := s.len + num
+	newLen := typecheck.Temp(types.Types[types.TINT])
+	l = append(l, ir.NewAssignStmt(base.Pos, newLen, ir.NewBinaryExpr(base.Pos, ir.OADD, ir.NewUnaryExpr(base.Pos, ir.OLEN, s), num)))
 
-	nif.Body = []ir.Node{ir.NewAssignStmt(base.Pos, ns, mkcall1(fn, ns.Type(), nif.PtrInit(), reflectdata.TypePtr(ns.Type().Elem()), ns,
-		ir.NewBinaryExpr(base.Pos, ir.OADD, ir.NewUnaryExpr(base.Pos, ir.OLEN, ns), na)))}
+	// if uint(newLen) <= uint(s.cap)
+	nif := ir.NewIfStmt(base.Pos, nil, nil, nil)
+	nif.Cond = ir.NewBinaryExpr(base.Pos, ir.OLE, typecheck.Conv(newLen, types.Types[types.TUINT]), typecheck.Conv(ir.NewUnaryExpr(base.Pos, ir.OCAP, s), types.Types[types.TUINT]))
+	nif.Likely = true
+
+	// then { s = s[:n] }
+	slice := ir.NewSliceExpr(base.Pos, ir.OSLICE, s, nil, newLen, nil)
+	slice.SetBounded(true)
+	nif.Body = []ir.Node{
+		ir.NewAssignStmt(base.Pos, s, slice),
+	}
+
+	fn := typecheck.LookupRuntime("growslice") //   growslice(ptr *T, newLen, oldCap, num int, <type>) (ret []T)
+	fn = typecheck.SubstArgTypes(fn, s.Type().Elem(), s.Type().Elem())
+
+	// else { s = growslice(s.ptr, n, s.cap, a, T) }
+	nif.Else = []ir.Node{
+		ir.NewAssignStmt(base.Pos, s, mkcall1(fn, s.Type(), nif.PtrInit(),
+			ir.NewUnaryExpr(base.Pos, ir.OSPTR, s),
+			newLen,
+			ir.NewUnaryExpr(base.Pos, ir.OCAP, s),
+			num,
+			reflectdata.TypePtr(s.Type().Elem()))),
+	}
 
 	l = append(l, nif)
 
-	nn := typecheck.Temp(types.Types[types.TINT])
-	l = append(l, ir.NewAssignStmt(base.Pos, nn, ir.NewUnaryExpr(base.Pos, ir.OLEN, ns))) // n = len(s)
-
-	slice := ir.NewSliceExpr(base.Pos, ir.OSLICE, ns, nil, ir.NewBinaryExpr(base.Pos, ir.OADD, nn, na), nil) // ...s[:n+argc]
-	slice.SetBounded(true)
-	l = append(l, ir.NewAssignStmt(base.Pos, ns, slice)) // s = s[:n+argc]
-
 	ls = n.Args[1:]
 	for i, n := range ls {
-		ix := ir.NewIndexExpr(base.Pos, ns, nn) // s[n] ...
+		// s[s.len-argc+i] = arg
+		ix := ir.NewIndexExpr(base.Pos, s, ir.NewBinaryExpr(base.Pos, ir.OSUB, newLen, ir.NewInt(int64(argc-i))))
 		ix.SetBounded(true)
-		l = append(l, ir.NewAssignStmt(base.Pos, ix, n)) // s[n] = arg
-		if i+1 < len(ls) {
-			l = append(l, ir.NewAssignStmt(base.Pos, nn, ir.NewBinaryExpr(base.Pos, ir.OADD, nn, ir.NewInt(1)))) // n = n + 1
-		}
+		l = append(l, ir.NewAssignStmt(base.Pos, ix, n))
 	}
 
 	typecheck.Stmts(l)
 	walkStmtList(l)
 	init.Append(l...)
-	return ns
+	return s
 }
 
 // walkClose walks an OCLOSE node.
@@ -141,7 +156,7 @@
 		ptrL, lenL := backingArrayPtrLen(n.X)
 		n.Y = cheapExpr(n.Y, init)
 		ptrR, lenR := backingArrayPtrLen(n.Y)
-		return mkcall1(fn, n.Type(), init, reflectdata.TypePtr(n.X.Type().Elem()), ptrL, lenL, ptrR, lenR)
+		return mkcall1(fn, n.Type(), init, reflectdata.CopyElemRType(base.Pos, n), ptrL, lenL, ptrR, lenR)
 	}
 
 	if runtimecall {
@@ -214,7 +229,7 @@
 	t := map_.Type()
 	fast := mapfast(t)
 	key = mapKeyArg(fast, n, key, false)
-	return mkcall1(mapfndel(mapdelete[fast], t), nil, init, reflectdata.TypePtr(t), map_, key)
+	return mkcall1(mapfndel(mapdelete[fast], t), nil, init, reflectdata.DeleteMapRType(base.Pos, n), map_, key)
 }
 
 // walkLenCap walks an OLEN or OCAP node.
@@ -258,7 +273,7 @@
 		argtype = types.Types[types.TINT]
 	}
 
-	return mkcall1(chanfn(fnname, 1, n.Type()), n.Type(), init, reflectdata.TypePtr(n.Type()), typecheck.Conv(size, argtype))
+	return mkcall1(chanfn(fnname, 1, n.Type()), n.Type(), init, reflectdata.MakeChanRType(base.Pos, n), typecheck.Conv(size, argtype))
 }
 
 // walkMakeMap walks an OMAKEMAP node.
@@ -356,7 +371,7 @@
 
 	fn := typecheck.LookupRuntime(fnname)
 	fn = typecheck.SubstArgTypes(fn, hmapType, t.Key(), t.Elem())
-	return mkcall1(fn, n.Type(), init, reflectdata.TypePtr(n.Type()), typecheck.Conv(hint, argtype), h)
+	return mkcall1(fn, n.Type(), init, reflectdata.MakeMapRType(base.Pos, n), typecheck.Conv(hint, argtype), h)
 }
 
 // walkMakeSlice walks an OMAKESLICE node.
@@ -421,7 +436,7 @@
 		argtype = types.Types[types.TINT]
 	}
 	fn := typecheck.LookupRuntime(fnname)
-	ptr := mkcall1(fn, types.Types[types.TUNSAFEPTR], init, reflectdata.TypePtr(t.Elem()), typecheck.Conv(len, argtype), typecheck.Conv(cap, argtype))
+	ptr := mkcall1(fn, types.Types[types.TUNSAFEPTR], init, reflectdata.MakeSliceElemRType(base.Pos, n), typecheck.Conv(len, argtype), typecheck.Conv(cap, argtype))
 	ptr.MarkNonNil()
 	len = typecheck.Conv(len, types.Types[types.TINT])
 	cap = typecheck.Conv(cap, types.Types[types.TINT])
@@ -475,7 +490,7 @@
 	// Replace make+copy with runtime.makeslicecopy.
 	// instantiate makeslicecopy(typ *byte, tolen int, fromlen int, from unsafe.Pointer) unsafe.Pointer
 	fn := typecheck.LookupRuntime("makeslicecopy")
-	ptr := mkcall1(fn, types.Types[types.TUNSAFEPTR], init, reflectdata.TypePtr(t.Elem()), length, copylen, typecheck.Conv(copyptr, types.Types[types.TUNSAFEPTR]))
+	ptr := mkcall1(fn, types.Types[types.TUNSAFEPTR], init, reflectdata.MakeSliceElemRType(base.Pos, n), length, copylen, typecheck.Conv(copyptr, types.Types[types.TUNSAFEPTR]))
 	ptr.MarkNonNil()
 	sh := ir.NewSliceHeaderExpr(base.Pos, t, ptr, length, length)
 	return walkExpr(typecheck.Expr(sh), init)
@@ -498,7 +513,7 @@
 	return n
 }
 
-// generate code for print
+// generate code for print.
 func walkPrint(nn *ir.CallExpr, init *ir.Nodes) ir.Node {
 	// Hoist all the argument evaluation up before the lock.
 	walkExprListCheap(nn.Args, init)
@@ -642,6 +657,14 @@
 	return mkcall("gorecover", nn.Type(), init, walkExpr(nn.Args[0], init))
 }
 
+// walkUnsafeData walks an OUNSAFESLICEDATA or OUNSAFESTRINGDATA expression.
+func walkUnsafeData(n *ir.UnaryExpr, init *ir.Nodes) ir.Node {
+	slice := walkExpr(n.X, init)
+	res := typecheck.Expr(ir.NewUnaryExpr(n.Pos(), ir.OSPTR, slice))
+	res.SetType(n.Type())
+	return walkExpr(res, init)
+}
+
 func walkUnsafeSlice(n *ir.BinaryExpr, init *ir.Nodes) ir.Node {
 	ptr := safeExpr(n.X, init)
 	len := safeExpr(n.Y, init)
@@ -658,7 +681,7 @@
 	if ir.ShouldCheckPtr(ir.CurFunc, 1) {
 		fnname := "unsafeslicecheckptr"
 		fn := typecheck.LookupRuntime(fnname)
-		init.Append(mkcall1(fn, nil, init, reflectdata.TypePtr(sliceType.Elem()), unsafePtr, typecheck.Conv(len, lenType)))
+		init.Append(mkcall1(fn, nil, init, reflectdata.UnsafeSliceElemRType(base.Pos, n), unsafePtr, typecheck.Conv(len, lenType)))
 	} else {
 		// Otherwise, open code unsafe.Slice to prevent runtime call overhead.
 		// Keep this code in sync with runtime.unsafeslice{,64}
@@ -682,6 +705,25 @@
 		nif.Body.Append(mkcall("panicunsafeslicelen", nil, &nif.Body))
 		appendWalkStmt(init, nif)
 
+		if sliceType.Elem().Size() == 0 {
+			// if ptr == nil && len > 0  {
+			//      panicunsafesliceptrnil()
+			// }
+			nifPtr := ir.NewIfStmt(base.Pos, nil, nil, nil)
+			isNil := ir.NewBinaryExpr(base.Pos, ir.OEQ, unsafePtr, typecheck.NodNil())
+			gtZero := ir.NewBinaryExpr(base.Pos, ir.OGT, typecheck.Conv(len, lenType), ir.NewInt(0))
+			nifPtr.Cond =
+				ir.NewLogicalExpr(base.Pos, ir.OANDAND, isNil, gtZero)
+			nifPtr.Body.Append(mkcall("panicunsafeslicenilptr", nil, &nifPtr.Body))
+			appendWalkStmt(init, nifPtr)
+
+			h := ir.NewSliceHeaderExpr(n.Pos(), sliceType,
+				typecheck.Conv(ptr, types.Types[types.TUNSAFEPTR]),
+				typecheck.Conv(len, types.Types[types.TINT]),
+				typecheck.Conv(len, types.Types[types.TINT]))
+			return walkExpr(typecheck.Expr(h), init)
+		}
+
 		// mem, overflow := runtime.mulUintptr(et.size, len)
 		mem := typecheck.Temp(types.Types[types.TUINTPTR])
 		overflow := typecheck.Temp(types.Types[types.TBOOL])
@@ -712,6 +754,64 @@
 	return walkExpr(typecheck.Expr(h), init)
 }
 
+func walkUnsafeString(n *ir.BinaryExpr, init *ir.Nodes) ir.Node {
+	ptr := safeExpr(n.X, init)
+	len := safeExpr(n.Y, init)
+
+	lenType := types.Types[types.TINT64]
+	unsafePtr := typecheck.Conv(ptr, types.Types[types.TUNSAFEPTR])
+
+	// If checkptr enabled, call runtime.unsafestringcheckptr to check ptr and len.
+	// for simplicity, unsafestringcheckptr always uses int64.
+	// Type checking guarantees that TIDEAL len are positive and fit in an int.
+	if ir.ShouldCheckPtr(ir.CurFunc, 1) {
+		fnname := "unsafestringcheckptr"
+		fn := typecheck.LookupRuntime(fnname)
+		init.Append(mkcall1(fn, nil, init, unsafePtr, typecheck.Conv(len, lenType)))
+	} else {
+		// Otherwise, open code unsafe.String to prevent runtime call overhead.
+		// Keep this code in sync with runtime.unsafestring{,64}
+		if len.Type().IsKind(types.TIDEAL) || len.Type().Size() <= types.Types[types.TUINT].Size() {
+			lenType = types.Types[types.TINT]
+		} else {
+			// len64 := int64(len)
+			// if int64(int(len64)) != len64 {
+			//     panicunsafestringlen()
+			// }
+			len64 := typecheck.Conv(len, lenType)
+			nif := ir.NewIfStmt(base.Pos, nil, nil, nil)
+			nif.Cond = ir.NewBinaryExpr(base.Pos, ir.ONE, typecheck.Conv(typecheck.Conv(len64, types.Types[types.TINT]), lenType), len64)
+			nif.Body.Append(mkcall("panicunsafestringlen", nil, &nif.Body))
+			appendWalkStmt(init, nif)
+		}
+
+		// if len < 0 { panicunsafestringlen() }
+		nif := ir.NewIfStmt(base.Pos, nil, nil, nil)
+		nif.Cond = ir.NewBinaryExpr(base.Pos, ir.OLT, typecheck.Conv(len, lenType), ir.NewInt(0))
+		nif.Body.Append(mkcall("panicunsafestringlen", nil, &nif.Body))
+		appendWalkStmt(init, nif)
+
+		// if uintpr(len) > -uintptr(ptr) {
+		//    if ptr == nil {
+		//       panicunsafestringnilptr()
+		//    }
+		//    panicunsafeslicelen()
+		// }
+		nifLen := ir.NewIfStmt(base.Pos, nil, nil, nil)
+		nifLen.Cond = ir.NewBinaryExpr(base.Pos, ir.OGT, typecheck.Conv(len, types.Types[types.TUINTPTR]), ir.NewUnaryExpr(base.Pos, ir.ONEG, typecheck.Conv(unsafePtr, types.Types[types.TUINTPTR])))
+		nifPtr := ir.NewIfStmt(base.Pos, nil, nil, nil)
+		nifPtr.Cond = ir.NewBinaryExpr(base.Pos, ir.OEQ, unsafePtr, typecheck.NodNil())
+		nifPtr.Body.Append(mkcall("panicunsafestringnilptr", nil, &nifPtr.Body))
+		nifLen.Body.Append(nifPtr, mkcall("panicunsafestringlen", nil, &nifLen.Body))
+		appendWalkStmt(init, nifLen)
+	}
+	h := ir.NewStringHeaderExpr(n.Pos(),
+		typecheck.Conv(ptr, types.Types[types.TUNSAFEPTR]),
+		typecheck.Conv(len, types.Types[types.TINT]),
+	)
+	return walkExpr(typecheck.Expr(h), init)
+}
+
 func badtype(op ir.Op, tl, tr *types.Type) {
 	var s string
 	if tl != nil {
diff --git a/src/cmd/compile/internal/walk/compare.go b/src/cmd/compile/internal/walk/compare.go
index 6a8ad56..fe9c5d8 100644
--- a/src/cmd/compile/internal/walk/compare.go
+++ b/src/cmd/compile/internal/walk/compare.go
@@ -54,6 +54,10 @@
 	// Given mixed interface/concrete comparison,
 	// rewrite into types-equal && data-equal.
 	// This is efficient, avoids allocations, and avoids runtime calls.
+	//
+	// TODO(mdempsky): It would be more general and probably overall
+	// simpler to just extend walkCompareInterface to optimize when one
+	// operand is an OCONVIFACE.
 	if n.X.Type().IsInterface() != n.Y.Type().IsInterface() {
 		// Preserve side-effects in case of short-circuiting; see #32187.
 		l := cheapExpr(n.X, init)
@@ -74,9 +78,12 @@
 		//   l.tab == type(r)
 		// For non-empty interface, this is:
 		//   l.tab != nil && l.tab._type == type(r)
+		//
+		// TODO(mdempsky): For non-empty interface comparisons, just
+		// compare against the itab address directly?
 		var eqtype ir.Node
 		tab := ir.NewUnaryExpr(base.Pos, ir.OITAB, l)
-		rtyp := reflectdata.TypePtr(r.Type())
+		rtyp := reflectdata.CompareRType(base.Pos, n)
 		if l.Type().IsEmptyInterface() {
 			tab.SetType(types.NewPtr(types.Types[types.TUINT8]))
 			tab.SetTypecheck(1)
@@ -109,7 +116,7 @@
 
 	switch t.Kind() {
 	default:
-		if base.Debug.Libfuzzer != 0 && t.IsInteger() {
+		if base.Debug.Libfuzzer != 0 && t.IsInteger() && (n.X.Name() == nil || !n.X.Name().Libfuzzer8BitCounter()) {
 			n.X = cheapExpr(n.X, init)
 			n.Y = cheapExpr(n.Y, init)
 
@@ -160,7 +167,7 @@
 		// We can compare several elements at once with 2/4/8 byte integer compares
 		inline = t.NumElem() <= 1 || (types.IsSimple[t.Elem().Kind()] && (t.NumElem() <= 4 || t.Elem().Size()*t.NumElem() <= maxcmpsize))
 	case types.TSTRUCT:
-		inline = t.NumComponents(types.IgnoreBlankFields) <= 4
+		inline = compare.EqStructCost(t) <= 4
 	}
 
 	cmpl := n.X
diff --git a/src/cmd/compile/internal/walk/complit.go b/src/cmd/compile/internal/walk/complit.go
index 595fe85..187c28b 100644
--- a/src/cmd/compile/internal/walk/complit.go
+++ b/src/cmd/compile/internal/walk/complit.go
@@ -243,6 +243,8 @@
 					// confuses about variables lifetime. So making sure those expressions
 					// are ordered correctly here. See issue #52673.
 					orderBlock(&sinit, map[string][]*ir.Name{})
+					typecheck.Stmts(sinit)
+					walkStmtList(sinit)
 				}
 				init.Append(sinit...)
 				continue
@@ -414,9 +416,10 @@
 
 func maplit(n *ir.CompLitExpr, m ir.Node, init *ir.Nodes) {
 	// make the map var
-	a := ir.NewCallExpr(base.Pos, ir.OMAKE, nil, nil)
+	args := []ir.Node{ir.TypeNode(n.Type()), ir.NewInt(n.Len + int64(len(n.List)))}
+	a := typecheck.Expr(ir.NewCallExpr(base.Pos, ir.OMAKE, nil, args)).(*ir.MakeExpr)
+	a.RType = n.RType
 	a.SetEsc(n.Esc())
-	a.Args = []ir.Node{ir.TypeNode(n.Type()), ir.NewInt(n.Len + int64(len(n.List)))}
 	appendWalkStmt(init, ir.NewAssignStmt(base.Pos, m, a))
 
 	entries := n.List
@@ -467,14 +470,18 @@
 
 		kidx := ir.NewIndexExpr(base.Pos, vstatk, i)
 		kidx.SetBounded(true)
-		lhs := ir.NewIndexExpr(base.Pos, m, kidx)
+
+		// typechecker rewrites OINDEX to OINDEXMAP
+		lhs := typecheck.AssignExpr(ir.NewIndexExpr(base.Pos, m, kidx)).(*ir.IndexExpr)
+		base.AssertfAt(lhs.Op() == ir.OINDEXMAP, lhs.Pos(), "want OINDEXMAP, have %+v", lhs)
+		lhs.RType = n.RType
 
 		zero := ir.NewAssignStmt(base.Pos, i, ir.NewInt(0))
 		cond := ir.NewBinaryExpr(base.Pos, ir.OLT, i, ir.NewInt(tk.NumElem()))
 		incr := ir.NewAssignStmt(base.Pos, i, ir.NewBinaryExpr(base.Pos, ir.OADD, i, ir.NewInt(1)))
 
 		var body ir.Node = ir.NewAssignStmt(base.Pos, lhs, rhs)
-		body = typecheck.Stmt(body) // typechecker rewrites OINDEX to OINDEXMAP
+		body = typecheck.Stmt(body)
 		body = orderStmtInPlace(body, map[string][]*ir.Name{})
 
 		loop := ir.NewForStmt(base.Pos, nil, cond, incr, nil)
@@ -489,6 +496,7 @@
 	// Build list of var[c] = expr.
 	// Use temporaries so that mapassign1 can have addressable key, elem.
 	// TODO(josharian): avoid map key temporaries for mapfast_* assignments with literal keys.
+	// TODO(khr): assign these temps in order phase so we can reuse them across multiple maplits?
 	tmpkey := typecheck.Temp(m.Type().Key())
 	tmpelem := typecheck.Temp(m.Type().Elem())
 
@@ -503,14 +511,17 @@
 		appendWalkStmt(init, ir.NewAssignStmt(base.Pos, tmpelem, elem))
 
 		ir.SetPos(tmpelem)
-		var a ir.Node = ir.NewAssignStmt(base.Pos, ir.NewIndexExpr(base.Pos, m, tmpkey), tmpelem)
-		a = typecheck.Stmt(a) // typechecker rewrites OINDEX to OINDEXMAP
+
+		// typechecker rewrites OINDEX to OINDEXMAP
+		lhs := typecheck.AssignExpr(ir.NewIndexExpr(base.Pos, m, tmpkey)).(*ir.IndexExpr)
+		base.AssertfAt(lhs.Op() == ir.OINDEXMAP, lhs.Pos(), "want OINDEXMAP, have %+v", lhs)
+		lhs.RType = n.RType
+
+		var a ir.Node = ir.NewAssignStmt(base.Pos, lhs, tmpelem)
+		a = typecheck.Stmt(a)
 		a = orderStmtInPlace(a, map[string][]*ir.Name{})
 		appendWalkStmt(init, a)
 	}
-
-	appendWalkStmt(init, ir.NewUnaryExpr(base.Pos, ir.OVARKILL, tmpkey))
-	appendWalkStmt(init, ir.NewUnaryExpr(base.Pos, ir.OVARKILL, tmpelem))
 }
 
 func anylit(n ir.Node, var_ ir.Node, init *ir.Nodes) {
diff --git a/src/cmd/compile/internal/walk/convert.go b/src/cmd/compile/internal/walk/convert.go
index 72631e7..bf06ed6 100644
--- a/src/cmd/compile/internal/walk/convert.go
+++ b/src/cmd/compile/internal/walk/convert.go
@@ -14,7 +14,6 @@
 	"cmd/compile/internal/ssagen"
 	"cmd/compile/internal/typecheck"
 	"cmd/compile/internal/types"
-	"cmd/internal/src"
 	"cmd/internal/sys"
 )
 
@@ -46,17 +45,19 @@
 	toType := n.Type()
 	if !fromType.IsInterface() && !ir.IsBlank(ir.CurFunc.Nname) {
 		// skip unnamed functions (func _())
-		reflectdata.MarkTypeUsedInInterface(fromType, ir.CurFunc.LSym)
+		if base.Debug.Unified != 0 && fromType.HasShape() {
+			// Unified IR uses OCONVIFACE for converting all derived types
+			// to interface type. Avoid assertion failure in
+			// MarkTypeUsedInInterface, because we've marked used types
+			// separately anyway.
+		} else {
+			reflectdata.MarkTypeUsedInInterface(fromType, ir.CurFunc.LSym)
+		}
 	}
 
 	if !fromType.IsInterface() {
-		var typeWord ir.Node
-		if toType.IsEmptyInterface() {
-			typeWord = reflectdata.TypePtr(fromType)
-		} else {
-			typeWord = reflectdata.ITabAddr(fromType, toType)
-		}
-		l := ir.NewBinaryExpr(base.Pos, ir.OEFACE, typeWord, dataWord(n.Pos(), n.X, init, n.Esc() != ir.EscNone))
+		typeWord := reflectdata.ConvIfaceTypeWord(base.Pos, n)
+		l := ir.NewBinaryExpr(base.Pos, ir.OEFACE, typeWord, dataWord(n, init))
 		l.SetType(toType)
 		l.SetTypecheck(n.Typecheck())
 		return l
@@ -79,13 +80,15 @@
 
 	var typeWord ir.Node
 	if toType.IsEmptyInterface() {
-		// Implement interface to empty interface conversion.
-		// res = itab
+		// Implement interface to empty interface conversion:
+		//
+		// var res *uint8
+		// res = (*uint8)(unsafe.Pointer(itab))
 		// if res != nil {
 		//    res = res.type
 		// }
 		typeWord = typecheck.Temp(types.NewPtr(types.Types[types.TUINT8]))
-		init.Append(ir.NewAssignStmt(base.Pos, typeWord, itab))
+		init.Append(ir.NewAssignStmt(base.Pos, typeWord, typecheck.Conv(typecheck.Conv(itab, types.Types[types.TUNSAFEPTR]), typeWord.Type())))
 		nif := ir.NewIfStmt(base.Pos, typecheck.Expr(ir.NewBinaryExpr(base.Pos, ir.ONE, typeWord, typecheck.NodNil())), nil, nil)
 		nif.Body = []ir.Node{ir.NewAssignStmt(base.Pos, typeWord, itabType(typeWord))}
 		init.Append(nif)
@@ -95,7 +98,7 @@
 		fn := typecheck.LookupRuntime("convI2I")
 		types.CalcSize(fn.Type())
 		call := ir.NewCallExpr(base.Pos, ir.OCALL, fn, nil)
-		call.Args = []ir.Node{reflectdata.TypePtr(toType), itab}
+		call.Args = []ir.Node{reflectdata.ConvIfaceTypeWord(base.Pos, n), itab}
 		typeWord = walkExpr(typecheck.Expr(call), init)
 	}
 
@@ -107,10 +110,10 @@
 	return e
 }
 
-// Returns the data word (the second word) used to represent n in an interface.
-// n must not be of interface type.
-// esc describes whether the result escapes.
-func dataWord(pos src.XPos, n ir.Node, init *ir.Nodes, escapes bool) ir.Node {
+// Returns the data word (the second word) used to represent conv.X in
+// an interface.
+func dataWord(conv *ir.ConvExpr, init *ir.Nodes) ir.Node {
+	pos, n := conv.Pos(), conv.X
 	fromType := n.Type()
 
 	// If it's a pointer, it is its own representation.
@@ -150,7 +153,7 @@
 	case n.Op() == ir.ONAME && n.(*ir.Name).Class == ir.PEXTERN && n.(*ir.Name).Readonly():
 		// n is a readonly global; use it directly.
 		value = n
-	case !escapes && fromType.Size() <= 1024:
+	case conv.Esc() == ir.EscNone && fromType.Size() <= 1024:
 		// n does not escape. Use a stack temporary initialized to n.
 		value = typecheck.Temp(fromType)
 		init.Append(typecheck.Stmt(ir.NewAssignStmt(base.Pos, value, n)))
@@ -176,7 +179,7 @@
 			n = copyExpr(n, fromType, init)
 		}
 		fn = typecheck.SubstArgTypes(fn, fromType)
-		args = []ir.Node{reflectdata.TypePtr(fromType), typecheck.NodAddr(n)}
+		args = []ir.Node{reflectdata.ConvIfaceSrcRType(base.Pos, conv), typecheck.NodAddr(n)}
 	} else {
 		// Use a specialized conversion routine that takes the type being
 		// converted by value, not by pointer.
@@ -211,7 +214,7 @@
 // walkConvIData walks an OCONVIDATA node.
 func walkConvIData(n *ir.ConvExpr, init *ir.Nodes) ir.Node {
 	n.X = walkExpr(n.X, init)
-	return dataWord(n.Pos(), n.X, init, n.Esc() != ir.EscNone)
+	return dataWord(n, init)
 }
 
 // walkBytesRunesToString walks an OBYTES2STR or ORUNES2STR node.
@@ -502,3 +505,21 @@
 
 	return cheap
 }
+
+// walkSliceToArray walks an OSLICE2ARR expression.
+func walkSliceToArray(n *ir.ConvExpr, init *ir.Nodes) ir.Node {
+	// Replace T(x) with *(*T)(x).
+	conv := typecheck.Expr(ir.NewConvExpr(base.Pos, ir.OCONV, types.NewPtr(n.Type()), n.X)).(*ir.ConvExpr)
+	deref := typecheck.Expr(ir.NewStarExpr(base.Pos, conv)).(*ir.StarExpr)
+
+	// The OSLICE2ARRPTR conversion handles checking the slice length,
+	// so the dereference can't fail.
+	//
+	// However, this is more than just an optimization: if T is a
+	// zero-length array, then x (and thus (*T)(x)) can be nil, but T(x)
+	// should *not* panic. So suppressing the nil check here is
+	// necessary for correctness in that case.
+	deref.SetBounded(true)
+
+	return walkExpr(deref, init)
+}
diff --git a/src/cmd/compile/internal/walk/expr.go b/src/cmd/compile/internal/walk/expr.go
index 803a07a..24fe0d0 100644
--- a/src/cmd/compile/internal/walk/expr.go
+++ b/src/cmd/compile/internal/walk/expr.go
@@ -129,6 +129,14 @@
 		n := n.(*ir.BinaryExpr)
 		return walkUnsafeSlice(n, init)
 
+	case ir.OUNSAFESTRING:
+		n := n.(*ir.BinaryExpr)
+		return walkUnsafeString(n, init)
+
+	case ir.OUNSAFESTRINGDATA, ir.OUNSAFESLICEDATA:
+		n := n.(*ir.UnaryExpr)
+		return walkUnsafeData(n, init)
+
 	case ir.ODOT, ir.ODOTPTR:
 		n := n.(*ir.SelectorExpr)
 		return walkDot(n, init)
@@ -219,6 +227,10 @@
 		n := n.(*ir.ConvExpr)
 		return walkConv(n, init)
 
+	case ir.OSLICE2ARR:
+		n := n.(*ir.ConvExpr)
+		return walkSliceToArray(n, init)
+
 	case ir.OSLICE2ARRPTR:
 		n := n.(*ir.ConvExpr)
 		n.X = walkExpr(n.X, init)
@@ -244,6 +256,10 @@
 		n := n.(*ir.SliceHeaderExpr)
 		return walkSliceHeader(n, init)
 
+	case ir.OSTRINGHEADER:
+		n := n.(*ir.StringHeaderExpr)
+		return walkStringHeader(n, init)
+
 	case ir.OSLICE, ir.OSLICEARR, ir.OSLICESTR, ir.OSLICE3, ir.OSLICE3ARR:
 		n := n.(*ir.SliceExpr)
 		return walkSlice(n, init)
@@ -330,7 +346,7 @@
 // expression or simple statement.
 // the types expressions are calculated.
 // compile-time constants are evaluated.
-// complex side effects like statements are appended to init
+// complex side effects like statements are appended to init.
 func walkExprList(s []ir.Node, init *ir.Nodes) {
 	for i := range s {
 		s[i] = walkExpr(s[i], init)
@@ -545,8 +561,7 @@
 			var e ir.Node = ir.NewLinksymExpr(n.Pos(), fn.Sym().LinksymABI(abi), types.Types[types.TUINTPTR])
 			e = ir.NewAddrExpr(n.Pos(), e)
 			e.SetType(types.Types[types.TUINTPTR].PtrTo())
-			e = ir.NewConvExpr(n.Pos(), ir.OCONVNOP, n.Type(), e)
-			return e
+			return typecheck.Expr(ir.NewConvExpr(n.Pos(), ir.OCONVNOP, n.Type(), e))
 		}
 		// fn is not a defined function. It must be ABIInternal.
 		// Read the address from func value, i.e. *(*uintptr)(idata(fn)).
@@ -556,8 +571,10 @@
 		arg = walkExpr(arg, init)
 		var e ir.Node = ir.NewUnaryExpr(n.Pos(), ir.OIDATA, arg)
 		e.SetType(n.Type().PtrTo())
+		e.SetTypecheck(1)
 		e = ir.NewStarExpr(n.Pos(), e)
 		e.SetType(n.Type())
+		e.SetTypecheck(1)
 		return e
 	}
 
@@ -695,7 +712,7 @@
 	return n
 }
 
-// walkDynamicdotType walks an ODYNAMICDOTTYPE or ODYNAMICDOTTYPE2 node.
+// walkDynamicDotType walks an ODYNAMICDOTTYPE or ODYNAMICDOTTYPE2 node.
 func walkDynamicDotType(n *ir.DynamicTypeAssertExpr, init *ir.Nodes) ir.Node {
 	n.X = walkExpr(n.X, init)
 	n.RType = walkExpr(n.RType, init)
@@ -727,23 +744,11 @@
 		if base.Flag.LowerM != 0 && n.Bounded() && !ir.IsConst(n.Index, constant.Int) {
 			base.Warn("index bounds check elided")
 		}
-		if ir.IsSmallIntConst(n.Index) && !n.Bounded() {
-			base.Errorf("index out of bounds")
-		}
 	} else if ir.IsConst(n.X, constant.String) {
 		n.SetBounded(bounded(r, int64(len(ir.StringVal(n.X)))))
 		if base.Flag.LowerM != 0 && n.Bounded() && !ir.IsConst(n.Index, constant.Int) {
 			base.Warn("index bounds check elided")
 		}
-		if ir.IsSmallIntConst(n.Index) && !n.Bounded() {
-			base.Errorf("index out of bounds")
-		}
-	}
-
-	if ir.IsConst(n.Index, constant.Int) {
-		if v := n.Index.Val(); constant.Sign(v) < 0 || ir.ConstOverflow(v, types.Types[types.TINT]) {
-			base.Errorf("index out of bounds")
-		}
 	}
 	return n
 }
@@ -782,7 +787,7 @@
 	t := map_.Type()
 	fast := mapfast(t)
 	key := mapKeyArg(fast, n, n.Index, n.Assigned)
-	args := []ir.Node{reflectdata.TypePtr(t), map_, key}
+	args := []ir.Node{reflectdata.IndexMapRType(base.Pos, n), map_, key}
 
 	var mapFn ir.Node
 	switch {
@@ -837,35 +842,6 @@
 	n.High = walkExpr(n.High, init)
 	n.Max = walkExpr(n.Max, init)
 
-	if n.Op().IsSlice3() {
-		if n.Max != nil && n.Max.Op() == ir.OCAP && ir.SameSafeExpr(n.X, n.Max.(*ir.UnaryExpr).X) {
-			// Reduce x[i:j:cap(x)] to x[i:j].
-			if n.Op() == ir.OSLICE3 {
-				n.SetOp(ir.OSLICE)
-			} else {
-				n.SetOp(ir.OSLICEARR)
-			}
-			return reduceSlice(n)
-		}
-		return n
-	}
-	return reduceSlice(n)
-}
-
-// walkSliceHeader walks an OSLICEHEADER node.
-func walkSliceHeader(n *ir.SliceHeaderExpr, init *ir.Nodes) ir.Node {
-	n.Ptr = walkExpr(n.Ptr, init)
-	n.Len = walkExpr(n.Len, init)
-	n.Cap = walkExpr(n.Cap, init)
-	return n
-}
-
-// TODO(josharian): combine this with its caller and simplify
-func reduceSlice(n *ir.SliceExpr) ir.Node {
-	if n.High != nil && n.High.Op() == ir.OLEN && ir.SameSafeExpr(n.X, n.High.(*ir.UnaryExpr).X) {
-		// Reduce x[i:len(x)] to x[i:].
-		n.High = nil
-	}
 	if (n.Op() == ir.OSLICE || n.Op() == ir.OSLICESTR) && n.Low == nil && n.High == nil {
 		// Reduce x[:] to x.
 		if base.Debug.Slice > 0 {
@@ -876,7 +852,22 @@
 	return n
 }
 
-// return 1 if integer n must be in range [0, max), 0 otherwise
+// walkSliceHeader walks an OSLICEHEADER node.
+func walkSliceHeader(n *ir.SliceHeaderExpr, init *ir.Nodes) ir.Node {
+	n.Ptr = walkExpr(n.Ptr, init)
+	n.Len = walkExpr(n.Len, init)
+	n.Cap = walkExpr(n.Cap, init)
+	return n
+}
+
+// walkStringHeader walks an OSTRINGHEADER node.
+func walkStringHeader(n *ir.StringHeaderExpr, init *ir.Nodes) ir.Node {
+	n.Ptr = walkExpr(n.Ptr, init)
+	n.Len = walkExpr(n.Len, init)
+	return n
+}
+
+// return 1 if integer n must be in range [0, max), 0 otherwise.
 func bounded(n ir.Node, max int64) bool {
 	if n.Type() == nil || !n.Type().IsInteger() {
 		return false
diff --git a/src/cmd/compile/internal/walk/order.go b/src/cmd/compile/internal/walk/order.go
index 2d1e882..c7c3d97 100644
--- a/src/cmd/compile/internal/walk/order.go
+++ b/src/cmd/compile/internal/walk/order.go
@@ -36,18 +36,6 @@
 // Arrange that receive expressions only appear in direct assignments
 // x = <-c or as standalone statements <-c, never in larger expressions.
 
-// TODO(rsc): The temporary introduction during multiple assignments
-// should be moved into this file, so that the temporaries can be cleaned
-// and so that conversions implicit in the OAS2FUNC and OAS2RECV
-// nodes can be made explicit and then have their temporaries cleaned.
-
-// TODO(rsc): Goto and multilevel break/continue can jump over
-// inserted VARKILL annotations. Work out a way to handle these.
-// The current implementation is safe, in that it will execute correctly.
-// But it won't reuse temporaries as aggressively as it might, and
-// it can result in unnecessary zeroing of those variables in the function
-// prologue.
-
 // orderState holds state during the ordering process.
 type orderState struct {
 	out  []ir.Node             // list of generated statements
@@ -56,7 +44,7 @@
 	edit func(ir.Node) ir.Node // cached closure of o.exprNoLHS
 }
 
-// Order rewrites fn.Nbody to apply the ordering constraints
+// order rewrites fn.Nbody to apply the ordering constraints
 // described in the comment at the top of the file.
 func order(fn *ir.Func) {
 	if base.Flag.W > 1 {
@@ -223,16 +211,6 @@
 	}
 }
 
-// isaddrokay reports whether it is okay to pass n's address to runtime routines.
-// Taking the address of a variable makes the liveness and optimization analyses
-// lose track of where the variable's lifetime ends. To avoid hurting the analyses
-// of ordinary stack variables, those are not 'isaddrokay'. Temporaries are okay,
-// because we emit explicit VARKILL instructions marking the end of those
-// temporaries' lifetimes.
-func isaddrokay(n ir.Node) bool {
-	return ir.IsAddressable(n) && (n.Op() != ir.ONAME || n.(*ir.Name).Class == ir.PEXTERN || ir.IsAutoTmp(n))
-}
-
 // addrTemp ensures that n is okay to pass by address to runtime routines.
 // If the original argument n is not okay, addrTemp creates a tmp, emits
 // tmp = n, and then returns tmp.
@@ -253,7 +231,7 @@
 		vstat = typecheck.Expr(vstat).(*ir.Name)
 		return vstat
 	}
-	if isaddrokay(n) {
+	if ir.IsAddressable(n) {
 		return n
 	}
 	return o.copyExpr(n)
@@ -261,7 +239,13 @@
 
 // mapKeyTemp prepares n to be a key in a map runtime call and returns n.
 // It should only be used for map runtime calls which have *_fast* versions.
-func (o *orderState) mapKeyTemp(t *types.Type, n ir.Node) ir.Node {
+// The first parameter is the position of n's containing node, for use in case
+// that n's position is not unique (e.g., if n is an ONAME).
+func (o *orderState) mapKeyTemp(outerPos src.XPos, t *types.Type, n ir.Node) ir.Node {
+	pos := outerPos
+	if ir.HasUniquePos(n) {
+		pos = n.Pos()
+	}
 	// Most map calls need to take the address of the key.
 	// Exception: map*_fast* calls. See golang.org/issue/19015.
 	alg := mapfast(t)
@@ -285,7 +269,7 @@
 		return n
 	case nt.Kind() == kt.Kind(), nt.IsPtrShaped() && kt.IsPtrShaped():
 		// can directly convert (e.g. named type to underlying type, or one pointer to another)
-		return typecheck.Expr(ir.NewConvExpr(n.Pos(), ir.OCONVNOP, kt, n))
+		return typecheck.Expr(ir.NewConvExpr(pos, ir.OCONVNOP, kt, n))
 	case nt.IsInteger() && kt.IsInteger():
 		// can directly convert (e.g. int32 to uint32)
 		if n.Op() == ir.OLITERAL && nt.IsSigned() {
@@ -294,7 +278,7 @@
 			n.SetType(kt)
 			return n
 		}
-		return typecheck.Expr(ir.NewConvExpr(n.Pos(), ir.OCONV, kt, n))
+		return typecheck.Expr(ir.NewConvExpr(pos, ir.OCONV, kt, n))
 	default:
 		// Unsafe cast through memory.
 		// We'll need to do a load with type kt. Create a temporary of type kt to
@@ -305,9 +289,9 @@
 		tmp := o.newTemp(kt, true)
 		// *(*nt)(&tmp) = n
 		var e ir.Node = typecheck.NodAddr(tmp)
-		e = ir.NewConvExpr(n.Pos(), ir.OCONVNOP, nt.PtrTo(), e)
-		e = ir.NewStarExpr(n.Pos(), e)
-		o.append(ir.NewAssignStmt(base.Pos, e, n))
+		e = ir.NewConvExpr(pos, ir.OCONVNOP, nt.PtrTo(), e)
+		e = ir.NewStarExpr(pos, e)
+		o.append(ir.NewAssignStmt(pos, e, n))
 		return tmp
 	}
 }
@@ -374,25 +358,6 @@
 	o.temp = o.temp[:mark]
 }
 
-// cleanTempNoPop emits VARKILL instructions to *out
-// for each temporary above the mark on the temporary stack.
-// It does not pop the temporaries from the stack.
-func (o *orderState) cleanTempNoPop(mark ordermarker) []ir.Node {
-	var out []ir.Node
-	for i := len(o.temp) - 1; i >= int(mark); i-- {
-		n := o.temp[i]
-		out = append(out, typecheck.Stmt(ir.NewUnaryExpr(base.Pos, ir.OVARKILL, n)))
-	}
-	return out
-}
-
-// cleanTemp emits VARKILL instructions for each temporary above the
-// mark on the temporary stack and removes them from the stack.
-func (o *orderState) cleanTemp(top ordermarker) {
-	o.out = append(o.out, o.cleanTempNoPop(top)...)
-	o.popTemp(top)
-}
-
 // stmtList orders each of the statements in the list.
 func (o *orderState) stmtList(l ir.Nodes) {
 	s := l
@@ -488,7 +453,7 @@
 	mark := order.markTemp()
 	order.edge()
 	order.stmtList(*n)
-	order.cleanTemp(mark)
+	order.popTemp(mark)
 	*n = order.out
 }
 
@@ -521,7 +486,7 @@
 	order.free = free
 	mark := order.markTemp()
 	order.stmt(n)
-	order.cleanTemp(mark)
+	order.popTemp(mark)
 	return ir.NewBlockStmt(src.NoXPos, order.out)
 }
 
@@ -620,8 +585,6 @@
 }
 
 // stmt orders the statement n, appending to o.out.
-// Temporaries created during the statement are cleaned
-// up using VARKILL instructions as possible.
 func (o *orderState) stmt(n ir.Node) {
 	if n == nil {
 		return
@@ -634,7 +597,7 @@
 	default:
 		base.Fatalf("order.stmt %v", n.Op())
 
-	case ir.OVARKILL, ir.OVARLIVE, ir.OINLMARK:
+	case ir.OINLMARK:
 		o.out = append(o.out, n)
 
 	case ir.OAS:
@@ -643,7 +606,7 @@
 		n.X = o.expr(n.X, nil)
 		n.Y = o.expr(n.Y, n.X)
 		o.mapAssign(n)
-		o.cleanTemp(t)
+		o.popTemp(t)
 
 	case ir.OASOP:
 		n := n.(*ir.AssignOpStmt)
@@ -668,12 +631,12 @@
 			r := o.expr(typecheck.Expr(ir.NewBinaryExpr(n.Pos(), n.AsOp, l2, n.Y)), nil)
 			as := typecheck.Stmt(ir.NewAssignStmt(n.Pos(), l1, r))
 			o.mapAssign(as)
-			o.cleanTemp(t)
+			o.popTemp(t)
 			return
 		}
 
 		o.mapAssign(n)
-		o.cleanTemp(t)
+		o.popTemp(t)
 
 	case ir.OAS2:
 		n := n.(*ir.AssignListStmt)
@@ -681,7 +644,7 @@
 		o.exprList(n.Lhs)
 		o.exprList(n.Rhs)
 		o.out = append(o.out, n)
-		o.cleanTemp(t)
+		o.popTemp(t)
 
 	// Special: avoid copy of func call n.Right
 	case ir.OAS2FUNC:
@@ -702,7 +665,7 @@
 			o.call(call)
 			o.as2func(n)
 		}
-		o.cleanTemp(t)
+		o.popTemp(t)
 
 	// Special: use temporary variables to hold result,
 	// so that runtime can take address of temporary.
@@ -733,13 +696,13 @@
 			r.Index = o.expr(r.Index, nil)
 			// See similar conversion for OINDEXMAP below.
 			_ = mapKeyReplaceStrConv(r.Index)
-			r.Index = o.mapKeyTemp(r.X.Type(), r.Index)
+			r.Index = o.mapKeyTemp(r.Pos(), r.X.Type(), r.Index)
 		default:
 			base.Fatalf("order.stmt: %v", r.Op())
 		}
 
 		o.as2ok(n)
-		o.cleanTemp(t)
+		o.popTemp(t)
 
 	// Special: does not save n onto out.
 	case ir.OBLOCK:
@@ -764,7 +727,7 @@
 		t := o.markTemp()
 		o.call(n)
 		o.out = append(o.out, n)
-		o.cleanTemp(t)
+		o.popTemp(t)
 
 	case ir.OINLCALL:
 		n := n.(*ir.InlinedCallExpr)
@@ -782,7 +745,7 @@
 		t := o.markTemp()
 		n.X = o.expr(n.X, nil)
 		o.out = append(o.out, n)
-		o.cleanTemp(t)
+		o.popTemp(t)
 
 	case ir.OCOPY:
 		n := n.(*ir.BinaryExpr)
@@ -790,14 +753,14 @@
 		n.X = o.expr(n.X, nil)
 		n.Y = o.expr(n.Y, nil)
 		o.out = append(o.out, n)
-		o.cleanTemp(t)
+		o.popTemp(t)
 
 	case ir.OPRINT, ir.OPRINTN, ir.ORECOVERFP:
 		n := n.(*ir.CallExpr)
 		t := o.markTemp()
 		o.call(n)
 		o.out = append(o.out, n)
-		o.cleanTemp(t)
+		o.popTemp(t)
 
 	// Special: order arguments to inner call but not call itself.
 	case ir.ODEFER, ir.OGO:
@@ -806,16 +769,16 @@
 		o.init(n.Call)
 		o.call(n.Call)
 		o.out = append(o.out, n)
-		o.cleanTemp(t)
+		o.popTemp(t)
 
 	case ir.ODELETE:
 		n := n.(*ir.CallExpr)
 		t := o.markTemp()
 		n.Args[0] = o.expr(n.Args[0], nil)
 		n.Args[1] = o.expr(n.Args[1], nil)
-		n.Args[1] = o.mapKeyTemp(n.Args[0].Type(), n.Args[1])
+		n.Args[1] = o.mapKeyTemp(n.Pos(), n.Args[0].Type(), n.Args[1])
 		o.out = append(o.out, n)
-		o.cleanTemp(t)
+		o.popTemp(t)
 
 	// Clean temporaries from condition evaluation at
 	// beginning of loop body and after for statement.
@@ -823,11 +786,10 @@
 		n := n.(*ir.ForStmt)
 		t := o.markTemp()
 		n.Cond = o.exprInPlace(n.Cond)
-		n.Body.Prepend(o.cleanTempNoPop(t)...)
 		orderBlock(&n.Body, o.free)
 		n.Post = orderStmtInPlace(n.Post, o.free)
 		o.out = append(o.out, n)
-		o.cleanTemp(t)
+		o.popTemp(t)
 
 	// Clean temporaries from condition at
 	// beginning of both branches.
@@ -835,8 +797,6 @@
 		n := n.(*ir.IfStmt)
 		t := o.markTemp()
 		n.Cond = o.exprInPlace(n.Cond)
-		n.Body.Prepend(o.cleanTempNoPop(t)...)
-		n.Else.Prepend(o.cleanTempNoPop(t)...)
 		o.popTemp(t)
 		orderBlock(&n.Body, o.free)
 		orderBlock(&n.Else, o.free)
@@ -916,7 +876,7 @@
 			orderBlock(&n.Body, o.free)
 		}
 		o.out = append(o.out, n)
-		o.cleanTemp(t)
+		o.popTemp(t)
 
 	case ir.ORETURN:
 		n := n.(*ir.ReturnStmt)
@@ -993,7 +953,7 @@
 				do(0, recv.X.Type().Elem())
 				do(1, types.Types[types.TBOOL])
 				if len(init) != 0 {
-					ir.DumpList("ninit", r.Init())
+					ir.DumpList("ninit", init)
 					base.Fatalf("ninit on select recv")
 				}
 				orderBlock(ncas.PtrInit(), o.free)
@@ -1023,7 +983,6 @@
 		// (The temporary cleaning must follow that ninit work.)
 		for _, cas := range n.Cases {
 			orderBlock(&cas.Body, o.free)
-			cas.Body.Prepend(o.cleanTempNoPop(t)...)
 
 			// TODO(mdempsky): Is this actually necessary?
 			// walkSelect appears to walk Ninit.
@@ -1047,7 +1006,7 @@
 			n.Value = o.addrTemp(n.Value)
 		}
 		o.out = append(o.out, n)
-		o.cleanTemp(t)
+		o.popTemp(t)
 
 	// TODO(rsc): Clean temporaries more aggressively.
 	// Note that because walkSwitch will rewrite some of the
@@ -1071,7 +1030,7 @@
 		}
 
 		o.out = append(o.out, n)
-		o.cleanTemp(t)
+		o.popTemp(t)
 	}
 
 	base.Pos = lno
@@ -1193,7 +1152,7 @@
 		}
 
 		// key must be addressable
-		n.Index = o.mapKeyTemp(n.X.Type(), n.Index)
+		n.Index = o.mapKeyTemp(n.Pos(), n.X.Type(), n.Index)
 		if needCopy {
 			return o.copyExpr(n)
 		}
@@ -1259,7 +1218,7 @@
 		o.edge()
 		rhs := o.expr(n.Y, nil)
 		o.out = append(o.out, typecheck.Stmt(ir.NewAssignStmt(base.Pos, r, rhs)))
-		o.cleanTemp(t)
+		o.popTemp(t)
 		gen := o.out
 		o.out = saveout
 
@@ -1456,8 +1415,12 @@
 
 		// Emit eval+insert of dynamic entries, one at a time.
 		for _, r := range dynamics {
-			as := ir.NewAssignStmt(base.Pos, ir.NewIndexExpr(base.Pos, m, r.Key), r.Value)
-			typecheck.Stmt(as) // Note: this converts the OINDEX to an OINDEXMAP
+			lhs := typecheck.AssignExpr(ir.NewIndexExpr(base.Pos, m, r.Key)).(*ir.IndexExpr)
+			base.AssertfAt(lhs.Op() == ir.OINDEXMAP, lhs.Pos(), "want OINDEXMAP, have %+v", lhs)
+			lhs.RType = n.RType
+
+			as := ir.NewAssignStmt(base.Pos, lhs, r.Value)
+			typecheck.Stmt(as)
 			o.stmt(as)
 		}
 
diff --git a/src/cmd/compile/internal/walk/range.go b/src/cmd/compile/internal/walk/range.go
index 6c30fa2..64af26b 100644
--- a/src/cmd/compile/internal/walk/range.go
+++ b/src/cmd/compile/internal/walk/range.go
@@ -38,11 +38,7 @@
 // the returned node.
 func walkRange(nrange *ir.RangeStmt) ir.Node {
 	if isMapClear(nrange) {
-		m := nrange.X
-		lno := ir.SetPos(m)
-		n := mapClear(m)
-		base.Pos = lno
-		return n
+		return mapClear(nrange)
 	}
 
 	nfor := ir.NewForStmt(nrange.Pos(), nil, nil, nil, nil)
@@ -57,7 +53,7 @@
 	//	a, v1, v2: not hidden aggregate, val 1, 2
 
 	a := nrange.X
-	t := typecheck.RangeExprType(a.Type())
+	t := a.Type()
 	lno := ir.SetPos(a)
 
 	v1, v2 := nrange.Key, nrange.Value
@@ -74,20 +70,27 @@
 		base.Fatalf("walkRange: v2 != nil while v1 == nil")
 	}
 
-	var ifGuard *ir.IfStmt
-
 	var body []ir.Node
 	var init []ir.Node
 	switch t.Kind() {
 	default:
 		base.Fatalf("walkRange")
 
-	case types.TARRAY, types.TSLICE:
+	case types.TARRAY, types.TSLICE, types.TPTR: // TPTR is pointer-to-array
 		if nn := arrayClear(nrange, v1, v2, a); nn != nil {
 			base.Pos = lno
 			return nn
 		}
 
+		// Element type of the iteration
+		var elem *types.Type
+		switch t.Kind() {
+		case types.TSLICE, types.TARRAY:
+			elem = t.Elem()
+		case types.TPTR:
+			elem = t.Elem().Elem()
+		}
+
 		// order.stmt arranged for a copy of the array/slice variable if needed.
 		ha := a
 
@@ -107,55 +110,111 @@
 
 		// for v1 := range ha { body }
 		if v2 == nil {
-			body = []ir.Node{ir.NewAssignStmt(base.Pos, v1, hv1)}
+			body = []ir.Node{rangeAssign(nrange, hv1)}
 			break
 		}
 
 		// for v1, v2 := range ha { body }
-		if cheapComputableIndex(t.Elem().Size()) {
+		if cheapComputableIndex(elem.Size()) {
 			// v1, v2 = hv1, ha[hv1]
 			tmp := ir.NewIndexExpr(base.Pos, ha, hv1)
 			tmp.SetBounded(true)
-			// Use OAS2 to correctly handle assignments
-			// of the form "v1, a[v1] := range".
-			a := ir.NewAssignListStmt(base.Pos, ir.OAS2, []ir.Node{v1, v2}, []ir.Node{hv1, tmp})
-			body = []ir.Node{a}
+			body = []ir.Node{rangeAssign2(nrange, hv1, tmp)}
 			break
 		}
 
-		// TODO(austin): OFORUNTIL is a strange beast, but is
-		// necessary for expressing the control flow we need
-		// while also making "break" and "continue" work. It
-		// would be nice to just lower ORANGE during SSA, but
-		// racewalk needs to see many of the operations
-		// involved in ORANGE's implementation. If racewalk
-		// moves into SSA, consider moving ORANGE into SSA and
-		// eliminating OFORUNTIL.
+		// Slice to iterate over
+		var hs ir.Node
+		if t.IsSlice() {
+			hs = ha
+		} else {
+			var arr ir.Node
+			if t.IsPtr() {
+				arr = ha
+			} else {
+				arr = typecheck.NodAddr(ha)
+				arr.SetType(t.PtrTo())
+				arr.SetTypecheck(1)
+			}
+			hs = ir.NewSliceExpr(base.Pos, ir.OSLICEARR, arr, nil, nil, nil)
+			// old typechecker doesn't know OSLICEARR, so we set types explicitly
+			hs.SetType(types.NewSlice(elem))
+			hs.SetTypecheck(1)
+		}
 
-		// TODO(austin): OFORUNTIL inhibits bounds-check
-		// elimination on the index variable (see #20711).
-		// Enhance the prove pass to understand this.
-		ifGuard = ir.NewIfStmt(base.Pos, nil, nil, nil)
-		ifGuard.Cond = ir.NewBinaryExpr(base.Pos, ir.OLT, hv1, hn)
-		nfor.SetOp(ir.OFORUNTIL)
+		// We use a "pointer" to keep track of where we are in the backing array
+		// of the slice hs. This pointer starts at hs.ptr and gets incremented
+		// by the element size each time through the loop.
+		//
+		// It's tricky, though, as on the last iteration this pointer gets
+		// incremented to point past the end of the backing array. We can't
+		// let the garbage collector see that final out-of-bounds pointer.
+		//
+		// To avoid this, we keep the "pointer" alternately in 2 variables, one
+		// pointer typed and one uintptr typed. Most of the time it lives in the
+		// regular pointer variable, but when it might be out of bounds (after it
+		// has been incremented, but before the loop condition has been checked)
+		// it lives briefly in the uintptr variable.
+		//
+		// hp contains the pointer version (of type *T, where T is the element type).
+		// It is guaranteed to always be in range, keeps the backing store alive,
+		// and is updated on stack copies. If a GC occurs when this function is
+		// suspended at any safepoint, this variable ensures correct operation.
+		//
+		// hu contains the equivalent uintptr version. It may point past the
+		// end, but doesn't keep the backing store alive and doesn't get updated
+		// on a stack copy. If a GC occurs while this function is on the top of
+		// the stack, then the last frame is scanned conservatively and hu will
+		// act as a reference to the backing array to ensure it is not collected.
+		//
+		// The "pointer" we're moving across the backing array lives in one
+		// or the other of hp and hu as the loop proceeds.
+		//
+		// hp is live during most of the body of the loop. But it isn't live
+		// at the very top of the loop, when we haven't checked i<n yet, and
+		// it could point off the end of the backing store.
+		// hu is live only at the very top and very bottom of the loop.
+		// In particular, only when it cannot possibly be live across a call.
+		//
+		// So we do
+		//   hu = uintptr(unsafe.Pointer(hs.ptr))
+		//   for i := 0; i < hs.len; i++ {
+		//     hp = (*T)(unsafe.Pointer(hu))
+		//     v1, v2 = i, *hp
+		//     ... body of loop ...
+		//     hu = uintptr(unsafe.Pointer(hp)) + elemsize
+		//   }
+		//
+		// Between the assignments to hu and the assignment back to hp, there
+		// must not be any calls.
 
-		hp := typecheck.Temp(types.NewPtr(t.Elem()))
-		tmp := ir.NewIndexExpr(base.Pos, ha, ir.NewInt(0))
-		tmp.SetBounded(true)
-		init = append(init, ir.NewAssignStmt(base.Pos, hp, typecheck.NodAddr(tmp)))
+		// Pointer to current iteration position. Start on entry to the loop
+		// with the pointer in hu.
+		ptr := ir.NewUnaryExpr(base.Pos, ir.OSPTR, hs)
+		huVal := ir.NewConvExpr(base.Pos, ir.OCONVNOP, types.Types[types.TUNSAFEPTR], ptr)
+		huVal = ir.NewConvExpr(base.Pos, ir.OCONVNOP, types.Types[types.TUINTPTR], huVal)
+		hu := typecheck.Temp(types.Types[types.TUINTPTR])
+		init = append(init, ir.NewAssignStmt(base.Pos, hu, huVal))
 
-		// Use OAS2 to correctly handle assignments
-		// of the form "v1, a[v1] := range".
-		a := ir.NewAssignListStmt(base.Pos, ir.OAS2, []ir.Node{v1, v2}, []ir.Node{hv1, ir.NewStarExpr(base.Pos, hp)})
+		// Convert hu to hp at the top of the loop (afer the condition has been checked).
+		hpVal := ir.NewConvExpr(base.Pos, ir.OCONVNOP, types.Types[types.TUNSAFEPTR], hu)
+		hpVal.SetCheckPtr(true) // disable checkptr on this conversion
+		hpVal = ir.NewConvExpr(base.Pos, ir.OCONVNOP, elem.PtrTo(), hpVal)
+		hp := typecheck.Temp(elem.PtrTo())
+		body = append(body, ir.NewAssignStmt(base.Pos, hp, hpVal))
+
+		// Assign variables on the LHS of the range statement. Use *hp to get the element.
+		e := ir.NewStarExpr(base.Pos, hp)
+		e.SetBounded(true)
+		a := rangeAssign2(nrange, hv1, e)
 		body = append(body, a)
 
-		// Advance pointer as part of the late increment.
-		//
-		// This runs *after* the condition check, so we know
-		// advancing the pointer is safe and won't go past the
-		// end of the allocation.
-		as := ir.NewAssignStmt(base.Pos, hp, addptr(hp, t.Elem().Size()))
-		nfor.Late = []ir.Node{typecheck.Stmt(as)}
+		// Advance pointer for next iteration of the loop.
+		// This reads from hp and writes to hu.
+		huVal = ir.NewConvExpr(base.Pos, ir.OCONVNOP, types.Types[types.TUNSAFEPTR], hp)
+		huVal = ir.NewConvExpr(base.Pos, ir.OCONVNOP, types.Types[types.TUINTPTR], huVal)
+		as := ir.NewAssignStmt(base.Pos, hu, ir.NewBinaryExpr(base.Pos, ir.OADD, huVal, ir.NewInt(elem.Size())))
+		nfor.Post = ir.NewBlockStmt(base.Pos, []ir.Node{nfor.Post, as})
 
 	case types.TMAP:
 		// order.stmt allocated the iterator for us.
@@ -172,7 +231,7 @@
 		fn := typecheck.LookupRuntime("mapiterinit")
 
 		fn = typecheck.SubstArgTypes(fn, t.Key(), t.Elem(), th)
-		init = append(init, mkcallstmt1(fn, reflectdata.TypePtr(t), ha, typecheck.NodAddr(hit)))
+		init = append(init, mkcallstmt1(fn, reflectdata.RangeMapRType(base.Pos, nrange), ha, typecheck.NodAddr(hit)))
 		nfor.Cond = ir.NewBinaryExpr(base.Pos, ir.ONE, ir.NewSelectorExpr(base.Pos, ir.ODOT, hit, keysym), typecheck.NodNil())
 
 		fn = typecheck.LookupRuntime("mapiternext")
@@ -183,11 +242,10 @@
 		if v1 == nil {
 			body = nil
 		} else if v2 == nil {
-			body = []ir.Node{ir.NewAssignStmt(base.Pos, v1, key)}
+			body = []ir.Node{rangeAssign(nrange, key)}
 		} else {
 			elem := ir.NewStarExpr(base.Pos, ir.NewSelectorExpr(base.Pos, ir.ODOT, hit, elemsym))
-			a := ir.NewAssignListStmt(base.Pos, ir.OAS2, []ir.Node{v1, v2}, []ir.Node{key, elem})
-			body = []ir.Node{a}
+			body = []ir.Node{rangeAssign2(nrange, key, elem)}
 		}
 
 	case types.TCHAN:
@@ -210,7 +268,7 @@
 		if v1 == nil {
 			body = nil
 		} else {
-			body = []ir.Node{ir.NewAssignStmt(base.Pos, v1, hv1)}
+			body = []ir.Node{rangeAssign(nrange, hv1)}
 		}
 		// Zero hv1. This prevents hv1 from being the sole, inaccessible
 		// reference to an otherwise GC-able value during the next channel receive.
@@ -275,23 +333,17 @@
 		if v1 != nil {
 			if v2 != nil {
 				// v1, v2 = hv1t, hv2
-				a := ir.NewAssignListStmt(base.Pos, ir.OAS2, []ir.Node{v1, v2}, []ir.Node{hv1t, hv2})
-				body = append(body, a)
+				body = append(body, rangeAssign2(nrange, hv1t, hv2))
 			} else {
 				// v1 = hv1t
-				body = append(body, ir.NewAssignStmt(base.Pos, v1, hv1t))
+				body = append(body, rangeAssign(nrange, hv1t))
 			}
 		}
 	}
 
 	typecheck.Stmts(init)
 
-	if ifGuard != nil {
-		ifGuard.PtrInit().Append(init...)
-		ifGuard = typecheck.Stmt(ifGuard).(*ir.IfStmt)
-	} else {
-		nfor.PtrInit().Append(init...)
-	}
+	nfor.PtrInit().Append(init...)
 
 	typecheck.Stmts(nfor.Cond.Init())
 
@@ -303,10 +355,6 @@
 	nfor.Body.Append(nrange.Body...)
 
 	var n ir.Node = nfor
-	if ifGuard != nil {
-		ifGuard.Body = []ir.Node{n}
-		n = ifGuard
-	}
 
 	n = walkStmt(n)
 
@@ -314,6 +362,36 @@
 	return n
 }
 
+// rangeAssign returns "n.Key = key".
+func rangeAssign(n *ir.RangeStmt, key ir.Node) ir.Node {
+	key = rangeConvert(n, n.Key.Type(), key, n.KeyTypeWord, n.KeySrcRType)
+	return ir.NewAssignStmt(n.Pos(), n.Key, key)
+}
+
+// rangeAssign2 returns "n.Key, n.Value = key, value".
+func rangeAssign2(n *ir.RangeStmt, key, value ir.Node) ir.Node {
+	// Use OAS2 to correctly handle assignments
+	// of the form "v1, a[v1] = range".
+	key = rangeConvert(n, n.Key.Type(), key, n.KeyTypeWord, n.KeySrcRType)
+	value = rangeConvert(n, n.Value.Type(), value, n.ValueTypeWord, n.ValueSrcRType)
+	return ir.NewAssignListStmt(n.Pos(), ir.OAS2, []ir.Node{n.Key, n.Value}, []ir.Node{key, value})
+}
+
+// rangeConvert returns src, converted to dst if necessary. If a
+// conversion is necessary, then typeWord and srcRType are copied to
+// their respective ConvExpr fields.
+func rangeConvert(nrange *ir.RangeStmt, dst *types.Type, src, typeWord, srcRType ir.Node) ir.Node {
+	src = typecheck.Expr(src)
+	if dst.Kind() == types.TBLANK || types.Identical(dst, src.Type()) {
+		return src
+	}
+
+	n := ir.NewConvExpr(nrange.Pos(), ir.OCONV, dst, src)
+	n.TypeWord = typeWord
+	n.SrcRType = srcRType
+	return typecheck.Expr(n)
+}
+
 // isMapClear checks if n is of the form:
 //
 //	for k := range m {
@@ -360,13 +438,17 @@
 }
 
 // mapClear constructs a call to runtime.mapclear for the map m.
-func mapClear(m ir.Node) ir.Node {
+func mapClear(nrange *ir.RangeStmt) ir.Node {
+	m := nrange.X
+	origPos := ir.SetPos(m)
+	defer func() { base.Pos = origPos }()
+
 	t := m.Type()
 
 	// instantiate mapclear(typ *type, hmap map[any]any)
 	fn := typecheck.LookupRuntime("mapclear")
 	fn = typecheck.SubstArgTypes(fn, t.Key(), t.Elem())
-	n := mkcallstmt1(fn, reflectdata.TypePtr(t), m)
+	n := mkcallstmt1(fn, reflectdata.RangeMapRType(base.Pos, nrange), m)
 	return walkStmt(typecheck.Stmt(n))
 }
 
diff --git a/src/cmd/compile/internal/walk/select.go b/src/cmd/compile/internal/walk/select.go
index 5cea66f..570e9b5 100644
--- a/src/cmd/compile/internal/walk/select.go
+++ b/src/cmd/compile/internal/walk/select.go
@@ -230,12 +230,7 @@
 	init = append(init, fnInit...)
 	init = append(init, typecheck.Stmt(r))
 
-	// selv and order are no longer alive after selectgo.
-	init = append(init, ir.NewUnaryExpr(base.Pos, ir.OVARKILL, selv))
-	init = append(init, ir.NewUnaryExpr(base.Pos, ir.OVARKILL, order))
-	if base.Flag.Race {
-		init = append(init, ir.NewUnaryExpr(base.Pos, ir.OVARKILL, pcs))
-	}
+	// selv, order, and pcs (if race) are no longer alive after selectgo.
 
 	// dispatch cases
 	dispatch := func(cond ir.Node, cas *ir.CommClause) {
diff --git a/src/cmd/compile/internal/walk/stmt.go b/src/cmd/compile/internal/walk/stmt.go
index 8a42dbf..ceee1b1 100644
--- a/src/cmd/compile/internal/walk/stmt.go
+++ b/src/cmd/compile/internal/walk/stmt.go
@@ -89,10 +89,7 @@
 		ir.ODCL,
 		ir.ODCLCONST,
 		ir.ODCLTYPE,
-		ir.OCHECKNIL,
-		ir.OVARDEF,
-		ir.OVARKILL,
-		ir.OVARLIVE:
+		ir.OCHECKNIL:
 		return n
 
 	case ir.OBLOCK:
@@ -124,7 +121,7 @@
 		n := n.(*ir.GoDeferStmt)
 		return walkGoDefer(n)
 
-	case ir.OFOR, ir.OFORUNTIL:
+	case ir.OFOR:
 		n := n.(*ir.ForStmt)
 		return walkFor(n)
 
@@ -178,7 +175,7 @@
 	}
 }
 
-// walkFor walks an OFOR or OFORUNTIL node.
+// walkFor walks an OFOR node.
 func walkFor(n *ir.ForStmt) ir.Node {
 	if n.Cond != nil {
 		init := ir.TakeInit(n.Cond)
@@ -188,9 +185,6 @@
 	}
 
 	n.Post = walkStmt(n.Post)
-	if n.Op() == ir.OFORUNTIL {
-		walkStmtList(n.Late)
-	}
 	walkStmtList(n.Body)
 	return n
 }
diff --git a/src/cmd/compile/internal/walk/switch.go b/src/cmd/compile/internal/walk/switch.go
index 6cac8f2..8ca8fa8 100644
--- a/src/cmd/compile/internal/walk/switch.go
+++ b/src/cmd/compile/internal/walk/switch.go
@@ -85,8 +85,12 @@
 			defaultGoto = jmp
 		}
 
-		for _, n1 := range ncase.List {
-			s.Add(ncase.Pos(), n1, jmp)
+		for i, n1 := range ncase.List {
+			var rtype ir.Node
+			if i < len(ncase.RTypes) {
+				rtype = ncase.RTypes[i]
+			}
+			s.Add(ncase.Pos(), n1, rtype, jmp)
 		}
 
 		// Process body.
@@ -124,11 +128,12 @@
 type exprClause struct {
 	pos    src.XPos
 	lo, hi ir.Node
+	rtype  ir.Node // *runtime._type for OEQ node
 	jmp    ir.Node
 }
 
-func (s *exprSwitch) Add(pos src.XPos, expr, jmp ir.Node) {
-	c := exprClause{pos: pos, lo: expr, hi: expr, jmp: jmp}
+func (s *exprSwitch) Add(pos src.XPos, expr, rtype, jmp ir.Node) {
+	c := exprClause{pos: pos, lo: expr, hi: expr, rtype: rtype, jmp: jmp}
 	if types.IsOrdered[s.exprname.Type().Kind()] && expr.Op() == ir.OLITERAL {
 		s.clauses = append(s.clauses, c)
 		return
@@ -185,10 +190,6 @@
 		}
 		runs = append(runs, cc[start:])
 
-		if len(runs) == 1 {
-			s.search(runs[0], &s.done)
-			return
-		}
 		// We have strings of more than one length. Generate an
 		// outer switch which switches on the length of the string
 		// and an inner switch in each case which resolves all the
@@ -227,13 +228,13 @@
 			// Search within this run of same-length strings.
 			pos := run[0].pos
 			s.done.Append(ir.NewLabelStmt(pos, label))
-			s.search(run, &s.done)
+			stringSearch(s.exprname, run, &s.done)
 			s.done.Append(ir.NewBranchStmt(pos, ir.OGOTO, endLabel))
 
 			// Add length case to outer switch.
 			cas := ir.NewBasicLit(pos, constant.MakeInt64(runLen(run)))
 			jmp := ir.NewBranchStmt(pos, ir.OGOTO, label)
-			outer.Add(pos, cas, jmp)
+			outer.Add(pos, cas, nil, jmp)
 		}
 		s.done.Append(ir.NewLabelStmt(s.pos, outerLabel))
 		outer.Emit(&s.done)
@@ -289,7 +290,7 @@
 	const minCases = 8   // have at least minCases cases in the switch
 	const minDensity = 4 // use at least 1 out of every minDensity entries
 
-	if !go119UseJumpTables || base.Flag.N != 0 || !ssagen.Arch.LinkArch.CanJumpTable {
+	if !go119UseJumpTables || base.Flag.N != 0 || !ssagen.Arch.LinkArch.CanJumpTable || base.Ctxt.Retpoline {
 		return false
 	}
 	if len(cc) < minCases {
@@ -342,7 +343,9 @@
 		}
 	}
 
-	return ir.NewBinaryExpr(c.pos, ir.OEQ, exprname, c.lo)
+	n := ir.NewBinaryExpr(c.pos, ir.OEQ, exprname, c.lo)
+	n.RType = c.rtype
+	return n
 }
 
 func allCaseExprsAreSideEffectFree(sw *ir.SwitchStmt) bool {
@@ -365,19 +368,10 @@
 
 // endsInFallthrough reports whether stmts ends with a "fallthrough" statement.
 func endsInFallthrough(stmts []ir.Node) (bool, src.XPos) {
-	// Search backwards for the index of the fallthrough
-	// statement. Do not assume it'll be in the last
-	// position, since in some cases (e.g. when the statement
-	// list contains autotmp_ variables), one or more OVARKILL
-	// nodes will be at the end of the list.
-
-	i := len(stmts) - 1
-	for i >= 0 && stmts[i].Op() == ir.OVARKILL {
-		i--
-	}
-	if i < 0 {
+	if len(stmts) == 0 {
 		return false, src.NoXPos
 	}
+	i := len(stmts) - 1
 	return stmts[i].Op() == ir.OFALL, stmts[i].Pos()
 }
 
@@ -680,3 +674,89 @@
 
 	do(0, n, out)
 }
+
+func stringSearch(expr ir.Node, cc []exprClause, out *ir.Nodes) {
+	if len(cc) < 4 {
+		// Short list, just do brute force equality checks.
+		for _, c := range cc {
+			nif := ir.NewIfStmt(base.Pos.WithNotStmt(), typecheck.DefaultLit(typecheck.Expr(c.test(expr)), nil), []ir.Node{c.jmp}, nil)
+			out.Append(nif)
+			out = &nif.Else
+		}
+		return
+	}
+
+	// The strategy here is to find a simple test to divide the set of possible strings
+	// that might match expr approximately in half.
+	// The test we're going to use is to do an ordered comparison of a single byte
+	// of expr to a constant. We will pick the index of that byte and the value we're
+	// comparing against to make the split as even as possible.
+	//   if expr[3] <= 'd' { ... search strings with expr[3] at 'd' or lower  ... }
+	//   else              { ... search strings with expr[3] at 'e' or higher ... }
+	//
+	// To add complication, we will do the ordered comparison in the signed domain.
+	// The reason for this is to prevent CSE from merging the load used for the
+	// ordered comparison with the load used for the later equality check.
+	//   if expr[3] <= 'd' { ... if expr[0] == 'f' && expr[1] == 'o' && expr[2] == 'o' && expr[3] == 'd' { ... } }
+	// If we did both expr[3] loads in the unsigned domain, they would be CSEd, and that
+	// would in turn defeat the combining of expr[0]...expr[3] into a single 4-byte load.
+	// See issue 48222.
+	// By using signed loads for the ordered comparison and unsigned loads for the
+	// equality comparison, they don't get CSEd and the equality comparisons will be
+	// done using wider loads.
+
+	n := len(ir.StringVal(cc[0].lo)) // Length of the constant strings.
+	bestScore := int64(0)            // measure of how good the split is.
+	bestIdx := 0                     // split using expr[bestIdx]
+	bestByte := int8(0)              // compare expr[bestIdx] against bestByte
+	for idx := 0; idx < n; idx++ {
+		for b := int8(-128); b < 127; b++ {
+			le := 0
+			for _, c := range cc {
+				s := ir.StringVal(c.lo)
+				if int8(s[idx]) <= b {
+					le++
+				}
+			}
+			score := int64(le) * int64(len(cc)-le)
+			if score > bestScore {
+				bestScore = score
+				bestIdx = idx
+				bestByte = b
+			}
+		}
+	}
+
+	// The split must be at least 1:n-1 because we have at least 2 distinct strings; they
+	// have to be different somewhere.
+	// TODO: what if the best split is still pretty bad?
+	if bestScore == 0 {
+		base.Fatalf("unable to split string set")
+	}
+
+	// Convert expr to a []int8
+	slice := ir.NewConvExpr(base.Pos, ir.OSTR2BYTESTMP, types.NewSlice(types.Types[types.TINT8]), expr)
+	slice.SetTypecheck(1) // legacy typechecker doesn't handle this op
+	// Load the byte we're splitting on.
+	load := ir.NewIndexExpr(base.Pos, slice, ir.NewInt(int64(bestIdx)))
+	// Compare with the value we're splitting on.
+	cmp := ir.Node(ir.NewBinaryExpr(base.Pos, ir.OLE, load, ir.NewInt(int64(bestByte))))
+	cmp = typecheck.DefaultLit(typecheck.Expr(cmp), nil)
+	nif := ir.NewIfStmt(base.Pos, cmp, nil, nil)
+
+	var le []exprClause
+	var gt []exprClause
+	for _, c := range cc {
+		s := ir.StringVal(c.lo)
+		if int8(s[bestIdx]) <= bestByte {
+			le = append(le, c)
+		} else {
+			gt = append(gt, c)
+		}
+	}
+	stringSearch(expr, le, &nif.Body)
+	stringSearch(expr, gt, &nif.Else)
+	out.Append(nif)
+
+	// TODO: if expr[bestIdx] has enough different possible values, use a jump table.
+}
diff --git a/src/cmd/compile/internal/walk/walk.go b/src/cmd/compile/internal/walk/walk.go
index 78cc2e6..f5a2f9b 100644
--- a/src/cmd/compile/internal/walk/walk.go
+++ b/src/cmd/compile/internal/walk/walk.go
@@ -312,7 +312,8 @@
 			return true
 
 		case ir.OINDEX, ir.OSLICE, ir.OSLICEARR, ir.OSLICE3, ir.OSLICE3ARR, ir.OSLICESTR,
-			ir.ODEREF, ir.ODOTPTR, ir.ODOTTYPE, ir.ODYNAMICDOTTYPE, ir.ODIV, ir.OMOD, ir.OSLICE2ARRPTR:
+			ir.ODEREF, ir.ODOTPTR, ir.ODOTTYPE, ir.ODYNAMICDOTTYPE, ir.ODIV, ir.OMOD,
+			ir.OSLICE2ARR, ir.OSLICE2ARRPTR:
 			// These ops might panic, make sure they are done
 			// before we start marshaling args for a call. See issue 16760.
 			return true
@@ -342,7 +343,7 @@
 			ir.OCAP, ir.OIMAG, ir.OLEN, ir.OREAL,
 			ir.OCONVNOP, ir.ODOT,
 			ir.OCFUNC, ir.OIDATA, ir.OITAB, ir.OSPTR,
-			ir.OBYTES2STRTMP, ir.OGETG, ir.OGETCALLERPC, ir.OGETCALLERSP, ir.OSLICEHEADER:
+			ir.OBYTES2STRTMP, ir.OGETG, ir.OGETCALLERPC, ir.OGETCALLERSP, ir.OSLICEHEADER, ir.OSTRINGHEADER:
 			// ok: operations that don't require function calls.
 			// Expand as needed.
 		}
diff --git a/src/cmd/compile/internal/wasm/ssa.go b/src/cmd/compile/internal/wasm/ssa.go
index 765051c..0578c20 100644
--- a/src/cmd/compile/internal/wasm/ssa.go
+++ b/src/cmd/compile/internal/wasm/ssa.go
@@ -17,6 +17,119 @@
 	"internal/buildcfg"
 )
 
+/*
+
+   Wasm implementation
+   -------------------
+
+   Wasm is a strange Go port because the machine isn't
+   a register-based machine, threads are different, code paths
+   are different, etc. We outline those differences here.
+
+   See the design doc for some additional info on this topic.
+   https://docs.google.com/document/d/131vjr4DH6JFnb-blm_uRdaC0_Nv3OUwjEY5qVCxCup4/edit#heading=h.mjo1bish3xni
+
+   PCs:
+
+   Wasm doesn't have PCs in the normal sense that you can jump
+   to or call to. Instead, we simulate these PCs using our own construct.
+
+   A PC in the Wasm implementation is the combination of a function
+   ID and a block ID within that function. The function ID is an index
+   into a function table which transfers control to the start of the
+   function in question, and the block ID is a sequential integer
+   indicating where in the function we are.
+
+   Every function starts with a branch table which transfers control
+   to the place in the function indicated by the block ID. The block
+   ID is provided to the function as the sole Wasm argument.
+
+   Block IDs do not encode every possible PC. They only encode places
+   in the function where it might be suspended. Typically these places
+   are call sites.
+
+   Sometimes we encode the function ID and block ID separately. When
+   recorded together as a single integer, we use the value F<<16+B.
+
+   Threads:
+
+   Wasm doesn't (yet) have threads. We have to simulate threads by
+   keeping goroutine stacks in linear memory and unwinding
+   the Wasm stack each time we want to switch goroutines.
+
+   To support unwinding a stack, each function call returns on the Wasm
+   stack a boolean that tells the function whether it should return
+   immediately or not. When returning immediately, a return address
+   is left on the top of the Go stack indicating where the goroutine
+   should be resumed.
+
+   Stack pointer:
+
+   There is a single global stack pointer which records the stack pointer
+   used by the currently active goroutine. This is just an address in
+   linear memory where the Go runtime is maintaining the stack for that
+   goroutine.
+
+   Functions cache the global stack pointer in a local variable for
+   faster access, but any changes must be spilled to the global variable
+   before any call and restored from the global variable after any call.
+
+   Calling convention:
+
+   All Go arguments and return values are passed on the Go stack, not
+   the wasm stack. In addition, return addresses are pushed on the
+   Go stack at every call point. Return addresses are not used during
+   normal execution, they are used only when resuming goroutines.
+   (So they are not really a "return address", they are a "resume address".)
+
+   All Go functions have the Wasm type (i32)->i32. The argument
+   is the block ID and the return value is the exit immediately flag.
+
+   Callsite:
+    - write arguments to the Go stack (starting at SP+0)
+    - push return address to Go stack (8 bytes)
+    - write local SP to global SP
+    - push 0 (type i32) to Wasm stack
+    - issue Call
+    - restore local SP from global SP
+    - pop int32 from top of Wasm stack. If nonzero, exit function immediately.
+    - use results from Go stack (starting at SP+sizeof(args))
+       - note that the callee will have popped the return address
+
+   Prologue:
+    - initialize local SP from global SP
+    - jump to the location indicated by the block ID argument
+      (which appears in local variable 0)
+    - at block 0
+      - check for Go stack overflow, call morestack if needed
+      - subtract frame size from SP
+      - note that arguments now start at SP+framesize+8
+
+   Normal epilogue:
+    - pop frame from Go stack
+    - pop return address from Go stack
+    - push 0 (type i32) on the Wasm stack
+    - return
+   Exit immediately epilogue:
+    - push 1 (type i32) on the Wasm stack
+    - return
+    - note that the return address and stack frame are left on the Go stack
+
+   The main loop that executes goroutines is wasm_pc_f_loop, in
+   runtime/rt0_js_wasm.s. It grabs the saved return address from
+   the top of the Go stack (actually SP-8?), splits it up into F
+   and B parts, then calls F with its Wasm argument set to B.
+
+   Note that when resuming a goroutine, only the most recent function
+   invocation of that goroutine appears on the Wasm stack. When that
+   Wasm function returns normally, the next most recent frame will
+   then be started up by wasm_pc_f_loop.
+
+   Global 0 is SP (stack pointer)
+   Global 1 is CTXT (closure pointer)
+   Global 2 is GP (goroutine pointer)
+*/
+
 func Init(arch *ssagen.ArchInfo) {
 	arch.LinkArch = &wasm.Linkwasm
 	arch.REGSP = wasm.REG_SP
@@ -149,14 +262,13 @@
 		getValue32(s, v.Args[0])
 		getValue32(s, v.Args[1])
 		i32Const(s, int32(v.AuxInt))
-		p := s.Prog(wasm.ACall)
-		p.To = obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_EXTERN, Sym: ir.Syms.WasmMove}
+		s.Prog(wasm.AMemoryCopy)
 
 	case ssa.OpWasmLoweredZero:
 		getValue32(s, v.Args[0])
+		i32Const(s, 0)
 		i32Const(s, int32(v.AuxInt))
-		p := s.Prog(wasm.ACall)
-		p.To = obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_EXTERN, Sym: ir.Syms.WasmZero}
+		s.Prog(wasm.AMemoryFill)
 
 	case ssa.OpWasmLoweredNilCheck:
 		getValue64(s, v.Args[0])
diff --git a/src/cmd/compile/internal/x86/ssa.go b/src/cmd/compile/internal/x86/ssa.go
index 378100b..40a483f 100644
--- a/src/cmd/compile/internal/x86/ssa.go
+++ b/src/cmd/compile/internal/x86/ssa.go
@@ -18,7 +18,7 @@
 	"cmd/internal/obj/x86"
 )
 
-// markMoves marks any MOVXconst ops that need to avoid clobbering flags.
+// ssaMarkMoves marks any MOVXconst ops that need to avoid clobbering flags.
 func ssaMarkMoves(s *ssagen.State, b *ssa.Block) {
 	flive := b.FlagsLiveAtEnd
 	for _, c := range b.ControlValues() {
@@ -158,6 +158,7 @@
 		ssa.Op386SHLL,
 		ssa.Op386SHRL, ssa.Op386SHRW, ssa.Op386SHRB,
 		ssa.Op386SARL, ssa.Op386SARW, ssa.Op386SARB,
+		ssa.Op386ROLL, ssa.Op386ROLW, ssa.Op386ROLB,
 		ssa.Op386ADDSS, ssa.Op386ADDSD, ssa.Op386SUBSS, ssa.Op386SUBSD,
 		ssa.Op386MULSS, ssa.Op386MULSD, ssa.Op386DIVSS, ssa.Op386DIVSD,
 		ssa.Op386PXOR,
diff --git a/src/cmd/covdata/argsmerge.go b/src/cmd/covdata/argsmerge.go
new file mode 100644
index 0000000..8815a4a
--- /dev/null
+++ b/src/cmd/covdata/argsmerge.go
@@ -0,0 +1,64 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "fmt"
+
+type argvalues struct {
+	osargs []string
+	goos   string
+	goarch string
+}
+
+type argstate struct {
+	state       argvalues
+	initialized bool
+}
+
+func ssleq(s1 []string, s2 []string) bool {
+	if len(s1) != len(s2) {
+		return false
+	}
+	for i := range s1 {
+		if s1[i] != s2[i] {
+			return false
+		}
+	}
+	return true
+}
+
+func (a *argstate) Merge(state argvalues) {
+	if !a.initialized {
+		a.state = state
+		a.initialized = true
+		return
+	}
+	if !ssleq(a.state.osargs, state.osargs) {
+		a.state.osargs = nil
+	}
+	if state.goos != a.state.goos {
+		a.state.goos = ""
+	}
+	if state.goarch != a.state.goarch {
+		a.state.goarch = ""
+	}
+}
+
+func (a *argstate) ArgsSummary() map[string]string {
+	m := make(map[string]string)
+	if len(a.state.osargs) != 0 {
+		m["argc"] = fmt.Sprintf("%d", len(a.state.osargs))
+		for k, a := range a.state.osargs {
+			m[fmt.Sprintf("argv%d", k)] = a
+		}
+	}
+	if a.state.goos != "" {
+		m["GOOS"] = a.state.goos
+	}
+	if a.state.goarch != "" {
+		m["GOARCH"] = a.state.goarch
+	}
+	return m
+}
diff --git a/src/cmd/covdata/covdata.go b/src/cmd/covdata/covdata.go
new file mode 100644
index 0000000..95bc30d
--- /dev/null
+++ b/src/cmd/covdata/covdata.go
@@ -0,0 +1,224 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"cmd/internal/cov"
+	"cmd/internal/pkgpattern"
+	"flag"
+	"fmt"
+	"os"
+	"runtime"
+	"runtime/pprof"
+	"strings"
+)
+
+var verbflag = flag.Int("v", 0, "Verbose trace output level")
+var hflag = flag.Bool("h", false, "Panic on fatal errors (for stack trace)")
+var hwflag = flag.Bool("hw", false, "Panic on warnings (for stack trace)")
+var indirsflag = flag.String("i", "", "Input dirs to examine (comma separated)")
+var pkgpatflag = flag.String("pkg", "", "Restrict output to package(s) matching specified package pattern.")
+var cpuprofileflag = flag.String("cpuprofile", "", "Write CPU profile to specified file")
+var memprofileflag = flag.String("memprofile", "", "Write memory profile to specified file")
+var memprofilerateflag = flag.Int("memprofilerate", 0, "Set memprofile sampling rate to value")
+
+var matchpkg func(name string) bool
+
+var atExitFuncs []func()
+
+func atExit(f func()) {
+	atExitFuncs = append(atExitFuncs, f)
+}
+
+func Exit(code int) {
+	for i := len(atExitFuncs) - 1; i >= 0; i-- {
+		f := atExitFuncs[i]
+		atExitFuncs = atExitFuncs[:i]
+		f()
+	}
+	os.Exit(code)
+}
+
+func dbgtrace(vlevel int, s string, a ...interface{}) {
+	if *verbflag >= vlevel {
+		fmt.Printf(s, a...)
+		fmt.Printf("\n")
+	}
+}
+
+func warn(s string, a ...interface{}) {
+	fmt.Fprintf(os.Stderr, "warning: ")
+	fmt.Fprintf(os.Stderr, s, a...)
+	fmt.Fprintf(os.Stderr, "\n")
+	if *hwflag {
+		panic("unexpected warning")
+	}
+}
+
+func fatal(s string, a ...interface{}) {
+	fmt.Fprintf(os.Stderr, "error: ")
+	fmt.Fprintf(os.Stderr, s, a...)
+	fmt.Fprintf(os.Stderr, "\n")
+	if *hflag {
+		panic("fatal error")
+	}
+	Exit(1)
+}
+
+func usage(msg string) {
+	if len(msg) > 0 {
+		fmt.Fprintf(os.Stderr, "error: %s\n", msg)
+	}
+	fmt.Fprintf(os.Stderr, "usage: go tool covdata [command]\n")
+	fmt.Fprintf(os.Stderr, `
+Commands are:
+
+textfmt     convert coverage data to textual format
+percent     output total percentage of statements covered
+pkglist     output list of package import paths
+func        output coverage profile information for each function
+merge       merge data files together
+subtract    subtract one set of data files from another set
+intersect   generate intersection of two sets of data files
+debugdump   dump data in human-readable format for debugging purposes
+`)
+	fmt.Fprintf(os.Stderr, "\nFor help on a specific subcommand, try:\n")
+	fmt.Fprintf(os.Stderr, "\ngo tool covdata <cmd> -help\n")
+	Exit(2)
+}
+
+type covOperation interface {
+	cov.CovDataVisitor
+	Setup()
+	Usage(string)
+}
+
+// Modes of operation.
+const (
+	funcMode      = "func"
+	mergeMode     = "merge"
+	intersectMode = "intersect"
+	subtractMode  = "subtract"
+	percentMode   = "percent"
+	pkglistMode   = "pkglist"
+	textfmtMode   = "textfmt"
+	debugDumpMode = "debugdump"
+)
+
+func main() {
+	// First argument should be mode/subcommand.
+	if len(os.Args) < 2 {
+		usage("missing command selector")
+	}
+
+	// Select mode
+	var op covOperation
+	cmd := os.Args[1]
+	switch cmd {
+	case mergeMode:
+		op = makeMergeOp()
+	case debugDumpMode:
+		op = makeDumpOp(debugDumpMode)
+	case textfmtMode:
+		op = makeDumpOp(textfmtMode)
+	case percentMode:
+		op = makeDumpOp(percentMode)
+	case funcMode:
+		op = makeDumpOp(funcMode)
+	case pkglistMode:
+		op = makeDumpOp(pkglistMode)
+	case subtractMode:
+		op = makeSubtractIntersectOp(subtractMode)
+	case intersectMode:
+		op = makeSubtractIntersectOp(intersectMode)
+	default:
+		usage(fmt.Sprintf("unknown command selector %q", cmd))
+	}
+
+	// Edit out command selector, then parse flags.
+	os.Args = append(os.Args[:1], os.Args[2:]...)
+	flag.Usage = func() {
+		op.Usage("")
+	}
+	flag.Parse()
+
+	// Mode-independent flag setup
+	dbgtrace(1, "starting mode-independent setup")
+	if flag.NArg() != 0 {
+		op.Usage("unknown extra arguments")
+	}
+	if *pkgpatflag != "" {
+		pats := strings.Split(*pkgpatflag, ",")
+		matchers := []func(name string) bool{}
+		for _, p := range pats {
+			if p == "" {
+				continue
+			}
+			f := pkgpattern.MatchSimplePattern(p)
+			matchers = append(matchers, f)
+		}
+		matchpkg = func(name string) bool {
+			for _, f := range matchers {
+				if f(name) {
+					return true
+				}
+			}
+			return false
+		}
+	}
+	if *cpuprofileflag != "" {
+		f, err := os.Create(*cpuprofileflag)
+		if err != nil {
+			fatal("%v", err)
+		}
+		if err := pprof.StartCPUProfile(f); err != nil {
+			fatal("%v", err)
+		}
+		atExit(pprof.StopCPUProfile)
+	}
+	if *memprofileflag != "" {
+		if *memprofilerateflag != 0 {
+			runtime.MemProfileRate = *memprofilerateflag
+		}
+		f, err := os.Create(*memprofileflag)
+		if err != nil {
+			fatal("%v", err)
+		}
+		atExit(func() {
+			runtime.GC()
+			const writeLegacyFormat = 1
+			if err := pprof.Lookup("heap").WriteTo(f, writeLegacyFormat); err != nil {
+				fatal("%v", err)
+			}
+		})
+	} else {
+		// Not doing memory profiling; disable it entirely.
+		runtime.MemProfileRate = 0
+	}
+
+	// Mode-dependent setup.
+	op.Setup()
+
+	// ... off and running now.
+	dbgtrace(1, "starting perform")
+
+	indirs := strings.Split(*indirsflag, ",")
+	vis := cov.CovDataVisitor(op)
+	var flags cov.CovDataReaderFlags
+	if *hflag {
+		flags |= cov.PanicOnError
+	}
+	if *hwflag {
+		flags |= cov.PanicOnWarning
+	}
+	reader := cov.MakeCovDataReader(vis, indirs, *verbflag, flags, matchpkg)
+	st := 0
+	if err := reader.Visit(); err != nil {
+		fmt.Fprintf(os.Stderr, "error: %v\n", err)
+		st = 1
+	}
+	dbgtrace(1, "leaving main")
+	Exit(st)
+}
diff --git a/src/cmd/covdata/doc.go b/src/cmd/covdata/doc.go
new file mode 100644
index 0000000..924a742
--- /dev/null
+++ b/src/cmd/covdata/doc.go
@@ -0,0 +1,84 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+//
+// Covdata is a program for manipulating and generating reports
+// from 2nd-generation coverage testing output files, those produced
+// from running applications or integration tests. E.g.
+//
+//		$ mkdir ./profiledir
+//		$ go build -cover -o myapp.exe .
+//		$ GOCOVERDIR=./profiledir ./myapp.exe <arguments>
+//		$ ls ./profiledir
+//		covcounters.cce1b350af34b6d0fb59cc1725f0ee27.821598.1663006712821344241
+//		covmeta.cce1b350af34b6d0fb59cc1725f0ee27
+//		$
+//
+// Run covdata via "go tool covdata <mode>", where 'mode' is a subcommand
+// selecting a specific reporting, merging, or data manipulation operation.
+// Descriptions on the various modes (run "go tool cover <mode> -help" for
+// specifics on usage of a given mode:
+//
+// 1. Report percent of statements covered in each profiled package
+//
+//		$ go tool covdata percent -i=profiledir
+//		cov-example/p	coverage: 41.1% of statements
+//		main	coverage: 87.5% of statements
+//      $
+//
+//
+// 2. Report import paths of packages profiled
+//
+//		$ go tool covdata pkglist -i=profiledir
+//		cov-example/p
+//		main
+//      $
+//
+// 3. Report percent statements covered by function:
+//
+//		$ go tool covdata func -i=profiledir
+//		cov-example/p/p.go:12:		emptyFn			0.0%
+//		cov-example/p/p.go:32:		Small			100.0%
+//		cov-example/p/p.go:47:		Medium			90.9%
+//      ...
+//      $
+//
+// 4. Convert coverage data to legacy textual format:
+//
+//		$ go tool covdata textfmt -i=profiledir -o=cov.txt
+//      $ head cov.txt
+//      mode: set
+//      cov-example/p/p.go:12.22,13.2 0 0
+//      cov-example/p/p.go:15.31,16.2 1 0
+//      cov-example/p/p.go:16.3,18.3 0 0
+//      cov-example/p/p.go:19.3,21.3 0 0
+//      ...
+//      $ go tool cover -html=cov.txt
+//      $
+//
+// 5. Merge profiles together:
+//
+//		$ go tool covdata merge -i=indir1,indir2 -o=outdir -modpaths=github.com/go-delve/delve
+//      $
+//
+// 6. Subtract one profile from another
+//
+//		$ go tool covdata subtract -i=indir1,indir2 -o=outdir
+//      $
+//
+// 7. Intersect profiles
+//
+//		$ go tool covdata intersect -i=indir1,indir2 -o=outdir
+//      $
+//
+// 8. Dump a profile for debugging purposes.
+//
+//		$ go tool covdata debugdump -i=indir
+//      <human readable output>
+//      $
+//
+*/
+
+package main
diff --git a/src/cmd/covdata/dump.go b/src/cmd/covdata/dump.go
new file mode 100644
index 0000000..6226717
--- /dev/null
+++ b/src/cmd/covdata/dump.go
@@ -0,0 +1,349 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+// This file contains functions and apis to support the "go tool
+// covdata" sub-commands that relate to dumping text format summaries
+// and reports: "pkglist", "func",  "debugdump", "percent", and
+// "textfmt".
+
+import (
+	"flag"
+	"fmt"
+	"internal/coverage"
+	"internal/coverage/calloc"
+	"internal/coverage/cformat"
+	"internal/coverage/cmerge"
+	"internal/coverage/decodecounter"
+	"internal/coverage/decodemeta"
+	"internal/coverage/pods"
+	"os"
+	"sort"
+	"strings"
+)
+
+var textfmtoutflag *string
+var liveflag *bool
+
+func makeDumpOp(cmd string) covOperation {
+	if cmd == textfmtMode || cmd == percentMode {
+		textfmtoutflag = flag.String("o", "", "Output text format to file")
+	}
+	if cmd == debugDumpMode {
+		liveflag = flag.Bool("live", false, "Select only live (executed) functions for dump output.")
+	}
+	d := &dstate{
+		cmd: cmd,
+		cm:  &cmerge.Merger{},
+	}
+	if d.cmd == pkglistMode {
+		d.pkgpaths = make(map[string]struct{})
+	}
+	return d
+}
+
+// dstate encapsulates state and provides methods for implementing
+// various dump operations. Specifically, dstate implements the
+// CovDataVisitor interface, and is designed to be used in
+// concert with the CovDataReader utility, which abstracts away most
+// of the grubby details of reading coverage data files.
+type dstate struct {
+	// for batch allocation of counter arrays
+	calloc.BatchCounterAlloc
+
+	// counter merging state + methods
+	cm *cmerge.Merger
+
+	// counter data formatting helper
+	format *cformat.Formatter
+
+	// 'mm' stores values read from a counter data file; the pkfunc key
+	// is a pkgid/funcid pair that uniquely identifies a function in
+	// instrumented application.
+	mm map[pkfunc]decodecounter.FuncPayload
+
+	// pkm maps package ID to the number of functions in the package
+	// with that ID. It is used to report inconsistencies in counter
+	// data (for example, a counter data entry with pkgid=N funcid=10
+	// where package N only has 3 functions).
+	pkm map[uint32]uint32
+
+	// pkgpaths records all package import paths encountered while
+	// visiting coverage data files (used to implement the "pkglist"
+	// subcommand).
+	pkgpaths map[string]struct{}
+
+	// Current package name and import path.
+	pkgName       string
+	pkgImportPath string
+
+	// Module path for current package (may be empty).
+	modulePath string
+
+	// Dump subcommand (ex: "textfmt", "debugdump", etc).
+	cmd string
+
+	// File to which we will write text format output, if enabled.
+	textfmtoutf *os.File
+
+	// Total and covered statements (used by "debugdump" subcommand).
+	totalStmts, coveredStmts int
+
+	// Records whether preamble has been emitted for current pkg
+	// (used when in "debugdump" mode)
+	preambleEmitted bool
+}
+
+func (d *dstate) Usage(msg string) {
+	if len(msg) > 0 {
+		fmt.Fprintf(os.Stderr, "error: %s\n", msg)
+	}
+	fmt.Fprintf(os.Stderr, "usage: go tool covdata %s -i=<directories>\n\n", d.cmd)
+	flag.PrintDefaults()
+	fmt.Fprintf(os.Stderr, "\nExamples:\n\n")
+	switch d.cmd {
+	case pkglistMode:
+		fmt.Fprintf(os.Stderr, "  go tool covdata pkglist -i=dir1,dir2\n\n")
+		fmt.Fprintf(os.Stderr, "  \treads coverage data files from dir1+dirs2\n")
+		fmt.Fprintf(os.Stderr, "  \tand writes out a list of the import paths\n")
+		fmt.Fprintf(os.Stderr, "  \tof all compiled packages.\n")
+	case textfmtMode:
+		fmt.Fprintf(os.Stderr, "  go tool covdata textfmt -i=dir1,dir2 -o=out.txt\n\n")
+		fmt.Fprintf(os.Stderr, "  \tmerges data from input directories dir1+dir2\n")
+		fmt.Fprintf(os.Stderr, "  \tand emits text format into file 'out.txt'\n")
+	case percentMode:
+		fmt.Fprintf(os.Stderr, "  go tool covdata percent -i=dir1,dir2\n\n")
+		fmt.Fprintf(os.Stderr, "  \tmerges data from input directories dir1+dir2\n")
+		fmt.Fprintf(os.Stderr, "  \tand emits percentage of statements covered\n\n")
+	case funcMode:
+		fmt.Fprintf(os.Stderr, "  go tool covdata func -i=dir1,dir2\n\n")
+		fmt.Fprintf(os.Stderr, "  \treads coverage data files from dir1+dirs2\n")
+		fmt.Fprintf(os.Stderr, "  \tand writes out coverage profile data for\n")
+		fmt.Fprintf(os.Stderr, "  \teach function.\n")
+	case debugDumpMode:
+		fmt.Fprintf(os.Stderr, "  go tool covdata debugdump [flags] -i=dir1,dir2\n\n")
+		fmt.Fprintf(os.Stderr, "  \treads coverage data from dir1+dir2 and dumps\n")
+		fmt.Fprintf(os.Stderr, "  \tcontents in human-readable form to stdout, for\n")
+		fmt.Fprintf(os.Stderr, "  \tdebugging purposes.\n")
+	default:
+		panic("unexpected")
+	}
+	Exit(2)
+}
+
+// Setup is called once at program startup time to vet flag values
+// and do any necessary setup operations.
+func (d *dstate) Setup() {
+	if *indirsflag == "" {
+		d.Usage("select input directories with '-i' option")
+	}
+	if d.cmd == textfmtMode || (d.cmd == percentMode && *textfmtoutflag != "") {
+		if *textfmtoutflag == "" {
+			d.Usage("select output file name with '-o' option")
+		}
+		var err error
+		d.textfmtoutf, err = os.Create(*textfmtoutflag)
+		if err != nil {
+			d.Usage(fmt.Sprintf("unable to open textfmt output file %q: %v", *textfmtoutflag, err))
+		}
+	}
+	if d.cmd == debugDumpMode {
+		fmt.Printf("/* WARNING: the format of this dump is not stable and is\n")
+		fmt.Printf(" * expected to change from one Go release to the next.\n")
+		fmt.Printf(" *\n")
+		fmt.Printf(" * produced by:\n")
+		args := append([]string{os.Args[0]}, debugDumpMode)
+		args = append(args, os.Args[1:]...)
+		fmt.Printf(" *\t%s\n", strings.Join(args, " "))
+		fmt.Printf(" */\n")
+	}
+}
+
+func (d *dstate) BeginPod(p pods.Pod) {
+	d.mm = make(map[pkfunc]decodecounter.FuncPayload)
+}
+
+func (d *dstate) EndPod(p pods.Pod) {
+	if d.cmd == debugDumpMode {
+		d.cm.ResetModeAndGranularity()
+	}
+}
+
+func (d *dstate) BeginCounterDataFile(cdf string, cdr *decodecounter.CounterDataReader, dirIdx int) {
+	dbgtrace(2, "visit counter data file %s dirIdx %d", cdf, dirIdx)
+	if d.cmd == debugDumpMode {
+		fmt.Printf("data file %s", cdf)
+		if cdr.Goos() != "" {
+			fmt.Printf(" GOOS=%s", cdr.Goos())
+		}
+		if cdr.Goarch() != "" {
+			fmt.Printf(" GOARCH=%s", cdr.Goarch())
+		}
+		if len(cdr.OsArgs()) != 0 {
+			fmt.Printf("  program args: %+v\n", cdr.OsArgs())
+		}
+		fmt.Printf("\n")
+	}
+}
+
+func (d *dstate) EndCounterDataFile(cdf string, cdr *decodecounter.CounterDataReader, dirIdx int) {
+}
+
+func (d *dstate) VisitFuncCounterData(data decodecounter.FuncPayload) {
+	if nf, ok := d.pkm[data.PkgIdx]; !ok || data.FuncIdx > nf {
+		warn("func payload inconsistency: id [p=%d,f=%d] nf=%d len(ctrs)=%d in VisitFuncCounterData, ignored", data.PkgIdx, data.FuncIdx, nf, len(data.Counters))
+		return
+	}
+	key := pkfunc{pk: data.PkgIdx, fcn: data.FuncIdx}
+	val, found := d.mm[key]
+
+	dbgtrace(5, "ctr visit pk=%d fid=%d found=%v len(val.ctrs)=%d len(data.ctrs)=%d", data.PkgIdx, data.FuncIdx, found, len(val.Counters), len(data.Counters))
+
+	if len(val.Counters) < len(data.Counters) {
+		t := val.Counters
+		val.Counters = d.AllocateCounters(len(data.Counters))
+		copy(val.Counters, t)
+	}
+	err, overflow := d.cm.MergeCounters(val.Counters, data.Counters)
+	if err != nil {
+		fatal("%v", err)
+	}
+	if overflow {
+		warn("uint32 overflow during counter merge")
+	}
+	d.mm[key] = val
+}
+
+func (d *dstate) EndCounters() {
+}
+
+func (d *dstate) VisitMetaDataFile(mdf string, mfr *decodemeta.CoverageMetaFileReader) {
+	newgran := mfr.CounterGranularity()
+	newmode := mfr.CounterMode()
+	if err := d.cm.SetModeAndGranularity(mdf, newmode, newgran); err != nil {
+		fatal("%v", err)
+	}
+	if d.cmd == debugDumpMode {
+		fmt.Printf("Cover mode: %s\n", newmode.String())
+		fmt.Printf("Cover granularity: %s\n", newgran.String())
+	}
+	if d.format == nil {
+		d.format = cformat.NewFormatter(mfr.CounterMode())
+	}
+
+	// To provide an additional layer of checking when reading counter
+	// data, walk the meta-data file to determine the set of legal
+	// package/function combinations. This will help catch bugs in the
+	// counter file reader.
+	d.pkm = make(map[uint32]uint32)
+	np := uint32(mfr.NumPackages())
+	payload := []byte{}
+	for pkIdx := uint32(0); pkIdx < np; pkIdx++ {
+		var pd *decodemeta.CoverageMetaDataDecoder
+		var err error
+		pd, payload, err = mfr.GetPackageDecoder(pkIdx, payload)
+		if err != nil {
+			fatal("reading pkg %d from meta-file %s: %s", pkIdx, mdf, err)
+		}
+		d.pkm[pkIdx] = pd.NumFuncs()
+	}
+}
+
+func (d *dstate) BeginPackage(pd *decodemeta.CoverageMetaDataDecoder, pkgIdx uint32) {
+	d.preambleEmitted = false
+	d.pkgImportPath = pd.PackagePath()
+	d.pkgName = pd.PackageName()
+	d.modulePath = pd.ModulePath()
+	if d.cmd == pkglistMode {
+		d.pkgpaths[d.pkgImportPath] = struct{}{}
+	}
+	d.format.SetPackage(pd.PackagePath())
+}
+
+func (d *dstate) EndPackage(pd *decodemeta.CoverageMetaDataDecoder, pkgIdx uint32) {
+}
+
+func (d *dstate) VisitFunc(pkgIdx uint32, fnIdx uint32, fd *coverage.FuncDesc) {
+	var counters []uint32
+	key := pkfunc{pk: pkgIdx, fcn: fnIdx}
+	v, haveCounters := d.mm[key]
+
+	dbgtrace(5, "meta visit pk=%d fid=%d fname=%s file=%s found=%v len(val.ctrs)=%d", pkgIdx, fnIdx, fd.Funcname, fd.Srcfile, haveCounters, len(v.Counters))
+
+	suppressOutput := false
+	if haveCounters {
+		counters = v.Counters
+	} else if d.cmd == debugDumpMode && *liveflag {
+		suppressOutput = true
+	}
+
+	if d.cmd == debugDumpMode && !suppressOutput {
+		if !d.preambleEmitted {
+			fmt.Printf("\nPackage path: %s\n", d.pkgImportPath)
+			fmt.Printf("Package name: %s\n", d.pkgName)
+			fmt.Printf("Module path: %s\n", d.modulePath)
+			d.preambleEmitted = true
+		}
+		fmt.Printf("\nFunc: %s\n", fd.Funcname)
+		fmt.Printf("Srcfile: %s\n", fd.Srcfile)
+		fmt.Printf("Literal: %v\n", fd.Lit)
+	}
+	for i := 0; i < len(fd.Units); i++ {
+		u := fd.Units[i]
+		var count uint32
+		if counters != nil {
+			count = counters[i]
+		}
+		d.format.AddUnit(fd.Srcfile, fd.Funcname, fd.Lit, u, count)
+		if d.cmd == debugDumpMode && !suppressOutput {
+			fmt.Printf("%d: L%d:C%d -- L%d:C%d ",
+				i, u.StLine, u.StCol, u.EnLine, u.EnCol)
+			if u.Parent != 0 {
+				fmt.Printf("Parent:%d = %d\n", u.Parent, count)
+			} else {
+				fmt.Printf("NS=%d = %d\n", u.NxStmts, count)
+			}
+		}
+		d.totalStmts += int(u.NxStmts)
+		if count != 0 {
+			d.coveredStmts += int(u.NxStmts)
+		}
+	}
+}
+
+func (d *dstate) Finish() {
+	// d.format maybe nil here if the specified input dir was empty.
+	if d.format != nil {
+		if d.cmd == percentMode {
+			d.format.EmitPercent(os.Stdout, "", false)
+		}
+		if d.cmd == funcMode {
+			d.format.EmitFuncs(os.Stdout)
+		}
+		if d.textfmtoutf != nil {
+			if err := d.format.EmitTextual(d.textfmtoutf); err != nil {
+				fatal("writing to %s: %v", *textfmtoutflag, err)
+			}
+		}
+	}
+	if d.textfmtoutf != nil {
+		if err := d.textfmtoutf.Close(); err != nil {
+			fatal("closing textfmt output file %s: %v", *textfmtoutflag, err)
+		}
+	}
+	if d.cmd == debugDumpMode {
+		fmt.Printf("totalStmts: %d coveredStmts: %d\n", d.totalStmts, d.coveredStmts)
+	}
+	if d.cmd == pkglistMode {
+		pkgs := make([]string, 0, len(d.pkgpaths))
+		for p := range d.pkgpaths {
+			pkgs = append(pkgs, p)
+		}
+		sort.Strings(pkgs)
+		for _, p := range pkgs {
+			fmt.Printf("%s\n", p)
+		}
+	}
+}
diff --git a/src/cmd/covdata/export_test.go b/src/cmd/covdata/export_test.go
new file mode 100644
index 0000000..e4592ee
--- /dev/null
+++ b/src/cmd/covdata/export_test.go
@@ -0,0 +1,7 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func Main() { main() }
diff --git a/src/cmd/covdata/merge.go b/src/cmd/covdata/merge.go
new file mode 100644
index 0000000..225861d
--- /dev/null
+++ b/src/cmd/covdata/merge.go
@@ -0,0 +1,109 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+// This file contains functions and apis to support the "merge"
+// subcommand of "go tool covdata".
+
+import (
+	"flag"
+	"fmt"
+	"internal/coverage"
+	"internal/coverage/decodecounter"
+	"internal/coverage/decodemeta"
+	"internal/coverage/pods"
+	"os"
+)
+
+var outdirflag *string
+var pcombineflag *bool
+
+func makeMergeOp() covOperation {
+	outdirflag = flag.String("o", "", "Output directory to write")
+	pcombineflag = flag.Bool("pcombine", false, "Combine profiles derived from distinct program executables")
+	m := &mstate{
+		mm: newMetaMerge(),
+	}
+	return m
+}
+
+// mstate encapsulates state and provides methods for implementing the
+// merge operation. This type implements the CovDataVisitor interface,
+// and is designed to be used in concert with the CovDataReader
+// utility, which abstracts away most of the grubby details of reading
+// coverage data files. Most of the heavy lifting for merging is done
+// using apis from 'metaMerge' (this is mainly a wrapper around that
+// functionality).
+type mstate struct {
+	mm *metaMerge
+}
+
+func (m *mstate) Usage(msg string) {
+	if len(msg) > 0 {
+		fmt.Fprintf(os.Stderr, "error: %s\n", msg)
+	}
+	fmt.Fprintf(os.Stderr, "usage: go tool covdata merge -i=<directories> -o=<dir>\n\n")
+	flag.PrintDefaults()
+	fmt.Fprintf(os.Stderr, "\nExamples:\n\n")
+	fmt.Fprintf(os.Stderr, "  go tool covdata merge -i=dir1,dir2,dir3 -o=outdir\n\n")
+	fmt.Fprintf(os.Stderr, "  \tmerges all files in dir1/dir2/dir3\n")
+	fmt.Fprintf(os.Stderr, "  \tinto output dir outdir\n")
+	Exit(2)
+}
+
+func (m *mstate) Setup() {
+	if *indirsflag == "" {
+		m.Usage("select input directories with '-i' option")
+	}
+	if *outdirflag == "" {
+		m.Usage("select output directory with '-o' option")
+	}
+}
+
+func (m *mstate) BeginPod(p pods.Pod) {
+	m.mm.beginPod()
+}
+
+func (m *mstate) EndPod(p pods.Pod) {
+	m.mm.endPod(*pcombineflag)
+}
+
+func (m *mstate) BeginCounterDataFile(cdf string, cdr *decodecounter.CounterDataReader, dirIdx int) {
+	dbgtrace(2, "visit counter data file %s dirIdx %d", cdf, dirIdx)
+	m.mm.beginCounterDataFile(cdr)
+}
+
+func (m *mstate) EndCounterDataFile(cdf string, cdr *decodecounter.CounterDataReader, dirIdx int) {
+}
+
+func (m *mstate) VisitFuncCounterData(data decodecounter.FuncPayload) {
+	m.mm.visitFuncCounterData(data)
+}
+
+func (m *mstate) EndCounters() {
+}
+
+func (m *mstate) VisitMetaDataFile(mdf string, mfr *decodemeta.CoverageMetaFileReader) {
+	m.mm.visitMetaDataFile(mdf, mfr)
+}
+
+func (m *mstate) BeginPackage(pd *decodemeta.CoverageMetaDataDecoder, pkgIdx uint32) {
+	dbgtrace(3, "VisitPackage(pk=%d path=%s)", pkgIdx, pd.PackagePath())
+	m.mm.visitPackage(pd, pkgIdx, *pcombineflag)
+}
+
+func (m *mstate) EndPackage(pd *decodemeta.CoverageMetaDataDecoder, pkgIdx uint32) {
+}
+
+func (m *mstate) VisitFunc(pkgIdx uint32, fnIdx uint32, fd *coverage.FuncDesc) {
+	m.mm.visitFunc(pkgIdx, fnIdx, fd, mergeMode, *pcombineflag)
+}
+
+func (m *mstate) Finish() {
+	if *pcombineflag {
+		finalHash := m.mm.emitMeta(*outdirflag, true)
+		m.mm.emitCounters(*outdirflag, finalHash)
+	}
+}
diff --git a/src/cmd/covdata/metamerge.go b/src/cmd/covdata/metamerge.go
new file mode 100644
index 0000000..7f15742
--- /dev/null
+++ b/src/cmd/covdata/metamerge.go
@@ -0,0 +1,433 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+// This file contains functions and apis that support merging of
+// meta-data information.  It helps implement the "merge", "subtract",
+// and "intersect" subcommands.
+
+import (
+	"crypto/md5"
+	"fmt"
+	"internal/coverage"
+	"internal/coverage/calloc"
+	"internal/coverage/cmerge"
+	"internal/coverage/decodecounter"
+	"internal/coverage/decodemeta"
+	"internal/coverage/encodecounter"
+	"internal/coverage/encodemeta"
+	"internal/coverage/slicewriter"
+	"io"
+	"os"
+	"path/filepath"
+	"sort"
+	"time"
+	"unsafe"
+)
+
+// metaMerge provides state and methods to help manage the process
+// of selecting or merging meta data files. There are three cases
+// of interest here: the "-pcombine" flag provided by merge, the
+// "-pkg" option provided by all merge/subtract/intersect, and
+// a regular vanilla merge with no package selection
+//
+// In the -pcombine case, we're essentially glomming together all the
+// meta-data for all packages and all functions, meaning that
+// everything we see in a given package needs to be added into the
+// meta-data file builder; we emit a single meta-data file at the end
+// of the run.
+//
+// In the -pkg case, we will typically emit a single meta-data file
+// per input pod, where that new meta-data file contains entries for
+// just the selected packages.
+//
+// In the third case (vanilla merge with no combining or package
+// selection) we can carry over meta-data files without touching them
+// at all (only counter data files will be merged).
+type metaMerge struct {
+	calloc.BatchCounterAlloc
+	cmerge.Merger
+	// maps package import path to package state
+	pkm map[string]*pkstate
+	// list of packages
+	pkgs []*pkstate
+	// current package state
+	p *pkstate
+	// current pod state
+	pod *podstate
+	// counter data file osargs/goos/goarch state
+	astate *argstate
+}
+
+// pkstate
+type pkstate struct {
+	// index of package within meta-data file.
+	pkgIdx uint32
+	// this maps function index within the package to counter data payload
+	ctab map[uint32]decodecounter.FuncPayload
+	// pointer to meta-data blob for package
+	mdblob []byte
+	// filled in only for -pcombine merges
+	*pcombinestate
+}
+
+type podstate struct {
+	pmm      map[pkfunc]decodecounter.FuncPayload
+	mdf      string
+	mfr      *decodemeta.CoverageMetaFileReader
+	fileHash [16]byte
+}
+
+type pkfunc struct {
+	pk, fcn uint32
+}
+
+// pcombinestate
+type pcombinestate struct {
+	// Meta-data builder for the package.
+	cmdb *encodemeta.CoverageMetaDataBuilder
+	// Maps function meta-data hash to new function index in the
+	// new version of the package we're building.
+	ftab map[[16]byte]uint32
+}
+
+func newMetaMerge() *metaMerge {
+	return &metaMerge{
+		pkm:    make(map[string]*pkstate),
+		astate: &argstate{},
+	}
+}
+
+func (mm *metaMerge) visitMetaDataFile(mdf string, mfr *decodemeta.CoverageMetaFileReader) {
+	dbgtrace(2, "visitMetaDataFile(mdf=%s)", mdf)
+
+	// Record meta-data file name.
+	mm.pod.mdf = mdf
+	// Keep a pointer to the file-level reader.
+	mm.pod.mfr = mfr
+	// Record file hash.
+	mm.pod.fileHash = mfr.FileHash()
+	// Counter mode and granularity -- detect and record clashes here.
+	newgran := mfr.CounterGranularity()
+	newmode := mfr.CounterMode()
+	if err := mm.SetModeAndGranularity(mdf, newmode, newgran); err != nil {
+		fatal("%v", err)
+	}
+}
+
+func (mm *metaMerge) beginCounterDataFile(cdr *decodecounter.CounterDataReader) {
+	state := argvalues{
+		osargs: cdr.OsArgs(),
+		goos:   cdr.Goos(),
+		goarch: cdr.Goarch(),
+	}
+	mm.astate.Merge(state)
+}
+
+func copyMetaDataFile(inpath, outpath string) {
+	inf, err := os.Open(inpath)
+	if err != nil {
+		fatal("opening input meta-data file %s: %v", inpath, err)
+	}
+	defer inf.Close()
+
+	fi, err := inf.Stat()
+	if err != nil {
+		fatal("accessing input meta-data file %s: %v", inpath, err)
+	}
+
+	outf, err := os.OpenFile(outpath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, fi.Mode())
+	if err != nil {
+		fatal("opening output meta-data file %s: %v", outpath, err)
+	}
+
+	_, err = io.Copy(outf, inf)
+	outf.Close()
+	if err != nil {
+		fatal("writing output meta-data file %s: %v", outpath, err)
+	}
+}
+
+func (mm *metaMerge) beginPod() {
+	mm.pod = &podstate{
+		pmm: make(map[pkfunc]decodecounter.FuncPayload),
+	}
+}
+
+// metaEndPod handles actions needed when we're done visiting all of
+// the things in a pod -- counter files and meta-data file. There are
+// three cases of interest here:
+//
+// Case 1: in an unconditonal merge (we're not selecting a specific set of
+// packages using "-pkg", and the "-pcombine" option is not in use),
+// we can simply copy over the meta-data file from input to output.
+//
+// Case 2: if this is a select merge (-pkg is in effect), then at
+// this point we write out a new smaller meta-data file that includes
+// only the packages of interest). At this point we also emit a merged
+// counter data file as well.
+//
+// Case 3: if "-pcombine" is in effect, we don't write anything at
+// this point (all writes will happen at the end of the run).
+func (mm *metaMerge) endPod(pcombine bool) {
+	if pcombine {
+		// Just clear out the pod data, we'll do all the
+		// heavy lifting at the end.
+		mm.pod = nil
+		return
+	}
+
+	finalHash := mm.pod.fileHash
+	if matchpkg != nil {
+		// Emit modified meta-data file for this pod.
+		finalHash = mm.emitMeta(*outdirflag, pcombine)
+	} else {
+		// Copy meta-data file for this pod to the output directory.
+		inpath := mm.pod.mdf
+		mdfbase := filepath.Base(mm.pod.mdf)
+		outpath := filepath.Join(*outdirflag, mdfbase)
+		copyMetaDataFile(inpath, outpath)
+	}
+
+	// Emit acccumulated counter data for this pod.
+	mm.emitCounters(*outdirflag, finalHash)
+
+	// Reset package state.
+	mm.pkm = make(map[string]*pkstate)
+	mm.pkgs = nil
+	mm.pod = nil
+
+	// Reset counter mode and granularity
+	mm.ResetModeAndGranularity()
+}
+
+// emitMeta encodes and writes out a new coverage meta-data file as
+// part of a merge operation, specifically a merge with the
+// "-pcombine" flag.
+func (mm *metaMerge) emitMeta(outdir string, pcombine bool) [16]byte {
+	fh := md5.New()
+	blobs := [][]byte{}
+	tlen := uint64(unsafe.Sizeof(coverage.MetaFileHeader{}))
+	for _, p := range mm.pkgs {
+		var blob []byte
+		if pcombine {
+			mdw := &slicewriter.WriteSeeker{}
+			p.cmdb.Emit(mdw)
+			blob = mdw.BytesWritten()
+		} else {
+			blob = p.mdblob
+		}
+		ph := md5.Sum(blob)
+		blobs = append(blobs, blob)
+		if _, err := fh.Write(ph[:]); err != nil {
+			panic(fmt.Sprintf("internal error: md5 sum failed: %v", err))
+		}
+		tlen += uint64(len(blob))
+	}
+	var finalHash [16]byte
+	fhh := fh.Sum(nil)
+	copy(finalHash[:], fhh)
+
+	// Open meta-file for writing.
+	fn := fmt.Sprintf("%s.%x", coverage.MetaFilePref, finalHash)
+	fpath := filepath.Join(outdir, fn)
+	mf, err := os.OpenFile(fpath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
+	if err != nil {
+		fatal("unable to open output meta-data file %s: %v", fpath, err)
+	}
+
+	// Encode and write.
+	mfw := encodemeta.NewCoverageMetaFileWriter(fpath, mf)
+	err = mfw.Write(finalHash, blobs, mm.Mode(), mm.Granularity())
+	if err != nil {
+		fatal("error writing %s: %v\n", fpath, err)
+	}
+	return finalHash
+}
+
+func (mm *metaMerge) emitCounters(outdir string, metaHash [16]byte) {
+	// Open output file. The file naming scheme is intended to mimic
+	// that used when running a coverage-instrumented binary, for
+	// consistency (however the process ID is not meaningful here, so
+	// use a value of zero).
+	var dummyPID int
+	fn := fmt.Sprintf(coverage.CounterFileTempl, coverage.CounterFilePref, metaHash, dummyPID, time.Now().UnixNano())
+	fpath := filepath.Join(outdir, fn)
+	cf, err := os.OpenFile(fpath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
+	if err != nil {
+		fatal("opening counter data file %s: %v", fpath, err)
+	}
+	defer func() {
+		if err := cf.Close(); err != nil {
+			fatal("error closing output meta-data file %s: %v", fpath, err)
+		}
+	}()
+
+	args := mm.astate.ArgsSummary()
+	cfw := encodecounter.NewCoverageDataWriter(cf, coverage.CtrULeb128)
+	if err := cfw.Write(metaHash, args, mm); err != nil {
+		fatal("counter file write failed: %v", err)
+	}
+	mm.astate = &argstate{}
+}
+
+// NumFuncs is used while writing the counter data files; it
+// implements the 'NumFuncs' method required by the interface
+// internal/coverage/encodecounter/CounterVisitor.
+func (mm *metaMerge) NumFuncs() (int, error) {
+	rval := 0
+	for _, p := range mm.pkgs {
+		rval += len(p.ctab)
+	}
+	return rval, nil
+}
+
+// VisitFuncs is used while writing the counter data files; it
+// implements the 'VisitFuncs' method required by the interface
+// internal/coverage/encodecounter/CounterVisitor.
+func (mm *metaMerge) VisitFuncs(f encodecounter.CounterVisitorFn) error {
+	if *verbflag >= 4 {
+		fmt.Printf("counterVisitor invoked\n")
+	}
+	// For each package, for each function, construct counter
+	// array and then call "f" on it.
+	for pidx, p := range mm.pkgs {
+		fids := make([]int, 0, len(p.ctab))
+		for fid := range p.ctab {
+			fids = append(fids, int(fid))
+		}
+		sort.Ints(fids)
+		if *verbflag >= 4 {
+			fmt.Printf("fids for pk=%d: %+v\n", pidx, fids)
+		}
+		for _, fid := range fids {
+			fp := p.ctab[uint32(fid)]
+			if *verbflag >= 4 {
+				fmt.Printf("counter write for pk=%d fid=%d len(ctrs)=%d\n", pidx, fid, len(fp.Counters))
+			}
+			if err := f(uint32(pidx), uint32(fid), fp.Counters); err != nil {
+				return err
+			}
+		}
+	}
+	return nil
+}
+
+func (mm *metaMerge) visitPackage(pd *decodemeta.CoverageMetaDataDecoder, pkgIdx uint32, pcombine bool) {
+	p, ok := mm.pkm[pd.PackagePath()]
+	if !ok {
+		p = &pkstate{
+			pkgIdx: uint32(len(mm.pkgs)),
+		}
+		mm.pkgs = append(mm.pkgs, p)
+		mm.pkm[pd.PackagePath()] = p
+		if pcombine {
+			p.pcombinestate = new(pcombinestate)
+			cmdb, err := encodemeta.NewCoverageMetaDataBuilder(pd.PackagePath(), pd.PackageName(), pd.ModulePath())
+			if err != nil {
+				fatal("fatal error creating meta-data builder: %v", err)
+			}
+			dbgtrace(2, "install new pkm entry for package %s pk=%d", pd.PackagePath(), pkgIdx)
+			p.cmdb = cmdb
+			p.ftab = make(map[[16]byte]uint32)
+		} else {
+			var err error
+			p.mdblob, err = mm.pod.mfr.GetPackagePayload(pkgIdx, nil)
+			if err != nil {
+				fatal("error extracting package %d payload from %s: %v",
+					pkgIdx, mm.pod.mdf, err)
+			}
+		}
+		p.ctab = make(map[uint32]decodecounter.FuncPayload)
+	}
+	mm.p = p
+}
+
+func (mm *metaMerge) visitFuncCounterData(data decodecounter.FuncPayload) {
+	key := pkfunc{pk: data.PkgIdx, fcn: data.FuncIdx}
+	val := mm.pod.pmm[key]
+	// FIXME: in theory either A) len(val.Counters) is zero, or B)
+	// the two lengths are equal. Assert if not? Of course, we could
+	// see odd stuff if there is source file skew.
+	if *verbflag > 4 {
+		fmt.Printf("visit pk=%d fid=%d len(counters)=%d\n", data.PkgIdx, data.FuncIdx, len(data.Counters))
+	}
+	if len(val.Counters) < len(data.Counters) {
+		t := val.Counters
+		val.Counters = mm.AllocateCounters(len(data.Counters))
+		copy(val.Counters, t)
+	}
+	err, overflow := mm.MergeCounters(val.Counters, data.Counters)
+	if err != nil {
+		fatal("%v", err)
+	}
+	if overflow {
+		warn("uint32 overflow during counter merge")
+	}
+	mm.pod.pmm[key] = val
+}
+
+func (mm *metaMerge) visitFunc(pkgIdx uint32, fnIdx uint32, fd *coverage.FuncDesc, verb string, pcombine bool) {
+	if *verbflag >= 3 {
+		fmt.Printf("visit pk=%d fid=%d func %s\n", pkgIdx, fnIdx, fd.Funcname)
+	}
+
+	var counters []uint32
+	key := pkfunc{pk: pkgIdx, fcn: fnIdx}
+	v, haveCounters := mm.pod.pmm[key]
+	if haveCounters {
+		counters = v.Counters
+	}
+
+	if pcombine {
+		// If the merge is running in "combine programs" mode, then hash
+		// the function and look it up in the package ftab to see if we've
+		// encountered it before. If we haven't, then register it with the
+		// meta-data builder.
+		fnhash := encodemeta.HashFuncDesc(fd)
+		gfidx, ok := mm.p.ftab[fnhash]
+		if !ok {
+			// We haven't seen this function before, need to add it to
+			// the meta data.
+			gfidx = uint32(mm.p.cmdb.AddFunc(*fd))
+			mm.p.ftab[fnhash] = gfidx
+			if *verbflag >= 3 {
+				fmt.Printf("new meta entry for fn %s fid=%d\n", fd.Funcname, gfidx)
+			}
+		}
+		fnIdx = gfidx
+	}
+	if !haveCounters {
+		return
+	}
+
+	// Install counters in package ctab.
+	gfp, ok := mm.p.ctab[fnIdx]
+	if ok {
+		if verb == "subtract" || verb == "intersect" {
+			panic("should never see this for intersect/subtract")
+		}
+		if *verbflag >= 3 {
+			fmt.Printf("counter merge for %s fidx=%d\n", fd.Funcname, fnIdx)
+		}
+		// Merge.
+		err, overflow := mm.MergeCounters(gfp.Counters, counters)
+		if err != nil {
+			fatal("%v", err)
+		}
+		if overflow {
+			warn("uint32 overflow during counter merge")
+		}
+		mm.p.ctab[fnIdx] = gfp
+	} else {
+		if *verbflag >= 3 {
+			fmt.Printf("null merge for %s fidx %d\n", fd.Funcname, fnIdx)
+		}
+		gfp := v
+		gfp.PkgIdx = mm.p.pkgIdx
+		gfp.FuncIdx = fnIdx
+		mm.p.ctab[fnIdx] = gfp
+	}
+}
diff --git a/src/cmd/covdata/subtractintersect.go b/src/cmd/covdata/subtractintersect.go
new file mode 100644
index 0000000..5d71e3d
--- /dev/null
+++ b/src/cmd/covdata/subtractintersect.go
@@ -0,0 +1,196 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+// This file contains functions and apis to support the "subtract" and
+// "intersect" subcommands of "go tool covdata".
+
+import (
+	"flag"
+	"fmt"
+	"internal/coverage"
+	"internal/coverage/decodecounter"
+	"internal/coverage/decodemeta"
+	"internal/coverage/pods"
+	"os"
+	"strings"
+)
+
+// makeSubtractIntersectOp creates a subtract or intersect operation.
+// 'mode' here must be either "subtract" or "intersect".
+func makeSubtractIntersectOp(mode string) covOperation {
+	outdirflag = flag.String("o", "", "Output directory to write")
+	s := &sstate{
+		mode:  mode,
+		mm:    newMetaMerge(),
+		inidx: -1,
+	}
+	return s
+}
+
+// sstate holds state needed to implement subtraction and intersection
+// operations on code coverage data files. This type provides methods
+// to implement the CovDataVisitor interface, and is designed to be
+// used in concert with the CovDataReader utility, which abstracts
+// away most of the grubby details of reading coverage data files.
+type sstate struct {
+	mm    *metaMerge
+	inidx int
+	mode  string
+	// Used only for intersection; keyed by pkg/fn ID, it keeps track of
+	// just the set of functions for which we have data in the current
+	// input directory.
+	imm map[pkfunc]struct{}
+}
+
+func (s *sstate) Usage(msg string) {
+	if len(msg) > 0 {
+		fmt.Fprintf(os.Stderr, "error: %s\n", msg)
+	}
+	fmt.Fprintf(os.Stderr, "usage: go tool covdata %s -i=dir1,dir2 -o=<dir>\n\n", s.mode)
+	flag.PrintDefaults()
+	fmt.Fprintf(os.Stderr, "\nExamples:\n\n")
+	op := "from"
+	if s.mode == intersectMode {
+		op = "with"
+	}
+	fmt.Fprintf(os.Stderr, "  go tool covdata %s -i=dir1,dir2 -o=outdir\n\n", s.mode)
+	fmt.Fprintf(os.Stderr, "  \t%ss dir2 %s dir1, writing result\n", s.mode, op)
+	fmt.Fprintf(os.Stderr, "  \tinto output dir outdir.\n")
+	os.Exit(2)
+}
+
+func (s *sstate) Setup() {
+	if *indirsflag == "" {
+		usage("select input directories with '-i' option")
+	}
+	indirs := strings.Split(*indirsflag, ",")
+	if s.mode == subtractMode && len(indirs) != 2 {
+		usage("supply exactly two input dirs for subtract operation")
+	}
+	if *outdirflag == "" {
+		usage("select output directory with '-o' option")
+	}
+}
+
+func (s *sstate) BeginPod(p pods.Pod) {
+	s.mm.beginPod()
+}
+
+func (s *sstate) EndPod(p pods.Pod) {
+	const pcombine = false
+	s.mm.endPod(pcombine)
+}
+
+func (s *sstate) EndCounters() {
+	if s.imm != nil {
+		s.pruneCounters()
+	}
+}
+
+// pruneCounters performs a function-level partial intersection using the
+// current POD counter data (s.mm.pod.pmm) and the intersected data from
+// PODs in previous dirs (s.imm).
+func (s *sstate) pruneCounters() {
+	pkeys := make([]pkfunc, 0, len(s.mm.pod.pmm))
+	for k := range s.mm.pod.pmm {
+		pkeys = append(pkeys, k)
+	}
+	// Remove anything from pmm not found in imm. We don't need to
+	// go the other way (removing things from imm not found in pmm)
+	// since we don't add anything to imm if there is no pmm entry.
+	for _, k := range pkeys {
+		if _, found := s.imm[k]; !found {
+			delete(s.mm.pod.pmm, k)
+		}
+	}
+	s.imm = nil
+}
+
+func (s *sstate) BeginCounterDataFile(cdf string, cdr *decodecounter.CounterDataReader, dirIdx int) {
+	dbgtrace(2, "visiting counter data file %s diridx %d", cdf, dirIdx)
+	if s.inidx != dirIdx {
+		if s.inidx > dirIdx {
+			// We're relying on having data files presented in
+			// the order they appear in the inputs (e.g. first all
+			// data files from input dir 0, then dir 1, etc).
+			panic("decreasing dir index, internal error")
+		}
+		if dirIdx == 0 {
+			// No need to keep track of the functions in the first
+			// directory, since that info will be replicated in
+			// s.mm.pod.pmm.
+			s.imm = nil
+		} else {
+			// We're now starting to visit the Nth directory, N != 0.
+			if s.mode == intersectMode {
+				if s.imm != nil {
+					s.pruneCounters()
+				}
+				s.imm = make(map[pkfunc]struct{})
+			}
+		}
+		s.inidx = dirIdx
+	}
+}
+
+func (s *sstate) EndCounterDataFile(cdf string, cdr *decodecounter.CounterDataReader, dirIdx int) {
+}
+
+func (s *sstate) VisitFuncCounterData(data decodecounter.FuncPayload) {
+	key := pkfunc{pk: data.PkgIdx, fcn: data.FuncIdx}
+
+	if *verbflag >= 5 {
+		fmt.Printf("ctr visit fid=%d pk=%d inidx=%d data.Counters=%+v\n", data.FuncIdx, data.PkgIdx, s.inidx, data.Counters)
+	}
+
+	// If we're processing counter data from the initial (first) input
+	// directory, then just install it into the counter data map
+	// as usual.
+	if s.inidx == 0 {
+		s.mm.visitFuncCounterData(data)
+		return
+	}
+
+	// If we're looking at counter data from a dir other than
+	// the first, then perform the intersect/subtract.
+	if val, ok := s.mm.pod.pmm[key]; ok {
+		if s.mode == subtractMode {
+			for i := 0; i < len(data.Counters); i++ {
+				if data.Counters[i] != 0 {
+					val.Counters[i] = 0
+				}
+			}
+		} else if s.mode == intersectMode {
+			s.imm[key] = struct{}{}
+			for i := 0; i < len(data.Counters); i++ {
+				if data.Counters[i] == 0 {
+					val.Counters[i] = 0
+				}
+			}
+		}
+	}
+}
+
+func (s *sstate) VisitMetaDataFile(mdf string, mfr *decodemeta.CoverageMetaFileReader) {
+	if s.mode == intersectMode {
+		s.imm = make(map[pkfunc]struct{})
+	}
+	s.mm.visitMetaDataFile(mdf, mfr)
+}
+
+func (s *sstate) BeginPackage(pd *decodemeta.CoverageMetaDataDecoder, pkgIdx uint32) {
+	s.mm.visitPackage(pd, pkgIdx, false)
+}
+
+func (s *sstate) EndPackage(pd *decodemeta.CoverageMetaDataDecoder, pkgIdx uint32) {
+}
+
+func (s *sstate) VisitFunc(pkgIdx uint32, fnIdx uint32, fd *coverage.FuncDesc) {
+	s.mm.visitFunc(pkgIdx, fnIdx, fd, s.mode, false)
+}
+
+func (s *sstate) Finish() {
+}
diff --git a/src/cmd/covdata/testdata/dep.go b/src/cmd/covdata/testdata/dep.go
new file mode 100644
index 0000000..2127ab2
--- /dev/null
+++ b/src/cmd/covdata/testdata/dep.go
@@ -0,0 +1,17 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package dep
+
+func Dep1() int {
+	return 42
+}
+
+func PDep(x int) {
+	if x != 1010101 {
+		println(x)
+	} else {
+		panic("bad")
+	}
+}
diff --git a/src/cmd/covdata/testdata/prog1.go b/src/cmd/covdata/testdata/prog1.go
new file mode 100644
index 0000000..76e9e91
--- /dev/null
+++ b/src/cmd/covdata/testdata/prog1.go
@@ -0,0 +1,48 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"os"
+	"prog/dep"
+)
+
+//go:noinline
+func first() {
+	println("whee")
+}
+
+//go:noinline
+func second() {
+	println("oy")
+}
+
+//go:noinline
+func third(x int) int {
+	if x != 0 {
+		return 42
+	}
+	println("blarg")
+	return 0
+}
+
+//go:noinline
+func fourth() int {
+	return 99
+}
+
+func main() {
+	println(dep.Dep1())
+	dep.PDep(2)
+	if len(os.Args) > 1 {
+		second()
+		third(1)
+	} else if len(os.Args) > 2 {
+		fourth()
+	} else {
+		first()
+		third(0)
+	}
+}
diff --git a/src/cmd/covdata/testdata/prog2.go b/src/cmd/covdata/testdata/prog2.go
new file mode 100644
index 0000000..e51e786
--- /dev/null
+++ b/src/cmd/covdata/testdata/prog2.go
@@ -0,0 +1,29 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"os"
+	"prog/dep"
+)
+
+//go:noinline
+func fifth() {
+	println("hubba")
+}
+
+//go:noinline
+func sixth() {
+	println("wha?")
+}
+
+func main() {
+	println(dep.Dep1())
+	if len(os.Args) > 1 {
+		fifth()
+	} else {
+		sixth()
+	}
+}
diff --git a/src/cmd/covdata/tool_test.go b/src/cmd/covdata/tool_test.go
new file mode 100644
index 0000000..42334ea
--- /dev/null
+++ b/src/cmd/covdata/tool_test.go
@@ -0,0 +1,944 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main_test
+
+import (
+	cmdcovdata "cmd/covdata"
+	"flag"
+	"fmt"
+	"internal/coverage/pods"
+	"internal/goexperiment"
+	"internal/testenv"
+	"log"
+	"os"
+	"path/filepath"
+	"regexp"
+	"strconv"
+	"strings"
+	"sync"
+	"testing"
+)
+
+// testcovdata returns the path to the unit test executable to be used as
+// standin for 'go tool covdata'.
+func testcovdata(t testing.TB) string {
+	exe, err := os.Executable()
+	if err != nil {
+		t.Helper()
+		t.Fatal(err)
+	}
+	return exe
+}
+
+// Top level tempdir for test.
+var testTempDir string
+
+// If set, this will preserve all the tmpdir files from the test run.
+var preserveTmp = flag.Bool("preservetmp", false, "keep tmpdir files for debugging")
+
+// TestMain used here so that we can leverage the test executable
+// itself as a cmd/covdata executable; compare to similar usage in
+// the cmd/go tests.
+func TestMain(m *testing.M) {
+	// When CMDCOVDATA_TEST_RUN_MAIN is set, we're reusing the test
+	// binary as cmd/cover. In this case we run the main func exported
+	// via export_test.go, and exit; CMDCOVDATA_TEST_RUN_MAIN is set below
+	// for actual test invocations.
+	if os.Getenv("CMDCOVDATA_TEST_RUN_MAIN") != "" {
+		cmdcovdata.Main()
+		os.Exit(0)
+	}
+	flag.Parse()
+	topTmpdir, err := os.MkdirTemp("", "cmd-covdata-test-")
+	if err != nil {
+		log.Fatal(err)
+	}
+	testTempDir = topTmpdir
+	if !*preserveTmp {
+		defer os.RemoveAll(topTmpdir)
+	} else {
+		fmt.Fprintf(os.Stderr, "debug: preserving tmpdir %s\n", topTmpdir)
+	}
+	os.Setenv("CMDCOVDATA_TEST_RUN_MAIN", "true")
+	os.Exit(m.Run())
+}
+
+var tdmu sync.Mutex
+var tdcount int
+
+func tempDir(t *testing.T) string {
+	tdmu.Lock()
+	dir := filepath.Join(testTempDir, fmt.Sprintf("%03d", tdcount))
+	tdcount++
+	if err := os.Mkdir(dir, 0777); err != nil {
+		t.Fatal(err)
+	}
+	defer tdmu.Unlock()
+	return dir
+}
+
+const debugtrace = false
+
+func gobuild(t *testing.T, indir string, bargs []string) {
+	t.Helper()
+
+	if debugtrace {
+		if indir != "" {
+			t.Logf("in dir %s: ", indir)
+		}
+		t.Logf("cmd: %s %+v\n", testenv.GoToolPath(t), bargs)
+	}
+	cmd := testenv.Command(t, testenv.GoToolPath(t), bargs...)
+	cmd.Dir = indir
+	b, err := cmd.CombinedOutput()
+	if len(b) != 0 {
+		t.Logf("## build output:\n%s", b)
+	}
+	if err != nil {
+		t.Fatalf("build error: %v", err)
+	}
+}
+
+func emitFile(t *testing.T, dst, src string) {
+	payload, err := os.ReadFile(src)
+	if err != nil {
+		t.Fatalf("error reading %q: %v", src, err)
+	}
+	if err := os.WriteFile(dst, payload, 0666); err != nil {
+		t.Fatalf("writing %q: %v", dst, err)
+	}
+}
+
+const mainPkgPath = "prog"
+
+func buildProg(t *testing.T, prog string, dir string, tag string, flags []string) (string, string) {
+	// Create subdirs.
+	subdir := filepath.Join(dir, prog+"dir"+tag)
+	if err := os.Mkdir(subdir, 0777); err != nil {
+		t.Fatalf("can't create outdir %s: %v", subdir, err)
+	}
+	depdir := filepath.Join(subdir, "dep")
+	if err := os.Mkdir(depdir, 0777); err != nil {
+		t.Fatalf("can't create outdir %s: %v", depdir, err)
+	}
+
+	// Emit program.
+	insrc := filepath.Join("testdata", prog+".go")
+	src := filepath.Join(subdir, prog+".go")
+	emitFile(t, src, insrc)
+	indep := filepath.Join("testdata", "dep.go")
+	dep := filepath.Join(depdir, "dep.go")
+	emitFile(t, dep, indep)
+
+	// Emit go.mod.
+	mod := filepath.Join(subdir, "go.mod")
+	modsrc := "\nmodule " + mainPkgPath + "\n\ngo 1.19\n"
+	if err := os.WriteFile(mod, []byte(modsrc), 0666); err != nil {
+		t.Fatal(err)
+	}
+	exepath := filepath.Join(subdir, prog+".exe")
+	bargs := []string{"build", "-cover", "-o", exepath}
+	bargs = append(bargs, flags...)
+	gobuild(t, subdir, bargs)
+	return exepath, subdir
+}
+
+type state struct {
+	dir      string
+	exedir1  string
+	exedir2  string
+	exedir3  string
+	exepath1 string
+	exepath2 string
+	exepath3 string
+	tool     string
+	outdirs  [4]string
+}
+
+const debugWorkDir = false
+
+func TestCovTool(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+	if !goexperiment.CoverageRedesign {
+		t.Skipf("stubbed out due to goexperiment.CoverageRedesign=false")
+	}
+	dir := tempDir(t)
+	if testing.Short() {
+		t.Skip()
+	}
+	if debugWorkDir {
+		// debugging
+		dir = "/tmp/qqq"
+		os.RemoveAll(dir)
+		os.Mkdir(dir, 0777)
+	}
+
+	s := state{
+		dir: dir,
+	}
+	s.exepath1, s.exedir1 = buildProg(t, "prog1", dir, "", nil)
+	s.exepath2, s.exedir2 = buildProg(t, "prog2", dir, "", nil)
+	flags := []string{"-covermode=atomic"}
+	s.exepath3, s.exedir3 = buildProg(t, "prog1", dir, "atomic", flags)
+
+	// Reuse unit test executable as tool to be tested.
+	s.tool = testcovdata(t)
+
+	// Create a few coverage output dirs.
+	for i := 0; i < 4; i++ {
+		d := filepath.Join(dir, fmt.Sprintf("covdata%d", i))
+		s.outdirs[i] = d
+		if err := os.Mkdir(d, 0777); err != nil {
+			t.Fatalf("can't create outdir %s: %v", d, err)
+		}
+	}
+
+	// Run instrumented program to generate some coverage data output files,
+	// as follows:
+	//
+	//   <tmp>/covdata0   -- prog1.go compiled -cover
+	//   <tmp>/covdata1   -- prog1.go compiled -cover
+	//   <tmp>/covdata2   -- prog1.go compiled -covermode=atomic
+	//   <tmp>/covdata3   -- prog1.go compiled -covermode=atomic
+	//
+	for m := 0; m < 2; m++ {
+		for k := 0; k < 2; k++ {
+			args := []string{}
+			if k != 0 {
+				args = append(args, "foo", "bar")
+			}
+			for i := 0; i <= k; i++ {
+				exepath := s.exepath1
+				if m != 0 {
+					exepath = s.exepath3
+				}
+				cmd := testenv.Command(t, exepath, args...)
+				cmd.Env = append(cmd.Env, "GOCOVERDIR="+s.outdirs[m*2+k])
+				b, err := cmd.CombinedOutput()
+				if len(b) != 0 {
+					t.Logf("## instrumented run output:\n%s", b)
+				}
+				if err != nil {
+					t.Fatalf("instrumented run error: %v", err)
+				}
+			}
+		}
+	}
+
+	// At this point we can fork off a bunch of child tests
+	// to check different tool modes.
+	t.Run("MergeSimple", func(t *testing.T) {
+		t.Parallel()
+		testMergeSimple(t, s, s.outdirs[0], s.outdirs[1], "set")
+		testMergeSimple(t, s, s.outdirs[2], s.outdirs[3], "atomic")
+	})
+	t.Run("MergeSelect", func(t *testing.T) {
+		t.Parallel()
+		testMergeSelect(t, s, s.outdirs[0], s.outdirs[1], "set")
+		testMergeSelect(t, s, s.outdirs[2], s.outdirs[3], "atomic")
+	})
+	t.Run("MergePcombine", func(t *testing.T) {
+		t.Parallel()
+		testMergeCombinePrograms(t, s)
+	})
+	t.Run("Dump", func(t *testing.T) {
+		t.Parallel()
+		testDump(t, s)
+	})
+	t.Run("Percent", func(t *testing.T) {
+		t.Parallel()
+		testPercent(t, s)
+	})
+	t.Run("PkgList", func(t *testing.T) {
+		t.Parallel()
+		testPkgList(t, s)
+	})
+	t.Run("Textfmt", func(t *testing.T) {
+		t.Parallel()
+		testTextfmt(t, s)
+	})
+	t.Run("Subtract", func(t *testing.T) {
+		t.Parallel()
+		testSubtract(t, s)
+	})
+	t.Run("Intersect", func(t *testing.T) {
+		t.Parallel()
+		testIntersect(t, s, s.outdirs[0], s.outdirs[1], "set")
+		testIntersect(t, s, s.outdirs[2], s.outdirs[3], "atomic")
+	})
+	t.Run("CounterClash", func(t *testing.T) {
+		t.Parallel()
+		testCounterClash(t, s)
+	})
+	t.Run("TestEmpty", func(t *testing.T) {
+		t.Parallel()
+		testEmpty(t, s)
+	})
+	t.Run("TestCommandLineErrors", func(t *testing.T) {
+		t.Parallel()
+		testCommandLineErrors(t, s, s.outdirs[0])
+	})
+}
+
+const showToolInvocations = true
+
+func runToolOp(t *testing.T, s state, op string, args []string) []string {
+	// Perform tool run.
+	t.Helper()
+	args = append([]string{op}, args...)
+	if showToolInvocations {
+		t.Logf("%s cmd is: %s %+v", op, s.tool, args)
+	}
+	cmd := testenv.Command(t, s.tool, args...)
+	b, err := cmd.CombinedOutput()
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "## %s output: %s\n", op, string(b))
+		t.Fatalf("%q run error: %v", op, err)
+	}
+	output := strings.TrimSpace(string(b))
+	lines := strings.Split(output, "\n")
+	if len(lines) == 1 && lines[0] == "" {
+		lines = nil
+	}
+	return lines
+}
+
+func testDump(t *testing.T, s state) {
+	// Run the dumper on the two dirs we generated.
+	dargs := []string{"-pkg=" + mainPkgPath, "-live", "-i=" + s.outdirs[0] + "," + s.outdirs[1]}
+	lines := runToolOp(t, s, "debugdump", dargs)
+
+	// Sift through the output to make sure it has some key elements.
+	testpoints := []struct {
+		tag string
+		re  *regexp.Regexp
+	}{
+		{
+			"args",
+			regexp.MustCompile(`^data file .+ GOOS=.+ GOARCH=.+ program args: .+$`),
+		},
+		{
+			"main package",
+			regexp.MustCompile(`^Package path: ` + mainPkgPath + `\s*$`),
+		},
+		{
+			"main function",
+			regexp.MustCompile(`^Func: main\s*$`),
+		},
+	}
+
+	bad := false
+	for _, testpoint := range testpoints {
+		found := false
+		for _, line := range lines {
+			if m := testpoint.re.FindStringSubmatch(line); m != nil {
+				found = true
+				break
+			}
+		}
+		if !found {
+			t.Errorf("dump output regexp match failed for %q", testpoint.tag)
+			bad = true
+		}
+	}
+	if bad {
+		dumplines(lines)
+	}
+}
+
+func testPercent(t *testing.T, s state) {
+	// Run the dumper on the two dirs we generated.
+	dargs := []string{"-pkg=" + mainPkgPath, "-i=" + s.outdirs[0] + "," + s.outdirs[1]}
+	lines := runToolOp(t, s, "percent", dargs)
+
+	// Sift through the output to make sure it has the needful.
+	testpoints := []struct {
+		tag string
+		re  *regexp.Regexp
+	}{
+		{
+			"statement coverage percent",
+			regexp.MustCompile(`coverage: \d+\.\d% of statements\s*$`),
+		},
+	}
+
+	bad := false
+	for _, testpoint := range testpoints {
+		found := false
+		for _, line := range lines {
+			if m := testpoint.re.FindStringSubmatch(line); m != nil {
+				found = true
+				break
+			}
+		}
+		if !found {
+			t.Errorf("percent output regexp match failed for %s", testpoint.tag)
+			bad = true
+		}
+	}
+	if bad {
+		dumplines(lines)
+	}
+}
+
+func testPkgList(t *testing.T, s state) {
+	dargs := []string{"-i=" + s.outdirs[0] + "," + s.outdirs[1]}
+	lines := runToolOp(t, s, "pkglist", dargs)
+
+	want := []string{mainPkgPath, mainPkgPath + "/dep"}
+	bad := false
+	if len(lines) != 2 {
+		t.Errorf("expect pkglist to return two lines")
+		bad = true
+	} else {
+		for i := 0; i < 2; i++ {
+			lines[i] = strings.TrimSpace(lines[i])
+			if want[i] != lines[i] {
+				t.Errorf("line %d want %s got %s", i, want[i], lines[i])
+				bad = true
+			}
+		}
+	}
+	if bad {
+		dumplines(lines)
+	}
+}
+
+func testTextfmt(t *testing.T, s state) {
+	outf := s.dir + "/" + "t.txt"
+	dargs := []string{"-pkg=" + mainPkgPath, "-i=" + s.outdirs[0] + "," + s.outdirs[1],
+		"-o", outf}
+	lines := runToolOp(t, s, "textfmt", dargs)
+
+	// No output expected.
+	if len(lines) != 0 {
+		dumplines(lines)
+		t.Errorf("unexpected output from go tool covdata textfmt")
+	}
+
+	// Open and read the first few bits of the file.
+	payload, err := os.ReadFile(outf)
+	if err != nil {
+		t.Errorf("opening %s: %v\n", outf, err)
+	}
+	lines = strings.Split(string(payload), "\n")
+	want0 := "mode: set"
+	if lines[0] != want0 {
+		dumplines(lines[0:10])
+		t.Errorf("textfmt: want %s got %s", want0, lines[0])
+	}
+	want1 := mainPkgPath + "/prog1.go:13.14,15.2 1 1"
+	if lines[1] != want1 {
+		dumplines(lines[0:10])
+		t.Errorf("textfmt: want %s got %s", want1, lines[1])
+	}
+}
+
+func dumplines(lines []string) {
+	for i := range lines {
+		fmt.Fprintf(os.Stderr, "%s\n", lines[i])
+	}
+}
+
+type dumpCheck struct {
+	tag     string
+	re      *regexp.Regexp
+	negate  bool
+	nonzero bool
+	zero    bool
+}
+
+// runDumpChecks examines the output of "go tool covdata debugdump"
+// for a given output directory, looking for the presence or absence
+// of specific markers.
+func runDumpChecks(t *testing.T, s state, dir string, flags []string, checks []dumpCheck) {
+	dargs := []string{"-i", dir}
+	dargs = append(dargs, flags...)
+	lines := runToolOp(t, s, "debugdump", dargs)
+	if len(lines) == 0 {
+		t.Fatalf("dump run produced no output")
+	}
+
+	bad := false
+	for _, check := range checks {
+		found := false
+		for _, line := range lines {
+			if m := check.re.FindStringSubmatch(line); m != nil {
+				found = true
+				if check.negate {
+					t.Errorf("tag %q: unexpected match", check.tag)
+					bad = true
+
+				}
+				if check.nonzero || check.zero {
+					if len(m) < 2 {
+						t.Errorf("tag %s: submatch failed (short m)", check.tag)
+						bad = true
+						continue
+					}
+					if m[1] == "" {
+						t.Errorf("tag %s: submatch failed", check.tag)
+						bad = true
+						continue
+					}
+					i, err := strconv.Atoi(m[1])
+					if err != nil {
+						t.Errorf("tag %s: match Atoi failed on %s",
+							check.tag, m[1])
+						continue
+					}
+					if check.zero && i != 0 {
+						t.Errorf("tag %s: match zero failed on %s",
+							check.tag, m[1])
+					} else if check.nonzero && i == 0 {
+						t.Errorf("tag %s: match nonzero failed on %s",
+							check.tag, m[1])
+					}
+				}
+				break
+			}
+		}
+		if !found && !check.negate {
+			t.Errorf("dump output regexp match failed for %s", check.tag)
+			bad = true
+		}
+	}
+	if bad {
+		fmt.Printf("output from 'dump' run:\n")
+		dumplines(lines)
+	}
+}
+
+func testMergeSimple(t *testing.T, s state, indir1, indir2, tag string) {
+	outdir := filepath.Join(s.dir, "simpleMergeOut"+tag)
+	if err := os.Mkdir(outdir, 0777); err != nil {
+		t.Fatalf("can't create outdir %s: %v", outdir, err)
+	}
+
+	// Merge the two dirs into a final result.
+	ins := fmt.Sprintf("-i=%s,%s", indir1, indir2)
+	out := fmt.Sprintf("-o=%s", outdir)
+	margs := []string{ins, out}
+	lines := runToolOp(t, s, "merge", margs)
+	if len(lines) != 0 {
+		t.Errorf("merge run produced %d lines of unexpected output", len(lines))
+		dumplines(lines)
+	}
+
+	// We expect the merge tool to produce exactly two files: a meta
+	// data file and a counter file. If we get more than just this one
+	// pair, something went wrong.
+	podlist, err := pods.CollectPods([]string{outdir}, true)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if len(podlist) != 1 {
+		t.Fatalf("expected 1 pod, got %d pods", len(podlist))
+	}
+	ncdfs := len(podlist[0].CounterDataFiles)
+	if ncdfs != 1 {
+		t.Fatalf("expected 1 counter data file, got %d", ncdfs)
+	}
+
+	// Sift through the output to make sure it has some key elements.
+	// In particular, we want to see entries for all three functions
+	// ("first", "second", and "third").
+	testpoints := []dumpCheck{
+		{
+			tag: "first function",
+			re:  regexp.MustCompile(`^Func: first\s*$`),
+		},
+		{
+			tag: "second function",
+			re:  regexp.MustCompile(`^Func: second\s*$`),
+		},
+		{
+			tag: "third function",
+			re:  regexp.MustCompile(`^Func: third\s*$`),
+		},
+		{
+			tag:     "third function unit 0",
+			re:      regexp.MustCompile(`^0: L23:C23 -- L24:C12 NS=1 = (\d+)$`),
+			nonzero: true,
+		},
+		{
+			tag:     "third function unit 1",
+			re:      regexp.MustCompile(`^1: L27:C2 -- L28:C10 NS=2 = (\d+)$`),
+			nonzero: true,
+		},
+		{
+			tag:     "third function unit 2",
+			re:      regexp.MustCompile(`^2: L24:C12 -- L26:C3 NS=1 = (\d+)$`),
+			nonzero: true,
+		},
+	}
+	flags := []string{"-live", "-pkg=" + mainPkgPath}
+	runDumpChecks(t, s, outdir, flags, testpoints)
+}
+
+func testMergeSelect(t *testing.T, s state, indir1, indir2 string, tag string) {
+	outdir := filepath.Join(s.dir, "selectMergeOut"+tag)
+	if err := os.Mkdir(outdir, 0777); err != nil {
+		t.Fatalf("can't create outdir %s: %v", outdir, err)
+	}
+
+	// Merge two input dirs into a final result, but filter
+	// based on package.
+	ins := fmt.Sprintf("-i=%s,%s", indir1, indir2)
+	out := fmt.Sprintf("-o=%s", outdir)
+	margs := []string{"-pkg=" + mainPkgPath + "/dep", ins, out}
+	lines := runToolOp(t, s, "merge", margs)
+	if len(lines) != 0 {
+		t.Errorf("merge run produced %d lines of unexpected output", len(lines))
+		dumplines(lines)
+	}
+
+	// Dump the files in the merged output dir and examine the result.
+	// We expect to see only the functions in package "dep".
+	dargs := []string{"-i=" + outdir}
+	lines = runToolOp(t, s, "debugdump", dargs)
+	if len(lines) == 0 {
+		t.Fatalf("dump run produced no output")
+	}
+	want := map[string]int{
+		"Package path: " + mainPkgPath + "/dep": 0,
+		"Func: Dep1":                            0,
+		"Func: PDep":                            0,
+	}
+	bad := false
+	for _, line := range lines {
+		if v, ok := want[line]; ok {
+			if v != 0 {
+				t.Errorf("duplicate line %s", line)
+				bad = true
+				break
+			}
+			want[line] = 1
+			continue
+		}
+		// no other functions or packages expected.
+		if strings.HasPrefix(line, "Func:") || strings.HasPrefix(line, "Package path:") {
+			t.Errorf("unexpected line: %s", line)
+			bad = true
+			break
+		}
+	}
+	if bad {
+		dumplines(lines)
+	}
+}
+
+func testMergeCombinePrograms(t *testing.T, s state) {
+
+	// Run the new program, emitting output into a new set
+	// of outdirs.
+	runout := [2]string{}
+	for k := 0; k < 2; k++ {
+		runout[k] = filepath.Join(s.dir, fmt.Sprintf("newcovdata%d", k))
+		if err := os.Mkdir(runout[k], 0777); err != nil {
+			t.Fatalf("can't create outdir %s: %v", runout[k], err)
+		}
+		args := []string{}
+		if k != 0 {
+			args = append(args, "foo", "bar")
+		}
+		cmd := testenv.Command(t, s.exepath2, args...)
+		cmd.Env = append(cmd.Env, "GOCOVERDIR="+runout[k])
+		b, err := cmd.CombinedOutput()
+		if len(b) != 0 {
+			t.Logf("## instrumented run output:\n%s", b)
+		}
+		if err != nil {
+			t.Fatalf("instrumented run error: %v", err)
+		}
+	}
+
+	// Create out dir for -pcombine merge.
+	moutdir := filepath.Join(s.dir, "mergeCombineOut")
+	if err := os.Mkdir(moutdir, 0777); err != nil {
+		t.Fatalf("can't create outdir %s: %v", moutdir, err)
+	}
+
+	// Run a merge over both programs, using the -pcombine
+	// flag to do maximal combining.
+	ins := fmt.Sprintf("-i=%s,%s,%s,%s", s.outdirs[0], s.outdirs[1],
+		runout[0], runout[1])
+	out := fmt.Sprintf("-o=%s", moutdir)
+	margs := []string{"-pcombine", ins, out}
+	lines := runToolOp(t, s, "merge", margs)
+	if len(lines) != 0 {
+		t.Errorf("merge run produced unexpected output: %v", lines)
+	}
+
+	// We expect the merge tool to produce exacty two files: a meta
+	// data file and a counter file. If we get more than just this one
+	// pair, something went wrong.
+	podlist, err := pods.CollectPods([]string{moutdir}, true)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if len(podlist) != 1 {
+		t.Fatalf("expected 1 pod, got %d pods", len(podlist))
+	}
+	ncdfs := len(podlist[0].CounterDataFiles)
+	if ncdfs != 1 {
+		t.Fatalf("expected 1 counter data file, got %d", ncdfs)
+	}
+
+	// Sift through the output to make sure it has some key elements.
+	testpoints := []dumpCheck{
+		{
+			tag: "first function",
+			re:  regexp.MustCompile(`^Func: first\s*$`),
+		},
+		{
+			tag: "sixth function",
+			re:  regexp.MustCompile(`^Func: sixth\s*$`),
+		},
+	}
+
+	flags := []string{"-live", "-pkg=" + mainPkgPath}
+	runDumpChecks(t, s, moutdir, flags, testpoints)
+}
+
+func testSubtract(t *testing.T, s state) {
+	// Create out dir for subtract merge.
+	soutdir := filepath.Join(s.dir, "subtractOut")
+	if err := os.Mkdir(soutdir, 0777); err != nil {
+		t.Fatalf("can't create outdir %s: %v", soutdir, err)
+	}
+
+	// Subtract the two dirs into a final result.
+	ins := fmt.Sprintf("-i=%s,%s", s.outdirs[0], s.outdirs[1])
+	out := fmt.Sprintf("-o=%s", soutdir)
+	sargs := []string{ins, out}
+	lines := runToolOp(t, s, "subtract", sargs)
+	if len(lines) != 0 {
+		t.Errorf("subtract run produced unexpected output: %+v", lines)
+	}
+
+	// Dump the files in the subtract output dir and examine the result.
+	dargs := []string{"-pkg=" + mainPkgPath, "-live", "-i=" + soutdir}
+	lines = runToolOp(t, s, "debugdump", dargs)
+	if len(lines) == 0 {
+		t.Errorf("dump run produced no output")
+	}
+
+	// Vet the output.
+	testpoints := []dumpCheck{
+		{
+			tag: "first function",
+			re:  regexp.MustCompile(`^Func: first\s*$`),
+		},
+		{
+			tag: "dep function",
+			re:  regexp.MustCompile(`^Func: Dep1\s*$`),
+		},
+		{
+			tag: "third function",
+			re:  regexp.MustCompile(`^Func: third\s*$`),
+		},
+		{
+			tag:  "third function unit 0",
+			re:   regexp.MustCompile(`^0: L23:C23 -- L24:C12 NS=1 = (\d+)$`),
+			zero: true,
+		},
+		{
+			tag:     "third function unit 1",
+			re:      regexp.MustCompile(`^1: L27:C2 -- L28:C10 NS=2 = (\d+)$`),
+			nonzero: true,
+		},
+		{
+			tag:  "third function unit 2",
+			re:   regexp.MustCompile(`^2: L24:C12 -- L26:C3 NS=1 = (\d+)$`),
+			zero: true,
+		},
+	}
+	flags := []string{}
+	runDumpChecks(t, s, soutdir, flags, testpoints)
+}
+
+func testIntersect(t *testing.T, s state, indir1, indir2, tag string) {
+	// Create out dir for intersection.
+	ioutdir := filepath.Join(s.dir, "intersectOut"+tag)
+	if err := os.Mkdir(ioutdir, 0777); err != nil {
+		t.Fatalf("can't create outdir %s: %v", ioutdir, err)
+	}
+
+	// Intersect the two dirs into a final result.
+	ins := fmt.Sprintf("-i=%s,%s", indir1, indir2)
+	out := fmt.Sprintf("-o=%s", ioutdir)
+	sargs := []string{ins, out}
+	lines := runToolOp(t, s, "intersect", sargs)
+	if len(lines) != 0 {
+		t.Errorf("intersect run produced unexpected output: %+v", lines)
+	}
+
+	// Dump the files in the subtract output dir and examine the result.
+	dargs := []string{"-pkg=" + mainPkgPath, "-live", "-i=" + ioutdir}
+	lines = runToolOp(t, s, "debugdump", dargs)
+	if len(lines) == 0 {
+		t.Errorf("dump run produced no output")
+	}
+
+	// Vet the output.
+	testpoints := []dumpCheck{
+		{
+			tag:    "first function",
+			re:     regexp.MustCompile(`^Func: first\s*$`),
+			negate: true,
+		},
+		{
+			tag: "third function",
+			re:  regexp.MustCompile(`^Func: third\s*$`),
+		},
+	}
+	flags := []string{"-live"}
+	runDumpChecks(t, s, ioutdir, flags, testpoints)
+}
+
+func testCounterClash(t *testing.T, s state) {
+	// Create out dir.
+	ccoutdir := filepath.Join(s.dir, "ccOut")
+	if err := os.Mkdir(ccoutdir, 0777); err != nil {
+		t.Fatalf("can't create outdir %s: %v", ccoutdir, err)
+	}
+
+	// Try to merge covdata0 (from prog1.go -countermode=set) with
+	// covdata1 (from prog1.go -countermode=atomic"). This should
+	// produce a counter mode clash error.
+	ins := fmt.Sprintf("-i=%s,%s", s.outdirs[0], s.outdirs[3])
+	out := fmt.Sprintf("-o=%s", ccoutdir)
+	args := append([]string{}, "merge", ins, out, "-pcombine")
+	if debugtrace {
+		t.Logf("cc merge command is %s %v\n", s.tool, args)
+	}
+	cmd := testenv.Command(t, s.tool, args...)
+	b, err := cmd.CombinedOutput()
+	t.Logf("%% output: %s\n", string(b))
+	if err == nil {
+		t.Fatalf("clash merge passed unexpectedly")
+	}
+	got := string(b)
+	want := "counter mode clash while reading meta-data"
+	if !strings.Contains(got, want) {
+		t.Errorf("counter clash merge: wanted %s got %s", want, got)
+	}
+}
+
+func testEmpty(t *testing.T, s state) {
+
+	// Create a new empty directory.
+	empty := filepath.Join(s.dir, "empty")
+	if err := os.Mkdir(empty, 0777); err != nil {
+		t.Fatalf("can't create dir %s: %v", empty, err)
+	}
+
+	// Create out dir.
+	eoutdir := filepath.Join(s.dir, "emptyOut")
+	if err := os.Mkdir(eoutdir, 0777); err != nil {
+		t.Fatalf("can't create outdir %s: %v", eoutdir, err)
+	}
+
+	// Run various operations (merge, dump, textfmt, and so on)
+	// using the empty directory. We're not interested in the output
+	// here, just making sure that you can do these runs without
+	// any error or crash.
+
+	scenarios := []struct {
+		tag  string
+		args []string
+	}{
+		{
+			tag:  "merge",
+			args: []string{"merge", "-o", eoutdir},
+		},
+		{
+			tag:  "textfmt",
+			args: []string{"textfmt", "-o", filepath.Join(eoutdir, "foo.txt")},
+		},
+		{
+			tag:  "func",
+			args: []string{"func"},
+		},
+		{
+			tag:  "pkglist",
+			args: []string{"pkglist"},
+		},
+		{
+			tag:  "debugdump",
+			args: []string{"debugdump"},
+		},
+		{
+			tag:  "percent",
+			args: []string{"percent"},
+		},
+	}
+
+	for _, x := range scenarios {
+		ins := fmt.Sprintf("-i=%s", empty)
+		args := append([]string{}, x.args...)
+		args = append(args, ins)
+		if false {
+			t.Logf("cmd is %s %v\n", s.tool, args)
+		}
+		cmd := testenv.Command(t, s.tool, args...)
+		b, err := cmd.CombinedOutput()
+		t.Logf("%% output: %s\n", string(b))
+		if err != nil {
+			t.Fatalf("command %s %+v failed with %v",
+				s.tool, x.args, err)
+		}
+	}
+}
+
+func testCommandLineErrors(t *testing.T, s state, outdir string) {
+
+	// Create out dir.
+	eoutdir := filepath.Join(s.dir, "errorsOut")
+	if err := os.Mkdir(eoutdir, 0777); err != nil {
+		t.Fatalf("can't create outdir %s: %v", eoutdir, err)
+	}
+
+	// Run various operations (merge, dump, textfmt, and so on)
+	// using the empty directory. We're not interested in the output
+	// here, just making sure that you can do these runs without
+	// any error or crash.
+
+	scenarios := []struct {
+		tag  string
+		args []string
+		exp  string
+	}{
+		{
+			tag:  "input missing",
+			args: []string{"merge", "-o", eoutdir, "-i", "not there"},
+			exp:  "error: reading inputs: ",
+		},
+		{
+			tag:  "badv",
+			args: []string{"textfmt", "-i", outdir, "-v=abc"},
+		},
+	}
+
+	for _, x := range scenarios {
+		args := append([]string{}, x.args...)
+		if false {
+			t.Logf("cmd is %s %v\n", s.tool, args)
+		}
+		cmd := testenv.Command(t, s.tool, args...)
+		b, err := cmd.CombinedOutput()
+		if err == nil {
+			t.Logf("%% output: %s\n", string(b))
+			t.Fatalf("command %s %+v unexpectedly succeeded",
+				s.tool, x.args)
+		} else {
+			if !strings.Contains(string(b), x.exp) {
+				t.Fatalf("command %s %+v:\ngot:\n%s\nwanted to see: %v\n",
+					s.tool, x.args, string(b), x.exp)
+			}
+		}
+	}
+}
diff --git a/src/cmd/cover/cfg_test.go b/src/cmd/cover/cfg_test.go
new file mode 100644
index 0000000..0a29567
--- /dev/null
+++ b/src/cmd/cover/cfg_test.go
@@ -0,0 +1,186 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main_test
+
+import (
+	"encoding/json"
+	"fmt"
+	"internal/coverage"
+	"internal/testenv"
+	"os"
+	"path/filepath"
+	"strings"
+	"testing"
+)
+
+func writeFile(t *testing.T, path string, contents []byte) {
+	if err := os.WriteFile(path, contents, 0666); err != nil {
+		t.Fatalf("os.WriteFile(%s) failed: %v", path, err)
+	}
+}
+
+func writePkgConfig(t *testing.T, outdir, tag, ppath, pname string, gran string) string {
+	incfg := filepath.Join(outdir, tag+"incfg.txt")
+	outcfg := filepath.Join(outdir, "outcfg.txt")
+	p := coverage.CoverPkgConfig{
+		PkgPath:     ppath,
+		PkgName:     pname,
+		Granularity: gran,
+		OutConfig:   outcfg,
+	}
+	data, err := json.Marshal(p)
+	if err != nil {
+		t.Fatalf("json.Marshal failed: %v", err)
+	}
+	writeFile(t, incfg, data)
+	return incfg
+}
+
+func writeOutFileList(t *testing.T, infiles []string, outdir, tag string) ([]string, string) {
+	outfilelist := filepath.Join(outdir, tag+"outfilelist.txt")
+	var sb strings.Builder
+	outfs := []string{}
+	for _, inf := range infiles {
+		base := filepath.Base(inf)
+		of := filepath.Join(outdir, tag+".cov."+base)
+		outfs = append(outfs, of)
+		fmt.Fprintf(&sb, "%s\n", of)
+	}
+	if err := os.WriteFile(outfilelist, []byte(sb.String()), 0666); err != nil {
+		t.Fatalf("writing %s: %v", outfilelist, err)
+	}
+	return outfs, outfilelist
+}
+
+func runPkgCover(t *testing.T, outdir string, tag string, incfg string, mode string, infiles []string, errExpected bool) ([]string, string, string) {
+	// Write the pkgcfg file.
+	outcfg := filepath.Join(outdir, "outcfg.txt")
+
+	// Form up the arguments and run the tool.
+	outfiles, outfilelist := writeOutFileList(t, infiles, outdir, tag)
+	args := []string{"-pkgcfg", incfg, "-mode=" + mode, "-var=var" + tag, "-outfilelist", outfilelist}
+	args = append(args, infiles...)
+	cmd := testenv.Command(t, testcover(t), args...)
+	if errExpected {
+		errmsg := runExpectingError(cmd, t)
+		return nil, "", errmsg
+	} else {
+		run(cmd, t)
+		return outfiles, outcfg, ""
+	}
+}
+
+// Set to true when debugging unit test (to inspect debris, etc).
+// Note that this functionality does not work on windows.
+const debugWorkDir = false
+
+func TestCoverWithCfg(t *testing.T) {
+	testenv.MustHaveGoRun(t)
+
+	t.Parallel()
+
+	// Subdir in testdata that has our input files of interest.
+	tpath := filepath.Join("testdata", "pkgcfg")
+
+	// Helper to collect input paths (go files) for a subdir in 'pkgcfg'
+	pfiles := func(subdir string) []string {
+		de, err := os.ReadDir(filepath.Join(tpath, subdir))
+		if err != nil {
+			t.Fatalf("reading subdir %s: %v", subdir, err)
+		}
+		paths := []string{}
+		for _, e := range de {
+			if !strings.HasSuffix(e.Name(), ".go") || strings.HasSuffix(e.Name(), "_test.go") {
+				continue
+			}
+			paths = append(paths, filepath.Join(tpath, subdir, e.Name()))
+		}
+		return paths
+	}
+
+	dir := tempDir(t)
+	if debugWorkDir {
+		dir = "/tmp/qqq"
+		os.RemoveAll(dir)
+		os.Mkdir(dir, 0777)
+	}
+	instdira := filepath.Join(dir, "insta")
+	if err := os.Mkdir(instdira, 0777); err != nil {
+		t.Fatal(err)
+	}
+
+	scenarios := []struct {
+		mode, gran string
+	}{
+		{
+			mode: "count",
+			gran: "perblock",
+		},
+		{
+			mode: "set",
+			gran: "perfunc",
+		},
+		{
+			mode: "regonly",
+			gran: "perblock",
+		},
+	}
+
+	var incfg string
+	for _, scenario := range scenarios {
+		// Instrument package "a", producing a set of instrumented output
+		// files and an 'output config' file to pass on to the compiler.
+		ppath := "cfg/a"
+		pname := "a"
+		mode := scenario.mode
+		gran := scenario.gran
+		tag := mode + "_" + gran
+		incfg = writePkgConfig(t, instdira, tag, ppath, pname, gran)
+		ofs, outcfg, _ := runPkgCover(t, instdira, tag, incfg, mode,
+			pfiles("a"), false)
+		t.Logf("outfiles: %+v\n", ofs)
+
+		// Run the compiler on the files to make sure the result is
+		// buildable.
+		bargs := []string{"tool", "compile", "-p", "a", "-coveragecfg", outcfg}
+		bargs = append(bargs, ofs...)
+		cmd := testenv.Command(t, testenv.GoToolPath(t), bargs...)
+		cmd.Dir = instdira
+		run(cmd, t)
+	}
+
+	// Do some error testing to ensure that various bad options and
+	// combinations are properly rejected.
+
+	// Expect error if config file inaccessible/unreadable.
+	mode := "atomic"
+	errExpected := true
+	tag := "errors"
+	_, _, errmsg := runPkgCover(t, instdira, tag, "/not/a/file", mode,
+		pfiles("a"), errExpected)
+	want := "error reading pkgconfig file"
+	if !strings.Contains(errmsg, want) {
+		t.Errorf("'bad config file' test: wanted %s got %s", want, errmsg)
+	}
+
+	// Expect err if config file contains unknown stuff.
+	t.Logf("mangling in config")
+	writeFile(t, incfg, []byte("blah=foo\n"))
+	_, _, errmsg = runPkgCover(t, instdira, tag, incfg, mode,
+		pfiles("a"), errExpected)
+	want = "error reading pkgconfig file"
+	if !strings.Contains(errmsg, want) {
+		t.Errorf("'bad config file' test: wanted %s got %s", want, errmsg)
+	}
+
+	// Expect error on empty config file.
+	t.Logf("writing empty config")
+	writeFile(t, incfg, []byte("\n"))
+	_, _, errmsg = runPkgCover(t, instdira, tag, incfg, mode,
+		pfiles("a"), errExpected)
+	if !strings.Contains(errmsg, want) {
+		t.Errorf("'bad config file' test: wanted %s got %s", want, errmsg)
+	}
+}
diff --git a/src/cmd/cover/cover.go b/src/cmd/cover/cover.go
index 86ef128..74bb500 100644
--- a/src/cmd/cover/cover.go
+++ b/src/cmd/cover/cover.go
@@ -6,15 +6,22 @@
 
 import (
 	"bytes"
+	"encoding/json"
 	"flag"
 	"fmt"
 	"go/ast"
 	"go/parser"
 	"go/token"
+	"internal/coverage"
+	"internal/coverage/encodemeta"
+	"internal/coverage/slicewriter"
 	"io"
 	"log"
 	"os"
+	"path/filepath"
 	"sort"
+	"strconv"
+	"strings"
 
 	"cmd/internal/edit"
 	"cmd/internal/objabi"
@@ -35,8 +42,16 @@
 	go tool cover -func=c.out
 
 Finally, to generate modified source code with coverage annotations
-(what go test -cover does):
-	go tool cover -mode=set -var=CoverageVariableName program.go
+for a package (what go test -cover does):
+	go tool cover -mode=set -var=CoverageVariableName \
+		-pkgcfg=<config> -outfilelist=<file> file1.go ... fileN.go
+
+where -pkgcfg points to a file containing the package path,
+package name, module path, and related info from "go build",
+and -outfilelist points to a file containing the filenames
+of the instrumented output files (one per input file).
+See https://pkg.go.dev/internal/coverage#CoverPkgConfig for
+more on the package config.
 `
 
 func usage() {
@@ -48,13 +63,19 @@
 }
 
 var (
-	mode    = flag.String("mode", "", "coverage mode: set, count, atomic")
-	varVar  = flag.String("var", "GoCover", "name of coverage variable to generate")
-	output  = flag.String("o", "", "file for output; default: stdout")
-	htmlOut = flag.String("html", "", "generate HTML representation of coverage profile")
-	funcOut = flag.String("func", "", "output coverage profile information for each function")
+	mode        = flag.String("mode", "", "coverage mode: set, count, atomic")
+	varVar      = flag.String("var", "GoCover", "name of coverage variable to generate")
+	output      = flag.String("o", "", "file for output")
+	outfilelist = flag.String("outfilelist", "", "file containing list of output files (one per line) if -pkgcfg is in use")
+	htmlOut     = flag.String("html", "", "generate HTML representation of coverage profile")
+	funcOut     = flag.String("func", "", "output coverage profile information for each function")
+	pkgcfg      = flag.String("pkgcfg", "", "enable full-package instrumentation mode using params from specified config file")
 )
 
+var pkgconfig coverage.CoverPkgConfig
+
+var outputfiles []string // set when -pkgcfg is in use
+
 var profile string // The profile to read; the value of -html or -func
 
 var counterStmt func(*File, string) string
@@ -83,7 +104,7 @@
 
 	// Generate coverage-annotated source.
 	if *mode != "" {
-		annotate(flag.Arg(0))
+		annotate(flag.Args())
 		return
 	}
 
@@ -127,14 +148,40 @@
 			counterStmt = incCounterStmt
 		case "atomic":
 			counterStmt = atomicCounterStmt
+		case "regonly", "testmain":
+			counterStmt = nil
 		default:
 			return fmt.Errorf("unknown -mode %v", *mode)
 		}
 
 		if flag.NArg() == 0 {
-			return fmt.Errorf("missing source file")
-		} else if flag.NArg() == 1 {
-			return nil
+			return fmt.Errorf("missing source file(s)")
+		} else {
+			if *pkgcfg != "" {
+				if *output != "" {
+					return fmt.Errorf("please use '-outfilelist' flag instead of '-o'")
+				}
+				var err error
+				if outputfiles, err = readOutFileList(*outfilelist); err != nil {
+					return err
+				}
+				numInputs := len(flag.Args())
+				numOutputs := len(outputfiles)
+				if numOutputs != numInputs {
+					return fmt.Errorf("number of output files (%d) not equal to number of input files (%d)", numOutputs, numInputs)
+				}
+				if err := readPackageConfig(*pkgcfg); err != nil {
+					return err
+				}
+				return nil
+			} else {
+				if *outfilelist != "" {
+					return fmt.Errorf("'-outfilelist' flag applicable only when -pkgcfg used")
+				}
+			}
+			if flag.NArg() == 1 {
+				return nil
+			}
 		}
 	} else if flag.NArg() == 0 {
 		return nil
@@ -142,6 +189,28 @@
 	return fmt.Errorf("too many arguments")
 }
 
+func readOutFileList(path string) ([]string, error) {
+	data, err := os.ReadFile(path)
+	if err != nil {
+		return nil, fmt.Errorf("error reading -outfilelist file %q: %v", path, err)
+	}
+	return strings.Split(strings.TrimSpace(string(data)), "\n"), nil
+}
+
+func readPackageConfig(path string) error {
+	data, err := os.ReadFile(path)
+	if err != nil {
+		return fmt.Errorf("error reading pkgconfig file %q: %v", path, err)
+	}
+	if err := json.Unmarshal(data, &pkgconfig); err != nil {
+		return fmt.Errorf("error reading pkgconfig file %q: %v", path, err)
+	}
+	if pkgconfig.Granularity != "perblock" && pkgconfig.Granularity != "perfunc" {
+		return fmt.Errorf(`%s: pkgconfig requires perblock/perfunc value`, path)
+	}
+	return nil
+}
+
 // Block represents the information about a basic block to be recorded in the analysis.
 // Note: Our definition of basic block is based on control structures; we don't break
 // apart && and ||. We could but it doesn't seem important enough to bother.
@@ -151,6 +220,18 @@
 	numStmt   int
 }
 
+// Package holds package-specific state.
+type Package struct {
+	mdb            *encodemeta.CoverageMetaDataBuilder
+	counterLengths []int
+}
+
+// Function holds func-specific state.
+type Func struct {
+	units      []coverage.CoverableUnit
+	counterVar string
+}
+
 // File is a wrapper for the state of a file used in the parser.
 // The basic parse tree walker is a method of this type.
 type File struct {
@@ -160,6 +241,9 @@
 	blocks  []Block
 	content []byte
 	edit    *edit.Buffer
+	mdb     *encodemeta.CoverageMetaDataBuilder
+	fn      Func
+	pkg     *Package
 }
 
 // findText finds text in the original source, starting at pos.
@@ -294,14 +378,228 @@
 		}
 	case *ast.FuncDecl:
 		// Don't annotate functions with blank names - they cannot be executed.
-		if n.Name.Name == "_" {
+		// Similarly for bodyless funcs.
+		if n.Name.Name == "_" || n.Body == nil {
 			return nil
 		}
+		fname := n.Name.Name
+		// Skip AddUint32 and StoreUint32 if we're instrumenting
+		// sync/atomic itself in atomic mode (out of an abundance of
+		// caution), since as part of the instrumentation process we
+		// add calls to AddUint32/StoreUint32, and we don't want to
+		// somehow create an infinite loop.
+		//
+		// Note that in the current implementation (Go 1.20) both
+		// routines are assembly stubs that forward calls to the
+		// runtime/internal/atomic equivalents, hence the infinite
+		// loop scenario is purely theoretical (maybe if in some
+		// future implementation one of these functions might be
+		// written in Go). See #57445 for more details.
+		if atomicOnAtomic() && (fname == "AddUint32" || fname == "StoreUint32") {
+			return nil
+		}
+		// Determine proper function or method name.
+		if r := n.Recv; r != nil && len(r.List) == 1 {
+			t := r.List[0].Type
+			star := ""
+			if p, _ := t.(*ast.StarExpr); p != nil {
+				t = p.X
+				star = "*"
+			}
+			if p, _ := t.(*ast.Ident); p != nil {
+				fname = star + p.Name + "." + fname
+			}
+		}
+		walkBody := true
+		if *pkgcfg != "" {
+			f.preFunc(n, fname)
+			if pkgconfig.Granularity == "perfunc" {
+				walkBody = false
+			}
+		}
+		if walkBody {
+			ast.Walk(f, n.Body)
+		}
+		if *pkgcfg != "" {
+			flit := false
+			f.postFunc(n, fname, flit, n.Body)
+		}
+		return nil
+	case *ast.FuncLit:
+		// For function literals enclosed in functions, just glom the
+		// code for the literal in with the enclosing function (for now).
+		if f.fn.counterVar != "" {
+			return f
+		}
+
+		// Hack: function literals aren't named in the go/ast representation,
+		// and we don't know what name the compiler will choose. For now,
+		// just make up a descriptive name.
+		pos := n.Pos()
+		p := f.fset.File(pos).Position(pos)
+		fname := fmt.Sprintf("func.L%d.C%d", p.Line, p.Column)
+		if *pkgcfg != "" {
+			f.preFunc(n, fname)
+		}
+		if pkgconfig.Granularity != "perfunc" {
+			ast.Walk(f, n.Body)
+		}
+		if *pkgcfg != "" {
+			flit := true
+			f.postFunc(n, fname, flit, n.Body)
+		}
+		return nil
 	}
 	return f
 }
 
-func annotate(name string) {
+func mkCounterVarName(idx int) string {
+	return fmt.Sprintf("%s_%d", *varVar, idx)
+}
+
+func mkPackageIdVar() string {
+	return *varVar + "P"
+}
+
+func mkMetaVar() string {
+	return *varVar + "M"
+}
+
+func mkPackageIdExpression() string {
+	ppath := pkgconfig.PkgPath
+	if hcid := coverage.HardCodedPkgID(ppath); hcid != -1 {
+		return fmt.Sprintf("uint32(%d)", uint32(hcid))
+	}
+	return mkPackageIdVar()
+}
+
+func (f *File) preFunc(fn ast.Node, fname string) {
+	f.fn.units = f.fn.units[:0]
+
+	// create a new counter variable for this function.
+	cv := mkCounterVarName(len(f.pkg.counterLengths))
+	f.fn.counterVar = cv
+}
+
+func (f *File) postFunc(fn ast.Node, funcname string, flit bool, body *ast.BlockStmt) {
+
+	// Tack on single counter write if we are in "perfunc" mode.
+	singleCtr := ""
+	if pkgconfig.Granularity == "perfunc" {
+		singleCtr = "; " + f.newCounter(fn.Pos(), fn.Pos(), 1)
+	}
+
+	// record the length of the counter var required.
+	nc := len(f.fn.units) + coverage.FirstCtrOffset
+	f.pkg.counterLengths = append(f.pkg.counterLengths, nc)
+
+	// FIXME: for windows, do we want "\" and not "/"? Need to test here.
+	// Currently filename is formed as packagepath + "/" + basename.
+	fnpos := f.fset.Position(fn.Pos())
+	ppath := pkgconfig.PkgPath
+	filename := ppath + "/" + filepath.Base(fnpos.Filename)
+
+	// The convention for cmd/cover is that if the go command that
+	// kicks off coverage specifies a local import path (e.g. "go test
+	// -cover ./thispackage"), the tool will capture full pathnames
+	// for source files instead of relative paths, which tend to work
+	// more smoothly for "go tool cover -html". See also issue #56433
+	// for more details.
+	if pkgconfig.Local {
+		filename = f.name
+	}
+
+	// Hand off function to meta-data builder.
+	fd := coverage.FuncDesc{
+		Funcname: funcname,
+		Srcfile:  filename,
+		Units:    f.fn.units,
+		Lit:      flit,
+	}
+	funcId := f.mdb.AddFunc(fd)
+
+	hookWrite := func(cv string, which int, val string) string {
+		return fmt.Sprintf("%s[%d] = %s", cv, which, val)
+	}
+	if *mode == "atomic" {
+		hookWrite = func(cv string, which int, val string) string {
+			return fmt.Sprintf("%sStoreUint32(&%s[%d], %s)",
+				atomicPackagePrefix(), cv, which, val)
+		}
+	}
+
+	// Generate the registration hook sequence for the function. This
+	// sequence looks like
+	//
+	//   counterVar[0] = <num_units>
+	//   counterVar[1] = pkgId
+	//   counterVar[2] = fnId
+	//
+	cv := f.fn.counterVar
+	regHook := hookWrite(cv, 0, strconv.Itoa(len(f.fn.units))) + " ; " +
+		hookWrite(cv, 1, mkPackageIdExpression()) + " ; " +
+		hookWrite(cv, 2, strconv.Itoa(int(funcId))) + singleCtr
+
+	// Insert the registration sequence into the function. We want this sequence to
+	// appear before any counter updates, so use a hack to ensure that this edit
+	// applies before the edit corresponding to the prolog counter update.
+
+	boff := f.offset(body.Pos())
+	ipos := f.fset.File(body.Pos()).Pos(boff)
+	ip := f.offset(ipos)
+	f.edit.Replace(ip, ip+1, string(f.content[ipos-1])+regHook+" ; ")
+
+	f.fn.counterVar = ""
+}
+
+func annotate(names []string) {
+	var p *Package
+	if *pkgcfg != "" {
+		pp := pkgconfig.PkgPath
+		pn := pkgconfig.PkgName
+		mp := pkgconfig.ModulePath
+		mdb, err := encodemeta.NewCoverageMetaDataBuilder(pp, pn, mp)
+		if err != nil {
+			log.Fatalf("creating coverage meta-data builder: %v\n", err)
+		}
+		p = &Package{
+			mdb: mdb,
+		}
+	}
+	// TODO: process files in parallel here if it matters.
+	for k, name := range names {
+		last := false
+		if k == len(names)-1 {
+			last = true
+		}
+
+		fd := os.Stdout
+		isStdout := true
+		if *pkgcfg != "" {
+			var err error
+			fd, err = os.Create(outputfiles[k])
+			if err != nil {
+				log.Fatalf("cover: %s", err)
+			}
+			isStdout = false
+		} else if *output != "" {
+			var err error
+			fd, err = os.Create(*output)
+			if err != nil {
+				log.Fatalf("cover: %s", err)
+			}
+			isStdout = false
+		}
+		p.annotateFile(name, fd, last)
+		if !isStdout {
+			if err := fd.Close(); err != nil {
+				log.Fatalf("cover: %s", err)
+			}
+		}
+	}
+}
+
+func (p *Package) annotateFile(name string, fd io.Writer, last bool) {
 	fset := token.NewFileSet()
 	content, err := os.ReadFile(name)
 	if err != nil {
@@ -319,34 +617,52 @@
 		edit:    edit.NewBuffer(content),
 		astFile: parsedFile,
 	}
+	if p != nil {
+		file.mdb = p.mdb
+		file.pkg = p
+	}
+
 	if *mode == "atomic" {
 		// Add import of sync/atomic immediately after package clause.
 		// We do this even if there is an existing import, because the
 		// existing import may be shadowed at any given place we want
 		// to refer to it, and our name (_cover_atomic_) is less likely to
-		// be shadowed.
-		file.edit.Insert(file.offset(file.astFile.Name.End()),
-			fmt.Sprintf("; import %s %q", atomicPackageName, atomicPackagePath))
-	}
-
-	ast.Walk(file, file.astFile)
-	newContent := file.edit.Bytes()
-
-	fd := os.Stdout
-	if *output != "" {
-		var err error
-		fd, err = os.Create(*output)
-		if err != nil {
-			log.Fatalf("cover: %s", err)
+		// be shadowed. The one exception is if we're visiting the
+		// sync/atomic package itself, in which case we can refer to
+		// functions directly without an import prefix. See also #57445.
+		if pkgconfig.PkgPath != "sync/atomic" {
+			file.edit.Insert(file.offset(file.astFile.Name.End()),
+				fmt.Sprintf("; import %s %q", atomicPackageName, atomicPackagePath))
 		}
 	}
+	if pkgconfig.PkgName == "main" {
+		file.edit.Insert(file.offset(file.astFile.Name.End()),
+			"; import _ \"runtime/coverage\"")
+	}
 
-	fmt.Fprintf(fd, "//line %s:1\n", name)
+	if counterStmt != nil {
+		ast.Walk(file, file.astFile)
+	}
+	newContent := file.edit.Bytes()
+
+	fmt.Fprintf(fd, "//line %s:1:1\n", name)
 	fd.Write(newContent)
 
-	// After printing the source tree, add some declarations for the counters etc.
-	// We could do this by adding to the tree, but it's easier just to print the text.
+	// After printing the source tree, add some declarations for the
+	// counters etc. We could do this by adding to the tree, but it's
+	// easier just to print the text.
 	file.addVariables(fd)
+
+	// Emit a reference to the atomic package to avoid
+	// import and not used error when there's no code in a file.
+	if *mode == "atomic" {
+		fmt.Fprintf(fd, "var _ = %sLoadUint32\n", atomicPackagePrefix())
+	}
+
+	// Last file? Emit meta-data and converage config.
+	if last {
+		p.emitMetaData(fd)
+	}
 }
 
 // setCounterStmt returns the expression: __count[23] = 1.
@@ -361,13 +677,34 @@
 
 // atomicCounterStmt returns the expression: atomic.AddUint32(&__count[23], 1)
 func atomicCounterStmt(f *File, counter string) string {
-	return fmt.Sprintf("%s.AddUint32(&%s, 1)", atomicPackageName, counter)
+	return fmt.Sprintf("%sAddUint32(&%s, 1)", atomicPackagePrefix(), counter)
 }
 
 // newCounter creates a new counter expression of the appropriate form.
 func (f *File) newCounter(start, end token.Pos, numStmt int) string {
-	stmt := counterStmt(f, fmt.Sprintf("%s.Count[%d]", *varVar, len(f.blocks)))
-	f.blocks = append(f.blocks, Block{start, end, numStmt})
+	var stmt string
+	if *pkgcfg != "" {
+		slot := len(f.fn.units) + coverage.FirstCtrOffset
+		if f.fn.counterVar == "" {
+			panic("internal error: counter var unset")
+		}
+		stmt = counterStmt(f, fmt.Sprintf("%s[%d]", f.fn.counterVar, slot))
+		stpos := f.fset.Position(start)
+		enpos := f.fset.Position(end)
+		stpos, enpos = dedup(stpos, enpos)
+		unit := coverage.CoverableUnit{
+			StLine:  uint32(stpos.Line),
+			StCol:   uint32(stpos.Column),
+			EnLine:  uint32(enpos.Line),
+			EnCol:   uint32(enpos.Column),
+			NxStmts: uint32(numStmt),
+		}
+		f.fn.units = append(f.fn.units, unit)
+	} else {
+		stmt = counterStmt(f, fmt.Sprintf("%s.Count[%d]", *varVar,
+			len(f.blocks)))
+		f.blocks = append(f.blocks, Block{start, end, numStmt})
+	}
 	return stmt
 }
 
@@ -621,6 +958,9 @@
 
 // addVariables adds to the end of the file the declarations to set up the counter and position variables.
 func (f *File) addVariables(w io.Writer) {
+	if *pkgcfg != "" {
+		return
+	}
 	// Self-check: Verify that the instrumented basic blocks are disjoint.
 	t := make([]block1, len(f.blocks))
 	for i := range f.blocks {
@@ -683,12 +1023,6 @@
 
 	// Close the struct initialization.
 	fmt.Fprintf(w, "}\n")
-
-	// Emit a reference to the atomic package to avoid
-	// import and not used error when there's no code in a file.
-	if *mode == "atomic" {
-		fmt.Fprintf(w, "var _ = %s.LoadUint32\n", atomicPackageName)
-	}
 }
 
 // It is possible for positions to repeat when there is a line
@@ -727,3 +1061,76 @@
 
 	return key.p1, key.p2
 }
+
+func (p *Package) emitMetaData(w io.Writer) {
+	if *pkgcfg == "" {
+		return
+	}
+
+	// Something went wrong if regonly/testmain mode is in effect and
+	// we have instrumented functions.
+	if counterStmt == nil && len(p.counterLengths) != 0 {
+		panic("internal error: seen functions with regonly/testmain")
+	}
+
+	// Emit package ID var.
+	fmt.Fprintf(w, "\nvar %sP uint32\n", *varVar)
+
+	// Emit all of the counter variables.
+	for k := range p.counterLengths {
+		cvn := mkCounterVarName(k)
+		fmt.Fprintf(w, "var %s [%d]uint32\n", cvn, p.counterLengths[k])
+	}
+
+	// Emit encoded meta-data.
+	var sws slicewriter.WriteSeeker
+	digest, err := p.mdb.Emit(&sws)
+	if err != nil {
+		log.Fatalf("encoding meta-data: %v", err)
+	}
+	p.mdb = nil
+	fmt.Fprintf(w, "var %s = [...]byte{\n", mkMetaVar())
+	payload := sws.BytesWritten()
+	for k, b := range payload {
+		fmt.Fprintf(w, " 0x%x,", b)
+		if k != 0 && k%8 == 0 {
+			fmt.Fprintf(w, "\n")
+		}
+	}
+	fmt.Fprintf(w, "}\n")
+
+	fixcfg := coverage.CoverFixupConfig{
+		Strategy:           "normal",
+		MetaVar:            mkMetaVar(),
+		MetaLen:            len(payload),
+		MetaHash:           fmt.Sprintf("%x", digest),
+		PkgIdVar:           mkPackageIdVar(),
+		CounterPrefix:      *varVar,
+		CounterGranularity: pkgconfig.Granularity,
+		CounterMode:        *mode,
+	}
+	fixdata, err := json.Marshal(fixcfg)
+	if err != nil {
+		log.Fatalf("marshal fixupcfg: %v", err)
+	}
+	if err := os.WriteFile(pkgconfig.OutConfig, fixdata, 0666); err != nil {
+		log.Fatalf("error writing %s: %v", pkgconfig.OutConfig, err)
+	}
+}
+
+// atomicOnAtomic returns true if we're instrumenting
+// the sync/atomic package AND using atomic mode.
+func atomicOnAtomic() bool {
+	return *mode == "atomic" && pkgconfig.PkgPath == "sync/atomic"
+}
+
+// atomicPackagePrefix returns the import path prefix used to refer to
+// our special import of sync/atomic; this is either set to the
+// constant atomicPackageName plus a dot or the empty string if we're
+// instrumenting the sync/atomic package itself.
+func atomicPackagePrefix() string {
+	if atomicOnAtomic() {
+		return ""
+	}
+	return atomicPackageName + "."
+}
diff --git a/src/cmd/cover/cover_test.go b/src/cmd/cover/cover_test.go
index 28be231..af266b5 100644
--- a/src/cmd/cover/cover_test.go
+++ b/src/cmd/cover/cover_test.go
@@ -7,12 +7,14 @@
 import (
 	"bufio"
 	"bytes"
+	cmdcover "cmd/cover"
 	"flag"
 	"fmt"
 	"go/ast"
 	"go/parser"
 	"go/token"
 	"internal/testenv"
+	"log"
 	"os"
 	"os/exec"
 	"path/filepath"
@@ -27,150 +29,117 @@
 	testdata = "testdata"
 )
 
-var (
-	// Input files.
-	testMain       = filepath.Join(testdata, "main.go")
-	testTest       = filepath.Join(testdata, "test.go")
-	coverProfile   = filepath.Join(testdata, "profile.cov")
-	toolexecSource = filepath.Join(testdata, "toolexec.go")
-
-	// The HTML test files are in a separate directory
-	// so they are a complete package.
-	htmlGolden = filepath.Join(testdata, "html", "html.golden")
-
-	// Temporary files.
-	tmpTestMain    string
-	coverInput     string
-	coverOutput    string
-	htmlProfile    string
-	htmlHTML       string
-	htmlUDir       string
-	htmlU          string
-	htmlUTest      string
-	htmlUProfile   string
-	htmlUHTML      string
-	lineDupDir     string
-	lineDupGo      string
-	lineDupTestGo  string
-	lineDupProfile string
-)
-
-var (
-	// testTempDir is a temporary directory created in TestMain.
-	testTempDir string
-
-	// testcover is a newly built version of the cover program.
-	testcover string
-
-	// toolexec is a program to use as the go tool's -toolexec argument.
-	toolexec string
-
-	// testcoverErr records an error building testcover or toolexec.
-	testcoverErr error
-
-	// testcoverOnce is used to build testcover once.
-	testcoverOnce sync.Once
-
-	// toolexecArg is the argument to pass to the go tool.
-	toolexecArg string
-)
-
-var debug = flag.Bool("debug", false, "keep rewritten files for debugging")
-
-// We use TestMain to set up a temporary directory and remove it when
-// the tests are done.
-func TestMain(m *testing.M) {
-	dir, err := os.MkdirTemp("", "go-testcover")
+// testcover returns the path to the cmd/cover binary that we are going to
+// test. At one point this was created via "go build"; we now reuse the unit
+// test executable itself.
+func testcover(t testing.TB) string {
+	exe, err := os.Executable()
 	if err != nil {
-		fmt.Fprintln(os.Stderr, err)
-		os.Exit(1)
+		t.Helper()
+		t.Fatal(err)
 	}
-	os.Setenv("GOPATH", filepath.Join(dir, "_gopath"))
-
-	testTempDir = dir
-
-	tmpTestMain = filepath.Join(dir, "main.go")
-	coverInput = filepath.Join(dir, "test_line.go")
-	coverOutput = filepath.Join(dir, "test_cover.go")
-	htmlProfile = filepath.Join(dir, "html.cov")
-	htmlHTML = filepath.Join(dir, "html.html")
-	htmlUDir = filepath.Join(dir, "htmlunformatted")
-	htmlU = filepath.Join(htmlUDir, "htmlunformatted.go")
-	htmlUTest = filepath.Join(htmlUDir, "htmlunformatted_test.go")
-	htmlUProfile = filepath.Join(htmlUDir, "htmlunformatted.cov")
-	htmlUHTML = filepath.Join(htmlUDir, "htmlunformatted.html")
-	lineDupDir = filepath.Join(dir, "linedup")
-	lineDupGo = filepath.Join(lineDupDir, "linedup.go")
-	lineDupTestGo = filepath.Join(lineDupDir, "linedup_test.go")
-	lineDupProfile = filepath.Join(lineDupDir, "linedup.out")
-
-	status := m.Run()
-
-	if !*debug {
-		os.RemoveAll(dir)
-	}
-
-	os.Exit(status)
+	return exe
 }
 
-// buildCover builds a version of the cover program for testing.
-// This ensures that "go test cmd/cover" tests the current cmd/cover.
-func buildCover(t *testing.T) {
-	t.Helper()
-	testenv.MustHaveGoBuild(t)
-	testcoverOnce.Do(func() {
-		var wg sync.WaitGroup
-		wg.Add(2)
+// testTempDir is a temporary directory created in TestMain.
+var testTempDir string
 
-		var err1, err2 error
-		go func() {
-			defer wg.Done()
-			testcover = filepath.Join(testTempDir, "cover.exe")
-			t.Logf("running [go build -o %s]", testcover)
-			out, err := exec.Command(testenv.GoToolPath(t), "build", "-o", testcover).CombinedOutput()
-			if len(out) > 0 {
-				t.Logf("%s", out)
+// If set, this will preserve all the tmpdir files from the test run.
+var debug = flag.Bool("debug", false, "keep tmpdir files for debugging")
+
+// TestMain used here so that we can leverage the test executable
+// itself as a cmd/cover executable; compare to similar usage in
+// the cmd/go tests.
+func TestMain(m *testing.M) {
+	if os.Getenv("CMDCOVER_TOOLEXEC") != "" {
+		// When CMDCOVER_TOOLEXEC is set, the test binary is also
+		// running as a -toolexec wrapper.
+		tool := strings.TrimSuffix(filepath.Base(os.Args[1]), ".exe")
+		if tool == "cover" {
+			// Inject this test binary as cmd/cover in place of the
+			// installed tool, so that the go command's invocations of
+			// cover produce coverage for the configuration in which
+			// the test was built.
+			os.Args = os.Args[1:]
+			cmdcover.Main()
+		} else {
+			cmd := exec.Command(os.Args[1], os.Args[2:]...)
+			cmd.Stdout = os.Stdout
+			cmd.Stderr = os.Stderr
+			if err := cmd.Run(); err != nil {
+				os.Exit(1)
 			}
-			err1 = err
-		}()
-
-		go func() {
-			defer wg.Done()
-			toolexec = filepath.Join(testTempDir, "toolexec.exe")
-			t.Logf("running [go -build -o %s %s]", toolexec, toolexecSource)
-			out, err := exec.Command(testenv.GoToolPath(t), "build", "-o", toolexec, toolexecSource).CombinedOutput()
-			if len(out) > 0 {
-				t.Logf("%s", out)
-			}
-			err2 = err
-		}()
-
-		wg.Wait()
-
-		testcoverErr = err1
-		if err2 != nil && err1 == nil {
-			testcoverErr = err2
 		}
-
-		toolexecArg = "-toolexec=" + toolexec + " " + testcover
-	})
-	if testcoverErr != nil {
-		t.Fatal("failed to build testcover or toolexec program:", testcoverErr)
+		os.Exit(0)
 	}
+	if os.Getenv("CMDCOVER_TEST_RUN_MAIN") != "" {
+		// When CMDCOVER_TEST_RUN_MAIN is set, we're reusing the test
+		// binary as cmd/cover. In this case we run the main func exported
+		// via export_test.go, and exit; CMDCOVER_TEST_RUN_MAIN is set below
+		// for actual test invocations.
+		cmdcover.Main()
+		os.Exit(0)
+	}
+	flag.Parse()
+	topTmpdir, err := os.MkdirTemp("", "cmd-cover-test-")
+	if err != nil {
+		log.Fatal(err)
+	}
+	testTempDir = topTmpdir
+	if !*debug {
+		defer os.RemoveAll(topTmpdir)
+	} else {
+		fmt.Fprintf(os.Stderr, "debug: preserving tmpdir %s\n", topTmpdir)
+	}
+	os.Setenv("CMDCOVER_TEST_RUN_MAIN", "normal")
+	os.Exit(m.Run())
 }
 
-// Run this shell script, but do it in Go so it can be run by "go test".
+var tdmu sync.Mutex
+var tdcount int
+
+func tempDir(t *testing.T) string {
+	tdmu.Lock()
+	dir := filepath.Join(testTempDir, fmt.Sprintf("%03d", tdcount))
+	tdcount++
+	if err := os.Mkdir(dir, 0777); err != nil {
+		t.Fatal(err)
+	}
+	defer tdmu.Unlock()
+	return dir
+}
+
+// TestCoverWithToolExec runs a set of subtests that all make use of a
+// "-toolexec" wrapper program to invoke the cover test executable
+// itself via "go test -cover".
+func TestCoverWithToolExec(t *testing.T) {
+	testenv.MustHaveExec(t)
+
+	toolexecArg := "-toolexec=" + testcover(t)
+
+	t.Run("CoverHTML", func(t *testing.T) {
+		testCoverHTML(t, toolexecArg)
+	})
+	t.Run("HtmlUnformatted", func(t *testing.T) {
+		testHtmlUnformatted(t, toolexecArg)
+	})
+	t.Run("FuncWithDuplicateLines", func(t *testing.T) {
+		testFuncWithDuplicateLines(t, toolexecArg)
+	})
+}
+
+// Execute this command sequence:
 //
 //	replace the word LINE with the line number < testdata/test.go > testdata/test_line.go
-//	go build -o testcover
 //	testcover -mode=count -var=CoverTest -o ./testdata/test_cover.go testdata/test_line.go
 //	go run ./testdata/main.go ./testdata/test.go
 func TestCover(t *testing.T) {
-	t.Parallel()
 	testenv.MustHaveGoRun(t)
-	buildCover(t)
+	t.Parallel()
+	dir := tempDir(t)
 
 	// Read in the test file (testTest) and write it, with LINEs specified, to coverInput.
+	testTest := filepath.Join(testdata, "test.go")
 	file, err := os.ReadFile(testTest)
 	if err != nil {
 		t.Fatal(err)
@@ -190,32 +159,36 @@
 		[]byte("}"))
 	lines = append(lines, []byte("func unFormatted2(b bool) {if b{}else{}}"))
 
+	coverInput := filepath.Join(dir, "test_line.go")
 	if err := os.WriteFile(coverInput, bytes.Join(lines, []byte("\n")), 0666); err != nil {
 		t.Fatal(err)
 	}
 
 	// testcover -mode=count -var=thisNameMustBeVeryLongToCauseOverflowOfCounterIncrementStatementOntoNextLineForTest -o ./testdata/test_cover.go testdata/test_line.go
-	cmd := exec.Command(testcover, "-mode=count", "-var=thisNameMustBeVeryLongToCauseOverflowOfCounterIncrementStatementOntoNextLineForTest", "-o", coverOutput, coverInput)
+	coverOutput := filepath.Join(dir, "test_cover.go")
+	cmd := testenv.Command(t, testcover(t), "-mode=count", "-var=thisNameMustBeVeryLongToCauseOverflowOfCounterIncrementStatementOntoNextLineForTest", "-o", coverOutput, coverInput)
 	run(cmd, t)
 
-	cmd = exec.Command(testcover, "-mode=set", "-var=Not_an-identifier", "-o", coverOutput, coverInput)
+	cmd = testenv.Command(t, testcover(t), "-mode=set", "-var=Not_an-identifier", "-o", coverOutput, coverInput)
 	err = cmd.Run()
 	if err == nil {
 		t.Error("Expected cover to fail with an error")
 	}
 
-	// Copy testmain to testTempDir, so that it is in the same directory
+	// Copy testmain to tmpdir, so that it is in the same directory
 	// as coverOutput.
+	testMain := filepath.Join(testdata, "main.go")
 	b, err := os.ReadFile(testMain)
 	if err != nil {
 		t.Fatal(err)
 	}
+	tmpTestMain := filepath.Join(dir, "main.go")
 	if err := os.WriteFile(tmpTestMain, b, 0444); err != nil {
 		t.Fatal(err)
 	}
 
 	// go run ./testdata/main.go ./testdata/test.go
-	cmd = exec.Command(testenv.GoToolPath(t), "run", tmpTestMain, coverOutput)
+	cmd = testenv.Command(t, testenv.GoToolPath(t), "run", tmpTestMain, coverOutput)
 	run(cmd, t)
 
 	file, err = os.ReadFile(coverOutput)
@@ -243,8 +216,8 @@
 // above those declarations, even if they are not part of the block of
 // documentation comments.
 func TestDirectives(t *testing.T) {
+	testenv.MustHaveExec(t)
 	t.Parallel()
-	buildCover(t)
 
 	// Read the source file and find all the directives. We'll keep
 	// track of whether each one has been seen in the output.
@@ -256,7 +229,7 @@
 	sourceDirectives := findDirectives(source)
 
 	// testcover -mode=atomic ./testdata/directives.go
-	cmd := exec.Command(testcover, "-mode=atomic", testDirectives)
+	cmd := testenv.Command(t, testcover(t), "-mode=atomic", testDirectives)
 	cmd.Stderr = os.Stderr
 	output, err := cmd.Output()
 	if err != nil {
@@ -362,10 +335,11 @@
 // Makes sure that `cover -func=profile.cov` reports accurate coverage.
 // Issue #20515.
 func TestCoverFunc(t *testing.T) {
-	t.Parallel()
-	buildCover(t)
+	testenv.MustHaveExec(t)
+
 	// testcover -func ./testdata/profile.cov
-	cmd := exec.Command(testcover, "-func", coverProfile)
+	coverProfile := filepath.Join(testdata, "profile.cov")
+	cmd := testenv.Command(t, testcover(t), "-func", coverProfile)
 	out, err := cmd.Output()
 	if err != nil {
 		if ee, ok := err.(*exec.ExitError); ok {
@@ -382,16 +356,20 @@
 
 // Check that cover produces correct HTML.
 // Issue #25767.
-func TestCoverHTML(t *testing.T) {
-	t.Parallel()
+func testCoverHTML(t *testing.T, toolexecArg string) {
 	testenv.MustHaveGoRun(t)
-	buildCover(t)
+	dir := tempDir(t)
+
+	t.Parallel()
 
 	// go test -coverprofile testdata/html/html.cov cmd/cover/testdata/html
-	cmd := exec.Command(testenv.GoToolPath(t), "test", toolexecArg, "-coverprofile", htmlProfile, "cmd/cover/testdata/html")
+	htmlProfile := filepath.Join(dir, "html.cov")
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "test", toolexecArg, "-coverprofile", htmlProfile, "cmd/cover/testdata/html")
+	cmd.Env = append(cmd.Environ(), "CMDCOVER_TOOLEXEC=true")
 	run(cmd, t)
 	// testcover -html testdata/html/html.cov -o testdata/html/html.html
-	cmd = exec.Command(testcover, "-html", htmlProfile, "-o", htmlHTML)
+	htmlHTML := filepath.Join(dir, "html.html")
+	cmd = testenv.Command(t, testcover(t), "-html", htmlProfile, "-o", htmlHTML)
 	run(cmd, t)
 
 	// Extract the parts of the HTML with comment markers,
@@ -400,7 +378,7 @@
 	if err != nil {
 		t.Fatal(err)
 	}
-	var out bytes.Buffer
+	var out strings.Builder
 	scan := bufio.NewScanner(bytes.NewReader(entireHTML))
 	in := false
 	for scan.Scan() {
@@ -418,6 +396,7 @@
 	if scan.Err() != nil {
 		t.Error(scan.Err())
 	}
+	htmlGolden := filepath.Join(testdata, "html", "html.golden")
 	golden, err := os.ReadFile(htmlGolden)
 	if err != nil {
 		t.Fatalf("reading golden file: %v", err)
@@ -446,10 +425,17 @@
 
 // Test HTML processing with a source file not run through gofmt.
 // Issue #27350.
-func TestHtmlUnformatted(t *testing.T) {
-	t.Parallel()
+func testHtmlUnformatted(t *testing.T, toolexecArg string) {
 	testenv.MustHaveGoRun(t)
-	buildCover(t)
+	dir := tempDir(t)
+
+	t.Parallel()
+
+	htmlUDir := filepath.Join(dir, "htmlunformatted")
+	htmlU := filepath.Join(htmlUDir, "htmlunformatted.go")
+	htmlUTest := filepath.Join(htmlUDir, "htmlunformatted_test.go")
+	htmlUProfile := filepath.Join(htmlUDir, "htmlunformatted.cov")
+	htmlUHTML := filepath.Join(htmlUDir, "htmlunformatted.html")
 
 	if err := os.Mkdir(htmlUDir, 0777); err != nil {
 		t.Fatal(err)
@@ -480,17 +466,18 @@
 	}
 
 	// go test -covermode=count -coverprofile TMPDIR/htmlunformatted.cov
-	cmd := exec.Command(testenv.GoToolPath(t), "test", toolexecArg, "-covermode=count", "-coverprofile", htmlUProfile)
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "test", "-test.v", toolexecArg, "-covermode=count", "-coverprofile", htmlUProfile)
+	cmd.Env = append(cmd.Environ(), "CMDCOVER_TOOLEXEC=true")
 	cmd.Dir = htmlUDir
 	run(cmd, t)
 
 	// testcover -html TMPDIR/htmlunformatted.cov -o unformatted.html
-	cmd = exec.Command(testcover, "-html", htmlUProfile, "-o", htmlUHTML)
+	cmd = testenv.Command(t, testcover(t), "-html", htmlUProfile, "-o", htmlUHTML)
 	cmd.Dir = htmlUDir
 	run(cmd, t)
 }
 
-// lineDupContents becomes linedup.go in TestFuncWithDuplicateLines.
+// lineDupContents becomes linedup.go in testFuncWithDuplicateLines.
 const lineDupContents = `
 package linedup
 
@@ -516,7 +503,7 @@
 }
 `
 
-// lineDupTestContents becomes linedup_test.go in TestFuncWithDuplicateLines.
+// lineDupTestContents becomes linedup_test.go in testFuncWithDuplicateLines.
 const lineDupTestContents = `
 package linedup
 
@@ -529,10 +516,16 @@
 
 // Test -func with duplicate //line directives with different numbers
 // of statements.
-func TestFuncWithDuplicateLines(t *testing.T) {
-	t.Parallel()
+func testFuncWithDuplicateLines(t *testing.T, toolexecArg string) {
 	testenv.MustHaveGoRun(t)
-	buildCover(t)
+	dir := tempDir(t)
+
+	t.Parallel()
+
+	lineDupDir := filepath.Join(dir, "linedup")
+	lineDupGo := filepath.Join(lineDupDir, "linedup.go")
+	lineDupTestGo := filepath.Join(lineDupDir, "linedup_test.go")
+	lineDupProfile := filepath.Join(lineDupDir, "linedup.out")
 
 	if err := os.Mkdir(lineDupDir, 0777); err != nil {
 		t.Fatal(err)
@@ -549,12 +542,13 @@
 	}
 
 	// go test -cover -covermode count -coverprofile TMPDIR/linedup.out
-	cmd := exec.Command(testenv.GoToolPath(t), "test", toolexecArg, "-cover", "-covermode", "count", "-coverprofile", lineDupProfile)
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "test", toolexecArg, "-cover", "-covermode", "count", "-coverprofile", lineDupProfile)
+	cmd.Env = append(cmd.Environ(), "CMDCOVER_TOOLEXEC=true")
 	cmd.Dir = lineDupDir
 	run(cmd, t)
 
 	// testcover -func=TMPDIR/linedup.out
-	cmd = exec.Command(testcover, "-func", lineDupProfile)
+	cmd = testenv.Command(t, testcover(t), "-func", lineDupProfile)
 	cmd.Dir = lineDupDir
 	run(cmd, t)
 }
@@ -570,3 +564,13 @@
 		t.Fatal(err)
 	}
 }
+
+func runExpectingError(c *exec.Cmd, t *testing.T) string {
+	t.Helper()
+	t.Log("running", c.Args)
+	out, err := c.CombinedOutput()
+	if err == nil {
+		return fmt.Sprintf("unexpected pass for %+v", c.Args)
+	}
+	return string(out)
+}
diff --git a/src/cmd/cover/doc.go b/src/cmd/cover/doc.go
index e091ce9..82580cd 100644
--- a/src/cmd/cover/doc.go
+++ b/src/cmd/cover/doc.go
@@ -7,12 +7,18 @@
 'go test -coverprofile=cover.out'.
 
 Cover is also used by 'go test -cover' to rewrite the source code with
-annotations to track which parts of each function are executed.
-It operates on one Go source file at a time, computing approximate
-basic block information by studying the source. It is thus more portable
-than binary-rewriting coverage tools, but also a little less capable.
-For instance, it does not probe inside && and || expressions, and can
-be mildly confused by single statements with multiple function literals.
+annotations to track which parts of each function are executed (this
+is referred to "instrumentation"). Cover can operate in "legacy mode"
+on a single Go source file at a time, or when invoked by the Go tool
+it will process all the source files in a single package at a time
+(package-scope instrumentation is enabled via "-pkgcfg" option,
+
+When generated instrumented code, the cover tool computes approximate
+basic block information by studying the source. It is thus more
+portable than binary-rewriting coverage tools, but also a little less
+capable. For instance, it does not probe inside && and || expressions,
+and can be mildly confused by single statements with multiple function
+literals.
 
 When computing coverage of a package that uses cgo, the cover tool
 must be applied to the output of cgo preprocessing, not the input,
diff --git a/src/cmd/cover/export_test.go b/src/cmd/cover/export_test.go
new file mode 100644
index 0000000..e4592ee
--- /dev/null
+++ b/src/cmd/cover/export_test.go
@@ -0,0 +1,7 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func Main() { main() }
diff --git a/src/cmd/cover/html.go b/src/cmd/cover/html.go
index 3c1d17e..400a7d8 100644
--- a/src/cmd/cover/html.go
+++ b/src/cmd/cover/html.go
@@ -6,7 +6,6 @@
 
 import (
 	"bufio"
-	"bytes"
 	"cmd/internal/browser"
 	"fmt"
 	"html/template"
@@ -157,7 +156,7 @@
 
 // colors generates the CSS rules for coverage colors.
 func colors() template.CSS {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	for i := 0; i < 11; i++ {
 		fmt.Fprintf(&buf, ".cov%v { color: %v }\n", i, rgb(i))
 	}
diff --git a/src/cmd/cover/testdata/pkgcfg/a/a.go b/src/cmd/cover/testdata/pkgcfg/a/a.go
new file mode 100644
index 0000000..44c380b
--- /dev/null
+++ b/src/cmd/cover/testdata/pkgcfg/a/a.go
@@ -0,0 +1,28 @@
+package a
+
+type Atyp int
+
+func (ap *Atyp) Set(q int) {
+	*ap = Atyp(q)
+}
+
+func (ap Atyp) Get() int {
+	inter := func(q Atyp) int {
+		return int(q)
+	}
+	return inter(ap)
+}
+
+var afunc = func(x int) int {
+	return x + 1
+}
+var Avar = afunc(42)
+
+func A(x int) int {
+	if x == 0 {
+		return 22
+	} else if x == 1 {
+		return 33
+	}
+	return 44
+}
diff --git a/src/cmd/cover/testdata/pkgcfg/a/a2.go b/src/cmd/cover/testdata/pkgcfg/a/a2.go
new file mode 100644
index 0000000..e6b2fc1
--- /dev/null
+++ b/src/cmd/cover/testdata/pkgcfg/a/a2.go
@@ -0,0 +1,8 @@
+package a
+
+func A2() {
+	{
+	}
+	{
+	}
+}
diff --git a/src/cmd/cover/testdata/pkgcfg/a/a_test.go b/src/cmd/cover/testdata/pkgcfg/a/a_test.go
new file mode 100644
index 0000000..a1608e0
--- /dev/null
+++ b/src/cmd/cover/testdata/pkgcfg/a/a_test.go
@@ -0,0 +1,14 @@
+package a_test
+
+import (
+	"cfg/a"
+	"testing"
+)
+
+func TestA(t *testing.T) {
+	a.A(0)
+	var aat a.Atyp
+	at := &aat
+	at.Set(42)
+	println(at.Get())
+}
diff --git a/src/cmd/cover/testdata/pkgcfg/b/b.go b/src/cmd/cover/testdata/pkgcfg/b/b.go
new file mode 100644
index 0000000..9e330ee
--- /dev/null
+++ b/src/cmd/cover/testdata/pkgcfg/b/b.go
@@ -0,0 +1,10 @@
+package b
+
+func B(x int) int {
+	if x == 0 {
+		return 22
+	} else if x == 1 {
+		return 33
+	}
+	return 44
+}
diff --git a/src/cmd/cover/testdata/pkgcfg/b/b_test.go b/src/cmd/cover/testdata/pkgcfg/b/b_test.go
new file mode 100644
index 0000000..7bdb73b
--- /dev/null
+++ b/src/cmd/cover/testdata/pkgcfg/b/b_test.go
@@ -0,0 +1,9 @@
+package b
+
+import "testing"
+
+func TestB(t *testing.T) {
+	B(0)
+	B(1)
+	B(2)
+}
diff --git a/src/cmd/cover/testdata/pkgcfg/main/main.go b/src/cmd/cover/testdata/pkgcfg/main/main.go
new file mode 100644
index 0000000..a908931
--- /dev/null
+++ b/src/cmd/cover/testdata/pkgcfg/main/main.go
@@ -0,0 +1,15 @@
+package main
+
+import (
+	"cfg/a"
+	"cfg/b"
+)
+
+func main() {
+	a.A(2)
+	a.A(1)
+	a.A(0)
+	b.B(1)
+	b.B(0)
+	println("done")
+}
diff --git a/src/cmd/cover/testdata/toolexec.go b/src/cmd/cover/testdata/toolexec.go
deleted file mode 100644
index 1769efe..0000000
--- a/src/cmd/cover/testdata/toolexec.go
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// The toolexec program is a helper program for cmd/cover tests.
-// It is used so that the go tool will call the newly built version
-// of the cover program, rather than the installed one.
-//
-// The tests arrange to run the go tool with the argument
-//    -toolexec="/path/to/toolexec /path/to/testcover"
-// The go tool will invoke this program (compiled into /path/to/toolexec)
-// with the arguments shown above followed by the command to run.
-// This program will check whether it is expected to run the cover
-// program, and if so replace it with /path/to/testcover.
-package main
-
-import (
-	"os"
-	"os/exec"
-	"strings"
-)
-
-func main() {
-	if strings.HasSuffix(strings.TrimSuffix(os.Args[2], ".exe"), "cover") {
-		os.Args[2] = os.Args[1]
-	}
-	cmd := exec.Command(os.Args[2], os.Args[3:]...)
-	cmd.Stdout = os.Stdout
-	cmd.Stderr = os.Stderr
-	if err := cmd.Run(); err != nil {
-		os.Exit(1)
-	}
-}
diff --git a/src/cmd/dist/README b/src/cmd/dist/README
index 0649e88..673c0f3 100644
--- a/src/cmd/dist/README
+++ b/src/cmd/dist/README
@@ -4,10 +4,10 @@
 in Go, making bootstrapping a little more involved than in the past.
 The approach is to build the current release of Go with an earlier one.
 
-The process to install Go 1.x, for x ≥ 5, is:
+The process to install Go 1.x, for x ≥ 20, is:
 
-1. Build cmd/dist with Go 1.4.
-2. Using dist, build Go 1.x compiler toolchain with Go 1.4.
+1. Build cmd/dist with Go 1.17.13.
+2. Using dist, build Go 1.x compiler toolchain with Go 1.17.13.
 3. Using dist, rebuild Go 1.x compiler toolchain with itself.
 4. Using dist, build Go 1.x cmd/go (as go_bootstrap) with Go 1.x compiler toolchain.
 5. Using go_bootstrap, build the remaining Go 1.x standard library and commands.
@@ -16,8 +16,8 @@
 step 2 also builds the parts of the toolchain written in C, and step 3 does not
 recompile those.
 
-Because of backward compatibility, although the steps above say Go 1.4,
-in practice any release ≥ Go 1.4 but < Go 1.x will work as the bootstrap base.
+Because of backward compatibility, although the steps above say Go 1.17.13,
+in practice any release ≥ Go 1.17.13 but < Go 1.x will work as the bootstrap base.
 
 See golang.org/s/go15bootstrap for more details.
 
diff --git a/src/cmd/dist/build.go b/src/cmd/dist/build.go
index 7c44c4a..c36a12e 100644
--- a/src/cmd/dist/build.go
+++ b/src/cmd/dist/build.go
@@ -9,7 +9,6 @@
 	"encoding/json"
 	"flag"
 	"fmt"
-	"io/ioutil"
 	"log"
 	"os"
 	"os/exec"
@@ -55,6 +54,7 @@
 
 	rebuildall   bool
 	defaultclang bool
+	noOpt        bool
 
 	vflag int // verbosity
 )
@@ -259,7 +259,7 @@
 	os.Setenv("GOWORK", "off")
 
 	workdir = xworkdir()
-	if err := ioutil.WriteFile(pathf("%s/go.mod", workdir), []byte("module bootstrap"), 0666); err != nil {
+	if err := os.WriteFile(pathf("%s/go.mod", workdir), []byte("module bootstrap"), 0666); err != nil {
 		fatalf("cannot write stub go.mod: %s", err)
 	}
 	xatexit(rmworkdir)
@@ -386,7 +386,7 @@
 	// Note that we lightly parse internal/goversion/goversion.go to
 	// obtain the base version. We can't just import the package,
 	// because cmd/dist is built with a bootstrap GOROOT which could
-	// be an entirely different version of Go, like 1.4. We assume
+	// be an entirely different version of Go. We assume
 	// that the file contains "const Version = <Integer>".
 	goversionSource := readfile(pathf("%s/src/internal/goversion/goversion.go", goroot))
 	m := regexp.MustCompile(`(?m)^const Version = (\d+)`).FindStringSubmatch(goversionSource)
@@ -463,11 +463,16 @@
 		xmkdir(p)
 	}
 
-	p := pathf("%s/pkg/%s_%s", goroot, gohostos, gohostarch)
+	goosGoarch := pathf("%s/pkg/%s_%s", goroot, gohostos, gohostarch)
 	if rebuildall {
-		xremoveall(p)
+		xremoveall(goosGoarch)
 	}
-	xmkdirall(p)
+	xmkdirall(goosGoarch)
+	xatexit(func() {
+		if files := xreaddir(goosGoarch); len(files) == 0 {
+			xremove(goosGoarch)
+		}
+	})
 
 	if goos != gohostos || goarch != gohostarch {
 		p := pathf("%s/pkg/%s_%s", goroot, goos, goarch)
@@ -480,13 +485,29 @@
 	// Create object directory.
 	// We used to use it for C objects.
 	// Now we use it for the build cache, to separate dist's cache
-	// from any other cache the user might have.
-	p = pathf("%s/pkg/obj/go-build", goroot)
-	if rebuildall {
-		xremoveall(p)
+	// from any other cache the user might have, and for the location
+	// to build the bootstrap versions of the standard library.
+	obj := pathf("%s/pkg/obj", goroot)
+	if !isdir(obj) {
+		xmkdir(obj)
 	}
-	xmkdirall(p)
-	xatexit(func() { xremoveall(p) })
+	xatexit(func() { xremove(obj) })
+
+	// Create build cache directory.
+	objGobuild := pathf("%s/pkg/obj/go-build", goroot)
+	if rebuildall {
+		xremoveall(objGobuild)
+	}
+	xmkdirall(objGobuild)
+	xatexit(func() { xremoveall(objGobuild) })
+
+	// Create directory for bootstrap versions of standard library .a files.
+	objGoBootstrap := pathf("%s/pkg/obj/go-bootstrap", goroot)
+	if rebuildall {
+		xremoveall(objGoBootstrap)
+	}
+	xmkdirall(objGoBootstrap)
+	xatexit(func() { xremoveall(objGoBootstrap) })
 
 	// Create tool directory.
 	// We keep it in pkg/, just like the object directory above.
@@ -651,6 +672,7 @@
 			link = append(link, goldflags)
 		}
 		link = append(link, "-extld="+compilerEnvLookup(defaultcc, goos, goarch))
+		link = append(link, "-L="+pathf("%s/pkg/obj/go-bootstrap/%s_%s", goroot, goos, goarch))
 		link = append(link, "-o", pathf("%s/%s%s", tooldir, elem, exe))
 		targ = len(link) - 1
 	}
@@ -820,6 +842,19 @@
 		// Define GOMIPS64_value from gomips64.
 		asmArgs = append(asmArgs, "-D", "GOMIPS64_"+gomips64)
 	}
+	if goarch == "ppc64" || goarch == "ppc64le" {
+		// We treat each powerpc version as a superset of functionality.
+		switch goppc64 {
+		case "power10":
+			asmArgs = append(asmArgs, "-D", "GOPPC64_power10")
+			fallthrough
+		case "power9":
+			asmArgs = append(asmArgs, "-D", "GOPPC64_power9")
+			fallthrough
+		default: // This should always be power8.
+			asmArgs = append(asmArgs, "-D", "GOPPC64_power8")
+		}
+	}
 	goasmh := pathf("%s/go_asm.h", workdir)
 	if IsRuntimePackagePath(pkg) {
 		asmArgs = append(asmArgs, "-compiling-runtime")
@@ -832,7 +867,7 @@
 		var wg sync.WaitGroup
 		asmabis := append(asmArgs[:len(asmArgs):len(asmArgs)], "-gensymabis", "-o", symabis)
 		asmabis = append(asmabis, sfiles...)
-		if err := ioutil.WriteFile(goasmh, nil, 0666); err != nil {
+		if err := os.WriteFile(goasmh, nil, 0666); err != nil {
 			fatalf("cannot write empty go_asm.h: %s", err)
 		}
 		bgrun(&wg, dir, asmabis...)
@@ -852,7 +887,7 @@
 		fmt.Fprintf(buf, "packagefile %s=%s\n", dep, packagefile(dep))
 	}
 	importcfg := pathf("%s/importcfg", workdir)
-	if err := ioutil.WriteFile(importcfg, buf.Bytes(), 0666); err != nil {
+	if err := os.WriteFile(importcfg, buf.Bytes(), 0666); err != nil {
 		fatalf("cannot write importcfg file: %v", err)
 	}
 
@@ -934,11 +969,12 @@
 // packagefile returns the path to a compiled .a file for the given package
 // path. Paths may need to be resolved with resolveVendor first.
 func packagefile(pkg string) string {
-	return pathf("%s/pkg/%s_%s/%s.a", goroot, goos, goarch, pkg)
+	return pathf("%s/pkg/obj/go-bootstrap/%s_%s/%s.a", goroot, goos, goarch, pkg)
 }
 
 // unixOS is the set of GOOS values matched by the "unix" build tag.
-// This is the same list as in go/build/syslist.go.
+// This is the same list as in go/build/syslist.go and
+// cmd/go/internal/imports/build.go.
 var unixOS = map[string]bool{
 	"aix":       true,
 	"android":   true,
@@ -1228,18 +1264,10 @@
 // The bootstrap command runs a build from scratch,
 // stopping at having installed the go_bootstrap command.
 //
-// WARNING: This command runs after cmd/dist is built with Go 1.4.
+// WARNING: This command runs after cmd/dist is built with the Go bootstrap toolchain.
 // It rebuilds and installs cmd/dist with the new toolchain, so other
 // commands (like "go tool dist test" in run.bash) can rely on bug fixes
-// made since Go 1.4, but this function cannot. In particular, the uses
-// of os/exec in this function cannot assume that
-//
-//	cmd.Env = append(os.Environ(), "X=Y")
-//
-// sets $X to Y in the command's environment. That guarantee was
-// added after Go 1.4, and in fact in Go 1.4 it was typically the opposite:
-// if $X was already present in os.Environ(), most systems preferred
-// that setting, not the new one.
+// made since the Go bootstrap version, but this function cannot.
 func cmdbootstrap() {
 	timelog("start", "dist bootstrap")
 	defer timelog("end", "dist bootstrap")
@@ -1325,6 +1353,7 @@
 	}
 
 	gogcflags = os.Getenv("GO_GCFLAGS") // we were using $BOOT_GO_GCFLAGS until now
+	setNoOpt()
 	goldflags = os.Getenv("GO_LDFLAGS") // we were using $BOOT_GO_LDFLAGS until now
 	goBootstrap := pathf("%s/go_bootstrap", tooldir)
 	cmdGo := pathf("%s/go", gorootBin)
@@ -1335,11 +1364,11 @@
 
 	// To recap, so far we have built the new toolchain
 	// (cmd/asm, cmd/cgo, cmd/compile, cmd/link)
-	// using Go 1.4's toolchain and go command.
+	// using the Go bootstrap toolchain and go command.
 	// Then we built the new go command (as go_bootstrap)
 	// using the new toolchain and our own build logic (above).
 	//
-	//	toolchain1 = mk(new toolchain, go1.4 toolchain, go1.4 cmd/go)
+	//	toolchain1 = mk(new toolchain, go1.17 toolchain, go1.17 cmd/go)
 	//	go_bootstrap = mk(new cmd/go, toolchain1, cmd/dist)
 	//
 	// The toolchain1 we built earlier is built from the new sources,
@@ -1357,15 +1386,14 @@
 	os.Setenv("CC", compilerEnvLookup(defaultcc, goos, goarch))
 	// Now that cmd/go is in charge of the build process, enable GOEXPERIMENT.
 	os.Setenv("GOEXPERIMENT", goexperiment)
-	goInstall(goBootstrap, append([]string{"-i"}, toolchain...)...)
+	goInstall(goBootstrap, toolchain...)
 	if debug {
 		run("", ShowOutput|CheckExit, pathf("%s/compile", tooldir), "-V=full")
-		run("", ShowOutput|CheckExit, pathf("%s/buildid", tooldir), pathf("%s/pkg/%s_%s/runtime/internal/sys.a", goroot, goos, goarch))
 		copyfile(pathf("%s/compile2", tooldir), pathf("%s/compile", tooldir), writeExec)
 	}
 
 	// Toolchain2 should be semantically equivalent to toolchain1,
-	// but it was built using the new compilers instead of the Go 1.4 compilers,
+	// but it was built using the newly built compiler instead of the Go bootstrap compiler,
 	// so it should at the least run faster. Also, toolchain1 had no build IDs
 	// in the binaries, while toolchain2 does. In non-release builds, the
 	// toolchain's build IDs feed into constructing the build IDs of built targets,
@@ -1385,13 +1413,11 @@
 		xprintf("\n")
 	}
 	xprintf("Building Go toolchain3 using go_bootstrap and Go toolchain2.\n")
-	goInstall(goBootstrap, append([]string{"-a", "-i"}, toolchain...)...)
+	goInstall(goBootstrap, append([]string{"-a"}, toolchain...)...)
 	if debug {
 		run("", ShowOutput|CheckExit, pathf("%s/compile", tooldir), "-V=full")
-		run("", ShowOutput|CheckExit, pathf("%s/buildid", tooldir), pathf("%s/pkg/%s_%s/runtime/internal/sys.a", goroot, goos, goarch))
 		copyfile(pathf("%s/compile3", tooldir), pathf("%s/compile", tooldir), writeExec)
 	}
-	checkNotStale(goBootstrap, append(toolchain, "runtime/internal/sys")...)
 
 	if goos == oldgoos && goarch == oldgoarch {
 		// Common case - not setting up for cross-compilation.
@@ -1425,16 +1451,12 @@
 		xprintf("Building packages and commands for target, %s/%s.\n", goos, goarch)
 	}
 	targets := []string{"std", "cmd"}
-	if goos == "js" && goarch == "wasm" {
-		// Skip the cmd tools for js/wasm. They're not usable.
-		targets = targets[:1]
-	}
 	goInstall(goBootstrap, targets...)
+	checkNotStale(goBootstrap, append(toolchain, "runtime/internal/sys")...)
 	checkNotStale(goBootstrap, targets...)
 	checkNotStale(cmdGo, targets...)
 	if debug {
 		run("", ShowOutput|CheckExit, pathf("%s/compile", tooldir), "-V=full")
-		run("", ShowOutput|CheckExit, pathf("%s/buildid", tooldir), pathf("%s/pkg/%s_%s/runtime/internal/sys.a", goroot, goos, goarch))
 		checkNotStale(goBootstrap, append(toolchain, "runtime/internal/sys")...)
 		copyfile(pathf("%s/compile4", tooldir), pathf("%s/compile", tooldir), writeExec)
 	}
@@ -1510,6 +1532,9 @@
 
 func goCmd(goBinary string, cmd string, args ...string) {
 	goCmd := []string{goBinary, cmd}
+	if noOpt {
+		goCmd = append(goCmd, "-tags=noopt")
+	}
 	goCmd = appendCompilerFlags(goCmd)
 	if vflag > 0 {
 		goCmd = append(goCmd, "-v")
@@ -1525,6 +1550,9 @@
 
 func checkNotStale(goBinary string, targets ...string) {
 	goCmd := []string{goBinary, "list"}
+	if noOpt {
+		goCmd = append(goCmd, "-tags=noopt")
+	}
 	goCmd = appendCompilerFlags(goCmd)
 	goCmd = append(goCmd, "-f={{if .Stale}}\tSTALE {{.ImportPath}}: {{.StaleReason}}{{end}}")
 
@@ -1557,6 +1585,7 @@
 	"freebsd/amd64":   true,
 	"freebsd/arm":     true,
 	"freebsd/arm64":   true,
+	"freebsd/riscv64": true,
 	"illumos/amd64":   true,
 	"linux/386":       true,
 	"linux/amd64":     true,
@@ -1800,3 +1829,12 @@
 	}
 	return rval
 }
+
+func setNoOpt() {
+	for _, gcflag := range strings.Split(gogcflags, " ") {
+		if gcflag == "-N" || gcflag == "-l" {
+			noOpt = true
+			break
+		}
+	}
+}
diff --git a/src/cmd/dist/buildgo.go b/src/cmd/dist/buildgo.go
index 520dde7..29b0167 100644
--- a/src/cmd/dist/buildgo.go
+++ b/src/cmd/dist/buildgo.go
@@ -5,7 +5,6 @@
 package main
 
 import (
-	"bytes"
 	"fmt"
 	"os"
 	"path/filepath"
@@ -28,7 +27,7 @@
 // but we also write cmd/cgo/zdefaultcc.go
 func mkzdefaultcc(dir, file string) {
 	if strings.Contains(file, filepath.FromSlash("go/internal/cfg")) {
-		var buf bytes.Buffer
+		var buf strings.Builder
 		fmt.Fprintf(&buf, "// Code generated by go tool dist; DO NOT EDIT.\n")
 		fmt.Fprintln(&buf)
 		fmt.Fprintf(&buf, "package cfg\n")
@@ -40,7 +39,7 @@
 		return
 	}
 
-	var buf bytes.Buffer
+	var buf strings.Builder
 	fmt.Fprintf(&buf, "// Code generated by go tool dist; DO NOT EDIT.\n")
 	fmt.Fprintln(&buf)
 	fmt.Fprintf(&buf, "package main\n")
@@ -52,7 +51,7 @@
 }
 
 func defaultCCFunc(name string, defaultcc map[string]string) string {
-	var buf bytes.Buffer
+	var buf strings.Builder
 
 	fmt.Fprintf(&buf, "func %s(goos, goarch string) string {\n", name)
 	fmt.Fprintf(&buf, "\tswitch goos+`/`+goarch {\n")
@@ -82,7 +81,7 @@
 	}
 	sort.Strings(list)
 
-	var buf bytes.Buffer
+	var buf strings.Builder
 	fmt.Fprintf(&buf, "// Code generated by go tool dist; DO NOT EDIT.\n\n")
 	fmt.Fprintf(&buf, "package cfg\n\n")
 	fmt.Fprintf(&buf, "var OSArchSupportsCgo = map[string]bool{\n")
@@ -110,7 +109,7 @@
 	}
 	sort.Strings(list)
 
-	var buf bytes.Buffer
+	var buf strings.Builder
 	fmt.Fprintf(&buf, "// Code generated by go tool dist; DO NOT EDIT.\n")
 	fmt.Fprintln(&buf)
 	fmt.Fprintf(&buf, "package build\n")
diff --git a/src/cmd/dist/buildruntime.go b/src/cmd/dist/buildruntime.go
index e66a9f0..932c509 100644
--- a/src/cmd/dist/buildruntime.go
+++ b/src/cmd/dist/buildruntime.go
@@ -5,9 +5,7 @@
 package main
 
 import (
-	"bytes"
 	"fmt"
-	"os"
 	"strings"
 )
 
@@ -19,15 +17,12 @@
 //
 //	package sys
 //
-//	const StackGuardMultiplier = <multiplier value>
+// (Nothing right now!)
 func mkzversion(dir, file string) {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	fmt.Fprintf(&buf, "// Code generated by go tool dist; DO NOT EDIT.\n")
 	fmt.Fprintln(&buf)
 	fmt.Fprintf(&buf, "package sys\n")
-	fmt.Fprintln(&buf)
-	fmt.Fprintf(&buf, "const StackGuardMultiplierDefault = %d\n", stackGuardMultiplierDefault())
-
 	writefile(buf.String(), file, writeSkipSame)
 }
 
@@ -51,7 +46,7 @@
 // This is more useful than having it default to generating objects for the
 // original target (in this example, a Mac).
 func mkbuildcfg(file string) {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	fmt.Fprintf(&buf, "// Code generated by go tool dist; DO NOT EDIT.\n")
 	fmt.Fprintln(&buf)
 	fmt.Fprintf(&buf, "package buildcfg\n")
@@ -78,26 +73,12 @@
 //
 //	package objabi
 //
-//	const stackGuardMultiplierDefault = <multiplier value>
+// (Nothing right now!)
 func mkobjabi(file string) {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	fmt.Fprintf(&buf, "// Code generated by go tool dist; DO NOT EDIT.\n")
 	fmt.Fprintln(&buf)
 	fmt.Fprintf(&buf, "package objabi\n")
-	fmt.Fprintln(&buf)
-	fmt.Fprintf(&buf, "const stackGuardMultiplierDefault = %d\n", stackGuardMultiplierDefault())
 
 	writefile(buf.String(), file, writeSkipSame)
 }
-
-// stackGuardMultiplierDefault returns a multiplier to apply to the default
-// stack guard size. Larger multipliers are used for non-optimized
-// builds that have larger stack frames.
-func stackGuardMultiplierDefault() int {
-	for _, s := range strings.Split(os.Getenv("GO_GCFLAGS"), " ") {
-		if s == "-N" {
-			return 2
-		}
-	}
-	return 1
-}
diff --git a/src/cmd/dist/buildtool.go b/src/cmd/dist/buildtool.go
index 400c2e8..c4e3660 100644
--- a/src/cmd/dist/buildtool.go
+++ b/src/cmd/dist/buildtool.go
@@ -2,11 +2,11 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Build toolchain using Go 1.4.
+// Build toolchain using Go bootstrap version.
 //
 // The general strategy is to copy the source files we need into
 // a new GOPATH workspace, adjust import paths appropriately,
-// invoke the Go 1.4 go command to build those sources,
+// invoke the Go bootstrap toolchains go command to build those sources,
 // and then copy the binaries back.
 
 package main
@@ -20,13 +20,13 @@
 )
 
 // bootstrapDirs is a list of directories holding code that must be
-// compiled with a Go 1.4 toolchain to produce the bootstrapTargets.
+// compiled with the Go bootstrap toolchain to produce the bootstrapTargets.
 // All directories in this list are relative to and must be below $GOROOT/src.
 //
 // The list has two kinds of entries: names beginning with cmd/ with
 // no other slashes, which are commands, and other paths, which are packages
 // supporting the commands. Packages in the standard library can be listed
-// if a newer copy needs to be substituted for the Go 1.4 copy when used
+// if a newer copy needs to be substituted for the Go bootstrap copy when used
 // by the command packages. Paths ending with /... automatically
 // include all packages within subdirectories as well.
 // These will be imported during bootstrap as bootstrap/name, like bootstrap/math/big.
@@ -60,11 +60,17 @@
 	"debug/macho",
 	"debug/pe",
 	"go/constant",
+	"internal/coverage",
 	"internal/buildcfg",
 	"internal/goexperiment",
+	"internal/goroot",
 	"internal/goversion",
 	"internal/pkgbits",
+	"internal/profile",
 	"internal/race",
+	"internal/saferio",
+	"internal/platform",
+	"internal/types/errors",
 	"internal/unsafeheader",
 	"internal/xcoff",
 	"math/big",
@@ -81,18 +87,10 @@
 	"#",
 }
 
-// File suffixes that use build tags introduced since Go 1.4.
+// File suffixes that use build tags introduced since Go 1.17.
 // These must not be copied into the bootstrap build directory.
 // Also ignore test files.
 var ignoreSuffixes = []string{
-	"_arm64.s",
-	"_arm64.go",
-	"_loong64.s",
-	"_loong64.go",
-	"_riscv64.s",
-	"_riscv64.go",
-	"_wasm.s",
-	"_wasm.go",
 	"_test.s",
 	"_test.go",
 }
@@ -175,12 +173,12 @@
 		})
 	}
 
-	// Set up environment for invoking Go 1.4 go command.
-	// GOROOT points at Go 1.4 GOROOT,
+	// Set up environment for invoking Go bootstrap toolchains go command.
+	// GOROOT points at Go bootstrap GOROOT,
 	// GOPATH points at our bootstrap workspace,
 	// GOBIN is empty, so that binaries are installed to GOPATH/bin,
 	// and GOOS, GOHOSTOS, GOARCH, and GOHOSTOS are empty,
-	// so that Go 1.4 builds whatever kind of binary it knows how to build.
+	// so that Go bootstrap toolchain builds whatever kind of binary it knows how to build.
 	// Restore GOROOT, GOPATH, and GOBIN when done.
 	// Don't bother with GOOS, GOHOSTOS, GOARCH, and GOHOSTARCH,
 	// because setup will take care of those when bootstrapBuildTools returns.
@@ -199,20 +197,14 @@
 	os.Setenv("GOARCH", "")
 	os.Setenv("GOHOSTARCH", "")
 
-	// Run Go 1.4 to build binaries. Use -gcflags=-l to disable inlining to
-	// workaround bugs in Go 1.4's compiler. See discussion thread:
-	// https://groups.google.com/d/msg/golang-dev/Ss7mCKsvk8w/Gsq7VYI0AwAJ
+	// Run Go bootstrap to build binaries.
 	// Use the math_big_pure_go build tag to disable the assembly in math/big
 	// which may contain unsupported instructions.
 	// Use the purego build tag to disable other assembly code,
 	// such as in cmd/internal/notsha256.
-	// Note that if we are using Go 1.10 or later as bootstrap, the -gcflags=-l
-	// only applies to the final cmd/go binary, but that's OK: if this is Go 1.10
-	// or later we don't need to disable inlining to work around bugs in the Go 1.4 compiler.
 	cmd := []string{
 		pathf("%s/bin/go", goroot_bootstrap),
 		"install",
-		"-gcflags=-l",
 		"-tags=math_big_pure_go compiler_bootstrap purego",
 	}
 	if vflag > 0 {
@@ -263,6 +255,7 @@
 	archCaps = fileArch
 	fileArch = strings.ToLower(fileArch)
 	fileArch = strings.TrimSuffix(fileArch, "splitload")
+	fileArch = strings.TrimSuffix(fileArch, "latelower")
 	if fileArch == goArch {
 		return "", false
 	}
diff --git a/src/cmd/dist/exec.go b/src/cmd/dist/exec.go
deleted file mode 100644
index 6730553..0000000
--- a/src/cmd/dist/exec.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import (
-	"os"
-	"os/exec"
-	"strings"
-)
-
-// setDir sets cmd.Dir to dir, and also adds PWD=dir to cmd's environment.
-func setDir(cmd *exec.Cmd, dir string) {
-	cmd.Dir = dir
-	setEnv(cmd, "PWD", dir)
-}
-
-// setEnv sets cmd.Env so that key = value.
-//
-// It first removes any existing values for key, so it is safe to call
-// even from within cmdbootstrap.
-func setEnv(cmd *exec.Cmd, key, value string) {
-	kv := key + "=" + value
-	if cmd.Env == nil {
-		cmd.Env = os.Environ()
-	}
-
-	prefix := kv[:len(key)+1]
-	for i, entry := range cmd.Env {
-		if strings.HasPrefix(entry, prefix) {
-			cmd.Env[i] = kv
-			return
-		}
-	}
-
-	cmd.Env = append(cmd.Env, kv)
-}
-
-// unsetEnv sets cmd.Env so that key is not present in the environment.
-func unsetEnv(cmd *exec.Cmd, key string) {
-	if cmd.Env == nil {
-		cmd.Env = os.Environ()
-	}
-
-	prefix := key + "="
-	for i, entry := range cmd.Env {
-		if strings.HasPrefix(entry, prefix) {
-			cmd.Env = append(cmd.Env[:i], cmd.Env[i+1:]...)
-			return
-		}
-	}
-}
diff --git a/src/cmd/dist/exec_118.go b/src/cmd/dist/exec_118.go
new file mode 100644
index 0000000..a1c3c64
--- /dev/null
+++ b/src/cmd/dist/exec_118.go
@@ -0,0 +1,47 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !go1.19
+// +build !go1.19
+
+package main
+
+import (
+	"os"
+	"os/exec"
+	"strings"
+)
+
+// setDir sets cmd.Dir to dir, and also adds PWD=dir to cmd's environment.
+func setDir(cmd *exec.Cmd, dir string) {
+	cmd.Dir = dir
+	setEnv(cmd, "PWD", dir)
+}
+
+// setEnv sets cmd.Env so that key = value.
+func setEnv(cmd *exec.Cmd, key, value string) {
+	kv := key + "=" + value
+	if cmd.Env == nil {
+		cmd.Env = os.Environ()
+	}
+	cmd.Env = append(cmd.Env, kv)
+}
+
+// unsetEnv sets cmd.Env so that key is not present in the environment.
+func unsetEnv(cmd *exec.Cmd, key string) {
+	if cmd.Env == nil {
+		cmd.Env = os.Environ()
+	}
+
+	prefix := key + "="
+	newEnv := []string{}
+	for _, entry := range cmd.Env {
+		if strings.HasPrefix(entry, prefix) {
+			continue
+		}
+		newEnv = append(newEnv, entry)
+		// key may appear multiple times, so keep going.
+	}
+	cmd.Env = newEnv
+}
diff --git a/src/cmd/dist/exec_119.go b/src/cmd/dist/exec_119.go
new file mode 100644
index 0000000..0b4baa0
--- /dev/null
+++ b/src/cmd/dist/exec_119.go
@@ -0,0 +1,43 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.19
+// +build go1.19
+
+package main
+
+import (
+	"os/exec"
+	"strings"
+)
+
+// setDir sets cmd.Dir to dir, and also adds PWD=dir to cmd's environment.
+func setDir(cmd *exec.Cmd, dir string) {
+	cmd.Dir = dir
+	if cmd.Env != nil {
+		// os/exec won't set PWD automatically.
+		setEnv(cmd, "PWD", dir)
+	}
+}
+
+// setEnv sets cmd.Env so that key = value.
+func setEnv(cmd *exec.Cmd, key, value string) {
+	cmd.Env = append(cmd.Environ(), key+"="+value)
+}
+
+// unsetEnv sets cmd.Env so that key is not present in the environment.
+func unsetEnv(cmd *exec.Cmd, key string) {
+	cmd.Env = cmd.Environ()
+
+	prefix := key + "="
+	newEnv := []string{}
+	for _, entry := range cmd.Env {
+		if strings.HasPrefix(entry, prefix) {
+			continue
+		}
+		newEnv = append(newEnv, entry)
+		// key may appear multiple times, so keep going.
+	}
+	cmd.Env = newEnv
+}
diff --git a/src/cmd/dist/main.go b/src/cmd/dist/main.go
index 2651ecb..6194ea9 100644
--- a/src/cmd/dist/main.go
+++ b/src/cmd/dist/main.go
@@ -143,6 +143,10 @@
 			if strings.Contains(run("", CheckExit, "uname", "-v"), "RELEASE_ARM64_") {
 				gohostarch = "arm64"
 			}
+		case gohostos == "freebsd":
+			if strings.Contains(run("", CheckExit, "uname", "-p"), "riscv64") {
+				gohostarch = "riscv64"
+			}
 		case gohostos == "openbsd":
 			if strings.Contains(run("", CheckExit, "uname", "-p"), "mips64") {
 				gohostarch = "mips64"
@@ -155,6 +159,12 @@
 	if gohostarch == "arm" || gohostarch == "mips64" || gohostarch == "mips64le" {
 		maxbg = min(maxbg, runtime.NumCPU())
 	}
+	// For deterministic make.bash debugging and for smallest-possible footprint,
+	// pay attention to GOMAXPROCS=1.  This was a bad idea for 1.4 bootstrap, but
+	// the bootstrap version is now 1.17+ and thus this is fine.
+	if runtime.GOMAXPROCS(0) == 1 {
+		maxbg = 1
+	}
 	bginit()
 
 	if len(os.Args) > 1 && os.Args[1] == "-check-goarm" {
diff --git a/src/cmd/dist/notgo117.go b/src/cmd/dist/notgo117.go
new file mode 100644
index 0000000..8d551df
--- /dev/null
+++ b/src/cmd/dist/notgo117.go
@@ -0,0 +1,22 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Go 1.20 and later requires Go 1.17 as the bootstrap toolchain.
+// If cmd/dist is built using an earlier Go version, this file will be
+// included in the build and cause an error like:
+//
+// % GOROOT_BOOTSTRAP=$HOME/sdk/go1.16 ./make.bash
+// Building Go cmd/dist using /Users/rsc/sdk/go1.16. (go1.16 darwin/amd64)
+// found packages main (build.go) and building_Go_requires_Go_1_17_13_or_later (notgo117.go) in /Users/rsc/go/src/cmd/dist
+// %
+//
+// which is the best we can do under the circumstances.
+//
+// See go.dev/issue/44505 for more background on
+// why Go moved on from Go 1.4 for bootstrap.
+
+//go:build !go1.17
+// +build !go1.17
+
+package building_Go_requires_Go_1_17_13_or_later
diff --git a/src/cmd/dist/quoted.go b/src/cmd/dist/quoted.go
index e87b8a3..9f30581 100644
--- a/src/cmd/dist/quoted.go
+++ b/src/cmd/dist/quoted.go
@@ -1,3 +1,7 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
 package main
 
 import "fmt"
diff --git a/src/cmd/dist/test.go b/src/cmd/dist/test.go
index da5b179..9f26606 100644
--- a/src/cmd/dist/test.go
+++ b/src/cmd/dist/test.go
@@ -8,11 +8,10 @@
 	"bytes"
 	"flag"
 	"fmt"
-	"io/ioutil"
+	"io/fs"
 	"log"
 	"os"
 	"os/exec"
-	"path"
 	"path/filepath"
 	"reflect"
 	"regexp"
@@ -25,6 +24,7 @@
 
 func cmdtest() {
 	gogcflags = os.Getenv("GO_GCFLAGS")
+	setNoOpt()
 
 	var t tester
 
@@ -67,9 +67,12 @@
 	banner      string   // prefix, or "" for none
 	lastHeading string   // last dir heading printed
 
+	short      bool
 	cgoEnabled bool
 	partial    bool
-	haveTime   bool // the 'time' binary is available
+
+	goExe    string // For host tests
+	goTmpDir string // For host tests
 
 	tests        []distTest
 	timeoutScale int
@@ -99,25 +102,35 @@
 
 	os.Setenv("PATH", fmt.Sprintf("%s%c%s", gorootBin, os.PathListSeparator, os.Getenv("PATH")))
 
-	cmd := exec.Command(gorootBinGo, "env", "CGO_ENABLED")
+	t.short = true
+	if v := os.Getenv("GO_TEST_SHORT"); v != "" {
+		short, err := strconv.ParseBool(v)
+		if err != nil {
+			fatalf("invalid GO_TEST_SHORT %q: %v", v, err)
+		}
+		t.short = short
+	}
+
+	cmd := exec.Command(gorootBinGo, "env", "CGO_ENABLED", "GOEXE", "GOTMPDIR")
 	cmd.Stderr = new(bytes.Buffer)
 	slurp, err := cmd.Output()
 	if err != nil {
-		fatalf("Error running go env CGO_ENABLED: %v\n%s", err, cmd.Stderr)
+		fatalf("Error running %s: %v\n%s", cmd, err, cmd.Stderr)
 	}
-	t.cgoEnabled, _ = strconv.ParseBool(strings.TrimSpace(string(slurp)))
+	parts := strings.Split(string(slurp), "\n")
+	if len(parts) < 3 {
+		fatalf("Error running %s: output contains <3 lines\n%s", cmd, cmd.Stderr)
+	}
+	t.cgoEnabled, _ = strconv.ParseBool(parts[0])
+	t.goExe = parts[1]
+	t.goTmpDir = parts[2]
+
 	if flag.NArg() > 0 && t.runRxStr != "" {
 		fatalf("the -run regular expression flag is mutually exclusive with test name arguments")
 	}
 
 	t.runNames = flag.Args()
 
-	if t.hasBash() {
-		if _, err := exec.LookPath("time"); err == nil {
-			t.haveTime = true
-		}
-	}
-
 	// Set GOTRACEBACK to system if the user didn't set a level explicitly.
 	// Since we're running tests for Go, we want as much detail as possible
 	// if something goes wrong.
@@ -136,11 +149,11 @@
 	if t.rebuild {
 		t.out("Building packages and commands.")
 		// Force rebuild the whole toolchain.
-		goInstall("go", append([]string{"-a", "-i"}, toolchain...)...)
+		goInstall("go", append([]string{"-a"}, toolchain...)...)
 	}
 
 	if !t.listMode {
-		if os.Getenv("GO_BUILDER_NAME") == "" {
+		if builder := os.Getenv("GO_BUILDER_NAME"); builder == "" {
 			// Complete rebuild bootstrap, even with -no-rebuild.
 			// If everything is up-to-date, this is a no-op.
 			// If everything is not up-to-date, the first checkNotStale
@@ -153,8 +166,8 @@
 			// to break if we don't automatically refresh things here.
 			// Rebuilding is a shortened bootstrap.
 			// See cmdbootstrap for a description of the overall process.
-			goInstall("go", append([]string{"-i"}, toolchain...)...)
-			goInstall("go", append([]string{"-i"}, toolchain...)...)
+			goInstall("go", toolchain...)
+			goInstall("go", toolchain...)
 			goInstall("go", "std", "cmd")
 		} else {
 			// The Go builder infrastructure should always begin running tests from a
@@ -162,11 +175,19 @@
 			// Instead, we can just check that it is not stale, which may be less
 			// expensive (and is also more likely to catch bugs in the builder
 			// implementation).
-			willTest := []string{"std"}
-			if t.shouldTestCmd() {
-				willTest = append(willTest, "cmd")
+			// The cache used by dist when building is different from that used when
+			// running dist test, so rebuild (but don't install) std and cmd to make
+			// sure packages without install targets are cached so they are not stale.
+			goCmd("go", "build", "std", "cmd") // make sure dependencies of targets are cached
+			if builder == "aix-ppc64" {
+				// The aix-ppc64 builder for some reason does not have deterministic cgo
+				// builds, so "cmd" is stale. Fortunately, most of the tests don't care.
+				// TODO(#56896): remove this special case once the builder supports
+				// determistic cgo builds.
+				checkNotStale("go", "std")
+			} else {
+				checkNotStale("go", "std", "cmd")
 			}
-			checkNotStale("go", willTest...)
 		}
 	}
 
@@ -293,55 +314,235 @@
 	return t.dirCmd(filepath.Join(goroot, "src/cmd/internal/metadata"), "go", []string{"run", "main.go"}).Run()
 }
 
-// short returns a -short flag value to use with 'go test'
-// or a test binary for tests intended to run in short mode.
-// It returns "true", unless the environment variable
-// GO_TEST_SHORT is set to a non-empty, false-ish string.
+// goTest represents all options to a "go test" command. The final command will
+// combine configuration from goTest and tester flags.
+type goTest struct {
+	timeout  time.Duration // If non-zero, override timeout
+	short    bool          // If true, force -short
+	tags     []string      // Build tags
+	race     bool          // Force -race
+	bench    bool          // Run benchmarks (briefly), not tests.
+	runTests string        // Regexp of tests to run
+	cpu      string        // If non-empty, -cpu flag
+	goroot   string        // If non-empty, use alternate goroot for go command
+
+	gcflags   string // If non-empty, build with -gcflags=all=X
+	ldflags   string // If non-empty, build with -ldflags=X
+	buildmode string // If non-empty, -buildmode flag
+
+	dir string   // If non-empty, run in GOROOT/src-relative directory dir
+	env []string // Environment variables to add, as KEY=VAL. KEY= unsets a variable
+
+	// We have both pkg and pkgs as a convenience. Both may be set, in which
+	// case they will be combined. If both are empty, the default is ".".
+	pkgs []string // Multiple packages to test
+	pkg  string   // A single package to test
+
+	testFlags []string // Additional flags accepted by this test
+}
+
+// bgCommand returns a go test Cmd. The result has Stdout and Stderr set to nil
+// and is intended to be added to the work queue.
+func (opts *goTest) bgCommand(t *tester) *exec.Cmd {
+	goCmd, build, run, pkgs, setupCmd := opts.buildArgs(t)
+
+	// Combine the flags.
+	args := append([]string{"test"}, build...)
+	if t.compileOnly {
+		// We can't pass -c with multiple packages, so run the tests but
+		// tell them not to do anything.
+		args = append(args, "-run=^$")
+	} else {
+		args = append(args, run...)
+	}
+	args = append(args, pkgs...)
+	if !t.compileOnly {
+		args = append(args, opts.testFlags...)
+	}
+
+	cmd := exec.Command(goCmd, args...)
+	setupCmd(cmd)
+
+	return cmd
+}
+
+// command returns a go test Cmd intended to be run immediately.
+func (opts *goTest) command(t *tester) *exec.Cmd {
+	cmd := opts.bgCommand(t)
+	cmd.Stdout = os.Stdout
+	cmd.Stderr = os.Stderr
+	return cmd
+}
+
+func (opts *goTest) run(t *tester) error {
+	return opts.command(t).Run()
+}
+
+// runHostTest runs a test that should be built and run on the host GOOS/GOARCH,
+// but run with GOOS/GOARCH set to the target GOOS/GOARCH. This is for tests
+// that do nothing but compile and run other binaries. If the host and target
+// are different, then the assumption is that the target is running in an
+// emulator and does not have a Go toolchain at all, so the test needs to run on
+// the host, but its resulting binaries will be run through a go_exec wrapper
+// that runs them on the target.
+func (opts *goTest) runHostTest(t *tester) error {
+	goCmd, build, run, pkgs, setupCmd := opts.buildArgs(t)
+
+	// Build the host test binary
+	if len(pkgs) != 1 {
+		// We can't compile more than one package.
+		panic("host tests must have a single test package")
+	}
+	if len(opts.env) != 0 {
+		// It's not clear if these are for the host or the target.
+		panic("host tests must not have environment variables")
+	}
+
+	f, err := os.CreateTemp(t.goTmpDir, "test.test-*"+t.goExe)
+	if err != nil {
+		fatalf("failed to create temporary file: %s", err)
+	}
+	bin := f.Name()
+	f.Close()
+	xatexit(func() { os.Remove(bin) })
+
+	args := append([]string{"test", "-c", "-o", bin}, build...)
+	args = append(args, pkgs...)
+	cmd := exec.Command(goCmd, args...)
+	setupCmd(cmd)
+	cmd.Stdout = os.Stdout
+	cmd.Stderr = os.Stderr
+	setEnv(cmd, "GOARCH", gohostarch)
+	setEnv(cmd, "GOOS", gohostos)
+	if vflag > 1 {
+		errprintf("%s\n", cmd)
+	}
+	if err := cmd.Run(); err != nil {
+		return err
+	}
+
+	if t.compileOnly {
+		return nil
+	}
+
+	// Transform run flags to be passed directly to a test binary.
+	for i, f := range run {
+		if !strings.HasPrefix(f, "-") {
+			panic("run flag does not start with -: " + f)
+		}
+		run[i] = "-test." + f[1:]
+	}
+
+	// Run the test
+	args = append(run, opts.testFlags...)
+	cmd = exec.Command(bin, args...)
+	setupCmd(cmd)
+	cmd.Stdout = os.Stdout
+	cmd.Stderr = os.Stderr
+	if vflag > 1 {
+		errprintf("%s\n", cmd)
+	}
+	return cmd.Run()
+}
+
+// buildArgs is in internal helper for goTest that constructs the elements of
+// the "go test" command line. goCmd is the path to the go command to use. build
+// is the flags for building the test. run is the flags for running the test.
+// pkgs is the list of packages to build and run.
 //
-// This environment variable is meant to be an internal
-// detail between the Go build system and cmd/dist for
-// the purpose of longtest builders, and is not intended
-// for use by users. See golang.org/issue/12508.
-func short() string {
-	if v := os.Getenv("GO_TEST_SHORT"); v != "" {
-		short, err := strconv.ParseBool(v)
-		if err != nil {
-			fatalf("invalid GO_TEST_SHORT %q: %v", v, err)
-		}
-		if !short {
-			return "false"
-		}
+// The caller is responsible for adding opts.testFlags, and must call setupCmd
+// on the resulting exec.Cmd to set its directory and environment.
+func (opts *goTest) buildArgs(t *tester) (goCmd string, build, run, pkgs []string, setupCmd func(*exec.Cmd)) {
+	goCmd = gorootBinGo
+	if opts.goroot != "" {
+		goCmd = filepath.Join(opts.goroot, "bin", "go")
 	}
-	return "true"
-}
 
-// goTest returns the beginning of the go test command line.
-// Callers should use goTest and then pass flags overriding these
-// defaults as later arguments in the command line.
-func (t *tester) goTest() []string {
-	return []string{
-		"go", "test", "-short=" + short(), "-count=1", t.tags(), t.runFlag(""),
+	run = append(run, "-count=1") // Disallow caching
+	if opts.timeout != 0 {
+		d := opts.timeout * time.Duration(t.timeoutScale)
+		run = append(run, "-timeout="+d.String())
 	}
-}
-
-func (t *tester) tags() string {
+	if opts.short || t.short {
+		run = append(run, "-short")
+	}
+	var tags []string
 	if t.iOS() {
-		return "-tags=lldb"
+		tags = append(tags, "lldb")
 	}
-	return "-tags="
-}
+	if noOpt {
+		tags = append(tags, "noopt")
+	}
+	tags = append(tags, opts.tags...)
+	if len(tags) > 0 {
+		build = append(build, "-tags="+strings.Join(tags, ","))
+	}
+	if t.race || opts.race {
+		build = append(build, "-race")
+	}
+	if t.msan {
+		build = append(build, "-msan")
+	}
+	if t.asan {
+		build = append(build, "-asan")
+	}
+	if opts.bench {
+		// Run no tests.
+		run = append(run, "-run=^$")
+		// Run benchmarks as a smoke test
+		run = append(run, "-bench=.*", "-benchtime=.1s")
+	} else if opts.runTests != "" {
+		run = append(run, "-run="+opts.runTests)
+	}
+	if opts.cpu != "" {
+		run = append(run, "-cpu="+opts.cpu)
+	}
 
-// timeoutDuration converts the provided number of seconds into a
-// time.Duration, scaled by the t.timeoutScale factor.
-func (t *tester) timeoutDuration(sec int) time.Duration {
-	return time.Duration(sec) * time.Second * time.Duration(t.timeoutScale)
-}
+	if opts.gcflags != "" {
+		build = append(build, "-gcflags=all="+opts.gcflags)
+	}
+	if opts.ldflags != "" {
+		build = append(build, "-ldflags="+opts.ldflags)
+	}
+	if opts.buildmode != "" {
+		build = append(build, "-buildmode="+opts.buildmode)
+	}
 
-// timeout returns the "-timeout=" string argument to "go test" given
-// the number of seconds of timeout. It scales it by the
-// t.timeoutScale factor.
-func (t *tester) timeout(sec int) string {
-	return "-timeout=" + t.timeoutDuration(sec).String()
+	pkgs = opts.pkgs
+	if opts.pkg != "" {
+		pkgs = append(pkgs[:len(pkgs):len(pkgs)], opts.pkg)
+	}
+	if len(pkgs) == 0 {
+		pkgs = []string{"."}
+	}
+
+	thisGoroot := goroot
+	if opts.goroot != "" {
+		thisGoroot = opts.goroot
+	}
+	var dir string
+	if opts.dir != "" {
+		if filepath.IsAbs(opts.dir) {
+			panic("dir must be relative, got: " + opts.dir)
+		}
+		dir = filepath.Join(thisGoroot, "src", opts.dir)
+	} else {
+		dir = filepath.Join(thisGoroot, "src")
+	}
+	setupCmd = func(cmd *exec.Cmd) {
+		setDir(cmd, dir)
+		if len(opts.env) != 0 {
+			for _, kv := range opts.env {
+				if i := strings.Index(kv, "="); i < 0 {
+					unsetEnv(cmd, kv[:len(kv)-1])
+				} else {
+					setEnv(cmd, kv[:i], kv[i+1:])
+				}
+			}
+		}
+	}
+
+	return
 }
 
 // ranGoTest and stdMatches are state closed over by the stdlib
@@ -380,44 +581,18 @@
 			defer timelog("end", dt.name)
 			ranGoTest = true
 
-			timeoutSec := 180
+			timeoutSec := 180 * time.Second
 			for _, pkg := range stdMatches {
 				if pkg == "cmd/go" {
 					timeoutSec *= 3
 					break
 				}
 			}
-			// Special case for our slow cross-compiled
-			// qemu builders:
-			if t.shouldUsePrecompiledStdTest() {
-				return t.runPrecompiledStdTest(t.timeoutDuration(timeoutSec))
-			}
-			args := []string{
-				"test",
-				"-short=" + short(),
-				t.tags(),
-				t.timeout(timeoutSec),
-			}
-			if gcflags != "" {
-				args = append(args, "-gcflags=all="+gcflags)
-			}
-			if t.race {
-				args = append(args, "-race")
-			}
-			if t.msan {
-				args = append(args, "-msan")
-			}
-			if t.asan {
-				args = append(args, "-asan")
-			}
-			if t.compileOnly {
-				args = append(args, "-run=^$")
-			}
-			args = append(args, stdMatches...)
-			cmd := exec.Command(gorootBinGo, args...)
-			cmd.Stdout = os.Stdout
-			cmd.Stderr = os.Stderr
-			return cmd.Run()
+			return (&goTest{
+				timeout: timeoutSec,
+				gcflags: gcflags,
+				pkgs:    stdMatches,
+			}).run(t)
 		},
 	})
 }
@@ -438,31 +613,17 @@
 			timelog("start", dt.name)
 			defer timelog("end", dt.name)
 			ranGoBench = true
-			args := []string{
-				"test",
-				"-short=" + short(),
-				"-race",
-				t.timeout(1200), // longer timeout for race with benchmarks
-				"-run=^$",       // nothing. only benchmarks.
-				"-benchtime=.1s",
-				"-cpu=4",
-			}
-			if !t.compileOnly {
-				args = append(args, "-bench=.*")
-			}
-			args = append(args, benchMatches...)
-			cmd := exec.Command(gorootBinGo, args...)
-			cmd.Stdout = os.Stdout
-			cmd.Stderr = os.Stderr
-			return cmd.Run()
+			return (&goTest{
+				timeout: 1200 * time.Second, // longer timeout for race with benchmarks
+				race:    true,
+				bench:   true,
+				cpu:     "4",
+				pkgs:    benchMatches,
+			}).run(t)
 		},
 	})
 }
 
-// stdOutErrAreTerminals is defined in test_linux.go, to report
-// whether stdout & stderr are terminals.
-var stdOutErrAreTerminals func() bool
-
 func (t *tester) registerTests() {
 	// Fast path to avoid the ~1 second of `go list std cmd` when
 	// the caller lists specific tests to run. (as the continuous
@@ -483,10 +644,7 @@
 		if t.race {
 			cmd.Args = append(cmd.Args, "-tags=race")
 		}
-		cmd.Args = append(cmd.Args, "std")
-		if t.shouldTestCmd() {
-			cmd.Args = append(cmd.Args, "cmd")
-		}
+		cmd.Args = append(cmd.Args, "std", "cmd")
 		cmd.Stderr = new(bytes.Buffer)
 		all, err := cmd.Output()
 		if err != nil {
@@ -505,57 +663,51 @@
 		}
 	}
 
-	// Test the os/user package in the pure-Go mode too.
-	if !t.compileOnly {
-		t.tests = append(t.tests, distTest{
-			name:    "osusergo",
-			heading: "os/user with tag osusergo",
-			fn: func(dt *distTest) error {
-				t.addCmd(dt, "src", t.goTest(), t.timeout(300), "-tags=osusergo", "os/user")
-				return nil
-			},
-		})
-	}
-
-	// Test ios/amd64 for the iOS simulator.
-	if goos == "darwin" && goarch == "amd64" && t.cgoEnabled {
-		t.tests = append(t.tests, distTest{
-			name:    "amd64ios",
-			heading: "GOOS=ios on darwin/amd64",
-			fn: func(dt *distTest) error {
-				cmd := t.addCmd(dt, "src", t.goTest(), t.timeout(300), "-run=SystemRoots", "crypto/x509")
-				setEnv(cmd, "GOOS", "ios")
-				setEnv(cmd, "CGO_ENABLED", "1")
-				return nil
-			},
-		})
-	}
-
 	if t.race {
 		return
 	}
 
+	// Test the os/user package in the pure-Go mode too.
+	if !t.compileOnly {
+		t.registerTest("osusergo", "os/user with tag osusergo",
+			&goTest{
+				timeout: 300 * time.Second,
+				tags:    []string{"osusergo"},
+				pkg:     "os/user",
+			})
+	}
+
+	// Test ios/amd64 for the iOS simulator.
+	if goos == "darwin" && goarch == "amd64" && t.cgoEnabled {
+		t.registerTest("amd64ios", "GOOS=ios on darwin/amd64",
+			&goTest{
+				timeout:  300 * time.Second,
+				runTests: "SystemRoots",
+				env:      []string{"GOOS=ios", "CGO_ENABLED=1"},
+				pkg:      "crypto/x509",
+			})
+	}
+
 	// Runtime CPU tests.
 	if !t.compileOnly && goos != "js" { // js can't handle -cpu != 1
-		testName := "runtime:cpu124"
-		t.tests = append(t.tests, distTest{
-			name:    testName,
-			heading: "GOMAXPROCS=2 runtime -cpu=1,2,4 -quick",
-			fn: func(dt *distTest) error {
-				cmd := t.addCmd(dt, "src", t.goTest(), "-short=true", t.timeout(300), "runtime", "-cpu=1,2,4", "-quick")
+		t.registerTest("runtime:cpu124", "GOMAXPROCS=2 runtime -cpu=1,2,4 -quick",
+			&goTest{
+				timeout:   300 * time.Second,
+				cpu:       "1,2,4",
+				short:     true,
+				testFlags: []string{"-quick"},
 				// We set GOMAXPROCS=2 in addition to -cpu=1,2,4 in order to test runtime bootstrap code,
 				// creation of first goroutines and first garbage collections in the parallel setting.
-				setEnv(cmd, "GOMAXPROCS", "2")
-				return nil
-			},
-		})
+				env: []string{"GOMAXPROCS=2"},
+				pkg: "runtime",
+			})
 	}
 
 	// morestack tests. We only run these on in long-test mode
 	// (with GO_TEST_SHORT=false) because the runtime test is
 	// already quite long and mayMoreStackMove makes it about
 	// twice as slow.
-	if !t.compileOnly && short() == "false" {
+	if !t.compileOnly && !t.short {
 		// hooks is the set of maymorestack hooks to test with.
 		hooks := []string{"mayMoreStackPreempt", "mayMoreStackMove"}
 		// pkgs is the set of test packages to run.
@@ -585,44 +737,17 @@
 			goFlags := strings.Join(goFlagsList, " ")
 
 			for _, pkg := range pkgs {
-				pkg := pkg
-				testName := hook + ":" + pkg
-				t.tests = append(t.tests, distTest{
-					name:    testName,
-					heading: "maymorestack=" + hook,
-					fn: func(dt *distTest) error {
-						cmd := t.addCmd(dt, "src", t.goTest(), t.timeout(600), pkg, "-short")
-						setEnv(cmd, "GOFLAGS", goFlags)
-						return nil
-					},
-				})
+				t.registerTest(hook+":"+pkg, "maymorestack="+hook,
+					&goTest{
+						timeout: 600 * time.Second,
+						short:   true,
+						env:     []string{"GOFLAGS=" + goFlags},
+						pkg:     pkg,
+					})
 			}
 		}
 	}
 
-	// This test needs its stdout/stderr to be terminals, so we don't run it from cmd/go's tests.
-	// See issue 18153.
-	if goos == "linux" {
-		t.tests = append(t.tests, distTest{
-			name:    "cmd_go_test_terminal",
-			heading: "cmd/go terminal test",
-			fn: func(dt *distTest) error {
-				t.runPending(dt)
-				timelog("start", dt.name)
-				defer timelog("end", dt.name)
-				if !stdOutErrAreTerminals() {
-					fmt.Println("skipping terminal test; stdout/stderr not terminals")
-					return nil
-				}
-				cmd := exec.Command(gorootBinGo, "test")
-				setDir(cmd, filepath.Join(os.Getenv("GOROOT"), "src/cmd/go/testdata/testterminal18153"))
-				cmd.Stdout = os.Stdout
-				cmd.Stderr = os.Stderr
-				return cmd.Run()
-			},
-		})
-	}
-
 	// On the builders only, test that a moved GOROOT still works.
 	// Fails on iOS because CC_FOR_TARGET refers to clangwrap.sh
 	// in the unmoved GOROOT.
@@ -654,9 +779,10 @@
 
 				// Run `go test fmt` in the moved GOROOT, without explicitly setting
 				// GOROOT in the environment. The 'go' command should find itself.
-				cmd := exec.Command(filepath.Join(moved, "bin", "go"), "test", "fmt")
-				cmd.Stdout = os.Stdout
-				cmd.Stderr = os.Stderr
+				cmd := (&goTest{
+					goroot: moved,
+					pkg:    "fmt",
+				}).command(t)
 				unsetEnv(cmd, "GOROOT")
 				unsetEnv(cmd, "GOCACHE") // TODO(bcmills): ...why‽
 				err := cmd.Run()
@@ -683,124 +809,86 @@
 			break
 		}
 
-		pkg := pkg
-		var run string
+		// What matters is that the tests build and start up.
+		// Skip expensive tests, especially x509 TestSystemRoots.
+		run := "^Test[^CS]"
 		if pkg == "net" {
 			run = "TestTCPStress"
 		}
-		t.tests = append(t.tests, distTest{
-			name:    "nolibgcc:" + pkg,
-			heading: "Testing without libgcc.",
-			fn: func(dt *distTest) error {
-				// What matters is that the tests build and start up.
-				// Skip expensive tests, especially x509 TestSystemRoots.
-				t.addCmd(dt, "src", t.goTest(), "-ldflags=-linkmode=internal -libgcc=none", "-run=^Test[^CS]", pkg, t.runFlag(run))
-				return nil
-			},
-		})
+		t.registerTest("nolibgcc:"+pkg, "Testing without libgcc.",
+			&goTest{
+				ldflags:  "-linkmode=internal -libgcc=none",
+				runTests: run,
+				pkg:      pkg,
+			})
 	}
 
+	// Stub out following test on alpine until 54354 resolved.
+	builderName := os.Getenv("GO_BUILDER_NAME")
+	disablePIE := strings.HasSuffix(builderName, "-alpine")
+
 	// Test internal linking of PIE binaries where it is supported.
-	if t.internalLinkPIE() {
-		t.tests = append(t.tests, distTest{
-			name:    "pie_internal",
-			heading: "internal linking of -buildmode=pie",
-			fn: func(dt *distTest) error {
-				t.addCmd(dt, "src", t.goTest(), "reflect", "-buildmode=pie", "-ldflags=-linkmode=internal", t.timeout(60))
-				return nil
-			},
-		})
-		// Also test a cgo package.
-		if t.cgoEnabled && t.internalLink() {
-			t.tests = append(t.tests, distTest{
-				name:    "pie_internal_cgo",
-				heading: "internal linking of -buildmode=pie",
-				fn: func(dt *distTest) error {
-					t.addCmd(dt, "src", t.goTest(), "os/user", "-buildmode=pie", "-ldflags=-linkmode=internal", t.timeout(60))
-					return nil
-				},
+	if t.internalLinkPIE() && !disablePIE {
+		t.registerTest("pie_internal", "internal linking of -buildmode=pie",
+			&goTest{
+				timeout:   60 * time.Second,
+				buildmode: "pie",
+				ldflags:   "-linkmode=internal",
+				env:       []string{"CGO_ENABLED=0"},
+				pkg:       "reflect",
 			})
+		// Also test a cgo package.
+		if t.cgoEnabled && t.internalLink() && !disablePIE {
+			t.registerTest("pie_internal_cgo", "internal linking of -buildmode=pie",
+				&goTest{
+					timeout:   60 * time.Second,
+					buildmode: "pie",
+					ldflags:   "-linkmode=internal",
+					pkg:       "os/user",
+				})
 		}
 	}
 
 	// sync tests
 	if goos != "js" { // js doesn't support -cpu=10
-		t.tests = append(t.tests, distTest{
-			name:    "sync_cpu",
-			heading: "sync -cpu=10",
-			fn: func(dt *distTest) error {
-				t.addCmd(dt, "src", t.goTest(), "sync", t.timeout(120), "-cpu=10", t.runFlag(""))
-				return nil
-			},
-		})
+		t.registerTest("sync_cpu", "sync -cpu=10",
+			&goTest{
+				timeout: 120 * time.Second,
+				cpu:     "10",
+				pkg:     "sync",
+			})
 	}
 
 	if t.raceDetectorSupported() {
-		t.tests = append(t.tests, distTest{
-			name:    "race",
-			heading: "Testing race detector",
-			fn:      t.raceTest,
-		})
+		t.registerRaceTests()
 	}
 
 	if t.cgoEnabled && !t.iOS() {
 		// Disabled on iOS. golang.org/issue/15919
-		t.registerHostTest("cgo_stdio", "../misc/cgo/stdio", "misc/cgo/stdio", ".")
-		t.registerHostTest("cgo_life", "../misc/cgo/life", "misc/cgo/life", ".")
-		fortran := os.Getenv("FC")
-		if fortran == "" {
-			fortran, _ = exec.LookPath("gfortran")
-		}
-		if t.hasBash() && goos != "android" && fortran != "" {
-			t.tests = append(t.tests, distTest{
-				name:    "cgo_fortran",
-				heading: "../misc/cgo/fortran",
-				fn: func(dt *distTest) error {
-					t.addCmd(dt, "misc/cgo/fortran", "./test.bash", fortran)
-					return nil
-				},
-			})
+		t.registerTest("cgo_stdio", "", &goTest{dir: "../misc/cgo/stdio", timeout: 5 * time.Minute}, rtHostTest{})
+		t.registerTest("cgo_life", "", &goTest{dir: "../misc/cgo/life", timeout: 5 * time.Minute}, rtHostTest{})
+		if goos != "android" {
+			t.registerTest("cgo_fortran", "", &goTest{dir: "../misc/cgo/fortran", timeout: 5 * time.Minute}, rtHostTest{})
 		}
 		if t.hasSwig() && goos != "android" {
-			t.tests = append(t.tests, distTest{
-				name:    "swig_stdio",
-				heading: "../misc/swig/stdio",
-				fn: func(dt *distTest) error {
-					t.addCmd(dt, "misc/swig/stdio", t.goTest(), ".")
-					return nil
-				},
-			})
+			t.registerTest("swig_stdio", "", &goTest{dir: "../misc/swig/stdio"})
 			if t.hasCxx() {
-				t.tests = append(t.tests,
-					distTest{
-						name:    "swig_callback",
-						heading: "../misc/swig/callback",
-						fn: func(dt *distTest) error {
-							t.addCmd(dt, "misc/swig/callback", t.goTest(), ".")
-							return nil
+				t.registerTest("swig_callback", "", &goTest{dir: "../misc/swig/callback"})
+				const cflags = "-flto -Wno-lto-type-mismatch -Wno-unknown-warning-option"
+				t.registerTest("swig_callback_lto", "",
+					&goTest{
+						dir: "../misc/swig/callback",
+						env: []string{
+							"CGO_CFLAGS=" + cflags,
+							"CGO_CXXFLAGS=" + cflags,
+							"CGO_LDFLAGS=" + cflags,
 						},
-					},
-					distTest{
-						name:    "swig_callback_lto",
-						heading: "../misc/swig/callback",
-						fn: func(dt *distTest) error {
-							cmd := t.addCmd(dt, "misc/swig/callback", t.goTest(), ".")
-							setEnv(cmd, "CGO_CFLAGS", "-flto -Wno-lto-type-mismatch -Wno-unknown-warning-option")
-							setEnv(cmd, "CGO_CXXFLAGS", "-flto -Wno-lto-type-mismatch -Wno-unknown-warning-option")
-							setEnv(cmd, "CGO_LDFLAGS", "-flto -Wno-lto-type-mismatch -Wno-unknown-warning-option")
-							return nil
-						},
-					},
-				)
+					})
 			}
 		}
 	}
 	if t.cgoEnabled {
-		t.tests = append(t.tests, distTest{
-			name:    "cgo_test",
-			heading: "../misc/cgo/test",
-			fn:      t.cgoTest,
-		})
+		t.registerCgoTests()
 	}
 
 	// Don't run these tests with $GO_GCFLAGS because most of them
@@ -808,43 +896,36 @@
 	// recompile the entire standard library. If make.bash ran with
 	// special -gcflags, that's not true.
 	if t.cgoEnabled && gogcflags == "" {
-		t.registerHostTest("testgodefs", "../misc/cgo/testgodefs", "misc/cgo/testgodefs", ".")
+		t.registerTest("testgodefs", "", &goTest{dir: "../misc/cgo/testgodefs", timeout: 5 * time.Minute}, rtHostTest{})
 
-		t.registerTest("testso", "../misc/cgo/testso", t.goTest(), t.timeout(600), ".")
-		t.registerTest("testsovar", "../misc/cgo/testsovar", t.goTest(), t.timeout(600), ".")
+		t.registerTest("testso", "", &goTest{dir: "../misc/cgo/testso", timeout: 600 * time.Second})
+		t.registerTest("testsovar", "", &goTest{dir: "../misc/cgo/testsovar", timeout: 600 * time.Second})
 		if t.supportedBuildmode("c-archive") {
-			t.registerHostTest("testcarchive", "../misc/cgo/testcarchive", "misc/cgo/testcarchive", ".")
+			t.registerTest("testcarchive", "", &goTest{dir: "../misc/cgo/testcarchive", timeout: 5 * time.Minute}, rtHostTest{})
 		}
 		if t.supportedBuildmode("c-shared") {
-			t.registerHostTest("testcshared", "../misc/cgo/testcshared", "misc/cgo/testcshared", ".")
+			t.registerTest("testcshared", "", &goTest{dir: "../misc/cgo/testcshared", timeout: 5 * time.Minute}, rtHostTest{})
 		}
 		if t.supportedBuildmode("shared") {
-			t.registerTest("testshared", "../misc/cgo/testshared", t.goTest(), t.timeout(600), ".")
+			t.registerTest("testshared", "", &goTest{dir: "../misc/cgo/testshared", timeout: 600 * time.Second})
 		}
 		if t.supportedBuildmode("plugin") {
-			t.registerTest("testplugin", "../misc/cgo/testplugin", t.goTest(), t.timeout(600), ".")
+			t.registerTest("testplugin", "", &goTest{dir: "../misc/cgo/testplugin", timeout: 600 * time.Second})
 		}
-		if gohostos == "linux" && goarch == "amd64" {
-			t.registerTest("testasan", "../misc/cgo/testasan", "go", "run", ".")
-		}
-		if goos == "linux" && goarch != "ppc64le" {
-			// because syscall.SysProcAttr struct used in misc/cgo/testsanitizers is only built on linux.
-			// Some inconsistent failures happen on ppc64le so disable for now.
-			t.registerHostTest("testsanitizers", "../misc/cgo/testsanitizers", "misc/cgo/testsanitizers", ".")
+		if goos == "linux" || (goos == "freebsd" && goarch == "amd64") {
+			// because Pdeathsig of syscall.SysProcAttr struct used in misc/cgo/testsanitizers is only
+			// supported on Linux and FreeBSD.
+			t.registerTest("testsanitizers", "", &goTest{dir: "../misc/cgo/testsanitizers", timeout: 5 * time.Minute}, rtHostTest{})
 		}
 		if t.hasBash() && goos != "android" && !t.iOS() && gohostos != "windows" {
-			t.registerHostTest("cgo_errors", "../misc/cgo/errors", "misc/cgo/errors", ".")
-		}
-		if gohostos == "linux" && t.extLink() {
-			t.registerTest("testsigfwd", "../misc/cgo/testsigfwd", "go", "run", ".")
+			t.registerTest("cgo_errors", "", &goTest{dir: "../misc/cgo/errors", timeout: 5 * time.Minute}, rtHostTest{})
 		}
 	}
 
 	if goos != "android" && !t.iOS() {
 		// There are no tests in this directory, only benchmarks.
-		// Check that the test binary builds but don't bother running it.
-		// (It has init-time work to set up for the benchmarks that is not worth doing unnecessarily.)
-		t.registerTest("bench_go1", "../test/bench/go1", t.goTest(), "-c", "-o="+os.DevNull)
+		// Check that the test binary builds.
+		t.registerTest("bench_go1", "", &goTest{dir: "../test/bench/go1"})
 	}
 	if goos != "android" && !t.iOS() {
 		// Only start multiple test dir shards on builders,
@@ -866,30 +947,19 @@
 			})
 		}
 	}
-	// Only run the API check on fast development platforms. Android, iOS, and JS
-	// are always cross-compiled, and the filesystems on our only plan9 builders
-	// are too slow to complete in a reasonable timeframe. Every platform checks
-	// the API on every GOOS/GOARCH/CGO_ENABLED combination anyway, so we really
-	// only need to run this check once anywhere to get adequate coverage.
-	if goos != "android" && !t.iOS() && goos != "js" && goos != "plan9" {
-		t.tests = append(t.tests, distTest{
-			name:    "api",
-			heading: "API check",
-			fn: func(dt *distTest) error {
-				if t.compileOnly {
-					t.addCmd(dt, "src", "go", "build", "-o", os.DevNull, filepath.Join(goroot, "src/cmd/api/run.go"))
-					return nil
-				}
-				t.addCmd(dt, "src", "go", "run", filepath.Join(goroot, "src/cmd/api/run.go"))
-				return nil
-			},
-		})
+	// Only run the API check on fast development platforms.
+	// Every platform checks the API on every GOOS/GOARCH/CGO_ENABLED combination anyway,
+	// so we really only need to run this check once anywhere to get adequate coverage.
+	// To help developers avoid trybot-only failures, we try to run on typical developer machines
+	// which is darwin,linux,windows/amd64 and darwin/arm64.
+	if goos == "darwin" || ((goos == "linux" || goos == "windows") && goarch == "amd64") {
+		t.registerTest("api", "", &goTest{dir: "cmd/api", timeout: 5 * time.Minute, testFlags: []string{"-check"}})
 	}
 
 	// Ensure that the toolchain can bootstrap itself.
 	// This test adds another ~45s to all.bash if run sequentially, so run it only on the builders.
 	if os.Getenv("GO_BUILDER_NAME") != "" && goos != "android" && !t.iOS() {
-		t.registerHostTest("reboot", "../misc/reboot", "misc/reboot", ".")
+		t.registerTest("reboot", "", &goTest{dir: "../misc/reboot", timeout: 5 * time.Minute}, rtHostTest{})
 	}
 }
 
@@ -904,38 +974,80 @@
 	return false
 }
 
-func (t *tester) registerTest1(seq bool, name, dirBanner string, cmdline ...interface{}) {
-	bin, args := flattenCmdline(cmdline)
-	if bin == "time" && !t.haveTime {
-		bin, args = args[0], args[1:]
+type registerTestOpt interface {
+	isRegisterTestOpt()
+}
+
+// rtSequential is a registerTest option that causes the registered test to run
+// sequentially.
+type rtSequential struct{}
+
+func (rtSequential) isRegisterTestOpt() {}
+
+// rtPreFunc is a registerTest option that runs a pre function before running
+// the test.
+type rtPreFunc struct {
+	pre func(*distTest) bool // Return false to skip the test
+}
+
+func (rtPreFunc) isRegisterTestOpt() {}
+
+// rtHostTest is a registerTest option that indicates this is a host test that
+// should be run using goTest.runHostTest. It implies rtSequential.
+type rtHostTest struct{}
+
+func (rtHostTest) isRegisterTestOpt() {}
+
+// registerTest registers a test that runs the given goTest.
+//
+// If heading is "", it uses test.dir as the heading.
+func (t *tester) registerTest(name, heading string, test *goTest, opts ...registerTestOpt) {
+	seq := false
+	hostTest := false
+	var preFunc func(*distTest) bool
+	for _, opt := range opts {
+		switch opt := opt.(type) {
+		case rtSequential:
+			seq = true
+		case rtPreFunc:
+			preFunc = opt.pre
+		case rtHostTest:
+			seq, hostTest = true, true
+		}
 	}
 	if t.isRegisteredTestName(name) {
 		panic("duplicate registered test name " + name)
 	}
+	if heading == "" {
+		heading = test.dir
+	}
 	t.tests = append(t.tests, distTest{
 		name:    name,
-		heading: dirBanner,
+		heading: heading,
 		fn: func(dt *distTest) error {
+			if preFunc != nil && !preFunc(dt) {
+				return nil
+			}
 			if seq {
 				t.runPending(dt)
-				timelog("start", name)
-				defer timelog("end", name)
-				return t.dirCmd(filepath.Join(goroot, "src", dirBanner), bin, args).Run()
+				if hostTest {
+					return test.runHostTest(t)
+				}
+				return test.run(t)
 			}
-			t.addCmd(dt, filepath.Join(goroot, "src", dirBanner), bin, args)
+			w := &work{
+				dt:  dt,
+				cmd: test.bgCommand(t),
+			}
+			t.worklist = append(t.worklist, w)
 			return nil
 		},
 	})
 }
 
-func (t *tester) registerTest(name, dirBanner string, cmdline ...interface{}) {
-	t.registerTest1(false, name, dirBanner, cmdline...)
-}
-
-func (t *tester) registerSeqTest(name, dirBanner string, cmdline ...interface{}) {
-	t.registerTest1(true, name, dirBanner, cmdline...)
-}
-
+// bgDirCmd constructs a Cmd intended to be run in the background as
+// part of the worklist. The worklist runner will buffer its output
+// and replay it sequentially. The command will be run in dir.
 func (t *tester) bgDirCmd(dir, bin string, args ...string) *exec.Cmd {
 	cmd := exec.Command(bin, args...)
 	if filepath.IsAbs(dir) {
@@ -946,6 +1058,9 @@
 	return cmd
 }
 
+// dirCmd constructs a Cmd intended to be run in the foreground.
+// The command will be run in dir, and Stdout and Stderr will go to os.Stdout
+// and os.Stderr.
 func (t *tester) dirCmd(dir string, cmdline ...interface{}) *exec.Cmd {
 	bin, args := flattenCmdline(cmdline)
 	cmd := t.bgDirCmd(dir, bin, args...)
@@ -972,32 +1087,6 @@
 		}
 	}
 
-	// The go command is too picky about duplicated flags.
-	// Drop all but the last of the allowed duplicated flags.
-	drop := make([]bool, len(list))
-	have := map[string]int{}
-	for i := 1; i < len(list); i++ {
-		j := strings.Index(list[i], "=")
-		if j < 0 {
-			continue
-		}
-		flag := list[i][:j]
-		switch flag {
-		case "-run", "-tags":
-			if have[flag] != 0 {
-				drop[have[flag]] = true
-			}
-			have[flag] = i
-		}
-	}
-	out := list[:0]
-	for i, x := range list {
-		if !drop[i] {
-			out = append(out, x)
-		}
-	}
-	list = out
-
 	bin = list[0]
 	if bin == "go" {
 		bin = gorootBinGo
@@ -1005,6 +1094,9 @@
 	return bin, list[1:]
 }
 
+// addCmd adds a command to the worklist. Commands can be run in
+// parallel, but their output will be buffered and replayed in the
+// order they were added to worklist.
 func (t *tester) addCmd(dt *distTest, dir string, cmdline ...interface{}) *exec.Cmd {
 	bin, args := flattenCmdline(cmdline)
 	w := &work{
@@ -1033,7 +1125,7 @@
 		"android-arm", "android-arm64",
 		"darwin-amd64", "darwin-arm64",
 		"dragonfly-amd64",
-		"freebsd-386", "freebsd-amd64", "freebsd-arm",
+		"freebsd-386", "freebsd-amd64", "freebsd-arm", "freebsd-riscv64",
 		"linux-386", "linux-amd64", "linux-arm", "linux-arm64", "linux-loong64", "linux-ppc64le", "linux-mips64", "linux-mips64le", "linux-mips", "linux-mipsle", "linux-riscv64", "linux-s390x",
 		"netbsd-386", "netbsd-amd64",
 		"openbsd-386", "openbsd-amd64",
@@ -1142,138 +1234,128 @@
 	}
 }
 
-func (t *tester) registerHostTest(name, heading, dir, pkg string) {
-	t.tests = append(t.tests, distTest{
-		name:    name,
-		heading: heading,
-		fn: func(dt *distTest) error {
-			t.runPending(dt)
-			timelog("start", name)
-			defer timelog("end", name)
-			return t.runHostTest(dir, pkg)
-		},
-	})
-}
+func (t *tester) registerCgoTests() {
+	cgoTest := func(name string, subdir, linkmode, buildmode string, opts ...registerTestOpt) *goTest {
+		gt := &goTest{
+			dir:       "../misc/cgo/" + subdir,
+			buildmode: buildmode,
+			ldflags:   "-linkmode=" + linkmode,
+		}
 
-func (t *tester) runHostTest(dir, pkg string) error {
-	out, err := exec.Command(gorootBinGo, "env", "GOEXE", "GOTMPDIR").Output()
-	if err != nil {
-		return err
+		if linkmode == "internal" {
+			gt.tags = append(gt.tags, "internal")
+			if buildmode == "pie" {
+				gt.tags = append(gt.tags, "internal_pie")
+			}
+		}
+		if buildmode == "static" {
+			// This isn't actually a Go buildmode, just a convenient way to tell
+			// cgoTest we want static linking.
+			gt.buildmode = ""
+			if linkmode == "external" {
+				gt.ldflags += ` -extldflags "-static -pthread"`
+			} else if linkmode == "auto" {
+				gt.env = append(gt.env, "CGO_LDFLAGS=-static -pthread")
+			} else {
+				panic("unknown linkmode with static build: " + linkmode)
+			}
+			gt.tags = append(gt.tags, "static")
+		}
+
+		t.registerTest("cgo:"+name, "../misc/cgo/test", gt, opts...)
+		return gt
 	}
 
-	parts := strings.Split(string(out), "\n")
-	if len(parts) < 2 {
-		return fmt.Errorf("'go env GOEXE GOTMPDIR' output contains <2 lines")
-	}
-	GOEXE := strings.TrimSpace(parts[0])
-	GOTMPDIR := strings.TrimSpace(parts[1])
+	cgoTest("test-auto", "test", "auto", "")
 
-	f, err := ioutil.TempFile(GOTMPDIR, "test.test-*"+GOEXE)
-	if err != nil {
-		return err
-	}
-	f.Close()
-	defer os.Remove(f.Name())
-
-	cmd := t.dirCmd(dir, t.goTest(), "-c", "-o", f.Name(), pkg)
-	setEnv(cmd, "GOARCH", gohostarch)
-	setEnv(cmd, "GOOS", gohostos)
-	if err := cmd.Run(); err != nil {
-		return err
-	}
-	return t.dirCmd(dir, f.Name(), "-test.short="+short(), "-test.timeout="+t.timeoutDuration(300).String()).Run()
-}
-
-func (t *tester) cgoTest(dt *distTest) error {
-	cmd := t.addCmd(dt, "misc/cgo/test", t.goTest(), ".")
-	setEnv(cmd, "GOFLAGS", "-ldflags=-linkmode=auto")
+	// Stub out various buildmode=pie tests  on alpine until 54354 resolved.
+	builderName := os.Getenv("GO_BUILDER_NAME")
+	disablePIE := strings.HasSuffix(builderName, "-alpine")
 
 	if t.internalLink() {
-		cmd := t.addCmd(dt, "misc/cgo/test", t.goTest(), "-tags=internal", ".")
-		setEnv(cmd, "GOFLAGS", "-ldflags=-linkmode=internal")
+		cgoTest("test-internal", "test", "internal", "")
 	}
 
-	pair := gohostos + "-" + goarch
-	switch pair {
-	case "darwin-amd64", "darwin-arm64",
-		"windows-386", "windows-amd64":
-		// test linkmode=external, but __thread not supported, so skip testtls.
+	os := gohostos
+	p := gohostos + "/" + goarch
+	switch {
+	case os == "darwin", os == "windows":
 		if !t.extLink() {
 			break
 		}
-		cmd := t.addCmd(dt, "misc/cgo/test", t.goTest(), ".")
-		setEnv(cmd, "GOFLAGS", "-ldflags=-linkmode=external")
+		// test linkmode=external, but __thread not supported, so skip testtls.
+		cgoTest("test-external", "test", "external", "")
 
-		t.addCmd(dt, "misc/cgo/test", t.goTest(), "-ldflags", "-linkmode=external -s", ".")
+		gt := cgoTest("test-external-s", "test", "external", "")
+		gt.ldflags += " -s"
 
-		if t.supportedBuildmode("pie") {
-			t.addCmd(dt, "misc/cgo/test", t.goTest(), "-buildmode=pie", ".")
+		if t.supportedBuildmode("pie") && !disablePIE {
+			cgoTest("test-auto-pie", "test", "auto", "pie")
 			if t.internalLink() && t.internalLinkPIE() {
-				t.addCmd(dt, "misc/cgo/test", t.goTest(), "-buildmode=pie", "-ldflags=-linkmode=internal", "-tags=internal,internal_pie", ".")
+				cgoTest("test-internal-pie", "test", "internal", "pie")
 			}
 		}
 
-	case "aix-ppc64",
-		"android-arm", "android-arm64",
-		"dragonfly-amd64",
-		"freebsd-386", "freebsd-amd64", "freebsd-arm",
-		"linux-386", "linux-amd64", "linux-arm", "linux-arm64", "linux-ppc64le", "linux-riscv64", "linux-s390x",
-		"netbsd-386", "netbsd-amd64",
-		"openbsd-386", "openbsd-amd64", "openbsd-arm", "openbsd-arm64", "openbsd-mips64":
+	case os == "aix", os == "android", os == "dragonfly", os == "freebsd", os == "linux", os == "netbsd", os == "openbsd":
+		gt := cgoTest("test-external-g0", "test", "external", "")
+		gt.env = append(gt.env, "CGO_CFLAGS=-g0 -fdiagnostics-color")
 
-		cmd := t.addCmd(dt, "misc/cgo/test", t.goTest(), ".")
-		setEnv(cmd, "GOFLAGS", "-ldflags=-linkmode=external")
-		// cgo should be able to cope with both -g arguments and colored
-		// diagnostics.
-		setEnv(cmd, "CGO_CFLAGS", "-g0 -fdiagnostics-color")
-
-		t.addCmd(dt, "misc/cgo/testtls", t.goTest(), "-ldflags", "-linkmode=auto", ".")
-		t.addCmd(dt, "misc/cgo/testtls", t.goTest(), "-ldflags", "-linkmode=external", ".")
-
-		switch pair {
-		case "aix-ppc64", "netbsd-386", "netbsd-amd64":
+		cgoTest("testtls-auto", "testtls", "auto", "")
+		cgoTest("testtls-external", "testtls", "external", "")
+		switch {
+		case os == "aix":
 			// no static linking
-		case "freebsd-arm":
+		case p == "freebsd/arm":
 			// -fPIC compiled tls code will use __tls_get_addr instead
 			// of __aeabi_read_tp, however, on FreeBSD/ARM, __tls_get_addr
 			// is implemented in rtld-elf, so -fPIC isn't compatible with
 			// static linking on FreeBSD/ARM with clang. (cgo depends on
 			// -fPIC fundamentally.)
 		default:
+			// Check for static linking support
+			var staticCheck rtPreFunc
 			cmd := t.dirCmd("misc/cgo/test",
 				compilerEnvLookup(defaultcc, goos, goarch), "-xc", "-o", "/dev/null", "-static", "-")
 			cmd.Stdin = strings.NewReader("int main() {}")
+			cmd.Stdout, cmd.Stderr = nil, nil // Discard output
 			if err := cmd.Run(); err != nil {
-				fmt.Println("No support for static linking found (lacks libc.a?), skip cgo static linking test.")
-			} else {
-				if goos != "android" {
-					t.addCmd(dt, "misc/cgo/testtls", t.goTest(), "-ldflags", `-linkmode=external -extldflags "-static -pthread"`, ".")
-				}
-				t.addCmd(dt, "misc/cgo/nocgo", t.goTest(), ".")
-				t.addCmd(dt, "misc/cgo/nocgo", t.goTest(), "-ldflags", `-linkmode=external`, ".")
-				if goos != "android" {
-					t.addCmd(dt, "misc/cgo/nocgo", t.goTest(), "-ldflags", `-linkmode=external -extldflags "-static -pthread"`, ".")
-					t.addCmd(dt, "misc/cgo/test", t.goTest(), "-tags=static", "-ldflags", `-linkmode=external -extldflags "-static -pthread"`, ".")
-					// -static in CGO_LDFLAGS triggers a different code path
-					// than -static in -extldflags, so test both.
-					// See issue #16651.
-					cmd := t.addCmd(dt, "misc/cgo/test", t.goTest(), "-tags=static", ".")
-					setEnv(cmd, "CGO_LDFLAGS", "-static -pthread")
+				// Skip these tests
+				staticCheck.pre = func(*distTest) bool {
+					fmt.Println("No support for static linking found (lacks libc.a?), skip cgo static linking test.")
+					return false
 				}
 			}
 
-			if t.supportedBuildmode("pie") {
-				t.addCmd(dt, "misc/cgo/test", t.goTest(), "-buildmode=pie", ".")
-				if t.internalLink() && t.internalLinkPIE() {
-					t.addCmd(dt, "misc/cgo/test", t.goTest(), "-buildmode=pie", "-ldflags=-linkmode=internal", "-tags=internal,internal_pie", ".")
+			// Static linking tests
+			if goos != "android" && p != "netbsd/arm" {
+				// TODO(#56629): Why does this fail on netbsd-arm?
+				cgoTest("testtls-static", "testtls", "external", "static", staticCheck)
+			}
+			cgoTest("nocgo-auto", "nocgo", "auto", "", staticCheck)
+			cgoTest("nocgo-external", "nocgo", "external", "", staticCheck)
+			if goos != "android" {
+				cgoTest("nocgo-static", "nocgo", "external", "static", staticCheck)
+				cgoTest("test-static", "test", "external", "static", staticCheck)
+				// -static in CGO_LDFLAGS triggers a different code path
+				// than -static in -extldflags, so test both.
+				// See issue #16651.
+				if goarch != "loong64" {
+					// TODO(#56623): Why does this fail on loong64?
+					cgoTest("test-static-env", "test", "auto", "static", staticCheck)
 				}
-				t.addCmd(dt, "misc/cgo/testtls", t.goTest(), "-buildmode=pie", ".")
-				t.addCmd(dt, "misc/cgo/nocgo", t.goTest(), "-buildmode=pie", ".")
+			}
+
+			// PIE linking tests
+			if t.supportedBuildmode("pie") && !disablePIE {
+				cgoTest("test-pie", "test", "auto", "pie")
+				if t.internalLink() && t.internalLinkPIE() {
+					cgoTest("test-pie-internal", "test", "internal", "pie")
+				}
+				cgoTest("testtls-pie", "testtls", "auto", "pie")
+				cgoTest("nocgo-pie", "nocgo", "auto", "pie")
 			}
 		}
 	}
-
-	return nil
 }
 
 // run pending test commands, in parallel, emitting headers as appropriate.
@@ -1398,7 +1480,7 @@
 		return false
 	}
 
-	re := regexp.MustCompile(`[vV]ersion +([\d]+)([.][\d]+)?([.][\d]+)?`)
+	re := regexp.MustCompile(`[vV]ersion +(\d+)([.]\d+)?([.]\d+)?`)
 	matches := re.FindSubmatch(out)
 	if matches == nil {
 		// Can't find version number; hope for the best.
@@ -1476,34 +1558,49 @@
 	return err == nil && fi.Mode().IsRegular()
 }
 
-func (t *tester) runFlag(rx string) string {
-	if t.compileOnly {
-		return "-run=^$"
-	}
-	return "-run=" + rx
-}
-
-func (t *tester) raceTest(dt *distTest) error {
-	t.addCmd(dt, "src", t.goTest(), "-race", t.runFlag("Output"), "runtime/race")
-	t.addCmd(dt, "src", t.goTest(), "-race", t.runFlag("TestParse|TestEcho|TestStdinCloseRace|TestClosedPipeRace|TestTypeRace|TestFdRace|TestFdReadRace|TestFileCloseRace"), "flag", "net", "os", "os/exec", "encoding/gob")
+func (t *tester) registerRaceTests() {
+	hdr := "Testing race detector"
+	t.registerTest("race:runtime/race", hdr,
+		&goTest{
+			race:     true,
+			runTests: "Output",
+			pkg:      "runtime/race",
+		})
+	t.registerTest("race", hdr,
+		&goTest{
+			race:     true,
+			runTests: "TestParse|TestEcho|TestStdinCloseRace|TestClosedPipeRace|TestTypeRace|TestFdRace|TestFdReadRace|TestFileCloseRace",
+			pkgs:     []string{"flag", "net", "os", "os/exec", "encoding/gob"},
+		})
 	// We don't want the following line, because it
 	// slows down all.bash (by 10 seconds on my laptop).
 	// The race builder should catch any error here, but doesn't.
 	// TODO(iant): Figure out how to catch this.
-	// t.addCmd(dt, "src", t.goTest(),  "-race", "-run=TestParallelTest", "cmd/go")
+	// t.registerTest("race:cmd/go", hdr, &goTest{race: true, runTests: "TestParallelTest", pkg: "cmd/go"})
 	if t.cgoEnabled {
 		// Building misc/cgo/test takes a long time.
 		// There are already cgo-enabled packages being tested with the race detector.
 		// We shouldn't need to redo all of misc/cgo/test too.
 		// The race buildler will take care of this.
-		// cmd := t.addCmd(dt, "misc/cgo/test", t.goTest(), "-race")
-		// setEnv(cmd, "GOTRACEBACK", "2")
+		// t.registerTest("race:misc/cgo/test", hdr, &goTest{dir: "../misc/cgo/test", race: true, env: []string{"GOTRACEBACK=2"}})
 	}
 	if t.extLink() {
+		var oldWindows rtPreFunc
+		if strings.HasPrefix(os.Getenv("GO_BUILDER_NAME"), "windows-amd64-2008") {
+			oldWindows.pre = func(*distTest) bool {
+				fmt.Println("skipping -race with external linkage on older windows builder, see https://github.com/golang/go/issues/56904 for details")
+				return false
+			}
+		}
 		// Test with external linking; see issue 9133.
-		t.addCmd(dt, "src", t.goTest(), "-race", "-ldflags=-linkmode=external", t.runFlag("TestParse|TestEcho|TestStdinCloseRace"), "flag", "os/exec")
+		t.registerTest("race:external", hdr,
+			&goTest{
+				race:     true,
+				ldflags:  "-linkmode=external",
+				runTests: "TestParse|TestEcho|TestStdinCloseRace",
+				pkgs:     []string{"flag", "os/exec"},
+			}, oldWindows)
 	}
-	return nil
 }
 
 var runtest struct {
@@ -1514,7 +1611,7 @@
 
 func (t *tester) testDirTest(dt *distTest, shard, shards int) error {
 	runtest.Do(func() {
-		f, err := ioutil.TempFile("", "runtest-*.exe") // named exe for Windows, but harmless elsewhere
+		f, err := os.CreateTemp("", "runtest-*.exe") // named exe for Windows, but harmless elsewhere
 		if err != nil {
 			runtest.err = err
 			return
@@ -1574,7 +1671,7 @@
 		if !strings.HasSuffix(name, "_test.go") {
 			continue
 		}
-		slurp, err := ioutil.ReadFile(filepath.Join(pkgDir, name))
+		slurp, err := os.ReadFile(filepath.Join(pkgDir, name))
 		if err != nil {
 			return true // conservatively
 		}
@@ -1611,8 +1708,7 @@
 	}
 	gocacheSubdir, _ := filepath.Rel(dir, gocache)
 
-	// Note: Can't use WalkDir here, because this has to compile with Go 1.4.
-	filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
+	filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error {
 		if suffix := strings.TrimPrefix(path, dir+string(filepath.Separator)); suffix != "" {
 			if suffix == gocacheSubdir {
 				// Leave GOCACHE writable: we may need to write test binaries into it.
@@ -1625,11 +1721,18 @@
 				return filepath.SkipDir
 			}
 		}
-		if err == nil {
-			mode := info.Mode()
-			if mode&0222 != 0 && (mode.IsDir() || mode.IsRegular()) {
-				dirs = append(dirs, pathMode{path, mode})
-			}
+		if err != nil {
+			return nil
+		}
+
+		info, err := d.Info()
+		if err != nil {
+			return nil
+		}
+
+		mode := info.Mode()
+		if mode&0222 != 0 && (mode.IsDir() || mode.IsRegular()) {
+			dirs = append(dirs, pathMode{path, mode})
 		}
 		return nil
 	})
@@ -1647,71 +1750,9 @@
 	return undo
 }
 
-// shouldUsePrecompiledStdTest reports whether "dist test" should use
-// a pre-compiled go test binary on disk rather than running "go test"
-// and compiling it again. This is used by our slow qemu-based builder
-// that do full processor emulation where we cross-compile the
-// make.bash step as well as pre-compile each std test binary.
-//
-// This only reports true if dist is run with an single go_test:foo
-// argument (as the build coordinator does with our slow qemu-based
-// builders), we're in a builder environment ("GO_BUILDER_NAME" is set),
-// and the pre-built test binary exists.
-func (t *tester) shouldUsePrecompiledStdTest() bool {
-	bin := t.prebuiltGoPackageTestBinary()
-	if bin == "" {
-		return false
-	}
-	_, err := os.Stat(bin)
-	return err == nil
-}
-
-func (t *tester) shouldTestCmd() bool {
-	if goos == "js" && goarch == "wasm" {
-		// Issues 25911, 35220
-		return false
-	}
-	return true
-}
-
-// prebuiltGoPackageTestBinary returns the path where we'd expect
-// the pre-built go test binary to be on disk when dist test is run with
-// a single argument.
-// It returns an empty string if a pre-built binary should not be used.
-func (t *tester) prebuiltGoPackageTestBinary() string {
-	if len(stdMatches) != 1 || t.race || t.compileOnly || os.Getenv("GO_BUILDER_NAME") == "" {
-		return ""
-	}
-	pkg := stdMatches[0]
-	return filepath.Join(os.Getenv("GOROOT"), "src", pkg, path.Base(pkg)+".test")
-}
-
-// runPrecompiledStdTest runs the pre-compiled standard library package test binary.
-// See shouldUsePrecompiledStdTest above; it must return true for this to be called.
-func (t *tester) runPrecompiledStdTest(timeout time.Duration) error {
-	bin := t.prebuiltGoPackageTestBinary()
-	fmt.Fprintf(os.Stderr, "# %s: using pre-built %s...\n", stdMatches[0], bin)
-	cmd := exec.Command(bin, "-test.short="+short(), "-test.timeout="+timeout.String())
-	setDir(cmd, filepath.Dir(bin))
-	cmd.Stdout = os.Stdout
-	cmd.Stderr = os.Stderr
-	if err := cmd.Start(); err != nil {
-		return err
-	}
-	// And start a timer to kill the process if it doesn't kill
-	// itself in the prescribed timeout.
-	const backupKillFactor = 1.05 // add 5%
-	timer := time.AfterFunc(time.Duration(float64(timeout)*backupKillFactor), func() {
-		fmt.Fprintf(os.Stderr, "# %s: timeout running %s; killing...\n", stdMatches[0], bin)
-		cmd.Process.Kill()
-	})
-	defer timer.Stop()
-	return cmd.Wait()
-}
-
 // raceDetectorSupported is a copy of the function
-// cmd/internal/sys.RaceDetectorSupported, which can't be used here
-// because cmd/dist has to be buildable by Go 1.4.
+// internal/platform.RaceDetectorSupported, which can't be used here
+// because cmd/dist can not import internal packages during bootstrap.
 // The race detector only supports 48-bit VMA on arm64. But we don't have
 // a good solution to check VMA size(See https://golang.org/issue/29948)
 // raceDetectorSupported will always return true for arm64. But race
diff --git a/src/cmd/dist/test_linux.go b/src/cmd/dist/test_linux.go
deleted file mode 100644
index 43d28dc..0000000
--- a/src/cmd/dist/test_linux.go
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build linux
-// +build linux
-
-package main
-
-import (
-	"syscall"
-	"unsafe"
-)
-
-const ioctlReadTermios = syscall.TCGETS
-
-// isTerminal reports whether fd is a terminal.
-func isTerminal(fd uintptr) bool {
-	var termios syscall.Termios
-	_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
-	return err == 0
-}
-
-func init() {
-	stdOutErrAreTerminals = func() bool {
-		return isTerminal(1) && isTerminal(2)
-	}
-}
diff --git a/src/cmd/dist/util.go b/src/cmd/dist/util.go
index ee8ba91..fe36230 100644
--- a/src/cmd/dist/util.go
+++ b/src/cmd/dist/util.go
@@ -9,7 +9,6 @@
 	"flag"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"os"
 	"os/exec"
 	"path/filepath"
@@ -86,7 +85,7 @@
 	// as it runs without fear of mixing the output with some
 	// other command's output. Not buffering lets the output
 	// appear as it is printed instead of once the command exits.
-	// This is most important for the invocation of 'go1.4 build -v bootstrap/...'.
+	// This is most important for the invocation of 'go build -v bootstrap/...'.
 	if mode&(Background|ShowOutput) == ShowOutput {
 		xcmd.Stdout = os.Stdout
 		xcmd.Stderr = os.Stderr
@@ -228,7 +227,7 @@
 
 // readfile returns the content of the named file.
 func readfile(file string) string {
-	data, err := ioutil.ReadFile(file)
+	data, err := os.ReadFile(file)
 	if err != nil {
 		fatalf("%v", err)
 	}
@@ -247,7 +246,7 @@
 func writefile(text, file string, flag int) {
 	new := []byte(text)
 	if flag&writeSkipSame != 0 {
-		old, err := ioutil.ReadFile(file)
+		old, err := os.ReadFile(file)
 		if err == nil && bytes.Equal(old, new) {
 			return
 		}
@@ -257,7 +256,7 @@
 		mode = 0777
 	}
 	xremove(file) // in case of symlink tricks by misc/reboot test
-	err := ioutil.WriteFile(file, new, mode)
+	err := os.WriteFile(file, new, mode)
 	if err != nil {
 		fatalf("%v", err)
 	}
@@ -310,31 +309,10 @@
 	return names
 }
 
-// xreaddir replaces dst with a list of the names of the files in dir.
-// The names are relative to dir; they are not full paths.
-func xreaddirfiles(dir string) []string {
-	f, err := os.Open(dir)
-	if err != nil {
-		fatalf("%v", err)
-	}
-	defer f.Close()
-	infos, err := f.Readdir(-1)
-	if err != nil {
-		fatalf("reading %s: %v", dir, err)
-	}
-	var names []string
-	for _, fi := range infos {
-		if !fi.IsDir() {
-			names = append(names, fi.Name())
-		}
-	}
-	return names
-}
-
 // xworkdir creates a new temporary directory to hold object files
 // and returns the name of that directory.
 func xworkdir() string {
-	name, err := ioutil.TempDir(os.Getenv("GOTMPDIR"), "go-tool-dist-")
+	name, err := os.MkdirTemp(os.Getenv("GOTMPDIR"), "go-tool-dist-")
 	if err != nil {
 		fatalf("%v", err)
 	}
@@ -380,7 +358,7 @@
 	fmt.Fprintf(os.Stderr, format, args...)
 }
 
-// xsamefile reports whether f1 and f2 are the same file (or dir)
+// xsamefile reports whether f1 and f2 are the same file (or dir).
 func xsamefile(f1, f2 string) bool {
 	fi1, err1 := os.Stat(f1)
 	fi2, err2 := os.Stat(f2)
diff --git a/src/cmd/doc/doc_test.go b/src/cmd/doc/doc_test.go
index 5887ad3..6a259ae 100644
--- a/src/cmd/doc/doc_test.go
+++ b/src/cmd/doc/doc_test.go
@@ -1012,7 +1012,7 @@
 	if err := os.Chdir(filepath.Join(buildCtx.GOROOT, "src", "text")); err != nil {
 		t.Fatal(err)
 	}
-	var b bytes.Buffer
+	var b strings.Builder
 	var flagSet flag.FlagSet
 	err = do(&b, &flagSet, []string{"./template"})
 	if err != nil {
@@ -1030,7 +1030,7 @@
 // when there should be no output at all. Issue 37969.
 func TestNoPackageClauseWhenNoMatch(t *testing.T) {
 	maybeSkip(t)
-	var b bytes.Buffer
+	var b strings.Builder
 	var flagSet flag.FlagSet
 	err := do(&b, &flagSet, []string{"template.ZZZ"})
 	// Expect an error.
diff --git a/src/cmd/doc/main.go b/src/cmd/doc/main.go
index 3c45dd7..ae1b757 100644
--- a/src/cmd/doc/main.go
+++ b/src/cmd/doc/main.go
@@ -57,12 +57,13 @@
 )
 
 var (
-	unexported bool // -u flag
-	matchCase  bool // -c flag
-	showAll    bool // -all flag
-	showCmd    bool // -cmd flag
-	showSrc    bool // -src flag
-	short      bool // -short flag
+	unexported bool   // -u flag
+	matchCase  bool   // -c flag
+	chdir      string // -C flag
+	showAll    bool   // -all flag
+	showCmd    bool   // -cmd flag
+	showSrc    bool   // -src flag
+	short      bool   // -short flag
 )
 
 // usage is a replacement usage function for the flags package.
@@ -96,6 +97,7 @@
 	flagSet.Usage = usage
 	unexported = false
 	matchCase = false
+	flagSet.StringVar(&chdir, "C", "", "change to `dir` before running command")
 	flagSet.BoolVar(&unexported, "u", false, "show unexported symbols as well as exported")
 	flagSet.BoolVar(&matchCase, "c", false, "symbol matching honors case (paths not affected)")
 	flagSet.BoolVar(&showAll, "all", false, "show all documentation for package")
@@ -103,6 +105,11 @@
 	flagSet.BoolVar(&showSrc, "src", false, "show source code for symbol")
 	flagSet.BoolVar(&short, "short", false, "one-line representation for each symbol")
 	flagSet.Parse(args)
+	if chdir != "" {
+		if err := os.Chdir(chdir); err != nil {
+			return err
+		}
+	}
 	var paths []string
 	var symbol, method string
 	// Loop until something is printed.
diff --git a/src/cmd/doc/pkg.go b/src/cmd/doc/pkg.go
index 35f2eb2..4cebdc9 100644
--- a/src/cmd/doc/pkg.go
+++ b/src/cmd/doc/pkg.go
@@ -420,7 +420,7 @@
 
 	default:
 		// As a fallback, use default formatter for all unknown node types.
-		buf := new(bytes.Buffer)
+		buf := new(strings.Builder)
 		format.Node(buf, pkg.fs, node)
 		s := buf.String()
 		if strings.Contains(s, "\n") {
diff --git a/src/cmd/fix/cftype_test.go b/src/cmd/fix/cftype_test.go
index a18eb25..cde47f2 100644
--- a/src/cmd/fix/cftype_test.go
+++ b/src/cmd/fix/cftype_test.go
@@ -13,6 +13,7 @@
 		Name: "cftype.localVariable",
 		In: `package main
 
+// typedef const void *CFTypeRef;
 import "C"
 
 func f() {
@@ -23,6 +24,7 @@
 `,
 		Out: `package main
 
+// typedef const void *CFTypeRef;
 import "C"
 
 func f() {
@@ -36,6 +38,7 @@
 		Name: "cftype.globalVariable",
 		In: `package main
 
+// typedef const void *CFTypeRef;
 import "C"
 
 var x C.CFTypeRef = nil
@@ -46,6 +49,7 @@
 `,
 		Out: `package main
 
+// typedef const void *CFTypeRef;
 import "C"
 
 var x C.CFTypeRef = 0
@@ -59,6 +63,7 @@
 		Name: "cftype.EqualArgument",
 		In: `package main
 
+// typedef const void *CFTypeRef;
 import "C"
 
 var x C.CFTypeRef
@@ -67,6 +72,7 @@
 `,
 		Out: `package main
 
+// typedef const void *CFTypeRef;
 import "C"
 
 var x C.CFTypeRef
@@ -78,6 +84,7 @@
 		Name: "cftype.StructField",
 		In: `package main
 
+// typedef const void *CFTypeRef;
 import "C"
 
 type T struct {
@@ -88,6 +95,7 @@
 `,
 		Out: `package main
 
+// typedef const void *CFTypeRef;
 import "C"
 
 type T struct {
@@ -101,6 +109,7 @@
 		Name: "cftype.FunctionArgument",
 		In: `package main
 
+// typedef const void *CFTypeRef;
 import "C"
 
 func f(x C.CFTypeRef) {
@@ -112,6 +121,7 @@
 `,
 		Out: `package main
 
+// typedef const void *CFTypeRef;
 import "C"
 
 func f(x C.CFTypeRef) {
@@ -126,12 +136,14 @@
 		Name: "cftype.ArrayElement",
 		In: `package main
 
+// typedef const void *CFTypeRef;
 import "C"
 
 var x = [3]C.CFTypeRef{nil, nil, nil}
 `,
 		Out: `package main
 
+// typedef const void *CFTypeRef;
 import "C"
 
 var x = [3]C.CFTypeRef{0, 0, 0}
@@ -141,12 +153,14 @@
 		Name: "cftype.SliceElement",
 		In: `package main
 
+// typedef const void *CFTypeRef;
 import "C"
 
 var x = []C.CFTypeRef{nil, nil, nil}
 `,
 		Out: `package main
 
+// typedef const void *CFTypeRef;
 import "C"
 
 var x = []C.CFTypeRef{0, 0, 0}
@@ -156,12 +170,14 @@
 		Name: "cftype.MapKey",
 		In: `package main
 
+// typedef const void *CFTypeRef;
 import "C"
 
 var x = map[C.CFTypeRef]int{nil: 0}
 `,
 		Out: `package main
 
+// typedef const void *CFTypeRef;
 import "C"
 
 var x = map[C.CFTypeRef]int{0: 0}
@@ -171,12 +187,14 @@
 		Name: "cftype.MapValue",
 		In: `package main
 
+// typedef const void *CFTypeRef;
 import "C"
 
 var x = map[int]C.CFTypeRef{0: nil}
 `,
 		Out: `package main
 
+// typedef const void *CFTypeRef;
 import "C"
 
 var x = map[int]C.CFTypeRef{0: 0}
@@ -186,6 +204,7 @@
 		Name: "cftype.Conversion1",
 		In: `package main
 
+// typedef const void *CFTypeRef;
 import "C"
 
 var x C.CFTypeRef
@@ -193,6 +212,7 @@
 `,
 		Out: `package main
 
+// typedef const void *CFTypeRef;
 import "C"
 
 var x C.CFTypeRef
@@ -203,6 +223,7 @@
 		Name: "cftype.Conversion2",
 		In: `package main
 
+// typedef const void *CFTypeRef;
 import "C"
 
 var x unsafe.Pointer
@@ -210,6 +231,7 @@
 `,
 		Out: `package main
 
+// typedef const void *CFTypeRef;
 import "C"
 
 var x unsafe.Pointer
diff --git a/src/cmd/fix/egltype_test.go b/src/cmd/fix/egltype_test.go
index 9b64a7c..c44525c 100644
--- a/src/cmd/fix/egltype_test.go
+++ b/src/cmd/fix/egltype_test.go
@@ -17,6 +17,7 @@
 			Name: "egl.localVariable",
 			In: `package main
 
+// typedef void *$EGLTYPE;
 import "C"
 
 func f() {
@@ -27,6 +28,7 @@
 `,
 			Out: `package main
 
+// typedef void *$EGLTYPE;
 import "C"
 
 func f() {
@@ -40,6 +42,7 @@
 			Name: "egl.globalVariable",
 			In: `package main
 
+// typedef void *$EGLTYPE;
 import "C"
 
 var x C.$EGLTYPE = nil
@@ -50,6 +53,7 @@
 `,
 			Out: `package main
 
+// typedef void *$EGLTYPE;
 import "C"
 
 var x C.$EGLTYPE = 0
@@ -63,6 +67,7 @@
 			Name: "egl.EqualArgument",
 			In: `package main
 
+// typedef void *$EGLTYPE;
 import "C"
 
 var x C.$EGLTYPE
@@ -71,6 +76,7 @@
 `,
 			Out: `package main
 
+// typedef void *$EGLTYPE;
 import "C"
 
 var x C.$EGLTYPE
@@ -82,6 +88,7 @@
 			Name: "egl.StructField",
 			In: `package main
 
+// typedef void *$EGLTYPE;
 import "C"
 
 type T struct {
@@ -92,6 +99,7 @@
 `,
 			Out: `package main
 
+// typedef void *$EGLTYPE;
 import "C"
 
 type T struct {
@@ -105,6 +113,7 @@
 			Name: "egl.FunctionArgument",
 			In: `package main
 
+// typedef void *$EGLTYPE;
 import "C"
 
 func f(x C.$EGLTYPE) {
@@ -116,6 +125,7 @@
 `,
 			Out: `package main
 
+// typedef void *$EGLTYPE;
 import "C"
 
 func f(x C.$EGLTYPE) {
@@ -130,12 +140,14 @@
 			Name: "egl.ArrayElement",
 			In: `package main
 
+// typedef void *$EGLTYPE;
 import "C"
 
 var x = [3]C.$EGLTYPE{nil, nil, nil}
 `,
 			Out: `package main
 
+// typedef void *$EGLTYPE;
 import "C"
 
 var x = [3]C.$EGLTYPE{0, 0, 0}
@@ -145,12 +157,14 @@
 			Name: "egl.SliceElement",
 			In: `package main
 
+// typedef void *$EGLTYPE;
 import "C"
 
 var x = []C.$EGLTYPE{nil, nil, nil}
 `,
 			Out: `package main
 
+// typedef void *$EGLTYPE;
 import "C"
 
 var x = []C.$EGLTYPE{0, 0, 0}
@@ -160,12 +174,14 @@
 			Name: "egl.MapKey",
 			In: `package main
 
+// typedef void *$EGLTYPE;
 import "C"
 
 var x = map[C.$EGLTYPE]int{nil: 0}
 `,
 			Out: `package main
 
+// typedef void *$EGLTYPE;
 import "C"
 
 var x = map[C.$EGLTYPE]int{0: 0}
@@ -175,12 +191,14 @@
 			Name: "egl.MapValue",
 			In: `package main
 
+// typedef void *$EGLTYPE;
 import "C"
 
 var x = map[int]C.$EGLTYPE{0: nil}
 `,
 			Out: `package main
 
+// typedef void *$EGLTYPE;
 import "C"
 
 var x = map[int]C.$EGLTYPE{0: 0}
diff --git a/src/cmd/fix/jnitype_test.go b/src/cmd/fix/jnitype_test.go
index a6420f7..ecf0140 100644
--- a/src/cmd/fix/jnitype_test.go
+++ b/src/cmd/fix/jnitype_test.go
@@ -13,6 +13,7 @@
 		Name: "jni.localVariable",
 		In: `package main
 
+// typedef struct _jobject* jobject;
 import "C"
 
 func f() {
@@ -23,6 +24,7 @@
 `,
 		Out: `package main
 
+// typedef struct _jobject* jobject;
 import "C"
 
 func f() {
@@ -36,6 +38,7 @@
 		Name: "jni.globalVariable",
 		In: `package main
 
+// typedef struct _jobject* jobject;
 import "C"
 
 var x C.jobject = nil
@@ -46,6 +49,7 @@
 `,
 		Out: `package main
 
+// typedef struct _jobject* jobject;
 import "C"
 
 var x C.jobject = 0
@@ -59,6 +63,7 @@
 		Name: "jni.EqualArgument",
 		In: `package main
 
+// typedef struct _jobject* jobject;
 import "C"
 
 var x C.jobject
@@ -67,6 +72,7 @@
 `,
 		Out: `package main
 
+// typedef struct _jobject* jobject;
 import "C"
 
 var x C.jobject
@@ -78,6 +84,7 @@
 		Name: "jni.StructField",
 		In: `package main
 
+// typedef struct _jobject* jobject;
 import "C"
 
 type T struct {
@@ -88,6 +95,7 @@
 `,
 		Out: `package main
 
+// typedef struct _jobject* jobject;
 import "C"
 
 type T struct {
@@ -101,6 +109,7 @@
 		Name: "jni.FunctionArgument",
 		In: `package main
 
+// typedef struct _jobject* jobject;
 import "C"
 
 func f(x C.jobject) {
@@ -112,6 +121,7 @@
 `,
 		Out: `package main
 
+// typedef struct _jobject* jobject;
 import "C"
 
 func f(x C.jobject) {
@@ -126,12 +136,14 @@
 		Name: "jni.ArrayElement",
 		In: `package main
 
+// typedef struct _jobject* jobject;
 import "C"
 
 var x = [3]C.jobject{nil, nil, nil}
 `,
 		Out: `package main
 
+// typedef struct _jobject* jobject;
 import "C"
 
 var x = [3]C.jobject{0, 0, 0}
@@ -141,12 +153,14 @@
 		Name: "jni.SliceElement",
 		In: `package main
 
+// typedef struct _jobject* jobject;
 import "C"
 
 var x = []C.jobject{nil, nil, nil}
 `,
 		Out: `package main
 
+// typedef struct _jobject* jobject;
 import "C"
 
 var x = []C.jobject{0, 0, 0}
@@ -156,12 +170,14 @@
 		Name: "jni.MapKey",
 		In: `package main
 
+// typedef struct _jobject* jobject;
 import "C"
 
 var x = map[C.jobject]int{nil: 0}
 `,
 		Out: `package main
 
+// typedef struct _jobject* jobject;
 import "C"
 
 var x = map[C.jobject]int{0: 0}
@@ -171,12 +187,14 @@
 		Name: "jni.MapValue",
 		In: `package main
 
+// typedef struct _jobject* jobject;
 import "C"
 
 var x = map[int]C.jobject{0: nil}
 `,
 		Out: `package main
 
+// typedef struct _jobject* jobject;
 import "C"
 
 var x = map[int]C.jobject{0: 0}
diff --git a/src/cmd/fix/main.go b/src/cmd/fix/main.go
index 4e5c087..0f36fcc 100644
--- a/src/cmd/fix/main.go
+++ b/src/cmd/fix/main.go
@@ -75,8 +75,8 @@
 		}
 		majorStr := (*goVersionStr)[len("go"):]
 		minorStr := "0"
-		if i := strings.Index(majorStr, "."); i >= 0 {
-			majorStr, minorStr = majorStr[:i], majorStr[i+len("."):]
+		if before, after, found := strings.Cut(majorStr, "."); found {
+			majorStr, minorStr = before, after
 		}
 		major, err1 := strconv.Atoi(majorStr)
 		minor, err2 := strconv.Atoi(minorStr)
@@ -141,7 +141,7 @@
 func processFile(filename string, useStdin bool) error {
 	var f *os.File
 	var err error
-	var fixlog bytes.Buffer
+	var fixlog strings.Builder
 
 	if useStdin {
 		f = os.Stdin
@@ -240,7 +240,7 @@
 }
 
 func gofmt(n any) string {
-	var gofmtBuf bytes.Buffer
+	var gofmtBuf strings.Builder
 	if err := format.Node(&gofmtBuf, fset, n); err != nil {
 		return "<" + err.Error() + ">"
 	}
diff --git a/src/cmd/fix/main_test.go b/src/cmd/fix/main_test.go
index 755007b..2b29307 100644
--- a/src/cmd/fix/main_test.go
+++ b/src/cmd/fix/main_test.go
@@ -5,13 +5,29 @@
 package main
 
 import (
+	"fmt"
 	"go/ast"
 	"go/parser"
 	"internal/diff"
+	"internal/testenv"
 	"strings"
 	"testing"
 )
 
+func init() {
+	// If cgo is enabled, enforce that cgo commands invoked by cmd/fix
+	// do not fail during testing.
+	if testenv.HasCGO() && testenv.HasGoBuild() {
+		// The reportCgoError hook is global, so we can't set it per-test
+		// if we want to be able to run those tests in parallel.
+		// Instead, simply set it to panic on error: the goroutine dump
+		// from the panic should help us determine which test failed.
+		reportCgoError = func(err error) {
+			panic(fmt.Sprintf("unexpected cgo error: %v", err))
+		}
+	}
+}
+
 type testCase struct {
 	Name    string
 	Fn      func(*ast.File) bool
@@ -79,7 +95,13 @@
 		tt := tt
 		t.Run(tt.Name, func(t *testing.T) {
 			if tt.Version == 0 {
-				t.Parallel()
+				if testing.Verbose() {
+					// Don't run in parallel: cmd/fix sometimes writes directly to stderr,
+					// and since -v prints which test is currently running we want that
+					// information to accurately correlate with the stderr output.
+				} else {
+					t.Parallel()
+				}
 			} else {
 				old := goVersion
 				goVersion = tt.Version
diff --git a/src/cmd/fix/typecheck.go b/src/cmd/fix/typecheck.go
index 015a0ee..b115987 100644
--- a/src/cmd/fix/typecheck.go
+++ b/src/cmd/fix/typecheck.go
@@ -170,7 +170,16 @@
 			if err != nil {
 				return err
 			}
-			cmd := exec.Command(filepath.Join(runtime.GOROOT(), "bin", "go"), "tool", "cgo", "-objdir", dir, "-srcdir", dir, "in.go")
+			goCmd := "go"
+			if goroot := runtime.GOROOT(); goroot != "" {
+				goCmd = filepath.Join(goroot, "bin", "go")
+			}
+			cmd := exec.Command(goCmd, "tool", "cgo", "-objdir", dir, "-srcdir", dir, "in.go")
+			if reportCgoError != nil {
+				// Since cgo command errors will be reported, also forward the error
+				// output from the command for debugging.
+				cmd.Stderr = os.Stderr
+			}
 			err = cmd.Run()
 			if err != nil {
 				return err
@@ -206,7 +215,11 @@
 			return nil
 		}()
 		if err != nil {
-			fmt.Fprintf(os.Stderr, "go fix: warning: no cgo types: %s\n", err)
+			if reportCgoError == nil {
+				fmt.Fprintf(os.Stderr, "go fix: warning: no cgo types: %s\n", err)
+			} else {
+				reportCgoError(err)
+			}
 		}
 	}
 
@@ -285,6 +298,10 @@
 	return typeof, assign
 }
 
+// reportCgoError, if non-nil, reports a non-nil error from running the "cgo"
+// tool. (Set to a non-nil hook during testing if cgo is expected to work.)
+var reportCgoError func(err error)
+
 func makeExprList(a []*ast.Ident) []ast.Expr {
 	var b []ast.Expr
 	for _, x := range a {
@@ -293,7 +310,7 @@
 	return b
 }
 
-// Typecheck1 is the recursive form of typecheck.
+// typecheck1 is the recursive form of typecheck.
 // It is like typecheck but adds to the information in typeof
 // instead of allocating a new map.
 func typecheck1(cfg *TypeConfig, f any, typeof map[any]string, assign map[string][]any) {
diff --git a/src/cmd/go.mod b/src/cmd/go.mod
index 8230a3e..d2e3949 100644
--- a/src/cmd/go.mod
+++ b/src/cmd/go.mod
@@ -1,18 +1,15 @@
 module cmd
 
-go 1.19
+go 1.20
 
 require (
-	github.com/google/pprof v0.0.0-20220517023622-154dc81eb7b0
-	golang.org/x/arch v0.0.0-20220412001346-fc48f9fe4c15
-	golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4
-	golang.org/x/sync v0.0.0-20220513210516-0976fa681c29
-	golang.org/x/sys v0.0.0-20220614162138-6c1b26c55098
-	golang.org/x/term v0.0.0-20220411215600-e5f449aeb171
-	golang.org/x/tools v0.1.11-0.20220516163903-1e55371df567
+	github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26
+	golang.org/x/arch v0.1.1-0.20221116201807-1bb480fc256a
+	golang.org/x/mod v0.7.0
+	golang.org/x/sync v0.1.0
+	golang.org/x/sys v0.3.0
+	golang.org/x/term v0.2.0
+	golang.org/x/tools v0.3.1-0.20230118190848-070db2996ebe
 )
 
-require (
-	github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2 // indirect
-	golang.org/x/crypto v0.0.0-20220516162934-403b01795ae8 // indirect
-)
+require github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2 // indirect
diff --git a/src/cmd/go.sum b/src/cmd/go.sum
index 435c3cc..da5f720 100644
--- a/src/cmd/go.sum
+++ b/src/cmd/go.sum
@@ -1,18 +1,16 @@
-github.com/google/pprof v0.0.0-20220517023622-154dc81eb7b0 h1:XgEFTOJTsN3Li0Txfhn2UzsysGJfXIDe7wE07uY7ZfI=
-github.com/google/pprof v0.0.0-20220517023622-154dc81eb7b0/go.mod h1:gSuNB+gJaOiQKLEZ+q+PK9Mq3SOzhRcw2GsGS/FhYDk=
+github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
+github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
 github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2 h1:rcanfLhLDA8nozr/K289V1zcntHr3V+SHlXwzz1ZI2g=
 github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
-golang.org/x/arch v0.0.0-20220412001346-fc48f9fe4c15 h1:GVfVkciLYxn5mY5EncwAe0SXUn9Rm81rRkZ0TTmn/cU=
-golang.org/x/arch v0.0.0-20220412001346-fc48f9fe4c15/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
-golang.org/x/crypto v0.0.0-20220516162934-403b01795ae8 h1:y+mHpWoQJNAHt26Nhh6JP7hvM71IRZureyvZhoVALIs=
-golang.org/x/crypto v0.0.0-20220516162934-403b01795ae8/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
-golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
-golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
-golang.org/x/sync v0.0.0-20220513210516-0976fa681c29 h1:w8s32wxx3sY+OjLlv9qltkLU5yvJzxjjgiHWLjdIcw4=
-golang.org/x/sync v0.0.0-20220513210516-0976fa681c29/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sys v0.0.0-20220614162138-6c1b26c55098 h1:PgOr27OhUx2IRqGJ2RxAWI4dJQ7bi9cSrB82uzFzfUA=
-golang.org/x/sys v0.0.0-20220614162138-6c1b26c55098/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/term v0.0.0-20220411215600-e5f449aeb171 h1:EH1Deb8WZJ0xc0WK//leUHXcX9aLE5SymusoTmMZye8=
-golang.org/x/term v0.0.0-20220411215600-e5f449aeb171/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-golang.org/x/tools v0.1.11-0.20220516163903-1e55371df567 h1:MksUZ/zlU+pMbsq1Sw16gK6E1aWzD0rLE+eS2SxF24Y=
-golang.org/x/tools v0.1.11-0.20220516163903-1e55371df567/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4=
+golang.org/x/arch v0.1.1-0.20221116201807-1bb480fc256a h1:TpDpIG2bYSheFxm9xw8NNrBKrurU1ZJ59ZMXnpQwPLQ=
+golang.org/x/arch v0.1.1-0.20221116201807-1bb480fc256a/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
+golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA=
+golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
+golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.2.0 h1:z85xZCsEl7bi/KwbNADeBYoOP0++7W1ipu+aGnpwzRM=
+golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
+golang.org/x/tools v0.3.1-0.20230118190848-070db2996ebe h1:1B2tjdkEp2f885xTfSsY+7mi5fNZHRxWciDl8Hz3EXg=
+golang.org/x/tools v0.3.1-0.20230118190848-070db2996ebe/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k=
diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go
index a3c1fec..84afcab 100644
--- a/src/cmd/go/alldocs.go
+++ b/src/cmd/go/alldocs.go
@@ -97,12 +97,13 @@
 // ends with a slash or backslash, then any resulting executables
 // will be written to that directory.
 //
-// The -i flag installs the packages that are dependencies of the target.
-// The -i flag is deprecated. Compiled packages are cached automatically.
-//
 // The build flags are shared by the build, clean, get, install, list, run,
 // and test commands:
 //
+//	-C dir
+//		Change to dir before running the command.
+//		Any files named on the command line are interpreted after
+//		changing directories.
 //	-a
 //		force rebuilding of packages that are already up-to-date.
 //	-n
@@ -117,14 +118,23 @@
 //		linux/ppc64le and linux/arm64 (only for 48-bit VMA).
 //	-msan
 //		enable interoperation with memory sanitizer.
-//		Supported only on linux/amd64, linux/arm64
+//		Supported only on linux/amd64, linux/arm64, freebsd/amd64
 //		and only with Clang/LLVM as the host C compiler.
-//		On linux/arm64, pie build mode will be used.
+//		PIE build mode will be used on all platforms except linux/amd64.
 //	-asan
 //		enable interoperation with address sanitizer.
 //		Supported only on linux/arm64, linux/amd64.
 //		Supported only on linux/amd64 or linux/arm64 and only with GCC 7 and higher
 //		or Clang/LLVM 9 and higher.
+//	-cover
+//		enable code coverage instrumentation (requires
+//		that GOEXPERIMENT=coverageredesign be set).
+//	-coverpkg pattern1,pattern2,pattern3
+//		For a build that targets package 'main' (e.g. building a Go
+//		executable), apply coverage analysis to each package matching
+//		the patterns. The default is to apply coverage analysis to
+//		packages in the main Go module. See 'go help packages' for a
+//		description of package patterns.  Sets -cover.
 //	-v
 //		print the names of packages as they are compiled.
 //	-work
@@ -190,6 +200,11 @@
 //		include path must be in the same directory as the Go package they are
 //		included from, and overlays will not appear when binaries and tests are
 //		run through go run and go test respectively.
+//	-pgo file
+//		specify the file path of a profile for profile-guided optimization (PGO).
+//		Special name "auto" lets the go command select a file named
+//		"default.pgo" in the main package's directory if that file exists.
+//		Special name "off" turns off PGO.
 //	-pkgdir dir
 //		install and load all packages from dir instead of the usual locations.
 //		For example, when building with a non-standard configuration,
@@ -594,7 +609,7 @@
 //
 // The generator is run in the package's source directory.
 //
-// Go generate accepts one specific flag:
+// Go generate accepts two specific flags:
 //
 //	-run=""
 //		if non-empty, specifies a regular expression to select
@@ -602,6 +617,13 @@
 //		any trailing spaces and final newline) matches the
 //		expression.
 //
+//	-skip=""
+//		if non-empty, specifies a regular expression to suppress
+//		directives whose full original source text (excluding
+//		any trailing spaces and final newline) matches the
+//		expression. If a directive matches both the -run and
+//		the -skip arguments, it is skipped.
+//
 // It also accepts the standard build flags including -v, -n, and -x.
 // The -v flag prints the names of packages and files as they are
 // processed.
@@ -724,12 +746,15 @@
 // If module-aware mode is enabled, "go install" runs in the context of the main
 // module.
 //
-// When module-aware mode is disabled, other packages are installed in the
+// When module-aware mode is disabled, non-main packages are installed in the
 // directory $GOPATH/pkg/$GOOS_$GOARCH. When module-aware mode is enabled,
-// other packages are built and cached but not installed.
+// non-main packages are built and cached but not installed.
 //
-// The -i flag installs the dependencies of the named packages as well.
-// The -i flag is deprecated. Compiled packages are cached automatically.
+// Before Go 1.20, the standard library was installed to
+// $GOROOT/pkg/$GOOS_$GOARCH.
+// Starting in Go 1.20, the standard library is built and cached but not installed.
+// Setting GODEBUG=installgoroot=all restores the use of
+// $GOROOT/pkg/$GOOS_$GOARCH.
 //
 // For more about the build flags, see 'go help build'.
 // For more about specifying packages, see 'go help packages'.
@@ -1223,13 +1248,15 @@
 // referred to indirectly. For the full set of modules available to a build,
 // use 'go list -m -json all'.
 //
+// Edit also provides the -C, -n, and -x build flags.
+//
 // See https://golang.org/ref/mod#go-mod-edit for more about 'go mod edit'.
 //
 // # Print module requirement graph
 //
 // Usage:
 //
-//	go mod graph [-go=version]
+//	go mod graph [-go=version] [-x]
 //
 // Graph prints the module requirement graph (with replacements applied)
 // in text form. Each line in the output has two space-separated fields: a module
@@ -1240,6 +1267,8 @@
 // given Go version, instead of the version indicated by the 'go' directive
 // in the go.mod file.
 //
+// The -x flag causes graph to print the commands graph executes.
+//
 // See https://golang.org/ref/mod#go-mod-graph for more about 'go mod graph'.
 //
 // # Initialize new module in current directory
@@ -1266,7 +1295,7 @@
 //
 // Usage:
 //
-//	go mod tidy [-e] [-v] [-go=version] [-compat=version]
+//	go mod tidy [-e] [-v] [-x] [-go=version] [-compat=version]
 //
 // Tidy makes sure go.mod matches the source code in the module.
 // It adds any missing modules necessary to build the current module's
@@ -1294,6 +1323,8 @@
 // version prior to the one indicated by the 'go' directive in the go.mod
 // file.
 //
+// The -x flag causes tidy to print the commands download executes.
+//
 // See https://golang.org/ref/mod#go-mod-tidy for more about 'go mod tidy'.
 //
 // # Make vendored copy of dependencies
@@ -1728,11 +1759,6 @@
 //	    Run the test binary using xprog. The behavior is the same as
 //	    in 'go run'. See 'go help run' for details.
 //
-//	-i
-//	    Install packages that are dependencies of the test.
-//	    Do not run the test.
-//	    The -i flag is deprecated. Compiled packages are cached automatically.
-//
 //	-json
 //	    Convert test output to JSON suitable for automated processing.
 //	    See 'go doc test2json' for the encoding details.
@@ -1769,10 +1795,9 @@
 //
 //	go version [-m] [-v] [file ...]
 //
-// Version prints the build information for Go executables.
+// Version prints the build information for Go binary files.
 //
-// Go version reports the Go version used to build each of the named
-// executable files.
+// Go version reports the Go version used to build each of the named files.
 //
 // If no files are named on the command line, go version prints its own
 // version information.
@@ -1782,7 +1807,7 @@
 // By default, go version does not report unrecognized files found
 // during a directory scan. The -v flag causes it to report unrecognized files.
 //
-// The -m flag causes go version to print each executable's embedded
+// The -m flag causes go version to print each file's embedded
 // module version information, when available. In the output, the module
 // information consists of multiple lines following the version line, each
 // indented by a leading tab character.
@@ -1793,7 +1818,7 @@
 //
 // Usage:
 //
-//	go vet [-n] [-x] [-vettool prog] [build flags] [vet flags] [packages]
+//	go vet [-C dir] [-n] [-x] [-vettool prog] [build flags] [vet flags] [packages]
 //
 // Vet runs the Go vet command on the packages named by the import paths.
 //
@@ -1802,6 +1827,7 @@
 // For a list of checkers and their flags, see 'go tool vet help'.
 // For details of a specific checker such as 'printf', see 'go tool vet help printf'.
 //
+// The -C flag changes to dir before running the 'go vet' command.
 // The -n flag prints commands that would be executed.
 // The -x flag prints commands as they are executed.
 //
@@ -1809,7 +1835,7 @@
 // or additional checks.
 // For example, the 'shadow' analyzer can be built and run using these commands:
 //
-//	go install golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow
+//	go install golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow@latest
 //	go vet -vettool=$(which shadow)
 //
 // The build flags supported by go vet are those that control package resolution
@@ -1852,6 +1878,8 @@
 //     GOOS environment variable.
 //   - the target architecture, as spelled by runtime.GOARCH, set with the
 //     GOARCH environment variable.
+//   - any architecture features, in the form GOARCH.feature
+//     (for example, "amd64.v2"), as detailed below.
 //   - "unix", if GOOS is a Unix or Unix-like system.
 //   - the compiler being used, either "gc" or "gccgo"
 //   - "cgo", if the cgo command is supported (see CGO_ENABLED in
@@ -1883,11 +1911,45 @@
 // Using GOOS=ios matches build tags and files as for GOOS=darwin
 // in addition to ios tags and files.
 //
-// To keep a file from being considered for the build:
+// The defined architecture feature build tags are:
+//
+//   - For GOARCH=386, GO386=387 and GO386=sse2
+//     set the 386.387 and 386.sse2 build tags, respectively.
+//   - For GOARCH=amd64, GOAMD64=v1, v2, and v3
+//     correspond to the amd64.v1, amd64.v2, and amd64.v3 feature build tags.
+//   - For GOARCH=arm, GOARM=5, 6, and 7
+//     correspond to the arm.5, arm.6, and arm.7 feature build tags.
+//   - For GOARCH=mips or mipsle,
+//     GOMIPS=hardfloat and softfloat
+//     correspond to the mips.hardfloat and mips.softfloat
+//     (or mipsle.hardfloat and mipsle.softfloat) feature build tags.
+//   - For GOARCH=mips64 or mips64le,
+//     GOMIPS64=hardfloat and softfloat
+//     correspond to the mips64.hardfloat and mips64.softfloat
+//     (or mips64le.hardfloat and mips64le.softfloat) feature build tags.
+//   - For GOARCH=ppc64 or ppc64le,
+//     GOPPC64=power8, power9, and power10 correspond to the
+//     ppc64.power8, ppc64.power9, and ppc64.power10
+//     (or ppc64le.power8, ppc64le.power9, and ppc64le.power10)
+//     feature build tags.
+//   - For GOARCH=wasm, GOWASM=satconv and signext
+//     correspond to the wasm.satconv and wasm.signext feature build tags.
+//
+// For GOARCH=amd64, arm, ppc64, and ppc64le, a particular feature level
+// sets the feature build tags for all previous levels as well.
+// For example, GOAMD64=v2 sets the amd64.v1 and amd64.v2 feature flags.
+// This ensures that code making use of v2 features continues to compile
+// when, say, GOAMD64=v4 is introduced.
+// Code handling the absence of a particular feature level
+// should use a negation:
+//
+//	//go:build !amd64.v2
+//
+// To keep a file from being considered for any build:
 //
 //	//go:build ignore
 //
-// (any other unsatisfied word will work as well, but "ignore" is conventional.)
+// (Any other unsatisfied word will work as well, but "ignore" is conventional.)
 //
 // To build a file only when using cgo, and only on Linux and OS X:
 //
@@ -2164,11 +2226,18 @@
 //		Valid values are hardfloat (default), softfloat.
 //	GOPPC64
 //		For GOARCH=ppc64{,le}, the target ISA (Instruction Set Architecture).
-//		Valid values are power8 (default), power9.
+//		Valid values are power8 (default), power9, power10.
 //	GOWASM
 //		For GOARCH=wasm, comma-separated list of experimental WebAssembly features to use.
 //		Valid values are satconv, signext.
 //
+// Environment variables for use with code coverage:
+//
+//	GOCOVERDIR
+//		Directory into which to write code coverage data files
+//		generated by running a "go build -cover" binary.
+//		Requires that GOEXPERIMENT=coverageredesign is enabled.
+//
 // Special-purpose environment variables:
 //
 //	GCCGOTOOLDIR
@@ -2976,6 +3045,7 @@
 //	    run too, so that -run=X/Y matches and runs and reports the result
 //	    of all tests matching X, even those without sub-tests matching Y,
 //	    because it must run them to look for those sub-tests.
+//	    See also -skip.
 //
 //	-short
 //	    Tell long-running tests to shorten their run time.
@@ -2990,6 +3060,14 @@
 //	    integer N, then N will be used as the seed value. In both cases,
 //	    the seed will be reported for reproducibility.
 //
+//	-skip regexp
+//	    Run only those tests, examples, fuzz tests, and benchmarks that
+//	    do not match the regular expression. Like for -run and -bench,
+//	    for tests and benchmarks, the regular expression is split by unbracketed
+//	    slash (/) characters into a sequence of regular expressions, and each
+//	    part of a test's identifier must match the corresponding element in
+//	    the sequence, if any.
+//
 //	-timeout d
 //	    If a test binary runs longer than duration d, panic.
 //	    If d is 0, the timeout is disabled.
diff --git a/src/cmd/go/chdir_test.go b/src/cmd/go/chdir_test.go
new file mode 100644
index 0000000..44cbb9c
--- /dev/null
+++ b/src/cmd/go/chdir_test.go
@@ -0,0 +1,49 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"cmd/go/internal/base"
+	"os"
+	"strings"
+	"testing"
+)
+
+func TestChdir(t *testing.T) {
+	// We want -C to apply to every go subcommand.
+	// Test that every command either has a -C flag registered
+	// or has CustomFlags set. In the latter case, the command
+	// must be explicitly tested in TestScript/chdir.
+	script, err := os.ReadFile("testdata/script/chdir.txt")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	var walk func(string, *base.Command)
+	walk = func(name string, cmd *base.Command) {
+		if len(cmd.Commands) > 0 {
+			for _, sub := range cmd.Commands {
+				walk(name+" "+sub.Name(), sub)
+			}
+			return
+		}
+		if !cmd.Runnable() {
+			return
+		}
+		if cmd.CustomFlags {
+			if !strings.Contains(string(script), "# "+name+"\n") {
+				t.Errorf("%s has custom flags, not tested in testdata/script/chdir.txt", name)
+			}
+			return
+		}
+		f := cmd.Flag.Lookup("C")
+		if f == nil {
+			t.Errorf("%s has no -C flag", name)
+		} else if f.Usage != "AddChdirFlag" {
+			t.Errorf("%s has -C flag but not from AddChdirFlag", name)
+		}
+	}
+	walk("go", base.Go)
+}
diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go
index a0082a3..ef22499 100644
--- a/src/cmd/go/go_test.go
+++ b/src/cmd/go/go_test.go
@@ -14,6 +14,7 @@
 	"fmt"
 	"go/format"
 	"internal/godebug"
+	"internal/platform"
 	"internal/testenv"
 	"io"
 	"io/fs"
@@ -32,6 +33,9 @@
 	"cmd/go/internal/cfg"
 	"cmd/go/internal/robustio"
 	"cmd/go/internal/search"
+	"cmd/go/internal/vcs"
+	"cmd/go/internal/vcweb/vcstest"
+	"cmd/go/internal/web"
 	"cmd/go/internal/work"
 	"cmd/internal/sys"
 
@@ -47,12 +51,15 @@
 }
 
 var (
-	canRace          = false // whether we can run the race detector
-	canCgo           = false // whether we can use cgo
-	canMSan          = false // whether we can run the memory sanitizer
-	canASan          = false // whether we can run the address sanitizer
-	canFuzz          = false // whether we can search for new fuzz failures
-	fuzzInstrumented = false // whether fuzzing uses instrumentation
+	canRace = false // whether we can run the race detector
+	canCgo  = false // whether we can use cgo
+	canMSan = false // whether we can run the memory sanitizer
+	canASan = false // whether we can run the address sanitizer
+)
+
+var (
+	goHostOS, goHostArch string
+	cgoEnabled           string // raw value from 'go env CGO_ENABLED'
 )
 
 var exeSuffix string = func() string {
@@ -96,6 +103,8 @@
 	// run the main func exported via export_test.go, and exit.
 	// We set CMDGO_TEST_RUN_MAIN via os.Setenv and testScript.setup.
 	if os.Getenv("CMDGO_TEST_RUN_MAIN") != "" {
+		cfg.SetGOROOT(cfg.GOROOT, true)
+
 		if v := os.Getenv("TESTGO_VERSION"); v != "" {
 			work.RuntimeVersion = v
 		}
@@ -120,9 +129,28 @@
 					}
 					callerPos = fmt.Sprintf("%s:%d: ", file, line)
 				}
-				return fmt.Errorf("%stestgo must not write to GOROOT (installing to %s)", callerPos, filepath.Join("GOROOT", rel))
+				notice := "This error error can occur if GOROOT is stale, in which case rerunning make.bash will fix it."
+				return fmt.Errorf("%stestgo must not write to GOROOT (installing to %s) (%v)", callerPos, filepath.Join("GOROOT", rel), notice)
 			}
 		}
+
+		if vcsTestHost := os.Getenv("TESTGO_VCSTEST_HOST"); vcsTestHost != "" {
+			vcs.VCSTestRepoURL = "http://" + vcsTestHost
+			vcs.VCSTestHosts = vcstest.Hosts
+			vcsTestTLSHost := os.Getenv("TESTGO_VCSTEST_TLS_HOST")
+			vcsTestClient, err := vcstest.TLSClient(os.Getenv("TESTGO_VCSTEST_CERT"))
+			if err != nil {
+				fmt.Fprintf(os.Stderr, "loading certificates from $TESTGO_VCSTEST_CERT: %v", err)
+			}
+			var interceptors []web.Interceptor
+			for _, host := range vcstest.Hosts {
+				interceptors = append(interceptors,
+					web.Interceptor{Scheme: "http", FromHost: host, ToHost: vcsTestHost},
+					web.Interceptor{Scheme: "https", FromHost: host, ToHost: vcsTestTLSHost, Client: vcsTestClient})
+			}
+			web.EnableTestHooks(interceptors)
+		}
+
 		cmdgo.Main()
 		os.Exit(0)
 	}
@@ -152,6 +180,8 @@
 	}
 	if !*testWork {
 		defer removeAll(topTmpdir)
+	} else {
+		fmt.Fprintf(os.Stderr, "TESTWORK: preserving top level tempdir %s\n", topTmpdir)
 	}
 	os.Setenv(tempEnvName(), topTmpdir)
 
@@ -204,13 +234,16 @@
 		// which will cause many tests to do unnecessary rebuilds and some
 		// tests to attempt to overwrite the installed standard library.
 		// Bail out entirely in this case.
-		hostGOOS := goEnv("GOHOSTOS")
-		hostGOARCH := goEnv("GOHOSTARCH")
-		if hostGOOS != runtime.GOOS || hostGOARCH != runtime.GOARCH {
-			fmt.Fprintf(os.Stderr, "testing: warning: no tests to run\n") // magic string for cmd/go
-			fmt.Printf("cmd/go test is not compatible with GOOS/GOARCH != GOHOSTOS/GOHOSTARCH (%s/%s != %s/%s)\n", runtime.GOOS, runtime.GOARCH, hostGOOS, hostGOARCH)
-			fmt.Printf("SKIP\n")
-			return
+		goHostOS = goEnv("GOHOSTOS")
+		os.Setenv("TESTGO_GOHOSTOS", goHostOS)
+		goHostArch = goEnv("GOHOSTARCH")
+		os.Setenv("TESTGO_GOHOSTARCH", goHostArch)
+
+		cgoEnabled = goEnv("CGO_ENABLED")
+		canCgo, err = strconv.ParseBool(cgoEnabled)
+		if err != nil {
+			fmt.Fprintf(os.Stderr, "can't parse go env CGO_ENABLED output: %q\n", strings.TrimSpace(cgoEnabled))
+			os.Exit(2)
 		}
 
 		// Duplicate the test executable into the path at testGo, for $PATH.
@@ -241,18 +274,6 @@
 			}
 		}
 
-		cmd := exec.Command(testGo, "env", "CGO_ENABLED")
-		cmd.Stderr = new(strings.Builder)
-		if out, err := cmd.Output(); err != nil {
-			fmt.Fprintf(os.Stderr, "running testgo failed: %v\n%s", err, cmd.Stderr)
-			os.Exit(2)
-		} else {
-			canCgo, err = strconv.ParseBool(strings.TrimSpace(string(out)))
-			if err != nil {
-				fmt.Fprintf(os.Stderr, "can't parse go env CGO_ENABLED output: %v\n", strings.TrimSpace(string(out)))
-			}
-		}
-
 		out, err := exec.Command(gotool, "env", "GOCACHE").CombinedOutput()
 		if err != nil {
 			fmt.Fprintf(os.Stderr, "could not find testing GOCACHE: %v\n%s", err, out)
@@ -260,18 +281,17 @@
 		}
 		testGOCACHE = strings.TrimSpace(string(out))
 
-		canMSan = canCgo && sys.MSanSupported(runtime.GOOS, runtime.GOARCH)
-		canASan = canCgo && sys.ASanSupported(runtime.GOOS, runtime.GOARCH)
-		canRace = canCgo && sys.RaceDetectorSupported(runtime.GOOS, runtime.GOARCH)
+		canMSan = canCgo && platform.MSanSupported(runtime.GOOS, runtime.GOARCH)
+		canASan = canCgo && platform.ASanSupported(runtime.GOOS, runtime.GOARCH)
+		canRace = canCgo && platform.RaceDetectorSupported(runtime.GOOS, runtime.GOARCH)
 		// The race detector doesn't work on Alpine Linux:
 		// golang.org/issue/14481
 		// gccgo does not support the race detector.
 		if isAlpineLinux() || runtime.Compiler == "gccgo" {
 			canRace = false
 		}
-		canFuzz = sys.FuzzSupported(runtime.GOOS, runtime.GOARCH)
-		fuzzInstrumented = sys.FuzzInstrumented(runtime.GOOS, runtime.GOARCH)
 	}
+
 	// Don't let these environment variables confuse the test.
 	os.Setenv("GOENV", "off")
 	os.Unsetenv("GOFLAGS")
@@ -467,7 +487,7 @@
 	}
 
 	tg.t.Logf("running testgo %v", args)
-	cmd := exec.Command(prog, args...)
+	cmd := testenv.Command(tg.t, prog, args...)
 	tg.stdout.Reset()
 	tg.stderr.Reset()
 	cmd.Dir = tg.execDir
@@ -510,7 +530,7 @@
 // runGit runs a git command, and expects it to succeed.
 func (tg *testgoData) runGit(dir string, args ...string) {
 	tg.t.Helper()
-	cmd := exec.Command("git", args...)
+	cmd := testenv.Command(tg.t, "git", args...)
 	tg.stdout.Reset()
 	tg.stderr.Reset()
 	cmd.Stdout = &tg.stdout
@@ -827,7 +847,9 @@
 func (tg *testgoData) cleanup() {
 	tg.t.Helper()
 	if *testWork {
-		tg.t.Logf("TESTWORK=%s\n", tg.path("."))
+		if tg.tempdir != "" {
+			tg.t.Logf("TESTWORK=%s\n", tg.path("."))
+		}
 		return
 	}
 	for _, path := range tg.temps {
@@ -873,20 +895,26 @@
 	defer tg.cleanup()
 	tg.parallel()
 
+	// Set GOCACHE to an empty directory so that a previous run of
+	// this test does not affect the staleness of the packages it builds.
+	tg.tempDir("gocache")
+	tg.setenv("GOCACHE", tg.path("gocache"))
+
 	// Copy the runtime packages into a temporary GOROOT
 	// so that we can change files.
 	for _, copydir := range []string{
 		"src/runtime",
 		"src/internal/abi",
 		"src/internal/bytealg",
+		"src/internal/coverage/rtcov",
 		"src/internal/cpu",
 		"src/internal/goarch",
 		"src/internal/goexperiment",
 		"src/internal/goos",
+		"src/internal/coverage/rtcov",
 		"src/math/bits",
 		"src/unsafe",
-		filepath.Join("pkg", runtime.GOOS+"_"+runtime.GOARCH),
-		filepath.Join("pkg/tool", runtime.GOOS+"_"+runtime.GOARCH),
+		filepath.Join("pkg/tool", goHostOS+"_"+goHostArch),
 		"pkg/include",
 	} {
 		srcdir := filepath.Join(testGOROOT, copydir)
@@ -942,7 +970,7 @@
 	tg.tempFile("d1/src/p1/p1.go", `package main; func main(){}`)
 	tg.setenv("GOPATH", tg.path("d1"))
 	// Pass -i flag to rebuild everything outdated.
-	tg.run("install", "-i", "p1")
+	tg.run("install", "p1")
 	tg.wantNotStale("p1", "", "./testgo list claims p1 is stale, incorrectly, before any changes")
 
 	// Changing mtime of runtime/internal/sys/sys.go
@@ -959,18 +987,18 @@
 	// now they all matter, so keep using sys.go.
 	restore = addVar(sys, 1)
 	defer restore()
-	tg.wantStale("p1", "stale dependency: runtime/internal/sys", "./testgo list claims p1 is NOT stale, incorrectly, after changing sys.go")
+	tg.wantStale("p1", "stale dependency: runtime/internal", "./testgo list claims p1 is NOT stale, incorrectly, after changing sys.go")
 	restore()
 	tg.wantNotStale("p1", "", "./testgo list claims p1 is stale, incorrectly, after changing back to old release")
 	addVar(sys, 2)
 	tg.wantStale("p1", "stale dependency: runtime", "./testgo list claims p1 is NOT stale, incorrectly, after changing sys.go again")
-	tg.run("install", "-i", "p1")
+	tg.run("install", "p1")
 	tg.wantNotStale("p1", "", "./testgo list claims p1 is stale after building with new release")
 
 	// Restore to "old" release.
 	restore()
-	tg.wantStale("p1", "stale dependency: runtime/internal/sys", "./testgo list claims p1 is NOT stale, incorrectly, after restoring sys.go")
-	tg.run("install", "-i", "p1")
+	tg.wantStale("p1", "stale dependency: runtime/internal", "./testgo list claims p1 is NOT stale, incorrectly, after restoring sys.go")
+	tg.run("install", "p1")
 	tg.wantNotStale("p1", "", "./testgo list claims p1 is stale after building with old release")
 }
 
@@ -1042,29 +1070,6 @@
 	tg.grepStdout(`\* another-branch`, "not on correct default branch")
 }
 
-// Security issue. Don't disable. See golang.org/issue/22125.
-func TestAccidentalGitCheckout(t *testing.T) {
-	testenv.MustHaveExternalNetwork(t)
-	testenv.MustHaveExecPath(t, "git")
-	testenv.MustHaveExecPath(t, "svn")
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.parallel()
-	tg.tempDir("src")
-
-	tg.setenv("GOPATH", tg.path("."))
-
-	tg.runFail("get", "-u", "vcs-test.golang.org/go/test1-svn-git")
-	tg.grepStderr("src[\\\\/]vcs-test.* uses git, but parent .*src[\\\\/]vcs-test.* uses svn", "get did not fail for right reason")
-
-	if _, err := os.Stat(tg.path("SrC")); err == nil {
-		// This case only triggers on a case-insensitive file system.
-		tg.runFail("get", "-u", "vcs-test.golang.org/go/test2-svn-git/test2main")
-		tg.grepStderr("src[\\\\/]vcs-test.* uses git, but parent .*src[\\\\/]vcs-test.* uses svn", "get did not fail for right reason")
-	}
-}
-
 func TestPackageMainTestCompilerFlags(t *testing.T) {
 	tg := testgo(t)
 	defer tg.cleanup()
@@ -1445,7 +1450,7 @@
 			print(extern)
 		}`)
 	testStr := "test test test test test \n\\ "
-	var buf bytes.Buffer
+	var buf strings.Builder
 	for buf.Len() < sys.ExecArgLengthLimit+1 {
 		buf.WriteString(testStr)
 	}
@@ -1477,22 +1482,6 @@
 	tg.wantExecutable(tg.path("myerrors.test"+exeSuffix), "go test -o myerrors.test did not create myerrors.test")
 }
 
-func TestGoTestDashIDashOWritesBinary(t *testing.T) {
-	skipIfGccgo(t, "gccgo has no standard packages")
-	tooSlow(t)
-	tg := testgo(t)
-	defer tg.cleanup()
-	tg.parallel()
-	tg.makeTempdir()
-
-	// don't let test -i overwrite runtime
-	tg.wantNotStale("runtime", "", "must be non-stale before test -i")
-
-	tg.run("test", "-v", "-i", "-o", tg.path("myerrors.test"+exeSuffix), "errors")
-	tg.grepBothNot("PASS|FAIL", "test should not have run")
-	tg.wantExecutable(tg.path("myerrors.test"+exeSuffix), "go test -o myerrors.test did not create myerrors.test")
-}
-
 // Issue 4515.
 func TestInstallWithTags(t *testing.T) {
 	tooSlow(t)
@@ -1593,7 +1582,7 @@
 	tg.run("env", "PKG_CONFIG")
 	pkgConfig := strings.TrimSpace(tg.getStdout())
 	testenv.MustHaveExecPath(t, pkgConfig)
-	if out, err := exec.Command(pkgConfig, "--atleast-pkgconfig-version", "0.24").CombinedOutput(); err != nil {
+	if out, err := testenv.Command(t, pkgConfig, "--atleast-pkgconfig-version", "0.24").CombinedOutput(); err != nil {
 		t.Skipf("%s --atleast-pkgconfig-version 0.24: %v\n%s", pkgConfig, err, out)
 	}
 
@@ -1819,19 +1808,23 @@
 
 func TestGoInstallPkgdir(t *testing.T) {
 	skipIfGccgo(t, "gccgo has no standard packages")
+	if !canCgo {
+		// Only the stdlib packages that use cgo have install
+		// targets, (we're using net below) so cgo is required
+		// for the install.
+		t.Skip("skipping because cgo not enabled")
+	}
 	tooSlow(t)
 
 	tg := testgo(t)
 	tg.parallel()
+	tg.setenv("GODEBUG", "installgoroot=all")
 	defer tg.cleanup()
 	tg.makeTempdir()
 	pkg := tg.path(".")
-	tg.run("install", "-pkgdir", pkg, "sync")
-	tg.mustExist(filepath.Join(pkg, "sync.a"))
-	tg.mustNotExist(filepath.Join(pkg, "sync/atomic.a"))
-	tg.run("install", "-i", "-pkgdir", pkg, "sync")
-	tg.mustExist(filepath.Join(pkg, "sync.a"))
-	tg.mustExist(filepath.Join(pkg, "sync/atomic.a"))
+	tg.run("install", "-pkgdir", pkg, "net")
+	tg.mustExist(filepath.Join(pkg, "net.a"))
+	tg.mustNotExist(filepath.Join(pkg, "runtime/cgo.a"))
 }
 
 // For issue 14337.
@@ -2142,11 +2135,15 @@
 	case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/riscv64", "linux/s390x",
 		"android/amd64", "android/arm", "android/arm64", "android/386",
 		"freebsd/amd64",
-		"windows/386", "windows/amd64", "windows/arm":
+		"windows/386", "windows/amd64", "windows/arm", "windows/arm64":
 	case "darwin/amd64":
 	default:
 		t.Skipf("skipping test because buildmode=pie is not supported on %s", platform)
 	}
+	// Skip on alpine until https://go.dev/issues/54354 resolved.
+	if strings.HasSuffix(testenv.Builder(), "-alpine") {
+		t.Skip("skipping PIE tests on alpine; see https://go.dev/issues/54354")
+	}
 	t.Run("non-cgo", func(t *testing.T) {
 		testBuildmodePIE(t, false, true)
 	})
@@ -2283,7 +2280,7 @@
 		panic("unreachable")
 	}
 
-	out, err := exec.Command(obj).CombinedOutput()
+	out, err := testenv.Command(t, obj).CombinedOutput()
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -2300,7 +2297,7 @@
 	}
 
 	testenv.MustHaveExecPath(t, "upx")
-	out, err := exec.Command("upx", "--version").CombinedOutput()
+	out, err := testenv.Command(t, "upx", "--version").CombinedOutput()
 	if err != nil {
 		t.Fatalf("upx --version failed: %v", err)
 	}
@@ -2334,13 +2331,13 @@
 	obj := tg.path("main")
 	tg.run("build", "-o", obj, src)
 
-	out, err = exec.Command("upx", obj).CombinedOutput()
+	out, err = testenv.Command(t, "upx", obj).CombinedOutput()
 	if err != nil {
 		t.Logf("executing upx\n%s\n", out)
 		t.Fatalf("upx failed with %v", err)
 	}
 
-	out, err = exec.Command(obj).CombinedOutput()
+	out, err = testenv.Command(t, obj).CombinedOutput()
 	if err != nil {
 		t.Logf("%s", out)
 		t.Fatalf("running compressed go binary failed with error %s", err)
@@ -2350,9 +2347,11 @@
 	}
 }
 
+var gocacheverify = godebug.New("gocacheverify")
+
 func TestCacheListStale(t *testing.T) {
 	tooSlow(t)
-	if godebug.Get("gocacheverify") == "1" {
+	if gocacheverify.Value() == "1" {
 		t.Skip("GODEBUG gocacheverify")
 	}
 	tg := testgo(t)
@@ -2375,7 +2374,7 @@
 func TestCacheCoverage(t *testing.T) {
 	tooSlow(t)
 
-	if godebug.Get("gocacheverify") == "1" {
+	if gocacheverify.Value() == "1" {
 		t.Skip("GODEBUG gocacheverify")
 	}
 
@@ -2396,6 +2395,8 @@
 	defer tg.cleanup()
 	tg.parallel()
 
+	tg.wantNotStale("runtime", "", "must be non-stale to compare staleness under -toolexec")
+
 	if _, err := os.Stat("/usr/bin/time"); err != nil {
 		t.Skip(err)
 	}
@@ -2407,7 +2408,7 @@
 
 func TestIssue22531(t *testing.T) {
 	tooSlow(t)
-	if godebug.Get("gocacheverify") == "1" {
+	if gocacheverify.Value() == "1" {
 		t.Skip("GODEBUG gocacheverify")
 	}
 	tg := testgo(t)
@@ -2436,7 +2437,7 @@
 
 func TestIssue22596(t *testing.T) {
 	tooSlow(t)
-	if godebug.Get("gocacheverify") == "1" {
+	if gocacheverify.Value() == "1" {
 		t.Skip("GODEBUG gocacheverify")
 	}
 	tg := testgo(t)
@@ -2466,7 +2467,7 @@
 func TestTestCache(t *testing.T) {
 	tooSlow(t)
 
-	if godebug.Get("gocacheverify") == "1" {
+	if gocacheverify.Value() == "1" {
 		t.Skip("GODEBUG gocacheverify")
 	}
 	tg := testgo(t)
@@ -2638,16 +2639,6 @@
 	tg.run("install", "p2")
 	tg.mustExist(p2)
 	tg.mustNotExist(p1)
-
-	// don't let install -i overwrite runtime
-	tg.wantNotStale("runtime", "", "must be non-stale before install -i")
-
-	tg.run("install", "-i", "main1")
-	tg.mustExist(p1)
-	tg.must(os.Remove(p1))
-
-	tg.run("install", "-i", "p2")
-	tg.mustExist(p1)
 }
 
 // Issue 22986.
@@ -2926,35 +2917,3 @@
 	// `go version` should not fail
 	tg.run("version")
 }
-
-// A missing C compiler should not force the net package to be stale.
-// Issue 47215.
-func TestMissingCC(t *testing.T) {
-	if !canCgo {
-		t.Skip("test is only meaningful on systems with cgo")
-	}
-	cc := os.Getenv("CC")
-	if cc == "" {
-		cc = "gcc"
-	}
-	if filepath.IsAbs(cc) {
-		t.Skipf(`"CC" (%s) is an absolute path`, cc)
-	}
-	_, err := exec.LookPath(cc)
-	if err != nil {
-		t.Skipf(`"CC" (%s) not on PATH`, cc)
-	}
-
-	tg := testgo(t)
-	defer tg.cleanup()
-	netStale, _ := tg.isStale("net")
-	if netStale {
-		t.Skip(`skipping test because "net" package is currently stale`)
-	}
-
-	tg.setenv("PATH", "") // No C compiler on PATH.
-	netStale, _ = tg.isStale("net")
-	if netStale {
-		t.Error(`clearing "PATH" causes "net" to be stale`)
-	}
-}
diff --git a/src/cmd/go/go_windows_test.go b/src/cmd/go/go_windows_test.go
index 3094212..0c443eb 100644
--- a/src/cmd/go/go_windows_test.go
+++ b/src/cmd/go/go_windows_test.go
@@ -5,8 +5,8 @@
 package main_test
 
 import (
+	"internal/testenv"
 	"os"
-	"os/exec"
 	"path/filepath"
 	"strings"
 	"testing"
@@ -38,7 +38,7 @@
 
 	noVolume := file[len(filepath.VolumeName(file)):]
 	wrongPath := filepath.Join(dir, noVolume)
-	cmd := exec.Command(tg.goTool(), "build", noVolume)
+	cmd := testenv.Command(t, tg.goTool(), "build", noVolume)
 	cmd.Dir = dir
 	output, err := cmd.CombinedOutput()
 	if err == nil {
diff --git a/src/cmd/go/init_test.go b/src/cmd/go/init_test.go
index 5a5cbe5..f76425d 100644
--- a/src/cmd/go/init_test.go
+++ b/src/cmd/go/init_test.go
@@ -6,7 +6,6 @@
 
 import (
 	"internal/testenv"
-	"os/exec"
 	"sync/atomic"
 	"testing"
 )
@@ -27,7 +26,7 @@
 	b.ResetTimer()
 	b.RunParallel(func(pb *testing.PB) {
 		for pb.Next() {
-			cmd := exec.Command(gotool, "env", "GOARCH")
+			cmd := testenv.Command(b, gotool, "env", "GOARCH")
 
 			if err := cmd.Run(); err != nil {
 				b.Fatal(err)
diff --git a/src/cmd/go/internal/auth/auth.go b/src/cmd/go/internal/auth/auth.go
index fe5a89d..77edeb8 100644
--- a/src/cmd/go/internal/auth/auth.go
+++ b/src/cmd/go/internal/auth/auth.go
@@ -10,7 +10,10 @@
 // AddCredentials fills in the user's credentials for req, if any.
 // The return value reports whether any matching credentials were found.
 func AddCredentials(req *http.Request) (added bool) {
-	host := req.URL.Hostname()
+	host := req.Host
+	if host == "" {
+		host = req.URL.Hostname()
+	}
 
 	// TODO(golang.org/issue/26232): Support arbitrary user-provided credentials.
 	netrcOnce.Do(readNetrc)
diff --git a/src/cmd/go/internal/base/flag.go b/src/cmd/go/internal/base/flag.go
index 120420a..9d8d1c0 100644
--- a/src/cmd/go/internal/base/flag.go
+++ b/src/cmd/go/internal/base/flag.go
@@ -6,6 +6,7 @@
 
 import (
 	"flag"
+	"os"
 
 	"cmd/go/internal/cfg"
 	"cmd/go/internal/fsys"
@@ -57,6 +58,13 @@
 	flags.BoolVar(&cfg.BuildX, "x", false, "")
 }
 
+// AddChdirFlag adds the -C flag to the flag set.
+func AddChdirFlag(flags *flag.FlagSet) {
+	// The usage message is never printed, but it's used in chdir_test.go
+	// to identify that the -C flag is from AddChdirFlag.
+	flags.Func("C", "AddChdirFlag", os.Chdir)
+}
+
 // AddModFlag adds the -mod build flag to the flag set.
 func AddModFlag(flags *flag.FlagSet) {
 	flags.Var(explicitStringFlag{value: &cfg.BuildMod, explicit: &cfg.BuildModExplicit}, "mod", "")
diff --git a/src/cmd/go/internal/base/goflags.go b/src/cmd/go/internal/base/goflags.go
index 267006b..eced2c5 100644
--- a/src/cmd/go/internal/base/goflags.go
+++ b/src/cmd/go/internal/base/goflags.go
@@ -11,6 +11,7 @@
 	"strings"
 
 	"cmd/go/internal/cfg"
+	"cmd/internal/quoted"
 )
 
 var goflags []string // cached $GOFLAGS list; can be -x or --x form
@@ -30,19 +31,27 @@
 		return
 	}
 
-	goflags = strings.Fields(cfg.Getenv("GOFLAGS"))
-	if len(goflags) == 0 {
-		// nothing to do; avoid work on later InitGOFLAGS call
-		goflags = []string{}
-		return
-	}
-
 	// Ignore bad flag in go env and go bug, because
 	// they are what people reach for when debugging
 	// a problem, and maybe they're debugging GOFLAGS.
 	// (Both will show the GOFLAGS setting if let succeed.)
 	hideErrors := cfg.CmdName == "env" || cfg.CmdName == "bug"
 
+	var err error
+	goflags, err = quoted.Split(cfg.Getenv("GOFLAGS"))
+	if err != nil {
+		if hideErrors {
+			return
+		}
+		Fatalf("go: parsing $GOFLAGS: %v", err)
+	}
+
+	if len(goflags) == 0 {
+		// nothing to do; avoid work on later InitGOFLAGS call
+		goflags = []string{}
+		return
+	}
+
 	// Each of the words returned by strings.Fields must be its own flag.
 	// To set flag arguments use -x=value instead of -x value.
 	// For boolean flags, -x is fine instead of -x=true.
diff --git a/src/cmd/go/internal/base/path.go b/src/cmd/go/internal/base/path.go
index 4d8715e..ebe4f15 100644
--- a/src/cmd/go/internal/base/path.go
+++ b/src/cmd/go/internal/base/path.go
@@ -7,6 +7,7 @@
 import (
 	"os"
 	"path/filepath"
+	"runtime"
 	"strings"
 	"sync"
 )
@@ -54,3 +55,17 @@
 	// We don't cover tests, only the code they test.
 	return strings.HasSuffix(file, "_test.go")
 }
+
+// IsNull reports whether the path is a common name for the null device.
+// It returns true for /dev/null on Unix, or NUL (case-insensitive) on Windows.
+func IsNull(path string) bool {
+	if path == os.DevNull {
+		return true
+	}
+	if runtime.GOOS == "windows" {
+		if strings.EqualFold(path, "NUL") {
+			return true
+		}
+	}
+	return false
+}
diff --git a/src/cmd/go/internal/base/tool.go b/src/cmd/go/internal/base/tool.go
index f927016..202e314 100644
--- a/src/cmd/go/internal/base/tool.go
+++ b/src/cmd/go/internal/base/tool.go
@@ -9,28 +9,14 @@
 	"go/build"
 	"os"
 	"path/filepath"
-	"runtime"
 
 	"cmd/go/internal/cfg"
 )
 
-// Configuration for finding tool binaries.
-var (
-	ToolGOOS      = runtime.GOOS
-	ToolGOARCH    = runtime.GOARCH
-	ToolIsWindows = ToolGOOS == "windows"
-	ToolDir       = build.ToolDir
-)
-
-const ToolWindowsExtension = ".exe"
-
 // Tool returns the path to the named tool (for example, "vet").
 // If the tool cannot be found, Tool exits the process.
 func Tool(toolName string) string {
-	toolPath := filepath.Join(ToolDir, toolName)
-	if ToolIsWindows {
-		toolPath += ToolWindowsExtension
-	}
+	toolPath := filepath.Join(build.ToolDir, toolName) + cfg.ToolExeSuffix()
 	if len(cfg.BuildToolexec) > 0 {
 		return toolPath
 	}
diff --git a/src/cmd/go/internal/bug/bug.go b/src/cmd/go/internal/bug/bug.go
index 9c9e9dd..ed18136 100644
--- a/src/cmd/go/internal/bug/bug.go
+++ b/src/cmd/go/internal/bug/bug.go
@@ -22,6 +22,7 @@
 	"cmd/go/internal/cfg"
 	"cmd/go/internal/envcmd"
 	"cmd/go/internal/web"
+	"cmd/go/internal/work"
 )
 
 var CmdBug = &base.Command{
@@ -36,13 +37,16 @@
 
 func init() {
 	CmdBug.Flag.BoolVar(&cfg.BuildV, "v", false, "")
+	base.AddChdirFlag(&CmdBug.Flag)
 }
 
 func runBug(ctx context.Context, cmd *base.Command, args []string) {
 	if len(args) > 0 {
 		base.Fatalf("go: bug takes no arguments")
 	}
-	var buf bytes.Buffer
+	work.BuildInit()
+
+	var buf strings.Builder
 	buf.WriteString(bugHeader)
 	printGoVersion(&buf)
 	buf.WriteString("### Does this issue reproduce with the latest release?\n\n\n")
@@ -214,7 +218,7 @@
 	fmt.Fprintf(w, "%s: %s\n", m[1], firstLine(out))
 
 	// print another line (the one containing version string) in case of musl libc
-	if idx := bytes.IndexByte(out, '\n'); bytes.Index(out, []byte("musl")) != -1 && idx > -1 {
+	if idx := bytes.IndexByte(out, '\n'); bytes.Contains(out, []byte("musl")) && idx > -1 {
 		fmt.Fprintf(w, "%s\n", firstLine(out[idx+1:]))
 	}
 }
diff --git a/src/cmd/go/internal/cache/cache_test.go b/src/cmd/go/internal/cache/cache_test.go
index a865b97..5527d44 100644
--- a/src/cmd/go/internal/cache/cache_test.go
+++ b/src/cmd/go/internal/cache/cache_test.go
@@ -8,8 +8,10 @@
 	"bytes"
 	"encoding/binary"
 	"fmt"
+	"internal/testenv"
 	"os"
 	"path/filepath"
+	"runtime"
 	"testing"
 	"time"
 )
@@ -150,6 +152,10 @@
 }
 
 func TestCacheTrim(t *testing.T) {
+	if runtime.GOOS == "js" {
+		testenv.SkipFlaky(t, 35220)
+	}
+
 	dir, err := os.MkdirTemp("", "cachetest-")
 	if err != nil {
 		t.Fatal(err)
diff --git a/src/cmd/go/internal/cfg/cfg.go b/src/cmd/go/internal/cfg/cfg.go
index c6ddfe5..3257140 100644
--- a/src/cmd/go/internal/cfg/cfg.go
+++ b/src/cmd/go/internal/cfg/cfg.go
@@ -14,6 +14,7 @@
 	"internal/cfg"
 	"io"
 	"os"
+	"os/exec"
 	"path/filepath"
 	"runtime"
 	"strings"
@@ -42,6 +43,25 @@
 	return ""
 }
 
+// Configuration for tools installed to GOROOT/bin.
+// Normally these match runtime.GOOS and runtime.GOARCH,
+// but when testing a cross-compiled cmd/go they will
+// indicate the GOOS and GOARCH of the installed cmd/go
+// rather than the test binary.
+var (
+	installedGOOS   string
+	installedGOARCH string
+)
+
+// ToolExeSuffix returns the suffix for executables installed
+// in build.ToolDir.
+func ToolExeSuffix() string {
+	if installedGOOS == "windows" {
+		return ".exe"
+	}
+	return ""
+}
+
 // These are general "build flags" used by build and other commands.
 var (
 	BuildA                 bool     // -a flag
@@ -51,13 +71,17 @@
 	BuildMod               string                  // -mod flag
 	BuildModExplicit       bool                    // whether -mod was set explicitly
 	BuildModReason         string                  // reason -mod was set, if set by default
-	BuildI                 bool                    // -i flag
 	BuildLinkshared        bool                    // -linkshared flag
 	BuildMSan              bool                    // -msan flag
 	BuildASan              bool                    // -asan flag
+	BuildCover             bool                    // -cover flag
+	BuildCoverMode         string                  // -covermode flag
+	BuildCoverPkg          []string                // -coverpkg flag
 	BuildN                 bool                    // -n flag
 	BuildO                 string                  // -o flag
 	BuildP                 = runtime.GOMAXPROCS(0) // -p flag
+	BuildPGO               string                  // -pgo flag
+	BuildPGOFile           string                  // profile selected by -pgo flag, an absolute path (if not empty)
 	BuildPkgdir            string                  // -pkgdir flag
 	BuildRace              bool                    // -race flag
 	BuildToolexec          []string                // -toolexec flag
@@ -93,9 +117,14 @@
 	ctxt.GOOS = Goos
 	ctxt.GOARCH = Goarch
 
-	// ToolTags are based on GOEXPERIMENT, which we will parse and
-	// initialize later.
-	ctxt.ToolTags = nil
+	// Clear the GOEXPERIMENT-based tool tags, which we will recompute later.
+	var save []string
+	for _, tag := range ctxt.ToolTags {
+		if !strings.HasPrefix(tag, "goexperiment.") {
+			save = append(save, tag)
+		}
+	}
+	ctxt.ToolTags = save
 
 	// The go/build rule for whether cgo is enabled is:
 	//	1. If $CGO_ENABLED is set, respect it.
@@ -120,7 +149,21 @@
 		// go/build.Default.GOOS/GOARCH == runtime.GOOS/GOARCH.
 		// So ctxt.CgoEnabled (== go/build.Default.CgoEnabled) is correct
 		// as is and can be left unmodified.
-		// Nothing to do here.
+		//
+		// All that said, starting in Go 1.20 we layer one more rule
+		// on top of the go/build decision: if CC is unset and
+		// the default C compiler we'd look for is not in the PATH,
+		// we automatically default cgo to off.
+		// This makes go builds work automatically on systems
+		// without a C compiler installed.
+		if ctxt.CgoEnabled {
+			if os.Getenv("CC") == "" {
+				cc := DefaultCC(ctxt.GOOS, ctxt.GOARCH)
+				if _, err := exec.LookPath(cc); err != nil {
+					ctxt.CgoEnabled = false
+				}
+			}
+		}
 	}
 
 	ctxt.OpenFile = func(path string) (io.ReadCloser, error) {
@@ -136,12 +179,17 @@
 }
 
 func init() {
-	SetGOROOT(findGOROOT())
+	SetGOROOT(findGOROOT(), false)
 	BuildToolchainCompiler = func() string { return "missing-compiler" }
 	BuildToolchainLinker = func() string { return "missing-linker" }
 }
 
-func SetGOROOT(goroot string) {
+// SetGOROOT sets GOROOT and associated variables to the given values.
+//
+// If isTestGo is true, build.ToolDir is set based on the TESTGO_GOHOSTOS and
+// TESTGO_GOHOSTARCH environment variables instead of runtime.GOOS and
+// runtime.GOARCH.
+func SetGOROOT(goroot string, isTestGo bool) {
 	BuildContext.GOROOT = goroot
 
 	GOROOT = goroot
@@ -156,13 +204,33 @@
 	}
 	GOROOT_FINAL = findGOROOT_FINAL(goroot)
 
-	if runtime.Compiler != "gccgo" && goroot != "" {
-		// Note that we must use runtime.GOOS and runtime.GOARCH here,
-		// as the tool directory does not move based on environment
-		// variables. This matches the initialization of ToolDir in
-		// go/build, except for using BuildContext.GOROOT rather than
-		// runtime.GOROOT.
-		build.ToolDir = filepath.Join(goroot, "pkg/tool/"+runtime.GOOS+"_"+runtime.GOARCH)
+	installedGOOS = runtime.GOOS
+	installedGOARCH = runtime.GOARCH
+	if isTestGo {
+		if testOS := os.Getenv("TESTGO_GOHOSTOS"); testOS != "" {
+			installedGOOS = testOS
+		}
+		if testArch := os.Getenv("TESTGO_GOHOSTARCH"); testArch != "" {
+			installedGOARCH = testArch
+		}
+	}
+
+	if runtime.Compiler != "gccgo" {
+		if goroot == "" {
+			build.ToolDir = ""
+		} else {
+			// Note that we must use the installed OS and arch here: the tool
+			// directory does not move based on environment variables, and even if we
+			// are testing a cross-compiled cmd/go all of the installed packages and
+			// tools would have been built using the native compiler and linker (and
+			// would spuriously appear stale if we used a cross-compiled compiler and
+			// linker).
+			//
+			// This matches the initialization of ToolDir in go/build, except for
+			// using ctxt.GOROOT and the installed GOOS and GOARCH rather than the
+			// GOROOT, GOOS, and GOARCH reported by the runtime package.
+			build.ToolDir = filepath.Join(GOROOTpkg, "tool", installedGOOS+"_"+installedGOARCH)
+		}
 	}
 }
 
@@ -188,9 +256,12 @@
 	CleanGOEXPERIMENT = Experiment.String()
 
 	// Add build tags based on the experiments in effect.
-	for _, exp := range Experiment.Enabled() {
-		BuildContext.ToolTags = append(BuildContext.ToolTags, "goexperiment."+exp)
+	exps := Experiment.Enabled()
+	expTags := make([]string, 0, len(exps)+len(BuildContext.ToolTags))
+	for _, exp := range exps {
+		expTags = append(expTags, "goexperiment."+exp)
 	}
+	BuildContext.ToolTags = append(expTags, BuildContext.ToolTags...)
 }
 
 // An EnvVar is an environment variable Name=Value.
diff --git a/src/cmd/go/internal/cfg/zosarch.go b/src/cmd/go/internal/cfg/zosarch.go
index d77eaf8..ef70558 100644
--- a/src/cmd/go/internal/cfg/zosarch.go
+++ b/src/cmd/go/internal/cfg/zosarch.go
@@ -15,6 +15,7 @@
 	"freebsd/amd64": true,
 	"freebsd/arm": true,
 	"freebsd/arm64": true,
+	"freebsd/riscv64": true,
 	"illumos/amd64": true,
 	"ios/amd64": true,
 	"ios/arm64": true,
diff --git a/src/cmd/go/internal/clean/clean.go b/src/cmd/go/internal/clean/clean.go
index 019d364..368288f 100644
--- a/src/cmd/go/internal/clean/clean.go
+++ b/src/cmd/go/internal/clean/clean.go
@@ -11,6 +11,7 @@
 	"io"
 	"os"
 	"path/filepath"
+	"runtime"
 	"strconv"
 	"strings"
 	"time"
@@ -117,6 +118,23 @@
 }
 
 func runClean(ctx context.Context, cmd *base.Command, args []string) {
+	if len(args) > 0 {
+		cacheFlag := ""
+		switch {
+		case cleanCache:
+			cacheFlag = "-cache"
+		case cleanTestcache:
+			cacheFlag = "-testcache"
+		case cleanFuzzcache:
+			cacheFlag = "-fuzzcache"
+		case cleanModcache:
+			cacheFlag = "-modcache"
+		}
+		if cacheFlag != "" {
+			base.Fatalf("go: clean %s cannot be used with package arguments", cacheFlag)
+		}
+	}
+
 	// golang.org/issue/29925: only load packages before cleaning if
 	// either the flags and arguments explicitly imply a package,
 	// or no other target (such as a cache) was requested to be cleaned.
@@ -322,16 +340,14 @@
 			continue
 		}
 
-		if strings.HasSuffix(name, "_test.go") {
-			base := name[:len(name)-len("_test.go")]
+		if base, found := strings.CutSuffix(name, "_test.go"); found {
 			allRemove = append(allRemove, base+".test", base+".test.exe")
 		}
 
-		if strings.HasSuffix(name, ".go") {
+		if base, found := strings.CutSuffix(name, ".go"); found {
 			// TODO(adg,rsc): check that this .go file is actually
 			// in "package main", and therefore capable of building
 			// to an executable file.
-			base := name[:len(name)-len(".go")]
 			allRemove = append(allRemove, base, base+".exe")
 		}
 	}
@@ -395,7 +411,7 @@
 		return
 	}
 	// Windows does not allow deletion of a binary file while it is executing.
-	if base.ToolIsWindows {
+	if runtime.GOOS == "windows" {
 		// Remove lingering ~ file from last attempt.
 		if _, err2 := os.Stat(f + "~"); err2 == nil {
 			os.Remove(f + "~")
diff --git a/src/cmd/go/internal/cmdflag/flag.go b/src/cmd/go/internal/cmdflag/flag.go
index a634bc1..86e33ea 100644
--- a/src/cmd/go/internal/cmdflag/flag.go
+++ b/src/cmd/go/internal/cmdflag/flag.go
@@ -70,14 +70,7 @@
 		return nil, args, NonFlagError{RawArg: raw}
 	}
 
-	name := arg[1:]
-	hasValue := false
-	value := ""
-	if i := strings.Index(name, "="); i >= 0 {
-		value = name[i+1:]
-		hasValue = true
-		name = name[0:i]
-	}
+	name, value, hasValue := strings.Cut(arg[1:], "=")
 
 	f = fs.Lookup(name)
 	if f == nil {
diff --git a/src/cmd/go/internal/envcmd/env.go b/src/cmd/go/internal/envcmd/env.go
index 529351d..66ef5ce 100644
--- a/src/cmd/go/internal/envcmd/env.go
+++ b/src/cmd/go/internal/envcmd/env.go
@@ -57,6 +57,8 @@
 
 func init() {
 	CmdEnv.Run = runEnv // break init cycle
+	base.AddChdirFlag(&CmdEnv.Flag)
+	base.AddBuildFlagsNX(&CmdEnv.Flag)
 }
 
 var (
@@ -96,7 +98,7 @@
 		{Name: "GOROOT", Value: cfg.GOROOT},
 		{Name: "GOSUMDB", Value: cfg.GOSUMDB},
 		{Name: "GOTMPDIR", Value: cfg.Getenv("GOTMPDIR")},
-		{Name: "GOTOOLDIR", Value: base.ToolDir},
+		{Name: "GOTOOLDIR", Value: build.ToolDir},
 		{Name: "GOVCS", Value: cfg.GOVCS},
 		{Name: "GOVERSION", Value: runtime.Version()},
 	}
@@ -174,8 +176,13 @@
 // ExtraEnvVarsCostly returns environment variables that should not leak into child processes
 // but are costly to evaluate.
 func ExtraEnvVarsCostly() []cfg.EnvVar {
-	var b work.Builder
-	b.Init()
+	b := work.NewBuilder("")
+	defer func() {
+		if err := b.Close(); err != nil {
+			base.Fatalf("go: %v", err)
+		}
+	}()
+
 	cppflags, cflags, cxxflags, fflags, ldflags, err := b.CFlags(&load.Package{})
 	if err != nil {
 		// Should not happen - b.CFlags was given an empty package.
@@ -272,6 +279,7 @@
 		}
 	}
 	if needCostly {
+		work.BuildInit()
 		env = append(env, ExtraEnvVarsCostly()...)
 	}
 
@@ -312,11 +320,10 @@
 	}
 	add := make(map[string]string)
 	for _, arg := range args {
-		i := strings.Index(arg, "=")
-		if i < 0 {
+		key, val, found := strings.Cut(arg, "=")
+		if !found {
 			base.Fatalf("go: arguments must be KEY=VALUE: invalid argument: %s", arg)
 		}
-		key, val := arg[:i], arg[i+1:]
 		if err := checkEnvWrite(key, val); err != nil {
 			base.Fatalf("go: %v", err)
 		}
@@ -447,8 +454,8 @@
 
 func getOrigEnv(key string) string {
 	for _, v := range cfg.OrigEnv {
-		if strings.HasPrefix(v, key+"=") {
-			return strings.TrimPrefix(v, key+"=")
+		if v, found := strings.CutPrefix(v, key+"="); found {
+			return v
 		}
 	}
 	return ""
diff --git a/src/cmd/go/internal/fmtcmd/fmt.go b/src/cmd/go/internal/fmtcmd/fmt.go
index 3dc29d4..62b22f6 100644
--- a/src/cmd/go/internal/fmtcmd/fmt.go
+++ b/src/cmd/go/internal/fmtcmd/fmt.go
@@ -21,6 +21,7 @@
 
 func init() {
 	base.AddBuildFlagsNX(&CmdFmt.Flag)
+	base.AddChdirFlag(&CmdFmt.Flag)
 	base.AddModFlag(&CmdFmt.Flag)
 	base.AddModCommonFlags(&CmdFmt.Flag)
 }
@@ -97,10 +98,7 @@
 }
 
 func gofmtPath() string {
-	gofmt := "gofmt"
-	if base.ToolIsWindows {
-		gofmt += base.ToolWindowsExtension
-	}
+	gofmt := "gofmt" + cfg.ToolExeSuffix()
 
 	gofmtPath := filepath.Join(cfg.GOBIN, gofmt)
 	if _, err := os.Stat(gofmtPath); err == nil {
diff --git a/src/cmd/go/internal/fsys/fsys.go b/src/cmd/go/internal/fsys/fsys.go
index 0d7bef9..454574a 100644
--- a/src/cmd/go/internal/fsys/fsys.go
+++ b/src/cmd/go/internal/fsys/fsys.go
@@ -1,3 +1,7 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
 // Package fsys is an abstraction for reading files that
 // allows for virtual overlays on top of the files on disk.
 package fsys
@@ -8,7 +12,6 @@
 	"fmt"
 	"internal/godebug"
 	"io/fs"
-	"io/ioutil"
 	"log"
 	"os"
 	pathpkg "path"
@@ -33,27 +36,29 @@
 	traceMu.Lock()
 	defer traceMu.Unlock()
 	fmt.Fprintf(traceFile, "%d gofsystrace %s %s\n", os.Getpid(), op, path)
-	if traceStack != "" {
-		if match, _ := pathpkg.Match(traceStack, path); match {
+	if pattern := gofsystracestack.Value(); pattern != "" {
+		if match, _ := pathpkg.Match(pattern, path); match {
 			traceFile.Write(debug.Stack())
 		}
 	}
 }
 
 var (
-	doTrace    bool
-	traceStack string
-	traceFile  *os.File
-	traceMu    sync.Mutex
+	doTrace   bool
+	traceFile *os.File
+	traceMu   sync.Mutex
+
+	gofsystrace      = godebug.New("gofsystrace")
+	gofsystracelog   = godebug.New("gofsystracelog")
+	gofsystracestack = godebug.New("gofsystracestack")
 )
 
 func init() {
-	if godebug.Get("gofsystrace") != "1" {
+	if gofsystrace.Value() != "1" {
 		return
 	}
 	doTrace = true
-	traceStack = godebug.Get("gofsystracestack")
-	if f := godebug.Get("gofsystracelog"); f != "" {
+	if f := gofsystracelog.Value(); f != "" {
 		// Note: No buffering on writes to this file, so no need to worry about closing it at exit.
 		var err error
 		traceFile, err = os.OpenFile(f, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666)
@@ -95,7 +100,7 @@
 var overlay map[string]*node // path -> file or directory node
 var cwd string               // copy of base.Cwd() to avoid dependency
 
-// Canonicalize a path for looking it up in the overlay.
+// canonicalize a path for looking it up in the overlay.
 // Important: filepath.Join(cwd, path) doesn't always produce
 // the correct absolute path if path is relative, because on
 // Windows producing the correct absolute path requires making
@@ -291,21 +296,29 @@
 var errNotDir = errors.New("not a directory")
 
 // readDir reads a dir on disk, returning an error that is errNotDir if the dir is not a directory.
-// Unfortunately, the error returned by ioutil.ReadDir if dir is not a directory
+// Unfortunately, the error returned by os.ReadDir if dir is not a directory
 // can vary depending on the OS (Linux, Mac, Windows return ENOTDIR; BSD returns EINVAL).
 func readDir(dir string) ([]fs.FileInfo, error) {
-	fis, err := ioutil.ReadDir(dir)
-	if err == nil {
-		return fis, nil
-	}
-
-	if os.IsNotExist(err) {
+	entries, err := os.ReadDir(dir)
+	if err != nil {
+		if os.IsNotExist(err) {
+			return nil, err
+		}
+		if dirfi, staterr := os.Stat(dir); staterr == nil && !dirfi.IsDir() {
+			return nil, &fs.PathError{Op: "ReadDir", Path: dir, Err: errNotDir}
+		}
 		return nil, err
 	}
-	if dirfi, staterr := os.Stat(dir); staterr == nil && !dirfi.IsDir() {
-		return nil, &fs.PathError{Op: "ReadDir", Path: dir, Err: errNotDir}
+
+	fis := make([]fs.FileInfo, 0, len(entries))
+	for _, entry := range entries {
+		info, err := entry.Info()
+		if err != nil {
+			continue
+		}
+		fis = append(fis, info)
 	}
-	return nil, err
+	return fis, nil
 }
 
 // ReadDir provides a slice of fs.FileInfo entries corresponding
@@ -500,7 +513,7 @@
 	return err
 }
 
-// lstat implements a version of os.Lstat that operates on the overlay filesystem.
+// Lstat implements a version of os.Lstat that operates on the overlay filesystem.
 func Lstat(path string) (fs.FileInfo, error) {
 	Trace("Lstat", path)
 	return overlayStat(path, os.Lstat, "lstat")
diff --git a/src/cmd/go/internal/fsys/fsys_test.go b/src/cmd/go/internal/fsys/fsys_test.go
index 8cfe1d8..b441e19 100644
--- a/src/cmd/go/internal/fsys/fsys_test.go
+++ b/src/cmd/go/internal/fsys/fsys_test.go
@@ -1,3 +1,7 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
 package fsys
 
 import (
@@ -760,6 +764,42 @@
 	}
 }
 
+func TestWalkSkipAll(t *testing.T) {
+	initOverlay(t, `
+{
+	"Replace": {
+		"dir/subdir1/foo1": "dummy.txt",
+		"dir/subdir1/foo2": "dummy.txt",
+		"dir/subdir1/foo3": "dummy.txt",
+		"dir/subdir2/foo4": "dummy.txt",
+		"dir/zzlast": "dummy.txt"
+	}
+}
+-- dummy.txt --
+`)
+
+	var seen []string
+	Walk("dir", func(path string, info fs.FileInfo, err error) error {
+		seen = append(seen, filepath.ToSlash(path))
+		if info.Name() == "foo2" {
+			return filepath.SkipAll
+		}
+		return nil
+	})
+
+	wantSeen := []string{"dir", "dir/subdir1", "dir/subdir1/foo1", "dir/subdir1/foo2"}
+
+	if len(seen) != len(wantSeen) {
+		t.Errorf("paths seen in walk: got %v entries; want %v entries", len(seen), len(wantSeen))
+	}
+
+	for i := 0; i < len(seen) && i < len(wantSeen); i++ {
+		if seen[i] != wantSeen[i] {
+			t.Errorf("path %#v seen walking tree: got %q, want %q", i, seen[i], wantSeen[i])
+		}
+	}
+}
+
 func TestWalkError(t *testing.T) {
 	initOverlay(t, "{}")
 
diff --git a/src/cmd/go/internal/generate/generate.go b/src/cmd/go/internal/generate/generate.go
index 65e7148..3eda6c7 100644
--- a/src/cmd/go/internal/generate/generate.go
+++ b/src/cmd/go/internal/generate/generate.go
@@ -133,7 +133,7 @@
 
 The generator is run in the package's source directory.
 
-Go generate accepts one specific flag:
+Go generate accepts two specific flags:
 
 	-run=""
 		if non-empty, specifies a regular expression to select
@@ -141,6 +141,13 @@
 		any trailing spaces and final newline) matches the
 		expression.
 
+	-skip=""
+		if non-empty, specifies a regular expression to suppress
+		directives whose full original source text (excluding
+		any trailing spaces and final newline) matches the
+		expression. If a directive matches both the -run and
+		the -skip arguments, it is skipped.
+
 It also accepts the standard build flags including -v, -n, and -x.
 The -v flag prints the names of packages and files as they are
 processed.
@@ -156,11 +163,15 @@
 var (
 	generateRunFlag string         // generate -run flag
 	generateRunRE   *regexp.Regexp // compiled expression for -run
+
+	generateSkipFlag string         // generate -skip flag
+	generateSkipRE   *regexp.Regexp // compiled expression for -skip
 )
 
 func init() {
 	work.AddBuildFlags(CmdGenerate, work.DefaultBuildFlags)
 	CmdGenerate.Flag.StringVar(&generateRunFlag, "run", "", "")
+	CmdGenerate.Flag.StringVar(&generateSkipFlag, "skip", "", "")
 }
 
 func runGenerate(ctx context.Context, cmd *base.Command, args []string) {
@@ -171,6 +182,13 @@
 			log.Fatalf("generate: %s", err)
 		}
 	}
+	if generateSkipFlag != "" {
+		var err error
+		generateSkipRE, err = regexp.Compile(generateSkipFlag)
+		if err != nil {
+			log.Fatalf("generate: %s", err)
+		}
+	}
 
 	cfg.BuildContext.BuildTags = append(cfg.BuildContext.BuildTags, "generate")
 
@@ -291,10 +309,11 @@
 		if !isGoGenerate(buf) {
 			continue
 		}
-		if generateRunFlag != "" {
-			if !generateRunRE.Match(bytes.TrimSpace(buf)) {
-				continue
-			}
+		if generateRunFlag != "" && !generateRunRE.Match(bytes.TrimSpace(buf)) {
+			continue
+		}
+		if generateSkipFlag != "" && generateSkipRE.Match(bytes.TrimSpace(buf)) {
+			continue
 		}
 
 		g.setEnv()
diff --git a/src/cmd/go/internal/get/get.go b/src/cmd/go/internal/get/get.go
index 1bb67bc..1c1f103 100644
--- a/src/cmd/go/internal/get/get.go
+++ b/src/cmd/go/internal/get/get.go
@@ -170,7 +170,7 @@
 		mode |= load.GetTestDeps
 	}
 	for _, pkg := range downloadPaths(args) {
-		download(pkg, nil, &stk, mode)
+		download(ctx, pkg, nil, &stk, mode)
 	}
 	base.ExitIfErrors()
 
@@ -206,7 +206,6 @@
 	for _, arg := range patterns {
 		if strings.Contains(arg, "@") {
 			base.Fatalf("go: can only use path@version syntax with 'go get' and 'go install' in module-aware mode")
-			continue
 		}
 
 		// Guard against 'go get x.go', a common mistake.
@@ -251,7 +250,7 @@
 
 // download runs the download half of the get command
 // for the package or pattern named by the argument.
-func download(arg string, parent *load.Package, stk *load.ImportStack, mode int) {
+func download(ctx context.Context, arg string, parent *load.Package, stk *load.ImportStack, mode int) {
 	if mode&load.ResolveImport != 0 {
 		// Caller is responsible for expanding vendor paths.
 		panic("internal error: download mode has useVendor set")
@@ -259,9 +258,9 @@
 	load1 := func(path string, mode int) *load.Package {
 		if parent == nil {
 			mode := 0 // don't do module or vendor resolution
-			return load.LoadImport(context.TODO(), load.PackageOpts{}, path, base.Cwd(), nil, stk, nil, mode)
+			return load.LoadImport(ctx, load.PackageOpts{}, path, base.Cwd(), nil, stk, nil, mode)
 		}
-		return load.LoadImport(context.TODO(), load.PackageOpts{}, path, parent.Dir, parent, stk, nil, mode|load.ResolveModule)
+		return load.LoadImport(ctx, load.PackageOpts{}, path, parent.Dir, parent, stk, nil, mode|load.ResolveModule)
 	}
 
 	p := load1(arg, mode)
@@ -404,7 +403,7 @@
 			if i >= len(p.Imports) {
 				path = load.ResolveImportPath(p, path)
 			}
-			download(path, p, stk, 0)
+			download(ctx, path, p, stk, 0)
 		}
 
 		if isWildcard {
@@ -496,21 +495,21 @@
 		vcsCmd, repo, rootPath = rr.VCS, rr.Repo, rr.Root
 	}
 	if !blindRepo && !vcsCmd.IsSecure(repo) && security != web.Insecure {
-		return fmt.Errorf("cannot download, %v uses insecure protocol", repo)
+		return fmt.Errorf("cannot download: %v uses insecure protocol", repo)
 	}
 
 	if p.Internal.Build.SrcRoot == "" {
 		// Package not found. Put in first directory of $GOPATH.
 		list := filepath.SplitList(cfg.BuildContext.GOPATH)
 		if len(list) == 0 {
-			return fmt.Errorf("cannot download, $GOPATH not set. For more details see: 'go help gopath'")
+			return fmt.Errorf("cannot download: $GOPATH not set. For more details see: 'go help gopath'")
 		}
 		// Guard against people setting GOPATH=$GOROOT.
 		if filepath.Clean(list[0]) == filepath.Clean(cfg.GOROOT) {
-			return fmt.Errorf("cannot download, $GOPATH must not be set to $GOROOT. For more details see: 'go help gopath'")
+			return fmt.Errorf("cannot download: $GOPATH must not be set to $GOROOT. For more details see: 'go help gopath'")
 		}
 		if _, err := os.Stat(filepath.Join(list[0], "src/cmd/go/alldocs.go")); err == nil {
-			return fmt.Errorf("cannot download, %s is a GOROOT, not a GOPATH. For more details see: 'go help gopath'", list[0])
+			return fmt.Errorf("cannot download: %s is a GOROOT, not a GOPATH. For more details see: 'go help gopath'", list[0])
 		}
 		p.Internal.Build.Root = list[0]
 		p.Internal.Build.SrcRoot = filepath.Join(list[0], "src")
diff --git a/src/cmd/go/internal/help/help.go b/src/cmd/go/internal/help/help.go
index f73097a..804c910 100644
--- a/src/cmd/go/internal/help/help.go
+++ b/src/cmd/go/internal/help/help.go
@@ -7,7 +7,6 @@
 
 import (
 	"bufio"
-	"bytes"
 	"fmt"
 	"io"
 	"os"
@@ -31,7 +30,7 @@
 		fmt.Fprintln(w, "// Code generated by mkalldocs.sh; DO NOT EDIT.")
 		fmt.Fprintln(w, "// Edit the documentation in other files and rerun mkalldocs.sh to generate this one.")
 		fmt.Fprintln(w)
-		buf := new(bytes.Buffer)
+		buf := new(strings.Builder)
 		PrintUsage(buf, base.Go)
 		usage := &base.Command{Long: buf.String()}
 		cmds := []*base.Command{usage}
diff --git a/src/cmd/go/internal/help/helpdoc.go b/src/cmd/go/internal/help/helpdoc.go
index c38c403..dddb785 100644
--- a/src/cmd/go/internal/help/helpdoc.go
+++ b/src/cmd/go/internal/help/helpdoc.go
@@ -614,11 +614,18 @@
 		Valid values are hardfloat (default), softfloat.
 	GOPPC64
 		For GOARCH=ppc64{,le}, the target ISA (Instruction Set Architecture).
-		Valid values are power8 (default), power9.
+		Valid values are power8 (default), power9, power10.
 	GOWASM
 		For GOARCH=wasm, comma-separated list of experimental WebAssembly features to use.
 		Valid values are satconv, signext.
 
+Environment variables for use with code coverage:
+
+	GOCOVERDIR
+		Directory into which to write code coverage data files
+		generated by running a "go build -cover" binary.
+		Requires that GOEXPERIMENT=coverageredesign is enabled.
+
 Special-purpose environment variables:
 
 	GCCGOTOOLDIR
@@ -844,6 +851,8 @@
 	  GOOS environment variable.
 	- the target architecture, as spelled by runtime.GOARCH, set with the
 	  GOARCH environment variable.
+	- any architecture features, in the form GOARCH.feature
+	  (for example, "amd64.v2"), as detailed below.
 	- "unix", if GOOS is a Unix or Unix-like system.
 	- the compiler being used, either "gc" or "gccgo"
 	- "cgo", if the cgo command is supported (see CGO_ENABLED in
@@ -873,11 +882,45 @@
 Using GOOS=ios matches build tags and files as for GOOS=darwin
 in addition to ios tags and files.
 
-To keep a file from being considered for the build:
+The defined architecture feature build tags are:
+
+	- For GOARCH=386, GO386=387 and GO386=sse2
+	  set the 386.387 and 386.sse2 build tags, respectively.
+	- For GOARCH=amd64, GOAMD64=v1, v2, and v3
+	  correspond to the amd64.v1, amd64.v2, and amd64.v3 feature build tags.
+	- For GOARCH=arm, GOARM=5, 6, and 7
+	  correspond to the arm.5, arm.6, and arm.7 feature build tags.
+	- For GOARCH=mips or mipsle,
+	  GOMIPS=hardfloat and softfloat
+	  correspond to the mips.hardfloat and mips.softfloat
+	  (or mipsle.hardfloat and mipsle.softfloat) feature build tags.
+	- For GOARCH=mips64 or mips64le,
+	  GOMIPS64=hardfloat and softfloat
+	  correspond to the mips64.hardfloat and mips64.softfloat
+	  (or mips64le.hardfloat and mips64le.softfloat) feature build tags.
+	- For GOARCH=ppc64 or ppc64le,
+	  GOPPC64=power8, power9, and power10 correspond to the
+	  ppc64.power8, ppc64.power9, and ppc64.power10
+	  (or ppc64le.power8, ppc64le.power9, and ppc64le.power10)
+	  feature build tags.
+	- For GOARCH=wasm, GOWASM=satconv and signext
+	  correspond to the wasm.satconv and wasm.signext feature build tags.
+
+For GOARCH=amd64, arm, ppc64, and ppc64le, a particular feature level
+sets the feature build tags for all previous levels as well.
+For example, GOAMD64=v2 sets the amd64.v1 and amd64.v2 feature flags.
+This ensures that code making use of v2 features continues to compile
+when, say, GOAMD64=v4 is introduced.
+Code handling the absence of a particular feature level
+should use a negation:
+
+	//go:build !amd64.v2
+
+To keep a file from being considered for any build:
 
 	//go:build ignore
 
-(any other unsatisfied word will work as well, but "ignore" is conventional.)
+(Any other unsatisfied word will work as well, but "ignore" is conventional.)
 
 To build a file only when using cgo, and only on Linux and OS X:
 
diff --git a/src/cmd/go/internal/imports/build.go b/src/cmd/go/internal/imports/build.go
index 9571136..be308ce 100644
--- a/src/cmd/go/internal/imports/build.go
+++ b/src/cmd/go/internal/imports/build.go
@@ -20,6 +20,7 @@
 
 import (
 	"bytes"
+	"cmd/go/internal/cfg"
 	"errors"
 	"fmt"
 	"go/build/constraint"
@@ -35,8 +36,7 @@
 
 	goBuildComment = []byte("//go:build")
 
-	errGoBuildWithoutBuild = errors.New("//go:build comment without // +build comment")
-	errMultipleGoBuild     = errors.New("multiple //go:build comments")
+	errMultipleGoBuild = errors.New("multiple //go:build comments")
 )
 
 func isGoBuildComment(line []byte) bool {
@@ -201,17 +201,22 @@
 		return prefer
 	}
 
-	have := tags[name]
-	if name == "linux" {
-		have = have || tags["android"]
+	if tags[name] {
+		return true
 	}
-	if name == "solaris" {
-		have = have || tags["illumos"]
+
+	switch name {
+	case "linux":
+		return tags["android"]
+	case "solaris":
+		return tags["illumos"]
+	case "darwin":
+		return tags["ios"]
+	case "unix":
+		return unixOS[cfg.BuildContext.GOOS]
+	default:
+		return false
 	}
-	if name == "darwin" {
-		have = have || tags["ios"]
-	}
-	return have
 }
 
 // eval is like
@@ -322,6 +327,24 @@
 	"zos":       true,
 }
 
+// unixOS is the set of GOOS values matched by the "unix" build tag.
+// This is not used for filename matching.
+// This is the same list as in go/build/syslist.go and cmd/dist/build.go.
+var unixOS = map[string]bool{
+	"aix":       true,
+	"android":   true,
+	"darwin":    true,
+	"dragonfly": true,
+	"freebsd":   true,
+	"hurd":      true,
+	"illumos":   true,
+	"ios":       true,
+	"linux":     true,
+	"netbsd":    true,
+	"openbsd":   true,
+	"solaris":   true,
+}
+
 var KnownArch = map[string]bool{
 	"386":         true,
 	"amd64":       true,
diff --git a/src/cmd/go/internal/imports/tags.go b/src/cmd/go/internal/imports/tags.go
index 01b448b..d1467b8 100644
--- a/src/cmd/go/internal/imports/tags.go
+++ b/src/cmd/go/internal/imports/tags.go
@@ -36,6 +36,9 @@
 	for _, tag := range cfg.BuildContext.BuildTags {
 		tags[tag] = true
 	}
+	for _, tag := range cfg.BuildContext.ToolTags {
+		tags[tag] = true
+	}
 	for _, tag := range cfg.BuildContext.ReleaseTags {
 		tags[tag] = true
 	}
diff --git a/src/cmd/go/internal/list/list.go b/src/cmd/go/internal/list/list.go
index 5f8be6e..811d659 100644
--- a/src/cmd/go/internal/list/list.go
+++ b/src/cmd/go/internal/list/list.go
@@ -336,6 +336,9 @@
 func init() {
 	CmdList.Run = runList // break init cycle
 	work.AddBuildFlags(CmdList, work.DefaultBuildFlags)
+	if cfg.Experiment != nil && cfg.Experiment.CoverageRedesign {
+		work.AddCoverFlags(CmdList, nil)
+	}
 	CmdList.Flag.Var(&listJsonFields, "json", "")
 }
 
@@ -409,7 +412,7 @@
 func runList(ctx context.Context, cmd *base.Command, args []string) {
 	modload.InitWorkfile()
 
-	if *listFmt != "" && listJson == true {
+	if *listFmt != "" && listJson {
 		base.Fatalf("go list -f cannot be used with -json")
 	}
 	if *listReuse != "" && !*listM {
@@ -592,7 +595,7 @@
 	pkgOpts := load.PackageOpts{
 		IgnoreImports:   *listFind,
 		ModResolveTests: *listTest,
-		LoadVCS:         true,
+		AutoVCS:         true,
 		// SuppressDeps is set if the user opts to explicitly ask for the json fields they
 		// need, don't ask for Deps or DepsErrors. It's not set when using a template string,
 		// even if *listFmt doesn't contain .Deps because Deps are used to find import cycles
@@ -689,8 +692,16 @@
 	// Do we need to run a build to gather information?
 	needStale := (listJson && listJsonFields.needAny("Stale", "StaleReason")) || strings.Contains(*listFmt, ".Stale")
 	if needStale || *listExport || *listCompiled {
-		var b work.Builder
-		b.Init()
+		b := work.NewBuilder("")
+		if *listE {
+			b.AllowErrors = true
+		}
+		defer func() {
+			if err := b.Close(); err != nil {
+				base.Fatalf("go: %v", err)
+			}
+		}()
+
 		b.IsCmdList = true
 		b.NeedExport = *listExport
 		b.NeedCompiledGoFiles = *listCompiled
diff --git a/src/cmd/go/internal/load/pkg.go b/src/cmd/go/internal/load/pkg.go
index 046f508..56a4e5e 100644
--- a/src/cmd/go/internal/load/pkg.go
+++ b/src/cmd/go/internal/load/pkg.go
@@ -8,16 +8,17 @@
 import (
 	"bytes"
 	"context"
+	"crypto/sha256"
 	"encoding/json"
 	"errors"
 	"fmt"
 	"go/build"
 	"go/scanner"
 	"go/token"
+	"internal/platform"
 	"io/fs"
 	"os"
 	"os/exec"
-	"path"
 	pathpkg "path"
 	"path/filepath"
 	"runtime"
@@ -42,7 +43,7 @@
 	"cmd/go/internal/str"
 	"cmd/go/internal/trace"
 	"cmd/go/internal/vcs"
-	"cmd/internal/sys"
+	"cmd/internal/pkgpattern"
 
 	"golang.org/x/mod/modfile"
 	"golang.org/x/mod/module"
@@ -222,6 +223,7 @@
 	FuzzInstrument    bool                 // package should be instrumented for fuzzing
 	CoverMode         string               // preprocess Go source files with the coverage tool in this mode
 	CoverVars         map[string]*CoverVar // variables created by coverage analysis
+	CoverageCfg       string               // coverage info config file path (passed to compiler)
 	OmitDebug         bool                 // tell linker not to write debug information
 	GobinSubdir       bool                 // install target would be subdir of GOBIN
 	BuildInfo         string               // add this info to package main
@@ -372,7 +374,9 @@
 		old := pp.PkgTargetRoot
 		pp.PkgRoot = cfg.BuildPkgdir
 		pp.PkgTargetRoot = cfg.BuildPkgdir
-		pp.PkgObj = filepath.Join(cfg.BuildPkgdir, strings.TrimPrefix(pp.PkgObj, old))
+		if pp.PkgObj != "" {
+			pp.PkgObj = filepath.Join(cfg.BuildPkgdir, strings.TrimPrefix(pp.PkgObj, old))
+		}
 	}
 
 	p.Dir = pp.Dir
@@ -874,8 +878,11 @@
 		var data packageData
 		if r.dir != "" {
 			var buildMode build.ImportMode
+			buildContext := cfg.BuildContext
 			if !cfg.ModulesEnabled {
 				buildMode = build.ImportComment
+			} else {
+				buildContext.GOPATH = "" // Clear GOPATH so packages are imported as pure module packages
 			}
 			modroot := modload.PackageModRoot(ctx, r.path)
 			if modroot == "" && str.HasPathPrefix(r.dir, cfg.GOROOTsrc) {
@@ -892,7 +899,7 @@
 					base.Fatalf("go: %v", err)
 				}
 			}
-			data.p, data.err = cfg.BuildContext.ImportDir(r.dir, buildMode)
+			data.p, data.err = buildContext.ImportDir(r.dir, buildMode)
 		Happy:
 			if cfg.ModulesEnabled {
 				// Override data.p.Root, since ImportDir sets it to $GOPATH, if
@@ -1776,9 +1783,9 @@
 			setError(e)
 			return
 		}
-		elem := p.DefaultExecName()
-		full := cfg.BuildContext.GOOS + "_" + cfg.BuildContext.GOARCH + "/" + elem
-		if cfg.BuildContext.GOOS != base.ToolGOOS || cfg.BuildContext.GOARCH != base.ToolGOARCH {
+		elem := p.DefaultExecName() + cfg.ExeSuffix
+		full := cfg.BuildContext.GOOS + "_" + cfg.BuildContext.GOARCH + string(filepath.Separator) + elem
+		if cfg.BuildContext.GOOS != runtime.GOOS || cfg.BuildContext.GOARCH != runtime.GOARCH {
 			// Install cross-compiled binaries to subdirectories of bin.
 			elem = full
 		}
@@ -1788,7 +1795,7 @@
 		if p.Internal.Build.BinDir != "" {
 			// Install to GOBIN or bin of GOPATH entry.
 			p.Target = filepath.Join(p.Internal.Build.BinDir, elem)
-			if !p.Goroot && strings.Contains(elem, "/") && cfg.GOBIN != "" {
+			if !p.Goroot && strings.Contains(elem, string(filepath.Separator)) && cfg.GOBIN != "" {
 				// Do not create $GOBIN/goos_goarch/elem.
 				p.Target = ""
 				p.Internal.GobinSubdir = true
@@ -1798,25 +1805,33 @@
 			// This is for 'go tool'.
 			// Override all the usual logic and force it into the tool directory.
 			if cfg.BuildToolchainName == "gccgo" {
-				p.Target = filepath.Join(base.ToolDir, elem)
+				p.Target = filepath.Join(build.ToolDir, elem)
 			} else {
 				p.Target = filepath.Join(cfg.GOROOTpkg, "tool", full)
 			}
 		}
-		if p.Target != "" && cfg.BuildContext.GOOS == "windows" {
-			p.Target += ".exe"
-		}
 	} else if p.Internal.Local {
 		// Local import turned into absolute path.
 		// No permanent install target.
 		p.Target = ""
+	} else if p.Standard && cfg.BuildContext.Compiler == "gccgo" {
+		// gccgo has a preinstalled standard library that cmd/go cannot rebuild.
+		p.Target = ""
 	} else {
 		p.Target = p.Internal.Build.PkgObj
-		if cfg.BuildLinkshared && p.Target != "" {
-			// TODO(bcmills): The reliance on p.Target implies that -linkshared does
-			// not work for any package that lacks a Target — such as a non-main
+		if cfg.BuildBuildmode == "shared" && p.Internal.Build.PkgTargetRoot != "" {
+			// TODO(matloob): This shouldn't be necessary, but the misc/cgo/testshared
+			// test fails without Target set for this condition. Figure out why and
+			// fix it.
+			p.Target = filepath.Join(p.Internal.Build.PkgTargetRoot, p.ImportPath+".a")
+		}
+		if cfg.BuildLinkshared && p.Internal.Build.PkgTargetRoot != "" {
+			// TODO(bcmills): The reliance on PkgTargetRoot implies that -linkshared does
+			// not work for any package that lacks a PkgTargetRoot — such as a non-main
 			// package in module mode. We should probably fix that.
-			shlibnamefile := p.Target[:len(p.Target)-2] + ".shlibname"
+			targetPrefix := filepath.Join(p.Internal.Build.PkgTargetRoot, p.ImportPath)
+			p.Target = targetPrefix + ".a"
+			shlibnamefile := targetPrefix + ".shlibname"
 			shlib, err := os.ReadFile(shlibnamefile)
 			if err != nil && !os.IsNotExist(err) {
 				base.Fatalf("reading shlibname: %v", err)
@@ -1974,12 +1989,7 @@
 		// Consider starting this as a background goroutine and retrieving the result
 		// asynchronously when we're actually ready to build the package, or when we
 		// actually need to evaluate whether the package's metadata is stale.
-		p.setBuildInfo(opts.LoadVCS)
-	}
-
-	// unsafe is a fake package.
-	if p.Standard && (p.ImportPath == "unsafe" || cfg.BuildContext.Compiler == "gccgo") {
-		p.Target = ""
+		p.setBuildInfo(opts.AutoVCS)
 	}
 
 	// If cgo is not enabled, ignore cgo supporting sources
@@ -2071,7 +2081,7 @@
 			glob = pattern[len("all:"):]
 		}
 		// Check pattern is valid for //go:embed.
-		if _, err := path.Match(glob, ""); err != nil || !validEmbedPattern(glob) {
+		if _, err := pathpkg.Match(glob, ""); err != nil || !validEmbedPattern(glob) {
 			return nil, nil, fmt.Errorf("invalid pattern syntax")
 		}
 
@@ -2264,7 +2274,7 @@
 //
 // Note that the GoVersion field is not set here to avoid encoding it twice.
 // It is stored separately in the binary, mostly for historical reasons.
-func (p *Package) setBuildInfo(includeVCS bool) {
+func (p *Package) setBuildInfo(autoVCS bool) {
 	setPkgErrorf := func(format string, args ...any) {
 		if p.Error == nil {
 			p.Error = &PackageError{Err: fmt.Errorf(format, args...)}
@@ -2346,6 +2356,15 @@
 	if BuildAsmflags.present {
 		appendSetting("-asmflags", BuildAsmflags.String())
 	}
+	buildmode := cfg.BuildBuildmode
+	if buildmode == "default" {
+		if p.Name == "main" {
+			buildmode = "exe"
+		} else {
+			buildmode = "archive"
+		}
+	}
+	appendSetting("-buildmode", buildmode)
 	appendSetting("-compiler", cfg.BuildContext.Compiler)
 	if gccgoflags := BuildGccgoflags.String(); gccgoflags != "" && cfg.BuildContext.Compiler == "gccgo" {
 		appendSetting("-gccgoflags", gccgoflags)
@@ -2366,6 +2385,13 @@
 			appendSetting("-ldflags", ldflags)
 		}
 	}
+	if cfg.BuildPGOFile != "" {
+		if cfg.BuildTrimpath {
+			appendSetting("-pgo", filepath.Base(cfg.BuildPGOFile))
+		} else {
+			appendSetting("-pgo", cfg.BuildPGOFile)
+		}
+	}
 	if cfg.BuildMSan {
 		appendSetting("-msan", "true")
 	}
@@ -2420,7 +2446,25 @@
 	var vcsCmd *vcs.Cmd
 	var err error
 	const allowNesting = true
-	if includeVCS && cfg.BuildBuildvcs != "false" && p.Module != nil && p.Module.Version == "" && !p.Standard && !p.IsTestOnly() {
+
+	wantVCS := false
+	switch cfg.BuildBuildvcs {
+	case "true":
+		wantVCS = true // Include VCS metadata even for tests if requested explicitly; see https://go.dev/issue/52648.
+	case "auto":
+		wantVCS = autoVCS && !p.IsTestOnly()
+	case "false":
+	default:
+		panic(fmt.Sprintf("unexpected value for cfg.BuildBuildvcs: %q", cfg.BuildBuildvcs))
+	}
+
+	if wantVCS && p.Module != nil && p.Module.Version == "" && !p.Standard {
+		if p.Module.Path == "bootstrap" && cfg.GOROOT == os.Getenv("GOROOT_BOOTSTRAP") {
+			// During bootstrapping, the bootstrap toolchain is built in module
+			// "bootstrap" (instead of "std"), with GOROOT set to GOROOT_BOOTSTRAP
+			// (so the bootstrap toolchain packages don't even appear to be in GOROOT).
+			goto omitVCS
+		}
 		repoDir, vcsCmd, err = vcs.FromDir(base.Cwd(), "", allowNesting)
 		if err != nil && !errors.Is(err, os.ErrNotExist) {
 			setVCSError(err)
@@ -2543,6 +2587,10 @@
 	if cfg.BuildASan {
 		deps = append(deps, "runtime/asan")
 	}
+	// Building for coverage forces an import of runtime/coverage.
+	if cfg.BuildCover && cfg.Experiment.CoverageRedesign {
+		deps = append(deps, "runtime/coverage")
+	}
 
 	return deps
 }
@@ -2571,7 +2619,7 @@
 	// -ldflags=-linkmode=external. External linking mode forces
 	// an import of runtime/cgo.
 	// If there are multiple -linkmode options, the last one wins.
-	pieCgo := cfg.BuildBuildmode == "pie" && !sys.InternalLinkPIESupported(cfg.BuildContext.GOOS, cfg.BuildContext.GOARCH)
+	pieCgo := cfg.BuildBuildmode == "pie" && !platform.InternalLinkPIESupported(cfg.BuildContext.GOOS, cfg.BuildContext.GOARCH)
 	linkmodeExternal := false
 	if p != nil {
 		ldflags := BuildLdflags.For(p)
@@ -2724,8 +2772,9 @@
 	// may be printed for non-literal arguments that match no main packages.
 	MainOnly bool
 
-	// LoadVCS controls whether we also load version-control metadata for main packages.
-	LoadVCS bool
+	// AutoVCS controls whether we also load version-control metadata for main packages
+	// when -buildvcs=auto (the default).
+	AutoVCS bool
 
 	// SuppressDeps is true if the caller does not need Deps and DepsErrors to be populated
 	// on the package. TestPackagesAndErrors examines the  Deps field to determine if the test
@@ -2758,7 +2807,9 @@
 			// We need to test whether the path is an actual Go file and not a
 			// package path or pattern ending in '.go' (see golang.org/issue/34653).
 			if fi, err := fsys.Stat(p); err == nil && !fi.IsDir() {
-				return []*Package{GoFilesPackage(ctx, opts, patterns)}
+				pkgs := []*Package{GoFilesPackage(ctx, opts, patterns)}
+				setPGOProfilePath(pkgs)
+				return pkgs
 			}
 		}
 	}
@@ -2837,9 +2888,60 @@
 	// their dependencies).
 	setToolFlags(pkgs...)
 
+	setPGOProfilePath(pkgs)
+
 	return pkgs
 }
 
+// setPGOProfilePath sets cfg.BuildPGOFile to the PGO profile path.
+// In -pgo=auto mode, it finds the default PGO profile.
+func setPGOProfilePath(pkgs []*Package) {
+	switch cfg.BuildPGO {
+	case "":
+		fallthrough // default to "off"
+	case "off":
+		return
+
+	case "auto":
+		// Locate PGO profile from the main package.
+
+		setError := func(p *Package) {
+			if p.Error == nil {
+				p.Error = &PackageError{Err: errors.New("-pgo=auto requires exactly one main package")}
+			}
+		}
+
+		var mainpkg *Package
+		for _, p := range pkgs {
+			if p.Name == "main" {
+				if mainpkg != nil {
+					setError(p)
+					setError(mainpkg)
+					continue
+				}
+				mainpkg = p
+			}
+		}
+		if mainpkg == nil {
+			// No main package, no default.pgo to look for.
+			return
+		}
+		file := filepath.Join(mainpkg.Dir, "default.pgo")
+		if fi, err := os.Stat(file); err == nil && !fi.IsDir() {
+			cfg.BuildPGOFile = file
+		}
+
+	default:
+		// Profile specified from the command line.
+		// Make it absolute path, as the compiler runs on various directories.
+		if p, err := filepath.Abs(cfg.BuildPGO); err != nil {
+			base.Fatalf("fail to get absolute path of PGO file %s: %v", cfg.BuildPGO, err)
+		} else {
+			cfg.BuildPGOFile = p
+		}
+	}
+}
+
 // CheckPackageErrors prints errors encountered loading pkgs and their
 // dependencies, then exits with a non-zero status if any errors were found.
 func CheckPackageErrors(pkgs []*Package) {
@@ -2902,7 +3004,7 @@
 
 	var mains []*Package
 	for _, pkg := range pkgs {
-		if pkg.Name == "main" {
+		if pkg.Name == "main" || (pkg.Name == "" && pkg.Error != nil) {
 			treatAsMain[pkg.ImportPath] = true
 			mains = append(mains, pkg)
 			continue
@@ -3088,10 +3190,10 @@
 	}
 	patterns := make([]string, len(args))
 	for i, arg := range args {
-		if !strings.HasSuffix(arg, "@"+version) {
+		p, found := strings.CutSuffix(arg, "@"+version)
+		if !found {
 			return nil, fmt.Errorf("%s: all arguments must refer to packages in the same module at the same version (@%s)", arg, version)
 		}
-		p := arg[:len(arg)-len(version)-1]
 		switch {
 		case build.IsLocalImport(p):
 			return nil, fmt.Errorf("%s: argument must be a package path, not a relative path", arg)
@@ -3099,7 +3201,7 @@
 			return nil, fmt.Errorf("%s: argument must be a package path, not an absolute path", arg)
 		case search.IsMetaPackage(p):
 			return nil, fmt.Errorf("%s: argument must be a package path, not a meta-package", arg)
-		case path.Clean(p) != p:
+		case pathpkg.Clean(p) != p:
 			return nil, fmt.Errorf("%s: argument must be a clean package path", arg)
 		case !strings.Contains(p, "...") && search.IsStandardImportPath(p) && modindex.IsStandardPackage(cfg.GOROOT, cfg.BuildContext.Compiler, p):
 			return nil, fmt.Errorf("%s: argument must not be a package in the standard library", arg)
@@ -3174,8 +3276,198 @@
 	matchers := make([]func(string) bool, len(patterns))
 	for i, p := range patterns {
 		if strings.Contains(p, "...") {
-			matchers[i] = search.MatchPattern(p)
+			matchers[i] = pkgpattern.MatchPattern(p)
 		}
 	}
 	return pkgs, nil
 }
+
+// EnsureImport ensures that package p imports the named package.
+func EnsureImport(p *Package, pkg string) {
+	for _, d := range p.Internal.Imports {
+		if d.Name == pkg {
+			return
+		}
+	}
+
+	p1 := LoadImportWithFlags(pkg, p.Dir, p, &ImportStack{}, nil, 0)
+	if p1.Error != nil {
+		base.Fatalf("load %s: %v", pkg, p1.Error)
+	}
+
+	p.Internal.Imports = append(p.Internal.Imports, p1)
+}
+
+// PrepareForCoverageBuild is a helper invoked for "go install
+// -cover", "go run -cover", and "go build -cover" (but not used by
+// "go test -cover"). It walks through the packages being built (and
+// dependencies) and marks them for coverage instrumentation when
+// appropriate, and possibly adding additional deps where needed.
+func PrepareForCoverageBuild(pkgs []*Package) {
+	var match []func(*Package) bool
+
+	matchMainModAndCommandLine := func(p *Package) bool {
+		// note that p.Standard implies p.Module == nil below.
+		return p.Internal.CmdlineFiles || p.Internal.CmdlinePkg || (p.Module != nil && p.Module.Main)
+	}
+
+	if len(cfg.BuildCoverPkg) != 0 {
+		// If -coverpkg has been specified, then we instrument only
+		// the specific packages selected by the user-specified pattern(s).
+		match = make([]func(*Package) bool, len(cfg.BuildCoverPkg))
+		for i := range cfg.BuildCoverPkg {
+			match[i] = MatchPackage(cfg.BuildCoverPkg[i], base.Cwd())
+		}
+	} else {
+		// Without -coverpkg, instrument only packages in the main module
+		// (if any), as well as packages/files specifically named on the
+		// command line.
+		match = []func(*Package) bool{matchMainModAndCommandLine}
+	}
+
+	// Visit the packages being built or installed, along with all of
+	// their dependencies, and mark them to be instrumented, taking
+	// into account the matchers we've set up in the sequence above.
+	SelectCoverPackages(PackageList(pkgs), match, "build")
+}
+
+func SelectCoverPackages(roots []*Package, match []func(*Package) bool, op string) []*Package {
+	var warntag string
+	var includeMain bool
+	switch op {
+	case "build":
+		warntag = "built"
+		includeMain = true
+	case "test":
+		warntag = "tested"
+	default:
+		panic("internal error, bad mode passed to SelectCoverPackages")
+	}
+
+	covered := []*Package{}
+	matched := make([]bool, len(match))
+	for _, p := range roots {
+		haveMatch := false
+		for i := range match {
+			if match[i](p) {
+				matched[i] = true
+				haveMatch = true
+			}
+		}
+		if !haveMatch {
+			continue
+		}
+
+		// There is nothing to cover in package unsafe; it comes from
+		// the compiler.
+		if p.ImportPath == "unsafe" {
+			continue
+		}
+
+		// A package which only has test files can't be imported as a
+		// dependency, and at the moment we don't try to instrument it
+		// for coverage. There isn't any technical reason why
+		// *_test.go files couldn't be instrumented, but it probably
+		// doesn't make much sense to lump together coverage metrics
+		// (ex: percent stmts covered) of *_test.go files with
+		// non-test Go code.
+		if len(p.GoFiles)+len(p.CgoFiles) == 0 {
+			continue
+		}
+
+		// Silently ignore attempts to run coverage on sync/atomic
+		// and/or runtime/internal/atomic when using atomic coverage
+		// mode. Atomic coverage mode uses sync/atomic, so we can't
+		// also do coverage on it.
+		if cfg.BuildCoverMode == "atomic" && p.Standard &&
+			(p.ImportPath == "sync/atomic" || p.ImportPath == "runtime/internal/atomic") {
+			continue
+		}
+
+		// If using the race detector, silently ignore attempts to run
+		// coverage on the runtime packages. It will cause the race
+		// detector to be invoked before it has been initialized. Note
+		// the use of "regonly" instead of just ignoring the package
+		// completely-- we do this due to the requirements of the
+		// package ID numbering scheme. See the comment in
+		// $GOROOT/src/internal/coverage/pkid.go dealing with
+		// hard-coding of runtime package IDs.
+		cmode := cfg.BuildCoverMode
+		if cfg.BuildRace && p.Standard && (p.ImportPath == "runtime" || strings.HasPrefix(p.ImportPath, "runtime/internal")) {
+			cmode = "regonly"
+		}
+
+		// If -coverpkg is in effect and for some reason we don't want
+		// coverage data for the main package, make sure that we at
+		// least process it for registration hooks.
+		if includeMain && p.Name == "main" && !haveMatch {
+			haveMatch = true
+			cmode = "regonly"
+		}
+
+		// Mark package for instrumentation.
+		p.Internal.CoverMode = cmode
+		covered = append(covered, p)
+
+		// Force import of sync/atomic into package if atomic mode.
+		if cfg.BuildCoverMode == "atomic" {
+			EnsureImport(p, "sync/atomic")
+		}
+
+		// Generate covervars if using legacy coverage design.
+		if !cfg.Experiment.CoverageRedesign {
+			var coverFiles []string
+			coverFiles = append(coverFiles, p.GoFiles...)
+			coverFiles = append(coverFiles, p.CgoFiles...)
+			p.Internal.CoverVars = DeclareCoverVars(p, coverFiles...)
+		}
+	}
+
+	// Warn about -coverpkg arguments that are not actually used.
+	for i := range cfg.BuildCoverPkg {
+		if !matched[i] {
+			fmt.Fprintf(os.Stderr, "warning: no packages being %s depend on matches for pattern %s\n", warntag, cfg.BuildCoverPkg[i])
+		}
+	}
+
+	return covered
+}
+
+// declareCoverVars attaches the required cover variables names
+// to the files, to be used when annotating the files. This
+// function only called when using legacy coverage test/build
+// (e.g. GOEXPERIMENT=coverageredesign is off).
+func DeclareCoverVars(p *Package, files ...string) map[string]*CoverVar {
+	coverVars := make(map[string]*CoverVar)
+	coverIndex := 0
+	// We create the cover counters as new top-level variables in the package.
+	// We need to avoid collisions with user variables (GoCover_0 is unlikely but still)
+	// and more importantly with dot imports of other covered packages,
+	// so we append 12 hex digits from the SHA-256 of the import path.
+	// The point is only to avoid accidents, not to defeat users determined to
+	// break things.
+	sum := sha256.Sum256([]byte(p.ImportPath))
+	h := fmt.Sprintf("%x", sum[:6])
+	for _, file := range files {
+		if base.IsTestFile(file) {
+			continue
+		}
+		// For a package that is "local" (imported via ./ import or command line, outside GOPATH),
+		// we record the full path to the file name.
+		// Otherwise we record the import path, then a forward slash, then the file name.
+		// This makes profiles within GOPATH file system-independent.
+		// These names appear in the cmd/cover HTML interface.
+		var longFile string
+		if p.Internal.Local {
+			longFile = filepath.Join(p.Dir, file)
+		} else {
+			longFile = pathpkg.Join(p.ImportPath, file)
+		}
+		coverVars[file] = &CoverVar{
+			File: longFile,
+			Var:  fmt.Sprintf("GoCover_%d_%x", coverIndex, h),
+		}
+		coverIndex++
+	}
+	return coverVars
+}
diff --git a/src/cmd/go/internal/load/pkg_test.go b/src/cmd/go/internal/load/pkg_test.go
index 1e59fb9..3bcddee 100644
--- a/src/cmd/go/internal/load/pkg_test.go
+++ b/src/cmd/go/internal/load/pkg_test.go
@@ -1,3 +1,7 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
 package load
 
 import (
diff --git a/src/cmd/go/internal/load/search.go b/src/cmd/go/internal/load/search.go
index cf09c7b..565996a 100644
--- a/src/cmd/go/internal/load/search.go
+++ b/src/cmd/go/internal/load/search.go
@@ -9,6 +9,7 @@
 	"strings"
 
 	"cmd/go/internal/search"
+	"cmd/internal/pkgpattern"
 )
 
 // MatchPackage(pattern, cwd)(p) reports whether package p matches pattern in the working directory cwd.
@@ -29,7 +30,7 @@
 		if pattern == "" {
 			return func(p *Package) bool { return p.Dir == dir }
 		}
-		matchPath := search.MatchPattern(pattern)
+		matchPath := pkgpattern.MatchPattern(pattern)
 		return func(p *Package) bool {
 			// Compute relative path to dir and see if it matches the pattern.
 			rel, err := filepath.Rel(dir, p.Dir)
@@ -50,7 +51,7 @@
 	case pattern == "cmd":
 		return func(p *Package) bool { return p.Standard && strings.HasPrefix(p.ImportPath, "cmd/") }
 	default:
-		matchPath := search.MatchPattern(pattern)
+		matchPath := pkgpattern.MatchPattern(pattern)
 		return func(p *Package) bool { return matchPath(p.ImportPath) }
 	}
 }
diff --git a/src/cmd/go/internal/load/test.go b/src/cmd/go/internal/load/test.go
index 3780f35..0c20a23 100644
--- a/src/cmd/go/internal/load/test.go
+++ b/src/cmd/go/internal/load/test.go
@@ -21,6 +21,7 @@
 	"unicode"
 	"unicode/utf8"
 
+	"cmd/go/internal/cfg"
 	"cmd/go/internal/fsys"
 	"cmd/go/internal/str"
 	"cmd/go/internal/trace"
@@ -35,12 +36,11 @@
 }
 
 type TestCover struct {
-	Mode     string
-	Local    bool
-	Pkgs     []*Package
-	Paths    []string
-	Vars     []coverInfo
-	DeclVars func(*Package, ...string) map[string]*CoverVar
+	Mode  string
+	Local bool
+	Pkgs  []*Package
+	Paths []string
+	Vars  []coverInfo
 }
 
 // TestPackagesFor is like TestPackagesAndErrors but it returns
@@ -287,7 +287,7 @@
 	}
 	stk.Pop()
 
-	if cover != nil && cover.Pkgs != nil {
+	if cover != nil && cover.Pkgs != nil && !cfg.Experiment.CoverageRedesign {
 		// Add imports, but avoid duplicates.
 		seen := map[*Package]bool{p: true, ptest: true}
 		for _, p1 := range pmain.Internal.Imports {
@@ -346,21 +346,36 @@
 	// Replace pmain's transitive dependencies with test copies, as necessary.
 	recompileForTest(pmain, p, ptest, pxtest)
 
-	// Should we apply coverage analysis locally,
-	// only for this package and only for this test?
-	// Yes, if -cover is on but -coverpkg has not specified
-	// a list of packages for global coverage.
-	if cover != nil && cover.Local {
-		ptest.Internal.CoverMode = cover.Mode
-		var coverFiles []string
-		coverFiles = append(coverFiles, ptest.GoFiles...)
-		coverFiles = append(coverFiles, ptest.CgoFiles...)
-		ptest.Internal.CoverVars = cover.DeclVars(ptest, coverFiles...)
-	}
+	if cover != nil {
+		if cfg.Experiment.CoverageRedesign {
+			// Here ptest needs to inherit the proper coverage mode (since
+			// it contains p's Go files), whereas pmain contains only
+			// test harness code (don't want to instrument it, and
+			// we don't want coverage hooks in the pkg init).
+			ptest.Internal.CoverMode = p.Internal.CoverMode
+			pmain.Internal.CoverMode = "testmain"
+		}
+		// Should we apply coverage analysis locally, only for this
+		// package and only for this test? Yes, if -cover is on but
+		// -coverpkg has not specified a list of packages for global
+		// coverage.
+		if cover.Local {
+			ptest.Internal.CoverMode = cover.Mode
 
-	for _, cp := range pmain.Internal.Imports {
-		if len(cp.Internal.CoverVars) > 0 {
-			t.Cover.Vars = append(t.Cover.Vars, coverInfo{cp, cp.Internal.CoverVars})
+			if !cfg.Experiment.CoverageRedesign {
+				var coverFiles []string
+				coverFiles = append(coverFiles, ptest.GoFiles...)
+				coverFiles = append(coverFiles, ptest.CgoFiles...)
+				ptest.Internal.CoverVars = DeclareCoverVars(ptest, coverFiles...)
+			}
+		}
+
+		if !cfg.Experiment.CoverageRedesign {
+			for _, cp := range pmain.Internal.Imports {
+				if len(cp.Internal.CoverVars) > 0 {
+					t.Cover.Vars = append(t.Cover.Vars, coverInfo{cp, cp.Internal.CoverVars})
+				}
+			}
 		}
 	}
 
@@ -546,7 +561,11 @@
 // formatTestmain returns the content of the _testmain.go file for t.
 func formatTestmain(t *testFuncs) ([]byte, error) {
 	var buf bytes.Buffer
-	if err := testmainTmpl.Execute(&buf, t); err != nil {
+	tmpl := testmainTmpl
+	if cfg.Experiment.CoverageRedesign {
+		tmpl = testmainTmplNewCoverage
+	}
+	if err := tmpl.Execute(&buf, t); err != nil {
 		return nil, err
 	}
 	return buf.Bytes(), nil
@@ -611,7 +630,7 @@
 		return err
 	}
 	defer src.Close()
-	f, err := parser.ParseFile(testFileSet, filename, src, parser.ParseComments)
+	f, err := parser.ParseFile(testFileSet, filename, src, parser.ParseComments|parser.SkipObjectResolution)
 	if err != nil {
 		return err
 	}
@@ -804,3 +823,99 @@
 }
 
 `)
+
+var testmainTmplNewCoverage = lazytemplate.New("main", `
+// Code generated by 'go test'. DO NOT EDIT.
+
+package main
+
+import (
+	"os"
+{{if .Cover}}
+	_ "unsafe"
+{{end}}
+{{if .TestMain}}
+	"reflect"
+{{end}}
+	"testing"
+	"testing/internal/testdeps"
+
+{{if .ImportTest}}
+	{{if .NeedTest}}_test{{else}}_{{end}} {{.Package.ImportPath | printf "%q"}}
+{{end}}
+{{if .ImportXtest}}
+	{{if .NeedXtest}}_xtest{{else}}_{{end}} {{.Package.ImportPath | printf "%s_test" | printf "%q"}}
+{{end}}
+)
+
+var tests = []testing.InternalTest{
+{{range .Tests}}
+	{"{{.Name}}", {{.Package}}.{{.Name}}},
+{{end}}
+}
+
+var benchmarks = []testing.InternalBenchmark{
+{{range .Benchmarks}}
+	{"{{.Name}}", {{.Package}}.{{.Name}}},
+{{end}}
+}
+
+var fuzzTargets = []testing.InternalFuzzTarget{
+{{range .FuzzTargets}}
+	{"{{.Name}}", {{.Package}}.{{.Name}}},
+{{end}}
+}
+
+var examples = []testing.InternalExample{
+{{range .Examples}}
+	{"{{.Name}}", {{.Package}}.{{.Name}}, {{.Output | printf "%q"}}, {{.Unordered}}},
+{{end}}
+}
+
+func init() {
+	testdeps.ImportPath = {{.ImportPath | printf "%q"}}
+}
+
+{{if .Cover}}
+
+//go:linkname runtime_coverage_processCoverTestDir runtime/coverage.processCoverTestDir
+func runtime_coverage_processCoverTestDir(dir string, cfile string, cmode string, cpkgs string) error
+
+//go:linkname testing_registerCover2 testing.registerCover2
+func testing_registerCover2(mode string, tearDown func(coverprofile string, gocoverdir string) (string, error))
+
+//go:linkname runtime_coverage_markProfileEmitted runtime/coverage.markProfileEmitted
+func runtime_coverage_markProfileEmitted(val bool)
+
+func coverTearDown(coverprofile string, gocoverdir string) (string, error) {
+	var err error
+	if gocoverdir == "" {
+		gocoverdir, err = os.MkdirTemp("", "gocoverdir")
+		if err != nil {
+			return "error setting GOCOVERDIR: bad os.MkdirTemp return", err
+		}
+		defer os.RemoveAll(gocoverdir)
+	}
+	runtime_coverage_markProfileEmitted(true)
+	cmode := {{printf "%q" .Cover.Mode}}
+	if err := runtime_coverage_processCoverTestDir(gocoverdir, coverprofile, cmode, {{printf "%q" .Covered}}); err != nil {
+		return "error generating coverage report", err
+	}
+	return "", nil
+}
+{{end}}
+
+func main() {
+{{if .Cover}}
+	testing_registerCover2({{printf "%q" .Cover.Mode}}, coverTearDown)
+{{end}}
+	m := testing.MainStart(testdeps.TestDeps{}, tests, benchmarks, fuzzTargets, examples)
+{{with .TestMain}}
+	{{.Package}}.{{.Name}}(m)
+	os.Exit(int(reflect.ValueOf(m).Elem().FieldByName("exitCode").Int()))
+{{else}}
+	os.Exit(m.Run())
+{{end}}
+}
+
+`)
diff --git a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go
index 09354d2..8568048 100644
--- a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go
+++ b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go
@@ -39,8 +39,6 @@
 	queue []<-chan File
 }
 
-type token struct{}
-
 var (
 	mu     sync.Mutex
 	inodes = map[File]inode{}
diff --git a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_test.go b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_test.go
index 7bd7bd2..8e2c6ab 100644
--- a/src/cmd/go/internal/lockedfile/internal/filelock/filelock_test.go
+++ b/src/cmd/go/internal/lockedfile/internal/filelock/filelock_test.go
@@ -10,7 +10,6 @@
 	"fmt"
 	"internal/testenv"
 	"os"
-	"os/exec"
 	"path/filepath"
 	"runtime"
 	"testing"
@@ -199,7 +198,7 @@
 	// Some kinds of file locks are dropped when a duplicated or forked file
 	// descriptor is unlocked. Double-check that the approach used by os/exec does
 	// not accidentally drop locks.
-	cmd := exec.Command(os.Args[0], "-test.run=^$")
+	cmd := testenv.Command(t, os.Args[0], "-test.run=^$")
 	if err := cmd.Run(); err != nil {
 		t.Fatalf("exec failed: %v", err)
 	}
diff --git a/src/cmd/go/internal/lockedfile/lockedfile_test.go b/src/cmd/go/internal/lockedfile/lockedfile_test.go
index 79352bc..5f6153c 100644
--- a/src/cmd/go/internal/lockedfile/lockedfile_test.go
+++ b/src/cmd/go/internal/lockedfile/lockedfile_test.go
@@ -12,7 +12,6 @@
 	"fmt"
 	"internal/testenv"
 	"os"
-	"os/exec"
 	"path/filepath"
 	"testing"
 	"time"
@@ -226,7 +225,7 @@
 		t.Fatal(err)
 	}
 
-	cmd := exec.Command(os.Args[0], "-test.run="+t.Name())
+	cmd := testenv.Command(t, os.Args[0], "-test.run="+t.Name())
 	cmd.Env = append(os.Environ(), fmt.Sprintf("%s=%s", dirVar, dir))
 
 	qDone := make(chan struct{})
diff --git a/src/cmd/go/internal/mmap/mmap_other.go b/src/cmd/go/internal/mmap/mmap_other.go
index 269fe8d..d146a42 100644
--- a/src/cmd/go/internal/mmap/mmap_other.go
+++ b/src/cmd/go/internal/mmap/mmap_other.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build plan9 || solaris
+//go:build (js && wasm) || plan9
 
 package mmap
 
diff --git a/src/cmd/go/internal/mmap/mmap_unix.go b/src/cmd/go/internal/mmap/mmap_unix.go
index 33e839c..53bcbb9 100644
--- a/src/cmd/go/internal/mmap/mmap_unix.go
+++ b/src/cmd/go/internal/mmap/mmap_unix.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build unix && !solaris
+//go:build unix
 
 package mmap
 
diff --git a/src/cmd/go/internal/modcmd/download.go b/src/cmd/go/internal/modcmd/download.go
index 0b50afb..f0b62e8 100644
--- a/src/cmd/go/internal/modcmd/download.go
+++ b/src/cmd/go/internal/modcmd/download.go
@@ -84,6 +84,7 @@
 
 	// TODO(jayconrod): https://golang.org/issue/35849 Apply -x to other 'go mod' commands.
 	cmdDownload.Flag.BoolVar(&cfg.BuildX, "x", false, "")
+	base.AddChdirFlag(&cmdDownload.Flag)
 	base.AddModCommonFlags(&cmdDownload.Flag)
 }
 
diff --git a/src/cmd/go/internal/modcmd/edit.go b/src/cmd/go/internal/modcmd/edit.go
index e5182a9..5fd13f2 100644
--- a/src/cmd/go/internal/modcmd/edit.go
+++ b/src/cmd/go/internal/modcmd/edit.go
@@ -127,6 +127,8 @@
 referred to indirectly. For the full set of modules available to a build,
 use 'go list -m -json all'.
 
+Edit also provides the -C, -n, and -x build flags.
+
 See https://golang.org/ref/mod#go-mod-edit for more about 'go mod edit'.
 	`,
 }
@@ -157,8 +159,9 @@
 	cmdEdit.Flag.Var(flagFunc(flagRetract), "retract", "")
 	cmdEdit.Flag.Var(flagFunc(flagDropRetract), "dropretract", "")
 
-	base.AddModCommonFlags(&cmdEdit.Flag)
 	base.AddBuildFlagsNX(&cmdEdit.Flag)
+	base.AddChdirFlag(&cmdEdit.Flag)
+	base.AddModCommonFlags(&cmdEdit.Flag)
 }
 
 func runEdit(ctx context.Context, cmd *base.Command, args []string) {
@@ -262,11 +265,11 @@
 
 // parsePathVersion parses -flag=arg expecting arg to be path@version.
 func parsePathVersion(flag, arg string) (path, version string) {
-	i := strings.Index(arg, "@")
-	if i < 0 {
+	before, after, found := strings.Cut(arg, "@")
+	if !found {
 		base.Fatalf("go: -%s=%s: need path@version", flag, arg)
 	}
-	path, version = strings.TrimSpace(arg[:i]), strings.TrimSpace(arg[i+1:])
+	path, version = strings.TrimSpace(before), strings.TrimSpace(after)
 	if err := module.CheckImportPath(path); err != nil {
 		base.Fatalf("go: -%s=%s: invalid path: %v", flag, arg, err)
 	}
@@ -293,10 +296,11 @@
 // parsePathVersionOptional parses path[@version], using adj to
 // describe any errors.
 func parsePathVersionOptional(adj, arg string, allowDirPath bool) (path, version string, err error) {
-	if i := strings.Index(arg, "@"); i < 0 {
+	before, after, found := strings.Cut(arg, "@")
+	if !found {
 		path = arg
 	} else {
-		path, version = strings.TrimSpace(arg[:i]), strings.TrimSpace(arg[i+1:])
+		path, version = strings.TrimSpace(before), strings.TrimSpace(after)
 	}
 	if err := module.CheckImportPath(path); err != nil {
 		if !allowDirPath || !modfile.IsDirectoryPath(path) {
@@ -324,12 +328,12 @@
 		return modfile.VersionInterval{}, fmt.Errorf("invalid version interval: %q", arg)
 	}
 	s := arg[1 : len(arg)-1]
-	i := strings.Index(s, ",")
-	if i < 0 {
+	before, after, found := strings.Cut(s, ",")
+	if !found {
 		return modfile.VersionInterval{}, fmt.Errorf("invalid version interval: %q", arg)
 	}
-	low := strings.TrimSpace(s[:i])
-	high := strings.TrimSpace(s[i+1:])
+	low := strings.TrimSpace(before)
+	high := strings.TrimSpace(after)
 	if !allowedVersionArg(low) || !allowedVersionArg(high) {
 		return modfile.VersionInterval{}, fmt.Errorf("invalid version interval: %q", arg)
 	}
@@ -387,11 +391,11 @@
 
 // flagReplace implements the -replace flag.
 func flagReplace(arg string) {
-	var i int
-	if i = strings.Index(arg, "="); i < 0 {
+	before, after, found := strings.Cut(arg, "=")
+	if !found {
 		base.Fatalf("go: -replace=%s: need old[@v]=new[@w] (missing =)", arg)
 	}
-	old, new := strings.TrimSpace(arg[:i]), strings.TrimSpace(arg[i+1:])
+	old, new := strings.TrimSpace(before), strings.TrimSpace(after)
 	if strings.HasPrefix(new, ">") {
 		base.Fatalf("go: -replace=%s: separator between old and new is =, not =>", arg)
 	}
diff --git a/src/cmd/go/internal/modcmd/graph.go b/src/cmd/go/internal/modcmd/graph.go
index 9568c65..555604d 100644
--- a/src/cmd/go/internal/modcmd/graph.go
+++ b/src/cmd/go/internal/modcmd/graph.go
@@ -12,13 +12,14 @@
 	"os"
 
 	"cmd/go/internal/base"
+	"cmd/go/internal/cfg"
 	"cmd/go/internal/modload"
 
 	"golang.org/x/mod/module"
 )
 
 var cmdGraph = &base.Command{
-	UsageLine: "go mod graph [-go=version]",
+	UsageLine: "go mod graph [-go=version] [-x]",
 	Short:     "print module requirement graph",
 	Long: `
 Graph prints the module requirement graph (with replacements applied)
@@ -30,6 +31,8 @@
 given Go version, instead of the version indicated by the 'go' directive
 in the go.mod file.
 
+The -x flag causes graph to print the commands graph executes.
+
 See https://golang.org/ref/mod#go-mod-graph for more about 'go mod graph'.
 	`,
 	Run: runGraph,
@@ -41,6 +44,8 @@
 
 func init() {
 	cmdGraph.Flag.Var(&graphGo, "go", "")
+	cmdGraph.Flag.BoolVar(&cfg.BuildX, "x", false, "")
+	base.AddChdirFlag(&cmdGraph.Flag)
 	base.AddModCommonFlags(&cmdGraph.Flag)
 }
 
diff --git a/src/cmd/go/internal/modcmd/init.go b/src/cmd/go/internal/modcmd/init.go
index bc4620a..e4be73f 100644
--- a/src/cmd/go/internal/modcmd/init.go
+++ b/src/cmd/go/internal/modcmd/init.go
@@ -34,6 +34,7 @@
 }
 
 func init() {
+	base.AddChdirFlag(&cmdInit.Flag)
 	base.AddModCommonFlags(&cmdInit.Flag)
 }
 
diff --git a/src/cmd/go/internal/modcmd/tidy.go b/src/cmd/go/internal/modcmd/tidy.go
index d35476e..7e33ad2 100644
--- a/src/cmd/go/internal/modcmd/tidy.go
+++ b/src/cmd/go/internal/modcmd/tidy.go
@@ -19,7 +19,7 @@
 )
 
 var cmdTidy = &base.Command{
-	UsageLine: "go mod tidy [-e] [-v] [-go=version] [-compat=version]",
+	UsageLine: "go mod tidy [-e] [-v] [-x] [-go=version] [-compat=version]",
 	Short:     "add missing and remove unused modules",
 	Long: `
 Tidy makes sure go.mod matches the source code in the module.
@@ -48,6 +48,8 @@
 version prior to the one indicated by the 'go' directive in the go.mod
 file.
 
+The -x flag causes tidy to print the commands download executes.
+
 See https://golang.org/ref/mod#go-mod-tidy for more about 'go mod tidy'.
 	`,
 	Run: runTidy,
@@ -61,9 +63,11 @@
 
 func init() {
 	cmdTidy.Flag.BoolVar(&cfg.BuildV, "v", false, "")
+	cmdTidy.Flag.BoolVar(&cfg.BuildX, "x", false, "")
 	cmdTidy.Flag.BoolVar(&tidyE, "e", false, "")
 	cmdTidy.Flag.Var(&tidyGo, "go", "")
 	cmdTidy.Flag.Var(&tidyCompat, "compat", "")
+	base.AddChdirFlag(&cmdTidy.Flag)
 	base.AddModCommonFlags(&cmdTidy.Flag)
 }
 
diff --git a/src/cmd/go/internal/modcmd/vendor.go b/src/cmd/go/internal/modcmd/vendor.go
index ef12370..2bb2eb8 100644
--- a/src/cmd/go/internal/modcmd/vendor.go
+++ b/src/cmd/go/internal/modcmd/vendor.go
@@ -61,6 +61,7 @@
 	cmdVendor.Flag.BoolVar(&cfg.BuildV, "v", false, "")
 	cmdVendor.Flag.BoolVar(&vendorE, "e", false, "")
 	cmdVendor.Flag.StringVar(&vendorO, "o", "", "")
+	base.AddChdirFlag(&cmdVendor.Flag)
 	base.AddModCommonFlags(&cmdVendor.Flag)
 }
 
@@ -210,6 +211,9 @@
 		b.WriteString(m.Version)
 	}
 	if r.Path != "" {
+		if strings.HasPrefix(r.Path, "./vendor") || strings.HasPrefix(r.Path, ".\vendor") {
+			base.Fatalf("go: replacement path %s inside vendor directory", r.Path)
+		}
 		b.WriteString(" => ")
 		b.WriteString(r.Path)
 		if r.Version != "" {
@@ -222,20 +226,25 @@
 }
 
 func vendorPkg(vdir, pkg string) {
-	// TODO(#42504): Instead of calling modload.ImportMap then build.ImportDir,
-	// just call load.PackagesAndErrors. To do that, we need to add a good way
-	// to ignore build constraints.
-	realPath := modload.ImportMap(pkg)
-	if realPath != pkg && modload.ImportMap(realPath) != "" {
+	src, realPath, _ := modload.Lookup("", false, pkg)
+	if src == "" {
+		base.Errorf("internal error: no pkg for %s\n", pkg)
+		return
+	}
+	if realPath != pkg {
+		// TODO(#26904): Revisit whether this behavior still makes sense.
+		// This should actually be impossible today, because the import map is the
+		// identity function for packages outside of the standard library.
+		//
+		// Part of the purpose of the vendor directory is to allow the packages in
+		// the module to continue to build in GOPATH mode, and GOPATH-mode users
+		// won't know about replacement aliasing. How important is it to maintain
+		// compatibility?
 		fmt.Fprintf(os.Stderr, "warning: %s imported as both %s and %s; making two copies.\n", realPath, realPath, pkg)
 	}
 
 	copiedFiles := make(map[string]bool)
 	dst := filepath.Join(vdir, pkg)
-	src := modload.PackageDir(realPath)
-	if src == "" {
-		fmt.Fprintf(os.Stderr, "internal error: no pkg for %s -> %s\n", pkg, realPath)
-	}
 	copyDir(dst, src, matchPotentialSourceFile, copiedFiles)
 	if m := modload.PackageModule(realPath); m.Path != "" {
 		copyMetadata(m.Path, realPath, dst, src, copiedFiles)
diff --git a/src/cmd/go/internal/modcmd/verify.go b/src/cmd/go/internal/modcmd/verify.go
index 459bf5d..a5f7f24 100644
--- a/src/cmd/go/internal/modcmd/verify.go
+++ b/src/cmd/go/internal/modcmd/verify.go
@@ -38,6 +38,7 @@
 }
 
 func init() {
+	base.AddChdirFlag(&cmdVerify.Flag)
 	base.AddModCommonFlags(&cmdVerify.Flag)
 }
 
diff --git a/src/cmd/go/internal/modcmd/why.go b/src/cmd/go/internal/modcmd/why.go
index 8e929a0..729c88f 100644
--- a/src/cmd/go/internal/modcmd/why.go
+++ b/src/cmd/go/internal/modcmd/why.go
@@ -58,6 +58,7 @@
 
 func init() {
 	cmdWhy.Run = runWhy // break init cycle
+	base.AddChdirFlag(&cmdWhy.Flag)
 	base.AddModCommonFlags(&cmdWhy.Flag)
 }
 
diff --git a/src/cmd/go/internal/modconv/dep.go b/src/cmd/go/internal/modconv/dep.go
index 2e673c3..9bea761 100644
--- a/src/cmd/go/internal/modconv/dep.go
+++ b/src/cmd/go/internal/modconv/dep.go
@@ -44,12 +44,12 @@
 		if r == nil {
 			continue
 		}
-		i := strings.Index(line, "=")
-		if i < 0 {
+		before, after, found := strings.Cut(line, "=")
+		if !found {
 			continue
 		}
-		key := strings.TrimSpace(line[:i])
-		val := strings.TrimSpace(line[i+1:])
+		key := strings.TrimSpace(before)
+		val := strings.TrimSpace(after)
 		if len(val) >= 2 && val[0] == '"' && val[len(val)-1] == '"' {
 			q, err := strconv.Unquote(val) // Go unquoting, but close enough for now
 			if err != nil {
diff --git a/src/cmd/go/internal/modfetch/cache.go b/src/cmd/go/internal/modfetch/cache.go
index c1ed187..928eb1f 100644
--- a/src/cmd/go/internal/modfetch/cache.go
+++ b/src/cmd/go/internal/modfetch/cache.go
@@ -710,8 +710,7 @@
 		// involved in module graph construction, many *.zip files
 		// will never be requested.
 		name := info.Name()
-		if strings.HasSuffix(name, ".mod") {
-			v := strings.TrimSuffix(name, ".mod")
+		if v, found := strings.CutSuffix(name, ".mod"); found {
 			if v != "" && module.CanonicalVersion(v) == v {
 				list = append(list, v)
 			}
diff --git a/src/cmd/go/internal/modfetch/codehost/codehost.go b/src/cmd/go/internal/modfetch/codehost/codehost.go
index 7470227..855b694 100644
--- a/src/cmd/go/internal/modfetch/codehost/codehost.go
+++ b/src/cmd/go/internal/modfetch/codehost/codehost.go
@@ -37,7 +37,9 @@
 // A Repo represents a code hosting source.
 // Typical implementations include local version control repositories,
 // remote version control servers, and code hosting sites.
-// A Repo must be safe for simultaneous use by multiple goroutines.
+//
+// A Repo must be safe for simultaneous use by multiple goroutines,
+// and callers must not modify returned values, which may be cached and shared.
 type Repo interface {
 	// CheckReuse checks whether the old origin information
 	// remains up to date. If so, whatever cached object it was
@@ -199,6 +201,19 @@
 	return err == fs.ErrNotExist
 }
 
+// ErrUnsupported indicates that a requested operation cannot be performed,
+// because it is unsupported. This error indicates that there is no alternative
+// way to perform the operation.
+//
+// TODO(#41198): Remove this declaration and use errors.ErrUnsupported instead.
+var ErrUnsupported = unsupportedOperationError{}
+
+type unsupportedOperationError struct{}
+
+func (unsupportedOperationError) Error() string {
+	return "unsupported operation"
+}
+
 // AllHex reports whether the revision rev is entirely lower-case hexadecimal digits.
 func AllHex(rev string) bool {
 	for i := 0; i < len(rev); i++ {
diff --git a/src/cmd/go/internal/modfetch/codehost/git.go b/src/cmd/go/internal/modfetch/codehost/git.go
index 35f77e8..127ad26 100644
--- a/src/cmd/go/internal/modfetch/codehost/git.go
+++ b/src/cmd/go/internal/modfetch/codehost/git.go
@@ -262,8 +262,8 @@
 			}
 		}
 		for ref, hash := range refs {
-			if strings.HasSuffix(ref, "^{}") { // record unwrapped annotated tag as value of tag
-				refs[strings.TrimSuffix(ref, "^{}")] = hash
+			if k, found := strings.CutSuffix(ref, "^{}"); found { // record unwrapped annotated tag as value of tag
+				refs[k] = hash
 				delete(refs, ref)
 			}
 		}
@@ -348,12 +348,21 @@
 	if refs["HEAD"] == "" {
 		return nil, ErrNoCommits
 	}
-	info, err := r.Stat(refs["HEAD"])
+	statInfo, err := r.Stat(refs["HEAD"])
 	if err != nil {
 		return nil, err
 	}
+
+	// Stat may return cached info, so make a copy to modify here.
+	info := new(RevInfo)
+	*info = *statInfo
+	info.Origin = new(Origin)
+	if statInfo.Origin != nil {
+		*info.Origin = *statInfo.Origin
+	}
 	info.Origin.Ref = "HEAD"
 	info.Origin.Hash = refs["HEAD"]
+
 	return info, nil
 }
 
@@ -477,9 +486,9 @@
 	// Either way, try a local stat before falling back to network I/O.
 	if !didStatLocal {
 		if info, err := r.statLocal(rev, hash); err == nil {
-			if strings.HasPrefix(ref, "refs/tags/") {
+			if after, found := strings.CutPrefix(ref, "refs/tags/"); found {
 				// Make sure tag exists, so it will be in localTags next time the go command is run.
-				Run(r.dir, "git", "tag", strings.TrimPrefix(ref, "refs/tags/"), hash)
+				Run(r.dir, "git", "tag", after, hash)
 			}
 			return info, nil
 		}
@@ -560,7 +569,7 @@
 	return nil
 }
 
-// statLocal returns a RevInfo describing rev in the local git repository.
+// statLocal returns a new RevInfo describing rev in the local git repository.
 // It uses version as info.Version.
 func (r *gitRepo) statLocal(version, rev string) (*RevInfo, error) {
 	out, err := Run(r.dir, "git", "-c", "log.showsignature=false", "log", "--no-decorate", "-n1", "--format=format:%H %ct %D", rev, "--")
diff --git a/src/cmd/go/internal/modfetch/codehost/git_test.go b/src/cmd/go/internal/modfetch/codehost/git_test.go
index 6a4212f..ec95097 100644
--- a/src/cmd/go/internal/modfetch/codehost/git_test.go
+++ b/src/cmd/go/internal/modfetch/codehost/git_test.go
@@ -7,6 +7,8 @@
 import (
 	"archive/zip"
 	"bytes"
+	"cmd/go/internal/cfg"
+	"cmd/go/internal/vcweb/vcstest"
 	"flag"
 	"internal/testenv"
 	"io"
@@ -26,17 +28,18 @@
 	// needed for initializing the test environment variables as testing.Short
 	// and HasExternalNetwork
 	flag.Parse()
-	os.Exit(testMain(m))
+	if err := testMain(m); err != nil {
+		log.Fatal(err)
+	}
 }
 
-const (
-	gitrepo1 = "https://vcs-test.golang.org/git/gitrepo1"
-	hgrepo1  = "https://vcs-test.golang.org/hg/hgrepo1"
-)
+var gitrepo1, hgrepo1 string
 
-var altRepos = []string{
-	"localGitRepo",
-	hgrepo1,
+var altRepos = func() []string {
+	return []string{
+		"localGitRepo",
+		hgrepo1,
+	}
 }
 
 // TODO: Convert gitrepo1 to svn, bzr, fossil and add tests.
@@ -45,14 +48,38 @@
 // localGitRepo is like gitrepo1 but allows archive access.
 var localGitRepo, localGitURL string
 
-func testMain(m *testing.M) int {
+func testMain(m *testing.M) (err error) {
+	cfg.BuildX = true
+
+	srv, err := vcstest.NewServer()
+	if err != nil {
+		return err
+	}
+	defer func() {
+		if closeErr := srv.Close(); err == nil {
+			err = closeErr
+		}
+	}()
+
+	gitrepo1 = srv.HTTP.URL + "/git/gitrepo1"
+	hgrepo1 = srv.HTTP.URL + "/hg/hgrepo1"
+
 	dir, err := os.MkdirTemp("", "gitrepo-test-")
 	if err != nil {
-		log.Fatal(err)
+		return err
 	}
-	defer os.RemoveAll(dir)
+	defer func() {
+		if rmErr := os.RemoveAll(dir); err == nil {
+			err = rmErr
+		}
+	}()
 
-	if testenv.HasExternalNetwork() && testenv.HasExec() {
+	// Redirect the module cache to a fresh directory to avoid crosstalk, and make
+	// it read/write so that the test can still clean it up easily when done.
+	cfg.GOMODCACHE = filepath.Join(dir, "modcache")
+	cfg.ModCacheRW = true
+
+	if !testing.Short() && testenv.HasExec() {
 		if _, err := exec.LookPath("git"); err == nil {
 			// Clone gitrepo1 into a local directory.
 			// If we use a file:// URL to access the local directory,
@@ -60,10 +87,10 @@
 			// which will let us test remote git archive invocations.
 			localGitRepo = filepath.Join(dir, "gitrepo2")
 			if _, err := Run("", "git", "clone", "--mirror", gitrepo1, localGitRepo); err != nil {
-				log.Fatal(err)
+				return err
 			}
 			if _, err := Run(localGitRepo, "git", "config", "daemon.uploadarch", "true"); err != nil {
-				log.Fatal(err)
+				return err
 			}
 
 			// Convert absolute path to file URL. LocalGitRepo will not accept
@@ -77,7 +104,8 @@
 		}
 	}
 
-	return m.Run()
+	m.Run()
+	return nil
 }
 
 func testRepo(t *testing.T, remote string) (Repo, error) {
@@ -85,49 +113,31 @@
 		testenv.MustHaveExecPath(t, "git")
 		return LocalGitRepo(localGitURL)
 	}
-	vcs := "git"
+	vcsName := "git"
 	for _, k := range []string{"hg"} {
 		if strings.Contains(remote, "/"+k+"/") {
-			vcs = k
+			vcsName = k
 		}
 	}
-	testenv.MustHaveExecPath(t, vcs)
-	return NewRepo(vcs, remote)
-}
-
-var tagsTests = []struct {
-	repo   string
-	prefix string
-	tags   []Tag
-}{
-	{gitrepo1, "xxx", []Tag{}},
-	{gitrepo1, "", []Tag{
-		{"v1.2.3", "ede458df7cd0fdca520df19a33158086a8a68e81"},
-		{"v1.2.4-annotated", "ede458df7cd0fdca520df19a33158086a8a68e81"},
-		{"v2.0.1", "76a00fb249b7f93091bc2c89a789dab1fc1bc26f"},
-		{"v2.0.2", "9d02800338b8a55be062c838d1f02e0c5780b9eb"},
-		{"v2.3", "76a00fb249b7f93091bc2c89a789dab1fc1bc26f"},
-	}},
-	{gitrepo1, "v", []Tag{
-		{"v1.2.3", "ede458df7cd0fdca520df19a33158086a8a68e81"},
-		{"v1.2.4-annotated", "ede458df7cd0fdca520df19a33158086a8a68e81"},
-		{"v2.0.1", "76a00fb249b7f93091bc2c89a789dab1fc1bc26f"},
-		{"v2.0.2", "9d02800338b8a55be062c838d1f02e0c5780b9eb"},
-		{"v2.3", "76a00fb249b7f93091bc2c89a789dab1fc1bc26f"},
-	}},
-	{gitrepo1, "v1", []Tag{
-		{"v1.2.3", "ede458df7cd0fdca520df19a33158086a8a68e81"},
-		{"v1.2.4-annotated", "ede458df7cd0fdca520df19a33158086a8a68e81"},
-	}},
-	{gitrepo1, "2", []Tag{}},
+	testenv.MustHaveExecPath(t, vcsName)
+	return NewRepo(vcsName, remote)
 }
 
 func TestTags(t *testing.T) {
 	testenv.MustHaveExternalNetwork(t)
 	testenv.MustHaveExec(t)
+	t.Parallel()
 
-	for _, tt := range tagsTests {
-		f := func(t *testing.T) {
+	type tagsTest struct {
+		repo   string
+		prefix string
+		tags   []Tag
+	}
+
+	runTest := func(tt tagsTest) func(*testing.T) {
+		return func(t *testing.T) {
+			t.Parallel()
+
 			r, err := testRepo(t, tt.repo)
 			if err != nil {
 				t.Fatal(err)
@@ -140,7 +150,31 @@
 				t.Errorf("Tags(%q): incorrect tags\nhave %v\nwant %v", tt.prefix, tags, tt.tags)
 			}
 		}
-		t.Run(path.Base(tt.repo)+"/"+tt.prefix, f)
+	}
+
+	for _, tt := range []tagsTest{
+		{gitrepo1, "xxx", []Tag{}},
+		{gitrepo1, "", []Tag{
+			{"v1.2.3", "ede458df7cd0fdca520df19a33158086a8a68e81"},
+			{"v1.2.4-annotated", "ede458df7cd0fdca520df19a33158086a8a68e81"},
+			{"v2.0.1", "76a00fb249b7f93091bc2c89a789dab1fc1bc26f"},
+			{"v2.0.2", "9d02800338b8a55be062c838d1f02e0c5780b9eb"},
+			{"v2.3", "76a00fb249b7f93091bc2c89a789dab1fc1bc26f"},
+		}},
+		{gitrepo1, "v", []Tag{
+			{"v1.2.3", "ede458df7cd0fdca520df19a33158086a8a68e81"},
+			{"v1.2.4-annotated", "ede458df7cd0fdca520df19a33158086a8a68e81"},
+			{"v2.0.1", "76a00fb249b7f93091bc2c89a789dab1fc1bc26f"},
+			{"v2.0.2", "9d02800338b8a55be062c838d1f02e0c5780b9eb"},
+			{"v2.3", "76a00fb249b7f93091bc2c89a789dab1fc1bc26f"},
+		}},
+		{gitrepo1, "v1", []Tag{
+			{"v1.2.3", "ede458df7cd0fdca520df19a33158086a8a68e81"},
+			{"v1.2.4-annotated", "ede458df7cd0fdca520df19a33158086a8a68e81"},
+		}},
+		{gitrepo1, "2", []Tag{}},
+	} {
+		t.Run(path.Base(tt.repo)+"/"+tt.prefix, runTest(tt))
 		if tt.repo == gitrepo1 {
 			// Clear hashes.
 			clearTags := []Tag{}
@@ -148,60 +182,31 @@
 				clearTags = append(clearTags, Tag{tag.Name, ""})
 			}
 			tags := tt.tags
-			for _, tt.repo = range altRepos {
+			for _, tt.repo = range altRepos() {
 				if strings.Contains(tt.repo, "Git") {
 					tt.tags = tags
 				} else {
 					tt.tags = clearTags
 				}
-				t.Run(path.Base(tt.repo)+"/"+tt.prefix, f)
+				t.Run(path.Base(tt.repo)+"/"+tt.prefix, runTest(tt))
 			}
 		}
 	}
 }
 
-var latestTests = []struct {
-	repo string
-	info *RevInfo
-}{
-	{
-		gitrepo1,
-		&RevInfo{
-			Origin: &Origin{
-				VCS:  "git",
-				URL:  "https://vcs-test.golang.org/git/gitrepo1",
-				Ref:  "HEAD",
-				Hash: "ede458df7cd0fdca520df19a33158086a8a68e81",
-			},
-			Name:    "ede458df7cd0fdca520df19a33158086a8a68e81",
-			Short:   "ede458df7cd0",
-			Version: "ede458df7cd0fdca520df19a33158086a8a68e81",
-			Time:    time.Date(2018, 4, 17, 19, 43, 22, 0, time.UTC),
-			Tags:    []string{"v1.2.3", "v1.2.4-annotated"},
-		},
-	},
-	{
-		hgrepo1,
-		&RevInfo{
-			Origin: &Origin{
-				VCS:  "hg",
-				URL:  "https://vcs-test.golang.org/hg/hgrepo1",
-				Hash: "18518c07eb8ed5c80221e997e518cccaa8c0c287",
-			},
-			Name:    "18518c07eb8ed5c80221e997e518cccaa8c0c287",
-			Short:   "18518c07eb8e",
-			Version: "18518c07eb8ed5c80221e997e518cccaa8c0c287",
-			Time:    time.Date(2018, 6, 27, 16, 16, 30, 0, time.UTC),
-		},
-	},
-}
-
 func TestLatest(t *testing.T) {
 	testenv.MustHaveExternalNetwork(t)
 	testenv.MustHaveExec(t)
+	t.Parallel()
 
-	for _, tt := range latestTests {
-		f := func(t *testing.T) {
+	type latestTest struct {
+		repo string
+		info *RevInfo
+	}
+	runTest := func(tt latestTest) func(*testing.T) {
+		return func(t *testing.T) {
+			t.Parallel()
+
 			r, err := testRepo(t, tt.repo)
 			if err != nil {
 				t.Fatal(err)
@@ -214,7 +219,41 @@
 				t.Errorf("Latest: incorrect info\nhave %+v (origin %+v)\nwant %+v (origin %+v)", info, info.Origin, tt.info, tt.info.Origin)
 			}
 		}
-		t.Run(path.Base(tt.repo), f)
+	}
+
+	for _, tt := range []latestTest{
+		{
+			gitrepo1,
+			&RevInfo{
+				Origin: &Origin{
+					VCS:  "git",
+					URL:  gitrepo1,
+					Ref:  "HEAD",
+					Hash: "ede458df7cd0fdca520df19a33158086a8a68e81",
+				},
+				Name:    "ede458df7cd0fdca520df19a33158086a8a68e81",
+				Short:   "ede458df7cd0",
+				Version: "ede458df7cd0fdca520df19a33158086a8a68e81",
+				Time:    time.Date(2018, 4, 17, 19, 43, 22, 0, time.UTC),
+				Tags:    []string{"v1.2.3", "v1.2.4-annotated"},
+			},
+		},
+		{
+			hgrepo1,
+			&RevInfo{
+				Origin: &Origin{
+					VCS:  "hg",
+					URL:  hgrepo1,
+					Hash: "18518c07eb8ed5c80221e997e518cccaa8c0c287",
+				},
+				Name:    "18518c07eb8ed5c80221e997e518cccaa8c0c287",
+				Short:   "18518c07eb8e",
+				Version: "18518c07eb8ed5c80221e997e518cccaa8c0c287",
+				Time:    time.Date(2018, 6, 27, 16, 16, 30, 0, time.UTC),
+			},
+		},
+	} {
+		t.Run(path.Base(tt.repo), runTest(tt))
 		if tt.repo == gitrepo1 {
 			tt.repo = "localGitRepo"
 			info := *tt.info
@@ -222,44 +261,27 @@
 			o := *info.Origin
 			info.Origin = &o
 			o.URL = localGitURL
-			t.Run(path.Base(tt.repo), f)
+			t.Run(path.Base(tt.repo), runTest(tt))
 		}
 	}
 }
 
-var readFileTests = []struct {
-	repo string
-	rev  string
-	file string
-	err  string
-	data string
-}{
-	{
-		repo: gitrepo1,
-		rev:  "latest",
-		file: "README",
-		data: "",
-	},
-	{
-		repo: gitrepo1,
-		rev:  "v2",
-		file: "another.txt",
-		data: "another\n",
-	},
-	{
-		repo: gitrepo1,
-		rev:  "v2.3.4",
-		file: "another.txt",
-		err:  fs.ErrNotExist.Error(),
-	},
-}
-
 func TestReadFile(t *testing.T) {
 	testenv.MustHaveExternalNetwork(t)
 	testenv.MustHaveExec(t)
+	t.Parallel()
 
-	for _, tt := range readFileTests {
-		f := func(t *testing.T) {
+	type readFileTest struct {
+		repo string
+		rev  string
+		file string
+		err  string
+		data string
+	}
+	runTest := func(tt readFileTest) func(*testing.T) {
+		return func(t *testing.T) {
+			t.Parallel()
+
 			r, err := testRepo(t, tt.repo)
 			if err != nil {
 				t.Fatal(err)
@@ -284,162 +306,37 @@
 				t.Errorf("ReadFile: incorrect data\nhave %q\nwant %q", data, tt.data)
 			}
 		}
-		t.Run(path.Base(tt.repo)+"/"+tt.rev+"/"+tt.file, f)
+	}
+
+	for _, tt := range []readFileTest{
+		{
+			repo: gitrepo1,
+			rev:  "latest",
+			file: "README",
+			data: "",
+		},
+		{
+			repo: gitrepo1,
+			rev:  "v2",
+			file: "another.txt",
+			data: "another\n",
+		},
+		{
+			repo: gitrepo1,
+			rev:  "v2.3.4",
+			file: "another.txt",
+			err:  fs.ErrNotExist.Error(),
+		},
+	} {
+		t.Run(path.Base(tt.repo)+"/"+tt.rev+"/"+tt.file, runTest(tt))
 		if tt.repo == gitrepo1 {
-			for _, tt.repo = range altRepos {
-				t.Run(path.Base(tt.repo)+"/"+tt.rev+"/"+tt.file, f)
+			for _, tt.repo = range altRepos() {
+				t.Run(path.Base(tt.repo)+"/"+tt.rev+"/"+tt.file, runTest(tt))
 			}
 		}
 	}
 }
 
-var readZipTests = []struct {
-	repo   string
-	rev    string
-	subdir string
-	err    string
-	files  map[string]uint64
-}{
-	{
-		repo:   gitrepo1,
-		rev:    "v2.3.4",
-		subdir: "",
-		files: map[string]uint64{
-			"prefix/":       0,
-			"prefix/README": 0,
-			"prefix/v2":     3,
-		},
-	},
-	{
-		repo:   hgrepo1,
-		rev:    "v2.3.4",
-		subdir: "",
-		files: map[string]uint64{
-			"prefix/.hg_archival.txt": ^uint64(0),
-			"prefix/README":           0,
-			"prefix/v2":               3,
-		},
-	},
-
-	{
-		repo:   gitrepo1,
-		rev:    "v2",
-		subdir: "",
-		files: map[string]uint64{
-			"prefix/":            0,
-			"prefix/README":      0,
-			"prefix/v2":          3,
-			"prefix/another.txt": 8,
-			"prefix/foo.txt":     13,
-		},
-	},
-	{
-		repo:   hgrepo1,
-		rev:    "v2",
-		subdir: "",
-		files: map[string]uint64{
-			"prefix/.hg_archival.txt": ^uint64(0),
-			"prefix/README":           0,
-			"prefix/v2":               3,
-			"prefix/another.txt":      8,
-			"prefix/foo.txt":          13,
-		},
-	},
-
-	{
-		repo:   gitrepo1,
-		rev:    "v3",
-		subdir: "",
-		files: map[string]uint64{
-			"prefix/":                    0,
-			"prefix/v3/":                 0,
-			"prefix/v3/sub/":             0,
-			"prefix/v3/sub/dir/":         0,
-			"prefix/v3/sub/dir/file.txt": 16,
-			"prefix/README":              0,
-		},
-	},
-	{
-		repo:   hgrepo1,
-		rev:    "v3",
-		subdir: "",
-		files: map[string]uint64{
-			"prefix/.hg_archival.txt":    ^uint64(0),
-			"prefix/.hgtags":             405,
-			"prefix/v3/sub/dir/file.txt": 16,
-			"prefix/README":              0,
-		},
-	},
-
-	{
-		repo:   gitrepo1,
-		rev:    "v3",
-		subdir: "v3/sub/dir",
-		files: map[string]uint64{
-			"prefix/":                    0,
-			"prefix/v3/":                 0,
-			"prefix/v3/sub/":             0,
-			"prefix/v3/sub/dir/":         0,
-			"prefix/v3/sub/dir/file.txt": 16,
-		},
-	},
-	{
-		repo:   hgrepo1,
-		rev:    "v3",
-		subdir: "v3/sub/dir",
-		files: map[string]uint64{
-			"prefix/v3/sub/dir/file.txt": 16,
-		},
-	},
-
-	{
-		repo:   gitrepo1,
-		rev:    "v3",
-		subdir: "v3/sub",
-		files: map[string]uint64{
-			"prefix/":                    0,
-			"prefix/v3/":                 0,
-			"prefix/v3/sub/":             0,
-			"prefix/v3/sub/dir/":         0,
-			"prefix/v3/sub/dir/file.txt": 16,
-		},
-	},
-	{
-		repo:   hgrepo1,
-		rev:    "v3",
-		subdir: "v3/sub",
-		files: map[string]uint64{
-			"prefix/v3/sub/dir/file.txt": 16,
-		},
-	},
-
-	{
-		repo:   gitrepo1,
-		rev:    "aaaaaaaaab",
-		subdir: "",
-		err:    "unknown revision",
-	},
-	{
-		repo:   hgrepo1,
-		rev:    "aaaaaaaaab",
-		subdir: "",
-		err:    "unknown revision",
-	},
-
-	{
-		repo:   "https://github.com/rsc/vgotest1",
-		rev:    "submod/v1.0.4",
-		subdir: "submod",
-		files: map[string]uint64{
-			"prefix/":                0,
-			"prefix/submod/":         0,
-			"prefix/submod/go.mod":   53,
-			"prefix/submod/pkg/":     0,
-			"prefix/submod/pkg/p.go": 31,
-		},
-	},
-}
-
 type zipFile struct {
 	name string
 	size int64
@@ -448,9 +345,19 @@
 func TestReadZip(t *testing.T) {
 	testenv.MustHaveExternalNetwork(t)
 	testenv.MustHaveExec(t)
+	t.Parallel()
 
-	for _, tt := range readZipTests {
-		f := func(t *testing.T) {
+	type readZipTest struct {
+		repo   string
+		rev    string
+		subdir string
+		err    string
+		files  map[string]uint64
+	}
+	runTest := func(tt readZipTest) func(*testing.T) {
+		return func(t *testing.T) {
+			t.Parallel()
+
 			r, err := testRepo(t, tt.repo)
 			if err != nil {
 				t.Fatal(err)
@@ -498,10 +405,152 @@
 				}
 			}
 		}
-		t.Run(path.Base(tt.repo)+"/"+tt.rev+"/"+tt.subdir, f)
+	}
+
+	for _, tt := range []readZipTest{
+		{
+			repo:   gitrepo1,
+			rev:    "v2.3.4",
+			subdir: "",
+			files: map[string]uint64{
+				"prefix/":       0,
+				"prefix/README": 0,
+				"prefix/v2":     3,
+			},
+		},
+		{
+			repo:   hgrepo1,
+			rev:    "v2.3.4",
+			subdir: "",
+			files: map[string]uint64{
+				"prefix/.hg_archival.txt": ^uint64(0),
+				"prefix/README":           0,
+				"prefix/v2":               3,
+			},
+		},
+
+		{
+			repo:   gitrepo1,
+			rev:    "v2",
+			subdir: "",
+			files: map[string]uint64{
+				"prefix/":            0,
+				"prefix/README":      0,
+				"prefix/v2":          3,
+				"prefix/another.txt": 8,
+				"prefix/foo.txt":     13,
+			},
+		},
+		{
+			repo:   hgrepo1,
+			rev:    "v2",
+			subdir: "",
+			files: map[string]uint64{
+				"prefix/.hg_archival.txt": ^uint64(0),
+				"prefix/README":           0,
+				"prefix/v2":               3,
+				"prefix/another.txt":      8,
+				"prefix/foo.txt":          13,
+			},
+		},
+
+		{
+			repo:   gitrepo1,
+			rev:    "v3",
+			subdir: "",
+			files: map[string]uint64{
+				"prefix/":                    0,
+				"prefix/v3/":                 0,
+				"prefix/v3/sub/":             0,
+				"prefix/v3/sub/dir/":         0,
+				"prefix/v3/sub/dir/file.txt": 16,
+				"prefix/README":              0,
+			},
+		},
+		{
+			repo:   hgrepo1,
+			rev:    "v3",
+			subdir: "",
+			files: map[string]uint64{
+				"prefix/.hg_archival.txt":    ^uint64(0),
+				"prefix/.hgtags":             405,
+				"prefix/v3/sub/dir/file.txt": 16,
+				"prefix/README":              0,
+			},
+		},
+
+		{
+			repo:   gitrepo1,
+			rev:    "v3",
+			subdir: "v3/sub/dir",
+			files: map[string]uint64{
+				"prefix/":                    0,
+				"prefix/v3/":                 0,
+				"prefix/v3/sub/":             0,
+				"prefix/v3/sub/dir/":         0,
+				"prefix/v3/sub/dir/file.txt": 16,
+			},
+		},
+		{
+			repo:   hgrepo1,
+			rev:    "v3",
+			subdir: "v3/sub/dir",
+			files: map[string]uint64{
+				"prefix/v3/sub/dir/file.txt": 16,
+			},
+		},
+
+		{
+			repo:   gitrepo1,
+			rev:    "v3",
+			subdir: "v3/sub",
+			files: map[string]uint64{
+				"prefix/":                    0,
+				"prefix/v3/":                 0,
+				"prefix/v3/sub/":             0,
+				"prefix/v3/sub/dir/":         0,
+				"prefix/v3/sub/dir/file.txt": 16,
+			},
+		},
+		{
+			repo:   hgrepo1,
+			rev:    "v3",
+			subdir: "v3/sub",
+			files: map[string]uint64{
+				"prefix/v3/sub/dir/file.txt": 16,
+			},
+		},
+
+		{
+			repo:   gitrepo1,
+			rev:    "aaaaaaaaab",
+			subdir: "",
+			err:    "unknown revision",
+		},
+		{
+			repo:   hgrepo1,
+			rev:    "aaaaaaaaab",
+			subdir: "",
+			err:    "unknown revision",
+		},
+
+		{
+			repo:   "https://github.com/rsc/vgotest1",
+			rev:    "submod/v1.0.4",
+			subdir: "submod",
+			files: map[string]uint64{
+				"prefix/":                0,
+				"prefix/submod/":         0,
+				"prefix/submod/go.mod":   53,
+				"prefix/submod/pkg/":     0,
+				"prefix/submod/pkg/p.go": 31,
+			},
+		},
+	} {
+		t.Run(path.Base(tt.repo)+"/"+tt.rev+"/"+tt.subdir, runTest(tt))
 		if tt.repo == gitrepo1 {
 			tt.repo = "localGitRepo"
-			t.Run(path.Base(tt.repo)+"/"+tt.rev+"/"+tt.subdir, f)
+			t.Run(path.Base(tt.repo)+"/"+tt.rev+"/"+tt.subdir, runTest(tt))
 		}
 	}
 }
@@ -514,112 +563,21 @@
 	"97f6aa59c81c623494825b43d39e445566e429a4": "c0cbbfb24c7c3c50c35c7b88e7db777da4ff625d",
 }
 
-var statTests = []struct {
-	repo string
-	rev  string
-	err  string
-	info *RevInfo
-}{
-	{
-		repo: gitrepo1,
-		rev:  "HEAD",
-		info: &RevInfo{
-			Name:    "ede458df7cd0fdca520df19a33158086a8a68e81",
-			Short:   "ede458df7cd0",
-			Version: "ede458df7cd0fdca520df19a33158086a8a68e81",
-			Time:    time.Date(2018, 4, 17, 19, 43, 22, 0, time.UTC),
-			Tags:    []string{"v1.2.3", "v1.2.4-annotated"},
-		},
-	},
-	{
-		repo: gitrepo1,
-		rev:  "v2", // branch
-		info: &RevInfo{
-			Name:    "9d02800338b8a55be062c838d1f02e0c5780b9eb",
-			Short:   "9d02800338b8",
-			Version: "9d02800338b8a55be062c838d1f02e0c5780b9eb",
-			Time:    time.Date(2018, 4, 17, 20, 00, 32, 0, time.UTC),
-			Tags:    []string{"v2.0.2"},
-		},
-	},
-	{
-		repo: gitrepo1,
-		rev:  "v2.3.4", // badly-named branch (semver should be a tag)
-		info: &RevInfo{
-			Name:    "76a00fb249b7f93091bc2c89a789dab1fc1bc26f",
-			Short:   "76a00fb249b7",
-			Version: "76a00fb249b7f93091bc2c89a789dab1fc1bc26f",
-			Time:    time.Date(2018, 4, 17, 19, 45, 48, 0, time.UTC),
-			Tags:    []string{"v2.0.1", "v2.3"},
-		},
-	},
-	{
-		repo: gitrepo1,
-		rev:  "v2.3", // badly-named tag (we only respect full semver v2.3.0)
-		info: &RevInfo{
-			Name:    "76a00fb249b7f93091bc2c89a789dab1fc1bc26f",
-			Short:   "76a00fb249b7",
-			Version: "v2.3",
-			Time:    time.Date(2018, 4, 17, 19, 45, 48, 0, time.UTC),
-			Tags:    []string{"v2.0.1", "v2.3"},
-		},
-	},
-	{
-		repo: gitrepo1,
-		rev:  "v1.2.3", // tag
-		info: &RevInfo{
-			Name:    "ede458df7cd0fdca520df19a33158086a8a68e81",
-			Short:   "ede458df7cd0",
-			Version: "v1.2.3",
-			Time:    time.Date(2018, 4, 17, 19, 43, 22, 0, time.UTC),
-			Tags:    []string{"v1.2.3", "v1.2.4-annotated"},
-		},
-	},
-	{
-		repo: gitrepo1,
-		rev:  "ede458df", // hash prefix in refs
-		info: &RevInfo{
-			Name:    "ede458df7cd0fdca520df19a33158086a8a68e81",
-			Short:   "ede458df7cd0",
-			Version: "ede458df7cd0fdca520df19a33158086a8a68e81",
-			Time:    time.Date(2018, 4, 17, 19, 43, 22, 0, time.UTC),
-			Tags:    []string{"v1.2.3", "v1.2.4-annotated"},
-		},
-	},
-	{
-		repo: gitrepo1,
-		rev:  "97f6aa59", // hash prefix not in refs
-		info: &RevInfo{
-			Name:    "97f6aa59c81c623494825b43d39e445566e429a4",
-			Short:   "97f6aa59c81c",
-			Version: "97f6aa59c81c623494825b43d39e445566e429a4",
-			Time:    time.Date(2018, 4, 17, 20, 0, 19, 0, time.UTC),
-		},
-	},
-	{
-		repo: gitrepo1,
-		rev:  "v1.2.4-annotated", // annotated tag uses unwrapped commit hash
-		info: &RevInfo{
-			Name:    "ede458df7cd0fdca520df19a33158086a8a68e81",
-			Short:   "ede458df7cd0",
-			Version: "v1.2.4-annotated",
-			Time:    time.Date(2018, 4, 17, 19, 43, 22, 0, time.UTC),
-			Tags:    []string{"v1.2.3", "v1.2.4-annotated"},
-		},
-	},
-	{
-		repo: gitrepo1,
-		rev:  "aaaaaaaaab",
-		err:  "unknown revision",
-	},
-}
-
 func TestStat(t *testing.T) {
 	testenv.MustHaveExternalNetwork(t)
 	testenv.MustHaveExec(t)
+	t.Parallel()
 
-	for _, tt := range statTests {
-		f := func(t *testing.T) {
+	type statTest struct {
+		repo string
+		rev  string
+		err  string
+		info *RevInfo
+	}
+	runTest := func(tt statTest) func(*testing.T) {
+		return func(t *testing.T) {
+			t.Parallel()
+
 			r, err := testRepo(t, tt.repo)
 			if err != nil {
 				t.Fatal(err)
@@ -642,9 +600,105 @@
 				t.Errorf("Stat: incorrect info\nhave %+v\nwant %+v", *info, *tt.info)
 			}
 		}
-		t.Run(path.Base(tt.repo)+"/"+tt.rev, f)
+	}
+
+	for _, tt := range []statTest{
+		{
+			repo: gitrepo1,
+			rev:  "HEAD",
+			info: &RevInfo{
+				Name:    "ede458df7cd0fdca520df19a33158086a8a68e81",
+				Short:   "ede458df7cd0",
+				Version: "ede458df7cd0fdca520df19a33158086a8a68e81",
+				Time:    time.Date(2018, 4, 17, 19, 43, 22, 0, time.UTC),
+				Tags:    []string{"v1.2.3", "v1.2.4-annotated"},
+			},
+		},
+		{
+			repo: gitrepo1,
+			rev:  "v2", // branch
+			info: &RevInfo{
+				Name:    "9d02800338b8a55be062c838d1f02e0c5780b9eb",
+				Short:   "9d02800338b8",
+				Version: "9d02800338b8a55be062c838d1f02e0c5780b9eb",
+				Time:    time.Date(2018, 4, 17, 20, 00, 32, 0, time.UTC),
+				Tags:    []string{"v2.0.2"},
+			},
+		},
+		{
+			repo: gitrepo1,
+			rev:  "v2.3.4", // badly-named branch (semver should be a tag)
+			info: &RevInfo{
+				Name:    "76a00fb249b7f93091bc2c89a789dab1fc1bc26f",
+				Short:   "76a00fb249b7",
+				Version: "76a00fb249b7f93091bc2c89a789dab1fc1bc26f",
+				Time:    time.Date(2018, 4, 17, 19, 45, 48, 0, time.UTC),
+				Tags:    []string{"v2.0.1", "v2.3"},
+			},
+		},
+		{
+			repo: gitrepo1,
+			rev:  "v2.3", // badly-named tag (we only respect full semver v2.3.0)
+			info: &RevInfo{
+				Name:    "76a00fb249b7f93091bc2c89a789dab1fc1bc26f",
+				Short:   "76a00fb249b7",
+				Version: "v2.3",
+				Time:    time.Date(2018, 4, 17, 19, 45, 48, 0, time.UTC),
+				Tags:    []string{"v2.0.1", "v2.3"},
+			},
+		},
+		{
+			repo: gitrepo1,
+			rev:  "v1.2.3", // tag
+			info: &RevInfo{
+				Name:    "ede458df7cd0fdca520df19a33158086a8a68e81",
+				Short:   "ede458df7cd0",
+				Version: "v1.2.3",
+				Time:    time.Date(2018, 4, 17, 19, 43, 22, 0, time.UTC),
+				Tags:    []string{"v1.2.3", "v1.2.4-annotated"},
+			},
+		},
+		{
+			repo: gitrepo1,
+			rev:  "ede458df", // hash prefix in refs
+			info: &RevInfo{
+				Name:    "ede458df7cd0fdca520df19a33158086a8a68e81",
+				Short:   "ede458df7cd0",
+				Version: "ede458df7cd0fdca520df19a33158086a8a68e81",
+				Time:    time.Date(2018, 4, 17, 19, 43, 22, 0, time.UTC),
+				Tags:    []string{"v1.2.3", "v1.2.4-annotated"},
+			},
+		},
+		{
+			repo: gitrepo1,
+			rev:  "97f6aa59", // hash prefix not in refs
+			info: &RevInfo{
+				Name:    "97f6aa59c81c623494825b43d39e445566e429a4",
+				Short:   "97f6aa59c81c",
+				Version: "97f6aa59c81c623494825b43d39e445566e429a4",
+				Time:    time.Date(2018, 4, 17, 20, 0, 19, 0, time.UTC),
+			},
+		},
+		{
+			repo: gitrepo1,
+			rev:  "v1.2.4-annotated", // annotated tag uses unwrapped commit hash
+			info: &RevInfo{
+				Name:    "ede458df7cd0fdca520df19a33158086a8a68e81",
+				Short:   "ede458df7cd0",
+				Version: "v1.2.4-annotated",
+				Time:    time.Date(2018, 4, 17, 19, 43, 22, 0, time.UTC),
+				Tags:    []string{"v1.2.3", "v1.2.4-annotated"},
+			},
+		},
+		{
+			repo: gitrepo1,
+			rev:  "aaaaaaaaab",
+			err:  "unknown revision",
+		},
+	} {
+		t.Run(path.Base(tt.repo)+"/"+tt.rev, runTest(tt))
 		if tt.repo == gitrepo1 {
-			for _, tt.repo = range altRepos {
+			for _, tt.repo = range altRepos() {
 				old := tt
 				var m map[string]string
 				if tt.repo == hgrepo1 {
@@ -658,7 +712,7 @@
 					tt.info.Short = remap(tt.info.Short, m)
 				}
 				tt.rev = remap(tt.rev, m)
-				t.Run(path.Base(tt.repo)+"/"+tt.rev, f)
+				t.Run(path.Base(tt.repo)+"/"+tt.rev, runTest(tt))
 				tt = old
 			}
 		}
diff --git a/src/cmd/go/internal/modfetch/codehost/vcs.go b/src/cmd/go/internal/modfetch/codehost/vcs.go
index f1c4099..300a23c 100644
--- a/src/cmd/go/internal/modfetch/codehost/vcs.go
+++ b/src/cmd/go/internal/modfetch/codehost/vcs.go
@@ -38,6 +38,8 @@
 
 func (e *VCSError) Error() string { return e.Err.Error() }
 
+func (e *VCSError) Unwrap() error { return e.Err }
+
 func vcsErrorf(format string, a ...any) error {
 	return &VCSError{Err: fmt.Errorf(format, a...)}
 }
@@ -290,10 +292,8 @@
 	}
 }
 
-var ErrNoRepoHash = errors.New("RepoHash not supported")
-
 func (r *vcsRepo) CheckReuse(old *Origin, subdir string) error {
-	return fmt.Errorf("vcs %s does not implement CheckReuse", r.cmd.vcs)
+	return fmt.Errorf("vcs %s: CheckReuse: %w", r.cmd.vcs, ErrUnsupported)
 }
 
 func (r *vcsRepo) Tags(prefix string) (*Tags, error) {
@@ -417,7 +417,7 @@
 	}
 	defer unlock()
 
-	return "", vcsErrorf("RecentTag not implemented")
+	return "", vcsErrorf("vcs %s: RecentTag: %w", r.cmd.vcs, ErrUnsupported)
 }
 
 func (r *vcsRepo) DescendsFrom(rev, tag string) (bool, error) {
@@ -427,12 +427,12 @@
 	}
 	defer unlock()
 
-	return false, vcsErrorf("DescendsFrom not implemented")
+	return false, vcsErrorf("vcs %s: DescendsFrom: %w", r.cmd.vcs, ErrUnsupported)
 }
 
 func (r *vcsRepo) ReadZip(rev, subdir string, maxSize int64) (zip io.ReadCloser, err error) {
 	if r.cmd.readZip == nil && r.cmd.doReadZip == nil {
-		return nil, vcsErrorf("ReadZip not implemented for %s", r.cmd.vcs)
+		return nil, vcsErrorf("vcs %s: ReadZip: %w", r.cmd.vcs, ErrUnsupported)
 	}
 
 	unlock, err := r.mu.Lock()
@@ -539,12 +539,12 @@
 		if line[0] == '-' {
 			continue
 		}
-		i := strings.Index(line, ":")
-		if i < 0 {
+		before, after, found := strings.Cut(line, ":")
+		if !found {
 			// End of header, start of commit message.
 			break
 		}
-		key, val := line[:i], strings.TrimSpace(line[i+1:])
+		key, val := before, strings.TrimSpace(after)
 		switch key {
 		case "revno":
 			if j := strings.Index(val, " "); j >= 0 {
@@ -587,7 +587,7 @@
 			if len(f) != 5 || len(f[1]) != 40 || f[4] != "UTC" {
 				return nil, vcsErrorf("unexpected response from fossil info: %q", line)
 			}
-			t, err := time.Parse("2006-01-02 15:04:05", f[2]+" "+f[3])
+			t, err := time.Parse(time.DateTime, f[2]+" "+f[3])
 			if err != nil {
 				return nil, vcsErrorf("unexpected response from fossil info: %q", line)
 			}
diff --git a/src/cmd/go/internal/modfetch/coderepo.go b/src/cmd/go/internal/modfetch/coderepo.go
index 8fb0035..04164ff 100644
--- a/src/cmd/go/internal/modfetch/coderepo.go
+++ b/src/cmd/go/internal/modfetch/coderepo.go
@@ -607,7 +607,10 @@
 		return !isRetracted(v)
 	}
 	if pseudoBase == "" {
-		tag, _ := r.code.RecentTag(info.Name, tagPrefix, tagAllowed)
+		tag, err := r.code.RecentTag(info.Name, tagPrefix, tagAllowed)
+		if err != nil && !errors.Is(err, codehost.ErrUnsupported) {
+			return nil, err
+		}
 		if tag != "" {
 			pseudoBase, _ = tagToVersion(tag)
 		}
@@ -959,7 +962,7 @@
 // for dependencies in the middle of a build, impossible to
 // correct. So we stopped.
 func LegacyGoMod(modPath string) []byte {
-	return []byte(fmt.Sprintf("module %s\n", modfile.AutoQuote(modPath)))
+	return fmt.Appendf(nil, "module %s\n", modfile.AutoQuote(modPath))
 }
 
 func (r *codeRepo) modPrefix(rev string) string {
@@ -1092,14 +1095,16 @@
 			}
 			topPrefix = zf.Name[:i+1]
 		}
-		if !strings.HasPrefix(zf.Name, topPrefix) {
+		var name string
+		var found bool
+		if name, found = strings.CutPrefix(zf.Name, topPrefix); !found {
 			return fmt.Errorf("zip file contains more than one top-level directory")
 		}
-		name := strings.TrimPrefix(zf.Name, topPrefix)
-		if !strings.HasPrefix(name, subdir) {
+
+		if name, found = strings.CutPrefix(name, subdir); !found {
 			continue
 		}
-		name = strings.TrimPrefix(name, subdir)
+
 		if name == "" || strings.HasSuffix(name, "/") {
 			continue
 		}
diff --git a/src/cmd/go/internal/modfetch/coderepo_test.go b/src/cmd/go/internal/modfetch/coderepo_test.go
index 967978c..8ccd9b2 100644
--- a/src/cmd/go/internal/modfetch/coderepo_test.go
+++ b/src/cmd/go/internal/modfetch/coderepo_test.go
@@ -8,11 +8,13 @@
 	"archive/zip"
 	"crypto/sha256"
 	"encoding/hex"
+	"flag"
 	"hash"
 	"internal/testenv"
 	"io"
 	"log"
 	"os"
+	"path/filepath"
 	"reflect"
 	"strings"
 	"testing"
@@ -20,15 +22,20 @@
 
 	"cmd/go/internal/cfg"
 	"cmd/go/internal/modfetch/codehost"
+	"cmd/go/internal/vcweb/vcstest"
 
 	"golang.org/x/mod/sumdb/dirhash"
 )
 
 func TestMain(m *testing.M) {
-	os.Exit(testMain(m))
+	flag.Parse()
+	if err := testMain(m); err != nil {
+		log.Fatal(err)
+	}
 }
 
-func testMain(m *testing.M) int {
+func testMain(m *testing.M) (err error) {
+
 	cfg.GOPROXY = "direct"
 
 	// The sum database is populated using a released version of the go command,
@@ -39,12 +46,31 @@
 
 	dir, err := os.MkdirTemp("", "gitrepo-test-")
 	if err != nil {
-		log.Fatal(err)
+		return err
 	}
-	defer os.RemoveAll(dir)
+	defer func() {
+		if rmErr := os.RemoveAll(dir); err == nil {
+			err = rmErr
+		}
+	}()
 
-	cfg.GOMODCACHE = dir
-	return m.Run()
+	cfg.GOMODCACHE = filepath.Join(dir, "modcache")
+	if err := os.Mkdir(cfg.GOMODCACHE, 0755); err != nil {
+		return err
+	}
+
+	srv, err := vcstest.NewServer()
+	if err != nil {
+		return err
+	}
+	defer func() {
+		if closeErr := srv.Close(); err == nil {
+			err = closeErr
+		}
+	}()
+
+	m.Run()
+	return nil
 }
 
 const (
@@ -379,18 +405,6 @@
 		zipFileHash: "c15e49d58b7a4c37966cbe5bc01a0330cd5f2927e990e1839bda1d407766d9c5",
 	},
 	{
-		vcs:         "git",
-		path:        "gopkg.in/natefinch/lumberjack.v2",
-		rev:         "latest",
-		version:     "v2.0.0-20170531160350-a96e63847dc3",
-		name:        "a96e63847dc3c67d17befa69c303767e2f84e54f",
-		short:       "a96e63847dc3",
-		time:        time.Date(2017, 5, 31, 16, 3, 50, 0, time.UTC),
-		gomod:       "module gopkg.in/natefinch/lumberjack.v2\n",
-		zipSum:      "h1:AFxeG48hTWHhDTQDk/m2gorfVHUEa9vo3tp3D7TzwjI=",
-		zipFileHash: "b5de0da7bbbec76709eef1ac71b6c9ff423b9fbf3bb97b56743450d4937b06d5",
-	},
-	{
 		vcs:  "git",
 		path: "gopkg.in/natefinch/lumberjack.v2",
 		// This repo has a v2.1 tag.
@@ -578,6 +592,10 @@
 	for _, tt := range codeRepoTests {
 		f := func(tt codeRepoTest) func(t *testing.T) {
 			return func(t *testing.T) {
+				if strings.Contains(tt.path, "gopkg.in") {
+					testenv.SkipFlaky(t, 54503)
+				}
+
 				t.Parallel()
 				if tt.vcs != "mod" {
 					testenv.MustHaveExecPath(t, tt.vcs)
@@ -790,11 +808,6 @@
 	},
 	{
 		vcs:      "git",
-		path:     "gopkg.in/natefinch/lumberjack.v2",
-		versions: []string{"v2.0.0"},
-	},
-	{
-		vcs:      "git",
 		path:     "vcs-test.golang.org/git/odd-tags.git",
 		versions: nil,
 	},
@@ -811,8 +824,12 @@
 
 	t.Run("parallel", func(t *testing.T) {
 		for _, tt := range codeRepoVersionsTests {
+			tt := tt
 			t.Run(strings.ReplaceAll(tt.path, "/", "_"), func(t *testing.T) {
-				tt := tt
+				if strings.Contains(tt.path, "gopkg.in") {
+					testenv.SkipFlaky(t, 54503)
+				}
+
 				t.Parallel()
 				if tt.vcs != "mod" {
 					testenv.MustHaveExecPath(t, tt.vcs)
diff --git a/src/cmd/go/internal/modfetch/fetch.go b/src/cmd/go/internal/modfetch/fetch.go
index 2e8c4c8..dfe5da6 100644
--- a/src/cmd/go/internal/modfetch/fetch.go
+++ b/src/cmd/go/internal/modfetch/fetch.go
@@ -408,7 +408,7 @@
 }
 
 // Reset resets globals in the modfetch package, so previous loads don't affect
-// contents of go.sum files
+// contents of go.sum files.
 func Reset() {
 	GoSumFile = ""
 	WorkspaceGoSumFiles = nil
@@ -698,9 +698,9 @@
 func checkSumDB(mod module.Version, h string) error {
 	modWithoutSuffix := mod
 	noun := "module"
-	if strings.HasSuffix(mod.Version, "/go.mod") {
+	if before, found := strings.CutSuffix(mod.Version, "/go.mod"); found {
 		noun = "go.mod"
-		modWithoutSuffix.Version = strings.TrimSuffix(mod.Version, "/go.mod")
+		modWithoutSuffix.Version = before
 	}
 
 	db, lines, err := lookupSumDB(mod)
diff --git a/src/cmd/go/internal/modget/query.go b/src/cmd/go/internal/modget/query.go
index 887cb51..d18770e 100644
--- a/src/cmd/go/internal/modget/query.go
+++ b/src/cmd/go/internal/modget/query.go
@@ -15,6 +15,7 @@
 	"cmd/go/internal/modload"
 	"cmd/go/internal/search"
 	"cmd/go/internal/str"
+	"cmd/internal/pkgpattern"
 
 	"golang.org/x/mod/module"
 )
@@ -137,13 +138,9 @@
 // newQuery returns a new query parsed from the raw argument,
 // which must be either path or path@version.
 func newQuery(raw string) (*query, error) {
-	pattern := raw
-	rawVers := ""
-	if i := strings.Index(raw, "@"); i >= 0 {
-		pattern, rawVers = raw[:i], raw[i+1:]
-		if strings.Contains(rawVers, "@") || rawVers == "" {
-			return nil, fmt.Errorf("invalid module version syntax %q", raw)
-		}
+	pattern, rawVers, found := strings.Cut(raw, "@")
+	if found && (strings.Contains(rawVers, "@") || rawVers == "") {
+		return nil, fmt.Errorf("invalid module version syntax %q", raw)
 	}
 
 	// If no version suffix is specified, assume @upgrade.
@@ -165,8 +162,8 @@
 		version:        version,
 	}
 	if strings.Contains(q.pattern, "...") {
-		q.matchWildcard = search.MatchPattern(q.pattern)
-		q.canMatchWildcardInModule = search.TreeCanMatchPattern(q.pattern)
+		q.matchWildcard = pkgpattern.MatchPattern(q.pattern)
+		q.canMatchWildcardInModule = pkgpattern.TreeCanMatchPattern(q.pattern)
 	}
 	if err := q.validate(); err != nil {
 		return q, err
diff --git a/src/cmd/go/internal/modindex/build.go b/src/cmd/go/internal/modindex/build.go
index d6d4ea3..e438097 100644
--- a/src/cmd/go/internal/modindex/build.go
+++ b/src/cmd/go/internal/modindex/build.go
@@ -477,6 +477,8 @@
 	pos     token.Position
 }
 
+var errNonSource = errors.New("non source file")
+
 // getFileInfo extracts the information needed from each go file for the module
 // index.
 //
@@ -484,6 +486,9 @@
 // Imports and returns that section of the file in the FileInfo's Header field,
 // even though it only considers text until the first non-comment
 // for +build lines.
+//
+// getFileInfo will return errNonSource if the file is not a source or object
+// file and shouldn't even be added to IgnoredFiles.
 func getFileInfo(dir, name string, fset *token.FileSet) (*fileInfo, error) {
 	if strings.HasPrefix(name, "_") ||
 		strings.HasPrefix(name, ".") {
@@ -498,7 +503,7 @@
 
 	if ext != ".go" && fileListForExt(&dummyPkg, ext) == nil {
 		// skip
-		return nil, nil
+		return nil, errNonSource
 	}
 
 	info := &fileInfo{name: filepath.Join(dir, name), fset: fset}
@@ -558,8 +563,7 @@
 
 	goBuildComment = []byte("//go:build")
 
-	errGoBuildWithoutBuild = errors.New("//go:build comment without // +build comment")
-	errMultipleGoBuild     = errors.New("multiple //go:build comments")
+	errMultipleGoBuild = errors.New("multiple //go:build comments")
 )
 
 func isGoBuildComment(line []byte) bool {
diff --git a/src/cmd/go/internal/modindex/index_test.go b/src/cmd/go/internal/modindex/index_test.go
index 2c072f9..6bc62f3 100644
--- a/src/cmd/go/internal/modindex/index_test.go
+++ b/src/cmd/go/internal/modindex/index_test.go
@@ -28,7 +28,7 @@
 		if err != nil {
 			t.Fatal(err)
 		}
-		bp1, err := build.Default.Import(pkg, filepath.Join(src, pkg), build.ImportComment)
+		bp1, err := build.Default.Import(".", filepath.Join(src, pkg), build.ImportComment)
 		if err != nil {
 			t.Fatal(err)
 		}
@@ -85,3 +85,20 @@
 		}
 	})
 }
+
+func TestImportRaw_IgnoreNonGo(t *testing.T) {
+	path := filepath.Join("testdata", "ignore_non_source")
+	p := importRaw(path, ".")
+
+	wantFiles := []string{"a.syso", "b.go", "c.c"}
+
+	var gotFiles []string
+	for i := range p.sourceFiles {
+		gotFiles = append(gotFiles, p.sourceFiles[i].name)
+	}
+
+	if !reflect.DeepEqual(gotFiles, wantFiles) {
+		t.Errorf("names of files in importRaw(testdata/ignore_non_source): got %v; want %v",
+			gotFiles, wantFiles)
+	}
+}
diff --git a/src/cmd/go/internal/modindex/read.go b/src/cmd/go/internal/modindex/read.go
index 707f17e..7c4fa7a 100644
--- a/src/cmd/go/internal/modindex/read.go
+++ b/src/cmd/go/internal/modindex/read.go
@@ -14,7 +14,6 @@
 	"go/token"
 	"internal/godebug"
 	"internal/goroot"
-	"internal/unsafeheader"
 	"path"
 	"path/filepath"
 	"runtime"
@@ -38,7 +37,7 @@
 // It will be removed before the release.
 // TODO(matloob): Remove enabled once we have more confidence on the
 // module index.
-var enabled bool = godebug.Get("goindex") != "0"
+var enabled = godebug.New("goindex").Value() != "0"
 
 // Module represents and encoded module index file. It is used to
 // do the equivalent of build.Import of packages in the module and answer other
@@ -369,6 +368,8 @@
 	return str.TrimFilePathPrefix(filepath.Clean(path), filepath.Clean(modroot))
 }
 
+var installgorootAll = godebug.New("installgoroot").Value() == "all"
+
 // Import is the equivalent of build.Import given the information in Module.
 func (rp *IndexPackage) Import(bctxt build.Context, mode build.ImportMode) (p *build.Package, err error) {
 	defer unprotect(protect(), &err)
@@ -396,15 +397,12 @@
 	inTestdata := func(sub string) bool {
 		return strings.Contains(sub, "/testdata/") || strings.HasSuffix(sub, "/testdata") || str.HasPathPrefix(sub, "testdata")
 	}
+	var pkga string
 	if !inTestdata(rp.dir) {
 		// In build.go, p.Root should only be set in the non-local-import case, or in
 		// GOROOT or GOPATH. Since module mode only calls Import with path set to "."
 		// and the module index doesn't apply outside modules, the GOROOT case is
-		// the only case where GOROOT needs to be set.
-		// But: p.Root is actually set in the local-import case outside GOROOT, if
-		// the directory is contained in GOPATH/src
-		// TODO(#37015): fix that behavior in go/build and remove the gopath case
-		// below.
+		// the only case where p.Root needs to be set.
 		if ctxt.GOROOT != "" && str.HasFilePathPrefix(p.Dir, cfg.GOROOTsrc) && p.Dir != cfg.GOROOTsrc {
 			p.Root = ctxt.GOROOT
 			p.Goroot = true
@@ -413,47 +411,37 @@
 			if modprefix != "" {
 				p.ImportPath = filepath.Join(modprefix, p.ImportPath)
 			}
-		}
-		for _, root := range ctxt.gopath() {
-			// TODO(matloob): do we need to reimplement the conflictdir logic?
 
-			// TODO(matloob): ctxt.hasSubdir evaluates symlinks, so it
-			// can be slower than we'd like. Find out if we can drop this
-			// logic before the release.
-			if sub, ok := ctxt.hasSubdir(filepath.Join(root, "src"), p.Dir); ok {
-				p.ImportPath = sub
-				p.Root = root
+			// Set GOROOT-specific fields (sometimes for modules in a GOPATH directory).
+			// The fields set below (SrcRoot, PkgRoot, BinDir, PkgTargetRoot, and PkgObj)
+			// are only set in build.Import if p.Root != "".
+			var pkgtargetroot string
+			suffix := ""
+			if ctxt.InstallSuffix != "" {
+				suffix = "_" + ctxt.InstallSuffix
 			}
-		}
-	}
-	if p.Root != "" {
-		// Set GOROOT-specific fields (sometimes for modules in a GOPATH directory).
-		// The fields set below (SrcRoot, PkgRoot, BinDir, PkgTargetRoot, and PkgObj)
-		// are only set in build.Import if p.Root != "". As noted in the comment
-		// on setting p.Root above, p.Root should only be set in the GOROOT case for the
-		// set of packages we care about, but is also set for modules in a GOPATH src
-		// directory.
-		var pkgtargetroot string
-		var pkga string
-		suffix := ""
-		if ctxt.InstallSuffix != "" {
-			suffix = "_" + ctxt.InstallSuffix
-		}
-		switch ctxt.Compiler {
-		case "gccgo":
-			pkgtargetroot = "pkg/gccgo_" + ctxt.GOOS + "_" + ctxt.GOARCH + suffix
-			dir, elem := path.Split(p.ImportPath)
-			pkga = pkgtargetroot + "/" + dir + "lib" + elem + ".a"
-		case "gc":
-			pkgtargetroot = "pkg/" + ctxt.GOOS + "_" + ctxt.GOARCH + suffix
-			pkga = pkgtargetroot + "/" + p.ImportPath + ".a"
-		}
-		p.SrcRoot = ctxt.joinPath(p.Root, "src")
-		p.PkgRoot = ctxt.joinPath(p.Root, "pkg")
-		p.BinDir = ctxt.joinPath(p.Root, "bin")
-		if pkga != "" {
-			p.PkgTargetRoot = ctxt.joinPath(p.Root, pkgtargetroot)
-			p.PkgObj = ctxt.joinPath(p.Root, pkga)
+			switch ctxt.Compiler {
+			case "gccgo":
+				pkgtargetroot = "pkg/gccgo_" + ctxt.GOOS + "_" + ctxt.GOARCH + suffix
+				dir, elem := path.Split(p.ImportPath)
+				pkga = pkgtargetroot + "/" + dir + "lib" + elem + ".a"
+			case "gc":
+				pkgtargetroot = "pkg/" + ctxt.GOOS + "_" + ctxt.GOARCH + suffix
+				pkga = pkgtargetroot + "/" + p.ImportPath + ".a"
+			}
+			p.SrcRoot = ctxt.joinPath(p.Root, "src")
+			p.PkgRoot = ctxt.joinPath(p.Root, "pkg")
+			p.BinDir = ctxt.joinPath(p.Root, "bin")
+			if pkga != "" {
+				// Always set PkgTargetRoot. It might be used when building in shared
+				// mode.
+				p.PkgTargetRoot = ctxt.joinPath(p.Root, pkgtargetroot)
+
+				// Set the install target if applicable.
+				if !p.Goroot || (installgorootAll && p.ImportPath != "unsafe" && p.ImportPath != "builtin") {
+					p.PkgObj = ctxt.joinPath(p.Root, pkga)
+				}
+			}
 		}
 	}
 
@@ -470,14 +458,14 @@
 
 	// We need to do a second round of bad file processing.
 	var badGoError error
-	badFiles := make(map[string]bool)
-	badFile := func(name string, err error) {
+	badGoFiles := make(map[string]bool)
+	badGoFile := func(name string, err error) {
 		if badGoError == nil {
 			badGoError = err
 		}
-		if !badFiles[name] {
+		if !badGoFiles[name] {
 			p.InvalidGoFiles = append(p.InvalidGoFiles, name)
-			badFiles[name] = true
+			badGoFiles[name] = true
 		}
 	}
 
@@ -492,12 +480,16 @@
 	allTags := make(map[string]bool)
 	for _, tf := range rp.sourceFiles {
 		name := tf.name()
-		if error := tf.error(); error != "" {
-			badFile(name, errors.New(tf.error()))
-			continue
-		} else if parseError := tf.parseError(); parseError != "" {
-			badFile(name, parseErrorFromString(tf.parseError()))
-			// Fall through: we still want to list files with parse errors.
+		// Check errors for go files and call badGoFiles to put them in
+		// InvalidGoFiles if they do have an error.
+		if strings.HasSuffix(name, ".go") {
+			if error := tf.error(); error != "" {
+				badGoFile(name, errors.New(tf.error()))
+				continue
+			} else if parseError := tf.parseError(); parseError != "" {
+				badGoFile(name, parseErrorFromString(tf.parseError()))
+				// Fall through: we still want to list files with parse errors.
+			}
 		}
 
 		var shouldBuild = true
@@ -567,7 +559,7 @@
 			// TODO(#45999): The choice of p.Name is arbitrary based on file iteration
 			// order. Instead of resolving p.Name arbitrarily, we should clear out the
 			// existing Name and mark the existing files as also invalid.
-			badFile(name, &MultiplePackageError{
+			badGoFile(name, &MultiplePackageError{
 				Dir:      p.Dir,
 				Packages: []string{p.Name, pkg},
 				Files:    []string{firstFile, name},
@@ -586,7 +578,7 @@
 		for _, imp := range imports {
 			if imp.path == "C" {
 				if isTest {
-					badFile(name, fmt.Errorf("use of cgo in test %s not supported", name))
+					badGoFile(name, fmt.Errorf("use of cgo in test %s not supported", name))
 					continue
 				}
 				isCgo = true
@@ -594,7 +586,7 @@
 		}
 		if directives := tf.cgoDirectives(); directives != "" {
 			if err := ctxt.saveCgo(name, (*Package)(p), directives); err != nil {
-				badFile(name, err)
+				badGoFile(name, err)
 			}
 		}
 
@@ -789,7 +781,7 @@
 	plusBuildConstraints := sf.plusBuildConstraints()
 	for _, text := range plusBuildConstraints {
 		if x, err := constraint.Parse(text); err == nil {
-			if imports.Eval(x, tags, true) == false {
+			if !imports.Eval(x, tags, true) {
 				return false
 			}
 		}
@@ -948,14 +940,7 @@
 }
 
 func asString(b []byte) string {
-	p := (*unsafeheader.Slice)(unsafe.Pointer(&b)).Data
-
-	var s string
-	hdr := (*unsafeheader.String)(unsafe.Pointer(&s))
-	hdr.Data = p
-	hdr.Len = len(b)
-
-	return s
+	return unsafe.String(unsafe.SliceData(b), len(b))
 }
 
 // A decoder helps decode the index format.
diff --git a/src/cmd/go/internal/modindex/scan.go b/src/cmd/go/internal/modindex/scan.go
index d3f059b..712257a 100644
--- a/src/cmd/go/internal/modindex/scan.go
+++ b/src/cmd/go/internal/modindex/scan.go
@@ -1,3 +1,7 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
 package modindex
 
 import (
@@ -69,7 +73,7 @@
 	return encodeModuleBytes(packages), nil
 }
 
-// indexModule indexes the package at the given directory and returns its
+// indexPackage indexes the package at the given directory and returns its
 // encoded representation. It returns ErrNotIndexed if the package can't
 // be indexed.
 func indexPackage(modroot, pkgdir string) []byte {
@@ -115,7 +119,7 @@
 	return string(s)
 }
 
-// parseErrorFrom string converts a string produced by parseErrorToString back
+// parseErrorFromString converts a string produced by parseErrorToString back
 // to an error.  An empty string is converted to a nil error, and all
 // other strings are expected to be JSON-marshalled parseError structs.
 // The two functions are meant to preserve the structure of an
@@ -210,7 +214,10 @@
 			continue
 		}
 		info, err := getFileInfo(absdir, name, fset)
-		if err != nil {
+		if err == errNonSource {
+			// not a source or object file. completely ignore in the index
+			continue
+		} else if err != nil {
 			p.sourceFiles = append(p.sourceFiles, &rawFile{name: name, error: err.Error()})
 			continue
 		} else if info == nil {
diff --git a/src/cmd/go/internal/modindex/testdata/ignore_non_source/a.syso b/src/cmd/go/internal/modindex/testdata/ignore_non_source/a.syso
new file mode 100644
index 0000000..9527d05
--- /dev/null
+++ b/src/cmd/go/internal/modindex/testdata/ignore_non_source/a.syso
@@ -0,0 +1 @@
+package ignore_non_source
diff --git a/src/cmd/go/internal/modindex/testdata/ignore_non_source/b.go b/src/cmd/go/internal/modindex/testdata/ignore_non_source/b.go
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/cmd/go/internal/modindex/testdata/ignore_non_source/b.go
diff --git a/src/cmd/go/internal/modindex/testdata/ignore_non_source/bar.json b/src/cmd/go/internal/modindex/testdata/ignore_non_source/bar.json
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/cmd/go/internal/modindex/testdata/ignore_non_source/bar.json
diff --git a/src/cmd/go/internal/modindex/testdata/ignore_non_source/baz.log b/src/cmd/go/internal/modindex/testdata/ignore_non_source/baz.log
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/cmd/go/internal/modindex/testdata/ignore_non_source/baz.log
diff --git a/src/cmd/go/internal/modindex/testdata/ignore_non_source/c.c b/src/cmd/go/internal/modindex/testdata/ignore_non_source/c.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/cmd/go/internal/modindex/testdata/ignore_non_source/c.c
diff --git a/src/cmd/go/internal/modindex/write.go b/src/cmd/go/internal/modindex/write.go
index 7db1fb0..df1467d 100644
--- a/src/cmd/go/internal/modindex/write.go
+++ b/src/cmd/go/internal/modindex/write.go
@@ -126,7 +126,7 @@
 	e.strings[s] = pos
 	e.Int(pos)
 	e.stringTable = binary.AppendUvarint(e.stringTable, uint64(len(s)))
-	e.stringTable = append(e.stringTable, []byte(s)...)
+	e.stringTable = append(e.stringTable, s...)
 }
 
 func (e *encoder) Bool(b bool) {
diff --git a/src/cmd/go/internal/modload/build.go b/src/cmd/go/internal/modload/build.go
index 555d4b3..30b248e 100644
--- a/src/cmd/go/internal/modload/build.go
+++ b/src/cmd/go/internal/modload/build.go
@@ -76,8 +76,7 @@
 	if !ok {
 		return ""
 	}
-	const needSum = true
-	root, _, err := fetch(ctx, m, needSum)
+	root, _, err := fetch(ctx, m)
 	if err != nil {
 		return ""
 	}
@@ -89,8 +88,8 @@
 		return nil
 	}
 
-	if i := strings.Index(path, "@"); i >= 0 {
-		m := module.Version{Path: path[:i], Version: path[i+1:]}
+	if path, vers, found := strings.Cut(path, "@"); found {
+		m := module.Version{Path: path, Version: vers}
 		return moduleInfo(ctx, nil, m, 0, nil)
 	}
 
@@ -182,23 +181,27 @@
 	if !m2.Checkable() {
 		return m2
 	}
+
+	merged := new(codehost.Origin)
+	*merged = *m1 // Clone to avoid overwriting fields in cached results.
+
 	if m2.TagSum != "" {
 		if m1.TagSum != "" && (m1.TagSum != m2.TagSum || m1.TagPrefix != m2.TagPrefix) {
-			m1.ClearCheckable()
-			return m1
+			merged.ClearCheckable()
+			return merged
 		}
-		m1.TagSum = m2.TagSum
-		m1.TagPrefix = m2.TagPrefix
+		merged.TagSum = m2.TagSum
+		merged.TagPrefix = m2.TagPrefix
 	}
 	if m2.Hash != "" {
 		if m1.Hash != "" && (m1.Hash != m2.Hash || m1.Ref != m2.Ref) {
-			m1.ClearCheckable()
-			return m1
+			merged.ClearCheckable()
+			return merged
 		}
-		m1.Hash = m2.Hash
-		m1.Ref = m2.Ref
+		merged.Hash = m2.Hash
+		merged.Ref = m2.Ref
 	}
-	return m1
+	return merged
 }
 
 // addVersions fills in m.Versions with the list of known versions.
@@ -316,7 +319,7 @@
 		}
 
 		checksumOk := func(suffix string) bool {
-			return rs == nil || m.Version == "" || cfg.BuildMod == "mod" ||
+			return rs == nil || m.Version == "" || !mustHaveSums() ||
 				modfetch.HaveSum(module.Version{Path: m.Path, Version: m.Version + suffix})
 		}
 
@@ -427,12 +430,12 @@
 	// look at the module info in their init functions (see issue 29628),
 	// which won't work. See also issue 30344.
 	if isgccgo {
-		return []byte(fmt.Sprintf(`package main
+		return fmt.Appendf(nil, `package main
 import _ "unsafe"
 //go:linkname __set_debug_modinfo__ runtime.setmodinfo
 func __set_debug_modinfo__(string)
 func init() { __set_debug_modinfo__(%q) }
-`, ModInfoData(info)))
+`, ModInfoData(info))
 	}
 	return nil
 }
diff --git a/src/cmd/go/internal/modload/buildlist.go b/src/cmd/go/internal/modload/buildlist.go
index cde4953..aa59611 100644
--- a/src/cmd/go/internal/modload/buildlist.go
+++ b/src/cmd/go/internal/modload/buildlist.go
@@ -73,8 +73,8 @@
 	// nested module back into a parent module).
 	direct map[string]bool
 
-	graphOnce sync.Once    // guards writes to (but not reads from) graph
-	graph     atomic.Value // cachedGraph
+	graphOnce sync.Once // guards writes to (but not reads from) graph
+	graph     atomic.Pointer[cachedGraph]
 }
 
 // A cachedGraph is a non-nil *ModuleGraph, together with any error discovered
@@ -199,7 +199,7 @@
 			mg.g.Require(vendorMod, vendorList)
 		}
 
-		rs.graph.Store(cachedGraph{mg, nil})
+		rs.graph.Store(&cachedGraph{mg, nil})
 	})
 }
 
@@ -240,9 +240,9 @@
 func (rs *Requirements) Graph(ctx context.Context) (*ModuleGraph, error) {
 	rs.graphOnce.Do(func() {
 		mg, mgErr := readModGraph(ctx, rs.pruning, rs.rootModules)
-		rs.graph.Store(cachedGraph{mg, mgErr})
+		rs.graph.Store(&cachedGraph{mg, mgErr})
 	})
-	cached := rs.graph.Load().(cachedGraph)
+	cached := rs.graph.Load()
 	return cached.mg, cached.err
 }
 
diff --git a/src/cmd/go/internal/modload/import.go b/src/cmd/go/internal/modload/import.go
index f2c7592..2815ba9 100644
--- a/src/cmd/go/internal/modload/import.go
+++ b/src/cmd/go/internal/modload/import.go
@@ -41,6 +41,10 @@
 	// modules.
 	isStd bool
 
+	// importerGoVersion is the version the module containing the import error
+	// specified. It is only set when isStd is true.
+	importerGoVersion string
+
 	// replaced the highest replaced version of the module where the replacement
 	// contains the package. replaced is only set if the replacement is unused.
 	replaced module.Version
@@ -53,7 +57,11 @@
 func (e *ImportMissingError) Error() string {
 	if e.Module.Path == "" {
 		if e.isStd {
-			return fmt.Sprintf("package %s is not in GOROOT (%s)", e.Path, filepath.Join(cfg.GOROOT, "src", e.Path))
+			msg := fmt.Sprintf("package %s is not in GOROOT (%s)", e.Path, filepath.Join(cfg.GOROOT, "src", e.Path))
+			if e.importerGoVersion != "" {
+				msg += fmt.Sprintf("\nnote: imported by a module that requires go %s", e.importerGoVersion)
+			}
+			return msg
 		}
 		if e.QueryErr != nil && e.QueryErr != ErrNoModRoot {
 			return fmt.Sprintf("cannot find module providing package %s: %v", e.Path, e.QueryErr)
@@ -278,6 +286,10 @@
 		return module.Version{}, "", "", nil, &invalidImportError{importPath: path, err: err}
 	}
 
+	// Check each module on the build list.
+	var dirs, roots []string
+	var mods []module.Version
+
 	// Is the package in the standard library?
 	pathIsStd := search.IsStandardImportPath(path)
 	if pathIsStd && modindex.IsStandardPackage(cfg.GOROOT, cfg.BuildContext.Compiler, path) {
@@ -295,35 +307,47 @@
 		if str.HasPathPrefix(path, "cmd") {
 			modroot = filepath.Join(cfg.GOROOTsrc, "cmd")
 		}
-		return module.Version{}, modroot, dir, nil, nil
+		dirs = append(dirs, dir)
+		roots = append(roots, modroot)
+		mods = append(mods, module.Version{})
 	}
-
 	// -mod=vendor is special.
 	// Everything must be in the main module or the main module's vendor directory.
 	if cfg.BuildMod == "vendor" {
 		mainModule := MainModules.mustGetSingleMainModule()
 		modRoot := MainModules.ModRoot(mainModule)
-		mainDir, mainOK, mainErr := dirInModule(path, MainModules.PathPrefix(mainModule), modRoot, true)
-		vendorDir, vendorOK, _ := dirInModule(path, "", filepath.Join(modRoot, "vendor"), false)
-		if mainOK && vendorOK {
-			return module.Version{}, modRoot, "", nil, &AmbiguousImportError{importPath: path, Dirs: []string{mainDir, vendorDir}}
+		var mainErr error
+		if modRoot != "" {
+			mainDir, mainOK, err := dirInModule(path, MainModules.PathPrefix(mainModule), modRoot, true)
+			mainErr = err
+			if mainOK {
+				mods = append(mods, mainModule)
+				dirs = append(dirs, mainDir)
+				roots = append(roots, modRoot)
+			}
+			vendorDir, vendorOK, _ := dirInModule(path, "", filepath.Join(modRoot, "vendor"), false)
+			if vendorOK {
+				readVendorList(mainModule)
+				mods = append(mods, vendorPkgModule[path])
+				dirs = append(dirs, vendorDir)
+				roots = append(roots, modRoot)
+			}
 		}
-		// Prefer to return main directory if there is one,
-		// Note that we're not checking that the package exists.
-		// We'll leave that for load.
-		if !vendorOK && mainDir != "" {
-			return mainModule, modRoot, mainDir, nil, nil
+
+		if len(dirs) > 1 {
+			return module.Version{}, modRoot, "", nil, &AmbiguousImportError{importPath: path, Dirs: dirs}
 		}
+
 		if mainErr != nil {
 			return module.Version{}, "", "", nil, mainErr
 		}
-		readVendorList(mainModule)
-		return vendorPkgModule[path], modRoot, vendorDir, nil, nil
-	}
 
-	// Check each module on the build list.
-	var dirs, roots []string
-	var mods []module.Version
+		if len(dirs) == 0 {
+			return module.Version{}, modRoot, "", nil, &ImportMissingError{Path: path}
+		}
+
+		return mods[0], roots[0], dirs[0], nil, nil
+	}
 
 	// Iterate over possible modules for the path, not all selected modules.
 	// Iterating over selected modules would make the overall loading time
@@ -355,8 +379,7 @@
 			}
 			m := module.Version{Path: prefix, Version: v}
 
-			needSum := true
-			root, isLocal, err := fetch(ctx, m, needSum)
+			root, isLocal, err := fetch(ctx, m)
 			if err != nil {
 				if sumErr := (*sumMissingError)(nil); errors.As(err, &sumErr) {
 					// We are missing a sum needed to fetch a module in the build list.
@@ -483,8 +506,7 @@
 		return len(mods[i].Path) > len(mods[j].Path)
 	})
 	for _, m := range mods {
-		needSum := true
-		root, isLocal, err := fetch(ctx, m, needSum)
+		root, isLocal, err := fetch(ctx, m)
 		if err != nil {
 			if sumErr := (*sumMissingError)(nil); errors.As(err, &sumErr) {
 				return module.Version{}, &ImportMissingSumError{importPath: path}
@@ -676,14 +698,9 @@
 // fetch downloads the given module (or its replacement)
 // and returns its location.
 //
-// needSum indicates whether the module may be downloaded in readonly mode
-// without a go.sum entry. It should only be false for modules fetched
-// speculatively (for example, for incompatible version filtering). The sum
-// will still be verified normally.
-//
 // The isLocal return value reports whether the replacement,
 // if any, is local to the filesystem.
-func fetch(ctx context.Context, mod module.Version, needSum bool) (dir string, isLocal bool, err error) {
+func fetch(ctx context.Context, mod module.Version) (dir string, isLocal bool, err error) {
 	if modRoot := MainModules.ModRoot(mod); modRoot != "" {
 		return modRoot, true, nil
 	}
@@ -713,7 +730,7 @@
 		mod = r
 	}
 
-	if HasModRoot() && cfg.BuildMod == "readonly" && !inWorkspaceMode() && needSum && !modfetch.HaveSum(mod) {
+	if mustHaveSums() && !modfetch.HaveSum(mod) {
 		return "", false, module.VersionError(mod, &sumMissingError{})
 	}
 
@@ -721,6 +738,12 @@
 	return dir, false, err
 }
 
+// mustHaveSums reports whether we require that all checksums
+// needed to load or build packages are already present in the go.sum file.
+func mustHaveSums() bool {
+	return HasModRoot() && cfg.BuildMod == "readonly" && !inWorkspaceMode()
+}
+
 type sumMissingError struct {
 	suggestion string
 }
diff --git a/src/cmd/go/internal/modload/import_test.go b/src/cmd/go/internal/modload/import_test.go
index 65a889e..eb4f5d6 100644
--- a/src/cmd/go/internal/modload/import_test.go
+++ b/src/cmd/go/internal/modload/import_test.go
@@ -27,7 +27,7 @@
 	},
 	{
 		path: "golang.org/x/net",
-		err:  `module golang.org/x/net@.* found \(v0.0.0-.*\), but does not contain package golang.org/x/net`,
+		err:  `module golang.org/x/net@.* found \(v[01]\.\d+\.\d+\), but does not contain package golang.org/x/net`,
 	},
 	{
 		path: "golang.org/x/text",
diff --git a/src/cmd/go/internal/modload/init.go b/src/cmd/go/internal/modload/init.go
index f960edd..34b00d5 100644
--- a/src/cmd/go/internal/modload/init.go
+++ b/src/cmd/go/internal/modload/init.go
@@ -12,7 +12,6 @@
 	"fmt"
 	"go/build"
 	"internal/lazyregexp"
-	"io/ioutil"
 	"os"
 	"path"
 	"path/filepath"
@@ -592,7 +591,7 @@
 
 // ReadWorkFile reads and parses the go.work file at the given path.
 func ReadWorkFile(path string) (*modfile.WorkFile, error) {
-	workData, err := ioutil.ReadFile(path)
+	workData, err := os.ReadFile(path)
 	if err != nil {
 		return nil, err
 	}
@@ -606,7 +605,7 @@
 	wf.Cleanup()
 	out := modfile.Format(wf.Syntax)
 
-	return ioutil.WriteFile(path, out, 0666)
+	return os.WriteFile(path, out, 0666)
 }
 
 // UpdateWorkFile updates comments on directory directives in the go.work
@@ -674,7 +673,7 @@
 			modfetch.WorkspaceGoSumFiles = append(modfetch.WorkspaceGoSumFiles, sumFile)
 		}
 		modfetch.GoSumFile = workFilePath + ".sum"
-	} else if modRoots == nil {
+	} else if len(modRoots) == 0 {
 		// We're in module mode, but not inside a module.
 		//
 		// Commands like 'go build', 'go run', 'go list' have no go.mod file to
@@ -708,6 +707,12 @@
 			pruning = workspace
 		}
 		requirements = newRequirements(pruning, nil, nil)
+		if cfg.BuildMod == "vendor" {
+			// For issue 56536: Some users may have GOFLAGS=-mod=vendor set.
+			// Make sure it behaves as though the fake module is vendored
+			// with no dependencies.
+			requirements.initVendor(nil)
+		}
 		return requirements
 	}
 
@@ -719,7 +724,11 @@
 		var fixed bool
 		data, f, err := ReadModFile(gomod, fixVersion(ctx, &fixed))
 		if err != nil {
-			base.Fatalf("go: %v", err)
+			if inWorkspaceMode() {
+				base.Fatalf("go: cannot load module listed in go.work file: %v", err)
+			} else {
+				base.Fatalf("go: %v", err)
+			}
 		}
 
 		modFiles = append(modFiles, f)
@@ -993,6 +1002,9 @@
 	}
 	mainModulePaths := make(map[string]bool)
 	for _, m := range ms {
+		if mainModulePaths[m.Path] {
+			base.Errorf("go: module %s appears multiple times in workspace", m.Path)
+		}
 		mainModulePaths[m.Path] = true
 	}
 	replacedByWorkFile := make(map[string]bool)
@@ -1148,7 +1160,7 @@
 		return
 	}
 
-	if len(modRoots) == 1 {
+	if len(modRoots) == 1 && !inWorkspaceMode() {
 		index := MainModules.GetSingleIndexOrNil()
 		if fi, err := fsys.Stat(filepath.Join(modRoots[0], "vendor")); err == nil && fi.IsDir() {
 			modGo := "unspecified"
@@ -1663,7 +1675,7 @@
 	addBuildListZipSums
 )
 
-// modKey returns the module.Version under which the checksum for m's go.mod
+// modkey returns the module.Version under which the checksum for m's go.mod
 // file is stored in the go.sum file.
 func modkey(m module.Version) module.Version {
 	return module.Version{Path: m.Path, Version: m.Version + "/go.mod"}
diff --git a/src/cmd/go/internal/modload/list.go b/src/cmd/go/internal/modload/list.go
index e822d06..f77901f 100644
--- a/src/cmd/go/internal/modload/list.go
+++ b/src/cmd/go/internal/modload/list.go
@@ -20,6 +20,7 @@
 	"cmd/go/internal/modfetch/codehost"
 	"cmd/go/internal/modinfo"
 	"cmd/go/internal/search"
+	"cmd/internal/pkgpattern"
 
 	"golang.org/x/mod/module"
 )
@@ -139,9 +140,7 @@
 			}
 			continue
 		}
-		if i := strings.Index(arg, "@"); i >= 0 {
-			path := arg[:i]
-			vers := arg[i+1:]
+		if path, vers, found := strings.Cut(arg, "@"); found {
 			if vers == "upgrade" || vers == "patch" {
 				if _, ok := rs.rootSelected(path); !ok || rs.pruning == unpruned {
 					needFullGraph = true
@@ -167,10 +166,7 @@
 
 	matchedModule := map[module.Version]bool{}
 	for _, arg := range args {
-		if i := strings.Index(arg, "@"); i >= 0 {
-			path := arg[:i]
-			vers := arg[i+1:]
-
+		if path, vers, found := strings.Cut(arg, "@"); found {
 			var current string
 			if mg == nil {
 				current, _ = rs.rootSelected(path)
@@ -225,7 +221,7 @@
 		if arg == "all" {
 			match = func(string) bool { return true }
 		} else if strings.Contains(arg, "...") {
-			match = search.MatchPattern(arg)
+			match = pkgpattern.MatchPattern(arg)
 		} else {
 			var v string
 			if mg == nil {
diff --git a/src/cmd/go/internal/modload/load.go b/src/cmd/go/internal/modload/load.go
index ba85dc2..e4f6a95 100644
--- a/src/cmd/go/internal/modload/load.go
+++ b/src/cmd/go/internal/modload/load.go
@@ -94,7 +94,6 @@
 // if those packages are not found in existing dependencies of the main module.
 
 import (
-	"bytes"
 	"context"
 	"errors"
 	"fmt"
@@ -549,13 +548,12 @@
 		modRoot := MainModules.ModRoot(mainModule)
 		if modRoot != "" && strings.HasPrefix(absDir, modRoot+string(filepath.Separator)) && !strings.Contains(absDir[len(modRoot):], "@") {
 			suffix := filepath.ToSlash(absDir[len(modRoot):])
-			if strings.HasPrefix(suffix, "/vendor/") {
+			if pkg, found := strings.CutPrefix(suffix, "/vendor/"); found {
 				if cfg.BuildMod != "vendor" {
 					return "", fmt.Errorf("without -mod=vendor, directory %s has no package path", absDir)
 				}
 
 				readVendorList(mainModule)
-				pkg := strings.TrimPrefix(suffix, "/vendor/")
 				if _, ok := vendorPkgModule[pkg]; !ok {
 					return "", fmt.Errorf("directory %s is not a package listed in vendor/modules.txt", absDir)
 				}
@@ -605,13 +603,17 @@
 
 	pkg := pathInModuleCache(ctx, absDir, rs)
 	if pkg == "" {
+		dirstr := fmt.Sprintf("directory %s", base.ShortPath(absDir))
+		if dirstr == "directory ." {
+			dirstr = "current directory"
+		}
 		if inWorkspaceMode() {
 			if mr := findModuleRoot(absDir); mr != "" {
-				return "", fmt.Errorf("directory %s is contained in a module that is not one of the workspace modules listed in go.work. You can add the module to the workspace using go work use %s", base.ShortPath(absDir), base.ShortPath(mr))
+				return "", fmt.Errorf("%s is contained in a module that is not one of the workspace modules listed in go.work. You can add the module to the workspace using:\n\tgo work use %s", dirstr, base.ShortPath(mr))
 			}
-			return "", fmt.Errorf("directory %s outside modules listed in go.work or their selected dependencies", base.ShortPath(absDir))
+			return "", fmt.Errorf("%s outside modules listed in go.work or their selected dependencies", dirstr)
 		}
-		return "", fmt.Errorf("directory %s outside main module or its selected dependencies", base.ShortPath(absDir))
+		return "", fmt.Errorf("%s outside main module or its selected dependencies", dirstr)
 	}
 	return pkg, nil
 }
@@ -755,6 +757,7 @@
 				suffix := filepath.ToSlash(dir[len(modRoot):])
 				if strings.HasPrefix(suffix, "/vendor/") {
 					longestPrefixPath = strings.TrimPrefix(suffix, "/vendor/")
+					continue
 				}
 				longestPrefixPath = mms.PathPrefix(v) + suffix
 			}
@@ -767,28 +770,6 @@
 	return ".", module.Version{}
 }
 
-// ImportMap returns the actual package import path
-// for an import path found in source code.
-// If the given import path does not appear in the source code
-// for the packages that have been loaded, ImportMap returns the empty string.
-func ImportMap(path string) string {
-	pkg, ok := loaded.pkgCache.Get(path).(*loadPkg)
-	if !ok {
-		return ""
-	}
-	return pkg.path
-}
-
-// PackageDir returns the directory containing the source code
-// for the package named by the import path.
-func PackageDir(path string) string {
-	pkg, ok := loaded.pkgCache.Get(path).(*loadPkg)
-	if !ok {
-		return ""
-	}
-	return pkg.dir
-}
-
 // PackageModule returns the module providing the package named by the import path.
 func PackageModule(path string) module.Version {
 	pkg, ok := loaded.pkgCache.Get(path).(*loadPkg)
@@ -954,7 +935,7 @@
 // An atomicLoadPkgFlags stores a loadPkgFlags for which individual flags can be
 // added atomically.
 type atomicLoadPkgFlags struct {
-	bits int32
+	bits atomic.Int32
 }
 
 // update sets the given flags in af (in addition to any flags already set).
@@ -963,9 +944,9 @@
 // flags were newly-set.
 func (af *atomicLoadPkgFlags) update(flags loadPkgFlags) (old loadPkgFlags) {
 	for {
-		old := atomic.LoadInt32(&af.bits)
+		old := af.bits.Load()
 		new := old | int32(flags)
-		if new == old || atomic.CompareAndSwapInt32(&af.bits, old, new) {
+		if new == old || af.bits.CompareAndSwap(old, new) {
 			return loadPkgFlags(old)
 		}
 	}
@@ -973,7 +954,7 @@
 
 // has reports whether all of the flags in cond are set in af.
 func (af *atomicLoadPkgFlags) has(cond loadPkgFlags) bool {
-	return loadPkgFlags(atomic.LoadInt32(&af.bits))&cond == cond
+	return loadPkgFlags(af.bits.Load())&cond == cond
 }
 
 // isTest reports whether pkg is a test of another package.
@@ -1007,7 +988,7 @@
 	if ld.GoVersion == "" {
 		ld.GoVersion = MainModules.GoVersion()
 
-		if ld.Tidy && semver.Compare("v"+ld.GoVersion, "v"+LatestGoVersion()) > 0 {
+		if ld.Tidy && versionLess(LatestGoVersion(), ld.GoVersion) {
 			ld.errorf("go: go.mod file indicates go %s, but maximum version supported by tidy is %s\n", ld.GoVersion, LatestGoVersion())
 			base.ExitIfErrors()
 		}
@@ -1016,7 +997,7 @@
 	if ld.Tidy {
 		if ld.TidyCompatibleVersion == "" {
 			ld.TidyCompatibleVersion = priorGoVersion(ld.GoVersion)
-		} else if semver.Compare("v"+ld.TidyCompatibleVersion, "v"+ld.GoVersion) > 0 {
+		} else if versionLess(ld.GoVersion, ld.TidyCompatibleVersion) {
 			// Each version of the Go toolchain knows how to interpret go.mod and
 			// go.sum files produced by all previous versions, so a compatibility
 			// version higher than the go.mod version adds nothing.
@@ -1128,7 +1109,7 @@
 		}
 
 		toAdd := make([]module.Version, 0, len(modAddedBy))
-		for m, _ := range modAddedBy {
+		for m := range modAddedBy {
 			toAdd = append(toAdd, m)
 		}
 		module.Sort(toAdd) // to make errors deterministic
@@ -1174,22 +1155,23 @@
 		rs, err := tidyRoots(ctx, ld.requirements, ld.pkgs)
 		if err != nil {
 			ld.errorf("go: %v\n", err)
-		}
-
-		if ld.requirements.pruning == pruned {
-			// We continuously add tidy roots to ld.requirements during loading, so at
-			// this point the tidy roots should be a subset of the roots of
-			// ld.requirements, ensuring that no new dependencies are brought inside
-			// the graph-pruning horizon.
-			// If that is not the case, there is a bug in the loading loop above.
-			for _, m := range rs.rootModules {
-				if v, ok := ld.requirements.rootSelected(m.Path); !ok || v != m.Version {
-					ld.errorf("go: internal error: a requirement on %v is needed but was not added during package loading\n", m)
-					base.ExitIfErrors()
+			base.ExitIfErrors()
+		} else {
+			if ld.requirements.pruning == pruned {
+				// We continuously add tidy roots to ld.requirements during loading, so at
+				// this point the tidy roots should be a subset of the roots of
+				// ld.requirements, ensuring that no new dependencies are brought inside
+				// the graph-pruning horizon.
+				// If that is not the case, there is a bug in the loading loop above.
+				for _, m := range rs.rootModules {
+					if v, ok := ld.requirements.rootSelected(m.Path); !ok || v != m.Version {
+						ld.errorf("go: internal error: a requirement on %v is needed but was not added during package loading\n", m)
+						base.ExitIfErrors()
+					}
 				}
 			}
+			ld.requirements = rs
 		}
-		ld.requirements = rs
 	}
 
 	// Report errors, if any.
@@ -1207,11 +1189,19 @@
 			}
 		}
 
-		if ld.SilencePackageErrors {
-			continue
+		if stdErr := (*ImportMissingError)(nil); errors.As(pkg.err, &stdErr) && stdErr.isStd {
+			// Add importer go version information to import errors of standard
+			// library packages arising from newer releases.
+			if importer := pkg.stack; importer != nil {
+				if v, ok := rawGoVersion.Load(importer.mod); ok && versionLess(LatestGoVersion(), v.(string)) {
+					stdErr.importerGoVersion = v.(string)
+				}
+			}
+			if ld.SilenceMissingStdImports {
+				continue
+			}
 		}
-		if stdErr := (*ImportMissingError)(nil); errors.As(pkg.err, &stdErr) &&
-			stdErr.isStd && ld.SilenceMissingStdImports {
+		if ld.SilencePackageErrors {
 			continue
 		}
 		if ld.SilenceNoGoErrors && errors.Is(pkg.err, imports.ErrNoGo) {
@@ -1225,6 +1215,12 @@
 	return ld
 }
 
+// versionLess returns whether a < b according to semantic version precedence.
+// Both strings are interpreted as go version strings, e.g. "1.19".
+func versionLess(a, b string) bool {
+	return semver.Compare("v"+a, "v"+b) < 0
+}
+
 // updateRequirements ensures that ld.requirements is consistent with the
 // information gained from ld.pkgs.
 //
@@ -1859,7 +1855,7 @@
 func (ld *loader) checkMultiplePaths() {
 	mods := ld.requirements.rootModules
 	if cached := ld.requirements.graph.Load(); cached != nil {
-		if mg := cached.(cachedGraph).mg; mg != nil {
+		if mg := cached.mg; mg != nil {
 			mods = mg.BuildList()
 		}
 	}
@@ -2174,7 +2170,7 @@
 		stack = append(stack, p)
 	}
 
-	var buf bytes.Buffer
+	var buf strings.Builder
 	for i := len(stack) - 1; i >= 0; i-- {
 		p := stack[i]
 		fmt.Fprint(&buf, p.path)
diff --git a/src/cmd/go/internal/modload/query.go b/src/cmd/go/internal/modload/query.go
index 01df14f..c3764b4 100644
--- a/src/cmd/go/internal/modload/query.go
+++ b/src/cmd/go/internal/modload/query.go
@@ -25,6 +25,7 @@
 	"cmd/go/internal/search"
 	"cmd/go/internal/str"
 	"cmd/go/internal/trace"
+	"cmd/internal/pkgpattern"
 
 	"golang.org/x/mod/module"
 	"golang.org/x/mod/semver"
@@ -220,6 +221,17 @@
 		return revErr, err
 	}
 
+	mergeRevOrigin := func(rev *modfetch.RevInfo, origin *codehost.Origin) *modfetch.RevInfo {
+		merged := mergeOrigin(rev.Origin, origin)
+		if merged == rev.Origin {
+			return rev
+		}
+		clone := new(modfetch.RevInfo)
+		*clone = *rev
+		clone.Origin = merged
+		return clone
+	}
+
 	lookup := func(v string) (*modfetch.RevInfo, error) {
 		rev, err := repo.Stat(v)
 		// Stat can return a non-nil rev and a non-nil err,
@@ -227,7 +239,7 @@
 		if rev == nil && err != nil {
 			return revErr, err
 		}
-		rev.Origin = mergeOrigin(rev.Origin, versions.Origin)
+		rev = mergeRevOrigin(rev, versions.Origin)
 		if err != nil {
 			return rev, err
 		}
@@ -256,12 +268,12 @@
 				if err := allowed(ctx, module.Version{Path: path, Version: current}); errors.Is(err, ErrDisallowed) {
 					return revErr, err
 				}
-				info, err := repo.Stat(current)
-				if info == nil && err != nil {
+				rev, err = repo.Stat(current)
+				if rev == nil && err != nil {
 					return revErr, err
 				}
-				info.Origin = mergeOrigin(info.Origin, versions.Origin)
-				return info, err
+				rev = mergeRevOrigin(rev, versions.Origin)
+				return rev, err
 			}
 		}
 
@@ -613,7 +625,7 @@
 	}
 
 	var match func(mod module.Version, roots []string, isLocal bool) *search.Match
-	matchPattern := search.MatchPattern(pattern)
+	matchPattern := pkgpattern.MatchPattern(pattern)
 
 	if i := strings.Index(pattern, "..."); i >= 0 {
 		base = pathpkg.Dir(pattern[:i+3])
@@ -717,8 +729,7 @@
 				return r, err
 			}
 			r.Mod.Version = r.Rev.Version
-			needSum := true
-			root, isLocal, err := fetch(ctx, r.Mod, needSum)
+			root, isLocal, err := fetch(ctx, r.Mod)
 			if err != nil {
 				return r, err
 			}
@@ -997,17 +1008,6 @@
 	return ""
 }
 
-// moduleHasRootPackage returns whether module m contains a package m.Path.
-func moduleHasRootPackage(ctx context.Context, m module.Version) (bool, error) {
-	needSum := false
-	root, isLocal, err := fetch(ctx, m, needSum)
-	if err != nil {
-		return false, err
-	}
-	_, ok, err := dirInModule(m.Path, m.Path, root, isLocal)
-	return ok, err
-}
-
 // versionHasGoMod returns whether a version has a go.mod file.
 //
 // versionHasGoMod fetches the go.mod file (possibly a fake) and true if it
@@ -1116,7 +1116,7 @@
 	for _, mm := range MainModules.Versions() {
 		if index := MainModules.Index(mm); index != nil && len(index.replace) > 0 {
 			path := rr.ModulePath()
-			for m, _ := range index.replace {
+			for m := range index.replace {
 				if m.Path == path && strings.HasPrefix(m.Version, prefix) && m.Version != "" && !module.IsPseudoVersion(m.Version) {
 					versions = append(versions, m.Version)
 				}
diff --git a/src/cmd/go/internal/modload/query_test.go b/src/cmd/go/internal/modload/query_test.go
index a3f2f84..fe9ae9f 100644
--- a/src/cmd/go/internal/modload/query_test.go
+++ b/src/cmd/go/internal/modload/query_test.go
@@ -6,6 +6,7 @@
 
 import (
 	"context"
+	"flag"
 	"internal/testenv"
 	"log"
 	"os"
@@ -15,27 +16,47 @@
 	"testing"
 
 	"cmd/go/internal/cfg"
+	"cmd/go/internal/vcweb/vcstest"
 
 	"golang.org/x/mod/module"
 )
 
 func TestMain(m *testing.M) {
-	os.Exit(testMain(m))
+	flag.Parse()
+	if err := testMain(m); err != nil {
+		log.Fatal(err)
+	}
 }
 
-func testMain(m *testing.M) int {
+func testMain(m *testing.M) (err error) {
 	cfg.GOPROXY = "direct"
+	cfg.ModCacheRW = true
+
+	srv, err := vcstest.NewServer()
+	if err != nil {
+		return err
+	}
+	defer func() {
+		if closeErr := srv.Close(); err == nil {
+			err = closeErr
+		}
+	}()
 
 	dir, err := os.MkdirTemp("", "modload-test-")
 	if err != nil {
-		log.Fatal(err)
+		return err
 	}
-	defer os.RemoveAll(dir)
+	defer func() {
+		if rmErr := os.RemoveAll(dir); err == nil {
+			err = rmErr
+		}
+	}()
 
 	os.Setenv("GOPATH", dir)
 	cfg.BuildContext.GOPATH = dir
 	cfg.GOMODCACHE = filepath.Join(dir, "pkg/mod")
-	return m.Run()
+	m.Run()
+	return nil
 }
 
 var (
@@ -55,42 +76,6 @@
 	vers    string
 	err     string
 }{
-	/*
-		git init
-		echo module vcs-test.golang.org/git/querytest.git >go.mod
-		git add go.mod
-		git commit -m v1 go.mod
-		git tag start
-		for i in v0.0.0-pre1 v0.0.0 v0.0.1 v0.0.2 v0.0.3 v0.1.0 v0.1.1 v0.1.2 v0.3.0 v1.0.0 v1.1.0 v1.9.0 v1.9.9 v1.9.10-pre1 v1.9.10-pre2+metadata unversioned; do
-			echo before $i >status
-			git add status
-			git commit -m "before $i" status
-			echo at $i >status
-			git commit -m "at $i" status
-			git tag $i
-		done
-		git tag favorite v0.0.3
-
-		git branch v2 start
-		git checkout v2
-		echo module vcs-test.golang.org/git/querytest.git/v2 >go.mod
-		git commit -m v2 go.mod
-		for i in v2.0.0 v2.1.0 v2.2.0 v2.5.5 v2.6.0-pre1; do
-			echo before $i >status
-			git add status
-			git commit -m "before $i" status
-			echo at $i >status
-			git commit -m "at $i" status
-			git tag $i
-		done
-		git checkout v2.5.5
-		echo after v2.5.5 >status
-		git commit -m 'after v2.5.5' status
-		git checkout master
-		zip -r ../querytest.zip
-		gsutil cp ../querytest.zip gs://vcs-test/git/querytest.zip
-		curl 'https://vcs-test.golang.org/git/querytest?go-get=1'
-	*/
 	{path: queryRepo, query: "<v0.0.0", vers: "v0.0.0-pre1"},
 	{path: queryRepo, query: "<v0.0.0-pre1", err: `no matching versions for query "<v0.0.0-pre1"`},
 	{path: queryRepo, query: "<=v0.0.0", vers: "v0.0.0"},
diff --git a/src/cmd/go/internal/modload/search.go b/src/cmd/go/internal/modload/search.go
index b2ac7f2..1da46a4 100644
--- a/src/cmd/go/internal/modload/search.go
+++ b/src/cmd/go/internal/modload/search.go
@@ -24,6 +24,7 @@
 	"cmd/go/internal/par"
 	"cmd/go/internal/search"
 	"cmd/go/internal/trace"
+	"cmd/internal/pkgpattern"
 
 	"golang.org/x/mod/module"
 )
@@ -47,8 +48,8 @@
 	isMatch := func(string) bool { return true }
 	treeCanMatch := func(string) bool { return true }
 	if !m.IsMeta() {
-		isMatch = search.MatchPattern(m.Pattern())
-		treeCanMatch = search.TreeCanMatchPattern(m.Pattern())
+		isMatch = pkgpattern.MatchPattern(m.Pattern())
+		treeCanMatch = pkgpattern.TreeCanMatchPattern(m.Pattern())
 	}
 
 	var mu sync.Mutex
@@ -187,8 +188,7 @@
 			isLocal = true
 		} else {
 			var err error
-			const needSum = true
-			root, isLocal, err = fetch(ctx, mod, needSum)
+			root, isLocal, err = fetch(ctx, mod)
 			if err != nil {
 				m.AddError(err)
 				continue
@@ -278,8 +278,7 @@
 		return match
 	}
 
-	const needSum = true
-	root, isLocal, err := fetch(ctx, m, needSum)
+	root, isLocal, err := fetch(ctx, m)
 	if err != nil {
 		match.Errs = []error{err}
 		return match
diff --git a/src/cmd/go/internal/modload/vendor.go b/src/cmd/go/internal/modload/vendor.go
index 5ea82a8..e369049 100644
--- a/src/cmd/go/internal/modload/vendor.go
+++ b/src/cmd/go/internal/modload/vendor.go
@@ -98,16 +98,16 @@
 				continue
 			}
 
-			if strings.HasPrefix(line, "## ") {
+			if annonations, ok := strings.CutPrefix(line, "## "); ok {
 				// Metadata. Take the union of annotations across multiple lines, if present.
 				meta := vendorMeta[mod]
-				for _, entry := range strings.Split(strings.TrimPrefix(line, "## "), ";") {
+				for _, entry := range strings.Split(annonations, ";") {
 					entry = strings.TrimSpace(entry)
 					if entry == "explicit" {
 						meta.Explicit = true
 					}
-					if strings.HasPrefix(entry, "go ") {
-						meta.GoVersion = strings.TrimPrefix(entry, "go ")
+					if goVersion, ok := strings.CutPrefix(entry, "go "); ok {
+						meta.GoVersion = goVersion
 						rawGoVersion.Store(mod, meta.GoVersion)
 					}
 					// All other tokens are reserved for future use.
diff --git a/src/cmd/go/internal/mvs/mvs.go b/src/cmd/go/internal/mvs/mvs.go
index a1b5155..eb33ebd 100644
--- a/src/cmd/go/internal/mvs/mvs.go
+++ b/src/cmd/go/internal/mvs/mvs.go
@@ -166,7 +166,7 @@
 			}
 			return false
 		}
-		return nil, NewBuildListError(err.(error), errPath, isUpgrade)
+		return nil, NewBuildListError(err, errPath, isUpgrade)
 	}
 
 	// The final list is the minimum version of each module found in the graph.
diff --git a/src/cmd/go/internal/par/work.go b/src/cmd/go/internal/par/work.go
index 496c41b..7626251 100644
--- a/src/cmd/go/internal/par/work.go
+++ b/src/cmd/go/internal/par/work.go
@@ -108,7 +108,7 @@
 }
 
 type cacheEntry struct {
-	done   uint32
+	done   atomic.Bool
 	mu     sync.Mutex
 	result any
 }
@@ -122,11 +122,11 @@
 		entryIface, _ = c.m.LoadOrStore(key, new(cacheEntry))
 	}
 	e := entryIface.(*cacheEntry)
-	if atomic.LoadUint32(&e.done) == 0 {
+	if !e.done.Load() {
 		e.mu.Lock()
-		if atomic.LoadUint32(&e.done) == 0 {
+		if !e.done.Load() {
 			e.result = f()
-			atomic.StoreUint32(&e.done, 1)
+			e.done.Store(true)
 		}
 		e.mu.Unlock()
 	}
@@ -142,7 +142,7 @@
 		return nil
 	}
 	e := entryIface.(*cacheEntry)
-	if atomic.LoadUint32(&e.done) == 0 {
+	if !e.done.Load() {
 		return nil
 	}
 	return e.result
diff --git a/src/cmd/go/internal/run/run.go b/src/cmd/go/internal/run/run.go
index ebe1611..137ee1d 100644
--- a/src/cmd/go/internal/run/run.go
+++ b/src/cmd/go/internal/run/run.go
@@ -69,6 +69,9 @@
 	CmdRun.Run = runRun // break init loop
 
 	work.AddBuildFlags(CmdRun, work.DefaultBuildFlags)
+	if cfg.Experiment != nil && cfg.Experiment.CoverageRedesign {
+		work.AddCoverFlags(CmdRun, nil)
+	}
 	CmdRun.Flag.Var((*base.StringsFlag)(&work.ExecCmd), "exec", "")
 }
 
@@ -91,8 +94,12 @@
 	}
 
 	work.BuildInit()
-	var b work.Builder
-	b.Init()
+	b := work.NewBuilder("")
+	defer func() {
+		if err := b.Close(); err != nil {
+			base.Fatalf("go: %v", err)
+		}
+	}()
 	b.Print = printStderr
 
 	i := 0
@@ -142,6 +149,10 @@
 	cmdArgs := args[i:]
 	load.CheckPackageErrors([]*load.Package{p})
 
+	if cfg.Experiment.CoverageRedesign && cfg.BuildCover {
+		load.PrepareForCoverageBuild([]*load.Package{p})
+	}
+
 	p.Internal.OmitDebug = true
 	p.Target = "" // must build - not up to date
 	if p.Internal.CmdlineFiles {
@@ -166,7 +177,7 @@
 	}
 
 	a1 := b.LinkAction(work.ModeBuild, work.ModeBuild, p)
-	a := &work.Action{Mode: "go run", Func: buildRunProgram, Args: cmdArgs, Deps: []*work.Action{a1}}
+	a := &work.Action{Mode: "go run", Actor: work.ActorFunc(buildRunProgram), Args: cmdArgs, Deps: []*work.Action{a1}}
 	b.Do(ctx, a)
 }
 
diff --git a/src/cmd/go/internal/script/cmds.go b/src/cmd/go/internal/script/cmds.go
new file mode 100644
index 0000000..666d2d6
--- /dev/null
+++ b/src/cmd/go/internal/script/cmds.go
@@ -0,0 +1,1113 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package script
+
+import (
+	"cmd/go/internal/robustio"
+	"errors"
+	"fmt"
+	"internal/diff"
+	"io/fs"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"regexp"
+	"runtime"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+)
+
+// DefaultCmds returns a set of broadly useful script commands.
+//
+// Run the 'help' command within a script engine to view a list of the available
+// commands.
+func DefaultCmds() map[string]Cmd {
+	return map[string]Cmd{
+		"cat":     Cat(),
+		"cd":      Cd(),
+		"chmod":   Chmod(),
+		"cmp":     Cmp(),
+		"cmpenv":  Cmpenv(),
+		"cp":      Cp(),
+		"echo":    Echo(),
+		"env":     Env(),
+		"exec":    Exec(func(cmd *exec.Cmd) error { return cmd.Process.Signal(os.Interrupt) }, 100*time.Millisecond), // arbitrary grace period
+		"exists":  Exists(),
+		"grep":    Grep(),
+		"help":    Help(),
+		"mkdir":   Mkdir(),
+		"mv":      Mv(),
+		"rm":      Rm(),
+		"replace": Replace(),
+		"sleep":   Sleep(),
+		"stderr":  Stderr(),
+		"stdout":  Stdout(),
+		"stop":    Stop(),
+		"symlink": Symlink(),
+		"wait":    Wait(),
+	}
+}
+
+// Command returns a new Cmd with a Usage method that returns a copy of the
+// given CmdUsage and a Run method calls the given function.
+func Command(usage CmdUsage, run func(*State, ...string) (WaitFunc, error)) Cmd {
+	return &funcCmd{
+		usage: usage,
+		run:   run,
+	}
+}
+
+// A funcCmd implements Cmd using a function value.
+type funcCmd struct {
+	usage CmdUsage
+	run   func(*State, ...string) (WaitFunc, error)
+}
+
+func (c *funcCmd) Run(s *State, args ...string) (WaitFunc, error) {
+	return c.run(s, args...)
+}
+
+func (c *funcCmd) Usage() *CmdUsage { return &c.usage }
+
+// firstNonFlag returns a slice containing the index of the first argument in
+// rawArgs that is not a flag, or nil if all arguments are flags.
+func firstNonFlag(rawArgs ...string) []int {
+	for i, arg := range rawArgs {
+		if !strings.HasPrefix(arg, "-") {
+			return []int{i}
+		}
+		if arg == "--" {
+			return []int{i + 1}
+		}
+	}
+	return nil
+}
+
+// Cat writes the concatenated contents of the named file(s) to the script's
+// stdout buffer.
+func Cat() Cmd {
+	return Command(
+		CmdUsage{
+			Summary: "concatenate files and print to the script's stdout buffer",
+			Args:    "files...",
+		},
+		func(s *State, args ...string) (WaitFunc, error) {
+			if len(args) == 0 {
+				return nil, ErrUsage
+			}
+
+			paths := make([]string, 0, len(args))
+			for _, arg := range args {
+				paths = append(paths, s.Path(arg))
+			}
+
+			var buf strings.Builder
+			errc := make(chan error, 1)
+			go func() {
+				for _, p := range paths {
+					b, err := os.ReadFile(p)
+					buf.Write(b)
+					if err != nil {
+						errc <- err
+						return
+					}
+				}
+				errc <- nil
+			}()
+
+			wait := func(*State) (stdout, stderr string, err error) {
+				err = <-errc
+				return buf.String(), "", err
+			}
+			return wait, nil
+		})
+}
+
+// Cd changes the current working directory.
+func Cd() Cmd {
+	return Command(
+		CmdUsage{
+			Summary: "change the working directory",
+			Args:    "dir",
+		},
+		func(s *State, args ...string) (WaitFunc, error) {
+			if len(args) != 1 {
+				return nil, ErrUsage
+			}
+			return nil, s.Chdir(args[0])
+		})
+}
+
+// Chmod changes the permissions of a file or a directory..
+func Chmod() Cmd {
+	return Command(
+		CmdUsage{
+			Summary: "change file mode bits",
+			Args:    "perm paths...",
+			Detail: []string{
+				"Changes the permissions of the named files or directories to be equal to perm.",
+				"Only numerical permissions are supported.",
+			},
+		},
+		func(s *State, args ...string) (WaitFunc, error) {
+			if len(args) < 2 {
+				return nil, ErrUsage
+			}
+
+			perm, err := strconv.ParseUint(args[0], 0, 32)
+			if err != nil || perm&uint64(fs.ModePerm) != perm {
+				return nil, fmt.Errorf("invalid mode: %s", args[0])
+			}
+
+			for _, arg := range args[1:] {
+				err := os.Chmod(s.Path(arg), fs.FileMode(perm))
+				if err != nil {
+					return nil, err
+				}
+			}
+			return nil, nil
+		})
+}
+
+// Cmp compares the contents of two files, or the contents of either the
+// "stdout" or "stderr" buffer and a file, returning a non-nil error if the
+// contents differ.
+func Cmp() Cmd {
+	return Command(
+		CmdUsage{
+			Args:    "[-q] file1 file2",
+			Summary: "compare files for differences",
+			Detail: []string{
+				"By convention, file1 is the actual data and file2 is the expected data.",
+				"The command succeeds if the file contents are identical.",
+				"File1 can be 'stdout' or 'stderr' to compare the stdout or stderr buffer from the most recent command.",
+			},
+		},
+		func(s *State, args ...string) (WaitFunc, error) {
+			return nil, doCompare(s, false, args...)
+		})
+}
+
+// Cmpenv is like Compare, but also performs environment substitutions
+// on the contents of both arguments.
+func Cmpenv() Cmd {
+	return Command(
+		CmdUsage{
+			Args:    "[-q] file1 file2",
+			Summary: "compare files for differences, with environment expansion",
+			Detail: []string{
+				"By convention, file1 is the actual data and file2 is the expected data.",
+				"The command succeeds if the file contents are identical after substituting variables from the script environment.",
+				"File1 can be 'stdout' or 'stderr' to compare the script's stdout or stderr buffer.",
+			},
+		},
+		func(s *State, args ...string) (WaitFunc, error) {
+			return nil, doCompare(s, true, args...)
+		})
+}
+
+func doCompare(s *State, env bool, args ...string) error {
+	quiet := false
+	if len(args) > 0 && args[0] == "-q" {
+		quiet = true
+		args = args[1:]
+	}
+	if len(args) != 2 {
+		return ErrUsage
+	}
+
+	name1, name2 := args[0], args[1]
+	var text1, text2 string
+	switch name1 {
+	case "stdout":
+		text1 = s.Stdout()
+	case "stderr":
+		text1 = s.Stderr()
+	default:
+		data, err := os.ReadFile(s.Path(name1))
+		if err != nil {
+			return err
+		}
+		text1 = string(data)
+	}
+
+	data, err := os.ReadFile(s.Path(name2))
+	if err != nil {
+		return err
+	}
+	text2 = string(data)
+
+	if env {
+		text1 = s.ExpandEnv(text1, false)
+		text2 = s.ExpandEnv(text2, false)
+	}
+
+	if text1 != text2 {
+		if !quiet {
+			diffText := diff.Diff(name1, []byte(text1), name2, []byte(text2))
+			s.Logf("%s\n", diffText)
+		}
+		return fmt.Errorf("%s and %s differ", name1, name2)
+	}
+	return nil
+}
+
+// Cp copies one or more files to a new location.
+func Cp() Cmd {
+	return Command(
+		CmdUsage{
+			Summary: "copy files to a target file or directory",
+			Args:    "src... dst",
+			Detail: []string{
+				"src can include 'stdout' or 'stderr' to copy from the script's stdout or stderr buffer.",
+			},
+		},
+		func(s *State, args ...string) (WaitFunc, error) {
+			if len(args) < 2 {
+				return nil, ErrUsage
+			}
+
+			dst := s.Path(args[len(args)-1])
+			info, err := os.Stat(dst)
+			dstDir := err == nil && info.IsDir()
+			if len(args) > 2 && !dstDir {
+				return nil, &fs.PathError{Op: "cp", Path: dst, Err: errors.New("destination is not a directory")}
+			}
+
+			for _, arg := range args[:len(args)-1] {
+				var (
+					src  string
+					data []byte
+					mode fs.FileMode
+				)
+				switch arg {
+				case "stdout":
+					src = arg
+					data = []byte(s.Stdout())
+					mode = 0666
+				case "stderr":
+					src = arg
+					data = []byte(s.Stderr())
+					mode = 0666
+				default:
+					src = s.Path(arg)
+					info, err := os.Stat(src)
+					if err != nil {
+						return nil, err
+					}
+					mode = info.Mode() & 0777
+					data, err = os.ReadFile(src)
+					if err != nil {
+						return nil, err
+					}
+				}
+				targ := dst
+				if dstDir {
+					targ = filepath.Join(dst, filepath.Base(src))
+				}
+				err := os.WriteFile(targ, data, mode)
+				if err != nil {
+					return nil, err
+				}
+			}
+
+			return nil, nil
+		})
+}
+
+// Echo writes its arguments to stdout, followed by a newline.
+func Echo() Cmd {
+	return Command(
+		CmdUsage{
+			Summary: "display a line of text",
+			Args:    "string...",
+		},
+		func(s *State, args ...string) (WaitFunc, error) {
+			var buf strings.Builder
+			for i, arg := range args {
+				if i > 0 {
+					buf.WriteString(" ")
+				}
+				buf.WriteString(arg)
+			}
+			buf.WriteString("\n")
+			out := buf.String()
+
+			// Stuff the result into a callback to satisfy the OutputCommandFunc
+			// interface, even though it isn't really asynchronous even if run in the
+			// background.
+			//
+			// Nobody should be running 'echo' as a background command, but it's not worth
+			// defining yet another interface, and also doesn't seem worth shoehorning
+			// into a SimpleCommand the way we did with Wait.
+			return func(*State) (stdout, stderr string, err error) {
+				return out, "", nil
+			}, nil
+		})
+}
+
+// Env sets or logs the values of environment variables.
+//
+// With no arguments, Env reports all variables in the environment.
+// "key=value" arguments set variables, and arguments without "="
+// cause the corresponding value to be printed to the stdout buffer.
+func Env() Cmd {
+	return Command(
+		CmdUsage{
+			Summary: "set or log the values of environment variables",
+			Args:    "[key[=value]...]",
+			Detail: []string{
+				"With no arguments, print the script environment to the log.",
+				"Otherwise, add the listed key=value pairs to the environment or print the listed keys.",
+			},
+		},
+		func(s *State, args ...string) (WaitFunc, error) {
+			out := new(strings.Builder)
+			if len(args) == 0 {
+				for _, kv := range s.env {
+					fmt.Fprintf(out, "%s\n", kv)
+				}
+			} else {
+				for _, env := range args {
+					i := strings.Index(env, "=")
+					if i < 0 {
+						// Display value instead of setting it.
+						fmt.Fprintf(out, "%s=%s\n", env, s.envMap[env])
+						continue
+					}
+					if err := s.Setenv(env[:i], env[i+1:]); err != nil {
+						return nil, err
+					}
+				}
+			}
+			var wait WaitFunc
+			if out.Len() > 0 || len(args) == 0 {
+				wait = func(*State) (stdout, stderr string, err error) {
+					return out.String(), "", nil
+				}
+			}
+			return wait, nil
+		})
+}
+
+// Exec runs an arbitrary executable as a subprocess.
+//
+// When the Script's context is canceled, Exec sends the interrupt signal, then
+// waits for up to the given delay for the subprocess to flush output before
+// terminating it with os.Kill.
+func Exec(cancel func(*exec.Cmd) error, waitDelay time.Duration) Cmd {
+	return Command(
+		CmdUsage{
+			Summary: "run an executable program with arguments",
+			Args:    "program [args...]",
+			Detail: []string{
+				"Note that 'exec' does not terminate the script (unlike Unix shells).",
+			},
+			Async: true,
+		},
+		func(s *State, args ...string) (WaitFunc, error) {
+			if len(args) < 1 {
+				return nil, ErrUsage
+			}
+
+			// Use the script's PATH to look up the command if it contains a separator
+			// instead of the test process's PATH (see lookPath).
+			// Don't use filepath.Clean, since that changes "./foo" to "foo".
+			name := filepath.FromSlash(args[0])
+			path := name
+			if !strings.Contains(name, string(filepath.Separator)) {
+				var err error
+				path, err = lookPath(s, name)
+				if err != nil {
+					return nil, err
+				}
+			}
+
+			return startCommand(s, name, path, args[1:], cancel, waitDelay)
+		})
+}
+
+func startCommand(s *State, name, path string, args []string, cancel func(*exec.Cmd) error, waitDelay time.Duration) (WaitFunc, error) {
+	var (
+		cmd                  *exec.Cmd
+		stdoutBuf, stderrBuf strings.Builder
+	)
+	for {
+		cmd = exec.CommandContext(s.Context(), path, args...)
+		if cancel == nil {
+			cmd.Cancel = nil
+		} else {
+			cmd.Cancel = func() error { return cancel(cmd) }
+		}
+		cmd.WaitDelay = waitDelay
+		cmd.Args[0] = name
+		cmd.Dir = s.Getwd()
+		cmd.Env = s.env
+		cmd.Stdout = &stdoutBuf
+		cmd.Stderr = &stderrBuf
+		err := cmd.Start()
+		if err == nil {
+			break
+		}
+		if isETXTBSY(err) {
+			// If the script (or its host process) just wrote the executable we're
+			// trying to run, a fork+exec in another thread may be holding open the FD
+			// that we used to write the executable (see https://go.dev/issue/22315).
+			// Since the descriptor should have CLOEXEC set, the problem should
+			// resolve as soon as the forked child reaches its exec call.
+			// Keep retrying until that happens.
+		} else {
+			return nil, err
+		}
+	}
+
+	wait := func(s *State) (stdout, stderr string, err error) {
+		err = cmd.Wait()
+		return stdoutBuf.String(), stderrBuf.String(), err
+	}
+	return wait, nil
+}
+
+// lookPath is (roughly) like exec.LookPath, but it uses the script's current
+// PATH to find the executable.
+func lookPath(s *State, command string) (string, error) {
+	var strEqual func(string, string) bool
+	if runtime.GOOS == "windows" || runtime.GOOS == "darwin" {
+		// Using GOOS as a proxy for case-insensitive file system.
+		// TODO(bcmills): Remove this assumption.
+		strEqual = strings.EqualFold
+	} else {
+		strEqual = func(a, b string) bool { return a == b }
+	}
+
+	var pathExt []string
+	var searchExt bool
+	var isExecutable func(os.FileInfo) bool
+	if runtime.GOOS == "windows" {
+		// Use the test process's PathExt instead of the script's.
+		// If PathExt is set in the command's environment, cmd.Start fails with
+		// "parameter is invalid". Not sure why.
+		// If the command already has an extension in PathExt (like "cmd.exe")
+		// don't search for other extensions (not "cmd.bat.exe").
+		pathExt = strings.Split(os.Getenv("PathExt"), string(filepath.ListSeparator))
+		searchExt = true
+		cmdExt := filepath.Ext(command)
+		for _, ext := range pathExt {
+			if strEqual(cmdExt, ext) {
+				searchExt = false
+				break
+			}
+		}
+		isExecutable = func(fi os.FileInfo) bool {
+			return fi.Mode().IsRegular()
+		}
+	} else {
+		isExecutable = func(fi os.FileInfo) bool {
+			return fi.Mode().IsRegular() && fi.Mode().Perm()&0111 != 0
+		}
+	}
+
+	pathEnv, _ := s.LookupEnv(pathEnvName())
+	for _, dir := range strings.Split(pathEnv, string(filepath.ListSeparator)) {
+		if searchExt {
+			ents, err := os.ReadDir(dir)
+			if err != nil {
+				continue
+			}
+			for _, ent := range ents {
+				for _, ext := range pathExt {
+					if !ent.IsDir() && strEqual(ent.Name(), command+ext) {
+						return dir + string(filepath.Separator) + ent.Name(), nil
+					}
+				}
+			}
+		} else {
+			path := dir + string(filepath.Separator) + command
+			if fi, err := os.Stat(path); err == nil && isExecutable(fi) {
+				return path, nil
+			}
+		}
+	}
+	return "", &exec.Error{Name: command, Err: exec.ErrNotFound}
+}
+
+// pathEnvName returns the platform-specific variable used by os/exec.LookPath
+// to look up executable names (either "PATH" or "path").
+//
+// TODO(bcmills): Investigate whether we can instead use PATH uniformly and
+// rewrite it to $path when executing subprocesses.
+func pathEnvName() string {
+	switch runtime.GOOS {
+	case "plan9":
+		return "path"
+	default:
+		return "PATH"
+	}
+}
+
+// Exists checks that the named file(s) exist.
+func Exists() Cmd {
+	return Command(
+		CmdUsage{
+			Summary: "check that files exist",
+			Args:    "[-readonly] [-exec] file...",
+		},
+		func(s *State, args ...string) (WaitFunc, error) {
+			var readonly, exec bool
+		loop:
+			for len(args) > 0 {
+				switch args[0] {
+				case "-readonly":
+					readonly = true
+					args = args[1:]
+				case "-exec":
+					exec = true
+					args = args[1:]
+				default:
+					break loop
+				}
+			}
+			if len(args) == 0 {
+				return nil, ErrUsage
+			}
+
+			for _, file := range args {
+				file = s.Path(file)
+				info, err := os.Stat(file)
+				if err != nil {
+					return nil, err
+				}
+				if readonly && info.Mode()&0222 != 0 {
+					return nil, fmt.Errorf("%s exists but is writable", file)
+				}
+				if exec && runtime.GOOS != "windows" && info.Mode()&0111 == 0 {
+					return nil, fmt.Errorf("%s exists but is not executable", file)
+				}
+			}
+
+			return nil, nil
+		})
+}
+
+// Grep checks that file content matches a regexp.
+// Like stdout/stderr and unlike Unix grep, it accepts Go regexp syntax.
+//
+// Grep does not modify the State's stdout or stderr buffers.
+// (Its output goes to the script log, not stdout.)
+func Grep() Cmd {
+	return Command(
+		CmdUsage{
+			Summary: "find lines in a file that match a pattern",
+			Args:    matchUsage + " file",
+			Detail: []string{
+				"The command succeeds if at least one match (or the exact count, if given) is found.",
+				"The -q flag suppresses printing of matches.",
+			},
+			RegexpArgs: firstNonFlag,
+		},
+		func(s *State, args ...string) (WaitFunc, error) {
+			return nil, match(s, args, "", "grep")
+		})
+}
+
+const matchUsage = "[-count=N] [-q] 'pattern'"
+
+// match implements the Grep, Stdout, and Stderr commands.
+func match(s *State, args []string, text, name string) error {
+	n := 0
+	if len(args) >= 1 && strings.HasPrefix(args[0], "-count=") {
+		var err error
+		n, err = strconv.Atoi(args[0][len("-count="):])
+		if err != nil {
+			return fmt.Errorf("bad -count=: %v", err)
+		}
+		if n < 1 {
+			return fmt.Errorf("bad -count=: must be at least 1")
+		}
+		args = args[1:]
+	}
+	quiet := false
+	if len(args) >= 1 && args[0] == "-q" {
+		quiet = true
+		args = args[1:]
+	}
+
+	isGrep := name == "grep"
+
+	wantArgs := 1
+	if isGrep {
+		wantArgs = 2
+	}
+	if len(args) != wantArgs {
+		return ErrUsage
+	}
+
+	pattern := `(?m)` + args[0]
+	re, err := regexp.Compile(pattern)
+	if err != nil {
+		return err
+	}
+
+	if isGrep {
+		name = args[1] // for error messages
+		data, err := os.ReadFile(s.Path(args[1]))
+		if err != nil {
+			return err
+		}
+		text = string(data)
+	}
+
+	if n > 0 {
+		count := len(re.FindAllString(text, -1))
+		if count != n {
+			return fmt.Errorf("found %d matches for %#q in %s", count, pattern, name)
+		}
+		return nil
+	}
+
+	if !re.MatchString(text) {
+		return fmt.Errorf("no match for %#q in %s", pattern, name)
+	}
+
+	if !quiet {
+		// Print the lines containing the match.
+		loc := re.FindStringIndex(text)
+		for loc[0] > 0 && text[loc[0]-1] != '\n' {
+			loc[0]--
+		}
+		for loc[1] < len(text) && text[loc[1]] != '\n' {
+			loc[1]++
+		}
+		lines := strings.TrimSuffix(text[loc[0]:loc[1]], "\n")
+		s.Logf("matched: %s\n", lines)
+	}
+	return nil
+}
+
+// Help writes command documentation to the script log.
+func Help() Cmd {
+	return Command(
+		CmdUsage{
+			Summary: "log help text for commands and conditions",
+			Args:    "[-v] name...",
+			Detail: []string{
+				"To display help for a specific condition, enclose it in brackets: 'help [amd64]'.",
+				"To display complete documentation when listing all commands, pass the -v flag.",
+			},
+		},
+		func(s *State, args ...string) (WaitFunc, error) {
+			if s.engine == nil {
+				return nil, errors.New("no engine configured")
+			}
+
+			verbose := false
+			if len(args) > 0 {
+				verbose = true
+				if args[0] == "-v" {
+					args = args[1:]
+				}
+			}
+
+			var cmds, conds []string
+			for _, arg := range args {
+				if strings.HasPrefix(arg, "[") && strings.HasSuffix(arg, "]") {
+					conds = append(conds, arg[1:len(arg)-1])
+				} else {
+					cmds = append(cmds, arg)
+				}
+			}
+
+			out := new(strings.Builder)
+
+			if len(conds) > 0 || (len(args) == 0 && len(s.engine.Conds) > 0) {
+				if conds == nil {
+					out.WriteString("conditions:\n\n")
+				}
+				s.engine.ListConds(out, s, conds...)
+			}
+
+			if len(cmds) > 0 || len(args) == 0 {
+				if len(args) == 0 {
+					out.WriteString("\ncommands:\n\n")
+				}
+				s.engine.ListCmds(out, verbose, cmds...)
+			}
+
+			wait := func(*State) (stdout, stderr string, err error) {
+				return out.String(), "", nil
+			}
+			return wait, nil
+		})
+}
+
+// Mkdir creates a directory and any needed parent directories.
+func Mkdir() Cmd {
+	return Command(
+		CmdUsage{
+			Summary: "create directories, if they do not already exist",
+			Args:    "path...",
+			Detail: []string{
+				"Unlike Unix mkdir, parent directories are always created if needed.",
+			},
+		},
+		func(s *State, args ...string) (WaitFunc, error) {
+			if len(args) < 1 {
+				return nil, ErrUsage
+			}
+			for _, arg := range args {
+				if err := os.MkdirAll(s.Path(arg), 0777); err != nil {
+					return nil, err
+				}
+			}
+			return nil, nil
+		})
+}
+
+// Mv renames an existing file or directory to a new path.
+func Mv() Cmd {
+	return Command(
+		CmdUsage{
+			Summary: "rename a file or directory to a new path",
+			Args:    "old new",
+			Detail: []string{
+				"OS-specific restrictions may apply when old and new are in different directories.",
+			},
+		},
+		func(s *State, args ...string) (WaitFunc, error) {
+			if len(args) != 2 {
+				return nil, ErrUsage
+			}
+			return nil, os.Rename(s.Path(args[0]), s.Path(args[1]))
+		})
+}
+
+// Program returns a new command that runs the named program, found from the
+// host process's PATH (not looked up in the script's PATH).
+func Program(name string, cancel func(*exec.Cmd) error, waitDelay time.Duration) Cmd {
+	var (
+		shortName    string
+		summary      string
+		lookPathOnce sync.Once
+		path         string
+		pathErr      error
+	)
+	if filepath.IsAbs(name) {
+		lookPathOnce.Do(func() { path = filepath.Clean(name) })
+		shortName = strings.TrimSuffix(filepath.Base(path), ".exe")
+		summary = "run the '" + shortName + "' program provided by the script host"
+	} else {
+		shortName = name
+		summary = "run the '" + shortName + "' program from the script host's PATH"
+	}
+
+	return Command(
+		CmdUsage{
+			Summary: summary,
+			Args:    "[args...]",
+			Async:   true,
+		},
+		func(s *State, args ...string) (WaitFunc, error) {
+			lookPathOnce.Do(func() {
+				path, pathErr = exec.LookPath(name)
+			})
+			if pathErr != nil {
+				return nil, pathErr
+			}
+			return startCommand(s, shortName, path, args, cancel, waitDelay)
+		})
+}
+
+// Replace replaces all occurrences of a string in a file with another string.
+func Replace() Cmd {
+	return Command(
+		CmdUsage{
+			Summary: "replace strings in a file",
+			Args:    "[old new]... file",
+			Detail: []string{
+				"The 'old' and 'new' arguments are unquoted as if in quoted Go strings.",
+			},
+		},
+		func(s *State, args ...string) (WaitFunc, error) {
+			if len(args)%2 != 1 {
+				return nil, ErrUsage
+			}
+
+			oldNew := make([]string, 0, len(args)-1)
+			for _, arg := range args[:len(args)-1] {
+				s, err := strconv.Unquote(`"` + arg + `"`)
+				if err != nil {
+					return nil, err
+				}
+				oldNew = append(oldNew, s)
+			}
+
+			r := strings.NewReplacer(oldNew...)
+			file := s.Path(args[len(args)-1])
+
+			data, err := os.ReadFile(file)
+			if err != nil {
+				return nil, err
+			}
+			replaced := r.Replace(string(data))
+
+			return nil, os.WriteFile(file, []byte(replaced), 0666)
+		})
+}
+
+// Rm removes a file or directory.
+//
+// If a directory, Rm also recursively removes that directory's
+// contents.
+func Rm() Cmd {
+	return Command(
+		CmdUsage{
+			Summary: "remove a file or directory",
+			Args:    "path...",
+			Detail: []string{
+				"If the path is a directory, its contents are removed recursively.",
+			},
+		},
+		func(s *State, args ...string) (WaitFunc, error) {
+			if len(args) < 1 {
+				return nil, ErrUsage
+			}
+			for _, arg := range args {
+				if err := removeAll(s.Path(arg)); err != nil {
+					return nil, err
+				}
+			}
+			return nil, nil
+		})
+}
+
+// removeAll removes dir and all files and directories it contains.
+//
+// Unlike os.RemoveAll, removeAll attempts to make the directories writable if
+// needed in order to remove their contents.
+func removeAll(dir string) error {
+	// module cache has 0444 directories;
+	// make them writable in order to remove content.
+	filepath.WalkDir(dir, func(path string, info fs.DirEntry, err error) error {
+		// chmod not only directories, but also things that we couldn't even stat
+		// due to permission errors: they may also be unreadable directories.
+		if err != nil || info.IsDir() {
+			os.Chmod(path, 0777)
+		}
+		return nil
+	})
+	return robustio.RemoveAll(dir)
+}
+
+// Sleep sleeps for the given Go duration or until the script's context is
+// cancelled, whichever happens first.
+func Sleep() Cmd {
+	return Command(
+		CmdUsage{
+			Summary: "sleep for a specified duration",
+			Args:    "duration",
+			Detail: []string{
+				"The duration must be given as a Go time.Duration string.",
+			},
+			Async: true,
+		},
+		func(s *State, args ...string) (WaitFunc, error) {
+			if len(args) != 1 {
+				return nil, ErrUsage
+			}
+
+			d, err := time.ParseDuration(args[0])
+			if err != nil {
+				return nil, err
+			}
+
+			timer := time.NewTimer(d)
+			wait := func(s *State) (stdout, stderr string, err error) {
+				ctx := s.Context()
+				select {
+				case <-ctx.Done():
+					timer.Stop()
+					return "", "", ctx.Err()
+				case <-timer.C:
+					return "", "", nil
+				}
+			}
+			return wait, nil
+		})
+}
+
+// Stderr searches for a regular expression in the stderr buffer.
+func Stderr() Cmd {
+	return Command(
+		CmdUsage{
+			Summary: "find lines in the stderr buffer that match a pattern",
+			Args:    matchUsage + " file",
+			Detail: []string{
+				"The command succeeds if at least one match (or the exact count, if given) is found.",
+				"The -q flag suppresses printing of matches.",
+			},
+			RegexpArgs: firstNonFlag,
+		},
+		func(s *State, args ...string) (WaitFunc, error) {
+			return nil, match(s, args, s.Stderr(), "stderr")
+		})
+}
+
+// Stdout searches for a regular expression in the stdout buffer.
+func Stdout() Cmd {
+	return Command(
+		CmdUsage{
+			Summary: "find lines in the stdout buffer that match a pattern",
+			Args:    matchUsage + " file",
+			Detail: []string{
+				"The command succeeds if at least one match (or the exact count, if given) is found.",
+				"The -q flag suppresses printing of matches.",
+			},
+			RegexpArgs: firstNonFlag,
+		},
+		func(s *State, args ...string) (WaitFunc, error) {
+			return nil, match(s, args, s.Stdout(), "stdout")
+		})
+}
+
+// Stop returns a sentinel error that causes script execution to halt
+// and s.Execute to return with a nil error.
+func Stop() Cmd {
+	return Command(
+		CmdUsage{
+			Summary: "stop execution of the script",
+			Args:    "[msg]",
+			Detail: []string{
+				"The message is written to the script log, but no error is reported from the script engine.",
+			},
+		},
+		func(s *State, args ...string) (WaitFunc, error) {
+			if len(args) > 1 {
+				return nil, ErrUsage
+			}
+			// TODO(bcmills): The argument passed to stop seems redundant with comments.
+			// Either use it systematically or remove it.
+			if len(args) == 1 {
+				return nil, stopError{msg: args[0]}
+			}
+			return nil, stopError{}
+		})
+}
+
+// stopError is the sentinel error type returned by the Stop command.
+type stopError struct {
+	msg string
+}
+
+func (s stopError) Error() string {
+	if s.msg == "" {
+		return "stop"
+	}
+	return "stop: " + s.msg
+}
+
+// Symlink creates a symbolic link.
+func Symlink() Cmd {
+	return Command(
+		CmdUsage{
+			Summary: "create a symlink",
+			Args:    "path -> target",
+			Detail: []string{
+				"Creates path as a symlink to target.",
+				"The '->' token (like in 'ls -l' output on Unix) is required.",
+			},
+		},
+		func(s *State, args ...string) (WaitFunc, error) {
+			if len(args) != 3 || args[1] != "->" {
+				return nil, ErrUsage
+			}
+
+			// Note that the link target args[2] is not interpreted with s.Path:
+			// it will be interpreted relative to the directory file is in.
+			return nil, os.Symlink(filepath.FromSlash(args[2]), s.Path(args[0]))
+		})
+}
+
+// Wait waits for the completion of background commands.
+//
+// When Wait returns, the stdout and stderr buffers contain the concatenation of
+// the background commands' respective outputs in the order in which those
+// commands were started.
+func Wait() Cmd {
+	return Command(
+		CmdUsage{
+			Summary: "wait for completion of background commands",
+			Args:    "",
+			Detail: []string{
+				"Waits for all background commands to complete.",
+				"The output (and any error) from each command is printed to the log in the order in which the commands were started.",
+				"After the call to 'wait', the script's stdout and stderr buffers contain the concatenation of the background commands' outputs.",
+			},
+		},
+		func(s *State, args ...string) (WaitFunc, error) {
+			if len(args) > 0 {
+				return nil, ErrUsage
+			}
+
+			var stdouts, stderrs []string
+			var errs []*CommandError
+			for _, bg := range s.background {
+				stdout, stderr, err := bg.wait(s)
+
+				beforeArgs := ""
+				if len(bg.args) > 0 {
+					beforeArgs = " "
+				}
+				s.Logf("[background] %s%s%s\n", bg.name, beforeArgs, quoteArgs(bg.args))
+
+				if stdout != "" {
+					s.Logf("[stdout]\n%s", stdout)
+					stdouts = append(stdouts, stdout)
+				}
+				if stderr != "" {
+					s.Logf("[stderr]\n%s", stderr)
+					stderrs = append(stderrs, stderr)
+				}
+				if err != nil {
+					s.Logf("[%v]\n", err)
+				}
+				if cmdErr := checkStatus(bg.command, err); cmdErr != nil {
+					errs = append(errs, cmdErr.(*CommandError))
+				}
+			}
+
+			s.stdout = strings.Join(stdouts, "")
+			s.stderr = strings.Join(stderrs, "")
+			s.background = nil
+			if len(errs) > 0 {
+				return nil, waitError{errs: errs}
+			}
+			return nil, nil
+		})
+}
+
+// A waitError wraps one or more errors returned by background commands.
+type waitError struct {
+	errs []*CommandError
+}
+
+func (w waitError) Error() string {
+	b := new(strings.Builder)
+	for i, err := range w.errs {
+		if i != 0 {
+			b.WriteString("\n")
+		}
+		b.WriteString(err.Error())
+	}
+	return b.String()
+}
+
+func (w waitError) Unwrap() error {
+	if len(w.errs) == 1 {
+		return w.errs[0]
+	}
+	return nil
+}
diff --git a/src/cmd/go/internal/script/cmds_other.go b/src/cmd/go/internal/script/cmds_other.go
new file mode 100644
index 0000000..847b225
--- /dev/null
+++ b/src/cmd/go/internal/script/cmds_other.go
@@ -0,0 +1,11 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !(unix || windows)
+
+package script
+
+func isETXTBSY(err error) bool {
+	return false
+}
diff --git a/src/cmd/go/internal/script/cmds_posix.go b/src/cmd/go/internal/script/cmds_posix.go
new file mode 100644
index 0000000..2525f6e
--- /dev/null
+++ b/src/cmd/go/internal/script/cmds_posix.go
@@ -0,0 +1,16 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build unix || windows
+
+package script
+
+import (
+	"errors"
+	"syscall"
+)
+
+func isETXTBSY(err error) bool {
+	return errors.Is(err, syscall.ETXTBSY)
+}
diff --git a/src/cmd/go/internal/script/conds.go b/src/cmd/go/internal/script/conds.go
new file mode 100644
index 0000000..d70f274
--- /dev/null
+++ b/src/cmd/go/internal/script/conds.go
@@ -0,0 +1,205 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package script
+
+import (
+	"cmd/go/internal/imports"
+	"fmt"
+	"os"
+	"runtime"
+	"sync"
+)
+
+// DefaultConds returns a set of broadly useful script conditions.
+//
+// Run the 'help' command within a script engine to view a list of the available
+// conditions.
+func DefaultConds() map[string]Cond {
+	conds := make(map[string]Cond)
+
+	conds["GOOS"] = PrefixCondition(
+		"runtime.GOOS == <suffix>",
+		func(_ *State, suffix string) (bool, error) {
+			if suffix == runtime.GOOS {
+				return true, nil
+			}
+			if _, ok := imports.KnownOS[suffix]; !ok {
+				return false, fmt.Errorf("unrecognized GOOS %q", suffix)
+			}
+			return false, nil
+		})
+
+	conds["GOARCH"] = PrefixCondition(
+		"runtime.GOARCH == <suffix>",
+		func(_ *State, suffix string) (bool, error) {
+			if suffix == runtime.GOARCH {
+				return true, nil
+			}
+			if _, ok := imports.KnownArch[suffix]; !ok {
+				return false, fmt.Errorf("unrecognized GOOS %q", suffix)
+			}
+			return false, nil
+		})
+
+	conds["compiler"] = PrefixCondition(
+		"runtime.Compiler == <suffix>",
+		func(_ *State, suffix string) (bool, error) {
+			if suffix == runtime.Compiler {
+				return true, nil
+			}
+			switch suffix {
+			case "gc", "gccgo":
+				return false, nil
+			default:
+				return false, fmt.Errorf("unrecognized compiler %q", suffix)
+			}
+		})
+
+	conds["root"] = BoolCondition("os.Geteuid() == 0", os.Geteuid() == 0)
+
+	return conds
+}
+
+// Condition returns a Cond with the given summary and evaluation function.
+func Condition(summary string, eval func(*State) (bool, error)) Cond {
+	return &funcCond{eval: eval, usage: CondUsage{Summary: summary}}
+}
+
+type funcCond struct {
+	eval  func(*State) (bool, error)
+	usage CondUsage
+}
+
+func (c *funcCond) Usage() *CondUsage { return &c.usage }
+
+func (c *funcCond) Eval(s *State, suffix string) (bool, error) {
+	if suffix != "" {
+		return false, ErrUsage
+	}
+	return c.eval(s)
+}
+
+// PrefixCondition returns a Cond with the given summary and evaluation function.
+func PrefixCondition(summary string, eval func(*State, string) (bool, error)) Cond {
+	return &prefixCond{eval: eval, usage: CondUsage{Summary: summary, Prefix: true}}
+}
+
+type prefixCond struct {
+	eval  func(*State, string) (bool, error)
+	usage CondUsage
+}
+
+func (c *prefixCond) Usage() *CondUsage { return &c.usage }
+
+func (c *prefixCond) Eval(s *State, suffix string) (bool, error) {
+	return c.eval(s, suffix)
+}
+
+// BoolCondition returns a Cond with the given truth value and summary.
+// The Cond rejects the use of condition suffixes.
+func BoolCondition(summary string, v bool) Cond {
+	return &boolCond{v: v, usage: CondUsage{Summary: summary}}
+}
+
+type boolCond struct {
+	v     bool
+	usage CondUsage
+}
+
+func (b *boolCond) Usage() *CondUsage { return &b.usage }
+
+func (b *boolCond) Eval(s *State, suffix string) (bool, error) {
+	if suffix != "" {
+		return false, ErrUsage
+	}
+	return b.v, nil
+}
+
+// OnceCondition returns a Cond that calls eval the first time the condition is
+// evaluated. Future calls reuse the same result.
+//
+// The eval function is not passed a *State because the condition is cached
+// across all execution states and must not vary by state.
+func OnceCondition(summary string, eval func() (bool, error)) Cond {
+	return &onceCond{eval: eval, usage: CondUsage{Summary: summary}}
+}
+
+type onceCond struct {
+	once  sync.Once
+	v     bool
+	err   error
+	eval  func() (bool, error)
+	usage CondUsage
+}
+
+func (l *onceCond) Usage() *CondUsage { return &l.usage }
+
+func (l *onceCond) Eval(s *State, suffix string) (bool, error) {
+	if suffix != "" {
+		return false, ErrUsage
+	}
+	l.once.Do(func() { l.v, l.err = l.eval() })
+	return l.v, l.err
+}
+
+// CachedCondition is like Condition but only calls eval the first time the
+// condition is evaluated for a given suffix.
+// Future calls with the same suffix reuse the earlier result.
+//
+// The eval function is not passed a *State because the condition is cached
+// across all execution states and must not vary by state.
+func CachedCondition(summary string, eval func(string) (bool, error)) Cond {
+	return &cachedCond{eval: eval, usage: CondUsage{Summary: summary, Prefix: true}}
+}
+
+type cachedCond struct {
+	m     sync.Map
+	eval  func(string) (bool, error)
+	usage CondUsage
+}
+
+func (c *cachedCond) Usage() *CondUsage { return &c.usage }
+
+func (c *cachedCond) Eval(_ *State, suffix string) (bool, error) {
+	for {
+		var ready chan struct{}
+
+		v, loaded := c.m.Load(suffix)
+		if !loaded {
+			ready = make(chan struct{})
+			v, loaded = c.m.LoadOrStore(suffix, (<-chan struct{})(ready))
+
+			if !loaded {
+				inPanic := true
+				defer func() {
+					if inPanic {
+						c.m.Delete(suffix)
+					}
+					close(ready)
+				}()
+
+				b, err := c.eval(suffix)
+				inPanic = false
+
+				if err == nil {
+					c.m.Store(suffix, b)
+					return b, nil
+				} else {
+					c.m.Store(suffix, err)
+					return false, err
+				}
+			}
+		}
+
+		switch v := v.(type) {
+		case bool:
+			return v, nil
+		case error:
+			return false, v
+		case <-chan struct{}:
+			<-v
+		}
+	}
+}
diff --git a/src/cmd/go/internal/script/engine.go b/src/cmd/go/internal/script/engine.go
new file mode 100644
index 0000000..dfce755
--- /dev/null
+++ b/src/cmd/go/internal/script/engine.go
@@ -0,0 +1,788 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package script implements a small, customizable, platform-agnostic scripting
+// language.
+//
+// Scripts are run by an [Engine] configured with a set of available commands
+// and conditions that guard those commands. Each script has an associated
+// working directory and environment, along with a buffer containing the stdout
+// and stderr output of a prior command, tracked in a [State] that commands can
+// inspect and modify.
+//
+// The default commands configured by [NewEngine] resemble a simplified Unix
+// shell.
+//
+// # Script Language
+//
+// Each line of a script is parsed into a sequence of space-separated command
+// words, with environment variable expansion within each word and # marking an
+// end-of-line comment. Additional variables named ':' and '/' are expanded
+// within script arguments (expanding to the value of os.PathListSeparator and
+// os.PathSeparator respectively) but are not inherited in subprocess
+// environments.
+//
+// Adding single quotes around text keeps spaces in that text from being treated
+// as word separators and also disables environment variable expansion.
+// Inside a single-quoted block of text, a repeated single quote indicates
+// a literal single quote, as in:
+//
+//	'Don''t communicate by sharing memory.'
+//
+// A line beginning with # is a comment and conventionally explains what is
+// being done or tested at the start of a new section of the script.
+//
+// Commands are executed one at a time, and errors are checked for each command;
+// if any command fails unexpectedly, no subsequent commands in the script are
+// executed. The command prefix ! indicates that the command on the rest of the
+// line (typically go or a matching predicate) must fail instead of succeeding.
+// The command prefix ? indicates that the command may or may not succeed, but
+// the script should continue regardless.
+//
+// The command prefix [cond] indicates that the command on the rest of the line
+// should only run when the condition is satisfied.
+//
+// A condition can be negated: [!root] means to run the rest of the line only if
+// the user is not root. Multiple conditions may be given for a single command,
+// for example, '[linux] [amd64] skip'. The command will run if all conditions
+// are satisfied.
+package script
+
+import (
+	"bufio"
+	"context"
+	"errors"
+	"fmt"
+	"io"
+	"sort"
+	"strings"
+	"time"
+)
+
+// An Engine stores the configuration for executing a set of scripts.
+//
+// The same Engine may execute multiple scripts concurrently.
+type Engine struct {
+	Cmds  map[string]Cmd
+	Conds map[string]Cond
+
+	// If Quiet is true, Execute deletes log prints from the previous
+	// section when starting a new section.
+	Quiet bool
+}
+
+// NewEngine returns an Engine configured with a basic set of commands and conditions.
+func NewEngine() *Engine {
+	return &Engine{
+		Cmds:  DefaultCmds(),
+		Conds: DefaultConds(),
+	}
+}
+
+// A Cmd is a command that is available to a script.
+type Cmd interface {
+	// Run begins running the command.
+	//
+	// If the command produces output or can be run in the background, run returns
+	// a WaitFunc that will be called to obtain the result of the command and
+	// update the engine's stdout and stderr buffers.
+	//
+	// Run itself and the returned WaitFunc may inspect and/or modify the State,
+	// but the State's methods must not be called concurrently after Run has
+	// returned.
+	//
+	// Run may retain and access the args slice until the WaitFunc has returned.
+	Run(s *State, args ...string) (WaitFunc, error)
+
+	// Usage returns the usage for the command, which the caller must not modify.
+	Usage() *CmdUsage
+}
+
+// A WaitFunc is a function called to retrieve the results of a Cmd.
+type WaitFunc func(*State) (stdout, stderr string, err error)
+
+// A CmdUsage describes the usage of a Cmd, independent of its name
+// (which can change based on its registration).
+type CmdUsage struct {
+	Summary string   // in the style of the Name section of a Unix 'man' page, omitting the name
+	Args    string   // a brief synopsis of the command's arguments (only)
+	Detail  []string // zero or more sentences in the style of the Description section of a Unix 'man' page
+
+	// If Async is true, the Cmd is meaningful to run in the background, and its
+	// Run method must return either a non-nil WaitFunc or a non-nil error.
+	Async bool
+
+	// RegexpArgs reports which arguments, if any, should be treated as regular
+	// expressions. It takes as input the raw, unexpanded arguments and returns
+	// the list of argument indices that will be interpreted as regular
+	// expressions.
+	//
+	// If RegexpArgs is nil, all arguments are assumed not to be regular
+	// expressions.
+	RegexpArgs func(rawArgs ...string) []int
+}
+
+// A Cond is a condition deciding whether a command should be run.
+type Cond interface {
+	// Eval reports whether the condition applies to the given State.
+	//
+	// If the condition's usage reports that it is a prefix,
+	// the condition must be used with a suffix.
+	// Otherwise, the passed-in suffix argument is always the empty string.
+	Eval(s *State, suffix string) (bool, error)
+
+	// Usage returns the usage for the condition, which the caller must not modify.
+	Usage() *CondUsage
+}
+
+// A CondUsage describes the usage of a Cond, independent of its name
+// (which can change based on its registration).
+type CondUsage struct {
+	Summary string // a single-line summary of when the condition is true
+
+	// If Prefix is true, the condition is a prefix and requires a
+	// colon-separated suffix (like "[GOOS:linux]" for the "GOOS" condition).
+	// The suffix may be the empty string (like "[prefix:]").
+	Prefix bool
+}
+
+// Execute reads and executes script, writing the output to log.
+//
+// Execute stops and returns an error at the first command that does not succeed.
+// The returned error's text begins with "file:line: ".
+//
+// If the script runs to completion or ends by a 'stop' command,
+// Execute returns nil.
+//
+// Execute does not stop background commands started by the script
+// before returning. To stop those, use [State.CloseAndWait] or the
+// [Wait] command.
+func (e *Engine) Execute(s *State, file string, script *bufio.Reader, log io.Writer) (err error) {
+	defer func(prev *Engine) { s.engine = prev }(s.engine)
+	s.engine = e
+
+	var sectionStart time.Time
+	// endSection flushes the logs for the current section from s.log to log.
+	// ok indicates whether all commands in the section succeeded.
+	endSection := func(ok bool) error {
+		var err error
+		if sectionStart.IsZero() {
+			// We didn't write a section header or record a timestamp, so just dump the
+			// whole log without those.
+			if s.log.Len() > 0 {
+				err = s.flushLog(log)
+			}
+		} else if s.log.Len() == 0 {
+			// Adding elapsed time for doing nothing is meaningless, so don't.
+			_, err = io.WriteString(log, "\n")
+		} else {
+			// Insert elapsed time for section at the end of the section's comment.
+			_, err = fmt.Fprintf(log, " (%.3fs)\n", time.Since(sectionStart).Seconds())
+
+			if err == nil && (!ok || !e.Quiet) {
+				err = s.flushLog(log)
+			} else {
+				s.log.Reset()
+			}
+		}
+
+		sectionStart = time.Time{}
+		return err
+	}
+
+	var lineno int
+	lineErr := func(err error) error {
+		if errors.As(err, new(*CommandError)) {
+			return err
+		}
+		return fmt.Errorf("%s:%d: %w", file, lineno, err)
+	}
+
+	// In case of failure or panic, flush any pending logs for the section.
+	defer func() {
+		if sErr := endSection(false); sErr != nil && err == nil {
+			err = lineErr(sErr)
+		}
+	}()
+
+	for {
+		if err := s.ctx.Err(); err != nil {
+			// This error wasn't produced by any particular command,
+			// so don't wrap it in a CommandError.
+			return lineErr(err)
+		}
+
+		line, err := script.ReadString('\n')
+		if err == io.EOF {
+			if line == "" {
+				break // Reached the end of the script.
+			}
+			// If the script doesn't end in a newline, interpret the final line.
+		} else if err != nil {
+			return lineErr(err)
+		}
+		line = strings.TrimSuffix(line, "\n")
+		lineno++
+
+		// The comment character "#" at the start of the line delimits a section of
+		// the script.
+		if strings.HasPrefix(line, "#") {
+			// If there was a previous section, the fact that we are starting a new
+			// one implies the success of the previous one.
+			//
+			// At the start of the script, the state may also contain accumulated logs
+			// from commands executed on the State outside of the engine in order to
+			// set it up; flush those logs too.
+			if err := endSection(true); err != nil {
+				return lineErr(err)
+			}
+
+			// Log the section start without a newline so that we can add
+			// a timestamp for the section when it ends.
+			_, err = fmt.Fprintf(log, "%s", line)
+			sectionStart = time.Now()
+			if err != nil {
+				return lineErr(err)
+			}
+			continue
+		}
+
+		cmd, err := parse(file, lineno, line)
+		if cmd == nil && err == nil {
+			continue // Ignore blank lines.
+		}
+		s.Logf("> %s\n", line)
+		if err != nil {
+			return lineErr(err)
+		}
+
+		// Evaluate condition guards.
+		ok, err := e.conditionsActive(s, cmd.conds)
+		if err != nil {
+			return lineErr(err)
+		}
+		if !ok {
+			s.Logf("[condition not met]\n")
+			continue
+		}
+
+		impl := e.Cmds[cmd.name]
+
+		// Expand variables in arguments.
+		var regexpArgs []int
+		if impl != nil {
+			usage := impl.Usage()
+			if usage.RegexpArgs != nil {
+				// First join rawArgs without expansion to pass to RegexpArgs.
+				rawArgs := make([]string, 0, len(cmd.rawArgs))
+				for _, frags := range cmd.rawArgs {
+					var b strings.Builder
+					for _, frag := range frags {
+						b.WriteString(frag.s)
+					}
+					rawArgs = append(rawArgs, b.String())
+				}
+				regexpArgs = usage.RegexpArgs(rawArgs...)
+			}
+		}
+		cmd.args = expandArgs(s, cmd.rawArgs, regexpArgs)
+
+		// Run the command.
+		err = e.runCommand(s, cmd, impl)
+		if err != nil {
+			if stop := (stopError{}); errors.As(err, &stop) {
+				// Since the 'stop' command halts execution of the entire script,
+				// log its message separately from the section in which it appears.
+				err = endSection(true)
+				s.Logf("%v\n", s)
+				if err == nil {
+					return nil
+				}
+			}
+			return lineErr(err)
+		}
+	}
+
+	if err := endSection(true); err != nil {
+		return lineErr(err)
+	}
+	return nil
+}
+
+// A command is a complete command parsed from a script.
+type command struct {
+	file       string
+	line       int
+	want       expectedStatus
+	conds      []condition // all must be satisfied
+	name       string      // the name of the command; must be non-empty
+	rawArgs    [][]argFragment
+	args       []string // shell-expanded arguments following name
+	background bool     // command should run in background (ends with a trailing &)
+}
+
+// A expectedStatus describes the expected outcome of a command.
+// Script execution halts when a command does not match its expected status.
+type expectedStatus string
+
+const (
+	success          expectedStatus = ""
+	failure          expectedStatus = "!"
+	successOrFailure expectedStatus = "?"
+)
+
+type argFragment struct {
+	s      string
+	quoted bool // if true, disable variable expansion for this fragment
+}
+
+type condition struct {
+	want bool
+	tag  string
+}
+
+const argSepChars = " \t\r\n#"
+
+// parse parses a single line as a list of space-separated arguments.
+// subject to environment variable expansion (but not resplitting).
+// Single quotes around text disable splitting and expansion.
+// To embed a single quote, double it:
+//
+//	'Don''t communicate by sharing memory.'
+func parse(filename string, lineno int, line string) (cmd *command, err error) {
+	cmd = &command{file: filename, line: lineno}
+	var (
+		rawArg []argFragment // text fragments of current arg so far (need to add line[start:i])
+		start  = -1          // if >= 0, position where current arg text chunk starts
+		quoted = false       // currently processing quoted text
+	)
+
+	flushArg := func() error {
+		if len(rawArg) == 0 {
+			return nil // Nothing to flush.
+		}
+		defer func() { rawArg = nil }()
+
+		if cmd.name == "" && len(rawArg) == 1 && !rawArg[0].quoted {
+			arg := rawArg[0].s
+
+			// Command prefix ! means negate the expectations about this command:
+			// go command should fail, match should not be found, etc.
+			// Prefix ? means allow either success or failure.
+			switch want := expectedStatus(arg); want {
+			case failure, successOrFailure:
+				if cmd.want != "" {
+					return errors.New("duplicated '!' or '?' token")
+				}
+				cmd.want = want
+				return nil
+			}
+
+			// Command prefix [cond] means only run this command if cond is satisfied.
+			if strings.HasPrefix(arg, "[") && strings.HasSuffix(arg, "]") {
+				want := true
+				arg = strings.TrimSpace(arg[1 : len(arg)-1])
+				if strings.HasPrefix(arg, "!") {
+					want = false
+					arg = strings.TrimSpace(arg[1:])
+				}
+				if arg == "" {
+					return errors.New("empty condition")
+				}
+				cmd.conds = append(cmd.conds, condition{want: want, tag: arg})
+				return nil
+			}
+
+			if arg == "" {
+				return errors.New("empty command")
+			}
+			cmd.name = arg
+			return nil
+		}
+
+		cmd.rawArgs = append(cmd.rawArgs, rawArg)
+		return nil
+	}
+
+	for i := 0; ; i++ {
+		if !quoted && (i >= len(line) || strings.ContainsRune(argSepChars, rune(line[i]))) {
+			// Found arg-separating space.
+			if start >= 0 {
+				rawArg = append(rawArg, argFragment{s: line[start:i], quoted: false})
+				start = -1
+			}
+			if err := flushArg(); err != nil {
+				return nil, err
+			}
+			if i >= len(line) || line[i] == '#' {
+				break
+			}
+			continue
+		}
+		if i >= len(line) {
+			return nil, errors.New("unterminated quoted argument")
+		}
+		if line[i] == '\'' {
+			if !quoted {
+				// starting a quoted chunk
+				if start >= 0 {
+					rawArg = append(rawArg, argFragment{s: line[start:i], quoted: false})
+				}
+				start = i + 1
+				quoted = true
+				continue
+			}
+			// 'foo''bar' means foo'bar, like in rc shell and Pascal.
+			if i+1 < len(line) && line[i+1] == '\'' {
+				rawArg = append(rawArg, argFragment{s: line[start:i], quoted: true})
+				start = i + 1
+				i++ // skip over second ' before next iteration
+				continue
+			}
+			// ending a quoted chunk
+			rawArg = append(rawArg, argFragment{s: line[start:i], quoted: true})
+			start = i + 1
+			quoted = false
+			continue
+		}
+		// found character worth saving; make sure we're saving
+		if start < 0 {
+			start = i
+		}
+	}
+
+	if cmd.name == "" {
+		if cmd.want != "" || len(cmd.conds) > 0 || len(cmd.rawArgs) > 0 || cmd.background {
+			// The line contains a command prefix or suffix, but no actual command.
+			return nil, errors.New("missing command")
+		}
+
+		// The line is blank, or contains only a comment.
+		return nil, nil
+	}
+
+	if n := len(cmd.rawArgs); n > 0 {
+		last := cmd.rawArgs[n-1]
+		if len(last) == 1 && !last[0].quoted && last[0].s == "&" {
+			cmd.background = true
+			cmd.rawArgs = cmd.rawArgs[:n-1]
+		}
+	}
+	return cmd, nil
+}
+
+// expandArgs expands the shell variables in rawArgs and joins them to form the
+// final arguments to pass to a command.
+func expandArgs(s *State, rawArgs [][]argFragment, regexpArgs []int) []string {
+	args := make([]string, 0, len(rawArgs))
+	for i, frags := range rawArgs {
+		isRegexp := false
+		for _, j := range regexpArgs {
+			if i == j {
+				isRegexp = true
+				break
+			}
+		}
+
+		var b strings.Builder
+		for _, frag := range frags {
+			if frag.quoted {
+				b.WriteString(frag.s)
+			} else {
+				b.WriteString(s.ExpandEnv(frag.s, isRegexp))
+			}
+		}
+		args = append(args, b.String())
+	}
+	return args
+}
+
+// quoteArgs returns a string that parse would parse as args when passed to a command.
+//
+// TODO(bcmills): This function should have a fuzz test.
+func quoteArgs(args []string) string {
+	var b strings.Builder
+	for i, arg := range args {
+		if i > 0 {
+			b.WriteString(" ")
+		}
+		if strings.ContainsAny(arg, "'"+argSepChars) {
+			// Quote the argument to a form that would be parsed as a single argument.
+			b.WriteString("'")
+			b.WriteString(strings.ReplaceAll(arg, "'", "''"))
+			b.WriteString("'")
+		} else {
+			b.WriteString(arg)
+		}
+	}
+	return b.String()
+}
+
+func (e *Engine) conditionsActive(s *State, conds []condition) (bool, error) {
+	for _, cond := range conds {
+		var impl Cond
+		prefix, suffix, ok := strings.Cut(cond.tag, ":")
+		if ok {
+			impl = e.Conds[prefix]
+			if impl == nil {
+				return false, fmt.Errorf("unknown condition prefix %q", prefix)
+			}
+			if !impl.Usage().Prefix {
+				return false, fmt.Errorf("condition %q cannot be used with a suffix", prefix)
+			}
+		} else {
+			impl = e.Conds[cond.tag]
+			if impl == nil {
+				return false, fmt.Errorf("unknown condition %q", cond.tag)
+			}
+			if impl.Usage().Prefix {
+				return false, fmt.Errorf("condition %q requires a suffix", cond.tag)
+			}
+		}
+		active, err := impl.Eval(s, suffix)
+
+		if err != nil {
+			return false, fmt.Errorf("evaluating condition %q: %w", cond.tag, err)
+		}
+		if active != cond.want {
+			return false, nil
+		}
+	}
+
+	return true, nil
+}
+
+func (e *Engine) runCommand(s *State, cmd *command, impl Cmd) error {
+	if impl == nil {
+		return cmdError(cmd, errors.New("unknown command"))
+	}
+
+	async := impl.Usage().Async
+	if cmd.background && !async {
+		return cmdError(cmd, errors.New("command cannot be run in background"))
+	}
+
+	wait, runErr := impl.Run(s, cmd.args...)
+	if wait == nil {
+		if async && runErr == nil {
+			return cmdError(cmd, errors.New("internal error: async command returned a nil WaitFunc"))
+		}
+		return checkStatus(cmd, runErr)
+	}
+	if runErr != nil {
+		return cmdError(cmd, errors.New("internal error: command returned both an error and a WaitFunc"))
+	}
+
+	if cmd.background {
+		s.background = append(s.background, backgroundCmd{
+			command: cmd,
+			wait:    wait,
+		})
+		// Clear stdout and stderr, since they no longer correspond to the last
+		// command executed.
+		s.stdout = ""
+		s.stderr = ""
+		return nil
+	}
+
+	if wait != nil {
+		stdout, stderr, waitErr := wait(s)
+		s.stdout = stdout
+		s.stderr = stderr
+		if stdout != "" {
+			s.Logf("[stdout]\n%s", stdout)
+		}
+		if stderr != "" {
+			s.Logf("[stderr]\n%s", stderr)
+		}
+		if cmdErr := checkStatus(cmd, waitErr); cmdErr != nil {
+			return cmdErr
+		}
+		if waitErr != nil {
+			// waitErr was expected (by cmd.want), so log it instead of returning it.
+			s.Logf("[%v]\n", waitErr)
+		}
+	}
+	return nil
+}
+
+func checkStatus(cmd *command, err error) error {
+	if err == nil {
+		if cmd.want == failure {
+			return cmdError(cmd, ErrUnexpectedSuccess)
+		}
+		return nil
+	}
+
+	if s := (stopError{}); errors.As(err, &s) {
+		// This error originated in the Stop command.
+		// Propagate it as-is.
+		return cmdError(cmd, err)
+	}
+
+	if w := (waitError{}); errors.As(err, &w) {
+		// This error was surfaced from a background process by a call to Wait.
+		// Add a call frame for Wait itself, but ignore its "want" field.
+		// (Wait itself cannot fail to wait on commands or else it would leak
+		// processes and/or goroutines — so a negative assertion for it would be at
+		// best ambiguous.)
+		return cmdError(cmd, err)
+	}
+
+	if cmd.want == success {
+		return cmdError(cmd, err)
+	}
+
+	if cmd.want == failure && (errors.Is(err, context.DeadlineExceeded) || errors.Is(err, context.Canceled)) {
+		// The command was terminated because the script is no longer interested in
+		// its output, so we don't know what it would have done had it run to
+		// completion — for all we know, it could have exited without error if it
+		// ran just a smidge faster.
+		return cmdError(cmd, err)
+	}
+
+	return nil
+}
+
+// ListCmds prints to w a list of the named commands,
+// annotating each with its arguments and a short usage summary.
+// If verbose is true, ListCmds prints full details for each command.
+//
+// Each of the name arguments should be a command name.
+// If no names are passed as arguments, ListCmds lists all the
+// commands registered in e.
+func (e *Engine) ListCmds(w io.Writer, verbose bool, names ...string) error {
+	if names == nil {
+		names = make([]string, 0, len(e.Cmds))
+		for name := range e.Cmds {
+			names = append(names, name)
+		}
+		sort.Strings(names)
+	}
+
+	for _, name := range names {
+		cmd := e.Cmds[name]
+		usage := cmd.Usage()
+
+		suffix := ""
+		if usage.Async {
+			suffix = " [&]"
+		}
+
+		_, err := fmt.Fprintf(w, "%s %s%s\n\t%s\n", name, usage.Args, suffix, usage.Summary)
+		if err != nil {
+			return err
+		}
+
+		if verbose {
+			if _, err := io.WriteString(w, "\n"); err != nil {
+				return err
+			}
+			for _, line := range usage.Detail {
+				if err := wrapLine(w, line, 60, "\t"); err != nil {
+					return err
+				}
+			}
+			if _, err := io.WriteString(w, "\n"); err != nil {
+				return err
+			}
+		}
+	}
+
+	return nil
+}
+
+func wrapLine(w io.Writer, line string, cols int, indent string) error {
+	line = strings.TrimLeft(line, " ")
+	for len(line) > cols {
+		bestSpace := -1
+		for i, r := range line {
+			if r == ' ' {
+				if i <= cols || bestSpace < 0 {
+					bestSpace = i
+				}
+				if i > cols {
+					break
+				}
+			}
+		}
+		if bestSpace < 0 {
+			break
+		}
+
+		if _, err := fmt.Fprintf(w, "%s%s\n", indent, line[:bestSpace]); err != nil {
+			return err
+		}
+		line = line[bestSpace+1:]
+	}
+
+	_, err := fmt.Fprintf(w, "%s%s\n", indent, line)
+	return err
+}
+
+// ListConds prints to w a list of conditions, one per line,
+// annotating each with a description and whether the condition
+// is true in the state s (if s is non-nil).
+//
+// Each of the tag arguments should be a condition string of
+// the form "name" or "name:suffix". If no tags are passed as
+// arguments, ListConds lists all conditions registered in
+// the engine e.
+func (e *Engine) ListConds(w io.Writer, s *State, tags ...string) error {
+	if tags == nil {
+		tags = make([]string, 0, len(e.Conds))
+		for name := range e.Conds {
+			tags = append(tags, name)
+		}
+		sort.Strings(tags)
+	}
+
+	for _, tag := range tags {
+		if prefix, suffix, ok := strings.Cut(tag, ":"); ok {
+			cond := e.Conds[prefix]
+			if cond == nil {
+				return fmt.Errorf("unknown condition prefix %q", prefix)
+			}
+			usage := cond.Usage()
+			if !usage.Prefix {
+				return fmt.Errorf("condition %q cannot be used with a suffix", prefix)
+			}
+
+			activeStr := ""
+			if s != nil {
+				if active, _ := cond.Eval(s, suffix); active {
+					activeStr = " (active)"
+				}
+			}
+			_, err := fmt.Fprintf(w, "[%s]%s\n\t%s\n", tag, activeStr, usage.Summary)
+			if err != nil {
+				return err
+			}
+			continue
+		}
+
+		cond := e.Conds[tag]
+		if cond == nil {
+			return fmt.Errorf("unknown condition %q", tag)
+		}
+		var err error
+		usage := cond.Usage()
+		if usage.Prefix {
+			_, err = fmt.Fprintf(w, "[%s:*]\n\t%s\n", tag, usage.Summary)
+		} else {
+			activeStr := ""
+			if s != nil {
+				if ok, _ := cond.Eval(s, ""); ok {
+					activeStr = " (active)"
+				}
+			}
+			_, err = fmt.Fprintf(w, "[%s]%s\n\t%s\n", tag, activeStr, usage.Summary)
+		}
+		if err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
diff --git a/src/cmd/go/internal/script/errors.go b/src/cmd/go/internal/script/errors.go
new file mode 100644
index 0000000..7f43e72
--- /dev/null
+++ b/src/cmd/go/internal/script/errors.go
@@ -0,0 +1,64 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package script
+
+import (
+	"errors"
+	"fmt"
+)
+
+// ErrUnexpectedSuccess indicates that a script command that was expected to
+// fail (as indicated by a "!" prefix) instead completed successfully.
+var ErrUnexpectedSuccess = errors.New("unexpected success")
+
+// A CommandError describes an error resulting from attempting to execute a
+// specific command.
+type CommandError struct {
+	File string
+	Line int
+	Op   string
+	Args []string
+	Err  error
+}
+
+func cmdError(cmd *command, err error) *CommandError {
+	return &CommandError{
+		File: cmd.file,
+		Line: cmd.line,
+		Op:   cmd.name,
+		Args: cmd.args,
+		Err:  err,
+	}
+}
+
+func (e *CommandError) Error() string {
+	if len(e.Args) == 0 {
+		return fmt.Sprintf("%s:%d: %s: %v", e.File, e.Line, e.Op, e.Err)
+	}
+	return fmt.Sprintf("%s:%d: %s %s: %v", e.File, e.Line, e.Op, quoteArgs(e.Args), e.Err)
+}
+
+func (e *CommandError) Unwrap() error { return e.Err }
+
+// A UsageError reports the valid arguments for a command.
+//
+// It may be returned in response to invalid arguments.
+type UsageError struct {
+	Name    string
+	Command Cmd
+}
+
+func (e *UsageError) Error() string {
+	usage := e.Command.Usage()
+	suffix := ""
+	if usage.Async {
+		suffix = " [&]"
+	}
+	return fmt.Sprintf("usage: %s %s%s", e.Name, usage.Args, suffix)
+}
+
+// ErrUsage may be returned by a Command to indicate that it was called with
+// invalid arguments; its Usage method may be called to obtain details.
+var ErrUsage = errors.New("invalid usage")
diff --git a/src/cmd/go/internal/script/scripttest/scripttest.go b/src/cmd/go/internal/script/scripttest/scripttest.go
new file mode 100644
index 0000000..0696624
--- /dev/null
+++ b/src/cmd/go/internal/script/scripttest/scripttest.go
@@ -0,0 +1,143 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package scripttest adapts the script engine for use in tests.
+package scripttest
+
+import (
+	"bufio"
+	"cmd/go/internal/script"
+	"errors"
+	"io"
+	"os/exec"
+	"strings"
+	"testing"
+)
+
+// DefaultCmds returns a set of broadly useful script commands.
+//
+// This set includes all of the commands in script.DefaultCmds,
+// as well as a "skip" command that halts the script and causes the
+// testing.TB passed to Run to be skipped.
+func DefaultCmds() map[string]script.Cmd {
+	cmds := script.DefaultCmds()
+	cmds["skip"] = Skip()
+	return cmds
+}
+
+// DefaultConds returns a set of broadly useful script conditions.
+//
+// This set includes all of the conditions in script.DefaultConds,
+// as well as:
+//
+//   - Conditions of the form "exec:foo" are active when the executable "foo" is
+//     found in the test process's PATH, and inactive when the executable is
+//     not found.
+//
+//   - "short" is active when testing.Short() is true.
+//
+//   - "verbose" is active when testing.Verbose() is true.
+func DefaultConds() map[string]script.Cond {
+	conds := script.DefaultConds()
+	conds["exec"] = CachedExec()
+	conds["short"] = script.BoolCondition("testing.Short()", testing.Short())
+	conds["verbose"] = script.BoolCondition("testing.Verbose()", testing.Verbose())
+	return conds
+}
+
+// Run runs the script from the given filename starting at the given initial state.
+// When the script completes, Run closes the state.
+func Run(t testing.TB, e *script.Engine, s *script.State, filename string, testScript io.Reader) {
+	t.Helper()
+	err := func() (err error) {
+		log := new(strings.Builder)
+		log.WriteString("\n") // Start output on a new line for consistent indentation.
+
+		// Defer writing to the test log in case the script engine panics during execution,
+		// but write the log before we write the final "skip" or "FAIL" line.
+		t.Helper()
+		defer func() {
+			t.Helper()
+
+			if closeErr := s.CloseAndWait(log); err == nil {
+				err = closeErr
+			}
+
+			if log.Len() > 0 {
+				t.Log(strings.TrimSuffix(log.String(), "\n"))
+			}
+		}()
+
+		if testing.Verbose() {
+			// Add the environment to the start of the script log.
+			wait, err := script.Env().Run(s)
+			if err != nil {
+				t.Fatal(err)
+			}
+			if wait != nil {
+				stdout, stderr, err := wait(s)
+				if err != nil {
+					t.Fatalf("env: %v\n%s", err, stderr)
+				}
+				if len(stdout) > 0 {
+					s.Logf("%s\n", stdout)
+				}
+			}
+		}
+
+		return e.Execute(s, filename, bufio.NewReader(testScript), log)
+	}()
+
+	if skip := (skipError{}); errors.As(err, &skip) {
+		if skip.msg == "" {
+			t.Skip("SKIP")
+		} else {
+			t.Skipf("SKIP: %v", skip.msg)
+		}
+	}
+	if err != nil {
+		t.Errorf("FAIL: %v", err)
+	}
+}
+
+// Skip returns a sentinel error that causes Run to mark the test as skipped.
+func Skip() script.Cmd {
+	return script.Command(
+		script.CmdUsage{
+			Summary: "skip the current test",
+			Args:    "[msg]",
+		},
+		func(_ *script.State, args ...string) (script.WaitFunc, error) {
+			if len(args) > 1 {
+				return nil, script.ErrUsage
+			}
+			if len(args) == 0 {
+				return nil, skipError{""}
+			}
+			return nil, skipError{args[0]}
+		})
+}
+
+type skipError struct {
+	msg string
+}
+
+func (s skipError) Error() string {
+	if s.msg == "" {
+		return "skip"
+	}
+	return s.msg
+}
+
+// CachedExec returns a Condition that reports whether the PATH of the test
+// binary itself (not the script's current environment) contains the named
+// executable.
+func CachedExec() script.Cond {
+	return script.CachedCondition(
+		"<suffix> names an executable in the test binary's PATH",
+		func(name string) (bool, error) {
+			_, err := exec.LookPath(name)
+			return err == nil, nil
+		})
+}
diff --git a/src/cmd/go/internal/script/state.go b/src/cmd/go/internal/script/state.go
new file mode 100644
index 0000000..f40c442
--- /dev/null
+++ b/src/cmd/go/internal/script/state.go
@@ -0,0 +1,232 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package script
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"internal/txtar"
+	"io"
+	"io/fs"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"regexp"
+	"strings"
+)
+
+// A State encapsulates the current state of a running script engine,
+// including the script environment and any running background commands.
+type State struct {
+	engine *Engine // the engine currently executing the script, if any
+
+	ctx    context.Context
+	cancel context.CancelFunc
+	file   string
+	log    bytes.Buffer
+
+	workdir string            // initial working directory
+	pwd     string            // current working directory during execution
+	env     []string          // environment list (for os/exec)
+	envMap  map[string]string // environment mapping (matches env)
+	stdout  string            // standard output from last 'go' command; for 'stdout' command
+	stderr  string            // standard error from last 'go' command; for 'stderr' command
+
+	background []backgroundCmd
+}
+
+type backgroundCmd struct {
+	*command
+	wait WaitFunc
+}
+
+// NewState returns a new State permanently associated with ctx, with its
+// initial working directory in workdir and its initial environment set to
+// initialEnv (or os.Environ(), if initialEnv is nil).
+//
+// The new State also contains pseudo-environment-variables for
+// ${/} and ${:} (for the platform's path and list separators respectively),
+// but does not pass those to subprocesses.
+func NewState(ctx context.Context, workdir string, initialEnv []string) (*State, error) {
+	absWork, err := filepath.Abs(workdir)
+	if err != nil {
+		return nil, err
+	}
+
+	ctx, cancel := context.WithCancel(ctx)
+
+	// Make a fresh copy of the env slice to avoid aliasing bugs if we ever
+	// start modifying it in place; this also establishes the invariant that
+	// s.env contains no duplicates.
+	env := cleanEnv(initialEnv, absWork)
+
+	envMap := make(map[string]string, len(env))
+
+	// Add entries for ${:} and ${/} to make it easier to write platform-independent
+	// paths in scripts.
+	envMap["/"] = string(os.PathSeparator)
+	envMap[":"] = string(os.PathListSeparator)
+
+	for _, kv := range env {
+		if k, v, ok := strings.Cut(kv, "="); ok {
+			envMap[k] = v
+		}
+	}
+
+	s := &State{
+		ctx:     ctx,
+		cancel:  cancel,
+		workdir: absWork,
+		pwd:     absWork,
+		env:     env,
+		envMap:  envMap,
+	}
+	s.Setenv("PWD", absWork)
+	return s, nil
+}
+
+// CloseAndWait cancels the State's Context and waits for any background commands to
+// finish. If any remaining background command ended in an unexpected state,
+// Close returns a non-nil error.
+func (s *State) CloseAndWait(log io.Writer) error {
+	s.cancel()
+	wait, err := Wait().Run(s)
+	if wait != nil {
+		panic("script: internal error: Wait unexpectedly returns its own WaitFunc")
+	}
+	if flushErr := s.flushLog(log); err == nil {
+		err = flushErr
+	}
+	return err
+}
+
+// Chdir changes the State's working directory to the given path.
+func (s *State) Chdir(path string) error {
+	dir := s.Path(path)
+	if _, err := os.Stat(dir); err != nil {
+		return &fs.PathError{Op: "Chdir", Path: dir, Err: err}
+	}
+	s.pwd = dir
+	s.Setenv("PWD", dir)
+	return nil
+}
+
+// Context returns the Context with which the State was created.
+func (s *State) Context() context.Context {
+	return s.ctx
+}
+
+// Environ returns a copy of the current script environment,
+// in the form "key=value".
+func (s *State) Environ() []string {
+	return append([]string(nil), s.env...)
+}
+
+// ExpandEnv replaces ${var} or $var in the string according to the values of
+// the environment variables in s. References to undefined variables are
+// replaced by the empty string.
+func (s *State) ExpandEnv(str string, inRegexp bool) string {
+	return os.Expand(str, func(key string) string {
+		e := s.envMap[key]
+		if inRegexp {
+			// Quote to literal strings: we want paths like C:\work\go1.4 to remain
+			// paths rather than regular expressions.
+			e = regexp.QuoteMeta(e)
+		}
+		return e
+	})
+}
+
+// ExtractFiles extracts the files in ar to the state's current directory,
+// expanding any environment variables within each name.
+//
+// The files must reside within the working directory with which the State was
+// originally created.
+func (s *State) ExtractFiles(ar *txtar.Archive) error {
+	wd := s.workdir
+	// Add trailing separator to terminate wd.
+	// This prevents extracting to outside paths which prefix wd,
+	// e.g. extracting to /home/foobar when wd is /home/foo
+	if !strings.HasSuffix(wd, string(filepath.Separator)) {
+		wd += string(filepath.Separator)
+	}
+
+	for _, f := range ar.Files {
+		name := s.Path(s.ExpandEnv(f.Name, false))
+
+		if !strings.HasPrefix(name, wd) {
+			return fmt.Errorf("file %#q is outside working directory", f.Name)
+		}
+
+		if err := os.MkdirAll(filepath.Dir(name), 0777); err != nil {
+			return err
+		}
+		if err := os.WriteFile(name, f.Data, 0666); err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+// Getwd returns the directory in which to run the next script command.
+func (s *State) Getwd() string { return s.pwd }
+
+// Logf writes output to the script's log without updating its stdout or stderr
+// buffers. (The output log functions as a kind of meta-stderr.)
+func (s *State) Logf(format string, args ...any) {
+	fmt.Fprintf(&s.log, format, args...)
+}
+
+// flushLog writes the contents of the script's log to w and clears the log.
+func (s *State) flushLog(w io.Writer) error {
+	_, err := w.Write(s.log.Bytes())
+	s.log.Reset()
+	return err
+}
+
+// LookupEnv retrieves the value of the environment variable in s named by the key.
+func (s *State) LookupEnv(key string) (string, bool) {
+	v, ok := s.envMap[key]
+	return v, ok
+}
+
+// Path returns the absolute path in the host operaating system for a
+// script-based (generally slash-separated and relative) path.
+func (s *State) Path(path string) string {
+	if filepath.IsAbs(path) {
+		return filepath.Clean(path)
+	}
+	return filepath.Join(s.pwd, path)
+}
+
+// Setenv sets the value of the environment variable in s named by the key.
+func (s *State) Setenv(key, value string) error {
+	s.env = cleanEnv(append(s.env, key+"="+value), s.pwd)
+	s.envMap[key] = value
+	return nil
+}
+
+// Stdout returns the stdout output of the last command run,
+// or the empty string if no command has been run.
+func (s *State) Stdout() string { return s.stdout }
+
+// Stderr returns the stderr output of the last command run,
+// or the empty string if no command has been run.
+func (s *State) Stderr() string { return s.stderr }
+
+// cleanEnv returns a copy of env with any duplicates removed in favor of
+// later values and any required system variables defined.
+//
+// If env is nil, cleanEnv copies the environment from os.Environ().
+func cleanEnv(env []string, pwd string) []string {
+	// There are some funky edge-cases in this logic, especially on Windows (with
+	// case-insensitive environment variables and variables with keys like "=C:").
+	// Rather than duplicating exec.dedupEnv here, cheat and use exec.Cmd directly.
+	cmd := &exec.Cmd{Env: env}
+	cmd.Dir = pwd
+	return cmd.Environ()
+}
diff --git a/src/cmd/go/internal/search/search.go b/src/cmd/go/internal/search/search.go
index ebd4990..c107a02 100644
--- a/src/cmd/go/internal/search/search.go
+++ b/src/cmd/go/internal/search/search.go
@@ -8,13 +8,13 @@
 	"cmd/go/internal/base"
 	"cmd/go/internal/cfg"
 	"cmd/go/internal/fsys"
+	"cmd/internal/pkgpattern"
 	"fmt"
 	"go/build"
 	"io/fs"
 	"os"
 	"path"
 	"path/filepath"
-	"regexp"
 	"strings"
 )
 
@@ -109,8 +109,8 @@
 	match := func(string) bool { return true }
 	treeCanMatch := func(string) bool { return true }
 	if !m.IsMeta() {
-		match = MatchPattern(m.pattern)
-		treeCanMatch = TreeCanMatchPattern(m.pattern)
+		match = pkgpattern.MatchPattern(m.pattern)
+		treeCanMatch = pkgpattern.TreeCanMatchPattern(m.pattern)
 	}
 
 	have := map[string]bool{
@@ -233,7 +233,7 @@
 		cleanPattern = "." + string(os.PathSeparator) + cleanPattern
 	}
 	slashPattern := filepath.ToSlash(cleanPattern)
-	match := MatchPattern(slashPattern)
+	match := pkgpattern.MatchPattern(slashPattern)
 
 	// Find directory to begin the scan.
 	// Could be smarter but this one optimization
@@ -332,90 +332,6 @@
 	}
 }
 
-// TreeCanMatchPattern(pattern)(name) reports whether
-// name or children of name can possibly match pattern.
-// Pattern is the same limited glob accepted by matchPattern.
-func TreeCanMatchPattern(pattern string) func(name string) bool {
-	wildCard := false
-	if i := strings.Index(pattern, "..."); i >= 0 {
-		wildCard = true
-		pattern = pattern[:i]
-	}
-	return func(name string) bool {
-		return len(name) <= len(pattern) && hasPathPrefix(pattern, name) ||
-			wildCard && strings.HasPrefix(name, pattern)
-	}
-}
-
-// MatchPattern(pattern)(name) reports whether
-// name matches pattern. Pattern is a limited glob
-// pattern in which '...' means 'any string' and there
-// is no other special syntax.
-// Unfortunately, there are two special cases. Quoting "go help packages":
-//
-// First, /... at the end of the pattern can match an empty string,
-// so that net/... matches both net and packages in its subdirectories, like net/http.
-// Second, any slash-separated pattern element containing a wildcard never
-// participates in a match of the "vendor" element in the path of a vendored
-// package, so that ./... does not match packages in subdirectories of
-// ./vendor or ./mycode/vendor, but ./vendor/... and ./mycode/vendor/... do.
-// Note, however, that a directory named vendor that itself contains code
-// is not a vendored package: cmd/vendor would be a command named vendor,
-// and the pattern cmd/... matches it.
-func MatchPattern(pattern string) func(name string) bool {
-	// Convert pattern to regular expression.
-	// The strategy for the trailing /... is to nest it in an explicit ? expression.
-	// The strategy for the vendor exclusion is to change the unmatchable
-	// vendor strings to a disallowed code point (vendorChar) and to use
-	// "(anything but that codepoint)*" as the implementation of the ... wildcard.
-	// This is a bit complicated but the obvious alternative,
-	// namely a hand-written search like in most shell glob matchers,
-	// is too easy to make accidentally exponential.
-	// Using package regexp guarantees linear-time matching.
-
-	const vendorChar = "\x00"
-
-	if strings.Contains(pattern, vendorChar) {
-		return func(name string) bool { return false }
-	}
-
-	re := regexp.QuoteMeta(pattern)
-	re = replaceVendor(re, vendorChar)
-	switch {
-	case strings.HasSuffix(re, `/`+vendorChar+`/\.\.\.`):
-		re = strings.TrimSuffix(re, `/`+vendorChar+`/\.\.\.`) + `(/vendor|/` + vendorChar + `/\.\.\.)`
-	case re == vendorChar+`/\.\.\.`:
-		re = `(/vendor|/` + vendorChar + `/\.\.\.)`
-	case strings.HasSuffix(re, `/\.\.\.`):
-		re = strings.TrimSuffix(re, `/\.\.\.`) + `(/\.\.\.)?`
-	}
-	re = strings.ReplaceAll(re, `\.\.\.`, `[^`+vendorChar+`]*`)
-
-	reg := regexp.MustCompile(`^` + re + `$`)
-
-	return func(name string) bool {
-		if strings.Contains(name, vendorChar) {
-			return false
-		}
-		return reg.MatchString(replaceVendor(name, vendorChar))
-	}
-}
-
-// replaceVendor returns the result of replacing
-// non-trailing vendor path elements in x with repl.
-func replaceVendor(x, repl string) string {
-	if !strings.Contains(x, "vendor") {
-		return x
-	}
-	elem := strings.Split(x, "/")
-	for i := 0; i < len(elem)-1; i++ {
-		if elem[i] == "vendor" {
-			elem[i] = repl
-		}
-	}
-	return strings.Join(elem, "/")
-}
-
 // WarnUnmatched warns about patterns that didn't match any packages.
 func WarnUnmatched(matches []*Match) {
 	for _, m := range matches {
@@ -512,22 +428,6 @@
 	return out
 }
 
-// hasPathPrefix reports whether the path s begins with the
-// elements in prefix.
-func hasPathPrefix(s, prefix string) bool {
-	switch {
-	default:
-		return false
-	case len(s) == len(prefix):
-		return s == prefix
-	case len(s) > len(prefix):
-		if prefix != "" && prefix[len(prefix)-1] == '/' {
-			return strings.HasPrefix(s, prefix)
-		}
-		return s[len(prefix)] == '/' && s[:len(prefix)] == prefix
-	}
-}
-
 // hasFilepathPrefix reports whether the path s begins with the
 // elements in prefix.
 func hasFilepathPrefix(s, prefix string) bool {
diff --git a/src/cmd/go/internal/search/search_test.go b/src/cmd/go/internal/search/search_test.go
deleted file mode 100644
index 5f27daf..0000000
--- a/src/cmd/go/internal/search/search_test.go
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package search
-
-import (
-	"strings"
-	"testing"
-)
-
-var matchPatternTests = `
-	pattern ...
-	match foo
-	
-	pattern net
-	match net
-	not net/http
-	
-	pattern net/http
-	match net/http
-	not net
-	
-	pattern net...
-	match net net/http netchan
-	not not/http not/net/http
-	
-	# Special cases. Quoting docs:
-
-	# First, /... at the end of the pattern can match an empty string,
-	# so that net/... matches both net and packages in its subdirectories, like net/http.
-	pattern net/...
-	match net net/http
-	not not/http not/net/http netchan
-
-	# Second, any slash-separated pattern element containing a wildcard never
-	# participates in a match of the "vendor" element in the path of a vendored
-	# package, so that ./... does not match packages in subdirectories of
-	# ./vendor or ./mycode/vendor, but ./vendor/... and ./mycode/vendor/... do.
-	# Note, however, that a directory named vendor that itself contains code
-	# is not a vendored package: cmd/vendor would be a command named vendor,
-	# and the pattern cmd/... matches it.
-	pattern ./...
-	match ./vendor ./mycode/vendor
-	not ./vendor/foo ./mycode/vendor/foo
-	
-	pattern ./vendor/...
-	match ./vendor/foo ./vendor/foo/vendor
-	not ./vendor/foo/vendor/bar
-	
-	pattern mycode/vendor/...
-	match mycode/vendor mycode/vendor/foo mycode/vendor/foo/vendor
-	not mycode/vendor/foo/vendor/bar
-	
-	pattern x/vendor/y
-	match x/vendor/y
-	not x/vendor
-	
-	pattern x/vendor/y/...
-	match x/vendor/y x/vendor/y/z x/vendor/y/vendor x/vendor/y/z/vendor
-	not x/vendor/y/vendor/z
-	
-	pattern .../vendor/...
-	match x/vendor/y x/vendor/y/z x/vendor/y/vendor x/vendor/y/z/vendor
-`
-
-func TestMatchPattern(t *testing.T) {
-	testPatterns(t, "MatchPattern", matchPatternTests, func(pattern, name string) bool {
-		return MatchPattern(pattern)(name)
-	})
-}
-
-var treeCanMatchPatternTests = `
-	pattern ...
-	match foo
-	
-	pattern net
-	match net
-	not net/http
-	
-	pattern net/http
-	match net net/http
-	
-	pattern net...
-	match net netchan net/http
-	not not/http not/net/http
-
-	pattern net/...
-	match net net/http
-	not not/http netchan
-	
-	pattern abc.../def
-	match abcxyz
-	not xyzabc
-	
-	pattern x/y/z/...
-	match x x/y x/y/z x/y/z/w
-	
-	pattern x/y/z
-	match x x/y x/y/z
-	not x/y/z/w
-	
-	pattern x/.../y/z
-	match x/a/b/c
-	not y/x/a/b/c
-`
-
-func TestTreeCanMatchPattern(t *testing.T) {
-	testPatterns(t, "TreeCanMatchPattern", treeCanMatchPatternTests, func(pattern, name string) bool {
-		return TreeCanMatchPattern(pattern)(name)
-	})
-}
-
-var hasPathPrefixTests = []stringPairTest{
-	{"abc", "a", false},
-	{"a/bc", "a", true},
-	{"a", "a", true},
-	{"a/bc", "a/", true},
-}
-
-func TestHasPathPrefix(t *testing.T) {
-	testStringPairs(t, "hasPathPrefix", hasPathPrefixTests, hasPathPrefix)
-}
-
-type stringPairTest struct {
-	in1 string
-	in2 string
-	out bool
-}
-
-func testStringPairs(t *testing.T, name string, tests []stringPairTest, f func(string, string) bool) {
-	for _, tt := range tests {
-		if out := f(tt.in1, tt.in2); out != tt.out {
-			t.Errorf("%s(%q, %q) = %v, want %v", name, tt.in1, tt.in2, out, tt.out)
-		}
-	}
-}
-
-func testPatterns(t *testing.T, name, tests string, fn func(string, string) bool) {
-	var patterns []string
-	for _, line := range strings.Split(tests, "\n") {
-		if i := strings.Index(line, "#"); i >= 0 {
-			line = line[:i]
-		}
-		f := strings.Fields(line)
-		if len(f) == 0 {
-			continue
-		}
-		switch f[0] {
-		default:
-			t.Fatalf("unknown directive %q", f[0])
-		case "pattern":
-			patterns = f[1:]
-		case "match", "not":
-			want := f[0] == "match"
-			for _, pattern := range patterns {
-				for _, in := range f[1:] {
-					if fn(pattern, in) != want {
-						t.Errorf("%s(%q, %q) = %v, want %v", name, pattern, in, !want, want)
-					}
-				}
-			}
-		}
-	}
-}
diff --git a/src/cmd/go/internal/str/str.go b/src/cmd/go/internal/str/str.go
index 975869d..af7c699 100644
--- a/src/cmd/go/internal/str/str.go
+++ b/src/cmd/go/internal/str/str.go
@@ -6,8 +6,8 @@
 package str
 
 import (
-	"bytes"
 	"fmt"
+	"strings"
 	"unicode"
 	"unicode/utf8"
 )
@@ -49,7 +49,7 @@
 	return s
 
 Slow:
-	var buf bytes.Buffer
+	var b strings.Builder
 	for _, r := range s {
 		// SimpleFold(x) cycles to the next equivalent rune > x
 		// or wraps around to smaller values. Iterate until it wraps,
@@ -65,9 +65,9 @@
 		if 'A' <= r && r <= 'Z' {
 			r += 'a' - 'A'
 		}
-		buf.WriteRune(r)
+		b.WriteRune(r)
 	}
-	return buf.String()
+	return b.String()
 }
 
 // FoldDup reports a pair of strings from the list that are
diff --git a/src/cmd/go/internal/test/cover.go b/src/cmd/go/internal/test/cover.go
index 657d22a..f614458 100644
--- a/src/cmd/go/internal/test/cover.go
+++ b/src/cmd/go/internal/test/cover.go
@@ -6,6 +6,7 @@
 
 import (
 	"cmd/go/internal/base"
+	"cmd/go/internal/cfg"
 	"fmt"
 	"io"
 	"os"
@@ -35,7 +36,7 @@
 	if err != nil {
 		base.Fatalf("%v", err)
 	}
-	_, err = fmt.Fprintf(f, "mode: %s\n", testCoverMode)
+	_, err = fmt.Fprintf(f, "mode: %s\n", cfg.BuildCoverMode)
 	if err != nil {
 		base.Fatalf("%v", err)
 	}
@@ -51,7 +52,7 @@
 	coverMerge.Lock()
 	defer coverMerge.Unlock()
 
-	expect := fmt.Sprintf("mode: %s\n", testCoverMode)
+	expect := fmt.Sprintf("mode: %s\n", cfg.BuildCoverMode)
 	buf := make([]byte, len(expect))
 	r, err := os.Open(file)
 	if err != nil {
@@ -65,7 +66,7 @@
 		return
 	}
 	if err != nil || string(buf) != expect {
-		fmt.Fprintf(ew, "error: test wrote malformed coverage profile.\n")
+		fmt.Fprintf(ew, "error: test wrote malformed coverage profile %s.\n", file)
 		return
 	}
 	_, err = io.Copy(coverMerge.f, r)
diff --git a/src/cmd/go/internal/test/flagdefs.go b/src/cmd/go/internal/test/flagdefs.go
index 1b79314..3f3709f 100644
--- a/src/cmd/go/internal/test/flagdefs.go
+++ b/src/cmd/go/internal/test/flagdefs.go
@@ -32,6 +32,7 @@
 	"run":                  true,
 	"short":                true,
 	"shuffle":              true,
+	"skip":                 true,
 	"timeout":              true,
 	"trace":                true,
 	"v":                    true,
@@ -65,6 +66,7 @@
 	"structtag":        true,
 	"testinggoroutine": true,
 	"tests":            true,
+	"timeformat":       true,
 	"unmarshal":        true,
 	"unreachable":      true,
 	"unsafeptr":        true,
diff --git a/src/cmd/go/internal/test/flagdefs_test.go b/src/cmd/go/internal/test/flagdefs_test.go
index f74f3c1..d5facb7 100644
--- a/src/cmd/go/internal/test/flagdefs_test.go
+++ b/src/cmd/go/internal/test/flagdefs_test.go
@@ -9,13 +9,15 @@
 	"cmd/go/internal/test/internal/genflags"
 	"flag"
 	"internal/testenv"
+	"os"
 	"reflect"
 	"strings"
 	"testing"
 )
 
 func TestMain(m *testing.M) {
-	cfg.SetGOROOT(testenv.GOROOT(nil))
+	cfg.SetGOROOT(testenv.GOROOT(nil), false)
+	os.Exit(m.Run())
 }
 
 func TestPassFlagToTestIncludesAllTestFlags(t *testing.T) {
@@ -25,7 +27,8 @@
 		}
 		name := strings.TrimPrefix(f.Name, "test.")
 		switch name {
-		case "testlogfile", "paniconexit0", "fuzzcachedir", "fuzzworker":
+		case "testlogfile", "paniconexit0", "fuzzcachedir", "fuzzworker",
+			"gocoverdir":
 			// These are internal flags.
 		default:
 			if !passFlagToTest[name] {
@@ -47,6 +50,8 @@
 }
 
 func TestVetAnalyzersSetIsCorrect(t *testing.T) {
+	testenv.MustHaveGoBuild(t) // runs 'go tool vet -flags'
+
 	vetAns, err := genflags.VetAnalyzers()
 	if err != nil {
 		t.Fatal(err)
diff --git a/src/cmd/go/internal/test/genflags.go b/src/cmd/go/internal/test/genflags.go
index f50ae5c..625f941 100644
--- a/src/cmd/go/internal/test/genflags.go
+++ b/src/cmd/go/internal/test/genflags.go
@@ -68,13 +68,14 @@
 
 	var names []string
 	flag.VisitAll(func(f *flag.Flag) {
-		if !strings.HasPrefix(f.Name, "test.") {
+		var name string
+		var found bool
+		if name, found = strings.CutPrefix(f.Name, "test."); !found {
 			return
 		}
-		name := strings.TrimPrefix(f.Name, "test.")
 
 		switch name {
-		case "testlogfile", "paniconexit0", "fuzzcachedir", "fuzzworker":
+		case "testlogfile", "paniconexit0", "fuzzcachedir", "fuzzworker", "gocoverdir":
 			// These flags are only for use by cmd/go.
 		default:
 			names = append(names, name)
diff --git a/src/cmd/go/internal/test/test.go b/src/cmd/go/internal/test/test.go
index aa5e41e..fe6e733 100644
--- a/src/cmd/go/internal/test/test.go
+++ b/src/cmd/go/internal/test/test.go
@@ -7,18 +7,15 @@
 import (
 	"bytes"
 	"context"
-	"crypto/sha256"
 	"errors"
 	"fmt"
-	"go/build"
+	"internal/platform"
 	"io"
 	"io/fs"
 	"os"
 	"os/exec"
-	"path"
 	"path/filepath"
 	"regexp"
-	"sort"
 	"strconv"
 	"strings"
 	"sync"
@@ -34,7 +31,6 @@
 	"cmd/go/internal/str"
 	"cmd/go/internal/trace"
 	"cmd/go/internal/work"
-	"cmd/internal/sys"
 	"cmd/internal/test2json"
 
 	"golang.org/x/mod/module"
@@ -152,11 +148,6 @@
 	    Run the test binary using xprog. The behavior is the same as
 	    in 'go run'. See 'go help run' for details.
 
-	-i
-	    Install packages that are dependencies of the test.
-	    Do not run the test.
-	    The -i flag is deprecated. Compiled packages are cached automatically.
-
 	-json
 	    Convert test output to JSON suitable for automated processing.
 	    See 'go doc test2json' for the encoding details.
@@ -306,6 +297,7 @@
 	    run too, so that -run=X/Y matches and runs and reports the result
 	    of all tests matching X, even those without sub-tests matching Y,
 	    because it must run them to look for those sub-tests.
+	    See also -skip.
 
 	-short
 	    Tell long-running tests to shorten their run time.
@@ -320,6 +312,14 @@
 	    integer N, then N will be used as the seed value. In both cases,
 	    the seed will be reported for reproducibility.
 
+	-skip regexp
+	    Run only those tests, examples, fuzz tests, and benchmarks that
+	    do not match the regular expression. Like for -run and -bench,
+	    for tests and benchmarks, the regular expression is split by unbracketed
+	    slash (/) characters into a sequence of regular expressions, and each
+	    part of a test's identifier must match the corresponding element in
+	    the sequence, if any.
+
 	-timeout d
 	    If a test binary runs longer than duration d, panic.
 	    If d is 0, the timeout is disabled.
@@ -527,9 +527,6 @@
 var (
 	testBench        string                            // -bench flag
 	testC            bool                              // -c flag
-	testCover        bool                              // -cover flag
-	testCoverMode    string                            // -covermode flag
-	testCoverPaths   []string                          // -coverpkg flag
 	testCoverPkgs    []*load.Package                   // -coverpkg flag
 	testCoverProfile string                            // -coverprofile flag
 	testFuzz         string                            // -fuzz flag
@@ -539,10 +536,41 @@
 	testOutputDir    outputdirFlag                     // -outputdir flag
 	testShuffle      shuffleFlag                       // -shuffle flag
 	testTimeout      time.Duration                     // -timeout flag
-	testV            bool                              // -v flag
+	testV            testVFlag                         // -v flag
 	testVet          = vetFlag{flags: defaultVetFlags} // -vet flag
 )
 
+type testVFlag struct {
+	on   bool // -v is set in some form
+	json bool // -v=test2json is set, to make output better for test2json
+}
+
+func (*testVFlag) IsBoolFlag() bool { return true }
+
+func (f *testVFlag) Set(arg string) error {
+	if v, err := strconv.ParseBool(arg); err == nil {
+		f.on = v
+		f.json = false
+		return nil
+	}
+	if arg == "test2json" {
+		f.on = true
+		f.json = arg == "test2json"
+		return nil
+	}
+	return fmt.Errorf("invalid flag -test.v=%s", arg)
+}
+
+func (f *testVFlag) String() string {
+	if f.json {
+		return "test2json"
+	}
+	if f.on {
+		return "true"
+	}
+	return "false"
+}
+
 var (
 	testArgs []string
 	pkgArgs  []string
@@ -595,7 +623,7 @@
 
 // testShowPass reports whether the output for a passing test should be shown.
 func testShowPass() bool {
-	return testV || (testList != "") || testHelp
+	return testV.on || testList != "" || testHelp
 }
 
 var defaultVetFlags = []string{
@@ -667,7 +695,7 @@
 		base.Fatalf("cannot use -o flag with multiple packages")
 	}
 	if testFuzz != "" {
-		if !sys.FuzzSupported(cfg.Goos, cfg.Goarch) {
+		if !platform.FuzzSupported(cfg.Goos, cfg.Goarch) {
 			base.Fatalf("-fuzz flag is not supported on %s/%s", cfg.Goos, cfg.Goarch)
 		}
 		if len(pkgs) != 1 {
@@ -728,11 +756,6 @@
 		testKillTimeout = testTimeout + 1*time.Minute
 	}
 
-	// For 'go test -i -o x.test', we want to build x.test. Imply -c to make the logic easier.
-	if cfg.BuildI && testO != "" {
-		testC = true
-	}
-
 	// Read testcache expiration time, if present.
 	// (We implement go clean -testcache by writing an expiration date
 	// instead of searching out and deleting test result cache entries.)
@@ -744,134 +767,25 @@
 		}
 	}
 
-	var b work.Builder
-	b.Init()
-
-	if cfg.BuildI {
-		fmt.Fprint(os.Stderr, "go: -i flag is deprecated\n")
-		cfg.BuildV = testV
-
-		deps := make(map[string]bool)
-		for _, dep := range load.TestMainDeps {
-			deps[dep] = true
+	b := work.NewBuilder("")
+	defer func() {
+		if err := b.Close(); err != nil {
+			base.Fatalf("go: %v", err)
 		}
-
-		for _, p := range pkgs {
-			// Dependencies for each test.
-			for _, path := range p.Imports {
-				deps[path] = true
-			}
-			for _, path := range p.Resolve(p.TestImports) {
-				deps[path] = true
-			}
-			for _, path := range p.Resolve(p.XTestImports) {
-				deps[path] = true
-			}
-		}
-
-		// translate C to runtime/cgo
-		if deps["C"] {
-			delete(deps, "C")
-			deps["runtime/cgo"] = true
-		}
-		// Ignore pseudo-packages.
-		delete(deps, "unsafe")
-
-		all := []string{}
-		for path := range deps {
-			if !build.IsLocalImport(path) {
-				all = append(all, path)
-			}
-		}
-		sort.Strings(all)
-
-		a := &work.Action{Mode: "go test -i"}
-		pkgs := load.PackagesAndErrors(ctx, pkgOpts, all)
-		load.CheckPackageErrors(pkgs)
-		for _, p := range pkgs {
-			if cfg.BuildToolchainName == "gccgo" && p.Standard {
-				// gccgo's standard library packages
-				// can not be reinstalled.
-				continue
-			}
-			a.Deps = append(a.Deps, b.CompileAction(work.ModeInstall, work.ModeInstall, p))
-		}
-		b.Do(ctx, a)
-		if !testC || a.Failed {
-			return
-		}
-		b.Init()
-	}
+	}()
 
 	var builds, runs, prints []*work.Action
 
-	if testCoverPaths != nil {
-		match := make([]func(*load.Package) bool, len(testCoverPaths))
-		matched := make([]bool, len(testCoverPaths))
-		for i := range testCoverPaths {
-			match[i] = load.MatchPackage(testCoverPaths[i], base.Cwd())
+	if cfg.BuildCoverPkg != nil {
+		match := make([]func(*load.Package) bool, len(cfg.BuildCoverPkg))
+		for i := range cfg.BuildCoverPkg {
+			match[i] = load.MatchPackage(cfg.BuildCoverPkg[i], base.Cwd())
 		}
 
-		// Select for coverage all dependencies matching the testCoverPaths patterns.
-		for _, p := range load.TestPackageList(ctx, pkgOpts, pkgs) {
-			haveMatch := false
-			for i := range testCoverPaths {
-				if match[i](p) {
-					matched[i] = true
-					haveMatch = true
-				}
-			}
-
-			// A package which only has test files can't be imported
-			// as a dependency, nor can it be instrumented for coverage.
-			if len(p.GoFiles)+len(p.CgoFiles) == 0 {
-				continue
-			}
-
-			// Silently ignore attempts to run coverage on
-			// sync/atomic when using atomic coverage mode.
-			// Atomic coverage mode uses sync/atomic, so
-			// we can't also do coverage on it.
-			if testCoverMode == "atomic" && p.Standard && p.ImportPath == "sync/atomic" {
-				continue
-			}
-
-			// If using the race detector, silently ignore
-			// attempts to run coverage on the runtime
-			// packages. It will cause the race detector
-			// to be invoked before it has been initialized.
-			if cfg.BuildRace && p.Standard && (p.ImportPath == "runtime" || strings.HasPrefix(p.ImportPath, "runtime/internal")) {
-				continue
-			}
-
-			if haveMatch {
-				testCoverPkgs = append(testCoverPkgs, p)
-			}
-		}
-
-		// Warn about -coverpkg arguments that are not actually used.
-		for i := range testCoverPaths {
-			if !matched[i] {
-				fmt.Fprintf(os.Stderr, "warning: no packages being tested depend on matches for pattern %s\n", testCoverPaths[i])
-			}
-		}
-
-		// Mark all the coverage packages for rebuilding with coverage.
-		for _, p := range testCoverPkgs {
-			// There is nothing to cover in package unsafe; it comes from the compiler.
-			if p.ImportPath == "unsafe" {
-				continue
-			}
-			p.Internal.CoverMode = testCoverMode
-			var coverFiles []string
-			coverFiles = append(coverFiles, p.GoFiles...)
-			coverFiles = append(coverFiles, p.CgoFiles...)
-			coverFiles = append(coverFiles, p.TestGoFiles...)
-			p.Internal.CoverVars = declareCoverVars(p, coverFiles...)
-			if testCover && testCoverMode == "atomic" {
-				ensureImport(p, "sync/atomic")
-			}
-		}
+		// Select for coverage all dependencies matching the -coverpkg
+		// patterns.
+		plist := load.TestPackageList(ctx, pkgOpts, pkgs)
+		testCoverPkgs = load.SelectCoverPackages(plist, match, "test")
 	}
 
 	// Inform the compiler that it should instrument the binary at
@@ -911,12 +825,15 @@
 
 	// Prepare build + run + print actions for all packages being tested.
 	for _, p := range pkgs {
-		// sync/atomic import is inserted by the cover tool. See #18486
-		if testCover && testCoverMode == "atomic" {
-			ensureImport(p, "sync/atomic")
+		// sync/atomic import is inserted by the cover tool if we're
+		// using atomic mode (and not compiling sync/atomic package itself).
+		// See #18486 and #57445.
+		if cfg.BuildCover && cfg.BuildCoverMode == "atomic" &&
+			p.ImportPath != "sync/atomic" {
+			load.EnsureImport(p, "sync/atomic")
 		}
 
-		buildTest, runTest, printTest, err := builderTest(&b, ctx, pkgOpts, p, allImports[p])
+		buildTest, runTest, printTest, err := builderTest(b, ctx, pkgOpts, p, allImports[p])
 		if err != nil {
 			str := err.Error()
 			str = strings.TrimPrefix(str, "\n")
@@ -933,8 +850,19 @@
 		prints = append(prints, printTest)
 	}
 
+	// Order runs for coordinating start JSON prints.
+	ch := make(chan struct{})
+	close(ch)
+	for _, a := range runs {
+		if r, ok := a.Actor.(*runTestActor); ok {
+			r.prev = ch
+			ch = make(chan struct{})
+			r.next = ch
+		}
+	}
+
 	// Ultimately the goal is to print the output.
-	root := &work.Action{Mode: "go test", Func: printExitStatus, Deps: prints}
+	root := &work.Action{Mode: "go test", Actor: work.ActorFunc(printExitStatus), Deps: prints}
 
 	// Force the printing of results to happen in order,
 	// one at a time.
@@ -960,22 +888,6 @@
 	b.Do(ctx, root)
 }
 
-// ensures that package p imports the named package
-func ensureImport(p *load.Package, pkg string) {
-	for _, d := range p.Internal.Imports {
-		if d.Name == pkg {
-			return
-		}
-	}
-
-	p1 := load.LoadImportWithFlags(pkg, p.Dir, p, &load.ImportStack{}, nil, 0)
-	if p1.Error != nil {
-		base.Fatalf("load %s: %v", pkg, p1.Error)
-	}
-
-	p.Internal.Imports = append(p.Internal.Imports, p1)
-}
-
 var windowsBadWords = []string{
 	"install",
 	"patch",
@@ -986,9 +898,21 @@
 func builderTest(b *work.Builder, ctx context.Context, pkgOpts load.PackageOpts, p *load.Package, imported bool) (buildAction, runAction, printAction *work.Action, err error) {
 	if len(p.TestGoFiles)+len(p.XTestGoFiles) == 0 {
 		build := b.CompileAction(work.ModeBuild, work.ModeBuild, p)
-		run := &work.Action{Mode: "test run", Package: p, Deps: []*work.Action{build}}
+		run := &work.Action{
+			Mode:       "test run",
+			Actor:      new(runTestActor),
+			Deps:       []*work.Action{build},
+			Package:    p,
+			IgnoreFail: true, // run (prepare output) even if build failed
+		}
 		addTestVet(b, p, run, nil)
-		print := &work.Action{Mode: "test print", Func: builderNoTest, Package: p, Deps: []*work.Action{run}}
+		print := &work.Action{
+			Mode:       "test print",
+			Actor:      work.ActorFunc(builderPrintTest),
+			Deps:       []*work.Action{run},
+			Package:    p,
+			IgnoreFail: true, // print even if test failed
+		}
 		return build, run, print, nil
 	}
 
@@ -997,13 +921,12 @@
 	//	ptest - package + test files
 	//	pxtest - package of external test files
 	var cover *load.TestCover
-	if testCover {
+	if cfg.BuildCover {
 		cover = &load.TestCover{
-			Mode:     testCoverMode,
-			Local:    testCover && testCoverPaths == nil,
-			Pkgs:     testCoverPkgs,
-			Paths:    testCoverPaths,
-			DeclVars: declareCoverVars,
+			Mode:  cfg.BuildCoverMode,
+			Local: cfg.BuildCoverPkg == nil,
+			Pkgs:  testCoverPkgs,
+			Paths: cfg.BuildCoverPkg,
 		}
 	}
 	pmain, ptest, pxtest, err := load.TestPackagesFor(ctx, pkgOpts, p, cover)
@@ -1090,19 +1013,22 @@
 	if testC || testNeedBinary() {
 		// -c or profiling flag: create action to copy binary to ./test.out.
 		target := filepath.Join(base.Cwd(), testBinary+cfg.ExeSuffix)
+		isNull := false
 		if testO != "" {
 			target = testO
-			if !filepath.IsAbs(target) {
+			if base.IsNull(target) {
+				isNull = true
+			} else if !filepath.IsAbs(target) {
 				target = filepath.Join(base.Cwd(), target)
 			}
 		}
-		if target == os.DevNull {
+		if isNull {
 			runAction = buildAction
 		} else {
 			pmain.Target = target
 			installAction = &work.Action{
 				Mode:    "test build",
-				Func:    work.BuildInstallFunc,
+				Actor:   work.ActorFunc(work.BuildInstallFunc),
 				Deps:    []*work.Action{buildAction},
 				Package: pmain,
 				Target:  target,
@@ -1116,20 +1042,20 @@
 		vetRunAction = printAction
 	} else {
 		// run test
-		c := new(runCache)
+		r := new(runTestActor)
 		runAction = &work.Action{
 			Mode:       "test run",
-			Func:       c.builderRunTest,
+			Actor:      r,
 			Deps:       []*work.Action{buildAction},
 			Package:    p,
 			IgnoreFail: true, // run (prepare output) even if build failed
-			TryCache:   c.tryCache,
+			TryCache:   r.c.tryCache,
 			Objdir:     testDir,
 		}
 		vetRunAction = runAction
 		cleanAction = &work.Action{
 			Mode:       "test clean",
-			Func:       builderCleanTest,
+			Actor:      work.ActorFunc(builderCleanTest),
 			Deps:       []*work.Action{runAction},
 			Package:    p,
 			IgnoreFail: true, // clean even if test failed
@@ -1137,7 +1063,7 @@
 		}
 		printAction = &work.Action{
 			Mode:       "test print",
-			Func:       builderPrintTest,
+			Actor:      work.ActorFunc(builderPrintTest),
 			Deps:       []*work.Action{cleanAction},
 			Package:    p,
 			IgnoreFail: true, // print even if test failed
@@ -1179,54 +1105,20 @@
 	}
 }
 
-// isTestFile reports whether the source file is a set of tests and should therefore
-// be excluded from coverage analysis.
-func isTestFile(file string) bool {
-	// We don't cover tests, only the code they test.
-	return strings.HasSuffix(file, "_test.go")
-}
-
-// declareCoverVars attaches the required cover variables names
-// to the files, to be used when annotating the files.
-func declareCoverVars(p *load.Package, files ...string) map[string]*load.CoverVar {
-	coverVars := make(map[string]*load.CoverVar)
-	coverIndex := 0
-	// We create the cover counters as new top-level variables in the package.
-	// We need to avoid collisions with user variables (GoCover_0 is unlikely but still)
-	// and more importantly with dot imports of other covered packages,
-	// so we append 12 hex digits from the SHA-256 of the import path.
-	// The point is only to avoid accidents, not to defeat users determined to
-	// break things.
-	sum := sha256.Sum256([]byte(p.ImportPath))
-	h := fmt.Sprintf("%x", sum[:6])
-	for _, file := range files {
-		if isTestFile(file) {
-			continue
-		}
-		// For a package that is "local" (imported via ./ import or command line, outside GOPATH),
-		// we record the full path to the file name.
-		// Otherwise we record the import path, then a forward slash, then the file name.
-		// This makes profiles within GOPATH file system-independent.
-		// These names appear in the cmd/cover HTML interface.
-		var longFile string
-		if p.Internal.Local {
-			longFile = filepath.Join(p.Dir, file)
-		} else {
-			longFile = path.Join(p.ImportPath, file)
-		}
-		coverVars[file] = &load.CoverVar{
-			File: longFile,
-			Var:  fmt.Sprintf("GoCover_%d_%x", coverIndex, h),
-		}
-		coverIndex++
-	}
-	return coverVars
-}
-
 var noTestsToRun = []byte("\ntesting: warning: no tests to run\n")
 var noFuzzTestsToFuzz = []byte("\ntesting: warning: no fuzz tests to fuzz\n")
 var tooManyFuzzTestsToFuzz = []byte("\ntesting: warning: -fuzz matches more than one fuzz test, won't fuzz\n")
 
+// runTestActor is the actor for running a test.
+type runTestActor struct {
+	c runCache
+
+	// sequencing of json start messages, to preserve test order
+	prev <-chan struct{} // wait to start until prev is closed
+	next chan<- struct{} // close next once the next test can start.
+}
+
+// runCache is the cache for running a single test.
 type runCache struct {
 	disableCache bool // cache should be disabled for this run
 
@@ -1250,14 +1142,19 @@
 	return os.Stdout.Write(b)
 }
 
-// builderRunTest is the action for running a test binary.
-func (c *runCache) builderRunTest(b *work.Builder, ctx context.Context, a *work.Action) error {
+func (r *runTestActor) Act(b *work.Builder, ctx context.Context, a *work.Action) error {
+	// Wait for previous test to get started and print its first json line.
+	<-r.prev
+
 	if a.Failed {
 		// We were unable to build the binary.
 		a.Failed = false
 		a.TestOutput = new(bytes.Buffer)
 		fmt.Fprintf(a.TestOutput, "FAIL\t%s [build failed]\n", a.Package.ImportPath)
 		base.SetExitStatus(1)
+
+		// release next test to start
+		close(r.next)
 		return nil
 	}
 
@@ -1272,6 +1169,14 @@
 		stdout = json
 	}
 
+	// Release next test to start (test2json.NewConverter writes the start event).
+	close(r.next)
+
+	if p := a.Package; len(p.TestGoFiles)+len(p.XTestGoFiles) == 0 {
+		fmt.Fprintf(stdout, "?   \t%s\t[no test files]\n", p.ImportPath)
+		return nil
+	}
+
 	var buf bytes.Buffer
 	if len(pkgArgs) == 0 || testBench != "" || testFuzz != "" {
 		// Stream test output (no buffering) when no package has
@@ -1302,7 +1207,7 @@
 		}
 	}
 
-	if c.buf == nil {
+	if r.c.buf == nil {
 		// We did not find a cached result using the link step action ID,
 		// so we ran the link step. Try again now with the link output
 		// content ID. The attempt using the action ID makes sure that
@@ -1312,20 +1217,20 @@
 		// we have different link inputs but the same final binary,
 		// we still reuse the cached test result.
 		// c.saveOutput will store the result under both IDs.
-		c.tryCacheWithID(b, a, a.Deps[0].BuildContentID())
+		r.c.tryCacheWithID(b, a, a.Deps[0].BuildContentID())
 	}
-	if c.buf != nil {
+	if r.c.buf != nil {
 		if stdout != &buf {
-			stdout.Write(c.buf.Bytes())
-			c.buf.Reset()
+			stdout.Write(r.c.buf.Bytes())
+			r.c.buf.Reset()
 		}
-		a.TestOutput = c.buf
+		a.TestOutput = r.c.buf
 		return nil
 	}
 
 	execCmd := work.FindExecCmd()
 	testlogArg := []string{}
-	if !c.disableCache && len(execCmd) == 0 {
+	if !r.c.disableCache && len(execCmd) == 0 {
 		testlogArg = []string{"-test.testlogfile=" + a.Objdir + "testlog.txt"}
 	}
 	panicArg := "-test.paniconexit0"
@@ -1334,7 +1239,26 @@
 		fuzzCacheDir := filepath.Join(cache.Default().FuzzDir(), a.Package.ImportPath)
 		fuzzArg = []string{"-test.fuzzcachedir=" + fuzzCacheDir}
 	}
-	args := str.StringList(execCmd, a.Deps[0].BuiltTarget(), testlogArg, panicArg, fuzzArg, testArgs)
+	coverdirArg := []string{}
+	addToEnv := ""
+	if cfg.BuildCover {
+		gcd := filepath.Join(a.Objdir, "gocoverdir")
+		if err := b.Mkdir(gcd); err != nil {
+			// If we can't create a temp dir, terminate immediately
+			// with an error as opposed to returning an error to the
+			// caller; failed MkDir most likely indicates that we're
+			// out of disk space or there is some other systemic error
+			// that will make forward progress unlikely.
+			base.Fatalf("failed to create temporary dir: %v", err)
+		}
+		coverdirArg = append(coverdirArg, "-test.gocoverdir="+gcd)
+		// Even though we are passing the -test.gocoverdir option to
+		// the test binary, also set GOCOVERDIR as well. This is
+		// intended to help with tests that run "go build" to build
+		// fresh copies of tools to test as part of the testing.
+		addToEnv = "GOCOVERDIR=" + gcd
+	}
+	args := str.StringList(execCmd, a.Deps[0].BuiltTarget(), testlogArg, panicArg, fuzzArg, coverdirArg, testArgs)
 
 	if testCoverProfile != "" {
 		// Write coverage to temporary profile, for merging later.
@@ -1359,6 +1283,9 @@
 	env = base.AppendPATH(env)
 	env = base.AppendPWD(env, cmd.Dir)
 	cmd.Env = env
+	if addToEnv != "" {
+		cmd.Env = append(cmd.Env, addToEnv)
+	}
 
 	cmd.Stdout = stdout
 	cmd.Stderr = stdout
@@ -1382,6 +1309,7 @@
 		cmd.Env = env
 	}
 
+	base.StartSigHandlers()
 	t0 := time.Now()
 	err = cmd.Start()
 
@@ -1390,7 +1318,6 @@
 	// running.
 	if err == nil {
 		tick := time.NewTimer(testKillTimeout)
-		base.StartSigHandlers()
 		done := make(chan error)
 		go func() {
 			done <- cmd.Wait()
@@ -1444,7 +1371,7 @@
 			cmd.Stdout.Write([]byte("\n"))
 		}
 		fmt.Fprintf(cmd.Stdout, "ok  \t%s\t%s%s%s\n", a.Package.ImportPath, t, coveragePercentage(out), norun)
-		c.saveOutput(a)
+		r.c.saveOutput(a)
 	} else {
 		base.SetExitStatus(1)
 		if len(out) == 0 {
@@ -1465,7 +1392,11 @@
 		// not a pipe.
 		// TODO(golang.org/issue/29062): tests that exit with status 0 without
 		// printing a final result should fail.
-		fmt.Fprintf(cmd.Stdout, "FAIL\t%s\t%s\n", a.Package.ImportPath, t)
+		prefix := ""
+		if testJSON || testV.json {
+			prefix = "\x16"
+		}
+		fmt.Fprintf(cmd.Stdout, "%sFAIL\t%s\t%s\n", prefix, a.Package.ImportPath, t)
 	}
 
 	if cmd.Stdout != &buf {
@@ -1663,15 +1594,13 @@
 			continue
 		}
 		s := string(line)
-		i := strings.Index(s, " ")
-		if i < 0 {
+		op, name, found := strings.Cut(s, " ")
+		if !found {
 			if cache.DebugTest {
 				fmt.Fprintf(os.Stderr, "testcache: %s: input list malformed (%q)\n", a.Package.ImportPath, line)
 			}
 			return cache.ActionID{}, errBadTestInputs
 		}
-		op := s[:i]
-		name := s[i+1:]
 		switch op {
 		default:
 			if cache.DebugTest {
@@ -1833,7 +1762,7 @@
 // coveragePercentage returns the coverage results (if enabled) for the
 // test. It uncovers the data by scanning the output from the test run.
 func coveragePercentage(out []byte) string {
-	if !testCover {
+	if !cfg.BuildCover {
 		return ""
 	}
 	// The string looks like
@@ -1872,18 +1801,6 @@
 	return nil
 }
 
-// builderNoTest is the action for testing a package with no test files.
-func builderNoTest(b *work.Builder, ctx context.Context, a *work.Action) error {
-	var stdout io.Writer = os.Stdout
-	if testJSON {
-		json := test2json.NewConverter(lockedStdout{}, a.Package.ImportPath, test2json.Timestamp)
-		defer json.Close()
-		stdout = json
-	}
-	fmt.Fprintf(stdout, "?   \t%s\t[no test files]\n", a.Package.ImportPath)
-	return nil
-}
-
 // printExitStatus is the action for printing the final exit status.
 // If we are running multiple test targets, print a final "FAIL"
 // in case a failure in an early package has already scrolled
diff --git a/src/cmd/go/internal/test/testflag.go b/src/cmd/go/internal/test/testflag.go
index f3cd0b1..e690689 100644
--- a/src/cmd/go/internal/test/testflag.go
+++ b/src/cmd/go/internal/test/testflag.go
@@ -6,7 +6,6 @@
 
 import (
 	"cmd/go/internal/base"
-	"cmd/go/internal/cfg"
 	"cmd/go/internal/cmdflag"
 	"cmd/go/internal/work"
 	"errors"
@@ -31,13 +30,8 @@
 
 	cf := CmdTest.Flag
 	cf.BoolVar(&testC, "c", false, "")
-	cf.BoolVar(&cfg.BuildI, "i", false, "")
 	cf.StringVar(&testO, "o", "", "")
-
-	cf.BoolVar(&testCover, "cover", false, "")
-	cf.Var(coverFlag{(*coverModeFlag)(&testCoverMode)}, "covermode", "")
-	cf.Var(coverFlag{commaListFlag{&testCoverPaths}}, "coverpkg", "")
-
+	work.AddCoverFlags(CmdTest, &testCoverProfile)
 	cf.Var((*base.StringsFlag)(&work.ExecCmd), "exec", "")
 	cf.BoolVar(&testJSON, "json", false, "")
 	cf.Var(&testVet, "vet", "")
@@ -52,7 +46,6 @@
 	cf.StringVar(&testBlockProfile, "blockprofile", "", "")
 	cf.String("blockprofilerate", "", "")
 	cf.Int("count", 0, "")
-	cf.Var(coverFlag{stringFlag{&testCoverProfile}}, "coverprofile", "")
 	cf.String("cpu", "", "")
 	cf.StringVar(&testCPUProfile, "cpuprofile", "", "")
 	cf.Bool("failfast", false, "")
@@ -66,11 +59,12 @@
 	cf.Int("parallel", 0, "")
 	cf.String("run", "", "")
 	cf.Bool("short", false, "")
+	cf.String("skip", "", "")
 	cf.DurationVar(&testTimeout, "timeout", 10*time.Minute, "")
 	cf.String("fuzztime", "", "")
 	cf.String("fuzzminimizetime", "", "")
 	cf.StringVar(&testTrace, "trace", "", "")
-	cf.BoolVar(&testV, "v", false, "")
+	cf.Var(&testV, "v", "")
 	cf.Var(&testShuffle, "shuffle", "")
 
 	for name := range passFlagToTest {
@@ -78,55 +72,6 @@
 	}
 }
 
-// A coverFlag is a flag.Value that also implies -cover.
-type coverFlag struct{ v flag.Value }
-
-func (f coverFlag) String() string { return f.v.String() }
-
-func (f coverFlag) Set(value string) error {
-	if err := f.v.Set(value); err != nil {
-		return err
-	}
-	testCover = true
-	return nil
-}
-
-type coverModeFlag string
-
-func (f *coverModeFlag) String() string { return string(*f) }
-func (f *coverModeFlag) Set(value string) error {
-	switch value {
-	case "", "set", "count", "atomic":
-		*f = coverModeFlag(value)
-		return nil
-	default:
-		return errors.New(`valid modes are "set", "count", or "atomic"`)
-	}
-}
-
-// A commaListFlag is a flag.Value representing a comma-separated list.
-type commaListFlag struct{ vals *[]string }
-
-func (f commaListFlag) String() string { return strings.Join(*f.vals, ",") }
-
-func (f commaListFlag) Set(value string) error {
-	if value == "" {
-		*f.vals = nil
-	} else {
-		*f.vals = strings.Split(value, ",")
-	}
-	return nil
-}
-
-// A stringFlag is a flag.Value representing a single string.
-type stringFlag struct{ val *string }
-
-func (f stringFlag) String() string { return *f.val }
-func (f stringFlag) Set(value string) error {
-	*f.val = value
-	return nil
-}
-
 // outputdirFlag implements the -outputdir flag.
 // It interprets an empty value as the working directory of the 'go' command.
 type outputdirFlag struct {
@@ -390,20 +335,18 @@
 
 		args = remainingArgs
 	}
-	if firstUnknownFlag != "" && (testC || cfg.BuildI) {
-		buildFlag := "-c"
-		if !testC {
-			buildFlag = "-i"
-		}
-		fmt.Fprintf(os.Stderr, "go: unknown flag %s cannot be used with %s\n", firstUnknownFlag, buildFlag)
+	if firstUnknownFlag != "" && testC {
+		fmt.Fprintf(os.Stderr, "go: unknown flag %s cannot be used with -c\n", firstUnknownFlag)
 		exitWithUsage()
 	}
 
 	var injectedFlags []string
 	if testJSON {
-		// If converting to JSON, we need the full output in order to pipe it to
-		// test2json.
-		injectedFlags = append(injectedFlags, "-test.v=true")
+		// If converting to JSON, we need the full output in order to pipe it to test2json.
+		// The -test.v=test2json flag is like -test.v=true but causes the test to add
+		// extra ^V characters before testing output lines and other framing,
+		// which helps test2json do a better job creating the JSON events.
+		injectedFlags = append(injectedFlags, "-test.v=test2json")
 		delete(addFromGOFLAGS, "v")
 		delete(addFromGOFLAGS, "test.v")
 	}
@@ -457,18 +400,6 @@
 		}
 	}
 
-	// Ensure that -race and -covermode are compatible.
-	if testCoverMode == "" {
-		testCoverMode = "set"
-		if cfg.BuildRace {
-			// Default coverage mode is atomic when -race is set.
-			testCoverMode = "atomic"
-		}
-	}
-	if cfg.BuildRace && testCoverMode != "atomic" {
-		base.Fatalf(`-covermode must be "atomic", not %q, when -race is enabled`, testCoverMode)
-	}
-
 	// Forward any unparsed arguments (following --args) to the test binary.
 	return packageNames, append(injectedFlags, explicitArgs...)
 }
diff --git a/src/cmd/go/internal/tool/tool.go b/src/cmd/go/internal/tool/tool.go
index d61b524..069968b 100644
--- a/src/cmd/go/internal/tool/tool.go
+++ b/src/cmd/go/internal/tool/tool.go
@@ -8,6 +8,7 @@
 import (
 	"context"
 	"fmt"
+	"go/build"
 	"os"
 	"os/exec"
 	"os/signal"
@@ -47,6 +48,7 @@
 }
 
 func init() {
+	base.AddChdirFlag(&CmdTool.Flag)
 	CmdTool.Flag.BoolVar(&toolN, "n", false, "")
 }
 
@@ -115,7 +117,7 @@
 
 // listTools prints a list of the available tools in the tools directory.
 func listTools() {
-	f, err := os.Open(base.ToolDir)
+	f, err := os.Open(build.ToolDir)
 	if err != nil {
 		fmt.Fprintf(os.Stderr, "go: no tool directory: %s\n", err)
 		base.SetExitStatus(2)
@@ -132,11 +134,9 @@
 	sort.Strings(names)
 	for _, name := range names {
 		// Unify presentation by going to lower case.
-		name = strings.ToLower(name)
 		// If it's windows, don't show the .exe suffix.
-		if base.ToolIsWindows && strings.HasSuffix(name, base.ToolWindowsExtension) {
-			name = name[:len(name)-len(base.ToolWindowsExtension)]
-		}
+		name = strings.TrimSuffix(strings.ToLower(name), cfg.ToolExeSuffix())
+
 		// The tool directory used by gccgo will have other binaries
 		// in addition to go tools. Only display go tools here.
 		if cfg.BuildToolchainName == "gccgo" && !isGccgoTool(name) {
diff --git a/src/cmd/go/internal/trace/trace.go b/src/cmd/go/internal/trace/trace.go
index f108a2b..d69dc4f 100644
--- a/src/cmd/go/internal/trace/trace.go
+++ b/src/cmd/go/internal/trace/trace.go
@@ -27,10 +27,10 @@
 	bindEnclosingSlice = "e"
 )
 
-var traceStarted int32
+var traceStarted atomic.Bool
 
 func getTraceContext(ctx context.Context) (traceContext, bool) {
-	if atomic.LoadInt32(&traceStarted) == 0 {
+	if !traceStarted.Load() {
 		return traceContext{}, false
 	}
 	v := ctx.Value(traceKey{})
@@ -179,7 +179,7 @@
 
 // Start starts a trace which writes to the given file.
 func Start(ctx context.Context, file string) (context.Context, func() error, error) {
-	atomic.StoreInt32(&traceStarted, 1)
+	traceStarted.Store(true)
 	if file == "" {
 		return nil, nil, errors.New("no trace file supplied")
 	}
diff --git a/src/cmd/go/internal/vcs/vcs.go b/src/cmd/go/internal/vcs/vcs.go
index 4f16bef..12ea052 100644
--- a/src/cmd/go/internal/vcs/vcs.go
+++ b/src/cmd/go/internal/vcs/vcs.go
@@ -34,8 +34,8 @@
 // like Mercurial, Git, or Subversion.
 type Cmd struct {
 	Name      string
-	Cmd       string   // name of binary to invoke command
-	RootNames []string // filename indicating the root of a checkout directory
+	Cmd       string     // name of binary to invoke command
+	RootNames []rootName // filename and mode indicating the root of a checkout directory
 
 	CreateCmd   []string // commands to download a fresh copy of a repository
 	DownloadCmd []string // commands to download updates into an existing repository
@@ -60,6 +60,22 @@
 	Uncommitted bool      // Required.
 }
 
+var (
+	// VCSTestRepoURL is the URL of the HTTP server that serves the repos for
+	// vcs-test.golang.org.
+	//
+	// In tests, this is set to the URL of an httptest.Server hosting a
+	// cmd/go/internal/vcweb.Server.
+	VCSTestRepoURL string
+
+	// VCSTestHosts is the set of hosts supported by the vcs-test server.
+	VCSTestHosts []string
+
+	// VCSTestIsLocalHost reports whether the given URL refers to a local
+	// (loopback) host, such as "localhost" or "127.0.0.1:8080".
+	VCSTestIsLocalHost func(*urlpkg.URL) bool
+)
+
 var defaultSecureScheme = map[string]bool{
 	"https":   true,
 	"git+ssh": true,
@@ -74,6 +90,12 @@
 		// If repo is not a URL, it's not secure.
 		return false
 	}
+	if VCSTestRepoURL != "" && web.IsLocalHost(u) {
+		// If the vcstest server is in use, it may redirect to other local ports for
+		// other protocols (such as svn). Assume that all loopback addresses are
+		// secure during testing.
+		return true
+	}
 	return v.isSecureScheme(u.Scheme)
 }
 
@@ -128,9 +150,11 @@
 
 // vcsHg describes how to use Mercurial.
 var vcsHg = &Cmd{
-	Name:      "Mercurial",
-	Cmd:       "hg",
-	RootNames: []string{".hg"},
+	Name: "Mercurial",
+	Cmd:  "hg",
+	RootNames: []rootName{
+		{filename: ".hg", isDir: true},
+	},
 
 	CreateCmd:   []string{"clone -U -- {repo} {dir}"},
 	DownloadCmd: []string{"pull"},
@@ -216,9 +240,11 @@
 
 // vcsGit describes how to use Git.
 var vcsGit = &Cmd{
-	Name:      "Git",
-	Cmd:       "git",
-	RootNames: []string{".git"},
+	Name: "Git",
+	Cmd:  "git",
+	RootNames: []rootName{
+		{filename: ".git", isDir: true},
+	},
 
 	CreateCmd:   []string{"clone -- {repo} {dir}", "-go-internal-cd {dir} submodule update --init --recursive"},
 	DownloadCmd: []string{"pull --ff-only", "submodule update --init --recursive"},
@@ -253,7 +279,7 @@
 
 // scpSyntaxRe matches the SCP-like addresses used by Git to access
 // repositories by SSH.
-var scpSyntaxRe = lazyregexp.New(`^([a-zA-Z0-9_]+)@([a-zA-Z0-9._-]+):(.*)$`)
+var scpSyntaxRe = lazyregexp.New(`^(\w+)@([\w.-]+):(.*)$`)
 
 func gitRemoteRepo(vcsGit *Cmd, rootDir string) (remoteRepo string, err error) {
 	cmd := "config remote.origin.url"
@@ -330,9 +356,11 @@
 
 // vcsBzr describes how to use Bazaar.
 var vcsBzr = &Cmd{
-	Name:      "Bazaar",
-	Cmd:       "bzr",
-	RootNames: []string{".bzr"},
+	Name: "Bazaar",
+	Cmd:  "bzr",
+	RootNames: []rootName{
+		{filename: ".bzr", isDir: true},
+	},
 
 	CreateCmd: []string{"branch -- {repo} {dir}"},
 
@@ -451,9 +479,11 @@
 
 // vcsSvn describes how to use Subversion.
 var vcsSvn = &Cmd{
-	Name:      "Subversion",
-	Cmd:       "svn",
-	RootNames: []string{".svn"},
+	Name: "Subversion",
+	Cmd:  "svn",
+	RootNames: []rootName{
+		{filename: ".svn", isDir: true},
+	},
 
 	CreateCmd:   []string{"checkout -- {repo} {dir}"},
 	DownloadCmd: []string{"update"},
@@ -502,9 +532,12 @@
 
 // vcsFossil describes how to use Fossil (fossil-scm.org)
 var vcsFossil = &Cmd{
-	Name:      "Fossil",
-	Cmd:       "fossil",
-	RootNames: []string{".fslckout", "_FOSSIL_"},
+	Name: "Fossil",
+	Cmd:  "fossil",
+	RootNames: []rootName{
+		{filename: ".fslckout", isDir: false},
+		{filename: "_FOSSIL_", isDir: false},
+	},
 
 	CreateCmd:   []string{"-go-internal-mkdir {dir} clone -- {repo} " + filepath.Join("{dir}", fossilRepoName), "-go-internal-cd {dir} open .fossil"},
 	DownloadCmd: []string{"up"},
@@ -561,7 +594,7 @@
 	}
 	rev := checkout[:i]
 
-	commitTime, err := time.ParseInLocation("2006-01-02 15:04:05", checkout[i+1:], time.UTC)
+	commitTime, err := time.ParseInLocation(time.DateTime, checkout[i+1:], time.UTC)
 	if err != nil {
 		return Status{}, fmt.Errorf("%v: %v", errFossilInfo, err)
 	}
@@ -792,7 +825,7 @@
 	origDir := dir
 	for len(dir) > len(srcRoot) {
 		for _, vcs := range vcsList {
-			if _, err := statAny(dir, vcs.RootNames); err == nil {
+			if isVCSRoot(dir, vcs.RootNames) {
 				// Record first VCS we find.
 				// If allowNesting is false (as it is in GOPATH), keep looking for
 				// repositories in parent directories and report an error if one is
@@ -805,10 +838,6 @@
 					}
 					continue
 				}
-				// Allow .git inside .git, which can arise due to submodules.
-				if vcsCmd == vcs && vcs.Cmd == "git" {
-					continue
-				}
 				// Otherwise, we have one VCS inside a different VCS.
 				return "", nil, fmt.Errorf("directory %q uses %s, but parent %q uses %s",
 					repoDir, vcsCmd.Cmd, dir, vcs.Cmd)
@@ -828,23 +857,22 @@
 	return repoDir, vcsCmd, nil
 }
 
-// statAny provides FileInfo for the first filename found in the directory.
-// Otherwise, it returns the last error seen.
-func statAny(dir string, filenames []string) (os.FileInfo, error) {
-	if len(filenames) == 0 {
-		return nil, errors.New("invalid argument: no filenames provided")
-	}
-
-	var err error
-	var fi os.FileInfo
-	for _, name := range filenames {
-		fi, err = os.Stat(filepath.Join(dir, name))
-		if err == nil {
-			return fi, nil
+// isVCSRoot identifies a VCS root by checking whether the directory contains
+// any of the listed root names.
+func isVCSRoot(dir string, rootNames []rootName) bool {
+	for _, root := range rootNames {
+		fi, err := os.Stat(filepath.Join(dir, root.filename))
+		if err == nil && fi.IsDir() == root.isDir {
+			return true
 		}
 	}
 
-	return nil, err
+	return false
+}
+
+type rootName struct {
+	filename string
+	isDir    bool
 }
 
 type vcsNotFoundError struct {
@@ -880,11 +908,11 @@
 		if item == "" {
 			return nil, fmt.Errorf("empty entry in GOVCS")
 		}
-		i := strings.Index(item, ":")
-		if i < 0 {
+		pattern, list, found := strings.Cut(item, ":")
+		if !found {
 			return nil, fmt.Errorf("malformed entry in GOVCS (missing colon): %q", item)
 		}
-		pattern, list := strings.TrimSpace(item[:i]), strings.TrimSpace(item[i+1:])
+		pattern, list = strings.TrimSpace(pattern), strings.TrimSpace(list)
 		if pattern == "" {
 			return nil, fmt.Errorf("empty pattern in GOVCS: %q", item)
 		}
@@ -1004,15 +1032,11 @@
 	otherDir := dir
 	for len(otherDir) > len(srcRoot) {
 		for _, otherVCS := range vcsList {
-			if _, err := statAny(otherDir, otherVCS.RootNames); err == nil {
+			if isVCSRoot(otherDir, otherVCS.RootNames) {
 				// Allow expected vcs in original dir.
 				if otherDir == dir && otherVCS == vcs {
 					continue
 				}
-				// Allow .git inside .git, which can arise due to submodules.
-				if otherVCS == vcs && vcs.Cmd == "git" {
-					continue
-				}
 				// Otherwise, we have one VCS inside a different VCS.
 				return fmt.Errorf("directory %q uses %s, but parent %q uses %s", dir, vcs.Cmd, otherDir, otherVCS.Cmd)
 			}
@@ -1151,21 +1175,25 @@
 		if !srv.schemelessRepo {
 			repoURL = match["repo"]
 		} else {
-			scheme := vcs.Scheme[0] // default to first scheme
 			repo := match["repo"]
-			if vcs.PingCmd != "" {
-				// If we know how to test schemes, scan to find one.
-				for _, s := range vcs.Scheme {
-					if security == web.SecureOnly && !vcs.isSecureScheme(s) {
-						continue
-					}
-					if vcs.Ping(s, repo) == nil {
-						scheme = s
-						break
+			var ok bool
+			repoURL, ok = interceptVCSTest(repo, vcs, security)
+			if !ok {
+				scheme := vcs.Scheme[0] // default to first scheme
+				if vcs.PingCmd != "" {
+					// If we know how to test schemes, scan to find one.
+					for _, s := range vcs.Scheme {
+						if security == web.SecureOnly && !vcs.isSecureScheme(s) {
+							continue
+						}
+						if vcs.Ping(s, repo) == nil {
+							scheme = s
+							break
+						}
 					}
 				}
+				repoURL = scheme + "://" + repo
 			}
-			repoURL = scheme + "://" + repo
 		}
 		rr := &RepoRoot{
 			Repo: repoURL,
@@ -1177,6 +1205,51 @@
 	return nil, errUnknownSite
 }
 
+func interceptVCSTest(repo string, vcs *Cmd, security web.SecurityMode) (repoURL string, ok bool) {
+	if VCSTestRepoURL == "" {
+		return "", false
+	}
+	if vcs == vcsMod {
+		// Since the "mod" protocol is implemented internally,
+		// requests will be intercepted at a lower level (in cmd/go/internal/web).
+		return "", false
+	}
+
+	if scheme, path, ok := strings.Cut(repo, "://"); ok {
+		if security == web.SecureOnly && !vcs.isSecureScheme(scheme) {
+			return "", false // Let the caller reject the original URL.
+		}
+		repo = path // Remove leading URL scheme if present.
+	}
+	for _, host := range VCSTestHosts {
+		if !str.HasPathPrefix(repo, host) {
+			continue
+		}
+
+		httpURL := VCSTestRepoURL + strings.TrimPrefix(repo, host)
+
+		if vcs == vcsSvn {
+			// Ping the vcweb HTTP server to tell it to initialize the SVN repository
+			// and get the SVN server URL.
+			u, err := urlpkg.Parse(httpURL + "?vcwebsvn=1")
+			if err != nil {
+				panic(fmt.Sprintf("invalid vcs-test repo URL: %v", err))
+			}
+			svnURL, err := web.GetBytes(u)
+			svnURL = bytes.TrimSpace(svnURL)
+			if err == nil && len(svnURL) > 0 {
+				return string(svnURL) + strings.TrimPrefix(repo, host), true
+			}
+
+			// vcs-test doesn't have a svn handler for the given path,
+			// so resolve the repo to HTTPS instead.
+		}
+
+		return httpURL, true
+	}
+	return "", false
+}
+
 // urlForImportPath returns a partially-populated URL for the given Go import path.
 //
 // The URL leaves the Scheme field blank so that web.Get will try any scheme
@@ -1275,8 +1348,12 @@
 		return nil, err
 	}
 
+	repoURL, ok := interceptVCSTest(mmi.RepoRoot, vcs, security)
+	if !ok {
+		repoURL = mmi.RepoRoot
+	}
 	rr := &RepoRoot{
-		Repo:     mmi.RepoRoot,
+		Repo:     repoURL,
 		Root:     mmi.Prefix,
 		IsCustom: true,
 		VCS:      vcs,
@@ -1438,7 +1515,7 @@
 	// GitHub
 	{
 		pathPrefix: "github.com",
-		regexp:     lazyregexp.New(`^(?P<root>github\.com/[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+)(/[A-Za-z0-9_.\-]+)*$`),
+		regexp:     lazyregexp.New(`^(?P<root>github\.com/[\w.\-]+/[\w.\-]+)(/[\w.\-]+)*$`),
 		vcs:        "git",
 		repo:       "https://{root}",
 		check:      noVCSSuffix,
@@ -1447,7 +1524,7 @@
 	// Bitbucket
 	{
 		pathPrefix: "bitbucket.org",
-		regexp:     lazyregexp.New(`^(?P<root>bitbucket\.org/(?P<bitname>[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+))(/[A-Za-z0-9_.\-]+)*$`),
+		regexp:     lazyregexp.New(`^(?P<root>bitbucket\.org/(?P<bitname>[\w.\-]+/[\w.\-]+))(/[\w.\-]+)*$`),
 		vcs:        "git",
 		repo:       "https://{root}",
 		check:      noVCSSuffix,
@@ -1456,7 +1533,7 @@
 	// IBM DevOps Services (JazzHub)
 	{
 		pathPrefix: "hub.jazz.net/git",
-		regexp:     lazyregexp.New(`^(?P<root>hub\.jazz\.net/git/[a-z0-9]+/[A-Za-z0-9_.\-]+)(/[A-Za-z0-9_.\-]+)*$`),
+		regexp:     lazyregexp.New(`^(?P<root>hub\.jazz\.net/git/[a-z0-9]+/[\w.\-]+)(/[\w.\-]+)*$`),
 		vcs:        "git",
 		repo:       "https://{root}",
 		check:      noVCSSuffix,
@@ -1465,7 +1542,7 @@
 	// Git at Apache
 	{
 		pathPrefix: "git.apache.org",
-		regexp:     lazyregexp.New(`^(?P<root>git\.apache\.org/[a-z0-9_.\-]+\.git)(/[A-Za-z0-9_.\-]+)*$`),
+		regexp:     lazyregexp.New(`^(?P<root>git\.apache\.org/[a-z0-9_.\-]+\.git)(/[\w.\-]+)*$`),
 		vcs:        "git",
 		repo:       "https://{root}",
 	},
@@ -1473,7 +1550,7 @@
 	// Git at OpenStack
 	{
 		pathPrefix: "git.openstack.org",
-		regexp:     lazyregexp.New(`^(?P<root>git\.openstack\.org/[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+)(\.git)?(/[A-Za-z0-9_.\-]+)*$`),
+		regexp:     lazyregexp.New(`^(?P<root>git\.openstack\.org/[\w.\-]+/[\w.\-]+)(\.git)?(/[\w.\-]+)*$`),
 		vcs:        "git",
 		repo:       "https://{root}",
 	},
@@ -1481,7 +1558,7 @@
 	// chiselapp.com for fossil
 	{
 		pathPrefix: "chiselapp.com",
-		regexp:     lazyregexp.New(`^(?P<root>chiselapp\.com/user/[A-Za-z0-9]+/repository/[A-Za-z0-9_.\-]+)$`),
+		regexp:     lazyregexp.New(`^(?P<root>chiselapp\.com/user/[A-Za-z0-9]+/repository/[\w.\-]+)$`),
 		vcs:        "fossil",
 		repo:       "https://{root}",
 	},
@@ -1489,7 +1566,7 @@
 	// General syntax for any server.
 	// Must be last.
 	{
-		regexp:         lazyregexp.New(`(?P<root>(?P<repo>([a-z0-9.\-]+\.)+[a-z0-9.\-]+(:[0-9]+)?(/~?[A-Za-z0-9_.\-]+)+?)\.(?P<vcs>bzr|fossil|git|hg|svn))(/~?[A-Za-z0-9_.\-]+)*$`),
+		regexp:         lazyregexp.New(`(?P<root>(?P<repo>([a-z0-9.\-]+\.)+[a-z0-9.\-]+(:[0-9]+)?(/~?[\w.\-]+)+?)\.(?P<vcs>bzr|fossil|git|hg|svn))(/~?[\w.\-]+)*$`),
 		schemelessRepo: true,
 	},
 }
@@ -1502,7 +1579,7 @@
 	// Launchpad. See golang.org/issue/11436.
 	{
 		pathPrefix: "launchpad.net",
-		regexp:     lazyregexp.New(`^(?P<root>launchpad\.net/((?P<project>[A-Za-z0-9_.\-]+)(?P<series>/[A-Za-z0-9_.\-]+)?|~[A-Za-z0-9_.\-]+/(\+junk|[A-Za-z0-9_.\-]+)/[A-Za-z0-9_.\-]+))(/[A-Za-z0-9_.\-]+)*$`),
+		regexp:     lazyregexp.New(`^(?P<root>launchpad\.net/((?P<project>[\w.\-]+)(?P<series>/[\w.\-]+)?|~[\w.\-]+/(\+junk|[\w.\-]+)/[\w.\-]+))(/[\w.\-]+)*$`),
 		vcs:        "bzr",
 		repo:       "https://{root}",
 		check:      launchpadVCS,
diff --git a/src/cmd/go/internal/vcs/vcs_test.go b/src/cmd/go/internal/vcs/vcs_test.go
index 943d520..2ce85ea 100644
--- a/src/cmd/go/internal/vcs/vcs_test.go
+++ b/src/cmd/go/internal/vcs/vcs_test.go
@@ -215,17 +215,13 @@
 // Test that vcs.FromDir correctly inspects a given directory and returns the
 // right VCS and repo directory.
 func TestFromDir(t *testing.T) {
-	tempDir, err := os.MkdirTemp("", "vcstest")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tempDir)
+	tempDir := t.TempDir()
 
-	for j, vcs := range vcsList {
-		for r, rootName := range vcs.RootNames {
+	for _, vcs := range vcsList {
+		for r, root := range vcs.RootNames {
 			vcsName := fmt.Sprint(vcs.Name, r)
-			dir := filepath.Join(tempDir, "example.com", vcsName, rootName)
-			if j&1 == 0 {
+			dir := filepath.Join(tempDir, "example.com", vcsName, root.filename)
+			if root.isDir {
 				err := os.MkdirAll(dir, 0755)
 				if err != nil {
 					t.Fatal(err)
diff --git a/src/cmd/go/internal/vcweb/auth.go b/src/cmd/go/internal/vcweb/auth.go
new file mode 100644
index 0000000..094a828
--- /dev/null
+++ b/src/cmd/go/internal/vcweb/auth.go
@@ -0,0 +1,108 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package vcweb
+
+import (
+	"encoding/json"
+	"fmt"
+	"io/ioutil"
+	"log"
+	"net/http"
+	"os"
+	"path"
+	"strings"
+)
+
+// authHandler serves requests only if the Basic Auth data sent with the request
+// matches the contents of a ".access" file in the requested directory.
+//
+// For each request, the handler looks for a file named ".access" and parses it
+// as a JSON-serialized accessToken. If the credentials from the request match
+// the accessToken, the file is served normally; otherwise, it is rejected with
+// the StatusCode and Message provided by the token.
+type authHandler struct{}
+
+type accessToken struct {
+	Username, Password string
+	StatusCode         int // defaults to 401.
+	Message            string
+}
+
+func (h *authHandler) Available() bool { return true }
+
+func (h *authHandler) Handler(dir string, env []string, logger *log.Logger) (http.Handler, error) {
+	fs := http.Dir(dir)
+
+	handler := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
+		urlPath := req.URL.Path
+		if urlPath != "" && strings.HasPrefix(path.Base(urlPath), ".") {
+			http.Error(w, "filename contains leading dot", http.StatusBadRequest)
+			return
+		}
+
+		f, err := fs.Open(urlPath)
+		if err != nil {
+			if os.IsNotExist(err) {
+				http.NotFound(w, req)
+			} else {
+				http.Error(w, err.Error(), http.StatusInternalServerError)
+			}
+			return
+		}
+
+		accessDir := urlPath
+		if fi, err := f.Stat(); err == nil && !fi.IsDir() {
+			accessDir = path.Dir(urlPath)
+		}
+		f.Close()
+
+		var accessFile http.File
+		for {
+			var err error
+			accessFile, err = fs.Open(path.Join(accessDir, ".access"))
+			if err == nil {
+				break
+			}
+
+			if !os.IsNotExist(err) {
+				http.Error(w, err.Error(), http.StatusInternalServerError)
+				return
+			}
+			if accessDir == "." {
+				http.Error(w, "failed to locate access file", http.StatusInternalServerError)
+				return
+			}
+			accessDir = path.Dir(accessDir)
+		}
+
+		data, err := ioutil.ReadAll(accessFile)
+		if err != nil {
+			http.Error(w, err.Error(), http.StatusInternalServerError)
+			return
+		}
+
+		var token accessToken
+		if err := json.Unmarshal(data, &token); err != nil {
+			logger.Print(err)
+			http.Error(w, "malformed access file", http.StatusInternalServerError)
+			return
+		}
+		if username, password, ok := req.BasicAuth(); !ok || username != token.Username || password != token.Password {
+			code := token.StatusCode
+			if code == 0 {
+				code = http.StatusUnauthorized
+			}
+			if code == http.StatusUnauthorized {
+				w.Header().Add("WWW-Authenticate", fmt.Sprintf("basic realm=%s", accessDir))
+			}
+			http.Error(w, token.Message, code)
+			return
+		}
+
+		http.FileServer(fs).ServeHTTP(w, req)
+	})
+
+	return handler, nil
+}
diff --git a/src/cmd/go/internal/vcweb/bzr.go b/src/cmd/go/internal/vcweb/bzr.go
new file mode 100644
index 0000000..a915fb2
--- /dev/null
+++ b/src/cmd/go/internal/vcweb/bzr.go
@@ -0,0 +1,18 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package vcweb
+
+import (
+	"log"
+	"net/http"
+)
+
+type bzrHandler struct{}
+
+func (*bzrHandler) Available() bool { return true }
+
+func (*bzrHandler) Handler(dir string, env []string, logger *log.Logger) (http.Handler, error) {
+	return http.FileServer(http.Dir(dir)), nil
+}
diff --git a/src/cmd/go/internal/vcweb/dir.go b/src/cmd/go/internal/vcweb/dir.go
new file mode 100644
index 0000000..2f122f4
--- /dev/null
+++ b/src/cmd/go/internal/vcweb/dir.go
@@ -0,0 +1,19 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package vcweb
+
+import (
+	"log"
+	"net/http"
+)
+
+// dirHandler is a vcsHandler that serves the raw contents of a directory.
+type dirHandler struct{}
+
+func (*dirHandler) Available() bool { return true }
+
+func (*dirHandler) Handler(dir string, env []string, logger *log.Logger) (http.Handler, error) {
+	return http.FileServer(http.Dir(dir)), nil
+}
diff --git a/src/cmd/go/internal/vcweb/fossil.go b/src/cmd/go/internal/vcweb/fossil.go
new file mode 100644
index 0000000..4b5db22
--- /dev/null
+++ b/src/cmd/go/internal/vcweb/fossil.go
@@ -0,0 +1,62 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package vcweb
+
+import (
+	"fmt"
+	"io/ioutil"
+	"log"
+	"net/http"
+	"net/http/cgi"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"sync"
+)
+
+type fossilHandler struct {
+	once          sync.Once
+	fossilPath    string
+	fossilPathErr error
+}
+
+func (h *fossilHandler) Available() bool {
+	h.once.Do(func() {
+		h.fossilPath, h.fossilPathErr = exec.LookPath("fossil")
+	})
+	return h.fossilPathErr == nil
+}
+
+func (h *fossilHandler) Handler(dir string, env []string, logger *log.Logger) (http.Handler, error) {
+	if !h.Available() {
+		return nil, ServerNotInstalledError{name: "fossil"}
+	}
+
+	name := filepath.Base(dir)
+	db := filepath.Join(dir, name+".fossil")
+
+	cgiPath := db + ".cgi"
+	cgiScript := fmt.Sprintf("#!%s\nrepository: %s\n", h.fossilPath, db)
+	if err := ioutil.WriteFile(cgiPath, []byte(cgiScript), 0755); err != nil {
+		return nil, err
+	}
+
+	handler := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
+		if _, err := os.Stat(db); err != nil {
+			http.Error(w, err.Error(), http.StatusInternalServerError)
+			return
+		}
+		ch := &cgi.Handler{
+			Env:    env,
+			Logger: logger,
+			Path:   h.fossilPath,
+			Args:   []string{cgiPath},
+			Dir:    dir,
+		}
+		ch.ServeHTTP(w, req)
+	})
+
+	return handler, nil
+}
diff --git a/src/cmd/go/internal/vcweb/git.go b/src/cmd/go/internal/vcweb/git.go
new file mode 100644
index 0000000..5f9864e
--- /dev/null
+++ b/src/cmd/go/internal/vcweb/git.go
@@ -0,0 +1,51 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package vcweb
+
+import (
+	"log"
+	"net/http"
+	"net/http/cgi"
+	"os/exec"
+	"runtime"
+	"sync"
+)
+
+type gitHandler struct {
+	once       sync.Once
+	gitPath    string
+	gitPathErr error
+}
+
+func (h *gitHandler) Available() bool {
+	if runtime.GOOS == "plan9" {
+		// The Git command is usually not the real Git on Plan 9.
+		// See https://golang.org/issues/29640.
+		return false
+	}
+	h.once.Do(func() {
+		h.gitPath, h.gitPathErr = exec.LookPath("git")
+	})
+	return h.gitPathErr == nil
+}
+
+func (h *gitHandler) Handler(dir string, env []string, logger *log.Logger) (http.Handler, error) {
+	if !h.Available() {
+		return nil, ServerNotInstalledError{name: "git"}
+	}
+
+	handler := &cgi.Handler{
+		Path:   h.gitPath,
+		Logger: logger,
+		Args:   []string{"http-backend"},
+		Dir:    dir,
+		Env: append(env[:len(env):len(env)],
+			"GIT_PROJECT_ROOT="+dir,
+			"GIT_HTTP_EXPORT_ALL=1",
+		),
+	}
+
+	return handler, nil
+}
diff --git a/src/cmd/go/internal/vcweb/hg.go b/src/cmd/go/internal/vcweb/hg.go
new file mode 100644
index 0000000..e78f850
--- /dev/null
+++ b/src/cmd/go/internal/vcweb/hg.go
@@ -0,0 +1,121 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package vcweb
+
+import (
+	"bufio"
+	"errors"
+	"io"
+	"log"
+	"net/http"
+	"net/http/httputil"
+	"net/url"
+	"os"
+	"os/exec"
+	"strings"
+	"sync"
+)
+
+type hgHandler struct {
+	once      sync.Once
+	hgPath    string
+	hgPathErr error
+}
+
+func (h *hgHandler) Available() bool {
+	h.once.Do(func() {
+		h.hgPath, h.hgPathErr = exec.LookPath("hg")
+	})
+	return h.hgPathErr == nil
+}
+
+func (h *hgHandler) Handler(dir string, env []string, logger *log.Logger) (http.Handler, error) {
+	if !h.Available() {
+		return nil, ServerNotInstalledError{name: "hg"}
+	}
+
+	handler := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
+		// Mercurial has a CGI server implementation (called hgweb). In theory we
+		// could use that — however, assuming that hgweb is even installed, the
+		// configuration for hgweb varies by Python version (2 vs 3), and we would
+		// rather not go rooting around trying to find the right Python version to
+		// run.
+		//
+		// Instead, we'll take a somewhat more roundabout approach: we assume that
+		// if "hg" works at all then "hg serve" works too, and we'll execute that as
+		// a subprocess, using a reverse proxy to forward the request and response.
+
+		cmd := exec.Command(h.hgPath, "serve", "--port", "0", "--address", "localhost", "--accesslog", os.DevNull, "--name", "vcweb", "--print-url")
+		cmd.Dir = dir
+		cmd.Env = append(env[:len(env):len(env)], "PWD="+dir)
+
+		stderr := new(strings.Builder)
+		cmd.Stderr = stderr
+
+		stdout, err := cmd.StdoutPipe()
+		if err != nil {
+			http.Error(w, err.Error(), http.StatusInternalServerError)
+			return
+		}
+		readDone := make(chan struct{})
+		defer func() {
+			stdout.Close()
+			<-readDone
+		}()
+
+		hgURL := make(chan *url.URL, 1)
+		hgURLError := make(chan error, 1)
+		go func() {
+			defer close(readDone)
+			r := bufio.NewReader(stdout)
+			for {
+				line, err := r.ReadString('\n')
+				if err != nil {
+					return
+				}
+				u, err := url.Parse(strings.TrimSpace(line))
+				if err == nil {
+					hgURL <- u
+				} else {
+					hgURLError <- err
+				}
+				break
+			}
+			io.Copy(io.Discard, r)
+		}()
+
+		if err := cmd.Start(); err != nil {
+			http.Error(w, err.Error(), http.StatusInternalServerError)
+			return
+		}
+		defer func() {
+			if err := cmd.Process.Signal(os.Interrupt); err != nil && !errors.Is(err, os.ErrProcessDone) {
+				cmd.Process.Kill()
+			}
+			err := cmd.Wait()
+			if out := strings.TrimSuffix(stderr.String(), "interrupted!\n"); out != "" {
+				logger.Printf("%v: %v\n%s", cmd, err, out)
+			} else {
+				logger.Printf("%v", cmd)
+			}
+		}()
+
+		select {
+		case <-req.Context().Done():
+			logger.Printf("%v: %v", req.Context().Err(), cmd)
+			http.Error(w, req.Context().Err().Error(), http.StatusBadGateway)
+			return
+		case err := <-hgURLError:
+			logger.Printf("%v: %v", cmd, err)
+			http.Error(w, err.Error(), http.StatusBadGateway)
+			return
+		case url := <-hgURL:
+			logger.Printf("proxying hg request to %s", url)
+			httputil.NewSingleHostReverseProxy(url).ServeHTTP(w, req)
+		}
+	})
+
+	return handler, nil
+}
diff --git a/src/cmd/go/internal/vcweb/insecure.go b/src/cmd/go/internal/vcweb/insecure.go
new file mode 100644
index 0000000..1d6af25
--- /dev/null
+++ b/src/cmd/go/internal/vcweb/insecure.go
@@ -0,0 +1,42 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package vcweb
+
+import (
+	"log"
+	"net/http"
+)
+
+// insecureHandler redirects requests to the same host and path but using the
+// "http" scheme instead of "https".
+type insecureHandler struct{}
+
+func (h *insecureHandler) Available() bool { return true }
+
+func (h *insecureHandler) Handler(dir string, env []string, logger *log.Logger) (http.Handler, error) {
+	// The insecure-redirect handler implementation doesn't depend or dir or env.
+	//
+	// The only effect of the directory is to determine which prefix the caller
+	// will strip from the request before passing it on to this handler.
+	return h, nil
+}
+
+func (h *insecureHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
+	if req.Host == "" && req.URL.Host == "" {
+		http.Error(w, "no Host provided in request", http.StatusBadRequest)
+		return
+	}
+
+	// Note that if the handler is wrapped with http.StripPrefix, the prefix
+	// will remain stripped in the redirected URL, preventing redirect loops
+	// if the scheme is already "http".
+
+	u := *req.URL
+	u.Scheme = "http"
+	u.User = nil
+	u.Host = req.Host
+
+	http.Redirect(w, req, u.String(), http.StatusFound)
+}
diff --git a/src/cmd/go/internal/vcweb/script.go b/src/cmd/go/internal/vcweb/script.go
new file mode 100644
index 0000000..c35b46f
--- /dev/null
+++ b/src/cmd/go/internal/vcweb/script.go
@@ -0,0 +1,345 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package vcweb
+
+import (
+	"bufio"
+	"bytes"
+	"cmd/go/internal/script"
+	"context"
+	"errors"
+	"fmt"
+	"internal/txtar"
+	"io"
+	"log"
+	"net/http"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"runtime"
+	"strconv"
+	"strings"
+	"time"
+
+	"golang.org/x/mod/module"
+	"golang.org/x/mod/zip"
+)
+
+// newScriptEngine returns a script engine augmented with commands for
+// reproducing version-control repositories by replaying commits.
+func newScriptEngine() *script.Engine {
+	conds := script.DefaultConds()
+
+	interrupt := func(cmd *exec.Cmd) error { return cmd.Process.Signal(os.Interrupt) }
+	gracePeriod := 30 * time.Second // arbitrary
+
+	cmds := script.DefaultCmds()
+	cmds["at"] = scriptAt()
+	cmds["bzr"] = script.Program("bzr", interrupt, gracePeriod)
+	cmds["fossil"] = script.Program("fossil", interrupt, gracePeriod)
+	cmds["git"] = script.Program("git", interrupt, gracePeriod)
+	cmds["hg"] = script.Program("hg", interrupt, gracePeriod)
+	cmds["handle"] = scriptHandle()
+	cmds["modzip"] = scriptModzip()
+	cmds["svnadmin"] = script.Program("svnadmin", interrupt, gracePeriod)
+	cmds["svn"] = script.Program("svn", interrupt, gracePeriod)
+	cmds["unquote"] = scriptUnquote()
+
+	return &script.Engine{
+		Cmds:  cmds,
+		Conds: conds,
+	}
+}
+
+// loadScript interprets the given script content using the vcweb script engine.
+// loadScript always returns either a non-nil handler or a non-nil error.
+//
+// The script content must be a txtar archive with a comment containing a script
+// with exactly one "handle" command and zero or more VCS commands to prepare
+// the repository to be served.
+func (s *Server) loadScript(ctx context.Context, logger *log.Logger, scriptPath string, scriptContent []byte, workDir string) (http.Handler, error) {
+	ar := txtar.Parse(scriptContent)
+
+	if err := os.MkdirAll(workDir, 0755); err != nil {
+		return nil, err
+	}
+
+	st, err := s.newState(ctx, workDir)
+	if err != nil {
+		return nil, err
+	}
+	if err := st.ExtractFiles(ar); err != nil {
+		return nil, err
+	}
+
+	scriptName := filepath.Base(scriptPath)
+	scriptLog := new(strings.Builder)
+	err = s.engine.Execute(st, scriptName, bufio.NewReader(bytes.NewReader(ar.Comment)), scriptLog)
+	closeErr := st.CloseAndWait(scriptLog)
+	logger.Printf("%s:", scriptName)
+	io.WriteString(logger.Writer(), scriptLog.String())
+	io.WriteString(logger.Writer(), "\n")
+	if err != nil {
+		return nil, err
+	}
+	if closeErr != nil {
+		return nil, err
+	}
+
+	sc, err := getScriptCtx(st)
+	if err != nil {
+		return nil, err
+	}
+	if sc.handler == nil {
+		return nil, errors.New("script completed without setting handler")
+	}
+	return sc.handler, nil
+}
+
+// newState returns a new script.State for executing scripts in workDir.
+func (s *Server) newState(ctx context.Context, workDir string) (*script.State, error) {
+	ctx = &scriptCtx{
+		Context: ctx,
+		server:  s,
+	}
+
+	st, err := script.NewState(ctx, workDir, s.env)
+	if err != nil {
+		return nil, err
+	}
+	return st, nil
+}
+
+// scriptEnviron returns a new environment that attempts to provide predictable
+// behavior for the supported version-control tools.
+func scriptEnviron(homeDir string) []string {
+	env := []string{
+		"USER=gopher",
+		homeEnvName() + "=" + homeDir,
+		"GIT_CONFIG_NOSYSTEM=1",
+		"HGRCPATH=" + filepath.Join(homeDir, ".hgrc"),
+		"HGENCODING=utf-8",
+	}
+	// Preserve additional environment variables that may be needed by VCS tools.
+	for _, k := range []string{
+		pathEnvName(),
+		tempEnvName(),
+		"SYSTEMROOT",        // must be preserved on Windows to find DLLs; golang.org/issue/25210
+		"WINDIR",            // must be preserved on Windows to be able to run PowerShell command; golang.org/issue/30711
+		"ComSpec",           // must be preserved on Windows to be able to run Batch files; golang.org/issue/56555
+		"DYLD_LIBRARY_PATH", // must be preserved on macOS systems to find shared libraries
+		"LD_LIBRARY_PATH",   // must be preserved on Unix systems to find shared libraries
+		"LIBRARY_PATH",      // allow override of non-standard static library paths
+		"PYTHONPATH",        // may be needed by hg to find imported modules
+	} {
+		if v, ok := os.LookupEnv(k); ok {
+			env = append(env, k+"="+v)
+		}
+	}
+
+	if os.Getenv("GO_BUILDER_NAME") != "" || os.Getenv("GIT_TRACE_CURL") == "1" {
+		// To help diagnose https://go.dev/issue/52545,
+		// enable tracing for Git HTTPS requests.
+		env = append(env,
+			"GIT_TRACE_CURL=1",
+			"GIT_TRACE_CURL_NO_DATA=1",
+			"GIT_REDACT_COOKIES=o,SSO,GSSO_Uberproxy")
+	}
+
+	return env
+}
+
+// homeEnvName returns the environment variable used by os.UserHomeDir
+// to locate the user's home directory.
+func homeEnvName() string {
+	switch runtime.GOOS {
+	case "windows":
+		return "USERPROFILE"
+	case "plan9":
+		return "home"
+	default:
+		return "HOME"
+	}
+}
+
+// tempEnvName returns the environment variable used by os.TempDir
+// to locate the default directory for temporary files.
+func tempEnvName() string {
+	switch runtime.GOOS {
+	case "windows":
+		return "TMP"
+	case "plan9":
+		return "TMPDIR" // actually plan 9 doesn't have one at all but this is fine
+	default:
+		return "TMPDIR"
+	}
+}
+
+// pathEnvName returns the environment variable used by exec.LookPath to
+// identify directories to search for executables.
+func pathEnvName() string {
+	switch runtime.GOOS {
+	case "plan9":
+		return "path"
+	default:
+		return "PATH"
+	}
+}
+
+// A scriptCtx is a context.Context that stores additional state for script
+// commands.
+type scriptCtx struct {
+	context.Context
+	server      *Server
+	commitTime  time.Time
+	handlerName string
+	handler     http.Handler
+}
+
+// scriptCtxKey is the key associating the *scriptCtx in a script's Context..
+type scriptCtxKey struct{}
+
+func (sc *scriptCtx) Value(key any) any {
+	if key == (scriptCtxKey{}) {
+		return sc
+	}
+	return sc.Context.Value(key)
+}
+
+func getScriptCtx(st *script.State) (*scriptCtx, error) {
+	sc, ok := st.Context().Value(scriptCtxKey{}).(*scriptCtx)
+	if !ok {
+		return nil, errors.New("scriptCtx not found in State.Context")
+	}
+	return sc, nil
+}
+
+func scriptAt() script.Cmd {
+	return script.Command(
+		script.CmdUsage{
+			Summary: "set the current commit time for all version control systems",
+			Args:    "time",
+			Detail: []string{
+				"The argument must be an absolute timestamp in RFC3339 format.",
+			},
+		},
+		func(st *script.State, args ...string) (script.WaitFunc, error) {
+			if len(args) != 1 {
+				return nil, script.ErrUsage
+			}
+
+			sc, err := getScriptCtx(st)
+			if err != nil {
+				return nil, err
+			}
+
+			sc.commitTime, err = time.ParseInLocation(time.RFC3339, args[0], time.UTC)
+			if err == nil {
+				st.Setenv("GIT_COMMITTER_DATE", args[0])
+				st.Setenv("GIT_AUTHOR_DATE", args[0])
+			}
+			return nil, err
+		})
+}
+
+func scriptHandle() script.Cmd {
+	return script.Command(
+		script.CmdUsage{
+			Summary: "set the HTTP handler that will serve the script's output",
+			Args:    "handler [dir]",
+			Detail: []string{
+				"The handler will be passed the script's current working directory and environment as arguments.",
+				"Valid handlers include 'dir' (for general http.Dir serving), 'bzr', 'fossil', 'git', and 'hg'",
+			},
+		},
+		func(st *script.State, args ...string) (script.WaitFunc, error) {
+			if len(args) == 0 || len(args) > 2 {
+				return nil, script.ErrUsage
+			}
+
+			sc, err := getScriptCtx(st)
+			if err != nil {
+				return nil, err
+			}
+
+			if sc.handler != nil {
+				return nil, fmt.Errorf("server handler already set to %s", sc.handlerName)
+			}
+
+			name := args[0]
+			h, ok := sc.server.vcsHandlers[name]
+			if !ok {
+				return nil, fmt.Errorf("unrecognized VCS %q", name)
+			}
+			sc.handlerName = name
+			if !h.Available() {
+				return nil, ServerNotInstalledError{name}
+			}
+
+			dir := st.Getwd()
+			if len(args) >= 2 {
+				dir = st.Path(args[1])
+			}
+			sc.handler, err = h.Handler(dir, st.Environ(), sc.server.logger)
+			return nil, err
+		})
+}
+
+func scriptModzip() script.Cmd {
+	return script.Command(
+		script.CmdUsage{
+			Summary: "create a Go module zip file from a directory",
+			Args:    "zipfile path@version dir",
+		},
+		func(st *script.State, args ...string) (wait script.WaitFunc, err error) {
+			if len(args) != 3 {
+				return nil, script.ErrUsage
+			}
+			zipPath := st.Path(args[0])
+			mPath, version, ok := strings.Cut(args[1], "@")
+			if !ok {
+				return nil, script.ErrUsage
+			}
+			dir := st.Path(args[2])
+
+			if err := os.MkdirAll(filepath.Dir(zipPath), 0755); err != nil {
+				return nil, err
+			}
+			f, err := os.Create(zipPath)
+			if err != nil {
+				return nil, err
+			}
+			defer func() {
+				if closeErr := f.Close(); err == nil {
+					err = closeErr
+				}
+			}()
+
+			return nil, zip.CreateFromDir(f, module.Version{Path: mPath, Version: version}, dir)
+		})
+}
+
+func scriptUnquote() script.Cmd {
+	return script.Command(
+		script.CmdUsage{
+			Summary: "unquote the argument as a Go string",
+			Args:    "string",
+		},
+		func(st *script.State, args ...string) (script.WaitFunc, error) {
+			if len(args) != 1 {
+				return nil, script.ErrUsage
+			}
+
+			s, err := strconv.Unquote(`"` + args[0] + `"`)
+			if err != nil {
+				return nil, err
+			}
+
+			wait := func(*script.State) (stdout, stderr string, err error) {
+				return s, "", nil
+			}
+			return wait, nil
+		})
+}
diff --git a/src/cmd/go/internal/vcweb/svn.go b/src/cmd/go/internal/vcweb/svn.go
new file mode 100644
index 0000000..60222f1
--- /dev/null
+++ b/src/cmd/go/internal/vcweb/svn.go
@@ -0,0 +1,199 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package vcweb
+
+import (
+	"io"
+	"log"
+	"net"
+	"net/http"
+	"os/exec"
+	"strings"
+	"sync"
+)
+
+// An svnHandler serves requests for Subversion repos.
+//
+// Unlike the other vcweb handlers, svnHandler does not serve the Subversion
+// protocol directly over the HTTP connection. Instead, it opens a separate port
+// that serves the (non-HTTP) 'svn' protocol. The test binary can retrieve the
+// URL for that port by sending an HTTP request with the query parameter
+// "vcwebsvn=1".
+//
+// We take this approach because the 'svn' protocol is implemented by a
+// lightweight 'svnserve' binary that is usually packaged along with the 'svn'
+// client binary, whereas only known implementation of the Subversion HTTP
+// protocol is the mod_dav_svn apache2 module. Apache2 has a lot of dependencies
+// and also seems to rely on global configuration via well-known file paths, so
+// implementing a hermetic test using apache2 would require the test to run in a
+// complicated container environment, which wouldn't be nearly as
+// straightforward for Go contributors to set up and test against on their local
+// machine.
+type svnHandler struct {
+	svnRoot string // a directory containing all svn repos to be served
+	logger  *log.Logger
+
+	pathOnce     sync.Once
+	svnservePath string // the path to the 'svnserve' executable
+	svnserveErr  error
+
+	listenOnce sync.Once
+	s          chan *svnState // 1-buffered
+}
+
+// An svnState describes the state of a port serving the 'svn://' protocol.
+type svnState struct {
+	listener  net.Listener
+	listenErr error
+	conns     map[net.Conn]struct{}
+	closing   bool
+	done      chan struct{}
+}
+
+func (h *svnHandler) Available() bool {
+	h.pathOnce.Do(func() {
+		h.svnservePath, h.svnserveErr = exec.LookPath("svnserve")
+	})
+	return h.svnserveErr == nil
+}
+
+// Handler returns an http.Handler that checks for the "vcwebsvn" query
+// parameter and then serves the 'svn://' URL for the repository at the
+// requested path.
+// The HTTP client is expected to read that URL and pass it to the 'svn' client.
+func (h *svnHandler) Handler(dir string, env []string, logger *log.Logger) (http.Handler, error) {
+	if !h.Available() {
+		return nil, ServerNotInstalledError{name: "svn"}
+	}
+
+	// Go ahead and start the listener now, so that if it fails (for example, due
+	// to port exhaustion) we can return an error from the Handler method instead
+	// of serving an error for each individual HTTP request.
+	h.listenOnce.Do(func() {
+		h.s = make(chan *svnState, 1)
+		l, err := net.Listen("tcp", "localhost:0")
+		done := make(chan struct{})
+
+		h.s <- &svnState{
+			listener:  l,
+			listenErr: err,
+			conns:     map[net.Conn]struct{}{},
+			done:      done,
+		}
+		if err != nil {
+			close(done)
+			return
+		}
+
+		h.logger.Printf("serving svn on svn://%v", l.Addr())
+
+		go func() {
+			for {
+				c, err := l.Accept()
+
+				s := <-h.s
+				if err != nil {
+					s.listenErr = err
+					if len(s.conns) == 0 {
+						close(s.done)
+					}
+					h.s <- s
+					return
+				}
+				if s.closing {
+					c.Close()
+				} else {
+					s.conns[c] = struct{}{}
+					go h.serve(c)
+				}
+				h.s <- s
+			}
+		}()
+	})
+
+	s := <-h.s
+	addr := ""
+	if s.listener != nil {
+		addr = s.listener.Addr().String()
+	}
+	err := s.listenErr
+	h.s <- s
+	if err != nil {
+		return nil, err
+	}
+
+	handler := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
+		if req.FormValue("vcwebsvn") != "" {
+			w.Header().Add("Content-Type", "text/plain; charset=UTF-8")
+			io.WriteString(w, "svn://"+addr+"\n")
+			return
+		}
+		http.NotFound(w, req)
+	})
+
+	return handler, nil
+}
+
+// serve serves a single 'svn://' connection on c.
+func (h *svnHandler) serve(c net.Conn) {
+	defer func() {
+		c.Close()
+
+		s := <-h.s
+		delete(s.conns, c)
+		if len(s.conns) == 0 && s.listenErr != nil {
+			close(s.done)
+		}
+		h.s <- s
+	}()
+
+	// The "--inetd" flag causes svnserve to speak the 'svn' protocol over its
+	// stdin and stdout streams as if invoked by the Unix "inetd" service.
+	// We aren't using inetd, but we are implementing essentially the same
+	// approach: using a host process to listen for connections and spawn
+	// subprocesses to serve them.
+	cmd := exec.Command(h.svnservePath, "--read-only", "--root="+h.svnRoot, "--inetd")
+	cmd.Stdin = c
+	cmd.Stdout = c
+	stderr := new(strings.Builder)
+	cmd.Stderr = stderr
+	err := cmd.Run()
+
+	var errFrag any = "ok"
+	if err != nil {
+		errFrag = err
+	}
+	stderrFrag := ""
+	if stderr.Len() > 0 {
+		stderrFrag = "\n" + stderr.String()
+	}
+	h.logger.Printf("%v: %s%s", cmd, errFrag, stderrFrag)
+}
+
+// Close stops accepting new svn:// connections and terminates the existing
+// ones, then waits for the 'svnserve' subprocesses to complete.
+func (h *svnHandler) Close() error {
+	h.listenOnce.Do(func() {})
+	if h.s == nil {
+		return nil
+	}
+
+	var err error
+	s := <-h.s
+	s.closing = true
+	if s.listener == nil {
+		err = s.listenErr
+	} else {
+		err = s.listener.Close()
+	}
+	for c := range s.conns {
+		c.Close()
+	}
+	done := s.done
+	h.s <- s
+
+	<-done
+	return err
+}
diff --git a/src/cmd/go/internal/vcweb/vcstest/vcstest.go b/src/cmd/go/internal/vcweb/vcstest/vcstest.go
new file mode 100644
index 0000000..d460259
--- /dev/null
+++ b/src/cmd/go/internal/vcweb/vcstest/vcstest.go
@@ -0,0 +1,169 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package vcstest serves the repository scripts in cmd/go/testdata/vcstest
+// using the [vcweb] script engine.
+package vcstest
+
+import (
+	"cmd/go/internal/vcs"
+	"cmd/go/internal/vcweb"
+	"cmd/go/internal/web"
+	"crypto/tls"
+	"crypto/x509"
+	"encoding/pem"
+	"fmt"
+	"internal/testenv"
+	"io"
+	"log"
+	"net/http"
+	"net/http/httptest"
+	"net/url"
+	"os"
+	"path/filepath"
+	"testing"
+)
+
+var Hosts = []string{
+	"vcs-test.golang.org",
+}
+
+type Server struct {
+	vcweb   *vcweb.Server
+	workDir string
+	HTTP    *httptest.Server
+	HTTPS   *httptest.Server
+}
+
+// NewServer returns a new test-local vcweb server that serves VCS requests
+// for modules with paths that begin with "vcs-test.golang.org" using the
+// scripts in cmd/go/testdata/vcstest.
+func NewServer() (srv *Server, err error) {
+	if vcs.VCSTestRepoURL != "" {
+		panic("vcs URL hooks already set")
+	}
+
+	scriptDir := filepath.Join(testenv.GOROOT(nil), "src/cmd/go/testdata/vcstest")
+
+	workDir, err := os.MkdirTemp("", "vcstest")
+	if err != nil {
+		return nil, err
+	}
+	defer func() {
+		if err != nil {
+			os.RemoveAll(workDir)
+		}
+	}()
+
+	logger := log.Default()
+	if !testing.Verbose() {
+		logger = log.New(io.Discard, "", log.LstdFlags)
+	}
+	handler, err := vcweb.NewServer(scriptDir, workDir, logger)
+	if err != nil {
+		return nil, err
+	}
+	defer func() {
+		if err != nil {
+			handler.Close()
+		}
+	}()
+
+	srvHTTP := httptest.NewServer(handler)
+	httpURL, err := url.Parse(srvHTTP.URL)
+	if err != nil {
+		return nil, err
+	}
+	defer func() {
+		if err != nil {
+			srvHTTP.Close()
+		}
+	}()
+
+	srvHTTPS := httptest.NewTLSServer(handler)
+	httpsURL, err := url.Parse(srvHTTPS.URL)
+	if err != nil {
+		return nil, err
+	}
+	defer func() {
+		if err != nil {
+			srvHTTPS.Close()
+		}
+	}()
+
+	srv = &Server{
+		vcweb:   handler,
+		workDir: workDir,
+		HTTP:    srvHTTP,
+		HTTPS:   srvHTTPS,
+	}
+	vcs.VCSTestRepoURL = srv.HTTP.URL
+	vcs.VCSTestHosts = Hosts
+
+	var interceptors []web.Interceptor
+	for _, host := range Hosts {
+		interceptors = append(interceptors,
+			web.Interceptor{Scheme: "http", FromHost: host, ToHost: httpURL.Host, Client: srv.HTTP.Client()},
+			web.Interceptor{Scheme: "https", FromHost: host, ToHost: httpsURL.Host, Client: srv.HTTPS.Client()})
+	}
+	web.EnableTestHooks(interceptors)
+
+	fmt.Fprintln(os.Stderr, "vcs-test.golang.org rerouted to "+srv.HTTP.URL)
+	fmt.Fprintln(os.Stderr, "https://vcs-test.golang.org rerouted to "+srv.HTTPS.URL)
+
+	return srv, nil
+}
+
+func (srv *Server) Close() error {
+	if vcs.VCSTestRepoURL != srv.HTTP.URL {
+		panic("vcs URL hooks modified before Close")
+	}
+	vcs.VCSTestRepoURL = ""
+	vcs.VCSTestHosts = nil
+	web.DisableTestHooks()
+
+	srv.HTTP.Close()
+	srv.HTTPS.Close()
+	err := srv.vcweb.Close()
+	if rmErr := os.RemoveAll(srv.workDir); err == nil {
+		err = rmErr
+	}
+	return err
+}
+
+func (srv *Server) WriteCertificateFile() (string, error) {
+	b := pem.EncodeToMemory(&pem.Block{
+		Type:  "CERTIFICATE",
+		Bytes: srv.HTTPS.Certificate().Raw,
+	})
+
+	filename := filepath.Join(srv.workDir, "cert.pem")
+	if err := os.WriteFile(filename, b, 0644); err != nil {
+		return "", err
+	}
+	return filename, nil
+}
+
+// TLSClient returns an http.Client that can talk to the httptest.Server
+// whose certificate is written to the given file path.
+func TLSClient(certFile string) (*http.Client, error) {
+	client := &http.Client{
+		Transport: http.DefaultTransport.(*http.Transport).Clone(),
+	}
+
+	pemBytes, err := os.ReadFile(certFile)
+	if err != nil {
+		return nil, err
+	}
+
+	certpool := x509.NewCertPool()
+	if !certpool.AppendCertsFromPEM(pemBytes) {
+		return nil, fmt.Errorf("no certificates found in %s", certFile)
+	}
+	client.Transport.(*http.Transport).TLSClientConfig = &tls.Config{
+		RootCAs: certpool,
+	}
+
+	return client, nil
+}
diff --git a/src/cmd/go/internal/vcweb/vcstest/vcstest_test.go b/src/cmd/go/internal/vcweb/vcstest/vcstest_test.go
new file mode 100644
index 0000000..4a6d600
--- /dev/null
+++ b/src/cmd/go/internal/vcweb/vcstest/vcstest_test.go
@@ -0,0 +1,170 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package vcstest_test
+
+import (
+	"cmd/go/internal/vcweb"
+	"errors"
+	"flag"
+	"fmt"
+	"io"
+	"io/fs"
+	"log"
+	"net"
+	"net/http"
+	"net/http/httptest"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"strings"
+	"testing"
+	"time"
+)
+
+var (
+	dir  = flag.String("dir", "../../../testdata/vcstest", "directory containing scripts to serve")
+	host = flag.String("host", "localhost", "hostname on which to serve HTTP")
+	port = flag.Int("port", -1, "port on which to serve HTTP; if nonnegative, skips running tests")
+)
+
+func TestMain(m *testing.M) {
+	flag.Parse()
+
+	if *port >= 0 {
+		err := serveStandalone(*host, *port)
+		if err != nil {
+			log.Fatal(err)
+		}
+		os.Exit(0)
+	}
+
+	m.Run()
+}
+
+// serveStandalone serves the vcweb testdata in a standalone HTTP server.
+func serveStandalone(host string, port int) (err error) {
+	scriptDir, err := filepath.Abs(*dir)
+	if err != nil {
+		return err
+	}
+	work, err := os.MkdirTemp("", "vcweb")
+	if err != nil {
+		return err
+	}
+	defer func() {
+		if rmErr := os.RemoveAll(work); err == nil {
+			err = rmErr
+		}
+	}()
+
+	log.Printf("running scripts in %s", work)
+
+	v, err := vcweb.NewServer(scriptDir, work, log.Default())
+	if err != nil {
+		return err
+	}
+
+	l, err := net.Listen("tcp", fmt.Sprintf("%s:%d", host, port))
+	if err != nil {
+		return err
+	}
+	log.Printf("serving on http://%s:%d/", host, l.Addr().(*net.TCPAddr).Port)
+
+	return http.Serve(l, v)
+}
+
+// TestScripts verifies that the VCS setup scripts in cmd/go/testdata/vcstest
+// run successfully.
+func TestScripts(t *testing.T) {
+	scriptDir, err := filepath.Abs(*dir)
+	if err != nil {
+		t.Fatal(err)
+	}
+	s, err := vcweb.NewServer(scriptDir, t.TempDir(), log.Default())
+	if err != nil {
+		t.Fatal(err)
+	}
+	srv := httptest.NewServer(s)
+
+	// To check for data races in the handler, run the root handler to produce an
+	// overview of the script status at an arbitrary point during the test.
+	// (We ignore the output because the expected failure mode is a friendly stack
+	// dump from the race detector.)
+	t.Run("overview", func(t *testing.T) {
+		t.Parallel()
+
+		time.Sleep(1 * time.Millisecond) // Give the other handlers time to race.
+
+		resp, err := http.Get(srv.URL)
+		if err == nil {
+			io.Copy(io.Discard, resp.Body)
+			resp.Body.Close()
+		} else {
+			t.Error(err)
+		}
+	})
+
+	t.Cleanup(func() {
+		// The subtests spawned by WalkDir run in parallel. When they complete, this
+		// Cleanup callback will run. At that point we fetch the root URL (which
+		// contains a status page), both to test that the root handler runs without
+		// crashing and to display a nice summary of the server's view of the test
+		// coverage.
+		resp, err := http.Get(srv.URL)
+		if err == nil {
+			var body []byte
+			body, err = io.ReadAll(resp.Body)
+			if err == nil && testing.Verbose() {
+				t.Logf("GET %s:\n%s", srv.URL, body)
+			}
+			resp.Body.Close()
+		}
+		if err != nil {
+			t.Error(err)
+		}
+
+		srv.Close()
+	})
+
+	err = filepath.WalkDir(scriptDir, func(path string, d fs.DirEntry, err error) error {
+		if err != nil || d.IsDir() {
+			return err
+		}
+
+		rel, err := filepath.Rel(scriptDir, path)
+		if err != nil {
+			return err
+		}
+		if rel == "README" {
+			return nil
+		}
+
+		t.Run(filepath.ToSlash(rel), func(t *testing.T) {
+			t.Parallel()
+
+			buf := new(strings.Builder)
+			logger := log.New(buf, "", log.LstdFlags)
+			// Load the script but don't try to serve the results:
+			// different VCS tools have different handler protocols,
+			// and the tests that actually use these repos will ensure
+			// that they are served correctly as a side effect anyway.
+			err := s.HandleScript(rel, logger, func(http.Handler) {})
+			if buf.Len() > 0 {
+				t.Log(buf)
+			}
+			if err != nil {
+				if notInstalled := (vcweb.ServerNotInstalledError{}); errors.As(err, &notInstalled) || errors.Is(err, exec.ErrNotFound) {
+					t.Skip(err)
+				}
+				t.Error(err)
+			}
+		})
+		return nil
+	})
+
+	if err != nil {
+		t.Error(err)
+	}
+}
diff --git a/src/cmd/go/internal/vcweb/vcweb.go b/src/cmd/go/internal/vcweb/vcweb.go
new file mode 100644
index 0000000..e1f1282
--- /dev/null
+++ b/src/cmd/go/internal/vcweb/vcweb.go
@@ -0,0 +1,425 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package vcweb serves version control repos for testing the go command.
+//
+// It is loosely derived from golang.org/x/build/vcs-test/vcweb,
+// which ran as a service hosted at vcs-test.golang.org.
+//
+// When a repository URL is first requested, the vcweb [Server] dynamically
+// regenerates the repository using a script interpreted by a [script.Engine].
+// The script produces the server's contents for a corresponding root URL and
+// all subdirectories of that URL, which are then cached: subsequent requests
+// for any URL generated by the script will serve the script's previous output
+// until the script is modified.
+//
+// The script engine includes all of the engine's default commands and
+// conditions, as well as commands for each supported VCS binary (bzr, fossil,
+// git, hg, and svn), a "handle" command that informs the script which protocol
+// or handler to use to serve the request, and utilities "at" (which sets
+// environment variables for Git timestamps) and "unquote" (which unquotes its
+// argument as if it were a Go string literal).
+//
+// The server's "/" endpoint provides a summary of the available scripts,
+// and "/help" provides documentation for the script environment.
+//
+// To run a standalone server based on the vcweb engine, use:
+//
+//	go test cmd/go/internal/vcweb/vcstest -v --port=0
+package vcweb
+
+import (
+	"bufio"
+	"cmd/go/internal/script"
+	"context"
+	"crypto/sha256"
+	"errors"
+	"fmt"
+	"io"
+	"io/fs"
+	"log"
+	"net/http"
+	"os"
+	"os/exec"
+	"path"
+	"path/filepath"
+	"runtime/debug"
+	"strings"
+	"sync"
+	"text/tabwriter"
+	"time"
+)
+
+// A Server serves cached, dynamically-generated version control repositories.
+type Server struct {
+	env    []string
+	logger *log.Logger
+
+	scriptDir string
+	workDir   string
+	homeDir   string // $workdir/home
+	engine    *script.Engine
+
+	scriptCache sync.Map // script path → *scriptResult
+
+	vcsHandlers map[string]vcsHandler
+}
+
+// A vcsHandler serves repositories over HTTP for a known version-control tool.
+type vcsHandler interface {
+	Available() bool
+	Handler(dir string, env []string, logger *log.Logger) (http.Handler, error)
+}
+
+// A scriptResult describes the cached result of executing a vcweb script.
+type scriptResult struct {
+	mu sync.RWMutex
+
+	hash     [sha256.Size]byte // hash of the script file, for cache invalidation
+	hashTime time.Time         // timestamp at which the script was run, for diagnostics
+
+	handler http.Handler // HTTP handler configured by the script
+	err     error        // error from executing the script, if any
+}
+
+// NewServer returns a Server that generates and serves repositories in workDir
+// using the scripts found in scriptDir and its subdirectories.
+//
+// A request for the path /foo/bar/baz will be handled by the first script along
+// that path that exists: $scriptDir/foo.txt, $scriptDir/foo/bar.txt, or
+// $scriptDir/foo/bar/baz.txt.
+func NewServer(scriptDir, workDir string, logger *log.Logger) (*Server, error) {
+	if scriptDir == "" {
+		panic("vcweb.NewServer: scriptDir is required")
+	}
+	var err error
+	scriptDir, err = filepath.Abs(scriptDir)
+	if err != nil {
+		return nil, err
+	}
+
+	if workDir == "" {
+		workDir, err = os.MkdirTemp("", "vcweb-*")
+		if err != nil {
+			return nil, err
+		}
+		logger.Printf("vcweb work directory: %s", workDir)
+	} else {
+		workDir, err = filepath.Abs(workDir)
+		if err != nil {
+			return nil, err
+		}
+	}
+
+	homeDir := filepath.Join(workDir, "home")
+	if err := os.MkdirAll(homeDir, 0755); err != nil {
+		return nil, err
+	}
+
+	env := scriptEnviron(homeDir)
+
+	s := &Server{
+		env:       env,
+		logger:    logger,
+		scriptDir: scriptDir,
+		workDir:   workDir,
+		homeDir:   homeDir,
+		engine:    newScriptEngine(),
+		vcsHandlers: map[string]vcsHandler{
+			"auth":     new(authHandler),
+			"dir":      new(dirHandler),
+			"bzr":      new(bzrHandler),
+			"fossil":   new(fossilHandler),
+			"git":      new(gitHandler),
+			"hg":       new(hgHandler),
+			"insecure": new(insecureHandler),
+			"svn":      &svnHandler{svnRoot: workDir, logger: logger},
+		},
+	}
+
+	if err := os.WriteFile(filepath.Join(s.homeDir, ".gitconfig"), []byte(gitConfig), 0644); err != nil {
+		return nil, err
+	}
+	gitConfigDir := filepath.Join(s.homeDir, ".config", "git")
+	if err := os.MkdirAll(gitConfigDir, 0755); err != nil {
+		return nil, err
+	}
+	if err := os.WriteFile(filepath.Join(gitConfigDir, "ignore"), []byte(""), 0644); err != nil {
+		return nil, err
+	}
+
+	if err := os.WriteFile(filepath.Join(s.homeDir, ".hgrc"), []byte(hgrc), 0644); err != nil {
+		return nil, err
+	}
+
+	return s, nil
+}
+
+func (s *Server) Close() error {
+	var firstErr error
+	for _, h := range s.vcsHandlers {
+		if c, ok := h.(io.Closer); ok {
+			if closeErr := c.Close(); firstErr == nil {
+				firstErr = closeErr
+			}
+		}
+	}
+	return firstErr
+}
+
+// gitConfig contains a ~/.gitconfg file that attempts to provide
+// deterministic, platform-agnostic behavior for the 'git' command.
+var gitConfig = `
+[user]
+	name = Go Gopher
+	email = [email protected]
+[init]
+	defaultBranch = main
+[core]
+	eol = lf
+[gui]
+	encoding = utf-8
+`[1:]
+
+// hgrc contains a ~/.hgrc file that attempts to provide
+// deterministic, platform-agnostic behavior for the 'hg' command.
+var hgrc = `
+[ui]
+username=Go Gopher <[email protected]>
+[phases]
+new-commit=public
+[extensions]
+convert=
+`[1:]
+
+// ServeHTTP implements [http.Handler] for version-control repositories.
+func (s *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) {
+	s.logger.Printf("serving %s", req.URL)
+
+	defer func() {
+		if v := recover(); v != nil {
+			debug.PrintStack()
+			s.logger.Fatal(v)
+		}
+	}()
+
+	urlPath := req.URL.Path
+	if !strings.HasPrefix(urlPath, "/") {
+		urlPath = "/" + urlPath
+	}
+	clean := path.Clean(urlPath)[1:]
+	if clean == "" {
+		s.overview(w, req)
+		return
+	}
+	if clean == "help" {
+		s.help(w, req)
+		return
+	}
+
+	// Locate the script that generates the requested path.
+	// We follow directories all the way to the end, then look for a ".txt" file
+	// matching the first component that doesn't exist. That guarantees
+	// uniqueness: if a path exists as a directory, then it cannot exist as a
+	// ".txt" script (because the search would ignore that file).
+	scriptPath := "."
+	for _, part := range strings.Split(clean, "/") {
+		scriptPath = filepath.Join(scriptPath, part)
+		dir := filepath.Join(s.scriptDir, scriptPath)
+		if _, err := os.Stat(dir); err != nil {
+			if !os.IsNotExist(err) {
+				http.Error(w, err.Error(), http.StatusInternalServerError)
+				return
+			}
+			// scriptPath does not exist as a directory, so it either is the script
+			// location or the script doesn't exist.
+			break
+		}
+	}
+	scriptPath += ".txt"
+
+	err := s.HandleScript(scriptPath, s.logger, func(handler http.Handler) {
+		handler.ServeHTTP(w, req)
+	})
+	if err != nil {
+		s.logger.Print(err)
+		if notFound := (ScriptNotFoundError{}); errors.As(err, &notFound) {
+			http.NotFound(w, req)
+		} else if notInstalled := (ServerNotInstalledError{}); errors.As(err, &notInstalled) || errors.Is(err, exec.ErrNotFound) {
+			http.Error(w, err.Error(), http.StatusNotImplemented)
+		} else {
+			http.Error(w, err.Error(), http.StatusInternalServerError)
+		}
+	}
+}
+
+// A ScriptNotFoundError indicates that the requested script file does not exist.
+// (It typically wraps a "stat" error for the script file.)
+type ScriptNotFoundError struct{ err error }
+
+func (e ScriptNotFoundError) Error() string { return e.err.Error() }
+func (e ScriptNotFoundError) Unwrap() error { return e.err }
+
+// A ServerNotInstalledError indicates that the server binary required for the
+// indicated VCS does not exist.
+type ServerNotInstalledError struct{ name string }
+
+func (v ServerNotInstalledError) Error() string {
+	return fmt.Sprintf("server for %#q VCS is not installed", v.name)
+}
+
+// HandleScript ensures that the script at scriptRelPath has been evaluated
+// with its current contents.
+//
+// If the script completed successfully, HandleScript invokes f on the handler
+// with the script's result still read-locked, and waits for it to return. (That
+// ensures that cache invalidation does not race with an in-flight handler.)
+//
+// Otherwise, HandleScript returns the (cached) error from executing the script.
+func (s *Server) HandleScript(scriptRelPath string, logger *log.Logger, f func(http.Handler)) error {
+	ri, ok := s.scriptCache.Load(scriptRelPath)
+	if !ok {
+		ri, _ = s.scriptCache.LoadOrStore(scriptRelPath, new(scriptResult))
+	}
+	r := ri.(*scriptResult)
+
+	relDir := strings.TrimSuffix(scriptRelPath, filepath.Ext(scriptRelPath))
+	workDir := filepath.Join(s.workDir, relDir)
+	prefix := path.Join("/", filepath.ToSlash(relDir))
+
+	r.mu.RLock()
+	defer r.mu.RUnlock()
+	for {
+		// For efficiency, we cache the script's output (in the work directory)
+		// across invocations. However, to allow for rapid iteration, we hash the
+		// script's contents and regenerate its output if the contents change.
+		//
+		// That way, one can use 'go run main.go' in this directory to stand up a
+		// server and see the output of the test script in order to fine-tune it.
+		content, err := os.ReadFile(filepath.Join(s.scriptDir, scriptRelPath))
+		if err != nil {
+			if !os.IsNotExist(err) {
+				return err
+			}
+			return ScriptNotFoundError{err}
+		}
+
+		hash := sha256.Sum256(content)
+		if prevHash := r.hash; prevHash != hash {
+			// The script's hash has changed, so regenerate its output.
+			func() {
+				r.mu.RUnlock()
+				r.mu.Lock()
+				defer func() {
+					r.mu.Unlock()
+					r.mu.RLock()
+				}()
+				if r.hash != prevHash {
+					// The cached result changed while we were waiting on the lock.
+					// It may have been updated to our hash or something even newer,
+					// so don't overwrite it.
+					return
+				}
+
+				r.hash = hash
+				r.hashTime = time.Now()
+				r.handler, r.err = nil, nil
+
+				if err := os.RemoveAll(workDir); err != nil {
+					r.err = err
+					return
+				}
+
+				// Note: we use context.Background here instead of req.Context() so that we
+				// don't cache a spurious error (and lose work) if the request is canceled
+				// while the script is still running.
+				scriptHandler, err := s.loadScript(context.Background(), logger, scriptRelPath, content, workDir)
+				if err != nil {
+					r.err = err
+					return
+				}
+				r.handler = http.StripPrefix(prefix, scriptHandler)
+			}()
+		}
+
+		if r.hash != hash {
+			continue // Raced with an update from another handler; try again.
+		}
+
+		if r.err != nil {
+			return r.err
+		}
+		f(r.handler)
+		return nil
+	}
+}
+
+// overview serves an HTML summary of the status of the scripts in the server's
+// script directory.
+func (s *Server) overview(w http.ResponseWriter, r *http.Request) {
+	fmt.Fprintf(w, "<html>\n")
+	fmt.Fprintf(w, "<title>vcweb</title>\n<pre>\n")
+	fmt.Fprintf(w, "<b>vcweb</b>\n\n")
+	fmt.Fprintf(w, "This server serves various version control repos for testing the go command.\n\n")
+	fmt.Fprintf(w, "For an overview of the script lanugage, see <a href=\"/help\">/help</a>.\n\n")
+
+	fmt.Fprintf(w, "<b>cache</b>\n")
+
+	tw := tabwriter.NewWriter(w, 1, 8, 1, '\t', 0)
+	err := filepath.WalkDir(s.scriptDir, func(path string, d fs.DirEntry, err error) error {
+		if err != nil {
+			return err
+		}
+		if filepath.Ext(path) != ".txt" {
+			return nil
+		}
+
+		rel, err := filepath.Rel(s.scriptDir, path)
+		if err != nil {
+			return err
+		}
+		hashTime := "(not loaded)"
+		status := ""
+		if ri, ok := s.scriptCache.Load(rel); ok {
+			r := ri.(*scriptResult)
+			r.mu.RLock()
+			defer r.mu.RUnlock()
+
+			if !r.hashTime.IsZero() {
+				hashTime = r.hashTime.Format(time.RFC3339)
+			}
+			if r.err == nil {
+				status = "ok"
+			} else {
+				status = r.err.Error()
+			}
+		}
+		fmt.Fprintf(tw, "%s\t%s\t%s\n", rel, hashTime, status)
+		return nil
+	})
+	tw.Flush()
+
+	if err != nil {
+		fmt.Fprintln(w, err)
+	}
+}
+
+// help serves a plain-text summary of the server's supported script language.
+func (s *Server) help(w http.ResponseWriter, req *http.Request) {
+	st, err := s.newState(req.Context(), s.workDir)
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+
+	scriptLog := new(strings.Builder)
+	err = s.engine.Execute(st, "help", bufio.NewReader(strings.NewReader("help")), scriptLog)
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+
+	w.Header().Set("Content-Type", "text/plain; charset=UTF-8")
+	io.WriteString(w, scriptLog.String())
+}
diff --git a/src/cmd/go/internal/vcweb/vcweb_test.go b/src/cmd/go/internal/vcweb/vcweb_test.go
new file mode 100644
index 0000000..20b2137
--- /dev/null
+++ b/src/cmd/go/internal/vcweb/vcweb_test.go
@@ -0,0 +1,63 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package vcweb_test
+
+import (
+	"cmd/go/internal/vcweb"
+	"io"
+	"log"
+	"net/http"
+	"net/http/httptest"
+	"os"
+	"testing"
+)
+
+func TestHelp(t *testing.T) {
+	s, err := vcweb.NewServer(os.DevNull, t.TempDir(), log.Default())
+	if err != nil {
+		t.Fatal(err)
+	}
+	srv := httptest.NewServer(s)
+	defer srv.Close()
+
+	resp, err := http.Get(srv.URL + "/help")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer resp.Body.Close()
+
+	if resp.StatusCode != 200 {
+		t.Fatal(resp.Status)
+	}
+	body, err := io.ReadAll(resp.Body)
+	if err != nil {
+		t.Fatal(err)
+	}
+	t.Logf("%s", body)
+}
+
+func TestOverview(t *testing.T) {
+	s, err := vcweb.NewServer(os.DevNull, t.TempDir(), log.Default())
+	if err != nil {
+		t.Fatal(err)
+	}
+	srv := httptest.NewServer(s)
+	defer srv.Close()
+
+	resp, err := http.Get(srv.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer resp.Body.Close()
+
+	if resp.StatusCode != 200 {
+		t.Fatal(resp.Status)
+	}
+	body, err := io.ReadAll(resp.Body)
+	if err != nil {
+		t.Fatal(err)
+	}
+	t.Logf("%s", body)
+}
diff --git a/src/cmd/go/internal/version/version.go b/src/cmd/go/internal/version/version.go
index 5de7b83..a0f6123 100644
--- a/src/cmd/go/internal/version/version.go
+++ b/src/cmd/go/internal/version/version.go
@@ -22,10 +22,9 @@
 var CmdVersion = &base.Command{
 	UsageLine: "go version [-m] [-v] [file ...]",
 	Short:     "print Go version",
-	Long: `Version prints the build information for Go executables.
+	Long: `Version prints the build information for Go binary files.
 
-Go version reports the Go version used to build each of the named
-executable files.
+Go version reports the Go version used to build each of the named files.
 
 If no files are named on the command line, go version prints its own
 version information.
@@ -35,7 +34,7 @@
 By default, go version does not report unrecognized files found
 during a directory scan. The -v flag causes it to report unrecognized files.
 
-The -m flag causes go version to print each executable's embedded
+The -m flag causes go version to print each file's embedded
 module version information, when available. In the output, the module
 information consists of multiple lines following the version line, each
 indented by a leading tab character.
@@ -45,6 +44,7 @@
 }
 
 func init() {
+	base.AddChdirFlag(&CmdVersion.Flag)
 	CmdVersion.Run = runVersion // break init cycle
 }
 
@@ -92,7 +92,7 @@
 	}
 }
 
-// scanDir scans a directory for executables to run scanFile on.
+// scanDir scans a directory for binary to run scanFile on.
 func scanDir(dir string) {
 	filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error {
 		if d.Type().IsRegular() || d.Type()&fs.ModeSymlink != 0 {
@@ -109,18 +109,24 @@
 	})
 }
 
-// isExe reports whether the file should be considered executable.
-func isExe(file string, info fs.FileInfo) bool {
-	if runtime.GOOS == "windows" {
-		return strings.HasSuffix(strings.ToLower(file), ".exe")
+// isGoBinaryCandidate reports whether the file is a candidate to be a Go binary.
+func isGoBinaryCandidate(file string, info fs.FileInfo) bool {
+	if info.Mode().IsRegular() && info.Mode()&0111 != 0 {
+		return true
 	}
-	return info.Mode().IsRegular() && info.Mode()&0111 != 0
+	name := strings.ToLower(file)
+	switch filepath.Ext(name) {
+	case ".so", ".exe", ".dll":
+		return true
+	default:
+		return strings.Contains(name, ".so.")
+	}
 }
 
 // scanFile scans file to try to report the Go and module versions.
 // If mustPrint is true, scanFile will report any error reading file.
 // Otherwise (mustPrint is false, because scanFile is being called
-// by scanDir) scanFile prints nothing for non-Go executables.
+// by scanDir) scanFile prints nothing for non-Go binaries.
 func scanFile(file string, info fs.FileInfo, mustPrint bool) {
 	if info.Mode()&fs.ModeSymlink != 0 {
 		// Accept file symlinks only.
@@ -134,20 +140,20 @@
 		info = i
 	}
 
-	if !isExe(file, info) {
-		if mustPrint {
-			fmt.Fprintf(os.Stderr, "%s: not executable file\n", file)
-		}
-		return
-	}
-
 	bi, err := buildinfo.ReadFile(file)
 	if err != nil {
 		if mustPrint {
 			if pathErr := (*os.PathError)(nil); errors.As(err, &pathErr) && filepath.Clean(pathErr.Path) == filepath.Clean(file) {
 				fmt.Fprintf(os.Stderr, "%v\n", file)
 			} else {
-				fmt.Fprintf(os.Stderr, "%s: %v\n", file, err)
+
+				// Skip errors for non-Go binaries.
+				// buildinfo.ReadFile errors are not fine-grained enough
+				// to know if the file is a Go binary or not,
+				// so try to infer it from the file mode and extension.
+				if isGoBinaryCandidate(file, info) {
+					fmt.Fprintf(os.Stderr, "%s: %v\n", file, err)
+				}
 			}
 		}
 		return
diff --git a/src/cmd/go/internal/vet/vet.go b/src/cmd/go/internal/vet/vet.go
index a0b11fd..c73fa5b 100644
--- a/src/cmd/go/internal/vet/vet.go
+++ b/src/cmd/go/internal/vet/vet.go
@@ -25,7 +25,7 @@
 
 var CmdVet = &base.Command{
 	CustomFlags: true,
-	UsageLine:   "go vet [-n] [-x] [-vettool prog] [build flags] [vet flags] [packages]",
+	UsageLine:   "go vet [-C dir] [-n] [-x] [-vettool prog] [build flags] [vet flags] [packages]",
 	Short:       "report likely mistakes in packages",
 	Long: `
 Vet runs the Go vet command on the packages named by the import paths.
@@ -35,6 +35,7 @@
 For a list of checkers and their flags, see 'go tool vet help'.
 For details of a specific checker such as 'printf', see 'go tool vet help printf'.
 
+The -C flag changes to dir before running the 'go vet' command.
 The -n flag prints commands that would be executed.
 The -x flag prints commands as they are executed.
 
@@ -42,7 +43,7 @@
 or additional checks.
 For example, the 'shadow' analyzer can be built and run using these commands:
 
-  go install golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow
+  go install golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow@latest
   go vet -vettool=$(which shadow)
 
 The build flags supported by go vet are those that control package resolution
@@ -94,8 +95,12 @@
 		base.Fatalf("no packages to vet")
 	}
 
-	var b work.Builder
-	b.Init()
+	b := work.NewBuilder("")
+	defer func() {
+		if err := b.Close(); err != nil {
+			base.Fatalf("go: %v", err)
+		}
+	}()
 
 	root := &work.Action{Mode: "go vet"}
 	for _, p := range pkgs {
diff --git a/src/cmd/go/internal/web/api.go b/src/cmd/go/internal/web/api.go
index 9053b16..7a6e0c3 100644
--- a/src/cmd/go/internal/web/api.go
+++ b/src/cmd/go/internal/web/api.go
@@ -54,12 +54,16 @@
 		return fmt.Sprintf("reading %s: %v\n\tserver response:%s%s", e.URL, e.Status, detailSep, e.Detail)
 	}
 
-	if err := e.Err; err != nil {
-		if pErr, ok := e.Err.(*fs.PathError); ok && strings.HasSuffix(e.URL, pErr.Path) {
-			// Remove the redundant copy of the path.
-			err = pErr.Err
+	if eErr := e.Err; eErr != nil {
+		if pErr, ok := e.Err.(*fs.PathError); ok {
+			if u, err := url.Parse(e.URL); err == nil {
+				if fp, err := urlToFilePath(u); err == nil && pErr.Path == fp {
+					// Remove the redundant copy of the path.
+					eErr = pErr.Err
+				}
+			}
 		}
-		return fmt.Sprintf("reading %s: %v", e.URL, err)
+		return fmt.Sprintf("reading %s: %v", e.URL, eErr)
 	}
 
 	return fmt.Sprintf("reading %s: %v", e.URL, e.Status)
@@ -234,3 +238,9 @@
 
 	return n, err
 }
+
+// IsLocalHost reports whether the given URL refers to a local
+// (loopback) host, such as "localhost" or "127.0.0.1:8080".
+func IsLocalHost(u *url.URL) bool {
+	return isLocalHost(u)
+}
diff --git a/src/cmd/go/internal/web/bootstrap.go b/src/cmd/go/internal/web/bootstrap.go
index ab88e9e..6312169 100644
--- a/src/cmd/go/internal/web/bootstrap.go
+++ b/src/cmd/go/internal/web/bootstrap.go
@@ -21,3 +21,5 @@
 }
 
 func openBrowser(url string) bool { return false }
+
+func isLocalHost(u *urlpkg.URL) bool { return false }
diff --git a/src/cmd/go/internal/web/http.go b/src/cmd/go/internal/web/http.go
index a92326d..a3b7787 100644
--- a/src/cmd/go/internal/web/http.go
+++ b/src/cmd/go/internal/web/http.go
@@ -32,7 +32,8 @@
 // when we're connecting to https servers that might not be there
 // or might be using self-signed certificates.
 var impatientInsecureHTTPClient = &http.Client{
-	Timeout: 5 * time.Second,
+	CheckRedirect: checkRedirect,
+	Timeout:       5 * time.Second,
 	Transport: &http.Transport{
 		Proxy: http.ProxyFromEnvironment,
 		TLSClientConfig: &tls.Config{
@@ -41,23 +42,90 @@
 	},
 }
 
-// securityPreservingHTTPClient is like the default HTTP client, but rejects
-// redirects to plain-HTTP URLs if the original URL was secure.
-var securityPreservingHTTPClient = &http.Client{
-	CheckRedirect: func(req *http.Request, via []*http.Request) error {
+var securityPreservingDefaultClient = securityPreservingHTTPClient(http.DefaultClient)
+
+// securityPreservingDefaultClient returns a client that is like the original
+// but rejects redirects to plain-HTTP URLs if the original URL was secure.
+func securityPreservingHTTPClient(original *http.Client) *http.Client {
+	c := new(http.Client)
+	*c = *original
+	c.CheckRedirect = func(req *http.Request, via []*http.Request) error {
 		if len(via) > 0 && via[0].URL.Scheme == "https" && req.URL.Scheme != "https" {
 			lastHop := via[len(via)-1].URL
 			return fmt.Errorf("redirected from secure URL %s to insecure URL %s", lastHop, req.URL)
 		}
+		return checkRedirect(req, via)
+	}
+	return c
+}
 
-		// Go's http.DefaultClient allows 10 redirects before returning an error.
-		// The securityPreservingHTTPClient also uses this default policy to avoid
-		// Go command hangs.
-		if len(via) >= 10 {
-			return errors.New("stopped after 10 redirects")
+func checkRedirect(req *http.Request, via []*http.Request) error {
+	// Go's http.DefaultClient allows 10 redirects before returning an error.
+	// Mimic that behavior here.
+	if len(via) >= 10 {
+		return errors.New("stopped after 10 redirects")
+	}
+
+	interceptRequest(req)
+	return nil
+}
+
+type Interceptor struct {
+	Scheme   string
+	FromHost string
+	ToHost   string
+	Client   *http.Client
+}
+
+func EnableTestHooks(interceptors []Interceptor) error {
+	if enableTestHooks {
+		return errors.New("web: test hooks already enabled")
+	}
+
+	for _, t := range interceptors {
+		if t.FromHost == "" {
+			panic("EnableTestHooks: missing FromHost")
 		}
-		return nil
-	},
+		if t.ToHost == "" {
+			panic("EnableTestHooks: missing ToHost")
+		}
+	}
+
+	testInterceptors = interceptors
+	enableTestHooks = true
+	return nil
+}
+
+func DisableTestHooks() {
+	if !enableTestHooks {
+		panic("web: test hooks not enabled")
+	}
+	enableTestHooks = false
+	testInterceptors = nil
+}
+
+var (
+	enableTestHooks  = false
+	testInterceptors []Interceptor
+)
+
+func interceptURL(u *urlpkg.URL) (*Interceptor, bool) {
+	if !enableTestHooks {
+		return nil, false
+	}
+	for i, t := range testInterceptors {
+		if u.Host == t.FromHost && (t.Scheme == "" || u.Scheme == t.Scheme) {
+			return &testInterceptors[i], true
+		}
+	}
+	return nil, false
+}
+
+func interceptRequest(req *http.Request) {
+	if t, ok := interceptURL(req.URL); ok {
+		req.Host = req.URL.Host
+		req.URL.Host = t.ToHost
+	}
 }
 
 func get(security SecurityMode, url *urlpkg.URL) (*Response, error) {
@@ -67,31 +135,39 @@
 		return getFile(url)
 	}
 
-	if os.Getenv("TESTGOPROXY404") == "1" && url.Host == "proxy.golang.org" {
-		res := &Response{
-			URL:        url.Redacted(),
-			Status:     "404 testing",
-			StatusCode: 404,
-			Header:     make(map[string][]string),
-			Body:       http.NoBody,
-		}
-		if cfg.BuildX {
-			fmt.Fprintf(os.Stderr, "# get %s: %v (%.3fs)\n", url.Redacted(), res.Status, time.Since(start).Seconds())
-		}
-		return res, nil
-	}
+	if enableTestHooks {
+		switch url.Host {
+		case "proxy.golang.org":
+			if os.Getenv("TESTGOPROXY404") == "1" {
+				res := &Response{
+					URL:        url.Redacted(),
+					Status:     "404 testing",
+					StatusCode: 404,
+					Header:     make(map[string][]string),
+					Body:       http.NoBody,
+				}
+				if cfg.BuildX {
+					fmt.Fprintf(os.Stderr, "# get %s: %v (%.3fs)\n", url.Redacted(), res.Status, time.Since(start).Seconds())
+				}
+				return res, nil
+			}
 
-	if url.Host == "localhost.localdev" {
-		return nil, fmt.Errorf("no such host localhost.localdev")
-	}
-	if os.Getenv("TESTGONETWORK") == "panic" {
-		host := url.Host
-		if h, _, err := net.SplitHostPort(url.Host); err == nil && h != "" {
-			host = h
-		}
-		addr := net.ParseIP(host)
-		if addr == nil || (!addr.IsLoopback() && !addr.IsUnspecified()) {
-			panic("use of network: " + url.String())
+		case "localhost.localdev":
+			return nil, fmt.Errorf("no such host localhost.localdev")
+
+		default:
+			if os.Getenv("TESTGONETWORK") == "panic" {
+				if _, ok := interceptURL(url); !ok {
+					host := url.Host
+					if h, _, err := net.SplitHostPort(url.Host); err == nil && h != "" {
+						host = h
+					}
+					addr := net.ParseIP(host)
+					if addr == nil || (!addr.IsLoopback() && !addr.IsUnspecified()) {
+						panic("use of network: " + url.String())
+					}
+				}
+			}
 		}
 	}
 
@@ -111,12 +187,22 @@
 		if url.Scheme == "https" {
 			auth.AddCredentials(req)
 		}
+		t, intercepted := interceptURL(req.URL)
+		if intercepted {
+			req.Host = req.URL.Host
+			req.URL.Host = t.ToHost
+		}
 
 		var res *http.Response
 		if security == Insecure && url.Scheme == "https" { // fail earlier
 			res, err = impatientInsecureHTTPClient.Do(req)
 		} else {
-			res, err = securityPreservingHTTPClient.Do(req)
+			if intercepted && t.Client != nil {
+				client := securityPreservingHTTPClient(t.Client)
+				res, err = client.Do(req)
+			} else {
+				res, err = securityPreservingDefaultClient.Do(req)
+			}
 		}
 		return url, res, err
 	}
@@ -255,3 +341,20 @@
 }
 
 func openBrowser(url string) bool { return browser.Open(url) }
+
+func isLocalHost(u *urlpkg.URL) bool {
+	// VCSTestRepoURL itself is secure, and it may redirect requests to other
+	// ports (such as a port serving the "svn" protocol) which should also be
+	// considered secure.
+	host, _, err := net.SplitHostPort(u.Host)
+	if err != nil {
+		host = u.Host
+	}
+	if host == "localhost" {
+		return true
+	}
+	if ip := net.ParseIP(host); ip != nil && ip.IsLoopback() {
+		return true
+	}
+	return false
+}
diff --git a/src/cmd/go/internal/work/action.go b/src/cmd/go/internal/work/action.go
index c0862c5..8beb134 100644
--- a/src/cmd/go/internal/work/action.go
+++ b/src/cmd/go/internal/work/action.go
@@ -16,7 +16,6 @@
 	"fmt"
 	"os"
 	"path/filepath"
-	"runtime"
 	"strings"
 	"sync"
 	"time"
@@ -25,6 +24,7 @@
 	"cmd/go/internal/cache"
 	"cmd/go/internal/cfg"
 	"cmd/go/internal/load"
+	"cmd/go/internal/robustio"
 	"cmd/go/internal/trace"
 	"cmd/internal/buildid"
 )
@@ -33,16 +33,18 @@
 // It does not hold per-package state, because we
 // build packages in parallel, and the builder is shared.
 type Builder struct {
-	WorkDir     string               // the temporary work directory (ends in filepath.Separator)
-	actionCache map[cacheKey]*Action // a cache of already-constructed actions
-	mkdirCache  map[string]bool      // a cache of created directories
-	flagCache   map[[2]string]bool   // a cache of supported compiler flags
-	Print       func(args ...any) (int, error)
+	WorkDir            string                    // the temporary work directory (ends in filepath.Separator)
+	actionCache        map[cacheKey]*Action      // a cache of already-constructed actions
+	mkdirCache         map[string]bool           // a cache of created directories
+	flagCache          map[[2]string]bool        // a cache of supported compiler flags
+	gccCompilerIDCache map[string]cache.ActionID // cache for gccCompilerID
+	Print              func(args ...any) (int, error)
 
 	IsCmdList           bool // running as part of go list; set p.Stale and additional fields below
 	NeedError           bool // list needs p.Error
 	NeedExport          bool // list needs p.Export
 	NeedCompiledGoFiles bool // list needs p.CompiledGoFiles
+	AllowErrors         bool // errors don't immediately exit the program
 
 	objdirSeq int // counter for NewObjdir
 	pkgSeq    int
@@ -62,15 +64,27 @@
 // NOTE: Much of Action would not need to be exported if not for test.
 // Maybe test functionality should move into this package too?
 
+// An Actor runs an action.
+type Actor interface {
+	Act(*Builder, context.Context, *Action) error
+}
+
+// An ActorFunc is an Actor that calls the function.
+type ActorFunc func(*Builder, context.Context, *Action) error
+
+func (f ActorFunc) Act(b *Builder, ctx context.Context, a *Action) error {
+	return f(b, ctx, a)
+}
+
 // An Action represents a single action in the action graph.
 type Action struct {
-	Mode       string                                         // description of action operation
-	Package    *load.Package                                  // the package this action works on
-	Deps       []*Action                                      // actions that must happen before this one
-	Func       func(*Builder, context.Context, *Action) error // the action itself (nil = no-op)
-	IgnoreFail bool                                           // whether to run f even if dependencies fail
-	TestOutput *bytes.Buffer                                  // test output buffer
-	Args       []string                                       // additional args for runProgram
+	Mode       string        // description of action operation
+	Package    *load.Package // the package this action works on
+	Deps       []*Action     // actions that must happen before this one
+	Actor      Actor         // the action itself (nil = no-op)
+	IgnoreFail bool          // whether to run f even if dependencies fail
+	TestOutput *bytes.Buffer // test output buffer
+	Args       []string      // additional args for runProgram
 
 	triggers []*Action // inverse of deps
 
@@ -240,7 +254,15 @@
 	ModeVetOnly = 1 << 8
 )
 
-func (b *Builder) Init() {
+// NewBuilder returns a new Builder ready for use.
+//
+// If workDir is the empty string, NewBuilder creates a WorkDir if needed
+// and arranges for it to be removed in case of an unclean exit.
+// The caller must Close the builder explicitly to clean up the WorkDir
+// before a clean exit.
+func NewBuilder(workDir string) *Builder {
+	b := new(Builder)
+
 	b.Print = func(a ...any) (int, error) {
 		return fmt.Fprint(os.Stderr, a...)
 	}
@@ -249,9 +271,14 @@
 	b.toolIDCache = make(map[string]string)
 	b.buildIDCache = make(map[string]string)
 
-	if cfg.BuildN {
+	if workDir != "" {
+		b.WorkDir = workDir
+	} else if cfg.BuildN {
 		b.WorkDir = "$WORK"
 	} else {
+		if !buildInitStarted {
+			panic("internal error: NewBuilder called before BuildInit")
+		}
 		tmp, err := os.MkdirTemp(cfg.Getenv("GOTMPDIR"), "go-build")
 		if err != nil {
 			base.Fatalf("go: creating work dir: %v", err)
@@ -265,32 +292,10 @@
 			tmp = abs
 		}
 		b.WorkDir = tmp
+		builderWorkDirs.Store(b, b.WorkDir)
 		if cfg.BuildX || cfg.BuildWork {
 			fmt.Fprintf(os.Stderr, "WORK=%s\n", b.WorkDir)
 		}
-		if !cfg.BuildWork {
-			workdir := b.WorkDir
-			base.AtExit(func() {
-				start := time.Now()
-				for {
-					err := os.RemoveAll(workdir)
-					if err == nil {
-						return
-					}
-
-					// On some configurations of Windows, directories containing executable
-					// files may be locked for a while after the executable exits (perhaps
-					// due to antivirus scans?). It's probably worth a little extra latency
-					// on exit to avoid filling up the user's temporary directory with leaked
-					// files. (See golang.org/issue/30789.)
-					if runtime.GOOS != "windows" || time.Since(start) >= 500*time.Millisecond {
-						fmt.Fprintf(os.Stderr, "go: failed to remove work dir: %s\n", err)
-						return
-					}
-					time.Sleep(5 * time.Millisecond)
-				}
-			})
-		}
 	}
 
 	if err := CheckGOOSARCHPair(cfg.Goos, cfg.Goarch); err != nil {
@@ -306,6 +311,46 @@
 			base.Exit()
 		}
 	}
+
+	return b
+}
+
+var builderWorkDirs sync.Map // *Builder → WorkDir
+
+func (b *Builder) Close() error {
+	wd, ok := builderWorkDirs.Load(b)
+	if !ok {
+		return nil
+	}
+	defer builderWorkDirs.Delete(b)
+
+	if b.WorkDir != wd.(string) {
+		base.Errorf("go: internal error: Builder WorkDir unexpectedly changed from %s to %s", wd, b.WorkDir)
+	}
+
+	if !cfg.BuildWork {
+		if err := robustio.RemoveAll(b.WorkDir); err != nil {
+			return err
+		}
+	}
+	b.WorkDir = ""
+	return nil
+}
+
+func closeBuilders() {
+	leakedBuilders := 0
+	builderWorkDirs.Range(func(bi, _ any) bool {
+		leakedBuilders++
+		if err := bi.(*Builder).Close(); err != nil {
+			base.Errorf("go: %v", err)
+		}
+		return true
+	})
+
+	if leakedBuilders > 0 && base.GetExitStatus() == 0 {
+		fmt.Fprintf(os.Stderr, "go: internal error: Builder leaked on successful exit\n")
+		base.SetExitStatus(1)
+	}
 }
 
 func CheckGOOSARCHPair(goos, goarch string) error {
@@ -341,8 +386,8 @@
 		scanner := bufio.NewScanner(bytes.NewBuffer(data))
 		for scanner.Scan() {
 			t := scanner.Text()
-			if strings.HasPrefix(t, "pkgpath ") {
-				t = strings.TrimPrefix(t, "pkgpath ")
+			var found bool
+			if t, found = strings.CutPrefix(t, "pkgpath "); found {
 				t = strings.TrimSuffix(t, ";")
 				pkgs = append(pkgs, load.LoadImportWithFlags(t, base.Cwd(), nil, &stk, nil, 0))
 			}
@@ -391,8 +436,8 @@
 	vetOnly := mode&ModeVetOnly != 0
 	mode &^= ModeVetOnly
 
-	if mode != ModeBuild && (p.Internal.Local || p.Module != nil) && p.Target == "" {
-		// Imported via local path or using modules. No permanent target.
+	if mode != ModeBuild && p.Target == "" {
+		// No permanent target.
 		mode = ModeBuild
 	}
 	if mode != ModeBuild && p.Name == "main" {
@@ -405,7 +450,7 @@
 		a := &Action{
 			Mode:    "build",
 			Package: p,
-			Func:    (*Builder).build,
+			Actor:   ActorFunc((*Builder).build),
 			Objdir:  b.NewObjdir(),
 		}
 
@@ -420,7 +465,7 @@
 			case "builtin", "unsafe":
 				// Fake packages - nothing to build.
 				a.Mode = "built-in package"
-				a.Func = nil
+				a.Actor = nil
 				return a
 			}
 
@@ -429,7 +474,7 @@
 				// the target name is needed for cgo.
 				a.Mode = "gccgo stdlib"
 				a.Target = p.Target
-				a.Func = nil
+				a.Actor = nil
 				return a
 			}
 		}
@@ -502,12 +547,12 @@
 			VetxOnly:   true,
 			IgnoreFail: true, // it's OK if vet of dependencies "fails" (reports problems)
 		}
-		if a1.Func == nil {
+		if a1.Actor == nil {
 			// Built-in packages like unsafe.
 			return a
 		}
 		deps[0].needVet = true
-		a.Func = (*Builder).vet
+		a.Actor = ActorFunc((*Builder).vet)
 		return a
 	})
 	return a
@@ -525,7 +570,7 @@
 		}
 
 		a1 := b.CompileAction(ModeBuild, depMode, p)
-		a.Func = (*Builder).link
+		a.Actor = ActorFunc((*Builder).link)
 		a.Deps = []*Action{a1}
 		a.Objdir = a1.Objdir
 
@@ -587,7 +632,7 @@
 	// If there's no actual action to build a1,
 	// there's nothing to install either.
 	// This happens if a1 corresponds to reusing an already-built object.
-	if a1.Func == nil {
+	if a1.Actor == nil {
 		return a1
 	}
 
@@ -613,7 +658,7 @@
 		// on the install.
 		*a1 = Action{
 			Mode:    buildAction.Mode + "-install",
-			Func:    BuildInstallFunc,
+			Actor:   ActorFunc(BuildInstallFunc),
 			Package: p,
 			Objdir:  buildAction.Objdir,
 			Deps:    []*Action{buildAction},
@@ -704,7 +749,7 @@
 			Mode:    "install header",
 			Package: a.Package,
 			Deps:    []*Action{a.Deps[0]},
-			Func:    (*Builder).installHeader,
+			Actor:   ActorFunc((*Builder).installHeader),
 			Objdir:  a.Deps[0].Objdir,
 			Target:  hdrTarget,
 		}
@@ -764,7 +809,7 @@
 			Mode:    "go build -buildmode=shared",
 			Package: p,
 			Objdir:  b.NewObjdir(),
-			Func:    (*Builder).linkShared,
+			Actor:   ActorFunc((*Builder).linkShared),
 			Deps:    []*Action{a1},
 		}
 		a.Target = filepath.Join(a.Objdir, shlib)
@@ -805,7 +850,7 @@
 	})
 
 	// Install result.
-	if (mode == ModeInstall || mode == ModeBuggyInstall) && a.Func != nil {
+	if (mode == ModeInstall || mode == ModeBuggyInstall) && a.Actor != nil {
 		buildAction := a
 
 		a = b.cacheAction("install-shlib "+shlib, nil, func() *Action {
@@ -834,20 +879,21 @@
 			a := &Action{
 				Mode:   "go install -buildmode=shared",
 				Objdir: buildAction.Objdir,
-				Func:   BuildInstallFunc,
+				Actor:  ActorFunc(BuildInstallFunc),
 				Deps:   []*Action{buildAction},
 				Target: target,
 			}
 			for _, a2 := range buildAction.Deps[0].Deps {
 				p := a2.Package
-				if p.Target == "" {
+				pkgTargetRoot := p.Internal.Build.PkgTargetRoot
+				if pkgTargetRoot == "" {
 					continue
 				}
 				a.Deps = append(a.Deps, &Action{
 					Mode:    "shlibname",
 					Package: p,
-					Func:    (*Builder).installShlibname,
-					Target:  strings.TrimSuffix(p.Target, ".a") + ".shlibname",
+					Actor:   ActorFunc((*Builder).installShlibname),
+					Target:  filepath.Join(pkgTargetRoot, p.ImportPath+".shlibname"),
 					Deps:    []*Action{a.Deps[0]},
 				})
 			}
diff --git a/src/cmd/go/internal/work/build.go b/src/cmd/go/internal/work/build.go
index 42745d9..2f2860a 100644
--- a/src/cmd/go/internal/work/build.go
+++ b/src/cmd/go/internal/work/build.go
@@ -7,6 +7,7 @@
 import (
 	"context"
 	"errors"
+	"flag"
 	"fmt"
 	"go/build"
 	"os"
@@ -53,12 +54,13 @@
 ends with a slash or backslash, then any resulting executables
 will be written to that directory.
 
-The -i flag installs the packages that are dependencies of the target.
-The -i flag is deprecated. Compiled packages are cached automatically.
-
 The build flags are shared by the build, clean, get, install, list, run,
 and test commands:
 
+	-C dir
+		Change to dir before running the command.
+		Any files named on the command line are interpreted after
+		changing directories.
 	-a
 		force rebuilding of packages that are already up-to-date.
 	-n
@@ -73,14 +75,23 @@
 		linux/ppc64le and linux/arm64 (only for 48-bit VMA).
 	-msan
 		enable interoperation with memory sanitizer.
-		Supported only on linux/amd64, linux/arm64
+		Supported only on linux/amd64, linux/arm64, freebsd/amd64
 		and only with Clang/LLVM as the host C compiler.
-		On linux/arm64, pie build mode will be used.
+		PIE build mode will be used on all platforms except linux/amd64.
 	-asan
 		enable interoperation with address sanitizer.
 		Supported only on linux/arm64, linux/amd64.
 		Supported only on linux/amd64 or linux/arm64 and only with GCC 7 and higher
 		or Clang/LLVM 9 and higher.
+	-cover
+		enable code coverage instrumentation (requires
+		that GOEXPERIMENT=coverageredesign be set).
+	-coverpkg pattern1,pattern2,pattern3
+		For a build that targets package 'main' (e.g. building a Go
+		executable), apply coverage analysis to each package matching
+		the patterns. The default is to apply coverage analysis to
+		packages in the main Go module. See 'go help packages' for a
+		description of package patterns.  Sets -cover.
 	-v
 		print the names of packages as they are compiled.
 	-work
@@ -146,6 +157,11 @@
 		include path must be in the same directory as the Go package they are
 		included from, and overlays will not appear when binaries and tests are
 		run through go run and go test respectively.
+	-pgo file
+		specify the file path of a profile for profile-guided optimization (PGO).
+		Special name "auto" lets the go command select a file named
+		"default.pgo" in the main package's directory if that file exists.
+		Special name "off" turns off PGO.
 	-pkgdir dir
 		install and load all packages from dir instead of the usual locations.
 		For example, when building with a non-standard configuration,
@@ -206,13 +222,14 @@
 	CmdBuild.Run = runBuild
 	CmdInstall.Run = runInstall
 
-	CmdBuild.Flag.BoolVar(&cfg.BuildI, "i", false, "")
 	CmdBuild.Flag.StringVar(&cfg.BuildO, "o", "", "output file or directory")
 
-	CmdInstall.Flag.BoolVar(&cfg.BuildI, "i", false, "")
-
 	AddBuildFlags(CmdBuild, DefaultBuildFlags)
 	AddBuildFlags(CmdInstall, DefaultBuildFlags)
+	if cfg.Experiment != nil && cfg.Experiment.CoverageRedesign {
+		AddCoverFlags(CmdBuild, nil)
+		AddCoverFlags(CmdInstall, nil)
+	}
 }
 
 // Note that flags consulted by other parts of the code
@@ -273,6 +290,7 @@
 // install, list, run, and test commands.
 func AddBuildFlags(cmd *base.Command, mask BuildFlagMask) {
 	base.AddBuildFlagsNX(&cmd.Flag)
+	base.AddChdirFlag(&cmd.Flag)
 	cmd.Flag.BoolVar(&cfg.BuildA, "a", false, "")
 	cmd.Flag.IntVar(&cfg.BuildP, "p", cfg.BuildP, "")
 	if mask&OmitVFlag == 0 {
@@ -298,6 +316,7 @@
 	cmd.Flag.StringVar(&cfg.BuildContext.InstallSuffix, "installsuffix", "", "")
 	cmd.Flag.Var(&load.BuildLdflags, "ldflags", "")
 	cmd.Flag.BoolVar(&cfg.BuildLinkshared, "linkshared", false, "")
+	cmd.Flag.StringVar(&cfg.BuildPGO, "pgo", "", "")
 	cmd.Flag.StringVar(&cfg.BuildPkgdir, "pkgdir", "", "")
 	cmd.Flag.BoolVar(&cfg.BuildRace, "race", false, "")
 	cmd.Flag.BoolVar(&cfg.BuildMSan, "msan", false, "")
@@ -313,6 +332,31 @@
 	cmd.Flag.StringVar(&cfg.DebugTrace, "debug-trace", "", "")
 }
 
+// AddCoverFlags adds coverage-related flags to "cmd". If the
+// CoverageRedesign experiment is enabled, we add -cover{mode,pkg} to
+// the build command and only -coverprofile to the test command. If
+// the CoverageRedesign experiment is disabled, -cover* flags are
+// added only to the test command.
+func AddCoverFlags(cmd *base.Command, coverProfileFlag *string) {
+	addCover := false
+	if cfg.Experiment != nil && cfg.Experiment.CoverageRedesign {
+		// New coverage enabled: both build and test commands get
+		// coverage flags.
+		addCover = true
+	} else {
+		// New coverage disabled: only test command gets cover flags.
+		addCover = coverProfileFlag != nil
+	}
+	if addCover {
+		cmd.Flag.BoolVar(&cfg.BuildCover, "cover", false, "")
+		cmd.Flag.Var(coverFlag{(*coverModeFlag)(&cfg.BuildCoverMode)}, "covermode", "")
+		cmd.Flag.Var(coverFlag{commaListFlag{&cfg.BuildCoverPkg}}, "coverpkg", "")
+	}
+	if coverProfileFlag != nil {
+		cmd.Flag.Var(coverFlag{V: stringFlag{coverProfileFlag}}, "coverprofile", "")
+	}
+}
+
 // tagsFlag is the implementation of the -tags flag.
 type tagsFlag []string
 
@@ -403,10 +447,14 @@
 func runBuild(ctx context.Context, cmd *base.Command, args []string) {
 	modload.InitWorkfile()
 	BuildInit()
-	var b Builder
-	b.Init()
+	b := NewBuilder("")
+	defer func() {
+		if err := b.Close(); err != nil {
+			base.Fatalf("go: %v", err)
+		}
+	}()
 
-	pkgs := load.PackagesAndErrors(ctx, load.PackageOpts{LoadVCS: true}, args)
+	pkgs := load.PackagesAndErrors(ctx, load.PackageOpts{AutoVCS: true}, args)
 	load.CheckPackageErrors(pkgs)
 
 	explicitO := len(cfg.BuildO) > 0
@@ -432,18 +480,18 @@
 	}
 
 	depMode := ModeBuild
-	if cfg.BuildI {
-		depMode = ModeInstall
-		fmt.Fprint(os.Stderr, "go: -i flag is deprecated\n")
-	}
 
 	pkgs = omitTestOnly(pkgsFilter(pkgs))
 
 	// Special case -o /dev/null by not writing at all.
-	if cfg.BuildO == os.DevNull {
+	if base.IsNull(cfg.BuildO) {
 		cfg.BuildO = ""
 	}
 
+	if cfg.Experiment.CoverageRedesign && cfg.BuildCover {
+		load.PrepareForCoverageBuild(pkgs)
+	}
+
 	if cfg.BuildO != "" {
 		// If the -o name exists and is a directory or
 		// ends with a slash or backslash, then
@@ -542,12 +590,15 @@
 If module-aware mode is enabled, "go install" runs in the context of the main
 module.
 
-When module-aware mode is disabled, other packages are installed in the
+When module-aware mode is disabled, non-main packages are installed in the
 directory $GOPATH/pkg/$GOOS_$GOARCH. When module-aware mode is enabled,
-other packages are built and cached but not installed.
+non-main packages are built and cached but not installed.
 
-The -i flag installs the dependencies of the named packages as well.
-The -i flag is deprecated. Compiled packages are cached automatically.
+Before Go 1.20, the standard library was installed to
+$GOROOT/pkg/$GOOS_$GOARCH.
+Starting in Go 1.20, the standard library is built and cached but not installed.
+Setting GODEBUG=installgoroot=all restores the use of
+$GOROOT/pkg/$GOOS_$GOARCH.
 
 For more about the build flags, see 'go help build'.
 For more about specifying packages, see 'go help packages'.
@@ -619,16 +670,8 @@
 }
 
 func runInstall(ctx context.Context, cmd *base.Command, args []string) {
-	// TODO(golang.org/issue/41696): print a deprecation message for the -i flag
-	// whenever it's set (or just remove it). For now, we don't print a message
-	// if all named packages are in GOROOT. cmd/dist (run by make.bash) uses
-	// 'go install -i' when bootstrapping, and we don't want to show deprecation
-	// messages in that case.
 	for _, arg := range args {
 		if strings.Contains(arg, "@") && !build.IsLocalImport(arg) && !filepath.IsAbs(arg) {
-			if cfg.BuildI {
-				fmt.Fprint(os.Stderr, "go: -i flag is deprecated\n")
-			}
 			installOutsideModule(ctx, args)
 			return
 		}
@@ -636,7 +679,7 @@
 
 	modload.InitWorkfile()
 	BuildInit()
-	pkgs := load.PackagesAndErrors(ctx, load.PackageOpts{LoadVCS: true}, args)
+	pkgs := load.PackagesAndErrors(ctx, load.PackageOpts{AutoVCS: true}, args)
 	if cfg.ModulesEnabled && !modload.HasModRoot() {
 		haveErrors := false
 		allMissingErrors := true
@@ -660,17 +703,9 @@
 		}
 	}
 	load.CheckPackageErrors(pkgs)
-	if cfg.BuildI {
-		allGoroot := true
-		for _, pkg := range pkgs {
-			if !pkg.Goroot {
-				allGoroot = false
-				break
-			}
-		}
-		if !allGoroot {
-			fmt.Fprintf(os.Stderr, "go: -i flag is deprecated\n")
-		}
+
+	if cfg.Experiment.CoverageRedesign && cfg.BuildCover {
+		load.PrepareForCoverageBuild(pkgs)
 	}
 
 	InstallPackages(ctx, args, pkgs)
@@ -705,8 +740,6 @@
 	for _, p := range pkgs {
 		if p.Target == "" {
 			switch {
-			case p.Standard && p.ImportPath == "unsafe":
-				// unsafe is a built-in package, has no target
 			case p.Name != "main" && p.Internal.Local && p.ConflictDir == "":
 				// Non-executables outside GOPATH need not have a target:
 				// we can use the cache to hold the built package archive for use in future builds.
@@ -714,6 +747,11 @@
 				// or else something is wrong and worth reporting (like a ConflictDir).
 			case p.Name != "main" && p.Module != nil:
 				// Non-executables have no target (except the cache) when building with modules.
+			case p.Name != "main" && p.Standard && p.Internal.Build.PkgObj == "":
+				// Most packages in std do not need an installed .a, because they can be
+				// rebuilt and used directly from the build cache.
+				// A few targets (notably those using cgo) still do need to be installed
+				// in case the user's environment lacks a C compiler.
 			case p.Internal.GobinSubdir:
 				base.Errorf("go: cannot install cross-compiled binaries when GOBIN is set")
 			case p.Internal.CmdlineFiles:
@@ -728,12 +766,14 @@
 	}
 	base.ExitIfErrors()
 
-	var b Builder
-	b.Init()
+	b := NewBuilder("")
+	defer func() {
+		if err := b.Close(); err != nil {
+			base.Fatalf("go: %v", err)
+		}
+	}()
+
 	depMode := ModeBuild
-	if cfg.BuildI {
-		depMode = ModeInstall
-	}
 	a := &Action{Mode: "go install"}
 	var tools []*Action
 	for _, p := range pkgs {
@@ -853,3 +893,53 @@
 	}
 	return ExecCmd
 }
+
+// A coverFlag is a flag.Value that also implies -cover.
+type coverFlag struct{ V flag.Value }
+
+func (f coverFlag) String() string { return f.V.String() }
+
+func (f coverFlag) Set(value string) error {
+	if err := f.V.Set(value); err != nil {
+		return err
+	}
+	cfg.BuildCover = true
+	return nil
+}
+
+type coverModeFlag string
+
+func (f *coverModeFlag) String() string { return string(*f) }
+func (f *coverModeFlag) Set(value string) error {
+	switch value {
+	case "", "set", "count", "atomic":
+		*f = coverModeFlag(value)
+		cfg.BuildCoverMode = value
+		return nil
+	default:
+		return errors.New(`valid modes are "set", "count", or "atomic"`)
+	}
+}
+
+// A commaListFlag is a flag.Value representing a comma-separated list.
+type commaListFlag struct{ Vals *[]string }
+
+func (f commaListFlag) String() string { return strings.Join(*f.Vals, ",") }
+
+func (f commaListFlag) Set(value string) error {
+	if value == "" {
+		*f.Vals = nil
+	} else {
+		*f.Vals = strings.Split(value, ",")
+	}
+	return nil
+}
+
+// A stringFlag is a flag.Value representing a single string.
+type stringFlag struct{ val *string }
+
+func (f stringFlag) String() string { return *f.val }
+func (f stringFlag) Set(value string) error {
+	*f.val = value
+	return nil
+}
diff --git a/src/cmd/go/internal/work/build_test.go b/src/cmd/go/internal/work/build_test.go
index 0b6b83a..9e32b39 100644
--- a/src/cmd/go/internal/work/build_test.go
+++ b/src/cmd/go/internal/work/build_test.go
@@ -5,7 +5,6 @@
 package work
 
 import (
-	"bytes"
 	"fmt"
 	"io/fs"
 	"os"
@@ -233,7 +232,7 @@
 	// Check that `cp` is called instead of `mv` by looking at the output
 	// of `(*Builder).ShowCmd` afterwards as a sanity check.
 	cfg.BuildX = true
-	var cmdBuf bytes.Buffer
+	var cmdBuf strings.Builder
 	b.Print = func(a ...any) (int, error) {
 		return cmdBuf.WriteString(fmt.Sprint(a...))
 	}
diff --git a/src/cmd/go/internal/work/buildid.go b/src/cmd/go/internal/work/buildid.go
index a5b5570..db56714 100644
--- a/src/cmd/go/internal/work/buildid.go
+++ b/src/cmd/go/internal/work/buildid.go
@@ -17,6 +17,7 @@
 	"cmd/go/internal/fsys"
 	"cmd/go/internal/str"
 	"cmd/internal/buildid"
+	"cmd/internal/quoted"
 )
 
 // Build IDs
@@ -160,12 +161,12 @@
 
 	cmdline := str.StringList(cfg.BuildToolexec, path, "-V=full")
 	cmd := exec.Command(cmdline[0], cmdline[1:]...)
-	var stdout, stderr bytes.Buffer
+	var stdout, stderr strings.Builder
 	cmd.Stdout = &stdout
 	cmd.Stderr = &stderr
 	if err := cmd.Run(); err != nil {
 		if stderr.Len() > 0 {
-			os.Stderr.Write(stderr.Bytes())
+			os.Stderr.WriteString(stderr.String())
 		}
 		base.Fatalf("go: error obtaining buildID for %s: %v", desc, err)
 	}
@@ -206,14 +207,20 @@
 // In order to get reproducible builds for released compilers, we
 // detect a released compiler by the absence of "experimental" in the
 // --version output, and in that case we just use the version string.
-func (b *Builder) gccToolID(name, language string) (string, error) {
+//
+// gccToolID also returns the underlying executable for the compiler.
+// The caller assumes that stat of the exe can be used, combined with the id,
+// to detect changes in the underlying compiler. The returned exe can be empty,
+// which means to rely only on the id.
+func (b *Builder) gccToolID(name, language string) (id, exe string, err error) {
 	key := name + "." + language
 	b.id.Lock()
-	id := b.toolIDCache[key]
+	id = b.toolIDCache[key]
+	exe = b.toolIDCache[key+".exe"]
 	b.id.Unlock()
 
 	if id != "" {
-		return id, nil
+		return id, exe, nil
 	}
 
 	// Invoke the driver with -### to see the subcommands and the
@@ -225,19 +232,19 @@
 	cmd.Env = append(os.Environ(), "LC_ALL=C")
 	out, err := cmd.CombinedOutput()
 	if err != nil {
-		return "", fmt.Errorf("%s: %v; output: %q", name, err, out)
+		return "", "", fmt.Errorf("%s: %v; output: %q", name, err, out)
 	}
 
 	version := ""
 	lines := strings.Split(string(out), "\n")
 	for _, line := range lines {
-		if fields := strings.Fields(line); len(fields) > 1 && fields[1] == "version" {
+		if fields := strings.Fields(line); len(fields) > 1 && fields[1] == "version" || len(fields) > 2 && fields[2] == "version" {
 			version = line
 			break
 		}
 	}
 	if version == "" {
-		return "", fmt.Errorf("%s: can not find version number in %q", name, out)
+		return "", "", fmt.Errorf("%s: can not find version number in %q", name, out)
 	}
 
 	if !strings.Contains(version, "experimental") {
@@ -248,20 +255,20 @@
 		// a leading space is the compiler proper.
 		compiler := ""
 		for _, line := range lines {
-			if len(line) > 1 && line[0] == ' ' {
+			if strings.HasPrefix(line, " ") && !strings.HasPrefix(line, " (in-process)") {
 				compiler = line
 				break
 			}
 		}
 		if compiler == "" {
-			return "", fmt.Errorf("%s: can not find compilation command in %q", name, out)
+			return "", "", fmt.Errorf("%s: can not find compilation command in %q", name, out)
 		}
 
-		fields := strings.Fields(compiler)
+		fields, _ := quoted.Split(compiler)
 		if len(fields) == 0 {
-			return "", fmt.Errorf("%s: compilation command confusion %q", name, out)
+			return "", "", fmt.Errorf("%s: compilation command confusion %q", name, out)
 		}
-		exe := fields[0]
+		exe = fields[0]
 		if !strings.ContainsAny(exe, `/\`) {
 			if lp, err := exec.LookPath(exe); err == nil {
 				exe = lp
@@ -269,7 +276,7 @@
 		}
 		id, err = buildid.ReadFile(exe)
 		if err != nil {
-			return "", err
+			return "", "", err
 		}
 
 		// If we can't find a build ID, use a hash.
@@ -280,9 +287,10 @@
 
 	b.id.Lock()
 	b.toolIDCache[key] = id
+	b.toolIDCache[key+".exe"] = exe
 	b.id.Unlock()
 
-	return id, nil
+	return id, exe, nil
 }
 
 // Check if assembler used by gccgo is GNU as.
@@ -397,7 +405,7 @@
 // during a's work. The caller should defer b.flushOutput(a), to make sure
 // that flushOutput is eventually called regardless of whether the action
 // succeeds. The flushOutput call must happen after updateBuildID.
-func (b *Builder) useCache(a *Action, actionHash cache.ActionID, target string) bool {
+func (b *Builder) useCache(a *Action, actionHash cache.ActionID, target string, printOutput bool) bool {
 	// The second half of the build ID here is a placeholder for the content hash.
 	// It's important that the overall buildID be unlikely verging on impossible
 	// to appear in the output by chance, but that should be taken care of by
@@ -418,11 +426,19 @@
 		a.buildID = actionID + buildIDSeparator + mainpkg.buildID + buildIDSeparator + contentID
 	}
 
-	// Check to see if target exists and matches the expected action ID.
-	// If so, it's up to date and we can reuse it instead of rebuilding it.
-	var buildID string
-	if target != "" && !cfg.BuildA {
-		buildID, _ = buildid.ReadFile(target)
+	// If user requested -a, we force a rebuild, so don't use the cache.
+	if cfg.BuildA {
+		if p := a.Package; p != nil && !p.Stale {
+			p.Stale = true
+			p.StaleReason = "build -a flag in use"
+		}
+		// Begin saving output for later writing to cache.
+		a.output = []byte{}
+		return false
+	}
+
+	if target != "" {
+		buildID, _ := buildid.ReadFile(target)
 		if strings.HasPrefix(buildID, actionID+buildIDSeparator) {
 			a.buildID = buildID
 			if a.json != nil {
@@ -433,18 +449,13 @@
 			a.Target = "DO NOT USE - " + a.Mode
 			return true
 		}
-	}
-
-	// Special case for building a main package: if the only thing we
-	// want the package for is to link a binary, and the binary is
-	// already up-to-date, then to avoid a rebuild, report the package
-	// as up-to-date as well. See "Build IDs" comment above.
-	// TODO(rsc): Rewrite this code to use a TryCache func on the link action.
-	if target != "" && !cfg.BuildA && !b.NeedExport && a.Mode == "build" && len(a.triggers) == 1 && a.triggers[0].Mode == "link" {
-		buildID, err := buildid.ReadFile(target)
-		if err == nil {
-			id := strings.Split(buildID, buildIDSeparator)
-			if len(id) == 4 && id[1] == actionID {
+		// Special case for building a main package: if the only thing we
+		// want the package for is to link a binary, and the binary is
+		// already up-to-date, then to avoid a rebuild, report the package
+		// as up-to-date as well. See "Build IDs" comment above.
+		// TODO(rsc): Rewrite this code to use a TryCache func on the link action.
+		if !b.NeedExport && a.Mode == "build" && len(a.triggers) == 1 && a.triggers[0].Mode == "link" {
+			if id := strings.Split(buildID, buildIDSeparator); len(id) == 4 && id[1] == actionID {
 				// Temporarily assume a.buildID is the package build ID
 				// stored in the installed binary, and see if that makes
 				// the upcoming link action ID a match. If so, report that
@@ -462,9 +473,11 @@
 					// Best effort attempt to display output from the compile and link steps.
 					// If it doesn't work, it doesn't work: reusing the cached binary is more
 					// important than reprinting diagnostic information.
-					if c := cache.Default(); c != nil {
-						showStdout(b, c, a.actionID, "stdout")      // compile output
-						showStdout(b, c, a.actionID, "link-stdout") // link output
+					if printOutput {
+						if c := cache.Default(); c != nil {
+							showStdout(b, c, a.actionID, "stdout")      // compile output
+							showStdout(b, c, a.actionID, "link-stdout") // link output
+						}
 					}
 
 					// Poison a.Target to catch uses later in the build.
@@ -486,13 +499,15 @@
 	// then to avoid the link step, report the link as up-to-date.
 	// We avoid the nested build ID problem in the previous special case
 	// by recording the test results in the cache under the action ID half.
-	if !cfg.BuildA && len(a.triggers) == 1 && a.triggers[0].TryCache != nil && a.triggers[0].TryCache(b, a.triggers[0]) {
+	if len(a.triggers) == 1 && a.triggers[0].TryCache != nil && a.triggers[0].TryCache(b, a.triggers[0]) {
 		// Best effort attempt to display output from the compile and link steps.
 		// If it doesn't work, it doesn't work: reusing the test result is more
 		// important than reprinting diagnostic information.
-		if c := cache.Default(); c != nil {
-			showStdout(b, c, a.Deps[0].actionID, "stdout")      // compile output
-			showStdout(b, c, a.Deps[0].actionID, "link-stdout") // link output
+		if printOutput {
+			if c := cache.Default(); c != nil {
+				showStdout(b, c, a.Deps[0].actionID, "stdout")      // compile output
+				showStdout(b, c, a.Deps[0].actionID, "link-stdout") // link output
+			}
 		}
 
 		// Poison a.Target to catch uses later in the build.
@@ -501,62 +516,51 @@
 		return true
 	}
 
-	if b.IsCmdList {
-		// Invoked during go list to compute and record staleness.
-		if p := a.Package; p != nil && !p.Stale {
-			p.Stale = true
-			if cfg.BuildA {
-				p.StaleReason = "build -a flag in use"
-			} else {
-				p.StaleReason = "build ID mismatch"
-				for _, p1 := range p.Internal.Imports {
-					if p1.Stale && p1.StaleReason != "" {
-						if strings.HasPrefix(p1.StaleReason, "stale dependency: ") {
-							p.StaleReason = p1.StaleReason
-							break
-						}
-						if strings.HasPrefix(p.StaleReason, "build ID mismatch") {
-							p.StaleReason = "stale dependency: " + p1.ImportPath
-						}
-					}
-				}
-			}
-		}
-
-		// Fall through to update a.buildID from the build artifact cache,
-		// which will affect the computation of buildIDs for targets
-		// higher up in the dependency graph.
-	}
-
-	// Check the build artifact cache.
-	// We treat hits in this cache as being "stale" for the purposes of go list
-	// (in effect, "stale" means whether p.Target is up-to-date),
-	// but we're still happy to use results from the build artifact cache.
+	// Check to see if the action output is cached.
 	if c := cache.Default(); c != nil {
-		if !cfg.BuildA {
-			if file, _, err := c.GetFile(actionHash); err == nil {
-				if buildID, err := buildid.ReadFile(file); err == nil {
-					if err := showStdout(b, c, a.actionID, "stdout"); err == nil {
-						a.built = file
-						a.Target = "DO NOT USE - using cache"
-						a.buildID = buildID
-						if a.json != nil {
-							a.json.BuildID = a.buildID
-						}
-						if p := a.Package; p != nil {
-							// Clearer than explaining that something else is stale.
-							p.StaleReason = "not installed but available in build cache"
-						}
-						return true
+		if file, _, err := c.GetFile(actionHash); err == nil {
+			if buildID, err := buildid.ReadFile(file); err == nil {
+				if printOutput {
+					showStdout(b, c, a.actionID, "stdout")
+				}
+				a.built = file
+				a.Target = "DO NOT USE - using cache"
+				a.buildID = buildID
+				if a.json != nil {
+					a.json.BuildID = a.buildID
+				}
+				if p := a.Package; p != nil && target != "" {
+					p.Stale = true
+					// Clearer than explaining that something else is stale.
+					p.StaleReason = "not installed but available in build cache"
+				}
+				return true
+			}
+		}
+	}
+
+	// If we've reached this point, we can't use the cache for the action.
+	if p := a.Package; p != nil && !p.Stale {
+		p.Stale = true
+		p.StaleReason = "build ID mismatch"
+		if b.IsCmdList {
+			// Since we may end up printing StaleReason, include more detail.
+			for _, p1 := range p.Internal.Imports {
+				if p1.Stale && p1.StaleReason != "" {
+					if strings.HasPrefix(p1.StaleReason, "stale dependency: ") {
+						p.StaleReason = p1.StaleReason
+						break
+					}
+					if strings.HasPrefix(p.StaleReason, "build ID mismatch") {
+						p.StaleReason = "stale dependency: " + p1.ImportPath
 					}
 				}
 			}
 		}
-
-		// Begin saving output for later writing to cache.
-		a.output = []byte{}
 	}
 
+	// Begin saving output for later writing to cache.
+	a.output = []byte{}
 	return false
 }
 
diff --git a/src/cmd/go/internal/work/exec.go b/src/cmd/go/internal/work/exec.go
index c88b315..d6fa847 100644
--- a/src/cmd/go/internal/work/exec.go
+++ b/src/cmd/go/internal/work/exec.go
@@ -9,9 +9,11 @@
 import (
 	"bytes"
 	"context"
+	"crypto/sha256"
 	"encoding/json"
 	"errors"
 	"fmt"
+	"internal/coverage"
 	"internal/lazyregexp"
 	"io"
 	"io/fs"
@@ -40,6 +42,8 @@
 	"cmd/internal/sys"
 )
 
+const defaultCFlags = "-O2 -g"
+
 // actionList returns the list of actions in the dag rooted at root
 // as visited in a depth-first post-order traversal.
 func actionList(root *Action) []*Action {
@@ -125,7 +129,7 @@
 			a.json.TimeStart = time.Now()
 		}
 		var err error
-		if a.Func != nil && (!a.Failed || a.IgnoreFail) {
+		if a.Actor != nil && (!a.Failed || a.IgnoreFail) {
 			// TODO(matloob): Better action descriptions
 			desc := "Executing action "
 			if a.Package != nil {
@@ -136,7 +140,7 @@
 			for _, d := range a.Deps {
 				trace.Flow(ctx, d.traceSpan, a.traceSpan)
 			}
-			err = a.Func(b, ctx, a)
+			err = a.Actor.Act(b, ctx, a)
 			span.Done()
 		}
 		if a.json != nil {
@@ -149,9 +153,15 @@
 		defer b.exec.Unlock()
 
 		if err != nil {
-			if err == errPrintedOutput {
-				base.SetExitStatus(2)
+			if b.AllowErrors && a.Package != nil {
+				if a.Package.Error == nil {
+					a.Package.Error = &load.PackageError{Err: err}
+				}
 			} else {
+				var ipe load.ImportPathError
+				if a.Package != nil && (!errors.As(err, &ipe) || ipe.ImportPath() != a.Package.ImportPath) {
+					err = fmt.Errorf("%s: %v", a.Package.ImportPath, err)
+				}
 				base.Errorf("%s", err)
 			}
 			a.Failed = true
@@ -272,25 +282,20 @@
 		fmt.Fprintf(h, "CC=%q %q %q %q\n", ccExe, cppflags, cflags, ldflags)
 		// Include the C compiler tool ID so that if the C
 		// compiler changes we rebuild the package.
-		// But don't do that for standard library packages like net,
-		// so that the prebuilt .a files from a Go binary install
-		// don't need to be rebuilt with the local compiler.
-		if !p.Standard {
-			if ccID, err := b.gccToolID(ccExe[0], "c"); err == nil {
-				fmt.Fprintf(h, "CC ID=%q\n", ccID)
-			}
+		if ccID, _, err := b.gccToolID(ccExe[0], "c"); err == nil {
+			fmt.Fprintf(h, "CC ID=%q\n", ccID)
 		}
 		if len(p.CXXFiles)+len(p.SwigCXXFiles) > 0 {
 			cxxExe := b.cxxExe()
 			fmt.Fprintf(h, "CXX=%q %q\n", cxxExe, cxxflags)
-			if cxxID, err := b.gccToolID(cxxExe[0], "c++"); err == nil {
+			if cxxID, _, err := b.gccToolID(cxxExe[0], "c++"); err == nil {
 				fmt.Fprintf(h, "CXX ID=%q\n", cxxID)
 			}
 		}
 		if len(p.FFiles) > 0 {
 			fcExe := b.fcExe()
 			fmt.Fprintf(h, "FC=%q %q\n", fcExe, fflags)
-			if fcID, err := b.gccToolID(fcExe[0], "f95"); err == nil {
+			if fcID, _, err := b.gccToolID(fcExe[0], "f95"); err == nil {
 				fmt.Fprintf(h, "FC ID=%q\n", fcID)
 			}
 		}
@@ -335,33 +340,16 @@
 			"GOCLOBBERDEADHASH",
 			"GOSSAFUNC",
 			"GOSSADIR",
-			"GOSSAHASH",
+			"GOCOMPILEDEBUG",
 		}
 		for _, env := range magic {
 			if x := os.Getenv(env); x != "" {
 				fmt.Fprintf(h, "magic %s=%s\n", env, x)
 			}
 		}
-		if os.Getenv("GOSSAHASH") != "" {
-			for i := 0; ; i++ {
-				env := fmt.Sprintf("GOSSAHASH%d", i)
-				x := os.Getenv(env)
-				if x == "" {
-					break
-				}
-				fmt.Fprintf(h, "magic %s=%s\n", env, x)
-			}
-		}
-		if os.Getenv("GSHS_LOGFILE") != "" {
-			// Clumsy hack. Compiler writes to this log file,
-			// so do not allow use of cache at all.
-			// We will still write to the cache but it will be
-			// essentially unfindable.
-			fmt.Fprintf(h, "nocache %d\n", time.Now().UnixNano())
-		}
 
 	case "gccgo":
-		id, err := b.gccToolID(BuildToolchain.compiler(), "go")
+		id, _, err := b.gccToolID(BuildToolchain.compiler(), "go")
 		if err != nil {
 			base.Fatalf("%v", err)
 		}
@@ -369,7 +357,7 @@
 		fmt.Fprintf(h, "pkgpath %s\n", gccgoPkgpath(p))
 		fmt.Fprintf(h, "ar %q\n", BuildToolchain.(gccgoToolchain).ar())
 		if len(p.SFiles) > 0 {
-			id, _ = b.gccToolID(BuildToolchain.compiler(), "assembler-with-cpp")
+			id, _, _ = b.gccToolID(BuildToolchain.compiler(), "assembler-with-cpp")
 			// Ignore error; different assembler versions
 			// are unlikely to make any difference anyhow.
 			fmt.Fprintf(h, "asm %q\n", id)
@@ -394,6 +382,9 @@
 	for _, file := range inputFiles {
 		fmt.Fprintf(h, "file %s %s\n", file, b.fileHash(filepath.Join(p.Dir, file)))
 	}
+	if cfg.BuildPGOFile != "" {
+		fmt.Fprintf(h, "pgofile %s\n", b.fileHash(cfg.BuildPGOFile))
+	}
 	for _, a1 := range a.Deps {
 		p1 := a1.Package
 		if p1 != nil {
@@ -473,7 +464,7 @@
 		bit(needCompiledGoFiles, b.NeedCompiledGoFiles)
 
 	if !p.BinaryOnly {
-		if b.useCache(a, b.buildActionID(a), p.Target) {
+		if b.useCache(a, b.buildActionID(a), p.Target, need&needBuild != 0) {
 			// We found the main output in the cache.
 			// If we don't need any other outputs, we can stop.
 			// Otherwise, we need to write files to a.Objdir (needVet, needCgoHdr).
@@ -487,7 +478,7 @@
 				p.BuildID = a.buildID
 			}
 			if need&needCompiledGoFiles != 0 {
-				if err := b.loadCachedSrcFiles(a); err == nil {
+				if err := b.loadCachedCompiledGoFiles(a); err == nil {
 					need &^= needCompiledGoFiles
 				}
 			}
@@ -496,7 +487,7 @@
 		// Source files might be cached, even if the full action is not
 		// (e.g., go list -compiled -find).
 		if !cachedBuild && need&needCompiledGoFiles != 0 {
-			if err := b.loadCachedSrcFiles(a); err == nil {
+			if err := b.loadCachedCompiledGoFiles(a); err == nil {
 				need &^= needCompiledGoFiles
 			}
 		}
@@ -508,9 +499,6 @@
 	}
 
 	defer func() {
-		if err != nil && err != errPrintedOutput {
-			err = fmt.Errorf("go build %s: %v", a.Package.ImportPath, err)
-		}
 		if err != nil && b.IsCmdList && b.NeedError && p.Error == nil {
 			p.Error = &load.PackageError{Err: err}
 		}
@@ -521,14 +509,14 @@
 		// different sections of the bootstrap script have to
 		// be merged, the banners give patch something
 		// to use to find its context.
-		b.Print("\n#\n# " + a.Package.ImportPath + "\n#\n\n")
+		b.Print("\n#\n# " + p.ImportPath + "\n#\n\n")
 	}
 
 	if cfg.BuildV {
-		b.Print(a.Package.ImportPath + "\n")
+		b.Print(p.ImportPath + "\n")
 	}
 
-	if a.Package.BinaryOnly {
+	if p.BinaryOnly {
 		p.Stale = true
 		p.StaleReason = "binary-only packages are no longer supported"
 		if b.IsCmdList {
@@ -574,15 +562,15 @@
 		}
 	}
 
-	gofiles := str.StringList(a.Package.GoFiles)
-	cgofiles := str.StringList(a.Package.CgoFiles)
-	cfiles := str.StringList(a.Package.CFiles)
-	sfiles := str.StringList(a.Package.SFiles)
-	cxxfiles := str.StringList(a.Package.CXXFiles)
+	gofiles := str.StringList(p.GoFiles)
+	cgofiles := str.StringList(p.CgoFiles)
+	cfiles := str.StringList(p.CFiles)
+	sfiles := str.StringList(p.SFiles)
+	cxxfiles := str.StringList(p.CXXFiles)
 	var objects, cgoObjects, pcCFLAGS, pcLDFLAGS []string
 
-	if a.Package.UsesCgo() || a.Package.UsesSwig() {
-		if pcCFLAGS, pcLDFLAGS, err = b.getPkgConfigFlags(a.Package); err != nil {
+	if p.UsesCgo() || p.UsesSwig() {
+		if pcCFLAGS, pcLDFLAGS, err = b.getPkgConfigFlags(p); err != nil {
 			return
 		}
 	}
@@ -591,7 +579,7 @@
 	// put correct contents of all those files in the objdir, to ensure
 	// the correct headers are included. nonGoOverlay is the overlay that
 	// points from nongo files to the copied files in objdir.
-	nonGoFileLists := [][]string{a.Package.CFiles, a.Package.SFiles, a.Package.CXXFiles, a.Package.HFiles, a.Package.FFiles}
+	nonGoFileLists := [][]string{p.CFiles, p.SFiles, p.CXXFiles, p.HFiles, p.FFiles}
 OverlayLoop:
 	for _, fs := range nonGoFileLists {
 		for _, f := range fs {
@@ -618,8 +606,8 @@
 	// Run SWIG on each .swig and .swigcxx file.
 	// Each run will generate two files, a .go file and a .c or .cxx file.
 	// The .go file will use import "C" and is to be processed by cgo.
-	if a.Package.UsesSwig() {
-		outGo, outC, outCXX, err := b.swig(a, a.Package, objdir, pcCFLAGS)
+	if p.UsesSwig() {
+		outGo, outC, outCXX, err := b.swig(a, p, objdir, pcCFLAGS)
 		if err != nil {
 			return err
 		}
@@ -629,30 +617,40 @@
 	}
 
 	// If we're doing coverage, preprocess the .go files and put them in the work directory
-	if a.Package.Internal.CoverMode != "" {
+	if p.Internal.CoverMode != "" {
+		outfiles := []string{}
+		infiles := []string{}
 		for i, file := range str.StringList(gofiles, cgofiles) {
+			if base.IsTestFile(file) {
+				continue // Not covering this file.
+			}
+
 			var sourceFile string
 			var coverFile string
 			var key string
-			if strings.HasSuffix(file, ".cgo1.go") {
+			if base, found := strings.CutSuffix(file, ".cgo1.go"); found {
 				// cgo files have absolute paths
-				base := filepath.Base(file)
+				base = filepath.Base(base)
 				sourceFile = file
-				coverFile = objdir + base
-				key = strings.TrimSuffix(base, ".cgo1.go") + ".go"
+				coverFile = objdir + base + ".cgo1.go"
+				key = base + ".go"
 			} else {
-				sourceFile = filepath.Join(a.Package.Dir, file)
+				sourceFile = filepath.Join(p.Dir, file)
 				coverFile = objdir + file
 				key = file
 			}
 			coverFile = strings.TrimSuffix(coverFile, ".go") + ".cover.go"
-			cover := a.Package.Internal.CoverVars[key]
-			if cover == nil || base.IsTestFile(file) {
-				// Not covering this file.
-				continue
-			}
-			if err := b.cover(a, coverFile, sourceFile, cover.Var); err != nil {
-				return err
+			if cfg.Experiment.CoverageRedesign {
+				infiles = append(infiles, sourceFile)
+				outfiles = append(outfiles, coverFile)
+			} else {
+				cover := p.Internal.CoverVars[key]
+				if cover == nil {
+					continue // Not covering this file.
+				}
+				if err := b.cover(a, coverFile, sourceFile, cover.Var); err != nil {
+					return err
+				}
 			}
 			if i < len(gofiles) {
 				gofiles[i] = coverFile
@@ -660,10 +658,42 @@
 				cgofiles[i-len(gofiles)] = coverFile
 			}
 		}
+
+		if cfg.Experiment.CoverageRedesign {
+			if len(infiles) != 0 {
+				// Coverage instrumentation creates new top level
+				// variables in the target package for things like
+				// meta-data containers, counter vars, etc. To avoid
+				// collisions with user variables, suffix the var name
+				// with 12 hex digits from the SHA-256 hash of the
+				// import path. Choice of 12 digits is historical/arbitrary,
+				// we just need enough of the hash to avoid accidents,
+				// as opposed to precluding determined attempts by
+				// users to break things.
+				sum := sha256.Sum256([]byte(a.Package.ImportPath))
+				coverVar := fmt.Sprintf("goCover_%x_", sum[:6])
+				mode := a.Package.Internal.CoverMode
+				if mode == "" {
+					panic("covermode should be set at this point")
+				}
+				pkgcfg := a.Objdir + "pkgcfg.txt"
+				covoutfiles := a.Objdir + "coveroutfiles.txt"
+				if err := b.cover2(a, pkgcfg, covoutfiles, infiles, outfiles, coverVar, mode); err != nil {
+					return err
+				}
+			} else {
+				// If there are no input files passed to cmd/cover,
+				// then we don't want to pass -covercfg when building
+				// the package with the compiler, so set covermode to
+				// the empty string so as to signal that we need to do
+				// that.
+				p.Internal.CoverMode = ""
+			}
+		}
 	}
 
 	// Run cgo.
-	if a.Package.UsesCgo() || a.Package.UsesSwig() {
+	if p.UsesCgo() || p.UsesSwig() {
 		// In a package using cgo, cgo compiles the C, C++ and assembly files with gcc.
 		// There is one exception: runtime/cgo's job is to bridge the
 		// cgo and non-cgo worlds, so it necessarily has files in both.
@@ -671,7 +701,7 @@
 		var gccfiles []string
 		gccfiles = append(gccfiles, cfiles...)
 		cfiles = nil
-		if a.Package.Standard && a.Package.ImportPath == "runtime/cgo" {
+		if p.Standard && p.ImportPath == "runtime/cgo" {
 			filter := func(files, nongcc, gcc []string) ([]string, []string) {
 				for _, f := range files {
 					if strings.HasPrefix(f, "gcc_") {
@@ -685,7 +715,7 @@
 			sfiles, gccfiles = filter(sfiles, sfiles[:0], gccfiles)
 		} else {
 			for _, sfile := range sfiles {
-				data, err := os.ReadFile(filepath.Join(a.Package.Dir, sfile))
+				data, err := os.ReadFile(filepath.Join(p.Dir, sfile))
 				if err == nil {
 					if bytes.HasPrefix(data, []byte("TEXT")) || bytes.Contains(data, []byte("\nTEXT")) ||
 						bytes.HasPrefix(data, []byte("DATA")) || bytes.Contains(data, []byte("\nDATA")) ||
@@ -698,7 +728,7 @@
 			sfiles = nil
 		}
 
-		outGo, outObj, err := b.cgo(a, base.Tool("cgo"), objdir, pcCFLAGS, pcLDFLAGS, mkAbsFiles(a.Package.Dir, cgofiles), gccfiles, cxxfiles, a.Package.MFiles, a.Package.FFiles)
+		outGo, outObj, err := b.cgo(a, base.Tool("cgo"), objdir, pcCFLAGS, pcLDFLAGS, mkAbsFiles(p.Dir, cgofiles), gccfiles, cxxfiles, p.MFiles, p.FFiles)
 
 		// The files in cxxfiles have now been handled by b.cgo.
 		cxxfiles = nil
@@ -730,7 +760,7 @@
 
 	// Sanity check only, since Package.load already checked as well.
 	if len(gofiles) == 0 {
-		return &load.NoGoError{Package: a.Package}
+		return &load.NoGoError{Package: p}
 	}
 
 	// Prepare Go vet config if needed.
@@ -739,7 +769,7 @@
 		need &^= needVet
 	}
 	if need&needCompiledGoFiles != 0 {
-		if err := b.loadCachedSrcFiles(a); err != nil {
+		if err := b.loadCachedCompiledGoFiles(a); err != nil {
 			return fmt.Errorf("loading compiled Go files from cache: %w", err)
 		}
 		need &^= needCompiledGoFiles
@@ -763,8 +793,8 @@
 	// except when it doesn't.
 	var icfg bytes.Buffer
 	fmt.Fprintf(&icfg, "# import config\n")
-	for i, raw := range a.Package.Internal.RawImports {
-		final := a.Package.Imports[i]
+	for i, raw := range p.Internal.RawImports {
+		final := p.Imports[i]
 		if final != raw {
 			fmt.Fprintf(&icfg, "importmap %s=%s\n", raw, final)
 		}
@@ -815,14 +845,16 @@
 		if p.Module != nil && !allowedVersion(p.Module.GoVersion) {
 			output += "note: module requires Go " + p.Module.GoVersion + "\n"
 		}
-		b.showOutput(a, a.Package.Dir, a.Package.Desc(), output)
+
 		if err != nil {
-			return errPrintedOutput
+			return formatOutput(b.WorkDir, p.Dir, p.ImportPath, p.Desc(), output)
+		} else {
+			b.showOutput(a, p.Dir, p.Desc(), output)
 		}
 	}
 	if err != nil {
 		if p.Module != nil && !allowedVersion(p.Module.GoVersion) {
-			b.showOutput(a, a.Package.Dir, a.Package.Desc(), "note: module requires Go "+p.Module.GoVersion+"\n")
+			b.showOutput(a, p.Dir, p.Desc(), "note: module requires Go "+p.Module.GoVersion+"\n")
 		}
 		return err
 	}
@@ -836,22 +868,22 @@
 	_goos_goarch := "_" + cfg.Goos + "_" + cfg.Goarch
 	_goos := "_" + cfg.Goos
 	_goarch := "_" + cfg.Goarch
-	for _, file := range a.Package.HFiles {
+	for _, file := range p.HFiles {
 		name, ext := fileExtSplit(file)
 		switch {
 		case strings.HasSuffix(name, _goos_goarch):
 			targ := file[:len(name)-len(_goos_goarch)] + "_GOOS_GOARCH." + ext
-			if err := b.copyFile(objdir+targ, filepath.Join(a.Package.Dir, file), 0666, true); err != nil {
+			if err := b.copyFile(objdir+targ, filepath.Join(p.Dir, file), 0666, true); err != nil {
 				return err
 			}
 		case strings.HasSuffix(name, _goarch):
 			targ := file[:len(name)-len(_goarch)] + "_GOARCH." + ext
-			if err := b.copyFile(objdir+targ, filepath.Join(a.Package.Dir, file), 0666, true); err != nil {
+			if err := b.copyFile(objdir+targ, filepath.Join(p.Dir, file), 0666, true); err != nil {
 				return err
 			}
 		case strings.HasSuffix(name, _goos):
 			targ := file[:len(name)-len(_goos)] + "_GOOS." + ext
-			if err := b.copyFile(objdir+targ, filepath.Join(a.Package.Dir, file), 0666, true); err != nil {
+			if err := b.copyFile(objdir+targ, filepath.Join(p.Dir, file), 0666, true); err != nil {
 				return err
 			}
 		}
@@ -899,8 +931,8 @@
 	objects = append(objects, cgoObjects...)
 
 	// Add system object files.
-	for _, syso := range a.Package.SysoFiles {
-		objects = append(objects, filepath.Join(a.Package.Dir, syso))
+	for _, syso := range p.SysoFiles {
+		objects = append(objects, filepath.Join(p.Dir, syso))
 	}
 
 	// Pack into archive in objdir directory.
@@ -1003,28 +1035,30 @@
 	return nil
 }
 
-func (b *Builder) loadCachedSrcFiles(a *Action) error {
+func (b *Builder) loadCachedCompiledGoFiles(a *Action) error {
 	c := cache.Default()
 	list, _, err := c.GetBytes(cache.Subkey(a.actionID, "srcfiles"))
 	if err != nil {
 		return fmt.Errorf("reading srcfiles list: %w", err)
 	}
-	var files []string
+	var gofiles []string
 	for _, name := range strings.Split(string(list), "\n") {
 		if name == "" { // end of list
 			continue
+		} else if !strings.HasSuffix(name, ".go") {
+			continue
 		}
 		if strings.HasPrefix(name, "./") {
-			files = append(files, name[len("./"):])
+			gofiles = append(gofiles, name[len("./"):])
 			continue
 		}
 		file, err := b.findCachedObjdirFile(a, c, name)
 		if err != nil {
 			return fmt.Errorf("finding %s: %w", name, err)
 		}
-		files = append(files, file)
+		gofiles = append(gofiles, file)
 	}
-	a.Package.CompiledGoFiles = files
+	a.Package.CompiledGoFiles = gofiles
 	return nil
 }
 
@@ -1322,7 +1356,7 @@
 		// Or external linker settings and flags?
 
 	case "gccgo":
-		id, err := b.gccToolID(BuildToolchain.linker(), "go")
+		id, _, err := b.gccToolID(BuildToolchain.linker(), "go")
 		if err != nil {
 			base.Fatalf("%v", err)
 		}
@@ -1334,7 +1368,7 @@
 // link is the action for linking a single command.
 // Note that any new influence on this logic must be reported in b.linkActionID above as well.
 func (b *Builder) link(ctx context.Context, a *Action) (err error) {
-	if b.useCache(a, b.linkActionID(a), a.Package.Target) || b.IsCmdList {
+	if b.useCache(a, b.linkActionID(a), a.Package.Target, !b.IsCmdList) || b.IsCmdList {
 		return nil
 	}
 	defer b.flushOutput(a)
@@ -1496,9 +1530,8 @@
 		var out []byte
 		out, err = b.runOut(nil, p.Dir, nil, b.PkgconfigCmd(), "--cflags", pcflags, "--", pkgs)
 		if err != nil {
-			b.showOutput(nil, p.Dir, b.PkgconfigCmd()+" --cflags "+strings.Join(pcflags, " ")+" -- "+strings.Join(pkgs, " "), string(out))
-			b.Print(err.Error() + "\n")
-			return nil, nil, errPrintedOutput
+			err = formatOutput(b.WorkDir, p.Dir, p.ImportPath, b.PkgconfigCmd()+" --cflags "+strings.Join(pcflags, " ")+" -- "+strings.Join(pkgs, " "), string(out)+err.Error())
+			return nil, nil, err
 		}
 		if len(out) > 0 {
 			cflags, err = splitPkgConfigOutput(out)
@@ -1511,9 +1544,8 @@
 		}
 		out, err = b.runOut(nil, p.Dir, nil, b.PkgconfigCmd(), "--libs", pcflags, "--", pkgs)
 		if err != nil {
-			b.showOutput(nil, p.Dir, b.PkgconfigCmd()+" --libs "+strings.Join(pcflags, " ")+" -- "+strings.Join(pkgs, " "), string(out))
-			b.Print(err.Error() + "\n")
-			return nil, nil, errPrintedOutput
+			err = formatOutput(b.WorkDir, p.Dir, p.ImportPath, b.PkgconfigCmd()+" --libs "+strings.Join(pcflags, " ")+" -- "+strings.Join(pkgs, " "), string(out)+err.Error())
+			return nil, nil, err
 		}
 		if len(out) > 0 {
 			// NOTE: we don't attempt to parse quotes and unescapes here. pkg-config
@@ -1535,6 +1567,9 @@
 
 	// TODO: BuildN
 	a1 := a.Deps[0]
+	if err := b.Mkdir(filepath.Dir(a.Target)); err != nil {
+		return err
+	}
 	err := os.WriteFile(a.Target, []byte(filepath.Base(a1.Target)+"\n"), 0666)
 	if err != nil {
 		return err
@@ -1578,7 +1613,7 @@
 }
 
 func (b *Builder) linkShared(ctx context.Context, a *Action) (err error) {
-	if b.useCache(a, b.linkSharedActionID(a), a.Target) || b.IsCmdList {
+	if b.useCache(a, b.linkSharedActionID(a), a.Target, !b.IsCmdList) || b.IsCmdList {
 		return nil
 	}
 	defer b.flushOutput(a)
@@ -1605,7 +1640,7 @@
 // BuildInstallFunc is the action for installing a single package or executable.
 func BuildInstallFunc(b *Builder, ctx context.Context, a *Action) (err error) {
 	defer func() {
-		if err != nil && err != errPrintedOutput {
+		if err != nil {
 			// a.Package == nil is possible for the go install -buildmode=shared
 			// action that installs libmangledname.so, which corresponds to
 			// a list of packages, not just one.
@@ -1813,7 +1848,7 @@
 	}
 
 	// On Windows, remove lingering ~ file from last attempt.
-	if base.ToolIsWindows {
+	if runtime.GOOS == "windows" {
 		if _, err := os.Stat(dst + "~"); err == nil {
 			os.Remove(dst + "~")
 		}
@@ -1821,7 +1856,7 @@
 
 	mayberemovefile(dst)
 	df, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
-	if err != nil && base.ToolIsWindows {
+	if err != nil && runtime.GOOS == "windows" {
 		// Windows does not allow deletion of a binary file
 		// while it is executing. Try to move it out of the way.
 		// If the move fails, which is likely, we'll try again the
@@ -1897,6 +1932,55 @@
 		src)
 }
 
+// cover2 runs, in effect,
+//
+//	go tool cover -pkgcfg=<config file> -mode=b.coverMode -var="varName" -o <outfiles> <infiles>
+func (b *Builder) cover2(a *Action, pkgcfg, covoutputs string, infiles, outfiles []string, varName string, mode string) error {
+	if err := b.writeCoverPkgInputs(a, pkgcfg, covoutputs, outfiles); err != nil {
+		return err
+	}
+	args := []string{base.Tool("cover"),
+		"-pkgcfg", pkgcfg,
+		"-mode", mode,
+		"-var", varName,
+		"-outfilelist", covoutputs,
+	}
+	args = append(args, infiles...)
+	return b.run(a, a.Objdir, "cover "+a.Package.ImportPath, nil,
+		cfg.BuildToolexec, args)
+}
+
+func (b *Builder) writeCoverPkgInputs(a *Action, pconfigfile string, covoutputsfile string, outfiles []string) error {
+	p := a.Package
+	p.Internal.CoverageCfg = a.Objdir + "coveragecfg"
+	pcfg := coverage.CoverPkgConfig{
+		PkgPath: p.ImportPath,
+		PkgName: p.Name,
+		// Note: coverage granularity is currently hard-wired to
+		// 'perblock'; there isn't a way using "go build -cover" or "go
+		// test -cover" to select it. This may change in the future
+		// depending on user demand.
+		Granularity: "perblock",
+		OutConfig:   p.Internal.CoverageCfg,
+		Local:       p.Internal.Local,
+	}
+	if a.Package.Module != nil {
+		pcfg.ModulePath = a.Package.Module.Path
+	}
+	data, err := json.Marshal(pcfg)
+	if err != nil {
+		return err
+	}
+	if err := b.writeFile(pconfigfile, data); err != nil {
+		return err
+	}
+	var sb strings.Builder
+	for i := range outfiles {
+		fmt.Fprintf(&sb, "%s\n", outfiles[i])
+	}
+	return b.writeFile(covoutputsfile, []byte(sb.String()))
+}
+
 var objectMagic = [][]byte{
 	{'!', '<', 'a', 'r', 'c', 'h', '>', '\n'}, // Package archive
 	{'<', 'b', 'i', 'g', 'a', 'f', '>', '\n'}, // Package AIX big archive
@@ -1965,7 +2049,7 @@
 			cmd = "cd " + dir + "\n" + cmd
 		}
 	}
-	if b.WorkDir != "" {
+	if b.WorkDir != "" && !strings.HasPrefix(cmd, "cat ") {
 		cmd = strings.ReplaceAll(cmd, b.WorkDir, "$WORK")
 		escaped := strconv.Quote(b.WorkDir)
 		escaped = escaped[1 : len(escaped)-1] // strip quote characters
@@ -2009,6 +2093,63 @@
 // If a is not nil and a.output is not nil, showOutput appends to that slice instead of
 // printing to b.Print.
 func (b *Builder) showOutput(a *Action, dir, desc, out string) {
+	importPath := ""
+	if a != nil && a.Package != nil {
+		importPath = a.Package.ImportPath
+	}
+	psErr := formatOutput(b.WorkDir, dir, importPath, desc, out)
+	if a != nil && a.output != nil {
+		a.output = append(a.output, psErr.prefix...)
+		a.output = append(a.output, psErr.suffix...)
+		return
+	}
+
+	b.output.Lock()
+	defer b.output.Unlock()
+	b.Print(psErr.prefix, psErr.suffix)
+}
+
+// A prefixSuffixError is an error formatted by formatOutput.
+type prefixSuffixError struct {
+	importPath     string
+	prefix, suffix string
+}
+
+func (e *prefixSuffixError) Error() string {
+	if e.importPath != "" && !strings.HasPrefix(strings.TrimPrefix(e.prefix, "# "), e.importPath) {
+		return fmt.Sprintf("go build %s:\n%s%s", e.importPath, e.prefix, e.suffix)
+	}
+	return e.prefix + e.suffix
+}
+
+func (e *prefixSuffixError) ImportPath() string {
+	return e.importPath
+}
+
+// formatOutput prints "# desc" followed by the given output.
+// The output is expected to contain references to 'dir', usually
+// the source directory for the package that has failed to build.
+// formatOutput rewrites mentions of dir with a relative path to dir
+// when the relative path is shorter. This is usually more pleasant.
+// For example, if fmt doesn't compile and we are in src/html,
+// the output is
+//
+//	$ go build
+//	# fmt
+//	../fmt/print.go:1090: undefined: asdf
+//	$
+//
+// instead of
+//
+//	$ go build
+//	# fmt
+//	/usr/gopher/go/src/fmt/print.go:1090: undefined: asdf
+//	$
+//
+// formatOutput also replaces references to the work directory with $WORK.
+// formatOutput returns the output in a prefix with the description and a
+// suffix with the actual output.
+func formatOutput(workDir, dir, importPath, desc, out string) *prefixSuffixError {
 	prefix := "# " + desc
 	suffix := "\n" + out
 	if reldir := base.ShortPath(dir); reldir != dir {
@@ -2016,26 +2157,11 @@
 		suffix = strings.ReplaceAll(suffix, "\n"+dir, "\n"+reldir)
 		suffix = strings.ReplaceAll(suffix, "\n\t"+dir, "\n\t"+reldir)
 	}
-	suffix = strings.ReplaceAll(suffix, " "+b.WorkDir, " $WORK")
+	suffix = strings.ReplaceAll(suffix, " "+workDir, " $WORK")
 
-	if a != nil && a.output != nil {
-		a.output = append(a.output, prefix...)
-		a.output = append(a.output, suffix...)
-		return
-	}
-
-	b.output.Lock()
-	defer b.output.Unlock()
-	b.Print(prefix, suffix)
+	return &prefixSuffixError{importPath: importPath, prefix: prefix, suffix: suffix}
 }
 
-// errPrintedOutput is a special error indicating that a command failed
-// but that it generated output as well, and that output has already
-// been printed, so there's no point showing 'exit status 1' or whatever
-// the wait status was. The main executor, builder.do, knows not to
-// print this error.
-var errPrintedOutput = errors.New("already printed output - no need to show error")
-
 var cgoLine = lazyregexp.New(`\[[^\[\]]+\.(cgo1|cover)\.go:[0-9]+(:[0-9]+)?\]`)
 var cgoTypeSigRe = lazyregexp.New(`\b_C2?(type|func|var|macro)_\B`)
 
@@ -2048,9 +2174,10 @@
 		if desc == "" {
 			desc = b.fmtcmd(dir, "%s", strings.Join(str.StringList(cmdargs...), " "))
 		}
-		b.showOutput(a, dir, desc, b.processOutput(out))
 		if err != nil {
-			err = errPrintedOutput
+			err = formatOutput(b.WorkDir, dir, a.Package.ImportPath, desc, b.processOutput(out))
+		} else {
+			b.showOutput(a, dir, desc, b.processOutput(out))
 		}
 	}
 	return err
@@ -2159,7 +2286,7 @@
 // output unambiguous.
 // TODO: See issue 5279. The printing of commands needs a complete redo.
 func joinUnambiguously(a []string) string {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	for i, s := range a {
 		if i > 0 {
 			buf.WriteByte(' ')
@@ -2334,7 +2461,6 @@
 // ccompile runs the given C or C++ compiler and creates an object from a single source file.
 func (b *Builder) ccompile(a *Action, p *load.Package, outfile string, flags []string, file string, compiler []string) error {
 	file = mkAbs(p.Dir, file)
-	desc := p.ImportPath
 	outfile = mkAbs(p.Dir, outfile)
 
 	// Elide source directory paths if -trimpath or GOROOT_FINAL is set.
@@ -2394,11 +2520,10 @@
 			}
 		}
 
-		b.showOutput(a, p.Dir, desc, b.processOutput(output))
-		if err != nil {
-			err = errPrintedOutput
-		} else if os.Getenv("GO_BUILDER_NAME") != "" {
-			return errors.New("C compiler warning promoted to error on Go builders")
+		if err != nil || os.Getenv("GO_BUILDER_NAME") != "" {
+			err = formatOutput(b.WorkDir, p.Dir, p.ImportPath, p.Desc(), b.processOutput(output))
+		} else {
+			b.showOutput(a, p.Dir, p.Desc(), b.processOutput(output))
 		}
 	}
 	return err
@@ -2579,21 +2704,23 @@
 func (b *Builder) gccSupportsFlag(compiler []string, flag string) bool {
 	key := [2]string{compiler[0], flag}
 
-	b.exec.Lock()
-	defer b.exec.Unlock()
-	if b, ok := b.flagCache[key]; ok {
-		return b
-	}
-	if b.flagCache == nil {
-		b.flagCache = make(map[[2]string]bool)
-	}
-
-	tmp := os.DevNull
+	// We used to write an empty C file, but that gets complicated with go
+	// build -n. We tried using a file that does not exist, but that fails on
+	// systems with GCC version 4.2.1; that is the last GPLv2 version of GCC,
+	// so some systems have frozen on it. Now we pass an empty file on stdin,
+	// which should work at least for GCC and clang.
+	//
+	// If the argument is "-Wl,", then it is testing the linker. In that case,
+	// skip "-c". If it's not "-Wl,", then we are testing the compiler and can
+	// omit the linking step with "-c".
+	//
+	// Using the same CFLAGS/LDFLAGS here and for building the program.
 
 	// On the iOS builder the command
 	//   $CC -Wl,--no-gc-sections -x c - -o /dev/null < /dev/null
 	// is failing with:
 	//   Unable to remove existing file: Invalid argument
+	tmp := os.DevNull
 	if runtime.GOOS == "windows" || runtime.GOOS == "ios" {
 		f, err := os.CreateTemp(b.WorkDir, "")
 		if err != nil {
@@ -2604,26 +2731,54 @@
 		defer os.Remove(tmp)
 	}
 
-	// We used to write an empty C file, but that gets complicated with go
-	// build -n. We tried using a file that does not exist, but that fails on
-	// systems with GCC version 4.2.1; that is the last GPLv2 version of GCC,
-	// so some systems have frozen on it. Now we pass an empty file on stdin,
-	// which should work at least for GCC and clang.
-	//
-	// If the argument is "-Wl,", then it's testing the linker. In that case,
-	// skip "-c". If it's not "-Wl,", then we are testing the compiler and
-	// can emit the linking step with "-c".
 	cmdArgs := str.StringList(compiler, flag)
-	if !strings.HasPrefix(flag, "-Wl,") /* linker flag */ {
-		cmdArgs = append(cmdArgs, "-c")
-	}
-	cmdArgs = append(cmdArgs, "-x", "c", "-", "-o", tmp)
-
-	if cfg.BuildN || cfg.BuildX {
-		b.Showcmd(b.WorkDir, "%s || true", joinUnambiguously(cmdArgs))
-		if cfg.BuildN {
+	if strings.HasPrefix(flag, "-Wl,") /* linker flag */ {
+		ldflags, err := buildFlags("LDFLAGS", defaultCFlags, nil, checkLinkerFlags)
+		if err != nil {
 			return false
 		}
+		cmdArgs = append(cmdArgs, ldflags...)
+	} else { /* compiler flag, add "-c" */
+		cflags, err := buildFlags("CFLAGS", defaultCFlags, nil, checkCompilerFlags)
+		if err != nil {
+			return false
+		}
+		cmdArgs = append(cmdArgs, cflags...)
+		cmdArgs = append(cmdArgs, "-c")
+	}
+
+	cmdArgs = append(cmdArgs, "-x", "c", "-", "-o", tmp)
+
+	if cfg.BuildN {
+		b.Showcmd(b.WorkDir, "%s || true", joinUnambiguously(cmdArgs))
+		return false
+	}
+
+	// gccCompilerID acquires b.exec, so do before acquiring lock.
+	compilerID, cacheOK := b.gccCompilerID(compiler[0])
+
+	b.exec.Lock()
+	defer b.exec.Unlock()
+	if b, ok := b.flagCache[key]; ok {
+		return b
+	}
+	if b.flagCache == nil {
+		b.flagCache = make(map[[2]string]bool)
+	}
+
+	// Look in build cache.
+	var flagID cache.ActionID
+	if cacheOK {
+		flagID = cache.Subkey(compilerID, "gccSupportsFlag "+flag)
+		if data, _, err := cache.Default().GetBytes(flagID); err == nil {
+			supported := string(data) == "true"
+			b.flagCache[key] = supported
+			return supported
+		}
+	}
+
+	if cfg.BuildX {
+		b.Showcmd(b.WorkDir, "%s || true", joinUnambiguously(cmdArgs))
 	}
 	cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...)
 	cmd.Dir = b.WorkDir
@@ -2641,10 +2796,120 @@
 		!bytes.Contains(out, []byte("is not supported")) &&
 		!bytes.Contains(out, []byte("not recognized")) &&
 		!bytes.Contains(out, []byte("unsupported"))
+
+	if cacheOK {
+		s := "false"
+		if supported {
+			s = "true"
+		}
+		cache.Default().PutBytes(flagID, []byte(s))
+	}
+
 	b.flagCache[key] = supported
 	return supported
 }
 
+// statString returns a string form of an os.FileInfo, for serializing and comparison.
+func statString(info os.FileInfo) string {
+	return fmt.Sprintf("stat %d %x %v %v\n", info.Size(), uint64(info.Mode()), info.ModTime(), info.IsDir())
+}
+
+// gccCompilerID returns a build cache key for the current gcc,
+// as identified by running 'compiler'.
+// The caller can use subkeys of the key.
+// Other parts of cmd/go can use the id as a hash
+// of the installed compiler version.
+func (b *Builder) gccCompilerID(compiler string) (id cache.ActionID, ok bool) {
+	if cfg.BuildN {
+		b.Showcmd(b.WorkDir, "%s || true", joinUnambiguously([]string{compiler, "--version"}))
+		return cache.ActionID{}, false
+	}
+
+	b.exec.Lock()
+	defer b.exec.Unlock()
+
+	if id, ok := b.gccCompilerIDCache[compiler]; ok {
+		return id, ok
+	}
+
+	// We hash the compiler's full path to get a cache entry key.
+	// That cache entry holds a validation description,
+	// which is of the form:
+	//
+	//	filename \x00 statinfo \x00
+	//	...
+	//	compiler id
+	//
+	// If os.Stat of each filename matches statinfo,
+	// then the entry is still valid, and we can use the
+	// compiler id without any further expense.
+	//
+	// Otherwise, we compute a new validation description
+	// and compiler id (below).
+	exe, err := exec.LookPath(compiler)
+	if err != nil {
+		return cache.ActionID{}, false
+	}
+
+	h := cache.NewHash("gccCompilerID")
+	fmt.Fprintf(h, "gccCompilerID %q", exe)
+	key := h.Sum()
+	data, _, err := cache.Default().GetBytes(key)
+	if err == nil && len(data) > len(id) {
+		stats := strings.Split(string(data[:len(data)-len(id)]), "\x00")
+		if len(stats)%2 != 0 {
+			goto Miss
+		}
+		for i := 0; i+2 <= len(stats); i++ {
+			info, err := os.Stat(stats[i])
+			if err != nil || statString(info) != stats[i+1] {
+				goto Miss
+			}
+		}
+		copy(id[:], data[len(data)-len(id):])
+		return id, true
+	Miss:
+	}
+
+	// Validation failed. Compute a new description (in buf) and compiler ID (in h).
+	// For now, there are only at most two filenames in the stat information.
+	// The first one is the compiler executable we invoke.
+	// The second is the underlying compiler as reported by -v -###
+	// (see b.gccToolID implementation in buildid.go).
+	toolID, exe2, err := b.gccToolID(compiler, "c")
+	if err != nil {
+		return cache.ActionID{}, false
+	}
+
+	exes := []string{exe, exe2}
+	str.Uniq(&exes)
+	fmt.Fprintf(h, "gccCompilerID %q %q\n", exes, toolID)
+	id = h.Sum()
+
+	var buf bytes.Buffer
+	for _, exe := range exes {
+		if exe == "" {
+			continue
+		}
+		info, err := os.Stat(exe)
+		if err != nil {
+			return cache.ActionID{}, false
+		}
+		buf.WriteString(exe)
+		buf.WriteString("\x00")
+		buf.WriteString(statString(info))
+		buf.WriteString("\x00")
+	}
+	buf.Write(id[:])
+
+	cache.Default().PutBytes(key, buf.Bytes())
+	if b.gccCompilerIDCache == nil {
+		b.gccCompilerIDCache = make(map[string]cache.ActionID)
+	}
+	b.gccCompilerIDCache[compiler] = id
+	return id, true
+}
+
 // gccArchArgs returns arguments to pass to gcc based on the architecture.
 func (b *Builder) gccArchArgs() []string {
 	switch cfg.Goarch {
@@ -2691,7 +2956,7 @@
 // into fields, using the default value when the variable is empty.
 //
 // The environment variable must be quoted correctly for
-// str.SplitQuotedFields. This should be done before building
+// quoted.Split. This should be done before building
 // anything, for example, in BuildInit.
 func envList(key, def string) []string {
 	v := cfg.Getenv(key)
@@ -2707,21 +2972,19 @@
 
 // CFlags returns the flags to use when invoking the C, C++ or Fortran compilers, or cgo.
 func (b *Builder) CFlags(p *load.Package) (cppflags, cflags, cxxflags, fflags, ldflags []string, err error) {
-	defaults := "-g -O2"
-
 	if cppflags, err = buildFlags("CPPFLAGS", "", p.CgoCPPFLAGS, checkCompilerFlags); err != nil {
 		return
 	}
-	if cflags, err = buildFlags("CFLAGS", defaults, p.CgoCFLAGS, checkCompilerFlags); err != nil {
+	if cflags, err = buildFlags("CFLAGS", defaultCFlags, p.CgoCFLAGS, checkCompilerFlags); err != nil {
 		return
 	}
-	if cxxflags, err = buildFlags("CXXFLAGS", defaults, p.CgoCXXFLAGS, checkCompilerFlags); err != nil {
+	if cxxflags, err = buildFlags("CXXFLAGS", defaultCFlags, p.CgoCXXFLAGS, checkCompilerFlags); err != nil {
 		return
 	}
-	if fflags, err = buildFlags("FFLAGS", defaults, p.CgoFFLAGS, checkCompilerFlags); err != nil {
+	if fflags, err = buildFlags("FFLAGS", defaultCFlags, p.CgoFFLAGS, checkCompilerFlags); err != nil {
 		return
 	}
-	if ldflags, err = buildFlags("LDFLAGS", defaults, p.CgoLDFLAGS, checkLinkerFlags); err != nil {
+	if ldflags, err = buildFlags("LDFLAGS", defaultCFlags, p.CgoLDFLAGS, checkLinkerFlags); err != nil {
 		return
 	}
 
@@ -2821,6 +3084,9 @@
 		if pkgpath := gccgoPkgpath(p); pkgpath != "" {
 			cgoflags = append(cgoflags, "-gccgopkgpath="+pkgpath)
 		}
+		if !BuildToolchain.(gccgoToolchain).supportsCgoIncomplete(b) {
+			cgoflags = append(cgoflags, "-gccgo_define_cgoincomplete")
+		}
 	}
 
 	switch cfg.BuildBuildmode {
@@ -2831,8 +3097,6 @@
 		cgoflags = append(cgoflags, "-exportheader="+objdir+"_cgo_install.h")
 	}
 
-	execdir := p.Dir
-
 	// Rewrite overlaid paths in cgo files.
 	// cgo adds //line and #line pragmas in generated files with these paths.
 	var trimpath []string
@@ -2847,7 +3111,7 @@
 		cgoflags = append(cgoflags, "-trimpath", strings.Join(trimpath, ";"))
 	}
 
-	if err := b.run(a, execdir, p.ImportPath, cgoenv, cfg.BuildToolexec, cgoExe, "-objdir", objdir, "-importpath", p.ImportPath, cgoflags, "--", cgoCPPFLAGS, cgoCFLAGS, cgofiles); err != nil {
+	if err := b.run(a, p.Dir, p.ImportPath, cgoenv, cfg.BuildToolexec, cgoExe, "-objdir", objdir, "-importpath", p.ImportPath, cgoflags, "--", cgoCPPFLAGS, cgoCFLAGS, cgofiles); err != nil {
 		return nil, nil, err
 	}
 	outGo = append(outGo, gofiles...)
@@ -3147,7 +3411,7 @@
 	if err != nil {
 		return err
 	}
-	re := regexp.MustCompile(`[vV]ersion +([\d]+)([.][\d]+)?([.][\d]+)?`)
+	re := regexp.MustCompile(`[vV]ersion +(\d+)([.]\d+)?([.]\d+)?`)
 	matches := re.FindSubmatch(out)
 	if matches == nil {
 		// Can't find version number; hope for the best.
@@ -3304,8 +3568,8 @@
 			if bytes.Contains(out, []byte("-intgosize")) || bytes.Contains(out, []byte("-cgo")) {
 				return "", "", errors.New("must have SWIG version >= 3.0.6")
 			}
-			b.showOutput(a, p.Dir, p.Desc(), b.processOutput(out)) // swig error
-			return "", "", errPrintedOutput
+			// swig error
+			err = formatOutput(b.WorkDir, p.Dir, p.ImportPath, p.Desc(), b.processOutput(out))
 		}
 		return "", "", err
 	}
@@ -3407,10 +3671,10 @@
 func useResponseFile(path string, argLen int) bool {
 	// Unless the program uses objabi.Flagparse, which understands
 	// response files, don't use response files.
-	// TODO: do we need more commands? asm? cgo? For now, no.
+	// TODO: Note that other toolchains like CC are missing here for now.
 	prog := strings.TrimSuffix(filepath.Base(path), ".exe")
 	switch prog {
-	case "compile", "link":
+	case "compile", "link", "cgo", "asm":
 	default:
 		return false
 	}
diff --git a/src/cmd/go/internal/work/gc.go b/src/cmd/go/internal/work/gc.go
index 8429529..ded751f 100644
--- a/src/cmd/go/internal/work/gc.go
+++ b/src/cmd/go/internal/work/gc.go
@@ -8,6 +8,7 @@
 	"bufio"
 	"bytes"
 	"fmt"
+	"internal/platform"
 	"io"
 	"log"
 	"os"
@@ -22,7 +23,6 @@
 	"cmd/go/internal/str"
 	"cmd/internal/objabi"
 	"cmd/internal/quoted"
-	"cmd/internal/sys"
 	"crypto/sha1"
 )
 
@@ -32,6 +32,7 @@
 var runtimePackages = map[string]struct{}{
 	"internal/abi":             struct{}{},
 	"internal/bytealg":         struct{}{},
+	"internal/coverage/rtcov":  struct{}{},
 	"internal/cpu":             struct{}{},
 	"internal/goarch":          struct{}{},
 	"internal/goos":            struct{}{},
@@ -140,6 +141,12 @@
 	if strings.HasPrefix(RuntimeVersion, "go1") && !strings.Contains(os.Args[0], "go_bootstrap") {
 		defaultGcFlags = append(defaultGcFlags, "-goversion", RuntimeVersion)
 	}
+	if p.Internal.CoverageCfg != "" {
+		defaultGcFlags = append(defaultGcFlags, "-coveragecfg="+p.Internal.CoverageCfg)
+	}
+	if cfg.BuildPGOFile != "" {
+		defaultGcFlags = append(defaultGcFlags, "-pgoprofile="+cfg.BuildPGOFile)
+	}
 	if symabis != "" {
 		defaultGcFlags = append(defaultGcFlags, "-symabis", symabis)
 	}
@@ -230,20 +237,6 @@
 		log.Fatalf("GO19CONCURRENTCOMPILATION must be 0, 1, or unset, got %q", e)
 	}
 
-CheckFlags:
-	for _, flag := range gcflags {
-		// Concurrent compilation is presumed incompatible with any gcflags,
-		// except for known commonly used flags.
-		// If the user knows better, they can manually add their own -c to the gcflags.
-		switch flag {
-		case "-N", "-l", "-S", "-B", "-C", "-I", "-shared":
-			// OK
-		default:
-			canDashC = false
-			break CheckFlags
-		}
-	}
-
 	// TODO: Test and delete these conditions.
 	if cfg.ExperimentErr != nil || cfg.Experiment.FieldTrack || cfg.Experiment.PreemptibleLoops {
 		canDashC = false
@@ -398,6 +391,21 @@
 		args = append(args, "-D", "GOMIPS64_"+cfg.GOMIPS64)
 	}
 
+	if cfg.Goarch == "ppc64" || cfg.Goarch == "ppc64le" {
+		// Define GOPPC64_power8..N from cfg.PPC64.
+		// We treat each powerpc version as a superset of functionality.
+		switch cfg.GOPPC64 {
+		case "power10":
+			args = append(args, "-D", "GOPPC64_power10")
+			fallthrough
+		case "power9":
+			args = append(args, "-D", "GOPPC64_power9")
+			fallthrough
+		default: // This should always be power8.
+			args = append(args, "-D", "GOPPC64_power8")
+		}
+	}
+
 	return args
 }
 
@@ -502,8 +510,7 @@
 		return nil
 	}
 	if err := packInternal(absAfile, absOfiles); err != nil {
-		b.showOutput(a, p.Dir, p.Desc(), err.Error()+"\n")
-		return errPrintedOutput
+		return formatOutput(b.WorkDir, p.Dir, p.ImportPath, p.Desc(), err.Error()+"\n")
 	}
 	return nil
 }
@@ -636,7 +643,7 @@
 		// linker's build id, which will cause our build id to not
 		// match the next time the tool is built.
 		// Rely on the external build id instead.
-		if !sys.MustLinkExternal(cfg.Goos, cfg.Goarch) {
+		if !platform.MustLinkExternal(cfg.Goos, cfg.Goarch) {
 			ldflags = append(ldflags, "-X=cmd/internal/objabi.buildID="+root.buildID)
 		}
 	}
diff --git a/src/cmd/go/internal/work/gccgo.go b/src/cmd/go/internal/work/gccgo.go
index d37b8df..08a4c2d 100644
--- a/src/cmd/go/internal/work/gccgo.go
+++ b/src/cmd/go/internal/work/gccgo.go
@@ -157,10 +157,7 @@
 		} else {
 			verb, args = line[:i], strings.TrimSpace(line[i+1:])
 		}
-		var before, after string
-		if i := strings.Index(args, "="); i >= 0 {
-			before, after = args[:i], args[i+1:]
-		}
+		before, after, _ := strings.Cut(args, "=")
 		switch verb {
 		default:
 			base.Fatalf("importcfg:%d: unknown directive %q", lineNum, verb)
@@ -620,3 +617,63 @@
 
 	return gccgoToSymbolFunc(gccgoPkgpath(p))
 }
+
+var (
+	gccgoSupportsCgoIncompleteOnce sync.Once
+	gccgoSupportsCgoIncomplete     bool
+)
+
+const gccgoSupportsCgoIncompleteCode = `
+package p
+
+import "runtime/cgo"
+
+type I cgo.Incomplete
+`
+
+// supportsCgoIncomplete reports whether the gccgo/GoLLVM compiler
+// being used supports cgo.Incomplete, which was added in GCC 13.
+func (tools gccgoToolchain) supportsCgoIncomplete(b *Builder) bool {
+	gccgoSupportsCgoIncompleteOnce.Do(func() {
+		fail := func(err error) {
+			fmt.Fprintf(os.Stderr, "cmd/go: %v\n", err)
+			base.SetExitStatus(2)
+			base.Exit()
+		}
+
+		tmpdir := b.WorkDir
+		if cfg.BuildN {
+			tmpdir = os.TempDir()
+		}
+		f, err := os.CreateTemp(tmpdir, "*_gccgo_cgoincomplete.go")
+		if err != nil {
+			fail(err)
+		}
+		fn := f.Name()
+		f.Close()
+		defer os.Remove(fn)
+
+		if err := os.WriteFile(fn, []byte(gccgoSupportsCgoIncompleteCode), 0644); err != nil {
+			fail(err)
+		}
+
+		on := strings.TrimSuffix(fn, ".go") + ".o"
+		if cfg.BuildN || cfg.BuildX {
+			b.Showcmd(tmpdir, "%s -c -o %s %s || true", tools.compiler(), on, fn)
+			// Since this function affects later builds,
+			// and only generates temporary files,
+			// we run the command even with -n.
+		}
+		cmd := exec.Command(tools.compiler(), "-c", "-o", on, fn)
+		cmd.Dir = tmpdir
+		var buf strings.Builder
+		cmd.Stdout = &buf
+		cmd.Stderr = &buf
+		err = cmd.Run()
+		if out := buf.String(); len(out) > 0 {
+			b.showOutput(nil, tmpdir, b.fmtcmd(tmpdir, "%s -c -o %s %s", tools.compiler(), on, fn), buf.String())
+		}
+		gccgoSupportsCgoIncomplete = err == nil
+	})
+	return gccgoSupportsCgoIncomplete
+}
diff --git a/src/cmd/go/internal/work/init.go b/src/cmd/go/internal/work/init.go
index 255ff3a..cd99a33 100644
--- a/src/cmd/go/internal/work/init.go
+++ b/src/cmd/go/internal/work/init.go
@@ -13,8 +13,8 @@
 	"cmd/go/internal/fsys"
 	"cmd/go/internal/modload"
 	"cmd/internal/quoted"
-	"cmd/internal/sys"
 	"fmt"
+	"internal/platform"
 	"os"
 	"os/exec"
 	"path/filepath"
@@ -24,7 +24,15 @@
 	"sync"
 )
 
+var buildInitStarted = false
+
 func BuildInit() {
+	if buildInitStarted {
+		base.Fatalf("go: internal error: work.BuildInit called more than once")
+	}
+	buildInitStarted = true
+	base.AtExit(closeBuilders)
+
 	modload.Init()
 	instrumentInit()
 	buildModeInit()
@@ -63,6 +71,19 @@
 			base.Fatalf("go: %s environment variable is relative; must be absolute path: %s\n", key, path)
 		}
 	}
+
+	// Set covermode if not already set.
+	// Ensure that -race and -covermode are compatible.
+	if cfg.BuildCoverMode == "" {
+		cfg.BuildCoverMode = "set"
+		if cfg.BuildRace {
+			// Default coverage mode is atomic when -race is set.
+			cfg.BuildCoverMode = "atomic"
+		}
+	}
+	if cfg.BuildRace && cfg.BuildCoverMode != "atomic" {
+		base.Fatalf(`-covermode must be "atomic", not %q, when -race is enabled`, cfg.BuildCoverMode)
+	}
 }
 
 // fuzzInstrumentFlags returns compiler flags that enable fuzzing instrumation
@@ -72,7 +93,7 @@
 // instrumentation is added. 'go test -fuzz' still works without coverage,
 // but it generates random inputs without guidance, so it's much less effective.
 func fuzzInstrumentFlags() []string {
-	if !sys.FuzzInstrumented(cfg.Goos, cfg.Goarch) {
+	if !platform.FuzzInstrumented(cfg.Goos, cfg.Goarch) {
 		return nil
 	}
 	return []string{"-d=libfuzzer"}
@@ -97,17 +118,17 @@
 		base.SetExitStatus(2)
 		base.Exit()
 	}
-	if cfg.BuildMSan && !sys.MSanSupported(cfg.Goos, cfg.Goarch) {
+	if cfg.BuildMSan && !platform.MSanSupported(cfg.Goos, cfg.Goarch) {
 		fmt.Fprintf(os.Stderr, "-msan is not supported on %s/%s\n", cfg.Goos, cfg.Goarch)
 		base.SetExitStatus(2)
 		base.Exit()
 	}
-	if cfg.BuildRace && !sys.RaceDetectorSupported(cfg.Goos, cfg.Goarch) {
+	if cfg.BuildRace && !platform.RaceDetectorSupported(cfg.Goos, cfg.Goarch) {
 		fmt.Fprintf(os.Stderr, "-race is not supported on %s/%s\n", cfg.Goos, cfg.Goarch)
 		base.SetExitStatus(2)
 		base.Exit()
 	}
-	if cfg.BuildASan && !sys.ASanSupported(cfg.Goos, cfg.Goarch) {
+	if cfg.BuildASan && !platform.ASanSupported(cfg.Goos, cfg.Goarch) {
 		fmt.Fprintf(os.Stderr, "-asan is not supported on %s/%s\n", cfg.Goos, cfg.Goarch)
 		base.SetExitStatus(2)
 		base.Exit()
@@ -128,9 +149,9 @@
 	mode := "race"
 	if cfg.BuildMSan {
 		mode = "msan"
-		// MSAN does not support non-PIE binaries on ARM64.
-		// See issue #33712 for details.
-		if cfg.Goos == "linux" && cfg.Goarch == "arm64" && cfg.BuildBuildmode == "default" {
+		// MSAN needs PIE on all platforms except linux/amd64.
+		// https://github.com/llvm/llvm-project/blob/llvmorg-13.0.1/clang/lib/Driver/SanitizerArgs.cpp#L621
+		if cfg.BuildBuildmode == "default" && (cfg.Goos != "linux" || cfg.Goarch != "amd64") {
 			cfg.BuildBuildmode = "pie"
 		}
 	}
@@ -139,7 +160,9 @@
 	}
 	modeFlag := "-" + mode
 
-	if !cfg.BuildContext.CgoEnabled {
+	// Check that cgo is enabled.
+	// Note: On macOS, -race does not require cgo. -asan and -msan still do.
+	if !cfg.BuildContext.CgoEnabled && (cfg.Goos != "darwin" || cfg.BuildASan || cfg.BuildMSan) {
 		if runtime.GOOS != cfg.Goos || runtime.GOARCH != cfg.Goarch {
 			fmt.Fprintf(os.Stderr, "go: %s requires cgo\n", modeFlag)
 		} else {
@@ -278,12 +301,12 @@
 		base.Fatalf("buildmode=%s not supported", cfg.BuildBuildmode)
 	}
 
-	if !sys.BuildModeSupported(cfg.BuildToolchainName, cfg.BuildBuildmode, cfg.Goos, cfg.Goarch) {
+	if !platform.BuildModeSupported(cfg.BuildToolchainName, cfg.BuildBuildmode, cfg.Goos, cfg.Goarch) {
 		base.Fatalf("-buildmode=%s not supported on %s/%s\n", cfg.BuildBuildmode, cfg.Goos, cfg.Goarch)
 	}
 
 	if cfg.BuildLinkshared {
-		if !sys.BuildModeSupported(cfg.BuildToolchainName, "shared", cfg.Goos, cfg.Goarch) {
+		if !platform.BuildModeSupported(cfg.BuildToolchainName, "shared", cfg.Goos, cfg.Goarch) {
 			base.Fatalf("-linkshared not supported on %s/%s\n", cfg.Goos, cfg.Goarch)
 		}
 		if gccgo {
@@ -402,12 +425,15 @@
 
 	switch compiler.name {
 	case "gcc":
+		if runtime.GOARCH == "ppc64le" && compiler.major < 9 {
+			return fmt.Errorf("-asan is not supported with %s compiler %d.%d\n", compiler.name, compiler.major, compiler.minor)
+		}
 		if compiler.major < 7 {
-			return fmt.Errorf("-asan is not supported with C compiler %d.%d\n", compiler.major, compiler.minor)
+			return fmt.Errorf("-asan is not supported with %s compiler %d.%d\n", compiler.name, compiler.major, compiler.minor)
 		}
 	case "clang":
 		if compiler.major < 9 {
-			return fmt.Errorf("-asan is not supported with C compiler %d.%d\n", compiler.major, compiler.minor)
+			return fmt.Errorf("-asan is not supported with %s compiler %d.%d\n", compiler.name, compiler.major, compiler.minor)
 		}
 	default:
 		return fmt.Errorf("-asan: C compiler is not gcc or clang")
diff --git a/src/cmd/go/internal/workcmd/edit.go b/src/cmd/go/internal/workcmd/edit.go
index 1478c19..f5e3304 100644
--- a/src/cmd/go/internal/workcmd/edit.go
+++ b/src/cmd/go/internal/workcmd/edit.go
@@ -109,6 +109,7 @@
 	cmdEdit.Flag.Var(flagFunc(flagEditworkDropUse), "dropuse", "")
 	cmdEdit.Flag.Var(flagFunc(flagEditworkReplace), "replace", "")
 	cmdEdit.Flag.Var(flagFunc(flagEditworkDropReplace), "dropreplace", "")
+	base.AddChdirFlag(&cmdEdit.Flag)
 }
 
 func runEditwork(ctx context.Context, cmd *base.Command, args []string) {
@@ -219,10 +220,11 @@
 // parsePathVersionOptional parses path[@version], using adj to
 // describe any errors.
 func parsePathVersionOptional(adj, arg string, allowDirPath bool) (path, version string, err error) {
-	if i := strings.Index(arg, "@"); i < 0 {
+	before, after, found := strings.Cut(arg, "@")
+	if !found {
 		path = arg
 	} else {
-		path, version = strings.TrimSpace(arg[:i]), strings.TrimSpace(arg[i+1:])
+		path, version = strings.TrimSpace(before), strings.TrimSpace(after)
 	}
 	if err := module.CheckImportPath(path); err != nil {
 		if !allowDirPath || !modfile.IsDirectoryPath(path) {
@@ -235,13 +237,13 @@
 	return path, version, nil
 }
 
-// flagReplace implements the -replace flag.
+// flagEditworkReplace implements the -replace flag.
 func flagEditworkReplace(arg string) {
-	var i int
-	if i = strings.Index(arg, "="); i < 0 {
+	before, after, found := strings.Cut(arg, "=")
+	if !found {
 		base.Fatalf("go: -replace=%s: need old[@v]=new[@w] (missing =)", arg)
 	}
-	old, new := strings.TrimSpace(arg[:i]), strings.TrimSpace(arg[i+1:])
+	old, new := strings.TrimSpace(before), strings.TrimSpace(after)
 	if strings.HasPrefix(new, ">") {
 		base.Fatalf("go: -replace=%s: separator between old and new is =, not =>", arg)
 	}
@@ -264,7 +266,7 @@
 	})
 }
 
-// flagDropReplace implements the -dropreplace flag.
+// flagEditworkDropReplace implements the -dropreplace flag.
 func flagEditworkDropReplace(arg string) {
 	path, version, err := parsePathVersionOptional("old", arg, true)
 	if err != nil {
diff --git a/src/cmd/go/internal/workcmd/init.go b/src/cmd/go/internal/workcmd/init.go
index c2513ba..6fb033e 100644
--- a/src/cmd/go/internal/workcmd/init.go
+++ b/src/cmd/go/internal/workcmd/init.go
@@ -34,6 +34,7 @@
 }
 
 func init() {
+	base.AddChdirFlag(&cmdInit.Flag)
 	base.AddModCommonFlags(&cmdInit.Flag)
 }
 
diff --git a/src/cmd/go/internal/workcmd/sync.go b/src/cmd/go/internal/workcmd/sync.go
index 7712eb6..9f99627 100644
--- a/src/cmd/go/internal/workcmd/sync.go
+++ b/src/cmd/go/internal/workcmd/sync.go
@@ -41,6 +41,7 @@
 }
 
 func init() {
+	base.AddChdirFlag(&cmdSync.Flag)
 	base.AddModCommonFlags(&cmdSync.Flag)
 }
 
diff --git a/src/cmd/go/internal/workcmd/use.go b/src/cmd/go/internal/workcmd/use.go
index 6da64b3..be90989 100644
--- a/src/cmd/go/internal/workcmd/use.go
+++ b/src/cmd/go/internal/workcmd/use.go
@@ -43,6 +43,7 @@
 func init() {
 	cmdUse.Run = runUse // break init cycle
 
+	base.AddChdirFlag(&cmdUse.Flag)
 	base.AddModCommonFlags(&cmdUse.Flag)
 }
 
@@ -149,7 +150,7 @@
 
 		// Remove entries for subdirectories that no longer exist.
 		// Because they don't exist, they will be skipped by Walk.
-		for absDir, _ := range haveDirs {
+		for absDir := range haveDirs {
 			if str.HasFilePathPrefix(absDir, absArg) {
 				if _, ok := keepDirs[absDir]; !ok {
 					keepDirs[absDir] = "" // Mark for deletion.
diff --git a/src/cmd/go/script_test.go b/src/cmd/go/script_test.go
index 809dfb4..4211fb6 100644
--- a/src/cmd/go/script_test.go
+++ b/src/cmd/go/script_test.go
@@ -5,36 +5,32 @@
 // Script-driven tests.
 // See testdata/script/README for an overview.
 
+//go:generate go test cmd/go -v -run=TestScript/README --fixreadme
+
 package main_test
 
 import (
+	"bufio"
 	"bytes"
 	"context"
-	"errors"
 	"flag"
 	"fmt"
 	"go/build"
 	"internal/testenv"
 	"internal/txtar"
-	"io/fs"
+	"net/url"
 	"os"
-	"os/exec"
 	"path/filepath"
 	"regexp"
 	"runtime"
-	"runtime/debug"
-	"strconv"
 	"strings"
-	"sync"
 	"testing"
 	"time"
 
 	"cmd/go/internal/cfg"
-	"cmd/go/internal/imports"
-	"cmd/go/internal/par"
-	"cmd/go/internal/robustio"
-	"cmd/go/internal/work"
-	"cmd/internal/sys"
+	"cmd/go/internal/script"
+	"cmd/go/internal/script/scripttest"
+	"cmd/go/internal/vcweb/vcstest"
 )
 
 var testSum = flag.String("testsum", "", `may be tidy, listm, or listall. If set, TestScript generates a go.sum file at the beginning of each test and updates test files if they pass.`)
@@ -44,6 +40,22 @@
 	testenv.MustHaveGoBuild(t)
 	testenv.SkipIfShortAndSlow(t)
 
+	srv, err := vcstest.NewServer()
+	if err != nil {
+		t.Fatal(err)
+	}
+	t.Cleanup(func() {
+		if err := srv.Close(); err != nil {
+			t.Fatal(err)
+		}
+	})
+	certFile, err := srv.WriteCertificateFile()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	StartProxy()
+
 	var (
 		ctx         = context.Background()
 		gracePeriod = 100 * time.Millisecond
@@ -71,6 +83,20 @@
 		t.Cleanup(cancel)
 	}
 
+	env, err := scriptEnv(srv, certFile)
+	if err != nil {
+		t.Fatal(err)
+	}
+	engine := &script.Engine{
+		Conds: scriptConditions(),
+		Cmds:  scriptCommands(quitSignal(), gracePeriod),
+		Quiet: !testing.Verbose(),
+	}
+
+	t.Run("README", func(t *testing.T) {
+		checkScriptReadme(t, engine, env)
+	})
+
 	files, err := filepath.Glob("testdata/script/*.txt")
 	if err != nil {
 		t.Fatal(err)
@@ -80,63 +106,160 @@
 		name := strings.TrimSuffix(filepath.Base(file), ".txt")
 		t.Run(name, func(t *testing.T) {
 			t.Parallel()
-			ctx, cancel := context.WithCancel(ctx)
-			defer cancel()
-			ts := &testScript{
-				t:           t,
-				ctx:         ctx,
-				cancel:      cancel,
-				gracePeriod: gracePeriod,
-				name:        name,
-				file:        file,
+			StartProxy()
+
+			workdir, err := os.MkdirTemp(testTmpDir, name)
+			if err != nil {
+				t.Fatal(err)
 			}
-			ts.setup()
 			if !*testWork {
-				defer removeAll(ts.workdir)
+				defer removeAll(workdir)
 			}
-			ts.run()
+
+			s, err := script.NewState(ctx, workdir, env)
+			if err != nil {
+				t.Fatal(err)
+			}
+
+			// Unpack archive.
+			a, err := txtar.ParseFile(file)
+			if err != nil {
+				t.Fatal(err)
+			}
+			initScriptDirs(t, s)
+			if err := s.ExtractFiles(a); err != nil {
+				t.Fatal(err)
+			}
+
+			t.Log(time.Now().UTC().Format(time.RFC3339))
+			work, _ := s.LookupEnv("WORK")
+			t.Logf("$WORK=%s", work)
+
+			// With -testsum, if a go.mod file is present in the test's initial
+			// working directory, run 'go mod tidy'.
+			if *testSum != "" {
+				if updateSum(t, engine, s, a) {
+					defer func() {
+						if t.Failed() {
+							return
+						}
+						data := txtar.Format(a)
+						if err := os.WriteFile(file, data, 0666); err != nil {
+							t.Errorf("rewriting test file: %v", err)
+						}
+					}()
+				}
+			}
+
+			scripttest.Run(t, engine, s, filepath.Base(file), bytes.NewReader(a.Comment))
 		})
 	}
 }
 
-// A testScript holds execution state for a single test script.
-type testScript struct {
-	t           *testing.T
-	ctx         context.Context
-	cancel      context.CancelFunc
-	gracePeriod time.Duration
-	workdir     string            // temporary work dir ($WORK)
-	log         bytes.Buffer      // test execution log (printed at end of test)
-	mark        int               // offset of next log truncation
-	cd          string            // current directory during test execution; initially $WORK/gopath/src
-	name        string            // short name of test ("foo")
-	file        string            // full file name ("testdata/script/foo.txt")
-	lineno      int               // line number currently executing
-	line        string            // line currently executing
-	env         []string          // environment list (for os/exec)
-	envMap      map[string]string // environment mapping (matches env)
-	stdout      string            // standard output from last 'go' command; for 'stdout' command
-	stderr      string            // standard error from last 'go' command; for 'stderr' command
-	stopped     bool              // test wants to stop early
-	start       time.Time         // time phase started
-	background  []*backgroundCmd  // backgrounded 'exec' and 'go' commands
+// initScriptState creates the initial directory structure in s for unpacking a
+// cmd/go script.
+func initScriptDirs(t testing.TB, s *script.State) {
+	must := func(err error) {
+		if err != nil {
+			t.Helper()
+			t.Fatal(err)
+		}
+	}
+
+	work := s.Getwd()
+	must(s.Setenv("WORK", work))
+
+	must(os.MkdirAll(filepath.Join(work, "tmp"), 0777))
+	must(s.Setenv(tempEnvName(), filepath.Join(work, "tmp")))
+
+	gopath := filepath.Join(work, "gopath")
+	must(s.Setenv("GOPATH", gopath))
+	gopathSrc := filepath.Join(gopath, "src")
+	must(os.MkdirAll(gopathSrc, 0777))
+	must(s.Chdir(gopathSrc))
 }
 
-type backgroundCmd struct {
-	want           simpleStatus
-	args           []string
-	done           <-chan struct{}
-	err            error
-	stdout, stderr strings.Builder
+func scriptEnv(srv *vcstest.Server, srvCertFile string) ([]string, error) {
+	httpURL, err := url.Parse(srv.HTTP.URL)
+	if err != nil {
+		return nil, err
+	}
+	httpsURL, err := url.Parse(srv.HTTPS.URL)
+	if err != nil {
+		return nil, err
+	}
+	version, err := goVersion()
+	if err != nil {
+		return nil, err
+	}
+	env := []string{
+		pathEnvName() + "=" + testBin + string(filepath.ListSeparator) + os.Getenv(pathEnvName()),
+		homeEnvName() + "=/no-home",
+		"CCACHE_DISABLE=1", // ccache breaks with non-existent HOME
+		"GOARCH=" + runtime.GOARCH,
+		"TESTGO_GOHOSTARCH=" + goHostArch,
+		"GOCACHE=" + testGOCACHE,
+		"GOCOVERDIR=" + os.Getenv("GOCOVERDIR"),
+		"GODEBUG=" + os.Getenv("GODEBUG"),
+		"GOEXE=" + cfg.ExeSuffix,
+		"GOEXPERIMENT=" + os.Getenv("GOEXPERIMENT"),
+		"GOOS=" + runtime.GOOS,
+		"TESTGO_GOHOSTOS=" + goHostOS,
+		"GOPROXY=" + proxyURL,
+		"GOPRIVATE=",
+		"GOROOT=" + testGOROOT,
+		"GOROOT_FINAL=" + testGOROOT_FINAL, // causes spurious rebuilds and breaks the "stale" built-in if not propagated
+		"GOTRACEBACK=system",
+		"TESTGO_GOROOT=" + testGOROOT,
+		"TESTGO_EXE=" + testGo,
+		"TESTGO_VCSTEST_HOST=" + httpURL.Host,
+		"TESTGO_VCSTEST_TLS_HOST=" + httpsURL.Host,
+		"TESTGO_VCSTEST_CERT=" + srvCertFile,
+		"GOSUMDB=" + testSumDBVerifierKey,
+		"GONOPROXY=",
+		"GONOSUMDB=",
+		"GOVCS=*:all",
+		"devnull=" + os.DevNull,
+		"goversion=" + version,
+		"CMDGO_TEST_RUN_MAIN=true",
+	}
+
+	if testenv.Builder() != "" || os.Getenv("GIT_TRACE_CURL") == "1" {
+		// To help diagnose https://go.dev/issue/52545,
+		// enable tracing for Git HTTPS requests.
+		env = append(env,
+			"GIT_TRACE_CURL=1",
+			"GIT_TRACE_CURL_NO_DATA=1",
+			"GIT_REDACT_COOKIES=o,SSO,GSSO_Uberproxy")
+	}
+	if !testenv.HasExternalNetwork() {
+		env = append(env, "TESTGONETWORK=panic", "TESTGOVCS=panic")
+	}
+	if os.Getenv("CGO_ENABLED") != "" || runtime.GOOS != goHostOS || runtime.GOARCH != goHostArch {
+		// If the actual CGO_ENABLED might not match the cmd/go default, set it
+		// explicitly in the environment. Otherwise, leave it unset so that we also
+		// cover the default behaviors.
+		env = append(env, "CGO_ENABLED="+cgoEnabled)
+	}
+
+	for _, key := range extraEnvKeys {
+		if val, ok := os.LookupEnv(key); ok {
+			env = append(env, key+"="+val)
+		}
+	}
+
+	return env, nil
 }
 
-type simpleStatus string
-
-const (
-	success          simpleStatus = ""
-	failure          simpleStatus = "!"
-	successOrFailure simpleStatus = "?"
-)
+// goVersion returns the current Go version.
+func goVersion() (string, error) {
+	tags := build.Default.ReleaseTags
+	version := tags[len(tags)-1]
+	if !regexp.MustCompile(`^go([1-9][0-9]*)\.(0|[1-9][0-9]*)$`).MatchString(version) {
+		return "", fmt.Errorf("invalid go version %q", version)
+	}
+	return version[2:], nil
+}
 
 var extraEnvKeys = []string{
 	"SYSTEMROOT",         // must be preserved on Windows to find DLLs; golang.org/issue/25210
@@ -150,1364 +273,11 @@
 	"GCCGOTOOLDIR",       // for gccgo testing
 }
 
-// setup sets up the test execution temporary directory and environment.
-func (ts *testScript) setup() {
-	if err := ts.ctx.Err(); err != nil {
-		ts.t.Fatalf("test interrupted during setup: %v", err)
-	}
-
-	StartProxy()
-	ts.workdir = filepath.Join(testTmpDir, "script-"+ts.name)
-	ts.check(os.MkdirAll(filepath.Join(ts.workdir, "tmp"), 0777))
-	ts.check(os.MkdirAll(filepath.Join(ts.workdir, "gopath/src"), 0777))
-	ts.cd = filepath.Join(ts.workdir, "gopath/src")
-	ts.env = []string{
-		"WORK=" + ts.workdir, // must be first for ts.abbrev
-		pathEnvName() + "=" + testBin + string(filepath.ListSeparator) + os.Getenv(pathEnvName()),
-		homeEnvName() + "=/no-home",
-		"CCACHE_DISABLE=1", // ccache breaks with non-existent HOME
-		"GOARCH=" + runtime.GOARCH,
-		"GOCACHE=" + testGOCACHE,
-		"GODEBUG=" + os.Getenv("GODEBUG"),
-		"GOEXE=" + cfg.ExeSuffix,
-		"GOEXPERIMENT=" + os.Getenv("GOEXPERIMENT"),
-		"GOOS=" + runtime.GOOS,
-		"GOPATH=" + filepath.Join(ts.workdir, "gopath"),
-		"GOPROXY=" + proxyURL,
-		"GOPRIVATE=",
-		"GOROOT=" + testGOROOT,
-		"GOROOT_FINAL=" + testGOROOT_FINAL, // causes spurious rebuilds and breaks the "stale" built-in if not propagated
-		"GOTRACEBACK=system",
-		"TESTGO_GOROOT=" + testGOROOT,
-		"GOSUMDB=" + testSumDBVerifierKey,
-		"GONOPROXY=",
-		"GONOSUMDB=",
-		"GOVCS=*:all",
-		"PWD=" + ts.cd,
-		tempEnvName() + "=" + filepath.Join(ts.workdir, "tmp"),
-		"devnull=" + os.DevNull,
-		"goversion=" + goVersion(ts),
-		"CMDGO_TEST_RUN_MAIN=true",
-	}
-	if testenv.Builder() != "" || os.Getenv("GIT_TRACE_CURL") == "1" {
-		// To help diagnose https://go.dev/issue/52545,
-		// enable tracing for Git HTTPS requests.
-		ts.env = append(ts.env,
-			"GIT_TRACE_CURL=1",
-			"GIT_TRACE_CURL_NO_DATA=1",
-			"GIT_REDACT_COOKIES=o,SSO,GSSO_Uberproxy")
-	}
-	if !testenv.HasExternalNetwork() {
-		ts.env = append(ts.env, "TESTGONETWORK=panic", "TESTGOVCS=panic")
-	}
-
-	for _, key := range extraEnvKeys {
-		if val := os.Getenv(key); val != "" {
-			ts.env = append(ts.env, key+"="+val)
-		}
-	}
-
-	ts.envMap = make(map[string]string)
-	for _, kv := range ts.env {
-		if i := strings.Index(kv, "="); i >= 0 {
-			ts.envMap[kv[:i]] = kv[i+1:]
-		}
-	}
-	// Add entries for ${:} and ${/} to make it easier to write platform-independent
-	// environment variables.
-	ts.envMap["/"] = string(os.PathSeparator)
-	ts.envMap[":"] = string(os.PathListSeparator)
-
-	fmt.Fprintf(&ts.log, "# (%s)\n", time.Now().UTC().Format(time.RFC3339))
-	ts.mark = ts.log.Len()
-}
-
-// goVersion returns the current Go version.
-func goVersion(ts *testScript) string {
-	tags := build.Default.ReleaseTags
-	version := tags[len(tags)-1]
-	if !regexp.MustCompile(`^go([1-9][0-9]*)\.(0|[1-9][0-9]*)$`).MatchString(version) {
-		ts.fatalf("invalid go version %q", version)
-	}
-	return version[2:]
-}
-
-var execCache par.Cache
-
-// run runs the test script.
-func (ts *testScript) run() {
-	// Truncate log at end of last phase marker,
-	// discarding details of successful phase.
-	rewind := func() {
-		if !testing.Verbose() {
-			ts.log.Truncate(ts.mark)
-		}
-	}
-
-	// Insert elapsed time for phase at end of phase marker
-	markTime := func() {
-		if ts.mark > 0 && !ts.start.IsZero() {
-			afterMark := append([]byte{}, ts.log.Bytes()[ts.mark:]...)
-			ts.log.Truncate(ts.mark - 1) // cut \n and afterMark
-			fmt.Fprintf(&ts.log, " (%.3fs)\n", time.Since(ts.start).Seconds())
-			ts.log.Write(afterMark)
-		}
-		ts.start = time.Time{}
-	}
-
-	defer func() {
-		// On a normal exit from the test loop, background processes are cleaned up
-		// before we print PASS. If we return early (e.g., due to a test failure),
-		// don't print anything about the processes that were still running.
-		ts.cancel()
-		for _, bg := range ts.background {
-			<-bg.done
-		}
-		ts.background = nil
-
-		markTime()
-		// Flush testScript log to testing.T log.
-		ts.t.Log("\n" + ts.abbrev(ts.log.String()))
-	}()
-
-	// Unpack archive.
-	a, err := txtar.ParseFile(ts.file)
-	ts.check(err)
-	for _, f := range a.Files {
-		name := ts.mkabs(ts.expand(f.Name, false))
-		ts.check(os.MkdirAll(filepath.Dir(name), 0777))
-		ts.check(os.WriteFile(name, f.Data, 0666))
-	}
-
-	// With -v or -testwork, start log with full environment.
-	if *testWork || testing.Verbose() {
-		// Display environment.
-		ts.cmdEnv(success, nil)
-		fmt.Fprintf(&ts.log, "\n")
-		ts.mark = ts.log.Len()
-	}
-
-	// With -testsum, if a go.mod file is present in the test's initial
-	// working directory, run 'go mod tidy'.
-	if *testSum != "" {
-		if ts.updateSum(a) {
-			defer func() {
-				if ts.t.Failed() {
-					return
-				}
-				data := txtar.Format(a)
-				if err := os.WriteFile(ts.file, data, 0666); err != nil {
-					ts.t.Errorf("rewriting test file: %v", err)
-				}
-			}()
-		}
-	}
-
-	// Run script.
-	// See testdata/script/README for documentation of script form.
-	script := string(a.Comment)
-Script:
-	for script != "" {
-		// Extract next line.
-		ts.lineno++
-		var line string
-		if i := strings.Index(script, "\n"); i >= 0 {
-			line, script = script[:i], script[i+1:]
-		} else {
-			line, script = script, ""
-		}
-
-		// # is a comment indicating the start of new phase.
-		if strings.HasPrefix(line, "#") {
-			// If there was a previous phase, it succeeded,
-			// so rewind the log to delete its details (unless -v is in use).
-			// If nothing has happened at all since the mark,
-			// rewinding is a no-op and adding elapsed time
-			// for doing nothing is meaningless, so don't.
-			if ts.log.Len() > ts.mark {
-				rewind()
-				markTime()
-			}
-			// Print phase heading and mark start of phase output.
-			fmt.Fprintf(&ts.log, "%s\n", line)
-			ts.mark = ts.log.Len()
-			ts.start = time.Now()
-			continue
-		}
-
-		// Parse input line. Ignore blanks entirely.
-		parsed := ts.parse(line)
-		if parsed.name == "" {
-			if parsed.want != "" || len(parsed.conds) > 0 {
-				ts.fatalf("missing command")
-			}
-			continue
-		}
-
-		// Echo command to log.
-		fmt.Fprintf(&ts.log, "> %s\n", line)
-
-		for _, cond := range parsed.conds {
-			if err := ts.ctx.Err(); err != nil {
-				ts.fatalf("test interrupted: %v", err)
-			}
-
-			// Known conds are: $GOOS, $GOARCH, runtime.Compiler, and 'short' (for testing.Short).
-			//
-			// NOTE: If you make changes here, update testdata/script/README too!
-			//
-			ok := false
-			switch cond.tag {
-			case runtime.GOOS, runtime.GOARCH, runtime.Compiler:
-				ok = true
-			case "short":
-				ok = testing.Short()
-			case "cgo":
-				ok = canCgo
-			case "msan":
-				ok = canMSan
-			case "asan":
-				ok = canASan
-			case "race":
-				ok = canRace
-			case "fuzz":
-				ok = canFuzz
-			case "fuzz-instrumented":
-				ok = fuzzInstrumented
-			case "net":
-				ok = testenv.HasExternalNetwork()
-			case "link":
-				ok = testenv.HasLink()
-			case "root":
-				ok = os.Geteuid() == 0
-			case "symlink":
-				ok = testenv.HasSymlink()
-			case "case-sensitive":
-				ok = isCaseSensitive(ts.t)
-			case "trimpath":
-				if info, _ := debug.ReadBuildInfo(); info == nil {
-					ts.fatalf("missing build info")
-				} else {
-					for _, s := range info.Settings {
-						if s.Key == "-trimpath" && s.Value == "true" {
-							ok = true
-							break
-						}
-					}
-				}
-			case "mismatched-goroot":
-				ok = testGOROOT_FINAL != "" && testGOROOT_FINAL != testGOROOT
-			default:
-				if strings.HasPrefix(cond.tag, "exec:") {
-					prog := cond.tag[len("exec:"):]
-					ok = execCache.Do(prog, func() any {
-						if runtime.GOOS == "plan9" && prog == "git" {
-							// The Git command is usually not the real Git on Plan 9.
-							// See https://golang.org/issues/29640.
-							return false
-						}
-						_, err := exec.LookPath(prog)
-						return err == nil
-					}).(bool)
-					break
-				}
-				if strings.HasPrefix(cond.tag, "GODEBUG:") {
-					value := strings.TrimPrefix(cond.tag, "GODEBUG:")
-					parts := strings.Split(os.Getenv("GODEBUG"), ",")
-					for _, p := range parts {
-						if strings.TrimSpace(p) == value {
-							ok = true
-							break
-						}
-					}
-					break
-				}
-				if strings.HasPrefix(cond.tag, "buildmode:") {
-					value := strings.TrimPrefix(cond.tag, "buildmode:")
-					ok = sys.BuildModeSupported(runtime.Compiler, value, runtime.GOOS, runtime.GOARCH)
-					break
-				}
-				if !imports.KnownArch[cond.tag] && !imports.KnownOS[cond.tag] && cond.tag != "gc" && cond.tag != "gccgo" {
-					ts.fatalf("unknown condition %q", cond.tag)
-				}
-			}
-			if ok != cond.want {
-				// Don't run rest of line.
-				continue Script
-			}
-		}
-
-		// Run command.
-		cmd := scriptCmds[parsed.name]
-		if cmd == nil {
-			ts.fatalf("unknown command %q", parsed.name)
-		}
-		cmd(ts, parsed.want, parsed.args)
-
-		// Command can ask script to stop early.
-		if ts.stopped {
-			// Break instead of returning, so that we check the status of any
-			// background processes and print PASS.
-			break
-		}
-	}
-
-	ts.cancel()
-	ts.cmdWait(success, nil)
-
-	// Final phase ended.
-	rewind()
-	markTime()
-	if !ts.stopped {
-		fmt.Fprintf(&ts.log, "PASS\n")
-	}
-}
-
-var (
-	onceCaseSensitive sync.Once
-	caseSensitive     bool
-)
-
-func isCaseSensitive(t *testing.T) bool {
-	onceCaseSensitive.Do(func() {
-		tmpdir, err := os.MkdirTemp("", "case-sensitive")
-		if err != nil {
-			t.Fatal("failed to create directory to determine case-sensitivity:", err)
-		}
-		defer os.RemoveAll(tmpdir)
-
-		fcap := filepath.Join(tmpdir, "FILE")
-		if err := os.WriteFile(fcap, []byte{}, 0644); err != nil {
-			t.Fatal("error writing file to determine case-sensitivity:", err)
-		}
-
-		flow := filepath.Join(tmpdir, "file")
-		_, err = os.ReadFile(flow)
-		switch {
-		case err == nil:
-			caseSensitive = false
-			return
-		case os.IsNotExist(err):
-			caseSensitive = true
-			return
-		default:
-			t.Fatal("unexpected error reading file when determining case-sensitivity:", err)
-		}
-	})
-
-	return caseSensitive
-}
-
-// scriptCmds are the script command implementations.
-// Keep list and the implementations below sorted by name.
-//
-// NOTE: If you make changes here, update testdata/script/README too!
-var scriptCmds = map[string]func(*testScript, simpleStatus, []string){
-	"addcrlf": (*testScript).cmdAddcrlf,
-	"cc":      (*testScript).cmdCc,
-	"cd":      (*testScript).cmdCd,
-	"chmod":   (*testScript).cmdChmod,
-	"cmp":     (*testScript).cmdCmp,
-	"cmpenv":  (*testScript).cmdCmpenv,
-	"cp":      (*testScript).cmdCp,
-	"env":     (*testScript).cmdEnv,
-	"exec":    (*testScript).cmdExec,
-	"exists":  (*testScript).cmdExists,
-	"go":      (*testScript).cmdGo,
-	"grep":    (*testScript).cmdGrep,
-	"mkdir":   (*testScript).cmdMkdir,
-	"mv":      (*testScript).cmdMv,
-	"rm":      (*testScript).cmdRm,
-	"skip":    (*testScript).cmdSkip,
-	"sleep":   (*testScript).cmdSleep,
-	"stale":   (*testScript).cmdStale,
-	"stderr":  (*testScript).cmdStderr,
-	"stdout":  (*testScript).cmdStdout,
-	"stop":    (*testScript).cmdStop,
-	"symlink": (*testScript).cmdSymlink,
-	"wait":    (*testScript).cmdWait,
-}
-
-// When expanding shell variables for these commands, we apply regexp quoting to
-// expanded strings within the first argument.
-var regexpCmd = map[string]bool{
-	"grep":   true,
-	"stderr": true,
-	"stdout": true,
-}
-
-// addcrlf adds CRLF line endings to the named files.
-func (ts *testScript) cmdAddcrlf(want simpleStatus, args []string) {
-	if len(args) == 0 {
-		ts.fatalf("usage: addcrlf file...")
-	}
-
-	for _, file := range args {
-		file = ts.mkabs(file)
-		data, err := os.ReadFile(file)
-		ts.check(err)
-		ts.check(os.WriteFile(file, bytes.ReplaceAll(data, []byte("\n"), []byte("\r\n")), 0666))
-	}
-}
-
-// cc runs the C compiler along with platform specific options.
-func (ts *testScript) cmdCc(want simpleStatus, args []string) {
-	if len(args) < 1 || (len(args) == 1 && args[0] == "&") {
-		ts.fatalf("usage: cc args... [&]")
-	}
-
-	var b work.Builder
-	b.Init()
-	ts.cmdExec(want, append(b.GccCmd(".", ""), args...))
-	robustio.RemoveAll(b.WorkDir)
-}
-
-// cd changes to a different directory.
-func (ts *testScript) cmdCd(want simpleStatus, args []string) {
-	if want != success {
-		ts.fatalf("unsupported: %v cd", want)
-	}
-	if len(args) != 1 {
-		ts.fatalf("usage: cd dir")
-	}
-
-	dir := filepath.FromSlash(args[0])
-	if !filepath.IsAbs(dir) {
-		dir = filepath.Join(ts.cd, dir)
-	}
-	info, err := os.Stat(dir)
-	if os.IsNotExist(err) {
-		ts.fatalf("directory %s does not exist", dir)
-	}
-	ts.check(err)
-	if !info.IsDir() {
-		ts.fatalf("%s is not a directory", dir)
-	}
-	ts.cd = dir
-	ts.envMap["PWD"] = dir
-	fmt.Fprintf(&ts.log, "%s\n", ts.cd)
-}
-
-// chmod changes permissions for a file or directory.
-func (ts *testScript) cmdChmod(want simpleStatus, args []string) {
-	if want != success {
-		ts.fatalf("unsupported: %v chmod", want)
-	}
-	if len(args) < 2 {
-		ts.fatalf("usage: chmod perm paths...")
-	}
-	perm, err := strconv.ParseUint(args[0], 0, 32)
-	if err != nil || perm&uint64(fs.ModePerm) != perm {
-		ts.fatalf("invalid mode: %s", args[0])
-	}
-	for _, arg := range args[1:] {
-		path := arg
-		if !filepath.IsAbs(path) {
-			path = filepath.Join(ts.cd, arg)
-		}
-		err := os.Chmod(path, fs.FileMode(perm))
-		ts.check(err)
-	}
-}
-
-// cmp compares two files.
-func (ts *testScript) cmdCmp(want simpleStatus, args []string) {
-	quiet := false
-	if len(args) > 0 && args[0] == "-q" {
-		quiet = true
-		args = args[1:]
-	}
-	if len(args) != 2 {
-		ts.fatalf("usage: cmp file1 file2")
-	}
-	ts.doCmdCmp(want, args, false, quiet)
-}
-
-// cmpenv compares two files with environment variable substitution.
-func (ts *testScript) cmdCmpenv(want simpleStatus, args []string) {
-	quiet := false
-	if len(args) > 0 && args[0] == "-q" {
-		quiet = true
-		args = args[1:]
-	}
-	if len(args) != 2 {
-		ts.fatalf("usage: cmpenv file1 file2")
-	}
-	ts.doCmdCmp(want, args, true, quiet)
-}
-
-func (ts *testScript) doCmdCmp(want simpleStatus, args []string, env, quiet bool) {
-	name1, name2 := args[0], args[1]
-	var text1, text2 string
-	switch name1 {
-	case "stdout":
-		text1 = ts.stdout
-	case "stderr":
-		text1 = ts.stderr
-	default:
-		data, err := os.ReadFile(ts.mkabs(name1))
-		ts.check(err)
-		text1 = string(data)
-	}
-
-	data, err := os.ReadFile(ts.mkabs(name2))
-	ts.check(err)
-	text2 = string(data)
-
-	if env {
-		text1 = ts.expand(text1, false)
-		text2 = ts.expand(text2, false)
-	}
-
-	eq := text1 == text2
-	if !eq && !quiet && want != failure {
-		fmt.Fprintf(&ts.log, "[diff -%s +%s]\n%s\n", name1, name2, diff(text1, text2))
-	}
-	switch want {
-	case failure:
-		if eq {
-			ts.fatalf("%s and %s do not differ", name1, name2)
-		}
-	case success:
-		if !eq {
-			ts.fatalf("%s and %s differ", name1, name2)
-		}
-	case successOrFailure:
-		if eq {
-			fmt.Fprintf(&ts.log, "%s and %s do not differ\n", name1, name2)
-		} else {
-			fmt.Fprintf(&ts.log, "%s and %s differ\n", name1, name2)
-		}
-	default:
-		ts.fatalf("unsupported: %v cmp", want)
-	}
-}
-
-// cp copies files, maybe eventually directories.
-func (ts *testScript) cmdCp(want simpleStatus, args []string) {
-	if len(args) < 2 {
-		ts.fatalf("usage: cp src... dst")
-	}
-
-	dst := ts.mkabs(args[len(args)-1])
-	info, err := os.Stat(dst)
-	dstDir := err == nil && info.IsDir()
-	if len(args) > 2 && !dstDir {
-		ts.fatalf("cp: destination %s is not a directory", dst)
-	}
-
-	for _, arg := range args[:len(args)-1] {
-		var (
-			src  string
-			data []byte
-			mode fs.FileMode
-		)
-		switch arg {
-		case "stdout":
-			src = arg
-			data = []byte(ts.stdout)
-			mode = 0666
-		case "stderr":
-			src = arg
-			data = []byte(ts.stderr)
-			mode = 0666
-		default:
-			src = ts.mkabs(arg)
-			info, err := os.Stat(src)
-			ts.check(err)
-			mode = info.Mode() & 0777
-			data, err = os.ReadFile(src)
-			ts.check(err)
-		}
-		targ := dst
-		if dstDir {
-			targ = filepath.Join(dst, filepath.Base(src))
-		}
-		err := os.WriteFile(targ, data, mode)
-		switch want {
-		case failure:
-			if err == nil {
-				ts.fatalf("unexpected command success")
-			}
-		case success:
-			ts.check(err)
-		}
-	}
-}
-
-// env displays or adds to the environment.
-func (ts *testScript) cmdEnv(want simpleStatus, args []string) {
-	if want != success {
-		ts.fatalf("unsupported: %v env", want)
-	}
-
-	conv := func(s string) string { return s }
-	if len(args) > 0 && args[0] == "-r" {
-		conv = regexp.QuoteMeta
-		args = args[1:]
-	}
-
-	var out strings.Builder
-	if len(args) == 0 {
-		printed := make(map[string]bool) // env list can have duplicates; only print effective value (from envMap) once
-		for _, kv := range ts.env {
-			k := kv[:strings.Index(kv, "=")]
-			if !printed[k] {
-				fmt.Fprintf(&out, "%s=%s\n", k, ts.envMap[k])
-			}
-		}
-	} else {
-		for _, env := range args {
-			i := strings.Index(env, "=")
-			if i < 0 {
-				// Display value instead of setting it.
-				fmt.Fprintf(&out, "%s=%s\n", env, ts.envMap[env])
-				continue
-			}
-			key, val := env[:i], conv(env[i+1:])
-			ts.env = append(ts.env, key+"="+val)
-			ts.envMap[key] = val
-		}
-	}
-	if out.Len() > 0 || len(args) > 0 {
-		ts.stdout = out.String()
-		ts.log.WriteString(out.String())
-	}
-}
-
-// exec runs the given command.
-func (ts *testScript) cmdExec(want simpleStatus, args []string) {
-	if len(args) < 1 || (len(args) == 1 && args[0] == "&") {
-		ts.fatalf("usage: exec program [args...] [&]")
-	}
-
-	background := false
-	if len(args) > 0 && args[len(args)-1] == "&" {
-		background = true
-		args = args[:len(args)-1]
-	}
-
-	bg, err := ts.startBackground(want, args[0], args[1:]...)
-	if err != nil {
-		ts.fatalf("unexpected error starting command: %v", err)
-	}
-	if background {
-		ts.stdout, ts.stderr = "", ""
-		ts.background = append(ts.background, bg)
-		return
-	}
-
-	<-bg.done
-	ts.stdout = bg.stdout.String()
-	ts.stderr = bg.stderr.String()
-	if ts.stdout != "" {
-		fmt.Fprintf(&ts.log, "[stdout]\n%s", ts.stdout)
-	}
-	if ts.stderr != "" {
-		fmt.Fprintf(&ts.log, "[stderr]\n%s", ts.stderr)
-	}
-	if bg.err != nil {
-		fmt.Fprintf(&ts.log, "[%v]\n", bg.err)
-	}
-	ts.checkCmd(bg)
-}
-
-// exists checks that the list of files exists.
-func (ts *testScript) cmdExists(want simpleStatus, args []string) {
-	if want == successOrFailure {
-		ts.fatalf("unsupported: %v exists", want)
-	}
-	var readonly, exec bool
-loop:
-	for len(args) > 0 {
-		switch args[0] {
-		case "-readonly":
-			readonly = true
-			args = args[1:]
-		case "-exec":
-			exec = true
-			args = args[1:]
-		default:
-			break loop
-		}
-	}
-	if len(args) == 0 {
-		ts.fatalf("usage: exists [-readonly] [-exec] file...")
-	}
-
-	for _, file := range args {
-		file = ts.mkabs(file)
-		info, err := os.Stat(file)
-		if err == nil && want == failure {
-			what := "file"
-			if info.IsDir() {
-				what = "directory"
-			}
-			ts.fatalf("%s %s unexpectedly exists", what, file)
-		}
-		if err != nil && want == success {
-			ts.fatalf("%s does not exist", file)
-		}
-		if err == nil && want == success && readonly && info.Mode()&0222 != 0 {
-			ts.fatalf("%s exists but is writable", file)
-		}
-		if err == nil && want == success && exec && runtime.GOOS != "windows" && info.Mode()&0111 == 0 {
-			ts.fatalf("%s exists but is not executable", file)
-		}
-	}
-}
-
-// go runs the go command.
-func (ts *testScript) cmdGo(want simpleStatus, args []string) {
-	ts.cmdExec(want, append([]string{testGo}, args...))
-}
-
-// mkdir creates directories.
-func (ts *testScript) cmdMkdir(want simpleStatus, args []string) {
-	if want != success {
-		ts.fatalf("unsupported: %v mkdir", want)
-	}
-	if len(args) < 1 {
-		ts.fatalf("usage: mkdir dir...")
-	}
-	for _, arg := range args {
-		ts.check(os.MkdirAll(ts.mkabs(arg), 0777))
-	}
-}
-
-func (ts *testScript) cmdMv(want simpleStatus, args []string) {
-	if want != success {
-		ts.fatalf("unsupported: %v mv", want)
-	}
-	if len(args) != 2 {
-		ts.fatalf("usage: mv old new")
-	}
-	ts.check(os.Rename(ts.mkabs(args[0]), ts.mkabs(args[1])))
-}
-
-// rm removes files or directories.
-func (ts *testScript) cmdRm(want simpleStatus, args []string) {
-	if want != success {
-		ts.fatalf("unsupported: %v rm", want)
-	}
-	if len(args) < 1 {
-		ts.fatalf("usage: rm file...")
-	}
-	for _, arg := range args {
-		file := ts.mkabs(arg)
-		removeAll(file)                    // does chmod and then attempts rm
-		ts.check(robustio.RemoveAll(file)) // report error
-	}
-}
-
-// skip marks the test skipped.
-func (ts *testScript) cmdSkip(want simpleStatus, args []string) {
-	if len(args) > 1 {
-		ts.fatalf("usage: skip [msg]")
-	}
-	if want != success {
-		ts.fatalf("unsupported: %v skip", want)
-	}
-
-	// Before we mark the test as skipped, shut down any background processes and
-	// make sure they have returned the correct status.
-	ts.cancel()
-	ts.cmdWait(success, nil)
-
-	if len(args) == 1 {
-		ts.t.Skip(args[0])
-	}
-	ts.t.Skip()
-}
-
-// sleep sleeps for the given duration
-func (ts *testScript) cmdSleep(want simpleStatus, args []string) {
-	if len(args) != 1 {
-		ts.fatalf("usage: sleep duration")
-	}
-	d, err := time.ParseDuration(args[0])
-	if err != nil {
-		ts.fatalf("sleep: %v", err)
-	}
-	if want != success {
-		ts.fatalf("unsupported: %v sleep", want)
-	}
-	time.Sleep(d)
-}
-
-// stale checks that the named build targets are stale.
-func (ts *testScript) cmdStale(want simpleStatus, args []string) {
-	if len(args) == 0 {
-		ts.fatalf("usage: stale target...")
-	}
-	tmpl := "{{if .Error}}{{.ImportPath}}: {{.Error.Err}}{{else}}"
-	switch want {
-	case failure:
-		tmpl += "{{if .Stale}}{{.ImportPath}} is unexpectedly stale: {{.StaleReason}}{{end}}"
-	case success:
-		tmpl += "{{if not .Stale}}{{.ImportPath}} is unexpectedly NOT stale{{end}}"
-	default:
-		ts.fatalf("unsupported: %v stale", want)
-	}
-	tmpl += "{{end}}"
-	goArgs := append([]string{"list", "-e", "-f=" + tmpl}, args...)
-	stdout, stderr, err := ts.exec(testGo, goArgs...)
-	if err != nil {
-		ts.fatalf("go list: %v\n%s%s", err, stdout, stderr)
-	}
-	if stdout != "" {
-		ts.fatalf("%s", stdout)
-	}
-}
-
-// stdout checks that the last go command standard output matches a regexp.
-func (ts *testScript) cmdStdout(want simpleStatus, args []string) {
-	scriptMatch(ts, want, args, ts.stdout, "stdout")
-}
-
-// stderr checks that the last go command standard output matches a regexp.
-func (ts *testScript) cmdStderr(want simpleStatus, args []string) {
-	scriptMatch(ts, want, args, ts.stderr, "stderr")
-}
-
-// grep checks that file content matches a regexp.
-// Like stdout/stderr and unlike Unix grep, it accepts Go regexp syntax.
-func (ts *testScript) cmdGrep(want simpleStatus, args []string) {
-	scriptMatch(ts, want, args, "", "grep")
-}
-
-// scriptMatch implements both stdout and stderr.
-func scriptMatch(ts *testScript, want simpleStatus, args []string, text, name string) {
-	if want == successOrFailure {
-		ts.fatalf("unsupported: %v %s", want, name)
-	}
-
-	n := 0
-	if len(args) >= 1 && strings.HasPrefix(args[0], "-count=") {
-		if want == failure {
-			ts.fatalf("cannot use -count= with negated match")
-		}
-		var err error
-		n, err = strconv.Atoi(args[0][len("-count="):])
-		if err != nil {
-			ts.fatalf("bad -count=: %v", err)
-		}
-		if n < 1 {
-			ts.fatalf("bad -count=: must be at least 1")
-		}
-		args = args[1:]
-	}
-	quiet := false
-	if len(args) >= 1 && args[0] == "-q" {
-		quiet = true
-		args = args[1:]
-	}
-
-	extraUsage := ""
-	wantArgs := 1
-	if name == "grep" {
-		extraUsage = " file"
-		wantArgs = 2
-	}
-	if len(args) != wantArgs {
-		ts.fatalf("usage: %s [-count=N] 'pattern'%s", name, extraUsage)
-	}
-
-	pattern := `(?m)` + args[0]
-	re, err := regexp.Compile(pattern)
-	if err != nil {
-		ts.fatalf("regexp.Compile(%q): %v", pattern, err)
-	}
-
-	isGrep := name == "grep"
-	if isGrep {
-		name = args[1] // for error messages
-		data, err := os.ReadFile(ts.mkabs(args[1]))
-		ts.check(err)
-		text = string(data)
-	}
-
-	// Matching against workdir would be misleading.
-	text = strings.ReplaceAll(text, ts.workdir, "$WORK")
-
-	switch want {
-	case failure:
-		if re.MatchString(text) {
-			if isGrep && !quiet {
-				fmt.Fprintf(&ts.log, "[%s]\n%s\n", name, text)
-			}
-			ts.fatalf("unexpected match for %#q found in %s: %s", pattern, name, re.FindString(text))
-		}
-
-	case success:
-		if !re.MatchString(text) {
-			if isGrep && !quiet {
-				fmt.Fprintf(&ts.log, "[%s]\n%s\n", name, text)
-			}
-			ts.fatalf("no match for %#q found in %s", pattern, name)
-		}
-		if n > 0 {
-			count := len(re.FindAllString(text, -1))
-			if count != n {
-				if isGrep && !quiet {
-					fmt.Fprintf(&ts.log, "[%s]\n%s\n", name, text)
-				}
-				ts.fatalf("have %d matches for %#q, want %d", count, pattern, n)
-			}
-		}
-	}
-}
-
-// stop stops execution of the test (marking it passed).
-func (ts *testScript) cmdStop(want simpleStatus, args []string) {
-	if want != success {
-		ts.fatalf("unsupported: %v stop", want)
-	}
-	if len(args) > 1 {
-		ts.fatalf("usage: stop [msg]")
-	}
-	if len(args) == 1 {
-		fmt.Fprintf(&ts.log, "stop: %s\n", args[0])
-	} else {
-		fmt.Fprintf(&ts.log, "stop\n")
-	}
-	ts.stopped = true
-}
-
-// symlink creates a symbolic link.
-func (ts *testScript) cmdSymlink(want simpleStatus, args []string) {
-	if want != success {
-		ts.fatalf("unsupported: %v symlink", want)
-	}
-	if len(args) != 3 || args[1] != "->" {
-		ts.fatalf("usage: symlink file -> target")
-	}
-	// Note that the link target args[2] is not interpreted with mkabs:
-	// it will be interpreted relative to the directory file is in.
-	ts.check(os.Symlink(args[2], ts.mkabs(args[0])))
-}
-
-// wait waits for background commands to exit, setting stderr and stdout to their result.
-func (ts *testScript) cmdWait(want simpleStatus, args []string) {
-	if want != success {
-		ts.fatalf("unsupported: %v wait", want)
-	}
-	if len(args) > 0 {
-		ts.fatalf("usage: wait")
-	}
-
-	var stdouts, stderrs []string
-	for _, bg := range ts.background {
-		<-bg.done
-
-		args := append([]string{filepath.Base(bg.args[0])}, bg.args[1:]...)
-		fmt.Fprintf(&ts.log, "[background] %s: %v\n", strings.Join(args, " "), bg.err)
-
-		cmdStdout := bg.stdout.String()
-		if cmdStdout != "" {
-			fmt.Fprintf(&ts.log, "[stdout]\n%s", cmdStdout)
-			stdouts = append(stdouts, cmdStdout)
-		}
-
-		cmdStderr := bg.stderr.String()
-		if cmdStderr != "" {
-			fmt.Fprintf(&ts.log, "[stderr]\n%s", cmdStderr)
-			stderrs = append(stderrs, cmdStderr)
-		}
-
-		ts.checkCmd(bg)
-	}
-
-	ts.stdout = strings.Join(stdouts, "")
-	ts.stderr = strings.Join(stderrs, "")
-	ts.background = nil
-}
-
-// Helpers for command implementations.
-
-// abbrev abbreviates the actual work directory in the string s to the literal string "$WORK".
-func (ts *testScript) abbrev(s string) string {
-	s = strings.ReplaceAll(s, ts.workdir, "$WORK")
-	if *testWork {
-		// Expose actual $WORK value in environment dump on first line of work script,
-		// so that the user can find out what directory -testwork left behind.
-		s = "WORK=" + ts.workdir + "\n" + strings.TrimPrefix(s, "WORK=$WORK\n")
-	}
-	return s
-}
-
-// check calls ts.fatalf if err != nil.
-func (ts *testScript) check(err error) {
-	if err != nil {
-		ts.fatalf("%v", err)
-	}
-}
-
-func (ts *testScript) checkCmd(bg *backgroundCmd) {
-	select {
-	case <-bg.done:
-	default:
-		panic("checkCmd called when not done")
-	}
-
-	if bg.err == nil {
-		if bg.want == failure {
-			ts.fatalf("unexpected command success")
-		}
-		return
-	}
-
-	if errors.Is(bg.err, context.DeadlineExceeded) {
-		ts.fatalf("test timed out while running command")
-	}
-
-	if errors.Is(bg.err, context.Canceled) {
-		// The process was still running at the end of the test.
-		// The test must not depend on its exit status.
-		if bg.want != successOrFailure {
-			ts.fatalf("unexpected background command remaining at test end")
-		}
-		return
-	}
-
-	if bg.want == success {
-		ts.fatalf("unexpected command failure")
-	}
-}
-
-// exec runs the given command line (an actual subprocess, not simulated)
-// in ts.cd with environment ts.env and then returns collected standard output and standard error.
-func (ts *testScript) exec(command string, args ...string) (stdout, stderr string, err error) {
-	bg, err := ts.startBackground(success, command, args...)
-	if err != nil {
-		return "", "", err
-	}
-	<-bg.done
-	return bg.stdout.String(), bg.stderr.String(), bg.err
-}
-
-// startBackground starts the given command line (an actual subprocess, not simulated)
-// in ts.cd with environment ts.env.
-func (ts *testScript) startBackground(want simpleStatus, command string, args ...string) (*backgroundCmd, error) {
-	done := make(chan struct{})
-	bg := &backgroundCmd{
-		want: want,
-		args: append([]string{command}, args...),
-		done: done,
-	}
-
-	// Use the script's PATH to look up the command if it contains a separator
-	// instead of the test process's PATH (see lookPath).
-	// Don't use filepath.Clean, since that changes "./foo" to "foo".
-	command = filepath.FromSlash(command)
-	if !strings.Contains(command, string(filepath.Separator)) {
-		var err error
-		command, err = ts.lookPath(command)
-		if err != nil {
-			return nil, err
-		}
-	}
-	cmd := exec.Command(command, args...)
-	cmd.Dir = ts.cd
-	cmd.Env = append(ts.env, "PWD="+ts.cd)
-	cmd.Stdout = &bg.stdout
-	cmd.Stderr = &bg.stderr
-	if err := cmd.Start(); err != nil {
-		return nil, err
-	}
-
-	go func() {
-		bg.err = waitOrStop(ts.ctx, cmd, quitSignal(), ts.gracePeriod)
-		close(done)
-	}()
-	return bg, nil
-}
-
-// lookPath is (roughly) like exec.LookPath, but it uses the test script's PATH
-// instead of the test process's PATH to find the executable. We don't change
-// the test process's PATH since it may run scripts in parallel.
-func (ts *testScript) lookPath(command string) (string, error) {
-	var strEqual func(string, string) bool
-	if runtime.GOOS == "windows" || runtime.GOOS == "darwin" {
-		// Using GOOS as a proxy for case-insensitive file system.
-		strEqual = strings.EqualFold
-	} else {
-		strEqual = func(a, b string) bool { return a == b }
-	}
-
-	var pathExt []string
-	var searchExt bool
-	var isExecutable func(os.FileInfo) bool
-	if runtime.GOOS == "windows" {
-		// Use the test process's PathExt instead of the script's.
-		// If PathExt is set in the command's environment, cmd.Start fails with
-		// "parameter is invalid". Not sure why.
-		// If the command already has an extension in PathExt (like "cmd.exe")
-		// don't search for other extensions (not "cmd.bat.exe").
-		pathExt = strings.Split(os.Getenv("PathExt"), string(filepath.ListSeparator))
-		searchExt = true
-		cmdExt := filepath.Ext(command)
-		for _, ext := range pathExt {
-			if strEqual(cmdExt, ext) {
-				searchExt = false
-				break
-			}
-		}
-		isExecutable = func(fi os.FileInfo) bool {
-			return fi.Mode().IsRegular()
-		}
-	} else {
-		isExecutable = func(fi os.FileInfo) bool {
-			return fi.Mode().IsRegular() && fi.Mode().Perm()&0111 != 0
-		}
-	}
-
-	for _, dir := range strings.Split(ts.envMap[pathEnvName()], string(filepath.ListSeparator)) {
-		if searchExt {
-			ents, err := os.ReadDir(dir)
-			if err != nil {
-				continue
-			}
-			for _, ent := range ents {
-				for _, ext := range pathExt {
-					if !ent.IsDir() && strEqual(ent.Name(), command+ext) {
-						return dir + string(filepath.Separator) + ent.Name(), nil
-					}
-				}
-			}
-		} else {
-			path := dir + string(filepath.Separator) + command
-			if fi, err := os.Stat(path); err == nil && isExecutable(fi) {
-				return path, nil
-			}
-		}
-	}
-	return "", &exec.Error{Name: command, Err: exec.ErrNotFound}
-}
-
-// waitOrStop waits for the already-started command cmd by calling its Wait method.
-//
-// If cmd does not return before ctx is done, waitOrStop sends it the given interrupt signal.
-// If killDelay is positive, waitOrStop waits that additional period for Wait to return before sending os.Kill.
-//
-// This function is copied from the one added to x/playground/internal in
-// http://golang.org/cl/228438.
-func waitOrStop(ctx context.Context, cmd *exec.Cmd, interrupt os.Signal, killDelay time.Duration) error {
-	if cmd.Process == nil {
-		panic("waitOrStop called with a nil cmd.Process — missing Start call?")
-	}
-	if interrupt == nil {
-		panic("waitOrStop requires a non-nil interrupt signal")
-	}
-
-	errc := make(chan error)
-	go func() {
-		select {
-		case errc <- nil:
-			return
-		case <-ctx.Done():
-		}
-
-		err := cmd.Process.Signal(interrupt)
-		if err == nil {
-			err = ctx.Err() // Report ctx.Err() as the reason we interrupted.
-		} else if err == os.ErrProcessDone {
-			errc <- nil
-			return
-		}
-
-		if killDelay > 0 {
-			timer := time.NewTimer(killDelay)
-			select {
-			// Report ctx.Err() as the reason we interrupted the process...
-			case errc <- ctx.Err():
-				timer.Stop()
-				return
-			// ...but after killDelay has elapsed, fall back to a stronger signal.
-			case <-timer.C:
-			}
-
-			// Wait still hasn't returned.
-			// Kill the process harder to make sure that it exits.
-			//
-			// Ignore any error: if cmd.Process has already terminated, we still
-			// want to send ctx.Err() (or the error from the Interrupt call)
-			// to properly attribute the signal that may have terminated it.
-			_ = cmd.Process.Kill()
-		}
-
-		errc <- err
-	}()
-
-	waitErr := cmd.Wait()
-	if interruptErr := <-errc; interruptErr != nil {
-		return interruptErr
-	}
-	return waitErr
-}
-
-// expand applies environment variable expansion to the string s.
-func (ts *testScript) expand(s string, inRegexp bool) string {
-	return os.Expand(s, func(key string) string {
-		e := ts.envMap[key]
-		if inRegexp {
-			// Replace workdir with $WORK, since we have done the same substitution in
-			// the text we're about to compare against.
-			e = strings.ReplaceAll(e, ts.workdir, "$WORK")
-
-			// Quote to literal strings: we want paths like C:\work\go1.4 to remain
-			// paths rather than regular expressions.
-			e = regexp.QuoteMeta(e)
-		}
-		return e
-	})
-}
-
-// fatalf aborts the test with the given failure message.
-func (ts *testScript) fatalf(format string, args ...any) {
-	fmt.Fprintf(&ts.log, "FAIL: %s:%d: %s\n", ts.file, ts.lineno, fmt.Sprintf(format, args...))
-	ts.t.FailNow()
-}
-
-// mkabs interprets file relative to the test script's current directory
-// and returns the corresponding absolute path.
-func (ts *testScript) mkabs(file string) string {
-	if filepath.IsAbs(file) {
-		return file
-	}
-	return filepath.Join(ts.cd, file)
-}
-
-// A condition guards execution of a command.
-type condition struct {
-	want bool
-	tag  string
-}
-
-// A command is a complete command parsed from a script.
-type command struct {
-	want  simpleStatus
-	conds []condition // all must be satisfied
-	name  string      // the name of the command; must be non-empty
-	args  []string    // shell-expanded arguments following name
-}
-
-// parse parses a single line as a list of space-separated arguments
-// subject to environment variable expansion (but not resplitting).
-// Single quotes around text disable splitting and expansion.
-// To embed a single quote, double it:
-//
-//	'Don''t communicate by sharing memory.'
-func (ts *testScript) parse(line string) command {
-	ts.line = line
-
-	var (
-		cmd      command
-		arg      string  // text of current arg so far (need to add line[start:i])
-		start    = -1    // if >= 0, position where current arg text chunk starts
-		quoted   = false // currently processing quoted text
-		isRegexp = false // currently processing unquoted regular expression
-	)
-
-	flushArg := func() {
-		defer func() {
-			arg = ""
-			start = -1
-		}()
-
-		if cmd.name != "" {
-			cmd.args = append(cmd.args, arg)
-			// Commands take only one regexp argument (after the optional flags),
-			// so no subsequent args are regexps. Liberally assume an argument that
-			// starts with a '-' is a flag.
-			if len(arg) == 0 || arg[0] != '-' {
-				isRegexp = false
-			}
-			return
-		}
-
-		// Command prefix ! means negate the expectations about this command:
-		// go command should fail, match should not be found, etc.
-		// Prefix ? means allow either success or failure.
-		switch want := simpleStatus(arg); want {
-		case failure, successOrFailure:
-			if cmd.want != "" {
-				ts.fatalf("duplicated '!' or '?' token")
-			}
-			cmd.want = want
-			return
-		}
-
-		// Command prefix [cond] means only run this command if cond is satisfied.
-		if strings.HasPrefix(arg, "[") && strings.HasSuffix(arg, "]") {
-			want := true
-			arg = strings.TrimSpace(arg[1 : len(arg)-1])
-			if strings.HasPrefix(arg, "!") {
-				want = false
-				arg = strings.TrimSpace(arg[1:])
-			}
-			if arg == "" {
-				ts.fatalf("empty condition")
-			}
-			cmd.conds = append(cmd.conds, condition{want: want, tag: arg})
-			return
-		}
-
-		cmd.name = arg
-		isRegexp = regexpCmd[cmd.name]
-	}
-
-	for i := 0; ; i++ {
-		if !quoted && (i >= len(line) || line[i] == ' ' || line[i] == '\t' || line[i] == '\r' || line[i] == '#') {
-			// Found arg-separating space.
-			if start >= 0 {
-				arg += ts.expand(line[start:i], isRegexp)
-				flushArg()
-			}
-			if i >= len(line) || line[i] == '#' {
-				break
-			}
-			continue
-		}
-		if i >= len(line) {
-			ts.fatalf("unterminated quoted argument")
-		}
-		if line[i] == '\'' {
-			if !quoted {
-				// starting a quoted chunk
-				if start >= 0 {
-					arg += ts.expand(line[start:i], isRegexp)
-				}
-				start = i + 1
-				quoted = true
-				continue
-			}
-			// 'foo''bar' means foo'bar, like in rc shell and Pascal.
-			if i+1 < len(line) && line[i+1] == '\'' {
-				arg += line[start:i]
-				start = i + 1
-				i++ // skip over second ' before next iteration
-				continue
-			}
-			// ending a quoted chunk
-			arg += line[start:i]
-			start = i + 1
-			quoted = false
-			continue
-		}
-		// found character worth saving; make sure we're saving
-		if start < 0 {
-			start = i
-		}
-	}
-	return cmd
-}
-
 // updateSum runs 'go mod tidy', 'go list -mod=mod -m all', or
 // 'go list -mod=mod all' in the test's current directory if a file named
 // "go.mod" is present after the archive has been extracted. updateSum modifies
 // archive and returns true if go.mod or go.sum were changed.
-func (ts *testScript) updateSum(archive *txtar.Archive) (rewrite bool) {
+func updateSum(t testing.TB, e *script.Engine, s *script.State, archive *txtar.Archive) (rewrite bool) {
 	gomodIdx, gosumIdx := -1, -1
 	for i := range archive.Files {
 		switch archive.Files[i].Name {
@@ -1521,29 +291,39 @@
 		return false
 	}
 
+	var cmd string
 	switch *testSum {
 	case "tidy":
-		ts.cmdGo(success, []string{"mod", "tidy"})
+		cmd = "go mod tidy"
 	case "listm":
-		ts.cmdGo(success, []string{"list", "-m", "-mod=mod", "all"})
+		cmd = "go list -m -mod=mod all"
 	case "listall":
-		ts.cmdGo(success, []string{"list", "-mod=mod", "all"})
+		cmd = "go list -mod=mod all"
 	default:
-		ts.t.Fatalf(`unknown value for -testsum %q; may be "tidy", "listm", or "listall"`, *testSum)
+		t.Fatalf(`unknown value for -testsum %q; may be "tidy", "listm", or "listall"`, *testSum)
 	}
 
-	newGomodData, err := os.ReadFile(filepath.Join(ts.cd, "go.mod"))
+	log := new(strings.Builder)
+	err := e.Execute(s, "updateSum", bufio.NewReader(strings.NewReader(cmd)), log)
+	if log.Len() > 0 {
+		t.Logf("%s", log)
+	}
 	if err != nil {
-		ts.t.Fatalf("reading go.mod after -testsum: %v", err)
+		t.Fatal(err)
+	}
+
+	newGomodData, err := os.ReadFile(s.Path("go.mod"))
+	if err != nil {
+		t.Fatalf("reading go.mod after -testsum: %v", err)
 	}
 	if !bytes.Equal(newGomodData, archive.Files[gomodIdx].Data) {
 		archive.Files[gomodIdx].Data = newGomodData
 		rewrite = true
 	}
 
-	newGosumData, err := os.ReadFile(filepath.Join(ts.cd, "go.sum"))
+	newGosumData, err := os.ReadFile(s.Path("go.sum"))
 	if err != nil && !os.IsNotExist(err) {
-		ts.t.Fatalf("reading go.sum after -testsum: %v", err)
+		t.Fatalf("reading go.sum after -testsum: %v", err)
 	}
 	switch {
 	case os.IsNotExist(err) && gosumIdx >= 0:
@@ -1564,106 +344,3 @@
 	}
 	return rewrite
 }
-
-// diff returns a formatted diff of the two texts,
-// showing the entire text and the minimum line-level
-// additions and removals to turn text1 into text2.
-// (That is, lines only in text1 appear with a leading -,
-// and lines only in text2 appear with a leading +.)
-func diff(text1, text2 string) string {
-	if text1 != "" && !strings.HasSuffix(text1, "\n") {
-		text1 += "(missing final newline)"
-	}
-	lines1 := strings.Split(text1, "\n")
-	lines1 = lines1[:len(lines1)-1] // remove empty string after final line
-	if text2 != "" && !strings.HasSuffix(text2, "\n") {
-		text2 += "(missing final newline)"
-	}
-	lines2 := strings.Split(text2, "\n")
-	lines2 = lines2[:len(lines2)-1] // remove empty string after final line
-
-	// Naive dynamic programming algorithm for edit distance.
-	// https://en.wikipedia.org/wiki/Wagner–Fischer_algorithm
-	// dist[i][j] = edit distance between lines1[:len(lines1)-i] and lines2[:len(lines2)-j]
-	// (The reversed indices make following the minimum cost path
-	// visit lines in the same order as in the text.)
-	dist := make([][]int, len(lines1)+1)
-	for i := range dist {
-		dist[i] = make([]int, len(lines2)+1)
-		if i == 0 {
-			for j := range dist[0] {
-				dist[0][j] = j
-			}
-			continue
-		}
-		for j := range dist[i] {
-			if j == 0 {
-				dist[i][0] = i
-				continue
-			}
-			cost := dist[i][j-1] + 1
-			if cost > dist[i-1][j]+1 {
-				cost = dist[i-1][j] + 1
-			}
-			if lines1[len(lines1)-i] == lines2[len(lines2)-j] {
-				if cost > dist[i-1][j-1] {
-					cost = dist[i-1][j-1]
-				}
-			}
-			dist[i][j] = cost
-		}
-	}
-
-	var buf strings.Builder
-	i, j := len(lines1), len(lines2)
-	for i > 0 || j > 0 {
-		cost := dist[i][j]
-		if i > 0 && j > 0 && cost == dist[i-1][j-1] && lines1[len(lines1)-i] == lines2[len(lines2)-j] {
-			fmt.Fprintf(&buf, " %s\n", lines1[len(lines1)-i])
-			i--
-			j--
-		} else if i > 0 && cost == dist[i-1][j]+1 {
-			fmt.Fprintf(&buf, "-%s\n", lines1[len(lines1)-i])
-			i--
-		} else {
-			fmt.Fprintf(&buf, "+%s\n", lines2[len(lines2)-j])
-			j--
-		}
-	}
-	return buf.String()
-}
-
-var diffTests = []struct {
-	text1 string
-	text2 string
-	diff  string
-}{
-	{"a b c", "a b d e f", "a b -c +d +e +f"},
-	{"", "a b c", "+a +b +c"},
-	{"a b c", "", "-a -b -c"},
-	{"a b c", "d e f", "-a -b -c +d +e +f"},
-	{"a b c d e f", "a b d e f", "a b -c d e f"},
-	{"a b c e f", "a b c d e f", "a b c +d e f"},
-}
-
-func TestDiff(t *testing.T) {
-	t.Parallel()
-
-	for _, tt := range diffTests {
-		// Turn spaces into \n.
-		text1 := strings.ReplaceAll(tt.text1, " ", "\n")
-		if text1 != "" {
-			text1 += "\n"
-		}
-		text2 := strings.ReplaceAll(tt.text2, " ", "\n")
-		if text2 != "" {
-			text2 += "\n"
-		}
-		out := diff(text1, text2)
-		// Cut final \n, cut spaces, turn remaining \n into spaces.
-		out = strings.ReplaceAll(strings.ReplaceAll(strings.TrimSuffix(out, "\n"), " ", ""), "\n", " ")
-		if out != tt.diff {
-			t.Errorf("diff(%q, %q) = %q, want %q", text1, text2, out, tt.diff)
-		}
-	}
-}
diff --git a/src/cmd/go/scriptcmds_test.go b/src/cmd/go/scriptcmds_test.go
new file mode 100644
index 0000000..db5e6ca
--- /dev/null
+++ b/src/cmd/go/scriptcmds_test.go
@@ -0,0 +1,109 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main_test
+
+import (
+	"cmd/go/internal/script"
+	"cmd/go/internal/script/scripttest"
+	"cmd/go/internal/work"
+	"errors"
+	"fmt"
+	"os"
+	"os/exec"
+	"strings"
+	"time"
+)
+
+func scriptCommands(interrupt os.Signal, waitDelay time.Duration) map[string]script.Cmd {
+	cmds := scripttest.DefaultCmds()
+
+	// Customize the "exec" interrupt signal and grace period.
+	var cancel func(cmd *exec.Cmd) error
+	if interrupt != nil {
+		cancel = func(cmd *exec.Cmd) error {
+			return cmd.Process.Signal(interrupt)
+		}
+	}
+
+	cmdExec := script.Exec(cancel, waitDelay)
+	cmds["exec"] = cmdExec
+
+	add := func(name string, cmd script.Cmd) {
+		if _, ok := cmds[name]; ok {
+			panic(fmt.Sprintf("command %q is already registered", name))
+		}
+		cmds[name] = cmd
+	}
+
+	add("cc", scriptCC(cmdExec))
+	cmdGo := scriptGo(cancel, waitDelay)
+	add("go", cmdGo)
+	add("stale", scriptStale(cmdGo))
+
+	return cmds
+}
+
+// scriptCC runs the C compiler along with platform specific options.
+func scriptCC(cmdExec script.Cmd) script.Cmd {
+	return script.Command(
+		script.CmdUsage{
+			Summary: "run the platform C compiler",
+			Args:    "args...",
+		},
+		func(s *script.State, args ...string) (script.WaitFunc, error) {
+			b := work.NewBuilder(s.Getwd())
+			wait, err := cmdExec.Run(s, append(b.GccCmd(".", ""), args...)...)
+			if err != nil {
+				return wait, err
+			}
+			waitAndClean := func(s *script.State) (stdout, stderr string, err error) {
+				stdout, stderr, err = wait(s)
+				if closeErr := b.Close(); err == nil {
+					err = closeErr
+				}
+				return stdout, stderr, err
+			}
+			return waitAndClean, nil
+		})
+}
+
+// scriptGo runs the go command.
+func scriptGo(cancel func(*exec.Cmd) error, waitDelay time.Duration) script.Cmd {
+	return script.Program(testGo, cancel, waitDelay)
+}
+
+// scriptStale checks that the named build targets are stale.
+func scriptStale(cmdGo script.Cmd) script.Cmd {
+	return script.Command(
+		script.CmdUsage{
+			Summary: "check that build targets are stale",
+			Args:    "target...",
+		},
+		func(s *script.State, args ...string) (script.WaitFunc, error) {
+			if len(args) == 0 {
+				return nil, script.ErrUsage
+			}
+			tmpl := "{{if .Error}}{{.ImportPath}}: {{.Error.Err}}" +
+				"{{else}}{{if not .Stale}}{{.ImportPath}} ({{.Target}}) is not stale{{end}}" +
+				"{{end}}"
+
+			wait, err := cmdGo.Run(s, append([]string{"list", "-e", "-f=" + tmpl}, args...)...)
+			if err != nil {
+				return nil, err
+			}
+
+			stdout, stderr, err := wait(s)
+			if len(stderr) != 0 {
+				s.Logf("%s", stderr)
+			}
+			if err != nil {
+				return nil, err
+			}
+			if out := strings.TrimSpace(stdout); out != "" {
+				return nil, errors.New(out)
+			}
+			return nil, nil
+		})
+}
diff --git a/src/cmd/go/scriptconds_test.go b/src/cmd/go/scriptconds_test.go
new file mode 100644
index 0000000..5163750
--- /dev/null
+++ b/src/cmd/go/scriptconds_test.go
@@ -0,0 +1,172 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main_test
+
+import (
+	"cmd/go/internal/cfg"
+	"cmd/go/internal/script"
+	"cmd/go/internal/script/scripttest"
+	"errors"
+	"fmt"
+	"internal/buildcfg"
+	"internal/platform"
+	"internal/testenv"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"runtime"
+	"runtime/debug"
+	"strings"
+)
+
+func scriptConditions() map[string]script.Cond {
+	conds := scripttest.DefaultConds()
+
+	add := func(name string, cond script.Cond) {
+		if _, ok := conds[name]; ok {
+			panic(fmt.Sprintf("condition %q is already registered", name))
+		}
+		conds[name] = cond
+	}
+
+	lazyBool := func(summary string, f func() bool) script.Cond {
+		return script.OnceCondition(summary, func() (bool, error) { return f(), nil })
+	}
+
+	add("abscc", script.Condition("default $CC path is absolute and exists", defaultCCIsAbsolute))
+	add("asan", sysCondition("-asan", platform.ASanSupported, true))
+	add("buildmode", script.PrefixCondition("go supports -buildmode=<suffix>", hasBuildmode))
+	add("case-sensitive", script.OnceCondition("$WORK filesystem is case-sensitive", isCaseSensitive))
+	add("cgo", script.BoolCondition("host CGO_ENABLED", canCgo))
+	add("cross", script.BoolCondition("cmd/go GOOS/GOARCH != GOHOSTOS/GOHOSTARCH", goHostOS != runtime.GOOS || goHostArch != runtime.GOARCH))
+	add("fuzz", sysCondition("-fuzz", platform.FuzzSupported, false))
+	add("fuzz-instrumented", sysCondition("-fuzz with instrumentation", platform.FuzzInstrumented, false))
+	add("git", lazyBool("the 'git' executable exists and provides the standard CLI", hasWorkingGit))
+	add("GODEBUG", script.PrefixCondition("GODEBUG contains <suffix>", hasGodebug))
+	add("GOEXPERIMENT", script.PrefixCondition("GOEXPERIMENT <suffix> is enabled", hasGoexperiment))
+	add("link", lazyBool("testenv.HasLink()", testenv.HasLink))
+	add("mismatched-goroot", script.Condition("test's GOROOT_FINAL does not match the real GOROOT", isMismatchedGoroot))
+	add("msan", sysCondition("-msan", platform.MSanSupported, true))
+	add("net", lazyBool("testenv.HasExternalNetwork()", testenv.HasExternalNetwork))
+	add("race", sysCondition("-race", platform.RaceDetectorSupported, true))
+	add("symlink", lazyBool("testenv.HasSymlink()", testenv.HasSymlink))
+	add("trimpath", script.OnceCondition("test binary was built with -trimpath", isTrimpath))
+
+	return conds
+}
+
+func defaultCCIsAbsolute(s *script.State) (bool, error) {
+	GOOS, _ := s.LookupEnv("GOOS")
+	GOARCH, _ := s.LookupEnv("GOARCH")
+	defaultCC := cfg.DefaultCC(GOOS, GOARCH)
+	if filepath.IsAbs(defaultCC) {
+		if _, err := exec.LookPath(defaultCC); err == nil {
+			return true, nil
+		}
+	}
+	return false, nil
+}
+
+func isMismatchedGoroot(s *script.State) (bool, error) {
+	gorootFinal, _ := s.LookupEnv("GOROOT_FINAL")
+	if gorootFinal == "" {
+		gorootFinal, _ = s.LookupEnv("GOROOT")
+	}
+	return gorootFinal != testGOROOT, nil
+}
+
+func sysCondition(flag string, f func(goos, goarch string) bool, needsCgo bool) script.Cond {
+	return script.Condition(
+		"GOOS/GOARCH supports "+flag,
+		func(s *script.State) (bool, error) {
+			GOOS, _ := s.LookupEnv("GOOS")
+			GOARCH, _ := s.LookupEnv("GOARCH")
+			cross := goHostOS != GOOS || goHostArch != GOARCH
+			return (!needsCgo || (canCgo && !cross)) && f(GOOS, GOARCH), nil
+		})
+}
+
+func hasBuildmode(s *script.State, mode string) (bool, error) {
+	GOOS, _ := s.LookupEnv("GOOS")
+	GOARCH, _ := s.LookupEnv("GOARCH")
+	return platform.BuildModeSupported(runtime.Compiler, mode, GOOS, GOARCH), nil
+}
+
+func hasGodebug(s *script.State, value string) (bool, error) {
+	godebug, _ := s.LookupEnv("GODEBUG")
+	for _, p := range strings.Split(godebug, ",") {
+		if strings.TrimSpace(p) == value {
+			return true, nil
+		}
+	}
+	return false, nil
+}
+
+func hasGoexperiment(s *script.State, value string) (bool, error) {
+	GOOS, _ := s.LookupEnv("GOOS")
+	GOARCH, _ := s.LookupEnv("GOARCH")
+	goexp, _ := s.LookupEnv("GOEXPERIMENT")
+	flags, err := buildcfg.ParseGOEXPERIMENT(GOOS, GOARCH, goexp)
+	if err != nil {
+		return false, err
+	}
+	for _, exp := range flags.All() {
+		if value == exp {
+			return true, nil
+		}
+		if strings.TrimPrefix(value, "no") == strings.TrimPrefix(exp, "no") {
+			return false, nil
+		}
+	}
+	return false, fmt.Errorf("unrecognized GOEXPERIMENT %q", value)
+}
+
+func isCaseSensitive() (bool, error) {
+	tmpdir, err := os.MkdirTemp(testTmpDir, "case-sensitive")
+	if err != nil {
+		return false, fmt.Errorf("failed to create directory to determine case-sensitivity: %w", err)
+	}
+	defer os.RemoveAll(tmpdir)
+
+	fcap := filepath.Join(tmpdir, "FILE")
+	if err := os.WriteFile(fcap, []byte{}, 0644); err != nil {
+		return false, fmt.Errorf("error writing file to determine case-sensitivity: %w", err)
+	}
+
+	flow := filepath.Join(tmpdir, "file")
+	_, err = os.ReadFile(flow)
+	switch {
+	case err == nil:
+		return false, nil
+	case os.IsNotExist(err):
+		return true, nil
+	default:
+		return false, fmt.Errorf("unexpected error reading file when determining case-sensitivity: %w", err)
+	}
+}
+
+func isTrimpath() (bool, error) {
+	info, _ := debug.ReadBuildInfo()
+	if info == nil {
+		return false, errors.New("missing build info")
+	}
+
+	for _, s := range info.Settings {
+		if s.Key == "-trimpath" && s.Value == "true" {
+			return true, nil
+		}
+	}
+	return false, nil
+}
+
+func hasWorkingGit() bool {
+	if runtime.GOOS == "plan9" {
+		// The Git command is usually not the real Git on Plan 9.
+		// See https://golang.org/issues/29640.
+		return false
+	}
+	_, err := exec.LookPath("git")
+	return err == nil
+}
diff --git a/src/cmd/go/scriptreadme_test.go b/src/cmd/go/scriptreadme_test.go
new file mode 100644
index 0000000..fde1e8e
--- /dev/null
+++ b/src/cmd/go/scriptreadme_test.go
@@ -0,0 +1,271 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main_test
+
+import (
+	"bytes"
+	"cmd/go/internal/script"
+	"flag"
+	"internal/diff"
+	"internal/testenv"
+	"os"
+	"strings"
+	"testing"
+	"text/template"
+)
+
+var fixReadme = flag.Bool("fixreadme", false, "if true, update ../testdata/script/README")
+
+func checkScriptReadme(t *testing.T, engine *script.Engine, env []string) {
+	var args struct {
+		Language   string
+		Commands   string
+		Conditions string
+	}
+
+	cmds := new(strings.Builder)
+	if err := engine.ListCmds(cmds, true); err != nil {
+		t.Fatal(err)
+	}
+	args.Commands = cmds.String()
+
+	conds := new(strings.Builder)
+	if err := engine.ListConds(conds, nil); err != nil {
+		t.Fatal(err)
+	}
+	args.Conditions = conds.String()
+
+	if !testenv.HasExec() {
+		t.Skipf("updating script README requires os/exec")
+	}
+
+	doc := new(strings.Builder)
+	cmd := testenv.Command(t, testGo, "doc", "cmd/go/internal/script")
+	cmd.Env = env
+	cmd.Stdout = doc
+	if err := cmd.Run(); err != nil {
+		t.Fatal(cmd, ":", err)
+	}
+	_, lang, ok := strings.Cut(doc.String(), "# Script Language\n\n")
+	if !ok {
+		t.Fatalf("%q did not include Script Language section", cmd)
+	}
+	lang, _, ok = strings.Cut(lang, "\n\nvar ")
+	if !ok {
+		t.Fatalf("%q did not include vars after Script Language section", cmd)
+	}
+	args.Language = lang
+
+	tmpl := template.Must(template.New("README").Parse(readmeTmpl[1:]))
+	buf := new(bytes.Buffer)
+	if err := tmpl.Execute(buf, args); err != nil {
+		t.Fatal(err)
+	}
+
+	const readmePath = "testdata/script/README"
+	old, err := os.ReadFile(readmePath)
+	if err != nil {
+		t.Fatal(err)
+	}
+	diff := diff.Diff(readmePath, old, "readmeTmpl", buf.Bytes())
+	if diff == nil {
+		t.Logf("%s is up to date.", readmePath)
+		return
+	}
+
+	if *fixReadme {
+		if err := os.WriteFile(readmePath, buf.Bytes(), 0666); err != nil {
+			t.Fatal(err)
+		}
+		t.Logf("wrote %d bytes to %s", buf.Len(), readmePath)
+	} else {
+		t.Logf("\n%s", diff)
+		t.Errorf("%s is stale. To update, run 'go generate cmd/go'.", readmePath)
+	}
+}
+
+const readmeTmpl = `
+This file is generated by 'go generate cmd/go'. DO NOT EDIT.
+
+This directory holds test scripts *.txt run during 'go test cmd/go'.
+To run a specific script foo.txt
+
+	go test cmd/go -run=Script/^foo$
+
+In general script files should have short names: a few words, not whole sentences.
+The first word should be the general category of behavior being tested,
+often the name of a go subcommand (list, build, test, ...) or concept (vendor, pattern).
+
+Each script is a text archive (go doc internal/txtar).
+The script begins with an actual command script to run
+followed by the content of zero or more supporting files to
+create in the script's temporary file system before it starts executing.
+
+As an example, run_hello.txt says:
+
+	# hello world
+	go run hello.go
+	stderr 'hello world'
+	! stdout .
+
+	-- hello.go --
+	package main
+	func main() { println("hello world") }
+
+Each script runs in a fresh temporary work directory tree, available to scripts as $WORK.
+Scripts also have access to other environment variables, including:
+
+	GOARCH=<target GOARCH>
+	GOCACHE=<actual GOCACHE being used outside the test>
+	GOEXE=<executable file suffix: .exe on Windows, empty on other systems>
+	GOOS=<target GOOS>
+	GOPATH=$WORK/gopath
+	GOPROXY=<local module proxy serving from cmd/go/testdata/mod>
+	GOROOT=<actual GOROOT>
+	GOROOT_FINAL=<actual GOROOT_FINAL>
+	TESTGO_GOROOT=<GOROOT used to build cmd/go, for use in tests that may change GOROOT>
+	HOME=/no-home
+	PATH=<actual PATH>
+	TMPDIR=$WORK/tmp
+	GODEBUG=<actual GODEBUG>
+	devnull=<value of os.DevNull>
+	goversion=<current Go version; for example, 1.12>
+
+On Plan 9, the variables $path and $home are set instead of $PATH and $HOME.
+On Windows, the variables $USERPROFILE and $TMP are set instead of
+$HOME and $TMPDIR.
+
+The lines at the top of the script are a sequence of commands to be executed by
+a small script engine configured in ../../script_test.go (not the system shell).
+
+The scripts' supporting files are unpacked relative to $GOPATH/src
+(aka $WORK/gopath/src) and then the script begins execution in that directory as
+well. Thus the example above runs in $WORK/gopath/src with GOPATH=$WORK/gopath
+and $WORK/gopath/src/hello.go containing the listed contents.
+
+{{.Language}}
+
+When TestScript runs a script and the script fails, by default TestScript shows
+the execution of the most recent phase of the script (since the last # comment)
+and only shows the # comments for earlier phases. For example, here is a
+multi-phase script with a bug in it:
+
+	# GOPATH with p1 in d2, p2 in d2
+	env GOPATH=$WORK${/}d1${:}$WORK${/}d2
+
+	# build & install p1
+	env
+	go install -i p1
+	! stale p1
+	! stale p2
+
+	# modify p2 - p1 should appear stale
+	cp $WORK/p2x.go $WORK/d2/src/p2/p2.go
+	stale p1 p2
+
+	# build & install p1 again
+	go install -i p11
+	! stale p1
+	! stale p2
+
+	-- $WORK/d1/src/p1/p1.go --
+	package p1
+	import "p2"
+	func F() { p2.F() }
+	-- $WORK/d2/src/p2/p2.go --
+	package p2
+	func F() {}
+	-- $WORK/p2x.go --
+	package p2
+	func F() {}
+	func G() {}
+
+The bug is that the final phase installs p11 instead of p1. The test failure looks like:
+
+	$ go test -run=Script
+	--- FAIL: TestScript (3.75s)
+	    --- FAIL: TestScript/install_rebuild_gopath (0.16s)
+	        script_test.go:223:
+	            # GOPATH with p1 in d2, p2 in d2 (0.000s)
+	            # build & install p1 (0.087s)
+	            # modify p2 - p1 should appear stale (0.029s)
+	            # build & install p1 again (0.022s)
+	            > go install -i p11
+	            [stderr]
+	            can't load package: package p11: cannot find package "p11" in any of:
+	            	/Users/rsc/go/src/p11 (from $GOROOT)
+	            	$WORK/d1/src/p11 (from $GOPATH)
+	            	$WORK/d2/src/p11
+	            [exit status 1]
+	            FAIL: unexpected go command failure
+
+	        script_test.go:73: failed at testdata/script/install_rebuild_gopath.txt:15 in $WORK/gopath/src
+
+	FAIL
+	exit status 1
+	FAIL	cmd/go	4.875s
+	$
+
+Note that the commands in earlier phases have been hidden, so that the relevant
+commands are more easily found, and the elapsed time for a completed phase
+is shown next to the phase heading. To see the entire execution, use "go test -v",
+which also adds an initial environment dump to the beginning of the log.
+
+Note also that in reported output, the actual name of the per-script temporary directory
+has been consistently replaced with the literal string $WORK.
+
+The cmd/go test flag -testwork (which must appear on the "go test" command line after
+standard test flags) causes each test to log the name of its $WORK directory and other
+environment variable settings and also to leave that directory behind when it exits,
+for manual debugging of failing tests:
+
+	$ go test -run=Script -work
+	--- FAIL: TestScript (3.75s)
+	    --- FAIL: TestScript/install_rebuild_gopath (0.16s)
+	        script_test.go:223:
+	            WORK=/tmp/cmd-go-test-745953508/script-install_rebuild_gopath
+	            GOARCH=
+	            GOCACHE=/Users/rsc/Library/Caches/go-build
+	            GOOS=
+	            GOPATH=$WORK/gopath
+	            GOROOT=/Users/rsc/go
+	            HOME=/no-home
+	            TMPDIR=$WORK/tmp
+	            exe=
+
+	            # GOPATH with p1 in d2, p2 in d2 (0.000s)
+	            # build & install p1 (0.085s)
+	            # modify p2 - p1 should appear stale (0.030s)
+	            # build & install p1 again (0.019s)
+	            > go install -i p11
+	            [stderr]
+	            can't load package: package p11: cannot find package "p11" in any of:
+	            	/Users/rsc/go/src/p11 (from $GOROOT)
+	            	$WORK/d1/src/p11 (from $GOPATH)
+	            	$WORK/d2/src/p11
+	            [exit status 1]
+	            FAIL: unexpected go command failure
+
+	        script_test.go:73: failed at testdata/script/install_rebuild_gopath.txt:15 in $WORK/gopath/src
+
+	FAIL
+	exit status 1
+	FAIL	cmd/go	4.875s
+	$
+
+	$ WORK=/tmp/cmd-go-test-745953508/script-install_rebuild_gopath
+	$ cd $WORK/d1/src/p1
+	$ cat p1.go
+	package p1
+	import "p2"
+	func F() { p2.F() }
+	$
+
+The available commands are:
+{{.Commands}}
+
+The available conditions are:
+{{.Conditions}}
+`
diff --git a/src/cmd/go/terminal_test.go b/src/cmd/go/terminal_test.go
new file mode 100644
index 0000000..a5ad919
--- /dev/null
+++ b/src/cmd/go/terminal_test.go
@@ -0,0 +1,130 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main_test
+
+import (
+	"errors"
+	"internal/testenv"
+	"internal/testpty"
+	"io"
+	"os"
+	"testing"
+
+	"golang.org/x/term"
+)
+
+func TestTerminalPassthrough(t *testing.T) {
+	// Check that if 'go test' is run with a terminal connected to stdin/stdout,
+	// then the go command passes that terminal down to the test binary
+	// invocation (rather than, e.g., putting a pipe in the way).
+	//
+	// See issue 18153.
+	testenv.MustHaveGoBuild(t)
+
+	// Start with a "self test" to make sure that if we *don't* pass in a
+	// terminal, the test can correctly detect that. (cmd/go doesn't guarantee
+	// that it won't add a terminal in the middle, but that would be pretty weird.)
+	t.Run("pipe", func(t *testing.T) {
+		r, w, err := os.Pipe()
+		if err != nil {
+			t.Fatalf("pipe failed: %s", err)
+		}
+		defer r.Close()
+		defer w.Close()
+		stdout, stderr := runTerminalPassthrough(t, r, w)
+		if stdout {
+			t.Errorf("stdout is unexpectedly a terminal")
+		}
+		if stderr {
+			t.Errorf("stderr is unexpectedly a terminal")
+		}
+	})
+
+	// Now test with a read PTY.
+	t.Run("pty", func(t *testing.T) {
+		r, processTTY, err := testpty.Open()
+		if errors.Is(err, testpty.ErrNotSupported) {
+			t.Skipf("%s", err)
+		} else if err != nil {
+			t.Fatalf("failed to open test PTY: %s", err)
+		}
+		defer r.Close()
+		w, err := os.OpenFile(processTTY, os.O_RDWR, 0)
+		if err != nil {
+			t.Fatal(err)
+		}
+		defer w.Close()
+		stdout, stderr := runTerminalPassthrough(t, r, w)
+		if !stdout {
+			t.Errorf("stdout is not a terminal")
+		}
+		if !stderr {
+			t.Errorf("stderr is not a terminal")
+		}
+	})
+}
+
+func runTerminalPassthrough(t *testing.T, r, w *os.File) (stdout, stderr bool) {
+	cmd := testenv.Command(t, testGo, "test", "-run=^$")
+	cmd.Env = append(cmd.Environ(), "GO_TEST_TERMINAL_PASSTHROUGH=1")
+	cmd.Stdout = w
+	cmd.Stderr = w
+
+	// The behavior of reading from a PTY after the child closes it is very
+	// strange: on Linux, Read returns EIO, and on at least some versions of
+	// macOS, unread output may be discarded (see https://go.dev/issue/57141).
+	//
+	// To avoid that situation, we keep the child process running until the
+	// parent has finished reading from the PTY, at which point we unblock the
+	// child by closing its stdin pipe.
+	stdin, err := cmd.StdinPipe()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	t.Logf("running %s", cmd)
+	err = cmd.Start()
+	if err != nil {
+		t.Fatalf("starting subprocess: %s", err)
+	}
+	w.Close()
+	t.Cleanup(func() {
+		stdin.Close()
+		if err := cmd.Wait(); err != nil {
+			t.Errorf("suprocess failed with: %s", err)
+		}
+	})
+
+	buf := make([]byte, 2)
+	n, err := io.ReadFull(r, buf)
+	if err != nil || !(buf[0] == '1' || buf[0] == 'X') || !(buf[1] == '2' || buf[1] == 'X') {
+		t.Logf("read error: %v", err)
+		t.Fatalf("expected 2 bytes matching `[1X][2X]`; got %q", buf[:n])
+	}
+	return buf[0] == '1', buf[1] == '2'
+}
+
+func init() {
+	if os.Getenv("GO_TEST_TERMINAL_PASSTHROUGH") == "" {
+		return
+	}
+
+	if term.IsTerminal(1) {
+		os.Stdout.WriteString("1")
+	} else {
+		os.Stdout.WriteString("X")
+	}
+	if term.IsTerminal(2) {
+		os.Stdout.WriteString("2")
+	} else {
+		os.Stdout.WriteString("X")
+	}
+
+	// Before exiting, wait for the parent process to read the PTY output,
+	// at which point it will close stdin.
+	io.Copy(io.Discard, os.Stdin)
+
+	os.Exit(0)
+}
diff --git a/src/cmd/go/testdata/mod/example.com_depends_on_generics_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_depends_on_generics_v1.0.0.txt
new file mode 100644
index 0000000..80d3095
--- /dev/null
+++ b/src/cmd/go/testdata/mod/example.com_depends_on_generics_v1.0.0.txt
@@ -0,0 +1,23 @@
+example.com/depends/on/generics v1.0.0
+written by hand
+
+-- .mod --
+module example.com/depends/on/generics
+
+go 1.18
+
+require example.com/generics v1.0.0
+-- .info --
+{"Version":"v1.0.0"}
+-- go.mod --
+module example.com/depends/on/generics
+
+go 1.18
+
+require example.com/generics v1.0.0
+-- main.go --
+package main
+
+import "example.com/generics"
+
+func main() {generics.Bar()}
\ No newline at end of file
diff --git a/src/cmd/go/testdata/mod/example.com_generics_v1.0.0.txt b/src/cmd/go/testdata/mod/example.com_generics_v1.0.0.txt
new file mode 100644
index 0000000..092241e
--- /dev/null
+++ b/src/cmd/go/testdata/mod/example.com_generics_v1.0.0.txt
@@ -0,0 +1,21 @@
+example.com/generics v1.0.0
+written by hand
+
+-- .mod --
+module example.com/generics
+
+go 1.18
+-- .info --
+{"Version":"v1.0.0"}
+-- go.mod --
+module example.com/generics
+
+go 1.18
+-- generics.go --
+package generics
+
+type Int interface {
+	~int
+}
+
+func Bar() {}
\ No newline at end of file
diff --git a/src/cmd/go/testdata/modlegacy/src/new/go.mod b/src/cmd/go/testdata/modlegacy/src/new/go.mod
deleted file mode 100644
index d0dd46d..0000000
--- a/src/cmd/go/testdata/modlegacy/src/new/go.mod
+++ /dev/null
@@ -1 +0,0 @@
-module "new/v2"
diff --git a/src/cmd/go/testdata/modlegacy/src/new/new.go b/src/cmd/go/testdata/modlegacy/src/new/new.go
deleted file mode 100644
index e99c47a..0000000
--- a/src/cmd/go/testdata/modlegacy/src/new/new.go
+++ /dev/null
@@ -1,3 +0,0 @@
-package new
-
-import _ "new/v2/p2"
diff --git a/src/cmd/go/testdata/modlegacy/src/new/p1/p1.go b/src/cmd/go/testdata/modlegacy/src/new/p1/p1.go
deleted file mode 100644
index 4539f40..0000000
--- a/src/cmd/go/testdata/modlegacy/src/new/p1/p1.go
+++ /dev/null
@@ -1,7 +0,0 @@
-package p1
-
-import _ "old/p2"
-import _ "new/v2"
-import _ "new/v2/p2"
-import _ "new/sub/v2/x/v1/y" // v2 is module, v1 is directory in module
-import _ "new/sub/inner/x"   // new/sub/inner/go.mod overrides new/sub/go.mod
diff --git a/src/cmd/go/testdata/modlegacy/src/new/p2/p2.go b/src/cmd/go/testdata/modlegacy/src/new/p2/p2.go
deleted file mode 100644
index 9b9052f..0000000
--- a/src/cmd/go/testdata/modlegacy/src/new/p2/p2.go
+++ /dev/null
@@ -1 +0,0 @@
-package p2
diff --git a/src/cmd/go/testdata/modlegacy/src/new/sub/go.mod b/src/cmd/go/testdata/modlegacy/src/new/sub/go.mod
deleted file mode 100644
index 484d20c..0000000
--- a/src/cmd/go/testdata/modlegacy/src/new/sub/go.mod
+++ /dev/null
@@ -1 +0,0 @@
-module new/sub/v2
diff --git a/src/cmd/go/testdata/modlegacy/src/new/sub/inner/go.mod b/src/cmd/go/testdata/modlegacy/src/new/sub/inner/go.mod
deleted file mode 100644
index ba39345..0000000
--- a/src/cmd/go/testdata/modlegacy/src/new/sub/inner/go.mod
+++ /dev/null
@@ -1 +0,0 @@
-module new/sub/inner
diff --git a/src/cmd/go/testdata/modlegacy/src/new/sub/inner/x/x.go b/src/cmd/go/testdata/modlegacy/src/new/sub/inner/x/x.go
deleted file mode 100644
index 823aafd..0000000
--- a/src/cmd/go/testdata/modlegacy/src/new/sub/inner/x/x.go
+++ /dev/null
@@ -1 +0,0 @@
-package x
diff --git a/src/cmd/go/testdata/modlegacy/src/new/sub/x/v1/y/y.go b/src/cmd/go/testdata/modlegacy/src/new/sub/x/v1/y/y.go
deleted file mode 100644
index 789ca71..0000000
--- a/src/cmd/go/testdata/modlegacy/src/new/sub/x/v1/y/y.go
+++ /dev/null
@@ -1 +0,0 @@
-package y
diff --git a/src/cmd/go/testdata/modlegacy/src/old/p1/p1.go b/src/cmd/go/testdata/modlegacy/src/old/p1/p1.go
deleted file mode 100644
index 9052748..0000000
--- a/src/cmd/go/testdata/modlegacy/src/old/p1/p1.go
+++ /dev/null
@@ -1,5 +0,0 @@
-package p1
-
-import _ "old/p2"
-import _ "new/p1"
-import _ "new"
diff --git a/src/cmd/go/testdata/modlegacy/src/old/p2/p2.go b/src/cmd/go/testdata/modlegacy/src/old/p2/p2.go
deleted file mode 100644
index 9b9052f..0000000
--- a/src/cmd/go/testdata/modlegacy/src/old/p2/p2.go
+++ /dev/null
@@ -1 +0,0 @@
-package p2
diff --git a/src/cmd/go/testdata/script/README b/src/cmd/go/testdata/script/README
index e529176..7b74799 100644
--- a/src/cmd/go/testdata/script/README
+++ b/src/cmd/go/testdata/script/README
@@ -1,3 +1,5 @@
+This file is generated by 'go generate cmd/go'. DO NOT EDIT.
+
 This directory holds test scripts *.txt run during 'go test cmd/go'.
 To run a specific script foo.txt
 
@@ -24,7 +26,7 @@
 	func main() { println("hello world") }
 
 Each script runs in a fresh temporary work directory tree, available to scripts as $WORK.
-Scripts also have access to these other environment variables:
+Scripts also have access to other environment variables, including:
 
 	GOARCH=<target GOARCH>
 	GOCACHE=<actual GOCACHE being used outside the test>
@@ -46,172 +48,44 @@
 On Windows, the variables $USERPROFILE and $TMP are set instead of
 $HOME and $TMPDIR.
 
-In addition, variables named ':' and '/' are expanded within script arguments
-(expanding to the value of os.PathListSeparator and os.PathSeparator
-respectively) but are not inherited in subprocess environments.
+The lines at the top of the script are a sequence of commands to be executed by
+a small script engine configured in ../../script_test.go (not the system shell).
 
 The scripts' supporting files are unpacked relative to $GOPATH/src
 (aka $WORK/gopath/src) and then the script begins execution in that directory as
 well. Thus the example above runs in $WORK/gopath/src with GOPATH=$WORK/gopath
 and $WORK/gopath/src/hello.go containing the listed contents.
 
-The lines at the top of the script are a sequence of commands to be executed
-by a tiny script engine in ../../script_test.go (not the system shell).
-The script stops and the overall test fails if any particular command fails.
+Each line of a script is parsed into a sequence of space-separated command
+words, with environment variable expansion within each word and # marking
+an end-of-line comment. Additional variables named ':' and '/' are expanded
+within script arguments (expanding to the value of os.PathListSeparator and
+os.PathSeparator respectively) but are not inherited in subprocess environments.
 
-Each line is parsed into a sequence of space-separated command words,
-with environment variable expansion and # marking an end-of-line comment.
 Adding single quotes around text keeps spaces in that text from being treated
-as word separators and also disables environment variable expansion.
-Inside a single-quoted block of text, a repeated single quote indicates
-a literal single quote, as in:
+as word separators and also disables environment variable expansion. Inside a
+single-quoted block of text, a repeated single quote indicates a literal single
+quote, as in:
 
-	'Don''t communicate by sharing memory.'
+    'Don''t communicate by sharing memory.'
 
-A line beginning with # is a comment and conventionally explains what is
-being done or tested at the start of a new phase in the script.
+A line beginning with # is a comment and conventionally explains what is being
+done or tested at the start of a new section of the script.
 
-The command prefix ! indicates that the command on the rest of the line
-(typically go or a matching predicate) must fail, not succeed. Only certain
-commands support this prefix. They are indicated below by [!] in the synopsis.
-
-The command prefix ? indicates that the command on the rest of the line
-may or may not succeed, but the test should continue regardless.
-Commands that support this prefix are indicated by [?].
+Commands are executed one at a time, and errors are checked for each command;
+if any command fails unexpectedly, no subsequent commands in the script are
+executed. The command prefix ! indicates that the command on the rest of the
+line (typically go or a matching predicate) must fail instead of succeeding.
+The command prefix ? indicates that the command may or may not succeed, but the
+script should continue regardless.
 
 The command prefix [cond] indicates that the command on the rest of the line
-should only run when the condition is satisfied. The available conditions are:
+should only run when the condition is satisfied.
 
- - GOOS and GOARCH values, like [386], [windows], and so on.
- - Compiler names, like [gccgo], [gc].
- - Test environment details:
-   - [short] for testing.Short()
-   - [cgo], [msan], [asan], [race] for whether cgo, msan, asan, and the race detector can be used
-   - [fuzz] for whether 'go test -fuzz' can be used at all
-   - [fuzz-instrumented] for whether 'go test -fuzz' uses coverage-instrumented binaries
-   - [net] for whether the external network can be used
-   - [link] for testenv.HasLink()
-   - [root] for os.Geteuid() == 0
-   - [symlink] for testenv.HasSymlink()
-   - [case-sensitive] for whether the file system is case-sensitive
-   - [exec:prog] for whether prog is available for execution (found by exec.LookPath)
-   - [GODEBUG:value] for whether value is one of the comma-separated entries in the GODEBUG variable
-   - [buildmode:value] for whether -buildmode=value is supported
-   - [trimpath] for whether the 'go' binary was built with -trimpath
-   - [mismatched-goroot] for whether the test's GOROOT_FINAL does not match the real GOROOT
-
-A condition can be negated: [!short] means to run the rest of the line
-when testing.Short() is false. Multiple conditions may be given for a single
-command, for example, '[linux] [amd64] skip'. The command will run if all conditions
-are satisfied.
-
-The commands are:
-
-- [! | ?] cc args... [&]
-  Run the C compiler, the platform specific flags (i.e. `go env GOGCCFLAGS`) will be
-  added automatically before args.
-
-- cd dir
-  Change to the given directory for future commands.
-  The directory must use slashes as path separator.
-
-- chmod perm path...
-  Change the permissions of the files or directories named by the path arguments
-  to be equal to perm. Only numerical permissions are supported.
-
-- [! | ?] cmp file1 file2
-  Check that the named files have (or do not have) the same content.
-  By convention, file1 is the actual data and file2 the expected data.
-  File1 can be "stdout" or "stderr" to use the standard output or standard error
-  from the most recent exec or go command.
-  (If the file contents differ and the command is not negated,
-  the failure prints a diff.)
-
-- [! | ?] cmpenv file1 file2
-  Like cmp, but environment variables are substituted in the file contents
-  before the comparison. For example, $GOOS is replaced by the target GOOS.
-
-- [! | ?] cp src... dst
-  Copy the listed files to the target file or existing directory.
-  src can include "stdout" or "stderr" to use the standard output or standard error
-  from the most recent exec or go command.
-
-- env [-r] [key=value...]
-  With no arguments, print the environment to stdout
-  (useful for debugging and for verifying initial state).
-  Otherwise add the listed key=value pairs to the environment.
-  The -r flag causes the values to be escaped using regexp.QuoteMeta
-  before being recorded.
-
-- [! | ?] exec program [args...] [&]
-  Run the given executable program with the arguments.
-  It must (or must not) succeed.
-  Note that 'exec' does not terminate the script (unlike in Unix shells).
-
-  If the last token is '&', the program executes in the background. The standard
-  output and standard error of the previous command is cleared, but the output
-  of the background process is buffered — and checking of its exit status is
-  delayed — until the next call to 'wait', 'skip', or 'stop' or the end of the
-  test. If any background processes remain at the end of the test, they
-  are terminated using os.Interrupt (if supported) or os.Kill and the test
-  must not depend upon their exit status.
-
-- [!] exists [-readonly] [-exec] file...
-  Each of the listed files or directories must (or must not) exist.
-  If -readonly is given, the files or directories must be unwritable.
-  If -exec is given, the files or directories must be executable.
-
-- [! | ?] go args... [&]
-  Run the (test copy of the) go command with the given arguments.
-  It must (or must not) succeed.
-
-- [!] grep [-count=N] [-q] pattern file
-  The file's content must (or must not) match the regular expression pattern.
-  For positive matches, -count=N specifies an exact number of matches to require.
-  The -q flag disables printing the file content on a mismatch.
-
-- mkdir path...
-  Create the listed directories, if they do not already exists.
-
-- mv path1 path2
-  Rename path1 to path2. OS-specific restrictions may apply when path1 and path2
-  are in different directories.
-
-- rm file...
-  Remove the listed files or directories.
-
-- skip [message]
-  Mark the test skipped, including the message if given.
-
-- sleep duration
-  Sleep for the given duration (a time.Duration string).
-  (Tests should generally poll instead of sleeping, but sleeping may sometimes
-  be necessary, for example, to ensure that modified files have unique mtimes.)
-
-- [!] stale path...
-  The packages named by the path arguments must (or must not)
-  be reported as "stale" by the go command.
-
-- [!] stderr [-count=N] pattern
-  Apply the grep command (see above) to the standard error
-  from the most recent exec, go, or wait command.
-
-- [!] stdout [-count=N] pattern
-  Apply the grep command (see above) to the standard output
-  from the most recent exec, go, wait, or env command.
-
-- stop [message]
-  Stop the test early (marking it as passing), including the message if given.
-
-- symlink file -> target
-  Create file as a symlink to target. The -> (like in ls -l output) is required.
-
-- wait
-  Wait for all 'exec' and 'go' commands started in the background (with the '&'
-  token) to exit, and display success or failure status for them.
-  After a call to wait, the 'stderr' and 'stdout' commands will apply to the
-  concatenation of the corresponding streams of the background commands,
-  in the order in which those commands were started.
+A condition can be negated: [!root] means to run the rest of the line only if
+the user is not root. Multiple conditions may be given for a single command,
+for example, '[linux] [amd64] skip'. The command will run if all conditions are
+satisfied.
 
 When TestScript runs a script and the script fails, by default TestScript shows
 the execution of the most recent phase of the script (since the last # comment)
@@ -219,7 +93,7 @@
 multi-phase script with a bug in it:
 
 	# GOPATH with p1 in d2, p2 in d2
-	env GOPATH=$WORK/d1${:}$WORK/d2
+	env GOPATH=$WORK${/}d1${:}$WORK${/}d2
 
 	# build & install p1
 	env
@@ -329,3 +203,215 @@
 	func F() { p2.F() }
 	$
 
+The available commands are:
+cat files...
+	concatenate files and print to the script's stdout buffer
+
+
+cc args...
+	run the platform C compiler
+
+
+cd dir
+	change the working directory
+
+
+chmod perm paths...
+	change file mode bits
+
+	Changes the permissions of the named files or directories to
+	be equal to perm.
+	Only numerical permissions are supported.
+
+cmp [-q] file1 file2
+	compare files for differences
+
+	By convention, file1 is the actual data and file2 is the
+	expected data.
+	The command succeeds if the file contents are identical.
+	File1 can be 'stdout' or 'stderr' to compare the stdout or
+	stderr buffer from the most recent command.
+
+cmpenv [-q] file1 file2
+	compare files for differences, with environment expansion
+
+	By convention, file1 is the actual data and file2 is the
+	expected data.
+	The command succeeds if the file contents are identical
+	after substituting variables from the script environment.
+	File1 can be 'stdout' or 'stderr' to compare the script's
+	stdout or stderr buffer.
+
+cp src... dst
+	copy files to a target file or directory
+
+	src can include 'stdout' or 'stderr' to copy from the
+	script's stdout or stderr buffer.
+
+echo string...
+	display a line of text
+
+
+env [key[=value]...]
+	set or log the values of environment variables
+
+	With no arguments, print the script environment to the log.
+	Otherwise, add the listed key=value pairs to the environment
+	or print the listed keys.
+
+exec program [args...] [&]
+	run an executable program with arguments
+
+	Note that 'exec' does not terminate the script (unlike Unix
+	shells).
+
+exists [-readonly] [-exec] file...
+	check that files exist
+
+
+go [args...] [&]
+	run the 'go' program provided by the script host
+
+
+grep [-count=N] [-q] 'pattern' file
+	find lines in a file that match a pattern
+
+	The command succeeds if at least one match (or the exact
+	count, if given) is found.
+	The -q flag suppresses printing of matches.
+
+help [-v] name...
+	log help text for commands and conditions
+
+	To display help for a specific condition, enclose it in
+	brackets: 'help [amd64]'.
+	To display complete documentation when listing all commands,
+	pass the -v flag.
+
+mkdir path...
+	create directories, if they do not already exist
+
+	Unlike Unix mkdir, parent directories are always created if
+	needed.
+
+mv old new
+	rename a file or directory to a new path
+
+	OS-specific restrictions may apply when old and new are in
+	different directories.
+
+replace [old new]... file
+	replace strings in a file
+
+	The 'old' and 'new' arguments are unquoted as if in quoted
+	Go strings.
+
+rm path...
+	remove a file or directory
+
+	If the path is a directory, its contents are removed
+	recursively.
+
+skip [msg]
+	skip the current test
+
+
+sleep duration [&]
+	sleep for a specified duration
+
+	The duration must be given as a Go time.Duration string.
+
+stale target...
+	check that build targets are stale
+
+
+stderr [-count=N] [-q] 'pattern' file
+	find lines in the stderr buffer that match a pattern
+
+	The command succeeds if at least one match (or the exact
+	count, if given) is found.
+	The -q flag suppresses printing of matches.
+
+stdout [-count=N] [-q] 'pattern' file
+	find lines in the stdout buffer that match a pattern
+
+	The command succeeds if at least one match (or the exact
+	count, if given) is found.
+	The -q flag suppresses printing of matches.
+
+stop [msg]
+	stop execution of the script
+
+	The message is written to the script log, but no error is
+	reported from the script engine.
+
+symlink path -> target
+	create a symlink
+
+	Creates path as a symlink to target.
+	The '->' token (like in 'ls -l' output on Unix) is required.
+
+wait 
+	wait for completion of background commands
+
+	Waits for all background commands to complete.
+	The output (and any error) from each command is printed to
+	the log in the order in which the commands were started.
+	After the call to 'wait', the script's stdout and stderr
+	buffers contain the concatenation of the background
+	commands' outputs.
+
+
+
+The available conditions are:
+[GOARCH:*]
+	runtime.GOARCH == <suffix>
+[GODEBUG:*]
+	GODEBUG contains <suffix>
+[GOEXPERIMENT:*]
+	GOEXPERIMENT <suffix> is enabled
+[GOOS:*]
+	runtime.GOOS == <suffix>
+[abscc]
+	default $CC path is absolute and exists
+[asan]
+	GOOS/GOARCH supports -asan
+[buildmode:*]
+	go supports -buildmode=<suffix>
+[case-sensitive]
+	$WORK filesystem is case-sensitive
+[cgo]
+	host CGO_ENABLED
+[compiler:*]
+	runtime.Compiler == <suffix>
+[cross]
+	cmd/go GOOS/GOARCH != GOHOSTOS/GOHOSTARCH
+[exec:*]
+	<suffix> names an executable in the test binary's PATH
+[fuzz]
+	GOOS/GOARCH supports -fuzz
+[fuzz-instrumented]
+	GOOS/GOARCH supports -fuzz with instrumentation
+[git]
+	the 'git' executable exists and provides the standard CLI
+[link]
+	testenv.HasLink()
+[mismatched-goroot]
+	test's GOROOT_FINAL does not match the real GOROOT
+[msan]
+	GOOS/GOARCH supports -msan
+[net]
+	testenv.HasExternalNetwork()
+[race]
+	GOOS/GOARCH supports -race
+[root]
+	os.Geteuid() == 0
+[short]
+	testing.Short()
+[symlink]
+	testenv.HasSymlink()
+[trimpath]
+	test binary was built with -trimpath
+[verbose]
+	testing.Verbose()
+
diff --git a/src/cmd/go/testdata/script/autocgo.txt b/src/cmd/go/testdata/script/autocgo.txt
new file mode 100644
index 0000000..586c802
--- /dev/null
+++ b/src/cmd/go/testdata/script/autocgo.txt
@@ -0,0 +1,29 @@
+# Test automatic setting of CGO_ENABLED based on $CC and what's in $PATH.
+
+[!cgo] skip
+[cross] skip
+
+# Assume we're on a system that can enable cgo normally.
+env CGO_ENABLED=
+go env CGO_ENABLED
+stdout 1
+
+# Clearing CC and removing everything but Go from the PATH should usually
+# disable cgo: no C compiler anymore (unless the baked-in defaultCC is an
+# absolute path and exists.
+env CC=
+env PATH=$GOROOT/bin
+go env CGO_ENABLED
+[!abscc] stdout 0
+[abscc] stdout 1
+
+# Setting CC should re-enable cgo.
+env CC=cc
+go env CGO_ENABLED
+stdout 1
+
+# So should setting CGO_ENABLED.
+env CC=
+env CGO_ENABLED=1
+go env CGO_ENABLED
+stdout 1
diff --git a/src/cmd/go/testdata/script/bug.txt b/src/cmd/go/testdata/script/bug.txt
index 571d507..f64fb85 100644
--- a/src/cmd/go/testdata/script/bug.txt
+++ b/src/cmd/go/testdata/script/bug.txt
@@ -1,6 +1,6 @@
 # Verify that go bug creates the appropriate URL issue body
 
-[!linux] skip
+[!GOOS:linux] skip
 [short] skip
 
 go install
diff --git a/src/cmd/go/testdata/script/build_GOTMPDIR.txt b/src/cmd/go/testdata/script/build_GOTMPDIR.txt
index 1073517..4c9129e 100644
--- a/src/cmd/go/testdata/script/build_GOTMPDIR.txt
+++ b/src/cmd/go/testdata/script/build_GOTMPDIR.txt
@@ -1,10 +1,10 @@
 # Set GOCACHE to a clean directory to ensure that 'go build' has work to report.
-[!windows] env GOCACHE=$WORK/gocache
-[windows] env GOCACHE=$WORK\gocache
+[!GOOS:windows] env GOCACHE=$WORK/gocache
+[GOOS:windows] env GOCACHE=$WORK\gocache
 
 # 'go build' should use GOTMPDIR if set.
-[!windows] env GOTMPDIR=$WORK/my-favorite-tmpdir
-[windows] env GOTMPDIR=$WORK\my-favorite-tmpdir
+[!GOOS:windows] env GOTMPDIR=$WORK/my-favorite-tmpdir
+[GOOS:windows] env GOTMPDIR=$WORK\my-favorite-tmpdir
 mkdir $GOTMPDIR
 go build -x hello.go
 stderr ^WORK=.*my-favorite-tmpdir
diff --git a/src/cmd/go/testdata/script/build_acl_windows.txt b/src/cmd/go/testdata/script/build_acl_windows.txt
index 13a3ba2..2cb60e0 100644
--- a/src/cmd/go/testdata/script/build_acl_windows.txt
+++ b/src/cmd/go/testdata/script/build_acl_windows.txt
@@ -1,4 +1,4 @@
-[!windows] stop
+[!GOOS:windows] stop
 [!exec:icacls] skip
 [!exec:powershell] skip
 
diff --git a/src/cmd/go/testdata/script/build_buildvcs_auto.txt b/src/cmd/go/testdata/script/build_buildvcs_auto.txt
index dd9eef5..cfd5d82 100644
--- a/src/cmd/go/testdata/script/build_buildvcs_auto.txt
+++ b/src/cmd/go/testdata/script/build_buildvcs_auto.txt
@@ -2,7 +2,7 @@
 # not attempt to stamp VCS information when the VCS tool is not present.
 
 [short] skip
-[!exec:git] skip
+[!git] skip
 
 cd sub
 exec git init .
diff --git a/src/cmd/go/testdata/script/build_cache_output.txt b/src/cmd/go/testdata/script/build_cache_output.txt
index 0d94bf6..fc040b4 100644
--- a/src/cmd/go/testdata/script/build_cache_output.txt
+++ b/src/cmd/go/testdata/script/build_cache_output.txt
@@ -1,7 +1,7 @@
 env GO111MODULE=off
 env GODEBUG=gocachetest=1
 
-[!gc] skip
+[!compiler:gc] skip
 [short] skip # clears cache, rebuilds too much
 
 # Set up fresh GOCACHE.
diff --git a/src/cmd/go/testdata/script/build_cd_gopath_different.txt b/src/cmd/go/testdata/script/build_cd_gopath_different.txt
index a7a4bf4..64d7d74 100644
--- a/src/cmd/go/testdata/script/build_cd_gopath_different.txt
+++ b/src/cmd/go/testdata/script/build_cd_gopath_different.txt
@@ -1,4 +1,4 @@
-[gccgo] skip 'gccgo does not support -ldflags -X'
+[compiler:gccgo] skip 'gccgo does not support -ldflags -X'
 env GO111MODULE=off
 go build run_go.go
 
@@ -8,7 +8,7 @@
 stderr 'linkXworked'
 rm $WORK/tmp/a.exe
 
-[!windows] stop 'rest of the tests only apply to Windows'
+[!GOOS:windows] stop 'rest of the tests only apply to Windows'
 
 # Replace '\' with '/' in GOPATH
 exec ./run_go$GOEXE $GOPATH/src/my.pkg/main $GOPATH REPLACE_SLASH build -o $WORK/tmp/a.exe -ldflags -X=my.pkg.Text=linkXworked
diff --git a/src/cmd/go/testdata/script/build_cgo_consistent_results.txt b/src/cmd/go/testdata/script/build_cgo_consistent_results.txt
index 88a24de..f22994f 100644
--- a/src/cmd/go/testdata/script/build_cgo_consistent_results.txt
+++ b/src/cmd/go/testdata/script/build_cgo_consistent_results.txt
@@ -1,8 +1,8 @@
 [short] skip
 [!cgo] skip
 
-[solaris] skip "skipping on Solaris; see golang.org/issue/13247"
-[illumos] skip "skipping on Solaris; see golang.org/issue/13247"
+[GOOS:solaris] skip "skipping on Solaris; see golang.org/issue/13247"
+[GOOS:illumos] skip "skipping on Solaris; see golang.org/issue/13247"
 
 go build -o $WORK/exe1$GOEXE cgotest
 go build -x -o $WORK/exe2$GOEXE cgotest
diff --git a/src/cmd/go/testdata/script/build_cgo_error.txt b/src/cmd/go/testdata/script/build_cgo_error.txt
new file mode 100644
index 0000000..c11ab46
--- /dev/null
+++ b/src/cmd/go/testdata/script/build_cgo_error.txt
@@ -0,0 +1,17 @@
+[short] skip
+[!cgo] skip
+
+! go build .
+stderr '# foo\nfoo.c:'
+! stderr 'EXTRA string'
+
+-- go.mod --
+module foo
+
+go 1.20
+-- foo.go --
+package foo
+
+import "C"
+-- foo.c --
+#include "doesnotexist.h"
\ No newline at end of file
diff --git a/src/cmd/go/testdata/script/build_darwin_cc_arch.txt b/src/cmd/go/testdata/script/build_darwin_cc_arch.txt
index 2b81b4c..df3fa5b 100644
--- a/src/cmd/go/testdata/script/build_darwin_cc_arch.txt
+++ b/src/cmd/go/testdata/script/build_darwin_cc_arch.txt
@@ -1,6 +1,6 @@
 # Test that we pass -arch flag to C compiler on Darwin (issue 43692).
 
-[!darwin] skip
+[!GOOS:darwin] skip
 [!cgo] skip
 
 # clear CC, in case user sets it
diff --git a/src/cmd/go/testdata/script/build_dash_x.txt b/src/cmd/go/testdata/script/build_dash_x.txt
index 6fd5bbe..e5580a2 100644
--- a/src/cmd/go/testdata/script/build_dash_x.txt
+++ b/src/cmd/go/testdata/script/build_dash_x.txt
@@ -3,7 +3,6 @@
 
 [!exec:/usr/bin/env] skip
 [!exec:bash] skip
-[!exec:cat] skip
 
 mkdir $WORK/tmp/cache
 env GOCACHE=$WORK/tmp/cache
@@ -22,7 +21,7 @@
 
 go build -x -o main main.go
 cp stderr commands.txt
-exec cat header.txt commands.txt
+cat header.txt commands.txt
 cp stdout test.sh
 
 exec ./main
diff --git a/src/cmd/go/testdata/script/build_gcflags.txt b/src/cmd/go/testdata/script/build_gcflags.txt
index b472374..9603e0b 100644
--- a/src/cmd/go/testdata/script/build_gcflags.txt
+++ b/src/cmd/go/testdata/script/build_gcflags.txt
@@ -2,9 +2,9 @@
 
 # Test that the user can override default code generation flags.
 
-[gccgo] skip  # gccgo does not use -gcflags
+[compiler:gccgo] skip  # gccgo does not use -gcflags
 [!cgo] skip
-[!linux] skip  # test only works if c-archive implies -shared
+[!GOOS:linux] skip  # test only works if c-archive implies -shared
 [short] skip
 
 env GOCACHE=$WORK/gocache  # Looking for compile commands, so need a clean cache.
diff --git a/src/cmd/go/testdata/script/build_i.txt b/src/cmd/go/testdata/script/build_i.txt
deleted file mode 100644
index 0e7ebed..0000000
--- a/src/cmd/go/testdata/script/build_i.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-env GO111MODULE=off
-
-# Test that 'go build -i' installs dependencies of the requested package.
-
-[short] skip
-
-# Since we are checking installation of dependencies, use a clean cache
-# to ensure that multiple runs of the test do not interfere.
-env GOCACHE=$WORK/cache
-
-# The initial 'go build -i' for bar should install its dependency foo.
-
-go build -v -i x/y/bar
-stderr 'x/y/foo'    # should be rebuilt
-go build -v -i x/y/bar
-! stderr 'x/y/foo'  # should already be installed
-
-# After modifying the source files, both packages should be rebuild.
-
-cp x/y/foo/foo.go.next x/y/foo/foo.go
-cp x/y/bar/bar.go.next x/y/bar/bar.go
-
-go build -v -i x/y/bar
-stderr 'x/y/foo'    # should be rebuilt
-go build -v -i x/y/bar
-! stderr 'x/y/foo'  # should already be installed
-
--- x/y/foo/foo.go --
-package foo
-func F() {}
--- x/y/bar/bar.go --
-package bar
-import "x/y/foo"
-func F() { foo.F() }
--- x/y/foo/foo.go.next --
-package foo
-func F() { F() }
--- x/y/bar/bar.go.next --
-package main
-import "x/y/foo"
-func main() { foo.F() }
diff --git a/src/cmd/go/testdata/script/build_i_deprecate.txt b/src/cmd/go/testdata/script/build_i_deprecate.txt
deleted file mode 100644
index 5c17995..0000000
--- a/src/cmd/go/testdata/script/build_i_deprecate.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-# Check that deprecation warnings are printed when the -i flag is used.
-# TODO(golang.org/issue/41696): remove the -i flag after Go 1.16, and this test.
-
-go build -n -i
-stderr '^go: -i flag is deprecated$'
-
-go install -n -i
-stderr '^go: -i flag is deprecated$'
-
-go test -n -i
-stderr '^go: -i flag is deprecated$'
-
-
-# 'go clean -i' should not print a deprecation warning.
-# It will continue working.
-go clean -i .
-! stderr .
-
--- go.mod --
-module m
-
-go 1.16
--- m.go --
-package m
diff --git a/src/cmd/go/testdata/script/build_internal.txt b/src/cmd/go/testdata/script/build_internal.txt
index 5b786f2..0a37d65 100644
--- a/src/cmd/go/testdata/script/build_internal.txt
+++ b/src/cmd/go/testdata/script/build_internal.txt
@@ -15,7 +15,7 @@
 stderr 'p\.go:3:8: use of internal package .*internal/w not allowed'
 env GO111MODULE=''
 
-[gccgo] skip # gccgo does not have GOROOT
+[compiler:gccgo] skip # gccgo does not have GOROOT
 cd ../testinternal
 ! go build -v .
 stderr 'p\.go:3:8: use of internal package net/http/internal not allowed'
diff --git a/src/cmd/go/testdata/script/build_issue48319.txt b/src/cmd/go/testdata/script/build_issue48319.txt
index 3979247..4543303 100644
--- a/src/cmd/go/testdata/script/build_issue48319.txt
+++ b/src/cmd/go/testdata/script/build_issue48319.txt
@@ -3,7 +3,6 @@
 
 [short] skip
 [!cgo] skip
-[windows] skip  # The Go Windows builders have an extremely out-of-date gcc that does not support reproducible builds; see https://go.dev/issue/50824.
 
 # This test is sensitive to cache invalidation,
 # so use a separate build cache that we can control.
@@ -21,7 +20,7 @@
 env GOROOT_FINAL=$WORK${/}goroot2
 go build -o main.exe
 mv main.exe main2.exe
-! cmp main2.exe main1.exe
+! cmp -q main2.exe main1.exe
 
 # Set GOROOT_FINAL back to the first value.
 # If the build is properly reproducible, the two binaries should match.
diff --git a/src/cmd/go/testdata/script/build_issue6480.txt b/src/cmd/go/testdata/script/build_issue6480.txt
index cf1e9ea..991112f 100644
--- a/src/cmd/go/testdata/script/build_issue6480.txt
+++ b/src/cmd/go/testdata/script/build_issue6480.txt
@@ -3,7 +3,7 @@
 # "go test -c" should also appear to write a new binary every time,
 # even if it's really just updating the mtime on an existing up-to-date binary.
 
-[gccgo] skip
+[compiler:gccgo] skip
 [short] skip
 
 # Install some commands to compare mtimes
diff --git a/src/cmd/go/testdata/script/build_link_x_import_path_escape.txt b/src/cmd/go/testdata/script/build_link_x_import_path_escape.txt
index f1de1e4..d47c482 100644
--- a/src/cmd/go/testdata/script/build_link_x_import_path_escape.txt
+++ b/src/cmd/go/testdata/script/build_link_x_import_path_escape.txt
@@ -1,4 +1,4 @@
-[gccgo] skip 'gccgo does not support -ldflags -X'
+[compiler:gccgo] skip 'gccgo does not support -ldflags -X'
 
 go build -o linkx$GOEXE -ldflags -X=my.pkg.Text=linkXworked my.pkg/main
 exec ./linkx$GOEXE
diff --git a/src/cmd/go/testdata/script/build_n_cgo.txt b/src/cmd/go/testdata/script/build_n_cgo.txt
index 7aa77ae..fa01927 100644
--- a/src/cmd/go/testdata/script/build_n_cgo.txt
+++ b/src/cmd/go/testdata/script/build_n_cgo.txt
@@ -4,6 +4,7 @@
 # See issue golang.org/issue/37012.
 go build -n
 ! stderr '[/\\]\$WORK'
+stderr '[ =]\$WORK'
 
 -- go.mod --
 module m
diff --git a/src/cmd/go/testdata/script/build_nocache.txt b/src/cmd/go/testdata/script/build_nocache.txt
index 1059cad..b21e755 100644
--- a/src/cmd/go/testdata/script/build_nocache.txt
+++ b/src/cmd/go/testdata/script/build_nocache.txt
@@ -7,8 +7,8 @@
 env GOCACHE=
 env XDG_CACHE_HOME=
 env HOME=
-[plan9] env home=
-[windows] env LocalAppData=
+[GOOS:plan9] env home=
+[GOOS:windows] env LocalAppData=
 ! go build -o triv triv.go
 stderr 'build cache is required, but could not be located: GOCACHE is not defined and .*'
 
@@ -23,13 +23,13 @@
 stderr 'build cache is disabled by GOCACHE=off'
 
 # If GOCACHE is set to an unwritable directory, we should diagnose it as such.
-[windows] stop # Does not support unwritable directories.
+[GOOS:windows] stop # Does not support unwritable directories.
 [root] skip # Can write to unwritable directories.
 
 mkdir $WORK/unwritable/home
 chmod 0555 $WORK/unwritable/home
-[!plan9] env HOME=$WORK/unwritable/home
-[plan9] env home=$WORK/unwritable/home
+[!GOOS:plan9] env HOME=$WORK/unwritable/home
+[GOOS:plan9] env home=$WORK/unwritable/home
 
 env GOCACHE=$WORK/unwritable/home
 ! go build -o triv triv.go
diff --git a/src/cmd/go/testdata/script/build_output.txt b/src/cmd/go/testdata/script/build_output.txt
index 1e82950..457960f 100644
--- a/src/cmd/go/testdata/script/build_output.txt
+++ b/src/cmd/go/testdata/script/build_output.txt
@@ -1,8 +1,8 @@
-[gccgo] skip 'gccgo has no standard packages'
+[compiler:gccgo] skip 'gccgo has no standard packages'
 [short] skip
 
-[!windows] env NONEXE='.exe'
-[windows] env NONEXE=''
+[!GOOS:windows] env NONEXE='.exe'
+[GOOS:windows] env NONEXE=''
 
 env GOBIN=$WORK/tmp/bin
 go install m/isarchive &
@@ -28,15 +28,15 @@
 exists -exec bin/x$GOEXE
 rm bin
 
-[windows] ! exists bin
-[windows] go build -o bin\x x.go
-[windows] exists -exec bin\x
-[windows] rm bin
+[GOOS:windows] ! exists bin
+[GOOS:windows] go build -o bin\x x.go
+[GOOS:windows] exists -exec bin\x
+[GOOS:windows] rm bin
 
-[windows] ! exists bin
-[windows] go build -o bin\ x.go
-[windows] exists -exec bin\x.exe
-[windows] rm bin
+[GOOS:windows] ! exists bin
+[GOOS:windows] go build -o bin\ x.go
+[GOOS:windows] exists -exec bin\x.exe
+[GOOS:windows] rm bin
 
 ! exists bin
 mkdir bin
diff --git a/src/cmd/go/testdata/script/build_overlay.txt b/src/cmd/go/testdata/script/build_overlay.txt
index 70cd7f8..b64bc02 100644
--- a/src/cmd/go/testdata/script/build_overlay.txt
+++ b/src/cmd/go/testdata/script/build_overlay.txt
@@ -68,6 +68,7 @@
 # Run same tests but with gccgo.
 env GO111MODULE=off
 [!exec:gccgo] stop
+[cross] stop  # gccgo can't necessarily cross-compile
 
 ! go build -compiler=gccgo .
 go build -compiler=gccgo -overlay overlay.json -o main_gccgo$GOEXE .
diff --git a/src/cmd/go/testdata/script/build_pgo.txt b/src/cmd/go/testdata/script/build_pgo.txt
new file mode 100644
index 0000000..65ecd57
--- /dev/null
+++ b/src/cmd/go/testdata/script/build_pgo.txt
@@ -0,0 +1,62 @@
+# Test go build -pgo flag.
+# Specifically, the build cache handles profile content correctly.
+
+# this test rebuild runtime with different flags, skip in short mode
+[short] skip
+
+# build without PGO
+go build triv.go
+
+# build with PGO, should trigger rebuild
+# starting with an empty profile (the compiler accepts it)
+go build -x -pgo=prof triv.go
+stderr 'compile.*-pgoprofile=.*prof.*triv.go'
+
+# store the build ID
+go list -export -json=BuildID -pgo=prof triv.go
+stdout '"BuildID":' # check that output actually contains a build ID
+cp stdout list.out
+
+# build again with the same profile, should be cached
+go build -x -pgo=prof triv.go
+! stderr 'compile.*triv.go'
+
+# check that the build ID is the same
+go list -export -json=BuildID -pgo=prof triv.go
+cmp stdout list.out
+
+# overwrite the prof
+go run overwrite.go
+
+# build again, profile content changed, should trigger rebuild
+go build -n -pgo=prof triv.go
+stderr 'compile.*-pgoprofile=.*prof.*p.go'
+
+# check that the build ID is different
+go list -export -json=BuildID -pgo=prof triv.go
+! cmp stdout list.out
+
+-- prof --
+-- triv.go --
+package main
+func main() {}
+-- overwrite.go --
+package main
+
+import (
+	"os"
+	"runtime/pprof"
+)
+
+func main() {
+	f, err := os.Create("prof")
+	if err != nil {
+		panic(err)
+	}
+	err = pprof.StartCPUProfile(f)
+	if err != nil {
+		panic(err)
+	}
+	pprof.StopCPUProfile()
+	f.Close()
+}
diff --git a/src/cmd/go/testdata/script/build_pgo_auto.txt b/src/cmd/go/testdata/script/build_pgo_auto.txt
new file mode 100644
index 0000000..b78137d
--- /dev/null
+++ b/src/cmd/go/testdata/script/build_pgo_auto.txt
@@ -0,0 +1,69 @@
+# Test go build -pgo=auto flag.
+
+# use default.pgo for a single main package
+go build -n -pgo=auto ./a/a1
+stderr 'compile.*-pgoprofile=.*default\.pgo.*a1.go'
+
+# check that pgo applied to dependencies
+stderr 'compile.*-p test/dep.*-pgoprofile=.*default\.pgo'
+
+# use default.pgo for ... with a single main package
+go build -n -pgo=auto ./a/...
+stderr 'compile.*-pgoprofile=.*default\.pgo.*a1.go'
+
+# error with multiple packages
+! go build -n -pgo=auto ./b/...
+stderr '-pgo=auto requires exactly one main package'
+
+# build succeeds without PGO when default.pgo file is absent
+go build -n -pgo=auto -o nopgo.exe ./nopgo
+stderr 'compile.*nopgo.go'
+! stderr '-pgoprofile'
+
+# other build-related commands
+go install -n -pgo=auto ./a/a1
+stderr 'compile.*-pgoprofile=.*default\.pgo.*a1.go'
+
+go run -n -pgo=auto ./a/a1
+stderr 'compile.*-pgoprofile=.*default\.pgo.*a1.go'
+
+go test -n -pgo=auto ./a/a1
+stderr 'compile.*-pgoprofile=.*default\.pgo.*a1.go.*a1_test.go'
+stderr 'compile.*-pgoprofile=.*default\.pgo.*external_test.go'
+
+# go list commands should succeed as usual
+go list -pgo=auto ./a/a1
+
+go list -test -pgo=auto ./a/a1
+
+go list -deps -pgo=auto ./a/a1
+
+-- go.mod --
+module test
+go 1.20
+-- a/a1/a1.go --
+package main
+import _ "test/dep"
+func main() {}
+-- a/a1/a1_test.go --
+package main
+import "testing"
+func TestA(*testing.T) {}
+-- a/a1/external_test.go --
+package main_test
+import "testing"
+func TestExternal(*testing.T) {}
+-- a/a1/default.pgo --
+-- b/b1/b1.go --
+package main
+func main() {}
+-- b/b1/default.pgo --
+-- b/b2/b2.go --
+package main
+func main() {}
+-- b/b2/default.pgo --
+-- nopgo/nopgo.go --
+package main
+func main() {}
+-- dep/dep.go --
+package dep
diff --git a/src/cmd/go/testdata/script/build_relative_pkgdir.txt b/src/cmd/go/testdata/script/build_relative_pkgdir.txt
index 0716bcd..57f18ee 100644
--- a/src/cmd/go/testdata/script/build_relative_pkgdir.txt
+++ b/src/cmd/go/testdata/script/build_relative_pkgdir.txt
@@ -6,4 +6,4 @@
 
 mkdir $WORK/gocache
 env GOCACHE=$WORK/gocache
-go build -i -pkgdir=. runtime
+go build -pkgdir=. runtime
diff --git a/src/cmd/go/testdata/script/build_relative_tmpdir.txt b/src/cmd/go/testdata/script/build_relative_tmpdir.txt
index 3e98a67..ea7412e 100644
--- a/src/cmd/go/testdata/script/build_relative_tmpdir.txt
+++ b/src/cmd/go/testdata/script/build_relative_tmpdir.txt
@@ -5,14 +5,14 @@
 mkdir tmp
 env GOTMPDIR=tmp
 go build -work a
-stderr 'WORK=\$WORK' # the test script itself converts the absolute directory back to $WORK
+stderr 'WORK='$WORK
 
 # Similarly if TMP/TMPDIR is relative.
 env GOTMPDIR=
 env TMP=tmp    # Windows
 env TMPDIR=tmp # Unix
 go build -work a
-stderr 'WORK=\$WORK'
+stderr 'WORK='$WORK
 
 -- a/a.go --
 package a
diff --git a/src/cmd/go/testdata/script/build_tags_no_comma.txt b/src/cmd/go/testdata/script/build_tags_no_comma.txt
index f3eb282..a14a200 100644
--- a/src/cmd/go/testdata/script/build_tags_no_comma.txt
+++ b/src/cmd/go/testdata/script/build_tags_no_comma.txt
@@ -1,4 +1,4 @@
-[gccgo] skip 'gccgo has no standard packages'
+[compiler:gccgo] skip 'gccgo has no standard packages'
 go build -tags 'tag1 tag2' math
 ! go build -tags 'tag1,tag2 tag3' math
 stderr 'space-separated list contains comma'
\ No newline at end of file
diff --git a/src/cmd/go/testdata/script/build_trimpath.txt b/src/cmd/go/testdata/script/build_trimpath.txt
index f36b123..2a2aa20 100644
--- a/src/cmd/go/testdata/script/build_trimpath.txt
+++ b/src/cmd/go/testdata/script/build_trimpath.txt
@@ -95,6 +95,7 @@
 # Same sequence of tests but with gccgo.
 # gccgo does not support builds in module mode.
 [!exec:gccgo] stop
+[cross] stop  # gccgo can't necessarily cross-compile
 env GOPATH=$WORK/a
 
 # A binary built with gccgo without -trimpath should contain the current
diff --git a/src/cmd/go/testdata/script/build_trimpath_cgo.txt b/src/cmd/go/testdata/script/build_trimpath_cgo.txt
index 3187b4d..5289824 100644
--- a/src/cmd/go/testdata/script/build_trimpath_cgo.txt
+++ b/src/cmd/go/testdata/script/build_trimpath_cgo.txt
@@ -14,7 +14,7 @@
 stdout gopath[/\\]src
 
 # Check that the source path does not appear when -trimpath is used.
-[aix] stop # can't inspect XCOFF binaries
+[GOOS:aix] stop # can't inspect XCOFF binaries
 go build -trimpath -o hello.exe .
 ! grep -q gopath[/\\]src hello.exe
 go run ./list-dwarf hello.exe
diff --git a/src/cmd/go/testdata/script/build_unsupported_goos.txt b/src/cmd/go/testdata/script/build_unsupported_goos.txt
index d61e420..8c12129 100644
--- a/src/cmd/go/testdata/script/build_unsupported_goos.txt
+++ b/src/cmd/go/testdata/script/build_unsupported_goos.txt
@@ -1,4 +1,4 @@
-[gccgo] skip # gccgo assumes cross-compilation is always possible
+[compiler:gccgo] skip # gccgo assumes cross-compilation is always possible
 
 env GOOS=windwos
 
diff --git a/src/cmd/go/testdata/script/cache_unix.txt b/src/cmd/go/testdata/script/cache_unix.txt
index 0e07ba6..5694800 100644
--- a/src/cmd/go/testdata/script/cache_unix.txt
+++ b/src/cmd/go/testdata/script/cache_unix.txt
@@ -2,9 +2,9 @@
 
 # Integration test for cache directory calculation (cmd/go/internal/cache).
 
-[windows] skip
-[darwin] skip
-[plan9] skip
+[GOOS:windows] skip
+[GOOS:darwin] skip
+[GOOS:plan9] skip
 
 mkdir $WORK/gocache
 mkdir $WORK/xdg
@@ -17,17 +17,17 @@
 
 # With all three set, we should prefer GOCACHE.
 go env GOCACHE
-stdout '\$WORK/gocache$'
+stdout $WORK'/gocache$'
 
 # Without GOCACHE, we should prefer XDG_CACHE_HOME over HOME.
 env GOCACHE=
 go env GOCACHE
-stdout '\$WORK/xdg/go-build$$'
+stdout $WORK'/xdg/go-build$$'
 
 # With only HOME set, we should use $HOME/.cache.
 env XDG_CACHE_HOME=
 go env GOCACHE
-stdout '\$WORK/home/.cache/go-build$'
+stdout $WORK'/home/.cache/go-build$'
 
 # With no guidance from the environment, we must disable the cache, but that
 # should not cause commands that do not write to the cache to fail.
diff --git a/src/cmd/go/testdata/script/cache_vet.txt b/src/cmd/go/testdata/script/cache_vet.txt
index 928024e..6689048 100644
--- a/src/cmd/go/testdata/script/cache_vet.txt
+++ b/src/cmd/go/testdata/script/cache_vet.txt
@@ -2,7 +2,7 @@
 
 [short] skip
 [GODEBUG:gocacheverify=1] skip
-[gccgo] skip  # gccgo has no standard packages
+[compiler:gccgo] skip  # gccgo has no standard packages
 
 # Start with a clean build cache:
 # test failures may be masked if the cache has just the right entries already.
diff --git a/src/cmd/go/testdata/script/cgo_bad_directives.txt b/src/cmd/go/testdata/script/cgo_bad_directives.txt
index 6bf3beb..7d28171 100644
--- a/src/cmd/go/testdata/script/cgo_bad_directives.txt
+++ b/src/cmd/go/testdata/script/cgo_bad_directives.txt
@@ -4,9 +4,9 @@
 cp x.go.txt x.go
 
 # Only allow //go:cgo_ldflag .* in cgo-generated code
-[gc] cp x_gc.go.txt x.go
-[gc] ! go build x
-[gc] stderr '//go:cgo_ldflag .* only allowed in cgo-generated code'
+[compiler:gc] cp x_gc.go.txt x.go
+[compiler:gc] ! go build x
+[compiler:gc] stderr '//go:cgo_ldflag .* only allowed in cgo-generated code'
 
 # Ignore _* files
 rm x.go
@@ -16,11 +16,11 @@
 ! go build .
 stderr 'no Go files' #_* files are ignored...
 
-[gc] ! go build _cgo_yy.go # ... but if forced, the comment is rejected
+[compiler:gc] ! go build _cgo_yy.go # ... but if forced, the comment is rejected
 # Actually, today there is a separate issue that _ files named
 # on the command line are ignored. Once that is fixed,
 # we want to see the cgo_ldflag error.
-[gc] stderr '//go:cgo_ldflag only allowed in cgo-generated code|no Go files'
+[compiler:gc] stderr '//go:cgo_ldflag only allowed in cgo-generated code|no Go files'
 
 rm _cgo_yy.go
 
diff --git a/src/cmd/go/testdata/script/cgo_path.txt b/src/cmd/go/testdata/script/cgo_path.txt
index 1f84dbc..88f57f0 100644
--- a/src/cmd/go/testdata/script/cgo_path.txt
+++ b/src/cmd/go/testdata/script/cgo_path.txt
@@ -8,10 +8,10 @@
 [!exec:clang] [!exec:gcc] skip 'Unknown C compiler'
 
 env GOCACHE=$WORK/gocache  # Looking for compile flags, so need a clean cache.
-[!windows] env PATH=.:$PATH
-[!windows] chmod 0755 p/gcc p/clang
-[!windows] exists -exec p/gcc p/clang
-[windows] exists -exec p/gcc.bat p/clang.bat
+[!GOOS:windows] env PATH=.:$PATH
+[!GOOS:windows] chmod 0755 p/gcc p/clang
+[!GOOS:windows] exists -exec p/gcc p/clang
+[GOOS:windows] exists -exec p/gcc.bat p/clang.bat
 ! exists p/bug.txt
 ! go build -x
 stderr '^cgo: C compiler "(clang|gcc)" not found: exec: "(clang|gcc)": cannot run executable found relative to current directory'
diff --git a/src/cmd/go/testdata/script/cgo_path_space.txt b/src/cmd/go/testdata/script/cgo_path_space.txt
index 654295d..1a78902 100644
--- a/src/cmd/go/testdata/script/cgo_path_space.txt
+++ b/src/cmd/go/testdata/script/cgo_path_space.txt
@@ -10,14 +10,14 @@
 [exec:gcc] env CC=gcc
 [!exec:clang] [!exec:gcc] skip 'Unknown C compiler'
 
-[!windows] chmod 0755 $WORK/'program files'/clang
-[!windows] chmod 0755 $WORK/'program files'/gcc
-[!windows] exists -exec $WORK/'program files'/clang
-[!windows] exists -exec $WORK/'program files'/gcc
-[!windows] env PATH=$WORK/'program files':$PATH
-[windows] exists -exec $WORK/'program files'/gcc.bat
-[windows] exists -exec $WORK/'program files'/clang.bat
-[windows] env PATH=$WORK\'program files';%PATH%
+[!GOOS:windows] chmod 0755 $WORK/'program files'/clang
+[!GOOS:windows] chmod 0755 $WORK/'program files'/gcc
+[!GOOS:windows] exists -exec $WORK/'program files'/clang
+[!GOOS:windows] exists -exec $WORK/'program files'/gcc
+[!GOOS:windows] env PATH=$WORK/'program files':$PATH
+[GOOS:windows] exists -exec $WORK/'program files'/gcc.bat
+[GOOS:windows] exists -exec $WORK/'program files'/clang.bat
+[GOOS:windows] env PATH=$WORK\'program files';%PATH%
 
 ! exists $WORK/log.txt
 ? go build -x
@@ -28,8 +28,8 @@
 # contain spaces separating arguments, and it should be possible to quote
 # arguments with spaces (including the path), as in CGO_CFLAGS and other
 # variables. For now, this doesn't work.
-[!windows] env CC=$WORK/'program files'/gcc
-[windows] env CC=$WORK\'program files'\gcc.bat
+[!GOOS:windows] env CC=$WORK/'program files'/gcc
+[GOOS:windows] env CC=$WORK\'program files'\gcc.bat
 ! go build -x
 ! exists $WORK/log.txt
 
diff --git a/src/cmd/go/testdata/script/cgo_stale.txt b/src/cmd/go/testdata/script/cgo_stale.txt
index 9e46855..0d30aea 100644
--- a/src/cmd/go/testdata/script/cgo_stale.txt
+++ b/src/cmd/go/testdata/script/cgo_stale.txt
@@ -12,21 +12,21 @@
 
 
 # If we then build a package that uses cgo, runtime/cgo should be rebuilt and
-# cached with the new flag, but not installed to GOROOT (and thus still stale).
+# cached with the new flag, but not installed to GOROOT.
+# It has no install target, and thus is never stale.
 
 env GOCACHE=$WORK/cache  # Use a fresh cache to avoid interference between runs.
 
 go build -x .
 stderr '[/\\]cgo'$GOEXE'["]? .* -importpath runtime/cgo'
-stale runtime/cgo
+! stale runtime/cgo
 
 
-# After runtime/cgo has been rebuilt and cached, it should not be rebuilt again
-# even though it is still reported as stale.
+# After runtime/cgo has been rebuilt and cached, it should not be rebuilt again.
 
 go build -x .
 ! stderr '[/\\]cgo'$GOEXE'["]? .* -importpath runtime/cgo'
-stale runtime/cgo
+! stale runtime/cgo
 
 
 -- go.mod --
diff --git a/src/cmd/go/testdata/script/cgo_stale_precompiled.txt b/src/cmd/go/testdata/script/cgo_stale_precompiled.txt
index 80ed751..eb7e105 100644
--- a/src/cmd/go/testdata/script/cgo_stale_precompiled.txt
+++ b/src/cmd/go/testdata/script/cgo_stale_precompiled.txt
@@ -16,13 +16,21 @@
 go build -x runtime/cgo
 [!short] stderr '[/\\]cgo'$GOEXE'["]? .* -importpath runtime/cgo'
 
-# https://go.dev/issue/47215: a missing $(go env CC) caused the precompiled net to be stale.
-[!plan9] env PATH=''  # Guaranteed not to include $(go env CC)!
-[plan9] env path=''
-go build -x runtime/cgo
-! stderr '[/\\]cgo'$GOEXE'["]? .* -importpath runtime/cgo'
-
 # https://go.dev/issue/50183: a mismatched GOROOT_FINAL caused net to be stale.
+env oldGOROOT_FINAL=$GOROOT_FINAL
 env GOROOT_FINAL=$WORK${/}goroot
 go build -x runtime/cgo
 ! stderr '[/\\]cgo'$GOEXE'["]? .* -importpath runtime/cgo'
+
+env GOROOT_FINAL=$oldGOROOT_FINAL
+
+# https://go.dev/issue/47215: a missing $(go env CC) caused the precompiled net
+# to be stale. But as of https://go.dev/cl/452457 the precompiled libraries are
+# no longer installed anyway! Since we're requiring a C compiler in order to
+# build and use cgo libraries in the standard library, we should make sure it
+# matches what's in the cache.
+[!abscc] env CGO_ENABLED=1
+[!abscc] [!GOOS:plan9] env PATH=''  # Guaranteed not to include $(go env CC)!
+[!abscc] [GOOS:plan9] env path=''
+[!abscc] ! go build -x runtime/cgo
+[!abscc] stderr 'C compiler .* not found'
diff --git a/src/cmd/go/testdata/script/cgo_syso_issue29253.txt b/src/cmd/go/testdata/script/cgo_syso_issue29253.txt
index 4fb5cca..18526c6 100644
--- a/src/cmd/go/testdata/script/cgo_syso_issue29253.txt
+++ b/src/cmd/go/testdata/script/cgo_syso_issue29253.txt
@@ -4,7 +4,7 @@
 # This test tests that we can link in-package syso files that provides symbols
 # for cgo. See issue 29253.
 [!cgo] stop
-[!gc] stop
+[!compiler:gc] stop
 cc -c -o pkg/o.syso ext.c
 go build main.go
 
diff --git a/src/cmd/go/testdata/script/chdir.txt b/src/cmd/go/testdata/script/chdir.txt
new file mode 100644
index 0000000..8952d18
--- /dev/null
+++ b/src/cmd/go/testdata/script/chdir.txt
@@ -0,0 +1,31 @@
+env OLD=$PWD
+
+# basic -C functionality
+cd $GOROOT/src/math
+go list -C ../strings
+stdout strings
+! go list -C ../nonexist
+stderr 'chdir.*nonexist'
+
+# check for -C in subcommands with custom flag parsing
+# cmd/go/chdir_test.go handles the normal ones more directly.
+
+# go doc
+go doc -C ../strings HasPrefix
+
+# go env
+go env -C $OLD/custom GOMOD
+stdout 'custom[\\/]go.mod'
+! go env -C ../nonexist
+stderr '^invalid value "../nonexist" for flag -C: chdir ../nonexist:.*$'
+
+# go test
+go test -n -C ../strings
+stderr 'strings\.test'
+
+# go vet
+go vet -n -C ../strings
+stderr strings_test
+
+-- custom/go.mod --
+module m
diff --git a/src/cmd/go/testdata/script/check_goexperiment.txt b/src/cmd/go/testdata/script/check_goexperiment.txt
new file mode 100644
index 0000000..3434cb9
--- /dev/null
+++ b/src/cmd/go/testdata/script/check_goexperiment.txt
@@ -0,0 +1,10 @@
+# Test that [GOEXPERIMENT:x] is accepted.
+# Here fieldtrack is picked arbitrarily.
+
+[GOEXPERIMENT:nofieldtrack] env
+
+[GOEXPERIMENT:fieldtrack] env
+
+#[GOEXPERIMENT:crashme] env
+
+
diff --git a/src/cmd/go/testdata/script/clean_cache_n.txt b/src/cmd/go/testdata/script/clean_cache_n.txt
index 4497b36..72f9abf 100644
--- a/src/cmd/go/testdata/script/clean_cache_n.txt
+++ b/src/cmd/go/testdata/script/clean_cache_n.txt
@@ -15,6 +15,9 @@
 go clean -cache
 ! exists $GOCACHE/00
 
+! go clean -cache .
+stderr 'go: clean -cache cannot be used with package arguments'
+
 -- main.go --
 package main
 
diff --git a/src/cmd/go/testdata/script/clean_testcache.txt b/src/cmd/go/testdata/script/clean_testcache.txt
index b3f32fe..3f98602 100644
--- a/src/cmd/go/testdata/script/clean_testcache.txt
+++ b/src/cmd/go/testdata/script/clean_testcache.txt
@@ -8,6 +8,8 @@
 go clean -testcache
 go test x_test.go
 ! stdout 'cached'
+! go clean -testcache ../x
+stderr 'go: clean -testcache cannot be used with package arguments'
 
 # golang.org/issue/29100: 'go clean -testcache' should succeed
 # if the cache directory doesn't exist at all.
diff --git a/src/cmd/go/testdata/script/cover_asm.txt b/src/cmd/go/testdata/script/cover_asm.txt
index 57f76d6..c7b7114 100644
--- a/src/cmd/go/testdata/script/cover_asm.txt
+++ b/src/cmd/go/testdata/script/cover_asm.txt
@@ -1,5 +1,5 @@
 [short] skip
-[gccgo] skip # gccgo has no cover tool
+[compiler:gccgo] skip # gccgo has no cover tool
 
 # Test cover for a package that has an assembly function.
 
diff --git a/src/cmd/go/testdata/script/cover_build_cmdline_pkgs.txt b/src/cmd/go/testdata/script/cover_build_cmdline_pkgs.txt
new file mode 100644
index 0000000..ba38263
--- /dev/null
+++ b/src/cmd/go/testdata/script/cover_build_cmdline_pkgs.txt
@@ -0,0 +1,72 @@
+
+# This test is intended to verify that when a user does "go run -cover ..."
+# or "go build -cover ...", packages named on the command line are
+# always instrumented (but not their dependencies). This rule applies
+# inside and outside the standard library.
+
+[short] skip
+
+# Compile an object.
+go tool compile -p tiny tiny/tiny.go tiny/tiny2.go
+
+# Build a stdlib command with coverage.
+go build -o $WORK/nm.exe -cover cmd/nm 
+
+# Save off old GOCOVERDIR setting
+env SAVEGOCOVERDIR=$GOCOVERDIR
+
+# Collect a coverage profile from running 'cmd/nm' on the object.
+mkdir $WORK/covdata
+env GOCOVERDIR=$WORK/covdata
+exec $WORK/nm.exe tiny.o
+
+# Restore previous GOCOVERDIR setting
+env GOCOVERDIR=$SAVEGOCOVERDIR
+
+# Check to make sure we instrumented just the main package, not
+# any dependencies.
+go tool covdata pkglist -i=$WORK/covdata
+stdout cmd/nm
+! stdout cmd/internal/goobj pkglist.txt
+
+# ... now collect a coverage profile from a Go file
+# listed on the command line.
+go build -cover -o $WORK/another.exe testdata/another.go
+mkdir $WORK/covdata2
+env GOCOVERDIR=$WORK/covdata2
+exec $WORK/another.exe 
+
+# Restore previous GOCOVERDIR setting
+env GOCOVERDIR=$SAVEGOCOVERDIR
+
+# Check to make sure we instrumented just the main package.
+go tool covdata pkglist -i=$WORK/covdata2
+stdout command-line-arguments
+! stdout fmt
+
+-- go.mod --
+
+module example.prog
+
+-- testdata/another.go --
+
+package main
+
+import "fmt"
+
+func main() {
+  fmt.Println("Hi dad")
+}
+
+-- tiny/tiny.go --
+
+package tiny
+
+var Tvar int
+
+-- tiny/tiny2.go --
+
+package tiny
+
+var Tvar2 bool
+
diff --git a/src/cmd/go/testdata/script/cover_build_pkg_select.txt b/src/cmd/go/testdata/script/cover_build_pkg_select.txt
new file mode 100644
index 0000000..447ca77
--- /dev/null
+++ b/src/cmd/go/testdata/script/cover_build_pkg_select.txt
@@ -0,0 +1,114 @@
+# This test checks more of the "go build -cover" functionality,
+# specifically which packages get selected when building.
+
+[short] skip
+
+# Skip if new coverage is not enabled.
+[!GOEXPERIMENT:coverageredesign] skip
+
+#-------------------------------------------
+
+# Build for coverage.
+go build -mod=mod -o $WORK/modex.exe -cover mod.example/main
+
+# Save off old GOCOVERDIR setting
+env SAVEGOCOVERDIR=$GOCOVERDIR
+
+# Execute.
+mkdir $WORK/covdata
+env GOCOVERDIR=$WORK/covdata
+exec $WORK/modex.exe
+
+# Restore previous GOCOVERDIR setting
+env GOCOVERDIR=$SAVEGOCOVERDIR
+
+# Examine the result.
+go tool covdata percent -i=$WORK/covdata
+stdout 'coverage: 100.0% of statements'
+
+# By default we want to see packages resident in the module covered,
+# but not dependencies.
+go tool covdata textfmt -i=$WORK/covdata -o=$WORK/covdata/out.txt
+grep 'mode: set' $WORK/covdata/out.txt
+grep 'mod.example/main/main.go:' $WORK/covdata/out.txt
+grep 'mod.example/sub/sub.go:' $WORK/covdata/out.txt
+! grep 'rsc.io' $WORK/covdata/out.txt
+
+rm $WORK/covdata
+rm $WORK/modex.exe
+
+#-------------------------------------------
+
+# Repeat the build but with -coverpkg=all
+
+go build -mod=mod -coverpkg=all -o $WORK/modex.exe -cover mod.example/main
+
+# Execute.
+mkdir $WORK/covdata
+env GOCOVERDIR=$WORK/covdata
+exec $WORK/modex.exe
+
+# Restore previous GOCOVERDIR setting
+env GOCOVERDIR=$SAVEGOCOVERDIR
+
+# Examine the result.
+go tool covdata percent -i=$WORK/covdata
+stdout  'coverage:.*[1-9][0-9.]+%'
+
+# The whole enchilada.
+go tool covdata textfmt -i=$WORK/covdata -o=$WORK/covdata/out.txt
+grep 'mode: set' $WORK/covdata/out.txt
+grep 'mod.example/main/main.go:' $WORK/covdata/out.txt
+grep 'mod.example/sub/sub.go:' $WORK/covdata/out.txt
+grep 'rsc.io' $WORK/covdata/out.txt
+grep 'bufio/bufio.go:' $WORK/covdata/out.txt
+
+# Use the covdata tool to select a specific set of module paths
+mkdir $WORK/covdata2
+go tool covdata merge -pkg=rsc.io/quote -i=$WORK/covdata -o=$WORK/covdata2
+
+# Examine the result.
+go tool covdata percent -i=$WORK/covdata2
+stdout  'coverage:.*[1-9][0-9.]+%'
+
+# Check for expected packages + check that we don't see things from stdlib.
+go tool covdata textfmt -i=$WORK/covdata2 -o=$WORK/covdata2/out.txt
+grep 'mode: set' $WORK/covdata2/out.txt
+! grep 'mod.example/main/main.go:' $WORK/covdata2/out.txt
+! grep 'mod.example/sub/sub.go:' $WORK/covdata2/out.txt
+grep 'rsc.io' $WORK/covdata2/out.txt
+! grep 'bufio/bufio.go:' $WORK/covdata2/out.txt
+
+#-------------------------------------------
+# end of test cmds, start of harness and related files.
+
+-- go.mod --
+module mod.example
+
+go 1.20
+
+require rsc.io/quote/v3 v3.0.0
+
+-- main/main.go --
+package main
+
+import (
+	"fmt"
+	"mod.example/sub"
+
+	"rsc.io/quote"
+)
+
+func main() {
+	fmt.Println(quote.Go(), sub.F())
+}
+
+-- sub/sub.go --
+
+package sub
+
+func F() int {
+	return 42
+}
+
+
diff --git a/src/cmd/go/testdata/script/cover_build_simple.txt b/src/cmd/go/testdata/script/cover_build_simple.txt
new file mode 100644
index 0000000..b61e631
--- /dev/null
+++ b/src/cmd/go/testdata/script/cover_build_simple.txt
@@ -0,0 +1,149 @@
+# This test checks basic "go build -cover" functionality.
+
+[short] skip
+
+# Hard-wire new coverage for this test.
+env GOEXPERIMENT=coverageredesign
+
+# Build for coverage.
+go build -gcflags=-m -o example.exe -cover example/main &
+[race] go build -o examplewithrace.exe -race -cover example/main &
+wait
+
+# First execute without GOCOVERDIR set...
+env GOCOVERDIR=
+exec ./example.exe normal
+stderr '^warning: GOCOVERDIR not set, no coverage data emitted'
+
+# ... then with GOCOVERDIR set.
+env GOCOVERDIR=data/normal
+exec ./example.exe normal
+! stderr '^warning: GOCOVERDIR not set, no coverage data emitted'
+go tool covdata percent -i=data/normal
+stdout  'coverage:.*[1-9][0-9.]+%'
+
+# Program makes a direct call to os.Exit(0).
+env GOCOVERDIR=data/goodexit
+exec ./example.exe goodexit
+! stderr '^warning: GOCOVERDIR not set, no coverage data emitted'
+go tool covdata percent -i=data/goodexit
+stdout  'coverage:.*[1-9][0-9.]+%'
+
+# Program makes a direct call to os.Exit(1).
+env GOCOVERDIR=data/badexit
+! exec ./example.exe badexit
+! stderr '^warning: GOCOVERDIR not set, no coverage data emitted'
+go tool covdata percent -i=data/badexit
+stdout  'coverage:.*[1-9][0-9.]+%'
+
+# Program invokes panic.
+env GOCOVERDIR=data/panic
+! exec ./example.exe panic
+! stderr '^warning: GOCOVERDIR not set, no coverage data emitted'
+go tool covdata percent -i=data/panic
+stdout  'coverage:.*[0-9.]+%'
+
+# Skip remainder if no race detector support.
+[!race] skip
+
+env GOCOVERDIR=data2/normal
+exec ./examplewithrace.exe normal
+! stderr '^warning: GOCOVERDIR not set, no coverage data emitted'
+go tool covdata percent -i=data2/normal
+stdout  'coverage:.*[1-9][0-9.]+%'
+
+# Program makes a direct call to os.Exit(0).
+env GOCOVERDIR=data2/goodexit
+exec ./examplewithrace.exe goodexit
+! stderr '^warning: GOCOVERDIR not set, no coverage data emitted'
+go tool covdata percent -i=data2/goodexit
+stdout  'coverage:.*[1-9][0-9.]+%'
+
+# Program makes a direct call to os.Exit(1).
+env GOCOVERDIR=data2/badexit
+! exec ./examplewithrace.exe badexit
+! stderr '^warning: GOCOVERDIR not set, no coverage data emitted'
+go tool covdata percent -i=data2/badexit
+stdout  'coverage:.*[1-9][0-9.]+%'
+
+# Program invokes panic.
+env GOCOVERDIR=data2/panic
+! exec ./examplewithrace.exe panic
+! stderr '^warning: GOCOVERDIR not set, no coverage data emitted'
+go tool covdata percent -i=data2/panic
+stdout  'coverage:.*[0-9.]+%'
+
+# end of test cmds, start of harness and related files.
+
+-- go.mod --
+module example
+
+go 1.18
+
+-- main/example.go --
+package main
+
+import "example/sub"
+
+func main() {
+	sub.S()
+}
+
+-- sub/sub.go --
+
+package sub
+
+import "os"
+
+func S() {
+	switch os.Args[1] {
+	case "normal":
+		println("hi")
+	case "goodexit":
+		os.Exit(0)
+	case "badexit":
+		os.Exit(1)
+	case "panic":
+		panic("something bad happened")
+	}
+}
+
+-- data/README.txt --
+
+Just a location where we can write coverage profiles.
+
+-- data/normal/f.txt --
+
+X
+
+-- data/goodexit/f.txt --
+
+X
+
+-- data/badexit/f.txt --
+
+X
+
+-- data/panic/f.txt --
+
+X
+
+-- data2/README.txt --
+
+Just a location where we can write coverage profiles.
+
+-- data2/normal/f.txt --
+
+X
+
+-- data2/goodexit/f.txt --
+
+X
+
+-- data2/badexit/f.txt --
+
+X
+
+-- data2/panic/f.txt --
+
+X
diff --git a/src/cmd/go/testdata/script/cover_cgo.txt b/src/cmd/go/testdata/script/cover_cgo.txt
index 9cf78f7..85754b5 100644
--- a/src/cmd/go/testdata/script/cover_cgo.txt
+++ b/src/cmd/go/testdata/script/cover_cgo.txt
@@ -1,6 +1,6 @@
 [short] skip
 [!cgo] skip
-[gccgo] skip # gccgo has no cover tool
+[compiler:gccgo] skip # gccgo has no cover tool
 
 # Test coverage on cgo code.
 
diff --git a/src/cmd/go/testdata/script/cover_cgo_extra_file.txt b/src/cmd/go/testdata/script/cover_cgo_extra_file.txt
index c53b979..afc2178 100644
--- a/src/cmd/go/testdata/script/cover_cgo_extra_file.txt
+++ b/src/cmd/go/testdata/script/cover_cgo_extra_file.txt
@@ -1,6 +1,6 @@
 [short] skip
 [!cgo] skip
-[gccgo] skip # gccgo has no cover tool
+[compiler:gccgo] skip # gccgo has no cover tool
 
 # Test coverage on cgo code. This test case includes an
 # extra empty non-cgo file in the package being checked.
diff --git a/src/cmd/go/testdata/script/cover_cgo_extra_test.txt b/src/cmd/go/testdata/script/cover_cgo_extra_test.txt
index b501ab0..ad09bab 100644
--- a/src/cmd/go/testdata/script/cover_cgo_extra_test.txt
+++ b/src/cmd/go/testdata/script/cover_cgo_extra_test.txt
@@ -1,6 +1,6 @@
 [short] skip
 [!cgo] skip
-[gccgo] skip # gccgo has no cover tool
+[compiler:gccgo] skip # gccgo has no cover tool
 
 # Test coverage on cgo code. This test case has an external
 # test that tests the code and an in-package test file with
diff --git a/src/cmd/go/testdata/script/cover_cgo_xtest.txt b/src/cmd/go/testdata/script/cover_cgo_xtest.txt
index 79cc08c..0900a48 100644
--- a/src/cmd/go/testdata/script/cover_cgo_xtest.txt
+++ b/src/cmd/go/testdata/script/cover_cgo_xtest.txt
@@ -1,6 +1,6 @@
 [short] skip
 [!cgo] skip
-[gccgo] skip # gccgo has no cover tool
+[compiler:gccgo] skip # gccgo has no cover tool
 
 # Test cgo coverage with an external test.
 
diff --git a/src/cmd/go/testdata/script/cover_dash_c.txt b/src/cmd/go/testdata/script/cover_dash_c.txt
index 8950f8d..f28c69e 100644
--- a/src/cmd/go/testdata/script/cover_dash_c.txt
+++ b/src/cmd/go/testdata/script/cover_dash_c.txt
@@ -1,5 +1,5 @@
 [short] skip
-[gccgo] skip
+[compiler:gccgo] skip
 
 # Test for issue 24588
 
diff --git a/src/cmd/go/testdata/script/cover_dep_loop.txt b/src/cmd/go/testdata/script/cover_dep_loop.txt
index 36ea6e0..46748e1 100644
--- a/src/cmd/go/testdata/script/cover_dep_loop.txt
+++ b/src/cmd/go/testdata/script/cover_dep_loop.txt
@@ -1,5 +1,5 @@
 [short] skip
-[gccgo] skip
+[compiler:gccgo] skip
 
 # coverdep2/p1's xtest imports coverdep2/p2 which imports coverdep2/p1.
 # Make sure that coverage on coverdep2/p2 recompiles coverdep2/p2.
diff --git a/src/cmd/go/testdata/script/cover_dot_import.txt b/src/cmd/go/testdata/script/cover_dot_import.txt
index d492e42..a336b1c 100644
--- a/src/cmd/go/testdata/script/cover_dot_import.txt
+++ b/src/cmd/go/testdata/script/cover_dot_import.txt
@@ -1,5 +1,5 @@
 [short] skip
-[gccgo] skip # gccgo has no cover tool
+[compiler:gccgo] skip # gccgo has no cover tool
 
 go test -coverpkg=coverdot/a,coverdot/b coverdot/b
 ! stderr '[^0-9]0\.0%'
diff --git a/src/cmd/go/testdata/script/cover_error.txt b/src/cmd/go/testdata/script/cover_error.txt
index 583a664..fa4b58b 100644
--- a/src/cmd/go/testdata/script/cover_error.txt
+++ b/src/cmd/go/testdata/script/cover_error.txt
@@ -1,21 +1,16 @@
 [short] skip
-[gccgo] skip
+[compiler:gccgo] skip
 
 # Test line numbers in cover errors.
 
 # Get errors from a go test into stderr.txt
 ! go test coverbad
-stderr 'p\.go:4' # look for error at coverbad/p.go:4
-[cgo] stderr 'p1\.go:6' # look for error at coverbad/p.go:6
+stderr 'p\.go:4:2' # look for error at coverbad/p.go:4
+[cgo] stderr 'p1\.go:6:2' # look for error at coverbad/p.go:6
 ! stderr $WORK # make sure temporary directory isn't in error
 
 cp stderr $WORK/stderr.txt
 
-# Clean out character positions from stderr.txt
-# It's OK that stderr2 drops the character position in the error,
-# because of the //line directive (see golang.org/issue/22662).
-go run clean_charpos.go $WORK/stderr.txt &
-
 # Get errors from coverage into stderr2.txt
 ! go test -cover coverbad
 cp stderr $WORK/stderr2.txt
@@ -48,27 +43,3 @@
 import "testing"
 
 func Test(t *testing.T) {}
--- clean_charpos.go --
-// +build ignore
-
-package main
-
-import (
-	"log"
-	"os"
-	"strings"
-)
-
-func main() {
-	log.SetFlags(0)
-	b, err := os.ReadFile(os.Args[1])
-	if err != nil {
-		log.Fatal(err)
-	}
-	s := strings.ReplaceAll(string(b), "p.go:4:2:", "p.go:4:")
-	s = strings.ReplaceAll(s, "p1.go:6:2:", "p1.go:6:")
-	os.WriteFile(os.Args[1], []byte(s), 0644)
-	if err != nil {
-		log.Fatal(err)
-	}
-}
diff --git a/src/cmd/go/testdata/script/cover_import_main_loop.txt b/src/cmd/go/testdata/script/cover_import_main_loop.txt
index eb6de67..36a09c2 100644
--- a/src/cmd/go/testdata/script/cover_import_main_loop.txt
+++ b/src/cmd/go/testdata/script/cover_import_main_loop.txt
@@ -1,4 +1,4 @@
-[gccgo] skip # gccgo has no cover tool
+[compiler:gccgo] skip # gccgo has no cover tool
 
 ! go test -n importmain/test
 stderr 'not an importable package' # check that import main was detected
diff --git a/src/cmd/go/testdata/script/cover_list.txt b/src/cmd/go/testdata/script/cover_list.txt
new file mode 100644
index 0000000..c66c087
--- /dev/null
+++ b/src/cmd/go/testdata/script/cover_list.txt
@@ -0,0 +1,28 @@
+
+# This test is intended to verify that "go list" accepts coverage related
+# build arguments (such as -cover, -covermode). See issue #57785.
+
+[short] skip
+[!GOEXPERIMENT:coverageredesign] skip
+
+env GOBIN=$WORK/bin
+
+# Install a target and then do an ordinary staleness check on it.
+go install m/example
+! stale m/example
+
+# Run a second staleness check with "-cover" as a build flag. The
+# installed target should indeed be stale, since we didn't build it
+# with -cover.
+stale -cover m/example
+
+-- go.mod --
+module m
+
+go 1.20
+-- example/main.go --
+package main
+
+func main() {
+     println("hi mom")
+}
diff --git a/src/cmd/go/testdata/script/cover_main_import_path.txt b/src/cmd/go/testdata/script/cover_main_import_path.txt
new file mode 100644
index 0000000..3a2f3c3
--- /dev/null
+++ b/src/cmd/go/testdata/script/cover_main_import_path.txt
@@ -0,0 +1,54 @@
+
+# This test is intended to verify that coverage reporting is consistent
+# between "go test -cover" and "go build -cover" with respect to how
+# the "main" package is handled. See issue 57169 for details.
+
+[short] skip
+
+# Build this program with -cover and run to collect a profile.
+
+go build -cover -o $WORK/prog.exe .
+
+# Save off old GOCOVERDIR setting
+env SAVEGOCOVERDIR=$GOCOVERDIR
+
+mkdir $WORK/covdata
+env GOCOVERDIR=$WORK/covdata
+exec $WORK/prog.exe
+
+# Restore previous GOCOVERDIR setting
+env GOCOVERDIR=$SAVEGOCOVERDIR
+
+# Report percent lines covered.
+go tool covdata percent -i=$WORK/covdata
+stdout '\s*mainwithtest\s+coverage:'
+! stdout 'main\s+coverage:'
+
+# Go test -cover should behave the same way.
+go test -cover .
+stdout 'ok\s+mainwithtest\s+\S+\s+coverage:'
+! stdout 'ok\s+main\s+.*'
+
+
+-- go.mod --
+module mainwithtest
+
+go 1.20
+-- mymain.go --
+package main
+
+func main() {
+	println("hi mom")
+}
+
+func Mainer() int {
+	return 42
+}
+-- main_test.go --
+package main
+
+import "testing"
+
+func TestCoverage(t *testing.T) {
+	println(Mainer())
+}
diff --git a/src/cmd/go/testdata/script/cover_modes.txt b/src/cmd/go/testdata/script/cover_modes.txt
index f8a399d..a27296e 100644
--- a/src/cmd/go/testdata/script/cover_modes.txt
+++ b/src/cmd/go/testdata/script/cover_modes.txt
@@ -4,7 +4,7 @@
 # and should merge coverage profiles correctly.
 
 [short] skip
-[gccgo] skip # gccgo has no cover tool
+[compiler:gccgo] skip # gccgo has no cover tool
 
 go test -short -cover encoding/binary errors -coverprofile=$WORK/cover.out
 ! stderr '[^0-9]0\.0%'
diff --git a/src/cmd/go/testdata/script/cover_pattern.txt b/src/cmd/go/testdata/script/cover_pattern.txt
index ec0850c..6c79c10 100644
--- a/src/cmd/go/testdata/script/cover_pattern.txt
+++ b/src/cmd/go/testdata/script/cover_pattern.txt
@@ -1,4 +1,4 @@
-[gccgo] skip
+[compiler:gccgo] skip
 
 # If coverpkg=m/sleepy... expands by package loading
 # (as opposed to pattern matching on deps)
diff --git a/src/cmd/go/testdata/script/cover_runs.txt b/src/cmd/go/testdata/script/cover_runs.txt
index 38a7bb7..6df6096 100644
--- a/src/cmd/go/testdata/script/cover_runs.txt
+++ b/src/cmd/go/testdata/script/cover_runs.txt
@@ -1,4 +1,4 @@
-[gccgo] skip 'gccgo has no cover tool'
+[compiler:gccgo] skip 'gccgo has no cover tool'
 [short] skip
 
 go test -short -coverpkg=strings strings regexp
diff --git a/src/cmd/go/testdata/script/cover_sync_atomic_import.txt b/src/cmd/go/testdata/script/cover_sync_atomic_import.txt
index 433af9a..b933cdb 100644
--- a/src/cmd/go/testdata/script/cover_sync_atomic_import.txt
+++ b/src/cmd/go/testdata/script/cover_sync_atomic_import.txt
@@ -1,8 +1,23 @@
 [short] skip
-[gccgo] skip # gccgo has no cover tool
+[compiler:gccgo] skip # gccgo has no cover tool
 
 go test -short -cover -covermode=atomic -coverpkg=coverdep/p1 coverdep
 
+# In addition to the above, test to make sure there is no funny
+# business if we try "go test -cover" in atomic mode targeting
+# sync/atomic itself (see #57445). Just a short test run is needed
+# since we're mainly interested in making sure the test builds and can
+# execute at least one test.
+
+go test -short -covermode=atomic -run=TestStoreInt64 sync/atomic
+go test -short -covermode=atomic -run=TestAnd8 runtime/internal/atomic
+
+# Skip remainder if no race detector support.
+[!race] skip
+
+go test -short -cover -race -run=TestStoreInt64 sync/atomic
+go test -short -cover -race -run=TestAnd8 runtime/internal/atomic
+
 -- go.mod --
 module coverdep
 
diff --git a/src/cmd/go/testdata/script/cover_test_localpkg_filepath.txt b/src/cmd/go/testdata/script/cover_test_localpkg_filepath.txt
new file mode 100644
index 0000000..17c5808
--- /dev/null
+++ b/src/cmd/go/testdata/script/cover_test_localpkg_filepath.txt
@@ -0,0 +1,40 @@
+
+[short] skip
+
+# collect coverage profile in text format
+go test -coverprofile=blah.prof prog.go prog_test.go
+
+# should not contain cmd-line pseudo-import-path
+grep prog.go blah.prof
+grep $PWD blah.prof
+! grep command-line-arguments blah.prof
+
+-- prog.go --
+package main
+
+func Mumble(x int) int {
+	if x < 0 {
+		return -x
+	}
+	return 42
+}
+
+func Grumble(y int) int {
+	return -y
+}
+
+func main() {
+}
+
+-- prog_test.go --
+package main
+
+import (
+	"testing"
+)
+
+func TestMumble(t *testing.T) {
+	if x := Mumble(10); x != 42 {
+		t.Errorf("Mumble(%d): got %d want %d", 10, x, 42)
+	}
+}
diff --git a/src/cmd/go/testdata/script/cover_test_pkgselect.txt b/src/cmd/go/testdata/script/cover_test_pkgselect.txt
new file mode 100644
index 0000000..97a1d2c
--- /dev/null
+++ b/src/cmd/go/testdata/script/cover_test_pkgselect.txt
@@ -0,0 +1,80 @@
+
+[short] skip
+
+# Hard-wire new coverage for this test.
+env GOEXPERIMENT=coverageredesign
+
+# Baseline run.
+go test -cover example/foo
+stdout 'coverage: 50.0% of statements$'
+
+# Coverage percentage output should mention -coverpkg selection.
+go test -coverpkg=example/foo example/foo
+stdout 'coverage: 50.0% of statements in example/foo'
+
+# Try to ask for coverage of a package that doesn't exist.
+go test -coverpkg nonexistent example/bar
+stderr 'no packages being tested depend on matches for pattern nonexistent'
+stdout 'coverage: \[no statements\]'
+
+# Ask for foo coverage, but test bar.
+go test -coverpkg=example/foo example/bar
+stdout 'coverage: 50.0% of statements in example/foo'
+
+# end of test cmds, start of harness and related files.
+
+-- go.mod --
+module example
+
+go 1.18
+
+-- foo/foo.go --
+package foo
+
+func FooFunc() int {
+	return 42
+}
+func FooFunc2() int {
+	return 42
+}
+
+-- foo/foo_test.go --
+package foo
+
+import "testing"
+
+func TestFoo(t *testing.T) {
+	if FooFunc() != 42 {
+		t.Fatalf("bad")
+	}
+}
+
+-- bar/bar.go --
+package bar
+
+import "example/foo"
+
+func BarFunc() int {
+	return foo.FooFunc2()
+}
+
+-- bar/bar_test.go --
+package bar_test
+
+import (
+	"example/bar"
+	"testing"
+)
+
+func TestBar(t *testing.T) {
+	if bar.BarFunc() != 42 {
+		t.Fatalf("bad")
+	}
+}
+
+-- baz/baz.go --
+package baz
+
+func BazFunc() int {
+	return -42
+}
diff --git a/src/cmd/go/testdata/script/cover_test_race_issue56370.txt b/src/cmd/go/testdata/script/cover_test_race_issue56370.txt
new file mode 100644
index 0000000..2e55f10
--- /dev/null
+++ b/src/cmd/go/testdata/script/cover_test_race_issue56370.txt
@@ -0,0 +1,54 @@
+[short] skip
+[!race] skip
+
+go test -race -cover issue.56370/filter
+
+-- go.mod --
+module issue.56370
+
+go 1.20
+
+-- filter/filter.go --
+
+package filter
+
+func New() func(error) bool {
+	return func(error) bool {
+		return false
+	}
+}
+
+-- filter/filter_test.go --
+
+package filter_test
+
+import (
+	"testing"
+
+	"issue.56370/filter"
+)
+
+func Test1(t *testing.T) {
+	t.Parallel()
+
+	_ = filter.New()
+}
+
+func Test2(t *testing.T) {
+	t.Parallel()
+
+	_ = filter.New()
+}
+
+func Test3(t *testing.T) {
+	t.Parallel()
+
+	_ = filter.New()
+}
+
+func Test4(t *testing.T) {
+	t.Parallel()
+
+	_ = filter.New()
+}
+
diff --git a/src/cmd/go/testdata/script/cover_var_init_order.txt b/src/cmd/go/testdata/script/cover_var_init_order.txt
new file mode 100644
index 0000000..37e07b7
--- /dev/null
+++ b/src/cmd/go/testdata/script/cover_var_init_order.txt
@@ -0,0 +1,55 @@
+# This test verifies that issue 56293 has been fixed, and that the
+# insertion of coverage instrumentation doesn't perturb package
+# initialization order.
+
+[short] skip
+
+# Skip if new coverage is turned off.
+[!GOEXPERIMENT:coverageredesign] skip
+
+go test -cover example
+
+-- go.mod --
+module example
+
+go 1.20
+
+-- m.go --
+
+package main
+
+import (
+	"flag"
+)
+
+var (
+	fooFlag = flag.String("foo", "", "this should be ok")
+	foo     = flag.Lookup("foo")
+
+	barFlag = flag.String("bar", "", "this should be also ok, but is "+notOK()+".")
+	bar     = flag.Lookup("bar")
+)
+
+func notOK() string {
+	return "not OK"
+}
+
+-- m_test.go --
+
+package main
+
+import (
+	"testing"
+)
+
+func TestFoo(t *testing.T) {
+	if foo == nil {
+		t.Fatal()
+	}
+}
+
+func TestBar(t *testing.T) {
+	if bar == nil {
+		t.Fatal()
+	}
+}
diff --git a/src/cmd/go/testdata/script/embed_brackets.txt b/src/cmd/go/testdata/script/embed_brackets.txt
index 7093a84..ec17ff3 100644
--- a/src/cmd/go/testdata/script/embed_brackets.txt
+++ b/src/cmd/go/testdata/script/embed_brackets.txt
@@ -1,5 +1,5 @@
 # issue 53314
-[windows] skip
+[GOOS:windows] skip
 cd [pkg]
 go build
 
diff --git a/src/cmd/go/testdata/script/env_cache.txt b/src/cmd/go/testdata/script/env_cache.txt
new file mode 100644
index 0000000..f2af7ee
--- /dev/null
+++ b/src/cmd/go/testdata/script/env_cache.txt
@@ -0,0 +1,5 @@
+# go env should caches compiler results
+go env
+go env -x
+! stdout '\|\| true'
+
diff --git a/src/cmd/go/testdata/script/env_write.txt b/src/cmd/go/testdata/script/env_write.txt
index 132947c..ccd0eb3 100644
--- a/src/cmd/go/testdata/script/env_write.txt
+++ b/src/cmd/go/testdata/script/env_write.txt
@@ -4,14 +4,14 @@
 env AppData=$HOME/windowsappdata
 env home=$HOME/plan9home
 go env GOENV
-[aix] stdout $HOME/.config/go/env
-[darwin] stdout $HOME'/Library/Application Support/go/env'
-[freebsd] stdout $HOME/.config/go/env
-[linux] stdout $HOME/.config/go/env
-[netbsd] stdout $HOME/.config/go/env
-[openbsd] stdout $HOME/.config/go/env
-[plan9] stdout $HOME/plan9home/lib/go/env
-[windows] stdout $HOME\\windowsappdata\\go\\env
+[GOOS:aix] stdout $HOME/.config/go/env
+[GOOS:darwin] stdout $HOME'/Library/Application Support/go/env'
+[GOOS:freebsd] stdout $HOME/.config/go/env
+[GOOS:linux] stdout $HOME/.config/go/env
+[GOOS:netbsd] stdout $HOME/.config/go/env
+[GOOS:openbsd] stdout $HOME/.config/go/env
+[GOOS:plan9] stdout $HOME/plan9home/lib/go/env
+[GOOS:windows] stdout $HOME\\windowsappdata\\go\\env
 
 # Now override it to something writable.
 env GOENV=$WORK/envdir/go/env
@@ -36,7 +36,7 @@
 
 # go env -w changes default setting
 env root=
-[windows] env root=c:
+[GOOS:windows] env root=c:
 env GOPATH=
 go env -w GOPATH=$root/non-exist/gopath
 ! stderr .+
@@ -115,43 +115,43 @@
 
 # go env -w should accept absolute GOTMPDIR value
 # and should not create it
-[windows] go env -w GOTMPDIR=$WORK\x\y\z
-[!windows] go env -w GOTMPDIR=$WORK/x/y/z
+[GOOS:windows] go env -w GOTMPDIR=$WORK\x\y\z
+[!GOOS:windows] go env -w GOTMPDIR=$WORK/x/y/z
 ! exists $WORK/x/y/z
 # we should be able to clear an env
 go env -u GOTMPDIR
 go env GOTMPDIR
 stdout ^$
 
-[windows] go env -w GOTMPDIR=$WORK\x\y\z
-[!windows] go env -w GOTMPDIR=$WORK/x/y/z
+[GOOS:windows] go env -w GOTMPDIR=$WORK\x\y\z
+[!GOOS:windows] go env -w GOTMPDIR=$WORK/x/y/z
 go env -w GOTMPDIR=
 go env GOTMPDIR
 stdout ^$
 
 # go env -w rejects relative CC values
-[!windows] go env -w CC=/usr/bin/clang
+[!GOOS:windows] go env -w CC=/usr/bin/clang
 go env -w CC=clang
-[!windows] ! go env -w CC=./clang
-[!windows] ! go env -w CC=bin/clang
-[!windows] stderr 'go: CC entry is relative; must be absolute path'
+[!GOOS:windows] ! go env -w CC=./clang
+[!GOOS:windows] ! go env -w CC=bin/clang
+[!GOOS:windows] stderr 'go: CC entry is relative; must be absolute path'
 
-[windows] go env -w CC=$WORK\bin\clang
-[windows] ! go env -w CC=.\clang
-[windows] ! go env -w CC=bin\clang
-[windows] stderr 'go: CC entry is relative; must be absolute path'
+[GOOS:windows] go env -w CC=$WORK\bin\clang
+[GOOS:windows] ! go env -w CC=.\clang
+[GOOS:windows] ! go env -w CC=bin\clang
+[GOOS:windows] stderr 'go: CC entry is relative; must be absolute path'
 
 # go env -w rejects relative CXX values
-[!windows] go env -w CC=/usr/bin/cpp
+[!GOOS:windows] go env -w CC=/usr/bin/cpp
 go env -w CXX=cpp
-[!windows] ! go env -w CXX=./cpp
-[!windows] ! go env -w CXX=bin/cpp
-[!windows] stderr 'go: CXX entry is relative; must be absolute path'
+[!GOOS:windows] ! go env -w CXX=./cpp
+[!GOOS:windows] ! go env -w CXX=bin/cpp
+[!GOOS:windows] stderr 'go: CXX entry is relative; must be absolute path'
 
-[windows] go env -w CXX=$WORK\bin\cpp
-[windows] ! go env -w CXX=.\cpp
-[windows] ! go env -w CXX=bin\cpp
-[windows] stderr 'go: CXX entry is relative; must be absolute path'
+[GOOS:windows] go env -w CXX=$WORK\bin\cpp
+[GOOS:windows] ! go env -w CXX=.\cpp
+[GOOS:windows] ! go env -w CXX=bin\cpp
+[GOOS:windows] stderr 'go: CXX entry is relative; must be absolute path'
 
 # go env -w/-u checks validity of GOOS/ARCH combinations
 env GOOS=
diff --git a/src/cmd/go/testdata/script/gccgo_m.txt b/src/cmd/go/testdata/script/gccgo_m.txt
index b63ba46..beb9c50 100644
--- a/src/cmd/go/testdata/script/gccgo_m.txt
+++ b/src/cmd/go/testdata/script/gccgo_m.txt
@@ -4,6 +4,7 @@
 env GO111MODULE=off
 
 [short] skip
+[cross] skip # gccgo can't necessarily cross-compile
 
 cd m
 go build
diff --git a/src/cmd/go/testdata/script/gcflags_patterns.txt b/src/cmd/go/testdata/script/gcflags_patterns.txt
index 0705277..918c32d 100644
--- a/src/cmd/go/testdata/script/gcflags_patterns.txt
+++ b/src/cmd/go/testdata/script/gcflags_patterns.txt
@@ -1,6 +1,6 @@
 env GO111MODULE=off
 
-[!gc] skip 'using -gcflags and -ldflags'
+[!compiler:gc] skip 'using -gcflags and -ldflags'
 [short] skip
 
 env GOCACHE=$WORK/gocache  # Looking for compile commands, so need a clean cache.
diff --git a/src/cmd/go/testdata/script/generate.txt b/src/cmd/go/testdata/script/generate.txt
index 73f5bbd..58777c5 100644
--- a/src/cmd/go/testdata/script/generate.txt
+++ b/src/cmd/go/testdata/script/generate.txt
@@ -17,11 +17,19 @@
 go generate './generate/substitution.go'
 stdout $GOARCH' substitution.go:7 pabc xyzp/substitution.go/123'
 
-# Test go generate's run flag
+# Test go generate's run and skip flags
 go generate -run y.s './generate/flag.go'
 stdout 'yes' # flag.go should select yes
 ! stdout 'no' # flag.go should not select no
 
+go generate -skip th..sand './generate/flag.go'
+stdout 'yes' # flag.go should select yes
+! stdout 'no' # flag.go should not select no
+
+go generate -run . -skip th..sand './generate/flag.go'
+stdout 'yes' # flag.go should select yes
+! stdout 'no' # flag.go should not select no
+
 # Test go generate provides the right "$GOPACKAGE" name in an x_test
 go generate './generate/env_test.go'
 stdout 'main_test'
diff --git a/src/cmd/go/testdata/script/generate_bad_imports.txt b/src/cmd/go/testdata/script/generate_bad_imports.txt
index 4d31573..3da391e 100644
--- a/src/cmd/go/testdata/script/generate_bad_imports.txt
+++ b/src/cmd/go/testdata/script/generate_bad_imports.txt
@@ -1,4 +1,4 @@
-[windows] skip # skip because windows has no echo command
+[GOOS:windows] skip # skip because windows has no echo command
 
 go generate gencycle
 stdout 'hello world' # check go generate gencycle ran the generator
diff --git a/src/cmd/go/testdata/script/generate_env.txt b/src/cmd/go/testdata/script/generate_env.txt
index 2df1663..cb76d30 100644
--- a/src/cmd/go/testdata/script/generate_env.txt
+++ b/src/cmd/go/testdata/script/generate_env.txt
@@ -1,8 +1,8 @@
 # Install an env command because Windows and plan9 don't have it.
 env GOBIN=$WORK/tmp/bin
 go install env.go
-[plan9] env path=$GOBIN${:}$path
-[!plan9] env PATH=$GOBIN${:}$PATH
+[GOOS:plan9] env path=$GOBIN${:}$path
+[!GOOS:plan9] env PATH=$GOBIN${:}$PATH
 
 # Test generators have access to the environment
 go generate ./printenv.go
diff --git a/src/cmd/go/testdata/script/generate_goroot_PATH.txt b/src/cmd/go/testdata/script/generate_goroot_PATH.txt
index 647cea3..24591f0 100644
--- a/src/cmd/go/testdata/script/generate_goroot_PATH.txt
+++ b/src/cmd/go/testdata/script/generate_goroot_PATH.txt
@@ -4,12 +4,12 @@
 
 [short] skip
 
-[!plan9] env PATH=
-[plan9] env path=
+[!GOOS:plan9] env PATH=
+[GOOS:plan9] env path=
 go generate .
 
-[!plan9] env PATH=$WORK${/}bin
-[plan9] env path=$WORK${/}bin
+[!GOOS:plan9] env PATH=$WORK${/}bin
+[GOOS:plan9] env path=$WORK${/}bin
 go generate .
 
 -- go.mod --
diff --git a/src/cmd/go/testdata/script/get_404_meta.txt b/src/cmd/go/testdata/script/get_404_meta.txt
index 29fc542..553afb9 100644
--- a/src/cmd/go/testdata/script/get_404_meta.txt
+++ b/src/cmd/go/testdata/script/get_404_meta.txt
@@ -1,7 +1,7 @@
 # golang.org/issue/13037: 'go get' was not parsing <meta> tags in 404 served over HTTPS.
 
 [!net] skip
-[!exec:git] skip
+[!git] skip
 
 env GONOSUMDB=bazil.org,github.com,golang.org
 env GO111MODULE=off
diff --git a/src/cmd/go/testdata/script/get_brace.txt b/src/cmd/go/testdata/script/get_brace.txt
index 3449a0c..34f66a6 100644
--- a/src/cmd/go/testdata/script/get_brace.txt
+++ b/src/cmd/go/testdata/script/get_brace.txt
@@ -1,6 +1,6 @@
 env GO111MODULE=off
 
-[!exec:git] skip
+[!git] skip
 
 # Set up some empty repositories.
 cd $WORK/_origin/foo
diff --git a/src/cmd/go/testdata/script/get_custom_domain_wildcard.txt b/src/cmd/go/testdata/script/get_custom_domain_wildcard.txt
index cda25e1..32ddd92 100644
--- a/src/cmd/go/testdata/script/get_custom_domain_wildcard.txt
+++ b/src/cmd/go/testdata/script/get_custom_domain_wildcard.txt
@@ -1,5 +1,5 @@
 [!net] skip
-[!exec:git] skip
+[!git] skip
 env GO111MODULE=off
 
 go get -u rsc.io/pdf/...
diff --git a/src/cmd/go/testdata/script/get_dash_t.txt b/src/cmd/go/testdata/script/get_dash_t.txt
index baac916..0a0a608 100644
--- a/src/cmd/go/testdata/script/get_dash_t.txt
+++ b/src/cmd/go/testdata/script/get_dash_t.txt
@@ -1,7 +1,7 @@
 # Tests issue 8181
 
 [!net] skip
-[!exec:git] skip
+[!git] skip
 env GO111MODULE=off
 
 go get -v -t github.com/rsc/go-get-issue-8181/a github.com/rsc/go-get-issue-8181/b
diff --git a/src/cmd/go/testdata/script/get_domain_root.txt b/src/cmd/go/testdata/script/get_domain_root.txt
index 9187848..250fa64 100644
--- a/src/cmd/go/testdata/script/get_domain_root.txt
+++ b/src/cmd/go/testdata/script/get_domain_root.txt
@@ -2,7 +2,7 @@
 # go get foo.io (not foo.io/subdir) was not working consistently.
 
 [!net] skip
-[!exec:git] skip
+[!git] skip
 env GO111MODULE=off
 
 # go-get-issue-9357.appspot.com is running
diff --git a/src/cmd/go/testdata/script/get_dot_slash_download.txt b/src/cmd/go/testdata/script/get_dot_slash_download.txt
index dbaf46c..2af9564 100644
--- a/src/cmd/go/testdata/script/get_dot_slash_download.txt
+++ b/src/cmd/go/testdata/script/get_dot_slash_download.txt
@@ -1,5 +1,5 @@
 [!net] skip
-[!exec:git] skip
+[!git] skip
 env GO111MODULE=off
 
 # Tests Issues #9797 and #19769
diff --git a/src/cmd/go/testdata/script/get_dotfiles.txt b/src/cmd/go/testdata/script/get_dotfiles.txt
index 6757f9d..676a044 100644
--- a/src/cmd/go/testdata/script/get_dotfiles.txt
+++ b/src/cmd/go/testdata/script/get_dotfiles.txt
@@ -1,7 +1,7 @@
 env GO111MODULE=off
 [short] skip
 
-[!exec:git] skip
+[!git] skip
 
 # Set up a benign repository and a repository with a dotfile name.
 cd $WORK/_origin/foo
diff --git a/src/cmd/go/testdata/script/get_goroot.txt b/src/cmd/go/testdata/script/get_goroot.txt
index 929435a..dc1e5ad 100644
--- a/src/cmd/go/testdata/script/get_goroot.txt
+++ b/src/cmd/go/testdata/script/get_goroot.txt
@@ -28,25 +28,25 @@
 mkdir $WORK/home/go
 
 # Fails because GOROOT=$HOME/go so default GOPATH unset.
-[windows] env USERPROFILE=$WORK/home
-[plan9] env home=$WORK/home
-[!windows] [!plan9] env HOME=$WORK/home
+[GOOS:windows] env USERPROFILE=$WORK/home
+[GOOS:plan9] env home=$WORK/home
+[!GOOS:windows] [!GOOS:plan9] env HOME=$WORK/home
 env GOPATH=
 env GOROOT=$WORK/home/go
 ! go get -d github.com/golang/example/hello
 stderr '\$GOPATH not set'
 
-[windows] env USERPROFILE=$WORK/home/
-[plan9] env home=$WORK/home/
-[!windows] [!plan9] env HOME=$WORK/home/
+[GOOS:windows] env USERPROFILE=$WORK/home/
+[GOOS:plan9] env home=$WORK/home/
+[!GOOS:windows] [!GOOS:plan9] env HOME=$WORK/home/
 env GOPATH=
 env GOROOT=$WORK/home/go
 ! go get -d github.com/golang/example/hello
 stderr '\$GOPATH not set'
 
-[windows] env USERPROFILE=$WORK/home
-[plan9] env home=$WORK/home
-[!windows] [!plan9] env HOME=$WORK/home
+[GOOS:windows] env USERPROFILE=$WORK/home
+[GOOS:plan9] env home=$WORK/home
+[!GOOS:windows] [!GOOS:plan9] env HOME=$WORK/home
 env GOPATH=
 env GOROOT=$WORK/home/go/
 ! go get -d github.com/golang/example/hello
diff --git a/src/cmd/go/testdata/script/get_insecure.txt b/src/cmd/go/testdata/script/get_insecure.txt
index 69930f7..0079220 100644
--- a/src/cmd/go/testdata/script/get_insecure.txt
+++ b/src/cmd/go/testdata/script/get_insecure.txt
@@ -1,7 +1,7 @@
 # TODO(matloob): Split this test into two? It's one of the slowest tests we have.
 
 [!net] skip
-[!exec:git] skip
+[!git] skip
 
 env PATH=$WORK/tmp/bin${:}$PATH
 go build -o $WORK/tmp/bin/ssh ssh.go
diff --git a/src/cmd/go/testdata/script/get_insecure_custom_domain.txt b/src/cmd/go/testdata/script/get_insecure_custom_domain.txt
index 7eba42e..3a0765f 100644
--- a/src/cmd/go/testdata/script/get_insecure_custom_domain.txt
+++ b/src/cmd/go/testdata/script/get_insecure_custom_domain.txt
@@ -1,5 +1,5 @@
 [!net] skip
-[!exec:git] skip
+[!git] skip
 env GO111MODULE=off
 
 ! go get -d insecure.go-get-issue-15410.appspot.com/pkg/p
diff --git a/src/cmd/go/testdata/script/get_insecure_env.txt b/src/cmd/go/testdata/script/get_insecure_env.txt
index 8d88427..8748440 100644
--- a/src/cmd/go/testdata/script/get_insecure_env.txt
+++ b/src/cmd/go/testdata/script/get_insecure_env.txt
@@ -1,5 +1,5 @@
 [!net] skip
-[!exec:git] skip
+[!git] skip
 
 # GOPATH: Set up
 env GO111MODULE=off
diff --git a/src/cmd/go/testdata/script/get_insecure_redirect.txt b/src/cmd/go/testdata/script/get_insecure_redirect.txt
index fb5f269..2e5ec4e 100644
--- a/src/cmd/go/testdata/script/get_insecure_redirect.txt
+++ b/src/cmd/go/testdata/script/get_insecure_redirect.txt
@@ -2,7 +2,7 @@
 # golang.org/issue/34049: 'go get' would panic in case of an insecure redirect in GOPATH mode
 
 [!net] skip
-[!exec:git] skip
+[!git] skip
 
 env GO111MODULE=off
 
diff --git a/src/cmd/go/testdata/script/get_insecure_update.txt b/src/cmd/go/testdata/script/get_insecure_update.txt
index e1a1a23..01660d5 100644
--- a/src/cmd/go/testdata/script/get_insecure_update.txt
+++ b/src/cmd/go/testdata/script/get_insecure_update.txt
@@ -1,5 +1,5 @@
 [!net] skip
-[!exec:git] skip
+[!git] skip
 env GO111MODULE=off
 
 # Clone the repo via HTTP manually.
diff --git a/src/cmd/go/testdata/script/get_internal_wildcard.txt b/src/cmd/go/testdata/script/get_internal_wildcard.txt
index ff20d4b..71ecb8c 100644
--- a/src/cmd/go/testdata/script/get_internal_wildcard.txt
+++ b/src/cmd/go/testdata/script/get_internal_wildcard.txt
@@ -1,5 +1,5 @@
 [!net] skip
-[!exec:git] skip
+[!git] skip
 env GO111MODULE=off
 
 # This used to fail with errors about internal packages
diff --git a/src/cmd/go/testdata/script/get_issue11307.txt b/src/cmd/go/testdata/script/get_issue11307.txt
index 9d6b7dd..dc46e74 100644
--- a/src/cmd/go/testdata/script/get_issue11307.txt
+++ b/src/cmd/go/testdata/script/get_issue11307.txt
@@ -1,7 +1,7 @@
 # go get -u was not working except in checkout directory
 
 [!net] skip
-[!exec:git] skip
+[!git] skip
 env GO111MODULE=off
 
 env GOPATH=$WORK/tmp/gopath
diff --git a/src/cmd/go/testdata/script/get_issue16471.txt b/src/cmd/go/testdata/script/get_issue16471.txt
index 2a2225a..6036913 100644
--- a/src/cmd/go/testdata/script/get_issue16471.txt
+++ b/src/cmd/go/testdata/script/get_issue16471.txt
@@ -1,5 +1,5 @@
 [!net] skip
-[!exec:git] skip
+[!git] skip
 
 env GO111MODULE=off
 
diff --git a/src/cmd/go/testdata/script/get_issue22125.txt b/src/cmd/go/testdata/script/get_issue22125.txt
new file mode 100644
index 0000000..3418df8
--- /dev/null
+++ b/src/cmd/go/testdata/script/get_issue22125.txt
@@ -0,0 +1,14 @@
+# This test verifies a fix for a security issue; see https://go.dev/issue/22125.
+
+[!net] skip
+[!git] skip
+[!exec:svn] skip
+
+env GO111MODULE=off
+
+cd $GOPATH
+! go get -u vcs-test.golang.org/go/test1-svn-git
+stderr 'src'${/}'vcs-test.* uses git, but parent .*src'${/}'vcs-test.* uses svn'
+
+[!case-sensitive] ! go get -u vcs-test.golang.org/go/test2-svn-git/test2main
+[!case-sensitive] stderr 'src'${/}'vcs-test.* uses git, but parent .*src'${/}'vcs-test.* uses svn'
diff --git a/src/cmd/go/testdata/script/get_legacy.txt b/src/cmd/go/testdata/script/get_legacy.txt
index 938d428..2909b73 100644
--- a/src/cmd/go/testdata/script/get_legacy.txt
+++ b/src/cmd/go/testdata/script/get_legacy.txt
@@ -4,7 +4,7 @@
 # The test still seems to be useful as a test of direct-mode go get.
 
 [short] skip
-[!exec:git] skip
+[!git] skip
 env GO111MODULE=off
 
 env GOPATH=$WORK/tmp/d1
diff --git a/src/cmd/go/testdata/script/get_non_pkg.txt b/src/cmd/go/testdata/script/get_non_pkg.txt
index a878530..5eac1e3 100644
--- a/src/cmd/go/testdata/script/get_non_pkg.txt
+++ b/src/cmd/go/testdata/script/get_non_pkg.txt
@@ -1,5 +1,5 @@
 [!net] skip
-[!exec:git] skip
+[!git] skip
 
 env GOBIN=$WORK/tmp/gobin
 env GO111MODULE=off
diff --git a/src/cmd/go/testdata/script/get_race.txt b/src/cmd/go/testdata/script/get_race.txt
index 16a560a..87fbf62 100644
--- a/src/cmd/go/testdata/script/get_race.txt
+++ b/src/cmd/go/testdata/script/get_race.txt
@@ -1,7 +1,7 @@
 # Tests issue #20502
 
 [!net] skip
-[!exec:git] skip
+[!git] skip
 [!race] skip
 env GO111MODULE=off
 
diff --git a/src/cmd/go/testdata/script/get_test_only.txt b/src/cmd/go/testdata/script/get_test_only.txt
index a3f38dd..ec8baf9 100644
--- a/src/cmd/go/testdata/script/get_test_only.txt
+++ b/src/cmd/go/testdata/script/get_test_only.txt
@@ -1,5 +1,5 @@
 [!net] skip
-[!exec:git] skip
+[!git] skip
 env GO111MODULE=off
 
 go get golang.org/x/tour/content...
diff --git a/src/cmd/go/testdata/script/get_update.txt b/src/cmd/go/testdata/script/get_update.txt
index 9afce6a..5aeb990 100644
--- a/src/cmd/go/testdata/script/get_update.txt
+++ b/src/cmd/go/testdata/script/get_update.txt
@@ -3,7 +3,7 @@
 # former dependencies, not current ones.
 
 [!net] skip
-[!exec:git] skip
+[!git] skip
 env GO111MODULE=off
 
 # Rewind
diff --git a/src/cmd/go/testdata/script/get_update_unknown_protocol.txt b/src/cmd/go/testdata/script/get_update_unknown_protocol.txt
index b00adea..12807ad 100644
--- a/src/cmd/go/testdata/script/get_update_unknown_protocol.txt
+++ b/src/cmd/go/testdata/script/get_update_unknown_protocol.txt
@@ -1,5 +1,5 @@
 [!net] skip
-[!exec:git] skip
+[!git] skip
 env GO111MODULE=off
 
 # Clone the repo via HTTPS manually.
diff --git a/src/cmd/go/testdata/script/get_update_wildcard.txt b/src/cmd/go/testdata/script/get_update_wildcard.txt
index 4e66004..01e2c37 100644
--- a/src/cmd/go/testdata/script/get_update_wildcard.txt
+++ b/src/cmd/go/testdata/script/get_update_wildcard.txt
@@ -1,7 +1,7 @@
 # Issue 14450: go get -u .../ tried to import not downloaded package
 
 [!net] skip
-[!exec:git] skip
+[!git] skip
 env GO111MODULE=off
 
 go get github.com/tmwh/go-get-issue-14450/a
diff --git a/src/cmd/go/testdata/script/get_vendor.txt b/src/cmd/go/testdata/script/get_vendor.txt
index 4ebb8a2..f9a4a6b 100644
--- a/src/cmd/go/testdata/script/get_vendor.txt
+++ b/src/cmd/go/testdata/script/get_vendor.txt
@@ -12,7 +12,7 @@
 go get -t -d
 
 [!net] stop
-[!exec:git] stop
+[!git] stop
 
 cd $GOPATH/src
 
diff --git a/src/cmd/go/testdata/script/get_with_git_trace.txt b/src/cmd/go/testdata/script/get_with_git_trace.txt
index 98854c7..abc7014 100644
--- a/src/cmd/go/testdata/script/get_with_git_trace.txt
+++ b/src/cmd/go/testdata/script/get_with_git_trace.txt
@@ -3,7 +3,7 @@
 env GIT_TRACE=1
 
 [!net] skip
-[!exec:git] skip
+[!git] skip
 
 # go get should be success when GIT_TRACE set
 go get golang.org/x/text
diff --git a/src/cmd/go/testdata/script/goflags.txt b/src/cmd/go/testdata/script/goflags.txt
index f4872ff..1120860 100644
--- a/src/cmd/go/testdata/script/goflags.txt
+++ b/src/cmd/go/testdata/script/goflags.txt
@@ -55,5 +55,10 @@
 go test -tags=magic -c -o $devnull
 go vet -tags=magic
 
+# GOFLAGS uses the same quoting rules (quoted.Split) as the rest of
+# the go command env variables
+env GOFLAGS='"-tags=magic wizardry"'
+go list
+
 -- foo_test.go --
 package foo
diff --git a/src/cmd/go/testdata/script/gopath_local.txt b/src/cmd/go/testdata/script/gopath_local.txt
index 54beaca..efde0e7 100644
--- a/src/cmd/go/testdata/script/gopath_local.txt
+++ b/src/cmd/go/testdata/script/gopath_local.txt
@@ -24,7 +24,7 @@
 ! go install testdata/local/easy.go
 stderr '^go: no install location for \.go files listed on command line \(GOBIN not set\)$'
 
-[windows] stop  # Windows does not allow the ridiculous directory name we're about to use.
+[GOOS:windows] stop  # Windows does not allow the ridiculous directory name we're about to use.
 
 env BAD_DIR_NAME='#$%:, &()*;<=>?\^{}'
 
diff --git a/src/cmd/go/testdata/script/gopath_moved_repo.txt b/src/cmd/go/testdata/script/gopath_moved_repo.txt
index 99d80bf..5815d73 100644
--- a/src/cmd/go/testdata/script/gopath_moved_repo.txt
+++ b/src/cmd/go/testdata/script/gopath_moved_repo.txt
@@ -18,14 +18,14 @@
 
 # Test that 'go get -u' reports moved git packages.
 
-[exec:git] go get -d rsc.io/pdf
-[exec:git] go get -d -u rsc.io/pdf
-[exec:git] exec ./replace.exe pdf rsc.io/pdf/.git/config
+[git] go get -d rsc.io/pdf
+[git] go get -d -u rsc.io/pdf
+[git] exec ./replace.exe pdf rsc.io/pdf/.git/config
 
-[exec:git] ! go get -d -u rsc.io/pdf
-[exec:git] stderr 'is a custom import path for'
-[exec:git] ! go get -d -f -u rsc.io/pdf
-[exec:git] stderr 'validating server certificate|[nN]ot [fF]ound'
+[git] ! go get -d -u rsc.io/pdf
+[git] stderr 'is a custom import path for'
+[git] ! go get -d -f -u rsc.io/pdf
+[git] stderr 'validating server certificate|[nN]ot [fF]ound'
 
 
 # Test that 'go get -u' reports moved Mercurial packages.
diff --git a/src/cmd/go/testdata/script/gopath_std_vendor.txt b/src/cmd/go/testdata/script/gopath_std_vendor.txt
index a0a41a5..4aaf46b 100644
--- a/src/cmd/go/testdata/script/gopath_std_vendor.txt
+++ b/src/cmd/go/testdata/script/gopath_std_vendor.txt
@@ -1,6 +1,6 @@
 env GO111MODULE=off
 
-[!gc] skip
+[!compiler:gc] skip
 
 go list -f '{{.Dir}}' vendor/golang.org/x/net/http2/hpack
 stdout $GOPATH[/\\]src[/\\]vendor
diff --git a/src/cmd/go/testdata/script/goroot_executable.txt b/src/cmd/go/testdata/script/goroot_executable.txt
index fdbcde0..1a0e23e 100644
--- a/src/cmd/go/testdata/script/goroot_executable.txt
+++ b/src/cmd/go/testdata/script/goroot_executable.txt
@@ -1,4 +1,4 @@
-[gccgo] skip
+[compiler:gccgo] skip
 
 mkdir $WORK/new/bin
 
diff --git a/src/cmd/go/testdata/script/govcs.txt b/src/cmd/go/testdata/script/govcs.txt
index 46f1bd0..419a6c5 100644
--- a/src/cmd/go/testdata/script/govcs.txt
+++ b/src/cmd/go/testdata/script/govcs.txt
@@ -67,7 +67,7 @@
 # git is OK by default
 env GOVCS=
 env GONOSUMDB='*'
-[net] [exec:git] [!short] go get rsc.io/sampler
+[net] [git] [!short] go get rsc.io/sampler
 
 # hg is OK by default
 env GOVCS=
@@ -150,7 +150,7 @@
 # git is OK by default
 env GOVCS=
 env GONOSUMDB='*'
-[net] [exec:git] [!short] go get rsc.io/sampler
+[net] [git] [!short] go get rsc.io/sampler
 
 # hg is OK by default
 env GOVCS=
diff --git a/src/cmd/go/testdata/script/import_unix_tag.txt b/src/cmd/go/testdata/script/import_unix_tag.txt
new file mode 100644
index 0000000..b88ca1e
--- /dev/null
+++ b/src/cmd/go/testdata/script/import_unix_tag.txt
@@ -0,0 +1,32 @@
+# Regression test for https://go.dev/issue/54712: the "unix" build constraint
+# was not applied consistently during package loading.
+
+go list -x -f '{{if .Module}}{{.ImportPath}}{{end}}' -deps .
+stdout 'example.com/version'
+
+-- go.mod --
+module example
+
+go 1.19
+
+require example.com/version v1.1.0
+-- go.sum --
+example.com/version v1.1.0 h1:VdPnGmIF1NJrntStkxGrF3L/OfhaL567VzCjncGUgtM=
+example.com/version v1.1.0/go.mod h1:S7K9BnT4o5wT4PCczXPfWVzpjD4ud4e7AJMQJEgiu2Q=
+-- main_notunix.go --
+//go:build !(aix || darwin || dragonfly || freebsd || hurd || linux || netbsd || openbsd || solaris)
+
+package main
+
+import _ "example.com/version"
+
+func main() {}
+
+-- main_unix.go --
+//go:build unix
+
+package main
+
+import _ "example.com/version"
+
+func main() {}
diff --git a/src/cmd/go/testdata/script/install_cmd_gobin.txt b/src/cmd/go/testdata/script/install_cmd_gobin.txt
index 38fd66c..049bf41 100644
--- a/src/cmd/go/testdata/script/install_cmd_gobin.txt
+++ b/src/cmd/go/testdata/script/install_cmd_gobin.txt
@@ -3,8 +3,8 @@
 env GOBIN=gobin
 mkdir gobin
 go list -f '{{.Target}}' cmd/go
-stdout $GOROOT[/\\]bin[/\\]go$GOEXE
+stdout $GOROOT${/}bin${/}go$GOEXE
 
 # Check that tools are installed to $GOTOOLDIR, not $GOBIN.
 go list -f '{{.Target}}' cmd/compile
-stdout $GOROOT[/\\]pkg[/\\]tool[/\\]${GOOS}_${GOARCH}[/\\]compile$GOEXE
+stdout $GOROOT${/}pkg${/}tool${/}${GOOS}_${GOARCH}${/}compile$GOEXE
diff --git a/src/cmd/go/testdata/script/install_cross_gobin.txt b/src/cmd/go/testdata/script/install_cross_gobin.txt
index 33d48fc..7679a7e 100644
--- a/src/cmd/go/testdata/script/install_cross_gobin.txt
+++ b/src/cmd/go/testdata/script/install_cross_gobin.txt
@@ -6,7 +6,7 @@
 
 # cross-compile install with implicit GOBIN=$GOPATH/bin can make subdirectory
 env GOARCH=386
-[386] env GOARCH=amd64
+[GOARCH:386] env GOARCH=amd64
 env GOOS=linux
 go install mycmd
 exists $GOPATH/bin/linux_$GOARCH/mycmd
diff --git a/src/cmd/go/testdata/script/install_dep_version.txt b/src/cmd/go/testdata/script/install_dep_version.txt
new file mode 100644
index 0000000..22b52e5
--- /dev/null
+++ b/src/cmd/go/testdata/script/install_dep_version.txt
@@ -0,0 +1,6 @@
+# Regression test for Issue #54908. When running a go install module@version
+# with --mod=readonly moduleInfo was not setting the GoVersion for the module
+# because the checksumOk function was failing because modfetch.GoSumFile
+# was not set when running outside of a module.
+
+go install --mod=readonly example.com/depends/on/[email protected]
\ No newline at end of file
diff --git a/src/cmd/go/testdata/script/install_goroot_targets.txt b/src/cmd/go/testdata/script/install_goroot_targets.txt
new file mode 100644
index 0000000..f26ee82
--- /dev/null
+++ b/src/cmd/go/testdata/script/install_goroot_targets.txt
@@ -0,0 +1,27 @@
+[short] skip
+
+# Packages in std do not have an install target.
+go list -f '{{.Target}}' fmt
+! stdout .
+go list -export -f '{{.Export}}' fmt
+stdout $GOCACHE
+
+# With GODEBUG=installgoroot=all, fmt has a target.
+# (Though we can't try installing it without modifying goroot).
+env GODEBUG=installgoroot=all
+go list -f '{{.Target}}' fmt
+stdout fmt\.a
+
+# However, the fake packages "builtin" and "unsafe" do not.
+go list -f '{{.Target}}' builtin unsafe
+! stdout .
+go install builtin unsafe  # Should succeed as no-ops.
+
+# With CGO_ENABLED=0, packages that would have
+# an install target with cgo on no longer do.
+env GODEBUG=
+env CGO_ENABLED=0
+go list -f '{{.Target}}' runtime/cgo
+! stdout .
+go list -export -f '{{.Export}}' runtime/cgo
+stdout $GOCACHE
diff --git a/src/cmd/go/testdata/script/install_move_not_stale.txt b/src/cmd/go/testdata/script/install_move_not_stale.txt
new file mode 100644
index 0000000..de191cf
--- /dev/null
+++ b/src/cmd/go/testdata/script/install_move_not_stale.txt
@@ -0,0 +1,26 @@
+# Check to see that the distribution is not stale
+# even when it's been moved to a different directory.
+# Simulate that by creating a symlink to the tree.
+
+# We use net instead of std because stale std has
+# the behavior of checking that all std targets
+# are stale rather than any of them.
+
+[!symlink] skip
+[short] skip
+
+go build net
+! stale net
+
+symlink new -> $GOROOT
+env OLDGOROOT=$GOROOT
+env GOROOT=$WORK${/}gopath${/}src${/}new
+go env GOROOT
+stdout $WORK[\\/]gopath[\\/]src[\\/]new
+cd new
+! stale net
+
+# Add a control case to check that std is
+# stale with an empty cache
+env GOCACHE=$WORK${/}gopath${/}cache
+stale net
diff --git a/src/cmd/go/testdata/script/install_msan_and_race_and_asan_require_cgo.txt b/src/cmd/go/testdata/script/install_msan_and_race_and_asan_require_cgo.txt
index d496eaa..d8f2aba 100644
--- a/src/cmd/go/testdata/script/install_msan_and_race_and_asan_require_cgo.txt
+++ b/src/cmd/go/testdata/script/install_msan_and_race_and_asan_require_cgo.txt
@@ -2,19 +2,21 @@
 
 env CGO_ENABLED=0
 
-[race] ! go install -race triv.go
-[race] stderr '-race requires cgo'
-[race] ! stderr '-msan'
+[GOOS:darwin] [!short] [race] go build -race triv.go
+
+[!GOOS:darwin] [race] ! go install -race triv.go
+[!GOOS:darwin] [race] stderr '-race requires cgo'
+[!GOOS:darwin] [race] ! stderr '-msan'
 
 [msan] ! go install -msan triv.go
 [msan] stderr '-msan requires cgo'
 [msan] ! stderr '-race'
 
 [asan] ! go install -asan triv.go
-[asan] stderr '(-asan: the version of $(go env CC) could not be parsed)|(-asan: C compiler is not gcc or clang)|(-asan is not supported with C compiler (\d+)\.(\d+))|(-asan requires cgo)'
+[asan] stderr '(-asan: the version of $(go env CC) could not be parsed)|(-asan: C compiler is not gcc or clang)|(-asan is not supported with [A-Za-z]+ compiler (\d+)\.(\d+))|(-asan requires cgo)'
 [asan] ! stderr '-msan'
 
 -- triv.go --
 package main
 
-func main() {}
\ No newline at end of file
+func main() {}
diff --git a/src/cmd/go/testdata/script/install_rebuild_gopath.txt b/src/cmd/go/testdata/script/install_rebuild_gopath.txt
deleted file mode 100644
index 14a6c86..0000000
--- a/src/cmd/go/testdata/script/install_rebuild_gopath.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-env GO111MODULE=off
-
-# GOPATH with p1 in d1, p2 in d2
-env GOPATH=$WORK/d1${:}$WORK/d2
-
-# build & install p1
-go install -i p1
-! stale p1 p2
-
-# modify p2 - p1 should appear stale
-cp $WORK/p2x.go $WORK/d2/src/p2/p2.go
-stale p1 p2
-
-# build & install p1 again
-go install -i p1
-! stale p1 p2
-
--- $WORK/d1/src/p1/p1.go --
-package p1
-import "p2"
-func F() { p2.F() }
-
--- $WORK/d2/src/p2/p2.go --
-package p2
-func F() {}
-
--- $WORK/p2x.go --
-package p2
-func F() {}
-func G() {}
diff --git a/src/cmd/go/testdata/script/link_syso_deps.txt b/src/cmd/go/testdata/script/link_syso_deps.txt
index 7b458b0..6bb9005 100644
--- a/src/cmd/go/testdata/script/link_syso_deps.txt
+++ b/src/cmd/go/testdata/script/link_syso_deps.txt
@@ -1,11 +1,12 @@
 # Test that syso in deps is available to cgo.
 
-[!gc] skip
+[!compiler:gc] skip 'requires syso support'
 [!cgo] skip
+[short] skip 'invokes system C compiler'
 
 # External linking is not supported on linux/ppc64.
 # See: https://github.com/golang/go/issues/8912
-[linux] [ppc64] skip
+[GOOS:linux] [GOARCH:ppc64] skip
 
 cc -c -o syso/x.syso syso/x.c
 cc -c -o syso2/x.syso syso2/x.c
diff --git a/src/cmd/go/testdata/script/link_syso_issue33139.txt b/src/cmd/go/testdata/script/link_syso_issue33139.txt
index 8a8cb4a..b0d4a7c 100644
--- a/src/cmd/go/testdata/script/link_syso_issue33139.txt
+++ b/src/cmd/go/testdata/script/link_syso_issue33139.txt
@@ -1,12 +1,14 @@
 # Test that we can use the external linker with a host syso file that is
 # embedded in a package, that is referenced by a Go assembly function.
 # See issue 33139.
-[!gc] skip
+
+[!compiler:gc] skip
 [!cgo] skip
+[short] skip 'invokes system C compiler'
 
 # External linking is not supported on linux/ppc64.
 # See: https://github.com/golang/go/issues/8912
-[linux] [ppc64] skip
+[GOOS:linux] [GOARCH:ppc64] skip
 
 cc -c -o syso/objTestImpl.syso syso/src/objTestImpl.c
 go build -ldflags='-linkmode=external' ./cmd/main.go
diff --git a/src/cmd/go/testdata/script/linkname.txt b/src/cmd/go/testdata/script/linkname.txt
index 1133659..36ac8eb 100644
--- a/src/cmd/go/testdata/script/linkname.txt
+++ b/src/cmd/go/testdata/script/linkname.txt
@@ -1,7 +1,7 @@
 env GO111MODULE=off
 
 # check for linker name in error message about linker crash
-[!gc] skip
+[!compiler:gc] skip
 ! go build -ldflags=-crash_for_testing x.go
 stderr [\\/]tool[\\/].*[\\/]link
 
diff --git a/src/cmd/go/testdata/script/list_ambiguous_path.txt b/src/cmd/go/testdata/script/list_ambiguous_path.txt
index 82dde45..6f22314 100644
--- a/src/cmd/go/testdata/script/list_ambiguous_path.txt
+++ b/src/cmd/go/testdata/script/list_ambiguous_path.txt
@@ -22,9 +22,9 @@
 # Multiple patterns for Go files with a typo. This should
 # treat the wrong pattern as if it were a nonexistent file.
 ! go list ./foo.go/a.go ./foo.go/b.go
-[plan9] stderr 'stat ./foo.go/b.go: ''./foo.go/b.go'' does not exist'
-[windows] stderr './foo.go/b.go: The system cannot find the file specified'
-[!plan9] [!windows] stderr './foo.go/b.go: no such file or directory'
+[GOOS:plan9] stderr 'stat ./foo.go/b.go: ''./foo.go/b.go'' does not exist'
+[GOOS:windows] stderr './foo.go/b.go: The system cannot find the file specified'
+[!GOOS:plan9] [!GOOS:windows] stderr './foo.go/b.go: no such file or directory'
 
 -- a.go --
 package main
diff --git a/src/cmd/go/testdata/script/list_compiled_files_issue28749.txt b/src/cmd/go/testdata/script/list_compiled_files_issue28749.txt
new file mode 100644
index 0000000..e0fb977
--- /dev/null
+++ b/src/cmd/go/testdata/script/list_compiled_files_issue28749.txt
@@ -0,0 +1,10 @@
+go list -compiled -f {{.CompiledGoFiles}} .
+! stdout 'foo.s'
+
+-- go.mod --
+module example.com/foo
+
+go 1.20
+-- foo.go --
+package foo
+-- foo.s --
diff --git a/src/cmd/go/testdata/script/list_compiler_output.txt b/src/cmd/go/testdata/script/list_compiler_output.txt
new file mode 100644
index 0000000..5230bab
--- /dev/null
+++ b/src/cmd/go/testdata/script/list_compiler_output.txt
@@ -0,0 +1,16 @@
+[short] skip
+
+go install -gcflags=-m .
+stderr 'can inline main'
+go list -gcflags=-m -f '{{.Stale}}' .
+stdout 'false'
+! stderr 'can inline main'
+
+-- go.mod --
+module example.com/foo
+
+go 1.20
+-- main.go --
+package main
+
+func main() {}
diff --git a/src/cmd/go/testdata/script/list_export_e.txt b/src/cmd/go/testdata/script/list_export_e.txt
new file mode 100644
index 0000000..8e4c361
--- /dev/null
+++ b/src/cmd/go/testdata/script/list_export_e.txt
@@ -0,0 +1,26 @@
+! go list -export ./...
+stderr '^# example.com/p2\np2'${/}'main\.go:7:.*'
+! stderr '^go build '
+
+go list -f '{{with .Error}}{{.}}{{end}}' -e -export ./...
+! stderr '.'
+stdout '^# example.com/p2\np2'${/}'main\.go:7:.*'
+
+go list -e -export -json=Error ./...
+stdout '"Err": "# example.com/p2'
+
+-- go.mod --
+module example.com
+-- p1/p1.go --
+package p1
+
+const Name = "p1"
+-- p2/main.go --
+package main
+
+import "fmt"
+import "example.com/p1"
+
+func main() {
+	fmt.Println(p1.Name == 5)
+}
diff --git a/src/cmd/go/testdata/script/list_gofile_in_goroot.txt b/src/cmd/go/testdata/script/list_gofile_in_goroot.txt
index 6e48d7b..b4ff3cb 100644
--- a/src/cmd/go/testdata/script/list_gofile_in_goroot.txt
+++ b/src/cmd/go/testdata/script/list_gofile_in_goroot.txt
@@ -36,8 +36,8 @@
 go list ./...
 stdout -count=2 '^.+$' # Both 'fmt' and GOROOT/src should be listed.
 stdout '^fmt$'
-[!windows] stdout ^_$WORK/goroot/src$
-[windows] stdout goroot/src$ # On windows the ":" in the volume name is mangled
+[!GOOS:windows] stdout ^_$WORK/goroot/src$
+[GOOS:windows] stdout goroot/src$ # On windows the ":" in the volume name is mangled
 
 go list ...
 ! stdout goroot/src
@@ -46,8 +46,8 @@
 ! stdout goroot/src
 
 go list .
-[!windows] stdout ^_$WORK/goroot/src$
-[windows] stdout goroot/src$
+[!GOOS:windows] stdout ^_$WORK/goroot/src$
+[GOOS:windows] stdout goroot/src$
 
 # switch to GOPATH/src
 cd $GOPATH/src
@@ -55,8 +55,8 @@
 # GO111MODULE=off,GOPATH
 env GO111MODULE=off
 go list ./...
-[!windows] stdout ^_$WORK/gopath/src$
-[windows] stdout gopath/src$
+[!GOOS:windows] stdout ^_$WORK/gopath/src$
+[GOOS:windows] stdout gopath/src$
 
 go list all
 ! stdout gopath/src
diff --git a/src/cmd/go/testdata/script/list_goroot_symlink.txt b/src/cmd/go/testdata/script/list_goroot_symlink.txt
new file mode 100644
index 0000000..8e50e4b
--- /dev/null
+++ b/src/cmd/go/testdata/script/list_goroot_symlink.txt
@@ -0,0 +1,63 @@
+# Regression test for https://go.dev/issue/57754: 'go list' failed if ../src
+# relative to the location of the go executable was a symlink to the real src
+# directory. (cmd/go expects that ../src is GOROOT/src, but it appears that the
+# Debian build of the Go toolchain is attempting to split GOROOT into binary and
+# source artifacts in different parent directories.)
+
+[short] skip 'copies the cmd/go binary'
+[!symlink] skip 'tests symlink-specific behavior'
+
+# Ensure that the relative path to $WORK/lib/goroot/src from $PWD is a different
+# number of ".." hops than the relative path to it from $WORK/share/goroot/src.
+
+cd $WORK
+
+# Construct a fake GOROOT in $WORK/lib/goroot whose src directory is a symlink
+# to a subdirectory of $WORK/share. This mimics the directory structure reported
+# in https://go.dev/issue/57754.
+#
+# Symlink everything else to the original $GOROOT to avoid needless copying work.
+
+mkdir $WORK/lib/goroot
+mkdir $WORK/share/goroot
+symlink $WORK/share/goroot/src -> $GOROOT${/}src
+symlink $WORK/lib/goroot/src -> ../../share/goroot/src
+symlink $WORK/lib/goroot/pkg -> $GOROOT${/}pkg
+
+# Verify that our symlink shenanigans don't prevent cmd/go from finding its
+# GOROOT using os.Executable.
+#
+# To do so, we copy the actual cmd/go executable — which is implemented as the
+# cmd/go test binary instead of the original $GOROOT/bin/go, which may be
+# arbitrarily stale — into the bin subdirectory of the fake GOROOT, causing
+# os.Executable to report a path in that directory.
+
+mkdir $WORK/lib/goroot/bin
+cp $TESTGO_EXE $WORK/lib/goroot/bin/go$GOEXE
+
+env GOROOT=''  # Clear to force cmd/go to find GOROOT itself.
+exec $WORK/lib/goroot/bin/go env GOROOT
+stdout $WORK${/}lib${/}goroot
+
+# Now verify that 'go list' can find standard-library packages in the symlinked
+# source tree, with paths matching the one reported by 'go env GOROOT'.
+
+exec $WORK/lib/goroot/bin/go list -f '{{.ImportPath}}: {{.Dir}}' encoding/binary
+stdout '^encoding/binary: '$WORK${/}lib${/}goroot${/}src${/}encoding${/}binary'$'
+
+	# BUG(#50807): This doesn't work on Windows for some reason — perhaps
+	# a bug in the Windows Lstat implementation with trailing separators?
+[!GOOS:windows] exec $WORK/lib/goroot/bin/go list -f '{{.ImportPath}}: {{.Dir}}' std
+[!GOOS:windows] stdout '^encoding/binary: '$WORK${/}lib${/}goroot${/}src${/}encoding${/}binary'$'
+
+# Most path lookups in GOROOT are not sensitive to symlinks. However, patterns
+# involving '...' wildcards must use Walk to check the GOROOT tree, which makes
+# them more sensitive to symlinks (because Walk doesn't follow them).
+#
+# So we check such a pattern to confirm that it works and reports a path relative
+# to $GOROOT/src (and not the symlink target).
+
+	# BUG(#50807): This should report encoding/binary, not "matched no packages".
+exec $WORK/lib/goroot/bin/go list -f '{{.ImportPath}}: {{.Dir}}' .../binary
+! stdout .
+stderr '^go: warning: "\.\.\./binary" matched no packages$'
diff --git a/src/cmd/go/testdata/script/list_importmap.txt b/src/cmd/go/testdata/script/list_importmap.txt
index f424b98..3c59cfd 100644
--- a/src/cmd/go/testdata/script/list_importmap.txt
+++ b/src/cmd/go/testdata/script/list_importmap.txt
@@ -1,7 +1,7 @@
 env GO111MODULE=off
 
 # gccgo does not have standard packages.
-[gccgo] skip
+[compiler:gccgo] skip
 
 # fmt should have no rewritten imports.
 # The import from a/b should map c/d to a's vendor directory.
diff --git a/src/cmd/go/testdata/script/list_issue_56509.txt b/src/cmd/go/testdata/script/list_issue_56509.txt
new file mode 100644
index 0000000..b402b2b
--- /dev/null
+++ b/src/cmd/go/testdata/script/list_issue_56509.txt
@@ -0,0 +1,35 @@
+# Test that a directory with an .s file that has a comment that can't
+# be parsed isn't matched as a go directory. (This was happening because
+# non-go files with unparsable comments were being added to InvalidGoFiles
+# leading the package matching code to think there were Go files in the
+# directory.)
+
+cd bar
+go list ./...
+! stdout .
+cd ..
+
+[short] skip
+
+# Test that an unparsable .s file is completely ignored when its name
+# has build tags that cause it to be filtered out, but produces an error
+# when it is included
+
+env GOARCH=arm64
+env GOOS=linux
+go build ./baz
+
+env GOARCH=amd64
+env GOOS=linux
+! go build ./baz
+
+-- go.mod --
+module example.com/foo
+
+go 1.20
+-- bar/bar.s --
+;/
+-- baz/baz.go --
+package bar
+-- baz/baz_amd64.s --
+;/
diff --git a/src/cmd/go/testdata/script/list_json_fields.txt b/src/cmd/go/testdata/script/list_json_fields.txt
index 5ddbb73..54d2220 100644
--- a/src/cmd/go/testdata/script/list_json_fields.txt
+++ b/src/cmd/go/testdata/script/list_json_fields.txt
@@ -26,7 +26,7 @@
 stdout '"Deps": \['
 stdout '"errors",'
 
-[!exec:git] skip
+[!git] skip
 
 # Test -json=<field> without Stale skips computing buildinfo
 cd repo
diff --git a/src/cmd/go/testdata/script/list_legacy_mod.txt b/src/cmd/go/testdata/script/list_legacy_mod.txt
new file mode 100644
index 0000000..ab901d7
--- /dev/null
+++ b/src/cmd/go/testdata/script/list_legacy_mod.txt
@@ -0,0 +1,48 @@
+# In GOPATH mode, module legacy support does path rewriting very similar to vendoring.
+
+env GO111MODULE=off
+
+go list -f '{{range .Imports}}{{.}}{{"\n"}}{{end}}' old/p1
+stdout ^new/p1$
+
+go list -f '{{range .Imports}}{{.}}{{"\n"}}{{end}}' new/p1
+stdout ^new/p2$           # not new/v2/p2
+! stdout ^new/v2
+stdout ^new/sub/x/v1/y$   # not new/sub/v2/x/v1/y
+! stdout ^new/sub/v2
+stdout ^new/sub/inner/x # not new/sub/v2/inner/x
+
+go build old/p1 new/p1
+
+-- new/go.mod --
+module "new/v2"
+-- new/new.go --
+package new
+
+import _ "new/v2/p2"
+-- new/p1/p1.go --
+package p1
+
+import _ "old/p2"
+import _ "new/v2"
+import _ "new/v2/p2"
+import _ "new/sub/v2/x/v1/y" // v2 is module, v1 is directory in module
+import _ "new/sub/inner/x"   // new/sub/inner/go.mod overrides new/sub/go.mod
+-- new/p2/p2.go --
+package p2
+-- new/sub/go.mod --
+module new/sub/v2
+-- new/sub/inner/go.mod --
+module new/sub/inner
+-- new/sub/inner/x/x.go --
+package x
+-- new/sub/x/v1/y/y.go --
+package y
+-- old/p1/p1.go --
+package p1
+
+import _ "old/p2"
+import _ "new/p1"
+import _ "new"
+-- old/p2/p2.go --
+package p2
diff --git a/src/cmd/go/testdata/script/list_perm.txt b/src/cmd/go/testdata/script/list_perm.txt
index 3b850ef..14d6f72 100644
--- a/src/cmd/go/testdata/script/list_perm.txt
+++ b/src/cmd/go/testdata/script/list_perm.txt
@@ -16,8 +16,8 @@
 # equivalent to an empty directory).
 
 [root] stop # Root typically ignores file permissions.
-[windows] skip # Does not have Unix-style directory permissions.
-[plan9] skip   # Might not have Unix-style directory permissions.
+[GOOS:windows] skip # Does not have Unix-style directory permissions.
+[GOOS:plan9] skip   # Might not have Unix-style directory permissions.
 
 chmod 000 noread
 
diff --git a/src/cmd/go/testdata/script/list_pkgconfig_error.txt b/src/cmd/go/testdata/script/list_pkgconfig_error.txt
new file mode 100644
index 0000000..7d671a6
--- /dev/null
+++ b/src/cmd/go/testdata/script/list_pkgconfig_error.txt
@@ -0,0 +1,16 @@
+[!cgo] skip 'test verifies cgo pkg-config errors'
+[!exec:pkg-config] skip 'test requires pkg-config tool'
+
+! go list -export .
+stderr '^go build example:\n# pkg-config (.*\n)+pkg-config: exit status \d+$'
+
+-- go.mod --
+module example
+go 1.20
+-- example.go --
+package example
+
+// #cgo pkg-config: libnot-a-valid-cgo-library
+import "C"
+
+package main() {}
diff --git a/src/cmd/go/testdata/script/list_replace_absolute_windows.txt b/src/cmd/go/testdata/script/list_replace_absolute_windows.txt
index b3ff2a7..8b71921 100644
--- a/src/cmd/go/testdata/script/list_replace_absolute_windows.txt
+++ b/src/cmd/go/testdata/script/list_replace_absolute_windows.txt
@@ -3,7 +3,7 @@
 # whether the modindex logic cleans the modroot path before using
 # it.
 
-[!windows] skip
+[!GOOS:windows] skip
 [short] skip
 
 go run print_go_mod.go # use this program to write a go.mod with an absolute path
diff --git a/src/cmd/go/testdata/script/list_std.txt b/src/cmd/go/testdata/script/list_std.txt
index 6ab1bd1..64c4766 100644
--- a/src/cmd/go/testdata/script/list_std.txt
+++ b/src/cmd/go/testdata/script/list_std.txt
@@ -1,6 +1,6 @@
 env GO111MODULE=off
 
-[!gc] skip
+[!compiler:gc] skip
 [short] skip
 
 # Listing GOROOT should only find standard packages.
diff --git a/src/cmd/go/testdata/script/list_swigcxx.txt b/src/cmd/go/testdata/script/list_swigcxx.txt
index 4220487..731c1e5 100644
--- a/src/cmd/go/testdata/script/list_swigcxx.txt
+++ b/src/cmd/go/testdata/script/list_swigcxx.txt
@@ -16,8 +16,8 @@
 go list -f '{{.CompiledGoFiles}}' -compiled=true example/swig
 
 stdout a\.go
-[gc] stdout -count=3 $GOCACHE
-[gccgo] stdout -count=2 $GOCACHE
+[compiler:gc] stdout -count=3 $GOCACHE
+[compiler:gccgo] stdout -count=2 $GOCACHE
 
 -- go.mod --
 module example
diff --git a/src/cmd/go/testdata/script/mod_cache_rw.txt b/src/cmd/go/testdata/script/mod_cache_rw.txt
index 0775541..87f27e8 100644
--- a/src/cmd/go/testdata/script/mod_cache_rw.txt
+++ b/src/cmd/go/testdata/script/mod_cache_rw.txt
@@ -17,10 +17,10 @@
 
 # If all 'go' commands ran with the flag, the system's 'rm' binary
 # should be able to remove the module cache if the '-rf' flags are set.
-[!windows] [exec:rm] exec rm -rf $GOPATH/pkg/mod
-[!windows] [!exec:rm] go clean -modcache
-[windows] [exec:cmd.exe] exec cmd.exe /c rmdir /s /q $GOPATH\pkg\mod
-[windows] [!exec:cmd.exe] go clean -modcache
+[!GOOS:windows] [exec:rm] exec rm -rf $GOPATH/pkg/mod
+[!GOOS:windows] [!exec:rm] go clean -modcache
+[GOOS:windows] [exec:cmd.exe] exec cmd.exe /c rmdir /s /q $GOPATH\pkg\mod
+[GOOS:windows] [!exec:cmd.exe] go clean -modcache
 ! exists $GOPATH/pkg/mod
 
 # The directories in the module cache should by default be unwritable,
@@ -30,7 +30,7 @@
 # unwritable.
 go get rsc.io/quote@latest
 [!root] ! cp $WORK/extraneous.txt $GOPATH/pkg/mod/rsc.io/[email protected]/go.mod
-[!windows] [!root] ! cp $WORK/extraneous.txt $GOPATH/pkg/mod/rsc.io/[email protected]/extraneous_file.go
+[!GOOS:windows] [!root] ! cp $WORK/extraneous.txt $GOPATH/pkg/mod/rsc.io/[email protected]/extraneous_file.go
 ! exists $GOPATH/pkg/mod/rsc.io/[email protected]/extraneous_file.go
 
 
diff --git a/src/cmd/go/testdata/script/mod_clean_cache.txt b/src/cmd/go/testdata/script/mod_clean_cache.txt
index 01fbc38..2b8e820 100644
--- a/src/cmd/go/testdata/script/mod_clean_cache.txt
+++ b/src/cmd/go/testdata/script/mod_clean_cache.txt
@@ -35,6 +35,9 @@
 ! stderr 'finding rsc.io'
 go mod edit -droprequire rsc.io/quote
 
+! go clean -modcache m
+stderr 'go: clean -modcache cannot be used with package arguments'
+
 -- go.mod --
 module m
 -- m.go --
diff --git a/src/cmd/go/testdata/script/mod_convert.txt b/src/cmd/go/testdata/script/mod_convert.txt
index f60fe87..1c9d626 100644
--- a/src/cmd/go/testdata/script/mod_convert.txt
+++ b/src/cmd/go/testdata/script/mod_convert.txt
@@ -1,6 +1,6 @@
 [short] skip
 [!net] skip
-[!exec:git] skip
+[!git] skip
 
 env GO111MODULE=on
 env GOPROXY=
diff --git a/src/cmd/go/testdata/script/mod_convert_tsv_insecure.txt b/src/cmd/go/testdata/script/mod_convert_tsv_insecure.txt
index 283e2d9..9910ce7 100644
--- a/src/cmd/go/testdata/script/mod_convert_tsv_insecure.txt
+++ b/src/cmd/go/testdata/script/mod_convert_tsv_insecure.txt
@@ -3,7 +3,7 @@
 env GOSUMDB=off
 
 [!net] skip
-[!exec:git] skip
+[!git] skip
 
 # secure fetch should report insecure warning
 cd $WORK/test
diff --git a/src/cmd/go/testdata/script/mod_doc_path.txt b/src/cmd/go/testdata/script/mod_doc_path.txt
index 57470a9..83d5392 100644
--- a/src/cmd/go/testdata/script/mod_doc_path.txt
+++ b/src/cmd/go/testdata/script/mod_doc_path.txt
@@ -4,7 +4,7 @@
 # Remove 'go' from $PATH. (It can still be located via $GOROOT/bin/go, and the
 # test script's built-in 'go' command still knows where to find it.)
 env PATH=''
-[plan9] env path=''
+[GOOS:plan9] env path=''
 
 go doc p.X
 
diff --git a/src/cmd/go/testdata/script/mod_download_concurrent_read.txt b/src/cmd/go/testdata/script/mod_download_concurrent_read.txt
index 231babd..c2c8b18 100644
--- a/src/cmd/go/testdata/script/mod_download_concurrent_read.txt
+++ b/src/cmd/go/testdata/script/mod_download_concurrent_read.txt
@@ -10,7 +10,7 @@
 # Since 1.16, we extract to the final directory, but we create a .partial file
 # so that if we crash, other processes know the directory is incomplete.
 
-[!windows] skip
+[!GOOS:windows] skip
 [short] skip
 
 go run downloader.go
diff --git a/src/cmd/go/testdata/script/mod_download_git_decorate_full.txt b/src/cmd/go/testdata/script/mod_download_git_decorate_full.txt
index 3b19acc..997b502 100644
--- a/src/cmd/go/testdata/script/mod_download_git_decorate_full.txt
+++ b/src/cmd/go/testdata/script/mod_download_git_decorate_full.txt
@@ -1,7 +1,7 @@
 env GO111MODULE=on
 
 [!net] skip
-[!exec:git] skip
+[!git] skip
 
 env GOPROXY=direct
 env HOME=$WORK/home/gopher
diff --git a/src/cmd/go/testdata/script/mod_download_hash.txt b/src/cmd/go/testdata/script/mod_download_hash.txt
index 5a42c4b..e62a165 100644
--- a/src/cmd/go/testdata/script/mod_download_hash.txt
+++ b/src/cmd/go/testdata/script/mod_download_hash.txt
@@ -2,7 +2,7 @@
 
 # Testing mod download with non semantic versions; turn off proxy.
 [!net] skip
-[!exec:git] skip
+[!git] skip
 env GOPROXY=direct
 env GOSUMDB=off
 
diff --git a/src/cmd/go/testdata/script/mod_download_insecure_redirect.txt b/src/cmd/go/testdata/script/mod_download_insecure_redirect.txt
index 46eb666..fed5b8d 100644
--- a/src/cmd/go/testdata/script/mod_download_insecure_redirect.txt
+++ b/src/cmd/go/testdata/script/mod_download_insecure_redirect.txt
@@ -1,7 +1,7 @@
 # golang.org/issue/29591: 'go get' was following plain-HTTP redirects even without -insecure (now replaced by GOINSECURE).
 
 [!net] skip
-[!exec:git] skip
+[!git] skip
 
 env GO111MODULE=on
 env GOPROXY=direct
diff --git a/src/cmd/go/testdata/script/mod_download_issue51114.txt b/src/cmd/go/testdata/script/mod_download_issue51114.txt
index 92479c6..68cce8c 100644
--- a/src/cmd/go/testdata/script/mod_download_issue51114.txt
+++ b/src/cmd/go/testdata/script/mod_download_issue51114.txt
@@ -1,7 +1,7 @@
 [short] skip
-[!exec:git] skip
+[!git] skip
 [!net] skip
-[!linux] skip  # Uses XDG_CONFIG_HOME
+[!GOOS:linux] skip  # Uses XDG_CONFIG_HOME
 
 env GIT_CONFIG_GLOBAL=$WORK/.gitconfig
 env GOPROXY=direct
diff --git a/src/cmd/go/testdata/script/mod_download_private_vcs.txt b/src/cmd/go/testdata/script/mod_download_private_vcs.txt
index da9fe02..7459b80 100644
--- a/src/cmd/go/testdata/script/mod_download_private_vcs.txt
+++ b/src/cmd/go/testdata/script/mod_download_private_vcs.txt
@@ -2,7 +2,7 @@
 
 # Testing stderr for git ls-remote; turn off proxy.
 [!net] skip
-[!exec:git] skip
+[!git] skip
 env GOPROXY=direct
 
 ! go mod download github.com/golang/nonexist@latest
diff --git a/src/cmd/go/testdata/script/mod_empty_err.txt b/src/cmd/go/testdata/script/mod_empty_err.txt
index c4359bc..4b4a007 100644
--- a/src/cmd/go/testdata/script/mod_empty_err.txt
+++ b/src/cmd/go/testdata/script/mod_empty_err.txt
@@ -4,20 +4,20 @@
 cd $WORK
 
 go list -e -f {{.Error}} .
-stdout 'no Go files in \$WORK'
+stdout 'no Go files in '$WORK
 
 go list -e -f {{.Error}} ./empty
-stdout 'no Go files in \$WORK[/\\]empty'
+stdout 'no Go files in '$WORK${/}'empty'
 
 go list -e -f {{.Error}} ./exclude
-stdout 'build constraints exclude all Go files in \$WORK[/\\]exclude'
+stdout 'build constraints exclude all Go files in '$WORK${/}'exclude'
 
 go list -e -f {{.Error}} ./missing
 stdout 'stat '$WORK'[/\\]missing: directory not found'
 
 # use 'go build -n' because 'go list' reports no error.
 ! go build -n ./testonly
-stderr 'example.com/m/testonly: no non-test Go files in \$WORK[/\\]testonly'
+stderr 'example.com/m/testonly: no non-test Go files in '$WORK${/}'testonly'
 
 -- $WORK/go.mod --
 module example.com/m
diff --git a/src/cmd/go/testdata/script/mod_file_proxy.txt b/src/cmd/go/testdata/script/mod_file_proxy.txt
index 38d9fd2..ebc28a0 100644
--- a/src/cmd/go/testdata/script/mod_file_proxy.txt
+++ b/src/cmd/go/testdata/script/mod_file_proxy.txt
@@ -12,11 +12,11 @@
 
 # Use download cache as file:/// proxy.
 env GOPATH=$WORK/gopath2
-[windows] env GOPROXY=file:///C:/nonexist
-[!windows] env GOPROXY=file:///nonexist
+[GOOS:windows] env GOPROXY=file:///C:/nonexist
+[!GOOS:windows] env GOPROXY=file:///nonexist
 ! go list
-[windows] env GOPROXY=file:///$WORK/gopath1/pkg/mod/cache/download
-[!windows] env GOPROXY=file://$WORK/gopath1/pkg/mod/cache/download
+[GOOS:windows] env GOPROXY=file:///$WORK/gopath1/pkg/mod/cache/download
+[!GOOS:windows] env GOPROXY=file://$WORK/gopath1/pkg/mod/cache/download
 go list
 grep v1.5.1 $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/list
 
diff --git a/src/cmd/go/testdata/script/mod_fileproxy_vcs_missing_issue51589.txt b/src/cmd/go/testdata/script/mod_fileproxy_vcs_missing_issue51589.txt
new file mode 100644
index 0000000..633bd8b
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_fileproxy_vcs_missing_issue51589.txt
@@ -0,0 +1,42 @@
+# This test checks that "go mod tidy -e" do not panic when
+# using a file goproxy that is missing some modules.
+# Verifies golang.org/issue/51589
+
+# download the modules first
+env GO111MODULE=on
+env GOPATH=$WORK/gopath
+cd $WORK/x
+go mod tidy
+
+# Use download cache as file:/// proxy.
+[GOOS:windows] env GOPROXY=file:///$WORK/gopath/pkg/mod/cache/download
+[!GOOS:windows] env GOPROXY=file://$WORK/gopath/pkg/mod/cache/download
+rm $WORK/gopath/pkg/mod/cache/download/golang.org/x/text/
+go mod tidy -e
+stderr '^go: rsc.io/[email protected] requires\n\tgolang.org/x/text@.*: reading file://.*/pkg/mod/cache/download/golang.org/x/text/.*'
+! stderr 'signal SIGSEGV: segmentation violation'
+
+-- $WORK/x/go.mod --
+module example.com/mod
+
+go 1.17
+
+require rsc.io/quote v1.5.2
+
+require (
+	golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c // indirect
+	rsc.io/sampler v1.3.0 // indirect
+)
+
+-- $WORK/x/x.go --
+package mod
+
+import (
+	"fmt"
+
+	"rsc.io/quote"
+)
+
+func Echo() {
+	fmt.Println(quote.Hello())
+}
diff --git a/src/cmd/go/testdata/script/mod_find.txt b/src/cmd/go/testdata/script/mod_find.txt
index 1e01973..9c2037b 100644
--- a/src/cmd/go/testdata/script/mod_find.txt
+++ b/src/cmd/go/testdata/script/mod_find.txt
@@ -8,7 +8,7 @@
 
 # Import comment works even with CRLF line endings.
 rm go.mod
-addcrlf x.go
+replace '\n' '\r\n' x.go
 go mod init
 stderr 'module x'
 
diff --git a/src/cmd/go/testdata/script/mod_fs_patterns.txt b/src/cmd/go/testdata/script/mod_fs_patterns.txt
index 276d04e..c834ce8 100644
--- a/src/cmd/go/testdata/script/mod_fs_patterns.txt
+++ b/src/cmd/go/testdata/script/mod_fs_patterns.txt
@@ -51,11 +51,11 @@
 # a package path.
 cd ../badat/bad@
 ! go list .
-stderr 'directory . outside main module or its selected dependencies'
+stderr 'current directory outside main module or its selected dependencies'
 ! go list $PWD
-stderr 'directory . outside main module or its selected dependencies'
+stderr 'current directory outside main module or its selected dependencies'
 ! go list $PWD/...
-stderr 'directory . outside main module or its selected dependencies'
+stderr 'current directory outside main module or its selected dependencies'
 
 -- x/go.mod --
 module m
diff --git a/src/cmd/go/testdata/script/mod_get_commit.txt b/src/cmd/go/testdata/script/mod_get_commit.txt
index f60eaab..76650f3 100644
--- a/src/cmd/go/testdata/script/mod_get_commit.txt
+++ b/src/cmd/go/testdata/script/mod_get_commit.txt
@@ -19,10 +19,8 @@
 go build -x golang.org/x/text/language
 stderr 'compile|cp|gccgo .*language\.a$'
 
-# BUG: after the build, the package should not be stale, as 'go install' would
-# not do anything further.
 go list -f '{{.Stale}}' golang.org/x/text/language
-stdout ^true
+stdout ^false
 
 # install after build should not run the compiler again.
 go install -x golang.org/x/text/language
diff --git a/src/cmd/go/testdata/script/mod_get_direct.txt b/src/cmd/go/testdata/script/mod_get_direct.txt
index 856e05b..b7b0529 100644
--- a/src/cmd/go/testdata/script/mod_get_direct.txt
+++ b/src/cmd/go/testdata/script/mod_get_direct.txt
@@ -4,7 +4,7 @@
 
 [short] skip
 [!net] skip
-[!exec:git] skip
+[!git] skip
 
 env GO111MODULE=on
 env GOPROXY=direct
diff --git a/src/cmd/go/testdata/script/mod_get_hash.txt b/src/cmd/go/testdata/script/mod_get_hash.txt
index 3bb3ee7..63e9e46 100644
--- a/src/cmd/go/testdata/script/mod_get_hash.txt
+++ b/src/cmd/go/testdata/script/mod_get_hash.txt
@@ -2,7 +2,7 @@
 env GOPROXY=direct
 env GOSUMDB=off
 [!net] skip
-[!exec:git] skip
+[!git] skip
 
 # fetch commit hash reachable from refs/heads/* and refs/tags/* is OK
 go list -m golang.org/x/time@8be79e1e0910c292df4e79c241bb7e8f7e725959 # on master branch
diff --git a/src/cmd/go/testdata/script/mod_get_major.txt b/src/cmd/go/testdata/script/mod_get_major.txt
index 2db1318..76c9de5 100644
--- a/src/cmd/go/testdata/script/mod_get_major.txt
+++ b/src/cmd/go/testdata/script/mod_get_major.txt
@@ -1,5 +1,5 @@
 [!net] skip
-[!exec:git] skip
+[!git] skip
 
 env GO111MODULE=on
 env GOPROXY=direct
diff --git a/src/cmd/go/testdata/script/mod_get_pseudo.txt b/src/cmd/go/testdata/script/mod_get_pseudo.txt
index b964ae4..7b43c69 100644
--- a/src/cmd/go/testdata/script/mod_get_pseudo.txt
+++ b/src/cmd/go/testdata/script/mod_get_pseudo.txt
@@ -2,7 +2,7 @@
 
 # Testing git->module converter's generation of +incompatible tags; turn off proxy.
 [!net] skip
-[!exec:git] skip
+[!git] skip
 env GOPROXY=direct
 env GOSUMDB=off
 
diff --git a/src/cmd/go/testdata/script/mod_get_pseudo_other_branch.txt b/src/cmd/go/testdata/script/mod_get_pseudo_other_branch.txt
index d085f4f..21f900f 100644
--- a/src/cmd/go/testdata/script/mod_get_pseudo_other_branch.txt
+++ b/src/cmd/go/testdata/script/mod_get_pseudo_other_branch.txt
@@ -7,7 +7,7 @@
 # supplied to 'go get', regardless of branches
 
 [!net] skip
-[!exec:git] skip
+[!git] skip
 
 # For this test repository:
 #  tag v0.2.1 is most recent tag on master itself
diff --git a/src/cmd/go/testdata/script/mod_get_pseudo_prefix.txt b/src/cmd/go/testdata/script/mod_get_pseudo_prefix.txt
index 8e6cd90..513450d 100644
--- a/src/cmd/go/testdata/script/mod_get_pseudo_prefix.txt
+++ b/src/cmd/go/testdata/script/mod_get_pseudo_prefix.txt
@@ -7,7 +7,7 @@
 # to 'go get', when using a repo with go.mod in a sub directory.
 
 [!net] skip
-[!exec:git] skip
+[!git] skip
 
 # For this test repository go.mod resides in sub/ (only):
 #  master is not tagged
diff --git a/src/cmd/go/testdata/script/mod_getx.txt b/src/cmd/go/testdata/script/mod_getx.txt
index b3d06c1..dee3f74 100644
--- a/src/cmd/go/testdata/script/mod_getx.txt
+++ b/src/cmd/go/testdata/script/mod_getx.txt
@@ -1,6 +1,6 @@
 [short] skip
 [!net] skip
-[!exec:git] skip
+[!git] skip
 
 env GO111MODULE=on
 env GOPROXY=direct
diff --git a/src/cmd/go/testdata/script/mod_git_export_subst.txt b/src/cmd/go/testdata/script/mod_git_export_subst.txt
index a28b4f2..44fb501 100644
--- a/src/cmd/go/testdata/script/mod_git_export_subst.txt
+++ b/src/cmd/go/testdata/script/mod_git_export_subst.txt
@@ -3,7 +3,7 @@
 
 # Testing that git export-subst is disabled
 [!net] skip
-[!exec:git] skip
+[!git] skip
 go build
 
 -- x.go --
diff --git a/src/cmd/go/testdata/script/mod_go_version_missing.txt b/src/cmd/go/testdata/script/mod_go_version_missing.txt
index 2159a1e..f40b48f 100644
--- a/src/cmd/go/testdata/script/mod_go_version_missing.txt
+++ b/src/cmd/go/testdata/script/mod_go_version_missing.txt
@@ -27,7 +27,8 @@
 
 ! go list -mod=vendor all
 ! stderr '^go: inconsistent vendoring'
-stderr 'cannot find package "vendor/example.com/badedit" in:\n\t.*[/\\]vendor[/\\]example.com[/\\]badedit$'
+stderr 'go: finding module for package example.com/badedit'
+stderr 'cannot query module due to -mod=vendor'
 
 # When we set -mod=mod, the go version should be updated immediately,
 # to the current version, converting the requirements from eager to lazy.
diff --git a/src/cmd/go/testdata/script/mod_gobuild_import.txt b/src/cmd/go/testdata/script/mod_gobuild_import.txt
index c13ae84..70af331 100644
--- a/src/cmd/go/testdata/script/mod_gobuild_import.txt
+++ b/src/cmd/go/testdata/script/mod_gobuild_import.txt
@@ -55,13 +55,13 @@
 env GO111MODULE=on
 exec $WORK/testfindonly$GOEXE gobuild.example.com/x/y/z/i $WORK
 ! stdout 'build constraints'
-stdout '^dir=\$WORK.+i err=<nil>$'
+stdout '^dir='$WORK'.+i err=<nil>$'
 
 # Issue 37153: Import with empty srcDir should work.
 env GO111MODULE=on
 exec $WORK/testfindonly$GOEXE gobuild.example.com/x/y/z/i ''
 ! stdout 'build constraints'
-stdout '^dir=\$WORK.+i err=<nil>$'
+stdout '^dir='$WORK'.+i err=<nil>$'
 
 -- go.mod --
 module gobuild.example.com/x/y/z
diff --git a/src/cmd/go/testdata/script/mod_gomodcache.txt b/src/cmd/go/testdata/script/mod_gomodcache.txt
index bafa587..bfc6cb1 100644
--- a/src/cmd/go/testdata/script/mod_gomodcache.txt
+++ b/src/cmd/go/testdata/script/mod_gomodcache.txt
@@ -23,9 +23,9 @@
 grep '{"Version":"v1.0.0","Time":"2018-02-14T00:45:20Z"}' $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.0.0.info
 
 # If neither GOMODCACHE or GOPATH are set, GOPATH defaults to the user's $HOME/go, so GOMODCACHE becomes $HOME/go/pkg/mod
-[windows] env USERPROFILE=$WORK/home # Ensure USERPROFILE is a valid path (rather than /no-home/ so we don't run into the logic that "uninfers" GOPATH in cmd/go/main.go
-[plan9] env home=$WORK/home
-[!windows] [!plan9] env HOME=$WORK/home
+[GOOS:windows] env USERPROFILE=$WORK/home # Ensure USERPROFILE is a valid path (rather than /no-home/ so we don't run into the logic that "uninfers" GOPATH in cmd/go/main.go
+[GOOS:plan9] env home=$WORK/home
+[!GOOS:windows] [!GOOS:plan9] env HOME=$WORK/home
 env GOMODCACHE=
 env GOPATH=
 go env GOMODCACHE
diff --git a/src/cmd/go/testdata/script/mod_gonoproxy.txt b/src/cmd/go/testdata/script/mod_gonoproxy.txt
index d42d668..98a1d28 100644
--- a/src/cmd/go/testdata/script/mod_gonoproxy.txt
+++ b/src/cmd/go/testdata/script/mod_gonoproxy.txt
@@ -37,7 +37,7 @@
 
 # GONOPROXY bypasses proxy
 [!net] skip
-[!exec:git] skip
+[!git] skip
 env GOPRIVATE=none
 env GONOPROXY='*/fortune'
 ! go get rsc.io/fortune # does not exist in real world, only on test proxy
diff --git a/src/cmd/go/testdata/script/mod_gopkg_unstable.txt b/src/cmd/go/testdata/script/mod_gopkg_unstable.txt
index beba3e7..3608bcd 100644
--- a/src/cmd/go/testdata/script/mod_gopkg_unstable.txt
+++ b/src/cmd/go/testdata/script/mod_gopkg_unstable.txt
@@ -8,7 +8,9 @@
 go list
 
 [!net] skip
-[!exec:git] skip
+[!git] skip
+
+skip  # TODO(#54503): redirect gopkg.in requests to a local server and re-enable.
 
 env GOPROXY=direct
 env GOSUMDB=off
diff --git a/src/cmd/go/testdata/script/mod_graph.txt b/src/cmd/go/testdata/script/mod_graph.txt
index 07968f5..8d51439 100644
--- a/src/cmd/go/testdata/script/mod_graph.txt
+++ b/src/cmd/go/testdata/script/mod_graph.txt
@@ -4,6 +4,11 @@
 stdout '^m rsc.io/[email protected]$'
 stdout '^rsc.io/[email protected] rsc.io/[email protected]$'
 ! stdout '^m rsc.io/[email protected]$'
+! stderr 'get '$GOPROXY
+
+rm $GOPATH/pkg/mod/cache/download/rsc.io/quote
+go mod graph -x
+stderr 'get '$GOPROXY
 
 -- go.mod --
 module m
diff --git a/src/cmd/go/testdata/script/mod_graph_version.txt b/src/cmd/go/testdata/script/mod_graph_version.txt
index f9a73f4..ed7e399 100644
--- a/src/cmd/go/testdata/script/mod_graph_version.txt
+++ b/src/cmd/go/testdata/script/mod_graph_version.txt
@@ -57,7 +57,7 @@
 # Unsupported go versions should be rejected, since we don't know
 # what versions they would report.
 ! go mod graph -go=1.99999999999
-stderr '^invalid value "1\.99999999999" for flag -go: maximum supported Go version is '$goversion'\nusage: go mod graph \[-go=version\]\nRun ''go help mod graph'' for details.$'
+stderr '^invalid value "1\.99999999999" for flag -go: maximum supported Go version is '$goversion'\nusage: go mod graph \[-go=version\] \[-x\]\nRun ''go help mod graph'' for details.$'
 
 
 -- go.mod --
diff --git a/src/cmd/go/testdata/script/mod_init_empty.txt b/src/cmd/go/testdata/script/mod_init_empty.txt
index 1c3888c..d197a79 100644
--- a/src/cmd/go/testdata/script/mod_init_empty.txt
+++ b/src/cmd/go/testdata/script/mod_init_empty.txt
@@ -1,6 +1,6 @@
 env GO111MODULE=on
 
-env GOPATH=$devnull
+env GOPATH=$WORK${/}invalid-gopath
 
 go list -m
 stdout '^example.com$'
@@ -16,3 +16,6 @@
 package main
 
 func main() {}
+
+-- $WORK/invalid-gopath
+This is a text file, not a directory.
diff --git a/src/cmd/go/testdata/script/mod_init_glide.txt b/src/cmd/go/testdata/script/mod_init_glide.txt
index 373810c..2126ae5 100644
--- a/src/cmd/go/testdata/script/mod_init_glide.txt
+++ b/src/cmd/go/testdata/script/mod_init_glide.txt
@@ -1,5 +1,5 @@
 [!net] skip
-[!exec:git] skip
+[!git] skip
 
 env GO111MODULE=on
 env GOPROXY=direct
diff --git a/src/cmd/go/testdata/script/mod_invalid_version.txt b/src/cmd/go/testdata/script/mod_invalid_version.txt
index 8385b08..d1e1da4 100644
--- a/src/cmd/go/testdata/script/mod_invalid_version.txt
+++ b/src/cmd/go/testdata/script/mod_invalid_version.txt
@@ -1,5 +1,5 @@
 [!net] skip
-[!exec:git] skip
+[!git] skip
 
 env GO111MODULE=on
 env GOPROXY=direct
diff --git a/src/cmd/go/testdata/script/mod_issue35270.txt b/src/cmd/go/testdata/script/mod_issue35270.txt
new file mode 100644
index 0000000..6c2587a
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_issue35270.txt
@@ -0,0 +1,57 @@
+
+cd a
+! go build
+stderr '^ambiguous import: found package image in multiple modules:\s+image\s+.+\s.+image.+\s$'
+
+
+cd ../b
+! go build -mod=vendor
+stderr '^main.go:4:5: ambiguous import: found package image in multiple directories:\s+.+image\s+.+image\s+$'
+
+cd ../c
+! go build -mod=vendor
+stderr 'main.go:4:5: package p is not in GOROOT'
+
+-- a/go.mod --
+module image
+
+-- a/main.go --
+package main
+
+func main() {
+    println("hello world!")
+}
+
+-- b/go.mod --
+module test
+
+-- b/vendor/image/b.go --
+package image
+func Add(a, b int) int {
+    return a + b
+}
+
+-- b/main.go --
+package main
+
+import (
+    "image"
+)
+
+func main() {
+    println(image.Add(1,1))
+}
+
+-- c/go.mod --
+module test
+
+-- c/main.go --
+package main
+
+import (
+    "p"
+)
+
+func main() {
+    println(p.Add(1,1))
+}
\ No newline at end of file
diff --git a/src/cmd/go/testdata/script/mod_list_command_line_arguments.txt b/src/cmd/go/testdata/script/mod_list_command_line_arguments.txt
index fd99ae8..25c68c5 100644
--- a/src/cmd/go/testdata/script/mod_list_command_line_arguments.txt
+++ b/src/cmd/go/testdata/script/mod_list_command_line_arguments.txt
@@ -14,7 +14,7 @@
 go version -m a.exe
 stdout '^\tpath\tcommand-line-arguments$'
 stdout '^\tdep\ta\t\(devel\)\t$'
-! stdout mod
+! stdout mod[^e]
 
 -- a/go.mod --
 module a
diff --git a/src/cmd/go/testdata/script/mod_list_direct.txt b/src/cmd/go/testdata/script/mod_list_direct.txt
index 3aa1881..3e7c479 100644
--- a/src/cmd/go/testdata/script/mod_list_direct.txt
+++ b/src/cmd/go/testdata/script/mod_list_direct.txt
@@ -3,7 +3,7 @@
 env GOSUMDB=off
 
 [!net] skip
-[!exec:git] skip
+[!git] skip
 
 # golang.org/issue/33099: if an import path ends in a major-version suffix,
 # ensure that 'direct' mode can resolve the package to the module.
diff --git a/src/cmd/go/testdata/script/mod_list_odd_tags.txt b/src/cmd/go/testdata/script/mod_list_odd_tags.txt
index c1f40cd..b413e87 100644
--- a/src/cmd/go/testdata/script/mod_list_odd_tags.txt
+++ b/src/cmd/go/testdata/script/mod_list_odd_tags.txt
@@ -1,5 +1,5 @@
 [short] skip
-[!exec:git] skip
+[!git] skip
 [!net] skip
 
 env GOPROXY=direct
diff --git a/src/cmd/go/testdata/script/mod_list_std.txt b/src/cmd/go/testdata/script/mod_list_std.txt
index f4e0433..cd95b6a 100644
--- a/src/cmd/go/testdata/script/mod_list_std.txt
+++ b/src/cmd/go/testdata/script/mod_list_std.txt
@@ -1,7 +1,7 @@
 env GO111MODULE=on
 env GOPROXY=off
 
-[!gc] skip
+[!compiler:gc] skip
 [short] skip
 
 # Outside of GOROOT, our vendored packages should be reported as part of the standard library.
@@ -12,7 +12,7 @@
 
 # The dependencies of those packages should also be vendored.
 go list -deps vendor/golang.org/x/crypto/chacha20
-stdout ^vendor/golang\.org/x/crypto/internal/subtle
+stdout ^vendor/golang\.org/x/crypto/internal/alias
 
 # cmd/... should match the same packages it used to match in GOPATH mode.
 go list cmd/...
@@ -44,7 +44,7 @@
 # The dependencies of packages with an explicit 'vendor/' prefix should
 # still themselves resolve to vendored packages.
 go list -deps vendor/golang.org/x/crypto/chacha20
-stdout ^vendor/golang.org/x/crypto/internal/subtle
+stdout ^vendor/golang.org/x/crypto/internal/alias
 ! stdout ^golang\.org/x
 
 # Within the std module, the dependencies of the non-vendored packages within
diff --git a/src/cmd/go/testdata/script/mod_load_missing_std.txt b/src/cmd/go/testdata/script/mod_load_missing_std.txt
new file mode 100644
index 0000000..bd2508a
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_load_missing_std.txt
@@ -0,0 +1,17 @@
+# Go should indicate the version the module requires when a standard library
+# import is missing. See golang.org/issue/48966.
+
+! go build .
+stderr '^main.go:3:8: package nonexistent is not in GOROOT \(.*\)$'
+stderr '^note: imported by a module that requires go 1.99999$'
+
+-- go.mod --
+module example
+
+go 1.99999
+-- main.go --
+package main
+
+import _ "nonexistent"
+
+func main() {}
diff --git a/src/cmd/go/testdata/script/mod_missing_repo.txt b/src/cmd/go/testdata/script/mod_missing_repo.txt
index b91a8db..4b403fe 100644
--- a/src/cmd/go/testdata/script/mod_missing_repo.txt
+++ b/src/cmd/go/testdata/script/mod_missing_repo.txt
@@ -3,7 +3,7 @@
 # tags for prefixes of the module path.
 
 [!net] skip
-[!exec:git] skip
+[!git] skip
 
 env GO111MODULE=on
 env GOPROXY=direct
diff --git a/src/cmd/go/testdata/script/mod_outside.txt b/src/cmd/go/testdata/script/mod_outside.txt
index f88e2ae..ed13e59 100644
--- a/src/cmd/go/testdata/script/mod_outside.txt
+++ b/src/cmd/go/testdata/script/mod_outside.txt
@@ -203,7 +203,10 @@
 ! go install ./needmod/needmod.go
 stderr 'needmod[/\\]needmod.go:10:2: no required module provides package example.com/version: go.mod file not found in current directory or any parent directory; see ''go help modules''$'
 
-# 'go install' should succeed with a package in GOROOT.
+# 'go install' for a package in GOROOT should succeed.
+# (It must be non-stale here so that the test does not write to GOROOT).
+go build -o $devnull cmd/addr2line  # make sure any necessary dependencies are present in GOCACHE
+! stale cmd/addr2line
 go install cmd/addr2line
 ! stderr .
 
diff --git a/src/cmd/go/testdata/script/mod_perm.txt b/src/cmd/go/testdata/script/mod_perm.txt
index f5382ec..2972f46 100644
--- a/src/cmd/go/testdata/script/mod_perm.txt
+++ b/src/cmd/go/testdata/script/mod_perm.txt
@@ -5,8 +5,8 @@
 # skip in conditions where chmod 0 may not work.
 # plan9 should be fine, but copied from list_perm.txt unchanged.
 [root] skip
-[windows] skip
-[plan9] skip
+[GOOS:windows] skip
+[GOOS:plan9] skip
 
 # go list should work with unreadable _data directory.
 chmod 0 _data
diff --git a/src/cmd/go/testdata/script/mod_permissions.txt b/src/cmd/go/testdata/script/mod_permissions.txt
index 77e2508..b523e6a 100644
--- a/src/cmd/go/testdata/script/mod_permissions.txt
+++ b/src/cmd/go/testdata/script/mod_permissions.txt
@@ -5,8 +5,8 @@
 [short] skip
 
 # Skip platforms that do not have Unix-style file permissions.
-[windows] skip
-[plan9] skip
+[GOOS:windows] skip
+[GOOS:plan9] skip
 
 chmod 0640 go.mod
 chmod 0604 go.sum
diff --git a/src/cmd/go/testdata/script/mod_prefer_compatible.txt b/src/cmd/go/testdata/script/mod_prefer_compatible.txt
index 8e88997..7ba5eb4 100644
--- a/src/cmd/go/testdata/script/mod_prefer_compatible.txt
+++ b/src/cmd/go/testdata/script/mod_prefer_compatible.txt
@@ -34,7 +34,7 @@
 # order to determine whether it contains a go.mod file, and part of the point of
 # the proxy is to avoid fetching unnecessary data.)
 
-[!exec:git] stop
+[!git] stop
 env GOPROXY=direct
 
 go list -versions -m github.com/russross/blackfriday github.com/russross/blackfriday
diff --git a/src/cmd/go/testdata/script/mod_pseudo_cache.txt b/src/cmd/go/testdata/script/mod_pseudo_cache.txt
index dd89614..a7ceac4 100644
--- a/src/cmd/go/testdata/script/mod_pseudo_cache.txt
+++ b/src/cmd/go/testdata/script/mod_pseudo_cache.txt
@@ -1,5 +1,5 @@
 [!net] skip
-[!exec:git] skip
+[!git] skip
 
 env GO111MODULE=on
 env GOPROXY=direct
diff --git a/src/cmd/go/testdata/script/mod_replace_gopkgin.txt b/src/cmd/go/testdata/script/mod_replace_gopkgin.txt
index df752d9..04b79dd 100644
--- a/src/cmd/go/testdata/script/mod_replace_gopkgin.txt
+++ b/src/cmd/go/testdata/script/mod_replace_gopkgin.txt
@@ -4,9 +4,12 @@
 # even if there is an explicit go.mod file containing the
 # gopkg.in path.
 
+skip 'skipping test that depends on an unreliable third-party server; see https://go.dev/issue/54503'
+	# TODO(#54043): Make this test hermetic and re-enable it.
+
 [short] skip
 [!net] skip
-[!exec:git] skip
+[!git] skip
 
 env GO111MODULE=on
 env GOPROXY=direct
diff --git a/src/cmd/go/testdata/script/mod_retract_pseudo_base.txt b/src/cmd/go/testdata/script/mod_retract_pseudo_base.txt
index 27c2b67..c52f0b8 100644
--- a/src/cmd/go/testdata/script/mod_retract_pseudo_base.txt
+++ b/src/cmd/go/testdata/script/mod_retract_pseudo_base.txt
@@ -3,7 +3,7 @@
 # Verifies golang.org/issue/41700.
 
 [!net] skip
-[!exec:git] skip
+[!git] skip
 env GOPROXY=direct
 env GOSUMDB=off
 go mod init m
diff --git a/src/cmd/go/testdata/script/mod_stale.txt b/src/cmd/go/testdata/script/mod_stale.txt
new file mode 100644
index 0000000..c6ab27d
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_stale.txt
@@ -0,0 +1,15 @@
+[short] skip
+
+env GOCACHE=$WORK/cache
+go list -f '{{.Stale}}' .
+stdout true
+go install .
+go list -f '{{.Stale}}' .
+stdout false
+
+-- go.mod --
+module example.com/mod
+
+go 1.20
+-- m.go --
+package m
diff --git a/src/cmd/go/testdata/script/mod_std_vendor.txt b/src/cmd/go/testdata/script/mod_std_vendor.txt
index c3cde52..7e4c210 100644
--- a/src/cmd/go/testdata/script/mod_std_vendor.txt
+++ b/src/cmd/go/testdata/script/mod_std_vendor.txt
@@ -1,7 +1,7 @@
 env GO111MODULE=on
 env GOPROXY=off
 
-[!gc] skip
+[!compiler:gc] skip
 
 # 'go list' should report imports from _test.go in the TestImports field.
 go list -f '{{.TestImports}}'
@@ -22,8 +22,9 @@
 ! go build -mod=readonly
 stderr 'disabled by -mod=readonly'
 ! go build -mod=vendor
-stderr 'cannot find package'
-stderr 'hpack'
+stderr 'go: finding module for package golang.org/x/net/http2/hpack'
+stderr 'http.go:5:2: cannot query module due to -mod=vendor'
+
 
 # ...even if they explicitly use the "cmd/vendor/" or "vendor/" prefix.
 cd ../importcmd
diff --git a/src/cmd/go/testdata/script/mod_sumdb_file_path.txt b/src/cmd/go/testdata/script/mod_sumdb_file_path.txt
index a834c48..d89ad1a 100644
--- a/src/cmd/go/testdata/script/mod_sumdb_file_path.txt
+++ b/src/cmd/go/testdata/script/mod_sumdb_file_path.txt
@@ -10,23 +10,23 @@
 #
 # TODO(bcmills): The error message here is a bit redundant.
 # It comes from the sumweb package, which isn't yet producing structured errors.
-[windows] env GOPROXY=file:///$WORK/sumproxy,https://proxy.golang.org
-[!windows] env GOPROXY=file://$WORK/sumproxy,https://proxy.golang.org
+[GOOS:windows] env GOPROXY=file:///$WORK/sumproxy,https://proxy.golang.org
+[!GOOS:windows] env GOPROXY=file://$WORK/sumproxy,https://proxy.golang.org
 ! go get golang.org/x/[email protected]
 stderr '^go: golang.org/x/[email protected]: verifying module: golang.org/x/[email protected]: reading file://.*/sumdb/sum.golang.org/lookup/golang.org/x/[email protected]: (no such file or directory|.*cannot find the path specified.*)'
 
 # If the proxy does not claim to support the database,
 # checksum verification should fall through to the next proxy,
 # and downloading should succeed.
-[windows] env GOPROXY=file:///$WORK/emptyproxy,https://proxy.golang.org
-[!windows] env GOPROXY=file://$WORK/emptyproxy,https://proxy.golang.org
+[GOOS:windows] env GOPROXY=file:///$WORK/emptyproxy,https://proxy.golang.org
+[!GOOS:windows] env GOPROXY=file://$WORK/emptyproxy,https://proxy.golang.org
 go get golang.org/x/[email protected]
 
 # After a successful sumdb lookup, the lookup can be repeated
 # using the download cache as a proxy.
 cp supported $GOPATH/pkg/mod/cache/download/sumdb/sum.golang.org/supported
-[windows] env GOPROXY=file:///$WORK/gopath1/pkg/mod/cache/download,file:///$WORK/sumproxy
-[!windows] env GOPROXY=file://$WORK/gopath1/pkg/mod/cache/download,file://$WORK/sumproxy
+[GOOS:windows] env GOPROXY=file:///$WORK/gopath1/pkg/mod/cache/download,file:///$WORK/sumproxy
+[!GOOS:windows] env GOPROXY=file://$WORK/gopath1/pkg/mod/cache/download,file://$WORK/sumproxy
 env GOPATH=$WORK/gopath2
 rm go.sum
 go get -x -v golang.org/x/[email protected]
@@ -36,11 +36,11 @@
 # a fallback module mirror.
 grep golang.org/x/text go.sum
 env GOPATH=$WORK/gopath3
-[windows] env GOPROXY=file:///$WORK/sumproxy
-[!windows] env GOPROXY=file://$WORK/sumproxy
+[GOOS:windows] env GOPROXY=file:///$WORK/sumproxy
+[!GOOS:windows] env GOPROXY=file://$WORK/sumproxy
 ! go get golang.org/x/[email protected]
-[windows] env GOPROXY=file:///$WORK/sumproxy,https://proxy.golang.org
-[!windows] env GOPROXY=file://$WORK/sumproxy,https://proxy.golang.org
+[GOOS:windows] env GOPROXY=file:///$WORK/sumproxy,https://proxy.golang.org
+[!GOOS:windows] env GOPROXY=file://$WORK/sumproxy,https://proxy.golang.org
 go get golang.org/x/[email protected]
 
 -- supported --
diff --git a/src/cmd/go/testdata/script/mod_sumdb_golang.txt b/src/cmd/go/testdata/script/mod_sumdb_golang.txt
index a48a5ba..7dd6cdc 100644
--- a/src/cmd/go/testdata/script/mod_sumdb_golang.txt
+++ b/src/cmd/go/testdata/script/mod_sumdb_golang.txt
@@ -12,7 +12,7 @@
 # Download direct from github.
 
 [!net] skip
-[!exec:git] skip
+[!git] skip
 env GOSUMDB=sum.golang.org
 env GOPROXY=direct
 
diff --git a/src/cmd/go/testdata/script/mod_tidy_support_buildx.txt b/src/cmd/go/testdata/script/mod_tidy_support_buildx.txt
new file mode 100644
index 0000000..d2135e1
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_tidy_support_buildx.txt
@@ -0,0 +1,18 @@
+# This test checks that "go mod tidy -x" print
+# commands tidy executes.
+# Verifies golang.org/issue/35849
+
+rm $GOPATH/pkg/mod/cache/download/rsc.io/quote
+go mod tidy
+! stderr 'get '$GOPROXY
+
+rm $GOPATH/pkg/mod/cache/download/rsc.io/quote
+go mod tidy -x
+stderr 'get '$GOPROXY
+
+-- go.mod --
+module example.com/mod
+
+-- a.go --
+package mod
+import _ "rsc.io/quote"
\ No newline at end of file
diff --git a/src/cmd/go/testdata/script/mod_tidy_temp.txt b/src/cmd/go/testdata/script/mod_tidy_temp.txt
index 635a336..8a2fa4e 100644
--- a/src/cmd/go/testdata/script/mod_tidy_temp.txt
+++ b/src/cmd/go/testdata/script/mod_tidy_temp.txt
@@ -4,7 +4,7 @@
 # 1. /tmp/go.mod exists
 # 2. run 'go mod tidy' in /tmp or in the child directory not having go.mod.
 
-[plan9] stop  # Plan 9 has no $TMPDIR variable to set.
+[GOOS:plan9] stop  # Plan 9 has no $TMPDIR variable to set.
 
 env GOROOT=$TESTGO_GOROOT
 env TMP=$WORK
diff --git a/src/cmd/go/testdata/script/mod_vendor.txt b/src/cmd/go/testdata/script/mod_vendor.txt
index a2727dd..a11d7a1 100644
--- a/src/cmd/go/testdata/script/mod_vendor.txt
+++ b/src/cmd/go/testdata/script/mod_vendor.txt
@@ -55,7 +55,7 @@
 go list -mod=mod -f {{.Dir}} w
 stdout 'src[\\/]w'
 ! go list -mod=vendor -f {{.Dir}} w
-stderr 'src[\\/]vendor[\\/]w'
+stderr 'package w is not in GOROOT'
 
 go list -mod=mod -f {{.Dir}} diamondright
 stdout 'src[\\/]diamondright'
diff --git a/src/cmd/go/testdata/script/mod_vendor_replace.txt b/src/cmd/go/testdata/script/mod_vendor_replace.txt
index 1820af6..c492999 100644
--- a/src/cmd/go/testdata/script/mod_vendor_replace.txt
+++ b/src/cmd/go/testdata/script/mod_vendor_replace.txt
@@ -1,5 +1,12 @@
 env GO111MODULE=on
 
+# Replacement should not use a vendor directory as the target.
+! go mod vendor
+stderr 'replacement path ./vendor/not-rsc.io/quote/v3 inside vendor directory'
+
+cp go.mod1 go.mod
+rm -r vendor
+
 # Before vendoring, we expect to see the original directory.
 go list -f '{{with .Module}}{{.Version}}{{end}} {{.Dir}}' rsc.io/quote/v3
 stdout 'v3.0.0'
@@ -35,7 +42,14 @@
 module example.com/replace
 
 require rsc.io/quote/v3 v3.0.0
+replace rsc.io/quote/v3 => ./vendor/not-rsc.io/quote/v3
+
+-- go.mod1 --
+module example.com/replace
+
+require rsc.io/quote/v3 v3.0.0
 replace rsc.io/quote/v3 => ./local/not-rsc.io/quote/v3
+
 -- imports.go --
 package replace
 
@@ -67,3 +81,9 @@
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 rsc.io/quote/v3 v3.0.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
 rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
+
+-- vendor/not-rsc.io/quote/v3/go.mod --
+module not-rsc.io/quote/v3
+
+-- vendor/not-rsc.io/quote/v3/quote.go --
+package quote
diff --git a/src/cmd/go/testdata/script/modfile_flag.txt b/src/cmd/go/testdata/script/modfile_flag.txt
index 398e523..6d28759 100644
--- a/src/cmd/go/testdata/script/modfile_flag.txt
+++ b/src/cmd/go/testdata/script/modfile_flag.txt
@@ -14,7 +14,7 @@
 # 'go env GOMOD' should print the path to the real file.
 # 'go env' does not recognize the '-modfile' flag.
 go env GOMOD
-stdout '^\$WORK[/\\]gopath[/\\]src[/\\]go.mod$'
+stdout '^'$WORK${/}gopath${/}src${/}'go\.mod$'
 
 # 'go list -m' should print the effective go.mod file as GoMod though.
 go list -m -f '{{.GoMod}}'
diff --git a/src/cmd/go/testdata/script/reuse_git.txt b/src/cmd/go/testdata/script/reuse_git.txt
index a5a0c8a..4f9e0dd 100644
--- a/src/cmd/go/testdata/script/reuse_git.txt
+++ b/src/cmd/go/testdata/script/reuse_git.txt
@@ -1,5 +1,5 @@
 [short] skip
-[!exec:git] skip
+[!git] skip
 [!net] skip
 
 env GO111MODULE=on
@@ -13,7 +13,7 @@
 ! stdout '"(Query|TagPrefix|TagSum|Ref)"'
 stdout '"Version": "v0.0.0-20170922010558-fc3a09f3dc5c"'
 stdout '"VCS": "git"'
-stdout '"URL": "https://vcs-test.golang.org/git/hello"'
+stdout '"URL": ".*/git/hello"'
 stdout '"Hash": "fc3a09f3dc5cfe0d7a743ea18f1f5226e68b3777"'
 go clean -modcache
 
@@ -23,7 +23,7 @@
 cp stdout hello.json
 stdout '"Version": "v0.0.0-20170922010558-fc3a09f3dc5c"'
 stdout '"VCS": "git"'
-stdout '"URL": "https://vcs-test.golang.org/git/hello"'
+stdout '"URL": ".*/git/hello"'
 stdout '"Query": "latest"'
 ! stdout '"TagPrefix"'
 stdout '"TagSum": "t1:47DEQpj8HBSa[+]/TImW[+]5JCeuQeRkm5NMpJWZG3hSuFU="'
@@ -36,7 +36,7 @@
 go mod download -x -json vcs-test.golang.org/git/[email protected]
 ! stderr 'git fetch'
 cp stdout hellopseudo2.json
-cmp hellopseudo.json hellopseudo2.json
+cmpenv hellopseudo.json hellopseudo2.json
 
 # go mod download vcstest/hello@hash needs to check TagSum to find pseudoversion base.
 go mod download -x -json vcs-test.golang.org/git/hello.git@fc3a09f3dc5c
@@ -45,7 +45,7 @@
 stdout '"Version": "v0.0.0-20170922010558-fc3a09f3dc5c"'
 stdout '"Query": "fc3a09f3dc5c"'
 stdout '"VCS": "git"'
-stdout '"URL": "https://vcs-test.golang.org/git/hello"'
+stdout '"URL": ".*/git/hello"'
 stdout '"TagSum": "t1:47DEQpj8HBSa[+]/TImW[+]5JCeuQeRkm5NMpJWZG3hSuFU="'
 stdout '"Hash": "fc3a09f3dc5cfe0d7a743ea18f1f5226e68b3777"'
 
@@ -100,7 +100,7 @@
 stdout '"Version": "v0.2.2"'
 stdout '"Query": "latest"'
 stdout '"VCS": "git"'
-stdout '"URL": "https://vcs-test.golang.org/git/tagtests"'
+stdout '"URL": ".*/git/tagtests"'
 ! stdout '"TagPrefix"'
 stdout '"TagSum": "t1:Dp7yRKDuE8WjG0429PN9hYWjqhy2te7P9Oki/sMEOGo="'
 stdout '"Ref": "refs/tags/v0.2.2"'
@@ -112,7 +112,7 @@
 stdout '"Version": "v0.2.2"'
 ! stdout '"Query":'
 stdout '"VCS": "git"'
-stdout '"URL": "https://vcs-test.golang.org/git/tagtests"'
+stdout '"URL": ".*/git/tagtests"'
 ! stdout '"TagPrefix"'
 ! stdout '"TagSum"'
 stdout '"Ref": "refs/tags/v0.2.2"'
@@ -124,7 +124,7 @@
 stdout '"Version": "v0.2.3-0.20190509225625-c7818c24fa2f"'
 stdout '"Query": "master"'
 stdout '"VCS": "git"'
-stdout '"URL": "https://vcs-test.golang.org/git/tagtests"'
+stdout '"URL": ".*/git/tagtests"'
 ! stdout '"TagPrefix"'
 stdout '"TagSum": "t1:Dp7yRKDuE8WjG0429PN9hYWjqhy2te7P9Oki/sMEOGo="'
 stdout '"Ref": "refs/heads/master"'
@@ -137,7 +137,7 @@
 stdout '"Version": "v0.0.10"'
 stdout '"Query": "latest"'
 stdout '"VCS": "git"'
-stdout '"URL": "https://vcs-test.golang.org/git/prefixtagtests"'
+stdout '"URL": ".*/git/prefixtagtests"'
 stdout '"Subdir": "sub"'
 stdout '"TagPrefix": "sub/"'
 stdout '"TagSum": "t1:YGSbWkJ8dn9ORAr[+]BlKHFK/2ZhXLb9hVuYfTZ9D8C7g="'
@@ -160,7 +160,7 @@
 stdout '"Reuse": true'
 stdout '"Version": "v0.0.0-20170922010558-fc3a09f3dc5c"'
 stdout '"VCS": "git"'
-stdout '"URL": "https://vcs-test.golang.org/git/hello"'
+stdout '"URL": ".*/git/hello"'
 ! stdout '"TagPrefix"'
 stdout '"TagSum": "t1:47DEQpj8HBSa[+]/TImW[+]5JCeuQeRkm5NMpJWZG3hSuFU="'
 stdout '"Ref": "HEAD"'
@@ -176,7 +176,7 @@
 stdout '"Reuse": true'
 stdout '"Version": "v0.0.0-20170922010558-fc3a09f3dc5c"'
 stdout '"VCS": "git"'
-stdout '"URL": "https://vcs-test.golang.org/git/hello"'
+stdout '"URL": ".*/git/hello"'
 ! stdout '"(Query|TagPrefix|TagSum|Ref)"'
 stdout '"Hash": "fc3a09f3dc5cfe0d7a743ea18f1f5226e68b3777"'
 ! stdout '"(Dir|Info|GoMod|Zip)"'
@@ -188,7 +188,7 @@
 stdout '"Query": "fc3a09f3dc5c"'
 stdout '"Version": "v0.0.0-20170922010558-fc3a09f3dc5c"'
 stdout '"VCS": "git"'
-stdout '"URL": "https://vcs-test.golang.org/git/hello"'
+stdout '"URL": ".*/git/hello"'
 ! stdout '"(TagPrefix|Ref)"'
 stdout '"TagSum": "t1:47DEQpj8HBSa[+]/TImW[+]5JCeuQeRkm5NMpJWZG3hSuFU="'
 stdout '"Hash": "fc3a09f3dc5cfe0d7a743ea18f1f5226e68b3777"'
@@ -251,7 +251,7 @@
 stdout '"Version": "v0.2.2"'
 stdout '"Query": "latest"'
 stdout '"VCS": "git"'
-stdout '"URL": "https://vcs-test.golang.org/git/tagtests"'
+stdout '"URL": ".*/git/tagtests"'
 ! stdout '"TagPrefix"'
 stdout '"TagSum": "t1:Dp7yRKDuE8WjG0429PN9hYWjqhy2te7P9Oki/sMEOGo="'
 stdout '"Ref": "refs/tags/v0.2.2"'
@@ -265,7 +265,7 @@
 stdout '"Version": "v0.2.2"'
 ! stdout '"Query":'
 stdout '"VCS": "git"'
-stdout '"URL": "https://vcs-test.golang.org/git/tagtests"'
+stdout '"URL": ".*/git/tagtests"'
 ! stdout '"TagPrefix"'
 ! stdout '"TagSum"'
 stdout '"Ref": "refs/tags/v0.2.2"'
@@ -279,7 +279,7 @@
 stdout '"Version": "v0.2.3-0.20190509225625-c7818c24fa2f"'
 stdout '"Query": "master"'
 stdout '"VCS": "git"'
-stdout '"URL": "https://vcs-test.golang.org/git/tagtests"'
+stdout '"URL": ".*/git/tagtests"'
 ! stdout '"TagPrefix"'
 stdout '"TagSum": "t1:Dp7yRKDuE8WjG0429PN9hYWjqhy2te7P9Oki/sMEOGo="'
 stdout '"Ref": "refs/heads/master"'
@@ -293,7 +293,7 @@
 stdout '"Version": "v0.2.3-0.20190509225625-c7818c24fa2f"'
 stdout '"Query": "master"'
 stdout '"VCS": "git"'
-stdout '"URL": "https://vcs-test.golang.org/git/tagtests"'
+stdout '"URL": ".*/git/tagtests"'
 ! stdout '"TagPrefix"'
 stdout '"TagSum": "t1:Dp7yRKDuE8WjG0429PN9hYWjqhy2te7P9Oki/sMEOGo="'
 stdout '"Ref": "refs/heads/master"'
@@ -306,7 +306,7 @@
 stdout '"Version": "v0.0.10"'
 stdout '"Query": "latest"'
 stdout '"VCS": "git"'
-stdout '"URL": "https://vcs-test.golang.org/git/prefixtagtests"'
+stdout '"URL": ".*/git/prefixtagtests"'
 stdout '"Subdir": "sub"'
 stdout '"TagPrefix": "sub/"'
 stdout '"TagSum": "t1:YGSbWkJ8dn9ORAr[+]BlKHFK/2ZhXLb9hVuYfTZ9D8C7g="'
@@ -321,13 +321,15 @@
 ! stdout '"(Dir|Info|GoMod|Zip)"'
 
 # reuse attempt with stale hash should reinvoke git, not report reuse
+cp tagtestsv022.json tagtestsv022badhash.json
+replace '57952' '56952XXX' tagtestsv022badhash.json
 go mod download -reuse=tagtestsv022badhash.json -x -json vcs-test.golang.org/git/[email protected]
 stderr 'git fetch'
 ! stdout '"Reuse": true'
 stdout '"Version": "v0.2.2"'
 ! stdout '"Query"'
 stdout '"VCS": "git"'
-stdout '"URL": "https://vcs-test.golang.org/git/tagtests"'
+stdout '"URL": ".*/git/tagtests"'
 ! stdout '"(TagPrefix|TagSum)"'
 stdout '"Ref": "refs/tags/v0.2.2"'
 stdout '"Hash": "59356c8cd18c5fe9a598167d98a6843e52d57952"'
@@ -337,89 +339,33 @@
 stdout '"Zip"'
 
 # reuse with stale repo URL
+cp tagtestsv022.json tagtestsv022badurl.json
+replace 'git/tagtests\"' 'git/tagtestsXXX\"' tagtestsv022badurl.json
 go mod download -reuse=tagtestsv022badurl.json -x -json vcs-test.golang.org/git/[email protected]
 ! stdout '"Reuse": true'
-stdout '"URL": "https://vcs-test.golang.org/git/tagtests"'
+stdout '"URL": ".*/git/tagtests"'
 stdout '"Dir"'
 stdout '"Info"'
 stdout '"GoMod"'
 stdout '"Zip"'
 
 # reuse with stale VCS
+cp tagtestsv022.json tagtestsv022badvcs.json
+replace '\"git\"' '\"gitXXX\"' tagtestsv022badvcs.json
 go mod download -reuse=tagtestsv022badvcs.json -x -json vcs-test.golang.org/git/[email protected]
 ! stdout '"Reuse": true'
-stdout '"URL": "https://vcs-test.golang.org/git/tagtests"'
+stdout '"URL": ".*/git/tagtests"'
 
 # reuse with stale Dir
+cp tagtestsv022.json tagtestsv022baddir.json
+replace '\t\t\"Ref\":' '\t\t\"Subdir\": \"subdir\",\n\t\t\"Ref\":' tagtestsv022baddir.json
 go mod download -reuse=tagtestsv022baddir.json -x -json vcs-test.golang.org/git/[email protected]
 ! stdout '"Reuse": true'
-stdout '"URL": "https://vcs-test.golang.org/git/tagtests"'
+stdout '"URL": ".*/git/tagtests"'
 
 # reuse with stale TagSum
+cp tagtests.json tagtestsbadtagsum.json
+replace 'sMEOGo=' 'sMEoGo=XXX' tagtestsbadtagsum.json
 go mod download -reuse=tagtestsbadtagsum.json -x -json vcs-test.golang.org/git/tagtests.git@latest
 ! stdout '"Reuse": true'
 stdout '"TagSum": "t1:Dp7yRKDuE8WjG0429PN9hYWjqhy2te7P9Oki/sMEOGo="'
-
--- tagtestsv022badhash.json --
-{
-	"Path": "vcs-test.golang.org/git/tagtests.git",
-	"Version": "v0.2.2",
-	"Origin": {
-		"VCS": "git",
-		"URL": "https://vcs-test.golang.org/git/tagtests",
-		"Ref": "refs/tags/v0.2.2",
-		"Hash": "59356c8cd18c5fe9a598167d98a6843e52d57952XXX"
-	}
-}
-
--- tagtestsbadtagsum.json --
-{
-	"Path": "vcs-test.golang.org/git/tagtests.git",
-	"Version": "v0.2.2",
-	"Query": "latest",
-	"Origin": {
-		"VCS": "git",
-		"URL": "https://vcs-test.golang.org/git/tagtests",
-		"TagSum": "t1:Dp7yRKDuE8WjG0429PN9hYWjqhy2te7P9Oki/sMEOGo=XXX",
-		"Ref": "refs/tags/v0.2.2",
-		"Hash": "59356c8cd18c5fe9a598167d98a6843e52d57952"
-	},
-	"Reuse": true
-}
-
--- tagtestsv022badvcs.json --
-{
-	"Path": "vcs-test.golang.org/git/tagtests.git",
-	"Version": "v0.2.2",
-	"Origin": {
-		"VCS": "gitXXX",
-		"URL": "https://vcs-test.golang.org/git/tagtests",
-		"Ref": "refs/tags/v0.2.2",
-		"Hash": "59356c8cd18c5fe9a598167d98a6843e52d57952"
-	}
-}
-
--- tagtestsv022baddir.json --
-{
-	"Path": "vcs-test.golang.org/git/tagtests.git",
-	"Version": "v0.2.2",
-	"Origin": {
-		"VCS": "git",
-		"URL": "https://vcs-test.golang.org/git/tagtests",
-		"Subdir": "subdir",
-		"Ref": "refs/tags/v0.2.2",
-		"Hash": "59356c8cd18c5fe9a598167d98a6843e52d57952"
-	}
-}
-
--- tagtestsv022badurl.json --
-{
-	"Path": "vcs-test.golang.org/git/tagtests.git",
-	"Version": "v0.2.2",
-	"Origin": {
-		"VCS": "git",
-		"URL": "https://vcs-test.golang.org/git/tagtestsXXX",
-		"Ref": "refs/tags/v0.2.2",
-		"Hash": "59356c8cd18c5fe9a598167d98a6843e52d57952"
-	}
-}
diff --git a/src/cmd/go/testdata/script/script_help.txt b/src/cmd/go/testdata/script/script_help.txt
new file mode 100644
index 0000000..dd7f203
--- /dev/null
+++ b/src/cmd/go/testdata/script/script_help.txt
@@ -0,0 +1,7 @@
+help -v
+
+# To see help for a specific command or condition, run 'help' for it here.
+# For example:
+help wait
+help [verbose]
+help [exec:bash]
diff --git a/src/cmd/go/testdata/script/script_wait.txt b/src/cmd/go/testdata/script/script_wait.txt
index acaccfe..f253060 100644
--- a/src/cmd/go/testdata/script/script_wait.txt
+++ b/src/cmd/go/testdata/script/script_wait.txt
@@ -21,5 +21,8 @@
 # The end of the test should interrupt or kill any remaining background
 # programs, but that should not cause the test to fail if it does not
 # care about the exit status of those programs.
-[!exec:sleep] stop
-? exec sleep 86400 &
+[exec:sleep] ? exec sleep 86400 &
+
+# It should also cancel any backgrounded builtins that respond to Context
+# cancellation.
+? sleep 86400s &
diff --git a/src/cmd/go/testdata/script/std_vendor.txt b/src/cmd/go/testdata/script/std_vendor.txt
index 6cb015f..731ee9e 100644
--- a/src/cmd/go/testdata/script/std_vendor.txt
+++ b/src/cmd/go/testdata/script/std_vendor.txt
@@ -1,6 +1,6 @@
 env GO111MODULE=off
 
-[!gc] skip
+[!compiler:gc] skip
 
 # 'go list' should report imports from _test.go in the TestImports field.
 go list -f '{{.TestImports}}'
diff --git a/src/cmd/go/testdata/script/test2json_interrupt.txt b/src/cmd/go/testdata/script/test2json_interrupt.txt
new file mode 100644
index 0000000..763c336
--- /dev/null
+++ b/src/cmd/go/testdata/script/test2json_interrupt.txt
@@ -0,0 +1,58 @@
+[short] skip 'links and runs a test binary'
+[!fuzz] skip 'tests SIGINT behavior for interrupting fuzz tests'
+[GOOS:windows] skip 'windows does not support os.Interrupt'
+
+? go test -json -fuzz FuzzInterrupt -run '^$' -parallel 1
+stdout -count=1 '"Action":"pass","Package":"example","Test":"FuzzInterrupt"'
+stdout -count=1 '"Action":"pass","Package":"example","Elapsed":'
+
+mkdir $WORK/fuzzcache
+go test -c . -fuzz=. -o example_test.exe
+? go tool test2json -p example -t ./example_test.exe -test.v -test.paniconexit0 -test.fuzzcachedir $WORK/fuzzcache -test.fuzz FuzzInterrupt -test.run '^$' -test.parallel 1
+stdout -count=1 '"Action":"pass","Package":"example","Test":"FuzzInterrupt"'
+stdout -count=1 '"Action":"pass","Package":"example","Elapsed":'
+
+-- go.mod --
+module example
+go 1.20
+-- example_test.go --
+package example_test
+
+import (
+	"fmt"
+	"os"
+	"strconv"
+	"testing"
+	"strings"
+	"time"
+)
+
+func FuzzInterrupt(f *testing.F) {
+	pids := os.Getenv("GO_TEST_INTERRUPT_PIDS")
+	if pids == "" {
+		// This is the main test process.
+		// Set the environment variable for fuzz workers.
+		pid := os.Getpid()
+		ppid := os.Getppid()
+		os.Setenv("GO_TEST_INTERRUPT_PIDS", fmt.Sprintf("%d,%d", ppid, pid))
+	}
+
+	sentInterrupt := false
+	f.Fuzz(func(t *testing.T, orig string) {
+		if !sentInterrupt {
+			// Simulate a ctrl-C on the keyboard by sending SIGINT
+			// to the main test process and its parent.
+			for _, pid := range strings.Split(pids, ",") {
+				i, err := strconv.Atoi(pid)
+				if err != nil {
+					t.Fatal(err)
+				}
+				if p, err := os.FindProcess(i); err == nil {
+					p.Signal(os.Interrupt)
+					sentInterrupt = true // Only send interrupts once.
+				}
+			}
+		}
+		time.Sleep(1 * time.Millisecond)  // Delay the fuzzer a bit to avoid wasting CPU.
+	})
+}
diff --git a/src/cmd/go/testdata/script/test_buildvcs.txt b/src/cmd/go/testdata/script/test_buildvcs.txt
index a669966..db844f8 100644
--- a/src/cmd/go/testdata/script/test_buildvcs.txt
+++ b/src/cmd/go/testdata/script/test_buildvcs.txt
@@ -3,16 +3,20 @@
 # test binaries are almost never distributed to users.)
 
 [short] skip
-[!exec:git] skip
-
-env GOFLAGS=-buildvcs  # override default -buildvcs=auto in GOFLAGS, as a user might
+[!git] skip
 
 exec git init
 
-# The test binaries should not have VCS settings stamped.
+# The test binaries should not have VCS settings stamped by default.
 # (The test itself verifies that.)
 go test . ./testonly
 
+# However, setting -buildvcs explicitly should override that and
+# stamp anyway (https://go.dev/issue/52648).
+go test -buildvcs -c -o ./testonly.exe ./testonly
+! exec ./testonly.exe
+stdout 'unexpected VCS setting: vcs\.modified=true'
+
 
 # Remove 'git' from $PATH. The test should still build.
 # This ensures that we aren't loading VCS metadata that
@@ -26,11 +30,11 @@
 
 # When listing a main package, in general we need its VCS metadata to determine
 # the .Stale and .StaleReason fields.
-! go list .
+! go list -buildvcs=true .
 stderr '^go: missing Git command\. See https://golang\.org/s/gogetcmd\nerror obtaining VCS status: .*\n\tUse -buildvcs=false to disable VCS stamping.'
 
 # Adding the -test flag should be strictly additive — it should not suppress the error.
-! go list -test .
+! go list -buildvcs=true -test .
 stderr '^go: missing Git command\. See https://golang\.org/s/gogetcmd\nerror obtaining VCS status: .*\n\tUse -buildvcs=false to disable VCS stamping.'
 
 # Adding the suggested flag should suppress the error.
@@ -38,13 +42,19 @@
 ! stderr .
 
 
-# Since the ./testonly package can't produce an actual binary, we shouldn't
-# invoke a VCS tool to compute a build stamp when listing it.
+# Since the ./testonly package doesn't itself produce an actual binary, we shouldn't
+# invoke a VCS tool to compute a build stamp by default when listing it.
 go list ./testonly
 ! stderr .
 go list -test ./testonly
 ! stderr .
 
+# Again, setting -buildvcs explicitly should force the use of the VCS tool.
+! go list -buildvcs ./testonly
+stderr '^go: missing Git command\. See https://golang\.org/s/gogetcmd\nerror obtaining VCS status: .*\n\tUse -buildvcs=false to disable VCS stamping.'
+! go list -buildvcs -test ./testonly
+stderr '^go: missing Git command\. See https://golang\.org/s/gogetcmd\nerror obtaining VCS status: .*\n\tUse -buildvcs=false to disable VCS stamping.'
+
 
 -- go.mod --
 module example
diff --git a/src/cmd/go/testdata/script/test_chatty_parallel_fail.txt b/src/cmd/go/testdata/script/test_chatty_parallel_fail.txt
index f8faa93..62f97db 100644
--- a/src/cmd/go/testdata/script/test_chatty_parallel_fail.txt
+++ b/src/cmd/go/testdata/script/test_chatty_parallel_fail.txt
@@ -1,17 +1,21 @@
-# Run parallel chatty tests. Assert on CONT lines. This test makes sure that
-# multiple parallel outputs have the appropriate CONT lines between them.
+# Run parallel chatty tests.
+# Check that multiple parallel outputs continue running.
 ! go test -parallel 3 chatty_parallel_test.go -v
 
-stdout -count=1 '^=== CONT  TestChattyParallel/sub-0\n    chatty_parallel_test.go:38: error from sub-0$'
-stdout -count=1 '^=== CONT  TestChattyParallel/sub-1\n    chatty_parallel_test.go:38: error from sub-1$'
-stdout -count=1 '^=== CONT  TestChattyParallel/sub-2\n    chatty_parallel_test.go:38: error from sub-2$'
+stdout -count=1 '^=== CONT  TestChattyParallel/sub-0'
+stdout -count=1 '^=== CONT  TestChattyParallel/sub-1'
+stdout -count=1 '^=== CONT  TestChattyParallel/sub-2'
 
-# Run parallel chatty tests with -json. Assert on CONT lines as above - make
-# sure there are CONT lines before each output line.
+stdout -count=1 '^=== (CONT|NAME)  TestChattyParallel/sub-0\n    chatty_parallel_test.go:38: error from sub-0$'
+stdout -count=1 '^=== (CONT|NAME)  TestChattyParallel/sub-1\n    chatty_parallel_test.go:38: error from sub-1$'
+stdout -count=1 '^=== (CONT|NAME)  TestChattyParallel/sub-2\n    chatty_parallel_test.go:38: error from sub-2$'
+
+# Run parallel chatty tests with -json.
+# Check that each output is attributed to the right test.
 ! go test -json -parallel 3 chatty_parallel_test.go -v
-stdout -count=1 '{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-0","Output":"=== CONT  TestChattyParallel/sub-0\\n"}\n{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-0","Output":"    chatty_parallel_test.go:38: error from sub-0\\n"}'
-stdout -count=1 '{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-1","Output":"=== CONT  TestChattyParallel/sub-1\\n"}\n{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-1","Output":"    chatty_parallel_test.go:38: error from sub-1\\n"}'
-stdout -count=1 '{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-2","Output":"=== CONT  TestChattyParallel/sub-2\\n"}\n{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-2","Output":"    chatty_parallel_test.go:38: error from sub-2\\n"}'
+stdout -count=1 '"Test":"TestChattyParallel/sub-0","Output":"    chatty_parallel_test.go:38: error from sub-0\\n"'
+stdout -count=1 '"Test":"TestChattyParallel/sub-1","Output":"    chatty_parallel_test.go:38: error from sub-1\\n"'
+stdout -count=1 '"Test":"TestChattyParallel/sub-2","Output":"    chatty_parallel_test.go:38: error from sub-2\\n"'
 
 -- chatty_parallel_test.go --
 package chatty_parallel_test
diff --git a/src/cmd/go/testdata/script/test_chatty_parallel_success.txt b/src/cmd/go/testdata/script/test_chatty_parallel_success.txt
index 63034fa..01653ac 100644
--- a/src/cmd/go/testdata/script/test_chatty_parallel_success.txt
+++ b/src/cmd/go/testdata/script/test_chatty_parallel_success.txt
@@ -1,16 +1,16 @@
-# Run parallel chatty tests. Assert on CONT lines. This test makes sure that
-# multiple parallel outputs have the appropriate CONT lines between them.
+# Run parallel chatty tests. Assert on CONT or NAME lines. This test makes sure that
+# multiple parallel outputs have the appropriate test name lines between them.
 go test -parallel 3 chatty_parallel_test.go -v
-stdout -count=2 '^=== CONT  TestChattyParallel/sub-0\n    chatty_parallel_test.go:32: this is sub-0$'
-stdout -count=2 '^=== CONT  TestChattyParallel/sub-1\n    chatty_parallel_test.go:32: this is sub-1$'
-stdout -count=2 '^=== CONT  TestChattyParallel/sub-2\n    chatty_parallel_test.go:32: this is sub-2$'
+stdout -count=2 '^=== (CONT|NAME)  TestChattyParallel/sub-0\n    chatty_parallel_test.go:32: this is sub-0$'
+stdout -count=2 '^=== (CONT|NAME)  TestChattyParallel/sub-1\n    chatty_parallel_test.go:32: this is sub-1$'
+stdout -count=2 '^=== (CONT|NAME)  TestChattyParallel/sub-2\n    chatty_parallel_test.go:32: this is sub-2$'
 
-# Run parallel chatty tests with -json. Assert on CONT lines as above - make
-# sure there are CONT lines before each output line.
+# Run parallel chatty tests with -json.
+# Assert test2json has properly attributed output.
 go test -json -parallel 3 chatty_parallel_test.go -v
-stdout -count=2 '{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-0","Output":"=== CONT  TestChattyParallel/sub-0\\n"}\n{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-0","Output":"    chatty_parallel_test.go:32: this is sub-0\\n"}'
-stdout -count=2 '{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-1","Output":"=== CONT  TestChattyParallel/sub-1\\n"}\n{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-1","Output":"    chatty_parallel_test.go:32: this is sub-1\\n"}'
-stdout -count=2 '{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-2","Output":"=== CONT  TestChattyParallel/sub-2\\n"}\n{"Time":"[0-9TZ:.+-]{20,40}","Action":"output","Package":"command-line-arguments","Test":"TestChattyParallel/sub-2","Output":"    chatty_parallel_test.go:32: this is sub-2\\n"}'
+stdout -count=2 '"Test":"TestChattyParallel/sub-0","Output":"    chatty_parallel_test.go:32: this is sub-0\\n"'
+stdout -count=2 '"Test":"TestChattyParallel/sub-1","Output":"    chatty_parallel_test.go:32: this is sub-1\\n"'
+stdout -count=2 '"Test":"TestChattyParallel/sub-2","Output":"    chatty_parallel_test.go:32: this is sub-2\\n"'
 
 -- chatty_parallel_test.go --
 package chatty_parallel_test
diff --git a/src/cmd/go/testdata/script/test_chatty_parallel_success_run.txt b/src/cmd/go/testdata/script/test_chatty_parallel_success_run.txt
index 4e0f239..1d4b6d6 100644
--- a/src/cmd/go/testdata/script/test_chatty_parallel_success_run.txt
+++ b/src/cmd/go/testdata/script/test_chatty_parallel_success_run.txt
@@ -1,8 +1,8 @@
-# Run parallel chatty tests. Assert on CONT lines. This test makes sure that
+# Run parallel chatty tests. Assert on CONT or NAME lines. This test makes sure that
 # multiple parallel outputs have the appropriate CONT lines between them.
 go test -parallel 3 chatty_parallel -v
 
-stdout '=== RUN   TestInterruptor/interruption\n=== CONT  TestLog\n    chatty_parallel_test.go:28: this is the second TestLog log\n--- PASS: Test(Log|Interruptor) \([0-9.]{4}s\)'
+stdout '=== RUN   TestInterruptor/interruption\n=== (CONT|NAME)  TestLog\n    chatty_parallel_test.go:28: this is the second TestLog log\n--- PASS: Test(Log|Interruptor) \([0-9.]{4}s\)'
 
 -- go.mod --
 module chatty_parallel
diff --git a/src/cmd/go/testdata/script/test_cleanup_failnow.txt b/src/cmd/go/testdata/script/test_cleanup_failnow.txt
index 0737a93..0aba8c7 100644
--- a/src/cmd/go/testdata/script/test_cleanup_failnow.txt
+++ b/src/cmd/go/testdata/script/test_cleanup_failnow.txt
@@ -2,11 +2,10 @@
 [short] skip
 
 # This test could fail if the testing package does not wait until
-# a panicking test does the panic. Turn off multithreading, GC, and
-# async preemption to increase the probability of such a failure.
+# a panicking test does the panic. Turn off multithreading and GC
+# to increase the probability of such a failure.
 env GOMAXPROCS=1
 env GOGC=off
-env GODEBUG=asyncpreempt=off
 
 # If the test exits with 'no tests to run', it means the testing package
 # implementation is incorrect and does not wait until a test panic.
diff --git a/src/cmd/go/testdata/script/test_flag.txt b/src/cmd/go/testdata/script/test_flag.txt
index d168cfe..6ef4529 100644
--- a/src/cmd/go/testdata/script/test_flag.txt
+++ b/src/cmd/go/testdata/script/test_flag.txt
@@ -6,14 +6,12 @@
 # Using a custom flag mixed with regular 'go test' flags should be OK.
 go test -count=1 -custom -args -v=7
 
-# However, it should be an error to use custom flags when -i or -c are used,
+# However, it should be an error to use custom flags when -c is used,
 # since we know for sure that no test binary will run at all.
-! go test -i -custom
-stderr '^go: unknown flag -custom cannot be used with -i$'
 ! go test -c -custom
 stderr '^go: unknown flag -custom cannot be used with -c$'
 
-# The same should apply even if -c or -i come after a custom flag.
+# The same should apply even if -c comes after a custom flag.
 ! go test -custom -c
 stderr '^go: unknown flag -custom cannot be used with -c$'
 
diff --git a/src/cmd/go/testdata/script/test_fuzz_cache.txt b/src/cmd/go/testdata/script/test_fuzz_cache.txt
index 19fb764..752ab3a 100644
--- a/src/cmd/go/testdata/script/test_fuzz_cache.txt
+++ b/src/cmd/go/testdata/script/test_fuzz_cache.txt
@@ -37,6 +37,9 @@
 stdout 'new interesting: 0'
 stdout 'total: 1'
 
+! go clean -fuzzcache example.com/y
+stderr 'go: clean -fuzzcache cannot be used with package arguments'
+
 -- go.mod --
 module example.com/y
 
diff --git a/src/cmd/go/testdata/script/test_fuzz_mutate_crash.txt b/src/cmd/go/testdata/script/test_fuzz_mutate_crash.txt
index d2ded27..aa4aa85 100644
--- a/src/cmd/go/testdata/script/test_fuzz_mutate_crash.txt
+++ b/src/cmd/go/testdata/script/test_fuzz_mutate_crash.txt
@@ -20,7 +20,7 @@
 # Now, the failing bytes should have been added to the seed corpus for
 # the target, and should fail when run without fuzzing.
 ! go test
-stdout 'FuzzWithBug/[a-f0-9]{64}'
+stdout 'FuzzWithBug/[a-f0-9]{16}'
 stdout 'this input caused a crash!'
 
 ! go test -run=FuzzWithNilPanic -fuzz=FuzzWithNilPanic -fuzztime=100x -fuzzminimizetime=1000x
@@ -315,7 +315,7 @@
 	}
 	// The hash of the bytes in the file should match the filename.
 	h := []byte(fmt.Sprintf("%x", sha256.Sum256(contents)))
-	if !bytes.Equal([]byte(fname), h) {
+	if !bytes.HasPrefix(h, []byte(fname)) {
 		fmt.Fprintf(os.Stderr, "hash of bytes %q does not match filename %q\n", h, fname)
 		os.Exit(1)
 	}
diff --git a/src/cmd/go/testdata/script/test_fuzz_mutator_repeat.txt b/src/cmd/go/testdata/script/test_fuzz_mutator_repeat.txt
index 3764dcb..b413f93 100644
--- a/src/cmd/go/testdata/script/test_fuzz_mutator_repeat.txt
+++ b/src/cmd/go/testdata/script/test_fuzz_mutator_repeat.txt
@@ -1,5 +1,5 @@
 # TODO(jayconrod): support shared memory on more platforms.
-[!darwin] [!linux] [!windows] skip
+[!GOOS:darwin] [!GOOS:linux] [!GOOS:windows] skip
 
 # Verify that the fuzzing engine records the actual crashing input, even when
 # a worker process terminates without communicating the crashing input back
diff --git a/src/cmd/go/testdata/script/test_fuzz_non_crash_signal.txt b/src/cmd/go/testdata/script/test_fuzz_non_crash_signal.txt
index 1051292..6f1eeab 100644
--- a/src/cmd/go/testdata/script/test_fuzz_non_crash_signal.txt
+++ b/src/cmd/go/testdata/script/test_fuzz_non_crash_signal.txt
@@ -1,6 +1,6 @@
 # NOTE: this test is skipped on Windows, since there's no concept of signals.
 # When a process terminates another process, it provides an exit code.
-[windows] skip
+[GOOS:windows] skip
 [!fuzz] skip
 [short] skip
 
diff --git a/src/cmd/go/testdata/script/test_goroot_PATH.txt b/src/cmd/go/testdata/script/test_goroot_PATH.txt
index f49ec10..a6278ca 100644
--- a/src/cmd/go/testdata/script/test_goroot_PATH.txt
+++ b/src/cmd/go/testdata/script/test_goroot_PATH.txt
@@ -4,12 +4,12 @@
 
 [short] skip
 
-[!plan9] env PATH=
-[plan9] env path=
+[!GOOS:plan9] env PATH=
+[GOOS:plan9] env path=
 go test .
 
-[!plan9] env PATH=$WORK${/}bin
-[plan9] env path=$WORK${/}bin
+[!GOOS:plan9] env PATH=$WORK${/}bin
+[GOOS:plan9] env path=$WORK${/}bin
 go test .
 
 -- go.mod --
diff --git a/src/cmd/go/testdata/script/test_json.txt b/src/cmd/go/testdata/script/test_json.txt
index cd5b0b9..6207c2e 100644
--- a/src/cmd/go/testdata/script/test_json.txt
+++ b/src/cmd/go/testdata/script/test_json.txt
@@ -1,4 +1,4 @@
-[gccgo] skip # gccgo does not have standard packages
+[compiler:gccgo] skip # gccgo does not have standard packages
 [short] skip
 
 env GOCACHE=$WORK/tmp
@@ -11,16 +11,22 @@
 
 # Check errors for run action
 stdout '"Package":"errors"'
+stdout '"Action":"start","Package":"errors"'
 stdout '"Action":"run","Package":"errors"'
 
 # Check m/empty/pkg for output and skip actions
+stdout '"Action":"start","Package":"m/empty/pkg"'
 stdout '"Action":"output","Package":"m/empty/pkg","Output":".*no test files'
 stdout '"Action":"skip","Package":"m/empty/pkg"'
 
 # Check skipper for output and skip actions
+stdout '"Action":"start","Package":"m/skipper"'
 stdout '"Action":"output","Package":"m/skipper","Test":"Test","Output":"--- SKIP:'
 stdout '"Action":"skip","Package":"m/skipper","Test":"Test"'
 
+# Check that starts were ordered properly.
+stdout '(?s)"Action":"start","Package":"errors".*"Action":"start","Package":"m/empty/pkg".*"Action":"start","Package":"m/skipper"'
+
 # Run go test -json on errors and check it's cached
 go test -json -short -v errors
 stdout '"Action":"output","Package":"errors","Output":".*\(cached\)'
diff --git a/src/cmd/go/testdata/script/test_json_panic_exit.txt b/src/cmd/go/testdata/script/test_json_panic_exit.txt
index d0a7991..5f1d033 100644
--- a/src/cmd/go/testdata/script/test_json_panic_exit.txt
+++ b/src/cmd/go/testdata/script/test_json_panic_exit.txt
@@ -4,7 +4,7 @@
 
 # 'go test -json' should say a test passes if it says it passes.
 go test -json ./pass
-stdout '"Action":"pass".*\n\z'
+stdout '"Action":"pass","Package":"[^"]*","Elapsed":[^"]*}\n\z'
 ! stdout '"Test":.*\n\z'
 
 # 'go test -json' should say a test passes if it exits 0 and prints nothing.
diff --git a/src/cmd/go/testdata/script/test_json_prints.txt b/src/cmd/go/testdata/script/test_json_prints.txt
new file mode 100644
index 0000000..f979998
--- /dev/null
+++ b/src/cmd/go/testdata/script/test_json_prints.txt
@@ -0,0 +1,48 @@
+go test -json
+
+stdout '"Action":"output","Package":"p","Output":"M1"}'
+stdout '"Action":"output","Package":"p","Test":"Test","Output":"=== RUN   Test\\n"}'
+stdout '"Action":"output","Package":"p","Test":"Test","Output":"T1"}'
+stdout '"Action":"output","Package":"p","Test":"Test/Sub1","Output":"=== RUN   Test/Sub1\\n"}'
+stdout '"Action":"output","Package":"p","Test":"Test/Sub1","Output":"Sub1    x_test.go:19: SubLog1\\n"}'
+stdout '"Action":"output","Package":"p","Test":"Test/Sub1","Output":"Sub2"}'
+stdout '"Action":"output","Package":"p","Test":"Test/Sub1","Output":"--- PASS: Test/Sub1 \([\d.]+s\)\\n"}'
+stdout '"Action":"pass","Package":"p","Test":"Test/Sub1","Elapsed"'
+stdout '"Action":"output","Package":"p","Test":"Test/Sub3","Output":"foo bar"}'
+stdout '"Action":"output","Package":"p","Test":"Test/Sub3","Output":"baz\\n"}'
+stdout '"Action":"output","Package":"p","Test":"Test","Output":"T2"}'
+stdout '"Action":"output","Package":"p","Test":"Test","Output":"--- PASS: Test \([\d.]+s\)\\n"}'
+stdout '"Action":"pass","Package":"p","Test":"Test","Elapsed"'
+stdout '"Action":"output","Package":"p","Output":"M2ok  \\tp\\t[\d.]+s\\n"}'
+stdout '"Action":"pass","Package":"p","Elapsed"'
+
+-- go.mod --
+module p
+
+-- x_test.go --
+package p
+
+import (
+	"os"
+	"testing"
+)
+
+func TestMain(m *testing.M) {
+	print("M1")
+	code := m.Run()
+	print("M2")
+	os.Exit(code)
+}
+
+func Test(t *testing.T) {
+	print("T1")
+	t.Run("Sub1", func(t *testing.T) {
+		print("Sub1")
+		t.Log("SubLog1")
+		print("Sub2")
+	})
+	t.Run("Sub3", func(t *testing.T) {
+		print("\x16foo bar\x16baz\n")
+	})
+	print("T2")
+}
diff --git a/src/cmd/go/testdata/script/test_json_timeout.txt b/src/cmd/go/testdata/script/test_json_timeout.txt
new file mode 100644
index 0000000..0a2329b
--- /dev/null
+++ b/src/cmd/go/testdata/script/test_json_timeout.txt
@@ -0,0 +1,19 @@
+! go test -json -timeout=1ms
+
+stdout '"Action":"output","Package":"p","Output":"FAIL\\tp\\t'
+stdout '"Action":"fail","Package":"p","Elapsed":'
+
+-- go.mod --
+module p
+
+-- x_test.go --
+package p
+
+import (
+	"testing"
+	"time"
+)
+
+func Test(t *testing.T) {
+	time.Sleep(1*time.Hour)
+}
diff --git a/src/cmd/go/testdata/script/test_ppc64_linker_funcs.txt b/src/cmd/go/testdata/script/test_ppc64_linker_funcs.txt
index a33f9df..735b5dc 100644
--- a/src/cmd/go/testdata/script/test_ppc64_linker_funcs.txt
+++ b/src/cmd/go/testdata/script/test_ppc64_linker_funcs.txt
@@ -5,10 +5,10 @@
 # -Os option.
 #
 # Verifies golang.org/issue/52366 for linux/ppc64le
-[!linux] skip
-[!gc] skip
+[!GOOS:linux] skip
+[!compiler:gc] skip
 [!cgo] skip
-[!ppc64le] skip
+[!GOARCH:ppc64le] skip
 
 go build -ldflags='-linkmode=internal'
 exec ./abitest
diff --git a/src/cmd/go/testdata/script/test_ppc64le_cgo_inline_plt.txt b/src/cmd/go/testdata/script/test_ppc64le_cgo_inline_plt.txt
new file mode 100644
index 0000000..ef9ff03
--- /dev/null
+++ b/src/cmd/go/testdata/script/test_ppc64le_cgo_inline_plt.txt
@@ -0,0 +1,38 @@
+# Verify the linker will correctly resolve
+# ppc64le objects compiled with gcc's -fno-plt
+# option. This inlines PLT calls, and generates
+# additional reloc types which the internal linker
+# should handle.
+#
+# Verifies golang.org/issue/53345
+#
+# Note, older gcc/clang may accept this option, but
+# ignore it if binutils does not support the relocs.
+[!compiler:gc] skip
+[!cgo] skip
+[!GOARCH:ppc64le] skip
+
+env CGO_CFLAGS='-fno-plt -O2 -g'
+
+go build -ldflags='-linkmode=internal'
+exec ./noplttest
+stdout helloworld
+
+-- go.mod --
+module noplttest
+
+-- noplttest.go --
+package main
+
+/*
+#include <stdio.h>
+void helloworld(void) {
+   printf("helloworld\n");
+   fflush(stdout);
+}
+*/
+import "C"
+
+func main() {
+	C.helloworld()
+}
diff --git a/src/cmd/go/testdata/script/test_profile.txt b/src/cmd/go/testdata/script/test_profile.txt
index 4bfa2cc..9110706 100644
--- a/src/cmd/go/testdata/script/test_profile.txt
+++ b/src/cmd/go/testdata/script/test_profile.txt
@@ -1,4 +1,4 @@
-[gccgo] skip 'gccgo has no standard packages'
+[compiler:gccgo] skip 'gccgo has no standard packages'
 [short] skip
 
 # Check go test -cpuprofile creates errors.test
diff --git a/src/cmd/go/testdata/script/test_race_install.txt b/src/cmd/go/testdata/script/test_race_install.txt
index a1d47a7..918d7e9 100644
--- a/src/cmd/go/testdata/script/test_race_install.txt
+++ b/src/cmd/go/testdata/script/test_race_install.txt
@@ -4,15 +4,9 @@
 mkdir $WORKDIR/tmp/pkg
 go install -race -pkgdir=$WORKDIR/tmp/pkg std
 
-# Make sure go test -i -race doesn't rebuild cached packages
-go test -race -pkgdir=$WORKDIR/tmp/pkg -i -v empty/pkg
-cmp stderr stderr.txt
-
 -- go.mod --
 module empty
 
 go 1.16
 -- pkg/pkg.go --
 package p
--- stderr.txt --
-go: -i flag is deprecated
diff --git a/src/cmd/go/testdata/script/test_race_tag.txt b/src/cmd/go/testdata/script/test_race_tag.txt
new file mode 100644
index 0000000..4b18ebc
--- /dev/null
+++ b/src/cmd/go/testdata/script/test_race_tag.txt
@@ -0,0 +1,29 @@
+# Tests Issue #54468
+
+[short] skip 'links a test binary'
+[!race] skip
+
+go mod tidy
+go test -c -o=$devnull -race .
+
+! stderr 'cannot find package'
+
+-- go.mod --
+module testrace
+
+go 1.18
+
+require rsc.io/sampler v1.0.0
+-- race_test.go --
+//go:build race
+
+package testrace
+
+import (
+        "testing"
+
+        _ "rsc.io/sampler"
+)
+
+func TestRaceTag(t *testing.T) {
+}
diff --git a/src/cmd/go/testdata/script/test_relative_import_dash_i.txt b/src/cmd/go/testdata/script/test_relative_import_dash_i.txt
deleted file mode 100644
index b2716d8..0000000
--- a/src/cmd/go/testdata/script/test_relative_import_dash_i.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-# Relative imports in go test -i
-env GO111MODULE=off # relative import not supported in module mode
-
-# Run tests outside GOPATH.
-env GOPATH=$WORK/tmp
-
-# Check that it's safe to pass -i (which installs dependencies in $GOPATH/pkg) to go test.
-! stale runtime # don't let test -i overwrite runtime
-go test -i ./testimport
-
--- testimport/p.go --
-package p
-
-func F() int { return 1 }
--- testimport/p1/p1.go --
-package p1
-
-func F() int { return 1 }
--- testimport/p_test.go --
-package p
-
-import (
-	"./p1"
-
-	"testing"
-)
-
-func TestF(t *testing.T) {
-	if F() != p1.F() {
-		t.Fatal(F())
-	}
-}
diff --git a/src/cmd/go/testdata/script/test_skip.txt b/src/cmd/go/testdata/script/test_skip.txt
new file mode 100644
index 0000000..94d20b9
--- /dev/null
+++ b/src/cmd/go/testdata/script/test_skip.txt
@@ -0,0 +1,34 @@
+go test -v -run Test -skip T skip_test.go
+! stdout RUN
+stdout '^ok.*\[no tests to run\]'
+
+go test -v -skip T skip_test.go
+! stdout RUN
+
+go test -v -skip 1 skip_test.go
+! stdout Test1
+stdout RUN.*Test2
+stdout RUN.*Test2/3
+
+go test -v -skip 2/3 skip_test.go
+stdout RUN.*Test1
+stdout RUN.*Test2
+! stdout Test2/3
+
+go test -v -skip 2/4 skip_test.go
+stdout RUN.*Test1
+stdout RUN.*Test2
+stdout RUN.*Test2/3
+
+
+-- skip_test.go --
+package skip_test
+
+import "testing"
+
+func Test1(t *testing.T) {
+}
+
+func Test2(t *testing.T) {
+	t.Run("3", func(t *testing.T) {})
+}
diff --git a/src/cmd/go/testdata/script/toolexec.txt b/src/cmd/go/testdata/script/toolexec.txt
index bb86467..20a5968 100644
--- a/src/cmd/go/testdata/script/toolexec.txt
+++ b/src/cmd/go/testdata/script/toolexec.txt
@@ -17,7 +17,7 @@
 # Finally, note that asm and cgo are run twice.
 
 go build -toolexec=$PWD/mytool
-[amd64] stderr -count=2 '^asm'${GOEXE}' TOOLEXEC_IMPORTPATH="test/main/withasm"$'
+[GOARCH:amd64] stderr -count=2 '^asm'${GOEXE}' TOOLEXEC_IMPORTPATH="test/main/withasm"$'
 stderr -count=1 '^compile'${GOEXE}' TOOLEXEC_IMPORTPATH="test/main/withasm"$'
 [cgo] stderr -count=2 '^cgo'${GOEXE}' TOOLEXEC_IMPORTPATH="test/main/withcgo"$'
 [cgo] stderr -count=1 '^compile'${GOEXE}' TOOLEXEC_IMPORTPATH="test/main/withcgo"$'
diff --git a/src/cmd/go/testdata/script/tooltags.txt b/src/cmd/go/testdata/script/tooltags.txt
new file mode 100644
index 0000000..3076185
--- /dev/null
+++ b/src/cmd/go/testdata/script/tooltags.txt
@@ -0,0 +1,55 @@
+env GOARCH=amd64
+env GOAMD64=v3
+go list -f '{{context.ToolTags}}'
+stdout 'amd64.v1 amd64.v2 amd64.v3'
+
+env GOARCH=arm
+env GOARM=6
+go list -f '{{context.ToolTags}}'
+stdout 'arm.5 arm.6'
+
+env GOARCH=mips
+env GOMIPS=hardfloat
+go list -f '{{context.ToolTags}}'
+stdout 'mips.hardfloat'
+
+env GOARCH=mips64
+env GOMIPS=hardfloat
+go list -f '{{context.ToolTags}}'
+stdout 'mips64.hardfloat'
+
+env GOARCH=ppc64
+env GOPPC64=power9
+go list -f '{{context.ToolTags}}'
+stdout 'ppc64.power8 ppc64.power9'
+
+env GOARCH=ppc64
+env GOPPC64=power10
+go list -f '{{context.ToolTags}}'
+stdout 'ppc64.power8 ppc64.power9 ppc64.power10'
+
+env GOARCH=ppc64le
+env GOPPC64=power9
+go list -f '{{context.ToolTags}}'
+stdout 'ppc64le.power8 ppc64le.power9'
+
+env GOARCH=ppc64le
+env GOPPC64=power10
+go list -f '{{context.ToolTags}}'
+stdout 'ppc64le.power8 ppc64le.power9 ppc64le.power10'
+
+env GOARCH=386
+env GO386=sse2
+go list -f '{{context.ToolTags}}'
+stdout '386.sse2'
+
+env GOARCH=wasm
+env GOWASM=satconv
+go list -f '{{context.ToolTags}}'
+stdout 'wasm.satconv'
+
+-- go.mod --
+module m
+
+-- p.go --
+package p
diff --git a/src/cmd/go/testdata/script/trampoline_reuse_test.txt b/src/cmd/go/testdata/script/trampoline_reuse_test.txt
new file mode 100644
index 0000000..41e86e4
--- /dev/null
+++ b/src/cmd/go/testdata/script/trampoline_reuse_test.txt
@@ -0,0 +1,100 @@
+# Verify PPC64 does not reuse a trampoline which is too far away.
+# This tests an edge case where the direct call relocation addend should
+# be ignored when computing the distance from the direct call to the
+# already placed trampoline
+[short] skip
+[!GOARCH:ppc64] [!GOARCH:ppc64le] skip
+[GOOS:aix] skip
+
+# Note, this program does not run. Presumably, 'DWORD $0' is simpler to
+# assembly 2^26 or so times.
+#
+# We build something which should be laid out as such:
+#
+# bar.Bar
+# main.Func1
+# bar.Bar+400-tramp0
+# main.BigAsm
+# main.Func2
+# bar.Bar+400-tramp1
+#
+# bar.Bar needs to be placed far enough away to generate relocations
+# from main package calls. and main.Func1 and main.Func2 are placed
+# a bit more than the direct call limit apart, but not more than 0x400
+# bytes beyond it (to verify the reloc calc).
+
+go build
+
+-- go.mod --
+
+module foo
+
+go 1.19
+
+-- main.go --
+
+package main
+
+import "foo/bar"
+
+func Func1()
+
+func main() {
+        Func1()
+        bar.Bar2()
+}
+
+-- foo.s --
+
+TEXT main·Func1(SB),0,$0-0
+        CALL bar·Bar+0x400(SB)
+        CALL main·BigAsm(SB)
+// A trampoline will be placed here to bar.Bar
+
+// This creates a gap sufficiently large to prevent trampoline reuse
+#define NOP64 DWORD $0; DWORD $0; DWORD $0; DWORD $0; DWORD $0; DWORD $0; DWORD $0; DWORD $0;
+#define NOP256 NOP64 NOP64 NOP64 NOP64
+#define NOP2S10 NOP256 NOP256 NOP256 NOP256
+#define NOP2S12 NOP2S10 NOP2S10 NOP2S10 NOP2S10
+#define NOP2S14 NOP2S12 NOP2S12 NOP2S12 NOP2S12
+#define NOP2S16 NOP2S14 NOP2S14 NOP2S14 NOP2S14
+#define NOP2S18 NOP2S16 NOP2S16 NOP2S16 NOP2S16
+#define NOP2S20 NOP2S18 NOP2S18 NOP2S18 NOP2S18
+#define NOP2S22 NOP2S20 NOP2S20 NOP2S20 NOP2S20
+#define NOP2S24 NOP2S22 NOP2S22 NOP2S22 NOP2S22
+#define BIGNOP NOP2S24 NOP2S24
+TEXT main·BigAsm(SB),0,$0-0
+        // Fill to the direct call limit so Func2 must generate a new trampoline.
+        // As the implicit trampoline above is just barely unreachable.
+        BIGNOP
+        MOVD $main·Func2(SB), R3
+
+TEXT main·Func2(SB),0,$0-0
+        CALL bar·Bar+0x400(SB)
+// Another trampoline should be placed here.
+
+-- bar/bar.s --
+
+#define NOP64 DWORD $0; DWORD $0; DWORD $0; DWORD $0; DWORD $0; DWORD $0; DWORD $0; DWORD $0;
+#define NOP256 NOP64 NOP64 NOP64 NOP64
+#define NOP2S10 NOP256 NOP256 NOP256 NOP256
+#define NOP2S12 NOP2S10 NOP2S10 NOP2S10 NOP2S10
+#define NOP2S14 NOP2S12 NOP2S12 NOP2S12 NOP2S12
+#define NOP2S16 NOP2S14 NOP2S14 NOP2S14 NOP2S14
+#define NOP2S18 NOP2S16 NOP2S16 NOP2S16 NOP2S16
+#define NOP2S20 NOP2S18 NOP2S18 NOP2S18 NOP2S18
+#define NOP2S22 NOP2S20 NOP2S20 NOP2S20 NOP2S20
+#define NOP2S24 NOP2S22 NOP2S22 NOP2S22 NOP2S22
+#define BIGNOP NOP2S24 NOP2S24 NOP2S10
+// A very big not very interesting function.
+TEXT bar·Bar(SB),0,$0-0
+        BIGNOP
+
+-- bar/bar.go --
+
+package bar
+
+func Bar()
+
+func Bar2() {
+}
diff --git a/src/cmd/go/testdata/script/vendor_complex.txt b/src/cmd/go/testdata/script/vendor_complex.txt
index 9ca94e7..290efdb 100644
--- a/src/cmd/go/testdata/script/vendor_complex.txt
+++ b/src/cmd/go/testdata/script/vendor_complex.txt
@@ -2,7 +2,7 @@
 
 # smoke test for complex build configuration
 go build -o complex.exe complex
-[exec:gccgo] go build -compiler=gccgo -o complex.exe complex
+[!cross] [exec:gccgo] go build -compiler=gccgo -o complex.exe complex
 
 -- complex/main.go --
 package main
diff --git a/src/cmd/go/testdata/script/vendor_gopath_issue11409.txt b/src/cmd/go/testdata/script/vendor_gopath_issue11409.txt
index da52f9a..c85f674 100644
--- a/src/cmd/go/testdata/script/vendor_gopath_issue11409.txt
+++ b/src/cmd/go/testdata/script/vendor_gopath_issue11409.txt
@@ -1,4 +1,4 @@
-[!windows] [short] stop 'this test only applies to Windows'
+[!GOOS:windows] [short] stop 'this test only applies to Windows'
 env GO111MODULE=off
 
 go build run_go.go
diff --git a/src/cmd/go/testdata/script/vendor_internal.txt b/src/cmd/go/testdata/script/vendor_internal.txt
new file mode 100644
index 0000000..4c0f1fa
--- /dev/null
+++ b/src/cmd/go/testdata/script/vendor_internal.txt
@@ -0,0 +1,16 @@
+go build ./vendor/foo.com/internal/bar/a
+
+-- go.mod --
+module example.com/x
+go 1.19
+
+require "foo.com/internal/bar" v1.0.0
+-- vendor/modules.txt --
+# foo.com/internal/bar v1.0.0
+## explicit
+foo.com/internal/bar/a
+-- vendor/foo.com/internal/bar/a/a.go --
+package a
+import _ "foo.com/internal/bar/b"
+-- vendor/foo.com/internal/bar/b/b.go --
+package b
\ No newline at end of file
diff --git a/src/cmd/go/testdata/script/vendor_list_issue11977.txt b/src/cmd/go/testdata/script/vendor_list_issue11977.txt
index cdab33c..35c82c7 100644
--- a/src/cmd/go/testdata/script/vendor_list_issue11977.txt
+++ b/src/cmd/go/testdata/script/vendor_list_issue11977.txt
@@ -1,5 +1,5 @@
 [!net] skip
-[!exec:git] skip
+[!git] skip
 env GO111MODULE=off
 
 go get github.com/rsc/go-get-issue-11864
diff --git a/src/cmd/go/testdata/script/vendor_outside_module.txt b/src/cmd/go/testdata/script/vendor_outside_module.txt
new file mode 100644
index 0000000..3ad4579
--- /dev/null
+++ b/src/cmd/go/testdata/script/vendor_outside_module.txt
@@ -0,0 +1,36 @@
+# baz.go (importing just fmt) works with -mod=mod,  -mod=vendor.
+go build -x -mod=mod my-module/vendor/example.com/another-module/foo/bar/baz.go
+go build -x -mod=readonly my-module/vendor/example.com/another-module/foo/bar/baz.go
+go build -x -mod=vendor my-module/vendor/example.com/another-module/foo/bar/baz.go
+
+# baz_with_outside_dep.go (with a non-std dependency) works with -mod=mod
+# but not with -mod=readonly and -mod=vendor.
+go build -x -mod=mod my-module/vendor/example.com/another-module/foo/bar/baz_with_outside_dep.go
+! go build -x -mod=readonly my-module/vendor/example.com/another-module/foo/bar/baz_with_outside_dep.go
+stderr 'no required module provides package rsc.io/quote'
+! go build -x -mod=vendor my-module/vendor/example.com/another-module/foo/bar/baz_with_outside_dep.go
+stderr 'no required module provides package rsc.io/quote'
+
+-- my-module/go.mod --
+module example.com/my-module
+
+go 1.20
+-- my-module/vendor/example.com/another-module/foo/bar/baz.go --
+package main
+
+import "fmt"
+
+func main() {
+	fmt.Println("hello, world.")
+}
+-- my-module/vendor/example.com/another-module/foo/bar/baz_with_outside_dep.go --
+package main
+
+import (
+    "fmt"
+    "rsc.io/quote"
+)
+
+func main() {
+	fmt.Println(quote.Hello())
+}
diff --git a/src/cmd/go/testdata/script/vendor_test_issue11864.txt b/src/cmd/go/testdata/script/vendor_test_issue11864.txt
index cfb43bf..ff179cb 100644
--- a/src/cmd/go/testdata/script/vendor_test_issue11864.txt
+++ b/src/cmd/go/testdata/script/vendor_test_issue11864.txt
@@ -1,17 +1,9 @@
 [!net] skip
-[!exec:git] skip
+[!git] skip
 env GO111MODULE=off
 
 go get github.com/rsc/go-get-issue-11864
 
-# build -i should work
-go build -i github.com/rsc/go-get-issue-11864
-go build -i github.com/rsc/go-get-issue-11864/t
-
-# test -i should work like build -i (golang.org/issue/11988)
-go test -i github.com/rsc/go-get-issue-11864
-go test -i github.com/rsc/go-get-issue-11864/t
-
 # test should work too
 go test github.com/rsc/go-get-issue-11864
 go test github.com/rsc/go-get-issue-11864/t
diff --git a/src/cmd/go/testdata/script/vendor_test_issue14613.txt b/src/cmd/go/testdata/script/vendor_test_issue14613.txt
index cfd7e58..7822dee 100644
--- a/src/cmd/go/testdata/script/vendor_test_issue14613.txt
+++ b/src/cmd/go/testdata/script/vendor_test_issue14613.txt
@@ -1,22 +1,18 @@
 [!net] skip
-[!exec:git] skip
+[!git] skip
 env GO111MODULE=off
 
 cd $GOPATH
 
 go get github.com/clsung/go-vendor-issue-14613
-go build -o $WORK/a.out -i github.com/clsung/go-vendor-issue-14613
 
 # test folder should work
-go test -i github.com/clsung/go-vendor-issue-14613
 go test github.com/clsung/go-vendor-issue-14613
 
 # test with specified _test.go should work too
 cd $GOPATH/src
-go test -i github.com/clsung/go-vendor-issue-14613/vendor_test.go
 go test github.com/clsung/go-vendor-issue-14613/vendor_test.go
 
 # test with imported and not used
-go test -i github.com/clsung/go-vendor-issue-14613/vendor/mylibtesttest/myapp/myapp_test.go
 ! go test github.com/clsung/go-vendor-issue-14613/vendor/mylibtesttest/myapp/myapp_test.go
 stderr 'imported and not used'
diff --git a/src/cmd/go/testdata/script/version.txt b/src/cmd/go/testdata/script/version.txt
index f7ead39..0a2ac1e 100644
--- a/src/cmd/go/testdata/script/version.txt
+++ b/src/cmd/go/testdata/script/version.txt
@@ -9,6 +9,19 @@
 ! go version -v
 stderr 'with arguments'
 
+# Check that 'go version' succeed even when it does not contain Go build info.
+# It should print an error if the file has a known Go binary extension.
+#
+go version empty.txt
+! stdout .
+! stderr .
+go version empty.exe
+stderr 'could not read Go build info'
+go version empty.so
+stderr 'could not read Go build info'
+go version empty.dll
+stderr 'could not read Go build info'
+
 # Neither of the two flags above should be an issue via GOFLAGS.
 env GOFLAGS='-m -v'
 go version
@@ -32,15 +45,17 @@
 go version fortune.exe
 stdout '^fortune.exe: .+'
 go version -m fortune.exe
+stdout -buildmode=exe
 stdout '^\tpath\trsc.io/fortune'
 stdout '^\tmod\trsc.io/fortune\tv1.0.0'
 
 # Check the build info of a binary built from $GOROOT/src/cmd
 go build -o test2json.exe cmd/test2json
 go version -m test2json.exe
+stdout -buildmode=exe
 stdout '^test2json.exe: .+'
 stdout '^\tpath\tcmd/test2json$'
-! stdout 'mod'
+! stdout 'mod[^e]'
 
 # Repeat the test with -buildmode=pie.
 [!buildmode:pie] stop
@@ -48,17 +63,19 @@
 go version external.exe
 stdout '^external.exe: .+'
 go version -m external.exe
+stdout -buildmode=pie
 stdout '^\tpath\trsc.io/fortune'
 stdout '^\tmod\trsc.io/fortune\tv1.0.0'
 
 # Also test PIE with internal linking.
 # currently only supported on linux/amd64, linux/arm64 and windows/amd64.
-[!linux] [!windows] stop
-[!amd64] [!arm64] stop
+[!GOOS:linux] [!GOOS:windows] stop
+[!GOARCH:amd64] [!GOARCH:arm64] stop
 go build -buildmode=pie -ldflags=-linkmode=internal -o internal.exe rsc.io/fortune
 go version internal.exe
 stdout '^internal.exe: .+'
 go version -m internal.exe
+stdout -buildmode=pie
 stdout '^\tpath\trsc.io/fortune'
 stdout '^\tmod\trsc.io/fortune\tv1.0.0'
 
@@ -68,3 +85,8 @@
 -- empty.go --
 package main
 func main(){}
+
+-- empty.txt --
+-- empty.exe --
+-- empty.so --
+-- empty.dll --
diff --git a/src/cmd/go/testdata/script/version_build_settings.txt b/src/cmd/go/testdata/script/version_build_settings.txt
index bfa7f5f..cd3f5cf 100644
--- a/src/cmd/go/testdata/script/version_build_settings.txt
+++ b/src/cmd/go/testdata/script/version_build_settings.txt
@@ -6,7 +6,7 @@
 stdout '^\tbuild\t-compiler=gc$'
 stdout '^\tbuild\tGOOS='
 stdout '^\tbuild\tGOARCH='
-[amd64] stdout '^\tbuild\tGOAMD64='
+[GOARCH:amd64] stdout '^\tbuild\tGOAMD64='
 ! stdout asmflags|gcflags|ldflags|gccgoflags
 
 # Toolchain flags are added if present.
diff --git a/src/cmd/go/testdata/script/version_buildvcs_fossil.txt b/src/cmd/go/testdata/script/version_buildvcs_fossil.txt
index 7203068..bd6b89d 100644
--- a/src/cmd/go/testdata/script/version_buildvcs_fossil.txt
+++ b/src/cmd/go/testdata/script/version_buildvcs_fossil.txt
@@ -3,15 +3,15 @@
 # The Git test covers common functionality.
 
 # "fossil" is the Fossil file server on Plan 9.
-[plan9] skip
+[GOOS:plan9] skip
 [!exec:fossil] skip
 [short] skip
 env GOBIN=$WORK/gopath/bin
 env oldpath=$PATH
 env HOME=$WORK
 env USER=gopher
-[!windows] env fslckout=.fslckout
-[windows] env fslckout=_FOSSIL_
+[!GOOS:windows] env fslckout=.fslckout
+[GOOS:windows] env fslckout=_FOSSIL_
 exec pwd
 exec fossil init repo.fossil
 cd repo/a
@@ -25,7 +25,7 @@
 # If there is a repository, but it can't be used for some reason,
 # there should be an error. It should hint about -buildvcs=false.
 cd ..
-mkdir $fslckout
+mv fslckout $fslckout
 env PATH=$WORK${/}fakebin${:}$oldpath
 chmod 0755 $WORK/fakebin/fossil
 ! exec fossil help
@@ -82,6 +82,7 @@
 -- repo/README --
 Far out in the uncharted backwaters of the unfashionable end of the western
 spiral arm of the Galaxy lies a small, unregarded yellow sun.
+-- repo/fslckout --
 -- repo/a/go.mod --
 module example.com/a
 
diff --git a/src/cmd/go/testdata/script/version_buildvcs_git.txt b/src/cmd/go/testdata/script/version_buildvcs_git.txt
index 4470687..680e492 100644
--- a/src/cmd/go/testdata/script/version_buildvcs_git.txt
+++ b/src/cmd/go/testdata/script/version_buildvcs_git.txt
@@ -2,7 +2,7 @@
 # controlled with -buildvcs. This test focuses on Git. Other tests focus on
 # other VCS tools but may not cover common functionality.
 
-[!exec:git] skip
+[!git] skip
 [short] skip
 env GOBIN=$WORK/gopath/bin
 env oldpath=$PATH
@@ -14,6 +14,14 @@
 ! stdout vcs.revision
 rm $GOBIN/a$GOEXE
 
+# If there's an orphan .git file left by a git submodule, it's not a git
+# repository, and there's no VCS info.
+cd ../gitsubmodule
+go install
+go version -m $GOBIN/gitsubmodule$GOEXE
+! stdout vcs.revision
+rm $GOBIN/gitsubmodule$GOEXE
+
 # If there is a repository, but it can't be used for some reason,
 # there should be an error. It should hint about -buildvcs=false.
 # Also ensure that multiple errors are collected by "go list -e".
@@ -141,6 +149,16 @@
 go 1.18
 -- repo/b/b.go --
 package b
+-- repo/gitsubmodule/.git --
+gitdir: ../.git/modules/gitsubmodule
+-- repo/gitsubmodule/go.mod --
+module example.com/gitsubmodule
+
+go 1.18
+-- repo/gitsubmodule/main.go --
+package main
+
+func main() {}
 -- outside/empty.txt --
 -- outside/c/go.mod --
 module example.com/c
diff --git a/src/cmd/go/testdata/script/version_buildvcs_git_gpg.txt b/src/cmd/go/testdata/script/version_buildvcs_git_gpg.txt
deleted file mode 100644
index dcf97d7..0000000
--- a/src/cmd/go/testdata/script/version_buildvcs_git_gpg.txt
+++ /dev/null
@@ -1,105 +0,0 @@
-# This test checks that VCS information is stamped into Go binaries even when
-# the current commit is signed and the use has configured git to display commit
-# signatures.
-
-[!exec:git] skip
-[!exec:gpg] skip
-[short] skip
-env GOBIN=$GOPATH/bin
-env GNUPGHOME=$WORK/.gpupg
-mkdir $GNUPGHOME
-chmod 0700 $GNUPGHOME
-
-# Create GPG key
-exec gpg --batch --passphrase '' --quick-generate-key [email protected]
-exec gpg --list-secret-keys --with-colons [email protected]
-cp stdout keyinfo.txt
-go run extract_key_id.go keyinfo.txt
-cp stdout keyid.txt
-
-# Initialize repo
-cd repo/
-exec git init
-exec git config user.email [email protected]
-exec git config user.name 'J.R. Gopher'
-exec git config --add log.showSignature true
-go run ../configure_signing_key.go ../keyid.txt
-
-# Create signed commit
-cd a
-exec git add -A
-exec git commit -m 'initial commit' --gpg-sign
-exec git log
-
-# Verify commit signature does not interfere with versioning
-go install
-go version -m $GOBIN/a
-stdout '^\tbuild\tvcs\.revision='
-stdout '^\tbuild\tvcs\.time='
-stdout '^\tbuild\tvcs\.modified=false$'
-
--- repo/README --
-Far out in the uncharted backwaters of the unfashionable end of the western
-spiral arm of the Galaxy lies a small, unregarded yellow sun.
--- repo/a/go.mod --
-module example.com/a
-
-go 1.18
--- repo/a/a.go --
-package main
-
-func main() {}
-
--- extract_key_id.go --
-package main
-
-import "fmt"
-import "io/ioutil"
-import "os"
-import "strings"
-
-func main() {
-    err := run(os.Args[1])
-    if err != nil {
-        panic(err)
-    }
-}
-
-func run(keyInfoFilePath string) error {
-    contents, err := ioutil.ReadFile(keyInfoFilePath)
-    if err != nil {
-        return err
-    }
-    lines := strings.Split(string(contents), "\n")
-    for _, line := range lines {
-        fields := strings.Split(line, ":")
-        if fields[0] == "sec" {
-            fmt.Print(fields[4])
-            return nil
-        }
-    }
-    return fmt.Errorf("key ID not found in: %s", keyInfoFilePath)
-}
-
--- configure_signing_key.go --
-package main
-
-import "io/ioutil"
-import "os"
-import "os/exec"
-
-func main() {
-    err := run(os.Args[1])
-    if err != nil {
-        panic(err)
-    }
-}
-
-func run(keyIdFilePath string) error {
-    keyId, err := ioutil.ReadFile(keyIdFilePath)
-    if err != nil {
-        return err
-    }
-    gitCmd := exec.Command("git", "config", "user.signingKey", string(keyId))
-    return gitCmd.Run()
-}
diff --git a/src/cmd/go/testdata/script/version_buildvcs_nested.txt b/src/cmd/go/testdata/script/version_buildvcs_nested.txt
index a0c69f9..6dab847 100644
--- a/src/cmd/go/testdata/script/version_buildvcs_nested.txt
+++ b/src/cmd/go/testdata/script/version_buildvcs_nested.txt
@@ -1,4 +1,4 @@
-[!exec:git] skip
+[!git] skip
 [!exec:hg] skip
 [short] skip
 env GOFLAGS='-n -buildvcs'
diff --git a/src/cmd/go/testdata/script/version_cshared.txt b/src/cmd/go/testdata/script/version_cshared.txt
new file mode 100644
index 0000000..29e21fc
--- /dev/null
+++ b/src/cmd/go/testdata/script/version_cshared.txt
@@ -0,0 +1,19 @@
+[short] skip
+[!buildmode:c-shared] stop
+
+env GO111MODULE=on
+
+go get rsc.io/fortune
+go build -buildmode=c-shared -o external.so rsc.io/fortune
+go version external.so
+stdout '^external.so: .+'
+go version -m external.so
+stdout '^\tpath\trsc.io/fortune'
+stdout '^\tmod\trsc.io/fortune\tv1.0.0'
+
+-- go.mod --
+module m
+
+-- empty.go --
+package main
+func main(){}
diff --git a/src/cmd/go/testdata/script/version_gc_sections.txt b/src/cmd/go/testdata/script/version_gc_sections.txt
new file mode 100644
index 0000000..4bda23b
--- /dev/null
+++ b/src/cmd/go/testdata/script/version_gc_sections.txt
@@ -0,0 +1,24 @@
+# This test checks that external linking with --gc-sections does not strip version information.
+
+[short] skip
+[!cgo] skip
+[GOOS:aix] skip  # no --gc-sections
+[GOOS:darwin] skip  # no --gc-sections
+
+go build -ldflags='-linkmode=external -extldflags=-Wl,--gc-sections'
+go version hello$GOEXE
+! stdout 'not a Go executable'
+! stderr 'not a Go executable'
+
+-- go.mod --
+module hello
+-- hello.go --
+package main
+
+/*
+*/
+import "C"
+
+func main() {
+	println("hello")
+}
diff --git a/src/cmd/go/testdata/script/vet_asm.txt b/src/cmd/go/testdata/script/vet_asm.txt
index 59b35ec..ae2db97 100644
--- a/src/cmd/go/testdata/script/vet_asm.txt
+++ b/src/cmd/go/testdata/script/vet_asm.txt
@@ -2,7 +2,7 @@
 
 # Issue 27665. Verify that "go vet" analyzes non-Go files.
 
-[!amd64] skip
+[!GOARCH:amd64] skip
 ! go vet -asmdecl a
 stderr 'f: invalid MOVW of x'
 
diff --git a/src/cmd/go/testdata/script/work_disablevendor.txt b/src/cmd/go/testdata/script/work_disablevendor.txt
new file mode 100644
index 0000000..c4c580b
--- /dev/null
+++ b/src/cmd/go/testdata/script/work_disablevendor.txt
@@ -0,0 +1,56 @@
+# Test that mod=vendor is disabled in workspace mode, even
+# with a single workspace module.
+
+cd workspace
+
+# Base case: ensure the module would default to mod=vendor
+# outside of workspace mode.
+env GOWORK=off
+go list -f '{{.Dir}}' example.com/dep
+stdout $GOPATH[\\/]src[\\/]workspace[\\/]vendor[\\/]example.com[\\/]dep
+
+# Test case: endure the module does not enter mod=vendor outside
+# worspace mode.
+env GOWORK=''
+go list -f '{{.Dir}}' example.com/dep
+stdout $GOPATH[\\/]src[\\/]dep
+
+-- workspace/go.work --
+use .
+replace example.com/dep => ../dep
+-- workspace/main.go --
+package main
+
+import "example.com/dep"
+
+func main() {
+	dep.Dep()
+}
+-- workspace/go.mod --
+module example.com/mod
+
+go 1.20
+
+require example.com/dep v1.0.0
+-- workspace/vendor/example.com/dep/dep.go --
+package dep
+
+import "fmt"
+
+func Dep() {
+	fmt.Println("the vendored dep")
+}
+-- workspace/vendor/modules.txt --
+# example.com/dep v1.0.0
+## explicit
+example.com/dep
+-- dep/go.mod --
+module example.com/dep
+-- dep/dep.go --
+package dep
+
+import "fmt"
+
+func Dep () {
+    fmt.Println("the real dep")
+}
diff --git a/src/cmd/go/testdata/script/work_issue54048.txt b/src/cmd/go/testdata/script/work_issue54048.txt
new file mode 100644
index 0000000..ced3d90
--- /dev/null
+++ b/src/cmd/go/testdata/script/work_issue54048.txt
@@ -0,0 +1,19 @@
+! go list -m -json all
+stderr 'go: module example.com/foo appears multiple times in workspace'
+
+-- go.work --
+go 1.18
+
+use (
+        ./a
+        ./b
+)
+-- a/go.mod --
+module example.com/foo
+
+go 1.18
+
+-- b/go.mod --
+module example.com/foo
+
+go 1.18
diff --git a/src/cmd/go/testdata/script/work_module_not_in_go_work.txt b/src/cmd/go/testdata/script/work_module_not_in_go_work.txt
index 9109b2d..074bac5 100644
--- a/src/cmd/go/testdata/script/work_module_not_in_go_work.txt
+++ b/src/cmd/go/testdata/script/work_module_not_in_go_work.txt
@@ -7,7 +7,18 @@
 stderr 'pattern ./...: directory prefix . does not contain modules listed in go.work or their selected dependencies'
 
 ! go list ./a/c
-stderr 'directory a[\\/]c is contained in a module that is not one of the workspace modules listed in go.work. You can add the module to the workspace using go work use a'
+stderr 'directory a[\\/]c is contained in a module that is not one of the workspace modules listed in go.work. You can add the module to the workspace using:\n\tgo work use a'
+
+! go install ./a/c
+stderr 'directory a[\\/]c is contained in a module that is not one of the workspace modules listed in go.work. You can add the module to the workspace using:\n\tgo work use a'
+
+cd a/c
+! go run .
+stderr 'current directory is contained in a module that is not one of the workspace modules listed in go.work. You can add the module to the workspace using:\n\tgo work use \.\.'
+
+cd ../..
+! go run .
+stderr 'current directory outside modules listed in go.work or their selected dependencies'
 
 -- go.work --
 go 1.18
@@ -20,8 +31,10 @@
 -- a/a.go --
 package a
 -- a/c/c.go --
-package c
+package main
 -- b/go.mod --
 module example.com/b
 
 go 1.18
+-- foo.go --
+package foo
diff --git a/src/cmd/go/testdata/script/work_prune.txt b/src/cmd/go/testdata/script/work_prune.txt
index 7e2ae4e..b1f569e 100644
--- a/src/cmd/go/testdata/script/work_prune.txt
+++ b/src/cmd/go/testdata/script/work_prune.txt
@@ -11,7 +11,6 @@
 # If we didn't load the whole graph and didn't load the dependencies of b
 # when loading p, we would end up loading q v1.0.0, rather than v1.1.0,
 # which is selected by MVS.
-# TODO(#48331): We currently load the wrong version of q. Fix this.
 
 go list -m -f '{{.Version}}' example.com/q
 stdout '^v1.1.0$'
diff --git a/src/cmd/go/testdata/script/work_sum_mismatch.txt b/src/cmd/go/testdata/script/work_sum_mismatch.txt
index 9e94743..ca5d71d 100644
--- a/src/cmd/go/testdata/script/work_sum_mismatch.txt
+++ b/src/cmd/go/testdata/script/work_sum_mismatch.txt
@@ -42,7 +42,7 @@
 -- b/go.mod --
 go 1.18
 
-module example.com/hi
+module example.com/hi2
 
 require "rsc.io/quote" v1.5.2
 -- b/go.sum --
diff --git a/src/cmd/go/testdata/script/work_use_issue55952.txt b/src/cmd/go/testdata/script/work_use_issue55952.txt
new file mode 100644
index 0000000..2eef361
--- /dev/null
+++ b/src/cmd/go/testdata/script/work_use_issue55952.txt
@@ -0,0 +1,11 @@
+! go list .
+stderr '^go: cannot load module listed in go\.work file: open .+go\.mod:'
+
+-- go.work --
+use ./y
+-- x/go.mod --
+module x
+
+go 1.19
+-- x/m.go --
+package m
diff --git a/src/cmd/go/testdata/testterminal18153/terminal_test.go b/src/cmd/go/testdata/testterminal18153/terminal_test.go
deleted file mode 100644
index 34ee580..0000000
--- a/src/cmd/go/testdata/testterminal18153/terminal_test.go
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build linux
-// +build linux
-
-// This test is run by src/cmd/dist/test.go (cmd_go_test_terminal),
-// and not by cmd/go's tests. This is because this test requires
-// that it be called with its stdout and stderr being a terminal.
-// dist doesn't run `cmd/go test` against this test directory if
-// dist's stdout/stderr aren't terminals.
-//
-// See issue 18153.
-
-package p
-
-import (
-	"syscall"
-	"testing"
-	"unsafe"
-)
-
-const ioctlReadTermios = syscall.TCGETS
-
-// isTerminal reports whether fd is a terminal.
-func isTerminal(fd uintptr) bool {
-	var termios syscall.Termios
-	_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
-	return err == 0
-}
-
-func TestIsTerminal(t *testing.T) {
-	if !isTerminal(1) {
-		t.Errorf("stdout is not a terminal")
-	}
-	if !isTerminal(2) {
-		t.Errorf("stderr is not a terminal")
-	}
-}
diff --git a/src/cmd/go/testdata/vcstest/README b/src/cmd/go/testdata/vcstest/README
new file mode 100644
index 0000000..f3a0e15
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/README
@@ -0,0 +1,14 @@
+The scripts in this directory set up version-control repos for use in
+tests of cmd/go and its subpackages.
+
+They are written in a dialect of the same script language as in
+cmd/go/testdata/script, and the outputs are hosted by the server in
+cmd/go/internal/vcweb.
+
+To see the conditions and commands available for these scripts, run:
+
+	go test cmd/go/internal/vcweb -v --run=TestHelp
+
+To host these scripts in a standalone server, run:
+
+	go test cmd/go/internal/vcweb/vcstest -v --port=0
diff --git a/src/cmd/go/testdata/vcstest/auth/or401.txt b/src/cmd/go/testdata/vcstest/auth/or401.txt
new file mode 100644
index 0000000..10da48d
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/auth/or401.txt
@@ -0,0 +1,29 @@
+handle auth
+
+modzip vcs-test.golang.org/auth/or401/@v/v0.0.0-20190405155051-52df474c8a8b.zip vcs-test.golang.org/auth/[email protected] .moddir
+
+-- .access --
+{
+	"Username": "aladdin",
+	"Password": "opensesame",
+	"StatusCode": 401,
+	"Message": "ACCESS DENIED, buddy"
+}
+-- index.html --
+<!DOCTYPE html>
+<html>
+<meta name="go-import" content="vcs-test.golang.org/auth/or401 mod https://vcs-test.golang.org/auth/or401">
+-- vcs-test.golang.org/auth/or401/@v/list --
+v0.0.0-20190405155051-52df474c8a8b
+-- vcs-test.golang.org/auth/or401/@v/v0.0.0-20190405155051-52df474c8a8b.info --
+{"Version":"v0.0.0-20190405155051-52df474c8a8b","Time":"2019-04-05T15:50:51Z"}
+-- vcs-test.golang.org/auth/or401/@v/v0.0.0-20190405155051-52df474c8a8b.mod --
+module vcs-test.golang.org/auth/or401
+
+go 1.13
+-- .moddir/go.mod --
+module vcs-test.golang.org/auth/or401
+
+go 1.13
+-- .moddir/or401.go --
+package or401
diff --git a/src/cmd/go/testdata/vcstest/auth/or404.txt b/src/cmd/go/testdata/vcstest/auth/or404.txt
new file mode 100644
index 0000000..9e393c7
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/auth/or404.txt
@@ -0,0 +1,30 @@
+handle auth
+
+modzip vcs-test.golang.org/auth/or404/@v/v0.0.0-20190405155004-2234c475880e.zip vcs-test.golang.org/auth/[email protected] .moddir
+
+-- .access --
+{
+	"Username": "aladdin",
+	"Password": "opensesame",
+	"StatusCode": 404,
+	"Message": "File? What file?"
+}
+-- index.html --
+<!DOCTYPE html>
+<html>
+<meta name="go-import" content="vcs-test.golang.org/auth/or404 mod https://vcs-test.golang.org/auth/or404">
+-- vcs-test.golang.org/auth/or404/@v/list --
+v0.0.0-20190405155004-2234c475880e
+-- vcs-test.golang.org/auth/or404/@v/v0.0.0-20190405155004-2234c475880e.info --
+{"Version":"v0.0.0-20190405155004-2234c475880e","Time":"2019-04-05T15:50:04Z"}
+-- vcs-test.golang.org/auth/or404/@v/v0.0.0-20190405155004-2234c475880e.mod --
+module vcs-test.golang.org/auth/or404
+
+go 1.13
+-- .moddir/go.mod --
+module vcs-test.golang.org/auth/or404
+
+go 1.13
+-- .moddir/or404.go --
+package or404
+-- vcs-test.golang.org/go/modauth404/@v/list --
diff --git a/src/cmd/go/testdata/vcstest/auth/ormanylines.txt b/src/cmd/go/testdata/vcstest/auth/ormanylines.txt
new file mode 100644
index 0000000..41cf5fe
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/auth/ormanylines.txt
@@ -0,0 +1,9 @@
+handle auth
+
+-- .access --
+{
+	"Username": "aladdin",
+	"Password": "opensesame",
+	"StatusCode": 404,
+	"Message": "line 1\nline 2\nline 3\nline 4\nline 5\nline 6\nline 7\nline 8\nline 9\nline 10\nline 11\nline 12\nline 13\nline 14\nline 15\nline 16"
+}
diff --git a/src/cmd/go/testdata/vcstest/auth/oronelongline.txt b/src/cmd/go/testdata/vcstest/auth/oronelongline.txt
new file mode 100644
index 0000000..d27653a
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/auth/oronelongline.txt
@@ -0,0 +1,9 @@
+handle auth
+
+-- .access --
+{
+	"Username": "aladdin",
+	"Password": "opensesame",
+	"StatusCode": 404,
+	"Message": "blahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblah"
+}
diff --git a/src/cmd/go/testdata/vcstest/bzr/hello.txt b/src/cmd/go/testdata/vcstest/bzr/hello.txt
new file mode 100644
index 0000000..7d06503
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/bzr/hello.txt
@@ -0,0 +1,32 @@
+handle bzr
+
+env BZR_EMAIL='Russ Cox <[email protected]>'
+
+bzr init-repo .
+
+bzr init b
+cd b
+cp ../hello.go .
+bzr add hello.go
+bzr commit --commit-time='2017-09-21 21:20:12 -0400' -m 'hello world'
+bzr push ..
+cd ..
+rm b
+
+bzr log
+cmp stdout .bzr-log
+
+-- .bzr-log --
+------------------------------------------------------------
+revno: 1
+committer: Russ Cox <[email protected]>
+branch nick: b
+timestamp: Thu 2017-09-21 21:20:12 -0400
+message:
+  hello world
+-- hello.go --
+package main
+
+func main() {
+	println("hello, world")
+}
diff --git a/src/cmd/go/testdata/vcstest/fossil/hello.txt b/src/cmd/go/testdata/vcstest/fossil/hello.txt
new file mode 100644
index 0000000..48fb774
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/fossil/hello.txt
@@ -0,0 +1,22 @@
+handle fossil
+
+env USER=rsc
+fossil init --date-override 2017-09-22T01:15:36Z hello.fossil
+fossil open --keep hello.fossil
+
+fossil add hello.go
+fossil commit --no-prompt --nosign --date-override 2017-09-22T01:19:07Z --comment 'hello world'
+
+fossil timeline --oneline
+cmp stdout .fossil-timeline
+
+-- .fossil-timeline --
+d4c7dcdc29 hello world
+58da0d15e9 initial empty check-in
++++ no more data (2) +++
+-- hello.go --
+package main
+
+func main() {
+	println("hello, world")
+}
diff --git a/src/cmd/go/testdata/vcstest/git/commit-after-tag.txt b/src/cmd/go/testdata/vcstest/git/commit-after-tag.txt
new file mode 100644
index 0000000..eb13a63
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/git/commit-after-tag.txt
@@ -0,0 +1,39 @@
+handle git
+
+env GIT_AUTHOR_NAME='Bryan C. Mills'
+env GIT_AUTHOR_EMAIL='[email protected]'
+env GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME
+env GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL
+
+git init
+
+at 2019-07-15T17:16:47-04:00
+git add go.mod main.go
+git commit -m 'all: add go.mod and main.go'
+git branch -m master
+git tag v1.0.0
+
+at 2019-07-15T17:17:27-04:00
+cp _next/main.go main.go
+git add main.go
+git commit -m 'add init function'
+
+git log --oneline --decorate=short
+cmp stdout .git-log
+
+-- .git-log --
+b325d82 (HEAD -> master) add init function
+8da67e0 (tag: v1.0.0) all: add go.mod and main.go
+-- go.mod --
+module vcs-test.golang.org/git/commit-after-tag.git
+
+go 1.13
+-- main.go --
+package main
+
+func main() {}
+-- _next/main.go --
+package main
+
+func main() {}
+func init() {}
diff --git a/src/cmd/go/testdata/vcstest/git/empty-v2-without-v1.txt b/src/cmd/go/testdata/vcstest/git/empty-v2-without-v1.txt
new file mode 100644
index 0000000..afe407e
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/git/empty-v2-without-v1.txt
@@ -0,0 +1,24 @@
+handle git
+
+env GIT_AUTHOR_NAME='Bryan C. Mills'
+env GIT_AUTHOR_EMAIL='[email protected]'
+env GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME
+env GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL
+
+git init
+
+at 2019-10-07T14:15:32-04:00
+git add go.mod
+git commit -m 'add go.mod file without go source files'
+git branch -m master
+git tag v2.0.0
+
+git log --oneline --decorate=short
+cmp stdout .git-log
+
+-- .git-log --
+122733c (HEAD -> master, tag: v2.0.0) add go.mod file without go source files
+-- go.mod --
+module vcs-test.golang.org/git/empty-v2-without-v1.git/v2
+
+go 1.14
diff --git a/src/cmd/go/testdata/vcstest/git/emptytest.txt b/src/cmd/go/testdata/vcstest/git/emptytest.txt
new file mode 100644
index 0000000..4526202
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/git/emptytest.txt
@@ -0,0 +1,21 @@
+handle git
+
+env GIT_AUTHOR_NAME='Russ Cox'
+env GIT_AUTHOR_EMAIL='[email protected]'
+env GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME
+env GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL
+
+git init
+
+at 2018-07-03T22:35:49-04:00
+git add go.mod
+git commit -m 'initial'
+git branch -m master
+
+git log --oneline
+cmp stdout .git-log
+
+-- .git-log --
+7bb9146 initial
+-- go.mod --
+module vcs-test.golang.org/git/emptytest.git
diff --git a/src/cmd/go/testdata/vcstest/git/gitrepo1.txt b/src/cmd/go/testdata/vcstest/git/gitrepo1.txt
new file mode 100644
index 0000000..7919089
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/git/gitrepo1.txt
@@ -0,0 +1,68 @@
+handle git
+
+env GIT_AUTHOR_NAME='Russ Cox'
+env GIT_AUTHOR_EMAIL='[email protected]'
+env GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME
+env GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL
+
+git init
+
+at 2018-04-17T15:43:22-04:00
+unquote ''
+cp stdout README
+git add README
+git commit -a -m 'empty README'
+git branch -m master
+git tag v1.2.3
+
+at 2018-04-17T15:45:48-04:00
+git branch v2
+git checkout v2
+echo 'v2'
+cp stdout v2
+git add v2
+git commit -a -m 'v2'
+git tag v2.3
+git tag v2.0.1
+git branch v2.3.4
+
+at 2018-04-17T16:00:19-04:00
+echo 'intermediate'
+cp stdout foo.txt
+git add foo.txt
+git commit -a -m 'intermediate'
+
+at 2018-04-17T16:00:32-04:00
+echo 'another'
+cp stdout another.txt
+git add another.txt
+git commit -a -m 'another'
+git tag v2.0.2
+
+at 2018-04-17T16:16:52-04:00
+git checkout master
+git branch v3
+git checkout v3
+mkdir v3/sub/dir
+echo 'v3/sub/dir/file'
+cp stdout v3/sub/dir/file.txt
+git add v3
+git commit -a -m 'add v3/sub/dir/file.txt'
+
+at 2018-04-17T22:23:00-04:00
+git checkout master
+git tag -a v1.2.4-annotated -m 'v1.2.4-annotated'
+
+git show-ref --tags --heads
+cmp stdout .git-refs
+
+-- .git-refs --
+ede458df7cd0fdca520df19a33158086a8a68e81 refs/heads/master
+9d02800338b8a55be062c838d1f02e0c5780b9eb refs/heads/v2
+76a00fb249b7f93091bc2c89a789dab1fc1bc26f refs/heads/v2.3.4
+a8205f853c297ad2c3c502ba9a355b35b7dd3ca5 refs/heads/v3
+ede458df7cd0fdca520df19a33158086a8a68e81 refs/tags/v1.2.3
+b004e48a345a86ed7a2fb7debfa7e0b2f9b0dd91 refs/tags/v1.2.4-annotated
+76a00fb249b7f93091bc2c89a789dab1fc1bc26f refs/tags/v2.0.1
+9d02800338b8a55be062c838d1f02e0c5780b9eb refs/tags/v2.0.2
+76a00fb249b7f93091bc2c89a789dab1fc1bc26f refs/tags/v2.3
diff --git a/src/cmd/go/testdata/vcstest/git/hello.txt b/src/cmd/go/testdata/vcstest/git/hello.txt
new file mode 100644
index 0000000..17ba09c
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/git/hello.txt
@@ -0,0 +1,25 @@
+handle git
+
+env GIT_AUTHOR_NAME=bwk
+env GIT_AUTHOR_EMAIL=bwk
+env GIT_COMMITTER_NAME='Russ Cox'
+env GIT_COMMITTER_EMAIL='[email protected]'
+
+git init
+
+at 2017-09-21T21:05:58-04:00
+git add hello.go
+git commit -a -m 'hello'
+git branch -m master
+
+git log --oneline --decorate=short
+cmp stdout .git-log
+
+-- .git-log --
+fc3a09f (HEAD -> master) hello
+-- hello.go --
+package main
+
+func main() {
+	println("hello, world")
+}
diff --git a/src/cmd/go/testdata/vcstest/git/insecurerepo.txt b/src/cmd/go/testdata/vcstest/git/insecurerepo.txt
new file mode 100644
index 0000000..e0ea62c
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/git/insecurerepo.txt
@@ -0,0 +1,32 @@
+handle git
+
+env GIT_AUTHOR_NAME='Bryan C. Mills'
+env GIT_AUTHOR_EMAIL='[email protected]'
+env GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME
+env GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL
+
+git init
+
+at 2019-04-03T13:30:35-04:00
+git add go.mod
+git commit -m 'all: initialize module'
+git branch -m master
+
+at 2019-09-04T14:39:48-04:00
+git add main.go
+git commit -m 'main: add Go source file'
+
+git log --oneline --decorate=short
+cmp stdout .git-log
+
+-- .git-log --
+6fecd21 (HEAD -> master) main: add Go source file
+d1a15cd all: initialize module
+-- go.mod --
+module vcs-test.golang.org/insecure/go/insecure
+
+go 1.13
+-- main.go --
+package main
+
+func main() {}
diff --git a/src/cmd/go/testdata/vcstest/git/mainonly.txt b/src/cmd/go/testdata/vcstest/git/mainonly.txt
new file mode 100644
index 0000000..d294e34
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/git/mainonly.txt
@@ -0,0 +1,23 @@
+handle git
+
+env GIT_AUTHOR_NAME='Bryan C. Mills'
+env GIT_AUTHOR_EMAIL='[email protected]'
+env GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME
+env GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL
+
+git init
+
+at 2019-09-05T14:07:43-04:00
+git add main.go
+git commit -a -m 'add main.go'
+git branch -m master
+
+git log --oneline --decorate=short
+cmp stdout .git-log
+
+-- .git-log --
+8a27e8b (HEAD -> master) add main.go
+-- main.go --
+package main
+
+func main() {}
diff --git a/src/cmd/go/testdata/vcstest/git/missingrepo.txt b/src/cmd/go/testdata/vcstest/git/missingrepo.txt
new file mode 100644
index 0000000..b947d8c
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/git/missingrepo.txt
@@ -0,0 +1,10 @@
+handle dir
+
+-- missingrepo-git/index.html --
+<!DOCTYPE html>
+<html>
+<meta name="go-import" content="vcs-test.golang.org/go/missingrepo/missingrepo-git git https://vcs-test.golang.org/git/missingrepo">
+-- missingrepo-git/notmissing/index.html --
+<!DOCTYPE html>
+<html>
+<meta name="go-import" content="vcs-test.golang.org/go/missingrepo/missingrepo-git/notmissing git https://vcs-test.golang.org/git/mainonly">
diff --git a/src/cmd/go/testdata/vcstest/git/modlegacy1-new.txt b/src/cmd/go/testdata/vcstest/git/modlegacy1-new.txt
new file mode 100644
index 0000000..ee14454
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/git/modlegacy1-new.txt
@@ -0,0 +1,33 @@
+handle git
+
+env GIT_AUTHOR_NAME='Russ Cox'
+env GIT_AUTHOR_EMAIL='[email protected]'
+env GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME
+env GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL
+
+git init
+
+at 2018-04-25T11:00:57-04:00
+git add go.mod new.go p1 p2
+git commit -m 'initial commit'
+git branch -m master
+
+git log --oneline --decorate=short
+cmp stdout .git-log
+
+-- .git-log --
+36cc50a (HEAD -> master) initial commit
+-- go.mod --
+module "vcs-test.golang.org/git/modlegacy1-new.git/v2"
+-- new.go --
+package new
+
+import _ "vcs-test.golang.org/git/modlegacy1-new.git/v2/p2"
+-- p1/p1.go --
+package p1
+
+import _ "vcs-test.golang.org/git/modlegacy1-old.git/p2"
+import _ "vcs-test.golang.org/git/modlegacy1-new.git"
+import _ "vcs-test.golang.org/git/modlegacy1-new.git/p2"
+-- p2/p2.go --
+package p2
diff --git a/src/cmd/go/testdata/vcstest/git/modlegacy1-old.txt b/src/cmd/go/testdata/vcstest/git/modlegacy1-old.txt
new file mode 100644
index 0000000..bca8f06
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/git/modlegacy1-old.txt
@@ -0,0 +1,27 @@
+handle git
+
+env GIT_AUTHOR_NAME='Russ Cox'
+env GIT_AUTHOR_EMAIL='[email protected]'
+env GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME
+env GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL
+
+git init
+
+at 2018-04-25T10:59:24-04:00
+git add p1 p2
+git commit -m 'initial commit'
+git branch -m master
+
+git log --oneline --decorate=short
+cmp stdout .git-log
+
+-- .git-log --
+6b4ba8b (HEAD -> master) initial commit
+-- p1/p1.go --
+package p1
+
+import _ "vcs-test.golang.org/git/modlegacy1-old.git/p2"
+import _ "vcs-test.golang.org/git/modlegacy1-new.git/p1"
+import _ "vcs-test.golang.org/git/modlegacy1-new.git"
+-- p2/p2.go --
+package p2
diff --git a/src/cmd/go/testdata/vcstest/git/no-tags.txt b/src/cmd/go/testdata/vcstest/git/no-tags.txt
new file mode 100644
index 0000000..5ff0091
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/git/no-tags.txt
@@ -0,0 +1,27 @@
+handle git
+
+env GIT_AUTHOR_NAME='Bryan C. Mills'
+env GIT_AUTHOR_EMAIL='[email protected]'
+env GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME
+env GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL
+
+git init
+
+at 2019-07-15T17:20:47-04:00
+git add go.mod main.go
+git commit -m 'all: add go.mod and main.go'
+git branch -m master
+
+git log --oneline --decorate=short
+cmp stdout .git-log
+
+-- .git-log --
+e706ba1 (HEAD -> master) all: add go.mod and main.go
+-- go.mod --
+module vcs-test.golang.org/git/no-tags.git
+
+go 1.13
+-- main.go --
+package main
+
+func main() {}
diff --git a/src/cmd/go/testdata/vcstest/git/odd-tags.txt b/src/cmd/go/testdata/vcstest/git/odd-tags.txt
new file mode 100644
index 0000000..8e24867
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/git/odd-tags.txt
@@ -0,0 +1,49 @@
+handle git
+
+env GIT_AUTHOR_NAME='Bryan C. Mills'
+env GIT_AUTHOR_EMAIL='[email protected]'
+env GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME
+env GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL
+
+git init
+
+at 2022-02-23T13:48:02-05:00
+git add README.txt
+git commit -m 'initial state'
+git branch -m main
+git tag 'v2.0.0+incompatible'
+
+at 2022-02-23T13:48:35-05:00
+git rm -r README.txt
+git add go.mod
+git commit -m 'migrate to Go modules'
+git tag 'v0.1.0+build-metadata'
+
+at 2022-02-23T14:41:55-05:00
+git branch v3-dev
+git checkout v3-dev
+cp v3/go.mod go.mod
+git commit go.mod -m 'update to /v3'
+git tag 'v3.0.0-20220223184802-12d19af20458'
+
+git checkout main
+
+git show-ref --tags --heads
+cmp stdout .git-refs
+
+-- .git-refs --
+9d863d525bbfcc8eda09364738c4032393711a56 refs/heads/main
+cce3d0f5d2ec85678cca3c45ac4a87f3be5efaca refs/heads/v3-dev
+9d863d525bbfcc8eda09364738c4032393711a56 refs/tags/v0.1.0+build-metadata
+12d19af204585b0db3d2a876ceddf5b9323f5a4a refs/tags/v2.0.0+incompatible
+cce3d0f5d2ec85678cca3c45ac4a87f3be5efaca refs/tags/v3.0.0-20220223184802-12d19af20458
+-- README.txt --
+This module lacks a go.mod file.
+-- go.mod --
+module vcs-test.golang.org/git/odd-tags.git
+
+go 1.18
+-- v3/go.mod --
+module vcs-test.golang.org/git/odd-tags.git/v3
+
+go 1.18
diff --git a/src/cmd/go/testdata/vcstest/git/prefixtagtests.txt b/src/cmd/go/testdata/vcstest/git/prefixtagtests.txt
new file mode 100644
index 0000000..6c89c85
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/git/prefixtagtests.txt
@@ -0,0 +1,53 @@
+handle git
+
+env GIT_AUTHOR_NAME='Jay Conrod'
+env GIT_AUTHOR_EMAIL='[email protected]'
+env GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME
+env GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL
+
+at 2019-05-09T18:35:00-04:00
+
+git init
+
+git add sub
+git commit -m 'create module sub'
+git branch -m master
+
+echo 'v0.1.0'
+cp stdout status
+git add status
+git commit -a -m 'v0.1.0'
+git tag 'v0.1.0'
+
+echo 'sub/v0.0.9'
+cp stdout status
+git commit -a -m 'sub/v0.0.9'
+git tag 'sub/v0.0.9'
+
+echo 'sub/v0.0.10'
+cp stdout status
+git commit -a -m 'sub/v0.0.10'
+git tag 'sub/v0.0.10'
+
+echo 'v0.2.0'
+cp stdout status
+git commit -a -m 'v0.2.0'
+git tag 'v0.2.0'
+
+echo 'after last tag'
+cp stdout status
+git commit -a -m 'after last tag'
+
+git show-ref --tags --heads
+cmp stdout .git-refs
+
+-- .git-refs --
+c3ee5d0dfbb9bf3c4d8bb2bce24cd8d14d2d4238 refs/heads/master
+2b7c4692e12c109263cab51b416fcc835ddd7eae refs/tags/sub/v0.0.10
+883885166298d79a0561d571a3044ec5db2e7c28 refs/tags/sub/v0.0.9
+db89fc573cfb939faf0aa0660671eb4cf8b8b673 refs/tags/v0.1.0
+1abe41965749e50828dd41de8d12c6ebc8e4e131 refs/tags/v0.2.0
+-- sub/go.mod --
+module vcs-test.golang.org/git/prefixtagtests.git/sub
+-- sub/sub.go --
+package sub
diff --git a/src/cmd/go/testdata/vcstest/git/querytest.txt b/src/cmd/go/testdata/vcstest/git/querytest.txt
new file mode 100644
index 0000000..b0f708a
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/git/querytest.txt
@@ -0,0 +1,273 @@
+handle git
+
+env GIT_AUTHOR_NAME='Russ Cox'
+env GIT_AUTHOR_EMAIL='[email protected]'
+env GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME
+env GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL
+
+git init
+
+at 2018-07-03T22:31:01-04:00
+git add go.mod
+git commit -a -m 'v1'
+git branch -m master
+git tag start
+
+git branch v2
+
+at 2018-07-03T22:33:47-04:00
+echo 'before v0.0.0-pre1'
+cp stdout status
+git add status
+git commit -a -m 'before v0.0.0-pre1'
+
+echo 'at v0.0.0-pre1'
+cp stdout status
+git commit -a -m 'at v0.0.0-pre1'
+git tag 'v0.0.0-pre1'
+
+echo 'before v0.0.0'
+cp stdout status
+git commit -a -m 'before v0.0.0'
+
+echo 'at v0.0.0'
+cp stdout status
+git commit -a -m 'at v0.0.0'
+git tag 'v0.0.0'
+
+echo 'before v0.0.1'
+cp stdout status
+git commit -a -m 'before v0.0.1'
+
+echo 'at v0.0.1'
+cp stdout status
+git commit -a -m 'at v0.0.1'
+git tag 'v0.0.1'
+
+echo 'before v0.0.2'
+cp stdout status
+git commit -a -m 'before v0.0.2'
+
+echo 'at v0.0.2'
+cp stdout status
+git commit -a -m 'at v0.0.2'
+git tag 'v0.0.2'
+
+echo 'before v0.0.3'
+cp stdout status
+git commit -a -m 'before v0.0.3'
+
+echo 'at v0.0.3'
+cp stdout status
+git commit -a -m 'at v0.0.3'
+git tag 'v0.0.3'
+git tag favorite
+
+echo 'before v0.1.0'
+cp stdout status
+git commit -a -m 'before v0.1.0'
+
+echo 'at v0.1.0'
+cp stdout status
+git commit -a -m 'at v0.1.0'
+git tag v0.1.0
+
+echo 'before v0.1.1'
+cp stdout status
+git commit -a -m 'before v0.1.1'
+
+echo 'at v0.1.1'
+cp stdout status
+git commit -a -m 'at v0.1.1'
+git tag 'v0.1.1'
+
+echo 'before v0.1.2'
+cp stdout status
+git commit -a -m 'before v0.1.2'
+
+echo 'at v0.1.2'
+cp stdout status
+git commit -a -m 'at v0.1.2'
+git tag 'v0.1.2'
+
+echo 'before v0.3.0'
+cp stdout status
+git commit -a -m 'before v0.3.0'
+
+echo 'at v0.3.0'
+cp stdout status
+git commit -a -m 'at v0.3.0'
+git tag 'v0.3.0'
+
+echo 'before v1.0.0'
+cp stdout status
+git commit -a -m 'before v1.0.0'
+
+echo 'at v1.0.0'
+cp stdout status
+git commit -a -m 'at v1.0.0'
+git tag 'v1.0.0'
+
+echo 'before v1.1.0'
+cp stdout status
+git commit -a -m 'before v1.1.0'
+
+echo 'at v1.1.0'
+cp stdout status
+git commit -a -m 'at v1.1.0'
+git tag 'v1.1.0'
+
+echo 'before v1.9.0'
+cp stdout status
+git commit -a -m 'before v1.9.0'
+
+echo 'at v1.9.0'
+cp stdout status
+git commit -a -m 'at v1.9.0'
+git tag 'v1.9.0'
+
+echo 'before v1.9.9'
+cp stdout status
+git commit -a -m 'before v1.9.9'
+
+echo 'at v1.9.9'
+cp stdout status
+git commit -a -m 'at v1.9.9'
+git tag 'v1.9.9'
+
+at 2018-07-03T22:45:01-04:00
+echo 'before v1.9.10-pre1'
+cp stdout status
+git commit -a -m 'before v1.9.10-pre1'
+
+echo 'at v1.9.10-pre1'
+cp stdout status
+git commit -a -m 'at v1.9.10-pre1'
+git tag 'v1.9.10-pre1'
+
+at 2018-07-03T22:50:24-04:00
+git checkout v2
+cp v2/go.mod go.mod
+git add go.mod
+git commit -a -m 'v2'
+
+at 2018-07-03T22:51:14-04:00
+echo 'before v2.0.0'
+cp stdout status
+git add status
+git commit -a -m 'before v2.0.0'
+
+at 2018-07-03T22:51:14-04:00
+echo 'at v2.0.0'
+cp stdout status
+git commit -a -m 'at v2.0.0'
+git tag 'v2.0.0'
+
+at 2018-07-03T22:51:14-04:00
+echo 'before v2.1.0'
+cp stdout status
+git commit -a -m 'before v2.1.0'
+
+at 2018-07-03T22:51:14-04:00
+echo 'at v2.1.0'
+cp stdout status
+git commit -a -m 'at v2.1.0'
+git tag 'v2.1.0'
+
+at 2018-07-03T22:51:14-04:00
+echo 'before v2.2.0'
+cp stdout status
+git commit -a -m 'before v2.2.0'
+
+at 2018-07-03T22:51:14-04:00
+echo 'at v2.2.0'
+cp stdout status
+git commit -a -m 'at v2.2.0'
+git tag 'v2.2.0'
+
+at 2018-07-03T22:51:14-04:00
+echo 'before v2.5.5'
+cp stdout status
+git commit -a -m 'before v2.5.5'
+
+at 2018-07-03T22:51:14-04:00
+echo 'at v2.5.5'
+cp stdout status
+git commit -a -m 'at v2.5.5'
+git tag 'v2.5.5'
+
+at 2018-07-03T23:35:18-04:00
+echo 'after v2.5.5'
+cp stdout status
+git commit -a -m 'after v2.5.5'
+
+
+env GIT_AUTHOR_NAME='Bryan C. Mills'
+env [email protected]
+env GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME
+env GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL
+
+git checkout v2.5.5
+
+at 2019-05-13T17:13:56-04:00
+echo 'before v2.6.0-pre1'
+cp stdout status
+git commit -a -m 'before v2.6.0-pre1'
+
+at 2019-05-13T17:13:56-04:00
+echo 'at v2.6.0-pre1'
+cp stdout status
+git commit -a -m 'at v2.6.0-pre1'
+git tag 'v2.6.0-pre1'
+
+git checkout master
+
+at 2019-05-13T16:11:25-04:00
+echo 'before v1.9.10-pre2+metadata'
+cp stdout status
+git commit -a -m 'before v1.9.10-pre2+metadata'
+
+at 2019-05-13T16:11:26-04:00
+echo 'at v1.9.10-pre2+metadata'
+cp stdout status
+git commit -a -m 'at v1.9.10-pre2+metadata'
+git tag 'v1.9.10-pre2+metadata'
+
+at 2019-12-20T08:46:14-05:00
+echo 'after v1.9.10-pre2+metadata'
+cp stdout status
+git commit -a -m 'after v1.9.10-pre2+metadata'
+
+
+git show-ref --tags --heads
+cmp stdout .git-refs
+
+-- .git-refs --
+ed5ffdaa1f5e7e0be6f5ba2d63097026506224f2 refs/heads/master
+feed8f518cf4a7215a3b2a8268b8b0746dcbb12d refs/heads/v2
+f6abd4e3ed7f2297bc8fd2888bd6d5412e255fcc refs/tags/favorite
+5e9e31667ddfe16e9350f4bd00acc933c8cd5e56 refs/tags/start
+0de900e0063bcc310ea0621bfbc227a9b4e3b020 refs/tags/v0.0.0
+e5ec98b1c15df29e3bd346d538d73b6e8c3b500c refs/tags/v0.0.0-pre1
+179bc86b1be3f6d4553f77ebe68a8b6d750ceff8 refs/tags/v0.0.1
+81da2346e009fa1072fe4de3a9a223398ea8ec39 refs/tags/v0.0.2
+f6abd4e3ed7f2297bc8fd2888bd6d5412e255fcc refs/tags/v0.0.3
+7a1b6bf60ae5bb2b2bd49d152e0bbad806056122 refs/tags/v0.1.0
+daedca9abee3171fe45e0344098a993675ac799e refs/tags/v0.1.1
+ce829e0f1c45a2eca0f1ad16d7c1aca7cddb433b refs/tags/v0.1.2
+44aadfee25d86acb32d6f352afd1d602b0e3a651 refs/tags/v0.3.0
+20756d3a393908b2edb5db0f0bb954e962860168 refs/tags/v1.0.0
+b0bf267f64b7d5b5cabe22fbcad22f3f1642b7e5 refs/tags/v1.1.0
+609dca58c03f0ddf1d8ebe46c1f74fc6a99f3e73 refs/tags/v1.9.0
+e0cf3de987e660c21b6950e85b317ce5f7fbb9d9 refs/tags/v1.9.10-pre1
+42abcb6df8eee6983aeca9a307c28ea40530aceb refs/tags/v1.9.10-pre2+metadata
+5ba9a4ea62136ae86213feba68bc73858f55b7e1 refs/tags/v1.9.9
+9763aa065ae27c6cacec5ca8b6dfa43a1b31dea0 refs/tags/v2.0.0
+23c28cb696ff40a2839ce406f2c173aa6c3cdda6 refs/tags/v2.1.0
+1828ee9f8074075675013e4d488d5d49ddc1b502 refs/tags/v2.2.0
+d7352560158175e3b6aa11e22efb06d9e87e6eea refs/tags/v2.5.5
+fb9e35b393eb0cccc37e13e243ce60b4ff8c7eea refs/tags/v2.6.0-pre1
+-- go.mod --
+module vcs-test.golang.org/git/querytest.git
+-- v2/go.mod --
+module vcs-test.golang.org/git/querytest.git/v2
diff --git a/src/cmd/go/testdata/vcstest/git/retract-pseudo.txt b/src/cmd/go/testdata/vcstest/git/retract-pseudo.txt
new file mode 100644
index 0000000..e189484
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/git/retract-pseudo.txt
@@ -0,0 +1,33 @@
+handle git
+
+env GIT_AUTHOR_NAME='Jay Conrod'
+env GIT_AUTHOR_EMAIL='[email protected]'
+env GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME
+env GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL
+
+at 2020-10-09T13:37:47-04:00
+
+git init
+
+git add go.mod p.go
+git commit -m 'create module retract-pseudo'
+git branch -m main
+git tag v1.0.0
+
+git mv p.go q.go
+git commit -m 'trivial change'
+
+git show-ref --tags --heads
+cmp stdout .git-refs
+
+-- .git-refs --
+713affd19d7b9b6dc876b603017f3dcaab8ba674 refs/heads/main
+64c061ed4371ef372b6bbfd58ee32015d6bfc3e5 refs/tags/v1.0.0
+-- go.mod --
+module vcs-test.golang.org/git/retract-pseudo.git
+
+go 1.16
+
+retract v1.0.0
+-- p.go --
+package p
diff --git a/src/cmd/go/testdata/vcstest/git/semver-branch.txt b/src/cmd/go/testdata/vcstest/git/semver-branch.txt
new file mode 100644
index 0000000..69e1762
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/git/semver-branch.txt
@@ -0,0 +1,53 @@
+handle git
+
+env GIT_AUTHOR_NAME='Bryan C. Mills'
+env GIT_AUTHOR_EMAIL='[email protected]'
+env GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME
+env GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL
+
+git init
+
+at 2022-02-02T14:15:21-05:00
+git add pkg go.mod
+git commit -a -m 'pkg: add empty package'
+git branch -m main
+git tag 'v0.1.0'
+
+at 2022-02-02T14:19:44-05:00
+git branch 'v1.0.0'
+git branch 'v2.0.0'
+git checkout 'v1.0.0'
+cp v1/pkg/pkg.go pkg/pkg.go
+git commit -a -m 'pkg: start developing toward v1.0.0'
+
+at 2022-02-03T10:53:13-05:00
+git branch 'v3.0.0-devel'
+git checkout 'v3.0.0-devel'
+git checkout v0.1.0 pkg/pkg.go
+git commit -a -m 'pkg: remove panic'
+git tag v4.0.0-beta.1
+
+git checkout main
+
+git show-ref --tags --heads
+cmp stdout .git-refs
+
+-- .git-refs --
+33ea7ee36f3e3f44f528664b3712c9fa0cef7502 refs/heads/main
+09c4d8f6938c7b5eeae46858a72712b8700fa46a refs/heads/v1.0.0
+33ea7ee36f3e3f44f528664b3712c9fa0cef7502 refs/heads/v2.0.0
+d59622f6e4d77f008819083582fde71ea1921b0c refs/heads/v3.0.0-devel
+33ea7ee36f3e3f44f528664b3712c9fa0cef7502 refs/tags/v0.1.0
+d59622f6e4d77f008819083582fde71ea1921b0c refs/tags/v4.0.0-beta.1
+-- go.mod --
+module vcs-test.golang.org/git/semver-branch.git
+
+go 1.16
+-- pkg/pkg.go --
+package pkg
+-- v1/pkg/pkg.go --
+package pkg
+
+func init() {
+	panic("TODO")
+}
diff --git a/src/cmd/go/testdata/vcstest/git/tagtests.txt b/src/cmd/go/testdata/vcstest/git/tagtests.txt
new file mode 100644
index 0000000..92e79cd
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/git/tagtests.txt
@@ -0,0 +1,44 @@
+handle git
+
+env GIT_AUTHOR_NAME='Jay Conrod'
+env GIT_AUTHOR_EMAIL='[email protected]'
+env GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME
+env GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL
+
+at 2019-05-09T18:56:25-04:00
+
+git init
+
+git add go.mod tagtests.go
+git commit -m 'create module tagtests'
+git branch -m master
+git branch b
+
+git add v0.2.1
+git commit -m 'v0.2.1'
+git tag 'v0.2.1'
+
+git checkout b
+git add 'v0.2.2'
+git commit -m 'v0.2.2'
+git tag 'v0.2.2'
+
+git checkout master
+git merge b -m 'merge'
+
+git show-ref --tags --heads
+cmp stdout .git-refs
+
+-- .git-refs --
+59356c8cd18c5fe9a598167d98a6843e52d57952 refs/heads/b
+c7818c24fa2f3f714c67d0a6d3e411c85a518d1f refs/heads/master
+101c49f5af1b2466332158058cf5f03c8cca6429 refs/tags/v0.2.1
+59356c8cd18c5fe9a598167d98a6843e52d57952 refs/tags/v0.2.2
+-- go.mod --
+module vcs-test.golang.org/git/tagtests.git
+-- tagtests.go --
+package tagtests
+-- v0.2.1 --
+v0.2.1
+-- v0.2.2 --
+v0.2.2
diff --git a/src/cmd/go/testdata/vcstest/git/v2repo.txt b/src/cmd/go/testdata/vcstest/git/v2repo.txt
new file mode 100644
index 0000000..6cbe924
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/git/v2repo.txt
@@ -0,0 +1,26 @@
+handle git
+
+env GIT_AUTHOR_NAME='Bryan C. Mills'
+env GIT_AUTHOR_EMAIL='[email protected]'
+env GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME
+env GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL
+
+git init
+
+at 2019-04-03T11:52:15-04:00
+env GIT_AUTHOR_DATE=2019-04-03T11:44:11-04:00
+git add go.mod
+git commit -m 'all: add go.mod'
+git branch -m master
+git tag 'v2.0.0'
+
+git show-ref --tags --heads
+cmp stdout .git-refs
+
+-- .git-refs --
+203b91c896acd173aa719e4cdcb7d463c4b090fa refs/heads/master
+203b91c896acd173aa719e4cdcb7d463c4b090fa refs/tags/v2.0.0
+-- go.mod --
+module vcs-test.golang.org/go/v2module/v2
+
+go 1.12
diff --git a/src/cmd/go/testdata/vcstest/git/v2sub.txt b/src/cmd/go/testdata/vcstest/git/v2sub.txt
new file mode 100644
index 0000000..5d4ab58
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/git/v2sub.txt
@@ -0,0 +1,35 @@
+handle git
+
+env GIT_AUTHOR_NAME='Bryan C. Mills'
+env GIT_AUTHOR_EMAIL='[email protected]'
+env GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME
+env GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL
+
+git init
+
+at 2022-02-22T15:53:33-05:00
+git add v2sub.go v2
+git commit -m 'all: add package v2sub and v2sub/v2'
+git branch -m main
+git tag v2.0.0
+
+at 2022-02-22T15:55:07-05:00
+git add README.txt
+git commit -m 'v2sub: add README.txt'
+
+git show-ref --tags --heads
+cmp stdout .git-refs
+
+-- .git-refs --
+80beb17a16036f17a5aedd1bb5bd6d407b3c6dc5 refs/heads/main
+5fcd3eaeeb391d399f562fd45a50dac9fc34ae8b refs/tags/v2.0.0
+-- v2/go.mod --
+module vcs-test.golang.org/git/v2sub.git/v2
+
+go 1.16
+-- v2/v2sub.go --
+package v2sub
+-- v2sub.go --
+package v2sub
+-- README.txt --
+This root module lacks a go.mod file.
diff --git a/src/cmd/go/testdata/vcstest/git/v3pkg.txt b/src/cmd/go/testdata/vcstest/git/v3pkg.txt
new file mode 100644
index 0000000..af18e01
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/git/v3pkg.txt
@@ -0,0 +1,28 @@
+handle git
+
+env GIT_AUTHOR_NAME='Bryan C. Mills'
+env GIT_AUTHOR_EMAIL='[email protected]'
+env GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME
+env GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL
+
+git init
+
+at 2019-07-15T14:01:24-04:00
+env GIT_AUTHOR_DATE=2019-07-15T13:59:34-04:00
+git add go.mod v3pkg.go
+git commit -a -m 'all: add go.mod with v3 path'
+git branch -m master
+git tag 'v3.0.0'
+
+git show-ref --tags --heads
+cmp stdout .git-refs
+
+-- .git-refs --
+a3eab1261b8e3164bcbde9171c23d5fd36e32a85 refs/heads/master
+a3eab1261b8e3164bcbde9171c23d5fd36e32a85 refs/tags/v3.0.0
+-- go.mod --
+module vcs-test.golang.org/git/v3pkg.git/v3
+
+go 1.13
+-- v3pkg.go --
+package v3pkg
diff --git a/src/cmd/go/testdata/vcstest/git/vgotest1.txt b/src/cmd/go/testdata/vcstest/git/vgotest1.txt
new file mode 100644
index 0000000..d2fc741
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/git/vgotest1.txt
@@ -0,0 +1,257 @@
+handle git
+
+env GIT_AUTHOR_NAME='Russ Cox'
+env GIT_AUTHOR_EMAIL='[email protected]'
+env GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME
+env GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL
+
+git init
+
+at 2018-02-19T17:21:09-05:00
+git add LICENSE README.md
+git commit -m 'initial commit'
+git branch -m master
+
+git checkout --detach HEAD
+
+at 2018-02-19T18:10:06-05:00
+mkdir pkg
+echo 'package p // pkg/p.go'
+cp stdout pkg/p.go
+git add pkg/p.go
+git commit -m 'add pkg/p.go'
+git tag v0.0.0
+git tag v1.0.0
+git tag mytag
+
+git checkout --detach HEAD
+
+at 2018-02-19T18:14:23-05:00
+mkdir v2
+echo 'module "github.com/rsc/vgotest1/v2" // root go.mod'
+cp stdout go.mod
+git add go.mod
+git commit -m 'go.mod v2'
+git tag v2.0.1
+
+at 2018-02-19T18:15:11-05:00
+mkdir submod/pkg
+echo 'package p // submod/pkg/p.go'
+cp stdout submod/pkg/p.go
+git add submod/pkg/p.go
+git commit -m 'submod/pkg/p.go'
+git tag v2.0.2
+
+at 2018-02-19T18:16:04-05:00
+echo 'module "github.com/rsc/vgotest" // v2/go.mod'
+cp stdout v2/go.mod
+git add v2/go.mod
+git commit -m 'v2/go.mod: bad go.mod (no version)'
+git tag v2.0.3
+
+at 2018-02-19T19:03:38-05:00
+env GIT_AUTHOR_DATE=2018-02-19T18:16:38-05:00
+echo 'module "github.com/rsc/vgotest1/v2" // v2/go.mod'
+cp stdout v2/go.mod
+git add v2/go.mod
+git commit -m 'v2/go.mod: fix'
+git tag v2.0.4
+
+at 2018-02-19T19:03:59-05:00
+env GIT_AUTHOR_DATE=2018-02-19T18:17:02-05:00
+echo 'module "github.com/rsc/vgotest1" // root go.mod'
+cp stdout go.mod
+git add go.mod
+git commit -m 'go.mod: drop v2'
+git tag v2.0.5
+
+git checkout --detach mytag
+
+at 2018-02-19T18:10:28-05:00
+echo 'module "github.com/rsc/vgotest1" // root go.mod'
+cp stdout go.mod
+git add go.mod
+git commit -m 'go.mod'
+git tag v0.0.1
+git tag v1.0.1
+
+at 2018-02-19T18:11:28-05:00
+mkdir submod/pkg
+echo 'package pkg // submod/pkg/p.go'
+cp stdout submod/pkg/p.go
+git add submod
+git commit -m 'submod/pkg/p.go'
+git tag v1.0.2
+
+at 2018-02-19T18:12:07-05:00
+echo 'module "github.com/vgotest1/submod" // submod/go.mod'
+cp stdout submod/go.mod
+git add submod/go.mod
+git commit -m 'submod/go.mod'
+git tag v1.0.3
+git tag submod/v1.0.4
+
+at 2018-02-19T18:12:59-05:00
+git apply 0001-submod-go.mod-add-require-vgotest1-v1.1.0.patch
+git commit -a -m 'submod/go.mod: add require vgotest1 v1.1.0'
+git tag submod/v1.0.5
+
+at 2018-02-19T18:13:36-05:00
+git apply 0002-go.mod-add-require-submod-v1.0.5.patch
+git commit -a -m 'go.mod: add require submod v1.0.5'
+git tag v1.1.0
+
+git checkout master
+
+at 2018-02-19T17:23:01-05:00
+mkdir pkg
+echo 'package pkg'
+cp stdout pkg/p.go
+git add pkg/p.go
+git commit -m 'pkg: add'
+
+at 2018-02-19T17:30:23-05:00
+env GIT_AUTHOR_DATE=2018-02-19T17:24:48-05:00
+echo 'module "github.com/vgotest1/v2"'
+cp stdout go.mod
+git add go.mod
+git commit -m 'add go.mod'
+
+at 2018-02-19T17:30:45-05:00
+echo 'module "github.com/vgotest1"'
+cp stdout go.mod
+git add go.mod
+git commit -m 'bad mod path'
+
+at 2018-02-19T17:31:34-05:00
+mkdir v2
+echo 'module "github.com/vgotest1/v2"'
+cp stdout v2/go.mod
+git add v2/go.mod
+git commit -m 'add v2/go.mod'
+
+at 2018-02-19T17:32:37-05:00
+echo 'module "github.com/vgotest1/v2"'
+cp stdout go.mod
+git add go.mod
+git commit -m 'say v2 in root go.mod'
+
+git checkout --detach HEAD
+at 2018-02-19T17:51:24-05:00
+	# README.md at this commit lacked a trailing newline, so 'git apply' can't
+	# seem to apply it correctly as a patch. Instead, we use 'echo -e' to write
+	# the exact contents.
+unquote 'This is a test repo for versioned go.\nThere''s nothing useful here.\n\n	v0.0.0 - has pkg/p.go\n	v0.0.1 - has go.mod\n	\n	v1.0.0 - has pkg/p.go\n	v1.0.1 - has go.mod\n	v1.0.2 - has submod/pkg/p.go\n	v1.0.3 - has submod/go.mod\n	submod/v1.0.4 - same\n	submod/v1.0.5 - add requirement on v1.1.0\n	v1.1.0 - add requirement on submod/v1.0.5\n	\n	v2.0.0 - has pkg/p.go\n	v2.0.1 - has go.mod with v2 module path\n	v2.0.2 - has go.mod with v1 (no version) module path\n	v2.0.3 - has v2/go.mod with v2 module path\n	v2.0.5 - has go.mod AND v2/go.mod with v2 module path\n	'
+cp stdout README.md
+mkdir v2/pkg
+echo 'package q'
+cp stdout v2/pkg/q.go
+git add README.md v2/pkg/q.go
+git commit -m 'add q'
+git tag v2.0.6
+
+git checkout --detach mytag~1
+at 2018-07-18T21:21:27-04:00
+env GIT_AUTHOR_DATE=2018-02-19T18:10:06-05:00
+mkdir pkg
+echo 'package p // pkg/p.go'
+cp stdout pkg/p.go
+git add pkg/p.go
+unquote 'add pkg/p.go\n\nv2\n'
+cp stdout COMMIT_MSG
+git commit -F COMMIT_MSG
+git tag v2.0.0
+
+git checkout master
+
+git show-ref --tags --heads
+cmp stdout .git-refs
+
+-- .git-refs --
+a08abb797a6764035a9314ed5f1d757e0224f3bf refs/heads/master
+80d85c5d4d17598a0e9055e7c175a32b415d6128 refs/tags/mytag
+8afe2b2efed96e0880ecd2a69b98a53b8c2738b6 refs/tags/submod/v1.0.4
+70fd92eaa4dacf82548d0c6099f5b853ae2c1fc8 refs/tags/submod/v1.0.5
+80d85c5d4d17598a0e9055e7c175a32b415d6128 refs/tags/v0.0.0
+5a115c66393dd8c4a5cc3215653850d7f5640d0e refs/tags/v0.0.1
+80d85c5d4d17598a0e9055e7c175a32b415d6128 refs/tags/v1.0.0
+5a115c66393dd8c4a5cc3215653850d7f5640d0e refs/tags/v1.0.1
+2e38a1a347ba4d9e9946ec0ce480710ff445c919 refs/tags/v1.0.2
+8afe2b2efed96e0880ecd2a69b98a53b8c2738b6 refs/tags/v1.0.3
+b769f2de407a4db81af9c5de0a06016d60d2ea09 refs/tags/v1.1.0
+45f53230a74ad275c7127e117ac46914c8126160 refs/tags/v2.0.0
+ea65f87c8f52c15ea68f3bdd9925ef17e20d91e9 refs/tags/v2.0.1
+f7b23352af1cd750b11e4673b20b24c2d239430a refs/tags/v2.0.2
+f18795870fb14388a21ef3ebc1d75911c8694f31 refs/tags/v2.0.3
+1f863feb76bc7029b78b21c5375644838962f88d refs/tags/v2.0.4
+2f615117ce481c8efef46e0cc0b4b4dccfac8fea refs/tags/v2.0.5
+a01a0aef06cbd571294fc5451788cd4eadbfd651 refs/tags/v2.0.6
+-- LICENSE --
+Copyright (c) 2009 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+   * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+   * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-- README.md --
+This is a test repo for versioned go.
+There's nothing useful here.
+-- 0001-submod-go.mod-add-require-vgotest1-v1.1.0.patch --
+From 70fd92eaa4dacf82548d0c6099f5b853ae2c1fc8 Mon Sep 17 00:00:00 2001
+From: Russ Cox <[email protected]>
+Date: Mon, 19 Feb 2018 18:12:59 -0500
+Subject: [PATCH] submod/go.mod: add require vgotest1 v1.1.0
+
+---
+ submod/go.mod | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/submod/go.mod b/submod/go.mod
+index 7b18d93..c88de0f 100644
+--- a/submod/go.mod
++++ b/submod/go.mod
+@@ -1 +1,2 @@
+ module "github.com/vgotest1/submod" // submod/go.mod
++require "github.com/vgotest1" v1.1.0
+--
+2.36.1.838.g23b219f8e3
+-- 0002-go.mod-add-require-submod-v1.0.5.patch --
+From b769f2de407a4db81af9c5de0a06016d60d2ea09 Mon Sep 17 00:00:00 2001
+From: Russ Cox <[email protected]>
+Date: Mon, 19 Feb 2018 18:13:36 -0500
+Subject: [PATCH] go.mod: add require submod v1.0.5
+
+---
+ go.mod | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/go.mod b/go.mod
+index ac7a6d7..6118671 100644
+--- a/go.mod
++++ b/go.mod
+@@ -1 +1,2 @@
+ module "github.com/rsc/vgotest1" // root go.mod
++require "github.com/rsc/vgotest1/submod" v1.0.5
+--
+2.36.1.838.g23b219f8e3
diff --git a/src/cmd/go/testdata/vcstest/go/custom-hg-hello.txt b/src/cmd/go/testdata/vcstest/go/custom-hg-hello.txt
new file mode 100644
index 0000000..40b1ef6
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/go/custom-hg-hello.txt
@@ -0,0 +1,4 @@
+handle dir
+
+-- index.html --
+<meta name="go-import" content="vcs-test.golang.org/go/custom-hg-hello hg https://vcs-test.golang.org/hg/custom-hg-hello">
diff --git a/src/cmd/go/testdata/vcstest/go/insecure.txt b/src/cmd/go/testdata/vcstest/go/insecure.txt
new file mode 100644
index 0000000..6eb83c3
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/go/insecure.txt
@@ -0,0 +1,6 @@
+handle dir
+
+-- index.html --
+<!DOCTYPE html>
+<html>
+<meta name="go-import" content="vcs-test.golang.org/insecure/go/insecure git https://vcs-test.golang.org/git/insecurerepo">
diff --git a/src/cmd/go/testdata/vcstest/go/missingrepo.txt b/src/cmd/go/testdata/vcstest/go/missingrepo.txt
new file mode 100644
index 0000000..9db6c14
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/go/missingrepo.txt
@@ -0,0 +1,18 @@
+handle dir
+
+-- missingrepo-git/index.html --
+<!DOCTYPE html>
+<html>
+<meta name="go-import" content="vcs-test.golang.org/go/missingrepo/missingrepo-git git https://vcs-test.golang.org/git/missingrepo">
+-- missingrepo-git/notmissing/index.html --
+<!DOCTYPE html>
+<html>
+<meta name="go-import" content="vcs-test.golang.org/go/missingrepo/missingrepo-git/notmissing git https://vcs-test.golang.org/git/mainonly">
+-- missingrepo-git-ssh/index.html --
+<!DOCTYPE html>
+<html>
+<meta name="go-import" content="vcs-test.golang.org/go/missingrepo/missingrepo-git-ssh git ssh://nonexistent.vcs-test.golang.org/git/missingrepo">
+-- missingrepo-git-ssh/notmissing/index.html --
+<!DOCTYPE html>
+<html>
+<meta name="go-import" content="vcs-test.golang.org/go/missingrepo/missingrepo-git-ssh/notmissing git https://vcs-test.golang.org/git/mainonly">
diff --git a/src/cmd/go/testdata/vcstest/go/mod/gitrepo1.txt b/src/cmd/go/testdata/vcstest/go/mod/gitrepo1.txt
new file mode 100644
index 0000000..0e727d3
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/go/mod/gitrepo1.txt
@@ -0,0 +1,6 @@
+handle dir
+
+-- index.html --
+<!DOCTYPE html>
+<html>
+<meta name="go-import" content="vcs-test.golang.org/go/mod/gitrepo1 git https://vcs-test.golang.org/git/gitrepo1">
diff --git a/src/cmd/go/testdata/vcstest/go/modauth404.txt b/src/cmd/go/testdata/vcstest/go/modauth404.txt
new file mode 100644
index 0000000..51f25a9
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/go/modauth404.txt
@@ -0,0 +1,6 @@
+handle dir
+
+-- index.html --
+<!DOCTYPE html>
+<html>
+<meta name="go-import" content="vcs-test.golang.org/go/modauth404 mod https://vcs-test.golang.org/auth/or404">
diff --git a/src/cmd/go/testdata/vcstest/go/test1-svn-git.txt b/src/cmd/go/testdata/vcstest/go/test1-svn-git.txt
new file mode 100644
index 0000000..42dc949
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/go/test1-svn-git.txt
@@ -0,0 +1,30 @@
+handle dir
+
+-- aaa/index.html --
+<!DOCTYPE html>
+<html>
+<meta name="go-import" content="vcs-test.golang.org/go/test1-svn-git svn https://vcs-test.golang.org/svn/test1-svn-git">
+-- git-README-only/index.html --
+<!DOCTYPE html>
+<html>
+<meta name="go-import" content="vcs-test.golang.org/go/test1-svn-git/git-README-only git https://vcs-test.golang.org/git/README-only">
+-- git-README-only/other/index.html --
+<!DOCTYPE html>
+<html>
+<meta name="go-import" content="vcs-test.golang.org/go/test1-svn-git/git-README-only git https://vcs-test.golang.org/git/README-only">
+-- git-README-only/pkg/index.html --
+<!DOCTYPE html>
+<html>
+<meta name="go-import" content="vcs-test.golang.org/go/test1-svn-git/git-README-only git https://vcs-test.golang.org/git/README-only">
+-- index.html --
+<!DOCTYPE html>
+<html>
+<meta name="go-import" content="vcs-test.golang.org/go/test1-svn-git svn https://vcs-test.golang.org/svn/test1-svn-git">
+-- other/index.html --
+<!DOCTYPE html>
+<html>
+<meta name="go-import" content="vcs-test.golang.org/go/test1-svn-git svn https://vcs-test.golang.org/svn/test1-svn-git">
+-- tiny/index.html --
+<!DOCTYPE html>
+<html>
+<meta name="go-import" content="vcs-test.golang.org/go/test1-svn-git svn https://vcs-test.golang.org/svn/test1-svn-git">
diff --git a/src/cmd/go/testdata/vcstest/go/test2-svn-git.txt b/src/cmd/go/testdata/vcstest/go/test2-svn-git.txt
new file mode 100644
index 0000000..8aae5c8
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/go/test2-svn-git.txt
@@ -0,0 +1,26 @@
+handle dir
+
+-- test2main/index.html --
+<!DOCTYPE html>
+<html>
+<meta name="go-import" content="vcs-test.golang.org/go/test2-svn-git/test2main git https://vcs-test.golang.org/git/test2main">
+-- test2pkg/index.html --
+<!DOCTYPE html>
+<html>
+<meta name="go-import" content="vcs-test.golang.org/go/test2-svn-git/test2pkg git https://vcs-test.golang.org/git/README-only">
+-- test2pkg/pkg/index.html --
+<!DOCTYPE html>
+<html>
+<meta name="go-import" content="vcs-test.golang.org/go/test2-svn-git/test2pkg git https://vcs-test.golang.org/git/README-only">
+-- test2PKG/index.html --
+<!DOCTYPE html>
+<html>
+<meta name="go-import" content="vcs-test.golang.org/go/test2-svn-git/test2PKG svn https://vcs-test.golang.org/svn/test2-svn-git">
+-- test2PKG/p1/index.html --
+<!DOCTYPE html>
+<html>
+<meta name="go-import" content="vcs-test.golang.org/go/test2-svn-git/test2PKG svn https://vcs-test.golang.org/svn/test2-svn-git">
+-- test2PKG/pkg/index.html --
+<!DOCTYPE html>
+<html>
+<meta name="go-import" content="vcs-test.golang.org/go/test2-svn-git/test2PKG svn https://vcs-test.golang.org/svn/test2-svn-git">
diff --git a/src/cmd/go/testdata/vcstest/go/v2module.txt b/src/cmd/go/testdata/vcstest/go/v2module.txt
new file mode 100644
index 0000000..abcf2fd
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/go/v2module.txt
@@ -0,0 +1,6 @@
+handle dir
+
+-- v2/index.html --
+<!DOCTYPE html>
+<html>
+<meta name="go-import" content="vcs-test.golang.org/go/v2module/v2 git https://vcs-test.golang.org/git/v2repo">
diff --git a/src/cmd/go/testdata/vcstest/hg/custom-hg-hello.txt b/src/cmd/go/testdata/vcstest/hg/custom-hg-hello.txt
new file mode 100644
index 0000000..572cbdf
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/hg/custom-hg-hello.txt
@@ -0,0 +1,17 @@
+handle hg
+hg init
+
+hg add hello.go
+hg commit --user 'Russ Cox <[email protected]>' --date '2017-10-10T19:39:36-04:00' --message 'hello'
+
+hg log -r ':' --template '{node|short} {desc|strip|firstline}\n'
+cmp stdout .hg-log
+
+-- .hg-log --
+a8c8e7a40da9 hello
+-- hello.go --
+package main // import "vcs-test.golang.org/go/custom-hg-hello"
+
+func main() {
+	println("hello")
+}
diff --git a/src/cmd/go/testdata/vcstest/hg/hello.txt b/src/cmd/go/testdata/vcstest/hg/hello.txt
new file mode 100644
index 0000000..10f114e
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/hg/hello.txt
@@ -0,0 +1,17 @@
+handle hg
+hg init
+
+hg add hello.go
+hg commit --user 'bwk' --date '2017-09-21T21:14:14-04:00' --message 'hello world'
+
+hg log -r ':' --template '{node|short} {desc|strip|firstline}\n'
+cmp stdout .hg-log
+
+-- .hg-log --
+e483a7d9f8c9 hello world
+-- hello.go --
+package main
+
+func main() {
+	println("hello, world")
+}
diff --git a/src/cmd/go/testdata/vcstest/hg/hgrepo1.txt b/src/cmd/go/testdata/vcstest/hg/hgrepo1.txt
new file mode 100644
index 0000000..1e4b83a
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/hg/hgrepo1.txt
@@ -0,0 +1,153 @@
+handle hg
+
+mkdir git
+cd git
+
+env GIT_AUTHOR_NAME='Russ Cox'
+env GIT_AUTHOR_EMAIL='[email protected]'
+env GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME
+env GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL
+
+git init
+
+at 2018-04-17T15:43:22-04:00
+unquote ''
+cp stdout README
+git add README
+git commit -a -m 'empty README'
+git branch -m master
+git tag v1.2.3
+
+at 2018-04-17T15:45:48-04:00
+git branch v2
+git checkout v2
+echo 'v2'
+cp stdout v2
+git add v2
+git commit -a -m 'v2'
+git tag v2.3
+git tag v2.0.1
+git branch v2.3.4
+git tag branch-v2.3.4
+
+at 2018-04-17T16:00:19-04:00
+echo 'intermediate'
+cp stdout foo.txt
+git add foo.txt
+git commit -a -m 'intermediate'
+
+at 2018-04-17T16:00:32-04:00
+echo 'another'
+cp stdout another.txt
+git add another.txt
+git commit -a -m 'another'
+git tag v2.0.2
+git tag branch-v2
+
+at 2018-04-17T16:16:52-04:00
+git checkout master
+git branch v3
+git checkout v3
+mkdir v3/sub/dir
+echo 'v3/sub/dir/file'
+cp stdout v3/sub/dir/file.txt
+git add v3
+git commit -a -m 'add v3/sub/dir/file.txt'
+git tag branch-v3
+
+at 2018-04-17T22:23:00-04:00
+git checkout master
+git tag -a v1.2.4-annotated -m 'v1.2.4-annotated'
+
+cd ..
+
+hg init
+hg convert --datesort ./git .
+rm ./git
+
+hg update -C v2
+hg branch v2
+unquote ''
+cp stdout dummy
+hg add dummy
+hg commit --user 'Russ Cox <[email protected]>' --date '2018-06-27T12:15:24-04:00' -m 'dummy'
+
+# 'hg convert' blindly stamps a tag-update commit at the end of whatever branch
+# happened to contain the last converted commit — in this case, v3. However, the
+# original vcs-test.golang.org copy of this repo had this commit on the v3
+# branch as a descendent of 'add v3/sub/dir/file.txt', so that's where we put it
+# here. That leaves the convert-repo 'update tags' commit only reachable as the
+# head of the default branch.
+hg update -r 4
+
+hg branch v3
+unquote ''
+cp stdout dummy
+hg add dummy
+hg commit --user 'Russ Cox <[email protected]>' --date '2018-06-27T12:15:45-04:00' -m 'dummy'
+
+hg update v2.3.4
+hg branch v2.3.4
+unquote ''
+cp stdout dummy
+hg add dummy
+hg commit --user 'Russ Cox <[email protected]>' --date '2018-06-27T12:16:10-04:00' -m 'dummy'
+
+hg tag --user 'Russ Cox <[email protected]>' --date '2018-06-27T12:16:30-04:00' -m 'Removed tag branch-v2, branch-v3, branch-v2.3.4' --remove branch-v2 branch-v3 branch-v2.3.4
+
+# Adding commits to the above branches updates both the branch heads and the
+# corresponding bookmarks.
+# But apparently at some point it did not do so? The original copy of this repo
+# had bookmarks pointing to the base of each branch instead of the tip. 🤔
+# Either way, force the bookmarks we care about to match the original copy of
+# the repo.
+hg book v2 -r 3 --force
+hg book v2.3.4 -r 1 --force
+hg book v3 -r 5 --force
+
+hg log -G --debug
+
+hg tags
+cmp stdout .hg-tags
+
+	# 'hg convert' leaves an 'update tags' commit on the default branch, and that
+	# commit always uses the current date (so is not reproducible). Fortunately,
+	# that commit lands on the 'default' branch and is not tagged as 'tip', so it
+	# seems to be mostly harmless. However, because it is nondeterministic we
+	# should avoid listing it here.
+	#
+	# Unfortunately, some of our builders are still running Debian 9 “Stretch”,
+	# which shipped with a version of 'hg' that does not support 'hg branch -r'
+	# to list branches for specific versions. Although Stretch is past its
+	# end-of-life date, we need to keep the builders happy until they can be
+	# turned down (https://go.dev/issue/56414).
+hg branches
+? cmp stdout .hg-branches
+stdout 'v2\s+6:9a4f43d231ec'
+stdout 'v2.3.4\s+9:18518c07eb8e'
+stdout 'v3\s+7:a2cad8a2b1bb'
+stdout 'default\s+5:'
+
+# Likewise, bookmark v3 ends up on the nondeterministic commit.
+hg bookmarks
+? cmp stdout .hg-bookmarks
+stdout 'master\s+0:41964ddce118'
+stdout 'v2\s+3:8f49ee7a6ddc'
+stdout 'v2.3.4\s+1:88fde824ec8b'
+stdout 'v3\s+5:.*'
+
+-- .hg-branches --
+v2.3.4                         9:18518c07eb8e
+v3                             7:a2cad8a2b1bb
+v2                             6:9a4f43d231ec
+-- .hg-tags --
+tip                                9:18518c07eb8e
+v2.0.2                             3:8f49ee7a6ddc
+v2.3                               1:88fde824ec8b
+v2.0.1                             1:88fde824ec8b
+v1.2.4-annotated                   0:41964ddce118
+v1.2.3                             0:41964ddce118
+-- .hg-bookmarks --
+   master                    0:41964ddce118
+   v2                        3:8f49ee7a6ddc
+   v2.3.4                    1:88fde824ec8b
diff --git a/src/cmd/go/testdata/vcstest/hg/vgotest1.txt b/src/cmd/go/testdata/vcstest/hg/vgotest1.txt
new file mode 100644
index 0000000..e53c5e0
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/hg/vgotest1.txt
@@ -0,0 +1,322 @@
+handle hg
+
+cd git
+
+env GIT_AUTHOR_NAME='Russ Cox'
+env GIT_AUTHOR_EMAIL='[email protected]'
+env GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME
+env GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL
+
+git init
+
+# 0
+at 2018-02-19T17:21:09-05:00
+git add LICENSE README.md
+git commit -m 'initial commit'
+git branch -m master
+
+# 1
+git branch mybranch
+git checkout mybranch
+
+at 2018-02-19T18:10:06-05:00
+mkdir pkg
+echo 'package p // pkg/p.go'
+cp stdout pkg/p.go
+git add pkg/p.go
+git commit -m 'add pkg/p.go'
+git tag v0.0.0
+git tag v1.0.0
+git tag v2.0.0
+git tag mytag
+
+git branch v1
+git branch v2
+git checkout v2
+
+# 2
+at 2018-02-19T18:14:23-05:00
+mkdir v2
+echo 'module "github.com/rsc/vgotest1/v2" // root go.mod'
+cp stdout go.mod
+git add go.mod
+git commit -m 'go.mod v2'
+git tag v2.0.1
+
+# 3
+at 2018-02-19T18:15:11-05:00
+mkdir submod/pkg
+echo 'package p // submod/pkg/p.go'
+cp stdout submod/pkg/p.go
+git add submod/pkg/p.go
+git commit -m 'submod/pkg/p.go'
+git tag v2.0.2
+
+# 4
+at 2018-02-19T18:16:04-05:00
+echo 'module "github.com/rsc/vgotest" // v2/go.mod'
+cp stdout v2/go.mod
+git add v2/go.mod
+git commit -m 'v2/go.mod: bad go.mod (no version)'
+git tag v2.0.3
+
+# 5
+at 2018-02-19T19:03:38-05:00
+env GIT_AUTHOR_DATE=2018-02-19T18:16:38-05:00
+echo 'module "github.com/rsc/vgotest1/v2" // v2/go.mod'
+cp stdout v2/go.mod
+git add v2/go.mod
+git commit -m 'v2/go.mod: fix'
+git tag v2.0.4
+
+# 6
+at 2018-02-19T19:03:59-05:00
+env GIT_AUTHOR_DATE=2018-02-19T18:17:02-05:00
+echo 'module "github.com/rsc/vgotest1" // root go.mod'
+cp stdout go.mod
+git add go.mod
+git commit -m 'go.mod: drop v2'
+git tag v2.0.5
+
+git checkout v1
+
+# 7
+at 2018-02-19T18:10:28-05:00
+echo 'module "github.com/rsc/vgotest1" // root go.mod'
+cp stdout go.mod
+git add go.mod
+git commit -m 'go.mod'
+git tag v0.0.1
+git tag v1.0.1
+
+# 8
+at 2018-02-19T18:11:28-05:00
+mkdir submod/pkg
+echo 'package pkg // submod/pkg/p.go'
+cp stdout submod/pkg/p.go
+git add submod
+git commit -m 'submod/pkg/p.go'
+git tag v1.0.2
+
+# 9
+at 2018-02-19T18:12:07-05:00
+echo 'module "github.com/vgotest1/submod" // submod/go.mod'
+cp stdout submod/go.mod
+git add submod/go.mod
+git commit -m 'submod/go.mod'
+git tag v1.0.3
+git tag submod/v1.0.4
+
+# 10
+at 2018-02-19T18:12:59-05:00
+git apply ../0001-submod-go.mod-add-require-vgotest1-v1.1.0.patch
+git commit -a -m 'submod/go.mod: add require vgotest1 v1.1.0'
+git tag submod/v1.0.5
+
+# 11
+at 2018-02-19T18:13:36-05:00
+git apply ../0002-go.mod-add-require-submod-v1.0.5.patch
+git commit -a -m 'go.mod: add require submod v1.0.5'
+git tag v1.1.0
+
+git checkout master
+
+# 12
+at 2018-02-19T17:23:01-05:00
+mkdir pkg
+echo 'package pkg'
+cp stdout pkg/p.go
+git add pkg/p.go
+git commit -m 'pkg: add'
+
+# 13
+at 2018-02-19T17:30:23-05:00
+env GIT_AUTHOR_DATE=2018-02-19T17:24:48-05:00
+echo 'module "github.com/vgotest1/v2"'
+cp stdout go.mod
+git add go.mod
+git commit -m 'add go.mod'
+
+# 14
+at 2018-02-19T17:30:45-05:00
+echo 'module "github.com/vgotest1"'
+cp stdout go.mod
+git add go.mod
+git commit -m 'bad mod path'
+
+# 15
+at 2018-02-19T17:31:34-05:00
+mkdir v2
+echo 'module "github.com/vgotest1/v2"'
+cp stdout v2/go.mod
+git add v2/go.mod
+git commit -m 'add v2/go.mod'
+
+# 16
+at 2018-02-19T17:32:37-05:00
+echo 'module "github.com/vgotest1/v2"'
+cp stdout go.mod
+git add go.mod
+git commit -m 'say v2 in root go.mod'
+
+# 17
+at 2018-02-19T17:51:24-05:00
+	# README.md at this commit lacked a trailing newline, so 'git apply' can't
+	# seem to apply it correctly as a patch. Instead, we use 'unquote' to write
+	# the exact contents.
+unquote 'This is a test repo for versioned go.\nThere''s nothing useful here.\n\n	v0.0.0 - has pkg/p.go\n	v0.0.1 - has go.mod\n	\n	v1.0.0 - has pkg/p.go\n	v1.0.1 - has go.mod\n	v1.0.2 - has submod/pkg/p.go\n	v1.0.3 - has submod/go.mod\n	submod/v1.0.4 - same\n	submod/v1.0.5 - add requirement on v1.1.0\n	v1.1.0 - add requirement on submod/v1.0.5\n	\n	v2.0.0 - has pkg/p.go\n	v2.0.1 - has go.mod with v2 module path\n	v2.0.2 - has go.mod with v1 (no version) module path\n	v2.0.3 - has v2/go.mod with v2 module path\n	v2.0.5 - has go.mod AND v2/go.mod with v2 module path\n	'
+cp stdout README.md
+mkdir v2/pkg
+echo 'package q'
+cp stdout v2/pkg/q.go
+git add README.md v2/pkg/q.go
+git commit -m 'add q'
+git tag v2.0.6
+
+cd ..
+
+hg init
+hg convert ./git .
+rm ./git
+
+# Note: commit #18 is an 'update tags' commit automatically generated by 'hg
+# convert'. We have no control over its timestamp, so it and its descendent
+# commit #19 both end up with unpredictable commit hashes.
+#
+# Fortunately, these commits don't seem to matter for the purpose of reproducing
+# the final branches and heads from the original copy of this repo.
+
+# 19
+hg update -C -r 18
+hg tag --user 'Russ Cox <[email protected]>' --date '2018-07-18T21:24:45-04:00' -m 'Removed tag v2.0.0' --remove v2.0.0
+
+# 20
+hg branch default
+hg update -C -r 1
+echo 'v2'
+cp stdout v2
+hg add v2
+hg commit --user 'Russ Cox <[email protected]>' --date '2018-07-18T21:25:08-04:00' -m 'v2.0.0'
+
+# 21
+hg tag --user 'Russ Cox <[email protected]>' --date '2018-07-18T21:25:13-04:00' -r f0ababb31f75 -m 'Added tag v2.0.0 for changeset f0ababb31f75' v2.0.0
+
+# 22
+hg tag --user 'Russ Cox <[email protected]>' --date '2018-07-18T21:26:02-04:00' -m 'Removed tag v2.0.0' --remove v2.0.0
+
+# 23
+hg update -C -r 1
+echo 'v2'
+cp stdout v2
+hg add v2
+hg commit --user 'Russ Cox <[email protected]>' --date '2018-07-19T01:21:27+00:00' -m 'v2'
+
+# 24
+hg tag --user 'Russ Cox <[email protected]>' --date '2018-07-18T21:26:33-04:00' -m 'Added tag v2.0.0 for changeset 814fce58e83a' -r 814fce58e83a v2.0.0
+
+hg book --delete v1
+hg book --delete v2
+hg book --force -r 16 master
+
+hg log -G --debug
+
+hg tags
+cmp stdout .hg-tags
+hg branches
+cmp stdout .hg-branches
+hg bookmarks
+cmp stdout .hg-bookmarks
+
+-- .hg-tags --
+tip                               24:645b06ca536d
+v2.0.0                            23:814fce58e83a
+v2.0.6                            17:3d4b89a2d059
+v1.1.0                            11:92c7eb888b4f
+submod/v1.0.5                     10:f3f560a6065c
+v1.0.3                             9:4e58084d459a
+submod/v1.0.4                      9:4e58084d459a
+v1.0.2                             8:3ccdce3897f9
+v1.0.1                             7:7890ea771ced
+v0.0.1                             7:7890ea771ced
+v2.0.5                             6:879ea98f7743
+v2.0.4                             5:bf6388016230
+v2.0.3                             4:a9ad6d1d14eb
+v2.0.2                             3:de3663002f0f
+v2.0.1                             2:f1fc0f22021b
+v1.0.0                             1:e125018e286a
+v0.0.0                             1:e125018e286a
+mytag                              1:e125018e286a
+-- .hg-branches --
+default                       24:645b06ca536d
+-- .hg-bookmarks --
+   master                    16:577bde103b24
+   mybranch                  1:e125018e286a
+-- git/LICENSE --
+Copyright (c) 2009 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+   * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+   * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-- git/README.md --
+This is a test repo for versioned go.
+There's nothing useful here.
+-- 0001-submod-go.mod-add-require-vgotest1-v1.1.0.patch --
+From 70fd92eaa4dacf82548d0c6099f5b853ae2c1fc8 Mon Sep 17 00:00:00 2001
+From: Russ Cox <[email protected]>
+Date: Mon, 19 Feb 2018 18:12:59 -0500
+Subject: [PATCH] submod/go.mod: add require vgotest1 v1.1.0
+
+---
+ submod/go.mod | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/submod/go.mod b/submod/go.mod
+index 7b18d93..c88de0f 100644
+--- a/submod/go.mod
++++ b/submod/go.mod
+@@ -1 +1,2 @@
+ module "github.com/vgotest1/submod" // submod/go.mod
++require "github.com/vgotest1" v1.1.0
+-- 
+2.36.1.838.g23b219f8e3
+-- 0002-go.mod-add-require-submod-v1.0.5.patch --
+From b769f2de407a4db81af9c5de0a06016d60d2ea09 Mon Sep 17 00:00:00 2001
+From: Russ Cox <[email protected]>
+Date: Mon, 19 Feb 2018 18:13:36 -0500
+Subject: [PATCH] go.mod: add require submod v1.0.5
+
+---
+ go.mod | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/go.mod b/go.mod
+index ac7a6d7..6118671 100644
+--- a/go.mod
++++ b/go.mod
+@@ -1 +1,2 @@
+ module "github.com/rsc/vgotest1" // root go.mod
++require "github.com/rsc/vgotest1/submod" v1.0.5
+-- 
+2.36.1.838.g23b219f8e3
diff --git a/src/cmd/go/testdata/vcstest/insecure.txt b/src/cmd/go/testdata/vcstest/insecure.txt
new file mode 100644
index 0000000..cbfb1b9
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/insecure.txt
@@ -0,0 +1 @@
+handle insecure
diff --git a/src/cmd/go/testdata/vcstest/svn/hello.txt b/src/cmd/go/testdata/vcstest/svn/hello.txt
new file mode 100644
index 0000000..c6ebd8d
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/svn/hello.txt
@@ -0,0 +1,87 @@
+handle svn
+
+mkdir db/transactions
+mkdir db/txn-protorevs
+chmod 0755 hooks/pre-revprop-change
+
+env ROOT=$PWD
+cd .checkout
+[GOOS:windows] svn checkout file:///$ROOT .
+[!GOOS:windows] svn checkout file://$ROOT .
+
+svn add hello.go
+svn commit --file MSG
+svn propset svn:author 'rsc' --revprop -r1
+svn propset svn:date '2017-09-22T01:12:45.861368Z' --revprop -r1
+
+svn update
+svn log --xml
+
+[GOOS:windows] replace '\n' '\r\n' .svn-log
+cmp stdout .svn-log
+
+-- .checkout/MSG --
+hello world
+
+-- .checkout/hello.go --
+package main
+
+func main() {
+	println("hello, world")
+}
+-- .checkout/.svn-log --
+<?xml version="1.0" encoding="UTF-8"?>
+<log>
+<logentry
+   revision="1">
+<author>rsc</author>
+<date>2017-09-22T01:12:45.861368Z</date>
+<msg>hello world
+
+</msg>
+</logentry>
+</log>
+-- conf/authz --
+-- conf/passwd --
+-- conf/svnserve.conf --
+-- db/current --
+0
+-- db/format --
+6
+layout sharded 1000
+-- db/fs-type --
+fsfs
+-- db/fsfs.conf --
+-- db/min-unpacked-rev --
+0
+-- db/revprops/0/0 --
+K 8
+svn:date
+V 27
+2017-09-22T01:11:53.895835Z
+END
+-- db/revs/0/0 --
+PLAIN
+END
+ENDREP
+id: 0.0.r0/17
+type: dir
+count: 0
+text: 0 0 4 4 2d2977d1c96f487abe4a1e202dd03b4e
+cpath: /
+
+
+17 107
+-- db/txn-current --
+0
+-- db/txn-current-lock --
+-- db/uuid --
+53cccb44-0fca-40a2-b0c5-acaf9e75039a
+-- db/write-lock --
+-- format --
+5
+-- hooks/pre-revprop-change --
+#!/bin/sh
+
+-- hooks/pre-revprop-change.bat --
+@exit
diff --git a/src/cmd/go/testdata/vcstest/svn/nonexistent.txt b/src/cmd/go/testdata/vcstest/svn/nonexistent.txt
new file mode 100644
index 0000000..a71ecf1
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/svn/nonexistent.txt
@@ -0,0 +1,5 @@
+handle svn
+
+# For this path, we turn on the svn handler but don't actually create the repo.
+# svnserve should use the svn protocol to tell the client that the repo doesn't
+# actually exist.
diff --git a/src/cmd/go/testdata/vcstest/svn/test1-svn-git.txt b/src/cmd/go/testdata/vcstest/svn/test1-svn-git.txt
new file mode 100644
index 0000000..2b94201
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/svn/test1-svn-git.txt
@@ -0,0 +1,188 @@
+handle svn
+
+# Note: this repo script does not produce a byte-for-byte copy of the original.
+#
+# The 'git init' operation in the nested Git repo creates some sample files
+# whose contents depend on the exact Git version in use, and the steps we take
+# to construct a fake 'git clone' status don't produce some log files that
+# a real 'git clone' leaves behind.
+#
+# However, the repo is probably accurate enough for the tests that need it.
+
+env GIT_AUTHOR_NAME='Russ Cox'
+env GIT_AUTHOR_EMAIL='[email protected]'
+env GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME
+env GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL
+
+mkdir db/transactions
+mkdir db/txn-protorevs
+chmod 0755 hooks/pre-revprop-change
+
+env ROOT=$PWD
+cd .checkout
+[GOOS:windows] svn checkout file:///$ROOT .
+[!GOOS:windows] svn checkout file://$ROOT .
+
+cd git-README-only
+git init
+git config --add core.ignorecase true
+git config --add core.precomposeunicode true
+
+git add README
+at 2017-09-22T11:39:03-04:00
+git commit -a -m 'README'
+git branch -m master
+
+git rev-parse HEAD
+stdout '^7f800d2ac276dd7042ea0e8d7438527d236fd098$'
+
+	# Fake a clone from an origin repo at this commit.
+git remote add origin https://vcs-test.swtch.com/git/README-only
+mkdir .git/refs/remotes/origin
+echo 'ref: refs/remotes/origin/master'
+cp stdout .git/refs/remotes/origin/HEAD
+unquote '# pack-refs with: peeled fully-peeled \n7f800d2ac276dd7042ea0e8d7438527d236fd098 refs/remotes/origin/master\n'
+cp stdout .git/packed-refs
+git branch --set-upstream-to=origin/master
+
+git add pkg/pkg.go
+at 2017-09-22T11:41:28-04:00
+git commit -a -m 'add pkg'
+
+git log --oneline --decorate=short
+cmp stdout ../.git-log
+
+cd ..
+svn add git-README-only
+svn commit -m 'add modified git-README-only'
+svn propset svn:author rsc --revprop -r1
+svn propset svn:date 2017-09-22T15:41:54.145716Z --revprop -r1
+
+svn add pkg.go
+svn commit -m 'use git-README-only/pkg'
+svn propset svn:author rsc --revprop -r2
+svn propset svn:date 2017-09-22T15:49:11.130406Z --revprop -r2
+
+svn add other
+svn commit -m 'add other'
+svn propset svn:author rsc --revprop -r3
+svn propset svn:date 2017-09-22T16:56:16.665173Z --revprop -r3
+
+svn add tiny
+svn commit -m 'add tiny'
+svn propset svn:author rsc --revprop -r4
+svn propset svn:date 2017-09-27T17:48:18.350817Z --revprop -r4
+
+cd git-README-only
+git remote set-url origin https://vcs-test.golang.org/git/README-only
+cd ..
+replace 'vcs-test.swtch.com' 'vcs-test.golang.org' other/pkg.go
+replace 'vcs-test.swtch.com' 'vcs-test.golang.org' pkg.go
+svn commit -m 'move from vcs-test.swtch.com to vcs-test.golang.org'
+svn propset svn:author rsc --revprop -r5
+svn propset svn:date 2017-10-04T15:08:26.291877Z --revprop -r5
+
+svn update
+svn log --xml
+
+[GOOS:windows] replace '\n' '\r\n' .svn-log
+cmp stdout .svn-log
+
+-- .checkout/git-README-only/pkg/pkg.go --
+package pkg
+const Message = "code not in git-README-only"
+-- .checkout/git-README-only/README --
+README
+-- .checkout/.git-log --
+ab9f66b (HEAD -> master) add pkg
+7f800d2 (origin/master, origin/HEAD) README
+-- .checkout/pkg.go --
+package p
+
+import "vcs-test.swtch.com/go/test1-svn-git/git-README-only/pkg"
+
+const _ = pkg.Message
+-- .checkout/other/pkg.go --
+package other
+
+import _ "vcs-test.swtch.com/go/test1-svn-git/git-README-only/other"
+-- .checkout/tiny/tiny.go --
+package tiny
+-- .checkout/.svn-log --
+<?xml version="1.0" encoding="UTF-8"?>
+<log>
+<logentry
+   revision="5">
+<author>rsc</author>
+<date>2017-10-04T15:08:26.291877Z</date>
+<msg>move from vcs-test.swtch.com to vcs-test.golang.org</msg>
+</logentry>
+<logentry
+   revision="4">
+<author>rsc</author>
+<date>2017-09-27T17:48:18.350817Z</date>
+<msg>add tiny</msg>
+</logentry>
+<logentry
+   revision="3">
+<author>rsc</author>
+<date>2017-09-22T16:56:16.665173Z</date>
+<msg>add other</msg>
+</logentry>
+<logentry
+   revision="2">
+<author>rsc</author>
+<date>2017-09-22T15:49:11.130406Z</date>
+<msg>use git-README-only/pkg</msg>
+</logentry>
+<logentry
+   revision="1">
+<author>rsc</author>
+<date>2017-09-22T15:41:54.145716Z</date>
+<msg>add modified git-README-only</msg>
+</logentry>
+</log>
+-- conf/authz --
+-- conf/passwd --
+-- conf/svnserve.conf --
+-- db/current --
+0
+-- db/format --
+6
+layout sharded 1000
+-- db/fs-type --
+fsfs
+-- db/fsfs.conf --
+-- db/min-unpacked-rev --
+0
+-- db/revprops/0/0 --
+K 8
+svn:date
+V 27
+2017-09-22T01:11:53.895835Z
+END
+-- db/revs/0/0 --
+PLAIN
+END
+ENDREP
+id: 0.0.r0/17
+type: dir
+count: 0
+text: 0 0 4 4 2d2977d1c96f487abe4a1e202dd03b4e
+cpath: /
+
+
+17 107
+-- db/txn-current --
+0
+-- db/txn-current-lock --
+-- db/uuid --
+53cccb44-0fca-40a2-b0c5-acaf9e75039a
+-- db/write-lock --
+-- format --
+5
+-- hooks/pre-revprop-change --
+#!/bin/sh
+
+-- hooks/pre-revprop-change.bat --
+@exit
diff --git a/src/cmd/go/testdata/vcstest/svn/test2-svn-git.txt b/src/cmd/go/testdata/vcstest/svn/test2-svn-git.txt
new file mode 100644
index 0000000..bf82797
--- /dev/null
+++ b/src/cmd/go/testdata/vcstest/svn/test2-svn-git.txt
@@ -0,0 +1,154 @@
+handle svn
+
+# Note: this repo script does not produce a byte-for-byte copy of the original.
+#
+# The 'git init' operation in the nested Git repo creates some sample files
+# whose contents depend on the exact Git version in use, and the steps we take
+# to construct a fake 'git clone' status don't produce some log files that
+# a real 'git clone' leaves behind.
+#
+# However, the repo is probably accurate enough for the tests that need it.
+
+env GIT_AUTHOR_NAME='Russ Cox'
+env GIT_AUTHOR_EMAIL='[email protected]'
+env GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME
+env GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL
+
+mkdir db/transactions
+mkdir db/txn-protorevs
+chmod 0755 hooks/pre-revprop-change
+
+env ROOT=$PWD
+cd .checkout
+[GOOS:windows] svn checkout file:///$ROOT .
+[!GOOS:windows] svn checkout file://$ROOT .
+
+git init
+git config --add core.ignorecase true
+git config --add core.precomposeunicode true
+
+git add README
+at 2017-09-22T11:39:03-04:00
+git commit -a -m 'README'
+git branch -m master
+
+git rev-parse HEAD
+stdout '^7f800d2ac276dd7042ea0e8d7438527d236fd098$'
+
+	# Fake a clone from an origin repo at this commit.
+git remote add origin https://vcs-test.swtch.com/git/README-only
+mkdir .git/refs/remotes/origin
+echo 'ref: refs/remotes/origin/master'
+cp stdout .git/refs/remotes/origin/HEAD
+unquote '# pack-refs with: peeled fully-peeled \n7f800d2ac276dd7042ea0e8d7438527d236fd098 refs/remotes/origin/master\n'
+cp stdout .git/packed-refs
+git branch --set-upstream-to=origin/master
+
+git add pkg/pkg.go
+at 2017-09-22T11:41:28-04:00
+git commit -a -m 'add pkg'
+
+git log --oneline --decorate=short
+cmp stdout .git-log
+
+rm README
+
+svn add .git pkg
+svn commit -m 'git'
+svn propset svn:author rsc --revprop -r1
+svn propset svn:date 2017-09-27T18:00:52.201719Z --revprop -r1
+
+svn add p1
+svn commit -m 'add p1'
+svn propset svn:author rsc --revprop -r2
+svn propset svn:date 2017-09-27T18:16:14.650893Z --revprop -r2
+
+git remote set-url origin https://vcs-test.golang.org/git/README-only
+svn commit -m 'move from vcs-test.swtch.com to vcs-test.golang.org'
+svn propset svn:author rsc --revprop -r3
+svn propset svn:date 2017-10-04T15:09:35.963034Z --revprop -r3
+
+svn update
+svn log --xml
+
+[GOOS:windows] replace '\n' '\r\n' .svn-log
+cmp stdout .svn-log
+
+-- .checkout/.git-log --
+ab9f66b (HEAD -> master) add pkg
+7f800d2 (origin/master, origin/HEAD) README
+-- .checkout/p1/p1.go --
+package p1
+-- .checkout/pkg/pkg.go --
+package pkg
+const Message = "code not in git-README-only"
+-- .checkout/README --
+README
+-- .checkout/p1/p1.go --
+package p1
+-- .checkout/.svn-log --
+<?xml version="1.0" encoding="UTF-8"?>
+<log>
+<logentry
+   revision="3">
+<author>rsc</author>
+<date>2017-10-04T15:09:35.963034Z</date>
+<msg>move from vcs-test.swtch.com to vcs-test.golang.org</msg>
+</logentry>
+<logentry
+   revision="2">
+<author>rsc</author>
+<date>2017-09-27T18:16:14.650893Z</date>
+<msg>add p1</msg>
+</logentry>
+<logentry
+   revision="1">
+<author>rsc</author>
+<date>2017-09-27T18:00:52.201719Z</date>
+<msg>git</msg>
+</logentry>
+</log>
+-- conf/authz --
+-- conf/passwd --
+-- conf/svnserve.conf --
+-- db/current --
+0
+-- db/format --
+6
+layout sharded 1000
+-- db/fs-type --
+fsfs
+-- db/fsfs.conf --
+-- db/min-unpacked-rev --
+0
+-- db/revprops/0/0 --
+K 8
+svn:date
+V 27
+2017-09-22T01:11:53.895835Z
+END
+-- db/revs/0/0 --
+PLAIN
+END
+ENDREP
+id: 0.0.r0/17
+type: dir
+count: 0
+text: 0 0 4 4 2d2977d1c96f487abe4a1e202dd03b4e
+cpath: /
+
+
+17 107
+-- db/txn-current --
+0
+-- db/txn-current-lock --
+-- db/uuid --
+53cccb44-0fca-40a2-b0c5-acaf9e75039a
+-- db/write-lock --
+-- format --
+5
+-- hooks/pre-revprop-change --
+#!/bin/sh
+
+-- hooks/pre-revprop-change.bat --
+@exit
diff --git a/src/cmd/gofmt/rewrite.go b/src/cmd/gofmt/rewrite.go
index a98c6a0..0b7e211 100644
--- a/src/cmd/gofmt/rewrite.go
+++ b/src/cmd/gofmt/rewrite.go
@@ -199,7 +199,7 @@
 		// object pointers and token positions always match
 		return true
 	case callExprType:
-		// For calls, the Ellipsis fields (token.Position) must
+		// For calls, the Ellipsis fields (token.Pos) must
 		// match since that is how f(x) and f(x...) are different.
 		// Check them here but fall through for the remaining fields.
 		p := pattern.Interface().(*ast.CallExpr)
diff --git a/src/cmd/internal/archive/archive.go b/src/cmd/internal/archive/archive.go
index da1f293..d2c4f69 100644
--- a/src/cmd/internal/archive/archive.go
+++ b/src/cmd/internal/archive/archive.go
@@ -124,9 +124,9 @@
 
 func (r *objReader) init(f *os.File) {
 	r.a = &Archive{f, nil}
-	r.offset, _ = f.Seek(0, os.SEEK_CUR)
-	r.limit, _ = f.Seek(0, os.SEEK_END)
-	f.Seek(r.offset, os.SEEK_SET)
+	r.offset, _ = f.Seek(0, io.SeekCurrent)
+	r.limit, _ = f.Seek(0, io.SeekEnd)
+	f.Seek(r.offset, io.SeekStart)
 	r.b = bio.NewReader(f)
 }
 
@@ -227,7 +227,7 @@
 		r.readFull(r.tmp[:n])
 	} else {
 		// Seek, giving up buffered data.
-		r.b.MustSeek(r.offset+n, os.SEEK_SET)
+		r.b.MustSeek(r.offset+n, io.SeekStart)
 		r.offset += n
 	}
 }
@@ -435,7 +435,7 @@
 
 // AddEntry adds an entry to the end of a, with the content from r.
 func (a *Archive) AddEntry(typ EntryType, name string, mtime int64, uid, gid int, mode os.FileMode, size int64, r io.Reader) {
-	off, err := a.f.Seek(0, os.SEEK_END)
+	off, err := a.f.Seek(0, io.SeekEnd)
 	if err != nil {
 		log.Fatal(err)
 	}
diff --git a/src/cmd/internal/archive/archive_test.go b/src/cmd/internal/archive/archive_test.go
index bbaa72c..0e2c7bc 100644
--- a/src/cmd/internal/archive/archive_test.go
+++ b/src/cmd/internal/archive/archive_test.go
@@ -13,9 +13,7 @@
 	"internal/testenv"
 	"internal/xcoff"
 	"io"
-	"io/ioutil"
 	"os"
-	"os/exec"
 	"path/filepath"
 	"runtime"
 	"sync"
@@ -43,12 +41,12 @@
 	if err != nil {
 		return err
 	}
-	fis, err := ioutil.ReadDir(src)
+	entries, err := os.ReadDir(src)
 	if err != nil {
 		return err
 	}
-	for _, fi := range fis {
-		err = copyFile(filepath.Join(dst, fi.Name()), filepath.Join(src, fi.Name()))
+	for _, entry := range entries {
+		err = copyFile(filepath.Join(dst, entry.Name()), filepath.Join(src, entry.Name()))
 		if err != nil {
 			return err
 		}
@@ -96,7 +94,7 @@
 func buildGoobj(t *testing.T) goobjPaths {
 	buildOnce.Do(func() {
 		buildErr = func() (err error) {
-			buildDir, err = ioutil.TempDir("", "TestGoobj")
+			buildDir, err = os.MkdirTemp("", "TestGoobj")
 			if err != nil {
 				return err
 			}
@@ -114,15 +112,18 @@
 			go1src := filepath.Join("testdata", "go1.go")
 			go2src := filepath.Join("testdata", "go2.go")
 
-			out, err := exec.Command(gotool, "tool", "compile", "-p=p", "-o", go1obj, go1src).CombinedOutput()
+			importcfgfile := filepath.Join(buildDir, "importcfg")
+			testenv.WriteImportcfg(t, importcfgfile, nil)
+
+			out, err := testenv.Command(t, gotool, "tool", "compile", "-importcfg="+importcfgfile, "-p=p", "-o", go1obj, go1src).CombinedOutput()
 			if err != nil {
 				return fmt.Errorf("go tool compile -o %s %s: %v\n%s", go1obj, go1src, err, out)
 			}
-			out, err = exec.Command(gotool, "tool", "compile", "-p=p", "-o", go2obj, go2src).CombinedOutput()
+			out, err = testenv.Command(t, gotool, "tool", "compile", "-importcfg="+importcfgfile, "-p=p", "-o", go2obj, go2src).CombinedOutput()
 			if err != nil {
 				return fmt.Errorf("go tool compile -o %s %s: %v\n%s", go2obj, go2src, err, out)
 			}
-			out, err = exec.Command(gotool, "tool", "pack", "c", goarchive, go1obj, go2obj).CombinedOutput()
+			out, err = testenv.Command(t, gotool, "tool", "pack", "c", goarchive, go1obj, go2obj).CombinedOutput()
 			if err != nil {
 				return fmt.Errorf("go tool pack c %s %s %s: %v\n%s", goarchive, go1obj, go2obj, err, out)
 			}
@@ -132,12 +133,12 @@
 				gopath := filepath.Join(buildDir, "gopath")
 				err = copyDir(filepath.Join(gopath, "src", "mycgo"), filepath.Join("testdata", "mycgo"))
 				if err == nil {
-					err = ioutil.WriteFile(filepath.Join(gopath, "src", "mycgo", "go.mod"), []byte("module mycgo\n"), 0666)
+					err = os.WriteFile(filepath.Join(gopath, "src", "mycgo", "go.mod"), []byte("module mycgo\n"), 0666)
 				}
 				if err != nil {
 					return err
 				}
-				cmd := exec.Command(gotool, "build", "-buildmode=archive", "-o", cgoarchive, "-gcflags=all="+os.Getenv("GO_GCFLAGS"), "mycgo")
+				cmd := testenv.Command(t, gotool, "build", "-buildmode=archive", "-o", cgoarchive, "-gcflags=all="+os.Getenv("GO_GCFLAGS"), "mycgo")
 				cmd.Dir = filepath.Join(gopath, "src", "mycgo")
 				cmd.Env = append(os.Environ(), "GOPATH="+gopath)
 				out, err = cmd.CombinedOutput()
diff --git a/src/cmd/internal/bio/buf_mmap.go b/src/cmd/internal/bio/buf_mmap.go
index 89ae39f..d089efa 100644
--- a/src/cmd/internal/bio/buf_mmap.go
+++ b/src/cmd/internal/bio/buf_mmap.go
@@ -2,8 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd
-// +build darwin dragonfly freebsd linux netbsd openbsd
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || (solaris && go1.20)
 
 package bio
 
diff --git a/src/cmd/internal/bio/buf_nommap.go b/src/cmd/internal/bio/buf_nommap.go
index 533a931..5ebe906 100644
--- a/src/cmd/internal/bio/buf_nommap.go
+++ b/src/cmd/internal/bio/buf_nommap.go
@@ -2,8 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd
-// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !(solaris && go1.20)
 
 package bio
 
diff --git a/src/cmd/internal/buildid/buildid_test.go b/src/cmd/internal/buildid/buildid_test.go
index f04e328..55835bf 100644
--- a/src/cmd/internal/buildid/buildid_test.go
+++ b/src/cmd/internal/buildid/buildid_test.go
@@ -8,7 +8,6 @@
 	"bytes"
 	"crypto/sha256"
 	"internal/obscuretestdata"
-	"io/ioutil"
 	"os"
 	"reflect"
 	"strings"
@@ -21,7 +20,7 @@
 )
 
 func TestReadFile(t *testing.T) {
-	f, err := ioutil.TempFile("", "buildid-test-")
+	f, err := os.CreateTemp("", "buildid-test-")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -59,7 +58,7 @@
 			t.Errorf("ReadFile(%s) [readSize=2k] = %q, %v, want %q, nil", f, id, err, expectedID)
 		}
 
-		data, err := ioutil.ReadFile(f)
+		data, err := os.ReadFile(f)
 		if err != nil {
 			t.Fatal(err)
 		}
@@ -68,7 +67,7 @@
 			t.Errorf("FindAndHash(%s): %v", f, err)
 			continue
 		}
-		if err := ioutil.WriteFile(tmp, data, 0666); err != nil {
+		if err := os.WriteFile(tmp, data, 0666); err != nil {
 			t.Error(err)
 			continue
 		}
diff --git a/src/cmd/internal/buildid/note.go b/src/cmd/internal/buildid/note.go
index f5b6fc5..ab98701 100644
--- a/src/cmd/internal/buildid/note.go
+++ b/src/cmd/internal/buildid/note.go
@@ -78,16 +78,19 @@
 // at least 4 kB out, in data.
 func readELF(name string, f *os.File, data []byte) (buildid string, err error) {
 	// Assume the note content is in the data, already read.
-	// Rewrite the ELF header to set shnum to 0, so that we can pass
+	// Rewrite the ELF header to set shoff and shnum to 0, so that we can pass
 	// the data to elf.NewFile and it will decode the Prog list but not
 	// try to read the section headers and the string table from disk.
 	// That's a waste of I/O when all we care about is the Prog list
 	// and the one ELF note.
 	switch elf.Class(data[elf.EI_CLASS]) {
 	case elf.ELFCLASS32:
+		data[32], data[33], data[34], data[35] = 0, 0, 0, 0
 		data[48] = 0
 		data[49] = 0
 	case elf.ELFCLASS64:
+		data[40], data[41], data[42], data[43] = 0, 0, 0, 0
+		data[44], data[45], data[46], data[47] = 0, 0, 0, 0
 		data[60] = 0
 		data[61] = 0
 	}
diff --git a/src/cmd/internal/cov/mreader.go b/src/cmd/internal/cov/mreader.go
new file mode 100644
index 0000000..30f53d6
--- /dev/null
+++ b/src/cmd/internal/cov/mreader.go
@@ -0,0 +1,85 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cov
+
+import (
+	"cmd/internal/bio"
+	"io"
+	"os"
+)
+
+// This file contains the helper "MReader", a wrapper around bio plus
+// an "mmap'd read-only" view of the file obtained from bio.SliceRO().
+// MReader is designed to implement the io.ReaderSeeker interface.
+// Since bio.SliceOS() is not guaranteed to succeed, MReader falls back
+// on explicit reads + seeks provided by bio.Reader if needed.
+
+type MReader struct {
+	f        *os.File
+	rdr      *bio.Reader
+	fileView []byte
+	off      int64
+}
+
+func NewMreader(f *os.File) (*MReader, error) {
+	rdr := bio.NewReader(f)
+	fi, err := f.Stat()
+	if err != nil {
+		return nil, err
+	}
+	r := MReader{
+		f:        f,
+		rdr:      rdr,
+		fileView: rdr.SliceRO(uint64(fi.Size())),
+	}
+	return &r, nil
+}
+
+func (r *MReader) Read(p []byte) (int, error) {
+	if r.fileView != nil {
+		amt := len(p)
+		toread := r.fileView[r.off:]
+		if len(toread) < 1 {
+			return 0, io.EOF
+		}
+		if len(toread) < amt {
+			amt = len(toread)
+		}
+		copy(p, toread)
+		r.off += int64(amt)
+		return amt, nil
+	}
+	return io.ReadFull(r.rdr, p)
+}
+
+func (r *MReader) ReadByte() (byte, error) {
+	if r.fileView != nil {
+		toread := r.fileView[r.off:]
+		if len(toread) < 1 {
+			return 0, io.EOF
+		}
+		rv := toread[0]
+		r.off++
+		return rv, nil
+	}
+	return r.rdr.ReadByte()
+}
+
+func (r *MReader) Seek(offset int64, whence int) (int64, error) {
+	if r.fileView == nil {
+		return r.rdr.MustSeek(offset, whence), nil
+	}
+	switch whence {
+	case io.SeekStart:
+		r.off = offset
+		return offset, nil
+	case io.SeekCurrent:
+		return r.off, nil
+	case io.SeekEnd:
+		r.off = int64(len(r.fileView)) + offset
+		return r.off, nil
+	}
+	panic("other modes not implemented")
+}
diff --git a/src/cmd/internal/cov/read_test.go b/src/cmd/internal/cov/read_test.go
new file mode 100644
index 0000000..cef03fa
--- /dev/null
+++ b/src/cmd/internal/cov/read_test.go
@@ -0,0 +1,98 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cov_test
+
+import (
+	"cmd/internal/cov"
+	"fmt"
+	"internal/coverage"
+	"internal/coverage/decodecounter"
+	"internal/coverage/decodemeta"
+	"internal/coverage/pods"
+	"internal/testenv"
+	"os"
+	"path/filepath"
+	"testing"
+)
+
+// visitor implements the CovDataVisitor interface in a very stripped
+// down way, just keeps track of interesting events.
+type visitor struct {
+	metaFileCount    int
+	counterFileCount int
+	funcCounterData  int
+	metaFuncCount    int
+}
+
+func (v *visitor) BeginPod(p pods.Pod) {}
+func (v *visitor) EndPod(p pods.Pod)   {}
+func (v *visitor) VisitMetaDataFile(mdf string, mfr *decodemeta.CoverageMetaFileReader) {
+	v.metaFileCount++
+}
+func (v *visitor) BeginCounterDataFile(cdf string, cdr *decodecounter.CounterDataReader, dirIdx int) {
+	v.counterFileCount++
+}
+func (v *visitor) EndCounterDataFile(cdf string, cdr *decodecounter.CounterDataReader, dirIdx int) {}
+func (v *visitor) VisitFuncCounterData(payload decodecounter.FuncPayload)                          { v.funcCounterData++ }
+func (v *visitor) EndCounters()                                                                    {}
+func (v *visitor) BeginPackage(pd *decodemeta.CoverageMetaDataDecoder, pkgIdx uint32)              {}
+func (v *visitor) EndPackage(pd *decodemeta.CoverageMetaDataDecoder, pkgIdx uint32)                {}
+func (v *visitor) VisitFunc(pkgIdx uint32, fnIdx uint32, fd *coverage.FuncDesc)                    { v.metaFuncCount++ }
+func (v *visitor) Finish()                                                                         {}
+
+func TestIssue58411(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	// Build a tiny test program with -cover. Smallness is important;
+	// it is one of the factors that triggers issue 58411.
+	d := t.TempDir()
+	exepath := filepath.Join(d, "small.exe")
+	path := filepath.Join("testdata", "small.go")
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "build",
+		"-o", exepath, "-cover", path)
+	b, err := cmd.CombinedOutput()
+	if len(b) != 0 {
+		t.Logf("## build output:\n%s", b)
+	}
+	if err != nil {
+		t.Fatalf("build error: %v", err)
+	}
+
+	// Run to produce coverage data. Note the large argument; we need a large
+	// argument (more than 4k) to trigger the bug, but the overall file
+	// has to remain small (since large files will be read with mmap).
+	covdir := filepath.Join(d, "covdata")
+	if err = os.Mkdir(covdir, 0777); err != nil {
+		t.Fatalf("creating covdir: %v", err)
+	}
+	large := fmt.Sprintf("%07999d", 0)
+	cmd = testenv.Command(t, exepath, "1", "2", "3", large)
+	cmd.Dir = covdir
+	cmd.Env = append(os.Environ(), "GOCOVERDIR="+covdir)
+	b, err = cmd.CombinedOutput()
+	if err != nil {
+		t.Logf("## run output:\n%s", b)
+		t.Fatalf("build error: %v", err)
+	}
+
+	vis := &visitor{}
+
+	// Read resulting coverage data. Without the fix, this would
+	// yield a "short read" error.
+	const verbosityLevel = 0
+	const flags = 0
+	cdr := cov.MakeCovDataReader(vis, []string{covdir}, verbosityLevel, flags, nil)
+	err = cdr.Visit()
+	if err != nil {
+		t.Fatalf("visit failed: %v", err)
+	}
+
+	// make sure we saw a few things just for grins
+	const want = "{metaFileCount:1 counterFileCount:1 funcCounterData:1 metaFuncCount:1}"
+	got := fmt.Sprintf("%+v", *vis)
+	if want != got {
+		t.Errorf("visitor contents: want %v got %v\n", want, got)
+	}
+}
diff --git a/src/cmd/internal/cov/readcovdata.go b/src/cmd/internal/cov/readcovdata.go
new file mode 100644
index 0000000..7e90e9e
--- /dev/null
+++ b/src/cmd/internal/cov/readcovdata.go
@@ -0,0 +1,277 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cov
+
+import (
+	"cmd/internal/bio"
+	"fmt"
+	"internal/coverage"
+	"internal/coverage/decodecounter"
+	"internal/coverage/decodemeta"
+	"internal/coverage/pods"
+	"io"
+	"os"
+)
+
+// CovDataReader is a general-purpose helper/visitor object for
+// reading coverage data files in a structured way. Clients create a
+// CovDataReader to process a given collection of coverage data file
+// directories, then pass in a visitor object with methods that get
+// invoked at various important points. CovDataReader is intended
+// to facilitate common coverage data file operations such as
+// merging or intersecting data files, analyzing data files, or
+// dumping data files.
+type CovDataReader struct {
+	vis            CovDataVisitor
+	indirs         []string
+	matchpkg       func(name string) bool
+	flags          CovDataReaderFlags
+	err            error
+	verbosityLevel int
+}
+
+// MakeCovDataReader creates a CovDataReader object to process the
+// given set of input directories. Here 'vis' is a visitor object
+// providing methods to be invoked as we walk through the data,
+// 'indirs' is the set of coverage data directories to examine,
+// 'verbosityLevel' controls the level of debugging trace messages
+// (zero for off, higher for more output), 'flags' stores flags that
+// indicate what to do if errors are detected, and 'matchpkg' is a
+// caller-provided function that can be used to select specific
+// packages by name (if nil, then all packages are included).
+func MakeCovDataReader(vis CovDataVisitor, indirs []string, verbosityLevel int, flags CovDataReaderFlags, matchpkg func(name string) bool) *CovDataReader {
+	return &CovDataReader{
+		vis:            vis,
+		indirs:         indirs,
+		matchpkg:       matchpkg,
+		verbosityLevel: verbosityLevel,
+		flags:          flags,
+	}
+}
+
+// CovDataVisitor defines hooks for clients of CovDataReader. When the
+// coverage data reader makes its way through a coverage meta-data
+// file and counter data files, it will invoke the methods below to
+// hand off info to the client. The normal sequence of expected
+// visitor method invocations is:
+//
+//	for each pod P {
+//		BeginPod(p)
+//		let MF be the meta-data file for P
+//		VisitMetaDataFile(MF)
+//		for each counter data file D in P {
+//			BeginCounterDataFile(D)
+//			for each live function F in D {
+//				VisitFuncCounterData(F)
+//			}
+//			EndCounterDataFile(D)
+//		}
+//		EndCounters(MF)
+//		for each package PK in MF {
+//			BeginPackage(PK)
+//			if <PK matched according to package pattern and/or modpath> {
+//				for each function PF in PK {
+//					VisitFunc(PF)
+//				}
+//			}
+//			EndPackage(PK)
+//		}
+//		EndPod(p)
+//	}
+//	Finish()
+
+type CovDataVisitor interface {
+	// Invoked at the start and end of a given pod (a pod here is a
+	// specific coverage meta-data files with the counter data files
+	// that correspond to it).
+	BeginPod(p pods.Pod)
+	EndPod(p pods.Pod)
+
+	// Invoked when the reader is starting to examine the meta-data
+	// file for a pod. Here 'mdf' is the path of the file, and 'mfr'
+	// is an open meta-data reader.
+	VisitMetaDataFile(mdf string, mfr *decodemeta.CoverageMetaFileReader)
+
+	// Invoked when the reader processes a counter data file, first
+	// the 'begin' method at the start, then the 'end' method when
+	// we're done with the file.
+	BeginCounterDataFile(cdf string, cdr *decodecounter.CounterDataReader, dirIdx int)
+	EndCounterDataFile(cdf string, cdr *decodecounter.CounterDataReader, dirIdx int)
+
+	// Invoked once for each live function in the counter data file.
+	VisitFuncCounterData(payload decodecounter.FuncPayload)
+
+	// Invoked when we've finished processing the counter files in a
+	// POD (e.g. no more calls to VisitFuncCounterData).
+	EndCounters()
+
+	// Invoked for each package in the meta-data file for the pod,
+	// first the 'begin' method when processinf of hte package starts,
+	// then the 'end' method when we're done
+	BeginPackage(pd *decodemeta.CoverageMetaDataDecoder, pkgIdx uint32)
+	EndPackage(pd *decodemeta.CoverageMetaDataDecoder, pkgIdx uint32)
+
+	// Invoked for each function  the package being visited.
+	VisitFunc(pkgIdx uint32, fnIdx uint32, fd *coverage.FuncDesc)
+
+	// Invoked when all counter + meta-data file processing is complete.
+	Finish()
+}
+
+type CovDataReaderFlags uint32
+
+const (
+	CovDataReaderNoFlags CovDataReaderFlags = 0
+	PanicOnError                            = 1 << iota
+	PanicOnWarning
+)
+
+func (r *CovDataReader) Visit() error {
+	podlist, err := pods.CollectPods(r.indirs, false)
+	if err != nil {
+		return fmt.Errorf("reading inputs: %v", err)
+	}
+	if len(podlist) == 0 {
+		r.warn("no applicable files found in input directories")
+	}
+	for _, p := range podlist {
+		if err := r.visitPod(p); err != nil {
+			return err
+		}
+	}
+	r.vis.Finish()
+	return nil
+}
+
+func (r *CovDataReader) verb(vlevel int, s string, a ...interface{}) {
+	if r.verbosityLevel >= vlevel {
+		fmt.Fprintf(os.Stderr, s, a...)
+		fmt.Fprintf(os.Stderr, "\n")
+	}
+}
+
+func (r *CovDataReader) warn(s string, a ...interface{}) {
+	fmt.Fprintf(os.Stderr, "warning: ")
+	fmt.Fprintf(os.Stderr, s, a...)
+	fmt.Fprintf(os.Stderr, "\n")
+	if (r.flags & PanicOnWarning) != 0 {
+		panic("unexpected warning")
+	}
+}
+
+func (r *CovDataReader) fatal(s string, a ...interface{}) error {
+	if r.err != nil {
+		return nil
+	}
+	errstr := "error: " + fmt.Sprintf(s, a...) + "\n"
+	if (r.flags & PanicOnError) != 0 {
+		fmt.Fprintf(os.Stderr, "%s", errstr)
+		panic("fatal error")
+	}
+	r.err = fmt.Errorf("%s", errstr)
+	return r.err
+}
+
+// visitPod examines a coverage data 'pod', that is, a meta-data file and
+// zero or more counter data files that refer to that meta-data file.
+func (r *CovDataReader) visitPod(p pods.Pod) error {
+	r.verb(1, "visiting pod: metafile %s with %d counter files",
+		p.MetaFile, len(p.CounterDataFiles))
+	r.vis.BeginPod(p)
+
+	// Open meta-file
+	f, err := os.Open(p.MetaFile)
+	if err != nil {
+		return r.fatal("unable to open meta-file %s", p.MetaFile)
+	}
+	defer f.Close()
+	br := bio.NewReader(f)
+	fi, err := f.Stat()
+	if err != nil {
+		return r.fatal("unable to stat metafile %s: %v", p.MetaFile, err)
+	}
+	fileView := br.SliceRO(uint64(fi.Size()))
+	br.MustSeek(0, io.SeekStart)
+
+	r.verb(1, "fileView for pod is length %d", len(fileView))
+
+	var mfr *decodemeta.CoverageMetaFileReader
+	mfr, err = decodemeta.NewCoverageMetaFileReader(f, fileView)
+	if err != nil {
+		return r.fatal("decoding meta-file %s: %s", p.MetaFile, err)
+	}
+	r.vis.VisitMetaDataFile(p.MetaFile, mfr)
+
+	// Read counter data files.
+	for k, cdf := range p.CounterDataFiles {
+		cf, err := os.Open(cdf)
+		if err != nil {
+			return r.fatal("opening counter data file %s: %s", cdf, err)
+		}
+		defer func(f *os.File) {
+			f.Close()
+		}(cf)
+		var mr *MReader
+		mr, err = NewMreader(cf)
+		if err != nil {
+			return r.fatal("creating reader for counter data file %s: %s", cdf, err)
+		}
+		var cdr *decodecounter.CounterDataReader
+		cdr, err = decodecounter.NewCounterDataReader(cdf, mr)
+		if err != nil {
+			return r.fatal("reading counter data file %s: %s", cdf, err)
+		}
+		r.vis.BeginCounterDataFile(cdf, cdr, p.Origins[k])
+		var data decodecounter.FuncPayload
+		for {
+			ok, err := cdr.NextFunc(&data)
+			if err != nil {
+				return r.fatal("reading counter data file %s: %v", cdf, err)
+			}
+			if !ok {
+				break
+			}
+			r.vis.VisitFuncCounterData(data)
+		}
+		r.vis.EndCounterDataFile(cdf, cdr, p.Origins[k])
+	}
+	r.vis.EndCounters()
+
+	// NB: packages in the meta-file will be in dependency order (basically
+	// the order in which init files execute). Do we want an additional sort
+	// pass here, say by packagepath?
+	np := uint32(mfr.NumPackages())
+	payload := []byte{}
+	for pkIdx := uint32(0); pkIdx < np; pkIdx++ {
+		var pd *decodemeta.CoverageMetaDataDecoder
+		pd, payload, err = mfr.GetPackageDecoder(pkIdx, payload)
+		if err != nil {
+			return r.fatal("reading pkg %d from meta-file %s: %s", pkIdx, p.MetaFile, err)
+		}
+		r.processPackage(p.MetaFile, pd, pkIdx)
+	}
+	r.vis.EndPod(p)
+
+	return nil
+}
+
+func (r *CovDataReader) processPackage(mfname string, pd *decodemeta.CoverageMetaDataDecoder, pkgIdx uint32) error {
+	if r.matchpkg != nil {
+		if !r.matchpkg(pd.PackagePath()) {
+			return nil
+		}
+	}
+	r.vis.BeginPackage(pd, pkgIdx)
+	nf := pd.NumFuncs()
+	var fd coverage.FuncDesc
+	for fidx := uint32(0); fidx < nf; fidx++ {
+		if err := pd.ReadFunc(fidx, &fd); err != nil {
+			return r.fatal("reading meta-data file %s: %v", mfname, err)
+		}
+		r.vis.VisitFunc(pkgIdx, fidx, &fd)
+	}
+	r.vis.EndPackage(pd, pkgIdx)
+	return nil
+}
diff --git a/src/cmd/internal/cov/testdata/small.go b/src/cmd/internal/cov/testdata/small.go
new file mode 100644
index 0000000..d81cb70
--- /dev/null
+++ b/src/cmd/internal/cov/testdata/small.go
@@ -0,0 +1,7 @@
+package main
+
+import "os"
+
+func main() {
+	println(len(os.Args))
+}
diff --git a/src/cmd/internal/dwarf/dwarf.go b/src/cmd/internal/dwarf/dwarf.go
index 8ba5737..a6d19c6 100644
--- a/src/cmd/internal/dwarf/dwarf.go
+++ b/src/cmd/internal/dwarf/dwarf.go
@@ -21,15 +21,15 @@
 )
 
 // InfoPrefix is the prefix for all the symbols containing DWARF info entries.
-const InfoPrefix = "go.info."
+const InfoPrefix = "go:info."
 
 // ConstInfoPrefix is the prefix for all symbols containing DWARF info
 // entries that contain constants.
-const ConstInfoPrefix = "go.constinfo."
+const ConstInfoPrefix = "go:constinfo."
 
 // CUInfoPrefix is the prefix for symbols containing information to
 // populate the DWARF compilation unit info entries.
-const CUInfoPrefix = "go.cuinfo."
+const CUInfoPrefix = "go:cuinfo."
 
 // Used to form the symbol name assigned to the DWARF 'abstract subprogram"
 // info entry for a function
@@ -396,7 +396,7 @@
 	return uint8(expandedForm)
 }
 
-// Abbrevs() returns the finalized abbrev array for the platform,
+// Abbrevs returns the finalized abbrev array for the platform,
 // expanding any DW_FORM pseudo-ops to real values.
 func Abbrevs() []dwAbbrev {
 	if abbrevsFinalized {
@@ -1159,8 +1159,8 @@
 	return !live
 }
 
-// Slot -1:    return top-level inlines
-// Slot >= 0:  return children of that slot
+// Slot -1:    return top-level inlines.
+// Slot >= 0:  return children of that slot.
 func inlChildren(slot int, calls *InlCalls) []int {
 	var kids []int
 	if slot != -1 {
@@ -1592,7 +1592,6 @@
 	switch fnabbrev {
 	case DW_ABRV_FUNCTION, DW_ABRV_WRAPPER:
 		concrete = false
-		break
 	case DW_ABRV_FUNCTION_CONCRETE, DW_ABRV_WRAPPER_CONCRETE:
 		// If we're emitting a concrete subprogram DIE and the variable
 		// in question is not part of the corresponding abstract function DIE,
@@ -1719,7 +1718,7 @@
 func (s byChildIndex) Less(i, j int) bool { return s[i].ChildIndex < s[j].ChildIndex }
 func (s byChildIndex) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
 
-// IsDWARFEnabledOnAIX returns true if DWARF is possible on the
+// IsDWARFEnabledOnAIXLd returns true if DWARF is possible on the
 // current extld.
 // AIX ld doesn't support DWARF with -bnoobjreorder with version
 // prior to 7.2.2.
diff --git a/src/cmd/internal/goobj/builtinlist.go b/src/cmd/internal/goobj/builtinlist.go
index 2d13222..ae2e6cc 100644
--- a/src/cmd/internal/goobj/builtinlist.go
+++ b/src/cmd/internal/goobj/builtinlist.go
@@ -214,40 +214,40 @@
 	{"runtime.morestack", 0},
 	{"runtime.morestackc", 0},
 	{"runtime.morestack_noctxt", 0},
-	{"type.int8", 0},
-	{"type.*int8", 0},
-	{"type.uint8", 0},
-	{"type.*uint8", 0},
-	{"type.int16", 0},
-	{"type.*int16", 0},
-	{"type.uint16", 0},
-	{"type.*uint16", 0},
-	{"type.int32", 0},
-	{"type.*int32", 0},
-	{"type.uint32", 0},
-	{"type.*uint32", 0},
-	{"type.int64", 0},
-	{"type.*int64", 0},
-	{"type.uint64", 0},
-	{"type.*uint64", 0},
-	{"type.float32", 0},
-	{"type.*float32", 0},
-	{"type.float64", 0},
-	{"type.*float64", 0},
-	{"type.complex64", 0},
-	{"type.*complex64", 0},
-	{"type.complex128", 0},
-	{"type.*complex128", 0},
-	{"type.unsafe.Pointer", 0},
-	{"type.*unsafe.Pointer", 0},
-	{"type.uintptr", 0},
-	{"type.*uintptr", 0},
-	{"type.bool", 0},
-	{"type.*bool", 0},
-	{"type.string", 0},
-	{"type.*string", 0},
-	{"type.error", 0},
-	{"type.*error", 0},
-	{"type.func(error) string", 0},
-	{"type.*func(error) string", 0},
+	{"type:int8", 0},
+	{"type:*int8", 0},
+	{"type:uint8", 0},
+	{"type:*uint8", 0},
+	{"type:int16", 0},
+	{"type:*int16", 0},
+	{"type:uint16", 0},
+	{"type:*uint16", 0},
+	{"type:int32", 0},
+	{"type:*int32", 0},
+	{"type:uint32", 0},
+	{"type:*uint32", 0},
+	{"type:int64", 0},
+	{"type:*int64", 0},
+	{"type:uint64", 0},
+	{"type:*uint64", 0},
+	{"type:float32", 0},
+	{"type:*float32", 0},
+	{"type:float64", 0},
+	{"type:*float64", 0},
+	{"type:complex64", 0},
+	{"type:*complex64", 0},
+	{"type:complex128", 0},
+	{"type:*complex128", 0},
+	{"type:unsafe.Pointer", 0},
+	{"type:*unsafe.Pointer", 0},
+	{"type:uintptr", 0},
+	{"type:*uintptr", 0},
+	{"type:bool", 0},
+	{"type:*bool", 0},
+	{"type:string", 0},
+	{"type:*string", 0},
+	{"type:error", 0},
+	{"type:*error", 0},
+	{"type:func(error) string", 0},
+	{"type:*func(error) string", 0},
 }
diff --git a/src/cmd/internal/goobj/funcinfo.go b/src/cmd/internal/goobj/funcinfo.go
index 59cb957..fbcf9d9 100644
--- a/src/cmd/internal/goobj/funcinfo.go
+++ b/src/cmd/internal/goobj/funcinfo.go
@@ -17,12 +17,13 @@
 // FuncInfo is serialized as a symbol (aux symbol). The symbol data is
 // the binary encoding of the struct below.
 type FuncInfo struct {
-	Args     uint32
-	Locals   uint32
-	FuncID   objabi.FuncID
-	FuncFlag objabi.FuncFlag
-	File     []CUFileIndex
-	InlTree  []InlTreeNode
+	Args      uint32
+	Locals    uint32
+	FuncID    objabi.FuncID
+	FuncFlag  objabi.FuncFlag
+	StartLine int32
+	File      []CUFileIndex
+	InlTree   []InlTreeNode
 }
 
 func (a *FuncInfo) Write(w *bytes.Buffer) {
@@ -41,6 +42,7 @@
 	writeUint8(uint8(a.FuncFlag))
 	writeUint8(0) // pad to uint32 boundary
 	writeUint8(0)
+	writeUint32(uint32(a.StartLine))
 
 	writeUint32(uint32(len(a.File)))
 	for _, f := range a.File {
@@ -70,7 +72,7 @@
 
 	// Offset to the number of the file table. This value is determined by counting
 	// the number of bytes until we write funcdataoff to the file.
-	const numfileOff = 12
+	const numfileOff = 16
 	result.NumFile = binary.LittleEndian.Uint32(b[numfileOff:])
 	result.FileOff = numfileOff + 4
 
@@ -91,6 +93,8 @@
 
 func (*FuncInfo) ReadFuncFlag(b []byte) objabi.FuncFlag { return objabi.FuncFlag(b[9]) }
 
+func (*FuncInfo) ReadStartLine(b []byte) int32 { return int32(binary.LittleEndian.Uint32(b[12:])) }
+
 func (*FuncInfo) ReadFile(b []byte, filesoff uint32, k uint32) CUFileIndex {
 	return CUFileIndex(binary.LittleEndian.Uint32(b[filesoff+4*k:]))
 }
diff --git a/src/cmd/internal/goobj/mkbuiltin.go b/src/cmd/internal/goobj/mkbuiltin.go
index c9995fc..57e39dc 100644
--- a/src/cmd/internal/goobj/mkbuiltin.go
+++ b/src/cmd/internal/goobj/mkbuiltin.go
@@ -18,7 +18,6 @@
 	"go/parser"
 	"go/token"
 	"io"
-	"io/ioutil"
 	"log"
 	"os"
 	"path/filepath"
@@ -44,7 +43,7 @@
 	if *stdout {
 		_, err = os.Stdout.Write(out)
 	} else {
-		err = ioutil.WriteFile("builtinlist.go", out, 0666)
+		err = os.WriteFile("builtinlist.go", out, 0666)
 	}
 	if err != nil {
 		log.Fatal(err)
@@ -105,7 +104,7 @@
 	extras := append(fextras[:], enumerateBasicTypes()...)
 	for _, b := range extras {
 		prefix := ""
-		if !strings.HasPrefix(b.name, "type.") {
+		if !strings.HasPrefix(b.name, "type:") {
 			prefix = pkg + "."
 		}
 		name := prefix + b.name
@@ -117,7 +116,7 @@
 	fmt.Fprintln(w, "}")
 }
 
-// addBasicTypes returns the symbol names for basic types that are
+// enumerateBasicTypes returns the symbol names for basic types that are
 // defined in the runtime and referenced in other packages.
 // Needs to be kept in sync with reflect.go:WriteBasicTypes() and
 // reflect.go:writeType() in the compiler.
@@ -130,8 +129,8 @@
 		"func(error) string"}
 	result := []extra{}
 	for _, n := range names {
-		result = append(result, extra{"type." + n, 0})
-		result = append(result, extra{"type.*" + n, 0})
+		result = append(result, extra{"type:" + n, 0})
+		result = append(result, extra{"type:*" + n, 0})
 	}
 	return result
 }
diff --git a/src/cmd/internal/goobj/objfile.go b/src/cmd/internal/goobj/objfile.go
index 39b86b0..ae215df 100644
--- a/src/cmd/internal/goobj/objfile.go
+++ b/src/cmd/internal/goobj/objfile.go
@@ -30,7 +30,7 @@
 // New object file format.
 //
 //    Header struct {
-//       Magic       [...]byte   // "\x00go118ld"
+//       Magic       [...]byte   // "\x00go120ld"
 //       Fingerprint [8]byte
 //       Flags       uint32
 //       Offsets     [...]uint32 // byte offset of each block below
@@ -215,7 +215,7 @@
 	Offsets     [NBlk]uint32
 }
 
-const Magic = "\x00go118ld"
+const Magic = "\x00go120ld"
 
 func (h *Header) Write(w *Writer) {
 	w.RawString(h.Magic)
@@ -527,6 +527,8 @@
 	wr        *bio.Writer
 	stringMap map[string]uint32
 	off       uint32 // running offset
+
+	b [8]byte // scratch space for writing bytes
 }
 
 func NewWriter(wr *bio.Writer) *Writer {
@@ -565,23 +567,20 @@
 }
 
 func (w *Writer) Uint64(x uint64) {
-	var b [8]byte
-	binary.LittleEndian.PutUint64(b[:], x)
-	w.wr.Write(b[:])
+	binary.LittleEndian.PutUint64(w.b[:], x)
+	w.wr.Write(w.b[:])
 	w.off += 8
 }
 
 func (w *Writer) Uint32(x uint32) {
-	var b [4]byte
-	binary.LittleEndian.PutUint32(b[:], x)
-	w.wr.Write(b[:])
+	binary.LittleEndian.PutUint32(w.b[:4], x)
+	w.wr.Write(w.b[:4])
 	w.off += 4
 }
 
 func (w *Writer) Uint16(x uint16) {
-	var b [2]byte
-	binary.LittleEndian.PutUint16(b[:], x)
-	w.wr.Write(b[:])
+	binary.LittleEndian.PutUint16(w.b[:2], x)
+	w.wr.Write(w.b[:2])
 	w.off += 2
 }
 
diff --git a/src/cmd/internal/goobj/objfile_test.go b/src/cmd/internal/goobj/objfile_test.go
index ed942aa..10e0564 100644
--- a/src/cmd/internal/goobj/objfile_test.go
+++ b/src/cmd/internal/goobj/objfile_test.go
@@ -7,15 +7,14 @@
 import (
 	"bufio"
 	"bytes"
-	"cmd/internal/bio"
-	"cmd/internal/objabi"
 	"fmt"
 	"internal/buildcfg"
 	"internal/testenv"
-	"io/ioutil"
 	"os"
-	"os/exec"
 	"testing"
+
+	"cmd/internal/bio"
+	"cmd/internal/objabi"
 )
 
 func dummyWriter(buf *bytes.Buffer) *Writer {
@@ -97,7 +96,7 @@
 	}
 	testenv.MustHaveGoBuild(t)
 
-	tmpdir, err := ioutil.TempDir("", "lotsofrelocs")
+	tmpdir, err := os.MkdirTemp("", "lotsofrelocs")
 	if err != nil {
 		t.Fatalf("can't create temp directory: %v\n", err)
 	}
@@ -110,7 +109,7 @@
 		fmt.Fprintf(&w, "\t\"%d\",\n", i)
 	}
 	fmt.Fprintf(&w, issue41621epilog)
-	err = ioutil.WriteFile(tmpdir+"/large.go", w.Bytes(), 0666)
+	err = os.WriteFile(tmpdir+"/large.go", w.Bytes(), 0666)
 	if err != nil {
 		t.Fatalf("can't write output: %v\n", err)
 	}
@@ -118,14 +117,14 @@
 	// Emit go.mod
 	w.Reset()
 	fmt.Fprintf(&w, "module issue41621\n\ngo 1.12\n")
-	err = ioutil.WriteFile(tmpdir+"/go.mod", w.Bytes(), 0666)
+	err = os.WriteFile(tmpdir+"/go.mod", w.Bytes(), 0666)
 	if err != nil {
 		t.Fatalf("can't write output: %v\n", err)
 	}
 	w.Reset()
 
 	// Build.
-	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", "large")
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-o", "large")
 	cmd.Dir = tmpdir
 	out, err := cmd.CombinedOutput()
 	if err != nil {
diff --git a/src/cmd/internal/moddeps/moddeps_test.go b/src/cmd/internal/moddeps/moddeps_test.go
index 053cb8f..4122064 100644
--- a/src/cmd/internal/moddeps/moddeps_test.go
+++ b/src/cmd/internal/moddeps/moddeps_test.go
@@ -11,9 +11,7 @@
 	"internal/testenv"
 	"io"
 	"io/fs"
-	"io/ioutil"
 	"os"
-	"os/exec"
 	"path/filepath"
 	"strings"
 	"sync"
@@ -54,7 +52,7 @@
 				// Load all of the packages in the module to ensure that their
 				// dependencies are vendored. If any imported package is missing,
 				// 'go list -deps' will fail when attempting to load it.
-				cmd := exec.Command(goBin, "list", "-mod=vendor", "-deps", "./...")
+				cmd := testenv.Command(t, goBin, "list", "-mod=vendor", "-deps", "./...")
 				cmd.Env = append(os.Environ(), "GO111MODULE=on", "GOWORK=off")
 				cmd.Dir = m.Dir
 				cmd.Stderr = new(strings.Builder)
@@ -68,7 +66,7 @@
 
 			// There is no vendor directory, so the module must have no dependencies.
 			// Check that the list of active modules contains only the main module.
-			cmd := exec.Command(goBin, "list", "-mod=readonly", "-m", "all")
+			cmd := testenv.Command(t, goBin, "list", "-mod=readonly", "-m", "all")
 			cmd.Env = append(os.Environ(), "GO111MODULE=on", "GOWORK=off")
 			cmd.Dir = m.Dir
 			cmd.Stderr = new(strings.Builder)
@@ -106,11 +104,11 @@
 
 	testenv.MustHaveExternalNetwork(t)
 	if haveDiff := func() bool {
-		diff, err := exec.Command("diff", "--recursive", "--unified", ".", ".").CombinedOutput()
+		diff, err := testenv.Command(t, "diff", "--recursive", "--unified", ".", ".").CombinedOutput()
 		if err != nil || len(diff) != 0 {
 			return false
 		}
-		diff, err = exec.Command("diff", "--recursive", "--unified", ".", "..").CombinedOutput()
+		diff, err = testenv.Command(t, "diff", "--recursive", "--unified", ".", "..").CombinedOutput()
 		if err == nil || len(diff) == 0 {
 			return false
 		}
@@ -130,7 +128,7 @@
 	// GO_TEST_SHORT=0 causes it to run this portion of the test.)
 	var modcacheEnv []string
 	{
-		out, err := exec.Command(goBin, "env", "GOMODCACHE").Output()
+		out, err := testenv.Command(t, goBin, "env", "GOMODCACHE").Output()
 		if err != nil {
 			t.Fatalf("%s env GOMODCACHE: %v", goBin, err)
 		}
@@ -216,7 +214,7 @@
 			}
 			// TODO(golang.org/issue/43440): Check anything else influenced by dependency versions.
 
-			diff, err := exec.Command("diff", "--recursive", "--unified", r.Dir, m.Dir).CombinedOutput()
+			diff, err := testenv.Command(t, "diff", "--recursive", "--unified", r.Dir, m.Dir).CombinedOutput()
 			if err != nil || len(diff) != 0 {
 				t.Errorf(`Module %s in %s is not tidy (-want +got):
 
@@ -322,7 +320,7 @@
 // run runs the command and requires that it succeeds.
 func (r runner) run(t *testing.T, args ...string) {
 	t.Helper()
-	cmd := exec.Command(args[0], args[1:]...)
+	cmd := testenv.Command(t, args[0], args[1:]...)
 	cmd.Dir = r.Dir
 	cmd.Env = r.Env
 	out, err := cmd.CombinedOutput()
@@ -361,7 +359,7 @@
 		// It's ok if there are undetected differences in modules that do not
 		// provide imported packages: we will not have to pull in any backports of
 		// fixes to those modules anyway.
-		vendor, err := ioutil.ReadFile(filepath.Join(m.Dir, "vendor", "modules.txt"))
+		vendor, err := os.ReadFile(filepath.Join(m.Dir, "vendor", "modules.txt"))
 		if err != nil {
 			t.Error(err)
 			continue
@@ -463,7 +461,7 @@
 
 			// Use 'go list' to describe the module contained in this directory (but
 			// not its dependencies).
-			cmd := exec.Command(goBin, "list", "-json", "-m")
+			cmd := testenv.Command(t, goBin, "list", "-json", "-m")
 			cmd.Env = append(os.Environ(), "GO111MODULE=on", "GOWORK=off")
 			cmd.Dir = dir
 			cmd.Stderr = new(strings.Builder)
diff --git a/src/cmd/internal/notsha256/sha256block_ppc64x.s b/src/cmd/internal/notsha256/sha256block_ppc64x.s
index e907d3b..ea4417d 100644
--- a/src/cmd/internal/notsha256/sha256block_ppc64x.s
+++ b/src/cmd/internal/notsha256/sha256block_ppc64x.s
@@ -65,13 +65,31 @@
 #define CTX	R3
 #define INP	R4
 #define END	R5
-#define TBL	R6
-#define IDX	R7
+#define TBL	R6 // Pointer into kcon table
 #define LEN	R9
 #define TEMP	R12
 
-#define HEX00	R0
-#define HEX10	R10
+#define TBL_STRT	R7 // Pointer to start of kcon table.
+
+#define R_x000	R0
+#define R_x010	R8
+#define R_x020	R10
+#define R_x030	R11
+#define R_x040	R14
+#define R_x050	R15
+#define R_x060	R16
+#define R_x070	R17
+#define R_x080	R18
+#define R_x090	R19
+#define R_x0a0	R20
+#define R_x0b0	R21
+#define R_x0c0	R22
+#define R_x0d0	R23
+#define R_x0e0	R24
+#define R_x0f0	R25
+#define R_x100	R26
+#define R_x110	R27
+
 
 // V0-V7 are A-H
 // V8-V23 are used for the message schedule
@@ -81,7 +99,7 @@
 #define S1	V27
 #define s0	V28
 #define s1	V29
-#define LEMASK	V31	// Permutation control register for little endian
+#define LEMASK	V31 // Permutation control register for little endian
 
 // 4 copies of each Kt, to fill all 4 words of a vector register
 DATA  ·kcon+0x000(SB)/8, $0x428a2f98428a2f98
@@ -216,7 +234,7 @@
 DATA  ·kcon+0x408(SB)/8, $0x0000000000000000
 
 #ifdef GOARCH_ppc64le
-DATA  ·kcon+0x410(SB)/8, $0x1011121310111213	// permutation control vectors
+DATA  ·kcon+0x410(SB)/8, $0x1011121310111213 // permutation control vectors
 DATA  ·kcon+0x418(SB)/8, $0x1011121300010203
 DATA  ·kcon+0x420(SB)/8, $0x1011121310111213
 DATA  ·kcon+0x428(SB)/8, $0x0405060700010203
@@ -224,7 +242,7 @@
 DATA  ·kcon+0x438(SB)/8, $0x0405060700010203
 #else
 DATA  ·kcon+0x410(SB)/8, $0x1011121300010203
-DATA  ·kcon+0x418(SB)/8, $0x1011121310111213	// permutation control vectors
+DATA  ·kcon+0x418(SB)/8, $0x1011121310111213 // permutation control vectors
 DATA  ·kcon+0x420(SB)/8, $0x0405060700010203
 DATA  ·kcon+0x428(SB)/8, $0x1011121310111213
 DATA  ·kcon+0x430(SB)/8, $0x0001020304050607
@@ -233,7 +251,7 @@
 
 GLOBL ·kcon(SB), RODATA, $1088
 
-#define SHA256ROUND0(a, b, c, d, e, f, g, h, xi) \
+#define SHA256ROUND0(a, b, c, d, e, f, g, h, xi, idx) \
 	VSEL		g, f, e, FUNC; \
 	VSHASIGMAW	$15, e, $1, S1; \
 	VADDUWM		xi, h, h; \
@@ -245,11 +263,10 @@
 	VADDUWM		KI, g, g; \
 	VADDUWM		h, d, d; \
 	VADDUWM		FUNC, S0, S0; \
-	LVX		(TBL)(IDX), KI; \
-	ADD		$16, IDX; \
+	LVX		(TBL)(idx), KI; \
 	VADDUWM		S0, h, h
 
-#define SHA256ROUND1(a, b, c, d, e, f, g, h, xi, xj, xj_1, xj_9, xj_14) \
+#define SHA256ROUND1(a, b, c, d, e, f, g, h, xi, xj, xj_1, xj_9, xj_14, idx) \
 	VSHASIGMAW	$0, xj_1, $0, s0; \
 	VSEL		g, f, e, FUNC; \
 	VSHASIGMAW	$15, e, $1, S1; \
@@ -265,8 +282,7 @@
 	VADDUWM		h, d, d; \
 	VADDUWM		FUNC, S0, S0; \
 	VADDUWM		s0, xj, xj; \
-	LVX		(TBL)(IDX), KI; \
-	ADD		$16, IDX; \
+	LVX		(TBL)(idx), KI; \
 	VADDUWM		S0, h, h; \
 	VADDUWM		s1, xj, xj
 
@@ -289,18 +305,18 @@
 	CMP	INP, END
 	BEQ	end
 
-	MOVD	$·kcon(SB), TBL
-	MOVWZ	$0x10, HEX10
-	MOVWZ	$8, IDX
+	MOVD	$·kcon(SB), TBL_STRT
+	MOVD	$0x10, R_x010
 
 #ifdef GOARCH_ppc64le
-	LVSL	(IDX)(R0), LEMASK
+	MOVWZ	$8, TEMP
+	LVSL	(TEMP)(R0), LEMASK
 	VSPLTISB	$0x0F, KI
 	VXOR	KI, LEMASK, LEMASK
 #endif
 
-	LXVW4X	(CTX)(HEX00), VS32	// v0 = vs32
-	LXVW4X	(CTX)(HEX10), VS36	// v4 = vs36
+	LXVW4X	(CTX)(R_x000), V0
+	LXVW4X	(CTX)(R_x010), V4
 
 	// unpack the input values into vector registers
 	VSLDOI	$4, V0, V0, V1
@@ -310,121 +326,135 @@
 	VSLDOI	$8, V4, V4, V6
 	VSLDOI	$12, V4, V4, V7
 
-loop:
-	LVX	(TBL)(HEX00), KI
-	MOVWZ	$16, IDX
+	MOVD	$0x020, R_x020
+	MOVD	$0x030, R_x030
+	MOVD	$0x040, R_x040
+	MOVD	$0x050, R_x050
+	MOVD	$0x060, R_x060
+	MOVD	$0x070, R_x070
+	MOVD	$0x080, R_x080
+	MOVD	$0x090, R_x090
+	MOVD	$0x0a0, R_x0a0
+	MOVD	$0x0b0, R_x0b0
+	MOVD	$0x0c0, R_x0c0
+	MOVD	$0x0d0, R_x0d0
+	MOVD	$0x0e0, R_x0e0
+	MOVD	$0x0f0, R_x0f0
+	MOVD	$0x100, R_x100
+	MOVD	$0x110, R_x110
 
-	LXVD2X	(INP)(R0), VS40	// load v8 (=vs40) in advance
-	ADD	$16, INP
+loop:
+	MOVD	TBL_STRT, TBL
+	LVX	(TBL)(R_x000), KI
+
+	LXVD2X	(INP)(R_x000), V8 // load v8 in advance
 
 	// Offload to VSR24-31 (aka FPR24-31)
-	XXLORQ	VS32, VS32, VS24
-	XXLORQ	VS33, VS33, VS25
-	XXLORQ	VS34, VS34, VS26
-	XXLORQ	VS35, VS35, VS27
-	XXLORQ	VS36, VS36, VS28
-	XXLORQ	VS37, VS37, VS29
-	XXLORQ	VS38, VS38, VS30
-	XXLORQ	VS39, VS39, VS31
+	XXLOR	V0, V0, VS24
+	XXLOR	V1, V1, VS25
+	XXLOR	V2, V2, VS26
+	XXLOR	V3, V3, VS27
+	XXLOR	V4, V4, VS28
+	XXLOR	V5, V5, VS29
+	XXLOR	V6, V6, VS30
+	XXLOR	V7, V7, VS31
 
-	VADDUWM	KI, V7, V7	// h+K[i]
-	LVX	(TBL)(IDX), KI
-	ADD	$16, IDX
+	VADDUWM	KI, V7, V7        // h+K[i]
+	LVX	(TBL)(R_x010), KI
 
 	VPERMLE(V8, V8, LEMASK, V8)
-	SHA256ROUND0(V0, V1, V2, V3, V4, V5, V6, V7, V8)
+	SHA256ROUND0(V0, V1, V2, V3, V4, V5, V6, V7, V8, R_x020)
 	VSLDOI	$4, V8, V8, V9
-	SHA256ROUND0(V7, V0, V1, V2, V3, V4, V5, V6, V9)
+	SHA256ROUND0(V7, V0, V1, V2, V3, V4, V5, V6, V9, R_x030)
 	VSLDOI	$4, V9, V9, V10
-	SHA256ROUND0(V6, V7, V0, V1, V2, V3, V4, V5, V10)
-	LXVD2X	(INP)(R0), VS44	// load v12 (=vs44) in advance
-	ADD	$16, INP, INP
+	SHA256ROUND0(V6, V7, V0, V1, V2, V3, V4, V5, V10, R_x040)
+	LXVD2X	(INP)(R_x010), V12 // load v12 in advance
 	VSLDOI	$4, V10, V10, V11
-	SHA256ROUND0(V5, V6, V7, V0, V1, V2, V3, V4, V11)
+	SHA256ROUND0(V5, V6, V7, V0, V1, V2, V3, V4, V11, R_x050)
 	VPERMLE(V12, V12, LEMASK, V12)
-	SHA256ROUND0(V4, V5, V6, V7, V0, V1, V2, V3, V12)
+	SHA256ROUND0(V4, V5, V6, V7, V0, V1, V2, V3, V12, R_x060)
 	VSLDOI	$4, V12, V12, V13
-	SHA256ROUND0(V3, V4, V5, V6, V7, V0, V1, V2, V13)
+	SHA256ROUND0(V3, V4, V5, V6, V7, V0, V1, V2, V13, R_x070)
 	VSLDOI	$4, V13, V13, V14
-	SHA256ROUND0(V2, V3, V4, V5, V6, V7, V0, V1, V14)
-	LXVD2X	(INP)(R0), VS48	// load v16 (=vs48) in advance
-	ADD	$16, INP, INP
+	SHA256ROUND0(V2, V3, V4, V5, V6, V7, V0, V1, V14, R_x080)
+	LXVD2X	(INP)(R_x020), V16 // load v16 in advance
 	VSLDOI	$4, V14, V14, V15
-	SHA256ROUND0(V1, V2, V3, V4, V5, V6, V7, V0, V15)
+	SHA256ROUND0(V1, V2, V3, V4, V5, V6, V7, V0, V15, R_x090)
 	VPERMLE(V16, V16, LEMASK, V16)
-	SHA256ROUND0(V0, V1, V2, V3, V4, V5, V6, V7, V16)
+	SHA256ROUND0(V0, V1, V2, V3, V4, V5, V6, V7, V16, R_x0a0)
 	VSLDOI	$4, V16, V16, V17
-	SHA256ROUND0(V7, V0, V1, V2, V3, V4, V5, V6, V17)
+	SHA256ROUND0(V7, V0, V1, V2, V3, V4, V5, V6, V17, R_x0b0)
 	VSLDOI	$4, V17, V17, V18
-	SHA256ROUND0(V6, V7, V0, V1, V2, V3, V4, V5, V18)
+	SHA256ROUND0(V6, V7, V0, V1, V2, V3, V4, V5, V18, R_x0c0)
 	VSLDOI	$4, V18, V18, V19
-	LXVD2X	(INP)(R0), VS52	// load v20 (=vs52) in advance
-	ADD	$16, INP, INP
-	SHA256ROUND0(V5, V6, V7, V0, V1, V2, V3, V4, V19)
+	LXVD2X	(INP)(R_x030), V20 // load v20 in advance
+	SHA256ROUND0(V5, V6, V7, V0, V1, V2, V3, V4, V19, R_x0d0)
 	VPERMLE(V20, V20, LEMASK, V20)
-	SHA256ROUND0(V4, V5, V6, V7, V0, V1, V2, V3, V20)
+	SHA256ROUND0(V4, V5, V6, V7, V0, V1, V2, V3, V20, R_x0e0)
 	VSLDOI	$4, V20, V20, V21
-	SHA256ROUND0(V3, V4, V5, V6, V7, V0, V1, V2, V21)
+	SHA256ROUND0(V3, V4, V5, V6, V7, V0, V1, V2, V21, R_x0f0)
 	VSLDOI	$4, V21, V21, V22
-	SHA256ROUND0(V2, V3, V4, V5, V6, V7, V0, V1, V22)
+	SHA256ROUND0(V2, V3, V4, V5, V6, V7, V0, V1, V22, R_x100)
 	VSLDOI	$4, V22, V22, V23
-	SHA256ROUND1(V1, V2, V3, V4, V5, V6, V7, V0, V23, V8, V9, V17, V22)
+	SHA256ROUND1(V1, V2, V3, V4, V5, V6, V7, V0, V23, V8, V9, V17, V22, R_x110)
 
-	MOVWZ	$3, TEMP
-	MOVWZ	TEMP, CTR
+	MOVD	$3, TEMP
+	MOVD	TEMP, CTR
+	ADD	$0x120, TBL
+	ADD	$0x40, INP
 
 L16_xx:
-	SHA256ROUND1(V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V18, V23)
-	SHA256ROUND1(V7, V0, V1, V2, V3, V4, V5, V6, V9, V10, V11, V19, V8)
-	SHA256ROUND1(V6, V7, V0, V1, V2, V3, V4, V5, V10, V11, V12, V20, V9)
-	SHA256ROUND1(V5, V6, V7, V0, V1, V2, V3, V4, V11, V12, V13, V21, V10)
-	SHA256ROUND1(V4, V5, V6, V7, V0, V1, V2, V3, V12, V13, V14, V22, V11)
-	SHA256ROUND1(V3, V4, V5, V6, V7, V0, V1, V2, V13, V14, V15, V23, V12)
-	SHA256ROUND1(V2, V3, V4, V5, V6, V7, V0, V1, V14, V15, V16, V8, V13)
-	SHA256ROUND1(V1, V2, V3, V4, V5, V6, V7, V0, V15, V16, V17, V9, V14)
-	SHA256ROUND1(V0, V1, V2, V3, V4, V5, V6, V7, V16, V17, V18, V10, V15)
-	SHA256ROUND1(V7, V0, V1, V2, V3, V4, V5, V6, V17, V18, V19, V11, V16)
-	SHA256ROUND1(V6, V7, V0, V1, V2, V3, V4, V5, V18, V19, V20, V12, V17)
-	SHA256ROUND1(V5, V6, V7, V0, V1, V2, V3, V4, V19, V20, V21, V13, V18)
-	SHA256ROUND1(V4, V5, V6, V7, V0, V1, V2, V3, V20, V21, V22, V14, V19)
-	SHA256ROUND1(V3, V4, V5, V6, V7, V0, V1, V2, V21, V22, V23, V15, V20)
-	SHA256ROUND1(V2, V3, V4, V5, V6, V7, V0, V1, V22, V23, V8, V16, V21)
-	SHA256ROUND1(V1, V2, V3, V4, V5, V6, V7, V0, V23, V8, V9, V17, V22)
+	SHA256ROUND1(V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V18, V23, R_x000)
+	SHA256ROUND1(V7, V0, V1, V2, V3, V4, V5, V6, V9, V10, V11, V19, V8, R_x010)
+	SHA256ROUND1(V6, V7, V0, V1, V2, V3, V4, V5, V10, V11, V12, V20, V9, R_x020)
+	SHA256ROUND1(V5, V6, V7, V0, V1, V2, V3, V4, V11, V12, V13, V21, V10, R_x030)
+	SHA256ROUND1(V4, V5, V6, V7, V0, V1, V2, V3, V12, V13, V14, V22, V11, R_x040)
+	SHA256ROUND1(V3, V4, V5, V6, V7, V0, V1, V2, V13, V14, V15, V23, V12, R_x050)
+	SHA256ROUND1(V2, V3, V4, V5, V6, V7, V0, V1, V14, V15, V16, V8, V13, R_x060)
+	SHA256ROUND1(V1, V2, V3, V4, V5, V6, V7, V0, V15, V16, V17, V9, V14, R_x070)
+	SHA256ROUND1(V0, V1, V2, V3, V4, V5, V6, V7, V16, V17, V18, V10, V15, R_x080)
+	SHA256ROUND1(V7, V0, V1, V2, V3, V4, V5, V6, V17, V18, V19, V11, V16, R_x090)
+	SHA256ROUND1(V6, V7, V0, V1, V2, V3, V4, V5, V18, V19, V20, V12, V17, R_x0a0)
+	SHA256ROUND1(V5, V6, V7, V0, V1, V2, V3, V4, V19, V20, V21, V13, V18, R_x0b0)
+	SHA256ROUND1(V4, V5, V6, V7, V0, V1, V2, V3, V20, V21, V22, V14, V19, R_x0c0)
+	SHA256ROUND1(V3, V4, V5, V6, V7, V0, V1, V2, V21, V22, V23, V15, V20, R_x0d0)
+	SHA256ROUND1(V2, V3, V4, V5, V6, V7, V0, V1, V22, V23, V8, V16, V21, R_x0e0)
+	SHA256ROUND1(V1, V2, V3, V4, V5, V6, V7, V0, V23, V8, V9, V17, V22, R_x0f0)
+	ADD	$0x100, TBL
 
-	BC	0x10, 0, L16_xx		// bdnz
+	BDNZ	L16_xx
 
-	XXLORQ	VS24, VS24, VS42
+	XXLOR	VS24, VS24, V10
 
-	XXLORQ	VS25, VS25, VS43
+	XXLOR	VS25, VS25, V11
 	VADDUWM	V10, V0, V0
-	XXLORQ	VS26, VS26, VS44
+	XXLOR	VS26, VS26, V12
 	VADDUWM	V11, V1, V1
-	XXLORQ	VS27, VS27, VS45
+	XXLOR	VS27, VS27, V13
 	VADDUWM	V12, V2, V2
-	XXLORQ	VS28, VS28, VS46
+	XXLOR	VS28, VS28, V14
 	VADDUWM	V13, V3, V3
-	XXLORQ	VS29, VS29, VS47
+	XXLOR	VS29, VS29, V15
 	VADDUWM	V14, V4, V4
-	XXLORQ	VS30, VS30, VS48
+	XXLOR	VS30, VS30, V16
 	VADDUWM	V15, V5, V5
-	XXLORQ	VS31, VS31, VS49
+	XXLOR	VS31, VS31, V17
 	VADDUWM	V16, V6, V6
 	VADDUWM	V17, V7, V7
 
 	CMPU	INP, END
 	BLT	loop
 
-	LVX	(TBL)(IDX), V8
-	ADD	$16, IDX
+	LVX	(TBL)(R_x000), V8
 	VPERM	V0, V1, KI, V0
-	LVX	(TBL)(IDX), V9
+	LVX	(TBL)(R_x010), V9
 	VPERM	V4, V5, KI, V4
 	VPERM	V0, V2, V8, V0
 	VPERM	V4, V6, V8, V4
 	VPERM	V0, V3, V9, V0
 	VPERM	V4, V7, V9, V4
-	STXVD2X	VS32, (CTX+HEX00)	// v0 = vs32
-	STXVD2X	VS36, (CTX+HEX10)	// v4 = vs36
+	STXVD2X	V0, (CTX+R_x000)
+	STXVD2X	V4, (CTX+R_x010)
 
 end:
 	RET
diff --git a/src/cmd/internal/obj/arm64/a.out.go b/src/cmd/internal/obj/arm64/a.out.go
index d6522f5..3bfc675 100644
--- a/src/cmd/internal/obj/arm64/a.out.go
+++ b/src/cmd/internal/obj/arm64/a.out.go
@@ -343,6 +343,7 @@
 	// The more specific class needs to come earlier.
 	C_NONE   = iota
 	C_REG    // R0..R30
+	C_ZREG   // R0..R30, ZR
 	C_RSP    // R0..R30, RSP
 	C_FREG   // F0..F31
 	C_VREG   // V0..V31
@@ -356,7 +357,7 @@
 	C_ELEM   // Vn.<T>[index]
 	C_LIST   // [V1, V2, V3]
 
-	C_ZCON     // $0 or ZR
+	C_ZCON     // $0
 	C_ABCON0   // could be C_ADDCON0 or C_BITCON
 	C_ADDCON0  // 12-bit unsigned, unshifted
 	C_ABCON    // could be C_ADDCON or C_BITCON
@@ -1009,6 +1010,7 @@
 	AVBSL
 	AVBIT
 	AVTBL
+	AVTBX
 	AVXAR
 	AVZIP1
 	AVZIP2
diff --git a/src/cmd/internal/obj/arm64/anames.go b/src/cmd/internal/obj/arm64/anames.go
index ab97a1a..03222f9 100644
--- a/src/cmd/internal/obj/arm64/anames.go
+++ b/src/cmd/internal/obj/arm64/anames.go
@@ -530,6 +530,7 @@
 	"VBSL",
 	"VBIT",
 	"VTBL",
+	"VTBX",
 	"VXAR",
 	"VZIP1",
 	"VZIP2",
diff --git a/src/cmd/internal/obj/arm64/anames7.go b/src/cmd/internal/obj/arm64/anames7.go
index 54fc939..2f20dfe 100644
--- a/src/cmd/internal/obj/arm64/anames7.go
+++ b/src/cmd/internal/obj/arm64/anames7.go
@@ -8,6 +8,7 @@
 var cnames7 = []string{
 	"NONE",
 	"REG",
+	"ZREG",
 	"RSP",
 	"FREG",
 	"VREG",
diff --git a/src/cmd/internal/obj/arm64/asm7.go b/src/cmd/internal/obj/arm64/asm7.go
index c2894a0..db18bc8 100644
--- a/src/cmd/internal/obj/arm64/asm7.go
+++ b/src/cmd/internal/obj/arm64/asm7.go
@@ -37,6 +37,7 @@
 	"log"
 	"math"
 	"sort"
+	"strings"
 )
 
 // ctxt7 holds state while assembling a single function.
@@ -73,7 +74,7 @@
 	a3    uint8
 	a4    uint8
 	type_ int8
-	size  int8
+	size_ int8 // the value of this field is not static, use the size() method to return the value
 	param int16
 	flag  int8
 	scond uint16
@@ -279,10 +280,12 @@
 
 const (
 	// Optab.flag
-	LFROM     = 1 << 0 // p.From uses constant pool
-	LFROM128  = 1 << 1 // p.From3<<64+p.From forms a 128-bit constant in literal pool
-	LTO       = 1 << 2 // p.To uses constant pool
-	NOTUSETMP = 1 << 3 // p expands to multiple instructions, but does NOT use REGTMP
+	LFROM        = 1 << iota // p.From uses constant pool
+	LFROM128                 // p.From3<<64+p.From forms a 128-bit constant in literal pool
+	LTO                      // p.To uses constant pool
+	NOTUSETMP                // p expands to multiple instructions, but does NOT use REGTMP
+	BRANCH14BITS             // branch instruction encodes 14 bits
+	BRANCH19BITS             // branch instruction encodes 19 bits
 )
 
 var optab = []Optab{
@@ -291,14 +294,14 @@
 	{obj.ATEXT, C_ADDR, C_NONE, C_NONE, C_TEXTSIZE, 0, 0, 0, 0, 0},
 
 	/* arithmetic operations */
-	{AADD, C_REG, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0},
-	{AADD, C_REG, C_NONE, C_NONE, C_REG, 1, 4, 0, 0, 0},
-	{AADC, C_REG, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0},
-	{AADC, C_REG, C_NONE, C_NONE, C_REG, 1, 4, 0, 0, 0},
-	{ANEG, C_REG, C_NONE, C_NONE, C_REG, 25, 4, 0, 0, 0},
-	{ANEG, C_NONE, C_NONE, C_NONE, C_REG, 25, 4, 0, 0, 0},
-	{ANGC, C_REG, C_NONE, C_NONE, C_REG, 17, 4, 0, 0, 0},
-	{ACMP, C_REG, C_REG, C_NONE, C_NONE, 1, 4, 0, 0, 0},
+	{AADD, C_ZREG, C_ZREG, C_NONE, C_ZREG, 1, 4, 0, 0, 0},
+	{AADD, C_ZREG, C_NONE, C_NONE, C_ZREG, 1, 4, 0, 0, 0},
+	{AADC, C_ZREG, C_ZREG, C_NONE, C_ZREG, 1, 4, 0, 0, 0},
+	{AADC, C_ZREG, C_NONE, C_NONE, C_ZREG, 1, 4, 0, 0, 0},
+	{ANEG, C_ZREG, C_NONE, C_NONE, C_ZREG, 25, 4, 0, 0, 0},
+	{ANEG, C_NONE, C_NONE, C_NONE, C_ZREG, 25, 4, 0, 0, 0},
+	{ANGC, C_ZREG, C_NONE, C_NONE, C_ZREG, 17, 4, 0, 0, 0},
+	{ACMP, C_ZREG, C_ZREG, C_NONE, C_NONE, 1, 4, 0, 0, 0},
 	{AADD, C_ADDCON, C_RSP, C_NONE, C_RSP, 2, 4, 0, 0, 0},
 	{AADD, C_ADDCON, C_NONE, C_NONE, C_RSP, 2, 4, 0, 0, 0},
 	{ACMP, C_ADDCON, C_RSP, C_NONE, C_NONE, 2, 4, 0, 0, 0},
@@ -316,29 +319,29 @@
 	{AADD, C_MOVCON3, C_NONE, C_NONE, C_RSP, 13, 16, 0, 0, 0},
 	{AADD, C_VCON, C_RSP, C_NONE, C_RSP, 13, 20, 0, 0, 0},
 	{AADD, C_VCON, C_NONE, C_NONE, C_RSP, 13, 20, 0, 0, 0},
-	{ACMP, C_MOVCON2, C_REG, C_NONE, C_NONE, 13, 12, 0, 0, 0},
-	{ACMP, C_MOVCON3, C_REG, C_NONE, C_NONE, 13, 16, 0, 0, 0},
-	{ACMP, C_VCON, C_REG, C_NONE, C_NONE, 13, 20, 0, 0, 0},
-	{AADD, C_SHIFT, C_REG, C_NONE, C_REG, 3, 4, 0, 0, 0},
-	{AADD, C_SHIFT, C_NONE, C_NONE, C_REG, 3, 4, 0, 0, 0},
-	{AMVN, C_SHIFT, C_NONE, C_NONE, C_REG, 3, 4, 0, 0, 0},
-	{ACMP, C_SHIFT, C_REG, C_NONE, C_NONE, 3, 4, 0, 0, 0},
-	{ANEG, C_SHIFT, C_NONE, C_NONE, C_REG, 3, 4, 0, 0, 0},
-	{AADD, C_REG, C_RSP, C_NONE, C_RSP, 27, 4, 0, 0, 0},
-	{AADD, C_REG, C_NONE, C_NONE, C_RSP, 27, 4, 0, 0, 0},
-	{ACMP, C_REG, C_RSP, C_NONE, C_NONE, 27, 4, 0, 0, 0},
+	{ACMP, C_MOVCON2, C_ZREG, C_NONE, C_NONE, 13, 12, 0, 0, 0},
+	{ACMP, C_MOVCON3, C_ZREG, C_NONE, C_NONE, 13, 16, 0, 0, 0},
+	{ACMP, C_VCON, C_ZREG, C_NONE, C_NONE, 13, 20, 0, 0, 0},
+	{AADD, C_SHIFT, C_ZREG, C_NONE, C_ZREG, 3, 4, 0, 0, 0},
+	{AADD, C_SHIFT, C_NONE, C_NONE, C_ZREG, 3, 4, 0, 0, 0},
+	{AMVN, C_SHIFT, C_NONE, C_NONE, C_ZREG, 3, 4, 0, 0, 0},
+	{ACMP, C_SHIFT, C_ZREG, C_NONE, C_NONE, 3, 4, 0, 0, 0},
+	{ANEG, C_SHIFT, C_NONE, C_NONE, C_ZREG, 3, 4, 0, 0, 0},
+	{AADD, C_ZREG, C_RSP, C_NONE, C_RSP, 27, 4, 0, 0, 0},
+	{AADD, C_ZREG, C_NONE, C_NONE, C_RSP, 27, 4, 0, 0, 0},
+	{ACMP, C_ZREG, C_RSP, C_NONE, C_NONE, 27, 4, 0, 0, 0},
 	{AADD, C_EXTREG, C_RSP, C_NONE, C_RSP, 27, 4, 0, 0, 0},
 	{AADD, C_EXTREG, C_NONE, C_NONE, C_RSP, 27, 4, 0, 0, 0},
 	{ACMP, C_EXTREG, C_RSP, C_NONE, C_NONE, 27, 4, 0, 0, 0},
-	{AADD, C_REG, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0},
-	{AADD, C_REG, C_NONE, C_NONE, C_REG, 1, 4, 0, 0, 0},
-	{AMUL, C_REG, C_REG, C_NONE, C_REG, 15, 4, 0, 0, 0},
-	{AMUL, C_REG, C_NONE, C_NONE, C_REG, 15, 4, 0, 0, 0},
-	{AMADD, C_REG, C_REG, C_REG, C_REG, 15, 4, 0, 0, 0},
-	{AREM, C_REG, C_REG, C_NONE, C_REG, 16, 8, 0, 0, 0},
-	{AREM, C_REG, C_NONE, C_NONE, C_REG, 16, 8, 0, 0, 0},
-	{ASDIV, C_REG, C_NONE, C_NONE, C_REG, 1, 4, 0, 0, 0},
-	{ASDIV, C_REG, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0},
+	{AADD, C_ZREG, C_ZREG, C_NONE, C_ZREG, 1, 4, 0, 0, 0},
+	{AADD, C_ZREG, C_NONE, C_NONE, C_ZREG, 1, 4, 0, 0, 0},
+	{AMUL, C_ZREG, C_ZREG, C_NONE, C_ZREG, 15, 4, 0, 0, 0},
+	{AMUL, C_ZREG, C_NONE, C_NONE, C_ZREG, 15, 4, 0, 0, 0},
+	{AMADD, C_ZREG, C_ZREG, C_ZREG, C_ZREG, 15, 4, 0, 0, 0},
+	{AREM, C_ZREG, C_ZREG, C_NONE, C_ZREG, 16, 8, 0, 0, 0},
+	{AREM, C_ZREG, C_NONE, C_NONE, C_ZREG, 16, 8, 0, 0, 0},
+	{ASDIV, C_ZREG, C_NONE, C_NONE, C_ZREG, 1, 4, 0, 0, 0},
+	{ASDIV, C_ZREG, C_ZREG, C_NONE, C_ZREG, 1, 4, 0, 0, 0},
 
 	{AFADDS, C_FREG, C_NONE, C_NONE, C_FREG, 54, 4, 0, 0, 0},
 	{AFADDS, C_FREG, C_FREG, C_NONE, C_FREG, 54, 4, 0, 0, 0},
@@ -352,67 +355,67 @@
 	{AVADDV, C_ARNG, C_NONE, C_NONE, C_VREG, 85, 4, 0, 0, 0},
 
 	/* logical operations */
-	{AAND, C_REG, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0},
-	{AAND, C_REG, C_NONE, C_NONE, C_REG, 1, 4, 0, 0, 0},
-	{AANDS, C_REG, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0},
-	{AANDS, C_REG, C_NONE, C_NONE, C_REG, 1, 4, 0, 0, 0},
-	{ATST, C_REG, C_REG, C_NONE, C_NONE, 1, 4, 0, 0, 0},
-	{AAND, C_MBCON, C_REG, C_NONE, C_RSP, 53, 4, 0, 0, 0},
+	{AAND, C_ZREG, C_ZREG, C_NONE, C_ZREG, 1, 4, 0, 0, 0},
+	{AAND, C_ZREG, C_NONE, C_NONE, C_ZREG, 1, 4, 0, 0, 0},
+	{AANDS, C_ZREG, C_ZREG, C_NONE, C_ZREG, 1, 4, 0, 0, 0},
+	{AANDS, C_ZREG, C_NONE, C_NONE, C_ZREG, 1, 4, 0, 0, 0},
+	{ATST, C_ZREG, C_ZREG, C_NONE, C_NONE, 1, 4, 0, 0, 0},
+	{AAND, C_MBCON, C_ZREG, C_NONE, C_RSP, 53, 4, 0, 0, 0},
 	{AAND, C_MBCON, C_NONE, C_NONE, C_RSP, 53, 4, 0, 0, 0},
-	{AANDS, C_MBCON, C_REG, C_NONE, C_REG, 53, 4, 0, 0, 0},
-	{AANDS, C_MBCON, C_NONE, C_NONE, C_REG, 53, 4, 0, 0, 0},
-	{ATST, C_MBCON, C_REG, C_NONE, C_NONE, 53, 4, 0, 0, 0},
-	{AAND, C_BITCON, C_REG, C_NONE, C_RSP, 53, 4, 0, 0, 0},
+	{AANDS, C_MBCON, C_ZREG, C_NONE, C_ZREG, 53, 4, 0, 0, 0},
+	{AANDS, C_MBCON, C_NONE, C_NONE, C_ZREG, 53, 4, 0, 0, 0},
+	{ATST, C_MBCON, C_ZREG, C_NONE, C_NONE, 53, 4, 0, 0, 0},
+	{AAND, C_BITCON, C_ZREG, C_NONE, C_RSP, 53, 4, 0, 0, 0},
 	{AAND, C_BITCON, C_NONE, C_NONE, C_RSP, 53, 4, 0, 0, 0},
-	{AANDS, C_BITCON, C_REG, C_NONE, C_REG, 53, 4, 0, 0, 0},
-	{AANDS, C_BITCON, C_NONE, C_NONE, C_REG, 53, 4, 0, 0, 0},
-	{ATST, C_BITCON, C_REG, C_NONE, C_NONE, 53, 4, 0, 0, 0},
-	{AAND, C_MOVCON, C_REG, C_NONE, C_REG, 62, 8, 0, 0, 0},
-	{AAND, C_MOVCON, C_NONE, C_NONE, C_REG, 62, 8, 0, 0, 0},
-	{AANDS, C_MOVCON, C_REG, C_NONE, C_REG, 62, 8, 0, 0, 0},
-	{AANDS, C_MOVCON, C_NONE, C_NONE, C_REG, 62, 8, 0, 0, 0},
-	{ATST, C_MOVCON, C_REG, C_NONE, C_NONE, 62, 8, 0, 0, 0},
-	{AAND, C_MOVCON2, C_REG, C_NONE, C_REG, 28, 12, 0, 0, 0},
-	{AAND, C_MOVCON2, C_NONE, C_NONE, C_REG, 28, 12, 0, 0, 0},
-	{AAND, C_MOVCON3, C_REG, C_NONE, C_REG, 28, 16, 0, 0, 0},
-	{AAND, C_MOVCON3, C_NONE, C_NONE, C_REG, 28, 16, 0, 0, 0},
-	{AAND, C_VCON, C_REG, C_NONE, C_REG, 28, 20, 0, 0, 0},
-	{AAND, C_VCON, C_NONE, C_NONE, C_REG, 28, 20, 0, 0, 0},
-	{AANDS, C_MOVCON2, C_REG, C_NONE, C_REG, 28, 12, 0, 0, 0},
-	{AANDS, C_MOVCON2, C_NONE, C_NONE, C_REG, 28, 12, 0, 0, 0},
-	{AANDS, C_MOVCON3, C_REG, C_NONE, C_REG, 28, 16, 0, 0, 0},
-	{AANDS, C_MOVCON3, C_NONE, C_NONE, C_REG, 28, 16, 0, 0, 0},
-	{AANDS, C_VCON, C_REG, C_NONE, C_REG, 28, 20, 0, 0, 0},
-	{AANDS, C_VCON, C_NONE, C_NONE, C_REG, 28, 20, 0, 0, 0},
-	{ATST, C_MOVCON2, C_REG, C_NONE, C_NONE, 28, 12, 0, 0, 0},
-	{ATST, C_MOVCON3, C_REG, C_NONE, C_NONE, 28, 16, 0, 0, 0},
-	{ATST, C_VCON, C_REG, C_NONE, C_NONE, 28, 20, 0, 0, 0},
-	{AAND, C_SHIFT, C_REG, C_NONE, C_REG, 3, 4, 0, 0, 0},
-	{AAND, C_SHIFT, C_NONE, C_NONE, C_REG, 3, 4, 0, 0, 0},
-	{AANDS, C_SHIFT, C_REG, C_NONE, C_REG, 3, 4, 0, 0, 0},
-	{AANDS, C_SHIFT, C_NONE, C_NONE, C_REG, 3, 4, 0, 0, 0},
-	{ATST, C_SHIFT, C_REG, C_NONE, C_NONE, 3, 4, 0, 0, 0},
+	{AANDS, C_BITCON, C_ZREG, C_NONE, C_ZREG, 53, 4, 0, 0, 0},
+	{AANDS, C_BITCON, C_NONE, C_NONE, C_ZREG, 53, 4, 0, 0, 0},
+	{ATST, C_BITCON, C_ZREG, C_NONE, C_NONE, 53, 4, 0, 0, 0},
+	{AAND, C_MOVCON, C_ZREG, C_NONE, C_ZREG, 62, 8, 0, 0, 0},
+	{AAND, C_MOVCON, C_NONE, C_NONE, C_ZREG, 62, 8, 0, 0, 0},
+	{AANDS, C_MOVCON, C_ZREG, C_NONE, C_ZREG, 62, 8, 0, 0, 0},
+	{AANDS, C_MOVCON, C_NONE, C_NONE, C_ZREG, 62, 8, 0, 0, 0},
+	{ATST, C_MOVCON, C_ZREG, C_NONE, C_NONE, 62, 8, 0, 0, 0},
+	{AAND, C_MOVCON2, C_ZREG, C_NONE, C_ZREG, 28, 12, 0, 0, 0},
+	{AAND, C_MOVCON2, C_NONE, C_NONE, C_ZREG, 28, 12, 0, 0, 0},
+	{AAND, C_MOVCON3, C_ZREG, C_NONE, C_ZREG, 28, 16, 0, 0, 0},
+	{AAND, C_MOVCON3, C_NONE, C_NONE, C_ZREG, 28, 16, 0, 0, 0},
+	{AAND, C_VCON, C_ZREG, C_NONE, C_ZREG, 28, 20, 0, 0, 0},
+	{AAND, C_VCON, C_NONE, C_NONE, C_ZREG, 28, 20, 0, 0, 0},
+	{AANDS, C_MOVCON2, C_ZREG, C_NONE, C_ZREG, 28, 12, 0, 0, 0},
+	{AANDS, C_MOVCON2, C_NONE, C_NONE, C_ZREG, 28, 12, 0, 0, 0},
+	{AANDS, C_MOVCON3, C_ZREG, C_NONE, C_ZREG, 28, 16, 0, 0, 0},
+	{AANDS, C_MOVCON3, C_NONE, C_NONE, C_ZREG, 28, 16, 0, 0, 0},
+	{AANDS, C_VCON, C_ZREG, C_NONE, C_ZREG, 28, 20, 0, 0, 0},
+	{AANDS, C_VCON, C_NONE, C_NONE, C_ZREG, 28, 20, 0, 0, 0},
+	{ATST, C_MOVCON2, C_ZREG, C_NONE, C_NONE, 28, 12, 0, 0, 0},
+	{ATST, C_MOVCON3, C_ZREG, C_NONE, C_NONE, 28, 16, 0, 0, 0},
+	{ATST, C_VCON, C_ZREG, C_NONE, C_NONE, 28, 20, 0, 0, 0},
+	{AAND, C_SHIFT, C_ZREG, C_NONE, C_ZREG, 3, 4, 0, 0, 0},
+	{AAND, C_SHIFT, C_NONE, C_NONE, C_ZREG, 3, 4, 0, 0, 0},
+	{AANDS, C_SHIFT, C_ZREG, C_NONE, C_ZREG, 3, 4, 0, 0, 0},
+	{AANDS, C_SHIFT, C_NONE, C_NONE, C_ZREG, 3, 4, 0, 0, 0},
+	{ATST, C_SHIFT, C_ZREG, C_NONE, C_NONE, 3, 4, 0, 0, 0},
 	{AMOVD, C_RSP, C_NONE, C_NONE, C_RSP, 24, 4, 0, 0, 0},
-	{AMVN, C_REG, C_NONE, C_NONE, C_REG, 24, 4, 0, 0, 0},
-	{AMOVB, C_REG, C_NONE, C_NONE, C_REG, 45, 4, 0, 0, 0},
-	{AMOVBU, C_REG, C_NONE, C_NONE, C_REG, 45, 4, 0, 0, 0},
-	{AMOVH, C_REG, C_NONE, C_NONE, C_REG, 45, 4, 0, 0, 0}, /* also MOVHU */
-	{AMOVW, C_REG, C_NONE, C_NONE, C_REG, 45, 4, 0, 0, 0}, /* also MOVWU */
+	{AMOVD, C_ZREG, C_NONE, C_NONE, C_ZREG, 24, 4, 0, 0, 0},
+	{AMVN, C_ZREG, C_NONE, C_NONE, C_ZREG, 24, 4, 0, 0, 0},
+	{AMOVB, C_ZREG, C_NONE, C_NONE, C_ZREG, 45, 4, 0, 0, 0}, /* also MOVBU */
+	{AMOVH, C_ZREG, C_NONE, C_NONE, C_ZREG, 45, 4, 0, 0, 0}, /* also MOVHU */
+	{AMOVW, C_ZREG, C_NONE, C_NONE, C_ZREG, 45, 4, 0, 0, 0}, /* also MOVWU */
 	/* TODO: MVN C_SHIFT */
 
 	/* MOVs that become MOVK/MOVN/MOVZ/ADD/SUB/OR */
-	{AMOVW, C_MBCON, C_NONE, C_NONE, C_REG, 32, 4, 0, 0, 0},
-	{AMOVD, C_MBCON, C_NONE, C_NONE, C_REG, 32, 4, 0, 0, 0},
-	{AMOVW, C_MOVCON, C_NONE, C_NONE, C_REG, 32, 4, 0, 0, 0},
-	{AMOVD, C_MOVCON, C_NONE, C_NONE, C_REG, 32, 4, 0, 0, 0},
+	{AMOVW, C_MBCON, C_NONE, C_NONE, C_ZREG, 32, 4, 0, 0, 0},
+	{AMOVD, C_MBCON, C_NONE, C_NONE, C_ZREG, 32, 4, 0, 0, 0},
+	{AMOVW, C_MOVCON, C_NONE, C_NONE, C_ZREG, 32, 4, 0, 0, 0},
+	{AMOVD, C_MOVCON, C_NONE, C_NONE, C_ZREG, 32, 4, 0, 0, 0},
 	{AMOVW, C_BITCON, C_NONE, C_NONE, C_RSP, 32, 4, 0, 0, 0},
 	{AMOVD, C_BITCON, C_NONE, C_NONE, C_RSP, 32, 4, 0, 0, 0},
-	{AMOVW, C_MOVCON2, C_NONE, C_NONE, C_REG, 12, 8, 0, NOTUSETMP, 0},
-	{AMOVD, C_MOVCON2, C_NONE, C_NONE, C_REG, 12, 8, 0, NOTUSETMP, 0},
-	{AMOVD, C_MOVCON3, C_NONE, C_NONE, C_REG, 12, 12, 0, NOTUSETMP, 0},
-	{AMOVD, C_VCON, C_NONE, C_NONE, C_REG, 12, 16, 0, NOTUSETMP, 0},
+	{AMOVW, C_MOVCON2, C_NONE, C_NONE, C_ZREG, 12, 8, 0, NOTUSETMP, 0},
+	{AMOVD, C_MOVCON2, C_NONE, C_NONE, C_ZREG, 12, 8, 0, NOTUSETMP, 0},
+	{AMOVD, C_MOVCON3, C_NONE, C_NONE, C_ZREG, 12, 12, 0, NOTUSETMP, 0},
+	{AMOVD, C_VCON, C_NONE, C_NONE, C_ZREG, 12, 16, 0, NOTUSETMP, 0},
 
-	{AMOVK, C_VCON, C_NONE, C_NONE, C_REG, 33, 4, 0, 0, 0},
+	{AMOVK, C_VCON, C_NONE, C_NONE, C_ZREG, 33, 4, 0, 0, 0},
 	{AMOVD, C_AACON, C_NONE, C_NONE, C_RSP, 4, 4, REGFROM, 0, 0},
 	{AMOVD, C_AACON2, C_NONE, C_NONE, C_RSP, 4, 8, REGFROM, NOTUSETMP, 0},
 
@@ -428,31 +431,30 @@
 	{AB, C_NONE, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0},
 	{ABL, C_NONE, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0},
 	{AB, C_NONE, C_NONE, C_NONE, C_ZOREG, 6, 4, 0, 0, 0},
-	{ABL, C_NONE, C_NONE, C_NONE, C_REG, 6, 4, 0, 0, 0},
-	{ABL, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0, 0, 0},
+	{ABL, C_NONE, C_NONE, C_NONE, C_ZREG, 6, 4, 0, 0, 0},
 	{ABL, C_NONE, C_NONE, C_NONE, C_ZOREG, 6, 4, 0, 0, 0},
-	{obj.ARET, C_NONE, C_NONE, C_NONE, C_REG, 6, 4, 0, 0, 0},
+	{obj.ARET, C_NONE, C_NONE, C_NONE, C_ZREG, 6, 4, 0, 0, 0},
 	{obj.ARET, C_NONE, C_NONE, C_NONE, C_ZOREG, 6, 4, 0, 0, 0},
-	{ABEQ, C_NONE, C_NONE, C_NONE, C_SBRA, 7, 4, 0, 0, 0},
-	{ACBZ, C_REG, C_NONE, C_NONE, C_SBRA, 39, 4, 0, 0, 0},
-	{ATBZ, C_VCON, C_REG, C_NONE, C_SBRA, 40, 4, 0, 0, 0},
+	{ABEQ, C_NONE, C_NONE, C_NONE, C_SBRA, 7, 4, 0, BRANCH19BITS, 0},
+	{ACBZ, C_ZREG, C_NONE, C_NONE, C_SBRA, 39, 4, 0, BRANCH19BITS, 0},
+	{ATBZ, C_VCON, C_ZREG, C_NONE, C_SBRA, 40, 4, 0, BRANCH14BITS, 0},
 	{AERET, C_NONE, C_NONE, C_NONE, C_NONE, 41, 4, 0, 0, 0},
 
 	// get a PC-relative address
-	{AADRP, C_SBRA, C_NONE, C_NONE, C_REG, 60, 4, 0, 0, 0},
-	{AADR, C_SBRA, C_NONE, C_NONE, C_REG, 61, 4, 0, 0, 0},
+	{AADRP, C_SBRA, C_NONE, C_NONE, C_ZREG, 60, 4, 0, 0, 0},
+	{AADR, C_SBRA, C_NONE, C_NONE, C_ZREG, 61, 4, 0, 0, 0},
 
 	{ACLREX, C_NONE, C_NONE, C_NONE, C_VCON, 38, 4, 0, 0, 0},
 	{ACLREX, C_NONE, C_NONE, C_NONE, C_NONE, 38, 4, 0, 0, 0},
-	{ABFM, C_VCON, C_REG, C_VCON, C_REG, 42, 4, 0, 0, 0},
-	{ABFI, C_VCON, C_REG, C_VCON, C_REG, 43, 4, 0, 0, 0},
-	{AEXTR, C_VCON, C_REG, C_REG, C_REG, 44, 4, 0, 0, 0},
-	{ASXTB, C_REG, C_NONE, C_NONE, C_REG, 45, 4, 0, 0, 0},
-	{ACLS, C_REG, C_NONE, C_NONE, C_REG, 46, 4, 0, 0, 0},
-	{ALSL, C_VCON, C_REG, C_NONE, C_REG, 8, 4, 0, 0, 0},
-	{ALSL, C_VCON, C_NONE, C_NONE, C_REG, 8, 4, 0, 0, 0},
-	{ALSL, C_REG, C_NONE, C_NONE, C_REG, 9, 4, 0, 0, 0},
-	{ALSL, C_REG, C_REG, C_NONE, C_REG, 9, 4, 0, 0, 0},
+	{ABFM, C_VCON, C_ZREG, C_VCON, C_ZREG, 42, 4, 0, 0, 0},
+	{ABFI, C_VCON, C_ZREG, C_VCON, C_ZREG, 43, 4, 0, 0, 0},
+	{AEXTR, C_VCON, C_ZREG, C_ZREG, C_ZREG, 44, 4, 0, 0, 0},
+	{ASXTB, C_ZREG, C_NONE, C_NONE, C_ZREG, 45, 4, 0, 0, 0},
+	{ACLS, C_ZREG, C_NONE, C_NONE, C_ZREG, 46, 4, 0, 0, 0},
+	{ALSL, C_VCON, C_ZREG, C_NONE, C_ZREG, 8, 4, 0, 0, 0},
+	{ALSL, C_VCON, C_NONE, C_NONE, C_ZREG, 8, 4, 0, 0, 0},
+	{ALSL, C_ZREG, C_NONE, C_NONE, C_ZREG, 9, 4, 0, 0, 0},
+	{ALSL, C_ZREG, C_ZREG, C_NONE, C_ZREG, 9, 4, 0, 0, 0},
 	{ASVC, C_VCON, C_NONE, C_NONE, C_NONE, 10, 4, 0, 0, 0},
 	{ASVC, C_NONE, C_NONE, C_NONE, C_NONE, 10, 4, 0, 0, 0},
 	{ADWORD, C_NONE, C_NONE, C_NONE, C_VCON, 11, 8, 0, NOTUSETMP, 0},
@@ -462,21 +464,19 @@
 	{AWORD, C_NONE, C_NONE, C_NONE, C_LCON, 14, 4, 0, 0, 0},
 	{AWORD, C_NONE, C_NONE, C_NONE, C_LEXT, 14, 4, 0, 0, 0},
 	{AWORD, C_NONE, C_NONE, C_NONE, C_ADDR, 14, 4, 0, 0, 0},
-	{AMOVW, C_VCONADDR, C_NONE, C_NONE, C_REG, 68, 8, 0, NOTUSETMP, 0},
-	{AMOVD, C_VCONADDR, C_NONE, C_NONE, C_REG, 68, 8, 0, NOTUSETMP, 0},
-	{AMOVB, C_REG, C_NONE, C_NONE, C_ADDR, 64, 12, 0, 0, 0},
-	{AMOVBU, C_REG, C_NONE, C_NONE, C_ADDR, 64, 12, 0, 0, 0},
-	{AMOVH, C_REG, C_NONE, C_NONE, C_ADDR, 64, 12, 0, 0, 0},
-	{AMOVW, C_REG, C_NONE, C_NONE, C_ADDR, 64, 12, 0, 0, 0},
-	{AMOVD, C_REG, C_NONE, C_NONE, C_ADDR, 64, 12, 0, 0, 0},
-	{AMOVB, C_ADDR, C_NONE, C_NONE, C_REG, 65, 12, 0, 0, 0},
-	{AMOVBU, C_ADDR, C_NONE, C_NONE, C_REG, 65, 12, 0, 0, 0},
-	{AMOVH, C_ADDR, C_NONE, C_NONE, C_REG, 65, 12, 0, 0, 0},
-	{AMOVW, C_ADDR, C_NONE, C_NONE, C_REG, 65, 12, 0, 0, 0},
-	{AMOVD, C_ADDR, C_NONE, C_NONE, C_REG, 65, 12, 0, 0, 0},
-	{AMOVD, C_GOTADDR, C_NONE, C_NONE, C_REG, 71, 8, 0, 0, 0},
-	{AMOVD, C_TLS_LE, C_NONE, C_NONE, C_REG, 69, 4, 0, 0, 0},
-	{AMOVD, C_TLS_IE, C_NONE, C_NONE, C_REG, 70, 8, 0, 0, 0},
+	{AMOVW, C_VCONADDR, C_NONE, C_NONE, C_ZREG, 68, 8, 0, NOTUSETMP, 0},
+	{AMOVD, C_VCONADDR, C_NONE, C_NONE, C_ZREG, 68, 8, 0, NOTUSETMP, 0},
+	{AMOVB, C_ZREG, C_NONE, C_NONE, C_ADDR, 64, 12, 0, 0, 0},
+	{AMOVH, C_ZREG, C_NONE, C_NONE, C_ADDR, 64, 12, 0, 0, 0},
+	{AMOVW, C_ZREG, C_NONE, C_NONE, C_ADDR, 64, 12, 0, 0, 0},
+	{AMOVD, C_ZREG, C_NONE, C_NONE, C_ADDR, 64, 12, 0, 0, 0},
+	{AMOVB, C_ADDR, C_NONE, C_NONE, C_ZREG, 65, 12, 0, 0, 0},
+	{AMOVH, C_ADDR, C_NONE, C_NONE, C_ZREG, 65, 12, 0, 0, 0},
+	{AMOVW, C_ADDR, C_NONE, C_NONE, C_ZREG, 65, 12, 0, 0, 0},
+	{AMOVD, C_ADDR, C_NONE, C_NONE, C_ZREG, 65, 12, 0, 0, 0},
+	{AMOVD, C_GOTADDR, C_NONE, C_NONE, C_ZREG, 71, 8, 0, 0, 0},
+	{AMOVD, C_TLS_LE, C_NONE, C_NONE, C_ZREG, 69, 4, 0, 0, 0},
+	{AMOVD, C_TLS_IE, C_NONE, C_NONE, C_ZREG, 70, 8, 0, 0, 0},
 
 	{AFMOVS, C_FREG, C_NONE, C_NONE, C_ADDR, 64, 12, 0, 0, 0},
 	{AFMOVS, C_ADDR, C_NONE, C_NONE, C_FREG, 65, 12, 0, 0, 0},
@@ -486,22 +486,22 @@
 	{AFMOVS, C_FREG, C_NONE, C_NONE, C_FREG, 54, 4, 0, 0, 0},
 	{AFMOVD, C_FCON, C_NONE, C_NONE, C_FREG, 55, 4, 0, 0, 0},
 	{AFMOVD, C_FREG, C_NONE, C_NONE, C_FREG, 54, 4, 0, 0, 0},
-	{AFMOVS, C_REG, C_NONE, C_NONE, C_FREG, 29, 4, 0, 0, 0},
-	{AFMOVS, C_FREG, C_NONE, C_NONE, C_REG, 29, 4, 0, 0, 0},
-	{AFMOVD, C_REG, C_NONE, C_NONE, C_FREG, 29, 4, 0, 0, 0},
-	{AFMOVD, C_FREG, C_NONE, C_NONE, C_REG, 29, 4, 0, 0, 0},
-	{AFCVTZSD, C_FREG, C_NONE, C_NONE, C_REG, 29, 4, 0, 0, 0},
-	{ASCVTFD, C_REG, C_NONE, C_NONE, C_FREG, 29, 4, 0, 0, 0},
+	{AFMOVS, C_ZREG, C_NONE, C_NONE, C_FREG, 29, 4, 0, 0, 0},
+	{AFMOVS, C_FREG, C_NONE, C_NONE, C_ZREG, 29, 4, 0, 0, 0},
+	{AFMOVD, C_ZREG, C_NONE, C_NONE, C_FREG, 29, 4, 0, 0, 0},
+	{AFMOVD, C_FREG, C_NONE, C_NONE, C_ZREG, 29, 4, 0, 0, 0},
+	{AFCVTZSD, C_FREG, C_NONE, C_NONE, C_ZREG, 29, 4, 0, 0, 0},
+	{ASCVTFD, C_ZREG, C_NONE, C_NONE, C_FREG, 29, 4, 0, 0, 0},
 	{AFCVTSD, C_FREG, C_NONE, C_NONE, C_FREG, 29, 4, 0, 0, 0},
-	{AVMOV, C_ELEM, C_NONE, C_NONE, C_REG, 73, 4, 0, 0, 0},
+	{AVMOV, C_ELEM, C_NONE, C_NONE, C_ZREG, 73, 4, 0, 0, 0},
 	{AVMOV, C_ELEM, C_NONE, C_NONE, C_ELEM, 92, 4, 0, 0, 0},
 	{AVMOV, C_ELEM, C_NONE, C_NONE, C_VREG, 80, 4, 0, 0, 0},
-	{AVMOV, C_REG, C_NONE, C_NONE, C_ARNG, 82, 4, 0, 0, 0},
-	{AVMOV, C_REG, C_NONE, C_NONE, C_ELEM, 78, 4, 0, 0, 0},
+	{AVMOV, C_ZREG, C_NONE, C_NONE, C_ARNG, 82, 4, 0, 0, 0},
+	{AVMOV, C_ZREG, C_NONE, C_NONE, C_ELEM, 78, 4, 0, 0, 0},
 	{AVMOV, C_ARNG, C_NONE, C_NONE, C_ARNG, 83, 4, 0, 0, 0},
 	{AVDUP, C_ELEM, C_NONE, C_NONE, C_ARNG, 79, 4, 0, 0, 0},
 	{AVDUP, C_ELEM, C_NONE, C_NONE, C_VREG, 80, 4, 0, 0, 0},
-	{AVDUP, C_REG, C_NONE, C_NONE, C_ARNG, 82, 4, 0, 0, 0},
+	{AVDUP, C_ZREG, C_NONE, C_NONE, C_ARNG, 82, 4, 0, 0, 0},
 	{AVMOVI, C_ADDCON, C_NONE, C_NONE, C_ARNG, 86, 4, 0, 0, 0},
 	{AVFMLA, C_ARNG, C_ARNG, C_NONE, C_ARNG, 72, 4, 0, 0, 0},
 	{AVEXT, C_VCON, C_ARNG, C_ARNG, C_ARNG, 94, 4, 0, 0, 0},
@@ -513,25 +513,23 @@
 	{AVUADDW, C_ARNG, C_ARNG, C_NONE, C_ARNG, 105, 4, 0, 0, 0},
 
 	/* conditional operations */
-	{ACSEL, C_COND, C_REG, C_REG, C_REG, 18, 4, 0, 0, 0},
-	{ACINC, C_COND, C_REG, C_NONE, C_REG, 18, 4, 0, 0, 0},
-	{ACSET, C_COND, C_NONE, C_NONE, C_REG, 18, 4, 0, 0, 0},
+	{ACSEL, C_COND, C_ZREG, C_ZREG, C_ZREG, 18, 4, 0, 0, 0},
+	{ACINC, C_COND, C_ZREG, C_NONE, C_ZREG, 18, 4, 0, 0, 0},
+	{ACSET, C_COND, C_NONE, C_NONE, C_ZREG, 18, 4, 0, 0, 0},
 	{AFCSELD, C_COND, C_FREG, C_FREG, C_FREG, 18, 4, 0, 0, 0},
-	{ACCMN, C_COND, C_REG, C_REG, C_VCON, 19, 4, 0, 0, 0},
-	{ACCMN, C_COND, C_REG, C_VCON, C_VCON, 19, 4, 0, 0, 0},
+	{ACCMN, C_COND, C_ZREG, C_ZREG, C_VCON, 19, 4, 0, 0, 0},
+	{ACCMN, C_COND, C_ZREG, C_VCON, C_VCON, 19, 4, 0, 0, 0},
 	{AFCCMPS, C_COND, C_FREG, C_FREG, C_VCON, 57, 4, 0, 0, 0},
 
 	/* scaled 12-bit unsigned displacement store */
-	{AMOVB, C_REG, C_NONE, C_NONE, C_UAUTO4K, 20, 4, REGSP, 0, 0},
-	{AMOVB, C_REG, C_NONE, C_NONE, C_UOREG4K, 20, 4, 0, 0, 0},
-	{AMOVBU, C_REG, C_NONE, C_NONE, C_UAUTO4K, 20, 4, REGSP, 0, 0},
-	{AMOVBU, C_REG, C_NONE, C_NONE, C_UOREG4K, 20, 4, 0, 0, 0},
-	{AMOVH, C_REG, C_NONE, C_NONE, C_UAUTO8K, 20, 4, REGSP, 0, 0},
-	{AMOVH, C_REG, C_NONE, C_NONE, C_UOREG8K, 20, 4, 0, 0, 0},
-	{AMOVW, C_REG, C_NONE, C_NONE, C_UAUTO16K, 20, 4, REGSP, 0, 0},
-	{AMOVW, C_REG, C_NONE, C_NONE, C_UOREG16K, 20, 4, 0, 0, 0},
-	{AMOVD, C_REG, C_NONE, C_NONE, C_UAUTO32K, 20, 4, REGSP, 0, 0},
-	{AMOVD, C_REG, C_NONE, C_NONE, C_UOREG32K, 20, 4, 0, 0, 0},
+	{AMOVB, C_ZREG, C_NONE, C_NONE, C_UAUTO4K, 20, 4, REGSP, 0, 0},
+	{AMOVB, C_ZREG, C_NONE, C_NONE, C_UOREG4K, 20, 4, 0, 0, 0},
+	{AMOVH, C_ZREG, C_NONE, C_NONE, C_UAUTO8K, 20, 4, REGSP, 0, 0},
+	{AMOVH, C_ZREG, C_NONE, C_NONE, C_UOREG8K, 20, 4, 0, 0, 0},
+	{AMOVW, C_ZREG, C_NONE, C_NONE, C_UAUTO16K, 20, 4, REGSP, 0, 0},
+	{AMOVW, C_ZREG, C_NONE, C_NONE, C_UOREG16K, 20, 4, 0, 0, 0},
+	{AMOVD, C_ZREG, C_NONE, C_NONE, C_UAUTO32K, 20, 4, REGSP, 0, 0},
+	{AMOVD, C_ZREG, C_NONE, C_NONE, C_UOREG32K, 20, 4, 0, 0, 0},
 
 	{AFMOVS, C_FREG, C_NONE, C_NONE, C_UAUTO16K, 20, 4, REGSP, 0, 0},
 	{AFMOVS, C_FREG, C_NONE, C_NONE, C_UOREG16K, 20, 4, 0, 0, 0},
@@ -541,16 +539,14 @@
 	{AFMOVQ, C_FREG, C_NONE, C_NONE, C_UOREG64K, 20, 4, 0, 0, 0},
 
 	/* unscaled 9-bit signed displacement store */
-	{AMOVB, C_REG, C_NONE, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0},
-	{AMOVB, C_REG, C_NONE, C_NONE, C_NSOREG, 20, 4, 0, 0, 0},
-	{AMOVBU, C_REG, C_NONE, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0},
-	{AMOVBU, C_REG, C_NONE, C_NONE, C_NSOREG, 20, 4, 0, 0, 0},
-	{AMOVH, C_REG, C_NONE, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0},
-	{AMOVH, C_REG, C_NONE, C_NONE, C_NSOREG, 20, 4, 0, 0, 0},
-	{AMOVW, C_REG, C_NONE, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0},
-	{AMOVW, C_REG, C_NONE, C_NONE, C_NSOREG, 20, 4, 0, 0, 0},
-	{AMOVD, C_REG, C_NONE, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0},
-	{AMOVD, C_REG, C_NONE, C_NONE, C_NSOREG, 20, 4, 0, 0, 0},
+	{AMOVB, C_ZREG, C_NONE, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0},
+	{AMOVB, C_ZREG, C_NONE, C_NONE, C_NSOREG, 20, 4, 0, 0, 0},
+	{AMOVH, C_ZREG, C_NONE, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0},
+	{AMOVH, C_ZREG, C_NONE, C_NONE, C_NSOREG, 20, 4, 0, 0, 0},
+	{AMOVW, C_ZREG, C_NONE, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0},
+	{AMOVW, C_ZREG, C_NONE, C_NONE, C_NSOREG, 20, 4, 0, 0, 0},
+	{AMOVD, C_ZREG, C_NONE, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0},
+	{AMOVD, C_ZREG, C_NONE, C_NONE, C_NSOREG, 20, 4, 0, 0, 0},
 
 	{AFMOVS, C_FREG, C_NONE, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0},
 	{AFMOVS, C_FREG, C_NONE, C_NONE, C_NSOREG, 20, 4, 0, 0, 0},
@@ -560,16 +556,14 @@
 	{AFMOVQ, C_FREG, C_NONE, C_NONE, C_NSOREG, 20, 4, 0, 0, 0},
 
 	/* scaled 12-bit unsigned displacement load */
-	{AMOVB, C_UAUTO4K, C_NONE, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
-	{AMOVB, C_UOREG4K, C_NONE, C_NONE, C_REG, 21, 4, 0, 0, 0},
-	{AMOVBU, C_UAUTO4K, C_NONE, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
-	{AMOVBU, C_UOREG4K, C_NONE, C_NONE, C_REG, 21, 4, 0, 0, 0},
-	{AMOVH, C_UAUTO8K, C_NONE, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
-	{AMOVH, C_UOREG8K, C_NONE, C_NONE, C_REG, 21, 4, 0, 0, 0},
-	{AMOVW, C_UAUTO16K, C_NONE, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
-	{AMOVW, C_UOREG16K, C_NONE, C_NONE, C_REG, 21, 4, 0, 0, 0},
-	{AMOVD, C_UAUTO32K, C_NONE, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
-	{AMOVD, C_UOREG32K, C_NONE, C_NONE, C_REG, 21, 4, 0, 0, 0},
+	{AMOVB, C_UAUTO4K, C_NONE, C_NONE, C_ZREG, 21, 4, REGSP, 0, 0},
+	{AMOVB, C_UOREG4K, C_NONE, C_NONE, C_ZREG, 21, 4, 0, 0, 0},
+	{AMOVH, C_UAUTO8K, C_NONE, C_NONE, C_ZREG, 21, 4, REGSP, 0, 0},
+	{AMOVH, C_UOREG8K, C_NONE, C_NONE, C_ZREG, 21, 4, 0, 0, 0},
+	{AMOVW, C_UAUTO16K, C_NONE, C_NONE, C_ZREG, 21, 4, REGSP, 0, 0},
+	{AMOVW, C_UOREG16K, C_NONE, C_NONE, C_ZREG, 21, 4, 0, 0, 0},
+	{AMOVD, C_UAUTO32K, C_NONE, C_NONE, C_ZREG, 21, 4, REGSP, 0, 0},
+	{AMOVD, C_UOREG32K, C_NONE, C_NONE, C_ZREG, 21, 4, 0, 0, 0},
 
 	{AFMOVS, C_UAUTO16K, C_NONE, C_NONE, C_FREG, 21, 4, REGSP, 0, 0},
 	{AFMOVS, C_UOREG16K, C_NONE, C_NONE, C_FREG, 21, 4, 0, 0, 0},
@@ -579,16 +573,14 @@
 	{AFMOVQ, C_UOREG64K, C_NONE, C_NONE, C_FREG, 21, 4, 0, 0, 0},
 
 	/* unscaled 9-bit signed displacement load */
-	{AMOVB, C_NSAUTO, C_NONE, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
-	{AMOVB, C_NSOREG, C_NONE, C_NONE, C_REG, 21, 4, 0, 0, 0},
-	{AMOVBU, C_NSAUTO, C_NONE, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
-	{AMOVBU, C_NSOREG, C_NONE, C_NONE, C_REG, 21, 4, 0, 0, 0},
-	{AMOVH, C_NSAUTO, C_NONE, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
-	{AMOVH, C_NSOREG, C_NONE, C_NONE, C_REG, 21, 4, 0, 0, 0},
-	{AMOVW, C_NSAUTO, C_NONE, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
-	{AMOVW, C_NSOREG, C_NONE, C_NONE, C_REG, 21, 4, 0, 0, 0},
-	{AMOVD, C_NSAUTO, C_NONE, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
-	{AMOVD, C_NSOREG, C_NONE, C_NONE, C_REG, 21, 4, 0, 0, 0},
+	{AMOVB, C_NSAUTO, C_NONE, C_NONE, C_ZREG, 21, 4, REGSP, 0, 0},
+	{AMOVB, C_NSOREG, C_NONE, C_NONE, C_ZREG, 21, 4, 0, 0, 0},
+	{AMOVH, C_NSAUTO, C_NONE, C_NONE, C_ZREG, 21, 4, REGSP, 0, 0},
+	{AMOVH, C_NSOREG, C_NONE, C_NONE, C_ZREG, 21, 4, 0, 0, 0},
+	{AMOVW, C_NSAUTO, C_NONE, C_NONE, C_ZREG, 21, 4, REGSP, 0, 0},
+	{AMOVW, C_NSOREG, C_NONE, C_NONE, C_ZREG, 21, 4, 0, 0, 0},
+	{AMOVD, C_NSAUTO, C_NONE, C_NONE, C_ZREG, 21, 4, REGSP, 0, 0},
+	{AMOVD, C_NSOREG, C_NONE, C_NONE, C_ZREG, 21, 4, 0, 0, 0},
 
 	{AFMOVS, C_NSAUTO, C_NONE, C_NONE, C_FREG, 21, 4, REGSP, 0, 0},
 	{AFMOVS, C_NSOREG, C_NONE, C_NONE, C_FREG, 21, 4, 0, 0, 0},
@@ -598,16 +590,14 @@
 	{AFMOVQ, C_NSOREG, C_NONE, C_NONE, C_FREG, 21, 4, 0, 0, 0},
 
 	/* long displacement store */
-	{AMOVB, C_REG, C_NONE, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0},
-	{AMOVB, C_REG, C_NONE, C_NONE, C_LOREG, 30, 8, 0, LTO, 0},
-	{AMOVBU, C_REG, C_NONE, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0},
-	{AMOVBU, C_REG, C_NONE, C_NONE, C_LOREG, 30, 8, 0, LTO, 0},
-	{AMOVH, C_REG, C_NONE, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0},
-	{AMOVH, C_REG, C_NONE, C_NONE, C_LOREG, 30, 8, 0, LTO, 0},
-	{AMOVW, C_REG, C_NONE, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0},
-	{AMOVW, C_REG, C_NONE, C_NONE, C_LOREG, 30, 8, 0, LTO, 0},
-	{AMOVD, C_REG, C_NONE, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0},
-	{AMOVD, C_REG, C_NONE, C_NONE, C_LOREG, 30, 8, 0, LTO, 0},
+	{AMOVB, C_ZREG, C_NONE, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0},
+	{AMOVB, C_ZREG, C_NONE, C_NONE, C_LOREG, 30, 8, 0, LTO, 0},
+	{AMOVH, C_ZREG, C_NONE, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0},
+	{AMOVH, C_ZREG, C_NONE, C_NONE, C_LOREG, 30, 8, 0, LTO, 0},
+	{AMOVW, C_ZREG, C_NONE, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0},
+	{AMOVW, C_ZREG, C_NONE, C_NONE, C_LOREG, 30, 8, 0, LTO, 0},
+	{AMOVD, C_ZREG, C_NONE, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0},
+	{AMOVD, C_ZREG, C_NONE, C_NONE, C_LOREG, 30, 8, 0, LTO, 0},
 
 	{AFMOVS, C_FREG, C_NONE, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0},
 	{AFMOVS, C_FREG, C_NONE, C_NONE, C_LOREG, 30, 8, 0, LTO, 0},
@@ -617,16 +607,14 @@
 	{AFMOVQ, C_FREG, C_NONE, C_NONE, C_LOREG, 30, 8, 0, LTO, 0},
 
 	/* long displacement load */
-	{AMOVB, C_LAUTO, C_NONE, C_NONE, C_REG, 31, 8, REGSP, LFROM, 0},
-	{AMOVB, C_LOREG, C_NONE, C_NONE, C_REG, 31, 8, 0, LFROM, 0},
-	{AMOVBU, C_LAUTO, C_NONE, C_NONE, C_REG, 31, 8, REGSP, LFROM, 0},
-	{AMOVBU, C_LOREG, C_NONE, C_NONE, C_REG, 31, 8, 0, LFROM, 0},
-	{AMOVH, C_LAUTO, C_NONE, C_NONE, C_REG, 31, 8, REGSP, LFROM, 0},
-	{AMOVH, C_LOREG, C_NONE, C_NONE, C_REG, 31, 8, 0, LFROM, 0},
-	{AMOVW, C_LAUTO, C_NONE, C_NONE, C_REG, 31, 8, REGSP, LFROM, 0},
-	{AMOVW, C_LOREG, C_NONE, C_NONE, C_REG, 31, 8, 0, LFROM, 0},
-	{AMOVD, C_LAUTO, C_NONE, C_NONE, C_REG, 31, 8, REGSP, LFROM, 0},
-	{AMOVD, C_LOREG, C_NONE, C_NONE, C_REG, 31, 8, 0, LFROM, 0},
+	{AMOVB, C_LAUTO, C_NONE, C_NONE, C_ZREG, 31, 8, REGSP, LFROM, 0},
+	{AMOVB, C_LOREG, C_NONE, C_NONE, C_ZREG, 31, 8, 0, LFROM, 0},
+	{AMOVH, C_LAUTO, C_NONE, C_NONE, C_ZREG, 31, 8, REGSP, LFROM, 0},
+	{AMOVH, C_LOREG, C_NONE, C_NONE, C_ZREG, 31, 8, 0, LFROM, 0},
+	{AMOVW, C_LAUTO, C_NONE, C_NONE, C_ZREG, 31, 8, REGSP, LFROM, 0},
+	{AMOVW, C_LOREG, C_NONE, C_NONE, C_ZREG, 31, 8, 0, LFROM, 0},
+	{AMOVD, C_LAUTO, C_NONE, C_NONE, C_ZREG, 31, 8, REGSP, LFROM, 0},
+	{AMOVD, C_LOREG, C_NONE, C_NONE, C_ZREG, 31, 8, 0, LFROM, 0},
 
 	{AFMOVS, C_LAUTO, C_NONE, C_NONE, C_FREG, 31, 8, REGSP, LFROM, 0},
 	{AFMOVS, C_LOREG, C_NONE, C_NONE, C_FREG, 31, 8, 0, LFROM, 0},
@@ -636,57 +624,52 @@
 	{AFMOVQ, C_LOREG, C_NONE, C_NONE, C_FREG, 31, 8, 0, LFROM, 0},
 
 	/* pre/post-indexed load (unscaled, signed 9-bit offset) */
-	{AMOVD, C_LOREG, C_NONE, C_NONE, C_REG, 22, 4, 0, 0, C_XPOST},
-	{AMOVW, C_LOREG, C_NONE, C_NONE, C_REG, 22, 4, 0, 0, C_XPOST},
-	{AMOVH, C_LOREG, C_NONE, C_NONE, C_REG, 22, 4, 0, 0, C_XPOST},
-	{AMOVB, C_LOREG, C_NONE, C_NONE, C_REG, 22, 4, 0, 0, C_XPOST},
-	{AMOVBU, C_LOREG, C_NONE, C_NONE, C_REG, 22, 4, 0, 0, C_XPOST},
+	{AMOVD, C_LOREG, C_NONE, C_NONE, C_ZREG, 22, 4, 0, 0, C_XPOST},
+	{AMOVW, C_LOREG, C_NONE, C_NONE, C_ZREG, 22, 4, 0, 0, C_XPOST},
+	{AMOVH, C_LOREG, C_NONE, C_NONE, C_ZREG, 22, 4, 0, 0, C_XPOST},
+	{AMOVB, C_LOREG, C_NONE, C_NONE, C_ZREG, 22, 4, 0, 0, C_XPOST},
 	{AFMOVS, C_LOREG, C_NONE, C_NONE, C_FREG, 22, 4, 0, 0, C_XPOST},
 	{AFMOVD, C_LOREG, C_NONE, C_NONE, C_FREG, 22, 4, 0, 0, C_XPOST},
 	{AFMOVQ, C_LOREG, C_NONE, C_NONE, C_FREG, 22, 4, 0, 0, C_XPOST},
 
-	{AMOVD, C_LOREG, C_NONE, C_NONE, C_REG, 22, 4, 0, 0, C_XPRE},
-	{AMOVW, C_LOREG, C_NONE, C_NONE, C_REG, 22, 4, 0, 0, C_XPRE},
-	{AMOVH, C_LOREG, C_NONE, C_NONE, C_REG, 22, 4, 0, 0, C_XPRE},
-	{AMOVB, C_LOREG, C_NONE, C_NONE, C_REG, 22, 4, 0, 0, C_XPRE},
-	{AMOVBU, C_LOREG, C_NONE, C_NONE, C_REG, 22, 4, 0, 0, C_XPRE},
+	{AMOVD, C_LOREG, C_NONE, C_NONE, C_ZREG, 22, 4, 0, 0, C_XPRE},
+	{AMOVW, C_LOREG, C_NONE, C_NONE, C_ZREG, 22, 4, 0, 0, C_XPRE},
+	{AMOVH, C_LOREG, C_NONE, C_NONE, C_ZREG, 22, 4, 0, 0, C_XPRE},
+	{AMOVB, C_LOREG, C_NONE, C_NONE, C_ZREG, 22, 4, 0, 0, C_XPRE},
 	{AFMOVS, C_LOREG, C_NONE, C_NONE, C_FREG, 22, 4, 0, 0, C_XPRE},
 	{AFMOVD, C_LOREG, C_NONE, C_NONE, C_FREG, 22, 4, 0, 0, C_XPRE},
 	{AFMOVQ, C_LOREG, C_NONE, C_NONE, C_FREG, 22, 4, 0, 0, C_XPRE},
 
 	/* pre/post-indexed store (unscaled, signed 9-bit offset) */
-	{AMOVD, C_REG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST},
-	{AMOVW, C_REG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST},
-	{AMOVH, C_REG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST},
-	{AMOVB, C_REG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST},
-	{AMOVBU, C_REG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST},
+	{AMOVD, C_ZREG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST},
+	{AMOVW, C_ZREG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST},
+	{AMOVH, C_ZREG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST},
+	{AMOVB, C_ZREG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST},
 	{AFMOVS, C_FREG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST},
 	{AFMOVD, C_FREG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST},
 	{AFMOVQ, C_FREG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST},
 
-	{AMOVD, C_REG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE},
-	{AMOVW, C_REG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE},
-	{AMOVH, C_REG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE},
-	{AMOVB, C_REG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE},
-	{AMOVBU, C_REG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE},
+	{AMOVD, C_ZREG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE},
+	{AMOVW, C_ZREG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE},
+	{AMOVH, C_ZREG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE},
+	{AMOVB, C_ZREG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE},
 	{AFMOVS, C_FREG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE},
 	{AFMOVD, C_FREG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE},
 	{AFMOVQ, C_FREG, C_NONE, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE},
 
 	/* load with shifted or extended register offset */
-	{AMOVD, C_ROFF, C_NONE, C_NONE, C_REG, 98, 4, 0, 0, 0},
-	{AMOVW, C_ROFF, C_NONE, C_NONE, C_REG, 98, 4, 0, 0, 0},
-	{AMOVH, C_ROFF, C_NONE, C_NONE, C_REG, 98, 4, 0, 0, 0},
-	{AMOVB, C_ROFF, C_NONE, C_NONE, C_REG, 98, 4, 0, 0, 0},
-	{AMOVBU, C_ROFF, C_NONE, C_NONE, C_REG, 98, 4, 0, 0, 0},
+	{AMOVD, C_ROFF, C_NONE, C_NONE, C_ZREG, 98, 4, 0, 0, 0},
+	{AMOVW, C_ROFF, C_NONE, C_NONE, C_ZREG, 98, 4, 0, 0, 0},
+	{AMOVH, C_ROFF, C_NONE, C_NONE, C_ZREG, 98, 4, 0, 0, 0},
+	{AMOVB, C_ROFF, C_NONE, C_NONE, C_ZREG, 98, 4, 0, 0, 0},
 	{AFMOVS, C_ROFF, C_NONE, C_NONE, C_FREG, 98, 4, 0, 0, 0},
 	{AFMOVD, C_ROFF, C_NONE, C_NONE, C_FREG, 98, 4, 0, 0, 0},
 
 	/* store with extended register offset */
-	{AMOVD, C_REG, C_NONE, C_NONE, C_ROFF, 99, 4, 0, 0, 0},
-	{AMOVW, C_REG, C_NONE, C_NONE, C_ROFF, 99, 4, 0, 0, 0},
-	{AMOVH, C_REG, C_NONE, C_NONE, C_ROFF, 99, 4, 0, 0, 0},
-	{AMOVB, C_REG, C_NONE, C_NONE, C_ROFF, 99, 4, 0, 0, 0},
+	{AMOVD, C_ZREG, C_NONE, C_NONE, C_ROFF, 99, 4, 0, 0, 0},
+	{AMOVW, C_ZREG, C_NONE, C_NONE, C_ROFF, 99, 4, 0, 0, 0},
+	{AMOVH, C_ZREG, C_NONE, C_NONE, C_ROFF, 99, 4, 0, 0, 0},
+	{AMOVB, C_ZREG, C_NONE, C_NONE, C_ROFF, 99, 4, 0, 0, 0},
 	{AFMOVS, C_FREG, C_NONE, C_NONE, C_ROFF, 99, 4, 0, 0, 0},
 	{AFMOVD, C_FREG, C_NONE, C_NONE, C_ROFF, 99, 4, 0, 0, 0},
 
@@ -792,17 +775,17 @@
 	{ASTPW, C_PAIR, C_NONE, C_NONE, C_LOREG, 77, 12, 0, LTO, 0},
 	{ASTPW, C_PAIR, C_NONE, C_NONE, C_ADDR, 87, 12, 0, 0, 0},
 
-	{ASWPD, C_REG, C_NONE, C_NONE, C_ZOREG, 47, 4, 0, 0, 0},        // RegTo2=C_REG
-	{ASWPD, C_REG, C_NONE, C_NONE, C_ZAUTO, 47, 4, REGSP, 0, 0},    // RegTo2=C_REG
+	{ASWPD, C_ZREG, C_NONE, C_NONE, C_ZOREG, 47, 4, 0, 0, 0},       // RegTo2=C_REG
+	{ASWPD, C_ZREG, C_NONE, C_NONE, C_ZAUTO, 47, 4, REGSP, 0, 0},   // RegTo2=C_REG
 	{ACASPD, C_PAIR, C_NONE, C_NONE, C_ZOREG, 106, 4, 0, 0, 0},     // RegTo2=C_REGREG
 	{ACASPD, C_PAIR, C_NONE, C_NONE, C_ZAUTO, 106, 4, REGSP, 0, 0}, // RegTo2=C_REGREG
-	{ALDAR, C_ZOREG, C_NONE, C_NONE, C_REG, 58, 4, 0, 0, 0},
-	{ALDXR, C_ZOREG, C_NONE, C_NONE, C_REG, 58, 4, 0, 0, 0},
-	{ALDAXR, C_ZOREG, C_NONE, C_NONE, C_REG, 58, 4, 0, 0, 0},
+	{ALDAR, C_ZOREG, C_NONE, C_NONE, C_ZREG, 58, 4, 0, 0, 0},
+	{ALDXR, C_ZOREG, C_NONE, C_NONE, C_ZREG, 58, 4, 0, 0, 0},
+	{ALDAXR, C_ZOREG, C_NONE, C_NONE, C_ZREG, 58, 4, 0, 0, 0},
 	{ALDXP, C_ZOREG, C_NONE, C_NONE, C_PAIR, 58, 4, 0, 0, 0},
-	{ASTLR, C_REG, C_NONE, C_NONE, C_ZOREG, 59, 4, 0, 0, 0},  // RegTo2=C_NONE
-	{ASTXR, C_REG, C_NONE, C_NONE, C_ZOREG, 59, 4, 0, 0, 0},  // RegTo2=C_REG
-	{ASTLXR, C_REG, C_NONE, C_NONE, C_ZOREG, 59, 4, 0, 0, 0}, // RegTo2=C_REG
+	{ASTLR, C_ZREG, C_NONE, C_NONE, C_ZOREG, 59, 4, 0, 0, 0},  // RegTo2=C_NONE
+	{ASTXR, C_ZREG, C_NONE, C_NONE, C_ZOREG, 59, 4, 0, 0, 0},  // RegTo2=C_REG
+	{ASTLXR, C_ZREG, C_NONE, C_NONE, C_ZOREG, 59, 4, 0, 0, 0}, // RegTo2=C_REG
 	{ASTXP, C_PAIR, C_NONE, C_NONE, C_ZOREG, 59, 4, 0, 0, 0},
 
 	/* VLD[1-4]/VST[1-4] */
@@ -832,10 +815,10 @@
 	{AVST1, C_ELEM, C_NONE, C_NONE, C_LOREG, 96, 4, 0, 0, 0},
 
 	/* special */
-	{AMOVD, C_SPR, C_NONE, C_NONE, C_REG, 35, 4, 0, 0, 0},
-	{AMRS, C_SPR, C_NONE, C_NONE, C_REG, 35, 4, 0, 0, 0},
-	{AMOVD, C_REG, C_NONE, C_NONE, C_SPR, 36, 4, 0, 0, 0},
-	{AMSR, C_REG, C_NONE, C_NONE, C_SPR, 36, 4, 0, 0, 0},
+	{AMOVD, C_SPR, C_NONE, C_NONE, C_ZREG, 35, 4, 0, 0, 0},
+	{AMRS, C_SPR, C_NONE, C_NONE, C_ZREG, 35, 4, 0, 0, 0},
+	{AMOVD, C_ZREG, C_NONE, C_NONE, C_SPR, 36, 4, 0, 0, 0},
+	{AMSR, C_ZREG, C_NONE, C_NONE, C_SPR, 36, 4, 0, 0, 0},
 	{AMOVD, C_VCON, C_NONE, C_NONE, C_SPR, 37, 4, 0, 0, 0},
 	{AMSR, C_VCON, C_NONE, C_NONE, C_SPR, 37, 4, 0, 0, 0},
 	{AMSR, C_VCON, C_NONE, C_NONE, C_SPOP, 37, 4, 0, 0, 0},
@@ -844,15 +827,15 @@
 	{ADMB, C_VCON, C_NONE, C_NONE, C_NONE, 51, 4, 0, 0, 0},
 	{AHINT, C_VCON, C_NONE, C_NONE, C_NONE, 52, 4, 0, 0, 0},
 	{ASYS, C_VCON, C_NONE, C_NONE, C_NONE, 50, 4, 0, 0, 0},
-	{ASYS, C_VCON, C_NONE, C_NONE, C_REG, 50, 4, 0, 0, 0},
-	{ASYSL, C_VCON, C_NONE, C_NONE, C_REG, 50, 4, 0, 0, 0},
+	{ASYS, C_VCON, C_NONE, C_NONE, C_ZREG, 50, 4, 0, 0, 0},
+	{ASYSL, C_VCON, C_NONE, C_NONE, C_ZREG, 50, 4, 0, 0, 0},
 	{ATLBI, C_SPOP, C_NONE, C_NONE, C_NONE, 107, 4, 0, 0, 0},
-	{ATLBI, C_SPOP, C_NONE, C_NONE, C_REG, 107, 4, 0, 0, 0},
+	{ATLBI, C_SPOP, C_NONE, C_NONE, C_ZREG, 107, 4, 0, 0, 0},
 
 	/* encryption instructions */
 	{AAESD, C_VREG, C_NONE, C_NONE, C_VREG, 29, 4, 0, 0, 0}, // for compatibility with old code
 	{AAESD, C_ARNG, C_NONE, C_NONE, C_ARNG, 29, 4, 0, 0, 0}, // recommend using the new one for better readability
-	{ASHA1C, C_VREG, C_REG, C_NONE, C_VREG, 1, 4, 0, 0, 0},
+	{ASHA1C, C_VREG, C_ZREG, C_NONE, C_VREG, 1, 4, 0, 0, 0},
 	{ASHA1C, C_ARNG, C_VREG, C_NONE, C_VREG, 1, 4, 0, 0, 0},
 	{ASHA1H, C_VREG, C_NONE, C_NONE, C_VREG, 29, 4, 0, 0, 0},
 	{ASHA1SU0, C_ARNG, C_ARNG, C_NONE, C_ARNG, 1, 4, 0, 0, 0},
@@ -867,7 +850,7 @@
 	{obj.AFUNCDATA, C_VCON, C_NONE, C_NONE, C_ADDR, 0, 0, 0, 0, 0},
 	{obj.ANOP, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0, 0},
 	{obj.ANOP, C_LCON, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0, 0}, // nop variants, see #40689
-	{obj.ANOP, C_REG, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0, 0},
+	{obj.ANOP, C_ZREG, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0, 0},
 	{obj.ANOP, C_VREG, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0, 0},
 	{obj.ADUFFZERO, C_NONE, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0}, // same as AB/ABL
 	{obj.ADUFFCOPY, C_NONE, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0}, // same as AB/ABL
@@ -1040,6 +1023,27 @@
 	return int(-pc & (alignedValue - 1))
 }
 
+// size returns the size of the sequence of machine instructions when p is encoded with o.
+// Usually it just returns o.size directly, in some cases it checks whether the optimization
+// conditions are met, and if so returns the size of the optimized instruction sequence.
+// These optimizations need to be synchronized with the asmout function.
+func (o *Optab) size(ctxt *obj.Link, p *obj.Prog) int {
+	// Optimize adrp+add+ld/st to adrp+ld/st(offset).
+	sz := movesize(p.As)
+	if sz != -1 {
+		// Relocations R_AARCH64_LDST{64,32,16,8}_ABS_LO12_NC can only generate 8-byte, 4-byte,
+		// 2-byte and 1-byte aligned addresses, so the address of load/store must be aligned.
+		// Also symbols with prefix of "go:string." are Go strings, which will go into
+		// the symbol table, their addresses are not necessary aligned, rule this out.
+		align := int64(1 << sz)
+		if o.a1 == C_ADDR && p.From.Offset%align == 0 && !strings.HasPrefix(p.From.Sym.Name, "go:string.") ||
+			o.a4 == C_ADDR && p.To.Offset%align == 0 && !strings.HasPrefix(p.To.Sym.Name, "go:string.") {
+			return 8
+		}
+	}
+	return int(o.size_)
+}
+
 func span7(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
 	if ctxt.Retpoline {
 		ctxt.Diag("-spectre=ret not supported on arm64")
@@ -1064,12 +1068,9 @@
 	var m int
 	var o *Optab
 	for p = p.Link; p != nil; p = p.Link {
-		if p.As == ADWORD && (pc&7) != 0 {
-			pc += 4
-		}
 		p.Pc = pc
 		o = c.oplook(p)
-		m = int(o.size)
+		m = o.size(c.ctxt, p)
 		if m == 0 {
 			switch p.As {
 			case obj.APCALIGN:
@@ -1086,6 +1087,8 @@
 				c.ctxt.Diag("zero-width instruction\n%v", p)
 			}
 		}
+		pc += int64(m)
+
 		if o.flag&LFROM != 0 {
 			c.addpool(p, &p.From)
 		}
@@ -1095,13 +1098,8 @@
 		if o.flag&LTO != 0 {
 			c.addpool(p, &p.To)
 		}
-
-		if p.As == AB || p.As == obj.ARET || p.As == AERET { /* TODO: other unconditional operations */
-			c.checkpool(p, 0)
-		}
-		pc += int64(m)
 		if c.blitrl != nil {
-			c.checkpool(p, 1)
+			c.checkpool(p)
 		}
 	}
 
@@ -1117,21 +1115,17 @@
 		bflag = 0
 		pc = 0
 		for p = c.cursym.Func().Text.Link; p != nil; p = p.Link {
-			if p.As == ADWORD && (pc&7) != 0 {
-				pc += 4
-			}
 			p.Pc = pc
 			o = c.oplook(p)
 
 			/* very large branches */
-			if (o.type_ == 7 || o.type_ == 39 || o.type_ == 40) && p.To.Target() != nil { // 7: BEQ and like, 39: CBZ and like, 40: TBZ and like
+			if (o.flag&BRANCH14BITS != 0 || o.flag&BRANCH19BITS != 0) && p.To.Target() != nil {
 				otxt := p.To.Target().Pc - pc
 				var toofar bool
-				switch o.type_ {
-				case 7, 39: // branch instruction encodes 19 bits
-					toofar = otxt <= -(1<<20)+10 || otxt >= (1<<20)-10
-				case 40: // branch instruction encodes 14 bits
+				if o.flag&BRANCH14BITS != 0 { // branch instruction encodes 14 bits
 					toofar = otxt <= -(1<<15)+10 || otxt >= (1<<15)-10
+				} else if o.flag&BRANCH19BITS != 0 { // branch instruction encodes 19 bits
+					toofar = otxt <= -(1<<20)+10 || otxt >= (1<<20)-10
 				}
 				if toofar {
 					q := c.newprog()
@@ -1150,7 +1144,7 @@
 					bflag = 1
 				}
 			}
-			m = int(o.size)
+			m = o.size(c.ctxt, p)
 
 			if m == 0 {
 				switch p.As {
@@ -1183,20 +1177,9 @@
 	for p := c.cursym.Func().Text.Link; p != nil; p = p.Link {
 		c.pc = p.Pc
 		o = c.oplook(p)
-
-		// need to align DWORDs on 8-byte boundary. The ISA doesn't
-		// require it, but the various 64-bit loads we generate assume it.
-		if o.as == ADWORD && psz%8 != 0 {
-			bp[3] = 0
-			bp[2] = bp[3]
-			bp[1] = bp[2]
-			bp[0] = bp[1]
-			bp = bp[4:]
-			psz += 4
-		}
-
-		if int(o.size) > 4*len(out) {
-			log.Fatalf("out array in span7 is too small, need at least %d for %v", o.size/4, p)
+		sz := o.size(c.ctxt, p)
+		if sz > 4*len(out) {
+			log.Fatalf("out array in span7 is too small, need at least %d for %v", sz/4, p)
 		}
 		if p.As == obj.APCALIGN {
 			alignedValue := p.From.Offset
@@ -1209,7 +1192,7 @@
 			}
 		} else {
 			c.asmout(p, o, out[:])
-			for i = 0; i < int(o.size/4); i++ {
+			for i = 0; i < sz/4; i++ {
 				c.ctxt.Arch.ByteOrder.PutUint32(bp, out[i])
 				bp = bp[4:]
 				psz += 4
@@ -1238,7 +1221,9 @@
 func (c *ctxt7) isUnsafePoint(p *obj.Prog) bool {
 	// If p explicitly uses REGTMP, it's unsafe to preempt, because the
 	// preemption sequence clobbers REGTMP.
-	return p.From.Reg == REGTMP || p.To.Reg == REGTMP || p.Reg == REGTMP
+	return p.From.Reg == REGTMP || p.To.Reg == REGTMP || p.Reg == REGTMP ||
+		p.From.Type == obj.TYPE_REGREG && p.From.Offset == REGTMP ||
+		p.To.Type == obj.TYPE_REGREG && p.To.Offset == REGTMP
 }
 
 // isRestartable returns whether p is a multi-instruction sequence that,
@@ -1255,54 +1240,60 @@
 	// If p doesn't use REGTMP, it can be simply preempted, so we don't
 	// mark it.
 	o := c.oplook(p)
-	return o.size > 4 && o.flag&NOTUSETMP == 0
+	return o.size(c.ctxt, p) > 4 && o.flag&NOTUSETMP == 0
 }
 
 /*
  * when the first reference to the literal pool threatens
  * to go out of range of a 1Mb PC-relative offset
- * drop the pool now, and branch round it.
+ * drop the pool now.
  */
-func (c *ctxt7) checkpool(p *obj.Prog, skip int) {
-	if c.pool.size >= 0xffff0 || !ispcdisp(int32(p.Pc+4+int64(c.pool.size)-int64(c.pool.start)+8)) {
-		c.flushpool(p, skip)
-	} else if p.Link == nil {
-		c.flushpool(p, 2)
+func (c *ctxt7) checkpool(p *obj.Prog) {
+	// If the pool is going to go out of range or p is the last instruction of the function,
+	// flush the pool.
+	if c.pool.size >= 0xffff0 || !ispcdisp(int32(p.Pc+4+int64(c.pool.size)-int64(c.pool.start)+8)) || p.Link == nil {
+		c.flushpool(p)
 	}
 }
 
-func (c *ctxt7) flushpool(p *obj.Prog, skip int) {
-	if c.blitrl != nil {
-		if skip != 0 {
-			if c.ctxt.Debugvlog && skip == 1 {
-				fmt.Printf("note: flush literal pool at %#x: len=%d ref=%x\n", uint64(p.Pc+4), c.pool.size, c.pool.start)
-			}
-			q := c.newprog()
+func (c *ctxt7) flushpool(p *obj.Prog) {
+	// Needs to insert a branch before flushing the pool.
+	// We don't need the jump if following an unconditional branch.
+	// TODO: other unconditional operations.
+	if !(p.As == AB || p.As == obj.ARET || p.As == AERET) {
+		if c.ctxt.Debugvlog {
+			fmt.Printf("note: flush literal pool at %#x: len=%d ref=%x\n", uint64(p.Pc+4), c.pool.size, c.pool.start)
+		}
+		q := c.newprog()
+		if p.Link == nil {
+			// If p is the last instruction of the function, insert an UNDEF instruction in case the
+			// exection fall through to the pool.
+			q.As = obj.AUNDEF
+		} else {
+			// Else insert a branch to the next instruction of p.
 			q.As = AB
 			q.To.Type = obj.TYPE_BRANCH
 			q.To.SetTarget(p.Link)
-			q.Link = c.blitrl
-			q.Pos = p.Pos
-			c.blitrl = q
-		} else if p.Pc+int64(c.pool.size)-int64(c.pool.start) < maxPCDisp {
-			return
 		}
-
-		// The line number for constant pool entries doesn't really matter.
-		// We set it to the line number of the preceding instruction so that
-		// there are no deltas to encode in the pc-line tables.
-		for q := c.blitrl; q != nil; q = q.Link {
-			q.Pos = p.Pos
-		}
-
-		c.elitrl.Link = p.Link
-		p.Link = c.blitrl
-
-		c.blitrl = nil /* BUG: should refer back to values until out-of-range */
-		c.elitrl = nil
-		c.pool.size = 0
-		c.pool.start = 0
+		q.Link = c.blitrl
+		q.Pos = p.Pos
+		c.blitrl = q
 	}
+
+	// The line number for constant pool entries doesn't really matter.
+	// We set it to the line number of the preceding instruction so that
+	// there are no deltas to encode in the pc-line tables.
+	for q := c.blitrl; q != nil; q = q.Link {
+		q.Pos = p.Pos
+	}
+
+	c.elitrl.Link = p.Link
+	p.Link = c.blitrl
+
+	c.blitrl = nil /* BUG: should refer back to values until out-of-range */
+	c.elitrl = nil
+	c.pool.size = 0
+	c.pool.start = 0
 }
 
 // addpool128 adds a 128-bit constant to literal pool by two consecutive DWORD
@@ -1371,23 +1362,21 @@
 		}
 	}
 
-	q := c.newprog()
-	*q = *t
 	if c.blitrl == nil {
-		c.blitrl = q
+		c.blitrl = t
 		c.pool.start = uint32(p.Pc)
 	} else {
-		c.elitrl.Link = q
+		c.elitrl.Link = t
 	}
-	c.elitrl = q
-	if q.As == ADWORD {
+	c.elitrl = t
+	if t.As == ADWORD {
 		// make DWORD 8-byte aligned, this is not required by ISA,
 		// just to avoid performance penalties when loading from
 		// the constant pool across a cache line.
 		c.pool.size = roundUp(c.pool.size, 8)
 	}
 	c.pool.size += uint32(sz)
-	p.Pool = q
+	p.Pool = t
 }
 
 // roundUp rounds up x to "to".
@@ -1536,7 +1525,7 @@
 	return sequenceOfOnes(x) || sequenceOfOnes(^x)
 }
 
-// sequenceOfOnes tests whether a constant is a sequence of ones in binary, with leading and trailing zeros
+// sequenceOfOnes tests whether a constant is a sequence of ones in binary, with leading and trailing zeros.
 func sequenceOfOnes(x uint64) bool {
 	y := x & -x // lowest set bit of x. x is good iff x+y is a power of 2
 	y += x
@@ -1789,7 +1778,7 @@
 /*
  * if v contains a single 16-bit value aligned
  * on a 16-bit field, and thus suitable for movk/movn,
- * return the field index 0 to 3; otherwise return -1
+ * return the field index 0 to 3; otherwise return -1.
  */
 func movcon(v int64) int {
 	for s := 0; s < 64; s += 16 {
@@ -1805,7 +1794,7 @@
 	case REG_R0 <= r && r <= REG_R30: // not 31
 		return C_REG
 	case r == REGZERO:
-		return C_ZCON
+		return C_ZREG
 	case REG_F0 <= r && r <= REG_F31:
 		return C_FREG
 	case REG_V0 <= r && r <= REG_V31:
@@ -2198,8 +2187,8 @@
 			return true
 		}
 
-	case C_REG:
-		if b == C_ZCON {
+	case C_ZREG:
+		if b == C_REG {
 			return true
 		}
 
@@ -2863,7 +2852,6 @@
 			oprangeset(ACSETMW, t)
 
 		case AMOVD,
-			AMOVBU,
 			AB,
 			ABL,
 			AWORD,
@@ -3154,6 +3142,9 @@
 		case AVUADDW:
 			oprangeset(AVUADDW2, t)
 
+		case AVTBL:
+			oprangeset(AVTBX, t)
+
 		case ASHA1H,
 			AVCNT,
 			AVMOV,
@@ -3162,7 +3153,6 @@
 			AVST2,
 			AVST3,
 			AVST4,
-			AVTBL,
 			AVDUP,
 			AVMOVI,
 			APRFM,
@@ -3225,7 +3215,7 @@
 	return SYSARG5(0, op1, Cn, Cm, op2)
 }
 
-// checkUnpredictable checks if the sourse and transfer registers are the same register.
+// checkUnpredictable checks if the source and transfer registers are the same register.
 // ARM64 manual says it is "constrained unpredictable" if the src and dst registers of STP/LDP are same.
 func (c *ctxt7) checkUnpredictable(p *obj.Prog, isload bool, wback bool, rn int16, rt1 int16, rt2 int16) {
 	if wback && rn != REGSP && (rn == rt1 || rn == rt2) {
@@ -3430,7 +3420,7 @@
 			op = int32(c.opirr(p, AADD))
 		}
 
-		if int(o.size) == 8 {
+		if int(o.size(c.ctxt, p)) == 8 {
 			// NOTE: this case does not use REGTMP. If it ever does,
 			// remove the NOTUSETMP flag in optab.
 			o1 = c.oaddi(p, op, v&0xfff000, r, rt)
@@ -3879,13 +3869,13 @@
 	case 29: /* op Rn, Rd */
 		fc := c.aclass(&p.From)
 		tc := c.aclass(&p.To)
-		if (p.As == AFMOVD || p.As == AFMOVS) && (fc == C_REG || fc == C_ZCON || tc == C_REG || tc == C_ZCON) {
+		if (p.As == AFMOVD || p.As == AFMOVS) && (fc == C_REG || fc == C_ZREG || tc == C_REG) {
 			// FMOV Rx, Fy or FMOV Fy, Rx
 			o1 = FPCVTI(0, 0, 0, 0, 6)
 			if p.As == AFMOVD {
 				o1 |= 1<<31 | 1<<22 // 64-bit
 			}
-			if fc == C_REG || fc == C_ZCON {
+			if fc == C_REG || fc == C_ZREG {
 				o1 |= 1 << 16 // FMOV Rx, Fy
 			}
 		} else {
@@ -4476,31 +4466,43 @@
 		o2 |= uint32(r&31) << 5
 		o2 |= uint32(rt & 31)
 
-		/* reloc ops */
-	case 64: /* movT R,addr -> adrp + add + movT R, (REGTMP) */
+	/* reloc ops */
+	case 64: /* movT R,addr -> adrp + movT R, (REGTMP) */
 		if p.From.Reg == REGTMP {
 			c.ctxt.Diag("cannot use REGTMP as source: %v\n", p)
 		}
 		o1 = ADR(1, 0, REGTMP)
-		o2 = c.opirr(p, AADD) | REGTMP&31<<5 | REGTMP&31
 		rel := obj.Addrel(c.cursym)
 		rel.Off = int32(c.pc)
 		rel.Siz = 8
 		rel.Sym = p.To.Sym
 		rel.Add = p.To.Offset
-		rel.Type = objabi.R_ADDRARM64
-		o3 = c.olsr12u(p, int32(c.opstr(p, p.As)), 0, REGTMP, int(p.From.Reg))
+		// For unaligned access, fall back to adrp + add + movT R, (REGTMP).
+		if o.size(c.ctxt, p) != 8 {
+			o2 = c.opirr(p, AADD) | REGTMP&31<<5 | REGTMP&31
+			o3 = c.olsr12u(p, int32(c.opstr(p, p.As)), 0, REGTMP, int(p.From.Reg))
+			rel.Type = objabi.R_ADDRARM64
+			break
+		}
+		o2 = c.olsr12u(p, int32(c.opstr(p, p.As)), 0, REGTMP, int(p.From.Reg))
+		rel.Type = c.addrRelocType(p)
 
-	case 65: /* movT addr,R -> adrp + add + movT (REGTMP), R */
+	case 65: /* movT addr,R -> adrp + movT (REGTMP), R */
 		o1 = ADR(1, 0, REGTMP)
-		o2 = c.opirr(p, AADD) | REGTMP&31<<5 | REGTMP&31
 		rel := obj.Addrel(c.cursym)
 		rel.Off = int32(c.pc)
 		rel.Siz = 8
 		rel.Sym = p.From.Sym
 		rel.Add = p.From.Offset
-		rel.Type = objabi.R_ADDRARM64
-		o3 = c.olsr12u(p, int32(c.opldr(p, p.As)), 0, REGTMP, int(p.To.Reg))
+		// For unaligned access, fall back to adrp + add + movT (REGTMP), R.
+		if o.size(c.ctxt, p) != 8 {
+			o2 = c.opirr(p, AADD) | REGTMP&31<<5 | REGTMP&31
+			o3 = c.olsr12u(p, int32(c.opldr(p, p.As)), 0, REGTMP, int(p.To.Reg))
+			rel.Type = objabi.R_ADDRARM64
+			break
+		}
+		o2 = c.olsr12u(p, int32(c.opldr(p, p.As)), 0, REGTMP, int(p.To.Reg))
+		rel.Type = c.addrRelocType(p)
 
 	case 66: /* ldp O(R)!, (r1, r2); ldp (R)O!, (r1, r2) */
 		v := int32(c.regoff(&p.From))
@@ -5479,7 +5481,7 @@
 		rf := int(p.From.Reg)
 		o1 |= uint32(rf & 31)
 
-	case 100: /* VTBL Vn.<T>, [Vt1.<T>, Vt2.<T>, ...], Vd.<T> */
+	case 100: /* VTBL/VTBX Vn.<T>, [Vt1.<T>, Vt2.<T>, ...], Vd.<T> */
 		af := int((p.From.Reg >> 5) & 15)
 		at := int((p.To.Reg >> 5) & 15)
 		if af != at {
@@ -5510,7 +5512,14 @@
 		default:
 			c.ctxt.Diag("invalid register numbers in ARM64 register list: %v", p)
 		}
-		o1 = q<<30 | 0xe<<24 | len<<13
+		var op uint32
+		switch p.As {
+		case AVTBL:
+			op = 0
+		case AVTBX:
+			op = 1
+		}
+		o1 = q<<30 | 0xe<<24 | len<<13 | op<<12
 		o1 |= (uint32(rf&31) << 16) | uint32(offset&31)<<5 | uint32(rt&31)
 
 	case 101: // VMOVQ $vcon1, $vcon2, Vd or VMOVD|VMOVS $vcon, Vd -> FMOVQ/FMOVD/FMOVS pool(PC), Vd: load from constant pool.
@@ -5685,6 +5694,22 @@
 	out[4] = o5
 }
 
+func (c *ctxt7) addrRelocType(p *obj.Prog) objabi.RelocType {
+	switch movesize(p.As) {
+	case 0:
+		return objabi.R_ARM64_PCREL_LDST8
+	case 1:
+		return objabi.R_ARM64_PCREL_LDST16
+	case 2:
+		return objabi.R_ARM64_PCREL_LDST32
+	case 3:
+		return objabi.R_ARM64_PCREL_LDST64
+	default:
+		c.ctxt.Diag("use R_ADDRARM64 relocation type for: %v\n", p)
+	}
+	return -1
+}
+
 /*
  * basic Rm op Rn -> Rd (using shifted register with 0)
  * also op Rn -> Rt
@@ -7438,7 +7463,7 @@
 	case ALDP, ALDPW, ALDPSW:
 		c.checkUnpredictable(p, true, wback, p.From.Reg, p.To.Reg, int16(p.To.Offset))
 	case ASTP, ASTPW:
-		if wback == true {
+		if wback {
 			c.checkUnpredictable(p, false, true, p.To.Reg, p.From.Reg, int16(p.From.Offset))
 		}
 	case AFLDPD, AFLDPQ, AFLDPS:
diff --git a/src/cmd/internal/obj/arm64/asm_arm64_test.go b/src/cmd/internal/obj/arm64/asm_arm64_test.go
index f468b6b..c52717d 100644
--- a/src/cmd/internal/obj/arm64/asm_arm64_test.go
+++ b/src/cmd/internal/obj/arm64/asm_arm64_test.go
@@ -8,9 +8,7 @@
 	"bytes"
 	"fmt"
 	"internal/testenv"
-	"io/ioutil"
 	"os"
-	"os/exec"
 	"path/filepath"
 	"regexp"
 	"testing"
@@ -27,7 +25,7 @@
 	}
 	testenv.MustHaveGoBuild(t)
 
-	dir, err := ioutil.TempDir("", "testlarge")
+	dir, err := os.MkdirTemp("", "testlarge")
 	if err != nil {
 		t.Fatalf("could not create directory: %v", err)
 	}
@@ -38,7 +36,7 @@
 	gen(buf)
 
 	tmpfile := filepath.Join(dir, "x.s")
-	err = ioutil.WriteFile(tmpfile, buf.Bytes(), 0644)
+	err = os.WriteFile(tmpfile, buf.Bytes(), 0644)
 	if err != nil {
 		t.Fatalf("can't write output: %v\n", err)
 	}
@@ -46,7 +44,7 @@
 	pattern := `0x0080\s00128\s\(.*\)\tMOVD\t\$3,\sR3`
 
 	// assemble generated file
-	cmd := exec.Command(testenv.GoToolPath(t), "tool", "asm", "-S", "-o", filepath.Join(dir, "test.o"), tmpfile)
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "tool", "asm", "-S", "-o", filepath.Join(dir, "test.o"), tmpfile)
 	cmd.Env = append(os.Environ(), "GOOS=linux")
 	out, err := cmd.CombinedOutput()
 	if err != nil {
@@ -61,7 +59,7 @@
 	}
 
 	// build generated file
-	cmd = exec.Command(testenv.GoToolPath(t), "tool", "asm", "-o", filepath.Join(dir, "x.o"), tmpfile)
+	cmd = testenv.Command(t, testenv.GoToolPath(t), "tool", "asm", "-o", filepath.Join(dir, "x.o"), tmpfile)
 	cmd.Env = append(os.Environ(), "GOOS=linux")
 	out, err = cmd.CombinedOutput()
 	if err != nil {
@@ -86,16 +84,16 @@
 
 // Issue 20348.
 func TestNoRet(t *testing.T) {
-	dir, err := ioutil.TempDir("", "testnoret")
+	dir, err := os.MkdirTemp("", "testnoret")
 	if err != nil {
 		t.Fatal(err)
 	}
 	defer os.RemoveAll(dir)
 	tmpfile := filepath.Join(dir, "x.s")
-	if err := ioutil.WriteFile(tmpfile, []byte("TEXT ·stub(SB),$0-0\nNOP\n"), 0644); err != nil {
+	if err := os.WriteFile(tmpfile, []byte("TEXT ·stub(SB),$0-0\nNOP\n"), 0644); err != nil {
 		t.Fatal(err)
 	}
-	cmd := exec.Command(testenv.GoToolPath(t), "tool", "asm", "-o", filepath.Join(dir, "x.o"), tmpfile)
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "tool", "asm", "-o", filepath.Join(dir, "x.o"), tmpfile)
 	cmd.Env = append(os.Environ(), "GOOS=linux")
 	if out, err := cmd.CombinedOutput(); err != nil {
 		t.Errorf("%v\n%s", err, out)
@@ -106,7 +104,7 @@
 // code can be aligned to the alignment value.
 func TestPCALIGN(t *testing.T) {
 	testenv.MustHaveGoBuild(t)
-	dir, err := ioutil.TempDir("", "testpcalign")
+	dir, err := os.MkdirTemp("", "testpcalign")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -130,10 +128,10 @@
 	}
 
 	for _, test := range testCases {
-		if err := ioutil.WriteFile(tmpfile, test.code, 0644); err != nil {
+		if err := os.WriteFile(tmpfile, test.code, 0644); err != nil {
 			t.Fatal(err)
 		}
-		cmd := exec.Command(testenv.GoToolPath(t), "tool", "asm", "-S", "-o", tmpout, tmpfile)
+		cmd := testenv.Command(t, testenv.GoToolPath(t), "tool", "asm", "-S", "-o", tmpout, tmpfile)
 		cmd.Env = append(os.Environ(), "GOOS=linux")
 		out, err := cmd.CombinedOutput()
 		if err != nil {
diff --git a/src/cmd/internal/obj/arm64/doc.go b/src/cmd/internal/obj/arm64/doc.go
index c12f618..4606e98 100644
--- a/src/cmd/internal/obj/arm64/doc.go
+++ b/src/cmd/internal/obj/arm64/doc.go
@@ -13,7 +13,7 @@
 
 Examples:
 
-	ADC R24, R14, R12          <=>     adc x12, x24
+	ADC R24, R14, R12          <=>     adc x12, x14, x24
 	ADDW R26->24, R21, R15     <=>     add w15, w21, w26, asr #24
 	FCMPS F2, F3               <=>     fcmp s3, s2
 	FCMPD F2, F3               <=>     fcmp d3, d2
diff --git a/src/cmd/internal/obj/arm64/obj7.go b/src/cmd/internal/obj/arm64/obj7.go
index 83ae64a..6c2cb63 100644
--- a/src/cmd/internal/obj/arm64/obj7.go
+++ b/src/cmd/internal/obj/arm64/obj7.go
@@ -40,21 +40,27 @@
 	"math"
 )
 
-var complements = []obj.As{
-	AADD:  ASUB,
-	AADDW: ASUBW,
-	ASUB:  AADD,
-	ASUBW: AADDW,
-	ACMP:  ACMN,
-	ACMPW: ACMNW,
-	ACMN:  ACMP,
-	ACMNW: ACMPW,
-}
-
-// noZRreplace is the set of instructions for which $0 in the To operand
-// should NOT be replaced with REGZERO.
-var noZRreplace = map[obj.As]bool{
-	APRFM: true,
+// zrReplace is the set of instructions for which $0 in the From operand
+// should be replaced with REGZERO.
+var zrReplace = map[obj.As]bool{
+	AMOVD:  true,
+	AMOVW:  true,
+	AMOVWU: true,
+	AMOVH:  true,
+	AMOVHU: true,
+	AMOVB:  true,
+	AMOVBU: true,
+	ASBC:   true,
+	ASBCW:  true,
+	ASBCS:  true,
+	ASBCSW: true,
+	AADC:   true,
+	AADCW:  true,
+	AADCS:  true,
+	AADCSW: true,
+	AFMOVD: true,
+	AFMOVS: true,
+	AMSR:   true,
 }
 
 func (c *ctxt7) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
@@ -301,18 +307,13 @@
 	p.From.Class = 0
 	p.To.Class = 0
 
-	// $0 results in C_ZCON, which matches both C_REG and various
-	// C_xCON, however the C_REG cases in asmout don't expect a
-	// constant, so they will use the register fields and assemble
-	// a R0. To prevent that, rewrite $0 as ZR.
-	if p.From.Type == obj.TYPE_CONST && p.From.Offset == 0 {
+	// Previously we rewrote $0 to ZR, but we have now removed this change.
+	// In order to be compatible with some previous legal instruction formats,
+	// reserve the previous conversion for some specific instructions.
+	if p.From.Type == obj.TYPE_CONST && p.From.Offset == 0 && zrReplace[p.As] {
 		p.From.Type = obj.TYPE_REG
 		p.From.Reg = REGZERO
 	}
-	if p.To.Type == obj.TYPE_CONST && p.To.Offset == 0 && !noZRreplace[p.As] {
-		p.To.Type = obj.TYPE_REG
-		p.To.Reg = REGZERO
-	}
 
 	// Rewrite BR/BL to symbol as TYPE_BRANCH.
 	switch p.As {
@@ -367,21 +368,6 @@
 		break
 	}
 
-	// Rewrite negative immediates as positive immediates with
-	// complementary instruction.
-	switch p.As {
-	case AADD, ASUB, ACMP, ACMN:
-		if p.From.Type == obj.TYPE_CONST && p.From.Offset < 0 && p.From.Offset != -1<<63 {
-			p.From.Offset = -p.From.Offset
-			p.As = complements[p.As]
-		}
-	case AADDW, ASUBW, ACMPW, ACMNW:
-		if p.From.Type == obj.TYPE_CONST && p.From.Offset < 0 && int32(p.From.Offset) != -1<<31 {
-			p.From.Offset = -p.From.Offset
-			p.As = complements[p.As]
-		}
-	}
-
 	if c.ctxt.Flag_dynlink {
 		c.rewriteToUseGot(p)
 	}
diff --git a/src/cmd/internal/obj/dwarf.go b/src/cmd/internal/obj/dwarf.go
index 3229382..a9c13fd 100644
--- a/src/cmd/internal/obj/dwarf.go
+++ b/src/cmd/internal/obj/dwarf.go
@@ -58,7 +58,7 @@
 			continue
 		}
 		newStmt := p.Pos.IsStmt() != src.PosNotStmt
-		newName, newLine := linkgetlineFromPos(ctxt, p.Pos)
+		newName, newLine := ctxt.getFileSymbolAndLine(p.Pos)
 
 		// Output debug info.
 		wrote := false
@@ -335,7 +335,7 @@
 func (ctxt *Link) fileSymbol(fn *LSym) *LSym {
 	p := fn.Func().Text
 	if p != nil {
-		f, _ := linkgetlineFromPos(ctxt, p.Pos)
+		f, _ := ctxt.getFileSymbolAndLine(p.Pos)
 		fsym := ctxt.Lookup(f)
 		return fsym
 	}
diff --git a/src/cmd/internal/obj/inl.go b/src/cmd/internal/obj/inl.go
index de3c73d..934f1c2 100644
--- a/src/cmd/internal/obj/inl.go
+++ b/src/cmd/internal/obj/inl.go
@@ -109,8 +109,9 @@
 }
 
 // AllPos returns a slice of the positions inlined at xpos, from
-// innermost (index zero) to outermost.  To avoid gratuitous allocation
-// the result is passed in and extended if necessary.
+// innermost (index zero) to outermost.  To avoid allocation
+// the input slice is truncated, and used for the result, extended
+// as necessary.
 func (ctxt *Link) AllPos(xpos src.XPos, result []src.Pos) []src.Pos {
 	pos := ctxt.InnermostPos(xpos)
 	result = result[:0]
diff --git a/src/cmd/internal/obj/line.go b/src/cmd/internal/obj/line.go
index 87cd32b..20f03d9 100644
--- a/src/cmd/internal/obj/line.go
+++ b/src/cmd/internal/obj/line.go
@@ -14,17 +14,22 @@
 	ctxt.Imports = append(ctxt.Imports, goobj.ImportedPkg{Pkg: pkg, Fingerprint: fingerprint})
 }
 
-func linkgetlineFromPos(ctxt *Link, xpos src.XPos) (f string, l int32) {
-	pos := ctxt.PosTable.Pos(xpos)
+// getFileSymbolAndLine returns the relative file symbol and relative line
+// number for a position (i.e., as adjusted by a //line directive). This is the
+// file/line visible in the final binary (pcfile, pcln, etc).
+func (ctxt *Link) getFileSymbolAndLine(xpos src.XPos) (f string, l int32) {
+	pos := ctxt.InnermostPos(xpos)
 	if !pos.IsKnown() {
 		pos = src.Pos{}
 	}
-	// TODO(gri) Should this use relative or absolute line number?
 	return pos.SymFilename(), int32(pos.RelLine())
 }
 
-// getFileIndexAndLine returns the file index (local to the CU), and the line number for a position.
-func getFileIndexAndLine(ctxt *Link, xpos src.XPos) (int, int32) {
-	f, l := linkgetlineFromPos(ctxt, xpos)
+// getFileIndexAndLine returns the relative file index (local to the CU), and
+// the relative line number for a position (i.e., as adjusted by a //line
+// directive). This is the file/line visible in the final binary (pcfile, pcln,
+// etc).
+func (ctxt *Link) getFileIndexAndLine(xpos src.XPos) (int, int32) {
+	f, l := ctxt.getFileSymbolAndLine(xpos)
 	return ctxt.PosTable.FileIndex(f), l
 }
diff --git a/src/cmd/internal/obj/line_test.go b/src/cmd/internal/obj/line_test.go
index e0db7f3..d3bb4e2 100644
--- a/src/cmd/internal/obj/line_test.go
+++ b/src/cmd/internal/obj/line_test.go
@@ -10,7 +10,7 @@
 	"testing"
 )
 
-func TestLinkgetlineFromPos(t *testing.T) {
+func TestGetFileSymbolAndLine(t *testing.T) {
 	ctxt := new(Link)
 	ctxt.hash = make(map[string]*LSym)
 	ctxt.statichash = make(map[string]*LSym)
@@ -31,10 +31,10 @@
 	}
 
 	for _, test := range tests {
-		f, l := linkgetlineFromPos(ctxt, ctxt.PosTable.XPos(test.pos))
+		f, l := ctxt.getFileSymbolAndLine(ctxt.PosTable.XPos(test.pos))
 		got := fmt.Sprintf("%s:%d", f, l)
 		if got != src.FileSymPrefix+test.want {
-			t.Errorf("linkgetline(%v) = %q, want %q", test.pos, got, test.want)
+			t.Errorf("ctxt.getFileSymbolAndLine(%v) = %q, want %q", test.pos, got, test.want)
 		}
 	}
 }
diff --git a/src/cmd/internal/obj/link.go b/src/cmd/internal/obj/link.go
index 1c2bfa9..8037017 100644
--- a/src/cmd/internal/obj/link.go
+++ b/src/cmd/internal/obj/link.go
@@ -319,7 +319,7 @@
 	Isize    uint8     // for x86 back end: size of the instruction in bytes
 }
 
-// Pos indicates whether the oprand is the source or the destination.
+// AddrPos indicates whether the operand is the source or the destination.
 type AddrPos struct {
 	Addr
 	Pos OperandPos
@@ -472,16 +472,17 @@
 
 // A FuncInfo contains extra fields for STEXT symbols.
 type FuncInfo struct {
-	Args     int32
-	Locals   int32
-	Align    int32
-	FuncID   objabi.FuncID
-	FuncFlag objabi.FuncFlag
-	Text     *Prog
-	Autot    map[*LSym]struct{}
-	Pcln     Pcln
-	InlMarks []InlMark
-	spills   []RegSpill
+	Args      int32
+	Locals    int32
+	Align     int32
+	FuncID    objabi.FuncID
+	FuncFlag  objabi.FuncFlag
+	StartLine int32
+	Text      *Prog
+	Autot     map[*LSym]struct{}
+	Pcln      Pcln
+	InlMarks  []InlMark
+	spills    []RegSpill
 
 	dwarfInfoSym       *LSym
 	dwarfLocSym        *LSym
diff --git a/src/cmd/internal/obj/loong64/a.out.go b/src/cmd/internal/obj/loong64/a.out.go
index 951eeb7..88bf714 100644
--- a/src/cmd/internal/obj/loong64/a.out.go
+++ b/src/cmd/internal/obj/loong64/a.out.go
@@ -335,6 +335,7 @@
 	ASQRTF
 	ASRA
 	ASRL
+	AROTR
 	ASUB
 	ASUBD
 	ASUBF
@@ -351,6 +352,9 @@
 
 	AXOR
 
+	AMASKEQZ
+	AMASKNEZ
+
 	// 64-bit
 	AMOVV
 	AMOVVL
@@ -359,6 +363,7 @@
 	ASLLV
 	ASRAV
 	ASRLV
+	AROTRV
 	ADIVV
 	ADIVVU
 
diff --git a/src/cmd/internal/obj/loong64/anames.go b/src/cmd/internal/obj/loong64/anames.go
index 48d8a78..20e7465 100644
--- a/src/cmd/internal/obj/loong64/anames.go
+++ b/src/cmd/internal/obj/loong64/anames.go
@@ -88,6 +88,7 @@
 	"SQRTF",
 	"SRA",
 	"SRL",
+	"ROTR",
 	"SUB",
 	"SUBD",
 	"SUBF",
@@ -99,12 +100,15 @@
 	"TNE",
 	"WORD",
 	"XOR",
+	"MASKEQZ",
+	"MASKNEZ",
 	"MOVV",
 	"MOVVL",
 	"MOVVR",
 	"SLLV",
 	"SRAV",
 	"SRLV",
+	"ROTRV",
 	"DIVV",
 	"DIVVU",
 	"REMV",
diff --git a/src/cmd/internal/obj/loong64/asm.go b/src/cmd/internal/obj/loong64/asm.go
index c5829ad..df3e9bf 100644
--- a/src/cmd/internal/obj/loong64/asm.go
+++ b/src/cmd/internal/obj/loong64/asm.go
@@ -68,6 +68,7 @@
 	{AAND, C_REG, C_NONE, C_REG, 2, 4, 0, 0, 0},
 	{ANEGW, C_REG, C_NONE, C_REG, 2, 4, 0, 0, 0},
 	{ANEGV, C_REG, C_NONE, C_REG, 2, 4, 0, sys.Loong64, 0},
+	{AMASKEQZ, C_REG, C_REG, C_REG, 2, 4, 0, 0, 0},
 
 	{ASLL, C_REG, C_NONE, C_REG, 9, 4, 0, 0, 0},
 	{ASLL, C_REG, C_REG, C_REG, 9, 4, 0, 0, 0},
@@ -979,10 +980,12 @@
 		case ASLL:
 			opset(ASRL, r0)
 			opset(ASRA, r0)
+			opset(AROTR, r0)
 
 		case ASLLV:
 			opset(ASRAV, r0)
 			opset(ASRLV, r0)
+			opset(AROTRV, r0)
 
 		case ASUB:
 			opset(ASUBU, r0)
@@ -1041,6 +1044,9 @@
 
 		case ATEQ:
 			opset(ATNE, r0)
+
+		case AMASKEQZ:
+			opset(AMASKNEZ, r0)
 		}
 	}
 }
@@ -1086,7 +1092,7 @@
 	return op | (i&0xFFFFF)<<5 | (r2&0x1F)<<0 // ui20, rd5
 }
 
-// Encoding for the 'b' or 'bl' instruction
+// Encoding for the 'b' or 'bl' instruction.
 func OP_B_BL(op uint32, i uint32) uint32 {
 	return op | ((i & 0xFFFF) << 10) | ((i >> 16) & 0x3FF)
 }
@@ -1627,6 +1633,10 @@
 		return 0x24 << 15 // SLT
 	case ASGTU:
 		return 0x25 << 15 // SLTU
+	case AMASKEQZ:
+		return 0x26 << 15
+	case AMASKNEZ:
+		return 0x27 << 15
 	case AAND:
 		return 0x29 << 15
 	case AOR:
@@ -1645,12 +1655,16 @@
 		return 0x2f << 15
 	case ASRA:
 		return 0x30 << 15
+	case AROTR:
+		return 0x36 << 15
 	case ASLLV:
 		return 0x31 << 15
 	case ASRLV:
 		return 0x32 << 15
 	case ASRAV:
 		return 0x33 << 15
+	case AROTRV:
+		return 0x37 << 15
 	case AADDV:
 		return 0x21 << 15
 	case AADDVU:
@@ -1837,6 +1851,8 @@
 		return 0x00089 << 15
 	case ASRA:
 		return 0x00091 << 15
+	case AROTR:
+		return 0x00099 << 15
 	case AADDV:
 		return 0x00b << 22
 	case AADDVU:
@@ -1931,6 +1947,9 @@
 	case ASRAV,
 		-ASRAV:
 		return 0x0049 << 16
+	case AROTRV,
+		-AROTRV:
+		return 0x004d << 16
 	case -ALL:
 		return 0x020 << 24
 	case -ALLV:
@@ -1953,7 +1972,8 @@
 	switch a {
 	case ASLLV,
 		ASRLV,
-		ASRAV:
+		ASRAV,
+		AROTRV:
 		return true
 	}
 	return false
diff --git a/src/cmd/internal/obj/objfile.go b/src/cmd/internal/obj/objfile.go
index 89339b0..ff0968e 100644
--- a/src/cmd/internal/obj/objfile.go
+++ b/src/cmd/internal/obj/objfile.go
@@ -220,6 +220,16 @@
 	ctxt    *Link
 	pkgpath string   // the package import path (escaped), "" if unknown
 	pkglist []string // list of packages referenced, indexed by ctxt.pkgIdx
+
+	// scratch space for writing (the Write methods escape
+	// as they are interface calls)
+	tmpSym      goobj.Sym
+	tmpReloc    goobj.Reloc
+	tmpAux      goobj.Aux
+	tmpHash64   goobj.Hash64Type
+	tmpHash     goobj.HashType
+	tmpRefFlags goobj.RefFlags
+	tmpRefName  goobj.RefName
 }
 
 // prepare package index list
@@ -321,14 +331,14 @@
 	if s.ReflectMethod() {
 		flag |= goobj.SymFlagReflectMethod
 	}
-	if strings.HasPrefix(s.Name, "type.") && s.Name[5] != '.' && s.Type == objabi.SRODATA {
+	if strings.HasPrefix(s.Name, "type:") && s.Name[5] != '.' && s.Type == objabi.SRODATA {
 		flag |= goobj.SymFlagGoType
 	}
 	flag2 := uint8(0)
 	if s.UsedInIface() {
 		flag2 |= goobj.SymFlagUsedInIface
 	}
-	if strings.HasPrefix(s.Name, "go.itab.") && s.Type == objabi.SRODATA {
+	if strings.HasPrefix(s.Name, "go:itab.") && s.Type == objabi.SRODATA {
 		flag2 |= goobj.SymFlagItab
 	}
 	if strings.HasPrefix(s.Name, w.ctxt.Pkgpath) && strings.HasPrefix(s.Name[len(w.ctxt.Pkgpath):], ".") && strings.HasPrefix(s.Name[len(w.ctxt.Pkgpath)+1:], objabi.GlobalDictPrefix) {
@@ -351,10 +361,9 @@
 		// TODO: maybe the compiler could set the alignment for all
 		// data symbols more carefully.
 		switch {
-		case strings.HasPrefix(s.Name, "go.string."),
-			strings.HasPrefix(name, "type..namedata."),
-			strings.HasPrefix(name, "type..importpath."),
-			strings.HasPrefix(name, "runtime.gcbits."),
+		case strings.HasPrefix(s.Name, "go:string."),
+			strings.HasPrefix(name, "type:.namedata."),
+			strings.HasPrefix(name, "type:.importpath."),
 			strings.HasSuffix(name, ".opendefer"),
 			strings.HasSuffix(name, ".arginfo0"),
 			strings.HasSuffix(name, ".arginfo1"),
@@ -380,7 +389,7 @@
 	if s.Size > cutoff {
 		w.ctxt.Diag("%s: symbol too large (%d bytes > %d bytes)", s.Name, s.Size, cutoff)
 	}
-	var o goobj.Sym
+	o := &w.tmpSym
 	o.SetName(name, w.Writer)
 	o.SetABI(abi)
 	o.SetType(uint8(s.Type))
@@ -395,16 +404,16 @@
 	if !s.ContentAddressable() || len(s.R) != 0 {
 		panic("Hash of non-content-addressable symbol")
 	}
-	b := contentHash64(s)
-	w.Bytes(b[:])
+	w.tmpHash64 = contentHash64(s)
+	w.Bytes(w.tmpHash64[:])
 }
 
 func (w *writer) Hash(s *LSym) {
 	if !s.ContentAddressable() {
 		panic("Hash of non-content-addressable symbol")
 	}
-	b := w.contentHash(s)
-	w.Bytes(b[:])
+	w.tmpHash = w.contentHash(s)
+	w.Bytes(w.tmpHash[:])
 }
 
 // contentHashSection returns a mnemonic for s's section.
@@ -430,9 +439,9 @@
 		strings.HasSuffix(name, ".wrapinfo") ||
 		strings.HasSuffix(name, ".args_stackmap") ||
 		strings.HasSuffix(name, ".stkobj") {
-		return 'F' // go.func.* or go.funcrel.*
+		return 'F' // go:func.* or go:funcrel.*
 	}
-	if strings.HasPrefix(name, "type.") {
+	if strings.HasPrefix(name, "type:") {
 		return 'T'
 	}
 	return 0
@@ -539,7 +548,7 @@
 }
 
 func (w *writer) Reloc(r *Reloc) {
-	var o goobj.Reloc
+	o := &w.tmpReloc
 	o.SetOff(r.Off)
 	o.SetSiz(r.Siz)
 	o.SetType(uint16(r.Type))
@@ -549,7 +558,7 @@
 }
 
 func (w *writer) aux1(typ uint8, rs *LSym) {
-	var o goobj.Aux
+	o := &w.tmpAux
 	o.SetType(typ)
 	o.SetSym(makeSymRef(rs))
 	o.Write(w.Writer)
@@ -619,7 +628,7 @@
 		if flag2 == 0 {
 			return // no need to write zero flags
 		}
-		var o goobj.RefFlags
+		o := &w.tmpRefFlags
 		o.SetSym(symref)
 		o.SetFlag2(flag2)
 		o.Write(w.Writer)
@@ -645,7 +654,7 @@
 		}
 		seen[rs] = true
 		symref := makeSymRef(rs)
-		var o goobj.RefName
+		o := &w.tmpRefName
 		o.SetSym(symref)
 		o.SetName(rs.Name, w.Writer)
 		o.Write(w.Writer)
@@ -698,7 +707,6 @@
 // generate symbols for FuncInfo.
 func genFuncInfoSyms(ctxt *Link) {
 	infosyms := make([]*LSym, 0, len(ctxt.Text))
-	hashedsyms := make([]*LSym, 0, 4*len(ctxt.Text))
 	var b bytes.Buffer
 	symidx := int32(len(ctxt.defs))
 	for _, s := range ctxt.Text {
@@ -707,10 +715,11 @@
 			continue
 		}
 		o := goobj.FuncInfo{
-			Args:     uint32(fn.Args),
-			Locals:   uint32(fn.Locals),
-			FuncID:   fn.FuncID,
-			FuncFlag: fn.FuncFlag,
+			Args:      uint32(fn.Args),
+			Locals:    uint32(fn.Locals),
+			FuncID:    fn.FuncID,
+			FuncFlag:  fn.FuncFlag,
+			StartLine: fn.StartLine,
 		}
 		pc := &fn.Pcln
 		i := 0
@@ -722,7 +731,7 @@
 		sort.Slice(o.File, func(i, j int) bool { return o.File[i] < o.File[j] })
 		o.InlTree = make([]goobj.InlTreeNode, len(pc.InlTree.nodes))
 		for i, inl := range pc.InlTree.nodes {
-			f, l := getFileIndexAndLine(ctxt, inl.Pos)
+			f, l := ctxt.getFileIndexAndLine(inl.Pos)
 			o.InlTree[i] = goobj.InlTreeNode{
 				Parent:   int32(inl.Parent),
 				File:     goobj.CUFileIndex(f),
@@ -760,7 +769,6 @@
 		}
 	}
 	ctxt.defs = append(ctxt.defs, infosyms...)
-	ctxt.hasheddefs = append(ctxt.hasheddefs, hashedsyms...)
 }
 
 func writeAuxSymDebug(ctxt *Link, par *LSym, aux *LSym) {
diff --git a/src/cmd/internal/obj/objfile_test.go b/src/cmd/internal/obj/objfile_test.go
index 91e96e4..9e99056 100644
--- a/src/cmd/internal/obj/objfile_test.go
+++ b/src/cmd/internal/obj/objfile_test.go
@@ -6,15 +6,14 @@
 
 import (
 	"bytes"
-	"cmd/internal/goobj"
-	"cmd/internal/sys"
 	"internal/testenv"
-	"io/ioutil"
 	"os"
-	"os/exec"
 	"path/filepath"
 	"testing"
 	"unsafe"
+
+	"cmd/internal/goobj"
+	"cmd/internal/sys"
 )
 
 var dummyArch = LinkArch{Arch: sys.ArchAMD64}
@@ -99,19 +98,19 @@
 		t.Skip("skip on 32-bit architectures")
 	}
 
-	tmpdir, err := ioutil.TempDir("", "TestSymbolTooLarge")
+	tmpdir, err := os.MkdirTemp("", "TestSymbolTooLarge")
 	if err != nil {
 		t.Fatal(err)
 	}
 	defer os.RemoveAll(tmpdir)
 
 	src := filepath.Join(tmpdir, "p.go")
-	err = ioutil.WriteFile(src, []byte("package p; var x [1<<32]byte"), 0666)
+	err = os.WriteFile(src, []byte("package p; var x [1<<32]byte"), 0666)
 	if err != nil {
 		t.Fatalf("failed to write source file: %v\n", err)
 	}
 	obj := filepath.Join(tmpdir, "p.o")
-	cmd := exec.Command(testenv.GoToolPath(t), "tool", "compile", "-p=p", "-o", obj, src)
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "tool", "compile", "-p=p", "-o", obj, src)
 	out, err := cmd.CombinedOutput()
 	if err == nil {
 		t.Fatalf("did not fail\noutput: %s", out)
@@ -129,7 +128,7 @@
 	tmpdir := t.TempDir()
 
 	src := filepath.Join(tmpdir, "x.go")
-	err := ioutil.WriteFile(src, []byte("package main; import \"fmt\"; func main() { fmt.Println(123) }\n"), 0666)
+	err := os.WriteFile(src, []byte("package main; import \"fmt\"; func main() { fmt.Println(123) }\n"), 0666)
 	if err != nil {
 		t.Fatalf("failed to write source file: %v\n", err)
 	}
@@ -137,7 +136,7 @@
 
 	// Build the fmt package with norefname. Not rebuilding all packages to save time.
 	// Also testing that norefname and non-norefname packages can link together.
-	cmd := exec.Command(testenv.GoToolPath(t), "build", "-gcflags=fmt=-d=norefname", "-o", exe, src)
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-gcflags=fmt=-d=norefname", "-o", exe, src)
 	out, err := cmd.CombinedOutput()
 	if err != nil {
 		t.Fatalf("build failed: %v, output:\n%s", err, out)
diff --git a/src/cmd/internal/obj/pcln.go b/src/cmd/internal/obj/pcln.go
index 49b425b..67a0780 100644
--- a/src/cmd/internal/obj/pcln.go
+++ b/src/cmd/internal/obj/pcln.go
@@ -142,7 +142,7 @@
 	if p.As == ATEXT || p.As == ANOP || p.Pos.Line() == 0 || phase == 1 {
 		return oldval
 	}
-	f, l := getFileIndexAndLine(ctxt, p.Pos)
+	f, l := ctxt.getFileIndexAndLine(p.Pos)
 	if arg == nil {
 		return l
 	}
@@ -294,9 +294,7 @@
 		inlMarkProgs[inlMark.p] = struct{}{}
 	}
 	for p := fn.Text; p != nil; p = p.Link {
-		if _, ok := inlMarkProgs[p]; ok {
-			delete(inlMarkProgs, p)
-		}
+		delete(inlMarkProgs, p)
 	}
 	if len(inlMarkProgs) > 0 {
 		ctxt.Diag("one or more instructions used as inline markers are no longer reachable")
@@ -369,7 +367,7 @@
 	Done    bool
 }
 
-// newPCIter creates a PCIter with a scale factor for the PC step size.
+// NewPCIter creates a PCIter with a scale factor for the PC step size.
 func NewPCIter(pcScale uint32) *PCIter {
 	it := new(PCIter)
 	it.PCScale = pcScale
diff --git a/src/cmd/internal/obj/plist.go b/src/cmd/internal/obj/plist.go
index ed33b21..fe9d2e1 100644
--- a/src/cmd/internal/obj/plist.go
+++ b/src/cmd/internal/obj/plist.go
@@ -6,6 +6,7 @@
 
 import (
 	"cmd/internal/objabi"
+	"cmd/internal/src"
 	"fmt"
 	"strings"
 )
@@ -57,12 +58,12 @@
 			switch p.To.Sym.Name {
 			case "go_args_stackmap":
 				if p.From.Type != TYPE_CONST || p.From.Offset != objabi.FUNCDATA_ArgsPointerMaps {
-					ctxt.Diag("FUNCDATA use of go_args_stackmap(SB) without FUNCDATA_ArgsPointerMaps")
+					ctxt.Diag("%s: FUNCDATA use of go_args_stackmap(SB) without FUNCDATA_ArgsPointerMaps", p.Pos)
 				}
 				p.To.Sym = ctxt.LookupDerived(curtext, curtext.Name+".args_stackmap")
 			case "no_pointers_stackmap":
 				if p.From.Type != TYPE_CONST || p.From.Offset != objabi.FUNCDATA_LocalsPointerMaps {
-					ctxt.Diag("FUNCDATA use of no_pointers_stackmap(SB) without FUNCDATA_LocalsPointerMaps")
+					ctxt.Diag("%s: FUNCDATA use of no_pointers_stackmap(SB) without FUNCDATA_LocalsPointerMaps", p.Pos)
 				}
 				// funcdata for functions with no local variables in frame.
 				// Define two zero-length bitmaps, because the same index is used
@@ -159,22 +160,31 @@
 	}
 }
 
-func (ctxt *Link) InitTextSym(s *LSym, flag int) {
+func (ctxt *Link) InitTextSym(s *LSym, flag int, start src.XPos) {
 	if s == nil {
 		// func _() { }
 		return
 	}
 	if s.Func() != nil {
-		ctxt.Diag("InitTextSym double init for %s", s.Name)
+		ctxt.Diag("%s: symbol %s redeclared\n\t%s: other declaration of symbol %s", ctxt.PosTable.Pos(start), s.Name, ctxt.PosTable.Pos(s.Func().Text.Pos), s.Name)
+		return
 	}
 	s.NewFuncInfo()
 	if s.OnList() {
-		ctxt.Diag("symbol %s listed multiple times", s.Name)
+		ctxt.Diag("%s: symbol %s redeclared", ctxt.PosTable.Pos(start), s.Name)
+		return
 	}
+
+	// startLine should be the same line number that would be displayed via
+	// pcln, etc for the declaration (i.e., relative line number, as
+	// adjusted by //line).
+	_, startLine := ctxt.getFileSymbolAndLine(start)
+
 	// TODO(mdempsky): Remove once cmd/asm stops writing "" symbols.
 	name := strings.Replace(s.Name, "\"\"", ctxt.Pkgpath, -1)
 	s.Func().FuncID = objabi.GetFuncID(name, flag&WRAPPER != 0 || flag&ABIWRAPPER != 0)
 	s.Func().FuncFlag = ctxt.toFuncFlag(flag)
+	s.Func().StartLine = startLine
 	s.Set(AttrOnList, true)
 	s.Set(AttrDuplicateOK, flag&DUPOK != 0)
 	s.Set(AttrNoSplit, flag&NOSPLIT != 0)
@@ -202,8 +212,12 @@
 }
 
 func (ctxt *Link) Globl(s *LSym, size int64, flag int) {
+	ctxt.GloblPos(s, size, flag, src.NoXPos)
+}
+func (ctxt *Link) GloblPos(s *LSym, size int64, flag int, pos src.XPos) {
 	if s.OnList() {
-		ctxt.Diag("symbol %s listed multiple times", s.Name)
+		// TODO: print where the first declaration was.
+		ctxt.Diag("%s: symbol %s redeclared", ctxt.PosTable.Pos(pos), s.Name)
 	}
 	s.Set(AttrOnList, true)
 	ctxt.Data = append(ctxt.Data, s)
diff --git a/src/cmd/internal/obj/ppc64/a.out.go b/src/cmd/internal/obj/ppc64/a.out.go
index 30eba43..995f9d9 100644
--- a/src/cmd/internal/obj/ppc64/a.out.go
+++ b/src/cmd/internal/obj/ppc64/a.out.go
@@ -258,6 +258,18 @@
 	REG_CR6
 	REG_CR7
 
+	// MMA accumulator registers, these shadow VSR 0-31
+	// e.g MMAx shadows VSRx*4-VSRx*4+3 or
+	//     MMA0 shadows VSR0-VSR3
+	REG_A0
+	REG_A1
+	REG_A2
+	REG_A3
+	REG_A4
+	REG_A5
+	REG_A6
+	REG_A7
+
 	REG_MSR
 	REG_FPSCR
 	REG_CR
@@ -399,6 +411,7 @@
 	C_CREG     /* The condition registor (CR) */
 	C_CRBIT    /* A single bit of the CR register (0-31) */
 	C_SPR      /* special processor register */
+	C_AREG     /* MMA accumulator register */
 	C_ZCON     /* The constant zero */
 	C_U1CON    /* 1 bit unsigned constant */
 	C_U2CON    /* 2 bit unsigned constant */
@@ -419,9 +432,10 @@
 	C_SBRA     /* A short offset argument to a branching instruction */
 	C_LBRA     /* A long offset argument to a branching instruction */
 	C_LBRAPIC  /* Like C_LBRA, but requires an extra NOP for potential TOC restore by the linker. */
-	C_ZOREG    /* An reg+reg memory arg, or a $0+reg memory op */
+	C_ZOREG    /* An $0+reg memory op */
 	C_SOREG    /* An $n+reg memory arg where n is a 16 bit signed offset */
 	C_LOREG    /* An $n+reg memory arg where n is a 32 bit signed offset */
+	C_XOREG    /* An reg+reg memory arg */
 	C_FPSCR    /* The fpscr register */
 	C_XER      /* The xer, holds the carry bit */
 	C_LR       /* The link register */
@@ -669,8 +683,6 @@
 	ADCBT
 	ADCBTST
 	ADCBZ
-	AECIWX
-	AECOWX
 	AEIEIO
 	AICBI
 	AISYNC
@@ -807,13 +819,11 @@
 	ACOPY
 	APASTECC
 	ADARN
-	ALDMX
 	AMADDHD
 	AMADDHDU
 	AMADDLD
 
 	/* Vector */
-	ALV
 	ALVEBX
 	ALVEHX
 	ALVEWX
@@ -821,7 +831,6 @@
 	ALVXL
 	ALVSL
 	ALVSR
-	ASTV
 	ASTVEBX
 	ASTVEHX
 	ASTVEWX
@@ -969,11 +978,9 @@
 	AVBPERMQ
 	AVBPERMD
 	AVSEL
-	AVSPLT
 	AVSPLTB
 	AVSPLTH
 	AVSPLTW
-	AVSPLTI
 	AVSPLTISB
 	AVSPLTISH
 	AVSPLTISW
@@ -1037,7 +1044,6 @@
 	AXXSEL
 	AXXMRGHW
 	AXXMRGLW
-	AXXSPLT
 	AXXSPLTW
 	AXXSPLTIB
 	AXXPERM
@@ -1077,13 +1083,10 @@
 	AXVCVSXWSP
 	AXVCVUXDSP
 	AXVCVUXWSP
-
-	/* ISA 3.1 opcodes */
-	APNOP
-
-	ALAST
+	ALASTAOUT // The last instruction in this list. Also the first opcode generated by ppc64map.
 
 	// aliases
-	ABR = obj.AJMP
-	ABL = obj.ACALL
+	ABR   = obj.AJMP
+	ABL   = obj.ACALL
+	ALAST = ALASTGEN // The final enumerated instruction value + 1. This is used to size the oprange table.
 )
diff --git a/src/cmd/internal/obj/ppc64/anames.go b/src/cmd/internal/obj/ppc64/anames.go
index 7521a92..05014ec 100644
--- a/src/cmd/internal/obj/ppc64/anames.go
+++ b/src/cmd/internal/obj/ppc64/anames.go
@@ -223,8 +223,6 @@
 	"DCBT",
 	"DCBTST",
 	"DCBZ",
-	"ECIWX",
-	"ECOWX",
 	"EIEIO",
 	"ICBI",
 	"ISYNC",
@@ -349,11 +347,9 @@
 	"COPY",
 	"PASTECC",
 	"DARN",
-	"LDMX",
 	"MADDHD",
 	"MADDHDU",
 	"MADDLD",
-	"LV",
 	"LVEBX",
 	"LVEHX",
 	"LVEWX",
@@ -361,7 +357,6 @@
 	"LVXL",
 	"LVSL",
 	"LVSR",
-	"STV",
 	"STVEBX",
 	"STVEHX",
 	"STVEWX",
@@ -509,11 +504,9 @@
 	"VBPERMQ",
 	"VBPERMD",
 	"VSEL",
-	"VSPLT",
 	"VSPLTB",
 	"VSPLTH",
 	"VSPLTW",
-	"VSPLTI",
 	"VSPLTISB",
 	"VSPLTISH",
 	"VSPLTISW",
@@ -575,7 +568,6 @@
 	"XXSEL",
 	"XXMRGHW",
 	"XXMRGLW",
-	"XXSPLT",
 	"XXSPLTW",
 	"XXSPLTIB",
 	"XXPERM",
@@ -615,6 +607,5 @@
 	"XVCVSXWSP",
 	"XVCVUXDSP",
 	"XVCVUXWSP",
-	"PNOP",
-	"LAST",
+	"LASTAOUT",
 }
diff --git a/src/cmd/internal/obj/ppc64/anames9.go b/src/cmd/internal/obj/ppc64/anames9.go
index 05bfd94..ad6776a 100644
--- a/src/cmd/internal/obj/ppc64/anames9.go
+++ b/src/cmd/internal/obj/ppc64/anames9.go
@@ -16,6 +16,7 @@
 	"CREG",
 	"CRBIT",
 	"SPR",
+	"MREG",
 	"ZCON",
 	"U1CON",
 	"U2CON",
@@ -39,6 +40,7 @@
 	"ZOREG",
 	"SOREG",
 	"LOREG",
+	"XOREG",
 	"FPSCR",
 	"XER",
 	"LR",
diff --git a/src/cmd/internal/obj/ppc64/asm9.go b/src/cmd/internal/obj/ppc64/asm9.go
index f69299f..9469eda 100644
--- a/src/cmd/internal/obj/ppc64/asm9.go
+++ b/src/cmd/internal/obj/ppc64/asm9.go
@@ -55,11 +55,6 @@
 // Instruction layout.
 
 const (
-	funcAlign     = 16
-	funcAlignMask = funcAlign - 1
-)
-
-const (
 	r0iszero = 1
 )
 
@@ -79,6 +74,8 @@
 	// prefixed instruction. The prefixed instruction should be written first
 	// (e.g when Optab.size > 8).
 	ispfx bool
+
+	asmout func(*ctxt9, *obj.Prog, *Optab, *[5]uint32)
 }
 
 // optab contains an array to be sliced of accepted operand combinations for an
@@ -202,28 +199,36 @@
 	{as: AFMUL, a1: C_FREG, a2: C_FREG, a6: C_FREG, type_: 32, size: 4},
 
 	{as: AMOVBU, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
+	{as: AMOVBU, a1: C_REG, a6: C_XOREG, type_: 108, size: 4},
 	{as: AMOVBU, a1: C_SOREG, a6: C_REG, type_: 8, size: 8},
+	{as: AMOVBU, a1: C_XOREG, a6: C_REG, type_: 109, size: 8},
 
 	{as: AMOVBZU, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
+	{as: AMOVBZU, a1: C_REG, a6: C_XOREG, type_: 108, size: 4},
 	{as: AMOVBZU, a1: C_SOREG, a6: C_REG, type_: 8, size: 4},
+	{as: AMOVBZU, a1: C_XOREG, a6: C_REG, type_: 109, size: 4},
 
-	{as: AMOVHBR, a1: C_REG, a6: C_ZOREG, type_: 44, size: 4},
-	{as: AMOVHBR, a1: C_ZOREG, a6: C_REG, type_: 45, size: 4},
+	{as: AMOVHBR, a1: C_REG, a6: C_XOREG, type_: 44, size: 4},
+	{as: AMOVHBR, a1: C_XOREG, a6: C_REG, type_: 45, size: 4},
 
 	{as: AMOVB, a1: C_ADDR, a6: C_REG, type_: 75, size: 12},
 	{as: AMOVB, a1: C_LOREG, a6: C_REG, type_: 36, size: 12},
 	{as: AMOVB, a1: C_SOREG, a6: C_REG, type_: 8, size: 8},
+	{as: AMOVB, a1: C_XOREG, a6: C_REG, type_: 109, size: 8},
 	{as: AMOVB, a1: C_REG, a6: C_ADDR, type_: 74, size: 8},
 	{as: AMOVB, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
 	{as: AMOVB, a1: C_REG, a6: C_LOREG, type_: 35, size: 8},
+	{as: AMOVB, a1: C_REG, a6: C_XOREG, type_: 108, size: 4},
 	{as: AMOVB, a1: C_REG, a6: C_REG, type_: 13, size: 4},
 
 	{as: AMOVBZ, a1: C_ADDR, a6: C_REG, type_: 75, size: 8},
 	{as: AMOVBZ, a1: C_LOREG, a6: C_REG, type_: 36, size: 8},
 	{as: AMOVBZ, a1: C_SOREG, a6: C_REG, type_: 8, size: 4},
+	{as: AMOVBZ, a1: C_XOREG, a6: C_REG, type_: 109, size: 4},
 	{as: AMOVBZ, a1: C_REG, a6: C_ADDR, type_: 74, size: 8},
 	{as: AMOVBZ, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
 	{as: AMOVBZ, a1: C_REG, a6: C_LOREG, type_: 35, size: 8},
+	{as: AMOVBZ, a1: C_REG, a6: C_XOREG, type_: 108, size: 4},
 	{as: AMOVBZ, a1: C_REG, a6: C_REG, type_: 13, size: 4},
 
 	{as: AMOVD, a1: C_ADDCON, a6: C_REG, type_: 3, size: 4},
@@ -234,6 +239,7 @@
 	{as: AMOVD, a1: C_LACON, a6: C_REG, type_: 26, size: 8},
 	{as: AMOVD, a1: C_ADDR, a6: C_REG, type_: 75, size: 8},
 	{as: AMOVD, a1: C_SOREG, a6: C_REG, type_: 8, size: 4},
+	{as: AMOVD, a1: C_XOREG, a6: C_REG, type_: 109, size: 4},
 	{as: AMOVD, a1: C_SOREG, a6: C_SPR, type_: 107, size: 8},
 	{as: AMOVD, a1: C_LOREG, a6: C_REG, type_: 36, size: 8},
 	{as: AMOVD, a1: C_TLS_LE, a6: C_REG, type_: 79, size: 8},
@@ -241,6 +247,7 @@
 	{as: AMOVD, a1: C_SPR, a6: C_REG, type_: 66, size: 4},
 	{as: AMOVD, a1: C_REG, a6: C_ADDR, type_: 74, size: 8},
 	{as: AMOVD, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
+	{as: AMOVD, a1: C_REG, a6: C_XOREG, type_: 108, size: 4},
 	{as: AMOVD, a1: C_SPR, a6: C_SOREG, type_: 106, size: 8},
 	{as: AMOVD, a1: C_REG, a6: C_LOREG, type_: 35, size: 8},
 	{as: AMOVD, a1: C_REG, a6: C_SPR, type_: 66, size: 4},
@@ -256,28 +263,33 @@
 	{as: AMOVW, a1: C_CREG, a6: C_REG, type_: 68, size: 4},
 	{as: AMOVW, a1: C_SOREG, a6: C_REG, type_: 8, size: 4},
 	{as: AMOVW, a1: C_LOREG, a6: C_REG, type_: 36, size: 8},
+	{as: AMOVW, a1: C_XOREG, a6: C_REG, type_: 109, size: 4},
 	{as: AMOVW, a1: C_SPR, a6: C_REG, type_: 66, size: 4},
 	{as: AMOVW, a1: C_REG, a6: C_ADDR, type_: 74, size: 8},
 	{as: AMOVW, a1: C_REG, a6: C_CREG, type_: 69, size: 4},
 	{as: AMOVW, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
 	{as: AMOVW, a1: C_REG, a6: C_LOREG, type_: 35, size: 8},
+	{as: AMOVW, a1: C_REG, a6: C_XOREG, type_: 108, size: 4},
 	{as: AMOVW, a1: C_REG, a6: C_SPR, type_: 66, size: 4},
 	{as: AMOVW, a1: C_REG, a6: C_REG, type_: 13, size: 4},
 
 	{as: AFMOVD, a1: C_ADDCON, a6: C_FREG, type_: 24, size: 8},
 	{as: AFMOVD, a1: C_SOREG, a6: C_FREG, type_: 8, size: 4},
+	{as: AFMOVD, a1: C_XOREG, a6: C_FREG, type_: 109, size: 4},
 	{as: AFMOVD, a1: C_LOREG, a6: C_FREG, type_: 36, size: 8},
 	{as: AFMOVD, a1: C_ZCON, a6: C_FREG, type_: 24, size: 4},
 	{as: AFMOVD, a1: C_ADDR, a6: C_FREG, type_: 75, size: 8},
 	{as: AFMOVD, a1: C_FREG, a6: C_FREG, type_: 33, size: 4},
 	{as: AFMOVD, a1: C_FREG, a6: C_SOREG, type_: 7, size: 4},
+	{as: AFMOVD, a1: C_FREG, a6: C_XOREG, type_: 108, size: 4},
 	{as: AFMOVD, a1: C_FREG, a6: C_LOREG, type_: 35, size: 8},
 	{as: AFMOVD, a1: C_FREG, a6: C_ADDR, type_: 74, size: 8},
 
-	{as: AFMOVSX, a1: C_ZOREG, a6: C_FREG, type_: 45, size: 4},
-	{as: AFMOVSX, a1: C_FREG, a6: C_ZOREG, type_: 44, size: 4},
+	{as: AFMOVSX, a1: C_XOREG, a6: C_FREG, type_: 45, size: 4},
+	{as: AFMOVSX, a1: C_FREG, a6: C_XOREG, type_: 44, size: 4},
 
 	{as: AFMOVSZ, a1: C_ZOREG, a6: C_FREG, type_: 45, size: 4},
+	{as: AFMOVSZ, a1: C_XOREG, a6: C_FREG, type_: 45, size: 4},
 
 	{as: AMOVFL, a1: C_CREG, a6: C_CREG, type_: 67, size: 4},
 	{as: AMOVFL, a1: C_FPSCR, a6: C_CREG, type_: 73, size: 4},
@@ -330,7 +342,6 @@
 	{as: AFTSQRT, a1: C_FREG, a6: C_SCON, type_: 93, size: 4},                     /* floating test for sw square root, x-form */
 	{as: ACOPY, a1: C_REG, a6: C_REG, type_: 92, size: 4},                         /* copy/paste facility, x-form */
 	{as: ADARN, a1: C_SCON, a6: C_REG, type_: 92, size: 4},                        /* deliver random number, x-form */
-	{as: ALDMX, a1: C_SOREG, a6: C_REG, type_: 45, size: 4},                       /* load doubleword monitored, x-form */
 	{as: AMADDHD, a1: C_REG, a2: C_REG, a3: C_REG, a6: C_REG, type_: 83, size: 4}, /* multiply-add high/low doubleword, va-form */
 	{as: AADDEX, a1: C_REG, a2: C_REG, a3: C_SCON, a6: C_REG, type_: 94, size: 4}, /* add extended using alternate carry, z23-form */
 	{as: ACRAND, a1: C_CRBIT, a2: C_CRBIT, a6: C_CRBIT, type_: 2, size: 4},        /* logical ops for condition register bits xl-form */
@@ -338,10 +349,10 @@
 	/* Vector instructions */
 
 	/* Vector load */
-	{as: ALV, a1: C_SOREG, a6: C_VREG, type_: 45, size: 4}, /* vector load, x-form */
+	{as: ALVEBX, a1: C_XOREG, a6: C_VREG, type_: 45, size: 4}, /* vector load, x-form */
 
 	/* Vector store */
-	{as: ASTV, a1: C_VREG, a6: C_SOREG, type_: 44, size: 4}, /* vector store, x-form */
+	{as: ASTVEBX, a1: C_VREG, a6: C_XOREG, type_: 44, size: 4}, /* vector store, x-form */
 
 	/* Vector logical */
 	{as: AVAND, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector and, vx-form */
@@ -410,26 +421,26 @@
 	{as: AVSHASIGMA, a1: C_ANDCON, a2: C_VREG, a3: C_ANDCON, a6: C_VREG, type_: 82, size: 4}, /* vector SHA sigma, vx-form */
 
 	/* VSX vector load */
-	{as: ALXVD2X, a1: C_SOREG, a6: C_VSREG, type_: 87, size: 4},        /* vsx vector load, xx1-form */
+	{as: ALXVD2X, a1: C_XOREG, a6: C_VSREG, type_: 87, size: 4},        /* vsx vector load, xx1-form */
 	{as: ALXV, a1: C_SOREG, a6: C_VSREG, type_: 96, size: 4},           /* vsx vector load, dq-form */
 	{as: ALXVL, a1: C_REG, a2: C_REG, a6: C_VSREG, type_: 98, size: 4}, /* vsx vector load length */
 
 	/* VSX vector store */
-	{as: ASTXVD2X, a1: C_VSREG, a6: C_SOREG, type_: 86, size: 4},        /* vsx vector store, xx1-form */
+	{as: ASTXVD2X, a1: C_VSREG, a6: C_XOREG, type_: 86, size: 4},        /* vsx vector store, xx1-form */
 	{as: ASTXV, a1: C_VSREG, a6: C_SOREG, type_: 97, size: 4},           /* vsx vector store, dq-form */
 	{as: ASTXVL, a1: C_VSREG, a2: C_REG, a6: C_REG, type_: 99, size: 4}, /* vsx vector store with length x-form */
 
 	/* VSX scalar load */
-	{as: ALXSDX, a1: C_SOREG, a6: C_VSREG, type_: 87, size: 4}, /* vsx scalar load, xx1-form */
+	{as: ALXSDX, a1: C_XOREG, a6: C_VSREG, type_: 87, size: 4}, /* vsx scalar load, xx1-form */
 
 	/* VSX scalar store */
-	{as: ASTXSDX, a1: C_VSREG, a6: C_SOREG, type_: 86, size: 4}, /* vsx scalar store, xx1-form */
+	{as: ASTXSDX, a1: C_VSREG, a6: C_XOREG, type_: 86, size: 4}, /* vsx scalar store, xx1-form */
 
 	/* VSX scalar as integer load */
-	{as: ALXSIWAX, a1: C_SOREG, a6: C_VSREG, type_: 87, size: 4}, /* vsx scalar as integer load, xx1-form */
+	{as: ALXSIWAX, a1: C_XOREG, a6: C_VSREG, type_: 87, size: 4}, /* vsx scalar as integer load, xx1-form */
 
 	/* VSX scalar store as integer */
-	{as: ASTXSIWX, a1: C_VSREG, a6: C_SOREG, type_: 86, size: 4}, /* vsx scalar as integer store, xx1-form */
+	{as: ASTXSIWX, a1: C_VSREG, a6: C_XOREG, type_: 86, size: 4}, /* vsx scalar as integer store, xx1-form */
 
 	/* VSX move from VSR */
 	{as: AMFVSRD, a1: C_VSREG, a6: C_REG, type_: 88, size: 4},
@@ -493,28 +504,25 @@
 	{as: AFCMPO, a1: C_FREG, a2: C_CREG, a6: C_FREG, type_: 70, size: 4},
 	{as: ATW, a1: C_LCON, a2: C_REG, a6: C_REG, type_: 60, size: 4},
 	{as: ATW, a1: C_LCON, a2: C_REG, a6: C_ADDCON, type_: 61, size: 4},
-	{as: ADCBF, a1: C_ZOREG, type_: 43, size: 4},
 	{as: ADCBF, a1: C_SOREG, type_: 43, size: 4},
-	{as: ADCBF, a1: C_ZOREG, a2: C_REG, a6: C_SCON, type_: 43, size: 4},
+	{as: ADCBF, a1: C_XOREG, type_: 43, size: 4},
+	{as: ADCBF, a1: C_XOREG, a2: C_REG, a6: C_SCON, type_: 43, size: 4},
 	{as: ADCBF, a1: C_SOREG, a6: C_SCON, type_: 43, size: 4},
-	{as: AECOWX, a1: C_REG, a2: C_REG, a6: C_ZOREG, type_: 44, size: 4},
-	{as: AECIWX, a1: C_ZOREG, a2: C_REG, a6: C_REG, type_: 45, size: 4},
-	{as: AECOWX, a1: C_REG, a6: C_ZOREG, type_: 44, size: 4},
-	{as: AECIWX, a1: C_ZOREG, a6: C_REG, type_: 45, size: 4},
-	{as: ALDAR, a1: C_ZOREG, a6: C_REG, type_: 45, size: 4},
-	{as: ALDAR, a1: C_ZOREG, a3: C_ANDCON, a6: C_REG, type_: 45, size: 4},
+	{as: ADCBF, a1: C_XOREG, a6: C_SCON, type_: 43, size: 4},
+	{as: ASTDCCC, a1: C_REG, a2: C_REG, a6: C_XOREG, type_: 44, size: 4},
+	{as: ASTDCCC, a1: C_REG, a6: C_XOREG, type_: 44, size: 4},
+	{as: ALDAR, a1: C_XOREG, a6: C_REG, type_: 45, size: 4},
+	{as: ALDAR, a1: C_XOREG, a3: C_ANDCON, a6: C_REG, type_: 45, size: 4},
 	{as: AEIEIO, type_: 46, size: 4},
 	{as: ATLBIE, a1: C_REG, type_: 49, size: 4},
 	{as: ATLBIE, a1: C_SCON, a6: C_REG, type_: 49, size: 4},
 	{as: ASLBMFEE, a1: C_REG, a6: C_REG, type_: 55, size: 4},
 	{as: ASLBMTE, a1: C_REG, a6: C_REG, type_: 55, size: 4},
-	{as: ASTSW, a1: C_REG, a6: C_ZOREG, type_: 44, size: 4},
+	{as: ASTSW, a1: C_REG, a6: C_XOREG, type_: 44, size: 4},
 	{as: ASTSW, a1: C_REG, a3: C_LCON, a6: C_ZOREG, type_: 41, size: 4},
-	{as: ALSW, a1: C_ZOREG, a6: C_REG, type_: 45, size: 4},
+	{as: ALSW, a1: C_XOREG, a6: C_REG, type_: 45, size: 4},
 	{as: ALSW, a1: C_ZOREG, a3: C_LCON, a6: C_REG, type_: 42, size: 4},
 
-	{as: APNOP, type_: 105, size: 8, ispfx: true},
-
 	{as: obj.AUNDEF, type_: 78, size: 4},
 	{as: obj.APCDATA, a1: C_LCON, a6: C_LCON, type_: 0, size: 0},
 	{as: obj.AFUNCDATA, a1: C_SCON, a6: C_ADDR, type_: 0, size: 0},
@@ -525,15 +533,13 @@
 	{as: obj.ADUFFZERO, a6: C_LBRA, type_: 11, size: 4}, // same as ABR/ABL
 	{as: obj.ADUFFCOPY, a6: C_LBRA, type_: 11, size: 4}, // same as ABR/ABL
 	{as: obj.APCALIGN, a1: C_LCON, type_: 0, size: 0},   // align code
-
-	{as: obj.AXXX, type_: 0, size: 4},
 }
 
 var oprange [ALAST & obj.AMask][]Optab
 
 var xcmp [C_NCLASS][C_NCLASS]bool
 
-// padding bytes to add to align code as requested
+// padding bytes to add to align code as requested.
 func addpad(pc, a int64, ctxt *obj.Link, cursym *obj.LSym) int {
 	// For 16 and 32 byte alignment, there is a tradeoff
 	// between aligning the code and adding too many NOPs.
@@ -588,7 +594,7 @@
 	switch class {
 	case C_SACON, C_LACON:
 		return REGSP
-	case C_LOREG, C_SOREG, C_ZOREG:
+	case C_LOREG, C_SOREG, C_ZOREG, C_XOREG:
 		switch a.Name {
 		case obj.NAME_EXTERN, obj.NAME_STATIC:
 			return REGSB
@@ -649,7 +655,7 @@
 
 	var otxt int64
 	var q *obj.Prog
-	var out [6]uint32
+	var out [5]uint32
 	var falign int32 // Track increased alignment requirements for prefix.
 	for bflag != 0 {
 		bflag = 0
@@ -668,7 +674,7 @@
 					// and only one extra branch is needed to reach the target.
 					tgt := p.To.Target()
 					p.To.SetTarget(p.Link)
-					c.asmout(p, o, out[:])
+					o.asmout(&c, p, o, &out)
 					p.To.SetTarget(tgt)
 
 					bo := int64(out[0]>>21) & 31
@@ -821,7 +827,7 @@
 				c.ctxt.Arch.ByteOrder.PutUint32(bp, nop)
 				bp = bp[4:]
 			}
-			c.asmout(p, o, out[:])
+			o.asmout(&c, p, o, &out)
 			for i = 0; i < int32(o.size/4); i++ {
 				c.ctxt.Arch.ByteOrder.PutUint32(bp, out[i])
 				bp = bp[4:]
@@ -871,6 +877,9 @@
 
 		return C_SPR
 	}
+	if REG_A0 <= reg && reg <= REG_A7 {
+		return C_AREG
+	}
 	if reg == REG_FPSCR {
 		return C_FPSCR
 	}
@@ -886,6 +895,13 @@
 		return c.aclassreg(a.Reg)
 
 	case obj.TYPE_MEM:
+		if a.Index != 0 {
+			if a.Name != obj.NAME_NONE || a.Offset != 0 {
+				c.ctxt.Logf("Unexpected Instruction operand index %d offset %d class %d \n", a.Index, a.Offset, a.Class)
+
+			}
+			return C_XOREG
+		}
 		switch a.Name {
 		case obj.NAME_GOTREF, obj.NAME_TOCREF:
 			return C_ADDR
@@ -908,6 +924,7 @@
 
 		case obj.NAME_AUTO:
 			c.instoffset = int64(c.autosize) + a.Offset
+
 			if c.instoffset >= -BIG && c.instoffset < BIG {
 				return C_SOREG
 			}
@@ -922,13 +939,13 @@
 
 		case obj.NAME_NONE:
 			c.instoffset = a.Offset
-			if c.instoffset == 0 {
+			if a.Offset == 0 && a.Index == 0 {
 				return C_ZOREG
-			}
-			if c.instoffset >= -BIG && c.instoffset < BIG {
+			} else if c.instoffset >= -BIG && c.instoffset < BIG {
 				return C_SOREG
+			} else {
+				return C_LOREG
 			}
-			return C_LOREG
 		}
 
 		return C_GOK
@@ -1165,6 +1182,9 @@
 	case C_LOREG:
 		return cmp(C_SOREG, b)
 
+	case C_XOREG:
+		return cmp(C_REG, b) || cmp(C_ZOREG, b)
+
 	// An even/odd register input always matches the regular register types.
 	case C_REG:
 		return cmp(C_REGP, b) || (b == C_ZCON && r0iszero != 0)
@@ -1181,22 +1201,12 @@
 	return false
 }
 
-type ocmp []Optab
-
-func (x ocmp) Len() int {
-	return len(x)
-}
-
-func (x ocmp) Swap(i, j int) {
-	x[i], x[j] = x[j], x[i]
-}
-
 // Used when sorting the optab. Sorting is
 // done in a way so that the best choice of
 // opcode/operand combination is considered first.
-func (x ocmp) Less(i, j int) bool {
-	p1 := &x[i]
-	p2 := &x[j]
+func optabLess(i, j int) bool {
+	p1 := &optab[i]
+	p2 := &optab[j]
 	n := int(p1.as) - int(p2.as)
 	// same opcode
 	if n != 0 {
@@ -1253,32 +1263,37 @@
 		return
 	}
 
-	var n int
-
 	for i := 0; i < C_NCLASS; i++ {
-		for n = 0; n < C_NCLASS; n++ {
+		for n := 0; n < C_NCLASS; n++ {
 			if cmp(n, i) {
 				xcmp[i][n] = true
 			}
 		}
 	}
-	for n = 0; optab[n].as != obj.AXXX; n++ {
+	for i := range optab {
+		// Use the legacy assembler function if none provided.
+		if optab[i].asmout == nil {
+			optab[i].asmout = asmout
+		}
 	}
-	sort.Sort(ocmp(optab[:n]))
-	for i := 0; i < n; i++ {
+	// Append the generated entries, sort, and fill out oprange.
+	optab = append(optab, optabGen...)
+	sort.Slice(optab, optabLess)
+	for i := 0; i < len(optab); {
 		r := optab[i].as
 		r0 := r & obj.AMask
 		start := i
-		for optab[i].as == r {
+		for i < len(optab) && optab[i].as == r {
 			i++
 		}
 		oprange[r0] = optab[start:i]
-		i--
 
 		switch r {
 		default:
-			ctxt.Diag("unknown op in build: %v", r)
-			log.Fatalf("instruction missing from switch in asm9.go:buildop: %v", r)
+			if !opsetGen(r) {
+				ctxt.Diag("unknown op in build: %v", r)
+				log.Fatalf("instruction missing from switch in asm9.go:buildop: %v", r)
+			}
 
 		case ADCBF: /* unary indexed: op (b+a); op (b) */
 			opset(ADCBI, r0)
@@ -1289,11 +1304,10 @@
 			opset(ADCBZ, r0)
 			opset(AICBI, r0)
 
-		case AECOWX: /* indexed store: op s,(b+a); op s,(b) */
+		case ASTDCCC: /* indexed store: op s,(b+a); op s,(b) */
 			opset(ASTWCCC, r0)
 			opset(ASTHCCC, r0)
 			opset(ASTBCCC, r0)
-			opset(ASTDCCC, r0)
 
 		case AREM: /* macro */
 			opset(AREM, r0)
@@ -1393,8 +1407,7 @@
 			opset(AMOVDU, r0)
 			opset(AMOVMW, r0)
 
-		case ALV: /* lvebx, lvehx, lvewx, lvx, lvxl, lvsl, lvsr */
-			opset(ALVEBX, r0)
+		case ALVEBX: /* lvebx, lvehx, lvewx, lvx, lvxl, lvsl, lvsr */
 			opset(ALVEHX, r0)
 			opset(ALVEWX, r0)
 			opset(ALVX, r0)
@@ -1402,8 +1415,7 @@
 			opset(ALVSL, r0)
 			opset(ALVSR, r0)
 
-		case ASTV: /* stvebx, stvehx, stvewx, stvx, stvxl */
-			opset(ASTVEBX, r0)
+		case ASTVEBX: /* stvebx, stvehx, stvewx, stvx, stvxl */
 			opset(ASTVEHX, r0)
 			opset(ASTVEWX, r0)
 			opset(ASTVX, r0)
@@ -2028,11 +2040,9 @@
 			AWORD,
 			ADWORD,
 			ADARN,
-			ALDMX,
 			AVMSUMUDM,
 			AADDEX,
 			ACMPEQB,
-			AECIWX,
 			ACLRLSLWI,
 			AMTVSRDD,
 			APNOP,
@@ -2095,7 +2105,7 @@
 	return o<<26 | xo<<2 | rc&1
 }
 
-/* the order is dest, a/s, b/imm for both arithmetic and logical operations */
+/* the order is dest, a/s, b/imm for both arithmetic and logical operations. */
 func AOP_RRR(op uint32, d uint32, a uint32, b uint32) uint32 {
 	return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11
 }
@@ -2455,7 +2465,7 @@
 	return uint16(d >> 16)
 }
 
-func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) {
+func asmout(c *ctxt9, p *obj.Prog, o *Optab, out *[5]uint32) {
 	o1 := uint32(0)
 	o2 := uint32(0)
 	o3 := uint32(0)
@@ -2567,22 +2577,15 @@
 			r = c.getimpliedreg(&p.To, p)
 		}
 		v := c.regoff(&p.To)
-		if p.To.Type == obj.TYPE_MEM && p.To.Index != 0 {
-			if v != 0 {
-				c.ctxt.Diag("illegal indexed instruction\n%v", p)
-			}
-			o1 = AOP_RRR(c.opstorex(p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(r))
-		} else {
-			if int32(int16(v)) != v {
-				log.Fatalf("mishandled instruction %v", p)
-			}
-			// Offsets in DS form stores must be a multiple of 4
-			inst := c.opstore(p.As)
-			if c.opform(inst) == DS_FORM && v&0x3 != 0 {
-				log.Fatalf("invalid offset for DS form load/store %v", p)
-			}
-			o1 = AOP_IRR(inst, uint32(p.From.Reg), uint32(r), uint32(v))
+		if int32(int16(v)) != v {
+			log.Fatalf("mishandled instruction %v", p)
 		}
+		// Offsets in DS form stores must be a multiple of 4
+		inst := c.opstore(p.As)
+		if c.opform(inst) == DS_FORM && v&0x3 != 0 {
+			log.Fatalf("invalid offset for DS form load/store %v", p)
+		}
+		o1 = AOP_IRR(inst, uint32(p.From.Reg), uint32(r), uint32(v))
 
 	case 8: /* mov soreg, r ==> lbz/lhz/lwz o(r), lbz o(r) + extsb r,r */
 		r := int(p.From.Reg)
@@ -2591,22 +2594,15 @@
 			r = c.getimpliedreg(&p.From, p)
 		}
 		v := c.regoff(&p.From)
-		if p.From.Type == obj.TYPE_MEM && p.From.Index != 0 {
-			if v != 0 {
-				c.ctxt.Diag("illegal indexed instruction\n%v", p)
-			}
-			o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(r))
-		} else {
-			if int32(int16(v)) != v {
-				log.Fatalf("mishandled instruction %v", p)
-			}
-			// Offsets in DS form loads must be a multiple of 4
-			inst := c.opload(p.As)
-			if c.opform(inst) == DS_FORM && v&0x3 != 0 {
-				log.Fatalf("invalid offset for DS form load/store %v", p)
-			}
-			o1 = AOP_IRR(inst, uint32(p.To.Reg), uint32(r), uint32(v))
+		if int32(int16(v)) != v {
+			log.Fatalf("mishandled instruction %v", p)
 		}
+		// Offsets in DS form loads must be a multiple of 4
+		inst := c.opload(p.As)
+		if c.opform(inst) == DS_FORM && v&0x3 != 0 {
+			log.Fatalf("invalid offset for DS form load/store %v", p)
+		}
+		o1 = AOP_IRR(inst, uint32(p.To.Reg), uint32(r), uint32(v))
 
 		// Sign extend MOVB operations. This is ignored for other cases (o.size == 4).
 		o2 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
@@ -2945,7 +2941,7 @@
 		case AROTL:
 			a = int(0)
 			op = OP_RLDICL
-		case AEXTSWSLI:
+		case AEXTSWSLI, AEXTSWSLICC:
 			a = int(v)
 		default:
 			c.ctxt.Diag("unexpected op in sldi case\n%v", p)
@@ -3146,9 +3142,16 @@
 		o1 = uint32(c.regoff(&p.From))
 
 	case 41: /* stswi */
+		if p.To.Type == obj.TYPE_MEM && p.To.Index == 0 && p.To.Offset != 0 {
+			c.ctxt.Diag("Invalid addressing mode used in index type instruction: %v", p.As)
+		}
+
 		o1 = AOP_RRR(c.opirr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), 0) | (uint32(c.regoff(p.GetFrom3()))&0x7F)<<11
 
 	case 42: /* lswi */
+		if p.From.Type == obj.TYPE_MEM && p.From.Index == 0 && p.From.Offset != 0 {
+			c.ctxt.Diag("Invalid addressing mode used in index type instruction: %v", p.As)
+		}
 		o1 = AOP_RRR(c.opirr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), 0) | (uint32(c.regoff(p.GetFrom3()))&0x7F)<<11
 
 	case 43: /* data cache instructions: op (Ra+[Rb]), [th|l] */
@@ -3750,10 +3753,6 @@
 	case 104: /* VSX mtvsr* instructions, XX1-form RA,RB,XT */
 		o1 = AOP_XX1(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg))
 
-	case 105: /* PNOP */
-		o1 = 0x07000000
-		o2 = 0x00000000
-
 	case 106: /* MOVD spr, soreg */
 		v := int32(p.From.Reg)
 		o1 = OPVCC(31, 339, 0, 0) /* mfspr */
@@ -3777,6 +3776,17 @@
 		if so&0x3 != 0 {
 			log.Fatalf("invalid offset for DS form load/store %v", p)
 		}
+
+	case 108: /* mov r, xoreg ==> stwx rx,ry */
+		r := int(p.To.Reg)
+		o1 = AOP_RRR(c.opstorex(p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(r))
+
+	case 109: /* mov xoreg, r ==> lbzx/lhzx/lwzx rx,ry, lbzx rx,ry + extsb r,r */
+		r := int(p.From.Reg)
+
+		o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(r))
+		// Sign extend MOVB operations. This is ignored for other cases (o.size == 4).
+		o2 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
 	}
 
 	out[0] = o1
@@ -5124,8 +5134,6 @@
 		return OPVCC(31, 279, 0, 0) /* lhzx */
 	case AMOVHZU:
 		return OPVCC(31, 311, 0, 0) /* lhzux */
-	case AECIWX:
-		return OPVCC(31, 310, 0, 0) /* eciwx */
 	case ALBAR:
 		return OPVCC(31, 52, 0, 0) /* lbarx */
 	case ALHAR:
@@ -5140,8 +5148,6 @@
 		return OPVCC(31, 21, 0, 0) /* ldx */
 	case AMOVDU:
 		return OPVCC(31, 53, 0, 0) /* ldux */
-	case ALDMX:
-		return OPVCC(31, 309, 0, 0) /* ldmx */
 
 	/* Vector (VMX/Altivec) instructions */
 	case ALVEBX:
@@ -5286,8 +5292,6 @@
 		return OPVCC(31, 150, 0, 1) /* stwcx. */
 	case ASTDCCC:
 		return OPVCC(31, 214, 0, 1) /* stwdx. */
-	case AECOWX:
-		return OPVCC(31, 438, 0, 0) /* ecowx */
 	case AMOVD:
 		return OPVCC(31, 149, 0, 0) /* stdx */
 	case AMOVDU:
diff --git a/src/cmd/internal/obj/ppc64/asm9_gtables.go b/src/cmd/internal/obj/ppc64/asm9_gtables.go
new file mode 100644
index 0000000..953b148
--- /dev/null
+++ b/src/cmd/internal/obj/ppc64/asm9_gtables.go
@@ -0,0 +1,1660 @@
+// DO NOT EDIT
+// generated by: ppc64map -fmt=encoder pp64.csv
+
+package ppc64
+
+import (
+	"cmd/internal/obj"
+)
+
+const (
+	AXXSETACCZ = ALASTAOUT + iota
+	AXXMTACC
+	AXXMFACC
+	AXXGENPCVWM
+	AXXGENPCVHM
+	AXXGENPCVDM
+	AXXGENPCVBM
+	AXVTLSBB
+	AXVI8GER4SPP
+	AXVI8GER4PP
+	AXVI8GER4
+	AXVI4GER8PP
+	AXVI4GER8
+	AXVI16GER2SPP
+	AXVI16GER2S
+	AXVI16GER2PP
+	AXVI16GER2
+	AXVF64GERPP
+	AXVF64GERPN
+	AXVF64GERNP
+	AXVF64GERNN
+	AXVF64GER
+	AXVF32GERPP
+	AXVF32GERPN
+	AXVF32GERNP
+	AXVF32GERNN
+	AXVF32GER
+	AXVF16GER2PP
+	AXVF16GER2PN
+	AXVF16GER2NP
+	AXVF16GER2NN
+	AXVF16GER2
+	AXVCVSPBF16
+	AXVCVBF16SPN
+	AXVBF16GER2PP
+	AXVBF16GER2PN
+	AXVBF16GER2NP
+	AXVBF16GER2NN
+	AXVBF16GER2
+	AXSMINCQP
+	AXSMAXCQP
+	AXSCVUQQP
+	AXSCVSQQP
+	AXSCVQPUQZ
+	AXSCVQPSQZ
+	AXSCMPGTQP
+	AXSCMPGEQP
+	AXSCMPEQQP
+	AVSTRIHRCC
+	AVSTRIHR
+	AVSTRIHLCC
+	AVSTRIHL
+	AVSTRIBRCC
+	AVSTRIBR
+	AVSTRIBLCC
+	AVSTRIBL
+	AVSRQ
+	AVSRDBI
+	AVSRAQ
+	AVSLQ
+	AVSLDBI
+	AVRLQNM
+	AVRLQMI
+	AVRLQ
+	AVPEXTD
+	AVPDEPD
+	AVMULOUD
+	AVMULOSD
+	AVMULLD
+	AVMULHUW
+	AVMULHUD
+	AVMULHSW
+	AVMULHSD
+	AVMULEUD
+	AVMULESD
+	AVMSUMCUD
+	AVMODUW
+	AVMODUQ
+	AVMODUD
+	AVMODSW
+	AVMODSQ
+	AVMODSD
+	AVINSWVRX
+	AVINSWVLX
+	AVINSWRX
+	AVINSWLX
+	AVINSW
+	AVINSHVRX
+	AVINSHVLX
+	AVINSHRX
+	AVINSHLX
+	AVINSDRX
+	AVINSDLX
+	AVINSD
+	AVINSBVRX
+	AVINSBVLX
+	AVINSBRX
+	AVINSBLX
+	AVGNB
+	AVEXTSD2Q
+	AVEXTRACTWM
+	AVEXTRACTQM
+	AVEXTRACTHM
+	AVEXTRACTDM
+	AVEXTRACTBM
+	AVEXTDUWVRX
+	AVEXTDUWVLX
+	AVEXTDUHVRX
+	AVEXTDUHVLX
+	AVEXTDUBVRX
+	AVEXTDUBVLX
+	AVEXTDDVRX
+	AVEXTDDVLX
+	AVEXPANDWM
+	AVEXPANDQM
+	AVEXPANDHM
+	AVEXPANDDM
+	AVEXPANDBM
+	AVDIVUW
+	AVDIVUQ
+	AVDIVUD
+	AVDIVSW
+	AVDIVSQ
+	AVDIVSD
+	AVDIVEUW
+	AVDIVEUQ
+	AVDIVEUD
+	AVDIVESW
+	AVDIVESQ
+	AVDIVESD
+	AVCTZDM
+	AVCNTMBW
+	AVCNTMBH
+	AVCNTMBD
+	AVCNTMBB
+	AVCMPUQ
+	AVCMPSQ
+	AVCMPGTUQCC
+	AVCMPGTUQ
+	AVCMPGTSQCC
+	AVCMPGTSQ
+	AVCMPEQUQCC
+	AVCMPEQUQ
+	AVCLZDM
+	AVCLRRB
+	AVCLRLB
+	AVCFUGED
+	ASTXVRWX
+	ASTXVRHX
+	ASTXVRDX
+	ASTXVRBX
+	ASTXVPX
+	ASTXVP
+	ASETNBCR
+	ASETNBC
+	ASETBCR
+	ASETBC
+	APEXTD
+	APDEPD
+	AMTVSRWM
+	AMTVSRQM
+	AMTVSRHM
+	AMTVSRDM
+	AMTVSRBMI
+	AMTVSRBM
+	ALXVRWX
+	ALXVRHX
+	ALXVRDX
+	ALXVRBX
+	ALXVPX
+	ALXVP
+	ALXVKQ
+	ADCTFIXQQ
+	ADCFFIXQQ
+	ACNTTZDM
+	ACNTLZDM
+	ACFUGED
+	ABRW
+	ABRH
+	ABRD
+	AHASHSTP
+	AHASHST
+	AHASHCHKP
+	AHASHCHK
+	AXXSPLTIW
+	AXXSPLTIDP
+	AXXSPLTI32DX
+	AXXPERMX
+	AXXEVAL
+	AXXBLENDVW
+	AXXBLENDVH
+	AXXBLENDVD
+	AXXBLENDVB
+	APSTXVP
+	APSTXV
+	APSTXSSP
+	APSTXSD
+	APSTW
+	APSTQ
+	APSTH
+	APSTFS
+	APSTFD
+	APSTD
+	APSTB
+	APNOP
+	APMXVI8GER4SPP
+	APMXVI8GER4PP
+	APMXVI8GER4
+	APMXVI4GER8PP
+	APMXVI4GER8
+	APMXVI16GER2SPP
+	APMXVI16GER2S
+	APMXVI16GER2PP
+	APMXVI16GER2
+	APMXVF64GERPP
+	APMXVF64GERPN
+	APMXVF64GERNP
+	APMXVF64GERNN
+	APMXVF64GER
+	APMXVF32GERPP
+	APMXVF32GERPN
+	APMXVF32GERNP
+	APMXVF32GERNN
+	APMXVF32GER
+	APMXVF16GER2PP
+	APMXVF16GER2PN
+	APMXVF16GER2NP
+	APMXVF16GER2NN
+	APMXVF16GER2
+	APMXVBF16GER2PP
+	APMXVBF16GER2PN
+	APMXVBF16GER2NP
+	APMXVBF16GER2NN
+	APMXVBF16GER2
+	APLXVP
+	APLXV
+	APLXSSP
+	APLXSD
+	APLWZ
+	APLWA
+	APLQ
+	APLHZ
+	APLHA
+	APLFS
+	APLFD
+	APLD
+	APLBZ
+	APADDI
+	ALASTGEN
+	AFIRSTGEN = AXXSETACCZ
+)
+
+var GenAnames = []string{
+	"XXSETACCZ",
+	"XXMTACC",
+	"XXMFACC",
+	"XXGENPCVWM",
+	"XXGENPCVHM",
+	"XXGENPCVDM",
+	"XXGENPCVBM",
+	"XVTLSBB",
+	"XVI8GER4SPP",
+	"XVI8GER4PP",
+	"XVI8GER4",
+	"XVI4GER8PP",
+	"XVI4GER8",
+	"XVI16GER2SPP",
+	"XVI16GER2S",
+	"XVI16GER2PP",
+	"XVI16GER2",
+	"XVF64GERPP",
+	"XVF64GERPN",
+	"XVF64GERNP",
+	"XVF64GERNN",
+	"XVF64GER",
+	"XVF32GERPP",
+	"XVF32GERPN",
+	"XVF32GERNP",
+	"XVF32GERNN",
+	"XVF32GER",
+	"XVF16GER2PP",
+	"XVF16GER2PN",
+	"XVF16GER2NP",
+	"XVF16GER2NN",
+	"XVF16GER2",
+	"XVCVSPBF16",
+	"XVCVBF16SPN",
+	"XVBF16GER2PP",
+	"XVBF16GER2PN",
+	"XVBF16GER2NP",
+	"XVBF16GER2NN",
+	"XVBF16GER2",
+	"XSMINCQP",
+	"XSMAXCQP",
+	"XSCVUQQP",
+	"XSCVSQQP",
+	"XSCVQPUQZ",
+	"XSCVQPSQZ",
+	"XSCMPGTQP",
+	"XSCMPGEQP",
+	"XSCMPEQQP",
+	"VSTRIHRCC",
+	"VSTRIHR",
+	"VSTRIHLCC",
+	"VSTRIHL",
+	"VSTRIBRCC",
+	"VSTRIBR",
+	"VSTRIBLCC",
+	"VSTRIBL",
+	"VSRQ",
+	"VSRDBI",
+	"VSRAQ",
+	"VSLQ",
+	"VSLDBI",
+	"VRLQNM",
+	"VRLQMI",
+	"VRLQ",
+	"VPEXTD",
+	"VPDEPD",
+	"VMULOUD",
+	"VMULOSD",
+	"VMULLD",
+	"VMULHUW",
+	"VMULHUD",
+	"VMULHSW",
+	"VMULHSD",
+	"VMULEUD",
+	"VMULESD",
+	"VMSUMCUD",
+	"VMODUW",
+	"VMODUQ",
+	"VMODUD",
+	"VMODSW",
+	"VMODSQ",
+	"VMODSD",
+	"VINSWVRX",
+	"VINSWVLX",
+	"VINSWRX",
+	"VINSWLX",
+	"VINSW",
+	"VINSHVRX",
+	"VINSHVLX",
+	"VINSHRX",
+	"VINSHLX",
+	"VINSDRX",
+	"VINSDLX",
+	"VINSD",
+	"VINSBVRX",
+	"VINSBVLX",
+	"VINSBRX",
+	"VINSBLX",
+	"VGNB",
+	"VEXTSD2Q",
+	"VEXTRACTWM",
+	"VEXTRACTQM",
+	"VEXTRACTHM",
+	"VEXTRACTDM",
+	"VEXTRACTBM",
+	"VEXTDUWVRX",
+	"VEXTDUWVLX",
+	"VEXTDUHVRX",
+	"VEXTDUHVLX",
+	"VEXTDUBVRX",
+	"VEXTDUBVLX",
+	"VEXTDDVRX",
+	"VEXTDDVLX",
+	"VEXPANDWM",
+	"VEXPANDQM",
+	"VEXPANDHM",
+	"VEXPANDDM",
+	"VEXPANDBM",
+	"VDIVUW",
+	"VDIVUQ",
+	"VDIVUD",
+	"VDIVSW",
+	"VDIVSQ",
+	"VDIVSD",
+	"VDIVEUW",
+	"VDIVEUQ",
+	"VDIVEUD",
+	"VDIVESW",
+	"VDIVESQ",
+	"VDIVESD",
+	"VCTZDM",
+	"VCNTMBW",
+	"VCNTMBH",
+	"VCNTMBD",
+	"VCNTMBB",
+	"VCMPUQ",
+	"VCMPSQ",
+	"VCMPGTUQCC",
+	"VCMPGTUQ",
+	"VCMPGTSQCC",
+	"VCMPGTSQ",
+	"VCMPEQUQCC",
+	"VCMPEQUQ",
+	"VCLZDM",
+	"VCLRRB",
+	"VCLRLB",
+	"VCFUGED",
+	"STXVRWX",
+	"STXVRHX",
+	"STXVRDX",
+	"STXVRBX",
+	"STXVPX",
+	"STXVP",
+	"SETNBCR",
+	"SETNBC",
+	"SETBCR",
+	"SETBC",
+	"PEXTD",
+	"PDEPD",
+	"MTVSRWM",
+	"MTVSRQM",
+	"MTVSRHM",
+	"MTVSRDM",
+	"MTVSRBMI",
+	"MTVSRBM",
+	"LXVRWX",
+	"LXVRHX",
+	"LXVRDX",
+	"LXVRBX",
+	"LXVPX",
+	"LXVP",
+	"LXVKQ",
+	"DCTFIXQQ",
+	"DCFFIXQQ",
+	"CNTTZDM",
+	"CNTLZDM",
+	"CFUGED",
+	"BRW",
+	"BRH",
+	"BRD",
+	"HASHSTP",
+	"HASHST",
+	"HASHCHKP",
+	"HASHCHK",
+	"XXSPLTIW",
+	"XXSPLTIDP",
+	"XXSPLTI32DX",
+	"XXPERMX",
+	"XXEVAL",
+	"XXBLENDVW",
+	"XXBLENDVH",
+	"XXBLENDVD",
+	"XXBLENDVB",
+	"PSTXVP",
+	"PSTXV",
+	"PSTXSSP",
+	"PSTXSD",
+	"PSTW",
+	"PSTQ",
+	"PSTH",
+	"PSTFS",
+	"PSTFD",
+	"PSTD",
+	"PSTB",
+	"PNOP",
+	"PMXVI8GER4SPP",
+	"PMXVI8GER4PP",
+	"PMXVI8GER4",
+	"PMXVI4GER8PP",
+	"PMXVI4GER8",
+	"PMXVI16GER2SPP",
+	"PMXVI16GER2S",
+	"PMXVI16GER2PP",
+	"PMXVI16GER2",
+	"PMXVF64GERPP",
+	"PMXVF64GERPN",
+	"PMXVF64GERNP",
+	"PMXVF64GERNN",
+	"PMXVF64GER",
+	"PMXVF32GERPP",
+	"PMXVF32GERPN",
+	"PMXVF32GERNP",
+	"PMXVF32GERNN",
+	"PMXVF32GER",
+	"PMXVF16GER2PP",
+	"PMXVF16GER2PN",
+	"PMXVF16GER2NP",
+	"PMXVF16GER2NN",
+	"PMXVF16GER2",
+	"PMXVBF16GER2PP",
+	"PMXVBF16GER2PN",
+	"PMXVBF16GER2NP",
+	"PMXVBF16GER2NN",
+	"PMXVBF16GER2",
+	"PLXVP",
+	"PLXV",
+	"PLXSSP",
+	"PLXSD",
+	"PLWZ",
+	"PLWA",
+	"PLQ",
+	"PLHZ",
+	"PLHA",
+	"PLFS",
+	"PLFD",
+	"PLD",
+	"PLBZ",
+	"PADDI",
+}
+
+var GenOpcodes = [...]uint32{
+	0x7c030162, // AXXSETACCZ
+	0x7c010162, // AXXMTACC
+	0x7c000162, // AXXMFACC
+	0xf0000768, // AXXGENPCVWM
+	0xf000072a, // AXXGENPCVHM
+	0xf000076a, // AXXGENPCVDM
+	0xf0000728, // AXXGENPCVBM
+	0xf002076c, // AXVTLSBB
+	0xec000318, // AXVI8GER4SPP
+	0xec000010, // AXVI8GER4PP
+	0xec000018, // AXVI8GER4
+	0xec000110, // AXVI4GER8PP
+	0xec000118, // AXVI4GER8
+	0xec000150, // AXVI16GER2SPP
+	0xec000158, // AXVI16GER2S
+	0xec000358, // AXVI16GER2PP
+	0xec000258, // AXVI16GER2
+	0xec0001d0, // AXVF64GERPP
+	0xec0005d0, // AXVF64GERPN
+	0xec0003d0, // AXVF64GERNP
+	0xec0007d0, // AXVF64GERNN
+	0xec0001d8, // AXVF64GER
+	0xec0000d0, // AXVF32GERPP
+	0xec0004d0, // AXVF32GERPN
+	0xec0002d0, // AXVF32GERNP
+	0xec0006d0, // AXVF32GERNN
+	0xec0000d8, // AXVF32GER
+	0xec000090, // AXVF16GER2PP
+	0xec000490, // AXVF16GER2PN
+	0xec000290, // AXVF16GER2NP
+	0xec000690, // AXVF16GER2NN
+	0xec000098, // AXVF16GER2
+	0xf011076c, // AXVCVSPBF16
+	0xf010076c, // AXVCVBF16SPN
+	0xec000190, // AXVBF16GER2PP
+	0xec000590, // AXVBF16GER2PN
+	0xec000390, // AXVBF16GER2NP
+	0xec000790, // AXVBF16GER2NN
+	0xec000198, // AXVBF16GER2
+	0xfc0005c8, // AXSMINCQP
+	0xfc000548, // AXSMAXCQP
+	0xfc030688, // AXSCVUQQP
+	0xfc0b0688, // AXSCVSQQP
+	0xfc000688, // AXSCVQPUQZ
+	0xfc080688, // AXSCVQPSQZ
+	0xfc0001c8, // AXSCMPGTQP
+	0xfc000188, // AXSCMPGEQP
+	0xfc000088, // AXSCMPEQQP
+	0x1003040d, // AVSTRIHRCC
+	0x1003000d, // AVSTRIHR
+	0x1002040d, // AVSTRIHLCC
+	0x1002000d, // AVSTRIHL
+	0x1001040d, // AVSTRIBRCC
+	0x1001000d, // AVSTRIBR
+	0x1000040d, // AVSTRIBLCC
+	0x1000000d, // AVSTRIBL
+	0x10000205, // AVSRQ
+	0x10000216, // AVSRDBI
+	0x10000305, // AVSRAQ
+	0x10000105, // AVSLQ
+	0x10000016, // AVSLDBI
+	0x10000145, // AVRLQNM
+	0x10000045, // AVRLQMI
+	0x10000005, // AVRLQ
+	0x1000058d, // AVPEXTD
+	0x100005cd, // AVPDEPD
+	0x100000c8, // AVMULOUD
+	0x100001c8, // AVMULOSD
+	0x100001c9, // AVMULLD
+	0x10000289, // AVMULHUW
+	0x100002c9, // AVMULHUD
+	0x10000389, // AVMULHSW
+	0x100003c9, // AVMULHSD
+	0x100002c8, // AVMULEUD
+	0x100003c8, // AVMULESD
+	0x10000017, // AVMSUMCUD
+	0x1000068b, // AVMODUW
+	0x1000060b, // AVMODUQ
+	0x100006cb, // AVMODUD
+	0x1000078b, // AVMODSW
+	0x1000070b, // AVMODSQ
+	0x100007cb, // AVMODSD
+	0x1000018f, // AVINSWVRX
+	0x1000008f, // AVINSWVLX
+	0x1000038f, // AVINSWRX
+	0x1000028f, // AVINSWLX
+	0x100000cf, // AVINSW
+	0x1000014f, // AVINSHVRX
+	0x1000004f, // AVINSHVLX
+	0x1000034f, // AVINSHRX
+	0x1000024f, // AVINSHLX
+	0x100003cf, // AVINSDRX
+	0x100002cf, // AVINSDLX
+	0x100001cf, // AVINSD
+	0x1000010f, // AVINSBVRX
+	0x1000000f, // AVINSBVLX
+	0x1000030f, // AVINSBRX
+	0x1000020f, // AVINSBLX
+	0x100004cc, // AVGNB
+	0x101b0602, // AVEXTSD2Q
+	0x100a0642, // AVEXTRACTWM
+	0x100c0642, // AVEXTRACTQM
+	0x10090642, // AVEXTRACTHM
+	0x100b0642, // AVEXTRACTDM
+	0x10080642, // AVEXTRACTBM
+	0x1000001d, // AVEXTDUWVRX
+	0x1000001c, // AVEXTDUWVLX
+	0x1000001b, // AVEXTDUHVRX
+	0x1000001a, // AVEXTDUHVLX
+	0x10000019, // AVEXTDUBVRX
+	0x10000018, // AVEXTDUBVLX
+	0x1000001f, // AVEXTDDVRX
+	0x1000001e, // AVEXTDDVLX
+	0x10020642, // AVEXPANDWM
+	0x10040642, // AVEXPANDQM
+	0x10010642, // AVEXPANDHM
+	0x10030642, // AVEXPANDDM
+	0x10000642, // AVEXPANDBM
+	0x1000008b, // AVDIVUW
+	0x1000000b, // AVDIVUQ
+	0x100000cb, // AVDIVUD
+	0x1000018b, // AVDIVSW
+	0x1000010b, // AVDIVSQ
+	0x100001cb, // AVDIVSD
+	0x1000028b, // AVDIVEUW
+	0x1000020b, // AVDIVEUQ
+	0x100002cb, // AVDIVEUD
+	0x1000038b, // AVDIVESW
+	0x1000030b, // AVDIVESQ
+	0x100003cb, // AVDIVESD
+	0x100007c4, // AVCTZDM
+	0x101c0642, // AVCNTMBW
+	0x101a0642, // AVCNTMBH
+	0x101e0642, // AVCNTMBD
+	0x10180642, // AVCNTMBB
+	0x10000101, // AVCMPUQ
+	0x10000141, // AVCMPSQ
+	0x10000687, // AVCMPGTUQCC
+	0x10000287, // AVCMPGTUQ
+	0x10000787, // AVCMPGTSQCC
+	0x10000387, // AVCMPGTSQ
+	0x100005c7, // AVCMPEQUQCC
+	0x100001c7, // AVCMPEQUQ
+	0x10000784, // AVCLZDM
+	0x100001cd, // AVCLRRB
+	0x1000018d, // AVCLRLB
+	0x1000054d, // AVCFUGED
+	0x7c00019a, // ASTXVRWX
+	0x7c00015a, // ASTXVRHX
+	0x7c0001da, // ASTXVRDX
+	0x7c00011a, // ASTXVRBX
+	0x7c00039a, // ASTXVPX
+	0x18000001, // ASTXVP
+	0x7c0003c0, // ASETNBCR
+	0x7c000380, // ASETNBC
+	0x7c000340, // ASETBCR
+	0x7c000300, // ASETBC
+	0x7c000178, // APEXTD
+	0x7c000138, // APDEPD
+	0x10120642, // AMTVSRWM
+	0x10140642, // AMTVSRQM
+	0x10110642, // AMTVSRHM
+	0x10130642, // AMTVSRDM
+	0x10000014, // AMTVSRBMI
+	0x10100642, // AMTVSRBM
+	0x7c00009a, // ALXVRWX
+	0x7c00005a, // ALXVRHX
+	0x7c0000da, // ALXVRDX
+	0x7c00001a, // ALXVRBX
+	0x7c00029a, // ALXVPX
+	0x18000000, // ALXVP
+	0xf01f02d0, // ALXVKQ
+	0xfc0107c4, // ADCTFIXQQ
+	0xfc0007c4, // ADCFFIXQQ
+	0x7c000476, // ACNTTZDM
+	0x7c000076, // ACNTLZDM
+	0x7c0001b8, // ACFUGED
+	0x7c000136, // ABRW
+	0x7c0001b6, // ABRH
+	0x7c000176, // ABRD
+	0x7c000524, // AHASHSTP
+	0x7c0005a4, // AHASHST
+	0x7c000564, // AHASHCHKP
+	0x7c0005e4, // AHASHCHK
+	0x80060000, // AXXSPLTIW
+	0x80040000, // AXXSPLTIDP
+	0x80000000, // AXXSPLTI32DX
+	0x88000000, // AXXPERMX
+	0x88000010, // AXXEVAL
+	0x84000020, // AXXBLENDVW
+	0x84000010, // AXXBLENDVH
+	0x84000030, // AXXBLENDVD
+	0x84000000, // AXXBLENDVB
+	0xf8000000, // APSTXVP
+	0xd8000000, // APSTXV
+	0xbc000000, // APSTXSSP
+	0xb8000000, // APSTXSD
+	0x90000000, // APSTW
+	0xf0000000, // APSTQ
+	0xb0000000, // APSTH
+	0xd0000000, // APSTFS
+	0xd8000000, // APSTFD
+	0xf4000000, // APSTD
+	0x98000000, // APSTB
+	0x00000000, // APNOP
+	0xec000318, // APMXVI8GER4SPP
+	0xec000010, // APMXVI8GER4PP
+	0xec000018, // APMXVI8GER4
+	0xec000110, // APMXVI4GER8PP
+	0xec000118, // APMXVI4GER8
+	0xec000150, // APMXVI16GER2SPP
+	0xec000158, // APMXVI16GER2S
+	0xec000358, // APMXVI16GER2PP
+	0xec000258, // APMXVI16GER2
+	0xec0001d0, // APMXVF64GERPP
+	0xec0005d0, // APMXVF64GERPN
+	0xec0003d0, // APMXVF64GERNP
+	0xec0007d0, // APMXVF64GERNN
+	0xec0001d8, // APMXVF64GER
+	0xec0000d0, // APMXVF32GERPP
+	0xec0004d0, // APMXVF32GERPN
+	0xec0002d0, // APMXVF32GERNP
+	0xec0006d0, // APMXVF32GERNN
+	0xec0000d8, // APMXVF32GER
+	0xec000090, // APMXVF16GER2PP
+	0xec000490, // APMXVF16GER2PN
+	0xec000290, // APMXVF16GER2NP
+	0xec000690, // APMXVF16GER2NN
+	0xec000098, // APMXVF16GER2
+	0xec000190, // APMXVBF16GER2PP
+	0xec000590, // APMXVBF16GER2PN
+	0xec000390, // APMXVBF16GER2NP
+	0xec000790, // APMXVBF16GER2NN
+	0xec000198, // APMXVBF16GER2
+	0xe8000000, // APLXVP
+	0xc8000000, // APLXV
+	0xac000000, // APLXSSP
+	0xa8000000, // APLXSD
+	0x80000000, // APLWZ
+	0xa4000000, // APLWA
+	0xe0000000, // APLQ
+	0xa0000000, // APLHZ
+	0xa8000000, // APLHA
+	0xc0000000, // APLFS
+	0xc8000000, // APLFD
+	0xe4000000, // APLD
+	0x88000000, // APLBZ
+	0x38000000, // APADDI
+}
+
+var GenPfxOpcodes = [...]uint32{
+	0x05000000, // AXXSPLTIW
+	0x05000000, // AXXSPLTIDP
+	0x05000000, // AXXSPLTI32DX
+	0x05000000, // AXXPERMX
+	0x05000000, // AXXEVAL
+	0x05000000, // AXXBLENDVW
+	0x05000000, // AXXBLENDVH
+	0x05000000, // AXXBLENDVD
+	0x05000000, // AXXBLENDVB
+	0x04000000, // APSTXVP
+	0x04000000, // APSTXV
+	0x04000000, // APSTXSSP
+	0x04000000, // APSTXSD
+	0x06000000, // APSTW
+	0x04000000, // APSTQ
+	0x06000000, // APSTH
+	0x06000000, // APSTFS
+	0x06000000, // APSTFD
+	0x04000000, // APSTD
+	0x06000000, // APSTB
+	0x07000000, // APNOP
+	0x07900000, // APMXVI8GER4SPP
+	0x07900000, // APMXVI8GER4PP
+	0x07900000, // APMXVI8GER4
+	0x07900000, // APMXVI4GER8PP
+	0x07900000, // APMXVI4GER8
+	0x07900000, // APMXVI16GER2SPP
+	0x07900000, // APMXVI16GER2S
+	0x07900000, // APMXVI16GER2PP
+	0x07900000, // APMXVI16GER2
+	0x07900000, // APMXVF64GERPP
+	0x07900000, // APMXVF64GERPN
+	0x07900000, // APMXVF64GERNP
+	0x07900000, // APMXVF64GERNN
+	0x07900000, // APMXVF64GER
+	0x07900000, // APMXVF32GERPP
+	0x07900000, // APMXVF32GERPN
+	0x07900000, // APMXVF32GERNP
+	0x07900000, // APMXVF32GERNN
+	0x07900000, // APMXVF32GER
+	0x07900000, // APMXVF16GER2PP
+	0x07900000, // APMXVF16GER2PN
+	0x07900000, // APMXVF16GER2NP
+	0x07900000, // APMXVF16GER2NN
+	0x07900000, // APMXVF16GER2
+	0x07900000, // APMXVBF16GER2PP
+	0x07900000, // APMXVBF16GER2PN
+	0x07900000, // APMXVBF16GER2NP
+	0x07900000, // APMXVBF16GER2NN
+	0x07900000, // APMXVBF16GER2
+	0x04000000, // APLXVP
+	0x04000000, // APLXV
+	0x04000000, // APLXSSP
+	0x04000000, // APLXSD
+	0x06000000, // APLWZ
+	0x04000000, // APLWA
+	0x04000000, // APLQ
+	0x06000000, // APLHZ
+	0x06000000, // APLHA
+	0x06000000, // APLFS
+	0x06000000, // APLFD
+	0x04000000, // APLD
+	0x06000000, // APLBZ
+	0x06000000, // APADDI
+}
+
+var optabGen = []Optab{
+	{as: ABRW, a1: C_REG, a6: C_REG, asmout: type_brw, size: 4},
+	{as: ADCFFIXQQ, a1: C_VREG, a6: C_FREGP, asmout: type_xscvuqqp, size: 4},
+	{as: ADCTFIXQQ, a1: C_FREGP, a6: C_VREG, asmout: type_xscvuqqp, size: 4},
+	{as: AHASHCHKP, a1: C_SOREG, a6: C_REG, asmout: type_hashchkp, size: 4},
+	{as: AHASHSTP, a1: C_REG, a6: C_SOREG, asmout: type_hashstp, size: 4},
+	{as: ALXVKQ, a1: C_U5CON, a6: C_VSREG, asmout: type_lxvkq, size: 4},
+	{as: ALXVP, a1: C_SOREG, a6: C_VSREGP, asmout: type_lxvp, size: 4},
+	{as: ALXVPX, a1: C_XOREG, a6: C_VSREGP, asmout: type_lxvpx, size: 4},
+	{as: ALXVRWX, a1: C_XOREG, a6: C_VSREG, asmout: type_lxvrwx, size: 4},
+	{as: AMTVSRBMI, a1: C_U16CON, a6: C_VREG, asmout: type_mtvsrbmi, size: 4},
+	{as: AMTVSRWM, a1: C_REG, a6: C_VREG, asmout: type_xscvuqqp, size: 4},
+	{as: APADDI, a1: C_REG, a3: C_S34CON, a4: C_U1CON, a6: C_REG, asmout: type_paddi, ispfx: true, size: 8},
+	{as: APEXTD, a1: C_REG, a2: C_REG, a6: C_REG, asmout: type_pextd, size: 4},
+	{as: APLFS, a1: C_LOREG, a3: C_U1CON, a6: C_FREG, asmout: type_plxssp, ispfx: true, size: 8},
+	{as: APLQ, a1: C_LOREG, a3: C_U1CON, a6: C_REGP, asmout: type_plxssp, ispfx: true, size: 8},
+	{as: APLWZ, a1: C_LOREG, a3: C_U1CON, a6: C_REG, asmout: type_plxssp, ispfx: true, size: 8},
+	{as: APLXSSP, a1: C_LOREG, a3: C_U1CON, a6: C_VREG, asmout: type_plxssp, ispfx: true, size: 8},
+	{as: APLXV, a1: C_LOREG, a3: C_U1CON, a6: C_VSREG, asmout: type_plxv, ispfx: true, size: 8},
+	{as: APLXVP, a1: C_LOREG, a3: C_U1CON, a6: C_VSREGP, asmout: type_plxvp, ispfx: true, size: 8},
+	{as: APMXVF32GERPP, a1: C_VSREG, a2: C_VSREG, a3: C_U4CON, a4: C_U4CON, a6: C_AREG, asmout: type_pmxvf32gerpp, ispfx: true, size: 8},
+	{as: APMXVF64GERPP, a1: C_VSREGP, a2: C_VSREG, a3: C_U4CON, a4: C_U2CON, a6: C_AREG, asmout: type_pmxvf64gerpp, ispfx: true, size: 8},
+	{as: APMXVI16GER2SPP, a1: C_VSREG, a2: C_VSREG, a3: C_U4CON, a4: C_U4CON, a5: C_U2CON, a6: C_AREG, asmout: type_pmxvi16ger2spp, ispfx: true, size: 8},
+	{as: APMXVI4GER8PP, a1: C_VSREG, a2: C_VSREG, a3: C_U4CON, a4: C_U4CON, a5: C_U8CON, a6: C_AREG, asmout: type_pmxvi4ger8pp, ispfx: true, size: 8},
+	{as: APMXVI8GER4SPP, a1: C_VSREG, a2: C_VSREG, a3: C_U4CON, a4: C_U4CON, a5: C_U4CON, a6: C_AREG, asmout: type_pmxvi8ger4spp, ispfx: true, size: 8},
+	{as: APNOP, asmout: type_pnop, ispfx: true, size: 8},
+	{as: APSTFS, a1: C_FREG, a3: C_U1CON, a6: C_LOREG, asmout: type_pstxssp, ispfx: true, size: 8},
+	{as: APSTQ, a1: C_REGP, a3: C_U1CON, a6: C_LOREG, asmout: type_pstxssp, ispfx: true, size: 8},
+	{as: APSTW, a1: C_REG, a3: C_U1CON, a6: C_LOREG, asmout: type_pstxssp, ispfx: true, size: 8},
+	{as: APSTXSSP, a1: C_VREG, a3: C_U1CON, a6: C_LOREG, asmout: type_pstxssp, ispfx: true, size: 8},
+	{as: APSTXV, a1: C_VSREG, a3: C_U1CON, a6: C_LOREG, asmout: type_pstxv, ispfx: true, size: 8},
+	{as: APSTXVP, a1: C_VSREGP, a3: C_U1CON, a6: C_LOREG, asmout: type_pstxvp, ispfx: true, size: 8},
+	{as: ASETNBCR, a1: C_CRBIT, a6: C_REG, asmout: type_setnbcr, size: 4},
+	{as: ASTXVP, a1: C_VSREGP, a6: C_SOREG, asmout: type_stxvp, size: 4},
+	{as: ASTXVPX, a1: C_VSREGP, a6: C_XOREG, asmout: type_stxvpx, size: 4},
+	{as: ASTXVRWX, a1: C_VSREG, a6: C_XOREG, asmout: type_stxvrwx, size: 4},
+	{as: AVCLRRB, a1: C_VREG, a2: C_REG, a6: C_VREG, asmout: type_xsmincqp, size: 4},
+	{as: AVCMPUQ, a1: C_VREG, a2: C_VREG, a6: C_CREG, asmout: type_vcmpuq, size: 4},
+	{as: AVCNTMBW, a1: C_VREG, a3: C_U1CON, a6: C_REG, asmout: type_vcntmbw, size: 4},
+	{as: AVEXTDUWVRX, a1: C_VREG, a2: C_VREG, a3: C_REG, a6: C_VREG, asmout: type_vmsumcud, size: 4},
+	{as: AVEXTRACTWM, a1: C_VREG, a6: C_REG, asmout: type_xscvuqqp, size: 4},
+	{as: AVGNB, a1: C_VREG, a3: C_U3CON, a6: C_REG, asmout: type_vgnb, size: 4},
+	{as: AVINSW, a1: C_REG, a3: C_U4CON, a6: C_VREG, asmout: type_vinsw, size: 4},
+	{as: AVINSWRX, a1: C_REG, a2: C_REG, a6: C_VREG, asmout: type_xsmincqp, size: 4},
+	{as: AVINSWVRX, a1: C_REG, a2: C_VREG, a6: C_VREG, asmout: type_xsmincqp, size: 4},
+	{as: AVMSUMCUD, a1: C_VREG, a2: C_VREG, a3: C_VREG, a6: C_VREG, asmout: type_vmsumcud, size: 4},
+	{as: AVSRDBI, a1: C_VREG, a2: C_VREG, a3: C_U3CON, a6: C_VREG, asmout: type_vsrdbi, size: 4},
+	{as: AXSCVUQQP, a1: C_VREG, a6: C_VREG, asmout: type_xscvuqqp, size: 4},
+	{as: AXSMINCQP, a1: C_VREG, a2: C_VREG, a6: C_VREG, asmout: type_xsmincqp, size: 4},
+	{as: AXVCVSPBF16, a1: C_VSREG, a6: C_VSREG, asmout: type_xvcvspbf16, size: 4},
+	{as: AXVI8GER4SPP, a1: C_VSREG, a2: C_VSREG, a6: C_AREG, asmout: type_xvi8ger4spp, size: 4},
+	{as: AXVTLSBB, a1: C_VSREG, a6: C_CREG, asmout: type_xvtlsbb, size: 4},
+	{as: AXXBLENDVW, a1: C_VSREG, a2: C_VSREG, a3: C_VSREG, a6: C_VSREG, asmout: type_xxblendvw, ispfx: true, size: 8},
+	{as: AXXEVAL, a1: C_VSREG, a2: C_VSREG, a3: C_VSREG, a4: C_U8CON, a6: C_VSREG, asmout: type_xxeval, ispfx: true, size: 8},
+	{as: AXXGENPCVWM, a1: C_VREG, a3: C_U5CON, a6: C_VSREG, asmout: type_xxgenpcvwm, size: 4},
+	{as: AXXPERMX, a1: C_VSREG, a2: C_VSREG, a3: C_VSREG, a4: C_U3CON, a6: C_VSREG, asmout: type_xxpermx, ispfx: true, size: 8},
+	{as: AXXSETACCZ, a6: C_AREG, asmout: type_xxsetaccz, size: 4},
+	{as: AXXSPLTI32DX, a1: C_U1CON, a3: C_U32CON, a6: C_VSREG, asmout: type_xxsplti32dx, ispfx: true, size: 8},
+	{as: AXXSPLTIW, a1: C_U32CON, a6: C_VSREG, asmout: type_xxspltiw, ispfx: true, size: 8},
+}
+
+// brw RA,RS
+func type_brw(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenOpcodes[p.As-AXXSETACCZ]
+	o0 |= uint32(p.To.Reg&0x1f) << 16   // RA
+	o0 |= uint32(p.From.Reg&0x1f) << 21 // RS
+	out[0] = o0
+}
+
+// hashchkp RB,offset(RA)
+func type_hashchkp(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenOpcodes[p.As-AXXSETACCZ]
+	o0 |= uint32(p.To.Reg&0x1f) << 11           // RB
+	o0 |= uint32((p.From.Offset>>8)&0x1) << 0   // DX
+	o0 |= uint32((p.From.Offset>>3)&0x1f) << 21 // D
+	o0 |= uint32(p.From.Reg&0x1f) << 16         // RA
+	if p.From.Offset&0xfffffe07 != 0xfffffe00 {
+		c.ctxt.Diag("Constant(%d) must within the range of [-512,-8] in steps of 8\n%v", p.From.Offset, p)
+	}
+	out[0] = o0
+}
+
+// hashstp RB,offset(RA)
+func type_hashstp(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenOpcodes[p.As-AXXSETACCZ]
+	o0 |= uint32(p.From.Reg&0x1f) << 11       // RB
+	o0 |= uint32((p.To.Offset>>8)&0x1) << 0   // DX
+	o0 |= uint32((p.To.Offset>>3)&0x1f) << 21 // D
+	o0 |= uint32(p.To.Reg&0x1f) << 16         // RA
+	if p.To.Offset&0xfffffe07 != 0xfffffe00 {
+		c.ctxt.Diag("Constant(%d) must within the range of [-512,-8] in steps of 8\n%v", p.To.Offset, p)
+	}
+	out[0] = o0
+}
+
+// lxvkq XT,UIM
+func type_lxvkq(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenOpcodes[p.As-AXXSETACCZ]
+	o0 |= uint32((p.To.Reg>>5)&0x1) << 0   // TX
+	o0 |= uint32(p.To.Reg&0x1f) << 21      // T
+	o0 |= uint32(p.From.Offset&0x1f) << 11 // UIM
+	out[0] = o0
+}
+
+// lxvp XTp,DQ(RA)
+func type_lxvp(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenOpcodes[p.As-AXXSETACCZ]
+	o0 |= uint32((p.To.Reg>>5)&0x1) << 21       // TX
+	o0 |= uint32((p.To.Reg>>1)&0xf) << 22       // Tp
+	o0 |= uint32((p.From.Offset>>4)&0xfff) << 4 // DQ
+	o0 |= uint32(p.From.Reg&0x1f) << 16         // RA
+	if p.From.Offset&0xf != 0 {
+		c.ctxt.Diag("Constant 0x%x (%d) is not a multiple of 16\n%v", p.From.Offset, p.From.Offset, p)
+	}
+	out[0] = o0
+}
+
+// lxvpx XTp,RA,RB
+func type_lxvpx(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenOpcodes[p.As-AXXSETACCZ]
+	o0 |= uint32((p.To.Reg>>5)&0x1) << 21 // TX
+	o0 |= uint32((p.To.Reg>>1)&0xf) << 22 // Tp
+	o0 |= uint32(p.From.Index&0x1f) << 16 // RA
+	o0 |= uint32(p.From.Reg&0x1f) << 11   // RB
+	out[0] = o0
+}
+
+// lxvrwx XT,RA,RB
+func type_lxvrwx(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenOpcodes[p.As-AXXSETACCZ]
+	o0 |= uint32((p.To.Reg>>5)&0x1) << 0  // TX
+	o0 |= uint32(p.To.Reg&0x1f) << 21     // T
+	o0 |= uint32(p.From.Index&0x1f) << 16 // RA
+	o0 |= uint32(p.From.Reg&0x1f) << 11   // RB
+	out[0] = o0
+}
+
+// mtvsrbmi VRT,bm
+func type_mtvsrbmi(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenOpcodes[p.As-AXXSETACCZ]
+	o0 |= uint32(p.To.Reg&0x1f) << 21           // VRT
+	o0 |= uint32((p.From.Offset>>6)&0x3ff) << 6 // b0
+	o0 |= uint32((p.From.Offset>>1)&0x1f) << 16 // b1
+	o0 |= uint32(p.From.Offset&0x1) << 0        // b2
+	out[0] = o0
+}
+
+// paddi RT,RA,SI,R
+func type_paddi(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenPfxOpcodes[p.As-AXXSPLTIW]
+	o1 := GenOpcodes[p.As-AXXSETACCZ]
+	o1 |= uint32(p.To.Reg&0x1f) << 21                          // RT
+	o1 |= uint32(p.From.Reg&0x1f) << 16                        // RA
+	o0 |= uint32((p.RestArgs[0].Addr.Offset>>16)&0x3ffff) << 0 // si0
+	o1 |= uint32(p.RestArgs[0].Addr.Offset&0xffff) << 0        // si1
+	o0 |= uint32(p.RestArgs[1].Addr.Offset&0x1) << 20          // R
+	out[1] = o1
+	out[0] = o0
+}
+
+// pextd RA,RS,RB
+func type_pextd(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenOpcodes[p.As-AXXSETACCZ]
+	o0 |= uint32(p.To.Reg&0x1f) << 16   // RA
+	o0 |= uint32(p.From.Reg&0x1f) << 21 // RS
+	o0 |= uint32(p.Reg&0x1f) << 11      // RB
+	out[0] = o0
+}
+
+// plxssp VRT,D(RA),R
+func type_plxssp(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenPfxOpcodes[p.As-AXXSPLTIW]
+	o1 := GenOpcodes[p.As-AXXSETACCZ]
+	o1 |= uint32(p.To.Reg&0x1f) << 21                 // VRT
+	o0 |= uint32((p.From.Offset>>16)&0x3ffff) << 0    // d0
+	o1 |= uint32(p.From.Offset&0xffff) << 0           // d1
+	o1 |= uint32(p.From.Reg&0x1f) << 16               // RA
+	o0 |= uint32(p.RestArgs[0].Addr.Offset&0x1) << 20 // R
+	out[1] = o1
+	out[0] = o0
+}
+
+// plxv XT,D(RA),R
+func type_plxv(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenPfxOpcodes[p.As-AXXSPLTIW]
+	o1 := GenOpcodes[p.As-AXXSETACCZ]
+	o1 |= uint32((p.To.Reg>>5)&0x1) << 26             // TX
+	o1 |= uint32(p.To.Reg&0x1f) << 21                 // T
+	o0 |= uint32((p.From.Offset>>16)&0x3ffff) << 0    // d0
+	o1 |= uint32(p.From.Offset&0xffff) << 0           // d1
+	o1 |= uint32(p.From.Reg&0x1f) << 16               // RA
+	o0 |= uint32(p.RestArgs[0].Addr.Offset&0x1) << 20 // R
+	out[1] = o1
+	out[0] = o0
+}
+
+// plxvp XTp,D(RA),R
+func type_plxvp(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenPfxOpcodes[p.As-AXXSPLTIW]
+	o1 := GenOpcodes[p.As-AXXSETACCZ]
+	o1 |= uint32((p.To.Reg>>5)&0x1) << 21             // TX
+	o1 |= uint32((p.To.Reg>>1)&0xf) << 22             // Tp
+	o0 |= uint32((p.From.Offset>>16)&0x3ffff) << 0    // d0
+	o1 |= uint32(p.From.Offset&0xffff) << 0           // d1
+	o1 |= uint32(p.From.Reg&0x1f) << 16               // RA
+	o0 |= uint32(p.RestArgs[0].Addr.Offset&0x1) << 20 // R
+	out[1] = o1
+	out[0] = o0
+}
+
+// pmxvf32gerpp AT,XA,XB,XMSK,YMSK
+func type_pmxvf32gerpp(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenPfxOpcodes[p.As-AXXSPLTIW]
+	o1 := GenOpcodes[p.As-AXXSETACCZ]
+	o1 |= uint32(p.To.Reg&0x7) << 23                 // AT
+	o1 |= uint32((p.From.Reg>>5)&0x1) << 2           // AX
+	o1 |= uint32(p.From.Reg&0x1f) << 16              // A
+	o1 |= uint32((p.Reg>>5)&0x1) << 1                // BX
+	o1 |= uint32(p.Reg&0x1f) << 11                   // B
+	o0 |= uint32(p.RestArgs[0].Addr.Offset&0xf) << 4 // XMSK
+	o0 |= uint32(p.RestArgs[1].Addr.Offset&0xf) << 0 // YMSK
+	out[1] = o1
+	out[0] = o0
+}
+
+// pmxvf64gerpp AT,XAp,XB,XMSK,YMSK
+func type_pmxvf64gerpp(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenPfxOpcodes[p.As-AXXSPLTIW]
+	o1 := GenOpcodes[p.As-AXXSETACCZ]
+	o1 |= uint32(p.To.Reg&0x7) << 23                 // AT
+	o1 |= uint32((p.From.Reg>>5)&0x1) << 2           // AX
+	o1 |= uint32(p.From.Reg&0x1f) << 16              // Ap
+	o1 |= uint32((p.Reg>>5)&0x1) << 1                // BX
+	o1 |= uint32(p.Reg&0x1f) << 11                   // B
+	o0 |= uint32(p.RestArgs[0].Addr.Offset&0xf) << 4 // XMSK
+	o0 |= uint32(p.RestArgs[1].Addr.Offset&0x3) << 2 // YMSK
+	out[1] = o1
+	out[0] = o0
+}
+
+// pmxvi16ger2spp AT,XA,XB,XMSK,YMSK,PMSK
+func type_pmxvi16ger2spp(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenPfxOpcodes[p.As-AXXSPLTIW]
+	o1 := GenOpcodes[p.As-AXXSETACCZ]
+	o1 |= uint32(p.To.Reg&0x7) << 23                  // AT
+	o1 |= uint32((p.From.Reg>>5)&0x1) << 2            // AX
+	o1 |= uint32(p.From.Reg&0x1f) << 16               // A
+	o1 |= uint32((p.Reg>>5)&0x1) << 1                 // BX
+	o1 |= uint32(p.Reg&0x1f) << 11                    // B
+	o0 |= uint32(p.RestArgs[0].Addr.Offset&0xf) << 4  // XMSK
+	o0 |= uint32(p.RestArgs[1].Addr.Offset&0xf) << 0  // YMSK
+	o0 |= uint32(p.RestArgs[2].Addr.Offset&0x3) << 14 // PMSK
+	out[1] = o1
+	out[0] = o0
+}
+
+// pmxvi4ger8pp AT,XA,XB,XMSK,YMSK,PMSK
+func type_pmxvi4ger8pp(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenPfxOpcodes[p.As-AXXSPLTIW]
+	o1 := GenOpcodes[p.As-AXXSETACCZ]
+	o1 |= uint32(p.To.Reg&0x7) << 23                  // AT
+	o1 |= uint32((p.From.Reg>>5)&0x1) << 2            // AX
+	o1 |= uint32(p.From.Reg&0x1f) << 16               // A
+	o1 |= uint32((p.Reg>>5)&0x1) << 1                 // BX
+	o1 |= uint32(p.Reg&0x1f) << 11                    // B
+	o0 |= uint32(p.RestArgs[0].Addr.Offset&0xf) << 4  // XMSK
+	o0 |= uint32(p.RestArgs[1].Addr.Offset&0xf) << 0  // YMSK
+	o0 |= uint32(p.RestArgs[2].Addr.Offset&0xff) << 8 // PMSK
+	out[1] = o1
+	out[0] = o0
+}
+
+// pmxvi8ger4spp AT,XA,XB,XMSK,YMSK,PMSK
+func type_pmxvi8ger4spp(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenPfxOpcodes[p.As-AXXSPLTIW]
+	o1 := GenOpcodes[p.As-AXXSETACCZ]
+	o1 |= uint32(p.To.Reg&0x7) << 23                  // AT
+	o1 |= uint32((p.From.Reg>>5)&0x1) << 2            // AX
+	o1 |= uint32(p.From.Reg&0x1f) << 16               // A
+	o1 |= uint32((p.Reg>>5)&0x1) << 1                 // BX
+	o1 |= uint32(p.Reg&0x1f) << 11                    // B
+	o0 |= uint32(p.RestArgs[0].Addr.Offset&0xf) << 4  // XMSK
+	o0 |= uint32(p.RestArgs[1].Addr.Offset&0xf) << 0  // YMSK
+	o0 |= uint32(p.RestArgs[2].Addr.Offset&0xf) << 12 // PMSK
+	out[1] = o1
+	out[0] = o0
+}
+
+// pnop
+func type_pnop(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenPfxOpcodes[p.As-AXXSPLTIW]
+	o1 := GenOpcodes[p.As-AXXSETACCZ]
+	out[1] = o1
+	out[0] = o0
+}
+
+// pstxssp VRS,D(RA),R
+func type_pstxssp(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenPfxOpcodes[p.As-AXXSPLTIW]
+	o1 := GenOpcodes[p.As-AXXSETACCZ]
+	o1 |= uint32(p.From.Reg&0x1f) << 21               // VRS
+	o0 |= uint32((p.To.Offset>>16)&0x3ffff) << 0      // d0
+	o1 |= uint32(p.To.Offset&0xffff) << 0             // d1
+	o1 |= uint32(p.To.Reg&0x1f) << 16                 // RA
+	o0 |= uint32(p.RestArgs[0].Addr.Offset&0x1) << 20 // R
+	out[1] = o1
+	out[0] = o0
+}
+
+// pstxv XS,D(RA),R
+func type_pstxv(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenPfxOpcodes[p.As-AXXSPLTIW]
+	o1 := GenOpcodes[p.As-AXXSETACCZ]
+	o1 |= uint32((p.From.Reg>>5)&0x1) << 26           // SX
+	o1 |= uint32(p.From.Reg&0x1f) << 21               // S
+	o0 |= uint32((p.To.Offset>>16)&0x3ffff) << 0      // d0
+	o1 |= uint32(p.To.Offset&0xffff) << 0             // d1
+	o1 |= uint32(p.To.Reg&0x1f) << 16                 // RA
+	o0 |= uint32(p.RestArgs[0].Addr.Offset&0x1) << 20 // R
+	out[1] = o1
+	out[0] = o0
+}
+
+// pstxvp XSp,D(RA),R
+func type_pstxvp(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenPfxOpcodes[p.As-AXXSPLTIW]
+	o1 := GenOpcodes[p.As-AXXSETACCZ]
+	o1 |= uint32((p.From.Reg>>5)&0x1) << 21           // SX
+	o1 |= uint32((p.From.Reg>>1)&0xf) << 22           // Sp
+	o0 |= uint32((p.To.Offset>>16)&0x3ffff) << 0      // d0
+	o1 |= uint32(p.To.Offset&0xffff) << 0             // d1
+	o1 |= uint32(p.To.Reg&0x1f) << 16                 // RA
+	o0 |= uint32(p.RestArgs[0].Addr.Offset&0x1) << 20 // R
+	out[1] = o1
+	out[0] = o0
+}
+
+// setnbcr RT,BI
+func type_setnbcr(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenOpcodes[p.As-AXXSETACCZ]
+	o0 |= uint32(p.To.Reg&0x1f) << 21   // RT
+	o0 |= uint32(p.From.Reg&0x1f) << 16 // BI
+	out[0] = o0
+}
+
+// stxvp XSp,DQ(RA)
+func type_stxvp(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenOpcodes[p.As-AXXSETACCZ]
+	o0 |= uint32((p.From.Reg>>5)&0x1) << 21   // SX
+	o0 |= uint32((p.From.Reg>>1)&0xf) << 22   // Sp
+	o0 |= uint32((p.To.Offset>>4)&0xfff) << 4 // DQ
+	o0 |= uint32(p.To.Reg&0x1f) << 16         // RA
+	if p.To.Offset&0xf != 0 {
+		c.ctxt.Diag("Constant 0x%x (%d) is not a multiple of 16\n%v", p.To.Offset, p.To.Offset, p)
+	}
+	out[0] = o0
+}
+
+// stxvpx XSp,RA,RB
+func type_stxvpx(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenOpcodes[p.As-AXXSETACCZ]
+	o0 |= uint32((p.From.Reg>>5)&0x1) << 21 // SX
+	o0 |= uint32((p.From.Reg>>1)&0xf) << 22 // Sp
+	o0 |= uint32(p.To.Index&0x1f) << 16     // RA
+	o0 |= uint32(p.To.Reg&0x1f) << 11       // RB
+	out[0] = o0
+}
+
+// stxvrwx XS,RA,RB
+func type_stxvrwx(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenOpcodes[p.As-AXXSETACCZ]
+	o0 |= uint32((p.From.Reg>>5)&0x1) << 0 // SX
+	o0 |= uint32(p.From.Reg&0x1f) << 21    // S
+	o0 |= uint32(p.To.Index&0x1f) << 16    // RA
+	o0 |= uint32(p.To.Reg&0x1f) << 11      // RB
+	out[0] = o0
+}
+
+// vcmpuq BF,VRA,VRB
+func type_vcmpuq(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenOpcodes[p.As-AXXSETACCZ]
+	o0 |= uint32(p.To.Reg&0x7) << 23    // BF
+	o0 |= uint32(p.From.Reg&0x1f) << 16 // VRA
+	o0 |= uint32(p.Reg&0x1f) << 11      // VRB
+	out[0] = o0
+}
+
+// vcntmbw RT,VRB,MP
+func type_vcntmbw(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenOpcodes[p.As-AXXSETACCZ]
+	o0 |= uint32(p.To.Reg&0x1f) << 21                 // RT
+	o0 |= uint32(p.From.Reg&0x1f) << 11               // VRB
+	o0 |= uint32(p.RestArgs[0].Addr.Offset&0x1) << 16 // MP
+	out[0] = o0
+}
+
+// vgnb RT,VRB,N
+func type_vgnb(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenOpcodes[p.As-AXXSETACCZ]
+	o0 |= uint32(p.To.Reg&0x1f) << 21                 // RT
+	o0 |= uint32(p.From.Reg&0x1f) << 11               // VRB
+	o0 |= uint32(p.RestArgs[0].Addr.Offset&0x7) << 16 // N
+	out[0] = o0
+}
+
+// vinsw VRT,RB,UIM
+func type_vinsw(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenOpcodes[p.As-AXXSETACCZ]
+	o0 |= uint32(p.To.Reg&0x1f) << 21                 // VRT
+	o0 |= uint32(p.From.Reg&0x1f) << 11               // RB
+	o0 |= uint32(p.RestArgs[0].Addr.Offset&0xf) << 16 // UIM
+	out[0] = o0
+}
+
+// vmsumcud VRT,VRA,VRB,VRC
+func type_vmsumcud(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenOpcodes[p.As-AXXSETACCZ]
+	o0 |= uint32(p.To.Reg&0x1f) << 21              // VRT
+	o0 |= uint32(p.From.Reg&0x1f) << 16            // VRA
+	o0 |= uint32(p.Reg&0x1f) << 11                 // VRB
+	o0 |= uint32(p.RestArgs[0].Addr.Reg&0x1f) << 6 // VRC
+	out[0] = o0
+}
+
+// vsrdbi VRT,VRA,VRB,SH
+func type_vsrdbi(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenOpcodes[p.As-AXXSETACCZ]
+	o0 |= uint32(p.To.Reg&0x1f) << 21                // VRT
+	o0 |= uint32(p.From.Reg&0x1f) << 16              // VRA
+	o0 |= uint32(p.Reg&0x1f) << 11                   // VRB
+	o0 |= uint32(p.RestArgs[0].Addr.Offset&0x7) << 6 // SH
+	out[0] = o0
+}
+
+// xscvuqqp VRT,VRB
+func type_xscvuqqp(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenOpcodes[p.As-AXXSETACCZ]
+	o0 |= uint32(p.To.Reg&0x1f) << 21   // VRT
+	o0 |= uint32(p.From.Reg&0x1f) << 11 // VRB
+	out[0] = o0
+}
+
+// xsmincqp VRT,VRA,VRB
+func type_xsmincqp(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenOpcodes[p.As-AXXSETACCZ]
+	o0 |= uint32(p.To.Reg&0x1f) << 21   // VRT
+	o0 |= uint32(p.From.Reg&0x1f) << 16 // VRA
+	o0 |= uint32(p.Reg&0x1f) << 11      // VRB
+	out[0] = o0
+}
+
+// xvcvspbf16 XT,XB
+func type_xvcvspbf16(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenOpcodes[p.As-AXXSETACCZ]
+	o0 |= uint32((p.To.Reg>>5)&0x1) << 0   // TX
+	o0 |= uint32(p.To.Reg&0x1f) << 21      // T
+	o0 |= uint32((p.From.Reg>>5)&0x1) << 1 // BX
+	o0 |= uint32(p.From.Reg&0x1f) << 11    // B
+	out[0] = o0
+}
+
+// xvi8ger4spp AT,XA,XB
+func type_xvi8ger4spp(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenOpcodes[p.As-AXXSETACCZ]
+	o0 |= uint32(p.To.Reg&0x7) << 23       // AT
+	o0 |= uint32((p.From.Reg>>5)&0x1) << 2 // AX
+	o0 |= uint32(p.From.Reg&0x1f) << 16    // A
+	o0 |= uint32((p.Reg>>5)&0x1) << 1      // BX
+	o0 |= uint32(p.Reg&0x1f) << 11         // B
+	out[0] = o0
+}
+
+// xvtlsbb BF,XB
+func type_xvtlsbb(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenOpcodes[p.As-AXXSETACCZ]
+	o0 |= uint32(p.To.Reg&0x7) << 23       // BF
+	o0 |= uint32((p.From.Reg>>5)&0x1) << 1 // BX
+	o0 |= uint32(p.From.Reg&0x1f) << 11    // B
+	out[0] = o0
+}
+
+// xxblendvw XT,XA,XB,XC
+func type_xxblendvw(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenPfxOpcodes[p.As-AXXSPLTIW]
+	o1 := GenOpcodes[p.As-AXXSETACCZ]
+	o1 |= uint32((p.To.Reg>>5)&0x1) << 0               // TX
+	o1 |= uint32(p.To.Reg&0x1f) << 21                  // T
+	o1 |= uint32((p.From.Reg>>5)&0x1) << 2             // AX
+	o1 |= uint32(p.From.Reg&0x1f) << 16                // A
+	o1 |= uint32((p.Reg>>5)&0x1) << 1                  // BX
+	o1 |= uint32(p.Reg&0x1f) << 11                     // B
+	o1 |= uint32((p.RestArgs[0].Addr.Reg>>5)&0x1) << 3 // CX
+	o1 |= uint32(p.RestArgs[0].Addr.Reg&0x1f) << 6     // C
+	out[1] = o1
+	out[0] = o0
+}
+
+// xxeval XT,XA,XB,XC,IMM
+func type_xxeval(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenPfxOpcodes[p.As-AXXSPLTIW]
+	o1 := GenOpcodes[p.As-AXXSETACCZ]
+	o1 |= uint32((p.To.Reg>>5)&0x1) << 0               // TX
+	o1 |= uint32(p.To.Reg&0x1f) << 21                  // T
+	o1 |= uint32((p.From.Reg>>5)&0x1) << 2             // AX
+	o1 |= uint32(p.From.Reg&0x1f) << 16                // A
+	o1 |= uint32((p.Reg>>5)&0x1) << 1                  // BX
+	o1 |= uint32(p.Reg&0x1f) << 11                     // B
+	o1 |= uint32((p.RestArgs[0].Addr.Reg>>5)&0x1) << 3 // CX
+	o1 |= uint32(p.RestArgs[0].Addr.Reg&0x1f) << 6     // C
+	o0 |= uint32(p.RestArgs[1].Addr.Offset&0xff) << 0  // IMM
+	out[1] = o1
+	out[0] = o0
+}
+
+// xxgenpcvwm XT,VRB,IMM
+func type_xxgenpcvwm(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenOpcodes[p.As-AXXSETACCZ]
+	o0 |= uint32((p.To.Reg>>5)&0x1) << 0               // TX
+	o0 |= uint32(p.To.Reg&0x1f) << 21                  // T
+	o0 |= uint32(p.From.Reg&0x1f) << 11                // VRB
+	o0 |= uint32(p.RestArgs[0].Addr.Offset&0x1f) << 16 // IMM
+	out[0] = o0
+}
+
+// xxpermx XT,XA,XB,XC,UIM
+func type_xxpermx(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenPfxOpcodes[p.As-AXXSPLTIW]
+	o1 := GenOpcodes[p.As-AXXSETACCZ]
+	o1 |= uint32((p.To.Reg>>5)&0x1) << 0               // TX
+	o1 |= uint32(p.To.Reg&0x1f) << 21                  // T
+	o1 |= uint32((p.From.Reg>>5)&0x1) << 2             // AX
+	o1 |= uint32(p.From.Reg&0x1f) << 16                // A
+	o1 |= uint32((p.Reg>>5)&0x1) << 1                  // BX
+	o1 |= uint32(p.Reg&0x1f) << 11                     // B
+	o1 |= uint32((p.RestArgs[0].Addr.Reg>>5)&0x1) << 3 // CX
+	o1 |= uint32(p.RestArgs[0].Addr.Reg&0x1f) << 6     // C
+	o0 |= uint32(p.RestArgs[1].Addr.Offset&0x7) << 0   // UIM
+	out[1] = o1
+	out[0] = o0
+}
+
+// xxsetaccz AT
+func type_xxsetaccz(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenOpcodes[p.As-AXXSETACCZ]
+	o0 |= uint32(p.To.Reg&0x7) << 23 // AT
+	out[0] = o0
+}
+
+// xxsplti32dx XT,IX,IMM32
+func type_xxsplti32dx(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenPfxOpcodes[p.As-AXXSPLTIW]
+	o1 := GenOpcodes[p.As-AXXSETACCZ]
+	o1 |= uint32((p.To.Reg>>5)&0x1) << 16                     // TX
+	o1 |= uint32(p.To.Reg&0x1f) << 21                         // T
+	o1 |= uint32(p.From.Offset&0x1) << 17                     // IX
+	o0 |= uint32((p.RestArgs[0].Addr.Offset>>16)&0xffff) << 0 // imm0
+	o1 |= uint32(p.RestArgs[0].Addr.Offset&0xffff) << 0       // imm1
+	out[1] = o1
+	out[0] = o0
+}
+
+// xxspltiw XT,IMM32
+func type_xxspltiw(c *ctxt9, p *obj.Prog, t *Optab, out *[5]uint32) {
+	o0 := GenPfxOpcodes[p.As-AXXSPLTIW]
+	o1 := GenOpcodes[p.As-AXXSETACCZ]
+	o1 |= uint32((p.To.Reg>>5)&0x1) << 16         // TX
+	o1 |= uint32(p.To.Reg&0x1f) << 21             // T
+	o0 |= uint32((p.From.Offset>>16)&0xffff) << 0 // imm0
+	o1 |= uint32(p.From.Offset&0xffff) << 0       // imm1
+	out[1] = o1
+	out[0] = o0
+}
+
+func opsetGen(from obj.As) bool {
+	r0 := from & obj.AMask
+	switch from {
+	case ABRW:
+		opset(ABRH, r0)
+		opset(ABRD, r0)
+	case ADCFFIXQQ:
+	case ADCTFIXQQ:
+	case AHASHCHKP:
+		opset(AHASHCHK, r0)
+	case AHASHSTP:
+		opset(AHASHST, r0)
+	case ALXVKQ:
+	case ALXVP:
+	case ALXVPX:
+	case ALXVRWX:
+		opset(ALXVRHX, r0)
+		opset(ALXVRDX, r0)
+		opset(ALXVRBX, r0)
+	case AMTVSRBMI:
+	case AMTVSRWM:
+		opset(AMTVSRQM, r0)
+		opset(AMTVSRHM, r0)
+		opset(AMTVSRDM, r0)
+		opset(AMTVSRBM, r0)
+	case APADDI:
+	case APEXTD:
+		opset(APDEPD, r0)
+		opset(ACNTTZDM, r0)
+		opset(ACNTLZDM, r0)
+		opset(ACFUGED, r0)
+	case APLFS:
+		opset(APLFD, r0)
+	case APLQ:
+	case APLWZ:
+		opset(APLWA, r0)
+		opset(APLHZ, r0)
+		opset(APLHA, r0)
+		opset(APLD, r0)
+		opset(APLBZ, r0)
+	case APLXSSP:
+		opset(APLXSD, r0)
+	case APLXV:
+	case APLXVP:
+	case APMXVF32GERPP:
+		opset(APMXVF32GERPN, r0)
+		opset(APMXVF32GERNP, r0)
+		opset(APMXVF32GERNN, r0)
+		opset(APMXVF32GER, r0)
+	case APMXVF64GERPP:
+		opset(APMXVF64GERPN, r0)
+		opset(APMXVF64GERNP, r0)
+		opset(APMXVF64GERNN, r0)
+		opset(APMXVF64GER, r0)
+	case APMXVI16GER2SPP:
+		opset(APMXVI16GER2S, r0)
+		opset(APMXVI16GER2PP, r0)
+		opset(APMXVI16GER2, r0)
+		opset(APMXVF16GER2PP, r0)
+		opset(APMXVF16GER2PN, r0)
+		opset(APMXVF16GER2NP, r0)
+		opset(APMXVF16GER2NN, r0)
+		opset(APMXVF16GER2, r0)
+		opset(APMXVBF16GER2PP, r0)
+		opset(APMXVBF16GER2PN, r0)
+		opset(APMXVBF16GER2NP, r0)
+		opset(APMXVBF16GER2NN, r0)
+		opset(APMXVBF16GER2, r0)
+	case APMXVI4GER8PP:
+		opset(APMXVI4GER8, r0)
+	case APMXVI8GER4SPP:
+		opset(APMXVI8GER4PP, r0)
+		opset(APMXVI8GER4, r0)
+	case APNOP:
+	case APSTFS:
+		opset(APSTFD, r0)
+	case APSTQ:
+	case APSTW:
+		opset(APSTH, r0)
+		opset(APSTD, r0)
+		opset(APSTB, r0)
+	case APSTXSSP:
+		opset(APSTXSD, r0)
+	case APSTXV:
+	case APSTXVP:
+	case ASETNBCR:
+		opset(ASETNBC, r0)
+		opset(ASETBCR, r0)
+		opset(ASETBC, r0)
+	case ASTXVP:
+	case ASTXVPX:
+	case ASTXVRWX:
+		opset(ASTXVRHX, r0)
+		opset(ASTXVRDX, r0)
+		opset(ASTXVRBX, r0)
+	case AVCLRRB:
+		opset(AVCLRLB, r0)
+	case AVCMPUQ:
+		opset(AVCMPSQ, r0)
+	case AVCNTMBW:
+		opset(AVCNTMBH, r0)
+		opset(AVCNTMBD, r0)
+		opset(AVCNTMBB, r0)
+	case AVEXTDUWVRX:
+		opset(AVEXTDUWVLX, r0)
+		opset(AVEXTDUHVRX, r0)
+		opset(AVEXTDUHVLX, r0)
+		opset(AVEXTDUBVRX, r0)
+		opset(AVEXTDUBVLX, r0)
+		opset(AVEXTDDVRX, r0)
+		opset(AVEXTDDVLX, r0)
+	case AVEXTRACTWM:
+		opset(AVEXTRACTQM, r0)
+		opset(AVEXTRACTHM, r0)
+		opset(AVEXTRACTDM, r0)
+		opset(AVEXTRACTBM, r0)
+	case AVGNB:
+	case AVINSW:
+		opset(AVINSD, r0)
+	case AVINSWRX:
+		opset(AVINSWLX, r0)
+		opset(AVINSHRX, r0)
+		opset(AVINSHLX, r0)
+		opset(AVINSDRX, r0)
+		opset(AVINSDLX, r0)
+		opset(AVINSBRX, r0)
+		opset(AVINSBLX, r0)
+	case AVINSWVRX:
+		opset(AVINSWVLX, r0)
+		opset(AVINSHVRX, r0)
+		opset(AVINSHVLX, r0)
+		opset(AVINSBVRX, r0)
+		opset(AVINSBVLX, r0)
+	case AVMSUMCUD:
+	case AVSRDBI:
+		opset(AVSLDBI, r0)
+	case AXSCVUQQP:
+		opset(AXSCVSQQP, r0)
+		opset(AXSCVQPUQZ, r0)
+		opset(AXSCVQPSQZ, r0)
+		opset(AVSTRIHRCC, r0)
+		opset(AVSTRIHR, r0)
+		opset(AVSTRIHLCC, r0)
+		opset(AVSTRIHL, r0)
+		opset(AVSTRIBRCC, r0)
+		opset(AVSTRIBR, r0)
+		opset(AVSTRIBLCC, r0)
+		opset(AVSTRIBL, r0)
+		opset(AVEXTSD2Q, r0)
+		opset(AVEXPANDWM, r0)
+		opset(AVEXPANDQM, r0)
+		opset(AVEXPANDHM, r0)
+		opset(AVEXPANDDM, r0)
+		opset(AVEXPANDBM, r0)
+	case AXSMINCQP:
+		opset(AXSMAXCQP, r0)
+		opset(AXSCMPGTQP, r0)
+		opset(AXSCMPGEQP, r0)
+		opset(AXSCMPEQQP, r0)
+		opset(AVSRQ, r0)
+		opset(AVSRAQ, r0)
+		opset(AVSLQ, r0)
+		opset(AVRLQNM, r0)
+		opset(AVRLQMI, r0)
+		opset(AVRLQ, r0)
+		opset(AVPEXTD, r0)
+		opset(AVPDEPD, r0)
+		opset(AVMULOUD, r0)
+		opset(AVMULOSD, r0)
+		opset(AVMULLD, r0)
+		opset(AVMULHUW, r0)
+		opset(AVMULHUD, r0)
+		opset(AVMULHSW, r0)
+		opset(AVMULHSD, r0)
+		opset(AVMULEUD, r0)
+		opset(AVMULESD, r0)
+		opset(AVMODUW, r0)
+		opset(AVMODUQ, r0)
+		opset(AVMODUD, r0)
+		opset(AVMODSW, r0)
+		opset(AVMODSQ, r0)
+		opset(AVMODSD, r0)
+		opset(AVDIVUW, r0)
+		opset(AVDIVUQ, r0)
+		opset(AVDIVUD, r0)
+		opset(AVDIVSW, r0)
+		opset(AVDIVSQ, r0)
+		opset(AVDIVSD, r0)
+		opset(AVDIVEUW, r0)
+		opset(AVDIVEUQ, r0)
+		opset(AVDIVEUD, r0)
+		opset(AVDIVESW, r0)
+		opset(AVDIVESQ, r0)
+		opset(AVDIVESD, r0)
+		opset(AVCTZDM, r0)
+		opset(AVCMPGTUQCC, r0)
+		opset(AVCMPGTUQ, r0)
+		opset(AVCMPGTSQCC, r0)
+		opset(AVCMPGTSQ, r0)
+		opset(AVCMPEQUQCC, r0)
+		opset(AVCMPEQUQ, r0)
+		opset(AVCLZDM, r0)
+		opset(AVCFUGED, r0)
+	case AXVCVSPBF16:
+		opset(AXVCVBF16SPN, r0)
+	case AXVI8GER4SPP:
+		opset(AXVI8GER4PP, r0)
+		opset(AXVI8GER4, r0)
+		opset(AXVI4GER8PP, r0)
+		opset(AXVI4GER8, r0)
+		opset(AXVI16GER2SPP, r0)
+		opset(AXVI16GER2S, r0)
+		opset(AXVI16GER2PP, r0)
+		opset(AXVI16GER2, r0)
+		opset(AXVF64GERPP, r0)
+		opset(AXVF64GERPN, r0)
+		opset(AXVF64GERNP, r0)
+		opset(AXVF64GERNN, r0)
+		opset(AXVF64GER, r0)
+		opset(AXVF32GERPP, r0)
+		opset(AXVF32GERPN, r0)
+		opset(AXVF32GERNP, r0)
+		opset(AXVF32GERNN, r0)
+		opset(AXVF32GER, r0)
+		opset(AXVF16GER2PP, r0)
+		opset(AXVF16GER2PN, r0)
+		opset(AXVF16GER2NP, r0)
+		opset(AXVF16GER2NN, r0)
+		opset(AXVF16GER2, r0)
+		opset(AXVBF16GER2PP, r0)
+		opset(AXVBF16GER2PN, r0)
+		opset(AXVBF16GER2NP, r0)
+		opset(AXVBF16GER2NN, r0)
+		opset(AXVBF16GER2, r0)
+	case AXVTLSBB:
+	case AXXBLENDVW:
+		opset(AXXBLENDVH, r0)
+		opset(AXXBLENDVD, r0)
+		opset(AXXBLENDVB, r0)
+	case AXXEVAL:
+	case AXXGENPCVWM:
+		opset(AXXGENPCVHM, r0)
+		opset(AXXGENPCVDM, r0)
+		opset(AXXGENPCVBM, r0)
+	case AXXPERMX:
+	case AXXSETACCZ:
+		opset(AXXMTACC, r0)
+		opset(AXXMFACC, r0)
+	case AXXSPLTI32DX:
+	case AXXSPLTIW:
+		opset(AXXSPLTIDP, r0)
+	default:
+		return false
+	}
+	return true
+}
diff --git a/src/cmd/internal/obj/ppc64/asm_test.go b/src/cmd/internal/obj/ppc64/asm_test.go
index c16d4a6..89fc9ba 100644
--- a/src/cmd/internal/obj/ppc64/asm_test.go
+++ b/src/cmd/internal/obj/ppc64/asm_test.go
@@ -6,18 +6,17 @@
 
 import (
 	"bytes"
-	"cmd/internal/obj"
-	"cmd/internal/objabi"
 	"fmt"
 	"internal/testenv"
-	"io/ioutil"
 	"math"
 	"os"
-	"os/exec"
 	"path/filepath"
 	"regexp"
 	"strings"
 	"testing"
+
+	"cmd/internal/obj"
+	"cmd/internal/objabi"
 )
 
 var platformEnvs = [][]string{
@@ -167,7 +166,7 @@
 func TestPfxAlign(t *testing.T) {
 	testenv.MustHaveGoBuild(t)
 
-	dir, err := ioutil.TempDir("", "testpfxalign")
+	dir, err := os.MkdirTemp("", "testpfxalign")
 	if err != nil {
 		t.Fatalf("could not create directory: %v", err)
 	}
@@ -188,11 +187,11 @@
 
 	for _, pgm := range pgms {
 		tmpfile := filepath.Join(dir, "x.s")
-		err = ioutil.WriteFile(tmpfile, pgm.text, 0644)
+		err = os.WriteFile(tmpfile, pgm.text, 0644)
 		if err != nil {
 			t.Fatalf("can't write output: %v\n", err)
 		}
-		cmd := exec.Command(testenv.GoToolPath(t), "tool", "asm", "-S", "-o", filepath.Join(dir, "test.o"), tmpfile)
+		cmd := testenv.Command(t, testenv.GoToolPath(t), "tool", "asm", "-S", "-o", filepath.Join(dir, "test.o"), tmpfile)
 		cmd.Env = append(os.Environ(), "GOOS=linux", "GOARCH=ppc64le")
 		out, err := cmd.CombinedOutput()
 		if err != nil {
@@ -217,7 +216,7 @@
 	}
 	testenv.MustHaveGoBuild(t)
 
-	dir, err := ioutil.TempDir("", "testlarge")
+	dir, err := os.MkdirTemp("", "testlarge")
 	if err != nil {
 		t.Fatalf("could not create directory: %v", err)
 	}
@@ -281,14 +280,14 @@
 		gen(buf, test.jmpinsn)
 
 		tmpfile := filepath.Join(dir, "x.s")
-		err = ioutil.WriteFile(tmpfile, buf.Bytes(), 0644)
+		err = os.WriteFile(tmpfile, buf.Bytes(), 0644)
 		if err != nil {
 			t.Fatalf("can't write output: %v\n", err)
 		}
 
 		// Test on all supported ppc64 platforms
 		for _, platenv := range platformEnvs {
-			cmd := exec.Command(testenv.GoToolPath(t), "tool", "asm", "-S", "-o", filepath.Join(dir, "test.o"), tmpfile)
+			cmd := testenv.Command(t, testenv.GoToolPath(t), "tool", "asm", "-S", "-o", filepath.Join(dir, "test.o"), tmpfile)
 			cmd.Env = append(os.Environ(), platenv...)
 			out, err := cmd.CombinedOutput()
 			if err != nil {
@@ -336,7 +335,7 @@
 
 	testenv.MustHaveGoBuild(t)
 
-	dir, err := ioutil.TempDir("", "testpcalign")
+	dir, err := os.MkdirTemp("", "testpcalign")
 	if err != nil {
 		t.Fatalf("could not create directory: %v", err)
 	}
@@ -345,13 +344,13 @@
 	// generate a test with valid uses of PCALIGN
 
 	tmpfile := filepath.Join(dir, "x.s")
-	err = ioutil.WriteFile(tmpfile, []byte(validPCAlignSrc), 0644)
+	err = os.WriteFile(tmpfile, []byte(validPCAlignSrc), 0644)
 	if err != nil {
 		t.Fatalf("can't write output: %v\n", err)
 	}
 
 	// build generated file without errors and assemble it
-	cmd := exec.Command(testenv.GoToolPath(t), "tool", "asm", "-o", filepath.Join(dir, "x.o"), "-S", tmpfile)
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "tool", "asm", "-o", filepath.Join(dir, "x.o"), "-S", tmpfile)
 	cmd.Env = append(os.Environ(), "GOARCH=ppc64le", "GOOS=linux")
 	out, err := cmd.CombinedOutput()
 	if err != nil {
@@ -385,13 +384,13 @@
 	// generate a test with invalid use of PCALIGN
 
 	tmpfile = filepath.Join(dir, "xi.s")
-	err = ioutil.WriteFile(tmpfile, []byte(invalidPCAlignSrc), 0644)
+	err = os.WriteFile(tmpfile, []byte(invalidPCAlignSrc), 0644)
 	if err != nil {
 		t.Fatalf("can't write output: %v\n", err)
 	}
 
 	// build test with errors and check for messages
-	cmd = exec.Command(testenv.GoToolPath(t), "tool", "asm", "-o", filepath.Join(dir, "xi.o"), "-S", tmpfile)
+	cmd = testenv.Command(t, testenv.GoToolPath(t), "tool", "asm", "-o", filepath.Join(dir, "xi.o"), "-S", tmpfile)
 	cmd.Env = append(os.Environ(), "GOARCH=ppc64le", "GOOS=linux")
 	out, err = cmd.CombinedOutput()
 	if !strings.Contains(string(out), "Unexpected alignment") {
@@ -469,6 +468,7 @@
 		{obj.Addr{Type: obj.TYPE_REG, Reg: REG_SPR0 + 8}, C_LR},
 		{obj.Addr{Type: obj.TYPE_REG, Reg: REG_SPR0 + 9}, C_CTR},
 		{obj.Addr{Type: obj.TYPE_REG, Reg: REG_FPSCR}, C_FPSCR},
+		{obj.Addr{Type: obj.TYPE_REG, Reg: REG_A1}, C_AREG},
 
 		// Memory type arguments.
 		{obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_GOTREF}, C_ADDR},
@@ -482,6 +482,7 @@
 		{obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_PARAM, Offset: BIG}, C_LOREG},
 		{obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_PARAM, Offset: -BIG - 33}, C_LOREG}, // 33 is FixedFrameSize-1
 		{obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_NONE}, C_ZOREG},
+		{obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_NONE, Index: REG_R4}, C_XOREG},
 		{obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_NONE, Offset: 1}, C_SOREG},
 		{obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_NONE, Offset: BIG}, C_LOREG},
 		{obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_NONE, Offset: -BIG - 33}, C_LOREG},
@@ -545,7 +546,7 @@
 		case int:
 			expect = []int{tst.output.(int), tst.output.(int), tst.output.(int), tst.output.(int)}
 		}
-		for i, _ := range ctxts {
+		for i := range ctxts {
 			if output := ctxts[i].aclass(&tst.arg); output != expect[i] {
 				t.Errorf("%s.aclass(%v) = %v, expected %v\n", name[i], tst.arg, DRconv(output), DRconv(expect[i]))
 			}
diff --git a/src/cmd/internal/obj/ppc64/doc.go b/src/cmd/internal/obj/ppc64/doc.go
index 48aff3c..28340e4 100644
--- a/src/cmd/internal/obj/ppc64/doc.go
+++ b/src/cmd/internal/obj/ppc64/doc.go
@@ -198,7 +198,7 @@
 32 bit values, 63 for 64 bit values). If the shift count is in a register, then
 only the low 5 or 6 bits of the register will be used as the shift count. The
 Go compiler will add appropriate code to compare the shift value to achieve the
-the correct result, and the assembler does not add extra checking.
+correct result, and the assembler does not add extra checking.
 
 Examples:
 
diff --git a/src/cmd/internal/obj/ppc64/list9.go b/src/cmd/internal/obj/ppc64/list9.go
index dda8d5a..451c162 100644
--- a/src/cmd/internal/obj/ppc64/list9.go
+++ b/src/cmd/internal/obj/ppc64/list9.go
@@ -36,7 +36,9 @@
 
 func init() {
 	obj.RegisterRegister(obj.RBasePPC64, REG_SPR0+1024, rconv)
-	obj.RegisterOpcode(obj.ABasePPC64, Anames)
+	// Note, the last entry in Anames is "LASTAOUT", it is not a real opcode.
+	obj.RegisterOpcode(obj.ABasePPC64, Anames[:len(Anames)-1])
+	obj.RegisterOpcode(AFIRSTGEN, GenAnames)
 }
 
 func rconv(r int) string {
@@ -67,6 +69,9 @@
 		crf := (r - REG_CR0LT) / 4
 		return fmt.Sprintf("CR%d%s", crf, bits[r%4])
 	}
+	if REG_A0 <= r && r <= REG_A7 {
+		return fmt.Sprintf("A%d", r-REG_A0)
+	}
 	if r == REG_CR {
 		return "CR"
 	}
diff --git a/src/cmd/internal/obj/ppc64/obj9.go b/src/cmd/internal/obj/ppc64/obj9.go
index 098f1cd..47ad85e 100644
--- a/src/cmd/internal/obj/ppc64/obj9.go
+++ b/src/cmd/internal/obj/ppc64/obj9.go
@@ -78,9 +78,12 @@
 			}
 		}
 
-		// Put >32-bit constants in memory and load them
 	case AMOVD:
-		if p.From.Type == obj.TYPE_CONST && p.From.Name == obj.NAME_NONE && p.From.Reg == 0 && int64(int32(p.From.Offset)) != p.From.Offset {
+		// 32b constants (signed and unsigned) can be generated via 1 or 2 instructions.
+		// All others must be placed in memory and loaded.
+		isS32 := int64(int32(p.From.Offset)) == p.From.Offset
+		isU32 := uint64(uint32(p.From.Offset)) == uint64(p.From.Offset)
+		if p.From.Type == obj.TYPE_CONST && p.From.Name == obj.NAME_NONE && p.From.Reg == 0 && !isS32 && !isU32 {
 			p.From.Type = obj.TYPE_MEM
 			p.From.Sym = ctxt.Int64Sym(p.From.Offset)
 			p.From.Name = obj.NAME_EXTERN
@@ -88,8 +91,8 @@
 		}
 	}
 
-	// Rewrite SUB constants into ADD.
 	switch p.As {
+	// Rewrite SUB constants into ADD.
 	case ASUBC:
 		if p.From.Type == obj.TYPE_CONST {
 			p.From.Offset = -p.From.Offset
@@ -107,7 +110,21 @@
 			p.From.Offset = -p.From.Offset
 			p.As = AADD
 		}
+
+	// To maintain backwards compatibility, we accept some 4 argument usage of
+	// several opcodes which was likely not intended, but did work. These are not
+	// added to optab to avoid the chance this behavior might be used with newer
+	// instructions.
+	//
+	// Rewrite argument ordering like "ADDEX R3, $3, R4, R5" into
+	//                                "ADDEX R3, R4, $3, R5"
+	case AVSHASIGMAW, AVSHASIGMAD, AADDEX, AXXSLDWI, AXXPERMDI:
+		if len(p.RestArgs) == 2 && p.Reg == 0 && p.RestArgs[0].Addr.Type == obj.TYPE_CONST && p.RestArgs[1].Addr.Type == obj.TYPE_REG {
+			p.Reg = p.RestArgs[1].Addr.Reg
+			p.RestArgs = p.RestArgs[:1]
+		}
 	}
+
 	if c.ctxt.Headtype == objabi.Haix {
 		c.rewriteToUseTOC(p)
 	} else if c.ctxt.Flag_dynlink {
@@ -460,8 +477,6 @@
 			ALBAR,
 			ASTBCCC,
 			ASTWCCC,
-			AECIWX,
-			AECOWX,
 			AEIEIO,
 			AICBI,
 			AISYNC,
@@ -1368,12 +1383,23 @@
 	return p
 }
 
+// MMA accumulator to/from instructions are slightly ambiguous since
+// the argument represents both source and destination, specified as
+// an accumulator. It is treated as a unary destination to simplify
+// the code generation in ppc64map.
+var unaryDst = map[obj.As]bool{
+	AXXSETACCZ: true,
+	AXXMTACC:   true,
+	AXXMFACC:   true,
+}
+
 var Linkppc64 = obj.LinkArch{
 	Arch:           sys.ArchPPC64,
 	Init:           buildop,
 	Preprocess:     preprocess,
 	Assemble:       span9,
 	Progedit:       progedit,
+	UnaryDst:       unaryDst,
 	DWARFRegisters: PPC64DWARFRegisters,
 }
 
@@ -1383,5 +1409,6 @@
 	Preprocess:     preprocess,
 	Assemble:       span9,
 	Progedit:       progedit,
+	UnaryDst:       unaryDst,
 	DWARFRegisters: PPC64DWARFRegisters,
 }
diff --git a/src/cmd/internal/obj/riscv/asm_test.go b/src/cmd/internal/obj/riscv/asm_test.go
index b23142d..c22428c 100644
--- a/src/cmd/internal/obj/riscv/asm_test.go
+++ b/src/cmd/internal/obj/riscv/asm_test.go
@@ -8,9 +8,7 @@
 	"bytes"
 	"fmt"
 	"internal/testenv"
-	"io/ioutil"
 	"os"
-	"os/exec"
 	"path/filepath"
 	"runtime"
 	"testing"
@@ -24,7 +22,7 @@
 	}
 	testenv.MustHaveGoBuild(t)
 
-	dir, err := ioutil.TempDir("", "testlargebranch")
+	dir, err := os.MkdirTemp("", "testlargebranch")
 	if err != nil {
 		t.Fatalf("Could not create directory: %v", err)
 	}
@@ -35,12 +33,12 @@
 	genLargeBranch(buf)
 
 	tmpfile := filepath.Join(dir, "x.s")
-	if err := ioutil.WriteFile(tmpfile, buf.Bytes(), 0644); err != nil {
+	if err := os.WriteFile(tmpfile, buf.Bytes(), 0644); err != nil {
 		t.Fatalf("Failed to write file: %v", err)
 	}
 
 	// Assemble generated file.
-	cmd := exec.Command(testenv.GoToolPath(t), "tool", "asm", "-o", filepath.Join(dir, "x.o"), tmpfile)
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "tool", "asm", "-o", filepath.Join(dir, "x.o"), tmpfile)
 	cmd.Env = append(os.Environ(), "GOARCH=riscv64", "GOOS=linux")
 	out, err := cmd.CombinedOutput()
 	if err != nil {
@@ -67,13 +65,13 @@
 	}
 	testenv.MustHaveGoBuild(t)
 
-	dir, err := ioutil.TempDir("", "testlargecall")
+	dir, err := os.MkdirTemp("", "testlargecall")
 	if err != nil {
 		t.Fatalf("could not create directory: %v", err)
 	}
 	defer os.RemoveAll(dir)
 
-	if err := ioutil.WriteFile(filepath.Join(dir, "go.mod"), []byte("module largecall"), 0644); err != nil {
+	if err := os.WriteFile(filepath.Join(dir, "go.mod"), []byte("module largecall"), 0644); err != nil {
 		t.Fatalf("Failed to write file: %v\n", err)
 	}
 	main := `package main
@@ -84,7 +82,7 @@
 func x()
 func y()
 `
-	if err := ioutil.WriteFile(filepath.Join(dir, "x.go"), []byte(main), 0644); err != nil {
+	if err := os.WriteFile(filepath.Join(dir, "x.go"), []byte(main), 0644); err != nil {
 		t.Fatalf("failed to write main: %v\n", err)
 	}
 
@@ -92,12 +90,12 @@
 	buf := bytes.NewBuffer(make([]byte, 0, 7000000))
 	genLargeCall(buf)
 
-	if err := ioutil.WriteFile(filepath.Join(dir, "x.s"), buf.Bytes(), 0644); err != nil {
+	if err := os.WriteFile(filepath.Join(dir, "x.s"), buf.Bytes(), 0644); err != nil {
 		t.Fatalf("Failed to write file: %v\n", err)
 	}
 
 	// Build generated files.
-	cmd := exec.Command(testenv.GoToolPath(t), "build", "-ldflags=-linkmode=internal")
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-ldflags=-linkmode=internal")
 	cmd.Dir = dir
 	cmd.Env = append(os.Environ(), "GOARCH=riscv64", "GOOS=linux")
 	out, err := cmd.CombinedOutput()
@@ -106,7 +104,7 @@
 	}
 
 	if runtime.GOARCH == "riscv64" && testenv.HasCGO() {
-		cmd := exec.Command(testenv.GoToolPath(t), "build", "-ldflags=-linkmode=external")
+		cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-ldflags=-linkmode=external")
 		cmd.Dir = dir
 		cmd.Env = append(os.Environ(), "GOARCH=riscv64", "GOOS=linux")
 		out, err := cmd.CombinedOutput()
@@ -130,16 +128,16 @@
 
 // Issue 20348.
 func TestNoRet(t *testing.T) {
-	dir, err := ioutil.TempDir("", "testnoret")
+	dir, err := os.MkdirTemp("", "testnoret")
 	if err != nil {
 		t.Fatal(err)
 	}
 	defer os.RemoveAll(dir)
 	tmpfile := filepath.Join(dir, "x.s")
-	if err := ioutil.WriteFile(tmpfile, []byte("TEXT ·stub(SB),$0-0\nNOP\n"), 0644); err != nil {
+	if err := os.WriteFile(tmpfile, []byte("TEXT ·stub(SB),$0-0\nNOP\n"), 0644); err != nil {
 		t.Fatal(err)
 	}
-	cmd := exec.Command(testenv.GoToolPath(t), "tool", "asm", "-o", filepath.Join(dir, "x.o"), tmpfile)
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "tool", "asm", "-o", filepath.Join(dir, "x.o"), tmpfile)
 	cmd.Env = append(os.Environ(), "GOARCH=riscv64", "GOOS=linux")
 	if out, err := cmd.CombinedOutput(); err != nil {
 		t.Errorf("%v\n%s", err, out)
@@ -147,7 +145,7 @@
 }
 
 func TestImmediateSplitting(t *testing.T) {
-	dir, err := ioutil.TempDir("", "testimmsplit")
+	dir, err := os.MkdirTemp("", "testimmsplit")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -190,10 +188,10 @@
 	MOVF	F6, 4096(X5)
 	MOVD	F6, 4096(X5)
 `
-	if err := ioutil.WriteFile(tmpfile, []byte(asm), 0644); err != nil {
+	if err := os.WriteFile(tmpfile, []byte(asm), 0644); err != nil {
 		t.Fatal(err)
 	}
-	cmd := exec.Command(testenv.GoToolPath(t), "tool", "asm", "-o", filepath.Join(dir, "x.o"), tmpfile)
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "tool", "asm", "-o", filepath.Join(dir, "x.o"), tmpfile)
 	cmd.Env = append(os.Environ(), "GOARCH=riscv64", "GOOS=linux")
 	if out, err := cmd.CombinedOutput(); err != nil {
 		t.Errorf("%v\n%s", err, out)
@@ -207,7 +205,7 @@
 
 	testenv.MustHaveGoBuild(t)
 
-	cmd := exec.Command(testenv.GoToolPath(t), "test")
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "test")
 	cmd.Dir = "testdata/testbranch"
 	if out, err := testenv.CleanCmdEnv(cmd).CombinedOutput(); err != nil {
 		t.Errorf("Branch test failed: %v\n%s", err, out)
diff --git a/src/cmd/internal/obj/riscv/obj.go b/src/cmd/internal/obj/riscv/obj.go
index 34aa923..95cd365 100644
--- a/src/cmd/internal/obj/riscv/obj.go
+++ b/src/cmd/internal/obj/riscv/obj.go
@@ -1715,7 +1715,7 @@
 	}
 
 	// LUI $high, TMP
-	// ADDI $low, TMP, TMP
+	// ADDIW $low, TMP, TMP
 	// <op> TMP, REG, TO
 	insLUI := &instruction{as: ALUI, rd: REG_TMP, imm: high}
 	insADDIW := &instruction{as: AADDIW, rd: REG_TMP, rs1: REG_TMP, imm: low}
diff --git a/src/cmd/internal/obj/s390x/asmz.go b/src/cmd/internal/obj/s390x/asmz.go
index 5760847..d8a36c4 100644
--- a/src/cmd/internal/obj/s390x/asmz.go
+++ b/src/cmd/internal/obj/s390x/asmz.go
@@ -4374,12 +4374,12 @@
 	return int32(c.vregoff(a))
 }
 
-// find if the displacement is within 12 bit
+// find if the displacement is within 12 bit.
 func isU12(displacement int32) bool {
 	return displacement >= 0 && displacement < DISP12
 }
 
-// zopload12 returns the RX op with 12 bit displacement for the given load
+// zopload12 returns the RX op with 12 bit displacement for the given load.
 func (c *ctxtz) zopload12(a obj.As) (uint32, bool) {
 	switch a {
 	case AFMOVD:
@@ -4390,7 +4390,7 @@
 	return 0, false
 }
 
-// zopload returns the RXY op for the given load
+// zopload returns the RXY op for the given load.
 func (c *ctxtz) zopload(a obj.As) uint32 {
 	switch a {
 	// fixed point load
@@ -4428,7 +4428,7 @@
 	return 0
 }
 
-// zopstore12 returns the RX op with 12 bit displacement for the given store
+// zopstore12 returns the RX op with 12 bit displacement for the given store.
 func (c *ctxtz) zopstore12(a obj.As) (uint32, bool) {
 	switch a {
 	case AFMOVD:
@@ -4445,7 +4445,7 @@
 	return 0, false
 }
 
-// zopstore returns the RXY op for the given store
+// zopstore returns the RXY op for the given store.
 func (c *ctxtz) zopstore(a obj.As) uint32 {
 	switch a {
 	// fixed point store
@@ -4477,7 +4477,7 @@
 	return 0
 }
 
-// zoprre returns the RRE op for the given a
+// zoprre returns the RRE op for the given a.
 func (c *ctxtz) zoprre(a obj.As) uint32 {
 	switch a {
 	case ACMP:
@@ -4495,7 +4495,7 @@
 	return 0
 }
 
-// zoprr returns the RR op for the given a
+// zoprr returns the RR op for the given a.
 func (c *ctxtz) zoprr(a obj.As) uint32 {
 	switch a {
 	case ACMPW:
@@ -4507,7 +4507,7 @@
 	return 0
 }
 
-// zopril returns the RIL op for the given a
+// zopril returns the RIL op for the given a.
 func (c *ctxtz) zopril(a obj.As) uint32 {
 	switch a {
 	case ACMP:
diff --git a/src/cmd/internal/obj/sym.go b/src/cmd/internal/obj/sym.go
index 40e5377..e5b052c 100644
--- a/src/cmd/internal/obj/sym.go
+++ b/src/cmd/internal/obj/sym.go
@@ -349,6 +349,7 @@
 		}
 	}
 	lists := [][]*LSym{ctxt.Text, ctxt.Data}
+	files := ctxt.PosTable.FileTable()
 	for _, list := range lists {
 		for _, s := range list {
 			if flag&traverseDefs != 0 {
@@ -365,7 +366,7 @@
 					f := func(parent *LSym, aux *LSym) {
 						fn(aux)
 					}
-					ctxt.traverseFuncAux(flag, s, f)
+					ctxt.traverseFuncAux(flag, s, f, files)
 				}
 			}
 			if flag&traversePcdata != 0 && s.Type == objabi.STEXT {
@@ -382,7 +383,7 @@
 	}
 }
 
-func (ctxt *Link) traverseFuncAux(flag traverseFlag, fsym *LSym, fn func(parent *LSym, aux *LSym)) {
+func (ctxt *Link) traverseFuncAux(flag traverseFlag, fsym *LSym, fn func(parent *LSym, aux *LSym), files []string) {
 	fninfo := fsym.Func()
 	pc := &fninfo.Pcln
 	if flag&traverseAux == 0 {
@@ -395,7 +396,6 @@
 			fn(fsym, d)
 		}
 	}
-	files := ctxt.PosTable.FileTable()
 	usedFiles := make([]goobj.CUFileIndex, 0, len(pc.UsedFiles))
 	for f := range pc.UsedFiles {
 		usedFiles = append(usedFiles, f)
@@ -410,7 +410,7 @@
 		if call.Func != nil {
 			fn(fsym, call.Func)
 		}
-		f, _ := linkgetlineFromPos(ctxt, call.Pos)
+		f, _ := ctxt.getFileSymbolAndLine(call.Pos)
 		if filesym := ctxt.Lookup(f); filesym != nil {
 			fn(fsym, filesym)
 		}
@@ -435,6 +435,7 @@
 // Traverse aux symbols, calling fn for each sym/aux pair.
 func (ctxt *Link) traverseAuxSyms(flag traverseFlag, fn func(parent *LSym, aux *LSym)) {
 	lists := [][]*LSym{ctxt.Text, ctxt.Data}
+	files := ctxt.PosTable.FileTable()
 	for _, list := range lists {
 		for _, s := range list {
 			if s.Gotype != nil {
@@ -445,7 +446,7 @@
 			if s.Type != objabi.STEXT {
 				continue
 			}
-			ctxt.traverseFuncAux(flag, s, fn)
+			ctxt.traverseFuncAux(flag, s, fn, files)
 		}
 	}
 }
diff --git a/src/cmd/internal/obj/util.go b/src/cmd/internal/obj/util.go
index 55b3dd2..b219a07 100644
--- a/src/cmd/internal/obj/util.go
+++ b/src/cmd/internal/obj/util.go
@@ -233,7 +233,7 @@
 	return buf.String()
 }
 
-// DconvDconvWithABIDetail accepts an argument 'a' within a prog 'p'
+// DconvWithABIDetail accepts an argument 'a' within a prog 'p'
 // and returns a string with a formatted version of the argument, in
 // which text symbols are rendered with explicit ABI selectors.
 func DconvWithABIDetail(p *Prog, a *Addr) string {
diff --git a/src/cmd/internal/obj/wasm/a.out.go b/src/cmd/internal/obj/wasm/a.out.go
index 72ecaa9..83ce0a6 100644
--- a/src/cmd/internal/obj/wasm/a.out.go
+++ b/src/cmd/internal/obj/wasm/a.out.go
@@ -231,6 +231,17 @@
 	AI64TruncSatF64S
 	AI64TruncSatF64U
 
+	AMemoryInit
+	ADataDrop
+	AMemoryCopy
+	AMemoryFill
+	ATableInit
+	AElemDrop
+	ATableCopy
+	ATableGrow
+	ATableSize
+	ATableFill
+
 	ALast // Sentinel: End of low-level WebAssembly instructions.
 
 	ARESUMEPOINT
diff --git a/src/cmd/internal/obj/wasm/anames.go b/src/cmd/internal/obj/wasm/anames.go
index 9412384..c9bc15d 100644
--- a/src/cmd/internal/obj/wasm/anames.go
+++ b/src/cmd/internal/obj/wasm/anames.go
@@ -195,6 +195,16 @@
 	"I64TruncSatF32U",
 	"I64TruncSatF64S",
 	"I64TruncSatF64U",
+	"MemoryInit",
+	"DataDrop",
+	"MemoryCopy",
+	"MemoryFill",
+	"TableInit",
+	"ElemDrop",
+	"TableCopy",
+	"TableGrow",
+	"TableSize",
+	"TableFill",
 	"Last",
 	"RESUMEPOINT",
 	"CALLNORESUME",
diff --git a/src/cmd/internal/obj/wasm/wasmobj.go b/src/cmd/internal/obj/wasm/wasmobj.go
index 1c726f7..9b0aabe 100644
--- a/src/cmd/internal/obj/wasm/wasmobj.go
+++ b/src/cmd/internal/obj/wasm/wasmobj.go
@@ -379,7 +379,7 @@
 			p = appendp(p, AGet, regAddr(REGG))
 			p = appendp(p, AI32WrapI64)
 			p = appendp(p, AI32Load, constAddr(2*int64(ctxt.Arch.PtrSize))) // G.stackguard0
-			p = appendp(p, AI32Const, constAddr(int64(framesize)-objabi.StackSmall))
+			p = appendp(p, AI32Const, constAddr(framesize-objabi.StackSmall))
 			p = appendp(p, AI32Add)
 			p = appendp(p, AI32LeU)
 		}
@@ -577,18 +577,18 @@
 	for p := s.Func().Text; p != nil; p = p.Link {
 		switch p.From.Name {
 		case obj.NAME_AUTO:
-			p.From.Offset += int64(framesize)
+			p.From.Offset += framesize
 		case obj.NAME_PARAM:
 			p.From.Reg = REG_SP
-			p.From.Offset += int64(framesize) + 8 // parameters are after the frame and the 8-byte return address
+			p.From.Offset += framesize + 8 // parameters are after the frame and the 8-byte return address
 		}
 
 		switch p.To.Name {
 		case obj.NAME_AUTO:
-			p.To.Offset += int64(framesize)
+			p.To.Offset += framesize
 		case obj.NAME_PARAM:
 			p.To.Reg = REG_SP
-			p.To.Offset += int64(framesize) + 8 // parameters are after the frame and the 8-byte return address
+			p.To.Offset += framesize + 8 // parameters are after the frame and the 8-byte return address
 		}
 
 		switch p.As {
@@ -799,8 +799,6 @@
 	"wasm_export_resume":     true,
 	"wasm_export_getsp":      true,
 	"wasm_pc_f_loop":         true,
-	"runtime.wasmMove":       true,
-	"runtime.wasmZero":       true,
 	"runtime.wasmDiv":        true,
 	"runtime.wasmTruncS":     true,
 	"runtime.wasmTruncU":     true,
@@ -844,7 +842,7 @@
 	// Some functions use a special calling convention.
 	switch s.Name {
 	case "_rt0_wasm_js", "wasm_export_run", "wasm_export_resume", "wasm_export_getsp", "wasm_pc_f_loop",
-		"runtime.wasmMove", "runtime.wasmZero", "runtime.wasmDiv", "runtime.wasmTruncS", "runtime.wasmTruncU", "memeqbody":
+		"runtime.wasmDiv", "runtime.wasmTruncS", "runtime.wasmTruncU", "memeqbody":
 		varDecls = []*varDecl{}
 		useAssemblyRegMap()
 	case "memchr", "memcmp":
@@ -1088,7 +1086,11 @@
 			writeUleb128(w, align(p.As))
 			writeUleb128(w, uint64(p.To.Offset))
 
-		case ACurrentMemory, AGrowMemory:
+		case ACurrentMemory, AGrowMemory, AMemoryFill:
+			w.WriteByte(0x00)
+
+		case AMemoryCopy:
+			w.WriteByte(0x00)
 			w.WriteByte(0x00)
 
 		}
diff --git a/src/cmd/internal/obj/x86/asm6.go b/src/cmd/internal/obj/x86/asm6.go
index b625845..953eedc 100644
--- a/src/cmd/internal/obj/x86/asm6.go
+++ b/src/cmd/internal/obj/x86/asm6.go
@@ -3612,7 +3612,7 @@
 		goto bad
 	}
 
-	if a.Index != REG_NONE && a.Index != REG_TLS {
+	if a.Index != REG_NONE && a.Index != REG_TLS && !(REG_CS <= a.Index && a.Index <= REG_GS) {
 		base := int(a.Reg)
 		switch a.Name {
 		case obj.NAME_EXTERN,
@@ -3724,7 +3724,8 @@
 	}
 
 	if REG_AX <= base && base <= REG_R15 {
-		if a.Index == REG_TLS && !ctxt.Flag_shared && !isAndroid {
+		if a.Index == REG_TLS && !ctxt.Flag_shared && !isAndroid &&
+			!(ctxt.Headtype == objabi.Hwindows && ctxt.Arch.Family == sys.AMD64) {
 			rel = obj.Reloc{}
 			rel.Type = objabi.R_TLS_LE
 			rel.Siz = 4
@@ -3951,10 +3952,7 @@
 		return true
 	}
 
-	if a.Index == REG_AX {
-		return true
-	}
-	return false
+	return a.Index == REG_AX
 }
 
 func subreg(p *obj.Prog, from int, to int) {
@@ -5208,21 +5206,6 @@
 						ab.Put2(0x64, // FS
 							0x8B)
 						ab.asmand(ctxt, cursym, p, &pp.From, &p.To)
-
-					case objabi.Hwindows:
-						// Windows TLS base is always 0x28(GS).
-						pp.From = p.From
-
-						pp.From.Type = obj.TYPE_MEM
-						pp.From.Name = obj.NAME_NONE
-						pp.From.Reg = REG_GS
-						pp.From.Offset = 0x28
-						pp.From.Index = REG_NONE
-						pp.From.Scale = 0
-						ab.rexflag |= Pw
-						ab.Put2(0x65, // GS
-							0x8B)
-						ab.asmand(ctxt, cursym, p, &pp.From, &p.To)
 					}
 				}
 				return
diff --git a/src/cmd/internal/obj/x86/obj6.go b/src/cmd/internal/obj/x86/obj6.go
index a82285a..85a4260 100644
--- a/src/cmd/internal/obj/x86/obj6.go
+++ b/src/cmd/internal/obj/x86/obj6.go
@@ -158,16 +158,33 @@
 		}
 	}
 
-	// Android uses a tls offset determined at runtime. Rewrite
+	// Android and Win64 use a tls offset determined at runtime. Rewrite
 	//	MOVQ TLS, BX
 	// to
 	//	MOVQ runtime.tls_g(SB), BX
-	if isAndroid && (p.As == AMOVQ || p.As == AMOVL) && p.From.Type == obj.TYPE_REG && p.From.Reg == REG_TLS && p.To.Type == obj.TYPE_REG && REG_AX <= p.To.Reg && p.To.Reg <= REG_R15 {
+	if (isAndroid || (ctxt.Headtype == objabi.Hwindows && ctxt.Arch.Family == sys.AMD64)) &&
+		(p.As == AMOVQ || p.As == AMOVL) && p.From.Type == obj.TYPE_REG && p.From.Reg == REG_TLS && p.To.Type == obj.TYPE_REG && REG_AX <= p.To.Reg && p.To.Reg <= REG_R15 {
 		p.From.Type = obj.TYPE_MEM
 		p.From.Name = obj.NAME_EXTERN
 		p.From.Reg = REG_NONE
 		p.From.Sym = ctxt.Lookup("runtime.tls_g")
 		p.From.Index = REG_NONE
+		if ctxt.Headtype == objabi.Hwindows {
+			// Win64 requires an additional indirection
+			// to retrieve the TLS pointer,
+			// as runtime.tls_g contains the TLS offset from GS.
+			// add
+			//	MOVQ 0(BX)(GS*1), BX
+			q := obj.Appendp(p, newprog)
+			q.As = p.As
+			q.From = obj.Addr{}
+			q.From.Type = obj.TYPE_MEM
+			q.From.Reg = p.To.Reg
+			q.From.Index = REG_GS
+			q.From.Scale = 1
+			q.From.Offset = 0
+			q.To = p.To
+		}
 	}
 
 	// TODO: Remove.
diff --git a/src/cmd/internal/obj/x86/obj6_test.go b/src/cmd/internal/obj/x86/obj6_test.go
index f9dd584..d1246be 100644
--- a/src/cmd/internal/obj/x86/obj6_test.go
+++ b/src/cmd/internal/obj/x86/obj6_test.go
@@ -1,3 +1,7 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
 package x86_test
 
 import (
@@ -5,9 +9,7 @@
 	"bytes"
 	"fmt"
 	"internal/testenv"
-	"io/ioutil"
 	"os"
-	"os/exec"
 	"path/filepath"
 	"regexp"
 	"strconv"
@@ -81,7 +83,7 @@
 }
 
 func asmOutput(t *testing.T, s string) []byte {
-	tmpdir, err := ioutil.TempDir("", "progedittest")
+	tmpdir, err := os.MkdirTemp("", "progedittest")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -95,7 +97,7 @@
 	if err != nil {
 		t.Fatal(err)
 	}
-	cmd := exec.Command(
+	cmd := testenv.Command(t,
 		testenv.GoToolPath(t), "tool", "asm", "-S", "-dynlink",
 		"-o", filepath.Join(tmpdir, "output.6"), tmpfile.Name())
 
diff --git a/src/cmd/internal/obj/x86/pcrelative_test.go b/src/cmd/internal/obj/x86/pcrelative_test.go
index 487a65d..3827100 100644
--- a/src/cmd/internal/obj/x86/pcrelative_test.go
+++ b/src/cmd/internal/obj/x86/pcrelative_test.go
@@ -8,9 +8,7 @@
 	"bytes"
 	"fmt"
 	"internal/testenv"
-	"io/ioutil"
 	"os"
-	"os/exec"
 	"path/filepath"
 	"testing"
 )
@@ -33,12 +31,12 @@
 `
 
 func objdumpOutput(t *testing.T, mname, source string) []byte {
-	tmpdir, err := ioutil.TempDir("", mname)
+	tmpdir, err := os.MkdirTemp("", mname)
 	if err != nil {
 		t.Fatal(err)
 	}
 	defer os.RemoveAll(tmpdir)
-	err = ioutil.WriteFile(filepath.Join(tmpdir, "go.mod"), []byte(fmt.Sprintf("module %s\n", mname)), 0666)
+	err = os.WriteFile(filepath.Join(tmpdir, "go.mod"), []byte(fmt.Sprintf("module %s\n", mname)), 0666)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -61,7 +59,7 @@
 		t.Fatal(err)
 	}
 
-	cmd := exec.Command(
+	cmd := testenv.Command(t,
 		testenv.GoToolPath(t), "build", "-o",
 		filepath.Join(tmpdir, "output"))
 
@@ -73,7 +71,7 @@
 	if err != nil {
 		t.Fatalf("error %s output %s", err, out)
 	}
-	cmd2 := exec.Command(
+	cmd2 := testenv.Command(t,
 		testenv.GoToolPath(t), "tool", "objdump", "-s", "testASM",
 		filepath.Join(tmpdir, "output"))
 	cmd2.Env = cmd.Env
diff --git a/src/cmd/internal/objabi/flag.go b/src/cmd/internal/objabi/flag.go
index acb2dd5..847ed48 100644
--- a/src/cmd/internal/objabi/flag.go
+++ b/src/cmd/internal/objabi/flag.go
@@ -5,12 +5,10 @@
 package objabi
 
 import (
-	"bytes"
 	"flag"
 	"fmt"
 	"internal/buildcfg"
 	"io"
-	"io/ioutil"
 	"log"
 	"os"
 	"reflect"
@@ -58,7 +56,7 @@
 				out = make([]string, 0, len(in)*2)
 				out = append(out, in[:i]...)
 			}
-			slurp, err := ioutil.ReadFile(s[1:])
+			slurp, err := os.ReadFile(s[1:])
 			if err != nil {
 				log.Fatal(err)
 			}
@@ -179,8 +177,7 @@
 		return arg
 	}
 
-	// We can't use strings.Builder as this must work at bootstrap.
-	var b bytes.Buffer
+	var b strings.Builder
 	var wasBS bool
 	for _, r := range arg {
 		if wasBS {
@@ -206,16 +203,16 @@
 }
 
 type debugField struct {
-	name string
-	help string
-	val  interface{} // *int or *string
+	name         string
+	help         string
+	concurrentOk bool        // true if this field/flag is compatible with concurrent compilation
+	val          interface{} // *int or *string
 }
 
 type DebugFlag struct {
-	tab map[string]debugField
-	any *bool
-
-	debugSSA DebugSSA
+	tab          map[string]debugField
+	concurrentOk *bool    // this is non-nil only for compiler's DebugFlags, but only compiler has concurrent:ok fields
+	debugSSA     DebugSSA // this is non-nil only for compiler's DebugFlags.
 }
 
 // A DebugSSA function is called to set a -d ssa/... option.
@@ -247,12 +244,12 @@
 	for i := 0; i < t.NumField(); i++ {
 		f := t.Field(i)
 		ptr := v.Field(i).Addr().Interface()
-		if f.Name == "Any" {
+		if f.Name == "ConcurrentOk" {
 			switch ptr := ptr.(type) {
 			default:
-				panic("debug.Any must have type bool")
+				panic("debug.ConcurrentOk must have type bool")
 			case *bool:
-				flag.any = ptr
+				flag.concurrentOk = ptr
 			}
 			continue
 		}
@@ -261,13 +258,15 @@
 		if help == "" {
 			panic(fmt.Sprintf("debug.%s is missing help text", f.Name))
 		}
+		concurrent := f.Tag.Get("concurrent")
+
 		switch ptr.(type) {
 		default:
 			panic(fmt.Sprintf("debug.%s has invalid type %v (must be int or string)", f.Name, f.Type))
 		case *int, *string:
 			// ok
 		}
-		flag.tab[name] = debugField{name, help, ptr}
+		flag.tab[name] = debugField{name, help, concurrent == "ok", ptr}
 	}
 
 	return flag
@@ -277,9 +276,6 @@
 	if debugstr == "" {
 		return nil
 	}
-	if f.any != nil {
-		*f.any = true
-	}
 	for _, name := range strings.Split(debugstr, ",") {
 		if name == "" {
 			continue
@@ -335,6 +331,10 @@
 			default:
 				panic("bad debugtab type")
 			}
+			// assembler DebugFlags don't have a ConcurrentOk field to reset, so check against that.
+			if !t.concurrentOk && f.concurrentOk != nil {
+				*f.concurrentOk = false
+			}
 		} else if f.debugSSA != nil && strings.HasPrefix(name, "ssa/") {
 			// expect form ssa/phase/flag
 			// e.g. -d=ssa/generic_cse/time
@@ -349,6 +349,11 @@
 			if err != "" {
 				log.Fatalf(err)
 			}
+			// Setting this false for -d=ssa/... preserves old behavior
+			// of turning off concurrency for any debug flags.
+			// It's not known for sure if this is necessary, but it is safe.
+			*f.concurrentOk = false
+
 		} else {
 			return fmt.Errorf("unknown debug key %s\n", name)
 		}
diff --git a/src/cmd/internal/objabi/head.go b/src/cmd/internal/objabi/head.go
index 48ff292..763910f 100644
--- a/src/cmd/internal/objabi/head.go
+++ b/src/cmd/internal/objabi/head.go
@@ -80,8 +80,8 @@
 	return nil
 }
 
-func (h *HeadType) String() string {
-	switch *h {
+func (h HeadType) String() string {
+	switch h {
 	case Haix:
 		return "aix"
 	case Hdarwin:
@@ -105,5 +105,5 @@
 	case Hwindows:
 		return "windows"
 	}
-	return fmt.Sprintf("HeadType(%d)", *h)
+	return fmt.Sprintf("HeadType(%d)", h)
 }
diff --git a/src/cmd/internal/objabi/reloctype.go b/src/cmd/internal/objabi/reloctype.go
index f60cac2..2bc7b2d 100644
--- a/src/cmd/internal/objabi/reloctype.go
+++ b/src/cmd/internal/objabi/reloctype.go
@@ -154,6 +154,22 @@
 	// adrp followed by another add instruction.
 	R_ARM64_PCREL
 
+	// R_ARM64_PCREL_LDST8 resolves a PC-relative addresses instruction sequence, usually an
+	// adrp followed by a LD8 or ST8 instruction.
+	R_ARM64_PCREL_LDST8
+
+	// R_ARM64_PCREL_LDST16 resolves a PC-relative addresses instruction sequence, usually an
+	// adrp followed by a LD16 or ST16 instruction.
+	R_ARM64_PCREL_LDST16
+
+	// R_ARM64_PCREL_LDST32 resolves a PC-relative addresses instruction sequence, usually an
+	// adrp followed by a LD32 or ST32 instruction.
+	R_ARM64_PCREL_LDST32
+
+	// R_ARM64_PCREL_LDST64 resolves a PC-relative addresses instruction sequence, usually an
+	// adrp followed by a LD64 or ST64 instruction.
+	R_ARM64_PCREL_LDST64
+
 	// R_ARM64_LDST8 sets a LD/ST immediate value to bits [11:0] of a local address.
 	R_ARM64_LDST8
 
@@ -192,6 +208,15 @@
 	// (usually called RB in X-form instructions) is assumed to be R13.
 	R_POWER_TLS
 
+	// R_POWER_TLS_IE_PCREL34 is similar to R_POWER_TLS_IE, but marks a single MOVD
+	// which has been assembled as a single prefixed load doubleword without using the
+	// TOC.
+	R_POWER_TLS_IE_PCREL34
+
+	// R_POWER_TLS_LE_TPREL34 is similar to R_POWER_TLS_LE, but computes an offset from
+	// the thread pointer in one prefixed instruction.
+	R_POWER_TLS_LE_TPREL34
+
 	// R_ADDRPOWER_DS is similar to R_ADDRPOWER above, but assumes the second
 	// instruction is a "DS-form" instruction, which has an immediate field occupying
 	// bits [15:2] of the instruction word. Bits [15:2] of the address of the
@@ -199,11 +224,14 @@
 	// bits of the address are not 0.
 	R_ADDRPOWER_DS
 
-	// R_ADDRPOWER_PCREL relocates a D-form, DS-form instruction sequence like
-	// R_ADDRPOWER_DS but inserts the offset of the GOT slot for the referenced symbol
-	// from the TOC rather than the symbol's address.
+	// R_ADDRPOWER_GOT relocates a D-form + DS-form instruction sequence by inserting
+	// a relative displacement of referenced symbol's GOT entry to the TOC pointer.
 	R_ADDRPOWER_GOT
 
+	// R_ADDRPOWER_GOT_PCREL34 is identical to R_ADDRPOWER_GOT, but uses a PC relative
+	// sequence to generate a GOT symbol addresss.
+	R_ADDRPOWER_GOT_PCREL34
+
 	// R_ADDRPOWER_PCREL relocates two D-form instructions like R_ADDRPOWER, but
 	// inserts the displacement from the place being relocated to the address of the
 	// relocated symbol instead of just its address.
@@ -214,11 +242,21 @@
 	// rather than the symbol's address.
 	R_ADDRPOWER_TOCREL
 
-	// R_ADDRPOWER_TOCREL relocates a D-form, DS-form instruction sequence like
+	// R_ADDRPOWER_TOCREL_DS relocates a D-form, DS-form instruction sequence like
 	// R_ADDRPOWER_DS but inserts the offset from the TOC to the address of the
 	// relocated symbol rather than the symbol's address.
 	R_ADDRPOWER_TOCREL_DS
 
+	// R_ADDRPOWER_D34 relocates a single prefixed D-form load/store operation.  All
+	// prefixed forms are D form. The high 18 bits are stored in the prefix,
+	// and the low 16 are stored in the suffix. The address is absolute.
+	R_ADDRPOWER_D34
+
+	// R_ADDRPOWER_PCREL34 relates a single prefixed D-form load/store/add operation.
+	// All prefixed forms are D form. The resulting address is relative to the
+	// PC. It is a signed 34 bit offset.
+	R_ADDRPOWER_PCREL34
+
 	// RISC-V.
 
 	// R_RISCV_CALL relocates a J-type instruction with a 21 bit PC-relative
diff --git a/src/cmd/internal/objabi/reloctype_string.go b/src/cmd/internal/objabi/reloctype_string.go
index 9756f2a..9ce37d0 100644
--- a/src/cmd/internal/objabi/reloctype_string.go
+++ b/src/cmd/internal/objabi/reloctype_string.go
@@ -45,42 +45,51 @@
 	_ = x[R_ARM64_GOTPCREL-35]
 	_ = x[R_ARM64_GOT-36]
 	_ = x[R_ARM64_PCREL-37]
-	_ = x[R_ARM64_LDST8-38]
-	_ = x[R_ARM64_LDST16-39]
-	_ = x[R_ARM64_LDST32-40]
-	_ = x[R_ARM64_LDST64-41]
-	_ = x[R_ARM64_LDST128-42]
-	_ = x[R_POWER_TLS_LE-43]
-	_ = x[R_POWER_TLS_IE-44]
-	_ = x[R_POWER_TLS-45]
-	_ = x[R_ADDRPOWER_DS-46]
-	_ = x[R_ADDRPOWER_GOT-47]
-	_ = x[R_ADDRPOWER_PCREL-48]
-	_ = x[R_ADDRPOWER_TOCREL-49]
-	_ = x[R_ADDRPOWER_TOCREL_DS-50]
-	_ = x[R_RISCV_CALL-51]
-	_ = x[R_RISCV_CALL_TRAMP-52]
-	_ = x[R_RISCV_PCREL_ITYPE-53]
-	_ = x[R_RISCV_PCREL_STYPE-54]
-	_ = x[R_RISCV_TLS_IE_ITYPE-55]
-	_ = x[R_RISCV_TLS_IE_STYPE-56]
-	_ = x[R_PCRELDBL-57]
-	_ = x[R_ADDRLOONG64-58]
-	_ = x[R_ADDRLOONG64U-59]
-	_ = x[R_ADDRLOONG64TLS-60]
-	_ = x[R_ADDRLOONG64TLSU-61]
-	_ = x[R_CALLLOONG64-62]
-	_ = x[R_JMPLOONG64-63]
-	_ = x[R_ADDRMIPSU-64]
-	_ = x[R_ADDRMIPSTLS-65]
-	_ = x[R_ADDRCUOFF-66]
-	_ = x[R_WASMIMPORT-67]
-	_ = x[R_XCOFFREF-68]
+	_ = x[R_ARM64_PCREL_LDST8-38]
+	_ = x[R_ARM64_PCREL_LDST16-39]
+	_ = x[R_ARM64_PCREL_LDST32-40]
+	_ = x[R_ARM64_PCREL_LDST64-41]
+	_ = x[R_ARM64_LDST8-42]
+	_ = x[R_ARM64_LDST16-43]
+	_ = x[R_ARM64_LDST32-44]
+	_ = x[R_ARM64_LDST64-45]
+	_ = x[R_ARM64_LDST128-46]
+	_ = x[R_POWER_TLS_LE-47]
+	_ = x[R_POWER_TLS_IE-48]
+	_ = x[R_POWER_TLS-49]
+	_ = x[R_POWER_TLS_IE_PCREL34-50]
+	_ = x[R_POWER_TLS_LE_TPREL34-51]
+	_ = x[R_ADDRPOWER_DS-52]
+	_ = x[R_ADDRPOWER_GOT-53]
+	_ = x[R_ADDRPOWER_GOT_PCREL34-54]
+	_ = x[R_ADDRPOWER_PCREL-55]
+	_ = x[R_ADDRPOWER_TOCREL-56]
+	_ = x[R_ADDRPOWER_TOCREL_DS-57]
+	_ = x[R_ADDRPOWER_D34-58]
+	_ = x[R_ADDRPOWER_PCREL34-59]
+	_ = x[R_RISCV_CALL-60]
+	_ = x[R_RISCV_CALL_TRAMP-61]
+	_ = x[R_RISCV_PCREL_ITYPE-62]
+	_ = x[R_RISCV_PCREL_STYPE-63]
+	_ = x[R_RISCV_TLS_IE_ITYPE-64]
+	_ = x[R_RISCV_TLS_IE_STYPE-65]
+	_ = x[R_PCRELDBL-66]
+	_ = x[R_ADDRLOONG64-67]
+	_ = x[R_ADDRLOONG64U-68]
+	_ = x[R_ADDRLOONG64TLS-69]
+	_ = x[R_ADDRLOONG64TLSU-70]
+	_ = x[R_CALLLOONG64-71]
+	_ = x[R_JMPLOONG64-72]
+	_ = x[R_ADDRMIPSU-73]
+	_ = x[R_ADDRMIPSTLS-74]
+	_ = x[R_ADDRCUOFF-75]
+	_ = x[R_WASMIMPORT-76]
+	_ = x[R_XCOFFREF-77]
 }
 
-const _RelocType_name = "R_ADDRR_ADDRPOWERR_ADDRARM64R_ADDRMIPSR_ADDROFFR_SIZER_CALLR_CALLARMR_CALLARM64R_CALLINDR_CALLPOWERR_CALLMIPSR_CONSTR_PCRELR_TLS_LER_TLS_IER_GOTOFFR_PLT0R_PLT1R_PLT2R_USEFIELDR_USETYPER_USEIFACER_USEIFACEMETHODR_USEGENERICIFACEMETHODR_METHODOFFR_KEEPR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFSECREFR_DWARFFILEREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_ARM64_GOTR_ARM64_PCRELR_ARM64_LDST8R_ARM64_LDST16R_ARM64_LDST32R_ARM64_LDST64R_ARM64_LDST128R_POWER_TLS_LER_POWER_TLS_IER_POWER_TLSR_ADDRPOWER_DSR_ADDRPOWER_GOTR_ADDRPOWER_PCRELR_ADDRPOWER_TOCRELR_ADDRPOWER_TOCREL_DSR_RISCV_CALLR_RISCV_CALL_TRAMPR_RISCV_PCREL_ITYPER_RISCV_PCREL_STYPER_RISCV_TLS_IE_ITYPER_RISCV_TLS_IE_STYPER_PCRELDBLR_ADDRLOONG64R_ADDRLOONG64UR_ADDRLOONG64TLSR_ADDRLOONG64TLSUR_CALLLOONG64R_JMPLOONG64R_ADDRMIPSUR_ADDRMIPSTLSR_ADDRCUOFFR_WASMIMPORTR_XCOFFREF"
+const _RelocType_name = "R_ADDRR_ADDRPOWERR_ADDRARM64R_ADDRMIPSR_ADDROFFR_SIZER_CALLR_CALLARMR_CALLARM64R_CALLINDR_CALLPOWERR_CALLMIPSR_CONSTR_PCRELR_TLS_LER_TLS_IER_GOTOFFR_PLT0R_PLT1R_PLT2R_USEFIELDR_USETYPER_USEIFACER_USEIFACEMETHODR_USEGENERICIFACEMETHODR_METHODOFFR_KEEPR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFSECREFR_DWARFFILEREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_ARM64_GOTR_ARM64_PCRELR_ARM64_PCREL_LDST8R_ARM64_PCREL_LDST16R_ARM64_PCREL_LDST32R_ARM64_PCREL_LDST64R_ARM64_LDST8R_ARM64_LDST16R_ARM64_LDST32R_ARM64_LDST64R_ARM64_LDST128R_POWER_TLS_LER_POWER_TLS_IER_POWER_TLSR_POWER_TLS_IE_PCREL34R_POWER_TLS_LE_TPREL34R_ADDRPOWER_DSR_ADDRPOWER_GOTR_ADDRPOWER_GOT_PCREL34R_ADDRPOWER_PCRELR_ADDRPOWER_TOCRELR_ADDRPOWER_TOCREL_DSR_ADDRPOWER_D34R_ADDRPOWER_PCREL34R_RISCV_CALLR_RISCV_CALL_TRAMPR_RISCV_PCREL_ITYPER_RISCV_PCREL_STYPER_RISCV_TLS_IE_ITYPER_RISCV_TLS_IE_STYPER_PCRELDBLR_ADDRLOONG64R_ADDRLOONG64UR_ADDRLOONG64TLSR_ADDRLOONG64TLSUR_CALLLOONG64R_JMPLOONG64R_ADDRMIPSUR_ADDRMIPSTLSR_ADDRCUOFFR_WASMIMPORTR_XCOFFREF"
 
-var _RelocType_index = [...]uint16{0, 6, 17, 28, 38, 47, 53, 59, 68, 79, 88, 99, 109, 116, 123, 131, 139, 147, 153, 159, 165, 175, 184, 194, 210, 233, 244, 250, 261, 271, 280, 293, 307, 321, 335, 351, 362, 375, 388, 402, 416, 430, 445, 459, 473, 484, 498, 513, 530, 548, 569, 581, 599, 618, 637, 657, 677, 687, 700, 714, 730, 747, 760, 772, 783, 796, 807, 819, 829}
+var _RelocType_index = [...]uint16{0, 6, 17, 28, 38, 47, 53, 59, 68, 79, 88, 99, 109, 116, 123, 131, 139, 147, 153, 159, 165, 175, 184, 194, 210, 233, 244, 250, 261, 271, 280, 293, 307, 321, 335, 351, 362, 375, 394, 414, 434, 454, 467, 481, 495, 509, 524, 538, 552, 563, 585, 607, 621, 636, 659, 676, 694, 715, 730, 749, 761, 779, 798, 817, 837, 857, 867, 880, 894, 910, 927, 940, 952, 963, 976, 987, 999, 1009}
 
 func (i RelocType) String() string {
 	i -= 1
diff --git a/src/cmd/internal/objabi/stack.go b/src/cmd/internal/objabi/stack.go
index 0c82a7c..88b4990 100644
--- a/src/cmd/internal/objabi/stack.go
+++ b/src/cmd/internal/objabi/stack.go
@@ -15,17 +15,26 @@
 	StackSmall  = 128
 )
 
-// Initialize StackGuard and StackLimit according to target system.
-var StackGuard = 928*stackGuardMultiplier() + StackSystem
-var StackLimit = StackGuard - StackSystem - StackSmall
+func StackLimit(race bool) int {
+	// This arithmetic must match that in runtime/stack.go:{_StackGuard,_StackLimit}.
+	stackGuard := 928*stackGuardMultiplier(race) + StackSystem
+	stackLimit := stackGuard - StackSystem - StackSmall
+	return stackLimit
+}
 
 // stackGuardMultiplier returns a multiplier to apply to the default
 // stack guard size. Larger multipliers are used for non-optimized
 // builds that have larger stack frames or for specific targets.
-func stackGuardMultiplier() int {
+func stackGuardMultiplier(race bool) int {
+	// This arithmetic must match that in runtime/internal/sys/consts.go:StackGuardMultiplier.
+	n := 1
 	// On AIX, a larger stack is needed for syscalls.
 	if buildcfg.GOOS == "aix" {
-		return 2
+		n += 1
 	}
-	return stackGuardMultiplierDefault
+	// The race build also needs more stack.
+	if race {
+		n += 1
+	}
+	return n
 }
diff --git a/src/cmd/internal/objabi/symkind.go b/src/cmd/internal/objabi/symkind.go
index ba1e4d5..a58816e 100644
--- a/src/cmd/internal/objabi/symkind.go
+++ b/src/cmd/internal/objabi/symkind.go
@@ -68,6 +68,9 @@
 	SDWARFLINES
 	// Coverage instrumentation counter for libfuzzer.
 	SLIBFUZZER_8BIT_COUNTER
-	// Update cmd/link/internal/sym/AbiSymKindToSymKind for new SymKind values.
+	// Coverage instrumentation counter, aux variable for cmd/cover
+	SCOVERAGE_COUNTER
+	SCOVERAGE_AUXVAR
 
+	// Update cmd/link/internal/sym/AbiSymKindToSymKind for new SymKind values.
 )
diff --git a/src/cmd/internal/objabi/symkind_string.go b/src/cmd/internal/objabi/symkind_string.go
index d0606aa..be4e91f 100644
--- a/src/cmd/internal/objabi/symkind_string.go
+++ b/src/cmd/internal/objabi/symkind_string.go
@@ -1,4 +1,4 @@
-// Code generated by "stringer -type=SymKind symkind.go"; DO NOT EDIT.
+// Code generated by "stringer -type=SymKind"; DO NOT EDIT.
 
 package objabi
 
@@ -26,11 +26,13 @@
 	_ = x[SDWARFLOC-15]
 	_ = x[SDWARFLINES-16]
 	_ = x[SLIBFUZZER_8BIT_COUNTER-17]
+	_ = x[SCOVERAGE_COUNTER-18]
+	_ = x[SCOVERAGE_AUXVAR-19]
 }
 
-const _SymKind_name = "SxxxSTEXTSRODATASNOPTRDATASDATASBSSSNOPTRBSSSTLSBSSSDWARFCUINFOSDWARFCONSTSDWARFFCNSDWARFABSFCNSDWARFTYPESDWARFVARSDWARFRANGESDWARFLOCSDWARFLINESSLIBFUZZER_8BIT_COUNTER"
+const _SymKind_name = "SxxxSTEXTSRODATASNOPTRDATASDATASBSSSNOPTRBSSSTLSBSSSDWARFCUINFOSDWARFCONSTSDWARFFCNSDWARFABSFCNSDWARFTYPESDWARFVARSDWARFRANGESDWARFLOCSDWARFLINESSLIBFUZZER_8BIT_COUNTERSCOVERAGE_COUNTERSCOVERAGE_AUXVAR"
 
-var _SymKind_index = [...]uint8{0, 4, 9, 16, 26, 31, 35, 44, 51, 63, 74, 83, 95, 105, 114, 125, 134, 145, 168}
+var _SymKind_index = [...]uint8{0, 4, 9, 16, 26, 31, 35, 44, 51, 63, 74, 83, 95, 105, 114, 125, 134, 145, 168, 185, 201}
 
 func (i SymKind) String() string {
 	if i >= SymKind(len(_SymKind_index)-1) {
diff --git a/src/cmd/internal/objabi/util.go b/src/cmd/internal/objabi/util.go
index c2f1b20..a3e1242 100644
--- a/src/cmd/internal/objabi/util.go
+++ b/src/cmd/internal/objabi/util.go
@@ -22,5 +22,12 @@
 // or link object files that are incompatible with each other. This
 // string always starts with "go object ".
 func HeaderString() string {
-	return fmt.Sprintf("go object %s %s %s X:%s\n", buildcfg.GOOS, buildcfg.GOARCH, buildcfg.Version, strings.Join(buildcfg.Experiment.Enabled(), ","))
+	archExtra := ""
+	if k, v := buildcfg.GOGOARCH(); k != "" && v != "" {
+		archExtra = " " + k + "=" + v
+	}
+	return fmt.Sprintf("go object %s %s %s%s X:%s\n",
+		buildcfg.GOOS, buildcfg.GOARCH,
+		buildcfg.Version, archExtra,
+		strings.Join(buildcfg.Experiment.Enabled(), ","))
 }
diff --git a/src/cmd/internal/objabi/zbootstrap.go b/src/cmd/internal/objabi/zbootstrap.go
index 512fb0f..6cfb5a6 100644
--- a/src/cmd/internal/objabi/zbootstrap.go
+++ b/src/cmd/internal/objabi/zbootstrap.go
@@ -1,5 +1,3 @@
 // Code generated by go tool dist; DO NOT EDIT.
 
 package objabi
-
-const stackGuardMultiplierDefault = 1
diff --git a/src/cmd/internal/objfile/disasm.go b/src/cmd/internal/objfile/disasm.go
index b5f1cd1..c298d7e 100644
--- a/src/cmd/internal/objfile/disasm.go
+++ b/src/cmd/internal/objfile/disasm.go
@@ -7,13 +7,11 @@
 import (
 	"bufio"
 	"bytes"
-	"cmd/internal/src"
 	"container/list"
 	"debug/gosym"
 	"encoding/binary"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"os"
 	"path/filepath"
 	"regexp"
@@ -21,6 +19,8 @@
 	"strings"
 	"text/tabwriter"
 
+	"cmd/internal/src"
+
 	"golang.org/x/arch/arm/armasm"
 	"golang.org/x/arch/arm64/arm64asm"
 	"golang.org/x/arch/ppc64/ppc64asm"
@@ -157,7 +157,7 @@
 	}
 
 	if e == nil {
-		content, err := ioutil.ReadFile(filename)
+		content, err := os.ReadFile(filename)
 		if err != nil {
 			return nil, err
 		}
diff --git a/src/cmd/internal/objfile/elf.go b/src/cmd/internal/objfile/elf.go
index a48a9df..c64c254 100644
--- a/src/cmd/internal/objfile/elf.go
+++ b/src/cmd/internal/objfile/elf.go
@@ -68,16 +68,35 @@
 	if sect := f.elf.Section(".text"); sect != nil {
 		textStart = sect.Addr
 	}
-	if sect := f.elf.Section(".gosymtab"); sect != nil {
+
+	sect := f.elf.Section(".gosymtab")
+	if sect == nil {
+		// try .data.rel.ro.gosymtab, for PIE binaries
+		sect = f.elf.Section(".data.rel.ro.gosymtab")
+	}
+	if sect != nil {
 		if symtab, err = sect.Data(); err != nil {
 			return 0, nil, nil, err
 		}
+	} else {
+		// if both sections failed, try the symbol
+		symtab = f.symbolData("runtime.symtab", "runtime.esymtab")
 	}
-	if sect := f.elf.Section(".gopclntab"); sect != nil {
+
+	sect = f.elf.Section(".gopclntab")
+	if sect == nil {
+		// try .data.rel.ro.gopclntab, for PIE binaries
+		sect = f.elf.Section(".data.rel.ro.gopclntab")
+	}
+	if sect != nil {
 		if pclntab, err = sect.Data(); err != nil {
 			return 0, nil, nil, err
 		}
+	} else {
+		// if both sections failed, try the symbol
+		pclntab = f.symbolData("runtime.pclntab", "runtime.epclntab")
 	}
+
 	return textStart, symtab, pclntab, nil
 }
 
@@ -124,3 +143,35 @@
 func (f *elfFile) dwarf() (*dwarf.Data, error) {
 	return f.elf.DWARF()
 }
+
+func (f *elfFile) symbolData(start, end string) []byte {
+	elfSyms, err := f.elf.Symbols()
+	if err != nil {
+		return nil
+	}
+	var addr, eaddr uint64
+	for _, s := range elfSyms {
+		if s.Name == start {
+			addr = s.Value
+		} else if s.Name == end {
+			eaddr = s.Value
+		}
+		if addr != 0 && eaddr != 0 {
+			break
+		}
+	}
+	if addr == 0 || eaddr < addr {
+		return nil
+	}
+	size := eaddr - addr
+	data := make([]byte, size)
+	for _, prog := range f.elf.Progs {
+		if prog.Vaddr <= addr && addr+size-1 <= prog.Vaddr+prog.Filesz-1 {
+			if _, err := prog.ReadAt(data, int64(addr-prog.Vaddr)); err != nil {
+				return nil
+			}
+			return data
+		}
+	}
+	return nil
+}
diff --git a/src/cmd/internal/objfile/pe.go b/src/cmd/internal/objfile/pe.go
index 9088866..4c4be1e 100644
--- a/src/cmd/internal/objfile/pe.go
+++ b/src/cmd/internal/objfile/pe.go
@@ -31,13 +31,7 @@
 	// We infer the size of a symbol by looking at where the next symbol begins.
 	var addrs []uint64
 
-	var imageBase uint64
-	switch oh := f.pe.OptionalHeader.(type) {
-	case *pe.OptionalHeader32:
-		imageBase = uint64(oh.ImageBase)
-	case *pe.OptionalHeader64:
-		imageBase = oh.ImageBase
-	}
+	imageBase, _ := f.imageBase()
 
 	var syms []Sym
 	for _, s := range f.pe.Symbols {
@@ -96,15 +90,11 @@
 }
 
 func (f *peFile) pcln() (textStart uint64, symtab, pclntab []byte, err error) {
-	var imageBase uint64
-	switch oh := f.pe.OptionalHeader.(type) {
-	case *pe.OptionalHeader32:
-		imageBase = uint64(oh.ImageBase)
-	case *pe.OptionalHeader64:
-		imageBase = oh.ImageBase
-	default:
-		return 0, nil, nil, fmt.Errorf("pe file format not recognized")
+	imageBase, err := f.imageBase()
+	if err != nil {
+		return 0, nil, nil, err
 	}
+
 	if sect := f.pe.Section(".text"); sect != nil {
 		textStart = imageBase + uint64(sect.VirtualAddress)
 	}
@@ -127,15 +117,11 @@
 }
 
 func (f *peFile) text() (textStart uint64, text []byte, err error) {
-	var imageBase uint64
-	switch oh := f.pe.OptionalHeader.(type) {
-	case *pe.OptionalHeader32:
-		imageBase = uint64(oh.ImageBase)
-	case *pe.OptionalHeader64:
-		imageBase = oh.ImageBase
-	default:
-		return 0, nil, fmt.Errorf("pe file format not recognized")
+	imageBase, err := f.imageBase()
+	if err != nil {
+		return 0, nil, err
 	}
+
 	sect := f.pe.Section(".text")
 	if sect == nil {
 		return 0, nil, fmt.Errorf("text section not found")
@@ -197,7 +183,18 @@
 }
 
 func (f *peFile) loadAddress() (uint64, error) {
-	return 0, fmt.Errorf("unknown load address")
+	return f.imageBase()
+}
+
+func (f *peFile) imageBase() (uint64, error) {
+	switch oh := f.pe.OptionalHeader.(type) {
+	case *pe.OptionalHeader32:
+		return uint64(oh.ImageBase), nil
+	case *pe.OptionalHeader64:
+		return oh.ImageBase, nil
+	default:
+		return 0, fmt.Errorf("pe file format not recognized")
+	}
 }
 
 func (f *peFile) dwarf() (*dwarf.Data, error) {
diff --git a/src/cmd/internal/osinfo/os_unix.go b/src/cmd/internal/osinfo/os_unix.go
index fab9e08..e148832 100644
--- a/src/cmd/internal/osinfo/os_unix.go
+++ b/src/cmd/internal/osinfo/os_unix.go
@@ -2,23 +2,11 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
+//go:build unix
 
 package osinfo
 
-import (
-	"bytes"
-
-	"golang.org/x/sys/unix"
-)
-
-func utsString(b []byte) string {
-	i := bytes.IndexByte(b, 0)
-	if i == -1 {
-		return string(b)
-	}
-	return string(b[:i])
-}
+import "golang.org/x/sys/unix"
 
 // Version returns the OS version name/number.
 func Version() (string, error) {
@@ -27,10 +15,10 @@
 		return "", err
 	}
 
-	sysname := utsString(uts.Sysname[:])
-	release := utsString(uts.Release[:])
-	version := utsString(uts.Version[:])
-	machine := utsString(uts.Machine[:])
+	sysname := unix.ByteSliceToString(uts.Sysname[:])
+	release := unix.ByteSliceToString(uts.Release[:])
+	version := unix.ByteSliceToString(uts.Version[:])
+	machine := unix.ByteSliceToString(uts.Machine[:])
 
 	return sysname + " " + release + " " + version + " " + machine, nil
 }
diff --git a/src/cmd/internal/pkgpath/pkgpath.go b/src/cmd/internal/pkgpath/pkgpath.go
index 40a040a..0bec137 100644
--- a/src/cmd/internal/pkgpath/pkgpath.go
+++ b/src/cmd/internal/pkgpath/pkgpath.go
@@ -10,7 +10,6 @@
 	"bytes"
 	"errors"
 	"fmt"
-	"io/ioutil"
 	"os"
 	"os/exec"
 	"strings"
@@ -19,7 +18,7 @@
 // ToSymbolFunc returns a function that may be used to convert a
 // package path into a string suitable for use as a symbol.
 // cmd is the gccgo/GoLLVM compiler in use, and tmpdir is a temporary
-// directory to pass to ioutil.TempFile.
+// directory to pass to os.CreateTemp().
 // For example, this returns a function that converts "net/http"
 // into a string like "net..z2fhttp". The actual string varies for
 // different gccgo/GoLLVM versions, which is why this returns a function
@@ -32,7 +31,7 @@
 	// the same string. More recent versions use a new mangler
 	// that avoids these collisions.
 	const filepat = "*_gccgo_manglechck.go"
-	f, err := ioutil.TempFile(tmpdir, filepat)
+	f, err := os.CreateTemp(tmpdir, filepat)
 	if err != nil {
 		return nil, err
 	}
@@ -40,7 +39,7 @@
 	f.Close()
 	defer os.Remove(gofilename)
 
-	if err := ioutil.WriteFile(gofilename, []byte(mangleCheckCode), 0644); err != nil {
+	if err := os.WriteFile(gofilename, []byte(mangleCheckCode), 0644); err != nil {
 		return nil, err
 	}
 
@@ -87,13 +86,11 @@
 
 // toSymbolV2 converts a package path using the second mangling scheme.
 func toSymbolV2(ppath string) string {
-	// This has to build at boostrap time, so it has to build
-	// with Go 1.4, so we don't use strings.Builder.
-	bsl := make([]byte, 0, len(ppath))
+	var bsl strings.Builder
 	changed := false
 	for _, c := range ppath {
 		if ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || ('0' <= c && c <= '9') || c == '_' {
-			bsl = append(bsl, byte(c))
+			bsl.WriteByte(byte(c))
 			continue
 		}
 		var enc string
@@ -107,13 +104,13 @@
 		default:
 			enc = fmt.Sprintf("..U%08x", c)
 		}
-		bsl = append(bsl, enc...)
+		bsl.WriteString(enc)
 		changed = true
 	}
 	if !changed {
 		return ppath
 	}
-	return string(bsl)
+	return bsl.String()
 }
 
 // v3UnderscoreCodes maps from a character that supports an underscore
@@ -137,19 +134,18 @@
 
 // toSymbolV3 converts a package path using the third mangling scheme.
 func toSymbolV3(ppath string) string {
-	// This has to build at boostrap time, so it has to build
-	// with Go 1.4, so we don't use strings.Builder.
-	bsl := make([]byte, 0, len(ppath))
+	var bsl strings.Builder
 	changed := false
 	for _, c := range ppath {
 		if ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || ('0' <= c && c <= '9') {
-			bsl = append(bsl, byte(c))
+			bsl.WriteByte(byte(c))
 			continue
 		}
 
 		if c < 0x80 {
 			if u, ok := v3UnderscoreCodes[byte(c)]; ok {
-				bsl = append(bsl, '_', u)
+				bsl.WriteByte('_')
+				bsl.WriteByte(u)
 				changed = true
 				continue
 			}
@@ -164,11 +160,11 @@
 		default:
 			enc = fmt.Sprintf("_U%08x", c)
 		}
-		bsl = append(bsl, enc...)
+		bsl.WriteString(enc)
 		changed = true
 	}
 	if !changed {
 		return ppath
 	}
-	return string(bsl)
+	return bsl.String()
 }
diff --git a/src/cmd/internal/pkgpath/pkgpath_test.go b/src/cmd/internal/pkgpath/pkgpath_test.go
index 232e803..ae4fac7 100644
--- a/src/cmd/internal/pkgpath/pkgpath_test.go
+++ b/src/cmd/internal/pkgpath/pkgpath_test.go
@@ -5,6 +5,7 @@
 package pkgpath
 
 import (
+	"internal/testenv"
 	"os"
 	"testing"
 )
@@ -34,6 +35,8 @@
 }
 
 func TestToSymbolFunc(t *testing.T) {
+	testenv.MustHaveExec(t)
+
 	const input = "pä世🜃"
 	tests := []struct {
 		env     string
diff --git a/src/cmd/internal/pkgpattern/pat_test.go b/src/cmd/internal/pkgpattern/pat_test.go
new file mode 100644
index 0000000..0a11570
--- /dev/null
+++ b/src/cmd/internal/pkgpattern/pat_test.go
@@ -0,0 +1,199 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkgpattern
+
+import (
+	"strings"
+	"testing"
+)
+
+var matchPatternTests = `
+	pattern ...
+	match foo
+
+	pattern net
+	match net
+	not net/http
+
+	pattern net/http
+	match net/http
+	not net
+
+	pattern net...
+	match net net/http netchan
+	not not/http not/net/http
+
+	# Special cases. Quoting docs:
+
+	# First, /... at the end of the pattern can match an empty string,
+	# so that net/... matches both net and packages in its subdirectories, like net/http.
+	pattern net/...
+	match net net/http
+	not not/http not/net/http netchan
+
+	# Second, any slash-separated pattern element containing a wildcard never
+	# participates in a match of the "vendor" element in the path of a vendored
+	# package, so that ./... does not match packages in subdirectories of
+	# ./vendor or ./mycode/vendor, but ./vendor/... and ./mycode/vendor/... do.
+	# Note, however, that a directory named vendor that itself contains code
+	# is not a vendored package: cmd/vendor would be a command named vendor,
+	# and the pattern cmd/... matches it.
+	pattern ./...
+	match ./vendor ./mycode/vendor
+	not ./vendor/foo ./mycode/vendor/foo
+
+	pattern ./vendor/...
+	match ./vendor/foo ./vendor/foo/vendor
+	not ./vendor/foo/vendor/bar
+
+	pattern mycode/vendor/...
+	match mycode/vendor mycode/vendor/foo mycode/vendor/foo/vendor
+	not mycode/vendor/foo/vendor/bar
+
+	pattern x/vendor/y
+	match x/vendor/y
+	not x/vendor
+
+	pattern x/vendor/y/...
+	match x/vendor/y x/vendor/y/z x/vendor/y/vendor x/vendor/y/z/vendor
+	not x/vendor/y/vendor/z
+
+	pattern .../vendor/...
+	match x/vendor/y x/vendor/y/z x/vendor/y/vendor x/vendor/y/z/vendor
+`
+
+func TestMatchPattern(t *testing.T) {
+	testPatterns(t, "MatchPattern", matchPatternTests, func(pattern, name string) bool {
+		return MatchPattern(pattern)(name)
+	})
+}
+
+var matchSimplePatternTests = `
+	pattern ...
+	match foo
+
+	pattern .../bar/.../baz
+	match foo/bar/abc/baz
+
+	pattern net
+	match net
+	not net/http
+
+	pattern net/http
+	match net/http
+	not net
+
+	pattern net...
+	match net net/http netchan
+	not not/http not/net/http
+
+	# Special cases. Quoting docs:
+
+	# First, /... at the end of the pattern can match an empty string,
+	# so that net/... matches both net and packages in its subdirectories, like net/http.
+	pattern net/...
+	match net net/http
+	not not/http not/net/http netchan
+`
+
+func TestSimpleMatchPattern(t *testing.T) {
+	testPatterns(t, "MatchSimplePattern", matchSimplePatternTests, func(pattern, name string) bool {
+		return MatchSimplePattern(pattern)(name)
+	})
+}
+
+var treeCanMatchPatternTests = `
+	pattern ...
+	match foo
+
+	pattern net
+	match net
+	not net/http
+
+	pattern net/http
+	match net net/http
+
+	pattern net...
+	match net netchan net/http
+	not not/http not/net/http
+
+	pattern net/...
+	match net net/http
+	not not/http netchan
+
+	pattern abc.../def
+	match abcxyz
+	not xyzabc
+
+	pattern x/y/z/...
+	match x x/y x/y/z x/y/z/w
+
+	pattern x/y/z
+	match x x/y x/y/z
+	not x/y/z/w
+
+	pattern x/.../y/z
+	match x/a/b/c
+	not y/x/a/b/c
+`
+
+func TestTreeCanMatchPattern(t *testing.T) {
+	testPatterns(t, "TreeCanMatchPattern", treeCanMatchPatternTests, func(pattern, name string) bool {
+		return TreeCanMatchPattern(pattern)(name)
+	})
+}
+
+var hasPathPrefixTests = []stringPairTest{
+	{"abc", "a", false},
+	{"a/bc", "a", true},
+	{"a", "a", true},
+	{"a/bc", "a/", true},
+}
+
+func TestHasPathPrefix(t *testing.T) {
+	testStringPairs(t, "hasPathPrefix", hasPathPrefixTests, hasPathPrefix)
+}
+
+type stringPairTest struct {
+	in1 string
+	in2 string
+	out bool
+}
+
+func testStringPairs(t *testing.T, name string, tests []stringPairTest, f func(string, string) bool) {
+	for _, tt := range tests {
+		if out := f(tt.in1, tt.in2); out != tt.out {
+			t.Errorf("%s(%q, %q) = %v, want %v", name, tt.in1, tt.in2, out, tt.out)
+		}
+	}
+}
+
+func testPatterns(t *testing.T, name, tests string, fn func(string, string) bool) {
+	var patterns []string
+	for _, line := range strings.Split(tests, "\n") {
+		if i := strings.Index(line, "#"); i >= 0 {
+			line = line[:i]
+		}
+		f := strings.Fields(line)
+		if len(f) == 0 {
+			continue
+		}
+		switch f[0] {
+		default:
+			t.Fatalf("unknown directive %q", f[0])
+		case "pattern":
+			patterns = f[1:]
+		case "match", "not":
+			want := f[0] == "match"
+			for _, pattern := range patterns {
+				for _, in := range f[1:] {
+					if fn(pattern, in) != want {
+						t.Errorf("%s(%q, %q) = %v, want %v", name, pattern, in, !want, want)
+					}
+				}
+			}
+		}
+	}
+}
diff --git a/src/cmd/internal/pkgpattern/pkgpattern.go b/src/cmd/internal/pkgpattern/pkgpattern.go
new file mode 100644
index 0000000..1496eeb
--- /dev/null
+++ b/src/cmd/internal/pkgpattern/pkgpattern.go
@@ -0,0 +1,137 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkgpattern
+
+import (
+	"regexp"
+	"strings"
+)
+
+// Note: most of this code was originally part of the cmd/go/internal/search
+// package; it was migrated here in order to support the use case of
+// commands other than cmd/go that need to accept package pattern args.
+
+// TreeCanMatchPattern(pattern)(name) reports whether
+// name or children of name can possibly match pattern.
+// Pattern is the same limited glob accepted by MatchPattern.
+func TreeCanMatchPattern(pattern string) func(name string) bool {
+	wildCard := false
+	if i := strings.Index(pattern, "..."); i >= 0 {
+		wildCard = true
+		pattern = pattern[:i]
+	}
+	return func(name string) bool {
+		return len(name) <= len(pattern) && hasPathPrefix(pattern, name) ||
+			wildCard && strings.HasPrefix(name, pattern)
+	}
+}
+
+// MatchPattern(pattern)(name) reports whether
+// name matches pattern. Pattern is a limited glob
+// pattern in which '...' means 'any string' and there
+// is no other special syntax.
+// Unfortunately, there are two special cases. Quoting "go help packages":
+//
+// First, /... at the end of the pattern can match an empty string,
+// so that net/... matches both net and packages in its subdirectories, like net/http.
+// Second, any slash-separated pattern element containing a wildcard never
+// participates in a match of the "vendor" element in the path of a vendored
+// package, so that ./... does not match packages in subdirectories of
+// ./vendor or ./mycode/vendor, but ./vendor/... and ./mycode/vendor/... do.
+// Note, however, that a directory named vendor that itself contains code
+// is not a vendored package: cmd/vendor would be a command named vendor,
+// and the pattern cmd/... matches it.
+func MatchPattern(pattern string) func(name string) bool {
+	return matchPatternInternal(pattern, true)
+}
+
+// MatchSimplePattern returns a function that can be used to check
+// whether a given name matches a pattern, where pattern is a limited
+// glob pattern in which '...' means 'any string', with no other
+// special syntax. There is one special case for MatchPatternSimple:
+// according to the rules in "go help packages": a /... at the end of
+// the pattern can match an empty string, so that net/... matches both
+// net and packages in its subdirectories, like net/http.
+func MatchSimplePattern(pattern string) func(name string) bool {
+	return matchPatternInternal(pattern, false)
+}
+
+func matchPatternInternal(pattern string, vendorExclude bool) func(name string) bool {
+	// Convert pattern to regular expression.
+	// The strategy for the trailing /... is to nest it in an explicit ? expression.
+	// The strategy for the vendor exclusion is to change the unmatchable
+	// vendor strings to a disallowed code point (vendorChar) and to use
+	// "(anything but that codepoint)*" as the implementation of the ... wildcard.
+	// This is a bit complicated but the obvious alternative,
+	// namely a hand-written search like in most shell glob matchers,
+	// is too easy to make accidentally exponential.
+	// Using package regexp guarantees linear-time matching.
+
+	const vendorChar = "\x00"
+
+	if vendorExclude && strings.Contains(pattern, vendorChar) {
+		return func(name string) bool { return false }
+	}
+
+	re := regexp.QuoteMeta(pattern)
+	wild := `.*`
+	if vendorExclude {
+		wild = `[^` + vendorChar + `]*`
+		re = replaceVendor(re, vendorChar)
+		switch {
+		case strings.HasSuffix(re, `/`+vendorChar+`/\.\.\.`):
+			re = strings.TrimSuffix(re, `/`+vendorChar+`/\.\.\.`) + `(/vendor|/` + vendorChar + `/\.\.\.)`
+		case re == vendorChar+`/\.\.\.`:
+			re = `(/vendor|/` + vendorChar + `/\.\.\.)`
+		}
+	}
+	if strings.HasSuffix(re, `/\.\.\.`) {
+		re = strings.TrimSuffix(re, `/\.\.\.`) + `(/\.\.\.)?`
+	}
+	re = strings.ReplaceAll(re, `\.\.\.`, wild)
+
+	reg := regexp.MustCompile(`^` + re + `$`)
+
+	return func(name string) bool {
+		if vendorExclude {
+			if strings.Contains(name, vendorChar) {
+				return false
+			}
+			name = replaceVendor(name, vendorChar)
+		}
+		return reg.MatchString(name)
+	}
+}
+
+// hasPathPrefix reports whether the path s begins with the
+// elements in prefix.
+func hasPathPrefix(s, prefix string) bool {
+	switch {
+	default:
+		return false
+	case len(s) == len(prefix):
+		return s == prefix
+	case len(s) > len(prefix):
+		if prefix != "" && prefix[len(prefix)-1] == '/' {
+			return strings.HasPrefix(s, prefix)
+		}
+		return s[len(prefix)] == '/' && s[:len(prefix)] == prefix
+	}
+}
+
+// replaceVendor returns the result of replacing
+// non-trailing vendor path elements in x with repl.
+func replaceVendor(x, repl string) string {
+	if !strings.Contains(x, "vendor") {
+		return x
+	}
+	elem := strings.Split(x, "/")
+	for i := 0; i < len(elem)-1; i++ {
+		if elem[i] == "vendor" {
+			elem[i] = repl
+		}
+	}
+	return strings.Join(elem, "/")
+}
diff --git a/src/cmd/internal/quoted/quoted.go b/src/cmd/internal/quoted/quoted.go
index b3d3c40..a812275 100644
--- a/src/cmd/internal/quoted/quoted.go
+++ b/src/cmd/internal/quoted/quoted.go
@@ -83,16 +83,16 @@
 		}
 		switch {
 		case !sawSpace && !sawSingleQuote && !sawDoubleQuote:
-			buf = append(buf, []byte(arg)...)
+			buf = append(buf, arg...)
 
 		case !sawSingleQuote:
 			buf = append(buf, '\'')
-			buf = append(buf, []byte(arg)...)
+			buf = append(buf, arg...)
 			buf = append(buf, '\'')
 
 		case !sawDoubleQuote:
 			buf = append(buf, '"')
-			buf = append(buf, []byte(arg)...)
+			buf = append(buf, arg...)
 			buf = append(buf, '"')
 
 		default:
diff --git a/src/cmd/internal/sys/supported.go b/src/cmd/internal/sys/supported.go
deleted file mode 100644
index 1d74f6b..0000000
--- a/src/cmd/internal/sys/supported.go
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package sys
-
-// RaceDetectorSupported reports whether goos/goarch supports the race
-// detector. There is a copy of this function in cmd/dist/test.go.
-// Race detector only supports 48-bit VMA on arm64. But it will always
-// return true for arm64, because we don't have VMA size information during
-// the compile time.
-func RaceDetectorSupported(goos, goarch string) bool {
-	switch goos {
-	case "linux":
-		return goarch == "amd64" || goarch == "ppc64le" || goarch == "arm64" || goarch == "s390x"
-	case "darwin":
-		return goarch == "amd64" || goarch == "arm64"
-	case "freebsd", "netbsd", "openbsd", "windows":
-		return goarch == "amd64"
-	default:
-		return false
-	}
-}
-
-// MSanSupported reports whether goos/goarch supports the memory
-// sanitizer option.
-// There is a copy of this function in misc/cgo/testsanitizers/cc_test.go.
-func MSanSupported(goos, goarch string) bool {
-	switch goos {
-	case "linux":
-		return goarch == "amd64" || goarch == "arm64"
-	default:
-		return false
-	}
-}
-
-// ASanSupported reports whether goos/goarch supports the address
-// sanitizer option.
-// There is a copy of this function in misc/cgo/testsanitizers/cc_test.go.
-func ASanSupported(goos, goarch string) bool {
-	switch goos {
-	case "linux":
-		return goarch == "arm64" || goarch == "amd64" || goarch == "riscv64"
-	default:
-		return false
-	}
-}
-
-// FuzzSupported reports whether goos/goarch supports fuzzing
-// ('go test -fuzz=.').
-func FuzzSupported(goos, goarch string) bool {
-	switch goos {
-	case "darwin", "freebsd", "linux", "windows":
-		return true
-	default:
-		return false
-	}
-}
-
-// FuzzInstrumented reports whether fuzzing on goos/goarch uses coverage
-// instrumentation. (FuzzInstrumented implies FuzzSupported.)
-func FuzzInstrumented(goos, goarch string) bool {
-	switch goarch {
-	case "amd64", "arm64":
-		// TODO(#14565): support more architectures.
-		return FuzzSupported(goos, goarch)
-	default:
-		return false
-	}
-}
-
-// MustLinkExternal reports whether goos/goarch requires external linking.
-// (This is the opposite of internal/testenv.CanInternalLink. Keep them in sync.)
-func MustLinkExternal(goos, goarch string) bool {
-	switch goos {
-	case "android":
-		if goarch != "arm64" {
-			return true
-		}
-	case "ios":
-		if goarch == "arm64" {
-			return true
-		}
-	}
-	return false
-}
-
-// BuildModeSupported reports whether goos/goarch supports the given build mode
-// using the given compiler.
-func BuildModeSupported(compiler, buildmode, goos, goarch string) bool {
-	if compiler == "gccgo" {
-		return true
-	}
-
-	platform := goos + "/" + goarch
-
-	switch buildmode {
-	case "archive":
-		return true
-
-	case "c-archive":
-		// TODO(bcmills): This seems dubious.
-		// Do we really support c-archive mode on js/wasm‽
-		return platform != "linux/ppc64"
-
-	case "c-shared":
-		switch platform {
-		case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/ppc64le", "linux/riscv64", "linux/s390x",
-			"android/amd64", "android/arm", "android/arm64", "android/386",
-			"freebsd/amd64",
-			"darwin/amd64", "darwin/arm64",
-			"windows/amd64", "windows/386", "windows/arm64":
-			return true
-		}
-		return false
-
-	case "default":
-		return true
-
-	case "exe":
-		return true
-
-	case "pie":
-		switch platform {
-		case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/riscv64", "linux/s390x",
-			"android/amd64", "android/arm", "android/arm64", "android/386",
-			"freebsd/amd64",
-			"darwin/amd64", "darwin/arm64",
-			"ios/amd64", "ios/arm64",
-			"aix/ppc64",
-			"windows/386", "windows/amd64", "windows/arm":
-			return true
-		}
-		return false
-
-	case "shared":
-		switch platform {
-		case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x":
-			return true
-		}
-		return false
-
-	case "plugin":
-		switch platform {
-		case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/s390x", "linux/ppc64le",
-			"android/amd64", "android/arm", "android/arm64", "android/386",
-			"darwin/amd64", "darwin/arm64",
-			"freebsd/amd64":
-			return true
-		}
-		return false
-
-	default:
-		return false
-	}
-}
-
-func InternalLinkPIESupported(goos, goarch string) bool {
-	switch goos + "/" + goarch {
-	case "darwin/amd64", "darwin/arm64",
-		"linux/amd64", "linux/arm64", "linux/ppc64le",
-		"android/arm64",
-		"windows-amd64", "windows-386", "windows-arm":
-		return true
-	}
-	return false
-}
diff --git a/src/cmd/internal/sys/supported_test.go b/src/cmd/internal/sys/supported_test.go
deleted file mode 100644
index 1217814..0000000
--- a/src/cmd/internal/sys/supported_test.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package sys
-
-import (
-	"internal/testenv"
-	"runtime"
-	"testing"
-)
-
-func TestMustLinkExternalMatchesTestenv(t *testing.T) {
-	// MustLinkExternal and testenv.CanInternalLink are the exact opposite.
-	if b := MustLinkExternal(runtime.GOOS, runtime.GOARCH); b != !testenv.CanInternalLink() {
-		t.Fatalf("MustLinkExternal() == %v, testenv.CanInternalLink() == %v, don't match", b, testenv.CanInternalLink())
-	}
-}
diff --git a/src/cmd/internal/test2json/test2json.go b/src/cmd/internal/test2json/test2json.go
index d8b870f..f7dfbe6 100644
--- a/src/cmd/internal/test2json/test2json.go
+++ b/src/cmd/internal/test2json/test2json.go
@@ -49,15 +49,16 @@
 // It implements io.WriteCloser; the caller writes test output in,
 // and the converter writes JSON output to w.
 type Converter struct {
-	w        io.Writer  // JSON output stream
-	pkg      string     // package to name in events
-	mode     Mode       // mode bits
-	start    time.Time  // time converter started
-	testName string     // name of current test, for output attribution
-	report   []*event   // pending test result reports (nested for subtests)
-	result   string     // overall test result if seen
-	input    lineBuffer // input buffer
-	output   lineBuffer // output buffer
+	w          io.Writer  // JSON output stream
+	pkg        string     // package to name in events
+	mode       Mode       // mode bits
+	start      time.Time  // time converter started
+	testName   string     // name of current test, for output attribution
+	report     []*event   // pending test result reports (nested for subtests)
+	result     string     // overall test result if seen
+	input      lineBuffer // input buffer
+	output     lineBuffer // output buffer
+	needMarker bool       // require ^V marker to introduce test framing line
 }
 
 // inBuffer and outBuffer are the input and output buffer sizes.
@@ -118,6 +119,7 @@
 			part: c.writeOutputEvent,
 		},
 	}
+	c.writeEvent(&event{Action: "start"})
 	return c
 }
 
@@ -130,27 +132,39 @@
 // Exited marks the test process as having exited with the given error.
 func (c *Converter) Exited(err error) {
 	if err == nil {
-		c.result = "pass"
+		if c.result != "skip" {
+			c.result = "pass"
+		}
 	} else {
 		c.result = "fail"
 	}
 }
 
+const marker = byte(0x16) // ^V
+
 var (
 	// printed by test on successful run.
-	bigPass = []byte("PASS\n")
+	bigPass = []byte("PASS")
 
 	// printed by test after a normal test failure.
-	bigFail = []byte("FAIL\n")
+	bigFail = []byte("FAIL")
 
 	// printed by 'go test' along with an error if the test binary terminates
 	// with an error.
 	bigFailErrorPrefix = []byte("FAIL\t")
 
+	// an === NAME line with no test name, if trailing spaces are deleted
+	emptyName     = []byte("=== NAME")
+	emptyNameLine = []byte("=== NAME  \n")
+
 	updates = [][]byte{
 		[]byte("=== RUN   "),
 		[]byte("=== PAUSE "),
 		[]byte("=== CONT  "),
+		[]byte("=== NAME  "),
+		[]byte("=== PASS  "),
+		[]byte("=== FAIL  "),
+		[]byte("=== SKIP  "),
 	}
 
 	reports = [][]byte{
@@ -163,18 +177,49 @@
 	fourSpace = []byte("    ")
 
 	skipLinePrefix = []byte("?   \t")
-	skipLineSuffix = []byte("\t[no test files]\n")
+	skipLineSuffix = []byte("\t[no test files]")
 )
 
 // handleInputLine handles a single whole test output line.
 // It must write the line to c.output but may choose to do so
 // before or after emitting other events.
 func (c *Converter) handleInputLine(line []byte) {
-	// Final PASS or FAIL.
-	if bytes.Equal(line, bigPass) || bytes.Equal(line, bigFail) || bytes.HasPrefix(line, bigFailErrorPrefix) {
-		c.flushReport(0)
+	if len(line) == 0 {
+		return
+	}
+	sawMarker := false
+	if c.needMarker && line[0] != marker {
 		c.output.write(line)
-		if bytes.Equal(line, bigPass) {
+		return
+	}
+	if line[0] == marker {
+		c.output.flush()
+		sawMarker = true
+		line = line[1:]
+	}
+
+	// Trim is line without \n or \r\n.
+	trim := line
+	if len(trim) > 0 && trim[len(trim)-1] == '\n' {
+		trim = trim[:len(trim)-1]
+		if len(trim) > 0 && trim[len(trim)-1] == '\r' {
+			trim = trim[:len(trim)-1]
+		}
+	}
+
+	// === CONT followed by an empty test name can lose its trailing spaces.
+	if bytes.Equal(trim, emptyName) {
+		line = emptyNameLine
+		trim = line[:len(line)-1]
+	}
+
+	// Final PASS or FAIL.
+	if bytes.Equal(trim, bigPass) || bytes.Equal(trim, bigFail) || bytes.HasPrefix(trim, bigFailErrorPrefix) {
+		c.flushReport(0)
+		c.testName = ""
+		c.needMarker = sawMarker
+		c.output.write(line)
+		if bytes.Equal(trim, bigPass) {
 			c.result = "pass"
 		} else {
 			c.result = "fail"
@@ -184,7 +229,7 @@
 
 	// Special case for entirely skipped test binary: "?   \tpkgname\t[no test files]\n" is only line.
 	// Report it as plain output but remember to say skip in the final summary.
-	if bytes.HasPrefix(line, skipLinePrefix) && bytes.HasSuffix(line, skipLineSuffix) && len(c.report) == 0 {
+	if bytes.HasPrefix(line, skipLinePrefix) && bytes.HasSuffix(trim, skipLineSuffix) && len(c.report) == 0 {
 		c.result = "skip"
 	}
 
@@ -268,6 +313,7 @@
 			return
 		}
 		// Flush reports at this indentation level or deeper.
+		c.needMarker = sawMarker
 		c.flushReport(indent)
 		e.Test = name
 		c.testName = name
@@ -277,9 +323,16 @@
 	}
 	// === update.
 	// Finish any pending PASS/FAIL reports.
+	c.needMarker = sawMarker
 	c.flushReport(0)
 	c.testName = name
 
+	if action == "name" {
+		// This line is only generated to get c.testName right.
+		// Don't emit an event.
+		return
+	}
+
 	if action == "pause" {
 		// For a pause, we want to write the pause notification before
 		// delivering the pause event, just so it doesn't look like the test
@@ -343,7 +396,7 @@
 	js, err := json.Marshal(e)
 	if err != nil {
 		// Should not happen - event is valid for json.Marshal.
-		c.w.Write([]byte(fmt.Sprintf("testjson internal error: %v\n", err)))
+		fmt.Fprintf(c.w, "testjson internal error: %v\n", err)
 		return
 	}
 	js = append(js, '\n')
@@ -370,15 +423,15 @@
 // write writes b to the buffer.
 func (l *lineBuffer) write(b []byte) {
 	for len(b) > 0 {
-		// Copy what we can into b.
+		// Copy what we can into l.b.
 		m := copy(l.b[len(l.b):cap(l.b)], b)
 		l.b = l.b[:len(l.b)+m]
 		b = b[m:]
 
-		// Process lines in b.
+		// Process lines in l.b.
 		i := 0
 		for i < len(l.b) {
-			j := bytes.IndexByte(l.b[i:], '\n')
+			j, w := indexEOL(l.b[i:])
 			if j < 0 {
 				if !l.mid {
 					if j := bytes.IndexByte(l.b[i:], '\t'); j >= 0 {
@@ -391,7 +444,7 @@
 				}
 				break
 			}
-			e := i + j + 1
+			e := i + j + w
 			if l.mid {
 				// Found the end of a partial line.
 				l.part(l.b[i:e])
@@ -421,6 +474,23 @@
 	}
 }
 
+// indexEOL finds the index of a line ending,
+// returning its position and output width.
+// A line ending is either a \n or the empty string just before a ^V not beginning a line.
+// The output width for \n is 1 (meaning it should be printed)
+// but the output width for ^V is 0 (meaning it should be left to begin the next line).
+func indexEOL(b []byte) (pos, wid int) {
+	for i, c := range b {
+		if c == '\n' {
+			return i, 1
+		}
+		if c == marker && i > 0 { // test -v=json emits ^V at start of framing lines
+			return i, 0
+		}
+	}
+	return -1, 0
+}
+
 // flush flushes the line buffer.
 func (l *lineBuffer) flush() {
 	if len(l.b) > 0 {
diff --git a/src/cmd/internal/test2json/test2json_test.go b/src/cmd/internal/test2json/test2json_test.go
index e69739d..c1aecc8 100644
--- a/src/cmd/internal/test2json/test2json_test.go
+++ b/src/cmd/internal/test2json/test2json_test.go
@@ -10,7 +10,7 @@
 	"flag"
 	"fmt"
 	"io"
-	"io/ioutil"
+	"os"
 	"path/filepath"
 	"reflect"
 	"strings"
@@ -28,7 +28,7 @@
 	for _, file := range files {
 		name := strings.TrimSuffix(filepath.Base(file), ".test")
 		t.Run(name, func(t *testing.T) {
-			orig, err := ioutil.ReadFile(file)
+			orig, err := os.ReadFile(file)
 			if err != nil {
 				t.Fatal(err)
 			}
@@ -46,13 +46,13 @@
 			if *update {
 				js := strings.TrimSuffix(file, ".test") + ".json"
 				t.Logf("rewriting %s", js)
-				if err := ioutil.WriteFile(js, buf.Bytes(), 0666); err != nil {
+				if err := os.WriteFile(js, buf.Bytes(), 0666); err != nil {
 					t.Fatal(err)
 				}
 				return
 			}
 
-			want, err := ioutil.ReadFile(strings.TrimSuffix(file, ".test") + ".json")
+			want, err := os.ReadFile(strings.TrimSuffix(file, ".test") + ".json")
 			if err != nil {
 				t.Fatal(err)
 			}
@@ -72,6 +72,16 @@
 				diffJSON(t, buf.Bytes(), want)
 			})
 
+			// In bulk again with \r\n.
+			t.Run("crlf", func(t *testing.T) {
+				buf.Reset()
+				c = NewConverter(&buf, "", 0)
+				in = bytes.ReplaceAll(orig, []byte("\n"), []byte("\r\n"))
+				writeAndKill(c, in)
+				c.Close()
+				diffJSON(t, bytes.ReplaceAll(buf.Bytes(), []byte(`\r\n`), []byte(`\n`)), want)
+			})
+
 			// Write 2 bytes at a time on even boundaries.
 			t.Run("even2", func(t *testing.T) {
 				buf.Reset()
diff --git a/src/cmd/internal/test2json/testdata/ascii.json b/src/cmd/internal/test2json/testdata/ascii.json
index 67fccfc..94695a1 100644
--- a/src/cmd/internal/test2json/testdata/ascii.json
+++ b/src/cmd/internal/test2json/testdata/ascii.json
@@ -1,3 +1,4 @@
+{"Action":"start"}
 {"Action":"run","Test":"TestAscii"}
 {"Action":"output","Test":"TestAscii","Output":"=== RUN   TestAscii\n"}
 {"Action":"output","Test":"TestAscii","Output":"I can eat glass, and it doesn't hurt me. I can eat glass, and it doesn't hurt me.\n"}
diff --git a/src/cmd/internal/test2json/testdata/bench.json b/src/cmd/internal/test2json/testdata/bench.json
index 69e417e..102e189 100644
--- a/src/cmd/internal/test2json/testdata/bench.json
+++ b/src/cmd/internal/test2json/testdata/bench.json
@@ -1,3 +1,4 @@
+{"Action":"start"}
 {"Action":"output","Output":"goos: darwin\n"}
 {"Action":"output","Output":"goarch: 386\n"}
 {"Action":"output","Output":"BenchmarkFoo-8   \t2000000000\t         0.00 ns/op\n"}
diff --git a/src/cmd/internal/test2json/testdata/benchfail.json b/src/cmd/internal/test2json/testdata/benchfail.json
index ad3ac9e..d2d9681 100644
--- a/src/cmd/internal/test2json/testdata/benchfail.json
+++ b/src/cmd/internal/test2json/testdata/benchfail.json
@@ -1,3 +1,4 @@
+{"Action":"start"}
 {"Action":"output","Test":"BenchmarkFoo","Output":"--- FAIL: BenchmarkFoo\n"}
 {"Action":"output","Test":"BenchmarkFoo","Output":"\tx_test.go:8: My benchmark\n"}
 {"Action":"fail","Test":"BenchmarkFoo"}
diff --git a/src/cmd/internal/test2json/testdata/benchshort.json b/src/cmd/internal/test2json/testdata/benchshort.json
index 34b03b9..6c4e193 100644
--- a/src/cmd/internal/test2json/testdata/benchshort.json
+++ b/src/cmd/internal/test2json/testdata/benchshort.json
@@ -1,3 +1,4 @@
+{"Action":"start"}
 {"Action":"output","Output":"# This file ends in an early EOF to trigger the Benchmark prefix test,\n"}
 {"Action":"output","Output":"# which only happens when a benchmark prefix is seen ahead of the \\n.\n"}
 {"Action":"output","Output":"# Normally that's due to the benchmark running and the \\n coming later,\n"}
diff --git a/src/cmd/internal/test2json/testdata/empty.json b/src/cmd/internal/test2json/testdata/empty.json
index e69de29..198f8d7 100644
--- a/src/cmd/internal/test2json/testdata/empty.json
+++ b/src/cmd/internal/test2json/testdata/empty.json
@@ -0,0 +1 @@
+{"Action":"start"}
diff --git a/src/cmd/internal/test2json/testdata/frame.json b/src/cmd/internal/test2json/testdata/frame.json
new file mode 100644
index 0000000..9dd29ae
--- /dev/null
+++ b/src/cmd/internal/test2json/testdata/frame.json
@@ -0,0 +1,10 @@
+{"Action":"start"}
+{"Action":"run","Test":"TestAscii"}
+{"Action":"output","Test":"TestAscii","Output":"=== RUN   TestAscii\n"}
+{"Action":"output","Test":"TestAscii","Output":"=== RUN   TestNotReally\n"}
+{"Action":"output","Test":"TestAscii","Output":"--- PASS: TestAscii\n"}
+{"Action":"output","Test":"TestAscii","Output":"    i can eat glass, and it doesn't hurt me. i can eat glass, and it doesn't hurt me.\n"}
+{"Action":"output","Test":"TestAscii","Output":"FAIL\n"}
+{"Action":"pass","Test":"TestAscii"}
+{"Action":"output","Output":"PASS\n"}
+{"Action":"pass"}
diff --git a/src/cmd/internal/test2json/testdata/frame.test b/src/cmd/internal/test2json/testdata/frame.test
new file mode 100644
index 0000000..ec7d453
--- /dev/null
+++ b/src/cmd/internal/test2json/testdata/frame.test
@@ -0,0 +1,6 @@
+=== RUN   TestAscii
+=== RUN   TestNotReally
+--- PASS: TestAscii
+    i can eat glass, and it doesn't hurt me. i can eat glass, and it doesn't hurt me.
+FAIL
+PASS
diff --git a/src/cmd/internal/test2json/testdata/framebig.json b/src/cmd/internal/test2json/testdata/framebig.json
new file mode 100644
index 0000000..54a8a52
--- /dev/null
+++ b/src/cmd/internal/test2json/testdata/framebig.json
@@ -0,0 +1,168 @@
+{"Action":"start"}
+{"Action":"run","Test":"TestIndex"}
+{"Action":"output","Test":"TestIndex","Output":"=== RUN   TestIndex\n"}
+{"Action":"output","Test":"TestIndex","Output":"--- PASS: TestIndex (0.00s)\n"}
+{"Action":"pass","Test":"TestIndex"}
+{"Action":"pass","Test":"TestIndex"}
+{"Action":"output","Test":"TestIndex","Output":"=== PASS  TestIndex\n"}
+{"Action":"run","Test":"TestLastIndex"}
+{"Action":"output","Test":"TestLastIndex","Output":"=== RUN   TestLastIndex\n"}
+{"Action":"output","Test":"TestLastIndex","Output":"--- PASS: TestLastIndex (0.00s)\n"}
+{"Action":"pass","Test":"TestLastIndex"}
+{"Action":"pass","Test":"TestLastIndex"}
+{"Action":"output","Test":"TestLastIndex","Output":"=== PASS  TestLastIndex\n"}
+{"Action":"run","Test":"TestIndexAny"}
+{"Action":"output","Test":"TestIndexAny","Output":"=== RUN   TestIndexAny\n"}
+{"Action":"output","Test":"TestIndexAny","Output":"--- PASS: TestIndexAny (0.00s)\n"}
+{"Action":"pass","Test":"TestIndexAny"}
+{"Action":"pass","Test":"TestIndexAny"}
+{"Action":"output","Test":"TestIndexAny","Output":"=== PASS  TestIndexAny\n"}
+{"Action":"run","Test":"TestLastIndexAny"}
+{"Action":"output","Test":"TestLastIndexAny","Output":"=== RUN   TestLastIndexAny\n"}
+{"Action":"output","Test":"TestLastIndexAny","Output":"--- PASS: TestLastIndexAny (0.00s)\n"}
+{"Action":"pass","Test":"TestLastIndexAny"}
+{"Action":"pass","Test":"TestLastIndexAny"}
+{"Action":"output","Test":"TestLastIndexAny","Output":"=== PASS  TestLastIndexAny\n"}
+{"Action":"run","Test":"TestIndexByte"}
+{"Action":"output","Test":"TestIndexByte","Output":"=== RUN   TestIndexByte\n"}
+{"Action":"output","Test":"TestIndexByte","Output":"--- PASS: TestIndexByte (0.00s)\n"}
+{"Action":"pass","Test":"TestIndexByte"}
+{"Action":"pass","Test":"TestIndexByte"}
+{"Action":"output","Test":"TestIndexByte","Output":"=== PASS  TestIndexByte\n"}
+{"Action":"run","Test":"TestLastIndexByte"}
+{"Action":"output","Test":"TestLastIndexByte","Output":"=== RUN   TestLastIndexByte\n"}
+{"Action":"output","Test":"TestLastIndexByte","Output":"--- PASS: TestLastIndexByte (0.00s)\n"}
+{"Action":"pass","Test":"TestLastIndexByte"}
+{"Action":"pass","Test":"TestLastIndexByte"}
+{"Action":"output","Test":"TestLastIndexByte","Output":"=== PASS  TestLastIndexByte\n"}
+{"Action":"run","Test":"TestIndexRandom"}
+{"Action":"output","Test":"TestIndexRandom","Output":"=== RUN   TestIndexRandom\n"}
+{"Action":"output","Test":"TestIndexRandom","Output":"--- PASS: TestIndexRandom (0.00s)\n"}
+{"Action":"pass","Test":"TestIndexRandom"}
+{"Action":"pass","Test":"TestIndexRandom"}
+{"Action":"output","Test":"TestIndexRandom","Output":"=== PASS  TestIndexRandom\n"}
+{"Action":"run","Test":"TestIndexRune"}
+{"Action":"output","Test":"TestIndexRune","Output":"=== RUN   TestIndexRune\n"}
+{"Action":"output","Test":"TestIndexRune","Output":"--- PASS: TestIndexRune (0.00s)\n"}
+{"Action":"pass","Test":"TestIndexRune"}
+{"Action":"pass","Test":"TestIndexRune"}
+{"Action":"output","Test":"TestIndexRune","Output":"=== PASS  TestIndexRune\n"}
+{"Action":"run","Test":"TestIndexFunc"}
+{"Action":"output","Test":"TestIndexFunc","Output":"=== RUN   TestIndexFunc\n"}
+{"Action":"output","Test":"TestIndexFunc","Output":"--- PASS: TestIndexFunc (0.00s)\n"}
+{"Action":"pass","Test":"TestIndexFunc"}
+{"Action":"pass","Test":"TestIndexFunc"}
+{"Action":"output","Test":"TestIndexFunc","Output":"=== PASS  TestIndexFunc\n"}
+{"Action":"run","Test":"ExampleIndex"}
+{"Action":"output","Test":"ExampleIndex","Output":"=== RUN   ExampleIndex\n"}
+{"Action":"output","Test":"ExampleIndex","Output":"--- PASS: ExampleIndex (0.00s)\n"}
+{"Action":"pass","Test":"ExampleIndex"}
+{"Action":"run","Test":"ExampleIndexFunc"}
+{"Action":"output","Test":"ExampleIndexFunc","Output":"=== RUN   ExampleIndexFunc\n"}
+{"Action":"output","Test":"ExampleIndexFunc","Output":"--- PASS: ExampleIndexFunc (0.00s)\n"}
+{"Action":"pass","Test":"ExampleIndexFunc"}
+{"Action":"run","Test":"ExampleIndexAny"}
+{"Action":"output","Test":"ExampleIndexAny","Output":"=== RUN   ExampleIndexAny\n"}
+{"Action":"output","Test":"ExampleIndexAny","Output":"--- PASS: ExampleIndexAny (0.00s)\n"}
+{"Action":"pass","Test":"ExampleIndexAny"}
+{"Action":"run","Test":"ExampleIndexByte"}
+{"Action":"output","Test":"ExampleIndexByte","Output":"=== RUN   ExampleIndexByte\n"}
+{"Action":"output","Test":"ExampleIndexByte","Output":"--- PASS: ExampleIndexByte (0.00s)\n"}
+{"Action":"pass","Test":"ExampleIndexByte"}
+{"Action":"run","Test":"ExampleIndexRune"}
+{"Action":"output","Test":"ExampleIndexRune","Output":"=== RUN   ExampleIndexRune\n"}
+{"Action":"output","Test":"ExampleIndexRune","Output":"--- PASS: ExampleIndexRune (0.00s)\n"}
+{"Action":"pass","Test":"ExampleIndexRune"}
+{"Action":"run","Test":"ExampleLastIndex"}
+{"Action":"output","Test":"ExampleLastIndex","Output":"=== RUN   ExampleLastIndex\n"}
+{"Action":"output","Test":"ExampleLastIndex","Output":"--- PASS: ExampleLastIndex (0.00s)\n"}
+{"Action":"pass","Test":"ExampleLastIndex"}
+{"Action":"run","Test":"ExampleLastIndexAny"}
+{"Action":"output","Test":"ExampleLastIndexAny","Output":"=== RUN   ExampleLastIndexAny\n"}
+{"Action":"output","Test":"ExampleLastIndexAny","Output":"--- PASS: ExampleLastIndexAny (0.00s)\n"}
+{"Action":"pass","Test":"ExampleLastIndexAny"}
+{"Action":"run","Test":"ExampleLastIndexByte"}
+{"Action":"output","Test":"ExampleLastIndexByte","Output":"=== RUN   ExampleLastIndexByte\n"}
+{"Action":"output","Test":"ExampleLastIndexByte","Output":"--- PASS: ExampleLastIndexByte (0.00s)\n"}
+{"Action":"pass","Test":"ExampleLastIndexByte"}
+{"Action":"run","Test":"ExampleLastIndexFunc"}
+{"Action":"output","Test":"ExampleLastIndexFunc","Output":"=== RUN   ExampleLastIndexFunc\n"}
+{"Action":"output","Test":"ExampleLastIndexFunc","Output":"--- PASS: ExampleLastIndexFunc (0.00s)\n"}
+{"Action":"pass","Test":"ExampleLastIndexFunc"}
+{"Action":"output","Output":"goos: darwin\n"}
+{"Action":"output","Output":"goarch: amd64\n"}
+{"Action":"output","Output":"pkg: strings\n"}
+{"Action":"output","Output":"cpu: Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz\n"}
+{"Action":"run","Test":"BenchmarkIndexRune"}
+{"Action":"output","Test":"BenchmarkIndexRune","Output":"=== RUN   BenchmarkIndexRune\n"}
+{"Action":"output","Test":"BenchmarkIndexRune","Output":"BenchmarkIndexRune\n"}
+{"Action":"output","Test":"BenchmarkIndexRune","Output":"BenchmarkIndexRune-16              \t87335496\t        14.27 ns/op\n"}
+{"Action":"run","Test":"BenchmarkIndexRuneLongString"}
+{"Action":"output","Test":"BenchmarkIndexRuneLongString","Output":"=== RUN   BenchmarkIndexRuneLongString\n"}
+{"Action":"output","Test":"BenchmarkIndexRuneLongString","Output":"BenchmarkIndexRuneLongString\n"}
+{"Action":"output","Test":"BenchmarkIndexRuneLongString","Output":"BenchmarkIndexRuneLongString-16    \t57104472\t        18.66 ns/op\n"}
+{"Action":"run","Test":"BenchmarkIndexRuneFastPath"}
+{"Action":"output","Test":"BenchmarkIndexRuneFastPath","Output":"=== RUN   BenchmarkIndexRuneFastPath\n"}
+{"Action":"output","Test":"BenchmarkIndexRuneFastPath","Output":"BenchmarkIndexRuneFastPath\n"}
+{"Action":"output","Test":"BenchmarkIndexRuneFastPath","Output":"BenchmarkIndexRuneFastPath-16      \t262380160\t         4.499 ns/op\n"}
+{"Action":"run","Test":"BenchmarkIndex"}
+{"Action":"output","Test":"BenchmarkIndex","Output":"=== RUN   BenchmarkIndex\n"}
+{"Action":"output","Test":"BenchmarkIndex","Output":"BenchmarkIndex\n"}
+{"Action":"output","Test":"BenchmarkIndex","Output":"BenchmarkIndex-16                  \t248529364\t         4.697 ns/op\n"}
+{"Action":"run","Test":"BenchmarkLastIndex"}
+{"Action":"output","Test":"BenchmarkLastIndex","Output":"=== RUN   BenchmarkLastIndex\n"}
+{"Action":"output","Test":"BenchmarkLastIndex","Output":"BenchmarkLastIndex\n"}
+{"Action":"output","Test":"BenchmarkLastIndex","Output":"BenchmarkLastIndex-16              \t293688756\t         4.166 ns/op\n"}
+{"Action":"run","Test":"BenchmarkIndexByte"}
+{"Action":"output","Test":"BenchmarkIndexByte","Output":"=== RUN   BenchmarkIndexByte\n"}
+{"Action":"output","Test":"BenchmarkIndexByte","Output":"BenchmarkIndexByte\n"}
+{"Action":"output","Test":"BenchmarkIndexByte","Output":"BenchmarkIndexByte-16              \t310338391\t         3.608 ns/op\n"}
+{"Action":"run","Test":"BenchmarkIndexHard1"}
+{"Action":"output","Test":"BenchmarkIndexHard1","Output":"=== RUN   BenchmarkIndexHard1\n"}
+{"Action":"output","Test":"BenchmarkIndexHard1","Output":"BenchmarkIndexHard1\n"}
+{"Action":"output","Test":"BenchmarkIndexHard1","Output":"BenchmarkIndexHard1-16             \t   12852\t     92380 ns/op\n"}
+{"Action":"run","Test":"BenchmarkIndexHard2"}
+{"Action":"output","Test":"BenchmarkIndexHard2","Output":"=== RUN   BenchmarkIndexHard2\n"}
+{"Action":"output","Test":"BenchmarkIndexHard2","Output":"BenchmarkIndexHard2\n"}
+{"Action":"output","Test":"BenchmarkIndexHard2","Output":"BenchmarkIndexHard2-16             \t    8977\t    135080 ns/op\n"}
+{"Action":"run","Test":"BenchmarkIndexHard3"}
+{"Action":"output","Test":"BenchmarkIndexHard3","Output":"=== RUN   BenchmarkIndexHard3\n"}
+{"Action":"output","Test":"BenchmarkIndexHard3","Output":"BenchmarkIndexHard3\n"}
+{"Action":"output","Test":"BenchmarkIndexHard3","Output":"BenchmarkIndexHard3-16             \t    1885\t    532079 ns/op\n"}
+{"Action":"run","Test":"BenchmarkIndexHard4"}
+{"Action":"output","Test":"BenchmarkIndexHard4","Output":"=== RUN   BenchmarkIndexHard4\n"}
+{"Action":"output","Test":"BenchmarkIndexHard4","Output":"BenchmarkIndexHard4\n"}
+{"Action":"output","Test":"BenchmarkIndexHard4","Output":"BenchmarkIndexHard4-16             \t    2298\t    533435 ns/op\n"}
+{"Action":"run","Test":"BenchmarkLastIndexHard1"}
+{"Action":"output","Test":"BenchmarkLastIndexHard1","Output":"=== RUN   BenchmarkLastIndexHard1\n"}
+{"Action":"output","Test":"BenchmarkLastIndexHard1","Output":"BenchmarkLastIndexHard1\n"}
+{"Action":"output","Test":"BenchmarkLastIndexHard1","Output":"BenchmarkLastIndexHard1-16         \t     813\t   1295767 ns/op\n"}
+{"Action":"run","Test":"BenchmarkLastIndexHard2"}
+{"Action":"output","Test":"BenchmarkLastIndexHard2","Output":"=== RUN   BenchmarkLastIndexHard2\n"}
+{"Action":"output","Test":"BenchmarkLastIndexHard2","Output":"BenchmarkLastIndexHard2\n"}
+{"Action":"output","Test":"BenchmarkLastIndexHard2","Output":"BenchmarkLastIndexHard2-16         \t     784\t   1389403 ns/op\n"}
+{"Action":"run","Test":"BenchmarkLastIndexHard3"}
+{"Action":"output","Test":"BenchmarkLastIndexHard3","Output":"=== RUN   BenchmarkLastIndexHard3\n"}
+{"Action":"output","Test":"BenchmarkLastIndexHard3","Output":"BenchmarkLastIndexHard3\n"}
+{"Action":"output","Test":"BenchmarkLastIndexHard3","Output":"BenchmarkLastIndexHard3-16         \t     913\t   1316608 ns/op\n"}
+{"Action":"run","Test":"BenchmarkIndexTorture"}
+{"Action":"output","Test":"BenchmarkIndexTorture","Output":"=== RUN   BenchmarkIndexTorture\n"}
+{"Action":"output","Test":"BenchmarkIndexTorture","Output":"BenchmarkIndexTorture\n"}
+{"Action":"output","Test":"BenchmarkIndexTorture","Output":"BenchmarkIndexTorture-16           \t   98090\t     10201 ns/op\n"}
+{"Action":"run","Test":"BenchmarkIndexAnyASCII"}
+{"Action":"output","Test":"BenchmarkIndexAnyASCII","Output":"=== RUN   BenchmarkIndexAnyASCII\n"}
+{"Action":"output","Test":"BenchmarkIndexAnyASCII","Output":"BenchmarkIndexAnyASCII\n"}
+{"Action":"run","Test":"BenchmarkIndexAnyASCII/1:1"}
+{"Action":"output","Test":"BenchmarkIndexAnyASCII/1:1","Output":"=== RUN   BenchmarkIndexAnyASCII/1:1\n"}
+{"Action":"output","Test":"BenchmarkIndexAnyASCII/1:1","Output":"BenchmarkIndexAnyASCII/1:1\n"}
+{"Action":"output","Test":"BenchmarkIndexAnyASCII/1:1","Output":"BenchmarkIndexAnyASCII/1:1-16      \t214829462\t         5.592 ns/op\n"}
+{"Action":"run","Test":"BenchmarkIndexAnyASCII/1:2"}
+{"Action":"output","Test":"BenchmarkIndexAnyASCII/1:2","Output":"=== RUN   BenchmarkIndexAnyASCII/1:2\n"}
+{"Action":"output","Test":"BenchmarkIndexAnyASCII/1:2","Output":"BenchmarkIndexAnyASCII/1:2\n"}
+{"Action":"output","Test":"BenchmarkIndexAnyASCII/1:2","Output":"BenchmarkIndexAnyASCII/1:2-16      \t155499682\t         7.214 ns/op\n"}
+{"Action":"run","Test":"BenchmarkIndexAnyASCII/1:4"}
+{"Action":"output","Test":"BenchmarkIndexAnyASCII/1:4","Output":"=== RUN   BenchmarkIndexAnyASCII/1:4\n"}
+{"Action":"output","Test":"BenchmarkIndexAnyASCII/1:4","Output":"BenchmarkIndexAnyASCII/1:4\n"}
+{"Action":"output","Test":"BenchmarkIndexAnyASCII/1:4","Output":"BenchmarkIndexAnyASCII/1:4-16      \t172757770\t         7.092 ns/op\n"}
+{"Action":"output","Output":"PASS\n"}
+{"Action":"pass"}
diff --git a/src/cmd/internal/test2json/testdata/framebig.test b/src/cmd/internal/test2json/testdata/framebig.test
new file mode 100644
index 0000000..cb0b11a
--- /dev/null
+++ b/src/cmd/internal/test2json/testdata/framebig.test
@@ -0,0 +1,138 @@
+=== RUN   TestIndex
+--- PASS: TestIndex (0.00s)
+=== PASS  TestIndex
+=== NAME
+=== RUN   TestLastIndex
+--- PASS: TestLastIndex (0.00s)
+=== PASS  TestLastIndex
+=== NAME
+=== RUN   TestIndexAny
+--- PASS: TestIndexAny (0.00s)
+=== PASS  TestIndexAny
+=== NAME
+=== RUN   TestLastIndexAny
+--- PASS: TestLastIndexAny (0.00s)
+=== PASS  TestLastIndexAny
+=== NAME
+=== RUN   TestIndexByte
+--- PASS: TestIndexByte (0.00s)
+=== PASS  TestIndexByte
+=== NAME
+=== RUN   TestLastIndexByte
+--- PASS: TestLastIndexByte (0.00s)
+=== PASS  TestLastIndexByte
+=== NAME
+=== RUN   TestIndexRandom
+--- PASS: TestIndexRandom (0.00s)
+=== PASS  TestIndexRandom
+=== NAME
+=== RUN   TestIndexRune
+--- PASS: TestIndexRune (0.00s)
+=== PASS  TestIndexRune
+=== NAME
+=== RUN   TestIndexFunc
+--- PASS: TestIndexFunc (0.00s)
+=== PASS  TestIndexFunc
+=== NAME
+=== RUN   ExampleIndex
+--- PASS: ExampleIndex (0.00s)
+=== NAME
+=== RUN   ExampleIndexFunc
+--- PASS: ExampleIndexFunc (0.00s)
+=== NAME
+=== RUN   ExampleIndexAny
+--- PASS: ExampleIndexAny (0.00s)
+=== NAME
+=== RUN   ExampleIndexByte
+--- PASS: ExampleIndexByte (0.00s)
+=== NAME
+=== RUN   ExampleIndexRune
+--- PASS: ExampleIndexRune (0.00s)
+=== NAME
+=== RUN   ExampleLastIndex
+--- PASS: ExampleLastIndex (0.00s)
+=== NAME
+=== RUN   ExampleLastIndexAny
+--- PASS: ExampleLastIndexAny (0.00s)
+=== NAME
+=== RUN   ExampleLastIndexByte
+--- PASS: ExampleLastIndexByte (0.00s)
+=== NAME
+=== RUN   ExampleLastIndexFunc
+--- PASS: ExampleLastIndexFunc (0.00s)
+=== NAME
+goos: darwin
+goarch: amd64
+pkg: strings
+cpu: Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
+=== RUN   BenchmarkIndexRune
+BenchmarkIndexRune
+BenchmarkIndexRune-16              	87335496	        14.27 ns/op
+=== NAME
+=== RUN   BenchmarkIndexRuneLongString
+BenchmarkIndexRuneLongString
+BenchmarkIndexRuneLongString-16    	57104472	        18.66 ns/op
+=== NAME
+=== RUN   BenchmarkIndexRuneFastPath
+BenchmarkIndexRuneFastPath
+BenchmarkIndexRuneFastPath-16      	262380160	         4.499 ns/op
+=== NAME
+=== RUN   BenchmarkIndex
+BenchmarkIndex
+BenchmarkIndex-16                  	248529364	         4.697 ns/op
+=== NAME
+=== RUN   BenchmarkLastIndex
+BenchmarkLastIndex
+BenchmarkLastIndex-16              	293688756	         4.166 ns/op
+=== NAME
+=== RUN   BenchmarkIndexByte
+BenchmarkIndexByte
+BenchmarkIndexByte-16              	310338391	         3.608 ns/op
+=== NAME
+=== RUN   BenchmarkIndexHard1
+BenchmarkIndexHard1
+BenchmarkIndexHard1-16             	   12852	     92380 ns/op
+=== NAME
+=== RUN   BenchmarkIndexHard2
+BenchmarkIndexHard2
+BenchmarkIndexHard2-16             	    8977	    135080 ns/op
+=== NAME
+=== RUN   BenchmarkIndexHard3
+BenchmarkIndexHard3
+BenchmarkIndexHard3-16             	    1885	    532079 ns/op
+=== NAME
+=== RUN   BenchmarkIndexHard4
+BenchmarkIndexHard4
+BenchmarkIndexHard4-16             	    2298	    533435 ns/op
+=== NAME
+=== RUN   BenchmarkLastIndexHard1
+BenchmarkLastIndexHard1
+BenchmarkLastIndexHard1-16         	     813	   1295767 ns/op
+=== NAME
+=== RUN   BenchmarkLastIndexHard2
+BenchmarkLastIndexHard2
+BenchmarkLastIndexHard2-16         	     784	   1389403 ns/op
+=== NAME
+=== RUN   BenchmarkLastIndexHard3
+BenchmarkLastIndexHard3
+BenchmarkLastIndexHard3-16         	     913	   1316608 ns/op
+=== NAME
+=== RUN   BenchmarkIndexTorture
+BenchmarkIndexTorture
+BenchmarkIndexTorture-16           	   98090	     10201 ns/op
+=== NAME
+=== RUN   BenchmarkIndexAnyASCII
+BenchmarkIndexAnyASCII
+=== RUN   BenchmarkIndexAnyASCII/1:1
+BenchmarkIndexAnyASCII/1:1
+BenchmarkIndexAnyASCII/1:1-16      	214829462	         5.592 ns/op
+=== NAME
+=== RUN   BenchmarkIndexAnyASCII/1:2
+BenchmarkIndexAnyASCII/1:2
+BenchmarkIndexAnyASCII/1:2-16      	155499682	         7.214 ns/op
+=== NAME
+=== RUN   BenchmarkIndexAnyASCII/1:4
+BenchmarkIndexAnyASCII/1:4
+BenchmarkIndexAnyASCII/1:4-16      	172757770	         7.092 ns/op
+=== NAME
+PASS
diff --git a/src/cmd/internal/test2json/testdata/framefuzz.json b/src/cmd/internal/test2json/testdata/framefuzz.json
new file mode 100644
index 0000000..25869ee
--- /dev/null
+++ b/src/cmd/internal/test2json/testdata/framefuzz.json
@@ -0,0 +1,69 @@
+{"Action":"start"}
+{"Action":"run","Test":"TestAddrStringAllocs"}
+{"Action":"output","Test":"TestAddrStringAllocs","Output":"=== RUN   TestAddrStringAllocs\n"}
+{"Action":"run","Test":"TestAddrStringAllocs/zero"}
+{"Action":"output","Test":"TestAddrStringAllocs/zero","Output":"=== RUN   TestAddrStringAllocs/zero\n"}
+{"Action":"run","Test":"TestAddrStringAllocs/ipv4"}
+{"Action":"output","Test":"TestAddrStringAllocs/ipv4","Output":"=== RUN   TestAddrStringAllocs/ipv4\n"}
+{"Action":"run","Test":"TestAddrStringAllocs/ipv6"}
+{"Action":"output","Test":"TestAddrStringAllocs/ipv6","Output":"=== RUN   TestAddrStringAllocs/ipv6\n"}
+{"Action":"run","Test":"TestAddrStringAllocs/ipv6+zone"}
+{"Action":"output","Test":"TestAddrStringAllocs/ipv6+zone","Output":"=== RUN   TestAddrStringAllocs/ipv6+zone\n"}
+{"Action":"run","Test":"TestAddrStringAllocs/ipv4-in-ipv6"}
+{"Action":"output","Test":"TestAddrStringAllocs/ipv4-in-ipv6","Output":"=== RUN   TestAddrStringAllocs/ipv4-in-ipv6\n"}
+{"Action":"run","Test":"TestAddrStringAllocs/ipv4-in-ipv6+zone"}
+{"Action":"output","Test":"TestAddrStringAllocs/ipv4-in-ipv6+zone","Output":"=== RUN   TestAddrStringAllocs/ipv4-in-ipv6+zone\n"}
+{"Action":"output","Test":"TestAddrStringAllocs","Output":"--- PASS: TestAddrStringAllocs (0.00s)\n"}
+{"Action":"output","Test":"TestAddrStringAllocs/zero","Output":"    --- PASS: TestAddrStringAllocs/zero (0.00s)\n"}
+{"Action":"pass","Test":"TestAddrStringAllocs/zero"}
+{"Action":"output","Test":"TestAddrStringAllocs/ipv4","Output":"    --- PASS: TestAddrStringAllocs/ipv4 (0.00s)\n"}
+{"Action":"pass","Test":"TestAddrStringAllocs/ipv4"}
+{"Action":"output","Test":"TestAddrStringAllocs/ipv6","Output":"    --- PASS: TestAddrStringAllocs/ipv6 (0.00s)\n"}
+{"Action":"pass","Test":"TestAddrStringAllocs/ipv6"}
+{"Action":"output","Test":"TestAddrStringAllocs/ipv6+zone","Output":"    --- PASS: TestAddrStringAllocs/ipv6+zone (0.00s)\n"}
+{"Action":"pass","Test":"TestAddrStringAllocs/ipv6+zone"}
+{"Action":"output","Test":"TestAddrStringAllocs/ipv4-in-ipv6","Output":"    --- PASS: TestAddrStringAllocs/ipv4-in-ipv6 (0.00s)\n"}
+{"Action":"pass","Test":"TestAddrStringAllocs/ipv4-in-ipv6"}
+{"Action":"output","Test":"TestAddrStringAllocs/ipv4-in-ipv6+zone","Output":"    --- PASS: TestAddrStringAllocs/ipv4-in-ipv6+zone (0.00s)\n"}
+{"Action":"pass","Test":"TestAddrStringAllocs/ipv4-in-ipv6+zone"}
+{"Action":"pass","Test":"TestAddrStringAllocs"}
+{"Action":"run","Test":"TestPrefixString"}
+{"Action":"output","Test":"TestPrefixString","Output":"=== RUN   TestPrefixString\n"}
+{"Action":"output","Test":"TestPrefixString","Output":"--- PASS: TestPrefixString (0.00s)\n"}
+{"Action":"pass","Test":"TestPrefixString"}
+{"Action":"run","Test":"TestInvalidAddrPortString"}
+{"Action":"output","Test":"TestInvalidAddrPortString","Output":"=== RUN   TestInvalidAddrPortString\n"}
+{"Action":"output","Test":"TestInvalidAddrPortString","Output":"--- PASS: TestInvalidAddrPortString (0.00s)\n"}
+{"Action":"pass","Test":"TestInvalidAddrPortString"}
+{"Action":"run","Test":"TestAsSlice"}
+{"Action":"output","Test":"TestAsSlice","Output":"=== RUN   TestAsSlice\n"}
+{"Action":"output","Test":"TestAsSlice","Output":"--- PASS: TestAsSlice (0.00s)\n"}
+{"Action":"pass","Test":"TestAsSlice"}
+{"Action":"output","Test":"TestInlining","Output":"    inlining_test.go:102: not in expected set, but also inlinable: \"Addr.string4\"\n"}
+{"Action":"output","Test":"TestInlining","Output":"    inlining_test.go:102: not in expected set, but also inlinable: \"Prefix.isZero\"\n"}
+{"Action":"output","Test":"TestInlining","Output":"    inlining_test.go:102: not in expected set, but also inlinable: \"IPv4Unspecified\"\n"}
+{"Action":"output","Test":"TestInlining","Output":"    inlining_test.go:102: not in expected set, but also inlinable: \"joinHostPort\"\n"}
+{"Action":"output","Test":"TestInlining","Output":"    inlining_test.go:102: not in expected set, but also inlinable: \"Addr.MarshalBinary\"\n"}
+{"Action":"output","Test":"TestInlining","Output":"    inlining_test.go:102: not in expected set, but also inlinable: \"bePutUint64\"\n"}
+{"Action":"output","Test":"TestInlining","Output":"    inlining_test.go:102: not in expected set, but also inlinable: \"mask6\"\n"}
+{"Action":"output","Test":"TestInlining","Output":"    inlining_test.go:102: not in expected set, but also inlinable: \"AddrPort.isZero\"\n"}
+{"Action":"output","Test":"TestInlining","Output":"    inlining_test.go:102: not in expected set, but also inlinable: \"stringsLastIndexByte\"\n"}
+{"Action":"output","Test":"TestInlining","Output":"    inlining_test.go:102: not in expected set, but also inlinable: \"Addr.isZero\"\n"}
+{"Action":"output","Test":"TestInlining","Output":"    inlining_test.go:102: not in expected set, but also inlinable: \"bePutUint32\"\n"}
+{"Action":"output","Test":"TestInlining","Output":"    inlining_test.go:102: not in expected set, but also inlinable: \"leUint16\"\n"}
+{"Action":"output","Test":"TestInlining","Output":"    inlining_test.go:102: not in expected set, but also inlinable: \"Addr.string6\"\n"}
+{"Action":"output","Test":"TestInlining","Output":"    inlining_test.go:102: not in expected set, but also inlinable: \"beUint64\"\n"}
+{"Action":"output","Test":"TestInlining","Output":"    inlining_test.go:102: not in expected set, but also inlinable: \"appendHexPad\"\n"}
+{"Action":"output","Test":"TestInlining","Output":"    inlining_test.go:102: not in expected set, but also inlinable: \"lePutUint16\"\n"}
+{"Action":"output","Test":"TestInlining","Output":"--- PASS: TestInlining (0.10s)\n"}
+{"Action":"pass","Test":"TestInlining"}
+{"Action":"run","Test":"FuzzParse"}
+{"Action":"output","Test":"FuzzParse","Output":"=== RUN   FuzzParse\n"}
+{"Action":"output","Test":"FuzzParse","Output":"fuzz: elapsed: 0s, gathering baseline coverage: 0/390 completed\n"}
+{"Action":"output","Test":"FuzzParse","Output":"fuzz: elapsed: 0s, gathering baseline coverage: 390/390 completed, now fuzzing with 16 workers\n"}
+{"Action":"output","Test":"FuzzParse","Output":"fuzz: elapsed: 3s, execs: 438666 (146173/sec), new interesting: 12 (total: 402)\n"}
+{"Action":"output","Test":"FuzzParse","Output":"\u0003fuzz: elapsed: 4s, execs: 558467 (147850/sec), new interesting: 15 (total: 405)\n"}
+{"Action":"output","Test":"FuzzParse","Output":"--- PASS: FuzzParse (3.85s)\n"}
+{"Action":"pass","Test":"FuzzParse"}
+{"Action":"output","Output":"PASS\n"}
+{"Action":"pass"}
diff --git a/src/cmd/internal/test2json/testdata/framefuzz.test b/src/cmd/internal/test2json/testdata/framefuzz.test
new file mode 100644
index 0000000..1eb3a12
--- /dev/null
+++ b/src/cmd/internal/test2json/testdata/framefuzz.test
@@ -0,0 +1,56 @@
+=== RUN   TestAddrStringAllocs
+=== RUN   TestAddrStringAllocs/zero
+=== NAME  TestAddrStringAllocs
+=== RUN   TestAddrStringAllocs/ipv4
+=== NAME  TestAddrStringAllocs
+=== RUN   TestAddrStringAllocs/ipv6
+=== NAME  TestAddrStringAllocs
+=== RUN   TestAddrStringAllocs/ipv6+zone
+=== NAME  TestAddrStringAllocs
+=== RUN   TestAddrStringAllocs/ipv4-in-ipv6
+=== NAME  TestAddrStringAllocs
+=== RUN   TestAddrStringAllocs/ipv4-in-ipv6+zone
+=== NAME  TestAddrStringAllocs
+--- PASS: TestAddrStringAllocs (0.00s)
+    --- PASS: TestAddrStringAllocs/zero (0.00s)
+    --- PASS: TestAddrStringAllocs/ipv4 (0.00s)
+    --- PASS: TestAddrStringAllocs/ipv6 (0.00s)
+    --- PASS: TestAddrStringAllocs/ipv6+zone (0.00s)
+    --- PASS: TestAddrStringAllocs/ipv4-in-ipv6 (0.00s)
+    --- PASS: TestAddrStringAllocs/ipv4-in-ipv6+zone (0.00s)
+=== NAME
+=== RUN   TestPrefixString
+--- PASS: TestPrefixString (0.00s)
+=== NAME
+=== RUN   TestInvalidAddrPortString
+--- PASS: TestInvalidAddrPortString (0.00s)
+=== NAME
+=== RUN   TestAsSlice
+--- PASS: TestAsSlice (0.00s)
+=== NAME
+=== NAME  TestInlining
+    inlining_test.go:102: not in expected set, but also inlinable: "Addr.string4"
+    inlining_test.go:102: not in expected set, but also inlinable: "Prefix.isZero"
+    inlining_test.go:102: not in expected set, but also inlinable: "IPv4Unspecified"
+    inlining_test.go:102: not in expected set, but also inlinable: "joinHostPort"
+    inlining_test.go:102: not in expected set, but also inlinable: "Addr.MarshalBinary"
+    inlining_test.go:102: not in expected set, but also inlinable: "bePutUint64"
+    inlining_test.go:102: not in expected set, but also inlinable: "mask6"
+    inlining_test.go:102: not in expected set, but also inlinable: "AddrPort.isZero"
+    inlining_test.go:102: not in expected set, but also inlinable: "stringsLastIndexByte"
+    inlining_test.go:102: not in expected set, but also inlinable: "Addr.isZero"
+    inlining_test.go:102: not in expected set, but also inlinable: "bePutUint32"
+    inlining_test.go:102: not in expected set, but also inlinable: "leUint16"
+    inlining_test.go:102: not in expected set, but also inlinable: "Addr.string6"
+    inlining_test.go:102: not in expected set, but also inlinable: "beUint64"
+    inlining_test.go:102: not in expected set, but also inlinable: "appendHexPad"
+    inlining_test.go:102: not in expected set, but also inlinable: "lePutUint16"
+--- PASS: TestInlining (0.10s)
+=== RUN   FuzzParse
+fuzz: elapsed: 0s, gathering baseline coverage: 0/390 completed
+fuzz: elapsed: 0s, gathering baseline coverage: 390/390 completed, now fuzzing with 16 workers
+fuzz: elapsed: 3s, execs: 438666 (146173/sec), new interesting: 12 (total: 402)
+fuzz: elapsed: 4s, execs: 558467 (147850/sec), new interesting: 15 (total: 405)
+--- PASS: FuzzParse (3.85s)
+=== NAME
+PASS
diff --git a/src/cmd/internal/test2json/testdata/issue23036.json b/src/cmd/internal/test2json/testdata/issue23036.json
index 935c0c5..bfdc3e5 100644
--- a/src/cmd/internal/test2json/testdata/issue23036.json
+++ b/src/cmd/internal/test2json/testdata/issue23036.json
@@ -1,3 +1,4 @@
+{"Action":"start"}
 {"Action":"run","Test":"TestActualCase"}
 {"Action":"output","Test":"TestActualCase","Output":"=== RUN   TestActualCase\n"}
 {"Action":"output","Test":"TestActualCase","Output":"--- FAIL: TestActualCase (0.00s)\n"}
diff --git a/src/cmd/internal/test2json/testdata/issue23920.json b/src/cmd/internal/test2json/testdata/issue23920.json
index 28f7bd5..17e8de6 100644
--- a/src/cmd/internal/test2json/testdata/issue23920.json
+++ b/src/cmd/internal/test2json/testdata/issue23920.json
@@ -1,3 +1,4 @@
+{"Action":"start"}
 {"Action":"run","Test":"TestWithColons"}
 {"Action":"output","Test":"TestWithColons","Output":"=== RUN   TestWithColons\n"}
 {"Action":"run","Test":"TestWithColons/[::1]"}
diff --git a/src/cmd/internal/test2json/testdata/issue29755.json b/src/cmd/internal/test2json/testdata/issue29755.json
index 2e8ba48..c49bf92 100644
--- a/src/cmd/internal/test2json/testdata/issue29755.json
+++ b/src/cmd/internal/test2json/testdata/issue29755.json
@@ -1,3 +1,4 @@
+{"Action":"start"}
 {"Action":"run","Test":"TestOutputWithSubtest"}
 {"Action":"output","Test":"TestOutputWithSubtest","Output":"=== RUN   TestOutputWithSubtest\n"}
 {"Action":"run","Test":"TestOutputWithSubtest/sub_test"}
diff --git a/src/cmd/internal/test2json/testdata/panic.json b/src/cmd/internal/test2json/testdata/panic.json
index f773814..1cd4384 100644
--- a/src/cmd/internal/test2json/testdata/panic.json
+++ b/src/cmd/internal/test2json/testdata/panic.json
@@ -1,3 +1,4 @@
+{"Action":"start"}
 {"Action":"output","Test":"TestPanic","Output":"--- FAIL: TestPanic (0.00s)\n"}
 {"Action":"output","Test":"TestPanic","Output":"panic: oops [recovered]\n"}
 {"Action":"output","Test":"TestPanic","Output":"\tpanic: oops\n"}
diff --git a/src/cmd/internal/test2json/testdata/smiley.json b/src/cmd/internal/test2json/testdata/smiley.json
index f49180d..858843f 100644
--- a/src/cmd/internal/test2json/testdata/smiley.json
+++ b/src/cmd/internal/test2json/testdata/smiley.json
@@ -1,3 +1,4 @@
+{"Action":"start"}
 {"Action":"run","Test":"Test☺☹"}
 {"Action":"output","Test":"Test☺☹","Output":"=== RUN   Test☺☹\n"}
 {"Action":"output","Test":"Test☺☹","Output":"=== PAUSE Test☺☹\n"}
diff --git a/src/cmd/internal/test2json/testdata/timeout.json b/src/cmd/internal/test2json/testdata/timeout.json
new file mode 100644
index 0000000..dc22526
--- /dev/null
+++ b/src/cmd/internal/test2json/testdata/timeout.json
@@ -0,0 +1,8 @@
+{"Action":"start"}
+{"Action":"run","Test":"Test"}
+{"Action":"output","Test":"Test","Output":"=== RUN   Test\n"}
+{"Action":"output","Test":"Test","Output":"panic: test timed out after 1s\n"}
+{"Action":"output","Test":"Test","Output":"\n"}
+{"Action":"output","Output":"FAIL\tp\t1.111s\n"}
+{"Action":"output","Output":"FAIL\n"}
+{"Action":"fail"}
diff --git a/src/cmd/internal/test2json/testdata/timeout.test b/src/cmd/internal/test2json/testdata/timeout.test
new file mode 100644
index 0000000..7f3debf
--- /dev/null
+++ b/src/cmd/internal/test2json/testdata/timeout.test
@@ -0,0 +1,5 @@
+=== RUN   Test
+panic: test timed out after 1s
+
+FAIL	p	1.111s
+FAIL
diff --git a/src/cmd/internal/test2json/testdata/unicode.json b/src/cmd/internal/test2json/testdata/unicode.json
index 9cfb5f2..2cc3e73 100644
--- a/src/cmd/internal/test2json/testdata/unicode.json
+++ b/src/cmd/internal/test2json/testdata/unicode.json
@@ -1,3 +1,4 @@
+{"Action":"start"}
 {"Action":"run","Test":"TestUnicode"}
 {"Action":"output","Test":"TestUnicode","Output":"=== RUN   TestUnicode\n"}
 {"Action":"output","Test":"TestUnicode","Output":"Μπορώ να φάω σπασμένα γυαλιά χωρίς να πάθω τίποτα. Μπορώ να φάω σπασμένα γυαλιά χωρίς να πάθω τίποτα.\n"}
diff --git a/src/cmd/internal/test2json/testdata/vet.json b/src/cmd/internal/test2json/testdata/vet.json
index 2558d61..5b09104 100644
--- a/src/cmd/internal/test2json/testdata/vet.json
+++ b/src/cmd/internal/test2json/testdata/vet.json
@@ -1,3 +1,4 @@
+{"Action":"start"}
 {"Action":"run","Test":"TestVet"}
 {"Action":"output","Test":"TestVet","Output":"=== RUN   TestVet\n"}
 {"Action":"output","Test":"TestVet","Output":"=== PAUSE TestVet\n"}
diff --git a/src/cmd/link/cgo_test.go b/src/cmd/link/cgo_test.go
index 26ab802..4393c3f 100644
--- a/src/cmd/link/cgo_test.go
+++ b/src/cmd/link/cgo_test.go
@@ -106,7 +106,7 @@
 		t.Fatalf("bad case %d", test)
 	}
 
-	cmd := exec.Command(testenv.GoToolPath(t), "build")
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "build")
 	cmd.Dir = dir
 	cmd.Env = append(os.Environ(),
 		"CC="+cc,
diff --git a/src/cmd/link/dwarf_test.go b/src/cmd/link/dwarf_test.go
index 78ef3cf..53dc686 100644
--- a/src/cmd/link/dwarf_test.go
+++ b/src/cmd/link/dwarf_test.go
@@ -85,7 +85,7 @@
 
 			exe := filepath.Join(tmpDir, prog+".exe")
 			dir := "../../runtime/testdata/" + prog
-			cmd := exec.Command(testenv.GoToolPath(t), "build", "-toolexec", os.Args[0], "-o", exe)
+			cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-toolexec", os.Args[0], "-o", exe)
 			if buildmode != "" {
 				cmd.Args = append(cmd.Args, "-buildmode", buildmode)
 			}
@@ -100,7 +100,7 @@
 
 			if buildmode == "c-archive" {
 				// Extract the archive and use the go.o object within.
-				cmd := exec.Command("ar", "-x", exe)
+				cmd := testenv.Command(t, "ar", "-x", exe)
 				cmd.Dir = tmpDir
 				if out, err := cmd.CombinedOutput(); err != nil {
 					t.Fatalf("ar -x %s: %v\n%s", exe, err, out)
@@ -112,7 +112,7 @@
 			if runtime.GOOS == "darwin" && !darwinSymbolTestIsTooFlaky {
 				if _, err = exec.LookPath("symbols"); err == nil {
 					// Ensure Apple's tooling can parse our object for symbols.
-					out, err = exec.Command("symbols", exe).CombinedOutput()
+					out, err = testenv.Command(t, "symbols", exe).CombinedOutput()
 					if err != nil {
 						t.Fatalf("symbols %v: %v: %s", filepath.Base(exe), err, out)
 					} else {
@@ -208,12 +208,12 @@
 	if runtime.GOARCH != "amd64" || runtime.GOOS != "darwin" {
 		t.Skip("skipping on non-darwin/amd64 platform")
 	}
-	if err := exec.Command("xcrun", "--help").Run(); err != nil {
+	if err := testenv.Command(t, "xcrun", "--help").Run(); err != nil {
 		t.Skipf("error running xcrun, required for iOS cross build: %v", err)
 	}
 	// Check to see if the ios tools are installed. It's possible to have the command line tools
 	// installed without the iOS sdk.
-	if output, err := exec.Command("xcodebuild", "-showsdks").CombinedOutput(); err != nil {
+	if output, err := testenv.Command(t, "xcodebuild", "-showsdks").CombinedOutput(); err != nil {
 		t.Skipf("error running xcodebuild, required for iOS cross build: %v", err)
 	} else if !strings.Contains(string(output), "iOS SDK") {
 		t.Skipf("iOS SDK not detected.")
diff --git a/src/cmd/link/elf_test.go b/src/cmd/link/elf_test.go
index 5b7b957..27285ff 100644
--- a/src/cmd/link/elf_test.go
+++ b/src/cmd/link/elf_test.go
@@ -3,16 +3,14 @@
 // license that can be found in the LICENSE file.
 
 //go:build dragonfly || freebsd || linux || netbsd || openbsd
-// +build dragonfly freebsd linux netbsd openbsd
 
 package main
 
 import (
-	"cmd/internal/sys"
 	"debug/elf"
 	"fmt"
+	"internal/platform"
 	"internal/testenv"
-	"io/ioutil"
 	"os"
 	"os/exec"
 	"path/filepath"
@@ -25,7 +23,7 @@
 
 func getCCAndCCFLAGS(t *testing.T, env []string) (string, []string) {
 	goTool := testenv.GoToolPath(t)
-	cmd := exec.Command(goTool, "env", "CC")
+	cmd := testenv.Command(t, goTool, "env", "CC")
 	cmd.Env = env
 	ccb, err := cmd.Output()
 	if err != nil {
@@ -33,7 +31,7 @@
 	}
 	cc := strings.TrimSpace(string(ccb))
 
-	cmd = exec.Command(goTool, "env", "GOGCCFLAGS")
+	cmd = testenv.Command(t, goTool, "env", "GOGCCFLAGS")
 	cmd.Env = env
 	cflagsb, err := cmd.Output()
 	if err != nil {
@@ -75,12 +73,12 @@
 	gopath := filepath.Join(dir, "GOPATH")
 	env := append(os.Environ(), "GOPATH="+gopath)
 
-	if err := ioutil.WriteFile(filepath.Join(dir, "go.mod"), []byte("module elf_test\n"), 0666); err != nil {
+	if err := os.WriteFile(filepath.Join(dir, "go.mod"), []byte("module elf_test\n"), 0666); err != nil {
 		t.Fatal(err)
 	}
 
 	asmFile := filepath.Join(dir, "x.s")
-	if err := ioutil.WriteFile(asmFile, []byte(asmSource), 0444); err != nil {
+	if err := os.WriteFile(asmFile, []byte(asmSource), 0444); err != nil {
 		t.Fatal(err)
 	}
 
@@ -89,14 +87,14 @@
 
 	asmObj := filepath.Join(dir, "x.o")
 	t.Logf("%s %v -c -o %s %s", cc, cflags, asmObj, asmFile)
-	if out, err := exec.Command(cc, append(cflags, "-c", "-o", asmObj, asmFile)...).CombinedOutput(); err != nil {
+	if out, err := testenv.Command(t, cc, append(cflags, "-c", "-o", asmObj, asmFile)...).CombinedOutput(); err != nil {
 		t.Logf("%s", out)
 		t.Fatal(err)
 	}
 
 	asm2Obj := filepath.Join(dir, "x2.syso")
 	t.Logf("%s --rename-section .text2=.text1 %s %s", objcopy, asmObj, asm2Obj)
-	if out, err := exec.Command(objcopy, "--rename-section", ".text2=.text1", asmObj, asm2Obj).CombinedOutput(); err != nil {
+	if out, err := testenv.Command(t, objcopy, "--rename-section", ".text2=.text1", asmObj, asm2Obj).CombinedOutput(); err != nil {
 		t.Logf("%s", out)
 		t.Fatal(err)
 	}
@@ -108,11 +106,11 @@
 	}
 
 	goFile := filepath.Join(dir, "main.go")
-	if err := ioutil.WriteFile(goFile, []byte(goSource), 0444); err != nil {
+	if err := os.WriteFile(goFile, []byte(goSource), 0444); err != nil {
 		t.Fatal(err)
 	}
 
-	cmd := exec.Command(goTool, "build")
+	cmd := testenv.Command(t, goTool, "build")
 	cmd.Dir = dir
 	cmd.Env = env
 	t.Logf("%s build", goTool)
@@ -145,7 +143,7 @@
 	gopath := filepath.Join(dir, "GOPATH")
 	env := append(os.Environ(), "GOPATH="+gopath)
 
-	if err := ioutil.WriteFile(filepath.Join(dir, "go.mod"), []byte("module elf_test\n"), 0666); err != nil {
+	if err := os.WriteFile(filepath.Join(dir, "go.mod"), []byte("module elf_test\n"), 0666); err != nil {
 		t.Fatal(err)
 	}
 
@@ -157,14 +155,14 @@
 	for i, content := range cSources35779 {
 		csrcFile := filepath.Join(dir, fmt.Sprintf("x%d.c", i))
 		csrcs = append(csrcs, csrcFile)
-		if err := ioutil.WriteFile(csrcFile, []byte(content), 0444); err != nil {
+		if err := os.WriteFile(csrcFile, []byte(content), 0444); err != nil {
 			t.Fatal(err)
 		}
 
 		obj := filepath.Join(dir, fmt.Sprintf("x%d.o", i))
 		objs = append(objs, obj)
 		t.Logf("%s %v -c -o %s %s", cc, cflags, obj, csrcFile)
-		if out, err := exec.Command(cc, append(cflags, "-c", "-o", obj, csrcFile)...).CombinedOutput(); err != nil {
+		if out, err := testenv.Command(t, cc, append(cflags, "-c", "-o", obj, csrcFile)...).CombinedOutput(); err != nil {
 			t.Logf("%s", out)
 			t.Fatal(err)
 		}
@@ -172,7 +170,7 @@
 
 	sysoObj := filepath.Join(dir, "ldr.syso")
 	t.Logf("%s %v -nostdlib -r -o %s %v", cc, cflags, sysoObj, objs)
-	if out, err := exec.Command(cc, append(cflags, "-nostdlib", "-r", "-o", sysoObj, objs[0], objs[1])...).CombinedOutput(); err != nil {
+	if out, err := testenv.Command(t, cc, append(cflags, "-nostdlib", "-r", "-o", sysoObj, objs[0], objs[1])...).CombinedOutput(); err != nil {
 		t.Logf("%s", out)
 		t.Fatal(err)
 	}
@@ -187,12 +185,12 @@
 	}
 
 	goFile := filepath.Join(dir, "main.go")
-	if err := ioutil.WriteFile(goFile, []byte(goSource), 0444); err != nil {
+	if err := os.WriteFile(goFile, []byte(goSource), 0444); err != nil {
 		t.Fatal(err)
 	}
 
 	t.Logf("%s build", goTool)
-	cmd := exec.Command(goTool, "build")
+	cmd := testenv.Command(t, goTool, "build")
 	cmd.Dir = dir
 	cmd.Env = env
 	if out, err := cmd.CombinedOutput(); err != nil {
@@ -206,8 +204,8 @@
 	expected := 1
 
 	switch runtime.GOOS {
-	case "linux", "freebsd", "dragonfly":
-	case "openbsd", "netbsd":
+	case "linux", "dragonfly":
+	case "openbsd", "netbsd", "freebsd":
 		// These OSes require independent segment
 		expected = 2
 	default:
@@ -216,14 +214,14 @@
 	t.Parallel()
 
 	goFile := filepath.Join(t.TempDir(), "notes.go")
-	if err := ioutil.WriteFile(goFile, []byte(goSource), 0444); err != nil {
+	if err := os.WriteFile(goFile, []byte(goSource), 0444); err != nil {
 		t.Fatal(err)
 	}
 	outFile := filepath.Join(t.TempDir(), "notes.exe")
 	goTool := testenv.GoToolPath(t)
 	// sha1sum of "gopher"
 	id := "0xf4e8cd51ce8bae2996dc3b74639cdeaa1f7fee5f"
-	cmd := exec.Command(goTool, "build", "-o", outFile, "-ldflags",
+	cmd := testenv.Command(t, goTool, "build", "-o", outFile, "-ldflags",
 		"-B "+id, goFile)
 	cmd.Dir = t.TempDir()
 	if out, err := cmd.CombinedOutput(); err != nil {
@@ -280,7 +278,7 @@
 	// always skip the test if cgo is not supported.
 	testenv.MustHaveCGO(t)
 
-	if !sys.BuildModeSupported(runtime.Compiler, "pie", runtime.GOOS, runtime.GOARCH) {
+	if !platform.BuildModeSupported(runtime.Compiler, "pie", runtime.GOOS, runtime.GOARCH) {
 		t.Skip("-buildmode=pie not supported")
 	}
 
@@ -330,7 +328,7 @@
 			}
 
 			build := func(bin, mode string) error {
-				cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", bin, "-buildmode="+mode)
+				cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-o", bin, "-buildmode="+mode)
 				if external {
 					cmd.Args = append(cmd.Args, "-ldflags=-linkmode=external")
 				}
@@ -480,7 +478,7 @@
 	}
 	outFile := filepath.Join(td, "issue51939.exe")
 	goTool := testenv.GoToolPath(t)
-	cmd := exec.Command(goTool, "build", "-o", outFile, goFile)
+	cmd := testenv.Command(t, goTool, "build", "-o", outFile, goFile)
 	if out, err := cmd.CombinedOutput(); err != nil {
 		t.Logf("%s", out)
 		t.Fatal(err)
diff --git a/src/cmd/link/internal/amd64/obj.go b/src/cmd/link/internal/amd64/obj.go
index d09c90e..c5e2117 100644
--- a/src/cmd/link/internal/amd64/obj.go
+++ b/src/cmd/link/internal/amd64/obj.go
@@ -65,6 +65,7 @@
 		TLSIEtoLE:        tlsIEtoLE,
 
 		Linuxdynld:     "/lib64/ld-linux-x86-64.so.2",
+		LinuxdynldMusl: "/lib/ld-musl-x86_64.so.1",
 		Freebsddynld:   "/libexec/ld-elf.so.1",
 		Openbsddynld:   "/usr/libexec/ld.so",
 		Netbsddynld:    "/libexec/ld.elf_so",
diff --git a/src/cmd/link/internal/arm/asm.go b/src/cmd/link/internal/arm/asm.go
index 347932c..1e4b36d 100644
--- a/src/cmd/link/internal/arm/asm.go
+++ b/src/cmd/link/internal/arm/asm.go
@@ -91,7 +91,7 @@
 }
 
 // Preserve highest 8 bits of a, and do addition to lower 24-bit
-// of a and b; used to adjust ARM branch instruction's target
+// of a and b; used to adjust ARM branch instruction's target.
 func braddoff(a int32, b int32) int32 {
 	return int32((uint32(a))&0xff000000 | 0x00ffffff&uint32(a+b))
 }
@@ -363,7 +363,7 @@
 	return true
 }
 
-// sign extend a 24-bit integer
+// sign extend a 24-bit integer.
 func signext24(x int64) int32 {
 	return (int32(x) << 8) >> 8
 }
@@ -379,7 +379,7 @@
 	return 0
 }
 
-// Convert the direct jump relocation r to refer to a trampoline if the target is too far
+// Convert the direct jump relocation r to refer to a trampoline if the target is too far.
 func trampoline(ctxt *ld.Link, ldr *loader.Loader, ri int, rs, s loader.Sym) {
 	relocs := ldr.Relocs(s)
 	r := relocs.At(ri)
@@ -396,9 +396,26 @@
 		// laid out. Conservatively use a trampoline. This should be rare, as we lay out packages
 		// in dependency order.
 		if ldr.SymValue(rs) != 0 {
-			// r.Add is the instruction
-			// low 24-bit encodes the target address
-			t = (ldr.SymValue(rs) + int64(signext24(r.Add()&0xffffff)*4) - (ldr.SymValue(s) + int64(r.Off()))) / 4
+			// Workaround for issue #58425: it appears that the
+			// external linker doesn't always take into account the
+			// relocation addend when doing reachability checks. This
+			// means that if you have a call from function XYZ at
+			// offset 8 to runtime.duffzero with addend 800 (for
+			// example), where the distance between the start of XYZ
+			// and the start of runtime.duffzero is just over the
+			// limit (by 100 bytes, say), you can get "relocation
+			// doesn't fit" errors from the external linker. To deal
+			// with this, ignore the addend when performing the
+			// distance calculation (this assumes that we're only
+			// handling backward jumps; ideally we might want to check
+			// both with and without the addend).
+			if ctxt.IsExternal() {
+				t = (ldr.SymValue(rs) - (ldr.SymValue(s) + int64(r.Off()))) / 4
+			} else {
+				// r.Add is the instruction
+				// low 24-bit encodes the target address
+				t = (ldr.SymValue(rs) + int64(signext24(r.Add()&0xffffff)*4) - (ldr.SymValue(s) + int64(r.Off()))) / 4
+			}
 		}
 		if t > 0x7fffff || t < -0x800000 || ldr.SymValue(rs) == 0 || (*ld.FlagDebugTramp > 1 && ldr.SymPkg(s) != ldr.SymPkg(rs)) {
 			// direct call too far, need to insert trampoline.
@@ -459,7 +476,7 @@
 	}
 }
 
-// generate a trampoline to target+offset
+// generate a trampoline to target+offset.
 func gentramp(arch *sys.Arch, linkmode ld.LinkMode, ldr *loader.Loader, tramp *loader.SymbolBuilder, target loader.Sym, offset int64) {
 	tramp.SetSize(12) // 3 instructions
 	P := make([]byte, tramp.Size())
@@ -481,7 +498,7 @@
 	}
 }
 
-// generate a trampoline to target+offset in position independent code
+// generate a trampoline to target+offset in position independent code.
 func gentramppic(arch *sys.Arch, tramp *loader.SymbolBuilder, target loader.Sym, offset int64) {
 	tramp.SetSize(16) // 4 instructions
 	P := make([]byte, tramp.Size())
@@ -502,7 +519,7 @@
 	r.SetAdd(offset + 4)
 }
 
-// generate a trampoline to target+offset in dynlink mode (using GOT)
+// generate a trampoline to target+offset in dynlink mode (using GOT).
 func gentrampdyn(arch *sys.Arch, tramp *loader.SymbolBuilder, target loader.Sym, offset int64) {
 	tramp.SetSize(20)                               // 5 instructions
 	o1 := uint32(0xe5900000 | 12<<12 | 15<<16 | 8)  // MOVW 8(R15), R12 // R15 is actual pc + 8
diff --git a/src/cmd/link/internal/arm/obj.go b/src/cmd/link/internal/arm/obj.go
index b7d1498..6da0c77 100644
--- a/src/cmd/link/internal/arm/obj.go
+++ b/src/cmd/link/internal/arm/obj.go
@@ -63,6 +63,7 @@
 		PEreloc1:         pereloc1,
 
 		Linuxdynld:     "/lib/ld-linux.so.3", // 2 for OABI, 3 for EABI
+		LinuxdynldMusl: "/lib/ld-musl-arm.so.1",
 		Freebsddynld:   "/usr/libexec/ld-elf.so.1",
 		Openbsddynld:   "/usr/libexec/ld.so",
 		Netbsddynld:    "/libexec/ld.elf_so",
diff --git a/src/cmd/link/internal/arm64/asm.go b/src/cmd/link/internal/arm64/asm.go
index 9937683..fc0ad3f 100644
--- a/src/cmd/link/internal/arm64/asm.go
+++ b/src/cmd/link/internal/arm64/asm.go
@@ -467,6 +467,28 @@
 		out.Write64(uint64(r.Xadd))
 		out.Write64(uint64(sectoff + 4))
 		out.Write64(uint64(elf.R_AARCH64_ADD_ABS_LO12_NC) | uint64(elfsym)<<32)
+
+	case objabi.R_ARM64_PCREL_LDST8,
+		objabi.R_ARM64_PCREL_LDST16,
+		objabi.R_ARM64_PCREL_LDST32,
+		objabi.R_ARM64_PCREL_LDST64:
+		// two relocations: R_AARCH64_ADR_PREL_PG_HI21 and R_AARCH64_LDST{64/32/16/8}_ABS_LO12_NC
+		out.Write64(uint64(elf.R_AARCH64_ADR_PREL_PG_HI21) | uint64(elfsym)<<32)
+		out.Write64(uint64(r.Xadd))
+		out.Write64(uint64(sectoff + 4))
+		var ldstType elf.R_AARCH64
+		switch r.Type {
+		case objabi.R_ARM64_PCREL_LDST8:
+			ldstType = elf.R_AARCH64_LDST8_ABS_LO12_NC
+		case objabi.R_ARM64_PCREL_LDST16:
+			ldstType = elf.R_AARCH64_LDST16_ABS_LO12_NC
+		case objabi.R_ARM64_PCREL_LDST32:
+			ldstType = elf.R_AARCH64_LDST32_ABS_LO12_NC
+		case objabi.R_ARM64_PCREL_LDST64:
+			ldstType = elf.R_AARCH64_LDST64_ABS_LO12_NC
+		}
+		out.Write64(uint64(ldstType) | uint64(elfsym)<<32)
+
 	case objabi.R_ARM64_TLS_LE:
 		out.Write64(uint64(elf.R_AARCH64_TLSLE_MOVW_TPREL_G0) | uint64(elfsym)<<32)
 	case objabi.R_ARM64_TLS_IE:
@@ -516,7 +538,10 @@
 		}
 	}
 
-	if ldr.SymType(rs) == sym.SHOSTOBJ || rt == objabi.R_CALLARM64 || rt == objabi.R_ADDRARM64 || rt == objabi.R_ARM64_GOTPCREL {
+	if ldr.SymType(rs) == sym.SHOSTOBJ || rt == objabi.R_CALLARM64 ||
+		rt == objabi.R_ARM64_PCREL_LDST8 || rt == objabi.R_ARM64_PCREL_LDST16 ||
+		rt == objabi.R_ARM64_PCREL_LDST32 || rt == objabi.R_ARM64_PCREL_LDST64 ||
+		rt == objabi.R_ADDRARM64 || rt == objabi.R_ARM64_GOTPCREL {
 		if ldr.SymDynid(rs) < 0 {
 			ldr.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", rt, sym.RelocName(arch, rt), ldr.SymName(rs), ldr.SymType(rs), ldr.SymType(rs))
 			return false
@@ -539,12 +564,17 @@
 		v |= ld.MACHO_ARM64_RELOC_UNSIGNED << 28
 	case objabi.R_CALLARM64:
 		if xadd != 0 {
-			ldr.Errorf(s, "ld64 doesn't allow BR26 reloc with non-zero addend: %s+%d", ldr.SymName(rs), xadd)
+			out.Write32(uint32(sectoff))
+			out.Write32((ld.MACHO_ARM64_RELOC_ADDEND << 28) | (2 << 25) | uint32(xadd&0xffffff))
 		}
 
 		v |= 1 << 24 // pc-relative bit
 		v |= ld.MACHO_ARM64_RELOC_BRANCH26 << 28
-	case objabi.R_ADDRARM64:
+	case objabi.R_ADDRARM64,
+		objabi.R_ARM64_PCREL_LDST8,
+		objabi.R_ARM64_PCREL_LDST16,
+		objabi.R_ARM64_PCREL_LDST32,
+		objabi.R_ARM64_PCREL_LDST64:
 		siz = 4
 		// Two relocation entries: MACHO_ARM64_RELOC_PAGEOFF12 MACHO_ARM64_RELOC_PAGE21
 		// if r.Xadd is non-zero, add two MACHO_ARM64_RELOC_ADDEND.
@@ -600,7 +630,8 @@
 	rs := r.Xsym
 	rt := r.Type
 
-	if rt == objabi.R_ADDRARM64 && r.Xadd != signext21(r.Xadd) {
+	if (rt == objabi.R_ADDRARM64 || rt == objabi.R_ARM64_PCREL_LDST8 || rt == objabi.R_ARM64_PCREL_LDST16 ||
+		rt == objabi.R_ARM64_PCREL_LDST32 || rt == objabi.R_ARM64_PCREL_LDST64) && r.Xadd != signext21(r.Xadd) {
 		// If the relocation target would overflow the addend, then target
 		// a linker-manufactured label symbol with a smaller addend instead.
 		label := ldr.Lookup(offsetLabelName(ldr, rs, r.Xadd/peRelocLimit*peRelocLimit), ldr.SymVersion(rs))
@@ -652,6 +683,19 @@
 		out.Write32(uint32(symdynid))
 		out.Write16(ld.IMAGE_REL_ARM64_PAGEOFFSET_12A)
 
+	case objabi.R_ARM64_PCREL_LDST8,
+		objabi.R_ARM64_PCREL_LDST16,
+		objabi.R_ARM64_PCREL_LDST32,
+		objabi.R_ARM64_PCREL_LDST64:
+		// Note: r.Xadd has been taken care of below, in archreloc.
+		out.Write32(uint32(sectoff))
+		out.Write32(uint32(symdynid))
+		out.Write16(ld.IMAGE_REL_ARM64_PAGEBASE_REL21)
+
+		out.Write32(uint32(sectoff + 4))
+		out.Write32(uint32(symdynid))
+		out.Write16(ld.IMAGE_REL_ARM64_PAGEOFFSET_12L)
+
 	case objabi.R_CALLARM64:
 		// Note: r.Xadd has been taken care of above, by using a label pointing into the middle of the function.
 		out.Write32(uint32(sectoff))
@@ -673,6 +717,10 @@
 		switch rt := r.Type(); rt {
 		default:
 		case objabi.R_ARM64_GOTPCREL,
+			objabi.R_ARM64_PCREL_LDST8,
+			objabi.R_ARM64_PCREL_LDST16,
+			objabi.R_ARM64_PCREL_LDST32,
+			objabi.R_ARM64_PCREL_LDST64,
 			objabi.R_ADDRARM64:
 
 			// set up addend for eventual relocation via outer symbol.
@@ -699,17 +747,35 @@
 				}
 
 				// The first instruction (ADRP) has a 21-bit immediate field,
-				// and the second (ADD) has a 12-bit immediate field.
+				// and the second (ADD or LD/ST) has a 12-bit immediate field.
 				// The first instruction is only for high bits, but to get the carry bits right we have
 				// to put the full addend, including the bottom 12 bits again.
 				// That limits the distance of any addend to only 21 bits.
-				// But we assume that LDRP's top bit will be interpreted as a sign bit,
+				// But we assume that ADRP's top bit will be interpreted as a sign bit,
 				// so we only use 20 bits.
 				// pereloc takes care of introducing new symbol labels
 				// every megabyte for longer relocations.
 				xadd := uint32(xadd)
 				o0 |= (xadd&3)<<29 | (xadd&0xffffc)<<3
-				o1 |= (xadd & 0xfff) << 10
+				switch rt {
+				case objabi.R_ARM64_PCREL_LDST8, objabi.R_ADDRARM64:
+					o1 |= (xadd & 0xfff) << 10
+				case objabi.R_ARM64_PCREL_LDST16:
+					if xadd&0x1 != 0 {
+						ldr.Errorf(s, "offset for 16-bit load/store has unaligned value %d", xadd&0xfff)
+					}
+					o1 |= ((xadd & 0xfff) >> 1) << 10
+				case objabi.R_ARM64_PCREL_LDST32:
+					if xadd&0x3 != 0 {
+						ldr.Errorf(s, "offset for 32-bit load/store has unaligned value %d", xadd&0xfff)
+					}
+					o1 |= ((xadd & 0xfff) >> 2) << 10
+				case objabi.R_ARM64_PCREL_LDST64:
+					if xadd&0x7 != 0 {
+						ldr.Errorf(s, "offset for 64-bit load/store has unaligned value %d", xadd&0xfff)
+					}
+					o1 |= ((xadd & 0xfff) >> 3) << 10
+				}
 
 				if target.IsBigEndian() {
 					val = int64(o0)<<32 | int64(o1)
@@ -719,15 +785,22 @@
 			}
 
 			return val, nExtReloc, isOk
-		case objabi.R_CALLARM64,
-			objabi.R_ARM64_TLS_LE,
-			objabi.R_ARM64_TLS_IE:
+
+		case objabi.R_CALLARM64:
 			nExtReloc = 1
-			if rt == objabi.R_ARM64_TLS_IE {
-				nExtReloc = 2 // need two ELF relocations. see elfreloc1
+			if target.IsDarwin() && r.Add() != 0 {
+				nExtReloc = 2 // need another relocation for addend
 			}
 			return val, nExtReloc, isOk
 
+		case objabi.R_ARM64_TLS_LE:
+			nExtReloc = 1
+			return val, nExtReloc, isOk
+
+		case objabi.R_ARM64_TLS_IE:
+			nExtReloc = 2 // need two ELF relocations. see elfreloc1
+			return val, nExtReloc, isOk
+
 		case objabi.R_ADDR:
 			if target.IsWindows() && r.Add() != 0 {
 				if r.Siz() == 8 {
@@ -742,8 +815,12 @@
 		}
 	}
 
-	switch r.Type() {
-	case objabi.R_ADDRARM64:
+	switch rt := r.Type(); rt {
+	case objabi.R_ADDRARM64,
+		objabi.R_ARM64_PCREL_LDST8,
+		objabi.R_ARM64_PCREL_LDST16,
+		objabi.R_ARM64_PCREL_LDST32,
+		objabi.R_ARM64_PCREL_LDST64:
 		t := ldr.SymAddr(rs) + r.Add() - ((ldr.SymValue(s) + int64(r.Off())) &^ 0xfff)
 		if t >= 1<<32 || t < -1<<32 {
 			ldr.Errorf(s, "program too large, address relocation distance = %d", t)
@@ -760,7 +837,25 @@
 		}
 
 		o0 |= (uint32((t>>12)&3) << 29) | (uint32((t>>12>>2)&0x7ffff) << 5)
-		o1 |= uint32(t&0xfff) << 10
+		switch rt {
+		case objabi.R_ARM64_PCREL_LDST8, objabi.R_ADDRARM64:
+			o1 |= uint32(t&0xfff) << 10
+		case objabi.R_ARM64_PCREL_LDST16:
+			if t&0x1 != 0 {
+				ldr.Errorf(s, "offset for 16-bit load/store has unaligned value %d", t&0xfff)
+			}
+			o1 |= (uint32(t&0xfff) >> 1) << 10
+		case objabi.R_ARM64_PCREL_LDST32:
+			if t&0x3 != 0 {
+				ldr.Errorf(s, "offset for 32-bit load/store has unaligned value %d", t&0xfff)
+			}
+			o1 |= (uint32(t&0xfff) >> 2) << 10
+		case objabi.R_ARM64_PCREL_LDST64:
+			if t&0x7 != 0 {
+				ldr.Errorf(s, "offset for 64-bit load/store has unaligned value %d", t&0xfff)
+			}
+			o1 |= (uint32(t&0xfff) >> 3) << 10
+		}
 
 		// when laid out, the instruction order must always be o1, o2.
 		if target.IsBigEndian() {
@@ -944,22 +1039,12 @@
 func extreloc(target *ld.Target, ldr *loader.Loader, r loader.Reloc, s loader.Sym) (loader.ExtReloc, bool) {
 	switch rt := r.Type(); rt {
 	case objabi.R_ARM64_GOTPCREL,
+		objabi.R_ARM64_PCREL_LDST8,
+		objabi.R_ARM64_PCREL_LDST16,
+		objabi.R_ARM64_PCREL_LDST32,
+		objabi.R_ARM64_PCREL_LDST64,
 		objabi.R_ADDRARM64:
 		rr := ld.ExtrelocViaOuterSym(ldr, r, s)
-
-		// Note: ld64 currently has a bug that any non-zero addend for BR26 relocation
-		// will make the linking fail because it thinks the code is not PIC even though
-		// the BR26 relocation should be fully resolved at link time.
-		// That is the reason why the next if block is disabled. When the bug in ld64
-		// is fixed, we can enable this block and also enable duff's device in cmd/7g.
-		if false && target.IsDarwin() {
-			// Mach-O wants the addend to be encoded in the instruction
-			// Note that although Mach-O supports ARM64_RELOC_ADDEND, it
-			// can only encode 24-bit of signed addend, but the instructions
-			// supports 33-bit of signed addend, so we always encode the
-			// addend in place.
-			rr.Xadd = 0
-		}
 		return rr, true
 	case objabi.R_CALLARM64,
 		objabi.R_ARM64_TLS_LE,
@@ -1186,7 +1271,7 @@
 	return fmt.Sprintf("%s+%d", ldr.SymExtname(s), off)
 }
 
-// Convert the direct jump relocation r to refer to a trampoline if the target is too far
+// Convert the direct jump relocation r to refer to a trampoline if the target is too far.
 func trampoline(ctxt *ld.Link, ldr *loader.Loader, ri int, rs, s loader.Sym) {
 	relocs := ldr.Relocs(s)
 	r := relocs.At(ri)
diff --git a/src/cmd/link/internal/arm64/obj.go b/src/cmd/link/internal/arm64/obj.go
index 9c74598..a47be0b 100644
--- a/src/cmd/link/internal/arm64/obj.go
+++ b/src/cmd/link/internal/arm64/obj.go
@@ -62,8 +62,9 @@
 		PEreloc1:         pereloc1,
 		Trampoline:       trampoline,
 
-		Androiddynld: "/system/bin/linker64",
-		Linuxdynld:   "/lib/ld-linux-aarch64.so.1",
+		Androiddynld:   "/system/bin/linker64",
+		Linuxdynld:     "/lib/ld-linux-aarch64.so.1",
+		LinuxdynldMusl: "/lib/ld-musl-aarch64.so.1",
 
 		Freebsddynld:   "/usr/libexec/ld-elf.so.1",
 		Openbsddynld:   "/usr/libexec/ld.so",
diff --git a/src/cmd/link/internal/ld/ar.go b/src/cmd/link/internal/ld/ar.go
index 125a5d6..73c1cd3 100644
--- a/src/cmd/link/internal/ld/ar.go
+++ b/src/cmd/link/internal/ld/ar.go
@@ -32,6 +32,7 @@
 
 import (
 	"cmd/internal/bio"
+	"cmd/link/internal/loader"
 	"cmd/link/internal/sym"
 	"encoding/binary"
 	"fmt"
@@ -61,6 +62,39 @@
 	fmag string
 }
 
+// pruneUndefsForWindows trims the list "undefs" of currently
+// outstanding unresolved symbols to remove references to DLL import
+// symbols (e.g. "__imp_XXX"). In older versions of the linker, we
+// would just immediately forward references from the import sym
+// (__imp_XXX) to the DLL sym (XXX), but with newer compilers this
+// strategy falls down in certain cases. We instead now do this
+// forwarding later on as a post-processing step, and meaning that
+// during the middle part of host object loading we can see a lot of
+// unresolved (SXREF) import symbols. We do not, however, want to
+// trigger the inclusion of an object from a host archive if the
+// reference is going to be eventually forwarded to the corresponding
+// SDYNIMPORT symbol, so here we strip out such refs from the undefs
+// list.
+func pruneUndefsForWindows(ldr *loader.Loader, undefs, froms []loader.Sym) ([]loader.Sym, []loader.Sym) {
+	var newundefs []loader.Sym
+	var newfroms []loader.Sym
+	for _, s := range undefs {
+		sname := ldr.SymName(s)
+		if strings.HasPrefix(sname, "__imp_") {
+			dname := sname[len("__imp_"):]
+			ds := ldr.Lookup(dname, 0)
+			if ds != 0 && ldr.SymType(ds) == sym.SDYNIMPORT {
+				// Don't try to pull things out of a host archive to
+				// satisfy this symbol.
+				continue
+			}
+		}
+		newundefs = append(newundefs, s)
+		newfroms = append(newfroms, s)
+	}
+	return newundefs, newfroms
+}
+
 // hostArchive reads an archive file holding host objects and links in
 // required objects. The general format is the same as a Go archive
 // file, but it has an armap listing symbols and the objects that
@@ -110,12 +144,18 @@
 	for any {
 		var load []uint64
 		returnAllUndefs := -1
-		undefs := ctxt.loader.UndefinedRelocTargets(returnAllUndefs)
-		for _, symIdx := range undefs {
-			name := ctxt.loader.SymName(symIdx)
-			if off := armap[name]; off != 0 && !loaded[off] {
+		undefs, froms := ctxt.loader.UndefinedRelocTargets(returnAllUndefs)
+		if buildcfg.GOOS == "windows" {
+			undefs, froms = pruneUndefsForWindows(ctxt.loader, undefs, froms)
+		}
+		for k, symIdx := range undefs {
+			sname := ctxt.loader.SymName(symIdx)
+			if off := armap[sname]; off != 0 && !loaded[off] {
 				load = append(load, off)
 				loaded[off] = true
+				if ctxt.Debugvlog > 1 {
+					ctxt.Logf("hostArchive(%s): selecting object at offset %x to resolve %s [%d] reference from %s [%d]\n", name, off, sname, symIdx, ctxt.loader.SymName(froms[k]), froms[k])
+				}
 			}
 		}
 
@@ -139,6 +179,9 @@
 			}
 			f.MustSeek(h.off, 0)
 			h.ld(ctxt, f, h.pkg, h.length, h.pn)
+			if *flagCaptureHostObjs != "" {
+				captureHostObj(h)
+			}
 		}
 
 		any = len(load) > 0
diff --git a/src/cmd/link/internal/ld/config.go b/src/cmd/link/internal/ld/config.go
index 4dd43a1..336cb33 100644
--- a/src/cmd/link/internal/ld/config.go
+++ b/src/cmd/link/internal/ld/config.go
@@ -8,6 +8,7 @@
 	"cmd/internal/sys"
 	"fmt"
 	"internal/buildcfg"
+	"internal/platform"
 )
 
 // A BuildMode indicates the sort of object we are building.
@@ -185,7 +186,7 @@
 		}()
 	}
 
-	if sys.MustLinkExternal(buildcfg.GOOS, buildcfg.GOARCH) {
+	if platform.MustLinkExternal(buildcfg.GOOS, buildcfg.GOARCH) {
 		return true, fmt.Sprintf("%s/%s requires external linking", buildcfg.GOOS, buildcfg.GOARCH)
 	}
 
diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go
index cb2afea..925e554 100644
--- a/src/cmd/link/internal/ld/data.go
+++ b/src/cmd/link/internal/ld/data.go
@@ -37,6 +37,7 @@
 	"cmd/internal/objabi"
 	"cmd/internal/sys"
 	"cmd/link/internal/loader"
+	"cmd/link/internal/loadpe"
 	"cmd/link/internal/sym"
 	"compress/zlib"
 	"debug/elf"
@@ -51,7 +52,7 @@
 	"sync/atomic"
 )
 
-// isRuntimeDepPkg reports whether pkg is the runtime package or its dependency
+// isRuntimeDepPkg reports whether pkg is the runtime package or its dependency.
 func isRuntimeDepPkg(pkg string) bool {
 	switch pkg {
 	case "runtime",
@@ -222,7 +223,7 @@
 				if ldr.SymName(rs) == "main.main" || (!target.IsPlugin() && ldr.SymName(rs) == "main..inittask") {
 					sb := ldr.MakeSymbolUpdater(rs)
 					sb.SetType(sym.SDYNIMPORT)
-				} else if strings.HasPrefix(ldr.SymName(rs), "go.info.") {
+				} else if strings.HasPrefix(ldr.SymName(rs), "go:info.") {
 					// Skip go.info symbols. They are only needed to communicate
 					// DWARF info between the compiler and linker.
 					continue
@@ -747,7 +748,38 @@
 	}
 }
 
-func windynrelocsym(ctxt *Link, rel *loader.SymbolBuilder, s loader.Sym) {
+// windynrelocsym examines a text symbol 's' and looks for relocations
+// from it that correspond to references to symbols defined in DLLs,
+// then fixes up those relocations as needed. A reference to a symbol
+// XYZ from some DLL will fall into one of two categories: an indirect
+// ref via "__imp_XYZ", or a direct ref to "XYZ". Here's an example of
+// an indirect ref (this is an excerpt from objdump -ldr):
+//
+//	     1c1: 48 89 c6                     	movq	%rax, %rsi
+//	     1c4: ff 15 00 00 00 00            	callq	*(%rip)
+//			00000000000001c6:  IMAGE_REL_AMD64_REL32	__imp__errno
+//
+// In the assembly above, the code loads up the value of __imp_errno
+// and then does an indirect call to that value.
+//
+// Here is what a direct reference might look like:
+//
+//	     137: e9 20 06 00 00               	jmp	0x75c <pow+0x75c>
+//	     13c: e8 00 00 00 00               	callq	0x141 <pow+0x141>
+//			000000000000013d:  IMAGE_REL_AMD64_REL32	_errno
+//
+// The assembly below dispenses with the import symbol and just makes
+// a direct call to _errno.
+//
+// The code below handles indirect refs by redirecting the target of
+// the relocation from "__imp_XYZ" to "XYZ" (since the latter symbol
+// is what the Windows loader is expected to resolve). For direct refs
+// the call is redirected to a stub, where the stub first loads the
+// symbol and then direct an indirect call to that value.
+//
+// Note that for a given symbol (as above) it is perfectly legal to
+// have both direct and indirect references.
+func windynrelocsym(ctxt *Link, rel *loader.SymbolBuilder, s loader.Sym) error {
 	var su *loader.SymbolBuilder
 	relocs := ctxt.loader.Relocs(s)
 	for ri := 0; ri < relocs.Count(); ri++ {
@@ -763,13 +795,43 @@
 			if r.Weak() {
 				continue
 			}
-			ctxt.Errorf(s, "dynamic relocation to unreachable symbol %s",
+			return fmt.Errorf("dynamic relocation to unreachable symbol %s",
 				ctxt.loader.SymName(targ))
 		}
+		tgot := ctxt.loader.SymGot(targ)
+		if tgot == loadpe.RedirectToDynImportGotToken {
+
+			// Consistency check: name should be __imp_X
+			sname := ctxt.loader.SymName(targ)
+			if !strings.HasPrefix(sname, "__imp_") {
+				return fmt.Errorf("internal error in windynrelocsym: redirect GOT token applied to non-import symbol %s", sname)
+			}
+
+			// Locate underlying symbol (which originally had type
+			// SDYNIMPORT but has since been retyped to SWINDOWS).
+			ds, err := loadpe.LookupBaseFromImport(targ, ctxt.loader, ctxt.Arch)
+			if err != nil {
+				return err
+			}
+			dstyp := ctxt.loader.SymType(ds)
+			if dstyp != sym.SWINDOWS {
+				return fmt.Errorf("internal error in windynrelocsym: underlying sym for %q has wrong type %s", sname, dstyp.String())
+			}
+
+			// Redirect relocation to the dynimport.
+			r.SetSym(ds)
+			continue
+		}
 
 		tplt := ctxt.loader.SymPlt(targ)
-		tgot := ctxt.loader.SymGot(targ)
-		if tplt == -2 && tgot != -2 { // make dynimport JMP table for PE object files.
+		if tplt == loadpe.CreateImportStubPltToken {
+
+			// Consistency check: don't want to see both PLT and GOT tokens.
+			if tgot != -1 {
+				return fmt.Errorf("internal error in windynrelocsym: invalid GOT setting %d for reloc to %s", tgot, ctxt.loader.SymName(targ))
+			}
+
+			// make dynimport JMP table for PE object files.
 			tplt := int32(rel.Size())
 			ctxt.loader.SetPlt(targ, tplt)
 
@@ -782,8 +844,7 @@
 			// jmp *addr
 			switch ctxt.Arch.Family {
 			default:
-				ctxt.Errorf(s, "unsupported arch %v", ctxt.Arch.Family)
-				return
+				return fmt.Errorf("internal error in windynrelocsym: unsupported arch %v", ctxt.Arch.Family)
 			case sys.I386:
 				rel.AddUint8(0xff)
 				rel.AddUint8(0x25)
@@ -805,6 +866,7 @@
 			r.SetAdd(int64(tplt))
 		}
 	}
+	return nil
 }
 
 // windynrelocsyms generates jump table to C library functions that will be
@@ -818,7 +880,9 @@
 	rel.SetType(sym.STEXT)
 
 	for _, s := range ctxt.Textp {
-		windynrelocsym(ctxt, rel, s)
+		if err := windynrelocsym(ctxt, rel, s); err != nil {
+			ctxt.Errorf(s, "%v", err)
+		}
 	}
 
 	ctxt.Textp = append(ctxt.Textp, rel.Sym())
@@ -1074,6 +1138,8 @@
 	writeBlocks(ctxt, out, ctxt.outSem, ctxt.loader, syms, addr, size, zeros[:])
 }
 
+var covCounterDataStartOff, covCounterDataLen uint64
+
 var zeros [512]byte
 
 var (
@@ -1108,7 +1174,7 @@
 	}
 	if goType := l.SymGoType(s); goType == 0 {
 		return
-	} else if typeName := l.SymName(goType); typeName != "type.string" {
+	} else if typeName := l.SymName(goType); typeName != "type:string" {
 		Errorf(nil, "%s: cannot set with -X: not a var of type string (%s)", name, typeName)
 		return
 	}
@@ -1125,12 +1191,14 @@
 	sbld.Addstring(value)
 	sbld.SetType(sym.SRODATA)
 
-	bld.SetSize(0)
-	bld.SetData(make([]byte, 0, arch.PtrSize*2))
+	// Don't reset the variable's size. String variable usually has size of
+	// 2*PtrSize, but in ASAN build it can be larger due to red zone.
+	// (See issue 56175.)
+	bld.SetData(make([]byte, arch.PtrSize*2))
 	bld.SetReadOnly(false)
 	bld.ResetRelocs()
-	bld.AddAddrPlus(arch, sbld.Sym(), 0)
-	bld.AddUint(arch, uint64(len(value)))
+	bld.SetAddrPlus(arch, 0, sbld.Sym(), 0)
+	bld.SetUint(arch, int64(arch.PtrSize), uint64(len(value)))
 }
 
 func (ctxt *Link) dostrdata() {
@@ -1601,6 +1669,9 @@
 func (state *dodataState) allocateDataSectionForSym(seg *sym.Segment, s loader.Sym, rwx int) *sym.Section {
 	ldr := state.ctxt.loader
 	sname := ldr.SymName(s)
+	if strings.HasPrefix(sname, "go:") {
+		sname = ".go." + sname[len("go:"):]
+	}
 	sect := addsection(ldr, state.ctxt.Arch, seg, sname, rwx)
 	sect.Align = symalign(ldr, s)
 	state.datsize = Rnd(state.datsize, int64(sect.Align))
@@ -1781,11 +1852,20 @@
 	ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.enoptrbss", 0), sect)
 	ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.end", 0), sect)
 
+	// Code coverage counters are assigned to the .noptrbss section.
+	// We assign them in a separate pass so that they stay aggregated
+	// together in a single blob (coverage runtime depends on this).
+	covCounterDataStartOff = sect.Length
+	state.assignToSection(sect, sym.SCOVERAGE_COUNTER, sym.SNOPTRBSS)
+	covCounterDataLen = sect.Length - covCounterDataStartOff
+	ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.covctrs", 0), sect)
+	ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.ecovctrs", 0), sect)
+
 	// Coverage instrumentation counters for libfuzzer.
 	if len(state.data[sym.SLIBFUZZER_8BIT_COUNTER]) > 0 {
-		sect := state.allocateNamedSectionAndAssignSyms(&Segdata, "__sancov_cntrs", sym.SLIBFUZZER_8BIT_COUNTER, sym.Sxxx, 06)
-		ldr.SetSymSect(ldr.LookupOrCreateSym("__start___sancov_cntrs", 0), sect)
-		ldr.SetSymSect(ldr.LookupOrCreateSym("__stop___sancov_cntrs", 0), sect)
+		sect := state.allocateNamedSectionAndAssignSyms(&Segdata, ".go.fuzzcntrs", sym.SLIBFUZZER_8BIT_COUNTER, sym.Sxxx, 06)
+		ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.__start___sancov_cntrs", 0), sect)
+		ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.__stop___sancov_cntrs", 0), sect)
 		ldr.SetSymSect(ldr.LookupOrCreateSym("internal/fuzz._counters", 0), sect)
 		ldr.SetSymSect(ldr.LookupOrCreateSym("internal/fuzz._ecounters", 0), sect)
 	}
@@ -2152,7 +2232,7 @@
 	}
 
 	ldr := ctxt.loader
-	s := ldr.CreateSymForUpdate("go.buildid", 0)
+	s := ldr.CreateSymForUpdate("go:buildid", 0)
 	// The \xff is invalid UTF-8, meant to make it less likely
 	// to find one of these accidentally.
 	data := "\xff Go build ID: " + strconv.Quote(*flagBuildid) + "\n \xff"
@@ -2177,7 +2257,7 @@
 	// Write the buildinfo symbol, which go version looks for.
 	// The code reading this data is in package debug/buildinfo.
 	ldr := ctxt.loader
-	s := ldr.CreateSymForUpdate(".go.buildinfo", 0)
+	s := ldr.CreateSymForUpdate("go:buildinfo", 0)
 	s.SetType(sym.SBUILDINFO)
 	s.SetAlign(16)
 	// The \xff is invalid UTF-8, meant to make it less likely
@@ -2199,6 +2279,14 @@
 	}
 	s.SetData(data)
 	s.SetSize(int64(len(data)))
+
+	// Add reference to go:buildinfo from the rodata section,
+	// so that external linking with -Wl,--gc-sections does not
+	// delete the build info.
+	sr := ldr.CreateSymForUpdate("go:buildinfo.ref", 0)
+	sr.SetType(sym.SRODATA)
+	sr.SetAlign(int32(ctxt.Arch.PtrSize))
+	sr.AddAddr(ctxt.Arch, s.Sym())
 }
 
 // appendString appends s to data, prefixed by its varint-encoded length.
@@ -2336,7 +2424,7 @@
 	}
 }
 
-// assigns address for a text symbol, returns (possibly new) section, its number, and the address
+// assigns address for a text symbol, returns (possibly new) section, its number, and the address.
 func assignAddress(ctxt *Link, sect *sym.Section, n int, s loader.Sym, va uint64, isTramp, big bool) (*sym.Section, int, uint64) {
 	ldr := ctxt.loader
 	if thearch.AssignAddress != nil {
@@ -2566,7 +2654,7 @@
 			bss = s
 		case ".noptrbss":
 			noptrbss = s
-		case "__sancov_cntrs":
+		case ".go.fuzzcntrs":
 			fuzzCounters = s
 		}
 	}
@@ -2627,7 +2715,7 @@
 	}
 
 	if ctxt.BuildMode == BuildModeShared {
-		s := ldr.LookupOrCreateSym("go.link.abihashbytes", 0)
+		s := ldr.LookupOrCreateSym("go:link.abihashbytes", 0)
 		sect := ldr.SymSect(ldr.LookupOrCreateSym(".note.go.abihash", 0))
 		ldr.SetSymSect(s, sect)
 		ldr.SetSymValue(s, int64(sect.Vaddr+16))
@@ -2682,11 +2770,13 @@
 	ctxt.xdefine("runtime.edata", sym.SDATA, int64(data.Vaddr+data.Length))
 	ctxt.xdefine("runtime.noptrbss", sym.SNOPTRBSS, int64(noptrbss.Vaddr))
 	ctxt.xdefine("runtime.enoptrbss", sym.SNOPTRBSS, int64(noptrbss.Vaddr+noptrbss.Length))
+	ctxt.xdefine("runtime.covctrs", sym.SCOVERAGE_COUNTER, int64(noptrbss.Vaddr+covCounterDataStartOff))
+	ctxt.xdefine("runtime.ecovctrs", sym.SCOVERAGE_COUNTER, int64(noptrbss.Vaddr+covCounterDataStartOff+covCounterDataLen))
 	ctxt.xdefine("runtime.end", sym.SBSS, int64(Segdata.Vaddr+Segdata.Length))
 
 	if fuzzCounters != nil {
-		ctxt.xdefine("__start___sancov_cntrs", sym.SLIBFUZZER_8BIT_COUNTER, int64(fuzzCounters.Vaddr))
-		ctxt.xdefine("__stop___sancov_cntrs", sym.SLIBFUZZER_8BIT_COUNTER, int64(fuzzCounters.Vaddr+fuzzCounters.Length))
+		ctxt.xdefine("runtime.__start___sancov_cntrs", sym.SLIBFUZZER_8BIT_COUNTER, int64(fuzzCounters.Vaddr))
+		ctxt.xdefine("runtime.__stop___sancov_cntrs", sym.SLIBFUZZER_8BIT_COUNTER, int64(fuzzCounters.Vaddr+fuzzCounters.Length))
 		ctxt.xdefine("internal/fuzz._counters", sym.SLIBFUZZER_8BIT_COUNTER, int64(fuzzCounters.Vaddr))
 		ctxt.xdefine("internal/fuzz._ecounters", sym.SLIBFUZZER_8BIT_COUNTER, int64(fuzzCounters.Vaddr+fuzzCounters.Length))
 	}
@@ -2717,7 +2807,7 @@
 		if gotAddr := ldr.SymValue(ctxt.GOT); gotAddr != 0 {
 			tocAddr = gotAddr + 0x8000
 		}
-		for i, _ := range ctxt.DotTOC {
+		for i := range ctxt.DotTOC {
 			if i >= sym.SymVerABICount && i < sym.SymVerStatic { // these versions are not used currently
 				continue
 			}
diff --git a/src/cmd/link/internal/ld/deadcode.go b/src/cmd/link/internal/ld/deadcode.go
index 48f447b..0738a51 100644
--- a/src/cmd/link/internal/ld/deadcode.go
+++ b/src/cmd/link/internal/ld/deadcode.go
@@ -72,11 +72,11 @@
 	// We redirect unreachable methods to it.
 	names = append(names, "runtime.unreachableMethod")
 	if d.ctxt.BuildMode == BuildModePlugin {
-		names = append(names, objabi.PathToPrefix(*flagPluginPath)+"..inittask", objabi.PathToPrefix(*flagPluginPath)+".main", "go.plugin.tabs")
+		names = append(names, objabi.PathToPrefix(*flagPluginPath)+"..inittask", objabi.PathToPrefix(*flagPluginPath)+".main", "go:plugin.tabs")
 
 		// We don't keep the go.plugin.exports symbol,
 		// but we do keep the symbols it refers to.
-		exportsIdx := d.ldr.Lookup("go.plugin.exports", 0)
+		exportsIdx := d.ldr.Lookup("go:plugin.exports", 0)
 		if exportsIdx != 0 {
 			relocs := d.ldr.Relocs(exportsIdx)
 			for i := 0; i < relocs.Count(); i++ {
diff --git a/src/cmd/link/internal/ld/deadcode_test.go b/src/cmd/link/internal/ld/deadcode_test.go
index 6e12843..573bff3 100644
--- a/src/cmd/link/internal/ld/deadcode_test.go
+++ b/src/cmd/link/internal/ld/deadcode_test.go
@@ -7,7 +7,6 @@
 import (
 	"bytes"
 	"internal/testenv"
-	"os/exec"
 	"path/filepath"
 	"testing"
 )
@@ -23,7 +22,7 @@
 		pos, neg string // positive and negative patterns
 	}{
 		{"reflectcall", "", "main.T.M"},
-		{"typedesc", "", "type.main.T"},
+		{"typedesc", "", "type:main.T"},
 		{"ifacemethod", "", "main.T.M"},
 		{"ifacemethod2", "main.T.M", ""},
 		{"ifacemethod3", "main.S.M", ""},
@@ -35,7 +34,7 @@
 			t.Parallel()
 			src := filepath.Join("testdata", "deadcode", test.src+".go")
 			exe := filepath.Join(tmpdir, test.src+".exe")
-			cmd := exec.Command(testenv.GoToolPath(t), "build", "-ldflags=-dumpdep", "-o", exe, src)
+			cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-ldflags=-dumpdep", "-o", exe, src)
 			out, err := cmd.CombinedOutput()
 			if err != nil {
 				t.Fatalf("%v: %v:\n%s", cmd.Args, err, out)
diff --git a/src/cmd/link/internal/ld/dwarf.go b/src/cmd/link/internal/ld/dwarf.go
index c42511e..feea864 100644
--- a/src/cmd/link/internal/ld/dwarf.go
+++ b/src/cmd/link/internal/ld/dwarf.go
@@ -43,18 +43,18 @@
 	arch     *sys.Arch
 
 	// This maps type name string (e.g. "uintptr") to loader symbol for
-	// the DWARF DIE for that type (e.g. "go.info.type.uintptr")
+	// the DWARF DIE for that type (e.g. "go:info.type.uintptr")
 	tmap map[string]loader.Sym
 
 	// This maps loader symbol for the DWARF DIE symbol generated for
-	// a type (e.g. "go.info.uintptr") to the type symbol itself
-	// ("type.uintptr").
+	// a type (e.g. "go:info.uintptr") to the type symbol itself
+	// ("type:uintptr").
 	// FIXME: try converting this map (and the next one) to a single
 	// array indexed by loader.Sym -- this may perform better.
 	rtmap map[loader.Sym]loader.Sym
 
-	// This maps Go type symbol (e.g. "type.XXX") to loader symbol for
-	// the typedef DIE for that type (e.g. "go.info.XXX..def")
+	// This maps Go type symbol (e.g. "type:XXX") to loader symbol for
+	// the typedef DIE for that type (e.g. "go:info.XXX..def")
 	tdmap map[loader.Sym]loader.Sym
 
 	// Cache these type symbols, so as to avoid repeatedly looking them up
@@ -337,8 +337,8 @@
 func (d *dwctxt) walksymtypedef(symIdx loader.Sym) loader.Sym {
 
 	// We're being given the loader symbol for the type DIE, e.g.
-	// "go.info.type.uintptr". Map that first to the type symbol (e.g.
-	// "type.uintptr") and then to the typedef DIE for the type.
+	// "go:info.type.uintptr". Map that first to the type symbol (e.g.
+	// "type:uintptr") and then to the typedef DIE for the type.
 	// FIXME: this seems clunky, maybe there is a better way to do this.
 
 	if ts, ok := d.rtmap[symIdx]; ok {
@@ -519,8 +519,8 @@
 	}
 
 	sn := d.ldr.SymName(gotype)
-	if !strings.HasPrefix(sn, "type.") {
-		d.linkctxt.Errorf(gotype, "dwarf: type name doesn't start with \"type.\"")
+	if !strings.HasPrefix(sn, "type:") {
+		d.linkctxt.Errorf(gotype, "dwarf: type name doesn't start with \"type:\"")
 		return d.mustFind("<unspecified>")
 	}
 	name := sn[5:] // could also decode from Type.string
@@ -539,6 +539,9 @@
 	sn := d.ldr.SymName(gotype)
 	name := sn[5:] // could also decode from Type.string
 	tdata := d.ldr.Data(gotype)
+	if len(tdata) == 0 {
+		d.linkctxt.Errorf(gotype, "missing type")
+	}
 	kind := decodetypeKind(d.arch, tdata)
 	bytesize := decodetypeSize(d.arch, tdata)
 
@@ -678,7 +681,7 @@
 			s := decodetypeStructFieldType(d.ldr, d.arch, gotype, i)
 			if f == "" {
 				sn := d.ldr.SymName(s)
-				f = sn[5:] // skip "type."
+				f = sn[5:] // skip "type:"
 			}
 			fld := d.newdie(die, dwarf.DW_ABRV_STRUCTFIELD, f)
 			d.newrefattr(fld, dwarf.DW_AT_type, d.defgotype(s))
@@ -747,7 +750,7 @@
 	// The DWARF info synthesizes pointer types that don't exist at the
 	// language level, like *hash<...> and *bucket<...>, and the data
 	// pointers of slices. Link to the ones we can find.
-	gts := d.ldr.Lookup("type."+ptrname, 0)
+	gts := d.ldr.Lookup("type:"+ptrname, 0)
 	if gts != 0 && d.ldr.AttrReachable(gts) {
 		newattr(pdie, dwarf.DW_AT_go_runtime_type, dwarf.DW_CLS_GO_TYPEREF, 0, dwSym(gts))
 	}
@@ -814,7 +817,7 @@
 }
 
 func (d *dwctxt) synthesizestringtypes(ctxt *Link, die *dwarf.DWDie) {
-	prototype := walktypedef(d.findprotodie(ctxt, "type.runtime.stringStructDWARF"))
+	prototype := walktypedef(d.findprotodie(ctxt, "type:runtime.stringStructDWARF"))
 	if prototype == nil {
 		return
 	}
@@ -828,7 +831,7 @@
 }
 
 func (d *dwctxt) synthesizeslicetypes(ctxt *Link, die *dwarf.DWDie) {
-	prototype := walktypedef(d.findprotodie(ctxt, "type.runtime.slice"))
+	prototype := walktypedef(d.findprotodie(ctxt, "type:runtime.slice"))
 	if prototype == nil {
 		return
 	}
@@ -870,8 +873,8 @@
 }
 
 func (d *dwctxt) synthesizemaptypes(ctxt *Link, die *dwarf.DWDie) {
-	hash := walktypedef(d.findprotodie(ctxt, "type.runtime.hmap"))
-	bucket := walktypedef(d.findprotodie(ctxt, "type.runtime.bmap"))
+	hash := walktypedef(d.findprotodie(ctxt, "type:runtime.hmap"))
+	bucket := walktypedef(d.findprotodie(ctxt, "type:runtime.bmap"))
 
 	if hash == nil {
 		return
@@ -966,9 +969,9 @@
 }
 
 func (d *dwctxt) synthesizechantypes(ctxt *Link, die *dwarf.DWDie) {
-	sudog := walktypedef(d.findprotodie(ctxt, "type.runtime.sudog"))
-	waitq := walktypedef(d.findprotodie(ctxt, "type.runtime.waitq"))
-	hchan := walktypedef(d.findprotodie(ctxt, "type.runtime.hchan"))
+	sudog := walktypedef(d.findprotodie(ctxt, "type:runtime.sudog"))
+	waitq := walktypedef(d.findprotodie(ctxt, "type:runtime.waitq"))
+	hchan := walktypedef(d.findprotodie(ctxt, "type:runtime.hchan"))
 	if sudog == nil || waitq == nil || hchan == nil {
 		return
 	}
@@ -1135,7 +1138,7 @@
 		// symbol name here?
 		sn := d.ldr.SymName(rsym)
 		tn := sn[len(dwarf.InfoPrefix):]
-		ts := d.ldr.Lookup("type."+tn, 0)
+		ts := d.ldr.Lookup("type:"+tn, 0)
 		d.defgotype(ts)
 	}
 }
@@ -1662,7 +1665,7 @@
 	die := d.newdie(&dwtypes, abrv, tname)
 
 	// Look up type symbol.
-	gotype := d.lookupOrDiag("type." + tname)
+	gotype := d.lookupOrDiag("type:" + tname)
 
 	// Map from die sym to type sym
 	ds := loader.Sym(die.Sym.(dwSym))
@@ -1735,7 +1738,7 @@
 
 		rsn := d.ldr.SymName(rsym)
 		tn := rsn[len(dwarf.InfoPrefix):]
-		ts := d.ldr.Lookup("type."+tn, 0)
+		ts := d.ldr.Lookup("type:"+tn, 0)
 		d.defgotype(ts)
 	}
 }
@@ -1760,8 +1763,8 @@
 		tdmap:    make(map[loader.Sym]loader.Sym),
 		rtmap:    make(map[loader.Sym]loader.Sym),
 	}
-	d.typeRuntimeEface = d.lookupOrDiag("type.runtime.eface")
-	d.typeRuntimeIface = d.lookupOrDiag("type.runtime.iface")
+	d.typeRuntimeEface = d.lookupOrDiag("type:runtime.eface")
+	d.typeRuntimeIface = d.lookupOrDiag("type:runtime.iface")
 
 	if ctxt.HeadType == objabi.Haix {
 		// Initial map used to store package size for each DWARF section.
@@ -1781,34 +1784,34 @@
 	newattr(die, dwarf.DW_AT_encoding, dwarf.DW_CLS_CONSTANT, dwarf.DW_ATE_unsigned, 0)
 	newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, int64(d.arch.PtrSize), 0)
 	newattr(die, dwarf.DW_AT_go_kind, dwarf.DW_CLS_CONSTANT, objabi.KindUintptr, 0)
-	newattr(die, dwarf.DW_AT_go_runtime_type, dwarf.DW_CLS_ADDRESS, 0, dwSym(d.lookupOrDiag("type.uintptr")))
+	newattr(die, dwarf.DW_AT_go_runtime_type, dwarf.DW_CLS_ADDRESS, 0, dwSym(d.lookupOrDiag("type:uintptr")))
 
 	d.uintptrInfoSym = d.mustFind("uintptr")
 
 	// Prototypes needed for type synthesis.
 	prototypedies = map[string]*dwarf.DWDie{
-		"type.runtime.stringStructDWARF": nil,
-		"type.runtime.slice":             nil,
-		"type.runtime.hmap":              nil,
-		"type.runtime.bmap":              nil,
-		"type.runtime.sudog":             nil,
-		"type.runtime.waitq":             nil,
-		"type.runtime.hchan":             nil,
+		"type:runtime.stringStructDWARF": nil,
+		"type:runtime.slice":             nil,
+		"type:runtime.hmap":              nil,
+		"type:runtime.bmap":              nil,
+		"type:runtime.sudog":             nil,
+		"type:runtime.waitq":             nil,
+		"type:runtime.hchan":             nil,
 	}
 
 	// Needed by the prettyprinter code for interface inspection.
 	for _, typ := range []string{
-		"type.runtime._type",
-		"type.runtime.arraytype",
-		"type.runtime.chantype",
-		"type.runtime.functype",
-		"type.runtime.maptype",
-		"type.runtime.ptrtype",
-		"type.runtime.slicetype",
-		"type.runtime.structtype",
-		"type.runtime.interfacetype",
-		"type.runtime.itab",
-		"type.runtime.imethod"} {
+		"type:runtime._type",
+		"type:runtime.arraytype",
+		"type:runtime.chantype",
+		"type:runtime.functype",
+		"type:runtime.maptype",
+		"type:runtime.ptrtype",
+		"type:runtime.slicetype",
+		"type:runtime.structtype",
+		"type:runtime.interfacetype",
+		"type:runtime.itab",
+		"type:runtime.imethod"} {
 		d.defgotype(d.lookupOrDiag(typ))
 	}
 
diff --git a/src/cmd/link/internal/ld/dwarf_test.go b/src/cmd/link/internal/ld/dwarf_test.go
index db5be74..a3db4a9 100644
--- a/src/cmd/link/internal/ld/dwarf_test.go
+++ b/src/cmd/link/internal/ld/dwarf_test.go
@@ -5,18 +5,12 @@
 package ld
 
 import (
-	intdwarf "cmd/internal/dwarf"
-	objfilepkg "cmd/internal/objfile" // renamed to avoid conflict with objfile function
-	"cmd/link/internal/dwtest"
 	"debug/dwarf"
 	"debug/pe"
 	"fmt"
-	"internal/buildcfg"
 	"internal/testenv"
 	"io"
-	"io/ioutil"
 	"os"
-	"os/exec"
 	"path/filepath"
 	"reflect"
 	"runtime"
@@ -24,6 +18,10 @@
 	"strconv"
 	"strings"
 	"testing"
+
+	intdwarf "cmd/internal/dwarf"
+	objfilepkg "cmd/internal/objfile" // renamed to avoid conflict with objfile function
+	"cmd/link/internal/dwtest"
 )
 
 const (
@@ -97,11 +95,11 @@
 	src := filepath.Join(dir, "test.go")
 	dst := filepath.Join(dir, "out.exe")
 
-	if err := ioutil.WriteFile(src, []byte(testfile), 0666); err != nil {
+	if err := os.WriteFile(src, []byte(testfile), 0666); err != nil {
 		t.Fatal(err)
 	}
 
-	cmd := exec.Command(testenv.GoToolPath(t), "build", gcflags, "-o", dst, src)
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "build", gcflags, "-o", dst, src)
 	b, err := cmd.CombinedOutput()
 	if len(b) != 0 {
 		t.Logf("## build output:\n%s", b)
@@ -123,7 +121,7 @@
 	dst := filepath.Join(tdir, "out.exe")
 
 	// Run a build with an updated GOPATH
-	cmd := exec.Command(testenv.GoToolPath(t), "build", gcflags, "-o", dst)
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "build", gcflags, "-o", dst)
 	cmd.Dir = pkgDir
 	if b, err := cmd.CombinedOutput(); err != nil {
 		t.Logf("build: %s\n", b)
@@ -769,7 +767,7 @@
 	f := gobuild(t, dir, prog, flags)
 	defer f.Close()
 
-	out, err := exec.Command(f.path).CombinedOutput()
+	out, err := testenv.Command(t, f.path).CombinedOutput()
 	if err != nil {
 		t.Fatalf("could not run test program: %v", err)
 	}
@@ -1395,7 +1393,7 @@
 
 	t.Parallel()
 
-	tmpdir, err := ioutil.TempDir("", "TestIssue42484")
+	tmpdir, err := os.MkdirTemp("", "TestIssue42484")
 	if err != nil {
 		t.Fatalf("could not create directory: %v", err)
 	}
@@ -1597,9 +1595,6 @@
 	if runtime.GOOS == "plan9" {
 		t.Skip("skipping on plan9; no DWARF symbol table in executables")
 	}
-	if buildcfg.Experiment.Unified {
-		t.Skip("GOEXPERIMENT=unified does not emit dictionaries yet")
-	}
 	t.Parallel()
 
 	const prog = `
@@ -1842,3 +1837,135 @@
 		}
 	}
 }
+func TestIssue54320(t *testing.T) {
+	// Check that when trampolines are used, the DWARF LPT is correctly
+	// emitted in the final binary
+	testenv.MustHaveGoBuild(t)
+
+	if runtime.GOOS == "plan9" {
+		t.Skip("skipping on plan9; no DWARF symbol table in executables")
+	}
+
+	t.Parallel()
+
+	const prog = `
+package main
+
+import "fmt"
+
+func main() {
+	fmt.Printf("Hello world\n");
+}
+`
+
+	dir := t.TempDir()
+	f := gobuild(t, dir, prog, "-ldflags=-debugtramp=2")
+	defer f.Close()
+
+	d, err := f.DWARF()
+	if err != nil {
+		t.Fatalf("error reading DWARF: %v", err)
+	}
+
+	rdr := d.Reader()
+	found := false
+	var entry *dwarf.Entry
+	for entry, err = rdr.Next(); entry != nil; entry, err = rdr.Next() {
+		if err != nil {
+			t.Fatalf("error reading DWARF: %v", err)
+		}
+		if entry.Tag != dwarf.TagCompileUnit {
+			continue
+		}
+		name, _ := entry.Val(dwarf.AttrName).(string)
+		if name == "main" {
+			found = true
+			break
+		}
+		rdr.SkipChildren()
+	}
+
+	if !found {
+		t.Fatalf("could not find main compile unit")
+	}
+	lr, err := d.LineReader(entry)
+	if err != nil {
+		t.Fatalf("error obtaining linereader: %v", err)
+	}
+
+	var le dwarf.LineEntry
+	found = false
+	for {
+		if err := lr.Next(&le); err != nil {
+			if err == io.EOF {
+				break
+			}
+			t.Fatalf("error reading linentry: %v", err)
+		}
+		// check LE contains an entry to test.go
+		if le.File == nil {
+			continue
+		}
+		file := filepath.Base(le.File.Name)
+		if file == "test.go" {
+			found = true
+			break
+		}
+	}
+	if !found {
+		t.Errorf("no LPT entries for test.go")
+	}
+}
+
+func TestZeroSizedVariable(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	if runtime.GOOS == "plan9" {
+		t.Skip("skipping on plan9; no DWARF symbol table in executables")
+	}
+	t.Parallel()
+
+	// This test verifies that the compiler emits DIEs for zero sized variables
+	// (for example variables of type 'struct {}').
+	// See go.dev/issues/54615.
+
+	const prog = `
+package main
+
+import (
+	"fmt"
+)
+
+func main() {
+	zeroSizedVariable := struct{}{}
+	fmt.Println(zeroSizedVariable)
+}
+`
+
+	for _, opt := range []string{NoOpt, DefaultOpt} {
+		dir := t.TempDir()
+		f := gobuild(t, dir, prog, opt)
+		defer f.Close()
+		defer os.RemoveAll(dir)
+
+		d, err := f.DWARF()
+		if err != nil {
+			t.Fatalf("error reading DWARF: %v", err)
+		}
+
+		rdr := d.Reader()
+		ex := dwtest.Examiner{}
+		if err := ex.Populate(rdr); err != nil {
+			t.Fatalf("error reading DWARF: %v", err)
+		}
+
+		// Locate the main.zeroSizedVariable DIE
+		abcs := ex.Named("zeroSizedVariable")
+		if len(abcs) == 0 {
+			t.Fatalf("unable to locate DIE for zeroSizedVariable")
+		}
+		if len(abcs) != 1 {
+			t.Fatalf("more than one zeroSizedVariable DIE")
+		}
+	}
+}
diff --git a/src/cmd/link/internal/ld/elf.go b/src/cmd/link/internal/ld/elf.go
index 2566ded..a1ae7ea 100644
--- a/src/cmd/link/internal/ld/elf.go
+++ b/src/cmd/link/internal/ld/elf.go
@@ -15,6 +15,7 @@
 	"encoding/hex"
 	"fmt"
 	"internal/buildcfg"
+	"os"
 	"path/filepath"
 	"runtime"
 	"sort"
@@ -457,7 +458,7 @@
 	return elf32writehdr(out)
 }
 
-/* Taken directly from the definition document for ELF64 */
+/* Taken directly from the definition document for ELF64. */
 func elfhash(name string) uint32 {
 	var h uint32
 	for i := 0; i < len(name); i++ {
@@ -606,8 +607,13 @@
 	return int(sh.Size)
 }
 
-func elfnote(sh *ElfShdr, startva uint64, resoff uint64, sz int) int {
-	n := 3*4 + uint64(sz) + resoff%4
+func elfnote(sh *ElfShdr, startva uint64, resoff uint64, sizes ...int) int {
+	n := resoff % 4
+	// if section contains multiple notes (as is the case with FreeBSD signature),
+	// multiple note sizes can be specified
+	for _, sz := range sizes {
+		n += 3*4 + uint64(sz)
+	}
 
 	sh.Type = uint32(elf.SHT_NOTE)
 	sh.Flags = uint64(elf.SHF_ALLOC)
@@ -713,6 +719,67 @@
 	return int(sh.Size)
 }
 
+// FreeBSD Signature (as per sys/elf_common.h)
+const (
+	ELF_NOTE_FREEBSD_NAMESZ            = 8
+	ELF_NOTE_FREEBSD_DESCSZ            = 4
+	ELF_NOTE_FREEBSD_ABI_TAG           = 1
+	ELF_NOTE_FREEBSD_NOINIT_TAG        = 2
+	ELF_NOTE_FREEBSD_FEATURE_CTL_TAG   = 4
+	ELF_NOTE_FREEBSD_VERSION           = 1203000 // 12.3-RELEASE
+	ELF_NOTE_FREEBSD_FCTL_ASLR_DISABLE = 0x1
+)
+
+const ELF_NOTE_FREEBSD_NAME = "FreeBSD\x00"
+
+func elffreebsdsig(sh *ElfShdr, startva uint64, resoff uint64) int {
+	n := ELF_NOTE_FREEBSD_NAMESZ + ELF_NOTE_FREEBSD_DESCSZ
+	// FreeBSD signature section contains 3 equally sized notes
+	return elfnote(sh, startva, resoff, n, n, n)
+}
+
+// elfwritefreebsdsig writes FreeBSD .note section.
+//
+// See https://www.netbsd.org/docs/kernel/elf-notes.html for the description of
+// a Note element format and
+// https://github.com/freebsd/freebsd-src/blob/main/sys/sys/elf_common.h#L790
+// for the FreeBSD-specific values.
+func elfwritefreebsdsig(out *OutBuf) int {
+	sh := elfshname(".note.tag")
+	if sh == nil {
+		return 0
+	}
+	out.SeekSet(int64(sh.Off))
+
+	// NT_FREEBSD_ABI_TAG
+	out.Write32(ELF_NOTE_FREEBSD_NAMESZ)
+	out.Write32(ELF_NOTE_FREEBSD_DESCSZ)
+	out.Write32(ELF_NOTE_FREEBSD_ABI_TAG)
+	out.WriteString(ELF_NOTE_FREEBSD_NAME)
+	out.Write32(ELF_NOTE_FREEBSD_VERSION)
+
+	// NT_FREEBSD_NOINIT_TAG
+	out.Write32(ELF_NOTE_FREEBSD_NAMESZ)
+	out.Write32(ELF_NOTE_FREEBSD_DESCSZ)
+	out.Write32(ELF_NOTE_FREEBSD_NOINIT_TAG)
+	out.WriteString(ELF_NOTE_FREEBSD_NAME)
+	out.Write32(0)
+
+	// NT_FREEBSD_FEATURE_CTL
+	out.Write32(ELF_NOTE_FREEBSD_NAMESZ)
+	out.Write32(ELF_NOTE_FREEBSD_DESCSZ)
+	out.Write32(ELF_NOTE_FREEBSD_FEATURE_CTL_TAG)
+	out.WriteString(ELF_NOTE_FREEBSD_NAME)
+	if *flagRace {
+		// The race detector can't handle ASLR, turn the ASLR off when compiling with -race.
+		out.Write32(ELF_NOTE_FREEBSD_FCTL_ASLR_DISABLE)
+	} else {
+		out.Write32(0)
+	}
+
+	return int(sh.Size)
+}
+
 func addbuildinfo(val string) {
 	if !strings.HasPrefix(val, "0x") {
 		Exitf("-B argument must start with 0x: %s", val)
@@ -1030,7 +1097,7 @@
 }
 
 // Create an ElfShdr for the section with name.
-// Create a duplicate if one already exists with that name
+// Create a duplicate if one already exists with that name.
 func elfshnamedup(name string) *ElfShdr {
 	for i := 0; i < nelfstr; i++ {
 		if name == elfstr[i].s {
@@ -1304,7 +1371,7 @@
 	shstrtab.Addstring(".data")
 	shstrtab.Addstring(".bss")
 	shstrtab.Addstring(".noptrbss")
-	shstrtab.Addstring("__sancov_cntrs")
+	shstrtab.Addstring(".go.fuzzcntrs")
 	shstrtab.Addstring(".go.buildinfo")
 	if ctxt.IsMIPS() {
 		shstrtab.Addstring(".MIPS.abiflags")
@@ -1326,6 +1393,9 @@
 	if ctxt.IsOpenbsd() {
 		shstrtab.Addstring(".note.openbsd.ident")
 	}
+	if ctxt.IsFreebsd() {
+		shstrtab.Addstring(".note.tag")
+	}
 	if len(buildinfo) > 0 {
 		shstrtab.Addstring(".note.gnu.build-id")
 	}
@@ -1530,7 +1600,7 @@
 	if ctxt.IsShared() {
 		// The go.link.abihashbytes symbol will be pointed at the appropriate
 		// part of the .note.go.abihash section in data.go:func address().
-		s := ldr.LookupOrCreateSym("go.link.abihashbytes", 0)
+		s := ldr.LookupOrCreateSym("go:link.abihashbytes", 0)
 		sb := ldr.MakeSymbolUpdater(s)
 		ldr.SetAttrLocal(s, true)
 		sb.SetType(sym.SRODATA)
@@ -1782,6 +1852,16 @@
 					}
 				} else {
 					interpreter = thearch.Linuxdynld
+					// If interpreter does not exist, try musl instead.
+					// This lets the same cmd/link binary work on
+					// both glibc-based and musl-based systems.
+					if _, err := os.Stat(interpreter); err != nil {
+						if musl := thearch.LinuxdynldMusl; musl != "" {
+							if _, err := os.Stat(musl); err == nil {
+								interpreter = musl
+							}
+						}
+					}
 				}
 
 			case objabi.Hfreebsd:
@@ -1809,7 +1889,7 @@
 		phsh(ph, sh)
 	}
 
-	if ctxt.HeadType == objabi.Hnetbsd || ctxt.HeadType == objabi.Hopenbsd {
+	if ctxt.HeadType == objabi.Hnetbsd || ctxt.HeadType == objabi.Hopenbsd || ctxt.HeadType == objabi.Hfreebsd {
 		var sh *ElfShdr
 		switch ctxt.HeadType {
 		case objabi.Hnetbsd:
@@ -1819,8 +1899,12 @@
 		case objabi.Hopenbsd:
 			sh = elfshname(".note.openbsd.ident")
 			resoff -= int64(elfopenbsdsig(sh, uint64(startva), uint64(resoff)))
+
+		case objabi.Hfreebsd:
+			sh = elfshname(".note.tag")
+			resoff -= int64(elffreebsdsig(sh, uint64(startva), uint64(resoff)))
 		}
-		// netbsd and openbsd require ident in an independent segment.
+		// NetBSD, OpenBSD and FreeBSD require ident in an independent segment.
 		pnotei := newElfPhdr()
 		pnotei.Type = elf.PT_NOTE
 		pnotei.Flags = elf.PF_R
@@ -2198,6 +2282,9 @@
 		if ctxt.HeadType == objabi.Hopenbsd {
 			a += int64(elfwriteopenbsdsig(ctxt.Out))
 		}
+		if ctxt.HeadType == objabi.Hfreebsd {
+			a += int64(elfwritefreebsdsig(ctxt.Out))
+		}
 		if len(buildinfo) > 0 {
 			a += int64(elfwritebuildinfo(ctxt.Out))
 		}
diff --git a/src/cmd/link/internal/ld/elf_test.go b/src/cmd/link/internal/ld/elf_test.go
index 15eaa13..8af0ca1 100644
--- a/src/cmd/link/internal/ld/elf_test.go
+++ b/src/cmd/link/internal/ld/elf_test.go
@@ -1,18 +1,16 @@
-//go:build cgo
-// +build cgo
-
 // Copyright 2019 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build cgo
+// +build cgo
+
 package ld
 
 import (
 	"debug/elf"
 	"internal/testenv"
-	"io/ioutil"
 	"os"
-	"os/exec"
 	"path/filepath"
 	"runtime"
 	"strings"
@@ -34,12 +32,12 @@
 }
 `
 	src := filepath.Join(dir, "issue33358.go")
-	if err := ioutil.WriteFile(src, []byte(prog), 0666); err != nil {
+	if err := os.WriteFile(src, []byte(prog), 0666); err != nil {
 		t.Fatal(err)
 	}
 
 	binFile := filepath.Join(dir, "issue33358")
-	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", binFile, src)
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-o", binFile, src)
 	if out, err := cmd.CombinedOutput(); err != nil {
 		t.Fatalf("%v: %v:\n%s", cmd.Args, err, out)
 	}
@@ -102,7 +100,7 @@
 
 	path := filepath.Join(dir, "x")
 	argv := []string{"build", "-o", path, filepath.Join(wd, "testdata", "issue39256")}
-	out, err := exec.Command(testenv.GoToolPath(t), argv...).CombinedOutput()
+	out, err := testenv.Command(t, testenv.GoToolPath(t), argv...).CombinedOutput()
 	if err != nil {
 		t.Fatalf("Build failure: %s\n%s\n", err, string(out))
 	}
diff --git a/src/cmd/link/internal/ld/errors.go b/src/cmd/link/internal/ld/errors.go
index d6e8ff2..b553d68 100644
--- a/src/cmd/link/internal/ld/errors.go
+++ b/src/cmd/link/internal/ld/errors.go
@@ -21,7 +21,6 @@
 // ErrorReporter is used to make error reporting thread safe.
 type ErrorReporter struct {
 	loader.ErrorReporter
-	unresOnce  sync.Once
 	unresSyms  map[unresolvedSymKey]bool
 	unresMutex sync.Mutex
 	SymName    symNameFn
@@ -29,11 +28,13 @@
 
 // errorUnresolved prints unresolved symbol error for rs that is referenced from s.
 func (reporter *ErrorReporter) errorUnresolved(ldr *loader.Loader, s, rs loader.Sym) {
-	reporter.unresOnce.Do(func() { reporter.unresSyms = make(map[unresolvedSymKey]bool) })
-
-	k := unresolvedSymKey{from: s, to: rs}
 	reporter.unresMutex.Lock()
 	defer reporter.unresMutex.Unlock()
+
+	if reporter.unresSyms == nil {
+		reporter.unresSyms = make(map[unresolvedSymKey]bool)
+	}
+	k := unresolvedSymKey{from: s, to: rs}
 	if !reporter.unresSyms[k] {
 		reporter.unresSyms[k] = true
 		name := ldr.SymName(rs)
diff --git a/src/cmd/link/internal/ld/go.go b/src/cmd/link/internal/ld/go.go
index 1affe24..9dfb0f7 100644
--- a/src/cmd/link/internal/ld/go.go
+++ b/src/cmd/link/internal/ld/go.go
@@ -7,7 +7,6 @@
 package ld
 
 import (
-	"bytes"
 	"cmd/internal/bio"
 	"cmd/internal/obj"
 	"cmd/internal/objabi"
@@ -383,9 +382,9 @@
 }
 
 func fieldtrack(arch *sys.Arch, l *loader.Loader) {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	for i := loader.Sym(1); i < loader.Sym(l.NSym()); i++ {
-		if name := l.SymName(i); strings.HasPrefix(name, "go.track.") {
+		if name := l.SymName(i); strings.HasPrefix(name, "go:track.") {
 			if l.AttrReachable(i) {
 				l.SetAttrSpecial(i, true)
 				l.SetAttrNotInSymbolTable(i, true)
diff --git a/src/cmd/link/internal/ld/go_test.go b/src/cmd/link/internal/ld/go_test.go
index 230f85a..836731a 100644
--- a/src/cmd/link/internal/ld/go_test.go
+++ b/src/cmd/link/internal/ld/go_test.go
@@ -5,14 +5,14 @@
 package ld
 
 import (
-	"cmd/internal/objabi"
 	"internal/testenv"
-	"io/ioutil"
-	"os/exec"
+	"os"
 	"path/filepath"
 	"reflect"
 	"runtime"
 	"testing"
+
+	"cmd/internal/objabi"
 )
 
 func TestDedupLibraries(t *testing.T) {
@@ -99,18 +99,18 @@
 //go:cgo_import_dynamic _ _ "libc.so"
 
 func main() {}`
-	if err := ioutil.WriteFile(srcFile, []byte(src), 0644); err != nil {
+	if err := os.WriteFile(srcFile, []byte(src), 0644); err != nil {
 		t.Fatal(err)
 	}
 
 	exe := filepath.Join(dir, "deduped.exe")
-	out, err := exec.Command(testenv.GoToolPath(t), "build", "-o", exe, srcFile).CombinedOutput()
+	out, err := testenv.Command(t, testenv.GoToolPath(t), "build", "-o", exe, srcFile).CombinedOutput()
 	if err != nil {
 		t.Fatalf("build failure: %s\n%s\n", err, string(out))
 	}
 
 	// Result should be runnable.
-	if _, err = exec.Command(exe).CombinedOutput(); err != nil {
+	if _, err = testenv.Command(t, exe).CombinedOutput(); err != nil {
 		t.Fatal(err)
 	}
 }
diff --git a/src/cmd/link/internal/ld/ld.go b/src/cmd/link/internal/ld/ld.go
index aaad152..d416571 100644
--- a/src/cmd/link/internal/ld/ld.go
+++ b/src/cmd/link/internal/ld/ld.go
@@ -32,22 +32,22 @@
 package ld
 
 import (
-	"cmd/internal/goobj"
-	"cmd/link/internal/loader"
-	"cmd/link/internal/sym"
-	"io/ioutil"
 	"log"
 	"os"
 	"path"
 	"path/filepath"
 	"strconv"
 	"strings"
+
+	"cmd/internal/goobj"
+	"cmd/link/internal/loader"
+	"cmd/link/internal/sym"
 )
 
 func (ctxt *Link) readImportCfg(file string) {
 	ctxt.PackageFile = make(map[string]string)
 	ctxt.PackageShlib = make(map[string]string)
-	data, err := ioutil.ReadFile(file)
+	data, err := os.ReadFile(file)
 	if err != nil {
 		log.Fatalf("-importcfg: %v", err)
 	}
@@ -196,7 +196,7 @@
 	l.Fingerprint = fingerprint
 	if shlib != "" {
 		if strings.HasSuffix(shlib, ".shlibname") {
-			data, err := ioutil.ReadFile(shlib)
+			data, err := os.ReadFile(shlib)
 			if err != nil {
 				Errorf(nil, "cannot read %s: %v", shlib, err)
 			}
@@ -232,7 +232,7 @@
 
 	// Create a new init func text symbol. Caller will populate this
 	// sym with arch-specific content.
-	ifs := ctxt.loader.LookupOrCreateSym("go.link.addmoduledata", 0)
+	ifs := ctxt.loader.LookupOrCreateSym("go:link.addmoduledata", 0)
 	initfunc := ctxt.loader.MakeSymbolUpdater(ifs)
 	ctxt.loader.SetAttrReachable(ifs, true)
 	ctxt.loader.SetAttrLocal(ifs, true)
@@ -245,7 +245,7 @@
 	ctxt.Textp = append(ctxt.Textp, initfunc.Sym())
 
 	// Create an init array entry
-	amdi := ctxt.loader.LookupOrCreateSym("go.link.addmoduledatainit", 0)
+	amdi := ctxt.loader.LookupOrCreateSym("go:link.addmoduledatainit", 0)
 	initarray_entry := ctxt.loader.MakeSymbolUpdater(amdi)
 	ctxt.loader.SetAttrReachable(amdi, true)
 	ctxt.loader.SetAttrLocal(amdi, true)
diff --git a/src/cmd/link/internal/ld/ld_test.go b/src/cmd/link/internal/ld/ld_test.go
index 2d5a7ad..314dab7 100644
--- a/src/cmd/link/internal/ld/ld_test.go
+++ b/src/cmd/link/internal/ld/ld_test.go
@@ -9,8 +9,7 @@
 	"debug/pe"
 	"fmt"
 	"internal/testenv"
-	"io/ioutil"
-	"os/exec"
+	"os"
 	"path/filepath"
 	"runtime"
 	"strings"
@@ -26,7 +25,7 @@
 
 	t.Parallel()
 
-	out, err := exec.Command(testenv.GoToolPath(t), "build", "./testdata/issue10978").CombinedOutput()
+	out, err := testenv.Command(t, testenv.GoToolPath(t), "build", "./testdata/issue10978").CombinedOutput()
 	if err == nil {
 		t.Fatal("expected build to fail")
 	}
@@ -107,13 +106,13 @@
 
 	srcfile := filepath.Join(dir, "test.go")
 	arfile := filepath.Join(dir, "test.a")
-	if err := ioutil.WriteFile(srcfile, []byte(carchiveSrcText), 0666); err != nil {
+	if err := os.WriteFile(srcfile, []byte(carchiveSrcText), 0666); err != nil {
 		t.Fatal(err)
 	}
 
 	ldf := fmt.Sprintf("-ldflags=-v -tmpdir=%s", dir)
 	argv := []string{"build", "-buildmode=c-archive", "-o", arfile, ldf, srcfile}
-	out, err := exec.Command(testenv.GoToolPath(t), argv...).CombinedOutput()
+	out, err := testenv.Command(t, testenv.GoToolPath(t), argv...).CombinedOutput()
 	if err != nil {
 		t.Fatalf("build failure: %s\n%s\n", err, string(out))
 	}
@@ -155,13 +154,13 @@
 	// is arbitrary; we just need something sufficiently large that uses
 	// external linking.
 	exe := filepath.Join(dir, "go.exe")
-	out, err := exec.Command(testenv.GoToolPath(t), "build", "-o", exe, "-ldflags=-linkmode=external -debugtextsize=1048576", "cmd/go").CombinedOutput()
+	out, err := testenv.Command(t, testenv.GoToolPath(t), "build", "-o", exe, "-ldflags=-linkmode=external -debugtextsize=1048576", "cmd/go").CombinedOutput()
 	if err != nil {
 		t.Fatalf("build failure: %s\n%s\n", err, string(out))
 	}
 
 	// Check that we did split text sections.
-	out, err = exec.Command(testenv.GoToolPath(t), "tool", "nm", exe).CombinedOutput()
+	out, err = testenv.Command(t, testenv.GoToolPath(t), "tool", "nm", exe).CombinedOutput()
 	if err != nil {
 		t.Fatalf("nm failure: %s\n%s\n", err, string(out))
 	}
@@ -170,7 +169,7 @@
 	}
 
 	// Result should be runnable.
-	_, err = exec.Command(exe, "version").CombinedOutput()
+	_, err = testenv.Command(t, exe, "version").CombinedOutput()
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -202,7 +201,7 @@
 
 	srcfile := filepath.Join(dir, "test.go")
 	objfile := filepath.Join(dir, "test.dll")
-	if err := ioutil.WriteFile(srcfile, []byte(`package main; func main() { print("hello") }`), 0666); err != nil {
+	if err := os.WriteFile(srcfile, []byte(`package main; func main() { print("hello") }`), 0666); err != nil {
 		t.Fatal(err)
 	}
 	argv := []string{"build", "-buildmode=c-shared"}
@@ -210,7 +209,7 @@
 		argv = append(argv, "-ldflags", "-aslr=false")
 	}
 	argv = append(argv, "-o", objfile, srcfile)
-	out, err := exec.Command(testenv.GoToolPath(t), argv...).CombinedOutput()
+	out, err := testenv.Command(t, testenv.GoToolPath(t), argv...).CombinedOutput()
 	if err != nil {
 		t.Fatalf("build failure: %s\n%s\n", err, string(out))
 	}
@@ -327,10 +326,10 @@
 			t.Parallel()
 			tempDir := t.TempDir()
 			src := filepath.Join(tempDir, "x.go")
-			if err := ioutil.WriteFile(src, []byte(tt.prog), 0644); err != nil {
+			if err := os.WriteFile(src, []byte(tt.prog), 0644); err != nil {
 				t.Fatal(err)
 			}
-			cmd := exec.Command(testenv.GoToolPath(t), "run", src)
+			cmd := testenv.Command(t, testenv.GoToolPath(t), "run", src)
 			out, err := cmd.CombinedOutput()
 			if err != nil {
 				t.Fatal(err)
diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go
index 18910dd..c073017 100644
--- a/src/cmd/link/internal/ld/lib.go
+++ b/src/cmd/link/internal/ld/lib.go
@@ -32,6 +32,21 @@
 
 import (
 	"bytes"
+	"debug/elf"
+	"debug/macho"
+	"encoding/base64"
+	"encoding/binary"
+	"fmt"
+	"internal/buildcfg"
+	"io"
+	"log"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"runtime"
+	"strings"
+	"sync"
+
 	"cmd/internal/bio"
 	"cmd/internal/goobj"
 	"cmd/internal/notsha256"
@@ -43,21 +58,6 @@
 	"cmd/link/internal/loadpe"
 	"cmd/link/internal/loadxcoff"
 	"cmd/link/internal/sym"
-	"debug/elf"
-	"debug/macho"
-	"encoding/base64"
-	"encoding/binary"
-	"fmt"
-	"internal/buildcfg"
-	"io"
-	"io/ioutil"
-	"log"
-	"os"
-	"os/exec"
-	"path/filepath"
-	"runtime"
-	"strings"
-	"sync"
 )
 
 // Data layout and relocation.
@@ -183,6 +183,7 @@
 
 	Androiddynld   string
 	Linuxdynld     string
+	LinuxdynldMusl string
 	Freebsddynld   string
 	Netbsddynld    string
 	Openbsddynld   string
@@ -465,6 +466,9 @@
 		}
 	}
 
+	if name == "runtime" {
+		Exitf("error: unable to find runtime.a")
+	}
 	ctxt.Logf("warning: unable to find %s.a\n", name)
 	return nil
 }
@@ -472,7 +476,15 @@
 // extld returns the current external linker.
 func (ctxt *Link) extld() []string {
 	if len(flagExtld) == 0 {
-		flagExtld = []string{"gcc"}
+		// Return the default external linker for the platform.
+		// This only matters when link tool is called directly without explicit -extld,
+		// go tool already passes the correct linker in other cases.
+		switch buildcfg.GOOS {
+		case "darwin", "freebsd", "openbsd":
+			flagExtld = []string{"clang"}
+		default:
+			flagExtld = []string{"gcc"}
+		}
 	}
 	return flagExtld
 }
@@ -603,9 +615,14 @@
 		// If we have any undefined symbols in external
 		// objects, try to read them from the libgcc file.
 		any := false
-		undefs := ctxt.loader.UndefinedRelocTargets(1)
+		undefs, froms := ctxt.loader.UndefinedRelocTargets(1)
 		if len(undefs) > 0 {
 			any = true
+			if ctxt.Debugvlog > 1 {
+				ctxt.Logf("loadlib: first unresolved is %s [%d] from %s [%d]\n",
+					ctxt.loader.SymName(undefs[0]), undefs[0],
+					ctxt.loader.SymName(froms[0]), froms[0])
+			}
 		}
 		if any {
 			if *flagLibGCC == "" {
@@ -669,9 +686,14 @@
 			hostArchive(ctxt, p)
 		}
 		any = false
-		undefs := ctxt.loader.UndefinedRelocTargets(1)
+		undefs, froms := ctxt.loader.UndefinedRelocTargets(1)
 		if len(undefs) > 0 {
 			any = true
+			if ctxt.Debugvlog > 1 {
+				ctxt.Logf("loadWindowsHostArchives: remaining unresolved is %s [%d] from %s [%d]\n",
+					ctxt.loader.SymName(undefs[0]), undefs[0],
+					ctxt.loader.SymName(froms[0]), froms[0])
+			}
 		}
 	}
 	// If needed, create the __CTOR_LIST__ and __DTOR_LIST__
@@ -689,6 +711,13 @@
 			ctxt.loader.SetAttrSpecial(sb.Sym(), true)
 		}
 	}
+
+	// Fix up references to DLL import symbols now that we're done
+	// pulling in new objects.
+	if err := loadpe.PostProcessImports(); err != nil {
+		Errorf(nil, "%v", err)
+	}
+
 	// TODO: maybe do something similar to peimporteddlls to collect
 	// all lib names and try link them all to final exe just like
 	// libmingwex.a and libmingw32.a:
@@ -925,24 +954,24 @@
 
 // typeSymbolMangle mangles the given symbol name into something shorter.
 //
-// Keep the type.. prefix, which parts of the linker (like the
+// Keep the type:. prefix, which parts of the linker (like the
 // DWARF generator) know means the symbol is not decodable.
-// Leave type.runtime. symbols alone, because other parts of
+// Leave type:runtime. symbols alone, because other parts of
 // the linker manipulates them.
 func typeSymbolMangle(name string) string {
-	if !strings.HasPrefix(name, "type.") {
+	if !strings.HasPrefix(name, "type:") {
 		return name
 	}
-	if strings.HasPrefix(name, "type.runtime.") {
+	if strings.HasPrefix(name, "type:runtime.") {
 		return name
 	}
 	if len(name) <= 14 && !strings.Contains(name, "@") { // Issue 19529
 		return name
 	}
 	hash := notsha256.Sum256([]byte(name))
-	prefix := "type."
+	prefix := "type:"
 	if name[5] == '.' {
-		prefix = "type.."
+		prefix = "type:."
 	}
 	return prefix + base64.StdEncoding.EncodeToString(hash[:6])
 }
@@ -1080,6 +1109,8 @@
 	"os/user",
 	"runtime/cgo",
 	"runtime/race",
+	"runtime/race/internal/amd64v1",
+	"runtime/race/internal/amd64v3",
 	"runtime/msan",
 	"runtime/asan",
 }
@@ -1132,13 +1163,15 @@
 		if err != nil {
 			Exitf("cannot reopen %s: %v", h.pn, err)
 		}
-
 		f.MustSeek(h.off, 0)
 		if h.ld == nil {
 			Errorf(nil, "%s: unrecognized object file format", h.pn)
 			continue
 		}
 		h.ld(ctxt, f, h.pkg, h.length, h.pn)
+		if *flagCaptureHostObjs != "" {
+			captureHostObj(h)
+		}
 		f.Close()
 	}
 }
@@ -1156,7 +1189,7 @@
 
 	// create temporary directory and arrange cleanup
 	if *flagTmpdir == "" {
-		dir, err := ioutil.TempDir("", "go-link-")
+		dir, err := os.MkdirTemp("", "go-link-")
 		if err != nil {
 			log.Fatal(err)
 		}
@@ -1237,7 +1270,7 @@
 }
 INSERT AFTER .debug_types;
 `
-	err := ioutil.WriteFile(path, []byte(src), 0666)
+	err := os.WriteFile(path, []byte(src), 0666)
 	if err != nil {
 		Errorf(nil, "WriteFile %s failed: %v", name, err)
 	}
@@ -1423,7 +1456,6 @@
 		if ctxt.HeadType == objabi.Hdarwin {
 			if machoPlatform == PLATFORM_MACOS && ctxt.IsAMD64() {
 				argv = append(argv, "-Wl,-no_pie")
-				argv = append(argv, "-Wl,-pagezero_size,4000000")
 			}
 		}
 		if *flagRace && ctxt.HeadType == objabi.Hwindows {
@@ -1587,6 +1619,17 @@
 		argv = append(argv, unusedArguments)
 	}
 
+	if ctxt.IsWindows() {
+		// Suppress generation of the PE file header timestamp,
+		// so as to avoid spurious build ID differences between
+		// linked binaries that are otherwise identical other than
+		// the date/time they were linked.
+		const noTimeStamp = "-Wl,--no-insert-timestamp"
+		if linkerFlagSupported(ctxt.Arch, argv[0], altLinker, noTimeStamp) {
+			argv = append(argv, noTimeStamp)
+		}
+	}
+
 	const compressDWARF = "-Wl,--compress-debug-sections=zlib"
 	if ctxt.compressDWARF && linkerFlagSupported(ctxt.Arch, argv[0], altLinker, compressDWARF) {
 		argv = append(argv, compressDWARF)
@@ -1775,6 +1818,13 @@
 	if len(out) > 0 {
 		// always print external output even if the command is successful, so that we don't
 		// swallow linker warnings (see https://golang.org/issue/17935).
+		if ctxt.IsDarwin() && ctxt.IsAMD64() {
+			const noPieWarning = "ld: warning: -no_pie is deprecated when targeting new OS versions\n"
+			if i := bytes.Index(out, []byte(noPieWarning)); i >= 0 {
+				// swallow -no_pie deprecation warning, issue 54482
+				out = append(out[:i], out[i+len(noPieWarning):]...)
+			}
+		}
 		ctxt.Logf("%s", out)
 	}
 
@@ -1842,7 +1892,7 @@
 func linkerFlagSupported(arch *sys.Arch, linker, altLinker, flag string) bool {
 	createTrivialCOnce.Do(func() {
 		src := filepath.Join(*flagTmpdir, "trivial.c")
-		if err := ioutil.WriteFile(src, []byte("int main() { return 0; }"), 0666); err != nil {
+		if err := os.WriteFile(src, []byte("int main() { return 0; }"), 0666); err != nil {
 			Errorf(nil, "WriteFile trivial.c failed: %v", err)
 		}
 	})
@@ -2121,7 +2171,7 @@
 // to true if there is an unresolved reference to the symbol in want[K].
 func symbolsAreUnresolved(ctxt *Link, want []string) []bool {
 	returnAllUndefs := -1
-	undefs := ctxt.loader.UndefinedRelocTargets(returnAllUndefs)
+	undefs, _ := ctxt.loader.UndefinedRelocTargets(returnAllUndefs)
 	seen := make(map[loader.Sym]struct{})
 	rval := make([]bool, len(want))
 	wantm := make(map[string]int)
@@ -2164,8 +2214,13 @@
 	if h.ld == nil {
 		Exitf("unrecognized object file format in %s", path)
 	}
+	h.file = path
+	h.length = f.MustSeek(0, 2)
 	f.MustSeek(h.off, 0)
 	h.ld(ctxt, f, h.pkg, h.length, h.pn)
+	if *flagCaptureHostObjs != "" {
+		captureHostObj(h)
+	}
 }
 
 func checkFingerprint(lib *sym.Library, libfp goobj.FingerprintType, src string, srcfp goobj.FingerprintType) {
@@ -2318,11 +2373,11 @@
 			continue
 		}
 
-		// Symbols whose names start with "type." are compiler
-		// generated, so make functions with that prefix internal.
+		// Symbols whose names start with "type:" are compiler generated,
+		// so make functions with that prefix internal.
 		ver := 0
 		symname := elfsym.Name // (unmangled) symbol name
-		if elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC && strings.HasPrefix(elfsym.Name, "type.") {
+		if elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC && strings.HasPrefix(elfsym.Name, "type:") {
 			ver = abiInternalVer
 		} else if buildcfg.Experiment.RegabiWrappers && elf.ST_TYPE(elfsym.Info) == elf.STT_FUNC {
 			// Demangle the ABI name. Keep in sync with symtab.go:mangleABIName.
@@ -2356,7 +2411,7 @@
 			// The decodetype_* functions in decodetype.go need access to
 			// the type data.
 			sname := l.SymName(s)
-			if strings.HasPrefix(sname, "type.") && !strings.HasPrefix(sname, "type..") {
+			if strings.HasPrefix(sname, "type:") && !strings.HasPrefix(sname, "type:.") {
 				su.SetData(readelfsymboldata(ctxt, f, &elfsym))
 			}
 		}
@@ -2434,6 +2489,10 @@
 	}
 	ldr := ctxt.loader
 	s := ldr.Lookup(a, 0)
+	if s == 0 {
+		Errorf(nil, "missing entry symbol %q", a)
+		return 0
+	}
 	st := ldr.SymType(s)
 	if st == 0 {
 		return *FlagTextAddr
@@ -2565,3 +2624,46 @@
 		ldr.Errorf(s, "addgotsym: unsupported binary format")
 	}
 }
+
+var hostobjcounter int
+
+// captureHostObj writes out the content of a host object (pulled from
+// an archive or loaded from a *.o file directly) to a directory
+// specified via the linker's "-capturehostobjs" debugging flag. This
+// is intended to make it easier for a developer to inspect the actual
+// object feeding into "CGO internal" link step.
+func captureHostObj(h *Hostobj) {
+	// Form paths for info file and obj file.
+	ofile := fmt.Sprintf("captured-obj-%d.o", hostobjcounter)
+	ifile := fmt.Sprintf("captured-obj-%d.txt", hostobjcounter)
+	hostobjcounter++
+	opath := filepath.Join(*flagCaptureHostObjs, ofile)
+	ipath := filepath.Join(*flagCaptureHostObjs, ifile)
+
+	// Write the info file.
+	info := fmt.Sprintf("pkg: %s\npn: %s\nfile: %s\noff: %d\nlen: %d\n",
+		h.pkg, h.pn, h.file, h.off, h.length)
+	if err := os.WriteFile(ipath, []byte(info), 0666); err != nil {
+		log.Fatalf("error writing captured host obj info %s: %v", ipath, err)
+	}
+
+	readObjData := func() []byte {
+		inf, err := os.Open(h.file)
+		if err != nil {
+			log.Fatalf("capturing host obj: open failed on %s: %v", h.pn, err)
+		}
+		res := make([]byte, h.length)
+		if n, err := inf.ReadAt(res, h.off); err != nil || n != int(h.length) {
+			log.Fatalf("capturing host obj: readat failed on %s: %v", h.pn, err)
+		}
+		return res
+	}
+
+	// Write the object file.
+	if err := os.WriteFile(opath, readObjData(), 0666); err != nil {
+		log.Fatalf("error writing captured host object %s: %v", opath, err)
+	}
+
+	fmt.Fprintf(os.Stderr, "link: info: captured host object %s to %s\n",
+		h.file, opath)
+}
diff --git a/src/cmd/link/internal/ld/macho.go b/src/cmd/link/internal/ld/macho.go
index e7fd1cd..d6c28e4 100644
--- a/src/cmd/link/internal/ld/macho.go
+++ b/src/cmd/link/internal/ld/macho.go
@@ -479,8 +479,11 @@
 			var version uint32
 			switch ctxt.Arch.Family {
 			case sys.AMD64:
-				// The version must be at least 10.9; see golang.org/issues/30488.
-				version = 10<<16 | 9<<8 | 0<<0 // 10.9.0
+				// This must be fairly recent for Apple signing (go.dev/issue/30488).
+				// Having too old a version here was also implicated in some problems
+				// calling into macOS libraries (go.dev/issue/56784).
+				// In general this can be the most recent supported macOS version.
+				version = 10<<16 | 13<<8 | 0<<0 // 10.13.0
 			case sys.ARM64:
 				version = 11<<16 | 0<<8 | 0<<0 // 11.0.0
 			}
@@ -1020,16 +1023,16 @@
 		return true
 	}
 	name := ldr.SymName(s)
-	if strings.HasPrefix(name, "go.itab.") {
+	if strings.HasPrefix(name, "go:itab.") {
 		return true
 	}
-	if strings.HasPrefix(name, "type.") && !strings.HasPrefix(name, "type..") {
+	if strings.HasPrefix(name, "type:") && !strings.HasPrefix(name, "type:.") {
 		// reduce runtime typemap pressure, but do not
-		// export alg functions (type..*), as these
+		// export alg functions (type:.*), as these
 		// appear in pclntable.
 		return true
 	}
-	if strings.HasPrefix(name, "go.link.pkghash") {
+	if strings.HasPrefix(name, "go:link.pkghash") {
 		return true
 	}
 	return ldr.SymType(s) >= sym.SFirstWritable // only writable sections
diff --git a/src/cmd/link/internal/ld/main.go b/src/cmd/link/internal/ld/main.go
index c52e6e9..0058bd4 100644
--- a/src/cmd/link/internal/ld/main.go
+++ b/src/cmd/link/internal/ld/main.go
@@ -80,6 +80,8 @@
 	flagExtldflags quoted.Flag
 	flagExtar      = flag.String("extar", "", "archive program for buildmode=c-archive")
 
+	flagCaptureHostObjs = flag.String("capturehostobjs", "", "capture host object files loaded during internal linking to specified dir")
+
 	flagA             = flag.Bool("a", false, "no-op (deprecated)")
 	FlagC             = flag.Bool("c", false, "dump call graph")
 	FlagD             = flag.Bool("d", false, "disable dynamic executable")
diff --git a/src/cmd/link/internal/ld/msync_darwin_libc.go b/src/cmd/link/internal/ld/msync_darwin_libc.go
new file mode 100644
index 0000000..eb2a526
--- /dev/null
+++ b/src/cmd/link/internal/ld/msync_darwin_libc.go
@@ -0,0 +1,12 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build darwin && go1.20
+
+package ld
+
+import _ "unsafe" // for go:linkname
+
+//go:linkname msync syscall.msync
+func msync(b []byte, flags int) (err error)
diff --git a/src/cmd/link/internal/ld/msync_darwin_syscall.go b/src/cmd/link/internal/ld/msync_darwin_syscall.go
new file mode 100644
index 0000000..270d9f3
--- /dev/null
+++ b/src/cmd/link/internal/ld/msync_darwin_syscall.go
@@ -0,0 +1,24 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build darwin && !go1.20
+
+package ld
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+func msync(b []byte, flags int) (err error) {
+	var p unsafe.Pointer
+	if len(b) > 0 {
+		p = unsafe.Pointer(&b[0])
+	}
+	_, _, errno := syscall.Syscall(syscall.SYS_MSYNC, uintptr(p), uintptr(len(b)), uintptr(flags))
+	if errno != 0 {
+		return errno
+	}
+	return nil
+}
diff --git a/src/cmd/link/internal/ld/nooptcgolink_test.go b/src/cmd/link/internal/ld/nooptcgolink_test.go
index 0b76eca..646583f 100644
--- a/src/cmd/link/internal/ld/nooptcgolink_test.go
+++ b/src/cmd/link/internal/ld/nooptcgolink_test.go
@@ -6,7 +6,6 @@
 
 import (
 	"internal/testenv"
-	"os/exec"
 	"path/filepath"
 	"testing"
 )
@@ -20,7 +19,7 @@
 	testenv.MustHaveGoBuild(t)
 	testenv.MustHaveCGO(t)
 	dir := t.TempDir()
-	cmd := exec.Command(testenv.GoToolPath(t), "build", "-gcflags=-N -l", "-o", filepath.Join(dir, "a.out"))
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-gcflags=-N -l", "-o", filepath.Join(dir, "a.out"))
 	cmd.Dir = filepath.Join(testenv.GOROOT(t), "src", "runtime", "testdata", "testprogcgo")
 	out, err := cmd.CombinedOutput()
 	if err != nil {
diff --git a/src/cmd/link/internal/ld/outbuf_darwin.go b/src/cmd/link/internal/ld/outbuf_darwin.go
index e372b37..17f7e2a 100644
--- a/src/cmd/link/internal/ld/outbuf_darwin.go
+++ b/src/cmd/link/internal/ld/outbuf_darwin.go
@@ -2,9 +2,6 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build darwin && go1.12
-// +build darwin,go1.12
-
 package ld
 
 import (
@@ -24,7 +21,7 @@
 	}
 	// F_PEOFPOSMODE allocates from the end of the file, so we want the size difference.
 	// Apparently, it uses the end of the allocation, instead of the logical end of the
-	// the file.
+	// file.
 	cursize := uint64(stat.Sys().(*syscall.Stat_t).Blocks * 512) // allocated size
 	if size <= cursize {
 		return nil
@@ -46,6 +43,6 @@
 	// When we mmap the output buffer, it doesn't have a code signature
 	// (as we haven't generated one). Invalidate the kernel cache now that
 	// we have generated the signature. See issue #42684.
-	syscall.Syscall(syscall.SYS_MSYNC, uintptr(unsafe.Pointer(&out.buf[0])), uintptr(len(out.buf)), syscall.MS_INVALIDATE)
+	msync(out.buf, syscall.MS_INVALIDATE)
 	// Best effort. Ignore error.
 }
diff --git a/src/cmd/link/internal/ld/outbuf_mmap.go b/src/cmd/link/internal/ld/outbuf_mmap.go
index 40a3222..7bb728a 100644
--- a/src/cmd/link/internal/ld/outbuf_mmap.go
+++ b/src/cmd/link/internal/ld/outbuf_mmap.go
@@ -2,8 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd
-// +build aix darwin dragonfly freebsd linux netbsd openbsd
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || (solaris && go1.20)
 
 package ld
 
diff --git a/src/cmd/link/internal/ld/outbuf_nofallocate.go b/src/cmd/link/internal/ld/outbuf_nofallocate.go
index 3bffe45..dd5afc6 100644
--- a/src/cmd/link/internal/ld/outbuf_nofallocate.go
+++ b/src/cmd/link/internal/ld/outbuf_nofallocate.go
@@ -2,8 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build (!darwin && !linux) || (darwin && !go1.12)
-// +build !darwin,!linux darwin,!go1.12
+//go:build !darwin && !linux
 
 package ld
 
diff --git a/src/cmd/link/internal/ld/outbuf_nommap.go b/src/cmd/link/internal/ld/outbuf_nommap.go
index c870fa2..b1d3d27 100644
--- a/src/cmd/link/internal/ld/outbuf_nommap.go
+++ b/src/cmd/link/internal/ld/outbuf_nommap.go
@@ -2,8 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !windows
-// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!windows
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !(solaris && go1.20) && !windows
 
 package ld
 
diff --git a/src/cmd/link/internal/ld/outbuf_notdarwin.go b/src/cmd/link/internal/ld/outbuf_notdarwin.go
index 85e6442..f9caa41 100644
--- a/src/cmd/link/internal/ld/outbuf_notdarwin.go
+++ b/src/cmd/link/internal/ld/outbuf_notdarwin.go
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build !darwin || (darwin && !go1.12)
-// +build !darwin darwin,!go1.12
+//go:build !darwin
+// +build !darwin
 
 package ld
 
diff --git a/src/cmd/link/internal/ld/outbuf_windows.go b/src/cmd/link/internal/ld/outbuf_windows.go
index a568a17..95937e7 100644
--- a/src/cmd/link/internal/ld/outbuf_windows.go
+++ b/src/cmd/link/internal/ld/outbuf_windows.go
@@ -5,7 +5,7 @@
 package ld
 
 import (
-	"reflect"
+	"internal/unsafeheader"
 	"syscall"
 	"unsafe"
 )
@@ -35,8 +35,8 @@
 	if err != nil {
 		return err
 	}
-	bufHdr := (*reflect.SliceHeader)(unsafe.Pointer(&out.buf))
-	bufHdr.Data = ptr
+	bufHdr := (*unsafeheader.Slice)(unsafe.Pointer(&out.buf))
+	bufHdr.Data = unsafe.Pointer(ptr)
 	bufHdr.Len = int(filesize)
 	bufHdr.Cap = int(filesize)
 
diff --git a/src/cmd/link/internal/ld/pcln.go b/src/cmd/link/internal/ld/pcln.go
index 7a7a483..34ab86c 100644
--- a/src/cmd/link/internal/ld/pcln.go
+++ b/src/cmd/link/internal/ld/pcln.go
@@ -17,7 +17,7 @@
 	"strings"
 )
 
-const funcSize = 10 * 4 // funcSize is the size of the _func object in runtime/runtime2.go
+const funcSize = 11 * 4 // funcSize is the size of the _func object in runtime/runtime2.go
 
 // pclntab holds the state needed for pclntab generation.
 type pclntab struct {
@@ -162,26 +162,36 @@
 	ninl := fi.NumInlTree()
 	for i := 0; i < int(ninl); i++ {
 		call := fi.InlTree(i)
-		val := call.File
-		nameoff, ok := nameOffsets[call.Func]
+		nameOff, ok := nameOffsets[call.Func]
 		if !ok {
 			panic("couldn't find function name offset")
 		}
 
-		inlTreeSym.SetUint16(arch, int64(i*20+0), uint16(call.Parent))
 		inlFunc := ldr.FuncInfo(call.Func)
-
 		var funcID objabi.FuncID
+		startLine := int32(0)
 		if inlFunc.Valid() {
 			funcID = inlFunc.FuncID()
+			startLine = inlFunc.StartLine()
+		} else if !ctxt.linkShared {
+			// Inlined functions are always Go functions, and thus
+			// must have FuncInfo.
+			//
+			// Unfortunately, with -linkshared, the inlined
+			// function may be external symbols (from another
+			// shared library), and we don't load FuncInfo from the
+			// shared library. We will report potentially incorrect
+			// FuncID in this case. See https://go.dev/issue/55954.
+			panic(fmt.Sprintf("inlined function %s missing func info", ldr.SymName(call.Func)))
 		}
-		inlTreeSym.SetUint8(arch, int64(i*20+2), uint8(funcID))
 
-		// byte 3 is unused
-		inlTreeSym.SetUint32(arch, int64(i*20+4), uint32(val))
-		inlTreeSym.SetUint32(arch, int64(i*20+8), uint32(call.Line))
-		inlTreeSym.SetUint32(arch, int64(i*20+12), uint32(nameoff))
-		inlTreeSym.SetUint32(arch, int64(i*20+16), uint32(call.ParentPC))
+		// Construct runtime.inlinedCall value.
+		const size = 16
+		inlTreeSym.SetUint8(arch, int64(i*size+0), uint8(funcID))
+		// Bytes 1-3 are unused.
+		inlTreeSym.SetUint32(arch, int64(i*size+4), uint32(nameOff))
+		inlTreeSym.SetUint32(arch, int64(i*size+8), uint32(call.ParentPC))
+		inlTreeSym.SetUint32(arch, int64(i*size+12), uint32(startLine))
 	}
 	return its
 }
@@ -222,7 +232,7 @@
 
 		// Write header.
 		// Keep in sync with runtime/symtab.go:pcHeader and package debug/gosym.
-		header.SetUint32(ctxt.Arch, 0, 0xfffffff0)
+		header.SetUint32(ctxt.Arch, 0, 0xfffffff1)
 		header.SetUint8(ctxt.Arch, 6, uint8(ctxt.Arch.MinLC))
 		header.SetUint8(ctxt.Arch, 7, uint8(ctxt.Arch.PtrSize))
 		off := header.SetUint(ctxt.Arch, 8, uint64(state.nfunc))
@@ -627,7 +637,7 @@
 func writeFuncs(ctxt *Link, sb *loader.SymbolBuilder, funcs []loader.Sym, inlSyms map[loader.Sym]loader.Sym, startLocations, cuOffsets []uint32, nameOffsets map[loader.Sym]uint32) {
 	ldr := ctxt.loader
 	deferReturnSym := ldr.Lookup("runtime.deferreturn", abiInternalVer)
-	gofunc := ldr.Lookup("go.func.*", 0)
+	gofunc := ldr.Lookup("go:func.*", 0)
 	gofuncBase := ldr.SymValue(gofunc)
 	textStart := ldr.SymValue(ldr.Lookup("runtime.text", 0))
 	funcdata := []loader.Sym{}
@@ -636,26 +646,28 @@
 
 	// Write the individual func objects.
 	for i, s := range funcs {
+		startLine := int32(0)
 		fi := ldr.FuncInfo(s)
 		if fi.Valid() {
 			fi.Preload()
 			pcsp, pcfile, pcline, pcinline, pcdata = ldr.PcdataAuxs(s, pcdata)
+			startLine = fi.StartLine()
 		}
 
 		off := int64(startLocations[i])
-		// entry uintptr (offset of func entry PC from textStart)
+		// entryOff uint32 (offset of func entry PC from textStart)
 		entryOff := ldr.SymValue(s) - textStart
 		if entryOff < 0 {
 			panic(fmt.Sprintf("expected func %s(%x) to be placed before or at textStart (%x)", ldr.SymName(s), ldr.SymValue(s), textStart))
 		}
 		off = sb.SetUint32(ctxt.Arch, off, uint32(entryOff))
 
-		// name int32
-		nameoff, ok := nameOffsets[s]
+		// nameOff int32
+		nameOff, ok := nameOffsets[s]
 		if !ok {
 			panic("couldn't find function name offset")
 		}
-		off = sb.SetUint32(ctxt.Arch, off, uint32(nameoff))
+		off = sb.SetUint32(ctxt.Arch, off, uint32(nameOff))
 
 		// args int32
 		// TODO: Move into funcinfo.
@@ -686,6 +698,9 @@
 		}
 		off = sb.SetUint32(ctxt.Arch, off, cuIdx)
 
+		// startLine int32
+		off = sb.SetUint32(ctxt.Arch, off, uint32(startLine))
+
 		// funcID uint8
 		var funcID objabi.FuncID
 		if fi.Valid() {
@@ -716,7 +731,7 @@
 			}
 		}
 
-		// Write funcdata refs as offsets from go.func.* and go.funcrel.*.
+		// Write funcdata refs as offsets from go:func.* and go:funcrel.*.
 		funcdata = funcData(ldr, s, fi, inlSyms[s], funcdata)
 		// Missing funcdata will be ^0. See runtime/symtab.go:funcdata.
 		off = int64(startLocations[i] + funcSize + numPCData(ldr, s, fi)*4)
@@ -729,7 +744,7 @@
 			}
 
 			if outer := ldr.OuterSym(fdsym); outer != gofunc {
-				panic(fmt.Sprintf("bad carrier sym for symbol %s (funcdata %s#%d), want go.func.* got %s", ldr.SymName(fdsym), ldr.SymName(s), j, ldr.SymName(outer)))
+				panic(fmt.Sprintf("bad carrier sym for symbol %s (funcdata %s#%d), want go:func.* got %s", ldr.SymName(fdsym), ldr.SymName(s), j, ldr.SymName(outer)))
 			}
 			sb.SetUint32(ctxt.Arch, dataoff, uint32(ldr.SymValue(fdsym)-gofuncBase))
 		}
diff --git a/src/cmd/link/internal/ld/pe.go b/src/cmd/link/internal/ld/pe.go
index 6d1cd72..0e29131 100644
--- a/src/cmd/link/internal/ld/pe.go
+++ b/src/cmd/link/internal/ld/pe.go
@@ -723,7 +723,27 @@
 
 		// Only windows/386 requires underscore prefix on external symbols.
 		if ctxt.Is386() && ctxt.IsExternal() &&
-			(t == sym.SHOSTOBJ || t == sym.SUNDEFEXT || ldr.AttrCgoExport(s)) {
+			(t == sym.SHOSTOBJ || t == sym.SUNDEFEXT || ldr.AttrCgoExport(s) ||
+				// TODO(cuonglm): remove this hack
+				//
+				// Previously, windows/386 requires underscore prefix on external symbols,
+				// but that's only applied for SHOSTOBJ/SUNDEFEXT or cgo export symbols.
+				// "go.buildid" is STEXT, "type.*" is STYPE, thus they are not prefixed
+				// with underscore.
+				//
+				// In external linking mode, the external linker can't resolve them as
+				// external symbols. But we are lucky that they have "." in their name,
+				// so the external linker see them as Forwarder RVA exports. See:
+				//
+				//  - https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#export-address-table
+				//  - https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=ld/pe-dll.c;h=e7b82ba6ffadf74dc1b9ee71dc13d48336941e51;hb=HEAD#l972)
+				//
+				// CL 317917 changes "." to ":" in symbols name, so theses symbols can not be
+				// found by external linker anymore. So a hacky way is adding the
+				// underscore prefix for these 2 symbols. I don't have enough knowledge to
+				// verify whether adding the underscore for all STEXT/STYPE symbols are
+				// fine, even if it could be, that would be done in future CL.
+				name == "go:buildid" || name == "type:*") {
 			name = "_" + name
 		}
 
diff --git a/src/cmd/link/internal/ld/stackcheck.go b/src/cmd/link/internal/ld/stackcheck.go
index f0e1367..c82dafe 100644
--- a/src/cmd/link/internal/ld/stackcheck.go
+++ b/src/cmd/link/internal/ld/stackcheck.go
@@ -61,7 +61,7 @@
 	// The call to morestack in every splittable function ensures
 	// that there are at least StackLimit bytes available below SP
 	// when morestack returns.
-	limit := objabi.StackLimit - sc.callSize
+	limit := objabi.StackLimit(*flagRace) - sc.callSize
 	if buildcfg.GOARCH == "arm64" {
 		// Need an extra 8 bytes below SP to save FP.
 		limit -= 8
diff --git a/src/cmd/link/internal/ld/stackcheck_test.go b/src/cmd/link/internal/ld/stackcheck_test.go
index 2089bad..dd7e205 100644
--- a/src/cmd/link/internal/ld/stackcheck_test.go
+++ b/src/cmd/link/internal/ld/stackcheck_test.go
@@ -8,7 +8,6 @@
 	"fmt"
 	"internal/testenv"
 	"os"
-	"os/exec"
 	"regexp"
 	"strconv"
 	"testing"
@@ -20,7 +19,7 @@
 	testenv.MustHaveGoBuild(t)
 	t.Parallel()
 
-	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", os.DevNull, "./testdata/stackcheck")
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-o", os.DevNull, "./testdata/stackcheck")
 	// The rules for computing frame sizes on all of the
 	// architectures are complicated, so just do this on amd64.
 	cmd.Env = append(os.Environ(), "GOARCH=amd64", "GOOS=linux")
@@ -34,7 +33,7 @@
 	t.Logf("linker output:\n%s", out)
 
 	// Get expected limit.
-	limitRe := regexp.MustCompile("nosplit stack over ([0-9]+) byte limit")
+	limitRe := regexp.MustCompile(`nosplit stack over (\d+) byte limit`)
 	m := limitRe.FindStringSubmatch(out)
 	if m == nil {
 		t.Fatalf("no overflow errors in output")
@@ -66,7 +65,7 @@
 	}
 
 	// Parse stanzas
-	stanza := regexp.MustCompile(`^(.*): nosplit stack over [0-9]+ byte limit\n(.*\n(?: .*\n)*)`)
+	stanza := regexp.MustCompile(`^(.*): nosplit stack over \d+ byte limit\n(.*\n(?: .*\n)*)`)
 	// Strip comments from cmd/go
 	out = regexp.MustCompile(`(?m)^#.*\n`).ReplaceAllString(out, "")
 	for len(out) > 0 {
diff --git a/src/cmd/link/internal/ld/symtab.go b/src/cmd/link/internal/ld/symtab.go
index ee963bc..21a1466 100644
--- a/src/cmd/link/internal/ld/symtab.go
+++ b/src/cmd/link/internal/ld/symtab.go
@@ -453,6 +453,8 @@
 	ctxt.xdefine("runtime.ebss", sym.SBSS, 0)
 	ctxt.xdefine("runtime.noptrbss", sym.SNOPTRBSS, 0)
 	ctxt.xdefine("runtime.enoptrbss", sym.SNOPTRBSS, 0)
+	ctxt.xdefine("runtime.covctrs", sym.SNOPTRBSS, 0)
+	ctxt.xdefine("runtime.ecovctrs", sym.SNOPTRBSS, 0)
 	ctxt.xdefine("runtime.end", sym.SBSS, 0)
 	ctxt.xdefine("runtime.epclntab", sym.SRODATA, 0)
 	ctxt.xdefine("runtime.esymtab", sym.SRODATA, 0)
@@ -472,7 +474,7 @@
 	var symtype, symtyperel loader.Sym
 	if !ctxt.DynlinkingGo() {
 		if ctxt.UseRelro() && (ctxt.BuildMode == BuildModeCArchive || ctxt.BuildMode == BuildModeCShared || ctxt.BuildMode == BuildModePIE) {
-			s = ldr.CreateSymForUpdate("type.*", 0)
+			s = ldr.CreateSymForUpdate("type:*", 0)
 			s.SetType(sym.STYPE)
 			s.SetSize(0)
 			s.SetAlign(int32(ctxt.Arch.PtrSize))
@@ -484,7 +486,7 @@
 			s.SetAlign(int32(ctxt.Arch.PtrSize))
 			symtyperel = s.Sym()
 		} else {
-			s = ldr.CreateSymForUpdate("type.*", 0)
+			s = ldr.CreateSymForUpdate("type:*", 0)
 			s.SetType(sym.STYPE)
 			s.SetSize(0)
 			s.SetAlign(int32(ctxt.Arch.PtrSize))
@@ -505,14 +507,14 @@
 		return s.Sym()
 	}
 	var (
-		symgostring = groupSym("go.string.*", sym.SGOSTRING)
-		symgofunc   = groupSym("go.func.*", sym.SGOFUNC)
+		symgostring = groupSym("go:string.*", sym.SGOSTRING)
+		symgofunc   = groupSym("go:func.*", sym.SGOFUNC)
 		symgcbits   = groupSym("runtime.gcbits.*", sym.SGCBITS)
 	)
 
 	symgofuncrel := symgofunc
 	if ctxt.UseRelro() {
-		symgofuncrel = groupSym("go.funcrel.*", sym.SGOFUNCRELRO)
+		symgofuncrel = groupSym("go:funcrel.*", sym.SGOFUNCRELRO)
 	}
 
 	symt := ldr.CreateSymForUpdate("runtime.symtab", 0)
@@ -529,7 +531,7 @@
 	nsym := loader.Sym(ldr.NSym())
 	symGroupType := make([]sym.SymKind, nsym)
 	for s := loader.Sym(1); s < nsym; s++ {
-		if !ctxt.IsExternal() && ldr.IsFileLocal(s) && !ldr.IsFromAssembly(s) && ldr.SymPkg(s) != "" {
+		if (!ctxt.IsExternal() && ldr.IsFileLocal(s) && !ldr.IsFromAssembly(s) && ldr.SymPkg(s) != "") || (ctxt.LinkMode == LinkInternal && ldr.SymType(s) == sym.SCOVERAGE_COUNTER) {
 			ldr.SetAttrNotInSymbolTable(s, true)
 		}
 		if !ldr.AttrReachable(s) || ldr.AttrSpecial(s) || (ldr.SymType(s) != sym.SRODATA && ldr.SymType(s) != sym.SGOFUNC) {
@@ -538,13 +540,13 @@
 
 		name := ldr.SymName(s)
 		switch {
-		case strings.HasPrefix(name, "go.string."):
+		case strings.HasPrefix(name, "go:string."):
 			symGroupType[s] = sym.SGOSTRING
 			ldr.SetAttrNotInSymbolTable(s, true)
 			ldr.SetCarrierSym(s, symgostring)
 
 		case strings.HasPrefix(name, "runtime.gcbits."),
-			strings.HasPrefix(name, "type..gcprog."):
+			strings.HasPrefix(name, "type:.gcprog."):
 			symGroupType[s] = sym.SGCBITS
 			ldr.SetAttrNotInSymbolTable(s, true)
 			ldr.SetCarrierSym(s, symgcbits)
@@ -582,10 +584,10 @@
 				liveness += (ldr.SymSize(s) + int64(align) - 1) &^ (int64(align) - 1)
 			}
 
-		// Note: Check for "type." prefix after checking for .arginfo1 suffix.
-		// That way symbols like "type..eq.[2]interface {}.arginfo1" that belong
-		// in go.func.* end up there.
-		case strings.HasPrefix(name, "type."):
+		// Note: Check for "type:" prefix after checking for .arginfo1 suffix.
+		// That way symbols like "type:.eq.[2]interface {}.arginfo1" that belong
+		// in go:func.* end up there.
+		case strings.HasPrefix(name, "type:"):
 			if !ctxt.DynlinkingGo() {
 				ldr.SetAttrNotInSymbolTable(s, true)
 			}
@@ -604,19 +606,19 @@
 	}
 
 	if ctxt.BuildMode == BuildModeShared {
-		abihashgostr := ldr.CreateSymForUpdate("go.link.abihash."+filepath.Base(*flagOutfile), 0)
+		abihashgostr := ldr.CreateSymForUpdate("go:link.abihash."+filepath.Base(*flagOutfile), 0)
 		abihashgostr.SetType(sym.SRODATA)
-		hashsym := ldr.LookupOrCreateSym("go.link.abihashbytes", 0)
+		hashsym := ldr.LookupOrCreateSym("go:link.abihashbytes", 0)
 		abihashgostr.AddAddr(ctxt.Arch, hashsym)
 		abihashgostr.AddUint(ctxt.Arch, uint64(ldr.SymSize(hashsym)))
 	}
 	if ctxt.BuildMode == BuildModePlugin || ctxt.CanUsePlugins() {
 		for _, l := range ctxt.Library {
-			s := ldr.CreateSymForUpdate("go.link.pkghashbytes."+l.Pkg, 0)
+			s := ldr.CreateSymForUpdate("go:link.pkghashbytes."+l.Pkg, 0)
 			s.SetType(sym.SRODATA)
 			s.SetSize(int64(len(l.Fingerprint)))
 			s.SetData(l.Fingerprint[:])
-			str := ldr.CreateSymForUpdate("go.link.pkghash."+l.Pkg, 0)
+			str := ldr.CreateSymForUpdate("go:link.pkghash."+l.Pkg, 0)
 			str.SetType(sym.SRODATA)
 			str.AddAddr(ctxt.Arch, s.Sym())
 			str.AddUint(ctxt.Arch, uint64(len(l.Fingerprint)))
@@ -672,20 +674,26 @@
 	moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.ebss", 0))
 	moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.noptrbss", 0))
 	moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.enoptrbss", 0))
+	moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.covctrs", 0))
+	moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.ecovctrs", 0))
 	moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.end", 0))
 	moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.gcdata", 0))
 	moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.gcbss", 0))
 	moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.types", 0))
 	moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.etypes", 0))
 	moduledata.AddAddr(ctxt.Arch, ldr.Lookup("runtime.rodata", 0))
-	moduledata.AddAddr(ctxt.Arch, ldr.Lookup("go.func.*", 0))
+	moduledata.AddAddr(ctxt.Arch, ldr.Lookup("go:func.*", 0))
 
 	if ctxt.IsAIX() && ctxt.IsExternal() {
 		// Add R_XCOFFREF relocation to prevent ld's garbage collection of
 		// the following symbols. They might not be referenced in the program.
 		addRef := func(name string) {
+			s := ldr.Lookup(name, 0)
+			if s == 0 {
+				return
+			}
 			r, _ := moduledata.AddRel(objabi.R_XCOFFREF)
-			r.SetSym(ldr.Lookup(name, 0))
+			r.SetSym(s)
 			r.SetSiz(uint8(ctxt.Arch.PtrSize))
 		}
 		addRef("runtime.rodata")
@@ -695,8 +703,8 @@
 		// important that the offsets we computed stay unchanged by the external
 		// linker, i.e. all symbols in Textp should not be removed.
 		// Most of them are actually referenced (our deadcode pass ensures that),
-		// except go.buildid which is generated late and not used by the program.
-		addRef("go.buildid")
+		// except go:buildid which is generated late and not used by the program.
+		addRef("go:buildid")
 	}
 
 	// text section information
@@ -717,10 +725,10 @@
 	moduledata.AddUint(ctxt.Arch, nitablinks)
 	moduledata.AddUint(ctxt.Arch, nitablinks)
 	// The ptab slice
-	if ptab := ldr.Lookup("go.plugin.tabs", 0); ptab != 0 && ldr.AttrReachable(ptab) {
+	if ptab := ldr.Lookup("go:plugin.tabs", 0); ptab != 0 && ldr.AttrReachable(ptab) {
 		ldr.SetAttrLocal(ptab, true)
 		if ldr.SymType(ptab) != sym.SRODATA {
-			panic(fmt.Sprintf("go.plugin.tabs is %v, not SRODATA", ldr.SymType(ptab)))
+			panic(fmt.Sprintf("go:plugin.tabs is %v, not SRODATA", ldr.SymType(ptab)))
 		}
 		nentries := uint64(len(ldr.Data(ptab)) / 8) // sizeof(nameOff) + sizeof(typeOff)
 		moduledata.AddAddr(ctxt.Arch, ptab)
@@ -732,19 +740,19 @@
 		moduledata.AddUint(ctxt.Arch, 0)
 	}
 	if ctxt.BuildMode == BuildModePlugin {
-		addgostring(ctxt, ldr, moduledata, "go.link.thispluginpath", objabi.PathToPrefix(*flagPluginPath))
+		addgostring(ctxt, ldr, moduledata, "go:link.thispluginpath", objabi.PathToPrefix(*flagPluginPath))
 
-		pkghashes := ldr.CreateSymForUpdate("go.link.pkghashes", 0)
+		pkghashes := ldr.CreateSymForUpdate("go:link.pkghashes", 0)
 		pkghashes.SetLocal(true)
 		pkghashes.SetType(sym.SRODATA)
 
 		for i, l := range ctxt.Library {
 			// pkghashes[i].name
-			addgostring(ctxt, ldr, pkghashes, fmt.Sprintf("go.link.pkgname.%d", i), l.Pkg)
+			addgostring(ctxt, ldr, pkghashes, fmt.Sprintf("go:link.pkgname.%d", i), l.Pkg)
 			// pkghashes[i].linktimehash
-			addgostring(ctxt, ldr, pkghashes, fmt.Sprintf("go.link.pkglinkhash.%d", i), string(l.Fingerprint[:]))
+			addgostring(ctxt, ldr, pkghashes, fmt.Sprintf("go:link.pkglinkhash.%d", i), string(l.Fingerprint[:]))
 			// pkghashes[i].runtimehash
-			hash := ldr.Lookup("go.link.pkghash."+l.Pkg, 0)
+			hash := ldr.Lookup("go:link.pkghash."+l.Pkg, 0)
 			pkghashes.AddAddr(ctxt.Arch, hash)
 		}
 		moduledata.AddAddr(ctxt.Arch, pkghashes.Sym())
@@ -765,22 +773,22 @@
 			// it something slightly more comprehensible.
 			thismodulename = "the executable"
 		}
-		addgostring(ctxt, ldr, moduledata, "go.link.thismodulename", thismodulename)
+		addgostring(ctxt, ldr, moduledata, "go:link.thismodulename", thismodulename)
 
-		modulehashes := ldr.CreateSymForUpdate("go.link.abihashes", 0)
+		modulehashes := ldr.CreateSymForUpdate("go:link.abihashes", 0)
 		modulehashes.SetLocal(true)
 		modulehashes.SetType(sym.SRODATA)
 
 		for i, shlib := range ctxt.Shlibs {
 			// modulehashes[i].modulename
 			modulename := filepath.Base(shlib.Path)
-			addgostring(ctxt, ldr, modulehashes, fmt.Sprintf("go.link.libname.%d", i), modulename)
+			addgostring(ctxt, ldr, modulehashes, fmt.Sprintf("go:link.libname.%d", i), modulename)
 
 			// modulehashes[i].linktimehash
-			addgostring(ctxt, ldr, modulehashes, fmt.Sprintf("go.link.linkhash.%d", i), string(shlib.Hash))
+			addgostring(ctxt, ldr, modulehashes, fmt.Sprintf("go:link.linkhash.%d", i), string(shlib.Hash))
 
 			// modulehashes[i].runtimehash
-			abihash := ldr.LookupOrCreateSym("go.link.abihash."+modulename, 0)
+			abihash := ldr.LookupOrCreateSym("go:link.abihash."+modulename, 0)
 			ldr.SetAttrReachable(abihash, true)
 			modulehashes.AddAddr(ctxt.Arch, abihash)
 		}
@@ -807,7 +815,7 @@
 	// When linking an object that does not contain the runtime we are
 	// creating the moduledata from scratch and it does not have a
 	// compiler-provided size, so read it from the type data.
-	moduledatatype := ldr.Lookup("type.runtime.moduledata", 0)
+	moduledatatype := ldr.Lookup("type:runtime.moduledata", 0)
 	moduledata.SetSize(decodetypeSize(ctxt.Arch, ldr.Data(moduledatatype)))
 	moduledata.Grow(moduledata.Size())
 
@@ -873,7 +881,7 @@
 	// except symbols that are exported to C. Type symbols are always
 	// ABIInternal so they are not mangled.
 	if ctxt.IsShared() {
-		if ldr.SymType(x) == sym.STEXT && ldr.SymVersion(x) == sym.SymVerABIInternal && !ldr.AttrCgoExport(x) && !strings.HasPrefix(name, "type.") {
+		if ldr.SymType(x) == sym.STEXT && ldr.SymVersion(x) == sym.SymVerABIInternal && !ldr.AttrCgoExport(x) && !strings.HasPrefix(name, "type:") {
 			name = fmt.Sprintf("%s.abiinternal", name)
 		}
 	}
diff --git a/src/cmd/link/internal/ld/target.go b/src/cmd/link/internal/ld/target.go
index cc8e418..d0ce99f 100644
--- a/src/cmd/link/internal/ld/target.go
+++ b/src/cmd/link/internal/ld/target.go
@@ -176,6 +176,11 @@
 	return t.HeadType == objabi.Hopenbsd
 }
 
+func (t *Target) IsFreebsd() bool {
+	t.mustSetHeadType()
+	return t.HeadType == objabi.Hfreebsd
+}
+
 func (t *Target) mustSetHeadType() {
 	if t.HeadType == objabi.Hunknown {
 		panic("HeadType is not set")
diff --git a/src/cmd/link/internal/ld/xcoff.go b/src/cmd/link/internal/ld/xcoff.go
index 259db13..1265c45 100644
--- a/src/cmd/link/internal/ld/xcoff.go
+++ b/src/cmd/link/internal/ld/xcoff.go
@@ -6,17 +6,18 @@
 
 import (
 	"bytes"
-	"cmd/internal/objabi"
-	"cmd/link/internal/loader"
-	"cmd/link/internal/sym"
 	"encoding/binary"
 	"fmt"
-	"io/ioutil"
 	"math/bits"
+	"os"
 	"path/filepath"
 	"sort"
 	"strings"
 	"sync"
+
+	"cmd/internal/objabi"
+	"cmd/link/internal/loader"
+	"cmd/link/internal/sym"
 )
 
 // This file handles all algorithms related to XCOFF files generation.
@@ -538,7 +539,7 @@
 }
 
 // Xcoffinit initialised some internal value and setups
-// already known header information
+// already known header information.
 func Xcoffinit(ctxt *Link) {
 	xfile.dynLibraries = make(map[string]int)
 
@@ -598,16 +599,16 @@
 		if !ctxt.DynlinkingGo() {
 			// runtime.types size must be removed, as it's a real symbol.
 			tsize := ldr.SymSize(ldr.Lookup("runtime.types", 0))
-			outerSymSize["type.*"] = size - tsize
+			outerSymSize["type:*"] = size - tsize
 		}
 	case sym.SGOSTRING:
-		outerSymSize["go.string.*"] = size
+		outerSymSize["go:string.*"] = size
 	case sym.SGOFUNC:
 		if !ctxt.DynlinkingGo() {
-			outerSymSize["go.func.*"] = size
+			outerSymSize["go:func.*"] = size
 		}
 	case sym.SGOFUNCRELRO:
-		outerSymSize["go.funcrel.*"] = size
+		outerSymSize["go:funcrel.*"] = size
 	case sym.SGCBITS:
 		outerSymSize["runtime.gcbits.*"] = size
 	case sym.SPCLNTAB:
@@ -871,7 +872,7 @@
 	return syms
 }
 
-// put function used by genasmsym to write symbol table
+// put function used by genasmsym to write symbol table.
 func putaixsym(ctxt *Link, x loader.Sym, t SymbolType) {
 	// All XCOFF symbols generated by this GO symbols
 	// Can be a symbol entry or a auxiliary entry
@@ -893,7 +894,7 @@
 			syms = xfile.writeSymbolFunc(ctxt, x)
 		} else {
 			// Only runtime.text and runtime.etext come through this way
-			if name != "runtime.text" && name != "runtime.etext" && name != "go.buildid" {
+			if name != "runtime.text" && name != "runtime.etext" && name != "go:buildid" {
 				Exitf("putaixsym: unknown text symbol %s", name)
 			}
 			s := &XcoffSymEnt64{
@@ -1117,7 +1118,7 @@
 				putaixsym(ctxt, s, TLSSym)
 			}
 
-		case st == sym.SBSS, st == sym.SNOPTRBSS, st == sym.SLIBFUZZER_8BIT_COUNTER:
+		case st == sym.SBSS, st == sym.SNOPTRBSS, st == sym.SLIBFUZZER_8BIT_COUNTER, st == sym.SCOVERAGE_COUNTER:
 			if ldr.AttrReachable(s) {
 				data := ldr.Data(s)
 				if len(data) > 0 {
@@ -1354,7 +1355,7 @@
 // Currently, this section is created from scratch when assembling the XCOFF file
 // according to information retrieved in xfile object.
 
-// Create loader section and returns its size
+// Create loader section and returns its size.
 func Loaderblk(ctxt *Link, off uint64) {
 	xfile.writeLdrScn(ctxt, off)
 }
@@ -1581,7 +1582,7 @@
 	}
 }
 
-// Generate XCOFF assembly file
+// Generate XCOFF assembly file.
 func asmbXcoff(ctxt *Link) {
 	ctxt.Out.SeekSet(0)
 	fileoff := int64(Segdwarf.Fileoff + Segdwarf.Filelen)
@@ -1805,7 +1806,7 @@
 		buf.Write([]byte(name + "\n"))
 	}
 
-	err := ioutil.WriteFile(fname, buf.Bytes(), 0666)
+	err := os.WriteFile(fname, buf.Bytes(), 0666)
 	if err != nil {
 		Errorf(nil, "WriteFile %s failed: %v", fname, err)
 	}
diff --git a/src/cmd/link/internal/loadelf/ldelf.go b/src/cmd/link/internal/loadelf/ldelf.go
index f5b7907..7ac7699 100644
--- a/src/cmd/link/internal/loadelf/ldelf.go
+++ b/src/cmd/link/internal/loadelf/ldelf.go
@@ -634,10 +634,16 @@
 
 		if elf.Machine(elfobj.machine) == elf.EM_PPC64 {
 			flag := int(elfsym.other) >> 5
-			if 2 <= flag && flag <= 6 {
-				l.SetSymLocalentry(s, 1<<uint(flag-2))
-			} else if flag == 7 {
+			switch flag {
+			case 0:
+				// No local entry. R2 is preserved.
+			case 1:
+				// These require R2 be saved and restored by the caller. This isn't supported today.
+				return errorf("%s: unable to handle local entry type 1", sb.Name())
+			case 7:
 				return errorf("%s: invalid sym.other 0x%x", sb.Name(), elfsym.other)
+			default:
+				l.SetSymLocalentry(s, 4<<uint(flag-2))
 			}
 		}
 	}
@@ -1002,7 +1008,8 @@
 		LOONG64 | uint32(elf.R_LARCH_MARK_LA)<<16,
 		LOONG64 | uint32(elf.R_LARCH_SOP_POP_32_S_0_10_10_16_S2)<<16,
 		LOONG64 | uint32(elf.R_LARCH_64)<<16,
-		LOONG64 | uint32(elf.R_LARCH_MARK_PCREL)<<16:
+		LOONG64 | uint32(elf.R_LARCH_MARK_PCREL)<<16,
+		LOONG64 | uint32(elf.R_LARCH_32_PCREL)<<16:
 		return 4, 4, nil
 
 	case S390X | uint32(elf.R_390_8)<<16:
@@ -1079,8 +1086,16 @@
 		S390X | uint32(elf.R_390_PLT64)<<16:
 		return 8, 8, nil
 
+	case RISCV64 | uint32(elf.R_RISCV_SET6)<<16,
+		RISCV64 | uint32(elf.R_RISCV_SUB6)<<16,
+		RISCV64 | uint32(elf.R_RISCV_SET8)<<16,
+		RISCV64 | uint32(elf.R_RISCV_SUB8)<<16:
+		return 1, 1, nil
+
 	case RISCV64 | uint32(elf.R_RISCV_RVC_BRANCH)<<16,
-		RISCV64 | uint32(elf.R_RISCV_RVC_JUMP)<<16:
+		RISCV64 | uint32(elf.R_RISCV_RVC_JUMP)<<16,
+		RISCV64 | uint32(elf.R_RISCV_SET16)<<16,
+		RISCV64 | uint32(elf.R_RISCV_SUB16)<<16:
 		return 2, 2, nil
 
 	case RISCV64 | uint32(elf.R_RISCV_32)<<16,
@@ -1092,6 +1107,10 @@
 		RISCV64 | uint32(elf.R_RISCV_PCREL_HI20)<<16,
 		RISCV64 | uint32(elf.R_RISCV_PCREL_LO12_I)<<16,
 		RISCV64 | uint32(elf.R_RISCV_PCREL_LO12_S)<<16,
+		RISCV64 | uint32(elf.R_RISCV_ADD32)<<16,
+		RISCV64 | uint32(elf.R_RISCV_SET32)<<16,
+		RISCV64 | uint32(elf.R_RISCV_SUB32)<<16,
+		RISCV64 | uint32(elf.R_RISCV_32_PCREL)<<16,
 		RISCV64 | uint32(elf.R_RISCV_RELAX)<<16:
 		return 4, 4, nil
 
@@ -1107,8 +1126,19 @@
 		PPC64 | uint32(elf.R_PPC64_TOC16_LO_DS)<<16,
 		PPC64 | uint32(elf.R_PPC64_REL16_LO)<<16,
 		PPC64 | uint32(elf.R_PPC64_REL16_HI)<<16,
-		PPC64 | uint32(elf.R_PPC64_REL16_HA)<<16:
+		PPC64 | uint32(elf.R_PPC64_REL16_HA)<<16,
+		PPC64 | uint32(elf.R_PPC64_PLT16_HA)<<16,
+		PPC64 | uint32(elf.R_PPC64_PLT16_LO_DS)<<16:
 		return 2, 4, nil
+
+	// PPC64 inline PLT sequence hint relocations (-fno-plt)
+	// These are informational annotations to assist linker optimizations.
+	case PPC64 | uint32(elf.R_PPC64_PLTSEQ)<<16,
+		PPC64 | uint32(elf.R_PPC64_PLTCALL)<<16,
+		PPC64 | uint32(elf.R_PPC64_PLTCALL_NOTOC)<<16,
+		PPC64 | uint32(elf.R_PPC64_PLTSEQ_NOTOC)<<16:
+		return 0, 0, nil
+
 	}
 }
 
diff --git a/src/cmd/link/internal/loader/loader.go b/src/cmd/link/internal/loader/loader.go
index 0cf9551..8e1575a 100644
--- a/src/cmd/link/internal/loader/loader.go
+++ b/src/cmd/link/internal/loader/loader.go
@@ -14,6 +14,7 @@
 	"cmd/link/internal/sym"
 	"debug/elf"
 	"fmt"
+	"io"
 	"log"
 	"math/bits"
 	"os"
@@ -721,9 +722,9 @@
 	// here is that we get different line numbers on formal
 	// params; I am guessing that the pos is being inherited
 	// from the spot where the wrapper is needed.
-	allowed := strings.HasPrefix(name, "go.info.go.interface") ||
-		strings.HasPrefix(name, "go.info.go.builtin") ||
-		strings.HasPrefix(name, "go.debuglines")
+	allowed := strings.HasPrefix(name, "go:info.go.interface") ||
+		strings.HasPrefix(name, "go:info.go.builtin") ||
+		strings.HasPrefix(name, "go:debuglines")
 	if !allowed {
 		l.strictDupMsgs++
 	}
@@ -1561,13 +1562,12 @@
 	l.symPkg[i] = pkg
 }
 
-// SymLocalentry returns the "local entry" value for the specified
-// symbol.
+// SymLocalentry returns an offset in bytes of the "local entry" of a symbol.
 func (l *Loader) SymLocalentry(i Sym) uint8 {
 	return l.localentry[i]
 }
 
-// SetSymLocalentry sets the "local entry" attribute for a symbol.
+// SetSymLocalentry sets the "local entry" offset attribute for a symbol.
 func (l *Loader) SetSymLocalentry(i Sym, value uint8) {
 	// reject bad symbols
 	if i >= Sym(len(l.objSyms)) || i == 0 {
@@ -1610,13 +1610,8 @@
 	if l.SymType(fnSymIdx) != sym.STEXT {
 		log.Fatalf("error: non-function sym %d/%s t=%s passed to GetFuncDwarfAuxSyms", fnSymIdx, l.SymName(fnSymIdx), l.SymType(fnSymIdx).String())
 	}
-	if l.IsExternal(fnSymIdx) {
-		// Current expectation is that any external function will
-		// not have auxsyms.
-		return
-	}
-	r, li := l.toLocal(fnSymIdx)
-	auxs := r.Auxs(li)
+	r, auxs := l.auxs(fnSymIdx)
+
 	for i := range auxs {
 		a := &auxs[i]
 		switch a.Type() {
@@ -1703,7 +1698,7 @@
 // SubSym gets the subsymbol for host object loaded symbols.
 func (l *Loader) SubSym(i Sym) Sym {
 	// NB: note -- no check for l.isExternal(), since I am pretty sure
-	// that later phases in the linker set subsym for "type." syms
+	// that later phases in the linker set subsym for "type:" syms
 	return l.sub[i]
 }
 
@@ -1716,7 +1711,7 @@
 // emits named string symbols (type SGOSTRING) when compiling a
 // package; after being deduplicated, these symbols are collected into
 // a single unit by assigning them a new carrier symbol named
-// "go.string.*" (which appears in the final symbol table for the
+// "go:string.*" (which appears in the final symbol table for the
 // output load module).
 func (l *Loader) SetCarrierSym(s Sym, c Sym) {
 	if c == 0 {
@@ -1963,6 +1958,10 @@
 	return (*goobj.FuncInfo)(nil).ReadFuncFlag(fi.data)
 }
 
+func (fi *FuncInfo) StartLine() int32 {
+	return (*goobj.FuncInfo)(nil).ReadStartLine(fi.data)
+}
+
 // Preload has to be called prior to invoking the various methods
 // below related to pcdata, funcdataoff, files, and inltree nodes.
 func (fi *FuncInfo) Preload() {
@@ -2081,7 +2080,7 @@
 	l.addObj(lib.Pkg, or)
 
 	// The caller expects us consuming all the data
-	f.MustSeek(length, os.SEEK_CUR)
+	f.MustSeek(length, io.SeekCurrent)
 
 	return r.Fingerprint()
 }
@@ -2132,7 +2131,7 @@
 			l.SetAttrUsedInIface(gi, true)
 		}
 		if strings.HasPrefix(name, "runtime.") ||
-			(loadingRuntimePkg && strings.HasPrefix(name, "type.")) {
+			(loadingRuntimePkg && strings.HasPrefix(name, "type:")) {
 			if bi := goobj.BuiltinIdx(name, int(osym.ABI())); bi != -1 {
 				// This is a definition of a builtin symbol. Record where it is.
 				l.builtinSyms[bi] = gi
@@ -2393,12 +2392,15 @@
 // space, looking for symbols with relocations targeting undefined
 // references. The linker's loadlib method uses this to determine if
 // there are unresolved references to functions in system libraries
-// (for example, libgcc.a), presumably due to CGO code. Return
-// value is a list of loader.Sym's corresponding to the undefined
-// cross-refs. The "limit" param controls the maximum number of
-// results returned; if "limit" is -1, then all undefs are returned.
-func (l *Loader) UndefinedRelocTargets(limit int) []Sym {
-	result := []Sym{}
+// (for example, libgcc.a), presumably due to CGO code. Return value
+// is a pair of lists of loader.Sym's. First list corresponds to the
+// corresponding to the undefined symbols themselves, the second list
+// is the symbol that is making a reference to the undef. The "limit"
+// param controls the maximum number of results returned; if "limit"
+// is -1, then all undefs are returned.
+func (l *Loader) UndefinedRelocTargets(limit int) ([]Sym, []Sym) {
+	result, fromr := []Sym{}, []Sym{}
+outerloop:
 	for si := Sym(1); si < Sym(len(l.objSyms)); si++ {
 		relocs := l.Relocs(si)
 		for ri := 0; ri < relocs.Count(); ri++ {
@@ -2406,13 +2408,14 @@
 			rs := r.Sym()
 			if rs != 0 && l.SymType(rs) == sym.SXREF && l.SymName(rs) != ".got" {
 				result = append(result, rs)
+				fromr = append(fromr, si)
 				if limit != -1 && len(result) >= limit {
-					break
+					break outerloop
 				}
 			}
 		}
 	}
-	return result
+	return result, fromr
 }
 
 // AssignTextSymbolOrder populates the Textp slices within each
diff --git a/src/cmd/link/internal/loader/loader_test.go b/src/cmd/link/internal/loader/loader_test.go
index b22e213..7d1031e 100644
--- a/src/cmd/link/internal/loader/loader_test.go
+++ b/src/cmd/link/internal/loader/loader_test.go
@@ -39,9 +39,9 @@
 	or := &dummyOreader
 
 	// Create some syms from a dummy object file symbol to get things going.
-	ts1 := addDummyObjSym(t, ldr, or, "type.uint8")
+	ts1 := addDummyObjSym(t, ldr, or, "type:uint8")
 	ts2 := addDummyObjSym(t, ldr, or, "mumble")
-	ts3 := addDummyObjSym(t, ldr, or, "type.string")
+	ts3 := addDummyObjSym(t, ldr, or, "type:string")
 
 	// Create some external symbols.
 	es1 := ldr.LookupOrCreateSym("extnew1", 0)
@@ -52,7 +52,7 @@
 	if es1x != es1 {
 		t.Fatalf("LookupOrCreateSym lookup: expected %d got %d for second lookup", es1, es1x)
 	}
-	es2 := ldr.LookupOrCreateSym("go.info.type.uint8", 0)
+	es2 := ldr.LookupOrCreateSym("go:info.type.uint8", 0)
 	if es2 == 0 {
 		t.Fatalf("LookupOrCreateSym failed for go.info.type.uint8")
 	}
@@ -252,7 +252,7 @@
 	or := &dummyOreader
 
 	// Populate loader with some symbols.
-	addDummyObjSym(t, ldr, or, "type.uint8")
+	addDummyObjSym(t, ldr, or, "type:uint8")
 	ldr.LookupOrCreateSym("hello", 0)
 
 	arch := sys.ArchAMD64
@@ -371,7 +371,7 @@
 	or := &dummyOreader
 
 	// Populate loader with some symbols.
-	addDummyObjSym(t, ldr, or, "type.uint8")
+	addDummyObjSym(t, ldr, or, "type:uint8")
 	es1 := ldr.LookupOrCreateSym("outer", 0)
 	ldr.MakeSymbolUpdater(es1).SetSize(101)
 	es2 := ldr.LookupOrCreateSym("sub1", 0)
diff --git a/src/cmd/link/internal/loadpe/ldpe.go b/src/cmd/link/internal/loadpe/ldpe.go
index bc66252..0d33823 100644
--- a/src/cmd/link/internal/loadpe/ldpe.go
+++ b/src/cmd/link/internal/loadpe/ldpe.go
@@ -135,6 +135,19 @@
 	IMAGE_REL_ARM64_REL32            = 0x0011
 )
 
+const (
+	// When stored into the PLT value for a symbol, this token tells
+	// windynrelocsym to redirect direct references to this symbol to a stub
+	// that loads from the corresponding import symbol and then does
+	// a jump to the loaded value.
+	CreateImportStubPltToken = -2
+
+	// When stored into the GOT value for a import symbol __imp_X this
+	// token tells windynrelocsym to redirect references to the
+	// underlying DYNIMPORT symbol X.
+	RedirectToDynImportGotToken = -2
+)
+
 // TODO(brainman): maybe just add ReadAt method to bio.Reader instead of creating peBiobuf
 
 // peBiobuf makes bio.Reader look like io.ReaderAt.
@@ -162,15 +175,43 @@
 	return bld
 }
 
+// peImportSymsState tracks the set of DLL import symbols we've seen
+// while reading host objects. We create a singleton instance of this
+// type, which will persist across multiple host objects.
+type peImportSymsState struct {
+
+	// Text and non-text sections read in by the host object loader.
+	secSyms []loader.Sym
+
+	// SDYNIMPORT symbols encountered along the way
+	dynimports map[loader.Sym]struct{}
+
+	// Loader and arch, for use in postprocessing.
+	l    *loader.Loader
+	arch *sys.Arch
+}
+
+var importSymsState *peImportSymsState
+
+func createImportSymsState(l *loader.Loader, arch *sys.Arch) {
+	if importSymsState != nil {
+		return
+	}
+	importSymsState = &peImportSymsState{
+		dynimports: make(map[loader.Sym]struct{}),
+		l:          l,
+		arch:       arch,
+	}
+}
+
 // peLoaderState holds various bits of useful state information needed
-// while loading a PE object file.
+// while loading a single PE object file.
 type peLoaderState struct {
 	l               *loader.Loader
 	arch            *sys.Arch
 	f               *pe.File
 	pn              string
 	sectsyms        map[*pe.Section]loader.Sym
-	defWithImp      map[string]struct{}
 	comdats         map[uint16]int64 // key is section index, val is size
 	sectdata        map[*pe.Section][]byte
 	localSymVersion int
@@ -182,7 +223,8 @@
 var comdatDefinitions = make(map[string]int64)
 
 // Load loads the PE file pn from input.
-// Symbols are written into syms, and a slice of the text symbols is returned.
+// Symbols from the object file are created via the loader 'l', and
+// and a slice of the text symbols is returned.
 // If an .rsrc section or set of .rsrc$xx sections is found, its symbols are
 // returned as rsrc.
 func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Reader, pkg string, length int64, pn string) (textp []loader.Sym, rsrc []loader.Sym, err error) {
@@ -194,6 +236,7 @@
 		localSymVersion: localSymVersion,
 		pn:              pn,
 	}
+	createImportSymsState(state.l, state.arch)
 
 	// Some input files are archives containing multiple of
 	// object files, and pe.NewFile seeks to the start of
@@ -259,9 +302,7 @@
 		}
 	}
 
-	// Make a prepass over the symbols to detect situations where
-	// we have both a defined symbol X and an import symbol __imp_X
-	// (needed by readpesym()).
+	// Make a prepass over the symbols to collect info about COMDAT symbols.
 	if err := state.preprocessSymbols(); err != nil {
 		return nil, nil, err
 	}
@@ -438,10 +479,6 @@
 		}
 
 		if pesym.SectionNumber == 0 { // extern
-			if l.SymType(s) == sym.SDYNIMPORT {
-				bld = makeUpdater(l, bld, s)
-				bld.SetPlt(-2) // flag for dynimport in PE object files.
-			}
 			if l.SymType(s) == sym.SXREF && pesym.Value > 0 { // global data
 				bld = makeUpdater(l, bld, s)
 				bld.SetType(sym.SNOPTRDATA)
@@ -511,6 +548,7 @@
 			continue
 		}
 		l.SortSub(s)
+		importSymsState.secSyms = append(importSymsState.secSyms, s)
 		if l.SymType(s) == sym.STEXT {
 			for ; s != 0; s = l.SubSym(s) {
 				if l.AttrOnList(s) {
@@ -525,6 +563,84 @@
 	return textp, rsrc, nil
 }
 
+// PostProcessImports works to resolve inconsistencies with DLL import
+// symbols; it is needed when building with more "modern" C compilers
+// with internal linkage.
+//
+// Background: DLL import symbols are data (SNOPTRDATA) symbols whose
+// name is of the form "__imp_XXX", which contain a pointer/reference
+// to symbol XXX. It's possible to have import symbols for both data
+// symbols ("__imp__fmode") and text symbols ("__imp_CreateEventA").
+// In some case import symbols are just references to some external
+// thing, and in other cases we see actual definitions of import
+// symbols when reading host objects.
+//
+// Previous versions of the linker would in most cases immediately
+// "forward" import symbol references, e.g. treat a references to
+// "__imp_XXX" a references to "XXX", however this doesn't work well
+// with more modern compilers, where you can sometimes see import
+// symbols that are defs (as opposed to external refs).
+//
+// The main actions taken below are to search for references to
+// SDYNIMPORT symbols in host object text/data sections and flag the
+// symbols for later fixup. When we see a reference to an import
+// symbol __imp_XYZ where XYZ corresponds to some SDYNIMPORT symbol,
+// we flag the symbol (via GOT setting) so that it can be redirected
+// to XYZ later in windynrelocsym. When we see a direct reference to
+// an SDYNIMPORT symbol XYZ, we also flag the symbol (via PLT setting)
+// to indicated that the reference will need to be redirected to a
+// stub.
+func PostProcessImports() error {
+	ldr := importSymsState.l
+	arch := importSymsState.arch
+	keeprelocneeded := make(map[loader.Sym]loader.Sym)
+	for _, s := range importSymsState.secSyms {
+		isText := ldr.SymType(s) == sym.STEXT
+		relocs := ldr.Relocs(s)
+		for i := 0; i < relocs.Count(); i++ {
+			r := relocs.At(i)
+			rs := r.Sym()
+			if ldr.SymType(rs) == sym.SDYNIMPORT {
+				// Tag the symbol for later stub generation.
+				ldr.SetPlt(rs, CreateImportStubPltToken)
+				continue
+			}
+			isym, err := LookupBaseFromImport(rs, ldr, arch)
+			if err != nil {
+				return err
+			}
+			if isym == 0 {
+				continue
+			}
+			if ldr.SymType(isym) != sym.SDYNIMPORT {
+				continue
+			}
+			// For non-text symbols, forward the reference from __imp_X to
+			// X immediately.
+			if !isText {
+				r.SetSym(isym)
+				continue
+			}
+			// Flag this imp symbol to be processed later in windynrelocsym.
+			ldr.SetGot(rs, RedirectToDynImportGotToken)
+			// Consistency check: should be no PLT token here.
+			splt := ldr.SymPlt(rs)
+			if splt != -1 {
+				return fmt.Errorf("internal error: import symbol %q has invalid PLT setting %d", ldr.SymName(rs), splt)
+			}
+			// Flag for dummy relocation.
+			keeprelocneeded[rs] = isym
+		}
+	}
+	for k, v := range keeprelocneeded {
+		sb := ldr.MakeSymbolUpdater(k)
+		r, _ := sb.AddRel(objabi.R_KEEP)
+		r.SetSym(v)
+	}
+	importSymsState = nil
+	return nil
+}
+
 func issect(s *pe.COFFSymbol) bool {
 	return s.StorageClass == IMAGE_SYM_CLASS_STATIC && s.Type == 0 && s.Name[0] == '.'
 }
@@ -539,25 +655,13 @@
 		name = state.l.SymName(state.sectsyms[state.f.Sections[pesym.SectionNumber-1]])
 	} else {
 		name = symname
-		if strings.HasPrefix(symname, "__imp_") {
-			orig := symname[len("__imp_"):]
-			if _, ok := state.defWithImp[orig]; ok {
-				// Don't rename __imp_XXX to XXX, since if we do this
-				// we'll wind up with a duplicate definition. One
-				// example is "__acrt_iob_func"; see commit b295099
-				// from git://git.code.sf.net/p/mingw-w64/mingw-w64
-				// for details.
-			} else {
-				name = strings.TrimPrefix(name, "__imp_") // __imp_Name => Name
-			}
-		}
 		// A note on the "_main" exclusion below: the main routine
 		// defined by the Go runtime is named "_main", not "main", so
 		// when reading references to _main from a host object we want
 		// to avoid rewriting "_main" to "main" in this specific
 		// instance. See #issuecomment-1143698749 on #35006 for more
 		// details on this problem.
-		if state.arch.Family == sys.I386 && name[0] == '_' && name != "_main" {
+		if state.arch.Family == sys.I386 && name[0] == '_' && name != "_main" && !strings.HasPrefix(name, "__imp_") {
 			name = name[1:] // _Name => Name
 		}
 	}
@@ -592,10 +696,6 @@
 		bld = makeUpdater(state.l, bld, s)
 		bld.SetType(sym.SXREF)
 	}
-	if strings.HasPrefix(symname, "__imp_") {
-		bld = makeUpdater(state.l, bld, s)
-		bld.SetGot(-2) // flag for __imp_
-	}
 
 	return bld, s, nil
 }
@@ -618,8 +718,6 @@
 	}
 
 	// Examine symbol defs.
-	imp := make(map[string]struct{})
-	def := make(map[string]struct{})
 	for i, numaux := 0, 0; i < len(state.f.COFFSymbols); i += numaux + 1 {
 		pesym := &state.f.COFFSymbols[i]
 		numaux = int(pesym.NumberOfAuxSymbols)
@@ -630,10 +728,6 @@
 		if err != nil {
 			return err
 		}
-		def[symname] = struct{}{}
-		if strings.HasPrefix(symname, "__imp_") {
-			imp[strings.TrimPrefix(symname, "__imp_")] = struct{}{}
-		}
 		if _, isc := state.comdats[uint16(pesym.SectionNumber-1)]; !isc {
 			continue
 		}
@@ -658,11 +752,26 @@
 			return fmt.Errorf("internal error: unsupported COMDAT selection strategy found in path=%s sec=%d strategy=%d idx=%d, please file a bug", state.pn, auxsymp.SecNum, auxsymp.Selection, i)
 		}
 	}
-	state.defWithImp = make(map[string]struct{})
-	for n := range imp {
-		if _, ok := def[n]; ok {
-			state.defWithImp[n] = struct{}{}
-		}
-	}
 	return nil
 }
+
+// LookupBaseFromImport examines the symbol "s" to see if it
+// corresponds to an import symbol (name of the form "__imp_XYZ") and
+// if so, it looks up the underlying target of the import symbol and
+// returns it. An error is returned if the symbol is of the form
+// "__imp_XYZ" but no XYZ can be found.
+func LookupBaseFromImport(s loader.Sym, ldr *loader.Loader, arch *sys.Arch) (loader.Sym, error) {
+	sname := ldr.SymName(s)
+	if !strings.HasPrefix(sname, "__imp_") {
+		return 0, nil
+	}
+	basename := sname[len("__imp_"):]
+	if arch.Family == sys.I386 && basename[0] == '_' {
+		basename = basename[1:] // _Name => Name
+	}
+	isym := ldr.Lookup(basename, 0)
+	if isym == 0 {
+		return 0, fmt.Errorf("internal error: import symbol %q with no underlying sym", sname)
+	}
+	return isym, nil
+}
diff --git a/src/cmd/link/internal/loong64/obj.go b/src/cmd/link/internal/loong64/obj.go
index b564dfd..0a5bb0a 100644
--- a/src/cmd/link/internal/loong64/obj.go
+++ b/src/cmd/link/internal/loong64/obj.go
@@ -31,6 +31,7 @@
 		Gentext:          gentext,
 
 		Linuxdynld:     "/lib64/ld.so.1",
+		LinuxdynldMusl: "/lib64/ld-musl-loongarch.so.1",
 		Freebsddynld:   "XXX",
 		Openbsddynld:   "XXX",
 		Netbsddynld:    "XXX",
diff --git a/src/cmd/link/internal/mips/obj.go b/src/cmd/link/internal/mips/obj.go
index 5ca7582..f03c9ab 100644
--- a/src/cmd/link/internal/mips/obj.go
+++ b/src/cmd/link/internal/mips/obj.go
@@ -39,8 +39,10 @@
 
 func Init() (*sys.Arch, ld.Arch) {
 	arch := sys.ArchMIPS
+	musl := "/lib/ld-musl-mips.so.1"
 	if buildcfg.GOARCH == "mipsle" {
 		arch = sys.ArchMIPSLE
+		musl = "/lib/ld-musl-mipsel.so.1"
 	}
 
 	theArch := ld.Arch{
@@ -60,7 +62,8 @@
 		Gentext:          gentext,
 		Machoreloc1:      machoreloc1,
 
-		Linuxdynld: "/lib/ld.so.1",
+		Linuxdynld:     "/lib/ld.so.1",
+		LinuxdynldMusl: musl,
 
 		Freebsddynld:   "XXX",
 		Openbsddynld:   "XXX",
diff --git a/src/cmd/link/internal/mips64/obj.go b/src/cmd/link/internal/mips64/obj.go
index 544e1ef..557d799 100644
--- a/src/cmd/link/internal/mips64/obj.go
+++ b/src/cmd/link/internal/mips64/obj.go
@@ -39,8 +39,10 @@
 
 func Init() (*sys.Arch, ld.Arch) {
 	arch := sys.ArchMIPS64
+	musl := "/lib/ld-musl-mips64.so.1"
 	if buildcfg.GOARCH == "mips64le" {
 		arch = sys.ArchMIPS64LE
+		musl = "/lib/ld-musl-mips64el.so.1"
 	}
 
 	theArch := ld.Arch{
@@ -60,6 +62,7 @@
 		Machoreloc1:      machoreloc1,
 
 		Linuxdynld:     "/lib64/ld64.so.1",
+		LinuxdynldMusl: musl,
 		Freebsddynld:   "XXX",
 		Openbsddynld:   "/usr/libexec/ld.so",
 		Netbsddynld:    "XXX",
diff --git a/src/cmd/link/internal/ppc64/asm.go b/src/cmd/link/internal/ppc64/asm.go
index 5d5fbe2..7413599 100644
--- a/src/cmd/link/internal/ppc64/asm.go
+++ b/src/cmd/link/internal/ppc64/asm.go
@@ -133,17 +133,19 @@
 	return stub.Sym(), firstUse
 }
 
-// Scan relocs and generate PLT stubs and generate/fixup ABI defined functions created by the linker
+// Scan relocs and generate PLT stubs and generate/fixup ABI defined functions created by the linker.
 func genstubs(ctxt *ld.Link, ldr *loader.Loader) {
 	var stubs []loader.Sym
 	var abifuncs []loader.Sym
 	for _, s := range ctxt.Textp {
 		relocs := ldr.Relocs(s)
 		for i := 0; i < relocs.Count(); i++ {
-			if r := relocs.At(i); r.Type() == objabi.ElfRelocOffset+objabi.RelocType(elf.R_PPC64_REL24) {
+			r := relocs.At(i)
+			switch r.Type() {
+			case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_REL24):
 				switch ldr.SymType(r.Sym()) {
 				case sym.SDYNIMPORT:
-					// This call goes throught the PLT, generate and call through a PLT stub.
+					// This call goes through the PLT, generate and call through a PLT stub.
 					if sym, firstUse := genpltstub(ctxt, ldr, r, s); firstUse {
 						stubs = append(stubs, sym)
 					}
@@ -159,6 +161,34 @@
 						}
 					}
 				}
+
+			// Handle objects compiled with -fno-plt. Rewrite local calls to avoid indirect calling.
+			// These are 0 sized relocs. They mark the mtctr r12, or bctrl + ld r2,24(r1).
+			case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_PLTSEQ):
+				if ldr.SymType(r.Sym()) == sym.STEXT {
+					// This should be an mtctr instruction. Turn it into a nop.
+					su := ldr.MakeSymbolUpdater(s)
+					const OP_MTCTR = 31<<26 | 0x9<<16 | 467<<1
+					const MASK_OP_MTCTR = 63<<26 | 0x3FF<<11 | 0x1FF<<1
+					rewritetonop(&ctxt.Target, ldr, su, int64(r.Off()), MASK_OP_MTCTR, OP_MTCTR)
+				}
+			case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_PLTCALL):
+				if ldr.SymType(r.Sym()) == sym.STEXT {
+					// This relocation should point to a bctrl followed by a ld r2, 24(41)
+					const OP_BL = 0x48000001         // bl 0
+					const OP_TOCRESTORE = 0xe8410018 // ld r2,24(r1)
+					const OP_BCTRL = 0x4e800421      // bctrl
+
+					// Convert the bctrl into a bl.
+					su := ldr.MakeSymbolUpdater(s)
+					rewritetoinsn(&ctxt.Target, ldr, su, int64(r.Off()), 0xFFFFFFFF, OP_BCTRL, OP_BL)
+
+					// Turn this reloc into an R_CALLPOWER, and convert the TOC restore into a nop.
+					su.SetRelocType(i, objabi.R_CALLPOWER)
+					su.SetRelocAdd(i, r.Add()+int64(ldr.SymLocalentry(r.Sym())))
+					r.SetSiz(4)
+					rewritetonop(&ctxt.Target, ldr, su, int64(r.Off()+4), 0xFFFFFFFF, OP_TOCRESTORE)
+				}
 			}
 		}
 	}
@@ -347,6 +377,24 @@
 	stub.AddUint32(ctxt.Arch, 0x4e800420) // bctr
 }
 
+// Rewrite the instruction at offset into newinsn. Also, verify the
+// existing instruction under mask matches the check value.
+func rewritetoinsn(target *ld.Target, ldr *loader.Loader, su *loader.SymbolBuilder, offset int64, mask, check, newinsn uint32) {
+	su.MakeWritable()
+	op := target.Arch.ByteOrder.Uint32(su.Data()[offset:])
+	if op&mask != check {
+		ldr.Errorf(su.Sym(), "Rewrite offset 0x%x to 0x%08X failed check (0x%08X&0x%08X != 0x%08X)", offset, newinsn, op, mask, check)
+	}
+	su.SetUint32(target.Arch, offset, newinsn)
+}
+
+// Rewrite the instruction at offset into a hardware nop instruction. Also, verify the
+// existing instruction under mask matches the check value.
+func rewritetonop(target *ld.Target, ldr *loader.Loader, su *loader.SymbolBuilder, offset int64, mask, check uint32) {
+	const NOP = 0x60000000
+	rewritetoinsn(target, ldr, su, offset, mask, check, NOP)
+}
+
 func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym, r loader.Reloc, rIdx int) bool {
 	if target.IsElf() {
 		return addelfdynrel(target, ldr, syms, s, r, rIdx)
@@ -380,7 +428,7 @@
 		// callee. Hence, we need to go to the local entry
 		// point.  (If we don't do this, the callee will try
 		// to use r12 to compute r2.)
-		su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymLocalentry(targ))*4)
+		su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymLocalentry(targ)))
 
 		if targType == sym.SDYNIMPORT {
 			// Should have been handled in elfsetupplt
@@ -476,6 +524,51 @@
 		ldr.SetRelocVariant(s, rIdx, sym.RV_POWER_HA|sym.RV_CHECK_OVERFLOW)
 		su.SetRelocAdd(rIdx, r.Add()+2)
 		return true
+
+	// When compiling with gcc's -fno-plt option (no PLT), the following code and relocation
+	// sequences may be present to call an external function:
+	//
+	//   1. addis Rx,foo@R_PPC64_PLT16_HA
+	//   2. ld 12,foo@R_PPC64_PLT16_LO_DS(Rx)
+	//   3. mtctr 12 ; foo@R_PPC64_PLTSEQ
+	//   4. bctrl ; foo@R_PPC64_PLTCALL
+	//   5. ld r2,24(r1)
+	//
+	// Note, 5 is required to follow the R_PPC64_PLTCALL. Similarly, relocations targeting
+	// instructions 3 and 4 are zero sized informational relocations.
+	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_PLT16_HA),
+		objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_PLT16_LO_DS):
+		su := ldr.MakeSymbolUpdater(s)
+		isPLT16_LO_DS := r.Type() == objabi.ElfRelocOffset+objabi.RelocType(elf.R_PPC64_PLT16_LO_DS)
+		if isPLT16_LO_DS {
+			ldr.SetRelocVariant(s, rIdx, sym.RV_POWER_DS)
+		} else {
+			ldr.SetRelocVariant(s, rIdx, sym.RV_POWER_HA|sym.RV_CHECK_OVERFLOW)
+		}
+		su.SetRelocType(rIdx, objabi.R_POWER_TOC)
+		if targType == sym.SDYNIMPORT {
+			// This is an external symbol, make space in the GOT and retarget the reloc.
+			ld.AddGotSym(target, ldr, syms, targ, uint32(elf.R_PPC64_GLOB_DAT))
+			su.SetRelocSym(rIdx, syms.GOT)
+			su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymGot(targ)))
+		} else if targType == sym.STEXT {
+			if isPLT16_LO_DS {
+				// Expect an ld opcode to nop
+				const MASK_OP_LD = 63<<26 | 0x3
+				const OP_LD = 58 << 26
+				rewritetonop(target, ldr, su, int64(r.Off()), MASK_OP_LD, OP_LD)
+			} else {
+				// Expect an addis opcode to nop
+				const MASK_OP_ADDIS = 63 << 26
+				const OP_ADDIS = 15 << 26
+				rewritetonop(target, ldr, su, int64(r.Off()), MASK_OP_ADDIS, OP_ADDIS)
+			}
+			// And we can ignore this reloc now.
+			su.SetRelocType(rIdx, objabi.ElfRelocOffset)
+		} else {
+			ldr.Errorf(s, "unexpected PLT relocation target symbol type %s", targType.String())
+		}
+		return true
 	}
 
 	// Handle references to ELF symbols from our own object files.
@@ -634,6 +727,10 @@
 		default:
 			return false
 		}
+	case objabi.R_ADDRPOWER_D34:
+		out.Write64(uint64(elf.R_PPC64_D34) | uint64(elfsym)<<32)
+	case objabi.R_ADDRPOWER_PCREL34:
+		out.Write64(uint64(elf.R_PPC64_PCREL34) | uint64(elfsym)<<32)
 	case objabi.R_POWER_TLS:
 		out.Write64(uint64(elf.R_PPC64_TLS) | uint64(elfsym)<<32)
 	case objabi.R_POWER_TLS_LE:
@@ -641,6 +738,10 @@
 		out.Write64(uint64(r.Xadd))
 		out.Write64(uint64(sectoff + 4))
 		out.Write64(uint64(elf.R_PPC64_TPREL16_LO) | uint64(elfsym)<<32)
+	case objabi.R_POWER_TLS_LE_TPREL34:
+		out.Write64(uint64(elf.R_PPC64_TPREL34) | uint64(elfsym)<<32)
+	case objabi.R_POWER_TLS_IE_PCREL34:
+		out.Write64(uint64(elf.R_PPC64_GOT_TPREL_PCREL34) | uint64(elfsym)<<32)
 	case objabi.R_POWER_TLS_IE:
 		out.Write64(uint64(elf.R_PPC64_GOT_TPREL16_HA) | uint64(elfsym)<<32)
 		out.Write64(uint64(r.Xadd))
@@ -795,51 +896,44 @@
 	if target.IsAIX() {
 		ldr.Errorf(s, "archrelocaddr called for %s relocation\n", ldr.SymName(rs))
 	}
-	var o1, o2 uint32
-	if target.IsBigEndian() {
-		o1 = uint32(val >> 32)
-		o2 = uint32(val)
-	} else {
-		o1 = uint32(val)
-		o2 = uint32(val >> 32)
-	}
+	o1, o2 := unpackInstPair(target, val)
 
-	// We are spreading a 31-bit address across two instructions, putting the
-	// high (adjusted) part in the low 16 bits of the first instruction and the
-	// low part in the low 16 bits of the second instruction, or, in the DS case,
-	// bits 15-2 (inclusive) of the address into bits 15-2 of the second
-	// instruction (it is an error in this case if the low 2 bits of the address
-	// are non-zero).
-
+	// Verify resulting address fits within a 31 bit (2GB) address space.
+	// This is a restriction arising  from the usage of lis (HA) + d-form
+	// (LO) instruction sequences used to implement absolute relocations
+	// on PPC64 prior to ISA 3.1 (P10). For consistency, maintain this
+	// restriction for ISA 3.1 unless it becomes problematic.
 	t := ldr.SymAddr(rs) + r.Add()
 	if t < 0 || t >= 1<<31 {
 		ldr.Errorf(s, "relocation for %s is too big (>=2G): 0x%x", ldr.SymName(s), ldr.SymValue(rs))
 	}
-	if t&0x8000 != 0 {
-		t += 0x10000
-	}
 
 	switch r.Type() {
+	case objabi.R_ADDRPOWER_PCREL34:
+		// S + A - P
+		t -= (ldr.SymValue(s) + int64(r.Off()))
+		o1 |= computePrefix34HI(t)
+		o2 |= computeLO(int32(t))
+	case objabi.R_ADDRPOWER_D34:
+		o1 |= computePrefix34HI(t)
+		o2 |= computeLO(int32(t))
 	case objabi.R_ADDRPOWER:
-		o1 |= (uint32(t) >> 16) & 0xffff
-		o2 |= uint32(t) & 0xffff
+		o1 |= computeHA(int32(t))
+		o2 |= computeLO(int32(t))
 	case objabi.R_ADDRPOWER_DS:
-		o1 |= (uint32(t) >> 16) & 0xffff
+		o1 |= computeHA(int32(t))
+		o2 |= computeLO(int32(t))
 		if t&3 != 0 {
 			ldr.Errorf(s, "bad DS reloc for %s: %d", ldr.SymName(s), ldr.SymValue(rs))
 		}
-		o2 |= uint32(t) & 0xfffc
 	default:
 		return -1
 	}
 
-	if target.IsBigEndian() {
-		return int64(o1)<<32 | int64(o2)
-	}
-	return int64(o2)<<32 | int64(o1)
+	return packInstPair(target, o1, o2)
 }
 
-// Determine if the code was compiled so that the TOC register R2 is initialized and maintained
+// Determine if the code was compiled so that the TOC register R2 is initialized and maintained.
 func r2Valid(ctxt *ld.Link) bool {
 	switch ctxt.BuildMode {
 	case ld.BuildModeCArchive, ld.BuildModeCShared, ld.BuildModePIE, ld.BuildModeShared, ld.BuildModePlugin:
@@ -849,7 +943,7 @@
 	return ctxt.IsSharedGoLink()
 }
 
-// resolve direct jump relocation r in s, and add trampoline if necessary
+// resolve direct jump relocation r in s, and add trampoline if necessary.
 func trampoline(ctxt *ld.Link, ldr *loader.Loader, ri int, rs, s loader.Sym) {
 
 	// Trampolines are created if the branch offset is too large and the linker cannot insert a call stub to handle it.
@@ -900,8 +994,9 @@
 				if ldr.SymValue(tramp) == 0 {
 					break
 				}
-
-				t = ldr.SymValue(tramp) + r.Add() - (ldr.SymValue(s) + int64(r.Off()))
+				// Note, the trampoline is always called directly. The addend of the original relocation is accounted for in the
+				// trampoline itself.
+				t = ldr.SymValue(tramp) - (ldr.SymValue(s) + int64(r.Off()))
 
 				// With internal linking, the trampoline can be used if it is not too far.
 				// With external linking, the trampoline must be in this section for it to be reused.
@@ -991,6 +1086,61 @@
 	tramp.SetData(P)
 }
 
+// Unpack a pair of 32 bit instruction words from
+// a 64 bit relocation into instN and instN+1 in endian order.
+func unpackInstPair(target *ld.Target, r int64) (uint32, uint32) {
+	if target.IsBigEndian() {
+		return uint32(r >> 32), uint32(r)
+	}
+	return uint32(r), uint32(r >> 32)
+}
+
+// Pack a pair of 32 bit instruction words o1, o2 into 64 bit relocation
+// in endian order.
+func packInstPair(target *ld.Target, o1, o2 uint32) int64 {
+	if target.IsBigEndian() {
+		return (int64(o1) << 32) | int64(o2)
+	}
+	return int64(o1) | (int64(o2) << 32)
+}
+
+// Compute the high-adjusted value (always a signed 32b value) per the ELF ABI.
+// The returned value is always 0 <= x <= 0xFFFF.
+func computeHA(val int32) uint32 {
+	return uint32(uint16((val + 0x8000) >> 16))
+}
+
+// Compute the low value (the lower 16 bits of any 32b value) per the ELF ABI.
+// The returned value is always 0 <= x <= 0xFFFF.
+func computeLO(val int32) uint32 {
+	return uint32(uint16(val))
+}
+
+// Compute the high 18 bits of a signed 34b constant. Used to pack the high 18 bits
+// of a prefix34 relocation field. This assumes the input is already restricted to
+// 34 bits.
+func computePrefix34HI(val int64) uint32 {
+	return uint32((val >> 16) & 0x3FFFF)
+}
+
+func computeTLSLEReloc(target *ld.Target, ldr *loader.Loader, rs, s loader.Sym) int64 {
+	// The thread pointer points 0x7000 bytes after the start of the
+	// thread local storage area as documented in section "3.7.2 TLS
+	// Runtime Handling" of "Power Architecture 64-Bit ELF V2 ABI
+	// Specification".
+	v := ldr.SymValue(rs) - 0x7000
+	if target.IsAIX() {
+		// On AIX, the thread pointer points 0x7800 bytes after
+		// the TLS.
+		v -= 0x800
+	}
+
+	if int64(int32(v)) != v {
+		ldr.Errorf(s, "TLS offset out of range %d", v)
+	}
+	return v
+}
+
 func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loader.Reloc, s loader.Sym, val int64) (relocatedOffset int64, nExtReloc int, ok bool) {
 	rs := r.Sym()
 	if target.IsExternal() {
@@ -1001,7 +1151,7 @@
 			if !target.IsAIX() {
 				return val, nExtReloc, false
 			}
-		case objabi.R_POWER_TLS:
+		case objabi.R_POWER_TLS, objabi.R_POWER_TLS_IE_PCREL34, objabi.R_POWER_TLS_LE_TPREL34:
 			nExtReloc = 1
 			return val, nExtReloc, true
 		case objabi.R_POWER_TLS_LE, objabi.R_POWER_TLS_IE:
@@ -1032,7 +1182,7 @@
 			if !target.IsAIX() {
 				return val, nExtReloc, true
 			}
-		case objabi.R_CALLPOWER:
+		case objabi.R_CALLPOWER, objabi.R_ADDRPOWER_D34, objabi.R_ADDRPOWER_PCREL34:
 			nExtReloc = 1
 			if !target.IsAIX() {
 				return val, nExtReloc, true
@@ -1043,7 +1193,7 @@
 	switch r.Type() {
 	case objabi.R_ADDRPOWER_TOCREL, objabi.R_ADDRPOWER_TOCREL_DS:
 		return archreloctoc(ldr, target, syms, r, s, val), nExtReloc, true
-	case objabi.R_ADDRPOWER, objabi.R_ADDRPOWER_DS:
+	case objabi.R_ADDRPOWER, objabi.R_ADDRPOWER_DS, objabi.R_ADDRPOWER_D34, objabi.R_ADDRPOWER_PCREL34:
 		return archrelocaddr(ldr, target, syms, r, s, val), nExtReloc, true
 	case objabi.R_CALLPOWER:
 		// Bits 6 through 29 = (S + A - P) >> 2
@@ -1076,16 +1226,10 @@
 
 	case objabi.R_ADDRPOWER_PCREL: // S + A - P
 		t := ldr.SymValue(rs) + r.Add() - (ldr.SymValue(s) + int64(r.Off()))
-		ha := uint16(((t + 0x8000) >> 16) & 0xFFFF)
-		l := uint16(t)
-		if target.IsBigEndian() {
-			val |= int64(l)
-			val |= int64(ha) << 32
-		} else {
-			val |= int64(ha)
-			val |= int64(l) << 32
-		}
-		return val, nExtReloc, true
+		ha, l := unpackInstPair(target, val)
+		l |= computeLO(int32(t))
+		ha |= computeHA(int32(t))
+		return packInstPair(target, ha, l), nExtReloc, true
 
 	case objabi.R_POWER_TLS:
 		const OP_ADD = 31<<26 | 266<<1
@@ -1117,50 +1261,48 @@
 		const OP_ADDI = 14 << 26
 		const OP_MASK = 0x3F << 26
 		const OP_RA_MASK = 0x1F << 16
-		uval := uint64(val)
 		// convert r2 to r0, and ld to addi
-		if target.IsBigEndian() {
-			uval = uval &^ (OP_RA_MASK << 32)
-			uval = (uval &^ OP_MASK) | OP_ADDI
-		} else {
-			uval = uval &^ (OP_RA_MASK)
-			uval = (uval &^ (OP_MASK << 32)) | (OP_ADDI << 32)
-		}
-		val = int64(uval)
-		// Treat this like an R_POWER_TLS_LE relocation now.
+		mask := packInstPair(target, OP_RA_MASK, OP_MASK)
+		addi_op := packInstPair(target, 0, OP_ADDI)
+		val &^= mask
+		val |= addi_op
 		fallthrough
 
 	case objabi.R_POWER_TLS_LE:
-		// The thread pointer points 0x7000 bytes after the start of the
-		// thread local storage area as documented in section "3.7.2 TLS
-		// Runtime Handling" of "Power Architecture 64-Bit ELF V2 ABI
-		// Specification".
-		v := ldr.SymValue(rs) - 0x7000
-		if target.IsAIX() {
-			// On AIX, the thread pointer points 0x7800 bytes after
-			// the TLS.
-			v -= 0x800
+		v := computeTLSLEReloc(target, ldr, rs, s)
+		o1, o2 := unpackInstPair(target, val)
+		o1 |= computeHA(int32(v))
+		o2 |= computeLO(int32(v))
+		return packInstPair(target, o1, o2), nExtReloc, true
+
+	case objabi.R_POWER_TLS_IE_PCREL34:
+		// Convert TLS_IE relocation to TLS_LE if supported.
+		if !(target.IsPIE() && target.IsElf()) {
+			log.Fatalf("cannot handle R_POWER_TLS_IE (sym %s) when linking non-PIE, non-ELF binaries internally", ldr.SymName(s))
 		}
 
-		var o1, o2 uint32
-		if int64(int32(v)) != v {
-			ldr.Errorf(s, "TLS offset out of range %d", v)
-		}
-		if target.IsBigEndian() {
-			o1 = uint32(val >> 32)
-			o2 = uint32(val)
-		} else {
-			o1 = uint32(val)
-			o2 = uint32(val >> 32)
-		}
+		// We are an ELF binary, we can safely convert to TLS_LE_TPREL34 from:
+		// pld rX, x@got@tprel@pcrel
+		//
+		// to TLS_LE_TPREL32 by converting to:
+		// pla rX, x@tprel
 
-		o1 |= uint32(((v + 0x8000) >> 16) & 0xFFFF)
-		o2 |= uint32(v & 0xFFFF)
+		const OP_MASK_PFX = 0xFFFFFFFF        // Discard prefix word
+		const OP_MASK = (0x3F << 26) | 0xFFFF // Preserve RT, RA
+		const OP_PFX = 1<<26 | 2<<24
+		const OP_PLA = 14 << 26
+		mask := packInstPair(target, OP_MASK_PFX, OP_MASK)
+		pla_op := packInstPair(target, OP_PFX, OP_PLA)
+		val &^= mask
+		val |= pla_op
+		fallthrough
 
-		if target.IsBigEndian() {
-			return int64(o1)<<32 | int64(o2), nExtReloc, true
-		}
-		return int64(o2)<<32 | int64(o1), nExtReloc, true
+	case objabi.R_POWER_TLS_LE_TPREL34:
+		v := computeTLSLEReloc(target, ldr, rs, s)
+		o1, o2 := unpackInstPair(target, val)
+		o1 |= computePrefix34HI(v)
+		o2 |= computeLO(int32(v))
+		return packInstPair(target, o1, o2), nExtReloc, true
 	}
 
 	return val, nExtReloc, false
@@ -1261,14 +1403,16 @@
 
 func extreloc(target *ld.Target, ldr *loader.Loader, r loader.Reloc, s loader.Sym) (loader.ExtReloc, bool) {
 	switch r.Type() {
-	case objabi.R_POWER_TLS, objabi.R_POWER_TLS_LE, objabi.R_POWER_TLS_IE, objabi.R_CALLPOWER:
+	case objabi.R_POWER_TLS, objabi.R_POWER_TLS_LE, objabi.R_POWER_TLS_IE, objabi.R_POWER_TLS_IE_PCREL34, objabi.R_POWER_TLS_LE_TPREL34, objabi.R_CALLPOWER:
 		return ld.ExtrelocSimple(ldr, r), true
 	case objabi.R_ADDRPOWER,
 		objabi.R_ADDRPOWER_DS,
 		objabi.R_ADDRPOWER_TOCREL,
 		objabi.R_ADDRPOWER_TOCREL_DS,
 		objabi.R_ADDRPOWER_GOT,
-		objabi.R_ADDRPOWER_PCREL:
+		objabi.R_ADDRPOWER_PCREL,
+		objabi.R_ADDRPOWER_D34,
+		objabi.R_ADDRPOWER_PCREL34:
 		return ld.ExtrelocViaOuterSym(ldr, r, s), true
 	}
 	return loader.ExtReloc{}, false
@@ -1318,7 +1462,7 @@
 	}
 }
 
-// Generate the glink resolver stub if necessary and return the .glink section
+// Generate the glink resolver stub if necessary and return the .glink section.
 func ensureglinkresolver(ctxt *ld.Link, ldr *loader.Loader) *loader.SymbolBuilder {
 	glink := ldr.CreateSymForUpdate(".glink", 0)
 	if glink.Size() != 0 {
diff --git a/src/cmd/link/internal/ppc64/obj.go b/src/cmd/link/internal/ppc64/obj.go
index b6d5ad9..f580c55 100644
--- a/src/cmd/link/internal/ppc64/obj.go
+++ b/src/cmd/link/internal/ppc64/obj.go
@@ -38,9 +38,14 @@
 )
 
 func Init() (*sys.Arch, ld.Arch) {
-	arch := sys.ArchPPC64
-	if buildcfg.GOARCH == "ppc64le" {
-		arch = sys.ArchPPC64LE
+	arch := sys.ArchPPC64LE
+	dynld := "/lib64/ld64.so.2"
+	musl := "/lib/ld-musl-powerpc64le.so.1"
+
+	if buildcfg.GOARCH == "ppc64" {
+		arch = sys.ArchPPC64
+		dynld = "/lib64/ld64.so.1"
+		musl = "/lib/ld-musl-powerpc64.so.1"
 	}
 
 	theArch := ld.Arch{
@@ -64,8 +69,8 @@
 		Machoreloc1:      machoreloc1,
 		Xcoffreloc1:      xcoffreloc1,
 
-		// TODO(austin): ABI v1 uses /usr/lib/ld.so.1,
-		Linuxdynld: "/lib64/ld64.so.1",
+		Linuxdynld:     dynld,
+		LinuxdynldMusl: musl,
 
 		Freebsddynld:   "XXX",
 		Openbsddynld:   "XXX",
diff --git a/src/cmd/link/internal/riscv64/obj.go b/src/cmd/link/internal/riscv64/obj.go
index 557e893..8e4e41f 100644
--- a/src/cmd/link/internal/riscv64/obj.go
+++ b/src/cmd/link/internal/riscv64/obj.go
@@ -41,7 +41,7 @@
 
 		Linuxdynld: "/lib/ld.so.1",
 
-		Freebsddynld:   "XXX",
+		Freebsddynld:   "/usr/libexec/ld-elf.so.1",
 		Netbsddynld:    "XXX",
 		Openbsddynld:   "XXX",
 		Dragonflydynld: "XXX",
@@ -53,7 +53,7 @@
 
 func archinit(ctxt *ld.Link) {
 	switch ctxt.HeadType {
-	case objabi.Hlinux:
+	case objabi.Hlinux, objabi.Hfreebsd:
 		ld.Elfinit(ctxt)
 		ld.HEADR = ld.ELFRESERVE
 		if *ld.FlagTextAddr == -1 {
diff --git a/src/cmd/link/internal/s390x/asm.go b/src/cmd/link/internal/s390x/asm.go
index 482b3c8..2d9f750 100644
--- a/src/cmd/link/internal/s390x/asm.go
+++ b/src/cmd/link/internal/s390x/asm.go
@@ -210,11 +210,7 @@
 		return true
 	}
 	// Handle references to ELF symbols from our own object files.
-	if targType != sym.SDYNIMPORT {
-		return true
-	}
-
-	return false
+	return targType != sym.SDYNIMPORT
 }
 
 func elfreloc1(ctxt *ld.Link, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym, r loader.ExtReloc, ri int, sectoff int64) bool {
diff --git a/src/cmd/link/internal/s390x/obj.go b/src/cmd/link/internal/s390x/obj.go
index 8acc1d4..3aa8948 100644
--- a/src/cmd/link/internal/s390x/obj.go
+++ b/src/cmd/link/internal/s390x/obj.go
@@ -56,7 +56,8 @@
 		Gentext:          gentext,
 		Machoreloc1:      machoreloc1,
 
-		Linuxdynld: "/lib64/ld64.so.1",
+		Linuxdynld:     "/lib64/ld64.so.1",
+		LinuxdynldMusl: "/lib/ld-musl-s390x.so.1",
 
 		// not relevant for s390x
 		Freebsddynld:   "XXX",
diff --git a/src/cmd/link/internal/sym/symkind.go b/src/cmd/link/internal/sym/symkind.go
index 0f8fbed..2f8e8fe 100644
--- a/src/cmd/link/internal/sym/symkind.go
+++ b/src/cmd/link/internal/sym/symkind.go
@@ -98,6 +98,8 @@
 	SBSS
 	SNOPTRBSS
 	SLIBFUZZER_8BIT_COUNTER
+	SCOVERAGE_COUNTER
+	SCOVERAGE_AUXVAR
 	STLSBSS
 	SXREF
 	SMACHOSYMSTR
@@ -144,6 +146,8 @@
 	objabi.SDWARFLOC:               SDWARFLOC,
 	objabi.SDWARFLINES:             SDWARFLINES,
 	objabi.SLIBFUZZER_8BIT_COUNTER: SLIBFUZZER_8BIT_COUNTER,
+	objabi.SCOVERAGE_COUNTER:       SCOVERAGE_COUNTER,
+	objabi.SCOVERAGE_AUXVAR:        SCOVERAGE_AUXVAR,
 }
 
 // ReadOnly are the symbol kinds that form read-only sections. In some
diff --git a/src/cmd/link/internal/sym/symkind_string.go b/src/cmd/link/internal/sym/symkind_string.go
index 14b57db..1cd7ab1 100644
--- a/src/cmd/link/internal/sym/symkind_string.go
+++ b/src/cmd/link/internal/sym/symkind_string.go
@@ -45,31 +45,33 @@
 	_ = x[SBSS-34]
 	_ = x[SNOPTRBSS-35]
 	_ = x[SLIBFUZZER_8BIT_COUNTER-36]
-	_ = x[STLSBSS-37]
-	_ = x[SXREF-38]
-	_ = x[SMACHOSYMSTR-39]
-	_ = x[SMACHOSYMTAB-40]
-	_ = x[SMACHOINDIRECTPLT-41]
-	_ = x[SMACHOINDIRECTGOT-42]
-	_ = x[SFILEPATH-43]
-	_ = x[SDYNIMPORT-44]
-	_ = x[SHOSTOBJ-45]
-	_ = x[SUNDEFEXT-46]
-	_ = x[SDWARFSECT-47]
-	_ = x[SDWARFCUINFO-48]
-	_ = x[SDWARFCONST-49]
-	_ = x[SDWARFFCN-50]
-	_ = x[SDWARFABSFCN-51]
-	_ = x[SDWARFTYPE-52]
-	_ = x[SDWARFVAR-53]
-	_ = x[SDWARFRANGE-54]
-	_ = x[SDWARFLOC-55]
-	_ = x[SDWARFLINES-56]
+	_ = x[SCOVERAGE_COUNTER-37]
+	_ = x[SCOVERAGE_AUXVAR-38]
+	_ = x[STLSBSS-39]
+	_ = x[SXREF-40]
+	_ = x[SMACHOSYMSTR-41]
+	_ = x[SMACHOSYMTAB-42]
+	_ = x[SMACHOINDIRECTPLT-43]
+	_ = x[SMACHOINDIRECTGOT-44]
+	_ = x[SFILEPATH-45]
+	_ = x[SDYNIMPORT-46]
+	_ = x[SHOSTOBJ-47]
+	_ = x[SUNDEFEXT-48]
+	_ = x[SDWARFSECT-49]
+	_ = x[SDWARFCUINFO-50]
+	_ = x[SDWARFCONST-51]
+	_ = x[SDWARFFCN-52]
+	_ = x[SDWARFABSFCN-53]
+	_ = x[SDWARFTYPE-54]
+	_ = x[SDWARFVAR-55]
+	_ = x[SDWARFRANGE-56]
+	_ = x[SDWARFLOC-57]
+	_ = x[SDWARFLINES-58]
 }
 
-const _SymKind_name = "SxxxSTEXTSELFRXSECTSMACHOPLTSTYPESSTRINGSGOSTRINGSGOFUNCSGCBITSSRODATASFUNCTABSELFROSECTSTYPERELROSSTRINGRELROSGOSTRINGRELROSGOFUNCRELROSGCBITSRELROSRODATARELROSFUNCTABRELROSTYPELINKSITABLINKSSYMTABSPCLNTABSFirstWritableSBUILDINFOSELFSECTSMACHOSMACHOGOTSWINDOWSSELFGOTSNOPTRDATASINITARRSDATASXCOFFTOCSBSSSNOPTRBSSSLIBFUZZER_8BIT_COUNTERSTLSBSSSXREFSMACHOSYMSTRSMACHOSYMTABSMACHOINDIRECTPLTSMACHOINDIRECTGOTSFILEPATHSDYNIMPORTSHOSTOBJSUNDEFEXTSDWARFSECTSDWARFCUINFOSDWARFCONSTSDWARFFCNSDWARFABSFCNSDWARFTYPESDWARFVARSDWARFRANGESDWARFLOCSDWARFLINES"
+const _SymKind_name = "SxxxSTEXTSELFRXSECTSMACHOPLTSTYPESSTRINGSGOSTRINGSGOFUNCSGCBITSSRODATASFUNCTABSELFROSECTSTYPERELROSSTRINGRELROSGOSTRINGRELROSGOFUNCRELROSGCBITSRELROSRODATARELROSFUNCTABRELROSTYPELINKSITABLINKSSYMTABSPCLNTABSFirstWritableSBUILDINFOSELFSECTSMACHOSMACHOGOTSWINDOWSSELFGOTSNOPTRDATASINITARRSDATASXCOFFTOCSBSSSNOPTRBSSSLIBFUZZER_8BIT_COUNTERSCOVERAGE_COUNTERSCOVERAGE_AUXVARSTLSBSSSXREFSMACHOSYMSTRSMACHOSYMTABSMACHOINDIRECTPLTSMACHOINDIRECTGOTSFILEPATHSDYNIMPORTSHOSTOBJSUNDEFEXTSDWARFSECTSDWARFCUINFOSDWARFCONSTSDWARFFCNSDWARFABSFCNSDWARFTYPESDWARFVARSDWARFRANGESDWARFLOCSDWARFLINES"
 
-var _SymKind_index = [...]uint16{0, 4, 9, 19, 28, 33, 40, 49, 56, 63, 70, 78, 88, 98, 110, 124, 136, 148, 160, 173, 182, 191, 198, 206, 220, 230, 238, 244, 253, 261, 268, 278, 286, 291, 300, 304, 313, 336, 343, 348, 360, 372, 389, 406, 415, 425, 433, 442, 452, 464, 475, 484, 496, 506, 515, 526, 535, 546}
+var _SymKind_index = [...]uint16{0, 4, 9, 19, 28, 33, 40, 49, 56, 63, 70, 78, 88, 98, 110, 124, 136, 148, 160, 173, 182, 191, 198, 206, 220, 230, 238, 244, 253, 261, 268, 278, 286, 291, 300, 304, 313, 336, 353, 369, 376, 381, 393, 405, 422, 439, 448, 458, 466, 475, 485, 497, 508, 517, 529, 539, 548, 559, 568, 579}
 
 func (i SymKind) String() string {
 	if i >= SymKind(len(_SymKind_index)-1) {
diff --git a/src/cmd/link/internal/wasm/asm.go b/src/cmd/link/internal/wasm/asm.go
index 01c500e..99018c8 100644
--- a/src/cmd/link/internal/wasm/asm.go
+++ b/src/cmd/link/internal/wasm/asm.go
@@ -60,8 +60,6 @@
 	"wasm_export_resume":     {Params: []byte{}},                                         //
 	"wasm_export_getsp":      {Results: []byte{I32}},                                     // sp
 	"wasm_pc_f_loop":         {Params: []byte{}},                                         //
-	"runtime.wasmMove":       {Params: []byte{I32, I32, I32}},                            // dst, src, len
-	"runtime.wasmZero":       {Params: []byte{I32, I32}},                                 // ptr, len
 	"runtime.wasmDiv":        {Params: []byte{I64, I64}, Results: []byte{I64}},           // x, y -> x/y
 	"runtime.wasmTruncS":     {Params: []byte{F64}, Results: []byte{I64}},                // x -> int(x)
 	"runtime.wasmTruncU":     {Params: []byte{F64}, Results: []byte{I64}},                // x -> uint(x)
@@ -156,7 +154,7 @@
 	fns := make([]*wasmFunc, len(ctxt.Textp))
 	for i, fn := range ctxt.Textp {
 		wfn := new(bytes.Buffer)
-		if ldr.SymName(fn) == "go.buildid" {
+		if ldr.SymName(fn) == "go:buildid" {
 			writeUleb128(wfn, 0) // number of sets of locals
 			writeI32Const(wfn, 0)
 			wfn.WriteByte(0x0b) // end
@@ -248,7 +246,7 @@
 
 func writeBuildID(ctxt *ld.Link, buildid []byte) {
 	sizeOffset := writeSecHeader(ctxt, sectionCustom)
-	writeName(ctxt.Out, "go.buildid")
+	writeName(ctxt.Out, "go:buildid")
 	ctxt.Out.Write(buildid)
 	writeSecSize(ctxt, sizeOffset)
 }
@@ -412,7 +410,7 @@
 	writeSecSize(ctxt, sizeOffset)
 }
 
-// writeElementSec writes the section that provides the function bodies for the functions
+// writeCodeSec writes the section that provides the function bodies for the functions
 // declared by the "func" section.
 func writeCodeSec(ctxt *ld.Link, fns []*wasmFunc) {
 	sizeOffset := writeSecHeader(ctxt, sectionCode)
@@ -520,7 +518,7 @@
 	writeSecSize(ctxt, sizeOffset)
 }
 
-var nameRegexp = regexp.MustCompile(`[^\w\.]`)
+var nameRegexp = regexp.MustCompile(`[^\w.]`)
 
 // writeNameSec writes an optional section that assigns names to the functions declared by the "func" section.
 // The names are only used by WebAssembly stack traces, debuggers and decompilers.
diff --git a/src/cmd/link/internal/x86/obj.go b/src/cmd/link/internal/x86/obj.go
index a19437d..b0a129e 100644
--- a/src/cmd/link/internal/x86/obj.go
+++ b/src/cmd/link/internal/x86/obj.go
@@ -61,11 +61,12 @@
 		Machoreloc1:      machoreloc1,
 		PEreloc1:         pereloc1,
 
-		Linuxdynld:   "/lib/ld-linux.so.2",
-		Freebsddynld: "/usr/libexec/ld-elf.so.1",
-		Openbsddynld: "/usr/libexec/ld.so",
-		Netbsddynld:  "/usr/libexec/ld.elf_so",
-		Solarisdynld: "/lib/ld.so.1",
+		Linuxdynld:     "/lib/ld-linux.so.2",
+		LinuxdynldMusl: "/lib/ld-musl-i386.so.1",
+		Freebsddynld:   "/usr/libexec/ld-elf.so.1",
+		Openbsddynld:   "/usr/libexec/ld.so",
+		Netbsddynld:    "/usr/libexec/ld.elf_so",
+		Solarisdynld:   "/lib/ld.so.1",
 	}
 
 	return arch, theArch
diff --git a/src/cmd/link/link_test.go b/src/cmd/link/link_test.go
index 45dc6b3..a770c91 100644
--- a/src/cmd/link/link_test.go
+++ b/src/cmd/link/link_test.go
@@ -7,13 +7,11 @@
 import (
 	"bufio"
 	"bytes"
-	"cmd/internal/sys"
 	"debug/macho"
 	"internal/buildcfg"
+	"internal/platform"
 	"internal/testenv"
-	"io/ioutil"
 	"os"
-	"os/exec"
 	"path/filepath"
 	"regexp"
 	"runtime"
@@ -51,19 +49,22 @@
 
 	tmpdir := t.TempDir()
 
-	err := ioutil.WriteFile(filepath.Join(tmpdir, "main.go"), []byte(source), 0666)
+	importcfgfile := filepath.Join(tmpdir, "importcfg")
+	testenv.WriteImportcfg(t, importcfgfile, nil)
+
+	err := os.WriteFile(filepath.Join(tmpdir, "main.go"), []byte(source), 0666)
 	if err != nil {
 		t.Fatalf("failed to write main.go: %v\n", err)
 	}
 
-	cmd := exec.Command(testenv.GoToolPath(t), "tool", "compile", "-p=main", "main.go")
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "tool", "compile", "-importcfg="+importcfgfile, "-p=main", "main.go")
 	cmd.Dir = tmpdir
 	out, err := cmd.CombinedOutput()
 	if err != nil {
 		t.Fatalf("failed to compile main.go: %v, output: %s\n", err, out)
 	}
 
-	cmd = exec.Command(testenv.GoToolPath(t), "tool", "link", "main.o")
+	cmd = testenv.Command(t, testenv.GoToolPath(t), "tool", "link", "-importcfg="+importcfgfile, "main.o")
 	cmd.Dir = tmpdir
 	out, err = cmd.CombinedOutput()
 	if err != nil {
@@ -83,14 +84,14 @@
 	tmpdir := t.TempDir()
 
 	write := func(name, content string) {
-		err := ioutil.WriteFile(filepath.Join(tmpdir, name), []byte(content), 0666)
+		err := os.WriteFile(filepath.Join(tmpdir, name), []byte(content), 0666)
 		if err != nil {
 			t.Fatal(err)
 		}
 	}
 
 	runGo := func(args ...string) {
-		cmd := exec.Command(testenv.GoToolPath(t), args...)
+		cmd := testenv.Command(t, testenv.GoToolPath(t), args...)
 		cmd.Dir = tmpdir
 		out, err := cmd.CombinedOutput()
 		if err != nil {
@@ -99,9 +100,12 @@
 		}
 	}
 
+	importcfgfile := filepath.Join(tmpdir, "importcfg")
+	testenv.WriteImportcfg(t, importcfgfile, nil)
+
 	// Compile a main package.
 	write("main.go", "package main; func main() {}")
-	runGo("tool", "compile", "-p=main", "main.go")
+	runGo("tool", "compile", "-importcfg="+importcfgfile, "-p=main", "main.go")
 	runGo("tool", "pack", "c", "main.a", "main.o")
 
 	// Add an extra section with a short, non-.o name.
@@ -111,7 +115,7 @@
 
 	// Verify that the linker does not attempt
 	// to compile the extra section.
-	runGo("tool", "link", "main.a")
+	runGo("tool", "link", "-importcfg="+importcfgfile, "main.a")
 }
 
 func TestUnresolved(t *testing.T) {
@@ -122,7 +126,7 @@
 	tmpdir := t.TempDir()
 
 	write := func(name, content string) {
-		err := ioutil.WriteFile(filepath.Join(tmpdir, name), []byte(content), 0666)
+		err := os.WriteFile(filepath.Join(tmpdir, name), []byte(content), 0666)
 		if err != nil {
 			t.Fatal(err)
 		}
@@ -149,7 +153,7 @@
         MOVD ·zero(SB), AX
         RET
 `)
-	cmd := exec.Command(testenv.GoToolPath(t), "build")
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "build")
 	cmd.Dir = tmpdir
 	cmd.Env = append(os.Environ(),
 		"GOARCH=amd64", "GOOS=linux", "GOPATH="+filepath.Join(tmpdir, "_gopath"))
@@ -190,14 +194,14 @@
 	tmpdir := t.TempDir()
 
 	write := func(name, content string) {
-		err := ioutil.WriteFile(filepath.Join(tmpdir, name), []byte(content), 0666)
+		err := os.WriteFile(filepath.Join(tmpdir, name), []byte(content), 0666)
 		if err != nil {
 			t.Fatal(err)
 		}
 	}
 
 	run := func(name string, args ...string) string {
-		cmd := exec.Command(name, args...)
+		cmd := testenv.Command(t, name, args...)
 		cmd.Dir = tmpdir
 		out, err := cmd.CombinedOutput()
 		if err != nil {
@@ -237,15 +241,18 @@
 	cc := strings.TrimSpace(runGo("env", "CC"))
 	cflags := strings.Fields(runGo("env", "GOGCCFLAGS"))
 
+	importcfgfile := filepath.Join(tmpdir, "importcfg")
+	testenv.WriteImportcfg(t, importcfgfile, nil)
+
 	// Compile, assemble and pack the Go and C code.
 	runGo("tool", "asm", "-p=main", "-gensymabis", "-o", "symabis", "x.s")
-	runGo("tool", "compile", "-symabis", "symabis", "-p=main", "-o", "x1.o", "main.go")
+	runGo("tool", "compile", "-importcfg="+importcfgfile, "-symabis", "symabis", "-p=main", "-o", "x1.o", "main.go")
 	runGo("tool", "asm", "-p=main", "-o", "x2.o", "x.s")
 	run(cc, append(cflags, "-c", "-o", "x3.o", "x.c")...)
 	runGo("tool", "pack", "c", "x.a", "x1.o", "x2.o", "x3.o")
 
 	// Now attempt to link using the internal linker.
-	cmd := exec.Command(testenv.GoToolPath(t), "tool", "link", "-linkmode=internal", "x.a")
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "tool", "link", "-importcfg="+importcfgfile, "-linkmode=internal", "x.a")
 	cmd.Dir = tmpdir
 	out, err := cmd.CombinedOutput()
 	if err == nil {
@@ -268,13 +275,13 @@
 	if testing.Short() && os.Getenv("GO_BUILDER_NAME") == "" {
 		t.Skip("skipping in -short mode with $GO_BUILDER_NAME empty")
 	}
-	if err := exec.Command("xcrun", "--help").Run(); err != nil {
+	if err := testenv.Command(t, "xcrun", "--help").Run(); err != nil {
 		t.Skipf("error running xcrun, required for iOS cross build: %v", err)
 	}
 
 	t.Parallel()
 
-	sdkPath, err := exec.Command("xcrun", "--sdk", "appletvos", "--show-sdk-path").Output()
+	sdkPath, err := testenv.Command(t, "xcrun", "--sdk", "appletvos", "--show-sdk-path").Output()
 	if err != nil {
 		t.Skip("failed to locate appletvos SDK, skipping")
 	}
@@ -291,7 +298,7 @@
 	tmpDir := t.TempDir()
 
 	ar := filepath.Join(tmpDir, "lib.a")
-	cmd := exec.Command(testenv.GoToolPath(t), "build", "-buildmode=c-archive", "-o", ar, lib)
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-buildmode=c-archive", "-o", ar, lib)
 	cmd.Env = append(os.Environ(),
 		"CGO_ENABLED=1",
 		"GOOS=ios",
@@ -304,7 +311,7 @@
 		t.Fatalf("%v: %v:\n%s", cmd.Args, err, out)
 	}
 
-	link := exec.Command(CC[0], CC[1:]...)
+	link := testenv.Command(t, CC[0], CC[1:]...)
 	link.Args = append(link.Args, CGO_LDFLAGS...)
 	link.Args = append(link.Args, "-o", filepath.Join(tmpDir, "a.out")) // Avoid writing to package directory.
 	link.Args = append(link.Args, ar, filepath.Join("testdata", "testBuildFortvOS", "main.m"))
@@ -328,12 +335,12 @@
 	tmpdir := t.TempDir()
 
 	src := filepath.Join(tmpdir, "main.go")
-	err := ioutil.WriteFile(src, []byte(testXFlagSrc), 0666)
+	err := os.WriteFile(src, []byte(testXFlagSrc), 0666)
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	cmd := exec.Command(testenv.GoToolPath(t), "build", "-ldflags=-X=main.X=meow", "-o", filepath.Join(tmpdir, "main"), src)
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-ldflags=-X=main.X=meow", "-o", filepath.Join(tmpdir, "main"), src)
 	if out, err := cmd.CombinedOutput(); err != nil {
 		t.Errorf("%v: %v:\n%s", cmd.Args, err, out)
 	}
@@ -352,13 +359,13 @@
 	tmpdir := t.TempDir()
 
 	src := filepath.Join(tmpdir, "main.go")
-	err := ioutil.WriteFile(src, []byte(testMachOBuildVersionSrc), 0666)
+	err := os.WriteFile(src, []byte(testMachOBuildVersionSrc), 0666)
 	if err != nil {
 		t.Fatal(err)
 	}
 
 	exe := filepath.Join(tmpdir, "main")
-	cmd := exec.Command(testenv.GoToolPath(t), "build", "-ldflags=-linkmode=internal", "-o", exe, src)
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-ldflags=-linkmode=internal", "-o", exe, src)
 	cmd.Env = append(os.Environ(),
 		"CGO_ENABLED=0",
 		"GOOS=darwin",
@@ -428,20 +435,20 @@
 	tmpdir := t.TempDir()
 
 	src := filepath.Join(tmpdir, "blah.go")
-	err := ioutil.WriteFile(src, []byte(Issue34788src), 0666)
+	err := os.WriteFile(src, []byte(Issue34788src), 0666)
 	if err != nil {
 		t.Fatal(err)
 	}
 
 	obj := filepath.Join(tmpdir, "blah.o")
-	cmd := exec.Command(testenv.GoToolPath(t), "tool", "compile", "-p=blah", "-o", obj, src)
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "tool", "compile", "-p=blah", "-o", obj, src)
 	cmd.Env = append(os.Environ(), "GOARCH=386", "GOOS=android")
 	if out, err := cmd.CombinedOutput(); err != nil {
 		t.Fatalf("failed to compile blah.go: %v, output: %s\n", err, out)
 	}
 
 	// Run objdump on the resulting object.
-	cmd = exec.Command(testenv.GoToolPath(t), "tool", "objdump", obj)
+	cmd = testenv.Command(t, testenv.GoToolPath(t), "tool", "objdump", obj)
 	out, oerr := cmd.CombinedOutput()
 	if oerr != nil {
 		t.Fatalf("failed to objdump blah.o: %v, output: %s\n", oerr, out)
@@ -504,24 +511,24 @@
 	tmpdir := t.TempDir()
 
 	src := filepath.Join(tmpdir, "x.go")
-	err := ioutil.WriteFile(src, []byte(testStrictDupGoSrc), 0666)
+	err := os.WriteFile(src, []byte(testStrictDupGoSrc), 0666)
 	if err != nil {
 		t.Fatal(err)
 	}
 	for _, af := range asmfiles {
 		src = filepath.Join(tmpdir, af.fname+".s")
-		err = ioutil.WriteFile(src, []byte(af.payload), 0666)
+		err = os.WriteFile(src, []byte(af.payload), 0666)
 		if err != nil {
 			t.Fatal(err)
 		}
 	}
 	src = filepath.Join(tmpdir, "go.mod")
-	err = ioutil.WriteFile(src, []byte("module teststrictdup\n"), 0666)
+	err = os.WriteFile(src, []byte("module teststrictdup\n"), 0666)
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	cmd := exec.Command(testenv.GoToolPath(t), "build", "-ldflags=-strictdups=1")
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-ldflags=-strictdups=1")
 	cmd.Dir = tmpdir
 	out, err := cmd.CombinedOutput()
 	if err != nil {
@@ -531,7 +538,7 @@
 		t.Errorf("unexpected output:\n%s", out)
 	}
 
-	cmd = exec.Command(testenv.GoToolPath(t), "build", "-ldflags=-strictdups=2")
+	cmd = testenv.Command(t, testenv.GoToolPath(t), "build", "-ldflags=-strictdups=2")
 	cmd.Dir = tmpdir
 	out, err = cmd.CombinedOutput()
 	if err == nil {
@@ -589,29 +596,29 @@
 	tmpdir := t.TempDir()
 
 	src := filepath.Join(tmpdir, "go.mod")
-	err := ioutil.WriteFile(src, []byte("module cmd/link/TestFuncAlign/falign"), 0666)
+	err := os.WriteFile(src, []byte("module cmd/link/TestFuncAlign/falign"), 0666)
 	if err != nil {
 		t.Fatal(err)
 	}
 	src = filepath.Join(tmpdir, "falign.go")
-	err = ioutil.WriteFile(src, []byte(testFuncAlignSrc), 0666)
+	err = os.WriteFile(src, []byte(testFuncAlignSrc), 0666)
 	if err != nil {
 		t.Fatal(err)
 	}
 	src = filepath.Join(tmpdir, "falign.s")
-	err = ioutil.WriteFile(src, []byte(testFuncAlignAsmSrc), 0666)
+	err = os.WriteFile(src, []byte(testFuncAlignAsmSrc), 0666)
 	if err != nil {
 		t.Fatal(err)
 	}
 
 	// Build and run with old object file format.
-	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", "falign")
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-o", "falign")
 	cmd.Dir = tmpdir
 	out, err := cmd.CombinedOutput()
 	if err != nil {
 		t.Errorf("build failed: %v", err)
 	}
-	cmd = exec.Command(tmpdir + "/falign")
+	cmd = testenv.Command(t, tmpdir+"/falign")
 	out, err = cmd.CombinedOutput()
 	if err != nil {
 		t.Errorf("failed to run with err %v, output: %s", err, out)
@@ -662,19 +669,19 @@
 	tmpdir := t.TempDir()
 
 	src := filepath.Join(tmpdir, "hello.go")
-	err := ioutil.WriteFile(src, []byte(testTrampSrc), 0666)
+	err := os.WriteFile(src, []byte(testTrampSrc), 0666)
 	if err != nil {
 		t.Fatal(err)
 	}
 	exe := filepath.Join(tmpdir, "hello.exe")
 
 	for _, mode := range buildmodes {
-		cmd := exec.Command(testenv.GoToolPath(t), "build", "-buildmode="+mode, "-ldflags=-debugtramp=2", "-o", exe, src)
+		cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-buildmode="+mode, "-ldflags=-debugtramp=2", "-o", exe, src)
 		out, err := cmd.CombinedOutput()
 		if err != nil {
 			t.Fatalf("build (%s) failed: %v\n%s", mode, err, out)
 		}
-		cmd = exec.Command(exe)
+		cmd = testenv.Command(t, exe)
 		out, err = cmd.CombinedOutput()
 		if err != nil {
 			t.Errorf("executable failed to run (%s): %v\n%s", mode, err, out)
@@ -720,19 +727,19 @@
 	tmpdir := t.TempDir()
 
 	src := filepath.Join(tmpdir, "hello.go")
-	err := ioutil.WriteFile(src, []byte(testTrampCgoSrc), 0666)
+	err := os.WriteFile(src, []byte(testTrampCgoSrc), 0666)
 	if err != nil {
 		t.Fatal(err)
 	}
 	exe := filepath.Join(tmpdir, "hello.exe")
 
 	for _, mode := range buildmodes {
-		cmd := exec.Command(testenv.GoToolPath(t), "build", "-buildmode="+mode, "-ldflags=-debugtramp=2", "-o", exe, src)
+		cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-buildmode="+mode, "-ldflags=-debugtramp=2", "-o", exe, src)
 		out, err := cmd.CombinedOutput()
 		if err != nil {
 			t.Fatalf("build (%s) failed: %v\n%s", mode, err, out)
 		}
-		cmd = exec.Command(exe)
+		cmd = testenv.Command(t, exe)
 		out, err = cmd.CombinedOutput()
 		if err != nil {
 			t.Errorf("executable failed to run (%s): %v\n%s", mode, err, out)
@@ -746,12 +753,12 @@
 		if runtime.GOARCH == "ppc64" || (runtime.GOARCH == "arm64" && runtime.GOOS == "windows") || !testenv.CanInternalLink() {
 			return // internal linking cgo is not supported
 		}
-		cmd = exec.Command(testenv.GoToolPath(t), "build", "-buildmode="+mode, "-ldflags=-debugtramp=2 -linkmode=internal", "-o", exe, src)
+		cmd = testenv.Command(t, testenv.GoToolPath(t), "build", "-buildmode="+mode, "-ldflags=-debugtramp=2 -linkmode=internal", "-o", exe, src)
 		out, err = cmd.CombinedOutput()
 		if err != nil {
 			t.Fatalf("build (%s) failed: %v\n%s", mode, err, out)
 		}
-		cmd = exec.Command(exe)
+		cmd = testenv.Command(t, exe)
 		out, err = cmd.CombinedOutput()
 		if err != nil {
 			t.Errorf("executable failed to run (%s): %v\n%s", mode, err, out)
@@ -779,20 +786,25 @@
 	mObj := filepath.Join(tmpdir, "main.o")
 	exe := filepath.Join(tmpdir, "main.exe")
 
+	importcfgFile := filepath.Join(tmpdir, "stdlib.importcfg")
+	testenv.WriteImportcfg(t, importcfgFile, nil)
+	importcfgWithAFile := filepath.Join(tmpdir, "witha.importcfg")
+	testenv.WriteImportcfg(t, importcfgWithAFile, map[string]string{"a": aObj})
+
 	// Build a program with main package importing package a.
-	cmd := exec.Command(testenv.GoToolPath(t), "tool", "compile", "-p=a", "-o", aObj, aSrc)
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "tool", "compile", "-importcfg="+importcfgFile, "-p=a", "-o", aObj, aSrc)
 	t.Log(cmd)
 	out, err := cmd.CombinedOutput()
 	if err != nil {
 		t.Fatalf("compiling a.go failed: %v\n%s", err, out)
 	}
-	cmd = exec.Command(testenv.GoToolPath(t), "tool", "compile", "-p=main", "-I", tmpdir, "-o", mObj, mSrc)
+	cmd = testenv.Command(t, testenv.GoToolPath(t), "tool", "compile", "-importcfg="+importcfgWithAFile, "-p=main", "-I", tmpdir, "-o", mObj, mSrc)
 	t.Log(cmd)
 	out, err = cmd.CombinedOutput()
 	if err != nil {
 		t.Fatalf("compiling main.go failed: %v\n%s", err, out)
 	}
-	cmd = exec.Command(testenv.GoToolPath(t), "tool", "link", "-L", tmpdir, "-o", exe, mObj)
+	cmd = testenv.Command(t, testenv.GoToolPath(t), "tool", "link", "-importcfg="+importcfgWithAFile, "-L", tmpdir, "-o", exe, mObj)
 	t.Log(cmd)
 	out, err = cmd.CombinedOutput()
 	if err != nil {
@@ -801,13 +813,13 @@
 
 	// Now, overwrite a.o with the object of b.go. This should
 	// result in an index mismatch.
-	cmd = exec.Command(testenv.GoToolPath(t), "tool", "compile", "-p=a", "-o", aObj, bSrc)
+	cmd = testenv.Command(t, testenv.GoToolPath(t), "tool", "compile", "-importcfg="+importcfgFile, "-p=a", "-o", aObj, bSrc)
 	t.Log(cmd)
 	out, err = cmd.CombinedOutput()
 	if err != nil {
 		t.Fatalf("compiling a.go failed: %v\n%s", err, out)
 	}
-	cmd = exec.Command(testenv.GoToolPath(t), "tool", "link", "-L", tmpdir, "-o", exe, mObj)
+	cmd = testenv.Command(t, testenv.GoToolPath(t), "tool", "link", "-importcfg="+importcfgWithAFile, "-L", tmpdir, "-o", exe, mObj)
 	t.Log(cmd)
 	out, err = cmd.CombinedOutput()
 	if err == nil {
@@ -833,7 +845,7 @@
 
 	pkgdir := filepath.Join("testdata", "pe-binutils")
 	exe := filepath.Join(tmpdir, "a.exe")
-	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", exe)
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-o", exe)
 	cmd.Dir = pkgdir
 	// cmd.Env = append(os.Environ(), "GOOS=windows", "GOARCH=amd64") // uncomment if debugging in a cross-compiling environment
 	out, err := cmd.CombinedOutput()
@@ -842,7 +854,7 @@
 	}
 
 	// Check that the binary contains the rsrc data
-	b, err := ioutil.ReadFile(exe)
+	b, err := os.ReadFile(exe)
 	if err != nil {
 		t.Fatalf("reading output failed: %v", err)
 	}
@@ -865,7 +877,7 @@
 
 	pkgdir := filepath.Join("testdata", "pe-llvm")
 	exe := filepath.Join(tmpdir, "a.exe")
-	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", exe)
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-o", exe)
 	cmd.Dir = pkgdir
 	// cmd.Env = append(os.Environ(), "GOOS=windows", "GOARCH=amd64") // uncomment if debugging in a cross-compiling environment
 	out, err := cmd.CombinedOutput()
@@ -874,7 +886,7 @@
 	}
 
 	// Check that the binary contains the rsrc data
-	b, err := ioutil.ReadFile(exe)
+	b, err := os.ReadFile(exe)
 	if err != nil {
 		t.Fatalf("reading output failed: %v", err)
 	}
@@ -890,7 +902,7 @@
 	t.Parallel()
 
 	src := filepath.Join("testdata", "testHashedSyms", "p.go")
-	cmd := exec.Command(testenv.GoToolPath(t), "run", src)
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "run", src)
 	out, err := cmd.CombinedOutput()
 	if err != nil {
 		t.Errorf("command %s failed: %v\n%s", cmd, err, out)
@@ -904,7 +916,7 @@
 	t.Parallel()
 
 	src := filepath.Join("testdata", "testRO", "x.go")
-	cmd := exec.Command(testenv.GoToolPath(t), "run", src)
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "run", src)
 	out, err := cmd.CombinedOutput()
 	if err == nil {
 		t.Errorf("running test program did not fail. output:\n%s", out)
@@ -935,12 +947,12 @@
 	tmpdir := t.TempDir()
 
 	src := filepath.Join(tmpdir, "x.go")
-	err := ioutil.WriteFile(src, []byte(testIssue38554Src), 0666)
+	err := os.WriteFile(src, []byte(testIssue38554Src), 0666)
 	if err != nil {
 		t.Fatalf("failed to write source file: %v", err)
 	}
 	exe := filepath.Join(tmpdir, "x.exe")
-	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", exe, src)
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-o", exe, src)
 	out, err := cmd.CombinedOutput()
 	if err != nil {
 		t.Fatalf("build failed: %v\n%s", err, out)
@@ -976,7 +988,7 @@
 func TestIssue42396(t *testing.T) {
 	testenv.MustHaveGoBuild(t)
 
-	if !sys.RaceDetectorSupported(runtime.GOOS, runtime.GOARCH) {
+	if !platform.RaceDetectorSupported(runtime.GOOS, runtime.GOARCH) {
 		t.Skip("no race detector support")
 	}
 
@@ -985,12 +997,12 @@
 	tmpdir := t.TempDir()
 
 	src := filepath.Join(tmpdir, "main.go")
-	err := ioutil.WriteFile(src, []byte(testIssue42396src), 0666)
+	err := os.WriteFile(src, []byte(testIssue42396src), 0666)
 	if err != nil {
 		t.Fatalf("failed to write source file: %v", err)
 	}
 	exe := filepath.Join(tmpdir, "main.exe")
-	cmd := exec.Command(testenv.GoToolPath(t), "build", "-gcflags=-race", "-o", exe, src)
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-gcflags=-race", "-o", exe, src)
 	out, err := cmd.CombinedOutput()
 	if err == nil {
 		t.Fatalf("build unexpectedly succeeded")
@@ -1056,18 +1068,18 @@
 	tmpdir := t.TempDir()
 
 	src := filepath.Join(tmpdir, "x.go")
-	err := ioutil.WriteFile(src, []byte(testLargeRelocSrc), 0666)
+	err := os.WriteFile(src, []byte(testLargeRelocSrc), 0666)
 	if err != nil {
 		t.Fatalf("failed to write source file: %v", err)
 	}
-	cmd := exec.Command(testenv.GoToolPath(t), "run", src)
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "run", src)
 	out, err := cmd.CombinedOutput()
 	if err != nil {
 		t.Errorf("build failed: %v. output:\n%s", err, out)
 	}
 
 	if testenv.HasCGO() { // currently all targets that support cgo can external link
-		cmd = exec.Command(testenv.GoToolPath(t), "run", "-ldflags=-linkmode=external", src)
+		cmd = testenv.Command(t, testenv.GoToolPath(t), "run", "-ldflags=-linkmode=external", src)
 		out, err = cmd.CombinedOutput()
 		if err != nil {
 			t.Fatalf("build failed: %v. output:\n%s", err, out)
@@ -1091,25 +1103,27 @@
 	xObj := filepath.Join(tmpdir, "x.o")
 	pObj := filepath.Join(tmpdir, "p.o")
 	exe := filepath.Join(tmpdir, "x.exe")
-	err := ioutil.WriteFile(xSrc, []byte("package main\nimport _ \"p\"\nfunc main() {}\n"), 0666)
+	importcfgfile := filepath.Join(tmpdir, "importcfg")
+	testenv.WriteImportcfg(t, importcfgfile, map[string]string{"p": pObj})
+	err := os.WriteFile(xSrc, []byte("package main\nimport _ \"p\"\nfunc main() {}\n"), 0666)
 	if err != nil {
 		t.Fatalf("failed to write source file: %v", err)
 	}
-	err = ioutil.WriteFile(pSrc, []byte("package p\n"), 0666)
+	err = os.WriteFile(pSrc, []byte("package p\n"), 0666)
 	if err != nil {
 		t.Fatalf("failed to write source file: %v", err)
 	}
-	cmd := exec.Command(testenv.GoToolPath(t), "tool", "compile", "-o", pObj, pSrc) // without -p
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "tool", "compile", "-importcfg="+importcfgfile, "-o", pObj, pSrc) // without -p
 	out, err := cmd.CombinedOutput()
 	if err != nil {
 		t.Fatalf("compile p.go failed: %v. output:\n%s", err, out)
 	}
-	cmd = exec.Command(testenv.GoToolPath(t), "tool", "compile", "-I", tmpdir, "-p=main", "-o", xObj, xSrc)
+	cmd = testenv.Command(t, testenv.GoToolPath(t), "tool", "compile", "-importcfg="+importcfgfile, "-p=main", "-o", xObj, xSrc)
 	out, err = cmd.CombinedOutput()
 	if err != nil {
 		t.Fatalf("compile x.go failed: %v. output:\n%s", err, out)
 	}
-	cmd = exec.Command(testenv.GoToolPath(t), "tool", "link", "-L", tmpdir, "-o", exe, xObj)
+	cmd = testenv.Command(t, testenv.GoToolPath(t), "tool", "link", "-importcfg="+importcfgfile, "-o", exe, xObj)
 	out, err = cmd.CombinedOutput()
 	if err == nil {
 		t.Fatalf("link did not fail")
@@ -1119,17 +1133,18 @@
 	}
 
 	// It is okay to omit -p for (only) main package.
-	cmd = exec.Command(testenv.GoToolPath(t), "tool", "compile", "-p=p", "-o", pObj, pSrc)
+	cmd = testenv.Command(t, testenv.GoToolPath(t), "tool", "compile", "-importcfg="+importcfgfile, "-p=p", "-o", pObj, pSrc)
 	out, err = cmd.CombinedOutput()
 	if err != nil {
 		t.Fatalf("compile p.go failed: %v. output:\n%s", err, out)
 	}
-	cmd = exec.Command(testenv.GoToolPath(t), "tool", "compile", "-I", tmpdir, "-o", xObj, xSrc) // without -p
+	cmd = testenv.Command(t, testenv.GoToolPath(t), "tool", "compile", "-importcfg="+importcfgfile, "-o", xObj, xSrc) // without -p
 	out, err = cmd.CombinedOutput()
 	if err != nil {
 		t.Fatalf("compile failed: %v. output:\n%s", err, out)
 	}
-	cmd = exec.Command(testenv.GoToolPath(t), "tool", "link", "-L", tmpdir, "-o", exe, xObj)
+
+	cmd = testenv.Command(t, testenv.GoToolPath(t), "tool", "link", "-importcfg="+importcfgfile, "-o", exe, xObj)
 	out, err = cmd.CombinedOutput()
 	if err != nil {
 		t.Errorf("link failed: %v. output:\n%s", err, out)
diff --git a/src/cmd/link/linkbig_test.go b/src/cmd/link/linkbig_test.go
index 2551afc..45cb1b3 100644
--- a/src/cmd/link/linkbig_test.go
+++ b/src/cmd/link/linkbig_test.go
@@ -13,8 +13,7 @@
 	"fmt"
 	"internal/buildcfg"
 	"internal/testenv"
-	"io/ioutil"
-	"os/exec"
+	"os"
 	"testing"
 )
 
@@ -28,7 +27,7 @@
 	const FN = 4
 	tmpdir := t.TempDir()
 
-	if err := ioutil.WriteFile(tmpdir+"/go.mod", []byte("module big_test\n"), 0666); err != nil {
+	if err := os.WriteFile(tmpdir+"/go.mod", []byte("module big_test\n"), 0666); err != nil {
 		t.Fatal(err)
 	}
 
@@ -50,7 +49,7 @@
 			fmt.Fprintf(&w, inst)
 		}
 		fmt.Fprintf(&w, "\tRET\n")
-		err := ioutil.WriteFile(tmpdir+"/"+testname+".s", w.Bytes(), 0666)
+		err := os.WriteFile(tmpdir+"/"+testname+".s", w.Bytes(), 0666)
 		if err != nil {
 			t.Fatalf("can't write output: %v\n", err)
 		}
@@ -77,19 +76,19 @@
 	fmt.Fprintf(&w, "\t}\n")
 	fmt.Fprintf(&w, "\tfmt.Printf(\"PASS\\n\")\n")
 	fmt.Fprintf(&w, "}")
-	err := ioutil.WriteFile(tmpdir+"/bigfn.go", w.Bytes(), 0666)
+	err := os.WriteFile(tmpdir+"/bigfn.go", w.Bytes(), 0666)
 	if err != nil {
 		t.Fatalf("can't write output: %v\n", err)
 	}
 
 	// Build and run with internal linking.
-	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", "bigtext")
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-o", "bigtext")
 	cmd.Dir = tmpdir
 	out, err := cmd.CombinedOutput()
 	if err != nil {
 		t.Fatalf("Build failed for big text program with internal linking: %v, output: %s", err, out)
 	}
-	cmd = exec.Command("./bigtext")
+	cmd = testenv.Command(t, "./bigtext")
 	cmd.Dir = tmpdir
 	out, err = cmd.CombinedOutput()
 	if err != nil {
@@ -97,13 +96,13 @@
 	}
 
 	// Build and run with external linking
-	cmd = exec.Command(testenv.GoToolPath(t), "build", "-o", "bigtext", "-ldflags", "-linkmode=external")
+	cmd = testenv.Command(t, testenv.GoToolPath(t), "build", "-o", "bigtext", "-ldflags", "-linkmode=external")
 	cmd.Dir = tmpdir
 	out, err = cmd.CombinedOutput()
 	if err != nil {
 		t.Fatalf("Build failed for big text program with external linking: %v, output: %s", err, out)
 	}
-	cmd = exec.Command("./bigtext")
+	cmd = testenv.Command(t, "./bigtext")
 	cmd.Dir = tmpdir
 	out, err = cmd.CombinedOutput()
 	if err != nil {
diff --git a/src/cmd/nm/nm.go b/src/cmd/nm/nm.go
index 178eeb2..78fa600 100644
--- a/src/cmd/nm/nm.go
+++ b/src/cmd/nm/nm.go
@@ -29,7 +29,7 @@
 `
 
 func usage() {
-	fmt.Fprintf(os.Stderr, helpText)
+	fmt.Fprint(os.Stderr, helpText)
 	os.Exit(2)
 }
 
diff --git a/src/cmd/nm/nm_cgo_test.go b/src/cmd/nm/nm_cgo_test.go
index 23caa74..210577e 100644
--- a/src/cmd/nm/nm_cgo_test.go
+++ b/src/cmd/nm/nm_cgo_test.go
@@ -19,7 +19,7 @@
 		return false
 	case "freebsd":
 		switch runtime.GOARCH {
-		case "arm64":
+		case "arm64", "riscv64":
 			return false
 		}
 	case "linux":
diff --git a/src/cmd/nm/nm_test.go b/src/cmd/nm/nm_test.go
index 4bc9bf9..7d8358e 100644
--- a/src/cmd/nm/nm_test.go
+++ b/src/cmd/nm/nm_test.go
@@ -5,53 +5,49 @@
 package main
 
 import (
-	"fmt"
 	"internal/obscuretestdata"
 	"internal/testenv"
 	"os"
-	"os/exec"
 	"path/filepath"
 	"runtime"
 	"strings"
+	"sync"
 	"testing"
 	"text/template"
 )
 
-var testnmpath string // path to nm command created for testing purposes
-
-// The TestMain function creates a nm command for testing purposes and
-// deletes it after the tests have been run.
+// TestMain executes the test binary as the nm command if
+// GO_NMTEST_IS_NM is set, and runs the tests otherwise.
 func TestMain(m *testing.M) {
-	os.Exit(testMain(m))
+	if os.Getenv("GO_NMTEST_IS_NM") != "" {
+		main()
+		os.Exit(0)
+	}
+
+	os.Setenv("GO_NMTEST_IS_NM", "1") // Set for subprocesses to inherit.
+	os.Exit(m.Run())
 }
 
-func testMain(m *testing.M) int {
-	if !testenv.HasGoBuild() {
-		return 0
-	}
+// nmPath returns the path to the "nm" binary to run.
+func nmPath(t testing.TB) string {
+	t.Helper()
+	testenv.MustHaveExec(t)
 
-	tmpDir, err := os.MkdirTemp("", "TestNM")
-	if err != nil {
-		fmt.Println("TempDir failed:", err)
-		return 2
+	nmPathOnce.Do(func() {
+		nmExePath, nmPathErr = os.Executable()
+	})
+	if nmPathErr != nil {
+		t.Fatal(nmPathErr)
 	}
-	defer os.RemoveAll(tmpDir)
-
-	testnmpath = filepath.Join(tmpDir, "testnm.exe")
-	gotool, err := testenv.GoTool()
-	if err != nil {
-		fmt.Println("GoTool failed:", err)
-		return 2
-	}
-	out, err := exec.Command(gotool, "build", "-o", testnmpath, "cmd/nm").CombinedOutput()
-	if err != nil {
-		fmt.Printf("go build -o %v cmd/nm: %v\n%s", testnmpath, err, string(out))
-		return 2
-	}
-
-	return m.Run()
+	return nmExePath
 }
 
+var (
+	nmPathOnce sync.Once
+	nmExePath  string
+	nmPathErr  error
+)
+
 func TestNonGoExecs(t *testing.T) {
 	t.Parallel()
 	testfiles := []string{
@@ -77,7 +73,7 @@
 			exepath = tf
 		}
 
-		cmd := exec.Command(testnmpath, exepath)
+		cmd := testenv.Command(t, nmPath(t), exepath)
 		out, err := cmd.CombinedOutput()
 		if err != nil {
 			t.Errorf("go tool nm %v: %v\n%s", exepath, err, string(out))
@@ -116,12 +112,12 @@
 		args = append(args, "-ldflags", "-linkmode="+linkmode)
 	}
 	args = append(args, src)
-	out, err := exec.Command(testenv.GoToolPath(t), args...).CombinedOutput()
+	out, err := testenv.Command(t, testenv.GoToolPath(t), args...).CombinedOutput()
 	if err != nil {
 		t.Fatalf("building test executable failed: %s %s", err, out)
 	}
 
-	out, err = exec.Command(exe).CombinedOutput()
+	out, err = testenv.Command(t, exe).CombinedOutput()
 	if err != nil {
 		t.Fatalf("running test executable failed: %s %s", err, out)
 	}
@@ -151,7 +147,7 @@
 		runtimeSyms["runtime.epclntab"] = "D"
 	}
 
-	out, err = exec.Command(testnmpath, exe).CombinedOutput()
+	out, err = testenv.Command(t, nmPath(t), exe).CombinedOutput()
 	if err != nil {
 		t.Fatalf("go tool nm: %v\n%s", err, string(out))
 	}
@@ -250,7 +246,7 @@
 		t.Fatal(err)
 	}
 
-	cmd := exec.Command(testenv.GoToolPath(t), "build", "-buildmode=archive", "-o", "mylib.a", ".")
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-buildmode=archive", "-o", "mylib.a", ".")
 	cmd.Dir = libpath
 	cmd.Env = append(os.Environ(), "GOPATH="+gopath)
 	out, err := cmd.CombinedOutput()
@@ -259,7 +255,7 @@
 	}
 	mylib := filepath.Join(libpath, "mylib.a")
 
-	out, err = exec.Command(testnmpath, mylib).CombinedOutput()
+	out, err = testenv.Command(t, nmPath(t), mylib).CombinedOutput()
 	if err != nil {
 		t.Fatalf("go tool nm: %v\n%s", err, string(out))
 	}
diff --git a/src/cmd/objdump/objdump_test.go b/src/cmd/objdump/objdump_test.go
index e984ef2..69b4cf4 100644
--- a/src/cmd/objdump/objdump_test.go
+++ b/src/cmd/objdump/objdump_test.go
@@ -9,54 +9,48 @@
 	"flag"
 	"fmt"
 	"go/build"
+	"internal/platform"
 	"internal/testenv"
 	"os"
-	"os/exec"
 	"path/filepath"
 	"runtime"
 	"strings"
+	"sync"
 	"testing"
 )
 
-var tmp, exe string // populated by buildObjdump
-
+// TestMain executes the test binary as the objdump command if
+// GO_OBJDUMPTEST_IS_OBJDUMP is set, and runs the test otherwise.
 func TestMain(m *testing.M) {
-	if !testenv.HasGoBuild() {
-		return
+	if os.Getenv("GO_OBJDUMPTEST_IS_OBJDUMP") != "" {
+		main()
+		os.Exit(0)
 	}
 
-	var exitcode int
-	if err := buildObjdump(); err == nil {
-		exitcode = m.Run()
-	} else {
-		fmt.Println(err)
-		exitcode = 1
-	}
-	os.RemoveAll(tmp)
-	os.Exit(exitcode)
+	os.Setenv("GO_OBJDUMPTEST_IS_OBJDUMP", "1")
+	os.Exit(m.Run())
 }
 
-func buildObjdump() error {
-	var err error
-	tmp, err = os.MkdirTemp("", "TestObjDump")
-	if err != nil {
-		return fmt.Errorf("TempDir failed: %v", err)
-	}
+// objdumpPath returns the path to the "objdump" binary to run.
+func objdumpPath(t testing.TB) string {
+	t.Helper()
+	testenv.MustHaveExec(t)
 
-	exe = filepath.Join(tmp, "testobjdump.exe")
-	gotool, err := testenv.GoTool()
-	if err != nil {
-		return err
+	objdumpPathOnce.Do(func() {
+		objdumpExePath, objdumpPathErr = os.Executable()
+	})
+	if objdumpPathErr != nil {
+		t.Fatal(objdumpPathErr)
 	}
-	out, err := exec.Command(gotool, "build", "-o", exe, "cmd/objdump").CombinedOutput()
-	if err != nil {
-		os.RemoveAll(tmp)
-		return fmt.Errorf("go build -o %v cmd/objdump: %v\n%s", exe, err, string(out))
-	}
-
-	return nil
+	return objdumpExePath
 }
 
+var (
+	objdumpPathOnce sync.Once
+	objdumpExePath  string
+	objdumpPathErr  error
+)
+
 var x86Need = []string{ // for both 386 and AMD64
 	"JMP main.main(SB)",
 	"CALL main.Println(SB)",
@@ -99,6 +93,12 @@
 	"RET",
 }
 
+var ppcPIENeed = []string{
+	"BR",
+	"CALL",
+	"RET",
+}
+
 var ppcGnuNeed = []string{
 	"mflr",
 	"lbz",
@@ -145,11 +145,12 @@
 	}
 
 	hash := notsha256.Sum256([]byte(fmt.Sprintf("%v-%v-%v-%v", srcfname, flags, printCode, printGnuAsm)))
+	tmp := t.TempDir()
 	hello := filepath.Join(tmp, fmt.Sprintf("hello-%x.exe", hash))
 	args := []string{"build", "-o", hello}
 	args = append(args, flags...)
 	args = append(args, srcfname)
-	cmd := exec.Command(testenv.GoToolPath(t), args...)
+	cmd := testenv.Command(t, testenv.GoToolPath(t), args...)
 	// "Bad line" bug #36683 is sensitive to being run in the source directory.
 	cmd.Dir = "testdata"
 	// Ensure that the source file location embedded in the binary matches our
@@ -178,7 +179,21 @@
 	case "arm64":
 		need = append(need, arm64Need...)
 	case "ppc64", "ppc64le":
-		need = append(need, ppcNeed...)
+		var pie bool
+		for _, flag := range flags {
+			if flag == "-buildmode=pie" {
+				pie = true
+				break
+			}
+		}
+		if pie {
+			// In PPC64 PIE binaries we use a "local entry point" which is
+			// function symbol address + 8. Currently we don't symbolize that.
+			// Expect a different output.
+			need = append(need, ppcPIENeed...)
+		} else {
+			need = append(need, ppcNeed...)
+		}
 	}
 
 	if printGnuAsm {
@@ -205,7 +220,7 @@
 	if printGnuAsm {
 		args = append([]string{"-gnu"}, args...)
 	}
-	cmd = exec.Command(exe, args...)
+	cmd = testenv.Command(t, objdumpPath(t), args...)
 	cmd.Dir = "testdata" // "Bad line" bug #36683 is sensitive to being run in the source directory
 	out, err = cmd.CombinedOutput()
 	t.Logf("Running %v", cmd.Args)
@@ -265,13 +280,31 @@
 	testDisasm(t, "fmthello.go", false, false, "-ldflags=-linkmode=external")
 }
 
+func TestDisasmPIE(t *testing.T) {
+	if !platform.BuildModeSupported("gc", "pie", runtime.GOOS, runtime.GOARCH) {
+		t.Skipf("skipping on %s/%s, PIE buildmode not supported", runtime.GOOS, runtime.GOARCH)
+	}
+	if !platform.InternalLinkPIESupported(runtime.GOOS, runtime.GOARCH) {
+		// require cgo on platforms that PIE needs external linking
+		testenv.MustHaveCGO(t)
+	}
+	t.Parallel()
+	testDisasm(t, "fmthello.go", false, false, "-buildmode=pie")
+}
+
 func TestDisasmGoobj(t *testing.T) {
 	mustHaveDisasm(t)
+	testenv.MustHaveGoBuild(t)
+
+	tmp := t.TempDir()
+
+	importcfgfile := filepath.Join(tmp, "hello.importcfg")
+	testenv.WriteImportcfg(t, importcfgfile, nil)
 
 	hello := filepath.Join(tmp, "hello.o")
-	args := []string{"tool", "compile", "-p=main", "-o", hello}
+	args := []string{"tool", "compile", "-p=main", "-importcfg=" + importcfgfile, "-o", hello}
 	args = append(args, "testdata/fmthello.go")
-	out, err := exec.Command(testenv.GoToolPath(t), args...).CombinedOutput()
+	out, err := testenv.Command(t, testenv.GoToolPath(t), args...).CombinedOutput()
 	if err != nil {
 		t.Fatalf("go tool compile fmthello.go: %v\n%s", err, out)
 	}
@@ -285,7 +318,7 @@
 		hello,
 	}
 
-	out, err = exec.Command(exe, args...).CombinedOutput()
+	out, err = testenv.Command(t, objdumpPath(t), args...).CombinedOutput()
 	if err != nil {
 		t.Fatalf("objdump fmthello.o: %v\n%s", err, out)
 	}
@@ -316,21 +349,17 @@
 
 	t.Parallel()
 
-	tmpdir, err := os.MkdirTemp("", "TestGoobjFileNumber")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpdir)
+	tmp := t.TempDir()
 
-	obj := filepath.Join(tmpdir, "p.a")
-	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", obj)
+	obj := filepath.Join(tmp, "p.a")
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-o", obj)
 	cmd.Dir = filepath.Join("testdata/testfilenum")
 	out, err := cmd.CombinedOutput()
 	if err != nil {
 		t.Fatalf("build failed: %v\n%s", err, out)
 	}
 
-	cmd = exec.Command(exe, obj)
+	cmd = testenv.Command(t, objdumpPath(t), obj)
 	out, err = cmd.CombinedOutput()
 	if err != nil {
 		t.Fatalf("objdump failed: %v\n%s", err, out)
@@ -353,7 +382,7 @@
 	t.Parallel()
 
 	obj := filepath.Join("testdata", "go116.o")
-	cmd := exec.Command(exe, obj)
+	cmd := testenv.Command(t, objdumpPath(t), obj)
 	out, err := cmd.CombinedOutput()
 	if err == nil {
 		t.Fatalf("objdump go116.o succeeded unexpectedly")
diff --git a/src/cmd/pack/pack_test.go b/src/cmd/pack/pack_test.go
index 6eec1f5..be75738 100644
--- a/src/cmd/pack/pack_test.go
+++ b/src/cmd/pack/pack_test.go
@@ -6,19 +6,51 @@
 
 import (
 	"bufio"
-	"bytes"
 	"cmd/internal/archive"
 	"fmt"
 	"internal/testenv"
 	"io"
 	"io/fs"
 	"os"
-	"os/exec"
 	"path/filepath"
+	"strings"
+	"sync"
 	"testing"
 	"time"
 )
 
+// TestMain executes the test binary as the pack command if
+// GO_PACKTEST_IS_PACK is set, and runs the tests otherwise.
+func TestMain(m *testing.M) {
+	if os.Getenv("GO_PACKTEST_IS_PACK") != "" {
+		main()
+		os.Exit(0)
+	}
+
+	os.Setenv("GO_PACKTEST_IS_PACK", "1") // Set for subprocesses to inherit.
+	os.Exit(m.Run())
+}
+
+// packPath returns the path to the "pack" binary to run.
+func packPath(t testing.TB) string {
+	t.Helper()
+	testenv.MustHaveExec(t)
+
+	packPathOnce.Do(func() {
+		packExePath, packPathErr = os.Executable()
+	})
+	if packPathErr != nil {
+		t.Fatal(packPathErr)
+	}
+	return packExePath
+}
+
+var (
+	packPathOnce sync.Once
+	packExePath  string
+	packPathErr  error
+)
+
 // testCreate creates an archive in the specified directory.
 func testCreate(t *testing.T, dir string) {
 	name := filepath.Join(dir, "pack.a")
@@ -28,7 +60,7 @@
 	ar.a.File().Close()
 	// Now check it.
 	ar = openArchive(name, os.O_RDONLY, []string{helloFile.name})
-	var buf bytes.Buffer
+	var buf strings.Builder
 	stdout = &buf
 	verbose = true
 	defer func() {
@@ -72,7 +104,7 @@
 	ar.a.File().Close()
 
 	// Now print it.
-	var buf bytes.Buffer
+	var buf strings.Builder
 	stdout = &buf
 	verbose = true
 	defer func() {
@@ -177,11 +209,13 @@
 		return doRun(t, dir, args...)
 	}
 
+	importcfgfile := filepath.Join(dir, "hello.importcfg")
+	testenv.WriteImportcfg(t, importcfgfile, nil)
+
 	goBin := testenv.GoToolPath(t)
-	run(goBin, "build", "cmd/pack") // writes pack binary to dir
-	run(goBin, "tool", "compile", "-p=main", "hello.go")
-	run("./pack", "grc", "hello.a", "hello.o")
-	run(goBin, "tool", "link", "-o", "a.out", "hello.a")
+	run(goBin, "tool", "compile", "-importcfg="+importcfgfile, "-p=main", "hello.go")
+	run(packPath(t), "grc", "hello.a", "hello.o")
+	run(goBin, "tool", "link", "-importcfg="+importcfgfile, "-o", "a.out", "hello.a")
 	out := run("./a.out")
 	if out != "hello world\n" {
 		t.Fatalf("incorrect output: %q, want %q", out, "hello world\n")
@@ -244,12 +278,15 @@
 		return doRun(t, dir, args...)
 	}
 
+	importcfgfile := filepath.Join(dir, "hello.importcfg")
+	testenv.WriteImportcfg(t, importcfgfile, nil)
+
 	goBin := testenv.GoToolPath(t)
-	run(goBin, "build", "cmd/pack") // writes pack binary to dir
-	run(goBin, "tool", "compile", "-p=large", "large.go")
-	run("./pack", "grc", "large.a", "large.o")
-	run(goBin, "tool", "compile", "-p=main", "-I", ".", "main.go")
-	run(goBin, "tool", "link", "-L", ".", "-o", "a.out", "main.o")
+	run(goBin, "tool", "compile", "-importcfg="+importcfgfile, "-p=large", "large.go")
+	run(packPath(t), "grc", "large.a", "large.o")
+	testenv.WriteImportcfg(t, importcfgfile, map[string]string{"large": filepath.Join(dir, "large.o")})
+	run(goBin, "tool", "compile", "-importcfg="+importcfgfile, "-p=main", "main.go")
+	run(goBin, "tool", "link", "-importcfg="+importcfgfile, "-L", ".", "-o", "a.out", "main.o")
 	out := run("./a.out")
 	if out != "ok\n" {
 		t.Fatalf("incorrect output: %q, want %q", out, "ok\n")
@@ -280,9 +317,8 @@
 	}
 
 	goBin := testenv.GoToolPath(t)
-	run(goBin, "build", "cmd/pack") // writes pack binary to dir
 	run(goBin, "tool", "compile", "-p=a", "a.go")
-	run("./pack", "c", "a.a", "a.o")
+	run(packPath(t), "c", "a.a", "a.o")
 	run(goBin, "tool", "compile", "-p=b", "-I", ".", "b.go")
 }
 
@@ -304,9 +340,8 @@
 	}
 
 	goBin := testenv.GoToolPath(t)
-	run(goBin, "build", "cmd/pack") // writes pack binary to dir
 	run(goBin, "tool", "compile", "-pack", "-p=p", "-o", "p.a", "p.go")
-	run("./pack", "c", "packed.a", "p.a")
+	run(packPath(t), "c", "packed.a", "p.a")
 	fi, err := os.Stat(filepath.Join(dir, "p.a"))
 	if err != nil {
 		t.Fatalf("stat p.a failed: %v", err)
@@ -324,7 +359,7 @@
 
 	// Test -linkobj flag as well.
 	run(goBin, "tool", "compile", "-p=p", "-linkobj", "p2.a", "-o", "p.x", "p.go")
-	run("./pack", "c", "packed2.a", "p2.a")
+	run(packPath(t), "c", "packed2.a", "p2.a")
 	fi, err = os.Stat(filepath.Join(dir, "p2.a"))
 	if err != nil {
 		t.Fatalf("stat p2.a failed: %v", err)
@@ -337,7 +372,7 @@
 		t.Errorf("packed file with different size: want %d, got %d", want, got)
 	}
 
-	run("./pack", "c", "packed3.a", "p.x")
+	run(packPath(t), "c", "packed3.a", "p.x")
 	fi, err = os.Stat(filepath.Join(dir, "p.x"))
 	if err != nil {
 		t.Fatalf("stat p.x failed: %v", err)
@@ -368,14 +403,13 @@
 	}
 
 	goBin := testenv.GoToolPath(t)
-	run(goBin, "build", "cmd/pack") // writes pack binary to dir
 	run(goBin, "tool", "compile", "-p=p", "-o", "p.o", "p.go")
-	run("./pack", "r", "p.a", "p.o") // should succeed
+	run(packPath(t), "r", "p.a", "p.o") // should succeed
 }
 
 // doRun runs a program in a directory and returns the output.
 func doRun(t *testing.T, dir string, args ...string) string {
-	cmd := exec.Command(args[0], args[1:]...)
+	cmd := testenv.Command(t, args[0], args[1:]...)
 	cmd.Dir = dir
 	out, err := cmd.CombinedOutput()
 	if err != nil {
diff --git a/src/cmd/pprof/pprof.go b/src/cmd/pprof/pprof.go
index c073c96..bc1a4cf 100644
--- a/src/cmd/pprof/pprof.go
+++ b/src/cmd/pprof/pprof.go
@@ -104,7 +104,7 @@
 // cpuProfileHandler is the Go pprof CPU profile handler URL.
 const cpuProfileHandler = "/debug/pprof/profile"
 
-// adjustURL applies the duration/timeout values and Go specific defaults
+// adjustURL applies the duration/timeout values and Go specific defaults.
 func adjustURL(source string, duration, timeout time.Duration) (string, time.Duration) {
 	u, err := url.Parse(source)
 	if err != nil || (u.Host == "" && u.Scheme != "" && u.Scheme != "file") {
@@ -233,8 +233,7 @@
 }
 
 func (f *file) ObjAddr(addr uint64) (uint64, error) {
-	// No support for shared libraries, so translation is a no-op.
-	return addr, nil
+	return addr - f.offset, nil
 }
 
 func (f *file) BuildID() string {
diff --git a/src/cmd/pprof/pprof_test.go b/src/cmd/pprof/pprof_test.go
index 9a37b97..353781a 100644
--- a/src/cmd/pprof/pprof_test.go
+++ b/src/cmd/pprof/pprof_test.go
@@ -5,55 +5,47 @@
 package main
 
 import (
-	"fmt"
 	"internal/testenv"
 	"os"
-	"os/exec"
 	"path/filepath"
 	"runtime"
 	"strings"
+	"sync"
 	"testing"
 )
 
-var tmp, pprofExe string // populated by buildPprof
-
+// TestMain executes the test binary as the pprof command if
+// GO_PPROFTEST_IS_PPROF is set, and runs the tests otherwise.
 func TestMain(m *testing.M) {
-	if !testenv.HasGoBuild() {
-		return
+	if os.Getenv("GO_PPROFTEST_IS_PPROF") != "" {
+		main()
+		os.Exit(0)
 	}
 
-	var exitcode int
-	if err := buildPprof(); err == nil {
-		exitcode = m.Run()
-	} else {
-		fmt.Println(err)
-		exitcode = 1
-	}
-	os.RemoveAll(tmp)
-	os.Exit(exitcode)
+	os.Setenv("GO_PPROFTEST_IS_PPROF", "1") // Set for subprocesses to inherit.
+	os.Exit(m.Run())
 }
 
-func buildPprof() error {
-	var err error
-	tmp, err = os.MkdirTemp("", "TestPprof")
-	if err != nil {
-		return fmt.Errorf("TempDir failed: %v", err)
-	}
+// pprofPath returns the path to the "pprof" binary to run.
+func pprofPath(t testing.TB) string {
+	t.Helper()
+	testenv.MustHaveExec(t)
 
-	pprofExe = filepath.Join(tmp, "testpprof.exe")
-	gotool, err := testenv.GoTool()
-	if err != nil {
-		return err
+	pprofPathOnce.Do(func() {
+		pprofExePath, pprofPathErr = os.Executable()
+	})
+	if pprofPathErr != nil {
+		t.Fatal(pprofPathErr)
 	}
-	out, err := exec.Command(gotool, "build", "-o", pprofExe, "cmd/pprof").CombinedOutput()
-	if err != nil {
-		os.RemoveAll(tmp)
-		return fmt.Errorf("go build -o %v cmd/pprof: %v\n%s", pprofExe, err, string(out))
-	}
-
-	return nil
+	return pprofExePath
 }
 
+var (
+	pprofPathOnce sync.Once
+	pprofExePath  string
+	pprofPathErr  error
+)
+
 // See also runtime/pprof.cpuProfilingBroken.
 func mustHaveCPUProfiling(t *testing.T) {
 	switch runtime.GOOS {
@@ -83,9 +75,6 @@
 	}
 
 	// Skip PIE platforms, pprof can't disassemble PIE.
-	if runtime.GOOS == "windows" {
-		t.Skipf("skipping on %s, issue 46639", runtime.GOOS)
-	}
 	if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" {
 		t.Skipf("skipping on %s/%s, issue 46639", runtime.GOOS, runtime.GOARCH)
 	}
@@ -101,7 +90,7 @@
 
 	tmpdir := t.TempDir()
 	cpuExe := filepath.Join(tmpdir, "cpu.exe")
-	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", cpuExe, "cpu.go")
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-o", cpuExe, "cpu.go")
 	cmd.Dir = "testdata/"
 	out, err := cmd.CombinedOutput()
 	if err != nil {
@@ -109,21 +98,31 @@
 	}
 
 	profile := filepath.Join(tmpdir, "cpu.pprof")
-	cmd = exec.Command(cpuExe, "-output", profile)
+	cmd = testenv.Command(t, cpuExe, "-output", profile)
 	out, err = cmd.CombinedOutput()
 	if err != nil {
 		t.Fatalf("cpu failed: %v\n%s", err, out)
 	}
 
-	cmd = exec.Command(pprofExe, "-disasm", "main.main", cpuExe, profile)
+	cmd = testenv.Command(t, pprofPath(t), "-disasm", "main.main", cpuExe, profile)
 	out, err = cmd.CombinedOutput()
 	if err != nil {
-		t.Fatalf("pprof failed: %v\n%s", err, out)
+		t.Errorf("pprof -disasm failed: %v\n%s", err, out)
+
+		// Try to print out profile content for debugging.
+		cmd = testenv.Command(t, pprofPath(t), "-raw", cpuExe, profile)
+		out, err = cmd.CombinedOutput()
+		if err != nil {
+			t.Logf("pprof -raw failed: %v\n%s", err, out)
+		} else {
+			t.Logf("profile content:\n%s", out)
+		}
+		return
 	}
 
 	sout := string(out)
 	want := "ROUTINE ======================== main.main"
 	if !strings.Contains(sout, want) {
-		t.Errorf("pprof disasm got %s want contains %q", sout, want)
+		t.Errorf("pprof -disasm got %s want contains %q", sout, want)
 	}
 }
diff --git a/src/cmd/test2json/main.go b/src/cmd/test2json/main.go
index 5e17e0d..09d5fce 100644
--- a/src/cmd/test2json/main.go
+++ b/src/cmd/test2json/main.go
@@ -6,7 +6,7 @@
 //
 // Usage:
 //
-//	go tool test2json [-p pkg] [-t] [./pkg.test -test.v [-test.paniconexit0]]
+//	go tool test2json [-p pkg] [-t] [./pkg.test -test.v=test2json]
 //
 // Test2json runs the given test command and converts its output to JSON;
 // with no command specified, test2json expects test output on standard input.
@@ -18,13 +18,16 @@
 //
 // The -t flag requests that time stamps be added to each test event.
 //
-// The test must be invoked with -test.v. Additionally passing
-// -test.paniconexit0 will cause test2json to exit with a non-zero
-// status if one of the tests being run calls os.Exit(0).
+// The test should be invoked with -test.v=test2json. Using only -test.v
+// (or -test.v=true) is permissible but produces lower fidelity results.
 //
-// Note that test2json is only intended for converting a single test
-// binary's output. To convert the output of a "go test" command,
-// use "go test -json" instead of invoking test2json directly.
+// Note that "go test -json" takes care of invoking test2json correctly,
+// so "go tool test2json" is only needed when a test binary is being run
+// separately from "go test". Use "go test -json" whenever possible.
+//
+// Note also that test2json is only intended for converting a single test
+// binary's output. To convert the output of a "go test" command that
+// runs multiple packages, again use "go test -json".
 //
 // # Output Format
 //
@@ -45,6 +48,7 @@
 //
 // The Action field is one of a fixed set of action descriptions:
 //
+//	start  - the test binary is about to be executed
 //	run    - the test has started running
 //	pause  - the test has been paused
 //	cont   - the test has continued running
@@ -54,6 +58,8 @@
 //	output - the test printed output
 //	skip   - the test was skipped or the package contained no tests
 //
+// Every JSON stream begins with a "start" event.
+//
 // The Package field, if present, specifies the package being tested.
 // When the go command runs parallel tests in -json mode, events from
 // different tests are interlaced; the Package field allows readers to
@@ -79,7 +85,7 @@
 // (for example, by using b.Log or b.Error), that extra output is reported
 // as a sequence of events with Test set to the benchmark name, terminated
 // by a final event with Action == "bench" or "fail".
-// Benchmarks have no events with Action == "run", "pause", or "cont".
+// Benchmarks have no events with Action == "pause".
 package main
 
 import (
@@ -88,6 +94,7 @@
 	"io"
 	"os"
 	"os/exec"
+	"os/signal"
 
 	"cmd/internal/test2json"
 )
@@ -102,6 +109,11 @@
 	os.Exit(2)
 }
 
+// ignoreSignals ignore the interrupt signals.
+func ignoreSignals() {
+	signal.Ignore(signalsToIgnore...)
+}
+
 func main() {
 	flag.Usage = usage
 	flag.Parse()
@@ -121,6 +133,7 @@
 		w := &countWriter{0, c}
 		cmd.Stdout = w
 		cmd.Stderr = w
+		ignoreSignals()
 		err := cmd.Run()
 		if err != nil {
 			if w.n > 0 {
diff --git a/src/cmd/test2json/signal_notunix.go b/src/cmd/test2json/signal_notunix.go
new file mode 100644
index 0000000..e5a73be
--- /dev/null
+++ b/src/cmd/test2json/signal_notunix.go
@@ -0,0 +1,13 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build plan9 || windows
+
+package main
+
+import (
+	"os"
+)
+
+var signalsToIgnore = []os.Signal{os.Interrupt}
diff --git a/src/cmd/test2json/signal_unix.go b/src/cmd/test2json/signal_unix.go
new file mode 100644
index 0000000..ed5ca7e
--- /dev/null
+++ b/src/cmd/test2json/signal_unix.go
@@ -0,0 +1,14 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build unix || js
+
+package main
+
+import (
+	"os"
+	"syscall"
+)
+
+var signalsToIgnore = []os.Signal{os.Interrupt, syscall.SIGQUIT}
diff --git a/src/cmd/trace/annotations.go b/src/cmd/trace/annotations.go
index 1c0dad5..9ffce1b 100644
--- a/src/cmd/trace/annotations.go
+++ b/src/cmd/trace/annotations.go
@@ -370,7 +370,7 @@
 	if task == nil {
 		return "task <nil>"
 	}
-	wb := new(bytes.Buffer)
+	wb := new(strings.Builder)
 	fmt.Fprintf(wb, "task %d:\t%s\n", task.id, task.name)
 	fmt.Fprintf(wb, "\tstart: %v end: %v complete: %t\n", task.firstTimestamp(), task.endTimestamp(), task.complete())
 	fmt.Fprintf(wb, "\t%d goroutines\n", len(task.goroutines))
@@ -446,9 +446,7 @@
 	res := []*taskDesc{task}
 	for i := 0; len(res[i:]) > 0; i++ {
 		t := res[i]
-		for _, c := range t.children {
-			res = append(res, c)
-		}
+		res = append(res, t.children...)
 	}
 	return res
 }
@@ -872,7 +870,7 @@
 		}
 	}
 
-	w := new(bytes.Buffer)
+	w := new(strings.Builder)
 	fmt.Fprintf(w, `<table>`)
 	for i := h.MinBucket; i <= h.MaxBucket; i++ {
 		// Tick label.
@@ -914,7 +912,7 @@
 		}
 	}
 
-	w := new(bytes.Buffer)
+	w := new(strings.Builder)
 	for i := h.MinBucket; i <= h.MaxBucket; i++ {
 		count := h.Buckets[i]
 		bar := count * barWidth / maxCount
@@ -1097,7 +1095,7 @@
 `))
 
 func elapsed(d time.Duration) string {
-	b := []byte(fmt.Sprintf("%.9f", d.Seconds()))
+	b := fmt.Appendf(nil, "%.9f", d.Seconds())
 
 	// For subsecond durations, blank all zeros before decimal point,
 	// and all zeros between the decimal point and the first non-zero digit.
diff --git a/src/cmd/trace/goroutines.go b/src/cmd/trace/goroutines.go
index 74d1b0a..7850fc0 100644
--- a/src/cmd/trace/goroutines.go
+++ b/src/cmd/trace/goroutines.go
@@ -64,6 +64,11 @@
 	var glist []gtype
 	for k, v := range gss {
 		v.ID = k
+		// If goroutine didn't run during the trace (no sampled PC),
+		// the v.ID and v.Name will be zero value.
+		if v.ID == 0 && v.Name == "" {
+			v.Name = "(Inactive, no stack trace sampled)"
+		}
 		glist = append(glist, v)
 	}
 	sort.Slice(glist, func(i, j int) bool { return glist[i].ExecTime > glist[j].ExecTime })
diff --git a/src/cmd/trace/trace.go b/src/cmd/trace/trace.go
index e6c4cca..84fca62 100644
--- a/src/cmd/trace/trace.go
+++ b/src/cmd/trace/trace.go
@@ -310,15 +310,76 @@
 	Ranges []Range
 }
 
+// walkStackFrames calls fn for id and all of its parent frames from allFrames.
+func walkStackFrames(allFrames map[string]traceviewer.Frame, id int, fn func(id int)) {
+	for id != 0 {
+		f, ok := allFrames[strconv.Itoa(id)]
+		if !ok {
+			break
+		}
+		fn(id)
+		id = f.Parent
+	}
+}
+
+func stackFrameEncodedSize(id uint, f traceviewer.Frame) int {
+	// We want to know the marginal size of traceviewer.Data.Frames for
+	// each event. Running full JSON encoding of the map for each event is
+	// far too slow.
+	//
+	// Since the format is fixed, we can easily compute the size without
+	// encoding.
+	//
+	// A single entry looks like one of the following:
+	//
+	//   "1":{"name":"main.main:30"},
+	//   "10":{"name":"pkg.NewSession:173","parent":9},
+	//
+	// The parent is omitted if 0. The trailing comma is omitted from the
+	// last entry, but we don't need that much precision.
+	const (
+		baseSize = len(`"`) + len (`":{"name":"`) + len(`"},`)
+
+		// Don't count the trailing quote on the name, as that is
+		// counted in baseSize.
+		parentBaseSize = len(`,"parent":`)
+	)
+
+	size := baseSize
+
+	size += len(f.Name)
+
+	// Bytes for id (always positive).
+	for id > 0 {
+		size += 1
+		id /= 10
+	}
+
+	if f.Parent > 0 {
+		size += parentBaseSize
+		// Bytes for parent (always positive).
+		for f.Parent > 0 {
+			size += 1
+			f.Parent /= 10
+		}
+	}
+
+	return size
+}
+
 func splittingTraceConsumer(max int) (*splitter, traceConsumer) {
 	type eventSz struct {
-		Time float64
-		Sz   int
+		Time   float64
+		Sz     int
+		Frames []int
 	}
 
 	var (
+		// data.Frames contains only the frames for required events.
 		data = traceviewer.Data{Frames: make(map[string]traceviewer.Frame)}
 
+		allFrames = make(map[string]traceviewer.Frame)
+
 		sizes []eventSz
 		cw    countingWriter
 	)
@@ -331,48 +392,95 @@
 		},
 		consumeViewerEvent: func(v *traceviewer.Event, required bool) {
 			if required {
-				// Store required events inside data
-				// so flush can include them in the required
-				// part of the trace.
+				// Store required events inside data so flush
+				// can include them in the required part of the
+				// trace.
 				data.Events = append(data.Events, v)
+				walkStackFrames(allFrames, v.Stack, func(id int) {
+					s := strconv.Itoa(id)
+					data.Frames[s] = allFrames[s]
+				})
+				walkStackFrames(allFrames, v.EndStack, func(id int) {
+					s := strconv.Itoa(id)
+					data.Frames[s] = allFrames[s]
+				})
 				return
 			}
 			enc := json.NewEncoder(&cw)
 			enc.Encode(v)
-			sizes = append(sizes, eventSz{v.Time, cw.size + 1}) // +1 for ",".
+			size := eventSz{Time: v.Time, Sz: cw.size + 1} // +1 for ",".
+			// Add referenced stack frames. Their size is computed
+			// in flush, where we can dedup across events.
+			walkStackFrames(allFrames, v.Stack, func(id int) {
+				size.Frames = append(size.Frames, id)
+			})
+			walkStackFrames(allFrames, v.EndStack, func(id int) {
+				size.Frames = append(size.Frames, id) // This may add duplicates. We'll dedup later.
+			})
+			sizes = append(sizes, size)
 			cw.size = 0
 		},
 		consumeViewerFrame: func(k string, v traceviewer.Frame) {
-			data.Frames[k] = v
+			allFrames[k] = v
 		},
 		flush: func() {
 			// Calculate size of the mandatory part of the trace.
-			// This includes stack traces and thread names.
+			// This includes thread names and stack frames for
+			// required events.
 			cw.size = 0
 			enc := json.NewEncoder(&cw)
 			enc.Encode(data)
-			minSize := cw.size
+			requiredSize := cw.size
 
-			// Then calculate size of each individual event
-			// and group them into ranges.
-			sum := minSize
-			start := 0
+			// Then calculate size of each individual event and
+			// their stack frames, grouping them into ranges. We
+			// only include stack frames relevant to the events in
+			// the range to reduce overhead.
+
+			var (
+				start = 0
+
+				eventsSize = 0
+
+				frames     = make(map[string]traceviewer.Frame)
+				framesSize = 0
+			)
 			for i, ev := range sizes {
-				if sum+ev.Sz > max {
-					startTime := time.Duration(sizes[start].Time * 1000)
-					endTime := time.Duration(ev.Time * 1000)
-					ranges = append(ranges, Range{
-						Name:      fmt.Sprintf("%v-%v", startTime, endTime),
-						Start:     start,
-						End:       i + 1,
-						StartTime: int64(startTime),
-						EndTime:   int64(endTime),
-					})
-					start = i + 1
-					sum = minSize
-				} else {
-					sum += ev.Sz + 1
+				eventsSize += ev.Sz
+
+				// Add required stack frames. Note that they
+				// may already be in the map.
+				for _, id := range ev.Frames {
+					s := strconv.Itoa(id)
+					_, ok := frames[s]
+					if ok {
+						continue
+					}
+					f := allFrames[s]
+					frames[s] = f
+					framesSize += stackFrameEncodedSize(uint(id), f)
 				}
+
+				total := requiredSize + framesSize + eventsSize
+				if total < max {
+					continue
+				}
+
+				// Reached max size, commit this range and
+				// start a new range.
+				startTime := time.Duration(sizes[start].Time * 1000)
+				endTime := time.Duration(ev.Time * 1000)
+				ranges = append(ranges, Range{
+					Name:      fmt.Sprintf("%v-%v", startTime, endTime),
+					Start:     start,
+					End:       i + 1,
+					StartTime: int64(startTime),
+					EndTime:   int64(endTime),
+				})
+				start = i + 1
+				frames = make(map[string]traceviewer.Frame)
+				framesSize = 0
+				eventsSize = 0
 			}
 			if len(ranges) <= 1 {
 				s.Ranges = nil
@@ -765,10 +873,8 @@
 	// Display task and its regions if we are in task-oriented presentation mode.
 	if ctx.mode&modeTaskOriented != 0 {
 		// sort tasks based on the task start time.
-		sortedTask := make([]*taskDesc, 0, len(ctx.tasks))
-		for _, task := range ctx.tasks {
-			sortedTask = append(sortedTask, task)
-		}
+		sortedTask := make([]*taskDesc, len(ctx.tasks))
+		copy(sortedTask, ctx.tasks)
 		sort.SliceStable(sortedTask, func(i, j int) bool {
 			ti, tj := sortedTask[i], sortedTask[j]
 			if ti.firstTimestamp() == tj.firstTimestamp() {
@@ -1153,7 +1259,8 @@
 }
 
 func viewerDataTraceConsumer(w io.Writer, start, end int64) traceConsumer {
-	frames := make(map[string]traceviewer.Frame)
+	allFrames := make(map[string]traceviewer.Frame)
+	requiredFrames := make(map[string]traceviewer.Frame)
 	enc := json.NewEncoder(w)
 	written := 0
 	index := int64(-1)
@@ -1171,6 +1278,14 @@
 				// not in the range. Skip!
 				return
 			}
+			walkStackFrames(allFrames, v.Stack, func(id int) {
+				s := strconv.Itoa(id)
+				requiredFrames[s] = allFrames[s]
+			})
+			walkStackFrames(allFrames, v.EndStack, func(id int) {
+				s := strconv.Itoa(id)
+				requiredFrames[s] = allFrames[s]
+			})
 			if written == 0 {
 				io.WriteString(w, `"traceEvents": [`)
 			}
@@ -1183,11 +1298,11 @@
 			written++
 		},
 		consumeViewerFrame: func(k string, v traceviewer.Frame) {
-			frames[k] = v
+			allFrames[k] = v
 		},
 		flush: func() {
 			io.WriteString(w, `], "stackFrames":`)
-			enc.Encode(frames)
+			enc.Encode(requiredFrames)
 			io.WriteString(w, `}`)
 		},
 	}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/cli.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/cli.go
index 237cc33..a9cae92 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/cli.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/cli.go
@@ -363,5 +363,6 @@
 	"   PPROF_TOOLS        Search path for object-level tools\n" +
 	"   PPROF_BINARY_PATH  Search path for local binary files\n" +
 	"                      default: $HOME/pprof/binaries\n" +
-	"                      searches $name, $path, $buildid/$name, $path/$buildid\n" +
+	"                      searches $buildid/$name, $buildid/*, $path/$buildid,\n" +
+	"                      ${buildid:0:2}/${buildid:2}.debug, $name, $path\n" +
 	"   * On Windows, %USERPROFILE% is used instead of $HOME"
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/driver.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/driver.go
index 6a1e64c..27681c5 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/driver.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/driver.go
@@ -59,9 +59,8 @@
 	return interactive(p, o)
 }
 
+// generateRawReport is allowed to modify p.
 func generateRawReport(p *profile.Profile, cmd []string, cfg config, o *plugin.Options) (*command, *report.Report, error) {
-	p = p.Copy() // Prevent modification to the incoming profile.
-
 	// Identify units of numeric tags in profile.
 	numLabelUnits := identifyNumLabelUnits(p, o.UI)
 
@@ -110,6 +109,7 @@
 	return c, rpt, nil
 }
 
+// generateReport is allowed to modify p.
 func generateReport(p *profile.Profile, cmd []string, cfg config, o *plugin.Options) error {
 	c, rpt, err := generateRawReport(p, cmd, cfg, o)
 	if err != nil {
@@ -201,7 +201,6 @@
 	case report.Proto, report.Raw, report.Callgrind:
 		trim = false
 		cfg.Granularity = "addresses"
-		cfg.NoInlines = false
 	}
 
 	if !trim {
@@ -365,3 +364,23 @@
 		return v[ix]
 	}
 }
+
+// profileCopier can be used to obtain a fresh copy of a profile.
+// It is useful since reporting code may mutate the profile handed to it.
+type profileCopier []byte
+
+func makeProfileCopier(src *profile.Profile) profileCopier {
+	// Pre-serialize the profile. We will deserialize every time a fresh copy is needed.
+	var buf bytes.Buffer
+	src.WriteUncompressed(&buf)
+	return profileCopier(buf.Bytes())
+}
+
+// newCopy returns a new copy of the profile.
+func (c profileCopier) newCopy() *profile.Profile {
+	p, err := profile.ParseUncompressed([]byte(c))
+	if err != nil {
+		panic(err)
+	}
+	return p
+}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/fetch.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/fetch.go
index 0b36165..5ddee33 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/fetch.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/fetch.go
@@ -18,7 +18,6 @@
 	"bytes"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"net/http"
 	"net/url"
 	"os"
@@ -167,7 +166,7 @@
 // a single profile. It fetches a chunk of profiles concurrently, with a maximum
 // chunk size to limit its memory usage.
 func chunkedGrab(sources []profileSource, fetch plugin.Fetcher, obj plugin.ObjTool, ui plugin.UI, tr http.RoundTripper) (*profile.Profile, plugin.MappingSources, bool, int, error) {
-	const chunkSize = 64
+	const chunkSize = 128
 
 	var p *profile.Profile
 	var msrc plugin.MappingSources
@@ -242,10 +241,22 @@
 
 func combineProfiles(profiles []*profile.Profile, msrcs []plugin.MappingSources) (*profile.Profile, plugin.MappingSources, error) {
 	// Merge profiles.
+	//
+	// The merge call below only treats exactly matching sample type lists as
+	// compatible and will fail otherwise. Make the profiles' sample types
+	// compatible for the merge, see CompatibilizeSampleTypes() doc for details.
+	if err := profile.CompatibilizeSampleTypes(profiles); err != nil {
+		return nil, nil, err
+	}
 	if err := measurement.ScaleProfiles(profiles); err != nil {
 		return nil, nil, err
 	}
 
+	// Avoid expensive work for the common case of a single profile/src.
+	if len(profiles) == 1 && len(msrcs) == 1 {
+		return profiles[0], msrcs[0], nil
+	}
+
 	p, err := profile.Merge(profiles)
 	if err != nil {
 		return nil, nil, err
@@ -410,6 +421,10 @@
 					fileNames = append(fileNames, matches...)
 				}
 				fileNames = append(fileNames, filepath.Join(path, m.File, m.BuildID)) // perf path format
+				// Llvm buildid protocol: the first two characters of the build id
+				// are used as directory, and the remaining part is in the filename.
+				// e.g. `/ab/cdef0123456.debug`
+				fileNames = append(fileNames, filepath.Join(path, m.BuildID[:2], m.BuildID[2:]+".debug"))
 			}
 			if m.File != "" {
 				// Try both the basename and the full path, to support the same directory
@@ -507,7 +522,7 @@
 func statusCodeError(resp *http.Response) error {
 	if resp.Header.Get("X-Go-Pprof") != "" && strings.Contains(resp.Header.Get("Content-Type"), "text/plain") {
 		// error is from pprof endpoint
-		if body, err := ioutil.ReadAll(resp.Body); err == nil {
+		if body, err := io.ReadAll(resp.Body); err == nil {
 			return fmt.Errorf("server response: %s - %s", resp.Status, body)
 		}
 	}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/common.css b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/common.css
index 03755ab..e0de53c 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/common.css
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/common.css
@@ -116,6 +116,7 @@
   box-shadow: 0 1px 5px rgba(0,0,0,.3);
   font-size: 100%;
   text-transform: none;
+  white-space: nowrap;
 }
 .menu-item, .submenu {
   user-select: none;
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/common.js b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/common.js
index 4fe3caa..5282c1b 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/common.js
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/common.js
@@ -388,7 +388,12 @@
   }
 }
 
-function viewer(baseUrl, nodes) {
+// options if present can contain:
+//   hiliter: function(Number, Boolean): Boolean
+//     Overridable mechanism for highlighting/unhighlighting specified node.
+//   current: function() Map[Number,Boolean]
+//     Overridable mechanism for fetching set of currently selected nodes.
+function viewer(baseUrl, nodes, options) {
   'use strict';
 
   // Elements
@@ -403,6 +408,16 @@
   let searchAlarm = null;
   let buttonsEnabled = true;
 
+  // Return current selection.
+  function getSelection() {
+    if (selected.size > 0) {
+      return selected;
+    } else if (options && options.current) {
+      return options.current();
+    }
+    return new Map();
+  }
+
   function handleDetails(e) {
     e.preventDefault();
     const detailsText = document.getElementById('detailsbox');
@@ -453,7 +468,7 @@
     // drop currently selected items that do not match re.
     selected.forEach(function(v, n) {
       if (!match(nodes[n])) {
-        unselect(n, document.getElementById('node' + n));
+        unselect(n);
       }
     })
 
@@ -461,7 +476,7 @@
     if (nodes) {
       for (let n = 0; n < nodes.length; n++) {
         if (!selected.has(n) && match(nodes[n])) {
-          select(n, document.getElementById('node' + n));
+          select(n);
         }
       }
     }
@@ -482,23 +497,19 @@
     const n = nodeId(elem);
     if (n < 0) return;
     if (selected.has(n)) {
-      unselect(n, elem);
+      unselect(n);
     } else {
-      select(n, elem);
+      select(n);
     }
     updateButtons();
   }
 
-  function unselect(n, elem) {
-    if (elem == null) return;
-    selected.delete(n);
-    setBackground(elem, false);
+  function unselect(n) {
+    if (setNodeHighlight(n, false)) selected.delete(n);
   }
 
   function select(n, elem) {
-    if (elem == null) return;
-    selected.set(n, true);
-    setBackground(elem, true);
+    if (setNodeHighlight(n, true)) selected.set(n, true);
   }
 
   function nodeId(elem) {
@@ -511,11 +522,17 @@
     return n;
   }
 
-  function setBackground(elem, set) {
+  // Change highlighting of node (returns true if node was found).
+  function setNodeHighlight(n, set) {
+    if (options && options.hiliter) return options.hiliter(n, set);
+
+    const elem = document.getElementById('node' + n);
+    if (!elem) return false;
+
     // Handle table row highlighting.
     if (elem.nodeName == 'TR') {
       elem.classList.toggle('hilite', set);
-      return;
+      return true;
     }
 
     // Handle svg element highlighting.
@@ -528,6 +545,8 @@
         p.style.fill = origFill.get(p);
       }
     }
+
+    return true;
   }
 
   function findPolygon(elem) {
@@ -575,8 +594,8 @@
       // The selection can be in one of two modes: regexp-based or
       // list-based.  Construct regular expression depending on mode.
       let re = regexpActive
-        ? search.value
-        : Array.from(selected.keys()).map(key => quotemeta(nodes[key])).join('|');
+          ? search.value
+          : Array.from(getSelection().keys()).map(key => quotemeta(nodes[key])).join('|');
 
       setHrefParams(elem, function (params) {
         if (re != '') {
@@ -639,7 +658,7 @@
   }
 
   function updateButtons() {
-    const enable = (search.value != '' || selected.size != 0);
+    const enable = (search.value != '' || getSelection().size != 0);
     if (buttonsEnabled == enable) return;
     buttonsEnabled = enable;
     for (const id of ['focus', 'ignore', 'hide', 'show', 'show-from']) {
@@ -663,8 +682,8 @@
     toptable.addEventListener('touchstart', handleTopClick);
   }
 
-  const ids = ['topbtn', 'graphbtn', 'flamegraph', 'peek', 'list', 'disasm',
-               'focus', 'ignore', 'hide', 'show', 'show-from'];
+  const ids = ['topbtn', 'graphbtn', 'flamegraph', 'flamegraph2', 'peek', 'list',
+	       'disasm', 'focus', 'ignore', 'hide', 'show', 'show-from'];
   ids.forEach(makeSearchLinkDynamic);
 
   const sampleIDs = [{{range .SampleTypes}}'{{.}}', {{end}}];
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/header.html b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/header.html
index 66cabbb..39cb55a 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/header.html
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/header.html
@@ -12,6 +12,7 @@
       <a title="{{.Help.top}}"  href="./top" id="topbtn">Top</a>
       <a title="{{.Help.graph}}" href="./" id="graphbtn">Graph</a>
       <a title="{{.Help.flamegraph}}" href="./flamegraph" id="flamegraph">Flame Graph</a>
+      <a title="{{.Help.flamegraph2}}" href="./flamegraph2" id="flamegraph2">Flame Graph (new)</a>
       <a title="{{.Help.peek}}" href="./peek" id="peek">Peek</a>
       <a title="{{.Help.list}}" href="./source" id="list">Source</a>
       <a title="{{.Help.disasm}}" href="./disasm" id="disasm">Disassemble</a>
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/stacks.css b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/stacks.css
new file mode 100644
index 0000000..d142aa7
--- /dev/null
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/stacks.css
@@ -0,0 +1,80 @@
+body {
+  overflow: hidden; /* Want scrollbar not here, but in #stack-holder */
+}
+/* Scrollable container for flame graph */
+#stack-holder {
+  width: 100%;
+  flex-grow: 1;
+  overflow-y: auto;
+  background: #eee; /* Light grey gives better contrast with boxes */
+  position: relative; /* Allows absolute positioning of child boxes */
+}
+/* Flame graph */
+#stack-chart {
+  width: 100%;
+  position: relative; /* Allows absolute positioning of child boxes */
+}
+/* Shows details of frame that is under the mouse */
+#current-details {
+  position: absolute;
+  top: 5px;
+  right: 5px;
+  z-index: 2;
+  font-size: 12pt;
+}
+/* Background of a single flame-graph frame */
+.boxbg {
+  border-width: 0px;
+  position: absolute;
+  overflow: hidden;
+  box-sizing: border-box;
+}
+/* Not-inlined frames are visually separated from their caller. */
+.not-inlined {
+  border-top: 1px solid black;
+}
+/* Function name */
+.boxtext {
+  position: absolute;
+  width: 100%;
+  padding-left: 2px;
+  line-height: 18px;
+  cursor: default;
+  font-family: "Google Sans", Arial, sans-serif;
+  font-size: 12pt;
+  z-index: 2;
+}
+/* Box highlighting via shadows to avoid size changes */
+.hilite { box-shadow: 0px 0px 0px 2px #000; z-index: 1; }
+.hilite2 { box-shadow: 0px 0px 0px 2px #000; z-index: 1; }
+/* Self-cost region inside a box */
+.self {
+  position: absolute;
+  background: rgba(0,0,0,0.25); /* Darker hue */
+}
+/* Gap left between callers and callees */
+.separator {
+  position: absolute;
+  text-align: center;
+  font-size: 12pt;
+  font-weight: bold;
+}
+/* Ensure that pprof menu is above boxes */
+.submenu { z-index: 3; }
+/* Right-click menu */
+#action-menu {
+  max-width: 15em;
+}
+/* Right-click menu title */
+#action-title {
+  display: block;
+  padding: 0.5em 1em;
+  background: #888;
+  text-overflow: ellipsis;
+  overflow: hidden;
+}
+/* Internal canvas used to measure text size when picking fonts */
+#textsizer {
+  position: absolute;
+  bottom: -100px;
+}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/stacks.html b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/stacks.html
new file mode 100644
index 0000000..1ddb7a3
--- /dev/null
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/stacks.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>{{.Title}}</title>
+  {{template "css" .}}
+  {{template "stacks_css"}}
+</head>
+<body>
+  {{template "header" .}}
+  <div id="stack-holder">
+    <div id="stack-chart"></div>
+    <div id="current-details"></div>
+  </div>
+  <div id="action-menu" class="submenu">
+    <span id="action-title"></span>
+    <hr>
+    <a title="{{.Help.list}}" id="action-source" href="./source">Show source code</a>
+    <a title="{{.Help.list}}" id="action-source-tab" href="./source" target="_blank">Show source in new tab</a>
+    <hr>
+    <a title="{{.Help.focus}}" id="action-focus" href="?">Focus</a>
+    <a title="{{.Help.ignore}}" id="action-ignore" href="?">Ignore</a>
+    <a title="{{.Help.hide}}" id="action-hide" href="?">Hide</a>
+    <a title="{{.Help.show_from}}" id="action-showfrom" href="?">Show from</a>
+  </div>
+  {{template "script" .}}
+  {{template "stacks_js"}}
+  <script>
+    stackViewer({{.Stacks}}, {{.Nodes}});
+  </script>
+</body>
+</html>
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/html/stacks.js b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/stacks.js
new file mode 100644
index 0000000..64229a0
--- /dev/null
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/html/stacks.js
@@ -0,0 +1,524 @@
+// stackViewer displays a flame-graph like view (extended to show callers).
+//   stacks - report.StackSet
+//   nodes  - List of names for each source in report.StackSet
+function stackViewer(stacks, nodes) {
+  'use strict';
+
+  // Constants used in rendering.
+  const ROW = 20;
+  const PADDING = 2;
+  const MIN_WIDTH = 4;
+  const MIN_TEXT_WIDTH = 16;
+  const TEXT_MARGIN = 2;
+  const FONT_SIZE = 12;
+  const MIN_FONT_SIZE = 8;
+
+  // Mapping from unit to a list of display scales/labels.
+  // List should be ordered by increasing unit size.
+  const UNITS = new Map([
+    ['B', [
+      ['B', 1],
+      ['kB', Math.pow(2, 10)],
+      ['MB', Math.pow(2, 20)],
+      ['GB', Math.pow(2, 30)],
+      ['TB', Math.pow(2, 40)],
+      ['PB', Math.pow(2, 50)]]],
+    ['s', [
+      ['ns', 1e-9],
+      ['µs', 1e-6],
+      ['ms', 1e-3],
+      ['s', 1],
+      ['hrs', 60*60]]]]);
+
+  // Fields
+  let shownTotal = 0;       // Total value of all stacks
+  let pivots = [];          // Indices of currently selected data.Sources entries.
+  let matches = new Set();  // Indices of sources that match search
+  let elems = new Map();    // Mapping from source index to display elements
+  let displayList = [];     // List of boxes to display.
+  let actionMenuOn = false; // Is action menu visible?
+  let actionTarget = null;  // Box on which action menu is operating.
+
+  // Setup to allow measuring text width.
+  const textSizer = document.createElement('canvas');
+  textSizer.id = 'textsizer';
+  const textContext = textSizer.getContext('2d');
+
+  // Get DOM elements.
+  const chart = find('stack-chart');
+  const search = find('search');
+  const actions = find('action-menu');
+  const actionTitle = find('action-title');
+  const detailBox = find('current-details');
+
+  window.addEventListener('resize', render);
+  window.addEventListener('popstate', render);
+  search.addEventListener('keydown', handleSearchKey);
+
+  // Withdraw action menu when clicking outside, or when item selected.
+  document.addEventListener('mousedown', (e) => {
+    if (!actions.contains(e.target)) {
+      hideActionMenu();
+    }
+  });
+  actions.addEventListener('click', hideActionMenu);
+
+  // Initialize menus and other general UI elements.
+  viewer(new URL(window.location.href), nodes, {
+    hiliter: (n, on) => { return hilite(n, on); },
+    current: () => {
+      let r = new Map();
+      for (let p of pivots) {
+        r.set(p, true);
+      }
+      return r;
+    }});
+
+  render();
+
+  // Helper functions follow:
+
+  // hilite changes the highlighting of elements corresponding to specified src.
+  function hilite(src, on) {
+    if (on) {
+      matches.add(src);
+    } else {
+      matches.delete(src);
+    }
+    toggleClass(src, 'hilite', on);
+    return true;
+  }
+
+  // Display action menu (triggered by right-click on a frame)
+  function showActionMenu(e, box) {
+    if (box.src == 0) return; // No action menu for root
+    e.preventDefault(); // Disable browser context menu
+    const src = stacks.Sources[box.src];
+    actionTitle.innerText = src.Display[src.Display.length-1];
+    const menu = actions;
+    menu.style.display = 'block';
+    // Compute position so menu stays visible and near the mouse.
+    const x = Math.min(e.clientX - 10, document.body.clientWidth - menu.clientWidth);
+    const y = Math.min(e.clientY - 10, document.body.clientHeight - menu.clientHeight);
+    menu.style.left = x + 'px';
+    menu.style.top = y + 'px';
+    // Set menu links to operate on clicked box.
+    setHrefParam('action-source', 'f', box.src);
+    setHrefParam('action-source-tab', 'f', box.src);
+    setHrefParam('action-focus', 'f', box.src);
+    setHrefParam('action-ignore', 'i', box.src);
+    setHrefParam('action-hide', 'h', box.src);
+    setHrefParam('action-showfrom', 'sf', box.src);
+    toggleClass(box.src, 'hilite2', true);
+    actionTarget = box;
+    actionMenuOn = true;
+  }
+
+  function hideActionMenu() {
+    actions.style.display = 'none';
+    actionMenuOn = false;
+    if (actionTarget != null) {
+      toggleClass(actionTarget.src, 'hilite2', false);
+    }
+  }
+
+  // setHrefParam updates the specified parameter in the  href of an <a>
+  // element to make it operate on the specified src.
+  function setHrefParam(id, param, src) {
+    const elem = document.getElementById(id);
+    if (!elem) return;
+
+    let url = new URL(elem.href);
+    url.hash = '';
+
+    // Copy params from this page's URL.
+    const params = url.searchParams;
+    for (const p of new URLSearchParams(window.location.search)) {
+      params.set(p[0], p[1]);
+    }
+
+    // Update params to include src.
+    let v = stacks.Sources[src].RE;
+    if (param != 'f' && param != 'sf') { // old f,sf values are overwritten
+      // Add new source to current parameter value.
+      const old = params.get(param);
+      if (old && old != '') {
+        v += '|' + old;
+      }
+    }
+    params.set(param, v);
+
+    elem.href = url.toString();
+  }
+
+  // Capture Enter key in the search box to make it pivot instead of focus.
+  function handleSearchKey(e) {
+    if (e.key != 'Enter') return;
+    e.stopImmediatePropagation();  // Disable normal enter key handling
+    const val = search.value;
+    try {
+      new RegExp(search.value);
+    } catch (error) {
+      return;  // TODO: Display error state in search box
+    }
+    switchPivots(val);
+  }
+
+  function switchPivots(regexp) {
+    // Switch URL without hitting the server.
+    const url = new URL(document.URL);
+    url.searchParams.set('p', regexp);
+    history.pushState('', '', url.toString()); // Makes back-button work
+    matches = new Set();
+    search.value = '';
+    render();
+  }
+
+  function handleEnter(box, div) {
+    if (actionMenuOn) return;
+    const src = stacks.Sources[box.src];
+    const d = details(box);
+    div.title = d + ' ' + src.FullName + (src.Inlined ? "\n(inlined)" : "");
+    detailBox.innerText = d;
+    // Highlight all boxes that have the same source as box.
+    toggleClass(box.src, 'hilite2', true);
+  }
+
+  function handleLeave(box) {
+    if (actionMenuOn) return;
+    detailBox.innerText = '';
+    toggleClass(box.src, 'hilite2', false);
+  }
+
+  // Return list of sources that match the regexp given by the 'p' URL parameter.
+  function urlPivots() {
+    const pivots = [];
+    const params = (new URL(document.URL)).searchParams;
+    const val = params.get('p');
+    if (val !== null && val != '') {
+      try {
+        const re = new RegExp(val);
+        for (let i = 0; i < stacks.Sources.length; i++) {
+          const src = stacks.Sources[i];
+          if (re.test(src.UniqueName) || re.test(src.FileName)) {
+            pivots.push(i);
+          }
+        }
+      } catch (error) {}
+    }
+    if (pivots.length == 0) {
+      pivots.push(0);
+    }
+    return pivots;
+  }
+
+  // render re-generates the stack display.
+  function render() {
+    pivots = urlPivots();
+
+    // Get places where pivots occur.
+    let places = [];
+    for (let pivot of pivots) {
+      const src = stacks.Sources[pivot];
+      for (let p of src.Places) {
+        places.push(p);
+      }
+    }
+
+    const width = chart.clientWidth;
+    elems.clear();
+    actionTarget = null;
+    const total = totalValue(places);
+    const xscale = (width-2*PADDING) / total; // Converts from profile value to X pixels
+    const x = PADDING;
+    const y = 0;
+    shownTotal = total;
+
+    displayList.length = 0;
+    renderStacks(0, xscale, x, y, places, +1);  // Callees
+    renderStacks(0, xscale, x, y-ROW, places, -1);  // Callers (ROW left for separator)
+    display(displayList);
+  }
+
+  // renderStacks creates boxes with top-left at x,y with children drawn as
+  // nested stacks (below or above based on the sign of direction).
+  // Returns the largest y coordinate filled.
+  function renderStacks(depth, xscale, x, y, places, direction) {
+    // Example: suppose we are drawing the following stacks:
+    //   a->b->c
+    //   a->b->d
+    //   a->e->f
+    // After rendering a, we will call renderStacks, with places pointing to
+    // the preceding stacks.
+    //
+    // We first group all places with the same leading entry. In this example
+    // we get [b->c, b->d] and [e->f]. We render the two groups side-by-side.
+    const groups = partitionPlaces(places);
+    for (const g of groups) {
+      renderGroup(depth, xscale, x, y, g, direction);
+      x += xscale*g.sum;
+    }
+  }
+
+  function renderGroup(depth, xscale, x, y, g, direction) {
+    // Skip if not wide enough.
+    const width = xscale * g.sum;
+    if (width < MIN_WIDTH) return;
+
+    // Draw the box for g.src (except for selected element in upwards direction
+    // since that duplicates the box we added in downwards direction).
+    if (depth != 0 || direction > 0) {
+      const box = {
+        x:         x,
+        y:         y,
+        src:       g.src,
+        sum:       g.sum,
+        selfValue: g.self,
+        width:     xscale*g.sum,
+        selfWidth: (direction > 0) ? xscale*g.self : 0,
+      };
+      displayList.push(box);
+      x += box.selfWidth;
+    }
+    y += direction * ROW;
+
+    // Find child or parent stacks.
+    const next = [];
+    for (const place of g.places) {
+      const stack = stacks.Stacks[place.Stack];
+      const nextSlot = place.Pos + direction;
+      if (nextSlot >= 0 && nextSlot < stack.Sources.length) {
+        next.push({Stack: place.Stack, Pos: nextSlot});
+      }
+    }
+    renderStacks(depth+1, xscale, x, y, next, direction);
+  }
+
+  // partitionPlaces partitions a set of places into groups where each group
+  // contains places with the same source. If a stack occurs multiple times
+  // in places, only the outer-most occurrence is kept.
+  function partitionPlaces(places) {
+    // Find outer-most slot per stack (used later to elide duplicate stacks).
+    const stackMap = new Map();  // Map from stack index to outer-most slot#
+    for (const place of places) {
+      const prevSlot = stackMap.get(place.Stack);
+      if (prevSlot && prevSlot <= place.Pos) {
+        // We already have a higher slot in this stack.
+      } else {
+        stackMap.set(place.Stack, place.Pos);
+      }
+    }
+
+    // Now partition the stacks.
+    const groups = [];           // Array of Group {name, src, sum, self, places}
+    const groupMap = new Map();  // Map from Source to Group
+    for (const place of places) {
+      if (stackMap.get(place.Stack) != place.Pos) {
+        continue;
+      }
+
+      const stack = stacks.Stacks[place.Stack];
+      const src = stack.Sources[place.Pos];
+      let group = groupMap.get(src);
+      if (!group) {
+        const name = stacks.Sources[src].FullName;
+        group = {name: name, src: src, sum: 0, self: 0, places: []};
+        groupMap.set(src, group);
+        groups.push(group);
+      }
+      group.sum += stack.Value;
+      group.self += (place.Pos == stack.Sources.length-1) ? stack.Value : 0;
+      group.places.push(place);
+    }
+
+    // Order by decreasing cost (makes it easier to spot heavy functions).
+    // Though alphabetical ordering is a potential alternative that will make
+    // profile comparisons easier.
+    groups.sort(function(a, b) { return b.sum - a.sum; });
+
+    return groups;
+  }
+
+  function display(list) {
+    // Sort boxes so that text selection follows a predictable order.
+    list.sort(function(a, b) {
+      if (a.y != b.y) return a.y - b.y;
+      return a.x - b.x;
+    });
+
+    // Adjust Y coordinates so that zero is at top.
+    let adjust = (list.length > 0) ? list[0].y : 0;
+    adjust -= ROW + 2*PADDING;  // Room for details
+
+    const divs = [];
+    for (const box of list) {
+      box.y -= adjust;
+      divs.push(drawBox(box));
+    }
+    divs.push(drawSep(-adjust));
+
+    const h = (list.length > 0 ?  list[list.length-1].y : 0) + 4*ROW;
+    chart.style.height = h+'px';
+    chart.replaceChildren(...divs);
+  }
+
+  function drawBox(box) {
+    const srcIndex = box.src;
+    const src = stacks.Sources[srcIndex];
+
+    // Background
+    const w = box.width - 1; // Leave 1px gap
+    const r = document.createElement('div');
+    r.style.left = box.x + 'px';
+    r.style.top = box.y + 'px';
+    r.style.width = w + 'px';
+    r.style.height = ROW + 'px';
+    r.classList.add('boxbg');
+    r.style.background = makeColor(src.Color);
+    addElem(srcIndex, r);
+    if (!src.Inlined) {
+      r.classList.add('not-inlined');
+    }
+
+    // Box that shows time spent in self
+    if (box.selfWidth >= MIN_WIDTH) {
+      const s = document.createElement('div');
+      s.style.width = Math.min(box.selfWidth, w)+'px';
+      s.style.height = (ROW-1)+'px';
+      s.classList.add('self');
+      r.appendChild(s);
+    }
+
+    // Label
+    if (box.width >= MIN_TEXT_WIDTH) {
+      const t = document.createElement('div');
+      t.classList.add('boxtext');
+      fitText(t, box.width-2*TEXT_MARGIN, src.Display);
+      r.appendChild(t);
+    }
+
+    r.addEventListener('click', () => { switchPivots(src.RE); });
+    r.addEventListener('mouseenter', () => { handleEnter(box, r); });
+    r.addEventListener('mouseleave', () => { handleLeave(box); });
+    r.addEventListener('contextmenu', (e) => { showActionMenu(e, box); });
+    return r;
+  }
+
+  function drawSep(y) {
+    const m = document.createElement('div');
+    m.innerText = percent(shownTotal, stacks.Total) +
+	'\xa0\xa0\xa0\xa0' +  // Some non-breaking spaces
+	valueString(shownTotal);
+    m.style.top = (y-ROW) + 'px';
+    m.style.left = PADDING + 'px';
+    m.style.width = (chart.clientWidth - PADDING*2) + 'px';
+    m.classList.add('separator');
+    return m;
+  }
+
+  // addElem registers an element that belongs to the specified src.
+  function addElem(src, elem) {
+    let list = elems.get(src);
+    if (!list) {
+      list = [];
+      elems.set(src, list);
+    }
+    list.push(elem);
+    elem.classList.toggle('hilite', matches.has(src));
+  }
+
+  // Adds or removes cl from classList of all elements for the specified source.
+  function toggleClass(src, cl, value) {
+    const list = elems.get(src);
+    if (list) {
+      for (const elem of list) {
+        elem.classList.toggle(cl, value);
+      }
+    }
+  }
+
+  // fitText sets text and font-size clipped to the specified width w.
+  function fitText(t, avail, textList) {
+    // Find first entry in textList that fits.
+    let width = avail;
+    textContext.font = FONT_SIZE + 'pt Arial';
+    for (let i = 0; i < textList.length; i++) {
+      let text = textList[i];
+      width = textContext.measureText(text).width;
+      if (width <= avail) {
+        t.innerText = text;
+        return;
+      }
+    }
+
+    // Try to fit by dropping font size.
+    let text = textList[textList.length-1];
+    const fs = Math.max(MIN_FONT_SIZE, FONT_SIZE * (avail / width));
+    t.style.fontSize = fs + 'pt';
+    t.innerText = text;
+  }
+
+  // totalValue returns the combined sum of the stacks listed in places.
+  function totalValue(places) {
+    const seen = new Set();
+    let result = 0;
+    for (const place of places) {
+      if (seen.has(place.Stack)) continue; // Do not double-count stacks
+      seen.add(place.Stack);
+      const stack = stacks.Stacks[place.Stack];
+      result += stack.Value;
+    }
+    return result;
+  }
+
+  function details(box) {
+    // E.g., 10% 7s
+    // or    10% 7s (3s self
+    let result = percent(box.sum, stacks.Total) + ' ' + valueString(box.sum);
+    if (box.selfValue > 0) {
+      result += ` (${valueString(box.selfValue)} self)`;
+    }
+    return result;
+  }
+
+  function percent(v, total) {
+    return Number(((100.0 * v) / total).toFixed(1)) + '%';
+  }
+
+  // valueString returns a formatted string to display for value.
+  function valueString(value) {
+    let v = value * stacks.Scale;
+    // Rescale to appropriate display unit.
+    let unit = stacks.Unit;
+    const list = UNITS.get(unit);
+    if (list) {
+      // Find first entry in list that is not too small.
+      for (const [name, scale] of list) {
+        if (v <= 100*scale) {
+          v /= scale;
+          unit = name;
+          break;
+        }
+      }
+    }
+    return Number(v.toFixed(2)) + unit;
+  }
+
+  function find(name) {
+    const elem = document.getElementById(name);
+    if (!elem) {
+      throw 'element not found: ' + name
+    }
+    return elem;
+  }
+
+  function makeColor(index) {
+    // Rotate hue around a circle. Multiple by phi to spread things
+    // out better. Use 50% saturation to make subdued colors, and
+    // 80% lightness to have good contrast with black foreground text.
+    const PHI = 1.618033988;
+    const hue = (index+1) * PHI * 2 * Math.PI; // +1 to avoid 0
+    const hsl = `hsl(${hue}rad 50% 80%)`;
+    return hsl;
+  }
+}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/interactive.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/interactive.go
index 777fb90..e6e865f 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/interactive.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/interactive.go
@@ -42,6 +42,7 @@
 	interactiveMode = true
 	shortcuts := profileShortcuts(p)
 
+	copier := makeProfileCopier(p)
 	greetings(p, o.UI)
 	for {
 		input, err := o.UI.ReadLine("(pprof) ")
@@ -110,7 +111,7 @@
 
 			args, cfg, err := parseCommandLine(tokens)
 			if err == nil {
-				err = generateReportWrapper(p, args, cfg, o)
+				err = generateReportWrapper(copier.newCopy(), args, cfg, o)
 			}
 
 			if err != nil {
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/settings.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/settings.go
index f72314b..b784618 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/settings.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/settings.go
@@ -3,7 +3,6 @@
 import (
 	"encoding/json"
 	"fmt"
-	"io/ioutil"
 	"net/url"
 	"os"
 	"path/filepath"
@@ -33,7 +32,7 @@
 
 // readSettings reads settings from fname.
 func readSettings(fname string) (*settings, error) {
-	data, err := ioutil.ReadFile(fname)
+	data, err := os.ReadFile(fname)
 	if err != nil {
 		if os.IsNotExist(err) {
 			return &settings{}, nil
@@ -64,7 +63,7 @@
 		return fmt.Errorf("failed to create settings directory: %w", err)
 	}
 
-	if err := ioutil.WriteFile(fname, data, 0644); err != nil {
+	if err := os.WriteFile(fname, data, 0644); err != nil {
 		return fmt.Errorf("failed to write settings: %w", err)
 	}
 	return nil
@@ -79,7 +78,7 @@
 }
 
 // configMenu returns a list of items to add to a menu in the web UI.
-func configMenu(fname string, url url.URL) []configMenuEntry {
+func configMenu(fname string, u url.URL) []configMenuEntry {
 	// Start with system configs.
 	configs := []namedConfig{{Name: "Default", config: defaultConfig()}}
 	if settings, err := readSettings(fname); err == nil {
@@ -91,13 +90,15 @@
 	result := make([]configMenuEntry, len(configs))
 	lastMatch := -1
 	for i, cfg := range configs {
-		dst, changed := cfg.config.makeURL(url)
+		dst, changed := cfg.config.makeURL(u)
 		if !changed {
 			lastMatch = i
 		}
+		// Use a relative URL to work in presence of stripping/redirects in webui.go.
+		rel := &url.URL{RawQuery: dst.RawQuery, ForceQuery: true}
 		result[i] = configMenuEntry{
 			Name:       cfg.Name,
-			URL:        dst.String(),
+			URL:        rel.String(),
 			UserConfig: (i != 0),
 		}
 	}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/stacks.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/stacks.go
new file mode 100644
index 0000000..249dfe0
--- /dev/null
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/stacks.go
@@ -0,0 +1,58 @@
+// Copyright 2022 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package driver
+
+import (
+	"encoding/json"
+	"html/template"
+	"net/http"
+
+	"github.com/google/pprof/internal/report"
+)
+
+// stackView generates the new flamegraph view.
+func (ui *webInterface) stackView(w http.ResponseWriter, req *http.Request) {
+	// Get all data in a report.
+	rpt, errList := ui.makeReport(w, req, []string{"svg"}, func(cfg *config) {
+		cfg.CallTree = true
+		cfg.Trim = false
+		cfg.Granularity = "filefunctions"
+	})
+	if rpt == nil {
+		return // error already reported
+	}
+
+	// Make stack data and generate corresponding JSON.
+	stacks := rpt.Stacks()
+	b, err := json.Marshal(stacks)
+	if err != nil {
+		http.Error(w, "error serializing stacks for flame graph",
+			http.StatusInternalServerError)
+		ui.options.UI.PrintErr(err)
+		return
+	}
+
+	nodes := make([]string, len(stacks.Sources))
+	for i, src := range stacks.Sources {
+		nodes[i] = src.FullName
+	}
+	nodes[0] = "" // root is not a real node
+
+	_, legend := report.TextItems(rpt)
+	ui.render(w, req, "stacks", rpt, errList, legend, webArgs{
+		Stacks: template.JS(b),
+		Nodes:  nodes,
+	})
+}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/tagroot.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/tagroot.go
index c43d599..76a594d 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/tagroot.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/tagroot.go
@@ -97,6 +97,10 @@
 			leafm = true
 		}
 
+		if len(leavesToAdd)+len(rootsToAdd) == 0 {
+			continue
+		}
+
 		var newLocs []*profile.Location
 		newLocs = append(newLocs, leavesToAdd...)
 		newLocs = append(newLocs, s.Location...)
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/webhtml.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/webhtml.go
index 94f32e3..55973ff 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/webhtml.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/webhtml.go
@@ -65,4 +65,7 @@
 	def("sourcelisting", loadFile("html/source.html"))
 	def("plaintext", loadFile("html/plaintext.html"))
 	def("flamegraph", loadFile("html/flamegraph.html"))
+	def("stacks", loadFile("html/stacks.html"))
+	def("stacks_css", loadCSS("html/stacks.css"))
+	def("stacks_js", loadJS("html/stacks.js"))
 }
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/driver/webui.go b/src/cmd/vendor/github.com/google/pprof/internal/driver/webui.go
index 0f3e8bf..8881e39 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/driver/webui.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/driver/webui.go
@@ -36,13 +36,14 @@
 // webInterface holds the state needed for serving a browser based interface.
 type webInterface struct {
 	prof         *profile.Profile
+	copier       profileCopier
 	options      *plugin.Options
 	help         map[string]string
 	templates    *template.Template
 	settingsFile string
 }
 
-func makeWebInterface(p *profile.Profile, opt *plugin.Options) (*webInterface, error) {
+func makeWebInterface(p *profile.Profile, copier profileCopier, opt *plugin.Options) (*webInterface, error) {
 	settingsFile, err := settingsFileName()
 	if err != nil {
 		return nil, err
@@ -52,6 +53,7 @@
 	report.AddSourceTemplates(templates)
 	return &webInterface{
 		prof:         p,
+		copier:       copier,
 		options:      opt,
 		help:         make(map[string]string),
 		templates:    templates,
@@ -86,6 +88,7 @@
 	TextBody    string
 	Top         []report.TextItem
 	FlameGraph  template.JS
+	Stacks      template.JS
 	Configs     []configMenuEntry
 }
 
@@ -95,7 +98,8 @@
 		return err
 	}
 	interactiveMode = true
-	ui, err := makeWebInterface(p, o)
+	copier := makeProfileCopier(p)
+	ui, err := makeWebInterface(p, copier, o)
 	if err != nil {
 		return err
 	}
@@ -107,6 +111,8 @@
 	}
 	ui.help["details"] = "Show information about the profile and this view"
 	ui.help["graph"] = "Display profile as a directed graph"
+	ui.help["flamegraph"] = "Display profile as a flame graph"
+	ui.help["flamegraph2"] = "Display profile as a flame graph (experimental version that can display caller info on selection)"
 	ui.help["reset"] = "Show the entire profile"
 	ui.help["save_config"] = "Save current settings"
 
@@ -125,6 +131,7 @@
 			"/source":       http.HandlerFunc(ui.source),
 			"/peek":         http.HandlerFunc(ui.peek),
 			"/flamegraph":   http.HandlerFunc(ui.flamegraph),
+			"/flamegraph2":  http.HandlerFunc(ui.stackView), // Experimental
 			"/saveconfig":   http.HandlerFunc(ui.saveConfig),
 			"/deleteconfig": http.HandlerFunc(ui.deleteConfig),
 			"/download": http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
@@ -262,7 +269,7 @@
 	catcher := &errorCatcher{UI: ui.options.UI}
 	options := *ui.options
 	options.UI = catcher
-	_, rpt, err := generateRawReport(ui.prof, cmd, cfg, &options)
+	_, rpt, err := generateRawReport(ui.copier.newCopy(), cmd, cfg, &options)
 	if err != nil {
 		http.Error(w, err.Error(), http.StatusBadRequest)
 		ui.options.UI.PrintErr(err)
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/graph/dotgraph.go b/src/cmd/vendor/github.com/google/pprof/internal/graph/dotgraph.go
index 9ff4c95..09d40fd 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/graph/dotgraph.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/graph/dotgraph.go
@@ -385,6 +385,9 @@
 	infoCopy := *info
 	infoCopy.Name = escapeForDot(ShortenFunctionName(infoCopy.Name))
 	infoCopy.Name = strings.Replace(infoCopy.Name, "::", `\n`, -1)
+	// Go type parameters are reported as "[...]" by Go pprof profiles.
+	// Keep this ellipsis rather than replacing with newlines below.
+	infoCopy.Name = strings.Replace(infoCopy.Name, "[...]", "[…]", -1)
 	infoCopy.Name = strings.Replace(infoCopy.Name, ".", `\n`, -1)
 	if infoCopy.File != "" {
 		infoCopy.File = filepath.Base(infoCopy.File)
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/report/package.go b/src/cmd/vendor/github.com/google/pprof/internal/report/package.go
new file mode 100644
index 0000000..6d53859
--- /dev/null
+++ b/src/cmd/vendor/github.com/google/pprof/internal/report/package.go
@@ -0,0 +1,17 @@
+package report
+
+import "regexp"
+
+// pkgRE extracts package name, It looks for the first "." or "::" that occurs
+// after the last "/". (Searching after the last / allows us to correctly handle
+// names that look like "some.url.com/foo.bar".
+var pkgRE = regexp.MustCompile(`^((.*/)?[\w\d_]+)(\.|::)([^/]*)$`)
+
+// packageName returns the package name of the named symbol, or "" if not found.
+func packageName(name string) string {
+	m := pkgRE.FindStringSubmatch(name)
+	if m == nil {
+		return ""
+	}
+	return m[1]
+}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/report/shortnames.go b/src/cmd/vendor/github.com/google/pprof/internal/report/shortnames.go
new file mode 100644
index 0000000..3d9f3f4
--- /dev/null
+++ b/src/cmd/vendor/github.com/google/pprof/internal/report/shortnames.go
@@ -0,0 +1,39 @@
+// Copyright 2022 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package report
+
+import (
+	"regexp"
+
+	"github.com/google/pprof/internal/graph"
+)
+
+var sepRE = regexp.MustCompile(`::|\.`)
+
+// shortNameList returns a non-empty sequence of shortened names
+// (in decreasing preference) that can be used to represent name.
+func shortNameList(name string) []string {
+	name = graph.ShortenFunctionName(name)
+	seps := sepRE.FindAllStringIndex(name, -1)
+	result := make([]string, 0, len(seps)+1)
+	result = append(result, name)
+	for _, sep := range seps {
+		// Suffix starting just after sep
+		if sep[1] < len(name) {
+			result = append(result, name[sep[1]:])
+		}
+	}
+	return result
+}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/report/stacks.go b/src/cmd/vendor/github.com/google/pprof/internal/report/stacks.go
new file mode 100644
index 0000000..7db51bc
--- /dev/null
+++ b/src/cmd/vendor/github.com/google/pprof/internal/report/stacks.go
@@ -0,0 +1,194 @@
+// Copyright 2022 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package report
+
+import (
+	"crypto/sha256"
+	"encoding/binary"
+	"fmt"
+	"regexp"
+
+	"github.com/google/pprof/internal/measurement"
+	"github.com/google/pprof/profile"
+)
+
+// StackSet holds a set of stacks corresponding to a profile.
+//
+// Slices in StackSet and the types it contains are always non-nil,
+// which makes Javascript code that uses the JSON encoding less error-prone.
+type StackSet struct {
+	Total   int64         // Total value of the profile.
+	Scale   float64       // Multiplier to generate displayed value
+	Type    string        // Profile type. E.g., "cpu".
+	Unit    string        // One of "B", "s", "GCU", or "" (if unknown)
+	Stacks  []Stack       // List of stored stacks
+	Sources []StackSource // Mapping from source index to info
+}
+
+// Stack holds a single stack instance.
+type Stack struct {
+	Value   int64 // Total value for all samples of this stack.
+	Sources []int // Indices in StackSet.Sources (callers before callees).
+}
+
+// StackSource holds function/location info for a stack entry.
+type StackSource struct {
+	FullName   string
+	FileName   string
+	UniqueName string // Disambiguates functions with same names
+	Inlined    bool   // If true this source was inlined into its caller
+
+	// Alternative names to display (with decreasing lengths) to make text fit.
+	// Guaranteed to be non-empty.
+	Display []string
+
+	// Regular expression (anchored) that matches exactly FullName.
+	RE string
+
+	// Places holds the list of stack slots where this source occurs.
+	// In particular, if [a,b] is an element in Places,
+	// StackSet.Stacks[a].Sources[b] points to this source.
+	//
+	// No stack will be referenced twice in the Places slice for a given
+	// StackSource. In case of recursion, Places will contain the outer-most
+	// entry in the recursive stack. E.g., if stack S has source X at positions
+	// 4,6,9,10, the Places entry for X will contain [S,4].
+	Places []StackSlot
+
+	// Combined count of stacks where this source is the leaf.
+	Self int64
+
+	// Color number to use for this source.
+	// Colors with high numbers than supported may be treated as zero.
+	Color int
+}
+
+// StackSlot identifies a particular StackSlot.
+type StackSlot struct {
+	Stack int // Index in StackSet.Stacks
+	Pos   int // Index in Stack.Sources
+}
+
+// Stacks returns a StackSet for the profile in rpt.
+func (rpt *Report) Stacks() StackSet {
+	// Get scale for converting to default unit of the right type.
+	scale, unit := measurement.Scale(1, rpt.options.SampleUnit, "default")
+	if unit == "default" {
+		unit = ""
+	}
+	if rpt.options.Ratio > 0 {
+		scale *= rpt.options.Ratio
+	}
+	s := &StackSet{
+		Total:   rpt.total,
+		Scale:   scale,
+		Type:    rpt.options.SampleType,
+		Unit:    unit,
+		Stacks:  []Stack{},       // Ensure non-nil
+		Sources: []StackSource{}, // Ensure non-nil
+	}
+	s.makeInitialStacks(rpt)
+	s.fillPlaces()
+	s.assignColors()
+	return *s
+}
+
+func (s *StackSet) makeInitialStacks(rpt *Report) {
+	type key struct {
+		line    profile.Line
+		inlined bool
+	}
+	srcs := map[key]int{} // Sources identified so far.
+	seenFunctions := map[string]bool{}
+	unknownIndex := 1
+	getSrc := func(line profile.Line, inlined bool) int {
+		k := key{line, inlined}
+		if i, ok := srcs[k]; ok {
+			return i
+		}
+		x := StackSource{Places: []StackSlot{}} // Ensure Places is non-nil
+		if fn := line.Function; fn != nil {
+			x.FullName = fn.Name
+			x.FileName = fn.Filename
+			if !seenFunctions[fn.Name] {
+				x.UniqueName = fn.Name
+				seenFunctions[fn.Name] = true
+			} else {
+				// Assign a different name so pivoting picks this function.
+				x.UniqueName = fmt.Sprint(fn.Name, "#", fn.ID)
+			}
+		} else {
+			x.FullName = fmt.Sprintf("?%d?", unknownIndex)
+			x.UniqueName = x.FullName
+			unknownIndex++
+		}
+		x.Inlined = inlined
+		x.RE = "^" + regexp.QuoteMeta(x.UniqueName) + "$"
+		x.Display = shortNameList(x.FullName)
+		s.Sources = append(s.Sources, x)
+		srcs[k] = len(s.Sources) - 1
+		return len(s.Sources) - 1
+	}
+
+	// Synthesized root location that will be placed at the beginning of each stack.
+	s.Sources = []StackSource{{
+		FullName: "root",
+		Display:  []string{"root"},
+		Places:   []StackSlot{},
+	}}
+
+	for _, sample := range rpt.prof.Sample {
+		value := rpt.options.SampleValue(sample.Value)
+		stack := Stack{Value: value, Sources: []int{0}} // Start with the root
+
+		// Note: we need to reverse the order in the produced stack.
+		for i := len(sample.Location) - 1; i >= 0; i-- {
+			loc := sample.Location[i]
+			for j := len(loc.Line) - 1; j >= 0; j-- {
+				line := loc.Line[j]
+				inlined := (j != len(loc.Line)-1)
+				stack.Sources = append(stack.Sources, getSrc(line, inlined))
+			}
+		}
+
+		leaf := stack.Sources[len(stack.Sources)-1]
+		s.Sources[leaf].Self += value
+		s.Stacks = append(s.Stacks, stack)
+	}
+}
+
+func (s *StackSet) fillPlaces() {
+	for i, stack := range s.Stacks {
+		seenSrcs := map[int]bool{}
+		for j, src := range stack.Sources {
+			if seenSrcs[src] {
+				continue
+			}
+			seenSrcs[src] = true
+			s.Sources[src].Places = append(s.Sources[src].Places, StackSlot{i, j})
+		}
+	}
+}
+
+func (s *StackSet) assignColors() {
+	// Assign different color indices to different packages.
+	const numColors = 1048576
+	for i, src := range s.Sources {
+		pkg := packageName(src.FullName)
+		h := sha256.Sum256([]byte(pkg))
+		index := binary.LittleEndian.Uint32(h[:])
+		s.Sources[i].Color = int(index % numColors)
+	}
+}
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/symbolizer/symbolizer.go b/src/cmd/vendor/github.com/google/pprof/internal/symbolizer/symbolizer.go
index cbb0ed4..87f202b 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/symbolizer/symbolizer.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/symbolizer/symbolizer.go
@@ -19,7 +19,7 @@
 
 import (
 	"fmt"
-	"io/ioutil"
+	"io"
 	"net/http"
 	"net/url"
 	"path/filepath"
@@ -110,13 +110,13 @@
 	if resp.StatusCode != http.StatusOK {
 		return nil, fmt.Errorf("http post %s: %v", source, statusCodeError(resp))
 	}
-	return ioutil.ReadAll(resp.Body)
+	return io.ReadAll(resp.Body)
 }
 
 func statusCodeError(resp *http.Response) error {
 	if resp.Header.Get("X-Go-Pprof") != "" && strings.Contains(resp.Header.Get("Content-Type"), "text/plain") {
 		// error is from pprof endpoint
-		if body, err := ioutil.ReadAll(resp.Body); err == nil {
+		if body, err := io.ReadAll(resp.Body); err == nil {
 			return fmt.Errorf("server response: %s - %s", resp.Status, body)
 		}
 	}
@@ -205,49 +205,64 @@
 		}
 	}
 
-	var options []demangle.Option
+	options := demanglerModeToOptions(demanglerMode)
+	for _, fn := range prof.Function {
+		demangleSingleFunction(fn, options)
+	}
+}
+
+func demanglerModeToOptions(demanglerMode string) []demangle.Option {
 	switch demanglerMode {
 	case "": // demangled, simplified: no parameters, no templates, no return type
-		options = []demangle.Option{demangle.NoParams, demangle.NoTemplateParams}
+		return []demangle.Option{demangle.NoParams, demangle.NoTemplateParams}
 	case "templates": // demangled, simplified: no parameters, no return type
-		options = []demangle.Option{demangle.NoParams}
+		return []demangle.Option{demangle.NoParams}
 	case "full":
-		options = []demangle.Option{demangle.NoClones}
+		return []demangle.Option{demangle.NoClones}
 	case "none": // no demangling
-		return
+		return []demangle.Option{}
 	}
 
+	panic(fmt.Sprintf("unknown demanglerMode %s", demanglerMode))
+}
+
+func demangleSingleFunction(fn *profile.Function, options []demangle.Option) {
+	if fn.Name != "" && fn.SystemName != fn.Name {
+		return // Already demangled.
+	}
 	// Copy the options because they may be updated by the call.
 	o := make([]demangle.Option, len(options))
-	for _, fn := range prof.Function {
-		if fn.Name != "" && fn.SystemName != fn.Name {
-			continue // Already demangled.
-		}
-		copy(o, options)
-		if demangled := demangle.Filter(fn.SystemName, o...); demangled != fn.SystemName {
-			fn.Name = demangled
-			continue
-		}
-		// Could not demangle. Apply heuristics in case the name is
-		// already demangled.
-		name := fn.SystemName
-		if looksLikeDemangledCPlusPlus(name) {
-			if demanglerMode == "" || demanglerMode == "templates" {
+	copy(o, options)
+	if demangled := demangle.Filter(fn.SystemName, o...); demangled != fn.SystemName {
+		fn.Name = demangled
+		return
+	}
+	// Could not demangle. Apply heuristics in case the name is
+	// already demangled.
+	name := fn.SystemName
+	if looksLikeDemangledCPlusPlus(name) {
+		for _, o := range options {
+			switch o {
+			case demangle.NoParams:
 				name = removeMatching(name, '(', ')')
-			}
-			if demanglerMode == "" {
+			case demangle.NoTemplateParams:
 				name = removeMatching(name, '<', '>')
 			}
 		}
-		fn.Name = name
 	}
+	fn.Name = name
 }
 
 // looksLikeDemangledCPlusPlus is a heuristic to decide if a name is
 // the result of demangling C++. If so, further heuristics will be
 // applied to simplify the name.
 func looksLikeDemangledCPlusPlus(demangled string) bool {
-	if strings.Contains(demangled, ".<") { // Skip java names of the form "class.<init>"
+	// Skip java names of the form "class.<init>".
+	if strings.Contains(demangled, ".<") {
+		return false
+	}
+	// Skip Go names of the form "foo.(*Bar[...]).Method".
+	if strings.Contains(demangled, "]).") {
 		return false
 	}
 	return strings.ContainsAny(demangled, "<>[]") || strings.Contains(demangled, "::")
diff --git a/src/cmd/vendor/github.com/google/pprof/internal/transport/transport.go b/src/cmd/vendor/github.com/google/pprof/internal/transport/transport.go
index b5fb1dd..6c3bd0d 100644
--- a/src/cmd/vendor/github.com/google/pprof/internal/transport/transport.go
+++ b/src/cmd/vendor/github.com/google/pprof/internal/transport/transport.go
@@ -20,8 +20,8 @@
 	"crypto/tls"
 	"crypto/x509"
 	"fmt"
-	"io/ioutil"
 	"net/http"
+	"os"
 	"sync"
 
 	"github.com/google/pprof/internal/plugin"
@@ -86,7 +86,7 @@
 
 	if ca != "" {
 		caCertPool := x509.NewCertPool()
-		caCert, err := ioutil.ReadFile(ca)
+		caCert, err := os.ReadFile(ca)
 		if err != nil {
 			return fmt.Errorf("could not load CA specified by -tls_ca: %v", err)
 		}
diff --git a/src/cmd/vendor/github.com/google/pprof/profile/encode.go b/src/cmd/vendor/github.com/google/pprof/profile/encode.go
index 96aa271..c8a1beb 100644
--- a/src/cmd/vendor/github.com/google/pprof/profile/encode.go
+++ b/src/cmd/vendor/github.com/google/pprof/profile/encode.go
@@ -184,12 +184,13 @@
 	// repeated Location location = 4
 	func(b *buffer, m message) error {
 		x := new(Location)
-		x.Line = make([]Line, 0, 8) // Pre-allocate Line buffer
+		x.Line = b.tmpLines[:0] // Use shared space temporarily
 		pp := m.(*Profile)
 		pp.Location = append(pp.Location, x)
 		err := decodeMessage(b, x)
-		var tmp []Line
-		x.Line = append(tmp, x.Line...) // Shrink to allocated size
+		b.tmpLines = x.Line[:0]
+		// Copy to shrink size and detach from shared space.
+		x.Line = append([]Line(nil), x.Line...)
 		return err
 	},
 	// repeated Function function = 5
@@ -307,41 +308,52 @@
 		st.Unit, err = getString(p.stringTable, &st.unitX, err)
 	}
 
+	// Pre-allocate space for all locations.
+	numLocations := 0
 	for _, s := range p.Sample {
-		labels := make(map[string][]string, len(s.labelX))
-		numLabels := make(map[string][]int64, len(s.labelX))
-		numUnits := make(map[string][]string, len(s.labelX))
-		for _, l := range s.labelX {
-			var key, value string
-			key, err = getString(p.stringTable, &l.keyX, err)
-			if l.strX != 0 {
-				value, err = getString(p.stringTable, &l.strX, err)
-				labels[key] = append(labels[key], value)
-			} else if l.numX != 0 || l.unitX != 0 {
-				numValues := numLabels[key]
-				units := numUnits[key]
-				if l.unitX != 0 {
-					var unit string
-					unit, err = getString(p.stringTable, &l.unitX, err)
-					units = padStringArray(units, len(numValues))
-					numUnits[key] = append(units, unit)
-				}
-				numLabels[key] = append(numLabels[key], l.numX)
-			}
-		}
-		if len(labels) > 0 {
-			s.Label = labels
-		}
-		if len(numLabels) > 0 {
-			s.NumLabel = numLabels
-			for key, units := range numUnits {
-				if len(units) > 0 {
-					numUnits[key] = padStringArray(units, len(numLabels[key]))
+		numLocations += len(s.locationIDX)
+	}
+	locBuffer := make([]*Location, numLocations)
+
+	for _, s := range p.Sample {
+		if len(s.labelX) > 0 {
+			labels := make(map[string][]string, len(s.labelX))
+			numLabels := make(map[string][]int64, len(s.labelX))
+			numUnits := make(map[string][]string, len(s.labelX))
+			for _, l := range s.labelX {
+				var key, value string
+				key, err = getString(p.stringTable, &l.keyX, err)
+				if l.strX != 0 {
+					value, err = getString(p.stringTable, &l.strX, err)
+					labels[key] = append(labels[key], value)
+				} else if l.numX != 0 || l.unitX != 0 {
+					numValues := numLabels[key]
+					units := numUnits[key]
+					if l.unitX != 0 {
+						var unit string
+						unit, err = getString(p.stringTable, &l.unitX, err)
+						units = padStringArray(units, len(numValues))
+						numUnits[key] = append(units, unit)
+					}
+					numLabels[key] = append(numLabels[key], l.numX)
 				}
 			}
-			s.NumUnit = numUnits
+			if len(labels) > 0 {
+				s.Label = labels
+			}
+			if len(numLabels) > 0 {
+				s.NumLabel = numLabels
+				for key, units := range numUnits {
+					if len(units) > 0 {
+						numUnits[key] = padStringArray(units, len(numLabels[key]))
+					}
+				}
+				s.NumUnit = numUnits
+			}
 		}
-		s.Location = make([]*Location, len(s.locationIDX))
+
+		s.Location = locBuffer[:len(s.locationIDX)]
+		locBuffer = locBuffer[len(s.locationIDX):]
 		for i, lid := range s.locationIDX {
 			if lid < uint64(len(locationIds)) {
 				s.Location[i] = locationIds[lid]
diff --git a/src/cmd/vendor/github.com/google/pprof/profile/filter.go b/src/cmd/vendor/github.com/google/pprof/profile/filter.go
index ea8e66c..c794b93 100644
--- a/src/cmd/vendor/github.com/google/pprof/profile/filter.go
+++ b/src/cmd/vendor/github.com/google/pprof/profile/filter.go
@@ -22,6 +22,10 @@
 // samples where at least one frame matches focus but none match ignore.
 // Returns true is the corresponding regexp matched at least one sample.
 func (p *Profile) FilterSamplesByName(focus, ignore, hide, show *regexp.Regexp) (fm, im, hm, hnm bool) {
+	if focus == nil && ignore == nil && hide == nil && show == nil {
+		fm = true // Missing focus implies a match
+		return
+	}
 	focusOrIgnore := make(map[uint64]bool)
 	hidden := make(map[uint64]bool)
 	for _, l := range p.Location {
diff --git a/src/cmd/vendor/github.com/google/pprof/profile/legacy_profile.go b/src/cmd/vendor/github.com/google/pprof/profile/legacy_profile.go
index 9ba9a77..8d07fd6 100644
--- a/src/cmd/vendor/github.com/google/pprof/profile/legacy_profile.go
+++ b/src/cmd/vendor/github.com/google/pprof/profile/legacy_profile.go
@@ -865,7 +865,6 @@
 	// Recognize each thread and populate profile samples.
 	for !isMemoryMapSentinel(line) {
 		if strings.HasPrefix(line, "---- no stack trace for") {
-			line = ""
 			break
 		}
 		if t := threadStartRE.FindStringSubmatch(line); len(t) != 4 {
diff --git a/src/cmd/vendor/github.com/google/pprof/profile/merge.go b/src/cmd/vendor/github.com/google/pprof/profile/merge.go
index 6fcd11d..4b66282 100644
--- a/src/cmd/vendor/github.com/google/pprof/profile/merge.go
+++ b/src/cmd/vendor/github.com/google/pprof/profile/merge.go
@@ -15,6 +15,7 @@
 package profile
 
 import (
+	"encoding/binary"
 	"fmt"
 	"sort"
 	"strconv"
@@ -58,7 +59,7 @@
 
 	for _, src := range srcs {
 		// Clear the profile-specific hash tables
-		pm.locationsByID = make(map[uint64]*Location, len(src.Location))
+		pm.locationsByID = makeLocationIDMap(len(src.Location))
 		pm.functionsByID = make(map[uint64]*Function, len(src.Function))
 		pm.mappingsByID = make(map[uint64]mapInfo, len(src.Mapping))
 
@@ -136,7 +137,7 @@
 	p *Profile
 
 	// Memoization tables within a profile.
-	locationsByID map[uint64]*Location
+	locationsByID locationIDMap
 	functionsByID map[uint64]*Function
 	mappingsByID  map[uint64]mapInfo
 
@@ -153,6 +154,16 @@
 }
 
 func (pm *profileMerger) mapSample(src *Sample) *Sample {
+	// Check memoization table
+	k := pm.sampleKey(src)
+	if ss, ok := pm.samples[k]; ok {
+		for i, v := range src.Value {
+			ss.Value[i] += v
+		}
+		return ss
+	}
+
+	// Make new sample.
 	s := &Sample{
 		Location: make([]*Location, len(src.Location)),
 		Value:    make([]int64, len(src.Value)),
@@ -177,52 +188,98 @@
 		s.NumLabel[k] = vv
 		s.NumUnit[k] = uu
 	}
-	// Check memoization table. Must be done on the remapped location to
-	// account for the remapped mapping. Add current values to the
-	// existing sample.
-	k := s.key()
-	if ss, ok := pm.samples[k]; ok {
-		for i, v := range src.Value {
-			ss.Value[i] += v
-		}
-		return ss
-	}
 	copy(s.Value, src.Value)
 	pm.samples[k] = s
 	pm.p.Sample = append(pm.p.Sample, s)
 	return s
 }
 
-// key generates sampleKey to be used as a key for maps.
-func (sample *Sample) key() sampleKey {
-	ids := make([]string, len(sample.Location))
-	for i, l := range sample.Location {
-		ids[i] = strconv.FormatUint(l.ID, 16)
+func (pm *profileMerger) sampleKey(sample *Sample) sampleKey {
+	// Accumulate contents into a string.
+	var buf strings.Builder
+	buf.Grow(64) // Heuristic to avoid extra allocs
+
+	// encode a number
+	putNumber := func(v uint64) {
+		var num [binary.MaxVarintLen64]byte
+		n := binary.PutUvarint(num[:], v)
+		buf.Write(num[:n])
 	}
 
-	labels := make([]string, 0, len(sample.Label))
-	for k, v := range sample.Label {
-		labels = append(labels, fmt.Sprintf("%q%q", k, v))
+	// encode a string prefixed with its length.
+	putDelimitedString := func(s string) {
+		putNumber(uint64(len(s)))
+		buf.WriteString(s)
 	}
-	sort.Strings(labels)
 
-	numlabels := make([]string, 0, len(sample.NumLabel))
-	for k, v := range sample.NumLabel {
-		numlabels = append(numlabels, fmt.Sprintf("%q%x%x", k, v, sample.NumUnit[k]))
+	for _, l := range sample.Location {
+		// Get the location in the merged profile, which may have a different ID.
+		if loc := pm.mapLocation(l); loc != nil {
+			putNumber(loc.ID)
+		}
 	}
-	sort.Strings(numlabels)
+	putNumber(0) // Delimiter
 
-	return sampleKey{
-		strings.Join(ids, "|"),
-		strings.Join(labels, ""),
-		strings.Join(numlabels, ""),
+	for _, l := range sortedKeys1(sample.Label) {
+		putDelimitedString(l)
+		values := sample.Label[l]
+		putNumber(uint64(len(values)))
+		for _, v := range values {
+			putDelimitedString(v)
+		}
 	}
+
+	for _, l := range sortedKeys2(sample.NumLabel) {
+		putDelimitedString(l)
+		values := sample.NumLabel[l]
+		putNumber(uint64(len(values)))
+		for _, v := range values {
+			putNumber(uint64(v))
+		}
+		units := sample.NumUnit[l]
+		putNumber(uint64(len(units)))
+		for _, v := range units {
+			putDelimitedString(v)
+		}
+	}
+
+	return sampleKey(buf.String())
 }
 
-type sampleKey struct {
-	locations string
-	labels    string
-	numlabels string
+type sampleKey string
+
+// sortedKeys1 returns the sorted keys found in a string->[]string map.
+//
+// Note: this is currently non-generic since github pprof runs golint,
+// which does not support generics. When that issue is fixed, it can
+// be merged with sortedKeys2 and made into a generic function.
+func sortedKeys1(m map[string][]string) []string {
+	if len(m) == 0 {
+		return nil
+	}
+	keys := make([]string, 0, len(m))
+	for k := range m {
+		keys = append(keys, k)
+	}
+	sort.Strings(keys)
+	return keys
+}
+
+// sortedKeys2 returns the sorted keys found in a string->[]int64 map.
+//
+// Note: this is currently non-generic since github pprof runs golint,
+// which does not support generics. When that issue is fixed, it can
+// be merged with sortedKeys1 and made into a generic function.
+func sortedKeys2(m map[string][]int64) []string {
+	if len(m) == 0 {
+		return nil
+	}
+	keys := make([]string, 0, len(m))
+	for k := range m {
+		keys = append(keys, k)
+	}
+	sort.Strings(keys)
+	return keys
 }
 
 func (pm *profileMerger) mapLocation(src *Location) *Location {
@@ -230,7 +287,7 @@
 		return nil
 	}
 
-	if l, ok := pm.locationsByID[src.ID]; ok {
+	if l := pm.locationsByID.get(src.ID); l != nil {
 		return l
 	}
 
@@ -249,10 +306,10 @@
 	// account for the remapped mapping ID.
 	k := l.key()
 	if ll, ok := pm.locations[k]; ok {
-		pm.locationsByID[src.ID] = ll
+		pm.locationsByID.set(src.ID, ll)
 		return ll
 	}
-	pm.locationsByID[src.ID] = l
+	pm.locationsByID.set(src.ID, l)
 	pm.locations[k] = l
 	pm.p.Location = append(pm.p.Location, l)
 	return l
@@ -480,3 +537,131 @@
 func equalValueType(st1, st2 *ValueType) bool {
 	return st1.Type == st2.Type && st1.Unit == st2.Unit
 }
+
+// locationIDMap is like a map[uint64]*Location, but provides efficiency for
+// ids that are densely numbered, which is often the case.
+type locationIDMap struct {
+	dense  []*Location          // indexed by id for id < len(dense)
+	sparse map[uint64]*Location // indexed by id for id >= len(dense)
+}
+
+func makeLocationIDMap(n int) locationIDMap {
+	return locationIDMap{
+		dense:  make([]*Location, n),
+		sparse: map[uint64]*Location{},
+	}
+}
+
+func (lm locationIDMap) get(id uint64) *Location {
+	if id < uint64(len(lm.dense)) {
+		return lm.dense[int(id)]
+	}
+	return lm.sparse[id]
+}
+
+func (lm locationIDMap) set(id uint64, loc *Location) {
+	if id < uint64(len(lm.dense)) {
+		lm.dense[id] = loc
+		return
+	}
+	lm.sparse[id] = loc
+}
+
+// CompatibilizeSampleTypes makes profiles compatible to be compared/merged. It
+// keeps sample types that appear in all profiles only and drops/reorders the
+// sample types as necessary.
+//
+// In the case of sample types order is not the same for given profiles the
+// order is derived from the first profile.
+//
+// Profiles are modified in-place.
+//
+// It returns an error if the sample type's intersection is empty.
+func CompatibilizeSampleTypes(ps []*Profile) error {
+	sTypes := commonSampleTypes(ps)
+	if len(sTypes) == 0 {
+		return fmt.Errorf("profiles have empty common sample type list")
+	}
+	for _, p := range ps {
+		if err := compatibilizeSampleTypes(p, sTypes); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// commonSampleTypes returns sample types that appear in all profiles in the
+// order how they ordered in the first profile.
+func commonSampleTypes(ps []*Profile) []string {
+	if len(ps) == 0 {
+		return nil
+	}
+	sTypes := map[string]int{}
+	for _, p := range ps {
+		for _, st := range p.SampleType {
+			sTypes[st.Type]++
+		}
+	}
+	var res []string
+	for _, st := range ps[0].SampleType {
+		if sTypes[st.Type] == len(ps) {
+			res = append(res, st.Type)
+		}
+	}
+	return res
+}
+
+// compatibilizeSampleTypes drops sample types that are not present in sTypes
+// list and reorder them if needed.
+//
+// It sets DefaultSampleType to sType[0] if it is not in sType list.
+//
+// It assumes that all sample types from the sTypes list are present in the
+// given profile otherwise it returns an error.
+func compatibilizeSampleTypes(p *Profile, sTypes []string) error {
+	if len(sTypes) == 0 {
+		return fmt.Errorf("sample type list is empty")
+	}
+	defaultSampleType := sTypes[0]
+	reMap, needToModify := make([]int, len(sTypes)), false
+	for i, st := range sTypes {
+		if st == p.DefaultSampleType {
+			defaultSampleType = p.DefaultSampleType
+		}
+		idx := searchValueType(p.SampleType, st)
+		if idx < 0 {
+			return fmt.Errorf("%q sample type is not found in profile", st)
+		}
+		reMap[i] = idx
+		if idx != i {
+			needToModify = true
+		}
+	}
+	if !needToModify && len(sTypes) == len(p.SampleType) {
+		return nil
+	}
+	p.DefaultSampleType = defaultSampleType
+	oldSampleTypes := p.SampleType
+	p.SampleType = make([]*ValueType, len(sTypes))
+	for i, idx := range reMap {
+		p.SampleType[i] = oldSampleTypes[idx]
+	}
+	values := make([]int64, len(sTypes))
+	for _, s := range p.Sample {
+		for i, idx := range reMap {
+			values[i] = s.Value[idx]
+		}
+		s.Value = s.Value[:len(values)]
+		copy(s.Value, values)
+	}
+	return nil
+}
+
+func searchValueType(vts []*ValueType, s string) int {
+	for i, vt := range vts {
+		if vt.Type == s {
+			return i
+		}
+	}
+	return -1
+}
diff --git a/src/cmd/vendor/github.com/google/pprof/profile/profile.go b/src/cmd/vendor/github.com/google/pprof/profile/profile.go
index 5a3807f..4ec00fe 100644
--- a/src/cmd/vendor/github.com/google/pprof/profile/profile.go
+++ b/src/cmd/vendor/github.com/google/pprof/profile/profile.go
@@ -21,7 +21,6 @@
 	"compress/gzip"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"math"
 	"path/filepath"
 	"regexp"
@@ -153,7 +152,7 @@
 // may be a gzip-compressed encoded protobuf or one of many legacy
 // profile formats which may be unsupported in the future.
 func Parse(r io.Reader) (*Profile, error) {
-	data, err := ioutil.ReadAll(r)
+	data, err := io.ReadAll(r)
 	if err != nil {
 		return nil, err
 	}
@@ -168,7 +167,7 @@
 	if len(data) >= 2 && data[0] == 0x1f && data[1] == 0x8b {
 		gz, err := gzip.NewReader(bytes.NewBuffer(data))
 		if err == nil {
-			data, err = ioutil.ReadAll(gz)
+			data, err = io.ReadAll(gz)
 		}
 		if err != nil {
 			return nil, fmt.Errorf("decompressing profile: %v", err)
diff --git a/src/cmd/vendor/github.com/google/pprof/profile/proto.go b/src/cmd/vendor/github.com/google/pprof/profile/proto.go
index 539ad3a..a15696b 100644
--- a/src/cmd/vendor/github.com/google/pprof/profile/proto.go
+++ b/src/cmd/vendor/github.com/google/pprof/profile/proto.go
@@ -39,11 +39,12 @@
 )
 
 type buffer struct {
-	field int // field tag
-	typ   int // proto wire type code for field
-	u64   uint64
-	data  []byte
-	tmp   [16]byte
+	field    int // field tag
+	typ      int // proto wire type code for field
+	u64      uint64
+	data     []byte
+	tmp      [16]byte
+	tmpLines []Line // temporary storage used while decoding "repeated Line".
 }
 
 type decoder func(*buffer, message) error
@@ -286,7 +287,6 @@
 	if b.typ == 2 {
 		// Packed encoding
 		data := b.data
-		tmp := make([]int64, 0, len(data)) // Maximally sized
 		for len(data) > 0 {
 			var u uint64
 			var err error
@@ -294,9 +294,8 @@
 			if u, data, err = decodeVarint(data); err != nil {
 				return err
 			}
-			tmp = append(tmp, int64(u))
+			*x = append(*x, int64(u))
 		}
-		*x = append(*x, tmp...)
 		return nil
 	}
 	var i int64
@@ -319,7 +318,6 @@
 	if b.typ == 2 {
 		data := b.data
 		// Packed encoding
-		tmp := make([]uint64, 0, len(data)) // Maximally sized
 		for len(data) > 0 {
 			var u uint64
 			var err error
@@ -327,9 +325,8 @@
 			if u, data, err = decodeVarint(data); err != nil {
 				return err
 			}
-			tmp = append(tmp, u)
+			*x = append(*x, u)
 		}
-		*x = append(*x, tmp...)
 		return nil
 	}
 	var u uint64
diff --git a/src/cmd/vendor/github.com/google/pprof/profile/prune.go b/src/cmd/vendor/github.com/google/pprof/profile/prune.go
index 02d21a8..b2f9fd5 100644
--- a/src/cmd/vendor/github.com/google/pprof/profile/prune.go
+++ b/src/cmd/vendor/github.com/google/pprof/profile/prune.go
@@ -62,15 +62,31 @@
 	prune := make(map[uint64]bool)
 	pruneBeneath := make(map[uint64]bool)
 
+	// simplifyFunc can be expensive, so cache results.
+	// Note that the same function name can be encountered many times due
+	// different lines and addresses in the same function.
+	pruneCache := map[string]bool{} // Map from function to whether or not to prune
+	pruneFromHere := func(s string) bool {
+		if r, ok := pruneCache[s]; ok {
+			return r
+		}
+		funcName := simplifyFunc(s)
+		if dropRx.MatchString(funcName) {
+			if keepRx == nil || !keepRx.MatchString(funcName) {
+				pruneCache[s] = true
+				return true
+			}
+		}
+		pruneCache[s] = false
+		return false
+	}
+
 	for _, loc := range p.Location {
 		var i int
 		for i = len(loc.Line) - 1; i >= 0; i-- {
 			if fn := loc.Line[i].Function; fn != nil && fn.Name != "" {
-				funcName := simplifyFunc(fn.Name)
-				if dropRx.MatchString(funcName) {
-					if keepRx == nil || !keepRx.MatchString(funcName) {
-						break
-					}
+				if pruneFromHere(fn.Name) {
+					break
 				}
 			}
 		}
diff --git a/src/cmd/vendor/golang.org/x/arch/AUTHORS b/src/cmd/vendor/golang.org/x/arch/AUTHORS
deleted file mode 100644
index 2b00ddb..0000000
--- a/src/cmd/vendor/golang.org/x/arch/AUTHORS
+++ /dev/null
@@ -1,3 +0,0 @@
-# This source code refers to The Go Authors for copyright purposes.
-# The master list of authors is in the main Go distribution,
-# visible at https://tip.golang.org/AUTHORS.
diff --git a/src/cmd/vendor/golang.org/x/arch/CONTRIBUTORS b/src/cmd/vendor/golang.org/x/arch/CONTRIBUTORS
deleted file mode 100644
index 1fbd3e9..0000000
--- a/src/cmd/vendor/golang.org/x/arch/CONTRIBUTORS
+++ /dev/null
@@ -1,3 +0,0 @@
-# This source code was written by the Go contributors.
-# The master list of contributors is in the main Go distribution,
-# visible at https://tip.golang.org/CONTRIBUTORS.
diff --git a/src/cmd/vendor/golang.org/x/arch/arm/armasm/decode.go b/src/cmd/vendor/golang.org/x/arch/arm/armasm/decode.go
index 6b4d738..f61ac12 100644
--- a/src/cmd/vendor/golang.org/x/arch/arm/armasm/decode.go
+++ b/src/cmd/vendor/golang.org/x/arch/arm/armasm/decode.go
@@ -17,7 +17,9 @@
 // If x matches the format, then the rest of the fields describe how to interpret x.
 // The opBits describe bits that should be extracted from x and added to the opcode.
 // For example opBits = 0x1234 means that the value
+//
 //	(2 bits at offset 1) followed by (4 bits at offset 3)
+//
 // should be added to op.
 // Finally the args describe how to decode the instruction arguments.
 // args is stored as a fixed-size array; if there are fewer than len(args) arguments,
@@ -233,9 +235,9 @@
 		typ, count := decodeShift(x)
 		// ROR #0 here means ROR #0, but decodeShift rewrites to RRX #1.
 		if typ == RotateRightExt {
-			return Reg(Rm)
+			return Rm
 		}
-		return RegShift{Rm, typ, uint8(count)}
+		return RegShift{Rm, typ, count}
 
 	case arg_R_shift_R:
 		Rm := Reg(x & (1<<4 - 1))
@@ -249,7 +251,7 @@
 		if typ == ShiftLeft && count == 0 {
 			return Reg(Rm)
 		}
-		return RegShift{Rm, typ, uint8(count)}
+		return RegShift{Rm, typ, count}
 
 	case arg_R1_0:
 		return Reg((x & (1<<4 - 1)))
diff --git a/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/decode.go b/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/decode.go
index 59bd325..b8d857c 100644
--- a/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/decode.go
+++ b/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/decode.go
@@ -22,9 +22,12 @@
 // The Args are stored in the same order as the instruction manual.
 //
 // Prefixed instructions are stored as:
-//   prefix << 32 | suffix,
+//
+//	prefix << 32 | suffix,
+//
 // Regular instructions are:
-//   inst << 32
+//
+//	inst << 32
 type instFormat struct {
 	Op       Op
 	Mask     uint64
@@ -77,6 +80,12 @@
 		return Label(a.BitFields.ParseSigned(i) << a.Shift)
 	case TypeOffset:
 		return Offset(a.BitFields.ParseSigned(i) << a.Shift)
+	case TypeNegOffset:
+		// An oddball encoding of offset for hashchk and similar.
+		// e.g hashchk offset is 0b1111111000000000 | DX << 8 | D << 3
+		off := a.BitFields.ParseSigned(i) << a.Shift
+		neg := int64(-1) << (int(a.Shift) + a.BitFields.NumBits())
+		return Offset(neg | off)
 	}
 }
 
@@ -98,6 +107,7 @@
 	TypeImmSigned            // signed immediate
 	TypeImmUnsigned          // unsigned immediate/flag/mask, this is the catch-all type
 	TypeOffset               // signed offset in load/store
+	TypeNegOffset            // A negative 16 bit value 0b1111111xxxxx000 encoded as 0bxxxxx (e.g in the hashchk instruction)
 	TypeLast                 // must be the last one
 )
 
@@ -135,6 +145,8 @@
 		return "Label"
 	case TypeOffset:
 		return "Offset"
+	case TypeNegOffset:
+		return "NegOffset"
 	}
 }
 
diff --git a/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/field.go b/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/field.go
index 882c91a..3779446 100644
--- a/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/field.go
+++ b/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/field.go
@@ -67,7 +67,7 @@
 // the sequence of bitfields is reasonable.
 func (bs BitFields) parse(i [2]uint32) (u uint64, Bits uint8) {
 	for _, b := range bs {
-		u = (uint64(u) << b.Bits) | uint64(b.Parse(i))
+		u = (u << b.Bits) | uint64(b.Parse(i))
 		Bits += b.Bits
 	}
 	return u, Bits
@@ -86,3 +86,12 @@
 	u, l := bs.parse(i)
 	return int64(u) << (64 - l) >> (64 - l)
 }
+
+// Count the number of bits in the aggregate BitFields
+func (bs BitFields) NumBits() int {
+	num := 0
+	for _, b := range bs {
+		num += int(b.Bits)
+	}
+	return num
+}
diff --git a/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/plan9.go b/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/plan9.go
index 88e8e1c..fcb2a12 100644
--- a/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/plan9.go
+++ b/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/plan9.go
@@ -83,7 +83,9 @@
 		STH, STHU,
 		STW, STWU,
 		STD, STDU,
-		STQ, STFD, STFDU, STFS, STFSU:
+		STFD, STFDU,
+		STFS, STFSU,
+		STQ, HASHST, HASHSTP:
 		return op + " " + strings.Join(args, ",")
 
 	case FCMPU, FCMPO, CMPD, CMPDI, CMPLD, CMPLDI, CMPW, CMPWI, CMPLW, CMPLWI:
@@ -168,8 +170,9 @@
 }
 
 // plan9Arg formats arg (which is the argIndex's arg in inst) according to Plan 9 rules.
+//
 // NOTE: because Plan9Syntax is the only caller of this func, and it receives a copy
-//       of inst, it's ok to modify inst.Args here.
+// of inst, it's ok to modify inst.Args here.
 func plan9Arg(inst *Inst, argIndex int, pc uint64, arg Arg, symname func(uint64) (string, uint64)) string {
 	// special cases for load/store instructions
 	if _, ok := arg.(Offset); ok {
@@ -211,9 +214,16 @@
 		return fmt.Sprintf("SPR(%d)", int(arg))
 	case PCRel:
 		addr := pc + uint64(int64(arg))
-		if s, base := symname(addr); s != "" && base == addr {
+		s, base := symname(addr)
+		if s != "" && addr == base {
 			return fmt.Sprintf("%s(SB)", s)
 		}
+		if inst.Op == BL && s != "" && (addr-base) == 8 {
+			// When decoding an object built for PIE, a CALL targeting
+			// a global entry point will be adjusted to the local entry
+			// if any. For now, assume any symname+8 PC is a local call.
+			return fmt.Sprintf("%s+%d(SB)", s, addr-base)
+		}
 		return fmt.Sprintf("%#x", addr)
 	case Label:
 		return fmt.Sprintf("%#x", int(arg))
@@ -251,7 +261,7 @@
 		return true
 	case FADDCC, FADDSCC, FSUBCC, FMULCC, FDIVCC, FDIVSCC:
 		return true
-	case OR, ORC, AND, ANDC, XOR, NAND, EQV, NOR, ANDCC, ORCC, XORCC, EQVCC, NORCC, NANDCC:
+	case OR, ORCC, ORC, ORCCC, AND, ANDCC, ANDC, ANDCCC, XOR, XORCC, NAND, NANDCC, EQV, EQVCC, NOR, NORCC:
 		return true
 	case SLW, SLWCC, SLD, SLDCC, SRW, SRAW, SRWCC, SRAWCC, SRD, SRDCC, SRAD, SRADCC:
 		return true
@@ -305,6 +315,7 @@
 	ORI:       "OR",
 	ANDICC:    "ANDCC",
 	ANDC:      "ANDN",
+	ANDCCC:    "ANDNCC",
 	ADDEO:     "ADDEV",
 	ADDEOCC:   "ADDEVCC",
 	ADDO:      "ADDV",
@@ -321,8 +332,12 @@
 	SUBFZECC:  "SUBZECC",
 	SUBFZEO:   "SUBZEV",
 	SUBFZEOCC: "SUBZEVCC",
+	SUBF:      "SUB",
 	SUBFC:     "SUBC",
+	SUBFCC:    "SUBCC",
+	SUBFCCC:   "SUBCCC",
 	ORC:       "ORN",
+	ORCCC:     "ORNCC",
 	MULLWO:    "MULLWV",
 	MULLWOCC:  "MULLWVCC",
 	MULLDO:    "MULLDV",
@@ -334,7 +349,6 @@
 	ADDI:      "ADD",
 	MULLI:     "MULLD",
 	SRADI:     "SRAD",
-	SUBF:      "SUB",
 	STBCXCC:   "STBCCC",
 	STWCXCC:   "STWCCC",
 	STDCXCC:   "STDCCC",
diff --git a/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/tables.go b/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/tables.go
index 9e3b26f..8705077 100644
--- a/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/tables.go
+++ b/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/tables.go
@@ -1,9 +1,13 @@
-// Code generated by ppc64map -fmt=decoder pp64.csv DO NOT EDIT.
+// Code generated by ppc64map -fmt=decoder ../pp64.csv DO NOT EDIT.
 
 package ppc64asm
 
 const (
 	_ Op = iota
+	HASHCHK
+	HASHCHKP
+	HASHST
+	HASHSTP
 	BRD
 	BRH
 	BRW
@@ -1420,6 +1424,10 @@
 )
 
 var opstr = [...]string{
+	HASHCHK:        "hashchk",
+	HASHCHKP:       "hashchkp",
+	HASHST:         "hashst",
+	HASHSTP:        "hashstp",
 	BRD:            "brd",
 	BRH:            "brh",
 	BRW:            "brw",
@@ -2836,9 +2844,10 @@
 }
 
 var (
+	ap_Reg_16_20                     = &argField{Type: TypeReg, Shift: 0, BitFields: BitFields{{16, 5, 0}}}
+	ap_NegOffset_31_31_6_10_shift3   = &argField{Type: TypeNegOffset, Shift: 3, BitFields: BitFields{{31, 1, 0}, {6, 5, 0}}}
 	ap_Reg_11_15                     = &argField{Type: TypeReg, Shift: 0, BitFields: BitFields{{11, 5, 0}}}
 	ap_Reg_6_10                      = &argField{Type: TypeReg, Shift: 0, BitFields: BitFields{{6, 5, 0}}}
-	ap_Reg_16_20                     = &argField{Type: TypeReg, Shift: 0, BitFields: BitFields{{16, 5, 0}}}
 	ap_FPReg_6_10                    = &argField{Type: TypeFPReg, Shift: 0, BitFields: BitFields{{6, 5, 0}}}
 	ap_VecReg_16_20                  = &argField{Type: TypeVecReg, Shift: 0, BitFields: BitFields{{16, 5, 0}}}
 	ap_VecReg_6_10                   = &argField{Type: TypeVecReg, Shift: 0, BitFields: BitFields{{6, 5, 0}}}
@@ -2906,7 +2915,7 @@
 	ap_FPReg_11_15                   = &argField{Type: TypeFPReg, Shift: 0, BitFields: BitFields{{11, 5, 0}}}
 	ap_ImmUnsigned_7_10              = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{7, 4, 0}}}
 	ap_ImmUnsigned_31_31             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{31, 1, 0}}}
-	ap_SpReg_11_20                   = &argField{Type: TypeSpReg, Shift: 0, BitFields: BitFields{{11, 10, 0}}}
+	ap_ImmUnsigned_11_20             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{11, 10, 0}}}
 	ap_ImmUnsigned_20_20             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{20, 1, 0}}}
 	ap_ImmUnsigned_16_16             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{16, 1, 0}}}
 	ap_ImmUnsigned_17_20             = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{17, 4, 0}}}
@@ -2942,6 +2951,14 @@
 )
 
 var instFormats = [...]instFormat{
+	{HASHCHK, 0xfc0007fe00000000, 0x7c0005e400000000, 0x0, // Hash Check X-form (hashchk RB,offset(RA))
+		[6]*argField{ap_Reg_16_20, ap_NegOffset_31_31_6_10_shift3, ap_Reg_11_15}},
+	{HASHCHKP, 0xfc0007fe00000000, 0x7c00056400000000, 0x0, // Hash Check Privileged X-form (hashchkp RB,offset(RA))
+		[6]*argField{ap_Reg_16_20, ap_NegOffset_31_31_6_10_shift3, ap_Reg_11_15}},
+	{HASHST, 0xfc0007fe00000000, 0x7c0005a400000000, 0x0, // Hash Store X-form (hashst RB,offset(RA))
+		[6]*argField{ap_Reg_16_20, ap_NegOffset_31_31_6_10_shift3, ap_Reg_11_15}},
+	{HASHSTP, 0xfc0007fe00000000, 0x7c00052400000000, 0x0, // Hash Store Privileged X-form (hashstp RB,offset(RA))
+		[6]*argField{ap_Reg_16_20, ap_NegOffset_31_31_6_10_shift3, ap_Reg_11_15}},
 	{BRD, 0xfc0007fe00000000, 0x7c00017600000000, 0xf80100000000, // Byte-Reverse Doubleword X-form (brd RA,RS)
 		[6]*argField{ap_Reg_11_15, ap_Reg_6_10}},
 	{BRH, 0xfc0007fe00000000, 0x7c0001b600000000, 0xf80100000000, // Byte-Reverse Halfword X-form (brh RA,RS)
@@ -3344,7 +3361,7 @@
 		[6]*argField{ap_MMAReg_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
 	{XVBF16GER2PP, 0xfc0007f800000000, 0xec00019000000000, 0x60000100000000, // VSX Vector bfloat16 GER (Rank-2 Update) Positive multiply, Positive accumulate XX3-form (xvbf16ger2pp AT,XA,XB)
 		[6]*argField{ap_MMAReg_6_8, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
-	{XVCVBF16SPN, 0xfc1f07fc00000000, 0xf010076c00000000, 0x0, // VSX Vector Convert bfloat16 to Single-Precision format XX2-form (xvcvbf16spn XT,XB)
+	{XVCVBF16SPN, 0xfc1f07fc00000000, 0xf010076c00000000, 0x0, // VSX Vector Convert bfloat16 to Single-Precision format Non-signaling XX2-form (xvcvbf16spn XT,XB)
 		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
 	{XVCVSPBF16, 0xfc1f07fc00000000, 0xf011076c00000000, 0x0, // VSX Vector Convert with round Single-Precision to bfloat16 format XX2-form (xvcvspbf16 XT,XB)
 		[6]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
@@ -3883,7 +3900,7 @@
 	{LXSSPX, 0xfc0007fe00000000, 0x7c00041800000000, 0x0, // Load VSX Scalar Single-Precision Indexed X-form (lxsspx XT,RA,RB)
 		[6]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
 	{MFBHRBE, 0xfc0007fe00000000, 0x7c00025c00000000, 0x100000000, // Move From BHRB XFX-form (mfbhrbe RT,BHRBE)
-		[6]*argField{ap_Reg_6_10, ap_SpReg_11_20}},
+		[6]*argField{ap_Reg_6_10, ap_ImmUnsigned_11_20}},
 	{MFVSRD, 0xfc0007fe00000000, 0x7c00006600000000, 0xf80000000000, // Move From VSR Doubleword X-form (mfvsrd RA,XS)
 		[6]*argField{ap_Reg_11_15, ap_VecSReg_31_31_6_10}},
 	{MFVSRWZ, 0xfc0007fe00000000, 0x7c0000e600000000, 0xf80000000000, // Move From VSR Word and Zero X-form (mfvsrwz RA,XS)
@@ -5334,7 +5351,7 @@
 		[6]*argField{ap_Reg_6_10, ap_ImmSigned_16_31}},
 	{ADDI, 0xfc00000000000000, 0x3800000000000000, 0x0, // Add Immediate D-form (addi RT,RA,SI)
 		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmSigned_16_31}},
-	{ADDIC, 0xfc00000000000000, 0x3000000000000000, 0x0, // Add Immediate Carrying D-formy (addic RT,RA,SI)
+	{ADDIC, 0xfc00000000000000, 0x3000000000000000, 0x0, // Add Immediate Carrying D-form (addic RT,RA,SI)
 		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmSigned_16_31}},
 	{ADDICCC, 0xfc00000000000000, 0x3400000000000000, 0x0, // Add Immediate Carrying and Record D-form (addic. RT,RA,SI)
 		[6]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_ImmSigned_16_31}},
diff --git a/src/cmd/vendor/golang.org/x/crypto/AUTHORS b/src/cmd/vendor/golang.org/x/crypto/AUTHORS
deleted file mode 100644
index 2b00ddb..0000000
--- a/src/cmd/vendor/golang.org/x/crypto/AUTHORS
+++ /dev/null
@@ -1,3 +0,0 @@
-# This source code refers to The Go Authors for copyright purposes.
-# The master list of authors is in the main Go distribution,
-# visible at https://tip.golang.org/AUTHORS.
diff --git a/src/cmd/vendor/golang.org/x/crypto/CONTRIBUTORS b/src/cmd/vendor/golang.org/x/crypto/CONTRIBUTORS
deleted file mode 100644
index 1fbd3e9..0000000
--- a/src/cmd/vendor/golang.org/x/crypto/CONTRIBUTORS
+++ /dev/null
@@ -1,3 +0,0 @@
-# This source code was written by the Go contributors.
-# The master list of contributors is in the main Go distribution,
-# visible at https://tip.golang.org/CONTRIBUTORS.
diff --git a/src/cmd/vendor/golang.org/x/crypto/LICENSE b/src/cmd/vendor/golang.org/x/crypto/LICENSE
deleted file mode 100644
index 6a66aea..0000000
--- a/src/cmd/vendor/golang.org/x/crypto/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) 2009 The Go Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-   * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-   * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
-   * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/src/cmd/vendor/golang.org/x/crypto/PATENTS b/src/cmd/vendor/golang.org/x/crypto/PATENTS
deleted file mode 100644
index 7330990..0000000
--- a/src/cmd/vendor/golang.org/x/crypto/PATENTS
+++ /dev/null
@@ -1,22 +0,0 @@
-Additional IP Rights Grant (Patents)
-
-"This implementation" means the copyrightable works distributed by
-Google as part of the Go project.
-
-Google hereby grants to You a perpetual, worldwide, non-exclusive,
-no-charge, royalty-free, irrevocable (except as stated in this section)
-patent license to make, have made, use, offer to sell, sell, import,
-transfer and otherwise run, modify and propagate the contents of this
-implementation of Go, where such license applies only to those patent
-claims, both currently owned or controlled by Google and acquired in
-the future, licensable by Google that are necessarily infringed by this
-implementation of Go.  This grant does not include claims that would be
-infringed only as a consequence of further modification of this
-implementation.  If you or your agent or exclusive licensee institute or
-order or agree to the institution of patent litigation against any
-entity (including a cross-claim or counterclaim in a lawsuit) alleging
-that this implementation of Go or any code incorporated within this
-implementation of Go constitutes direct or contributory patent
-infringement, or inducement of patent infringement, then any patent
-rights granted to you under this License for this implementation of Go
-shall terminate as of the date such litigation is filed.
diff --git a/src/cmd/vendor/golang.org/x/crypto/ed25519/ed25519.go b/src/cmd/vendor/golang.org/x/crypto/ed25519/ed25519.go
deleted file mode 100644
index a782834..0000000
--- a/src/cmd/vendor/golang.org/x/crypto/ed25519/ed25519.go
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package ed25519 implements the Ed25519 signature algorithm. See
-// https://ed25519.cr.yp.to/.
-//
-// These functions are also compatible with the “Ed25519” function defined in
-// RFC 8032. However, unlike RFC 8032's formulation, this package's private key
-// representation includes a public key suffix to make multiple signing
-// operations with the same key more efficient. This package refers to the RFC
-// 8032 private key as the “seed”.
-//
-// Beginning with Go 1.13, the functionality of this package was moved to the
-// standard library as crypto/ed25519. This package only acts as a compatibility
-// wrapper.
-package ed25519
-
-import (
-	"crypto/ed25519"
-	"io"
-)
-
-const (
-	// PublicKeySize is the size, in bytes, of public keys as used in this package.
-	PublicKeySize = 32
-	// PrivateKeySize is the size, in bytes, of private keys as used in this package.
-	PrivateKeySize = 64
-	// SignatureSize is the size, in bytes, of signatures generated and verified by this package.
-	SignatureSize = 64
-	// SeedSize is the size, in bytes, of private key seeds. These are the private key representations used by RFC 8032.
-	SeedSize = 32
-)
-
-// PublicKey is the type of Ed25519 public keys.
-//
-// This type is an alias for crypto/ed25519's PublicKey type.
-// See the crypto/ed25519 package for the methods on this type.
-type PublicKey = ed25519.PublicKey
-
-// PrivateKey is the type of Ed25519 private keys. It implements crypto.Signer.
-//
-// This type is an alias for crypto/ed25519's PrivateKey type.
-// See the crypto/ed25519 package for the methods on this type.
-type PrivateKey = ed25519.PrivateKey
-
-// GenerateKey generates a public/private key pair using entropy from rand.
-// If rand is nil, crypto/rand.Reader will be used.
-func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) {
-	return ed25519.GenerateKey(rand)
-}
-
-// NewKeyFromSeed calculates a private key from a seed. It will panic if
-// len(seed) is not SeedSize. This function is provided for interoperability
-// with RFC 8032. RFC 8032's private keys correspond to seeds in this
-// package.
-func NewKeyFromSeed(seed []byte) PrivateKey {
-	return ed25519.NewKeyFromSeed(seed)
-}
-
-// Sign signs the message with privateKey and returns a signature. It will
-// panic if len(privateKey) is not PrivateKeySize.
-func Sign(privateKey PrivateKey, message []byte) []byte {
-	return ed25519.Sign(privateKey, message)
-}
-
-// Verify reports whether sig is a valid signature of message by publicKey. It
-// will panic if len(publicKey) is not PublicKeySize.
-func Verify(publicKey PublicKey, message, sig []byte) bool {
-	return ed25519.Verify(publicKey, message, sig)
-}
diff --git a/src/cmd/vendor/golang.org/x/mod/modfile/read.go b/src/cmd/vendor/golang.org/x/mod/modfile/read.go
index 70947ee..a503bc2 100644
--- a/src/cmd/vendor/golang.org/x/mod/modfile/read.go
+++ b/src/cmd/vendor/golang.org/x/mod/modfile/read.go
@@ -494,7 +494,7 @@
 	in.token.endPos = in.pos
 }
 
-// peek returns the kind of the the next token returned by lex.
+// peek returns the kind of the next token returned by lex.
 func (in *input) peek() tokenKind {
 	return in.token.kind
 }
diff --git a/src/cmd/vendor/golang.org/x/mod/modfile/rule.go b/src/cmd/vendor/golang.org/x/mod/modfile/rule.go
index ed2f31a..6bcde8f 100644
--- a/src/cmd/vendor/golang.org/x/mod/modfile/rule.go
+++ b/src/cmd/vendor/golang.org/x/mod/modfile/rule.go
@@ -513,6 +513,9 @@
 	nv := ""
 	if len(args) == arrow+2 {
 		if !IsDirectoryPath(ns) {
+			if strings.Contains(ns, "@") {
+				return nil, errorf("replacement module must match format 'path version', not 'path@version'")
+			}
 			return nil, errorf("replacement module without version must be directory path (rooted or starting with ./ or ../)")
 		}
 		if filepath.Separator == '/' && strings.Contains(ns, `\`) {
diff --git a/src/cmd/vendor/golang.org/x/mod/module/module.go b/src/cmd/vendor/golang.org/x/mod/module/module.go
index c26d1d2..e9dec6e 100644
--- a/src/cmd/vendor/golang.org/x/mod/module/module.go
+++ b/src/cmd/vendor/golang.org/x/mod/module/module.go
@@ -96,13 +96,13 @@
 // Changes to the semantics in this file require approval from rsc.
 
 import (
+	"errors"
 	"fmt"
 	"path"
 	"sort"
 	"strings"
 	"unicode"
 	"unicode/utf8"
-	"errors"
 
 	"golang.org/x/mod/semver"
 )
@@ -258,7 +258,7 @@
 	return false
 }
 
-// modPathOK reports whether r can appear in a package import path element.
+// importPathOK reports whether r can appear in a package import path element.
 //
 // Import paths are intermediate between module paths and file paths: we allow
 // disallow characters that would be confusing or ambiguous as arguments to
diff --git a/src/cmd/vendor/golang.org/x/mod/sumdb/note/note.go b/src/cmd/vendor/golang.org/x/mod/sumdb/note/note.go
index 4d86eef..140b937 100644
--- a/src/cmd/vendor/golang.org/x/mod/sumdb/note/note.go
+++ b/src/cmd/vendor/golang.org/x/mod/sumdb/note/note.go
@@ -175,6 +175,7 @@
 
 import (
 	"bytes"
+	"crypto/ed25519"
 	"crypto/sha256"
 	"encoding/base64"
 	"encoding/binary"
@@ -185,8 +186,6 @@
 	"strings"
 	"unicode"
 	"unicode/utf8"
-
-	"golang.org/x/crypto/ed25519"
 )
 
 // A Verifier verifies messages signed with a specific key.
diff --git a/src/cmd/vendor/golang.org/x/mod/sumdb/test.go b/src/cmd/vendor/golang.org/x/mod/sumdb/test.go
index e4c166d..c2755b8 100644
--- a/src/cmd/vendor/golang.org/x/mod/sumdb/test.go
+++ b/src/cmd/vendor/golang.org/x/mod/sumdb/test.go
@@ -107,7 +107,7 @@
 		s.lookup = make(map[string]int64)
 	}
 	s.lookup[key] = id
-	hashes, err := tlog.StoredHashesForRecordHash(id, tlog.RecordHash([]byte(data)), s.hashes)
+	hashes, err := tlog.StoredHashesForRecordHash(id, tlog.RecordHash(data), s.hashes)
 	if err != nil {
 		panic(err)
 	}
diff --git a/src/cmd/vendor/golang.org/x/mod/zip/zip.go b/src/cmd/vendor/golang.org/x/mod/zip/zip.go
index 949cae2..0328705 100644
--- a/src/cmd/vendor/golang.org/x/mod/zip/zip.go
+++ b/src/cmd/vendor/golang.org/x/mod/zip/zip.go
@@ -619,7 +619,7 @@
 	return fmt.Sprintf("could not find a recognized version control system at %q", e.RepoRoot)
 }
 
-// filterGitIgnored filters out any files that are git ignored in the directory.
+// filesInGitRepo filters out any files that are git ignored in the directory.
 func filesInGitRepo(dir, rev, subdir string) ([]File, error) {
 	stderr := bytes.Buffer{}
 	stdout := bytes.Buffer{}
@@ -641,6 +641,7 @@
 		cmd.Args = append(cmd.Args, subdir)
 	}
 	cmd.Dir = dir
+	cmd.Env = append(os.Environ(), "PWD="+dir)
 	cmd.Stdout = &stdout
 	cmd.Stderr = &stderr
 	if err := cmd.Run(); err != nil {
@@ -679,11 +680,12 @@
 	stdout := &bytes.Buffer{}
 	cmd := exec.Command("git", "rev-parse", "--git-dir")
 	cmd.Dir = dir
+	cmd.Env = append(os.Environ(), "PWD="+dir)
 	cmd.Stdout = stdout
 	if err := cmd.Run(); err != nil {
 		return false
 	}
-	gitDir := strings.TrimSpace(string(stdout.Bytes()))
+	gitDir := strings.TrimSpace(stdout.String())
 	if !filepath.IsAbs(gitDir) {
 		gitDir = filepath.Join(dir, gitDir)
 	}
diff --git a/src/cmd/vendor/golang.org/x/sync/AUTHORS b/src/cmd/vendor/golang.org/x/sync/AUTHORS
deleted file mode 100644
index 15167cd..0000000
--- a/src/cmd/vendor/golang.org/x/sync/AUTHORS
+++ /dev/null
@@ -1,3 +0,0 @@
-# This source code refers to The Go Authors for copyright purposes.
-# The master list of authors is in the main Go distribution,
-# visible at http://tip.golang.org/AUTHORS.
diff --git a/src/cmd/vendor/golang.org/x/sync/CONTRIBUTORS b/src/cmd/vendor/golang.org/x/sync/CONTRIBUTORS
deleted file mode 100644
index 1c4577e..0000000
--- a/src/cmd/vendor/golang.org/x/sync/CONTRIBUTORS
+++ /dev/null
@@ -1,3 +0,0 @@
-# This source code was written by the Go contributors.
-# The master list of contributors is in the main Go distribution,
-# visible at http://tip.golang.org/CONTRIBUTORS.
diff --git a/src/cmd/vendor/golang.org/x/sys/AUTHORS b/src/cmd/vendor/golang.org/x/sys/AUTHORS
deleted file mode 100644
index 15167cd..0000000
--- a/src/cmd/vendor/golang.org/x/sys/AUTHORS
+++ /dev/null
@@ -1,3 +0,0 @@
-# This source code refers to The Go Authors for copyright purposes.
-# The master list of authors is in the main Go distribution,
-# visible at http://tip.golang.org/AUTHORS.
diff --git a/src/cmd/vendor/golang.org/x/sys/CONTRIBUTORS b/src/cmd/vendor/golang.org/x/sys/CONTRIBUTORS
deleted file mode 100644
index 1c4577e..0000000
--- a/src/cmd/vendor/golang.org/x/sys/CONTRIBUTORS
+++ /dev/null
@@ -1,3 +0,0 @@
-# This source code was written by the Go contributors.
-# The master list of contributors is in the main Go distribution,
-# visible at http://tip.golang.org/CONTRIBUTORS.
diff --git a/src/cmd/vendor/golang.org/x/sys/plan9/mkerrors.sh b/src/cmd/vendor/golang.org/x/sys/plan9/mkerrors.sh
index 85309c4..526d04a 100644
--- a/src/cmd/vendor/golang.org/x/sys/plan9/mkerrors.sh
+++ b/src/cmd/vendor/golang.org/x/sys/plan9/mkerrors.sh
@@ -126,7 +126,7 @@
 signals=$(
 	echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
 	awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' |
-	egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT)' |
+	grep -v 'SIGSTKSIZE\|SIGSTKSZ\|SIGRT' |
 	sort
 )
 
@@ -136,7 +136,7 @@
 	sort >_error.grep
 echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
 	awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print "^\t" $2 "[ \t]*=" }' |
-	egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT)' |
+	grep -v 'SIGSTKSIZE\|SIGSTKSZ\|SIGRT' |
 	sort >_signal.grep
 
 echo '// mkerrors.sh' "$@"
diff --git a/src/cmd/vendor/golang.org/x/sys/plan9/syscall.go b/src/cmd/vendor/golang.org/x/sys/plan9/syscall.go
index a25223b..67e5b01 100644
--- a/src/cmd/vendor/golang.org/x/sys/plan9/syscall.go
+++ b/src/cmd/vendor/golang.org/x/sys/plan9/syscall.go
@@ -29,8 +29,6 @@
 	"bytes"
 	"strings"
 	"unsafe"
-
-	"golang.org/x/sys/internal/unsafeheader"
 )
 
 // ByteSliceFromString returns a NUL-terminated slice of bytes
@@ -82,13 +80,7 @@
 		ptr = unsafe.Pointer(uintptr(ptr) + 1)
 	}
 
-	var s []byte
-	h := (*unsafeheader.Slice)(unsafe.Pointer(&s))
-	h.Data = unsafe.Pointer(p)
-	h.Len = n
-	h.Cap = n
-
-	return string(s)
+	return string(unsafe.Slice(p, n))
 }
 
 // Single-word zero for use when we need a valid pointer to 0 bytes.
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_bsd_ppc64.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_bsd_ppc64.s
new file mode 100644
index 0000000..e5b9a84
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_bsd_ppc64.s
@@ -0,0 +1,31 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build (darwin || freebsd || netbsd || openbsd) && gc
+// +build darwin freebsd netbsd openbsd
+// +build gc
+
+#include "textflag.h"
+
+//
+// System call support for ppc64, BSD
+//
+
+// Just jump to package syscall's implementation for all these functions.
+// The runtime may know about them.
+
+TEXT	·Syscall(SB),NOSPLIT,$0-56
+	JMP	syscall·Syscall(SB)
+
+TEXT	·Syscall6(SB),NOSPLIT,$0-80
+	JMP	syscall·Syscall6(SB)
+
+TEXT	·Syscall9(SB),NOSPLIT,$0-104
+	JMP	syscall·Syscall9(SB)
+
+TEXT	·RawSyscall(SB),NOSPLIT,$0-56
+	JMP	syscall·RawSyscall(SB)
+
+TEXT	·RawSyscall6(SB),NOSPLIT,$0-80
+	JMP	syscall·RawSyscall6(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/asm_bsd_riscv64.s b/src/cmd/vendor/golang.org/x/sys/unix/asm_bsd_riscv64.s
new file mode 100644
index 0000000..d560019
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/asm_bsd_riscv64.s
@@ -0,0 +1,29 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build (darwin || freebsd || netbsd || openbsd) && gc
+// +build darwin freebsd netbsd openbsd
+// +build gc
+
+#include "textflag.h"
+
+// System call support for RISCV64 BSD
+
+// Just jump to package syscall's implementation for all these functions.
+// The runtime may know about them.
+
+TEXT	·Syscall(SB),NOSPLIT,$0-56
+	JMP	syscall·Syscall(SB)
+
+TEXT	·Syscall6(SB),NOSPLIT,$0-80
+	JMP	syscall·Syscall6(SB)
+
+TEXT	·Syscall9(SB),NOSPLIT,$0-104
+	JMP	syscall·Syscall9(SB)
+
+TEXT	·RawSyscall(SB),NOSPLIT,$0-56
+	JMP	syscall·RawSyscall(SB)
+
+TEXT	·RawSyscall6(SB),NOSPLIT,$0-80
+	JMP	syscall·RawSyscall6(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/dirent.go b/src/cmd/vendor/golang.org/x/sys/unix/dirent.go
index e74e5ea..2499f97 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/dirent.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/dirent.go
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
+// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
 
 package unix
 
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/errors_freebsd_386.go b/src/cmd/vendor/golang.org/x/sys/unix/errors_freebsd_386.go
deleted file mode 100644
index 761db66..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/errors_freebsd_386.go
+++ /dev/null
@@ -1,233 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep
-// them here for backwards compatibility.
-
-package unix
-
-const (
-	DLT_HHDLC                         = 0x79
-	IFF_SMART                         = 0x20
-	IFT_1822                          = 0x2
-	IFT_A12MPPSWITCH                  = 0x82
-	IFT_AAL2                          = 0xbb
-	IFT_AAL5                          = 0x31
-	IFT_ADSL                          = 0x5e
-	IFT_AFLANE8023                    = 0x3b
-	IFT_AFLANE8025                    = 0x3c
-	IFT_ARAP                          = 0x58
-	IFT_ARCNET                        = 0x23
-	IFT_ARCNETPLUS                    = 0x24
-	IFT_ASYNC                         = 0x54
-	IFT_ATM                           = 0x25
-	IFT_ATMDXI                        = 0x69
-	IFT_ATMFUNI                       = 0x6a
-	IFT_ATMIMA                        = 0x6b
-	IFT_ATMLOGICAL                    = 0x50
-	IFT_ATMRADIO                      = 0xbd
-	IFT_ATMSUBINTERFACE               = 0x86
-	IFT_ATMVCIENDPT                   = 0xc2
-	IFT_ATMVIRTUAL                    = 0x95
-	IFT_BGPPOLICYACCOUNTING           = 0xa2
-	IFT_BSC                           = 0x53
-	IFT_CCTEMUL                       = 0x3d
-	IFT_CEPT                          = 0x13
-	IFT_CES                           = 0x85
-	IFT_CHANNEL                       = 0x46
-	IFT_CNR                           = 0x55
-	IFT_COFFEE                        = 0x84
-	IFT_COMPOSITELINK                 = 0x9b
-	IFT_DCN                           = 0x8d
-	IFT_DIGITALPOWERLINE              = 0x8a
-	IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
-	IFT_DLSW                          = 0x4a
-	IFT_DOCSCABLEDOWNSTREAM           = 0x80
-	IFT_DOCSCABLEMACLAYER             = 0x7f
-	IFT_DOCSCABLEUPSTREAM             = 0x81
-	IFT_DS0                           = 0x51
-	IFT_DS0BUNDLE                     = 0x52
-	IFT_DS1FDL                        = 0xaa
-	IFT_DS3                           = 0x1e
-	IFT_DTM                           = 0x8c
-	IFT_DVBASILN                      = 0xac
-	IFT_DVBASIOUT                     = 0xad
-	IFT_DVBRCCDOWNSTREAM              = 0x93
-	IFT_DVBRCCMACLAYER                = 0x92
-	IFT_DVBRCCUPSTREAM                = 0x94
-	IFT_ENC                           = 0xf4
-	IFT_EON                           = 0x19
-	IFT_EPLRS                         = 0x57
-	IFT_ESCON                         = 0x49
-	IFT_ETHER                         = 0x6
-	IFT_FAITH                         = 0xf2
-	IFT_FAST                          = 0x7d
-	IFT_FASTETHER                     = 0x3e
-	IFT_FASTETHERFX                   = 0x45
-	IFT_FDDI                          = 0xf
-	IFT_FIBRECHANNEL                  = 0x38
-	IFT_FRAMERELAYINTERCONNECT        = 0x3a
-	IFT_FRAMERELAYMPI                 = 0x5c
-	IFT_FRDLCIENDPT                   = 0xc1
-	IFT_FRELAY                        = 0x20
-	IFT_FRELAYDCE                     = 0x2c
-	IFT_FRF16MFRBUNDLE                = 0xa3
-	IFT_FRFORWARD                     = 0x9e
-	IFT_G703AT2MB                     = 0x43
-	IFT_G703AT64K                     = 0x42
-	IFT_GIF                           = 0xf0
-	IFT_GIGABITETHERNET               = 0x75
-	IFT_GR303IDT                      = 0xb2
-	IFT_GR303RDT                      = 0xb1
-	IFT_H323GATEKEEPER                = 0xa4
-	IFT_H323PROXY                     = 0xa5
-	IFT_HDH1822                       = 0x3
-	IFT_HDLC                          = 0x76
-	IFT_HDSL2                         = 0xa8
-	IFT_HIPERLAN2                     = 0xb7
-	IFT_HIPPI                         = 0x2f
-	IFT_HIPPIINTERFACE                = 0x39
-	IFT_HOSTPAD                       = 0x5a
-	IFT_HSSI                          = 0x2e
-	IFT_HY                            = 0xe
-	IFT_IBM370PARCHAN                 = 0x48
-	IFT_IDSL                          = 0x9a
-	IFT_IEEE80211                     = 0x47
-	IFT_IEEE80212                     = 0x37
-	IFT_IEEE8023ADLAG                 = 0xa1
-	IFT_IFGSN                         = 0x91
-	IFT_IMT                           = 0xbe
-	IFT_INTERLEAVE                    = 0x7c
-	IFT_IP                            = 0x7e
-	IFT_IPFORWARD                     = 0x8e
-	IFT_IPOVERATM                     = 0x72
-	IFT_IPOVERCDLC                    = 0x6d
-	IFT_IPOVERCLAW                    = 0x6e
-	IFT_IPSWITCH                      = 0x4e
-	IFT_IPXIP                         = 0xf9
-	IFT_ISDN                          = 0x3f
-	IFT_ISDNBASIC                     = 0x14
-	IFT_ISDNPRIMARY                   = 0x15
-	IFT_ISDNS                         = 0x4b
-	IFT_ISDNU                         = 0x4c
-	IFT_ISO88022LLC                   = 0x29
-	IFT_ISO88023                      = 0x7
-	IFT_ISO88024                      = 0x8
-	IFT_ISO88025                      = 0x9
-	IFT_ISO88025CRFPINT               = 0x62
-	IFT_ISO88025DTR                   = 0x56
-	IFT_ISO88025FIBER                 = 0x73
-	IFT_ISO88026                      = 0xa
-	IFT_ISUP                          = 0xb3
-	IFT_L3IPXVLAN                     = 0x89
-	IFT_LAPB                          = 0x10
-	IFT_LAPD                          = 0x4d
-	IFT_LAPF                          = 0x77
-	IFT_LOCALTALK                     = 0x2a
-	IFT_LOOP                          = 0x18
-	IFT_MEDIAMAILOVERIP               = 0x8b
-	IFT_MFSIGLINK                     = 0xa7
-	IFT_MIOX25                        = 0x26
-	IFT_MODEM                         = 0x30
-	IFT_MPC                           = 0x71
-	IFT_MPLS                          = 0xa6
-	IFT_MPLSTUNNEL                    = 0x96
-	IFT_MSDSL                         = 0x8f
-	IFT_MVL                           = 0xbf
-	IFT_MYRINET                       = 0x63
-	IFT_NFAS                          = 0xaf
-	IFT_NSIP                          = 0x1b
-	IFT_OPTICALCHANNEL                = 0xc3
-	IFT_OPTICALTRANSPORT              = 0xc4
-	IFT_OTHER                         = 0x1
-	IFT_P10                           = 0xc
-	IFT_P80                           = 0xd
-	IFT_PARA                          = 0x22
-	IFT_PFLOG                         = 0xf6
-	IFT_PFSYNC                        = 0xf7
-	IFT_PLC                           = 0xae
-	IFT_POS                           = 0xab
-	IFT_PPPMULTILINKBUNDLE            = 0x6c
-	IFT_PROPBWAP2MP                   = 0xb8
-	IFT_PROPCNLS                      = 0x59
-	IFT_PROPDOCSWIRELESSDOWNSTREAM    = 0xb5
-	IFT_PROPDOCSWIRELESSMACLAYER      = 0xb4
-	IFT_PROPDOCSWIRELESSUPSTREAM      = 0xb6
-	IFT_PROPMUX                       = 0x36
-	IFT_PROPWIRELESSP2P               = 0x9d
-	IFT_PTPSERIAL                     = 0x16
-	IFT_PVC                           = 0xf1
-	IFT_QLLC                          = 0x44
-	IFT_RADIOMAC                      = 0xbc
-	IFT_RADSL                         = 0x5f
-	IFT_REACHDSL                      = 0xc0
-	IFT_RFC1483                       = 0x9f
-	IFT_RS232                         = 0x21
-	IFT_RSRB                          = 0x4f
-	IFT_SDLC                          = 0x11
-	IFT_SDSL                          = 0x60
-	IFT_SHDSL                         = 0xa9
-	IFT_SIP                           = 0x1f
-	IFT_SLIP                          = 0x1c
-	IFT_SMDSDXI                       = 0x2b
-	IFT_SMDSICIP                      = 0x34
-	IFT_SONET                         = 0x27
-	IFT_SONETOVERHEADCHANNEL          = 0xb9
-	IFT_SONETPATH                     = 0x32
-	IFT_SONETVT                       = 0x33
-	IFT_SRP                           = 0x97
-	IFT_SS7SIGLINK                    = 0x9c
-	IFT_STACKTOSTACK                  = 0x6f
-	IFT_STARLAN                       = 0xb
-	IFT_STF                           = 0xd7
-	IFT_T1                            = 0x12
-	IFT_TDLC                          = 0x74
-	IFT_TERMPAD                       = 0x5b
-	IFT_TR008                         = 0xb0
-	IFT_TRANSPHDLC                    = 0x7b
-	IFT_TUNNEL                        = 0x83
-	IFT_ULTRA                         = 0x1d
-	IFT_USB                           = 0xa0
-	IFT_V11                           = 0x40
-	IFT_V35                           = 0x2d
-	IFT_V36                           = 0x41
-	IFT_V37                           = 0x78
-	IFT_VDSL                          = 0x61
-	IFT_VIRTUALIPADDRESS              = 0x70
-	IFT_VOICEEM                       = 0x64
-	IFT_VOICEENCAP                    = 0x67
-	IFT_VOICEFXO                      = 0x65
-	IFT_VOICEFXS                      = 0x66
-	IFT_VOICEOVERATM                  = 0x98
-	IFT_VOICEOVERFRAMERELAY           = 0x99
-	IFT_VOICEOVERIP                   = 0x68
-	IFT_X213                          = 0x5d
-	IFT_X25                           = 0x5
-	IFT_X25DDN                        = 0x4
-	IFT_X25HUNTGROUP                  = 0x7a
-	IFT_X25MLP                        = 0x79
-	IFT_X25PLE                        = 0x28
-	IFT_XETHER                        = 0x1a
-	IPPROTO_MAXID                     = 0x34
-	IPV6_FAITH                        = 0x1d
-	IPV6_MIN_MEMBERSHIPS              = 0x1f
-	IP_FAITH                          = 0x16
-	IP_MAX_SOURCE_FILTER              = 0x400
-	IP_MIN_MEMBERSHIPS                = 0x1f
-	MAP_NORESERVE                     = 0x40
-	MAP_RENAME                        = 0x20
-	NET_RT_MAXID                      = 0x6
-	RTF_PRCLONING                     = 0x10000
-	RTM_OLDADD                        = 0x9
-	RTM_OLDDEL                        = 0xa
-	RT_CACHING_CONTEXT                = 0x1
-	RT_NORTREF                        = 0x2
-	SIOCADDRT                         = 0x8030720a
-	SIOCALIFADDR                      = 0x8118691b
-	SIOCDELRT                         = 0x8030720b
-	SIOCDLIFADDR                      = 0x8118691d
-	SIOCGLIFADDR                      = 0xc118691c
-	SIOCGLIFPHYADDR                   = 0xc118694b
-	SIOCSLIFPHYADDR                   = 0x8118694a
-)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/errors_freebsd_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/errors_freebsd_amd64.go
deleted file mode 100644
index 070f44b..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/errors_freebsd_amd64.go
+++ /dev/null
@@ -1,233 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep
-// them here for backwards compatibility.
-
-package unix
-
-const (
-	DLT_HHDLC                         = 0x79
-	IFF_SMART                         = 0x20
-	IFT_1822                          = 0x2
-	IFT_A12MPPSWITCH                  = 0x82
-	IFT_AAL2                          = 0xbb
-	IFT_AAL5                          = 0x31
-	IFT_ADSL                          = 0x5e
-	IFT_AFLANE8023                    = 0x3b
-	IFT_AFLANE8025                    = 0x3c
-	IFT_ARAP                          = 0x58
-	IFT_ARCNET                        = 0x23
-	IFT_ARCNETPLUS                    = 0x24
-	IFT_ASYNC                         = 0x54
-	IFT_ATM                           = 0x25
-	IFT_ATMDXI                        = 0x69
-	IFT_ATMFUNI                       = 0x6a
-	IFT_ATMIMA                        = 0x6b
-	IFT_ATMLOGICAL                    = 0x50
-	IFT_ATMRADIO                      = 0xbd
-	IFT_ATMSUBINTERFACE               = 0x86
-	IFT_ATMVCIENDPT                   = 0xc2
-	IFT_ATMVIRTUAL                    = 0x95
-	IFT_BGPPOLICYACCOUNTING           = 0xa2
-	IFT_BSC                           = 0x53
-	IFT_CCTEMUL                       = 0x3d
-	IFT_CEPT                          = 0x13
-	IFT_CES                           = 0x85
-	IFT_CHANNEL                       = 0x46
-	IFT_CNR                           = 0x55
-	IFT_COFFEE                        = 0x84
-	IFT_COMPOSITELINK                 = 0x9b
-	IFT_DCN                           = 0x8d
-	IFT_DIGITALPOWERLINE              = 0x8a
-	IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
-	IFT_DLSW                          = 0x4a
-	IFT_DOCSCABLEDOWNSTREAM           = 0x80
-	IFT_DOCSCABLEMACLAYER             = 0x7f
-	IFT_DOCSCABLEUPSTREAM             = 0x81
-	IFT_DS0                           = 0x51
-	IFT_DS0BUNDLE                     = 0x52
-	IFT_DS1FDL                        = 0xaa
-	IFT_DS3                           = 0x1e
-	IFT_DTM                           = 0x8c
-	IFT_DVBASILN                      = 0xac
-	IFT_DVBASIOUT                     = 0xad
-	IFT_DVBRCCDOWNSTREAM              = 0x93
-	IFT_DVBRCCMACLAYER                = 0x92
-	IFT_DVBRCCUPSTREAM                = 0x94
-	IFT_ENC                           = 0xf4
-	IFT_EON                           = 0x19
-	IFT_EPLRS                         = 0x57
-	IFT_ESCON                         = 0x49
-	IFT_ETHER                         = 0x6
-	IFT_FAITH                         = 0xf2
-	IFT_FAST                          = 0x7d
-	IFT_FASTETHER                     = 0x3e
-	IFT_FASTETHERFX                   = 0x45
-	IFT_FDDI                          = 0xf
-	IFT_FIBRECHANNEL                  = 0x38
-	IFT_FRAMERELAYINTERCONNECT        = 0x3a
-	IFT_FRAMERELAYMPI                 = 0x5c
-	IFT_FRDLCIENDPT                   = 0xc1
-	IFT_FRELAY                        = 0x20
-	IFT_FRELAYDCE                     = 0x2c
-	IFT_FRF16MFRBUNDLE                = 0xa3
-	IFT_FRFORWARD                     = 0x9e
-	IFT_G703AT2MB                     = 0x43
-	IFT_G703AT64K                     = 0x42
-	IFT_GIF                           = 0xf0
-	IFT_GIGABITETHERNET               = 0x75
-	IFT_GR303IDT                      = 0xb2
-	IFT_GR303RDT                      = 0xb1
-	IFT_H323GATEKEEPER                = 0xa4
-	IFT_H323PROXY                     = 0xa5
-	IFT_HDH1822                       = 0x3
-	IFT_HDLC                          = 0x76
-	IFT_HDSL2                         = 0xa8
-	IFT_HIPERLAN2                     = 0xb7
-	IFT_HIPPI                         = 0x2f
-	IFT_HIPPIINTERFACE                = 0x39
-	IFT_HOSTPAD                       = 0x5a
-	IFT_HSSI                          = 0x2e
-	IFT_HY                            = 0xe
-	IFT_IBM370PARCHAN                 = 0x48
-	IFT_IDSL                          = 0x9a
-	IFT_IEEE80211                     = 0x47
-	IFT_IEEE80212                     = 0x37
-	IFT_IEEE8023ADLAG                 = 0xa1
-	IFT_IFGSN                         = 0x91
-	IFT_IMT                           = 0xbe
-	IFT_INTERLEAVE                    = 0x7c
-	IFT_IP                            = 0x7e
-	IFT_IPFORWARD                     = 0x8e
-	IFT_IPOVERATM                     = 0x72
-	IFT_IPOVERCDLC                    = 0x6d
-	IFT_IPOVERCLAW                    = 0x6e
-	IFT_IPSWITCH                      = 0x4e
-	IFT_IPXIP                         = 0xf9
-	IFT_ISDN                          = 0x3f
-	IFT_ISDNBASIC                     = 0x14
-	IFT_ISDNPRIMARY                   = 0x15
-	IFT_ISDNS                         = 0x4b
-	IFT_ISDNU                         = 0x4c
-	IFT_ISO88022LLC                   = 0x29
-	IFT_ISO88023                      = 0x7
-	IFT_ISO88024                      = 0x8
-	IFT_ISO88025                      = 0x9
-	IFT_ISO88025CRFPINT               = 0x62
-	IFT_ISO88025DTR                   = 0x56
-	IFT_ISO88025FIBER                 = 0x73
-	IFT_ISO88026                      = 0xa
-	IFT_ISUP                          = 0xb3
-	IFT_L3IPXVLAN                     = 0x89
-	IFT_LAPB                          = 0x10
-	IFT_LAPD                          = 0x4d
-	IFT_LAPF                          = 0x77
-	IFT_LOCALTALK                     = 0x2a
-	IFT_LOOP                          = 0x18
-	IFT_MEDIAMAILOVERIP               = 0x8b
-	IFT_MFSIGLINK                     = 0xa7
-	IFT_MIOX25                        = 0x26
-	IFT_MODEM                         = 0x30
-	IFT_MPC                           = 0x71
-	IFT_MPLS                          = 0xa6
-	IFT_MPLSTUNNEL                    = 0x96
-	IFT_MSDSL                         = 0x8f
-	IFT_MVL                           = 0xbf
-	IFT_MYRINET                       = 0x63
-	IFT_NFAS                          = 0xaf
-	IFT_NSIP                          = 0x1b
-	IFT_OPTICALCHANNEL                = 0xc3
-	IFT_OPTICALTRANSPORT              = 0xc4
-	IFT_OTHER                         = 0x1
-	IFT_P10                           = 0xc
-	IFT_P80                           = 0xd
-	IFT_PARA                          = 0x22
-	IFT_PFLOG                         = 0xf6
-	IFT_PFSYNC                        = 0xf7
-	IFT_PLC                           = 0xae
-	IFT_POS                           = 0xab
-	IFT_PPPMULTILINKBUNDLE            = 0x6c
-	IFT_PROPBWAP2MP                   = 0xb8
-	IFT_PROPCNLS                      = 0x59
-	IFT_PROPDOCSWIRELESSDOWNSTREAM    = 0xb5
-	IFT_PROPDOCSWIRELESSMACLAYER      = 0xb4
-	IFT_PROPDOCSWIRELESSUPSTREAM      = 0xb6
-	IFT_PROPMUX                       = 0x36
-	IFT_PROPWIRELESSP2P               = 0x9d
-	IFT_PTPSERIAL                     = 0x16
-	IFT_PVC                           = 0xf1
-	IFT_QLLC                          = 0x44
-	IFT_RADIOMAC                      = 0xbc
-	IFT_RADSL                         = 0x5f
-	IFT_REACHDSL                      = 0xc0
-	IFT_RFC1483                       = 0x9f
-	IFT_RS232                         = 0x21
-	IFT_RSRB                          = 0x4f
-	IFT_SDLC                          = 0x11
-	IFT_SDSL                          = 0x60
-	IFT_SHDSL                         = 0xa9
-	IFT_SIP                           = 0x1f
-	IFT_SLIP                          = 0x1c
-	IFT_SMDSDXI                       = 0x2b
-	IFT_SMDSICIP                      = 0x34
-	IFT_SONET                         = 0x27
-	IFT_SONETOVERHEADCHANNEL          = 0xb9
-	IFT_SONETPATH                     = 0x32
-	IFT_SONETVT                       = 0x33
-	IFT_SRP                           = 0x97
-	IFT_SS7SIGLINK                    = 0x9c
-	IFT_STACKTOSTACK                  = 0x6f
-	IFT_STARLAN                       = 0xb
-	IFT_STF                           = 0xd7
-	IFT_T1                            = 0x12
-	IFT_TDLC                          = 0x74
-	IFT_TERMPAD                       = 0x5b
-	IFT_TR008                         = 0xb0
-	IFT_TRANSPHDLC                    = 0x7b
-	IFT_TUNNEL                        = 0x83
-	IFT_ULTRA                         = 0x1d
-	IFT_USB                           = 0xa0
-	IFT_V11                           = 0x40
-	IFT_V35                           = 0x2d
-	IFT_V36                           = 0x41
-	IFT_V37                           = 0x78
-	IFT_VDSL                          = 0x61
-	IFT_VIRTUALIPADDRESS              = 0x70
-	IFT_VOICEEM                       = 0x64
-	IFT_VOICEENCAP                    = 0x67
-	IFT_VOICEFXO                      = 0x65
-	IFT_VOICEFXS                      = 0x66
-	IFT_VOICEOVERATM                  = 0x98
-	IFT_VOICEOVERFRAMERELAY           = 0x99
-	IFT_VOICEOVERIP                   = 0x68
-	IFT_X213                          = 0x5d
-	IFT_X25                           = 0x5
-	IFT_X25DDN                        = 0x4
-	IFT_X25HUNTGROUP                  = 0x7a
-	IFT_X25MLP                        = 0x79
-	IFT_X25PLE                        = 0x28
-	IFT_XETHER                        = 0x1a
-	IPPROTO_MAXID                     = 0x34
-	IPV6_FAITH                        = 0x1d
-	IPV6_MIN_MEMBERSHIPS              = 0x1f
-	IP_FAITH                          = 0x16
-	IP_MAX_SOURCE_FILTER              = 0x400
-	IP_MIN_MEMBERSHIPS                = 0x1f
-	MAP_NORESERVE                     = 0x40
-	MAP_RENAME                        = 0x20
-	NET_RT_MAXID                      = 0x6
-	RTF_PRCLONING                     = 0x10000
-	RTM_OLDADD                        = 0x9
-	RTM_OLDDEL                        = 0xa
-	RT_CACHING_CONTEXT                = 0x1
-	RT_NORTREF                        = 0x2
-	SIOCADDRT                         = 0x8040720a
-	SIOCALIFADDR                      = 0x8118691b
-	SIOCDELRT                         = 0x8040720b
-	SIOCDLIFADDR                      = 0x8118691d
-	SIOCGLIFADDR                      = 0xc118691c
-	SIOCGLIFPHYADDR                   = 0xc118694b
-	SIOCSLIFPHYADDR                   = 0x8118694a
-)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/errors_freebsd_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/errors_freebsd_arm.go
deleted file mode 100644
index 856dca3..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/errors_freebsd_arm.go
+++ /dev/null
@@ -1,226 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package unix
-
-const (
-	IFT_1822                          = 0x2
-	IFT_A12MPPSWITCH                  = 0x82
-	IFT_AAL2                          = 0xbb
-	IFT_AAL5                          = 0x31
-	IFT_ADSL                          = 0x5e
-	IFT_AFLANE8023                    = 0x3b
-	IFT_AFLANE8025                    = 0x3c
-	IFT_ARAP                          = 0x58
-	IFT_ARCNET                        = 0x23
-	IFT_ARCNETPLUS                    = 0x24
-	IFT_ASYNC                         = 0x54
-	IFT_ATM                           = 0x25
-	IFT_ATMDXI                        = 0x69
-	IFT_ATMFUNI                       = 0x6a
-	IFT_ATMIMA                        = 0x6b
-	IFT_ATMLOGICAL                    = 0x50
-	IFT_ATMRADIO                      = 0xbd
-	IFT_ATMSUBINTERFACE               = 0x86
-	IFT_ATMVCIENDPT                   = 0xc2
-	IFT_ATMVIRTUAL                    = 0x95
-	IFT_BGPPOLICYACCOUNTING           = 0xa2
-	IFT_BSC                           = 0x53
-	IFT_CCTEMUL                       = 0x3d
-	IFT_CEPT                          = 0x13
-	IFT_CES                           = 0x85
-	IFT_CHANNEL                       = 0x46
-	IFT_CNR                           = 0x55
-	IFT_COFFEE                        = 0x84
-	IFT_COMPOSITELINK                 = 0x9b
-	IFT_DCN                           = 0x8d
-	IFT_DIGITALPOWERLINE              = 0x8a
-	IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
-	IFT_DLSW                          = 0x4a
-	IFT_DOCSCABLEDOWNSTREAM           = 0x80
-	IFT_DOCSCABLEMACLAYER             = 0x7f
-	IFT_DOCSCABLEUPSTREAM             = 0x81
-	IFT_DS0                           = 0x51
-	IFT_DS0BUNDLE                     = 0x52
-	IFT_DS1FDL                        = 0xaa
-	IFT_DS3                           = 0x1e
-	IFT_DTM                           = 0x8c
-	IFT_DVBASILN                      = 0xac
-	IFT_DVBASIOUT                     = 0xad
-	IFT_DVBRCCDOWNSTREAM              = 0x93
-	IFT_DVBRCCMACLAYER                = 0x92
-	IFT_DVBRCCUPSTREAM                = 0x94
-	IFT_ENC                           = 0xf4
-	IFT_EON                           = 0x19
-	IFT_EPLRS                         = 0x57
-	IFT_ESCON                         = 0x49
-	IFT_ETHER                         = 0x6
-	IFT_FAST                          = 0x7d
-	IFT_FASTETHER                     = 0x3e
-	IFT_FASTETHERFX                   = 0x45
-	IFT_FDDI                          = 0xf
-	IFT_FIBRECHANNEL                  = 0x38
-	IFT_FRAMERELAYINTERCONNECT        = 0x3a
-	IFT_FRAMERELAYMPI                 = 0x5c
-	IFT_FRDLCIENDPT                   = 0xc1
-	IFT_FRELAY                        = 0x20
-	IFT_FRELAYDCE                     = 0x2c
-	IFT_FRF16MFRBUNDLE                = 0xa3
-	IFT_FRFORWARD                     = 0x9e
-	IFT_G703AT2MB                     = 0x43
-	IFT_G703AT64K                     = 0x42
-	IFT_GIF                           = 0xf0
-	IFT_GIGABITETHERNET               = 0x75
-	IFT_GR303IDT                      = 0xb2
-	IFT_GR303RDT                      = 0xb1
-	IFT_H323GATEKEEPER                = 0xa4
-	IFT_H323PROXY                     = 0xa5
-	IFT_HDH1822                       = 0x3
-	IFT_HDLC                          = 0x76
-	IFT_HDSL2                         = 0xa8
-	IFT_HIPERLAN2                     = 0xb7
-	IFT_HIPPI                         = 0x2f
-	IFT_HIPPIINTERFACE                = 0x39
-	IFT_HOSTPAD                       = 0x5a
-	IFT_HSSI                          = 0x2e
-	IFT_HY                            = 0xe
-	IFT_IBM370PARCHAN                 = 0x48
-	IFT_IDSL                          = 0x9a
-	IFT_IEEE80211                     = 0x47
-	IFT_IEEE80212                     = 0x37
-	IFT_IEEE8023ADLAG                 = 0xa1
-	IFT_IFGSN                         = 0x91
-	IFT_IMT                           = 0xbe
-	IFT_INTERLEAVE                    = 0x7c
-	IFT_IP                            = 0x7e
-	IFT_IPFORWARD                     = 0x8e
-	IFT_IPOVERATM                     = 0x72
-	IFT_IPOVERCDLC                    = 0x6d
-	IFT_IPOVERCLAW                    = 0x6e
-	IFT_IPSWITCH                      = 0x4e
-	IFT_ISDN                          = 0x3f
-	IFT_ISDNBASIC                     = 0x14
-	IFT_ISDNPRIMARY                   = 0x15
-	IFT_ISDNS                         = 0x4b
-	IFT_ISDNU                         = 0x4c
-	IFT_ISO88022LLC                   = 0x29
-	IFT_ISO88023                      = 0x7
-	IFT_ISO88024                      = 0x8
-	IFT_ISO88025                      = 0x9
-	IFT_ISO88025CRFPINT               = 0x62
-	IFT_ISO88025DTR                   = 0x56
-	IFT_ISO88025FIBER                 = 0x73
-	IFT_ISO88026                      = 0xa
-	IFT_ISUP                          = 0xb3
-	IFT_L3IPXVLAN                     = 0x89
-	IFT_LAPB                          = 0x10
-	IFT_LAPD                          = 0x4d
-	IFT_LAPF                          = 0x77
-	IFT_LOCALTALK                     = 0x2a
-	IFT_LOOP                          = 0x18
-	IFT_MEDIAMAILOVERIP               = 0x8b
-	IFT_MFSIGLINK                     = 0xa7
-	IFT_MIOX25                        = 0x26
-	IFT_MODEM                         = 0x30
-	IFT_MPC                           = 0x71
-	IFT_MPLS                          = 0xa6
-	IFT_MPLSTUNNEL                    = 0x96
-	IFT_MSDSL                         = 0x8f
-	IFT_MVL                           = 0xbf
-	IFT_MYRINET                       = 0x63
-	IFT_NFAS                          = 0xaf
-	IFT_NSIP                          = 0x1b
-	IFT_OPTICALCHANNEL                = 0xc3
-	IFT_OPTICALTRANSPORT              = 0xc4
-	IFT_OTHER                         = 0x1
-	IFT_P10                           = 0xc
-	IFT_P80                           = 0xd
-	IFT_PARA                          = 0x22
-	IFT_PFLOG                         = 0xf6
-	IFT_PFSYNC                        = 0xf7
-	IFT_PLC                           = 0xae
-	IFT_POS                           = 0xab
-	IFT_PPPMULTILINKBUNDLE            = 0x6c
-	IFT_PROPBWAP2MP                   = 0xb8
-	IFT_PROPCNLS                      = 0x59
-	IFT_PROPDOCSWIRELESSDOWNSTREAM    = 0xb5
-	IFT_PROPDOCSWIRELESSMACLAYER      = 0xb4
-	IFT_PROPDOCSWIRELESSUPSTREAM      = 0xb6
-	IFT_PROPMUX                       = 0x36
-	IFT_PROPWIRELESSP2P               = 0x9d
-	IFT_PTPSERIAL                     = 0x16
-	IFT_PVC                           = 0xf1
-	IFT_QLLC                          = 0x44
-	IFT_RADIOMAC                      = 0xbc
-	IFT_RADSL                         = 0x5f
-	IFT_REACHDSL                      = 0xc0
-	IFT_RFC1483                       = 0x9f
-	IFT_RS232                         = 0x21
-	IFT_RSRB                          = 0x4f
-	IFT_SDLC                          = 0x11
-	IFT_SDSL                          = 0x60
-	IFT_SHDSL                         = 0xa9
-	IFT_SIP                           = 0x1f
-	IFT_SLIP                          = 0x1c
-	IFT_SMDSDXI                       = 0x2b
-	IFT_SMDSICIP                      = 0x34
-	IFT_SONET                         = 0x27
-	IFT_SONETOVERHEADCHANNEL          = 0xb9
-	IFT_SONETPATH                     = 0x32
-	IFT_SONETVT                       = 0x33
-	IFT_SRP                           = 0x97
-	IFT_SS7SIGLINK                    = 0x9c
-	IFT_STACKTOSTACK                  = 0x6f
-	IFT_STARLAN                       = 0xb
-	IFT_STF                           = 0xd7
-	IFT_T1                            = 0x12
-	IFT_TDLC                          = 0x74
-	IFT_TERMPAD                       = 0x5b
-	IFT_TR008                         = 0xb0
-	IFT_TRANSPHDLC                    = 0x7b
-	IFT_TUNNEL                        = 0x83
-	IFT_ULTRA                         = 0x1d
-	IFT_USB                           = 0xa0
-	IFT_V11                           = 0x40
-	IFT_V35                           = 0x2d
-	IFT_V36                           = 0x41
-	IFT_V37                           = 0x78
-	IFT_VDSL                          = 0x61
-	IFT_VIRTUALIPADDRESS              = 0x70
-	IFT_VOICEEM                       = 0x64
-	IFT_VOICEENCAP                    = 0x67
-	IFT_VOICEFXO                      = 0x65
-	IFT_VOICEFXS                      = 0x66
-	IFT_VOICEOVERATM                  = 0x98
-	IFT_VOICEOVERFRAMERELAY           = 0x99
-	IFT_VOICEOVERIP                   = 0x68
-	IFT_X213                          = 0x5d
-	IFT_X25                           = 0x5
-	IFT_X25DDN                        = 0x4
-	IFT_X25HUNTGROUP                  = 0x7a
-	IFT_X25MLP                        = 0x79
-	IFT_X25PLE                        = 0x28
-	IFT_XETHER                        = 0x1a
-
-	// missing constants on FreeBSD-11.1-RELEASE, copied from old values in ztypes_freebsd_arm.go
-	IFF_SMART       = 0x20
-	IFT_FAITH       = 0xf2
-	IFT_IPXIP       = 0xf9
-	IPPROTO_MAXID   = 0x34
-	IPV6_FAITH      = 0x1d
-	IP_FAITH        = 0x16
-	MAP_NORESERVE   = 0x40
-	MAP_RENAME      = 0x20
-	NET_RT_MAXID    = 0x6
-	RTF_PRCLONING   = 0x10000
-	RTM_OLDADD      = 0x9
-	RTM_OLDDEL      = 0xa
-	SIOCADDRT       = 0x8030720a
-	SIOCALIFADDR    = 0x8118691b
-	SIOCDELRT       = 0x8030720b
-	SIOCDLIFADDR    = 0x8118691d
-	SIOCGLIFADDR    = 0xc118691c
-	SIOCGLIFPHYADDR = 0xc118694b
-	SIOCSLIFPHYADDR = 0x8118694a
-)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/errors_freebsd_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/errors_freebsd_arm64.go
deleted file mode 100644
index 946dcf3..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/errors_freebsd_arm64.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep
-// them here for backwards compatibility.
-
-package unix
-
-const (
-	DLT_HHDLC            = 0x79
-	IPV6_MIN_MEMBERSHIPS = 0x1f
-	IP_MAX_SOURCE_FILTER = 0x400
-	IP_MIN_MEMBERSHIPS   = 0x1f
-	RT_CACHING_CONTEXT   = 0x1
-	RT_NORTREF           = 0x2
-)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ioctl_linux.go b/src/cmd/vendor/golang.org/x/sys/unix/ioctl_linux.go
index 884430b..0d12c08 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ioctl_linux.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ioctl_linux.go
@@ -4,9 +4,7 @@
 
 package unix
 
-import (
-	"unsafe"
-)
+import "unsafe"
 
 // IoctlRetInt performs an ioctl operation specified by req on a device
 // associated with opened file descriptor fd, and returns a non-negative
@@ -217,3 +215,19 @@
 func IoctlKCMUnattach(fd int, info KCMUnattach) error {
 	return ioctlPtr(fd, SIOCKCMUNATTACH, unsafe.Pointer(&info))
 }
+
+// IoctlLoopGetStatus64 gets the status of the loop device associated with the
+// file descriptor fd using the LOOP_GET_STATUS64 operation.
+func IoctlLoopGetStatus64(fd int) (*LoopInfo64, error) {
+	var value LoopInfo64
+	if err := ioctlPtr(fd, LOOP_GET_STATUS64, unsafe.Pointer(&value)); err != nil {
+		return nil, err
+	}
+	return &value, nil
+}
+
+// IoctlLoopSetStatus64 sets the status of the loop device associated with the
+// file descriptor fd using the LOOP_SET_STATUS64 operation.
+func IoctlLoopSetStatus64(fd int, value *LoopInfo64) error {
+	return ioctlPtr(fd, LOOP_SET_STATUS64, unsafe.Pointer(value))
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/mkall.sh b/src/cmd/vendor/golang.org/x/sys/unix/mkall.sh
index ee73623..727cba2 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/mkall.sh
+++ b/src/cmd/vendor/golang.org/x/sys/unix/mkall.sh
@@ -73,12 +73,12 @@
 darwin_amd64)
 	mkerrors="$mkerrors -m64"
 	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
-	mkasm="go run mkasm_darwin.go"
+	mkasm="go run mkasm.go"
 	;;
 darwin_arm64)
 	mkerrors="$mkerrors -m64"
 	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
-	mkasm="go run mkasm_darwin.go"
+	mkasm="go run mkasm.go"
 	;;
 dragonfly_amd64)
 	mkerrors="$mkerrors -m64"
@@ -89,25 +89,30 @@
 freebsd_386)
 	mkerrors="$mkerrors -m32"
 	mksyscall="go run mksyscall.go -l32"
-	mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master'"
+	mksysnum="go run mksysnum.go 'https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12'"
 	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
 	;;
 freebsd_amd64)
 	mkerrors="$mkerrors -m64"
-	mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master'"
+	mksysnum="go run mksysnum.go 'https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12'"
 	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
 	;;
 freebsd_arm)
 	mkerrors="$mkerrors"
 	mksyscall="go run mksyscall.go -l32 -arm"
-	mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master'"
+	mksysnum="go run mksysnum.go 'https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12'"
 	# Let the type of C char be signed for making the bare syscall
 	# API consistent across platforms.
 	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
 	;;
 freebsd_arm64)
 	mkerrors="$mkerrors -m64"
-	mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master'"
+	mksysnum="go run mksysnum.go 'https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12'"
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
+	;;
+freebsd_riscv64)
+	mkerrors="$mkerrors -m64"
+	mksysnum="go run mksysnum.go 'https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12'"
 	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
 	;;
 netbsd_386)
@@ -137,33 +142,33 @@
 	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
 	;;
 openbsd_386)
+	mkasm="go run mkasm.go"
 	mkerrors="$mkerrors -m32"
-	mksyscall="go run mksyscall.go -l32 -openbsd"
+	mksyscall="go run mksyscall.go -l32 -openbsd -libc"
 	mksysctl="go run mksysctl_openbsd.go"
-	mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'"
 	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
 	;;
 openbsd_amd64)
+	mkasm="go run mkasm.go"
 	mkerrors="$mkerrors -m64"
-	mksyscall="go run mksyscall.go -openbsd"
+	mksyscall="go run mksyscall.go -openbsd -libc"
 	mksysctl="go run mksysctl_openbsd.go"
-	mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'"
 	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
 	;;
 openbsd_arm)
+	mkasm="go run mkasm.go"
 	mkerrors="$mkerrors"
-	mksyscall="go run mksyscall.go -l32 -openbsd -arm"
+	mksyscall="go run mksyscall.go -l32 -openbsd -arm -libc"
 	mksysctl="go run mksysctl_openbsd.go"
-	mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'"
 	# Let the type of C char be signed for making the bare syscall
 	# API consistent across platforms.
 	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
 	;;
 openbsd_arm64)
+	mkasm="go run mkasm.go"
 	mkerrors="$mkerrors -m64"
-	mksyscall="go run mksyscall.go -openbsd"
+	mksyscall="go run mksyscall.go -openbsd -libc"
 	mksysctl="go run mksysctl_openbsd.go"
-	mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'"
 	# Let the type of C char be signed for making the bare syscall
 	# API consistent across platforms.
 	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
@@ -177,6 +182,24 @@
 	# API consistent across platforms.
 	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
 	;;
+openbsd_ppc64)
+	mkasm="go run mkasm.go"
+	mkerrors="$mkerrors -m64"
+	mksyscall="go run mksyscall.go -openbsd -libc"
+	mksysctl="go run mksysctl_openbsd.go"
+	# Let the type of C char be signed for making the bare syscall
+	# API consistent across platforms.
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
+	;;
+openbsd_riscv64)
+	mkasm="go run mkasm.go"
+	mkerrors="$mkerrors -m64"
+	mksyscall="go run mksyscall.go -openbsd -libc"
+	mksysctl="go run mksysctl_openbsd.go"
+	# Let the type of C char be signed for making the bare syscall
+	# API consistent across platforms.
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
+	;;
 solaris_amd64)
 	mksyscall="go run mksyscall_solaris.go"
 	mkerrors="$mkerrors -m64"
@@ -209,11 +232,6 @@
 			if [ "$GOOSARCH" == "aix_ppc64" ]; then
 				# aix/ppc64 script generates files instead of writing to stdin.
 				echo "$mksyscall -tags $GOOS,$GOARCH $syscall_goos $GOOSARCH_in && gofmt -w zsyscall_$GOOSARCH.go && gofmt -w zsyscall_"$GOOSARCH"_gccgo.go && gofmt -w zsyscall_"$GOOSARCH"_gc.go " ;
-			elif [ "$GOOS" == "darwin" ]; then
-			        # 1.12 and later, syscalls via libSystem
-				echo "$mksyscall -tags $GOOS,$GOARCH,go1.12 $syscall_goos $GOOSARCH_in |gofmt >zsyscall_$GOOSARCH.go";
-				# 1.13 and later, syscalls via libSystem (including syscallPtr)
-				echo "$mksyscall -tags $GOOS,$GOARCH,go1.13 syscall_darwin.1_13.go |gofmt >zsyscall_$GOOSARCH.1_13.go";
 			elif [ "$GOOS" == "illumos" ]; then
 			        # illumos code generation requires a --illumos switch
 			        echo "$mksyscall -illumos -tags illumos,$GOARCH syscall_illumos.go |gofmt > zsyscall_illumos_$GOARCH.go";
@@ -227,5 +245,5 @@
 	if [ -n "$mksysctl" ]; then echo "$mksysctl |gofmt >$zsysctl"; fi
 	if [ -n "$mksysnum" ]; then echo "$mksysnum |gofmt >zsysnum_$GOOSARCH.go"; fi
 	if [ -n "$mktypes" ]; then echo "$mktypes types_$GOOS.go | go run mkpost.go > ztypes_$GOOSARCH.go"; fi
-	if [ -n "$mkasm" ]; then echo "$mkasm $GOARCH"; fi
+	if [ -n "$mkasm" ]; then echo "$mkasm $GOOS $GOARCH"; fi
 ) | $run
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/mkerrors.sh b/src/cmd/vendor/golang.org/x/sys/unix/mkerrors.sh
index d888fb7..7456d9d 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/mkerrors.sh
+++ b/src/cmd/vendor/golang.org/x/sys/unix/mkerrors.sh
@@ -128,6 +128,7 @@
 #include <sys/mount.h>
 #include <sys/wait.h>
 #include <sys/ioctl.h>
+#include <sys/ptrace.h>
 #include <net/bpf.h>
 #include <net/if.h>
 #include <net/if_types.h>
@@ -202,6 +203,7 @@
 #include <sys/timerfd.h>
 #include <sys/uio.h>
 #include <sys/xattr.h>
+#include <linux/audit.h>
 #include <linux/bpf.h>
 #include <linux/can.h>
 #include <linux/can/error.h>
@@ -295,6 +297,10 @@
 #define SOL_NETLINK	270
 #endif
 
+#ifndef SOL_SMC
+#define SOL_SMC 286
+#endif
+
 #ifdef SOL_BLUETOOTH
 // SPARC includes this in /usr/include/sparc64-linux-gnu/bits/socket.h
 // but it is already in bluetooth_linux.go
@@ -529,7 +535,7 @@
 		$2 ~ /^(MS|MNT|MOUNT|UMOUNT)_/ ||
 		$2 ~ /^NS_GET_/ ||
 		$2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ ||
-		$2 ~ /^(O|F|[ES]?FD|NAME|S|PTRACE|PT|TFD)_/ ||
+		$2 ~ /^(O|F|[ES]?FD|NAME|S|PTRACE|PT|PIOD|TFD)_/ ||
 		$2 ~ /^KEXEC_/ ||
 		$2 ~ /^LINUX_REBOOT_CMD_/ ||
 		$2 ~ /^LINUX_REBOOT_MAGIC[12]$/ ||
@@ -553,6 +559,7 @@
 		$2 ~ /^CLONE_[A-Z_]+/ ||
 		$2 !~ /^(BPF_TIMEVAL|BPF_FIB_LOOKUP_[A-Z]+)$/ &&
 		$2 ~ /^(BPF|DLT)_/ ||
+		$2 ~ /^AUDIT_/ ||
 		$2 ~ /^(CLOCK|TIMER)_/ ||
 		$2 ~ /^CAN_/ ||
 		$2 ~ /^CAP_/ ||
@@ -575,7 +582,6 @@
 		$2 ~ /^SEEK_/ ||
 		$2 ~ /^SPLICE_/ ||
 		$2 ~ /^SYNC_FILE_RANGE_/ ||
-		$2 !~ /^AUDIT_RECORD_MAGIC/ &&
 		$2 !~ /IOC_MAGIC/ &&
 		$2 ~ /^[A-Z][A-Z0-9_]+_MAGIC2?$/ ||
 		$2 ~ /^(VM|VMADDR)_/ ||
@@ -636,7 +642,7 @@
 signals=$(
 	echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
 	awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' |
-	egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT|SIGMAX64)' |
+	grep -v 'SIGSTKSIZE\|SIGSTKSZ\|SIGRT\|SIGMAX64' |
 	sort
 )
 
@@ -646,7 +652,7 @@
 	sort >_error.grep
 echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
 	awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print "^\t" $2 "[ \t]*=" }' |
-	egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT|SIGMAX64)' |
+	grep -v 'SIGSTKSIZE\|SIGSTKSZ\|SIGRT\|SIGMAX64' |
 	sort >_signal.grep
 
 echo '// mkerrors.sh' "$@"
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/sockcmsg_unix.go b/src/cmd/vendor/golang.org/x/sys/unix/sockcmsg_unix.go
index 453a942..3865943 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/sockcmsg_unix.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/sockcmsg_unix.go
@@ -52,6 +52,20 @@
 	return msgs, nil
 }
 
+// ParseOneSocketControlMessage parses a single socket control message from b, returning the message header,
+// message data (a slice of b), and the remainder of b after that single message.
+// When there are no remaining messages, len(remainder) == 0.
+func ParseOneSocketControlMessage(b []byte) (hdr Cmsghdr, data []byte, remainder []byte, err error) {
+	h, dbuf, err := socketControlMessageHeaderAndData(b)
+	if err != nil {
+		return Cmsghdr{}, nil, nil, err
+	}
+	if i := cmsgAlignOf(int(h.Len)); i < len(b) {
+		remainder = b[i:]
+	}
+	return *h, dbuf, remainder, nil
+}
+
 func socketControlMessageHeaderAndData(b []byte) (*Cmsghdr, []byte, error) {
 	h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
 	if h.Len < SizeofCmsghdr || uint64(h.Len) > uint64(len(b)) {
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/str.go b/src/cmd/vendor/golang.org/x/sys/unix/str.go
deleted file mode 100644
index 8ba89ed..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/str.go
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
-
-package unix
-
-func itoa(val int) string { // do it here rather than with fmt to avoid dependency
-	if val < 0 {
-		return "-" + uitoa(uint(-val))
-	}
-	return uitoa(uint(val))
-}
-
-func uitoa(val uint) string {
-	var buf [32]byte // big enough for int64
-	i := len(buf) - 1
-	for val >= 10 {
-		buf[i] = byte(val%10 + '0')
-		i--
-		val /= 10
-	}
-	buf[i] = byte(val + '0')
-	return string(buf[i:])
-}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall.go
index 649fa87..63e8c83 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall.go
@@ -29,8 +29,6 @@
 	"bytes"
 	"strings"
 	"unsafe"
-
-	"golang.org/x/sys/internal/unsafeheader"
 )
 
 // ByteSliceFromString returns a NUL-terminated slice of bytes
@@ -82,13 +80,7 @@
 		ptr = unsafe.Pointer(uintptr(ptr) + 1)
 	}
 
-	var s []byte
-	h := (*unsafeheader.Slice)(unsafe.Pointer(&s))
-	h.Data = unsafe.Pointer(p)
-	h.Len = n
-	h.Cap = n
-
-	return string(s)
+	return string(unsafe.Slice(p, n))
 }
 
 // Single-word zero for use when we need a valid pointer to 0 bytes.
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_aix.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_aix.go
index ad22c33..2db1b51 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_aix.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_aix.go
@@ -217,14 +217,63 @@
 	return
 }
 
-func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
-	// Recvmsg not implemented on AIX
-	return -1, -1, -1, ENOSYS
+func recvmsgRaw(fd int, iov []Iovec, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
+	var msg Msghdr
+	msg.Name = (*byte)(unsafe.Pointer(rsa))
+	msg.Namelen = uint32(SizeofSockaddrAny)
+	var dummy byte
+	if len(oob) > 0 {
+		// receive at least one normal byte
+		if emptyIovecs(iov) {
+			var iova [1]Iovec
+			iova[0].Base = &dummy
+			iova[0].SetLen(1)
+			iov = iova[:]
+		}
+		msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
+		msg.SetControllen(len(oob))
+	}
+	if len(iov) > 0 {
+		msg.Iov = &iov[0]
+		msg.SetIovlen(len(iov))
+	}
+	if n, err = recvmsg(fd, &msg, flags); n == -1 {
+		return
+	}
+	oobn = int(msg.Controllen)
+	recvflags = int(msg.Flags)
+	return
 }
 
-func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
-	// SendmsgN not implemented on AIX
-	return -1, ENOSYS
+func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
+	var msg Msghdr
+	msg.Name = (*byte)(unsafe.Pointer(ptr))
+	msg.Namelen = uint32(salen)
+	var dummy byte
+	var empty bool
+	if len(oob) > 0 {
+		// send at least one normal byte
+		empty = emptyIovecs(iov)
+		if empty {
+			var iova [1]Iovec
+			iova[0].Base = &dummy
+			iova[0].SetLen(1)
+			iov = iova[:]
+		}
+		msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
+		msg.SetControllen(len(oob))
+	}
+	if len(iov) > 0 {
+		msg.Iov = &iov[0]
+		msg.SetIovlen(len(iov))
+	}
+	if n, err = sendmsg(fd, &msg, flags); err != nil {
+		return 0, err
+	}
+	if len(oob) > 0 && empty {
+		n = 0
+	}
+	return n, nil
 }
 
 func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_bsd.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_bsd.go
index 9c87c5f..eda4267 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_bsd.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_bsd.go
@@ -325,27 +325,26 @@
 //sys	sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)
 //sys	recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
 
-func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
+func recvmsgRaw(fd int, iov []Iovec, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
 	var msg Msghdr
 	msg.Name = (*byte)(unsafe.Pointer(rsa))
 	msg.Namelen = uint32(SizeofSockaddrAny)
-	var iov Iovec
-	if len(p) > 0 {
-		iov.Base = (*byte)(unsafe.Pointer(&p[0]))
-		iov.SetLen(len(p))
-	}
 	var dummy byte
 	if len(oob) > 0 {
 		// receive at least one normal byte
-		if len(p) == 0 {
-			iov.Base = &dummy
-			iov.SetLen(1)
+		if emptyIovecs(iov) {
+			var iova [1]Iovec
+			iova[0].Base = &dummy
+			iova[0].SetLen(1)
+			iov = iova[:]
 		}
 		msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
 		msg.SetControllen(len(oob))
 	}
-	msg.Iov = &iov
-	msg.Iovlen = 1
+	if len(iov) > 0 {
+		msg.Iov = &iov[0]
+		msg.SetIovlen(len(iov))
+	}
 	if n, err = recvmsg(fd, &msg, flags); err != nil {
 		return
 	}
@@ -356,31 +355,32 @@
 
 //sys	sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
 
-func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
+func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
 	var msg Msghdr
 	msg.Name = (*byte)(unsafe.Pointer(ptr))
 	msg.Namelen = uint32(salen)
-	var iov Iovec
-	if len(p) > 0 {
-		iov.Base = (*byte)(unsafe.Pointer(&p[0]))
-		iov.SetLen(len(p))
-	}
 	var dummy byte
+	var empty bool
 	if len(oob) > 0 {
 		// send at least one normal byte
-		if len(p) == 0 {
-			iov.Base = &dummy
-			iov.SetLen(1)
+		empty = emptyIovecs(iov)
+		if empty {
+			var iova [1]Iovec
+			iova[0].Base = &dummy
+			iova[0].SetLen(1)
+			iov = iova[:]
 		}
 		msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
 		msg.SetControllen(len(oob))
 	}
-	msg.Iov = &iov
-	msg.Iovlen = 1
+	if len(iov) > 0 {
+		msg.Iov = &iov[0]
+		msg.SetIovlen(len(iov))
+	}
 	if n, err = sendmsg(fd, &msg, flags); err != nil {
 		return 0, err
 	}
-	if len(oob) > 0 && len(p) == 0 {
+	if len(oob) > 0 && empty {
 		n = 0
 	}
 	return n, nil
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin.1_12.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin.1_12.go
deleted file mode 100644
index b009860..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin.1_12.go
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build darwin && go1.12 && !go1.13
-// +build darwin,go1.12,!go1.13
-
-package unix
-
-import (
-	"unsafe"
-)
-
-const _SYS_GETDIRENTRIES64 = 344
-
-func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
-	// To implement this using libSystem we'd need syscall_syscallPtr for
-	// fdopendir. However, syscallPtr was only added in Go 1.13, so we fall
-	// back to raw syscalls for this func on Go 1.12.
-	var p unsafe.Pointer
-	if len(buf) > 0 {
-		p = unsafe.Pointer(&buf[0])
-	} else {
-		p = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(_SYS_GETDIRENTRIES64, uintptr(fd), uintptr(p), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		return n, errnoErr(e1)
-	}
-	return n, nil
-}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin.1_13.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin.1_13.go
deleted file mode 100644
index 1596426..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin.1_13.go
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build darwin && go1.13
-// +build darwin,go1.13
-
-package unix
-
-import (
-	"unsafe"
-
-	"golang.org/x/sys/internal/unsafeheader"
-)
-
-//sys	closedir(dir uintptr) (err error)
-//sys	readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno)
-
-func fdopendir(fd int) (dir uintptr, err error) {
-	r0, _, e1 := syscall_syscallPtr(libc_fdopendir_trampoline_addr, uintptr(fd), 0, 0)
-	dir = uintptr(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-var libc_fdopendir_trampoline_addr uintptr
-
-//go:cgo_import_dynamic libc_fdopendir fdopendir "/usr/lib/libSystem.B.dylib"
-
-func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
-	// Simulate Getdirentries using fdopendir/readdir_r/closedir.
-	// We store the number of entries to skip in the seek
-	// offset of fd. See issue #31368.
-	// It's not the full required semantics, but should handle the case
-	// of calling Getdirentries or ReadDirent repeatedly.
-	// It won't handle assigning the results of lseek to *basep, or handle
-	// the directory being edited underfoot.
-	skip, err := Seek(fd, 0, 1 /* SEEK_CUR */)
-	if err != nil {
-		return 0, err
-	}
-
-	// We need to duplicate the incoming file descriptor
-	// because the caller expects to retain control of it, but
-	// fdopendir expects to take control of its argument.
-	// Just Dup'ing the file descriptor is not enough, as the
-	// result shares underlying state. Use Openat to make a really
-	// new file descriptor referring to the same directory.
-	fd2, err := Openat(fd, ".", O_RDONLY, 0)
-	if err != nil {
-		return 0, err
-	}
-	d, err := fdopendir(fd2)
-	if err != nil {
-		Close(fd2)
-		return 0, err
-	}
-	defer closedir(d)
-
-	var cnt int64
-	for {
-		var entry Dirent
-		var entryp *Dirent
-		e := readdir_r(d, &entry, &entryp)
-		if e != 0 {
-			return n, errnoErr(e)
-		}
-		if entryp == nil {
-			break
-		}
-		if skip > 0 {
-			skip--
-			cnt++
-			continue
-		}
-
-		reclen := int(entry.Reclen)
-		if reclen > len(buf) {
-			// Not enough room. Return for now.
-			// The counter will let us know where we should start up again.
-			// Note: this strategy for suspending in the middle and
-			// restarting is O(n^2) in the length of the directory. Oh well.
-			break
-		}
-
-		// Copy entry into return buffer.
-		var s []byte
-		hdr := (*unsafeheader.Slice)(unsafe.Pointer(&s))
-		hdr.Data = unsafe.Pointer(&entry)
-		hdr.Cap = reclen
-		hdr.Len = reclen
-		copy(buf, s)
-
-		buf = buf[reclen:]
-		n += reclen
-		cnt++
-	}
-	// Set the seek offset of the input fd to record
-	// how many files we've already returned.
-	_, err = Seek(fd, cnt, 0 /* SEEK_SET */)
-	if err != nil {
-		return n, err
-	}
-
-	return n, nil
-}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin.go
index e5448cc..1f63382 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin.go
@@ -19,6 +19,96 @@
 	"unsafe"
 )
 
+//sys	closedir(dir uintptr) (err error)
+//sys	readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno)
+
+func fdopendir(fd int) (dir uintptr, err error) {
+	r0, _, e1 := syscall_syscallPtr(libc_fdopendir_trampoline_addr, uintptr(fd), 0, 0)
+	dir = uintptr(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_fdopendir_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fdopendir fdopendir "/usr/lib/libSystem.B.dylib"
+
+func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
+	// Simulate Getdirentries using fdopendir/readdir_r/closedir.
+	// We store the number of entries to skip in the seek
+	// offset of fd. See issue #31368.
+	// It's not the full required semantics, but should handle the case
+	// of calling Getdirentries or ReadDirent repeatedly.
+	// It won't handle assigning the results of lseek to *basep, or handle
+	// the directory being edited underfoot.
+	skip, err := Seek(fd, 0, 1 /* SEEK_CUR */)
+	if err != nil {
+		return 0, err
+	}
+
+	// We need to duplicate the incoming file descriptor
+	// because the caller expects to retain control of it, but
+	// fdopendir expects to take control of its argument.
+	// Just Dup'ing the file descriptor is not enough, as the
+	// result shares underlying state. Use Openat to make a really
+	// new file descriptor referring to the same directory.
+	fd2, err := Openat(fd, ".", O_RDONLY, 0)
+	if err != nil {
+		return 0, err
+	}
+	d, err := fdopendir(fd2)
+	if err != nil {
+		Close(fd2)
+		return 0, err
+	}
+	defer closedir(d)
+
+	var cnt int64
+	for {
+		var entry Dirent
+		var entryp *Dirent
+		e := readdir_r(d, &entry, &entryp)
+		if e != 0 {
+			return n, errnoErr(e)
+		}
+		if entryp == nil {
+			break
+		}
+		if skip > 0 {
+			skip--
+			cnt++
+			continue
+		}
+
+		reclen := int(entry.Reclen)
+		if reclen > len(buf) {
+			// Not enough room. Return for now.
+			// The counter will let us know where we should start up again.
+			// Note: this strategy for suspending in the middle and
+			// restarting is O(n^2) in the length of the directory. Oh well.
+			break
+		}
+
+		// Copy entry into return buffer.
+		s := unsafe.Slice((*byte)(unsafe.Pointer(&entry)), reclen)
+		copy(buf, s)
+
+		buf = buf[reclen:]
+		n += reclen
+		cnt++
+	}
+	// Set the seek offset of the input fd to record
+	// how many files we've already returned.
+	_, err = Seek(fd, cnt, 0 /* SEEK_SET */)
+	if err != nil {
+		return n, err
+	}
+
+	return n, nil
+}
+
 // SockaddrDatalink implements the Sockaddr interface for AF_LINK type sockets.
 type SockaddrDatalink struct {
 	Len    uint8
@@ -393,6 +483,13 @@
 	return x, err
 }
 
+func GetsockoptTCPConnectionInfo(fd, level, opt int) (*TCPConnectionInfo, error) {
+	var value TCPConnectionInfo
+	vallen := _Socklen(SizeofTCPConnectionInfo)
+	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
+	return &value, err
+}
+
 func SysctlKinfoProc(name string, args ...int) (*KinfoProc, error) {
 	mib, err := sysctlmib(name, args...)
 	if err != nil {
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd.go
index 6f6c510..de7c23e 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd.go
@@ -17,25 +17,12 @@
 	"unsafe"
 )
 
-const (
-	SYS_FSTAT_FREEBSD12         = 551 // { int fstat(int fd, _Out_ struct stat *sb); }
-	SYS_FSTATAT_FREEBSD12       = 552 // { int fstatat(int fd, _In_z_ char *path, \
-	SYS_GETDIRENTRIES_FREEBSD12 = 554 // { ssize_t getdirentries(int fd, \
-	SYS_STATFS_FREEBSD12        = 555 // { int statfs(_In_z_ char *path, \
-	SYS_FSTATFS_FREEBSD12       = 556 // { int fstatfs(int fd, \
-	SYS_GETFSSTAT_FREEBSD12     = 557 // { int getfsstat( \
-	SYS_MKNODAT_FREEBSD12       = 559 // { int mknodat(int fd, _In_z_ char *path, \
-)
-
 // See https://www.freebsd.org/doc/en_US.ISO8859-1/books/porters-handbook/versions.html.
 var (
 	osreldateOnce sync.Once
 	osreldate     uint32
 )
 
-// INO64_FIRST from /usr/src/lib/libc/sys/compat-ino64.h
-const _ino64First = 1200031
-
 func supportsABI(ver uint32) bool {
 	osreldateOnce.Do(func() { osreldate, _ = SysctlUint32("kern.osreldate") })
 	return osreldate >= ver
@@ -159,38 +146,18 @@
 
 func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
 	var (
-		_p0          unsafe.Pointer
-		bufsize      uintptr
-		oldBuf       []statfs_freebsd11_t
-		needsConvert bool
+		_p0     unsafe.Pointer
+		bufsize uintptr
 	)
-
 	if len(buf) > 0 {
-		if supportsABI(_ino64First) {
-			_p0 = unsafe.Pointer(&buf[0])
-			bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))
-		} else {
-			n := len(buf)
-			oldBuf = make([]statfs_freebsd11_t, n)
-			_p0 = unsafe.Pointer(&oldBuf[0])
-			bufsize = unsafe.Sizeof(statfs_freebsd11_t{}) * uintptr(n)
-			needsConvert = true
-		}
+		_p0 = unsafe.Pointer(&buf[0])
+		bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))
 	}
-	var sysno uintptr = SYS_GETFSSTAT
-	if supportsABI(_ino64First) {
-		sysno = SYS_GETFSSTAT_FREEBSD12
-	}
-	r0, _, e1 := Syscall(sysno, uintptr(_p0), bufsize, uintptr(flags))
+	r0, _, e1 := Syscall(SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags))
 	n = int(r0)
 	if e1 != 0 {
 		err = e1
 	}
-	if e1 == 0 && needsConvert {
-		for i := range oldBuf {
-			buf[i].convertFrom(&oldBuf[i])
-		}
-	}
 	return
 }
 
@@ -245,87 +212,11 @@
 }
 
 func Stat(path string, st *Stat_t) (err error) {
-	var oldStat stat_freebsd11_t
-	if supportsABI(_ino64First) {
-		return fstatat_freebsd12(AT_FDCWD, path, st, 0)
-	}
-	err = stat(path, &oldStat)
-	if err != nil {
-		return err
-	}
-
-	st.convertFrom(&oldStat)
-	return nil
+	return Fstatat(AT_FDCWD, path, st, 0)
 }
 
 func Lstat(path string, st *Stat_t) (err error) {
-	var oldStat stat_freebsd11_t
-	if supportsABI(_ino64First) {
-		return fstatat_freebsd12(AT_FDCWD, path, st, AT_SYMLINK_NOFOLLOW)
-	}
-	err = lstat(path, &oldStat)
-	if err != nil {
-		return err
-	}
-
-	st.convertFrom(&oldStat)
-	return nil
-}
-
-func Fstat(fd int, st *Stat_t) (err error) {
-	var oldStat stat_freebsd11_t
-	if supportsABI(_ino64First) {
-		return fstat_freebsd12(fd, st)
-	}
-	err = fstat(fd, &oldStat)
-	if err != nil {
-		return err
-	}
-
-	st.convertFrom(&oldStat)
-	return nil
-}
-
-func Fstatat(fd int, path string, st *Stat_t, flags int) (err error) {
-	var oldStat stat_freebsd11_t
-	if supportsABI(_ino64First) {
-		return fstatat_freebsd12(fd, path, st, flags)
-	}
-	err = fstatat(fd, path, &oldStat, flags)
-	if err != nil {
-		return err
-	}
-
-	st.convertFrom(&oldStat)
-	return nil
-}
-
-func Statfs(path string, st *Statfs_t) (err error) {
-	var oldStatfs statfs_freebsd11_t
-	if supportsABI(_ino64First) {
-		return statfs_freebsd12(path, st)
-	}
-	err = statfs(path, &oldStatfs)
-	if err != nil {
-		return err
-	}
-
-	st.convertFrom(&oldStatfs)
-	return nil
-}
-
-func Fstatfs(fd int, st *Statfs_t) (err error) {
-	var oldStatfs statfs_freebsd11_t
-	if supportsABI(_ino64First) {
-		return fstatfs_freebsd12(fd, st)
-	}
-	err = fstatfs(fd, &oldStatfs)
-	if err != nil {
-		return err
-	}
-
-	st.convertFrom(&oldStatfs)
-	return nil
+	return Fstatat(AT_FDCWD, path, st, AT_SYMLINK_NOFOLLOW)
 }
 
 func Getdents(fd int, buf []byte) (n int, err error) {
@@ -333,162 +224,25 @@
 }
 
 func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
-	if supportsABI(_ino64First) {
-		if basep == nil || unsafe.Sizeof(*basep) == 8 {
-			return getdirentries_freebsd12(fd, buf, (*uint64)(unsafe.Pointer(basep)))
-		}
-		// The freebsd12 syscall needs a 64-bit base. On 32-bit machines
-		// we can't just use the basep passed in. See #32498.
-		var base uint64 = uint64(*basep)
-		n, err = getdirentries_freebsd12(fd, buf, &base)
-		*basep = uintptr(base)
-		if base>>32 != 0 {
-			// We can't stuff the base back into a uintptr, so any
-			// future calls would be suspect. Generate an error.
-			// EIO is allowed by getdirentries.
-			err = EIO
-		}
-		return
+	if basep == nil || unsafe.Sizeof(*basep) == 8 {
+		return getdirentries(fd, buf, (*uint64)(unsafe.Pointer(basep)))
 	}
-
-	// The old syscall entries are smaller than the new. Use 1/4 of the original
-	// buffer size rounded up to DIRBLKSIZ (see /usr/src/lib/libc/sys/getdirentries.c).
-	oldBufLen := roundup(len(buf)/4, _dirblksiz)
-	oldBuf := make([]byte, oldBufLen)
-	n, err = getdirentries(fd, oldBuf, basep)
-	if err == nil && n > 0 {
-		n = convertFromDirents11(buf, oldBuf[:n])
+	// The syscall needs a 64-bit base. On 32-bit machines
+	// we can't just use the basep passed in. See #32498.
+	var base uint64 = uint64(*basep)
+	n, err = getdirentries(fd, buf, &base)
+	*basep = uintptr(base)
+	if base>>32 != 0 {
+		// We can't stuff the base back into a uintptr, so any
+		// future calls would be suspect. Generate an error.
+		// EIO is allowed by getdirentries.
+		err = EIO
 	}
 	return
 }
 
 func Mknod(path string, mode uint32, dev uint64) (err error) {
-	var oldDev int
-	if supportsABI(_ino64First) {
-		return mknodat_freebsd12(AT_FDCWD, path, mode, dev)
-	}
-	oldDev = int(dev)
-	return mknod(path, mode, oldDev)
-}
-
-func Mknodat(fd int, path string, mode uint32, dev uint64) (err error) {
-	var oldDev int
-	if supportsABI(_ino64First) {
-		return mknodat_freebsd12(fd, path, mode, dev)
-	}
-	oldDev = int(dev)
-	return mknodat(fd, path, mode, oldDev)
-}
-
-// round x to the nearest multiple of y, larger or equal to x.
-//
-// from /usr/include/sys/param.h Macros for counting and rounding.
-// #define roundup(x, y)   ((((x)+((y)-1))/(y))*(y))
-func roundup(x, y int) int {
-	return ((x + y - 1) / y) * y
-}
-
-func (s *Stat_t) convertFrom(old *stat_freebsd11_t) {
-	*s = Stat_t{
-		Dev:     uint64(old.Dev),
-		Ino:     uint64(old.Ino),
-		Nlink:   uint64(old.Nlink),
-		Mode:    old.Mode,
-		Uid:     old.Uid,
-		Gid:     old.Gid,
-		Rdev:    uint64(old.Rdev),
-		Atim:    old.Atim,
-		Mtim:    old.Mtim,
-		Ctim:    old.Ctim,
-		Btim:    old.Btim,
-		Size:    old.Size,
-		Blocks:  old.Blocks,
-		Blksize: old.Blksize,
-		Flags:   old.Flags,
-		Gen:     uint64(old.Gen),
-	}
-}
-
-func (s *Statfs_t) convertFrom(old *statfs_freebsd11_t) {
-	*s = Statfs_t{
-		Version:     _statfsVersion,
-		Type:        old.Type,
-		Flags:       old.Flags,
-		Bsize:       old.Bsize,
-		Iosize:      old.Iosize,
-		Blocks:      old.Blocks,
-		Bfree:       old.Bfree,
-		Bavail:      old.Bavail,
-		Files:       old.Files,
-		Ffree:       old.Ffree,
-		Syncwrites:  old.Syncwrites,
-		Asyncwrites: old.Asyncwrites,
-		Syncreads:   old.Syncreads,
-		Asyncreads:  old.Asyncreads,
-		// Spare
-		Namemax: old.Namemax,
-		Owner:   old.Owner,
-		Fsid:    old.Fsid,
-		// Charspare
-		// Fstypename
-		// Mntfromname
-		// Mntonname
-	}
-
-	sl := old.Fstypename[:]
-	n := clen(*(*[]byte)(unsafe.Pointer(&sl)))
-	copy(s.Fstypename[:], old.Fstypename[:n])
-
-	sl = old.Mntfromname[:]
-	n = clen(*(*[]byte)(unsafe.Pointer(&sl)))
-	copy(s.Mntfromname[:], old.Mntfromname[:n])
-
-	sl = old.Mntonname[:]
-	n = clen(*(*[]byte)(unsafe.Pointer(&sl)))
-	copy(s.Mntonname[:], old.Mntonname[:n])
-}
-
-func convertFromDirents11(buf []byte, old []byte) int {
-	const (
-		fixedSize    = int(unsafe.Offsetof(Dirent{}.Name))
-		oldFixedSize = int(unsafe.Offsetof(dirent_freebsd11{}.Name))
-	)
-
-	dstPos := 0
-	srcPos := 0
-	for dstPos+fixedSize < len(buf) && srcPos+oldFixedSize < len(old) {
-		var dstDirent Dirent
-		var srcDirent dirent_freebsd11
-
-		// If multiple direntries are written, sometimes when we reach the final one,
-		// we may have cap of old less than size of dirent_freebsd11.
-		copy((*[unsafe.Sizeof(srcDirent)]byte)(unsafe.Pointer(&srcDirent))[:], old[srcPos:])
-
-		reclen := roundup(fixedSize+int(srcDirent.Namlen)+1, 8)
-		if dstPos+reclen > len(buf) {
-			break
-		}
-
-		dstDirent.Fileno = uint64(srcDirent.Fileno)
-		dstDirent.Off = 0
-		dstDirent.Reclen = uint16(reclen)
-		dstDirent.Type = srcDirent.Type
-		dstDirent.Pad0 = 0
-		dstDirent.Namlen = uint16(srcDirent.Namlen)
-		dstDirent.Pad1 = 0
-
-		copy(dstDirent.Name[:], srcDirent.Name[:srcDirent.Namlen])
-		copy(buf[dstPos:], (*[unsafe.Sizeof(dstDirent)]byte)(unsafe.Pointer(&dstDirent))[:])
-		padding := buf[dstPos+fixedSize+int(dstDirent.Namlen) : dstPos+reclen]
-		for i := range padding {
-			padding[i] = 0
-		}
-
-		dstPos += int(dstDirent.Reclen)
-		srcPos += int(srcDirent.Reclen)
-	}
-
-	return dstPos
+	return Mknodat(AT_FDCWD, path, mode, dev)
 }
 
 func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
@@ -501,31 +255,31 @@
 //sys	ptrace(request int, pid int, addr uintptr, data int) (err error)
 
 func PtraceAttach(pid int) (err error) {
-	return ptrace(PTRACE_ATTACH, pid, 0, 0)
+	return ptrace(PT_ATTACH, pid, 0, 0)
 }
 
 func PtraceCont(pid int, signal int) (err error) {
-	return ptrace(PTRACE_CONT, pid, 1, signal)
+	return ptrace(PT_CONTINUE, pid, 1, signal)
 }
 
 func PtraceDetach(pid int) (err error) {
-	return ptrace(PTRACE_DETACH, pid, 1, 0)
+	return ptrace(PT_DETACH, pid, 1, 0)
 }
 
 func PtraceGetFpRegs(pid int, fpregsout *FpReg) (err error) {
-	return ptrace(PTRACE_GETFPREGS, pid, uintptr(unsafe.Pointer(fpregsout)), 0)
+	return ptrace(PT_GETFPREGS, pid, uintptr(unsafe.Pointer(fpregsout)), 0)
 }
 
 func PtraceGetRegs(pid int, regsout *Reg) (err error) {
-	return ptrace(PTRACE_GETREGS, pid, uintptr(unsafe.Pointer(regsout)), 0)
+	return ptrace(PT_GETREGS, pid, uintptr(unsafe.Pointer(regsout)), 0)
 }
 
 func PtraceLwpEvents(pid int, enable int) (err error) {
-	return ptrace(PTRACE_LWPEVENTS, pid, 0, enable)
+	return ptrace(PT_LWP_EVENTS, pid, 0, enable)
 }
 
 func PtraceLwpInfo(pid int, info uintptr) (err error) {
-	return ptrace(PTRACE_LWPINFO, pid, info, int(unsafe.Sizeof(PtraceLwpInfoStruct{})))
+	return ptrace(PT_LWPINFO, pid, info, int(unsafe.Sizeof(PtraceLwpInfoStruct{})))
 }
 
 func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) {
@@ -545,11 +299,11 @@
 }
 
 func PtraceSetRegs(pid int, regs *Reg) (err error) {
-	return ptrace(PTRACE_SETREGS, pid, uintptr(unsafe.Pointer(regs)), 0)
+	return ptrace(PT_SETREGS, pid, uintptr(unsafe.Pointer(regs)), 0)
 }
 
 func PtraceSingleStep(pid int) (err error) {
-	return ptrace(PTRACE_SINGLESTEP, pid, 1, 0)
+	return ptrace(PT_STEP, pid, 1, 0)
 }
 
 /*
@@ -591,16 +345,12 @@
 //sys	Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
 //sys	Flock(fd int, how int) (err error)
 //sys	Fpathconf(fd int, name int) (val int, err error)
-//sys	fstat(fd int, stat *stat_freebsd11_t) (err error)
-//sys	fstat_freebsd12(fd int, stat *Stat_t) (err error)
-//sys	fstatat(fd int, path string, stat *stat_freebsd11_t, flags int) (err error)
-//sys	fstatat_freebsd12(fd int, path string, stat *Stat_t, flags int) (err error)
-//sys	fstatfs(fd int, stat *statfs_freebsd11_t) (err error)
-//sys	fstatfs_freebsd12(fd int, stat *Statfs_t) (err error)
+//sys	Fstat(fd int, stat *Stat_t) (err error)
+//sys	Fstatat(fd int, path string, stat *Stat_t, flags int) (err error)
+//sys	Fstatfs(fd int, stat *Statfs_t) (err error)
 //sys	Fsync(fd int) (err error)
 //sys	Ftruncate(fd int, length int64) (err error)
-//sys	getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error)
-//sys	getdirentries_freebsd12(fd int, buf []byte, basep *uint64) (n int, err error)
+//sys	getdirentries(fd int, buf []byte, basep *uint64) (n int, err error)
 //sys	Getdtablesize() (size int)
 //sysnb	Getegid() (egid int)
 //sysnb	Geteuid() (uid int)
@@ -622,13 +372,10 @@
 //sys	Link(path string, link string) (err error)
 //sys	Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error)
 //sys	Listen(s int, backlog int) (err error)
-//sys	lstat(path string, stat *stat_freebsd11_t) (err error)
 //sys	Mkdir(path string, mode uint32) (err error)
 //sys	Mkdirat(dirfd int, path string, mode uint32) (err error)
 //sys	Mkfifo(path string, mode uint32) (err error)
-//sys	mknod(path string, mode uint32, dev int) (err error)
-//sys	mknodat(fd int, path string, mode uint32, dev int) (err error)
-//sys	mknodat_freebsd12(fd int, path string, mode uint32, dev uint64) (err error)
+//sys	Mknodat(fd int, path string, mode uint32, dev uint64) (err error)
 //sys	Nanosleep(time *Timespec, leftover *Timespec) (err error)
 //sys	Open(path string, mode int, perm uint32) (fd int, err error)
 //sys	Openat(fdat int, path string, mode int, perm uint32) (fd int, err error)
@@ -658,9 +405,7 @@
 //sysnb	Setsid() (pid int, err error)
 //sysnb	Settimeofday(tp *Timeval) (err error)
 //sysnb	Setuid(uid int) (err error)
-//sys	stat(path string, stat *stat_freebsd11_t) (err error)
-//sys	statfs(path string, stat *statfs_freebsd11_t) (err error)
-//sys	statfs_freebsd12(path string, stat *Statfs_t) (err error)
+//sys	Statfs(path string, stat *Statfs_t) (err error)
 //sys	Symlink(path string, link string) (err error)
 //sys	Symlinkat(oldpath string, newdirfd int, newpath string) (err error)
 //sys	Sync() (err error)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd_386.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd_386.go
index 342fc32..b11ede8 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd_386.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd_386.go
@@ -57,11 +57,11 @@
 func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
 
 func PtraceGetFsBase(pid int, fsbase *int64) (err error) {
-	return ptrace(PTRACE_GETFSBASE, pid, uintptr(unsafe.Pointer(fsbase)), 0)
+	return ptrace(PT_GETFSBASE, pid, uintptr(unsafe.Pointer(fsbase)), 0)
 }
 
 func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
-	ioDesc := PtraceIoDesc{Op: int32(req), Offs: (*byte)(unsafe.Pointer(addr)), Addr: (*byte)(unsafe.Pointer(&out[0])), Len: uint32(countin)}
-	err = ptrace(PTRACE_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
+	ioDesc := PtraceIoDesc{Op: int32(req), Offs: uintptr(unsafe.Pointer(addr)), Addr: uintptr(unsafe.Pointer(&out[0])), Len: uint32(countin)}
+	err = ptrace(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
 	return int(ioDesc.Len), err
 }
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd_amd64.go
index a32d5aa..9ed8eec 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd_amd64.go
@@ -57,11 +57,11 @@
 func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
 
 func PtraceGetFsBase(pid int, fsbase *int64) (err error) {
-	return ptrace(PTRACE_GETFSBASE, pid, uintptr(unsafe.Pointer(fsbase)), 0)
+	return ptrace(PT_GETFSBASE, pid, uintptr(unsafe.Pointer(fsbase)), 0)
 }
 
 func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
-	ioDesc := PtraceIoDesc{Op: int32(req), Offs: (*byte)(unsafe.Pointer(addr)), Addr: (*byte)(unsafe.Pointer(&out[0])), Len: uint64(countin)}
-	err = ptrace(PTRACE_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
+	ioDesc := PtraceIoDesc{Op: int32(req), Offs: uintptr(unsafe.Pointer(addr)), Addr: uintptr(unsafe.Pointer(&out[0])), Len: uint64(countin)}
+	err = ptrace(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
 	return int(ioDesc.Len), err
 }
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd_arm.go
index 1e36d39..f8ac982 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd_arm.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd_arm.go
@@ -57,7 +57,7 @@
 func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
 
 func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
-	ioDesc := PtraceIoDesc{Op: int32(req), Offs: (*byte)(unsafe.Pointer(addr)), Addr: (*byte)(unsafe.Pointer(&out[0])), Len: uint32(countin)}
-	err = ptrace(PTRACE_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
+	ioDesc := PtraceIoDesc{Op: int32(req), Offs: uintptr(unsafe.Pointer(addr)), Addr: uintptr(unsafe.Pointer(&out[0])), Len: uint32(countin)}
+	err = ptrace(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
 	return int(ioDesc.Len), err
 }
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd_arm64.go
index a09a153..8e93203 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd_arm64.go
@@ -57,7 +57,7 @@
 func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
 
 func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
-	ioDesc := PtraceIoDesc{Op: int32(req), Offs: (*byte)(unsafe.Pointer(addr)), Addr: (*byte)(unsafe.Pointer(&out[0])), Len: uint64(countin)}
-	err = ptrace(PTRACE_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
+	ioDesc := PtraceIoDesc{Op: int32(req), Offs: uintptr(unsafe.Pointer(addr)), Addr: uintptr(unsafe.Pointer(&out[0])), Len: uint64(countin)}
+	err = ptrace(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
 	return int(ioDesc.Len), err
 }
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd_riscv64.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd_riscv64.go
new file mode 100644
index 0000000..cbe1222
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_freebsd_riscv64.go
@@ -0,0 +1,63 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build riscv64 && freebsd
+// +build riscv64,freebsd
+
+package unix
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+func setTimespec(sec, nsec int64) Timespec {
+	return Timespec{Sec: sec, Nsec: nsec}
+}
+
+func setTimeval(sec, usec int64) Timeval {
+	return Timeval{Sec: sec, Usec: usec}
+}
+
+func SetKevent(k *Kevent_t, fd, mode, flags int) {
+	k.Ident = uint64(fd)
+	k.Filter = int16(mode)
+	k.Flags = uint16(flags)
+}
+
+func (iov *Iovec) SetLen(length int) {
+	iov.Len = uint64(length)
+}
+
+func (msghdr *Msghdr) SetControllen(length int) {
+	msghdr.Controllen = uint32(length)
+}
+
+func (msghdr *Msghdr) SetIovlen(length int) {
+	msghdr.Iovlen = int32(length)
+}
+
+func (cmsg *Cmsghdr) SetLen(length int) {
+	cmsg.Len = uint32(length)
+}
+
+func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
+	var writtenOut uint64 = 0
+	_, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0, 0)
+
+	written = int(writtenOut)
+
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
+
+func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
+	ioDesc := PtraceIoDesc{Op: int32(req), Offs: uintptr(unsafe.Pointer(addr)), Addr: uintptr(unsafe.Pointer(&out[0])), Len: uint64(countin)}
+	err = ptrace(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
+	return int(ioDesc.Len), err
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_illumos.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_illumos.go
index 8d5f294..87db5a6 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_illumos.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_illumos.go
@@ -10,8 +10,6 @@
 package unix
 
 import (
-	"fmt"
-	"runtime"
 	"unsafe"
 )
 
@@ -20,10 +18,9 @@
 	for i, b := range bs {
 		iovecs[i].SetLen(len(b))
 		if len(b) > 0 {
-			// somehow Iovec.Base on illumos is (*int8), not (*byte)
-			iovecs[i].Base = (*int8)(unsafe.Pointer(&b[0]))
+			iovecs[i].Base = &b[0]
 		} else {
-			iovecs[i].Base = (*int8)(unsafe.Pointer(&_zero))
+			iovecs[i].Base = (*byte)(unsafe.Pointer(&_zero))
 		}
 	}
 	return iovecs
@@ -80,107 +77,3 @@
 	}
 	return
 }
-
-//sys	putmsg(fd int, clptr *strbuf, dataptr *strbuf, flags int) (err error)
-
-func Putmsg(fd int, cl []byte, data []byte, flags int) (err error) {
-	var clp, datap *strbuf
-	if len(cl) > 0 {
-		clp = &strbuf{
-			Len: int32(len(cl)),
-			Buf: (*int8)(unsafe.Pointer(&cl[0])),
-		}
-	}
-	if len(data) > 0 {
-		datap = &strbuf{
-			Len: int32(len(data)),
-			Buf: (*int8)(unsafe.Pointer(&data[0])),
-		}
-	}
-	return putmsg(fd, clp, datap, flags)
-}
-
-//sys	getmsg(fd int, clptr *strbuf, dataptr *strbuf, flags *int) (err error)
-
-func Getmsg(fd int, cl []byte, data []byte) (retCl []byte, retData []byte, flags int, err error) {
-	var clp, datap *strbuf
-	if len(cl) > 0 {
-		clp = &strbuf{
-			Maxlen: int32(len(cl)),
-			Buf:    (*int8)(unsafe.Pointer(&cl[0])),
-		}
-	}
-	if len(data) > 0 {
-		datap = &strbuf{
-			Maxlen: int32(len(data)),
-			Buf:    (*int8)(unsafe.Pointer(&data[0])),
-		}
-	}
-
-	if err = getmsg(fd, clp, datap, &flags); err != nil {
-		return nil, nil, 0, err
-	}
-
-	if len(cl) > 0 {
-		retCl = cl[:clp.Len]
-	}
-	if len(data) > 0 {
-		retData = data[:datap.Len]
-	}
-	return retCl, retData, flags, nil
-}
-
-func IoctlSetIntRetInt(fd int, req uint, arg int) (int, error) {
-	return ioctlRet(fd, req, uintptr(arg))
-}
-
-func IoctlSetString(fd int, req uint, val string) error {
-	bs := make([]byte, len(val)+1)
-	copy(bs[:len(bs)-1], val)
-	err := ioctl(fd, req, uintptr(unsafe.Pointer(&bs[0])))
-	runtime.KeepAlive(&bs[0])
-	return err
-}
-
-// Lifreq Helpers
-
-func (l *Lifreq) SetName(name string) error {
-	if len(name) >= len(l.Name) {
-		return fmt.Errorf("name cannot be more than %d characters", len(l.Name)-1)
-	}
-	for i := range name {
-		l.Name[i] = int8(name[i])
-	}
-	return nil
-}
-
-func (l *Lifreq) SetLifruInt(d int) {
-	*(*int)(unsafe.Pointer(&l.Lifru[0])) = d
-}
-
-func (l *Lifreq) GetLifruInt() int {
-	return *(*int)(unsafe.Pointer(&l.Lifru[0]))
-}
-
-func (l *Lifreq) SetLifruUint(d uint) {
-	*(*uint)(unsafe.Pointer(&l.Lifru[0])) = d
-}
-
-func (l *Lifreq) GetLifruUint() uint {
-	return *(*uint)(unsafe.Pointer(&l.Lifru[0]))
-}
-
-func IoctlLifreq(fd int, req uint, l *Lifreq) error {
-	return ioctl(fd, req, uintptr(unsafe.Pointer(l)))
-}
-
-// Strioctl Helpers
-
-func (s *Strioctl) SetInt(i int) {
-	s.Len = int32(unsafe.Sizeof(i))
-	s.Dp = (*int8)(unsafe.Pointer(&i))
-}
-
-func IoctlSetStrioctlRetInt(fd int, req uint, s *Strioctl) (int, error) {
-	return ioctlRet(fd, req, uintptr(unsafe.Pointer(s)))
-}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux.go
index c8d2032..c5a9844 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux.go
@@ -13,6 +13,7 @@
 
 import (
 	"encoding/binary"
+	"strconv"
 	"syscall"
 	"time"
 	"unsafe"
@@ -233,7 +234,7 @@
 func Futimes(fd int, tv []Timeval) (err error) {
 	// Believe it or not, this is the best we can do on Linux
 	// (and is what glibc does).
-	return Utimes("/proc/self/fd/"+itoa(fd), tv)
+	return Utimes("/proc/self/fd/"+strconv.Itoa(fd), tv)
 }
 
 const ImplementsGetwd = true
@@ -1499,18 +1500,13 @@
 //sys	keyctlRestrictKeyringByType(cmd int, arg2 int, keyType string, restriction string) (err error) = SYS_KEYCTL
 //sys	keyctlRestrictKeyring(cmd int, arg2 int) (err error) = SYS_KEYCTL
 
-func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
+func recvmsgRaw(fd int, iov []Iovec, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
 	var msg Msghdr
 	msg.Name = (*byte)(unsafe.Pointer(rsa))
 	msg.Namelen = uint32(SizeofSockaddrAny)
-	var iov Iovec
-	if len(p) > 0 {
-		iov.Base = &p[0]
-		iov.SetLen(len(p))
-	}
 	var dummy byte
 	if len(oob) > 0 {
-		if len(p) == 0 {
+		if emptyIovecs(iov) {
 			var sockType int
 			sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
 			if err != nil {
@@ -1518,15 +1514,19 @@
 			}
 			// receive at least one normal byte
 			if sockType != SOCK_DGRAM {
-				iov.Base = &dummy
-				iov.SetLen(1)
+				var iova [1]Iovec
+				iova[0].Base = &dummy
+				iova[0].SetLen(1)
+				iov = iova[:]
 			}
 		}
 		msg.Control = &oob[0]
 		msg.SetControllen(len(oob))
 	}
-	msg.Iov = &iov
-	msg.Iovlen = 1
+	if len(iov) > 0 {
+		msg.Iov = &iov[0]
+		msg.SetIovlen(len(iov))
+	}
 	if n, err = recvmsg(fd, &msg, flags); err != nil {
 		return
 	}
@@ -1535,18 +1535,15 @@
 	return
 }
 
-func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
+func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
 	var msg Msghdr
 	msg.Name = (*byte)(ptr)
 	msg.Namelen = uint32(salen)
-	var iov Iovec
-	if len(p) > 0 {
-		iov.Base = &p[0]
-		iov.SetLen(len(p))
-	}
 	var dummy byte
+	var empty bool
 	if len(oob) > 0 {
-		if len(p) == 0 {
+		empty = emptyIovecs(iov)
+		if empty {
 			var sockType int
 			sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
 			if err != nil {
@@ -1554,19 +1551,23 @@
 			}
 			// send at least one normal byte
 			if sockType != SOCK_DGRAM {
-				iov.Base = &dummy
-				iov.SetLen(1)
+				var iova [1]Iovec
+				iova[0].Base = &dummy
+				iova[0].SetLen(1)
+				iov = iova[:]
 			}
 		}
 		msg.Control = &oob[0]
 		msg.SetControllen(len(oob))
 	}
-	msg.Iov = &iov
-	msg.Iovlen = 1
+	if len(iov) > 0 {
+		msg.Iov = &iov[0]
+		msg.SetIovlen(len(iov))
+	}
 	if n, err = sendmsg(fd, &msg, flags); err != nil {
 		return 0, err
 	}
-	if len(oob) > 0 && len(p) == 0 {
+	if len(oob) > 0 && empty {
 		n = 0
 	}
 	return n, nil
@@ -1892,17 +1893,28 @@
 	return int(ret), nil
 }
 
-// issue 1435.
-// On linux Setuid and Setgid only affects the current thread, not the process.
-// This does not match what most callers expect so we must return an error
-// here rather than letting the caller think that the call succeeded.
-
 func Setuid(uid int) (err error) {
-	return EOPNOTSUPP
+	return syscall.Setuid(uid)
 }
 
-func Setgid(uid int) (err error) {
-	return EOPNOTSUPP
+func Setgid(gid int) (err error) {
+	return syscall.Setgid(gid)
+}
+
+func Setreuid(ruid, euid int) (err error) {
+	return syscall.Setreuid(ruid, euid)
+}
+
+func Setregid(rgid, egid int) (err error) {
+	return syscall.Setregid(rgid, egid)
+}
+
+func Setresuid(ruid, euid, suid int) (err error) {
+	return syscall.Setresuid(ruid, euid, suid)
+}
+
+func Setresgid(rgid, egid, sgid int) (err error) {
+	return syscall.Setresgid(rgid, egid, sgid)
 }
 
 // SetfsgidRetGid sets fsgid for current thread and returns previous fsgid set.
@@ -2241,7 +2253,7 @@
 	if n == 0 {
 		return nil
 	}
-	return (*[1 << 30]byte)(unsafe.Pointer(uintptr(unsafe.Pointer(&fh.fileHandle.Type)) + 4))[:n:n]
+	return unsafe.Slice((*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(&fh.fileHandle.Type))+4)), n)
 }
 
 // NameToHandleAt wraps the name_to_handle_at system call; it obtains
@@ -2357,6 +2369,16 @@
 	return prev, nil
 }
 
+//sysnb	rtSigprocmask(how int, set *Sigset_t, oldset *Sigset_t, sigsetsize uintptr) (err error) = SYS_RT_SIGPROCMASK
+
+func PthreadSigmask(how int, set, oldset *Sigset_t) error {
+	if oldset != nil {
+		// Explicitly clear in case Sigset_t is larger than _C__NSIG.
+		*oldset = Sigset_t{}
+	}
+	return rtSigprocmask(how, set, oldset, _C__NSIG/8)
+}
+
 /*
  * Unimplemented
  */
@@ -2415,7 +2437,6 @@
 // RestartSyscall
 // RtSigaction
 // RtSigpending
-// RtSigprocmask
 // RtSigqueueinfo
 // RtSigreturn
 // RtSigsuspend
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_386.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_386.go
index 518e476..ff5b589 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_386.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_386.go
@@ -41,10 +41,6 @@
 //sys	sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
 //sys	setfsgid(gid int) (prev int, err error) = SYS_SETFSGID32
 //sys	setfsuid(uid int) (prev int, err error) = SYS_SETFSUID32
-//sysnb	Setregid(rgid int, egid int) (err error) = SYS_SETREGID32
-//sysnb	Setresgid(rgid int, egid int, sgid int) (err error) = SYS_SETRESGID32
-//sysnb	Setresuid(ruid int, euid int, suid int) (err error) = SYS_SETRESUID32
-//sysnb	Setreuid(ruid int, euid int) (err error) = SYS_SETREUID32
 //sys	Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
 //sys	Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
 //sys	SyncFileRange(fd int, off int64, n int64, flags int) (err error)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go
index f5e9d6b..9b27035 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go
@@ -46,11 +46,7 @@
 //sys	sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
 //sys	setfsgid(gid int) (prev int, err error)
 //sys	setfsuid(uid int) (prev int, err error)
-//sysnb	Setregid(rgid int, egid int) (err error)
-//sysnb	Setresgid(rgid int, egid int, sgid int) (err error)
-//sysnb	Setresuid(ruid int, euid int, suid int) (err error)
 //sysnb	Setrlimit(resource int, rlim *Rlimit) (err error)
-//sysnb	Setreuid(ruid int, euid int) (err error)
 //sys	Shutdown(fd int, how int) (err error)
 //sys	Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
 
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_arm.go
index c1a7778..856ad1d 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_arm.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_arm.go
@@ -62,10 +62,6 @@
 //sys	Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT
 //sys	setfsgid(gid int) (prev int, err error) = SYS_SETFSGID32
 //sys	setfsuid(uid int) (prev int, err error) = SYS_SETFSUID32
-//sysnb	Setregid(rgid int, egid int) (err error) = SYS_SETREGID32
-//sysnb	Setresgid(rgid int, egid int, sgid int) (err error) = SYS_SETRESGID32
-//sysnb	Setresuid(ruid int, euid int, suid int) (err error) = SYS_SETRESUID32
-//sysnb	Setreuid(ruid int, euid int) (err error) = SYS_SETREUID32
 //sys	Shutdown(fd int, how int) (err error)
 //sys	Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
 //sys	Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go
index d83e2c6..6422704 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go
@@ -39,11 +39,7 @@
 //sys	sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
 //sys	setfsgid(gid int) (prev int, err error)
 //sys	setfsuid(uid int) (prev int, err error)
-//sysnb	Setregid(rgid int, egid int) (err error)
-//sysnb	Setresgid(rgid int, egid int, sgid int) (err error)
-//sysnb	Setresuid(ruid int, euid int, suid int) (err error)
 //sysnb	setrlimit(resource int, rlim *Rlimit) (err error)
-//sysnb	Setreuid(ruid int, euid int) (err error)
 //sys	Shutdown(fd int, how int) (err error)
 //sys	Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
 
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_loong64.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_loong64.go
index 28ba7b8..59dab51 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_loong64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_loong64.go
@@ -12,8 +12,6 @@
 //sys	EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_PWAIT
 //sys	Fadvise(fd int, offset int64, length int64, advice int) (err error) = SYS_FADVISE64
 //sys	Fchown(fd int, uid int, gid int) (err error)
-//sys	Fstat(fd int, stat *Stat_t) (err error)
-//sys	Fstatat(fd int, path string, stat *Stat_t, flags int) (err error)
 //sys	Fstatfs(fd int, buf *Statfs_t) (err error)
 //sys	Ftruncate(fd int, length int64) (err error)
 //sysnb	Getegid() (egid int)
@@ -36,13 +34,46 @@
 //sys	sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
 //sys	setfsgid(gid int) (prev int, err error)
 //sys	setfsuid(uid int) (prev int, err error)
-//sysnb	Setregid(rgid int, egid int) (err error)
-//sysnb	Setresgid(rgid int, egid int, sgid int) (err error)
-//sysnb	Setresuid(ruid int, euid int, suid int) (err error)
-//sysnb	Setreuid(ruid int, euid int) (err error)
 //sys	Shutdown(fd int, how int) (err error)
 //sys	Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
 
+func timespecFromStatxTimestamp(x StatxTimestamp) Timespec {
+	return Timespec{
+		Sec:  x.Sec,
+		Nsec: int64(x.Nsec),
+	}
+}
+
+func Fstatat(fd int, path string, stat *Stat_t, flags int) error {
+	var r Statx_t
+	// Do it the glibc way, add AT_NO_AUTOMOUNT.
+	if err := Statx(fd, path, AT_NO_AUTOMOUNT|flags, STATX_BASIC_STATS, &r); err != nil {
+		return err
+	}
+
+	stat.Dev = Mkdev(r.Dev_major, r.Dev_minor)
+	stat.Ino = r.Ino
+	stat.Mode = uint32(r.Mode)
+	stat.Nlink = r.Nlink
+	stat.Uid = r.Uid
+	stat.Gid = r.Gid
+	stat.Rdev = Mkdev(r.Rdev_major, r.Rdev_minor)
+	// hope we don't get to process files so large to overflow these size
+	// fields...
+	stat.Size = int64(r.Size)
+	stat.Blksize = int32(r.Blksize)
+	stat.Blocks = int64(r.Blocks)
+	stat.Atim = timespecFromStatxTimestamp(r.Atime)
+	stat.Mtim = timespecFromStatxTimestamp(r.Mtime)
+	stat.Ctim = timespecFromStatxTimestamp(r.Ctime)
+
+	return nil
+}
+
+func Fstat(fd int, stat *Stat_t) (err error) {
+	return Fstatat(fd, "", stat, AT_EMPTY_PATH)
+}
+
 func Stat(path string, stat *Stat_t) (err error) {
 	return Fstatat(AT_FDCWD, path, stat, 0)
 }
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go
index 98a2660..bfef09a 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go
@@ -37,11 +37,7 @@
 //sys	sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
 //sys	setfsgid(gid int) (prev int, err error)
 //sys	setfsuid(uid int) (prev int, err error)
-//sysnb	Setregid(rgid int, egid int) (err error)
-//sysnb	Setresgid(rgid int, egid int, sgid int) (err error)
-//sysnb	Setresuid(ruid int, euid int, suid int) (err error)
 //sysnb	Setrlimit(resource int, rlim *Rlimit) (err error)
-//sysnb	Setreuid(ruid int, euid int) (err error)
 //sys	Shutdown(fd int, how int) (err error)
 //sys	Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
 //sys	Statfs(path string, buf *Statfs_t) (err error)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go
index b8a18c0..ab30250 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go
@@ -32,10 +32,6 @@
 //sys	sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
 //sys	setfsgid(gid int) (prev int, err error)
 //sys	setfsuid(uid int) (prev int, err error)
-//sysnb	Setregid(rgid int, egid int) (err error)
-//sysnb	Setresgid(rgid int, egid int, sgid int) (err error)
-//sysnb	Setresuid(ruid int, euid int, suid int) (err error)
-//sysnb	Setreuid(ruid int, euid int) (err error)
 //sys	Shutdown(fd int, how int) (err error)
 //sys	Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
 //sys	SyncFileRange(fd int, off int64, n int64, flags int) (err error)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_ppc.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_ppc.go
index 4ed9e67..eac1cf1 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_ppc.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_ppc.go
@@ -34,10 +34,6 @@
 //sys	sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
 //sys	setfsgid(gid int) (prev int, err error)
 //sys	setfsuid(uid int) (prev int, err error)
-//sysnb	Setregid(rgid int, egid int) (err error)
-//sysnb	Setresgid(rgid int, egid int, sgid int) (err error)
-//sysnb	Setresuid(ruid int, euid int, suid int) (err error)
-//sysnb	Setreuid(ruid int, euid int) (err error)
 //sys	Shutdown(fd int, how int) (err error)
 //sys	Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
 //sys	Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go
index db63d38..4df5661 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go
@@ -34,11 +34,7 @@
 //sys	sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
 //sys	setfsgid(gid int) (prev int, err error)
 //sys	setfsuid(uid int) (prev int, err error)
-//sysnb	Setregid(rgid int, egid int) (err error)
-//sysnb	Setresgid(rgid int, egid int, sgid int) (err error)
-//sysnb	Setresuid(ruid int, euid int, suid int) (err error)
 //sysnb	Setrlimit(resource int, rlim *Rlimit) (err error)
-//sysnb	Setreuid(ruid int, euid int) (err error)
 //sys	Shutdown(fd int, how int) (err error)
 //sys	Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
 //sys	Stat(path string, stat *Stat_t) (err error)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go
index 8ff7adb..5f4243d 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go
@@ -22,6 +22,7 @@
 //sysnb	Getrlimit(resource int, rlim *Rlimit) (err error)
 //sysnb	Getuid() (uid int)
 //sys	Listen(s int, n int) (err error)
+//sys	MemfdSecret(flags int) (fd int, err error)
 //sys	pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
 //sys	pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
 //sys	Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
@@ -37,11 +38,7 @@
 //sys	sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
 //sys	setfsgid(gid int) (prev int, err error)
 //sys	setfsuid(uid int) (prev int, err error)
-//sysnb	Setregid(rgid int, egid int) (err error)
-//sysnb	Setresgid(rgid int, egid int, sgid int) (err error)
-//sysnb	Setresuid(ruid int, euid int, suid int) (err error)
 //sysnb	Setrlimit(resource int, rlim *Rlimit) (err error)
-//sysnb	Setreuid(ruid int, euid int) (err error)
 //sys	Shutdown(fd int, how int) (err error)
 //sys	Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
 
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go
index 6fcf277..d0a7d40 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go
@@ -34,11 +34,7 @@
 //sys	sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
 //sys	setfsgid(gid int) (prev int, err error)
 //sys	setfsuid(uid int) (prev int, err error)
-//sysnb	Setregid(rgid int, egid int) (err error)
-//sysnb	Setresgid(rgid int, egid int, sgid int) (err error)
-//sysnb	Setresuid(ruid int, euid int, suid int) (err error)
 //sysnb	Setrlimit(resource int, rlim *Rlimit) (err error)
-//sysnb	Setreuid(ruid int, euid int) (err error)
 //sys	Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
 //sys	Stat(path string, stat *Stat_t) (err error)
 //sys	Statfs(path string, buf *Statfs_t) (err error)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go
index 02a45d9..f5c793b 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go
@@ -31,11 +31,7 @@
 //sys	sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
 //sys	setfsgid(gid int) (prev int, err error)
 //sys	setfsuid(uid int) (prev int, err error)
-//sysnb	Setregid(rgid int, egid int) (err error)
-//sysnb	Setresgid(rgid int, egid int, sgid int) (err error)
-//sysnb	Setresuid(ruid int, euid int, suid int) (err error)
 //sysnb	Setrlimit(resource int, rlim *Rlimit) (err error)
-//sysnb	Setreuid(ruid int, euid int) (err error)
 //sys	Shutdown(fd int, how int) (err error)
 //sys	Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
 //sys	Stat(path string, stat *Stat_t) (err error)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd_libc.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd_libc.go
new file mode 100644
index 0000000..e23c539
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd_libc.go
@@ -0,0 +1,27 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build openbsd && !mips64
+// +build openbsd,!mips64
+
+package unix
+
+import _ "unsafe"
+
+// Implemented in the runtime package (runtime/sys_openbsd3.go)
+func syscall_syscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
+func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
+func syscall_syscall10(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 uintptr) (r1, r2 uintptr, err Errno)
+func syscall_rawSyscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
+func syscall_rawSyscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
+
+//go:linkname syscall_syscall syscall.syscall
+//go:linkname syscall_syscall6 syscall.syscall6
+//go:linkname syscall_syscall10 syscall.syscall10
+//go:linkname syscall_rawSyscall syscall.rawSyscall
+//go:linkname syscall_rawSyscall6 syscall.rawSyscall6
+
+func syscall_syscall9(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno) {
+	return syscall_syscall10(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, 0)
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd_mips64.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd_mips64.go
index 30f2853..1378489 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd_mips64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd_mips64.go
@@ -26,6 +26,10 @@
 	msghdr.Controllen = uint32(length)
 }
 
+func (msghdr *Msghdr) SetIovlen(length int) {
+	msghdr.Iovlen = uint32(length)
+}
+
 func (cmsg *Cmsghdr) SetLen(length int) {
 	cmsg.Len = uint32(length)
 }
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd_ppc64.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd_ppc64.go
new file mode 100644
index 0000000..c279613
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd_ppc64.go
@@ -0,0 +1,42 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build ppc64 && openbsd
+// +build ppc64,openbsd
+
+package unix
+
+func setTimespec(sec, nsec int64) Timespec {
+	return Timespec{Sec: sec, Nsec: nsec}
+}
+
+func setTimeval(sec, usec int64) Timeval {
+	return Timeval{Sec: sec, Usec: usec}
+}
+
+func SetKevent(k *Kevent_t, fd, mode, flags int) {
+	k.Ident = uint64(fd)
+	k.Filter = int16(mode)
+	k.Flags = uint16(flags)
+}
+
+func (iov *Iovec) SetLen(length int) {
+	iov.Len = uint64(length)
+}
+
+func (msghdr *Msghdr) SetControllen(length int) {
+	msghdr.Controllen = uint32(length)
+}
+
+func (msghdr *Msghdr) SetIovlen(length int) {
+	msghdr.Iovlen = uint32(length)
+}
+
+func (cmsg *Cmsghdr) SetLen(length int) {
+	cmsg.Len = uint32(length)
+}
+
+// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions
+// of openbsd/ppc64 the syscall is called sysctl instead of __sysctl.
+const SYS___SYSCTL = SYS_SYSCTL
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd_riscv64.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd_riscv64.go
new file mode 100644
index 0000000..23199a7
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_openbsd_riscv64.go
@@ -0,0 +1,42 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build riscv64 && openbsd
+// +build riscv64,openbsd
+
+package unix
+
+func setTimespec(sec, nsec int64) Timespec {
+	return Timespec{Sec: sec, Nsec: nsec}
+}
+
+func setTimeval(sec, usec int64) Timeval {
+	return Timeval{Sec: sec, Usec: usec}
+}
+
+func SetKevent(k *Kevent_t, fd, mode, flags int) {
+	k.Ident = uint64(fd)
+	k.Filter = int16(mode)
+	k.Flags = uint16(flags)
+}
+
+func (iov *Iovec) SetLen(length int) {
+	iov.Len = uint64(length)
+}
+
+func (msghdr *Msghdr) SetControllen(length int) {
+	msghdr.Controllen = uint32(length)
+}
+
+func (msghdr *Msghdr) SetIovlen(length int) {
+	msghdr.Iovlen = uint32(length)
+}
+
+func (cmsg *Cmsghdr) SetLen(length int) {
+	cmsg.Len = uint32(length)
+}
+
+// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions
+// of openbsd/riscv64 the syscall is called sysctl instead of __sysctl.
+const SYS___SYSCTL = SYS_SYSCTL
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_solaris.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_solaris.go
index 932996c..2109e56 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_solaris.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_solaris.go
@@ -451,26 +451,25 @@
 
 //sys	recvmsg(s int, msg *Msghdr, flags int) (n int, err error) = libsocket.__xnet_recvmsg
 
-func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
+func recvmsgRaw(fd int, iov []Iovec, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
 	var msg Msghdr
 	msg.Name = (*byte)(unsafe.Pointer(rsa))
 	msg.Namelen = uint32(SizeofSockaddrAny)
-	var iov Iovec
-	if len(p) > 0 {
-		iov.Base = (*int8)(unsafe.Pointer(&p[0]))
-		iov.SetLen(len(p))
-	}
-	var dummy int8
+	var dummy byte
 	if len(oob) > 0 {
 		// receive at least one normal byte
-		if len(p) == 0 {
-			iov.Base = &dummy
-			iov.SetLen(1)
+		if emptyIovecs(iov) {
+			var iova [1]Iovec
+			iova[0].Base = &dummy
+			iova[0].SetLen(1)
+			iov = iova[:]
 		}
 		msg.Accrightslen = int32(len(oob))
 	}
-	msg.Iov = &iov
-	msg.Iovlen = 1
+	if len(iov) > 0 {
+		msg.Iov = &iov[0]
+		msg.SetIovlen(len(iov))
+	}
 	if n, err = recvmsg(fd, &msg, flags); n == -1 {
 		return
 	}
@@ -480,30 +479,31 @@
 
 //sys	sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = libsocket.__xnet_sendmsg
 
-func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
+func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
 	var msg Msghdr
 	msg.Name = (*byte)(unsafe.Pointer(ptr))
 	msg.Namelen = uint32(salen)
-	var iov Iovec
-	if len(p) > 0 {
-		iov.Base = (*int8)(unsafe.Pointer(&p[0]))
-		iov.SetLen(len(p))
-	}
-	var dummy int8
+	var dummy byte
+	var empty bool
 	if len(oob) > 0 {
 		// send at least one normal byte
-		if len(p) == 0 {
-			iov.Base = &dummy
-			iov.SetLen(1)
+		empty = emptyIovecs(iov)
+		if empty {
+			var iova [1]Iovec
+			iova[0].Base = &dummy
+			iova[0].SetLen(1)
+			iov = iova[:]
 		}
 		msg.Accrightslen = int32(len(oob))
 	}
-	msg.Iov = &iov
-	msg.Iovlen = 1
+	if len(iov) > 0 {
+		msg.Iov = &iov[0]
+		msg.SetIovlen(len(iov))
+	}
 	if n, err = sendmsg(fd, &msg, flags); err != nil {
 		return 0, err
 	}
-	if len(oob) > 0 && len(p) == 0 {
+	if len(oob) > 0 && empty {
 		n = 0
 	}
 	return n, nil
@@ -750,8 +750,8 @@
 	// we should handle things gracefully. To do so, we need to keep an extra
 	// reference to the cookie around until the event is processed
 	// thus the otherwise seemingly extraneous "cookies" map
-	// The key of this map is a pointer to the corresponding &fCookie.cookie
-	cookies map[*interface{}]*fileObjCookie
+	// The key of this map is a pointer to the corresponding fCookie
+	cookies map[*fileObjCookie]struct{}
 }
 
 // PortEvent is an abstraction of the port_event C struct.
@@ -778,7 +778,7 @@
 		port:    port,
 		fds:     make(map[uintptr]*fileObjCookie),
 		paths:   make(map[string]*fileObjCookie),
-		cookies: make(map[*interface{}]*fileObjCookie),
+		cookies: make(map[*fileObjCookie]struct{}),
 	}
 	return e, nil
 }
@@ -799,6 +799,7 @@
 	}
 	e.fds = nil
 	e.paths = nil
+	e.cookies = nil
 	return nil
 }
 
@@ -826,17 +827,16 @@
 	if _, found := e.paths[path]; found {
 		return fmt.Errorf("%v is already associated with this Event Port", path)
 	}
-	fobj, err := createFileObj(path, stat)
+	fCookie, err := createFileObjCookie(path, stat, cookie)
 	if err != nil {
 		return err
 	}
-	fCookie := &fileObjCookie{fobj, cookie}
-	_, err = port_associate(e.port, PORT_SOURCE_FILE, uintptr(unsafe.Pointer(fobj)), events, (*byte)(unsafe.Pointer(&fCookie.cookie)))
+	_, err = port_associate(e.port, PORT_SOURCE_FILE, uintptr(unsafe.Pointer(fCookie.fobj)), events, (*byte)(unsafe.Pointer(fCookie)))
 	if err != nil {
 		return err
 	}
 	e.paths[path] = fCookie
-	e.cookies[&fCookie.cookie] = fCookie
+	e.cookies[fCookie] = struct{}{}
 	return nil
 }
 
@@ -858,7 +858,7 @@
 	if err == nil {
 		// dissociate was successful, safe to delete the cookie
 		fCookie := e.paths[path]
-		delete(e.cookies, &fCookie.cookie)
+		delete(e.cookies, fCookie)
 	}
 	delete(e.paths, path)
 	return err
@@ -871,13 +871,16 @@
 	if _, found := e.fds[fd]; found {
 		return fmt.Errorf("%v is already associated with this Event Port", fd)
 	}
-	fCookie := &fileObjCookie{nil, cookie}
-	_, err := port_associate(e.port, PORT_SOURCE_FD, fd, events, (*byte)(unsafe.Pointer(&fCookie.cookie)))
+	fCookie, err := createFileObjCookie("", nil, cookie)
+	if err != nil {
+		return err
+	}
+	_, err = port_associate(e.port, PORT_SOURCE_FD, fd, events, (*byte)(unsafe.Pointer(fCookie)))
 	if err != nil {
 		return err
 	}
 	e.fds[fd] = fCookie
-	e.cookies[&fCookie.cookie] = fCookie
+	e.cookies[fCookie] = struct{}{}
 	return nil
 }
 
@@ -896,27 +899,31 @@
 	if err == nil {
 		// dissociate was successful, safe to delete the cookie
 		fCookie := e.fds[fd]
-		delete(e.cookies, &fCookie.cookie)
+		delete(e.cookies, fCookie)
 	}
 	delete(e.fds, fd)
 	return err
 }
 
-func createFileObj(name string, stat os.FileInfo) (*fileObj, error) {
-	fobj := new(fileObj)
-	bs, err := ByteSliceFromString(name)
-	if err != nil {
-		return nil, err
+func createFileObjCookie(name string, stat os.FileInfo, cookie interface{}) (*fileObjCookie, error) {
+	fCookie := new(fileObjCookie)
+	fCookie.cookie = cookie
+	if name != "" && stat != nil {
+		fCookie.fobj = new(fileObj)
+		bs, err := ByteSliceFromString(name)
+		if err != nil {
+			return nil, err
+		}
+		fCookie.fobj.Name = (*int8)(unsafe.Pointer(&bs[0]))
+		s := stat.Sys().(*syscall.Stat_t)
+		fCookie.fobj.Atim.Sec = s.Atim.Sec
+		fCookie.fobj.Atim.Nsec = s.Atim.Nsec
+		fCookie.fobj.Mtim.Sec = s.Mtim.Sec
+		fCookie.fobj.Mtim.Nsec = s.Mtim.Nsec
+		fCookie.fobj.Ctim.Sec = s.Ctim.Sec
+		fCookie.fobj.Ctim.Nsec = s.Ctim.Nsec
 	}
-	fobj.Name = (*int8)(unsafe.Pointer(&bs[0]))
-	s := stat.Sys().(*syscall.Stat_t)
-	fobj.Atim.Sec = s.Atim.Sec
-	fobj.Atim.Nsec = s.Atim.Nsec
-	fobj.Mtim.Sec = s.Mtim.Sec
-	fobj.Mtim.Nsec = s.Mtim.Nsec
-	fobj.Ctim.Sec = s.Ctim.Sec
-	fobj.Ctim.Nsec = s.Ctim.Nsec
-	return fobj, nil
+	return fCookie, nil
 }
 
 // GetOne wraps port_get(3c) and returns a single PortEvent.
@@ -929,44 +936,50 @@
 	p := new(PortEvent)
 	e.mu.Lock()
 	defer e.mu.Unlock()
-	e.peIntToExt(pe, p)
+	err = e.peIntToExt(pe, p)
+	if err != nil {
+		return nil, err
+	}
 	return p, nil
 }
 
 // peIntToExt converts a cgo portEvent struct into the friendlier PortEvent
 // NOTE: Always call this function while holding the e.mu mutex
-func (e *EventPort) peIntToExt(peInt *portEvent, peExt *PortEvent) {
+func (e *EventPort) peIntToExt(peInt *portEvent, peExt *PortEvent) error {
+	if e.cookies == nil {
+		return fmt.Errorf("this EventPort is already closed")
+	}
 	peExt.Events = peInt.Events
 	peExt.Source = peInt.Source
-	cookie := (*interface{})(unsafe.Pointer(peInt.User))
-	peExt.Cookie = *cookie
+	fCookie := (*fileObjCookie)(unsafe.Pointer(peInt.User))
+	_, found := e.cookies[fCookie]
+
+	if !found {
+		panic("unexpected event port address; may be due to kernel bug; see https://go.dev/issue/54254")
+	}
+	peExt.Cookie = fCookie.cookie
+	delete(e.cookies, fCookie)
+
 	switch peInt.Source {
 	case PORT_SOURCE_FD:
-		delete(e.cookies, cookie)
 		peExt.Fd = uintptr(peInt.Object)
 		// Only remove the fds entry if it exists and this cookie matches
 		if fobj, ok := e.fds[peExt.Fd]; ok {
-			if &fobj.cookie == cookie {
+			if fobj == fCookie {
 				delete(e.fds, peExt.Fd)
 			}
 		}
 	case PORT_SOURCE_FILE:
-		if fCookie, ok := e.cookies[cookie]; ok && uintptr(unsafe.Pointer(fCookie.fobj)) == uintptr(peInt.Object) {
-			// Use our stashed reference rather than using unsafe on what we got back
-			// the unsafe version would be (*fileObj)(unsafe.Pointer(uintptr(peInt.Object)))
-			peExt.fobj = fCookie.fobj
-		} else {
-			panic("mismanaged memory")
-		}
-		delete(e.cookies, cookie)
+		peExt.fobj = fCookie.fobj
 		peExt.Path = BytePtrToString((*byte)(unsafe.Pointer(peExt.fobj.Name)))
 		// Only remove the paths entry if it exists and this cookie matches
 		if fobj, ok := e.paths[peExt.Path]; ok {
-			if &fobj.cookie == cookie {
+			if fobj == fCookie {
 				delete(e.paths, peExt.Path)
 			}
 		}
 	}
+	return nil
 }
 
 // Pending wraps port_getn(3c) and returns how many events are pending.
@@ -990,7 +1003,7 @@
 	got := uint32(min)
 	max := uint32(len(s))
 	var err error
-	ps := make([]portEvent, max, max)
+	ps := make([]portEvent, max)
 	_, err = port_getn(e.port, &ps[0], max, &got, timeout)
 	// got will be trustworthy with ETIME, but not any other error.
 	if err != nil && err != ETIME {
@@ -998,8 +1011,122 @@
 	}
 	e.mu.Lock()
 	defer e.mu.Unlock()
+	valid := 0
 	for i := 0; i < int(got); i++ {
-		e.peIntToExt(&ps[i], &s[i])
+		err2 := e.peIntToExt(&ps[i], &s[i])
+		if err2 != nil {
+			if valid == 0 && err == nil {
+				// If err2 is the only error and there are no valid events
+				// to return, return it to the caller.
+				err = err2
+			}
+			break
+		}
+		valid = i + 1
 	}
-	return int(got), err
+	return valid, err
+}
+
+//sys	putmsg(fd int, clptr *strbuf, dataptr *strbuf, flags int) (err error)
+
+func Putmsg(fd int, cl []byte, data []byte, flags int) (err error) {
+	var clp, datap *strbuf
+	if len(cl) > 0 {
+		clp = &strbuf{
+			Len: int32(len(cl)),
+			Buf: (*int8)(unsafe.Pointer(&cl[0])),
+		}
+	}
+	if len(data) > 0 {
+		datap = &strbuf{
+			Len: int32(len(data)),
+			Buf: (*int8)(unsafe.Pointer(&data[0])),
+		}
+	}
+	return putmsg(fd, clp, datap, flags)
+}
+
+//sys	getmsg(fd int, clptr *strbuf, dataptr *strbuf, flags *int) (err error)
+
+func Getmsg(fd int, cl []byte, data []byte) (retCl []byte, retData []byte, flags int, err error) {
+	var clp, datap *strbuf
+	if len(cl) > 0 {
+		clp = &strbuf{
+			Maxlen: int32(len(cl)),
+			Buf:    (*int8)(unsafe.Pointer(&cl[0])),
+		}
+	}
+	if len(data) > 0 {
+		datap = &strbuf{
+			Maxlen: int32(len(data)),
+			Buf:    (*int8)(unsafe.Pointer(&data[0])),
+		}
+	}
+
+	if err = getmsg(fd, clp, datap, &flags); err != nil {
+		return nil, nil, 0, err
+	}
+
+	if len(cl) > 0 {
+		retCl = cl[:clp.Len]
+	}
+	if len(data) > 0 {
+		retData = data[:datap.Len]
+	}
+	return retCl, retData, flags, nil
+}
+
+func IoctlSetIntRetInt(fd int, req uint, arg int) (int, error) {
+	return ioctlRet(fd, req, uintptr(arg))
+}
+
+func IoctlSetString(fd int, req uint, val string) error {
+	bs := make([]byte, len(val)+1)
+	copy(bs[:len(bs)-1], val)
+	err := ioctl(fd, req, uintptr(unsafe.Pointer(&bs[0])))
+	runtime.KeepAlive(&bs[0])
+	return err
+}
+
+// Lifreq Helpers
+
+func (l *Lifreq) SetName(name string) error {
+	if len(name) >= len(l.Name) {
+		return fmt.Errorf("name cannot be more than %d characters", len(l.Name)-1)
+	}
+	for i := range name {
+		l.Name[i] = int8(name[i])
+	}
+	return nil
+}
+
+func (l *Lifreq) SetLifruInt(d int) {
+	*(*int)(unsafe.Pointer(&l.Lifru[0])) = d
+}
+
+func (l *Lifreq) GetLifruInt() int {
+	return *(*int)(unsafe.Pointer(&l.Lifru[0]))
+}
+
+func (l *Lifreq) SetLifruUint(d uint) {
+	*(*uint)(unsafe.Pointer(&l.Lifru[0])) = d
+}
+
+func (l *Lifreq) GetLifruUint() uint {
+	return *(*uint)(unsafe.Pointer(&l.Lifru[0]))
+}
+
+func IoctlLifreq(fd int, req uint, l *Lifreq) error {
+	return ioctl(fd, req, uintptr(unsafe.Pointer(l)))
+}
+
+// Strioctl Helpers
+
+func (s *Strioctl) SetInt(i int) {
+	s.Len = int32(unsafe.Sizeof(i))
+	s.Dp = (*int8)(unsafe.Pointer(&i))
+}
+
+func IoctlSetStrioctlRetInt(fd int, req uint, s *Strioctl) (int, error) {
+	return ioctlRet(fd, req, uintptr(unsafe.Pointer(s)))
 }
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_unix.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_unix.go
index 70508af..00bafda 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_unix.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_unix.go
@@ -13,8 +13,6 @@
 	"sync"
 	"syscall"
 	"unsafe"
-
-	"golang.org/x/sys/internal/unsafeheader"
 )
 
 var (
@@ -117,11 +115,7 @@
 	}
 
 	// Use unsafe to convert addr into a []byte.
-	var b []byte
-	hdr := (*unsafeheader.Slice)(unsafe.Pointer(&b))
-	hdr.Data = unsafe.Pointer(addr)
-	hdr.Cap = length
-	hdr.Len = length
+	b := unsafe.Slice((*byte)(unsafe.Pointer(addr)), length)
 
 	// Register mapping in m and return it.
 	p := &b[cap(b)-1]
@@ -338,8 +332,13 @@
 }
 
 func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
+	var iov [1]Iovec
+	if len(p) > 0 {
+		iov[0].Base = &p[0]
+		iov[0].SetLen(len(p))
+	}
 	var rsa RawSockaddrAny
-	n, oobn, recvflags, err = recvmsgRaw(fd, p, oob, flags, &rsa)
+	n, oobn, recvflags, err = recvmsgRaw(fd, iov[:], oob, flags, &rsa)
 	// source address is only specified if the socket is unconnected
 	if rsa.Addr.Family != AF_UNSPEC {
 		from, err = anyToSockaddr(fd, &rsa)
@@ -347,12 +346,42 @@
 	return
 }
 
+// RecvmsgBuffers receives a message from a socket using the recvmsg
+// system call. The flags are passed to recvmsg. Any non-control data
+// read is scattered into the buffers slices. The results are:
+//   - n is the number of non-control data read into bufs
+//   - oobn is the number of control data read into oob; this may be interpreted using [ParseSocketControlMessage]
+//   - recvflags is flags returned by recvmsg
+//   - from is the address of the sender
+func RecvmsgBuffers(fd int, buffers [][]byte, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
+	iov := make([]Iovec, len(buffers))
+	for i := range buffers {
+		if len(buffers[i]) > 0 {
+			iov[i].Base = &buffers[i][0]
+			iov[i].SetLen(len(buffers[i]))
+		} else {
+			iov[i].Base = (*byte)(unsafe.Pointer(&_zero))
+		}
+	}
+	var rsa RawSockaddrAny
+	n, oobn, recvflags, err = recvmsgRaw(fd, iov, oob, flags, &rsa)
+	if err == nil && rsa.Addr.Family != AF_UNSPEC {
+		from, err = anyToSockaddr(fd, &rsa)
+	}
+	return
+}
+
 func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
 	_, err = SendmsgN(fd, p, oob, to, flags)
 	return
 }
 
 func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
+	var iov [1]Iovec
+	if len(p) > 0 {
+		iov[0].Base = &p[0]
+		iov[0].SetLen(len(p))
+	}
 	var ptr unsafe.Pointer
 	var salen _Socklen
 	if to != nil {
@@ -361,7 +390,32 @@
 			return 0, err
 		}
 	}
-	return sendmsgN(fd, p, oob, ptr, salen, flags)
+	return sendmsgN(fd, iov[:], oob, ptr, salen, flags)
+}
+
+// SendmsgBuffers sends a message on a socket to an address using the sendmsg
+// system call. The flags are passed to sendmsg. Any non-control data written
+// is gathered from buffers. The function returns the number of bytes written
+// to the socket.
+func SendmsgBuffers(fd int, buffers [][]byte, oob []byte, to Sockaddr, flags int) (n int, err error) {
+	iov := make([]Iovec, len(buffers))
+	for i := range buffers {
+		if len(buffers[i]) > 0 {
+			iov[i].Base = &buffers[i][0]
+			iov[i].SetLen(len(buffers[i]))
+		} else {
+			iov[i].Base = (*byte)(unsafe.Pointer(&_zero))
+		}
+	}
+	var ptr unsafe.Pointer
+	var salen _Socklen
+	if to != nil {
+		ptr, salen, err = to.sockaddr()
+		if err != nil {
+			return 0, err
+		}
+	}
+	return sendmsgN(fd, iov, oob, ptr, salen, flags)
 }
 
 func Send(s int, buf []byte, flags int) (err error) {
@@ -369,11 +423,15 @@
 }
 
 func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
-	ptr, n, err := to.sockaddr()
-	if err != nil {
-		return err
+	var ptr unsafe.Pointer
+	var salen _Socklen
+	if to != nil {
+		ptr, salen, err = to.sockaddr()
+		if err != nil {
+			return err
+		}
 	}
-	return sendto(fd, p, flags, ptr, n)
+	return sendto(fd, p, flags, ptr, salen)
 }
 
 func SetsockoptByte(fd, level, opt int, value byte) (err error) {
@@ -484,3 +542,13 @@
 	}
 	return UtimesNanoAt(AT_FDCWD, path, ts, AT_SYMLINK_NOFOLLOW)
 }
+
+// emptyIovec reports whether there are no bytes in the slice of Iovec.
+func emptyIovecs(iov []Iovec) bool {
+	for i := range iov {
+		if iov[i].Len > 0 {
+			return false
+		}
+	}
+	return true
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_unix_gc.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_unix_gc.go
index 5898e9a..b6919ca 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_unix_gc.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_unix_gc.go
@@ -2,11 +2,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build (darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris) && gc && !ppc64le && !ppc64
-// +build darwin dragonfly freebsd linux netbsd openbsd solaris
+//go:build (darwin || dragonfly || freebsd || (linux && !ppc64 && !ppc64le) || netbsd || openbsd || solaris) && gc
+// +build darwin dragonfly freebsd linux,!ppc64,!ppc64le netbsd openbsd solaris
 // +build gc
-// +build !ppc64le
-// +build !ppc64
 
 package unix
 
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go
index f8616f4..68b2f3e 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go
@@ -9,8 +9,10 @@
 
 import (
 	"bytes"
+	"fmt"
 	"runtime"
 	"sort"
+	"strings"
 	"sync"
 	"syscall"
 	"unsafe"
@@ -55,7 +57,13 @@
 	if d == nil {
 		return ""
 	}
-	return string(d.Name[:d.Namlen])
+	s := string(d.Name[:])
+	idx := strings.IndexByte(s, 0)
+	if idx == -1 {
+		return s
+	} else {
+		return s[:idx]
+	}
 }
 
 func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
@@ -1230,6 +1238,14 @@
 	return &ent, err
 }
 
+func readdir_r(dirp uintptr, entry *direntLE, result **direntLE) (err error) {
+	r0, _, e1 := syscall_syscall(SYS___READDIR_R_A, dirp, uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result)))
+	if int64(r0) == -1 {
+		err = errnoErr(Errno(e1))
+	}
+	return
+}
+
 func Closedir(dir uintptr) error {
 	_, _, e := syscall_syscall(SYS_CLOSEDIR, dir, 0, 0)
 	if e != 0 {
@@ -1821,3 +1837,158 @@
 	}
 	return err
 }
+
+func fdToPath(dirfd int) (path string, err error) {
+	var buffer [1024]byte
+	// w_ctrl()
+	ret := runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS_W_IOCTL<<4,
+		[]uintptr{uintptr(dirfd), 17, 1024, uintptr(unsafe.Pointer(&buffer[0]))})
+	if ret == 0 {
+		zb := bytes.IndexByte(buffer[:], 0)
+		if zb == -1 {
+			zb = len(buffer)
+		}
+		// __e2a_l()
+		runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___E2A_L<<4,
+			[]uintptr{uintptr(unsafe.Pointer(&buffer[0])), uintptr(zb)})
+		return string(buffer[:zb]), nil
+	}
+	// __errno()
+	errno := int(*(*int32)(unsafe.Pointer(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO<<4,
+		[]uintptr{}))))
+	// __errno2()
+	errno2 := int(runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS___ERRNO2<<4,
+		[]uintptr{}))
+	// strerror_r()
+	ret = runtime.CallLeFuncByPtr(runtime.XplinkLibvec+SYS_STRERROR_R<<4,
+		[]uintptr{uintptr(errno), uintptr(unsafe.Pointer(&buffer[0])), 1024})
+	if ret == 0 {
+		zb := bytes.IndexByte(buffer[:], 0)
+		if zb == -1 {
+			zb = len(buffer)
+		}
+		return "", fmt.Errorf("%s (errno2=0x%x)", buffer[:zb], errno2)
+	} else {
+		return "", fmt.Errorf("fdToPath errno %d (errno2=0x%x)", errno, errno2)
+	}
+}
+
+func direntLeToDirentUnix(dirent *direntLE, dir uintptr, path string) (Dirent, error) {
+	var d Dirent
+
+	d.Ino = uint64(dirent.Ino)
+	offset, err := Telldir(dir)
+	if err != nil {
+		return d, err
+	}
+
+	d.Off = int64(offset)
+	s := string(bytes.Split(dirent.Name[:], []byte{0})[0])
+	copy(d.Name[:], s)
+
+	d.Reclen = uint16(24 + len(d.NameString()))
+	var st Stat_t
+	path = path + "/" + s
+	err = Lstat(path, &st)
+	if err != nil {
+		return d, err
+	}
+
+	d.Type = uint8(st.Mode >> 24)
+	return d, err
+}
+
+func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
+	// Simulation of Getdirentries port from the Darwin implementation.
+	// COMMENTS FROM DARWIN:
+	// It's not the full required semantics, but should handle the case
+	// of calling Getdirentries or ReadDirent repeatedly.
+	// It won't handle assigning the results of lseek to *basep, or handle
+	// the directory being edited underfoot.
+
+	skip, err := Seek(fd, 0, 1 /* SEEK_CUR */)
+	if err != nil {
+		return 0, err
+	}
+
+	// Get path from fd to avoid unavailable call (fdopendir)
+	path, err := fdToPath(fd)
+	if err != nil {
+		return 0, err
+	}
+	d, err := Opendir(path)
+	if err != nil {
+		return 0, err
+	}
+	defer Closedir(d)
+
+	var cnt int64
+	for {
+		var entryLE direntLE
+		var entrypLE *direntLE
+		e := readdir_r(d, &entryLE, &entrypLE)
+		if e != nil {
+			return n, e
+		}
+		if entrypLE == nil {
+			break
+		}
+		if skip > 0 {
+			skip--
+			cnt++
+			continue
+		}
+
+		// Dirent on zos has a different structure
+		entry, e := direntLeToDirentUnix(&entryLE, d, path)
+		if e != nil {
+			return n, e
+		}
+
+		reclen := int(entry.Reclen)
+		if reclen > len(buf) {
+			// Not enough room. Return for now.
+			// The counter will let us know where we should start up again.
+			// Note: this strategy for suspending in the middle and
+			// restarting is O(n^2) in the length of the directory. Oh well.
+			break
+		}
+
+		// Copy entry into return buffer.
+		s := unsafe.Slice((*byte)(unsafe.Pointer(&entry)), reclen)
+		copy(buf, s)
+
+		buf = buf[reclen:]
+		n += reclen
+		cnt++
+	}
+	// Set the seek offset of the input fd to record
+	// how many files we've already returned.
+	_, err = Seek(fd, cnt, 0 /* SEEK_SET */)
+	if err != nil {
+		return n, err
+	}
+
+	return n, nil
+}
+
+func ReadDirent(fd int, buf []byte) (n int, err error) {
+	var base = (*uintptr)(unsafe.Pointer(new(uint64)))
+	return Getdirentries(fd, buf, base)
+}
+
+func direntIno(buf []byte) (uint64, bool) {
+	return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
+}
+
+func direntReclen(buf []byte) (uint64, bool) {
+	return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
+}
+
+func direntNamlen(buf []byte) (uint64, bool) {
+	reclen, ok := direntReclen(buf)
+	if !ok {
+		return 0, false
+	}
+	return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/sysvshm_unix.go b/src/cmd/vendor/golang.org/x/sys/unix/sysvshm_unix.go
index 0bb4c8d..5bb41d1 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/sysvshm_unix.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/sysvshm_unix.go
@@ -7,11 +7,7 @@
 
 package unix
 
-import (
-	"unsafe"
-
-	"golang.org/x/sys/internal/unsafeheader"
-)
+import "unsafe"
 
 // SysvShmAttach attaches the Sysv shared memory segment associated with the
 // shared memory identifier id.
@@ -34,12 +30,7 @@
 	}
 
 	// Use unsafe to convert addr into a []byte.
-	// TODO: convert to unsafe.Slice once we can assume Go 1.17
-	var b []byte
-	hdr := (*unsafeheader.Slice)(unsafe.Pointer(&b))
-	hdr.Data = unsafe.Pointer(addr)
-	hdr.Cap = int(info.Segsz)
-	hdr.Len = int(info.Segsz)
+	b := unsafe.Slice((*byte)(unsafe.Pointer(addr)), int(info.Segsz))
 	return b, nil
 }
 
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/xattr_bsd.go b/src/cmd/vendor/golang.org/x/sys/unix/xattr_bsd.go
index 25df1e3..663b377 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/xattr_bsd.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/xattr_bsd.go
@@ -160,13 +160,12 @@
 }
 
 func Listxattr(file string, dest []byte) (sz int, err error) {
-	d := initxattrdest(dest, 0)
 	destsiz := len(dest)
 
 	// FreeBSD won't allow you to list xattrs from multiple namespaces
-	s := 0
+	s, pos := 0, 0
 	for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
-		stmp, e := ExtattrListFile(file, nsid, uintptr(d), destsiz)
+		stmp, e := ListxattrNS(file, nsid, dest[pos:])
 
 		/* Errors accessing system attrs are ignored so that
 		 * we can implement the Linux-like behavior of omitting errors that
@@ -175,66 +174,102 @@
 		 * Linux will still error if we ask for user attributes on a file that
 		 * we don't have read permissions on, so don't ignore those errors
 		 */
-		if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
-			continue
-		} else if e != nil {
+		if e != nil {
+			if e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
+				continue
+			}
 			return s, e
 		}
 
 		s += stmp
-		destsiz -= s
-		if destsiz < 0 {
-			destsiz = 0
+		pos = s
+		if pos > destsiz {
+			pos = destsiz
 		}
-		d = initxattrdest(dest, s)
+	}
+
+	return s, nil
+}
+
+func ListxattrNS(file string, nsid int, dest []byte) (sz int, err error) {
+	d := initxattrdest(dest, 0)
+	destsiz := len(dest)
+
+	s, e := ExtattrListFile(file, nsid, uintptr(d), destsiz)
+	if e != nil {
+		return 0, err
 	}
 
 	return s, nil
 }
 
 func Flistxattr(fd int, dest []byte) (sz int, err error) {
-	d := initxattrdest(dest, 0)
 	destsiz := len(dest)
 
-	s := 0
+	s, pos := 0, 0
 	for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
-		stmp, e := ExtattrListFd(fd, nsid, uintptr(d), destsiz)
-		if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
-			continue
-		} else if e != nil {
+		stmp, e := FlistxattrNS(fd, nsid, dest[pos:])
+
+		if e != nil {
+			if e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
+				continue
+			}
 			return s, e
 		}
 
 		s += stmp
-		destsiz -= s
-		if destsiz < 0 {
-			destsiz = 0
+		pos = s
+		if pos > destsiz {
+			pos = destsiz
 		}
-		d = initxattrdest(dest, s)
+	}
+
+	return s, nil
+}
+
+func FlistxattrNS(fd int, nsid int, dest []byte) (sz int, err error) {
+	d := initxattrdest(dest, 0)
+	destsiz := len(dest)
+
+	s, e := ExtattrListFd(fd, nsid, uintptr(d), destsiz)
+	if e != nil {
+		return 0, err
 	}
 
 	return s, nil
 }
 
 func Llistxattr(link string, dest []byte) (sz int, err error) {
-	d := initxattrdest(dest, 0)
 	destsiz := len(dest)
 
-	s := 0
+	s, pos := 0, 0
 	for _, nsid := range [...]int{EXTATTR_NAMESPACE_USER, EXTATTR_NAMESPACE_SYSTEM} {
-		stmp, e := ExtattrListLink(link, nsid, uintptr(d), destsiz)
-		if e != nil && e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
-			continue
-		} else if e != nil {
+		stmp, e := LlistxattrNS(link, nsid, dest[pos:])
+
+		if e != nil {
+			if e == EPERM && nsid != EXTATTR_NAMESPACE_USER {
+				continue
+			}
 			return s, e
 		}
 
 		s += stmp
-		destsiz -= s
-		if destsiz < 0 {
-			destsiz = 0
+		pos = s
+		if pos > destsiz {
+			pos = destsiz
 		}
-		d = initxattrdest(dest, s)
+	}
+
+	return s, nil
+}
+
+func LlistxattrNS(link string, nsid int, dest []byte) (sz int, err error) {
+	d := initxattrdest(dest, 0)
+	destsiz := len(dest)
+
+	s, e := ExtattrListLink(link, nsid, uintptr(d), destsiz)
+	if e != nil {
+		return 0, err
 	}
 
 	return s, nil
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go
index 4409001..f8c2c51 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_386.go
@@ -151,6 +151,7 @@
 	BIOCSETF                       = 0x80084267
 	BIOCSETFNR                     = 0x80084282
 	BIOCSETIF                      = 0x8020426c
+	BIOCSETVLANPCP                 = 0x80044285
 	BIOCSETWF                      = 0x8008427b
 	BIOCSETZBUF                    = 0x800c4281
 	BIOCSHDRCMPLT                  = 0x80044275
@@ -447,7 +448,7 @@
 	DLT_IEEE802_16_MAC_CPS_RADIO   = 0xc1
 	DLT_INFINIBAND                 = 0xf7
 	DLT_IPFILTER                   = 0x74
-	DLT_IPMB                       = 0xc7
+	DLT_IPMB_KONTRON               = 0xc7
 	DLT_IPMB_LINUX                 = 0xd1
 	DLT_IPMI_HPM_2                 = 0x104
 	DLT_IPNET                      = 0xe2
@@ -487,10 +488,11 @@
 	DLT_LINUX_LAPD                 = 0xb1
 	DLT_LINUX_PPP_WITHDIRECTION    = 0xa6
 	DLT_LINUX_SLL                  = 0x71
+	DLT_LINUX_SLL2                 = 0x114
 	DLT_LOOP                       = 0x6c
 	DLT_LORATAP                    = 0x10e
 	DLT_LTALK                      = 0x72
-	DLT_MATCHING_MAX               = 0x113
+	DLT_MATCHING_MAX               = 0x114
 	DLT_MATCHING_MIN               = 0x68
 	DLT_MFR                        = 0xb6
 	DLT_MOST                       = 0xd3
@@ -734,6 +736,7 @@
 	IPPROTO_CMTP                   = 0x26
 	IPPROTO_CPHB                   = 0x49
 	IPPROTO_CPNX                   = 0x48
+	IPPROTO_DCCP                   = 0x21
 	IPPROTO_DDP                    = 0x25
 	IPPROTO_DGP                    = 0x56
 	IPPROTO_DIVERT                 = 0x102
@@ -814,7 +817,6 @@
 	IPPROTO_SCTP                   = 0x84
 	IPPROTO_SDRP                   = 0x2a
 	IPPROTO_SEND                   = 0x103
-	IPPROTO_SEP                    = 0x21
 	IPPROTO_SHIM6                  = 0x8c
 	IPPROTO_SKIP                   = 0x39
 	IPPROTO_SPACER                 = 0x7fff
@@ -911,6 +913,7 @@
 	IPV6_V6ONLY                    = 0x1b
 	IPV6_VERSION                   = 0x60
 	IPV6_VERSION_MASK              = 0xf0
+	IPV6_VLAN_PCP                  = 0x4b
 	IP_ADD_MEMBERSHIP              = 0xc
 	IP_ADD_SOURCE_MEMBERSHIP       = 0x46
 	IP_BINDANY                     = 0x18
@@ -989,8 +992,12 @@
 	IP_TOS                         = 0x3
 	IP_TTL                         = 0x4
 	IP_UNBLOCK_SOURCE              = 0x49
+	IP_VLAN_PCP                    = 0x4b
 	ISIG                           = 0x80
 	ISTRIP                         = 0x20
+	ITIMER_PROF                    = 0x2
+	ITIMER_REAL                    = 0x0
+	ITIMER_VIRTUAL                 = 0x1
 	IXANY                          = 0x800
 	IXOFF                          = 0x400
 	IXON                           = 0x200
@@ -1000,7 +1007,6 @@
 	KERN_VERSION                   = 0x4
 	LOCAL_CONNWAIT                 = 0x4
 	LOCAL_CREDS                    = 0x2
-	LOCAL_CREDS_PERSISTENT         = 0x3
 	LOCAL_PEERCRED                 = 0x1
 	LOCAL_VENDOR                   = 0x80000000
 	LOCK_EX                        = 0x2
@@ -1179,6 +1185,8 @@
 	O_NONBLOCK                     = 0x4
 	O_RDONLY                       = 0x0
 	O_RDWR                         = 0x2
+	O_RESOLVE_BENEATH              = 0x800000
+	O_SEARCH                       = 0x40000
 	O_SHLOCK                       = 0x10
 	O_SYNC                         = 0x80
 	O_TRUNC                        = 0x400
@@ -1189,6 +1197,10 @@
 	PARMRK                         = 0x8
 	PARODD                         = 0x2000
 	PENDIN                         = 0x20000000
+	PIOD_READ_D                    = 0x1
+	PIOD_READ_I                    = 0x3
+	PIOD_WRITE_D                   = 0x2
+	PIOD_WRITE_I                   = 0x4
 	PRIO_PGRP                      = 0x1
 	PRIO_PROCESS                   = 0x0
 	PRIO_USER                      = 0x2
@@ -1196,6 +1208,60 @@
 	PROT_NONE                      = 0x0
 	PROT_READ                      = 0x1
 	PROT_WRITE                     = 0x2
+	PTRACE_DEFAULT                 = 0x1
+	PTRACE_EXEC                    = 0x1
+	PTRACE_FORK                    = 0x8
+	PTRACE_LWP                     = 0x10
+	PTRACE_SCE                     = 0x2
+	PTRACE_SCX                     = 0x4
+	PTRACE_SYSCALL                 = 0x6
+	PTRACE_VFORK                   = 0x20
+	PT_ATTACH                      = 0xa
+	PT_CLEARSTEP                   = 0x10
+	PT_CONTINUE                    = 0x7
+	PT_DETACH                      = 0xb
+	PT_FIRSTMACH                   = 0x40
+	PT_FOLLOW_FORK                 = 0x17
+	PT_GETDBREGS                   = 0x25
+	PT_GETFPREGS                   = 0x23
+	PT_GETFSBASE                   = 0x47
+	PT_GETGSBASE                   = 0x49
+	PT_GETLWPLIST                  = 0xf
+	PT_GETNUMLWPS                  = 0xe
+	PT_GETREGS                     = 0x21
+	PT_GETXMMREGS                  = 0x40
+	PT_GETXSTATE                   = 0x45
+	PT_GETXSTATE_INFO              = 0x44
+	PT_GET_EVENT_MASK              = 0x19
+	PT_GET_SC_ARGS                 = 0x1b
+	PT_GET_SC_RET                  = 0x1c
+	PT_IO                          = 0xc
+	PT_KILL                        = 0x8
+	PT_LWPINFO                     = 0xd
+	PT_LWP_EVENTS                  = 0x18
+	PT_READ_D                      = 0x2
+	PT_READ_I                      = 0x1
+	PT_RESUME                      = 0x13
+	PT_SETDBREGS                   = 0x26
+	PT_SETFPREGS                   = 0x24
+	PT_SETFSBASE                   = 0x48
+	PT_SETGSBASE                   = 0x4a
+	PT_SETREGS                     = 0x22
+	PT_SETSTEP                     = 0x11
+	PT_SETXMMREGS                  = 0x41
+	PT_SETXSTATE                   = 0x46
+	PT_SET_EVENT_MASK              = 0x1a
+	PT_STEP                        = 0x9
+	PT_SUSPEND                     = 0x12
+	PT_SYSCALL                     = 0x16
+	PT_TO_SCE                      = 0x14
+	PT_TO_SCX                      = 0x15
+	PT_TRACE_ME                    = 0x0
+	PT_VM_ENTRY                    = 0x29
+	PT_VM_TIMESTAMP                = 0x28
+	PT_WRITE_D                     = 0x5
+	PT_WRITE_I                     = 0x4
+	P_ZONEID                       = 0xc
 	RLIMIT_AS                      = 0xa
 	RLIMIT_CORE                    = 0x4
 	RLIMIT_CPU                     = 0x0
@@ -1320,10 +1386,12 @@
 	SIOCGHWADDR                    = 0xc020693e
 	SIOCGI2C                       = 0xc020693d
 	SIOCGIFADDR                    = 0xc0206921
+	SIOCGIFALIAS                   = 0xc044692d
 	SIOCGIFBRDADDR                 = 0xc0206923
 	SIOCGIFCAP                     = 0xc020691f
 	SIOCGIFCONF                    = 0xc0086924
 	SIOCGIFDESCR                   = 0xc020692a
+	SIOCGIFDOWNREASON              = 0xc058699a
 	SIOCGIFDSTADDR                 = 0xc0206922
 	SIOCGIFFIB                     = 0xc020695c
 	SIOCGIFFLAGS                   = 0xc0206911
@@ -1414,6 +1482,7 @@
 	SO_RCVBUF                      = 0x1002
 	SO_RCVLOWAT                    = 0x1004
 	SO_RCVTIMEO                    = 0x1006
+	SO_RERROR                      = 0x20000
 	SO_REUSEADDR                   = 0x4
 	SO_REUSEPORT                   = 0x200
 	SO_REUSEPORT_LB                = 0x10000
@@ -1472,22 +1541,40 @@
 	TCOFLUSH                       = 0x2
 	TCOOFF                         = 0x1
 	TCOON                          = 0x2
+	TCPOPT_EOL                     = 0x0
+	TCPOPT_FAST_OPEN               = 0x22
+	TCPOPT_MAXSEG                  = 0x2
+	TCPOPT_NOP                     = 0x1
+	TCPOPT_PAD                     = 0x0
+	TCPOPT_SACK                    = 0x5
+	TCPOPT_SACK_PERMITTED          = 0x4
+	TCPOPT_SIGNATURE               = 0x13
+	TCPOPT_TIMESTAMP               = 0x8
+	TCPOPT_WINDOW                  = 0x3
 	TCP_BBR_ACK_COMP_ALG           = 0x448
+	TCP_BBR_ALGORITHM              = 0x43b
 	TCP_BBR_DRAIN_INC_EXTRA        = 0x43c
 	TCP_BBR_DRAIN_PG               = 0x42e
 	TCP_BBR_EXTRA_GAIN             = 0x449
+	TCP_BBR_EXTRA_STATE            = 0x453
+	TCP_BBR_FLOOR_MIN_TSO          = 0x454
+	TCP_BBR_HDWR_PACE              = 0x451
+	TCP_BBR_HOLD_TARGET            = 0x436
 	TCP_BBR_IWINTSO                = 0x42b
 	TCP_BBR_LOWGAIN_FD             = 0x436
 	TCP_BBR_LOWGAIN_HALF           = 0x435
 	TCP_BBR_LOWGAIN_THRESH         = 0x434
 	TCP_BBR_MAX_RTO                = 0x439
 	TCP_BBR_MIN_RTO                = 0x438
+	TCP_BBR_MIN_TOPACEOUT          = 0x455
 	TCP_BBR_ONE_RETRAN             = 0x431
 	TCP_BBR_PACE_CROSS             = 0x442
 	TCP_BBR_PACE_DEL_TAR           = 0x43f
+	TCP_BBR_PACE_OH                = 0x435
 	TCP_BBR_PACE_PER_SEC           = 0x43e
 	TCP_BBR_PACE_SEG_MAX           = 0x440
 	TCP_BBR_PACE_SEG_MIN           = 0x441
+	TCP_BBR_POLICER_DETECT         = 0x457
 	TCP_BBR_PROBE_RTT_GAIN         = 0x44d
 	TCP_BBR_PROBE_RTT_INT          = 0x430
 	TCP_BBR_PROBE_RTT_LEN          = 0x44e
@@ -1496,12 +1583,18 @@
 	TCP_BBR_REC_OVER_HPTS          = 0x43a
 	TCP_BBR_RETRAN_WTSO            = 0x44b
 	TCP_BBR_RWND_IS_APP            = 0x42f
+	TCP_BBR_SEND_IWND_IN_TSO       = 0x44f
 	TCP_BBR_STARTUP_EXIT_EPOCH     = 0x43d
 	TCP_BBR_STARTUP_LOSS_EXIT      = 0x432
 	TCP_BBR_STARTUP_PG             = 0x42d
+	TCP_BBR_TMR_PACE_OH            = 0x448
+	TCP_BBR_TSLIMITS               = 0x434
+	TCP_BBR_TSTMP_RAISES           = 0x456
 	TCP_BBR_UNLIMITED              = 0x43b
 	TCP_BBR_USEDEL_RATE            = 0x437
 	TCP_BBR_USE_LOWGAIN            = 0x433
+	TCP_BBR_USE_RACK_CHEAT         = 0x450
+	TCP_BBR_UTTER_MAX_TSO          = 0x452
 	TCP_CA_NAME_MAX                = 0x10
 	TCP_CCALGOOPT                  = 0x41
 	TCP_CONGESTION                 = 0x40
@@ -1541,6 +1634,7 @@
 	TCP_PCAP_OUT                   = 0x800
 	TCP_RACK_EARLY_RECOV           = 0x423
 	TCP_RACK_EARLY_SEG             = 0x424
+	TCP_RACK_GP_INCREASE           = 0x446
 	TCP_RACK_IDLE_REDUCE_HIGH      = 0x444
 	TCP_RACK_MIN_PACE              = 0x445
 	TCP_RACK_MIN_PACE_SEG          = 0x446
@@ -1554,7 +1648,6 @@
 	TCP_RACK_PRR_SENDALOT          = 0x421
 	TCP_RACK_REORD_FADE            = 0x426
 	TCP_RACK_REORD_THRESH          = 0x425
-	TCP_RACK_SESS_CWV              = 0x42a
 	TCP_RACK_TLP_INC_VAR           = 0x429
 	TCP_RACK_TLP_REDUCE            = 0x41c
 	TCP_RACK_TLP_THRESH            = 0x427
@@ -1694,12 +1787,13 @@
 	EIDRM           = syscall.Errno(0x52)
 	EILSEQ          = syscall.Errno(0x56)
 	EINPROGRESS     = syscall.Errno(0x24)
+	EINTEGRITY      = syscall.Errno(0x61)
 	EINTR           = syscall.Errno(0x4)
 	EINVAL          = syscall.Errno(0x16)
 	EIO             = syscall.Errno(0x5)
 	EISCONN         = syscall.Errno(0x38)
 	EISDIR          = syscall.Errno(0x15)
-	ELAST           = syscall.Errno(0x60)
+	ELAST           = syscall.Errno(0x61)
 	ELOOP           = syscall.Errno(0x3e)
 	EMFILE          = syscall.Errno(0x18)
 	EMLINK          = syscall.Errno(0x1f)
@@ -1842,7 +1936,7 @@
 	{32, "EPIPE", "broken pipe"},
 	{33, "EDOM", "numerical argument out of domain"},
 	{34, "ERANGE", "result too large"},
-	{35, "EAGAIN", "resource temporarily unavailable"},
+	{35, "EWOULDBLOCK", "resource temporarily unavailable"},
 	{36, "EINPROGRESS", "operation now in progress"},
 	{37, "EALREADY", "operation already in progress"},
 	{38, "ENOTSOCK", "socket operation on non-socket"},
@@ -1904,6 +1998,7 @@
 	{94, "ECAPMODE", "not permitted in capability mode"},
 	{95, "ENOTRECOVERABLE", "state not recoverable"},
 	{96, "EOWNERDEAD", "previous owner died"},
+	{97, "EINTEGRITY", "integrity check failed"},
 }
 
 // Signal table
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go
index 64520d3..96310c3 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_amd64.go
@@ -151,6 +151,7 @@
 	BIOCSETF                       = 0x80104267
 	BIOCSETFNR                     = 0x80104282
 	BIOCSETIF                      = 0x8020426c
+	BIOCSETVLANPCP                 = 0x80044285
 	BIOCSETWF                      = 0x8010427b
 	BIOCSETZBUF                    = 0x80184281
 	BIOCSHDRCMPLT                  = 0x80044275
@@ -447,7 +448,7 @@
 	DLT_IEEE802_16_MAC_CPS_RADIO   = 0xc1
 	DLT_INFINIBAND                 = 0xf7
 	DLT_IPFILTER                   = 0x74
-	DLT_IPMB                       = 0xc7
+	DLT_IPMB_KONTRON               = 0xc7
 	DLT_IPMB_LINUX                 = 0xd1
 	DLT_IPMI_HPM_2                 = 0x104
 	DLT_IPNET                      = 0xe2
@@ -487,10 +488,11 @@
 	DLT_LINUX_LAPD                 = 0xb1
 	DLT_LINUX_PPP_WITHDIRECTION    = 0xa6
 	DLT_LINUX_SLL                  = 0x71
+	DLT_LINUX_SLL2                 = 0x114
 	DLT_LOOP                       = 0x6c
 	DLT_LORATAP                    = 0x10e
 	DLT_LTALK                      = 0x72
-	DLT_MATCHING_MAX               = 0x113
+	DLT_MATCHING_MAX               = 0x114
 	DLT_MATCHING_MIN               = 0x68
 	DLT_MFR                        = 0xb6
 	DLT_MOST                       = 0xd3
@@ -734,6 +736,7 @@
 	IPPROTO_CMTP                   = 0x26
 	IPPROTO_CPHB                   = 0x49
 	IPPROTO_CPNX                   = 0x48
+	IPPROTO_DCCP                   = 0x21
 	IPPROTO_DDP                    = 0x25
 	IPPROTO_DGP                    = 0x56
 	IPPROTO_DIVERT                 = 0x102
@@ -814,7 +817,6 @@
 	IPPROTO_SCTP                   = 0x84
 	IPPROTO_SDRP                   = 0x2a
 	IPPROTO_SEND                   = 0x103
-	IPPROTO_SEP                    = 0x21
 	IPPROTO_SHIM6                  = 0x8c
 	IPPROTO_SKIP                   = 0x39
 	IPPROTO_SPACER                 = 0x7fff
@@ -911,6 +913,7 @@
 	IPV6_V6ONLY                    = 0x1b
 	IPV6_VERSION                   = 0x60
 	IPV6_VERSION_MASK              = 0xf0
+	IPV6_VLAN_PCP                  = 0x4b
 	IP_ADD_MEMBERSHIP              = 0xc
 	IP_ADD_SOURCE_MEMBERSHIP       = 0x46
 	IP_BINDANY                     = 0x18
@@ -989,8 +992,12 @@
 	IP_TOS                         = 0x3
 	IP_TTL                         = 0x4
 	IP_UNBLOCK_SOURCE              = 0x49
+	IP_VLAN_PCP                    = 0x4b
 	ISIG                           = 0x80
 	ISTRIP                         = 0x20
+	ITIMER_PROF                    = 0x2
+	ITIMER_REAL                    = 0x0
+	ITIMER_VIRTUAL                 = 0x1
 	IXANY                          = 0x800
 	IXOFF                          = 0x400
 	IXON                           = 0x200
@@ -1000,7 +1007,6 @@
 	KERN_VERSION                   = 0x4
 	LOCAL_CONNWAIT                 = 0x4
 	LOCAL_CREDS                    = 0x2
-	LOCAL_CREDS_PERSISTENT         = 0x3
 	LOCAL_PEERCRED                 = 0x1
 	LOCAL_VENDOR                   = 0x80000000
 	LOCK_EX                        = 0x2
@@ -1180,6 +1186,8 @@
 	O_NONBLOCK                     = 0x4
 	O_RDONLY                       = 0x0
 	O_RDWR                         = 0x2
+	O_RESOLVE_BENEATH              = 0x800000
+	O_SEARCH                       = 0x40000
 	O_SHLOCK                       = 0x10
 	O_SYNC                         = 0x80
 	O_TRUNC                        = 0x400
@@ -1190,6 +1198,10 @@
 	PARMRK                         = 0x8
 	PARODD                         = 0x2000
 	PENDIN                         = 0x20000000
+	PIOD_READ_D                    = 0x1
+	PIOD_READ_I                    = 0x3
+	PIOD_WRITE_D                   = 0x2
+	PIOD_WRITE_I                   = 0x4
 	PRIO_PGRP                      = 0x1
 	PRIO_PROCESS                   = 0x0
 	PRIO_USER                      = 0x2
@@ -1197,6 +1209,58 @@
 	PROT_NONE                      = 0x0
 	PROT_READ                      = 0x1
 	PROT_WRITE                     = 0x2
+	PTRACE_DEFAULT                 = 0x1
+	PTRACE_EXEC                    = 0x1
+	PTRACE_FORK                    = 0x8
+	PTRACE_LWP                     = 0x10
+	PTRACE_SCE                     = 0x2
+	PTRACE_SCX                     = 0x4
+	PTRACE_SYSCALL                 = 0x6
+	PTRACE_VFORK                   = 0x20
+	PT_ATTACH                      = 0xa
+	PT_CLEARSTEP                   = 0x10
+	PT_CONTINUE                    = 0x7
+	PT_DETACH                      = 0xb
+	PT_FIRSTMACH                   = 0x40
+	PT_FOLLOW_FORK                 = 0x17
+	PT_GETDBREGS                   = 0x25
+	PT_GETFPREGS                   = 0x23
+	PT_GETFSBASE                   = 0x47
+	PT_GETGSBASE                   = 0x49
+	PT_GETLWPLIST                  = 0xf
+	PT_GETNUMLWPS                  = 0xe
+	PT_GETREGS                     = 0x21
+	PT_GETXSTATE                   = 0x45
+	PT_GETXSTATE_INFO              = 0x44
+	PT_GET_EVENT_MASK              = 0x19
+	PT_GET_SC_ARGS                 = 0x1b
+	PT_GET_SC_RET                  = 0x1c
+	PT_IO                          = 0xc
+	PT_KILL                        = 0x8
+	PT_LWPINFO                     = 0xd
+	PT_LWP_EVENTS                  = 0x18
+	PT_READ_D                      = 0x2
+	PT_READ_I                      = 0x1
+	PT_RESUME                      = 0x13
+	PT_SETDBREGS                   = 0x26
+	PT_SETFPREGS                   = 0x24
+	PT_SETFSBASE                   = 0x48
+	PT_SETGSBASE                   = 0x4a
+	PT_SETREGS                     = 0x22
+	PT_SETSTEP                     = 0x11
+	PT_SETXSTATE                   = 0x46
+	PT_SET_EVENT_MASK              = 0x1a
+	PT_STEP                        = 0x9
+	PT_SUSPEND                     = 0x12
+	PT_SYSCALL                     = 0x16
+	PT_TO_SCE                      = 0x14
+	PT_TO_SCX                      = 0x15
+	PT_TRACE_ME                    = 0x0
+	PT_VM_ENTRY                    = 0x29
+	PT_VM_TIMESTAMP                = 0x28
+	PT_WRITE_D                     = 0x5
+	PT_WRITE_I                     = 0x4
+	P_ZONEID                       = 0xc
 	RLIMIT_AS                      = 0xa
 	RLIMIT_CORE                    = 0x4
 	RLIMIT_CPU                     = 0x0
@@ -1321,10 +1385,12 @@
 	SIOCGHWADDR                    = 0xc020693e
 	SIOCGI2C                       = 0xc020693d
 	SIOCGIFADDR                    = 0xc0206921
+	SIOCGIFALIAS                   = 0xc044692d
 	SIOCGIFBRDADDR                 = 0xc0206923
 	SIOCGIFCAP                     = 0xc020691f
 	SIOCGIFCONF                    = 0xc0106924
 	SIOCGIFDESCR                   = 0xc020692a
+	SIOCGIFDOWNREASON              = 0xc058699a
 	SIOCGIFDSTADDR                 = 0xc0206922
 	SIOCGIFFIB                     = 0xc020695c
 	SIOCGIFFLAGS                   = 0xc0206911
@@ -1415,6 +1481,7 @@
 	SO_RCVBUF                      = 0x1002
 	SO_RCVLOWAT                    = 0x1004
 	SO_RCVTIMEO                    = 0x1006
+	SO_RERROR                      = 0x20000
 	SO_REUSEADDR                   = 0x4
 	SO_REUSEPORT                   = 0x200
 	SO_REUSEPORT_LB                = 0x10000
@@ -1473,22 +1540,40 @@
 	TCOFLUSH                       = 0x2
 	TCOOFF                         = 0x1
 	TCOON                          = 0x2
+	TCPOPT_EOL                     = 0x0
+	TCPOPT_FAST_OPEN               = 0x22
+	TCPOPT_MAXSEG                  = 0x2
+	TCPOPT_NOP                     = 0x1
+	TCPOPT_PAD                     = 0x0
+	TCPOPT_SACK                    = 0x5
+	TCPOPT_SACK_PERMITTED          = 0x4
+	TCPOPT_SIGNATURE               = 0x13
+	TCPOPT_TIMESTAMP               = 0x8
+	TCPOPT_WINDOW                  = 0x3
 	TCP_BBR_ACK_COMP_ALG           = 0x448
+	TCP_BBR_ALGORITHM              = 0x43b
 	TCP_BBR_DRAIN_INC_EXTRA        = 0x43c
 	TCP_BBR_DRAIN_PG               = 0x42e
 	TCP_BBR_EXTRA_GAIN             = 0x449
+	TCP_BBR_EXTRA_STATE            = 0x453
+	TCP_BBR_FLOOR_MIN_TSO          = 0x454
+	TCP_BBR_HDWR_PACE              = 0x451
+	TCP_BBR_HOLD_TARGET            = 0x436
 	TCP_BBR_IWINTSO                = 0x42b
 	TCP_BBR_LOWGAIN_FD             = 0x436
 	TCP_BBR_LOWGAIN_HALF           = 0x435
 	TCP_BBR_LOWGAIN_THRESH         = 0x434
 	TCP_BBR_MAX_RTO                = 0x439
 	TCP_BBR_MIN_RTO                = 0x438
+	TCP_BBR_MIN_TOPACEOUT          = 0x455
 	TCP_BBR_ONE_RETRAN             = 0x431
 	TCP_BBR_PACE_CROSS             = 0x442
 	TCP_BBR_PACE_DEL_TAR           = 0x43f
+	TCP_BBR_PACE_OH                = 0x435
 	TCP_BBR_PACE_PER_SEC           = 0x43e
 	TCP_BBR_PACE_SEG_MAX           = 0x440
 	TCP_BBR_PACE_SEG_MIN           = 0x441
+	TCP_BBR_POLICER_DETECT         = 0x457
 	TCP_BBR_PROBE_RTT_GAIN         = 0x44d
 	TCP_BBR_PROBE_RTT_INT          = 0x430
 	TCP_BBR_PROBE_RTT_LEN          = 0x44e
@@ -1497,12 +1582,18 @@
 	TCP_BBR_REC_OVER_HPTS          = 0x43a
 	TCP_BBR_RETRAN_WTSO            = 0x44b
 	TCP_BBR_RWND_IS_APP            = 0x42f
+	TCP_BBR_SEND_IWND_IN_TSO       = 0x44f
 	TCP_BBR_STARTUP_EXIT_EPOCH     = 0x43d
 	TCP_BBR_STARTUP_LOSS_EXIT      = 0x432
 	TCP_BBR_STARTUP_PG             = 0x42d
+	TCP_BBR_TMR_PACE_OH            = 0x448
+	TCP_BBR_TSLIMITS               = 0x434
+	TCP_BBR_TSTMP_RAISES           = 0x456
 	TCP_BBR_UNLIMITED              = 0x43b
 	TCP_BBR_USEDEL_RATE            = 0x437
 	TCP_BBR_USE_LOWGAIN            = 0x433
+	TCP_BBR_USE_RACK_CHEAT         = 0x450
+	TCP_BBR_UTTER_MAX_TSO          = 0x452
 	TCP_CA_NAME_MAX                = 0x10
 	TCP_CCALGOOPT                  = 0x41
 	TCP_CONGESTION                 = 0x40
@@ -1542,6 +1633,7 @@
 	TCP_PCAP_OUT                   = 0x800
 	TCP_RACK_EARLY_RECOV           = 0x423
 	TCP_RACK_EARLY_SEG             = 0x424
+	TCP_RACK_GP_INCREASE           = 0x446
 	TCP_RACK_IDLE_REDUCE_HIGH      = 0x444
 	TCP_RACK_MIN_PACE              = 0x445
 	TCP_RACK_MIN_PACE_SEG          = 0x446
@@ -1555,7 +1647,6 @@
 	TCP_RACK_PRR_SENDALOT          = 0x421
 	TCP_RACK_REORD_FADE            = 0x426
 	TCP_RACK_REORD_THRESH          = 0x425
-	TCP_RACK_SESS_CWV              = 0x42a
 	TCP_RACK_TLP_INC_VAR           = 0x429
 	TCP_RACK_TLP_REDUCE            = 0x41c
 	TCP_RACK_TLP_THRESH            = 0x427
@@ -1693,12 +1784,13 @@
 	EIDRM           = syscall.Errno(0x52)
 	EILSEQ          = syscall.Errno(0x56)
 	EINPROGRESS     = syscall.Errno(0x24)
+	EINTEGRITY      = syscall.Errno(0x61)
 	EINTR           = syscall.Errno(0x4)
 	EINVAL          = syscall.Errno(0x16)
 	EIO             = syscall.Errno(0x5)
 	EISCONN         = syscall.Errno(0x38)
 	EISDIR          = syscall.Errno(0x15)
-	ELAST           = syscall.Errno(0x60)
+	ELAST           = syscall.Errno(0x61)
 	ELOOP           = syscall.Errno(0x3e)
 	EMFILE          = syscall.Errno(0x18)
 	EMLINK          = syscall.Errno(0x1f)
@@ -1841,7 +1933,7 @@
 	{32, "EPIPE", "broken pipe"},
 	{33, "EDOM", "numerical argument out of domain"},
 	{34, "ERANGE", "result too large"},
-	{35, "EAGAIN", "resource temporarily unavailable"},
+	{35, "EWOULDBLOCK", "resource temporarily unavailable"},
 	{36, "EINPROGRESS", "operation now in progress"},
 	{37, "EALREADY", "operation already in progress"},
 	{38, "ENOTSOCK", "socket operation on non-socket"},
@@ -1903,6 +1995,7 @@
 	{94, "ECAPMODE", "not permitted in capability mode"},
 	{95, "ENOTRECOVERABLE", "state not recoverable"},
 	{96, "EOWNERDEAD", "previous owner died"},
+	{97, "EINTEGRITY", "integrity check failed"},
 }
 
 // Signal table
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go
index 99e9a0e..777b69d 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm.go
@@ -151,6 +151,7 @@
 	BIOCSETF                       = 0x80084267
 	BIOCSETFNR                     = 0x80084282
 	BIOCSETIF                      = 0x8020426c
+	BIOCSETVLANPCP                 = 0x80044285
 	BIOCSETWF                      = 0x8008427b
 	BIOCSETZBUF                    = 0x800c4281
 	BIOCSHDRCMPLT                  = 0x80044275
@@ -362,7 +363,7 @@
 	CTL_KERN                       = 0x1
 	CTL_MAXNAME                    = 0x18
 	CTL_NET                        = 0x4
-	DIOCGATTR                      = 0xc144648e
+	DIOCGATTR                      = 0xc148648e
 	DIOCGDELETE                    = 0x80106488
 	DIOCGFLUSH                     = 0x20006487
 	DIOCGFRONTSTUFF                = 0x40086486
@@ -377,7 +378,7 @@
 	DIOCGSTRIPESIZE                = 0x4008648b
 	DIOCSKERNELDUMP                = 0x804c6490
 	DIOCSKERNELDUMP_FREEBSD11      = 0x80046485
-	DIOCZONECMD                    = 0xc06c648f
+	DIOCZONECMD                    = 0xc078648f
 	DLT_A429                       = 0xb8
 	DLT_A653_ICM                   = 0xb9
 	DLT_AIRONET_HEADER             = 0x78
@@ -407,7 +408,9 @@
 	DLT_C_HDLC_WITH_DIR            = 0xcd
 	DLT_DBUS                       = 0xe7
 	DLT_DECT                       = 0xdd
+	DLT_DISPLAYPORT_AUX            = 0x113
 	DLT_DOCSIS                     = 0x8f
+	DLT_DOCSIS31_XRA31             = 0x111
 	DLT_DVB_CI                     = 0xeb
 	DLT_ECONET                     = 0x73
 	DLT_EN10MB                     = 0x1
@@ -417,6 +420,7 @@
 	DLT_ERF                        = 0xc5
 	DLT_ERF_ETH                    = 0xaf
 	DLT_ERF_POS                    = 0xb0
+	DLT_ETHERNET_MPACKET           = 0x112
 	DLT_FC_2                       = 0xe0
 	DLT_FC_2_WITH_FRAME_DELIMS     = 0xe1
 	DLT_FDDI                       = 0xa
@@ -444,7 +448,7 @@
 	DLT_IEEE802_16_MAC_CPS_RADIO   = 0xc1
 	DLT_INFINIBAND                 = 0xf7
 	DLT_IPFILTER                   = 0x74
-	DLT_IPMB                       = 0xc7
+	DLT_IPMB_KONTRON               = 0xc7
 	DLT_IPMB_LINUX                 = 0xd1
 	DLT_IPMI_HPM_2                 = 0x104
 	DLT_IPNET                      = 0xe2
@@ -484,9 +488,11 @@
 	DLT_LINUX_LAPD                 = 0xb1
 	DLT_LINUX_PPP_WITHDIRECTION    = 0xa6
 	DLT_LINUX_SLL                  = 0x71
+	DLT_LINUX_SLL2                 = 0x114
 	DLT_LOOP                       = 0x6c
+	DLT_LORATAP                    = 0x10e
 	DLT_LTALK                      = 0x72
-	DLT_MATCHING_MAX               = 0x109
+	DLT_MATCHING_MAX               = 0x114
 	DLT_MATCHING_MIN               = 0x68
 	DLT_MFR                        = 0xb6
 	DLT_MOST                       = 0xd3
@@ -502,7 +508,9 @@
 	DLT_NFC_LLCP                   = 0xf5
 	DLT_NFLOG                      = 0xef
 	DLT_NG40                       = 0xf4
+	DLT_NORDIC_BLE                 = 0x110
 	DLT_NULL                       = 0x0
+	DLT_OPENFLOW                   = 0x10b
 	DLT_PCI_EXP                    = 0x7d
 	DLT_PFLOG                      = 0x75
 	DLT_PFSYNC                     = 0x79
@@ -526,15 +534,18 @@
 	DLT_RTAC_SERIAL                = 0xfa
 	DLT_SCCP                       = 0x8e
 	DLT_SCTP                       = 0xf8
+	DLT_SDLC                       = 0x10c
 	DLT_SITA                       = 0xc4
 	DLT_SLIP                       = 0x8
 	DLT_SLIP_BSDOS                 = 0xd
 	DLT_STANAG_5066_D_PDU          = 0xed
 	DLT_SUNATM                     = 0x7b
 	DLT_SYMANTEC_FIREWALL          = 0x63
+	DLT_TI_LLN_SNIFFER             = 0x10d
 	DLT_TZSP                       = 0x80
 	DLT_USB                        = 0xba
 	DLT_USBPCAP                    = 0xf9
+	DLT_USB_DARWIN                 = 0x10a
 	DLT_USB_FREEBSD                = 0xba
 	DLT_USB_LINUX                  = 0xbd
 	DLT_USB_LINUX_MMAPPED          = 0xdc
@@ -554,6 +565,7 @@
 	DLT_USER7                      = 0x9a
 	DLT_USER8                      = 0x9b
 	DLT_USER9                      = 0x9c
+	DLT_VSOCK                      = 0x10f
 	DLT_WATTSTOPPER_DLM            = 0x107
 	DLT_WIHART                     = 0xdf
 	DLT_WIRESHARK_UPPER_PDU        = 0xfc
@@ -578,6 +590,7 @@
 	ECHONL                         = 0x10
 	ECHOPRT                        = 0x20
 	EVFILT_AIO                     = -0x3
+	EVFILT_EMPTY                   = -0xd
 	EVFILT_FS                      = -0x9
 	EVFILT_LIO                     = -0xa
 	EVFILT_PROC                    = -0x5
@@ -585,11 +598,12 @@
 	EVFILT_READ                    = -0x1
 	EVFILT_SENDFILE                = -0xc
 	EVFILT_SIGNAL                  = -0x6
-	EVFILT_SYSCOUNT                = 0xc
+	EVFILT_SYSCOUNT                = 0xd
 	EVFILT_TIMER                   = -0x7
 	EVFILT_USER                    = -0xb
 	EVFILT_VNODE                   = -0x4
 	EVFILT_WRITE                   = -0x2
+	EVNAMEMAP_NAME_SIZE            = 0x40
 	EV_ADD                         = 0x1
 	EV_CLEAR                       = 0x20
 	EV_DELETE                      = 0x2
@@ -606,6 +620,7 @@
 	EV_RECEIPT                     = 0x40
 	EV_SYSFLAGS                    = 0xf000
 	EXTA                           = 0x4b00
+	EXTATTR_MAXNAMELEN             = 0xff
 	EXTATTR_NAMESPACE_EMPTY        = 0x0
 	EXTATTR_NAMESPACE_SYSTEM       = 0x2
 	EXTATTR_NAMESPACE_USER         = 0x1
@@ -647,6 +662,7 @@
 	IEXTEN                         = 0x400
 	IFAN_ARRIVAL                   = 0x0
 	IFAN_DEPARTURE                 = 0x1
+	IFCAP_WOL_MAGIC                = 0x2000
 	IFF_ALLMULTI                   = 0x200
 	IFF_ALTPHYS                    = 0x4000
 	IFF_BROADCAST                  = 0x2
@@ -663,6 +679,7 @@
 	IFF_MONITOR                    = 0x40000
 	IFF_MULTICAST                  = 0x8000
 	IFF_NOARP                      = 0x80
+	IFF_NOGROUP                    = 0x800000
 	IFF_OACTIVE                    = 0x400
 	IFF_POINTOPOINT                = 0x10
 	IFF_PPROMISC                   = 0x20000
@@ -719,6 +736,7 @@
 	IPPROTO_CMTP                   = 0x26
 	IPPROTO_CPHB                   = 0x49
 	IPPROTO_CPNX                   = 0x48
+	IPPROTO_DCCP                   = 0x21
 	IPPROTO_DDP                    = 0x25
 	IPPROTO_DGP                    = 0x56
 	IPPROTO_DIVERT                 = 0x102
@@ -799,7 +817,6 @@
 	IPPROTO_SCTP                   = 0x84
 	IPPROTO_SDRP                   = 0x2a
 	IPPROTO_SEND                   = 0x103
-	IPPROTO_SEP                    = 0x21
 	IPPROTO_SHIM6                  = 0x8c
 	IPPROTO_SKIP                   = 0x39
 	IPPROTO_SPACER                 = 0x7fff
@@ -837,6 +854,7 @@
 	IPV6_DSTOPTS                   = 0x32
 	IPV6_FLOWID                    = 0x43
 	IPV6_FLOWINFO_MASK             = 0xffffff0f
+	IPV6_FLOWLABEL_LEN             = 0x14
 	IPV6_FLOWLABEL_MASK            = 0xffff0f00
 	IPV6_FLOWTYPE                  = 0x44
 	IPV6_FRAGTTL                   = 0x78
@@ -857,13 +875,13 @@
 	IPV6_MAX_GROUP_SRC_FILTER      = 0x200
 	IPV6_MAX_MEMBERSHIPS           = 0xfff
 	IPV6_MAX_SOCK_SRC_FILTER       = 0x80
-	IPV6_MIN_MEMBERSHIPS           = 0x1f
 	IPV6_MMTU                      = 0x500
 	IPV6_MSFILTER                  = 0x4a
 	IPV6_MULTICAST_HOPS            = 0xa
 	IPV6_MULTICAST_IF              = 0x9
 	IPV6_MULTICAST_LOOP            = 0xb
 	IPV6_NEXTHOP                   = 0x30
+	IPV6_ORIGDSTADDR               = 0x48
 	IPV6_PATHMTU                   = 0x2c
 	IPV6_PKTINFO                   = 0x2e
 	IPV6_PORTRANGE                 = 0xe
@@ -875,6 +893,7 @@
 	IPV6_RECVFLOWID                = 0x46
 	IPV6_RECVHOPLIMIT              = 0x25
 	IPV6_RECVHOPOPTS               = 0x27
+	IPV6_RECVORIGDSTADDR           = 0x48
 	IPV6_RECVPATHMTU               = 0x2b
 	IPV6_RECVPKTINFO               = 0x24
 	IPV6_RECVRSSBUCKETID           = 0x47
@@ -894,6 +913,7 @@
 	IPV6_V6ONLY                    = 0x1b
 	IPV6_VERSION                   = 0x60
 	IPV6_VERSION_MASK              = 0xf0
+	IPV6_VLAN_PCP                  = 0x4b
 	IP_ADD_MEMBERSHIP              = 0xc
 	IP_ADD_SOURCE_MEMBERSHIP       = 0x46
 	IP_BINDANY                     = 0x18
@@ -935,10 +955,8 @@
 	IP_MAX_MEMBERSHIPS             = 0xfff
 	IP_MAX_SOCK_MUTE_FILTER        = 0x80
 	IP_MAX_SOCK_SRC_FILTER         = 0x80
-	IP_MAX_SOURCE_FILTER           = 0x400
 	IP_MF                          = 0x2000
 	IP_MINTTL                      = 0x42
-	IP_MIN_MEMBERSHIPS             = 0x1f
 	IP_MSFILTER                    = 0x4a
 	IP_MSS                         = 0x240
 	IP_MULTICAST_IF                = 0x9
@@ -948,6 +966,7 @@
 	IP_OFFMASK                     = 0x1fff
 	IP_ONESBCAST                   = 0x17
 	IP_OPTIONS                     = 0x1
+	IP_ORIGDSTADDR                 = 0x1b
 	IP_PORTRANGE                   = 0x13
 	IP_PORTRANGE_DEFAULT           = 0x0
 	IP_PORTRANGE_HIGH              = 0x1
@@ -956,6 +975,7 @@
 	IP_RECVFLOWID                  = 0x5d
 	IP_RECVIF                      = 0x14
 	IP_RECVOPTS                    = 0x5
+	IP_RECVORIGDSTADDR             = 0x1b
 	IP_RECVRETOPTS                 = 0x6
 	IP_RECVRSSBUCKETID             = 0x5e
 	IP_RECVTOS                     = 0x44
@@ -972,8 +992,12 @@
 	IP_TOS                         = 0x3
 	IP_TTL                         = 0x4
 	IP_UNBLOCK_SOURCE              = 0x49
+	IP_VLAN_PCP                    = 0x4b
 	ISIG                           = 0x80
 	ISTRIP                         = 0x20
+	ITIMER_PROF                    = 0x2
+	ITIMER_REAL                    = 0x0
+	ITIMER_VIRTUAL                 = 0x1
 	IXANY                          = 0x800
 	IXOFF                          = 0x400
 	IXON                           = 0x200
@@ -983,7 +1007,6 @@
 	KERN_VERSION                   = 0x4
 	LOCAL_CONNWAIT                 = 0x4
 	LOCAL_CREDS                    = 0x2
-	LOCAL_CREDS_PERSISTENT         = 0x3
 	LOCAL_PEERCRED                 = 0x1
 	LOCAL_VENDOR                   = 0x80000000
 	LOCK_EX                        = 0x2
@@ -1071,10 +1094,12 @@
 	MNT_SUSPEND                    = 0x4
 	MNT_SYNCHRONOUS                = 0x2
 	MNT_UNION                      = 0x20
+	MNT_UNTRUSTED                  = 0x800000000
 	MNT_UPDATE                     = 0x10000
-	MNT_UPDATEMASK                 = 0x2d8d0807e
+	MNT_UPDATEMASK                 = 0xad8d0807e
 	MNT_USER                       = 0x8000
-	MNT_VISFLAGMASK                = 0x3fef0ffff
+	MNT_VERIFIED                   = 0x400000000
+	MNT_VISFLAGMASK                = 0xffef0ffff
 	MNT_WAIT                       = 0x1
 	MSG_CMSG_CLOEXEC               = 0x40000
 	MSG_COMPAT                     = 0x8000
@@ -1103,6 +1128,7 @@
 	NFDBITS                        = 0x20
 	NOFLSH                         = 0x80000000
 	NOKERNINFO                     = 0x2000000
+	NOTE_ABSTIME                   = 0x10
 	NOTE_ATTRIB                    = 0x8
 	NOTE_CHILD                     = 0x4
 	NOTE_CLOSE                     = 0x100
@@ -1159,6 +1185,8 @@
 	O_NONBLOCK                     = 0x4
 	O_RDONLY                       = 0x0
 	O_RDWR                         = 0x2
+	O_RESOLVE_BENEATH              = 0x800000
+	O_SEARCH                       = 0x40000
 	O_SHLOCK                       = 0x10
 	O_SYNC                         = 0x80
 	O_TRUNC                        = 0x400
@@ -1169,6 +1197,10 @@
 	PARMRK                         = 0x8
 	PARODD                         = 0x2000
 	PENDIN                         = 0x20000000
+	PIOD_READ_D                    = 0x1
+	PIOD_READ_I                    = 0x3
+	PIOD_WRITE_D                   = 0x2
+	PIOD_WRITE_I                   = 0x4
 	PRIO_PGRP                      = 0x1
 	PRIO_PROCESS                   = 0x0
 	PRIO_USER                      = 0x2
@@ -1176,6 +1208,53 @@
 	PROT_NONE                      = 0x0
 	PROT_READ                      = 0x1
 	PROT_WRITE                     = 0x2
+	PTRACE_DEFAULT                 = 0x1
+	PTRACE_EXEC                    = 0x1
+	PTRACE_FORK                    = 0x8
+	PTRACE_LWP                     = 0x10
+	PTRACE_SCE                     = 0x2
+	PTRACE_SCX                     = 0x4
+	PTRACE_SYSCALL                 = 0x6
+	PTRACE_VFORK                   = 0x20
+	PT_ATTACH                      = 0xa
+	PT_CLEARSTEP                   = 0x10
+	PT_CONTINUE                    = 0x7
+	PT_DETACH                      = 0xb
+	PT_FIRSTMACH                   = 0x40
+	PT_FOLLOW_FORK                 = 0x17
+	PT_GETDBREGS                   = 0x25
+	PT_GETFPREGS                   = 0x23
+	PT_GETLWPLIST                  = 0xf
+	PT_GETNUMLWPS                  = 0xe
+	PT_GETREGS                     = 0x21
+	PT_GETVFPREGS                  = 0x40
+	PT_GET_EVENT_MASK              = 0x19
+	PT_GET_SC_ARGS                 = 0x1b
+	PT_GET_SC_RET                  = 0x1c
+	PT_IO                          = 0xc
+	PT_KILL                        = 0x8
+	PT_LWPINFO                     = 0xd
+	PT_LWP_EVENTS                  = 0x18
+	PT_READ_D                      = 0x2
+	PT_READ_I                      = 0x1
+	PT_RESUME                      = 0x13
+	PT_SETDBREGS                   = 0x26
+	PT_SETFPREGS                   = 0x24
+	PT_SETREGS                     = 0x22
+	PT_SETSTEP                     = 0x11
+	PT_SETVFPREGS                  = 0x41
+	PT_SET_EVENT_MASK              = 0x1a
+	PT_STEP                        = 0x9
+	PT_SUSPEND                     = 0x12
+	PT_SYSCALL                     = 0x16
+	PT_TO_SCE                      = 0x14
+	PT_TO_SCX                      = 0x15
+	PT_TRACE_ME                    = 0x0
+	PT_VM_ENTRY                    = 0x29
+	PT_VM_TIMESTAMP                = 0x28
+	PT_WRITE_D                     = 0x5
+	PT_WRITE_I                     = 0x4
+	P_ZONEID                       = 0xc
 	RLIMIT_AS                      = 0xa
 	RLIMIT_CORE                    = 0x4
 	RLIMIT_CPU                     = 0x0
@@ -1257,7 +1336,6 @@
 	RTV_WEIGHT                     = 0x100
 	RT_ALL_FIBS                    = -0x1
 	RT_BLACKHOLE                   = 0x40
-	RT_CACHING_CONTEXT             = 0x1
 	RT_DEFAULT_FIB                 = 0x0
 	RT_HAS_GW                      = 0x80
 	RT_HAS_HEADER                  = 0x10
@@ -1267,15 +1345,17 @@
 	RT_LLE_CACHE                   = 0x100
 	RT_MAY_LOOP                    = 0x8
 	RT_MAY_LOOP_BIT                = 0x3
-	RT_NORTREF                     = 0x2
 	RT_REJECT                      = 0x20
 	RUSAGE_CHILDREN                = -0x1
 	RUSAGE_SELF                    = 0x0
 	RUSAGE_THREAD                  = 0x1
 	SCM_BINTIME                    = 0x4
 	SCM_CREDS                      = 0x3
+	SCM_MONOTONIC                  = 0x6
+	SCM_REALTIME                   = 0x5
 	SCM_RIGHTS                     = 0x1
 	SCM_TIMESTAMP                  = 0x2
+	SCM_TIME_INFO                  = 0x7
 	SEEK_CUR                       = 0x1
 	SEEK_DATA                      = 0x3
 	SEEK_END                       = 0x2
@@ -1299,10 +1379,12 @@
 	SIOCGHWADDR                    = 0xc020693e
 	SIOCGI2C                       = 0xc020693d
 	SIOCGIFADDR                    = 0xc0206921
+	SIOCGIFALIAS                   = 0xc044692d
 	SIOCGIFBRDADDR                 = 0xc0206923
 	SIOCGIFCAP                     = 0xc020691f
 	SIOCGIFCONF                    = 0xc0086924
 	SIOCGIFDESCR                   = 0xc020692a
+	SIOCGIFDOWNREASON              = 0xc058699a
 	SIOCGIFDSTADDR                 = 0xc0206922
 	SIOCGIFFIB                     = 0xc020695c
 	SIOCGIFFLAGS                   = 0xc0206911
@@ -1318,8 +1400,11 @@
 	SIOCGIFPDSTADDR                = 0xc0206948
 	SIOCGIFPHYS                    = 0xc0206935
 	SIOCGIFPSRCADDR                = 0xc0206947
+	SIOCGIFRSSHASH                 = 0xc0186997
+	SIOCGIFRSSKEY                  = 0xc0946996
 	SIOCGIFSTATUS                  = 0xc331693b
 	SIOCGIFXMEDIA                  = 0xc028698b
+	SIOCGLANPCP                    = 0xc0206998
 	SIOCGLOWAT                     = 0x40047303
 	SIOCGPGRP                      = 0x40047309
 	SIOCGPRIVATE_0                 = 0xc0206950
@@ -1350,6 +1435,7 @@
 	SIOCSIFPHYS                    = 0x80206936
 	SIOCSIFRVNET                   = 0xc020695b
 	SIOCSIFVNET                    = 0xc020695a
+	SIOCSLANPCP                    = 0x80206999
 	SIOCSLOWAT                     = 0x80047302
 	SIOCSPGRP                      = 0x80047308
 	SIOCSTUNFIB                    = 0x8020695f
@@ -1369,6 +1455,7 @@
 	SO_BINTIME                     = 0x2000
 	SO_BROADCAST                   = 0x20
 	SO_DEBUG                       = 0x1
+	SO_DOMAIN                      = 0x1019
 	SO_DONTROUTE                   = 0x10
 	SO_ERROR                       = 0x1007
 	SO_KEEPALIVE                   = 0x8
@@ -1377,6 +1464,7 @@
 	SO_LISTENINCQLEN               = 0x1013
 	SO_LISTENQLEN                  = 0x1012
 	SO_LISTENQLIMIT                = 0x1011
+	SO_MAX_PACING_RATE             = 0x1018
 	SO_NOSIGPIPE                   = 0x800
 	SO_NO_DDP                      = 0x8000
 	SO_NO_OFFLOAD                  = 0x4000
@@ -1387,13 +1475,22 @@
 	SO_RCVBUF                      = 0x1002
 	SO_RCVLOWAT                    = 0x1004
 	SO_RCVTIMEO                    = 0x1006
+	SO_RERROR                      = 0x20000
 	SO_REUSEADDR                   = 0x4
 	SO_REUSEPORT                   = 0x200
+	SO_REUSEPORT_LB                = 0x10000
 	SO_SETFIB                      = 0x1014
 	SO_SNDBUF                      = 0x1001
 	SO_SNDLOWAT                    = 0x1003
 	SO_SNDTIMEO                    = 0x1005
 	SO_TIMESTAMP                   = 0x400
+	SO_TS_BINTIME                  = 0x1
+	SO_TS_CLOCK                    = 0x1017
+	SO_TS_CLOCK_MAX                = 0x3
+	SO_TS_DEFAULT                  = 0x0
+	SO_TS_MONOTONIC                = 0x3
+	SO_TS_REALTIME                 = 0x2
+	SO_TS_REALTIME_MICRO           = 0x0
 	SO_TYPE                        = 0x1008
 	SO_USELOOPBACK                 = 0x40
 	SO_USER_COOKIE                 = 0x1015
@@ -1437,10 +1534,69 @@
 	TCOFLUSH                       = 0x2
 	TCOOFF                         = 0x1
 	TCOON                          = 0x2
+	TCPOPT_EOL                     = 0x0
+	TCPOPT_FAST_OPEN               = 0x22
+	TCPOPT_MAXSEG                  = 0x2
+	TCPOPT_NOP                     = 0x1
+	TCPOPT_PAD                     = 0x0
+	TCPOPT_SACK                    = 0x5
+	TCPOPT_SACK_PERMITTED          = 0x4
+	TCPOPT_SIGNATURE               = 0x13
+	TCPOPT_TIMESTAMP               = 0x8
+	TCPOPT_WINDOW                  = 0x3
+	TCP_BBR_ACK_COMP_ALG           = 0x448
+	TCP_BBR_ALGORITHM              = 0x43b
+	TCP_BBR_DRAIN_INC_EXTRA        = 0x43c
+	TCP_BBR_DRAIN_PG               = 0x42e
+	TCP_BBR_EXTRA_GAIN             = 0x449
+	TCP_BBR_EXTRA_STATE            = 0x453
+	TCP_BBR_FLOOR_MIN_TSO          = 0x454
+	TCP_BBR_HDWR_PACE              = 0x451
+	TCP_BBR_HOLD_TARGET            = 0x436
+	TCP_BBR_IWINTSO                = 0x42b
+	TCP_BBR_LOWGAIN_FD             = 0x436
+	TCP_BBR_LOWGAIN_HALF           = 0x435
+	TCP_BBR_LOWGAIN_THRESH         = 0x434
+	TCP_BBR_MAX_RTO                = 0x439
+	TCP_BBR_MIN_RTO                = 0x438
+	TCP_BBR_MIN_TOPACEOUT          = 0x455
+	TCP_BBR_ONE_RETRAN             = 0x431
+	TCP_BBR_PACE_CROSS             = 0x442
+	TCP_BBR_PACE_DEL_TAR           = 0x43f
+	TCP_BBR_PACE_OH                = 0x435
+	TCP_BBR_PACE_PER_SEC           = 0x43e
+	TCP_BBR_PACE_SEG_MAX           = 0x440
+	TCP_BBR_PACE_SEG_MIN           = 0x441
+	TCP_BBR_POLICER_DETECT         = 0x457
+	TCP_BBR_PROBE_RTT_GAIN         = 0x44d
+	TCP_BBR_PROBE_RTT_INT          = 0x430
+	TCP_BBR_PROBE_RTT_LEN          = 0x44e
+	TCP_BBR_RACK_RTT_USE           = 0x44a
+	TCP_BBR_RECFORCE               = 0x42c
+	TCP_BBR_REC_OVER_HPTS          = 0x43a
+	TCP_BBR_RETRAN_WTSO            = 0x44b
+	TCP_BBR_RWND_IS_APP            = 0x42f
+	TCP_BBR_SEND_IWND_IN_TSO       = 0x44f
+	TCP_BBR_STARTUP_EXIT_EPOCH     = 0x43d
+	TCP_BBR_STARTUP_LOSS_EXIT      = 0x432
+	TCP_BBR_STARTUP_PG             = 0x42d
+	TCP_BBR_TMR_PACE_OH            = 0x448
+	TCP_BBR_TSLIMITS               = 0x434
+	TCP_BBR_TSTMP_RAISES           = 0x456
+	TCP_BBR_UNLIMITED              = 0x43b
+	TCP_BBR_USEDEL_RATE            = 0x437
+	TCP_BBR_USE_LOWGAIN            = 0x433
+	TCP_BBR_USE_RACK_CHEAT         = 0x450
+	TCP_BBR_UTTER_MAX_TSO          = 0x452
 	TCP_CA_NAME_MAX                = 0x10
 	TCP_CCALGOOPT                  = 0x41
 	TCP_CONGESTION                 = 0x40
+	TCP_DATA_AFTER_CLOSE           = 0x44c
+	TCP_DELACK                     = 0x48
 	TCP_FASTOPEN                   = 0x401
+	TCP_FASTOPEN_MAX_COOKIE_LEN    = 0x10
+	TCP_FASTOPEN_MIN_COOKIE_LEN    = 0x4
+	TCP_FASTOPEN_PSK_LEN           = 0x10
 	TCP_FUNCTION_BLK               = 0x2000
 	TCP_FUNCTION_NAME_LEN_MAX      = 0x20
 	TCP_INFO                       = 0x20
@@ -1448,6 +1604,12 @@
 	TCP_KEEPIDLE                   = 0x100
 	TCP_KEEPINIT                   = 0x80
 	TCP_KEEPINTVL                  = 0x200
+	TCP_LOG                        = 0x22
+	TCP_LOGBUF                     = 0x23
+	TCP_LOGDUMP                    = 0x25
+	TCP_LOGDUMPID                  = 0x26
+	TCP_LOGID                      = 0x24
+	TCP_LOG_ID_LEN                 = 0x40
 	TCP_MAXBURST                   = 0x4
 	TCP_MAXHLEN                    = 0x3c
 	TCP_MAXOLEN                    = 0x28
@@ -1463,8 +1625,30 @@
 	TCP_NOPUSH                     = 0x4
 	TCP_PCAP_IN                    = 0x1000
 	TCP_PCAP_OUT                   = 0x800
+	TCP_RACK_EARLY_RECOV           = 0x423
+	TCP_RACK_EARLY_SEG             = 0x424
+	TCP_RACK_GP_INCREASE           = 0x446
+	TCP_RACK_IDLE_REDUCE_HIGH      = 0x444
+	TCP_RACK_MIN_PACE              = 0x445
+	TCP_RACK_MIN_PACE_SEG          = 0x446
+	TCP_RACK_MIN_TO                = 0x422
+	TCP_RACK_PACE_ALWAYS           = 0x41f
+	TCP_RACK_PACE_MAX_SEG          = 0x41e
+	TCP_RACK_PACE_REDUCE           = 0x41d
+	TCP_RACK_PKT_DELAY             = 0x428
+	TCP_RACK_PROP                  = 0x41b
+	TCP_RACK_PROP_RATE             = 0x420
+	TCP_RACK_PRR_SENDALOT          = 0x421
+	TCP_RACK_REORD_FADE            = 0x426
+	TCP_RACK_REORD_THRESH          = 0x425
+	TCP_RACK_TLP_INC_VAR           = 0x429
+	TCP_RACK_TLP_REDUCE            = 0x41c
+	TCP_RACK_TLP_THRESH            = 0x427
+	TCP_RACK_TLP_USE               = 0x447
 	TCP_VENDOR                     = 0x80000000
 	TCSAFLUSH                      = 0x2
+	TIMER_ABSTIME                  = 0x1
+	TIMER_RELTIME                  = 0x0
 	TIOCCBRK                       = 0x2000747a
 	TIOCCDTR                       = 0x20007478
 	TIOCCONS                       = 0x80047462
@@ -1528,6 +1712,8 @@
 	TIOCTIMESTAMP                  = 0x40107459
 	TIOCUCNTL                      = 0x80047466
 	TOSTOP                         = 0x400000
+	UTIME_NOW                      = -0x1
+	UTIME_OMIT                     = -0x2
 	VDISCARD                       = 0xf
 	VDSUSP                         = 0xb
 	VEOF                           = 0x0
@@ -1592,12 +1778,13 @@
 	EIDRM           = syscall.Errno(0x52)
 	EILSEQ          = syscall.Errno(0x56)
 	EINPROGRESS     = syscall.Errno(0x24)
+	EINTEGRITY      = syscall.Errno(0x61)
 	EINTR           = syscall.Errno(0x4)
 	EINVAL          = syscall.Errno(0x16)
 	EIO             = syscall.Errno(0x5)
 	EISCONN         = syscall.Errno(0x38)
 	EISDIR          = syscall.Errno(0x15)
-	ELAST           = syscall.Errno(0x60)
+	ELAST           = syscall.Errno(0x61)
 	ELOOP           = syscall.Errno(0x3e)
 	EMFILE          = syscall.Errno(0x18)
 	EMLINK          = syscall.Errno(0x1f)
@@ -1740,7 +1927,7 @@
 	{32, "EPIPE", "broken pipe"},
 	{33, "EDOM", "numerical argument out of domain"},
 	{34, "ERANGE", "result too large"},
-	{35, "EAGAIN", "resource temporarily unavailable"},
+	{35, "EWOULDBLOCK", "resource temporarily unavailable"},
 	{36, "EINPROGRESS", "operation now in progress"},
 	{37, "EALREADY", "operation already in progress"},
 	{38, "ENOTSOCK", "socket operation on non-socket"},
@@ -1802,6 +1989,7 @@
 	{94, "ECAPMODE", "not permitted in capability mode"},
 	{95, "ENOTRECOVERABLE", "state not recoverable"},
 	{96, "EOWNERDEAD", "previous owner died"},
+	{97, "EINTEGRITY", "integrity check failed"},
 }
 
 // Signal table
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm64.go
index 4c83771..c557ac2 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_arm64.go
@@ -151,6 +151,7 @@
 	BIOCSETF                       = 0x80104267
 	BIOCSETFNR                     = 0x80104282
 	BIOCSETIF                      = 0x8020426c
+	BIOCSETVLANPCP                 = 0x80044285
 	BIOCSETWF                      = 0x8010427b
 	BIOCSETZBUF                    = 0x80184281
 	BIOCSHDRCMPLT                  = 0x80044275
@@ -447,7 +448,7 @@
 	DLT_IEEE802_16_MAC_CPS_RADIO   = 0xc1
 	DLT_INFINIBAND                 = 0xf7
 	DLT_IPFILTER                   = 0x74
-	DLT_IPMB                       = 0xc7
+	DLT_IPMB_KONTRON               = 0xc7
 	DLT_IPMB_LINUX                 = 0xd1
 	DLT_IPMI_HPM_2                 = 0x104
 	DLT_IPNET                      = 0xe2
@@ -487,10 +488,11 @@
 	DLT_LINUX_LAPD                 = 0xb1
 	DLT_LINUX_PPP_WITHDIRECTION    = 0xa6
 	DLT_LINUX_SLL                  = 0x71
+	DLT_LINUX_SLL2                 = 0x114
 	DLT_LOOP                       = 0x6c
 	DLT_LORATAP                    = 0x10e
 	DLT_LTALK                      = 0x72
-	DLT_MATCHING_MAX               = 0x113
+	DLT_MATCHING_MAX               = 0x114
 	DLT_MATCHING_MIN               = 0x68
 	DLT_MFR                        = 0xb6
 	DLT_MOST                       = 0xd3
@@ -734,6 +736,7 @@
 	IPPROTO_CMTP                   = 0x26
 	IPPROTO_CPHB                   = 0x49
 	IPPROTO_CPNX                   = 0x48
+	IPPROTO_DCCP                   = 0x21
 	IPPROTO_DDP                    = 0x25
 	IPPROTO_DGP                    = 0x56
 	IPPROTO_DIVERT                 = 0x102
@@ -814,7 +817,6 @@
 	IPPROTO_SCTP                   = 0x84
 	IPPROTO_SDRP                   = 0x2a
 	IPPROTO_SEND                   = 0x103
-	IPPROTO_SEP                    = 0x21
 	IPPROTO_SHIM6                  = 0x8c
 	IPPROTO_SKIP                   = 0x39
 	IPPROTO_SPACER                 = 0x7fff
@@ -911,6 +913,7 @@
 	IPV6_V6ONLY                    = 0x1b
 	IPV6_VERSION                   = 0x60
 	IPV6_VERSION_MASK              = 0xf0
+	IPV6_VLAN_PCP                  = 0x4b
 	IP_ADD_MEMBERSHIP              = 0xc
 	IP_ADD_SOURCE_MEMBERSHIP       = 0x46
 	IP_BINDANY                     = 0x18
@@ -989,8 +992,12 @@
 	IP_TOS                         = 0x3
 	IP_TTL                         = 0x4
 	IP_UNBLOCK_SOURCE              = 0x49
+	IP_VLAN_PCP                    = 0x4b
 	ISIG                           = 0x80
 	ISTRIP                         = 0x20
+	ITIMER_PROF                    = 0x2
+	ITIMER_REAL                    = 0x0
+	ITIMER_VIRTUAL                 = 0x1
 	IXANY                          = 0x800
 	IXOFF                          = 0x400
 	IXON                           = 0x200
@@ -1000,7 +1007,6 @@
 	KERN_VERSION                   = 0x4
 	LOCAL_CONNWAIT                 = 0x4
 	LOCAL_CREDS                    = 0x2
-	LOCAL_CREDS_PERSISTENT         = 0x3
 	LOCAL_PEERCRED                 = 0x1
 	LOCAL_VENDOR                   = 0x80000000
 	LOCK_EX                        = 0x2
@@ -1180,6 +1186,8 @@
 	O_NONBLOCK                     = 0x4
 	O_RDONLY                       = 0x0
 	O_RDWR                         = 0x2
+	O_RESOLVE_BENEATH              = 0x800000
+	O_SEARCH                       = 0x40000
 	O_SHLOCK                       = 0x10
 	O_SYNC                         = 0x80
 	O_TRUNC                        = 0x400
@@ -1190,6 +1198,10 @@
 	PARMRK                         = 0x8
 	PARODD                         = 0x2000
 	PENDIN                         = 0x20000000
+	PIOD_READ_D                    = 0x1
+	PIOD_READ_I                    = 0x3
+	PIOD_WRITE_D                   = 0x2
+	PIOD_WRITE_I                   = 0x4
 	PRIO_PGRP                      = 0x1
 	PRIO_PROCESS                   = 0x0
 	PRIO_USER                      = 0x2
@@ -1197,6 +1209,51 @@
 	PROT_NONE                      = 0x0
 	PROT_READ                      = 0x1
 	PROT_WRITE                     = 0x2
+	PTRACE_DEFAULT                 = 0x1
+	PTRACE_EXEC                    = 0x1
+	PTRACE_FORK                    = 0x8
+	PTRACE_LWP                     = 0x10
+	PTRACE_SCE                     = 0x2
+	PTRACE_SCX                     = 0x4
+	PTRACE_SYSCALL                 = 0x6
+	PTRACE_VFORK                   = 0x20
+	PT_ATTACH                      = 0xa
+	PT_CLEARSTEP                   = 0x10
+	PT_CONTINUE                    = 0x7
+	PT_DETACH                      = 0xb
+	PT_FIRSTMACH                   = 0x40
+	PT_FOLLOW_FORK                 = 0x17
+	PT_GETDBREGS                   = 0x25
+	PT_GETFPREGS                   = 0x23
+	PT_GETLWPLIST                  = 0xf
+	PT_GETNUMLWPS                  = 0xe
+	PT_GETREGS                     = 0x21
+	PT_GET_EVENT_MASK              = 0x19
+	PT_GET_SC_ARGS                 = 0x1b
+	PT_GET_SC_RET                  = 0x1c
+	PT_IO                          = 0xc
+	PT_KILL                        = 0x8
+	PT_LWPINFO                     = 0xd
+	PT_LWP_EVENTS                  = 0x18
+	PT_READ_D                      = 0x2
+	PT_READ_I                      = 0x1
+	PT_RESUME                      = 0x13
+	PT_SETDBREGS                   = 0x26
+	PT_SETFPREGS                   = 0x24
+	PT_SETREGS                     = 0x22
+	PT_SETSTEP                     = 0x11
+	PT_SET_EVENT_MASK              = 0x1a
+	PT_STEP                        = 0x9
+	PT_SUSPEND                     = 0x12
+	PT_SYSCALL                     = 0x16
+	PT_TO_SCE                      = 0x14
+	PT_TO_SCX                      = 0x15
+	PT_TRACE_ME                    = 0x0
+	PT_VM_ENTRY                    = 0x29
+	PT_VM_TIMESTAMP                = 0x28
+	PT_WRITE_D                     = 0x5
+	PT_WRITE_I                     = 0x4
+	P_ZONEID                       = 0xc
 	RLIMIT_AS                      = 0xa
 	RLIMIT_CORE                    = 0x4
 	RLIMIT_CPU                     = 0x0
@@ -1321,10 +1378,12 @@
 	SIOCGHWADDR                    = 0xc020693e
 	SIOCGI2C                       = 0xc020693d
 	SIOCGIFADDR                    = 0xc0206921
+	SIOCGIFALIAS                   = 0xc044692d
 	SIOCGIFBRDADDR                 = 0xc0206923
 	SIOCGIFCAP                     = 0xc020691f
 	SIOCGIFCONF                    = 0xc0106924
 	SIOCGIFDESCR                   = 0xc020692a
+	SIOCGIFDOWNREASON              = 0xc058699a
 	SIOCGIFDSTADDR                 = 0xc0206922
 	SIOCGIFFIB                     = 0xc020695c
 	SIOCGIFFLAGS                   = 0xc0206911
@@ -1415,6 +1474,7 @@
 	SO_RCVBUF                      = 0x1002
 	SO_RCVLOWAT                    = 0x1004
 	SO_RCVTIMEO                    = 0x1006
+	SO_RERROR                      = 0x20000
 	SO_REUSEADDR                   = 0x4
 	SO_REUSEPORT                   = 0x200
 	SO_REUSEPORT_LB                = 0x10000
@@ -1473,22 +1533,40 @@
 	TCOFLUSH                       = 0x2
 	TCOOFF                         = 0x1
 	TCOON                          = 0x2
+	TCPOPT_EOL                     = 0x0
+	TCPOPT_FAST_OPEN               = 0x22
+	TCPOPT_MAXSEG                  = 0x2
+	TCPOPT_NOP                     = 0x1
+	TCPOPT_PAD                     = 0x0
+	TCPOPT_SACK                    = 0x5
+	TCPOPT_SACK_PERMITTED          = 0x4
+	TCPOPT_SIGNATURE               = 0x13
+	TCPOPT_TIMESTAMP               = 0x8
+	TCPOPT_WINDOW                  = 0x3
 	TCP_BBR_ACK_COMP_ALG           = 0x448
+	TCP_BBR_ALGORITHM              = 0x43b
 	TCP_BBR_DRAIN_INC_EXTRA        = 0x43c
 	TCP_BBR_DRAIN_PG               = 0x42e
 	TCP_BBR_EXTRA_GAIN             = 0x449
+	TCP_BBR_EXTRA_STATE            = 0x453
+	TCP_BBR_FLOOR_MIN_TSO          = 0x454
+	TCP_BBR_HDWR_PACE              = 0x451
+	TCP_BBR_HOLD_TARGET            = 0x436
 	TCP_BBR_IWINTSO                = 0x42b
 	TCP_BBR_LOWGAIN_FD             = 0x436
 	TCP_BBR_LOWGAIN_HALF           = 0x435
 	TCP_BBR_LOWGAIN_THRESH         = 0x434
 	TCP_BBR_MAX_RTO                = 0x439
 	TCP_BBR_MIN_RTO                = 0x438
+	TCP_BBR_MIN_TOPACEOUT          = 0x455
 	TCP_BBR_ONE_RETRAN             = 0x431
 	TCP_BBR_PACE_CROSS             = 0x442
 	TCP_BBR_PACE_DEL_TAR           = 0x43f
+	TCP_BBR_PACE_OH                = 0x435
 	TCP_BBR_PACE_PER_SEC           = 0x43e
 	TCP_BBR_PACE_SEG_MAX           = 0x440
 	TCP_BBR_PACE_SEG_MIN           = 0x441
+	TCP_BBR_POLICER_DETECT         = 0x457
 	TCP_BBR_PROBE_RTT_GAIN         = 0x44d
 	TCP_BBR_PROBE_RTT_INT          = 0x430
 	TCP_BBR_PROBE_RTT_LEN          = 0x44e
@@ -1497,12 +1575,18 @@
 	TCP_BBR_REC_OVER_HPTS          = 0x43a
 	TCP_BBR_RETRAN_WTSO            = 0x44b
 	TCP_BBR_RWND_IS_APP            = 0x42f
+	TCP_BBR_SEND_IWND_IN_TSO       = 0x44f
 	TCP_BBR_STARTUP_EXIT_EPOCH     = 0x43d
 	TCP_BBR_STARTUP_LOSS_EXIT      = 0x432
 	TCP_BBR_STARTUP_PG             = 0x42d
+	TCP_BBR_TMR_PACE_OH            = 0x448
+	TCP_BBR_TSLIMITS               = 0x434
+	TCP_BBR_TSTMP_RAISES           = 0x456
 	TCP_BBR_UNLIMITED              = 0x43b
 	TCP_BBR_USEDEL_RATE            = 0x437
 	TCP_BBR_USE_LOWGAIN            = 0x433
+	TCP_BBR_USE_RACK_CHEAT         = 0x450
+	TCP_BBR_UTTER_MAX_TSO          = 0x452
 	TCP_CA_NAME_MAX                = 0x10
 	TCP_CCALGOOPT                  = 0x41
 	TCP_CONGESTION                 = 0x40
@@ -1542,6 +1626,7 @@
 	TCP_PCAP_OUT                   = 0x800
 	TCP_RACK_EARLY_RECOV           = 0x423
 	TCP_RACK_EARLY_SEG             = 0x424
+	TCP_RACK_GP_INCREASE           = 0x446
 	TCP_RACK_IDLE_REDUCE_HIGH      = 0x444
 	TCP_RACK_MIN_PACE              = 0x445
 	TCP_RACK_MIN_PACE_SEG          = 0x446
@@ -1555,7 +1640,6 @@
 	TCP_RACK_PRR_SENDALOT          = 0x421
 	TCP_RACK_REORD_FADE            = 0x426
 	TCP_RACK_REORD_THRESH          = 0x425
-	TCP_RACK_SESS_CWV              = 0x42a
 	TCP_RACK_TLP_INC_VAR           = 0x429
 	TCP_RACK_TLP_REDUCE            = 0x41c
 	TCP_RACK_TLP_THRESH            = 0x427
@@ -1694,12 +1778,13 @@
 	EIDRM           = syscall.Errno(0x52)
 	EILSEQ          = syscall.Errno(0x56)
 	EINPROGRESS     = syscall.Errno(0x24)
+	EINTEGRITY      = syscall.Errno(0x61)
 	EINTR           = syscall.Errno(0x4)
 	EINVAL          = syscall.Errno(0x16)
 	EIO             = syscall.Errno(0x5)
 	EISCONN         = syscall.Errno(0x38)
 	EISDIR          = syscall.Errno(0x15)
-	ELAST           = syscall.Errno(0x60)
+	ELAST           = syscall.Errno(0x61)
 	ELOOP           = syscall.Errno(0x3e)
 	EMFILE          = syscall.Errno(0x18)
 	EMLINK          = syscall.Errno(0x1f)
@@ -1842,7 +1927,7 @@
 	{32, "EPIPE", "broken pipe"},
 	{33, "EDOM", "numerical argument out of domain"},
 	{34, "ERANGE", "result too large"},
-	{35, "EAGAIN", "resource temporarily unavailable"},
+	{35, "EWOULDBLOCK", "resource temporarily unavailable"},
 	{36, "EINPROGRESS", "operation now in progress"},
 	{37, "EALREADY", "operation already in progress"},
 	{38, "ENOTSOCK", "socket operation on non-socket"},
@@ -1904,6 +1989,7 @@
 	{94, "ECAPMODE", "not permitted in capability mode"},
 	{95, "ENOTRECOVERABLE", "state not recoverable"},
 	{96, "EOWNERDEAD", "previous owner died"},
+	{97, "EINTEGRITY", "integrity check failed"},
 }
 
 // Signal table
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_riscv64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_riscv64.go
new file mode 100644
index 0000000..341b4d9
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_freebsd_riscv64.go
@@ -0,0 +1,2148 @@
+// mkerrors.sh -m64
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+//go:build riscv64 && freebsd
+// +build riscv64,freebsd
+
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs -- -m64 _const.go
+
+package unix
+
+import "syscall"
+
+const (
+	AF_APPLETALK                   = 0x10
+	AF_ARP                         = 0x23
+	AF_ATM                         = 0x1e
+	AF_BLUETOOTH                   = 0x24
+	AF_CCITT                       = 0xa
+	AF_CHAOS                       = 0x5
+	AF_CNT                         = 0x15
+	AF_COIP                        = 0x14
+	AF_DATAKIT                     = 0x9
+	AF_DECnet                      = 0xc
+	AF_DLI                         = 0xd
+	AF_E164                        = 0x1a
+	AF_ECMA                        = 0x8
+	AF_HYLINK                      = 0xf
+	AF_HYPERV                      = 0x2b
+	AF_IEEE80211                   = 0x25
+	AF_IMPLINK                     = 0x3
+	AF_INET                        = 0x2
+	AF_INET6                       = 0x1c
+	AF_INET6_SDP                   = 0x2a
+	AF_INET_SDP                    = 0x28
+	AF_IPX                         = 0x17
+	AF_ISDN                        = 0x1a
+	AF_ISO                         = 0x7
+	AF_LAT                         = 0xe
+	AF_LINK                        = 0x12
+	AF_LOCAL                       = 0x1
+	AF_MAX                         = 0x2b
+	AF_NATM                        = 0x1d
+	AF_NETBIOS                     = 0x6
+	AF_NETGRAPH                    = 0x20
+	AF_OSI                         = 0x7
+	AF_PUP                         = 0x4
+	AF_ROUTE                       = 0x11
+	AF_SCLUSTER                    = 0x22
+	AF_SIP                         = 0x18
+	AF_SLOW                        = 0x21
+	AF_SNA                         = 0xb
+	AF_UNIX                        = 0x1
+	AF_UNSPEC                      = 0x0
+	AF_VENDOR00                    = 0x27
+	AF_VENDOR01                    = 0x29
+	AF_VENDOR03                    = 0x2d
+	AF_VENDOR04                    = 0x2f
+	AF_VENDOR05                    = 0x31
+	AF_VENDOR06                    = 0x33
+	AF_VENDOR07                    = 0x35
+	AF_VENDOR08                    = 0x37
+	AF_VENDOR09                    = 0x39
+	AF_VENDOR10                    = 0x3b
+	AF_VENDOR11                    = 0x3d
+	AF_VENDOR12                    = 0x3f
+	AF_VENDOR13                    = 0x41
+	AF_VENDOR14                    = 0x43
+	AF_VENDOR15                    = 0x45
+	AF_VENDOR16                    = 0x47
+	AF_VENDOR17                    = 0x49
+	AF_VENDOR18                    = 0x4b
+	AF_VENDOR19                    = 0x4d
+	AF_VENDOR20                    = 0x4f
+	AF_VENDOR21                    = 0x51
+	AF_VENDOR22                    = 0x53
+	AF_VENDOR23                    = 0x55
+	AF_VENDOR24                    = 0x57
+	AF_VENDOR25                    = 0x59
+	AF_VENDOR26                    = 0x5b
+	AF_VENDOR27                    = 0x5d
+	AF_VENDOR28                    = 0x5f
+	AF_VENDOR29                    = 0x61
+	AF_VENDOR30                    = 0x63
+	AF_VENDOR31                    = 0x65
+	AF_VENDOR32                    = 0x67
+	AF_VENDOR33                    = 0x69
+	AF_VENDOR34                    = 0x6b
+	AF_VENDOR35                    = 0x6d
+	AF_VENDOR36                    = 0x6f
+	AF_VENDOR37                    = 0x71
+	AF_VENDOR38                    = 0x73
+	AF_VENDOR39                    = 0x75
+	AF_VENDOR40                    = 0x77
+	AF_VENDOR41                    = 0x79
+	AF_VENDOR42                    = 0x7b
+	AF_VENDOR43                    = 0x7d
+	AF_VENDOR44                    = 0x7f
+	AF_VENDOR45                    = 0x81
+	AF_VENDOR46                    = 0x83
+	AF_VENDOR47                    = 0x85
+	ALTWERASE                      = 0x200
+	B0                             = 0x0
+	B1000000                       = 0xf4240
+	B110                           = 0x6e
+	B115200                        = 0x1c200
+	B1200                          = 0x4b0
+	B134                           = 0x86
+	B14400                         = 0x3840
+	B150                           = 0x96
+	B1500000                       = 0x16e360
+	B1800                          = 0x708
+	B19200                         = 0x4b00
+	B200                           = 0xc8
+	B2000000                       = 0x1e8480
+	B230400                        = 0x38400
+	B2400                          = 0x960
+	B2500000                       = 0x2625a0
+	B28800                         = 0x7080
+	B300                           = 0x12c
+	B3000000                       = 0x2dc6c0
+	B3500000                       = 0x3567e0
+	B38400                         = 0x9600
+	B4000000                       = 0x3d0900
+	B460800                        = 0x70800
+	B4800                          = 0x12c0
+	B50                            = 0x32
+	B500000                        = 0x7a120
+	B57600                         = 0xe100
+	B600                           = 0x258
+	B7200                          = 0x1c20
+	B75                            = 0x4b
+	B76800                         = 0x12c00
+	B921600                        = 0xe1000
+	B9600                          = 0x2580
+	BIOCFEEDBACK                   = 0x8004427c
+	BIOCFLUSH                      = 0x20004268
+	BIOCGBLEN                      = 0x40044266
+	BIOCGDIRECTION                 = 0x40044276
+	BIOCGDLT                       = 0x4004426a
+	BIOCGDLTLIST                   = 0xc0104279
+	BIOCGETBUFMODE                 = 0x4004427d
+	BIOCGETIF                      = 0x4020426b
+	BIOCGETZMAX                    = 0x4008427f
+	BIOCGHDRCMPLT                  = 0x40044274
+	BIOCGRSIG                      = 0x40044272
+	BIOCGRTIMEOUT                  = 0x4010426e
+	BIOCGSEESENT                   = 0x40044276
+	BIOCGSTATS                     = 0x4008426f
+	BIOCGTSTAMP                    = 0x40044283
+	BIOCIMMEDIATE                  = 0x80044270
+	BIOCLOCK                       = 0x2000427a
+	BIOCPROMISC                    = 0x20004269
+	BIOCROTZBUF                    = 0x40184280
+	BIOCSBLEN                      = 0xc0044266
+	BIOCSDIRECTION                 = 0x80044277
+	BIOCSDLT                       = 0x80044278
+	BIOCSETBUFMODE                 = 0x8004427e
+	BIOCSETF                       = 0x80104267
+	BIOCSETFNR                     = 0x80104282
+	BIOCSETIF                      = 0x8020426c
+	BIOCSETVLANPCP                 = 0x80044285
+	BIOCSETWF                      = 0x8010427b
+	BIOCSETZBUF                    = 0x80184281
+	BIOCSHDRCMPLT                  = 0x80044275
+	BIOCSRSIG                      = 0x80044273
+	BIOCSRTIMEOUT                  = 0x8010426d
+	BIOCSSEESENT                   = 0x80044277
+	BIOCSTSTAMP                    = 0x80044284
+	BIOCVERSION                    = 0x40044271
+	BPF_A                          = 0x10
+	BPF_ABS                        = 0x20
+	BPF_ADD                        = 0x0
+	BPF_ALIGNMENT                  = 0x8
+	BPF_ALU                        = 0x4
+	BPF_AND                        = 0x50
+	BPF_B                          = 0x10
+	BPF_BUFMODE_BUFFER             = 0x1
+	BPF_BUFMODE_ZBUF               = 0x2
+	BPF_DIV                        = 0x30
+	BPF_H                          = 0x8
+	BPF_IMM                        = 0x0
+	BPF_IND                        = 0x40
+	BPF_JA                         = 0x0
+	BPF_JEQ                        = 0x10
+	BPF_JGE                        = 0x30
+	BPF_JGT                        = 0x20
+	BPF_JMP                        = 0x5
+	BPF_JSET                       = 0x40
+	BPF_K                          = 0x0
+	BPF_LD                         = 0x0
+	BPF_LDX                        = 0x1
+	BPF_LEN                        = 0x80
+	BPF_LSH                        = 0x60
+	BPF_MAJOR_VERSION              = 0x1
+	BPF_MAXBUFSIZE                 = 0x80000
+	BPF_MAXINSNS                   = 0x200
+	BPF_MEM                        = 0x60
+	BPF_MEMWORDS                   = 0x10
+	BPF_MINBUFSIZE                 = 0x20
+	BPF_MINOR_VERSION              = 0x1
+	BPF_MISC                       = 0x7
+	BPF_MOD                        = 0x90
+	BPF_MSH                        = 0xa0
+	BPF_MUL                        = 0x20
+	BPF_NEG                        = 0x80
+	BPF_OR                         = 0x40
+	BPF_RELEASE                    = 0x30bb6
+	BPF_RET                        = 0x6
+	BPF_RSH                        = 0x70
+	BPF_ST                         = 0x2
+	BPF_STX                        = 0x3
+	BPF_SUB                        = 0x10
+	BPF_TAX                        = 0x0
+	BPF_TXA                        = 0x80
+	BPF_T_BINTIME                  = 0x2
+	BPF_T_BINTIME_FAST             = 0x102
+	BPF_T_BINTIME_MONOTONIC        = 0x202
+	BPF_T_BINTIME_MONOTONIC_FAST   = 0x302
+	BPF_T_FAST                     = 0x100
+	BPF_T_FLAG_MASK                = 0x300
+	BPF_T_FORMAT_MASK              = 0x3
+	BPF_T_MICROTIME                = 0x0
+	BPF_T_MICROTIME_FAST           = 0x100
+	BPF_T_MICROTIME_MONOTONIC      = 0x200
+	BPF_T_MICROTIME_MONOTONIC_FAST = 0x300
+	BPF_T_MONOTONIC                = 0x200
+	BPF_T_MONOTONIC_FAST           = 0x300
+	BPF_T_NANOTIME                 = 0x1
+	BPF_T_NANOTIME_FAST            = 0x101
+	BPF_T_NANOTIME_MONOTONIC       = 0x201
+	BPF_T_NANOTIME_MONOTONIC_FAST  = 0x301
+	BPF_T_NONE                     = 0x3
+	BPF_T_NORMAL                   = 0x0
+	BPF_W                          = 0x0
+	BPF_X                          = 0x8
+	BPF_XOR                        = 0xa0
+	BRKINT                         = 0x2
+	CAP_ACCEPT                     = 0x200000020000000
+	CAP_ACL_CHECK                  = 0x400000000010000
+	CAP_ACL_DELETE                 = 0x400000000020000
+	CAP_ACL_GET                    = 0x400000000040000
+	CAP_ACL_SET                    = 0x400000000080000
+	CAP_ALL0                       = 0x20007ffffffffff
+	CAP_ALL1                       = 0x4000000001fffff
+	CAP_BIND                       = 0x200000040000000
+	CAP_BINDAT                     = 0x200008000000400
+	CAP_CHFLAGSAT                  = 0x200000000001400
+	CAP_CONNECT                    = 0x200000080000000
+	CAP_CONNECTAT                  = 0x200010000000400
+	CAP_CREATE                     = 0x200000000000040
+	CAP_EVENT                      = 0x400000000000020
+	CAP_EXTATTR_DELETE             = 0x400000000001000
+	CAP_EXTATTR_GET                = 0x400000000002000
+	CAP_EXTATTR_LIST               = 0x400000000004000
+	CAP_EXTATTR_SET                = 0x400000000008000
+	CAP_FCHDIR                     = 0x200000000000800
+	CAP_FCHFLAGS                   = 0x200000000001000
+	CAP_FCHMOD                     = 0x200000000002000
+	CAP_FCHMODAT                   = 0x200000000002400
+	CAP_FCHOWN                     = 0x200000000004000
+	CAP_FCHOWNAT                   = 0x200000000004400
+	CAP_FCNTL                      = 0x200000000008000
+	CAP_FCNTL_ALL                  = 0x78
+	CAP_FCNTL_GETFL                = 0x8
+	CAP_FCNTL_GETOWN               = 0x20
+	CAP_FCNTL_SETFL                = 0x10
+	CAP_FCNTL_SETOWN               = 0x40
+	CAP_FEXECVE                    = 0x200000000000080
+	CAP_FLOCK                      = 0x200000000010000
+	CAP_FPATHCONF                  = 0x200000000020000
+	CAP_FSCK                       = 0x200000000040000
+	CAP_FSTAT                      = 0x200000000080000
+	CAP_FSTATAT                    = 0x200000000080400
+	CAP_FSTATFS                    = 0x200000000100000
+	CAP_FSYNC                      = 0x200000000000100
+	CAP_FTRUNCATE                  = 0x200000000000200
+	CAP_FUTIMES                    = 0x200000000200000
+	CAP_FUTIMESAT                  = 0x200000000200400
+	CAP_GETPEERNAME                = 0x200000100000000
+	CAP_GETSOCKNAME                = 0x200000200000000
+	CAP_GETSOCKOPT                 = 0x200000400000000
+	CAP_IOCTL                      = 0x400000000000080
+	CAP_IOCTLS_ALL                 = 0x7fffffffffffffff
+	CAP_KQUEUE                     = 0x400000000100040
+	CAP_KQUEUE_CHANGE              = 0x400000000100000
+	CAP_KQUEUE_EVENT               = 0x400000000000040
+	CAP_LINKAT_SOURCE              = 0x200020000000400
+	CAP_LINKAT_TARGET              = 0x200000000400400
+	CAP_LISTEN                     = 0x200000800000000
+	CAP_LOOKUP                     = 0x200000000000400
+	CAP_MAC_GET                    = 0x400000000000001
+	CAP_MAC_SET                    = 0x400000000000002
+	CAP_MKDIRAT                    = 0x200000000800400
+	CAP_MKFIFOAT                   = 0x200000001000400
+	CAP_MKNODAT                    = 0x200000002000400
+	CAP_MMAP                       = 0x200000000000010
+	CAP_MMAP_R                     = 0x20000000000001d
+	CAP_MMAP_RW                    = 0x20000000000001f
+	CAP_MMAP_RWX                   = 0x20000000000003f
+	CAP_MMAP_RX                    = 0x20000000000003d
+	CAP_MMAP_W                     = 0x20000000000001e
+	CAP_MMAP_WX                    = 0x20000000000003e
+	CAP_MMAP_X                     = 0x20000000000003c
+	CAP_PDGETPID                   = 0x400000000000200
+	CAP_PDKILL                     = 0x400000000000800
+	CAP_PDWAIT                     = 0x400000000000400
+	CAP_PEELOFF                    = 0x200001000000000
+	CAP_POLL_EVENT                 = 0x400000000000020
+	CAP_PREAD                      = 0x20000000000000d
+	CAP_PWRITE                     = 0x20000000000000e
+	CAP_READ                       = 0x200000000000001
+	CAP_RECV                       = 0x200000000000001
+	CAP_RENAMEAT_SOURCE            = 0x200000004000400
+	CAP_RENAMEAT_TARGET            = 0x200040000000400
+	CAP_RIGHTS_VERSION             = 0x0
+	CAP_RIGHTS_VERSION_00          = 0x0
+	CAP_SEEK                       = 0x20000000000000c
+	CAP_SEEK_TELL                  = 0x200000000000004
+	CAP_SEM_GETVALUE               = 0x400000000000004
+	CAP_SEM_POST                   = 0x400000000000008
+	CAP_SEM_WAIT                   = 0x400000000000010
+	CAP_SEND                       = 0x200000000000002
+	CAP_SETSOCKOPT                 = 0x200002000000000
+	CAP_SHUTDOWN                   = 0x200004000000000
+	CAP_SOCK_CLIENT                = 0x200007780000003
+	CAP_SOCK_SERVER                = 0x200007f60000003
+	CAP_SYMLINKAT                  = 0x200000008000400
+	CAP_TTYHOOK                    = 0x400000000000100
+	CAP_UNLINKAT                   = 0x200000010000400
+	CAP_UNUSED0_44                 = 0x200080000000000
+	CAP_UNUSED0_57                 = 0x300000000000000
+	CAP_UNUSED1_22                 = 0x400000000200000
+	CAP_UNUSED1_57                 = 0x500000000000000
+	CAP_WRITE                      = 0x200000000000002
+	CFLUSH                         = 0xf
+	CLOCAL                         = 0x8000
+	CLOCK_BOOTTIME                 = 0x5
+	CLOCK_MONOTONIC                = 0x4
+	CLOCK_MONOTONIC_COARSE         = 0xc
+	CLOCK_MONOTONIC_FAST           = 0xc
+	CLOCK_MONOTONIC_PRECISE        = 0xb
+	CLOCK_PROCESS_CPUTIME_ID       = 0xf
+	CLOCK_PROF                     = 0x2
+	CLOCK_REALTIME                 = 0x0
+	CLOCK_REALTIME_COARSE          = 0xa
+	CLOCK_REALTIME_FAST            = 0xa
+	CLOCK_REALTIME_PRECISE         = 0x9
+	CLOCK_SECOND                   = 0xd
+	CLOCK_THREAD_CPUTIME_ID        = 0xe
+	CLOCK_UPTIME                   = 0x5
+	CLOCK_UPTIME_FAST              = 0x8
+	CLOCK_UPTIME_PRECISE           = 0x7
+	CLOCK_VIRTUAL                  = 0x1
+	CPUSTATES                      = 0x5
+	CP_IDLE                        = 0x4
+	CP_INTR                        = 0x3
+	CP_NICE                        = 0x1
+	CP_SYS                         = 0x2
+	CP_USER                        = 0x0
+	CREAD                          = 0x800
+	CRTSCTS                        = 0x30000
+	CS5                            = 0x0
+	CS6                            = 0x100
+	CS7                            = 0x200
+	CS8                            = 0x300
+	CSIZE                          = 0x300
+	CSTART                         = 0x11
+	CSTATUS                        = 0x14
+	CSTOP                          = 0x13
+	CSTOPB                         = 0x400
+	CSUSP                          = 0x1a
+	CTL_HW                         = 0x6
+	CTL_KERN                       = 0x1
+	CTL_MAXNAME                    = 0x18
+	CTL_NET                        = 0x4
+	DIOCGATTR                      = 0xc148648e
+	DIOCGDELETE                    = 0x80106488
+	DIOCGFLUSH                     = 0x20006487
+	DIOCGFWHEADS                   = 0x40046483
+	DIOCGFWSECTORS                 = 0x40046482
+	DIOCGIDENT                     = 0x41006489
+	DIOCGKERNELDUMP                = 0xc0986492
+	DIOCGMEDIASIZE                 = 0x40086481
+	DIOCGPHYSPATH                  = 0x4400648d
+	DIOCGPROVIDERNAME              = 0x4400648a
+	DIOCGSECTORSIZE                = 0x40046480
+	DIOCGSTRIPEOFFSET              = 0x4008648c
+	DIOCGSTRIPESIZE                = 0x4008648b
+	DIOCSKERNELDUMP                = 0x80986491
+	DIOCSKERNELDUMP_FREEBSD11      = 0x80046485
+	DIOCSKERNELDUMP_FREEBSD12      = 0x80506490
+	DIOCZONECMD                    = 0xc080648f
+	DLT_A429                       = 0xb8
+	DLT_A653_ICM                   = 0xb9
+	DLT_AIRONET_HEADER             = 0x78
+	DLT_AOS                        = 0xde
+	DLT_APPLE_IP_OVER_IEEE1394     = 0x8a
+	DLT_ARCNET                     = 0x7
+	DLT_ARCNET_LINUX               = 0x81
+	DLT_ATM_CLIP                   = 0x13
+	DLT_ATM_RFC1483                = 0xb
+	DLT_AURORA                     = 0x7e
+	DLT_AX25                       = 0x3
+	DLT_AX25_KISS                  = 0xca
+	DLT_BACNET_MS_TP               = 0xa5
+	DLT_BLUETOOTH_BREDR_BB         = 0xff
+	DLT_BLUETOOTH_HCI_H4           = 0xbb
+	DLT_BLUETOOTH_HCI_H4_WITH_PHDR = 0xc9
+	DLT_BLUETOOTH_LE_LL            = 0xfb
+	DLT_BLUETOOTH_LE_LL_WITH_PHDR  = 0x100
+	DLT_BLUETOOTH_LINUX_MONITOR    = 0xfe
+	DLT_CAN20B                     = 0xbe
+	DLT_CAN_SOCKETCAN              = 0xe3
+	DLT_CHAOS                      = 0x5
+	DLT_CHDLC                      = 0x68
+	DLT_CISCO_IOS                  = 0x76
+	DLT_CLASS_NETBSD_RAWAF         = 0x2240000
+	DLT_C_HDLC                     = 0x68
+	DLT_C_HDLC_WITH_DIR            = 0xcd
+	DLT_DBUS                       = 0xe7
+	DLT_DECT                       = 0xdd
+	DLT_DISPLAYPORT_AUX            = 0x113
+	DLT_DOCSIS                     = 0x8f
+	DLT_DOCSIS31_XRA31             = 0x111
+	DLT_DVB_CI                     = 0xeb
+	DLT_ECONET                     = 0x73
+	DLT_EN10MB                     = 0x1
+	DLT_EN3MB                      = 0x2
+	DLT_ENC                        = 0x6d
+	DLT_EPON                       = 0x103
+	DLT_ERF                        = 0xc5
+	DLT_ERF_ETH                    = 0xaf
+	DLT_ERF_POS                    = 0xb0
+	DLT_ETHERNET_MPACKET           = 0x112
+	DLT_FC_2                       = 0xe0
+	DLT_FC_2_WITH_FRAME_DELIMS     = 0xe1
+	DLT_FDDI                       = 0xa
+	DLT_FLEXRAY                    = 0xd2
+	DLT_FRELAY                     = 0x6b
+	DLT_FRELAY_WITH_DIR            = 0xce
+	DLT_GCOM_SERIAL                = 0xad
+	DLT_GCOM_T1E1                  = 0xac
+	DLT_GPF_F                      = 0xab
+	DLT_GPF_T                      = 0xaa
+	DLT_GPRS_LLC                   = 0xa9
+	DLT_GSMTAP_ABIS                = 0xda
+	DLT_GSMTAP_UM                  = 0xd9
+	DLT_IBM_SN                     = 0x92
+	DLT_IBM_SP                     = 0x91
+	DLT_IEEE802                    = 0x6
+	DLT_IEEE802_11                 = 0x69
+	DLT_IEEE802_11_RADIO           = 0x7f
+	DLT_IEEE802_11_RADIO_AVS       = 0xa3
+	DLT_IEEE802_15_4               = 0xc3
+	DLT_IEEE802_15_4_LINUX         = 0xbf
+	DLT_IEEE802_15_4_NOFCS         = 0xe6
+	DLT_IEEE802_15_4_NONASK_PHY    = 0xd7
+	DLT_IEEE802_16_MAC_CPS         = 0xbc
+	DLT_IEEE802_16_MAC_CPS_RADIO   = 0xc1
+	DLT_INFINIBAND                 = 0xf7
+	DLT_IPFILTER                   = 0x74
+	DLT_IPMB_KONTRON               = 0xc7
+	DLT_IPMB_LINUX                 = 0xd1
+	DLT_IPMI_HPM_2                 = 0x104
+	DLT_IPNET                      = 0xe2
+	DLT_IPOIB                      = 0xf2
+	DLT_IPV4                       = 0xe4
+	DLT_IPV6                       = 0xe5
+	DLT_IP_OVER_FC                 = 0x7a
+	DLT_ISO_14443                  = 0x108
+	DLT_JUNIPER_ATM1               = 0x89
+	DLT_JUNIPER_ATM2               = 0x87
+	DLT_JUNIPER_ATM_CEMIC          = 0xee
+	DLT_JUNIPER_CHDLC              = 0xb5
+	DLT_JUNIPER_ES                 = 0x84
+	DLT_JUNIPER_ETHER              = 0xb2
+	DLT_JUNIPER_FIBRECHANNEL       = 0xea
+	DLT_JUNIPER_FRELAY             = 0xb4
+	DLT_JUNIPER_GGSN               = 0x85
+	DLT_JUNIPER_ISM                = 0xc2
+	DLT_JUNIPER_MFR                = 0x86
+	DLT_JUNIPER_MLFR               = 0x83
+	DLT_JUNIPER_MLPPP              = 0x82
+	DLT_JUNIPER_MONITOR            = 0xa4
+	DLT_JUNIPER_PIC_PEER           = 0xae
+	DLT_JUNIPER_PPP                = 0xb3
+	DLT_JUNIPER_PPPOE              = 0xa7
+	DLT_JUNIPER_PPPOE_ATM          = 0xa8
+	DLT_JUNIPER_SERVICES           = 0x88
+	DLT_JUNIPER_SRX_E2E            = 0xe9
+	DLT_JUNIPER_ST                 = 0xc8
+	DLT_JUNIPER_VP                 = 0xb7
+	DLT_JUNIPER_VS                 = 0xe8
+	DLT_LAPB_WITH_DIR              = 0xcf
+	DLT_LAPD                       = 0xcb
+	DLT_LIN                        = 0xd4
+	DLT_LINUX_EVDEV                = 0xd8
+	DLT_LINUX_IRDA                 = 0x90
+	DLT_LINUX_LAPD                 = 0xb1
+	DLT_LINUX_PPP_WITHDIRECTION    = 0xa6
+	DLT_LINUX_SLL                  = 0x71
+	DLT_LINUX_SLL2                 = 0x114
+	DLT_LOOP                       = 0x6c
+	DLT_LORATAP                    = 0x10e
+	DLT_LTALK                      = 0x72
+	DLT_MATCHING_MAX               = 0x114
+	DLT_MATCHING_MIN               = 0x68
+	DLT_MFR                        = 0xb6
+	DLT_MOST                       = 0xd3
+	DLT_MPEG_2_TS                  = 0xf3
+	DLT_MPLS                       = 0xdb
+	DLT_MTP2                       = 0x8c
+	DLT_MTP2_WITH_PHDR             = 0x8b
+	DLT_MTP3                       = 0x8d
+	DLT_MUX27010                   = 0xec
+	DLT_NETANALYZER                = 0xf0
+	DLT_NETANALYZER_TRANSPARENT    = 0xf1
+	DLT_NETLINK                    = 0xfd
+	DLT_NFC_LLCP                   = 0xf5
+	DLT_NFLOG                      = 0xef
+	DLT_NG40                       = 0xf4
+	DLT_NORDIC_BLE                 = 0x110
+	DLT_NULL                       = 0x0
+	DLT_OPENFLOW                   = 0x10b
+	DLT_PCI_EXP                    = 0x7d
+	DLT_PFLOG                      = 0x75
+	DLT_PFSYNC                     = 0x79
+	DLT_PKTAP                      = 0x102
+	DLT_PPI                        = 0xc0
+	DLT_PPP                        = 0x9
+	DLT_PPP_BSDOS                  = 0xe
+	DLT_PPP_ETHER                  = 0x33
+	DLT_PPP_PPPD                   = 0xa6
+	DLT_PPP_SERIAL                 = 0x32
+	DLT_PPP_WITH_DIR               = 0xcc
+	DLT_PPP_WITH_DIRECTION         = 0xa6
+	DLT_PRISM_HEADER               = 0x77
+	DLT_PROFIBUS_DL                = 0x101
+	DLT_PRONET                     = 0x4
+	DLT_RAIF1                      = 0xc6
+	DLT_RAW                        = 0xc
+	DLT_RDS                        = 0x109
+	DLT_REDBACK_SMARTEDGE          = 0x20
+	DLT_RIO                        = 0x7c
+	DLT_RTAC_SERIAL                = 0xfa
+	DLT_SCCP                       = 0x8e
+	DLT_SCTP                       = 0xf8
+	DLT_SDLC                       = 0x10c
+	DLT_SITA                       = 0xc4
+	DLT_SLIP                       = 0x8
+	DLT_SLIP_BSDOS                 = 0xd
+	DLT_STANAG_5066_D_PDU          = 0xed
+	DLT_SUNATM                     = 0x7b
+	DLT_SYMANTEC_FIREWALL          = 0x63
+	DLT_TI_LLN_SNIFFER             = 0x10d
+	DLT_TZSP                       = 0x80
+	DLT_USB                        = 0xba
+	DLT_USBPCAP                    = 0xf9
+	DLT_USB_DARWIN                 = 0x10a
+	DLT_USB_FREEBSD                = 0xba
+	DLT_USB_LINUX                  = 0xbd
+	DLT_USB_LINUX_MMAPPED          = 0xdc
+	DLT_USER0                      = 0x93
+	DLT_USER1                      = 0x94
+	DLT_USER10                     = 0x9d
+	DLT_USER11                     = 0x9e
+	DLT_USER12                     = 0x9f
+	DLT_USER13                     = 0xa0
+	DLT_USER14                     = 0xa1
+	DLT_USER15                     = 0xa2
+	DLT_USER2                      = 0x95
+	DLT_USER3                      = 0x96
+	DLT_USER4                      = 0x97
+	DLT_USER5                      = 0x98
+	DLT_USER6                      = 0x99
+	DLT_USER7                      = 0x9a
+	DLT_USER8                      = 0x9b
+	DLT_USER9                      = 0x9c
+	DLT_VSOCK                      = 0x10f
+	DLT_WATTSTOPPER_DLM            = 0x107
+	DLT_WIHART                     = 0xdf
+	DLT_WIRESHARK_UPPER_PDU        = 0xfc
+	DLT_X2E_SERIAL                 = 0xd5
+	DLT_X2E_XORAYA                 = 0xd6
+	DLT_ZWAVE_R1_R2                = 0x105
+	DLT_ZWAVE_R3                   = 0x106
+	DT_BLK                         = 0x6
+	DT_CHR                         = 0x2
+	DT_DIR                         = 0x4
+	DT_FIFO                        = 0x1
+	DT_LNK                         = 0xa
+	DT_REG                         = 0x8
+	DT_SOCK                        = 0xc
+	DT_UNKNOWN                     = 0x0
+	DT_WHT                         = 0xe
+	ECHO                           = 0x8
+	ECHOCTL                        = 0x40
+	ECHOE                          = 0x2
+	ECHOK                          = 0x4
+	ECHOKE                         = 0x1
+	ECHONL                         = 0x10
+	ECHOPRT                        = 0x20
+	EHE_DEAD_PRIORITY              = -0x1
+	EVFILT_AIO                     = -0x3
+	EVFILT_EMPTY                   = -0xd
+	EVFILT_FS                      = -0x9
+	EVFILT_LIO                     = -0xa
+	EVFILT_PROC                    = -0x5
+	EVFILT_PROCDESC                = -0x8
+	EVFILT_READ                    = -0x1
+	EVFILT_SENDFILE                = -0xc
+	EVFILT_SIGNAL                  = -0x6
+	EVFILT_SYSCOUNT                = 0xd
+	EVFILT_TIMER                   = -0x7
+	EVFILT_USER                    = -0xb
+	EVFILT_VNODE                   = -0x4
+	EVFILT_WRITE                   = -0x2
+	EVNAMEMAP_NAME_SIZE            = 0x40
+	EV_ADD                         = 0x1
+	EV_CLEAR                       = 0x20
+	EV_DELETE                      = 0x2
+	EV_DISABLE                     = 0x8
+	EV_DISPATCH                    = 0x80
+	EV_DROP                        = 0x1000
+	EV_ENABLE                      = 0x4
+	EV_EOF                         = 0x8000
+	EV_ERROR                       = 0x4000
+	EV_FLAG1                       = 0x2000
+	EV_FLAG2                       = 0x4000
+	EV_FORCEONESHOT                = 0x100
+	EV_ONESHOT                     = 0x10
+	EV_RECEIPT                     = 0x40
+	EV_SYSFLAGS                    = 0xf000
+	EXTA                           = 0x4b00
+	EXTATTR_MAXNAMELEN             = 0xff
+	EXTATTR_NAMESPACE_EMPTY        = 0x0
+	EXTATTR_NAMESPACE_SYSTEM       = 0x2
+	EXTATTR_NAMESPACE_USER         = 0x1
+	EXTB                           = 0x9600
+	EXTPROC                        = 0x800
+	FD_CLOEXEC                     = 0x1
+	FD_NONE                        = -0xc8
+	FD_SETSIZE                     = 0x400
+	FLUSHO                         = 0x800000
+	F_ADD_SEALS                    = 0x13
+	F_CANCEL                       = 0x5
+	F_DUP2FD                       = 0xa
+	F_DUP2FD_CLOEXEC               = 0x12
+	F_DUPFD                        = 0x0
+	F_DUPFD_CLOEXEC                = 0x11
+	F_GETFD                        = 0x1
+	F_GETFL                        = 0x3
+	F_GETLK                        = 0xb
+	F_GETOWN                       = 0x5
+	F_GET_SEALS                    = 0x14
+	F_ISUNIONSTACK                 = 0x15
+	F_KINFO                        = 0x16
+	F_OGETLK                       = 0x7
+	F_OK                           = 0x0
+	F_OSETLK                       = 0x8
+	F_OSETLKW                      = 0x9
+	F_RDAHEAD                      = 0x10
+	F_RDLCK                        = 0x1
+	F_READAHEAD                    = 0xf
+	F_SEAL_GROW                    = 0x4
+	F_SEAL_SEAL                    = 0x1
+	F_SEAL_SHRINK                  = 0x2
+	F_SEAL_WRITE                   = 0x8
+	F_SETFD                        = 0x2
+	F_SETFL                        = 0x4
+	F_SETLK                        = 0xc
+	F_SETLKW                       = 0xd
+	F_SETLK_REMOTE                 = 0xe
+	F_SETOWN                       = 0x6
+	F_UNLCK                        = 0x2
+	F_UNLCKSYS                     = 0x4
+	F_WRLCK                        = 0x3
+	HUPCL                          = 0x4000
+	HW_MACHINE                     = 0x1
+	ICANON                         = 0x100
+	ICMP6_FILTER                   = 0x12
+	ICRNL                          = 0x100
+	IEXTEN                         = 0x400
+	IFAN_ARRIVAL                   = 0x0
+	IFAN_DEPARTURE                 = 0x1
+	IFCAP_WOL_MAGIC                = 0x2000
+	IFF_ALLMULTI                   = 0x200
+	IFF_ALTPHYS                    = 0x4000
+	IFF_BROADCAST                  = 0x2
+	IFF_CANTCHANGE                 = 0x218f72
+	IFF_CANTCONFIG                 = 0x10000
+	IFF_DEBUG                      = 0x4
+	IFF_DRV_OACTIVE                = 0x400
+	IFF_DRV_RUNNING                = 0x40
+	IFF_DYING                      = 0x200000
+	IFF_KNOWSEPOCH                 = 0x20
+	IFF_LINK0                      = 0x1000
+	IFF_LINK1                      = 0x2000
+	IFF_LINK2                      = 0x4000
+	IFF_LOOPBACK                   = 0x8
+	IFF_MONITOR                    = 0x40000
+	IFF_MULTICAST                  = 0x8000
+	IFF_NOARP                      = 0x80
+	IFF_NOGROUP                    = 0x800000
+	IFF_OACTIVE                    = 0x400
+	IFF_POINTOPOINT                = 0x10
+	IFF_PPROMISC                   = 0x20000
+	IFF_PROMISC                    = 0x100
+	IFF_RENAMING                   = 0x400000
+	IFF_RUNNING                    = 0x40
+	IFF_SIMPLEX                    = 0x800
+	IFF_STATICARP                  = 0x80000
+	IFF_UP                         = 0x1
+	IFNAMSIZ                       = 0x10
+	IFT_BRIDGE                     = 0xd1
+	IFT_CARP                       = 0xf8
+	IFT_IEEE1394                   = 0x90
+	IFT_INFINIBAND                 = 0xc7
+	IFT_L2VLAN                     = 0x87
+	IFT_L3IPVLAN                   = 0x88
+	IFT_PPP                        = 0x17
+	IFT_PROPVIRTUAL                = 0x35
+	IGNBRK                         = 0x1
+	IGNCR                          = 0x80
+	IGNPAR                         = 0x4
+	IMAXBEL                        = 0x2000
+	INLCR                          = 0x40
+	INPCK                          = 0x10
+	IN_CLASSA_HOST                 = 0xffffff
+	IN_CLASSA_MAX                  = 0x80
+	IN_CLASSA_NET                  = 0xff000000
+	IN_CLASSA_NSHIFT               = 0x18
+	IN_CLASSB_HOST                 = 0xffff
+	IN_CLASSB_MAX                  = 0x10000
+	IN_CLASSB_NET                  = 0xffff0000
+	IN_CLASSB_NSHIFT               = 0x10
+	IN_CLASSC_HOST                 = 0xff
+	IN_CLASSC_NET                  = 0xffffff00
+	IN_CLASSC_NSHIFT               = 0x8
+	IN_CLASSD_HOST                 = 0xfffffff
+	IN_CLASSD_NET                  = 0xf0000000
+	IN_CLASSD_NSHIFT               = 0x1c
+	IN_LOOPBACKNET                 = 0x7f
+	IN_NETMASK_DEFAULT             = 0xffffff00
+	IN_RFC3021_MASK                = 0xfffffffe
+	IPPROTO_3PC                    = 0x22
+	IPPROTO_ADFS                   = 0x44
+	IPPROTO_AH                     = 0x33
+	IPPROTO_AHIP                   = 0x3d
+	IPPROTO_APES                   = 0x63
+	IPPROTO_ARGUS                  = 0xd
+	IPPROTO_AX25                   = 0x5d
+	IPPROTO_BHA                    = 0x31
+	IPPROTO_BLT                    = 0x1e
+	IPPROTO_BRSATMON               = 0x4c
+	IPPROTO_CARP                   = 0x70
+	IPPROTO_CFTP                   = 0x3e
+	IPPROTO_CHAOS                  = 0x10
+	IPPROTO_CMTP                   = 0x26
+	IPPROTO_CPHB                   = 0x49
+	IPPROTO_CPNX                   = 0x48
+	IPPROTO_DCCP                   = 0x21
+	IPPROTO_DDP                    = 0x25
+	IPPROTO_DGP                    = 0x56
+	IPPROTO_DIVERT                 = 0x102
+	IPPROTO_DONE                   = 0x101
+	IPPROTO_DSTOPTS                = 0x3c
+	IPPROTO_EGP                    = 0x8
+	IPPROTO_EMCON                  = 0xe
+	IPPROTO_ENCAP                  = 0x62
+	IPPROTO_EON                    = 0x50
+	IPPROTO_ESP                    = 0x32
+	IPPROTO_ETHERIP                = 0x61
+	IPPROTO_FRAGMENT               = 0x2c
+	IPPROTO_GGP                    = 0x3
+	IPPROTO_GMTP                   = 0x64
+	IPPROTO_GRE                    = 0x2f
+	IPPROTO_HELLO                  = 0x3f
+	IPPROTO_HIP                    = 0x8b
+	IPPROTO_HMP                    = 0x14
+	IPPROTO_HOPOPTS                = 0x0
+	IPPROTO_ICMP                   = 0x1
+	IPPROTO_ICMPV6                 = 0x3a
+	IPPROTO_IDP                    = 0x16
+	IPPROTO_IDPR                   = 0x23
+	IPPROTO_IDRP                   = 0x2d
+	IPPROTO_IGMP                   = 0x2
+	IPPROTO_IGP                    = 0x55
+	IPPROTO_IGRP                   = 0x58
+	IPPROTO_IL                     = 0x28
+	IPPROTO_INLSP                  = 0x34
+	IPPROTO_INP                    = 0x20
+	IPPROTO_IP                     = 0x0
+	IPPROTO_IPCOMP                 = 0x6c
+	IPPROTO_IPCV                   = 0x47
+	IPPROTO_IPEIP                  = 0x5e
+	IPPROTO_IPIP                   = 0x4
+	IPPROTO_IPPC                   = 0x43
+	IPPROTO_IPV4                   = 0x4
+	IPPROTO_IPV6                   = 0x29
+	IPPROTO_IRTP                   = 0x1c
+	IPPROTO_KRYPTOLAN              = 0x41
+	IPPROTO_LARP                   = 0x5b
+	IPPROTO_LEAF1                  = 0x19
+	IPPROTO_LEAF2                  = 0x1a
+	IPPROTO_MAX                    = 0x100
+	IPPROTO_MEAS                   = 0x13
+	IPPROTO_MH                     = 0x87
+	IPPROTO_MHRP                   = 0x30
+	IPPROTO_MICP                   = 0x5f
+	IPPROTO_MOBILE                 = 0x37
+	IPPROTO_MPLS                   = 0x89
+	IPPROTO_MTP                    = 0x5c
+	IPPROTO_MUX                    = 0x12
+	IPPROTO_ND                     = 0x4d
+	IPPROTO_NHRP                   = 0x36
+	IPPROTO_NONE                   = 0x3b
+	IPPROTO_NSP                    = 0x1f
+	IPPROTO_NVPII                  = 0xb
+	IPPROTO_OLD_DIVERT             = 0xfe
+	IPPROTO_OSPFIGP                = 0x59
+	IPPROTO_PFSYNC                 = 0xf0
+	IPPROTO_PGM                    = 0x71
+	IPPROTO_PIGP                   = 0x9
+	IPPROTO_PIM                    = 0x67
+	IPPROTO_PRM                    = 0x15
+	IPPROTO_PUP                    = 0xc
+	IPPROTO_PVP                    = 0x4b
+	IPPROTO_RAW                    = 0xff
+	IPPROTO_RCCMON                 = 0xa
+	IPPROTO_RDP                    = 0x1b
+	IPPROTO_RESERVED_253           = 0xfd
+	IPPROTO_RESERVED_254           = 0xfe
+	IPPROTO_ROUTING                = 0x2b
+	IPPROTO_RSVP                   = 0x2e
+	IPPROTO_RVD                    = 0x42
+	IPPROTO_SATEXPAK               = 0x40
+	IPPROTO_SATMON                 = 0x45
+	IPPROTO_SCCSP                  = 0x60
+	IPPROTO_SCTP                   = 0x84
+	IPPROTO_SDRP                   = 0x2a
+	IPPROTO_SEND                   = 0x103
+	IPPROTO_SHIM6                  = 0x8c
+	IPPROTO_SKIP                   = 0x39
+	IPPROTO_SPACER                 = 0x7fff
+	IPPROTO_SRPC                   = 0x5a
+	IPPROTO_ST                     = 0x7
+	IPPROTO_SVMTP                  = 0x52
+	IPPROTO_SWIPE                  = 0x35
+	IPPROTO_TCF                    = 0x57
+	IPPROTO_TCP                    = 0x6
+	IPPROTO_TLSP                   = 0x38
+	IPPROTO_TP                     = 0x1d
+	IPPROTO_TPXX                   = 0x27
+	IPPROTO_TRUNK1                 = 0x17
+	IPPROTO_TRUNK2                 = 0x18
+	IPPROTO_TTP                    = 0x54
+	IPPROTO_UDP                    = 0x11
+	IPPROTO_UDPLITE                = 0x88
+	IPPROTO_VINES                  = 0x53
+	IPPROTO_VISA                   = 0x46
+	IPPROTO_VMTP                   = 0x51
+	IPPROTO_WBEXPAK                = 0x4f
+	IPPROTO_WBMON                  = 0x4e
+	IPPROTO_WSN                    = 0x4a
+	IPPROTO_XNET                   = 0xf
+	IPPROTO_XTP                    = 0x24
+	IPV6_AUTOFLOWLABEL             = 0x3b
+	IPV6_BINDANY                   = 0x40
+	IPV6_BINDMULTI                 = 0x41
+	IPV6_BINDV6ONLY                = 0x1b
+	IPV6_CHECKSUM                  = 0x1a
+	IPV6_DEFAULT_MULTICAST_HOPS    = 0x1
+	IPV6_DEFAULT_MULTICAST_LOOP    = 0x1
+	IPV6_DEFHLIM                   = 0x40
+	IPV6_DONTFRAG                  = 0x3e
+	IPV6_DSTOPTS                   = 0x32
+	IPV6_FLOWID                    = 0x43
+	IPV6_FLOWINFO_MASK             = 0xffffff0f
+	IPV6_FLOWLABEL_LEN             = 0x14
+	IPV6_FLOWLABEL_MASK            = 0xffff0f00
+	IPV6_FLOWTYPE                  = 0x44
+	IPV6_FRAGTTL                   = 0x78
+	IPV6_FW_ADD                    = 0x1e
+	IPV6_FW_DEL                    = 0x1f
+	IPV6_FW_FLUSH                  = 0x20
+	IPV6_FW_GET                    = 0x22
+	IPV6_FW_ZERO                   = 0x21
+	IPV6_HLIMDEC                   = 0x1
+	IPV6_HOPLIMIT                  = 0x2f
+	IPV6_HOPOPTS                   = 0x31
+	IPV6_IPSEC_POLICY              = 0x1c
+	IPV6_JOIN_GROUP                = 0xc
+	IPV6_LEAVE_GROUP               = 0xd
+	IPV6_MAXHLIM                   = 0xff
+	IPV6_MAXOPTHDR                 = 0x800
+	IPV6_MAXPACKET                 = 0xffff
+	IPV6_MAX_GROUP_SRC_FILTER      = 0x200
+	IPV6_MAX_MEMBERSHIPS           = 0xfff
+	IPV6_MAX_SOCK_SRC_FILTER       = 0x80
+	IPV6_MMTU                      = 0x500
+	IPV6_MSFILTER                  = 0x4a
+	IPV6_MULTICAST_HOPS            = 0xa
+	IPV6_MULTICAST_IF              = 0x9
+	IPV6_MULTICAST_LOOP            = 0xb
+	IPV6_NEXTHOP                   = 0x30
+	IPV6_ORIGDSTADDR               = 0x48
+	IPV6_PATHMTU                   = 0x2c
+	IPV6_PKTINFO                   = 0x2e
+	IPV6_PORTRANGE                 = 0xe
+	IPV6_PORTRANGE_DEFAULT         = 0x0
+	IPV6_PORTRANGE_HIGH            = 0x1
+	IPV6_PORTRANGE_LOW             = 0x2
+	IPV6_PREFER_TEMPADDR           = 0x3f
+	IPV6_RECVDSTOPTS               = 0x28
+	IPV6_RECVFLOWID                = 0x46
+	IPV6_RECVHOPLIMIT              = 0x25
+	IPV6_RECVHOPOPTS               = 0x27
+	IPV6_RECVORIGDSTADDR           = 0x48
+	IPV6_RECVPATHMTU               = 0x2b
+	IPV6_RECVPKTINFO               = 0x24
+	IPV6_RECVRSSBUCKETID           = 0x47
+	IPV6_RECVRTHDR                 = 0x26
+	IPV6_RECVTCLASS                = 0x39
+	IPV6_RSSBUCKETID               = 0x45
+	IPV6_RSS_LISTEN_BUCKET         = 0x42
+	IPV6_RTHDR                     = 0x33
+	IPV6_RTHDRDSTOPTS              = 0x23
+	IPV6_RTHDR_LOOSE               = 0x0
+	IPV6_RTHDR_STRICT              = 0x1
+	IPV6_RTHDR_TYPE_0              = 0x0
+	IPV6_SOCKOPT_RESERVED1         = 0x3
+	IPV6_TCLASS                    = 0x3d
+	IPV6_UNICAST_HOPS              = 0x4
+	IPV6_USE_MIN_MTU               = 0x2a
+	IPV6_V6ONLY                    = 0x1b
+	IPV6_VERSION                   = 0x60
+	IPV6_VERSION_MASK              = 0xf0
+	IPV6_VLAN_PCP                  = 0x4b
+	IP_ADD_MEMBERSHIP              = 0xc
+	IP_ADD_SOURCE_MEMBERSHIP       = 0x46
+	IP_BINDANY                     = 0x18
+	IP_BINDMULTI                   = 0x19
+	IP_BLOCK_SOURCE                = 0x48
+	IP_DEFAULT_MULTICAST_LOOP      = 0x1
+	IP_DEFAULT_MULTICAST_TTL       = 0x1
+	IP_DF                          = 0x4000
+	IP_DONTFRAG                    = 0x43
+	IP_DROP_MEMBERSHIP             = 0xd
+	IP_DROP_SOURCE_MEMBERSHIP      = 0x47
+	IP_DUMMYNET3                   = 0x31
+	IP_DUMMYNET_CONFIGURE          = 0x3c
+	IP_DUMMYNET_DEL                = 0x3d
+	IP_DUMMYNET_FLUSH              = 0x3e
+	IP_DUMMYNET_GET                = 0x40
+	IP_FLOWID                      = 0x5a
+	IP_FLOWTYPE                    = 0x5b
+	IP_FW3                         = 0x30
+	IP_FW_ADD                      = 0x32
+	IP_FW_DEL                      = 0x33
+	IP_FW_FLUSH                    = 0x34
+	IP_FW_GET                      = 0x36
+	IP_FW_NAT_CFG                  = 0x38
+	IP_FW_NAT_DEL                  = 0x39
+	IP_FW_NAT_GET_CONFIG           = 0x3a
+	IP_FW_NAT_GET_LOG              = 0x3b
+	IP_FW_RESETLOG                 = 0x37
+	IP_FW_TABLE_ADD                = 0x28
+	IP_FW_TABLE_DEL                = 0x29
+	IP_FW_TABLE_FLUSH              = 0x2a
+	IP_FW_TABLE_GETSIZE            = 0x2b
+	IP_FW_TABLE_LIST               = 0x2c
+	IP_FW_ZERO                     = 0x35
+	IP_HDRINCL                     = 0x2
+	IP_IPSEC_POLICY                = 0x15
+	IP_MAXPACKET                   = 0xffff
+	IP_MAX_GROUP_SRC_FILTER        = 0x200
+	IP_MAX_MEMBERSHIPS             = 0xfff
+	IP_MAX_SOCK_MUTE_FILTER        = 0x80
+	IP_MAX_SOCK_SRC_FILTER         = 0x80
+	IP_MF                          = 0x2000
+	IP_MINTTL                      = 0x42
+	IP_MSFILTER                    = 0x4a
+	IP_MSS                         = 0x240
+	IP_MULTICAST_IF                = 0x9
+	IP_MULTICAST_LOOP              = 0xb
+	IP_MULTICAST_TTL               = 0xa
+	IP_MULTICAST_VIF               = 0xe
+	IP_OFFMASK                     = 0x1fff
+	IP_ONESBCAST                   = 0x17
+	IP_OPTIONS                     = 0x1
+	IP_ORIGDSTADDR                 = 0x1b
+	IP_PORTRANGE                   = 0x13
+	IP_PORTRANGE_DEFAULT           = 0x0
+	IP_PORTRANGE_HIGH              = 0x1
+	IP_PORTRANGE_LOW               = 0x2
+	IP_RECVDSTADDR                 = 0x7
+	IP_RECVFLOWID                  = 0x5d
+	IP_RECVIF                      = 0x14
+	IP_RECVOPTS                    = 0x5
+	IP_RECVORIGDSTADDR             = 0x1b
+	IP_RECVRETOPTS                 = 0x6
+	IP_RECVRSSBUCKETID             = 0x5e
+	IP_RECVTOS                     = 0x44
+	IP_RECVTTL                     = 0x41
+	IP_RETOPTS                     = 0x8
+	IP_RF                          = 0x8000
+	IP_RSSBUCKETID                 = 0x5c
+	IP_RSS_LISTEN_BUCKET           = 0x1a
+	IP_RSVP_OFF                    = 0x10
+	IP_RSVP_ON                     = 0xf
+	IP_RSVP_VIF_OFF                = 0x12
+	IP_RSVP_VIF_ON                 = 0x11
+	IP_SENDSRCADDR                 = 0x7
+	IP_TOS                         = 0x3
+	IP_TTL                         = 0x4
+	IP_UNBLOCK_SOURCE              = 0x49
+	IP_VLAN_PCP                    = 0x4b
+	ISIG                           = 0x80
+	ISTRIP                         = 0x20
+	ITIMER_PROF                    = 0x2
+	ITIMER_REAL                    = 0x0
+	ITIMER_VIRTUAL                 = 0x1
+	IXANY                          = 0x800
+	IXOFF                          = 0x400
+	IXON                           = 0x200
+	KERN_HOSTNAME                  = 0xa
+	KERN_OSRELEASE                 = 0x2
+	KERN_OSTYPE                    = 0x1
+	KERN_VERSION                   = 0x4
+	LOCAL_CONNWAIT                 = 0x4
+	LOCAL_CREDS                    = 0x2
+	LOCAL_CREDS_PERSISTENT         = 0x3
+	LOCAL_PEERCRED                 = 0x1
+	LOCAL_VENDOR                   = 0x80000000
+	LOCK_EX                        = 0x2
+	LOCK_NB                        = 0x4
+	LOCK_SH                        = 0x1
+	LOCK_UN                        = 0x8
+	MADV_AUTOSYNC                  = 0x7
+	MADV_CORE                      = 0x9
+	MADV_DONTNEED                  = 0x4
+	MADV_FREE                      = 0x5
+	MADV_NOCORE                    = 0x8
+	MADV_NORMAL                    = 0x0
+	MADV_NOSYNC                    = 0x6
+	MADV_PROTECT                   = 0xa
+	MADV_RANDOM                    = 0x1
+	MADV_SEQUENTIAL                = 0x2
+	MADV_WILLNEED                  = 0x3
+	MAP_32BIT                      = 0x80000
+	MAP_ALIGNED_SUPER              = 0x1000000
+	MAP_ALIGNMENT_MASK             = -0x1000000
+	MAP_ALIGNMENT_SHIFT            = 0x18
+	MAP_ANON                       = 0x1000
+	MAP_ANONYMOUS                  = 0x1000
+	MAP_COPY                       = 0x2
+	MAP_EXCL                       = 0x4000
+	MAP_FILE                       = 0x0
+	MAP_FIXED                      = 0x10
+	MAP_GUARD                      = 0x2000
+	MAP_HASSEMAPHORE               = 0x200
+	MAP_NOCORE                     = 0x20000
+	MAP_NOSYNC                     = 0x800
+	MAP_PREFAULT_READ              = 0x40000
+	MAP_PRIVATE                    = 0x2
+	MAP_RESERVED0020               = 0x20
+	MAP_RESERVED0040               = 0x40
+	MAP_RESERVED0080               = 0x80
+	MAP_RESERVED0100               = 0x100
+	MAP_SHARED                     = 0x1
+	MAP_STACK                      = 0x400
+	MCAST_BLOCK_SOURCE             = 0x54
+	MCAST_EXCLUDE                  = 0x2
+	MCAST_INCLUDE                  = 0x1
+	MCAST_JOIN_GROUP               = 0x50
+	MCAST_JOIN_SOURCE_GROUP        = 0x52
+	MCAST_LEAVE_GROUP              = 0x51
+	MCAST_LEAVE_SOURCE_GROUP       = 0x53
+	MCAST_UNBLOCK_SOURCE           = 0x55
+	MCAST_UNDEFINED                = 0x0
+	MCL_CURRENT                    = 0x1
+	MCL_FUTURE                     = 0x2
+	MFD_ALLOW_SEALING              = 0x2
+	MFD_CLOEXEC                    = 0x1
+	MFD_HUGETLB                    = 0x4
+	MFD_HUGE_16GB                  = -0x78000000
+	MFD_HUGE_16MB                  = 0x60000000
+	MFD_HUGE_1GB                   = 0x78000000
+	MFD_HUGE_1MB                   = 0x50000000
+	MFD_HUGE_256MB                 = 0x70000000
+	MFD_HUGE_2GB                   = 0x7c000000
+	MFD_HUGE_2MB                   = 0x54000000
+	MFD_HUGE_32MB                  = 0x64000000
+	MFD_HUGE_512KB                 = 0x4c000000
+	MFD_HUGE_512MB                 = 0x74000000
+	MFD_HUGE_64KB                  = 0x40000000
+	MFD_HUGE_8MB                   = 0x5c000000
+	MFD_HUGE_MASK                  = 0xfc000000
+	MFD_HUGE_SHIFT                 = 0x1a
+	MNT_ACLS                       = 0x8000000
+	MNT_ASYNC                      = 0x40
+	MNT_AUTOMOUNTED                = 0x200000000
+	MNT_BYFSID                     = 0x8000000
+	MNT_CMDFLAGS                   = 0x300d0f0000
+	MNT_DEFEXPORTED                = 0x200
+	MNT_DELEXPORT                  = 0x20000
+	MNT_EMPTYDIR                   = 0x2000000000
+	MNT_EXKERB                     = 0x800
+	MNT_EXPORTANON                 = 0x400
+	MNT_EXPORTED                   = 0x100
+	MNT_EXPUBLIC                   = 0x20000000
+	MNT_EXRDONLY                   = 0x80
+	MNT_EXTLS                      = 0x4000000000
+	MNT_EXTLSCERT                  = 0x8000000000
+	MNT_EXTLSCERTUSER              = 0x10000000000
+	MNT_FORCE                      = 0x80000
+	MNT_GJOURNAL                   = 0x2000000
+	MNT_IGNORE                     = 0x800000
+	MNT_LAZY                       = 0x3
+	MNT_LOCAL                      = 0x1000
+	MNT_MULTILABEL                 = 0x4000000
+	MNT_NFS4ACLS                   = 0x10
+	MNT_NOATIME                    = 0x10000000
+	MNT_NOCLUSTERR                 = 0x40000000
+	MNT_NOCLUSTERW                 = 0x80000000
+	MNT_NOCOVER                    = 0x1000000000
+	MNT_NOEXEC                     = 0x4
+	MNT_NONBUSY                    = 0x4000000
+	MNT_NOSUID                     = 0x8
+	MNT_NOSYMFOLLOW                = 0x400000
+	MNT_NOWAIT                     = 0x2
+	MNT_QUOTA                      = 0x2000
+	MNT_RDONLY                     = 0x1
+	MNT_RELOAD                     = 0x40000
+	MNT_ROOTFS                     = 0x4000
+	MNT_SNAPSHOT                   = 0x1000000
+	MNT_SOFTDEP                    = 0x200000
+	MNT_SUIDDIR                    = 0x100000
+	MNT_SUJ                        = 0x100000000
+	MNT_SUSPEND                    = 0x4
+	MNT_SYNCHRONOUS                = 0x2
+	MNT_UNION                      = 0x20
+	MNT_UNTRUSTED                  = 0x800000000
+	MNT_UPDATE                     = 0x10000
+	MNT_UPDATEMASK                 = 0xad8d0807e
+	MNT_USER                       = 0x8000
+	MNT_VERIFIED                   = 0x400000000
+	MNT_VISFLAGMASK                = 0xffef0ffff
+	MNT_WAIT                       = 0x1
+	MSG_CMSG_CLOEXEC               = 0x40000
+	MSG_COMPAT                     = 0x8000
+	MSG_CTRUNC                     = 0x20
+	MSG_DONTROUTE                  = 0x4
+	MSG_DONTWAIT                   = 0x80
+	MSG_EOF                        = 0x100
+	MSG_EOR                        = 0x8
+	MSG_NBIO                       = 0x4000
+	MSG_NOSIGNAL                   = 0x20000
+	MSG_NOTIFICATION               = 0x2000
+	MSG_OOB                        = 0x1
+	MSG_PEEK                       = 0x2
+	MSG_TRUNC                      = 0x10
+	MSG_WAITALL                    = 0x40
+	MSG_WAITFORONE                 = 0x80000
+	MS_ASYNC                       = 0x1
+	MS_INVALIDATE                  = 0x2
+	MS_SYNC                        = 0x0
+	NAME_MAX                       = 0xff
+	NET_RT_DUMP                    = 0x1
+	NET_RT_FLAGS                   = 0x2
+	NET_RT_IFLIST                  = 0x3
+	NET_RT_IFLISTL                 = 0x5
+	NET_RT_IFMALIST                = 0x4
+	NET_RT_NHGRP                   = 0x7
+	NET_RT_NHOP                    = 0x6
+	NFDBITS                        = 0x40
+	NOFLSH                         = 0x80000000
+	NOKERNINFO                     = 0x2000000
+	NOTE_ABSTIME                   = 0x10
+	NOTE_ATTRIB                    = 0x8
+	NOTE_CHILD                     = 0x4
+	NOTE_CLOSE                     = 0x100
+	NOTE_CLOSE_WRITE               = 0x200
+	NOTE_DELETE                    = 0x1
+	NOTE_EXEC                      = 0x20000000
+	NOTE_EXIT                      = 0x80000000
+	NOTE_EXTEND                    = 0x4
+	NOTE_FFAND                     = 0x40000000
+	NOTE_FFCOPY                    = 0xc0000000
+	NOTE_FFCTRLMASK                = 0xc0000000
+	NOTE_FFLAGSMASK                = 0xffffff
+	NOTE_FFNOP                     = 0x0
+	NOTE_FFOR                      = 0x80000000
+	NOTE_FILE_POLL                 = 0x2
+	NOTE_FORK                      = 0x40000000
+	NOTE_LINK                      = 0x10
+	NOTE_LOWAT                     = 0x1
+	NOTE_MSECONDS                  = 0x2
+	NOTE_NSECONDS                  = 0x8
+	NOTE_OPEN                      = 0x80
+	NOTE_PCTRLMASK                 = 0xf0000000
+	NOTE_PDATAMASK                 = 0xfffff
+	NOTE_READ                      = 0x400
+	NOTE_RENAME                    = 0x20
+	NOTE_REVOKE                    = 0x40
+	NOTE_SECONDS                   = 0x1
+	NOTE_TRACK                     = 0x1
+	NOTE_TRACKERR                  = 0x2
+	NOTE_TRIGGER                   = 0x1000000
+	NOTE_USECONDS                  = 0x4
+	NOTE_WRITE                     = 0x2
+	OCRNL                          = 0x10
+	ONLCR                          = 0x2
+	ONLRET                         = 0x40
+	ONOCR                          = 0x20
+	ONOEOT                         = 0x8
+	OPOST                          = 0x1
+	OXTABS                         = 0x4
+	O_ACCMODE                      = 0x3
+	O_APPEND                       = 0x8
+	O_ASYNC                        = 0x40
+	O_CLOEXEC                      = 0x100000
+	O_CREAT                        = 0x200
+	O_DIRECT                       = 0x10000
+	O_DIRECTORY                    = 0x20000
+	O_DSYNC                        = 0x1000000
+	O_EMPTY_PATH                   = 0x2000000
+	O_EXCL                         = 0x800
+	O_EXEC                         = 0x40000
+	O_EXLOCK                       = 0x20
+	O_FSYNC                        = 0x80
+	O_NDELAY                       = 0x4
+	O_NOCTTY                       = 0x8000
+	O_NOFOLLOW                     = 0x100
+	O_NONBLOCK                     = 0x4
+	O_PATH                         = 0x400000
+	O_RDONLY                       = 0x0
+	O_RDWR                         = 0x2
+	O_RESOLVE_BENEATH              = 0x800000
+	O_SEARCH                       = 0x40000
+	O_SHLOCK                       = 0x10
+	O_SYNC                         = 0x80
+	O_TRUNC                        = 0x400
+	O_TTY_INIT                     = 0x80000
+	O_VERIFY                       = 0x200000
+	O_WRONLY                       = 0x1
+	PARENB                         = 0x1000
+	PARMRK                         = 0x8
+	PARODD                         = 0x2000
+	PENDIN                         = 0x20000000
+	PIOD_READ_D                    = 0x1
+	PIOD_READ_I                    = 0x3
+	PIOD_WRITE_D                   = 0x2
+	PIOD_WRITE_I                   = 0x4
+	PRIO_PGRP                      = 0x1
+	PRIO_PROCESS                   = 0x0
+	PRIO_USER                      = 0x2
+	PROT_EXEC                      = 0x4
+	PROT_NONE                      = 0x0
+	PROT_READ                      = 0x1
+	PROT_WRITE                     = 0x2
+	PTRACE_DEFAULT                 = 0x1
+	PTRACE_EXEC                    = 0x1
+	PTRACE_FORK                    = 0x8
+	PTRACE_LWP                     = 0x10
+	PTRACE_SCE                     = 0x2
+	PTRACE_SCX                     = 0x4
+	PTRACE_SYSCALL                 = 0x6
+	PTRACE_VFORK                   = 0x20
+	PT_ATTACH                      = 0xa
+	PT_CLEARSTEP                   = 0x10
+	PT_CONTINUE                    = 0x7
+	PT_COREDUMP                    = 0x1d
+	PT_DETACH                      = 0xb
+	PT_FIRSTMACH                   = 0x40
+	PT_FOLLOW_FORK                 = 0x17
+	PT_GETDBREGS                   = 0x25
+	PT_GETFPREGS                   = 0x23
+	PT_GETLWPLIST                  = 0xf
+	PT_GETNUMLWPS                  = 0xe
+	PT_GETREGS                     = 0x21
+	PT_GET_EVENT_MASK              = 0x19
+	PT_GET_SC_ARGS                 = 0x1b
+	PT_GET_SC_RET                  = 0x1c
+	PT_IO                          = 0xc
+	PT_KILL                        = 0x8
+	PT_LWPINFO                     = 0xd
+	PT_LWP_EVENTS                  = 0x18
+	PT_READ_D                      = 0x2
+	PT_READ_I                      = 0x1
+	PT_RESUME                      = 0x13
+	PT_SETDBREGS                   = 0x26
+	PT_SETFPREGS                   = 0x24
+	PT_SETREGS                     = 0x22
+	PT_SETSTEP                     = 0x11
+	PT_SET_EVENT_MASK              = 0x1a
+	PT_STEP                        = 0x9
+	PT_SUSPEND                     = 0x12
+	PT_SYSCALL                     = 0x16
+	PT_TO_SCE                      = 0x14
+	PT_TO_SCX                      = 0x15
+	PT_TRACE_ME                    = 0x0
+	PT_VM_ENTRY                    = 0x29
+	PT_VM_TIMESTAMP                = 0x28
+	PT_WRITE_D                     = 0x5
+	PT_WRITE_I                     = 0x4
+	P_ZONEID                       = 0xc
+	RLIMIT_AS                      = 0xa
+	RLIMIT_CORE                    = 0x4
+	RLIMIT_CPU                     = 0x0
+	RLIMIT_DATA                    = 0x2
+	RLIMIT_FSIZE                   = 0x1
+	RLIMIT_MEMLOCK                 = 0x6
+	RLIMIT_NOFILE                  = 0x8
+	RLIMIT_NPROC                   = 0x7
+	RLIMIT_RSS                     = 0x5
+	RLIMIT_STACK                   = 0x3
+	RLIM_INFINITY                  = 0x7fffffffffffffff
+	RTAX_AUTHOR                    = 0x6
+	RTAX_BRD                       = 0x7
+	RTAX_DST                       = 0x0
+	RTAX_GATEWAY                   = 0x1
+	RTAX_GENMASK                   = 0x3
+	RTAX_IFA                       = 0x5
+	RTAX_IFP                       = 0x4
+	RTAX_MAX                       = 0x8
+	RTAX_NETMASK                   = 0x2
+	RTA_AUTHOR                     = 0x40
+	RTA_BRD                        = 0x80
+	RTA_DST                        = 0x1
+	RTA_GATEWAY                    = 0x2
+	RTA_GENMASK                    = 0x8
+	RTA_IFA                        = 0x20
+	RTA_IFP                        = 0x10
+	RTA_NETMASK                    = 0x4
+	RTF_BLACKHOLE                  = 0x1000
+	RTF_BROADCAST                  = 0x400000
+	RTF_DONE                       = 0x40
+	RTF_DYNAMIC                    = 0x10
+	RTF_FIXEDMTU                   = 0x80000
+	RTF_FMASK                      = 0x1004d808
+	RTF_GATEWAY                    = 0x2
+	RTF_GWFLAG_COMPAT              = 0x80000000
+	RTF_HOST                       = 0x4
+	RTF_LLDATA                     = 0x400
+	RTF_LLINFO                     = 0x400
+	RTF_LOCAL                      = 0x200000
+	RTF_MODIFIED                   = 0x20
+	RTF_MULTICAST                  = 0x800000
+	RTF_PINNED                     = 0x100000
+	RTF_PROTO1                     = 0x8000
+	RTF_PROTO2                     = 0x4000
+	RTF_PROTO3                     = 0x40000
+	RTF_REJECT                     = 0x8
+	RTF_STATIC                     = 0x800
+	RTF_STICKY                     = 0x10000000
+	RTF_UP                         = 0x1
+	RTF_XRESOLVE                   = 0x200
+	RTM_ADD                        = 0x1
+	RTM_CHANGE                     = 0x3
+	RTM_DELADDR                    = 0xd
+	RTM_DELETE                     = 0x2
+	RTM_DELMADDR                   = 0x10
+	RTM_GET                        = 0x4
+	RTM_IEEE80211                  = 0x12
+	RTM_IFANNOUNCE                 = 0x11
+	RTM_IFINFO                     = 0xe
+	RTM_LOCK                       = 0x8
+	RTM_LOSING                     = 0x5
+	RTM_MISS                       = 0x7
+	RTM_NEWADDR                    = 0xc
+	RTM_NEWMADDR                   = 0xf
+	RTM_REDIRECT                   = 0x6
+	RTM_RESOLVE                    = 0xb
+	RTM_RTTUNIT                    = 0xf4240
+	RTM_VERSION                    = 0x5
+	RTV_EXPIRE                     = 0x4
+	RTV_HOPCOUNT                   = 0x2
+	RTV_MTU                        = 0x1
+	RTV_RPIPE                      = 0x8
+	RTV_RTT                        = 0x40
+	RTV_RTTVAR                     = 0x80
+	RTV_SPIPE                      = 0x10
+	RTV_SSTHRESH                   = 0x20
+	RTV_WEIGHT                     = 0x100
+	RT_ALL_FIBS                    = -0x1
+	RT_BLACKHOLE                   = 0x40
+	RT_DEFAULT_FIB                 = 0x0
+	RT_DEFAULT_WEIGHT              = 0x1
+	RT_HAS_GW                      = 0x80
+	RT_HAS_HEADER                  = 0x10
+	RT_HAS_HEADER_BIT              = 0x4
+	RT_L2_ME                       = 0x4
+	RT_L2_ME_BIT                   = 0x2
+	RT_LLE_CACHE                   = 0x100
+	RT_MAX_WEIGHT                  = 0xffffff
+	RT_MAY_LOOP                    = 0x8
+	RT_MAY_LOOP_BIT                = 0x3
+	RT_REJECT                      = 0x20
+	RUSAGE_CHILDREN                = -0x1
+	RUSAGE_SELF                    = 0x0
+	RUSAGE_THREAD                  = 0x1
+	SCM_BINTIME                    = 0x4
+	SCM_CREDS                      = 0x3
+	SCM_CREDS2                     = 0x8
+	SCM_MONOTONIC                  = 0x6
+	SCM_REALTIME                   = 0x5
+	SCM_RIGHTS                     = 0x1
+	SCM_TIMESTAMP                  = 0x2
+	SCM_TIME_INFO                  = 0x7
+	SEEK_CUR                       = 0x1
+	SEEK_DATA                      = 0x3
+	SEEK_END                       = 0x2
+	SEEK_HOLE                      = 0x4
+	SEEK_SET                       = 0x0
+	SHUT_RD                        = 0x0
+	SHUT_RDWR                      = 0x2
+	SHUT_WR                        = 0x1
+	SIOCADDMULTI                   = 0x80206931
+	SIOCAIFADDR                    = 0x8040691a
+	SIOCAIFGROUP                   = 0x80286987
+	SIOCATMARK                     = 0x40047307
+	SIOCDELMULTI                   = 0x80206932
+	SIOCDIFADDR                    = 0x80206919
+	SIOCDIFGROUP                   = 0x80286989
+	SIOCDIFPHYADDR                 = 0x80206949
+	SIOCGDRVSPEC                   = 0xc028697b
+	SIOCGETSGCNT                   = 0xc0207210
+	SIOCGETVIFCNT                  = 0xc028720f
+	SIOCGHIWAT                     = 0x40047301
+	SIOCGHWADDR                    = 0xc020693e
+	SIOCGI2C                       = 0xc020693d
+	SIOCGIFADDR                    = 0xc0206921
+	SIOCGIFALIAS                   = 0xc044692d
+	SIOCGIFBRDADDR                 = 0xc0206923
+	SIOCGIFCAP                     = 0xc020691f
+	SIOCGIFCONF                    = 0xc0106924
+	SIOCGIFDATA                    = 0x8020692c
+	SIOCGIFDESCR                   = 0xc020692a
+	SIOCGIFDOWNREASON              = 0xc058699a
+	SIOCGIFDSTADDR                 = 0xc0206922
+	SIOCGIFFIB                     = 0xc020695c
+	SIOCGIFFLAGS                   = 0xc0206911
+	SIOCGIFGENERIC                 = 0xc020693a
+	SIOCGIFGMEMB                   = 0xc028698a
+	SIOCGIFGROUP                   = 0xc0286988
+	SIOCGIFINDEX                   = 0xc0206920
+	SIOCGIFMAC                     = 0xc0206926
+	SIOCGIFMEDIA                   = 0xc0306938
+	SIOCGIFMETRIC                  = 0xc0206917
+	SIOCGIFMTU                     = 0xc0206933
+	SIOCGIFNETMASK                 = 0xc0206925
+	SIOCGIFPDSTADDR                = 0xc0206948
+	SIOCGIFPHYS                    = 0xc0206935
+	SIOCGIFPSRCADDR                = 0xc0206947
+	SIOCGIFRSSHASH                 = 0xc0186997
+	SIOCGIFRSSKEY                  = 0xc0946996
+	SIOCGIFSTATUS                  = 0xc331693b
+	SIOCGIFXMEDIA                  = 0xc030698b
+	SIOCGLANPCP                    = 0xc0206998
+	SIOCGLOWAT                     = 0x40047303
+	SIOCGPGRP                      = 0x40047309
+	SIOCGPRIVATE_0                 = 0xc0206950
+	SIOCGPRIVATE_1                 = 0xc0206951
+	SIOCGTUNFIB                    = 0xc020695e
+	SIOCIFCREATE                   = 0xc020697a
+	SIOCIFCREATE2                  = 0xc020697c
+	SIOCIFDESTROY                  = 0x80206979
+	SIOCIFGCLONERS                 = 0xc0106978
+	SIOCSDRVSPEC                   = 0x8028697b
+	SIOCSHIWAT                     = 0x80047300
+	SIOCSIFADDR                    = 0x8020690c
+	SIOCSIFBRDADDR                 = 0x80206913
+	SIOCSIFCAP                     = 0x8020691e
+	SIOCSIFDESCR                   = 0x80206929
+	SIOCSIFDSTADDR                 = 0x8020690e
+	SIOCSIFFIB                     = 0x8020695d
+	SIOCSIFFLAGS                   = 0x80206910
+	SIOCSIFGENERIC                 = 0x80206939
+	SIOCSIFLLADDR                  = 0x8020693c
+	SIOCSIFMAC                     = 0x80206927
+	SIOCSIFMEDIA                   = 0xc0206937
+	SIOCSIFMETRIC                  = 0x80206918
+	SIOCSIFMTU                     = 0x80206934
+	SIOCSIFNAME                    = 0x80206928
+	SIOCSIFNETMASK                 = 0x80206916
+	SIOCSIFPHYADDR                 = 0x80406946
+	SIOCSIFPHYS                    = 0x80206936
+	SIOCSIFRVNET                   = 0xc020695b
+	SIOCSIFVNET                    = 0xc020695a
+	SIOCSLANPCP                    = 0x80206999
+	SIOCSLOWAT                     = 0x80047302
+	SIOCSPGRP                      = 0x80047308
+	SIOCSTUNFIB                    = 0x8020695f
+	SOCK_CLOEXEC                   = 0x10000000
+	SOCK_DGRAM                     = 0x2
+	SOCK_MAXADDRLEN                = 0xff
+	SOCK_NONBLOCK                  = 0x20000000
+	SOCK_RAW                       = 0x3
+	SOCK_RDM                       = 0x4
+	SOCK_SEQPACKET                 = 0x5
+	SOCK_STREAM                    = 0x1
+	SOL_LOCAL                      = 0x0
+	SOL_SOCKET                     = 0xffff
+	SOMAXCONN                      = 0x80
+	SO_ACCEPTCONN                  = 0x2
+	SO_ACCEPTFILTER                = 0x1000
+	SO_BINTIME                     = 0x2000
+	SO_BROADCAST                   = 0x20
+	SO_DEBUG                       = 0x1
+	SO_DOMAIN                      = 0x1019
+	SO_DONTROUTE                   = 0x10
+	SO_ERROR                       = 0x1007
+	SO_KEEPALIVE                   = 0x8
+	SO_LABEL                       = 0x1009
+	SO_LINGER                      = 0x80
+	SO_LISTENINCQLEN               = 0x1013
+	SO_LISTENQLEN                  = 0x1012
+	SO_LISTENQLIMIT                = 0x1011
+	SO_MAX_PACING_RATE             = 0x1018
+	SO_NOSIGPIPE                   = 0x800
+	SO_NO_DDP                      = 0x8000
+	SO_NO_OFFLOAD                  = 0x4000
+	SO_OOBINLINE                   = 0x100
+	SO_PEERLABEL                   = 0x1010
+	SO_PROTOCOL                    = 0x1016
+	SO_PROTOTYPE                   = 0x1016
+	SO_RCVBUF                      = 0x1002
+	SO_RCVLOWAT                    = 0x1004
+	SO_RCVTIMEO                    = 0x1006
+	SO_RERROR                      = 0x20000
+	SO_REUSEADDR                   = 0x4
+	SO_REUSEPORT                   = 0x200
+	SO_REUSEPORT_LB                = 0x10000
+	SO_SETFIB                      = 0x1014
+	SO_SNDBUF                      = 0x1001
+	SO_SNDLOWAT                    = 0x1003
+	SO_SNDTIMEO                    = 0x1005
+	SO_TIMESTAMP                   = 0x400
+	SO_TS_BINTIME                  = 0x1
+	SO_TS_CLOCK                    = 0x1017
+	SO_TS_CLOCK_MAX                = 0x3
+	SO_TS_DEFAULT                  = 0x0
+	SO_TS_MONOTONIC                = 0x3
+	SO_TS_REALTIME                 = 0x2
+	SO_TS_REALTIME_MICRO           = 0x0
+	SO_TYPE                        = 0x1008
+	SO_USELOOPBACK                 = 0x40
+	SO_USER_COOKIE                 = 0x1015
+	SO_VENDOR                      = 0x80000000
+	S_BLKSIZE                      = 0x200
+	S_IEXEC                        = 0x40
+	S_IFBLK                        = 0x6000
+	S_IFCHR                        = 0x2000
+	S_IFDIR                        = 0x4000
+	S_IFIFO                        = 0x1000
+	S_IFLNK                        = 0xa000
+	S_IFMT                         = 0xf000
+	S_IFREG                        = 0x8000
+	S_IFSOCK                       = 0xc000
+	S_IFWHT                        = 0xe000
+	S_IREAD                        = 0x100
+	S_IRGRP                        = 0x20
+	S_IROTH                        = 0x4
+	S_IRUSR                        = 0x100
+	S_IRWXG                        = 0x38
+	S_IRWXO                        = 0x7
+	S_IRWXU                        = 0x1c0
+	S_ISGID                        = 0x400
+	S_ISTXT                        = 0x200
+	S_ISUID                        = 0x800
+	S_ISVTX                        = 0x200
+	S_IWGRP                        = 0x10
+	S_IWOTH                        = 0x2
+	S_IWRITE                       = 0x80
+	S_IWUSR                        = 0x80
+	S_IXGRP                        = 0x8
+	S_IXOTH                        = 0x1
+	S_IXUSR                        = 0x40
+	TAB0                           = 0x0
+	TAB3                           = 0x4
+	TABDLY                         = 0x4
+	TCIFLUSH                       = 0x1
+	TCIOFF                         = 0x3
+	TCIOFLUSH                      = 0x3
+	TCION                          = 0x4
+	TCOFLUSH                       = 0x2
+	TCOOFF                         = 0x1
+	TCOON                          = 0x2
+	TCPOPT_EOL                     = 0x0
+	TCPOPT_FAST_OPEN               = 0x22
+	TCPOPT_MAXSEG                  = 0x2
+	TCPOPT_NOP                     = 0x1
+	TCPOPT_PAD                     = 0x0
+	TCPOPT_SACK                    = 0x5
+	TCPOPT_SACK_PERMITTED          = 0x4
+	TCPOPT_SIGNATURE               = 0x13
+	TCPOPT_TIMESTAMP               = 0x8
+	TCPOPT_WINDOW                  = 0x3
+	TCP_BBR_ACK_COMP_ALG           = 0x448
+	TCP_BBR_ALGORITHM              = 0x43b
+	TCP_BBR_DRAIN_INC_EXTRA        = 0x43c
+	TCP_BBR_DRAIN_PG               = 0x42e
+	TCP_BBR_EXTRA_GAIN             = 0x449
+	TCP_BBR_EXTRA_STATE            = 0x453
+	TCP_BBR_FLOOR_MIN_TSO          = 0x454
+	TCP_BBR_HDWR_PACE              = 0x451
+	TCP_BBR_HOLD_TARGET            = 0x436
+	TCP_BBR_IWINTSO                = 0x42b
+	TCP_BBR_LOWGAIN_FD             = 0x436
+	TCP_BBR_LOWGAIN_HALF           = 0x435
+	TCP_BBR_LOWGAIN_THRESH         = 0x434
+	TCP_BBR_MAX_RTO                = 0x439
+	TCP_BBR_MIN_RTO                = 0x438
+	TCP_BBR_MIN_TOPACEOUT          = 0x455
+	TCP_BBR_ONE_RETRAN             = 0x431
+	TCP_BBR_PACE_CROSS             = 0x442
+	TCP_BBR_PACE_DEL_TAR           = 0x43f
+	TCP_BBR_PACE_OH                = 0x435
+	TCP_BBR_PACE_PER_SEC           = 0x43e
+	TCP_BBR_PACE_SEG_MAX           = 0x440
+	TCP_BBR_PACE_SEG_MIN           = 0x441
+	TCP_BBR_POLICER_DETECT         = 0x457
+	TCP_BBR_PROBE_RTT_GAIN         = 0x44d
+	TCP_BBR_PROBE_RTT_INT          = 0x430
+	TCP_BBR_PROBE_RTT_LEN          = 0x44e
+	TCP_BBR_RACK_INIT_RATE         = 0x458
+	TCP_BBR_RACK_RTT_USE           = 0x44a
+	TCP_BBR_RECFORCE               = 0x42c
+	TCP_BBR_REC_OVER_HPTS          = 0x43a
+	TCP_BBR_RETRAN_WTSO            = 0x44b
+	TCP_BBR_RWND_IS_APP            = 0x42f
+	TCP_BBR_SEND_IWND_IN_TSO       = 0x44f
+	TCP_BBR_STARTUP_EXIT_EPOCH     = 0x43d
+	TCP_BBR_STARTUP_LOSS_EXIT      = 0x432
+	TCP_BBR_STARTUP_PG             = 0x42d
+	TCP_BBR_TMR_PACE_OH            = 0x448
+	TCP_BBR_TSLIMITS               = 0x434
+	TCP_BBR_TSTMP_RAISES           = 0x456
+	TCP_BBR_UNLIMITED              = 0x43b
+	TCP_BBR_USEDEL_RATE            = 0x437
+	TCP_BBR_USE_LOWGAIN            = 0x433
+	TCP_BBR_USE_RACK_CHEAT         = 0x450
+	TCP_BBR_USE_RACK_RR            = 0x450
+	TCP_BBR_UTTER_MAX_TSO          = 0x452
+	TCP_CA_NAME_MAX                = 0x10
+	TCP_CCALGOOPT                  = 0x41
+	TCP_CONGESTION                 = 0x40
+	TCP_DATA_AFTER_CLOSE           = 0x44c
+	TCP_DEFER_OPTIONS              = 0x470
+	TCP_DELACK                     = 0x48
+	TCP_FASTOPEN                   = 0x401
+	TCP_FASTOPEN_MAX_COOKIE_LEN    = 0x10
+	TCP_FASTOPEN_MIN_COOKIE_LEN    = 0x4
+	TCP_FASTOPEN_PSK_LEN           = 0x10
+	TCP_FAST_RSM_HACK              = 0x471
+	TCP_FIN_IS_RST                 = 0x49
+	TCP_FUNCTION_BLK               = 0x2000
+	TCP_FUNCTION_NAME_LEN_MAX      = 0x20
+	TCP_HDWR_RATE_CAP              = 0x46a
+	TCP_HDWR_UP_ONLY               = 0x46c
+	TCP_IDLE_REDUCE                = 0x46
+	TCP_INFO                       = 0x20
+	TCP_IWND_NB                    = 0x2b
+	TCP_IWND_NSEG                  = 0x2c
+	TCP_KEEPCNT                    = 0x400
+	TCP_KEEPIDLE                   = 0x100
+	TCP_KEEPINIT                   = 0x80
+	TCP_KEEPINTVL                  = 0x200
+	TCP_LOG                        = 0x22
+	TCP_LOGBUF                     = 0x23
+	TCP_LOGDUMP                    = 0x25
+	TCP_LOGDUMPID                  = 0x26
+	TCP_LOGID                      = 0x24
+	TCP_LOGID_CNT                  = 0x2e
+	TCP_LOG_ID_LEN                 = 0x40
+	TCP_LOG_LIMIT                  = 0x4a
+	TCP_LOG_TAG                    = 0x2f
+	TCP_MAXBURST                   = 0x4
+	TCP_MAXHLEN                    = 0x3c
+	TCP_MAXOLEN                    = 0x28
+	TCP_MAXPEAKRATE                = 0x45
+	TCP_MAXSEG                     = 0x2
+	TCP_MAXUNACKTIME               = 0x44
+	TCP_MAXWIN                     = 0xffff
+	TCP_MAX_SACK                   = 0x4
+	TCP_MAX_WINSHIFT               = 0xe
+	TCP_MD5SIG                     = 0x10
+	TCP_MINMSS                     = 0xd8
+	TCP_MSS                        = 0x218
+	TCP_NODELAY                    = 0x1
+	TCP_NOOPT                      = 0x8
+	TCP_NOPUSH                     = 0x4
+	TCP_NO_PRR                     = 0x462
+	TCP_PACING_RATE_CAP            = 0x46b
+	TCP_PCAP_IN                    = 0x1000
+	TCP_PCAP_OUT                   = 0x800
+	TCP_PERF_INFO                  = 0x4e
+	TCP_PROC_ACCOUNTING            = 0x4c
+	TCP_RACK_ABC_VAL               = 0x46d
+	TCP_RACK_CHEAT_NOT_CONF_RATE   = 0x459
+	TCP_RACK_DO_DETECTION          = 0x449
+	TCP_RACK_EARLY_RECOV           = 0x423
+	TCP_RACK_EARLY_SEG             = 0x424
+	TCP_RACK_FORCE_MSEG            = 0x45d
+	TCP_RACK_GP_INCREASE           = 0x446
+	TCP_RACK_GP_INCREASE_CA        = 0x45a
+	TCP_RACK_GP_INCREASE_REC       = 0x45c
+	TCP_RACK_GP_INCREASE_SS        = 0x45b
+	TCP_RACK_IDLE_REDUCE_HIGH      = 0x444
+	TCP_RACK_MBUF_QUEUE            = 0x41a
+	TCP_RACK_MEASURE_CNT           = 0x46f
+	TCP_RACK_MIN_PACE              = 0x445
+	TCP_RACK_MIN_PACE_SEG          = 0x446
+	TCP_RACK_MIN_TO                = 0x422
+	TCP_RACK_NONRXT_CFG_RATE       = 0x463
+	TCP_RACK_NO_PUSH_AT_MAX        = 0x466
+	TCP_RACK_PACE_ALWAYS           = 0x41f
+	TCP_RACK_PACE_MAX_SEG          = 0x41e
+	TCP_RACK_PACE_RATE_CA          = 0x45e
+	TCP_RACK_PACE_RATE_REC         = 0x460
+	TCP_RACK_PACE_RATE_SS          = 0x45f
+	TCP_RACK_PACE_REDUCE           = 0x41d
+	TCP_RACK_PACE_TO_FILL          = 0x467
+	TCP_RACK_PACING_BETA           = 0x472
+	TCP_RACK_PACING_BETA_ECN       = 0x473
+	TCP_RACK_PKT_DELAY             = 0x428
+	TCP_RACK_PROFILE               = 0x469
+	TCP_RACK_PROP                  = 0x41b
+	TCP_RACK_PROP_RATE             = 0x420
+	TCP_RACK_PRR_SENDALOT          = 0x421
+	TCP_RACK_REORD_FADE            = 0x426
+	TCP_RACK_REORD_THRESH          = 0x425
+	TCP_RACK_RR_CONF               = 0x459
+	TCP_RACK_TIMER_SLOP            = 0x474
+	TCP_RACK_TLP_INC_VAR           = 0x429
+	TCP_RACK_TLP_REDUCE            = 0x41c
+	TCP_RACK_TLP_THRESH            = 0x427
+	TCP_RACK_TLP_USE               = 0x447
+	TCP_REC_ABC_VAL                = 0x46e
+	TCP_REMOTE_UDP_ENCAPS_PORT     = 0x47
+	TCP_REUSPORT_LB_NUMA           = 0x402
+	TCP_REUSPORT_LB_NUMA_CURDOM    = -0x1
+	TCP_REUSPORT_LB_NUMA_NODOM     = -0x2
+	TCP_RXTLS_ENABLE               = 0x29
+	TCP_RXTLS_MODE                 = 0x2a
+	TCP_SHARED_CWND_ALLOWED        = 0x4b
+	TCP_SHARED_CWND_ENABLE         = 0x464
+	TCP_SHARED_CWND_TIME_LIMIT     = 0x468
+	TCP_STATS                      = 0x21
+	TCP_TIMELY_DYN_ADJ             = 0x465
+	TCP_TLS_MODE_IFNET             = 0x2
+	TCP_TLS_MODE_NONE              = 0x0
+	TCP_TLS_MODE_SW                = 0x1
+	TCP_TLS_MODE_TOE               = 0x3
+	TCP_TXTLS_ENABLE               = 0x27
+	TCP_TXTLS_MODE                 = 0x28
+	TCP_USER_LOG                   = 0x30
+	TCP_USE_CMP_ACKS               = 0x4d
+	TCP_VENDOR                     = 0x80000000
+	TCSAFLUSH                      = 0x2
+	TIMER_ABSTIME                  = 0x1
+	TIMER_RELTIME                  = 0x0
+	TIOCCBRK                       = 0x2000747a
+	TIOCCDTR                       = 0x20007478
+	TIOCCONS                       = 0x80047462
+	TIOCDRAIN                      = 0x2000745e
+	TIOCEXCL                       = 0x2000740d
+	TIOCEXT                        = 0x80047460
+	TIOCFLUSH                      = 0x80047410
+	TIOCGDRAINWAIT                 = 0x40047456
+	TIOCGETA                       = 0x402c7413
+	TIOCGETD                       = 0x4004741a
+	TIOCGPGRP                      = 0x40047477
+	TIOCGPTN                       = 0x4004740f
+	TIOCGSID                       = 0x40047463
+	TIOCGWINSZ                     = 0x40087468
+	TIOCMBIC                       = 0x8004746b
+	TIOCMBIS                       = 0x8004746c
+	TIOCMGDTRWAIT                  = 0x4004745a
+	TIOCMGET                       = 0x4004746a
+	TIOCMSDTRWAIT                  = 0x8004745b
+	TIOCMSET                       = 0x8004746d
+	TIOCM_CAR                      = 0x40
+	TIOCM_CD                       = 0x40
+	TIOCM_CTS                      = 0x20
+	TIOCM_DCD                      = 0x40
+	TIOCM_DSR                      = 0x100
+	TIOCM_DTR                      = 0x2
+	TIOCM_LE                       = 0x1
+	TIOCM_RI                       = 0x80
+	TIOCM_RNG                      = 0x80
+	TIOCM_RTS                      = 0x4
+	TIOCM_SR                       = 0x10
+	TIOCM_ST                       = 0x8
+	TIOCNOTTY                      = 0x20007471
+	TIOCNXCL                       = 0x2000740e
+	TIOCOUTQ                       = 0x40047473
+	TIOCPKT                        = 0x80047470
+	TIOCPKT_DATA                   = 0x0
+	TIOCPKT_DOSTOP                 = 0x20
+	TIOCPKT_FLUSHREAD              = 0x1
+	TIOCPKT_FLUSHWRITE             = 0x2
+	TIOCPKT_IOCTL                  = 0x40
+	TIOCPKT_NOSTOP                 = 0x10
+	TIOCPKT_START                  = 0x8
+	TIOCPKT_STOP                   = 0x4
+	TIOCPTMASTER                   = 0x2000741c
+	TIOCSBRK                       = 0x2000747b
+	TIOCSCTTY                      = 0x20007461
+	TIOCSDRAINWAIT                 = 0x80047457
+	TIOCSDTR                       = 0x20007479
+	TIOCSETA                       = 0x802c7414
+	TIOCSETAF                      = 0x802c7416
+	TIOCSETAW                      = 0x802c7415
+	TIOCSETD                       = 0x8004741b
+	TIOCSIG                        = 0x2004745f
+	TIOCSPGRP                      = 0x80047476
+	TIOCSTART                      = 0x2000746e
+	TIOCSTAT                       = 0x20007465
+	TIOCSTI                        = 0x80017472
+	TIOCSTOP                       = 0x2000746f
+	TIOCSWINSZ                     = 0x80087467
+	TIOCTIMESTAMP                  = 0x40107459
+	TIOCUCNTL                      = 0x80047466
+	TOSTOP                         = 0x400000
+	UTIME_NOW                      = -0x1
+	UTIME_OMIT                     = -0x2
+	VDISCARD                       = 0xf
+	VDSUSP                         = 0xb
+	VEOF                           = 0x0
+	VEOL                           = 0x1
+	VEOL2                          = 0x2
+	VERASE                         = 0x3
+	VERASE2                        = 0x7
+	VINTR                          = 0x8
+	VKILL                          = 0x5
+	VLNEXT                         = 0xe
+	VMIN                           = 0x10
+	VQUIT                          = 0x9
+	VREPRINT                       = 0x6
+	VSTART                         = 0xc
+	VSTATUS                        = 0x12
+	VSTOP                          = 0xd
+	VSUSP                          = 0xa
+	VTIME                          = 0x11
+	VWERASE                        = 0x4
+	WCONTINUED                     = 0x4
+	WCOREFLAG                      = 0x80
+	WEXITED                        = 0x10
+	WLINUXCLONE                    = 0x80000000
+	WNOHANG                        = 0x1
+	WNOWAIT                        = 0x8
+	WSTOPPED                       = 0x2
+	WTRAPPED                       = 0x20
+	WUNTRACED                      = 0x2
+)
+
+// Errors
+const (
+	E2BIG           = syscall.Errno(0x7)
+	EACCES          = syscall.Errno(0xd)
+	EADDRINUSE      = syscall.Errno(0x30)
+	EADDRNOTAVAIL   = syscall.Errno(0x31)
+	EAFNOSUPPORT    = syscall.Errno(0x2f)
+	EAGAIN          = syscall.Errno(0x23)
+	EALREADY        = syscall.Errno(0x25)
+	EAUTH           = syscall.Errno(0x50)
+	EBADF           = syscall.Errno(0x9)
+	EBADMSG         = syscall.Errno(0x59)
+	EBADRPC         = syscall.Errno(0x48)
+	EBUSY           = syscall.Errno(0x10)
+	ECANCELED       = syscall.Errno(0x55)
+	ECAPMODE        = syscall.Errno(0x5e)
+	ECHILD          = syscall.Errno(0xa)
+	ECONNABORTED    = syscall.Errno(0x35)
+	ECONNREFUSED    = syscall.Errno(0x3d)
+	ECONNRESET      = syscall.Errno(0x36)
+	EDEADLK         = syscall.Errno(0xb)
+	EDESTADDRREQ    = syscall.Errno(0x27)
+	EDOM            = syscall.Errno(0x21)
+	EDOOFUS         = syscall.Errno(0x58)
+	EDQUOT          = syscall.Errno(0x45)
+	EEXIST          = syscall.Errno(0x11)
+	EFAULT          = syscall.Errno(0xe)
+	EFBIG           = syscall.Errno(0x1b)
+	EFTYPE          = syscall.Errno(0x4f)
+	EHOSTDOWN       = syscall.Errno(0x40)
+	EHOSTUNREACH    = syscall.Errno(0x41)
+	EIDRM           = syscall.Errno(0x52)
+	EILSEQ          = syscall.Errno(0x56)
+	EINPROGRESS     = syscall.Errno(0x24)
+	EINTEGRITY      = syscall.Errno(0x61)
+	EINTR           = syscall.Errno(0x4)
+	EINVAL          = syscall.Errno(0x16)
+	EIO             = syscall.Errno(0x5)
+	EISCONN         = syscall.Errno(0x38)
+	EISDIR          = syscall.Errno(0x15)
+	ELAST           = syscall.Errno(0x61)
+	ELOOP           = syscall.Errno(0x3e)
+	EMFILE          = syscall.Errno(0x18)
+	EMLINK          = syscall.Errno(0x1f)
+	EMSGSIZE        = syscall.Errno(0x28)
+	EMULTIHOP       = syscall.Errno(0x5a)
+	ENAMETOOLONG    = syscall.Errno(0x3f)
+	ENEEDAUTH       = syscall.Errno(0x51)
+	ENETDOWN        = syscall.Errno(0x32)
+	ENETRESET       = syscall.Errno(0x34)
+	ENETUNREACH     = syscall.Errno(0x33)
+	ENFILE          = syscall.Errno(0x17)
+	ENOATTR         = syscall.Errno(0x57)
+	ENOBUFS         = syscall.Errno(0x37)
+	ENODEV          = syscall.Errno(0x13)
+	ENOENT          = syscall.Errno(0x2)
+	ENOEXEC         = syscall.Errno(0x8)
+	ENOLCK          = syscall.Errno(0x4d)
+	ENOLINK         = syscall.Errno(0x5b)
+	ENOMEM          = syscall.Errno(0xc)
+	ENOMSG          = syscall.Errno(0x53)
+	ENOPROTOOPT     = syscall.Errno(0x2a)
+	ENOSPC          = syscall.Errno(0x1c)
+	ENOSYS          = syscall.Errno(0x4e)
+	ENOTBLK         = syscall.Errno(0xf)
+	ENOTCAPABLE     = syscall.Errno(0x5d)
+	ENOTCONN        = syscall.Errno(0x39)
+	ENOTDIR         = syscall.Errno(0x14)
+	ENOTEMPTY       = syscall.Errno(0x42)
+	ENOTRECOVERABLE = syscall.Errno(0x5f)
+	ENOTSOCK        = syscall.Errno(0x26)
+	ENOTSUP         = syscall.Errno(0x2d)
+	ENOTTY          = syscall.Errno(0x19)
+	ENXIO           = syscall.Errno(0x6)
+	EOPNOTSUPP      = syscall.Errno(0x2d)
+	EOVERFLOW       = syscall.Errno(0x54)
+	EOWNERDEAD      = syscall.Errno(0x60)
+	EPERM           = syscall.Errno(0x1)
+	EPFNOSUPPORT    = syscall.Errno(0x2e)
+	EPIPE           = syscall.Errno(0x20)
+	EPROCLIM        = syscall.Errno(0x43)
+	EPROCUNAVAIL    = syscall.Errno(0x4c)
+	EPROGMISMATCH   = syscall.Errno(0x4b)
+	EPROGUNAVAIL    = syscall.Errno(0x4a)
+	EPROTO          = syscall.Errno(0x5c)
+	EPROTONOSUPPORT = syscall.Errno(0x2b)
+	EPROTOTYPE      = syscall.Errno(0x29)
+	ERANGE          = syscall.Errno(0x22)
+	EREMOTE         = syscall.Errno(0x47)
+	EROFS           = syscall.Errno(0x1e)
+	ERPCMISMATCH    = syscall.Errno(0x49)
+	ESHUTDOWN       = syscall.Errno(0x3a)
+	ESOCKTNOSUPPORT = syscall.Errno(0x2c)
+	ESPIPE          = syscall.Errno(0x1d)
+	ESRCH           = syscall.Errno(0x3)
+	ESTALE          = syscall.Errno(0x46)
+	ETIMEDOUT       = syscall.Errno(0x3c)
+	ETOOMANYREFS    = syscall.Errno(0x3b)
+	ETXTBSY         = syscall.Errno(0x1a)
+	EUSERS          = syscall.Errno(0x44)
+	EWOULDBLOCK     = syscall.Errno(0x23)
+	EXDEV           = syscall.Errno(0x12)
+)
+
+// Signals
+const (
+	SIGABRT   = syscall.Signal(0x6)
+	SIGALRM   = syscall.Signal(0xe)
+	SIGBUS    = syscall.Signal(0xa)
+	SIGCHLD   = syscall.Signal(0x14)
+	SIGCONT   = syscall.Signal(0x13)
+	SIGEMT    = syscall.Signal(0x7)
+	SIGFPE    = syscall.Signal(0x8)
+	SIGHUP    = syscall.Signal(0x1)
+	SIGILL    = syscall.Signal(0x4)
+	SIGINFO   = syscall.Signal(0x1d)
+	SIGINT    = syscall.Signal(0x2)
+	SIGIO     = syscall.Signal(0x17)
+	SIGIOT    = syscall.Signal(0x6)
+	SIGKILL   = syscall.Signal(0x9)
+	SIGLIBRT  = syscall.Signal(0x21)
+	SIGLWP    = syscall.Signal(0x20)
+	SIGPIPE   = syscall.Signal(0xd)
+	SIGPROF   = syscall.Signal(0x1b)
+	SIGQUIT   = syscall.Signal(0x3)
+	SIGSEGV   = syscall.Signal(0xb)
+	SIGSTOP   = syscall.Signal(0x11)
+	SIGSYS    = syscall.Signal(0xc)
+	SIGTERM   = syscall.Signal(0xf)
+	SIGTHR    = syscall.Signal(0x20)
+	SIGTRAP   = syscall.Signal(0x5)
+	SIGTSTP   = syscall.Signal(0x12)
+	SIGTTIN   = syscall.Signal(0x15)
+	SIGTTOU   = syscall.Signal(0x16)
+	SIGURG    = syscall.Signal(0x10)
+	SIGUSR1   = syscall.Signal(0x1e)
+	SIGUSR2   = syscall.Signal(0x1f)
+	SIGVTALRM = syscall.Signal(0x1a)
+	SIGWINCH  = syscall.Signal(0x1c)
+	SIGXCPU   = syscall.Signal(0x18)
+	SIGXFSZ   = syscall.Signal(0x19)
+)
+
+// Error table
+var errorList = [...]struct {
+	num  syscall.Errno
+	name string
+	desc string
+}{
+	{1, "EPERM", "operation not permitted"},
+	{2, "ENOENT", "no such file or directory"},
+	{3, "ESRCH", "no such process"},
+	{4, "EINTR", "interrupted system call"},
+	{5, "EIO", "input/output error"},
+	{6, "ENXIO", "device not configured"},
+	{7, "E2BIG", "argument list too long"},
+	{8, "ENOEXEC", "exec format error"},
+	{9, "EBADF", "bad file descriptor"},
+	{10, "ECHILD", "no child processes"},
+	{11, "EDEADLK", "resource deadlock avoided"},
+	{12, "ENOMEM", "cannot allocate memory"},
+	{13, "EACCES", "permission denied"},
+	{14, "EFAULT", "bad address"},
+	{15, "ENOTBLK", "block device required"},
+	{16, "EBUSY", "device busy"},
+	{17, "EEXIST", "file exists"},
+	{18, "EXDEV", "cross-device link"},
+	{19, "ENODEV", "operation not supported by device"},
+	{20, "ENOTDIR", "not a directory"},
+	{21, "EISDIR", "is a directory"},
+	{22, "EINVAL", "invalid argument"},
+	{23, "ENFILE", "too many open files in system"},
+	{24, "EMFILE", "too many open files"},
+	{25, "ENOTTY", "inappropriate ioctl for device"},
+	{26, "ETXTBSY", "text file busy"},
+	{27, "EFBIG", "file too large"},
+	{28, "ENOSPC", "no space left on device"},
+	{29, "ESPIPE", "illegal seek"},
+	{30, "EROFS", "read-only file system"},
+	{31, "EMLINK", "too many links"},
+	{32, "EPIPE", "broken pipe"},
+	{33, "EDOM", "numerical argument out of domain"},
+	{34, "ERANGE", "result too large"},
+	{35, "EWOULDBLOCK", "resource temporarily unavailable"},
+	{36, "EINPROGRESS", "operation now in progress"},
+	{37, "EALREADY", "operation already in progress"},
+	{38, "ENOTSOCK", "socket operation on non-socket"},
+	{39, "EDESTADDRREQ", "destination address required"},
+	{40, "EMSGSIZE", "message too long"},
+	{41, "EPROTOTYPE", "protocol wrong type for socket"},
+	{42, "ENOPROTOOPT", "protocol not available"},
+	{43, "EPROTONOSUPPORT", "protocol not supported"},
+	{44, "ESOCKTNOSUPPORT", "socket type not supported"},
+	{45, "EOPNOTSUPP", "operation not supported"},
+	{46, "EPFNOSUPPORT", "protocol family not supported"},
+	{47, "EAFNOSUPPORT", "address family not supported by protocol family"},
+	{48, "EADDRINUSE", "address already in use"},
+	{49, "EADDRNOTAVAIL", "can't assign requested address"},
+	{50, "ENETDOWN", "network is down"},
+	{51, "ENETUNREACH", "network is unreachable"},
+	{52, "ENETRESET", "network dropped connection on reset"},
+	{53, "ECONNABORTED", "software caused connection abort"},
+	{54, "ECONNRESET", "connection reset by peer"},
+	{55, "ENOBUFS", "no buffer space available"},
+	{56, "EISCONN", "socket is already connected"},
+	{57, "ENOTCONN", "socket is not connected"},
+	{58, "ESHUTDOWN", "can't send after socket shutdown"},
+	{59, "ETOOMANYREFS", "too many references: can't splice"},
+	{60, "ETIMEDOUT", "operation timed out"},
+	{61, "ECONNREFUSED", "connection refused"},
+	{62, "ELOOP", "too many levels of symbolic links"},
+	{63, "ENAMETOOLONG", "file name too long"},
+	{64, "EHOSTDOWN", "host is down"},
+	{65, "EHOSTUNREACH", "no route to host"},
+	{66, "ENOTEMPTY", "directory not empty"},
+	{67, "EPROCLIM", "too many processes"},
+	{68, "EUSERS", "too many users"},
+	{69, "EDQUOT", "disc quota exceeded"},
+	{70, "ESTALE", "stale NFS file handle"},
+	{71, "EREMOTE", "too many levels of remote in path"},
+	{72, "EBADRPC", "RPC struct is bad"},
+	{73, "ERPCMISMATCH", "RPC version wrong"},
+	{74, "EPROGUNAVAIL", "RPC prog. not avail"},
+	{75, "EPROGMISMATCH", "program version wrong"},
+	{76, "EPROCUNAVAIL", "bad procedure for program"},
+	{77, "ENOLCK", "no locks available"},
+	{78, "ENOSYS", "function not implemented"},
+	{79, "EFTYPE", "inappropriate file type or format"},
+	{80, "EAUTH", "authentication error"},
+	{81, "ENEEDAUTH", "need authenticator"},
+	{82, "EIDRM", "identifier removed"},
+	{83, "ENOMSG", "no message of desired type"},
+	{84, "EOVERFLOW", "value too large to be stored in data type"},
+	{85, "ECANCELED", "operation canceled"},
+	{86, "EILSEQ", "illegal byte sequence"},
+	{87, "ENOATTR", "attribute not found"},
+	{88, "EDOOFUS", "programming error"},
+	{89, "EBADMSG", "bad message"},
+	{90, "EMULTIHOP", "multihop attempted"},
+	{91, "ENOLINK", "link has been severed"},
+	{92, "EPROTO", "protocol error"},
+	{93, "ENOTCAPABLE", "capabilities insufficient"},
+	{94, "ECAPMODE", "not permitted in capability mode"},
+	{95, "ENOTRECOVERABLE", "state not recoverable"},
+	{96, "EOWNERDEAD", "previous owner died"},
+	{97, "EINTEGRITY", "integrity check failed"},
+}
+
+// Signal table
+var signalList = [...]struct {
+	num  syscall.Signal
+	name string
+	desc string
+}{
+	{1, "SIGHUP", "hangup"},
+	{2, "SIGINT", "interrupt"},
+	{3, "SIGQUIT", "quit"},
+	{4, "SIGILL", "illegal instruction"},
+	{5, "SIGTRAP", "trace/BPT trap"},
+	{6, "SIGIOT", "abort trap"},
+	{7, "SIGEMT", "EMT trap"},
+	{8, "SIGFPE", "floating point exception"},
+	{9, "SIGKILL", "killed"},
+	{10, "SIGBUS", "bus error"},
+	{11, "SIGSEGV", "segmentation fault"},
+	{12, "SIGSYS", "bad system call"},
+	{13, "SIGPIPE", "broken pipe"},
+	{14, "SIGALRM", "alarm clock"},
+	{15, "SIGTERM", "terminated"},
+	{16, "SIGURG", "urgent I/O condition"},
+	{17, "SIGSTOP", "suspended (signal)"},
+	{18, "SIGTSTP", "suspended"},
+	{19, "SIGCONT", "continued"},
+	{20, "SIGCHLD", "child exited"},
+	{21, "SIGTTIN", "stopped (tty input)"},
+	{22, "SIGTTOU", "stopped (tty output)"},
+	{23, "SIGIO", "I/O possible"},
+	{24, "SIGXCPU", "cputime limit exceeded"},
+	{25, "SIGXFSZ", "filesize limit exceeded"},
+	{26, "SIGVTALRM", "virtual timer expired"},
+	{27, "SIGPROF", "profiling timer expired"},
+	{28, "SIGWINCH", "window size changes"},
+	{29, "SIGINFO", "information request"},
+	{30, "SIGUSR1", "user defined signal 1"},
+	{31, "SIGUSR2", "user defined signal 2"},
+	{32, "SIGTHR", "unknown signal"},
+	{33, "SIGLIBRT", "unknown signal"},
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux.go
index c0a43f8..785d693 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux.go
@@ -140,6 +140,306 @@
 	ARPHRD_VOID                                 = 0xffff
 	ARPHRD_VSOCKMON                             = 0x33a
 	ARPHRD_X25                                  = 0x10f
+	AUDIT_ADD                                   = 0x3eb
+	AUDIT_ADD_RULE                              = 0x3f3
+	AUDIT_ALWAYS                                = 0x2
+	AUDIT_ANOM_ABEND                            = 0x6a5
+	AUDIT_ANOM_CREAT                            = 0x6a7
+	AUDIT_ANOM_LINK                             = 0x6a6
+	AUDIT_ANOM_PROMISCUOUS                      = 0x6a4
+	AUDIT_ARCH                                  = 0xb
+	AUDIT_ARCH_AARCH64                          = 0xc00000b7
+	AUDIT_ARCH_ALPHA                            = 0xc0009026
+	AUDIT_ARCH_ARCOMPACT                        = 0x4000005d
+	AUDIT_ARCH_ARCOMPACTBE                      = 0x5d
+	AUDIT_ARCH_ARCV2                            = 0x400000c3
+	AUDIT_ARCH_ARCV2BE                          = 0xc3
+	AUDIT_ARCH_ARM                              = 0x40000028
+	AUDIT_ARCH_ARMEB                            = 0x28
+	AUDIT_ARCH_C6X                              = 0x4000008c
+	AUDIT_ARCH_C6XBE                            = 0x8c
+	AUDIT_ARCH_CRIS                             = 0x4000004c
+	AUDIT_ARCH_CSKY                             = 0x400000fc
+	AUDIT_ARCH_FRV                              = 0x5441
+	AUDIT_ARCH_H8300                            = 0x2e
+	AUDIT_ARCH_HEXAGON                          = 0xa4
+	AUDIT_ARCH_I386                             = 0x40000003
+	AUDIT_ARCH_IA64                             = 0xc0000032
+	AUDIT_ARCH_LOONGARCH32                      = 0x40000102
+	AUDIT_ARCH_LOONGARCH64                      = 0xc0000102
+	AUDIT_ARCH_M32R                             = 0x58
+	AUDIT_ARCH_M68K                             = 0x4
+	AUDIT_ARCH_MICROBLAZE                       = 0xbd
+	AUDIT_ARCH_MIPS                             = 0x8
+	AUDIT_ARCH_MIPS64                           = 0x80000008
+	AUDIT_ARCH_MIPS64N32                        = 0xa0000008
+	AUDIT_ARCH_MIPSEL                           = 0x40000008
+	AUDIT_ARCH_MIPSEL64                         = 0xc0000008
+	AUDIT_ARCH_MIPSEL64N32                      = 0xe0000008
+	AUDIT_ARCH_NDS32                            = 0x400000a7
+	AUDIT_ARCH_NDS32BE                          = 0xa7
+	AUDIT_ARCH_NIOS2                            = 0x40000071
+	AUDIT_ARCH_OPENRISC                         = 0x5c
+	AUDIT_ARCH_PARISC                           = 0xf
+	AUDIT_ARCH_PARISC64                         = 0x8000000f
+	AUDIT_ARCH_PPC                              = 0x14
+	AUDIT_ARCH_PPC64                            = 0x80000015
+	AUDIT_ARCH_PPC64LE                          = 0xc0000015
+	AUDIT_ARCH_RISCV32                          = 0x400000f3
+	AUDIT_ARCH_RISCV64                          = 0xc00000f3
+	AUDIT_ARCH_S390                             = 0x16
+	AUDIT_ARCH_S390X                            = 0x80000016
+	AUDIT_ARCH_SH                               = 0x2a
+	AUDIT_ARCH_SH64                             = 0x8000002a
+	AUDIT_ARCH_SHEL                             = 0x4000002a
+	AUDIT_ARCH_SHEL64                           = 0xc000002a
+	AUDIT_ARCH_SPARC                            = 0x2
+	AUDIT_ARCH_SPARC64                          = 0x8000002b
+	AUDIT_ARCH_TILEGX                           = 0xc00000bf
+	AUDIT_ARCH_TILEGX32                         = 0x400000bf
+	AUDIT_ARCH_TILEPRO                          = 0x400000bc
+	AUDIT_ARCH_UNICORE                          = 0x4000006e
+	AUDIT_ARCH_X86_64                           = 0xc000003e
+	AUDIT_ARCH_XTENSA                           = 0x5e
+	AUDIT_ARG0                                  = 0xc8
+	AUDIT_ARG1                                  = 0xc9
+	AUDIT_ARG2                                  = 0xca
+	AUDIT_ARG3                                  = 0xcb
+	AUDIT_AVC                                   = 0x578
+	AUDIT_AVC_PATH                              = 0x57a
+	AUDIT_BITMASK_SIZE                          = 0x40
+	AUDIT_BIT_MASK                              = 0x8000000
+	AUDIT_BIT_TEST                              = 0x48000000
+	AUDIT_BPF                                   = 0x536
+	AUDIT_BPRM_FCAPS                            = 0x529
+	AUDIT_CAPSET                                = 0x52a
+	AUDIT_CLASS_CHATTR                          = 0x2
+	AUDIT_CLASS_CHATTR_32                       = 0x3
+	AUDIT_CLASS_DIR_WRITE                       = 0x0
+	AUDIT_CLASS_DIR_WRITE_32                    = 0x1
+	AUDIT_CLASS_READ                            = 0x4
+	AUDIT_CLASS_READ_32                         = 0x5
+	AUDIT_CLASS_SIGNAL                          = 0x8
+	AUDIT_CLASS_SIGNAL_32                       = 0x9
+	AUDIT_CLASS_WRITE                           = 0x6
+	AUDIT_CLASS_WRITE_32                        = 0x7
+	AUDIT_COMPARE_AUID_TO_EUID                  = 0x10
+	AUDIT_COMPARE_AUID_TO_FSUID                 = 0xe
+	AUDIT_COMPARE_AUID_TO_OBJ_UID               = 0x5
+	AUDIT_COMPARE_AUID_TO_SUID                  = 0xf
+	AUDIT_COMPARE_EGID_TO_FSGID                 = 0x17
+	AUDIT_COMPARE_EGID_TO_OBJ_GID               = 0x4
+	AUDIT_COMPARE_EGID_TO_SGID                  = 0x18
+	AUDIT_COMPARE_EUID_TO_FSUID                 = 0x12
+	AUDIT_COMPARE_EUID_TO_OBJ_UID               = 0x3
+	AUDIT_COMPARE_EUID_TO_SUID                  = 0x11
+	AUDIT_COMPARE_FSGID_TO_OBJ_GID              = 0x9
+	AUDIT_COMPARE_FSUID_TO_OBJ_UID              = 0x8
+	AUDIT_COMPARE_GID_TO_EGID                   = 0x14
+	AUDIT_COMPARE_GID_TO_FSGID                  = 0x15
+	AUDIT_COMPARE_GID_TO_OBJ_GID                = 0x2
+	AUDIT_COMPARE_GID_TO_SGID                   = 0x16
+	AUDIT_COMPARE_SGID_TO_FSGID                 = 0x19
+	AUDIT_COMPARE_SGID_TO_OBJ_GID               = 0x7
+	AUDIT_COMPARE_SUID_TO_FSUID                 = 0x13
+	AUDIT_COMPARE_SUID_TO_OBJ_UID               = 0x6
+	AUDIT_COMPARE_UID_TO_AUID                   = 0xa
+	AUDIT_COMPARE_UID_TO_EUID                   = 0xb
+	AUDIT_COMPARE_UID_TO_FSUID                  = 0xc
+	AUDIT_COMPARE_UID_TO_OBJ_UID                = 0x1
+	AUDIT_COMPARE_UID_TO_SUID                   = 0xd
+	AUDIT_CONFIG_CHANGE                         = 0x519
+	AUDIT_CWD                                   = 0x51b
+	AUDIT_DAEMON_ABORT                          = 0x4b2
+	AUDIT_DAEMON_CONFIG                         = 0x4b3
+	AUDIT_DAEMON_END                            = 0x4b1
+	AUDIT_DAEMON_START                          = 0x4b0
+	AUDIT_DEL                                   = 0x3ec
+	AUDIT_DEL_RULE                              = 0x3f4
+	AUDIT_DEVMAJOR                              = 0x64
+	AUDIT_DEVMINOR                              = 0x65
+	AUDIT_DIR                                   = 0x6b
+	AUDIT_DM_CTRL                               = 0x53a
+	AUDIT_DM_EVENT                              = 0x53b
+	AUDIT_EGID                                  = 0x6
+	AUDIT_EOE                                   = 0x528
+	AUDIT_EQUAL                                 = 0x40000000
+	AUDIT_EUID                                  = 0x2
+	AUDIT_EVENT_LISTENER                        = 0x537
+	AUDIT_EXE                                   = 0x70
+	AUDIT_EXECVE                                = 0x51d
+	AUDIT_EXIT                                  = 0x67
+	AUDIT_FAIL_PANIC                            = 0x2
+	AUDIT_FAIL_PRINTK                           = 0x1
+	AUDIT_FAIL_SILENT                           = 0x0
+	AUDIT_FANOTIFY                              = 0x533
+	AUDIT_FD_PAIR                               = 0x525
+	AUDIT_FEATURE_BITMAP_ALL                    = 0x7f
+	AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT          = 0x1
+	AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME      = 0x2
+	AUDIT_FEATURE_BITMAP_EXCLUDE_EXTEND         = 0x8
+	AUDIT_FEATURE_BITMAP_EXECUTABLE_PATH        = 0x4
+	AUDIT_FEATURE_BITMAP_FILTER_FS              = 0x40
+	AUDIT_FEATURE_BITMAP_LOST_RESET             = 0x20
+	AUDIT_FEATURE_BITMAP_SESSIONID_FILTER       = 0x10
+	AUDIT_FEATURE_CHANGE                        = 0x530
+	AUDIT_FEATURE_LOGINUID_IMMUTABLE            = 0x1
+	AUDIT_FEATURE_ONLY_UNSET_LOGINUID           = 0x0
+	AUDIT_FEATURE_VERSION                       = 0x1
+	AUDIT_FIELD_COMPARE                         = 0x6f
+	AUDIT_FILETYPE                              = 0x6c
+	AUDIT_FILTERKEY                             = 0xd2
+	AUDIT_FILTER_ENTRY                          = 0x2
+	AUDIT_FILTER_EXCLUDE                        = 0x5
+	AUDIT_FILTER_EXIT                           = 0x4
+	AUDIT_FILTER_FS                             = 0x6
+	AUDIT_FILTER_PREPEND                        = 0x10
+	AUDIT_FILTER_TASK                           = 0x1
+	AUDIT_FILTER_TYPE                           = 0x5
+	AUDIT_FILTER_URING_EXIT                     = 0x7
+	AUDIT_FILTER_USER                           = 0x0
+	AUDIT_FILTER_WATCH                          = 0x3
+	AUDIT_FIRST_KERN_ANOM_MSG                   = 0x6a4
+	AUDIT_FIRST_USER_MSG                        = 0x44c
+	AUDIT_FIRST_USER_MSG2                       = 0x834
+	AUDIT_FSGID                                 = 0x8
+	AUDIT_FSTYPE                                = 0x1a
+	AUDIT_FSUID                                 = 0x4
+	AUDIT_GET                                   = 0x3e8
+	AUDIT_GET_FEATURE                           = 0x3fb
+	AUDIT_GID                                   = 0x5
+	AUDIT_GREATER_THAN                          = 0x20000000
+	AUDIT_GREATER_THAN_OR_EQUAL                 = 0x60000000
+	AUDIT_INODE                                 = 0x66
+	AUDIT_INTEGRITY_DATA                        = 0x708
+	AUDIT_INTEGRITY_EVM_XATTR                   = 0x70e
+	AUDIT_INTEGRITY_HASH                        = 0x70b
+	AUDIT_INTEGRITY_METADATA                    = 0x709
+	AUDIT_INTEGRITY_PCR                         = 0x70c
+	AUDIT_INTEGRITY_POLICY_RULE                 = 0x70f
+	AUDIT_INTEGRITY_RULE                        = 0x70d
+	AUDIT_INTEGRITY_STATUS                      = 0x70a
+	AUDIT_IPC                                   = 0x517
+	AUDIT_IPC_SET_PERM                          = 0x51f
+	AUDIT_KERNEL                                = 0x7d0
+	AUDIT_KERNEL_OTHER                          = 0x524
+	AUDIT_KERN_MODULE                           = 0x532
+	AUDIT_LAST_FEATURE                          = 0x1
+	AUDIT_LAST_KERN_ANOM_MSG                    = 0x707
+	AUDIT_LAST_USER_MSG                         = 0x4af
+	AUDIT_LAST_USER_MSG2                        = 0xbb7
+	AUDIT_LESS_THAN                             = 0x10000000
+	AUDIT_LESS_THAN_OR_EQUAL                    = 0x50000000
+	AUDIT_LIST                                  = 0x3ea
+	AUDIT_LIST_RULES                            = 0x3f5
+	AUDIT_LOGIN                                 = 0x3ee
+	AUDIT_LOGINUID                              = 0x9
+	AUDIT_LOGINUID_SET                          = 0x18
+	AUDIT_MAC_CALIPSO_ADD                       = 0x58a
+	AUDIT_MAC_CALIPSO_DEL                       = 0x58b
+	AUDIT_MAC_CIPSOV4_ADD                       = 0x57f
+	AUDIT_MAC_CIPSOV4_DEL                       = 0x580
+	AUDIT_MAC_CONFIG_CHANGE                     = 0x57d
+	AUDIT_MAC_IPSEC_ADDSA                       = 0x583
+	AUDIT_MAC_IPSEC_ADDSPD                      = 0x585
+	AUDIT_MAC_IPSEC_DELSA                       = 0x584
+	AUDIT_MAC_IPSEC_DELSPD                      = 0x586
+	AUDIT_MAC_IPSEC_EVENT                       = 0x587
+	AUDIT_MAC_MAP_ADD                           = 0x581
+	AUDIT_MAC_MAP_DEL                           = 0x582
+	AUDIT_MAC_POLICY_LOAD                       = 0x57b
+	AUDIT_MAC_STATUS                            = 0x57c
+	AUDIT_MAC_UNLBL_ALLOW                       = 0x57e
+	AUDIT_MAC_UNLBL_STCADD                      = 0x588
+	AUDIT_MAC_UNLBL_STCDEL                      = 0x589
+	AUDIT_MAKE_EQUIV                            = 0x3f7
+	AUDIT_MAX_FIELDS                            = 0x40
+	AUDIT_MAX_FIELD_COMPARE                     = 0x19
+	AUDIT_MAX_KEY_LEN                           = 0x100
+	AUDIT_MESSAGE_TEXT_MAX                      = 0x2170
+	AUDIT_MMAP                                  = 0x52b
+	AUDIT_MQ_GETSETATTR                         = 0x523
+	AUDIT_MQ_NOTIFY                             = 0x522
+	AUDIT_MQ_OPEN                               = 0x520
+	AUDIT_MQ_SENDRECV                           = 0x521
+	AUDIT_MSGTYPE                               = 0xc
+	AUDIT_NEGATE                                = 0x80000000
+	AUDIT_NETFILTER_CFG                         = 0x52d
+	AUDIT_NETFILTER_PKT                         = 0x52c
+	AUDIT_NEVER                                 = 0x0
+	AUDIT_NLGRP_MAX                             = 0x1
+	AUDIT_NOT_EQUAL                             = 0x30000000
+	AUDIT_NR_FILTERS                            = 0x8
+	AUDIT_OBJ_GID                               = 0x6e
+	AUDIT_OBJ_LEV_HIGH                          = 0x17
+	AUDIT_OBJ_LEV_LOW                           = 0x16
+	AUDIT_OBJ_PID                               = 0x526
+	AUDIT_OBJ_ROLE                              = 0x14
+	AUDIT_OBJ_TYPE                              = 0x15
+	AUDIT_OBJ_UID                               = 0x6d
+	AUDIT_OBJ_USER                              = 0x13
+	AUDIT_OPENAT2                               = 0x539
+	AUDIT_OPERATORS                             = 0x78000000
+	AUDIT_PATH                                  = 0x516
+	AUDIT_PERM                                  = 0x6a
+	AUDIT_PERM_ATTR                             = 0x8
+	AUDIT_PERM_EXEC                             = 0x1
+	AUDIT_PERM_READ                             = 0x4
+	AUDIT_PERM_WRITE                            = 0x2
+	AUDIT_PERS                                  = 0xa
+	AUDIT_PID                                   = 0x0
+	AUDIT_POSSIBLE                              = 0x1
+	AUDIT_PPID                                  = 0x12
+	AUDIT_PROCTITLE                             = 0x52f
+	AUDIT_REPLACE                               = 0x531
+	AUDIT_SADDR_FAM                             = 0x71
+	AUDIT_SECCOMP                               = 0x52e
+	AUDIT_SELINUX_ERR                           = 0x579
+	AUDIT_SESSIONID                             = 0x19
+	AUDIT_SET                                   = 0x3e9
+	AUDIT_SET_FEATURE                           = 0x3fa
+	AUDIT_SGID                                  = 0x7
+	AUDIT_SID_UNSET                             = 0xffffffff
+	AUDIT_SIGNAL_INFO                           = 0x3f2
+	AUDIT_SOCKADDR                              = 0x51a
+	AUDIT_SOCKETCALL                            = 0x518
+	AUDIT_STATUS_BACKLOG_LIMIT                  = 0x10
+	AUDIT_STATUS_BACKLOG_WAIT_TIME              = 0x20
+	AUDIT_STATUS_BACKLOG_WAIT_TIME_ACTUAL       = 0x80
+	AUDIT_STATUS_ENABLED                        = 0x1
+	AUDIT_STATUS_FAILURE                        = 0x2
+	AUDIT_STATUS_LOST                           = 0x40
+	AUDIT_STATUS_PID                            = 0x4
+	AUDIT_STATUS_RATE_LIMIT                     = 0x8
+	AUDIT_SUBJ_CLR                              = 0x11
+	AUDIT_SUBJ_ROLE                             = 0xe
+	AUDIT_SUBJ_SEN                              = 0x10
+	AUDIT_SUBJ_TYPE                             = 0xf
+	AUDIT_SUBJ_USER                             = 0xd
+	AUDIT_SUCCESS                               = 0x68
+	AUDIT_SUID                                  = 0x3
+	AUDIT_SYSCALL                               = 0x514
+	AUDIT_SYSCALL_CLASSES                       = 0x10
+	AUDIT_TIME_ADJNTPVAL                        = 0x535
+	AUDIT_TIME_INJOFFSET                        = 0x534
+	AUDIT_TRIM                                  = 0x3f6
+	AUDIT_TTY                                   = 0x527
+	AUDIT_TTY_GET                               = 0x3f8
+	AUDIT_TTY_SET                               = 0x3f9
+	AUDIT_UID                                   = 0x1
+	AUDIT_UID_UNSET                             = 0xffffffff
+	AUDIT_UNUSED_BITS                           = 0x7fffc00
+	AUDIT_URINGOP                               = 0x538
+	AUDIT_USER                                  = 0x3ed
+	AUDIT_USER_AVC                              = 0x453
+	AUDIT_USER_TTY                              = 0x464
+	AUDIT_VERSION_BACKLOG_LIMIT                 = 0x1
+	AUDIT_VERSION_BACKLOG_WAIT_TIME             = 0x2
+	AUDIT_VERSION_LATEST                        = 0x7f
+	AUDIT_WATCH                                 = 0x69
+	AUDIT_WATCH_INS                             = 0x3ef
+	AUDIT_WATCH_LIST                            = 0x3f1
+	AUDIT_WATCH_REM                             = 0x3f0
 	AUTOFS_SUPER_MAGIC                          = 0x187
 	B0                                          = 0x0
 	B110                                        = 0x3
@@ -184,6 +484,7 @@
 	BPF_F_ALLOW_MULTI                           = 0x2
 	BPF_F_ALLOW_OVERRIDE                        = 0x1
 	BPF_F_ANY_ALIGNMENT                         = 0x2
+	BPF_F_KPROBE_MULTI_RETURN                   = 0x1
 	BPF_F_QUERY_EFFECTIVE                       = 0x1
 	BPF_F_REPLACE                               = 0x4
 	BPF_F_SLEEPABLE                             = 0x10
@@ -191,6 +492,8 @@
 	BPF_F_TEST_RND_HI32                         = 0x4
 	BPF_F_TEST_RUN_ON_CPU                       = 0x1
 	BPF_F_TEST_STATE_FREQ                       = 0x8
+	BPF_F_TEST_XDP_LIVE_FRAMES                  = 0x2
+	BPF_F_XDP_HAS_FRAGS                         = 0x20
 	BPF_H                                       = 0x8
 	BPF_IMM                                     = 0x0
 	BPF_IND                                     = 0x40
@@ -517,9 +820,9 @@
 	DM_UUID_FLAG                                = 0x4000
 	DM_UUID_LEN                                 = 0x81
 	DM_VERSION                                  = 0xc138fd00
-	DM_VERSION_EXTRA                            = "-ioctl (2021-03-22)"
+	DM_VERSION_EXTRA                            = "-ioctl (2022-02-22)"
 	DM_VERSION_MAJOR                            = 0x4
-	DM_VERSION_MINOR                            = 0x2d
+	DM_VERSION_MINOR                            = 0x2e
 	DM_VERSION_PATCHLEVEL                       = 0x0
 	DT_BLK                                      = 0x6
 	DT_CHR                                      = 0x2
@@ -535,6 +838,55 @@
 	EFD_SEMAPHORE                               = 0x1
 	EFIVARFS_MAGIC                              = 0xde5e81e4
 	EFS_SUPER_MAGIC                             = 0x414a53
+	EM_386                                      = 0x3
+	EM_486                                      = 0x6
+	EM_68K                                      = 0x4
+	EM_860                                      = 0x7
+	EM_88K                                      = 0x5
+	EM_AARCH64                                  = 0xb7
+	EM_ALPHA                                    = 0x9026
+	EM_ALTERA_NIOS2                             = 0x71
+	EM_ARCOMPACT                                = 0x5d
+	EM_ARCV2                                    = 0xc3
+	EM_ARM                                      = 0x28
+	EM_BLACKFIN                                 = 0x6a
+	EM_BPF                                      = 0xf7
+	EM_CRIS                                     = 0x4c
+	EM_CSKY                                     = 0xfc
+	EM_CYGNUS_M32R                              = 0x9041
+	EM_CYGNUS_MN10300                           = 0xbeef
+	EM_FRV                                      = 0x5441
+	EM_H8_300                                   = 0x2e
+	EM_HEXAGON                                  = 0xa4
+	EM_IA_64                                    = 0x32
+	EM_LOONGARCH                                = 0x102
+	EM_M32                                      = 0x1
+	EM_M32R                                     = 0x58
+	EM_MICROBLAZE                               = 0xbd
+	EM_MIPS                                     = 0x8
+	EM_MIPS_RS3_LE                              = 0xa
+	EM_MIPS_RS4_BE                              = 0xa
+	EM_MN10300                                  = 0x59
+	EM_NDS32                                    = 0xa7
+	EM_NONE                                     = 0x0
+	EM_OPENRISC                                 = 0x5c
+	EM_PARISC                                   = 0xf
+	EM_PPC                                      = 0x14
+	EM_PPC64                                    = 0x15
+	EM_RISCV                                    = 0xf3
+	EM_S390                                     = 0x16
+	EM_S390_OLD                                 = 0xa390
+	EM_SH                                       = 0x2a
+	EM_SPARC                                    = 0x2
+	EM_SPARC32PLUS                              = 0x12
+	EM_SPARCV9                                  = 0x2b
+	EM_SPU                                      = 0x17
+	EM_TILEGX                                   = 0xbf
+	EM_TILEPRO                                  = 0xbc
+	EM_TI_C6000                                 = 0x8c
+	EM_UNICORE                                  = 0x6e
+	EM_X86_64                                   = 0x3e
+	EM_XTENSA                                   = 0x5e
 	ENCODING_DEFAULT                            = 0x0
 	ENCODING_FM_MARK                            = 0x3
 	ENCODING_FM_SPACE                           = 0x4
@@ -712,6 +1064,7 @@
 	ETH_P_EDSA                                  = 0xdada
 	ETH_P_ERSPAN                                = 0x88be
 	ETH_P_ERSPAN2                               = 0x22eb
+	ETH_P_ETHERCAT                              = 0x88a4
 	ETH_P_FCOE                                  = 0x8906
 	ETH_P_FIP                                   = 0x8914
 	ETH_P_HDLC                                  = 0x19
@@ -749,6 +1102,7 @@
 	ETH_P_PPP_MP                                = 0x8
 	ETH_P_PPP_SES                               = 0x8864
 	ETH_P_PREAUTH                               = 0x88c7
+	ETH_P_PROFINET                              = 0x8892
 	ETH_P_PRP                                   = 0x88fb
 	ETH_P_PUP                                   = 0x200
 	ETH_P_PUPAT                                 = 0x201
@@ -837,6 +1191,7 @@
 	FAN_FS_ERROR                                = 0x8000
 	FAN_MARK_ADD                                = 0x1
 	FAN_MARK_DONT_FOLLOW                        = 0x4
+	FAN_MARK_EVICTABLE                          = 0x200
 	FAN_MARK_FILESYSTEM                         = 0x100
 	FAN_MARK_FLUSH                              = 0x80
 	FAN_MARK_IGNORED_MASK                       = 0x20
@@ -1055,7 +1410,7 @@
 	IFA_F_STABLE_PRIVACY                        = 0x800
 	IFA_F_TEMPORARY                             = 0x1
 	IFA_F_TENTATIVE                             = 0x40
-	IFA_MAX                                     = 0xa
+	IFA_MAX                                     = 0xb
 	IFF_ALLMULTI                                = 0x200
 	IFF_ATTACH_QUEUE                            = 0x200
 	IFF_AUTOMEDIA                               = 0x4000
@@ -1403,6 +1758,7 @@
 	LANDLOCK_ACCESS_FS_MAKE_SYM                 = 0x1000
 	LANDLOCK_ACCESS_FS_READ_DIR                 = 0x8
 	LANDLOCK_ACCESS_FS_READ_FILE                = 0x4
+	LANDLOCK_ACCESS_FS_REFER                    = 0x2000
 	LANDLOCK_ACCESS_FS_REMOVE_DIR               = 0x10
 	LANDLOCK_ACCESS_FS_REMOVE_FILE              = 0x20
 	LANDLOCK_ACCESS_FS_WRITE_FILE               = 0x2
@@ -1758,6 +2114,7 @@
 	NLM_F_ACK_TLVS                              = 0x200
 	NLM_F_APPEND                                = 0x800
 	NLM_F_ATOMIC                                = 0x400
+	NLM_F_BULK                                  = 0x200
 	NLM_F_CAPPED                                = 0x100
 	NLM_F_CREATE                                = 0x400
 	NLM_F_DUMP                                  = 0x300
@@ -2075,6 +2432,11 @@
 	PR_SET_UNALIGN                              = 0x6
 	PR_SET_VMA                                  = 0x53564d41
 	PR_SET_VMA_ANON_NAME                        = 0x0
+	PR_SME_GET_VL                               = 0x40
+	PR_SME_SET_VL                               = 0x3f
+	PR_SME_SET_VL_ONEXEC                        = 0x40000
+	PR_SME_VL_INHERIT                           = 0x20000
+	PR_SME_VL_LEN_MASK                          = 0xffff
 	PR_SPEC_DISABLE                             = 0x4
 	PR_SPEC_DISABLE_NOEXEC                      = 0x10
 	PR_SPEC_ENABLE                              = 0x2
@@ -2227,8 +2589,9 @@
 	RTC_FEATURE_ALARM                           = 0x0
 	RTC_FEATURE_ALARM_RES_2S                    = 0x3
 	RTC_FEATURE_ALARM_RES_MINUTE                = 0x1
+	RTC_FEATURE_ALARM_WAKEUP_ONLY               = 0x7
 	RTC_FEATURE_BACKUP_SWITCH_MODE              = 0x6
-	RTC_FEATURE_CNT                             = 0x7
+	RTC_FEATURE_CNT                             = 0x8
 	RTC_FEATURE_CORRECTION                      = 0x5
 	RTC_FEATURE_NEED_WEEK_DAY                   = 0x2
 	RTC_FEATURE_UPDATE_INTERRUPT                = 0x4
@@ -2302,6 +2665,7 @@
 	RTM_DELRULE                                 = 0x21
 	RTM_DELTCLASS                               = 0x29
 	RTM_DELTFILTER                              = 0x2d
+	RTM_DELTUNNEL                               = 0x79
 	RTM_DELVLAN                                 = 0x71
 	RTM_F_CLONED                                = 0x200
 	RTM_F_EQUALIZE                              = 0x400
@@ -2334,8 +2698,9 @@
 	RTM_GETSTATS                                = 0x5e
 	RTM_GETTCLASS                               = 0x2a
 	RTM_GETTFILTER                              = 0x2e
+	RTM_GETTUNNEL                               = 0x7a
 	RTM_GETVLAN                                 = 0x72
-	RTM_MAX                                     = 0x77
+	RTM_MAX                                     = 0x7b
 	RTM_NEWACTION                               = 0x30
 	RTM_NEWADDR                                 = 0x14
 	RTM_NEWADDRLABEL                            = 0x48
@@ -2359,11 +2724,13 @@
 	RTM_NEWSTATS                                = 0x5c
 	RTM_NEWTCLASS                               = 0x28
 	RTM_NEWTFILTER                              = 0x2c
-	RTM_NR_FAMILIES                             = 0x1a
-	RTM_NR_MSGTYPES                             = 0x68
+	RTM_NEWTUNNEL                               = 0x78
+	RTM_NR_FAMILIES                             = 0x1b
+	RTM_NR_MSGTYPES                             = 0x6c
 	RTM_SETDCB                                  = 0x4f
 	RTM_SETLINK                                 = 0x13
 	RTM_SETNEIGHTBL                             = 0x43
+	RTM_SETSTATS                                = 0x5f
 	RTNH_ALIGNTO                                = 0x4
 	RTNH_COMPARE_MASK                           = 0x59
 	RTNH_F_DEAD                                 = 0x1
@@ -2544,6 +2911,9 @@
 	SOCK_RDM                                    = 0x4
 	SOCK_SEQPACKET                              = 0x5
 	SOCK_SNDBUF_LOCK                            = 0x1
+	SOCK_TXREHASH_DEFAULT                       = 0xff
+	SOCK_TXREHASH_DISABLED                      = 0x0
+	SOCK_TXREHASH_ENABLED                       = 0x1
 	SOL_AAL                                     = 0x109
 	SOL_ALG                                     = 0x117
 	SOL_ATM                                     = 0x108
@@ -2559,6 +2929,8 @@
 	SOL_IUCV                                    = 0x115
 	SOL_KCM                                     = 0x119
 	SOL_LLC                                     = 0x10c
+	SOL_MCTP                                    = 0x11d
+	SOL_MPTCP                                   = 0x11c
 	SOL_NETBEUI                                 = 0x10b
 	SOL_NETLINK                                 = 0x10e
 	SOL_NFC                                     = 0x118
@@ -2568,6 +2940,7 @@
 	SOL_RAW                                     = 0xff
 	SOL_RDS                                     = 0x114
 	SOL_RXRPC                                   = 0x110
+	SOL_SMC                                     = 0x11e
 	SOL_TCP                                     = 0x6
 	SOL_TIPC                                    = 0x10f
 	SOL_TLS                                     = 0x11a
@@ -2674,7 +3047,7 @@
 	TASKSTATS_GENL_NAME                         = "TASKSTATS"
 	TASKSTATS_GENL_VERSION                      = 0x1
 	TASKSTATS_TYPE_MAX                          = 0x6
-	TASKSTATS_VERSION                           = 0xb
+	TASKSTATS_VERSION                           = 0xd
 	TCIFLUSH                                    = 0x0
 	TCIOFF                                      = 0x2
 	TCIOFLUSH                                   = 0x2
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_386.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_386.go
index 1b305fa..36c0dfc 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_386.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_386.go
@@ -1,11 +1,11 @@
-// mkerrors.sh -Wall -Werror -static -I/tmp/include -m32
+// mkerrors.sh -Wall -Werror -static -I/tmp/386/include -m32
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build 386 && linux
 // +build 386,linux
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include -m32 _const.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/386/include -m32 _const.go
 
 package unix
 
@@ -326,6 +326,7 @@
 	SO_RCVBUF                        = 0x8
 	SO_RCVBUFFORCE                   = 0x21
 	SO_RCVLOWAT                      = 0x12
+	SO_RCVMARK                       = 0x4b
 	SO_RCVTIMEO                      = 0x14
 	SO_RCVTIMEO_NEW                  = 0x42
 	SO_RCVTIMEO_OLD                  = 0x14
@@ -350,6 +351,7 @@
 	SO_TIMESTAMPNS_NEW               = 0x40
 	SO_TIMESTAMPNS_OLD               = 0x23
 	SO_TIMESTAMP_NEW                 = 0x3f
+	SO_TXREHASH                      = 0x4a
 	SO_TXTIME                        = 0x3d
 	SO_TYPE                          = 0x3
 	SO_WIFI_STATUS                   = 0x29
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
index 6bcdef5..4ff9427 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go
@@ -1,11 +1,11 @@
-// mkerrors.sh -Wall -Werror -static -I/tmp/include -m64
+// mkerrors.sh -Wall -Werror -static -I/tmp/amd64/include -m64
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build amd64 && linux
 // +build amd64,linux
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include -m64 _const.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/amd64/include -m64 _const.go
 
 package unix
 
@@ -327,6 +327,7 @@
 	SO_RCVBUF                        = 0x8
 	SO_RCVBUFFORCE                   = 0x21
 	SO_RCVLOWAT                      = 0x12
+	SO_RCVMARK                       = 0x4b
 	SO_RCVTIMEO                      = 0x14
 	SO_RCVTIMEO_NEW                  = 0x42
 	SO_RCVTIMEO_OLD                  = 0x14
@@ -351,6 +352,7 @@
 	SO_TIMESTAMPNS_NEW               = 0x40
 	SO_TIMESTAMPNS_OLD               = 0x23
 	SO_TIMESTAMP_NEW                 = 0x3f
+	SO_TXREHASH                      = 0x4a
 	SO_TXTIME                        = 0x3d
 	SO_TYPE                          = 0x3
 	SO_WIFI_STATUS                   = 0x29
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go
index e65df0f..3eaa0fb 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go
@@ -1,11 +1,11 @@
-// mkerrors.sh -Wall -Werror -static -I/tmp/include
+// mkerrors.sh -Wall -Werror -static -I/tmp/arm/include
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build arm && linux
 // +build arm,linux
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/arm/include _const.go
 
 package unix
 
@@ -333,6 +333,7 @@
 	SO_RCVBUF                        = 0x8
 	SO_RCVBUFFORCE                   = 0x21
 	SO_RCVLOWAT                      = 0x12
+	SO_RCVMARK                       = 0x4b
 	SO_RCVTIMEO                      = 0x14
 	SO_RCVTIMEO_NEW                  = 0x42
 	SO_RCVTIMEO_OLD                  = 0x14
@@ -357,6 +358,7 @@
 	SO_TIMESTAMPNS_NEW               = 0x40
 	SO_TIMESTAMPNS_OLD               = 0x23
 	SO_TIMESTAMP_NEW                 = 0x3f
+	SO_TXREHASH                      = 0x4a
 	SO_TXTIME                        = 0x3d
 	SO_TYPE                          = 0x3
 	SO_WIFI_STATUS                   = 0x29
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go
index c702111..d7995bd 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go
@@ -1,11 +1,11 @@
-// mkerrors.sh -Wall -Werror -static -I/tmp/include -fsigned-char
+// mkerrors.sh -Wall -Werror -static -I/tmp/arm64/include -fsigned-char
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build arm64 && linux
 // +build arm64,linux
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include -fsigned-char _const.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/arm64/include -fsigned-char _const.go
 
 package unix
 
@@ -323,6 +323,7 @@
 	SO_RCVBUF                        = 0x8
 	SO_RCVBUFFORCE                   = 0x21
 	SO_RCVLOWAT                      = 0x12
+	SO_RCVMARK                       = 0x4b
 	SO_RCVTIMEO                      = 0x14
 	SO_RCVTIMEO_NEW                  = 0x42
 	SO_RCVTIMEO_OLD                  = 0x14
@@ -347,6 +348,7 @@
 	SO_TIMESTAMPNS_NEW               = 0x40
 	SO_TIMESTAMPNS_OLD               = 0x23
 	SO_TIMESTAMP_NEW                 = 0x3f
+	SO_TXREHASH                      = 0x4a
 	SO_TXTIME                        = 0x3d
 	SO_TYPE                          = 0x3
 	SO_WIFI_STATUS                   = 0x29
@@ -511,6 +513,7 @@
 	WORDSIZE                         = 0x40
 	XCASE                            = 0x4
 	XTABS                            = 0x1800
+	ZA_MAGIC                         = 0x54366345
 	_HIDIOCGRAWNAME                  = 0x80804804
 	_HIDIOCGRAWPHYS                  = 0x80404805
 	_HIDIOCGRAWUNIQ                  = 0x80404808
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go
index 0d83a1c..928e24c 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go
@@ -1,11 +1,11 @@
-// mkerrors.sh -Wall -Werror -static -I/tmp/include
+// mkerrors.sh -Wall -Werror -static -I/tmp/loong64/include
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build loong64 && linux
 // +build loong64,linux
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/loong64/include _const.go
 
 package unix
 
@@ -109,8 +109,6 @@
 	IUCLC                            = 0x200
 	IXOFF                            = 0x1000
 	IXON                             = 0x400
-	LASX_CTX_MAGIC                   = 0x41535801
-	LSX_CTX_MAGIC                    = 0x53580001
 	MAP_ANON                         = 0x20
 	MAP_ANONYMOUS                    = 0x20
 	MAP_DENYWRITE                    = 0x800
@@ -319,6 +317,7 @@
 	SO_RCVBUF                        = 0x8
 	SO_RCVBUFFORCE                   = 0x21
 	SO_RCVLOWAT                      = 0x12
+	SO_RCVMARK                       = 0x4b
 	SO_RCVTIMEO                      = 0x14
 	SO_RCVTIMEO_NEW                  = 0x42
 	SO_RCVTIMEO_OLD                  = 0x14
@@ -343,6 +342,7 @@
 	SO_TIMESTAMPNS_NEW               = 0x40
 	SO_TIMESTAMPNS_OLD               = 0x23
 	SO_TIMESTAMP_NEW                 = 0x3f
+	SO_TXREHASH                      = 0x4a
 	SO_TXTIME                        = 0x3d
 	SO_TYPE                          = 0x3
 	SO_WIFI_STATUS                   = 0x29
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go
index 7f44a49..179bffb 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go
@@ -1,11 +1,11 @@
-// mkerrors.sh -Wall -Werror -static -I/tmp/include
+// mkerrors.sh -Wall -Werror -static -I/tmp/mips/include
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build mips && linux
 // +build mips,linux
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/mips/include _const.go
 
 package unix
 
@@ -326,6 +326,7 @@
 	SO_RCVBUF                        = 0x1002
 	SO_RCVBUFFORCE                   = 0x21
 	SO_RCVLOWAT                      = 0x1004
+	SO_RCVMARK                       = 0x4b
 	SO_RCVTIMEO                      = 0x1006
 	SO_RCVTIMEO_NEW                  = 0x42
 	SO_RCVTIMEO_OLD                  = 0x1006
@@ -351,6 +352,7 @@
 	SO_TIMESTAMPNS_NEW               = 0x40
 	SO_TIMESTAMPNS_OLD               = 0x23
 	SO_TIMESTAMP_NEW                 = 0x3f
+	SO_TXREHASH                      = 0x4a
 	SO_TXTIME                        = 0x3d
 	SO_TYPE                          = 0x1008
 	SO_WIFI_STATUS                   = 0x29
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go
index 2f92b4e..1fba17b 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go
@@ -1,11 +1,11 @@
-// mkerrors.sh -Wall -Werror -static -I/tmp/include
+// mkerrors.sh -Wall -Werror -static -I/tmp/mips64/include
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build mips64 && linux
 // +build mips64,linux
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/mips64/include _const.go
 
 package unix
 
@@ -326,6 +326,7 @@
 	SO_RCVBUF                        = 0x1002
 	SO_RCVBUFFORCE                   = 0x21
 	SO_RCVLOWAT                      = 0x1004
+	SO_RCVMARK                       = 0x4b
 	SO_RCVTIMEO                      = 0x1006
 	SO_RCVTIMEO_NEW                  = 0x42
 	SO_RCVTIMEO_OLD                  = 0x1006
@@ -351,6 +352,7 @@
 	SO_TIMESTAMPNS_NEW               = 0x40
 	SO_TIMESTAMPNS_OLD               = 0x23
 	SO_TIMESTAMP_NEW                 = 0x3f
+	SO_TXREHASH                      = 0x4a
 	SO_TXTIME                        = 0x3d
 	SO_TYPE                          = 0x1008
 	SO_WIFI_STATUS                   = 0x29
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go
index f5367a9..b77dde3 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go
@@ -1,11 +1,11 @@
-// mkerrors.sh -Wall -Werror -static -I/tmp/include
+// mkerrors.sh -Wall -Werror -static -I/tmp/mips64le/include
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build mips64le && linux
 // +build mips64le,linux
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/mips64le/include _const.go
 
 package unix
 
@@ -326,6 +326,7 @@
 	SO_RCVBUF                        = 0x1002
 	SO_RCVBUFFORCE                   = 0x21
 	SO_RCVLOWAT                      = 0x1004
+	SO_RCVMARK                       = 0x4b
 	SO_RCVTIMEO                      = 0x1006
 	SO_RCVTIMEO_NEW                  = 0x42
 	SO_RCVTIMEO_OLD                  = 0x1006
@@ -351,6 +352,7 @@
 	SO_TIMESTAMPNS_NEW               = 0x40
 	SO_TIMESTAMPNS_OLD               = 0x23
 	SO_TIMESTAMP_NEW                 = 0x3f
+	SO_TXREHASH                      = 0x4a
 	SO_TXTIME                        = 0x3d
 	SO_TYPE                          = 0x1008
 	SO_WIFI_STATUS                   = 0x29
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go
index 2e22337..78c6c75 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go
@@ -1,11 +1,11 @@
-// mkerrors.sh -Wall -Werror -static -I/tmp/include
+// mkerrors.sh -Wall -Werror -static -I/tmp/mipsle/include
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build mipsle && linux
 // +build mipsle,linux
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/mipsle/include _const.go
 
 package unix
 
@@ -326,6 +326,7 @@
 	SO_RCVBUF                        = 0x1002
 	SO_RCVBUFFORCE                   = 0x21
 	SO_RCVLOWAT                      = 0x1004
+	SO_RCVMARK                       = 0x4b
 	SO_RCVTIMEO                      = 0x1006
 	SO_RCVTIMEO_NEW                  = 0x42
 	SO_RCVTIMEO_OLD                  = 0x1006
@@ -351,6 +352,7 @@
 	SO_TIMESTAMPNS_NEW               = 0x40
 	SO_TIMESTAMPNS_OLD               = 0x23
 	SO_TIMESTAMP_NEW                 = 0x3f
+	SO_TXREHASH                      = 0x4a
 	SO_TXTIME                        = 0x3d
 	SO_TYPE                          = 0x1008
 	SO_WIFI_STATUS                   = 0x29
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go
index 858c4f3..1c0d31f 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go
@@ -1,11 +1,11 @@
-// mkerrors.sh -Wall -Werror -static -I/tmp/include
+// mkerrors.sh -Wall -Werror -static -I/tmp/ppc/include
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build ppc && linux
 // +build ppc,linux
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/ppc/include _const.go
 
 package unix
 
@@ -381,6 +381,7 @@
 	SO_RCVBUF                        = 0x8
 	SO_RCVBUFFORCE                   = 0x21
 	SO_RCVLOWAT                      = 0x10
+	SO_RCVMARK                       = 0x4b
 	SO_RCVTIMEO                      = 0x12
 	SO_RCVTIMEO_NEW                  = 0x42
 	SO_RCVTIMEO_OLD                  = 0x12
@@ -405,6 +406,7 @@
 	SO_TIMESTAMPNS_NEW               = 0x40
 	SO_TIMESTAMPNS_OLD               = 0x23
 	SO_TIMESTAMP_NEW                 = 0x3f
+	SO_TXREHASH                      = 0x4a
 	SO_TXTIME                        = 0x3d
 	SO_TYPE                          = 0x3
 	SO_WIFI_STATUS                   = 0x29
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go
index af2a7ba..959dd9b 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go
@@ -1,11 +1,11 @@
-// mkerrors.sh -Wall -Werror -static -I/tmp/include
+// mkerrors.sh -Wall -Werror -static -I/tmp/ppc64/include
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build ppc64 && linux
 // +build ppc64,linux
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/ppc64/include _const.go
 
 package unix
 
@@ -385,6 +385,7 @@
 	SO_RCVBUF                        = 0x8
 	SO_RCVBUFFORCE                   = 0x21
 	SO_RCVLOWAT                      = 0x10
+	SO_RCVMARK                       = 0x4b
 	SO_RCVTIMEO                      = 0x12
 	SO_RCVTIMEO_NEW                  = 0x42
 	SO_RCVTIMEO_OLD                  = 0x12
@@ -409,6 +410,7 @@
 	SO_TIMESTAMPNS_NEW               = 0x40
 	SO_TIMESTAMPNS_OLD               = 0x23
 	SO_TIMESTAMP_NEW                 = 0x3f
+	SO_TXREHASH                      = 0x4a
 	SO_TXTIME                        = 0x3d
 	SO_TYPE                          = 0x3
 	SO_WIFI_STATUS                   = 0x29
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go
index eaa2eb8..5a873cd 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go
@@ -1,11 +1,11 @@
-// mkerrors.sh -Wall -Werror -static -I/tmp/include
+// mkerrors.sh -Wall -Werror -static -I/tmp/ppc64le/include
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build ppc64le && linux
 // +build ppc64le,linux
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/ppc64le/include _const.go
 
 package unix
 
@@ -385,6 +385,7 @@
 	SO_RCVBUF                        = 0x8
 	SO_RCVBUFFORCE                   = 0x21
 	SO_RCVLOWAT                      = 0x10
+	SO_RCVMARK                       = 0x4b
 	SO_RCVTIMEO                      = 0x12
 	SO_RCVTIMEO_NEW                  = 0x42
 	SO_RCVTIMEO_OLD                  = 0x12
@@ -409,6 +410,7 @@
 	SO_TIMESTAMPNS_NEW               = 0x40
 	SO_TIMESTAMPNS_OLD               = 0x23
 	SO_TIMESTAMP_NEW                 = 0x3f
+	SO_TXREHASH                      = 0x4a
 	SO_TXTIME                        = 0x3d
 	SO_TYPE                          = 0x3
 	SO_WIFI_STATUS                   = 0x29
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go
index faaa9f0..e336d14 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go
@@ -1,11 +1,11 @@
-// mkerrors.sh -Wall -Werror -static -I/tmp/include
+// mkerrors.sh -Wall -Werror -static -I/tmp/riscv64/include
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build riscv64 && linux
 // +build riscv64,linux
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/riscv64/include _const.go
 
 package unix
 
@@ -314,6 +314,7 @@
 	SO_RCVBUF                        = 0x8
 	SO_RCVBUFFORCE                   = 0x21
 	SO_RCVLOWAT                      = 0x12
+	SO_RCVMARK                       = 0x4b
 	SO_RCVTIMEO                      = 0x14
 	SO_RCVTIMEO_NEW                  = 0x42
 	SO_RCVTIMEO_OLD                  = 0x14
@@ -338,6 +339,7 @@
 	SO_TIMESTAMPNS_NEW               = 0x40
 	SO_TIMESTAMPNS_OLD               = 0x23
 	SO_TIMESTAMP_NEW                 = 0x3f
+	SO_TXREHASH                      = 0x4a
 	SO_TXTIME                        = 0x3d
 	SO_TYPE                          = 0x3
 	SO_WIFI_STATUS                   = 0x29
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go
index 0d161f0..390c01d 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go
@@ -1,11 +1,11 @@
-// mkerrors.sh -Wall -Werror -static -I/tmp/include -fsigned-char
+// mkerrors.sh -Wall -Werror -static -I/tmp/s390x/include -fsigned-char
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build s390x && linux
 // +build s390x,linux
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include -fsigned-char _const.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/s390x/include -fsigned-char _const.go
 
 package unix
 
@@ -389,6 +389,7 @@
 	SO_RCVBUF                        = 0x8
 	SO_RCVBUFFORCE                   = 0x21
 	SO_RCVLOWAT                      = 0x12
+	SO_RCVMARK                       = 0x4b
 	SO_RCVTIMEO                      = 0x14
 	SO_RCVTIMEO_NEW                  = 0x42
 	SO_RCVTIMEO_OLD                  = 0x14
@@ -413,6 +414,7 @@
 	SO_TIMESTAMPNS_NEW               = 0x40
 	SO_TIMESTAMPNS_OLD               = 0x23
 	SO_TIMESTAMP_NEW                 = 0x3f
+	SO_TXREHASH                      = 0x4a
 	SO_TXTIME                        = 0x3d
 	SO_TYPE                          = 0x3
 	SO_WIFI_STATUS                   = 0x29
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go
index 4fd497a..98a6e5f 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go
@@ -1,11 +1,11 @@
-// mkerrors.sh -Wall -Werror -static -I/tmp/include
+// mkerrors.sh -Wall -Werror -static -I/tmp/sparc64/include
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build sparc64 && linux
 // +build sparc64,linux
 
 // Code generated by cmd/cgo -godefs; DO NOT EDIT.
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include _const.go
+// cgo -godefs -- -Wall -Werror -static -I/tmp/sparc64/include _const.go
 
 package unix
 
@@ -380,6 +380,7 @@
 	SO_RCVBUF                        = 0x1002
 	SO_RCVBUFFORCE                   = 0x100b
 	SO_RCVLOWAT                      = 0x800
+	SO_RCVMARK                       = 0x54
 	SO_RCVTIMEO                      = 0x2000
 	SO_RCVTIMEO_NEW                  = 0x44
 	SO_RCVTIMEO_OLD                  = 0x2000
@@ -404,6 +405,7 @@
 	SO_TIMESTAMPNS_NEW               = 0x42
 	SO_TIMESTAMPNS_OLD               = 0x21
 	SO_TIMESTAMP_NEW                 = 0x46
+	SO_TXREHASH                      = 0x53
 	SO_TXTIME                        = 0x3f
 	SO_TYPE                          = 0x1008
 	SO_WIFI_STATUS                   = 0x25
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_ppc64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_ppc64.go
new file mode 100644
index 0000000..8e2c51b
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_ppc64.go
@@ -0,0 +1,1905 @@
+// mkerrors.sh -m64
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+//go:build ppc64 && openbsd
+// +build ppc64,openbsd
+
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs -- -m64 _const.go
+
+package unix
+
+import "syscall"
+
+const (
+	AF_APPLETALK                      = 0x10
+	AF_BLUETOOTH                      = 0x20
+	AF_CCITT                          = 0xa
+	AF_CHAOS                          = 0x5
+	AF_CNT                            = 0x15
+	AF_COIP                           = 0x14
+	AF_DATAKIT                        = 0x9
+	AF_DECnet                         = 0xc
+	AF_DLI                            = 0xd
+	AF_E164                           = 0x1a
+	AF_ECMA                           = 0x8
+	AF_ENCAP                          = 0x1c
+	AF_HYLINK                         = 0xf
+	AF_IMPLINK                        = 0x3
+	AF_INET                           = 0x2
+	AF_INET6                          = 0x18
+	AF_IPX                            = 0x17
+	AF_ISDN                           = 0x1a
+	AF_ISO                            = 0x7
+	AF_KEY                            = 0x1e
+	AF_LAT                            = 0xe
+	AF_LINK                           = 0x12
+	AF_LOCAL                          = 0x1
+	AF_MAX                            = 0x24
+	AF_MPLS                           = 0x21
+	AF_NATM                           = 0x1b
+	AF_NS                             = 0x6
+	AF_OSI                            = 0x7
+	AF_PUP                            = 0x4
+	AF_ROUTE                          = 0x11
+	AF_SIP                            = 0x1d
+	AF_SNA                            = 0xb
+	AF_UNIX                           = 0x1
+	AF_UNSPEC                         = 0x0
+	ALTWERASE                         = 0x200
+	ARPHRD_ETHER                      = 0x1
+	ARPHRD_FRELAY                     = 0xf
+	ARPHRD_IEEE1394                   = 0x18
+	ARPHRD_IEEE802                    = 0x6
+	B0                                = 0x0
+	B110                              = 0x6e
+	B115200                           = 0x1c200
+	B1200                             = 0x4b0
+	B134                              = 0x86
+	B14400                            = 0x3840
+	B150                              = 0x96
+	B1800                             = 0x708
+	B19200                            = 0x4b00
+	B200                              = 0xc8
+	B230400                           = 0x38400
+	B2400                             = 0x960
+	B28800                            = 0x7080
+	B300                              = 0x12c
+	B38400                            = 0x9600
+	B4800                             = 0x12c0
+	B50                               = 0x32
+	B57600                            = 0xe100
+	B600                              = 0x258
+	B7200                             = 0x1c20
+	B75                               = 0x4b
+	B76800                            = 0x12c00
+	B9600                             = 0x2580
+	BIOCFLUSH                         = 0x20004268
+	BIOCGBLEN                         = 0x40044266
+	BIOCGDIRFILT                      = 0x4004427c
+	BIOCGDLT                          = 0x4004426a
+	BIOCGDLTLIST                      = 0xc010427b
+	BIOCGETIF                         = 0x4020426b
+	BIOCGFILDROP                      = 0x40044278
+	BIOCGHDRCMPLT                     = 0x40044274
+	BIOCGRSIG                         = 0x40044273
+	BIOCGRTIMEOUT                     = 0x4010426e
+	BIOCGSTATS                        = 0x4008426f
+	BIOCIMMEDIATE                     = 0x80044270
+	BIOCLOCK                          = 0x20004276
+	BIOCPROMISC                       = 0x20004269
+	BIOCSBLEN                         = 0xc0044266
+	BIOCSDIRFILT                      = 0x8004427d
+	BIOCSDLT                          = 0x8004427a
+	BIOCSETF                          = 0x80104267
+	BIOCSETIF                         = 0x8020426c
+	BIOCSETWF                         = 0x80104277
+	BIOCSFILDROP                      = 0x80044279
+	BIOCSHDRCMPLT                     = 0x80044275
+	BIOCSRSIG                         = 0x80044272
+	BIOCSRTIMEOUT                     = 0x8010426d
+	BIOCVERSION                       = 0x40044271
+	BPF_A                             = 0x10
+	BPF_ABS                           = 0x20
+	BPF_ADD                           = 0x0
+	BPF_ALIGNMENT                     = 0x4
+	BPF_ALU                           = 0x4
+	BPF_AND                           = 0x50
+	BPF_B                             = 0x10
+	BPF_DIRECTION_IN                  = 0x1
+	BPF_DIRECTION_OUT                 = 0x2
+	BPF_DIV                           = 0x30
+	BPF_FILDROP_CAPTURE               = 0x1
+	BPF_FILDROP_DROP                  = 0x2
+	BPF_FILDROP_PASS                  = 0x0
+	BPF_F_DIR_IN                      = 0x10
+	BPF_F_DIR_MASK                    = 0x30
+	BPF_F_DIR_OUT                     = 0x20
+	BPF_F_DIR_SHIFT                   = 0x4
+	BPF_F_FLOWID                      = 0x8
+	BPF_F_PRI_MASK                    = 0x7
+	BPF_H                             = 0x8
+	BPF_IMM                           = 0x0
+	BPF_IND                           = 0x40
+	BPF_JA                            = 0x0
+	BPF_JEQ                           = 0x10
+	BPF_JGE                           = 0x30
+	BPF_JGT                           = 0x20
+	BPF_JMP                           = 0x5
+	BPF_JSET                          = 0x40
+	BPF_K                             = 0x0
+	BPF_LD                            = 0x0
+	BPF_LDX                           = 0x1
+	BPF_LEN                           = 0x80
+	BPF_LSH                           = 0x60
+	BPF_MAJOR_VERSION                 = 0x1
+	BPF_MAXBUFSIZE                    = 0x200000
+	BPF_MAXINSNS                      = 0x200
+	BPF_MEM                           = 0x60
+	BPF_MEMWORDS                      = 0x10
+	BPF_MINBUFSIZE                    = 0x20
+	BPF_MINOR_VERSION                 = 0x1
+	BPF_MISC                          = 0x7
+	BPF_MSH                           = 0xa0
+	BPF_MUL                           = 0x20
+	BPF_NEG                           = 0x80
+	BPF_OR                            = 0x40
+	BPF_RELEASE                       = 0x30bb6
+	BPF_RET                           = 0x6
+	BPF_RND                           = 0xc0
+	BPF_RSH                           = 0x70
+	BPF_ST                            = 0x2
+	BPF_STX                           = 0x3
+	BPF_SUB                           = 0x10
+	BPF_TAX                           = 0x0
+	BPF_TXA                           = 0x80
+	BPF_W                             = 0x0
+	BPF_X                             = 0x8
+	BRKINT                            = 0x2
+	CFLUSH                            = 0xf
+	CLOCAL                            = 0x8000
+	CLOCK_BOOTTIME                    = 0x6
+	CLOCK_MONOTONIC                   = 0x3
+	CLOCK_PROCESS_CPUTIME_ID          = 0x2
+	CLOCK_REALTIME                    = 0x0
+	CLOCK_THREAD_CPUTIME_ID           = 0x4
+	CLOCK_UPTIME                      = 0x5
+	CPUSTATES                         = 0x6
+	CP_IDLE                           = 0x5
+	CP_INTR                           = 0x4
+	CP_NICE                           = 0x1
+	CP_SPIN                           = 0x3
+	CP_SYS                            = 0x2
+	CP_USER                           = 0x0
+	CREAD                             = 0x800
+	CRTSCTS                           = 0x10000
+	CS5                               = 0x0
+	CS6                               = 0x100
+	CS7                               = 0x200
+	CS8                               = 0x300
+	CSIZE                             = 0x300
+	CSTART                            = 0x11
+	CSTATUS                           = 0xff
+	CSTOP                             = 0x13
+	CSTOPB                            = 0x400
+	CSUSP                             = 0x1a
+	CTL_HW                            = 0x6
+	CTL_KERN                          = 0x1
+	CTL_MAXNAME                       = 0xc
+	CTL_NET                           = 0x4
+	DIOCADDQUEUE                      = 0xc110445d
+	DIOCADDRULE                       = 0xcd604404
+	DIOCADDSTATE                      = 0xc1084425
+	DIOCCHANGERULE                    = 0xcd60441a
+	DIOCCLRIFFLAG                     = 0xc028445a
+	DIOCCLRSRCNODES                   = 0x20004455
+	DIOCCLRSTATES                     = 0xc0e04412
+	DIOCCLRSTATUS                     = 0xc0284416
+	DIOCGETLIMIT                      = 0xc0084427
+	DIOCGETQSTATS                     = 0xc1204460
+	DIOCGETQUEUE                      = 0xc110445f
+	DIOCGETQUEUES                     = 0xc110445e
+	DIOCGETRULE                       = 0xcd604407
+	DIOCGETRULES                      = 0xcd604406
+	DIOCGETRULESET                    = 0xc444443b
+	DIOCGETRULESETS                   = 0xc444443a
+	DIOCGETSRCNODES                   = 0xc0104454
+	DIOCGETSTATE                      = 0xc1084413
+	DIOCGETSTATES                     = 0xc0104419
+	DIOCGETSTATUS                     = 0xc1e84415
+	DIOCGETSYNFLWATS                  = 0xc0084463
+	DIOCGETTIMEOUT                    = 0xc008441e
+	DIOCIGETIFACES                    = 0xc0284457
+	DIOCKILLSRCNODES                  = 0xc080445b
+	DIOCKILLSTATES                    = 0xc0e04429
+	DIOCNATLOOK                       = 0xc0504417
+	DIOCOSFPADD                       = 0xc088444f
+	DIOCOSFPFLUSH                     = 0x2000444e
+	DIOCOSFPGET                       = 0xc0884450
+	DIOCRADDADDRS                     = 0xc4504443
+	DIOCRADDTABLES                    = 0xc450443d
+	DIOCRCLRADDRS                     = 0xc4504442
+	DIOCRCLRASTATS                    = 0xc4504448
+	DIOCRCLRTABLES                    = 0xc450443c
+	DIOCRCLRTSTATS                    = 0xc4504441
+	DIOCRDELADDRS                     = 0xc4504444
+	DIOCRDELTABLES                    = 0xc450443e
+	DIOCRGETADDRS                     = 0xc4504446
+	DIOCRGETASTATS                    = 0xc4504447
+	DIOCRGETTABLES                    = 0xc450443f
+	DIOCRGETTSTATS                    = 0xc4504440
+	DIOCRINADEFINE                    = 0xc450444d
+	DIOCRSETADDRS                     = 0xc4504445
+	DIOCRSETTFLAGS                    = 0xc450444a
+	DIOCRTSTADDRS                     = 0xc4504449
+	DIOCSETDEBUG                      = 0xc0044418
+	DIOCSETHOSTID                     = 0xc0044456
+	DIOCSETIFFLAG                     = 0xc0284459
+	DIOCSETLIMIT                      = 0xc0084428
+	DIOCSETREASS                      = 0xc004445c
+	DIOCSETSTATUSIF                   = 0xc0284414
+	DIOCSETSYNCOOKIES                 = 0xc0014462
+	DIOCSETSYNFLWATS                  = 0xc0084461
+	DIOCSETTIMEOUT                    = 0xc008441d
+	DIOCSTART                         = 0x20004401
+	DIOCSTOP                          = 0x20004402
+	DIOCXBEGIN                        = 0xc0104451
+	DIOCXCOMMIT                       = 0xc0104452
+	DIOCXROLLBACK                     = 0xc0104453
+	DLT_ARCNET                        = 0x7
+	DLT_ATM_RFC1483                   = 0xb
+	DLT_AX25                          = 0x3
+	DLT_CHAOS                         = 0x5
+	DLT_C_HDLC                        = 0x68
+	DLT_EN10MB                        = 0x1
+	DLT_EN3MB                         = 0x2
+	DLT_ENC                           = 0xd
+	DLT_FDDI                          = 0xa
+	DLT_IEEE802                       = 0x6
+	DLT_IEEE802_11                    = 0x69
+	DLT_IEEE802_11_RADIO              = 0x7f
+	DLT_LOOP                          = 0xc
+	DLT_MPLS                          = 0xdb
+	DLT_NULL                          = 0x0
+	DLT_OPENFLOW                      = 0x10b
+	DLT_PFLOG                         = 0x75
+	DLT_PFSYNC                        = 0x12
+	DLT_PPP                           = 0x9
+	DLT_PPP_BSDOS                     = 0x10
+	DLT_PPP_ETHER                     = 0x33
+	DLT_PPP_SERIAL                    = 0x32
+	DLT_PRONET                        = 0x4
+	DLT_RAW                           = 0xe
+	DLT_SLIP                          = 0x8
+	DLT_SLIP_BSDOS                    = 0xf
+	DLT_USBPCAP                       = 0xf9
+	DLT_USER0                         = 0x93
+	DLT_USER1                         = 0x94
+	DLT_USER10                        = 0x9d
+	DLT_USER11                        = 0x9e
+	DLT_USER12                        = 0x9f
+	DLT_USER13                        = 0xa0
+	DLT_USER14                        = 0xa1
+	DLT_USER15                        = 0xa2
+	DLT_USER2                         = 0x95
+	DLT_USER3                         = 0x96
+	DLT_USER4                         = 0x97
+	DLT_USER5                         = 0x98
+	DLT_USER6                         = 0x99
+	DLT_USER7                         = 0x9a
+	DLT_USER8                         = 0x9b
+	DLT_USER9                         = 0x9c
+	DT_BLK                            = 0x6
+	DT_CHR                            = 0x2
+	DT_DIR                            = 0x4
+	DT_FIFO                           = 0x1
+	DT_LNK                            = 0xa
+	DT_REG                            = 0x8
+	DT_SOCK                           = 0xc
+	DT_UNKNOWN                        = 0x0
+	ECHO                              = 0x8
+	ECHOCTL                           = 0x40
+	ECHOE                             = 0x2
+	ECHOK                             = 0x4
+	ECHOKE                            = 0x1
+	ECHONL                            = 0x10
+	ECHOPRT                           = 0x20
+	EMT_TAGOVF                        = 0x1
+	EMUL_ENABLED                      = 0x1
+	EMUL_NATIVE                       = 0x2
+	ENDRUNDISC                        = 0x9
+	ETH64_8021_RSVD_MASK              = 0xfffffffffff0
+	ETH64_8021_RSVD_PREFIX            = 0x180c2000000
+	ETHERMIN                          = 0x2e
+	ETHERMTU                          = 0x5dc
+	ETHERTYPE_8023                    = 0x4
+	ETHERTYPE_AARP                    = 0x80f3
+	ETHERTYPE_ACCTON                  = 0x8390
+	ETHERTYPE_AEONIC                  = 0x8036
+	ETHERTYPE_ALPHA                   = 0x814a
+	ETHERTYPE_AMBER                   = 0x6008
+	ETHERTYPE_AMOEBA                  = 0x8145
+	ETHERTYPE_AOE                     = 0x88a2
+	ETHERTYPE_APOLLO                  = 0x80f7
+	ETHERTYPE_APOLLODOMAIN            = 0x8019
+	ETHERTYPE_APPLETALK               = 0x809b
+	ETHERTYPE_APPLITEK                = 0x80c7
+	ETHERTYPE_ARGONAUT                = 0x803a
+	ETHERTYPE_ARP                     = 0x806
+	ETHERTYPE_AT                      = 0x809b
+	ETHERTYPE_ATALK                   = 0x809b
+	ETHERTYPE_ATOMIC                  = 0x86df
+	ETHERTYPE_ATT                     = 0x8069
+	ETHERTYPE_ATTSTANFORD             = 0x8008
+	ETHERTYPE_AUTOPHON                = 0x806a
+	ETHERTYPE_AXIS                    = 0x8856
+	ETHERTYPE_BCLOOP                  = 0x9003
+	ETHERTYPE_BOFL                    = 0x8102
+	ETHERTYPE_CABLETRON               = 0x7034
+	ETHERTYPE_CHAOS                   = 0x804
+	ETHERTYPE_COMDESIGN               = 0x806c
+	ETHERTYPE_COMPUGRAPHIC            = 0x806d
+	ETHERTYPE_COUNTERPOINT            = 0x8062
+	ETHERTYPE_CRONUS                  = 0x8004
+	ETHERTYPE_CRONUSVLN               = 0x8003
+	ETHERTYPE_DCA                     = 0x1234
+	ETHERTYPE_DDE                     = 0x807b
+	ETHERTYPE_DEBNI                   = 0xaaaa
+	ETHERTYPE_DECAM                   = 0x8048
+	ETHERTYPE_DECCUST                 = 0x6006
+	ETHERTYPE_DECDIAG                 = 0x6005
+	ETHERTYPE_DECDNS                  = 0x803c
+	ETHERTYPE_DECDTS                  = 0x803e
+	ETHERTYPE_DECEXPER                = 0x6000
+	ETHERTYPE_DECLAST                 = 0x8041
+	ETHERTYPE_DECLTM                  = 0x803f
+	ETHERTYPE_DECMUMPS                = 0x6009
+	ETHERTYPE_DECNETBIOS              = 0x8040
+	ETHERTYPE_DELTACON                = 0x86de
+	ETHERTYPE_DIDDLE                  = 0x4321
+	ETHERTYPE_DLOG1                   = 0x660
+	ETHERTYPE_DLOG2                   = 0x661
+	ETHERTYPE_DN                      = 0x6003
+	ETHERTYPE_DOGFIGHT                = 0x1989
+	ETHERTYPE_DSMD                    = 0x8039
+	ETHERTYPE_EAPOL                   = 0x888e
+	ETHERTYPE_ECMA                    = 0x803
+	ETHERTYPE_ENCRYPT                 = 0x803d
+	ETHERTYPE_ES                      = 0x805d
+	ETHERTYPE_EXCELAN                 = 0x8010
+	ETHERTYPE_EXPERDATA               = 0x8049
+	ETHERTYPE_FLIP                    = 0x8146
+	ETHERTYPE_FLOWCONTROL             = 0x8808
+	ETHERTYPE_FRARP                   = 0x808
+	ETHERTYPE_GENDYN                  = 0x8068
+	ETHERTYPE_HAYES                   = 0x8130
+	ETHERTYPE_HIPPI_FP                = 0x8180
+	ETHERTYPE_HITACHI                 = 0x8820
+	ETHERTYPE_HP                      = 0x8005
+	ETHERTYPE_IEEEPUP                 = 0xa00
+	ETHERTYPE_IEEEPUPAT               = 0xa01
+	ETHERTYPE_IMLBL                   = 0x4c42
+	ETHERTYPE_IMLBLDIAG               = 0x424c
+	ETHERTYPE_IP                      = 0x800
+	ETHERTYPE_IPAS                    = 0x876c
+	ETHERTYPE_IPV6                    = 0x86dd
+	ETHERTYPE_IPX                     = 0x8137
+	ETHERTYPE_IPXNEW                  = 0x8037
+	ETHERTYPE_KALPANA                 = 0x8582
+	ETHERTYPE_LANBRIDGE               = 0x8038
+	ETHERTYPE_LANPROBE                = 0x8888
+	ETHERTYPE_LAT                     = 0x6004
+	ETHERTYPE_LBACK                   = 0x9000
+	ETHERTYPE_LITTLE                  = 0x8060
+	ETHERTYPE_LLDP                    = 0x88cc
+	ETHERTYPE_LOGICRAFT               = 0x8148
+	ETHERTYPE_LOOPBACK                = 0x9000
+	ETHERTYPE_MACSEC                  = 0x88e5
+	ETHERTYPE_MATRA                   = 0x807a
+	ETHERTYPE_MAX                     = 0xffff
+	ETHERTYPE_MERIT                   = 0x807c
+	ETHERTYPE_MICP                    = 0x873a
+	ETHERTYPE_MOPDL                   = 0x6001
+	ETHERTYPE_MOPRC                   = 0x6002
+	ETHERTYPE_MOTOROLA                = 0x818d
+	ETHERTYPE_MPLS                    = 0x8847
+	ETHERTYPE_MPLS_MCAST              = 0x8848
+	ETHERTYPE_MUMPS                   = 0x813f
+	ETHERTYPE_NBPCC                   = 0x3c04
+	ETHERTYPE_NBPCLAIM                = 0x3c09
+	ETHERTYPE_NBPCLREQ                = 0x3c05
+	ETHERTYPE_NBPCLRSP                = 0x3c06
+	ETHERTYPE_NBPCREQ                 = 0x3c02
+	ETHERTYPE_NBPCRSP                 = 0x3c03
+	ETHERTYPE_NBPDG                   = 0x3c07
+	ETHERTYPE_NBPDGB                  = 0x3c08
+	ETHERTYPE_NBPDLTE                 = 0x3c0a
+	ETHERTYPE_NBPRAR                  = 0x3c0c
+	ETHERTYPE_NBPRAS                  = 0x3c0b
+	ETHERTYPE_NBPRST                  = 0x3c0d
+	ETHERTYPE_NBPSCD                  = 0x3c01
+	ETHERTYPE_NBPVCD                  = 0x3c00
+	ETHERTYPE_NBS                     = 0x802
+	ETHERTYPE_NCD                     = 0x8149
+	ETHERTYPE_NESTAR                  = 0x8006
+	ETHERTYPE_NETBEUI                 = 0x8191
+	ETHERTYPE_NHRP                    = 0x2001
+	ETHERTYPE_NOVELL                  = 0x8138
+	ETHERTYPE_NS                      = 0x600
+	ETHERTYPE_NSAT                    = 0x601
+	ETHERTYPE_NSCOMPAT                = 0x807
+	ETHERTYPE_NSH                     = 0x984f
+	ETHERTYPE_NTRAILER                = 0x10
+	ETHERTYPE_OS9                     = 0x7007
+	ETHERTYPE_OS9NET                  = 0x7009
+	ETHERTYPE_PACER                   = 0x80c6
+	ETHERTYPE_PBB                     = 0x88e7
+	ETHERTYPE_PCS                     = 0x4242
+	ETHERTYPE_PLANNING                = 0x8044
+	ETHERTYPE_PPP                     = 0x880b
+	ETHERTYPE_PPPOE                   = 0x8864
+	ETHERTYPE_PPPOEDISC               = 0x8863
+	ETHERTYPE_PRIMENTS                = 0x7031
+	ETHERTYPE_PUP                     = 0x200
+	ETHERTYPE_PUPAT                   = 0x200
+	ETHERTYPE_QINQ                    = 0x88a8
+	ETHERTYPE_RACAL                   = 0x7030
+	ETHERTYPE_RATIONAL                = 0x8150
+	ETHERTYPE_RAWFR                   = 0x6559
+	ETHERTYPE_RCL                     = 0x1995
+	ETHERTYPE_RDP                     = 0x8739
+	ETHERTYPE_RETIX                   = 0x80f2
+	ETHERTYPE_REVARP                  = 0x8035
+	ETHERTYPE_SCA                     = 0x6007
+	ETHERTYPE_SECTRA                  = 0x86db
+	ETHERTYPE_SECUREDATA              = 0x876d
+	ETHERTYPE_SGITW                   = 0x817e
+	ETHERTYPE_SG_BOUNCE               = 0x8016
+	ETHERTYPE_SG_DIAG                 = 0x8013
+	ETHERTYPE_SG_NETGAMES             = 0x8014
+	ETHERTYPE_SG_RESV                 = 0x8015
+	ETHERTYPE_SIMNET                  = 0x5208
+	ETHERTYPE_SLOW                    = 0x8809
+	ETHERTYPE_SNA                     = 0x80d5
+	ETHERTYPE_SNMP                    = 0x814c
+	ETHERTYPE_SONIX                   = 0xfaf5
+	ETHERTYPE_SPIDER                  = 0x809f
+	ETHERTYPE_SPRITE                  = 0x500
+	ETHERTYPE_STP                     = 0x8181
+	ETHERTYPE_TALARIS                 = 0x812b
+	ETHERTYPE_TALARISMC               = 0x852b
+	ETHERTYPE_TCPCOMP                 = 0x876b
+	ETHERTYPE_TCPSM                   = 0x9002
+	ETHERTYPE_TEC                     = 0x814f
+	ETHERTYPE_TIGAN                   = 0x802f
+	ETHERTYPE_TRAIL                   = 0x1000
+	ETHERTYPE_TRANSETHER              = 0x6558
+	ETHERTYPE_TYMSHARE                = 0x802e
+	ETHERTYPE_UBBST                   = 0x7005
+	ETHERTYPE_UBDEBUG                 = 0x900
+	ETHERTYPE_UBDIAGLOOP              = 0x7002
+	ETHERTYPE_UBDL                    = 0x7000
+	ETHERTYPE_UBNIU                   = 0x7001
+	ETHERTYPE_UBNMC                   = 0x7003
+	ETHERTYPE_VALID                   = 0x1600
+	ETHERTYPE_VARIAN                  = 0x80dd
+	ETHERTYPE_VAXELN                  = 0x803b
+	ETHERTYPE_VEECO                   = 0x8067
+	ETHERTYPE_VEXP                    = 0x805b
+	ETHERTYPE_VGLAB                   = 0x8131
+	ETHERTYPE_VINES                   = 0xbad
+	ETHERTYPE_VINESECHO               = 0xbaf
+	ETHERTYPE_VINESLOOP               = 0xbae
+	ETHERTYPE_VITAL                   = 0xff00
+	ETHERTYPE_VLAN                    = 0x8100
+	ETHERTYPE_VLTLMAN                 = 0x8080
+	ETHERTYPE_VPROD                   = 0x805c
+	ETHERTYPE_VURESERVED              = 0x8147
+	ETHERTYPE_WATERLOO                = 0x8130
+	ETHERTYPE_WELLFLEET               = 0x8103
+	ETHERTYPE_X25                     = 0x805
+	ETHERTYPE_X75                     = 0x801
+	ETHERTYPE_XNSSM                   = 0x9001
+	ETHERTYPE_XTP                     = 0x817d
+	ETHER_ADDR_LEN                    = 0x6
+	ETHER_ALIGN                       = 0x2
+	ETHER_CRC_LEN                     = 0x4
+	ETHER_CRC_POLY_BE                 = 0x4c11db6
+	ETHER_CRC_POLY_LE                 = 0xedb88320
+	ETHER_HDR_LEN                     = 0xe
+	ETHER_MAX_DIX_LEN                 = 0x600
+	ETHER_MAX_HARDMTU_LEN             = 0xff9b
+	ETHER_MAX_LEN                     = 0x5ee
+	ETHER_MIN_LEN                     = 0x40
+	ETHER_TYPE_LEN                    = 0x2
+	ETHER_VLAN_ENCAP_LEN              = 0x4
+	EVFILT_AIO                        = -0x3
+	EVFILT_DEVICE                     = -0x8
+	EVFILT_EXCEPT                     = -0x9
+	EVFILT_PROC                       = -0x5
+	EVFILT_READ                       = -0x1
+	EVFILT_SIGNAL                     = -0x6
+	EVFILT_SYSCOUNT                   = 0x9
+	EVFILT_TIMER                      = -0x7
+	EVFILT_VNODE                      = -0x4
+	EVFILT_WRITE                      = -0x2
+	EVL_ENCAPLEN                      = 0x4
+	EVL_PRIO_BITS                     = 0xd
+	EVL_PRIO_MAX                      = 0x7
+	EVL_VLID_MASK                     = 0xfff
+	EVL_VLID_MAX                      = 0xffe
+	EVL_VLID_MIN                      = 0x1
+	EVL_VLID_NULL                     = 0x0
+	EV_ADD                            = 0x1
+	EV_CLEAR                          = 0x20
+	EV_DELETE                         = 0x2
+	EV_DISABLE                        = 0x8
+	EV_DISPATCH                       = 0x80
+	EV_ENABLE                         = 0x4
+	EV_EOF                            = 0x8000
+	EV_ERROR                          = 0x4000
+	EV_FLAG1                          = 0x2000
+	EV_ONESHOT                        = 0x10
+	EV_RECEIPT                        = 0x40
+	EV_SYSFLAGS                       = 0xf800
+	EXTA                              = 0x4b00
+	EXTB                              = 0x9600
+	EXTPROC                           = 0x800
+	FD_CLOEXEC                        = 0x1
+	FD_SETSIZE                        = 0x400
+	FLUSHO                            = 0x800000
+	F_DUPFD                           = 0x0
+	F_DUPFD_CLOEXEC                   = 0xa
+	F_GETFD                           = 0x1
+	F_GETFL                           = 0x3
+	F_GETLK                           = 0x7
+	F_GETOWN                          = 0x5
+	F_ISATTY                          = 0xb
+	F_OK                              = 0x0
+	F_RDLCK                           = 0x1
+	F_SETFD                           = 0x2
+	F_SETFL                           = 0x4
+	F_SETLK                           = 0x8
+	F_SETLKW                          = 0x9
+	F_SETOWN                          = 0x6
+	F_UNLCK                           = 0x2
+	F_WRLCK                           = 0x3
+	HUPCL                             = 0x4000
+	HW_MACHINE                        = 0x1
+	ICANON                            = 0x100
+	ICMP6_FILTER                      = 0x12
+	ICRNL                             = 0x100
+	IEXTEN                            = 0x400
+	IFAN_ARRIVAL                      = 0x0
+	IFAN_DEPARTURE                    = 0x1
+	IFF_ALLMULTI                      = 0x200
+	IFF_BROADCAST                     = 0x2
+	IFF_CANTCHANGE                    = 0x8e52
+	IFF_DEBUG                         = 0x4
+	IFF_LINK0                         = 0x1000
+	IFF_LINK1                         = 0x2000
+	IFF_LINK2                         = 0x4000
+	IFF_LOOPBACK                      = 0x8
+	IFF_MULTICAST                     = 0x8000
+	IFF_NOARP                         = 0x80
+	IFF_OACTIVE                       = 0x400
+	IFF_POINTOPOINT                   = 0x10
+	IFF_PROMISC                       = 0x100
+	IFF_RUNNING                       = 0x40
+	IFF_SIMPLEX                       = 0x800
+	IFF_STATICARP                     = 0x20
+	IFF_UP                            = 0x1
+	IFNAMSIZ                          = 0x10
+	IFT_1822                          = 0x2
+	IFT_A12MPPSWITCH                  = 0x82
+	IFT_AAL2                          = 0xbb
+	IFT_AAL5                          = 0x31
+	IFT_ADSL                          = 0x5e
+	IFT_AFLANE8023                    = 0x3b
+	IFT_AFLANE8025                    = 0x3c
+	IFT_ARAP                          = 0x58
+	IFT_ARCNET                        = 0x23
+	IFT_ARCNETPLUS                    = 0x24
+	IFT_ASYNC                         = 0x54
+	IFT_ATM                           = 0x25
+	IFT_ATMDXI                        = 0x69
+	IFT_ATMFUNI                       = 0x6a
+	IFT_ATMIMA                        = 0x6b
+	IFT_ATMLOGICAL                    = 0x50
+	IFT_ATMRADIO                      = 0xbd
+	IFT_ATMSUBINTERFACE               = 0x86
+	IFT_ATMVCIENDPT                   = 0xc2
+	IFT_ATMVIRTUAL                    = 0x95
+	IFT_BGPPOLICYACCOUNTING           = 0xa2
+	IFT_BLUETOOTH                     = 0xf8
+	IFT_BRIDGE                        = 0xd1
+	IFT_BSC                           = 0x53
+	IFT_CARP                          = 0xf7
+	IFT_CCTEMUL                       = 0x3d
+	IFT_CEPT                          = 0x13
+	IFT_CES                           = 0x85
+	IFT_CHANNEL                       = 0x46
+	IFT_CNR                           = 0x55
+	IFT_COFFEE                        = 0x84
+	IFT_COMPOSITELINK                 = 0x9b
+	IFT_DCN                           = 0x8d
+	IFT_DIGITALPOWERLINE              = 0x8a
+	IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
+	IFT_DLSW                          = 0x4a
+	IFT_DOCSCABLEDOWNSTREAM           = 0x80
+	IFT_DOCSCABLEMACLAYER             = 0x7f
+	IFT_DOCSCABLEUPSTREAM             = 0x81
+	IFT_DOCSCABLEUPSTREAMCHANNEL      = 0xcd
+	IFT_DS0                           = 0x51
+	IFT_DS0BUNDLE                     = 0x52
+	IFT_DS1FDL                        = 0xaa
+	IFT_DS3                           = 0x1e
+	IFT_DTM                           = 0x8c
+	IFT_DUMMY                         = 0xf1
+	IFT_DVBASILN                      = 0xac
+	IFT_DVBASIOUT                     = 0xad
+	IFT_DVBRCCDOWNSTREAM              = 0x93
+	IFT_DVBRCCMACLAYER                = 0x92
+	IFT_DVBRCCUPSTREAM                = 0x94
+	IFT_ECONET                        = 0xce
+	IFT_ENC                           = 0xf4
+	IFT_EON                           = 0x19
+	IFT_EPLRS                         = 0x57
+	IFT_ESCON                         = 0x49
+	IFT_ETHER                         = 0x6
+	IFT_FAITH                         = 0xf3
+	IFT_FAST                          = 0x7d
+	IFT_FASTETHER                     = 0x3e
+	IFT_FASTETHERFX                   = 0x45
+	IFT_FDDI                          = 0xf
+	IFT_FIBRECHANNEL                  = 0x38
+	IFT_FRAMERELAYINTERCONNECT        = 0x3a
+	IFT_FRAMERELAYMPI                 = 0x5c
+	IFT_FRDLCIENDPT                   = 0xc1
+	IFT_FRELAY                        = 0x20
+	IFT_FRELAYDCE                     = 0x2c
+	IFT_FRF16MFRBUNDLE                = 0xa3
+	IFT_FRFORWARD                     = 0x9e
+	IFT_G703AT2MB                     = 0x43
+	IFT_G703AT64K                     = 0x42
+	IFT_GIF                           = 0xf0
+	IFT_GIGABITETHERNET               = 0x75
+	IFT_GR303IDT                      = 0xb2
+	IFT_GR303RDT                      = 0xb1
+	IFT_H323GATEKEEPER                = 0xa4
+	IFT_H323PROXY                     = 0xa5
+	IFT_HDH1822                       = 0x3
+	IFT_HDLC                          = 0x76
+	IFT_HDSL2                         = 0xa8
+	IFT_HIPERLAN2                     = 0xb7
+	IFT_HIPPI                         = 0x2f
+	IFT_HIPPIINTERFACE                = 0x39
+	IFT_HOSTPAD                       = 0x5a
+	IFT_HSSI                          = 0x2e
+	IFT_HY                            = 0xe
+	IFT_IBM370PARCHAN                 = 0x48
+	IFT_IDSL                          = 0x9a
+	IFT_IEEE1394                      = 0x90
+	IFT_IEEE80211                     = 0x47
+	IFT_IEEE80212                     = 0x37
+	IFT_IEEE8023ADLAG                 = 0xa1
+	IFT_IFGSN                         = 0x91
+	IFT_IMT                           = 0xbe
+	IFT_INFINIBAND                    = 0xc7
+	IFT_INTERLEAVE                    = 0x7c
+	IFT_IP                            = 0x7e
+	IFT_IPFORWARD                     = 0x8e
+	IFT_IPOVERATM                     = 0x72
+	IFT_IPOVERCDLC                    = 0x6d
+	IFT_IPOVERCLAW                    = 0x6e
+	IFT_IPSWITCH                      = 0x4e
+	IFT_ISDN                          = 0x3f
+	IFT_ISDNBASIC                     = 0x14
+	IFT_ISDNPRIMARY                   = 0x15
+	IFT_ISDNS                         = 0x4b
+	IFT_ISDNU                         = 0x4c
+	IFT_ISO88022LLC                   = 0x29
+	IFT_ISO88023                      = 0x7
+	IFT_ISO88024                      = 0x8
+	IFT_ISO88025                      = 0x9
+	IFT_ISO88025CRFPINT               = 0x62
+	IFT_ISO88025DTR                   = 0x56
+	IFT_ISO88025FIBER                 = 0x73
+	IFT_ISO88026                      = 0xa
+	IFT_ISUP                          = 0xb3
+	IFT_L2VLAN                        = 0x87
+	IFT_L3IPVLAN                      = 0x88
+	IFT_L3IPXVLAN                     = 0x89
+	IFT_LAPB                          = 0x10
+	IFT_LAPD                          = 0x4d
+	IFT_LAPF                          = 0x77
+	IFT_LINEGROUP                     = 0xd2
+	IFT_LOCALTALK                     = 0x2a
+	IFT_LOOP                          = 0x18
+	IFT_MBIM                          = 0xfa
+	IFT_MEDIAMAILOVERIP               = 0x8b
+	IFT_MFSIGLINK                     = 0xa7
+	IFT_MIOX25                        = 0x26
+	IFT_MODEM                         = 0x30
+	IFT_MPC                           = 0x71
+	IFT_MPLS                          = 0xa6
+	IFT_MPLSTUNNEL                    = 0x96
+	IFT_MSDSL                         = 0x8f
+	IFT_MVL                           = 0xbf
+	IFT_MYRINET                       = 0x63
+	IFT_NFAS                          = 0xaf
+	IFT_NSIP                          = 0x1b
+	IFT_OPTICALCHANNEL                = 0xc3
+	IFT_OPTICALTRANSPORT              = 0xc4
+	IFT_OTHER                         = 0x1
+	IFT_P10                           = 0xc
+	IFT_P80                           = 0xd
+	IFT_PARA                          = 0x22
+	IFT_PFLOG                         = 0xf5
+	IFT_PFLOW                         = 0xf9
+	IFT_PFSYNC                        = 0xf6
+	IFT_PLC                           = 0xae
+	IFT_PON155                        = 0xcf
+	IFT_PON622                        = 0xd0
+	IFT_POS                           = 0xab
+	IFT_PPP                           = 0x17
+	IFT_PPPMULTILINKBUNDLE            = 0x6c
+	IFT_PROPATM                       = 0xc5
+	IFT_PROPBWAP2MP                   = 0xb8
+	IFT_PROPCNLS                      = 0x59
+	IFT_PROPDOCSWIRELESSDOWNSTREAM    = 0xb5
+	IFT_PROPDOCSWIRELESSMACLAYER      = 0xb4
+	IFT_PROPDOCSWIRELESSUPSTREAM      = 0xb6
+	IFT_PROPMUX                       = 0x36
+	IFT_PROPVIRTUAL                   = 0x35
+	IFT_PROPWIRELESSP2P               = 0x9d
+	IFT_PTPSERIAL                     = 0x16
+	IFT_PVC                           = 0xf2
+	IFT_Q2931                         = 0xc9
+	IFT_QLLC                          = 0x44
+	IFT_RADIOMAC                      = 0xbc
+	IFT_RADSL                         = 0x5f
+	IFT_REACHDSL                      = 0xc0
+	IFT_RFC1483                       = 0x9f
+	IFT_RS232                         = 0x21
+	IFT_RSRB                          = 0x4f
+	IFT_SDLC                          = 0x11
+	IFT_SDSL                          = 0x60
+	IFT_SHDSL                         = 0xa9
+	IFT_SIP                           = 0x1f
+	IFT_SIPSIG                        = 0xcc
+	IFT_SIPTG                         = 0xcb
+	IFT_SLIP                          = 0x1c
+	IFT_SMDSDXI                       = 0x2b
+	IFT_SMDSICIP                      = 0x34
+	IFT_SONET                         = 0x27
+	IFT_SONETOVERHEADCHANNEL          = 0xb9
+	IFT_SONETPATH                     = 0x32
+	IFT_SONETVT                       = 0x33
+	IFT_SRP                           = 0x97
+	IFT_SS7SIGLINK                    = 0x9c
+	IFT_STACKTOSTACK                  = 0x6f
+	IFT_STARLAN                       = 0xb
+	IFT_T1                            = 0x12
+	IFT_TDLC                          = 0x74
+	IFT_TELINK                        = 0xc8
+	IFT_TERMPAD                       = 0x5b
+	IFT_TR008                         = 0xb0
+	IFT_TRANSPHDLC                    = 0x7b
+	IFT_TUNNEL                        = 0x83
+	IFT_ULTRA                         = 0x1d
+	IFT_USB                           = 0xa0
+	IFT_V11                           = 0x40
+	IFT_V35                           = 0x2d
+	IFT_V36                           = 0x41
+	IFT_V37                           = 0x78
+	IFT_VDSL                          = 0x61
+	IFT_VIRTUALIPADDRESS              = 0x70
+	IFT_VIRTUALTG                     = 0xca
+	IFT_VOICEDID                      = 0xd5
+	IFT_VOICEEM                       = 0x64
+	IFT_VOICEEMFGD                    = 0xd3
+	IFT_VOICEENCAP                    = 0x67
+	IFT_VOICEFGDEANA                  = 0xd4
+	IFT_VOICEFXO                      = 0x65
+	IFT_VOICEFXS                      = 0x66
+	IFT_VOICEOVERATM                  = 0x98
+	IFT_VOICEOVERCABLE                = 0xc6
+	IFT_VOICEOVERFRAMERELAY           = 0x99
+	IFT_VOICEOVERIP                   = 0x68
+	IFT_WIREGUARD                     = 0xfb
+	IFT_X213                          = 0x5d
+	IFT_X25                           = 0x5
+	IFT_X25DDN                        = 0x4
+	IFT_X25HUNTGROUP                  = 0x7a
+	IFT_X25MLP                        = 0x79
+	IFT_X25PLE                        = 0x28
+	IFT_XETHER                        = 0x1a
+	IGNBRK                            = 0x1
+	IGNCR                             = 0x80
+	IGNPAR                            = 0x4
+	IMAXBEL                           = 0x2000
+	INLCR                             = 0x40
+	INPCK                             = 0x10
+	IN_CLASSA_HOST                    = 0xffffff
+	IN_CLASSA_MAX                     = 0x80
+	IN_CLASSA_NET                     = 0xff000000
+	IN_CLASSA_NSHIFT                  = 0x18
+	IN_CLASSB_HOST                    = 0xffff
+	IN_CLASSB_MAX                     = 0x10000
+	IN_CLASSB_NET                     = 0xffff0000
+	IN_CLASSB_NSHIFT                  = 0x10
+	IN_CLASSC_HOST                    = 0xff
+	IN_CLASSC_NET                     = 0xffffff00
+	IN_CLASSC_NSHIFT                  = 0x8
+	IN_CLASSD_HOST                    = 0xfffffff
+	IN_CLASSD_NET                     = 0xf0000000
+	IN_CLASSD_NSHIFT                  = 0x1c
+	IN_LOOPBACKNET                    = 0x7f
+	IN_RFC3021_HOST                   = 0x1
+	IN_RFC3021_NET                    = 0xfffffffe
+	IN_RFC3021_NSHIFT                 = 0x1f
+	IPPROTO_AH                        = 0x33
+	IPPROTO_CARP                      = 0x70
+	IPPROTO_DIVERT                    = 0x102
+	IPPROTO_DONE                      = 0x101
+	IPPROTO_DSTOPTS                   = 0x3c
+	IPPROTO_EGP                       = 0x8
+	IPPROTO_ENCAP                     = 0x62
+	IPPROTO_EON                       = 0x50
+	IPPROTO_ESP                       = 0x32
+	IPPROTO_ETHERIP                   = 0x61
+	IPPROTO_FRAGMENT                  = 0x2c
+	IPPROTO_GGP                       = 0x3
+	IPPROTO_GRE                       = 0x2f
+	IPPROTO_HOPOPTS                   = 0x0
+	IPPROTO_ICMP                      = 0x1
+	IPPROTO_ICMPV6                    = 0x3a
+	IPPROTO_IDP                       = 0x16
+	IPPROTO_IGMP                      = 0x2
+	IPPROTO_IP                        = 0x0
+	IPPROTO_IPCOMP                    = 0x6c
+	IPPROTO_IPIP                      = 0x4
+	IPPROTO_IPV4                      = 0x4
+	IPPROTO_IPV6                      = 0x29
+	IPPROTO_MAX                       = 0x100
+	IPPROTO_MAXID                     = 0x103
+	IPPROTO_MOBILE                    = 0x37
+	IPPROTO_MPLS                      = 0x89
+	IPPROTO_NONE                      = 0x3b
+	IPPROTO_PFSYNC                    = 0xf0
+	IPPROTO_PIM                       = 0x67
+	IPPROTO_PUP                       = 0xc
+	IPPROTO_RAW                       = 0xff
+	IPPROTO_ROUTING                   = 0x2b
+	IPPROTO_RSVP                      = 0x2e
+	IPPROTO_SCTP                      = 0x84
+	IPPROTO_TCP                       = 0x6
+	IPPROTO_TP                        = 0x1d
+	IPPROTO_UDP                       = 0x11
+	IPPROTO_UDPLITE                   = 0x88
+	IPV6_AUTH_LEVEL                   = 0x35
+	IPV6_AUTOFLOWLABEL                = 0x3b
+	IPV6_CHECKSUM                     = 0x1a
+	IPV6_DEFAULT_MULTICAST_HOPS       = 0x1
+	IPV6_DEFAULT_MULTICAST_LOOP       = 0x1
+	IPV6_DEFHLIM                      = 0x40
+	IPV6_DONTFRAG                     = 0x3e
+	IPV6_DSTOPTS                      = 0x32
+	IPV6_ESP_NETWORK_LEVEL            = 0x37
+	IPV6_ESP_TRANS_LEVEL              = 0x36
+	IPV6_FAITH                        = 0x1d
+	IPV6_FLOWINFO_MASK                = 0xfffffff
+	IPV6_FLOWLABEL_MASK               = 0xfffff
+	IPV6_FRAGTTL                      = 0x78
+	IPV6_HLIMDEC                      = 0x1
+	IPV6_HOPLIMIT                     = 0x2f
+	IPV6_HOPOPTS                      = 0x31
+	IPV6_IPCOMP_LEVEL                 = 0x3c
+	IPV6_JOIN_GROUP                   = 0xc
+	IPV6_LEAVE_GROUP                  = 0xd
+	IPV6_MAXHLIM                      = 0xff
+	IPV6_MAXPACKET                    = 0xffff
+	IPV6_MINHOPCOUNT                  = 0x41
+	IPV6_MMTU                         = 0x500
+	IPV6_MULTICAST_HOPS               = 0xa
+	IPV6_MULTICAST_IF                 = 0x9
+	IPV6_MULTICAST_LOOP               = 0xb
+	IPV6_NEXTHOP                      = 0x30
+	IPV6_OPTIONS                      = 0x1
+	IPV6_PATHMTU                      = 0x2c
+	IPV6_PIPEX                        = 0x3f
+	IPV6_PKTINFO                      = 0x2e
+	IPV6_PORTRANGE                    = 0xe
+	IPV6_PORTRANGE_DEFAULT            = 0x0
+	IPV6_PORTRANGE_HIGH               = 0x1
+	IPV6_PORTRANGE_LOW                = 0x2
+	IPV6_RECVDSTOPTS                  = 0x28
+	IPV6_RECVDSTPORT                  = 0x40
+	IPV6_RECVHOPLIMIT                 = 0x25
+	IPV6_RECVHOPOPTS                  = 0x27
+	IPV6_RECVPATHMTU                  = 0x2b
+	IPV6_RECVPKTINFO                  = 0x24
+	IPV6_RECVRTHDR                    = 0x26
+	IPV6_RECVTCLASS                   = 0x39
+	IPV6_RTABLE                       = 0x1021
+	IPV6_RTHDR                        = 0x33
+	IPV6_RTHDRDSTOPTS                 = 0x23
+	IPV6_RTHDR_LOOSE                  = 0x0
+	IPV6_RTHDR_STRICT                 = 0x1
+	IPV6_RTHDR_TYPE_0                 = 0x0
+	IPV6_SOCKOPT_RESERVED1            = 0x3
+	IPV6_TCLASS                       = 0x3d
+	IPV6_UNICAST_HOPS                 = 0x4
+	IPV6_USE_MIN_MTU                  = 0x2a
+	IPV6_V6ONLY                       = 0x1b
+	IPV6_VERSION                      = 0x60
+	IPV6_VERSION_MASK                 = 0xf0
+	IP_ADD_MEMBERSHIP                 = 0xc
+	IP_AUTH_LEVEL                     = 0x14
+	IP_DEFAULT_MULTICAST_LOOP         = 0x1
+	IP_DEFAULT_MULTICAST_TTL          = 0x1
+	IP_DF                             = 0x4000
+	IP_DROP_MEMBERSHIP                = 0xd
+	IP_ESP_NETWORK_LEVEL              = 0x16
+	IP_ESP_TRANS_LEVEL                = 0x15
+	IP_HDRINCL                        = 0x2
+	IP_IPCOMP_LEVEL                   = 0x1d
+	IP_IPDEFTTL                       = 0x25
+	IP_IPSECFLOWINFO                  = 0x24
+	IP_IPSEC_LOCAL_AUTH               = 0x1b
+	IP_IPSEC_LOCAL_CRED               = 0x19
+	IP_IPSEC_LOCAL_ID                 = 0x17
+	IP_IPSEC_REMOTE_AUTH              = 0x1c
+	IP_IPSEC_REMOTE_CRED              = 0x1a
+	IP_IPSEC_REMOTE_ID                = 0x18
+	IP_MAXPACKET                      = 0xffff
+	IP_MAX_MEMBERSHIPS                = 0xfff
+	IP_MF                             = 0x2000
+	IP_MINTTL                         = 0x20
+	IP_MIN_MEMBERSHIPS                = 0xf
+	IP_MSS                            = 0x240
+	IP_MULTICAST_IF                   = 0x9
+	IP_MULTICAST_LOOP                 = 0xb
+	IP_MULTICAST_TTL                  = 0xa
+	IP_OFFMASK                        = 0x1fff
+	IP_OPTIONS                        = 0x1
+	IP_PIPEX                          = 0x22
+	IP_PORTRANGE                      = 0x13
+	IP_PORTRANGE_DEFAULT              = 0x0
+	IP_PORTRANGE_HIGH                 = 0x1
+	IP_PORTRANGE_LOW                  = 0x2
+	IP_RECVDSTADDR                    = 0x7
+	IP_RECVDSTPORT                    = 0x21
+	IP_RECVIF                         = 0x1e
+	IP_RECVOPTS                       = 0x5
+	IP_RECVRETOPTS                    = 0x6
+	IP_RECVRTABLE                     = 0x23
+	IP_RECVTTL                        = 0x1f
+	IP_RETOPTS                        = 0x8
+	IP_RF                             = 0x8000
+	IP_RTABLE                         = 0x1021
+	IP_SENDSRCADDR                    = 0x7
+	IP_TOS                            = 0x3
+	IP_TTL                            = 0x4
+	ISIG                              = 0x80
+	ISTRIP                            = 0x20
+	ITIMER_PROF                       = 0x2
+	ITIMER_REAL                       = 0x0
+	ITIMER_VIRTUAL                    = 0x1
+	IUCLC                             = 0x1000
+	IXANY                             = 0x800
+	IXOFF                             = 0x400
+	IXON                              = 0x200
+	KERN_HOSTNAME                     = 0xa
+	KERN_OSRELEASE                    = 0x2
+	KERN_OSTYPE                       = 0x1
+	KERN_VERSION                      = 0x4
+	LCNT_OVERLOAD_FLUSH               = 0x6
+	LOCK_EX                           = 0x2
+	LOCK_NB                           = 0x4
+	LOCK_SH                           = 0x1
+	LOCK_UN                           = 0x8
+	MADV_DONTNEED                     = 0x4
+	MADV_FREE                         = 0x6
+	MADV_NORMAL                       = 0x0
+	MADV_RANDOM                       = 0x1
+	MADV_SEQUENTIAL                   = 0x2
+	MADV_SPACEAVAIL                   = 0x5
+	MADV_WILLNEED                     = 0x3
+	MAP_ANON                          = 0x1000
+	MAP_ANONYMOUS                     = 0x1000
+	MAP_CONCEAL                       = 0x8000
+	MAP_COPY                          = 0x2
+	MAP_FILE                          = 0x0
+	MAP_FIXED                         = 0x10
+	MAP_FLAGMASK                      = 0xfff7
+	MAP_HASSEMAPHORE                  = 0x0
+	MAP_INHERIT                       = 0x0
+	MAP_INHERIT_COPY                  = 0x1
+	MAP_INHERIT_NONE                  = 0x2
+	MAP_INHERIT_SHARE                 = 0x0
+	MAP_INHERIT_ZERO                  = 0x3
+	MAP_NOEXTEND                      = 0x0
+	MAP_NORESERVE                     = 0x0
+	MAP_PRIVATE                       = 0x2
+	MAP_RENAME                        = 0x0
+	MAP_SHARED                        = 0x1
+	MAP_STACK                         = 0x4000
+	MAP_TRYFIXED                      = 0x0
+	MCL_CURRENT                       = 0x1
+	MCL_FUTURE                        = 0x2
+	MNT_ASYNC                         = 0x40
+	MNT_DEFEXPORTED                   = 0x200
+	MNT_DELEXPORT                     = 0x20000
+	MNT_DOOMED                        = 0x8000000
+	MNT_EXPORTANON                    = 0x400
+	MNT_EXPORTED                      = 0x100
+	MNT_EXRDONLY                      = 0x80
+	MNT_FORCE                         = 0x80000
+	MNT_LAZY                          = 0x3
+	MNT_LOCAL                         = 0x1000
+	MNT_NOATIME                       = 0x8000
+	MNT_NODEV                         = 0x10
+	MNT_NOEXEC                        = 0x4
+	MNT_NOPERM                        = 0x20
+	MNT_NOSUID                        = 0x8
+	MNT_NOWAIT                        = 0x2
+	MNT_QUOTA                         = 0x2000
+	MNT_RDONLY                        = 0x1
+	MNT_RELOAD                        = 0x40000
+	MNT_ROOTFS                        = 0x4000
+	MNT_SOFTDEP                       = 0x4000000
+	MNT_STALLED                       = 0x100000
+	MNT_SWAPPABLE                     = 0x200000
+	MNT_SYNCHRONOUS                   = 0x2
+	MNT_UPDATE                        = 0x10000
+	MNT_VISFLAGMASK                   = 0x400ffff
+	MNT_WAIT                          = 0x1
+	MNT_WANTRDWR                      = 0x2000000
+	MNT_WXALLOWED                     = 0x800
+	MOUNT_AFS                         = "afs"
+	MOUNT_CD9660                      = "cd9660"
+	MOUNT_EXT2FS                      = "ext2fs"
+	MOUNT_FFS                         = "ffs"
+	MOUNT_FUSEFS                      = "fuse"
+	MOUNT_MFS                         = "mfs"
+	MOUNT_MSDOS                       = "msdos"
+	MOUNT_NCPFS                       = "ncpfs"
+	MOUNT_NFS                         = "nfs"
+	MOUNT_NTFS                        = "ntfs"
+	MOUNT_TMPFS                       = "tmpfs"
+	MOUNT_UDF                         = "udf"
+	MOUNT_UFS                         = "ffs"
+	MSG_BCAST                         = 0x100
+	MSG_CMSG_CLOEXEC                  = 0x800
+	MSG_CTRUNC                        = 0x20
+	MSG_DONTROUTE                     = 0x4
+	MSG_DONTWAIT                      = 0x80
+	MSG_EOR                           = 0x8
+	MSG_MCAST                         = 0x200
+	MSG_NOSIGNAL                      = 0x400
+	MSG_OOB                           = 0x1
+	MSG_PEEK                          = 0x2
+	MSG_TRUNC                         = 0x10
+	MSG_WAITALL                       = 0x40
+	MSG_WAITFORONE                    = 0x1000
+	MS_ASYNC                          = 0x1
+	MS_INVALIDATE                     = 0x4
+	MS_SYNC                           = 0x2
+	NAME_MAX                          = 0xff
+	NET_RT_DUMP                       = 0x1
+	NET_RT_FLAGS                      = 0x2
+	NET_RT_IFLIST                     = 0x3
+	NET_RT_IFNAMES                    = 0x6
+	NET_RT_MAXID                      = 0x8
+	NET_RT_SOURCE                     = 0x7
+	NET_RT_STATS                      = 0x4
+	NET_RT_TABLE                      = 0x5
+	NFDBITS                           = 0x20
+	NOFLSH                            = 0x80000000
+	NOKERNINFO                        = 0x2000000
+	NOTE_ATTRIB                       = 0x8
+	NOTE_CHANGE                       = 0x1
+	NOTE_CHILD                        = 0x4
+	NOTE_DELETE                       = 0x1
+	NOTE_EOF                          = 0x2
+	NOTE_EXEC                         = 0x20000000
+	NOTE_EXIT                         = 0x80000000
+	NOTE_EXTEND                       = 0x4
+	NOTE_FORK                         = 0x40000000
+	NOTE_LINK                         = 0x10
+	NOTE_LOWAT                        = 0x1
+	NOTE_OOB                          = 0x4
+	NOTE_PCTRLMASK                    = 0xf0000000
+	NOTE_PDATAMASK                    = 0xfffff
+	NOTE_RENAME                       = 0x20
+	NOTE_REVOKE                       = 0x40
+	NOTE_TRACK                        = 0x1
+	NOTE_TRACKERR                     = 0x2
+	NOTE_TRUNCATE                     = 0x80
+	NOTE_WRITE                        = 0x2
+	OCRNL                             = 0x10
+	OLCUC                             = 0x20
+	ONLCR                             = 0x2
+	ONLRET                            = 0x80
+	ONOCR                             = 0x40
+	ONOEOT                            = 0x8
+	OPOST                             = 0x1
+	OXTABS                            = 0x4
+	O_ACCMODE                         = 0x3
+	O_APPEND                          = 0x8
+	O_ASYNC                           = 0x40
+	O_CLOEXEC                         = 0x10000
+	O_CREAT                           = 0x200
+	O_DIRECTORY                       = 0x20000
+	O_DSYNC                           = 0x80
+	O_EXCL                            = 0x800
+	O_EXLOCK                          = 0x20
+	O_FSYNC                           = 0x80
+	O_NDELAY                          = 0x4
+	O_NOCTTY                          = 0x8000
+	O_NOFOLLOW                        = 0x100
+	O_NONBLOCK                        = 0x4
+	O_RDONLY                          = 0x0
+	O_RDWR                            = 0x2
+	O_RSYNC                           = 0x80
+	O_SHLOCK                          = 0x10
+	O_SYNC                            = 0x80
+	O_TRUNC                           = 0x400
+	O_WRONLY                          = 0x1
+	PARENB                            = 0x1000
+	PARMRK                            = 0x8
+	PARODD                            = 0x2000
+	PENDIN                            = 0x20000000
+	PF_FLUSH                          = 0x1
+	PRIO_PGRP                         = 0x1
+	PRIO_PROCESS                      = 0x0
+	PRIO_USER                         = 0x2
+	PROT_EXEC                         = 0x4
+	PROT_NONE                         = 0x0
+	PROT_READ                         = 0x1
+	PROT_WRITE                        = 0x2
+	RLIMIT_CORE                       = 0x4
+	RLIMIT_CPU                        = 0x0
+	RLIMIT_DATA                       = 0x2
+	RLIMIT_FSIZE                      = 0x1
+	RLIMIT_MEMLOCK                    = 0x6
+	RLIMIT_NOFILE                     = 0x8
+	RLIMIT_NPROC                      = 0x7
+	RLIMIT_RSS                        = 0x5
+	RLIMIT_STACK                      = 0x3
+	RLIM_INFINITY                     = 0x7fffffffffffffff
+	RTAX_AUTHOR                       = 0x6
+	RTAX_BFD                          = 0xb
+	RTAX_BRD                          = 0x7
+	RTAX_DNS                          = 0xc
+	RTAX_DST                          = 0x0
+	RTAX_GATEWAY                      = 0x1
+	RTAX_GENMASK                      = 0x3
+	RTAX_IFA                          = 0x5
+	RTAX_IFP                          = 0x4
+	RTAX_LABEL                        = 0xa
+	RTAX_MAX                          = 0xf
+	RTAX_NETMASK                      = 0x2
+	RTAX_SEARCH                       = 0xe
+	RTAX_SRC                          = 0x8
+	RTAX_SRCMASK                      = 0x9
+	RTAX_STATIC                       = 0xd
+	RTA_AUTHOR                        = 0x40
+	RTA_BFD                           = 0x800
+	RTA_BRD                           = 0x80
+	RTA_DNS                           = 0x1000
+	RTA_DST                           = 0x1
+	RTA_GATEWAY                       = 0x2
+	RTA_GENMASK                       = 0x8
+	RTA_IFA                           = 0x20
+	RTA_IFP                           = 0x10
+	RTA_LABEL                         = 0x400
+	RTA_NETMASK                       = 0x4
+	RTA_SEARCH                        = 0x4000
+	RTA_SRC                           = 0x100
+	RTA_SRCMASK                       = 0x200
+	RTA_STATIC                        = 0x2000
+	RTF_ANNOUNCE                      = 0x4000
+	RTF_BFD                           = 0x1000000
+	RTF_BLACKHOLE                     = 0x1000
+	RTF_BROADCAST                     = 0x400000
+	RTF_CACHED                        = 0x20000
+	RTF_CLONED                        = 0x10000
+	RTF_CLONING                       = 0x100
+	RTF_CONNECTED                     = 0x800000
+	RTF_DONE                          = 0x40
+	RTF_DYNAMIC                       = 0x10
+	RTF_FMASK                         = 0x110fc08
+	RTF_GATEWAY                       = 0x2
+	RTF_HOST                          = 0x4
+	RTF_LLINFO                        = 0x400
+	RTF_LOCAL                         = 0x200000
+	RTF_MODIFIED                      = 0x20
+	RTF_MPATH                         = 0x40000
+	RTF_MPLS                          = 0x100000
+	RTF_MULTICAST                     = 0x200
+	RTF_PERMANENT_ARP                 = 0x2000
+	RTF_PROTO1                        = 0x8000
+	RTF_PROTO2                        = 0x4000
+	RTF_PROTO3                        = 0x2000
+	RTF_REJECT                        = 0x8
+	RTF_STATIC                        = 0x800
+	RTF_UP                            = 0x1
+	RTF_USETRAILERS                   = 0x8000
+	RTM_80211INFO                     = 0x15
+	RTM_ADD                           = 0x1
+	RTM_BFD                           = 0x12
+	RTM_CHANGE                        = 0x3
+	RTM_CHGADDRATTR                   = 0x14
+	RTM_DELADDR                       = 0xd
+	RTM_DELETE                        = 0x2
+	RTM_DESYNC                        = 0x10
+	RTM_GET                           = 0x4
+	RTM_IFANNOUNCE                    = 0xf
+	RTM_IFINFO                        = 0xe
+	RTM_INVALIDATE                    = 0x11
+	RTM_LOSING                        = 0x5
+	RTM_MAXSIZE                       = 0x800
+	RTM_MISS                          = 0x7
+	RTM_NEWADDR                       = 0xc
+	RTM_PROPOSAL                      = 0x13
+	RTM_REDIRECT                      = 0x6
+	RTM_RESOLVE                       = 0xb
+	RTM_SOURCE                        = 0x16
+	RTM_VERSION                       = 0x5
+	RTV_EXPIRE                        = 0x4
+	RTV_HOPCOUNT                      = 0x2
+	RTV_MTU                           = 0x1
+	RTV_RPIPE                         = 0x8
+	RTV_RTT                           = 0x40
+	RTV_RTTVAR                        = 0x80
+	RTV_SPIPE                         = 0x10
+	RTV_SSTHRESH                      = 0x20
+	RT_TABLEID_BITS                   = 0x8
+	RT_TABLEID_MASK                   = 0xff
+	RT_TABLEID_MAX                    = 0xff
+	RUSAGE_CHILDREN                   = -0x1
+	RUSAGE_SELF                       = 0x0
+	RUSAGE_THREAD                     = 0x1
+	SCM_RIGHTS                        = 0x1
+	SCM_TIMESTAMP                     = 0x4
+	SEEK_CUR                          = 0x1
+	SEEK_END                          = 0x2
+	SEEK_SET                          = 0x0
+	SHUT_RD                           = 0x0
+	SHUT_RDWR                         = 0x2
+	SHUT_WR                           = 0x1
+	SIOCADDMULTI                      = 0x80206931
+	SIOCAIFADDR                       = 0x8040691a
+	SIOCAIFGROUP                      = 0x80286987
+	SIOCATMARK                        = 0x40047307
+	SIOCBRDGADD                       = 0x8060693c
+	SIOCBRDGADDL                      = 0x80606949
+	SIOCBRDGADDS                      = 0x80606941
+	SIOCBRDGARL                       = 0x808c694d
+	SIOCBRDGDADDR                     = 0x81286947
+	SIOCBRDGDEL                       = 0x8060693d
+	SIOCBRDGDELS                      = 0x80606942
+	SIOCBRDGFLUSH                     = 0x80606948
+	SIOCBRDGFRL                       = 0x808c694e
+	SIOCBRDGGCACHE                    = 0xc0146941
+	SIOCBRDGGFD                       = 0xc0146952
+	SIOCBRDGGHT                       = 0xc0146951
+	SIOCBRDGGIFFLGS                   = 0xc060693e
+	SIOCBRDGGMA                       = 0xc0146953
+	SIOCBRDGGPARAM                    = 0xc0406958
+	SIOCBRDGGPRI                      = 0xc0146950
+	SIOCBRDGGRL                       = 0xc030694f
+	SIOCBRDGGTO                       = 0xc0146946
+	SIOCBRDGIFS                       = 0xc0606942
+	SIOCBRDGRTS                       = 0xc0206943
+	SIOCBRDGSADDR                     = 0xc1286944
+	SIOCBRDGSCACHE                    = 0x80146940
+	SIOCBRDGSFD                       = 0x80146952
+	SIOCBRDGSHT                       = 0x80146951
+	SIOCBRDGSIFCOST                   = 0x80606955
+	SIOCBRDGSIFFLGS                   = 0x8060693f
+	SIOCBRDGSIFPRIO                   = 0x80606954
+	SIOCBRDGSIFPROT                   = 0x8060694a
+	SIOCBRDGSMA                       = 0x80146953
+	SIOCBRDGSPRI                      = 0x80146950
+	SIOCBRDGSPROTO                    = 0x8014695a
+	SIOCBRDGSTO                       = 0x80146945
+	SIOCBRDGSTXHC                     = 0x80146959
+	SIOCDELLABEL                      = 0x80206997
+	SIOCDELMULTI                      = 0x80206932
+	SIOCDIFADDR                       = 0x80206919
+	SIOCDIFGROUP                      = 0x80286989
+	SIOCDIFPARENT                     = 0x802069b4
+	SIOCDIFPHYADDR                    = 0x80206949
+	SIOCDPWE3NEIGHBOR                 = 0x802069de
+	SIOCDVNETID                       = 0x802069af
+	SIOCGETKALIVE                     = 0xc01869a4
+	SIOCGETLABEL                      = 0x8020699a
+	SIOCGETMPWCFG                     = 0xc02069ae
+	SIOCGETPFLOW                      = 0xc02069fe
+	SIOCGETPFSYNC                     = 0xc02069f8
+	SIOCGETSGCNT                      = 0xc0207534
+	SIOCGETVIFCNT                     = 0xc0287533
+	SIOCGETVLAN                       = 0xc0206990
+	SIOCGIFADDR                       = 0xc0206921
+	SIOCGIFBRDADDR                    = 0xc0206923
+	SIOCGIFCONF                       = 0xc0106924
+	SIOCGIFDATA                       = 0xc020691b
+	SIOCGIFDESCR                      = 0xc0206981
+	SIOCGIFDSTADDR                    = 0xc0206922
+	SIOCGIFFLAGS                      = 0xc0206911
+	SIOCGIFGATTR                      = 0xc028698b
+	SIOCGIFGENERIC                    = 0xc020693a
+	SIOCGIFGLIST                      = 0xc028698d
+	SIOCGIFGMEMB                      = 0xc028698a
+	SIOCGIFGROUP                      = 0xc0286988
+	SIOCGIFHARDMTU                    = 0xc02069a5
+	SIOCGIFLLPRIO                     = 0xc02069b6
+	SIOCGIFMEDIA                      = 0xc0406938
+	SIOCGIFMETRIC                     = 0xc0206917
+	SIOCGIFMTU                        = 0xc020697e
+	SIOCGIFNETMASK                    = 0xc0206925
+	SIOCGIFPAIR                       = 0xc02069b1
+	SIOCGIFPARENT                     = 0xc02069b3
+	SIOCGIFPRIORITY                   = 0xc020699c
+	SIOCGIFRDOMAIN                    = 0xc02069a0
+	SIOCGIFRTLABEL                    = 0xc0206983
+	SIOCGIFRXR                        = 0x802069aa
+	SIOCGIFSFFPAGE                    = 0xc1126939
+	SIOCGIFXFLAGS                     = 0xc020699e
+	SIOCGLIFPHYADDR                   = 0xc218694b
+	SIOCGLIFPHYDF                     = 0xc02069c2
+	SIOCGLIFPHYECN                    = 0xc02069c8
+	SIOCGLIFPHYRTABLE                 = 0xc02069a2
+	SIOCGLIFPHYTTL                    = 0xc02069a9
+	SIOCGPGRP                         = 0x40047309
+	SIOCGPWE3                         = 0xc0206998
+	SIOCGPWE3CTRLWORD                 = 0xc02069dc
+	SIOCGPWE3FAT                      = 0xc02069dd
+	SIOCGPWE3NEIGHBOR                 = 0xc21869de
+	SIOCGRXHPRIO                      = 0xc02069db
+	SIOCGSPPPPARAMS                   = 0xc0206994
+	SIOCGTXHPRIO                      = 0xc02069c6
+	SIOCGUMBINFO                      = 0xc02069be
+	SIOCGUMBPARAM                     = 0xc02069c0
+	SIOCGVH                           = 0xc02069f6
+	SIOCGVNETFLOWID                   = 0xc02069c4
+	SIOCGVNETID                       = 0xc02069a7
+	SIOCIFAFATTACH                    = 0x801169ab
+	SIOCIFAFDETACH                    = 0x801169ac
+	SIOCIFCREATE                      = 0x8020697a
+	SIOCIFDESTROY                     = 0x80206979
+	SIOCIFGCLONERS                    = 0xc0106978
+	SIOCSETKALIVE                     = 0x801869a3
+	SIOCSETLABEL                      = 0x80206999
+	SIOCSETMPWCFG                     = 0x802069ad
+	SIOCSETPFLOW                      = 0x802069fd
+	SIOCSETPFSYNC                     = 0x802069f7
+	SIOCSETVLAN                       = 0x8020698f
+	SIOCSIFADDR                       = 0x8020690c
+	SIOCSIFBRDADDR                    = 0x80206913
+	SIOCSIFDESCR                      = 0x80206980
+	SIOCSIFDSTADDR                    = 0x8020690e
+	SIOCSIFFLAGS                      = 0x80206910
+	SIOCSIFGATTR                      = 0x8028698c
+	SIOCSIFGENERIC                    = 0x80206939
+	SIOCSIFLLADDR                     = 0x8020691f
+	SIOCSIFLLPRIO                     = 0x802069b5
+	SIOCSIFMEDIA                      = 0xc0206937
+	SIOCSIFMETRIC                     = 0x80206918
+	SIOCSIFMTU                        = 0x8020697f
+	SIOCSIFNETMASK                    = 0x80206916
+	SIOCSIFPAIR                       = 0x802069b0
+	SIOCSIFPARENT                     = 0x802069b2
+	SIOCSIFPRIORITY                   = 0x8020699b
+	SIOCSIFRDOMAIN                    = 0x8020699f
+	SIOCSIFRTLABEL                    = 0x80206982
+	SIOCSIFXFLAGS                     = 0x8020699d
+	SIOCSLIFPHYADDR                   = 0x8218694a
+	SIOCSLIFPHYDF                     = 0x802069c1
+	SIOCSLIFPHYECN                    = 0x802069c7
+	SIOCSLIFPHYRTABLE                 = 0x802069a1
+	SIOCSLIFPHYTTL                    = 0x802069a8
+	SIOCSPGRP                         = 0x80047308
+	SIOCSPWE3CTRLWORD                 = 0x802069dc
+	SIOCSPWE3FAT                      = 0x802069dd
+	SIOCSPWE3NEIGHBOR                 = 0x821869de
+	SIOCSRXHPRIO                      = 0x802069db
+	SIOCSSPPPPARAMS                   = 0x80206993
+	SIOCSTXHPRIO                      = 0x802069c5
+	SIOCSUMBPARAM                     = 0x802069bf
+	SIOCSVH                           = 0xc02069f5
+	SIOCSVNETFLOWID                   = 0x802069c3
+	SIOCSVNETID                       = 0x802069a6
+	SOCK_CLOEXEC                      = 0x8000
+	SOCK_DGRAM                        = 0x2
+	SOCK_DNS                          = 0x1000
+	SOCK_NONBLOCK                     = 0x4000
+	SOCK_RAW                          = 0x3
+	SOCK_RDM                          = 0x4
+	SOCK_SEQPACKET                    = 0x5
+	SOCK_STREAM                       = 0x1
+	SOL_SOCKET                        = 0xffff
+	SOMAXCONN                         = 0x80
+	SO_ACCEPTCONN                     = 0x2
+	SO_BINDANY                        = 0x1000
+	SO_BROADCAST                      = 0x20
+	SO_DEBUG                          = 0x1
+	SO_DOMAIN                         = 0x1024
+	SO_DONTROUTE                      = 0x10
+	SO_ERROR                          = 0x1007
+	SO_KEEPALIVE                      = 0x8
+	SO_LINGER                         = 0x80
+	SO_NETPROC                        = 0x1020
+	SO_OOBINLINE                      = 0x100
+	SO_PEERCRED                       = 0x1022
+	SO_PROTOCOL                       = 0x1025
+	SO_RCVBUF                         = 0x1002
+	SO_RCVLOWAT                       = 0x1004
+	SO_RCVTIMEO                       = 0x1006
+	SO_REUSEADDR                      = 0x4
+	SO_REUSEPORT                      = 0x200
+	SO_RTABLE                         = 0x1021
+	SO_SNDBUF                         = 0x1001
+	SO_SNDLOWAT                       = 0x1003
+	SO_SNDTIMEO                       = 0x1005
+	SO_SPLICE                         = 0x1023
+	SO_TIMESTAMP                      = 0x800
+	SO_TYPE                           = 0x1008
+	SO_USELOOPBACK                    = 0x40
+	SO_ZEROIZE                        = 0x2000
+	S_BLKSIZE                         = 0x200
+	S_IEXEC                           = 0x40
+	S_IFBLK                           = 0x6000
+	S_IFCHR                           = 0x2000
+	S_IFDIR                           = 0x4000
+	S_IFIFO                           = 0x1000
+	S_IFLNK                           = 0xa000
+	S_IFMT                            = 0xf000
+	S_IFREG                           = 0x8000
+	S_IFSOCK                          = 0xc000
+	S_IREAD                           = 0x100
+	S_IRGRP                           = 0x20
+	S_IROTH                           = 0x4
+	S_IRUSR                           = 0x100
+	S_IRWXG                           = 0x38
+	S_IRWXO                           = 0x7
+	S_IRWXU                           = 0x1c0
+	S_ISGID                           = 0x400
+	S_ISTXT                           = 0x200
+	S_ISUID                           = 0x800
+	S_ISVTX                           = 0x200
+	S_IWGRP                           = 0x10
+	S_IWOTH                           = 0x2
+	S_IWRITE                          = 0x80
+	S_IWUSR                           = 0x80
+	S_IXGRP                           = 0x8
+	S_IXOTH                           = 0x1
+	S_IXUSR                           = 0x40
+	TCIFLUSH                          = 0x1
+	TCIOFF                            = 0x3
+	TCIOFLUSH                         = 0x3
+	TCION                             = 0x4
+	TCOFLUSH                          = 0x2
+	TCOOFF                            = 0x1
+	TCOON                             = 0x2
+	TCPOPT_EOL                        = 0x0
+	TCPOPT_MAXSEG                     = 0x2
+	TCPOPT_NOP                        = 0x1
+	TCPOPT_SACK                       = 0x5
+	TCPOPT_SACK_HDR                   = 0x1010500
+	TCPOPT_SACK_PERMITTED             = 0x4
+	TCPOPT_SACK_PERMIT_HDR            = 0x1010402
+	TCPOPT_SIGNATURE                  = 0x13
+	TCPOPT_TIMESTAMP                  = 0x8
+	TCPOPT_TSTAMP_HDR                 = 0x101080a
+	TCPOPT_WINDOW                     = 0x3
+	TCP_INFO                          = 0x9
+	TCP_MAXSEG                        = 0x2
+	TCP_MAXWIN                        = 0xffff
+	TCP_MAX_SACK                      = 0x3
+	TCP_MAX_WINSHIFT                  = 0xe
+	TCP_MD5SIG                        = 0x4
+	TCP_MSS                           = 0x200
+	TCP_NODELAY                       = 0x1
+	TCP_NOPUSH                        = 0x10
+	TCP_SACKHOLE_LIMIT                = 0x80
+	TCP_SACK_ENABLE                   = 0x8
+	TCSAFLUSH                         = 0x2
+	TIMER_ABSTIME                     = 0x1
+	TIMER_RELTIME                     = 0x0
+	TIOCCBRK                          = 0x2000747a
+	TIOCCDTR                          = 0x20007478
+	TIOCCHKVERAUTH                    = 0x2000741e
+	TIOCCLRVERAUTH                    = 0x2000741d
+	TIOCCONS                          = 0x80047462
+	TIOCDRAIN                         = 0x2000745e
+	TIOCEXCL                          = 0x2000740d
+	TIOCEXT                           = 0x80047460
+	TIOCFLAG_CLOCAL                   = 0x2
+	TIOCFLAG_CRTSCTS                  = 0x4
+	TIOCFLAG_MDMBUF                   = 0x8
+	TIOCFLAG_PPS                      = 0x10
+	TIOCFLAG_SOFTCAR                  = 0x1
+	TIOCFLUSH                         = 0x80047410
+	TIOCGETA                          = 0x402c7413
+	TIOCGETD                          = 0x4004741a
+	TIOCGFLAGS                        = 0x4004745d
+	TIOCGPGRP                         = 0x40047477
+	TIOCGSID                          = 0x40047463
+	TIOCGTSTAMP                       = 0x4010745b
+	TIOCGWINSZ                        = 0x40087468
+	TIOCMBIC                          = 0x8004746b
+	TIOCMBIS                          = 0x8004746c
+	TIOCMGET                          = 0x4004746a
+	TIOCMODG                          = 0x4004746a
+	TIOCMODS                          = 0x8004746d
+	TIOCMSET                          = 0x8004746d
+	TIOCM_CAR                         = 0x40
+	TIOCM_CD                          = 0x40
+	TIOCM_CTS                         = 0x20
+	TIOCM_DSR                         = 0x100
+	TIOCM_DTR                         = 0x2
+	TIOCM_LE                          = 0x1
+	TIOCM_RI                          = 0x80
+	TIOCM_RNG                         = 0x80
+	TIOCM_RTS                         = 0x4
+	TIOCM_SR                          = 0x10
+	TIOCM_ST                          = 0x8
+	TIOCNOTTY                         = 0x20007471
+	TIOCNXCL                          = 0x2000740e
+	TIOCOUTQ                          = 0x40047473
+	TIOCPKT                           = 0x80047470
+	TIOCPKT_DATA                      = 0x0
+	TIOCPKT_DOSTOP                    = 0x20
+	TIOCPKT_FLUSHREAD                 = 0x1
+	TIOCPKT_FLUSHWRITE                = 0x2
+	TIOCPKT_IOCTL                     = 0x40
+	TIOCPKT_NOSTOP                    = 0x10
+	TIOCPKT_START                     = 0x8
+	TIOCPKT_STOP                      = 0x4
+	TIOCREMOTE                        = 0x80047469
+	TIOCSBRK                          = 0x2000747b
+	TIOCSCTTY                         = 0x20007461
+	TIOCSDTR                          = 0x20007479
+	TIOCSETA                          = 0x802c7414
+	TIOCSETAF                         = 0x802c7416
+	TIOCSETAW                         = 0x802c7415
+	TIOCSETD                          = 0x8004741b
+	TIOCSETVERAUTH                    = 0x8004741c
+	TIOCSFLAGS                        = 0x8004745c
+	TIOCSIG                           = 0x8004745f
+	TIOCSPGRP                         = 0x80047476
+	TIOCSTART                         = 0x2000746e
+	TIOCSTAT                          = 0x20007465
+	TIOCSTOP                          = 0x2000746f
+	TIOCSTSTAMP                       = 0x8008745a
+	TIOCSWINSZ                        = 0x80087467
+	TIOCUCNTL                         = 0x80047466
+	TIOCUCNTL_CBRK                    = 0x7a
+	TIOCUCNTL_SBRK                    = 0x7b
+	TOSTOP                            = 0x400000
+	UTIME_NOW                         = -0x2
+	UTIME_OMIT                        = -0x1
+	VDISCARD                          = 0xf
+	VDSUSP                            = 0xb
+	VEOF                              = 0x0
+	VEOL                              = 0x1
+	VEOL2                             = 0x2
+	VERASE                            = 0x3
+	VINTR                             = 0x8
+	VKILL                             = 0x5
+	VLNEXT                            = 0xe
+	VMIN                              = 0x10
+	VM_ANONMIN                        = 0x7
+	VM_LOADAVG                        = 0x2
+	VM_MALLOC_CONF                    = 0xc
+	VM_MAXID                          = 0xd
+	VM_MAXSLP                         = 0xa
+	VM_METER                          = 0x1
+	VM_NKMEMPAGES                     = 0x6
+	VM_PSSTRINGS                      = 0x3
+	VM_SWAPENCRYPT                    = 0x5
+	VM_USPACE                         = 0xb
+	VM_UVMEXP                         = 0x4
+	VM_VNODEMIN                       = 0x9
+	VM_VTEXTMIN                       = 0x8
+	VQUIT                             = 0x9
+	VREPRINT                          = 0x6
+	VSTART                            = 0xc
+	VSTATUS                           = 0x12
+	VSTOP                             = 0xd
+	VSUSP                             = 0xa
+	VTIME                             = 0x11
+	VWERASE                           = 0x4
+	WALTSIG                           = 0x4
+	WCONTINUED                        = 0x8
+	WCOREFLAG                         = 0x80
+	WNOHANG                           = 0x1
+	WUNTRACED                         = 0x2
+	XCASE                             = 0x1000000
+)
+
+// Errors
+const (
+	E2BIG           = syscall.Errno(0x7)
+	EACCES          = syscall.Errno(0xd)
+	EADDRINUSE      = syscall.Errno(0x30)
+	EADDRNOTAVAIL   = syscall.Errno(0x31)
+	EAFNOSUPPORT    = syscall.Errno(0x2f)
+	EAGAIN          = syscall.Errno(0x23)
+	EALREADY        = syscall.Errno(0x25)
+	EAUTH           = syscall.Errno(0x50)
+	EBADF           = syscall.Errno(0x9)
+	EBADMSG         = syscall.Errno(0x5c)
+	EBADRPC         = syscall.Errno(0x48)
+	EBUSY           = syscall.Errno(0x10)
+	ECANCELED       = syscall.Errno(0x58)
+	ECHILD          = syscall.Errno(0xa)
+	ECONNABORTED    = syscall.Errno(0x35)
+	ECONNREFUSED    = syscall.Errno(0x3d)
+	ECONNRESET      = syscall.Errno(0x36)
+	EDEADLK         = syscall.Errno(0xb)
+	EDESTADDRREQ    = syscall.Errno(0x27)
+	EDOM            = syscall.Errno(0x21)
+	EDQUOT          = syscall.Errno(0x45)
+	EEXIST          = syscall.Errno(0x11)
+	EFAULT          = syscall.Errno(0xe)
+	EFBIG           = syscall.Errno(0x1b)
+	EFTYPE          = syscall.Errno(0x4f)
+	EHOSTDOWN       = syscall.Errno(0x40)
+	EHOSTUNREACH    = syscall.Errno(0x41)
+	EIDRM           = syscall.Errno(0x59)
+	EILSEQ          = syscall.Errno(0x54)
+	EINPROGRESS     = syscall.Errno(0x24)
+	EINTR           = syscall.Errno(0x4)
+	EINVAL          = syscall.Errno(0x16)
+	EIO             = syscall.Errno(0x5)
+	EIPSEC          = syscall.Errno(0x52)
+	EISCONN         = syscall.Errno(0x38)
+	EISDIR          = syscall.Errno(0x15)
+	ELAST           = syscall.Errno(0x5f)
+	ELOOP           = syscall.Errno(0x3e)
+	EMEDIUMTYPE     = syscall.Errno(0x56)
+	EMFILE          = syscall.Errno(0x18)
+	EMLINK          = syscall.Errno(0x1f)
+	EMSGSIZE        = syscall.Errno(0x28)
+	ENAMETOOLONG    = syscall.Errno(0x3f)
+	ENEEDAUTH       = syscall.Errno(0x51)
+	ENETDOWN        = syscall.Errno(0x32)
+	ENETRESET       = syscall.Errno(0x34)
+	ENETUNREACH     = syscall.Errno(0x33)
+	ENFILE          = syscall.Errno(0x17)
+	ENOATTR         = syscall.Errno(0x53)
+	ENOBUFS         = syscall.Errno(0x37)
+	ENODEV          = syscall.Errno(0x13)
+	ENOENT          = syscall.Errno(0x2)
+	ENOEXEC         = syscall.Errno(0x8)
+	ENOLCK          = syscall.Errno(0x4d)
+	ENOMEDIUM       = syscall.Errno(0x55)
+	ENOMEM          = syscall.Errno(0xc)
+	ENOMSG          = syscall.Errno(0x5a)
+	ENOPROTOOPT     = syscall.Errno(0x2a)
+	ENOSPC          = syscall.Errno(0x1c)
+	ENOSYS          = syscall.Errno(0x4e)
+	ENOTBLK         = syscall.Errno(0xf)
+	ENOTCONN        = syscall.Errno(0x39)
+	ENOTDIR         = syscall.Errno(0x14)
+	ENOTEMPTY       = syscall.Errno(0x42)
+	ENOTRECOVERABLE = syscall.Errno(0x5d)
+	ENOTSOCK        = syscall.Errno(0x26)
+	ENOTSUP         = syscall.Errno(0x5b)
+	ENOTTY          = syscall.Errno(0x19)
+	ENXIO           = syscall.Errno(0x6)
+	EOPNOTSUPP      = syscall.Errno(0x2d)
+	EOVERFLOW       = syscall.Errno(0x57)
+	EOWNERDEAD      = syscall.Errno(0x5e)
+	EPERM           = syscall.Errno(0x1)
+	EPFNOSUPPORT    = syscall.Errno(0x2e)
+	EPIPE           = syscall.Errno(0x20)
+	EPROCLIM        = syscall.Errno(0x43)
+	EPROCUNAVAIL    = syscall.Errno(0x4c)
+	EPROGMISMATCH   = syscall.Errno(0x4b)
+	EPROGUNAVAIL    = syscall.Errno(0x4a)
+	EPROTO          = syscall.Errno(0x5f)
+	EPROTONOSUPPORT = syscall.Errno(0x2b)
+	EPROTOTYPE      = syscall.Errno(0x29)
+	ERANGE          = syscall.Errno(0x22)
+	EREMOTE         = syscall.Errno(0x47)
+	EROFS           = syscall.Errno(0x1e)
+	ERPCMISMATCH    = syscall.Errno(0x49)
+	ESHUTDOWN       = syscall.Errno(0x3a)
+	ESOCKTNOSUPPORT = syscall.Errno(0x2c)
+	ESPIPE          = syscall.Errno(0x1d)
+	ESRCH           = syscall.Errno(0x3)
+	ESTALE          = syscall.Errno(0x46)
+	ETIMEDOUT       = syscall.Errno(0x3c)
+	ETOOMANYREFS    = syscall.Errno(0x3b)
+	ETXTBSY         = syscall.Errno(0x1a)
+	EUSERS          = syscall.Errno(0x44)
+	EWOULDBLOCK     = syscall.Errno(0x23)
+	EXDEV           = syscall.Errno(0x12)
+)
+
+// Signals
+const (
+	SIGABRT   = syscall.Signal(0x6)
+	SIGALRM   = syscall.Signal(0xe)
+	SIGBUS    = syscall.Signal(0xa)
+	SIGCHLD   = syscall.Signal(0x14)
+	SIGCONT   = syscall.Signal(0x13)
+	SIGEMT    = syscall.Signal(0x7)
+	SIGFPE    = syscall.Signal(0x8)
+	SIGHUP    = syscall.Signal(0x1)
+	SIGILL    = syscall.Signal(0x4)
+	SIGINFO   = syscall.Signal(0x1d)
+	SIGINT    = syscall.Signal(0x2)
+	SIGIO     = syscall.Signal(0x17)
+	SIGIOT    = syscall.Signal(0x6)
+	SIGKILL   = syscall.Signal(0x9)
+	SIGPIPE   = syscall.Signal(0xd)
+	SIGPROF   = syscall.Signal(0x1b)
+	SIGQUIT   = syscall.Signal(0x3)
+	SIGSEGV   = syscall.Signal(0xb)
+	SIGSTOP   = syscall.Signal(0x11)
+	SIGSYS    = syscall.Signal(0xc)
+	SIGTERM   = syscall.Signal(0xf)
+	SIGTHR    = syscall.Signal(0x20)
+	SIGTRAP   = syscall.Signal(0x5)
+	SIGTSTP   = syscall.Signal(0x12)
+	SIGTTIN   = syscall.Signal(0x15)
+	SIGTTOU   = syscall.Signal(0x16)
+	SIGURG    = syscall.Signal(0x10)
+	SIGUSR1   = syscall.Signal(0x1e)
+	SIGUSR2   = syscall.Signal(0x1f)
+	SIGVTALRM = syscall.Signal(0x1a)
+	SIGWINCH  = syscall.Signal(0x1c)
+	SIGXCPU   = syscall.Signal(0x18)
+	SIGXFSZ   = syscall.Signal(0x19)
+)
+
+// Error table
+var errorList = [...]struct {
+	num  syscall.Errno
+	name string
+	desc string
+}{
+	{1, "EPERM", "operation not permitted"},
+	{2, "ENOENT", "no such file or directory"},
+	{3, "ESRCH", "no such process"},
+	{4, "EINTR", "interrupted system call"},
+	{5, "EIO", "input/output error"},
+	{6, "ENXIO", "device not configured"},
+	{7, "E2BIG", "argument list too long"},
+	{8, "ENOEXEC", "exec format error"},
+	{9, "EBADF", "bad file descriptor"},
+	{10, "ECHILD", "no child processes"},
+	{11, "EDEADLK", "resource deadlock avoided"},
+	{12, "ENOMEM", "cannot allocate memory"},
+	{13, "EACCES", "permission denied"},
+	{14, "EFAULT", "bad address"},
+	{15, "ENOTBLK", "block device required"},
+	{16, "EBUSY", "device busy"},
+	{17, "EEXIST", "file exists"},
+	{18, "EXDEV", "cross-device link"},
+	{19, "ENODEV", "operation not supported by device"},
+	{20, "ENOTDIR", "not a directory"},
+	{21, "EISDIR", "is a directory"},
+	{22, "EINVAL", "invalid argument"},
+	{23, "ENFILE", "too many open files in system"},
+	{24, "EMFILE", "too many open files"},
+	{25, "ENOTTY", "inappropriate ioctl for device"},
+	{26, "ETXTBSY", "text file busy"},
+	{27, "EFBIG", "file too large"},
+	{28, "ENOSPC", "no space left on device"},
+	{29, "ESPIPE", "illegal seek"},
+	{30, "EROFS", "read-only file system"},
+	{31, "EMLINK", "too many links"},
+	{32, "EPIPE", "broken pipe"},
+	{33, "EDOM", "numerical argument out of domain"},
+	{34, "ERANGE", "result too large"},
+	{35, "EAGAIN", "resource temporarily unavailable"},
+	{36, "EINPROGRESS", "operation now in progress"},
+	{37, "EALREADY", "operation already in progress"},
+	{38, "ENOTSOCK", "socket operation on non-socket"},
+	{39, "EDESTADDRREQ", "destination address required"},
+	{40, "EMSGSIZE", "message too long"},
+	{41, "EPROTOTYPE", "protocol wrong type for socket"},
+	{42, "ENOPROTOOPT", "protocol not available"},
+	{43, "EPROTONOSUPPORT", "protocol not supported"},
+	{44, "ESOCKTNOSUPPORT", "socket type not supported"},
+	{45, "EOPNOTSUPP", "operation not supported"},
+	{46, "EPFNOSUPPORT", "protocol family not supported"},
+	{47, "EAFNOSUPPORT", "address family not supported by protocol family"},
+	{48, "EADDRINUSE", "address already in use"},
+	{49, "EADDRNOTAVAIL", "can't assign requested address"},
+	{50, "ENETDOWN", "network is down"},
+	{51, "ENETUNREACH", "network is unreachable"},
+	{52, "ENETRESET", "network dropped connection on reset"},
+	{53, "ECONNABORTED", "software caused connection abort"},
+	{54, "ECONNRESET", "connection reset by peer"},
+	{55, "ENOBUFS", "no buffer space available"},
+	{56, "EISCONN", "socket is already connected"},
+	{57, "ENOTCONN", "socket is not connected"},
+	{58, "ESHUTDOWN", "can't send after socket shutdown"},
+	{59, "ETOOMANYREFS", "too many references: can't splice"},
+	{60, "ETIMEDOUT", "operation timed out"},
+	{61, "ECONNREFUSED", "connection refused"},
+	{62, "ELOOP", "too many levels of symbolic links"},
+	{63, "ENAMETOOLONG", "file name too long"},
+	{64, "EHOSTDOWN", "host is down"},
+	{65, "EHOSTUNREACH", "no route to host"},
+	{66, "ENOTEMPTY", "directory not empty"},
+	{67, "EPROCLIM", "too many processes"},
+	{68, "EUSERS", "too many users"},
+	{69, "EDQUOT", "disk quota exceeded"},
+	{70, "ESTALE", "stale NFS file handle"},
+	{71, "EREMOTE", "too many levels of remote in path"},
+	{72, "EBADRPC", "RPC struct is bad"},
+	{73, "ERPCMISMATCH", "RPC version wrong"},
+	{74, "EPROGUNAVAIL", "RPC program not available"},
+	{75, "EPROGMISMATCH", "program version wrong"},
+	{76, "EPROCUNAVAIL", "bad procedure for program"},
+	{77, "ENOLCK", "no locks available"},
+	{78, "ENOSYS", "function not implemented"},
+	{79, "EFTYPE", "inappropriate file type or format"},
+	{80, "EAUTH", "authentication error"},
+	{81, "ENEEDAUTH", "need authenticator"},
+	{82, "EIPSEC", "IPsec processing failure"},
+	{83, "ENOATTR", "attribute not found"},
+	{84, "EILSEQ", "illegal byte sequence"},
+	{85, "ENOMEDIUM", "no medium found"},
+	{86, "EMEDIUMTYPE", "wrong medium type"},
+	{87, "EOVERFLOW", "value too large to be stored in data type"},
+	{88, "ECANCELED", "operation canceled"},
+	{89, "EIDRM", "identifier removed"},
+	{90, "ENOMSG", "no message of desired type"},
+	{91, "ENOTSUP", "not supported"},
+	{92, "EBADMSG", "bad message"},
+	{93, "ENOTRECOVERABLE", "state not recoverable"},
+	{94, "EOWNERDEAD", "previous owner died"},
+	{95, "ELAST", "protocol error"},
+}
+
+// Signal table
+var signalList = [...]struct {
+	num  syscall.Signal
+	name string
+	desc string
+}{
+	{1, "SIGHUP", "hangup"},
+	{2, "SIGINT", "interrupt"},
+	{3, "SIGQUIT", "quit"},
+	{4, "SIGILL", "illegal instruction"},
+	{5, "SIGTRAP", "trace/BPT trap"},
+	{6, "SIGABRT", "abort trap"},
+	{7, "SIGEMT", "EMT trap"},
+	{8, "SIGFPE", "floating point exception"},
+	{9, "SIGKILL", "killed"},
+	{10, "SIGBUS", "bus error"},
+	{11, "SIGSEGV", "segmentation fault"},
+	{12, "SIGSYS", "bad system call"},
+	{13, "SIGPIPE", "broken pipe"},
+	{14, "SIGALRM", "alarm clock"},
+	{15, "SIGTERM", "terminated"},
+	{16, "SIGURG", "urgent I/O condition"},
+	{17, "SIGSTOP", "suspended (signal)"},
+	{18, "SIGTSTP", "suspended"},
+	{19, "SIGCONT", "continued"},
+	{20, "SIGCHLD", "child exited"},
+	{21, "SIGTTIN", "stopped (tty input)"},
+	{22, "SIGTTOU", "stopped (tty output)"},
+	{23, "SIGIO", "I/O possible"},
+	{24, "SIGXCPU", "cputime limit exceeded"},
+	{25, "SIGXFSZ", "filesize limit exceeded"},
+	{26, "SIGVTALRM", "virtual timer expired"},
+	{27, "SIGPROF", "profiling timer expired"},
+	{28, "SIGWINCH", "window size changes"},
+	{29, "SIGINFO", "information request"},
+	{30, "SIGUSR1", "user defined signal 1"},
+	{31, "SIGUSR2", "user defined signal 2"},
+	{32, "SIGTHR", "thread AST"},
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_riscv64.go b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_riscv64.go
new file mode 100644
index 0000000..13d4030
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zerrors_openbsd_riscv64.go
@@ -0,0 +1,1904 @@
+// mkerrors.sh -m64
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+//go:build riscv64 && openbsd
+// +build riscv64,openbsd
+
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs -- -m64 _const.go
+
+package unix
+
+import "syscall"
+
+const (
+	AF_APPLETALK                      = 0x10
+	AF_BLUETOOTH                      = 0x20
+	AF_CCITT                          = 0xa
+	AF_CHAOS                          = 0x5
+	AF_CNT                            = 0x15
+	AF_COIP                           = 0x14
+	AF_DATAKIT                        = 0x9
+	AF_DECnet                         = 0xc
+	AF_DLI                            = 0xd
+	AF_E164                           = 0x1a
+	AF_ECMA                           = 0x8
+	AF_ENCAP                          = 0x1c
+	AF_HYLINK                         = 0xf
+	AF_IMPLINK                        = 0x3
+	AF_INET                           = 0x2
+	AF_INET6                          = 0x18
+	AF_IPX                            = 0x17
+	AF_ISDN                           = 0x1a
+	AF_ISO                            = 0x7
+	AF_KEY                            = 0x1e
+	AF_LAT                            = 0xe
+	AF_LINK                           = 0x12
+	AF_LOCAL                          = 0x1
+	AF_MAX                            = 0x24
+	AF_MPLS                           = 0x21
+	AF_NATM                           = 0x1b
+	AF_NS                             = 0x6
+	AF_OSI                            = 0x7
+	AF_PUP                            = 0x4
+	AF_ROUTE                          = 0x11
+	AF_SIP                            = 0x1d
+	AF_SNA                            = 0xb
+	AF_UNIX                           = 0x1
+	AF_UNSPEC                         = 0x0
+	ALTWERASE                         = 0x200
+	ARPHRD_ETHER                      = 0x1
+	ARPHRD_FRELAY                     = 0xf
+	ARPHRD_IEEE1394                   = 0x18
+	ARPHRD_IEEE802                    = 0x6
+	B0                                = 0x0
+	B110                              = 0x6e
+	B115200                           = 0x1c200
+	B1200                             = 0x4b0
+	B134                              = 0x86
+	B14400                            = 0x3840
+	B150                              = 0x96
+	B1800                             = 0x708
+	B19200                            = 0x4b00
+	B200                              = 0xc8
+	B230400                           = 0x38400
+	B2400                             = 0x960
+	B28800                            = 0x7080
+	B300                              = 0x12c
+	B38400                            = 0x9600
+	B4800                             = 0x12c0
+	B50                               = 0x32
+	B57600                            = 0xe100
+	B600                              = 0x258
+	B7200                             = 0x1c20
+	B75                               = 0x4b
+	B76800                            = 0x12c00
+	B9600                             = 0x2580
+	BIOCFLUSH                         = 0x20004268
+	BIOCGBLEN                         = 0x40044266
+	BIOCGDIRFILT                      = 0x4004427c
+	BIOCGDLT                          = 0x4004426a
+	BIOCGDLTLIST                      = 0xc010427b
+	BIOCGETIF                         = 0x4020426b
+	BIOCGFILDROP                      = 0x40044278
+	BIOCGHDRCMPLT                     = 0x40044274
+	BIOCGRSIG                         = 0x40044273
+	BIOCGRTIMEOUT                     = 0x4010426e
+	BIOCGSTATS                        = 0x4008426f
+	BIOCIMMEDIATE                     = 0x80044270
+	BIOCLOCK                          = 0x20004276
+	BIOCPROMISC                       = 0x20004269
+	BIOCSBLEN                         = 0xc0044266
+	BIOCSDIRFILT                      = 0x8004427d
+	BIOCSDLT                          = 0x8004427a
+	BIOCSETF                          = 0x80104267
+	BIOCSETIF                         = 0x8020426c
+	BIOCSETWF                         = 0x80104277
+	BIOCSFILDROP                      = 0x80044279
+	BIOCSHDRCMPLT                     = 0x80044275
+	BIOCSRSIG                         = 0x80044272
+	BIOCSRTIMEOUT                     = 0x8010426d
+	BIOCVERSION                       = 0x40044271
+	BPF_A                             = 0x10
+	BPF_ABS                           = 0x20
+	BPF_ADD                           = 0x0
+	BPF_ALIGNMENT                     = 0x4
+	BPF_ALU                           = 0x4
+	BPF_AND                           = 0x50
+	BPF_B                             = 0x10
+	BPF_DIRECTION_IN                  = 0x1
+	BPF_DIRECTION_OUT                 = 0x2
+	BPF_DIV                           = 0x30
+	BPF_FILDROP_CAPTURE               = 0x1
+	BPF_FILDROP_DROP                  = 0x2
+	BPF_FILDROP_PASS                  = 0x0
+	BPF_F_DIR_IN                      = 0x10
+	BPF_F_DIR_MASK                    = 0x30
+	BPF_F_DIR_OUT                     = 0x20
+	BPF_F_DIR_SHIFT                   = 0x4
+	BPF_F_FLOWID                      = 0x8
+	BPF_F_PRI_MASK                    = 0x7
+	BPF_H                             = 0x8
+	BPF_IMM                           = 0x0
+	BPF_IND                           = 0x40
+	BPF_JA                            = 0x0
+	BPF_JEQ                           = 0x10
+	BPF_JGE                           = 0x30
+	BPF_JGT                           = 0x20
+	BPF_JMP                           = 0x5
+	BPF_JSET                          = 0x40
+	BPF_K                             = 0x0
+	BPF_LD                            = 0x0
+	BPF_LDX                           = 0x1
+	BPF_LEN                           = 0x80
+	BPF_LSH                           = 0x60
+	BPF_MAJOR_VERSION                 = 0x1
+	BPF_MAXBUFSIZE                    = 0x200000
+	BPF_MAXINSNS                      = 0x200
+	BPF_MEM                           = 0x60
+	BPF_MEMWORDS                      = 0x10
+	BPF_MINBUFSIZE                    = 0x20
+	BPF_MINOR_VERSION                 = 0x1
+	BPF_MISC                          = 0x7
+	BPF_MSH                           = 0xa0
+	BPF_MUL                           = 0x20
+	BPF_NEG                           = 0x80
+	BPF_OR                            = 0x40
+	BPF_RELEASE                       = 0x30bb6
+	BPF_RET                           = 0x6
+	BPF_RND                           = 0xc0
+	BPF_RSH                           = 0x70
+	BPF_ST                            = 0x2
+	BPF_STX                           = 0x3
+	BPF_SUB                           = 0x10
+	BPF_TAX                           = 0x0
+	BPF_TXA                           = 0x80
+	BPF_W                             = 0x0
+	BPF_X                             = 0x8
+	BRKINT                            = 0x2
+	CFLUSH                            = 0xf
+	CLOCAL                            = 0x8000
+	CLOCK_BOOTTIME                    = 0x6
+	CLOCK_MONOTONIC                   = 0x3
+	CLOCK_PROCESS_CPUTIME_ID          = 0x2
+	CLOCK_REALTIME                    = 0x0
+	CLOCK_THREAD_CPUTIME_ID           = 0x4
+	CLOCK_UPTIME                      = 0x5
+	CPUSTATES                         = 0x6
+	CP_IDLE                           = 0x5
+	CP_INTR                           = 0x4
+	CP_NICE                           = 0x1
+	CP_SPIN                           = 0x3
+	CP_SYS                            = 0x2
+	CP_USER                           = 0x0
+	CREAD                             = 0x800
+	CRTSCTS                           = 0x10000
+	CS5                               = 0x0
+	CS6                               = 0x100
+	CS7                               = 0x200
+	CS8                               = 0x300
+	CSIZE                             = 0x300
+	CSTART                            = 0x11
+	CSTATUS                           = 0xff
+	CSTOP                             = 0x13
+	CSTOPB                            = 0x400
+	CSUSP                             = 0x1a
+	CTL_HW                            = 0x6
+	CTL_KERN                          = 0x1
+	CTL_MAXNAME                       = 0xc
+	CTL_NET                           = 0x4
+	DIOCADDQUEUE                      = 0xc110445d
+	DIOCADDRULE                       = 0xcd604404
+	DIOCADDSTATE                      = 0xc1084425
+	DIOCCHANGERULE                    = 0xcd60441a
+	DIOCCLRIFFLAG                     = 0xc028445a
+	DIOCCLRSRCNODES                   = 0x20004455
+	DIOCCLRSTATES                     = 0xc0e04412
+	DIOCCLRSTATUS                     = 0xc0284416
+	DIOCGETLIMIT                      = 0xc0084427
+	DIOCGETQSTATS                     = 0xc1204460
+	DIOCGETQUEUE                      = 0xc110445f
+	DIOCGETQUEUES                     = 0xc110445e
+	DIOCGETRULE                       = 0xcd604407
+	DIOCGETRULES                      = 0xcd604406
+	DIOCGETRULESET                    = 0xc444443b
+	DIOCGETRULESETS                   = 0xc444443a
+	DIOCGETSRCNODES                   = 0xc0104454
+	DIOCGETSTATE                      = 0xc1084413
+	DIOCGETSTATES                     = 0xc0104419
+	DIOCGETSTATUS                     = 0xc1e84415
+	DIOCGETSYNFLWATS                  = 0xc0084463
+	DIOCGETTIMEOUT                    = 0xc008441e
+	DIOCIGETIFACES                    = 0xc0284457
+	DIOCKILLSRCNODES                  = 0xc080445b
+	DIOCKILLSTATES                    = 0xc0e04429
+	DIOCNATLOOK                       = 0xc0504417
+	DIOCOSFPADD                       = 0xc088444f
+	DIOCOSFPFLUSH                     = 0x2000444e
+	DIOCOSFPGET                       = 0xc0884450
+	DIOCRADDADDRS                     = 0xc4504443
+	DIOCRADDTABLES                    = 0xc450443d
+	DIOCRCLRADDRS                     = 0xc4504442
+	DIOCRCLRASTATS                    = 0xc4504448
+	DIOCRCLRTABLES                    = 0xc450443c
+	DIOCRCLRTSTATS                    = 0xc4504441
+	DIOCRDELADDRS                     = 0xc4504444
+	DIOCRDELTABLES                    = 0xc450443e
+	DIOCRGETADDRS                     = 0xc4504446
+	DIOCRGETASTATS                    = 0xc4504447
+	DIOCRGETTABLES                    = 0xc450443f
+	DIOCRGETTSTATS                    = 0xc4504440
+	DIOCRINADEFINE                    = 0xc450444d
+	DIOCRSETADDRS                     = 0xc4504445
+	DIOCRSETTFLAGS                    = 0xc450444a
+	DIOCRTSTADDRS                     = 0xc4504449
+	DIOCSETDEBUG                      = 0xc0044418
+	DIOCSETHOSTID                     = 0xc0044456
+	DIOCSETIFFLAG                     = 0xc0284459
+	DIOCSETLIMIT                      = 0xc0084428
+	DIOCSETREASS                      = 0xc004445c
+	DIOCSETSTATUSIF                   = 0xc0284414
+	DIOCSETSYNCOOKIES                 = 0xc0014462
+	DIOCSETSYNFLWATS                  = 0xc0084461
+	DIOCSETTIMEOUT                    = 0xc008441d
+	DIOCSTART                         = 0x20004401
+	DIOCSTOP                          = 0x20004402
+	DIOCXBEGIN                        = 0xc0104451
+	DIOCXCOMMIT                       = 0xc0104452
+	DIOCXROLLBACK                     = 0xc0104453
+	DLT_ARCNET                        = 0x7
+	DLT_ATM_RFC1483                   = 0xb
+	DLT_AX25                          = 0x3
+	DLT_CHAOS                         = 0x5
+	DLT_C_HDLC                        = 0x68
+	DLT_EN10MB                        = 0x1
+	DLT_EN3MB                         = 0x2
+	DLT_ENC                           = 0xd
+	DLT_FDDI                          = 0xa
+	DLT_IEEE802                       = 0x6
+	DLT_IEEE802_11                    = 0x69
+	DLT_IEEE802_11_RADIO              = 0x7f
+	DLT_LOOP                          = 0xc
+	DLT_MPLS                          = 0xdb
+	DLT_NULL                          = 0x0
+	DLT_OPENFLOW                      = 0x10b
+	DLT_PFLOG                         = 0x75
+	DLT_PFSYNC                        = 0x12
+	DLT_PPP                           = 0x9
+	DLT_PPP_BSDOS                     = 0x10
+	DLT_PPP_ETHER                     = 0x33
+	DLT_PPP_SERIAL                    = 0x32
+	DLT_PRONET                        = 0x4
+	DLT_RAW                           = 0xe
+	DLT_SLIP                          = 0x8
+	DLT_SLIP_BSDOS                    = 0xf
+	DLT_USBPCAP                       = 0xf9
+	DLT_USER0                         = 0x93
+	DLT_USER1                         = 0x94
+	DLT_USER10                        = 0x9d
+	DLT_USER11                        = 0x9e
+	DLT_USER12                        = 0x9f
+	DLT_USER13                        = 0xa0
+	DLT_USER14                        = 0xa1
+	DLT_USER15                        = 0xa2
+	DLT_USER2                         = 0x95
+	DLT_USER3                         = 0x96
+	DLT_USER4                         = 0x97
+	DLT_USER5                         = 0x98
+	DLT_USER6                         = 0x99
+	DLT_USER7                         = 0x9a
+	DLT_USER8                         = 0x9b
+	DLT_USER9                         = 0x9c
+	DT_BLK                            = 0x6
+	DT_CHR                            = 0x2
+	DT_DIR                            = 0x4
+	DT_FIFO                           = 0x1
+	DT_LNK                            = 0xa
+	DT_REG                            = 0x8
+	DT_SOCK                           = 0xc
+	DT_UNKNOWN                        = 0x0
+	ECHO                              = 0x8
+	ECHOCTL                           = 0x40
+	ECHOE                             = 0x2
+	ECHOK                             = 0x4
+	ECHOKE                            = 0x1
+	ECHONL                            = 0x10
+	ECHOPRT                           = 0x20
+	EMT_TAGOVF                        = 0x1
+	EMUL_ENABLED                      = 0x1
+	EMUL_NATIVE                       = 0x2
+	ENDRUNDISC                        = 0x9
+	ETH64_8021_RSVD_MASK              = 0xfffffffffff0
+	ETH64_8021_RSVD_PREFIX            = 0x180c2000000
+	ETHERMIN                          = 0x2e
+	ETHERMTU                          = 0x5dc
+	ETHERTYPE_8023                    = 0x4
+	ETHERTYPE_AARP                    = 0x80f3
+	ETHERTYPE_ACCTON                  = 0x8390
+	ETHERTYPE_AEONIC                  = 0x8036
+	ETHERTYPE_ALPHA                   = 0x814a
+	ETHERTYPE_AMBER                   = 0x6008
+	ETHERTYPE_AMOEBA                  = 0x8145
+	ETHERTYPE_AOE                     = 0x88a2
+	ETHERTYPE_APOLLO                  = 0x80f7
+	ETHERTYPE_APOLLODOMAIN            = 0x8019
+	ETHERTYPE_APPLETALK               = 0x809b
+	ETHERTYPE_APPLITEK                = 0x80c7
+	ETHERTYPE_ARGONAUT                = 0x803a
+	ETHERTYPE_ARP                     = 0x806
+	ETHERTYPE_AT                      = 0x809b
+	ETHERTYPE_ATALK                   = 0x809b
+	ETHERTYPE_ATOMIC                  = 0x86df
+	ETHERTYPE_ATT                     = 0x8069
+	ETHERTYPE_ATTSTANFORD             = 0x8008
+	ETHERTYPE_AUTOPHON                = 0x806a
+	ETHERTYPE_AXIS                    = 0x8856
+	ETHERTYPE_BCLOOP                  = 0x9003
+	ETHERTYPE_BOFL                    = 0x8102
+	ETHERTYPE_CABLETRON               = 0x7034
+	ETHERTYPE_CHAOS                   = 0x804
+	ETHERTYPE_COMDESIGN               = 0x806c
+	ETHERTYPE_COMPUGRAPHIC            = 0x806d
+	ETHERTYPE_COUNTERPOINT            = 0x8062
+	ETHERTYPE_CRONUS                  = 0x8004
+	ETHERTYPE_CRONUSVLN               = 0x8003
+	ETHERTYPE_DCA                     = 0x1234
+	ETHERTYPE_DDE                     = 0x807b
+	ETHERTYPE_DEBNI                   = 0xaaaa
+	ETHERTYPE_DECAM                   = 0x8048
+	ETHERTYPE_DECCUST                 = 0x6006
+	ETHERTYPE_DECDIAG                 = 0x6005
+	ETHERTYPE_DECDNS                  = 0x803c
+	ETHERTYPE_DECDTS                  = 0x803e
+	ETHERTYPE_DECEXPER                = 0x6000
+	ETHERTYPE_DECLAST                 = 0x8041
+	ETHERTYPE_DECLTM                  = 0x803f
+	ETHERTYPE_DECMUMPS                = 0x6009
+	ETHERTYPE_DECNETBIOS              = 0x8040
+	ETHERTYPE_DELTACON                = 0x86de
+	ETHERTYPE_DIDDLE                  = 0x4321
+	ETHERTYPE_DLOG1                   = 0x660
+	ETHERTYPE_DLOG2                   = 0x661
+	ETHERTYPE_DN                      = 0x6003
+	ETHERTYPE_DOGFIGHT                = 0x1989
+	ETHERTYPE_DSMD                    = 0x8039
+	ETHERTYPE_EAPOL                   = 0x888e
+	ETHERTYPE_ECMA                    = 0x803
+	ETHERTYPE_ENCRYPT                 = 0x803d
+	ETHERTYPE_ES                      = 0x805d
+	ETHERTYPE_EXCELAN                 = 0x8010
+	ETHERTYPE_EXPERDATA               = 0x8049
+	ETHERTYPE_FLIP                    = 0x8146
+	ETHERTYPE_FLOWCONTROL             = 0x8808
+	ETHERTYPE_FRARP                   = 0x808
+	ETHERTYPE_GENDYN                  = 0x8068
+	ETHERTYPE_HAYES                   = 0x8130
+	ETHERTYPE_HIPPI_FP                = 0x8180
+	ETHERTYPE_HITACHI                 = 0x8820
+	ETHERTYPE_HP                      = 0x8005
+	ETHERTYPE_IEEEPUP                 = 0xa00
+	ETHERTYPE_IEEEPUPAT               = 0xa01
+	ETHERTYPE_IMLBL                   = 0x4c42
+	ETHERTYPE_IMLBLDIAG               = 0x424c
+	ETHERTYPE_IP                      = 0x800
+	ETHERTYPE_IPAS                    = 0x876c
+	ETHERTYPE_IPV6                    = 0x86dd
+	ETHERTYPE_IPX                     = 0x8137
+	ETHERTYPE_IPXNEW                  = 0x8037
+	ETHERTYPE_KALPANA                 = 0x8582
+	ETHERTYPE_LANBRIDGE               = 0x8038
+	ETHERTYPE_LANPROBE                = 0x8888
+	ETHERTYPE_LAT                     = 0x6004
+	ETHERTYPE_LBACK                   = 0x9000
+	ETHERTYPE_LITTLE                  = 0x8060
+	ETHERTYPE_LLDP                    = 0x88cc
+	ETHERTYPE_LOGICRAFT               = 0x8148
+	ETHERTYPE_LOOPBACK                = 0x9000
+	ETHERTYPE_MACSEC                  = 0x88e5
+	ETHERTYPE_MATRA                   = 0x807a
+	ETHERTYPE_MAX                     = 0xffff
+	ETHERTYPE_MERIT                   = 0x807c
+	ETHERTYPE_MICP                    = 0x873a
+	ETHERTYPE_MOPDL                   = 0x6001
+	ETHERTYPE_MOPRC                   = 0x6002
+	ETHERTYPE_MOTOROLA                = 0x818d
+	ETHERTYPE_MPLS                    = 0x8847
+	ETHERTYPE_MPLS_MCAST              = 0x8848
+	ETHERTYPE_MUMPS                   = 0x813f
+	ETHERTYPE_NBPCC                   = 0x3c04
+	ETHERTYPE_NBPCLAIM                = 0x3c09
+	ETHERTYPE_NBPCLREQ                = 0x3c05
+	ETHERTYPE_NBPCLRSP                = 0x3c06
+	ETHERTYPE_NBPCREQ                 = 0x3c02
+	ETHERTYPE_NBPCRSP                 = 0x3c03
+	ETHERTYPE_NBPDG                   = 0x3c07
+	ETHERTYPE_NBPDGB                  = 0x3c08
+	ETHERTYPE_NBPDLTE                 = 0x3c0a
+	ETHERTYPE_NBPRAR                  = 0x3c0c
+	ETHERTYPE_NBPRAS                  = 0x3c0b
+	ETHERTYPE_NBPRST                  = 0x3c0d
+	ETHERTYPE_NBPSCD                  = 0x3c01
+	ETHERTYPE_NBPVCD                  = 0x3c00
+	ETHERTYPE_NBS                     = 0x802
+	ETHERTYPE_NCD                     = 0x8149
+	ETHERTYPE_NESTAR                  = 0x8006
+	ETHERTYPE_NETBEUI                 = 0x8191
+	ETHERTYPE_NHRP                    = 0x2001
+	ETHERTYPE_NOVELL                  = 0x8138
+	ETHERTYPE_NS                      = 0x600
+	ETHERTYPE_NSAT                    = 0x601
+	ETHERTYPE_NSCOMPAT                = 0x807
+	ETHERTYPE_NSH                     = 0x984f
+	ETHERTYPE_NTRAILER                = 0x10
+	ETHERTYPE_OS9                     = 0x7007
+	ETHERTYPE_OS9NET                  = 0x7009
+	ETHERTYPE_PACER                   = 0x80c6
+	ETHERTYPE_PBB                     = 0x88e7
+	ETHERTYPE_PCS                     = 0x4242
+	ETHERTYPE_PLANNING                = 0x8044
+	ETHERTYPE_PPP                     = 0x880b
+	ETHERTYPE_PPPOE                   = 0x8864
+	ETHERTYPE_PPPOEDISC               = 0x8863
+	ETHERTYPE_PRIMENTS                = 0x7031
+	ETHERTYPE_PUP                     = 0x200
+	ETHERTYPE_PUPAT                   = 0x200
+	ETHERTYPE_QINQ                    = 0x88a8
+	ETHERTYPE_RACAL                   = 0x7030
+	ETHERTYPE_RATIONAL                = 0x8150
+	ETHERTYPE_RAWFR                   = 0x6559
+	ETHERTYPE_RCL                     = 0x1995
+	ETHERTYPE_RDP                     = 0x8739
+	ETHERTYPE_RETIX                   = 0x80f2
+	ETHERTYPE_REVARP                  = 0x8035
+	ETHERTYPE_SCA                     = 0x6007
+	ETHERTYPE_SECTRA                  = 0x86db
+	ETHERTYPE_SECUREDATA              = 0x876d
+	ETHERTYPE_SGITW                   = 0x817e
+	ETHERTYPE_SG_BOUNCE               = 0x8016
+	ETHERTYPE_SG_DIAG                 = 0x8013
+	ETHERTYPE_SG_NETGAMES             = 0x8014
+	ETHERTYPE_SG_RESV                 = 0x8015
+	ETHERTYPE_SIMNET                  = 0x5208
+	ETHERTYPE_SLOW                    = 0x8809
+	ETHERTYPE_SNA                     = 0x80d5
+	ETHERTYPE_SNMP                    = 0x814c
+	ETHERTYPE_SONIX                   = 0xfaf5
+	ETHERTYPE_SPIDER                  = 0x809f
+	ETHERTYPE_SPRITE                  = 0x500
+	ETHERTYPE_STP                     = 0x8181
+	ETHERTYPE_TALARIS                 = 0x812b
+	ETHERTYPE_TALARISMC               = 0x852b
+	ETHERTYPE_TCPCOMP                 = 0x876b
+	ETHERTYPE_TCPSM                   = 0x9002
+	ETHERTYPE_TEC                     = 0x814f
+	ETHERTYPE_TIGAN                   = 0x802f
+	ETHERTYPE_TRAIL                   = 0x1000
+	ETHERTYPE_TRANSETHER              = 0x6558
+	ETHERTYPE_TYMSHARE                = 0x802e
+	ETHERTYPE_UBBST                   = 0x7005
+	ETHERTYPE_UBDEBUG                 = 0x900
+	ETHERTYPE_UBDIAGLOOP              = 0x7002
+	ETHERTYPE_UBDL                    = 0x7000
+	ETHERTYPE_UBNIU                   = 0x7001
+	ETHERTYPE_UBNMC                   = 0x7003
+	ETHERTYPE_VALID                   = 0x1600
+	ETHERTYPE_VARIAN                  = 0x80dd
+	ETHERTYPE_VAXELN                  = 0x803b
+	ETHERTYPE_VEECO                   = 0x8067
+	ETHERTYPE_VEXP                    = 0x805b
+	ETHERTYPE_VGLAB                   = 0x8131
+	ETHERTYPE_VINES                   = 0xbad
+	ETHERTYPE_VINESECHO               = 0xbaf
+	ETHERTYPE_VINESLOOP               = 0xbae
+	ETHERTYPE_VITAL                   = 0xff00
+	ETHERTYPE_VLAN                    = 0x8100
+	ETHERTYPE_VLTLMAN                 = 0x8080
+	ETHERTYPE_VPROD                   = 0x805c
+	ETHERTYPE_VURESERVED              = 0x8147
+	ETHERTYPE_WATERLOO                = 0x8130
+	ETHERTYPE_WELLFLEET               = 0x8103
+	ETHERTYPE_X25                     = 0x805
+	ETHERTYPE_X75                     = 0x801
+	ETHERTYPE_XNSSM                   = 0x9001
+	ETHERTYPE_XTP                     = 0x817d
+	ETHER_ADDR_LEN                    = 0x6
+	ETHER_ALIGN                       = 0x2
+	ETHER_CRC_LEN                     = 0x4
+	ETHER_CRC_POLY_BE                 = 0x4c11db6
+	ETHER_CRC_POLY_LE                 = 0xedb88320
+	ETHER_HDR_LEN                     = 0xe
+	ETHER_MAX_DIX_LEN                 = 0x600
+	ETHER_MAX_HARDMTU_LEN             = 0xff9b
+	ETHER_MAX_LEN                     = 0x5ee
+	ETHER_MIN_LEN                     = 0x40
+	ETHER_TYPE_LEN                    = 0x2
+	ETHER_VLAN_ENCAP_LEN              = 0x4
+	EVFILT_AIO                        = -0x3
+	EVFILT_DEVICE                     = -0x8
+	EVFILT_EXCEPT                     = -0x9
+	EVFILT_PROC                       = -0x5
+	EVFILT_READ                       = -0x1
+	EVFILT_SIGNAL                     = -0x6
+	EVFILT_SYSCOUNT                   = 0x9
+	EVFILT_TIMER                      = -0x7
+	EVFILT_VNODE                      = -0x4
+	EVFILT_WRITE                      = -0x2
+	EVL_ENCAPLEN                      = 0x4
+	EVL_PRIO_BITS                     = 0xd
+	EVL_PRIO_MAX                      = 0x7
+	EVL_VLID_MASK                     = 0xfff
+	EVL_VLID_MAX                      = 0xffe
+	EVL_VLID_MIN                      = 0x1
+	EVL_VLID_NULL                     = 0x0
+	EV_ADD                            = 0x1
+	EV_CLEAR                          = 0x20
+	EV_DELETE                         = 0x2
+	EV_DISABLE                        = 0x8
+	EV_DISPATCH                       = 0x80
+	EV_ENABLE                         = 0x4
+	EV_EOF                            = 0x8000
+	EV_ERROR                          = 0x4000
+	EV_FLAG1                          = 0x2000
+	EV_ONESHOT                        = 0x10
+	EV_RECEIPT                        = 0x40
+	EV_SYSFLAGS                       = 0xf800
+	EXTA                              = 0x4b00
+	EXTB                              = 0x9600
+	EXTPROC                           = 0x800
+	FD_CLOEXEC                        = 0x1
+	FD_SETSIZE                        = 0x400
+	FLUSHO                            = 0x800000
+	F_DUPFD                           = 0x0
+	F_DUPFD_CLOEXEC                   = 0xa
+	F_GETFD                           = 0x1
+	F_GETFL                           = 0x3
+	F_GETLK                           = 0x7
+	F_GETOWN                          = 0x5
+	F_ISATTY                          = 0xb
+	F_OK                              = 0x0
+	F_RDLCK                           = 0x1
+	F_SETFD                           = 0x2
+	F_SETFL                           = 0x4
+	F_SETLK                           = 0x8
+	F_SETLKW                          = 0x9
+	F_SETOWN                          = 0x6
+	F_UNLCK                           = 0x2
+	F_WRLCK                           = 0x3
+	HUPCL                             = 0x4000
+	HW_MACHINE                        = 0x1
+	ICANON                            = 0x100
+	ICMP6_FILTER                      = 0x12
+	ICRNL                             = 0x100
+	IEXTEN                            = 0x400
+	IFAN_ARRIVAL                      = 0x0
+	IFAN_DEPARTURE                    = 0x1
+	IFF_ALLMULTI                      = 0x200
+	IFF_BROADCAST                     = 0x2
+	IFF_CANTCHANGE                    = 0x8e52
+	IFF_DEBUG                         = 0x4
+	IFF_LINK0                         = 0x1000
+	IFF_LINK1                         = 0x2000
+	IFF_LINK2                         = 0x4000
+	IFF_LOOPBACK                      = 0x8
+	IFF_MULTICAST                     = 0x8000
+	IFF_NOARP                         = 0x80
+	IFF_OACTIVE                       = 0x400
+	IFF_POINTOPOINT                   = 0x10
+	IFF_PROMISC                       = 0x100
+	IFF_RUNNING                       = 0x40
+	IFF_SIMPLEX                       = 0x800
+	IFF_STATICARP                     = 0x20
+	IFF_UP                            = 0x1
+	IFNAMSIZ                          = 0x10
+	IFT_1822                          = 0x2
+	IFT_A12MPPSWITCH                  = 0x82
+	IFT_AAL2                          = 0xbb
+	IFT_AAL5                          = 0x31
+	IFT_ADSL                          = 0x5e
+	IFT_AFLANE8023                    = 0x3b
+	IFT_AFLANE8025                    = 0x3c
+	IFT_ARAP                          = 0x58
+	IFT_ARCNET                        = 0x23
+	IFT_ARCNETPLUS                    = 0x24
+	IFT_ASYNC                         = 0x54
+	IFT_ATM                           = 0x25
+	IFT_ATMDXI                        = 0x69
+	IFT_ATMFUNI                       = 0x6a
+	IFT_ATMIMA                        = 0x6b
+	IFT_ATMLOGICAL                    = 0x50
+	IFT_ATMRADIO                      = 0xbd
+	IFT_ATMSUBINTERFACE               = 0x86
+	IFT_ATMVCIENDPT                   = 0xc2
+	IFT_ATMVIRTUAL                    = 0x95
+	IFT_BGPPOLICYACCOUNTING           = 0xa2
+	IFT_BLUETOOTH                     = 0xf8
+	IFT_BRIDGE                        = 0xd1
+	IFT_BSC                           = 0x53
+	IFT_CARP                          = 0xf7
+	IFT_CCTEMUL                       = 0x3d
+	IFT_CEPT                          = 0x13
+	IFT_CES                           = 0x85
+	IFT_CHANNEL                       = 0x46
+	IFT_CNR                           = 0x55
+	IFT_COFFEE                        = 0x84
+	IFT_COMPOSITELINK                 = 0x9b
+	IFT_DCN                           = 0x8d
+	IFT_DIGITALPOWERLINE              = 0x8a
+	IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
+	IFT_DLSW                          = 0x4a
+	IFT_DOCSCABLEDOWNSTREAM           = 0x80
+	IFT_DOCSCABLEMACLAYER             = 0x7f
+	IFT_DOCSCABLEUPSTREAM             = 0x81
+	IFT_DOCSCABLEUPSTREAMCHANNEL      = 0xcd
+	IFT_DS0                           = 0x51
+	IFT_DS0BUNDLE                     = 0x52
+	IFT_DS1FDL                        = 0xaa
+	IFT_DS3                           = 0x1e
+	IFT_DTM                           = 0x8c
+	IFT_DUMMY                         = 0xf1
+	IFT_DVBASILN                      = 0xac
+	IFT_DVBASIOUT                     = 0xad
+	IFT_DVBRCCDOWNSTREAM              = 0x93
+	IFT_DVBRCCMACLAYER                = 0x92
+	IFT_DVBRCCUPSTREAM                = 0x94
+	IFT_ECONET                        = 0xce
+	IFT_ENC                           = 0xf4
+	IFT_EON                           = 0x19
+	IFT_EPLRS                         = 0x57
+	IFT_ESCON                         = 0x49
+	IFT_ETHER                         = 0x6
+	IFT_FAITH                         = 0xf3
+	IFT_FAST                          = 0x7d
+	IFT_FASTETHER                     = 0x3e
+	IFT_FASTETHERFX                   = 0x45
+	IFT_FDDI                          = 0xf
+	IFT_FIBRECHANNEL                  = 0x38
+	IFT_FRAMERELAYINTERCONNECT        = 0x3a
+	IFT_FRAMERELAYMPI                 = 0x5c
+	IFT_FRDLCIENDPT                   = 0xc1
+	IFT_FRELAY                        = 0x20
+	IFT_FRELAYDCE                     = 0x2c
+	IFT_FRF16MFRBUNDLE                = 0xa3
+	IFT_FRFORWARD                     = 0x9e
+	IFT_G703AT2MB                     = 0x43
+	IFT_G703AT64K                     = 0x42
+	IFT_GIF                           = 0xf0
+	IFT_GIGABITETHERNET               = 0x75
+	IFT_GR303IDT                      = 0xb2
+	IFT_GR303RDT                      = 0xb1
+	IFT_H323GATEKEEPER                = 0xa4
+	IFT_H323PROXY                     = 0xa5
+	IFT_HDH1822                       = 0x3
+	IFT_HDLC                          = 0x76
+	IFT_HDSL2                         = 0xa8
+	IFT_HIPERLAN2                     = 0xb7
+	IFT_HIPPI                         = 0x2f
+	IFT_HIPPIINTERFACE                = 0x39
+	IFT_HOSTPAD                       = 0x5a
+	IFT_HSSI                          = 0x2e
+	IFT_HY                            = 0xe
+	IFT_IBM370PARCHAN                 = 0x48
+	IFT_IDSL                          = 0x9a
+	IFT_IEEE1394                      = 0x90
+	IFT_IEEE80211                     = 0x47
+	IFT_IEEE80212                     = 0x37
+	IFT_IEEE8023ADLAG                 = 0xa1
+	IFT_IFGSN                         = 0x91
+	IFT_IMT                           = 0xbe
+	IFT_INFINIBAND                    = 0xc7
+	IFT_INTERLEAVE                    = 0x7c
+	IFT_IP                            = 0x7e
+	IFT_IPFORWARD                     = 0x8e
+	IFT_IPOVERATM                     = 0x72
+	IFT_IPOVERCDLC                    = 0x6d
+	IFT_IPOVERCLAW                    = 0x6e
+	IFT_IPSWITCH                      = 0x4e
+	IFT_ISDN                          = 0x3f
+	IFT_ISDNBASIC                     = 0x14
+	IFT_ISDNPRIMARY                   = 0x15
+	IFT_ISDNS                         = 0x4b
+	IFT_ISDNU                         = 0x4c
+	IFT_ISO88022LLC                   = 0x29
+	IFT_ISO88023                      = 0x7
+	IFT_ISO88024                      = 0x8
+	IFT_ISO88025                      = 0x9
+	IFT_ISO88025CRFPINT               = 0x62
+	IFT_ISO88025DTR                   = 0x56
+	IFT_ISO88025FIBER                 = 0x73
+	IFT_ISO88026                      = 0xa
+	IFT_ISUP                          = 0xb3
+	IFT_L2VLAN                        = 0x87
+	IFT_L3IPVLAN                      = 0x88
+	IFT_L3IPXVLAN                     = 0x89
+	IFT_LAPB                          = 0x10
+	IFT_LAPD                          = 0x4d
+	IFT_LAPF                          = 0x77
+	IFT_LINEGROUP                     = 0xd2
+	IFT_LOCALTALK                     = 0x2a
+	IFT_LOOP                          = 0x18
+	IFT_MBIM                          = 0xfa
+	IFT_MEDIAMAILOVERIP               = 0x8b
+	IFT_MFSIGLINK                     = 0xa7
+	IFT_MIOX25                        = 0x26
+	IFT_MODEM                         = 0x30
+	IFT_MPC                           = 0x71
+	IFT_MPLS                          = 0xa6
+	IFT_MPLSTUNNEL                    = 0x96
+	IFT_MSDSL                         = 0x8f
+	IFT_MVL                           = 0xbf
+	IFT_MYRINET                       = 0x63
+	IFT_NFAS                          = 0xaf
+	IFT_NSIP                          = 0x1b
+	IFT_OPTICALCHANNEL                = 0xc3
+	IFT_OPTICALTRANSPORT              = 0xc4
+	IFT_OTHER                         = 0x1
+	IFT_P10                           = 0xc
+	IFT_P80                           = 0xd
+	IFT_PARA                          = 0x22
+	IFT_PFLOG                         = 0xf5
+	IFT_PFLOW                         = 0xf9
+	IFT_PFSYNC                        = 0xf6
+	IFT_PLC                           = 0xae
+	IFT_PON155                        = 0xcf
+	IFT_PON622                        = 0xd0
+	IFT_POS                           = 0xab
+	IFT_PPP                           = 0x17
+	IFT_PPPMULTILINKBUNDLE            = 0x6c
+	IFT_PROPATM                       = 0xc5
+	IFT_PROPBWAP2MP                   = 0xb8
+	IFT_PROPCNLS                      = 0x59
+	IFT_PROPDOCSWIRELESSDOWNSTREAM    = 0xb5
+	IFT_PROPDOCSWIRELESSMACLAYER      = 0xb4
+	IFT_PROPDOCSWIRELESSUPSTREAM      = 0xb6
+	IFT_PROPMUX                       = 0x36
+	IFT_PROPVIRTUAL                   = 0x35
+	IFT_PROPWIRELESSP2P               = 0x9d
+	IFT_PTPSERIAL                     = 0x16
+	IFT_PVC                           = 0xf2
+	IFT_Q2931                         = 0xc9
+	IFT_QLLC                          = 0x44
+	IFT_RADIOMAC                      = 0xbc
+	IFT_RADSL                         = 0x5f
+	IFT_REACHDSL                      = 0xc0
+	IFT_RFC1483                       = 0x9f
+	IFT_RS232                         = 0x21
+	IFT_RSRB                          = 0x4f
+	IFT_SDLC                          = 0x11
+	IFT_SDSL                          = 0x60
+	IFT_SHDSL                         = 0xa9
+	IFT_SIP                           = 0x1f
+	IFT_SIPSIG                        = 0xcc
+	IFT_SIPTG                         = 0xcb
+	IFT_SLIP                          = 0x1c
+	IFT_SMDSDXI                       = 0x2b
+	IFT_SMDSICIP                      = 0x34
+	IFT_SONET                         = 0x27
+	IFT_SONETOVERHEADCHANNEL          = 0xb9
+	IFT_SONETPATH                     = 0x32
+	IFT_SONETVT                       = 0x33
+	IFT_SRP                           = 0x97
+	IFT_SS7SIGLINK                    = 0x9c
+	IFT_STACKTOSTACK                  = 0x6f
+	IFT_STARLAN                       = 0xb
+	IFT_T1                            = 0x12
+	IFT_TDLC                          = 0x74
+	IFT_TELINK                        = 0xc8
+	IFT_TERMPAD                       = 0x5b
+	IFT_TR008                         = 0xb0
+	IFT_TRANSPHDLC                    = 0x7b
+	IFT_TUNNEL                        = 0x83
+	IFT_ULTRA                         = 0x1d
+	IFT_USB                           = 0xa0
+	IFT_V11                           = 0x40
+	IFT_V35                           = 0x2d
+	IFT_V36                           = 0x41
+	IFT_V37                           = 0x78
+	IFT_VDSL                          = 0x61
+	IFT_VIRTUALIPADDRESS              = 0x70
+	IFT_VIRTUALTG                     = 0xca
+	IFT_VOICEDID                      = 0xd5
+	IFT_VOICEEM                       = 0x64
+	IFT_VOICEEMFGD                    = 0xd3
+	IFT_VOICEENCAP                    = 0x67
+	IFT_VOICEFGDEANA                  = 0xd4
+	IFT_VOICEFXO                      = 0x65
+	IFT_VOICEFXS                      = 0x66
+	IFT_VOICEOVERATM                  = 0x98
+	IFT_VOICEOVERCABLE                = 0xc6
+	IFT_VOICEOVERFRAMERELAY           = 0x99
+	IFT_VOICEOVERIP                   = 0x68
+	IFT_WIREGUARD                     = 0xfb
+	IFT_X213                          = 0x5d
+	IFT_X25                           = 0x5
+	IFT_X25DDN                        = 0x4
+	IFT_X25HUNTGROUP                  = 0x7a
+	IFT_X25MLP                        = 0x79
+	IFT_X25PLE                        = 0x28
+	IFT_XETHER                        = 0x1a
+	IGNBRK                            = 0x1
+	IGNCR                             = 0x80
+	IGNPAR                            = 0x4
+	IMAXBEL                           = 0x2000
+	INLCR                             = 0x40
+	INPCK                             = 0x10
+	IN_CLASSA_HOST                    = 0xffffff
+	IN_CLASSA_MAX                     = 0x80
+	IN_CLASSA_NET                     = 0xff000000
+	IN_CLASSA_NSHIFT                  = 0x18
+	IN_CLASSB_HOST                    = 0xffff
+	IN_CLASSB_MAX                     = 0x10000
+	IN_CLASSB_NET                     = 0xffff0000
+	IN_CLASSB_NSHIFT                  = 0x10
+	IN_CLASSC_HOST                    = 0xff
+	IN_CLASSC_NET                     = 0xffffff00
+	IN_CLASSC_NSHIFT                  = 0x8
+	IN_CLASSD_HOST                    = 0xfffffff
+	IN_CLASSD_NET                     = 0xf0000000
+	IN_CLASSD_NSHIFT                  = 0x1c
+	IN_LOOPBACKNET                    = 0x7f
+	IN_RFC3021_HOST                   = 0x1
+	IN_RFC3021_NET                    = 0xfffffffe
+	IN_RFC3021_NSHIFT                 = 0x1f
+	IPPROTO_AH                        = 0x33
+	IPPROTO_CARP                      = 0x70
+	IPPROTO_DIVERT                    = 0x102
+	IPPROTO_DONE                      = 0x101
+	IPPROTO_DSTOPTS                   = 0x3c
+	IPPROTO_EGP                       = 0x8
+	IPPROTO_ENCAP                     = 0x62
+	IPPROTO_EON                       = 0x50
+	IPPROTO_ESP                       = 0x32
+	IPPROTO_ETHERIP                   = 0x61
+	IPPROTO_FRAGMENT                  = 0x2c
+	IPPROTO_GGP                       = 0x3
+	IPPROTO_GRE                       = 0x2f
+	IPPROTO_HOPOPTS                   = 0x0
+	IPPROTO_ICMP                      = 0x1
+	IPPROTO_ICMPV6                    = 0x3a
+	IPPROTO_IDP                       = 0x16
+	IPPROTO_IGMP                      = 0x2
+	IPPROTO_IP                        = 0x0
+	IPPROTO_IPCOMP                    = 0x6c
+	IPPROTO_IPIP                      = 0x4
+	IPPROTO_IPV4                      = 0x4
+	IPPROTO_IPV6                      = 0x29
+	IPPROTO_MAX                       = 0x100
+	IPPROTO_MAXID                     = 0x103
+	IPPROTO_MOBILE                    = 0x37
+	IPPROTO_MPLS                      = 0x89
+	IPPROTO_NONE                      = 0x3b
+	IPPROTO_PFSYNC                    = 0xf0
+	IPPROTO_PIM                       = 0x67
+	IPPROTO_PUP                       = 0xc
+	IPPROTO_RAW                       = 0xff
+	IPPROTO_ROUTING                   = 0x2b
+	IPPROTO_RSVP                      = 0x2e
+	IPPROTO_SCTP                      = 0x84
+	IPPROTO_TCP                       = 0x6
+	IPPROTO_TP                        = 0x1d
+	IPPROTO_UDP                       = 0x11
+	IPPROTO_UDPLITE                   = 0x88
+	IPV6_AUTH_LEVEL                   = 0x35
+	IPV6_AUTOFLOWLABEL                = 0x3b
+	IPV6_CHECKSUM                     = 0x1a
+	IPV6_DEFAULT_MULTICAST_HOPS       = 0x1
+	IPV6_DEFAULT_MULTICAST_LOOP       = 0x1
+	IPV6_DEFHLIM                      = 0x40
+	IPV6_DONTFRAG                     = 0x3e
+	IPV6_DSTOPTS                      = 0x32
+	IPV6_ESP_NETWORK_LEVEL            = 0x37
+	IPV6_ESP_TRANS_LEVEL              = 0x36
+	IPV6_FAITH                        = 0x1d
+	IPV6_FLOWINFO_MASK                = 0xffffff0f
+	IPV6_FLOWLABEL_MASK               = 0xffff0f00
+	IPV6_FRAGTTL                      = 0x78
+	IPV6_HLIMDEC                      = 0x1
+	IPV6_HOPLIMIT                     = 0x2f
+	IPV6_HOPOPTS                      = 0x31
+	IPV6_IPCOMP_LEVEL                 = 0x3c
+	IPV6_JOIN_GROUP                   = 0xc
+	IPV6_LEAVE_GROUP                  = 0xd
+	IPV6_MAXHLIM                      = 0xff
+	IPV6_MAXPACKET                    = 0xffff
+	IPV6_MINHOPCOUNT                  = 0x41
+	IPV6_MMTU                         = 0x500
+	IPV6_MULTICAST_HOPS               = 0xa
+	IPV6_MULTICAST_IF                 = 0x9
+	IPV6_MULTICAST_LOOP               = 0xb
+	IPV6_NEXTHOP                      = 0x30
+	IPV6_OPTIONS                      = 0x1
+	IPV6_PATHMTU                      = 0x2c
+	IPV6_PIPEX                        = 0x3f
+	IPV6_PKTINFO                      = 0x2e
+	IPV6_PORTRANGE                    = 0xe
+	IPV6_PORTRANGE_DEFAULT            = 0x0
+	IPV6_PORTRANGE_HIGH               = 0x1
+	IPV6_PORTRANGE_LOW                = 0x2
+	IPV6_RECVDSTOPTS                  = 0x28
+	IPV6_RECVDSTPORT                  = 0x40
+	IPV6_RECVHOPLIMIT                 = 0x25
+	IPV6_RECVHOPOPTS                  = 0x27
+	IPV6_RECVPATHMTU                  = 0x2b
+	IPV6_RECVPKTINFO                  = 0x24
+	IPV6_RECVRTHDR                    = 0x26
+	IPV6_RECVTCLASS                   = 0x39
+	IPV6_RTABLE                       = 0x1021
+	IPV6_RTHDR                        = 0x33
+	IPV6_RTHDRDSTOPTS                 = 0x23
+	IPV6_RTHDR_LOOSE                  = 0x0
+	IPV6_RTHDR_STRICT                 = 0x1
+	IPV6_RTHDR_TYPE_0                 = 0x0
+	IPV6_SOCKOPT_RESERVED1            = 0x3
+	IPV6_TCLASS                       = 0x3d
+	IPV6_UNICAST_HOPS                 = 0x4
+	IPV6_USE_MIN_MTU                  = 0x2a
+	IPV6_V6ONLY                       = 0x1b
+	IPV6_VERSION                      = 0x60
+	IPV6_VERSION_MASK                 = 0xf0
+	IP_ADD_MEMBERSHIP                 = 0xc
+	IP_AUTH_LEVEL                     = 0x14
+	IP_DEFAULT_MULTICAST_LOOP         = 0x1
+	IP_DEFAULT_MULTICAST_TTL          = 0x1
+	IP_DF                             = 0x4000
+	IP_DROP_MEMBERSHIP                = 0xd
+	IP_ESP_NETWORK_LEVEL              = 0x16
+	IP_ESP_TRANS_LEVEL                = 0x15
+	IP_HDRINCL                        = 0x2
+	IP_IPCOMP_LEVEL                   = 0x1d
+	IP_IPDEFTTL                       = 0x25
+	IP_IPSECFLOWINFO                  = 0x24
+	IP_IPSEC_LOCAL_AUTH               = 0x1b
+	IP_IPSEC_LOCAL_CRED               = 0x19
+	IP_IPSEC_LOCAL_ID                 = 0x17
+	IP_IPSEC_REMOTE_AUTH              = 0x1c
+	IP_IPSEC_REMOTE_CRED              = 0x1a
+	IP_IPSEC_REMOTE_ID                = 0x18
+	IP_MAXPACKET                      = 0xffff
+	IP_MAX_MEMBERSHIPS                = 0xfff
+	IP_MF                             = 0x2000
+	IP_MINTTL                         = 0x20
+	IP_MIN_MEMBERSHIPS                = 0xf
+	IP_MSS                            = 0x240
+	IP_MULTICAST_IF                   = 0x9
+	IP_MULTICAST_LOOP                 = 0xb
+	IP_MULTICAST_TTL                  = 0xa
+	IP_OFFMASK                        = 0x1fff
+	IP_OPTIONS                        = 0x1
+	IP_PIPEX                          = 0x22
+	IP_PORTRANGE                      = 0x13
+	IP_PORTRANGE_DEFAULT              = 0x0
+	IP_PORTRANGE_HIGH                 = 0x1
+	IP_PORTRANGE_LOW                  = 0x2
+	IP_RECVDSTADDR                    = 0x7
+	IP_RECVDSTPORT                    = 0x21
+	IP_RECVIF                         = 0x1e
+	IP_RECVOPTS                       = 0x5
+	IP_RECVRETOPTS                    = 0x6
+	IP_RECVRTABLE                     = 0x23
+	IP_RECVTTL                        = 0x1f
+	IP_RETOPTS                        = 0x8
+	IP_RF                             = 0x8000
+	IP_RTABLE                         = 0x1021
+	IP_SENDSRCADDR                    = 0x7
+	IP_TOS                            = 0x3
+	IP_TTL                            = 0x4
+	ISIG                              = 0x80
+	ISTRIP                            = 0x20
+	ITIMER_PROF                       = 0x2
+	ITIMER_REAL                       = 0x0
+	ITIMER_VIRTUAL                    = 0x1
+	IUCLC                             = 0x1000
+	IXANY                             = 0x800
+	IXOFF                             = 0x400
+	IXON                              = 0x200
+	KERN_HOSTNAME                     = 0xa
+	KERN_OSRELEASE                    = 0x2
+	KERN_OSTYPE                       = 0x1
+	KERN_VERSION                      = 0x4
+	LCNT_OVERLOAD_FLUSH               = 0x6
+	LOCK_EX                           = 0x2
+	LOCK_NB                           = 0x4
+	LOCK_SH                           = 0x1
+	LOCK_UN                           = 0x8
+	MADV_DONTNEED                     = 0x4
+	MADV_FREE                         = 0x6
+	MADV_NORMAL                       = 0x0
+	MADV_RANDOM                       = 0x1
+	MADV_SEQUENTIAL                   = 0x2
+	MADV_SPACEAVAIL                   = 0x5
+	MADV_WILLNEED                     = 0x3
+	MAP_ANON                          = 0x1000
+	MAP_ANONYMOUS                     = 0x1000
+	MAP_CONCEAL                       = 0x8000
+	MAP_COPY                          = 0x2
+	MAP_FILE                          = 0x0
+	MAP_FIXED                         = 0x10
+	MAP_FLAGMASK                      = 0xfff7
+	MAP_HASSEMAPHORE                  = 0x0
+	MAP_INHERIT                       = 0x0
+	MAP_INHERIT_COPY                  = 0x1
+	MAP_INHERIT_NONE                  = 0x2
+	MAP_INHERIT_SHARE                 = 0x0
+	MAP_INHERIT_ZERO                  = 0x3
+	MAP_NOEXTEND                      = 0x0
+	MAP_NORESERVE                     = 0x0
+	MAP_PRIVATE                       = 0x2
+	MAP_RENAME                        = 0x0
+	MAP_SHARED                        = 0x1
+	MAP_STACK                         = 0x4000
+	MAP_TRYFIXED                      = 0x0
+	MCL_CURRENT                       = 0x1
+	MCL_FUTURE                        = 0x2
+	MNT_ASYNC                         = 0x40
+	MNT_DEFEXPORTED                   = 0x200
+	MNT_DELEXPORT                     = 0x20000
+	MNT_DOOMED                        = 0x8000000
+	MNT_EXPORTANON                    = 0x400
+	MNT_EXPORTED                      = 0x100
+	MNT_EXRDONLY                      = 0x80
+	MNT_FORCE                         = 0x80000
+	MNT_LAZY                          = 0x3
+	MNT_LOCAL                         = 0x1000
+	MNT_NOATIME                       = 0x8000
+	MNT_NODEV                         = 0x10
+	MNT_NOEXEC                        = 0x4
+	MNT_NOPERM                        = 0x20
+	MNT_NOSUID                        = 0x8
+	MNT_NOWAIT                        = 0x2
+	MNT_QUOTA                         = 0x2000
+	MNT_RDONLY                        = 0x1
+	MNT_RELOAD                        = 0x40000
+	MNT_ROOTFS                        = 0x4000
+	MNT_SOFTDEP                       = 0x4000000
+	MNT_STALLED                       = 0x100000
+	MNT_SWAPPABLE                     = 0x200000
+	MNT_SYNCHRONOUS                   = 0x2
+	MNT_UPDATE                        = 0x10000
+	MNT_VISFLAGMASK                   = 0x400ffff
+	MNT_WAIT                          = 0x1
+	MNT_WANTRDWR                      = 0x2000000
+	MNT_WXALLOWED                     = 0x800
+	MOUNT_AFS                         = "afs"
+	MOUNT_CD9660                      = "cd9660"
+	MOUNT_EXT2FS                      = "ext2fs"
+	MOUNT_FFS                         = "ffs"
+	MOUNT_FUSEFS                      = "fuse"
+	MOUNT_MFS                         = "mfs"
+	MOUNT_MSDOS                       = "msdos"
+	MOUNT_NCPFS                       = "ncpfs"
+	MOUNT_NFS                         = "nfs"
+	MOUNT_NTFS                        = "ntfs"
+	MOUNT_TMPFS                       = "tmpfs"
+	MOUNT_UDF                         = "udf"
+	MOUNT_UFS                         = "ffs"
+	MSG_BCAST                         = 0x100
+	MSG_CMSG_CLOEXEC                  = 0x800
+	MSG_CTRUNC                        = 0x20
+	MSG_DONTROUTE                     = 0x4
+	MSG_DONTWAIT                      = 0x80
+	MSG_EOR                           = 0x8
+	MSG_MCAST                         = 0x200
+	MSG_NOSIGNAL                      = 0x400
+	MSG_OOB                           = 0x1
+	MSG_PEEK                          = 0x2
+	MSG_TRUNC                         = 0x10
+	MSG_WAITALL                       = 0x40
+	MS_ASYNC                          = 0x1
+	MS_INVALIDATE                     = 0x4
+	MS_SYNC                           = 0x2
+	NAME_MAX                          = 0xff
+	NET_RT_DUMP                       = 0x1
+	NET_RT_FLAGS                      = 0x2
+	NET_RT_IFLIST                     = 0x3
+	NET_RT_IFNAMES                    = 0x6
+	NET_RT_MAXID                      = 0x8
+	NET_RT_SOURCE                     = 0x7
+	NET_RT_STATS                      = 0x4
+	NET_RT_TABLE                      = 0x5
+	NFDBITS                           = 0x20
+	NOFLSH                            = 0x80000000
+	NOKERNINFO                        = 0x2000000
+	NOTE_ATTRIB                       = 0x8
+	NOTE_CHANGE                       = 0x1
+	NOTE_CHILD                        = 0x4
+	NOTE_DELETE                       = 0x1
+	NOTE_EOF                          = 0x2
+	NOTE_EXEC                         = 0x20000000
+	NOTE_EXIT                         = 0x80000000
+	NOTE_EXTEND                       = 0x4
+	NOTE_FORK                         = 0x40000000
+	NOTE_LINK                         = 0x10
+	NOTE_LOWAT                        = 0x1
+	NOTE_OOB                          = 0x4
+	NOTE_PCTRLMASK                    = 0xf0000000
+	NOTE_PDATAMASK                    = 0xfffff
+	NOTE_RENAME                       = 0x20
+	NOTE_REVOKE                       = 0x40
+	NOTE_TRACK                        = 0x1
+	NOTE_TRACKERR                     = 0x2
+	NOTE_TRUNCATE                     = 0x80
+	NOTE_WRITE                        = 0x2
+	OCRNL                             = 0x10
+	OLCUC                             = 0x20
+	ONLCR                             = 0x2
+	ONLRET                            = 0x80
+	ONOCR                             = 0x40
+	ONOEOT                            = 0x8
+	OPOST                             = 0x1
+	OXTABS                            = 0x4
+	O_ACCMODE                         = 0x3
+	O_APPEND                          = 0x8
+	O_ASYNC                           = 0x40
+	O_CLOEXEC                         = 0x10000
+	O_CREAT                           = 0x200
+	O_DIRECTORY                       = 0x20000
+	O_DSYNC                           = 0x80
+	O_EXCL                            = 0x800
+	O_EXLOCK                          = 0x20
+	O_FSYNC                           = 0x80
+	O_NDELAY                          = 0x4
+	O_NOCTTY                          = 0x8000
+	O_NOFOLLOW                        = 0x100
+	O_NONBLOCK                        = 0x4
+	O_RDONLY                          = 0x0
+	O_RDWR                            = 0x2
+	O_RSYNC                           = 0x80
+	O_SHLOCK                          = 0x10
+	O_SYNC                            = 0x80
+	O_TRUNC                           = 0x400
+	O_WRONLY                          = 0x1
+	PARENB                            = 0x1000
+	PARMRK                            = 0x8
+	PARODD                            = 0x2000
+	PENDIN                            = 0x20000000
+	PF_FLUSH                          = 0x1
+	PRIO_PGRP                         = 0x1
+	PRIO_PROCESS                      = 0x0
+	PRIO_USER                         = 0x2
+	PROT_EXEC                         = 0x4
+	PROT_NONE                         = 0x0
+	PROT_READ                         = 0x1
+	PROT_WRITE                        = 0x2
+	RLIMIT_CORE                       = 0x4
+	RLIMIT_CPU                        = 0x0
+	RLIMIT_DATA                       = 0x2
+	RLIMIT_FSIZE                      = 0x1
+	RLIMIT_MEMLOCK                    = 0x6
+	RLIMIT_NOFILE                     = 0x8
+	RLIMIT_NPROC                      = 0x7
+	RLIMIT_RSS                        = 0x5
+	RLIMIT_STACK                      = 0x3
+	RLIM_INFINITY                     = 0x7fffffffffffffff
+	RTAX_AUTHOR                       = 0x6
+	RTAX_BFD                          = 0xb
+	RTAX_BRD                          = 0x7
+	RTAX_DNS                          = 0xc
+	RTAX_DST                          = 0x0
+	RTAX_GATEWAY                      = 0x1
+	RTAX_GENMASK                      = 0x3
+	RTAX_IFA                          = 0x5
+	RTAX_IFP                          = 0x4
+	RTAX_LABEL                        = 0xa
+	RTAX_MAX                          = 0xf
+	RTAX_NETMASK                      = 0x2
+	RTAX_SEARCH                       = 0xe
+	RTAX_SRC                          = 0x8
+	RTAX_SRCMASK                      = 0x9
+	RTAX_STATIC                       = 0xd
+	RTA_AUTHOR                        = 0x40
+	RTA_BFD                           = 0x800
+	RTA_BRD                           = 0x80
+	RTA_DNS                           = 0x1000
+	RTA_DST                           = 0x1
+	RTA_GATEWAY                       = 0x2
+	RTA_GENMASK                       = 0x8
+	RTA_IFA                           = 0x20
+	RTA_IFP                           = 0x10
+	RTA_LABEL                         = 0x400
+	RTA_NETMASK                       = 0x4
+	RTA_SEARCH                        = 0x4000
+	RTA_SRC                           = 0x100
+	RTA_SRCMASK                       = 0x200
+	RTA_STATIC                        = 0x2000
+	RTF_ANNOUNCE                      = 0x4000
+	RTF_BFD                           = 0x1000000
+	RTF_BLACKHOLE                     = 0x1000
+	RTF_BROADCAST                     = 0x400000
+	RTF_CACHED                        = 0x20000
+	RTF_CLONED                        = 0x10000
+	RTF_CLONING                       = 0x100
+	RTF_CONNECTED                     = 0x800000
+	RTF_DONE                          = 0x40
+	RTF_DYNAMIC                       = 0x10
+	RTF_FMASK                         = 0x110fc08
+	RTF_GATEWAY                       = 0x2
+	RTF_HOST                          = 0x4
+	RTF_LLINFO                        = 0x400
+	RTF_LOCAL                         = 0x200000
+	RTF_MODIFIED                      = 0x20
+	RTF_MPATH                         = 0x40000
+	RTF_MPLS                          = 0x100000
+	RTF_MULTICAST                     = 0x200
+	RTF_PERMANENT_ARP                 = 0x2000
+	RTF_PROTO1                        = 0x8000
+	RTF_PROTO2                        = 0x4000
+	RTF_PROTO3                        = 0x2000
+	RTF_REJECT                        = 0x8
+	RTF_STATIC                        = 0x800
+	RTF_UP                            = 0x1
+	RTF_USETRAILERS                   = 0x8000
+	RTM_80211INFO                     = 0x15
+	RTM_ADD                           = 0x1
+	RTM_BFD                           = 0x12
+	RTM_CHANGE                        = 0x3
+	RTM_CHGADDRATTR                   = 0x14
+	RTM_DELADDR                       = 0xd
+	RTM_DELETE                        = 0x2
+	RTM_DESYNC                        = 0x10
+	RTM_GET                           = 0x4
+	RTM_IFANNOUNCE                    = 0xf
+	RTM_IFINFO                        = 0xe
+	RTM_INVALIDATE                    = 0x11
+	RTM_LOSING                        = 0x5
+	RTM_MAXSIZE                       = 0x800
+	RTM_MISS                          = 0x7
+	RTM_NEWADDR                       = 0xc
+	RTM_PROPOSAL                      = 0x13
+	RTM_REDIRECT                      = 0x6
+	RTM_RESOLVE                       = 0xb
+	RTM_SOURCE                        = 0x16
+	RTM_VERSION                       = 0x5
+	RTV_EXPIRE                        = 0x4
+	RTV_HOPCOUNT                      = 0x2
+	RTV_MTU                           = 0x1
+	RTV_RPIPE                         = 0x8
+	RTV_RTT                           = 0x40
+	RTV_RTTVAR                        = 0x80
+	RTV_SPIPE                         = 0x10
+	RTV_SSTHRESH                      = 0x20
+	RT_TABLEID_BITS                   = 0x8
+	RT_TABLEID_MASK                   = 0xff
+	RT_TABLEID_MAX                    = 0xff
+	RUSAGE_CHILDREN                   = -0x1
+	RUSAGE_SELF                       = 0x0
+	RUSAGE_THREAD                     = 0x1
+	SCM_RIGHTS                        = 0x1
+	SCM_TIMESTAMP                     = 0x4
+	SEEK_CUR                          = 0x1
+	SEEK_END                          = 0x2
+	SEEK_SET                          = 0x0
+	SHUT_RD                           = 0x0
+	SHUT_RDWR                         = 0x2
+	SHUT_WR                           = 0x1
+	SIOCADDMULTI                      = 0x80206931
+	SIOCAIFADDR                       = 0x8040691a
+	SIOCAIFGROUP                      = 0x80286987
+	SIOCATMARK                        = 0x40047307
+	SIOCBRDGADD                       = 0x8060693c
+	SIOCBRDGADDL                      = 0x80606949
+	SIOCBRDGADDS                      = 0x80606941
+	SIOCBRDGARL                       = 0x808c694d
+	SIOCBRDGDADDR                     = 0x81286947
+	SIOCBRDGDEL                       = 0x8060693d
+	SIOCBRDGDELS                      = 0x80606942
+	SIOCBRDGFLUSH                     = 0x80606948
+	SIOCBRDGFRL                       = 0x808c694e
+	SIOCBRDGGCACHE                    = 0xc0146941
+	SIOCBRDGGFD                       = 0xc0146952
+	SIOCBRDGGHT                       = 0xc0146951
+	SIOCBRDGGIFFLGS                   = 0xc060693e
+	SIOCBRDGGMA                       = 0xc0146953
+	SIOCBRDGGPARAM                    = 0xc0406958
+	SIOCBRDGGPRI                      = 0xc0146950
+	SIOCBRDGGRL                       = 0xc030694f
+	SIOCBRDGGTO                       = 0xc0146946
+	SIOCBRDGIFS                       = 0xc0606942
+	SIOCBRDGRTS                       = 0xc0206943
+	SIOCBRDGSADDR                     = 0xc1286944
+	SIOCBRDGSCACHE                    = 0x80146940
+	SIOCBRDGSFD                       = 0x80146952
+	SIOCBRDGSHT                       = 0x80146951
+	SIOCBRDGSIFCOST                   = 0x80606955
+	SIOCBRDGSIFFLGS                   = 0x8060693f
+	SIOCBRDGSIFPRIO                   = 0x80606954
+	SIOCBRDGSIFPROT                   = 0x8060694a
+	SIOCBRDGSMA                       = 0x80146953
+	SIOCBRDGSPRI                      = 0x80146950
+	SIOCBRDGSPROTO                    = 0x8014695a
+	SIOCBRDGSTO                       = 0x80146945
+	SIOCBRDGSTXHC                     = 0x80146959
+	SIOCDELLABEL                      = 0x80206997
+	SIOCDELMULTI                      = 0x80206932
+	SIOCDIFADDR                       = 0x80206919
+	SIOCDIFGROUP                      = 0x80286989
+	SIOCDIFPARENT                     = 0x802069b4
+	SIOCDIFPHYADDR                    = 0x80206949
+	SIOCDPWE3NEIGHBOR                 = 0x802069de
+	SIOCDVNETID                       = 0x802069af
+	SIOCGETKALIVE                     = 0xc01869a4
+	SIOCGETLABEL                      = 0x8020699a
+	SIOCGETMPWCFG                     = 0xc02069ae
+	SIOCGETPFLOW                      = 0xc02069fe
+	SIOCGETPFSYNC                     = 0xc02069f8
+	SIOCGETSGCNT                      = 0xc0207534
+	SIOCGETVIFCNT                     = 0xc0287533
+	SIOCGETVLAN                       = 0xc0206990
+	SIOCGIFADDR                       = 0xc0206921
+	SIOCGIFBRDADDR                    = 0xc0206923
+	SIOCGIFCONF                       = 0xc0106924
+	SIOCGIFDATA                       = 0xc020691b
+	SIOCGIFDESCR                      = 0xc0206981
+	SIOCGIFDSTADDR                    = 0xc0206922
+	SIOCGIFFLAGS                      = 0xc0206911
+	SIOCGIFGATTR                      = 0xc028698b
+	SIOCGIFGENERIC                    = 0xc020693a
+	SIOCGIFGLIST                      = 0xc028698d
+	SIOCGIFGMEMB                      = 0xc028698a
+	SIOCGIFGROUP                      = 0xc0286988
+	SIOCGIFHARDMTU                    = 0xc02069a5
+	SIOCGIFLLPRIO                     = 0xc02069b6
+	SIOCGIFMEDIA                      = 0xc0406938
+	SIOCGIFMETRIC                     = 0xc0206917
+	SIOCGIFMTU                        = 0xc020697e
+	SIOCGIFNETMASK                    = 0xc0206925
+	SIOCGIFPAIR                       = 0xc02069b1
+	SIOCGIFPARENT                     = 0xc02069b3
+	SIOCGIFPRIORITY                   = 0xc020699c
+	SIOCGIFRDOMAIN                    = 0xc02069a0
+	SIOCGIFRTLABEL                    = 0xc0206983
+	SIOCGIFRXR                        = 0x802069aa
+	SIOCGIFSFFPAGE                    = 0xc1126939
+	SIOCGIFXFLAGS                     = 0xc020699e
+	SIOCGLIFPHYADDR                   = 0xc218694b
+	SIOCGLIFPHYDF                     = 0xc02069c2
+	SIOCGLIFPHYECN                    = 0xc02069c8
+	SIOCGLIFPHYRTABLE                 = 0xc02069a2
+	SIOCGLIFPHYTTL                    = 0xc02069a9
+	SIOCGPGRP                         = 0x40047309
+	SIOCGPWE3                         = 0xc0206998
+	SIOCGPWE3CTRLWORD                 = 0xc02069dc
+	SIOCGPWE3FAT                      = 0xc02069dd
+	SIOCGPWE3NEIGHBOR                 = 0xc21869de
+	SIOCGRXHPRIO                      = 0xc02069db
+	SIOCGSPPPPARAMS                   = 0xc0206994
+	SIOCGTXHPRIO                      = 0xc02069c6
+	SIOCGUMBINFO                      = 0xc02069be
+	SIOCGUMBPARAM                     = 0xc02069c0
+	SIOCGVH                           = 0xc02069f6
+	SIOCGVNETFLOWID                   = 0xc02069c4
+	SIOCGVNETID                       = 0xc02069a7
+	SIOCIFAFATTACH                    = 0x801169ab
+	SIOCIFAFDETACH                    = 0x801169ac
+	SIOCIFCREATE                      = 0x8020697a
+	SIOCIFDESTROY                     = 0x80206979
+	SIOCIFGCLONERS                    = 0xc0106978
+	SIOCSETKALIVE                     = 0x801869a3
+	SIOCSETLABEL                      = 0x80206999
+	SIOCSETMPWCFG                     = 0x802069ad
+	SIOCSETPFLOW                      = 0x802069fd
+	SIOCSETPFSYNC                     = 0x802069f7
+	SIOCSETVLAN                       = 0x8020698f
+	SIOCSIFADDR                       = 0x8020690c
+	SIOCSIFBRDADDR                    = 0x80206913
+	SIOCSIFDESCR                      = 0x80206980
+	SIOCSIFDSTADDR                    = 0x8020690e
+	SIOCSIFFLAGS                      = 0x80206910
+	SIOCSIFGATTR                      = 0x8028698c
+	SIOCSIFGENERIC                    = 0x80206939
+	SIOCSIFLLADDR                     = 0x8020691f
+	SIOCSIFLLPRIO                     = 0x802069b5
+	SIOCSIFMEDIA                      = 0xc0206937
+	SIOCSIFMETRIC                     = 0x80206918
+	SIOCSIFMTU                        = 0x8020697f
+	SIOCSIFNETMASK                    = 0x80206916
+	SIOCSIFPAIR                       = 0x802069b0
+	SIOCSIFPARENT                     = 0x802069b2
+	SIOCSIFPRIORITY                   = 0x8020699b
+	SIOCSIFRDOMAIN                    = 0x8020699f
+	SIOCSIFRTLABEL                    = 0x80206982
+	SIOCSIFXFLAGS                     = 0x8020699d
+	SIOCSLIFPHYADDR                   = 0x8218694a
+	SIOCSLIFPHYDF                     = 0x802069c1
+	SIOCSLIFPHYECN                    = 0x802069c7
+	SIOCSLIFPHYRTABLE                 = 0x802069a1
+	SIOCSLIFPHYTTL                    = 0x802069a8
+	SIOCSPGRP                         = 0x80047308
+	SIOCSPWE3CTRLWORD                 = 0x802069dc
+	SIOCSPWE3FAT                      = 0x802069dd
+	SIOCSPWE3NEIGHBOR                 = 0x821869de
+	SIOCSRXHPRIO                      = 0x802069db
+	SIOCSSPPPPARAMS                   = 0x80206993
+	SIOCSTXHPRIO                      = 0x802069c5
+	SIOCSUMBPARAM                     = 0x802069bf
+	SIOCSVH                           = 0xc02069f5
+	SIOCSVNETFLOWID                   = 0x802069c3
+	SIOCSVNETID                       = 0x802069a6
+	SOCK_CLOEXEC                      = 0x8000
+	SOCK_DGRAM                        = 0x2
+	SOCK_DNS                          = 0x1000
+	SOCK_NONBLOCK                     = 0x4000
+	SOCK_RAW                          = 0x3
+	SOCK_RDM                          = 0x4
+	SOCK_SEQPACKET                    = 0x5
+	SOCK_STREAM                       = 0x1
+	SOL_SOCKET                        = 0xffff
+	SOMAXCONN                         = 0x80
+	SO_ACCEPTCONN                     = 0x2
+	SO_BINDANY                        = 0x1000
+	SO_BROADCAST                      = 0x20
+	SO_DEBUG                          = 0x1
+	SO_DOMAIN                         = 0x1024
+	SO_DONTROUTE                      = 0x10
+	SO_ERROR                          = 0x1007
+	SO_KEEPALIVE                      = 0x8
+	SO_LINGER                         = 0x80
+	SO_NETPROC                        = 0x1020
+	SO_OOBINLINE                      = 0x100
+	SO_PEERCRED                       = 0x1022
+	SO_PROTOCOL                       = 0x1025
+	SO_RCVBUF                         = 0x1002
+	SO_RCVLOWAT                       = 0x1004
+	SO_RCVTIMEO                       = 0x1006
+	SO_REUSEADDR                      = 0x4
+	SO_REUSEPORT                      = 0x200
+	SO_RTABLE                         = 0x1021
+	SO_SNDBUF                         = 0x1001
+	SO_SNDLOWAT                       = 0x1003
+	SO_SNDTIMEO                       = 0x1005
+	SO_SPLICE                         = 0x1023
+	SO_TIMESTAMP                      = 0x800
+	SO_TYPE                           = 0x1008
+	SO_USELOOPBACK                    = 0x40
+	SO_ZEROIZE                        = 0x2000
+	S_BLKSIZE                         = 0x200
+	S_IEXEC                           = 0x40
+	S_IFBLK                           = 0x6000
+	S_IFCHR                           = 0x2000
+	S_IFDIR                           = 0x4000
+	S_IFIFO                           = 0x1000
+	S_IFLNK                           = 0xa000
+	S_IFMT                            = 0xf000
+	S_IFREG                           = 0x8000
+	S_IFSOCK                          = 0xc000
+	S_IREAD                           = 0x100
+	S_IRGRP                           = 0x20
+	S_IROTH                           = 0x4
+	S_IRUSR                           = 0x100
+	S_IRWXG                           = 0x38
+	S_IRWXO                           = 0x7
+	S_IRWXU                           = 0x1c0
+	S_ISGID                           = 0x400
+	S_ISTXT                           = 0x200
+	S_ISUID                           = 0x800
+	S_ISVTX                           = 0x200
+	S_IWGRP                           = 0x10
+	S_IWOTH                           = 0x2
+	S_IWRITE                          = 0x80
+	S_IWUSR                           = 0x80
+	S_IXGRP                           = 0x8
+	S_IXOTH                           = 0x1
+	S_IXUSR                           = 0x40
+	TCIFLUSH                          = 0x1
+	TCIOFF                            = 0x3
+	TCIOFLUSH                         = 0x3
+	TCION                             = 0x4
+	TCOFLUSH                          = 0x2
+	TCOOFF                            = 0x1
+	TCOON                             = 0x2
+	TCPOPT_EOL                        = 0x0
+	TCPOPT_MAXSEG                     = 0x2
+	TCPOPT_NOP                        = 0x1
+	TCPOPT_SACK                       = 0x5
+	TCPOPT_SACK_HDR                   = 0x1010500
+	TCPOPT_SACK_PERMITTED             = 0x4
+	TCPOPT_SACK_PERMIT_HDR            = 0x1010402
+	TCPOPT_SIGNATURE                  = 0x13
+	TCPOPT_TIMESTAMP                  = 0x8
+	TCPOPT_TSTAMP_HDR                 = 0x101080a
+	TCPOPT_WINDOW                     = 0x3
+	TCP_INFO                          = 0x9
+	TCP_MAXSEG                        = 0x2
+	TCP_MAXWIN                        = 0xffff
+	TCP_MAX_SACK                      = 0x3
+	TCP_MAX_WINSHIFT                  = 0xe
+	TCP_MD5SIG                        = 0x4
+	TCP_MSS                           = 0x200
+	TCP_NODELAY                       = 0x1
+	TCP_NOPUSH                        = 0x10
+	TCP_SACKHOLE_LIMIT                = 0x80
+	TCP_SACK_ENABLE                   = 0x8
+	TCSAFLUSH                         = 0x2
+	TIMER_ABSTIME                     = 0x1
+	TIMER_RELTIME                     = 0x0
+	TIOCCBRK                          = 0x2000747a
+	TIOCCDTR                          = 0x20007478
+	TIOCCHKVERAUTH                    = 0x2000741e
+	TIOCCLRVERAUTH                    = 0x2000741d
+	TIOCCONS                          = 0x80047462
+	TIOCDRAIN                         = 0x2000745e
+	TIOCEXCL                          = 0x2000740d
+	TIOCEXT                           = 0x80047460
+	TIOCFLAG_CLOCAL                   = 0x2
+	TIOCFLAG_CRTSCTS                  = 0x4
+	TIOCFLAG_MDMBUF                   = 0x8
+	TIOCFLAG_PPS                      = 0x10
+	TIOCFLAG_SOFTCAR                  = 0x1
+	TIOCFLUSH                         = 0x80047410
+	TIOCGETA                          = 0x402c7413
+	TIOCGETD                          = 0x4004741a
+	TIOCGFLAGS                        = 0x4004745d
+	TIOCGPGRP                         = 0x40047477
+	TIOCGSID                          = 0x40047463
+	TIOCGTSTAMP                       = 0x4010745b
+	TIOCGWINSZ                        = 0x40087468
+	TIOCMBIC                          = 0x8004746b
+	TIOCMBIS                          = 0x8004746c
+	TIOCMGET                          = 0x4004746a
+	TIOCMODG                          = 0x4004746a
+	TIOCMODS                          = 0x8004746d
+	TIOCMSET                          = 0x8004746d
+	TIOCM_CAR                         = 0x40
+	TIOCM_CD                          = 0x40
+	TIOCM_CTS                         = 0x20
+	TIOCM_DSR                         = 0x100
+	TIOCM_DTR                         = 0x2
+	TIOCM_LE                          = 0x1
+	TIOCM_RI                          = 0x80
+	TIOCM_RNG                         = 0x80
+	TIOCM_RTS                         = 0x4
+	TIOCM_SR                          = 0x10
+	TIOCM_ST                          = 0x8
+	TIOCNOTTY                         = 0x20007471
+	TIOCNXCL                          = 0x2000740e
+	TIOCOUTQ                          = 0x40047473
+	TIOCPKT                           = 0x80047470
+	TIOCPKT_DATA                      = 0x0
+	TIOCPKT_DOSTOP                    = 0x20
+	TIOCPKT_FLUSHREAD                 = 0x1
+	TIOCPKT_FLUSHWRITE                = 0x2
+	TIOCPKT_IOCTL                     = 0x40
+	TIOCPKT_NOSTOP                    = 0x10
+	TIOCPKT_START                     = 0x8
+	TIOCPKT_STOP                      = 0x4
+	TIOCREMOTE                        = 0x80047469
+	TIOCSBRK                          = 0x2000747b
+	TIOCSCTTY                         = 0x20007461
+	TIOCSDTR                          = 0x20007479
+	TIOCSETA                          = 0x802c7414
+	TIOCSETAF                         = 0x802c7416
+	TIOCSETAW                         = 0x802c7415
+	TIOCSETD                          = 0x8004741b
+	TIOCSETVERAUTH                    = 0x8004741c
+	TIOCSFLAGS                        = 0x8004745c
+	TIOCSIG                           = 0x8004745f
+	TIOCSPGRP                         = 0x80047476
+	TIOCSTART                         = 0x2000746e
+	TIOCSTAT                          = 0x20007465
+	TIOCSTOP                          = 0x2000746f
+	TIOCSTSTAMP                       = 0x8008745a
+	TIOCSWINSZ                        = 0x80087467
+	TIOCUCNTL                         = 0x80047466
+	TIOCUCNTL_CBRK                    = 0x7a
+	TIOCUCNTL_SBRK                    = 0x7b
+	TOSTOP                            = 0x400000
+	UTIME_NOW                         = -0x2
+	UTIME_OMIT                        = -0x1
+	VDISCARD                          = 0xf
+	VDSUSP                            = 0xb
+	VEOF                              = 0x0
+	VEOL                              = 0x1
+	VEOL2                             = 0x2
+	VERASE                            = 0x3
+	VINTR                             = 0x8
+	VKILL                             = 0x5
+	VLNEXT                            = 0xe
+	VMIN                              = 0x10
+	VM_ANONMIN                        = 0x7
+	VM_LOADAVG                        = 0x2
+	VM_MALLOC_CONF                    = 0xc
+	VM_MAXID                          = 0xd
+	VM_MAXSLP                         = 0xa
+	VM_METER                          = 0x1
+	VM_NKMEMPAGES                     = 0x6
+	VM_PSSTRINGS                      = 0x3
+	VM_SWAPENCRYPT                    = 0x5
+	VM_USPACE                         = 0xb
+	VM_UVMEXP                         = 0x4
+	VM_VNODEMIN                       = 0x9
+	VM_VTEXTMIN                       = 0x8
+	VQUIT                             = 0x9
+	VREPRINT                          = 0x6
+	VSTART                            = 0xc
+	VSTATUS                           = 0x12
+	VSTOP                             = 0xd
+	VSUSP                             = 0xa
+	VTIME                             = 0x11
+	VWERASE                           = 0x4
+	WALTSIG                           = 0x4
+	WCONTINUED                        = 0x8
+	WCOREFLAG                         = 0x80
+	WNOHANG                           = 0x1
+	WUNTRACED                         = 0x2
+	XCASE                             = 0x1000000
+)
+
+// Errors
+const (
+	E2BIG           = syscall.Errno(0x7)
+	EACCES          = syscall.Errno(0xd)
+	EADDRINUSE      = syscall.Errno(0x30)
+	EADDRNOTAVAIL   = syscall.Errno(0x31)
+	EAFNOSUPPORT    = syscall.Errno(0x2f)
+	EAGAIN          = syscall.Errno(0x23)
+	EALREADY        = syscall.Errno(0x25)
+	EAUTH           = syscall.Errno(0x50)
+	EBADF           = syscall.Errno(0x9)
+	EBADMSG         = syscall.Errno(0x5c)
+	EBADRPC         = syscall.Errno(0x48)
+	EBUSY           = syscall.Errno(0x10)
+	ECANCELED       = syscall.Errno(0x58)
+	ECHILD          = syscall.Errno(0xa)
+	ECONNABORTED    = syscall.Errno(0x35)
+	ECONNREFUSED    = syscall.Errno(0x3d)
+	ECONNRESET      = syscall.Errno(0x36)
+	EDEADLK         = syscall.Errno(0xb)
+	EDESTADDRREQ    = syscall.Errno(0x27)
+	EDOM            = syscall.Errno(0x21)
+	EDQUOT          = syscall.Errno(0x45)
+	EEXIST          = syscall.Errno(0x11)
+	EFAULT          = syscall.Errno(0xe)
+	EFBIG           = syscall.Errno(0x1b)
+	EFTYPE          = syscall.Errno(0x4f)
+	EHOSTDOWN       = syscall.Errno(0x40)
+	EHOSTUNREACH    = syscall.Errno(0x41)
+	EIDRM           = syscall.Errno(0x59)
+	EILSEQ          = syscall.Errno(0x54)
+	EINPROGRESS     = syscall.Errno(0x24)
+	EINTR           = syscall.Errno(0x4)
+	EINVAL          = syscall.Errno(0x16)
+	EIO             = syscall.Errno(0x5)
+	EIPSEC          = syscall.Errno(0x52)
+	EISCONN         = syscall.Errno(0x38)
+	EISDIR          = syscall.Errno(0x15)
+	ELAST           = syscall.Errno(0x5f)
+	ELOOP           = syscall.Errno(0x3e)
+	EMEDIUMTYPE     = syscall.Errno(0x56)
+	EMFILE          = syscall.Errno(0x18)
+	EMLINK          = syscall.Errno(0x1f)
+	EMSGSIZE        = syscall.Errno(0x28)
+	ENAMETOOLONG    = syscall.Errno(0x3f)
+	ENEEDAUTH       = syscall.Errno(0x51)
+	ENETDOWN        = syscall.Errno(0x32)
+	ENETRESET       = syscall.Errno(0x34)
+	ENETUNREACH     = syscall.Errno(0x33)
+	ENFILE          = syscall.Errno(0x17)
+	ENOATTR         = syscall.Errno(0x53)
+	ENOBUFS         = syscall.Errno(0x37)
+	ENODEV          = syscall.Errno(0x13)
+	ENOENT          = syscall.Errno(0x2)
+	ENOEXEC         = syscall.Errno(0x8)
+	ENOLCK          = syscall.Errno(0x4d)
+	ENOMEDIUM       = syscall.Errno(0x55)
+	ENOMEM          = syscall.Errno(0xc)
+	ENOMSG          = syscall.Errno(0x5a)
+	ENOPROTOOPT     = syscall.Errno(0x2a)
+	ENOSPC          = syscall.Errno(0x1c)
+	ENOSYS          = syscall.Errno(0x4e)
+	ENOTBLK         = syscall.Errno(0xf)
+	ENOTCONN        = syscall.Errno(0x39)
+	ENOTDIR         = syscall.Errno(0x14)
+	ENOTEMPTY       = syscall.Errno(0x42)
+	ENOTRECOVERABLE = syscall.Errno(0x5d)
+	ENOTSOCK        = syscall.Errno(0x26)
+	ENOTSUP         = syscall.Errno(0x5b)
+	ENOTTY          = syscall.Errno(0x19)
+	ENXIO           = syscall.Errno(0x6)
+	EOPNOTSUPP      = syscall.Errno(0x2d)
+	EOVERFLOW       = syscall.Errno(0x57)
+	EOWNERDEAD      = syscall.Errno(0x5e)
+	EPERM           = syscall.Errno(0x1)
+	EPFNOSUPPORT    = syscall.Errno(0x2e)
+	EPIPE           = syscall.Errno(0x20)
+	EPROCLIM        = syscall.Errno(0x43)
+	EPROCUNAVAIL    = syscall.Errno(0x4c)
+	EPROGMISMATCH   = syscall.Errno(0x4b)
+	EPROGUNAVAIL    = syscall.Errno(0x4a)
+	EPROTO          = syscall.Errno(0x5f)
+	EPROTONOSUPPORT = syscall.Errno(0x2b)
+	EPROTOTYPE      = syscall.Errno(0x29)
+	ERANGE          = syscall.Errno(0x22)
+	EREMOTE         = syscall.Errno(0x47)
+	EROFS           = syscall.Errno(0x1e)
+	ERPCMISMATCH    = syscall.Errno(0x49)
+	ESHUTDOWN       = syscall.Errno(0x3a)
+	ESOCKTNOSUPPORT = syscall.Errno(0x2c)
+	ESPIPE          = syscall.Errno(0x1d)
+	ESRCH           = syscall.Errno(0x3)
+	ESTALE          = syscall.Errno(0x46)
+	ETIMEDOUT       = syscall.Errno(0x3c)
+	ETOOMANYREFS    = syscall.Errno(0x3b)
+	ETXTBSY         = syscall.Errno(0x1a)
+	EUSERS          = syscall.Errno(0x44)
+	EWOULDBLOCK     = syscall.Errno(0x23)
+	EXDEV           = syscall.Errno(0x12)
+)
+
+// Signals
+const (
+	SIGABRT   = syscall.Signal(0x6)
+	SIGALRM   = syscall.Signal(0xe)
+	SIGBUS    = syscall.Signal(0xa)
+	SIGCHLD   = syscall.Signal(0x14)
+	SIGCONT   = syscall.Signal(0x13)
+	SIGEMT    = syscall.Signal(0x7)
+	SIGFPE    = syscall.Signal(0x8)
+	SIGHUP    = syscall.Signal(0x1)
+	SIGILL    = syscall.Signal(0x4)
+	SIGINFO   = syscall.Signal(0x1d)
+	SIGINT    = syscall.Signal(0x2)
+	SIGIO     = syscall.Signal(0x17)
+	SIGIOT    = syscall.Signal(0x6)
+	SIGKILL   = syscall.Signal(0x9)
+	SIGPIPE   = syscall.Signal(0xd)
+	SIGPROF   = syscall.Signal(0x1b)
+	SIGQUIT   = syscall.Signal(0x3)
+	SIGSEGV   = syscall.Signal(0xb)
+	SIGSTOP   = syscall.Signal(0x11)
+	SIGSYS    = syscall.Signal(0xc)
+	SIGTERM   = syscall.Signal(0xf)
+	SIGTHR    = syscall.Signal(0x20)
+	SIGTRAP   = syscall.Signal(0x5)
+	SIGTSTP   = syscall.Signal(0x12)
+	SIGTTIN   = syscall.Signal(0x15)
+	SIGTTOU   = syscall.Signal(0x16)
+	SIGURG    = syscall.Signal(0x10)
+	SIGUSR1   = syscall.Signal(0x1e)
+	SIGUSR2   = syscall.Signal(0x1f)
+	SIGVTALRM = syscall.Signal(0x1a)
+	SIGWINCH  = syscall.Signal(0x1c)
+	SIGXCPU   = syscall.Signal(0x18)
+	SIGXFSZ   = syscall.Signal(0x19)
+)
+
+// Error table
+var errorList = [...]struct {
+	num  syscall.Errno
+	name string
+	desc string
+}{
+	{1, "EPERM", "operation not permitted"},
+	{2, "ENOENT", "no such file or directory"},
+	{3, "ESRCH", "no such process"},
+	{4, "EINTR", "interrupted system call"},
+	{5, "EIO", "input/output error"},
+	{6, "ENXIO", "device not configured"},
+	{7, "E2BIG", "argument list too long"},
+	{8, "ENOEXEC", "exec format error"},
+	{9, "EBADF", "bad file descriptor"},
+	{10, "ECHILD", "no child processes"},
+	{11, "EDEADLK", "resource deadlock avoided"},
+	{12, "ENOMEM", "cannot allocate memory"},
+	{13, "EACCES", "permission denied"},
+	{14, "EFAULT", "bad address"},
+	{15, "ENOTBLK", "block device required"},
+	{16, "EBUSY", "device busy"},
+	{17, "EEXIST", "file exists"},
+	{18, "EXDEV", "cross-device link"},
+	{19, "ENODEV", "operation not supported by device"},
+	{20, "ENOTDIR", "not a directory"},
+	{21, "EISDIR", "is a directory"},
+	{22, "EINVAL", "invalid argument"},
+	{23, "ENFILE", "too many open files in system"},
+	{24, "EMFILE", "too many open files"},
+	{25, "ENOTTY", "inappropriate ioctl for device"},
+	{26, "ETXTBSY", "text file busy"},
+	{27, "EFBIG", "file too large"},
+	{28, "ENOSPC", "no space left on device"},
+	{29, "ESPIPE", "illegal seek"},
+	{30, "EROFS", "read-only file system"},
+	{31, "EMLINK", "too many links"},
+	{32, "EPIPE", "broken pipe"},
+	{33, "EDOM", "numerical argument out of domain"},
+	{34, "ERANGE", "result too large"},
+	{35, "EAGAIN", "resource temporarily unavailable"},
+	{36, "EINPROGRESS", "operation now in progress"},
+	{37, "EALREADY", "operation already in progress"},
+	{38, "ENOTSOCK", "socket operation on non-socket"},
+	{39, "EDESTADDRREQ", "destination address required"},
+	{40, "EMSGSIZE", "message too long"},
+	{41, "EPROTOTYPE", "protocol wrong type for socket"},
+	{42, "ENOPROTOOPT", "protocol not available"},
+	{43, "EPROTONOSUPPORT", "protocol not supported"},
+	{44, "ESOCKTNOSUPPORT", "socket type not supported"},
+	{45, "EOPNOTSUPP", "operation not supported"},
+	{46, "EPFNOSUPPORT", "protocol family not supported"},
+	{47, "EAFNOSUPPORT", "address family not supported by protocol family"},
+	{48, "EADDRINUSE", "address already in use"},
+	{49, "EADDRNOTAVAIL", "can't assign requested address"},
+	{50, "ENETDOWN", "network is down"},
+	{51, "ENETUNREACH", "network is unreachable"},
+	{52, "ENETRESET", "network dropped connection on reset"},
+	{53, "ECONNABORTED", "software caused connection abort"},
+	{54, "ECONNRESET", "connection reset by peer"},
+	{55, "ENOBUFS", "no buffer space available"},
+	{56, "EISCONN", "socket is already connected"},
+	{57, "ENOTCONN", "socket is not connected"},
+	{58, "ESHUTDOWN", "can't send after socket shutdown"},
+	{59, "ETOOMANYREFS", "too many references: can't splice"},
+	{60, "ETIMEDOUT", "operation timed out"},
+	{61, "ECONNREFUSED", "connection refused"},
+	{62, "ELOOP", "too many levels of symbolic links"},
+	{63, "ENAMETOOLONG", "file name too long"},
+	{64, "EHOSTDOWN", "host is down"},
+	{65, "EHOSTUNREACH", "no route to host"},
+	{66, "ENOTEMPTY", "directory not empty"},
+	{67, "EPROCLIM", "too many processes"},
+	{68, "EUSERS", "too many users"},
+	{69, "EDQUOT", "disk quota exceeded"},
+	{70, "ESTALE", "stale NFS file handle"},
+	{71, "EREMOTE", "too many levels of remote in path"},
+	{72, "EBADRPC", "RPC struct is bad"},
+	{73, "ERPCMISMATCH", "RPC version wrong"},
+	{74, "EPROGUNAVAIL", "RPC program not available"},
+	{75, "EPROGMISMATCH", "program version wrong"},
+	{76, "EPROCUNAVAIL", "bad procedure for program"},
+	{77, "ENOLCK", "no locks available"},
+	{78, "ENOSYS", "function not implemented"},
+	{79, "EFTYPE", "inappropriate file type or format"},
+	{80, "EAUTH", "authentication error"},
+	{81, "ENEEDAUTH", "need authenticator"},
+	{82, "EIPSEC", "IPsec processing failure"},
+	{83, "ENOATTR", "attribute not found"},
+	{84, "EILSEQ", "illegal byte sequence"},
+	{85, "ENOMEDIUM", "no medium found"},
+	{86, "EMEDIUMTYPE", "wrong medium type"},
+	{87, "EOVERFLOW", "value too large to be stored in data type"},
+	{88, "ECANCELED", "operation canceled"},
+	{89, "EIDRM", "identifier removed"},
+	{90, "ENOMSG", "no message of desired type"},
+	{91, "ENOTSUP", "not supported"},
+	{92, "EBADMSG", "bad message"},
+	{93, "ENOTRECOVERABLE", "state not recoverable"},
+	{94, "EOWNERDEAD", "previous owner died"},
+	{95, "ELAST", "protocol error"},
+}
+
+// Signal table
+var signalList = [...]struct {
+	num  syscall.Signal
+	name string
+	desc string
+}{
+	{1, "SIGHUP", "hangup"},
+	{2, "SIGINT", "interrupt"},
+	{3, "SIGQUIT", "quit"},
+	{4, "SIGILL", "illegal instruction"},
+	{5, "SIGTRAP", "trace/BPT trap"},
+	{6, "SIGABRT", "abort trap"},
+	{7, "SIGEMT", "EMT trap"},
+	{8, "SIGFPE", "floating point exception"},
+	{9, "SIGKILL", "killed"},
+	{10, "SIGBUS", "bus error"},
+	{11, "SIGSEGV", "segmentation fault"},
+	{12, "SIGSYS", "bad system call"},
+	{13, "SIGPIPE", "broken pipe"},
+	{14, "SIGALRM", "alarm clock"},
+	{15, "SIGTERM", "terminated"},
+	{16, "SIGURG", "urgent I/O condition"},
+	{17, "SIGSTOP", "suspended (signal)"},
+	{18, "SIGTSTP", "suspended"},
+	{19, "SIGCONT", "continued"},
+	{20, "SIGCHLD", "child exited"},
+	{21, "SIGTTIN", "stopped (tty input)"},
+	{22, "SIGTTOU", "stopped (tty output)"},
+	{23, "SIGIO", "I/O possible"},
+	{24, "SIGXCPU", "cputime limit exceeded"},
+	{25, "SIGXFSZ", "filesize limit exceeded"},
+	{26, "SIGVTALRM", "virtual timer expired"},
+	{27, "SIGPROF", "profiling timer expired"},
+	{28, "SIGWINCH", "window size changes"},
+	{29, "SIGINFO", "information request"},
+	{30, "SIGUSR1", "user defined signal 1"},
+	{31, "SIGUSR2", "user defined signal 2"},
+	{32, "SIGTHR", "thread AST"},
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.go
deleted file mode 100644
index a06eb09..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.go
+++ /dev/null
@@ -1,40 +0,0 @@
-// go run mksyscall.go -tags darwin,amd64,go1.13 syscall_darwin.1_13.go
-// Code generated by the command above; see README.md. DO NOT EDIT.
-
-//go:build darwin && amd64 && go1.13
-// +build darwin,amd64,go1.13
-
-package unix
-
-import (
-	"syscall"
-	"unsafe"
-)
-
-var _ syscall.Errno
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func closedir(dir uintptr) (err error) {
-	_, _, e1 := syscall_syscall(libc_closedir_trampoline_addr, uintptr(dir), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-var libc_closedir_trampoline_addr uintptr
-
-//go:cgo_import_dynamic libc_closedir closedir "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno) {
-	r0, _, _ := syscall_syscall(libc_readdir_r_trampoline_addr, uintptr(dir), uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result)))
-	res = Errno(r0)
-	return
-}
-
-var libc_readdir_r_trampoline_addr uintptr
-
-//go:cgo_import_dynamic libc_readdir_r readdir_r "/usr/lib/libSystem.B.dylib"
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.s b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.s
deleted file mode 100644
index d6c3e25..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.s
+++ /dev/null
@@ -1,25 +0,0 @@
-// go run mkasm_darwin.go amd64
-// Code generated by the command above; DO NOT EDIT.
-
-//go:build go1.13
-// +build go1.13
-
-#include "textflag.h"
-
-TEXT libc_fdopendir_trampoline<>(SB),NOSPLIT,$0-0
-	JMP	libc_fdopendir(SB)
-
-GLOBL	·libc_fdopendir_trampoline_addr(SB), RODATA, $8
-DATA	·libc_fdopendir_trampoline_addr(SB)/8, $libc_fdopendir_trampoline<>(SB)
-
-TEXT libc_closedir_trampoline<>(SB),NOSPLIT,$0-0
-	JMP	libc_closedir(SB)
-
-GLOBL	·libc_closedir_trampoline_addr(SB), RODATA, $8
-DATA	·libc_closedir_trampoline_addr(SB)/8, $libc_closedir_trampoline<>(SB)
-
-TEXT libc_readdir_r_trampoline<>(SB),NOSPLIT,$0-0
-	JMP	libc_readdir_r(SB)
-
-GLOBL	·libc_readdir_r_trampoline_addr(SB), RODATA, $8
-DATA	·libc_readdir_r_trampoline_addr(SB)/8, $libc_readdir_r_trampoline<>(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go
index 467deed..c2461c4 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go
@@ -1,8 +1,8 @@
-// go run mksyscall.go -tags darwin,amd64,go1.12 syscall_bsd.go syscall_darwin.go syscall_darwin_amd64.go
+// go run mksyscall.go -tags darwin,amd64 syscall_bsd.go syscall_darwin.go syscall_darwin_amd64.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
-//go:build darwin && amd64 && go1.12
-// +build darwin,amd64,go1.12
+//go:build darwin && amd64
+// +build darwin,amd64
 
 package unix
 
@@ -463,6 +463,32 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func closedir(dir uintptr) (err error) {
+	_, _, e1 := syscall_syscall(libc_closedir_trampoline_addr, uintptr(dir), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_closedir_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_closedir closedir "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno) {
+	r0, _, _ := syscall_syscall(libc_readdir_r_trampoline_addr, uintptr(dir), uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result)))
+	res = Errno(r0)
+	return
+}
+
+var libc_readdir_r_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_readdir_r readdir_r "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func pipe(p *[2]int32) (err error) {
 	_, _, e1 := syscall_rawSyscall(libc_pipe_trampoline_addr, uintptr(unsafe.Pointer(p)), 0, 0)
 	if e1 != 0 {
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s
index 7e308a4..95fe4c0 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s
@@ -1,11 +1,14 @@
-// go run mkasm_darwin.go amd64
+// go run mkasm.go darwin amd64
 // Code generated by the command above; DO NOT EDIT.
 
-//go:build go1.12
-// +build go1.12
-
 #include "textflag.h"
 
+TEXT libc_fdopendir_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fdopendir(SB)
+
+GLOBL	·libc_fdopendir_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fdopendir_trampoline_addr(SB)/8, $libc_fdopendir_trampoline<>(SB)
+
 TEXT libc_getgroups_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getgroups(SB)
 
@@ -174,6 +177,18 @@
 GLOBL	·libc_munlockall_trampoline_addr(SB), RODATA, $8
 DATA	·libc_munlockall_trampoline_addr(SB)/8, $libc_munlockall_trampoline<>(SB)
 
+TEXT libc_closedir_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_closedir(SB)
+
+GLOBL	·libc_closedir_trampoline_addr(SB), RODATA, $8
+DATA	·libc_closedir_trampoline_addr(SB)/8, $libc_closedir_trampoline<>(SB)
+
+TEXT libc_readdir_r_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_readdir_r(SB)
+
+GLOBL	·libc_readdir_r_trampoline_addr(SB), RODATA, $8
+DATA	·libc_readdir_r_trampoline_addr(SB)/8, $libc_readdir_r_trampoline<>(SB)
+
 TEXT libc_pipe_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_pipe(SB)
 
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.go
deleted file mode 100644
index cec595d..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.go
+++ /dev/null
@@ -1,40 +0,0 @@
-// go run mksyscall.go -tags darwin,arm64,go1.13 syscall_darwin.1_13.go
-// Code generated by the command above; see README.md. DO NOT EDIT.
-
-//go:build darwin && arm64 && go1.13
-// +build darwin,arm64,go1.13
-
-package unix
-
-import (
-	"syscall"
-	"unsafe"
-)
-
-var _ syscall.Errno
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func closedir(dir uintptr) (err error) {
-	_, _, e1 := syscall_syscall(libc_closedir_trampoline_addr, uintptr(dir), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-var libc_closedir_trampoline_addr uintptr
-
-//go:cgo_import_dynamic libc_closedir closedir "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno) {
-	r0, _, _ := syscall_syscall(libc_readdir_r_trampoline_addr, uintptr(dir), uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result)))
-	res = Errno(r0)
-	return
-}
-
-var libc_readdir_r_trampoline_addr uintptr
-
-//go:cgo_import_dynamic libc_readdir_r readdir_r "/usr/lib/libSystem.B.dylib"
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.s b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.s
deleted file mode 100644
index 3579897..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.s
+++ /dev/null
@@ -1,25 +0,0 @@
-// go run mkasm_darwin.go arm64
-// Code generated by the command above; DO NOT EDIT.
-
-//go:build go1.13
-// +build go1.13
-
-#include "textflag.h"
-
-TEXT libc_fdopendir_trampoline<>(SB),NOSPLIT,$0-0
-	JMP	libc_fdopendir(SB)
-
-GLOBL	·libc_fdopendir_trampoline_addr(SB), RODATA, $8
-DATA	·libc_fdopendir_trampoline_addr(SB)/8, $libc_fdopendir_trampoline<>(SB)
-
-TEXT libc_closedir_trampoline<>(SB),NOSPLIT,$0-0
-	JMP	libc_closedir(SB)
-
-GLOBL	·libc_closedir_trampoline_addr(SB), RODATA, $8
-DATA	·libc_closedir_trampoline_addr(SB)/8, $libc_closedir_trampoline<>(SB)
-
-TEXT libc_readdir_r_trampoline<>(SB),NOSPLIT,$0-0
-	JMP	libc_readdir_r(SB)
-
-GLOBL	·libc_readdir_r_trampoline_addr(SB), RODATA, $8
-DATA	·libc_readdir_r_trampoline_addr(SB)/8, $libc_readdir_r_trampoline<>(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go
index 35938d3..26a0fdc 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go
@@ -1,8 +1,8 @@
-// go run mksyscall.go -tags darwin,arm64,go1.12 syscall_bsd.go syscall_darwin.go syscall_darwin_arm64.go
+// go run mksyscall.go -tags darwin,arm64 syscall_bsd.go syscall_darwin.go syscall_darwin_arm64.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
-//go:build darwin && arm64 && go1.12
-// +build darwin,arm64,go1.12
+//go:build darwin && arm64
+// +build darwin,arm64
 
 package unix
 
@@ -463,6 +463,32 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func closedir(dir uintptr) (err error) {
+	_, _, e1 := syscall_syscall(libc_closedir_trampoline_addr, uintptr(dir), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_closedir_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_closedir closedir "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno) {
+	r0, _, _ := syscall_syscall(libc_readdir_r_trampoline_addr, uintptr(dir), uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result)))
+	res = Errno(r0)
+	return
+}
+
+var libc_readdir_r_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_readdir_r readdir_r "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func pipe(p *[2]int32) (err error) {
 	_, _, e1 := syscall_rawSyscall(libc_pipe_trampoline_addr, uintptr(unsafe.Pointer(p)), 0, 0)
 	if e1 != 0 {
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s
index b09e5bb..efa5b4c 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s
@@ -1,11 +1,14 @@
-// go run mkasm_darwin.go arm64
+// go run mkasm.go darwin arm64
 // Code generated by the command above; DO NOT EDIT.
 
-//go:build go1.12
-// +build go1.12
-
 #include "textflag.h"
 
+TEXT libc_fdopendir_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fdopendir(SB)
+
+GLOBL	·libc_fdopendir_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fdopendir_trampoline_addr(SB)/8, $libc_fdopendir_trampoline<>(SB)
+
 TEXT libc_getgroups_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_getgroups(SB)
 
@@ -174,6 +177,18 @@
 GLOBL	·libc_munlockall_trampoline_addr(SB), RODATA, $8
 DATA	·libc_munlockall_trampoline_addr(SB)/8, $libc_munlockall_trampoline<>(SB)
 
+TEXT libc_closedir_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_closedir(SB)
+
+GLOBL	·libc_closedir_trampoline_addr(SB), RODATA, $8
+DATA	·libc_closedir_trampoline_addr(SB)/8, $libc_closedir_trampoline<>(SB)
+
+TEXT libc_readdir_r_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_readdir_r(SB)
+
+GLOBL	·libc_readdir_r_trampoline_addr(SB), RODATA, $8
+DATA	·libc_readdir_r_trampoline_addr(SB)/8, $libc_readdir_r_trampoline<>(SB)
+
 TEXT libc_pipe_trampoline<>(SB),NOSPLIT,$0-0
 	JMP	libc_pipe(SB)
 
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go
index e9d9997..039c4aa 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go
@@ -912,7 +912,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func fstat(fd int, stat *stat_freebsd11_t) (err error) {
+func Fstat(fd int, stat *Stat_t) (err error) {
 	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -922,17 +922,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func fstat_freebsd12(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTAT_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fstatat(fd int, path string, stat *stat_freebsd11_t, flags int) (err error) {
+func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
@@ -947,22 +937,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func fstatat_freebsd12(fd int, path string, stat *Stat_t, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_FSTATAT_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fstatfs(fd int, stat *statfs_freebsd11_t) (err error) {
+func Fstatfs(fd int, stat *Statfs_t) (err error) {
 	_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -972,16 +947,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func fstatfs_freebsd12(fd int, stat *Statfs_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTATFS_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Fsync(fd int) (err error) {
 	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
 	if e1 != 0 {
@@ -1002,7 +967,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
+func getdirentries(fd int, buf []byte, basep *uint64) (n int, err error) {
 	var _p0 unsafe.Pointer
 	if len(buf) > 0 {
 		_p0 = unsafe.Pointer(&buf[0])
@@ -1019,23 +984,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func getdirentries_freebsd12(fd int, buf []byte, basep *uint64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_GETDIRENTRIES_FREEBSD12, uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Getdtablesize() (size int) {
 	r0, _, _ := Syscall(SYS_GETDTABLESIZE, 0, 0, 0)
 	size = int(r0)
@@ -1257,21 +1205,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func lstat(path string, stat *stat_freebsd11_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Mkdir(path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -1317,43 +1250,13 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func mknod(path string, mode uint32, dev int) (err error) {
+func Mknodat(fd int, path string, mode uint32, dev uint64) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func mknodat(fd int, path string, mode uint32, dev int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_MKNODAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func mknodat_freebsd12(fd int, path string, mode uint32, dev uint64) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_MKNODAT_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), uintptr(dev>>32), 0)
+	_, _, e1 := Syscall6(SYS_MKNODAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), uintptr(dev>>32), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1753,22 +1656,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func stat(path string, stat *stat_freebsd11_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func statfs(path string, stat *statfs_freebsd11_t) (err error) {
+func Statfs(path string, stat *Statfs_t) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
@@ -1783,21 +1671,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func statfs_freebsd12(path string, stat *Statfs_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_STATFS_FREEBSD12, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Symlink(path string, link string) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go
index edd373b..0535d3c 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go
@@ -912,7 +912,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func fstat(fd int, stat *stat_freebsd11_t) (err error) {
+func Fstat(fd int, stat *Stat_t) (err error) {
 	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -922,17 +922,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func fstat_freebsd12(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTAT_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fstatat(fd int, path string, stat *stat_freebsd11_t, flags int) (err error) {
+func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
@@ -947,22 +937,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func fstatat_freebsd12(fd int, path string, stat *Stat_t, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_FSTATAT_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fstatfs(fd int, stat *statfs_freebsd11_t) (err error) {
+func Fstatfs(fd int, stat *Statfs_t) (err error) {
 	_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -972,16 +947,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func fstatfs_freebsd12(fd int, stat *Statfs_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTATFS_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Fsync(fd int) (err error) {
 	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
 	if e1 != 0 {
@@ -1002,7 +967,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
+func getdirentries(fd int, buf []byte, basep *uint64) (n int, err error) {
 	var _p0 unsafe.Pointer
 	if len(buf) > 0 {
 		_p0 = unsafe.Pointer(&buf[0])
@@ -1019,23 +984,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func getdirentries_freebsd12(fd int, buf []byte, basep *uint64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_GETDIRENTRIES_FREEBSD12, uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Getdtablesize() (size int) {
 	r0, _, _ := Syscall(SYS_GETDTABLESIZE, 0, 0, 0)
 	size = int(r0)
@@ -1257,21 +1205,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func lstat(path string, stat *stat_freebsd11_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Mkdir(path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -1317,22 +1250,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func mknod(path string, mode uint32, dev int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func mknodat(fd int, path string, mode uint32, dev int) (err error) {
+func Mknodat(fd int, path string, mode uint32, dev uint64) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
@@ -1347,21 +1265,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func mknodat_freebsd12(fd int, path string, mode uint32, dev uint64) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_MKNODAT_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
 	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
 	if e1 != 0 {
@@ -1753,22 +1656,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func stat(path string, stat *stat_freebsd11_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func statfs(path string, stat *statfs_freebsd11_t) (err error) {
+func Statfs(path string, stat *Statfs_t) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
@@ -1783,21 +1671,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func statfs_freebsd12(path string, stat *Statfs_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_STATFS_FREEBSD12, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Symlink(path string, link string) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go
index 82e9764..1018b52 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go
@@ -351,22 +351,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
-	var _p0 unsafe.Pointer
-	if len(mib) > 0 {
-		_p0 = unsafe.Pointer(&mib[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func pipe2(p *[2]_C_int, flags int) (err error) {
 	_, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
 	if e1 != 0 {
@@ -404,6 +388,22 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
+	var _p0 unsafe.Pointer
+	if len(mib) > 0 {
+		_p0 = unsafe.Pointer(&mib[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func ptrace(request int, pid int, addr uintptr, data int) (err error) {
 	_, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
 	if e1 != 0 {
@@ -912,7 +912,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func fstat(fd int, stat *stat_freebsd11_t) (err error) {
+func Fstat(fd int, stat *Stat_t) (err error) {
 	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -922,17 +922,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func fstat_freebsd12(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTAT_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fstatat(fd int, path string, stat *stat_freebsd11_t, flags int) (err error) {
+func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
@@ -947,22 +937,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func fstatat_freebsd12(fd int, path string, stat *Stat_t, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_FSTATAT_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fstatfs(fd int, stat *statfs_freebsd11_t) (err error) {
+func Fstatfs(fd int, stat *Statfs_t) (err error) {
 	_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -972,16 +947,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func fstatfs_freebsd12(fd int, stat *Statfs_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTATFS_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Fsync(fd int) (err error) {
 	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
 	if e1 != 0 {
@@ -1002,7 +967,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
+func getdirentries(fd int, buf []byte, basep *uint64) (n int, err error) {
 	var _p0 unsafe.Pointer
 	if len(buf) > 0 {
 		_p0 = unsafe.Pointer(&buf[0])
@@ -1019,23 +984,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func getdirentries_freebsd12(fd int, buf []byte, basep *uint64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_GETDIRENTRIES_FREEBSD12, uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Getdtablesize() (size int) {
 	r0, _, _ := Syscall(SYS_GETDTABLESIZE, 0, 0, 0)
 	size = int(r0)
@@ -1257,21 +1205,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func lstat(path string, stat *stat_freebsd11_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Mkdir(path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -1317,43 +1250,13 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func mknod(path string, mode uint32, dev int) (err error) {
+func Mknodat(fd int, path string, mode uint32, dev uint64) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func mknodat(fd int, path string, mode uint32, dev int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_MKNODAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func mknodat_freebsd12(fd int, path string, mode uint32, dev uint64) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_MKNODAT_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
+	_, _, e1 := Syscall6(SYS_MKNODAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0, uintptr(dev), uintptr(dev>>32))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1753,22 +1656,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func stat(path string, stat *stat_freebsd11_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func statfs(path string, stat *statfs_freebsd11_t) (err error) {
+func Statfs(path string, stat *Statfs_t) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
@@ -1783,21 +1671,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func statfs_freebsd12(path string, stat *Statfs_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_STATFS_FREEBSD12, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Symlink(path string, link string) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm64.go
index a6479ac..3802f4b 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm64.go
@@ -912,7 +912,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func fstat(fd int, stat *stat_freebsd11_t) (err error) {
+func Fstat(fd int, stat *Stat_t) (err error) {
 	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -922,17 +922,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func fstat_freebsd12(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTAT_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fstatat(fd int, path string, stat *stat_freebsd11_t, flags int) (err error) {
+func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
@@ -947,22 +937,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func fstatat_freebsd12(fd int, path string, stat *Stat_t, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_FSTATAT_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fstatfs(fd int, stat *statfs_freebsd11_t) (err error) {
+func Fstatfs(fd int, stat *Statfs_t) (err error) {
 	_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -972,16 +947,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func fstatfs_freebsd12(fd int, stat *Statfs_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTATFS_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Fsync(fd int) (err error) {
 	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
 	if e1 != 0 {
@@ -1002,7 +967,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
+func getdirentries(fd int, buf []byte, basep *uint64) (n int, err error) {
 	var _p0 unsafe.Pointer
 	if len(buf) > 0 {
 		_p0 = unsafe.Pointer(&buf[0])
@@ -1019,23 +984,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func getdirentries_freebsd12(fd int, buf []byte, basep *uint64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_GETDIRENTRIES_FREEBSD12, uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Getdtablesize() (size int) {
 	r0, _, _ := Syscall(SYS_GETDTABLESIZE, 0, 0, 0)
 	size = int(r0)
@@ -1257,21 +1205,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func lstat(path string, stat *stat_freebsd11_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Mkdir(path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -1317,22 +1250,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func mknod(path string, mode uint32, dev int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func mknodat(fd int, path string, mode uint32, dev int) (err error) {
+func Mknodat(fd int, path string, mode uint32, dev uint64) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
@@ -1347,21 +1265,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func mknodat_freebsd12(fd int, path string, mode uint32, dev uint64) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_MKNODAT_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
 	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
 	if e1 != 0 {
@@ -1753,22 +1656,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func stat(path string, stat *stat_freebsd11_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func statfs(path string, stat *statfs_freebsd11_t) (err error) {
+func Statfs(path string, stat *Statfs_t) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
@@ -1783,21 +1671,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func statfs_freebsd12(path string, stat *Statfs_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_STATFS_FREEBSD12, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Symlink(path string, link string) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_freebsd_riscv64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_freebsd_riscv64.go
new file mode 100644
index 0000000..8a2db7d
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_freebsd_riscv64.go
@@ -0,0 +1,1889 @@
+// go run mksyscall.go -tags freebsd,riscv64 syscall_bsd.go syscall_freebsd.go syscall_freebsd_riscv64.go
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+//go:build freebsd && riscv64
+// +build freebsd,riscv64
+
+package unix
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+var _ syscall.Errno
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setgroups(ngid int, gid *_Gid_t) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
+	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+	wpid = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socket(domain int, typ int, proto int) (fd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
+	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
+	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Shutdown(s int, how int) (err error) {
+	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
+	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
+	r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimes(path string, timeval *[2]Timeval) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func futimes(fd int, timeval *[2]Timeval) (err error) {
+	_, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Madvise(b []byte, behav int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlockall(flags int) (err error) {
+	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mprotect(b []byte, prot int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Msync(b []byte, flags int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlockall() (err error) {
+	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe2(p *[2]_C_int, flags int) (err error) {
+	_, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getcwd(buf []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS___GETCWD, uintptr(_p0), uintptr(len(buf)), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func ioctl(fd int, req uint, arg uintptr) (err error) {
+	_, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
+	var _p0 unsafe.Pointer
+	if len(mib) > 0 {
+		_p0 = unsafe.Pointer(&mib[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func ptrace(request int, pid int, addr uintptr, data int) (err error) {
+	_, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Access(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
+	_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func CapEnter() (err error) {
+	_, _, e1 := Syscall(SYS_CAP_ENTER, 0, 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func capRightsGet(version int, fd int, rightsp *CapRights) (err error) {
+	_, _, e1 := Syscall(SYS___CAP_RIGHTS_GET, uintptr(version), uintptr(fd), uintptr(unsafe.Pointer(rightsp)))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func capRightsLimit(fd int, rightsp *CapRights) (err error) {
+	_, _, e1 := Syscall(SYS_CAP_RIGHTS_LIMIT, uintptr(fd), uintptr(unsafe.Pointer(rightsp)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chflags(path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chmod(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chroot(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Close(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup(fd int) (nfd int, err error) {
+	r0, _, e1 := Syscall(SYS_DUP, uintptr(fd), 0, 0)
+	nfd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup2(from int, to int) (err error) {
+	_, _, e1 := Syscall(SYS_DUP2, uintptr(from), uintptr(to), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Exit(code int) {
+	Syscall(SYS_EXIT, uintptr(code), 0, 0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func ExtattrGetFd(fd int, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(attrname)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall6(SYS_EXTATTR_GET_FD, uintptr(fd), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p0)), uintptr(data), uintptr(nbytes), 0)
+	ret = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func ExtattrSetFd(fd int, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(attrname)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall6(SYS_EXTATTR_SET_FD, uintptr(fd), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p0)), uintptr(data), uintptr(nbytes), 0)
+	ret = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func ExtattrDeleteFd(fd int, attrnamespace int, attrname string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(attrname)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_EXTATTR_DELETE_FD, uintptr(fd), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p0)))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func ExtattrListFd(fd int, attrnamespace int, data uintptr, nbytes int) (ret int, err error) {
+	r0, _, e1 := Syscall6(SYS_EXTATTR_LIST_FD, uintptr(fd), uintptr(attrnamespace), uintptr(data), uintptr(nbytes), 0, 0)
+	ret = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func ExtattrGetFile(file string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(file)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(attrname)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall6(SYS_EXTATTR_GET_FILE, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p1)), uintptr(data), uintptr(nbytes), 0)
+	ret = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func ExtattrSetFile(file string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(file)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(attrname)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall6(SYS_EXTATTR_SET_FILE, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p1)), uintptr(data), uintptr(nbytes), 0)
+	ret = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func ExtattrDeleteFile(file string, attrnamespace int, attrname string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(file)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(attrname)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_EXTATTR_DELETE_FILE, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p1)))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func ExtattrListFile(file string, attrnamespace int, data uintptr, nbytes int) (ret int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(file)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall6(SYS_EXTATTR_LIST_FILE, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(data), uintptr(nbytes), 0, 0)
+	ret = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func ExtattrGetLink(link string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(attrname)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall6(SYS_EXTATTR_GET_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p1)), uintptr(data), uintptr(nbytes), 0)
+	ret = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func ExtattrSetLink(link string, attrnamespace int, attrname string, data uintptr, nbytes int) (ret int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(attrname)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall6(SYS_EXTATTR_SET_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p1)), uintptr(data), uintptr(nbytes), 0)
+	ret = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func ExtattrDeleteLink(link string, attrnamespace int, attrname string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(attrname)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_EXTATTR_DELETE_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(unsafe.Pointer(_p1)))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func ExtattrListLink(link string, attrnamespace int, data uintptr, nbytes int) (ret int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall6(SYS_EXTATTR_LIST_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(attrnamespace), uintptr(data), uintptr(nbytes), 0, 0)
+	ret = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fadvise(fd int, offset int64, length int64, advice int) (err error) {
+	_, _, e1 := Syscall6(SYS_POSIX_FADVISE, uintptr(fd), uintptr(offset), uintptr(length), uintptr(advice), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchdir(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchflags(fd int, flags int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchmod(fd int, mode uint32) (err error) {
+	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchown(fd int, uid int, gid int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_FCHOWNAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Flock(fd int, how int) (err error) {
+	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fpathconf(fd int, name int) (val int, err error) {
+	r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0)
+	val = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstat(fd int, stat *Stat_t) (err error) {
+	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstatfs(fd int, stat *Statfs_t) (err error) {
+	_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fsync(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ftruncate(fd int, length int64) (err error) {
+	_, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getdirentries(fd int, buf []byte, basep *uint64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_GETDIRENTRIES, uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getdtablesize() (size int) {
+	r0, _, _ := Syscall(SYS_GETDTABLESIZE, 0, 0, 0)
+	size = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getegid() (egid int) {
+	r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
+	egid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Geteuid() (uid int) {
+	r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getgid() (gid int) {
+	r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
+	gid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgid(pid int) (pgid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
+	pgid = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgrp() (pgrp int) {
+	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
+	pgrp = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpid() (pid int) {
+	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
+	pid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getppid() (ppid int) {
+	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
+	ppid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpriority(which int, who int) (prio int, err error) {
+	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
+	prio = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrlimit(which int, lim *Rlimit) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrusage(who int, rusage *Rusage) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getsid(pid int) (sid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0)
+	sid = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Gettimeofday(tv *Timeval) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getuid() (uid int) {
+	r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Issetugid() (tainted bool) {
+	r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0)
+	tainted = bool(r0 != 0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kill(pid int, signum syscall.Signal) (err error) {
+	_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kqueue() (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lchown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Link(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_LINKAT, uintptr(pathfd), uintptr(unsafe.Pointer(_p0)), uintptr(linkfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Listen(s int, backlog int) (err error) {
+	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkdir(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkdirat(dirfd int, path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKDIRAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkfifo(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mknodat(fd int, path string, mode uint32, dev uint64) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_MKNODAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
+	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Open(path string, mode int, perm uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Openat(fdat int, path string, mode int, perm uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(fdat), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pathconf(path string, name int) (val int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
+	val = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pread(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pwrite(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func read(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Readlink(path string, buf []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(buf) > 0 {
+		_p1 = unsafe.Pointer(&buf[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(buf) > 0 {
+		_p1 = unsafe.Pointer(&buf[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_READLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rename(from string, to string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(from)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(to)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Renameat(fromfd int, from string, tofd int, to string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(from)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(to)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Revoke(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rmdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
+	r0, _, e1 := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence))
+	newoffset = int64(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {
+	r0, _, e1 := Syscall6(SYS_SELECT, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setegid(egid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETEGID, uintptr(egid), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seteuid(euid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setgid(gid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setlogin(name string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(name)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpgid(pid int, pgid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpriority(which int, who int, prio int) (err error) {
+	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setregid(rgid int, egid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setreuid(ruid int, euid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setresgid(rgid int, egid int, sgid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setresuid(ruid int, euid int, suid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setrlimit(which int, lim *Rlimit) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setsid() (pid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
+	pid = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Settimeofday(tp *Timeval) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setuid(uid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Statfs(path string, stat *Statfs_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Symlink(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(oldpath)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(newpath)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SYMLINKAT, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sync() (err error) {
+	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Truncate(path string, length int64) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), uintptr(length), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Umask(newmask int) (oldmask int) {
+	r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0)
+	oldmask = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Undelete(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNDELETE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unlink(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unlinkat(dirfd int, path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unmount(path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func write(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
+	r0, _, e1 := Syscall6(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos))
+	ret = uintptr(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func munmap(addr uintptr, length uintptr) (err error) {
+	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error) {
+	r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
+	nfd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_illumos_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_illumos_amd64.go
index af5cb06..b57c705 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_illumos_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_illumos_amd64.go
@@ -15,25 +15,19 @@
 //go:cgo_import_dynamic libc_writev writev "libc.so"
 //go:cgo_import_dynamic libc_pwritev pwritev "libc.so"
 //go:cgo_import_dynamic libc_accept4 accept4 "libsocket.so"
-//go:cgo_import_dynamic libc_putmsg putmsg "libc.so"
-//go:cgo_import_dynamic libc_getmsg getmsg "libc.so"
 
 //go:linkname procreadv libc_readv
 //go:linkname procpreadv libc_preadv
 //go:linkname procwritev libc_writev
 //go:linkname procpwritev libc_pwritev
 //go:linkname procaccept4 libc_accept4
-//go:linkname procputmsg libc_putmsg
-//go:linkname procgetmsg libc_getmsg
 
 var (
 	procreadv,
 	procpreadv,
 	procwritev,
 	procpwritev,
-	procaccept4,
-	procputmsg,
-	procgetmsg syscallFunc
+	procaccept4 syscallFunc
 )
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -106,23 +100,3 @@
 	}
 	return
 }
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func putmsg(fd int, clptr *strbuf, dataptr *strbuf, flags int) (err error) {
-	_, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procputmsg)), 4, uintptr(fd), uintptr(unsafe.Pointer(clptr)), uintptr(unsafe.Pointer(dataptr)), uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getmsg(fd int, clptr *strbuf, dataptr *strbuf, flags *int) (err error) {
-	_, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procgetmsg)), 4, uintptr(fd), uintptr(unsafe.Pointer(clptr)), uintptr(unsafe.Pointer(dataptr)), uintptr(unsafe.Pointer(flags)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux.go
index bc4a275..293cf36 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux.go
@@ -2151,3 +2151,13 @@
 	}
 	return
 }
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func rtSigprocmask(how int, set *Sigset_t, oldset *Sigset_t, sigsetsize uintptr) (err error) {
+	_, _, e1 := RawSyscall6(SYS_RT_SIGPROCMASK, uintptr(how), uintptr(unsafe.Pointer(set)), uintptr(unsafe.Pointer(oldset)), uintptr(sigsetsize), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go
index 88af526..c81b0ad 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go
@@ -287,46 +287,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREGID32, uintptr(rgid), uintptr(egid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setresgid(rgid int, egid int, sgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESGID32, uintptr(rgid), uintptr(egid), uintptr(sgid))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setresuid(ruid int, euid int, suid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESUID32, uintptr(ruid), uintptr(euid), uintptr(suid))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREUID32, uintptr(ruid), uintptr(euid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) {
 	r0, _, e1 := Syscall6(SYS_SPLICE, uintptr(rfd), uintptr(unsafe.Pointer(roff)), uintptr(wfd), uintptr(unsafe.Pointer(woff)), uintptr(len), uintptr(flags))
 	n = int(r0)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go
index 2a0c4aa..2206bce 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go
@@ -334,36 +334,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setresgid(rgid int, egid int, sgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setresuid(ruid int, euid int, suid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Setrlimit(resource int, rlim *Rlimit) (err error) {
 	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
 	if e1 != 0 {
@@ -374,16 +344,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Shutdown(fd int, how int) (err error) {
 	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
 	if e1 != 0 {
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go
index 4882bde..edf6b39 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go
@@ -412,46 +412,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREGID32, uintptr(rgid), uintptr(egid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setresgid(rgid int, egid int, sgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESGID32, uintptr(rgid), uintptr(egid), uintptr(sgid))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setresuid(ruid int, euid int, suid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESUID32, uintptr(ruid), uintptr(euid), uintptr(suid))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREUID32, uintptr(ruid), uintptr(euid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Shutdown(fd int, how int) (err error) {
 	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
 	if e1 != 0 {
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go
index 9f8c24e..190609f 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go
@@ -289,36 +289,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setresgid(rgid int, egid int, sgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setresuid(ruid int, euid int, suid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func setrlimit(resource int, rlim *Rlimit) (err error) {
 	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
 	if e1 != 0 {
@@ -329,16 +299,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Shutdown(fd int, how int) (err error) {
 	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
 	if e1 != 0 {
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_loong64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_loong64.go
index 8cdfbe7..806ffd1 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_loong64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_loong64.go
@@ -83,31 +83,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Fstat(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Fstatfs(fd int, buf *Statfs_t) (err error) {
 	_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(buf)), 0)
 	if e1 != 0 {
@@ -248,46 +223,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setresgid(rgid int, egid int, sgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setresuid(ruid int, euid int, suid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Shutdown(fd int, how int) (err error) {
 	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
 	if e1 != 0 {
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go
index d7d6f42..5f984cb 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go
@@ -248,46 +248,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setresgid(rgid int, egid int, sgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setresuid(ruid int, euid int, suid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Shutdown(fd int, how int) (err error) {
 	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
 	if e1 != 0 {
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go
index 7f1f8e6..46fc380 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go
@@ -278,36 +278,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setresgid(rgid int, egid int, sgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setresuid(ruid int, euid int, suid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Setrlimit(resource int, rlim *Rlimit) (err error) {
 	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
 	if e1 != 0 {
@@ -318,16 +288,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Shutdown(fd int, how int) (err error) {
 	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
 	if e1 != 0 {
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go
index f933d0f..cbd0d4d 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go
@@ -278,36 +278,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setresgid(rgid int, egid int, sgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setresuid(ruid int, euid int, suid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Setrlimit(resource int, rlim *Rlimit) (err error) {
 	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
 	if e1 != 0 {
@@ -318,16 +288,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Shutdown(fd int, how int) (err error) {
 	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
 	if e1 != 0 {
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go
index 297d0a9..0c13d15 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go
@@ -248,46 +248,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setresgid(rgid int, egid int, sgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setresuid(ruid int, euid int, suid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Shutdown(fd int, how int) (err error) {
 	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
 	if e1 != 0 {
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc.go
index 2e32e7a..e01432a 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc.go
@@ -308,46 +308,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setresgid(rgid int, egid int, sgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setresuid(ruid int, euid int, suid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Shutdown(fd int, how int) (err error) {
 	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
 	if e1 != 0 {
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go
index 3c53170..13c7ee7 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go
@@ -349,36 +349,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setresgid(rgid int, egid int, sgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setresuid(ruid int, euid int, suid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Setrlimit(resource int, rlim *Rlimit) (err error) {
 	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
 	if e1 != 0 {
@@ -389,16 +359,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Shutdown(fd int, how int) (err error) {
 	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
 	if e1 != 0 {
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go
index a00c674..02d0c0f 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go
@@ -349,36 +349,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setresgid(rgid int, egid int, sgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setresuid(ruid int, euid int, suid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Setrlimit(resource int, rlim *Rlimit) (err error) {
 	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
 	if e1 != 0 {
@@ -389,16 +359,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Shutdown(fd int, how int) (err error) {
 	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
 	if e1 != 0 {
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go
index a1a9bcb..9fee3b1 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go
@@ -180,6 +180,17 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func MemfdSecret(flags int) (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_MEMFD_SECRET, uintptr(flags), 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func pread(fd int, p []byte, offset int64) (n int, err error) {
 	var _p0 unsafe.Pointer
 	if len(p) > 0 {
@@ -258,36 +269,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setresgid(rgid int, egid int, sgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setresuid(ruid int, euid int, suid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Setrlimit(resource int, rlim *Rlimit) (err error) {
 	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
 	if e1 != 0 {
@@ -298,16 +279,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Shutdown(fd int, how int) (err error) {
 	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
 	if e1 != 0 {
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go
index e0dabc6..647bbfe 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go
@@ -319,36 +319,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setresgid(rgid int, egid int, sgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setresuid(ruid int, euid int, suid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Setrlimit(resource int, rlim *Rlimit) (err error) {
 	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
 	if e1 != 0 {
@@ -359,16 +329,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) {
 	r0, _, e1 := Syscall6(SYS_SPLICE, uintptr(rfd), uintptr(unsafe.Pointer(roff)), uintptr(wfd), uintptr(unsafe.Pointer(woff)), uintptr(len), uintptr(flags))
 	n = int64(r0)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go
index 368623c..ada057f 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go
@@ -329,36 +329,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setresgid(rgid int, egid int, sgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setresuid(ruid int, euid int, suid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Setrlimit(resource int, rlim *Rlimit) (err error) {
 	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
 	if e1 != 0 {
@@ -369,16 +339,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Shutdown(fd int, how int) (err error) {
 	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
 	if e1 != 0 {
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go
index a057fc5..2925fe0 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go
@@ -1,4 +1,4 @@
-// go run mksyscall.go -l32 -openbsd -tags openbsd,386 syscall_bsd.go syscall_openbsd.go syscall_openbsd_386.go
+// go run mksyscall.go -l32 -openbsd -libc -tags openbsd,386 syscall_bsd.go syscall_openbsd.go syscall_openbsd_386.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build openbsd && 386
@@ -16,7 +16,7 @@
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	r0, _, e1 := syscall_rawSyscall(libc_getgroups_trampoline_addr, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -24,20 +24,28 @@
 	return
 }
 
+var libc_getgroups_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getgroups getgroups "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func setgroups(ngid int, gid *_Gid_t) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	_, _, e1 := syscall_rawSyscall(libc_setgroups_trampoline_addr, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setgroups_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setgroups setgroups "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
-	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+	r0, _, e1 := syscall_syscall6(libc_wait4_trampoline_addr, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
 	wpid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -45,10 +53,14 @@
 	return
 }
 
+var libc_wait4_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_wait4 wait4 "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	r0, _, e1 := syscall_syscall(libc_accept_trampoline_addr, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -56,30 +68,42 @@
 	return
 }
 
+var libc_accept_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_accept accept "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
+	_, _, e1 := syscall_syscall(libc_bind_trampoline_addr, uintptr(s), uintptr(addr), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_bind_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_bind bind "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
+	_, _, e1 := syscall_syscall(libc_connect_trampoline_addr, uintptr(s), uintptr(addr), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_connect_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_connect connect "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func socket(domain int, typ int, proto int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
+	r0, _, e1 := syscall_rawSyscall(libc_socket_trampoline_addr, uintptr(domain), uintptr(typ), uintptr(proto))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -87,66 +111,94 @@
 	return
 }
 
+var libc_socket_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_socket socket "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
-	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+	_, _, e1 := syscall_syscall6(libc_getsockopt_trampoline_addr, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_getsockopt_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getsockopt getsockopt "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
-	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+	_, _, e1 := syscall_syscall6(libc_setsockopt_trampoline_addr, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setsockopt_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setsockopt setsockopt "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	_, _, e1 := syscall_rawSyscall(libc_getpeername_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_getpeername_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getpeername getpeername "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	_, _, e1 := syscall_rawSyscall(libc_getsockname_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_getsockname_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getsockname getsockname "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Shutdown(s int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0)
+	_, _, e1 := syscall_syscall(libc_shutdown_trampoline_addr, uintptr(s), uintptr(how), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_shutdown_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_shutdown shutdown "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
-	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+	_, _, e1 := syscall_rawSyscall6(libc_socketpair_trampoline_addr, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_socketpair_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_socketpair socketpair "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
@@ -156,7 +208,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	r0, _, e1 := syscall_syscall6(libc_recvfrom_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -164,6 +216,10 @@
 	return
 }
 
+var libc_recvfrom_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_recvfrom recvfrom "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
@@ -173,17 +229,21 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+	_, _, e1 := syscall_syscall6(libc_sendto_trampoline_addr, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_sendto_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_sendto sendto "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	r0, _, e1 := syscall_syscall(libc_recvmsg_trampoline_addr, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -191,10 +251,14 @@
 	return
 }
 
+var libc_recvmsg_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_recvmsg recvmsg "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	r0, _, e1 := syscall_syscall(libc_sendmsg_trampoline_addr, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -202,10 +266,14 @@
 	return
 }
 
+var libc_sendmsg_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_sendmsg sendmsg "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
-	r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
+	r0, _, e1 := syscall_syscall6(libc_kevent_trampoline_addr, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -213,6 +281,10 @@
 	return
 }
 
+var libc_kevent_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_kevent kevent "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func utimes(path string, timeval *[2]Timeval) (err error) {
@@ -221,27 +293,35 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
+	_, _, e1 := syscall_syscall(libc_utimes_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_utimes_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_utimes utimes "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func futimes(fd int, timeval *[2]Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
+	_, _, e1 := syscall_syscall(libc_futimes_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_futimes_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_futimes futimes "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
+	r0, _, e1 := syscall_syscall(libc_poll_trampoline_addr, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -249,6 +329,10 @@
 	return
 }
 
+var libc_poll_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_poll poll "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Madvise(b []byte, behav int) (err error) {
@@ -258,13 +342,17 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav))
+	_, _, e1 := syscall_syscall(libc_madvise_trampoline_addr, uintptr(_p0), uintptr(len(b)), uintptr(behav))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_madvise_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_madvise madvise "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mlock(b []byte) (err error) {
@@ -274,23 +362,31 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	_, _, e1 := syscall_syscall(libc_mlock_trampoline_addr, uintptr(_p0), uintptr(len(b)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mlock_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mlock mlock "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mlockall(flags int) (err error) {
-	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
+	_, _, e1 := syscall_syscall(libc_mlockall_trampoline_addr, uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mlockall_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mlockall mlockall "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mprotect(b []byte, prot int) (err error) {
@@ -300,13 +396,17 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
+	_, _, e1 := syscall_syscall(libc_mprotect_trampoline_addr, uintptr(_p0), uintptr(len(b)), uintptr(prot))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mprotect_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mprotect mprotect "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Msync(b []byte, flags int) (err error) {
@@ -316,13 +416,17 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	_, _, e1 := syscall_syscall(libc_msync_trampoline_addr, uintptr(_p0), uintptr(len(b)), uintptr(flags))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_msync_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_msync msync "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Munlock(b []byte) (err error) {
@@ -332,33 +436,45 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	_, _, e1 := syscall_syscall(libc_munlock_trampoline_addr, uintptr(_p0), uintptr(len(b)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_munlock_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_munlock munlock "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Munlockall() (err error) {
-	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
+	_, _, e1 := syscall_syscall(libc_munlockall_trampoline_addr, 0, 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_munlockall_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_munlockall munlockall "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func pipe2(p *[2]_C_int, flags int) (err error) {
-	_, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
+	_, _, e1 := syscall_rawSyscall(libc_pipe2_trampoline_addr, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_pipe2_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_pipe2 pipe2 "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getdents(fd int, buf []byte) (n int, err error) {
@@ -368,7 +484,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(SYS_GETDENTS, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+	r0, _, e1 := syscall_syscall(libc_getdents_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -376,6 +492,10 @@
 	return
 }
 
+var libc_getdents_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getdents getdents "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getcwd(buf []byte) (n int, err error) {
@@ -385,7 +505,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(SYS___GETCWD, uintptr(_p0), uintptr(len(buf)), 0)
+	r0, _, e1 := syscall_syscall(libc_getcwd_trampoline_addr, uintptr(_p0), uintptr(len(buf)), 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -393,16 +513,24 @@
 	return
 }
 
+var libc_getcwd_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getcwd getcwd "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func ioctl(fd int, req uint, arg uintptr) (err error) {
-	_, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg))
+	_, _, e1 := syscall_syscall(libc_ioctl_trampoline_addr, uintptr(fd), uintptr(req), uintptr(arg))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_ioctl_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_ioctl ioctl "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
@@ -412,17 +540,21 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
+	_, _, e1 := syscall_syscall6(libc_sysctl_trampoline_addr, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_sysctl_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_sysctl sysctl "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
-	r0, _, e1 := Syscall6(SYS_PPOLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0)
+	r0, _, e1 := syscall_syscall6(libc_ppoll_trampoline_addr, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -430,6 +562,10 @@
 	return
 }
 
+var libc_ppoll_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_ppoll ppoll "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Access(path string, mode uint32) (err error) {
@@ -438,23 +574,31 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall_syscall(libc_access_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_access_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_access access "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
+	_, _, e1 := syscall_syscall(libc_adjtime_trampoline_addr, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_adjtime_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_adjtime adjtime "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Chdir(path string) (err error) {
@@ -463,13 +607,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_chdir_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_chdir_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_chdir chdir "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Chflags(path string, flags int) (err error) {
@@ -478,13 +626,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	_, _, e1 := syscall_syscall(libc_chflags_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_chflags_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_chflags chflags "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Chmod(path string, mode uint32) (err error) {
@@ -493,13 +645,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall_syscall(libc_chmod_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_chmod_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_chmod chmod "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Chown(path string, uid int, gid int) (err error) {
@@ -508,13 +664,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall_syscall(libc_chown_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_chown_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_chown chown "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Chroot(path string) (err error) {
@@ -523,27 +683,35 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_chroot_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_chroot_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_chroot chroot "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Close(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+	_, _, e1 := syscall_syscall(libc_close_trampoline_addr, uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_close_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_close close "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Dup(fd int) (nfd int, err error) {
-	r0, _, e1 := Syscall(SYS_DUP, uintptr(fd), 0, 0)
+	r0, _, e1 := syscall_syscall(libc_dup_trampoline_addr, uintptr(fd), 0, 0)
 	nfd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -551,33 +719,49 @@
 	return
 }
 
+var libc_dup_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_dup dup "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Dup2(from int, to int) (err error) {
-	_, _, e1 := Syscall(SYS_DUP2, uintptr(from), uintptr(to), 0)
+	_, _, e1 := syscall_syscall(libc_dup2_trampoline_addr, uintptr(from), uintptr(to), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_dup2_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_dup2 dup2 "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Dup3(from int, to int, flags int) (err error) {
-	_, _, e1 := Syscall(SYS_DUP3, uintptr(from), uintptr(to), uintptr(flags))
+	_, _, e1 := syscall_syscall(libc_dup3_trampoline_addr, uintptr(from), uintptr(to), uintptr(flags))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_dup3_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_dup3 dup3 "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Exit(code int) {
-	Syscall(SYS_EXIT, uintptr(code), 0, 0)
+	syscall_syscall(libc_exit_trampoline_addr, uintptr(code), 0, 0)
 	return
 }
 
+var libc_exit_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_exit exit "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
@@ -586,43 +770,59 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_faccessat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_faccessat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_faccessat faccessat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchdir(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
+	_, _, e1 := syscall_syscall(libc_fchdir_trampoline_addr, uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fchdir_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchdir fchdir "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchflags(fd int, flags int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0)
+	_, _, e1 := syscall_syscall(libc_fchflags_trampoline_addr, uintptr(fd), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fchflags_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchflags fchflags "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchmod(fd int, mode uint32) (err error) {
-	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
+	_, _, e1 := syscall_syscall(libc_fchmod_trampoline_addr, uintptr(fd), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fchmod_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchmod fchmod "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
@@ -631,23 +831,31 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_fchmodat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fchmodat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchmodat fchmodat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchown(fd int, uid int, gid int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall_syscall(libc_fchown_trampoline_addr, uintptr(fd), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fchown_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchown fchown "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) {
@@ -656,27 +864,35 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_FCHOWNAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
+	_, _, e1 := syscall_syscall6(libc_fchownat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fchownat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchownat fchownat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Flock(fd int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
+	_, _, e1 := syscall_syscall(libc_flock_trampoline_addr, uintptr(fd), uintptr(how), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_flock_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_flock flock "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fpathconf(fd int, name int) (val int, err error) {
-	r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0)
+	r0, _, e1 := syscall_syscall(libc_fpathconf_trampoline_addr, uintptr(fd), uintptr(name), 0)
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -684,16 +900,24 @@
 	return
 }
 
+var libc_fpathconf_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fpathconf fpathconf "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fstat(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall_syscall(libc_fstat_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fstat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fstat fstat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) {
@@ -702,71 +926,99 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_fstatat_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fstatat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fstatat fstatat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fstatfs(fd int, stat *Statfs_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall_syscall(libc_fstatfs_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fstatfs_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fstatfs fstatfs "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fsync(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
+	_, _, e1 := syscall_syscall(libc_fsync_trampoline_addr, uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fsync_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fsync fsync "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Ftruncate(fd int, length int64) (err error) {
-	_, _, e1 := Syscall6(SYS_FTRUNCATE, uintptr(fd), 0, uintptr(length), uintptr(length>>32), 0, 0)
+	_, _, e1 := syscall_syscall(libc_ftruncate_trampoline_addr, uintptr(fd), uintptr(length), uintptr(length>>32))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_ftruncate_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_ftruncate ftruncate "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getegid() (egid int) {
-	r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getegid_trampoline_addr, 0, 0, 0)
 	egid = int(r0)
 	return
 }
 
+var libc_getegid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getegid getegid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Geteuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_geteuid_trampoline_addr, 0, 0, 0)
 	uid = int(r0)
 	return
 }
 
+var libc_geteuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_geteuid geteuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getgid() (gid int) {
-	r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getgid_trampoline_addr, 0, 0, 0)
 	gid = int(r0)
 	return
 }
 
+var libc_getgid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getgid getgid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpgid(pid int) (pgid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
+	r0, _, e1 := syscall_rawSyscall(libc_getpgid_trampoline_addr, uintptr(pid), 0, 0)
 	pgid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -774,34 +1026,50 @@
 	return
 }
 
+var libc_getpgid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getpgid getpgid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpgrp() (pgrp int) {
-	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getpgrp_trampoline_addr, 0, 0, 0)
 	pgrp = int(r0)
 	return
 }
 
+var libc_getpgrp_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getpgrp getpgrp "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpid() (pid int) {
-	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getpid_trampoline_addr, 0, 0, 0)
 	pid = int(r0)
 	return
 }
 
+var libc_getpid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getpid getpid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getppid() (ppid int) {
-	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getppid_trampoline_addr, 0, 0, 0)
 	ppid = int(r0)
 	return
 }
 
+var libc_getppid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getppid getppid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpriority(which int, who int) (prio int, err error) {
-	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
+	r0, _, e1 := syscall_syscall(libc_getpriority_trampoline_addr, uintptr(which), uintptr(who), 0)
 	prio = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -809,20 +1077,28 @@
 	return
 }
 
+var libc_getpriority_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getpriority getpriority "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	_, _, e1 := syscall_rawSyscall(libc_getrlimit_trampoline_addr, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_getrlimit_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getrlimit getrlimit "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getrtable() (rtable int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETRTABLE, 0, 0, 0)
+	r0, _, e1 := syscall_rawSyscall(libc_getrtable_trampoline_addr, 0, 0, 0)
 	rtable = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -830,20 +1106,28 @@
 	return
 }
 
+var libc_getrtable_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getrtable getrtable "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getrusage(who int, rusage *Rusage) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+	_, _, e1 := syscall_rawSyscall(libc_getrusage_trampoline_addr, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_getrusage_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getrusage getrusage "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getsid(pid int) (sid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0)
+	r0, _, e1 := syscall_rawSyscall(libc_getsid_trampoline_addr, uintptr(pid), 0, 0)
 	sid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -851,46 +1135,66 @@
 	return
 }
 
+var libc_getsid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getsid getsid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Gettimeofday(tv *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_gettimeofday_trampoline_addr, uintptr(unsafe.Pointer(tv)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_gettimeofday_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_gettimeofday gettimeofday "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getuid_trampoline_addr, 0, 0, 0)
 	uid = int(r0)
 	return
 }
 
+var libc_getuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getuid getuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Issetugid() (tainted bool) {
-	r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0)
+	r0, _, _ := syscall_syscall(libc_issetugid_trampoline_addr, 0, 0, 0)
 	tainted = bool(r0 != 0)
 	return
 }
 
+var libc_issetugid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_issetugid issetugid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Kill(pid int, signum syscall.Signal) (err error) {
-	_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), 0)
+	_, _, e1 := syscall_syscall(libc_kill_trampoline_addr, uintptr(pid), uintptr(signum), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_kill_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_kill kill "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Kqueue() (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0)
+	r0, _, e1 := syscall_syscall(libc_kqueue_trampoline_addr, 0, 0, 0)
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -898,6 +1202,10 @@
 	return
 }
 
+var libc_kqueue_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_kqueue kqueue "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Lchown(path string, uid int, gid int) (err error) {
@@ -906,13 +1214,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall_syscall(libc_lchown_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_lchown_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_lchown lchown "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Link(path string, link string) (err error) {
@@ -926,13 +1238,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall_syscall(libc_link_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_link_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_link link "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error) {
@@ -946,23 +1262,31 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_LINKAT, uintptr(pathfd), uintptr(unsafe.Pointer(_p0)), uintptr(linkfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
+	_, _, e1 := syscall_syscall6(libc_linkat_trampoline_addr, uintptr(pathfd), uintptr(unsafe.Pointer(_p0)), uintptr(linkfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_linkat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_linkat linkat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Listen(s int, backlog int) (err error) {
-	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
+	_, _, e1 := syscall_syscall(libc_listen_trampoline_addr, uintptr(s), uintptr(backlog), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_listen_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_listen listen "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Lstat(path string, stat *Stat_t) (err error) {
@@ -971,13 +1295,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall_syscall(libc_lstat_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_lstat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_lstat lstat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mkdir(path string, mode uint32) (err error) {
@@ -986,13 +1314,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall_syscall(libc_mkdir_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mkdir_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mkdir mkdir "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mkdirat(dirfd int, path string, mode uint32) (err error) {
@@ -1001,13 +1333,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_MKDIRAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+	_, _, e1 := syscall_syscall(libc_mkdirat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mkdirat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mkdirat mkdirat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mkfifo(path string, mode uint32) (err error) {
@@ -1016,13 +1352,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall_syscall(libc_mkfifo_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mkfifo_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mkfifo mkfifo "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mkfifoat(dirfd int, path string, mode uint32) (err error) {
@@ -1031,13 +1371,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_MKFIFOAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+	_, _, e1 := syscall_syscall(libc_mkfifoat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mkfifoat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mkfifoat mkfifoat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mknod(path string, mode uint32, dev int) (err error) {
@@ -1046,13 +1390,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
+	_, _, e1 := syscall_syscall(libc_mknod_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mknod_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mknod mknod "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) {
@@ -1061,23 +1409,31 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_MKNODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_mknodat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mknodat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mknodat mknodat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
-	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
+	_, _, e1 := syscall_syscall(libc_nanosleep_trampoline_addr, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_nanosleep_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_nanosleep nanosleep "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Open(path string, mode int, perm uint32) (fd int, err error) {
@@ -1086,7 +1442,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	r0, _, e1 := syscall_syscall(libc_open_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1094,6 +1450,10 @@
 	return
 }
 
+var libc_open_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_open open "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) {
@@ -1102,7 +1462,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0)
+	r0, _, e1 := syscall_syscall6(libc_openat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0)
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1110,6 +1470,10 @@
 	return
 }
 
+var libc_openat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_openat openat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Pathconf(path string, name int) (val int, err error) {
@@ -1118,7 +1482,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
+	r0, _, e1 := syscall_syscall(libc_pathconf_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1126,6 +1490,10 @@
 	return
 }
 
+var libc_pathconf_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_pathconf pathconf "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func pread(fd int, p []byte, offset int64) (n int, err error) {
@@ -1135,7 +1503,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
+	r0, _, e1 := syscall_syscall6(libc_pread_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1143,6 +1511,10 @@
 	return
 }
 
+var libc_pread_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_pread pread "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func pwrite(fd int, p []byte, offset int64) (n int, err error) {
@@ -1152,7 +1524,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
+	r0, _, e1 := syscall_syscall6(libc_pwrite_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1160,6 +1532,10 @@
 	return
 }
 
+var libc_pwrite_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_pwrite pwrite "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func read(fd int, p []byte) (n int, err error) {
@@ -1169,7 +1545,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	r0, _, e1 := syscall_syscall(libc_read_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1177,6 +1553,10 @@
 	return
 }
 
+var libc_read_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_read read "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Readlink(path string, buf []byte) (n int, err error) {
@@ -1191,7 +1571,7 @@
 	} else {
 		_p1 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+	r0, _, e1 := syscall_syscall(libc_readlink_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1199,6 +1579,10 @@
 	return
 }
 
+var libc_readlink_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_readlink readlink "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
@@ -1213,7 +1597,7 @@
 	} else {
 		_p1 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall6(SYS_READLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0)
+	r0, _, e1 := syscall_syscall6(libc_readlinkat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1221,6 +1605,10 @@
 	return
 }
 
+var libc_readlinkat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_readlinkat readlinkat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Rename(from string, to string) (err error) {
@@ -1234,13 +1622,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall_syscall(libc_rename_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_rename_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_rename rename "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Renameat(fromfd int, from string, tofd int, to string) (err error) {
@@ -1254,13 +1646,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_renameat_trampoline_addr, uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_renameat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_renameat renameat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Revoke(path string) (err error) {
@@ -1269,13 +1665,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_revoke_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_revoke_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_revoke revoke "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Rmdir(path string) (err error) {
@@ -1284,17 +1684,21 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_rmdir_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_rmdir_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_rmdir rmdir "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
-	r0, r1, e1 := Syscall6(SYS_LSEEK, uintptr(fd), 0, uintptr(offset), uintptr(offset>>32), uintptr(whence), 0)
+	r0, r1, e1 := syscall_syscall6(libc_lseek_trampoline_addr, uintptr(fd), uintptr(offset), uintptr(offset>>32), uintptr(whence), 0, 0)
 	newoffset = int64(int64(r1)<<32 | int64(r0))
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1302,10 +1706,14 @@
 	return
 }
 
+var libc_lseek_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_lseek lseek "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {
-	r0, _, e1 := Syscall6(SYS_SELECT, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+	r0, _, e1 := syscall_syscall6(libc_select_trampoline_addr, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1313,36 +1721,52 @@
 	return
 }
 
+var libc_select_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_select select "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setegid(egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETEGID, uintptr(egid), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_setegid_trampoline_addr, uintptr(egid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setegid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setegid setegid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Seteuid(euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_seteuid_trampoline_addr, uintptr(euid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_seteuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_seteuid seteuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setgid(gid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_setgid_trampoline_addr, uintptr(gid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setgid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setgid setgid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setlogin(name string) (err error) {
@@ -1351,97 +1775,133 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_setlogin_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setlogin_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setlogin setlogin "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setpgid(pid int, pgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
+	_, _, e1 := syscall_rawSyscall(libc_setpgid_trampoline_addr, uintptr(pid), uintptr(pgid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setpgid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setpgid setpgid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setpriority(which int, who int, prio int) (err error) {
-	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
+	_, _, e1 := syscall_syscall(libc_setpriority_trampoline_addr, uintptr(which), uintptr(who), uintptr(prio))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setpriority_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setpriority setpriority "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
+	_, _, e1 := syscall_rawSyscall(libc_setregid_trampoline_addr, uintptr(rgid), uintptr(egid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setregid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setregid setregid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
+	_, _, e1 := syscall_rawSyscall(libc_setreuid_trampoline_addr, uintptr(ruid), uintptr(euid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setreuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setreuid setreuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setresgid(rgid int, egid int, sgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid))
+	_, _, e1 := syscall_rawSyscall(libc_setresgid_trampoline_addr, uintptr(rgid), uintptr(egid), uintptr(sgid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setresgid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setresgid setresgid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setresuid(ruid int, euid int, suid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid))
+	_, _, e1 := syscall_rawSyscall(libc_setresuid_trampoline_addr, uintptr(ruid), uintptr(euid), uintptr(suid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setresuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setresuid setresuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	_, _, e1 := syscall_rawSyscall(libc_setrlimit_trampoline_addr, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setrlimit_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setrlimit setrlimit "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setrtable(rtable int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRTABLE, uintptr(rtable), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_setrtable_trampoline_addr, uintptr(rtable), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setrtable_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setrtable setrtable "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setsid() (pid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
+	r0, _, e1 := syscall_rawSyscall(libc_setsid_trampoline_addr, 0, 0, 0)
 	pid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1449,26 +1909,38 @@
 	return
 }
 
+var libc_setsid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setsid setsid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Settimeofday(tp *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_settimeofday_trampoline_addr, uintptr(unsafe.Pointer(tp)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_settimeofday_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_settimeofday settimeofday "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setuid(uid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_setuid_trampoline_addr, uintptr(uid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setuid setuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Stat(path string, stat *Stat_t) (err error) {
@@ -1477,13 +1949,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall_syscall(libc_stat_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_stat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_stat stat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Statfs(path string, stat *Statfs_t) (err error) {
@@ -1492,13 +1968,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall_syscall(libc_statfs_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_statfs_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_statfs statfs "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Symlink(path string, link string) (err error) {
@@ -1512,13 +1992,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall_syscall(libc_symlink_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_symlink_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_symlink symlink "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) {
@@ -1532,23 +2016,31 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_SYMLINKAT, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)))
+	_, _, e1 := syscall_syscall(libc_symlinkat_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_symlinkat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_symlinkat symlinkat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Sync() (err error) {
-	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
+	_, _, e1 := syscall_syscall(libc_sync_trampoline_addr, 0, 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_sync_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_sync sync "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Truncate(path string, length int64) (err error) {
@@ -1557,21 +2049,29 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), 0, uintptr(length), uintptr(length>>32), 0, 0)
+	_, _, e1 := syscall_syscall(libc_truncate_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(length), uintptr(length>>32))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_truncate_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_truncate truncate "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Umask(newmask int) (oldmask int) {
-	r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0)
+	r0, _, _ := syscall_syscall(libc_umask_trampoline_addr, uintptr(newmask), 0, 0)
 	oldmask = int(r0)
 	return
 }
 
+var libc_umask_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_umask umask "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Unlink(path string) (err error) {
@@ -1580,13 +2080,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_unlink_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_unlink_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_unlink unlink "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Unlinkat(dirfd int, path string, flags int) (err error) {
@@ -1595,13 +2099,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+	_, _, e1 := syscall_syscall(libc_unlinkat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_unlinkat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_unlinkat unlinkat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Unmount(path string, flags int) (err error) {
@@ -1610,13 +2118,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	_, _, e1 := syscall_syscall(libc_unmount_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_unmount_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_unmount unmount "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func write(fd int, p []byte) (n int, err error) {
@@ -1626,7 +2138,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	r0, _, e1 := syscall_syscall(libc_write_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1634,10 +2146,14 @@
 	return
 }
 
+var libc_write_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_write write "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
-	r0, _, e1 := Syscall9(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), 0, uintptr(pos), uintptr(pos>>32), 0)
+	r0, _, e1 := syscall_syscall9(libc_mmap_trampoline_addr, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos), uintptr(pos>>32), 0, 0)
 	ret = uintptr(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1645,20 +2161,28 @@
 	return
 }
 
+var libc_mmap_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mmap mmap "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func munmap(addr uintptr, length uintptr) (err error) {
-	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
+	_, _, e1 := syscall_syscall(libc_munmap_trampoline_addr, uintptr(addr), uintptr(length), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_munmap_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_munmap munmap "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	r0, _, e1 := syscall_syscall(libc_read_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1669,7 +2193,7 @@
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	r0, _, e1 := syscall_syscall(libc_write_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1685,9 +2209,13 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_utimensat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
+
+var libc_utimensat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_utimensat utimensat "libc.so"
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.s b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.s
new file mode 100644
index 0000000..75eb2f5
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.s
@@ -0,0 +1,796 @@
+// go run mkasm.go openbsd 386
+// Code generated by the command above; DO NOT EDIT.
+
+#include "textflag.h"
+
+TEXT libc_getgroups_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getgroups(SB)
+
+GLOBL	·libc_getgroups_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getgroups_trampoline_addr(SB)/4, $libc_getgroups_trampoline<>(SB)
+
+TEXT libc_setgroups_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setgroups(SB)
+
+GLOBL	·libc_setgroups_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setgroups_trampoline_addr(SB)/4, $libc_setgroups_trampoline<>(SB)
+
+TEXT libc_wait4_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_wait4(SB)
+
+GLOBL	·libc_wait4_trampoline_addr(SB), RODATA, $4
+DATA	·libc_wait4_trampoline_addr(SB)/4, $libc_wait4_trampoline<>(SB)
+
+TEXT libc_accept_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_accept(SB)
+
+GLOBL	·libc_accept_trampoline_addr(SB), RODATA, $4
+DATA	·libc_accept_trampoline_addr(SB)/4, $libc_accept_trampoline<>(SB)
+
+TEXT libc_bind_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_bind(SB)
+
+GLOBL	·libc_bind_trampoline_addr(SB), RODATA, $4
+DATA	·libc_bind_trampoline_addr(SB)/4, $libc_bind_trampoline<>(SB)
+
+TEXT libc_connect_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_connect(SB)
+
+GLOBL	·libc_connect_trampoline_addr(SB), RODATA, $4
+DATA	·libc_connect_trampoline_addr(SB)/4, $libc_connect_trampoline<>(SB)
+
+TEXT libc_socket_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_socket(SB)
+
+GLOBL	·libc_socket_trampoline_addr(SB), RODATA, $4
+DATA	·libc_socket_trampoline_addr(SB)/4, $libc_socket_trampoline<>(SB)
+
+TEXT libc_getsockopt_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getsockopt(SB)
+
+GLOBL	·libc_getsockopt_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getsockopt_trampoline_addr(SB)/4, $libc_getsockopt_trampoline<>(SB)
+
+TEXT libc_setsockopt_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setsockopt(SB)
+
+GLOBL	·libc_setsockopt_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setsockopt_trampoline_addr(SB)/4, $libc_setsockopt_trampoline<>(SB)
+
+TEXT libc_getpeername_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getpeername(SB)
+
+GLOBL	·libc_getpeername_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getpeername_trampoline_addr(SB)/4, $libc_getpeername_trampoline<>(SB)
+
+TEXT libc_getsockname_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getsockname(SB)
+
+GLOBL	·libc_getsockname_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getsockname_trampoline_addr(SB)/4, $libc_getsockname_trampoline<>(SB)
+
+TEXT libc_shutdown_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_shutdown(SB)
+
+GLOBL	·libc_shutdown_trampoline_addr(SB), RODATA, $4
+DATA	·libc_shutdown_trampoline_addr(SB)/4, $libc_shutdown_trampoline<>(SB)
+
+TEXT libc_socketpair_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_socketpair(SB)
+
+GLOBL	·libc_socketpair_trampoline_addr(SB), RODATA, $4
+DATA	·libc_socketpair_trampoline_addr(SB)/4, $libc_socketpair_trampoline<>(SB)
+
+TEXT libc_recvfrom_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_recvfrom(SB)
+
+GLOBL	·libc_recvfrom_trampoline_addr(SB), RODATA, $4
+DATA	·libc_recvfrom_trampoline_addr(SB)/4, $libc_recvfrom_trampoline<>(SB)
+
+TEXT libc_sendto_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_sendto(SB)
+
+GLOBL	·libc_sendto_trampoline_addr(SB), RODATA, $4
+DATA	·libc_sendto_trampoline_addr(SB)/4, $libc_sendto_trampoline<>(SB)
+
+TEXT libc_recvmsg_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_recvmsg(SB)
+
+GLOBL	·libc_recvmsg_trampoline_addr(SB), RODATA, $4
+DATA	·libc_recvmsg_trampoline_addr(SB)/4, $libc_recvmsg_trampoline<>(SB)
+
+TEXT libc_sendmsg_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_sendmsg(SB)
+
+GLOBL	·libc_sendmsg_trampoline_addr(SB), RODATA, $4
+DATA	·libc_sendmsg_trampoline_addr(SB)/4, $libc_sendmsg_trampoline<>(SB)
+
+TEXT libc_kevent_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_kevent(SB)
+
+GLOBL	·libc_kevent_trampoline_addr(SB), RODATA, $4
+DATA	·libc_kevent_trampoline_addr(SB)/4, $libc_kevent_trampoline<>(SB)
+
+TEXT libc_utimes_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_utimes(SB)
+
+GLOBL	·libc_utimes_trampoline_addr(SB), RODATA, $4
+DATA	·libc_utimes_trampoline_addr(SB)/4, $libc_utimes_trampoline<>(SB)
+
+TEXT libc_futimes_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_futimes(SB)
+
+GLOBL	·libc_futimes_trampoline_addr(SB), RODATA, $4
+DATA	·libc_futimes_trampoline_addr(SB)/4, $libc_futimes_trampoline<>(SB)
+
+TEXT libc_poll_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_poll(SB)
+
+GLOBL	·libc_poll_trampoline_addr(SB), RODATA, $4
+DATA	·libc_poll_trampoline_addr(SB)/4, $libc_poll_trampoline<>(SB)
+
+TEXT libc_madvise_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_madvise(SB)
+
+GLOBL	·libc_madvise_trampoline_addr(SB), RODATA, $4
+DATA	·libc_madvise_trampoline_addr(SB)/4, $libc_madvise_trampoline<>(SB)
+
+TEXT libc_mlock_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mlock(SB)
+
+GLOBL	·libc_mlock_trampoline_addr(SB), RODATA, $4
+DATA	·libc_mlock_trampoline_addr(SB)/4, $libc_mlock_trampoline<>(SB)
+
+TEXT libc_mlockall_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mlockall(SB)
+
+GLOBL	·libc_mlockall_trampoline_addr(SB), RODATA, $4
+DATA	·libc_mlockall_trampoline_addr(SB)/4, $libc_mlockall_trampoline<>(SB)
+
+TEXT libc_mprotect_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mprotect(SB)
+
+GLOBL	·libc_mprotect_trampoline_addr(SB), RODATA, $4
+DATA	·libc_mprotect_trampoline_addr(SB)/4, $libc_mprotect_trampoline<>(SB)
+
+TEXT libc_msync_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_msync(SB)
+
+GLOBL	·libc_msync_trampoline_addr(SB), RODATA, $4
+DATA	·libc_msync_trampoline_addr(SB)/4, $libc_msync_trampoline<>(SB)
+
+TEXT libc_munlock_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_munlock(SB)
+
+GLOBL	·libc_munlock_trampoline_addr(SB), RODATA, $4
+DATA	·libc_munlock_trampoline_addr(SB)/4, $libc_munlock_trampoline<>(SB)
+
+TEXT libc_munlockall_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_munlockall(SB)
+
+GLOBL	·libc_munlockall_trampoline_addr(SB), RODATA, $4
+DATA	·libc_munlockall_trampoline_addr(SB)/4, $libc_munlockall_trampoline<>(SB)
+
+TEXT libc_pipe2_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_pipe2(SB)
+
+GLOBL	·libc_pipe2_trampoline_addr(SB), RODATA, $4
+DATA	·libc_pipe2_trampoline_addr(SB)/4, $libc_pipe2_trampoline<>(SB)
+
+TEXT libc_getdents_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getdents(SB)
+
+GLOBL	·libc_getdents_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getdents_trampoline_addr(SB)/4, $libc_getdents_trampoline<>(SB)
+
+TEXT libc_getcwd_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getcwd(SB)
+
+GLOBL	·libc_getcwd_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getcwd_trampoline_addr(SB)/4, $libc_getcwd_trampoline<>(SB)
+
+TEXT libc_ioctl_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_ioctl(SB)
+
+GLOBL	·libc_ioctl_trampoline_addr(SB), RODATA, $4
+DATA	·libc_ioctl_trampoline_addr(SB)/4, $libc_ioctl_trampoline<>(SB)
+
+TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_sysctl(SB)
+
+GLOBL	·libc_sysctl_trampoline_addr(SB), RODATA, $4
+DATA	·libc_sysctl_trampoline_addr(SB)/4, $libc_sysctl_trampoline<>(SB)
+
+TEXT libc_ppoll_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_ppoll(SB)
+
+GLOBL	·libc_ppoll_trampoline_addr(SB), RODATA, $4
+DATA	·libc_ppoll_trampoline_addr(SB)/4, $libc_ppoll_trampoline<>(SB)
+
+TEXT libc_access_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_access(SB)
+
+GLOBL	·libc_access_trampoline_addr(SB), RODATA, $4
+DATA	·libc_access_trampoline_addr(SB)/4, $libc_access_trampoline<>(SB)
+
+TEXT libc_adjtime_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_adjtime(SB)
+
+GLOBL	·libc_adjtime_trampoline_addr(SB), RODATA, $4
+DATA	·libc_adjtime_trampoline_addr(SB)/4, $libc_adjtime_trampoline<>(SB)
+
+TEXT libc_chdir_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_chdir(SB)
+
+GLOBL	·libc_chdir_trampoline_addr(SB), RODATA, $4
+DATA	·libc_chdir_trampoline_addr(SB)/4, $libc_chdir_trampoline<>(SB)
+
+TEXT libc_chflags_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_chflags(SB)
+
+GLOBL	·libc_chflags_trampoline_addr(SB), RODATA, $4
+DATA	·libc_chflags_trampoline_addr(SB)/4, $libc_chflags_trampoline<>(SB)
+
+TEXT libc_chmod_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_chmod(SB)
+
+GLOBL	·libc_chmod_trampoline_addr(SB), RODATA, $4
+DATA	·libc_chmod_trampoline_addr(SB)/4, $libc_chmod_trampoline<>(SB)
+
+TEXT libc_chown_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_chown(SB)
+
+GLOBL	·libc_chown_trampoline_addr(SB), RODATA, $4
+DATA	·libc_chown_trampoline_addr(SB)/4, $libc_chown_trampoline<>(SB)
+
+TEXT libc_chroot_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_chroot(SB)
+
+GLOBL	·libc_chroot_trampoline_addr(SB), RODATA, $4
+DATA	·libc_chroot_trampoline_addr(SB)/4, $libc_chroot_trampoline<>(SB)
+
+TEXT libc_close_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_close(SB)
+
+GLOBL	·libc_close_trampoline_addr(SB), RODATA, $4
+DATA	·libc_close_trampoline_addr(SB)/4, $libc_close_trampoline<>(SB)
+
+TEXT libc_dup_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_dup(SB)
+
+GLOBL	·libc_dup_trampoline_addr(SB), RODATA, $4
+DATA	·libc_dup_trampoline_addr(SB)/4, $libc_dup_trampoline<>(SB)
+
+TEXT libc_dup2_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_dup2(SB)
+
+GLOBL	·libc_dup2_trampoline_addr(SB), RODATA, $4
+DATA	·libc_dup2_trampoline_addr(SB)/4, $libc_dup2_trampoline<>(SB)
+
+TEXT libc_dup3_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_dup3(SB)
+
+GLOBL	·libc_dup3_trampoline_addr(SB), RODATA, $4
+DATA	·libc_dup3_trampoline_addr(SB)/4, $libc_dup3_trampoline<>(SB)
+
+TEXT libc_exit_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_exit(SB)
+
+GLOBL	·libc_exit_trampoline_addr(SB), RODATA, $4
+DATA	·libc_exit_trampoline_addr(SB)/4, $libc_exit_trampoline<>(SB)
+
+TEXT libc_faccessat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_faccessat(SB)
+
+GLOBL	·libc_faccessat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_faccessat_trampoline_addr(SB)/4, $libc_faccessat_trampoline<>(SB)
+
+TEXT libc_fchdir_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fchdir(SB)
+
+GLOBL	·libc_fchdir_trampoline_addr(SB), RODATA, $4
+DATA	·libc_fchdir_trampoline_addr(SB)/4, $libc_fchdir_trampoline<>(SB)
+
+TEXT libc_fchflags_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fchflags(SB)
+
+GLOBL	·libc_fchflags_trampoline_addr(SB), RODATA, $4
+DATA	·libc_fchflags_trampoline_addr(SB)/4, $libc_fchflags_trampoline<>(SB)
+
+TEXT libc_fchmod_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fchmod(SB)
+
+GLOBL	·libc_fchmod_trampoline_addr(SB), RODATA, $4
+DATA	·libc_fchmod_trampoline_addr(SB)/4, $libc_fchmod_trampoline<>(SB)
+
+TEXT libc_fchmodat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fchmodat(SB)
+
+GLOBL	·libc_fchmodat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_fchmodat_trampoline_addr(SB)/4, $libc_fchmodat_trampoline<>(SB)
+
+TEXT libc_fchown_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fchown(SB)
+
+GLOBL	·libc_fchown_trampoline_addr(SB), RODATA, $4
+DATA	·libc_fchown_trampoline_addr(SB)/4, $libc_fchown_trampoline<>(SB)
+
+TEXT libc_fchownat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fchownat(SB)
+
+GLOBL	·libc_fchownat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_fchownat_trampoline_addr(SB)/4, $libc_fchownat_trampoline<>(SB)
+
+TEXT libc_flock_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_flock(SB)
+
+GLOBL	·libc_flock_trampoline_addr(SB), RODATA, $4
+DATA	·libc_flock_trampoline_addr(SB)/4, $libc_flock_trampoline<>(SB)
+
+TEXT libc_fpathconf_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fpathconf(SB)
+
+GLOBL	·libc_fpathconf_trampoline_addr(SB), RODATA, $4
+DATA	·libc_fpathconf_trampoline_addr(SB)/4, $libc_fpathconf_trampoline<>(SB)
+
+TEXT libc_fstat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fstat(SB)
+
+GLOBL	·libc_fstat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_fstat_trampoline_addr(SB)/4, $libc_fstat_trampoline<>(SB)
+
+TEXT libc_fstatat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fstatat(SB)
+
+GLOBL	·libc_fstatat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_fstatat_trampoline_addr(SB)/4, $libc_fstatat_trampoline<>(SB)
+
+TEXT libc_fstatfs_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fstatfs(SB)
+
+GLOBL	·libc_fstatfs_trampoline_addr(SB), RODATA, $4
+DATA	·libc_fstatfs_trampoline_addr(SB)/4, $libc_fstatfs_trampoline<>(SB)
+
+TEXT libc_fsync_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fsync(SB)
+
+GLOBL	·libc_fsync_trampoline_addr(SB), RODATA, $4
+DATA	·libc_fsync_trampoline_addr(SB)/4, $libc_fsync_trampoline<>(SB)
+
+TEXT libc_ftruncate_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_ftruncate(SB)
+
+GLOBL	·libc_ftruncate_trampoline_addr(SB), RODATA, $4
+DATA	·libc_ftruncate_trampoline_addr(SB)/4, $libc_ftruncate_trampoline<>(SB)
+
+TEXT libc_getegid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getegid(SB)
+
+GLOBL	·libc_getegid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getegid_trampoline_addr(SB)/4, $libc_getegid_trampoline<>(SB)
+
+TEXT libc_geteuid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_geteuid(SB)
+
+GLOBL	·libc_geteuid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_geteuid_trampoline_addr(SB)/4, $libc_geteuid_trampoline<>(SB)
+
+TEXT libc_getgid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getgid(SB)
+
+GLOBL	·libc_getgid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getgid_trampoline_addr(SB)/4, $libc_getgid_trampoline<>(SB)
+
+TEXT libc_getpgid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getpgid(SB)
+
+GLOBL	·libc_getpgid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getpgid_trampoline_addr(SB)/4, $libc_getpgid_trampoline<>(SB)
+
+TEXT libc_getpgrp_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getpgrp(SB)
+
+GLOBL	·libc_getpgrp_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getpgrp_trampoline_addr(SB)/4, $libc_getpgrp_trampoline<>(SB)
+
+TEXT libc_getpid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getpid(SB)
+
+GLOBL	·libc_getpid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getpid_trampoline_addr(SB)/4, $libc_getpid_trampoline<>(SB)
+
+TEXT libc_getppid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getppid(SB)
+
+GLOBL	·libc_getppid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getppid_trampoline_addr(SB)/4, $libc_getppid_trampoline<>(SB)
+
+TEXT libc_getpriority_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getpriority(SB)
+
+GLOBL	·libc_getpriority_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getpriority_trampoline_addr(SB)/4, $libc_getpriority_trampoline<>(SB)
+
+TEXT libc_getrlimit_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getrlimit(SB)
+
+GLOBL	·libc_getrlimit_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getrlimit_trampoline_addr(SB)/4, $libc_getrlimit_trampoline<>(SB)
+
+TEXT libc_getrtable_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getrtable(SB)
+
+GLOBL	·libc_getrtable_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getrtable_trampoline_addr(SB)/4, $libc_getrtable_trampoline<>(SB)
+
+TEXT libc_getrusage_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getrusage(SB)
+
+GLOBL	·libc_getrusage_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getrusage_trampoline_addr(SB)/4, $libc_getrusage_trampoline<>(SB)
+
+TEXT libc_getsid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getsid(SB)
+
+GLOBL	·libc_getsid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getsid_trampoline_addr(SB)/4, $libc_getsid_trampoline<>(SB)
+
+TEXT libc_gettimeofday_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_gettimeofday(SB)
+
+GLOBL	·libc_gettimeofday_trampoline_addr(SB), RODATA, $4
+DATA	·libc_gettimeofday_trampoline_addr(SB)/4, $libc_gettimeofday_trampoline<>(SB)
+
+TEXT libc_getuid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getuid(SB)
+
+GLOBL	·libc_getuid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getuid_trampoline_addr(SB)/4, $libc_getuid_trampoline<>(SB)
+
+TEXT libc_issetugid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_issetugid(SB)
+
+GLOBL	·libc_issetugid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_issetugid_trampoline_addr(SB)/4, $libc_issetugid_trampoline<>(SB)
+
+TEXT libc_kill_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_kill(SB)
+
+GLOBL	·libc_kill_trampoline_addr(SB), RODATA, $4
+DATA	·libc_kill_trampoline_addr(SB)/4, $libc_kill_trampoline<>(SB)
+
+TEXT libc_kqueue_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_kqueue(SB)
+
+GLOBL	·libc_kqueue_trampoline_addr(SB), RODATA, $4
+DATA	·libc_kqueue_trampoline_addr(SB)/4, $libc_kqueue_trampoline<>(SB)
+
+TEXT libc_lchown_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_lchown(SB)
+
+GLOBL	·libc_lchown_trampoline_addr(SB), RODATA, $4
+DATA	·libc_lchown_trampoline_addr(SB)/4, $libc_lchown_trampoline<>(SB)
+
+TEXT libc_link_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_link(SB)
+
+GLOBL	·libc_link_trampoline_addr(SB), RODATA, $4
+DATA	·libc_link_trampoline_addr(SB)/4, $libc_link_trampoline<>(SB)
+
+TEXT libc_linkat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_linkat(SB)
+
+GLOBL	·libc_linkat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_linkat_trampoline_addr(SB)/4, $libc_linkat_trampoline<>(SB)
+
+TEXT libc_listen_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_listen(SB)
+
+GLOBL	·libc_listen_trampoline_addr(SB), RODATA, $4
+DATA	·libc_listen_trampoline_addr(SB)/4, $libc_listen_trampoline<>(SB)
+
+TEXT libc_lstat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_lstat(SB)
+
+GLOBL	·libc_lstat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_lstat_trampoline_addr(SB)/4, $libc_lstat_trampoline<>(SB)
+
+TEXT libc_mkdir_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mkdir(SB)
+
+GLOBL	·libc_mkdir_trampoline_addr(SB), RODATA, $4
+DATA	·libc_mkdir_trampoline_addr(SB)/4, $libc_mkdir_trampoline<>(SB)
+
+TEXT libc_mkdirat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mkdirat(SB)
+
+GLOBL	·libc_mkdirat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_mkdirat_trampoline_addr(SB)/4, $libc_mkdirat_trampoline<>(SB)
+
+TEXT libc_mkfifo_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mkfifo(SB)
+
+GLOBL	·libc_mkfifo_trampoline_addr(SB), RODATA, $4
+DATA	·libc_mkfifo_trampoline_addr(SB)/4, $libc_mkfifo_trampoline<>(SB)
+
+TEXT libc_mkfifoat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mkfifoat(SB)
+
+GLOBL	·libc_mkfifoat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_mkfifoat_trampoline_addr(SB)/4, $libc_mkfifoat_trampoline<>(SB)
+
+TEXT libc_mknod_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mknod(SB)
+
+GLOBL	·libc_mknod_trampoline_addr(SB), RODATA, $4
+DATA	·libc_mknod_trampoline_addr(SB)/4, $libc_mknod_trampoline<>(SB)
+
+TEXT libc_mknodat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mknodat(SB)
+
+GLOBL	·libc_mknodat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_mknodat_trampoline_addr(SB)/4, $libc_mknodat_trampoline<>(SB)
+
+TEXT libc_nanosleep_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_nanosleep(SB)
+
+GLOBL	·libc_nanosleep_trampoline_addr(SB), RODATA, $4
+DATA	·libc_nanosleep_trampoline_addr(SB)/4, $libc_nanosleep_trampoline<>(SB)
+
+TEXT libc_open_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_open(SB)
+
+GLOBL	·libc_open_trampoline_addr(SB), RODATA, $4
+DATA	·libc_open_trampoline_addr(SB)/4, $libc_open_trampoline<>(SB)
+
+TEXT libc_openat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_openat(SB)
+
+GLOBL	·libc_openat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_openat_trampoline_addr(SB)/4, $libc_openat_trampoline<>(SB)
+
+TEXT libc_pathconf_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_pathconf(SB)
+
+GLOBL	·libc_pathconf_trampoline_addr(SB), RODATA, $4
+DATA	·libc_pathconf_trampoline_addr(SB)/4, $libc_pathconf_trampoline<>(SB)
+
+TEXT libc_pread_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_pread(SB)
+
+GLOBL	·libc_pread_trampoline_addr(SB), RODATA, $4
+DATA	·libc_pread_trampoline_addr(SB)/4, $libc_pread_trampoline<>(SB)
+
+TEXT libc_pwrite_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_pwrite(SB)
+
+GLOBL	·libc_pwrite_trampoline_addr(SB), RODATA, $4
+DATA	·libc_pwrite_trampoline_addr(SB)/4, $libc_pwrite_trampoline<>(SB)
+
+TEXT libc_read_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_read(SB)
+
+GLOBL	·libc_read_trampoline_addr(SB), RODATA, $4
+DATA	·libc_read_trampoline_addr(SB)/4, $libc_read_trampoline<>(SB)
+
+TEXT libc_readlink_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_readlink(SB)
+
+GLOBL	·libc_readlink_trampoline_addr(SB), RODATA, $4
+DATA	·libc_readlink_trampoline_addr(SB)/4, $libc_readlink_trampoline<>(SB)
+
+TEXT libc_readlinkat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_readlinkat(SB)
+
+GLOBL	·libc_readlinkat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_readlinkat_trampoline_addr(SB)/4, $libc_readlinkat_trampoline<>(SB)
+
+TEXT libc_rename_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_rename(SB)
+
+GLOBL	·libc_rename_trampoline_addr(SB), RODATA, $4
+DATA	·libc_rename_trampoline_addr(SB)/4, $libc_rename_trampoline<>(SB)
+
+TEXT libc_renameat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_renameat(SB)
+
+GLOBL	·libc_renameat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_renameat_trampoline_addr(SB)/4, $libc_renameat_trampoline<>(SB)
+
+TEXT libc_revoke_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_revoke(SB)
+
+GLOBL	·libc_revoke_trampoline_addr(SB), RODATA, $4
+DATA	·libc_revoke_trampoline_addr(SB)/4, $libc_revoke_trampoline<>(SB)
+
+TEXT libc_rmdir_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_rmdir(SB)
+
+GLOBL	·libc_rmdir_trampoline_addr(SB), RODATA, $4
+DATA	·libc_rmdir_trampoline_addr(SB)/4, $libc_rmdir_trampoline<>(SB)
+
+TEXT libc_lseek_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_lseek(SB)
+
+GLOBL	·libc_lseek_trampoline_addr(SB), RODATA, $4
+DATA	·libc_lseek_trampoline_addr(SB)/4, $libc_lseek_trampoline<>(SB)
+
+TEXT libc_select_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_select(SB)
+
+GLOBL	·libc_select_trampoline_addr(SB), RODATA, $4
+DATA	·libc_select_trampoline_addr(SB)/4, $libc_select_trampoline<>(SB)
+
+TEXT libc_setegid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setegid(SB)
+
+GLOBL	·libc_setegid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setegid_trampoline_addr(SB)/4, $libc_setegid_trampoline<>(SB)
+
+TEXT libc_seteuid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_seteuid(SB)
+
+GLOBL	·libc_seteuid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_seteuid_trampoline_addr(SB)/4, $libc_seteuid_trampoline<>(SB)
+
+TEXT libc_setgid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setgid(SB)
+
+GLOBL	·libc_setgid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setgid_trampoline_addr(SB)/4, $libc_setgid_trampoline<>(SB)
+
+TEXT libc_setlogin_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setlogin(SB)
+
+GLOBL	·libc_setlogin_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setlogin_trampoline_addr(SB)/4, $libc_setlogin_trampoline<>(SB)
+
+TEXT libc_setpgid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setpgid(SB)
+
+GLOBL	·libc_setpgid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setpgid_trampoline_addr(SB)/4, $libc_setpgid_trampoline<>(SB)
+
+TEXT libc_setpriority_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setpriority(SB)
+
+GLOBL	·libc_setpriority_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setpriority_trampoline_addr(SB)/4, $libc_setpriority_trampoline<>(SB)
+
+TEXT libc_setregid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setregid(SB)
+
+GLOBL	·libc_setregid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setregid_trampoline_addr(SB)/4, $libc_setregid_trampoline<>(SB)
+
+TEXT libc_setreuid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setreuid(SB)
+
+GLOBL	·libc_setreuid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setreuid_trampoline_addr(SB)/4, $libc_setreuid_trampoline<>(SB)
+
+TEXT libc_setresgid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setresgid(SB)
+
+GLOBL	·libc_setresgid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setresgid_trampoline_addr(SB)/4, $libc_setresgid_trampoline<>(SB)
+
+TEXT libc_setresuid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setresuid(SB)
+
+GLOBL	·libc_setresuid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setresuid_trampoline_addr(SB)/4, $libc_setresuid_trampoline<>(SB)
+
+TEXT libc_setrlimit_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setrlimit(SB)
+
+GLOBL	·libc_setrlimit_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setrlimit_trampoline_addr(SB)/4, $libc_setrlimit_trampoline<>(SB)
+
+TEXT libc_setrtable_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setrtable(SB)
+
+GLOBL	·libc_setrtable_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setrtable_trampoline_addr(SB)/4, $libc_setrtable_trampoline<>(SB)
+
+TEXT libc_setsid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setsid(SB)
+
+GLOBL	·libc_setsid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setsid_trampoline_addr(SB)/4, $libc_setsid_trampoline<>(SB)
+
+TEXT libc_settimeofday_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_settimeofday(SB)
+
+GLOBL	·libc_settimeofday_trampoline_addr(SB), RODATA, $4
+DATA	·libc_settimeofday_trampoline_addr(SB)/4, $libc_settimeofday_trampoline<>(SB)
+
+TEXT libc_setuid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setuid(SB)
+
+GLOBL	·libc_setuid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setuid_trampoline_addr(SB)/4, $libc_setuid_trampoline<>(SB)
+
+TEXT libc_stat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_stat(SB)
+
+GLOBL	·libc_stat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_stat_trampoline_addr(SB)/4, $libc_stat_trampoline<>(SB)
+
+TEXT libc_statfs_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_statfs(SB)
+
+GLOBL	·libc_statfs_trampoline_addr(SB), RODATA, $4
+DATA	·libc_statfs_trampoline_addr(SB)/4, $libc_statfs_trampoline<>(SB)
+
+TEXT libc_symlink_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_symlink(SB)
+
+GLOBL	·libc_symlink_trampoline_addr(SB), RODATA, $4
+DATA	·libc_symlink_trampoline_addr(SB)/4, $libc_symlink_trampoline<>(SB)
+
+TEXT libc_symlinkat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_symlinkat(SB)
+
+GLOBL	·libc_symlinkat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_symlinkat_trampoline_addr(SB)/4, $libc_symlinkat_trampoline<>(SB)
+
+TEXT libc_sync_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_sync(SB)
+
+GLOBL	·libc_sync_trampoline_addr(SB), RODATA, $4
+DATA	·libc_sync_trampoline_addr(SB)/4, $libc_sync_trampoline<>(SB)
+
+TEXT libc_truncate_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_truncate(SB)
+
+GLOBL	·libc_truncate_trampoline_addr(SB), RODATA, $4
+DATA	·libc_truncate_trampoline_addr(SB)/4, $libc_truncate_trampoline<>(SB)
+
+TEXT libc_umask_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_umask(SB)
+
+GLOBL	·libc_umask_trampoline_addr(SB), RODATA, $4
+DATA	·libc_umask_trampoline_addr(SB)/4, $libc_umask_trampoline<>(SB)
+
+TEXT libc_unlink_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_unlink(SB)
+
+GLOBL	·libc_unlink_trampoline_addr(SB), RODATA, $4
+DATA	·libc_unlink_trampoline_addr(SB)/4, $libc_unlink_trampoline<>(SB)
+
+TEXT libc_unlinkat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_unlinkat(SB)
+
+GLOBL	·libc_unlinkat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_unlinkat_trampoline_addr(SB)/4, $libc_unlinkat_trampoline<>(SB)
+
+TEXT libc_unmount_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_unmount(SB)
+
+GLOBL	·libc_unmount_trampoline_addr(SB), RODATA, $4
+DATA	·libc_unmount_trampoline_addr(SB)/4, $libc_unmount_trampoline<>(SB)
+
+TEXT libc_write_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_write(SB)
+
+GLOBL	·libc_write_trampoline_addr(SB), RODATA, $4
+DATA	·libc_write_trampoline_addr(SB)/4, $libc_write_trampoline<>(SB)
+
+TEXT libc_mmap_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mmap(SB)
+
+GLOBL	·libc_mmap_trampoline_addr(SB), RODATA, $4
+DATA	·libc_mmap_trampoline_addr(SB)/4, $libc_mmap_trampoline<>(SB)
+
+TEXT libc_munmap_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_munmap(SB)
+
+GLOBL	·libc_munmap_trampoline_addr(SB), RODATA, $4
+DATA	·libc_munmap_trampoline_addr(SB)/4, $libc_munmap_trampoline<>(SB)
+
+TEXT libc_utimensat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_utimensat(SB)
+
+GLOBL	·libc_utimensat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_utimensat_trampoline_addr(SB)/4, $libc_utimensat_trampoline<>(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go
index 04db8fa..98446d2 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go
@@ -1,4 +1,4 @@
-// go run mksyscall.go -openbsd -tags openbsd,amd64 syscall_bsd.go syscall_openbsd.go syscall_openbsd_amd64.go
+// go run mksyscall.go -openbsd -libc -tags openbsd,amd64 syscall_bsd.go syscall_openbsd.go syscall_openbsd_amd64.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build openbsd && amd64
@@ -16,7 +16,7 @@
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	r0, _, e1 := syscall_rawSyscall(libc_getgroups_trampoline_addr, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -24,20 +24,28 @@
 	return
 }
 
+var libc_getgroups_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getgroups getgroups "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func setgroups(ngid int, gid *_Gid_t) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	_, _, e1 := syscall_rawSyscall(libc_setgroups_trampoline_addr, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setgroups_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setgroups setgroups "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
-	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+	r0, _, e1 := syscall_syscall6(libc_wait4_trampoline_addr, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
 	wpid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -45,10 +53,14 @@
 	return
 }
 
+var libc_wait4_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_wait4 wait4 "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	r0, _, e1 := syscall_syscall(libc_accept_trampoline_addr, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -56,30 +68,42 @@
 	return
 }
 
+var libc_accept_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_accept accept "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
+	_, _, e1 := syscall_syscall(libc_bind_trampoline_addr, uintptr(s), uintptr(addr), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_bind_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_bind bind "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
+	_, _, e1 := syscall_syscall(libc_connect_trampoline_addr, uintptr(s), uintptr(addr), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_connect_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_connect connect "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func socket(domain int, typ int, proto int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
+	r0, _, e1 := syscall_rawSyscall(libc_socket_trampoline_addr, uintptr(domain), uintptr(typ), uintptr(proto))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -87,66 +111,94 @@
 	return
 }
 
+var libc_socket_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_socket socket "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
-	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+	_, _, e1 := syscall_syscall6(libc_getsockopt_trampoline_addr, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_getsockopt_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getsockopt getsockopt "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
-	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+	_, _, e1 := syscall_syscall6(libc_setsockopt_trampoline_addr, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setsockopt_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setsockopt setsockopt "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	_, _, e1 := syscall_rawSyscall(libc_getpeername_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_getpeername_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getpeername getpeername "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	_, _, e1 := syscall_rawSyscall(libc_getsockname_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_getsockname_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getsockname getsockname "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Shutdown(s int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0)
+	_, _, e1 := syscall_syscall(libc_shutdown_trampoline_addr, uintptr(s), uintptr(how), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_shutdown_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_shutdown shutdown "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
-	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+	_, _, e1 := syscall_rawSyscall6(libc_socketpair_trampoline_addr, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_socketpair_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_socketpair socketpair "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
@@ -156,7 +208,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	r0, _, e1 := syscall_syscall6(libc_recvfrom_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -164,6 +216,10 @@
 	return
 }
 
+var libc_recvfrom_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_recvfrom recvfrom "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
@@ -173,17 +229,21 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+	_, _, e1 := syscall_syscall6(libc_sendto_trampoline_addr, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_sendto_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_sendto sendto "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	r0, _, e1 := syscall_syscall(libc_recvmsg_trampoline_addr, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -191,10 +251,14 @@
 	return
 }
 
+var libc_recvmsg_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_recvmsg recvmsg "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	r0, _, e1 := syscall_syscall(libc_sendmsg_trampoline_addr, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -202,10 +266,14 @@
 	return
 }
 
+var libc_sendmsg_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_sendmsg sendmsg "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
-	r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
+	r0, _, e1 := syscall_syscall6(libc_kevent_trampoline_addr, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -213,6 +281,10 @@
 	return
 }
 
+var libc_kevent_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_kevent kevent "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func utimes(path string, timeval *[2]Timeval) (err error) {
@@ -221,27 +293,35 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
+	_, _, e1 := syscall_syscall(libc_utimes_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_utimes_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_utimes utimes "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func futimes(fd int, timeval *[2]Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
+	_, _, e1 := syscall_syscall(libc_futimes_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_futimes_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_futimes futimes "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
+	r0, _, e1 := syscall_syscall(libc_poll_trampoline_addr, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -249,6 +329,10 @@
 	return
 }
 
+var libc_poll_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_poll poll "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Madvise(b []byte, behav int) (err error) {
@@ -258,13 +342,17 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav))
+	_, _, e1 := syscall_syscall(libc_madvise_trampoline_addr, uintptr(_p0), uintptr(len(b)), uintptr(behav))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_madvise_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_madvise madvise "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mlock(b []byte) (err error) {
@@ -274,23 +362,31 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	_, _, e1 := syscall_syscall(libc_mlock_trampoline_addr, uintptr(_p0), uintptr(len(b)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mlock_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mlock mlock "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mlockall(flags int) (err error) {
-	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
+	_, _, e1 := syscall_syscall(libc_mlockall_trampoline_addr, uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mlockall_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mlockall mlockall "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mprotect(b []byte, prot int) (err error) {
@@ -300,13 +396,17 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
+	_, _, e1 := syscall_syscall(libc_mprotect_trampoline_addr, uintptr(_p0), uintptr(len(b)), uintptr(prot))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mprotect_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mprotect mprotect "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Msync(b []byte, flags int) (err error) {
@@ -316,13 +416,17 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	_, _, e1 := syscall_syscall(libc_msync_trampoline_addr, uintptr(_p0), uintptr(len(b)), uintptr(flags))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_msync_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_msync msync "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Munlock(b []byte) (err error) {
@@ -332,33 +436,45 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	_, _, e1 := syscall_syscall(libc_munlock_trampoline_addr, uintptr(_p0), uintptr(len(b)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_munlock_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_munlock munlock "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Munlockall() (err error) {
-	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
+	_, _, e1 := syscall_syscall(libc_munlockall_trampoline_addr, 0, 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_munlockall_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_munlockall munlockall "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func pipe2(p *[2]_C_int, flags int) (err error) {
-	_, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
+	_, _, e1 := syscall_rawSyscall(libc_pipe2_trampoline_addr, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_pipe2_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_pipe2 pipe2 "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getdents(fd int, buf []byte) (n int, err error) {
@@ -368,7 +484,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(SYS_GETDENTS, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+	r0, _, e1 := syscall_syscall(libc_getdents_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -376,6 +492,10 @@
 	return
 }
 
+var libc_getdents_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getdents getdents "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getcwd(buf []byte) (n int, err error) {
@@ -385,7 +505,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(SYS___GETCWD, uintptr(_p0), uintptr(len(buf)), 0)
+	r0, _, e1 := syscall_syscall(libc_getcwd_trampoline_addr, uintptr(_p0), uintptr(len(buf)), 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -393,16 +513,24 @@
 	return
 }
 
+var libc_getcwd_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getcwd getcwd "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func ioctl(fd int, req uint, arg uintptr) (err error) {
-	_, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg))
+	_, _, e1 := syscall_syscall(libc_ioctl_trampoline_addr, uintptr(fd), uintptr(req), uintptr(arg))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_ioctl_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_ioctl ioctl "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
@@ -412,17 +540,21 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
+	_, _, e1 := syscall_syscall6(libc_sysctl_trampoline_addr, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_sysctl_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_sysctl sysctl "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
-	r0, _, e1 := Syscall6(SYS_PPOLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0)
+	r0, _, e1 := syscall_syscall6(libc_ppoll_trampoline_addr, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -430,6 +562,10 @@
 	return
 }
 
+var libc_ppoll_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_ppoll ppoll "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Access(path string, mode uint32) (err error) {
@@ -438,23 +574,31 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall_syscall(libc_access_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_access_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_access access "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
+	_, _, e1 := syscall_syscall(libc_adjtime_trampoline_addr, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_adjtime_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_adjtime adjtime "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Chdir(path string) (err error) {
@@ -463,13 +607,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_chdir_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_chdir_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_chdir chdir "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Chflags(path string, flags int) (err error) {
@@ -478,13 +626,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	_, _, e1 := syscall_syscall(libc_chflags_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_chflags_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_chflags chflags "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Chmod(path string, mode uint32) (err error) {
@@ -493,13 +645,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall_syscall(libc_chmod_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_chmod_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_chmod chmod "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Chown(path string, uid int, gid int) (err error) {
@@ -508,13 +664,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall_syscall(libc_chown_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_chown_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_chown chown "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Chroot(path string) (err error) {
@@ -523,27 +683,35 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_chroot_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_chroot_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_chroot chroot "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Close(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+	_, _, e1 := syscall_syscall(libc_close_trampoline_addr, uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_close_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_close close "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Dup(fd int) (nfd int, err error) {
-	r0, _, e1 := Syscall(SYS_DUP, uintptr(fd), 0, 0)
+	r0, _, e1 := syscall_syscall(libc_dup_trampoline_addr, uintptr(fd), 0, 0)
 	nfd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -551,33 +719,49 @@
 	return
 }
 
+var libc_dup_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_dup dup "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Dup2(from int, to int) (err error) {
-	_, _, e1 := Syscall(SYS_DUP2, uintptr(from), uintptr(to), 0)
+	_, _, e1 := syscall_syscall(libc_dup2_trampoline_addr, uintptr(from), uintptr(to), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_dup2_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_dup2 dup2 "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Dup3(from int, to int, flags int) (err error) {
-	_, _, e1 := Syscall(SYS_DUP3, uintptr(from), uintptr(to), uintptr(flags))
+	_, _, e1 := syscall_syscall(libc_dup3_trampoline_addr, uintptr(from), uintptr(to), uintptr(flags))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_dup3_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_dup3 dup3 "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Exit(code int) {
-	Syscall(SYS_EXIT, uintptr(code), 0, 0)
+	syscall_syscall(libc_exit_trampoline_addr, uintptr(code), 0, 0)
 	return
 }
 
+var libc_exit_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_exit exit "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
@@ -586,43 +770,59 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_faccessat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_faccessat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_faccessat faccessat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchdir(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
+	_, _, e1 := syscall_syscall(libc_fchdir_trampoline_addr, uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fchdir_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchdir fchdir "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchflags(fd int, flags int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0)
+	_, _, e1 := syscall_syscall(libc_fchflags_trampoline_addr, uintptr(fd), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fchflags_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchflags fchflags "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchmod(fd int, mode uint32) (err error) {
-	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
+	_, _, e1 := syscall_syscall(libc_fchmod_trampoline_addr, uintptr(fd), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fchmod_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchmod fchmod "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
@@ -631,23 +831,31 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_fchmodat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fchmodat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchmodat fchmodat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchown(fd int, uid int, gid int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall_syscall(libc_fchown_trampoline_addr, uintptr(fd), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fchown_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchown fchown "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) {
@@ -656,27 +864,35 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_FCHOWNAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
+	_, _, e1 := syscall_syscall6(libc_fchownat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fchownat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchownat fchownat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Flock(fd int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
+	_, _, e1 := syscall_syscall(libc_flock_trampoline_addr, uintptr(fd), uintptr(how), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_flock_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_flock flock "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fpathconf(fd int, name int) (val int, err error) {
-	r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0)
+	r0, _, e1 := syscall_syscall(libc_fpathconf_trampoline_addr, uintptr(fd), uintptr(name), 0)
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -684,16 +900,24 @@
 	return
 }
 
+var libc_fpathconf_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fpathconf fpathconf "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fstat(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall_syscall(libc_fstat_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fstat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fstat fstat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) {
@@ -702,71 +926,99 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_fstatat_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fstatat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fstatat fstatat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fstatfs(fd int, stat *Statfs_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall_syscall(libc_fstatfs_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fstatfs_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fstatfs fstatfs "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fsync(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
+	_, _, e1 := syscall_syscall(libc_fsync_trampoline_addr, uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fsync_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fsync fsync "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Ftruncate(fd int, length int64) (err error) {
-	_, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), 0, uintptr(length))
+	_, _, e1 := syscall_syscall(libc_ftruncate_trampoline_addr, uintptr(fd), uintptr(length), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_ftruncate_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_ftruncate ftruncate "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getegid() (egid int) {
-	r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getegid_trampoline_addr, 0, 0, 0)
 	egid = int(r0)
 	return
 }
 
+var libc_getegid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getegid getegid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Geteuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_geteuid_trampoline_addr, 0, 0, 0)
 	uid = int(r0)
 	return
 }
 
+var libc_geteuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_geteuid geteuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getgid() (gid int) {
-	r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getgid_trampoline_addr, 0, 0, 0)
 	gid = int(r0)
 	return
 }
 
+var libc_getgid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getgid getgid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpgid(pid int) (pgid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
+	r0, _, e1 := syscall_rawSyscall(libc_getpgid_trampoline_addr, uintptr(pid), 0, 0)
 	pgid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -774,34 +1026,50 @@
 	return
 }
 
+var libc_getpgid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getpgid getpgid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpgrp() (pgrp int) {
-	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getpgrp_trampoline_addr, 0, 0, 0)
 	pgrp = int(r0)
 	return
 }
 
+var libc_getpgrp_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getpgrp getpgrp "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpid() (pid int) {
-	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getpid_trampoline_addr, 0, 0, 0)
 	pid = int(r0)
 	return
 }
 
+var libc_getpid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getpid getpid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getppid() (ppid int) {
-	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getppid_trampoline_addr, 0, 0, 0)
 	ppid = int(r0)
 	return
 }
 
+var libc_getppid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getppid getppid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpriority(which int, who int) (prio int, err error) {
-	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
+	r0, _, e1 := syscall_syscall(libc_getpriority_trampoline_addr, uintptr(which), uintptr(who), 0)
 	prio = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -809,20 +1077,28 @@
 	return
 }
 
+var libc_getpriority_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getpriority getpriority "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	_, _, e1 := syscall_rawSyscall(libc_getrlimit_trampoline_addr, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_getrlimit_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getrlimit getrlimit "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getrtable() (rtable int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETRTABLE, 0, 0, 0)
+	r0, _, e1 := syscall_rawSyscall(libc_getrtable_trampoline_addr, 0, 0, 0)
 	rtable = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -830,20 +1106,28 @@
 	return
 }
 
+var libc_getrtable_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getrtable getrtable "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getrusage(who int, rusage *Rusage) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+	_, _, e1 := syscall_rawSyscall(libc_getrusage_trampoline_addr, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_getrusage_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getrusage getrusage "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getsid(pid int) (sid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0)
+	r0, _, e1 := syscall_rawSyscall(libc_getsid_trampoline_addr, uintptr(pid), 0, 0)
 	sid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -851,46 +1135,66 @@
 	return
 }
 
+var libc_getsid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getsid getsid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Gettimeofday(tv *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_gettimeofday_trampoline_addr, uintptr(unsafe.Pointer(tv)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_gettimeofday_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_gettimeofday gettimeofday "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getuid_trampoline_addr, 0, 0, 0)
 	uid = int(r0)
 	return
 }
 
+var libc_getuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getuid getuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Issetugid() (tainted bool) {
-	r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0)
+	r0, _, _ := syscall_syscall(libc_issetugid_trampoline_addr, 0, 0, 0)
 	tainted = bool(r0 != 0)
 	return
 }
 
+var libc_issetugid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_issetugid issetugid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Kill(pid int, signum syscall.Signal) (err error) {
-	_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), 0)
+	_, _, e1 := syscall_syscall(libc_kill_trampoline_addr, uintptr(pid), uintptr(signum), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_kill_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_kill kill "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Kqueue() (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0)
+	r0, _, e1 := syscall_syscall(libc_kqueue_trampoline_addr, 0, 0, 0)
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -898,6 +1202,10 @@
 	return
 }
 
+var libc_kqueue_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_kqueue kqueue "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Lchown(path string, uid int, gid int) (err error) {
@@ -906,13 +1214,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall_syscall(libc_lchown_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_lchown_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_lchown lchown "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Link(path string, link string) (err error) {
@@ -926,13 +1238,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall_syscall(libc_link_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_link_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_link link "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error) {
@@ -946,23 +1262,31 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_LINKAT, uintptr(pathfd), uintptr(unsafe.Pointer(_p0)), uintptr(linkfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
+	_, _, e1 := syscall_syscall6(libc_linkat_trampoline_addr, uintptr(pathfd), uintptr(unsafe.Pointer(_p0)), uintptr(linkfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_linkat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_linkat linkat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Listen(s int, backlog int) (err error) {
-	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
+	_, _, e1 := syscall_syscall(libc_listen_trampoline_addr, uintptr(s), uintptr(backlog), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_listen_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_listen listen "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Lstat(path string, stat *Stat_t) (err error) {
@@ -971,13 +1295,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall_syscall(libc_lstat_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_lstat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_lstat lstat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mkdir(path string, mode uint32) (err error) {
@@ -986,13 +1314,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall_syscall(libc_mkdir_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mkdir_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mkdir mkdir "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mkdirat(dirfd int, path string, mode uint32) (err error) {
@@ -1001,13 +1333,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_MKDIRAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+	_, _, e1 := syscall_syscall(libc_mkdirat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mkdirat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mkdirat mkdirat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mkfifo(path string, mode uint32) (err error) {
@@ -1016,13 +1352,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall_syscall(libc_mkfifo_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mkfifo_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mkfifo mkfifo "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mkfifoat(dirfd int, path string, mode uint32) (err error) {
@@ -1031,13 +1371,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_MKFIFOAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+	_, _, e1 := syscall_syscall(libc_mkfifoat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mkfifoat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mkfifoat mkfifoat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mknod(path string, mode uint32, dev int) (err error) {
@@ -1046,13 +1390,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
+	_, _, e1 := syscall_syscall(libc_mknod_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mknod_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mknod mknod "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) {
@@ -1061,23 +1409,31 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_MKNODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_mknodat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mknodat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mknodat mknodat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
-	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
+	_, _, e1 := syscall_syscall(libc_nanosleep_trampoline_addr, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_nanosleep_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_nanosleep nanosleep "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Open(path string, mode int, perm uint32) (fd int, err error) {
@@ -1086,7 +1442,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	r0, _, e1 := syscall_syscall(libc_open_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1094,6 +1450,10 @@
 	return
 }
 
+var libc_open_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_open open "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) {
@@ -1102,7 +1462,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0)
+	r0, _, e1 := syscall_syscall6(libc_openat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0)
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1110,6 +1470,10 @@
 	return
 }
 
+var libc_openat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_openat openat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Pathconf(path string, name int) (val int, err error) {
@@ -1118,7 +1482,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
+	r0, _, e1 := syscall_syscall(libc_pathconf_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1126,6 +1490,10 @@
 	return
 }
 
+var libc_pathconf_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_pathconf pathconf "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func pread(fd int, p []byte, offset int64) (n int, err error) {
@@ -1135,7 +1503,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), 0)
+	r0, _, e1 := syscall_syscall6(libc_pread_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1143,6 +1511,10 @@
 	return
 }
 
+var libc_pread_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_pread pread "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func pwrite(fd int, p []byte, offset int64) (n int, err error) {
@@ -1152,7 +1524,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), 0)
+	r0, _, e1 := syscall_syscall6(libc_pwrite_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1160,6 +1532,10 @@
 	return
 }
 
+var libc_pwrite_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_pwrite pwrite "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func read(fd int, p []byte) (n int, err error) {
@@ -1169,7 +1545,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	r0, _, e1 := syscall_syscall(libc_read_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1177,6 +1553,10 @@
 	return
 }
 
+var libc_read_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_read read "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Readlink(path string, buf []byte) (n int, err error) {
@@ -1191,7 +1571,7 @@
 	} else {
 		_p1 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+	r0, _, e1 := syscall_syscall(libc_readlink_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1199,6 +1579,10 @@
 	return
 }
 
+var libc_readlink_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_readlink readlink "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
@@ -1213,7 +1597,7 @@
 	} else {
 		_p1 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall6(SYS_READLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0)
+	r0, _, e1 := syscall_syscall6(libc_readlinkat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1221,6 +1605,10 @@
 	return
 }
 
+var libc_readlinkat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_readlinkat readlinkat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Rename(from string, to string) (err error) {
@@ -1234,13 +1622,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall_syscall(libc_rename_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_rename_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_rename rename "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Renameat(fromfd int, from string, tofd int, to string) (err error) {
@@ -1254,13 +1646,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_renameat_trampoline_addr, uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_renameat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_renameat renameat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Revoke(path string) (err error) {
@@ -1269,13 +1665,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_revoke_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_revoke_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_revoke revoke "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Rmdir(path string) (err error) {
@@ -1284,17 +1684,21 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_rmdir_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_rmdir_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_rmdir rmdir "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
-	r0, _, e1 := Syscall6(SYS_LSEEK, uintptr(fd), 0, uintptr(offset), uintptr(whence), 0, 0)
+	r0, _, e1 := syscall_syscall(libc_lseek_trampoline_addr, uintptr(fd), uintptr(offset), uintptr(whence))
 	newoffset = int64(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1302,10 +1706,14 @@
 	return
 }
 
+var libc_lseek_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_lseek lseek "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {
-	r0, _, e1 := Syscall6(SYS_SELECT, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+	r0, _, e1 := syscall_syscall6(libc_select_trampoline_addr, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1313,36 +1721,52 @@
 	return
 }
 
+var libc_select_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_select select "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setegid(egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETEGID, uintptr(egid), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_setegid_trampoline_addr, uintptr(egid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setegid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setegid setegid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Seteuid(euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_seteuid_trampoline_addr, uintptr(euid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_seteuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_seteuid seteuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setgid(gid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_setgid_trampoline_addr, uintptr(gid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setgid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setgid setgid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setlogin(name string) (err error) {
@@ -1351,97 +1775,133 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_setlogin_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setlogin_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setlogin setlogin "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setpgid(pid int, pgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
+	_, _, e1 := syscall_rawSyscall(libc_setpgid_trampoline_addr, uintptr(pid), uintptr(pgid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setpgid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setpgid setpgid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setpriority(which int, who int, prio int) (err error) {
-	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
+	_, _, e1 := syscall_syscall(libc_setpriority_trampoline_addr, uintptr(which), uintptr(who), uintptr(prio))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setpriority_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setpriority setpriority "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
+	_, _, e1 := syscall_rawSyscall(libc_setregid_trampoline_addr, uintptr(rgid), uintptr(egid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setregid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setregid setregid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
+	_, _, e1 := syscall_rawSyscall(libc_setreuid_trampoline_addr, uintptr(ruid), uintptr(euid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setreuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setreuid setreuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setresgid(rgid int, egid int, sgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid))
+	_, _, e1 := syscall_rawSyscall(libc_setresgid_trampoline_addr, uintptr(rgid), uintptr(egid), uintptr(sgid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setresgid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setresgid setresgid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setresuid(ruid int, euid int, suid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid))
+	_, _, e1 := syscall_rawSyscall(libc_setresuid_trampoline_addr, uintptr(ruid), uintptr(euid), uintptr(suid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setresuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setresuid setresuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	_, _, e1 := syscall_rawSyscall(libc_setrlimit_trampoline_addr, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setrlimit_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setrlimit setrlimit "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setrtable(rtable int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRTABLE, uintptr(rtable), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_setrtable_trampoline_addr, uintptr(rtable), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setrtable_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setrtable setrtable "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setsid() (pid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
+	r0, _, e1 := syscall_rawSyscall(libc_setsid_trampoline_addr, 0, 0, 0)
 	pid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1449,26 +1909,38 @@
 	return
 }
 
+var libc_setsid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setsid setsid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Settimeofday(tp *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_settimeofday_trampoline_addr, uintptr(unsafe.Pointer(tp)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_settimeofday_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_settimeofday settimeofday "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setuid(uid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_setuid_trampoline_addr, uintptr(uid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setuid setuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Stat(path string, stat *Stat_t) (err error) {
@@ -1477,13 +1949,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall_syscall(libc_stat_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_stat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_stat stat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Statfs(path string, stat *Statfs_t) (err error) {
@@ -1492,13 +1968,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall_syscall(libc_statfs_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_statfs_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_statfs statfs "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Symlink(path string, link string) (err error) {
@@ -1512,13 +1992,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall_syscall(libc_symlink_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_symlink_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_symlink symlink "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) {
@@ -1532,23 +2016,31 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_SYMLINKAT, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)))
+	_, _, e1 := syscall_syscall(libc_symlinkat_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_symlinkat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_symlinkat symlinkat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Sync() (err error) {
-	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
+	_, _, e1 := syscall_syscall(libc_sync_trampoline_addr, 0, 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_sync_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_sync sync "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Truncate(path string, length int64) (err error) {
@@ -1557,21 +2049,29 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), 0, uintptr(length))
+	_, _, e1 := syscall_syscall(libc_truncate_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(length), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_truncate_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_truncate truncate "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Umask(newmask int) (oldmask int) {
-	r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0)
+	r0, _, _ := syscall_syscall(libc_umask_trampoline_addr, uintptr(newmask), 0, 0)
 	oldmask = int(r0)
 	return
 }
 
+var libc_umask_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_umask umask "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Unlink(path string) (err error) {
@@ -1580,13 +2080,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_unlink_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_unlink_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_unlink unlink "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Unlinkat(dirfd int, path string, flags int) (err error) {
@@ -1595,13 +2099,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+	_, _, e1 := syscall_syscall(libc_unlinkat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_unlinkat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_unlinkat unlinkat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Unmount(path string, flags int) (err error) {
@@ -1610,13 +2118,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	_, _, e1 := syscall_syscall(libc_unmount_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_unmount_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_unmount unmount "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func write(fd int, p []byte) (n int, err error) {
@@ -1626,7 +2138,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	r0, _, e1 := syscall_syscall(libc_write_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1634,10 +2146,14 @@
 	return
 }
 
+var libc_write_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_write write "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
-	r0, _, e1 := Syscall9(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), 0, uintptr(pos), 0, 0)
+	r0, _, e1 := syscall_syscall6(libc_mmap_trampoline_addr, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos))
 	ret = uintptr(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1645,20 +2161,28 @@
 	return
 }
 
+var libc_mmap_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mmap mmap "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func munmap(addr uintptr, length uintptr) (err error) {
-	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
+	_, _, e1 := syscall_syscall(libc_munmap_trampoline_addr, uintptr(addr), uintptr(length), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_munmap_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_munmap munmap "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	r0, _, e1 := syscall_syscall(libc_read_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1669,7 +2193,7 @@
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	r0, _, e1 := syscall_syscall(libc_write_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1685,9 +2209,13 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_utimensat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
+
+var libc_utimensat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_utimensat utimensat "libc.so"
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.s b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.s
new file mode 100644
index 0000000..243a666
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.s
@@ -0,0 +1,796 @@
+// go run mkasm.go openbsd amd64
+// Code generated by the command above; DO NOT EDIT.
+
+#include "textflag.h"
+
+TEXT libc_getgroups_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getgroups(SB)
+
+GLOBL	·libc_getgroups_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getgroups_trampoline_addr(SB)/8, $libc_getgroups_trampoline<>(SB)
+
+TEXT libc_setgroups_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setgroups(SB)
+
+GLOBL	·libc_setgroups_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setgroups_trampoline_addr(SB)/8, $libc_setgroups_trampoline<>(SB)
+
+TEXT libc_wait4_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_wait4(SB)
+
+GLOBL	·libc_wait4_trampoline_addr(SB), RODATA, $8
+DATA	·libc_wait4_trampoline_addr(SB)/8, $libc_wait4_trampoline<>(SB)
+
+TEXT libc_accept_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_accept(SB)
+
+GLOBL	·libc_accept_trampoline_addr(SB), RODATA, $8
+DATA	·libc_accept_trampoline_addr(SB)/8, $libc_accept_trampoline<>(SB)
+
+TEXT libc_bind_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_bind(SB)
+
+GLOBL	·libc_bind_trampoline_addr(SB), RODATA, $8
+DATA	·libc_bind_trampoline_addr(SB)/8, $libc_bind_trampoline<>(SB)
+
+TEXT libc_connect_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_connect(SB)
+
+GLOBL	·libc_connect_trampoline_addr(SB), RODATA, $8
+DATA	·libc_connect_trampoline_addr(SB)/8, $libc_connect_trampoline<>(SB)
+
+TEXT libc_socket_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_socket(SB)
+
+GLOBL	·libc_socket_trampoline_addr(SB), RODATA, $8
+DATA	·libc_socket_trampoline_addr(SB)/8, $libc_socket_trampoline<>(SB)
+
+TEXT libc_getsockopt_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getsockopt(SB)
+
+GLOBL	·libc_getsockopt_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getsockopt_trampoline_addr(SB)/8, $libc_getsockopt_trampoline<>(SB)
+
+TEXT libc_setsockopt_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setsockopt(SB)
+
+GLOBL	·libc_setsockopt_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setsockopt_trampoline_addr(SB)/8, $libc_setsockopt_trampoline<>(SB)
+
+TEXT libc_getpeername_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getpeername(SB)
+
+GLOBL	·libc_getpeername_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getpeername_trampoline_addr(SB)/8, $libc_getpeername_trampoline<>(SB)
+
+TEXT libc_getsockname_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getsockname(SB)
+
+GLOBL	·libc_getsockname_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getsockname_trampoline_addr(SB)/8, $libc_getsockname_trampoline<>(SB)
+
+TEXT libc_shutdown_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_shutdown(SB)
+
+GLOBL	·libc_shutdown_trampoline_addr(SB), RODATA, $8
+DATA	·libc_shutdown_trampoline_addr(SB)/8, $libc_shutdown_trampoline<>(SB)
+
+TEXT libc_socketpair_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_socketpair(SB)
+
+GLOBL	·libc_socketpair_trampoline_addr(SB), RODATA, $8
+DATA	·libc_socketpair_trampoline_addr(SB)/8, $libc_socketpair_trampoline<>(SB)
+
+TEXT libc_recvfrom_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_recvfrom(SB)
+
+GLOBL	·libc_recvfrom_trampoline_addr(SB), RODATA, $8
+DATA	·libc_recvfrom_trampoline_addr(SB)/8, $libc_recvfrom_trampoline<>(SB)
+
+TEXT libc_sendto_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_sendto(SB)
+
+GLOBL	·libc_sendto_trampoline_addr(SB), RODATA, $8
+DATA	·libc_sendto_trampoline_addr(SB)/8, $libc_sendto_trampoline<>(SB)
+
+TEXT libc_recvmsg_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_recvmsg(SB)
+
+GLOBL	·libc_recvmsg_trampoline_addr(SB), RODATA, $8
+DATA	·libc_recvmsg_trampoline_addr(SB)/8, $libc_recvmsg_trampoline<>(SB)
+
+TEXT libc_sendmsg_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_sendmsg(SB)
+
+GLOBL	·libc_sendmsg_trampoline_addr(SB), RODATA, $8
+DATA	·libc_sendmsg_trampoline_addr(SB)/8, $libc_sendmsg_trampoline<>(SB)
+
+TEXT libc_kevent_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_kevent(SB)
+
+GLOBL	·libc_kevent_trampoline_addr(SB), RODATA, $8
+DATA	·libc_kevent_trampoline_addr(SB)/8, $libc_kevent_trampoline<>(SB)
+
+TEXT libc_utimes_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_utimes(SB)
+
+GLOBL	·libc_utimes_trampoline_addr(SB), RODATA, $8
+DATA	·libc_utimes_trampoline_addr(SB)/8, $libc_utimes_trampoline<>(SB)
+
+TEXT libc_futimes_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_futimes(SB)
+
+GLOBL	·libc_futimes_trampoline_addr(SB), RODATA, $8
+DATA	·libc_futimes_trampoline_addr(SB)/8, $libc_futimes_trampoline<>(SB)
+
+TEXT libc_poll_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_poll(SB)
+
+GLOBL	·libc_poll_trampoline_addr(SB), RODATA, $8
+DATA	·libc_poll_trampoline_addr(SB)/8, $libc_poll_trampoline<>(SB)
+
+TEXT libc_madvise_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_madvise(SB)
+
+GLOBL	·libc_madvise_trampoline_addr(SB), RODATA, $8
+DATA	·libc_madvise_trampoline_addr(SB)/8, $libc_madvise_trampoline<>(SB)
+
+TEXT libc_mlock_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mlock(SB)
+
+GLOBL	·libc_mlock_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mlock_trampoline_addr(SB)/8, $libc_mlock_trampoline<>(SB)
+
+TEXT libc_mlockall_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mlockall(SB)
+
+GLOBL	·libc_mlockall_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mlockall_trampoline_addr(SB)/8, $libc_mlockall_trampoline<>(SB)
+
+TEXT libc_mprotect_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mprotect(SB)
+
+GLOBL	·libc_mprotect_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mprotect_trampoline_addr(SB)/8, $libc_mprotect_trampoline<>(SB)
+
+TEXT libc_msync_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_msync(SB)
+
+GLOBL	·libc_msync_trampoline_addr(SB), RODATA, $8
+DATA	·libc_msync_trampoline_addr(SB)/8, $libc_msync_trampoline<>(SB)
+
+TEXT libc_munlock_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_munlock(SB)
+
+GLOBL	·libc_munlock_trampoline_addr(SB), RODATA, $8
+DATA	·libc_munlock_trampoline_addr(SB)/8, $libc_munlock_trampoline<>(SB)
+
+TEXT libc_munlockall_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_munlockall(SB)
+
+GLOBL	·libc_munlockall_trampoline_addr(SB), RODATA, $8
+DATA	·libc_munlockall_trampoline_addr(SB)/8, $libc_munlockall_trampoline<>(SB)
+
+TEXT libc_pipe2_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_pipe2(SB)
+
+GLOBL	·libc_pipe2_trampoline_addr(SB), RODATA, $8
+DATA	·libc_pipe2_trampoline_addr(SB)/8, $libc_pipe2_trampoline<>(SB)
+
+TEXT libc_getdents_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getdents(SB)
+
+GLOBL	·libc_getdents_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getdents_trampoline_addr(SB)/8, $libc_getdents_trampoline<>(SB)
+
+TEXT libc_getcwd_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getcwd(SB)
+
+GLOBL	·libc_getcwd_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getcwd_trampoline_addr(SB)/8, $libc_getcwd_trampoline<>(SB)
+
+TEXT libc_ioctl_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_ioctl(SB)
+
+GLOBL	·libc_ioctl_trampoline_addr(SB), RODATA, $8
+DATA	·libc_ioctl_trampoline_addr(SB)/8, $libc_ioctl_trampoline<>(SB)
+
+TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_sysctl(SB)
+
+GLOBL	·libc_sysctl_trampoline_addr(SB), RODATA, $8
+DATA	·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB)
+
+TEXT libc_ppoll_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_ppoll(SB)
+
+GLOBL	·libc_ppoll_trampoline_addr(SB), RODATA, $8
+DATA	·libc_ppoll_trampoline_addr(SB)/8, $libc_ppoll_trampoline<>(SB)
+
+TEXT libc_access_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_access(SB)
+
+GLOBL	·libc_access_trampoline_addr(SB), RODATA, $8
+DATA	·libc_access_trampoline_addr(SB)/8, $libc_access_trampoline<>(SB)
+
+TEXT libc_adjtime_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_adjtime(SB)
+
+GLOBL	·libc_adjtime_trampoline_addr(SB), RODATA, $8
+DATA	·libc_adjtime_trampoline_addr(SB)/8, $libc_adjtime_trampoline<>(SB)
+
+TEXT libc_chdir_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_chdir(SB)
+
+GLOBL	·libc_chdir_trampoline_addr(SB), RODATA, $8
+DATA	·libc_chdir_trampoline_addr(SB)/8, $libc_chdir_trampoline<>(SB)
+
+TEXT libc_chflags_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_chflags(SB)
+
+GLOBL	·libc_chflags_trampoline_addr(SB), RODATA, $8
+DATA	·libc_chflags_trampoline_addr(SB)/8, $libc_chflags_trampoline<>(SB)
+
+TEXT libc_chmod_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_chmod(SB)
+
+GLOBL	·libc_chmod_trampoline_addr(SB), RODATA, $8
+DATA	·libc_chmod_trampoline_addr(SB)/8, $libc_chmod_trampoline<>(SB)
+
+TEXT libc_chown_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_chown(SB)
+
+GLOBL	·libc_chown_trampoline_addr(SB), RODATA, $8
+DATA	·libc_chown_trampoline_addr(SB)/8, $libc_chown_trampoline<>(SB)
+
+TEXT libc_chroot_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_chroot(SB)
+
+GLOBL	·libc_chroot_trampoline_addr(SB), RODATA, $8
+DATA	·libc_chroot_trampoline_addr(SB)/8, $libc_chroot_trampoline<>(SB)
+
+TEXT libc_close_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_close(SB)
+
+GLOBL	·libc_close_trampoline_addr(SB), RODATA, $8
+DATA	·libc_close_trampoline_addr(SB)/8, $libc_close_trampoline<>(SB)
+
+TEXT libc_dup_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_dup(SB)
+
+GLOBL	·libc_dup_trampoline_addr(SB), RODATA, $8
+DATA	·libc_dup_trampoline_addr(SB)/8, $libc_dup_trampoline<>(SB)
+
+TEXT libc_dup2_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_dup2(SB)
+
+GLOBL	·libc_dup2_trampoline_addr(SB), RODATA, $8
+DATA	·libc_dup2_trampoline_addr(SB)/8, $libc_dup2_trampoline<>(SB)
+
+TEXT libc_dup3_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_dup3(SB)
+
+GLOBL	·libc_dup3_trampoline_addr(SB), RODATA, $8
+DATA	·libc_dup3_trampoline_addr(SB)/8, $libc_dup3_trampoline<>(SB)
+
+TEXT libc_exit_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_exit(SB)
+
+GLOBL	·libc_exit_trampoline_addr(SB), RODATA, $8
+DATA	·libc_exit_trampoline_addr(SB)/8, $libc_exit_trampoline<>(SB)
+
+TEXT libc_faccessat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_faccessat(SB)
+
+GLOBL	·libc_faccessat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_faccessat_trampoline_addr(SB)/8, $libc_faccessat_trampoline<>(SB)
+
+TEXT libc_fchdir_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fchdir(SB)
+
+GLOBL	·libc_fchdir_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fchdir_trampoline_addr(SB)/8, $libc_fchdir_trampoline<>(SB)
+
+TEXT libc_fchflags_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fchflags(SB)
+
+GLOBL	·libc_fchflags_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fchflags_trampoline_addr(SB)/8, $libc_fchflags_trampoline<>(SB)
+
+TEXT libc_fchmod_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fchmod(SB)
+
+GLOBL	·libc_fchmod_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fchmod_trampoline_addr(SB)/8, $libc_fchmod_trampoline<>(SB)
+
+TEXT libc_fchmodat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fchmodat(SB)
+
+GLOBL	·libc_fchmodat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fchmodat_trampoline_addr(SB)/8, $libc_fchmodat_trampoline<>(SB)
+
+TEXT libc_fchown_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fchown(SB)
+
+GLOBL	·libc_fchown_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fchown_trampoline_addr(SB)/8, $libc_fchown_trampoline<>(SB)
+
+TEXT libc_fchownat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fchownat(SB)
+
+GLOBL	·libc_fchownat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fchownat_trampoline_addr(SB)/8, $libc_fchownat_trampoline<>(SB)
+
+TEXT libc_flock_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_flock(SB)
+
+GLOBL	·libc_flock_trampoline_addr(SB), RODATA, $8
+DATA	·libc_flock_trampoline_addr(SB)/8, $libc_flock_trampoline<>(SB)
+
+TEXT libc_fpathconf_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fpathconf(SB)
+
+GLOBL	·libc_fpathconf_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fpathconf_trampoline_addr(SB)/8, $libc_fpathconf_trampoline<>(SB)
+
+TEXT libc_fstat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fstat(SB)
+
+GLOBL	·libc_fstat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fstat_trampoline_addr(SB)/8, $libc_fstat_trampoline<>(SB)
+
+TEXT libc_fstatat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fstatat(SB)
+
+GLOBL	·libc_fstatat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fstatat_trampoline_addr(SB)/8, $libc_fstatat_trampoline<>(SB)
+
+TEXT libc_fstatfs_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fstatfs(SB)
+
+GLOBL	·libc_fstatfs_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fstatfs_trampoline_addr(SB)/8, $libc_fstatfs_trampoline<>(SB)
+
+TEXT libc_fsync_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fsync(SB)
+
+GLOBL	·libc_fsync_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fsync_trampoline_addr(SB)/8, $libc_fsync_trampoline<>(SB)
+
+TEXT libc_ftruncate_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_ftruncate(SB)
+
+GLOBL	·libc_ftruncate_trampoline_addr(SB), RODATA, $8
+DATA	·libc_ftruncate_trampoline_addr(SB)/8, $libc_ftruncate_trampoline<>(SB)
+
+TEXT libc_getegid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getegid(SB)
+
+GLOBL	·libc_getegid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getegid_trampoline_addr(SB)/8, $libc_getegid_trampoline<>(SB)
+
+TEXT libc_geteuid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_geteuid(SB)
+
+GLOBL	·libc_geteuid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_geteuid_trampoline_addr(SB)/8, $libc_geteuid_trampoline<>(SB)
+
+TEXT libc_getgid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getgid(SB)
+
+GLOBL	·libc_getgid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getgid_trampoline_addr(SB)/8, $libc_getgid_trampoline<>(SB)
+
+TEXT libc_getpgid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getpgid(SB)
+
+GLOBL	·libc_getpgid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getpgid_trampoline_addr(SB)/8, $libc_getpgid_trampoline<>(SB)
+
+TEXT libc_getpgrp_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getpgrp(SB)
+
+GLOBL	·libc_getpgrp_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getpgrp_trampoline_addr(SB)/8, $libc_getpgrp_trampoline<>(SB)
+
+TEXT libc_getpid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getpid(SB)
+
+GLOBL	·libc_getpid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getpid_trampoline_addr(SB)/8, $libc_getpid_trampoline<>(SB)
+
+TEXT libc_getppid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getppid(SB)
+
+GLOBL	·libc_getppid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getppid_trampoline_addr(SB)/8, $libc_getppid_trampoline<>(SB)
+
+TEXT libc_getpriority_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getpriority(SB)
+
+GLOBL	·libc_getpriority_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getpriority_trampoline_addr(SB)/8, $libc_getpriority_trampoline<>(SB)
+
+TEXT libc_getrlimit_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getrlimit(SB)
+
+GLOBL	·libc_getrlimit_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getrlimit_trampoline_addr(SB)/8, $libc_getrlimit_trampoline<>(SB)
+
+TEXT libc_getrtable_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getrtable(SB)
+
+GLOBL	·libc_getrtable_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getrtable_trampoline_addr(SB)/8, $libc_getrtable_trampoline<>(SB)
+
+TEXT libc_getrusage_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getrusage(SB)
+
+GLOBL	·libc_getrusage_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getrusage_trampoline_addr(SB)/8, $libc_getrusage_trampoline<>(SB)
+
+TEXT libc_getsid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getsid(SB)
+
+GLOBL	·libc_getsid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getsid_trampoline_addr(SB)/8, $libc_getsid_trampoline<>(SB)
+
+TEXT libc_gettimeofday_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_gettimeofday(SB)
+
+GLOBL	·libc_gettimeofday_trampoline_addr(SB), RODATA, $8
+DATA	·libc_gettimeofday_trampoline_addr(SB)/8, $libc_gettimeofday_trampoline<>(SB)
+
+TEXT libc_getuid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getuid(SB)
+
+GLOBL	·libc_getuid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getuid_trampoline_addr(SB)/8, $libc_getuid_trampoline<>(SB)
+
+TEXT libc_issetugid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_issetugid(SB)
+
+GLOBL	·libc_issetugid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_issetugid_trampoline_addr(SB)/8, $libc_issetugid_trampoline<>(SB)
+
+TEXT libc_kill_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_kill(SB)
+
+GLOBL	·libc_kill_trampoline_addr(SB), RODATA, $8
+DATA	·libc_kill_trampoline_addr(SB)/8, $libc_kill_trampoline<>(SB)
+
+TEXT libc_kqueue_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_kqueue(SB)
+
+GLOBL	·libc_kqueue_trampoline_addr(SB), RODATA, $8
+DATA	·libc_kqueue_trampoline_addr(SB)/8, $libc_kqueue_trampoline<>(SB)
+
+TEXT libc_lchown_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_lchown(SB)
+
+GLOBL	·libc_lchown_trampoline_addr(SB), RODATA, $8
+DATA	·libc_lchown_trampoline_addr(SB)/8, $libc_lchown_trampoline<>(SB)
+
+TEXT libc_link_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_link(SB)
+
+GLOBL	·libc_link_trampoline_addr(SB), RODATA, $8
+DATA	·libc_link_trampoline_addr(SB)/8, $libc_link_trampoline<>(SB)
+
+TEXT libc_linkat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_linkat(SB)
+
+GLOBL	·libc_linkat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_linkat_trampoline_addr(SB)/8, $libc_linkat_trampoline<>(SB)
+
+TEXT libc_listen_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_listen(SB)
+
+GLOBL	·libc_listen_trampoline_addr(SB), RODATA, $8
+DATA	·libc_listen_trampoline_addr(SB)/8, $libc_listen_trampoline<>(SB)
+
+TEXT libc_lstat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_lstat(SB)
+
+GLOBL	·libc_lstat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_lstat_trampoline_addr(SB)/8, $libc_lstat_trampoline<>(SB)
+
+TEXT libc_mkdir_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mkdir(SB)
+
+GLOBL	·libc_mkdir_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mkdir_trampoline_addr(SB)/8, $libc_mkdir_trampoline<>(SB)
+
+TEXT libc_mkdirat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mkdirat(SB)
+
+GLOBL	·libc_mkdirat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mkdirat_trampoline_addr(SB)/8, $libc_mkdirat_trampoline<>(SB)
+
+TEXT libc_mkfifo_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mkfifo(SB)
+
+GLOBL	·libc_mkfifo_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mkfifo_trampoline_addr(SB)/8, $libc_mkfifo_trampoline<>(SB)
+
+TEXT libc_mkfifoat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mkfifoat(SB)
+
+GLOBL	·libc_mkfifoat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mkfifoat_trampoline_addr(SB)/8, $libc_mkfifoat_trampoline<>(SB)
+
+TEXT libc_mknod_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mknod(SB)
+
+GLOBL	·libc_mknod_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mknod_trampoline_addr(SB)/8, $libc_mknod_trampoline<>(SB)
+
+TEXT libc_mknodat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mknodat(SB)
+
+GLOBL	·libc_mknodat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mknodat_trampoline_addr(SB)/8, $libc_mknodat_trampoline<>(SB)
+
+TEXT libc_nanosleep_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_nanosleep(SB)
+
+GLOBL	·libc_nanosleep_trampoline_addr(SB), RODATA, $8
+DATA	·libc_nanosleep_trampoline_addr(SB)/8, $libc_nanosleep_trampoline<>(SB)
+
+TEXT libc_open_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_open(SB)
+
+GLOBL	·libc_open_trampoline_addr(SB), RODATA, $8
+DATA	·libc_open_trampoline_addr(SB)/8, $libc_open_trampoline<>(SB)
+
+TEXT libc_openat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_openat(SB)
+
+GLOBL	·libc_openat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_openat_trampoline_addr(SB)/8, $libc_openat_trampoline<>(SB)
+
+TEXT libc_pathconf_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_pathconf(SB)
+
+GLOBL	·libc_pathconf_trampoline_addr(SB), RODATA, $8
+DATA	·libc_pathconf_trampoline_addr(SB)/8, $libc_pathconf_trampoline<>(SB)
+
+TEXT libc_pread_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_pread(SB)
+
+GLOBL	·libc_pread_trampoline_addr(SB), RODATA, $8
+DATA	·libc_pread_trampoline_addr(SB)/8, $libc_pread_trampoline<>(SB)
+
+TEXT libc_pwrite_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_pwrite(SB)
+
+GLOBL	·libc_pwrite_trampoline_addr(SB), RODATA, $8
+DATA	·libc_pwrite_trampoline_addr(SB)/8, $libc_pwrite_trampoline<>(SB)
+
+TEXT libc_read_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_read(SB)
+
+GLOBL	·libc_read_trampoline_addr(SB), RODATA, $8
+DATA	·libc_read_trampoline_addr(SB)/8, $libc_read_trampoline<>(SB)
+
+TEXT libc_readlink_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_readlink(SB)
+
+GLOBL	·libc_readlink_trampoline_addr(SB), RODATA, $8
+DATA	·libc_readlink_trampoline_addr(SB)/8, $libc_readlink_trampoline<>(SB)
+
+TEXT libc_readlinkat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_readlinkat(SB)
+
+GLOBL	·libc_readlinkat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_readlinkat_trampoline_addr(SB)/8, $libc_readlinkat_trampoline<>(SB)
+
+TEXT libc_rename_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_rename(SB)
+
+GLOBL	·libc_rename_trampoline_addr(SB), RODATA, $8
+DATA	·libc_rename_trampoline_addr(SB)/8, $libc_rename_trampoline<>(SB)
+
+TEXT libc_renameat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_renameat(SB)
+
+GLOBL	·libc_renameat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_renameat_trampoline_addr(SB)/8, $libc_renameat_trampoline<>(SB)
+
+TEXT libc_revoke_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_revoke(SB)
+
+GLOBL	·libc_revoke_trampoline_addr(SB), RODATA, $8
+DATA	·libc_revoke_trampoline_addr(SB)/8, $libc_revoke_trampoline<>(SB)
+
+TEXT libc_rmdir_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_rmdir(SB)
+
+GLOBL	·libc_rmdir_trampoline_addr(SB), RODATA, $8
+DATA	·libc_rmdir_trampoline_addr(SB)/8, $libc_rmdir_trampoline<>(SB)
+
+TEXT libc_lseek_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_lseek(SB)
+
+GLOBL	·libc_lseek_trampoline_addr(SB), RODATA, $8
+DATA	·libc_lseek_trampoline_addr(SB)/8, $libc_lseek_trampoline<>(SB)
+
+TEXT libc_select_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_select(SB)
+
+GLOBL	·libc_select_trampoline_addr(SB), RODATA, $8
+DATA	·libc_select_trampoline_addr(SB)/8, $libc_select_trampoline<>(SB)
+
+TEXT libc_setegid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setegid(SB)
+
+GLOBL	·libc_setegid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setegid_trampoline_addr(SB)/8, $libc_setegid_trampoline<>(SB)
+
+TEXT libc_seteuid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_seteuid(SB)
+
+GLOBL	·libc_seteuid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_seteuid_trampoline_addr(SB)/8, $libc_seteuid_trampoline<>(SB)
+
+TEXT libc_setgid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setgid(SB)
+
+GLOBL	·libc_setgid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setgid_trampoline_addr(SB)/8, $libc_setgid_trampoline<>(SB)
+
+TEXT libc_setlogin_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setlogin(SB)
+
+GLOBL	·libc_setlogin_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setlogin_trampoline_addr(SB)/8, $libc_setlogin_trampoline<>(SB)
+
+TEXT libc_setpgid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setpgid(SB)
+
+GLOBL	·libc_setpgid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setpgid_trampoline_addr(SB)/8, $libc_setpgid_trampoline<>(SB)
+
+TEXT libc_setpriority_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setpriority(SB)
+
+GLOBL	·libc_setpriority_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setpriority_trampoline_addr(SB)/8, $libc_setpriority_trampoline<>(SB)
+
+TEXT libc_setregid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setregid(SB)
+
+GLOBL	·libc_setregid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setregid_trampoline_addr(SB)/8, $libc_setregid_trampoline<>(SB)
+
+TEXT libc_setreuid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setreuid(SB)
+
+GLOBL	·libc_setreuid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setreuid_trampoline_addr(SB)/8, $libc_setreuid_trampoline<>(SB)
+
+TEXT libc_setresgid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setresgid(SB)
+
+GLOBL	·libc_setresgid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setresgid_trampoline_addr(SB)/8, $libc_setresgid_trampoline<>(SB)
+
+TEXT libc_setresuid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setresuid(SB)
+
+GLOBL	·libc_setresuid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setresuid_trampoline_addr(SB)/8, $libc_setresuid_trampoline<>(SB)
+
+TEXT libc_setrlimit_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setrlimit(SB)
+
+GLOBL	·libc_setrlimit_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setrlimit_trampoline_addr(SB)/8, $libc_setrlimit_trampoline<>(SB)
+
+TEXT libc_setrtable_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setrtable(SB)
+
+GLOBL	·libc_setrtable_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setrtable_trampoline_addr(SB)/8, $libc_setrtable_trampoline<>(SB)
+
+TEXT libc_setsid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setsid(SB)
+
+GLOBL	·libc_setsid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setsid_trampoline_addr(SB)/8, $libc_setsid_trampoline<>(SB)
+
+TEXT libc_settimeofday_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_settimeofday(SB)
+
+GLOBL	·libc_settimeofday_trampoline_addr(SB), RODATA, $8
+DATA	·libc_settimeofday_trampoline_addr(SB)/8, $libc_settimeofday_trampoline<>(SB)
+
+TEXT libc_setuid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setuid(SB)
+
+GLOBL	·libc_setuid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setuid_trampoline_addr(SB)/8, $libc_setuid_trampoline<>(SB)
+
+TEXT libc_stat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_stat(SB)
+
+GLOBL	·libc_stat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_stat_trampoline_addr(SB)/8, $libc_stat_trampoline<>(SB)
+
+TEXT libc_statfs_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_statfs(SB)
+
+GLOBL	·libc_statfs_trampoline_addr(SB), RODATA, $8
+DATA	·libc_statfs_trampoline_addr(SB)/8, $libc_statfs_trampoline<>(SB)
+
+TEXT libc_symlink_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_symlink(SB)
+
+GLOBL	·libc_symlink_trampoline_addr(SB), RODATA, $8
+DATA	·libc_symlink_trampoline_addr(SB)/8, $libc_symlink_trampoline<>(SB)
+
+TEXT libc_symlinkat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_symlinkat(SB)
+
+GLOBL	·libc_symlinkat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_symlinkat_trampoline_addr(SB)/8, $libc_symlinkat_trampoline<>(SB)
+
+TEXT libc_sync_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_sync(SB)
+
+GLOBL	·libc_sync_trampoline_addr(SB), RODATA, $8
+DATA	·libc_sync_trampoline_addr(SB)/8, $libc_sync_trampoline<>(SB)
+
+TEXT libc_truncate_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_truncate(SB)
+
+GLOBL	·libc_truncate_trampoline_addr(SB), RODATA, $8
+DATA	·libc_truncate_trampoline_addr(SB)/8, $libc_truncate_trampoline<>(SB)
+
+TEXT libc_umask_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_umask(SB)
+
+GLOBL	·libc_umask_trampoline_addr(SB), RODATA, $8
+DATA	·libc_umask_trampoline_addr(SB)/8, $libc_umask_trampoline<>(SB)
+
+TEXT libc_unlink_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_unlink(SB)
+
+GLOBL	·libc_unlink_trampoline_addr(SB), RODATA, $8
+DATA	·libc_unlink_trampoline_addr(SB)/8, $libc_unlink_trampoline<>(SB)
+
+TEXT libc_unlinkat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_unlinkat(SB)
+
+GLOBL	·libc_unlinkat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_unlinkat_trampoline_addr(SB)/8, $libc_unlinkat_trampoline<>(SB)
+
+TEXT libc_unmount_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_unmount(SB)
+
+GLOBL	·libc_unmount_trampoline_addr(SB), RODATA, $8
+DATA	·libc_unmount_trampoline_addr(SB)/8, $libc_unmount_trampoline<>(SB)
+
+TEXT libc_write_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_write(SB)
+
+GLOBL	·libc_write_trampoline_addr(SB), RODATA, $8
+DATA	·libc_write_trampoline_addr(SB)/8, $libc_write_trampoline<>(SB)
+
+TEXT libc_mmap_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mmap(SB)
+
+GLOBL	·libc_mmap_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mmap_trampoline_addr(SB)/8, $libc_mmap_trampoline<>(SB)
+
+TEXT libc_munmap_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_munmap(SB)
+
+GLOBL	·libc_munmap_trampoline_addr(SB), RODATA, $8
+DATA	·libc_munmap_trampoline_addr(SB)/8, $libc_munmap_trampoline<>(SB)
+
+TEXT libc_utimensat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_utimensat(SB)
+
+GLOBL	·libc_utimensat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_utimensat_trampoline_addr(SB)/8, $libc_utimensat_trampoline<>(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go
index 69f8030..8da6791 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go
@@ -1,4 +1,4 @@
-// go run mksyscall.go -l32 -openbsd -arm -tags openbsd,arm syscall_bsd.go syscall_openbsd.go syscall_openbsd_arm.go
+// go run mksyscall.go -l32 -openbsd -arm -libc -tags openbsd,arm syscall_bsd.go syscall_openbsd.go syscall_openbsd_arm.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build openbsd && arm
@@ -16,7 +16,7 @@
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	r0, _, e1 := syscall_rawSyscall(libc_getgroups_trampoline_addr, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -24,20 +24,28 @@
 	return
 }
 
+var libc_getgroups_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getgroups getgroups "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func setgroups(ngid int, gid *_Gid_t) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	_, _, e1 := syscall_rawSyscall(libc_setgroups_trampoline_addr, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setgroups_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setgroups setgroups "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
-	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+	r0, _, e1 := syscall_syscall6(libc_wait4_trampoline_addr, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
 	wpid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -45,10 +53,14 @@
 	return
 }
 
+var libc_wait4_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_wait4 wait4 "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	r0, _, e1 := syscall_syscall(libc_accept_trampoline_addr, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -56,30 +68,42 @@
 	return
 }
 
+var libc_accept_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_accept accept "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
+	_, _, e1 := syscall_syscall(libc_bind_trampoline_addr, uintptr(s), uintptr(addr), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_bind_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_bind bind "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
+	_, _, e1 := syscall_syscall(libc_connect_trampoline_addr, uintptr(s), uintptr(addr), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_connect_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_connect connect "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func socket(domain int, typ int, proto int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
+	r0, _, e1 := syscall_rawSyscall(libc_socket_trampoline_addr, uintptr(domain), uintptr(typ), uintptr(proto))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -87,66 +111,94 @@
 	return
 }
 
+var libc_socket_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_socket socket "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
-	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+	_, _, e1 := syscall_syscall6(libc_getsockopt_trampoline_addr, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_getsockopt_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getsockopt getsockopt "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
-	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+	_, _, e1 := syscall_syscall6(libc_setsockopt_trampoline_addr, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setsockopt_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setsockopt setsockopt "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	_, _, e1 := syscall_rawSyscall(libc_getpeername_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_getpeername_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getpeername getpeername "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	_, _, e1 := syscall_rawSyscall(libc_getsockname_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_getsockname_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getsockname getsockname "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Shutdown(s int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0)
+	_, _, e1 := syscall_syscall(libc_shutdown_trampoline_addr, uintptr(s), uintptr(how), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_shutdown_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_shutdown shutdown "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
-	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+	_, _, e1 := syscall_rawSyscall6(libc_socketpair_trampoline_addr, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_socketpair_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_socketpair socketpair "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
@@ -156,7 +208,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	r0, _, e1 := syscall_syscall6(libc_recvfrom_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -164,6 +216,10 @@
 	return
 }
 
+var libc_recvfrom_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_recvfrom recvfrom "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
@@ -173,17 +229,21 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+	_, _, e1 := syscall_syscall6(libc_sendto_trampoline_addr, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_sendto_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_sendto sendto "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	r0, _, e1 := syscall_syscall(libc_recvmsg_trampoline_addr, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -191,10 +251,14 @@
 	return
 }
 
+var libc_recvmsg_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_recvmsg recvmsg "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	r0, _, e1 := syscall_syscall(libc_sendmsg_trampoline_addr, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -202,10 +266,14 @@
 	return
 }
 
+var libc_sendmsg_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_sendmsg sendmsg "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
-	r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
+	r0, _, e1 := syscall_syscall6(libc_kevent_trampoline_addr, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -213,6 +281,10 @@
 	return
 }
 
+var libc_kevent_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_kevent kevent "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func utimes(path string, timeval *[2]Timeval) (err error) {
@@ -221,27 +293,35 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
+	_, _, e1 := syscall_syscall(libc_utimes_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_utimes_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_utimes utimes "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func futimes(fd int, timeval *[2]Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
+	_, _, e1 := syscall_syscall(libc_futimes_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_futimes_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_futimes futimes "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
+	r0, _, e1 := syscall_syscall(libc_poll_trampoline_addr, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -249,6 +329,10 @@
 	return
 }
 
+var libc_poll_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_poll poll "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Madvise(b []byte, behav int) (err error) {
@@ -258,13 +342,17 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav))
+	_, _, e1 := syscall_syscall(libc_madvise_trampoline_addr, uintptr(_p0), uintptr(len(b)), uintptr(behav))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_madvise_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_madvise madvise "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mlock(b []byte) (err error) {
@@ -274,23 +362,31 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	_, _, e1 := syscall_syscall(libc_mlock_trampoline_addr, uintptr(_p0), uintptr(len(b)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mlock_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mlock mlock "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mlockall(flags int) (err error) {
-	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
+	_, _, e1 := syscall_syscall(libc_mlockall_trampoline_addr, uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mlockall_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mlockall mlockall "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mprotect(b []byte, prot int) (err error) {
@@ -300,13 +396,17 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
+	_, _, e1 := syscall_syscall(libc_mprotect_trampoline_addr, uintptr(_p0), uintptr(len(b)), uintptr(prot))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mprotect_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mprotect mprotect "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Msync(b []byte, flags int) (err error) {
@@ -316,13 +416,17 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	_, _, e1 := syscall_syscall(libc_msync_trampoline_addr, uintptr(_p0), uintptr(len(b)), uintptr(flags))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_msync_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_msync msync "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Munlock(b []byte) (err error) {
@@ -332,33 +436,45 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	_, _, e1 := syscall_syscall(libc_munlock_trampoline_addr, uintptr(_p0), uintptr(len(b)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_munlock_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_munlock munlock "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Munlockall() (err error) {
-	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
+	_, _, e1 := syscall_syscall(libc_munlockall_trampoline_addr, 0, 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_munlockall_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_munlockall munlockall "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func pipe2(p *[2]_C_int, flags int) (err error) {
-	_, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
+	_, _, e1 := syscall_rawSyscall(libc_pipe2_trampoline_addr, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_pipe2_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_pipe2 pipe2 "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getdents(fd int, buf []byte) (n int, err error) {
@@ -368,7 +484,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(SYS_GETDENTS, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+	r0, _, e1 := syscall_syscall(libc_getdents_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -376,6 +492,10 @@
 	return
 }
 
+var libc_getdents_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getdents getdents "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getcwd(buf []byte) (n int, err error) {
@@ -385,7 +505,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(SYS___GETCWD, uintptr(_p0), uintptr(len(buf)), 0)
+	r0, _, e1 := syscall_syscall(libc_getcwd_trampoline_addr, uintptr(_p0), uintptr(len(buf)), 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -393,16 +513,24 @@
 	return
 }
 
+var libc_getcwd_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getcwd getcwd "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func ioctl(fd int, req uint, arg uintptr) (err error) {
-	_, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg))
+	_, _, e1 := syscall_syscall(libc_ioctl_trampoline_addr, uintptr(fd), uintptr(req), uintptr(arg))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_ioctl_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_ioctl ioctl "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
@@ -412,17 +540,21 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
+	_, _, e1 := syscall_syscall6(libc_sysctl_trampoline_addr, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_sysctl_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_sysctl sysctl "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
-	r0, _, e1 := Syscall6(SYS_PPOLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0)
+	r0, _, e1 := syscall_syscall6(libc_ppoll_trampoline_addr, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -430,6 +562,10 @@
 	return
 }
 
+var libc_ppoll_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_ppoll ppoll "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Access(path string, mode uint32) (err error) {
@@ -438,23 +574,31 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall_syscall(libc_access_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_access_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_access access "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
+	_, _, e1 := syscall_syscall(libc_adjtime_trampoline_addr, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_adjtime_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_adjtime adjtime "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Chdir(path string) (err error) {
@@ -463,13 +607,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_chdir_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_chdir_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_chdir chdir "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Chflags(path string, flags int) (err error) {
@@ -478,13 +626,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	_, _, e1 := syscall_syscall(libc_chflags_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_chflags_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_chflags chflags "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Chmod(path string, mode uint32) (err error) {
@@ -493,13 +645,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall_syscall(libc_chmod_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_chmod_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_chmod chmod "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Chown(path string, uid int, gid int) (err error) {
@@ -508,13 +664,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall_syscall(libc_chown_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_chown_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_chown chown "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Chroot(path string) (err error) {
@@ -523,27 +683,35 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_chroot_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_chroot_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_chroot chroot "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Close(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+	_, _, e1 := syscall_syscall(libc_close_trampoline_addr, uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_close_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_close close "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Dup(fd int) (nfd int, err error) {
-	r0, _, e1 := Syscall(SYS_DUP, uintptr(fd), 0, 0)
+	r0, _, e1 := syscall_syscall(libc_dup_trampoline_addr, uintptr(fd), 0, 0)
 	nfd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -551,33 +719,49 @@
 	return
 }
 
+var libc_dup_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_dup dup "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Dup2(from int, to int) (err error) {
-	_, _, e1 := Syscall(SYS_DUP2, uintptr(from), uintptr(to), 0)
+	_, _, e1 := syscall_syscall(libc_dup2_trampoline_addr, uintptr(from), uintptr(to), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_dup2_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_dup2 dup2 "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Dup3(from int, to int, flags int) (err error) {
-	_, _, e1 := Syscall(SYS_DUP3, uintptr(from), uintptr(to), uintptr(flags))
+	_, _, e1 := syscall_syscall(libc_dup3_trampoline_addr, uintptr(from), uintptr(to), uintptr(flags))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_dup3_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_dup3 dup3 "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Exit(code int) {
-	Syscall(SYS_EXIT, uintptr(code), 0, 0)
+	syscall_syscall(libc_exit_trampoline_addr, uintptr(code), 0, 0)
 	return
 }
 
+var libc_exit_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_exit exit "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
@@ -586,43 +770,59 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_faccessat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_faccessat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_faccessat faccessat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchdir(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
+	_, _, e1 := syscall_syscall(libc_fchdir_trampoline_addr, uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fchdir_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchdir fchdir "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchflags(fd int, flags int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0)
+	_, _, e1 := syscall_syscall(libc_fchflags_trampoline_addr, uintptr(fd), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fchflags_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchflags fchflags "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchmod(fd int, mode uint32) (err error) {
-	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
+	_, _, e1 := syscall_syscall(libc_fchmod_trampoline_addr, uintptr(fd), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fchmod_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchmod fchmod "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
@@ -631,23 +831,31 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_fchmodat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fchmodat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchmodat fchmodat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchown(fd int, uid int, gid int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall_syscall(libc_fchown_trampoline_addr, uintptr(fd), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fchown_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchown fchown "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) {
@@ -656,27 +864,35 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_FCHOWNAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
+	_, _, e1 := syscall_syscall6(libc_fchownat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fchownat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchownat fchownat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Flock(fd int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
+	_, _, e1 := syscall_syscall(libc_flock_trampoline_addr, uintptr(fd), uintptr(how), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_flock_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_flock flock "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fpathconf(fd int, name int) (val int, err error) {
-	r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0)
+	r0, _, e1 := syscall_syscall(libc_fpathconf_trampoline_addr, uintptr(fd), uintptr(name), 0)
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -684,16 +900,24 @@
 	return
 }
 
+var libc_fpathconf_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fpathconf fpathconf "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fstat(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall_syscall(libc_fstat_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fstat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fstat fstat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) {
@@ -702,71 +926,99 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_fstatat_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fstatat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fstatat fstatat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fstatfs(fd int, stat *Statfs_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall_syscall(libc_fstatfs_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fstatfs_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fstatfs fstatfs "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fsync(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
+	_, _, e1 := syscall_syscall(libc_fsync_trampoline_addr, uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fsync_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fsync fsync "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Ftruncate(fd int, length int64) (err error) {
-	_, _, e1 := Syscall6(SYS_FTRUNCATE, uintptr(fd), 0, uintptr(length), uintptr(length>>32), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_ftruncate_trampoline_addr, uintptr(fd), 0, uintptr(length), uintptr(length>>32), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_ftruncate_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_ftruncate ftruncate "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getegid() (egid int) {
-	r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getegid_trampoline_addr, 0, 0, 0)
 	egid = int(r0)
 	return
 }
 
+var libc_getegid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getegid getegid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Geteuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_geteuid_trampoline_addr, 0, 0, 0)
 	uid = int(r0)
 	return
 }
 
+var libc_geteuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_geteuid geteuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getgid() (gid int) {
-	r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getgid_trampoline_addr, 0, 0, 0)
 	gid = int(r0)
 	return
 }
 
+var libc_getgid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getgid getgid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpgid(pid int) (pgid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
+	r0, _, e1 := syscall_rawSyscall(libc_getpgid_trampoline_addr, uintptr(pid), 0, 0)
 	pgid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -774,34 +1026,50 @@
 	return
 }
 
+var libc_getpgid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getpgid getpgid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpgrp() (pgrp int) {
-	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getpgrp_trampoline_addr, 0, 0, 0)
 	pgrp = int(r0)
 	return
 }
 
+var libc_getpgrp_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getpgrp getpgrp "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpid() (pid int) {
-	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getpid_trampoline_addr, 0, 0, 0)
 	pid = int(r0)
 	return
 }
 
+var libc_getpid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getpid getpid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getppid() (ppid int) {
-	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getppid_trampoline_addr, 0, 0, 0)
 	ppid = int(r0)
 	return
 }
 
+var libc_getppid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getppid getppid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpriority(which int, who int) (prio int, err error) {
-	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
+	r0, _, e1 := syscall_syscall(libc_getpriority_trampoline_addr, uintptr(which), uintptr(who), 0)
 	prio = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -809,20 +1077,28 @@
 	return
 }
 
+var libc_getpriority_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getpriority getpriority "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	_, _, e1 := syscall_rawSyscall(libc_getrlimit_trampoline_addr, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_getrlimit_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getrlimit getrlimit "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getrtable() (rtable int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETRTABLE, 0, 0, 0)
+	r0, _, e1 := syscall_rawSyscall(libc_getrtable_trampoline_addr, 0, 0, 0)
 	rtable = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -830,20 +1106,28 @@
 	return
 }
 
+var libc_getrtable_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getrtable getrtable "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getrusage(who int, rusage *Rusage) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+	_, _, e1 := syscall_rawSyscall(libc_getrusage_trampoline_addr, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_getrusage_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getrusage getrusage "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getsid(pid int) (sid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0)
+	r0, _, e1 := syscall_rawSyscall(libc_getsid_trampoline_addr, uintptr(pid), 0, 0)
 	sid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -851,46 +1135,66 @@
 	return
 }
 
+var libc_getsid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getsid getsid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Gettimeofday(tv *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_gettimeofday_trampoline_addr, uintptr(unsafe.Pointer(tv)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_gettimeofday_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_gettimeofday gettimeofday "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getuid_trampoline_addr, 0, 0, 0)
 	uid = int(r0)
 	return
 }
 
+var libc_getuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getuid getuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Issetugid() (tainted bool) {
-	r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0)
+	r0, _, _ := syscall_syscall(libc_issetugid_trampoline_addr, 0, 0, 0)
 	tainted = bool(r0 != 0)
 	return
 }
 
+var libc_issetugid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_issetugid issetugid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Kill(pid int, signum syscall.Signal) (err error) {
-	_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), 0)
+	_, _, e1 := syscall_syscall(libc_kill_trampoline_addr, uintptr(pid), uintptr(signum), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_kill_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_kill kill "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Kqueue() (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0)
+	r0, _, e1 := syscall_syscall(libc_kqueue_trampoline_addr, 0, 0, 0)
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -898,6 +1202,10 @@
 	return
 }
 
+var libc_kqueue_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_kqueue kqueue "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Lchown(path string, uid int, gid int) (err error) {
@@ -906,13 +1214,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall_syscall(libc_lchown_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_lchown_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_lchown lchown "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Link(path string, link string) (err error) {
@@ -926,13 +1238,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall_syscall(libc_link_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_link_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_link link "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error) {
@@ -946,23 +1262,31 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_LINKAT, uintptr(pathfd), uintptr(unsafe.Pointer(_p0)), uintptr(linkfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
+	_, _, e1 := syscall_syscall6(libc_linkat_trampoline_addr, uintptr(pathfd), uintptr(unsafe.Pointer(_p0)), uintptr(linkfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_linkat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_linkat linkat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Listen(s int, backlog int) (err error) {
-	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
+	_, _, e1 := syscall_syscall(libc_listen_trampoline_addr, uintptr(s), uintptr(backlog), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_listen_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_listen listen "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Lstat(path string, stat *Stat_t) (err error) {
@@ -971,13 +1295,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall_syscall(libc_lstat_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_lstat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_lstat lstat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mkdir(path string, mode uint32) (err error) {
@@ -986,13 +1314,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall_syscall(libc_mkdir_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mkdir_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mkdir mkdir "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mkdirat(dirfd int, path string, mode uint32) (err error) {
@@ -1001,13 +1333,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_MKDIRAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+	_, _, e1 := syscall_syscall(libc_mkdirat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mkdirat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mkdirat mkdirat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mkfifo(path string, mode uint32) (err error) {
@@ -1016,13 +1352,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall_syscall(libc_mkfifo_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mkfifo_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mkfifo mkfifo "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mkfifoat(dirfd int, path string, mode uint32) (err error) {
@@ -1031,13 +1371,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_MKFIFOAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+	_, _, e1 := syscall_syscall(libc_mkfifoat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mkfifoat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mkfifoat mkfifoat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mknod(path string, mode uint32, dev int) (err error) {
@@ -1046,13 +1390,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
+	_, _, e1 := syscall_syscall(libc_mknod_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mknod_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mknod mknod "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) {
@@ -1061,23 +1409,31 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_MKNODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_mknodat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mknodat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mknodat mknodat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
-	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
+	_, _, e1 := syscall_syscall(libc_nanosleep_trampoline_addr, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_nanosleep_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_nanosleep nanosleep "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Open(path string, mode int, perm uint32) (fd int, err error) {
@@ -1086,7 +1442,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	r0, _, e1 := syscall_syscall(libc_open_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1094,6 +1450,10 @@
 	return
 }
 
+var libc_open_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_open open "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) {
@@ -1102,7 +1462,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0)
+	r0, _, e1 := syscall_syscall6(libc_openat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0)
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1110,6 +1470,10 @@
 	return
 }
 
+var libc_openat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_openat openat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Pathconf(path string, name int) (val int, err error) {
@@ -1118,7 +1482,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
+	r0, _, e1 := syscall_syscall(libc_pathconf_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1126,6 +1490,10 @@
 	return
 }
 
+var libc_pathconf_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_pathconf pathconf "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func pread(fd int, p []byte, offset int64) (n int, err error) {
@@ -1135,7 +1503,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
+	r0, _, e1 := syscall_syscall6(libc_pread_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1143,6 +1511,10 @@
 	return
 }
 
+var libc_pread_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_pread pread "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func pwrite(fd int, p []byte, offset int64) (n int, err error) {
@@ -1152,7 +1524,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
+	r0, _, e1 := syscall_syscall6(libc_pwrite_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1160,6 +1532,10 @@
 	return
 }
 
+var libc_pwrite_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_pwrite pwrite "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func read(fd int, p []byte) (n int, err error) {
@@ -1169,7 +1545,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	r0, _, e1 := syscall_syscall(libc_read_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1177,6 +1553,10 @@
 	return
 }
 
+var libc_read_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_read read "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Readlink(path string, buf []byte) (n int, err error) {
@@ -1191,7 +1571,7 @@
 	} else {
 		_p1 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+	r0, _, e1 := syscall_syscall(libc_readlink_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1199,6 +1579,10 @@
 	return
 }
 
+var libc_readlink_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_readlink readlink "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
@@ -1213,7 +1597,7 @@
 	} else {
 		_p1 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall6(SYS_READLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0)
+	r0, _, e1 := syscall_syscall6(libc_readlinkat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1221,6 +1605,10 @@
 	return
 }
 
+var libc_readlinkat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_readlinkat readlinkat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Rename(from string, to string) (err error) {
@@ -1234,13 +1622,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall_syscall(libc_rename_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_rename_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_rename rename "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Renameat(fromfd int, from string, tofd int, to string) (err error) {
@@ -1254,13 +1646,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_renameat_trampoline_addr, uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_renameat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_renameat renameat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Revoke(path string) (err error) {
@@ -1269,13 +1665,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_revoke_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_revoke_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_revoke revoke "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Rmdir(path string) (err error) {
@@ -1284,17 +1684,21 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_rmdir_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_rmdir_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_rmdir rmdir "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
-	r0, r1, e1 := Syscall6(SYS_LSEEK, uintptr(fd), 0, uintptr(offset), uintptr(offset>>32), uintptr(whence), 0)
+	r0, r1, e1 := syscall_syscall6(libc_lseek_trampoline_addr, uintptr(fd), 0, uintptr(offset), uintptr(offset>>32), uintptr(whence), 0)
 	newoffset = int64(int64(r1)<<32 | int64(r0))
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1302,10 +1706,14 @@
 	return
 }
 
+var libc_lseek_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_lseek lseek "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {
-	r0, _, e1 := Syscall6(SYS_SELECT, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+	r0, _, e1 := syscall_syscall6(libc_select_trampoline_addr, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1313,36 +1721,52 @@
 	return
 }
 
+var libc_select_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_select select "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setegid(egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETEGID, uintptr(egid), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_setegid_trampoline_addr, uintptr(egid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setegid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setegid setegid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Seteuid(euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_seteuid_trampoline_addr, uintptr(euid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_seteuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_seteuid seteuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setgid(gid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_setgid_trampoline_addr, uintptr(gid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setgid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setgid setgid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setlogin(name string) (err error) {
@@ -1351,97 +1775,133 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_setlogin_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setlogin_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setlogin setlogin "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setpgid(pid int, pgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
+	_, _, e1 := syscall_rawSyscall(libc_setpgid_trampoline_addr, uintptr(pid), uintptr(pgid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setpgid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setpgid setpgid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setpriority(which int, who int, prio int) (err error) {
-	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
+	_, _, e1 := syscall_syscall(libc_setpriority_trampoline_addr, uintptr(which), uintptr(who), uintptr(prio))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setpriority_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setpriority setpriority "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
+	_, _, e1 := syscall_rawSyscall(libc_setregid_trampoline_addr, uintptr(rgid), uintptr(egid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setregid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setregid setregid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
+	_, _, e1 := syscall_rawSyscall(libc_setreuid_trampoline_addr, uintptr(ruid), uintptr(euid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setreuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setreuid setreuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setresgid(rgid int, egid int, sgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid))
+	_, _, e1 := syscall_rawSyscall(libc_setresgid_trampoline_addr, uintptr(rgid), uintptr(egid), uintptr(sgid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setresgid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setresgid setresgid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setresuid(ruid int, euid int, suid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid))
+	_, _, e1 := syscall_rawSyscall(libc_setresuid_trampoline_addr, uintptr(ruid), uintptr(euid), uintptr(suid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setresuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setresuid setresuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	_, _, e1 := syscall_rawSyscall(libc_setrlimit_trampoline_addr, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setrlimit_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setrlimit setrlimit "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setrtable(rtable int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRTABLE, uintptr(rtable), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_setrtable_trampoline_addr, uintptr(rtable), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setrtable_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setrtable setrtable "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setsid() (pid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
+	r0, _, e1 := syscall_rawSyscall(libc_setsid_trampoline_addr, 0, 0, 0)
 	pid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1449,26 +1909,38 @@
 	return
 }
 
+var libc_setsid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setsid setsid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Settimeofday(tp *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_settimeofday_trampoline_addr, uintptr(unsafe.Pointer(tp)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_settimeofday_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_settimeofday settimeofday "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setuid(uid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_setuid_trampoline_addr, uintptr(uid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setuid setuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Stat(path string, stat *Stat_t) (err error) {
@@ -1477,13 +1949,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall_syscall(libc_stat_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_stat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_stat stat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Statfs(path string, stat *Statfs_t) (err error) {
@@ -1492,13 +1968,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall_syscall(libc_statfs_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_statfs_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_statfs statfs "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Symlink(path string, link string) (err error) {
@@ -1512,13 +1992,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall_syscall(libc_symlink_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_symlink_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_symlink symlink "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) {
@@ -1532,23 +2016,31 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_SYMLINKAT, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)))
+	_, _, e1 := syscall_syscall(libc_symlinkat_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_symlinkat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_symlinkat symlinkat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Sync() (err error) {
-	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
+	_, _, e1 := syscall_syscall(libc_sync_trampoline_addr, 0, 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_sync_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_sync sync "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Truncate(path string, length int64) (err error) {
@@ -1557,21 +2049,29 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), 0, uintptr(length), uintptr(length>>32), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_truncate_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, uintptr(length), uintptr(length>>32), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_truncate_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_truncate truncate "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Umask(newmask int) (oldmask int) {
-	r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0)
+	r0, _, _ := syscall_syscall(libc_umask_trampoline_addr, uintptr(newmask), 0, 0)
 	oldmask = int(r0)
 	return
 }
 
+var libc_umask_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_umask umask "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Unlink(path string) (err error) {
@@ -1580,13 +2080,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_unlink_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_unlink_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_unlink unlink "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Unlinkat(dirfd int, path string, flags int) (err error) {
@@ -1595,13 +2099,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+	_, _, e1 := syscall_syscall(libc_unlinkat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_unlinkat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_unlinkat unlinkat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Unmount(path string, flags int) (err error) {
@@ -1610,13 +2118,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	_, _, e1 := syscall_syscall(libc_unmount_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_unmount_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_unmount unmount "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func write(fd int, p []byte) (n int, err error) {
@@ -1626,7 +2138,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	r0, _, e1 := syscall_syscall(libc_write_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1634,10 +2146,14 @@
 	return
 }
 
+var libc_write_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_write write "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
-	r0, _, e1 := Syscall9(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), 0, uintptr(pos), uintptr(pos>>32), 0)
+	r0, _, e1 := syscall_syscall9(libc_mmap_trampoline_addr, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), 0, uintptr(pos), uintptr(pos>>32), 0)
 	ret = uintptr(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1645,20 +2161,28 @@
 	return
 }
 
+var libc_mmap_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mmap mmap "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func munmap(addr uintptr, length uintptr) (err error) {
-	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
+	_, _, e1 := syscall_syscall(libc_munmap_trampoline_addr, uintptr(addr), uintptr(length), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_munmap_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_munmap munmap "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	r0, _, e1 := syscall_syscall(libc_read_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1669,7 +2193,7 @@
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	r0, _, e1 := syscall_syscall(libc_write_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1685,9 +2209,13 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_utimensat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
+
+var libc_utimensat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_utimensat utimensat "libc.so"
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.s b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.s
new file mode 100644
index 0000000..9ad116d
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.s
@@ -0,0 +1,796 @@
+// go run mkasm.go openbsd arm
+// Code generated by the command above; DO NOT EDIT.
+
+#include "textflag.h"
+
+TEXT libc_getgroups_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getgroups(SB)
+
+GLOBL	·libc_getgroups_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getgroups_trampoline_addr(SB)/4, $libc_getgroups_trampoline<>(SB)
+
+TEXT libc_setgroups_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setgroups(SB)
+
+GLOBL	·libc_setgroups_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setgroups_trampoline_addr(SB)/4, $libc_setgroups_trampoline<>(SB)
+
+TEXT libc_wait4_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_wait4(SB)
+
+GLOBL	·libc_wait4_trampoline_addr(SB), RODATA, $4
+DATA	·libc_wait4_trampoline_addr(SB)/4, $libc_wait4_trampoline<>(SB)
+
+TEXT libc_accept_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_accept(SB)
+
+GLOBL	·libc_accept_trampoline_addr(SB), RODATA, $4
+DATA	·libc_accept_trampoline_addr(SB)/4, $libc_accept_trampoline<>(SB)
+
+TEXT libc_bind_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_bind(SB)
+
+GLOBL	·libc_bind_trampoline_addr(SB), RODATA, $4
+DATA	·libc_bind_trampoline_addr(SB)/4, $libc_bind_trampoline<>(SB)
+
+TEXT libc_connect_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_connect(SB)
+
+GLOBL	·libc_connect_trampoline_addr(SB), RODATA, $4
+DATA	·libc_connect_trampoline_addr(SB)/4, $libc_connect_trampoline<>(SB)
+
+TEXT libc_socket_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_socket(SB)
+
+GLOBL	·libc_socket_trampoline_addr(SB), RODATA, $4
+DATA	·libc_socket_trampoline_addr(SB)/4, $libc_socket_trampoline<>(SB)
+
+TEXT libc_getsockopt_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getsockopt(SB)
+
+GLOBL	·libc_getsockopt_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getsockopt_trampoline_addr(SB)/4, $libc_getsockopt_trampoline<>(SB)
+
+TEXT libc_setsockopt_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setsockopt(SB)
+
+GLOBL	·libc_setsockopt_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setsockopt_trampoline_addr(SB)/4, $libc_setsockopt_trampoline<>(SB)
+
+TEXT libc_getpeername_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getpeername(SB)
+
+GLOBL	·libc_getpeername_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getpeername_trampoline_addr(SB)/4, $libc_getpeername_trampoline<>(SB)
+
+TEXT libc_getsockname_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getsockname(SB)
+
+GLOBL	·libc_getsockname_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getsockname_trampoline_addr(SB)/4, $libc_getsockname_trampoline<>(SB)
+
+TEXT libc_shutdown_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_shutdown(SB)
+
+GLOBL	·libc_shutdown_trampoline_addr(SB), RODATA, $4
+DATA	·libc_shutdown_trampoline_addr(SB)/4, $libc_shutdown_trampoline<>(SB)
+
+TEXT libc_socketpair_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_socketpair(SB)
+
+GLOBL	·libc_socketpair_trampoline_addr(SB), RODATA, $4
+DATA	·libc_socketpair_trampoline_addr(SB)/4, $libc_socketpair_trampoline<>(SB)
+
+TEXT libc_recvfrom_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_recvfrom(SB)
+
+GLOBL	·libc_recvfrom_trampoline_addr(SB), RODATA, $4
+DATA	·libc_recvfrom_trampoline_addr(SB)/4, $libc_recvfrom_trampoline<>(SB)
+
+TEXT libc_sendto_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_sendto(SB)
+
+GLOBL	·libc_sendto_trampoline_addr(SB), RODATA, $4
+DATA	·libc_sendto_trampoline_addr(SB)/4, $libc_sendto_trampoline<>(SB)
+
+TEXT libc_recvmsg_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_recvmsg(SB)
+
+GLOBL	·libc_recvmsg_trampoline_addr(SB), RODATA, $4
+DATA	·libc_recvmsg_trampoline_addr(SB)/4, $libc_recvmsg_trampoline<>(SB)
+
+TEXT libc_sendmsg_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_sendmsg(SB)
+
+GLOBL	·libc_sendmsg_trampoline_addr(SB), RODATA, $4
+DATA	·libc_sendmsg_trampoline_addr(SB)/4, $libc_sendmsg_trampoline<>(SB)
+
+TEXT libc_kevent_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_kevent(SB)
+
+GLOBL	·libc_kevent_trampoline_addr(SB), RODATA, $4
+DATA	·libc_kevent_trampoline_addr(SB)/4, $libc_kevent_trampoline<>(SB)
+
+TEXT libc_utimes_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_utimes(SB)
+
+GLOBL	·libc_utimes_trampoline_addr(SB), RODATA, $4
+DATA	·libc_utimes_trampoline_addr(SB)/4, $libc_utimes_trampoline<>(SB)
+
+TEXT libc_futimes_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_futimes(SB)
+
+GLOBL	·libc_futimes_trampoline_addr(SB), RODATA, $4
+DATA	·libc_futimes_trampoline_addr(SB)/4, $libc_futimes_trampoline<>(SB)
+
+TEXT libc_poll_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_poll(SB)
+
+GLOBL	·libc_poll_trampoline_addr(SB), RODATA, $4
+DATA	·libc_poll_trampoline_addr(SB)/4, $libc_poll_trampoline<>(SB)
+
+TEXT libc_madvise_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_madvise(SB)
+
+GLOBL	·libc_madvise_trampoline_addr(SB), RODATA, $4
+DATA	·libc_madvise_trampoline_addr(SB)/4, $libc_madvise_trampoline<>(SB)
+
+TEXT libc_mlock_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mlock(SB)
+
+GLOBL	·libc_mlock_trampoline_addr(SB), RODATA, $4
+DATA	·libc_mlock_trampoline_addr(SB)/4, $libc_mlock_trampoline<>(SB)
+
+TEXT libc_mlockall_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mlockall(SB)
+
+GLOBL	·libc_mlockall_trampoline_addr(SB), RODATA, $4
+DATA	·libc_mlockall_trampoline_addr(SB)/4, $libc_mlockall_trampoline<>(SB)
+
+TEXT libc_mprotect_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mprotect(SB)
+
+GLOBL	·libc_mprotect_trampoline_addr(SB), RODATA, $4
+DATA	·libc_mprotect_trampoline_addr(SB)/4, $libc_mprotect_trampoline<>(SB)
+
+TEXT libc_msync_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_msync(SB)
+
+GLOBL	·libc_msync_trampoline_addr(SB), RODATA, $4
+DATA	·libc_msync_trampoline_addr(SB)/4, $libc_msync_trampoline<>(SB)
+
+TEXT libc_munlock_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_munlock(SB)
+
+GLOBL	·libc_munlock_trampoline_addr(SB), RODATA, $4
+DATA	·libc_munlock_trampoline_addr(SB)/4, $libc_munlock_trampoline<>(SB)
+
+TEXT libc_munlockall_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_munlockall(SB)
+
+GLOBL	·libc_munlockall_trampoline_addr(SB), RODATA, $4
+DATA	·libc_munlockall_trampoline_addr(SB)/4, $libc_munlockall_trampoline<>(SB)
+
+TEXT libc_pipe2_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_pipe2(SB)
+
+GLOBL	·libc_pipe2_trampoline_addr(SB), RODATA, $4
+DATA	·libc_pipe2_trampoline_addr(SB)/4, $libc_pipe2_trampoline<>(SB)
+
+TEXT libc_getdents_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getdents(SB)
+
+GLOBL	·libc_getdents_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getdents_trampoline_addr(SB)/4, $libc_getdents_trampoline<>(SB)
+
+TEXT libc_getcwd_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getcwd(SB)
+
+GLOBL	·libc_getcwd_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getcwd_trampoline_addr(SB)/4, $libc_getcwd_trampoline<>(SB)
+
+TEXT libc_ioctl_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_ioctl(SB)
+
+GLOBL	·libc_ioctl_trampoline_addr(SB), RODATA, $4
+DATA	·libc_ioctl_trampoline_addr(SB)/4, $libc_ioctl_trampoline<>(SB)
+
+TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_sysctl(SB)
+
+GLOBL	·libc_sysctl_trampoline_addr(SB), RODATA, $4
+DATA	·libc_sysctl_trampoline_addr(SB)/4, $libc_sysctl_trampoline<>(SB)
+
+TEXT libc_ppoll_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_ppoll(SB)
+
+GLOBL	·libc_ppoll_trampoline_addr(SB), RODATA, $4
+DATA	·libc_ppoll_trampoline_addr(SB)/4, $libc_ppoll_trampoline<>(SB)
+
+TEXT libc_access_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_access(SB)
+
+GLOBL	·libc_access_trampoline_addr(SB), RODATA, $4
+DATA	·libc_access_trampoline_addr(SB)/4, $libc_access_trampoline<>(SB)
+
+TEXT libc_adjtime_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_adjtime(SB)
+
+GLOBL	·libc_adjtime_trampoline_addr(SB), RODATA, $4
+DATA	·libc_adjtime_trampoline_addr(SB)/4, $libc_adjtime_trampoline<>(SB)
+
+TEXT libc_chdir_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_chdir(SB)
+
+GLOBL	·libc_chdir_trampoline_addr(SB), RODATA, $4
+DATA	·libc_chdir_trampoline_addr(SB)/4, $libc_chdir_trampoline<>(SB)
+
+TEXT libc_chflags_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_chflags(SB)
+
+GLOBL	·libc_chflags_trampoline_addr(SB), RODATA, $4
+DATA	·libc_chflags_trampoline_addr(SB)/4, $libc_chflags_trampoline<>(SB)
+
+TEXT libc_chmod_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_chmod(SB)
+
+GLOBL	·libc_chmod_trampoline_addr(SB), RODATA, $4
+DATA	·libc_chmod_trampoline_addr(SB)/4, $libc_chmod_trampoline<>(SB)
+
+TEXT libc_chown_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_chown(SB)
+
+GLOBL	·libc_chown_trampoline_addr(SB), RODATA, $4
+DATA	·libc_chown_trampoline_addr(SB)/4, $libc_chown_trampoline<>(SB)
+
+TEXT libc_chroot_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_chroot(SB)
+
+GLOBL	·libc_chroot_trampoline_addr(SB), RODATA, $4
+DATA	·libc_chroot_trampoline_addr(SB)/4, $libc_chroot_trampoline<>(SB)
+
+TEXT libc_close_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_close(SB)
+
+GLOBL	·libc_close_trampoline_addr(SB), RODATA, $4
+DATA	·libc_close_trampoline_addr(SB)/4, $libc_close_trampoline<>(SB)
+
+TEXT libc_dup_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_dup(SB)
+
+GLOBL	·libc_dup_trampoline_addr(SB), RODATA, $4
+DATA	·libc_dup_trampoline_addr(SB)/4, $libc_dup_trampoline<>(SB)
+
+TEXT libc_dup2_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_dup2(SB)
+
+GLOBL	·libc_dup2_trampoline_addr(SB), RODATA, $4
+DATA	·libc_dup2_trampoline_addr(SB)/4, $libc_dup2_trampoline<>(SB)
+
+TEXT libc_dup3_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_dup3(SB)
+
+GLOBL	·libc_dup3_trampoline_addr(SB), RODATA, $4
+DATA	·libc_dup3_trampoline_addr(SB)/4, $libc_dup3_trampoline<>(SB)
+
+TEXT libc_exit_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_exit(SB)
+
+GLOBL	·libc_exit_trampoline_addr(SB), RODATA, $4
+DATA	·libc_exit_trampoline_addr(SB)/4, $libc_exit_trampoline<>(SB)
+
+TEXT libc_faccessat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_faccessat(SB)
+
+GLOBL	·libc_faccessat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_faccessat_trampoline_addr(SB)/4, $libc_faccessat_trampoline<>(SB)
+
+TEXT libc_fchdir_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fchdir(SB)
+
+GLOBL	·libc_fchdir_trampoline_addr(SB), RODATA, $4
+DATA	·libc_fchdir_trampoline_addr(SB)/4, $libc_fchdir_trampoline<>(SB)
+
+TEXT libc_fchflags_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fchflags(SB)
+
+GLOBL	·libc_fchflags_trampoline_addr(SB), RODATA, $4
+DATA	·libc_fchflags_trampoline_addr(SB)/4, $libc_fchflags_trampoline<>(SB)
+
+TEXT libc_fchmod_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fchmod(SB)
+
+GLOBL	·libc_fchmod_trampoline_addr(SB), RODATA, $4
+DATA	·libc_fchmod_trampoline_addr(SB)/4, $libc_fchmod_trampoline<>(SB)
+
+TEXT libc_fchmodat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fchmodat(SB)
+
+GLOBL	·libc_fchmodat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_fchmodat_trampoline_addr(SB)/4, $libc_fchmodat_trampoline<>(SB)
+
+TEXT libc_fchown_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fchown(SB)
+
+GLOBL	·libc_fchown_trampoline_addr(SB), RODATA, $4
+DATA	·libc_fchown_trampoline_addr(SB)/4, $libc_fchown_trampoline<>(SB)
+
+TEXT libc_fchownat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fchownat(SB)
+
+GLOBL	·libc_fchownat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_fchownat_trampoline_addr(SB)/4, $libc_fchownat_trampoline<>(SB)
+
+TEXT libc_flock_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_flock(SB)
+
+GLOBL	·libc_flock_trampoline_addr(SB), RODATA, $4
+DATA	·libc_flock_trampoline_addr(SB)/4, $libc_flock_trampoline<>(SB)
+
+TEXT libc_fpathconf_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fpathconf(SB)
+
+GLOBL	·libc_fpathconf_trampoline_addr(SB), RODATA, $4
+DATA	·libc_fpathconf_trampoline_addr(SB)/4, $libc_fpathconf_trampoline<>(SB)
+
+TEXT libc_fstat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fstat(SB)
+
+GLOBL	·libc_fstat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_fstat_trampoline_addr(SB)/4, $libc_fstat_trampoline<>(SB)
+
+TEXT libc_fstatat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fstatat(SB)
+
+GLOBL	·libc_fstatat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_fstatat_trampoline_addr(SB)/4, $libc_fstatat_trampoline<>(SB)
+
+TEXT libc_fstatfs_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fstatfs(SB)
+
+GLOBL	·libc_fstatfs_trampoline_addr(SB), RODATA, $4
+DATA	·libc_fstatfs_trampoline_addr(SB)/4, $libc_fstatfs_trampoline<>(SB)
+
+TEXT libc_fsync_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fsync(SB)
+
+GLOBL	·libc_fsync_trampoline_addr(SB), RODATA, $4
+DATA	·libc_fsync_trampoline_addr(SB)/4, $libc_fsync_trampoline<>(SB)
+
+TEXT libc_ftruncate_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_ftruncate(SB)
+
+GLOBL	·libc_ftruncate_trampoline_addr(SB), RODATA, $4
+DATA	·libc_ftruncate_trampoline_addr(SB)/4, $libc_ftruncate_trampoline<>(SB)
+
+TEXT libc_getegid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getegid(SB)
+
+GLOBL	·libc_getegid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getegid_trampoline_addr(SB)/4, $libc_getegid_trampoline<>(SB)
+
+TEXT libc_geteuid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_geteuid(SB)
+
+GLOBL	·libc_geteuid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_geteuid_trampoline_addr(SB)/4, $libc_geteuid_trampoline<>(SB)
+
+TEXT libc_getgid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getgid(SB)
+
+GLOBL	·libc_getgid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getgid_trampoline_addr(SB)/4, $libc_getgid_trampoline<>(SB)
+
+TEXT libc_getpgid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getpgid(SB)
+
+GLOBL	·libc_getpgid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getpgid_trampoline_addr(SB)/4, $libc_getpgid_trampoline<>(SB)
+
+TEXT libc_getpgrp_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getpgrp(SB)
+
+GLOBL	·libc_getpgrp_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getpgrp_trampoline_addr(SB)/4, $libc_getpgrp_trampoline<>(SB)
+
+TEXT libc_getpid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getpid(SB)
+
+GLOBL	·libc_getpid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getpid_trampoline_addr(SB)/4, $libc_getpid_trampoline<>(SB)
+
+TEXT libc_getppid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getppid(SB)
+
+GLOBL	·libc_getppid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getppid_trampoline_addr(SB)/4, $libc_getppid_trampoline<>(SB)
+
+TEXT libc_getpriority_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getpriority(SB)
+
+GLOBL	·libc_getpriority_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getpriority_trampoline_addr(SB)/4, $libc_getpriority_trampoline<>(SB)
+
+TEXT libc_getrlimit_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getrlimit(SB)
+
+GLOBL	·libc_getrlimit_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getrlimit_trampoline_addr(SB)/4, $libc_getrlimit_trampoline<>(SB)
+
+TEXT libc_getrtable_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getrtable(SB)
+
+GLOBL	·libc_getrtable_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getrtable_trampoline_addr(SB)/4, $libc_getrtable_trampoline<>(SB)
+
+TEXT libc_getrusage_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getrusage(SB)
+
+GLOBL	·libc_getrusage_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getrusage_trampoline_addr(SB)/4, $libc_getrusage_trampoline<>(SB)
+
+TEXT libc_getsid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getsid(SB)
+
+GLOBL	·libc_getsid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getsid_trampoline_addr(SB)/4, $libc_getsid_trampoline<>(SB)
+
+TEXT libc_gettimeofday_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_gettimeofday(SB)
+
+GLOBL	·libc_gettimeofday_trampoline_addr(SB), RODATA, $4
+DATA	·libc_gettimeofday_trampoline_addr(SB)/4, $libc_gettimeofday_trampoline<>(SB)
+
+TEXT libc_getuid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getuid(SB)
+
+GLOBL	·libc_getuid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_getuid_trampoline_addr(SB)/4, $libc_getuid_trampoline<>(SB)
+
+TEXT libc_issetugid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_issetugid(SB)
+
+GLOBL	·libc_issetugid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_issetugid_trampoline_addr(SB)/4, $libc_issetugid_trampoline<>(SB)
+
+TEXT libc_kill_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_kill(SB)
+
+GLOBL	·libc_kill_trampoline_addr(SB), RODATA, $4
+DATA	·libc_kill_trampoline_addr(SB)/4, $libc_kill_trampoline<>(SB)
+
+TEXT libc_kqueue_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_kqueue(SB)
+
+GLOBL	·libc_kqueue_trampoline_addr(SB), RODATA, $4
+DATA	·libc_kqueue_trampoline_addr(SB)/4, $libc_kqueue_trampoline<>(SB)
+
+TEXT libc_lchown_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_lchown(SB)
+
+GLOBL	·libc_lchown_trampoline_addr(SB), RODATA, $4
+DATA	·libc_lchown_trampoline_addr(SB)/4, $libc_lchown_trampoline<>(SB)
+
+TEXT libc_link_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_link(SB)
+
+GLOBL	·libc_link_trampoline_addr(SB), RODATA, $4
+DATA	·libc_link_trampoline_addr(SB)/4, $libc_link_trampoline<>(SB)
+
+TEXT libc_linkat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_linkat(SB)
+
+GLOBL	·libc_linkat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_linkat_trampoline_addr(SB)/4, $libc_linkat_trampoline<>(SB)
+
+TEXT libc_listen_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_listen(SB)
+
+GLOBL	·libc_listen_trampoline_addr(SB), RODATA, $4
+DATA	·libc_listen_trampoline_addr(SB)/4, $libc_listen_trampoline<>(SB)
+
+TEXT libc_lstat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_lstat(SB)
+
+GLOBL	·libc_lstat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_lstat_trampoline_addr(SB)/4, $libc_lstat_trampoline<>(SB)
+
+TEXT libc_mkdir_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mkdir(SB)
+
+GLOBL	·libc_mkdir_trampoline_addr(SB), RODATA, $4
+DATA	·libc_mkdir_trampoline_addr(SB)/4, $libc_mkdir_trampoline<>(SB)
+
+TEXT libc_mkdirat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mkdirat(SB)
+
+GLOBL	·libc_mkdirat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_mkdirat_trampoline_addr(SB)/4, $libc_mkdirat_trampoline<>(SB)
+
+TEXT libc_mkfifo_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mkfifo(SB)
+
+GLOBL	·libc_mkfifo_trampoline_addr(SB), RODATA, $4
+DATA	·libc_mkfifo_trampoline_addr(SB)/4, $libc_mkfifo_trampoline<>(SB)
+
+TEXT libc_mkfifoat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mkfifoat(SB)
+
+GLOBL	·libc_mkfifoat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_mkfifoat_trampoline_addr(SB)/4, $libc_mkfifoat_trampoline<>(SB)
+
+TEXT libc_mknod_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mknod(SB)
+
+GLOBL	·libc_mknod_trampoline_addr(SB), RODATA, $4
+DATA	·libc_mknod_trampoline_addr(SB)/4, $libc_mknod_trampoline<>(SB)
+
+TEXT libc_mknodat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mknodat(SB)
+
+GLOBL	·libc_mknodat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_mknodat_trampoline_addr(SB)/4, $libc_mknodat_trampoline<>(SB)
+
+TEXT libc_nanosleep_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_nanosleep(SB)
+
+GLOBL	·libc_nanosleep_trampoline_addr(SB), RODATA, $4
+DATA	·libc_nanosleep_trampoline_addr(SB)/4, $libc_nanosleep_trampoline<>(SB)
+
+TEXT libc_open_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_open(SB)
+
+GLOBL	·libc_open_trampoline_addr(SB), RODATA, $4
+DATA	·libc_open_trampoline_addr(SB)/4, $libc_open_trampoline<>(SB)
+
+TEXT libc_openat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_openat(SB)
+
+GLOBL	·libc_openat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_openat_trampoline_addr(SB)/4, $libc_openat_trampoline<>(SB)
+
+TEXT libc_pathconf_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_pathconf(SB)
+
+GLOBL	·libc_pathconf_trampoline_addr(SB), RODATA, $4
+DATA	·libc_pathconf_trampoline_addr(SB)/4, $libc_pathconf_trampoline<>(SB)
+
+TEXT libc_pread_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_pread(SB)
+
+GLOBL	·libc_pread_trampoline_addr(SB), RODATA, $4
+DATA	·libc_pread_trampoline_addr(SB)/4, $libc_pread_trampoline<>(SB)
+
+TEXT libc_pwrite_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_pwrite(SB)
+
+GLOBL	·libc_pwrite_trampoline_addr(SB), RODATA, $4
+DATA	·libc_pwrite_trampoline_addr(SB)/4, $libc_pwrite_trampoline<>(SB)
+
+TEXT libc_read_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_read(SB)
+
+GLOBL	·libc_read_trampoline_addr(SB), RODATA, $4
+DATA	·libc_read_trampoline_addr(SB)/4, $libc_read_trampoline<>(SB)
+
+TEXT libc_readlink_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_readlink(SB)
+
+GLOBL	·libc_readlink_trampoline_addr(SB), RODATA, $4
+DATA	·libc_readlink_trampoline_addr(SB)/4, $libc_readlink_trampoline<>(SB)
+
+TEXT libc_readlinkat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_readlinkat(SB)
+
+GLOBL	·libc_readlinkat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_readlinkat_trampoline_addr(SB)/4, $libc_readlinkat_trampoline<>(SB)
+
+TEXT libc_rename_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_rename(SB)
+
+GLOBL	·libc_rename_trampoline_addr(SB), RODATA, $4
+DATA	·libc_rename_trampoline_addr(SB)/4, $libc_rename_trampoline<>(SB)
+
+TEXT libc_renameat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_renameat(SB)
+
+GLOBL	·libc_renameat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_renameat_trampoline_addr(SB)/4, $libc_renameat_trampoline<>(SB)
+
+TEXT libc_revoke_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_revoke(SB)
+
+GLOBL	·libc_revoke_trampoline_addr(SB), RODATA, $4
+DATA	·libc_revoke_trampoline_addr(SB)/4, $libc_revoke_trampoline<>(SB)
+
+TEXT libc_rmdir_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_rmdir(SB)
+
+GLOBL	·libc_rmdir_trampoline_addr(SB), RODATA, $4
+DATA	·libc_rmdir_trampoline_addr(SB)/4, $libc_rmdir_trampoline<>(SB)
+
+TEXT libc_lseek_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_lseek(SB)
+
+GLOBL	·libc_lseek_trampoline_addr(SB), RODATA, $4
+DATA	·libc_lseek_trampoline_addr(SB)/4, $libc_lseek_trampoline<>(SB)
+
+TEXT libc_select_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_select(SB)
+
+GLOBL	·libc_select_trampoline_addr(SB), RODATA, $4
+DATA	·libc_select_trampoline_addr(SB)/4, $libc_select_trampoline<>(SB)
+
+TEXT libc_setegid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setegid(SB)
+
+GLOBL	·libc_setegid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setegid_trampoline_addr(SB)/4, $libc_setegid_trampoline<>(SB)
+
+TEXT libc_seteuid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_seteuid(SB)
+
+GLOBL	·libc_seteuid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_seteuid_trampoline_addr(SB)/4, $libc_seteuid_trampoline<>(SB)
+
+TEXT libc_setgid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setgid(SB)
+
+GLOBL	·libc_setgid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setgid_trampoline_addr(SB)/4, $libc_setgid_trampoline<>(SB)
+
+TEXT libc_setlogin_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setlogin(SB)
+
+GLOBL	·libc_setlogin_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setlogin_trampoline_addr(SB)/4, $libc_setlogin_trampoline<>(SB)
+
+TEXT libc_setpgid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setpgid(SB)
+
+GLOBL	·libc_setpgid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setpgid_trampoline_addr(SB)/4, $libc_setpgid_trampoline<>(SB)
+
+TEXT libc_setpriority_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setpriority(SB)
+
+GLOBL	·libc_setpriority_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setpriority_trampoline_addr(SB)/4, $libc_setpriority_trampoline<>(SB)
+
+TEXT libc_setregid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setregid(SB)
+
+GLOBL	·libc_setregid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setregid_trampoline_addr(SB)/4, $libc_setregid_trampoline<>(SB)
+
+TEXT libc_setreuid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setreuid(SB)
+
+GLOBL	·libc_setreuid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setreuid_trampoline_addr(SB)/4, $libc_setreuid_trampoline<>(SB)
+
+TEXT libc_setresgid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setresgid(SB)
+
+GLOBL	·libc_setresgid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setresgid_trampoline_addr(SB)/4, $libc_setresgid_trampoline<>(SB)
+
+TEXT libc_setresuid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setresuid(SB)
+
+GLOBL	·libc_setresuid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setresuid_trampoline_addr(SB)/4, $libc_setresuid_trampoline<>(SB)
+
+TEXT libc_setrlimit_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setrlimit(SB)
+
+GLOBL	·libc_setrlimit_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setrlimit_trampoline_addr(SB)/4, $libc_setrlimit_trampoline<>(SB)
+
+TEXT libc_setrtable_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setrtable(SB)
+
+GLOBL	·libc_setrtable_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setrtable_trampoline_addr(SB)/4, $libc_setrtable_trampoline<>(SB)
+
+TEXT libc_setsid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setsid(SB)
+
+GLOBL	·libc_setsid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setsid_trampoline_addr(SB)/4, $libc_setsid_trampoline<>(SB)
+
+TEXT libc_settimeofday_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_settimeofday(SB)
+
+GLOBL	·libc_settimeofday_trampoline_addr(SB), RODATA, $4
+DATA	·libc_settimeofday_trampoline_addr(SB)/4, $libc_settimeofday_trampoline<>(SB)
+
+TEXT libc_setuid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setuid(SB)
+
+GLOBL	·libc_setuid_trampoline_addr(SB), RODATA, $4
+DATA	·libc_setuid_trampoline_addr(SB)/4, $libc_setuid_trampoline<>(SB)
+
+TEXT libc_stat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_stat(SB)
+
+GLOBL	·libc_stat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_stat_trampoline_addr(SB)/4, $libc_stat_trampoline<>(SB)
+
+TEXT libc_statfs_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_statfs(SB)
+
+GLOBL	·libc_statfs_trampoline_addr(SB), RODATA, $4
+DATA	·libc_statfs_trampoline_addr(SB)/4, $libc_statfs_trampoline<>(SB)
+
+TEXT libc_symlink_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_symlink(SB)
+
+GLOBL	·libc_symlink_trampoline_addr(SB), RODATA, $4
+DATA	·libc_symlink_trampoline_addr(SB)/4, $libc_symlink_trampoline<>(SB)
+
+TEXT libc_symlinkat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_symlinkat(SB)
+
+GLOBL	·libc_symlinkat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_symlinkat_trampoline_addr(SB)/4, $libc_symlinkat_trampoline<>(SB)
+
+TEXT libc_sync_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_sync(SB)
+
+GLOBL	·libc_sync_trampoline_addr(SB), RODATA, $4
+DATA	·libc_sync_trampoline_addr(SB)/4, $libc_sync_trampoline<>(SB)
+
+TEXT libc_truncate_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_truncate(SB)
+
+GLOBL	·libc_truncate_trampoline_addr(SB), RODATA, $4
+DATA	·libc_truncate_trampoline_addr(SB)/4, $libc_truncate_trampoline<>(SB)
+
+TEXT libc_umask_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_umask(SB)
+
+GLOBL	·libc_umask_trampoline_addr(SB), RODATA, $4
+DATA	·libc_umask_trampoline_addr(SB)/4, $libc_umask_trampoline<>(SB)
+
+TEXT libc_unlink_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_unlink(SB)
+
+GLOBL	·libc_unlink_trampoline_addr(SB), RODATA, $4
+DATA	·libc_unlink_trampoline_addr(SB)/4, $libc_unlink_trampoline<>(SB)
+
+TEXT libc_unlinkat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_unlinkat(SB)
+
+GLOBL	·libc_unlinkat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_unlinkat_trampoline_addr(SB)/4, $libc_unlinkat_trampoline<>(SB)
+
+TEXT libc_unmount_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_unmount(SB)
+
+GLOBL	·libc_unmount_trampoline_addr(SB), RODATA, $4
+DATA	·libc_unmount_trampoline_addr(SB)/4, $libc_unmount_trampoline<>(SB)
+
+TEXT libc_write_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_write(SB)
+
+GLOBL	·libc_write_trampoline_addr(SB), RODATA, $4
+DATA	·libc_write_trampoline_addr(SB)/4, $libc_write_trampoline<>(SB)
+
+TEXT libc_mmap_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mmap(SB)
+
+GLOBL	·libc_mmap_trampoline_addr(SB), RODATA, $4
+DATA	·libc_mmap_trampoline_addr(SB)/4, $libc_mmap_trampoline<>(SB)
+
+TEXT libc_munmap_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_munmap(SB)
+
+GLOBL	·libc_munmap_trampoline_addr(SB), RODATA, $4
+DATA	·libc_munmap_trampoline_addr(SB)/4, $libc_munmap_trampoline<>(SB)
+
+TEXT libc_utimensat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_utimensat(SB)
+
+GLOBL	·libc_utimensat_trampoline_addr(SB), RODATA, $4
+DATA	·libc_utimensat_trampoline_addr(SB)/4, $libc_utimensat_trampoline<>(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go
index c96a505..800aab6 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go
@@ -1,4 +1,4 @@
-// go run mksyscall.go -openbsd -tags openbsd,arm64 syscall_bsd.go syscall_openbsd.go syscall_openbsd_arm64.go
+// go run mksyscall.go -openbsd -libc -tags openbsd,arm64 syscall_bsd.go syscall_openbsd.go syscall_openbsd_arm64.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build openbsd && arm64
@@ -16,7 +16,7 @@
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	r0, _, e1 := syscall_rawSyscall(libc_getgroups_trampoline_addr, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -24,20 +24,28 @@
 	return
 }
 
+var libc_getgroups_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getgroups getgroups "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func setgroups(ngid int, gid *_Gid_t) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	_, _, e1 := syscall_rawSyscall(libc_setgroups_trampoline_addr, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setgroups_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setgroups setgroups "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
-	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+	r0, _, e1 := syscall_syscall6(libc_wait4_trampoline_addr, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
 	wpid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -45,10 +53,14 @@
 	return
 }
 
+var libc_wait4_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_wait4 wait4 "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	r0, _, e1 := syscall_syscall(libc_accept_trampoline_addr, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -56,30 +68,42 @@
 	return
 }
 
+var libc_accept_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_accept accept "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
+	_, _, e1 := syscall_syscall(libc_bind_trampoline_addr, uintptr(s), uintptr(addr), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_bind_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_bind bind "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
+	_, _, e1 := syscall_syscall(libc_connect_trampoline_addr, uintptr(s), uintptr(addr), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_connect_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_connect connect "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func socket(domain int, typ int, proto int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
+	r0, _, e1 := syscall_rawSyscall(libc_socket_trampoline_addr, uintptr(domain), uintptr(typ), uintptr(proto))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -87,66 +111,94 @@
 	return
 }
 
+var libc_socket_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_socket socket "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
-	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+	_, _, e1 := syscall_syscall6(libc_getsockopt_trampoline_addr, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_getsockopt_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getsockopt getsockopt "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
-	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+	_, _, e1 := syscall_syscall6(libc_setsockopt_trampoline_addr, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setsockopt_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setsockopt setsockopt "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	_, _, e1 := syscall_rawSyscall(libc_getpeername_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_getpeername_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getpeername getpeername "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	_, _, e1 := syscall_rawSyscall(libc_getsockname_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_getsockname_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getsockname getsockname "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Shutdown(s int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0)
+	_, _, e1 := syscall_syscall(libc_shutdown_trampoline_addr, uintptr(s), uintptr(how), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_shutdown_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_shutdown shutdown "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
-	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+	_, _, e1 := syscall_rawSyscall6(libc_socketpair_trampoline_addr, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_socketpair_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_socketpair socketpair "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
@@ -156,7 +208,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	r0, _, e1 := syscall_syscall6(libc_recvfrom_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -164,6 +216,10 @@
 	return
 }
 
+var libc_recvfrom_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_recvfrom recvfrom "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
@@ -173,17 +229,21 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+	_, _, e1 := syscall_syscall6(libc_sendto_trampoline_addr, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_sendto_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_sendto sendto "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	r0, _, e1 := syscall_syscall(libc_recvmsg_trampoline_addr, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -191,10 +251,14 @@
 	return
 }
 
+var libc_recvmsg_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_recvmsg recvmsg "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	r0, _, e1 := syscall_syscall(libc_sendmsg_trampoline_addr, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -202,10 +266,14 @@
 	return
 }
 
+var libc_sendmsg_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_sendmsg sendmsg "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
-	r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
+	r0, _, e1 := syscall_syscall6(libc_kevent_trampoline_addr, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -213,6 +281,10 @@
 	return
 }
 
+var libc_kevent_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_kevent kevent "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func utimes(path string, timeval *[2]Timeval) (err error) {
@@ -221,27 +293,35 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
+	_, _, e1 := syscall_syscall(libc_utimes_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_utimes_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_utimes utimes "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func futimes(fd int, timeval *[2]Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
+	_, _, e1 := syscall_syscall(libc_futimes_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_futimes_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_futimes futimes "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_POLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
+	r0, _, e1 := syscall_syscall(libc_poll_trampoline_addr, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -249,6 +329,10 @@
 	return
 }
 
+var libc_poll_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_poll poll "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Madvise(b []byte, behav int) (err error) {
@@ -258,13 +342,17 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(behav))
+	_, _, e1 := syscall_syscall(libc_madvise_trampoline_addr, uintptr(_p0), uintptr(len(b)), uintptr(behav))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_madvise_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_madvise madvise "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mlock(b []byte) (err error) {
@@ -274,23 +362,31 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	_, _, e1 := syscall_syscall(libc_mlock_trampoline_addr, uintptr(_p0), uintptr(len(b)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mlock_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mlock mlock "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mlockall(flags int) (err error) {
-	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
+	_, _, e1 := syscall_syscall(libc_mlockall_trampoline_addr, uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mlockall_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mlockall mlockall "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mprotect(b []byte, prot int) (err error) {
@@ -300,13 +396,17 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
+	_, _, e1 := syscall_syscall(libc_mprotect_trampoline_addr, uintptr(_p0), uintptr(len(b)), uintptr(prot))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mprotect_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mprotect mprotect "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Msync(b []byte, flags int) (err error) {
@@ -316,13 +416,17 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall(SYS_MSYNC, uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	_, _, e1 := syscall_syscall(libc_msync_trampoline_addr, uintptr(_p0), uintptr(len(b)), uintptr(flags))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_msync_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_msync msync "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Munlock(b []byte) (err error) {
@@ -332,33 +436,45 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	_, _, e1 := syscall_syscall(libc_munlock_trampoline_addr, uintptr(_p0), uintptr(len(b)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_munlock_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_munlock munlock "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Munlockall() (err error) {
-	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
+	_, _, e1 := syscall_syscall(libc_munlockall_trampoline_addr, 0, 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_munlockall_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_munlockall munlockall "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func pipe2(p *[2]_C_int, flags int) (err error) {
-	_, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
+	_, _, e1 := syscall_rawSyscall(libc_pipe2_trampoline_addr, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_pipe2_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_pipe2 pipe2 "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getdents(fd int, buf []byte) (n int, err error) {
@@ -368,7 +484,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(SYS_GETDENTS, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+	r0, _, e1 := syscall_syscall(libc_getdents_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -376,6 +492,10 @@
 	return
 }
 
+var libc_getdents_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getdents getdents "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getcwd(buf []byte) (n int, err error) {
@@ -385,7 +505,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(SYS___GETCWD, uintptr(_p0), uintptr(len(buf)), 0)
+	r0, _, e1 := syscall_syscall(libc_getcwd_trampoline_addr, uintptr(_p0), uintptr(len(buf)), 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -393,16 +513,24 @@
 	return
 }
 
+var libc_getcwd_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getcwd getcwd "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func ioctl(fd int, req uint, arg uintptr) (err error) {
-	_, _, e1 := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg))
+	_, _, e1 := syscall_syscall(libc_ioctl_trampoline_addr, uintptr(fd), uintptr(req), uintptr(arg))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_ioctl_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_ioctl ioctl "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
@@ -412,17 +540,21 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
+	_, _, e1 := syscall_syscall6(libc_sysctl_trampoline_addr, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_sysctl_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_sysctl sysctl "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
-	r0, _, e1 := Syscall6(SYS_PPOLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0)
+	r0, _, e1 := syscall_syscall6(libc_ppoll_trampoline_addr, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -430,6 +562,10 @@
 	return
 }
 
+var libc_ppoll_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_ppoll ppoll "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Access(path string, mode uint32) (err error) {
@@ -438,23 +574,31 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall_syscall(libc_access_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_access_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_access access "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
+	_, _, e1 := syscall_syscall(libc_adjtime_trampoline_addr, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_adjtime_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_adjtime adjtime "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Chdir(path string) (err error) {
@@ -463,13 +607,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_chdir_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_chdir_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_chdir chdir "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Chflags(path string, flags int) (err error) {
@@ -478,13 +626,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	_, _, e1 := syscall_syscall(libc_chflags_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_chflags_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_chflags chflags "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Chmod(path string, mode uint32) (err error) {
@@ -493,13 +645,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall_syscall(libc_chmod_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_chmod_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_chmod chmod "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Chown(path string, uid int, gid int) (err error) {
@@ -508,13 +664,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall_syscall(libc_chown_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_chown_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_chown chown "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Chroot(path string) (err error) {
@@ -523,27 +683,35 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_chroot_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_chroot_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_chroot chroot "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Close(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+	_, _, e1 := syscall_syscall(libc_close_trampoline_addr, uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_close_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_close close "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Dup(fd int) (nfd int, err error) {
-	r0, _, e1 := Syscall(SYS_DUP, uintptr(fd), 0, 0)
+	r0, _, e1 := syscall_syscall(libc_dup_trampoline_addr, uintptr(fd), 0, 0)
 	nfd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -551,33 +719,49 @@
 	return
 }
 
+var libc_dup_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_dup dup "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Dup2(from int, to int) (err error) {
-	_, _, e1 := Syscall(SYS_DUP2, uintptr(from), uintptr(to), 0)
+	_, _, e1 := syscall_syscall(libc_dup2_trampoline_addr, uintptr(from), uintptr(to), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_dup2_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_dup2 dup2 "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Dup3(from int, to int, flags int) (err error) {
-	_, _, e1 := Syscall(SYS_DUP3, uintptr(from), uintptr(to), uintptr(flags))
+	_, _, e1 := syscall_syscall(libc_dup3_trampoline_addr, uintptr(from), uintptr(to), uintptr(flags))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_dup3_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_dup3 dup3 "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Exit(code int) {
-	Syscall(SYS_EXIT, uintptr(code), 0, 0)
+	syscall_syscall(libc_exit_trampoline_addr, uintptr(code), 0, 0)
 	return
 }
 
+var libc_exit_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_exit exit "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
@@ -586,43 +770,59 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_faccessat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_faccessat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_faccessat faccessat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchdir(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
+	_, _, e1 := syscall_syscall(libc_fchdir_trampoline_addr, uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fchdir_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchdir fchdir "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchflags(fd int, flags int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0)
+	_, _, e1 := syscall_syscall(libc_fchflags_trampoline_addr, uintptr(fd), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fchflags_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchflags fchflags "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchmod(fd int, mode uint32) (err error) {
-	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
+	_, _, e1 := syscall_syscall(libc_fchmod_trampoline_addr, uintptr(fd), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fchmod_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchmod fchmod "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
@@ -631,23 +831,31 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_fchmodat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fchmodat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchmodat fchmodat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchown(fd int, uid int, gid int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall_syscall(libc_fchown_trampoline_addr, uintptr(fd), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fchown_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchown fchown "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) {
@@ -656,27 +864,35 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_FCHOWNAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
+	_, _, e1 := syscall_syscall6(libc_fchownat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fchownat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchownat fchownat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Flock(fd int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
+	_, _, e1 := syscall_syscall(libc_flock_trampoline_addr, uintptr(fd), uintptr(how), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_flock_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_flock flock "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fpathconf(fd int, name int) (val int, err error) {
-	r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0)
+	r0, _, e1 := syscall_syscall(libc_fpathconf_trampoline_addr, uintptr(fd), uintptr(name), 0)
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -684,16 +900,24 @@
 	return
 }
 
+var libc_fpathconf_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fpathconf fpathconf "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fstat(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall_syscall(libc_fstat_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fstat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fstat fstat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) {
@@ -702,71 +926,99 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_fstatat_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fstatat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fstatat fstatat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fstatfs(fd int, stat *Statfs_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall_syscall(libc_fstatfs_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fstatfs_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fstatfs fstatfs "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Fsync(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
+	_, _, e1 := syscall_syscall(libc_fsync_trampoline_addr, uintptr(fd), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_fsync_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fsync fsync "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Ftruncate(fd int, length int64) (err error) {
-	_, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), 0, uintptr(length))
+	_, _, e1 := syscall_syscall(libc_ftruncate_trampoline_addr, uintptr(fd), uintptr(length), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_ftruncate_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_ftruncate ftruncate "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getegid() (egid int) {
-	r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getegid_trampoline_addr, 0, 0, 0)
 	egid = int(r0)
 	return
 }
 
+var libc_getegid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getegid getegid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Geteuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_geteuid_trampoline_addr, 0, 0, 0)
 	uid = int(r0)
 	return
 }
 
+var libc_geteuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_geteuid geteuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getgid() (gid int) {
-	r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getgid_trampoline_addr, 0, 0, 0)
 	gid = int(r0)
 	return
 }
 
+var libc_getgid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getgid getgid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpgid(pid int) (pgid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
+	r0, _, e1 := syscall_rawSyscall(libc_getpgid_trampoline_addr, uintptr(pid), 0, 0)
 	pgid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -774,34 +1026,50 @@
 	return
 }
 
+var libc_getpgid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getpgid getpgid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpgrp() (pgrp int) {
-	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getpgrp_trampoline_addr, 0, 0, 0)
 	pgrp = int(r0)
 	return
 }
 
+var libc_getpgrp_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getpgrp getpgrp "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpid() (pid int) {
-	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getpid_trampoline_addr, 0, 0, 0)
 	pid = int(r0)
 	return
 }
 
+var libc_getpid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getpid getpid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getppid() (ppid int) {
-	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getppid_trampoline_addr, 0, 0, 0)
 	ppid = int(r0)
 	return
 }
 
+var libc_getppid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getppid getppid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getpriority(which int, who int) (prio int, err error) {
-	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
+	r0, _, e1 := syscall_syscall(libc_getpriority_trampoline_addr, uintptr(which), uintptr(who), 0)
 	prio = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -809,20 +1077,28 @@
 	return
 }
 
+var libc_getpriority_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getpriority getpriority "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	_, _, e1 := syscall_rawSyscall(libc_getrlimit_trampoline_addr, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_getrlimit_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getrlimit getrlimit "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getrtable() (rtable int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETRTABLE, 0, 0, 0)
+	r0, _, e1 := syscall_rawSyscall(libc_getrtable_trampoline_addr, 0, 0, 0)
 	rtable = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -830,20 +1106,28 @@
 	return
 }
 
+var libc_getrtable_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getrtable getrtable "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getrusage(who int, rusage *Rusage) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+	_, _, e1 := syscall_rawSyscall(libc_getrusage_trampoline_addr, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_getrusage_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getrusage getrusage "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getsid(pid int) (sid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0)
+	r0, _, e1 := syscall_rawSyscall(libc_getsid_trampoline_addr, uintptr(pid), 0, 0)
 	sid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -851,46 +1135,66 @@
 	return
 }
 
+var libc_getsid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getsid getsid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Gettimeofday(tv *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_gettimeofday_trampoline_addr, uintptr(unsafe.Pointer(tv)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_gettimeofday_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_gettimeofday gettimeofday "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Getuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
+	r0, _, _ := syscall_rawSyscall(libc_getuid_trampoline_addr, 0, 0, 0)
 	uid = int(r0)
 	return
 }
 
+var libc_getuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getuid getuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Issetugid() (tainted bool) {
-	r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0)
+	r0, _, _ := syscall_syscall(libc_issetugid_trampoline_addr, 0, 0, 0)
 	tainted = bool(r0 != 0)
 	return
 }
 
+var libc_issetugid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_issetugid issetugid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Kill(pid int, signum syscall.Signal) (err error) {
-	_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), 0)
+	_, _, e1 := syscall_syscall(libc_kill_trampoline_addr, uintptr(pid), uintptr(signum), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_kill_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_kill kill "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Kqueue() (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0)
+	r0, _, e1 := syscall_syscall(libc_kqueue_trampoline_addr, 0, 0, 0)
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -898,6 +1202,10 @@
 	return
 }
 
+var libc_kqueue_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_kqueue kqueue "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Lchown(path string, uid int, gid int) (err error) {
@@ -906,13 +1214,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	_, _, e1 := syscall_syscall(libc_lchown_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_lchown_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_lchown lchown "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Link(path string, link string) (err error) {
@@ -926,13 +1238,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall_syscall(libc_link_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_link_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_link link "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error) {
@@ -946,23 +1262,31 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_LINKAT, uintptr(pathfd), uintptr(unsafe.Pointer(_p0)), uintptr(linkfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
+	_, _, e1 := syscall_syscall6(libc_linkat_trampoline_addr, uintptr(pathfd), uintptr(unsafe.Pointer(_p0)), uintptr(linkfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_linkat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_linkat linkat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Listen(s int, backlog int) (err error) {
-	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
+	_, _, e1 := syscall_syscall(libc_listen_trampoline_addr, uintptr(s), uintptr(backlog), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_listen_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_listen listen "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Lstat(path string, stat *Stat_t) (err error) {
@@ -971,13 +1295,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall_syscall(libc_lstat_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_lstat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_lstat lstat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mkdir(path string, mode uint32) (err error) {
@@ -986,13 +1314,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall_syscall(libc_mkdir_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mkdir_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mkdir mkdir "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mkdirat(dirfd int, path string, mode uint32) (err error) {
@@ -1001,13 +1333,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_MKDIRAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+	_, _, e1 := syscall_syscall(libc_mkdirat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mkdirat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mkdirat mkdirat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mkfifo(path string, mode uint32) (err error) {
@@ -1016,13 +1352,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	_, _, e1 := syscall_syscall(libc_mkfifo_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mkfifo_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mkfifo mkfifo "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mkfifoat(dirfd int, path string, mode uint32) (err error) {
@@ -1031,13 +1371,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_MKFIFOAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+	_, _, e1 := syscall_syscall(libc_mkfifoat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mkfifoat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mkfifoat mkfifoat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mknod(path string, mode uint32, dev int) (err error) {
@@ -1046,13 +1390,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
+	_, _, e1 := syscall_syscall(libc_mknod_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mknod_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mknod mknod "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) {
@@ -1061,23 +1409,31 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_MKNODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_mknodat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_mknodat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mknodat mknodat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
-	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
+	_, _, e1 := syscall_syscall(libc_nanosleep_trampoline_addr, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_nanosleep_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_nanosleep nanosleep "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Open(path string, mode int, perm uint32) (fd int, err error) {
@@ -1086,7 +1442,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	r0, _, e1 := syscall_syscall(libc_open_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1094,6 +1450,10 @@
 	return
 }
 
+var libc_open_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_open open "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) {
@@ -1102,7 +1462,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0)
+	r0, _, e1 := syscall_syscall6(libc_openat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0)
 	fd = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1110,6 +1470,10 @@
 	return
 }
 
+var libc_openat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_openat openat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Pathconf(path string, name int) (val int, err error) {
@@ -1118,7 +1482,7 @@
 	if err != nil {
 		return
 	}
-	r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
+	r0, _, e1 := syscall_syscall(libc_pathconf_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
 	val = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1126,6 +1490,10 @@
 	return
 }
 
+var libc_pathconf_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_pathconf pathconf "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func pread(fd int, p []byte, offset int64) (n int, err error) {
@@ -1135,7 +1503,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), 0)
+	r0, _, e1 := syscall_syscall6(libc_pread_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1143,6 +1511,10 @@
 	return
 }
 
+var libc_pread_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_pread pread "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func pwrite(fd int, p []byte, offset int64) (n int, err error) {
@@ -1152,7 +1524,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), 0)
+	r0, _, e1 := syscall_syscall6(libc_pwrite_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1160,6 +1532,10 @@
 	return
 }
 
+var libc_pwrite_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_pwrite pwrite "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func read(fd int, p []byte) (n int, err error) {
@@ -1169,7 +1545,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	r0, _, e1 := syscall_syscall(libc_read_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1177,6 +1553,10 @@
 	return
 }
 
+var libc_read_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_read read "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Readlink(path string, buf []byte) (n int, err error) {
@@ -1191,7 +1571,7 @@
 	} else {
 		_p1 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+	r0, _, e1 := syscall_syscall(libc_readlink_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1199,6 +1579,10 @@
 	return
 }
 
+var libc_readlink_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_readlink readlink "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
@@ -1213,7 +1597,7 @@
 	} else {
 		_p1 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall6(SYS_READLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0)
+	r0, _, e1 := syscall_syscall6(libc_readlinkat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1221,6 +1605,10 @@
 	return
 }
 
+var libc_readlinkat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_readlinkat readlinkat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Rename(from string, to string) (err error) {
@@ -1234,13 +1622,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall_syscall(libc_rename_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_rename_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_rename rename "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Renameat(fromfd int, from string, tofd int, to string) (err error) {
@@ -1254,13 +1646,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_renameat_trampoline_addr, uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_renameat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_renameat renameat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Revoke(path string) (err error) {
@@ -1269,13 +1665,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_revoke_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_revoke_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_revoke revoke "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Rmdir(path string) (err error) {
@@ -1284,17 +1684,21 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_rmdir_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_rmdir_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_rmdir rmdir "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
-	r0, _, e1 := Syscall6(SYS_LSEEK, uintptr(fd), 0, uintptr(offset), uintptr(whence), 0, 0)
+	r0, _, e1 := syscall_syscall(libc_lseek_trampoline_addr, uintptr(fd), uintptr(offset), uintptr(whence))
 	newoffset = int64(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1302,10 +1706,14 @@
 	return
 }
 
+var libc_lseek_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_lseek lseek "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {
-	r0, _, e1 := Syscall6(SYS_SELECT, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+	r0, _, e1 := syscall_syscall6(libc_select_trampoline_addr, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1313,36 +1721,52 @@
 	return
 }
 
+var libc_select_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_select select "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setegid(egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETEGID, uintptr(egid), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_setegid_trampoline_addr, uintptr(egid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setegid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setegid setegid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Seteuid(euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_seteuid_trampoline_addr, uintptr(euid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_seteuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_seteuid seteuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setgid(gid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_setgid_trampoline_addr, uintptr(gid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setgid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setgid setgid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setlogin(name string) (err error) {
@@ -1351,97 +1775,133 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_setlogin_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setlogin_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setlogin setlogin "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setpgid(pid int, pgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
+	_, _, e1 := syscall_rawSyscall(libc_setpgid_trampoline_addr, uintptr(pid), uintptr(pgid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setpgid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setpgid setpgid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setpriority(which int, who int, prio int) (err error) {
-	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
+	_, _, e1 := syscall_syscall(libc_setpriority_trampoline_addr, uintptr(which), uintptr(who), uintptr(prio))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setpriority_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setpriority setpriority "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
+	_, _, e1 := syscall_rawSyscall(libc_setregid_trampoline_addr, uintptr(rgid), uintptr(egid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setregid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setregid setregid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
+	_, _, e1 := syscall_rawSyscall(libc_setreuid_trampoline_addr, uintptr(ruid), uintptr(euid), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setreuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setreuid setreuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setresgid(rgid int, egid int, sgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid))
+	_, _, e1 := syscall_rawSyscall(libc_setresgid_trampoline_addr, uintptr(rgid), uintptr(egid), uintptr(sgid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setresgid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setresgid setresgid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setresuid(ruid int, euid int, suid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid))
+	_, _, e1 := syscall_rawSyscall(libc_setresuid_trampoline_addr, uintptr(ruid), uintptr(euid), uintptr(suid))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setresuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setresuid setresuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	_, _, e1 := syscall_rawSyscall(libc_setrlimit_trampoline_addr, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setrlimit_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setrlimit setrlimit "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setrtable(rtable int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRTABLE, uintptr(rtable), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_setrtable_trampoline_addr, uintptr(rtable), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setrtable_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setrtable setrtable "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setsid() (pid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
+	r0, _, e1 := syscall_rawSyscall(libc_setsid_trampoline_addr, 0, 0, 0)
 	pid = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1449,26 +1909,38 @@
 	return
 }
 
+var libc_setsid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setsid setsid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Settimeofday(tp *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_settimeofday_trampoline_addr, uintptr(unsafe.Pointer(tp)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_settimeofday_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_settimeofday settimeofday "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Setuid(uid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0)
+	_, _, e1 := syscall_rawSyscall(libc_setuid_trampoline_addr, uintptr(uid), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_setuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setuid setuid "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Stat(path string, stat *Stat_t) (err error) {
@@ -1477,13 +1949,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall_syscall(libc_stat_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_stat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_stat stat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Statfs(path string, stat *Statfs_t) (err error) {
@@ -1492,13 +1968,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	_, _, e1 := syscall_syscall(libc_statfs_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_statfs_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_statfs statfs "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Symlink(path string, link string) (err error) {
@@ -1512,13 +1992,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	_, _, e1 := syscall_syscall(libc_symlink_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_symlink_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_symlink symlink "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) {
@@ -1532,23 +2016,31 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_SYMLINKAT, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)))
+	_, _, e1 := syscall_syscall(libc_symlinkat_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_symlinkat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_symlinkat symlinkat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Sync() (err error) {
-	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
+	_, _, e1 := syscall_syscall(libc_sync_trampoline_addr, 0, 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_sync_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_sync sync "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Truncate(path string, length int64) (err error) {
@@ -1557,21 +2049,29 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), 0, uintptr(length))
+	_, _, e1 := syscall_syscall(libc_truncate_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(length), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_truncate_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_truncate truncate "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Umask(newmask int) (oldmask int) {
-	r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0)
+	r0, _, _ := syscall_syscall(libc_umask_trampoline_addr, uintptr(newmask), 0, 0)
 	oldmask = int(r0)
 	return
 }
 
+var libc_umask_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_umask umask "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Unlink(path string) (err error) {
@@ -1580,13 +2080,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	_, _, e1 := syscall_syscall(libc_unlink_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_unlink_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_unlink unlink "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Unlinkat(dirfd int, path string, flags int) (err error) {
@@ -1595,13 +2099,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+	_, _, e1 := syscall_syscall(libc_unlinkat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_unlinkat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_unlinkat unlinkat "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func Unmount(path string, flags int) (err error) {
@@ -1610,13 +2118,17 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	_, _, e1 := syscall_syscall(libc_unmount_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_unmount_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_unmount unmount "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func write(fd int, p []byte) (n int, err error) {
@@ -1626,7 +2138,7 @@
 	} else {
 		_p0 = unsafe.Pointer(&_zero)
 	}
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	r0, _, e1 := syscall_syscall(libc_write_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1634,10 +2146,14 @@
 	return
 }
 
+var libc_write_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_write write "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
-	r0, _, e1 := Syscall9(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), 0, uintptr(pos), 0, 0)
+	r0, _, e1 := syscall_syscall6(libc_mmap_trampoline_addr, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos))
 	ret = uintptr(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1645,20 +2161,28 @@
 	return
 }
 
+var libc_mmap_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mmap mmap "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func munmap(addr uintptr, length uintptr) (err error) {
-	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
+	_, _, e1 := syscall_syscall(libc_munmap_trampoline_addr, uintptr(addr), uintptr(length), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
 
+var libc_munmap_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_munmap munmap "libc.so"
+
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	r0, _, e1 := syscall_syscall(libc_read_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1669,7 +2193,7 @@
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
 func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	r0, _, e1 := syscall_syscall(libc_write_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
 	n = int(r0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -1685,9 +2209,13 @@
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0)
+	_, _, e1 := syscall_syscall6(libc_utimensat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
 	return
 }
+
+var libc_utimensat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_utimensat utimensat "libc.so"
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.s b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.s
new file mode 100644
index 0000000..4efeff9
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.s
@@ -0,0 +1,796 @@
+// go run mkasm.go openbsd arm64
+// Code generated by the command above; DO NOT EDIT.
+
+#include "textflag.h"
+
+TEXT libc_getgroups_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getgroups(SB)
+
+GLOBL	·libc_getgroups_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getgroups_trampoline_addr(SB)/8, $libc_getgroups_trampoline<>(SB)
+
+TEXT libc_setgroups_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setgroups(SB)
+
+GLOBL	·libc_setgroups_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setgroups_trampoline_addr(SB)/8, $libc_setgroups_trampoline<>(SB)
+
+TEXT libc_wait4_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_wait4(SB)
+
+GLOBL	·libc_wait4_trampoline_addr(SB), RODATA, $8
+DATA	·libc_wait4_trampoline_addr(SB)/8, $libc_wait4_trampoline<>(SB)
+
+TEXT libc_accept_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_accept(SB)
+
+GLOBL	·libc_accept_trampoline_addr(SB), RODATA, $8
+DATA	·libc_accept_trampoline_addr(SB)/8, $libc_accept_trampoline<>(SB)
+
+TEXT libc_bind_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_bind(SB)
+
+GLOBL	·libc_bind_trampoline_addr(SB), RODATA, $8
+DATA	·libc_bind_trampoline_addr(SB)/8, $libc_bind_trampoline<>(SB)
+
+TEXT libc_connect_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_connect(SB)
+
+GLOBL	·libc_connect_trampoline_addr(SB), RODATA, $8
+DATA	·libc_connect_trampoline_addr(SB)/8, $libc_connect_trampoline<>(SB)
+
+TEXT libc_socket_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_socket(SB)
+
+GLOBL	·libc_socket_trampoline_addr(SB), RODATA, $8
+DATA	·libc_socket_trampoline_addr(SB)/8, $libc_socket_trampoline<>(SB)
+
+TEXT libc_getsockopt_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getsockopt(SB)
+
+GLOBL	·libc_getsockopt_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getsockopt_trampoline_addr(SB)/8, $libc_getsockopt_trampoline<>(SB)
+
+TEXT libc_setsockopt_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setsockopt(SB)
+
+GLOBL	·libc_setsockopt_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setsockopt_trampoline_addr(SB)/8, $libc_setsockopt_trampoline<>(SB)
+
+TEXT libc_getpeername_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getpeername(SB)
+
+GLOBL	·libc_getpeername_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getpeername_trampoline_addr(SB)/8, $libc_getpeername_trampoline<>(SB)
+
+TEXT libc_getsockname_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getsockname(SB)
+
+GLOBL	·libc_getsockname_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getsockname_trampoline_addr(SB)/8, $libc_getsockname_trampoline<>(SB)
+
+TEXT libc_shutdown_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_shutdown(SB)
+
+GLOBL	·libc_shutdown_trampoline_addr(SB), RODATA, $8
+DATA	·libc_shutdown_trampoline_addr(SB)/8, $libc_shutdown_trampoline<>(SB)
+
+TEXT libc_socketpair_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_socketpair(SB)
+
+GLOBL	·libc_socketpair_trampoline_addr(SB), RODATA, $8
+DATA	·libc_socketpair_trampoline_addr(SB)/8, $libc_socketpair_trampoline<>(SB)
+
+TEXT libc_recvfrom_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_recvfrom(SB)
+
+GLOBL	·libc_recvfrom_trampoline_addr(SB), RODATA, $8
+DATA	·libc_recvfrom_trampoline_addr(SB)/8, $libc_recvfrom_trampoline<>(SB)
+
+TEXT libc_sendto_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_sendto(SB)
+
+GLOBL	·libc_sendto_trampoline_addr(SB), RODATA, $8
+DATA	·libc_sendto_trampoline_addr(SB)/8, $libc_sendto_trampoline<>(SB)
+
+TEXT libc_recvmsg_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_recvmsg(SB)
+
+GLOBL	·libc_recvmsg_trampoline_addr(SB), RODATA, $8
+DATA	·libc_recvmsg_trampoline_addr(SB)/8, $libc_recvmsg_trampoline<>(SB)
+
+TEXT libc_sendmsg_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_sendmsg(SB)
+
+GLOBL	·libc_sendmsg_trampoline_addr(SB), RODATA, $8
+DATA	·libc_sendmsg_trampoline_addr(SB)/8, $libc_sendmsg_trampoline<>(SB)
+
+TEXT libc_kevent_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_kevent(SB)
+
+GLOBL	·libc_kevent_trampoline_addr(SB), RODATA, $8
+DATA	·libc_kevent_trampoline_addr(SB)/8, $libc_kevent_trampoline<>(SB)
+
+TEXT libc_utimes_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_utimes(SB)
+
+GLOBL	·libc_utimes_trampoline_addr(SB), RODATA, $8
+DATA	·libc_utimes_trampoline_addr(SB)/8, $libc_utimes_trampoline<>(SB)
+
+TEXT libc_futimes_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_futimes(SB)
+
+GLOBL	·libc_futimes_trampoline_addr(SB), RODATA, $8
+DATA	·libc_futimes_trampoline_addr(SB)/8, $libc_futimes_trampoline<>(SB)
+
+TEXT libc_poll_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_poll(SB)
+
+GLOBL	·libc_poll_trampoline_addr(SB), RODATA, $8
+DATA	·libc_poll_trampoline_addr(SB)/8, $libc_poll_trampoline<>(SB)
+
+TEXT libc_madvise_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_madvise(SB)
+
+GLOBL	·libc_madvise_trampoline_addr(SB), RODATA, $8
+DATA	·libc_madvise_trampoline_addr(SB)/8, $libc_madvise_trampoline<>(SB)
+
+TEXT libc_mlock_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mlock(SB)
+
+GLOBL	·libc_mlock_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mlock_trampoline_addr(SB)/8, $libc_mlock_trampoline<>(SB)
+
+TEXT libc_mlockall_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mlockall(SB)
+
+GLOBL	·libc_mlockall_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mlockall_trampoline_addr(SB)/8, $libc_mlockall_trampoline<>(SB)
+
+TEXT libc_mprotect_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mprotect(SB)
+
+GLOBL	·libc_mprotect_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mprotect_trampoline_addr(SB)/8, $libc_mprotect_trampoline<>(SB)
+
+TEXT libc_msync_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_msync(SB)
+
+GLOBL	·libc_msync_trampoline_addr(SB), RODATA, $8
+DATA	·libc_msync_trampoline_addr(SB)/8, $libc_msync_trampoline<>(SB)
+
+TEXT libc_munlock_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_munlock(SB)
+
+GLOBL	·libc_munlock_trampoline_addr(SB), RODATA, $8
+DATA	·libc_munlock_trampoline_addr(SB)/8, $libc_munlock_trampoline<>(SB)
+
+TEXT libc_munlockall_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_munlockall(SB)
+
+GLOBL	·libc_munlockall_trampoline_addr(SB), RODATA, $8
+DATA	·libc_munlockall_trampoline_addr(SB)/8, $libc_munlockall_trampoline<>(SB)
+
+TEXT libc_pipe2_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_pipe2(SB)
+
+GLOBL	·libc_pipe2_trampoline_addr(SB), RODATA, $8
+DATA	·libc_pipe2_trampoline_addr(SB)/8, $libc_pipe2_trampoline<>(SB)
+
+TEXT libc_getdents_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getdents(SB)
+
+GLOBL	·libc_getdents_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getdents_trampoline_addr(SB)/8, $libc_getdents_trampoline<>(SB)
+
+TEXT libc_getcwd_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getcwd(SB)
+
+GLOBL	·libc_getcwd_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getcwd_trampoline_addr(SB)/8, $libc_getcwd_trampoline<>(SB)
+
+TEXT libc_ioctl_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_ioctl(SB)
+
+GLOBL	·libc_ioctl_trampoline_addr(SB), RODATA, $8
+DATA	·libc_ioctl_trampoline_addr(SB)/8, $libc_ioctl_trampoline<>(SB)
+
+TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_sysctl(SB)
+
+GLOBL	·libc_sysctl_trampoline_addr(SB), RODATA, $8
+DATA	·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB)
+
+TEXT libc_ppoll_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_ppoll(SB)
+
+GLOBL	·libc_ppoll_trampoline_addr(SB), RODATA, $8
+DATA	·libc_ppoll_trampoline_addr(SB)/8, $libc_ppoll_trampoline<>(SB)
+
+TEXT libc_access_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_access(SB)
+
+GLOBL	·libc_access_trampoline_addr(SB), RODATA, $8
+DATA	·libc_access_trampoline_addr(SB)/8, $libc_access_trampoline<>(SB)
+
+TEXT libc_adjtime_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_adjtime(SB)
+
+GLOBL	·libc_adjtime_trampoline_addr(SB), RODATA, $8
+DATA	·libc_adjtime_trampoline_addr(SB)/8, $libc_adjtime_trampoline<>(SB)
+
+TEXT libc_chdir_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_chdir(SB)
+
+GLOBL	·libc_chdir_trampoline_addr(SB), RODATA, $8
+DATA	·libc_chdir_trampoline_addr(SB)/8, $libc_chdir_trampoline<>(SB)
+
+TEXT libc_chflags_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_chflags(SB)
+
+GLOBL	·libc_chflags_trampoline_addr(SB), RODATA, $8
+DATA	·libc_chflags_trampoline_addr(SB)/8, $libc_chflags_trampoline<>(SB)
+
+TEXT libc_chmod_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_chmod(SB)
+
+GLOBL	·libc_chmod_trampoline_addr(SB), RODATA, $8
+DATA	·libc_chmod_trampoline_addr(SB)/8, $libc_chmod_trampoline<>(SB)
+
+TEXT libc_chown_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_chown(SB)
+
+GLOBL	·libc_chown_trampoline_addr(SB), RODATA, $8
+DATA	·libc_chown_trampoline_addr(SB)/8, $libc_chown_trampoline<>(SB)
+
+TEXT libc_chroot_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_chroot(SB)
+
+GLOBL	·libc_chroot_trampoline_addr(SB), RODATA, $8
+DATA	·libc_chroot_trampoline_addr(SB)/8, $libc_chroot_trampoline<>(SB)
+
+TEXT libc_close_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_close(SB)
+
+GLOBL	·libc_close_trampoline_addr(SB), RODATA, $8
+DATA	·libc_close_trampoline_addr(SB)/8, $libc_close_trampoline<>(SB)
+
+TEXT libc_dup_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_dup(SB)
+
+GLOBL	·libc_dup_trampoline_addr(SB), RODATA, $8
+DATA	·libc_dup_trampoline_addr(SB)/8, $libc_dup_trampoline<>(SB)
+
+TEXT libc_dup2_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_dup2(SB)
+
+GLOBL	·libc_dup2_trampoline_addr(SB), RODATA, $8
+DATA	·libc_dup2_trampoline_addr(SB)/8, $libc_dup2_trampoline<>(SB)
+
+TEXT libc_dup3_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_dup3(SB)
+
+GLOBL	·libc_dup3_trampoline_addr(SB), RODATA, $8
+DATA	·libc_dup3_trampoline_addr(SB)/8, $libc_dup3_trampoline<>(SB)
+
+TEXT libc_exit_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_exit(SB)
+
+GLOBL	·libc_exit_trampoline_addr(SB), RODATA, $8
+DATA	·libc_exit_trampoline_addr(SB)/8, $libc_exit_trampoline<>(SB)
+
+TEXT libc_faccessat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_faccessat(SB)
+
+GLOBL	·libc_faccessat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_faccessat_trampoline_addr(SB)/8, $libc_faccessat_trampoline<>(SB)
+
+TEXT libc_fchdir_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fchdir(SB)
+
+GLOBL	·libc_fchdir_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fchdir_trampoline_addr(SB)/8, $libc_fchdir_trampoline<>(SB)
+
+TEXT libc_fchflags_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fchflags(SB)
+
+GLOBL	·libc_fchflags_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fchflags_trampoline_addr(SB)/8, $libc_fchflags_trampoline<>(SB)
+
+TEXT libc_fchmod_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fchmod(SB)
+
+GLOBL	·libc_fchmod_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fchmod_trampoline_addr(SB)/8, $libc_fchmod_trampoline<>(SB)
+
+TEXT libc_fchmodat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fchmodat(SB)
+
+GLOBL	·libc_fchmodat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fchmodat_trampoline_addr(SB)/8, $libc_fchmodat_trampoline<>(SB)
+
+TEXT libc_fchown_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fchown(SB)
+
+GLOBL	·libc_fchown_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fchown_trampoline_addr(SB)/8, $libc_fchown_trampoline<>(SB)
+
+TEXT libc_fchownat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fchownat(SB)
+
+GLOBL	·libc_fchownat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fchownat_trampoline_addr(SB)/8, $libc_fchownat_trampoline<>(SB)
+
+TEXT libc_flock_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_flock(SB)
+
+GLOBL	·libc_flock_trampoline_addr(SB), RODATA, $8
+DATA	·libc_flock_trampoline_addr(SB)/8, $libc_flock_trampoline<>(SB)
+
+TEXT libc_fpathconf_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fpathconf(SB)
+
+GLOBL	·libc_fpathconf_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fpathconf_trampoline_addr(SB)/8, $libc_fpathconf_trampoline<>(SB)
+
+TEXT libc_fstat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fstat(SB)
+
+GLOBL	·libc_fstat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fstat_trampoline_addr(SB)/8, $libc_fstat_trampoline<>(SB)
+
+TEXT libc_fstatat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fstatat(SB)
+
+GLOBL	·libc_fstatat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fstatat_trampoline_addr(SB)/8, $libc_fstatat_trampoline<>(SB)
+
+TEXT libc_fstatfs_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fstatfs(SB)
+
+GLOBL	·libc_fstatfs_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fstatfs_trampoline_addr(SB)/8, $libc_fstatfs_trampoline<>(SB)
+
+TEXT libc_fsync_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fsync(SB)
+
+GLOBL	·libc_fsync_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fsync_trampoline_addr(SB)/8, $libc_fsync_trampoline<>(SB)
+
+TEXT libc_ftruncate_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_ftruncate(SB)
+
+GLOBL	·libc_ftruncate_trampoline_addr(SB), RODATA, $8
+DATA	·libc_ftruncate_trampoline_addr(SB)/8, $libc_ftruncate_trampoline<>(SB)
+
+TEXT libc_getegid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getegid(SB)
+
+GLOBL	·libc_getegid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getegid_trampoline_addr(SB)/8, $libc_getegid_trampoline<>(SB)
+
+TEXT libc_geteuid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_geteuid(SB)
+
+GLOBL	·libc_geteuid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_geteuid_trampoline_addr(SB)/8, $libc_geteuid_trampoline<>(SB)
+
+TEXT libc_getgid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getgid(SB)
+
+GLOBL	·libc_getgid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getgid_trampoline_addr(SB)/8, $libc_getgid_trampoline<>(SB)
+
+TEXT libc_getpgid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getpgid(SB)
+
+GLOBL	·libc_getpgid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getpgid_trampoline_addr(SB)/8, $libc_getpgid_trampoline<>(SB)
+
+TEXT libc_getpgrp_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getpgrp(SB)
+
+GLOBL	·libc_getpgrp_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getpgrp_trampoline_addr(SB)/8, $libc_getpgrp_trampoline<>(SB)
+
+TEXT libc_getpid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getpid(SB)
+
+GLOBL	·libc_getpid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getpid_trampoline_addr(SB)/8, $libc_getpid_trampoline<>(SB)
+
+TEXT libc_getppid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getppid(SB)
+
+GLOBL	·libc_getppid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getppid_trampoline_addr(SB)/8, $libc_getppid_trampoline<>(SB)
+
+TEXT libc_getpriority_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getpriority(SB)
+
+GLOBL	·libc_getpriority_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getpriority_trampoline_addr(SB)/8, $libc_getpriority_trampoline<>(SB)
+
+TEXT libc_getrlimit_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getrlimit(SB)
+
+GLOBL	·libc_getrlimit_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getrlimit_trampoline_addr(SB)/8, $libc_getrlimit_trampoline<>(SB)
+
+TEXT libc_getrtable_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getrtable(SB)
+
+GLOBL	·libc_getrtable_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getrtable_trampoline_addr(SB)/8, $libc_getrtable_trampoline<>(SB)
+
+TEXT libc_getrusage_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getrusage(SB)
+
+GLOBL	·libc_getrusage_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getrusage_trampoline_addr(SB)/8, $libc_getrusage_trampoline<>(SB)
+
+TEXT libc_getsid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getsid(SB)
+
+GLOBL	·libc_getsid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getsid_trampoline_addr(SB)/8, $libc_getsid_trampoline<>(SB)
+
+TEXT libc_gettimeofday_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_gettimeofday(SB)
+
+GLOBL	·libc_gettimeofday_trampoline_addr(SB), RODATA, $8
+DATA	·libc_gettimeofday_trampoline_addr(SB)/8, $libc_gettimeofday_trampoline<>(SB)
+
+TEXT libc_getuid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getuid(SB)
+
+GLOBL	·libc_getuid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getuid_trampoline_addr(SB)/8, $libc_getuid_trampoline<>(SB)
+
+TEXT libc_issetugid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_issetugid(SB)
+
+GLOBL	·libc_issetugid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_issetugid_trampoline_addr(SB)/8, $libc_issetugid_trampoline<>(SB)
+
+TEXT libc_kill_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_kill(SB)
+
+GLOBL	·libc_kill_trampoline_addr(SB), RODATA, $8
+DATA	·libc_kill_trampoline_addr(SB)/8, $libc_kill_trampoline<>(SB)
+
+TEXT libc_kqueue_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_kqueue(SB)
+
+GLOBL	·libc_kqueue_trampoline_addr(SB), RODATA, $8
+DATA	·libc_kqueue_trampoline_addr(SB)/8, $libc_kqueue_trampoline<>(SB)
+
+TEXT libc_lchown_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_lchown(SB)
+
+GLOBL	·libc_lchown_trampoline_addr(SB), RODATA, $8
+DATA	·libc_lchown_trampoline_addr(SB)/8, $libc_lchown_trampoline<>(SB)
+
+TEXT libc_link_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_link(SB)
+
+GLOBL	·libc_link_trampoline_addr(SB), RODATA, $8
+DATA	·libc_link_trampoline_addr(SB)/8, $libc_link_trampoline<>(SB)
+
+TEXT libc_linkat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_linkat(SB)
+
+GLOBL	·libc_linkat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_linkat_trampoline_addr(SB)/8, $libc_linkat_trampoline<>(SB)
+
+TEXT libc_listen_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_listen(SB)
+
+GLOBL	·libc_listen_trampoline_addr(SB), RODATA, $8
+DATA	·libc_listen_trampoline_addr(SB)/8, $libc_listen_trampoline<>(SB)
+
+TEXT libc_lstat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_lstat(SB)
+
+GLOBL	·libc_lstat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_lstat_trampoline_addr(SB)/8, $libc_lstat_trampoline<>(SB)
+
+TEXT libc_mkdir_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mkdir(SB)
+
+GLOBL	·libc_mkdir_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mkdir_trampoline_addr(SB)/8, $libc_mkdir_trampoline<>(SB)
+
+TEXT libc_mkdirat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mkdirat(SB)
+
+GLOBL	·libc_mkdirat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mkdirat_trampoline_addr(SB)/8, $libc_mkdirat_trampoline<>(SB)
+
+TEXT libc_mkfifo_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mkfifo(SB)
+
+GLOBL	·libc_mkfifo_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mkfifo_trampoline_addr(SB)/8, $libc_mkfifo_trampoline<>(SB)
+
+TEXT libc_mkfifoat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mkfifoat(SB)
+
+GLOBL	·libc_mkfifoat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mkfifoat_trampoline_addr(SB)/8, $libc_mkfifoat_trampoline<>(SB)
+
+TEXT libc_mknod_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mknod(SB)
+
+GLOBL	·libc_mknod_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mknod_trampoline_addr(SB)/8, $libc_mknod_trampoline<>(SB)
+
+TEXT libc_mknodat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mknodat(SB)
+
+GLOBL	·libc_mknodat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mknodat_trampoline_addr(SB)/8, $libc_mknodat_trampoline<>(SB)
+
+TEXT libc_nanosleep_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_nanosleep(SB)
+
+GLOBL	·libc_nanosleep_trampoline_addr(SB), RODATA, $8
+DATA	·libc_nanosleep_trampoline_addr(SB)/8, $libc_nanosleep_trampoline<>(SB)
+
+TEXT libc_open_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_open(SB)
+
+GLOBL	·libc_open_trampoline_addr(SB), RODATA, $8
+DATA	·libc_open_trampoline_addr(SB)/8, $libc_open_trampoline<>(SB)
+
+TEXT libc_openat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_openat(SB)
+
+GLOBL	·libc_openat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_openat_trampoline_addr(SB)/8, $libc_openat_trampoline<>(SB)
+
+TEXT libc_pathconf_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_pathconf(SB)
+
+GLOBL	·libc_pathconf_trampoline_addr(SB), RODATA, $8
+DATA	·libc_pathconf_trampoline_addr(SB)/8, $libc_pathconf_trampoline<>(SB)
+
+TEXT libc_pread_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_pread(SB)
+
+GLOBL	·libc_pread_trampoline_addr(SB), RODATA, $8
+DATA	·libc_pread_trampoline_addr(SB)/8, $libc_pread_trampoline<>(SB)
+
+TEXT libc_pwrite_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_pwrite(SB)
+
+GLOBL	·libc_pwrite_trampoline_addr(SB), RODATA, $8
+DATA	·libc_pwrite_trampoline_addr(SB)/8, $libc_pwrite_trampoline<>(SB)
+
+TEXT libc_read_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_read(SB)
+
+GLOBL	·libc_read_trampoline_addr(SB), RODATA, $8
+DATA	·libc_read_trampoline_addr(SB)/8, $libc_read_trampoline<>(SB)
+
+TEXT libc_readlink_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_readlink(SB)
+
+GLOBL	·libc_readlink_trampoline_addr(SB), RODATA, $8
+DATA	·libc_readlink_trampoline_addr(SB)/8, $libc_readlink_trampoline<>(SB)
+
+TEXT libc_readlinkat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_readlinkat(SB)
+
+GLOBL	·libc_readlinkat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_readlinkat_trampoline_addr(SB)/8, $libc_readlinkat_trampoline<>(SB)
+
+TEXT libc_rename_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_rename(SB)
+
+GLOBL	·libc_rename_trampoline_addr(SB), RODATA, $8
+DATA	·libc_rename_trampoline_addr(SB)/8, $libc_rename_trampoline<>(SB)
+
+TEXT libc_renameat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_renameat(SB)
+
+GLOBL	·libc_renameat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_renameat_trampoline_addr(SB)/8, $libc_renameat_trampoline<>(SB)
+
+TEXT libc_revoke_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_revoke(SB)
+
+GLOBL	·libc_revoke_trampoline_addr(SB), RODATA, $8
+DATA	·libc_revoke_trampoline_addr(SB)/8, $libc_revoke_trampoline<>(SB)
+
+TEXT libc_rmdir_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_rmdir(SB)
+
+GLOBL	·libc_rmdir_trampoline_addr(SB), RODATA, $8
+DATA	·libc_rmdir_trampoline_addr(SB)/8, $libc_rmdir_trampoline<>(SB)
+
+TEXT libc_lseek_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_lseek(SB)
+
+GLOBL	·libc_lseek_trampoline_addr(SB), RODATA, $8
+DATA	·libc_lseek_trampoline_addr(SB)/8, $libc_lseek_trampoline<>(SB)
+
+TEXT libc_select_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_select(SB)
+
+GLOBL	·libc_select_trampoline_addr(SB), RODATA, $8
+DATA	·libc_select_trampoline_addr(SB)/8, $libc_select_trampoline<>(SB)
+
+TEXT libc_setegid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setegid(SB)
+
+GLOBL	·libc_setegid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setegid_trampoline_addr(SB)/8, $libc_setegid_trampoline<>(SB)
+
+TEXT libc_seteuid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_seteuid(SB)
+
+GLOBL	·libc_seteuid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_seteuid_trampoline_addr(SB)/8, $libc_seteuid_trampoline<>(SB)
+
+TEXT libc_setgid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setgid(SB)
+
+GLOBL	·libc_setgid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setgid_trampoline_addr(SB)/8, $libc_setgid_trampoline<>(SB)
+
+TEXT libc_setlogin_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setlogin(SB)
+
+GLOBL	·libc_setlogin_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setlogin_trampoline_addr(SB)/8, $libc_setlogin_trampoline<>(SB)
+
+TEXT libc_setpgid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setpgid(SB)
+
+GLOBL	·libc_setpgid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setpgid_trampoline_addr(SB)/8, $libc_setpgid_trampoline<>(SB)
+
+TEXT libc_setpriority_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setpriority(SB)
+
+GLOBL	·libc_setpriority_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setpriority_trampoline_addr(SB)/8, $libc_setpriority_trampoline<>(SB)
+
+TEXT libc_setregid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setregid(SB)
+
+GLOBL	·libc_setregid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setregid_trampoline_addr(SB)/8, $libc_setregid_trampoline<>(SB)
+
+TEXT libc_setreuid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setreuid(SB)
+
+GLOBL	·libc_setreuid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setreuid_trampoline_addr(SB)/8, $libc_setreuid_trampoline<>(SB)
+
+TEXT libc_setresgid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setresgid(SB)
+
+GLOBL	·libc_setresgid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setresgid_trampoline_addr(SB)/8, $libc_setresgid_trampoline<>(SB)
+
+TEXT libc_setresuid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setresuid(SB)
+
+GLOBL	·libc_setresuid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setresuid_trampoline_addr(SB)/8, $libc_setresuid_trampoline<>(SB)
+
+TEXT libc_setrlimit_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setrlimit(SB)
+
+GLOBL	·libc_setrlimit_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setrlimit_trampoline_addr(SB)/8, $libc_setrlimit_trampoline<>(SB)
+
+TEXT libc_setrtable_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setrtable(SB)
+
+GLOBL	·libc_setrtable_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setrtable_trampoline_addr(SB)/8, $libc_setrtable_trampoline<>(SB)
+
+TEXT libc_setsid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setsid(SB)
+
+GLOBL	·libc_setsid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setsid_trampoline_addr(SB)/8, $libc_setsid_trampoline<>(SB)
+
+TEXT libc_settimeofday_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_settimeofday(SB)
+
+GLOBL	·libc_settimeofday_trampoline_addr(SB), RODATA, $8
+DATA	·libc_settimeofday_trampoline_addr(SB)/8, $libc_settimeofday_trampoline<>(SB)
+
+TEXT libc_setuid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setuid(SB)
+
+GLOBL	·libc_setuid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setuid_trampoline_addr(SB)/8, $libc_setuid_trampoline<>(SB)
+
+TEXT libc_stat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_stat(SB)
+
+GLOBL	·libc_stat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_stat_trampoline_addr(SB)/8, $libc_stat_trampoline<>(SB)
+
+TEXT libc_statfs_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_statfs(SB)
+
+GLOBL	·libc_statfs_trampoline_addr(SB), RODATA, $8
+DATA	·libc_statfs_trampoline_addr(SB)/8, $libc_statfs_trampoline<>(SB)
+
+TEXT libc_symlink_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_symlink(SB)
+
+GLOBL	·libc_symlink_trampoline_addr(SB), RODATA, $8
+DATA	·libc_symlink_trampoline_addr(SB)/8, $libc_symlink_trampoline<>(SB)
+
+TEXT libc_symlinkat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_symlinkat(SB)
+
+GLOBL	·libc_symlinkat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_symlinkat_trampoline_addr(SB)/8, $libc_symlinkat_trampoline<>(SB)
+
+TEXT libc_sync_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_sync(SB)
+
+GLOBL	·libc_sync_trampoline_addr(SB), RODATA, $8
+DATA	·libc_sync_trampoline_addr(SB)/8, $libc_sync_trampoline<>(SB)
+
+TEXT libc_truncate_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_truncate(SB)
+
+GLOBL	·libc_truncate_trampoline_addr(SB), RODATA, $8
+DATA	·libc_truncate_trampoline_addr(SB)/8, $libc_truncate_trampoline<>(SB)
+
+TEXT libc_umask_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_umask(SB)
+
+GLOBL	·libc_umask_trampoline_addr(SB), RODATA, $8
+DATA	·libc_umask_trampoline_addr(SB)/8, $libc_umask_trampoline<>(SB)
+
+TEXT libc_unlink_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_unlink(SB)
+
+GLOBL	·libc_unlink_trampoline_addr(SB), RODATA, $8
+DATA	·libc_unlink_trampoline_addr(SB)/8, $libc_unlink_trampoline<>(SB)
+
+TEXT libc_unlinkat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_unlinkat(SB)
+
+GLOBL	·libc_unlinkat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_unlinkat_trampoline_addr(SB)/8, $libc_unlinkat_trampoline<>(SB)
+
+TEXT libc_unmount_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_unmount(SB)
+
+GLOBL	·libc_unmount_trampoline_addr(SB), RODATA, $8
+DATA	·libc_unmount_trampoline_addr(SB)/8, $libc_unmount_trampoline<>(SB)
+
+TEXT libc_write_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_write(SB)
+
+GLOBL	·libc_write_trampoline_addr(SB), RODATA, $8
+DATA	·libc_write_trampoline_addr(SB)/8, $libc_write_trampoline<>(SB)
+
+TEXT libc_mmap_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mmap(SB)
+
+GLOBL	·libc_mmap_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mmap_trampoline_addr(SB)/8, $libc_mmap_trampoline<>(SB)
+
+TEXT libc_munmap_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_munmap(SB)
+
+GLOBL	·libc_munmap_trampoline_addr(SB), RODATA, $8
+DATA	·libc_munmap_trampoline_addr(SB)/8, $libc_munmap_trampoline<>(SB)
+
+TEXT libc_utimensat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_utimensat(SB)
+
+GLOBL	·libc_utimensat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_utimensat_trampoline_addr(SB)/8, $libc_utimensat_trampoline<>(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go
new file mode 100644
index 0000000..c85de2d
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go
@@ -0,0 +1,2221 @@
+// go run mksyscall.go -openbsd -libc -tags openbsd,ppc64 syscall_bsd.go syscall_openbsd.go syscall_openbsd_ppc64.go
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+//go:build openbsd && ppc64
+// +build openbsd,ppc64
+
+package unix
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+var _ syscall.Errno
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
+	r0, _, e1 := syscall_rawSyscall(libc_getgroups_trampoline_addr, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_getgroups_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getgroups getgroups "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setgroups(ngid int, gid *_Gid_t) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_setgroups_trampoline_addr, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_setgroups_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setgroups setgroups "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
+	r0, _, e1 := syscall_syscall6(libc_wait4_trampoline_addr, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+	wpid = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_wait4_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_wait4 wait4 "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+	r0, _, e1 := syscall_syscall(libc_accept_trampoline_addr, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_accept_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_accept accept "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := syscall_syscall(libc_bind_trampoline_addr, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_bind_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_bind bind "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := syscall_syscall(libc_connect_trampoline_addr, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_connect_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_connect connect "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socket(domain int, typ int, proto int) (fd int, err error) {
+	r0, _, e1 := syscall_rawSyscall(libc_socket_trampoline_addr, uintptr(domain), uintptr(typ), uintptr(proto))
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_socket_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_socket socket "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
+	_, _, e1 := syscall_syscall6(libc_getsockopt_trampoline_addr, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_getsockopt_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getsockopt getsockopt "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
+	_, _, e1 := syscall_syscall6(libc_setsockopt_trampoline_addr, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_setsockopt_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setsockopt setsockopt "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_getpeername_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_getpeername_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getpeername getpeername "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_getsockname_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_getsockname_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getsockname getsockname "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Shutdown(s int, how int) (err error) {
+	_, _, e1 := syscall_syscall(libc_shutdown_trampoline_addr, uintptr(s), uintptr(how), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_shutdown_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_shutdown shutdown "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
+	_, _, e1 := syscall_rawSyscall6(libc_socketpair_trampoline_addr, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_socketpair_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_socketpair socketpair "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := syscall_syscall6(libc_recvfrom_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_recvfrom_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_recvfrom recvfrom "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := syscall_syscall6(libc_sendto_trampoline_addr, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_sendto_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_sendto sendto "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := syscall_syscall(libc_recvmsg_trampoline_addr, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_recvmsg_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_recvmsg recvmsg "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := syscall_syscall(libc_sendmsg_trampoline_addr, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_sendmsg_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_sendmsg sendmsg "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
+	r0, _, e1 := syscall_syscall6(libc_kevent_trampoline_addr, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_kevent_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_kevent kevent "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimes(path string, timeval *[2]Timeval) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_utimes_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_utimes_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_utimes utimes "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func futimes(fd int, timeval *[2]Timeval) (err error) {
+	_, _, e1 := syscall_syscall(libc_futimes_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_futimes_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_futimes futimes "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
+	r0, _, e1 := syscall_syscall(libc_poll_trampoline_addr, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_poll_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_poll poll "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Madvise(b []byte, behav int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := syscall_syscall(libc_madvise_trampoline_addr, uintptr(_p0), uintptr(len(b)), uintptr(behav))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_madvise_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_madvise madvise "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := syscall_syscall(libc_mlock_trampoline_addr, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_mlock_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mlock mlock "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlockall(flags int) (err error) {
+	_, _, e1 := syscall_syscall(libc_mlockall_trampoline_addr, uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_mlockall_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mlockall mlockall "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mprotect(b []byte, prot int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := syscall_syscall(libc_mprotect_trampoline_addr, uintptr(_p0), uintptr(len(b)), uintptr(prot))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_mprotect_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mprotect mprotect "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Msync(b []byte, flags int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := syscall_syscall(libc_msync_trampoline_addr, uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_msync_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_msync msync "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := syscall_syscall(libc_munlock_trampoline_addr, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_munlock_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_munlock munlock "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlockall() (err error) {
+	_, _, e1 := syscall_syscall(libc_munlockall_trampoline_addr, 0, 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_munlockall_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_munlockall munlockall "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe2(p *[2]_C_int, flags int) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_pipe2_trampoline_addr, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_pipe2_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_pipe2 pipe2 "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getdents(fd int, buf []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := syscall_syscall(libc_getdents_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_getdents_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getdents getdents "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getcwd(buf []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := syscall_syscall(libc_getcwd_trampoline_addr, uintptr(_p0), uintptr(len(buf)), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_getcwd_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getcwd getcwd "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func ioctl(fd int, req uint, arg uintptr) (err error) {
+	_, _, e1 := syscall_syscall(libc_ioctl_trampoline_addr, uintptr(fd), uintptr(req), uintptr(arg))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_ioctl_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_ioctl ioctl "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
+	var _p0 unsafe.Pointer
+	if len(mib) > 0 {
+		_p0 = unsafe.Pointer(&mib[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := syscall_syscall6(libc_sysctl_trampoline_addr, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_sysctl_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_sysctl sysctl "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
+	r0, _, e1 := syscall_syscall6(libc_ppoll_trampoline_addr, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_ppoll_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_ppoll ppoll "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Access(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_access_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_access_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_access access "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
+	_, _, e1 := syscall_syscall(libc_adjtime_trampoline_addr, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_adjtime_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_adjtime adjtime "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_chdir_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_chdir_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_chdir chdir "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chflags(path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_chflags_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_chflags_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_chflags chflags "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chmod(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_chmod_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_chmod_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_chmod chmod "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_chown_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_chown_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_chown chown "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chroot(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_chroot_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_chroot_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_chroot chroot "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Close(fd int) (err error) {
+	_, _, e1 := syscall_syscall(libc_close_trampoline_addr, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_close_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_close close "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup(fd int) (nfd int, err error) {
+	r0, _, e1 := syscall_syscall(libc_dup_trampoline_addr, uintptr(fd), 0, 0)
+	nfd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_dup_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_dup dup "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup2(from int, to int) (err error) {
+	_, _, e1 := syscall_syscall(libc_dup2_trampoline_addr, uintptr(from), uintptr(to), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_dup2_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_dup2 dup2 "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup3(from int, to int, flags int) (err error) {
+	_, _, e1 := syscall_syscall(libc_dup3_trampoline_addr, uintptr(from), uintptr(to), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_dup3_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_dup3 dup3 "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Exit(code int) {
+	syscall_syscall(libc_exit_trampoline_addr, uintptr(code), 0, 0)
+	return
+}
+
+var libc_exit_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_exit exit "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall6(libc_faccessat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_faccessat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_faccessat faccessat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchdir(fd int) (err error) {
+	_, _, e1 := syscall_syscall(libc_fchdir_trampoline_addr, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_fchdir_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchdir fchdir "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchflags(fd int, flags int) (err error) {
+	_, _, e1 := syscall_syscall(libc_fchflags_trampoline_addr, uintptr(fd), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_fchflags_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchflags fchflags "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchmod(fd int, mode uint32) (err error) {
+	_, _, e1 := syscall_syscall(libc_fchmod_trampoline_addr, uintptr(fd), uintptr(mode), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_fchmod_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchmod fchmod "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall6(libc_fchmodat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_fchmodat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchmodat fchmodat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchown(fd int, uid int, gid int) (err error) {
+	_, _, e1 := syscall_syscall(libc_fchown_trampoline_addr, uintptr(fd), uintptr(uid), uintptr(gid))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_fchown_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchown fchown "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall6(libc_fchownat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_fchownat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchownat fchownat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Flock(fd int, how int) (err error) {
+	_, _, e1 := syscall_syscall(libc_flock_trampoline_addr, uintptr(fd), uintptr(how), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_flock_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_flock flock "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fpathconf(fd int, name int) (val int, err error) {
+	r0, _, e1 := syscall_syscall(libc_fpathconf_trampoline_addr, uintptr(fd), uintptr(name), 0)
+	val = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_fpathconf_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fpathconf fpathconf "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstat(fd int, stat *Stat_t) (err error) {
+	_, _, e1 := syscall_syscall(libc_fstat_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_fstat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fstat fstat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall6(libc_fstatat_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_fstatat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fstatat fstatat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstatfs(fd int, stat *Statfs_t) (err error) {
+	_, _, e1 := syscall_syscall(libc_fstatfs_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_fstatfs_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fstatfs fstatfs "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fsync(fd int) (err error) {
+	_, _, e1 := syscall_syscall(libc_fsync_trampoline_addr, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_fsync_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fsync fsync "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ftruncate(fd int, length int64) (err error) {
+	_, _, e1 := syscall_syscall(libc_ftruncate_trampoline_addr, uintptr(fd), uintptr(length), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_ftruncate_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_ftruncate ftruncate "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getegid() (egid int) {
+	r0, _, _ := syscall_rawSyscall(libc_getegid_trampoline_addr, 0, 0, 0)
+	egid = int(r0)
+	return
+}
+
+var libc_getegid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getegid getegid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Geteuid() (uid int) {
+	r0, _, _ := syscall_rawSyscall(libc_geteuid_trampoline_addr, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+var libc_geteuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_geteuid geteuid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getgid() (gid int) {
+	r0, _, _ := syscall_rawSyscall(libc_getgid_trampoline_addr, 0, 0, 0)
+	gid = int(r0)
+	return
+}
+
+var libc_getgid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getgid getgid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgid(pid int) (pgid int, err error) {
+	r0, _, e1 := syscall_rawSyscall(libc_getpgid_trampoline_addr, uintptr(pid), 0, 0)
+	pgid = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_getpgid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getpgid getpgid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgrp() (pgrp int) {
+	r0, _, _ := syscall_rawSyscall(libc_getpgrp_trampoline_addr, 0, 0, 0)
+	pgrp = int(r0)
+	return
+}
+
+var libc_getpgrp_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getpgrp getpgrp "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpid() (pid int) {
+	r0, _, _ := syscall_rawSyscall(libc_getpid_trampoline_addr, 0, 0, 0)
+	pid = int(r0)
+	return
+}
+
+var libc_getpid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getpid getpid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getppid() (ppid int) {
+	r0, _, _ := syscall_rawSyscall(libc_getppid_trampoline_addr, 0, 0, 0)
+	ppid = int(r0)
+	return
+}
+
+var libc_getppid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getppid getppid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpriority(which int, who int) (prio int, err error) {
+	r0, _, e1 := syscall_syscall(libc_getpriority_trampoline_addr, uintptr(which), uintptr(who), 0)
+	prio = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_getpriority_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getpriority getpriority "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrlimit(which int, lim *Rlimit) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_getrlimit_trampoline_addr, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_getrlimit_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getrlimit getrlimit "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrtable() (rtable int, err error) {
+	r0, _, e1 := syscall_rawSyscall(libc_getrtable_trampoline_addr, 0, 0, 0)
+	rtable = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_getrtable_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getrtable getrtable "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrusage(who int, rusage *Rusage) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_getrusage_trampoline_addr, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_getrusage_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getrusage getrusage "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getsid(pid int) (sid int, err error) {
+	r0, _, e1 := syscall_rawSyscall(libc_getsid_trampoline_addr, uintptr(pid), 0, 0)
+	sid = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_getsid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getsid getsid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Gettimeofday(tv *Timeval) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_gettimeofday_trampoline_addr, uintptr(unsafe.Pointer(tv)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_gettimeofday_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_gettimeofday gettimeofday "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getuid() (uid int) {
+	r0, _, _ := syscall_rawSyscall(libc_getuid_trampoline_addr, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+var libc_getuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getuid getuid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Issetugid() (tainted bool) {
+	r0, _, _ := syscall_syscall(libc_issetugid_trampoline_addr, 0, 0, 0)
+	tainted = bool(r0 != 0)
+	return
+}
+
+var libc_issetugid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_issetugid issetugid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kill(pid int, signum syscall.Signal) (err error) {
+	_, _, e1 := syscall_syscall(libc_kill_trampoline_addr, uintptr(pid), uintptr(signum), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_kill_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_kill kill "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kqueue() (fd int, err error) {
+	r0, _, e1 := syscall_syscall(libc_kqueue_trampoline_addr, 0, 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_kqueue_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_kqueue kqueue "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lchown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_lchown_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_lchown_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_lchown lchown "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Link(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_link_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_link_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_link link "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall6(libc_linkat_trampoline_addr, uintptr(pathfd), uintptr(unsafe.Pointer(_p0)), uintptr(linkfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_linkat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_linkat linkat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Listen(s int, backlog int) (err error) {
+	_, _, e1 := syscall_syscall(libc_listen_trampoline_addr, uintptr(s), uintptr(backlog), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_listen_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_listen listen "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lstat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_lstat_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_lstat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_lstat lstat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkdir(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_mkdir_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_mkdir_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mkdir mkdir "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkdirat(dirfd int, path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_mkdirat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_mkdirat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mkdirat mkdirat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkfifo(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_mkfifo_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_mkfifo_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mkfifo mkfifo "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkfifoat(dirfd int, path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_mkfifoat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_mkfifoat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mkfifoat mkfifoat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mknod(path string, mode uint32, dev int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_mknod_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_mknod_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mknod mknod "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall6(libc_mknodat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_mknodat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mknodat mknodat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
+	_, _, e1 := syscall_syscall(libc_nanosleep_trampoline_addr, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_nanosleep_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_nanosleep nanosleep "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Open(path string, mode int, perm uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := syscall_syscall(libc_open_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_open_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_open open "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := syscall_syscall6(libc_openat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_openat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_openat openat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pathconf(path string, name int) (val int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := syscall_syscall(libc_pathconf_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
+	val = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_pathconf_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_pathconf pathconf "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pread(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := syscall_syscall6(libc_pread_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_pread_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_pread pread "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pwrite(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := syscall_syscall6(libc_pwrite_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_pwrite_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_pwrite pwrite "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func read(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := syscall_syscall(libc_read_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_read_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_read read "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Readlink(path string, buf []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(buf) > 0 {
+		_p1 = unsafe.Pointer(&buf[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := syscall_syscall(libc_readlink_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_readlink_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_readlink readlink "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(buf) > 0 {
+		_p1 = unsafe.Pointer(&buf[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := syscall_syscall6(libc_readlinkat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_readlinkat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_readlinkat readlinkat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rename(from string, to string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(from)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(to)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_rename_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_rename_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_rename rename "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Renameat(fromfd int, from string, tofd int, to string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(from)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(to)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall6(libc_renameat_trampoline_addr, uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_renameat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_renameat renameat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Revoke(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_revoke_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_revoke_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_revoke revoke "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rmdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_rmdir_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_rmdir_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_rmdir rmdir "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
+	r0, _, e1 := syscall_syscall(libc_lseek_trampoline_addr, uintptr(fd), uintptr(offset), uintptr(whence))
+	newoffset = int64(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_lseek_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_lseek lseek "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {
+	r0, _, e1 := syscall_syscall6(libc_select_trampoline_addr, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_select_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_select select "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setegid(egid int) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_setegid_trampoline_addr, uintptr(egid), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_setegid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setegid setegid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seteuid(euid int) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_seteuid_trampoline_addr, uintptr(euid), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_seteuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_seteuid seteuid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setgid(gid int) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_setgid_trampoline_addr, uintptr(gid), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_setgid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setgid setgid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setlogin(name string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(name)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_setlogin_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_setlogin_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setlogin setlogin "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpgid(pid int, pgid int) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_setpgid_trampoline_addr, uintptr(pid), uintptr(pgid), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_setpgid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setpgid setpgid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpriority(which int, who int, prio int) (err error) {
+	_, _, e1 := syscall_syscall(libc_setpriority_trampoline_addr, uintptr(which), uintptr(who), uintptr(prio))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_setpriority_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setpriority setpriority "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setregid(rgid int, egid int) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_setregid_trampoline_addr, uintptr(rgid), uintptr(egid), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_setregid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setregid setregid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setreuid(ruid int, euid int) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_setreuid_trampoline_addr, uintptr(ruid), uintptr(euid), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_setreuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setreuid setreuid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setresgid(rgid int, egid int, sgid int) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_setresgid_trampoline_addr, uintptr(rgid), uintptr(egid), uintptr(sgid))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_setresgid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setresgid setresgid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setresuid(ruid int, euid int, suid int) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_setresuid_trampoline_addr, uintptr(ruid), uintptr(euid), uintptr(suid))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_setresuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setresuid setresuid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setrlimit(which int, lim *Rlimit) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_setrlimit_trampoline_addr, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_setrlimit_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setrlimit setrlimit "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setrtable(rtable int) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_setrtable_trampoline_addr, uintptr(rtable), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_setrtable_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setrtable setrtable "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setsid() (pid int, err error) {
+	r0, _, e1 := syscall_rawSyscall(libc_setsid_trampoline_addr, 0, 0, 0)
+	pid = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_setsid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setsid setsid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Settimeofday(tp *Timeval) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_settimeofday_trampoline_addr, uintptr(unsafe.Pointer(tp)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_settimeofday_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_settimeofday settimeofday "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setuid(uid int) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_setuid_trampoline_addr, uintptr(uid), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_setuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setuid setuid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Stat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_stat_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_stat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_stat stat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Statfs(path string, stat *Statfs_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_statfs_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_statfs_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_statfs statfs "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Symlink(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_symlink_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_symlink_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_symlink symlink "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(oldpath)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(newpath)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_symlinkat_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_symlinkat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_symlinkat symlinkat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sync() (err error) {
+	_, _, e1 := syscall_syscall(libc_sync_trampoline_addr, 0, 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_sync_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_sync sync "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Truncate(path string, length int64) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_truncate_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(length), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_truncate_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_truncate truncate "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Umask(newmask int) (oldmask int) {
+	r0, _, _ := syscall_syscall(libc_umask_trampoline_addr, uintptr(newmask), 0, 0)
+	oldmask = int(r0)
+	return
+}
+
+var libc_umask_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_umask umask "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unlink(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_unlink_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_unlink_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_unlink unlink "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unlinkat(dirfd int, path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_unlinkat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_unlinkat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_unlinkat unlinkat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unmount(path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_unmount_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_unmount_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_unmount unmount "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func write(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := syscall_syscall(libc_write_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_write_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_write write "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
+	r0, _, e1 := syscall_syscall6(libc_mmap_trampoline_addr, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos))
+	ret = uintptr(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_mmap_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mmap mmap "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func munmap(addr uintptr, length uintptr) (err error) {
+	_, _, e1 := syscall_syscall(libc_munmap_trampoline_addr, uintptr(addr), uintptr(length), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_munmap_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_munmap munmap "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
+	r0, _, e1 := syscall_syscall(libc_read_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
+	r0, _, e1 := syscall_syscall(libc_write_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall6(libc_utimensat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_utimensat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_utimensat utimensat "libc.so"
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.s b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.s
new file mode 100644
index 0000000..7c9223b
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.s
@@ -0,0 +1,796 @@
+// go run mkasm.go openbsd ppc64
+// Code generated by the command above; DO NOT EDIT.
+
+#include "textflag.h"
+
+TEXT libc_getgroups_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_getgroups(SB)
+	RET
+GLOBL	·libc_getgroups_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getgroups_trampoline_addr(SB)/8, $libc_getgroups_trampoline<>(SB)
+
+TEXT libc_setgroups_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_setgroups(SB)
+	RET
+GLOBL	·libc_setgroups_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setgroups_trampoline_addr(SB)/8, $libc_setgroups_trampoline<>(SB)
+
+TEXT libc_wait4_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_wait4(SB)
+	RET
+GLOBL	·libc_wait4_trampoline_addr(SB), RODATA, $8
+DATA	·libc_wait4_trampoline_addr(SB)/8, $libc_wait4_trampoline<>(SB)
+
+TEXT libc_accept_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_accept(SB)
+	RET
+GLOBL	·libc_accept_trampoline_addr(SB), RODATA, $8
+DATA	·libc_accept_trampoline_addr(SB)/8, $libc_accept_trampoline<>(SB)
+
+TEXT libc_bind_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_bind(SB)
+	RET
+GLOBL	·libc_bind_trampoline_addr(SB), RODATA, $8
+DATA	·libc_bind_trampoline_addr(SB)/8, $libc_bind_trampoline<>(SB)
+
+TEXT libc_connect_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_connect(SB)
+	RET
+GLOBL	·libc_connect_trampoline_addr(SB), RODATA, $8
+DATA	·libc_connect_trampoline_addr(SB)/8, $libc_connect_trampoline<>(SB)
+
+TEXT libc_socket_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_socket(SB)
+	RET
+GLOBL	·libc_socket_trampoline_addr(SB), RODATA, $8
+DATA	·libc_socket_trampoline_addr(SB)/8, $libc_socket_trampoline<>(SB)
+
+TEXT libc_getsockopt_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_getsockopt(SB)
+	RET
+GLOBL	·libc_getsockopt_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getsockopt_trampoline_addr(SB)/8, $libc_getsockopt_trampoline<>(SB)
+
+TEXT libc_setsockopt_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_setsockopt(SB)
+	RET
+GLOBL	·libc_setsockopt_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setsockopt_trampoline_addr(SB)/8, $libc_setsockopt_trampoline<>(SB)
+
+TEXT libc_getpeername_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_getpeername(SB)
+	RET
+GLOBL	·libc_getpeername_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getpeername_trampoline_addr(SB)/8, $libc_getpeername_trampoline<>(SB)
+
+TEXT libc_getsockname_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_getsockname(SB)
+	RET
+GLOBL	·libc_getsockname_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getsockname_trampoline_addr(SB)/8, $libc_getsockname_trampoline<>(SB)
+
+TEXT libc_shutdown_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_shutdown(SB)
+	RET
+GLOBL	·libc_shutdown_trampoline_addr(SB), RODATA, $8
+DATA	·libc_shutdown_trampoline_addr(SB)/8, $libc_shutdown_trampoline<>(SB)
+
+TEXT libc_socketpair_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_socketpair(SB)
+	RET
+GLOBL	·libc_socketpair_trampoline_addr(SB), RODATA, $8
+DATA	·libc_socketpair_trampoline_addr(SB)/8, $libc_socketpair_trampoline<>(SB)
+
+TEXT libc_recvfrom_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_recvfrom(SB)
+	RET
+GLOBL	·libc_recvfrom_trampoline_addr(SB), RODATA, $8
+DATA	·libc_recvfrom_trampoline_addr(SB)/8, $libc_recvfrom_trampoline<>(SB)
+
+TEXT libc_sendto_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_sendto(SB)
+	RET
+GLOBL	·libc_sendto_trampoline_addr(SB), RODATA, $8
+DATA	·libc_sendto_trampoline_addr(SB)/8, $libc_sendto_trampoline<>(SB)
+
+TEXT libc_recvmsg_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_recvmsg(SB)
+	RET
+GLOBL	·libc_recvmsg_trampoline_addr(SB), RODATA, $8
+DATA	·libc_recvmsg_trampoline_addr(SB)/8, $libc_recvmsg_trampoline<>(SB)
+
+TEXT libc_sendmsg_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_sendmsg(SB)
+	RET
+GLOBL	·libc_sendmsg_trampoline_addr(SB), RODATA, $8
+DATA	·libc_sendmsg_trampoline_addr(SB)/8, $libc_sendmsg_trampoline<>(SB)
+
+TEXT libc_kevent_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_kevent(SB)
+	RET
+GLOBL	·libc_kevent_trampoline_addr(SB), RODATA, $8
+DATA	·libc_kevent_trampoline_addr(SB)/8, $libc_kevent_trampoline<>(SB)
+
+TEXT libc_utimes_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_utimes(SB)
+	RET
+GLOBL	·libc_utimes_trampoline_addr(SB), RODATA, $8
+DATA	·libc_utimes_trampoline_addr(SB)/8, $libc_utimes_trampoline<>(SB)
+
+TEXT libc_futimes_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_futimes(SB)
+	RET
+GLOBL	·libc_futimes_trampoline_addr(SB), RODATA, $8
+DATA	·libc_futimes_trampoline_addr(SB)/8, $libc_futimes_trampoline<>(SB)
+
+TEXT libc_poll_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_poll(SB)
+	RET
+GLOBL	·libc_poll_trampoline_addr(SB), RODATA, $8
+DATA	·libc_poll_trampoline_addr(SB)/8, $libc_poll_trampoline<>(SB)
+
+TEXT libc_madvise_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_madvise(SB)
+	RET
+GLOBL	·libc_madvise_trampoline_addr(SB), RODATA, $8
+DATA	·libc_madvise_trampoline_addr(SB)/8, $libc_madvise_trampoline<>(SB)
+
+TEXT libc_mlock_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_mlock(SB)
+	RET
+GLOBL	·libc_mlock_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mlock_trampoline_addr(SB)/8, $libc_mlock_trampoline<>(SB)
+
+TEXT libc_mlockall_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_mlockall(SB)
+	RET
+GLOBL	·libc_mlockall_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mlockall_trampoline_addr(SB)/8, $libc_mlockall_trampoline<>(SB)
+
+TEXT libc_mprotect_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_mprotect(SB)
+	RET
+GLOBL	·libc_mprotect_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mprotect_trampoline_addr(SB)/8, $libc_mprotect_trampoline<>(SB)
+
+TEXT libc_msync_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_msync(SB)
+	RET
+GLOBL	·libc_msync_trampoline_addr(SB), RODATA, $8
+DATA	·libc_msync_trampoline_addr(SB)/8, $libc_msync_trampoline<>(SB)
+
+TEXT libc_munlock_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_munlock(SB)
+	RET
+GLOBL	·libc_munlock_trampoline_addr(SB), RODATA, $8
+DATA	·libc_munlock_trampoline_addr(SB)/8, $libc_munlock_trampoline<>(SB)
+
+TEXT libc_munlockall_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_munlockall(SB)
+	RET
+GLOBL	·libc_munlockall_trampoline_addr(SB), RODATA, $8
+DATA	·libc_munlockall_trampoline_addr(SB)/8, $libc_munlockall_trampoline<>(SB)
+
+TEXT libc_pipe2_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_pipe2(SB)
+	RET
+GLOBL	·libc_pipe2_trampoline_addr(SB), RODATA, $8
+DATA	·libc_pipe2_trampoline_addr(SB)/8, $libc_pipe2_trampoline<>(SB)
+
+TEXT libc_getdents_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_getdents(SB)
+	RET
+GLOBL	·libc_getdents_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getdents_trampoline_addr(SB)/8, $libc_getdents_trampoline<>(SB)
+
+TEXT libc_getcwd_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_getcwd(SB)
+	RET
+GLOBL	·libc_getcwd_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getcwd_trampoline_addr(SB)/8, $libc_getcwd_trampoline<>(SB)
+
+TEXT libc_ioctl_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_ioctl(SB)
+	RET
+GLOBL	·libc_ioctl_trampoline_addr(SB), RODATA, $8
+DATA	·libc_ioctl_trampoline_addr(SB)/8, $libc_ioctl_trampoline<>(SB)
+
+TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_sysctl(SB)
+	RET
+GLOBL	·libc_sysctl_trampoline_addr(SB), RODATA, $8
+DATA	·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB)
+
+TEXT libc_ppoll_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_ppoll(SB)
+	RET
+GLOBL	·libc_ppoll_trampoline_addr(SB), RODATA, $8
+DATA	·libc_ppoll_trampoline_addr(SB)/8, $libc_ppoll_trampoline<>(SB)
+
+TEXT libc_access_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_access(SB)
+	RET
+GLOBL	·libc_access_trampoline_addr(SB), RODATA, $8
+DATA	·libc_access_trampoline_addr(SB)/8, $libc_access_trampoline<>(SB)
+
+TEXT libc_adjtime_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_adjtime(SB)
+	RET
+GLOBL	·libc_adjtime_trampoline_addr(SB), RODATA, $8
+DATA	·libc_adjtime_trampoline_addr(SB)/8, $libc_adjtime_trampoline<>(SB)
+
+TEXT libc_chdir_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_chdir(SB)
+	RET
+GLOBL	·libc_chdir_trampoline_addr(SB), RODATA, $8
+DATA	·libc_chdir_trampoline_addr(SB)/8, $libc_chdir_trampoline<>(SB)
+
+TEXT libc_chflags_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_chflags(SB)
+	RET
+GLOBL	·libc_chflags_trampoline_addr(SB), RODATA, $8
+DATA	·libc_chflags_trampoline_addr(SB)/8, $libc_chflags_trampoline<>(SB)
+
+TEXT libc_chmod_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_chmod(SB)
+	RET
+GLOBL	·libc_chmod_trampoline_addr(SB), RODATA, $8
+DATA	·libc_chmod_trampoline_addr(SB)/8, $libc_chmod_trampoline<>(SB)
+
+TEXT libc_chown_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_chown(SB)
+	RET
+GLOBL	·libc_chown_trampoline_addr(SB), RODATA, $8
+DATA	·libc_chown_trampoline_addr(SB)/8, $libc_chown_trampoline<>(SB)
+
+TEXT libc_chroot_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_chroot(SB)
+	RET
+GLOBL	·libc_chroot_trampoline_addr(SB), RODATA, $8
+DATA	·libc_chroot_trampoline_addr(SB)/8, $libc_chroot_trampoline<>(SB)
+
+TEXT libc_close_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_close(SB)
+	RET
+GLOBL	·libc_close_trampoline_addr(SB), RODATA, $8
+DATA	·libc_close_trampoline_addr(SB)/8, $libc_close_trampoline<>(SB)
+
+TEXT libc_dup_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_dup(SB)
+	RET
+GLOBL	·libc_dup_trampoline_addr(SB), RODATA, $8
+DATA	·libc_dup_trampoline_addr(SB)/8, $libc_dup_trampoline<>(SB)
+
+TEXT libc_dup2_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_dup2(SB)
+	RET
+GLOBL	·libc_dup2_trampoline_addr(SB), RODATA, $8
+DATA	·libc_dup2_trampoline_addr(SB)/8, $libc_dup2_trampoline<>(SB)
+
+TEXT libc_dup3_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_dup3(SB)
+	RET
+GLOBL	·libc_dup3_trampoline_addr(SB), RODATA, $8
+DATA	·libc_dup3_trampoline_addr(SB)/8, $libc_dup3_trampoline<>(SB)
+
+TEXT libc_exit_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_exit(SB)
+	RET
+GLOBL	·libc_exit_trampoline_addr(SB), RODATA, $8
+DATA	·libc_exit_trampoline_addr(SB)/8, $libc_exit_trampoline<>(SB)
+
+TEXT libc_faccessat_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_faccessat(SB)
+	RET
+GLOBL	·libc_faccessat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_faccessat_trampoline_addr(SB)/8, $libc_faccessat_trampoline<>(SB)
+
+TEXT libc_fchdir_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_fchdir(SB)
+	RET
+GLOBL	·libc_fchdir_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fchdir_trampoline_addr(SB)/8, $libc_fchdir_trampoline<>(SB)
+
+TEXT libc_fchflags_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_fchflags(SB)
+	RET
+GLOBL	·libc_fchflags_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fchflags_trampoline_addr(SB)/8, $libc_fchflags_trampoline<>(SB)
+
+TEXT libc_fchmod_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_fchmod(SB)
+	RET
+GLOBL	·libc_fchmod_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fchmod_trampoline_addr(SB)/8, $libc_fchmod_trampoline<>(SB)
+
+TEXT libc_fchmodat_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_fchmodat(SB)
+	RET
+GLOBL	·libc_fchmodat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fchmodat_trampoline_addr(SB)/8, $libc_fchmodat_trampoline<>(SB)
+
+TEXT libc_fchown_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_fchown(SB)
+	RET
+GLOBL	·libc_fchown_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fchown_trampoline_addr(SB)/8, $libc_fchown_trampoline<>(SB)
+
+TEXT libc_fchownat_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_fchownat(SB)
+	RET
+GLOBL	·libc_fchownat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fchownat_trampoline_addr(SB)/8, $libc_fchownat_trampoline<>(SB)
+
+TEXT libc_flock_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_flock(SB)
+	RET
+GLOBL	·libc_flock_trampoline_addr(SB), RODATA, $8
+DATA	·libc_flock_trampoline_addr(SB)/8, $libc_flock_trampoline<>(SB)
+
+TEXT libc_fpathconf_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_fpathconf(SB)
+	RET
+GLOBL	·libc_fpathconf_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fpathconf_trampoline_addr(SB)/8, $libc_fpathconf_trampoline<>(SB)
+
+TEXT libc_fstat_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_fstat(SB)
+	RET
+GLOBL	·libc_fstat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fstat_trampoline_addr(SB)/8, $libc_fstat_trampoline<>(SB)
+
+TEXT libc_fstatat_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_fstatat(SB)
+	RET
+GLOBL	·libc_fstatat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fstatat_trampoline_addr(SB)/8, $libc_fstatat_trampoline<>(SB)
+
+TEXT libc_fstatfs_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_fstatfs(SB)
+	RET
+GLOBL	·libc_fstatfs_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fstatfs_trampoline_addr(SB)/8, $libc_fstatfs_trampoline<>(SB)
+
+TEXT libc_fsync_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_fsync(SB)
+	RET
+GLOBL	·libc_fsync_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fsync_trampoline_addr(SB)/8, $libc_fsync_trampoline<>(SB)
+
+TEXT libc_ftruncate_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_ftruncate(SB)
+	RET
+GLOBL	·libc_ftruncate_trampoline_addr(SB), RODATA, $8
+DATA	·libc_ftruncate_trampoline_addr(SB)/8, $libc_ftruncate_trampoline<>(SB)
+
+TEXT libc_getegid_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_getegid(SB)
+	RET
+GLOBL	·libc_getegid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getegid_trampoline_addr(SB)/8, $libc_getegid_trampoline<>(SB)
+
+TEXT libc_geteuid_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_geteuid(SB)
+	RET
+GLOBL	·libc_geteuid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_geteuid_trampoline_addr(SB)/8, $libc_geteuid_trampoline<>(SB)
+
+TEXT libc_getgid_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_getgid(SB)
+	RET
+GLOBL	·libc_getgid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getgid_trampoline_addr(SB)/8, $libc_getgid_trampoline<>(SB)
+
+TEXT libc_getpgid_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_getpgid(SB)
+	RET
+GLOBL	·libc_getpgid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getpgid_trampoline_addr(SB)/8, $libc_getpgid_trampoline<>(SB)
+
+TEXT libc_getpgrp_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_getpgrp(SB)
+	RET
+GLOBL	·libc_getpgrp_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getpgrp_trampoline_addr(SB)/8, $libc_getpgrp_trampoline<>(SB)
+
+TEXT libc_getpid_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_getpid(SB)
+	RET
+GLOBL	·libc_getpid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getpid_trampoline_addr(SB)/8, $libc_getpid_trampoline<>(SB)
+
+TEXT libc_getppid_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_getppid(SB)
+	RET
+GLOBL	·libc_getppid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getppid_trampoline_addr(SB)/8, $libc_getppid_trampoline<>(SB)
+
+TEXT libc_getpriority_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_getpriority(SB)
+	RET
+GLOBL	·libc_getpriority_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getpriority_trampoline_addr(SB)/8, $libc_getpriority_trampoline<>(SB)
+
+TEXT libc_getrlimit_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_getrlimit(SB)
+	RET
+GLOBL	·libc_getrlimit_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getrlimit_trampoline_addr(SB)/8, $libc_getrlimit_trampoline<>(SB)
+
+TEXT libc_getrtable_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_getrtable(SB)
+	RET
+GLOBL	·libc_getrtable_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getrtable_trampoline_addr(SB)/8, $libc_getrtable_trampoline<>(SB)
+
+TEXT libc_getrusage_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_getrusage(SB)
+	RET
+GLOBL	·libc_getrusage_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getrusage_trampoline_addr(SB)/8, $libc_getrusage_trampoline<>(SB)
+
+TEXT libc_getsid_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_getsid(SB)
+	RET
+GLOBL	·libc_getsid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getsid_trampoline_addr(SB)/8, $libc_getsid_trampoline<>(SB)
+
+TEXT libc_gettimeofday_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_gettimeofday(SB)
+	RET
+GLOBL	·libc_gettimeofday_trampoline_addr(SB), RODATA, $8
+DATA	·libc_gettimeofday_trampoline_addr(SB)/8, $libc_gettimeofday_trampoline<>(SB)
+
+TEXT libc_getuid_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_getuid(SB)
+	RET
+GLOBL	·libc_getuid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getuid_trampoline_addr(SB)/8, $libc_getuid_trampoline<>(SB)
+
+TEXT libc_issetugid_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_issetugid(SB)
+	RET
+GLOBL	·libc_issetugid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_issetugid_trampoline_addr(SB)/8, $libc_issetugid_trampoline<>(SB)
+
+TEXT libc_kill_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_kill(SB)
+	RET
+GLOBL	·libc_kill_trampoline_addr(SB), RODATA, $8
+DATA	·libc_kill_trampoline_addr(SB)/8, $libc_kill_trampoline<>(SB)
+
+TEXT libc_kqueue_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_kqueue(SB)
+	RET
+GLOBL	·libc_kqueue_trampoline_addr(SB), RODATA, $8
+DATA	·libc_kqueue_trampoline_addr(SB)/8, $libc_kqueue_trampoline<>(SB)
+
+TEXT libc_lchown_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_lchown(SB)
+	RET
+GLOBL	·libc_lchown_trampoline_addr(SB), RODATA, $8
+DATA	·libc_lchown_trampoline_addr(SB)/8, $libc_lchown_trampoline<>(SB)
+
+TEXT libc_link_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_link(SB)
+	RET
+GLOBL	·libc_link_trampoline_addr(SB), RODATA, $8
+DATA	·libc_link_trampoline_addr(SB)/8, $libc_link_trampoline<>(SB)
+
+TEXT libc_linkat_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_linkat(SB)
+	RET
+GLOBL	·libc_linkat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_linkat_trampoline_addr(SB)/8, $libc_linkat_trampoline<>(SB)
+
+TEXT libc_listen_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_listen(SB)
+	RET
+GLOBL	·libc_listen_trampoline_addr(SB), RODATA, $8
+DATA	·libc_listen_trampoline_addr(SB)/8, $libc_listen_trampoline<>(SB)
+
+TEXT libc_lstat_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_lstat(SB)
+	RET
+GLOBL	·libc_lstat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_lstat_trampoline_addr(SB)/8, $libc_lstat_trampoline<>(SB)
+
+TEXT libc_mkdir_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_mkdir(SB)
+	RET
+GLOBL	·libc_mkdir_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mkdir_trampoline_addr(SB)/8, $libc_mkdir_trampoline<>(SB)
+
+TEXT libc_mkdirat_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_mkdirat(SB)
+	RET
+GLOBL	·libc_mkdirat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mkdirat_trampoline_addr(SB)/8, $libc_mkdirat_trampoline<>(SB)
+
+TEXT libc_mkfifo_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_mkfifo(SB)
+	RET
+GLOBL	·libc_mkfifo_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mkfifo_trampoline_addr(SB)/8, $libc_mkfifo_trampoline<>(SB)
+
+TEXT libc_mkfifoat_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_mkfifoat(SB)
+	RET
+GLOBL	·libc_mkfifoat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mkfifoat_trampoline_addr(SB)/8, $libc_mkfifoat_trampoline<>(SB)
+
+TEXT libc_mknod_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_mknod(SB)
+	RET
+GLOBL	·libc_mknod_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mknod_trampoline_addr(SB)/8, $libc_mknod_trampoline<>(SB)
+
+TEXT libc_mknodat_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_mknodat(SB)
+	RET
+GLOBL	·libc_mknodat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mknodat_trampoline_addr(SB)/8, $libc_mknodat_trampoline<>(SB)
+
+TEXT libc_nanosleep_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_nanosleep(SB)
+	RET
+GLOBL	·libc_nanosleep_trampoline_addr(SB), RODATA, $8
+DATA	·libc_nanosleep_trampoline_addr(SB)/8, $libc_nanosleep_trampoline<>(SB)
+
+TEXT libc_open_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_open(SB)
+	RET
+GLOBL	·libc_open_trampoline_addr(SB), RODATA, $8
+DATA	·libc_open_trampoline_addr(SB)/8, $libc_open_trampoline<>(SB)
+
+TEXT libc_openat_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_openat(SB)
+	RET
+GLOBL	·libc_openat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_openat_trampoline_addr(SB)/8, $libc_openat_trampoline<>(SB)
+
+TEXT libc_pathconf_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_pathconf(SB)
+	RET
+GLOBL	·libc_pathconf_trampoline_addr(SB), RODATA, $8
+DATA	·libc_pathconf_trampoline_addr(SB)/8, $libc_pathconf_trampoline<>(SB)
+
+TEXT libc_pread_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_pread(SB)
+	RET
+GLOBL	·libc_pread_trampoline_addr(SB), RODATA, $8
+DATA	·libc_pread_trampoline_addr(SB)/8, $libc_pread_trampoline<>(SB)
+
+TEXT libc_pwrite_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_pwrite(SB)
+	RET
+GLOBL	·libc_pwrite_trampoline_addr(SB), RODATA, $8
+DATA	·libc_pwrite_trampoline_addr(SB)/8, $libc_pwrite_trampoline<>(SB)
+
+TEXT libc_read_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_read(SB)
+	RET
+GLOBL	·libc_read_trampoline_addr(SB), RODATA, $8
+DATA	·libc_read_trampoline_addr(SB)/8, $libc_read_trampoline<>(SB)
+
+TEXT libc_readlink_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_readlink(SB)
+	RET
+GLOBL	·libc_readlink_trampoline_addr(SB), RODATA, $8
+DATA	·libc_readlink_trampoline_addr(SB)/8, $libc_readlink_trampoline<>(SB)
+
+TEXT libc_readlinkat_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_readlinkat(SB)
+	RET
+GLOBL	·libc_readlinkat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_readlinkat_trampoline_addr(SB)/8, $libc_readlinkat_trampoline<>(SB)
+
+TEXT libc_rename_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_rename(SB)
+	RET
+GLOBL	·libc_rename_trampoline_addr(SB), RODATA, $8
+DATA	·libc_rename_trampoline_addr(SB)/8, $libc_rename_trampoline<>(SB)
+
+TEXT libc_renameat_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_renameat(SB)
+	RET
+GLOBL	·libc_renameat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_renameat_trampoline_addr(SB)/8, $libc_renameat_trampoline<>(SB)
+
+TEXT libc_revoke_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_revoke(SB)
+	RET
+GLOBL	·libc_revoke_trampoline_addr(SB), RODATA, $8
+DATA	·libc_revoke_trampoline_addr(SB)/8, $libc_revoke_trampoline<>(SB)
+
+TEXT libc_rmdir_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_rmdir(SB)
+	RET
+GLOBL	·libc_rmdir_trampoline_addr(SB), RODATA, $8
+DATA	·libc_rmdir_trampoline_addr(SB)/8, $libc_rmdir_trampoline<>(SB)
+
+TEXT libc_lseek_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_lseek(SB)
+	RET
+GLOBL	·libc_lseek_trampoline_addr(SB), RODATA, $8
+DATA	·libc_lseek_trampoline_addr(SB)/8, $libc_lseek_trampoline<>(SB)
+
+TEXT libc_select_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_select(SB)
+	RET
+GLOBL	·libc_select_trampoline_addr(SB), RODATA, $8
+DATA	·libc_select_trampoline_addr(SB)/8, $libc_select_trampoline<>(SB)
+
+TEXT libc_setegid_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_setegid(SB)
+	RET
+GLOBL	·libc_setegid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setegid_trampoline_addr(SB)/8, $libc_setegid_trampoline<>(SB)
+
+TEXT libc_seteuid_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_seteuid(SB)
+	RET
+GLOBL	·libc_seteuid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_seteuid_trampoline_addr(SB)/8, $libc_seteuid_trampoline<>(SB)
+
+TEXT libc_setgid_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_setgid(SB)
+	RET
+GLOBL	·libc_setgid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setgid_trampoline_addr(SB)/8, $libc_setgid_trampoline<>(SB)
+
+TEXT libc_setlogin_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_setlogin(SB)
+	RET
+GLOBL	·libc_setlogin_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setlogin_trampoline_addr(SB)/8, $libc_setlogin_trampoline<>(SB)
+
+TEXT libc_setpgid_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_setpgid(SB)
+	RET
+GLOBL	·libc_setpgid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setpgid_trampoline_addr(SB)/8, $libc_setpgid_trampoline<>(SB)
+
+TEXT libc_setpriority_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_setpriority(SB)
+	RET
+GLOBL	·libc_setpriority_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setpriority_trampoline_addr(SB)/8, $libc_setpriority_trampoline<>(SB)
+
+TEXT libc_setregid_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_setregid(SB)
+	RET
+GLOBL	·libc_setregid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setregid_trampoline_addr(SB)/8, $libc_setregid_trampoline<>(SB)
+
+TEXT libc_setreuid_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_setreuid(SB)
+	RET
+GLOBL	·libc_setreuid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setreuid_trampoline_addr(SB)/8, $libc_setreuid_trampoline<>(SB)
+
+TEXT libc_setresgid_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_setresgid(SB)
+	RET
+GLOBL	·libc_setresgid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setresgid_trampoline_addr(SB)/8, $libc_setresgid_trampoline<>(SB)
+
+TEXT libc_setresuid_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_setresuid(SB)
+	RET
+GLOBL	·libc_setresuid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setresuid_trampoline_addr(SB)/8, $libc_setresuid_trampoline<>(SB)
+
+TEXT libc_setrlimit_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_setrlimit(SB)
+	RET
+GLOBL	·libc_setrlimit_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setrlimit_trampoline_addr(SB)/8, $libc_setrlimit_trampoline<>(SB)
+
+TEXT libc_setrtable_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_setrtable(SB)
+	RET
+GLOBL	·libc_setrtable_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setrtable_trampoline_addr(SB)/8, $libc_setrtable_trampoline<>(SB)
+
+TEXT libc_setsid_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_setsid(SB)
+	RET
+GLOBL	·libc_setsid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setsid_trampoline_addr(SB)/8, $libc_setsid_trampoline<>(SB)
+
+TEXT libc_settimeofday_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_settimeofday(SB)
+	RET
+GLOBL	·libc_settimeofday_trampoline_addr(SB), RODATA, $8
+DATA	·libc_settimeofday_trampoline_addr(SB)/8, $libc_settimeofday_trampoline<>(SB)
+
+TEXT libc_setuid_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_setuid(SB)
+	RET
+GLOBL	·libc_setuid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setuid_trampoline_addr(SB)/8, $libc_setuid_trampoline<>(SB)
+
+TEXT libc_stat_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_stat(SB)
+	RET
+GLOBL	·libc_stat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_stat_trampoline_addr(SB)/8, $libc_stat_trampoline<>(SB)
+
+TEXT libc_statfs_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_statfs(SB)
+	RET
+GLOBL	·libc_statfs_trampoline_addr(SB), RODATA, $8
+DATA	·libc_statfs_trampoline_addr(SB)/8, $libc_statfs_trampoline<>(SB)
+
+TEXT libc_symlink_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_symlink(SB)
+	RET
+GLOBL	·libc_symlink_trampoline_addr(SB), RODATA, $8
+DATA	·libc_symlink_trampoline_addr(SB)/8, $libc_symlink_trampoline<>(SB)
+
+TEXT libc_symlinkat_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_symlinkat(SB)
+	RET
+GLOBL	·libc_symlinkat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_symlinkat_trampoline_addr(SB)/8, $libc_symlinkat_trampoline<>(SB)
+
+TEXT libc_sync_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_sync(SB)
+	RET
+GLOBL	·libc_sync_trampoline_addr(SB), RODATA, $8
+DATA	·libc_sync_trampoline_addr(SB)/8, $libc_sync_trampoline<>(SB)
+
+TEXT libc_truncate_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_truncate(SB)
+	RET
+GLOBL	·libc_truncate_trampoline_addr(SB), RODATA, $8
+DATA	·libc_truncate_trampoline_addr(SB)/8, $libc_truncate_trampoline<>(SB)
+
+TEXT libc_umask_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_umask(SB)
+	RET
+GLOBL	·libc_umask_trampoline_addr(SB), RODATA, $8
+DATA	·libc_umask_trampoline_addr(SB)/8, $libc_umask_trampoline<>(SB)
+
+TEXT libc_unlink_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_unlink(SB)
+	RET
+GLOBL	·libc_unlink_trampoline_addr(SB), RODATA, $8
+DATA	·libc_unlink_trampoline_addr(SB)/8, $libc_unlink_trampoline<>(SB)
+
+TEXT libc_unlinkat_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_unlinkat(SB)
+	RET
+GLOBL	·libc_unlinkat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_unlinkat_trampoline_addr(SB)/8, $libc_unlinkat_trampoline<>(SB)
+
+TEXT libc_unmount_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_unmount(SB)
+	RET
+GLOBL	·libc_unmount_trampoline_addr(SB), RODATA, $8
+DATA	·libc_unmount_trampoline_addr(SB)/8, $libc_unmount_trampoline<>(SB)
+
+TEXT libc_write_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_write(SB)
+	RET
+GLOBL	·libc_write_trampoline_addr(SB), RODATA, $8
+DATA	·libc_write_trampoline_addr(SB)/8, $libc_write_trampoline<>(SB)
+
+TEXT libc_mmap_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_mmap(SB)
+	RET
+GLOBL	·libc_mmap_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mmap_trampoline_addr(SB)/8, $libc_mmap_trampoline<>(SB)
+
+TEXT libc_munmap_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_munmap(SB)
+	RET
+GLOBL	·libc_munmap_trampoline_addr(SB), RODATA, $8
+DATA	·libc_munmap_trampoline_addr(SB)/8, $libc_munmap_trampoline<>(SB)
+
+TEXT libc_utimensat_trampoline<>(SB),NOSPLIT,$0-0
+	CALL	libc_utimensat(SB)
+	RET
+GLOBL	·libc_utimensat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_utimensat_trampoline_addr(SB)/8, $libc_utimensat_trampoline<>(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go
new file mode 100644
index 0000000..8e3e787
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go
@@ -0,0 +1,2221 @@
+// go run mksyscall.go -openbsd -libc -tags openbsd,riscv64 syscall_bsd.go syscall_openbsd.go syscall_openbsd_riscv64.go
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+//go:build openbsd && riscv64
+// +build openbsd,riscv64
+
+package unix
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+var _ syscall.Errno
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
+	r0, _, e1 := syscall_rawSyscall(libc_getgroups_trampoline_addr, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_getgroups_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getgroups getgroups "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setgroups(ngid int, gid *_Gid_t) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_setgroups_trampoline_addr, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_setgroups_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setgroups setgroups "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
+	r0, _, e1 := syscall_syscall6(libc_wait4_trampoline_addr, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+	wpid = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_wait4_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_wait4 wait4 "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+	r0, _, e1 := syscall_syscall(libc_accept_trampoline_addr, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_accept_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_accept accept "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := syscall_syscall(libc_bind_trampoline_addr, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_bind_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_bind bind "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := syscall_syscall(libc_connect_trampoline_addr, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_connect_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_connect connect "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socket(domain int, typ int, proto int) (fd int, err error) {
+	r0, _, e1 := syscall_rawSyscall(libc_socket_trampoline_addr, uintptr(domain), uintptr(typ), uintptr(proto))
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_socket_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_socket socket "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
+	_, _, e1 := syscall_syscall6(libc_getsockopt_trampoline_addr, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_getsockopt_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getsockopt getsockopt "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
+	_, _, e1 := syscall_syscall6(libc_setsockopt_trampoline_addr, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_setsockopt_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setsockopt setsockopt "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_getpeername_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_getpeername_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getpeername getpeername "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_getsockname_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_getsockname_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getsockname getsockname "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Shutdown(s int, how int) (err error) {
+	_, _, e1 := syscall_syscall(libc_shutdown_trampoline_addr, uintptr(s), uintptr(how), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_shutdown_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_shutdown shutdown "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
+	_, _, e1 := syscall_rawSyscall6(libc_socketpair_trampoline_addr, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_socketpair_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_socketpair socketpair "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := syscall_syscall6(libc_recvfrom_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_recvfrom_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_recvfrom recvfrom "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := syscall_syscall6(libc_sendto_trampoline_addr, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_sendto_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_sendto sendto "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := syscall_syscall(libc_recvmsg_trampoline_addr, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_recvmsg_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_recvmsg recvmsg "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := syscall_syscall(libc_sendmsg_trampoline_addr, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_sendmsg_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_sendmsg sendmsg "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
+	r0, _, e1 := syscall_syscall6(libc_kevent_trampoline_addr, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_kevent_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_kevent kevent "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimes(path string, timeval *[2]Timeval) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_utimes_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_utimes_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_utimes utimes "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func futimes(fd int, timeval *[2]Timeval) (err error) {
+	_, _, e1 := syscall_syscall(libc_futimes_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_futimes_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_futimes futimes "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func poll(fds *PollFd, nfds int, timeout int) (n int, err error) {
+	r0, _, e1 := syscall_syscall(libc_poll_trampoline_addr, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_poll_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_poll poll "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Madvise(b []byte, behav int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := syscall_syscall(libc_madvise_trampoline_addr, uintptr(_p0), uintptr(len(b)), uintptr(behav))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_madvise_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_madvise madvise "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := syscall_syscall(libc_mlock_trampoline_addr, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_mlock_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mlock mlock "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlockall(flags int) (err error) {
+	_, _, e1 := syscall_syscall(libc_mlockall_trampoline_addr, uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_mlockall_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mlockall mlockall "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mprotect(b []byte, prot int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := syscall_syscall(libc_mprotect_trampoline_addr, uintptr(_p0), uintptr(len(b)), uintptr(prot))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_mprotect_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mprotect mprotect "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Msync(b []byte, flags int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := syscall_syscall(libc_msync_trampoline_addr, uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_msync_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_msync msync "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := syscall_syscall(libc_munlock_trampoline_addr, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_munlock_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_munlock munlock "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlockall() (err error) {
+	_, _, e1 := syscall_syscall(libc_munlockall_trampoline_addr, 0, 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_munlockall_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_munlockall munlockall "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe2(p *[2]_C_int, flags int) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_pipe2_trampoline_addr, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_pipe2_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_pipe2 pipe2 "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getdents(fd int, buf []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := syscall_syscall(libc_getdents_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_getdents_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getdents getdents "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getcwd(buf []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := syscall_syscall(libc_getcwd_trampoline_addr, uintptr(_p0), uintptr(len(buf)), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_getcwd_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getcwd getcwd "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func ioctl(fd int, req uint, arg uintptr) (err error) {
+	_, _, e1 := syscall_syscall(libc_ioctl_trampoline_addr, uintptr(fd), uintptr(req), uintptr(arg))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_ioctl_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_ioctl ioctl "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
+	var _p0 unsafe.Pointer
+	if len(mib) > 0 {
+		_p0 = unsafe.Pointer(&mib[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := syscall_syscall6(libc_sysctl_trampoline_addr, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_sysctl_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_sysctl sysctl "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
+	r0, _, e1 := syscall_syscall6(libc_ppoll_trampoline_addr, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_ppoll_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_ppoll ppoll "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Access(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_access_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_access_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_access access "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
+	_, _, e1 := syscall_syscall(libc_adjtime_trampoline_addr, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_adjtime_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_adjtime adjtime "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_chdir_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_chdir_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_chdir chdir "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chflags(path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_chflags_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_chflags_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_chflags chflags "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chmod(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_chmod_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_chmod_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_chmod chmod "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_chown_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_chown_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_chown chown "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chroot(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_chroot_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_chroot_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_chroot chroot "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Close(fd int) (err error) {
+	_, _, e1 := syscall_syscall(libc_close_trampoline_addr, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_close_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_close close "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup(fd int) (nfd int, err error) {
+	r0, _, e1 := syscall_syscall(libc_dup_trampoline_addr, uintptr(fd), 0, 0)
+	nfd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_dup_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_dup dup "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup2(from int, to int) (err error) {
+	_, _, e1 := syscall_syscall(libc_dup2_trampoline_addr, uintptr(from), uintptr(to), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_dup2_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_dup2 dup2 "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup3(from int, to int, flags int) (err error) {
+	_, _, e1 := syscall_syscall(libc_dup3_trampoline_addr, uintptr(from), uintptr(to), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_dup3_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_dup3 dup3 "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Exit(code int) {
+	syscall_syscall(libc_exit_trampoline_addr, uintptr(code), 0, 0)
+	return
+}
+
+var libc_exit_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_exit exit "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall6(libc_faccessat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_faccessat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_faccessat faccessat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchdir(fd int) (err error) {
+	_, _, e1 := syscall_syscall(libc_fchdir_trampoline_addr, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_fchdir_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchdir fchdir "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchflags(fd int, flags int) (err error) {
+	_, _, e1 := syscall_syscall(libc_fchflags_trampoline_addr, uintptr(fd), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_fchflags_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchflags fchflags "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchmod(fd int, mode uint32) (err error) {
+	_, _, e1 := syscall_syscall(libc_fchmod_trampoline_addr, uintptr(fd), uintptr(mode), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_fchmod_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchmod fchmod "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall6(libc_fchmodat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_fchmodat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchmodat fchmodat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchown(fd int, uid int, gid int) (err error) {
+	_, _, e1 := syscall_syscall(libc_fchown_trampoline_addr, uintptr(fd), uintptr(uid), uintptr(gid))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_fchown_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchown fchown "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall6(libc_fchownat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_fchownat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fchownat fchownat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Flock(fd int, how int) (err error) {
+	_, _, e1 := syscall_syscall(libc_flock_trampoline_addr, uintptr(fd), uintptr(how), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_flock_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_flock flock "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fpathconf(fd int, name int) (val int, err error) {
+	r0, _, e1 := syscall_syscall(libc_fpathconf_trampoline_addr, uintptr(fd), uintptr(name), 0)
+	val = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_fpathconf_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fpathconf fpathconf "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstat(fd int, stat *Stat_t) (err error) {
+	_, _, e1 := syscall_syscall(libc_fstat_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_fstat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fstat fstat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall6(libc_fstatat_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_fstatat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fstatat fstatat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstatfs(fd int, stat *Statfs_t) (err error) {
+	_, _, e1 := syscall_syscall(libc_fstatfs_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_fstatfs_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fstatfs fstatfs "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fsync(fd int) (err error) {
+	_, _, e1 := syscall_syscall(libc_fsync_trampoline_addr, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_fsync_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_fsync fsync "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ftruncate(fd int, length int64) (err error) {
+	_, _, e1 := syscall_syscall(libc_ftruncate_trampoline_addr, uintptr(fd), uintptr(length), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_ftruncate_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_ftruncate ftruncate "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getegid() (egid int) {
+	r0, _, _ := syscall_rawSyscall(libc_getegid_trampoline_addr, 0, 0, 0)
+	egid = int(r0)
+	return
+}
+
+var libc_getegid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getegid getegid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Geteuid() (uid int) {
+	r0, _, _ := syscall_rawSyscall(libc_geteuid_trampoline_addr, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+var libc_geteuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_geteuid geteuid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getgid() (gid int) {
+	r0, _, _ := syscall_rawSyscall(libc_getgid_trampoline_addr, 0, 0, 0)
+	gid = int(r0)
+	return
+}
+
+var libc_getgid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getgid getgid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgid(pid int) (pgid int, err error) {
+	r0, _, e1 := syscall_rawSyscall(libc_getpgid_trampoline_addr, uintptr(pid), 0, 0)
+	pgid = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_getpgid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getpgid getpgid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgrp() (pgrp int) {
+	r0, _, _ := syscall_rawSyscall(libc_getpgrp_trampoline_addr, 0, 0, 0)
+	pgrp = int(r0)
+	return
+}
+
+var libc_getpgrp_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getpgrp getpgrp "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpid() (pid int) {
+	r0, _, _ := syscall_rawSyscall(libc_getpid_trampoline_addr, 0, 0, 0)
+	pid = int(r0)
+	return
+}
+
+var libc_getpid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getpid getpid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getppid() (ppid int) {
+	r0, _, _ := syscall_rawSyscall(libc_getppid_trampoline_addr, 0, 0, 0)
+	ppid = int(r0)
+	return
+}
+
+var libc_getppid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getppid getppid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpriority(which int, who int) (prio int, err error) {
+	r0, _, e1 := syscall_syscall(libc_getpriority_trampoline_addr, uintptr(which), uintptr(who), 0)
+	prio = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_getpriority_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getpriority getpriority "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrlimit(which int, lim *Rlimit) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_getrlimit_trampoline_addr, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_getrlimit_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getrlimit getrlimit "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrtable() (rtable int, err error) {
+	r0, _, e1 := syscall_rawSyscall(libc_getrtable_trampoline_addr, 0, 0, 0)
+	rtable = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_getrtable_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getrtable getrtable "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrusage(who int, rusage *Rusage) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_getrusage_trampoline_addr, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_getrusage_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getrusage getrusage "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getsid(pid int) (sid int, err error) {
+	r0, _, e1 := syscall_rawSyscall(libc_getsid_trampoline_addr, uintptr(pid), 0, 0)
+	sid = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_getsid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getsid getsid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Gettimeofday(tv *Timeval) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_gettimeofday_trampoline_addr, uintptr(unsafe.Pointer(tv)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_gettimeofday_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_gettimeofday gettimeofday "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getuid() (uid int) {
+	r0, _, _ := syscall_rawSyscall(libc_getuid_trampoline_addr, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+var libc_getuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_getuid getuid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Issetugid() (tainted bool) {
+	r0, _, _ := syscall_syscall(libc_issetugid_trampoline_addr, 0, 0, 0)
+	tainted = bool(r0 != 0)
+	return
+}
+
+var libc_issetugid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_issetugid issetugid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kill(pid int, signum syscall.Signal) (err error) {
+	_, _, e1 := syscall_syscall(libc_kill_trampoline_addr, uintptr(pid), uintptr(signum), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_kill_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_kill kill "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kqueue() (fd int, err error) {
+	r0, _, e1 := syscall_syscall(libc_kqueue_trampoline_addr, 0, 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_kqueue_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_kqueue kqueue "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lchown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_lchown_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_lchown_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_lchown lchown "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Link(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_link_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_link_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_link link "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Linkat(pathfd int, path string, linkfd int, link string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall6(libc_linkat_trampoline_addr, uintptr(pathfd), uintptr(unsafe.Pointer(_p0)), uintptr(linkfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_linkat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_linkat linkat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Listen(s int, backlog int) (err error) {
+	_, _, e1 := syscall_syscall(libc_listen_trampoline_addr, uintptr(s), uintptr(backlog), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_listen_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_listen listen "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lstat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_lstat_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_lstat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_lstat lstat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkdir(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_mkdir_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_mkdir_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mkdir mkdir "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkdirat(dirfd int, path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_mkdirat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_mkdirat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mkdirat mkdirat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkfifo(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_mkfifo_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_mkfifo_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mkfifo mkfifo "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkfifoat(dirfd int, path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_mkfifoat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_mkfifoat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mkfifoat mkfifoat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mknod(path string, mode uint32, dev int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_mknod_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_mknod_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mknod mknod "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall6(libc_mknodat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_mknodat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mknodat mknodat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
+	_, _, e1 := syscall_syscall(libc_nanosleep_trampoline_addr, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_nanosleep_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_nanosleep nanosleep "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Open(path string, mode int, perm uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := syscall_syscall(libc_open_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_open_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_open open "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Openat(dirfd int, path string, mode int, perm uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := syscall_syscall6(libc_openat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_openat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_openat openat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pathconf(path string, name int) (val int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := syscall_syscall(libc_pathconf_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
+	val = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_pathconf_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_pathconf pathconf "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pread(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := syscall_syscall6(libc_pread_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_pread_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_pread pread "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pwrite(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := syscall_syscall6(libc_pwrite_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_pwrite_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_pwrite pwrite "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func read(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := syscall_syscall(libc_read_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_read_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_read read "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Readlink(path string, buf []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(buf) > 0 {
+		_p1 = unsafe.Pointer(&buf[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := syscall_syscall(libc_readlink_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_readlink_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_readlink readlink "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(buf) > 0 {
+		_p1 = unsafe.Pointer(&buf[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := syscall_syscall6(libc_readlinkat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_readlinkat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_readlinkat readlinkat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rename(from string, to string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(from)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(to)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_rename_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_rename_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_rename rename "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Renameat(fromfd int, from string, tofd int, to string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(from)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(to)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall6(libc_renameat_trampoline_addr, uintptr(fromfd), uintptr(unsafe.Pointer(_p0)), uintptr(tofd), uintptr(unsafe.Pointer(_p1)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_renameat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_renameat renameat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Revoke(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_revoke_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_revoke_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_revoke revoke "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rmdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_rmdir_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_rmdir_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_rmdir rmdir "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
+	r0, _, e1 := syscall_syscall(libc_lseek_trampoline_addr, uintptr(fd), uintptr(offset), uintptr(whence))
+	newoffset = int64(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_lseek_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_lseek lseek "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {
+	r0, _, e1 := syscall_syscall6(libc_select_trampoline_addr, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_select_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_select select "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setegid(egid int) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_setegid_trampoline_addr, uintptr(egid), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_setegid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setegid setegid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seteuid(euid int) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_seteuid_trampoline_addr, uintptr(euid), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_seteuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_seteuid seteuid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setgid(gid int) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_setgid_trampoline_addr, uintptr(gid), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_setgid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setgid setgid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setlogin(name string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(name)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_setlogin_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_setlogin_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setlogin setlogin "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpgid(pid int, pgid int) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_setpgid_trampoline_addr, uintptr(pid), uintptr(pgid), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_setpgid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setpgid setpgid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpriority(which int, who int, prio int) (err error) {
+	_, _, e1 := syscall_syscall(libc_setpriority_trampoline_addr, uintptr(which), uintptr(who), uintptr(prio))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_setpriority_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setpriority setpriority "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setregid(rgid int, egid int) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_setregid_trampoline_addr, uintptr(rgid), uintptr(egid), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_setregid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setregid setregid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setreuid(ruid int, euid int) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_setreuid_trampoline_addr, uintptr(ruid), uintptr(euid), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_setreuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setreuid setreuid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setresgid(rgid int, egid int, sgid int) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_setresgid_trampoline_addr, uintptr(rgid), uintptr(egid), uintptr(sgid))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_setresgid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setresgid setresgid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setresuid(ruid int, euid int, suid int) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_setresuid_trampoline_addr, uintptr(ruid), uintptr(euid), uintptr(suid))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_setresuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setresuid setresuid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setrlimit(which int, lim *Rlimit) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_setrlimit_trampoline_addr, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_setrlimit_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setrlimit setrlimit "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setrtable(rtable int) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_setrtable_trampoline_addr, uintptr(rtable), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_setrtable_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setrtable setrtable "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setsid() (pid int, err error) {
+	r0, _, e1 := syscall_rawSyscall(libc_setsid_trampoline_addr, 0, 0, 0)
+	pid = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_setsid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setsid setsid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Settimeofday(tp *Timeval) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_settimeofday_trampoline_addr, uintptr(unsafe.Pointer(tp)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_settimeofday_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_settimeofday settimeofday "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setuid(uid int) (err error) {
+	_, _, e1 := syscall_rawSyscall(libc_setuid_trampoline_addr, uintptr(uid), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_setuid_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_setuid setuid "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Stat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_stat_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_stat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_stat stat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Statfs(path string, stat *Statfs_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_statfs_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_statfs_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_statfs statfs "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Symlink(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_symlink_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_symlink_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_symlink symlink "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Symlinkat(oldpath string, newdirfd int, newpath string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(oldpath)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(newpath)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_symlinkat_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_symlinkat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_symlinkat symlinkat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sync() (err error) {
+	_, _, e1 := syscall_syscall(libc_sync_trampoline_addr, 0, 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_sync_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_sync sync "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Truncate(path string, length int64) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_truncate_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(length), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_truncate_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_truncate truncate "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Umask(newmask int) (oldmask int) {
+	r0, _, _ := syscall_syscall(libc_umask_trampoline_addr, uintptr(newmask), 0, 0)
+	oldmask = int(r0)
+	return
+}
+
+var libc_umask_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_umask umask "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unlink(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_unlink_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_unlink_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_unlink unlink "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unlinkat(dirfd int, path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_unlinkat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_unlinkat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_unlinkat unlinkat "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unmount(path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall(libc_unmount_trampoline_addr, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_unmount_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_unmount unmount "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func write(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := syscall_syscall(libc_write_trampoline_addr, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_write_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_write write "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
+	r0, _, e1 := syscall_syscall6(libc_mmap_trampoline_addr, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos))
+	ret = uintptr(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_mmap_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_mmap mmap "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func munmap(addr uintptr, length uintptr) (err error) {
+	_, _, e1 := syscall_syscall(libc_munmap_trampoline_addr, uintptr(addr), uintptr(length), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_munmap_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_munmap munmap "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
+	r0, _, e1 := syscall_syscall(libc_read_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
+	r0, _, e1 := syscall_syscall(libc_write_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := syscall_syscall6(libc_utimensat_trampoline_addr, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+var libc_utimensat_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_utimensat utimensat "libc.so"
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.s b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.s
new file mode 100644
index 0000000..7dba789
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.s
@@ -0,0 +1,796 @@
+// go run mkasm.go openbsd riscv64
+// Code generated by the command above; DO NOT EDIT.
+
+#include "textflag.h"
+
+TEXT libc_getgroups_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getgroups(SB)
+
+GLOBL	·libc_getgroups_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getgroups_trampoline_addr(SB)/8, $libc_getgroups_trampoline<>(SB)
+
+TEXT libc_setgroups_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setgroups(SB)
+
+GLOBL	·libc_setgroups_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setgroups_trampoline_addr(SB)/8, $libc_setgroups_trampoline<>(SB)
+
+TEXT libc_wait4_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_wait4(SB)
+
+GLOBL	·libc_wait4_trampoline_addr(SB), RODATA, $8
+DATA	·libc_wait4_trampoline_addr(SB)/8, $libc_wait4_trampoline<>(SB)
+
+TEXT libc_accept_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_accept(SB)
+
+GLOBL	·libc_accept_trampoline_addr(SB), RODATA, $8
+DATA	·libc_accept_trampoline_addr(SB)/8, $libc_accept_trampoline<>(SB)
+
+TEXT libc_bind_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_bind(SB)
+
+GLOBL	·libc_bind_trampoline_addr(SB), RODATA, $8
+DATA	·libc_bind_trampoline_addr(SB)/8, $libc_bind_trampoline<>(SB)
+
+TEXT libc_connect_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_connect(SB)
+
+GLOBL	·libc_connect_trampoline_addr(SB), RODATA, $8
+DATA	·libc_connect_trampoline_addr(SB)/8, $libc_connect_trampoline<>(SB)
+
+TEXT libc_socket_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_socket(SB)
+
+GLOBL	·libc_socket_trampoline_addr(SB), RODATA, $8
+DATA	·libc_socket_trampoline_addr(SB)/8, $libc_socket_trampoline<>(SB)
+
+TEXT libc_getsockopt_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getsockopt(SB)
+
+GLOBL	·libc_getsockopt_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getsockopt_trampoline_addr(SB)/8, $libc_getsockopt_trampoline<>(SB)
+
+TEXT libc_setsockopt_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setsockopt(SB)
+
+GLOBL	·libc_setsockopt_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setsockopt_trampoline_addr(SB)/8, $libc_setsockopt_trampoline<>(SB)
+
+TEXT libc_getpeername_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getpeername(SB)
+
+GLOBL	·libc_getpeername_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getpeername_trampoline_addr(SB)/8, $libc_getpeername_trampoline<>(SB)
+
+TEXT libc_getsockname_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getsockname(SB)
+
+GLOBL	·libc_getsockname_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getsockname_trampoline_addr(SB)/8, $libc_getsockname_trampoline<>(SB)
+
+TEXT libc_shutdown_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_shutdown(SB)
+
+GLOBL	·libc_shutdown_trampoline_addr(SB), RODATA, $8
+DATA	·libc_shutdown_trampoline_addr(SB)/8, $libc_shutdown_trampoline<>(SB)
+
+TEXT libc_socketpair_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_socketpair(SB)
+
+GLOBL	·libc_socketpair_trampoline_addr(SB), RODATA, $8
+DATA	·libc_socketpair_trampoline_addr(SB)/8, $libc_socketpair_trampoline<>(SB)
+
+TEXT libc_recvfrom_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_recvfrom(SB)
+
+GLOBL	·libc_recvfrom_trampoline_addr(SB), RODATA, $8
+DATA	·libc_recvfrom_trampoline_addr(SB)/8, $libc_recvfrom_trampoline<>(SB)
+
+TEXT libc_sendto_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_sendto(SB)
+
+GLOBL	·libc_sendto_trampoline_addr(SB), RODATA, $8
+DATA	·libc_sendto_trampoline_addr(SB)/8, $libc_sendto_trampoline<>(SB)
+
+TEXT libc_recvmsg_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_recvmsg(SB)
+
+GLOBL	·libc_recvmsg_trampoline_addr(SB), RODATA, $8
+DATA	·libc_recvmsg_trampoline_addr(SB)/8, $libc_recvmsg_trampoline<>(SB)
+
+TEXT libc_sendmsg_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_sendmsg(SB)
+
+GLOBL	·libc_sendmsg_trampoline_addr(SB), RODATA, $8
+DATA	·libc_sendmsg_trampoline_addr(SB)/8, $libc_sendmsg_trampoline<>(SB)
+
+TEXT libc_kevent_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_kevent(SB)
+
+GLOBL	·libc_kevent_trampoline_addr(SB), RODATA, $8
+DATA	·libc_kevent_trampoline_addr(SB)/8, $libc_kevent_trampoline<>(SB)
+
+TEXT libc_utimes_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_utimes(SB)
+
+GLOBL	·libc_utimes_trampoline_addr(SB), RODATA, $8
+DATA	·libc_utimes_trampoline_addr(SB)/8, $libc_utimes_trampoline<>(SB)
+
+TEXT libc_futimes_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_futimes(SB)
+
+GLOBL	·libc_futimes_trampoline_addr(SB), RODATA, $8
+DATA	·libc_futimes_trampoline_addr(SB)/8, $libc_futimes_trampoline<>(SB)
+
+TEXT libc_poll_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_poll(SB)
+
+GLOBL	·libc_poll_trampoline_addr(SB), RODATA, $8
+DATA	·libc_poll_trampoline_addr(SB)/8, $libc_poll_trampoline<>(SB)
+
+TEXT libc_madvise_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_madvise(SB)
+
+GLOBL	·libc_madvise_trampoline_addr(SB), RODATA, $8
+DATA	·libc_madvise_trampoline_addr(SB)/8, $libc_madvise_trampoline<>(SB)
+
+TEXT libc_mlock_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mlock(SB)
+
+GLOBL	·libc_mlock_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mlock_trampoline_addr(SB)/8, $libc_mlock_trampoline<>(SB)
+
+TEXT libc_mlockall_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mlockall(SB)
+
+GLOBL	·libc_mlockall_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mlockall_trampoline_addr(SB)/8, $libc_mlockall_trampoline<>(SB)
+
+TEXT libc_mprotect_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mprotect(SB)
+
+GLOBL	·libc_mprotect_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mprotect_trampoline_addr(SB)/8, $libc_mprotect_trampoline<>(SB)
+
+TEXT libc_msync_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_msync(SB)
+
+GLOBL	·libc_msync_trampoline_addr(SB), RODATA, $8
+DATA	·libc_msync_trampoline_addr(SB)/8, $libc_msync_trampoline<>(SB)
+
+TEXT libc_munlock_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_munlock(SB)
+
+GLOBL	·libc_munlock_trampoline_addr(SB), RODATA, $8
+DATA	·libc_munlock_trampoline_addr(SB)/8, $libc_munlock_trampoline<>(SB)
+
+TEXT libc_munlockall_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_munlockall(SB)
+
+GLOBL	·libc_munlockall_trampoline_addr(SB), RODATA, $8
+DATA	·libc_munlockall_trampoline_addr(SB)/8, $libc_munlockall_trampoline<>(SB)
+
+TEXT libc_pipe2_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_pipe2(SB)
+
+GLOBL	·libc_pipe2_trampoline_addr(SB), RODATA, $8
+DATA	·libc_pipe2_trampoline_addr(SB)/8, $libc_pipe2_trampoline<>(SB)
+
+TEXT libc_getdents_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getdents(SB)
+
+GLOBL	·libc_getdents_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getdents_trampoline_addr(SB)/8, $libc_getdents_trampoline<>(SB)
+
+TEXT libc_getcwd_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getcwd(SB)
+
+GLOBL	·libc_getcwd_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getcwd_trampoline_addr(SB)/8, $libc_getcwd_trampoline<>(SB)
+
+TEXT libc_ioctl_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_ioctl(SB)
+
+GLOBL	·libc_ioctl_trampoline_addr(SB), RODATA, $8
+DATA	·libc_ioctl_trampoline_addr(SB)/8, $libc_ioctl_trampoline<>(SB)
+
+TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_sysctl(SB)
+
+GLOBL	·libc_sysctl_trampoline_addr(SB), RODATA, $8
+DATA	·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB)
+
+TEXT libc_ppoll_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_ppoll(SB)
+
+GLOBL	·libc_ppoll_trampoline_addr(SB), RODATA, $8
+DATA	·libc_ppoll_trampoline_addr(SB)/8, $libc_ppoll_trampoline<>(SB)
+
+TEXT libc_access_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_access(SB)
+
+GLOBL	·libc_access_trampoline_addr(SB), RODATA, $8
+DATA	·libc_access_trampoline_addr(SB)/8, $libc_access_trampoline<>(SB)
+
+TEXT libc_adjtime_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_adjtime(SB)
+
+GLOBL	·libc_adjtime_trampoline_addr(SB), RODATA, $8
+DATA	·libc_adjtime_trampoline_addr(SB)/8, $libc_adjtime_trampoline<>(SB)
+
+TEXT libc_chdir_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_chdir(SB)
+
+GLOBL	·libc_chdir_trampoline_addr(SB), RODATA, $8
+DATA	·libc_chdir_trampoline_addr(SB)/8, $libc_chdir_trampoline<>(SB)
+
+TEXT libc_chflags_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_chflags(SB)
+
+GLOBL	·libc_chflags_trampoline_addr(SB), RODATA, $8
+DATA	·libc_chflags_trampoline_addr(SB)/8, $libc_chflags_trampoline<>(SB)
+
+TEXT libc_chmod_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_chmod(SB)
+
+GLOBL	·libc_chmod_trampoline_addr(SB), RODATA, $8
+DATA	·libc_chmod_trampoline_addr(SB)/8, $libc_chmod_trampoline<>(SB)
+
+TEXT libc_chown_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_chown(SB)
+
+GLOBL	·libc_chown_trampoline_addr(SB), RODATA, $8
+DATA	·libc_chown_trampoline_addr(SB)/8, $libc_chown_trampoline<>(SB)
+
+TEXT libc_chroot_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_chroot(SB)
+
+GLOBL	·libc_chroot_trampoline_addr(SB), RODATA, $8
+DATA	·libc_chroot_trampoline_addr(SB)/8, $libc_chroot_trampoline<>(SB)
+
+TEXT libc_close_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_close(SB)
+
+GLOBL	·libc_close_trampoline_addr(SB), RODATA, $8
+DATA	·libc_close_trampoline_addr(SB)/8, $libc_close_trampoline<>(SB)
+
+TEXT libc_dup_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_dup(SB)
+
+GLOBL	·libc_dup_trampoline_addr(SB), RODATA, $8
+DATA	·libc_dup_trampoline_addr(SB)/8, $libc_dup_trampoline<>(SB)
+
+TEXT libc_dup2_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_dup2(SB)
+
+GLOBL	·libc_dup2_trampoline_addr(SB), RODATA, $8
+DATA	·libc_dup2_trampoline_addr(SB)/8, $libc_dup2_trampoline<>(SB)
+
+TEXT libc_dup3_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_dup3(SB)
+
+GLOBL	·libc_dup3_trampoline_addr(SB), RODATA, $8
+DATA	·libc_dup3_trampoline_addr(SB)/8, $libc_dup3_trampoline<>(SB)
+
+TEXT libc_exit_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_exit(SB)
+
+GLOBL	·libc_exit_trampoline_addr(SB), RODATA, $8
+DATA	·libc_exit_trampoline_addr(SB)/8, $libc_exit_trampoline<>(SB)
+
+TEXT libc_faccessat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_faccessat(SB)
+
+GLOBL	·libc_faccessat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_faccessat_trampoline_addr(SB)/8, $libc_faccessat_trampoline<>(SB)
+
+TEXT libc_fchdir_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fchdir(SB)
+
+GLOBL	·libc_fchdir_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fchdir_trampoline_addr(SB)/8, $libc_fchdir_trampoline<>(SB)
+
+TEXT libc_fchflags_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fchflags(SB)
+
+GLOBL	·libc_fchflags_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fchflags_trampoline_addr(SB)/8, $libc_fchflags_trampoline<>(SB)
+
+TEXT libc_fchmod_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fchmod(SB)
+
+GLOBL	·libc_fchmod_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fchmod_trampoline_addr(SB)/8, $libc_fchmod_trampoline<>(SB)
+
+TEXT libc_fchmodat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fchmodat(SB)
+
+GLOBL	·libc_fchmodat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fchmodat_trampoline_addr(SB)/8, $libc_fchmodat_trampoline<>(SB)
+
+TEXT libc_fchown_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fchown(SB)
+
+GLOBL	·libc_fchown_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fchown_trampoline_addr(SB)/8, $libc_fchown_trampoline<>(SB)
+
+TEXT libc_fchownat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fchownat(SB)
+
+GLOBL	·libc_fchownat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fchownat_trampoline_addr(SB)/8, $libc_fchownat_trampoline<>(SB)
+
+TEXT libc_flock_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_flock(SB)
+
+GLOBL	·libc_flock_trampoline_addr(SB), RODATA, $8
+DATA	·libc_flock_trampoline_addr(SB)/8, $libc_flock_trampoline<>(SB)
+
+TEXT libc_fpathconf_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fpathconf(SB)
+
+GLOBL	·libc_fpathconf_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fpathconf_trampoline_addr(SB)/8, $libc_fpathconf_trampoline<>(SB)
+
+TEXT libc_fstat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fstat(SB)
+
+GLOBL	·libc_fstat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fstat_trampoline_addr(SB)/8, $libc_fstat_trampoline<>(SB)
+
+TEXT libc_fstatat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fstatat(SB)
+
+GLOBL	·libc_fstatat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fstatat_trampoline_addr(SB)/8, $libc_fstatat_trampoline<>(SB)
+
+TEXT libc_fstatfs_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fstatfs(SB)
+
+GLOBL	·libc_fstatfs_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fstatfs_trampoline_addr(SB)/8, $libc_fstatfs_trampoline<>(SB)
+
+TEXT libc_fsync_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_fsync(SB)
+
+GLOBL	·libc_fsync_trampoline_addr(SB), RODATA, $8
+DATA	·libc_fsync_trampoline_addr(SB)/8, $libc_fsync_trampoline<>(SB)
+
+TEXT libc_ftruncate_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_ftruncate(SB)
+
+GLOBL	·libc_ftruncate_trampoline_addr(SB), RODATA, $8
+DATA	·libc_ftruncate_trampoline_addr(SB)/8, $libc_ftruncate_trampoline<>(SB)
+
+TEXT libc_getegid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getegid(SB)
+
+GLOBL	·libc_getegid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getegid_trampoline_addr(SB)/8, $libc_getegid_trampoline<>(SB)
+
+TEXT libc_geteuid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_geteuid(SB)
+
+GLOBL	·libc_geteuid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_geteuid_trampoline_addr(SB)/8, $libc_geteuid_trampoline<>(SB)
+
+TEXT libc_getgid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getgid(SB)
+
+GLOBL	·libc_getgid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getgid_trampoline_addr(SB)/8, $libc_getgid_trampoline<>(SB)
+
+TEXT libc_getpgid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getpgid(SB)
+
+GLOBL	·libc_getpgid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getpgid_trampoline_addr(SB)/8, $libc_getpgid_trampoline<>(SB)
+
+TEXT libc_getpgrp_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getpgrp(SB)
+
+GLOBL	·libc_getpgrp_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getpgrp_trampoline_addr(SB)/8, $libc_getpgrp_trampoline<>(SB)
+
+TEXT libc_getpid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getpid(SB)
+
+GLOBL	·libc_getpid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getpid_trampoline_addr(SB)/8, $libc_getpid_trampoline<>(SB)
+
+TEXT libc_getppid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getppid(SB)
+
+GLOBL	·libc_getppid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getppid_trampoline_addr(SB)/8, $libc_getppid_trampoline<>(SB)
+
+TEXT libc_getpriority_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getpriority(SB)
+
+GLOBL	·libc_getpriority_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getpriority_trampoline_addr(SB)/8, $libc_getpriority_trampoline<>(SB)
+
+TEXT libc_getrlimit_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getrlimit(SB)
+
+GLOBL	·libc_getrlimit_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getrlimit_trampoline_addr(SB)/8, $libc_getrlimit_trampoline<>(SB)
+
+TEXT libc_getrtable_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getrtable(SB)
+
+GLOBL	·libc_getrtable_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getrtable_trampoline_addr(SB)/8, $libc_getrtable_trampoline<>(SB)
+
+TEXT libc_getrusage_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getrusage(SB)
+
+GLOBL	·libc_getrusage_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getrusage_trampoline_addr(SB)/8, $libc_getrusage_trampoline<>(SB)
+
+TEXT libc_getsid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getsid(SB)
+
+GLOBL	·libc_getsid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getsid_trampoline_addr(SB)/8, $libc_getsid_trampoline<>(SB)
+
+TEXT libc_gettimeofday_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_gettimeofday(SB)
+
+GLOBL	·libc_gettimeofday_trampoline_addr(SB), RODATA, $8
+DATA	·libc_gettimeofday_trampoline_addr(SB)/8, $libc_gettimeofday_trampoline<>(SB)
+
+TEXT libc_getuid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_getuid(SB)
+
+GLOBL	·libc_getuid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_getuid_trampoline_addr(SB)/8, $libc_getuid_trampoline<>(SB)
+
+TEXT libc_issetugid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_issetugid(SB)
+
+GLOBL	·libc_issetugid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_issetugid_trampoline_addr(SB)/8, $libc_issetugid_trampoline<>(SB)
+
+TEXT libc_kill_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_kill(SB)
+
+GLOBL	·libc_kill_trampoline_addr(SB), RODATA, $8
+DATA	·libc_kill_trampoline_addr(SB)/8, $libc_kill_trampoline<>(SB)
+
+TEXT libc_kqueue_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_kqueue(SB)
+
+GLOBL	·libc_kqueue_trampoline_addr(SB), RODATA, $8
+DATA	·libc_kqueue_trampoline_addr(SB)/8, $libc_kqueue_trampoline<>(SB)
+
+TEXT libc_lchown_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_lchown(SB)
+
+GLOBL	·libc_lchown_trampoline_addr(SB), RODATA, $8
+DATA	·libc_lchown_trampoline_addr(SB)/8, $libc_lchown_trampoline<>(SB)
+
+TEXT libc_link_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_link(SB)
+
+GLOBL	·libc_link_trampoline_addr(SB), RODATA, $8
+DATA	·libc_link_trampoline_addr(SB)/8, $libc_link_trampoline<>(SB)
+
+TEXT libc_linkat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_linkat(SB)
+
+GLOBL	·libc_linkat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_linkat_trampoline_addr(SB)/8, $libc_linkat_trampoline<>(SB)
+
+TEXT libc_listen_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_listen(SB)
+
+GLOBL	·libc_listen_trampoline_addr(SB), RODATA, $8
+DATA	·libc_listen_trampoline_addr(SB)/8, $libc_listen_trampoline<>(SB)
+
+TEXT libc_lstat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_lstat(SB)
+
+GLOBL	·libc_lstat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_lstat_trampoline_addr(SB)/8, $libc_lstat_trampoline<>(SB)
+
+TEXT libc_mkdir_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mkdir(SB)
+
+GLOBL	·libc_mkdir_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mkdir_trampoline_addr(SB)/8, $libc_mkdir_trampoline<>(SB)
+
+TEXT libc_mkdirat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mkdirat(SB)
+
+GLOBL	·libc_mkdirat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mkdirat_trampoline_addr(SB)/8, $libc_mkdirat_trampoline<>(SB)
+
+TEXT libc_mkfifo_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mkfifo(SB)
+
+GLOBL	·libc_mkfifo_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mkfifo_trampoline_addr(SB)/8, $libc_mkfifo_trampoline<>(SB)
+
+TEXT libc_mkfifoat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mkfifoat(SB)
+
+GLOBL	·libc_mkfifoat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mkfifoat_trampoline_addr(SB)/8, $libc_mkfifoat_trampoline<>(SB)
+
+TEXT libc_mknod_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mknod(SB)
+
+GLOBL	·libc_mknod_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mknod_trampoline_addr(SB)/8, $libc_mknod_trampoline<>(SB)
+
+TEXT libc_mknodat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mknodat(SB)
+
+GLOBL	·libc_mknodat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mknodat_trampoline_addr(SB)/8, $libc_mknodat_trampoline<>(SB)
+
+TEXT libc_nanosleep_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_nanosleep(SB)
+
+GLOBL	·libc_nanosleep_trampoline_addr(SB), RODATA, $8
+DATA	·libc_nanosleep_trampoline_addr(SB)/8, $libc_nanosleep_trampoline<>(SB)
+
+TEXT libc_open_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_open(SB)
+
+GLOBL	·libc_open_trampoline_addr(SB), RODATA, $8
+DATA	·libc_open_trampoline_addr(SB)/8, $libc_open_trampoline<>(SB)
+
+TEXT libc_openat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_openat(SB)
+
+GLOBL	·libc_openat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_openat_trampoline_addr(SB)/8, $libc_openat_trampoline<>(SB)
+
+TEXT libc_pathconf_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_pathconf(SB)
+
+GLOBL	·libc_pathconf_trampoline_addr(SB), RODATA, $8
+DATA	·libc_pathconf_trampoline_addr(SB)/8, $libc_pathconf_trampoline<>(SB)
+
+TEXT libc_pread_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_pread(SB)
+
+GLOBL	·libc_pread_trampoline_addr(SB), RODATA, $8
+DATA	·libc_pread_trampoline_addr(SB)/8, $libc_pread_trampoline<>(SB)
+
+TEXT libc_pwrite_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_pwrite(SB)
+
+GLOBL	·libc_pwrite_trampoline_addr(SB), RODATA, $8
+DATA	·libc_pwrite_trampoline_addr(SB)/8, $libc_pwrite_trampoline<>(SB)
+
+TEXT libc_read_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_read(SB)
+
+GLOBL	·libc_read_trampoline_addr(SB), RODATA, $8
+DATA	·libc_read_trampoline_addr(SB)/8, $libc_read_trampoline<>(SB)
+
+TEXT libc_readlink_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_readlink(SB)
+
+GLOBL	·libc_readlink_trampoline_addr(SB), RODATA, $8
+DATA	·libc_readlink_trampoline_addr(SB)/8, $libc_readlink_trampoline<>(SB)
+
+TEXT libc_readlinkat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_readlinkat(SB)
+
+GLOBL	·libc_readlinkat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_readlinkat_trampoline_addr(SB)/8, $libc_readlinkat_trampoline<>(SB)
+
+TEXT libc_rename_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_rename(SB)
+
+GLOBL	·libc_rename_trampoline_addr(SB), RODATA, $8
+DATA	·libc_rename_trampoline_addr(SB)/8, $libc_rename_trampoline<>(SB)
+
+TEXT libc_renameat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_renameat(SB)
+
+GLOBL	·libc_renameat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_renameat_trampoline_addr(SB)/8, $libc_renameat_trampoline<>(SB)
+
+TEXT libc_revoke_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_revoke(SB)
+
+GLOBL	·libc_revoke_trampoline_addr(SB), RODATA, $8
+DATA	·libc_revoke_trampoline_addr(SB)/8, $libc_revoke_trampoline<>(SB)
+
+TEXT libc_rmdir_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_rmdir(SB)
+
+GLOBL	·libc_rmdir_trampoline_addr(SB), RODATA, $8
+DATA	·libc_rmdir_trampoline_addr(SB)/8, $libc_rmdir_trampoline<>(SB)
+
+TEXT libc_lseek_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_lseek(SB)
+
+GLOBL	·libc_lseek_trampoline_addr(SB), RODATA, $8
+DATA	·libc_lseek_trampoline_addr(SB)/8, $libc_lseek_trampoline<>(SB)
+
+TEXT libc_select_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_select(SB)
+
+GLOBL	·libc_select_trampoline_addr(SB), RODATA, $8
+DATA	·libc_select_trampoline_addr(SB)/8, $libc_select_trampoline<>(SB)
+
+TEXT libc_setegid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setegid(SB)
+
+GLOBL	·libc_setegid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setegid_trampoline_addr(SB)/8, $libc_setegid_trampoline<>(SB)
+
+TEXT libc_seteuid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_seteuid(SB)
+
+GLOBL	·libc_seteuid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_seteuid_trampoline_addr(SB)/8, $libc_seteuid_trampoline<>(SB)
+
+TEXT libc_setgid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setgid(SB)
+
+GLOBL	·libc_setgid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setgid_trampoline_addr(SB)/8, $libc_setgid_trampoline<>(SB)
+
+TEXT libc_setlogin_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setlogin(SB)
+
+GLOBL	·libc_setlogin_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setlogin_trampoline_addr(SB)/8, $libc_setlogin_trampoline<>(SB)
+
+TEXT libc_setpgid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setpgid(SB)
+
+GLOBL	·libc_setpgid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setpgid_trampoline_addr(SB)/8, $libc_setpgid_trampoline<>(SB)
+
+TEXT libc_setpriority_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setpriority(SB)
+
+GLOBL	·libc_setpriority_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setpriority_trampoline_addr(SB)/8, $libc_setpriority_trampoline<>(SB)
+
+TEXT libc_setregid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setregid(SB)
+
+GLOBL	·libc_setregid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setregid_trampoline_addr(SB)/8, $libc_setregid_trampoline<>(SB)
+
+TEXT libc_setreuid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setreuid(SB)
+
+GLOBL	·libc_setreuid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setreuid_trampoline_addr(SB)/8, $libc_setreuid_trampoline<>(SB)
+
+TEXT libc_setresgid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setresgid(SB)
+
+GLOBL	·libc_setresgid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setresgid_trampoline_addr(SB)/8, $libc_setresgid_trampoline<>(SB)
+
+TEXT libc_setresuid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setresuid(SB)
+
+GLOBL	·libc_setresuid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setresuid_trampoline_addr(SB)/8, $libc_setresuid_trampoline<>(SB)
+
+TEXT libc_setrlimit_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setrlimit(SB)
+
+GLOBL	·libc_setrlimit_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setrlimit_trampoline_addr(SB)/8, $libc_setrlimit_trampoline<>(SB)
+
+TEXT libc_setrtable_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setrtable(SB)
+
+GLOBL	·libc_setrtable_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setrtable_trampoline_addr(SB)/8, $libc_setrtable_trampoline<>(SB)
+
+TEXT libc_setsid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setsid(SB)
+
+GLOBL	·libc_setsid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setsid_trampoline_addr(SB)/8, $libc_setsid_trampoline<>(SB)
+
+TEXT libc_settimeofday_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_settimeofday(SB)
+
+GLOBL	·libc_settimeofday_trampoline_addr(SB), RODATA, $8
+DATA	·libc_settimeofday_trampoline_addr(SB)/8, $libc_settimeofday_trampoline<>(SB)
+
+TEXT libc_setuid_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_setuid(SB)
+
+GLOBL	·libc_setuid_trampoline_addr(SB), RODATA, $8
+DATA	·libc_setuid_trampoline_addr(SB)/8, $libc_setuid_trampoline<>(SB)
+
+TEXT libc_stat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_stat(SB)
+
+GLOBL	·libc_stat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_stat_trampoline_addr(SB)/8, $libc_stat_trampoline<>(SB)
+
+TEXT libc_statfs_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_statfs(SB)
+
+GLOBL	·libc_statfs_trampoline_addr(SB), RODATA, $8
+DATA	·libc_statfs_trampoline_addr(SB)/8, $libc_statfs_trampoline<>(SB)
+
+TEXT libc_symlink_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_symlink(SB)
+
+GLOBL	·libc_symlink_trampoline_addr(SB), RODATA, $8
+DATA	·libc_symlink_trampoline_addr(SB)/8, $libc_symlink_trampoline<>(SB)
+
+TEXT libc_symlinkat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_symlinkat(SB)
+
+GLOBL	·libc_symlinkat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_symlinkat_trampoline_addr(SB)/8, $libc_symlinkat_trampoline<>(SB)
+
+TEXT libc_sync_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_sync(SB)
+
+GLOBL	·libc_sync_trampoline_addr(SB), RODATA, $8
+DATA	·libc_sync_trampoline_addr(SB)/8, $libc_sync_trampoline<>(SB)
+
+TEXT libc_truncate_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_truncate(SB)
+
+GLOBL	·libc_truncate_trampoline_addr(SB), RODATA, $8
+DATA	·libc_truncate_trampoline_addr(SB)/8, $libc_truncate_trampoline<>(SB)
+
+TEXT libc_umask_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_umask(SB)
+
+GLOBL	·libc_umask_trampoline_addr(SB), RODATA, $8
+DATA	·libc_umask_trampoline_addr(SB)/8, $libc_umask_trampoline<>(SB)
+
+TEXT libc_unlink_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_unlink(SB)
+
+GLOBL	·libc_unlink_trampoline_addr(SB), RODATA, $8
+DATA	·libc_unlink_trampoline_addr(SB)/8, $libc_unlink_trampoline<>(SB)
+
+TEXT libc_unlinkat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_unlinkat(SB)
+
+GLOBL	·libc_unlinkat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_unlinkat_trampoline_addr(SB)/8, $libc_unlinkat_trampoline<>(SB)
+
+TEXT libc_unmount_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_unmount(SB)
+
+GLOBL	·libc_unmount_trampoline_addr(SB), RODATA, $8
+DATA	·libc_unmount_trampoline_addr(SB)/8, $libc_unmount_trampoline<>(SB)
+
+TEXT libc_write_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_write(SB)
+
+GLOBL	·libc_write_trampoline_addr(SB), RODATA, $8
+DATA	·libc_write_trampoline_addr(SB)/8, $libc_write_trampoline<>(SB)
+
+TEXT libc_mmap_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_mmap(SB)
+
+GLOBL	·libc_mmap_trampoline_addr(SB), RODATA, $8
+DATA	·libc_mmap_trampoline_addr(SB)/8, $libc_mmap_trampoline<>(SB)
+
+TEXT libc_munmap_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_munmap(SB)
+
+GLOBL	·libc_munmap_trampoline_addr(SB), RODATA, $8
+DATA	·libc_munmap_trampoline_addr(SB)/8, $libc_munmap_trampoline<>(SB)
+
+TEXT libc_utimensat_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_utimensat(SB)
+
+GLOBL	·libc_utimensat_trampoline_addr(SB), RODATA, $8
+DATA	·libc_utimensat_trampoline_addr(SB)/8, $libc_utimensat_trampoline<>(SB)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go
index fdf53f8..91f5a2b 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go
@@ -147,6 +147,8 @@
 //go:cgo_import_dynamic libc_port_dissociate port_dissociate "libc.so"
 //go:cgo_import_dynamic libc_port_get port_get "libc.so"
 //go:cgo_import_dynamic libc_port_getn port_getn "libc.so"
+//go:cgo_import_dynamic libc_putmsg putmsg "libc.so"
+//go:cgo_import_dynamic libc_getmsg getmsg "libc.so"
 
 //go:linkname procpipe libc_pipe
 //go:linkname procpipe2 libc_pipe2
@@ -284,6 +286,8 @@
 //go:linkname procport_dissociate libc_port_dissociate
 //go:linkname procport_get libc_port_get
 //go:linkname procport_getn libc_port_getn
+//go:linkname procputmsg libc_putmsg
+//go:linkname procgetmsg libc_getmsg
 
 var (
 	procpipe,
@@ -421,7 +425,9 @@
 	procport_associate,
 	procport_dissociate,
 	procport_get,
-	procport_getn syscallFunc
+	procport_getn,
+	procputmsg,
+	procgetmsg syscallFunc
 )
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
@@ -2065,3 +2071,23 @@
 	}
 	return
 }
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func putmsg(fd int, clptr *strbuf, dataptr *strbuf, flags int) (err error) {
+	_, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procputmsg)), 4, uintptr(fd), uintptr(unsafe.Pointer(clptr)), uintptr(unsafe.Pointer(dataptr)), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getmsg(fd int, clptr *strbuf, dataptr *strbuf, flags *int) (err error) {
+	_, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procgetmsg)), 4, uintptr(fd), uintptr(unsafe.Pointer(clptr)), uintptr(unsafe.Pointer(dataptr)), uintptr(unsafe.Pointer(flags)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_ppc64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_ppc64.go
new file mode 100644
index 0000000..e440544
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_ppc64.go
@@ -0,0 +1,281 @@
+// go run mksysctl_openbsd.go
+// Code generated by the command above; DO NOT EDIT.
+
+//go:build ppc64 && openbsd
+// +build ppc64,openbsd
+
+package unix
+
+type mibentry struct {
+	ctlname string
+	ctloid  []_C_int
+}
+
+var sysctlMib = []mibentry{
+	{"ddb.console", []_C_int{9, 6}},
+	{"ddb.log", []_C_int{9, 7}},
+	{"ddb.max_line", []_C_int{9, 3}},
+	{"ddb.max_width", []_C_int{9, 2}},
+	{"ddb.panic", []_C_int{9, 5}},
+	{"ddb.profile", []_C_int{9, 9}},
+	{"ddb.radix", []_C_int{9, 1}},
+	{"ddb.tab_stop_width", []_C_int{9, 4}},
+	{"ddb.trigger", []_C_int{9, 8}},
+	{"fs.posix.setuid", []_C_int{3, 1, 1}},
+	{"hw.allowpowerdown", []_C_int{6, 22}},
+	{"hw.byteorder", []_C_int{6, 4}},
+	{"hw.cpuspeed", []_C_int{6, 12}},
+	{"hw.diskcount", []_C_int{6, 10}},
+	{"hw.disknames", []_C_int{6, 8}},
+	{"hw.diskstats", []_C_int{6, 9}},
+	{"hw.machine", []_C_int{6, 1}},
+	{"hw.model", []_C_int{6, 2}},
+	{"hw.ncpu", []_C_int{6, 3}},
+	{"hw.ncpufound", []_C_int{6, 21}},
+	{"hw.ncpuonline", []_C_int{6, 25}},
+	{"hw.pagesize", []_C_int{6, 7}},
+	{"hw.perfpolicy", []_C_int{6, 23}},
+	{"hw.physmem", []_C_int{6, 19}},
+	{"hw.power", []_C_int{6, 26}},
+	{"hw.product", []_C_int{6, 15}},
+	{"hw.serialno", []_C_int{6, 17}},
+	{"hw.setperf", []_C_int{6, 13}},
+	{"hw.smt", []_C_int{6, 24}},
+	{"hw.usermem", []_C_int{6, 20}},
+	{"hw.uuid", []_C_int{6, 18}},
+	{"hw.vendor", []_C_int{6, 14}},
+	{"hw.version", []_C_int{6, 16}},
+	{"kern.allowdt", []_C_int{1, 65}},
+	{"kern.allowkmem", []_C_int{1, 52}},
+	{"kern.argmax", []_C_int{1, 8}},
+	{"kern.audio", []_C_int{1, 84}},
+	{"kern.boottime", []_C_int{1, 21}},
+	{"kern.bufcachepercent", []_C_int{1, 72}},
+	{"kern.ccpu", []_C_int{1, 45}},
+	{"kern.clockrate", []_C_int{1, 12}},
+	{"kern.consbuf", []_C_int{1, 83}},
+	{"kern.consbufsize", []_C_int{1, 82}},
+	{"kern.consdev", []_C_int{1, 75}},
+	{"kern.cp_time", []_C_int{1, 40}},
+	{"kern.cp_time2", []_C_int{1, 71}},
+	{"kern.cpustats", []_C_int{1, 85}},
+	{"kern.domainname", []_C_int{1, 22}},
+	{"kern.file", []_C_int{1, 73}},
+	{"kern.forkstat", []_C_int{1, 42}},
+	{"kern.fscale", []_C_int{1, 46}},
+	{"kern.fsync", []_C_int{1, 33}},
+	{"kern.global_ptrace", []_C_int{1, 81}},
+	{"kern.hostid", []_C_int{1, 11}},
+	{"kern.hostname", []_C_int{1, 10}},
+	{"kern.intrcnt.nintrcnt", []_C_int{1, 63, 1}},
+	{"kern.job_control", []_C_int{1, 19}},
+	{"kern.malloc.buckets", []_C_int{1, 39, 1}},
+	{"kern.malloc.kmemnames", []_C_int{1, 39, 3}},
+	{"kern.maxclusters", []_C_int{1, 67}},
+	{"kern.maxfiles", []_C_int{1, 7}},
+	{"kern.maxlocksperuid", []_C_int{1, 70}},
+	{"kern.maxpartitions", []_C_int{1, 23}},
+	{"kern.maxproc", []_C_int{1, 6}},
+	{"kern.maxthread", []_C_int{1, 25}},
+	{"kern.maxvnodes", []_C_int{1, 5}},
+	{"kern.mbstat", []_C_int{1, 59}},
+	{"kern.msgbuf", []_C_int{1, 48}},
+	{"kern.msgbufsize", []_C_int{1, 38}},
+	{"kern.nchstats", []_C_int{1, 41}},
+	{"kern.netlivelocks", []_C_int{1, 76}},
+	{"kern.nfiles", []_C_int{1, 56}},
+	{"kern.ngroups", []_C_int{1, 18}},
+	{"kern.nosuidcoredump", []_C_int{1, 32}},
+	{"kern.nprocs", []_C_int{1, 47}},
+	{"kern.nthreads", []_C_int{1, 26}},
+	{"kern.numvnodes", []_C_int{1, 58}},
+	{"kern.osrelease", []_C_int{1, 2}},
+	{"kern.osrevision", []_C_int{1, 3}},
+	{"kern.ostype", []_C_int{1, 1}},
+	{"kern.osversion", []_C_int{1, 27}},
+	{"kern.pfstatus", []_C_int{1, 86}},
+	{"kern.pool_debug", []_C_int{1, 77}},
+	{"kern.posix1version", []_C_int{1, 17}},
+	{"kern.proc", []_C_int{1, 66}},
+	{"kern.rawpartition", []_C_int{1, 24}},
+	{"kern.saved_ids", []_C_int{1, 20}},
+	{"kern.securelevel", []_C_int{1, 9}},
+	{"kern.seminfo", []_C_int{1, 61}},
+	{"kern.shminfo", []_C_int{1, 62}},
+	{"kern.somaxconn", []_C_int{1, 28}},
+	{"kern.sominconn", []_C_int{1, 29}},
+	{"kern.splassert", []_C_int{1, 54}},
+	{"kern.stackgap_random", []_C_int{1, 50}},
+	{"kern.sysvipc_info", []_C_int{1, 51}},
+	{"kern.sysvmsg", []_C_int{1, 34}},
+	{"kern.sysvsem", []_C_int{1, 35}},
+	{"kern.sysvshm", []_C_int{1, 36}},
+	{"kern.timecounter.choice", []_C_int{1, 69, 4}},
+	{"kern.timecounter.hardware", []_C_int{1, 69, 3}},
+	{"kern.timecounter.tick", []_C_int{1, 69, 1}},
+	{"kern.timecounter.timestepwarnings", []_C_int{1, 69, 2}},
+	{"kern.timeout_stats", []_C_int{1, 87}},
+	{"kern.tty.tk_cancc", []_C_int{1, 44, 4}},
+	{"kern.tty.tk_nin", []_C_int{1, 44, 1}},
+	{"kern.tty.tk_nout", []_C_int{1, 44, 2}},
+	{"kern.tty.tk_rawcc", []_C_int{1, 44, 3}},
+	{"kern.tty.ttyinfo", []_C_int{1, 44, 5}},
+	{"kern.ttycount", []_C_int{1, 57}},
+	{"kern.utc_offset", []_C_int{1, 88}},
+	{"kern.version", []_C_int{1, 4}},
+	{"kern.video", []_C_int{1, 89}},
+	{"kern.watchdog.auto", []_C_int{1, 64, 2}},
+	{"kern.watchdog.period", []_C_int{1, 64, 1}},
+	{"kern.witnesswatch", []_C_int{1, 53}},
+	{"kern.wxabort", []_C_int{1, 74}},
+	{"net.bpf.bufsize", []_C_int{4, 31, 1}},
+	{"net.bpf.maxbufsize", []_C_int{4, 31, 2}},
+	{"net.inet.ah.enable", []_C_int{4, 2, 51, 1}},
+	{"net.inet.ah.stats", []_C_int{4, 2, 51, 2}},
+	{"net.inet.carp.allow", []_C_int{4, 2, 112, 1}},
+	{"net.inet.carp.log", []_C_int{4, 2, 112, 3}},
+	{"net.inet.carp.preempt", []_C_int{4, 2, 112, 2}},
+	{"net.inet.carp.stats", []_C_int{4, 2, 112, 4}},
+	{"net.inet.divert.recvspace", []_C_int{4, 2, 258, 1}},
+	{"net.inet.divert.sendspace", []_C_int{4, 2, 258, 2}},
+	{"net.inet.divert.stats", []_C_int{4, 2, 258, 3}},
+	{"net.inet.esp.enable", []_C_int{4, 2, 50, 1}},
+	{"net.inet.esp.stats", []_C_int{4, 2, 50, 4}},
+	{"net.inet.esp.udpencap", []_C_int{4, 2, 50, 2}},
+	{"net.inet.esp.udpencap_port", []_C_int{4, 2, 50, 3}},
+	{"net.inet.etherip.allow", []_C_int{4, 2, 97, 1}},
+	{"net.inet.etherip.stats", []_C_int{4, 2, 97, 2}},
+	{"net.inet.gre.allow", []_C_int{4, 2, 47, 1}},
+	{"net.inet.gre.wccp", []_C_int{4, 2, 47, 2}},
+	{"net.inet.icmp.bmcastecho", []_C_int{4, 2, 1, 2}},
+	{"net.inet.icmp.errppslimit", []_C_int{4, 2, 1, 3}},
+	{"net.inet.icmp.maskrepl", []_C_int{4, 2, 1, 1}},
+	{"net.inet.icmp.rediraccept", []_C_int{4, 2, 1, 4}},
+	{"net.inet.icmp.redirtimeout", []_C_int{4, 2, 1, 5}},
+	{"net.inet.icmp.stats", []_C_int{4, 2, 1, 7}},
+	{"net.inet.icmp.tstamprepl", []_C_int{4, 2, 1, 6}},
+	{"net.inet.igmp.stats", []_C_int{4, 2, 2, 1}},
+	{"net.inet.ip.arpdown", []_C_int{4, 2, 0, 40}},
+	{"net.inet.ip.arpqueued", []_C_int{4, 2, 0, 36}},
+	{"net.inet.ip.arptimeout", []_C_int{4, 2, 0, 39}},
+	{"net.inet.ip.encdebug", []_C_int{4, 2, 0, 12}},
+	{"net.inet.ip.forwarding", []_C_int{4, 2, 0, 1}},
+	{"net.inet.ip.ifq.congestion", []_C_int{4, 2, 0, 30, 4}},
+	{"net.inet.ip.ifq.drops", []_C_int{4, 2, 0, 30, 3}},
+	{"net.inet.ip.ifq.len", []_C_int{4, 2, 0, 30, 1}},
+	{"net.inet.ip.ifq.maxlen", []_C_int{4, 2, 0, 30, 2}},
+	{"net.inet.ip.maxqueue", []_C_int{4, 2, 0, 11}},
+	{"net.inet.ip.mforwarding", []_C_int{4, 2, 0, 31}},
+	{"net.inet.ip.mrtmfc", []_C_int{4, 2, 0, 37}},
+	{"net.inet.ip.mrtproto", []_C_int{4, 2, 0, 34}},
+	{"net.inet.ip.mrtstats", []_C_int{4, 2, 0, 35}},
+	{"net.inet.ip.mrtvif", []_C_int{4, 2, 0, 38}},
+	{"net.inet.ip.mtu", []_C_int{4, 2, 0, 4}},
+	{"net.inet.ip.mtudisc", []_C_int{4, 2, 0, 27}},
+	{"net.inet.ip.mtudisctimeout", []_C_int{4, 2, 0, 28}},
+	{"net.inet.ip.multipath", []_C_int{4, 2, 0, 32}},
+	{"net.inet.ip.portfirst", []_C_int{4, 2, 0, 7}},
+	{"net.inet.ip.porthifirst", []_C_int{4, 2, 0, 9}},
+	{"net.inet.ip.porthilast", []_C_int{4, 2, 0, 10}},
+	{"net.inet.ip.portlast", []_C_int{4, 2, 0, 8}},
+	{"net.inet.ip.redirect", []_C_int{4, 2, 0, 2}},
+	{"net.inet.ip.sourceroute", []_C_int{4, 2, 0, 5}},
+	{"net.inet.ip.stats", []_C_int{4, 2, 0, 33}},
+	{"net.inet.ip.ttl", []_C_int{4, 2, 0, 3}},
+	{"net.inet.ipcomp.enable", []_C_int{4, 2, 108, 1}},
+	{"net.inet.ipcomp.stats", []_C_int{4, 2, 108, 2}},
+	{"net.inet.ipip.allow", []_C_int{4, 2, 4, 1}},
+	{"net.inet.ipip.stats", []_C_int{4, 2, 4, 2}},
+	{"net.inet.pfsync.stats", []_C_int{4, 2, 240, 1}},
+	{"net.inet.tcp.ackonpush", []_C_int{4, 2, 6, 13}},
+	{"net.inet.tcp.always_keepalive", []_C_int{4, 2, 6, 22}},
+	{"net.inet.tcp.baddynamic", []_C_int{4, 2, 6, 6}},
+	{"net.inet.tcp.drop", []_C_int{4, 2, 6, 19}},
+	{"net.inet.tcp.ecn", []_C_int{4, 2, 6, 14}},
+	{"net.inet.tcp.ident", []_C_int{4, 2, 6, 9}},
+	{"net.inet.tcp.keepidle", []_C_int{4, 2, 6, 3}},
+	{"net.inet.tcp.keepinittime", []_C_int{4, 2, 6, 2}},
+	{"net.inet.tcp.keepintvl", []_C_int{4, 2, 6, 4}},
+	{"net.inet.tcp.mssdflt", []_C_int{4, 2, 6, 11}},
+	{"net.inet.tcp.reasslimit", []_C_int{4, 2, 6, 18}},
+	{"net.inet.tcp.rfc1323", []_C_int{4, 2, 6, 1}},
+	{"net.inet.tcp.rfc3390", []_C_int{4, 2, 6, 17}},
+	{"net.inet.tcp.rootonly", []_C_int{4, 2, 6, 24}},
+	{"net.inet.tcp.rstppslimit", []_C_int{4, 2, 6, 12}},
+	{"net.inet.tcp.sack", []_C_int{4, 2, 6, 10}},
+	{"net.inet.tcp.sackholelimit", []_C_int{4, 2, 6, 20}},
+	{"net.inet.tcp.slowhz", []_C_int{4, 2, 6, 5}},
+	{"net.inet.tcp.stats", []_C_int{4, 2, 6, 21}},
+	{"net.inet.tcp.synbucketlimit", []_C_int{4, 2, 6, 16}},
+	{"net.inet.tcp.syncachelimit", []_C_int{4, 2, 6, 15}},
+	{"net.inet.tcp.synhashsize", []_C_int{4, 2, 6, 25}},
+	{"net.inet.tcp.synuselimit", []_C_int{4, 2, 6, 23}},
+	{"net.inet.udp.baddynamic", []_C_int{4, 2, 17, 2}},
+	{"net.inet.udp.checksum", []_C_int{4, 2, 17, 1}},
+	{"net.inet.udp.recvspace", []_C_int{4, 2, 17, 3}},
+	{"net.inet.udp.rootonly", []_C_int{4, 2, 17, 6}},
+	{"net.inet.udp.sendspace", []_C_int{4, 2, 17, 4}},
+	{"net.inet.udp.stats", []_C_int{4, 2, 17, 5}},
+	{"net.inet6.divert.recvspace", []_C_int{4, 24, 86, 1}},
+	{"net.inet6.divert.sendspace", []_C_int{4, 24, 86, 2}},
+	{"net.inet6.divert.stats", []_C_int{4, 24, 86, 3}},
+	{"net.inet6.icmp6.errppslimit", []_C_int{4, 24, 30, 14}},
+	{"net.inet6.icmp6.mtudisc_hiwat", []_C_int{4, 24, 30, 16}},
+	{"net.inet6.icmp6.mtudisc_lowat", []_C_int{4, 24, 30, 17}},
+	{"net.inet6.icmp6.nd6_debug", []_C_int{4, 24, 30, 18}},
+	{"net.inet6.icmp6.nd6_delay", []_C_int{4, 24, 30, 8}},
+	{"net.inet6.icmp6.nd6_maxnudhint", []_C_int{4, 24, 30, 15}},
+	{"net.inet6.icmp6.nd6_mmaxtries", []_C_int{4, 24, 30, 10}},
+	{"net.inet6.icmp6.nd6_umaxtries", []_C_int{4, 24, 30, 9}},
+	{"net.inet6.icmp6.redirtimeout", []_C_int{4, 24, 30, 3}},
+	{"net.inet6.ip6.auto_flowlabel", []_C_int{4, 24, 17, 17}},
+	{"net.inet6.ip6.dad_count", []_C_int{4, 24, 17, 16}},
+	{"net.inet6.ip6.dad_pending", []_C_int{4, 24, 17, 49}},
+	{"net.inet6.ip6.defmcasthlim", []_C_int{4, 24, 17, 18}},
+	{"net.inet6.ip6.forwarding", []_C_int{4, 24, 17, 1}},
+	{"net.inet6.ip6.forwsrcrt", []_C_int{4, 24, 17, 5}},
+	{"net.inet6.ip6.hdrnestlimit", []_C_int{4, 24, 17, 15}},
+	{"net.inet6.ip6.hlim", []_C_int{4, 24, 17, 3}},
+	{"net.inet6.ip6.log_interval", []_C_int{4, 24, 17, 14}},
+	{"net.inet6.ip6.maxdynroutes", []_C_int{4, 24, 17, 48}},
+	{"net.inet6.ip6.maxfragpackets", []_C_int{4, 24, 17, 9}},
+	{"net.inet6.ip6.maxfrags", []_C_int{4, 24, 17, 41}},
+	{"net.inet6.ip6.mforwarding", []_C_int{4, 24, 17, 42}},
+	{"net.inet6.ip6.mrtmfc", []_C_int{4, 24, 17, 53}},
+	{"net.inet6.ip6.mrtmif", []_C_int{4, 24, 17, 52}},
+	{"net.inet6.ip6.mrtproto", []_C_int{4, 24, 17, 8}},
+	{"net.inet6.ip6.mtudisctimeout", []_C_int{4, 24, 17, 50}},
+	{"net.inet6.ip6.multicast_mtudisc", []_C_int{4, 24, 17, 44}},
+	{"net.inet6.ip6.multipath", []_C_int{4, 24, 17, 43}},
+	{"net.inet6.ip6.neighborgcthresh", []_C_int{4, 24, 17, 45}},
+	{"net.inet6.ip6.redirect", []_C_int{4, 24, 17, 2}},
+	{"net.inet6.ip6.soiikey", []_C_int{4, 24, 17, 54}},
+	{"net.inet6.ip6.sourcecheck", []_C_int{4, 24, 17, 10}},
+	{"net.inet6.ip6.sourcecheck_logint", []_C_int{4, 24, 17, 11}},
+	{"net.inet6.ip6.use_deprecated", []_C_int{4, 24, 17, 21}},
+	{"net.key.sadb_dump", []_C_int{4, 30, 1}},
+	{"net.key.spd_dump", []_C_int{4, 30, 2}},
+	{"net.mpls.ifq.congestion", []_C_int{4, 33, 3, 4}},
+	{"net.mpls.ifq.drops", []_C_int{4, 33, 3, 3}},
+	{"net.mpls.ifq.len", []_C_int{4, 33, 3, 1}},
+	{"net.mpls.ifq.maxlen", []_C_int{4, 33, 3, 2}},
+	{"net.mpls.mapttl_ip", []_C_int{4, 33, 5}},
+	{"net.mpls.mapttl_ip6", []_C_int{4, 33, 6}},
+	{"net.mpls.ttl", []_C_int{4, 33, 2}},
+	{"net.pflow.stats", []_C_int{4, 34, 1}},
+	{"net.pipex.enable", []_C_int{4, 35, 1}},
+	{"vm.anonmin", []_C_int{2, 7}},
+	{"vm.loadavg", []_C_int{2, 2}},
+	{"vm.malloc_conf", []_C_int{2, 12}},
+	{"vm.maxslp", []_C_int{2, 10}},
+	{"vm.nkmempages", []_C_int{2, 6}},
+	{"vm.psstrings", []_C_int{2, 3}},
+	{"vm.swapencrypt.enable", []_C_int{2, 5, 0}},
+	{"vm.swapencrypt.keyscreated", []_C_int{2, 5, 1}},
+	{"vm.swapencrypt.keysdeleted", []_C_int{2, 5, 2}},
+	{"vm.uspace", []_C_int{2, 11}},
+	{"vm.uvmexp", []_C_int{2, 4}},
+	{"vm.vmmeter", []_C_int{2, 1}},
+	{"vm.vnodemin", []_C_int{2, 9}},
+	{"vm.vtextmin", []_C_int{2, 8}},
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_riscv64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_riscv64.go
new file mode 100644
index 0000000..a0db82f
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysctl_openbsd_riscv64.go
@@ -0,0 +1,282 @@
+// go run mksysctl_openbsd.go
+// Code generated by the command above; DO NOT EDIT.
+
+//go:build riscv64 && openbsd
+// +build riscv64,openbsd
+
+package unix
+
+type mibentry struct {
+	ctlname string
+	ctloid  []_C_int
+}
+
+var sysctlMib = []mibentry{
+	{"ddb.console", []_C_int{9, 6}},
+	{"ddb.log", []_C_int{9, 7}},
+	{"ddb.max_line", []_C_int{9, 3}},
+	{"ddb.max_width", []_C_int{9, 2}},
+	{"ddb.panic", []_C_int{9, 5}},
+	{"ddb.profile", []_C_int{9, 9}},
+	{"ddb.radix", []_C_int{9, 1}},
+	{"ddb.tab_stop_width", []_C_int{9, 4}},
+	{"ddb.trigger", []_C_int{9, 8}},
+	{"fs.posix.setuid", []_C_int{3, 1, 1}},
+	{"hw.allowpowerdown", []_C_int{6, 22}},
+	{"hw.byteorder", []_C_int{6, 4}},
+	{"hw.cpuspeed", []_C_int{6, 12}},
+	{"hw.diskcount", []_C_int{6, 10}},
+	{"hw.disknames", []_C_int{6, 8}},
+	{"hw.diskstats", []_C_int{6, 9}},
+	{"hw.machine", []_C_int{6, 1}},
+	{"hw.model", []_C_int{6, 2}},
+	{"hw.ncpu", []_C_int{6, 3}},
+	{"hw.ncpufound", []_C_int{6, 21}},
+	{"hw.ncpuonline", []_C_int{6, 25}},
+	{"hw.pagesize", []_C_int{6, 7}},
+	{"hw.perfpolicy", []_C_int{6, 23}},
+	{"hw.physmem", []_C_int{6, 19}},
+	{"hw.power", []_C_int{6, 26}},
+	{"hw.product", []_C_int{6, 15}},
+	{"hw.serialno", []_C_int{6, 17}},
+	{"hw.setperf", []_C_int{6, 13}},
+	{"hw.smt", []_C_int{6, 24}},
+	{"hw.usermem", []_C_int{6, 20}},
+	{"hw.uuid", []_C_int{6, 18}},
+	{"hw.vendor", []_C_int{6, 14}},
+	{"hw.version", []_C_int{6, 16}},
+	{"kern.allowdt", []_C_int{1, 65}},
+	{"kern.allowkmem", []_C_int{1, 52}},
+	{"kern.argmax", []_C_int{1, 8}},
+	{"kern.audio", []_C_int{1, 84}},
+	{"kern.boottime", []_C_int{1, 21}},
+	{"kern.bufcachepercent", []_C_int{1, 72}},
+	{"kern.ccpu", []_C_int{1, 45}},
+	{"kern.clockrate", []_C_int{1, 12}},
+	{"kern.consbuf", []_C_int{1, 83}},
+	{"kern.consbufsize", []_C_int{1, 82}},
+	{"kern.consdev", []_C_int{1, 75}},
+	{"kern.cp_time", []_C_int{1, 40}},
+	{"kern.cp_time2", []_C_int{1, 71}},
+	{"kern.cpustats", []_C_int{1, 85}},
+	{"kern.domainname", []_C_int{1, 22}},
+	{"kern.file", []_C_int{1, 73}},
+	{"kern.forkstat", []_C_int{1, 42}},
+	{"kern.fscale", []_C_int{1, 46}},
+	{"kern.fsync", []_C_int{1, 33}},
+	{"kern.global_ptrace", []_C_int{1, 81}},
+	{"kern.hostid", []_C_int{1, 11}},
+	{"kern.hostname", []_C_int{1, 10}},
+	{"kern.intrcnt.nintrcnt", []_C_int{1, 63, 1}},
+	{"kern.job_control", []_C_int{1, 19}},
+	{"kern.malloc.buckets", []_C_int{1, 39, 1}},
+	{"kern.malloc.kmemnames", []_C_int{1, 39, 3}},
+	{"kern.maxclusters", []_C_int{1, 67}},
+	{"kern.maxfiles", []_C_int{1, 7}},
+	{"kern.maxlocksperuid", []_C_int{1, 70}},
+	{"kern.maxpartitions", []_C_int{1, 23}},
+	{"kern.maxproc", []_C_int{1, 6}},
+	{"kern.maxthread", []_C_int{1, 25}},
+	{"kern.maxvnodes", []_C_int{1, 5}},
+	{"kern.mbstat", []_C_int{1, 59}},
+	{"kern.msgbuf", []_C_int{1, 48}},
+	{"kern.msgbufsize", []_C_int{1, 38}},
+	{"kern.nchstats", []_C_int{1, 41}},
+	{"kern.netlivelocks", []_C_int{1, 76}},
+	{"kern.nfiles", []_C_int{1, 56}},
+	{"kern.ngroups", []_C_int{1, 18}},
+	{"kern.nosuidcoredump", []_C_int{1, 32}},
+	{"kern.nprocs", []_C_int{1, 47}},
+	{"kern.nselcoll", []_C_int{1, 43}},
+	{"kern.nthreads", []_C_int{1, 26}},
+	{"kern.numvnodes", []_C_int{1, 58}},
+	{"kern.osrelease", []_C_int{1, 2}},
+	{"kern.osrevision", []_C_int{1, 3}},
+	{"kern.ostype", []_C_int{1, 1}},
+	{"kern.osversion", []_C_int{1, 27}},
+	{"kern.pfstatus", []_C_int{1, 86}},
+	{"kern.pool_debug", []_C_int{1, 77}},
+	{"kern.posix1version", []_C_int{1, 17}},
+	{"kern.proc", []_C_int{1, 66}},
+	{"kern.rawpartition", []_C_int{1, 24}},
+	{"kern.saved_ids", []_C_int{1, 20}},
+	{"kern.securelevel", []_C_int{1, 9}},
+	{"kern.seminfo", []_C_int{1, 61}},
+	{"kern.shminfo", []_C_int{1, 62}},
+	{"kern.somaxconn", []_C_int{1, 28}},
+	{"kern.sominconn", []_C_int{1, 29}},
+	{"kern.splassert", []_C_int{1, 54}},
+	{"kern.stackgap_random", []_C_int{1, 50}},
+	{"kern.sysvipc_info", []_C_int{1, 51}},
+	{"kern.sysvmsg", []_C_int{1, 34}},
+	{"kern.sysvsem", []_C_int{1, 35}},
+	{"kern.sysvshm", []_C_int{1, 36}},
+	{"kern.timecounter.choice", []_C_int{1, 69, 4}},
+	{"kern.timecounter.hardware", []_C_int{1, 69, 3}},
+	{"kern.timecounter.tick", []_C_int{1, 69, 1}},
+	{"kern.timecounter.timestepwarnings", []_C_int{1, 69, 2}},
+	{"kern.timeout_stats", []_C_int{1, 87}},
+	{"kern.tty.tk_cancc", []_C_int{1, 44, 4}},
+	{"kern.tty.tk_nin", []_C_int{1, 44, 1}},
+	{"kern.tty.tk_nout", []_C_int{1, 44, 2}},
+	{"kern.tty.tk_rawcc", []_C_int{1, 44, 3}},
+	{"kern.tty.ttyinfo", []_C_int{1, 44, 5}},
+	{"kern.ttycount", []_C_int{1, 57}},
+	{"kern.utc_offset", []_C_int{1, 88}},
+	{"kern.version", []_C_int{1, 4}},
+	{"kern.video", []_C_int{1, 89}},
+	{"kern.watchdog.auto", []_C_int{1, 64, 2}},
+	{"kern.watchdog.period", []_C_int{1, 64, 1}},
+	{"kern.witnesswatch", []_C_int{1, 53}},
+	{"kern.wxabort", []_C_int{1, 74}},
+	{"net.bpf.bufsize", []_C_int{4, 31, 1}},
+	{"net.bpf.maxbufsize", []_C_int{4, 31, 2}},
+	{"net.inet.ah.enable", []_C_int{4, 2, 51, 1}},
+	{"net.inet.ah.stats", []_C_int{4, 2, 51, 2}},
+	{"net.inet.carp.allow", []_C_int{4, 2, 112, 1}},
+	{"net.inet.carp.log", []_C_int{4, 2, 112, 3}},
+	{"net.inet.carp.preempt", []_C_int{4, 2, 112, 2}},
+	{"net.inet.carp.stats", []_C_int{4, 2, 112, 4}},
+	{"net.inet.divert.recvspace", []_C_int{4, 2, 258, 1}},
+	{"net.inet.divert.sendspace", []_C_int{4, 2, 258, 2}},
+	{"net.inet.divert.stats", []_C_int{4, 2, 258, 3}},
+	{"net.inet.esp.enable", []_C_int{4, 2, 50, 1}},
+	{"net.inet.esp.stats", []_C_int{4, 2, 50, 4}},
+	{"net.inet.esp.udpencap", []_C_int{4, 2, 50, 2}},
+	{"net.inet.esp.udpencap_port", []_C_int{4, 2, 50, 3}},
+	{"net.inet.etherip.allow", []_C_int{4, 2, 97, 1}},
+	{"net.inet.etherip.stats", []_C_int{4, 2, 97, 2}},
+	{"net.inet.gre.allow", []_C_int{4, 2, 47, 1}},
+	{"net.inet.gre.wccp", []_C_int{4, 2, 47, 2}},
+	{"net.inet.icmp.bmcastecho", []_C_int{4, 2, 1, 2}},
+	{"net.inet.icmp.errppslimit", []_C_int{4, 2, 1, 3}},
+	{"net.inet.icmp.maskrepl", []_C_int{4, 2, 1, 1}},
+	{"net.inet.icmp.rediraccept", []_C_int{4, 2, 1, 4}},
+	{"net.inet.icmp.redirtimeout", []_C_int{4, 2, 1, 5}},
+	{"net.inet.icmp.stats", []_C_int{4, 2, 1, 7}},
+	{"net.inet.icmp.tstamprepl", []_C_int{4, 2, 1, 6}},
+	{"net.inet.igmp.stats", []_C_int{4, 2, 2, 1}},
+	{"net.inet.ip.arpdown", []_C_int{4, 2, 0, 40}},
+	{"net.inet.ip.arpqueued", []_C_int{4, 2, 0, 36}},
+	{"net.inet.ip.arptimeout", []_C_int{4, 2, 0, 39}},
+	{"net.inet.ip.encdebug", []_C_int{4, 2, 0, 12}},
+	{"net.inet.ip.forwarding", []_C_int{4, 2, 0, 1}},
+	{"net.inet.ip.ifq.congestion", []_C_int{4, 2, 0, 30, 4}},
+	{"net.inet.ip.ifq.drops", []_C_int{4, 2, 0, 30, 3}},
+	{"net.inet.ip.ifq.len", []_C_int{4, 2, 0, 30, 1}},
+	{"net.inet.ip.ifq.maxlen", []_C_int{4, 2, 0, 30, 2}},
+	{"net.inet.ip.maxqueue", []_C_int{4, 2, 0, 11}},
+	{"net.inet.ip.mforwarding", []_C_int{4, 2, 0, 31}},
+	{"net.inet.ip.mrtmfc", []_C_int{4, 2, 0, 37}},
+	{"net.inet.ip.mrtproto", []_C_int{4, 2, 0, 34}},
+	{"net.inet.ip.mrtstats", []_C_int{4, 2, 0, 35}},
+	{"net.inet.ip.mrtvif", []_C_int{4, 2, 0, 38}},
+	{"net.inet.ip.mtu", []_C_int{4, 2, 0, 4}},
+	{"net.inet.ip.mtudisc", []_C_int{4, 2, 0, 27}},
+	{"net.inet.ip.mtudisctimeout", []_C_int{4, 2, 0, 28}},
+	{"net.inet.ip.multipath", []_C_int{4, 2, 0, 32}},
+	{"net.inet.ip.portfirst", []_C_int{4, 2, 0, 7}},
+	{"net.inet.ip.porthifirst", []_C_int{4, 2, 0, 9}},
+	{"net.inet.ip.porthilast", []_C_int{4, 2, 0, 10}},
+	{"net.inet.ip.portlast", []_C_int{4, 2, 0, 8}},
+	{"net.inet.ip.redirect", []_C_int{4, 2, 0, 2}},
+	{"net.inet.ip.sourceroute", []_C_int{4, 2, 0, 5}},
+	{"net.inet.ip.stats", []_C_int{4, 2, 0, 33}},
+	{"net.inet.ip.ttl", []_C_int{4, 2, 0, 3}},
+	{"net.inet.ipcomp.enable", []_C_int{4, 2, 108, 1}},
+	{"net.inet.ipcomp.stats", []_C_int{4, 2, 108, 2}},
+	{"net.inet.ipip.allow", []_C_int{4, 2, 4, 1}},
+	{"net.inet.ipip.stats", []_C_int{4, 2, 4, 2}},
+	{"net.inet.pfsync.stats", []_C_int{4, 2, 240, 1}},
+	{"net.inet.tcp.ackonpush", []_C_int{4, 2, 6, 13}},
+	{"net.inet.tcp.always_keepalive", []_C_int{4, 2, 6, 22}},
+	{"net.inet.tcp.baddynamic", []_C_int{4, 2, 6, 6}},
+	{"net.inet.tcp.drop", []_C_int{4, 2, 6, 19}},
+	{"net.inet.tcp.ecn", []_C_int{4, 2, 6, 14}},
+	{"net.inet.tcp.ident", []_C_int{4, 2, 6, 9}},
+	{"net.inet.tcp.keepidle", []_C_int{4, 2, 6, 3}},
+	{"net.inet.tcp.keepinittime", []_C_int{4, 2, 6, 2}},
+	{"net.inet.tcp.keepintvl", []_C_int{4, 2, 6, 4}},
+	{"net.inet.tcp.mssdflt", []_C_int{4, 2, 6, 11}},
+	{"net.inet.tcp.reasslimit", []_C_int{4, 2, 6, 18}},
+	{"net.inet.tcp.rfc1323", []_C_int{4, 2, 6, 1}},
+	{"net.inet.tcp.rfc3390", []_C_int{4, 2, 6, 17}},
+	{"net.inet.tcp.rootonly", []_C_int{4, 2, 6, 24}},
+	{"net.inet.tcp.rstppslimit", []_C_int{4, 2, 6, 12}},
+	{"net.inet.tcp.sack", []_C_int{4, 2, 6, 10}},
+	{"net.inet.tcp.sackholelimit", []_C_int{4, 2, 6, 20}},
+	{"net.inet.tcp.slowhz", []_C_int{4, 2, 6, 5}},
+	{"net.inet.tcp.stats", []_C_int{4, 2, 6, 21}},
+	{"net.inet.tcp.synbucketlimit", []_C_int{4, 2, 6, 16}},
+	{"net.inet.tcp.syncachelimit", []_C_int{4, 2, 6, 15}},
+	{"net.inet.tcp.synhashsize", []_C_int{4, 2, 6, 25}},
+	{"net.inet.tcp.synuselimit", []_C_int{4, 2, 6, 23}},
+	{"net.inet.udp.baddynamic", []_C_int{4, 2, 17, 2}},
+	{"net.inet.udp.checksum", []_C_int{4, 2, 17, 1}},
+	{"net.inet.udp.recvspace", []_C_int{4, 2, 17, 3}},
+	{"net.inet.udp.rootonly", []_C_int{4, 2, 17, 6}},
+	{"net.inet.udp.sendspace", []_C_int{4, 2, 17, 4}},
+	{"net.inet.udp.stats", []_C_int{4, 2, 17, 5}},
+	{"net.inet6.divert.recvspace", []_C_int{4, 24, 86, 1}},
+	{"net.inet6.divert.sendspace", []_C_int{4, 24, 86, 2}},
+	{"net.inet6.divert.stats", []_C_int{4, 24, 86, 3}},
+	{"net.inet6.icmp6.errppslimit", []_C_int{4, 24, 30, 14}},
+	{"net.inet6.icmp6.mtudisc_hiwat", []_C_int{4, 24, 30, 16}},
+	{"net.inet6.icmp6.mtudisc_lowat", []_C_int{4, 24, 30, 17}},
+	{"net.inet6.icmp6.nd6_debug", []_C_int{4, 24, 30, 18}},
+	{"net.inet6.icmp6.nd6_delay", []_C_int{4, 24, 30, 8}},
+	{"net.inet6.icmp6.nd6_maxnudhint", []_C_int{4, 24, 30, 15}},
+	{"net.inet6.icmp6.nd6_mmaxtries", []_C_int{4, 24, 30, 10}},
+	{"net.inet6.icmp6.nd6_umaxtries", []_C_int{4, 24, 30, 9}},
+	{"net.inet6.icmp6.redirtimeout", []_C_int{4, 24, 30, 3}},
+	{"net.inet6.ip6.auto_flowlabel", []_C_int{4, 24, 17, 17}},
+	{"net.inet6.ip6.dad_count", []_C_int{4, 24, 17, 16}},
+	{"net.inet6.ip6.dad_pending", []_C_int{4, 24, 17, 49}},
+	{"net.inet6.ip6.defmcasthlim", []_C_int{4, 24, 17, 18}},
+	{"net.inet6.ip6.forwarding", []_C_int{4, 24, 17, 1}},
+	{"net.inet6.ip6.forwsrcrt", []_C_int{4, 24, 17, 5}},
+	{"net.inet6.ip6.hdrnestlimit", []_C_int{4, 24, 17, 15}},
+	{"net.inet6.ip6.hlim", []_C_int{4, 24, 17, 3}},
+	{"net.inet6.ip6.log_interval", []_C_int{4, 24, 17, 14}},
+	{"net.inet6.ip6.maxdynroutes", []_C_int{4, 24, 17, 48}},
+	{"net.inet6.ip6.maxfragpackets", []_C_int{4, 24, 17, 9}},
+	{"net.inet6.ip6.maxfrags", []_C_int{4, 24, 17, 41}},
+	{"net.inet6.ip6.mforwarding", []_C_int{4, 24, 17, 42}},
+	{"net.inet6.ip6.mrtmfc", []_C_int{4, 24, 17, 53}},
+	{"net.inet6.ip6.mrtmif", []_C_int{4, 24, 17, 52}},
+	{"net.inet6.ip6.mrtproto", []_C_int{4, 24, 17, 8}},
+	{"net.inet6.ip6.mtudisctimeout", []_C_int{4, 24, 17, 50}},
+	{"net.inet6.ip6.multicast_mtudisc", []_C_int{4, 24, 17, 44}},
+	{"net.inet6.ip6.multipath", []_C_int{4, 24, 17, 43}},
+	{"net.inet6.ip6.neighborgcthresh", []_C_int{4, 24, 17, 45}},
+	{"net.inet6.ip6.redirect", []_C_int{4, 24, 17, 2}},
+	{"net.inet6.ip6.soiikey", []_C_int{4, 24, 17, 54}},
+	{"net.inet6.ip6.sourcecheck", []_C_int{4, 24, 17, 10}},
+	{"net.inet6.ip6.sourcecheck_logint", []_C_int{4, 24, 17, 11}},
+	{"net.inet6.ip6.use_deprecated", []_C_int{4, 24, 17, 21}},
+	{"net.key.sadb_dump", []_C_int{4, 30, 1}},
+	{"net.key.spd_dump", []_C_int{4, 30, 2}},
+	{"net.mpls.ifq.congestion", []_C_int{4, 33, 3, 4}},
+	{"net.mpls.ifq.drops", []_C_int{4, 33, 3, 3}},
+	{"net.mpls.ifq.len", []_C_int{4, 33, 3, 1}},
+	{"net.mpls.ifq.maxlen", []_C_int{4, 33, 3, 2}},
+	{"net.mpls.mapttl_ip", []_C_int{4, 33, 5}},
+	{"net.mpls.mapttl_ip6", []_C_int{4, 33, 6}},
+	{"net.mpls.ttl", []_C_int{4, 33, 2}},
+	{"net.pflow.stats", []_C_int{4, 34, 1}},
+	{"net.pipex.enable", []_C_int{4, 35, 1}},
+	{"vm.anonmin", []_C_int{2, 7}},
+	{"vm.loadavg", []_C_int{2, 2}},
+	{"vm.malloc_conf", []_C_int{2, 12}},
+	{"vm.maxslp", []_C_int{2, 10}},
+	{"vm.nkmempages", []_C_int{2, 6}},
+	{"vm.psstrings", []_C_int{2, 3}},
+	{"vm.swapencrypt.enable", []_C_int{2, 5, 0}},
+	{"vm.swapencrypt.keyscreated", []_C_int{2, 5, 1}},
+	{"vm.swapencrypt.keysdeleted", []_C_int{2, 5, 2}},
+	{"vm.uspace", []_C_int{2, 11}},
+	{"vm.uvmexp", []_C_int{2, 4}},
+	{"vm.vmmeter", []_C_int{2, 1}},
+	{"vm.vnodemin", []_C_int{2, 9}},
+	{"vm.vtextmin", []_C_int{2, 8}},
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_freebsd_386.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_freebsd_386.go
index 59d5dfc..4e0d961 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_freebsd_386.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_freebsd_386.go
@@ -1,4 +1,4 @@
-// go run mksysnum.go https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master
+// go run mksysnum.go https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build 386 && freebsd
@@ -19,10 +19,9 @@
 	SYS_UNLINK                   = 10  // { int unlink(char *path); }
 	SYS_CHDIR                    = 12  // { int chdir(char *path); }
 	SYS_FCHDIR                   = 13  // { int fchdir(int fd); }
-	SYS_MKNOD                    = 14  // { int mknod(char *path, int mode, int dev); }
 	SYS_CHMOD                    = 15  // { int chmod(char *path, int mode); }
 	SYS_CHOWN                    = 16  // { int chown(char *path, int uid, int gid); }
-	SYS_OBREAK                   = 17  // { int obreak(char *nsize); } break obreak_args int
+	SYS_BREAK                    = 17  // { caddr_t break(char *nsize); }
 	SYS_GETPID                   = 20  // { pid_t getpid(void); }
 	SYS_MOUNT                    = 21  // { int mount(char *type, char *path, int flags, caddr_t data); }
 	SYS_UNMOUNT                  = 22  // { int unmount(char *path, int flags); }
@@ -43,7 +42,6 @@
 	SYS_KILL                     = 37  // { int kill(int pid, int signum); }
 	SYS_GETPPID                  = 39  // { pid_t getppid(void); }
 	SYS_DUP                      = 41  // { int dup(u_int fd); }
-	SYS_PIPE                     = 42  // { int pipe(void); }
 	SYS_GETEGID                  = 43  // { gid_t getegid(void); }
 	SYS_PROFIL                   = 44  // { int profil(caddr_t samples, size_t size, size_t offset, u_int scale); }
 	SYS_KTRACE                   = 45  // { int ktrace(const char *fname, int ops, int facs, int pid); }
@@ -58,15 +56,14 @@
 	SYS_SYMLINK                  = 57  // { int symlink(char *path, char *link); }
 	SYS_READLINK                 = 58  // { ssize_t readlink(char *path, char *buf, size_t count); }
 	SYS_EXECVE                   = 59  // { int execve(char *fname, char **argv, char **envv); }
-	SYS_UMASK                    = 60  // { int umask(int newmask); } umask umask_args int
+	SYS_UMASK                    = 60  // { int umask(int newmask); }
 	SYS_CHROOT                   = 61  // { int chroot(char *path); }
 	SYS_MSYNC                    = 65  // { int msync(void *addr, size_t len, int flags); }
 	SYS_VFORK                    = 66  // { int vfork(void); }
 	SYS_SBRK                     = 69  // { int sbrk(int incr); }
 	SYS_SSTK                     = 70  // { int sstk(int incr); }
-	SYS_OVADVISE                 = 72  // { int ovadvise(int anom); } vadvise ovadvise_args int
 	SYS_MUNMAP                   = 73  // { int munmap(void *addr, size_t len); }
-	SYS_MPROTECT                 = 74  // { int mprotect(const void *addr, size_t len, int prot); }
+	SYS_MPROTECT                 = 74  // { int mprotect(void *addr, size_t len, int prot); }
 	SYS_MADVISE                  = 75  // { int madvise(void *addr, size_t len, int behav); }
 	SYS_MINCORE                  = 78  // { int mincore(const void *addr, size_t len, char *vec); }
 	SYS_GETGROUPS                = 79  // { int getgroups(u_int gidsetsize, gid_t *gidset); }
@@ -124,14 +121,10 @@
 	SYS_SETGID                   = 181 // { int setgid(gid_t gid); }
 	SYS_SETEGID                  = 182 // { int setegid(gid_t egid); }
 	SYS_SETEUID                  = 183 // { int seteuid(uid_t euid); }
-	SYS_STAT                     = 188 // { int stat(char *path, struct stat *ub); }
-	SYS_FSTAT                    = 189 // { int fstat(int fd, struct stat *sb); }
-	SYS_LSTAT                    = 190 // { int lstat(char *path, struct stat *ub); }
 	SYS_PATHCONF                 = 191 // { int pathconf(char *path, int name); }
 	SYS_FPATHCONF                = 192 // { int fpathconf(int fd, int name); }
 	SYS_GETRLIMIT                = 194 // { int getrlimit(u_int which, struct rlimit *rlp); } getrlimit __getrlimit_args int
 	SYS_SETRLIMIT                = 195 // { int setrlimit(u_int which, struct rlimit *rlp); } setrlimit __setrlimit_args int
-	SYS_GETDIRENTRIES            = 196 // { int getdirentries(int fd, char *buf, u_int count, long *basep); }
 	SYS___SYSCTL                 = 202 // { int __sysctl(int *name, u_int namelen, void *old, size_t *oldlenp, void *new, size_t newlen); } __sysctl sysctl_args int
 	SYS_MLOCK                    = 203 // { int mlock(const void *addr, size_t len); }
 	SYS_MUNLOCK                  = 204 // { int munlock(const void *addr, size_t len); }
@@ -143,12 +136,12 @@
 	SYS_SEMOP                    = 222 // { int semop(int semid, struct sembuf *sops, size_t nsops); }
 	SYS_MSGGET                   = 225 // { int msgget(key_t key, int msgflg); }
 	SYS_MSGSND                   = 226 // { int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); }
-	SYS_MSGRCV                   = 227 // { int msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg); }
+	SYS_MSGRCV                   = 227 // { ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg); }
 	SYS_SHMAT                    = 228 // { int shmat(int shmid, const void *shmaddr, int shmflg); }
 	SYS_SHMDT                    = 230 // { int shmdt(const void *shmaddr); }
 	SYS_SHMGET                   = 231 // { int shmget(key_t key, size_t size, int shmflg); }
 	SYS_CLOCK_GETTIME            = 232 // { int clock_gettime(clockid_t clock_id, struct timespec *tp); }
-	SYS_CLOCK_SETTIME            = 233 // { int clock_settime( clockid_t clock_id, const struct timespec *tp); }
+	SYS_CLOCK_SETTIME            = 233 // { int clock_settime(clockid_t clock_id, const struct timespec *tp); }
 	SYS_CLOCK_GETRES             = 234 // { int clock_getres(clockid_t clock_id, struct timespec *tp); }
 	SYS_KTIMER_CREATE            = 235 // { int ktimer_create(clockid_t clock_id, struct sigevent *evp, int *timerid); }
 	SYS_KTIMER_DELETE            = 236 // { int ktimer_delete(int timerid); }
@@ -157,50 +150,44 @@
 	SYS_KTIMER_GETOVERRUN        = 239 // { int ktimer_getoverrun(int timerid); }
 	SYS_NANOSLEEP                = 240 // { int nanosleep(const struct timespec *rqtp, struct timespec *rmtp); }
 	SYS_FFCLOCK_GETCOUNTER       = 241 // { int ffclock_getcounter(ffcounter *ffcount); }
-	SYS_FFCLOCK_SETESTIMATE      = 242 // { int ffclock_setestimate( struct ffclock_estimate *cest); }
-	SYS_FFCLOCK_GETESTIMATE      = 243 // { int ffclock_getestimate( struct ffclock_estimate *cest); }
+	SYS_FFCLOCK_SETESTIMATE      = 242 // { int ffclock_setestimate(struct ffclock_estimate *cest); }
+	SYS_FFCLOCK_GETESTIMATE      = 243 // { int ffclock_getestimate(struct ffclock_estimate *cest); }
 	SYS_CLOCK_NANOSLEEP          = 244 // { int clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *rqtp, struct timespec *rmtp); }
-	SYS_CLOCK_GETCPUCLOCKID2     = 247 // { int clock_getcpuclockid2(id_t id,int which, clockid_t *clock_id); }
+	SYS_CLOCK_GETCPUCLOCKID2     = 247 // { int clock_getcpuclockid2(id_t id, int which, clockid_t *clock_id); }
 	SYS_NTP_GETTIME              = 248 // { int ntp_gettime(struct ntptimeval *ntvp); }
 	SYS_MINHERIT                 = 250 // { int minherit(void *addr, size_t len, int inherit); }
 	SYS_RFORK                    = 251 // { int rfork(int flags); }
-	SYS_OPENBSD_POLL             = 252 // { int openbsd_poll(struct pollfd *fds, u_int nfds, int timeout); }
 	SYS_ISSETUGID                = 253 // { int issetugid(void); }
 	SYS_LCHOWN                   = 254 // { int lchown(char *path, int uid, int gid); }
 	SYS_AIO_READ                 = 255 // { int aio_read(struct aiocb *aiocbp); }
 	SYS_AIO_WRITE                = 256 // { int aio_write(struct aiocb *aiocbp); }
-	SYS_LIO_LISTIO               = 257 // { int lio_listio(int mode, struct aiocb * const *acb_list, int nent, struct sigevent *sig); }
-	SYS_GETDENTS                 = 272 // { int getdents(int fd, char *buf, size_t count); }
+	SYS_LIO_LISTIO               = 257 // { int lio_listio(int mode, struct aiocb* const *acb_list, int nent, struct sigevent *sig); }
 	SYS_LCHMOD                   = 274 // { int lchmod(char *path, mode_t mode); }
 	SYS_LUTIMES                  = 276 // { int lutimes(char *path, struct timeval *tptr); }
-	SYS_NSTAT                    = 278 // { int nstat(char *path, struct nstat *ub); }
-	SYS_NFSTAT                   = 279 // { int nfstat(int fd, struct nstat *sb); }
-	SYS_NLSTAT                   = 280 // { int nlstat(char *path, struct nstat *ub); }
 	SYS_PREADV                   = 289 // { ssize_t preadv(int fd, struct iovec *iovp, u_int iovcnt, off_t offset); }
 	SYS_PWRITEV                  = 290 // { ssize_t pwritev(int fd, struct iovec *iovp, u_int iovcnt, off_t offset); }
 	SYS_FHOPEN                   = 298 // { int fhopen(const struct fhandle *u_fhp, int flags); }
-	SYS_FHSTAT                   = 299 // { int fhstat(const struct fhandle *u_fhp, struct stat *sb); }
 	SYS_MODNEXT                  = 300 // { int modnext(int modid); }
-	SYS_MODSTAT                  = 301 // { int modstat(int modid, struct module_stat *stat); }
+	SYS_MODSTAT                  = 301 // { int modstat(int modid, struct module_stat* stat); }
 	SYS_MODFNEXT                 = 302 // { int modfnext(int modid); }
 	SYS_MODFIND                  = 303 // { int modfind(const char *name); }
 	SYS_KLDLOAD                  = 304 // { int kldload(const char *file); }
 	SYS_KLDUNLOAD                = 305 // { int kldunload(int fileid); }
 	SYS_KLDFIND                  = 306 // { int kldfind(const char *file); }
 	SYS_KLDNEXT                  = 307 // { int kldnext(int fileid); }
-	SYS_KLDSTAT                  = 308 // { int kldstat(int fileid, struct kld_file_stat* stat); }
+	SYS_KLDSTAT                  = 308 // { int kldstat(int fileid, struct kld_file_stat *stat); }
 	SYS_KLDFIRSTMOD              = 309 // { int kldfirstmod(int fileid); }
 	SYS_GETSID                   = 310 // { int getsid(pid_t pid); }
 	SYS_SETRESUID                = 311 // { int setresuid(uid_t ruid, uid_t euid, uid_t suid); }
 	SYS_SETRESGID                = 312 // { int setresgid(gid_t rgid, gid_t egid, gid_t sgid); }
 	SYS_AIO_RETURN               = 314 // { ssize_t aio_return(struct aiocb *aiocbp); }
-	SYS_AIO_SUSPEND              = 315 // { int aio_suspend( struct aiocb * const * aiocbp, int nent, const struct timespec *timeout); }
+	SYS_AIO_SUSPEND              = 315 // { int aio_suspend(struct aiocb * const * aiocbp, int nent, const struct timespec *timeout); }
 	SYS_AIO_CANCEL               = 316 // { int aio_cancel(int fd, struct aiocb *aiocbp); }
 	SYS_AIO_ERROR                = 317 // { int aio_error(struct aiocb *aiocbp); }
 	SYS_YIELD                    = 321 // { int yield(void); }
 	SYS_MLOCKALL                 = 324 // { int mlockall(int how); }
 	SYS_MUNLOCKALL               = 325 // { int munlockall(void); }
-	SYS___GETCWD                 = 326 // { int __getcwd(char *buf, u_int buflen); }
+	SYS___GETCWD                 = 326 // { int __getcwd(char *buf, size_t buflen); }
 	SYS_SCHED_SETPARAM           = 327 // { int sched_setparam (pid_t pid, const struct sched_param *param); }
 	SYS_SCHED_GETPARAM           = 328 // { int sched_getparam (pid_t pid, struct sched_param *param); }
 	SYS_SCHED_SETSCHEDULER       = 329 // { int sched_setscheduler (pid_t pid, int policy, const struct sched_param *param); }
@@ -226,14 +213,13 @@
 	SYS___ACL_ACLCHECK_FILE      = 353 // { int __acl_aclcheck_file(const char *path, acl_type_t type, struct acl *aclp); }
 	SYS___ACL_ACLCHECK_FD        = 354 // { int __acl_aclcheck_fd(int filedes, acl_type_t type, struct acl *aclp); }
 	SYS_EXTATTRCTL               = 355 // { int extattrctl(const char *path, int cmd, const char *filename, int attrnamespace, const char *attrname); }
-	SYS_EXTATTR_SET_FILE         = 356 // { ssize_t extattr_set_file( const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
-	SYS_EXTATTR_GET_FILE         = 357 // { ssize_t extattr_get_file( const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
+	SYS_EXTATTR_SET_FILE         = 356 // { ssize_t extattr_set_file(const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
+	SYS_EXTATTR_GET_FILE         = 357 // { ssize_t extattr_get_file(const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
 	SYS_EXTATTR_DELETE_FILE      = 358 // { int extattr_delete_file(const char *path, int attrnamespace, const char *attrname); }
-	SYS_AIO_WAITCOMPLETE         = 359 // { ssize_t aio_waitcomplete( struct aiocb **aiocbp, struct timespec *timeout); }
+	SYS_AIO_WAITCOMPLETE         = 359 // { ssize_t aio_waitcomplete(struct aiocb **aiocbp, struct timespec *timeout); }
 	SYS_GETRESUID                = 360 // { int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); }
 	SYS_GETRESGID                = 361 // { int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); }
 	SYS_KQUEUE                   = 362 // { int kqueue(void); }
-	SYS_KEVENT                   = 363 // { int kevent(int fd, struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents, const struct timespec *timeout); }
 	SYS_EXTATTR_SET_FD           = 371 // { ssize_t extattr_set_fd(int fd, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
 	SYS_EXTATTR_GET_FD           = 372 // { ssize_t extattr_get_fd(int fd, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
 	SYS_EXTATTR_DELETE_FD        = 373 // { int extattr_delete_fd(int fd, int attrnamespace, const char *attrname); }
@@ -251,10 +237,6 @@
 	SYS_UUIDGEN                  = 392 // { int uuidgen(struct uuid *store, int count); }
 	SYS_SENDFILE                 = 393 // { int sendfile(int fd, int s, off_t offset, size_t nbytes, struct sf_hdtr *hdtr, off_t *sbytes, int flags); }
 	SYS_MAC_SYSCALL              = 394 // { int mac_syscall(const char *policy, int call, void *arg); }
-	SYS_GETFSSTAT                = 395 // { int getfsstat(struct statfs *buf, long bufsize, int mode); }
-	SYS_STATFS                   = 396 // { int statfs(char *path, struct statfs *buf); }
-	SYS_FSTATFS                  = 397 // { int fstatfs(int fd, struct statfs *buf); }
-	SYS_FHSTATFS                 = 398 // { int fhstatfs(const struct fhandle *u_fhp, struct statfs *buf); }
 	SYS_KSEM_CLOSE               = 400 // { int ksem_close(semid_t id); }
 	SYS_KSEM_POST                = 401 // { int ksem_post(semid_t id); }
 	SYS_KSEM_WAIT                = 402 // { int ksem_wait(semid_t id); }
@@ -267,14 +249,14 @@
 	SYS___MAC_GET_PID            = 409 // { int __mac_get_pid(pid_t pid, struct mac *mac_p); }
 	SYS___MAC_GET_LINK           = 410 // { int __mac_get_link(const char *path_p, struct mac *mac_p); }
 	SYS___MAC_SET_LINK           = 411 // { int __mac_set_link(const char *path_p, struct mac *mac_p); }
-	SYS_EXTATTR_SET_LINK         = 412 // { ssize_t extattr_set_link( const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
-	SYS_EXTATTR_GET_LINK         = 413 // { ssize_t extattr_get_link( const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
-	SYS_EXTATTR_DELETE_LINK      = 414 // { int extattr_delete_link( const char *path, int attrnamespace, const char *attrname); }
+	SYS_EXTATTR_SET_LINK         = 412 // { ssize_t extattr_set_link(const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
+	SYS_EXTATTR_GET_LINK         = 413 // { ssize_t extattr_get_link(const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
+	SYS_EXTATTR_DELETE_LINK      = 414 // { int extattr_delete_link(const char *path, int attrnamespace, const char *attrname); }
 	SYS___MAC_EXECVE             = 415 // { int __mac_execve(char *fname, char **argv, char **envv, struct mac *mac_p); }
 	SYS_SIGACTION                = 416 // { int sigaction(int sig, const struct sigaction *act, struct sigaction *oact); }
-	SYS_SIGRETURN                = 417 // { int sigreturn( const struct __ucontext *sigcntxp); }
+	SYS_SIGRETURN                = 417 // { int sigreturn(const struct __ucontext *sigcntxp); }
 	SYS_GETCONTEXT               = 421 // { int getcontext(struct __ucontext *ucp); }
-	SYS_SETCONTEXT               = 422 // { int setcontext( const struct __ucontext *ucp); }
+	SYS_SETCONTEXT               = 422 // { int setcontext(const struct __ucontext *ucp); }
 	SYS_SWAPCONTEXT              = 423 // { int swapcontext(struct __ucontext *oucp, const struct __ucontext *ucp); }
 	SYS_SWAPOFF                  = 424 // { int swapoff(const char *name); }
 	SYS___ACL_GET_LINK           = 425 // { int __acl_get_link(const char *path, acl_type_t type, struct acl *aclp); }
@@ -288,10 +270,10 @@
 	SYS_THR_KILL                 = 433 // { int thr_kill(long id, int sig); }
 	SYS_JAIL_ATTACH              = 436 // { int jail_attach(int jid); }
 	SYS_EXTATTR_LIST_FD          = 437 // { ssize_t extattr_list_fd(int fd, int attrnamespace, void *data, size_t nbytes); }
-	SYS_EXTATTR_LIST_FILE        = 438 // { ssize_t extattr_list_file( const char *path, int attrnamespace, void *data, size_t nbytes); }
-	SYS_EXTATTR_LIST_LINK        = 439 // { ssize_t extattr_list_link( const char *path, int attrnamespace, void *data, size_t nbytes); }
+	SYS_EXTATTR_LIST_FILE        = 438 // { ssize_t extattr_list_file(const char *path, int attrnamespace, void *data, size_t nbytes); }
+	SYS_EXTATTR_LIST_LINK        = 439 // { ssize_t extattr_list_link(const char *path, int attrnamespace, void *data, size_t nbytes); }
 	SYS_KSEM_TIMEDWAIT           = 441 // { int ksem_timedwait(semid_t id, const struct timespec *abstime); }
-	SYS_THR_SUSPEND              = 442 // { int thr_suspend( const struct timespec *timeout); }
+	SYS_THR_SUSPEND              = 442 // { int thr_suspend(const struct timespec *timeout); }
 	SYS_THR_WAKE                 = 443 // { int thr_wake(long id); }
 	SYS_KLDUNLOADF               = 444 // { int kldunloadf(int fileid, int flags); }
 	SYS_AUDIT                    = 445 // { int audit(const void *record, u_int length); }
@@ -300,17 +282,17 @@
 	SYS_SETAUID                  = 448 // { int setauid(uid_t *auid); }
 	SYS_GETAUDIT                 = 449 // { int getaudit(struct auditinfo *auditinfo); }
 	SYS_SETAUDIT                 = 450 // { int setaudit(struct auditinfo *auditinfo); }
-	SYS_GETAUDIT_ADDR            = 451 // { int getaudit_addr( struct auditinfo_addr *auditinfo_addr, u_int length); }
-	SYS_SETAUDIT_ADDR            = 452 // { int setaudit_addr( struct auditinfo_addr *auditinfo_addr, u_int length); }
+	SYS_GETAUDIT_ADDR            = 451 // { int getaudit_addr(struct auditinfo_addr *auditinfo_addr, u_int length); }
+	SYS_SETAUDIT_ADDR            = 452 // { int setaudit_addr(struct auditinfo_addr *auditinfo_addr, u_int length); }
 	SYS_AUDITCTL                 = 453 // { int auditctl(char *path); }
 	SYS__UMTX_OP                 = 454 // { int _umtx_op(void *obj, int op, u_long val, void *uaddr1, void *uaddr2); }
 	SYS_THR_NEW                  = 455 // { int thr_new(struct thr_param *param, int param_size); }
 	SYS_SIGQUEUE                 = 456 // { int sigqueue(pid_t pid, int signum, void *value); }
 	SYS_KMQ_OPEN                 = 457 // { int kmq_open(const char *path, int flags, mode_t mode, const struct mq_attr *attr); }
-	SYS_KMQ_SETATTR              = 458 // { int kmq_setattr(int mqd,		const struct mq_attr *attr,		struct mq_attr *oattr); }
-	SYS_KMQ_TIMEDRECEIVE         = 459 // { int kmq_timedreceive(int mqd,	char *msg_ptr, size_t msg_len,	unsigned *msg_prio,			const struct timespec *abs_timeout); }
-	SYS_KMQ_TIMEDSEND            = 460 // { int kmq_timedsend(int mqd,		const char *msg_ptr, size_t msg_len,unsigned msg_prio,			const struct timespec *abs_timeout);}
-	SYS_KMQ_NOTIFY               = 461 // { int kmq_notify(int mqd,		const struct sigevent *sigev); }
+	SYS_KMQ_SETATTR              = 458 // { int kmq_setattr(int mqd, const struct mq_attr *attr, struct mq_attr *oattr); }
+	SYS_KMQ_TIMEDRECEIVE         = 459 // { int kmq_timedreceive(int mqd, char *msg_ptr, size_t msg_len, unsigned *msg_prio, const struct timespec *abs_timeout); }
+	SYS_KMQ_TIMEDSEND            = 460 // { int kmq_timedsend(int mqd, const char *msg_ptr, size_t msg_len, unsigned msg_prio, const struct timespec *abs_timeout); }
+	SYS_KMQ_NOTIFY               = 461 // { int kmq_notify(int mqd, const struct sigevent *sigev); }
 	SYS_KMQ_UNLINK               = 462 // { int kmq_unlink(const char *path); }
 	SYS_ABORT2                   = 463 // { int abort2(const char *why, int nargs, void **args); }
 	SYS_THR_SET_NAME             = 464 // { int thr_set_name(long id, const char *name); }
@@ -319,7 +301,7 @@
 	SYS_SCTP_PEELOFF             = 471 // { int sctp_peeloff(int sd, uint32_t name); }
 	SYS_SCTP_GENERIC_SENDMSG     = 472 // { int sctp_generic_sendmsg(int sd, caddr_t msg, int mlen, caddr_t to, __socklen_t tolen, struct sctp_sndrcvinfo *sinfo, int flags); }
 	SYS_SCTP_GENERIC_SENDMSG_IOV = 473 // { int sctp_generic_sendmsg_iov(int sd, struct iovec *iov, int iovlen, caddr_t to, __socklen_t tolen, struct sctp_sndrcvinfo *sinfo, int flags); }
-	SYS_SCTP_GENERIC_RECVMSG     = 474 // { int sctp_generic_recvmsg(int sd, struct iovec *iov, int iovlen, struct sockaddr * from, __socklen_t *fromlenaddr, struct sctp_sndrcvinfo *sinfo, int *msg_flags); }
+	SYS_SCTP_GENERIC_RECVMSG     = 474 // { int sctp_generic_recvmsg(int sd, struct iovec *iov, int iovlen, struct sockaddr *from, __socklen_t *fromlenaddr, struct sctp_sndrcvinfo *sinfo, int *msg_flags); }
 	SYS_PREAD                    = 475 // { ssize_t pread(int fd, void *buf, size_t nbyte, off_t offset); }
 	SYS_PWRITE                   = 476 // { ssize_t pwrite(int fd, const void *buf, size_t nbyte, off_t offset); }
 	SYS_MMAP                     = 477 // { caddr_t mmap(caddr_t addr, size_t len, int prot, int flags, int fd, off_t pos); }
@@ -338,14 +320,12 @@
 	SYS_FCHMODAT                 = 490 // { int fchmodat(int fd, char *path, mode_t mode, int flag); }
 	SYS_FCHOWNAT                 = 491 // { int fchownat(int fd, char *path, uid_t uid, gid_t gid, int flag); }
 	SYS_FEXECVE                  = 492 // { int fexecve(int fd, char **argv, char **envv); }
-	SYS_FSTATAT                  = 493 // { int fstatat(int fd, char *path, struct stat *buf, int flag); }
 	SYS_FUTIMESAT                = 494 // { int futimesat(int fd, char *path, struct timeval *times); }
 	SYS_LINKAT                   = 495 // { int linkat(int fd1, char *path1, int fd2, char *path2, int flag); }
 	SYS_MKDIRAT                  = 496 // { int mkdirat(int fd, char *path, mode_t mode); }
 	SYS_MKFIFOAT                 = 497 // { int mkfifoat(int fd, char *path, mode_t mode); }
-	SYS_MKNODAT                  = 498 // { int mknodat(int fd, char *path, mode_t mode, dev_t dev); }
 	SYS_OPENAT                   = 499 // { int openat(int fd, char *path, int flag, mode_t mode); }
-	SYS_READLINKAT               = 500 // { int readlinkat(int fd, char *path, char *buf, size_t bufsize); }
+	SYS_READLINKAT               = 500 // { ssize_t readlinkat(int fd, char *path, char *buf, size_t bufsize); }
 	SYS_RENAMEAT                 = 501 // { int renameat(int oldfd, char *old, int newfd, char *new); }
 	SYS_SYMLINKAT                = 502 // { int symlinkat(char *path1, int fd, char *path2); }
 	SYS_UNLINKAT                 = 503 // { int unlinkat(int fd, char *path, int flag); }
@@ -391,7 +371,24 @@
 	SYS_PPOLL                    = 545 // { int ppoll(struct pollfd *fds, u_int nfds, const struct timespec *ts, const sigset_t *set); }
 	SYS_FUTIMENS                 = 546 // { int futimens(int fd, struct timespec *times); }
 	SYS_UTIMENSAT                = 547 // { int utimensat(int fd, char *path, struct timespec *times, int flag); }
-	SYS_NUMA_GETAFFINITY         = 548 // { int numa_getaffinity(cpuwhich_t which, id_t id, struct vm_domain_policy_entry *policy); }
-	SYS_NUMA_SETAFFINITY         = 549 // { int numa_setaffinity(cpuwhich_t which, id_t id, const struct vm_domain_policy_entry *policy); }
 	SYS_FDATASYNC                = 550 // { int fdatasync(int fd); }
+	SYS_FSTAT                    = 551 // { int fstat(int fd, struct stat *sb); }
+	SYS_FSTATAT                  = 552 // { int fstatat(int fd, char *path, struct stat *buf, int flag); }
+	SYS_FHSTAT                   = 553 // { int fhstat(const struct fhandle *u_fhp, struct stat *sb); }
+	SYS_GETDIRENTRIES            = 554 // { ssize_t getdirentries(int fd, char *buf, size_t count, off_t *basep); }
+	SYS_STATFS                   = 555 // { int statfs(char *path, struct statfs *buf); }
+	SYS_FSTATFS                  = 556 // { int fstatfs(int fd, struct statfs *buf); }
+	SYS_GETFSSTAT                = 557 // { int getfsstat(struct statfs *buf, long bufsize, int mode); }
+	SYS_FHSTATFS                 = 558 // { int fhstatfs(const struct fhandle *u_fhp, struct statfs *buf); }
+	SYS_MKNODAT                  = 559 // { int mknodat(int fd, char *path, mode_t mode, dev_t dev); }
+	SYS_KEVENT                   = 560 // { int kevent(int fd, struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents, const struct timespec *timeout); }
+	SYS_CPUSET_GETDOMAIN         = 561 // { int cpuset_getdomain(cpulevel_t level, cpuwhich_t which, id_t id, size_t domainsetsize, domainset_t *mask, int *policy); }
+	SYS_CPUSET_SETDOMAIN         = 562 // { int cpuset_setdomain(cpulevel_t level, cpuwhich_t which, id_t id, size_t domainsetsize, domainset_t *mask, int policy); }
+	SYS_GETRANDOM                = 563 // { int getrandom(void *buf, size_t buflen, unsigned int flags); }
+	SYS_GETFHAT                  = 564 // { int getfhat(int fd, char *path, struct fhandle *fhp, int flags); }
+	SYS_FHLINK                   = 565 // { int fhlink(struct fhandle *fhp, const char *to); }
+	SYS_FHLINKAT                 = 566 // { int fhlinkat(struct fhandle *fhp, int tofd, const char *to,); }
+	SYS_FHREADLINK               = 567 // { int fhreadlink(struct fhandle *fhp, char *buf, size_t bufsize); }
+	SYS___SYSCTLBYNAME           = 570 // { int __sysctlbyname(const char *name, size_t namelen, void *old, size_t *oldlenp, void *new, size_t newlen); }
+	SYS_CLOSE_RANGE              = 575 // { int close_range(u_int lowfd, u_int highfd, int flags); }
 )
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_freebsd_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_freebsd_amd64.go
index 342d471..01636b8 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_freebsd_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_freebsd_amd64.go
@@ -1,4 +1,4 @@
-// go run mksysnum.go https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master
+// go run mksysnum.go https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build amd64 && freebsd
@@ -19,10 +19,9 @@
 	SYS_UNLINK                   = 10  // { int unlink(char *path); }
 	SYS_CHDIR                    = 12  // { int chdir(char *path); }
 	SYS_FCHDIR                   = 13  // { int fchdir(int fd); }
-	SYS_MKNOD                    = 14  // { int mknod(char *path, int mode, int dev); }
 	SYS_CHMOD                    = 15  // { int chmod(char *path, int mode); }
 	SYS_CHOWN                    = 16  // { int chown(char *path, int uid, int gid); }
-	SYS_OBREAK                   = 17  // { int obreak(char *nsize); } break obreak_args int
+	SYS_BREAK                    = 17  // { caddr_t break(char *nsize); }
 	SYS_GETPID                   = 20  // { pid_t getpid(void); }
 	SYS_MOUNT                    = 21  // { int mount(char *type, char *path, int flags, caddr_t data); }
 	SYS_UNMOUNT                  = 22  // { int unmount(char *path, int flags); }
@@ -43,7 +42,6 @@
 	SYS_KILL                     = 37  // { int kill(int pid, int signum); }
 	SYS_GETPPID                  = 39  // { pid_t getppid(void); }
 	SYS_DUP                      = 41  // { int dup(u_int fd); }
-	SYS_PIPE                     = 42  // { int pipe(void); }
 	SYS_GETEGID                  = 43  // { gid_t getegid(void); }
 	SYS_PROFIL                   = 44  // { int profil(caddr_t samples, size_t size, size_t offset, u_int scale); }
 	SYS_KTRACE                   = 45  // { int ktrace(const char *fname, int ops, int facs, int pid); }
@@ -58,15 +56,14 @@
 	SYS_SYMLINK                  = 57  // { int symlink(char *path, char *link); }
 	SYS_READLINK                 = 58  // { ssize_t readlink(char *path, char *buf, size_t count); }
 	SYS_EXECVE                   = 59  // { int execve(char *fname, char **argv, char **envv); }
-	SYS_UMASK                    = 60  // { int umask(int newmask); } umask umask_args int
+	SYS_UMASK                    = 60  // { int umask(int newmask); }
 	SYS_CHROOT                   = 61  // { int chroot(char *path); }
 	SYS_MSYNC                    = 65  // { int msync(void *addr, size_t len, int flags); }
 	SYS_VFORK                    = 66  // { int vfork(void); }
 	SYS_SBRK                     = 69  // { int sbrk(int incr); }
 	SYS_SSTK                     = 70  // { int sstk(int incr); }
-	SYS_OVADVISE                 = 72  // { int ovadvise(int anom); } vadvise ovadvise_args int
 	SYS_MUNMAP                   = 73  // { int munmap(void *addr, size_t len); }
-	SYS_MPROTECT                 = 74  // { int mprotect(const void *addr, size_t len, int prot); }
+	SYS_MPROTECT                 = 74  // { int mprotect(void *addr, size_t len, int prot); }
 	SYS_MADVISE                  = 75  // { int madvise(void *addr, size_t len, int behav); }
 	SYS_MINCORE                  = 78  // { int mincore(const void *addr, size_t len, char *vec); }
 	SYS_GETGROUPS                = 79  // { int getgroups(u_int gidsetsize, gid_t *gidset); }
@@ -124,14 +121,10 @@
 	SYS_SETGID                   = 181 // { int setgid(gid_t gid); }
 	SYS_SETEGID                  = 182 // { int setegid(gid_t egid); }
 	SYS_SETEUID                  = 183 // { int seteuid(uid_t euid); }
-	SYS_STAT                     = 188 // { int stat(char *path, struct stat *ub); }
-	SYS_FSTAT                    = 189 // { int fstat(int fd, struct stat *sb); }
-	SYS_LSTAT                    = 190 // { int lstat(char *path, struct stat *ub); }
 	SYS_PATHCONF                 = 191 // { int pathconf(char *path, int name); }
 	SYS_FPATHCONF                = 192 // { int fpathconf(int fd, int name); }
 	SYS_GETRLIMIT                = 194 // { int getrlimit(u_int which, struct rlimit *rlp); } getrlimit __getrlimit_args int
 	SYS_SETRLIMIT                = 195 // { int setrlimit(u_int which, struct rlimit *rlp); } setrlimit __setrlimit_args int
-	SYS_GETDIRENTRIES            = 196 // { int getdirentries(int fd, char *buf, u_int count, long *basep); }
 	SYS___SYSCTL                 = 202 // { int __sysctl(int *name, u_int namelen, void *old, size_t *oldlenp, void *new, size_t newlen); } __sysctl sysctl_args int
 	SYS_MLOCK                    = 203 // { int mlock(const void *addr, size_t len); }
 	SYS_MUNLOCK                  = 204 // { int munlock(const void *addr, size_t len); }
@@ -143,12 +136,12 @@
 	SYS_SEMOP                    = 222 // { int semop(int semid, struct sembuf *sops, size_t nsops); }
 	SYS_MSGGET                   = 225 // { int msgget(key_t key, int msgflg); }
 	SYS_MSGSND                   = 226 // { int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); }
-	SYS_MSGRCV                   = 227 // { int msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg); }
+	SYS_MSGRCV                   = 227 // { ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg); }
 	SYS_SHMAT                    = 228 // { int shmat(int shmid, const void *shmaddr, int shmflg); }
 	SYS_SHMDT                    = 230 // { int shmdt(const void *shmaddr); }
 	SYS_SHMGET                   = 231 // { int shmget(key_t key, size_t size, int shmflg); }
 	SYS_CLOCK_GETTIME            = 232 // { int clock_gettime(clockid_t clock_id, struct timespec *tp); }
-	SYS_CLOCK_SETTIME            = 233 // { int clock_settime( clockid_t clock_id, const struct timespec *tp); }
+	SYS_CLOCK_SETTIME            = 233 // { int clock_settime(clockid_t clock_id, const struct timespec *tp); }
 	SYS_CLOCK_GETRES             = 234 // { int clock_getres(clockid_t clock_id, struct timespec *tp); }
 	SYS_KTIMER_CREATE            = 235 // { int ktimer_create(clockid_t clock_id, struct sigevent *evp, int *timerid); }
 	SYS_KTIMER_DELETE            = 236 // { int ktimer_delete(int timerid); }
@@ -157,50 +150,44 @@
 	SYS_KTIMER_GETOVERRUN        = 239 // { int ktimer_getoverrun(int timerid); }
 	SYS_NANOSLEEP                = 240 // { int nanosleep(const struct timespec *rqtp, struct timespec *rmtp); }
 	SYS_FFCLOCK_GETCOUNTER       = 241 // { int ffclock_getcounter(ffcounter *ffcount); }
-	SYS_FFCLOCK_SETESTIMATE      = 242 // { int ffclock_setestimate( struct ffclock_estimate *cest); }
-	SYS_FFCLOCK_GETESTIMATE      = 243 // { int ffclock_getestimate( struct ffclock_estimate *cest); }
+	SYS_FFCLOCK_SETESTIMATE      = 242 // { int ffclock_setestimate(struct ffclock_estimate *cest); }
+	SYS_FFCLOCK_GETESTIMATE      = 243 // { int ffclock_getestimate(struct ffclock_estimate *cest); }
 	SYS_CLOCK_NANOSLEEP          = 244 // { int clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *rqtp, struct timespec *rmtp); }
-	SYS_CLOCK_GETCPUCLOCKID2     = 247 // { int clock_getcpuclockid2(id_t id,int which, clockid_t *clock_id); }
+	SYS_CLOCK_GETCPUCLOCKID2     = 247 // { int clock_getcpuclockid2(id_t id, int which, clockid_t *clock_id); }
 	SYS_NTP_GETTIME              = 248 // { int ntp_gettime(struct ntptimeval *ntvp); }
 	SYS_MINHERIT                 = 250 // { int minherit(void *addr, size_t len, int inherit); }
 	SYS_RFORK                    = 251 // { int rfork(int flags); }
-	SYS_OPENBSD_POLL             = 252 // { int openbsd_poll(struct pollfd *fds, u_int nfds, int timeout); }
 	SYS_ISSETUGID                = 253 // { int issetugid(void); }
 	SYS_LCHOWN                   = 254 // { int lchown(char *path, int uid, int gid); }
 	SYS_AIO_READ                 = 255 // { int aio_read(struct aiocb *aiocbp); }
 	SYS_AIO_WRITE                = 256 // { int aio_write(struct aiocb *aiocbp); }
-	SYS_LIO_LISTIO               = 257 // { int lio_listio(int mode, struct aiocb * const *acb_list, int nent, struct sigevent *sig); }
-	SYS_GETDENTS                 = 272 // { int getdents(int fd, char *buf, size_t count); }
+	SYS_LIO_LISTIO               = 257 // { int lio_listio(int mode, struct aiocb* const *acb_list, int nent, struct sigevent *sig); }
 	SYS_LCHMOD                   = 274 // { int lchmod(char *path, mode_t mode); }
 	SYS_LUTIMES                  = 276 // { int lutimes(char *path, struct timeval *tptr); }
-	SYS_NSTAT                    = 278 // { int nstat(char *path, struct nstat *ub); }
-	SYS_NFSTAT                   = 279 // { int nfstat(int fd, struct nstat *sb); }
-	SYS_NLSTAT                   = 280 // { int nlstat(char *path, struct nstat *ub); }
 	SYS_PREADV                   = 289 // { ssize_t preadv(int fd, struct iovec *iovp, u_int iovcnt, off_t offset); }
 	SYS_PWRITEV                  = 290 // { ssize_t pwritev(int fd, struct iovec *iovp, u_int iovcnt, off_t offset); }
 	SYS_FHOPEN                   = 298 // { int fhopen(const struct fhandle *u_fhp, int flags); }
-	SYS_FHSTAT                   = 299 // { int fhstat(const struct fhandle *u_fhp, struct stat *sb); }
 	SYS_MODNEXT                  = 300 // { int modnext(int modid); }
-	SYS_MODSTAT                  = 301 // { int modstat(int modid, struct module_stat *stat); }
+	SYS_MODSTAT                  = 301 // { int modstat(int modid, struct module_stat* stat); }
 	SYS_MODFNEXT                 = 302 // { int modfnext(int modid); }
 	SYS_MODFIND                  = 303 // { int modfind(const char *name); }
 	SYS_KLDLOAD                  = 304 // { int kldload(const char *file); }
 	SYS_KLDUNLOAD                = 305 // { int kldunload(int fileid); }
 	SYS_KLDFIND                  = 306 // { int kldfind(const char *file); }
 	SYS_KLDNEXT                  = 307 // { int kldnext(int fileid); }
-	SYS_KLDSTAT                  = 308 // { int kldstat(int fileid, struct kld_file_stat* stat); }
+	SYS_KLDSTAT                  = 308 // { int kldstat(int fileid, struct kld_file_stat *stat); }
 	SYS_KLDFIRSTMOD              = 309 // { int kldfirstmod(int fileid); }
 	SYS_GETSID                   = 310 // { int getsid(pid_t pid); }
 	SYS_SETRESUID                = 311 // { int setresuid(uid_t ruid, uid_t euid, uid_t suid); }
 	SYS_SETRESGID                = 312 // { int setresgid(gid_t rgid, gid_t egid, gid_t sgid); }
 	SYS_AIO_RETURN               = 314 // { ssize_t aio_return(struct aiocb *aiocbp); }
-	SYS_AIO_SUSPEND              = 315 // { int aio_suspend( struct aiocb * const * aiocbp, int nent, const struct timespec *timeout); }
+	SYS_AIO_SUSPEND              = 315 // { int aio_suspend(struct aiocb * const * aiocbp, int nent, const struct timespec *timeout); }
 	SYS_AIO_CANCEL               = 316 // { int aio_cancel(int fd, struct aiocb *aiocbp); }
 	SYS_AIO_ERROR                = 317 // { int aio_error(struct aiocb *aiocbp); }
 	SYS_YIELD                    = 321 // { int yield(void); }
 	SYS_MLOCKALL                 = 324 // { int mlockall(int how); }
 	SYS_MUNLOCKALL               = 325 // { int munlockall(void); }
-	SYS___GETCWD                 = 326 // { int __getcwd(char *buf, u_int buflen); }
+	SYS___GETCWD                 = 326 // { int __getcwd(char *buf, size_t buflen); }
 	SYS_SCHED_SETPARAM           = 327 // { int sched_setparam (pid_t pid, const struct sched_param *param); }
 	SYS_SCHED_GETPARAM           = 328 // { int sched_getparam (pid_t pid, struct sched_param *param); }
 	SYS_SCHED_SETSCHEDULER       = 329 // { int sched_setscheduler (pid_t pid, int policy, const struct sched_param *param); }
@@ -226,14 +213,13 @@
 	SYS___ACL_ACLCHECK_FILE      = 353 // { int __acl_aclcheck_file(const char *path, acl_type_t type, struct acl *aclp); }
 	SYS___ACL_ACLCHECK_FD        = 354 // { int __acl_aclcheck_fd(int filedes, acl_type_t type, struct acl *aclp); }
 	SYS_EXTATTRCTL               = 355 // { int extattrctl(const char *path, int cmd, const char *filename, int attrnamespace, const char *attrname); }
-	SYS_EXTATTR_SET_FILE         = 356 // { ssize_t extattr_set_file( const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
-	SYS_EXTATTR_GET_FILE         = 357 // { ssize_t extattr_get_file( const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
+	SYS_EXTATTR_SET_FILE         = 356 // { ssize_t extattr_set_file(const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
+	SYS_EXTATTR_GET_FILE         = 357 // { ssize_t extattr_get_file(const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
 	SYS_EXTATTR_DELETE_FILE      = 358 // { int extattr_delete_file(const char *path, int attrnamespace, const char *attrname); }
-	SYS_AIO_WAITCOMPLETE         = 359 // { ssize_t aio_waitcomplete( struct aiocb **aiocbp, struct timespec *timeout); }
+	SYS_AIO_WAITCOMPLETE         = 359 // { ssize_t aio_waitcomplete(struct aiocb **aiocbp, struct timespec *timeout); }
 	SYS_GETRESUID                = 360 // { int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); }
 	SYS_GETRESGID                = 361 // { int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); }
 	SYS_KQUEUE                   = 362 // { int kqueue(void); }
-	SYS_KEVENT                   = 363 // { int kevent(int fd, struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents, const struct timespec *timeout); }
 	SYS_EXTATTR_SET_FD           = 371 // { ssize_t extattr_set_fd(int fd, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
 	SYS_EXTATTR_GET_FD           = 372 // { ssize_t extattr_get_fd(int fd, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
 	SYS_EXTATTR_DELETE_FD        = 373 // { int extattr_delete_fd(int fd, int attrnamespace, const char *attrname); }
@@ -251,10 +237,6 @@
 	SYS_UUIDGEN                  = 392 // { int uuidgen(struct uuid *store, int count); }
 	SYS_SENDFILE                 = 393 // { int sendfile(int fd, int s, off_t offset, size_t nbytes, struct sf_hdtr *hdtr, off_t *sbytes, int flags); }
 	SYS_MAC_SYSCALL              = 394 // { int mac_syscall(const char *policy, int call, void *arg); }
-	SYS_GETFSSTAT                = 395 // { int getfsstat(struct statfs *buf, long bufsize, int mode); }
-	SYS_STATFS                   = 396 // { int statfs(char *path, struct statfs *buf); }
-	SYS_FSTATFS                  = 397 // { int fstatfs(int fd, struct statfs *buf); }
-	SYS_FHSTATFS                 = 398 // { int fhstatfs(const struct fhandle *u_fhp, struct statfs *buf); }
 	SYS_KSEM_CLOSE               = 400 // { int ksem_close(semid_t id); }
 	SYS_KSEM_POST                = 401 // { int ksem_post(semid_t id); }
 	SYS_KSEM_WAIT                = 402 // { int ksem_wait(semid_t id); }
@@ -267,14 +249,14 @@
 	SYS___MAC_GET_PID            = 409 // { int __mac_get_pid(pid_t pid, struct mac *mac_p); }
 	SYS___MAC_GET_LINK           = 410 // { int __mac_get_link(const char *path_p, struct mac *mac_p); }
 	SYS___MAC_SET_LINK           = 411 // { int __mac_set_link(const char *path_p, struct mac *mac_p); }
-	SYS_EXTATTR_SET_LINK         = 412 // { ssize_t extattr_set_link( const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
-	SYS_EXTATTR_GET_LINK         = 413 // { ssize_t extattr_get_link( const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
-	SYS_EXTATTR_DELETE_LINK      = 414 // { int extattr_delete_link( const char *path, int attrnamespace, const char *attrname); }
+	SYS_EXTATTR_SET_LINK         = 412 // { ssize_t extattr_set_link(const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
+	SYS_EXTATTR_GET_LINK         = 413 // { ssize_t extattr_get_link(const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
+	SYS_EXTATTR_DELETE_LINK      = 414 // { int extattr_delete_link(const char *path, int attrnamespace, const char *attrname); }
 	SYS___MAC_EXECVE             = 415 // { int __mac_execve(char *fname, char **argv, char **envv, struct mac *mac_p); }
 	SYS_SIGACTION                = 416 // { int sigaction(int sig, const struct sigaction *act, struct sigaction *oact); }
-	SYS_SIGRETURN                = 417 // { int sigreturn( const struct __ucontext *sigcntxp); }
+	SYS_SIGRETURN                = 417 // { int sigreturn(const struct __ucontext *sigcntxp); }
 	SYS_GETCONTEXT               = 421 // { int getcontext(struct __ucontext *ucp); }
-	SYS_SETCONTEXT               = 422 // { int setcontext( const struct __ucontext *ucp); }
+	SYS_SETCONTEXT               = 422 // { int setcontext(const struct __ucontext *ucp); }
 	SYS_SWAPCONTEXT              = 423 // { int swapcontext(struct __ucontext *oucp, const struct __ucontext *ucp); }
 	SYS_SWAPOFF                  = 424 // { int swapoff(const char *name); }
 	SYS___ACL_GET_LINK           = 425 // { int __acl_get_link(const char *path, acl_type_t type, struct acl *aclp); }
@@ -288,10 +270,10 @@
 	SYS_THR_KILL                 = 433 // { int thr_kill(long id, int sig); }
 	SYS_JAIL_ATTACH              = 436 // { int jail_attach(int jid); }
 	SYS_EXTATTR_LIST_FD          = 437 // { ssize_t extattr_list_fd(int fd, int attrnamespace, void *data, size_t nbytes); }
-	SYS_EXTATTR_LIST_FILE        = 438 // { ssize_t extattr_list_file( const char *path, int attrnamespace, void *data, size_t nbytes); }
-	SYS_EXTATTR_LIST_LINK        = 439 // { ssize_t extattr_list_link( const char *path, int attrnamespace, void *data, size_t nbytes); }
+	SYS_EXTATTR_LIST_FILE        = 438 // { ssize_t extattr_list_file(const char *path, int attrnamespace, void *data, size_t nbytes); }
+	SYS_EXTATTR_LIST_LINK        = 439 // { ssize_t extattr_list_link(const char *path, int attrnamespace, void *data, size_t nbytes); }
 	SYS_KSEM_TIMEDWAIT           = 441 // { int ksem_timedwait(semid_t id, const struct timespec *abstime); }
-	SYS_THR_SUSPEND              = 442 // { int thr_suspend( const struct timespec *timeout); }
+	SYS_THR_SUSPEND              = 442 // { int thr_suspend(const struct timespec *timeout); }
 	SYS_THR_WAKE                 = 443 // { int thr_wake(long id); }
 	SYS_KLDUNLOADF               = 444 // { int kldunloadf(int fileid, int flags); }
 	SYS_AUDIT                    = 445 // { int audit(const void *record, u_int length); }
@@ -300,17 +282,17 @@
 	SYS_SETAUID                  = 448 // { int setauid(uid_t *auid); }
 	SYS_GETAUDIT                 = 449 // { int getaudit(struct auditinfo *auditinfo); }
 	SYS_SETAUDIT                 = 450 // { int setaudit(struct auditinfo *auditinfo); }
-	SYS_GETAUDIT_ADDR            = 451 // { int getaudit_addr( struct auditinfo_addr *auditinfo_addr, u_int length); }
-	SYS_SETAUDIT_ADDR            = 452 // { int setaudit_addr( struct auditinfo_addr *auditinfo_addr, u_int length); }
+	SYS_GETAUDIT_ADDR            = 451 // { int getaudit_addr(struct auditinfo_addr *auditinfo_addr, u_int length); }
+	SYS_SETAUDIT_ADDR            = 452 // { int setaudit_addr(struct auditinfo_addr *auditinfo_addr, u_int length); }
 	SYS_AUDITCTL                 = 453 // { int auditctl(char *path); }
 	SYS__UMTX_OP                 = 454 // { int _umtx_op(void *obj, int op, u_long val, void *uaddr1, void *uaddr2); }
 	SYS_THR_NEW                  = 455 // { int thr_new(struct thr_param *param, int param_size); }
 	SYS_SIGQUEUE                 = 456 // { int sigqueue(pid_t pid, int signum, void *value); }
 	SYS_KMQ_OPEN                 = 457 // { int kmq_open(const char *path, int flags, mode_t mode, const struct mq_attr *attr); }
-	SYS_KMQ_SETATTR              = 458 // { int kmq_setattr(int mqd,		const struct mq_attr *attr,		struct mq_attr *oattr); }
-	SYS_KMQ_TIMEDRECEIVE         = 459 // { int kmq_timedreceive(int mqd,	char *msg_ptr, size_t msg_len,	unsigned *msg_prio,			const struct timespec *abs_timeout); }
-	SYS_KMQ_TIMEDSEND            = 460 // { int kmq_timedsend(int mqd,		const char *msg_ptr, size_t msg_len,unsigned msg_prio,			const struct timespec *abs_timeout);}
-	SYS_KMQ_NOTIFY               = 461 // { int kmq_notify(int mqd,		const struct sigevent *sigev); }
+	SYS_KMQ_SETATTR              = 458 // { int kmq_setattr(int mqd, const struct mq_attr *attr, struct mq_attr *oattr); }
+	SYS_KMQ_TIMEDRECEIVE         = 459 // { int kmq_timedreceive(int mqd, char *msg_ptr, size_t msg_len, unsigned *msg_prio, const struct timespec *abs_timeout); }
+	SYS_KMQ_TIMEDSEND            = 460 // { int kmq_timedsend(int mqd, const char *msg_ptr, size_t msg_len, unsigned msg_prio, const struct timespec *abs_timeout); }
+	SYS_KMQ_NOTIFY               = 461 // { int kmq_notify(int mqd, const struct sigevent *sigev); }
 	SYS_KMQ_UNLINK               = 462 // { int kmq_unlink(const char *path); }
 	SYS_ABORT2                   = 463 // { int abort2(const char *why, int nargs, void **args); }
 	SYS_THR_SET_NAME             = 464 // { int thr_set_name(long id, const char *name); }
@@ -319,7 +301,7 @@
 	SYS_SCTP_PEELOFF             = 471 // { int sctp_peeloff(int sd, uint32_t name); }
 	SYS_SCTP_GENERIC_SENDMSG     = 472 // { int sctp_generic_sendmsg(int sd, caddr_t msg, int mlen, caddr_t to, __socklen_t tolen, struct sctp_sndrcvinfo *sinfo, int flags); }
 	SYS_SCTP_GENERIC_SENDMSG_IOV = 473 // { int sctp_generic_sendmsg_iov(int sd, struct iovec *iov, int iovlen, caddr_t to, __socklen_t tolen, struct sctp_sndrcvinfo *sinfo, int flags); }
-	SYS_SCTP_GENERIC_RECVMSG     = 474 // { int sctp_generic_recvmsg(int sd, struct iovec *iov, int iovlen, struct sockaddr * from, __socklen_t *fromlenaddr, struct sctp_sndrcvinfo *sinfo, int *msg_flags); }
+	SYS_SCTP_GENERIC_RECVMSG     = 474 // { int sctp_generic_recvmsg(int sd, struct iovec *iov, int iovlen, struct sockaddr *from, __socklen_t *fromlenaddr, struct sctp_sndrcvinfo *sinfo, int *msg_flags); }
 	SYS_PREAD                    = 475 // { ssize_t pread(int fd, void *buf, size_t nbyte, off_t offset); }
 	SYS_PWRITE                   = 476 // { ssize_t pwrite(int fd, const void *buf, size_t nbyte, off_t offset); }
 	SYS_MMAP                     = 477 // { caddr_t mmap(caddr_t addr, size_t len, int prot, int flags, int fd, off_t pos); }
@@ -338,14 +320,12 @@
 	SYS_FCHMODAT                 = 490 // { int fchmodat(int fd, char *path, mode_t mode, int flag); }
 	SYS_FCHOWNAT                 = 491 // { int fchownat(int fd, char *path, uid_t uid, gid_t gid, int flag); }
 	SYS_FEXECVE                  = 492 // { int fexecve(int fd, char **argv, char **envv); }
-	SYS_FSTATAT                  = 493 // { int fstatat(int fd, char *path, struct stat *buf, int flag); }
 	SYS_FUTIMESAT                = 494 // { int futimesat(int fd, char *path, struct timeval *times); }
 	SYS_LINKAT                   = 495 // { int linkat(int fd1, char *path1, int fd2, char *path2, int flag); }
 	SYS_MKDIRAT                  = 496 // { int mkdirat(int fd, char *path, mode_t mode); }
 	SYS_MKFIFOAT                 = 497 // { int mkfifoat(int fd, char *path, mode_t mode); }
-	SYS_MKNODAT                  = 498 // { int mknodat(int fd, char *path, mode_t mode, dev_t dev); }
 	SYS_OPENAT                   = 499 // { int openat(int fd, char *path, int flag, mode_t mode); }
-	SYS_READLINKAT               = 500 // { int readlinkat(int fd, char *path, char *buf, size_t bufsize); }
+	SYS_READLINKAT               = 500 // { ssize_t readlinkat(int fd, char *path, char *buf, size_t bufsize); }
 	SYS_RENAMEAT                 = 501 // { int renameat(int oldfd, char *old, int newfd, char *new); }
 	SYS_SYMLINKAT                = 502 // { int symlinkat(char *path1, int fd, char *path2); }
 	SYS_UNLINKAT                 = 503 // { int unlinkat(int fd, char *path, int flag); }
@@ -391,7 +371,24 @@
 	SYS_PPOLL                    = 545 // { int ppoll(struct pollfd *fds, u_int nfds, const struct timespec *ts, const sigset_t *set); }
 	SYS_FUTIMENS                 = 546 // { int futimens(int fd, struct timespec *times); }
 	SYS_UTIMENSAT                = 547 // { int utimensat(int fd, char *path, struct timespec *times, int flag); }
-	SYS_NUMA_GETAFFINITY         = 548 // { int numa_getaffinity(cpuwhich_t which, id_t id, struct vm_domain_policy_entry *policy); }
-	SYS_NUMA_SETAFFINITY         = 549 // { int numa_setaffinity(cpuwhich_t which, id_t id, const struct vm_domain_policy_entry *policy); }
 	SYS_FDATASYNC                = 550 // { int fdatasync(int fd); }
+	SYS_FSTAT                    = 551 // { int fstat(int fd, struct stat *sb); }
+	SYS_FSTATAT                  = 552 // { int fstatat(int fd, char *path, struct stat *buf, int flag); }
+	SYS_FHSTAT                   = 553 // { int fhstat(const struct fhandle *u_fhp, struct stat *sb); }
+	SYS_GETDIRENTRIES            = 554 // { ssize_t getdirentries(int fd, char *buf, size_t count, off_t *basep); }
+	SYS_STATFS                   = 555 // { int statfs(char *path, struct statfs *buf); }
+	SYS_FSTATFS                  = 556 // { int fstatfs(int fd, struct statfs *buf); }
+	SYS_GETFSSTAT                = 557 // { int getfsstat(struct statfs *buf, long bufsize, int mode); }
+	SYS_FHSTATFS                 = 558 // { int fhstatfs(const struct fhandle *u_fhp, struct statfs *buf); }
+	SYS_MKNODAT                  = 559 // { int mknodat(int fd, char *path, mode_t mode, dev_t dev); }
+	SYS_KEVENT                   = 560 // { int kevent(int fd, struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents, const struct timespec *timeout); }
+	SYS_CPUSET_GETDOMAIN         = 561 // { int cpuset_getdomain(cpulevel_t level, cpuwhich_t which, id_t id, size_t domainsetsize, domainset_t *mask, int *policy); }
+	SYS_CPUSET_SETDOMAIN         = 562 // { int cpuset_setdomain(cpulevel_t level, cpuwhich_t which, id_t id, size_t domainsetsize, domainset_t *mask, int policy); }
+	SYS_GETRANDOM                = 563 // { int getrandom(void *buf, size_t buflen, unsigned int flags); }
+	SYS_GETFHAT                  = 564 // { int getfhat(int fd, char *path, struct fhandle *fhp, int flags); }
+	SYS_FHLINK                   = 565 // { int fhlink(struct fhandle *fhp, const char *to); }
+	SYS_FHLINKAT                 = 566 // { int fhlinkat(struct fhandle *fhp, int tofd, const char *to,); }
+	SYS_FHREADLINK               = 567 // { int fhreadlink(struct fhandle *fhp, char *buf, size_t bufsize); }
+	SYS___SYSCTLBYNAME           = 570 // { int __sysctlbyname(const char *name, size_t namelen, void *old, size_t *oldlenp, void *new, size_t newlen); }
+	SYS_CLOSE_RANGE              = 575 // { int close_range(u_int lowfd, u_int highfd, int flags); }
 )
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm.go
index e2e3d72..ad99bc1 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm.go
@@ -1,4 +1,4 @@
-// go run mksysnum.go https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master
+// go run mksysnum.go https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build arm && freebsd
@@ -19,10 +19,9 @@
 	SYS_UNLINK                   = 10  // { int unlink(char *path); }
 	SYS_CHDIR                    = 12  // { int chdir(char *path); }
 	SYS_FCHDIR                   = 13  // { int fchdir(int fd); }
-	SYS_MKNOD                    = 14  // { int mknod(char *path, int mode, int dev); }
 	SYS_CHMOD                    = 15  // { int chmod(char *path, int mode); }
 	SYS_CHOWN                    = 16  // { int chown(char *path, int uid, int gid); }
-	SYS_OBREAK                   = 17  // { int obreak(char *nsize); } break obreak_args int
+	SYS_BREAK                    = 17  // { caddr_t break(char *nsize); }
 	SYS_GETPID                   = 20  // { pid_t getpid(void); }
 	SYS_MOUNT                    = 21  // { int mount(char *type, char *path, int flags, caddr_t data); }
 	SYS_UNMOUNT                  = 22  // { int unmount(char *path, int flags); }
@@ -43,7 +42,6 @@
 	SYS_KILL                     = 37  // { int kill(int pid, int signum); }
 	SYS_GETPPID                  = 39  // { pid_t getppid(void); }
 	SYS_DUP                      = 41  // { int dup(u_int fd); }
-	SYS_PIPE                     = 42  // { int pipe(void); }
 	SYS_GETEGID                  = 43  // { gid_t getegid(void); }
 	SYS_PROFIL                   = 44  // { int profil(caddr_t samples, size_t size, size_t offset, u_int scale); }
 	SYS_KTRACE                   = 45  // { int ktrace(const char *fname, int ops, int facs, int pid); }
@@ -58,15 +56,14 @@
 	SYS_SYMLINK                  = 57  // { int symlink(char *path, char *link); }
 	SYS_READLINK                 = 58  // { ssize_t readlink(char *path, char *buf, size_t count); }
 	SYS_EXECVE                   = 59  // { int execve(char *fname, char **argv, char **envv); }
-	SYS_UMASK                    = 60  // { int umask(int newmask); } umask umask_args int
+	SYS_UMASK                    = 60  // { int umask(int newmask); }
 	SYS_CHROOT                   = 61  // { int chroot(char *path); }
 	SYS_MSYNC                    = 65  // { int msync(void *addr, size_t len, int flags); }
 	SYS_VFORK                    = 66  // { int vfork(void); }
 	SYS_SBRK                     = 69  // { int sbrk(int incr); }
 	SYS_SSTK                     = 70  // { int sstk(int incr); }
-	SYS_OVADVISE                 = 72  // { int ovadvise(int anom); } vadvise ovadvise_args int
 	SYS_MUNMAP                   = 73  // { int munmap(void *addr, size_t len); }
-	SYS_MPROTECT                 = 74  // { int mprotect(const void *addr, size_t len, int prot); }
+	SYS_MPROTECT                 = 74  // { int mprotect(void *addr, size_t len, int prot); }
 	SYS_MADVISE                  = 75  // { int madvise(void *addr, size_t len, int behav); }
 	SYS_MINCORE                  = 78  // { int mincore(const void *addr, size_t len, char *vec); }
 	SYS_GETGROUPS                = 79  // { int getgroups(u_int gidsetsize, gid_t *gidset); }
@@ -124,14 +121,10 @@
 	SYS_SETGID                   = 181 // { int setgid(gid_t gid); }
 	SYS_SETEGID                  = 182 // { int setegid(gid_t egid); }
 	SYS_SETEUID                  = 183 // { int seteuid(uid_t euid); }
-	SYS_STAT                     = 188 // { int stat(char *path, struct stat *ub); }
-	SYS_FSTAT                    = 189 // { int fstat(int fd, struct stat *sb); }
-	SYS_LSTAT                    = 190 // { int lstat(char *path, struct stat *ub); }
 	SYS_PATHCONF                 = 191 // { int pathconf(char *path, int name); }
 	SYS_FPATHCONF                = 192 // { int fpathconf(int fd, int name); }
 	SYS_GETRLIMIT                = 194 // { int getrlimit(u_int which, struct rlimit *rlp); } getrlimit __getrlimit_args int
 	SYS_SETRLIMIT                = 195 // { int setrlimit(u_int which, struct rlimit *rlp); } setrlimit __setrlimit_args int
-	SYS_GETDIRENTRIES            = 196 // { int getdirentries(int fd, char *buf, u_int count, long *basep); }
 	SYS___SYSCTL                 = 202 // { int __sysctl(int *name, u_int namelen, void *old, size_t *oldlenp, void *new, size_t newlen); } __sysctl sysctl_args int
 	SYS_MLOCK                    = 203 // { int mlock(const void *addr, size_t len); }
 	SYS_MUNLOCK                  = 204 // { int munlock(const void *addr, size_t len); }
@@ -143,12 +136,12 @@
 	SYS_SEMOP                    = 222 // { int semop(int semid, struct sembuf *sops, size_t nsops); }
 	SYS_MSGGET                   = 225 // { int msgget(key_t key, int msgflg); }
 	SYS_MSGSND                   = 226 // { int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); }
-	SYS_MSGRCV                   = 227 // { int msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg); }
+	SYS_MSGRCV                   = 227 // { ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg); }
 	SYS_SHMAT                    = 228 // { int shmat(int shmid, const void *shmaddr, int shmflg); }
 	SYS_SHMDT                    = 230 // { int shmdt(const void *shmaddr); }
 	SYS_SHMGET                   = 231 // { int shmget(key_t key, size_t size, int shmflg); }
 	SYS_CLOCK_GETTIME            = 232 // { int clock_gettime(clockid_t clock_id, struct timespec *tp); }
-	SYS_CLOCK_SETTIME            = 233 // { int clock_settime( clockid_t clock_id, const struct timespec *tp); }
+	SYS_CLOCK_SETTIME            = 233 // { int clock_settime(clockid_t clock_id, const struct timespec *tp); }
 	SYS_CLOCK_GETRES             = 234 // { int clock_getres(clockid_t clock_id, struct timespec *tp); }
 	SYS_KTIMER_CREATE            = 235 // { int ktimer_create(clockid_t clock_id, struct sigevent *evp, int *timerid); }
 	SYS_KTIMER_DELETE            = 236 // { int ktimer_delete(int timerid); }
@@ -157,50 +150,44 @@
 	SYS_KTIMER_GETOVERRUN        = 239 // { int ktimer_getoverrun(int timerid); }
 	SYS_NANOSLEEP                = 240 // { int nanosleep(const struct timespec *rqtp, struct timespec *rmtp); }
 	SYS_FFCLOCK_GETCOUNTER       = 241 // { int ffclock_getcounter(ffcounter *ffcount); }
-	SYS_FFCLOCK_SETESTIMATE      = 242 // { int ffclock_setestimate( struct ffclock_estimate *cest); }
-	SYS_FFCLOCK_GETESTIMATE      = 243 // { int ffclock_getestimate( struct ffclock_estimate *cest); }
+	SYS_FFCLOCK_SETESTIMATE      = 242 // { int ffclock_setestimate(struct ffclock_estimate *cest); }
+	SYS_FFCLOCK_GETESTIMATE      = 243 // { int ffclock_getestimate(struct ffclock_estimate *cest); }
 	SYS_CLOCK_NANOSLEEP          = 244 // { int clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *rqtp, struct timespec *rmtp); }
-	SYS_CLOCK_GETCPUCLOCKID2     = 247 // { int clock_getcpuclockid2(id_t id,int which, clockid_t *clock_id); }
+	SYS_CLOCK_GETCPUCLOCKID2     = 247 // { int clock_getcpuclockid2(id_t id, int which, clockid_t *clock_id); }
 	SYS_NTP_GETTIME              = 248 // { int ntp_gettime(struct ntptimeval *ntvp); }
 	SYS_MINHERIT                 = 250 // { int minherit(void *addr, size_t len, int inherit); }
 	SYS_RFORK                    = 251 // { int rfork(int flags); }
-	SYS_OPENBSD_POLL             = 252 // { int openbsd_poll(struct pollfd *fds, u_int nfds, int timeout); }
 	SYS_ISSETUGID                = 253 // { int issetugid(void); }
 	SYS_LCHOWN                   = 254 // { int lchown(char *path, int uid, int gid); }
 	SYS_AIO_READ                 = 255 // { int aio_read(struct aiocb *aiocbp); }
 	SYS_AIO_WRITE                = 256 // { int aio_write(struct aiocb *aiocbp); }
-	SYS_LIO_LISTIO               = 257 // { int lio_listio(int mode, struct aiocb * const *acb_list, int nent, struct sigevent *sig); }
-	SYS_GETDENTS                 = 272 // { int getdents(int fd, char *buf, size_t count); }
+	SYS_LIO_LISTIO               = 257 // { int lio_listio(int mode, struct aiocb* const *acb_list, int nent, struct sigevent *sig); }
 	SYS_LCHMOD                   = 274 // { int lchmod(char *path, mode_t mode); }
 	SYS_LUTIMES                  = 276 // { int lutimes(char *path, struct timeval *tptr); }
-	SYS_NSTAT                    = 278 // { int nstat(char *path, struct nstat *ub); }
-	SYS_NFSTAT                   = 279 // { int nfstat(int fd, struct nstat *sb); }
-	SYS_NLSTAT                   = 280 // { int nlstat(char *path, struct nstat *ub); }
 	SYS_PREADV                   = 289 // { ssize_t preadv(int fd, struct iovec *iovp, u_int iovcnt, off_t offset); }
 	SYS_PWRITEV                  = 290 // { ssize_t pwritev(int fd, struct iovec *iovp, u_int iovcnt, off_t offset); }
 	SYS_FHOPEN                   = 298 // { int fhopen(const struct fhandle *u_fhp, int flags); }
-	SYS_FHSTAT                   = 299 // { int fhstat(const struct fhandle *u_fhp, struct stat *sb); }
 	SYS_MODNEXT                  = 300 // { int modnext(int modid); }
-	SYS_MODSTAT                  = 301 // { int modstat(int modid, struct module_stat *stat); }
+	SYS_MODSTAT                  = 301 // { int modstat(int modid, struct module_stat* stat); }
 	SYS_MODFNEXT                 = 302 // { int modfnext(int modid); }
 	SYS_MODFIND                  = 303 // { int modfind(const char *name); }
 	SYS_KLDLOAD                  = 304 // { int kldload(const char *file); }
 	SYS_KLDUNLOAD                = 305 // { int kldunload(int fileid); }
 	SYS_KLDFIND                  = 306 // { int kldfind(const char *file); }
 	SYS_KLDNEXT                  = 307 // { int kldnext(int fileid); }
-	SYS_KLDSTAT                  = 308 // { int kldstat(int fileid, struct kld_file_stat* stat); }
+	SYS_KLDSTAT                  = 308 // { int kldstat(int fileid, struct kld_file_stat *stat); }
 	SYS_KLDFIRSTMOD              = 309 // { int kldfirstmod(int fileid); }
 	SYS_GETSID                   = 310 // { int getsid(pid_t pid); }
 	SYS_SETRESUID                = 311 // { int setresuid(uid_t ruid, uid_t euid, uid_t suid); }
 	SYS_SETRESGID                = 312 // { int setresgid(gid_t rgid, gid_t egid, gid_t sgid); }
 	SYS_AIO_RETURN               = 314 // { ssize_t aio_return(struct aiocb *aiocbp); }
-	SYS_AIO_SUSPEND              = 315 // { int aio_suspend( struct aiocb * const * aiocbp, int nent, const struct timespec *timeout); }
+	SYS_AIO_SUSPEND              = 315 // { int aio_suspend(struct aiocb * const * aiocbp, int nent, const struct timespec *timeout); }
 	SYS_AIO_CANCEL               = 316 // { int aio_cancel(int fd, struct aiocb *aiocbp); }
 	SYS_AIO_ERROR                = 317 // { int aio_error(struct aiocb *aiocbp); }
 	SYS_YIELD                    = 321 // { int yield(void); }
 	SYS_MLOCKALL                 = 324 // { int mlockall(int how); }
 	SYS_MUNLOCKALL               = 325 // { int munlockall(void); }
-	SYS___GETCWD                 = 326 // { int __getcwd(char *buf, u_int buflen); }
+	SYS___GETCWD                 = 326 // { int __getcwd(char *buf, size_t buflen); }
 	SYS_SCHED_SETPARAM           = 327 // { int sched_setparam (pid_t pid, const struct sched_param *param); }
 	SYS_SCHED_GETPARAM           = 328 // { int sched_getparam (pid_t pid, struct sched_param *param); }
 	SYS_SCHED_SETSCHEDULER       = 329 // { int sched_setscheduler (pid_t pid, int policy, const struct sched_param *param); }
@@ -226,14 +213,13 @@
 	SYS___ACL_ACLCHECK_FILE      = 353 // { int __acl_aclcheck_file(const char *path, acl_type_t type, struct acl *aclp); }
 	SYS___ACL_ACLCHECK_FD        = 354 // { int __acl_aclcheck_fd(int filedes, acl_type_t type, struct acl *aclp); }
 	SYS_EXTATTRCTL               = 355 // { int extattrctl(const char *path, int cmd, const char *filename, int attrnamespace, const char *attrname); }
-	SYS_EXTATTR_SET_FILE         = 356 // { ssize_t extattr_set_file( const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
-	SYS_EXTATTR_GET_FILE         = 357 // { ssize_t extattr_get_file( const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
+	SYS_EXTATTR_SET_FILE         = 356 // { ssize_t extattr_set_file(const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
+	SYS_EXTATTR_GET_FILE         = 357 // { ssize_t extattr_get_file(const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
 	SYS_EXTATTR_DELETE_FILE      = 358 // { int extattr_delete_file(const char *path, int attrnamespace, const char *attrname); }
-	SYS_AIO_WAITCOMPLETE         = 359 // { ssize_t aio_waitcomplete( struct aiocb **aiocbp, struct timespec *timeout); }
+	SYS_AIO_WAITCOMPLETE         = 359 // { ssize_t aio_waitcomplete(struct aiocb **aiocbp, struct timespec *timeout); }
 	SYS_GETRESUID                = 360 // { int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); }
 	SYS_GETRESGID                = 361 // { int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); }
 	SYS_KQUEUE                   = 362 // { int kqueue(void); }
-	SYS_KEVENT                   = 363 // { int kevent(int fd, struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents, const struct timespec *timeout); }
 	SYS_EXTATTR_SET_FD           = 371 // { ssize_t extattr_set_fd(int fd, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
 	SYS_EXTATTR_GET_FD           = 372 // { ssize_t extattr_get_fd(int fd, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
 	SYS_EXTATTR_DELETE_FD        = 373 // { int extattr_delete_fd(int fd, int attrnamespace, const char *attrname); }
@@ -251,10 +237,6 @@
 	SYS_UUIDGEN                  = 392 // { int uuidgen(struct uuid *store, int count); }
 	SYS_SENDFILE                 = 393 // { int sendfile(int fd, int s, off_t offset, size_t nbytes, struct sf_hdtr *hdtr, off_t *sbytes, int flags); }
 	SYS_MAC_SYSCALL              = 394 // { int mac_syscall(const char *policy, int call, void *arg); }
-	SYS_GETFSSTAT                = 395 // { int getfsstat(struct statfs *buf, long bufsize, int mode); }
-	SYS_STATFS                   = 396 // { int statfs(char *path, struct statfs *buf); }
-	SYS_FSTATFS                  = 397 // { int fstatfs(int fd, struct statfs *buf); }
-	SYS_FHSTATFS                 = 398 // { int fhstatfs(const struct fhandle *u_fhp, struct statfs *buf); }
 	SYS_KSEM_CLOSE               = 400 // { int ksem_close(semid_t id); }
 	SYS_KSEM_POST                = 401 // { int ksem_post(semid_t id); }
 	SYS_KSEM_WAIT                = 402 // { int ksem_wait(semid_t id); }
@@ -267,14 +249,14 @@
 	SYS___MAC_GET_PID            = 409 // { int __mac_get_pid(pid_t pid, struct mac *mac_p); }
 	SYS___MAC_GET_LINK           = 410 // { int __mac_get_link(const char *path_p, struct mac *mac_p); }
 	SYS___MAC_SET_LINK           = 411 // { int __mac_set_link(const char *path_p, struct mac *mac_p); }
-	SYS_EXTATTR_SET_LINK         = 412 // { ssize_t extattr_set_link( const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
-	SYS_EXTATTR_GET_LINK         = 413 // { ssize_t extattr_get_link( const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
-	SYS_EXTATTR_DELETE_LINK      = 414 // { int extattr_delete_link( const char *path, int attrnamespace, const char *attrname); }
+	SYS_EXTATTR_SET_LINK         = 412 // { ssize_t extattr_set_link(const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
+	SYS_EXTATTR_GET_LINK         = 413 // { ssize_t extattr_get_link(const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
+	SYS_EXTATTR_DELETE_LINK      = 414 // { int extattr_delete_link(const char *path, int attrnamespace, const char *attrname); }
 	SYS___MAC_EXECVE             = 415 // { int __mac_execve(char *fname, char **argv, char **envv, struct mac *mac_p); }
 	SYS_SIGACTION                = 416 // { int sigaction(int sig, const struct sigaction *act, struct sigaction *oact); }
-	SYS_SIGRETURN                = 417 // { int sigreturn( const struct __ucontext *sigcntxp); }
+	SYS_SIGRETURN                = 417 // { int sigreturn(const struct __ucontext *sigcntxp); }
 	SYS_GETCONTEXT               = 421 // { int getcontext(struct __ucontext *ucp); }
-	SYS_SETCONTEXT               = 422 // { int setcontext( const struct __ucontext *ucp); }
+	SYS_SETCONTEXT               = 422 // { int setcontext(const struct __ucontext *ucp); }
 	SYS_SWAPCONTEXT              = 423 // { int swapcontext(struct __ucontext *oucp, const struct __ucontext *ucp); }
 	SYS_SWAPOFF                  = 424 // { int swapoff(const char *name); }
 	SYS___ACL_GET_LINK           = 425 // { int __acl_get_link(const char *path, acl_type_t type, struct acl *aclp); }
@@ -288,10 +270,10 @@
 	SYS_THR_KILL                 = 433 // { int thr_kill(long id, int sig); }
 	SYS_JAIL_ATTACH              = 436 // { int jail_attach(int jid); }
 	SYS_EXTATTR_LIST_FD          = 437 // { ssize_t extattr_list_fd(int fd, int attrnamespace, void *data, size_t nbytes); }
-	SYS_EXTATTR_LIST_FILE        = 438 // { ssize_t extattr_list_file( const char *path, int attrnamespace, void *data, size_t nbytes); }
-	SYS_EXTATTR_LIST_LINK        = 439 // { ssize_t extattr_list_link( const char *path, int attrnamespace, void *data, size_t nbytes); }
+	SYS_EXTATTR_LIST_FILE        = 438 // { ssize_t extattr_list_file(const char *path, int attrnamespace, void *data, size_t nbytes); }
+	SYS_EXTATTR_LIST_LINK        = 439 // { ssize_t extattr_list_link(const char *path, int attrnamespace, void *data, size_t nbytes); }
 	SYS_KSEM_TIMEDWAIT           = 441 // { int ksem_timedwait(semid_t id, const struct timespec *abstime); }
-	SYS_THR_SUSPEND              = 442 // { int thr_suspend( const struct timespec *timeout); }
+	SYS_THR_SUSPEND              = 442 // { int thr_suspend(const struct timespec *timeout); }
 	SYS_THR_WAKE                 = 443 // { int thr_wake(long id); }
 	SYS_KLDUNLOADF               = 444 // { int kldunloadf(int fileid, int flags); }
 	SYS_AUDIT                    = 445 // { int audit(const void *record, u_int length); }
@@ -300,17 +282,17 @@
 	SYS_SETAUID                  = 448 // { int setauid(uid_t *auid); }
 	SYS_GETAUDIT                 = 449 // { int getaudit(struct auditinfo *auditinfo); }
 	SYS_SETAUDIT                 = 450 // { int setaudit(struct auditinfo *auditinfo); }
-	SYS_GETAUDIT_ADDR            = 451 // { int getaudit_addr( struct auditinfo_addr *auditinfo_addr, u_int length); }
-	SYS_SETAUDIT_ADDR            = 452 // { int setaudit_addr( struct auditinfo_addr *auditinfo_addr, u_int length); }
+	SYS_GETAUDIT_ADDR            = 451 // { int getaudit_addr(struct auditinfo_addr *auditinfo_addr, u_int length); }
+	SYS_SETAUDIT_ADDR            = 452 // { int setaudit_addr(struct auditinfo_addr *auditinfo_addr, u_int length); }
 	SYS_AUDITCTL                 = 453 // { int auditctl(char *path); }
 	SYS__UMTX_OP                 = 454 // { int _umtx_op(void *obj, int op, u_long val, void *uaddr1, void *uaddr2); }
 	SYS_THR_NEW                  = 455 // { int thr_new(struct thr_param *param, int param_size); }
 	SYS_SIGQUEUE                 = 456 // { int sigqueue(pid_t pid, int signum, void *value); }
 	SYS_KMQ_OPEN                 = 457 // { int kmq_open(const char *path, int flags, mode_t mode, const struct mq_attr *attr); }
-	SYS_KMQ_SETATTR              = 458 // { int kmq_setattr(int mqd,		const struct mq_attr *attr,		struct mq_attr *oattr); }
-	SYS_KMQ_TIMEDRECEIVE         = 459 // { int kmq_timedreceive(int mqd,	char *msg_ptr, size_t msg_len,	unsigned *msg_prio,			const struct timespec *abs_timeout); }
-	SYS_KMQ_TIMEDSEND            = 460 // { int kmq_timedsend(int mqd,		const char *msg_ptr, size_t msg_len,unsigned msg_prio,			const struct timespec *abs_timeout);}
-	SYS_KMQ_NOTIFY               = 461 // { int kmq_notify(int mqd,		const struct sigevent *sigev); }
+	SYS_KMQ_SETATTR              = 458 // { int kmq_setattr(int mqd, const struct mq_attr *attr, struct mq_attr *oattr); }
+	SYS_KMQ_TIMEDRECEIVE         = 459 // { int kmq_timedreceive(int mqd, char *msg_ptr, size_t msg_len, unsigned *msg_prio, const struct timespec *abs_timeout); }
+	SYS_KMQ_TIMEDSEND            = 460 // { int kmq_timedsend(int mqd, const char *msg_ptr, size_t msg_len, unsigned msg_prio, const struct timespec *abs_timeout); }
+	SYS_KMQ_NOTIFY               = 461 // { int kmq_notify(int mqd, const struct sigevent *sigev); }
 	SYS_KMQ_UNLINK               = 462 // { int kmq_unlink(const char *path); }
 	SYS_ABORT2                   = 463 // { int abort2(const char *why, int nargs, void **args); }
 	SYS_THR_SET_NAME             = 464 // { int thr_set_name(long id, const char *name); }
@@ -319,7 +301,7 @@
 	SYS_SCTP_PEELOFF             = 471 // { int sctp_peeloff(int sd, uint32_t name); }
 	SYS_SCTP_GENERIC_SENDMSG     = 472 // { int sctp_generic_sendmsg(int sd, caddr_t msg, int mlen, caddr_t to, __socklen_t tolen, struct sctp_sndrcvinfo *sinfo, int flags); }
 	SYS_SCTP_GENERIC_SENDMSG_IOV = 473 // { int sctp_generic_sendmsg_iov(int sd, struct iovec *iov, int iovlen, caddr_t to, __socklen_t tolen, struct sctp_sndrcvinfo *sinfo, int flags); }
-	SYS_SCTP_GENERIC_RECVMSG     = 474 // { int sctp_generic_recvmsg(int sd, struct iovec *iov, int iovlen, struct sockaddr * from, __socklen_t *fromlenaddr, struct sctp_sndrcvinfo *sinfo, int *msg_flags); }
+	SYS_SCTP_GENERIC_RECVMSG     = 474 // { int sctp_generic_recvmsg(int sd, struct iovec *iov, int iovlen, struct sockaddr *from, __socklen_t *fromlenaddr, struct sctp_sndrcvinfo *sinfo, int *msg_flags); }
 	SYS_PREAD                    = 475 // { ssize_t pread(int fd, void *buf, size_t nbyte, off_t offset); }
 	SYS_PWRITE                   = 476 // { ssize_t pwrite(int fd, const void *buf, size_t nbyte, off_t offset); }
 	SYS_MMAP                     = 477 // { caddr_t mmap(caddr_t addr, size_t len, int prot, int flags, int fd, off_t pos); }
@@ -338,14 +320,12 @@
 	SYS_FCHMODAT                 = 490 // { int fchmodat(int fd, char *path, mode_t mode, int flag); }
 	SYS_FCHOWNAT                 = 491 // { int fchownat(int fd, char *path, uid_t uid, gid_t gid, int flag); }
 	SYS_FEXECVE                  = 492 // { int fexecve(int fd, char **argv, char **envv); }
-	SYS_FSTATAT                  = 493 // { int fstatat(int fd, char *path, struct stat *buf, int flag); }
 	SYS_FUTIMESAT                = 494 // { int futimesat(int fd, char *path, struct timeval *times); }
 	SYS_LINKAT                   = 495 // { int linkat(int fd1, char *path1, int fd2, char *path2, int flag); }
 	SYS_MKDIRAT                  = 496 // { int mkdirat(int fd, char *path, mode_t mode); }
 	SYS_MKFIFOAT                 = 497 // { int mkfifoat(int fd, char *path, mode_t mode); }
-	SYS_MKNODAT                  = 498 // { int mknodat(int fd, char *path, mode_t mode, dev_t dev); }
 	SYS_OPENAT                   = 499 // { int openat(int fd, char *path, int flag, mode_t mode); }
-	SYS_READLINKAT               = 500 // { int readlinkat(int fd, char *path, char *buf, size_t bufsize); }
+	SYS_READLINKAT               = 500 // { ssize_t readlinkat(int fd, char *path, char *buf, size_t bufsize); }
 	SYS_RENAMEAT                 = 501 // { int renameat(int oldfd, char *old, int newfd, char *new); }
 	SYS_SYMLINKAT                = 502 // { int symlinkat(char *path1, int fd, char *path2); }
 	SYS_UNLINKAT                 = 503 // { int unlinkat(int fd, char *path, int flag); }
@@ -391,7 +371,24 @@
 	SYS_PPOLL                    = 545 // { int ppoll(struct pollfd *fds, u_int nfds, const struct timespec *ts, const sigset_t *set); }
 	SYS_FUTIMENS                 = 546 // { int futimens(int fd, struct timespec *times); }
 	SYS_UTIMENSAT                = 547 // { int utimensat(int fd, char *path, struct timespec *times, int flag); }
-	SYS_NUMA_GETAFFINITY         = 548 // { int numa_getaffinity(cpuwhich_t which, id_t id, struct vm_domain_policy_entry *policy); }
-	SYS_NUMA_SETAFFINITY         = 549 // { int numa_setaffinity(cpuwhich_t which, id_t id, const struct vm_domain_policy_entry *policy); }
 	SYS_FDATASYNC                = 550 // { int fdatasync(int fd); }
+	SYS_FSTAT                    = 551 // { int fstat(int fd, struct stat *sb); }
+	SYS_FSTATAT                  = 552 // { int fstatat(int fd, char *path, struct stat *buf, int flag); }
+	SYS_FHSTAT                   = 553 // { int fhstat(const struct fhandle *u_fhp, struct stat *sb); }
+	SYS_GETDIRENTRIES            = 554 // { ssize_t getdirentries(int fd, char *buf, size_t count, off_t *basep); }
+	SYS_STATFS                   = 555 // { int statfs(char *path, struct statfs *buf); }
+	SYS_FSTATFS                  = 556 // { int fstatfs(int fd, struct statfs *buf); }
+	SYS_GETFSSTAT                = 557 // { int getfsstat(struct statfs *buf, long bufsize, int mode); }
+	SYS_FHSTATFS                 = 558 // { int fhstatfs(const struct fhandle *u_fhp, struct statfs *buf); }
+	SYS_MKNODAT                  = 559 // { int mknodat(int fd, char *path, mode_t mode, dev_t dev); }
+	SYS_KEVENT                   = 560 // { int kevent(int fd, struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents, const struct timespec *timeout); }
+	SYS_CPUSET_GETDOMAIN         = 561 // { int cpuset_getdomain(cpulevel_t level, cpuwhich_t which, id_t id, size_t domainsetsize, domainset_t *mask, int *policy); }
+	SYS_CPUSET_SETDOMAIN         = 562 // { int cpuset_setdomain(cpulevel_t level, cpuwhich_t which, id_t id, size_t domainsetsize, domainset_t *mask, int policy); }
+	SYS_GETRANDOM                = 563 // { int getrandom(void *buf, size_t buflen, unsigned int flags); }
+	SYS_GETFHAT                  = 564 // { int getfhat(int fd, char *path, struct fhandle *fhp, int flags); }
+	SYS_FHLINK                   = 565 // { int fhlink(struct fhandle *fhp, const char *to); }
+	SYS_FHLINKAT                 = 566 // { int fhlinkat(struct fhandle *fhp, int tofd, const char *to,); }
+	SYS_FHREADLINK               = 567 // { int fhreadlink(struct fhandle *fhp, char *buf, size_t bufsize); }
+	SYS___SYSCTLBYNAME           = 570 // { int __sysctlbyname(const char *name, size_t namelen, void *old, size_t *oldlenp, void *new, size_t newlen); }
+	SYS_CLOSE_RANGE              = 575 // { int close_range(u_int lowfd, u_int highfd, int flags); }
 )
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm64.go
index 61ad5ca..89dcc42 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_freebsd_arm64.go
@@ -1,4 +1,4 @@
-// go run mksysnum.go https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master
+// go run mksysnum.go https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build arm64 && freebsd
@@ -19,10 +19,9 @@
 	SYS_UNLINK                   = 10  // { int unlink(char *path); }
 	SYS_CHDIR                    = 12  // { int chdir(char *path); }
 	SYS_FCHDIR                   = 13  // { int fchdir(int fd); }
-	SYS_MKNOD                    = 14  // { int mknod(char *path, int mode, int dev); }
 	SYS_CHMOD                    = 15  // { int chmod(char *path, int mode); }
 	SYS_CHOWN                    = 16  // { int chown(char *path, int uid, int gid); }
-	SYS_OBREAK                   = 17  // { int obreak(char *nsize); } break obreak_args int
+	SYS_BREAK                    = 17  // { caddr_t break(char *nsize); }
 	SYS_GETPID                   = 20  // { pid_t getpid(void); }
 	SYS_MOUNT                    = 21  // { int mount(char *type, char *path, int flags, caddr_t data); }
 	SYS_UNMOUNT                  = 22  // { int unmount(char *path, int flags); }
@@ -43,7 +42,6 @@
 	SYS_KILL                     = 37  // { int kill(int pid, int signum); }
 	SYS_GETPPID                  = 39  // { pid_t getppid(void); }
 	SYS_DUP                      = 41  // { int dup(u_int fd); }
-	SYS_PIPE                     = 42  // { int pipe(void); }
 	SYS_GETEGID                  = 43  // { gid_t getegid(void); }
 	SYS_PROFIL                   = 44  // { int profil(caddr_t samples, size_t size, size_t offset, u_int scale); }
 	SYS_KTRACE                   = 45  // { int ktrace(const char *fname, int ops, int facs, int pid); }
@@ -58,15 +56,14 @@
 	SYS_SYMLINK                  = 57  // { int symlink(char *path, char *link); }
 	SYS_READLINK                 = 58  // { ssize_t readlink(char *path, char *buf, size_t count); }
 	SYS_EXECVE                   = 59  // { int execve(char *fname, char **argv, char **envv); }
-	SYS_UMASK                    = 60  // { int umask(int newmask); } umask umask_args int
+	SYS_UMASK                    = 60  // { int umask(int newmask); }
 	SYS_CHROOT                   = 61  // { int chroot(char *path); }
 	SYS_MSYNC                    = 65  // { int msync(void *addr, size_t len, int flags); }
 	SYS_VFORK                    = 66  // { int vfork(void); }
 	SYS_SBRK                     = 69  // { int sbrk(int incr); }
 	SYS_SSTK                     = 70  // { int sstk(int incr); }
-	SYS_OVADVISE                 = 72  // { int ovadvise(int anom); } vadvise ovadvise_args int
 	SYS_MUNMAP                   = 73  // { int munmap(void *addr, size_t len); }
-	SYS_MPROTECT                 = 74  // { int mprotect(const void *addr, size_t len, int prot); }
+	SYS_MPROTECT                 = 74  // { int mprotect(void *addr, size_t len, int prot); }
 	SYS_MADVISE                  = 75  // { int madvise(void *addr, size_t len, int behav); }
 	SYS_MINCORE                  = 78  // { int mincore(const void *addr, size_t len, char *vec); }
 	SYS_GETGROUPS                = 79  // { int getgroups(u_int gidsetsize, gid_t *gidset); }
@@ -124,14 +121,10 @@
 	SYS_SETGID                   = 181 // { int setgid(gid_t gid); }
 	SYS_SETEGID                  = 182 // { int setegid(gid_t egid); }
 	SYS_SETEUID                  = 183 // { int seteuid(uid_t euid); }
-	SYS_STAT                     = 188 // { int stat(char *path, struct stat *ub); }
-	SYS_FSTAT                    = 189 // { int fstat(int fd, struct stat *sb); }
-	SYS_LSTAT                    = 190 // { int lstat(char *path, struct stat *ub); }
 	SYS_PATHCONF                 = 191 // { int pathconf(char *path, int name); }
 	SYS_FPATHCONF                = 192 // { int fpathconf(int fd, int name); }
 	SYS_GETRLIMIT                = 194 // { int getrlimit(u_int which, struct rlimit *rlp); } getrlimit __getrlimit_args int
 	SYS_SETRLIMIT                = 195 // { int setrlimit(u_int which, struct rlimit *rlp); } setrlimit __setrlimit_args int
-	SYS_GETDIRENTRIES            = 196 // { int getdirentries(int fd, char *buf, u_int count, long *basep); }
 	SYS___SYSCTL                 = 202 // { int __sysctl(int *name, u_int namelen, void *old, size_t *oldlenp, void *new, size_t newlen); } __sysctl sysctl_args int
 	SYS_MLOCK                    = 203 // { int mlock(const void *addr, size_t len); }
 	SYS_MUNLOCK                  = 204 // { int munlock(const void *addr, size_t len); }
@@ -143,12 +136,12 @@
 	SYS_SEMOP                    = 222 // { int semop(int semid, struct sembuf *sops, size_t nsops); }
 	SYS_MSGGET                   = 225 // { int msgget(key_t key, int msgflg); }
 	SYS_MSGSND                   = 226 // { int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); }
-	SYS_MSGRCV                   = 227 // { int msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg); }
+	SYS_MSGRCV                   = 227 // { ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg); }
 	SYS_SHMAT                    = 228 // { int shmat(int shmid, const void *shmaddr, int shmflg); }
 	SYS_SHMDT                    = 230 // { int shmdt(const void *shmaddr); }
 	SYS_SHMGET                   = 231 // { int shmget(key_t key, size_t size, int shmflg); }
 	SYS_CLOCK_GETTIME            = 232 // { int clock_gettime(clockid_t clock_id, struct timespec *tp); }
-	SYS_CLOCK_SETTIME            = 233 // { int clock_settime( clockid_t clock_id, const struct timespec *tp); }
+	SYS_CLOCK_SETTIME            = 233 // { int clock_settime(clockid_t clock_id, const struct timespec *tp); }
 	SYS_CLOCK_GETRES             = 234 // { int clock_getres(clockid_t clock_id, struct timespec *tp); }
 	SYS_KTIMER_CREATE            = 235 // { int ktimer_create(clockid_t clock_id, struct sigevent *evp, int *timerid); }
 	SYS_KTIMER_DELETE            = 236 // { int ktimer_delete(int timerid); }
@@ -157,50 +150,44 @@
 	SYS_KTIMER_GETOVERRUN        = 239 // { int ktimer_getoverrun(int timerid); }
 	SYS_NANOSLEEP                = 240 // { int nanosleep(const struct timespec *rqtp, struct timespec *rmtp); }
 	SYS_FFCLOCK_GETCOUNTER       = 241 // { int ffclock_getcounter(ffcounter *ffcount); }
-	SYS_FFCLOCK_SETESTIMATE      = 242 // { int ffclock_setestimate( struct ffclock_estimate *cest); }
-	SYS_FFCLOCK_GETESTIMATE      = 243 // { int ffclock_getestimate( struct ffclock_estimate *cest); }
+	SYS_FFCLOCK_SETESTIMATE      = 242 // { int ffclock_setestimate(struct ffclock_estimate *cest); }
+	SYS_FFCLOCK_GETESTIMATE      = 243 // { int ffclock_getestimate(struct ffclock_estimate *cest); }
 	SYS_CLOCK_NANOSLEEP          = 244 // { int clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *rqtp, struct timespec *rmtp); }
-	SYS_CLOCK_GETCPUCLOCKID2     = 247 // { int clock_getcpuclockid2(id_t id,int which, clockid_t *clock_id); }
+	SYS_CLOCK_GETCPUCLOCKID2     = 247 // { int clock_getcpuclockid2(id_t id, int which, clockid_t *clock_id); }
 	SYS_NTP_GETTIME              = 248 // { int ntp_gettime(struct ntptimeval *ntvp); }
 	SYS_MINHERIT                 = 250 // { int minherit(void *addr, size_t len, int inherit); }
 	SYS_RFORK                    = 251 // { int rfork(int flags); }
-	SYS_OPENBSD_POLL             = 252 // { int openbsd_poll(struct pollfd *fds, u_int nfds, int timeout); }
 	SYS_ISSETUGID                = 253 // { int issetugid(void); }
 	SYS_LCHOWN                   = 254 // { int lchown(char *path, int uid, int gid); }
 	SYS_AIO_READ                 = 255 // { int aio_read(struct aiocb *aiocbp); }
 	SYS_AIO_WRITE                = 256 // { int aio_write(struct aiocb *aiocbp); }
-	SYS_LIO_LISTIO               = 257 // { int lio_listio(int mode, struct aiocb * const *acb_list, int nent, struct sigevent *sig); }
-	SYS_GETDENTS                 = 272 // { int getdents(int fd, char *buf, size_t count); }
+	SYS_LIO_LISTIO               = 257 // { int lio_listio(int mode, struct aiocb* const *acb_list, int nent, struct sigevent *sig); }
 	SYS_LCHMOD                   = 274 // { int lchmod(char *path, mode_t mode); }
 	SYS_LUTIMES                  = 276 // { int lutimes(char *path, struct timeval *tptr); }
-	SYS_NSTAT                    = 278 // { int nstat(char *path, struct nstat *ub); }
-	SYS_NFSTAT                   = 279 // { int nfstat(int fd, struct nstat *sb); }
-	SYS_NLSTAT                   = 280 // { int nlstat(char *path, struct nstat *ub); }
 	SYS_PREADV                   = 289 // { ssize_t preadv(int fd, struct iovec *iovp, u_int iovcnt, off_t offset); }
 	SYS_PWRITEV                  = 290 // { ssize_t pwritev(int fd, struct iovec *iovp, u_int iovcnt, off_t offset); }
 	SYS_FHOPEN                   = 298 // { int fhopen(const struct fhandle *u_fhp, int flags); }
-	SYS_FHSTAT                   = 299 // { int fhstat(const struct fhandle *u_fhp, struct stat *sb); }
 	SYS_MODNEXT                  = 300 // { int modnext(int modid); }
-	SYS_MODSTAT                  = 301 // { int modstat(int modid, struct module_stat *stat); }
+	SYS_MODSTAT                  = 301 // { int modstat(int modid, struct module_stat* stat); }
 	SYS_MODFNEXT                 = 302 // { int modfnext(int modid); }
 	SYS_MODFIND                  = 303 // { int modfind(const char *name); }
 	SYS_KLDLOAD                  = 304 // { int kldload(const char *file); }
 	SYS_KLDUNLOAD                = 305 // { int kldunload(int fileid); }
 	SYS_KLDFIND                  = 306 // { int kldfind(const char *file); }
 	SYS_KLDNEXT                  = 307 // { int kldnext(int fileid); }
-	SYS_KLDSTAT                  = 308 // { int kldstat(int fileid, struct kld_file_stat* stat); }
+	SYS_KLDSTAT                  = 308 // { int kldstat(int fileid, struct kld_file_stat *stat); }
 	SYS_KLDFIRSTMOD              = 309 // { int kldfirstmod(int fileid); }
 	SYS_GETSID                   = 310 // { int getsid(pid_t pid); }
 	SYS_SETRESUID                = 311 // { int setresuid(uid_t ruid, uid_t euid, uid_t suid); }
 	SYS_SETRESGID                = 312 // { int setresgid(gid_t rgid, gid_t egid, gid_t sgid); }
 	SYS_AIO_RETURN               = 314 // { ssize_t aio_return(struct aiocb *aiocbp); }
-	SYS_AIO_SUSPEND              = 315 // { int aio_suspend( struct aiocb * const * aiocbp, int nent, const struct timespec *timeout); }
+	SYS_AIO_SUSPEND              = 315 // { int aio_suspend(struct aiocb * const * aiocbp, int nent, const struct timespec *timeout); }
 	SYS_AIO_CANCEL               = 316 // { int aio_cancel(int fd, struct aiocb *aiocbp); }
 	SYS_AIO_ERROR                = 317 // { int aio_error(struct aiocb *aiocbp); }
 	SYS_YIELD                    = 321 // { int yield(void); }
 	SYS_MLOCKALL                 = 324 // { int mlockall(int how); }
 	SYS_MUNLOCKALL               = 325 // { int munlockall(void); }
-	SYS___GETCWD                 = 326 // { int __getcwd(char *buf, u_int buflen); }
+	SYS___GETCWD                 = 326 // { int __getcwd(char *buf, size_t buflen); }
 	SYS_SCHED_SETPARAM           = 327 // { int sched_setparam (pid_t pid, const struct sched_param *param); }
 	SYS_SCHED_GETPARAM           = 328 // { int sched_getparam (pid_t pid, struct sched_param *param); }
 	SYS_SCHED_SETSCHEDULER       = 329 // { int sched_setscheduler (pid_t pid, int policy, const struct sched_param *param); }
@@ -226,14 +213,13 @@
 	SYS___ACL_ACLCHECK_FILE      = 353 // { int __acl_aclcheck_file(const char *path, acl_type_t type, struct acl *aclp); }
 	SYS___ACL_ACLCHECK_FD        = 354 // { int __acl_aclcheck_fd(int filedes, acl_type_t type, struct acl *aclp); }
 	SYS_EXTATTRCTL               = 355 // { int extattrctl(const char *path, int cmd, const char *filename, int attrnamespace, const char *attrname); }
-	SYS_EXTATTR_SET_FILE         = 356 // { ssize_t extattr_set_file( const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
-	SYS_EXTATTR_GET_FILE         = 357 // { ssize_t extattr_get_file( const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
+	SYS_EXTATTR_SET_FILE         = 356 // { ssize_t extattr_set_file(const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
+	SYS_EXTATTR_GET_FILE         = 357 // { ssize_t extattr_get_file(const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
 	SYS_EXTATTR_DELETE_FILE      = 358 // { int extattr_delete_file(const char *path, int attrnamespace, const char *attrname); }
-	SYS_AIO_WAITCOMPLETE         = 359 // { ssize_t aio_waitcomplete( struct aiocb **aiocbp, struct timespec *timeout); }
+	SYS_AIO_WAITCOMPLETE         = 359 // { ssize_t aio_waitcomplete(struct aiocb **aiocbp, struct timespec *timeout); }
 	SYS_GETRESUID                = 360 // { int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); }
 	SYS_GETRESGID                = 361 // { int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); }
 	SYS_KQUEUE                   = 362 // { int kqueue(void); }
-	SYS_KEVENT                   = 363 // { int kevent(int fd, struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents, const struct timespec *timeout); }
 	SYS_EXTATTR_SET_FD           = 371 // { ssize_t extattr_set_fd(int fd, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
 	SYS_EXTATTR_GET_FD           = 372 // { ssize_t extattr_get_fd(int fd, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
 	SYS_EXTATTR_DELETE_FD        = 373 // { int extattr_delete_fd(int fd, int attrnamespace, const char *attrname); }
@@ -251,10 +237,6 @@
 	SYS_UUIDGEN                  = 392 // { int uuidgen(struct uuid *store, int count); }
 	SYS_SENDFILE                 = 393 // { int sendfile(int fd, int s, off_t offset, size_t nbytes, struct sf_hdtr *hdtr, off_t *sbytes, int flags); }
 	SYS_MAC_SYSCALL              = 394 // { int mac_syscall(const char *policy, int call, void *arg); }
-	SYS_GETFSSTAT                = 395 // { int getfsstat(struct statfs *buf, long bufsize, int mode); }
-	SYS_STATFS                   = 396 // { int statfs(char *path, struct statfs *buf); }
-	SYS_FSTATFS                  = 397 // { int fstatfs(int fd, struct statfs *buf); }
-	SYS_FHSTATFS                 = 398 // { int fhstatfs(const struct fhandle *u_fhp, struct statfs *buf); }
 	SYS_KSEM_CLOSE               = 400 // { int ksem_close(semid_t id); }
 	SYS_KSEM_POST                = 401 // { int ksem_post(semid_t id); }
 	SYS_KSEM_WAIT                = 402 // { int ksem_wait(semid_t id); }
@@ -267,14 +249,14 @@
 	SYS___MAC_GET_PID            = 409 // { int __mac_get_pid(pid_t pid, struct mac *mac_p); }
 	SYS___MAC_GET_LINK           = 410 // { int __mac_get_link(const char *path_p, struct mac *mac_p); }
 	SYS___MAC_SET_LINK           = 411 // { int __mac_set_link(const char *path_p, struct mac *mac_p); }
-	SYS_EXTATTR_SET_LINK         = 412 // { ssize_t extattr_set_link( const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
-	SYS_EXTATTR_GET_LINK         = 413 // { ssize_t extattr_get_link( const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
-	SYS_EXTATTR_DELETE_LINK      = 414 // { int extattr_delete_link( const char *path, int attrnamespace, const char *attrname); }
+	SYS_EXTATTR_SET_LINK         = 412 // { ssize_t extattr_set_link(const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
+	SYS_EXTATTR_GET_LINK         = 413 // { ssize_t extattr_get_link(const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
+	SYS_EXTATTR_DELETE_LINK      = 414 // { int extattr_delete_link(const char *path, int attrnamespace, const char *attrname); }
 	SYS___MAC_EXECVE             = 415 // { int __mac_execve(char *fname, char **argv, char **envv, struct mac *mac_p); }
 	SYS_SIGACTION                = 416 // { int sigaction(int sig, const struct sigaction *act, struct sigaction *oact); }
-	SYS_SIGRETURN                = 417 // { int sigreturn( const struct __ucontext *sigcntxp); }
+	SYS_SIGRETURN                = 417 // { int sigreturn(const struct __ucontext *sigcntxp); }
 	SYS_GETCONTEXT               = 421 // { int getcontext(struct __ucontext *ucp); }
-	SYS_SETCONTEXT               = 422 // { int setcontext( const struct __ucontext *ucp); }
+	SYS_SETCONTEXT               = 422 // { int setcontext(const struct __ucontext *ucp); }
 	SYS_SWAPCONTEXT              = 423 // { int swapcontext(struct __ucontext *oucp, const struct __ucontext *ucp); }
 	SYS_SWAPOFF                  = 424 // { int swapoff(const char *name); }
 	SYS___ACL_GET_LINK           = 425 // { int __acl_get_link(const char *path, acl_type_t type, struct acl *aclp); }
@@ -288,10 +270,10 @@
 	SYS_THR_KILL                 = 433 // { int thr_kill(long id, int sig); }
 	SYS_JAIL_ATTACH              = 436 // { int jail_attach(int jid); }
 	SYS_EXTATTR_LIST_FD          = 437 // { ssize_t extattr_list_fd(int fd, int attrnamespace, void *data, size_t nbytes); }
-	SYS_EXTATTR_LIST_FILE        = 438 // { ssize_t extattr_list_file( const char *path, int attrnamespace, void *data, size_t nbytes); }
-	SYS_EXTATTR_LIST_LINK        = 439 // { ssize_t extattr_list_link( const char *path, int attrnamespace, void *data, size_t nbytes); }
+	SYS_EXTATTR_LIST_FILE        = 438 // { ssize_t extattr_list_file(const char *path, int attrnamespace, void *data, size_t nbytes); }
+	SYS_EXTATTR_LIST_LINK        = 439 // { ssize_t extattr_list_link(const char *path, int attrnamespace, void *data, size_t nbytes); }
 	SYS_KSEM_TIMEDWAIT           = 441 // { int ksem_timedwait(semid_t id, const struct timespec *abstime); }
-	SYS_THR_SUSPEND              = 442 // { int thr_suspend( const struct timespec *timeout); }
+	SYS_THR_SUSPEND              = 442 // { int thr_suspend(const struct timespec *timeout); }
 	SYS_THR_WAKE                 = 443 // { int thr_wake(long id); }
 	SYS_KLDUNLOADF               = 444 // { int kldunloadf(int fileid, int flags); }
 	SYS_AUDIT                    = 445 // { int audit(const void *record, u_int length); }
@@ -300,17 +282,17 @@
 	SYS_SETAUID                  = 448 // { int setauid(uid_t *auid); }
 	SYS_GETAUDIT                 = 449 // { int getaudit(struct auditinfo *auditinfo); }
 	SYS_SETAUDIT                 = 450 // { int setaudit(struct auditinfo *auditinfo); }
-	SYS_GETAUDIT_ADDR            = 451 // { int getaudit_addr( struct auditinfo_addr *auditinfo_addr, u_int length); }
-	SYS_SETAUDIT_ADDR            = 452 // { int setaudit_addr( struct auditinfo_addr *auditinfo_addr, u_int length); }
+	SYS_GETAUDIT_ADDR            = 451 // { int getaudit_addr(struct auditinfo_addr *auditinfo_addr, u_int length); }
+	SYS_SETAUDIT_ADDR            = 452 // { int setaudit_addr(struct auditinfo_addr *auditinfo_addr, u_int length); }
 	SYS_AUDITCTL                 = 453 // { int auditctl(char *path); }
 	SYS__UMTX_OP                 = 454 // { int _umtx_op(void *obj, int op, u_long val, void *uaddr1, void *uaddr2); }
 	SYS_THR_NEW                  = 455 // { int thr_new(struct thr_param *param, int param_size); }
 	SYS_SIGQUEUE                 = 456 // { int sigqueue(pid_t pid, int signum, void *value); }
 	SYS_KMQ_OPEN                 = 457 // { int kmq_open(const char *path, int flags, mode_t mode, const struct mq_attr *attr); }
-	SYS_KMQ_SETATTR              = 458 // { int kmq_setattr(int mqd,		const struct mq_attr *attr,		struct mq_attr *oattr); }
-	SYS_KMQ_TIMEDRECEIVE         = 459 // { int kmq_timedreceive(int mqd,	char *msg_ptr, size_t msg_len,	unsigned *msg_prio,			const struct timespec *abs_timeout); }
-	SYS_KMQ_TIMEDSEND            = 460 // { int kmq_timedsend(int mqd,		const char *msg_ptr, size_t msg_len,unsigned msg_prio,			const struct timespec *abs_timeout);}
-	SYS_KMQ_NOTIFY               = 461 // { int kmq_notify(int mqd,		const struct sigevent *sigev); }
+	SYS_KMQ_SETATTR              = 458 // { int kmq_setattr(int mqd, const struct mq_attr *attr, struct mq_attr *oattr); }
+	SYS_KMQ_TIMEDRECEIVE         = 459 // { int kmq_timedreceive(int mqd, char *msg_ptr, size_t msg_len, unsigned *msg_prio, const struct timespec *abs_timeout); }
+	SYS_KMQ_TIMEDSEND            = 460 // { int kmq_timedsend(int mqd, const char *msg_ptr, size_t msg_len, unsigned msg_prio, const struct timespec *abs_timeout); }
+	SYS_KMQ_NOTIFY               = 461 // { int kmq_notify(int mqd, const struct sigevent *sigev); }
 	SYS_KMQ_UNLINK               = 462 // { int kmq_unlink(const char *path); }
 	SYS_ABORT2                   = 463 // { int abort2(const char *why, int nargs, void **args); }
 	SYS_THR_SET_NAME             = 464 // { int thr_set_name(long id, const char *name); }
@@ -319,7 +301,7 @@
 	SYS_SCTP_PEELOFF             = 471 // { int sctp_peeloff(int sd, uint32_t name); }
 	SYS_SCTP_GENERIC_SENDMSG     = 472 // { int sctp_generic_sendmsg(int sd, caddr_t msg, int mlen, caddr_t to, __socklen_t tolen, struct sctp_sndrcvinfo *sinfo, int flags); }
 	SYS_SCTP_GENERIC_SENDMSG_IOV = 473 // { int sctp_generic_sendmsg_iov(int sd, struct iovec *iov, int iovlen, caddr_t to, __socklen_t tolen, struct sctp_sndrcvinfo *sinfo, int flags); }
-	SYS_SCTP_GENERIC_RECVMSG     = 474 // { int sctp_generic_recvmsg(int sd, struct iovec *iov, int iovlen, struct sockaddr * from, __socklen_t *fromlenaddr, struct sctp_sndrcvinfo *sinfo, int *msg_flags); }
+	SYS_SCTP_GENERIC_RECVMSG     = 474 // { int sctp_generic_recvmsg(int sd, struct iovec *iov, int iovlen, struct sockaddr *from, __socklen_t *fromlenaddr, struct sctp_sndrcvinfo *sinfo, int *msg_flags); }
 	SYS_PREAD                    = 475 // { ssize_t pread(int fd, void *buf, size_t nbyte, off_t offset); }
 	SYS_PWRITE                   = 476 // { ssize_t pwrite(int fd, const void *buf, size_t nbyte, off_t offset); }
 	SYS_MMAP                     = 477 // { caddr_t mmap(caddr_t addr, size_t len, int prot, int flags, int fd, off_t pos); }
@@ -338,14 +320,12 @@
 	SYS_FCHMODAT                 = 490 // { int fchmodat(int fd, char *path, mode_t mode, int flag); }
 	SYS_FCHOWNAT                 = 491 // { int fchownat(int fd, char *path, uid_t uid, gid_t gid, int flag); }
 	SYS_FEXECVE                  = 492 // { int fexecve(int fd, char **argv, char **envv); }
-	SYS_FSTATAT                  = 493 // { int fstatat(int fd, char *path, struct stat *buf, int flag); }
 	SYS_FUTIMESAT                = 494 // { int futimesat(int fd, char *path, struct timeval *times); }
 	SYS_LINKAT                   = 495 // { int linkat(int fd1, char *path1, int fd2, char *path2, int flag); }
 	SYS_MKDIRAT                  = 496 // { int mkdirat(int fd, char *path, mode_t mode); }
 	SYS_MKFIFOAT                 = 497 // { int mkfifoat(int fd, char *path, mode_t mode); }
-	SYS_MKNODAT                  = 498 // { int mknodat(int fd, char *path, mode_t mode, dev_t dev); }
 	SYS_OPENAT                   = 499 // { int openat(int fd, char *path, int flag, mode_t mode); }
-	SYS_READLINKAT               = 500 // { int readlinkat(int fd, char *path, char *buf, size_t bufsize); }
+	SYS_READLINKAT               = 500 // { ssize_t readlinkat(int fd, char *path, char *buf, size_t bufsize); }
 	SYS_RENAMEAT                 = 501 // { int renameat(int oldfd, char *old, int newfd, char *new); }
 	SYS_SYMLINKAT                = 502 // { int symlinkat(char *path1, int fd, char *path2); }
 	SYS_UNLINKAT                 = 503 // { int unlinkat(int fd, char *path, int flag); }
@@ -391,7 +371,24 @@
 	SYS_PPOLL                    = 545 // { int ppoll(struct pollfd *fds, u_int nfds, const struct timespec *ts, const sigset_t *set); }
 	SYS_FUTIMENS                 = 546 // { int futimens(int fd, struct timespec *times); }
 	SYS_UTIMENSAT                = 547 // { int utimensat(int fd, char *path, struct timespec *times, int flag); }
-	SYS_NUMA_GETAFFINITY         = 548 // { int numa_getaffinity(cpuwhich_t which, id_t id, struct vm_domain_policy_entry *policy); }
-	SYS_NUMA_SETAFFINITY         = 549 // { int numa_setaffinity(cpuwhich_t which, id_t id, const struct vm_domain_policy_entry *policy); }
 	SYS_FDATASYNC                = 550 // { int fdatasync(int fd); }
+	SYS_FSTAT                    = 551 // { int fstat(int fd, struct stat *sb); }
+	SYS_FSTATAT                  = 552 // { int fstatat(int fd, char *path, struct stat *buf, int flag); }
+	SYS_FHSTAT                   = 553 // { int fhstat(const struct fhandle *u_fhp, struct stat *sb); }
+	SYS_GETDIRENTRIES            = 554 // { ssize_t getdirentries(int fd, char *buf, size_t count, off_t *basep); }
+	SYS_STATFS                   = 555 // { int statfs(char *path, struct statfs *buf); }
+	SYS_FSTATFS                  = 556 // { int fstatfs(int fd, struct statfs *buf); }
+	SYS_GETFSSTAT                = 557 // { int getfsstat(struct statfs *buf, long bufsize, int mode); }
+	SYS_FHSTATFS                 = 558 // { int fhstatfs(const struct fhandle *u_fhp, struct statfs *buf); }
+	SYS_MKNODAT                  = 559 // { int mknodat(int fd, char *path, mode_t mode, dev_t dev); }
+	SYS_KEVENT                   = 560 // { int kevent(int fd, struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents, const struct timespec *timeout); }
+	SYS_CPUSET_GETDOMAIN         = 561 // { int cpuset_getdomain(cpulevel_t level, cpuwhich_t which, id_t id, size_t domainsetsize, domainset_t *mask, int *policy); }
+	SYS_CPUSET_SETDOMAIN         = 562 // { int cpuset_setdomain(cpulevel_t level, cpuwhich_t which, id_t id, size_t domainsetsize, domainset_t *mask, int policy); }
+	SYS_GETRANDOM                = 563 // { int getrandom(void *buf, size_t buflen, unsigned int flags); }
+	SYS_GETFHAT                  = 564 // { int getfhat(int fd, char *path, struct fhandle *fhp, int flags); }
+	SYS_FHLINK                   = 565 // { int fhlink(struct fhandle *fhp, const char *to); }
+	SYS_FHLINKAT                 = 566 // { int fhlinkat(struct fhandle *fhp, int tofd, const char *to,); }
+	SYS_FHREADLINK               = 567 // { int fhreadlink(struct fhandle *fhp, char *buf, size_t bufsize); }
+	SYS___SYSCTLBYNAME           = 570 // { int __sysctlbyname(const char *name, size_t namelen, void *old, size_t *oldlenp, void *new, size_t newlen); }
+	SYS_CLOSE_RANGE              = 575 // { int close_range(u_int lowfd, u_int highfd, int flags); }
 )
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_freebsd_riscv64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_freebsd_riscv64.go
new file mode 100644
index 0000000..ee37aaa
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_freebsd_riscv64.go
@@ -0,0 +1,394 @@
+// go run mksysnum.go https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+//go:build riscv64 && freebsd
+// +build riscv64,freebsd
+
+package unix
+
+const (
+	// SYS_NOSYS = 0;  // { int nosys(void); } syscall nosys_args int
+	SYS_EXIT                     = 1   // { void sys_exit(int rval); } exit sys_exit_args void
+	SYS_FORK                     = 2   // { int fork(void); }
+	SYS_READ                     = 3   // { ssize_t read(int fd, void *buf, size_t nbyte); }
+	SYS_WRITE                    = 4   // { ssize_t write(int fd, const void *buf, size_t nbyte); }
+	SYS_OPEN                     = 5   // { int open(char *path, int flags, int mode); }
+	SYS_CLOSE                    = 6   // { int close(int fd); }
+	SYS_WAIT4                    = 7   // { int wait4(int pid, int *status, int options, struct rusage *rusage); }
+	SYS_LINK                     = 9   // { int link(char *path, char *link); }
+	SYS_UNLINK                   = 10  // { int unlink(char *path); }
+	SYS_CHDIR                    = 12  // { int chdir(char *path); }
+	SYS_FCHDIR                   = 13  // { int fchdir(int fd); }
+	SYS_CHMOD                    = 15  // { int chmod(char *path, int mode); }
+	SYS_CHOWN                    = 16  // { int chown(char *path, int uid, int gid); }
+	SYS_BREAK                    = 17  // { caddr_t break(char *nsize); }
+	SYS_GETPID                   = 20  // { pid_t getpid(void); }
+	SYS_MOUNT                    = 21  // { int mount(char *type, char *path, int flags, caddr_t data); }
+	SYS_UNMOUNT                  = 22  // { int unmount(char *path, int flags); }
+	SYS_SETUID                   = 23  // { int setuid(uid_t uid); }
+	SYS_GETUID                   = 24  // { uid_t getuid(void); }
+	SYS_GETEUID                  = 25  // { uid_t geteuid(void); }
+	SYS_PTRACE                   = 26  // { int ptrace(int req, pid_t pid, caddr_t addr, int data); }
+	SYS_RECVMSG                  = 27  // { int recvmsg(int s, struct msghdr *msg, int flags); }
+	SYS_SENDMSG                  = 28  // { int sendmsg(int s, struct msghdr *msg, int flags); }
+	SYS_RECVFROM                 = 29  // { int recvfrom(int s, caddr_t buf, size_t len, int flags, struct sockaddr * __restrict from, __socklen_t * __restrict fromlenaddr); }
+	SYS_ACCEPT                   = 30  // { int accept(int s, struct sockaddr * __restrict name, __socklen_t * __restrict anamelen); }
+	SYS_GETPEERNAME              = 31  // { int getpeername(int fdes, struct sockaddr * __restrict asa, __socklen_t * __restrict alen); }
+	SYS_GETSOCKNAME              = 32  // { int getsockname(int fdes, struct sockaddr * __restrict asa, __socklen_t * __restrict alen); }
+	SYS_ACCESS                   = 33  // { int access(char *path, int amode); }
+	SYS_CHFLAGS                  = 34  // { int chflags(const char *path, u_long flags); }
+	SYS_FCHFLAGS                 = 35  // { int fchflags(int fd, u_long flags); }
+	SYS_SYNC                     = 36  // { int sync(void); }
+	SYS_KILL                     = 37  // { int kill(int pid, int signum); }
+	SYS_GETPPID                  = 39  // { pid_t getppid(void); }
+	SYS_DUP                      = 41  // { int dup(u_int fd); }
+	SYS_GETEGID                  = 43  // { gid_t getegid(void); }
+	SYS_PROFIL                   = 44  // { int profil(caddr_t samples, size_t size, size_t offset, u_int scale); }
+	SYS_KTRACE                   = 45  // { int ktrace(const char *fname, int ops, int facs, int pid); }
+	SYS_GETGID                   = 47  // { gid_t getgid(void); }
+	SYS_GETLOGIN                 = 49  // { int getlogin(char *namebuf, u_int namelen); }
+	SYS_SETLOGIN                 = 50  // { int setlogin(char *namebuf); }
+	SYS_ACCT                     = 51  // { int acct(char *path); }
+	SYS_SIGALTSTACK              = 53  // { int sigaltstack(stack_t *ss, stack_t *oss); }
+	SYS_IOCTL                    = 54  // { int ioctl(int fd, u_long com, caddr_t data); }
+	SYS_REBOOT                   = 55  // { int reboot(int opt); }
+	SYS_REVOKE                   = 56  // { int revoke(char *path); }
+	SYS_SYMLINK                  = 57  // { int symlink(char *path, char *link); }
+	SYS_READLINK                 = 58  // { ssize_t readlink(char *path, char *buf, size_t count); }
+	SYS_EXECVE                   = 59  // { int execve(char *fname, char **argv, char **envv); }
+	SYS_UMASK                    = 60  // { int umask(int newmask); }
+	SYS_CHROOT                   = 61  // { int chroot(char *path); }
+	SYS_MSYNC                    = 65  // { int msync(void *addr, size_t len, int flags); }
+	SYS_VFORK                    = 66  // { int vfork(void); }
+	SYS_SBRK                     = 69  // { int sbrk(int incr); }
+	SYS_SSTK                     = 70  // { int sstk(int incr); }
+	SYS_MUNMAP                   = 73  // { int munmap(void *addr, size_t len); }
+	SYS_MPROTECT                 = 74  // { int mprotect(void *addr, size_t len, int prot); }
+	SYS_MADVISE                  = 75  // { int madvise(void *addr, size_t len, int behav); }
+	SYS_MINCORE                  = 78  // { int mincore(const void *addr, size_t len, char *vec); }
+	SYS_GETGROUPS                = 79  // { int getgroups(u_int gidsetsize, gid_t *gidset); }
+	SYS_SETGROUPS                = 80  // { int setgroups(u_int gidsetsize, gid_t *gidset); }
+	SYS_GETPGRP                  = 81  // { int getpgrp(void); }
+	SYS_SETPGID                  = 82  // { int setpgid(int pid, int pgid); }
+	SYS_SETITIMER                = 83  // { int setitimer(u_int which, struct itimerval *itv, struct itimerval *oitv); }
+	SYS_SWAPON                   = 85  // { int swapon(char *name); }
+	SYS_GETITIMER                = 86  // { int getitimer(u_int which, struct itimerval *itv); }
+	SYS_GETDTABLESIZE            = 89  // { int getdtablesize(void); }
+	SYS_DUP2                     = 90  // { int dup2(u_int from, u_int to); }
+	SYS_FCNTL                    = 92  // { int fcntl(int fd, int cmd, long arg); }
+	SYS_SELECT                   = 93  // { int select(int nd, fd_set *in, fd_set *ou, fd_set *ex, struct timeval *tv); }
+	SYS_FSYNC                    = 95  // { int fsync(int fd); }
+	SYS_SETPRIORITY              = 96  // { int setpriority(int which, int who, int prio); }
+	SYS_SOCKET                   = 97  // { int socket(int domain, int type, int protocol); }
+	SYS_CONNECT                  = 98  // { int connect(int s, caddr_t name, int namelen); }
+	SYS_GETPRIORITY              = 100 // { int getpriority(int which, int who); }
+	SYS_BIND                     = 104 // { int bind(int s, caddr_t name, int namelen); }
+	SYS_SETSOCKOPT               = 105 // { int setsockopt(int s, int level, int name, caddr_t val, int valsize); }
+	SYS_LISTEN                   = 106 // { int listen(int s, int backlog); }
+	SYS_GETTIMEOFDAY             = 116 // { int gettimeofday(struct timeval *tp, struct timezone *tzp); }
+	SYS_GETRUSAGE                = 117 // { int getrusage(int who, struct rusage *rusage); }
+	SYS_GETSOCKOPT               = 118 // { int getsockopt(int s, int level, int name, caddr_t val, int *avalsize); }
+	SYS_READV                    = 120 // { int readv(int fd, struct iovec *iovp, u_int iovcnt); }
+	SYS_WRITEV                   = 121 // { int writev(int fd, struct iovec *iovp, u_int iovcnt); }
+	SYS_SETTIMEOFDAY             = 122 // { int settimeofday(struct timeval *tv, struct timezone *tzp); }
+	SYS_FCHOWN                   = 123 // { int fchown(int fd, int uid, int gid); }
+	SYS_FCHMOD                   = 124 // { int fchmod(int fd, int mode); }
+	SYS_SETREUID                 = 126 // { int setreuid(int ruid, int euid); }
+	SYS_SETREGID                 = 127 // { int setregid(int rgid, int egid); }
+	SYS_RENAME                   = 128 // { int rename(char *from, char *to); }
+	SYS_FLOCK                    = 131 // { int flock(int fd, int how); }
+	SYS_MKFIFO                   = 132 // { int mkfifo(char *path, int mode); }
+	SYS_SENDTO                   = 133 // { int sendto(int s, caddr_t buf, size_t len, int flags, caddr_t to, int tolen); }
+	SYS_SHUTDOWN                 = 134 // { int shutdown(int s, int how); }
+	SYS_SOCKETPAIR               = 135 // { int socketpair(int domain, int type, int protocol, int *rsv); }
+	SYS_MKDIR                    = 136 // { int mkdir(char *path, int mode); }
+	SYS_RMDIR                    = 137 // { int rmdir(char *path); }
+	SYS_UTIMES                   = 138 // { int utimes(char *path, struct timeval *tptr); }
+	SYS_ADJTIME                  = 140 // { int adjtime(struct timeval *delta, struct timeval *olddelta); }
+	SYS_SETSID                   = 147 // { int setsid(void); }
+	SYS_QUOTACTL                 = 148 // { int quotactl(char *path, int cmd, int uid, caddr_t arg); }
+	SYS_NLM_SYSCALL              = 154 // { int nlm_syscall(int debug_level, int grace_period, int addr_count, char **addrs); }
+	SYS_NFSSVC                   = 155 // { int nfssvc(int flag, caddr_t argp); }
+	SYS_LGETFH                   = 160 // { int lgetfh(char *fname, struct fhandle *fhp); }
+	SYS_GETFH                    = 161 // { int getfh(char *fname, struct fhandle *fhp); }
+	SYS_SYSARCH                  = 165 // { int sysarch(int op, char *parms); }
+	SYS_RTPRIO                   = 166 // { int rtprio(int function, pid_t pid, struct rtprio *rtp); }
+	SYS_SEMSYS                   = 169 // { int semsys(int which, int a2, int a3, int a4, int a5); }
+	SYS_MSGSYS                   = 170 // { int msgsys(int which, int a2, int a3, int a4, int a5, int a6); }
+	SYS_SHMSYS                   = 171 // { int shmsys(int which, int a2, int a3, int a4); }
+	SYS_SETFIB                   = 175 // { int setfib(int fibnum); }
+	SYS_NTP_ADJTIME              = 176 // { int ntp_adjtime(struct timex *tp); }
+	SYS_SETGID                   = 181 // { int setgid(gid_t gid); }
+	SYS_SETEGID                  = 182 // { int setegid(gid_t egid); }
+	SYS_SETEUID                  = 183 // { int seteuid(uid_t euid); }
+	SYS_PATHCONF                 = 191 // { int pathconf(char *path, int name); }
+	SYS_FPATHCONF                = 192 // { int fpathconf(int fd, int name); }
+	SYS_GETRLIMIT                = 194 // { int getrlimit(u_int which, struct rlimit *rlp); } getrlimit __getrlimit_args int
+	SYS_SETRLIMIT                = 195 // { int setrlimit(u_int which, struct rlimit *rlp); } setrlimit __setrlimit_args int
+	SYS___SYSCTL                 = 202 // { int __sysctl(int *name, u_int namelen, void *old, size_t *oldlenp, void *new, size_t newlen); } __sysctl sysctl_args int
+	SYS_MLOCK                    = 203 // { int mlock(const void *addr, size_t len); }
+	SYS_MUNLOCK                  = 204 // { int munlock(const void *addr, size_t len); }
+	SYS_UNDELETE                 = 205 // { int undelete(char *path); }
+	SYS_FUTIMES                  = 206 // { int futimes(int fd, struct timeval *tptr); }
+	SYS_GETPGID                  = 207 // { int getpgid(pid_t pid); }
+	SYS_POLL                     = 209 // { int poll(struct pollfd *fds, u_int nfds, int timeout); }
+	SYS_SEMGET                   = 221 // { int semget(key_t key, int nsems, int semflg); }
+	SYS_SEMOP                    = 222 // { int semop(int semid, struct sembuf *sops, size_t nsops); }
+	SYS_MSGGET                   = 225 // { int msgget(key_t key, int msgflg); }
+	SYS_MSGSND                   = 226 // { int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); }
+	SYS_MSGRCV                   = 227 // { ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg); }
+	SYS_SHMAT                    = 228 // { int shmat(int shmid, const void *shmaddr, int shmflg); }
+	SYS_SHMDT                    = 230 // { int shmdt(const void *shmaddr); }
+	SYS_SHMGET                   = 231 // { int shmget(key_t key, size_t size, int shmflg); }
+	SYS_CLOCK_GETTIME            = 232 // { int clock_gettime(clockid_t clock_id, struct timespec *tp); }
+	SYS_CLOCK_SETTIME            = 233 // { int clock_settime(clockid_t clock_id, const struct timespec *tp); }
+	SYS_CLOCK_GETRES             = 234 // { int clock_getres(clockid_t clock_id, struct timespec *tp); }
+	SYS_KTIMER_CREATE            = 235 // { int ktimer_create(clockid_t clock_id, struct sigevent *evp, int *timerid); }
+	SYS_KTIMER_DELETE            = 236 // { int ktimer_delete(int timerid); }
+	SYS_KTIMER_SETTIME           = 237 // { int ktimer_settime(int timerid, int flags, const struct itimerspec *value, struct itimerspec *ovalue); }
+	SYS_KTIMER_GETTIME           = 238 // { int ktimer_gettime(int timerid, struct itimerspec *value); }
+	SYS_KTIMER_GETOVERRUN        = 239 // { int ktimer_getoverrun(int timerid); }
+	SYS_NANOSLEEP                = 240 // { int nanosleep(const struct timespec *rqtp, struct timespec *rmtp); }
+	SYS_FFCLOCK_GETCOUNTER       = 241 // { int ffclock_getcounter(ffcounter *ffcount); }
+	SYS_FFCLOCK_SETESTIMATE      = 242 // { int ffclock_setestimate(struct ffclock_estimate *cest); }
+	SYS_FFCLOCK_GETESTIMATE      = 243 // { int ffclock_getestimate(struct ffclock_estimate *cest); }
+	SYS_CLOCK_NANOSLEEP          = 244 // { int clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *rqtp, struct timespec *rmtp); }
+	SYS_CLOCK_GETCPUCLOCKID2     = 247 // { int clock_getcpuclockid2(id_t id, int which, clockid_t *clock_id); }
+	SYS_NTP_GETTIME              = 248 // { int ntp_gettime(struct ntptimeval *ntvp); }
+	SYS_MINHERIT                 = 250 // { int minherit(void *addr, size_t len, int inherit); }
+	SYS_RFORK                    = 251 // { int rfork(int flags); }
+	SYS_ISSETUGID                = 253 // { int issetugid(void); }
+	SYS_LCHOWN                   = 254 // { int lchown(char *path, int uid, int gid); }
+	SYS_AIO_READ                 = 255 // { int aio_read(struct aiocb *aiocbp); }
+	SYS_AIO_WRITE                = 256 // { int aio_write(struct aiocb *aiocbp); }
+	SYS_LIO_LISTIO               = 257 // { int lio_listio(int mode, struct aiocb* const *acb_list, int nent, struct sigevent *sig); }
+	SYS_LCHMOD                   = 274 // { int lchmod(char *path, mode_t mode); }
+	SYS_LUTIMES                  = 276 // { int lutimes(char *path, struct timeval *tptr); }
+	SYS_PREADV                   = 289 // { ssize_t preadv(int fd, struct iovec *iovp, u_int iovcnt, off_t offset); }
+	SYS_PWRITEV                  = 290 // { ssize_t pwritev(int fd, struct iovec *iovp, u_int iovcnt, off_t offset); }
+	SYS_FHOPEN                   = 298 // { int fhopen(const struct fhandle *u_fhp, int flags); }
+	SYS_MODNEXT                  = 300 // { int modnext(int modid); }
+	SYS_MODSTAT                  = 301 // { int modstat(int modid, struct module_stat* stat); }
+	SYS_MODFNEXT                 = 302 // { int modfnext(int modid); }
+	SYS_MODFIND                  = 303 // { int modfind(const char *name); }
+	SYS_KLDLOAD                  = 304 // { int kldload(const char *file); }
+	SYS_KLDUNLOAD                = 305 // { int kldunload(int fileid); }
+	SYS_KLDFIND                  = 306 // { int kldfind(const char *file); }
+	SYS_KLDNEXT                  = 307 // { int kldnext(int fileid); }
+	SYS_KLDSTAT                  = 308 // { int kldstat(int fileid, struct kld_file_stat *stat); }
+	SYS_KLDFIRSTMOD              = 309 // { int kldfirstmod(int fileid); }
+	SYS_GETSID                   = 310 // { int getsid(pid_t pid); }
+	SYS_SETRESUID                = 311 // { int setresuid(uid_t ruid, uid_t euid, uid_t suid); }
+	SYS_SETRESGID                = 312 // { int setresgid(gid_t rgid, gid_t egid, gid_t sgid); }
+	SYS_AIO_RETURN               = 314 // { ssize_t aio_return(struct aiocb *aiocbp); }
+	SYS_AIO_SUSPEND              = 315 // { int aio_suspend(struct aiocb * const * aiocbp, int nent, const struct timespec *timeout); }
+	SYS_AIO_CANCEL               = 316 // { int aio_cancel(int fd, struct aiocb *aiocbp); }
+	SYS_AIO_ERROR                = 317 // { int aio_error(struct aiocb *aiocbp); }
+	SYS_YIELD                    = 321 // { int yield(void); }
+	SYS_MLOCKALL                 = 324 // { int mlockall(int how); }
+	SYS_MUNLOCKALL               = 325 // { int munlockall(void); }
+	SYS___GETCWD                 = 326 // { int __getcwd(char *buf, size_t buflen); }
+	SYS_SCHED_SETPARAM           = 327 // { int sched_setparam (pid_t pid, const struct sched_param *param); }
+	SYS_SCHED_GETPARAM           = 328 // { int sched_getparam (pid_t pid, struct sched_param *param); }
+	SYS_SCHED_SETSCHEDULER       = 329 // { int sched_setscheduler (pid_t pid, int policy, const struct sched_param *param); }
+	SYS_SCHED_GETSCHEDULER       = 330 // { int sched_getscheduler (pid_t pid); }
+	SYS_SCHED_YIELD              = 331 // { int sched_yield (void); }
+	SYS_SCHED_GET_PRIORITY_MAX   = 332 // { int sched_get_priority_max (int policy); }
+	SYS_SCHED_GET_PRIORITY_MIN   = 333 // { int sched_get_priority_min (int policy); }
+	SYS_SCHED_RR_GET_INTERVAL    = 334 // { int sched_rr_get_interval (pid_t pid, struct timespec *interval); }
+	SYS_UTRACE                   = 335 // { int utrace(const void *addr, size_t len); }
+	SYS_KLDSYM                   = 337 // { int kldsym(int fileid, int cmd, void *data); }
+	SYS_JAIL                     = 338 // { int jail(struct jail *jail); }
+	SYS_SIGPROCMASK              = 340 // { int sigprocmask(int how, const sigset_t *set, sigset_t *oset); }
+	SYS_SIGSUSPEND               = 341 // { int sigsuspend(const sigset_t *sigmask); }
+	SYS_SIGPENDING               = 343 // { int sigpending(sigset_t *set); }
+	SYS_SIGTIMEDWAIT             = 345 // { int sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec *timeout); }
+	SYS_SIGWAITINFO              = 346 // { int sigwaitinfo(const sigset_t *set, siginfo_t *info); }
+	SYS___ACL_GET_FILE           = 347 // { int __acl_get_file(const char *path, acl_type_t type, struct acl *aclp); }
+	SYS___ACL_SET_FILE           = 348 // { int __acl_set_file(const char *path, acl_type_t type, struct acl *aclp); }
+	SYS___ACL_GET_FD             = 349 // { int __acl_get_fd(int filedes, acl_type_t type, struct acl *aclp); }
+	SYS___ACL_SET_FD             = 350 // { int __acl_set_fd(int filedes, acl_type_t type, struct acl *aclp); }
+	SYS___ACL_DELETE_FILE        = 351 // { int __acl_delete_file(const char *path, acl_type_t type); }
+	SYS___ACL_DELETE_FD          = 352 // { int __acl_delete_fd(int filedes, acl_type_t type); }
+	SYS___ACL_ACLCHECK_FILE      = 353 // { int __acl_aclcheck_file(const char *path, acl_type_t type, struct acl *aclp); }
+	SYS___ACL_ACLCHECK_FD        = 354 // { int __acl_aclcheck_fd(int filedes, acl_type_t type, struct acl *aclp); }
+	SYS_EXTATTRCTL               = 355 // { int extattrctl(const char *path, int cmd, const char *filename, int attrnamespace, const char *attrname); }
+	SYS_EXTATTR_SET_FILE         = 356 // { ssize_t extattr_set_file(const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
+	SYS_EXTATTR_GET_FILE         = 357 // { ssize_t extattr_get_file(const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
+	SYS_EXTATTR_DELETE_FILE      = 358 // { int extattr_delete_file(const char *path, int attrnamespace, const char *attrname); }
+	SYS_AIO_WAITCOMPLETE         = 359 // { ssize_t aio_waitcomplete(struct aiocb **aiocbp, struct timespec *timeout); }
+	SYS_GETRESUID                = 360 // { int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); }
+	SYS_GETRESGID                = 361 // { int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); }
+	SYS_KQUEUE                   = 362 // { int kqueue(void); }
+	SYS_EXTATTR_SET_FD           = 371 // { ssize_t extattr_set_fd(int fd, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
+	SYS_EXTATTR_GET_FD           = 372 // { ssize_t extattr_get_fd(int fd, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
+	SYS_EXTATTR_DELETE_FD        = 373 // { int extattr_delete_fd(int fd, int attrnamespace, const char *attrname); }
+	SYS___SETUGID                = 374 // { int __setugid(int flag); }
+	SYS_EACCESS                  = 376 // { int eaccess(char *path, int amode); }
+	SYS_NMOUNT                   = 378 // { int nmount(struct iovec *iovp, unsigned int iovcnt, int flags); }
+	SYS___MAC_GET_PROC           = 384 // { int __mac_get_proc(struct mac *mac_p); }
+	SYS___MAC_SET_PROC           = 385 // { int __mac_set_proc(struct mac *mac_p); }
+	SYS___MAC_GET_FD             = 386 // { int __mac_get_fd(int fd, struct mac *mac_p); }
+	SYS___MAC_GET_FILE           = 387 // { int __mac_get_file(const char *path_p, struct mac *mac_p); }
+	SYS___MAC_SET_FD             = 388 // { int __mac_set_fd(int fd, struct mac *mac_p); }
+	SYS___MAC_SET_FILE           = 389 // { int __mac_set_file(const char *path_p, struct mac *mac_p); }
+	SYS_KENV                     = 390 // { int kenv(int what, const char *name, char *value, int len); }
+	SYS_LCHFLAGS                 = 391 // { int lchflags(const char *path, u_long flags); }
+	SYS_UUIDGEN                  = 392 // { int uuidgen(struct uuid *store, int count); }
+	SYS_SENDFILE                 = 393 // { int sendfile(int fd, int s, off_t offset, size_t nbytes, struct sf_hdtr *hdtr, off_t *sbytes, int flags); }
+	SYS_MAC_SYSCALL              = 394 // { int mac_syscall(const char *policy, int call, void *arg); }
+	SYS_KSEM_CLOSE               = 400 // { int ksem_close(semid_t id); }
+	SYS_KSEM_POST                = 401 // { int ksem_post(semid_t id); }
+	SYS_KSEM_WAIT                = 402 // { int ksem_wait(semid_t id); }
+	SYS_KSEM_TRYWAIT             = 403 // { int ksem_trywait(semid_t id); }
+	SYS_KSEM_INIT                = 404 // { int ksem_init(semid_t *idp, unsigned int value); }
+	SYS_KSEM_OPEN                = 405 // { int ksem_open(semid_t *idp, const char *name, int oflag, mode_t mode, unsigned int value); }
+	SYS_KSEM_UNLINK              = 406 // { int ksem_unlink(const char *name); }
+	SYS_KSEM_GETVALUE            = 407 // { int ksem_getvalue(semid_t id, int *val); }
+	SYS_KSEM_DESTROY             = 408 // { int ksem_destroy(semid_t id); }
+	SYS___MAC_GET_PID            = 409 // { int __mac_get_pid(pid_t pid, struct mac *mac_p); }
+	SYS___MAC_GET_LINK           = 410 // { int __mac_get_link(const char *path_p, struct mac *mac_p); }
+	SYS___MAC_SET_LINK           = 411 // { int __mac_set_link(const char *path_p, struct mac *mac_p); }
+	SYS_EXTATTR_SET_LINK         = 412 // { ssize_t extattr_set_link(const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
+	SYS_EXTATTR_GET_LINK         = 413 // { ssize_t extattr_get_link(const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
+	SYS_EXTATTR_DELETE_LINK      = 414 // { int extattr_delete_link(const char *path, int attrnamespace, const char *attrname); }
+	SYS___MAC_EXECVE             = 415 // { int __mac_execve(char *fname, char **argv, char **envv, struct mac *mac_p); }
+	SYS_SIGACTION                = 416 // { int sigaction(int sig, const struct sigaction *act, struct sigaction *oact); }
+	SYS_SIGRETURN                = 417 // { int sigreturn(const struct __ucontext *sigcntxp); }
+	SYS_GETCONTEXT               = 421 // { int getcontext(struct __ucontext *ucp); }
+	SYS_SETCONTEXT               = 422 // { int setcontext(const struct __ucontext *ucp); }
+	SYS_SWAPCONTEXT              = 423 // { int swapcontext(struct __ucontext *oucp, const struct __ucontext *ucp); }
+	SYS_SWAPOFF                  = 424 // { int swapoff(const char *name); }
+	SYS___ACL_GET_LINK           = 425 // { int __acl_get_link(const char *path, acl_type_t type, struct acl *aclp); }
+	SYS___ACL_SET_LINK           = 426 // { int __acl_set_link(const char *path, acl_type_t type, struct acl *aclp); }
+	SYS___ACL_DELETE_LINK        = 427 // { int __acl_delete_link(const char *path, acl_type_t type); }
+	SYS___ACL_ACLCHECK_LINK      = 428 // { int __acl_aclcheck_link(const char *path, acl_type_t type, struct acl *aclp); }
+	SYS_SIGWAIT                  = 429 // { int sigwait(const sigset_t *set, int *sig); }
+	SYS_THR_CREATE               = 430 // { int thr_create(ucontext_t *ctx, long *id, int flags); }
+	SYS_THR_EXIT                 = 431 // { void thr_exit(long *state); }
+	SYS_THR_SELF                 = 432 // { int thr_self(long *id); }
+	SYS_THR_KILL                 = 433 // { int thr_kill(long id, int sig); }
+	SYS_JAIL_ATTACH              = 436 // { int jail_attach(int jid); }
+	SYS_EXTATTR_LIST_FD          = 437 // { ssize_t extattr_list_fd(int fd, int attrnamespace, void *data, size_t nbytes); }
+	SYS_EXTATTR_LIST_FILE        = 438 // { ssize_t extattr_list_file(const char *path, int attrnamespace, void *data, size_t nbytes); }
+	SYS_EXTATTR_LIST_LINK        = 439 // { ssize_t extattr_list_link(const char *path, int attrnamespace, void *data, size_t nbytes); }
+	SYS_KSEM_TIMEDWAIT           = 441 // { int ksem_timedwait(semid_t id, const struct timespec *abstime); }
+	SYS_THR_SUSPEND              = 442 // { int thr_suspend(const struct timespec *timeout); }
+	SYS_THR_WAKE                 = 443 // { int thr_wake(long id); }
+	SYS_KLDUNLOADF               = 444 // { int kldunloadf(int fileid, int flags); }
+	SYS_AUDIT                    = 445 // { int audit(const void *record, u_int length); }
+	SYS_AUDITON                  = 446 // { int auditon(int cmd, void *data, u_int length); }
+	SYS_GETAUID                  = 447 // { int getauid(uid_t *auid); }
+	SYS_SETAUID                  = 448 // { int setauid(uid_t *auid); }
+	SYS_GETAUDIT                 = 449 // { int getaudit(struct auditinfo *auditinfo); }
+	SYS_SETAUDIT                 = 450 // { int setaudit(struct auditinfo *auditinfo); }
+	SYS_GETAUDIT_ADDR            = 451 // { int getaudit_addr(struct auditinfo_addr *auditinfo_addr, u_int length); }
+	SYS_SETAUDIT_ADDR            = 452 // { int setaudit_addr(struct auditinfo_addr *auditinfo_addr, u_int length); }
+	SYS_AUDITCTL                 = 453 // { int auditctl(char *path); }
+	SYS__UMTX_OP                 = 454 // { int _umtx_op(void *obj, int op, u_long val, void *uaddr1, void *uaddr2); }
+	SYS_THR_NEW                  = 455 // { int thr_new(struct thr_param *param, int param_size); }
+	SYS_SIGQUEUE                 = 456 // { int sigqueue(pid_t pid, int signum, void *value); }
+	SYS_KMQ_OPEN                 = 457 // { int kmq_open(const char *path, int flags, mode_t mode, const struct mq_attr *attr); }
+	SYS_KMQ_SETATTR              = 458 // { int kmq_setattr(int mqd, const struct mq_attr *attr, struct mq_attr *oattr); }
+	SYS_KMQ_TIMEDRECEIVE         = 459 // { int kmq_timedreceive(int mqd, char *msg_ptr, size_t msg_len, unsigned *msg_prio, const struct timespec *abs_timeout); }
+	SYS_KMQ_TIMEDSEND            = 460 // { int kmq_timedsend(int mqd, const char *msg_ptr, size_t msg_len, unsigned msg_prio, const struct timespec *abs_timeout); }
+	SYS_KMQ_NOTIFY               = 461 // { int kmq_notify(int mqd, const struct sigevent *sigev); }
+	SYS_KMQ_UNLINK               = 462 // { int kmq_unlink(const char *path); }
+	SYS_ABORT2                   = 463 // { int abort2(const char *why, int nargs, void **args); }
+	SYS_THR_SET_NAME             = 464 // { int thr_set_name(long id, const char *name); }
+	SYS_AIO_FSYNC                = 465 // { int aio_fsync(int op, struct aiocb *aiocbp); }
+	SYS_RTPRIO_THREAD            = 466 // { int rtprio_thread(int function, lwpid_t lwpid, struct rtprio *rtp); }
+	SYS_SCTP_PEELOFF             = 471 // { int sctp_peeloff(int sd, uint32_t name); }
+	SYS_SCTP_GENERIC_SENDMSG     = 472 // { int sctp_generic_sendmsg(int sd, caddr_t msg, int mlen, caddr_t to, __socklen_t tolen, struct sctp_sndrcvinfo *sinfo, int flags); }
+	SYS_SCTP_GENERIC_SENDMSG_IOV = 473 // { int sctp_generic_sendmsg_iov(int sd, struct iovec *iov, int iovlen, caddr_t to, __socklen_t tolen, struct sctp_sndrcvinfo *sinfo, int flags); }
+	SYS_SCTP_GENERIC_RECVMSG     = 474 // { int sctp_generic_recvmsg(int sd, struct iovec *iov, int iovlen, struct sockaddr *from, __socklen_t *fromlenaddr, struct sctp_sndrcvinfo *sinfo, int *msg_flags); }
+	SYS_PREAD                    = 475 // { ssize_t pread(int fd, void *buf, size_t nbyte, off_t offset); }
+	SYS_PWRITE                   = 476 // { ssize_t pwrite(int fd, const void *buf, size_t nbyte, off_t offset); }
+	SYS_MMAP                     = 477 // { caddr_t mmap(caddr_t addr, size_t len, int prot, int flags, int fd, off_t pos); }
+	SYS_LSEEK                    = 478 // { off_t lseek(int fd, off_t offset, int whence); }
+	SYS_TRUNCATE                 = 479 // { int truncate(char *path, off_t length); }
+	SYS_FTRUNCATE                = 480 // { int ftruncate(int fd, off_t length); }
+	SYS_THR_KILL2                = 481 // { int thr_kill2(pid_t pid, long id, int sig); }
+	SYS_SHM_OPEN                 = 482 // { int shm_open(const char *path, int flags, mode_t mode); }
+	SYS_SHM_UNLINK               = 483 // { int shm_unlink(const char *path); }
+	SYS_CPUSET                   = 484 // { int cpuset(cpusetid_t *setid); }
+	SYS_CPUSET_SETID             = 485 // { int cpuset_setid(cpuwhich_t which, id_t id, cpusetid_t setid); }
+	SYS_CPUSET_GETID             = 486 // { int cpuset_getid(cpulevel_t level, cpuwhich_t which, id_t id, cpusetid_t *setid); }
+	SYS_CPUSET_GETAFFINITY       = 487 // { int cpuset_getaffinity(cpulevel_t level, cpuwhich_t which, id_t id, size_t cpusetsize, cpuset_t *mask); }
+	SYS_CPUSET_SETAFFINITY       = 488 // { int cpuset_setaffinity(cpulevel_t level, cpuwhich_t which, id_t id, size_t cpusetsize, const cpuset_t *mask); }
+	SYS_FACCESSAT                = 489 // { int faccessat(int fd, char *path, int amode, int flag); }
+	SYS_FCHMODAT                 = 490 // { int fchmodat(int fd, char *path, mode_t mode, int flag); }
+	SYS_FCHOWNAT                 = 491 // { int fchownat(int fd, char *path, uid_t uid, gid_t gid, int flag); }
+	SYS_FEXECVE                  = 492 // { int fexecve(int fd, char **argv, char **envv); }
+	SYS_FUTIMESAT                = 494 // { int futimesat(int fd, char *path, struct timeval *times); }
+	SYS_LINKAT                   = 495 // { int linkat(int fd1, char *path1, int fd2, char *path2, int flag); }
+	SYS_MKDIRAT                  = 496 // { int mkdirat(int fd, char *path, mode_t mode); }
+	SYS_MKFIFOAT                 = 497 // { int mkfifoat(int fd, char *path, mode_t mode); }
+	SYS_OPENAT                   = 499 // { int openat(int fd, char *path, int flag, mode_t mode); }
+	SYS_READLINKAT               = 500 // { ssize_t readlinkat(int fd, char *path, char *buf, size_t bufsize); }
+	SYS_RENAMEAT                 = 501 // { int renameat(int oldfd, char *old, int newfd, char *new); }
+	SYS_SYMLINKAT                = 502 // { int symlinkat(char *path1, int fd, char *path2); }
+	SYS_UNLINKAT                 = 503 // { int unlinkat(int fd, char *path, int flag); }
+	SYS_POSIX_OPENPT             = 504 // { int posix_openpt(int flags); }
+	SYS_GSSD_SYSCALL             = 505 // { int gssd_syscall(char *path); }
+	SYS_JAIL_GET                 = 506 // { int jail_get(struct iovec *iovp, unsigned int iovcnt, int flags); }
+	SYS_JAIL_SET                 = 507 // { int jail_set(struct iovec *iovp, unsigned int iovcnt, int flags); }
+	SYS_JAIL_REMOVE              = 508 // { int jail_remove(int jid); }
+	SYS_CLOSEFROM                = 509 // { int closefrom(int lowfd); }
+	SYS___SEMCTL                 = 510 // { int __semctl(int semid, int semnum, int cmd, union semun *arg); }
+	SYS_MSGCTL                   = 511 // { int msgctl(int msqid, int cmd, struct msqid_ds *buf); }
+	SYS_SHMCTL                   = 512 // { int shmctl(int shmid, int cmd, struct shmid_ds *buf); }
+	SYS_LPATHCONF                = 513 // { int lpathconf(char *path, int name); }
+	SYS___CAP_RIGHTS_GET         = 515 // { int __cap_rights_get(int version, int fd, cap_rights_t *rightsp); }
+	SYS_CAP_ENTER                = 516 // { int cap_enter(void); }
+	SYS_CAP_GETMODE              = 517 // { int cap_getmode(u_int *modep); }
+	SYS_PDFORK                   = 518 // { int pdfork(int *fdp, int flags); }
+	SYS_PDKILL                   = 519 // { int pdkill(int fd, int signum); }
+	SYS_PDGETPID                 = 520 // { int pdgetpid(int fd, pid_t *pidp); }
+	SYS_PSELECT                  = 522 // { int pselect(int nd, fd_set *in, fd_set *ou, fd_set *ex, const struct timespec *ts, const sigset_t *sm); }
+	SYS_GETLOGINCLASS            = 523 // { int getloginclass(char *namebuf, size_t namelen); }
+	SYS_SETLOGINCLASS            = 524 // { int setloginclass(const char *namebuf); }
+	SYS_RCTL_GET_RACCT           = 525 // { int rctl_get_racct(const void *inbufp, size_t inbuflen, void *outbufp, size_t outbuflen); }
+	SYS_RCTL_GET_RULES           = 526 // { int rctl_get_rules(const void *inbufp, size_t inbuflen, void *outbufp, size_t outbuflen); }
+	SYS_RCTL_GET_LIMITS          = 527 // { int rctl_get_limits(const void *inbufp, size_t inbuflen, void *outbufp, size_t outbuflen); }
+	SYS_RCTL_ADD_RULE            = 528 // { int rctl_add_rule(const void *inbufp, size_t inbuflen, void *outbufp, size_t outbuflen); }
+	SYS_RCTL_REMOVE_RULE         = 529 // { int rctl_remove_rule(const void *inbufp, size_t inbuflen, void *outbufp, size_t outbuflen); }
+	SYS_POSIX_FALLOCATE          = 530 // { int posix_fallocate(int fd, off_t offset, off_t len); }
+	SYS_POSIX_FADVISE            = 531 // { int posix_fadvise(int fd, off_t offset, off_t len, int advice); }
+	SYS_WAIT6                    = 532 // { int wait6(idtype_t idtype, id_t id, int *status, int options, struct __wrusage *wrusage, siginfo_t *info); }
+	SYS_CAP_RIGHTS_LIMIT         = 533 // { int cap_rights_limit(int fd, cap_rights_t *rightsp); }
+	SYS_CAP_IOCTLS_LIMIT         = 534 // { int cap_ioctls_limit(int fd, const u_long *cmds, size_t ncmds); }
+	SYS_CAP_IOCTLS_GET           = 535 // { ssize_t cap_ioctls_get(int fd, u_long *cmds, size_t maxcmds); }
+	SYS_CAP_FCNTLS_LIMIT         = 536 // { int cap_fcntls_limit(int fd, uint32_t fcntlrights); }
+	SYS_CAP_FCNTLS_GET           = 537 // { int cap_fcntls_get(int fd, uint32_t *fcntlrightsp); }
+	SYS_BINDAT                   = 538 // { int bindat(int fd, int s, caddr_t name, int namelen); }
+	SYS_CONNECTAT                = 539 // { int connectat(int fd, int s, caddr_t name, int namelen); }
+	SYS_CHFLAGSAT                = 540 // { int chflagsat(int fd, const char *path, u_long flags, int atflag); }
+	SYS_ACCEPT4                  = 541 // { int accept4(int s, struct sockaddr * __restrict name, __socklen_t * __restrict anamelen, int flags); }
+	SYS_PIPE2                    = 542 // { int pipe2(int *fildes, int flags); }
+	SYS_AIO_MLOCK                = 543 // { int aio_mlock(struct aiocb *aiocbp); }
+	SYS_PROCCTL                  = 544 // { int procctl(idtype_t idtype, id_t id, int com, void *data); }
+	SYS_PPOLL                    = 545 // { int ppoll(struct pollfd *fds, u_int nfds, const struct timespec *ts, const sigset_t *set); }
+	SYS_FUTIMENS                 = 546 // { int futimens(int fd, struct timespec *times); }
+	SYS_UTIMENSAT                = 547 // { int utimensat(int fd, char *path, struct timespec *times, int flag); }
+	SYS_FDATASYNC                = 550 // { int fdatasync(int fd); }
+	SYS_FSTAT                    = 551 // { int fstat(int fd, struct stat *sb); }
+	SYS_FSTATAT                  = 552 // { int fstatat(int fd, char *path, struct stat *buf, int flag); }
+	SYS_FHSTAT                   = 553 // { int fhstat(const struct fhandle *u_fhp, struct stat *sb); }
+	SYS_GETDIRENTRIES            = 554 // { ssize_t getdirentries(int fd, char *buf, size_t count, off_t *basep); }
+	SYS_STATFS                   = 555 // { int statfs(char *path, struct statfs *buf); }
+	SYS_FSTATFS                  = 556 // { int fstatfs(int fd, struct statfs *buf); }
+	SYS_GETFSSTAT                = 557 // { int getfsstat(struct statfs *buf, long bufsize, int mode); }
+	SYS_FHSTATFS                 = 558 // { int fhstatfs(const struct fhandle *u_fhp, struct statfs *buf); }
+	SYS_MKNODAT                  = 559 // { int mknodat(int fd, char *path, mode_t mode, dev_t dev); }
+	SYS_KEVENT                   = 560 // { int kevent(int fd, struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents, const struct timespec *timeout); }
+	SYS_CPUSET_GETDOMAIN         = 561 // { int cpuset_getdomain(cpulevel_t level, cpuwhich_t which, id_t id, size_t domainsetsize, domainset_t *mask, int *policy); }
+	SYS_CPUSET_SETDOMAIN         = 562 // { int cpuset_setdomain(cpulevel_t level, cpuwhich_t which, id_t id, size_t domainsetsize, domainset_t *mask, int policy); }
+	SYS_GETRANDOM                = 563 // { int getrandom(void *buf, size_t buflen, unsigned int flags); }
+	SYS_GETFHAT                  = 564 // { int getfhat(int fd, char *path, struct fhandle *fhp, int flags); }
+	SYS_FHLINK                   = 565 // { int fhlink(struct fhandle *fhp, const char *to); }
+	SYS_FHLINKAT                 = 566 // { int fhlinkat(struct fhandle *fhp, int tofd, const char *to,); }
+	SYS_FHREADLINK               = 567 // { int fhreadlink(struct fhandle *fhp, char *buf, size_t bufsize); }
+	SYS___SYSCTLBYNAME           = 570 // { int __sysctlbyname(const char *name, size_t namelen, void *old, size_t *oldlenp, void *new, size_t newlen); }
+	SYS_CLOSE_RANGE              = 575 // { int close_range(u_int lowfd, u_int highfd, int flags); }
+)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go
index 62192e1..c9c4ad0 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go
@@ -1,4 +1,4 @@
-// go run linux/mksysnum.go -Wall -Werror -static -I/tmp/include -m32 /tmp/include/asm/unistd.h
+// go run linux/mksysnum.go -Wall -Werror -static -I/tmp/386/include -m32 /tmp/386/include/asm/unistd.h
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build 386 && linux
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go
index 490aab5..12ff341 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go
@@ -1,4 +1,4 @@
-// go run linux/mksysnum.go -Wall -Werror -static -I/tmp/include -m64 /tmp/include/asm/unistd.h
+// go run linux/mksysnum.go -Wall -Werror -static -I/tmp/amd64/include -m64 /tmp/amd64/include/asm/unistd.h
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build amd64 && linux
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go
index aca17b6..c3fb5e7 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go
@@ -1,4 +1,4 @@
-// go run linux/mksysnum.go -Wall -Werror -static -I/tmp/include /tmp/include/asm/unistd.h
+// go run linux/mksysnum.go -Wall -Werror -static -I/tmp/arm/include /tmp/arm/include/asm/unistd.h
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build arm && linux
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go
index 54b4dfa..358c847 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go
@@ -1,4 +1,4 @@
-// go run linux/mksysnum.go -Wall -Werror -static -I/tmp/include -fsigned-char /tmp/include/asm/unistd.h
+// go run linux/mksysnum.go -Wall -Werror -static -I/tmp/arm64/include -fsigned-char /tmp/arm64/include/asm/unistd.h
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build arm64 && linux
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go
index e443f9a..81c4849 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go
@@ -1,4 +1,4 @@
-// go run linux/mksysnum.go -Wall -Werror -static -I/tmp/include /tmp/include/asm/unistd.h
+// go run linux/mksysnum.go -Wall -Werror -static -I/tmp/loong64/include /tmp/loong64/include/asm/unistd.h
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build loong64 && linux
@@ -85,8 +85,6 @@
 	SYS_SPLICE                  = 76
 	SYS_TEE                     = 77
 	SYS_READLINKAT              = 78
-	SYS_FSTATAT                 = 79
-	SYS_FSTAT                   = 80
 	SYS_SYNC                    = 81
 	SYS_FSYNC                   = 82
 	SYS_FDATASYNC               = 83
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go
index 65a99ef..202a57e 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go
@@ -1,4 +1,4 @@
-// go run linux/mksysnum.go -Wall -Werror -static -I/tmp/include /tmp/include/asm/unistd.h
+// go run linux/mksysnum.go -Wall -Werror -static -I/tmp/mips/include /tmp/mips/include/asm/unistd.h
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build mips && linux
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go
index 841c8a6..1fbceb5 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go
@@ -1,4 +1,4 @@
-// go run linux/mksysnum.go -Wall -Werror -static -I/tmp/include /tmp/include/asm/unistd.h
+// go run linux/mksysnum.go -Wall -Werror -static -I/tmp/mips64/include /tmp/mips64/include/asm/unistd.h
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build mips64 && linux
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go
index e26a7c7..b4ffb7a 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go
@@ -1,4 +1,4 @@
-// go run linux/mksysnum.go -Wall -Werror -static -I/tmp/include /tmp/include/asm/unistd.h
+// go run linux/mksysnum.go -Wall -Werror -static -I/tmp/mips64le/include /tmp/mips64le/include/asm/unistd.h
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build mips64le && linux
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go
index 2644726..867985f 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go
@@ -1,4 +1,4 @@
-// go run linux/mksysnum.go -Wall -Werror -static -I/tmp/include /tmp/include/asm/unistd.h
+// go run linux/mksysnum.go -Wall -Werror -static -I/tmp/mipsle/include /tmp/mipsle/include/asm/unistd.h
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build mipsle && linux
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go
index 26aefc1..a8cce69 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go
@@ -1,4 +1,4 @@
-// go run linux/mksysnum.go -Wall -Werror -static -I/tmp/include /tmp/include/asm/unistd.h
+// go run linux/mksysnum.go -Wall -Werror -static -I/tmp/ppc/include /tmp/ppc/include/asm/unistd.h
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build ppc && linux
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go
index 8d4cd9d..d44c5b3 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go
@@ -1,4 +1,4 @@
-// go run linux/mksysnum.go -Wall -Werror -static -I/tmp/include /tmp/include/asm/unistd.h
+// go run linux/mksysnum.go -Wall -Werror -static -I/tmp/ppc64/include /tmp/ppc64/include/asm/unistd.h
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build ppc64 && linux
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go
index 3b405d1..4214dd9 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go
@@ -1,4 +1,4 @@
-// go run linux/mksysnum.go -Wall -Werror -static -I/tmp/include /tmp/include/asm/unistd.h
+// go run linux/mksysnum.go -Wall -Werror -static -I/tmp/ppc64le/include /tmp/ppc64le/include/asm/unistd.h
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build ppc64le && linux
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go
index c3a5af8..3e594a8 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go
@@ -1,4 +1,4 @@
-// go run linux/mksysnum.go -Wall -Werror -static -I/tmp/include /tmp/include/asm/unistd.h
+// go run linux/mksysnum.go -Wall -Werror -static -I/tmp/riscv64/include /tmp/riscv64/include/asm/unistd.h
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build riscv64 && linux
@@ -309,6 +309,7 @@
 	SYS_LANDLOCK_CREATE_RULESET = 444
 	SYS_LANDLOCK_ADD_RULE       = 445
 	SYS_LANDLOCK_RESTRICT_SELF  = 446
+	SYS_MEMFD_SECRET            = 447
 	SYS_PROCESS_MRELEASE        = 448
 	SYS_FUTEX_WAITV             = 449
 	SYS_SET_MEMPOLICY_HOME_NODE = 450
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go
index 8ffa664..7ea4652 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go
@@ -1,4 +1,4 @@
-// go run linux/mksysnum.go -Wall -Werror -static -I/tmp/include -fsigned-char /tmp/include/asm/unistd.h
+// go run linux/mksysnum.go -Wall -Werror -static -I/tmp/s390x/include -fsigned-char /tmp/s390x/include/asm/unistd.h
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build s390x && linux
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go
index 6a39640..92f628e 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go
@@ -1,4 +1,4 @@
-// go run linux/mksysnum.go -Wall -Werror -static -I/tmp/include /tmp/include/asm/unistd.h
+// go run linux/mksysnum.go -Wall -Werror -static -I/tmp/sparc64/include /tmp/sparc64/include/asm/unistd.h
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build sparc64 && linux
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_386.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_386.go
index 817edbf..5977338 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_386.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_386.go
@@ -6,6 +6,7 @@
 
 package unix
 
+// Deprecated: Use libc wrappers instead of direct syscalls.
 const (
 	SYS_EXIT           = 1   // { void sys_exit(int rval); }
 	SYS_FORK           = 2   // { int sys_fork(void); }
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_amd64.go
index ea45361..16af291 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_amd64.go
@@ -6,6 +6,7 @@
 
 package unix
 
+// Deprecated: Use libc wrappers instead of direct syscalls.
 const (
 	SYS_EXIT           = 1   // { void sys_exit(int rval); }
 	SYS_FORK           = 2   // { int sys_fork(void); }
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm.go
index 467971e..f59b18a 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm.go
@@ -6,6 +6,7 @@
 
 package unix
 
+// Deprecated: Use libc wrappers instead of direct syscalls.
 const (
 	SYS_EXIT           = 1   // { void sys_exit(int rval); }
 	SYS_FORK           = 2   // { int sys_fork(void); }
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm64.go
index 32eec5e..721ef59 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_arm64.go
@@ -6,6 +6,7 @@
 
 package unix
 
+// Deprecated: Use libc wrappers instead of direct syscalls.
 const (
 	SYS_EXIT           = 1   // { void sys_exit(int rval); }
 	SYS_FORK           = 2   // { int sys_fork(void); }
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_ppc64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_ppc64.go
new file mode 100644
index 0000000..f258cfa
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_ppc64.go
@@ -0,0 +1,218 @@
+// go run mksysnum.go https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+//go:build ppc64 && openbsd
+// +build ppc64,openbsd
+
+package unix
+
+const (
+	SYS_EXIT           = 1   // { void sys_exit(int rval); }
+	SYS_FORK           = 2   // { int sys_fork(void); }
+	SYS_READ           = 3   // { ssize_t sys_read(int fd, void *buf, size_t nbyte); }
+	SYS_WRITE          = 4   // { ssize_t sys_write(int fd, const void *buf, size_t nbyte); }
+	SYS_OPEN           = 5   // { int sys_open(const char *path, int flags, ... mode_t mode); }
+	SYS_CLOSE          = 6   // { int sys_close(int fd); }
+	SYS_GETENTROPY     = 7   // { int sys_getentropy(void *buf, size_t nbyte); }
+	SYS___TFORK        = 8   // { int sys___tfork(const struct __tfork *param, size_t psize); }
+	SYS_LINK           = 9   // { int sys_link(const char *path, const char *link); }
+	SYS_UNLINK         = 10  // { int sys_unlink(const char *path); }
+	SYS_WAIT4          = 11  // { pid_t sys_wait4(pid_t pid, int *status, int options, struct rusage *rusage); }
+	SYS_CHDIR          = 12  // { int sys_chdir(const char *path); }
+	SYS_FCHDIR         = 13  // { int sys_fchdir(int fd); }
+	SYS_MKNOD          = 14  // { int sys_mknod(const char *path, mode_t mode, dev_t dev); }
+	SYS_CHMOD          = 15  // { int sys_chmod(const char *path, mode_t mode); }
+	SYS_CHOWN          = 16  // { int sys_chown(const char *path, uid_t uid, gid_t gid); }
+	SYS_OBREAK         = 17  // { int sys_obreak(char *nsize); } break
+	SYS_GETDTABLECOUNT = 18  // { int sys_getdtablecount(void); }
+	SYS_GETRUSAGE      = 19  // { int sys_getrusage(int who, struct rusage *rusage); }
+	SYS_GETPID         = 20  // { pid_t sys_getpid(void); }
+	SYS_MOUNT          = 21  // { int sys_mount(const char *type, const char *path, int flags, void *data); }
+	SYS_UNMOUNT        = 22  // { int sys_unmount(const char *path, int flags); }
+	SYS_SETUID         = 23  // { int sys_setuid(uid_t uid); }
+	SYS_GETUID         = 24  // { uid_t sys_getuid(void); }
+	SYS_GETEUID        = 25  // { uid_t sys_geteuid(void); }
+	SYS_PTRACE         = 26  // { int sys_ptrace(int req, pid_t pid, caddr_t addr, int data); }
+	SYS_RECVMSG        = 27  // { ssize_t sys_recvmsg(int s, struct msghdr *msg, int flags); }
+	SYS_SENDMSG        = 28  // { ssize_t sys_sendmsg(int s, const struct msghdr *msg, int flags); }
+	SYS_RECVFROM       = 29  // { ssize_t sys_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlenaddr); }
+	SYS_ACCEPT         = 30  // { int sys_accept(int s, struct sockaddr *name, socklen_t *anamelen); }
+	SYS_GETPEERNAME    = 31  // { int sys_getpeername(int fdes, struct sockaddr *asa, socklen_t *alen); }
+	SYS_GETSOCKNAME    = 32  // { int sys_getsockname(int fdes, struct sockaddr *asa, socklen_t *alen); }
+	SYS_ACCESS         = 33  // { int sys_access(const char *path, int amode); }
+	SYS_CHFLAGS        = 34  // { int sys_chflags(const char *path, u_int flags); }
+	SYS_FCHFLAGS       = 35  // { int sys_fchflags(int fd, u_int flags); }
+	SYS_SYNC           = 36  // { void sys_sync(void); }
+	SYS_STAT           = 38  // { int sys_stat(const char *path, struct stat *ub); }
+	SYS_GETPPID        = 39  // { pid_t sys_getppid(void); }
+	SYS_LSTAT          = 40  // { int sys_lstat(const char *path, struct stat *ub); }
+	SYS_DUP            = 41  // { int sys_dup(int fd); }
+	SYS_FSTATAT        = 42  // { int sys_fstatat(int fd, const char *path, struct stat *buf, int flag); }
+	SYS_GETEGID        = 43  // { gid_t sys_getegid(void); }
+	SYS_PROFIL         = 44  // { int sys_profil(caddr_t samples, size_t size, u_long offset, u_int scale); }
+	SYS_KTRACE         = 45  // { int sys_ktrace(const char *fname, int ops, int facs, pid_t pid); }
+	SYS_SIGACTION      = 46  // { int sys_sigaction(int signum, const struct sigaction *nsa, struct sigaction *osa); }
+	SYS_GETGID         = 47  // { gid_t sys_getgid(void); }
+	SYS_SIGPROCMASK    = 48  // { int sys_sigprocmask(int how, sigset_t mask); }
+	SYS_SETLOGIN       = 50  // { int sys_setlogin(const char *namebuf); }
+	SYS_ACCT           = 51  // { int sys_acct(const char *path); }
+	SYS_SIGPENDING     = 52  // { int sys_sigpending(void); }
+	SYS_FSTAT          = 53  // { int sys_fstat(int fd, struct stat *sb); }
+	SYS_IOCTL          = 54  // { int sys_ioctl(int fd, u_long com, ... void *data); }
+	SYS_REBOOT         = 55  // { int sys_reboot(int opt); }
+	SYS_REVOKE         = 56  // { int sys_revoke(const char *path); }
+	SYS_SYMLINK        = 57  // { int sys_symlink(const char *path, const char *link); }
+	SYS_READLINK       = 58  // { ssize_t sys_readlink(const char *path, char *buf, size_t count); }
+	SYS_EXECVE         = 59  // { int sys_execve(const char *path, char * const *argp, char * const *envp); }
+	SYS_UMASK          = 60  // { mode_t sys_umask(mode_t newmask); }
+	SYS_CHROOT         = 61  // { int sys_chroot(const char *path); }
+	SYS_GETFSSTAT      = 62  // { int sys_getfsstat(struct statfs *buf, size_t bufsize, int flags); }
+	SYS_STATFS         = 63  // { int sys_statfs(const char *path, struct statfs *buf); }
+	SYS_FSTATFS        = 64  // { int sys_fstatfs(int fd, struct statfs *buf); }
+	SYS_FHSTATFS       = 65  // { int sys_fhstatfs(const fhandle_t *fhp, struct statfs *buf); }
+	SYS_VFORK          = 66  // { int sys_vfork(void); }
+	SYS_GETTIMEOFDAY   = 67  // { int sys_gettimeofday(struct timeval *tp, struct timezone *tzp); }
+	SYS_SETTIMEOFDAY   = 68  // { int sys_settimeofday(const struct timeval *tv, const struct timezone *tzp); }
+	SYS_SETITIMER      = 69  // { int sys_setitimer(int which, const struct itimerval *itv, struct itimerval *oitv); }
+	SYS_GETITIMER      = 70  // { int sys_getitimer(int which, struct itimerval *itv); }
+	SYS_SELECT         = 71  // { int sys_select(int nd, fd_set *in, fd_set *ou, fd_set *ex, struct timeval *tv); }
+	SYS_KEVENT         = 72  // { int sys_kevent(int fd, const struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents, const struct timespec *timeout); }
+	SYS_MUNMAP         = 73  // { int sys_munmap(void *addr, size_t len); }
+	SYS_MPROTECT       = 74  // { int sys_mprotect(void *addr, size_t len, int prot); }
+	SYS_MADVISE        = 75  // { int sys_madvise(void *addr, size_t len, int behav); }
+	SYS_UTIMES         = 76  // { int sys_utimes(const char *path, const struct timeval *tptr); }
+	SYS_FUTIMES        = 77  // { int sys_futimes(int fd, const struct timeval *tptr); }
+	SYS_GETGROUPS      = 79  // { int sys_getgroups(int gidsetsize, gid_t *gidset); }
+	SYS_SETGROUPS      = 80  // { int sys_setgroups(int gidsetsize, const gid_t *gidset); }
+	SYS_GETPGRP        = 81  // { int sys_getpgrp(void); }
+	SYS_SETPGID        = 82  // { int sys_setpgid(pid_t pid, pid_t pgid); }
+	SYS_FUTEX          = 83  // { int sys_futex(uint32_t *f, int op, int val, const struct timespec *timeout, uint32_t *g); }
+	SYS_UTIMENSAT      = 84  // { int sys_utimensat(int fd, const char *path, const struct timespec *times, int flag); }
+	SYS_FUTIMENS       = 85  // { int sys_futimens(int fd, const struct timespec *times); }
+	SYS_KBIND          = 86  // { int sys_kbind(const struct __kbind *param, size_t psize, int64_t proc_cookie); }
+	SYS_CLOCK_GETTIME  = 87  // { int sys_clock_gettime(clockid_t clock_id, struct timespec *tp); }
+	SYS_CLOCK_SETTIME  = 88  // { int sys_clock_settime(clockid_t clock_id, const struct timespec *tp); }
+	SYS_CLOCK_GETRES   = 89  // { int sys_clock_getres(clockid_t clock_id, struct timespec *tp); }
+	SYS_DUP2           = 90  // { int sys_dup2(int from, int to); }
+	SYS_NANOSLEEP      = 91  // { int sys_nanosleep(const struct timespec *rqtp, struct timespec *rmtp); }
+	SYS_FCNTL          = 92  // { int sys_fcntl(int fd, int cmd, ... void *arg); }
+	SYS_ACCEPT4        = 93  // { int sys_accept4(int s, struct sockaddr *name, socklen_t *anamelen, int flags); }
+	SYS___THRSLEEP     = 94  // { int sys___thrsleep(const volatile void *ident, clockid_t clock_id, const struct timespec *tp, void *lock, const int *abort); }
+	SYS_FSYNC          = 95  // { int sys_fsync(int fd); }
+	SYS_SETPRIORITY    = 96  // { int sys_setpriority(int which, id_t who, int prio); }
+	SYS_SOCKET         = 97  // { int sys_socket(int domain, int type, int protocol); }
+	SYS_CONNECT        = 98  // { int sys_connect(int s, const struct sockaddr *name, socklen_t namelen); }
+	SYS_GETDENTS       = 99  // { int sys_getdents(int fd, void *buf, size_t buflen); }
+	SYS_GETPRIORITY    = 100 // { int sys_getpriority(int which, id_t who); }
+	SYS_PIPE2          = 101 // { int sys_pipe2(int *fdp, int flags); }
+	SYS_DUP3           = 102 // { int sys_dup3(int from, int to, int flags); }
+	SYS_SIGRETURN      = 103 // { int sys_sigreturn(struct sigcontext *sigcntxp); }
+	SYS_BIND           = 104 // { int sys_bind(int s, const struct sockaddr *name, socklen_t namelen); }
+	SYS_SETSOCKOPT     = 105 // { int sys_setsockopt(int s, int level, int name, const void *val, socklen_t valsize); }
+	SYS_LISTEN         = 106 // { int sys_listen(int s, int backlog); }
+	SYS_CHFLAGSAT      = 107 // { int sys_chflagsat(int fd, const char *path, u_int flags, int atflags); }
+	SYS_PLEDGE         = 108 // { int sys_pledge(const char *promises, const char *execpromises); }
+	SYS_PPOLL          = 109 // { int sys_ppoll(struct pollfd *fds, u_int nfds, const struct timespec *ts, const sigset_t *mask); }
+	SYS_PSELECT        = 110 // { int sys_pselect(int nd, fd_set *in, fd_set *ou, fd_set *ex, const struct timespec *ts, const sigset_t *mask); }
+	SYS_SIGSUSPEND     = 111 // { int sys_sigsuspend(int mask); }
+	SYS_SENDSYSLOG     = 112 // { int sys_sendsyslog(const char *buf, size_t nbyte, int flags); }
+	SYS_UNVEIL         = 114 // { int sys_unveil(const char *path, const char *permissions); }
+	SYS_GETSOCKOPT     = 118 // { int sys_getsockopt(int s, int level, int name, void *val, socklen_t *avalsize); }
+	SYS_THRKILL        = 119 // { int sys_thrkill(pid_t tid, int signum, void *tcb); }
+	SYS_READV          = 120 // { ssize_t sys_readv(int fd, const struct iovec *iovp, int iovcnt); }
+	SYS_WRITEV         = 121 // { ssize_t sys_writev(int fd, const struct iovec *iovp, int iovcnt); }
+	SYS_KILL           = 122 // { int sys_kill(int pid, int signum); }
+	SYS_FCHOWN         = 123 // { int sys_fchown(int fd, uid_t uid, gid_t gid); }
+	SYS_FCHMOD         = 124 // { int sys_fchmod(int fd, mode_t mode); }
+	SYS_SETREUID       = 126 // { int sys_setreuid(uid_t ruid, uid_t euid); }
+	SYS_SETREGID       = 127 // { int sys_setregid(gid_t rgid, gid_t egid); }
+	SYS_RENAME         = 128 // { int sys_rename(const char *from, const char *to); }
+	SYS_FLOCK          = 131 // { int sys_flock(int fd, int how); }
+	SYS_MKFIFO         = 132 // { int sys_mkfifo(const char *path, mode_t mode); }
+	SYS_SENDTO         = 133 // { ssize_t sys_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen); }
+	SYS_SHUTDOWN       = 134 // { int sys_shutdown(int s, int how); }
+	SYS_SOCKETPAIR     = 135 // { int sys_socketpair(int domain, int type, int protocol, int *rsv); }
+	SYS_MKDIR          = 136 // { int sys_mkdir(const char *path, mode_t mode); }
+	SYS_RMDIR          = 137 // { int sys_rmdir(const char *path); }
+	SYS_ADJTIME        = 140 // { int sys_adjtime(const struct timeval *delta, struct timeval *olddelta); }
+	SYS_GETLOGIN_R     = 141 // { int sys_getlogin_r(char *namebuf, u_int namelen); }
+	SYS_SETSID         = 147 // { int sys_setsid(void); }
+	SYS_QUOTACTL       = 148 // { int sys_quotactl(const char *path, int cmd, int uid, char *arg); }
+	SYS_NFSSVC         = 155 // { int sys_nfssvc(int flag, void *argp); }
+	SYS_GETFH          = 161 // { int sys_getfh(const char *fname, fhandle_t *fhp); }
+	SYS_SYSARCH        = 165 // { int sys_sysarch(int op, void *parms); }
+	SYS_PREAD          = 173 // { ssize_t sys_pread(int fd, void *buf, size_t nbyte, int pad, off_t offset); }
+	SYS_PWRITE         = 174 // { ssize_t sys_pwrite(int fd, const void *buf, size_t nbyte, int pad, off_t offset); }
+	SYS_SETGID         = 181 // { int sys_setgid(gid_t gid); }
+	SYS_SETEGID        = 182 // { int sys_setegid(gid_t egid); }
+	SYS_SETEUID        = 183 // { int sys_seteuid(uid_t euid); }
+	SYS_PATHCONF       = 191 // { long sys_pathconf(const char *path, int name); }
+	SYS_FPATHCONF      = 192 // { long sys_fpathconf(int fd, int name); }
+	SYS_SWAPCTL        = 193 // { int sys_swapctl(int cmd, const void *arg, int misc); }
+	SYS_GETRLIMIT      = 194 // { int sys_getrlimit(int which, struct rlimit *rlp); }
+	SYS_SETRLIMIT      = 195 // { int sys_setrlimit(int which, const struct rlimit *rlp); }
+	SYS_MMAP           = 197 // { void *sys_mmap(void *addr, size_t len, int prot, int flags, int fd, long pad, off_t pos); }
+	SYS_LSEEK          = 199 // { off_t sys_lseek(int fd, int pad, off_t offset, int whence); }
+	SYS_TRUNCATE       = 200 // { int sys_truncate(const char *path, int pad, off_t length); }
+	SYS_FTRUNCATE      = 201 // { int sys_ftruncate(int fd, int pad, off_t length); }
+	SYS_SYSCTL         = 202 // { int sys_sysctl(const int *name, u_int namelen, void *old, size_t *oldlenp, void *new, size_t newlen); }
+	SYS_MLOCK          = 203 // { int sys_mlock(const void *addr, size_t len); }
+	SYS_MUNLOCK        = 204 // { int sys_munlock(const void *addr, size_t len); }
+	SYS_GETPGID        = 207 // { pid_t sys_getpgid(pid_t pid); }
+	SYS_UTRACE         = 209 // { int sys_utrace(const char *label, const void *addr, size_t len); }
+	SYS_SEMGET         = 221 // { int sys_semget(key_t key, int nsems, int semflg); }
+	SYS_MSGGET         = 225 // { int sys_msgget(key_t key, int msgflg); }
+	SYS_MSGSND         = 226 // { int sys_msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); }
+	SYS_MSGRCV         = 227 // { int sys_msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg); }
+	SYS_SHMAT          = 228 // { void *sys_shmat(int shmid, const void *shmaddr, int shmflg); }
+	SYS_SHMDT          = 230 // { int sys_shmdt(const void *shmaddr); }
+	SYS_MINHERIT       = 250 // { int sys_minherit(void *addr, size_t len, int inherit); }
+	SYS_POLL           = 252 // { int sys_poll(struct pollfd *fds, u_int nfds, int timeout); }
+	SYS_ISSETUGID      = 253 // { int sys_issetugid(void); }
+	SYS_LCHOWN         = 254 // { int sys_lchown(const char *path, uid_t uid, gid_t gid); }
+	SYS_GETSID         = 255 // { pid_t sys_getsid(pid_t pid); }
+	SYS_MSYNC          = 256 // { int sys_msync(void *addr, size_t len, int flags); }
+	SYS_PIPE           = 263 // { int sys_pipe(int *fdp); }
+	SYS_FHOPEN         = 264 // { int sys_fhopen(const fhandle_t *fhp, int flags); }
+	SYS_PREADV         = 267 // { ssize_t sys_preadv(int fd, const struct iovec *iovp, int iovcnt, int pad, off_t offset); }
+	SYS_PWRITEV        = 268 // { ssize_t sys_pwritev(int fd, const struct iovec *iovp, int iovcnt, int pad, off_t offset); }
+	SYS_KQUEUE         = 269 // { int sys_kqueue(void); }
+	SYS_MLOCKALL       = 271 // { int sys_mlockall(int flags); }
+	SYS_MUNLOCKALL     = 272 // { int sys_munlockall(void); }
+	SYS_GETRESUID      = 281 // { int sys_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); }
+	SYS_SETRESUID      = 282 // { int sys_setresuid(uid_t ruid, uid_t euid, uid_t suid); }
+	SYS_GETRESGID      = 283 // { int sys_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); }
+	SYS_SETRESGID      = 284 // { int sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid); }
+	SYS_MQUERY         = 286 // { void *sys_mquery(void *addr, size_t len, int prot, int flags, int fd, long pad, off_t pos); }
+	SYS_CLOSEFROM      = 287 // { int sys_closefrom(int fd); }
+	SYS_SIGALTSTACK    = 288 // { int sys_sigaltstack(const struct sigaltstack *nss, struct sigaltstack *oss); }
+	SYS_SHMGET         = 289 // { int sys_shmget(key_t key, size_t size, int shmflg); }
+	SYS_SEMOP          = 290 // { int sys_semop(int semid, struct sembuf *sops, size_t nsops); }
+	SYS_FHSTAT         = 294 // { int sys_fhstat(const fhandle_t *fhp, struct stat *sb); }
+	SYS___SEMCTL       = 295 // { int sys___semctl(int semid, int semnum, int cmd, union semun *arg); }
+	SYS_SHMCTL         = 296 // { int sys_shmctl(int shmid, int cmd, struct shmid_ds *buf); }
+	SYS_MSGCTL         = 297 // { int sys_msgctl(int msqid, int cmd, struct msqid_ds *buf); }
+	SYS_SCHED_YIELD    = 298 // { int sys_sched_yield(void); }
+	SYS_GETTHRID       = 299 // { pid_t sys_getthrid(void); }
+	SYS___THRWAKEUP    = 301 // { int sys___thrwakeup(const volatile void *ident, int n); }
+	SYS___THREXIT      = 302 // { void sys___threxit(pid_t *notdead); }
+	SYS___THRSIGDIVERT = 303 // { int sys___thrsigdivert(sigset_t sigmask, siginfo_t *info, const struct timespec *timeout); }
+	SYS___GETCWD       = 304 // { int sys___getcwd(char *buf, size_t len); }
+	SYS_ADJFREQ        = 305 // { int sys_adjfreq(const int64_t *freq, int64_t *oldfreq); }
+	SYS_SETRTABLE      = 310 // { int sys_setrtable(int rtableid); }
+	SYS_GETRTABLE      = 311 // { int sys_getrtable(void); }
+	SYS_FACCESSAT      = 313 // { int sys_faccessat(int fd, const char *path, int amode, int flag); }
+	SYS_FCHMODAT       = 314 // { int sys_fchmodat(int fd, const char *path, mode_t mode, int flag); }
+	SYS_FCHOWNAT       = 315 // { int sys_fchownat(int fd, const char *path, uid_t uid, gid_t gid, int flag); }
+	SYS_LINKAT         = 317 // { int sys_linkat(int fd1, const char *path1, int fd2, const char *path2, int flag); }
+	SYS_MKDIRAT        = 318 // { int sys_mkdirat(int fd, const char *path, mode_t mode); }
+	SYS_MKFIFOAT       = 319 // { int sys_mkfifoat(int fd, const char *path, mode_t mode); }
+	SYS_MKNODAT        = 320 // { int sys_mknodat(int fd, const char *path, mode_t mode, dev_t dev); }
+	SYS_OPENAT         = 321 // { int sys_openat(int fd, const char *path, int flags, ... mode_t mode); }
+	SYS_READLINKAT     = 322 // { ssize_t sys_readlinkat(int fd, const char *path, char *buf, size_t count); }
+	SYS_RENAMEAT       = 323 // { int sys_renameat(int fromfd, const char *from, int tofd, const char *to); }
+	SYS_SYMLINKAT      = 324 // { int sys_symlinkat(const char *path, int fd, const char *link); }
+	SYS_UNLINKAT       = 325 // { int sys_unlinkat(int fd, const char *path, int flag); }
+	SYS___SET_TCB      = 329 // { void sys___set_tcb(void *tcb); }
+	SYS___GET_TCB      = 330 // { void *sys___get_tcb(void); }
+)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_riscv64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_riscv64.go
new file mode 100644
index 0000000..07919e0
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsysnum_openbsd_riscv64.go
@@ -0,0 +1,219 @@
+// go run mksysnum.go https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+//go:build riscv64 && openbsd
+// +build riscv64,openbsd
+
+package unix
+
+// Deprecated: Use libc wrappers instead of direct syscalls.
+const (
+	SYS_EXIT           = 1   // { void sys_exit(int rval); }
+	SYS_FORK           = 2   // { int sys_fork(void); }
+	SYS_READ           = 3   // { ssize_t sys_read(int fd, void *buf, size_t nbyte); }
+	SYS_WRITE          = 4   // { ssize_t sys_write(int fd, const void *buf, size_t nbyte); }
+	SYS_OPEN           = 5   // { int sys_open(const char *path, int flags, ... mode_t mode); }
+	SYS_CLOSE          = 6   // { int sys_close(int fd); }
+	SYS_GETENTROPY     = 7   // { int sys_getentropy(void *buf, size_t nbyte); }
+	SYS___TFORK        = 8   // { int sys___tfork(const struct __tfork *param, size_t psize); }
+	SYS_LINK           = 9   // { int sys_link(const char *path, const char *link); }
+	SYS_UNLINK         = 10  // { int sys_unlink(const char *path); }
+	SYS_WAIT4          = 11  // { pid_t sys_wait4(pid_t pid, int *status, int options, struct rusage *rusage); }
+	SYS_CHDIR          = 12  // { int sys_chdir(const char *path); }
+	SYS_FCHDIR         = 13  // { int sys_fchdir(int fd); }
+	SYS_MKNOD          = 14  // { int sys_mknod(const char *path, mode_t mode, dev_t dev); }
+	SYS_CHMOD          = 15  // { int sys_chmod(const char *path, mode_t mode); }
+	SYS_CHOWN          = 16  // { int sys_chown(const char *path, uid_t uid, gid_t gid); }
+	SYS_OBREAK         = 17  // { int sys_obreak(char *nsize); } break
+	SYS_GETDTABLECOUNT = 18  // { int sys_getdtablecount(void); }
+	SYS_GETRUSAGE      = 19  // { int sys_getrusage(int who, struct rusage *rusage); }
+	SYS_GETPID         = 20  // { pid_t sys_getpid(void); }
+	SYS_MOUNT          = 21  // { int sys_mount(const char *type, const char *path, int flags, void *data); }
+	SYS_UNMOUNT        = 22  // { int sys_unmount(const char *path, int flags); }
+	SYS_SETUID         = 23  // { int sys_setuid(uid_t uid); }
+	SYS_GETUID         = 24  // { uid_t sys_getuid(void); }
+	SYS_GETEUID        = 25  // { uid_t sys_geteuid(void); }
+	SYS_PTRACE         = 26  // { int sys_ptrace(int req, pid_t pid, caddr_t addr, int data); }
+	SYS_RECVMSG        = 27  // { ssize_t sys_recvmsg(int s, struct msghdr *msg, int flags); }
+	SYS_SENDMSG        = 28  // { ssize_t sys_sendmsg(int s, const struct msghdr *msg, int flags); }
+	SYS_RECVFROM       = 29  // { ssize_t sys_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlenaddr); }
+	SYS_ACCEPT         = 30  // { int sys_accept(int s, struct sockaddr *name, socklen_t *anamelen); }
+	SYS_GETPEERNAME    = 31  // { int sys_getpeername(int fdes, struct sockaddr *asa, socklen_t *alen); }
+	SYS_GETSOCKNAME    = 32  // { int sys_getsockname(int fdes, struct sockaddr *asa, socklen_t *alen); }
+	SYS_ACCESS         = 33  // { int sys_access(const char *path, int amode); }
+	SYS_CHFLAGS        = 34  // { int sys_chflags(const char *path, u_int flags); }
+	SYS_FCHFLAGS       = 35  // { int sys_fchflags(int fd, u_int flags); }
+	SYS_SYNC           = 36  // { void sys_sync(void); }
+	SYS_STAT           = 38  // { int sys_stat(const char *path, struct stat *ub); }
+	SYS_GETPPID        = 39  // { pid_t sys_getppid(void); }
+	SYS_LSTAT          = 40  // { int sys_lstat(const char *path, struct stat *ub); }
+	SYS_DUP            = 41  // { int sys_dup(int fd); }
+	SYS_FSTATAT        = 42  // { int sys_fstatat(int fd, const char *path, struct stat *buf, int flag); }
+	SYS_GETEGID        = 43  // { gid_t sys_getegid(void); }
+	SYS_PROFIL         = 44  // { int sys_profil(caddr_t samples, size_t size, u_long offset, u_int scale); }
+	SYS_KTRACE         = 45  // { int sys_ktrace(const char *fname, int ops, int facs, pid_t pid); }
+	SYS_SIGACTION      = 46  // { int sys_sigaction(int signum, const struct sigaction *nsa, struct sigaction *osa); }
+	SYS_GETGID         = 47  // { gid_t sys_getgid(void); }
+	SYS_SIGPROCMASK    = 48  // { int sys_sigprocmask(int how, sigset_t mask); }
+	SYS_SETLOGIN       = 50  // { int sys_setlogin(const char *namebuf); }
+	SYS_ACCT           = 51  // { int sys_acct(const char *path); }
+	SYS_SIGPENDING     = 52  // { int sys_sigpending(void); }
+	SYS_FSTAT          = 53  // { int sys_fstat(int fd, struct stat *sb); }
+	SYS_IOCTL          = 54  // { int sys_ioctl(int fd, u_long com, ... void *data); }
+	SYS_REBOOT         = 55  // { int sys_reboot(int opt); }
+	SYS_REVOKE         = 56  // { int sys_revoke(const char *path); }
+	SYS_SYMLINK        = 57  // { int sys_symlink(const char *path, const char *link); }
+	SYS_READLINK       = 58  // { ssize_t sys_readlink(const char *path, char *buf, size_t count); }
+	SYS_EXECVE         = 59  // { int sys_execve(const char *path, char * const *argp, char * const *envp); }
+	SYS_UMASK          = 60  // { mode_t sys_umask(mode_t newmask); }
+	SYS_CHROOT         = 61  // { int sys_chroot(const char *path); }
+	SYS_GETFSSTAT      = 62  // { int sys_getfsstat(struct statfs *buf, size_t bufsize, int flags); }
+	SYS_STATFS         = 63  // { int sys_statfs(const char *path, struct statfs *buf); }
+	SYS_FSTATFS        = 64  // { int sys_fstatfs(int fd, struct statfs *buf); }
+	SYS_FHSTATFS       = 65  // { int sys_fhstatfs(const fhandle_t *fhp, struct statfs *buf); }
+	SYS_VFORK          = 66  // { int sys_vfork(void); }
+	SYS_GETTIMEOFDAY   = 67  // { int sys_gettimeofday(struct timeval *tp, struct timezone *tzp); }
+	SYS_SETTIMEOFDAY   = 68  // { int sys_settimeofday(const struct timeval *tv, const struct timezone *tzp); }
+	SYS_SETITIMER      = 69  // { int sys_setitimer(int which, const struct itimerval *itv, struct itimerval *oitv); }
+	SYS_GETITIMER      = 70  // { int sys_getitimer(int which, struct itimerval *itv); }
+	SYS_SELECT         = 71  // { int sys_select(int nd, fd_set *in, fd_set *ou, fd_set *ex, struct timeval *tv); }
+	SYS_KEVENT         = 72  // { int sys_kevent(int fd, const struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents, const struct timespec *timeout); }
+	SYS_MUNMAP         = 73  // { int sys_munmap(void *addr, size_t len); }
+	SYS_MPROTECT       = 74  // { int sys_mprotect(void *addr, size_t len, int prot); }
+	SYS_MADVISE        = 75  // { int sys_madvise(void *addr, size_t len, int behav); }
+	SYS_UTIMES         = 76  // { int sys_utimes(const char *path, const struct timeval *tptr); }
+	SYS_FUTIMES        = 77  // { int sys_futimes(int fd, const struct timeval *tptr); }
+	SYS_GETGROUPS      = 79  // { int sys_getgroups(int gidsetsize, gid_t *gidset); }
+	SYS_SETGROUPS      = 80  // { int sys_setgroups(int gidsetsize, const gid_t *gidset); }
+	SYS_GETPGRP        = 81  // { int sys_getpgrp(void); }
+	SYS_SETPGID        = 82  // { int sys_setpgid(pid_t pid, pid_t pgid); }
+	SYS_FUTEX          = 83  // { int sys_futex(uint32_t *f, int op, int val, const struct timespec *timeout, uint32_t *g); }
+	SYS_UTIMENSAT      = 84  // { int sys_utimensat(int fd, const char *path, const struct timespec *times, int flag); }
+	SYS_FUTIMENS       = 85  // { int sys_futimens(int fd, const struct timespec *times); }
+	SYS_KBIND          = 86  // { int sys_kbind(const struct __kbind *param, size_t psize, int64_t proc_cookie); }
+	SYS_CLOCK_GETTIME  = 87  // { int sys_clock_gettime(clockid_t clock_id, struct timespec *tp); }
+	SYS_CLOCK_SETTIME  = 88  // { int sys_clock_settime(clockid_t clock_id, const struct timespec *tp); }
+	SYS_CLOCK_GETRES   = 89  // { int sys_clock_getres(clockid_t clock_id, struct timespec *tp); }
+	SYS_DUP2           = 90  // { int sys_dup2(int from, int to); }
+	SYS_NANOSLEEP      = 91  // { int sys_nanosleep(const struct timespec *rqtp, struct timespec *rmtp); }
+	SYS_FCNTL          = 92  // { int sys_fcntl(int fd, int cmd, ... void *arg); }
+	SYS_ACCEPT4        = 93  // { int sys_accept4(int s, struct sockaddr *name, socklen_t *anamelen, int flags); }
+	SYS___THRSLEEP     = 94  // { int sys___thrsleep(const volatile void *ident, clockid_t clock_id, const struct timespec *tp, void *lock, const int *abort); }
+	SYS_FSYNC          = 95  // { int sys_fsync(int fd); }
+	SYS_SETPRIORITY    = 96  // { int sys_setpriority(int which, id_t who, int prio); }
+	SYS_SOCKET         = 97  // { int sys_socket(int domain, int type, int protocol); }
+	SYS_CONNECT        = 98  // { int sys_connect(int s, const struct sockaddr *name, socklen_t namelen); }
+	SYS_GETDENTS       = 99  // { int sys_getdents(int fd, void *buf, size_t buflen); }
+	SYS_GETPRIORITY    = 100 // { int sys_getpriority(int which, id_t who); }
+	SYS_PIPE2          = 101 // { int sys_pipe2(int *fdp, int flags); }
+	SYS_DUP3           = 102 // { int sys_dup3(int from, int to, int flags); }
+	SYS_SIGRETURN      = 103 // { int sys_sigreturn(struct sigcontext *sigcntxp); }
+	SYS_BIND           = 104 // { int sys_bind(int s, const struct sockaddr *name, socklen_t namelen); }
+	SYS_SETSOCKOPT     = 105 // { int sys_setsockopt(int s, int level, int name, const void *val, socklen_t valsize); }
+	SYS_LISTEN         = 106 // { int sys_listen(int s, int backlog); }
+	SYS_CHFLAGSAT      = 107 // { int sys_chflagsat(int fd, const char *path, u_int flags, int atflags); }
+	SYS_PLEDGE         = 108 // { int sys_pledge(const char *promises, const char *execpromises); }
+	SYS_PPOLL          = 109 // { int sys_ppoll(struct pollfd *fds, u_int nfds, const struct timespec *ts, const sigset_t *mask); }
+	SYS_PSELECT        = 110 // { int sys_pselect(int nd, fd_set *in, fd_set *ou, fd_set *ex, const struct timespec *ts, const sigset_t *mask); }
+	SYS_SIGSUSPEND     = 111 // { int sys_sigsuspend(int mask); }
+	SYS_SENDSYSLOG     = 112 // { int sys_sendsyslog(const char *buf, size_t nbyte, int flags); }
+	SYS_UNVEIL         = 114 // { int sys_unveil(const char *path, const char *permissions); }
+	SYS_GETSOCKOPT     = 118 // { int sys_getsockopt(int s, int level, int name, void *val, socklen_t *avalsize); }
+	SYS_THRKILL        = 119 // { int sys_thrkill(pid_t tid, int signum, void *tcb); }
+	SYS_READV          = 120 // { ssize_t sys_readv(int fd, const struct iovec *iovp, int iovcnt); }
+	SYS_WRITEV         = 121 // { ssize_t sys_writev(int fd, const struct iovec *iovp, int iovcnt); }
+	SYS_KILL           = 122 // { int sys_kill(int pid, int signum); }
+	SYS_FCHOWN         = 123 // { int sys_fchown(int fd, uid_t uid, gid_t gid); }
+	SYS_FCHMOD         = 124 // { int sys_fchmod(int fd, mode_t mode); }
+	SYS_SETREUID       = 126 // { int sys_setreuid(uid_t ruid, uid_t euid); }
+	SYS_SETREGID       = 127 // { int sys_setregid(gid_t rgid, gid_t egid); }
+	SYS_RENAME         = 128 // { int sys_rename(const char *from, const char *to); }
+	SYS_FLOCK          = 131 // { int sys_flock(int fd, int how); }
+	SYS_MKFIFO         = 132 // { int sys_mkfifo(const char *path, mode_t mode); }
+	SYS_SENDTO         = 133 // { ssize_t sys_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen); }
+	SYS_SHUTDOWN       = 134 // { int sys_shutdown(int s, int how); }
+	SYS_SOCKETPAIR     = 135 // { int sys_socketpair(int domain, int type, int protocol, int *rsv); }
+	SYS_MKDIR          = 136 // { int sys_mkdir(const char *path, mode_t mode); }
+	SYS_RMDIR          = 137 // { int sys_rmdir(const char *path); }
+	SYS_ADJTIME        = 140 // { int sys_adjtime(const struct timeval *delta, struct timeval *olddelta); }
+	SYS_GETLOGIN_R     = 141 // { int sys_getlogin_r(char *namebuf, u_int namelen); }
+	SYS_SETSID         = 147 // { int sys_setsid(void); }
+	SYS_QUOTACTL       = 148 // { int sys_quotactl(const char *path, int cmd, int uid, char *arg); }
+	SYS_NFSSVC         = 155 // { int sys_nfssvc(int flag, void *argp); }
+	SYS_GETFH          = 161 // { int sys_getfh(const char *fname, fhandle_t *fhp); }
+	SYS_SYSARCH        = 165 // { int sys_sysarch(int op, void *parms); }
+	SYS_PREAD          = 173 // { ssize_t sys_pread(int fd, void *buf, size_t nbyte, int pad, off_t offset); }
+	SYS_PWRITE         = 174 // { ssize_t sys_pwrite(int fd, const void *buf, size_t nbyte, int pad, off_t offset); }
+	SYS_SETGID         = 181 // { int sys_setgid(gid_t gid); }
+	SYS_SETEGID        = 182 // { int sys_setegid(gid_t egid); }
+	SYS_SETEUID        = 183 // { int sys_seteuid(uid_t euid); }
+	SYS_PATHCONF       = 191 // { long sys_pathconf(const char *path, int name); }
+	SYS_FPATHCONF      = 192 // { long sys_fpathconf(int fd, int name); }
+	SYS_SWAPCTL        = 193 // { int sys_swapctl(int cmd, const void *arg, int misc); }
+	SYS_GETRLIMIT      = 194 // { int sys_getrlimit(int which, struct rlimit *rlp); }
+	SYS_SETRLIMIT      = 195 // { int sys_setrlimit(int which, const struct rlimit *rlp); }
+	SYS_MMAP           = 197 // { void *sys_mmap(void *addr, size_t len, int prot, int flags, int fd, long pad, off_t pos); }
+	SYS_LSEEK          = 199 // { off_t sys_lseek(int fd, int pad, off_t offset, int whence); }
+	SYS_TRUNCATE       = 200 // { int sys_truncate(const char *path, int pad, off_t length); }
+	SYS_FTRUNCATE      = 201 // { int sys_ftruncate(int fd, int pad, off_t length); }
+	SYS_SYSCTL         = 202 // { int sys_sysctl(const int *name, u_int namelen, void *old, size_t *oldlenp, void *new, size_t newlen); }
+	SYS_MLOCK          = 203 // { int sys_mlock(const void *addr, size_t len); }
+	SYS_MUNLOCK        = 204 // { int sys_munlock(const void *addr, size_t len); }
+	SYS_GETPGID        = 207 // { pid_t sys_getpgid(pid_t pid); }
+	SYS_UTRACE         = 209 // { int sys_utrace(const char *label, const void *addr, size_t len); }
+	SYS_SEMGET         = 221 // { int sys_semget(key_t key, int nsems, int semflg); }
+	SYS_MSGGET         = 225 // { int sys_msgget(key_t key, int msgflg); }
+	SYS_MSGSND         = 226 // { int sys_msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); }
+	SYS_MSGRCV         = 227 // { int sys_msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg); }
+	SYS_SHMAT          = 228 // { void *sys_shmat(int shmid, const void *shmaddr, int shmflg); }
+	SYS_SHMDT          = 230 // { int sys_shmdt(const void *shmaddr); }
+	SYS_MINHERIT       = 250 // { int sys_minherit(void *addr, size_t len, int inherit); }
+	SYS_POLL           = 252 // { int sys_poll(struct pollfd *fds, u_int nfds, int timeout); }
+	SYS_ISSETUGID      = 253 // { int sys_issetugid(void); }
+	SYS_LCHOWN         = 254 // { int sys_lchown(const char *path, uid_t uid, gid_t gid); }
+	SYS_GETSID         = 255 // { pid_t sys_getsid(pid_t pid); }
+	SYS_MSYNC          = 256 // { int sys_msync(void *addr, size_t len, int flags); }
+	SYS_PIPE           = 263 // { int sys_pipe(int *fdp); }
+	SYS_FHOPEN         = 264 // { int sys_fhopen(const fhandle_t *fhp, int flags); }
+	SYS_PREADV         = 267 // { ssize_t sys_preadv(int fd, const struct iovec *iovp, int iovcnt, int pad, off_t offset); }
+	SYS_PWRITEV        = 268 // { ssize_t sys_pwritev(int fd, const struct iovec *iovp, int iovcnt, int pad, off_t offset); }
+	SYS_KQUEUE         = 269 // { int sys_kqueue(void); }
+	SYS_MLOCKALL       = 271 // { int sys_mlockall(int flags); }
+	SYS_MUNLOCKALL     = 272 // { int sys_munlockall(void); }
+	SYS_GETRESUID      = 281 // { int sys_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); }
+	SYS_SETRESUID      = 282 // { int sys_setresuid(uid_t ruid, uid_t euid, uid_t suid); }
+	SYS_GETRESGID      = 283 // { int sys_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); }
+	SYS_SETRESGID      = 284 // { int sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid); }
+	SYS_MQUERY         = 286 // { void *sys_mquery(void *addr, size_t len, int prot, int flags, int fd, long pad, off_t pos); }
+	SYS_CLOSEFROM      = 287 // { int sys_closefrom(int fd); }
+	SYS_SIGALTSTACK    = 288 // { int sys_sigaltstack(const struct sigaltstack *nss, struct sigaltstack *oss); }
+	SYS_SHMGET         = 289 // { int sys_shmget(key_t key, size_t size, int shmflg); }
+	SYS_SEMOP          = 290 // { int sys_semop(int semid, struct sembuf *sops, size_t nsops); }
+	SYS_FHSTAT         = 294 // { int sys_fhstat(const fhandle_t *fhp, struct stat *sb); }
+	SYS___SEMCTL       = 295 // { int sys___semctl(int semid, int semnum, int cmd, union semun *arg); }
+	SYS_SHMCTL         = 296 // { int sys_shmctl(int shmid, int cmd, struct shmid_ds *buf); }
+	SYS_MSGCTL         = 297 // { int sys_msgctl(int msqid, int cmd, struct msqid_ds *buf); }
+	SYS_SCHED_YIELD    = 298 // { int sys_sched_yield(void); }
+	SYS_GETTHRID       = 299 // { pid_t sys_getthrid(void); }
+	SYS___THRWAKEUP    = 301 // { int sys___thrwakeup(const volatile void *ident, int n); }
+	SYS___THREXIT      = 302 // { void sys___threxit(pid_t *notdead); }
+	SYS___THRSIGDIVERT = 303 // { int sys___thrsigdivert(sigset_t sigmask, siginfo_t *info, const struct timespec *timeout); }
+	SYS___GETCWD       = 304 // { int sys___getcwd(char *buf, size_t len); }
+	SYS_ADJFREQ        = 305 // { int sys_adjfreq(const int64_t *freq, int64_t *oldfreq); }
+	SYS_SETRTABLE      = 310 // { int sys_setrtable(int rtableid); }
+	SYS_GETRTABLE      = 311 // { int sys_getrtable(void); }
+	SYS_FACCESSAT      = 313 // { int sys_faccessat(int fd, const char *path, int amode, int flag); }
+	SYS_FCHMODAT       = 314 // { int sys_fchmodat(int fd, const char *path, mode_t mode, int flag); }
+	SYS_FCHOWNAT       = 315 // { int sys_fchownat(int fd, const char *path, uid_t uid, gid_t gid, int flag); }
+	SYS_LINKAT         = 317 // { int sys_linkat(int fd1, const char *path1, int fd2, const char *path2, int flag); }
+	SYS_MKDIRAT        = 318 // { int sys_mkdirat(int fd, const char *path, mode_t mode); }
+	SYS_MKFIFOAT       = 319 // { int sys_mkfifoat(int fd, const char *path, mode_t mode); }
+	SYS_MKNODAT        = 320 // { int sys_mknodat(int fd, const char *path, mode_t mode, dev_t dev); }
+	SYS_OPENAT         = 321 // { int sys_openat(int fd, const char *path, int flags, ... mode_t mode); }
+	SYS_READLINKAT     = 322 // { ssize_t sys_readlinkat(int fd, const char *path, char *buf, size_t count); }
+	SYS_RENAMEAT       = 323 // { int sys_renameat(int fromfd, const char *from, int tofd, const char *to); }
+	SYS_SYMLINKAT      = 324 // { int sys_symlinkat(const char *path, int fd, const char *link); }
+	SYS_UNLINKAT       = 325 // { int sys_unlinkat(int fd, const char *path, int flag); }
+	SYS___SET_TCB      = 329 // { void sys___set_tcb(void *tcb); }
+	SYS___GET_TCB      = 330 // { void *sys___get_tcb(void); }
+)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go
index 885842c..e2a64f0 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go
@@ -366,30 +366,57 @@
 	Filt [8]uint32
 }
 
+type TCPConnectionInfo struct {
+	State               uint8
+	Snd_wscale          uint8
+	Rcv_wscale          uint8
+	_                   uint8
+	Options             uint32
+	Flags               uint32
+	Rto                 uint32
+	Maxseg              uint32
+	Snd_ssthresh        uint32
+	Snd_cwnd            uint32
+	Snd_wnd             uint32
+	Snd_sbbytes         uint32
+	Rcv_wnd             uint32
+	Rttcur              uint32
+	Srtt                uint32
+	Rttvar              uint32
+	Txpackets           uint64
+	Txbytes             uint64
+	Txretransmitbytes   uint64
+	Rxpackets           uint64
+	Rxbytes             uint64
+	Rxoutoforderbytes   uint64
+	Txretransmitpackets uint64
+}
+
 const (
-	SizeofSockaddrInet4    = 0x10
-	SizeofSockaddrInet6    = 0x1c
-	SizeofSockaddrAny      = 0x6c
-	SizeofSockaddrUnix     = 0x6a
-	SizeofSockaddrDatalink = 0x14
-	SizeofSockaddrCtl      = 0x20
-	SizeofSockaddrVM       = 0xc
-	SizeofXvsockpcb        = 0xa8
-	SizeofXSocket          = 0x64
-	SizeofXSockbuf         = 0x18
-	SizeofXVSockPgen       = 0x20
-	SizeofXucred           = 0x4c
-	SizeofLinger           = 0x8
-	SizeofIovec            = 0x10
-	SizeofIPMreq           = 0x8
-	SizeofIPMreqn          = 0xc
-	SizeofIPv6Mreq         = 0x14
-	SizeofMsghdr           = 0x30
-	SizeofCmsghdr          = 0xc
-	SizeofInet4Pktinfo     = 0xc
-	SizeofInet6Pktinfo     = 0x14
-	SizeofIPv6MTUInfo      = 0x20
-	SizeofICMPv6Filter     = 0x20
+	SizeofSockaddrInet4     = 0x10
+	SizeofSockaddrInet6     = 0x1c
+	SizeofSockaddrAny       = 0x6c
+	SizeofSockaddrUnix      = 0x6a
+	SizeofSockaddrDatalink  = 0x14
+	SizeofSockaddrCtl       = 0x20
+	SizeofSockaddrVM        = 0xc
+	SizeofXvsockpcb         = 0xa8
+	SizeofXSocket           = 0x64
+	SizeofXSockbuf          = 0x18
+	SizeofXVSockPgen        = 0x20
+	SizeofXucred            = 0x4c
+	SizeofLinger            = 0x8
+	SizeofIovec             = 0x10
+	SizeofIPMreq            = 0x8
+	SizeofIPMreqn           = 0xc
+	SizeofIPv6Mreq          = 0x14
+	SizeofMsghdr            = 0x30
+	SizeofCmsghdr           = 0xc
+	SizeofInet4Pktinfo      = 0xc
+	SizeofInet6Pktinfo      = 0x14
+	SizeofIPv6MTUInfo       = 0x20
+	SizeofICMPv6Filter      = 0x20
+	SizeofTCPConnectionInfo = 0x70
 )
 
 const (
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go
index b23c023..34aa775 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go
@@ -366,30 +366,57 @@
 	Filt [8]uint32
 }
 
+type TCPConnectionInfo struct {
+	State               uint8
+	Snd_wscale          uint8
+	Rcv_wscale          uint8
+	_                   uint8
+	Options             uint32
+	Flags               uint32
+	Rto                 uint32
+	Maxseg              uint32
+	Snd_ssthresh        uint32
+	Snd_cwnd            uint32
+	Snd_wnd             uint32
+	Snd_sbbytes         uint32
+	Rcv_wnd             uint32
+	Rttcur              uint32
+	Srtt                uint32
+	Rttvar              uint32
+	Txpackets           uint64
+	Txbytes             uint64
+	Txretransmitbytes   uint64
+	Rxpackets           uint64
+	Rxbytes             uint64
+	Rxoutoforderbytes   uint64
+	Txretransmitpackets uint64
+}
+
 const (
-	SizeofSockaddrInet4    = 0x10
-	SizeofSockaddrInet6    = 0x1c
-	SizeofSockaddrAny      = 0x6c
-	SizeofSockaddrUnix     = 0x6a
-	SizeofSockaddrDatalink = 0x14
-	SizeofSockaddrCtl      = 0x20
-	SizeofSockaddrVM       = 0xc
-	SizeofXvsockpcb        = 0xa8
-	SizeofXSocket          = 0x64
-	SizeofXSockbuf         = 0x18
-	SizeofXVSockPgen       = 0x20
-	SizeofXucred           = 0x4c
-	SizeofLinger           = 0x8
-	SizeofIovec            = 0x10
-	SizeofIPMreq           = 0x8
-	SizeofIPMreqn          = 0xc
-	SizeofIPv6Mreq         = 0x14
-	SizeofMsghdr           = 0x30
-	SizeofCmsghdr          = 0xc
-	SizeofInet4Pktinfo     = 0xc
-	SizeofInet6Pktinfo     = 0x14
-	SizeofIPv6MTUInfo      = 0x20
-	SizeofICMPv6Filter     = 0x20
+	SizeofSockaddrInet4     = 0x10
+	SizeofSockaddrInet6     = 0x1c
+	SizeofSockaddrAny       = 0x6c
+	SizeofSockaddrUnix      = 0x6a
+	SizeofSockaddrDatalink  = 0x14
+	SizeofSockaddrCtl       = 0x20
+	SizeofSockaddrVM        = 0xc
+	SizeofXvsockpcb         = 0xa8
+	SizeofXSocket           = 0x64
+	SizeofXSockbuf          = 0x18
+	SizeofXVSockPgen        = 0x20
+	SizeofXucred            = 0x4c
+	SizeofLinger            = 0x8
+	SizeofIovec             = 0x10
+	SizeofIPMreq            = 0x8
+	SizeofIPMreqn           = 0xc
+	SizeofIPv6Mreq          = 0x14
+	SizeofMsghdr            = 0x30
+	SizeofCmsghdr           = 0xc
+	SizeofInet4Pktinfo      = 0xc
+	SizeofInet6Pktinfo      = 0x14
+	SizeofIPv6MTUInfo       = 0x20
+	SizeofICMPv6Filter      = 0x20
+	SizeofTCPConnectionInfo = 0x70
 )
 
 const (
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go
index 4eec078..d9c78cd 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_386.go
@@ -90,27 +90,6 @@
 	Spare   [10]uint64
 }
 
-type stat_freebsd11_t struct {
-	Dev     uint32
-	Ino     uint32
-	Mode    uint16
-	Nlink   uint16
-	Uid     uint32
-	Gid     uint32
-	Rdev    uint32
-	Atim    Timespec
-	Mtim    Timespec
-	Ctim    Timespec
-	Size    int64
-	Blocks  int64
-	Blksize int32
-	Flags   uint32
-	Gen     uint32
-	Lspare  int32
-	Btim    Timespec
-	_       [8]byte
-}
-
 type Statfs_t struct {
 	Version     uint32
 	Type        uint32
@@ -136,31 +115,6 @@
 	Mntonname   [1024]byte
 }
 
-type statfs_freebsd11_t struct {
-	Version     uint32
-	Type        uint32
-	Flags       uint64
-	Bsize       uint64
-	Iosize      uint64
-	Blocks      uint64
-	Bfree       uint64
-	Bavail      int64
-	Files       uint64
-	Ffree       int64
-	Syncwrites  uint64
-	Asyncwrites uint64
-	Syncreads   uint64
-	Asyncreads  uint64
-	Spare       [10]uint64
-	Namemax     uint32
-	Owner       uint32
-	Fsid        Fsid
-	Charspare   [80]int8
-	Fstypename  [16]byte
-	Mntfromname [88]byte
-	Mntonname   [88]byte
-}
-
 type Flock_t struct {
 	Start  int64
 	Len    int64
@@ -181,14 +135,6 @@
 	Name   [256]int8
 }
 
-type dirent_freebsd11 struct {
-	Fileno uint32
-	Reclen uint16
-	Type   uint8
-	Namlen uint8
-	Name   [256]int8
-}
-
 type Fsid struct {
 	Val [2]int32
 }
@@ -337,41 +283,9 @@
 )
 
 const (
-	PTRACE_ATTACH     = 0xa
-	PTRACE_CONT       = 0x7
-	PTRACE_DETACH     = 0xb
-	PTRACE_GETFPREGS  = 0x23
-	PTRACE_GETFSBASE  = 0x47
-	PTRACE_GETLWPLIST = 0xf
-	PTRACE_GETNUMLWPS = 0xe
-	PTRACE_GETREGS    = 0x21
-	PTRACE_GETXSTATE  = 0x45
-	PTRACE_IO         = 0xc
-	PTRACE_KILL       = 0x8
-	PTRACE_LWPEVENTS  = 0x18
-	PTRACE_LWPINFO    = 0xd
-	PTRACE_SETFPREGS  = 0x24
-	PTRACE_SETREGS    = 0x22
-	PTRACE_SINGLESTEP = 0x9
-	PTRACE_TRACEME    = 0x0
-)
-
-const (
-	PIOD_READ_D  = 0x1
-	PIOD_WRITE_D = 0x2
-	PIOD_READ_I  = 0x3
-	PIOD_WRITE_I = 0x4
-)
-
-const (
-	PL_FLAG_BORN   = 0x100
-	PL_FLAG_EXITED = 0x200
-	PL_FLAG_SI     = 0x20
-)
-
-const (
-	TRAP_BRKPT = 0x1
-	TRAP_TRACE = 0x2
+	PTRACE_TRACEME = 0x0
+	PTRACE_CONT    = 0x7
+	PTRACE_KILL    = 0x8
 )
 
 type PtraceLwpInfoStruct struct {
@@ -380,7 +294,7 @@
 	Flags        int32
 	Sigmask      Sigset_t
 	Siglist      Sigset_t
-	Siginfo      __Siginfo
+	Siginfo      __PtraceSiginfo
 	Tdname       [20]int8
 	Child_pid    int32
 	Syscall_code uint32
@@ -398,6 +312,17 @@
 	Value  [4]byte
 	_      [32]byte
 }
+type __PtraceSiginfo struct {
+	Signo  int32
+	Errno  int32
+	Code   int32
+	Pid    int32
+	Uid    uint32
+	Status int32
+	Addr   uintptr
+	Value  [4]byte
+	_      [32]byte
+}
 
 type Sigset_t struct {
 	Val [4]uint32
@@ -432,10 +357,12 @@
 	Pad   [64]uint8
 }
 
+type FpExtendedPrecision struct{}
+
 type PtraceIoDesc struct {
 	Op   int32
-	Offs *byte
-	Addr *byte
+	Offs uintptr
+	Addr uintptr
 	Len  uint32
 }
 
@@ -444,8 +371,9 @@
 	Filter int16
 	Flags  uint16
 	Fflags uint32
-	Data   int32
+	Data   int64
 	Udata  *byte
+	Ext    [4]uint64
 }
 
 type FdSet struct {
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go
index 7622904..26991b1 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_amd64.go
@@ -86,26 +86,6 @@
 	Spare   [10]uint64
 }
 
-type stat_freebsd11_t struct {
-	Dev     uint32
-	Ino     uint32
-	Mode    uint16
-	Nlink   uint16
-	Uid     uint32
-	Gid     uint32
-	Rdev    uint32
-	Atim    Timespec
-	Mtim    Timespec
-	Ctim    Timespec
-	Size    int64
-	Blocks  int64
-	Blksize int32
-	Flags   uint32
-	Gen     uint32
-	Lspare  int32
-	Btim    Timespec
-}
-
 type Statfs_t struct {
 	Version     uint32
 	Type        uint32
@@ -131,31 +111,6 @@
 	Mntonname   [1024]byte
 }
 
-type statfs_freebsd11_t struct {
-	Version     uint32
-	Type        uint32
-	Flags       uint64
-	Bsize       uint64
-	Iosize      uint64
-	Blocks      uint64
-	Bfree       uint64
-	Bavail      int64
-	Files       uint64
-	Ffree       int64
-	Syncwrites  uint64
-	Asyncwrites uint64
-	Syncreads   uint64
-	Asyncreads  uint64
-	Spare       [10]uint64
-	Namemax     uint32
-	Owner       uint32
-	Fsid        Fsid
-	Charspare   [80]int8
-	Fstypename  [16]byte
-	Mntfromname [88]byte
-	Mntonname   [88]byte
-}
-
 type Flock_t struct {
 	Start  int64
 	Len    int64
@@ -177,14 +132,6 @@
 	Name   [256]int8
 }
 
-type dirent_freebsd11 struct {
-	Fileno uint32
-	Reclen uint16
-	Type   uint8
-	Namlen uint8
-	Name   [256]int8
-}
-
 type Fsid struct {
 	Val [2]int32
 }
@@ -333,41 +280,9 @@
 )
 
 const (
-	PTRACE_ATTACH     = 0xa
-	PTRACE_CONT       = 0x7
-	PTRACE_DETACH     = 0xb
-	PTRACE_GETFPREGS  = 0x23
-	PTRACE_GETFSBASE  = 0x47
-	PTRACE_GETLWPLIST = 0xf
-	PTRACE_GETNUMLWPS = 0xe
-	PTRACE_GETREGS    = 0x21
-	PTRACE_GETXSTATE  = 0x45
-	PTRACE_IO         = 0xc
-	PTRACE_KILL       = 0x8
-	PTRACE_LWPEVENTS  = 0x18
-	PTRACE_LWPINFO    = 0xd
-	PTRACE_SETFPREGS  = 0x24
-	PTRACE_SETREGS    = 0x22
-	PTRACE_SINGLESTEP = 0x9
-	PTRACE_TRACEME    = 0x0
-)
-
-const (
-	PIOD_READ_D  = 0x1
-	PIOD_WRITE_D = 0x2
-	PIOD_READ_I  = 0x3
-	PIOD_WRITE_I = 0x4
-)
-
-const (
-	PL_FLAG_BORN   = 0x100
-	PL_FLAG_EXITED = 0x200
-	PL_FLAG_SI     = 0x20
-)
-
-const (
-	TRAP_BRKPT = 0x1
-	TRAP_TRACE = 0x2
+	PTRACE_TRACEME = 0x0
+	PTRACE_CONT    = 0x7
+	PTRACE_KILL    = 0x8
 )
 
 type PtraceLwpInfoStruct struct {
@@ -376,7 +291,7 @@
 	Flags        int32
 	Sigmask      Sigset_t
 	Siglist      Sigset_t
-	Siginfo      __Siginfo
+	Siginfo      __PtraceSiginfo
 	Tdname       [20]int8
 	Child_pid    int32
 	Syscall_code uint32
@@ -395,6 +310,18 @@
 	_      [40]byte
 }
 
+type __PtraceSiginfo struct {
+	Signo  int32
+	Errno  int32
+	Code   int32
+	Pid    int32
+	Uid    uint32
+	Status int32
+	Addr   uintptr
+	Value  [8]byte
+	_      [40]byte
+}
+
 type Sigset_t struct {
 	Val [4]uint32
 }
@@ -435,10 +362,12 @@
 	Spare [12]uint64
 }
 
+type FpExtendedPrecision struct{}
+
 type PtraceIoDesc struct {
 	Op   int32
-	Offs *byte
-	Addr *byte
+	Offs uintptr
+	Addr uintptr
 	Len  uint64
 }
 
@@ -449,6 +378,7 @@
 	Fflags uint32
 	Data   int64
 	Udata  *byte
+	Ext    [4]uint64
 }
 
 type FdSet struct {
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go
index 19223ce..f8324e7 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go
@@ -33,7 +33,7 @@
 	_    [4]byte
 }
 
-type Time_t int32
+type Time_t int64
 
 type Rusage struct {
 	Utime    Timeval
@@ -88,26 +88,6 @@
 	Spare   [10]uint64
 }
 
-type stat_freebsd11_t struct {
-	Dev     uint32
-	Ino     uint32
-	Mode    uint16
-	Nlink   uint16
-	Uid     uint32
-	Gid     uint32
-	Rdev    uint32
-	Atim    Timespec
-	Mtim    Timespec
-	Ctim    Timespec
-	Size    int64
-	Blocks  int64
-	Blksize int32
-	Flags   uint32
-	Gen     uint32
-	Lspare  int32
-	Btim    Timespec
-}
-
 type Statfs_t struct {
 	Version     uint32
 	Type        uint32
@@ -133,31 +113,6 @@
 	Mntonname   [1024]byte
 }
 
-type statfs_freebsd11_t struct {
-	Version     uint32
-	Type        uint32
-	Flags       uint64
-	Bsize       uint64
-	Iosize      uint64
-	Blocks      uint64
-	Bfree       uint64
-	Bavail      int64
-	Files       uint64
-	Ffree       int64
-	Syncwrites  uint64
-	Asyncwrites uint64
-	Syncreads   uint64
-	Asyncreads  uint64
-	Spare       [10]uint64
-	Namemax     uint32
-	Owner       uint32
-	Fsid        Fsid
-	Charspare   [80]int8
-	Fstypename  [16]byte
-	Mntfromname [88]byte
-	Mntonname   [88]byte
-}
-
 type Flock_t struct {
 	Start  int64
 	Len    int64
@@ -179,14 +134,6 @@
 	Name   [256]int8
 }
 
-type dirent_freebsd11 struct {
-	Fileno uint32
-	Reclen uint16
-	Type   uint8
-	Namlen uint8
-	Name   [256]int8
-}
-
 type Fsid struct {
 	Val [2]int32
 }
@@ -335,41 +282,9 @@
 )
 
 const (
-	PTRACE_ATTACH     = 0xa
-	PTRACE_CONT       = 0x7
-	PTRACE_DETACH     = 0xb
-	PTRACE_GETFPREGS  = 0x23
-	PTRACE_GETFSBASE  = 0x47
-	PTRACE_GETLWPLIST = 0xf
-	PTRACE_GETNUMLWPS = 0xe
-	PTRACE_GETREGS    = 0x21
-	PTRACE_GETXSTATE  = 0x45
-	PTRACE_IO         = 0xc
-	PTRACE_KILL       = 0x8
-	PTRACE_LWPEVENTS  = 0x18
-	PTRACE_LWPINFO    = 0xd
-	PTRACE_SETFPREGS  = 0x24
-	PTRACE_SETREGS    = 0x22
-	PTRACE_SINGLESTEP = 0x9
-	PTRACE_TRACEME    = 0x0
-)
-
-const (
-	PIOD_READ_D  = 0x1
-	PIOD_WRITE_D = 0x2
-	PIOD_READ_I  = 0x3
-	PIOD_WRITE_I = 0x4
-)
-
-const (
-	PL_FLAG_BORN   = 0x100
-	PL_FLAG_EXITED = 0x200
-	PL_FLAG_SI     = 0x20
-)
-
-const (
-	TRAP_BRKPT = 0x1
-	TRAP_TRACE = 0x2
+	PTRACE_TRACEME = 0x0
+	PTRACE_CONT    = 0x7
+	PTRACE_KILL    = 0x8
 )
 
 type PtraceLwpInfoStruct struct {
@@ -378,7 +293,7 @@
 	Flags        int32
 	Sigmask      Sigset_t
 	Siglist      Sigset_t
-	Siginfo      __Siginfo
+	Siginfo      __PtraceSiginfo
 	Tdname       [20]int8
 	Child_pid    int32
 	Syscall_code uint32
@@ -386,15 +301,27 @@
 }
 
 type __Siginfo struct {
-	Signo    int32
-	Errno    int32
-	Code     int32
-	Pid      int32
-	Uid      uint32
-	Status   int32
-	Addr     *byte
-	Value    [4]byte
-	X_reason [32]byte
+	Signo  int32
+	Errno  int32
+	Code   int32
+	Pid    int32
+	Uid    uint32
+	Status int32
+	Addr   *byte
+	Value  [4]byte
+	_      [32]byte
+}
+
+type __PtraceSiginfo struct {
+	Signo  int32
+	Errno  int32
+	Code   int32
+	Pid    int32
+	Uid    uint32
+	Status int32
+	Addr   uintptr
+	Value  [4]byte
+	_      [32]byte
 }
 
 type Sigset_t struct {
@@ -402,22 +329,28 @@
 }
 
 type Reg struct {
-	R      [13]uint32
-	R_sp   uint32
-	R_lr   uint32
-	R_pc   uint32
-	R_cpsr uint32
+	R    [13]uint32
+	Sp   uint32
+	Lr   uint32
+	Pc   uint32
+	Cpsr uint32
 }
 
 type FpReg struct {
-	Fpr_fpsr uint32
-	Fpr      [8][3]uint32
+	Fpsr uint32
+	Fpr  [8]FpExtendedPrecision
+}
+
+type FpExtendedPrecision struct {
+	Exponent    uint32
+	Mantissa_hi uint32
+	Mantissa_lo uint32
 }
 
 type PtraceIoDesc struct {
 	Op   int32
-	Offs *byte
-	Addr *byte
+	Offs uintptr
+	Addr uintptr
 	Len  uint32
 }
 
@@ -426,8 +359,11 @@
 	Filter int16
 	Flags  uint16
 	Fflags uint32
-	Data   int32
+	_      [4]byte
+	Data   int64
 	Udata  *byte
+	_      [4]byte
+	Ext    [4]uint64
 }
 
 type FdSet struct {
@@ -453,7 +389,7 @@
 	Addrs   int32
 	Flags   int32
 	Index   uint16
-	_       [2]byte
+	_       uint16
 	Data    ifData
 }
 
@@ -464,7 +400,6 @@
 	Addrs   int32
 	Flags   int32
 	Index   uint16
-	_       [2]byte
 	Data    IfData
 }
 
@@ -532,7 +467,7 @@
 	Addrs   int32
 	Flags   int32
 	Index   uint16
-	_       [2]byte
+	_       uint16
 	Metric  int32
 }
 
@@ -543,7 +478,7 @@
 	Addrs   int32
 	Flags   int32
 	Index   uint16
-	_       [2]byte
+	_       uint16
 }
 
 type IfAnnounceMsghdr struct {
@@ -560,7 +495,7 @@
 	Version uint8
 	Type    uint8
 	Index   uint16
-	_       [2]byte
+	_       uint16
 	Flags   int32
 	Addrs   int32
 	Pid     int32
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go
index 8e3e33f..4220411 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm64.go
@@ -86,26 +86,6 @@
 	Spare   [10]uint64
 }
 
-type stat_freebsd11_t struct {
-	Dev     uint32
-	Ino     uint32
-	Mode    uint16
-	Nlink   uint16
-	Uid     uint32
-	Gid     uint32
-	Rdev    uint32
-	Atim    Timespec
-	Mtim    Timespec
-	Ctim    Timespec
-	Size    int64
-	Blocks  int64
-	Blksize int32
-	Flags   uint32
-	Gen     uint32
-	Lspare  int32
-	Btim    Timespec
-}
-
 type Statfs_t struct {
 	Version     uint32
 	Type        uint32
@@ -131,31 +111,6 @@
 	Mntonname   [1024]byte
 }
 
-type statfs_freebsd11_t struct {
-	Version     uint32
-	Type        uint32
-	Flags       uint64
-	Bsize       uint64
-	Iosize      uint64
-	Blocks      uint64
-	Bfree       uint64
-	Bavail      int64
-	Files       uint64
-	Ffree       int64
-	Syncwrites  uint64
-	Asyncwrites uint64
-	Syncreads   uint64
-	Asyncreads  uint64
-	Spare       [10]uint64
-	Namemax     uint32
-	Owner       uint32
-	Fsid        Fsid
-	Charspare   [80]int8
-	Fstypename  [16]byte
-	Mntfromname [88]byte
-	Mntonname   [88]byte
-}
-
 type Flock_t struct {
 	Start  int64
 	Len    int64
@@ -177,14 +132,6 @@
 	Name   [256]int8
 }
 
-type dirent_freebsd11 struct {
-	Fileno uint32
-	Reclen uint16
-	Type   uint8
-	Namlen uint8
-	Name   [256]int8
-}
-
 type Fsid struct {
 	Val [2]int32
 }
@@ -333,39 +280,9 @@
 )
 
 const (
-	PTRACE_ATTACH     = 0xa
-	PTRACE_CONT       = 0x7
-	PTRACE_DETACH     = 0xb
-	PTRACE_GETFPREGS  = 0x23
-	PTRACE_GETLWPLIST = 0xf
-	PTRACE_GETNUMLWPS = 0xe
-	PTRACE_GETREGS    = 0x21
-	PTRACE_IO         = 0xc
-	PTRACE_KILL       = 0x8
-	PTRACE_LWPEVENTS  = 0x18
-	PTRACE_LWPINFO    = 0xd
-	PTRACE_SETFPREGS  = 0x24
-	PTRACE_SETREGS    = 0x22
-	PTRACE_SINGLESTEP = 0x9
-	PTRACE_TRACEME    = 0x0
-)
-
-const (
-	PIOD_READ_D  = 0x1
-	PIOD_WRITE_D = 0x2
-	PIOD_READ_I  = 0x3
-	PIOD_WRITE_I = 0x4
-)
-
-const (
-	PL_FLAG_BORN   = 0x100
-	PL_FLAG_EXITED = 0x200
-	PL_FLAG_SI     = 0x20
-)
-
-const (
-	TRAP_BRKPT = 0x1
-	TRAP_TRACE = 0x2
+	PTRACE_TRACEME = 0x0
+	PTRACE_CONT    = 0x7
+	PTRACE_KILL    = 0x8
 )
 
 type PtraceLwpInfoStruct struct {
@@ -374,7 +291,7 @@
 	Flags        int32
 	Sigmask      Sigset_t
 	Siglist      Sigset_t
-	Siginfo      __Siginfo
+	Siginfo      __PtraceSiginfo
 	Tdname       [20]int8
 	Child_pid    int32
 	Syscall_code uint32
@@ -393,6 +310,18 @@
 	_      [40]byte
 }
 
+type __PtraceSiginfo struct {
+	Signo  int32
+	Errno  int32
+	Code   int32
+	Pid    int32
+	Uid    uint32
+	Status int32
+	Addr   uintptr
+	Value  [8]byte
+	_      [40]byte
+}
+
 type Sigset_t struct {
 	Val [4]uint32
 }
@@ -413,10 +342,12 @@
 	_  [8]byte
 }
 
+type FpExtendedPrecision struct{}
+
 type PtraceIoDesc struct {
 	Op   int32
-	Offs *byte
-	Addr *byte
+	Offs uintptr
+	Addr uintptr
 	Len  uint64
 }
 
@@ -427,6 +358,7 @@
 	Fflags uint32
 	Data   int64
 	Udata  *byte
+	Ext    [4]uint64
 }
 
 type FdSet struct {
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_riscv64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_riscv64.go
new file mode 100644
index 0000000..0660fd4
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_freebsd_riscv64.go
@@ -0,0 +1,638 @@
+// cgo -godefs -- -fsigned-char types_freebsd.go | go run mkpost.go
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+//go:build riscv64 && freebsd
+// +build riscv64,freebsd
+
+package unix
+
+const (
+	SizeofPtr      = 0x8
+	SizeofShort    = 0x2
+	SizeofInt      = 0x4
+	SizeofLong     = 0x8
+	SizeofLongLong = 0x8
+)
+
+type (
+	_C_short     int16
+	_C_int       int32
+	_C_long      int64
+	_C_long_long int64
+)
+
+type Timespec struct {
+	Sec  int64
+	Nsec int64
+}
+
+type Timeval struct {
+	Sec  int64
+	Usec int64
+}
+
+type Time_t int64
+
+type Rusage struct {
+	Utime    Timeval
+	Stime    Timeval
+	Maxrss   int64
+	Ixrss    int64
+	Idrss    int64
+	Isrss    int64
+	Minflt   int64
+	Majflt   int64
+	Nswap    int64
+	Inblock  int64
+	Oublock  int64
+	Msgsnd   int64
+	Msgrcv   int64
+	Nsignals int64
+	Nvcsw    int64
+	Nivcsw   int64
+}
+
+type Rlimit struct {
+	Cur int64
+	Max int64
+}
+
+type _Gid_t uint32
+
+const (
+	_statfsVersion = 0x20140518
+	_dirblksiz     = 0x400
+)
+
+type Stat_t struct {
+	Dev     uint64
+	Ino     uint64
+	Nlink   uint64
+	Mode    uint16
+	_0      int16
+	Uid     uint32
+	Gid     uint32
+	_1      int32
+	Rdev    uint64
+	Atim    Timespec
+	Mtim    Timespec
+	Ctim    Timespec
+	Btim    Timespec
+	Size    int64
+	Blocks  int64
+	Blksize int32
+	Flags   uint32
+	Gen     uint64
+	Spare   [10]uint64
+}
+
+type Statfs_t struct {
+	Version     uint32
+	Type        uint32
+	Flags       uint64
+	Bsize       uint64
+	Iosize      uint64
+	Blocks      uint64
+	Bfree       uint64
+	Bavail      int64
+	Files       uint64
+	Ffree       int64
+	Syncwrites  uint64
+	Asyncwrites uint64
+	Syncreads   uint64
+	Asyncreads  uint64
+	Spare       [10]uint64
+	Namemax     uint32
+	Owner       uint32
+	Fsid        Fsid
+	Charspare   [80]int8
+	Fstypename  [16]byte
+	Mntfromname [1024]byte
+	Mntonname   [1024]byte
+}
+
+type Flock_t struct {
+	Start  int64
+	Len    int64
+	Pid    int32
+	Type   int16
+	Whence int16
+	Sysid  int32
+	_      [4]byte
+}
+
+type Dirent struct {
+	Fileno uint64
+	Off    int64
+	Reclen uint16
+	Type   uint8
+	Pad0   uint8
+	Namlen uint16
+	Pad1   uint16
+	Name   [256]int8
+}
+
+type Fsid struct {
+	Val [2]int32
+}
+
+const (
+	PathMax = 0x400
+)
+
+const (
+	FADV_NORMAL     = 0x0
+	FADV_RANDOM     = 0x1
+	FADV_SEQUENTIAL = 0x2
+	FADV_WILLNEED   = 0x3
+	FADV_DONTNEED   = 0x4
+	FADV_NOREUSE    = 0x5
+)
+
+type RawSockaddrInet4 struct {
+	Len    uint8
+	Family uint8
+	Port   uint16
+	Addr   [4]byte /* in_addr */
+	Zero   [8]int8
+}
+
+type RawSockaddrInet6 struct {
+	Len      uint8
+	Family   uint8
+	Port     uint16
+	Flowinfo uint32
+	Addr     [16]byte /* in6_addr */
+	Scope_id uint32
+}
+
+type RawSockaddrUnix struct {
+	Len    uint8
+	Family uint8
+	Path   [104]int8
+}
+
+type RawSockaddrDatalink struct {
+	Len    uint8
+	Family uint8
+	Index  uint16
+	Type   uint8
+	Nlen   uint8
+	Alen   uint8
+	Slen   uint8
+	Data   [46]int8
+}
+
+type RawSockaddr struct {
+	Len    uint8
+	Family uint8
+	Data   [14]int8
+}
+
+type RawSockaddrAny struct {
+	Addr RawSockaddr
+	Pad  [92]int8
+}
+
+type _Socklen uint32
+
+type Xucred struct {
+	Version uint32
+	Uid     uint32
+	Ngroups int16
+	Groups  [16]uint32
+	_       *byte
+}
+
+type Linger struct {
+	Onoff  int32
+	Linger int32
+}
+
+type Iovec struct {
+	Base *byte
+	Len  uint64
+}
+
+type IPMreq struct {
+	Multiaddr [4]byte /* in_addr */
+	Interface [4]byte /* in_addr */
+}
+
+type IPMreqn struct {
+	Multiaddr [4]byte /* in_addr */
+	Address   [4]byte /* in_addr */
+	Ifindex   int32
+}
+
+type IPv6Mreq struct {
+	Multiaddr [16]byte /* in6_addr */
+	Interface uint32
+}
+
+type Msghdr struct {
+	Name       *byte
+	Namelen    uint32
+	Iov        *Iovec
+	Iovlen     int32
+	Control    *byte
+	Controllen uint32
+	Flags      int32
+}
+
+type Cmsghdr struct {
+	Len   uint32
+	Level int32
+	Type  int32
+}
+
+type Inet6Pktinfo struct {
+	Addr    [16]byte /* in6_addr */
+	Ifindex uint32
+}
+
+type IPv6MTUInfo struct {
+	Addr RawSockaddrInet6
+	Mtu  uint32
+}
+
+type ICMPv6Filter struct {
+	Filt [8]uint32
+}
+
+const (
+	SizeofSockaddrInet4    = 0x10
+	SizeofSockaddrInet6    = 0x1c
+	SizeofSockaddrAny      = 0x6c
+	SizeofSockaddrUnix     = 0x6a
+	SizeofSockaddrDatalink = 0x36
+	SizeofXucred           = 0x58
+	SizeofLinger           = 0x8
+	SizeofIovec            = 0x10
+	SizeofIPMreq           = 0x8
+	SizeofIPMreqn          = 0xc
+	SizeofIPv6Mreq         = 0x14
+	SizeofMsghdr           = 0x30
+	SizeofCmsghdr          = 0xc
+	SizeofInet6Pktinfo     = 0x14
+	SizeofIPv6MTUInfo      = 0x20
+	SizeofICMPv6Filter     = 0x20
+)
+
+const (
+	PTRACE_TRACEME = 0x0
+	PTRACE_CONT    = 0x7
+	PTRACE_KILL    = 0x8
+)
+
+type PtraceLwpInfoStruct struct {
+	Lwpid        int32
+	Event        int32
+	Flags        int32
+	Sigmask      Sigset_t
+	Siglist      Sigset_t
+	Siginfo      __PtraceSiginfo
+	Tdname       [20]int8
+	Child_pid    int32
+	Syscall_code uint32
+	Syscall_narg uint32
+}
+
+type __Siginfo struct {
+	Signo  int32
+	Errno  int32
+	Code   int32
+	Pid    int32
+	Uid    uint32
+	Status int32
+	Addr   *byte
+	Value  [8]byte
+	_      [40]byte
+}
+
+type __PtraceSiginfo struct {
+	Signo  int32
+	Errno  int32
+	Code   int32
+	Pid    int32
+	Uid    uint32
+	Status int32
+	Addr   uintptr
+	Value  [8]byte
+	_      [40]byte
+}
+
+type Sigset_t struct {
+	Val [4]uint32
+}
+
+type Reg struct {
+	Ra      uint64
+	Sp      uint64
+	Gp      uint64
+	Tp      uint64
+	T       [7]uint64
+	S       [12]uint64
+	A       [8]uint64
+	Sepc    uint64
+	Sstatus uint64
+}
+
+type FpReg struct {
+	X    [32][2]uint64
+	Fcsr uint64
+}
+
+type FpExtendedPrecision struct{}
+
+type PtraceIoDesc struct {
+	Op   int32
+	Offs uintptr
+	Addr uintptr
+	Len  uint64
+}
+
+type Kevent_t struct {
+	Ident  uint64
+	Filter int16
+	Flags  uint16
+	Fflags uint32
+	Data   int64
+	Udata  *byte
+	Ext    [4]uint64
+}
+
+type FdSet struct {
+	Bits [16]uint64
+}
+
+const (
+	sizeofIfMsghdr         = 0xa8
+	SizeofIfMsghdr         = 0xa8
+	sizeofIfData           = 0x98
+	SizeofIfData           = 0x98
+	SizeofIfaMsghdr        = 0x14
+	SizeofIfmaMsghdr       = 0x10
+	SizeofIfAnnounceMsghdr = 0x18
+	SizeofRtMsghdr         = 0x98
+	SizeofRtMetrics        = 0x70
+)
+
+type ifMsghdr struct {
+	Msglen  uint16
+	Version uint8
+	Type    uint8
+	Addrs   int32
+	Flags   int32
+	Index   uint16
+	_       uint16
+	Data    ifData
+}
+
+type IfMsghdr struct {
+	Msglen  uint16
+	Version uint8
+	Type    uint8
+	Addrs   int32
+	Flags   int32
+	Index   uint16
+	Data    IfData
+}
+
+type ifData struct {
+	Type       uint8
+	Physical   uint8
+	Addrlen    uint8
+	Hdrlen     uint8
+	Link_state uint8
+	Vhid       uint8
+	Datalen    uint16
+	Mtu        uint32
+	Metric     uint32
+	Baudrate   uint64
+	Ipackets   uint64
+	Ierrors    uint64
+	Opackets   uint64
+	Oerrors    uint64
+	Collisions uint64
+	Ibytes     uint64
+	Obytes     uint64
+	Imcasts    uint64
+	Omcasts    uint64
+	Iqdrops    uint64
+	Oqdrops    uint64
+	Noproto    uint64
+	Hwassist   uint64
+	_          [8]byte
+	_          [16]byte
+}
+
+type IfData struct {
+	Type        uint8
+	Physical    uint8
+	Addrlen     uint8
+	Hdrlen      uint8
+	Link_state  uint8
+	Spare_char1 uint8
+	Spare_char2 uint8
+	Datalen     uint8
+	Mtu         uint64
+	Metric      uint64
+	Baudrate    uint64
+	Ipackets    uint64
+	Ierrors     uint64
+	Opackets    uint64
+	Oerrors     uint64
+	Collisions  uint64
+	Ibytes      uint64
+	Obytes      uint64
+	Imcasts     uint64
+	Omcasts     uint64
+	Iqdrops     uint64
+	Noproto     uint64
+	Hwassist    uint64
+	Epoch       int64
+	Lastchange  Timeval
+}
+
+type IfaMsghdr struct {
+	Msglen  uint16
+	Version uint8
+	Type    uint8
+	Addrs   int32
+	Flags   int32
+	Index   uint16
+	_       uint16
+	Metric  int32
+}
+
+type IfmaMsghdr struct {
+	Msglen  uint16
+	Version uint8
+	Type    uint8
+	Addrs   int32
+	Flags   int32
+	Index   uint16
+	_       uint16
+}
+
+type IfAnnounceMsghdr struct {
+	Msglen  uint16
+	Version uint8
+	Type    uint8
+	Index   uint16
+	Name    [16]int8
+	What    uint16
+}
+
+type RtMsghdr struct {
+	Msglen  uint16
+	Version uint8
+	Type    uint8
+	Index   uint16
+	_       uint16
+	Flags   int32
+	Addrs   int32
+	Pid     int32
+	Seq     int32
+	Errno   int32
+	Fmask   int32
+	Inits   uint64
+	Rmx     RtMetrics
+}
+
+type RtMetrics struct {
+	Locks    uint64
+	Mtu      uint64
+	Hopcount uint64
+	Expire   uint64
+	Recvpipe uint64
+	Sendpipe uint64
+	Ssthresh uint64
+	Rtt      uint64
+	Rttvar   uint64
+	Pksent   uint64
+	Weight   uint64
+	Nhidx    uint64
+	Filler   [2]uint64
+}
+
+const (
+	SizeofBpfVersion    = 0x4
+	SizeofBpfStat       = 0x8
+	SizeofBpfZbuf       = 0x18
+	SizeofBpfProgram    = 0x10
+	SizeofBpfInsn       = 0x8
+	SizeofBpfHdr        = 0x20
+	SizeofBpfZbufHeader = 0x20
+)
+
+type BpfVersion struct {
+	Major uint16
+	Minor uint16
+}
+
+type BpfStat struct {
+	Recv uint32
+	Drop uint32
+}
+
+type BpfZbuf struct {
+	Bufa   *byte
+	Bufb   *byte
+	Buflen uint64
+}
+
+type BpfProgram struct {
+	Len   uint32
+	Insns *BpfInsn
+}
+
+type BpfInsn struct {
+	Code uint16
+	Jt   uint8
+	Jf   uint8
+	K    uint32
+}
+
+type BpfHdr struct {
+	Tstamp  Timeval
+	Caplen  uint32
+	Datalen uint32
+	Hdrlen  uint16
+	_       [6]byte
+}
+
+type BpfZbufHeader struct {
+	Kernel_gen uint32
+	Kernel_len uint32
+	User_gen   uint32
+	_          [5]uint32
+}
+
+type Termios struct {
+	Iflag  uint32
+	Oflag  uint32
+	Cflag  uint32
+	Lflag  uint32
+	Cc     [20]uint8
+	Ispeed uint32
+	Ospeed uint32
+}
+
+type Winsize struct {
+	Row    uint16
+	Col    uint16
+	Xpixel uint16
+	Ypixel uint16
+}
+
+const (
+	AT_FDCWD            = -0x64
+	AT_EACCESS          = 0x100
+	AT_SYMLINK_NOFOLLOW = 0x200
+	AT_SYMLINK_FOLLOW   = 0x400
+	AT_REMOVEDIR        = 0x800
+)
+
+type PollFd struct {
+	Fd      int32
+	Events  int16
+	Revents int16
+}
+
+const (
+	POLLERR      = 0x8
+	POLLHUP      = 0x10
+	POLLIN       = 0x1
+	POLLINIGNEOF = 0x2000
+	POLLNVAL     = 0x20
+	POLLOUT      = 0x4
+	POLLPRI      = 0x2
+	POLLRDBAND   = 0x80
+	POLLRDNORM   = 0x40
+	POLLWRBAND   = 0x100
+	POLLWRNORM   = 0x4
+)
+
+type CapRights struct {
+	Rights [2]uint64
+}
+
+type Utsname struct {
+	Sysname  [256]byte
+	Nodename [256]byte
+	Release  [256]byte
+	Version  [256]byte
+	Machine  [256]byte
+}
+
+const SizeofClockinfo = 0x14
+
+type Clockinfo struct {
+	Hz     int32
+	Tick   int32
+	Spare  int32
+	Stathz int32
+	Profhz int32
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_illumos_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_illumos_amd64.go
deleted file mode 100644
index 4c48526..0000000
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_illumos_amd64.go
+++ /dev/null
@@ -1,42 +0,0 @@
-// cgo -godefs types_illumos.go | go run mkpost.go
-// Code generated by the command above; see README.md. DO NOT EDIT.
-
-//go:build amd64 && illumos
-// +build amd64,illumos
-
-package unix
-
-const (
-	TUNNEWPPA = 0x540001
-	TUNSETPPA = 0x540002
-
-	I_STR     = 0x5308
-	I_POP     = 0x5303
-	I_PUSH    = 0x5302
-	I_LINK    = 0x530c
-	I_UNLINK  = 0x530d
-	I_PLINK   = 0x5316
-	I_PUNLINK = 0x5317
-
-	IF_UNITSEL = -0x7ffb8cca
-)
-
-type strbuf struct {
-	Maxlen int32
-	Len    int32
-	Buf    *int8
-}
-
-type Strioctl struct {
-	Cmd    int32
-	Timout int32
-	Len    int32
-	Dp     *int8
-}
-
-type Lifreq struct {
-	Name   [32]int8
-	Lifru1 [4]byte
-	Type   uint32
-	Lifru  [336]byte
-}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux.go
index 9962d26..ff68811 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux.go
@@ -945,6 +945,9 @@
 	Aux_watermark      uint32
 	Sample_max_stack   uint16
 	_                  uint16
+	Aux_sample_size    uint32
+	_                  uint32
+	Sig_data           uint64
 }
 
 type PerfEventMmapPage struct {
@@ -1127,7 +1130,9 @@
 	PERF_BR_SYSRET                        = 0x8
 	PERF_BR_COND_CALL                     = 0x9
 	PERF_BR_COND_RET                      = 0xa
-	PERF_BR_MAX                           = 0xb
+	PERF_BR_ERET                          = 0xb
+	PERF_BR_IRQ                           = 0xc
+	PERF_BR_MAX                           = 0xd
 	PERF_SAMPLE_REGS_ABI_NONE             = 0x0
 	PERF_SAMPLE_REGS_ABI_32               = 0x1
 	PERF_SAMPLE_REGS_ABI_64               = 0x2
@@ -1461,6 +1466,11 @@
 	IFLA_ALT_IFNAME                            = 0x35
 	IFLA_PERM_ADDRESS                          = 0x36
 	IFLA_PROTO_DOWN_REASON                     = 0x37
+	IFLA_PARENT_DEV_NAME                       = 0x38
+	IFLA_PARENT_DEV_BUS_NAME                   = 0x39
+	IFLA_GRO_MAX_SIZE                          = 0x3a
+	IFLA_TSO_MAX_SIZE                          = 0x3b
+	IFLA_TSO_MAX_SEGS                          = 0x3c
 	IFLA_PROTO_DOWN_REASON_UNSPEC              = 0x0
 	IFLA_PROTO_DOWN_REASON_MASK                = 0x1
 	IFLA_PROTO_DOWN_REASON_VALUE               = 0x2
@@ -2969,7 +2979,7 @@
 	DEVLINK_CMD_TRAP_POLICER_NEW                       = 0x47
 	DEVLINK_CMD_TRAP_POLICER_DEL                       = 0x48
 	DEVLINK_CMD_HEALTH_REPORTER_TEST                   = 0x49
-	DEVLINK_CMD_MAX                                    = 0x4d
+	DEVLINK_CMD_MAX                                    = 0x51
 	DEVLINK_PORT_TYPE_NOTSET                           = 0x0
 	DEVLINK_PORT_TYPE_AUTO                             = 0x1
 	DEVLINK_PORT_TYPE_ETH                              = 0x2
@@ -3198,7 +3208,7 @@
 	DEVLINK_ATTR_RATE_NODE_NAME                        = 0xa8
 	DEVLINK_ATTR_RATE_PARENT_NODE_NAME                 = 0xa9
 	DEVLINK_ATTR_REGION_MAX_SNAPSHOTS                  = 0xaa
-	DEVLINK_ATTR_MAX                                   = 0xaa
+	DEVLINK_ATTR_MAX                                   = 0xae
 	DEVLINK_DPIPE_FIELD_MAPPING_TYPE_NONE              = 0x0
 	DEVLINK_DPIPE_FIELD_MAPPING_TYPE_IFINDEX           = 0x1
 	DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT               = 0x0
@@ -3638,7 +3648,11 @@
 	ETHTOOL_A_RINGS_RX_MINI                   = 0x7
 	ETHTOOL_A_RINGS_RX_JUMBO                  = 0x8
 	ETHTOOL_A_RINGS_TX                        = 0x9
-	ETHTOOL_A_RINGS_MAX                       = 0xa
+	ETHTOOL_A_RINGS_RX_BUF_LEN                = 0xa
+	ETHTOOL_A_RINGS_TCP_DATA_SPLIT            = 0xb
+	ETHTOOL_A_RINGS_CQE_SIZE                  = 0xc
+	ETHTOOL_A_RINGS_TX_PUSH                   = 0xd
+	ETHTOOL_A_RINGS_MAX                       = 0xd
 	ETHTOOL_A_CHANNELS_UNSPEC                 = 0x0
 	ETHTOOL_A_CHANNELS_HEADER                 = 0x1
 	ETHTOOL_A_CHANNELS_RX_MAX                 = 0x2
@@ -4323,7 +4337,7 @@
 	NL80211_ATTR_MAC_HINT                                   = 0xc8
 	NL80211_ATTR_MAC_MASK                                   = 0xd7
 	NL80211_ATTR_MAX_AP_ASSOC_STA                           = 0xca
-	NL80211_ATTR_MAX                                        = 0x135
+	NL80211_ATTR_MAX                                        = 0x137
 	NL80211_ATTR_MAX_CRIT_PROT_DURATION                     = 0xb4
 	NL80211_ATTR_MAX_CSA_COUNTERS                           = 0xce
 	NL80211_ATTR_MAX_MATCH_SETS                             = 0x85
@@ -4549,7 +4563,7 @@
 	NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY                     = 0x3
 	NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE                     = 0x5
 	NL80211_BAND_IFTYPE_ATTR_IFTYPES                        = 0x1
-	NL80211_BAND_IFTYPE_ATTR_MAX                            = 0x7
+	NL80211_BAND_IFTYPE_ATTR_MAX                            = 0xb
 	NL80211_BAND_S1GHZ                                      = 0x4
 	NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE                 = 0x2
 	NL80211_BITRATE_ATTR_MAX                                = 0x2
@@ -4887,7 +4901,7 @@
 	NL80211_FREQUENCY_ATTR_GO_CONCURRENT                    = 0xf
 	NL80211_FREQUENCY_ATTR_INDOOR_ONLY                      = 0xe
 	NL80211_FREQUENCY_ATTR_IR_CONCURRENT                    = 0xf
-	NL80211_FREQUENCY_ATTR_MAX                              = 0x19
+	NL80211_FREQUENCY_ATTR_MAX                              = 0x1b
 	NL80211_FREQUENCY_ATTR_MAX_TX_POWER                     = 0x6
 	NL80211_FREQUENCY_ATTR_NO_10MHZ                         = 0x11
 	NL80211_FREQUENCY_ATTR_NO_160MHZ                        = 0xc
@@ -5254,7 +5268,7 @@
 	NL80211_RATE_INFO_HE_RU_ALLOC_52                        = 0x1
 	NL80211_RATE_INFO_HE_RU_ALLOC_996                       = 0x5
 	NL80211_RATE_INFO_HE_RU_ALLOC                           = 0x11
-	NL80211_RATE_INFO_MAX                                   = 0x11
+	NL80211_RATE_INFO_MAX                                   = 0x16
 	NL80211_RATE_INFO_MCS                                   = 0x2
 	NL80211_RATE_INFO_SHORT_GI                              = 0x4
 	NL80211_RATE_INFO_VHT_MCS                               = 0x6
@@ -5588,3 +5602,8 @@
 	FR_ACT_UNREACHABLE     = 0x7
 	FR_ACT_PROHIBIT        = 0x8
 )
+
+const (
+	AUDIT_NLGRP_NONE    = 0x0
+	AUDIT_NLGRP_READLOG = 0x1
+)
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_386.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_386.go
index 4948362..89c516a 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_386.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_386.go
@@ -1,4 +1,4 @@
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include -m32 linux/types.go | go run mkpost.go
+// cgo -godefs -objdir=/tmp/386/cgo -- -Wall -Werror -static -I/tmp/386/include -m32 linux/types.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build 386 && linux
@@ -254,6 +254,12 @@
 
 const _C__NSIG = 0x41
 
+const (
+	SIG_BLOCK   = 0x0
+	SIG_UNBLOCK = 0x1
+	SIG_SETMASK = 0x2
+)
+
 type Siginfo struct {
 	Signo int32
 	Errno int32
@@ -324,6 +330,13 @@
 	Ac_btime64                uint64
 	Compact_count             uint64
 	Compact_delay_total       uint64
+	Ac_tgid                   uint32
+	_                         [4]byte
+	Ac_tgetime                uint64
+	Ac_exe_dev                uint64
+	Ac_exe_inode              uint64
+	Wpcopy_count              uint64
+	Wpcopy_delay_total        uint64
 }
 
 type cpuMask uint32
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go
index f64345e..62b4fb2 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go
@@ -1,4 +1,4 @@
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include -m64 linux/types.go | go run mkpost.go
+// cgo -godefs -objdir=/tmp/amd64/cgo -- -Wall -Werror -static -I/tmp/amd64/include -m64 linux/types.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build amd64 && linux
@@ -269,6 +269,12 @@
 
 const _C__NSIG = 0x41
 
+const (
+	SIG_BLOCK   = 0x0
+	SIG_UNBLOCK = 0x1
+	SIG_SETMASK = 0x2
+)
+
 type Siginfo struct {
 	Signo int32
 	Errno int32
@@ -338,6 +344,12 @@
 	Ac_btime64                uint64
 	Compact_count             uint64
 	Compact_delay_total       uint64
+	Ac_tgid                   uint32
+	Ac_tgetime                uint64
+	Ac_exe_dev                uint64
+	Ac_exe_inode              uint64
+	Wpcopy_count              uint64
+	Wpcopy_delay_total        uint64
 }
 
 type cpuMask uint64
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go
index 72469c7..e86b358 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go
@@ -1,4 +1,4 @@
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include linux/types.go | go run mkpost.go
+// cgo -godefs -objdir=/tmp/arm/cgo -- -Wall -Werror -static -I/tmp/arm/include linux/types.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build arm && linux
@@ -245,6 +245,12 @@
 
 const _C__NSIG = 0x41
 
+const (
+	SIG_BLOCK   = 0x0
+	SIG_UNBLOCK = 0x1
+	SIG_SETMASK = 0x2
+)
+
 type Siginfo struct {
 	Signo int32
 	Errno int32
@@ -315,6 +321,13 @@
 	Ac_btime64                uint64
 	Compact_count             uint64
 	Compact_delay_total       uint64
+	Ac_tgid                   uint32
+	_                         [4]byte
+	Ac_tgetime                uint64
+	Ac_exe_dev                uint64
+	Ac_exe_inode              uint64
+	Wpcopy_count              uint64
+	Wpcopy_delay_total        uint64
 }
 
 type cpuMask uint32
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go
index 68f0722..6c6be4c 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go
@@ -1,4 +1,4 @@
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include -fsigned-char linux/types.go | go run mkpost.go
+// cgo -godefs -objdir=/tmp/arm64/cgo -- -Wall -Werror -static -I/tmp/arm64/include -fsigned-char linux/types.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build arm64 && linux
@@ -248,6 +248,12 @@
 
 const _C__NSIG = 0x41
 
+const (
+	SIG_BLOCK   = 0x0
+	SIG_UNBLOCK = 0x1
+	SIG_SETMASK = 0x2
+)
+
 type Siginfo struct {
 	Signo int32
 	Errno int32
@@ -317,6 +323,12 @@
 	Ac_btime64                uint64
 	Compact_count             uint64
 	Compact_delay_total       uint64
+	Ac_tgid                   uint32
+	Ac_tgetime                uint64
+	Ac_exe_dev                uint64
+	Ac_exe_inode              uint64
+	Wpcopy_count              uint64
+	Wpcopy_delay_total        uint64
 }
 
 type cpuMask uint64
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go
index 090ae46..4982ea3 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go
@@ -1,4 +1,4 @@
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include linux/types.go | go run mkpost.go
+// cgo -godefs -objdir=/tmp/loong64/cgo -- -Wall -Werror -static -I/tmp/loong64/include linux/types.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build loong64 && linux
@@ -249,6 +249,12 @@
 
 const _C__NSIG = 0x41
 
+const (
+	SIG_BLOCK   = 0x0
+	SIG_UNBLOCK = 0x1
+	SIG_SETMASK = 0x2
+)
+
 type Siginfo struct {
 	Signo int32
 	Errno int32
@@ -318,6 +324,12 @@
 	Ac_btime64                uint64
 	Compact_count             uint64
 	Compact_delay_total       uint64
+	Ac_tgid                   uint32
+	Ac_tgetime                uint64
+	Ac_exe_dev                uint64
+	Ac_exe_inode              uint64
+	Wpcopy_count              uint64
+	Wpcopy_delay_total        uint64
 }
 
 type cpuMask uint64
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go
index 03604cc..173141a 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go
@@ -1,4 +1,4 @@
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include linux/types.go | go run mkpost.go
+// cgo -godefs -objdir=/tmp/mips/cgo -- -Wall -Werror -static -I/tmp/mips/include linux/types.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build mips && linux
@@ -250,6 +250,12 @@
 
 const _C__NSIG = 0x80
 
+const (
+	SIG_BLOCK   = 0x1
+	SIG_UNBLOCK = 0x2
+	SIG_SETMASK = 0x3
+)
+
 type Siginfo struct {
 	Signo int32
 	Code  int32
@@ -320,6 +326,13 @@
 	Ac_btime64                uint64
 	Compact_count             uint64
 	Compact_delay_total       uint64
+	Ac_tgid                   uint32
+	_                         [4]byte
+	Ac_tgetime                uint64
+	Ac_exe_dev                uint64
+	Ac_exe_inode              uint64
+	Wpcopy_count              uint64
+	Wpcopy_delay_total        uint64
 }
 
 type cpuMask uint32
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go
index fe57a7b..93ae4c5 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go
@@ -1,4 +1,4 @@
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include linux/types.go | go run mkpost.go
+// cgo -godefs -objdir=/tmp/mips64/cgo -- -Wall -Werror -static -I/tmp/mips64/include linux/types.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build mips64 && linux
@@ -251,6 +251,12 @@
 
 const _C__NSIG = 0x80
 
+const (
+	SIG_BLOCK   = 0x1
+	SIG_UNBLOCK = 0x2
+	SIG_SETMASK = 0x3
+)
+
 type Siginfo struct {
 	Signo int32
 	Code  int32
@@ -320,6 +326,12 @@
 	Ac_btime64                uint64
 	Compact_count             uint64
 	Compact_delay_total       uint64
+	Ac_tgid                   uint32
+	Ac_tgetime                uint64
+	Ac_exe_dev                uint64
+	Ac_exe_inode              uint64
+	Wpcopy_count              uint64
+	Wpcopy_delay_total        uint64
 }
 
 type cpuMask uint64
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go
index 3f0db4d..4e4e510 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go
@@ -1,4 +1,4 @@
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include linux/types.go | go run mkpost.go
+// cgo -godefs -objdir=/tmp/mips64le/cgo -- -Wall -Werror -static -I/tmp/mips64le/include linux/types.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build mips64le && linux
@@ -251,6 +251,12 @@
 
 const _C__NSIG = 0x80
 
+const (
+	SIG_BLOCK   = 0x1
+	SIG_UNBLOCK = 0x2
+	SIG_SETMASK = 0x3
+)
+
 type Siginfo struct {
 	Signo int32
 	Code  int32
@@ -320,6 +326,12 @@
 	Ac_btime64                uint64
 	Compact_count             uint64
 	Compact_delay_total       uint64
+	Ac_tgid                   uint32
+	Ac_tgetime                uint64
+	Ac_exe_dev                uint64
+	Ac_exe_inode              uint64
+	Wpcopy_count              uint64
+	Wpcopy_delay_total        uint64
 }
 
 type cpuMask uint64
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go
index 70ecd3b..3f5ba01 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go
@@ -1,4 +1,4 @@
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include linux/types.go | go run mkpost.go
+// cgo -godefs -objdir=/tmp/mipsle/cgo -- -Wall -Werror -static -I/tmp/mipsle/include linux/types.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build mipsle && linux
@@ -250,6 +250,12 @@
 
 const _C__NSIG = 0x80
 
+const (
+	SIG_BLOCK   = 0x1
+	SIG_UNBLOCK = 0x2
+	SIG_SETMASK = 0x3
+)
+
 type Siginfo struct {
 	Signo int32
 	Code  int32
@@ -320,6 +326,13 @@
 	Ac_btime64                uint64
 	Compact_count             uint64
 	Compact_delay_total       uint64
+	Ac_tgid                   uint32
+	_                         [4]byte
+	Ac_tgetime                uint64
+	Ac_exe_dev                uint64
+	Ac_exe_inode              uint64
+	Wpcopy_count              uint64
+	Wpcopy_delay_total        uint64
 }
 
 type cpuMask uint32
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go
index 4e70012..71dfe7c 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go
@@ -1,4 +1,4 @@
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include linux/types.go | go run mkpost.go
+// cgo -godefs -objdir=/tmp/ppc/cgo -- -Wall -Werror -static -I/tmp/ppc/include linux/types.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build ppc && linux
@@ -257,6 +257,12 @@
 
 const _C__NSIG = 0x41
 
+const (
+	SIG_BLOCK   = 0x0
+	SIG_UNBLOCK = 0x1
+	SIG_SETMASK = 0x2
+)
+
 type Siginfo struct {
 	Signo int32
 	Errno int32
@@ -327,6 +333,13 @@
 	Ac_btime64                uint64
 	Compact_count             uint64
 	Compact_delay_total       uint64
+	Ac_tgid                   uint32
+	_                         [4]byte
+	Ac_tgetime                uint64
+	Ac_exe_dev                uint64
+	Ac_exe_inode              uint64
+	Wpcopy_count              uint64
+	Wpcopy_delay_total        uint64
 }
 
 type cpuMask uint32
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go
index 34a57c6..3a2b7f0 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go
@@ -1,4 +1,4 @@
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include linux/types.go | go run mkpost.go
+// cgo -godefs -objdir=/tmp/ppc64/cgo -- -Wall -Werror -static -I/tmp/ppc64/include linux/types.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build ppc64 && linux
@@ -258,6 +258,12 @@
 
 const _C__NSIG = 0x41
 
+const (
+	SIG_BLOCK   = 0x0
+	SIG_UNBLOCK = 0x1
+	SIG_SETMASK = 0x2
+)
+
 type Siginfo struct {
 	Signo int32
 	Errno int32
@@ -327,6 +333,12 @@
 	Ac_btime64                uint64
 	Compact_count             uint64
 	Compact_delay_total       uint64
+	Ac_tgid                   uint32
+	Ac_tgetime                uint64
+	Ac_exe_dev                uint64
+	Ac_exe_inode              uint64
+	Wpcopy_count              uint64
+	Wpcopy_delay_total        uint64
 }
 
 type cpuMask uint64
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go
index 6b84a47..a52d627 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go
@@ -1,4 +1,4 @@
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include linux/types.go | go run mkpost.go
+// cgo -godefs -objdir=/tmp/ppc64le/cgo -- -Wall -Werror -static -I/tmp/ppc64le/include linux/types.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build ppc64le && linux
@@ -258,6 +258,12 @@
 
 const _C__NSIG = 0x41
 
+const (
+	SIG_BLOCK   = 0x0
+	SIG_UNBLOCK = 0x1
+	SIG_SETMASK = 0x2
+)
+
 type Siginfo struct {
 	Signo int32
 	Errno int32
@@ -327,6 +333,12 @@
 	Ac_btime64                uint64
 	Compact_count             uint64
 	Compact_delay_total       uint64
+	Ac_tgid                   uint32
+	Ac_tgetime                uint64
+	Ac_exe_dev                uint64
+	Ac_exe_inode              uint64
+	Wpcopy_count              uint64
+	Wpcopy_delay_total        uint64
 }
 
 type cpuMask uint64
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go
index c4a305f..dfc007d 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go
@@ -1,4 +1,4 @@
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include linux/types.go | go run mkpost.go
+// cgo -godefs -objdir=/tmp/riscv64/cgo -- -Wall -Werror -static -I/tmp/riscv64/include linux/types.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build riscv64 && linux
@@ -276,6 +276,12 @@
 
 const _C__NSIG = 0x41
 
+const (
+	SIG_BLOCK   = 0x0
+	SIG_UNBLOCK = 0x1
+	SIG_SETMASK = 0x2
+)
+
 type Siginfo struct {
 	Signo int32
 	Errno int32
@@ -345,6 +351,12 @@
 	Ac_btime64                uint64
 	Compact_count             uint64
 	Compact_delay_total       uint64
+	Ac_tgid                   uint32
+	Ac_tgetime                uint64
+	Ac_exe_dev                uint64
+	Ac_exe_inode              uint64
+	Wpcopy_count              uint64
+	Wpcopy_delay_total        uint64
 }
 
 type cpuMask uint64
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go
index a1f1e4c..b53cb91 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go
@@ -1,4 +1,4 @@
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include -fsigned-char linux/types.go | go run mkpost.go
+// cgo -godefs -objdir=/tmp/s390x/cgo -- -Wall -Werror -static -I/tmp/s390x/include -fsigned-char linux/types.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build s390x && linux
@@ -271,6 +271,12 @@
 
 const _C__NSIG = 0x41
 
+const (
+	SIG_BLOCK   = 0x0
+	SIG_UNBLOCK = 0x1
+	SIG_SETMASK = 0x2
+)
+
 type Siginfo struct {
 	Signo int32
 	Errno int32
@@ -340,6 +346,12 @@
 	Ac_btime64                uint64
 	Compact_count             uint64
 	Compact_delay_total       uint64
+	Ac_tgid                   uint32
+	Ac_tgetime                uint64
+	Ac_exe_dev                uint64
+	Ac_exe_inode              uint64
+	Wpcopy_count              uint64
+	Wpcopy_delay_total        uint64
 }
 
 type cpuMask uint64
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go
index df95ebf..fe0aa35 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go
@@ -1,4 +1,4 @@
-// cgo -godefs -- -Wall -Werror -static -I/tmp/include linux/types.go | go run mkpost.go
+// cgo -godefs -objdir=/tmp/sparc64/cgo -- -Wall -Werror -static -I/tmp/sparc64/include linux/types.go | go run mkpost.go
 // Code generated by the command above; see README.md. DO NOT EDIT.
 
 //go:build sparc64 && linux
@@ -253,6 +253,12 @@
 
 const _C__NSIG = 0x41
 
+const (
+	SIG_BLOCK   = 0x1
+	SIG_UNBLOCK = 0x2
+	SIG_SETMASK = 0x4
+)
+
 type Siginfo struct {
 	Signo int32
 	Errno int32
@@ -322,6 +328,12 @@
 	Ac_btime64                uint64
 	Compact_count             uint64
 	Compact_delay_total       uint64
+	Ac_tgid                   uint32
+	Ac_tgetime                uint64
+	Ac_exe_dev                uint64
+	Ac_exe_inode              uint64
+	Wpcopy_count              uint64
+	Wpcopy_delay_total        uint64
 }
 
 type cpuMask uint64
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_openbsd_ppc64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_openbsd_ppc64.go
new file mode 100644
index 0000000..d6724c0
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_openbsd_ppc64.go
@@ -0,0 +1,571 @@
+// cgo -godefs -- -fsigned-char types_openbsd.go | go run mkpost.go
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+//go:build ppc64 && openbsd
+// +build ppc64,openbsd
+
+package unix
+
+const (
+	SizeofPtr      = 0x8
+	SizeofShort    = 0x2
+	SizeofInt      = 0x4
+	SizeofLong     = 0x8
+	SizeofLongLong = 0x8
+)
+
+type (
+	_C_short     int16
+	_C_int       int32
+	_C_long      int64
+	_C_long_long int64
+)
+
+type Timespec struct {
+	Sec  int64
+	Nsec int64
+}
+
+type Timeval struct {
+	Sec  int64
+	Usec int64
+}
+
+type Rusage struct {
+	Utime    Timeval
+	Stime    Timeval
+	Maxrss   int64
+	Ixrss    int64
+	Idrss    int64
+	Isrss    int64
+	Minflt   int64
+	Majflt   int64
+	Nswap    int64
+	Inblock  int64
+	Oublock  int64
+	Msgsnd   int64
+	Msgrcv   int64
+	Nsignals int64
+	Nvcsw    int64
+	Nivcsw   int64
+}
+
+type Rlimit struct {
+	Cur uint64
+	Max uint64
+}
+
+type _Gid_t uint32
+
+type Stat_t struct {
+	Mode    uint32
+	Dev     int32
+	Ino     uint64
+	Nlink   uint32
+	Uid     uint32
+	Gid     uint32
+	Rdev    int32
+	Atim    Timespec
+	Mtim    Timespec
+	Ctim    Timespec
+	Size    int64
+	Blocks  int64
+	Blksize int32
+	Flags   uint32
+	Gen     uint32
+	_       Timespec
+}
+
+type Statfs_t struct {
+	F_flags       uint32
+	F_bsize       uint32
+	F_iosize      uint32
+	F_blocks      uint64
+	F_bfree       uint64
+	F_bavail      int64
+	F_files       uint64
+	F_ffree       uint64
+	F_favail      int64
+	F_syncwrites  uint64
+	F_syncreads   uint64
+	F_asyncwrites uint64
+	F_asyncreads  uint64
+	F_fsid        Fsid
+	F_namemax     uint32
+	F_owner       uint32
+	F_ctime       uint64
+	F_fstypename  [16]byte
+	F_mntonname   [90]byte
+	F_mntfromname [90]byte
+	F_mntfromspec [90]byte
+	_             [2]byte
+	Mount_info    [160]byte
+}
+
+type Flock_t struct {
+	Start  int64
+	Len    int64
+	Pid    int32
+	Type   int16
+	Whence int16
+}
+
+type Dirent struct {
+	Fileno uint64
+	Off    int64
+	Reclen uint16
+	Type   uint8
+	Namlen uint8
+	_      [4]uint8
+	Name   [256]int8
+}
+
+type Fsid struct {
+	Val [2]int32
+}
+
+const (
+	PathMax = 0x400
+)
+
+type RawSockaddrInet4 struct {
+	Len    uint8
+	Family uint8
+	Port   uint16
+	Addr   [4]byte /* in_addr */
+	Zero   [8]int8
+}
+
+type RawSockaddrInet6 struct {
+	Len      uint8
+	Family   uint8
+	Port     uint16
+	Flowinfo uint32
+	Addr     [16]byte /* in6_addr */
+	Scope_id uint32
+}
+
+type RawSockaddrUnix struct {
+	Len    uint8
+	Family uint8
+	Path   [104]int8
+}
+
+type RawSockaddrDatalink struct {
+	Len    uint8
+	Family uint8
+	Index  uint16
+	Type   uint8
+	Nlen   uint8
+	Alen   uint8
+	Slen   uint8
+	Data   [24]int8
+}
+
+type RawSockaddr struct {
+	Len    uint8
+	Family uint8
+	Data   [14]int8
+}
+
+type RawSockaddrAny struct {
+	Addr RawSockaddr
+	Pad  [92]int8
+}
+
+type _Socklen uint32
+
+type Linger struct {
+	Onoff  int32
+	Linger int32
+}
+
+type Iovec struct {
+	Base *byte
+	Len  uint64
+}
+
+type IPMreq struct {
+	Multiaddr [4]byte /* in_addr */
+	Interface [4]byte /* in_addr */
+}
+
+type IPv6Mreq struct {
+	Multiaddr [16]byte /* in6_addr */
+	Interface uint32
+}
+
+type Msghdr struct {
+	Name       *byte
+	Namelen    uint32
+	Iov        *Iovec
+	Iovlen     uint32
+	Control    *byte
+	Controllen uint32
+	Flags      int32
+}
+
+type Cmsghdr struct {
+	Len   uint32
+	Level int32
+	Type  int32
+}
+
+type Inet6Pktinfo struct {
+	Addr    [16]byte /* in6_addr */
+	Ifindex uint32
+}
+
+type IPv6MTUInfo struct {
+	Addr RawSockaddrInet6
+	Mtu  uint32
+}
+
+type ICMPv6Filter struct {
+	Filt [8]uint32
+}
+
+const (
+	SizeofSockaddrInet4    = 0x10
+	SizeofSockaddrInet6    = 0x1c
+	SizeofSockaddrAny      = 0x6c
+	SizeofSockaddrUnix     = 0x6a
+	SizeofSockaddrDatalink = 0x20
+	SizeofLinger           = 0x8
+	SizeofIovec            = 0x10
+	SizeofIPMreq           = 0x8
+	SizeofIPv6Mreq         = 0x14
+	SizeofMsghdr           = 0x30
+	SizeofCmsghdr          = 0xc
+	SizeofInet6Pktinfo     = 0x14
+	SizeofIPv6MTUInfo      = 0x20
+	SizeofICMPv6Filter     = 0x20
+)
+
+const (
+	PTRACE_TRACEME = 0x0
+	PTRACE_CONT    = 0x7
+	PTRACE_KILL    = 0x8
+)
+
+type Kevent_t struct {
+	Ident  uint64
+	Filter int16
+	Flags  uint16
+	Fflags uint32
+	Data   int64
+	Udata  *byte
+}
+
+type FdSet struct {
+	Bits [32]uint32
+}
+
+const (
+	SizeofIfMsghdr         = 0xa8
+	SizeofIfData           = 0x90
+	SizeofIfaMsghdr        = 0x18
+	SizeofIfAnnounceMsghdr = 0x1a
+	SizeofRtMsghdr         = 0x60
+	SizeofRtMetrics        = 0x38
+)
+
+type IfMsghdr struct {
+	Msglen  uint16
+	Version uint8
+	Type    uint8
+	Hdrlen  uint16
+	Index   uint16
+	Tableid uint16
+	Pad1    uint8
+	Pad2    uint8
+	Addrs   int32
+	Flags   int32
+	Xflags  int32
+	Data    IfData
+}
+
+type IfData struct {
+	Type         uint8
+	Addrlen      uint8
+	Hdrlen       uint8
+	Link_state   uint8
+	Mtu          uint32
+	Metric       uint32
+	Rdomain      uint32
+	Baudrate     uint64
+	Ipackets     uint64
+	Ierrors      uint64
+	Opackets     uint64
+	Oerrors      uint64
+	Collisions   uint64
+	Ibytes       uint64
+	Obytes       uint64
+	Imcasts      uint64
+	Omcasts      uint64
+	Iqdrops      uint64
+	Oqdrops      uint64
+	Noproto      uint64
+	Capabilities uint32
+	Lastchange   Timeval
+}
+
+type IfaMsghdr struct {
+	Msglen  uint16
+	Version uint8
+	Type    uint8
+	Hdrlen  uint16
+	Index   uint16
+	Tableid uint16
+	Pad1    uint8
+	Pad2    uint8
+	Addrs   int32
+	Flags   int32
+	Metric  int32
+}
+
+type IfAnnounceMsghdr struct {
+	Msglen  uint16
+	Version uint8
+	Type    uint8
+	Hdrlen  uint16
+	Index   uint16
+	What    uint16
+	Name    [16]int8
+}
+
+type RtMsghdr struct {
+	Msglen   uint16
+	Version  uint8
+	Type     uint8
+	Hdrlen   uint16
+	Index    uint16
+	Tableid  uint16
+	Priority uint8
+	Mpls     uint8
+	Addrs    int32
+	Flags    int32
+	Fmask    int32
+	Pid      int32
+	Seq      int32
+	Errno    int32
+	Inits    uint32
+	Rmx      RtMetrics
+}
+
+type RtMetrics struct {
+	Pksent   uint64
+	Expire   int64
+	Locks    uint32
+	Mtu      uint32
+	Refcnt   uint32
+	Hopcount uint32
+	Recvpipe uint32
+	Sendpipe uint32
+	Ssthresh uint32
+	Rtt      uint32
+	Rttvar   uint32
+	Pad      uint32
+}
+
+type Mclpool struct{}
+
+const (
+	SizeofBpfVersion = 0x4
+	SizeofBpfStat    = 0x8
+	SizeofBpfProgram = 0x10
+	SizeofBpfInsn    = 0x8
+	SizeofBpfHdr     = 0x18
+)
+
+type BpfVersion struct {
+	Major uint16
+	Minor uint16
+}
+
+type BpfStat struct {
+	Recv uint32
+	Drop uint32
+}
+
+type BpfProgram struct {
+	Len   uint32
+	Insns *BpfInsn
+}
+
+type BpfInsn struct {
+	Code uint16
+	Jt   uint8
+	Jf   uint8
+	K    uint32
+}
+
+type BpfHdr struct {
+	Tstamp  BpfTimeval
+	Caplen  uint32
+	Datalen uint32
+	Hdrlen  uint16
+	Ifidx   uint16
+	Flowid  uint16
+	Flags   uint8
+	Drops   uint8
+}
+
+type BpfTimeval struct {
+	Sec  uint32
+	Usec uint32
+}
+
+type Termios struct {
+	Iflag  uint32
+	Oflag  uint32
+	Cflag  uint32
+	Lflag  uint32
+	Cc     [20]uint8
+	Ispeed int32
+	Ospeed int32
+}
+
+type Winsize struct {
+	Row    uint16
+	Col    uint16
+	Xpixel uint16
+	Ypixel uint16
+}
+
+const (
+	AT_FDCWD            = -0x64
+	AT_EACCESS          = 0x1
+	AT_SYMLINK_NOFOLLOW = 0x2
+	AT_SYMLINK_FOLLOW   = 0x4
+	AT_REMOVEDIR        = 0x8
+)
+
+type PollFd struct {
+	Fd      int32
+	Events  int16
+	Revents int16
+}
+
+const (
+	POLLERR    = 0x8
+	POLLHUP    = 0x10
+	POLLIN     = 0x1
+	POLLNVAL   = 0x20
+	POLLOUT    = 0x4
+	POLLPRI    = 0x2
+	POLLRDBAND = 0x80
+	POLLRDNORM = 0x40
+	POLLWRBAND = 0x100
+	POLLWRNORM = 0x4
+)
+
+type Sigset_t uint32
+
+type Utsname struct {
+	Sysname  [256]byte
+	Nodename [256]byte
+	Release  [256]byte
+	Version  [256]byte
+	Machine  [256]byte
+}
+
+const SizeofUvmexp = 0x158
+
+type Uvmexp struct {
+	Pagesize           int32
+	Pagemask           int32
+	Pageshift          int32
+	Npages             int32
+	Free               int32
+	Active             int32
+	Inactive           int32
+	Paging             int32
+	Wired              int32
+	Zeropages          int32
+	Reserve_pagedaemon int32
+	Reserve_kernel     int32
+	Unused01           int32
+	Vnodepages         int32
+	Vtextpages         int32
+	Freemin            int32
+	Freetarg           int32
+	Inactarg           int32
+	Wiredmax           int32
+	Anonmin            int32
+	Vtextmin           int32
+	Vnodemin           int32
+	Anonminpct         int32
+	Vtextminpct        int32
+	Vnodeminpct        int32
+	Nswapdev           int32
+	Swpages            int32
+	Swpginuse          int32
+	Swpgonly           int32
+	Nswget             int32
+	Nanon              int32
+	Unused05           int32
+	Unused06           int32
+	Faults             int32
+	Traps              int32
+	Intrs              int32
+	Swtch              int32
+	Softs              int32
+	Syscalls           int32
+	Pageins            int32
+	Unused07           int32
+	Unused08           int32
+	Pgswapin           int32
+	Pgswapout          int32
+	Forks              int32
+	Forks_ppwait       int32
+	Forks_sharevm      int32
+	Pga_zerohit        int32
+	Pga_zeromiss       int32
+	Unused09           int32
+	Fltnoram           int32
+	Fltnoanon          int32
+	Fltnoamap          int32
+	Fltpgwait          int32
+	Fltpgrele          int32
+	Fltrelck           int32
+	Fltrelckok         int32
+	Fltanget           int32
+	Fltanretry         int32
+	Fltamcopy          int32
+	Fltnamap           int32
+	Fltnomap           int32
+	Fltlget            int32
+	Fltget             int32
+	Flt_anon           int32
+	Flt_acow           int32
+	Flt_obj            int32
+	Flt_prcopy         int32
+	Flt_przero         int32
+	Pdwoke             int32
+	Pdrevs             int32
+	Pdswout            int32
+	Pdfreed            int32
+	Pdscans            int32
+	Pdanscan           int32
+	Pdobscan           int32
+	Pdreact            int32
+	Pdbusy             int32
+	Pdpageouts         int32
+	Pdpending          int32
+	Pddeact            int32
+	Unused11           int32
+	Unused12           int32
+	Unused13           int32
+	Fpswtch            int32
+	Kmapent            int32
+}
+
+const SizeofClockinfo = 0x10
+
+type Clockinfo struct {
+	Hz     int32
+	Tick   int32
+	Stathz int32
+	Profhz int32
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_openbsd_riscv64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_openbsd_riscv64.go
new file mode 100644
index 0000000..ddfd27a
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_openbsd_riscv64.go
@@ -0,0 +1,571 @@
+// cgo -godefs -- -fsigned-char types_openbsd.go | go run mkpost.go
+// Code generated by the command above; see README.md. DO NOT EDIT.
+
+//go:build riscv64 && openbsd
+// +build riscv64,openbsd
+
+package unix
+
+const (
+	SizeofPtr      = 0x8
+	SizeofShort    = 0x2
+	SizeofInt      = 0x4
+	SizeofLong     = 0x8
+	SizeofLongLong = 0x8
+)
+
+type (
+	_C_short     int16
+	_C_int       int32
+	_C_long      int64
+	_C_long_long int64
+)
+
+type Timespec struct {
+	Sec  int64
+	Nsec int64
+}
+
+type Timeval struct {
+	Sec  int64
+	Usec int64
+}
+
+type Rusage struct {
+	Utime    Timeval
+	Stime    Timeval
+	Maxrss   int64
+	Ixrss    int64
+	Idrss    int64
+	Isrss    int64
+	Minflt   int64
+	Majflt   int64
+	Nswap    int64
+	Inblock  int64
+	Oublock  int64
+	Msgsnd   int64
+	Msgrcv   int64
+	Nsignals int64
+	Nvcsw    int64
+	Nivcsw   int64
+}
+
+type Rlimit struct {
+	Cur uint64
+	Max uint64
+}
+
+type _Gid_t uint32
+
+type Stat_t struct {
+	Mode    uint32
+	Dev     int32
+	Ino     uint64
+	Nlink   uint32
+	Uid     uint32
+	Gid     uint32
+	Rdev    int32
+	Atim    Timespec
+	Mtim    Timespec
+	Ctim    Timespec
+	Size    int64
+	Blocks  int64
+	Blksize int32
+	Flags   uint32
+	Gen     uint32
+	_       Timespec
+}
+
+type Statfs_t struct {
+	F_flags       uint32
+	F_bsize       uint32
+	F_iosize      uint32
+	F_blocks      uint64
+	F_bfree       uint64
+	F_bavail      int64
+	F_files       uint64
+	F_ffree       uint64
+	F_favail      int64
+	F_syncwrites  uint64
+	F_syncreads   uint64
+	F_asyncwrites uint64
+	F_asyncreads  uint64
+	F_fsid        Fsid
+	F_namemax     uint32
+	F_owner       uint32
+	F_ctime       uint64
+	F_fstypename  [16]byte
+	F_mntonname   [90]byte
+	F_mntfromname [90]byte
+	F_mntfromspec [90]byte
+	_             [2]byte
+	Mount_info    [160]byte
+}
+
+type Flock_t struct {
+	Start  int64
+	Len    int64
+	Pid    int32
+	Type   int16
+	Whence int16
+}
+
+type Dirent struct {
+	Fileno uint64
+	Off    int64
+	Reclen uint16
+	Type   uint8
+	Namlen uint8
+	_      [4]uint8
+	Name   [256]int8
+}
+
+type Fsid struct {
+	Val [2]int32
+}
+
+const (
+	PathMax = 0x400
+)
+
+type RawSockaddrInet4 struct {
+	Len    uint8
+	Family uint8
+	Port   uint16
+	Addr   [4]byte /* in_addr */
+	Zero   [8]int8
+}
+
+type RawSockaddrInet6 struct {
+	Len      uint8
+	Family   uint8
+	Port     uint16
+	Flowinfo uint32
+	Addr     [16]byte /* in6_addr */
+	Scope_id uint32
+}
+
+type RawSockaddrUnix struct {
+	Len    uint8
+	Family uint8
+	Path   [104]int8
+}
+
+type RawSockaddrDatalink struct {
+	Len    uint8
+	Family uint8
+	Index  uint16
+	Type   uint8
+	Nlen   uint8
+	Alen   uint8
+	Slen   uint8
+	Data   [24]int8
+}
+
+type RawSockaddr struct {
+	Len    uint8
+	Family uint8
+	Data   [14]int8
+}
+
+type RawSockaddrAny struct {
+	Addr RawSockaddr
+	Pad  [92]int8
+}
+
+type _Socklen uint32
+
+type Linger struct {
+	Onoff  int32
+	Linger int32
+}
+
+type Iovec struct {
+	Base *byte
+	Len  uint64
+}
+
+type IPMreq struct {
+	Multiaddr [4]byte /* in_addr */
+	Interface [4]byte /* in_addr */
+}
+
+type IPv6Mreq struct {
+	Multiaddr [16]byte /* in6_addr */
+	Interface uint32
+}
+
+type Msghdr struct {
+	Name       *byte
+	Namelen    uint32
+	Iov        *Iovec
+	Iovlen     uint32
+	Control    *byte
+	Controllen uint32
+	Flags      int32
+}
+
+type Cmsghdr struct {
+	Len   uint32
+	Level int32
+	Type  int32
+}
+
+type Inet6Pktinfo struct {
+	Addr    [16]byte /* in6_addr */
+	Ifindex uint32
+}
+
+type IPv6MTUInfo struct {
+	Addr RawSockaddrInet6
+	Mtu  uint32
+}
+
+type ICMPv6Filter struct {
+	Filt [8]uint32
+}
+
+const (
+	SizeofSockaddrInet4    = 0x10
+	SizeofSockaddrInet6    = 0x1c
+	SizeofSockaddrAny      = 0x6c
+	SizeofSockaddrUnix     = 0x6a
+	SizeofSockaddrDatalink = 0x20
+	SizeofLinger           = 0x8
+	SizeofIovec            = 0x10
+	SizeofIPMreq           = 0x8
+	SizeofIPv6Mreq         = 0x14
+	SizeofMsghdr           = 0x30
+	SizeofCmsghdr          = 0xc
+	SizeofInet6Pktinfo     = 0x14
+	SizeofIPv6MTUInfo      = 0x20
+	SizeofICMPv6Filter     = 0x20
+)
+
+const (
+	PTRACE_TRACEME = 0x0
+	PTRACE_CONT    = 0x7
+	PTRACE_KILL    = 0x8
+)
+
+type Kevent_t struct {
+	Ident  uint64
+	Filter int16
+	Flags  uint16
+	Fflags uint32
+	Data   int64
+	Udata  *byte
+}
+
+type FdSet struct {
+	Bits [32]uint32
+}
+
+const (
+	SizeofIfMsghdr         = 0xa8
+	SizeofIfData           = 0x90
+	SizeofIfaMsghdr        = 0x18
+	SizeofIfAnnounceMsghdr = 0x1a
+	SizeofRtMsghdr         = 0x60
+	SizeofRtMetrics        = 0x38
+)
+
+type IfMsghdr struct {
+	Msglen  uint16
+	Version uint8
+	Type    uint8
+	Hdrlen  uint16
+	Index   uint16
+	Tableid uint16
+	Pad1    uint8
+	Pad2    uint8
+	Addrs   int32
+	Flags   int32
+	Xflags  int32
+	Data    IfData
+}
+
+type IfData struct {
+	Type         uint8
+	Addrlen      uint8
+	Hdrlen       uint8
+	Link_state   uint8
+	Mtu          uint32
+	Metric       uint32
+	Rdomain      uint32
+	Baudrate     uint64
+	Ipackets     uint64
+	Ierrors      uint64
+	Opackets     uint64
+	Oerrors      uint64
+	Collisions   uint64
+	Ibytes       uint64
+	Obytes       uint64
+	Imcasts      uint64
+	Omcasts      uint64
+	Iqdrops      uint64
+	Oqdrops      uint64
+	Noproto      uint64
+	Capabilities uint32
+	Lastchange   Timeval
+}
+
+type IfaMsghdr struct {
+	Msglen  uint16
+	Version uint8
+	Type    uint8
+	Hdrlen  uint16
+	Index   uint16
+	Tableid uint16
+	Pad1    uint8
+	Pad2    uint8
+	Addrs   int32
+	Flags   int32
+	Metric  int32
+}
+
+type IfAnnounceMsghdr struct {
+	Msglen  uint16
+	Version uint8
+	Type    uint8
+	Hdrlen  uint16
+	Index   uint16
+	What    uint16
+	Name    [16]int8
+}
+
+type RtMsghdr struct {
+	Msglen   uint16
+	Version  uint8
+	Type     uint8
+	Hdrlen   uint16
+	Index    uint16
+	Tableid  uint16
+	Priority uint8
+	Mpls     uint8
+	Addrs    int32
+	Flags    int32
+	Fmask    int32
+	Pid      int32
+	Seq      int32
+	Errno    int32
+	Inits    uint32
+	Rmx      RtMetrics
+}
+
+type RtMetrics struct {
+	Pksent   uint64
+	Expire   int64
+	Locks    uint32
+	Mtu      uint32
+	Refcnt   uint32
+	Hopcount uint32
+	Recvpipe uint32
+	Sendpipe uint32
+	Ssthresh uint32
+	Rtt      uint32
+	Rttvar   uint32
+	Pad      uint32
+}
+
+type Mclpool struct{}
+
+const (
+	SizeofBpfVersion = 0x4
+	SizeofBpfStat    = 0x8
+	SizeofBpfProgram = 0x10
+	SizeofBpfInsn    = 0x8
+	SizeofBpfHdr     = 0x18
+)
+
+type BpfVersion struct {
+	Major uint16
+	Minor uint16
+}
+
+type BpfStat struct {
+	Recv uint32
+	Drop uint32
+}
+
+type BpfProgram struct {
+	Len   uint32
+	Insns *BpfInsn
+}
+
+type BpfInsn struct {
+	Code uint16
+	Jt   uint8
+	Jf   uint8
+	K    uint32
+}
+
+type BpfHdr struct {
+	Tstamp  BpfTimeval
+	Caplen  uint32
+	Datalen uint32
+	Hdrlen  uint16
+	Ifidx   uint16
+	Flowid  uint16
+	Flags   uint8
+	Drops   uint8
+}
+
+type BpfTimeval struct {
+	Sec  uint32
+	Usec uint32
+}
+
+type Termios struct {
+	Iflag  uint32
+	Oflag  uint32
+	Cflag  uint32
+	Lflag  uint32
+	Cc     [20]uint8
+	Ispeed int32
+	Ospeed int32
+}
+
+type Winsize struct {
+	Row    uint16
+	Col    uint16
+	Xpixel uint16
+	Ypixel uint16
+}
+
+const (
+	AT_FDCWD            = -0x64
+	AT_EACCESS          = 0x1
+	AT_SYMLINK_NOFOLLOW = 0x2
+	AT_SYMLINK_FOLLOW   = 0x4
+	AT_REMOVEDIR        = 0x8
+)
+
+type PollFd struct {
+	Fd      int32
+	Events  int16
+	Revents int16
+}
+
+const (
+	POLLERR    = 0x8
+	POLLHUP    = 0x10
+	POLLIN     = 0x1
+	POLLNVAL   = 0x20
+	POLLOUT    = 0x4
+	POLLPRI    = 0x2
+	POLLRDBAND = 0x80
+	POLLRDNORM = 0x40
+	POLLWRBAND = 0x100
+	POLLWRNORM = 0x4
+)
+
+type Sigset_t uint32
+
+type Utsname struct {
+	Sysname  [256]byte
+	Nodename [256]byte
+	Release  [256]byte
+	Version  [256]byte
+	Machine  [256]byte
+}
+
+const SizeofUvmexp = 0x158
+
+type Uvmexp struct {
+	Pagesize           int32
+	Pagemask           int32
+	Pageshift          int32
+	Npages             int32
+	Free               int32
+	Active             int32
+	Inactive           int32
+	Paging             int32
+	Wired              int32
+	Zeropages          int32
+	Reserve_pagedaemon int32
+	Reserve_kernel     int32
+	Unused01           int32
+	Vnodepages         int32
+	Vtextpages         int32
+	Freemin            int32
+	Freetarg           int32
+	Inactarg           int32
+	Wiredmax           int32
+	Anonmin            int32
+	Vtextmin           int32
+	Vnodemin           int32
+	Anonminpct         int32
+	Vtextminpct        int32
+	Vnodeminpct        int32
+	Nswapdev           int32
+	Swpages            int32
+	Swpginuse          int32
+	Swpgonly           int32
+	Nswget             int32
+	Nanon              int32
+	Unused05           int32
+	Unused06           int32
+	Faults             int32
+	Traps              int32
+	Intrs              int32
+	Swtch              int32
+	Softs              int32
+	Syscalls           int32
+	Pageins            int32
+	Unused07           int32
+	Unused08           int32
+	Pgswapin           int32
+	Pgswapout          int32
+	Forks              int32
+	Forks_ppwait       int32
+	Forks_sharevm      int32
+	Pga_zerohit        int32
+	Pga_zeromiss       int32
+	Unused09           int32
+	Fltnoram           int32
+	Fltnoanon          int32
+	Fltnoamap          int32
+	Fltpgwait          int32
+	Fltpgrele          int32
+	Fltrelck           int32
+	Fltrelckok         int32
+	Fltanget           int32
+	Fltanretry         int32
+	Fltamcopy          int32
+	Fltnamap           int32
+	Fltnomap           int32
+	Fltlget            int32
+	Fltget             int32
+	Flt_anon           int32
+	Flt_acow           int32
+	Flt_obj            int32
+	Flt_prcopy         int32
+	Flt_przero         int32
+	Pdwoke             int32
+	Pdrevs             int32
+	Pdswout            int32
+	Pdfreed            int32
+	Pdscans            int32
+	Pdanscan           int32
+	Pdobscan           int32
+	Pdreact            int32
+	Pdbusy             int32
+	Pdpageouts         int32
+	Pdpending          int32
+	Pddeact            int32
+	Unused11           int32
+	Unused12           int32
+	Unused13           int32
+	Fpswtch            int32
+	Kmapent            int32
+}
+
+const SizeofClockinfo = 0x10
+
+type Clockinfo struct {
+	Hz     int32
+	Tick   int32
+	Stathz int32
+	Profhz int32
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go
index ad4aad2..0400747 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_solaris_amd64.go
@@ -178,7 +178,7 @@
 }
 
 type Iovec struct {
-	Base *int8
+	Base *byte
 	Len  uint64
 }
 
@@ -480,3 +480,38 @@
 	MOUNTEDOVER        = 0x40000000
 	FILE_EXCEPTION     = 0x60000070
 )
+
+const (
+	TUNNEWPPA = 0x540001
+	TUNSETPPA = 0x540002
+
+	I_STR     = 0x5308
+	I_POP     = 0x5303
+	I_PUSH    = 0x5302
+	I_LINK    = 0x530c
+	I_UNLINK  = 0x530d
+	I_PLINK   = 0x5316
+	I_PUNLINK = 0x5317
+
+	IF_UNITSEL = -0x7ffb8cca
+)
+
+type strbuf struct {
+	Maxlen int32
+	Len    int32
+	Buf    *int8
+}
+
+type Strioctl struct {
+	Cmd    int32
+	Timout int32
+	Len    int32
+	Dp     *int8
+}
+
+type Lifreq struct {
+	Name   [32]int8
+	Lifru1 [4]byte
+	Type   uint32
+	Lifru  [336]byte
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_zos_s390x.go b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_zos_s390x.go
index 4ab638c..aec1efc 100644
--- a/src/cmd/vendor/golang.org/x/sys/unix/ztypes_zos_s390x.go
+++ b/src/cmd/vendor/golang.org/x/sys/unix/ztypes_zos_s390x.go
@@ -339,7 +339,7 @@
 	Flags   uint64
 }
 
-type Dirent struct {
+type direntLE struct {
 	Reclen uint16
 	Namlen uint16
 	Ino    uint32
@@ -347,6 +347,15 @@
 	Name   [256]byte
 }
 
+type Dirent struct {
+	Ino    uint64
+	Off    int64
+	Reclen uint16
+	Type   uint8
+	Name   [256]uint8
+	_      [5]byte
+}
+
 type FdSet struct {
 	Bits [64]int32
 }
diff --git a/src/cmd/vendor/golang.org/x/sys/windows/setupapi_windows.go b/src/cmd/vendor/golang.org/x/sys/windows/setupapi_windows.go
index 14027da..f812648 100644
--- a/src/cmd/vendor/golang.org/x/sys/windows/setupapi_windows.go
+++ b/src/cmd/vendor/golang.org/x/sys/windows/setupapi_windows.go
@@ -296,7 +296,7 @@
 	// Flag to indicate that the sorting from the INF file should be used.
 	DI_INF_IS_SORTED DI_FLAGS = 0x00008000
 
-	// Flag to indicate that only the the INF specified by SP_DEVINSTALL_PARAMS.DriverPath should be searched.
+	// Flag to indicate that only the INF specified by SP_DEVINSTALL_PARAMS.DriverPath should be searched.
 	DI_ENUMSINGLEINF DI_FLAGS = 0x00010000
 
 	// Flag that prevents ConfigMgr from removing/re-enumerating devices during device
diff --git a/src/cmd/vendor/golang.org/x/sys/windows/syscall.go b/src/cmd/vendor/golang.org/x/sys/windows/syscall.go
index 72074d5..8732cdb 100644
--- a/src/cmd/vendor/golang.org/x/sys/windows/syscall.go
+++ b/src/cmd/vendor/golang.org/x/sys/windows/syscall.go
@@ -30,8 +30,6 @@
 	"strings"
 	"syscall"
 	"unsafe"
-
-	"golang.org/x/sys/internal/unsafeheader"
 )
 
 // ByteSliceFromString returns a NUL-terminated slice of bytes
@@ -83,13 +81,7 @@
 		ptr = unsafe.Pointer(uintptr(ptr) + 1)
 	}
 
-	var s []byte
-	h := (*unsafeheader.Slice)(unsafe.Pointer(&s))
-	h.Data = unsafe.Pointer(p)
-	h.Len = n
-	h.Cap = n
-
-	return string(s)
+	return string(unsafe.Slice(p, n))
 }
 
 // Single-word zero for use when we need a valid pointer to 0 bytes.
diff --git a/src/cmd/vendor/golang.org/x/sys/windows/syscall_windows.go b/src/cmd/vendor/golang.org/x/sys/windows/syscall_windows.go
index 636e5de..a49853e 100644
--- a/src/cmd/vendor/golang.org/x/sys/windows/syscall_windows.go
+++ b/src/cmd/vendor/golang.org/x/sys/windows/syscall_windows.go
@@ -138,13 +138,7 @@
 		ptr = unsafe.Pointer(uintptr(ptr) + unsafe.Sizeof(*p))
 	}
 
-	var s []uint16
-	h := (*unsafeheader.Slice)(unsafe.Pointer(&s))
-	h.Data = unsafe.Pointer(p)
-	h.Len = n
-	h.Cap = n
-
-	return string(utf16.Decode(s))
+	return string(utf16.Decode(unsafe.Slice(p, n)))
 }
 
 func Getpagesize() int { return 4096 }
@@ -364,6 +358,16 @@
 //sys	SetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error)
 //sys	GetActiveProcessorCount(groupNumber uint16) (ret uint32)
 //sys	GetMaximumProcessorCount(groupNumber uint16) (ret uint32)
+//sys	EnumWindows(enumFunc uintptr, param unsafe.Pointer) (err error) = user32.EnumWindows
+//sys	EnumChildWindows(hwnd HWND, enumFunc uintptr, param unsafe.Pointer) = user32.EnumChildWindows
+//sys	GetClassName(hwnd HWND, className *uint16, maxCount int32) (copied int32, err error) = user32.GetClassNameW
+//sys	GetDesktopWindow() (hwnd HWND) = user32.GetDesktopWindow
+//sys	GetForegroundWindow() (hwnd HWND) = user32.GetForegroundWindow
+//sys	IsWindow(hwnd HWND) (isWindow bool) = user32.IsWindow
+//sys	IsWindowUnicode(hwnd HWND) (isUnicode bool) = user32.IsWindowUnicode
+//sys	IsWindowVisible(hwnd HWND) (isVisible bool) = user32.IsWindowVisible
+//sys	GetGUIThreadInfo(thread uint32, info *GUIThreadInfo) (err error) = user32.GetGUIThreadInfo
+//sys	GetLargePageMinimum() (size uintptr)
 
 // Volume Management Functions
 //sys	DefineDosDevice(flags uint32, deviceName *uint16, targetPath *uint16) (err error) = DefineDosDeviceW
@@ -417,6 +421,7 @@
 //sys	GetModuleInformation(process Handle, module Handle, modinfo *ModuleInfo, cb uint32) (err error) = psapi.GetModuleInformation
 //sys	GetModuleFileNameEx(process Handle, module Handle, filename *uint16, size uint32) (err error) = psapi.GetModuleFileNameExW
 //sys	GetModuleBaseName(process Handle, module Handle, baseName *uint16, size uint32) (err error) = psapi.GetModuleBaseNameW
+//sys   QueryWorkingSetEx(process Handle, pv uintptr, cb uint32) (err error) = psapi.QueryWorkingSetEx
 
 // NT Native APIs
 //sys	rtlNtStatusToDosErrorNoTeb(ntstatus NTStatus) (ret syscall.Errno) = ntdll.RtlNtStatusToDosErrorNoTeb
@@ -438,6 +443,10 @@
 //sys	RtlAddFunctionTable(functionTable *RUNTIME_FUNCTION, entryCount uint32, baseAddress uintptr) (ret bool) = ntdll.RtlAddFunctionTable
 //sys	RtlDeleteFunctionTable(functionTable *RUNTIME_FUNCTION) (ret bool) = ntdll.RtlDeleteFunctionTable
 
+// Desktop Window Manager API (Dwmapi)
+//sys	DwmGetWindowAttribute(hwnd HWND, attribute uint32, value unsafe.Pointer, size uint32) (ret error) = dwmapi.DwmGetWindowAttribute
+//sys	DwmSetWindowAttribute(hwnd HWND, attribute uint32, value unsafe.Pointer, size uint32) (ret error) = dwmapi.DwmSetWindowAttribute
+
 // syscall interface implementation for other packages
 
 // GetCurrentProcess returns the handle for the current process.
@@ -747,7 +756,7 @@
 	if e != nil {
 		return e
 	}
-	defer Close(h)
+	defer CloseHandle(h)
 	a := NsecToFiletime(tv[0].Nanoseconds())
 	w := NsecToFiletime(tv[1].Nanoseconds())
 	return SetFileTime(h, nil, &a, &w)
@@ -767,7 +776,7 @@
 	if e != nil {
 		return e
 	}
-	defer Close(h)
+	defer CloseHandle(h)
 	a := NsecToFiletime(TimespecToNsec(ts[0]))
 	w := NsecToFiletime(TimespecToNsec(ts[1]))
 	return SetFileTime(h, nil, &a, &w)
@@ -861,6 +870,7 @@
 //sys	GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) = iphlpapi.GetAdaptersAddresses
 //sys	GetACP() (acp uint32) = kernel32.GetACP
 //sys	MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) = kernel32.MultiByteToWideChar
+//sys	getBestInterfaceEx(sockaddr unsafe.Pointer, pdwBestIfIndex *uint32) (errcode error) = iphlpapi.GetBestInterfaceEx
 
 // For testing: clients can set this flag to force
 // creation of IPv6 sockets to return EAFNOSUPPORT.
@@ -970,6 +980,32 @@
 	return unsafe.Pointer(&sa.raw), sl, nil
 }
 
+type RawSockaddrBth struct {
+	AddressFamily  [2]byte
+	BtAddr         [8]byte
+	ServiceClassId [16]byte
+	Port           [4]byte
+}
+
+type SockaddrBth struct {
+	BtAddr         uint64
+	ServiceClassId GUID
+	Port           uint32
+
+	raw RawSockaddrBth
+}
+
+func (sa *SockaddrBth) sockaddr() (unsafe.Pointer, int32, error) {
+	family := AF_BTH
+	sa.raw = RawSockaddrBth{
+		AddressFamily:  *(*[2]byte)(unsafe.Pointer(&family)),
+		BtAddr:         *(*[8]byte)(unsafe.Pointer(&sa.BtAddr)),
+		Port:           *(*[4]byte)(unsafe.Pointer(&sa.Port)),
+		ServiceClassId: *(*[16]byte)(unsafe.Pointer(&sa.ServiceClassId)),
+	}
+	return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil
+}
+
 func (rsa *RawSockaddrAny) Sockaddr() (Sockaddr, error) {
 	switch rsa.Addr.Family {
 	case AF_UNIX:
@@ -1045,6 +1081,14 @@
 	return connect(fd, ptr, n)
 }
 
+func GetBestInterfaceEx(sa Sockaddr, pdwBestIfIndex *uint32) (err error) {
+	ptr, _, err := sa.sockaddr()
+	if err != nil {
+		return err
+	}
+	return getBestInterfaceEx(ptr, pdwBestIfIndex)
+}
+
 func Getsockname(fd Handle) (sa Sockaddr, err error) {
 	var rsa RawSockaddrAny
 	l := int32(unsafe.Sizeof(rsa))
@@ -1072,9 +1116,13 @@
 }
 
 func WSASendto(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to Sockaddr, overlapped *Overlapped, croutine *byte) (err error) {
-	rsa, l, err := to.sockaddr()
-	if err != nil {
-		return err
+	var rsa unsafe.Pointer
+	var l int32
+	if to != nil {
+		rsa, l, err = to.sockaddr()
+		if err != nil {
+			return err
+		}
 	}
 	return WSASendTo(s, bufs, bufcnt, sent, flags, (*RawSockaddrAny)(unsafe.Pointer(rsa)), l, overlapped, croutine)
 }
@@ -1698,3 +1746,71 @@
 	h.Cap = int(size)
 	return
 }
+
+// PSAPI_WORKING_SET_EX_BLOCK contains extended working set information for a page.
+type PSAPI_WORKING_SET_EX_BLOCK uint64
+
+// Valid returns the validity of this page.
+// If this bit is 1, the subsequent members are valid; otherwise they should be ignored.
+func (b PSAPI_WORKING_SET_EX_BLOCK) Valid() bool {
+	return (b & 1) == 1
+}
+
+// ShareCount is the number of processes that share this page. The maximum value of this member is 7.
+func (b PSAPI_WORKING_SET_EX_BLOCK) ShareCount() uint64 {
+	return b.intField(1, 3)
+}
+
+// Win32Protection is the memory protection attributes of the page. For a list of values, see
+// https://docs.microsoft.com/en-us/windows/win32/memory/memory-protection-constants
+func (b PSAPI_WORKING_SET_EX_BLOCK) Win32Protection() uint64 {
+	return b.intField(4, 11)
+}
+
+// Shared returns the shared status of this page.
+// If this bit is 1, the page can be shared.
+func (b PSAPI_WORKING_SET_EX_BLOCK) Shared() bool {
+	return (b & (1 << 15)) == 1
+}
+
+// Node is the NUMA node. The maximum value of this member is 63.
+func (b PSAPI_WORKING_SET_EX_BLOCK) Node() uint64 {
+	return b.intField(16, 6)
+}
+
+// Locked returns the locked status of this page.
+// If this bit is 1, the virtual page is locked in physical memory.
+func (b PSAPI_WORKING_SET_EX_BLOCK) Locked() bool {
+	return (b & (1 << 22)) == 1
+}
+
+// LargePage returns the large page status of this page.
+// If this bit is 1, the page is a large page.
+func (b PSAPI_WORKING_SET_EX_BLOCK) LargePage() bool {
+	return (b & (1 << 23)) == 1
+}
+
+// Bad returns the bad status of this page.
+// If this bit is 1, the page is has been reported as bad.
+func (b PSAPI_WORKING_SET_EX_BLOCK) Bad() bool {
+	return (b & (1 << 31)) == 1
+}
+
+// intField extracts an integer field in the PSAPI_WORKING_SET_EX_BLOCK union.
+func (b PSAPI_WORKING_SET_EX_BLOCK) intField(start, length int) uint64 {
+	var mask PSAPI_WORKING_SET_EX_BLOCK
+	for pos := start; pos < start+length; pos++ {
+		mask |= (1 << pos)
+	}
+
+	masked := b & mask
+	return uint64(masked >> start)
+}
+
+// PSAPI_WORKING_SET_EX_INFORMATION contains extended working set information for a process.
+type PSAPI_WORKING_SET_EX_INFORMATION struct {
+	// The virtual address.
+	VirtualAddress Pointer
+	// A PSAPI_WORKING_SET_EX_BLOCK union that indicates the attributes of the page at VirtualAddress.
+	VirtualAttributes PSAPI_WORKING_SET_EX_BLOCK
+}
diff --git a/src/cmd/vendor/golang.org/x/sys/windows/types_windows.go b/src/cmd/vendor/golang.org/x/sys/windows/types_windows.go
index e19471c..0c4add9 100644
--- a/src/cmd/vendor/golang.org/x/sys/windows/types_windows.go
+++ b/src/cmd/vendor/golang.org/x/sys/windows/types_windows.go
@@ -160,6 +160,10 @@
 
 	MAX_COMPUTERNAME_LENGTH = 15
 
+	MAX_DHCPV6_DUID_LENGTH = 130
+
+	MAX_DNS_SUFFIX_STRING_LENGTH = 256
+
 	TIME_ZONE_ID_UNKNOWN  = 0
 	TIME_ZONE_ID_STANDARD = 1
 
@@ -2000,27 +2004,62 @@
 }
 
 type IpAdapterAddresses struct {
-	Length                uint32
-	IfIndex               uint32
-	Next                  *IpAdapterAddresses
-	AdapterName           *byte
-	FirstUnicastAddress   *IpAdapterUnicastAddress
-	FirstAnycastAddress   *IpAdapterAnycastAddress
-	FirstMulticastAddress *IpAdapterMulticastAddress
-	FirstDnsServerAddress *IpAdapterDnsServerAdapter
-	DnsSuffix             *uint16
-	Description           *uint16
-	FriendlyName          *uint16
-	PhysicalAddress       [syscall.MAX_ADAPTER_ADDRESS_LENGTH]byte
-	PhysicalAddressLength uint32
-	Flags                 uint32
-	Mtu                   uint32
-	IfType                uint32
-	OperStatus            uint32
-	Ipv6IfIndex           uint32
-	ZoneIndices           [16]uint32
-	FirstPrefix           *IpAdapterPrefix
-	/* more fields might be present here. */
+	Length                 uint32
+	IfIndex                uint32
+	Next                   *IpAdapterAddresses
+	AdapterName            *byte
+	FirstUnicastAddress    *IpAdapterUnicastAddress
+	FirstAnycastAddress    *IpAdapterAnycastAddress
+	FirstMulticastAddress  *IpAdapterMulticastAddress
+	FirstDnsServerAddress  *IpAdapterDnsServerAdapter
+	DnsSuffix              *uint16
+	Description            *uint16
+	FriendlyName           *uint16
+	PhysicalAddress        [syscall.MAX_ADAPTER_ADDRESS_LENGTH]byte
+	PhysicalAddressLength  uint32
+	Flags                  uint32
+	Mtu                    uint32
+	IfType                 uint32
+	OperStatus             uint32
+	Ipv6IfIndex            uint32
+	ZoneIndices            [16]uint32
+	FirstPrefix            *IpAdapterPrefix
+	TransmitLinkSpeed      uint64
+	ReceiveLinkSpeed       uint64
+	FirstWinsServerAddress *IpAdapterWinsServerAddress
+	FirstGatewayAddress    *IpAdapterGatewayAddress
+	Ipv4Metric             uint32
+	Ipv6Metric             uint32
+	Luid                   uint64
+	Dhcpv4Server           SocketAddress
+	CompartmentId          uint32
+	NetworkGuid            GUID
+	ConnectionType         uint32
+	TunnelType             uint32
+	Dhcpv6Server           SocketAddress
+	Dhcpv6ClientDuid       [MAX_DHCPV6_DUID_LENGTH]byte
+	Dhcpv6ClientDuidLength uint32
+	Dhcpv6Iaid             uint32
+	FirstDnsSuffix         *IpAdapterDNSSuffix
+}
+
+type IpAdapterWinsServerAddress struct {
+	Length   uint32
+	Reserved uint32
+	Next     *IpAdapterWinsServerAddress
+	Address  SocketAddress
+}
+
+type IpAdapterGatewayAddress struct {
+	Length   uint32
+	Reserved uint32
+	Next     *IpAdapterGatewayAddress
+	Address  SocketAddress
+}
+
+type IpAdapterDNSSuffix struct {
+	Next   *IpAdapterDNSSuffix
+	String [MAX_DNS_SUFFIX_STRING_LENGTH]uint16
 }
 
 const (
@@ -3174,3 +3213,48 @@
 }
 
 const ALL_PROCESSOR_GROUPS = 0xFFFF
+
+type Rect struct {
+	Left   int32
+	Top    int32
+	Right  int32
+	Bottom int32
+}
+
+type GUIThreadInfo struct {
+	Size        uint32
+	Flags       uint32
+	Active      HWND
+	Focus       HWND
+	Capture     HWND
+	MenuOwner   HWND
+	MoveSize    HWND
+	CaretHandle HWND
+	CaretRect   Rect
+}
+
+const (
+	DWMWA_NCRENDERING_ENABLED            = 1
+	DWMWA_NCRENDERING_POLICY             = 2
+	DWMWA_TRANSITIONS_FORCEDISABLED      = 3
+	DWMWA_ALLOW_NCPAINT                  = 4
+	DWMWA_CAPTION_BUTTON_BOUNDS          = 5
+	DWMWA_NONCLIENT_RTL_LAYOUT           = 6
+	DWMWA_FORCE_ICONIC_REPRESENTATION    = 7
+	DWMWA_FLIP3D_POLICY                  = 8
+	DWMWA_EXTENDED_FRAME_BOUNDS          = 9
+	DWMWA_HAS_ICONIC_BITMAP              = 10
+	DWMWA_DISALLOW_PEEK                  = 11
+	DWMWA_EXCLUDED_FROM_PEEK             = 12
+	DWMWA_CLOAK                          = 13
+	DWMWA_CLOAKED                        = 14
+	DWMWA_FREEZE_REPRESENTATION          = 15
+	DWMWA_PASSIVE_UPDATE_MODE            = 16
+	DWMWA_USE_HOSTBACKDROPBRUSH          = 17
+	DWMWA_USE_IMMERSIVE_DARK_MODE        = 20
+	DWMWA_WINDOW_CORNER_PREFERENCE       = 33
+	DWMWA_BORDER_COLOR                   = 34
+	DWMWA_CAPTION_COLOR                  = 35
+	DWMWA_TEXT_COLOR                     = 36
+	DWMWA_VISIBLE_FRAME_BORDER_THICKNESS = 37
+)
diff --git a/src/cmd/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/src/cmd/vendor/golang.org/x/sys/windows/zsyscall_windows.go
index 68f52c1..ac60052 100644
--- a/src/cmd/vendor/golang.org/x/sys/windows/zsyscall_windows.go
+++ b/src/cmd/vendor/golang.org/x/sys/windows/zsyscall_windows.go
@@ -40,6 +40,7 @@
 	modadvapi32 = NewLazySystemDLL("advapi32.dll")
 	modcrypt32  = NewLazySystemDLL("crypt32.dll")
 	moddnsapi   = NewLazySystemDLL("dnsapi.dll")
+	moddwmapi   = NewLazySystemDLL("dwmapi.dll")
 	modiphlpapi = NewLazySystemDLL("iphlpapi.dll")
 	modkernel32 = NewLazySystemDLL("kernel32.dll")
 	modmswsock  = NewLazySystemDLL("mswsock.dll")
@@ -175,8 +176,11 @@
 	procDnsNameCompare_W                                     = moddnsapi.NewProc("DnsNameCompare_W")
 	procDnsQuery_W                                           = moddnsapi.NewProc("DnsQuery_W")
 	procDnsRecordListFree                                    = moddnsapi.NewProc("DnsRecordListFree")
+	procDwmGetWindowAttribute                                = moddwmapi.NewProc("DwmGetWindowAttribute")
+	procDwmSetWindowAttribute                                = moddwmapi.NewProc("DwmSetWindowAttribute")
 	procGetAdaptersAddresses                                 = modiphlpapi.NewProc("GetAdaptersAddresses")
 	procGetAdaptersInfo                                      = modiphlpapi.NewProc("GetAdaptersInfo")
+	procGetBestInterfaceEx                                   = modiphlpapi.NewProc("GetBestInterfaceEx")
 	procGetIfEntry                                           = modiphlpapi.NewProc("GetIfEntry")
 	procAssignProcessToJobObject                             = modkernel32.NewProc("AssignProcessToJobObject")
 	procCancelIo                                             = modkernel32.NewProc("CancelIo")
@@ -248,6 +252,7 @@
 	procGetFileType                                          = modkernel32.NewProc("GetFileType")
 	procGetFinalPathNameByHandleW                            = modkernel32.NewProc("GetFinalPathNameByHandleW")
 	procGetFullPathNameW                                     = modkernel32.NewProc("GetFullPathNameW")
+	procGetLargePageMinimum                                  = modkernel32.NewProc("GetLargePageMinimum")
 	procGetLastError                                         = modkernel32.NewProc("GetLastError")
 	procGetLogicalDriveStringsW                              = modkernel32.NewProc("GetLogicalDriveStringsW")
 	procGetLogicalDrives                                     = modkernel32.NewProc("GetLogicalDrives")
@@ -407,6 +412,7 @@
 	procGetModuleBaseNameW                                   = modpsapi.NewProc("GetModuleBaseNameW")
 	procGetModuleFileNameExW                                 = modpsapi.NewProc("GetModuleFileNameExW")
 	procGetModuleInformation                                 = modpsapi.NewProc("GetModuleInformation")
+	procQueryWorkingSetEx                                    = modpsapi.NewProc("QueryWorkingSetEx")
 	procSubscribeServiceChangeNotifications                  = modsechost.NewProc("SubscribeServiceChangeNotifications")
 	procUnsubscribeServiceChangeNotifications                = modsechost.NewProc("UnsubscribeServiceChangeNotifications")
 	procGetUserNameExW                                       = modsecur32.NewProc("GetUserNameExW")
@@ -442,9 +448,18 @@
 	procCommandLineToArgvW                                   = modshell32.NewProc("CommandLineToArgvW")
 	procSHGetKnownFolderPath                                 = modshell32.NewProc("SHGetKnownFolderPath")
 	procShellExecuteW                                        = modshell32.NewProc("ShellExecuteW")
+	procEnumChildWindows                                     = moduser32.NewProc("EnumChildWindows")
+	procEnumWindows                                          = moduser32.NewProc("EnumWindows")
 	procExitWindowsEx                                        = moduser32.NewProc("ExitWindowsEx")
+	procGetClassNameW                                        = moduser32.NewProc("GetClassNameW")
+	procGetDesktopWindow                                     = moduser32.NewProc("GetDesktopWindow")
+	procGetForegroundWindow                                  = moduser32.NewProc("GetForegroundWindow")
+	procGetGUIThreadInfo                                     = moduser32.NewProc("GetGUIThreadInfo")
 	procGetShellWindow                                       = moduser32.NewProc("GetShellWindow")
 	procGetWindowThreadProcessId                             = moduser32.NewProc("GetWindowThreadProcessId")
+	procIsWindow                                             = moduser32.NewProc("IsWindow")
+	procIsWindowUnicode                                      = moduser32.NewProc("IsWindowUnicode")
+	procIsWindowVisible                                      = moduser32.NewProc("IsWindowVisible")
 	procMessageBoxW                                          = moduser32.NewProc("MessageBoxW")
 	procCreateEnvironmentBlock                               = moduserenv.NewProc("CreateEnvironmentBlock")
 	procDestroyEnvironmentBlock                              = moduserenv.NewProc("DestroyEnvironmentBlock")
@@ -1523,6 +1538,22 @@
 	return
 }
 
+func DwmGetWindowAttribute(hwnd HWND, attribute uint32, value unsafe.Pointer, size uint32) (ret error) {
+	r0, _, _ := syscall.Syscall6(procDwmGetWindowAttribute.Addr(), 4, uintptr(hwnd), uintptr(attribute), uintptr(value), uintptr(size), 0, 0)
+	if r0 != 0 {
+		ret = syscall.Errno(r0)
+	}
+	return
+}
+
+func DwmSetWindowAttribute(hwnd HWND, attribute uint32, value unsafe.Pointer, size uint32) (ret error) {
+	r0, _, _ := syscall.Syscall6(procDwmSetWindowAttribute.Addr(), 4, uintptr(hwnd), uintptr(attribute), uintptr(value), uintptr(size), 0, 0)
+	if r0 != 0 {
+		ret = syscall.Errno(r0)
+	}
+	return
+}
+
 func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) {
 	r0, _, _ := syscall.Syscall6(procGetAdaptersAddresses.Addr(), 5, uintptr(family), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(adapterAddresses)), uintptr(unsafe.Pointer(sizePointer)), 0)
 	if r0 != 0 {
@@ -1539,6 +1570,14 @@
 	return
 }
 
+func getBestInterfaceEx(sockaddr unsafe.Pointer, pdwBestIfIndex *uint32) (errcode error) {
+	r0, _, _ := syscall.Syscall(procGetBestInterfaceEx.Addr(), 2, uintptr(sockaddr), uintptr(unsafe.Pointer(pdwBestIfIndex)), 0)
+	if r0 != 0 {
+		errcode = syscall.Errno(r0)
+	}
+	return
+}
+
 func GetIfEntry(pIfRow *MibIfRow) (errcode error) {
 	r0, _, _ := syscall.Syscall(procGetIfEntry.Addr(), 1, uintptr(unsafe.Pointer(pIfRow)), 0, 0)
 	if r0 != 0 {
@@ -2142,6 +2181,12 @@
 	return
 }
 
+func GetLargePageMinimum() (size uintptr) {
+	r0, _, _ := syscall.Syscall(procGetLargePageMinimum.Addr(), 0, 0, 0, 0)
+	size = uintptr(r0)
+	return
+}
+
 func GetLastError() (lasterr error) {
 	r0, _, _ := syscall.Syscall(procGetLastError.Addr(), 0, 0, 0, 0)
 	if r0 != 0 {
@@ -3495,6 +3540,14 @@
 	return
 }
 
+func QueryWorkingSetEx(process Handle, pv uintptr, cb uint32) (err error) {
+	r1, _, e1 := syscall.Syscall(procQueryWorkingSetEx.Addr(), 3, uintptr(process), uintptr(pv), uintptr(cb))
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
 func SubscribeServiceChangeNotifications(service Handle, eventType uint32, callback uintptr, callbackCtx uintptr, subscription *uintptr) (ret error) {
 	ret = procSubscribeServiceChangeNotifications.Find()
 	if ret != nil {
@@ -3784,6 +3837,19 @@
 	return
 }
 
+func EnumChildWindows(hwnd HWND, enumFunc uintptr, param unsafe.Pointer) {
+	syscall.Syscall(procEnumChildWindows.Addr(), 3, uintptr(hwnd), uintptr(enumFunc), uintptr(param))
+	return
+}
+
+func EnumWindows(enumFunc uintptr, param unsafe.Pointer) (err error) {
+	r1, _, e1 := syscall.Syscall(procEnumWindows.Addr(), 2, uintptr(enumFunc), uintptr(param), 0)
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
 func ExitWindowsEx(flags uint32, reason uint32) (err error) {
 	r1, _, e1 := syscall.Syscall(procExitWindowsEx.Addr(), 2, uintptr(flags), uintptr(reason), 0)
 	if r1 == 0 {
@@ -3792,6 +3858,35 @@
 	return
 }
 
+func GetClassName(hwnd HWND, className *uint16, maxCount int32) (copied int32, err error) {
+	r0, _, e1 := syscall.Syscall(procGetClassNameW.Addr(), 3, uintptr(hwnd), uintptr(unsafe.Pointer(className)), uintptr(maxCount))
+	copied = int32(r0)
+	if copied == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func GetDesktopWindow() (hwnd HWND) {
+	r0, _, _ := syscall.Syscall(procGetDesktopWindow.Addr(), 0, 0, 0, 0)
+	hwnd = HWND(r0)
+	return
+}
+
+func GetForegroundWindow() (hwnd HWND) {
+	r0, _, _ := syscall.Syscall(procGetForegroundWindow.Addr(), 0, 0, 0, 0)
+	hwnd = HWND(r0)
+	return
+}
+
+func GetGUIThreadInfo(thread uint32, info *GUIThreadInfo) (err error) {
+	r1, _, e1 := syscall.Syscall(procGetGUIThreadInfo.Addr(), 2, uintptr(thread), uintptr(unsafe.Pointer(info)), 0)
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
 func GetShellWindow() (shellWindow HWND) {
 	r0, _, _ := syscall.Syscall(procGetShellWindow.Addr(), 0, 0, 0, 0)
 	shellWindow = HWND(r0)
@@ -3807,6 +3902,24 @@
 	return
 }
 
+func IsWindow(hwnd HWND) (isWindow bool) {
+	r0, _, _ := syscall.Syscall(procIsWindow.Addr(), 1, uintptr(hwnd), 0, 0)
+	isWindow = r0 != 0
+	return
+}
+
+func IsWindowUnicode(hwnd HWND) (isUnicode bool) {
+	r0, _, _ := syscall.Syscall(procIsWindowUnicode.Addr(), 1, uintptr(hwnd), 0, 0)
+	isUnicode = r0 != 0
+	return
+}
+
+func IsWindowVisible(hwnd HWND) (isVisible bool) {
+	r0, _, _ := syscall.Syscall(procIsWindowVisible.Addr(), 1, uintptr(hwnd), 0, 0)
+	isVisible = r0 != 0
+	return
+}
+
 func MessageBox(hwnd HWND, text *uint16, caption *uint16, boxtype uint32) (ret int32, err error) {
 	r0, _, e1 := syscall.Syscall6(procMessageBoxW.Addr(), 4, uintptr(hwnd), uintptr(unsafe.Pointer(text)), uintptr(unsafe.Pointer(caption)), uintptr(boxtype), 0, 0)
 	ret = int32(r0)
diff --git a/src/cmd/vendor/golang.org/x/term/AUTHORS b/src/cmd/vendor/golang.org/x/term/AUTHORS
deleted file mode 100644
index 15167cd..0000000
--- a/src/cmd/vendor/golang.org/x/term/AUTHORS
+++ /dev/null
@@ -1,3 +0,0 @@
-# This source code refers to The Go Authors for copyright purposes.
-# The master list of authors is in the main Go distribution,
-# visible at http://tip.golang.org/AUTHORS.
diff --git a/src/cmd/vendor/golang.org/x/term/CONTRIBUTORS b/src/cmd/vendor/golang.org/x/term/CONTRIBUTORS
deleted file mode 100644
index 1c4577e..0000000
--- a/src/cmd/vendor/golang.org/x/term/CONTRIBUTORS
+++ /dev/null
@@ -1,3 +0,0 @@
-# This source code was written by the Go contributors.
-# The master list of contributors is in the main Go distribution,
-# visible at http://tip.golang.org/CONTRIBUTORS.
diff --git a/src/cmd/vendor/golang.org/x/term/terminal.go b/src/cmd/vendor/golang.org/x/term/terminal.go
index 535ab82..f636667 100644
--- a/src/cmd/vendor/golang.org/x/term/terminal.go
+++ b/src/cmd/vendor/golang.org/x/term/terminal.go
@@ -233,7 +233,6 @@
 	t.outBuf = append(t.outBuf, []byte(string(data))...)
 }
 
-var eraseUnderCursor = []rune{' ', keyEscape, '[', 'D'}
 var space = []rune{' '}
 
 func isPrintable(key rune) bool {
@@ -935,7 +934,7 @@
 // next most recent, and so on. If such an element doesn't exist then ok is
 // false.
 func (s *stRingBuffer) NthPreviousEntry(n int) (value string, ok bool) {
-	if n >= s.size {
+	if n < 0 || n >= s.size {
 		return "", false
 	}
 	index := s.head - n
diff --git a/src/cmd/vendor/golang.org/x/tools/AUTHORS b/src/cmd/vendor/golang.org/x/tools/AUTHORS
deleted file mode 100644
index 15167cd..0000000
--- a/src/cmd/vendor/golang.org/x/tools/AUTHORS
+++ /dev/null
@@ -1,3 +0,0 @@
-# This source code refers to The Go Authors for copyright purposes.
-# The master list of authors is in the main Go distribution,
-# visible at http://tip.golang.org/AUTHORS.
diff --git a/src/cmd/vendor/golang.org/x/tools/CONTRIBUTORS b/src/cmd/vendor/golang.org/x/tools/CONTRIBUTORS
deleted file mode 100644
index 1c4577e..0000000
--- a/src/cmd/vendor/golang.org/x/tools/CONTRIBUTORS
+++ /dev/null
@@ -1,3 +0,0 @@
-# This source code was written by the Go contributors.
-# The master list of contributors is in the main Go distribution,
-# visible at http://tip.golang.org/CONTRIBUTORS.
diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/analysis.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/analysis.go
index d11505a..44ada22 100644
--- a/src/cmd/vendor/golang.org/x/tools/go/analysis/analysis.go
+++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/analysis.go
@@ -11,8 +11,6 @@
 	"go/token"
 	"go/types"
 	"reflect"
-
-	"golang.org/x/tools/internal/analysisinternal"
 )
 
 // An Analyzer describes an analysis function and its options.
@@ -48,6 +46,7 @@
 	// RunDespiteErrors allows the driver to invoke
 	// the Run method of this analyzer even on a
 	// package that contains parse or type errors.
+	// The Pass.TypeErrors field may consequently be non-empty.
 	RunDespiteErrors bool
 
 	// Requires is a set of analyzers that must run successfully
@@ -75,17 +74,6 @@
 
 func (a *Analyzer) String() string { return a.Name }
 
-func init() {
-	// Set the analysisinternal functions to be able to pass type errors
-	// to the Pass type without modifying the go/analysis API.
-	analysisinternal.SetTypeErrors = func(p interface{}, errors []types.Error) {
-		p.(*Pass).typeErrors = errors
-	}
-	analysisinternal.GetTypeErrors = func(p interface{}) []types.Error {
-		return p.(*Pass).typeErrors
-	}
-}
-
 // A Pass provides information to the Run function that
 // applies a specific analyzer to a single Go package.
 //
@@ -106,6 +94,7 @@
 	Pkg          *types.Package // type information about the package
 	TypesInfo    *types.Info    // type information about the syntax trees
 	TypesSizes   types.Sizes    // function for computing sizes of types
+	TypeErrors   []types.Error  // type errors (only if Analyzer.RunDespiteErrors)
 
 	// Report reports a Diagnostic, a finding about a specific location
 	// in the analyzed source code such as a potential mistake.
diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/diagnostic.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/diagnostic.go
index cd462a0..5cdcf46 100644
--- a/src/cmd/vendor/golang.org/x/tools/go/analysis/diagnostic.go
+++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/diagnostic.go
@@ -37,7 +37,7 @@
 // declaration.
 type RelatedInformation struct {
 	Pos     token.Pos
-	End     token.Pos
+	End     token.Pos // optional
 	Message string
 }
 
diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/doc.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/doc.go
index 7679bda..b5a301c 100644
--- a/src/cmd/vendor/golang.org/x/tools/go/analysis/doc.go
+++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/doc.go
@@ -177,14 +177,14 @@
 The optional Category field is a short identifier that classifies the
 kind of message when an analysis produces several kinds of diagnostic.
 
-Many analyses want to associate diagnostics with a severity level.
-Because Diagnostic does not have a severity level field, an Analyzer's
-diagnostics effectively all have the same severity level. To separate which
-diagnostics are high severity and which are low severity, expose multiple
-Analyzers instead. Analyzers should also be separated when their
-diagnostics belong in different groups, or could be tagged differently
-before being shown to the end user. Analyzers should document their severity
-level to help downstream tools surface diagnostics properly.
+The Diagnostic struct does not have a field to indicate its severity
+because opinions about the relative importance of Analyzers and their
+diagnostics vary widely among users. The design of this framework does
+not hold each Analyzer responsible for identifying the severity of its
+diagnostics. Instead, we expect that drivers will allow the user to
+customize the filtering and prioritization of diagnostics based on the
+producing Analyzer and optional Category, according to the user's
+preferences.
 
 Most Analyzers inspect typed Go syntax trees, but a few, such as asmdecl
 and buildtag, inspect the raw text of Go source files or even non-Go
@@ -241,6 +241,9 @@
 use the gob encoding, an efficient, robust, self-describing binary
 protocol. A fact type may implement the GobEncoder/GobDecoder interfaces
 if the default encoding is unsuitable. Facts should be stateless.
+Because serialized facts may appear within build outputs, the gob encoding
+of a fact must be deterministic, to avoid spurious cache misses in
+build systems that use content-addressable caches.
 
 The Pass type has functions to import and export facts,
 associated either with an object or with a package:
@@ -294,7 +297,7 @@
 
 The singlechecker package provides the main function for a command that
 runs one analyzer. By convention, each analyzer such as
-go/passes/findcall should be accompanied by a singlechecker-based
+go/analysis/passes/findcall should be accompanied by a singlechecker-based
 command such as go/analysis/passes/findcall/cmd/findcall, defined in its
 entirety as:
 
diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/internal/analysisflags/flags.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/internal/analysisflags/flags.go
index 4b7be2d..2ea6306 100644
--- a/src/cmd/vendor/golang.org/x/tools/go/analysis/internal/analysisflags/flags.go
+++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/internal/analysisflags/flags.go
@@ -339,9 +339,38 @@
 }
 
 // A JSONTree is a mapping from package ID to analysis name to result.
-// Each result is either a jsonError or a list of jsonDiagnostic.
+// Each result is either a jsonError or a list of JSONDiagnostic.
 type JSONTree map[string]map[string]interface{}
 
+// A TextEdit describes the replacement of a portion of a file.
+// Start and End are zero-based half-open indices into the original byte
+// sequence of the file, and New is the new text.
+type JSONTextEdit struct {
+	Filename string `json:"filename"`
+	Start    int    `json:"start"`
+	End      int    `json:"end"`
+	New      string `json:"new"`
+}
+
+// A JSONSuggestedFix describes an edit that should be applied as a whole or not
+// at all. It might contain multiple TextEdits/text_edits if the SuggestedFix
+// consists of multiple non-contiguous edits.
+type JSONSuggestedFix struct {
+	Message string         `json:"message"`
+	Edits   []JSONTextEdit `json:"edits"`
+}
+
+// A JSONDiagnostic can be used to encode and decode analysis.Diagnostics to and
+// from JSON.
+// TODO(matloob): Should the JSON diagnostics contain ranges?
+// If so, how should they be formatted?
+type JSONDiagnostic struct {
+	Category       string             `json:"category,omitempty"`
+	Posn           string             `json:"posn"`
+	Message        string             `json:"message"`
+	SuggestedFixes []JSONSuggestedFix `json:"suggested_fixes,omitempty"`
+}
+
 // Add adds the result of analysis 'name' on package 'id'.
 // The result is either a list of diagnostics or an error.
 func (tree JSONTree) Add(fset *token.FileSet, id, name string, diags []analysis.Diagnostic, err error) {
@@ -352,20 +381,31 @@
 		}
 		v = jsonError{err.Error()}
 	} else if len(diags) > 0 {
-		type jsonDiagnostic struct {
-			Category string `json:"category,omitempty"`
-			Posn     string `json:"posn"`
-			Message  string `json:"message"`
-		}
-		var diagnostics []jsonDiagnostic
-		// TODO(matloob): Should the JSON diagnostics contain ranges?
-		// If so, how should they be formatted?
+		diagnostics := make([]JSONDiagnostic, 0, len(diags))
 		for _, f := range diags {
-			diagnostics = append(diagnostics, jsonDiagnostic{
-				Category: f.Category,
-				Posn:     fset.Position(f.Pos).String(),
-				Message:  f.Message,
-			})
+			var fixes []JSONSuggestedFix
+			for _, fix := range f.SuggestedFixes {
+				var edits []JSONTextEdit
+				for _, edit := range fix.TextEdits {
+					edits = append(edits, JSONTextEdit{
+						Filename: fset.Position(edit.Pos).Filename,
+						Start:    fset.Position(edit.Pos).Offset,
+						End:      fset.Position(edit.End).Offset,
+						New:      string(edit.NewText),
+					})
+				}
+				fixes = append(fixes, JSONSuggestedFix{
+					Message: fix.Message,
+					Edits:   edits,
+				})
+			}
+			jdiag := JSONDiagnostic{
+				Category:       f.Category,
+				Posn:           fset.Position(f.Pos).String(),
+				Message:        f.Message,
+				SuggestedFixes: fixes,
+			}
+			diagnostics = append(diagnostics, jdiag)
 		}
 		v = diagnostics
 	}
diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/internal/facts/facts.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/internal/facts/facts.go
deleted file mode 100644
index 006abab..0000000
--- a/src/cmd/vendor/golang.org/x/tools/go/analysis/internal/facts/facts.go
+++ /dev/null
@@ -1,322 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package facts defines a serializable set of analysis.Fact.
-//
-// It provides a partial implementation of the Fact-related parts of the
-// analysis.Pass interface for use in analysis drivers such as "go vet"
-// and other build systems.
-//
-// The serial format is unspecified and may change, so the same version
-// of this package must be used for reading and writing serialized facts.
-//
-// The handling of facts in the analysis system parallels the handling
-// of type information in the compiler: during compilation of package P,
-// the compiler emits an export data file that describes the type of
-// every object (named thing) defined in package P, plus every object
-// indirectly reachable from one of those objects. Thus the downstream
-// compiler of package Q need only load one export data file per direct
-// import of Q, and it will learn everything about the API of package P
-// and everything it needs to know about the API of P's dependencies.
-//
-// Similarly, analysis of package P emits a fact set containing facts
-// about all objects exported from P, plus additional facts about only
-// those objects of P's dependencies that are reachable from the API of
-// package P; the downstream analysis of Q need only load one fact set
-// per direct import of Q.
-//
-// The notion of "exportedness" that matters here is that of the
-// compiler. According to the language spec, a method pkg.T.f is
-// unexported simply because its name starts with lowercase. But the
-// compiler must nonetheless export f so that downstream compilations can
-// accurately ascertain whether pkg.T implements an interface pkg.I
-// defined as interface{f()}. Exported thus means "described in export
-// data".
-package facts
-
-import (
-	"bytes"
-	"encoding/gob"
-	"fmt"
-	"go/types"
-	"io/ioutil"
-	"log"
-	"reflect"
-	"sort"
-	"sync"
-
-	"golang.org/x/tools/go/analysis"
-	"golang.org/x/tools/go/types/objectpath"
-)
-
-const debug = false
-
-// A Set is a set of analysis.Facts.
-//
-// Decode creates a Set of facts by reading from the imports of a given
-// package, and Encode writes out the set. Between these operation,
-// the Import and Export methods will query and update the set.
-//
-// All of Set's methods except String are safe to call concurrently.
-type Set struct {
-	pkg *types.Package
-	mu  sync.Mutex
-	m   map[key]analysis.Fact
-}
-
-type key struct {
-	pkg *types.Package
-	obj types.Object // (object facts only)
-	t   reflect.Type
-}
-
-// ImportObjectFact implements analysis.Pass.ImportObjectFact.
-func (s *Set) ImportObjectFact(obj types.Object, ptr analysis.Fact) bool {
-	if obj == nil {
-		panic("nil object")
-	}
-	key := key{pkg: obj.Pkg(), obj: obj, t: reflect.TypeOf(ptr)}
-	s.mu.Lock()
-	defer s.mu.Unlock()
-	if v, ok := s.m[key]; ok {
-		reflect.ValueOf(ptr).Elem().Set(reflect.ValueOf(v).Elem())
-		return true
-	}
-	return false
-}
-
-// ExportObjectFact implements analysis.Pass.ExportObjectFact.
-func (s *Set) ExportObjectFact(obj types.Object, fact analysis.Fact) {
-	if obj.Pkg() != s.pkg {
-		log.Panicf("in package %s: ExportObjectFact(%s, %T): can't set fact on object belonging another package",
-			s.pkg, obj, fact)
-	}
-	key := key{pkg: obj.Pkg(), obj: obj, t: reflect.TypeOf(fact)}
-	s.mu.Lock()
-	s.m[key] = fact // clobber any existing entry
-	s.mu.Unlock()
-}
-
-func (s *Set) AllObjectFacts(filter map[reflect.Type]bool) []analysis.ObjectFact {
-	var facts []analysis.ObjectFact
-	s.mu.Lock()
-	for k, v := range s.m {
-		if k.obj != nil && filter[k.t] {
-			facts = append(facts, analysis.ObjectFact{Object: k.obj, Fact: v})
-		}
-	}
-	s.mu.Unlock()
-	return facts
-}
-
-// ImportPackageFact implements analysis.Pass.ImportPackageFact.
-func (s *Set) ImportPackageFact(pkg *types.Package, ptr analysis.Fact) bool {
-	if pkg == nil {
-		panic("nil package")
-	}
-	key := key{pkg: pkg, t: reflect.TypeOf(ptr)}
-	s.mu.Lock()
-	defer s.mu.Unlock()
-	if v, ok := s.m[key]; ok {
-		reflect.ValueOf(ptr).Elem().Set(reflect.ValueOf(v).Elem())
-		return true
-	}
-	return false
-}
-
-// ExportPackageFact implements analysis.Pass.ExportPackageFact.
-func (s *Set) ExportPackageFact(fact analysis.Fact) {
-	key := key{pkg: s.pkg, t: reflect.TypeOf(fact)}
-	s.mu.Lock()
-	s.m[key] = fact // clobber any existing entry
-	s.mu.Unlock()
-}
-
-func (s *Set) AllPackageFacts(filter map[reflect.Type]bool) []analysis.PackageFact {
-	var facts []analysis.PackageFact
-	s.mu.Lock()
-	for k, v := range s.m {
-		if k.obj == nil && filter[k.t] {
-			facts = append(facts, analysis.PackageFact{Package: k.pkg, Fact: v})
-		}
-	}
-	s.mu.Unlock()
-	return facts
-}
-
-// gobFact is the Gob declaration of a serialized fact.
-type gobFact struct {
-	PkgPath string          // path of package
-	Object  objectpath.Path // optional path of object relative to package itself
-	Fact    analysis.Fact   // type and value of user-defined Fact
-}
-
-// Decode decodes all the facts relevant to the analysis of package pkg.
-// The read function reads serialized fact data from an external source
-// for one of of pkg's direct imports. The empty file is a valid
-// encoding of an empty fact set.
-//
-// It is the caller's responsibility to call gob.Register on all
-// necessary fact types.
-func Decode(pkg *types.Package, read func(packagePath string) ([]byte, error)) (*Set, error) {
-	// Compute the import map for this package.
-	// See the package doc comment.
-	packages := importMap(pkg.Imports())
-
-	// Read facts from imported packages.
-	// Facts may describe indirectly imported packages, or their objects.
-	m := make(map[key]analysis.Fact) // one big bucket
-	for _, imp := range pkg.Imports() {
-		logf := func(format string, args ...interface{}) {
-			if debug {
-				prefix := fmt.Sprintf("in %s, importing %s: ",
-					pkg.Path(), imp.Path())
-				log.Print(prefix, fmt.Sprintf(format, args...))
-			}
-		}
-
-		// Read the gob-encoded facts.
-		data, err := read(imp.Path())
-		if err != nil {
-			return nil, fmt.Errorf("in %s, can't import facts for package %q: %v",
-				pkg.Path(), imp.Path(), err)
-		}
-		if len(data) == 0 {
-			continue // no facts
-		}
-		var gobFacts []gobFact
-		if err := gob.NewDecoder(bytes.NewReader(data)).Decode(&gobFacts); err != nil {
-			return nil, fmt.Errorf("decoding facts for %q: %v", imp.Path(), err)
-		}
-		if debug {
-			logf("decoded %d facts: %v", len(gobFacts), gobFacts)
-		}
-
-		// Parse each one into a key and a Fact.
-		for _, f := range gobFacts {
-			factPkg := packages[f.PkgPath]
-			if factPkg == nil {
-				// Fact relates to a dependency that was
-				// unused in this translation unit. Skip.
-				logf("no package %q; discarding %v", f.PkgPath, f.Fact)
-				continue
-			}
-			key := key{pkg: factPkg, t: reflect.TypeOf(f.Fact)}
-			if f.Object != "" {
-				// object fact
-				obj, err := objectpath.Object(factPkg, f.Object)
-				if err != nil {
-					// (most likely due to unexported object)
-					// TODO(adonovan): audit for other possibilities.
-					logf("no object for path: %v; discarding %s", err, f.Fact)
-					continue
-				}
-				key.obj = obj
-				logf("read %T fact %s for %v", f.Fact, f.Fact, key.obj)
-			} else {
-				// package fact
-				logf("read %T fact %s for %v", f.Fact, f.Fact, factPkg)
-			}
-			m[key] = f.Fact
-		}
-	}
-
-	return &Set{pkg: pkg, m: m}, nil
-}
-
-// Encode encodes a set of facts to a memory buffer.
-//
-// It may fail if one of the Facts could not be gob-encoded, but this is
-// a sign of a bug in an Analyzer.
-func (s *Set) Encode() []byte {
-
-	// TODO(adonovan): opt: use a more efficient encoding
-	// that avoids repeating PkgPath for each fact.
-
-	// Gather all facts, including those from imported packages.
-	var gobFacts []gobFact
-
-	s.mu.Lock()
-	for k, fact := range s.m {
-		if debug {
-			log.Printf("%v => %s\n", k, fact)
-		}
-		var object objectpath.Path
-		if k.obj != nil {
-			path, err := objectpath.For(k.obj)
-			if err != nil {
-				if debug {
-					log.Printf("discarding fact %s about %s\n", fact, k.obj)
-				}
-				continue // object not accessible from package API; discard fact
-			}
-			object = path
-		}
-		gobFacts = append(gobFacts, gobFact{
-			PkgPath: k.pkg.Path(),
-			Object:  object,
-			Fact:    fact,
-		})
-	}
-	s.mu.Unlock()
-
-	// Sort facts by (package, object, type) for determinism.
-	sort.Slice(gobFacts, func(i, j int) bool {
-		x, y := gobFacts[i], gobFacts[j]
-		if x.PkgPath != y.PkgPath {
-			return x.PkgPath < y.PkgPath
-		}
-		if x.Object != y.Object {
-			return x.Object < y.Object
-		}
-		tx := reflect.TypeOf(x.Fact)
-		ty := reflect.TypeOf(y.Fact)
-		if tx != ty {
-			return tx.String() < ty.String()
-		}
-		return false // equal
-	})
-
-	var buf bytes.Buffer
-	if len(gobFacts) > 0 {
-		if err := gob.NewEncoder(&buf).Encode(gobFacts); err != nil {
-			// Fact encoding should never fail. Identify the culprit.
-			for _, gf := range gobFacts {
-				if err := gob.NewEncoder(ioutil.Discard).Encode(gf); err != nil {
-					fact := gf.Fact
-					pkgpath := reflect.TypeOf(fact).Elem().PkgPath()
-					log.Panicf("internal error: gob encoding of analysis fact %s failed: %v; please report a bug against fact %T in package %q",
-						fact, err, fact, pkgpath)
-				}
-			}
-		}
-	}
-
-	if debug {
-		log.Printf("package %q: encode %d facts, %d bytes\n",
-			s.pkg.Path(), len(gobFacts), buf.Len())
-	}
-
-	return buf.Bytes()
-}
-
-// String is provided only for debugging, and must not be called
-// concurrent with any Import/Export method.
-func (s *Set) String() string {
-	var buf bytes.Buffer
-	buf.WriteString("{")
-	for k, f := range s.m {
-		if buf.Len() > 1 {
-			buf.WriteString(", ")
-		}
-		if k.obj != nil {
-			buf.WriteString(k.obj.String())
-		} else {
-			buf.WriteString(k.pkg.Path())
-		}
-		fmt.Fprintf(&buf, ": %v", f)
-	}
-	buf.WriteString("}")
-	return buf.String()
-}
diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/internal/facts/imports.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/internal/facts/imports.go
deleted file mode 100644
index 8a5553e..0000000
--- a/src/cmd/vendor/golang.org/x/tools/go/analysis/internal/facts/imports.go
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package facts
-
-import (
-	"go/types"
-
-	"golang.org/x/tools/internal/typeparams"
-)
-
-// importMap computes the import map for a package by traversing the
-// entire exported API each of its imports.
-//
-// This is a workaround for the fact that we cannot access the map used
-// internally by the types.Importer returned by go/importer. The entries
-// in this map are the packages and objects that may be relevant to the
-// current analysis unit.
-//
-// Packages in the map that are only indirectly imported may be
-// incomplete (!pkg.Complete()).
-func importMap(imports []*types.Package) map[string]*types.Package {
-	objects := make(map[types.Object]bool)
-	packages := make(map[string]*types.Package)
-
-	var addObj func(obj types.Object) bool
-	var addType func(T types.Type)
-
-	addObj = func(obj types.Object) bool {
-		if !objects[obj] {
-			objects[obj] = true
-			addType(obj.Type())
-			if pkg := obj.Pkg(); pkg != nil {
-				packages[pkg.Path()] = pkg
-			}
-			return true
-		}
-		return false
-	}
-
-	addType = func(T types.Type) {
-		switch T := T.(type) {
-		case *types.Basic:
-			// nop
-		case *types.Named:
-			if addObj(T.Obj()) {
-				// TODO(taking): Investigate why the Underlying type is not added here.
-				for i := 0; i < T.NumMethods(); i++ {
-					addObj(T.Method(i))
-				}
-				if tparams := typeparams.ForNamed(T); tparams != nil {
-					for i := 0; i < tparams.Len(); i++ {
-						addType(tparams.At(i))
-					}
-				}
-				if targs := typeparams.NamedTypeArgs(T); targs != nil {
-					for i := 0; i < targs.Len(); i++ {
-						addType(targs.At(i))
-					}
-				}
-			}
-		case *types.Pointer:
-			addType(T.Elem())
-		case *types.Slice:
-			addType(T.Elem())
-		case *types.Array:
-			addType(T.Elem())
-		case *types.Chan:
-			addType(T.Elem())
-		case *types.Map:
-			addType(T.Key())
-			addType(T.Elem())
-		case *types.Signature:
-			addType(T.Params())
-			addType(T.Results())
-			if tparams := typeparams.ForSignature(T); tparams != nil {
-				for i := 0; i < tparams.Len(); i++ {
-					addType(tparams.At(i))
-				}
-			}
-		case *types.Struct:
-			for i := 0; i < T.NumFields(); i++ {
-				addObj(T.Field(i))
-			}
-		case *types.Tuple:
-			for i := 0; i < T.Len(); i++ {
-				addObj(T.At(i))
-			}
-		case *types.Interface:
-			for i := 0; i < T.NumMethods(); i++ {
-				addObj(T.Method(i))
-			}
-			for i := 0; i < T.NumEmbeddeds(); i++ {
-				addType(T.EmbeddedType(i)) // walk Embedded for implicits
-			}
-		case *typeparams.Union:
-			for i := 0; i < T.Len(); i++ {
-				addType(T.Term(i).Type())
-			}
-		case *typeparams.TypeParam:
-			if addObj(T.Obj()) {
-				addType(T.Constraint())
-			}
-		}
-	}
-
-	for _, imp := range imports {
-		packages[imp.Path()] = imp
-
-		scope := imp.Scope()
-		for _, name := range scope.Names() {
-			addObj(scope.Lookup(name))
-		}
-	}
-
-	return packages
-}
diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/asmdecl/asmdecl.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/asmdecl/asmdecl.go
index 6fbfe7e..7288559 100644
--- a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/asmdecl/asmdecl.go
+++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/asmdecl/asmdecl.go
@@ -92,7 +92,7 @@
 	asmArchMips64LE = asmArch{name: "mips64le", bigEndian: false, stack: "R29", lr: true}
 	asmArchPpc64    = asmArch{name: "ppc64", bigEndian: true, stack: "R1", lr: true, retRegs: []string{"R3", "F1"}}
 	asmArchPpc64LE  = asmArch{name: "ppc64le", bigEndian: false, stack: "R1", lr: true, retRegs: []string{"R3", "F1"}}
-	asmArchRISCV64  = asmArch{name: "riscv64", bigEndian: false, stack: "SP", lr: true}
+	asmArchRISCV64  = asmArch{name: "riscv64", bigEndian: false, stack: "SP", lr: true, retRegs: []string{"X10", "F10"}}
 	asmArchS390X    = asmArch{name: "s390x", bigEndian: true, stack: "R15", lr: true}
 	asmArchWasm     = asmArch{name: "wasm", bigEndian: false, stack: "SP", lr: false}
 
diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/assign/assign.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/assign/assign.go
index 3586638..89146b7 100644
--- a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/assign/assign.go
+++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/assign/assign.go
@@ -12,6 +12,7 @@
 	"fmt"
 	"go/ast"
 	"go/token"
+	"go/types"
 	"reflect"
 
 	"golang.org/x/tools/go/analysis"
@@ -51,7 +52,8 @@
 		for i, lhs := range stmt.Lhs {
 			rhs := stmt.Rhs[i]
 			if analysisutil.HasSideEffects(pass.TypesInfo, lhs) ||
-				analysisutil.HasSideEffects(pass.TypesInfo, rhs) {
+				analysisutil.HasSideEffects(pass.TypesInfo, rhs) ||
+				isMapIndex(pass.TypesInfo, lhs) {
 				continue // expressions may not be equal
 			}
 			if reflect.TypeOf(lhs) != reflect.TypeOf(rhs) {
@@ -74,3 +76,14 @@
 
 	return nil, nil
 }
+
+// isMapIndex returns true if e is a map index expression.
+func isMapIndex(info *types.Info, e ast.Expr) bool {
+	if idx, ok := analysisutil.Unparen(e).(*ast.IndexExpr); ok {
+		if typ := info.Types[idx.X].Type; typ != nil {
+			_, ok := typ.Underlying().(*types.Map)
+			return ok
+		}
+	}
+	return false
+}
diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/composite/composite.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/composite/composite.go
index d3670ac..64e184d 100644
--- a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/composite/composite.go
+++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/composite/composite.go
@@ -7,6 +7,7 @@
 package composite
 
 import (
+	"fmt"
 	"go/ast"
 	"go/types"
 	"strings"
@@ -83,7 +84,8 @@
 		}
 		for _, typ := range structuralTypes {
 			under := deref(typ.Underlying())
-			if _, ok := under.(*types.Struct); !ok {
+			strct, ok := under.(*types.Struct)
+			if !ok {
 				// skip non-struct composite literals
 				continue
 			}
@@ -92,20 +94,47 @@
 				continue
 			}
 
-			// check if the CompositeLit contains an unkeyed field
+			// check if the struct contains an unkeyed field
 			allKeyValue := true
-			for _, e := range cl.Elts {
+			var suggestedFixAvailable = len(cl.Elts) == strct.NumFields()
+			var missingKeys []analysis.TextEdit
+			for i, e := range cl.Elts {
 				if _, ok := e.(*ast.KeyValueExpr); !ok {
 					allKeyValue = false
-					break
+					if i >= strct.NumFields() {
+						break
+					}
+					field := strct.Field(i)
+					if !field.Exported() {
+						// Adding unexported field names for structs not defined
+						// locally will not work.
+						suggestedFixAvailable = false
+						break
+					}
+					missingKeys = append(missingKeys, analysis.TextEdit{
+						Pos:     e.Pos(),
+						End:     e.Pos(),
+						NewText: []byte(fmt.Sprintf("%s: ", field.Name())),
+					})
 				}
 			}
 			if allKeyValue {
-				// all the composite literal fields are keyed
+				// all the struct fields are keyed
 				continue
 			}
 
-			pass.ReportRangef(cl, "%s composite literal uses unkeyed fields", typeName)
+			diag := analysis.Diagnostic{
+				Pos:     cl.Pos(),
+				End:     cl.End(),
+				Message: fmt.Sprintf("%s struct literal uses unkeyed fields", typeName),
+			}
+			if suggestedFixAvailable {
+				diag.SuggestedFixes = []analysis.SuggestedFix{{
+					Message:   "Add field names to struct literal",
+					TextEdits: missingKeys,
+				}}
+			}
+			pass.Report(diag)
 			return
 		}
 	})
diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/inspect/inspect.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/inspect/inspect.go
index c1c1127..165c70c 100644
--- a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/inspect/inspect.go
+++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/inspect/inspect.go
@@ -24,7 +24,7 @@
 //		inspect.Preorder(nil, func(n ast.Node) {
 //			...
 //		})
-//		return nil
+//		return nil, nil
 //	}
 package inspect
 
diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/loopclosure/loopclosure.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/loopclosure/loopclosure.go
index 98de9a9..ae5b415 100644
--- a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/loopclosure/loopclosure.go
+++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/loopclosure/loopclosure.go
@@ -18,19 +18,60 @@
 
 const Doc = `check references to loop variables from within nested functions
 
-This analyzer checks for references to loop variables from within a
-function literal inside the loop body. It checks only instances where
-the function literal is called in a defer or go statement that is the
-last statement in the loop body, as otherwise we would need whole
-program analysis.
+This analyzer reports places where a function literal references the
+iteration variable of an enclosing loop, and the loop calls the function
+in such a way (e.g. with go or defer) that it may outlive the loop
+iteration and possibly observe the wrong value of the variable.
 
-For example:
+In this example, all the deferred functions run after the loop has
+completed, so all observe the final value of v.
 
-	for i, v := range s {
-		go func() {
-			println(i, v) // not what you might expect
-		}()
-	}
+    for _, v := range list {
+        defer func() {
+            use(v) // incorrect
+        }()
+    }
+
+One fix is to create a new variable for each iteration of the loop:
+
+    for _, v := range list {
+        v := v // new var per iteration
+        defer func() {
+            use(v) // ok
+        }()
+    }
+
+The next example uses a go statement and has a similar problem.
+In addition, it has a data race because the loop updates v
+concurrent with the goroutines accessing it.
+
+    for _, v := range elem {
+        go func() {
+            use(v)  // incorrect, and a data race
+        }()
+    }
+
+A fix is the same as before. The checker also reports problems
+in goroutines started by golang.org/x/sync/errgroup.Group.
+A hard-to-spot variant of this form is common in parallel tests:
+
+    func Test(t *testing.T) {
+        for _, test := range tests {
+            t.Run(test.name, func(t *testing.T) {
+                t.Parallel()
+                use(test) // incorrect, and a data race
+            })
+        }
+    }
+
+The t.Parallel() call causes the rest of the function to execute
+concurrent with the loop.
+
+The analyzer reports references only in the last statement,
+as it is not deep enough to understand the effects of subsequent
+statements that might render the reference benign.
+("Last statement" is defined recursively in compound
+statements such as if, switch, and select.)
 
 See: https://golang.org/doc/go_faq.html#closures_and_goroutines`
 
@@ -50,10 +91,12 @@
 	}
 	inspect.Preorder(nodeFilter, func(n ast.Node) {
 		// Find the variables updated by the loop statement.
-		var vars []*ast.Ident
+		var vars []types.Object
 		addVar := func(expr ast.Expr) {
-			if id, ok := expr.(*ast.Ident); ok {
-				vars = append(vars, id)
+			if id, _ := expr.(*ast.Ident); id != nil {
+				if obj := pass.TypesInfo.ObjectOf(id); obj != nil {
+					vars = append(vars, obj)
+				}
 			}
 		}
 		var body *ast.BlockStmt
@@ -79,52 +122,141 @@
 			return
 		}
 
-		// Inspect a go or defer statement
-		// if it's the last one in the loop body.
-		// (We give up if there are following statements,
-		// because it's hard to prove go isn't followed by wait,
-		// or defer by return.)
-		if len(body.List) == 0 {
-			return
-		}
-		// The function invoked in the last return statement.
-		var fun ast.Expr
-		switch s := body.List[len(body.List)-1].(type) {
-		case *ast.GoStmt:
-			fun = s.Call.Fun
-		case *ast.DeferStmt:
-			fun = s.Call.Fun
-		case *ast.ExprStmt: // check for errgroup.Group.Go()
-			if call, ok := s.X.(*ast.CallExpr); ok {
-				fun = goInvokes(pass.TypesInfo, call)
-			}
-		}
-		lit, ok := fun.(*ast.FuncLit)
-		if !ok {
-			return
-		}
-		ast.Inspect(lit.Body, func(n ast.Node) bool {
-			id, ok := n.(*ast.Ident)
-			if !ok || id.Obj == nil {
-				return true
-			}
-			if pass.TypesInfo.Types[id].Type == nil {
-				// Not referring to a variable (e.g. struct field name)
-				return true
-			}
-			for _, v := range vars {
-				if v.Obj == id.Obj {
-					pass.ReportRangef(id, "loop variable %s captured by func literal",
-						id.Name)
+		// Inspect statements to find function literals that may be run outside of
+		// the current loop iteration.
+		//
+		// For go, defer, and errgroup.Group.Go, we ignore all but the last
+		// statement, because it's hard to prove go isn't followed by wait, or
+		// defer by return. "Last" is defined recursively.
+		//
+		// TODO: consider allowing the "last" go/defer/Go statement to be followed by
+		// N "trivial" statements, possibly under a recursive definition of "trivial"
+		// so that that checker could, for example, conclude that a go statement is
+		// followed by an if statement made of only trivial statements and trivial expressions,
+		// and hence the go statement could still be checked.
+		forEachLastStmt(body.List, func(last ast.Stmt) {
+			var stmts []ast.Stmt
+			switch s := last.(type) {
+			case *ast.GoStmt:
+				stmts = litStmts(s.Call.Fun)
+			case *ast.DeferStmt:
+				stmts = litStmts(s.Call.Fun)
+			case *ast.ExprStmt: // check for errgroup.Group.Go
+				if call, ok := s.X.(*ast.CallExpr); ok {
+					stmts = litStmts(goInvoke(pass.TypesInfo, call))
 				}
 			}
-			return true
+			for _, stmt := range stmts {
+				reportCaptured(pass, vars, stmt)
+			}
 		})
+
+		// Also check for testing.T.Run (with T.Parallel).
+		// We consider every t.Run statement in the loop body, because there is
+		// no commonly used mechanism for synchronizing parallel subtests.
+		// It is of course theoretically possible to synchronize parallel subtests,
+		// though such a pattern is likely to be exceedingly rare as it would be
+		// fighting against the test runner.
+		for _, s := range body.List {
+			switch s := s.(type) {
+			case *ast.ExprStmt:
+				if call, ok := s.X.(*ast.CallExpr); ok {
+					for _, stmt := range parallelSubtest(pass.TypesInfo, call) {
+						reportCaptured(pass, vars, stmt)
+					}
+
+				}
+			}
+		}
 	})
 	return nil, nil
 }
 
-// goInvokes returns a function expression that would be called asynchronously
+// reportCaptured reports a diagnostic stating a loop variable
+// has been captured by a func literal if checkStmt has escaping
+// references to vars. vars is expected to be variables updated by a loop statement,
+// and checkStmt is expected to be a statements from the body of a func literal in the loop.
+func reportCaptured(pass *analysis.Pass, vars []types.Object, checkStmt ast.Stmt) {
+	ast.Inspect(checkStmt, func(n ast.Node) bool {
+		id, ok := n.(*ast.Ident)
+		if !ok {
+			return true
+		}
+		obj := pass.TypesInfo.Uses[id]
+		if obj == nil {
+			return true
+		}
+		for _, v := range vars {
+			if v == obj {
+				pass.ReportRangef(id, "loop variable %s captured by func literal", id.Name)
+			}
+		}
+		return true
+	})
+}
+
+// forEachLastStmt calls onLast on each "last" statement in a list of statements.
+// "Last" is defined recursively so, for example, if the last statement is
+// a switch statement, then each switch case is also visited to examine
+// its last statements.
+func forEachLastStmt(stmts []ast.Stmt, onLast func(last ast.Stmt)) {
+	if len(stmts) == 0 {
+		return
+	}
+
+	s := stmts[len(stmts)-1]
+	switch s := s.(type) {
+	case *ast.IfStmt:
+	loop:
+		for {
+			forEachLastStmt(s.Body.List, onLast)
+			switch e := s.Else.(type) {
+			case *ast.BlockStmt:
+				forEachLastStmt(e.List, onLast)
+				break loop
+			case *ast.IfStmt:
+				s = e
+			case nil:
+				break loop
+			}
+		}
+	case *ast.ForStmt:
+		forEachLastStmt(s.Body.List, onLast)
+	case *ast.RangeStmt:
+		forEachLastStmt(s.Body.List, onLast)
+	case *ast.SwitchStmt:
+		for _, c := range s.Body.List {
+			cc := c.(*ast.CaseClause)
+			forEachLastStmt(cc.Body, onLast)
+		}
+	case *ast.TypeSwitchStmt:
+		for _, c := range s.Body.List {
+			cc := c.(*ast.CaseClause)
+			forEachLastStmt(cc.Body, onLast)
+		}
+	case *ast.SelectStmt:
+		for _, c := range s.Body.List {
+			cc := c.(*ast.CommClause)
+			forEachLastStmt(cc.Body, onLast)
+		}
+	default:
+		onLast(s)
+	}
+}
+
+// litStmts returns all statements from the function body of a function
+// literal.
+//
+// If fun is not a function literal, it returns nil.
+func litStmts(fun ast.Expr) []ast.Stmt {
+	lit, _ := fun.(*ast.FuncLit)
+	if lit == nil {
+		return nil
+	}
+	return lit.Body.List
+}
+
+// goInvoke returns a function expression that would be called asynchronously
 // (but not awaited) in another goroutine as a consequence of the call.
 // For example, given the g.Go call below, it returns the function literal expression.
 //
@@ -133,33 +265,169 @@
 //	g.Go(func() error { ... })
 //
 // Currently only "golang.org/x/sync/errgroup.Group()" is considered.
-func goInvokes(info *types.Info, call *ast.CallExpr) ast.Expr {
-	f := typeutil.StaticCallee(info, call)
-	// Note: Currently only supports: golang.org/x/sync/errgroup.Go.
-	if f == nil || f.Name() != "Go" {
-		return nil
-	}
-	recv := f.Type().(*types.Signature).Recv()
-	if recv == nil {
-		return nil
-	}
-	rtype, ok := recv.Type().(*types.Pointer)
-	if !ok {
-		return nil
-	}
-	named, ok := rtype.Elem().(*types.Named)
-	if !ok {
-		return nil
-	}
-	if named.Obj().Name() != "Group" {
-		return nil
-	}
-	pkg := f.Pkg()
-	if pkg == nil {
-		return nil
-	}
-	if pkg.Path() != "golang.org/x/sync/errgroup" {
+func goInvoke(info *types.Info, call *ast.CallExpr) ast.Expr {
+	if !isMethodCall(info, call, "golang.org/x/sync/errgroup", "Group", "Go") {
 		return nil
 	}
 	return call.Args[0]
 }
+
+// parallelSubtest returns statements that can be easily proven to execute
+// concurrently via the go test runner, as t.Run has been invoked with a
+// function literal that calls t.Parallel.
+//
+// In practice, users rely on the fact that statements before the call to
+// t.Parallel are synchronous. For example by declaring test := test inside the
+// function literal, but before the call to t.Parallel.
+//
+// Therefore, we only flag references in statements that are obviously
+// dominated by a call to t.Parallel. As a simple heuristic, we only consider
+// statements following the final labeled statement in the function body, to
+// avoid scenarios where a jump would cause either the call to t.Parallel or
+// the problematic reference to be skipped.
+//
+//	import "testing"
+//
+//	func TestFoo(t *testing.T) {
+//		tests := []int{0, 1, 2}
+//		for i, test := range tests {
+//			t.Run("subtest", func(t *testing.T) {
+//				println(i, test) // OK
+//		 		t.Parallel()
+//				println(i, test) // Not OK
+//			})
+//		}
+//	}
+func parallelSubtest(info *types.Info, call *ast.CallExpr) []ast.Stmt {
+	if !isMethodCall(info, call, "testing", "T", "Run") {
+		return nil
+	}
+
+	if len(call.Args) != 2 {
+		// Ignore calls such as t.Run(fn()).
+		return nil
+	}
+
+	lit, _ := call.Args[1].(*ast.FuncLit)
+	if lit == nil {
+		return nil
+	}
+
+	// Capture the *testing.T object for the first argument to the function
+	// literal.
+	if len(lit.Type.Params.List[0].Names) == 0 {
+		return nil
+	}
+
+	tObj := info.Defs[lit.Type.Params.List[0].Names[0]]
+	if tObj == nil {
+		return nil
+	}
+
+	// Match statements that occur after a call to t.Parallel following the final
+	// labeled statement in the function body.
+	//
+	// We iterate over lit.Body.List to have a simple, fast and "frequent enough"
+	// dominance relationship for t.Parallel(): lit.Body.List[i] dominates
+	// lit.Body.List[j] for i < j unless there is a jump.
+	var stmts []ast.Stmt
+	afterParallel := false
+	for _, stmt := range lit.Body.List {
+		stmt, labeled := unlabel(stmt)
+		if labeled {
+			// Reset: naively we don't know if a jump could have caused the
+			// previously considered statements to be skipped.
+			stmts = nil
+			afterParallel = false
+		}
+
+		if afterParallel {
+			stmts = append(stmts, stmt)
+			continue
+		}
+
+		// Check if stmt is a call to t.Parallel(), for the correct t.
+		exprStmt, ok := stmt.(*ast.ExprStmt)
+		if !ok {
+			continue
+		}
+		expr := exprStmt.X
+		if isMethodCall(info, expr, "testing", "T", "Parallel") {
+			call, _ := expr.(*ast.CallExpr)
+			if call == nil {
+				continue
+			}
+			x, _ := call.Fun.(*ast.SelectorExpr)
+			if x == nil {
+				continue
+			}
+			id, _ := x.X.(*ast.Ident)
+			if id == nil {
+				continue
+			}
+			if info.Uses[id] == tObj {
+				afterParallel = true
+			}
+		}
+	}
+
+	return stmts
+}
+
+// unlabel returns the inner statement for the possibly labeled statement stmt,
+// stripping any (possibly nested) *ast.LabeledStmt wrapper.
+//
+// The second result reports whether stmt was an *ast.LabeledStmt.
+func unlabel(stmt ast.Stmt) (ast.Stmt, bool) {
+	labeled := false
+	for {
+		labelStmt, ok := stmt.(*ast.LabeledStmt)
+		if !ok {
+			return stmt, labeled
+		}
+		labeled = true
+		stmt = labelStmt.Stmt
+	}
+}
+
+// isMethodCall reports whether expr is a method call of
+// <pkgPath>.<typeName>.<method>.
+func isMethodCall(info *types.Info, expr ast.Expr, pkgPath, typeName, method string) bool {
+	call, ok := expr.(*ast.CallExpr)
+	if !ok {
+		return false
+	}
+
+	// Check that we are calling a method <method>
+	f := typeutil.StaticCallee(info, call)
+	if f == nil || f.Name() != method {
+		return false
+	}
+	recv := f.Type().(*types.Signature).Recv()
+	if recv == nil {
+		return false
+	}
+
+	// Check that the receiver is a <pkgPath>.<typeName> or
+	// *<pkgPath>.<typeName>.
+	rtype := recv.Type()
+	if ptr, ok := recv.Type().(*types.Pointer); ok {
+		rtype = ptr.Elem()
+	}
+	named, ok := rtype.(*types.Named)
+	if !ok {
+		return false
+	}
+	if named.Obj().Name() != typeName {
+		return false
+	}
+	pkg := f.Pkg()
+	if pkg == nil {
+		return false
+	}
+	if pkg.Path() != pkgPath {
+		return false
+	}
+
+	return true
+}
diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/printf/printf.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/printf/printf.go
index c4ccc95..daaf709 100644
--- a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/printf/printf.go
+++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/printf/printf.go
@@ -583,7 +583,6 @@
 	argNum := firstArg
 	maxArgNum := firstArg
 	anyIndex := false
-	anyW := false
 	for i, w := 0, 0; i < len(format); i += w {
 		w = 1
 		if format[i] != '%' {
@@ -606,11 +605,6 @@
 				pass.Reportf(call.Pos(), "%s does not support error-wrapping directive %%w", state.name)
 				return
 			}
-			if anyW {
-				pass.Reportf(call.Pos(), "%s call has more than one error-wrapping directive %%w", state.name)
-				return
-			}
-			anyW = true
 		}
 		if len(state.argNums) > 0 {
 			// Continue with the next sequential argument.
@@ -672,12 +666,13 @@
 	s.scanNum()
 	ok := true
 	if s.nbytes == len(s.format) || s.nbytes == start || s.format[s.nbytes] != ']' {
-		ok = false
-		s.nbytes = strings.Index(s.format, "]")
+		ok = false // syntax error is either missing "]" or invalid index.
+		s.nbytes = strings.Index(s.format[start:], "]")
 		if s.nbytes < 0 {
 			s.pass.ReportRangef(s.call, "%s format %s is missing closing ]", s.name, s.format)
 			return false
 		}
+		s.nbytes = s.nbytes + start
 	}
 	arg32, err := strconv.ParseInt(s.format[start:s.nbytes], 10, 32)
 	if err != nil || !ok || arg32 <= 0 || arg32 > int64(len(s.call.Args)-s.firstArg) {
@@ -950,11 +945,16 @@
 		return "", false
 	}
 
+	// inScope returns true if e is in the scope of f.
+	inScope := func(e ast.Expr, f *types.Func) bool {
+		return f.Scope() != nil && f.Scope().Contains(e.Pos())
+	}
+
 	// Is the expression e within the body of that String or Error method?
 	var method *types.Func
-	if strOk && strMethod.Pkg() == pass.Pkg && strMethod.Scope().Contains(e.Pos()) {
+	if strOk && strMethod.Pkg() == pass.Pkg && inScope(e, strMethod) {
 		method = strMethod
-	} else if errOk && errMethod.Pkg() == pass.Pkg && errMethod.Scope().Contains(e.Pos()) {
+	} else if errOk && errMethod.Pkg() == pass.Pkg && inScope(e, errMethod) {
 		method = errMethod
 	} else {
 		return "", false
diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/printf/types.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/printf/types.go
index 270e917..7cbb0bd 100644
--- a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/printf/types.go
+++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/printf/types.go
@@ -299,13 +299,3 @@
 
 	return false
 }
-
-// hasBasicType reports whether x's type is a types.Basic with the given kind.
-func hasBasicType(pass *analysis.Pass, x ast.Expr, kind types.BasicKind) bool {
-	t := pass.TypesInfo.Types[x].Type
-	if t != nil {
-		t = t.Underlying()
-	}
-	b, ok := t.(*types.Basic)
-	return ok && b.Kind() == kind
-}
diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/stdmethods/stdmethods.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/stdmethods/stdmethods.go
index cc94971..41f455d 100644
--- a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/stdmethods/stdmethods.go
+++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/stdmethods/stdmethods.go
@@ -134,6 +134,19 @@
 		}
 	}
 
+	// Special case: Unwrap has two possible signatures.
+	// Check for Unwrap() []error here.
+	if id.Name == "Unwrap" {
+		if args.Len() == 0 && results.Len() == 1 {
+			t := typeString(results.At(0).Type())
+			if t == "error" || t == "[]error" {
+				return
+			}
+		}
+		pass.ReportRangef(id, "method Unwrap() should have signature Unwrap() error or Unwrap() []error")
+		return
+	}
+
 	// Do the =s (if any) all match?
 	if !matchParams(pass, expect.args, args, "=") || !matchParams(pass, expect.results, results, "=") {
 		return
diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/tests/tests.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/tests/tests.go
index 56b20eb..935aad0 100644
--- a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/tests/tests.go
+++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/tests/tests.go
@@ -269,7 +269,9 @@
 	if !ok {
 		return false
 	}
-	return named.Obj().Pkg().Path() == "testing" && named.Obj().Name() == testingType
+	obj := named.Obj()
+	// obj.Pkg is nil for the error type.
+	return obj != nil && obj.Pkg() != nil && obj.Pkg().Path() == "testing" && obj.Name() == testingType
 }
 
 // Validate that fuzz target function's arguments are of accepted types.
@@ -475,10 +477,12 @@
 	if tparams := typeparams.ForFuncType(fn.Type); tparams != nil && len(tparams.List) > 0 {
 		// Note: cmd/go/internal/load also errors about TestXXX and BenchmarkXXX functions with type parameters.
 		// We have currently decided to also warn before compilation/package loading. This can help users in IDEs.
+		// TODO(adonovan): use ReportRangef(tparams).
 		pass.Reportf(fn.Pos(), "%s has type parameters: it will not be run by go test as a %sXXX function", fn.Name.Name, prefix)
 	}
 
 	if !isTestSuffix(fn.Name.Name[len(prefix):]) {
+		// TODO(adonovan): use ReportRangef(fn.Name).
 		pass.Reportf(fn.Pos(), "%s has malformed name: first letter after '%s' must not be lowercase", fn.Name.Name, prefix)
 	}
 }
diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/timeformat/timeformat.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/timeformat/timeformat.go
new file mode 100644
index 0000000..acb198f
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/passes/timeformat/timeformat.go
@@ -0,0 +1,129 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package timeformat defines an Analyzer that checks for the use
+// of time.Format or time.Parse calls with a bad format.
+package timeformat
+
+import (
+	"go/ast"
+	"go/constant"
+	"go/token"
+	"go/types"
+	"strings"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+	"golang.org/x/tools/go/ast/inspector"
+	"golang.org/x/tools/go/types/typeutil"
+)
+
+const badFormat = "2006-02-01"
+const goodFormat = "2006-01-02"
+
+const Doc = `check for calls of (time.Time).Format or time.Parse with 2006-02-01
+
+The timeformat checker looks for time formats with the 2006-02-01 (yyyy-dd-mm)
+format. Internationally, "yyyy-dd-mm" does not occur in common calendar date
+standards, and so it is more likely that 2006-01-02 (yyyy-mm-dd) was intended.
+`
+
+var Analyzer = &analysis.Analyzer{
+	Name:     "timeformat",
+	Doc:      Doc,
+	Requires: []*analysis.Analyzer{inspect.Analyzer},
+	Run:      run,
+}
+
+func run(pass *analysis.Pass) (interface{}, error) {
+	inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
+
+	nodeFilter := []ast.Node{
+		(*ast.CallExpr)(nil),
+	}
+	inspect.Preorder(nodeFilter, func(n ast.Node) {
+		call := n.(*ast.CallExpr)
+		fn, ok := typeutil.Callee(pass.TypesInfo, call).(*types.Func)
+		if !ok {
+			return
+		}
+		if !isTimeDotFormat(fn) && !isTimeDotParse(fn) {
+			return
+		}
+		if len(call.Args) > 0 {
+			arg := call.Args[0]
+			badAt := badFormatAt(pass.TypesInfo, arg)
+
+			if badAt > -1 {
+				// Check if it's a literal string, otherwise we can't suggest a fix.
+				if _, ok := arg.(*ast.BasicLit); ok {
+					pos := int(arg.Pos()) + badAt + 1 // +1 to skip the " or `
+					end := pos + len(badFormat)
+
+					pass.Report(analysis.Diagnostic{
+						Pos:     token.Pos(pos),
+						End:     token.Pos(end),
+						Message: badFormat + " should be " + goodFormat,
+						SuggestedFixes: []analysis.SuggestedFix{{
+							Message: "Replace " + badFormat + " with " + goodFormat,
+							TextEdits: []analysis.TextEdit{{
+								Pos:     token.Pos(pos),
+								End:     token.Pos(end),
+								NewText: []byte(goodFormat),
+							}},
+						}},
+					})
+				} else {
+					pass.Reportf(arg.Pos(), badFormat+" should be "+goodFormat)
+				}
+			}
+		}
+	})
+	return nil, nil
+}
+
+func isTimeDotFormat(f *types.Func) bool {
+	if f.Name() != "Format" || f.Pkg().Path() != "time" {
+		return false
+	}
+	sig, ok := f.Type().(*types.Signature)
+	if !ok {
+		return false
+	}
+	// Verify that the receiver is time.Time.
+	recv := sig.Recv()
+	if recv == nil {
+		return false
+	}
+	named, ok := recv.Type().(*types.Named)
+	return ok && named.Obj().Name() == "Time"
+}
+
+func isTimeDotParse(f *types.Func) bool {
+	if f.Name() != "Parse" || f.Pkg().Path() != "time" {
+		return false
+	}
+	// Verify that there is no receiver.
+	sig, ok := f.Type().(*types.Signature)
+	return ok && sig.Recv() == nil
+}
+
+// badFormatAt return the start of a bad format in e or -1 if no bad format is found.
+func badFormatAt(info *types.Info, e ast.Expr) int {
+	tv, ok := info.Types[e]
+	if !ok { // no type info, assume good
+		return -1
+	}
+
+	t, ok := tv.Type.(*types.Basic)
+	if !ok || t.Info()&types.IsString == 0 {
+		return -1
+	}
+
+	if tv.Value == nil {
+		return -1
+	}
+
+	return strings.Index(constant.StringVal(tv.Value), badFormat)
+}
diff --git a/src/cmd/vendor/golang.org/x/tools/go/analysis/unitchecker/unitchecker.go b/src/cmd/vendor/golang.org/x/tools/go/analysis/unitchecker/unitchecker.go
index 9827b57..6e6907d 100644
--- a/src/cmd/vendor/golang.org/x/tools/go/analysis/unitchecker/unitchecker.go
+++ b/src/cmd/vendor/golang.org/x/tools/go/analysis/unitchecker/unitchecker.go
@@ -50,7 +50,7 @@
 
 	"golang.org/x/tools/go/analysis"
 	"golang.org/x/tools/go/analysis/internal/analysisflags"
-	"golang.org/x/tools/go/analysis/internal/facts"
+	"golang.org/x/tools/internal/facts"
 	"golang.org/x/tools/internal/typeparams"
 )
 
@@ -287,13 +287,13 @@
 	analyzers = filtered
 
 	// Read facts from imported packages.
-	read := func(path string) ([]byte, error) {
-		if vetx, ok := cfg.PackageVetx[path]; ok {
+	read := func(imp *types.Package) ([]byte, error) {
+		if vetx, ok := cfg.PackageVetx[imp.Path()]; ok {
 			return ioutil.ReadFile(vetx)
 		}
 		return nil, nil // no .vetx file, no facts
 	}
-	facts, err := facts.Decode(pkg, read)
+	facts, err := facts.NewDecoder(pkg).Decode(read)
 	if err != nil {
 		return nil, err
 	}
@@ -340,6 +340,7 @@
 				Pkg:               pkg,
 				TypesInfo:         info,
 				TypesSizes:        tc.Sizes,
+				TypeErrors:        nil, // unitchecker doesn't RunDespiteErrors
 				ResultOf:          inputs,
 				Report:            func(d analysis.Diagnostic) { act.diagnostics = append(act.diagnostics, d) },
 				ImportObjectFact:  facts.ImportObjectFact,
diff --git a/src/cmd/vendor/golang.org/x/tools/go/ast/astutil/enclosing.go b/src/cmd/vendor/golang.org/x/tools/go/ast/astutil/enclosing.go
index 1d8c401..9fa5aa1 100644
--- a/src/cmd/vendor/golang.org/x/tools/go/ast/astutil/enclosing.go
+++ b/src/cmd/vendor/golang.org/x/tools/go/ast/astutil/enclosing.go
@@ -54,11 +54,11 @@
 // interior whitespace of the assignment.  E is considered interior
 // whitespace of the BlockStmt containing the assignment.
 //
-// Precondition: [start, end) both lie within the same file as root.
-// TODO(adonovan): return (nil, false) in this case and remove precond.
-// Requires FileSet; see loader.tokenFileContainsPos.
-//
-// Postcondition: path is never nil; it always contains at least 'root'.
+// The resulting path is never empty; it always contains at least the
+// 'root' *ast.File.  Ideally PathEnclosingInterval would reject
+// intervals that lie wholly or partially outside the range of the
+// file, but unfortunately ast.File records only the token.Pos of
+// the 'package' keyword, but not of the start of the file itself.
 func PathEnclosingInterval(root *ast.File, start, end token.Pos) (path []ast.Node, exact bool) {
 	// fmt.Printf("EnclosingInterval %d %d\n", start, end) // debugging
 
@@ -134,6 +134,7 @@
 		return false // inexact: overlaps multiple children
 	}
 
+	// Ensure [start,end) is nondecreasing.
 	if start > end {
 		start, end = end, start
 	}
diff --git a/src/cmd/vendor/golang.org/x/tools/go/ast/inspector/typeof.go b/src/cmd/vendor/golang.org/x/tools/go/ast/inspector/typeof.go
index 11ab2bc..703c813 100644
--- a/src/cmd/vendor/golang.org/x/tools/go/ast/inspector/typeof.go
+++ b/src/cmd/vendor/golang.org/x/tools/go/ast/inspector/typeof.go
@@ -11,6 +11,7 @@
 
 import (
 	"go/ast"
+	"math"
 
 	"golang.org/x/tools/internal/typeparams"
 )
@@ -218,7 +219,7 @@
 
 func maskOf(nodes []ast.Node) uint64 {
 	if nodes == nil {
-		return 1<<64 - 1 // match all node types
+		return math.MaxUint64 // match all node types
 	}
 	var mask uint64
 	for _, n := range nodes {
diff --git a/src/cmd/vendor/golang.org/x/tools/go/types/typeutil/map.go b/src/cmd/vendor/golang.org/x/tools/go/types/typeutil/map.go
index dcc029b..7bd2fdb 100644
--- a/src/cmd/vendor/golang.org/x/tools/go/types/typeutil/map.go
+++ b/src/cmd/vendor/golang.org/x/tools/go/types/typeutil/map.go
@@ -332,7 +332,9 @@
 			// Method order is not significant.
 			// Ignore m.Pkg().
 			m := t.Method(i)
-			hash += 3*hashString(m.Name()) + 5*h.Hash(m.Type())
+			// Use shallow hash on method signature to
+			// avoid anonymous interface cycles.
+			hash += 3*hashString(m.Name()) + 5*h.shallowHash(m.Type())
 		}
 
 		// Hash type restrictions.
@@ -434,3 +436,76 @@
 	h.ptrMap[ptr] = hash
 	return hash
 }
+
+// shallowHash computes a hash of t without looking at any of its
+// element Types, to avoid potential anonymous cycles in the types of
+// interface methods.
+//
+// When an unnamed non-empty interface type appears anywhere among the
+// arguments or results of an interface method, there is a potential
+// for endless recursion. Consider:
+//
+//	type X interface { m() []*interface { X } }
+//
+// The problem is that the Methods of the interface in m's result type
+// include m itself; there is no mention of the named type X that
+// might help us break the cycle.
+// (See comment in go/types.identical, case *Interface, for more.)
+func (h Hasher) shallowHash(t types.Type) uint32 {
+	// t is the type of an interface method (Signature),
+	// its params or results (Tuples), or their immediate
+	// elements (mostly Slice, Pointer, Basic, Named),
+	// so there's no need to optimize anything else.
+	switch t := t.(type) {
+	case *types.Signature:
+		var hash uint32 = 604171
+		if t.Variadic() {
+			hash *= 971767
+		}
+		// The Signature/Tuple recursion is always finite
+		// and invariably shallow.
+		return hash + 1062599*h.shallowHash(t.Params()) + 1282529*h.shallowHash(t.Results())
+
+	case *types.Tuple:
+		n := t.Len()
+		hash := 9137 + 2*uint32(n)
+		for i := 0; i < n; i++ {
+			hash += 53471161 * h.shallowHash(t.At(i).Type())
+		}
+		return hash
+
+	case *types.Basic:
+		return 45212177 * uint32(t.Kind())
+
+	case *types.Array:
+		return 1524181 + 2*uint32(t.Len())
+
+	case *types.Slice:
+		return 2690201
+
+	case *types.Struct:
+		return 3326489
+
+	case *types.Pointer:
+		return 4393139
+
+	case *typeparams.Union:
+		return 562448657
+
+	case *types.Interface:
+		return 2124679 // no recursion here
+
+	case *types.Map:
+		return 9109
+
+	case *types.Chan:
+		return 9127
+
+	case *types.Named:
+		return h.hashPtr(t.Obj())
+
+	case *typeparams.TypeParam:
+		return h.hashPtr(t.Obj())
+	}
+	panic(fmt.Sprintf("shallowHash: %T: %v", t, t))
+}
diff --git a/src/cmd/vendor/golang.org/x/tools/internal/analysisinternal/analysis.go b/src/cmd/vendor/golang.org/x/tools/internal/analysisinternal/analysis.go
index 78ee2c0..d15f0eb 100644
--- a/src/cmd/vendor/golang.org/x/tools/internal/analysisinternal/analysis.go
+++ b/src/cmd/vendor/golang.org/x/tools/internal/analysisinternal/analysis.go
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Package analysisinternal exposes internal-only fields from go/analysis.
+// Package analysisinternal provides gopls' internal analyses with a
+// number of helper functions that operate on typed syntax trees.
 package analysisinternal
 
 import (
@@ -11,20 +12,13 @@
 	"go/ast"
 	"go/token"
 	"go/types"
-	"strings"
-
-	"golang.org/x/tools/go/ast/astutil"
-	"golang.org/x/tools/internal/lsp/fuzzy"
+	"strconv"
 )
 
-// Flag to gate diagnostics for fuzz tests in 1.18.
+// DiagnoseFuzzTests controls whether the 'tests' analyzer diagnoses fuzz tests
+// in Go 1.18+.
 var DiagnoseFuzzTests bool = false
 
-var (
-	GetTypeErrors func(p interface{}) []types.Error
-	SetTypeErrors func(p interface{}, errors []types.Error)
-)
-
 func TypeErrorEndPos(fset *token.FileSet, src []byte, start token.Pos) token.Pos {
 	// Get the end position for the type error.
 	offset, end := fset.PositionFor(start, false).Offset, start
@@ -37,7 +31,7 @@
 	return end
 }
 
-func ZeroValue(fset *token.FileSet, f *ast.File, pkg *types.Package, typ types.Type) ast.Expr {
+func ZeroValue(f *ast.File, pkg *types.Package, typ types.Type) ast.Expr {
 	under := typ
 	if n, ok := typ.(*types.Named); ok {
 		under = n.Underlying()
@@ -57,7 +51,7 @@
 	case *types.Chan, *types.Interface, *types.Map, *types.Pointer, *types.Signature, *types.Slice, *types.Array:
 		return ast.NewIdent("nil")
 	case *types.Struct:
-		texpr := TypeExpr(fset, f, pkg, typ) // typ because we want the name here.
+		texpr := TypeExpr(f, pkg, typ) // typ because we want the name here.
 		if texpr == nil {
 			return nil
 		}
@@ -81,7 +75,10 @@
 	}
 }
 
-func TypeExpr(fset *token.FileSet, f *ast.File, pkg *types.Package, typ types.Type) ast.Expr {
+// TypeExpr returns syntax for the specified type. References to
+// named types from packages other than pkg are qualified by an appropriate
+// package name, as defined by the import environment of file.
+func TypeExpr(f *ast.File, pkg *types.Package, typ types.Type) ast.Expr {
 	switch t := typ.(type) {
 	case *types.Basic:
 		switch t.Kind() {
@@ -91,7 +88,7 @@
 			return ast.NewIdent(t.Name())
 		}
 	case *types.Pointer:
-		x := TypeExpr(fset, f, pkg, t.Elem())
+		x := TypeExpr(f, pkg, t.Elem())
 		if x == nil {
 			return nil
 		}
@@ -100,7 +97,7 @@
 			X:  x,
 		}
 	case *types.Array:
-		elt := TypeExpr(fset, f, pkg, t.Elem())
+		elt := TypeExpr(f, pkg, t.Elem())
 		if elt == nil {
 			return nil
 		}
@@ -112,7 +109,7 @@
 			Elt: elt,
 		}
 	case *types.Slice:
-		elt := TypeExpr(fset, f, pkg, t.Elem())
+		elt := TypeExpr(f, pkg, t.Elem())
 		if elt == nil {
 			return nil
 		}
@@ -120,8 +117,8 @@
 			Elt: elt,
 		}
 	case *types.Map:
-		key := TypeExpr(fset, f, pkg, t.Key())
-		value := TypeExpr(fset, f, pkg, t.Elem())
+		key := TypeExpr(f, pkg, t.Key())
+		value := TypeExpr(f, pkg, t.Elem())
 		if key == nil || value == nil {
 			return nil
 		}
@@ -134,7 +131,7 @@
 		if t.Dir() == types.SendRecv {
 			dir = ast.SEND | ast.RECV
 		}
-		value := TypeExpr(fset, f, pkg, t.Elem())
+		value := TypeExpr(f, pkg, t.Elem())
 		if value == nil {
 			return nil
 		}
@@ -145,7 +142,7 @@
 	case *types.Signature:
 		var params []*ast.Field
 		for i := 0; i < t.Params().Len(); i++ {
-			p := TypeExpr(fset, f, pkg, t.Params().At(i).Type())
+			p := TypeExpr(f, pkg, t.Params().At(i).Type())
 			if p == nil {
 				return nil
 			}
@@ -160,7 +157,7 @@
 		}
 		var returns []*ast.Field
 		for i := 0; i < t.Results().Len(); i++ {
-			r := TypeExpr(fset, f, pkg, t.Results().At(i).Type())
+			r := TypeExpr(f, pkg, t.Results().At(i).Type())
 			if r == nil {
 				return nil
 			}
@@ -184,13 +181,12 @@
 			return ast.NewIdent(t.Obj().Name())
 		}
 		pkgName := t.Obj().Pkg().Name()
+
 		// If the file already imports the package under another name, use that.
-		for _, group := range astutil.Imports(fset, f) {
-			for _, cand := range group {
-				if strings.Trim(cand.Path.Value, `"`) == t.Obj().Pkg().Path() {
-					if cand.Name != nil && cand.Name.Name != "" {
-						pkgName = cand.Name.Name
-					}
+		for _, cand := range f.Imports {
+			if path, _ := strconv.Unquote(cand.Path.Value); path == t.Obj().Pkg().Path() {
+				if cand.Name != nil && cand.Name.Name != "" {
+					pkgName = cand.Name.Name
 				}
 			}
 		}
@@ -210,14 +206,6 @@
 	}
 }
 
-type TypeErrorPass string
-
-const (
-	NoNewVars      TypeErrorPass = "nonewvars"
-	NoResultValues TypeErrorPass = "noresultvalues"
-	UndeclaredName TypeErrorPass = "undeclaredname"
-)
-
 // StmtToInsertVarBefore returns the ast.Stmt before which we can safely insert a new variable.
 // Some examples:
 //
@@ -311,19 +299,21 @@
 	})
 }
 
-// FindMatchingIdents finds all identifiers in 'node' that match any of the given types.
+// MatchingIdents finds the names of all identifiers in 'node' that match any of the given types.
 // 'pos' represents the position at which the identifiers may be inserted. 'pos' must be within
 // the scope of each of identifier we select. Otherwise, we will insert a variable at 'pos' that
 // is unrecognized.
-func FindMatchingIdents(typs []types.Type, node ast.Node, pos token.Pos, info *types.Info, pkg *types.Package) map[types.Type][]*ast.Ident {
-	matches := map[types.Type][]*ast.Ident{}
+func MatchingIdents(typs []types.Type, node ast.Node, pos token.Pos, info *types.Info, pkg *types.Package) map[types.Type][]string {
+
 	// Initialize matches to contain the variable types we are searching for.
+	matches := make(map[types.Type][]string)
 	for _, typ := range typs {
 		if typ == nil {
-			continue
+			continue // TODO(adonovan): is this reachable?
 		}
-		matches[typ] = []*ast.Ident{}
+		matches[typ] = nil // create entry
 	}
+
 	seen := map[types.Object]struct{}{}
 	ast.Inspect(node, func(n ast.Node) bool {
 		if n == nil {
@@ -335,8 +325,7 @@
 		//
 		// x := fakeStruct{f0: x}
 		//
-		assignment, ok := n.(*ast.AssignStmt)
-		if ok && pos > assignment.Pos() && pos <= assignment.End() {
+		if assign, ok := n.(*ast.AssignStmt); ok && pos > assign.Pos() && pos <= assign.End() {
 			return false
 		}
 		if n.End() > pos {
@@ -369,17 +358,17 @@
 			return true
 		}
 		// The object must match one of the types that we are searching for.
-		if idents, ok := matches[obj.Type()]; ok {
-			matches[obj.Type()] = append(idents, ast.NewIdent(ident.Name))
-		}
-		// If the object type does not exactly match any of the target types, greedily
-		// find the first target type that the object type can satisfy.
-		for typ := range matches {
-			if obj.Type() == typ {
-				continue
-			}
-			if equivalentTypes(obj.Type(), typ) {
-				matches[typ] = append(matches[typ], ast.NewIdent(ident.Name))
+		// TODO(adonovan): opt: use typeutil.Map?
+		if names, ok := matches[obj.Type()]; ok {
+			matches[obj.Type()] = append(names, ident.Name)
+		} else {
+			// If the object type does not exactly match
+			// any of the target types, greedily find the first
+			// target type that the object type can satisfy.
+			for typ := range matches {
+				if equivalentTypes(obj.Type(), typ) {
+					matches[typ] = append(matches[typ], ident.Name)
+				}
 			}
 		}
 		return true
@@ -388,7 +377,7 @@
 }
 
 func equivalentTypes(want, got types.Type) bool {
-	if want == got || types.Identical(want, got) {
+	if types.Identical(want, got) {
 		return true
 	}
 	// Code segment to help check for untyped equality from (golang/go#32146).
@@ -399,30 +388,3 @@
 	}
 	return types.AssignableTo(want, got)
 }
-
-// FindBestMatch employs fuzzy matching to evaluate the similarity of each given identifier to the
-// given pattern. We return the identifier whose name is most similar to the pattern.
-func FindBestMatch(pattern string, idents []*ast.Ident) ast.Expr {
-	fuzz := fuzzy.NewMatcher(pattern)
-	var bestFuzz ast.Expr
-	highScore := float32(0) // minimum score is 0 (no match)
-	for _, ident := range idents {
-		// TODO: Improve scoring algorithm.
-		score := fuzz.Score(ident.Name)
-		if score > highScore {
-			highScore = score
-			bestFuzz = ident
-		} else if score == 0 {
-			// Order matters in the fuzzy matching algorithm. If we find no match
-			// when matching the target to the identifier, try matching the identifier
-			// to the target.
-			revFuzz := fuzzy.NewMatcher(ident.Name)
-			revScore := revFuzz.Score(pattern)
-			if revScore > highScore {
-				highScore = revScore
-				bestFuzz = ident
-			}
-		}
-	}
-	return bestFuzz
-}
diff --git a/src/cmd/vendor/golang.org/x/tools/internal/facts/facts.go b/src/cmd/vendor/golang.org/x/tools/internal/facts/facts.go
new file mode 100644
index 0000000..81df451
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/tools/internal/facts/facts.go
@@ -0,0 +1,335 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package facts defines a serializable set of analysis.Fact.
+//
+// It provides a partial implementation of the Fact-related parts of the
+// analysis.Pass interface for use in analysis drivers such as "go vet"
+// and other build systems.
+//
+// The serial format is unspecified and may change, so the same version
+// of this package must be used for reading and writing serialized facts.
+//
+// The handling of facts in the analysis system parallels the handling
+// of type information in the compiler: during compilation of package P,
+// the compiler emits an export data file that describes the type of
+// every object (named thing) defined in package P, plus every object
+// indirectly reachable from one of those objects. Thus the downstream
+// compiler of package Q need only load one export data file per direct
+// import of Q, and it will learn everything about the API of package P
+// and everything it needs to know about the API of P's dependencies.
+//
+// Similarly, analysis of package P emits a fact set containing facts
+// about all objects exported from P, plus additional facts about only
+// those objects of P's dependencies that are reachable from the API of
+// package P; the downstream analysis of Q need only load one fact set
+// per direct import of Q.
+//
+// The notion of "exportedness" that matters here is that of the
+// compiler. According to the language spec, a method pkg.T.f is
+// unexported simply because its name starts with lowercase. But the
+// compiler must nonetheless export f so that downstream compilations can
+// accurately ascertain whether pkg.T implements an interface pkg.I
+// defined as interface{f()}. Exported thus means "described in export
+// data".
+package facts
+
+import (
+	"bytes"
+	"encoding/gob"
+	"fmt"
+	"go/types"
+	"io/ioutil"
+	"log"
+	"reflect"
+	"sort"
+	"sync"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/types/objectpath"
+)
+
+const debug = false
+
+// A Set is a set of analysis.Facts.
+//
+// Decode creates a Set of facts by reading from the imports of a given
+// package, and Encode writes out the set. Between these operation,
+// the Import and Export methods will query and update the set.
+//
+// All of Set's methods except String are safe to call concurrently.
+type Set struct {
+	pkg *types.Package
+	mu  sync.Mutex
+	m   map[key]analysis.Fact
+}
+
+type key struct {
+	pkg *types.Package
+	obj types.Object // (object facts only)
+	t   reflect.Type
+}
+
+// ImportObjectFact implements analysis.Pass.ImportObjectFact.
+func (s *Set) ImportObjectFact(obj types.Object, ptr analysis.Fact) bool {
+	if obj == nil {
+		panic("nil object")
+	}
+	key := key{pkg: obj.Pkg(), obj: obj, t: reflect.TypeOf(ptr)}
+	s.mu.Lock()
+	defer s.mu.Unlock()
+	if v, ok := s.m[key]; ok {
+		reflect.ValueOf(ptr).Elem().Set(reflect.ValueOf(v).Elem())
+		return true
+	}
+	return false
+}
+
+// ExportObjectFact implements analysis.Pass.ExportObjectFact.
+func (s *Set) ExportObjectFact(obj types.Object, fact analysis.Fact) {
+	if obj.Pkg() != s.pkg {
+		log.Panicf("in package %s: ExportObjectFact(%s, %T): can't set fact on object belonging another package",
+			s.pkg, obj, fact)
+	}
+	key := key{pkg: obj.Pkg(), obj: obj, t: reflect.TypeOf(fact)}
+	s.mu.Lock()
+	s.m[key] = fact // clobber any existing entry
+	s.mu.Unlock()
+}
+
+func (s *Set) AllObjectFacts(filter map[reflect.Type]bool) []analysis.ObjectFact {
+	var facts []analysis.ObjectFact
+	s.mu.Lock()
+	for k, v := range s.m {
+		if k.obj != nil && filter[k.t] {
+			facts = append(facts, analysis.ObjectFact{Object: k.obj, Fact: v})
+		}
+	}
+	s.mu.Unlock()
+	return facts
+}
+
+// ImportPackageFact implements analysis.Pass.ImportPackageFact.
+func (s *Set) ImportPackageFact(pkg *types.Package, ptr analysis.Fact) bool {
+	if pkg == nil {
+		panic("nil package")
+	}
+	key := key{pkg: pkg, t: reflect.TypeOf(ptr)}
+	s.mu.Lock()
+	defer s.mu.Unlock()
+	if v, ok := s.m[key]; ok {
+		reflect.ValueOf(ptr).Elem().Set(reflect.ValueOf(v).Elem())
+		return true
+	}
+	return false
+}
+
+// ExportPackageFact implements analysis.Pass.ExportPackageFact.
+func (s *Set) ExportPackageFact(fact analysis.Fact) {
+	key := key{pkg: s.pkg, t: reflect.TypeOf(fact)}
+	s.mu.Lock()
+	s.m[key] = fact // clobber any existing entry
+	s.mu.Unlock()
+}
+
+func (s *Set) AllPackageFacts(filter map[reflect.Type]bool) []analysis.PackageFact {
+	var facts []analysis.PackageFact
+	s.mu.Lock()
+	for k, v := range s.m {
+		if k.obj == nil && filter[k.t] {
+			facts = append(facts, analysis.PackageFact{Package: k.pkg, Fact: v})
+		}
+	}
+	s.mu.Unlock()
+	return facts
+}
+
+// gobFact is the Gob declaration of a serialized fact.
+type gobFact struct {
+	PkgPath string          // path of package
+	Object  objectpath.Path // optional path of object relative to package itself
+	Fact    analysis.Fact   // type and value of user-defined Fact
+}
+
+// A Decoder decodes the facts from the direct imports of the package
+// provided to NewEncoder. A single decoder may be used to decode
+// multiple fact sets (e.g. each for a different set of fact types)
+// for the same package. Each call to Decode returns an independent
+// fact set.
+type Decoder struct {
+	pkg      *types.Package
+	packages map[string]*types.Package
+}
+
+// NewDecoder returns a fact decoder for the specified package.
+func NewDecoder(pkg *types.Package) *Decoder {
+	// Compute the import map for this package.
+	// See the package doc comment.
+	return &Decoder{pkg, importMap(pkg.Imports())}
+}
+
+// Decode decodes all the facts relevant to the analysis of package pkg.
+// The read function reads serialized fact data from an external source
+// for one of of pkg's direct imports. The empty file is a valid
+// encoding of an empty fact set.
+//
+// It is the caller's responsibility to call gob.Register on all
+// necessary fact types.
+func (d *Decoder) Decode(read func(*types.Package) ([]byte, error)) (*Set, error) {
+	// Read facts from imported packages.
+	// Facts may describe indirectly imported packages, or their objects.
+	m := make(map[key]analysis.Fact) // one big bucket
+	for _, imp := range d.pkg.Imports() {
+		logf := func(format string, args ...interface{}) {
+			if debug {
+				prefix := fmt.Sprintf("in %s, importing %s: ",
+					d.pkg.Path(), imp.Path())
+				log.Print(prefix, fmt.Sprintf(format, args...))
+			}
+		}
+
+		// Read the gob-encoded facts.
+		data, err := read(imp)
+		if err != nil {
+			return nil, fmt.Errorf("in %s, can't import facts for package %q: %v",
+				d.pkg.Path(), imp.Path(), err)
+		}
+		if len(data) == 0 {
+			continue // no facts
+		}
+		var gobFacts []gobFact
+		if err := gob.NewDecoder(bytes.NewReader(data)).Decode(&gobFacts); err != nil {
+			return nil, fmt.Errorf("decoding facts for %q: %v", imp.Path(), err)
+		}
+		if debug {
+			logf("decoded %d facts: %v", len(gobFacts), gobFacts)
+		}
+
+		// Parse each one into a key and a Fact.
+		for _, f := range gobFacts {
+			factPkg := d.packages[f.PkgPath]
+			if factPkg == nil {
+				// Fact relates to a dependency that was
+				// unused in this translation unit. Skip.
+				logf("no package %q; discarding %v", f.PkgPath, f.Fact)
+				continue
+			}
+			key := key{pkg: factPkg, t: reflect.TypeOf(f.Fact)}
+			if f.Object != "" {
+				// object fact
+				obj, err := objectpath.Object(factPkg, f.Object)
+				if err != nil {
+					// (most likely due to unexported object)
+					// TODO(adonovan): audit for other possibilities.
+					logf("no object for path: %v; discarding %s", err, f.Fact)
+					continue
+				}
+				key.obj = obj
+				logf("read %T fact %s for %v", f.Fact, f.Fact, key.obj)
+			} else {
+				// package fact
+				logf("read %T fact %s for %v", f.Fact, f.Fact, factPkg)
+			}
+			m[key] = f.Fact
+		}
+	}
+
+	return &Set{pkg: d.pkg, m: m}, nil
+}
+
+// Encode encodes a set of facts to a memory buffer.
+//
+// It may fail if one of the Facts could not be gob-encoded, but this is
+// a sign of a bug in an Analyzer.
+func (s *Set) Encode() []byte {
+
+	// TODO(adonovan): opt: use a more efficient encoding
+	// that avoids repeating PkgPath for each fact.
+
+	// Gather all facts, including those from imported packages.
+	var gobFacts []gobFact
+
+	s.mu.Lock()
+	for k, fact := range s.m {
+		if debug {
+			log.Printf("%v => %s\n", k, fact)
+		}
+		var object objectpath.Path
+		if k.obj != nil {
+			path, err := objectpath.For(k.obj)
+			if err != nil {
+				if debug {
+					log.Printf("discarding fact %s about %s\n", fact, k.obj)
+				}
+				continue // object not accessible from package API; discard fact
+			}
+			object = path
+		}
+		gobFacts = append(gobFacts, gobFact{
+			PkgPath: k.pkg.Path(),
+			Object:  object,
+			Fact:    fact,
+		})
+	}
+	s.mu.Unlock()
+
+	// Sort facts by (package, object, type) for determinism.
+	sort.Slice(gobFacts, func(i, j int) bool {
+		x, y := gobFacts[i], gobFacts[j]
+		if x.PkgPath != y.PkgPath {
+			return x.PkgPath < y.PkgPath
+		}
+		if x.Object != y.Object {
+			return x.Object < y.Object
+		}
+		tx := reflect.TypeOf(x.Fact)
+		ty := reflect.TypeOf(y.Fact)
+		if tx != ty {
+			return tx.String() < ty.String()
+		}
+		return false // equal
+	})
+
+	var buf bytes.Buffer
+	if len(gobFacts) > 0 {
+		if err := gob.NewEncoder(&buf).Encode(gobFacts); err != nil {
+			// Fact encoding should never fail. Identify the culprit.
+			for _, gf := range gobFacts {
+				if err := gob.NewEncoder(ioutil.Discard).Encode(gf); err != nil {
+					fact := gf.Fact
+					pkgpath := reflect.TypeOf(fact).Elem().PkgPath()
+					log.Panicf("internal error: gob encoding of analysis fact %s failed: %v; please report a bug against fact %T in package %q",
+						fact, err, fact, pkgpath)
+				}
+			}
+		}
+	}
+
+	if debug {
+		log.Printf("package %q: encode %d facts, %d bytes\n",
+			s.pkg.Path(), len(gobFacts), buf.Len())
+	}
+
+	return buf.Bytes()
+}
+
+// String is provided only for debugging, and must not be called
+// concurrent with any Import/Export method.
+func (s *Set) String() string {
+	var buf bytes.Buffer
+	buf.WriteString("{")
+	for k, f := range s.m {
+		if buf.Len() > 1 {
+			buf.WriteString(", ")
+		}
+		if k.obj != nil {
+			buf.WriteString(k.obj.String())
+		} else {
+			buf.WriteString(k.pkg.Path())
+		}
+		fmt.Fprintf(&buf, ": %v", f)
+	}
+	buf.WriteString("}")
+	return buf.String()
+}
diff --git a/src/cmd/vendor/golang.org/x/tools/internal/facts/imports.go b/src/cmd/vendor/golang.org/x/tools/internal/facts/imports.go
new file mode 100644
index 0000000..a3aa90d
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/tools/internal/facts/imports.go
@@ -0,0 +1,121 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package facts
+
+import (
+	"go/types"
+
+	"golang.org/x/tools/internal/typeparams"
+)
+
+// importMap computes the import map for a package by traversing the
+// entire exported API each of its imports.
+//
+// This is a workaround for the fact that we cannot access the map used
+// internally by the types.Importer returned by go/importer. The entries
+// in this map are the packages and objects that may be relevant to the
+// current analysis unit.
+//
+// Packages in the map that are only indirectly imported may be
+// incomplete (!pkg.Complete()).
+//
+// TODO(adonovan): opt: compute this information more efficiently
+// by obtaining it from the internals of the gcexportdata decoder.
+func importMap(imports []*types.Package) map[string]*types.Package {
+	objects := make(map[types.Object]bool)
+	packages := make(map[string]*types.Package)
+
+	var addObj func(obj types.Object) bool
+	var addType func(T types.Type)
+
+	addObj = func(obj types.Object) bool {
+		if !objects[obj] {
+			objects[obj] = true
+			addType(obj.Type())
+			if pkg := obj.Pkg(); pkg != nil {
+				packages[pkg.Path()] = pkg
+			}
+			return true
+		}
+		return false
+	}
+
+	addType = func(T types.Type) {
+		switch T := T.(type) {
+		case *types.Basic:
+			// nop
+		case *types.Named:
+			if addObj(T.Obj()) {
+				// TODO(taking): Investigate why the Underlying type is not added here.
+				for i := 0; i < T.NumMethods(); i++ {
+					addObj(T.Method(i))
+				}
+				if tparams := typeparams.ForNamed(T); tparams != nil {
+					for i := 0; i < tparams.Len(); i++ {
+						addType(tparams.At(i))
+					}
+				}
+				if targs := typeparams.NamedTypeArgs(T); targs != nil {
+					for i := 0; i < targs.Len(); i++ {
+						addType(targs.At(i))
+					}
+				}
+			}
+		case *types.Pointer:
+			addType(T.Elem())
+		case *types.Slice:
+			addType(T.Elem())
+		case *types.Array:
+			addType(T.Elem())
+		case *types.Chan:
+			addType(T.Elem())
+		case *types.Map:
+			addType(T.Key())
+			addType(T.Elem())
+		case *types.Signature:
+			addType(T.Params())
+			addType(T.Results())
+			if tparams := typeparams.ForSignature(T); tparams != nil {
+				for i := 0; i < tparams.Len(); i++ {
+					addType(tparams.At(i))
+				}
+			}
+		case *types.Struct:
+			for i := 0; i < T.NumFields(); i++ {
+				addObj(T.Field(i))
+			}
+		case *types.Tuple:
+			for i := 0; i < T.Len(); i++ {
+				addObj(T.At(i))
+			}
+		case *types.Interface:
+			for i := 0; i < T.NumMethods(); i++ {
+				addObj(T.Method(i))
+			}
+			for i := 0; i < T.NumEmbeddeds(); i++ {
+				addType(T.EmbeddedType(i)) // walk Embedded for implicits
+			}
+		case *typeparams.Union:
+			for i := 0; i < T.Len(); i++ {
+				addType(T.Term(i).Type())
+			}
+		case *typeparams.TypeParam:
+			if addObj(T.Obj()) {
+				addType(T.Constraint())
+			}
+		}
+	}
+
+	for _, imp := range imports {
+		packages[imp.Path()] = imp
+
+		scope := imp.Scope()
+		for _, name := range scope.Names() {
+			addObj(scope.Lookup(name))
+		}
+	}
+
+	return packages
+}
diff --git a/src/cmd/vendor/golang.org/x/tools/internal/lsp/fuzzy/input.go b/src/cmd/vendor/golang.org/x/tools/internal/lsp/fuzzy/input.go
deleted file mode 100644
index c103816..0000000
--- a/src/cmd/vendor/golang.org/x/tools/internal/lsp/fuzzy/input.go
+++ /dev/null
@@ -1,183 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package fuzzy
-
-import (
-	"unicode"
-)
-
-// RuneRole specifies the role of a rune in the context of an input.
-type RuneRole byte
-
-const (
-	// RNone specifies a rune without any role in the input (i.e., whitespace/non-ASCII).
-	RNone RuneRole = iota
-	// RSep specifies a rune with the role of segment separator.
-	RSep
-	// RTail specifies a rune which is a lower-case tail in a word in the input.
-	RTail
-	// RUCTail specifies a rune which is an upper-case tail in a word in the input.
-	RUCTail
-	// RHead specifies a rune which is the first character in a word in the input.
-	RHead
-)
-
-// RuneRoles detects the roles of each byte rune in an input string and stores it in the output
-// slice. The rune role depends on the input type. Stops when it parsed all the runes in the string
-// or when it filled the output. If output is nil, then it gets created.
-func RuneRoles(candidate []byte, reuse []RuneRole) []RuneRole {
-	var output []RuneRole
-	if cap(reuse) < len(candidate) {
-		output = make([]RuneRole, 0, len(candidate))
-	} else {
-		output = reuse[:0]
-	}
-
-	prev, prev2 := rtNone, rtNone
-	for i := 0; i < len(candidate); i++ {
-		r := rune(candidate[i])
-
-		role := RNone
-
-		curr := rtLower
-		if candidate[i] <= unicode.MaxASCII {
-			curr = runeType(rt[candidate[i]] - '0')
-		}
-
-		if curr == rtLower {
-			if prev == rtNone || prev == rtPunct {
-				role = RHead
-			} else {
-				role = RTail
-			}
-		} else if curr == rtUpper {
-			role = RHead
-
-			if prev == rtUpper {
-				// This and previous characters are both upper case.
-
-				if i+1 == len(candidate) {
-					// This is last character, previous was also uppercase -> this is UCTail
-					// i.e., (current char is C): aBC / BC / ABC
-					role = RUCTail
-				}
-			}
-		} else if curr == rtPunct {
-			switch r {
-			case '.', ':':
-				role = RSep
-			}
-		}
-		if curr != rtLower {
-			if i > 1 && output[i-1] == RHead && prev2 == rtUpper && (output[i-2] == RHead || output[i-2] == RUCTail) {
-				// The previous two characters were uppercase. The current one is not a lower case, so the
-				// previous one can't be a HEAD. Make it a UCTail.
-				// i.e., (last char is current char - B must be a UCTail): ABC / ZABC / AB.
-				output[i-1] = RUCTail
-			}
-		}
-
-		output = append(output, role)
-		prev2 = prev
-		prev = curr
-	}
-	return output
-}
-
-type runeType byte
-
-const (
-	rtNone runeType = iota
-	rtPunct
-	rtLower
-	rtUpper
-)
-
-const rt = "00000000000000000000000000000000000000000000001122222222221000000333333333333333333333333330000002222222222222222222222222200000"
-
-// LastSegment returns the substring representing the last segment from the input, where each
-// byte has an associated RuneRole in the roles slice. This makes sense only for inputs of Symbol
-// or Filename type.
-func LastSegment(input string, roles []RuneRole) string {
-	// Exclude ending separators.
-	end := len(input) - 1
-	for end >= 0 && roles[end] == RSep {
-		end--
-	}
-	if end < 0 {
-		return ""
-	}
-
-	start := end - 1
-	for start >= 0 && roles[start] != RSep {
-		start--
-	}
-
-	return input[start+1 : end+1]
-}
-
-// fromChunks copies string chunks into the given buffer.
-func fromChunks(chunks []string, buffer []byte) []byte {
-	ii := 0
-	for _, chunk := range chunks {
-		for i := 0; i < len(chunk); i++ {
-			if ii >= cap(buffer) {
-				break
-			}
-			buffer[ii] = chunk[i]
-			ii++
-		}
-	}
-	return buffer[:ii]
-}
-
-// toLower transforms the input string to lower case, which is stored in the output byte slice.
-// The lower casing considers only ASCII values - non ASCII values are left unmodified.
-// Stops when parsed all input or when it filled the output slice. If output is nil, then it gets
-// created.
-func toLower(input []byte, reuse []byte) []byte {
-	output := reuse
-	if cap(reuse) < len(input) {
-		output = make([]byte, len(input))
-	}
-
-	for i := 0; i < len(input); i++ {
-		r := rune(input[i])
-		if input[i] <= unicode.MaxASCII {
-			if 'A' <= r && r <= 'Z' {
-				r += 'a' - 'A'
-			}
-		}
-		output[i] = byte(r)
-	}
-	return output[:len(input)]
-}
-
-// WordConsumer defines a consumer for a word delimited by the [start,end) byte offsets in an input
-// (start is inclusive, end is exclusive).
-type WordConsumer func(start, end int)
-
-// Words find word delimiters in an input based on its bytes' mappings to rune roles. The offset
-// delimiters for each word are fed to the provided consumer function.
-func Words(roles []RuneRole, consume WordConsumer) {
-	var wordStart int
-	for i, r := range roles {
-		switch r {
-		case RUCTail, RTail:
-		case RHead, RNone, RSep:
-			if i != wordStart {
-				consume(wordStart, i)
-			}
-			wordStart = i
-			if r != RHead {
-				// Skip this character.
-				wordStart = i + 1
-			}
-		}
-	}
-	if wordStart != len(roles) {
-		consume(wordStart, len(roles))
-	}
-}
diff --git a/src/cmd/vendor/golang.org/x/tools/internal/lsp/fuzzy/matcher.go b/src/cmd/vendor/golang.org/x/tools/internal/lsp/fuzzy/matcher.go
deleted file mode 100644
index 265cdcf..0000000
--- a/src/cmd/vendor/golang.org/x/tools/internal/lsp/fuzzy/matcher.go
+++ /dev/null
@@ -1,407 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package fuzzy implements a fuzzy matching algorithm.
-package fuzzy
-
-import (
-	"bytes"
-	"fmt"
-)
-
-const (
-	// MaxInputSize is the maximum size of the input scored against the fuzzy matcher. Longer inputs
-	// will be truncated to this size.
-	MaxInputSize = 127
-	// MaxPatternSize is the maximum size of the pattern used to construct the fuzzy matcher. Longer
-	// inputs are truncated to this size.
-	MaxPatternSize = 63
-)
-
-type scoreVal int
-
-func (s scoreVal) val() int {
-	return int(s) >> 1
-}
-
-func (s scoreVal) prevK() int {
-	return int(s) & 1
-}
-
-func score(val int, prevK int /*0 or 1*/) scoreVal {
-	return scoreVal(val<<1 + prevK)
-}
-
-// Matcher implements a fuzzy matching algorithm for scoring candidates against a pattern.
-// The matcher does not support parallel usage.
-type Matcher struct {
-	pattern       string
-	patternLower  []byte // lower-case version of the pattern
-	patternShort  []byte // first characters of the pattern
-	caseSensitive bool   // set if the pattern is mix-cased
-
-	patternRoles []RuneRole // the role of each character in the pattern
-	roles        []RuneRole // the role of each character in the tested string
-
-	scores [MaxInputSize + 1][MaxPatternSize + 1][2]scoreVal
-
-	scoreScale float32
-
-	lastCandidateLen     int // in bytes
-	lastCandidateMatched bool
-
-	// Reusable buffers to avoid allocating for every candidate.
-	//  - inputBuf stores the concatenated input chunks
-	//  - lowerBuf stores the last candidate in lower-case
-	//  - rolesBuf stores the calculated roles for each rune in the last
-	//    candidate.
-	inputBuf [MaxInputSize]byte
-	lowerBuf [MaxInputSize]byte
-	rolesBuf [MaxInputSize]RuneRole
-}
-
-func (m *Matcher) bestK(i, j int) int {
-	if m.scores[i][j][0].val() < m.scores[i][j][1].val() {
-		return 1
-	}
-	return 0
-}
-
-// NewMatcher returns a new fuzzy matcher for scoring candidates against the provided pattern.
-func NewMatcher(pattern string) *Matcher {
-	if len(pattern) > MaxPatternSize {
-		pattern = pattern[:MaxPatternSize]
-	}
-
-	m := &Matcher{
-		pattern:      pattern,
-		patternLower: toLower([]byte(pattern), nil),
-	}
-
-	for i, c := range m.patternLower {
-		if pattern[i] != c {
-			m.caseSensitive = true
-			break
-		}
-	}
-
-	if len(pattern) > 3 {
-		m.patternShort = m.patternLower[:3]
-	} else {
-		m.patternShort = m.patternLower
-	}
-
-	m.patternRoles = RuneRoles([]byte(pattern), nil)
-
-	if len(pattern) > 0 {
-		maxCharScore := 4
-		m.scoreScale = 1 / float32(maxCharScore*len(pattern))
-	}
-
-	return m
-}
-
-// Score returns the score returned by matching the candidate to the pattern.
-// This is not designed for parallel use. Multiple candidates must be scored sequentially.
-// Returns a score between 0 and 1 (0 - no match, 1 - perfect match).
-func (m *Matcher) Score(candidate string) float32 {
-	return m.ScoreChunks([]string{candidate})
-}
-
-func (m *Matcher) ScoreChunks(chunks []string) float32 {
-	candidate := fromChunks(chunks, m.inputBuf[:])
-	if len(candidate) > MaxInputSize {
-		candidate = candidate[:MaxInputSize]
-	}
-	lower := toLower(candidate, m.lowerBuf[:])
-	m.lastCandidateLen = len(candidate)
-
-	if len(m.pattern) == 0 {
-		// Empty patterns perfectly match candidates.
-		return 1
-	}
-
-	if m.match(candidate, lower) {
-		sc := m.computeScore(candidate, lower)
-		if sc > minScore/2 && !m.poorMatch() {
-			m.lastCandidateMatched = true
-			if len(m.pattern) == len(candidate) {
-				// Perfect match.
-				return 1
-			}
-
-			if sc < 0 {
-				sc = 0
-			}
-			normalizedScore := float32(sc) * m.scoreScale
-			if normalizedScore > 1 {
-				normalizedScore = 1
-			}
-
-			return normalizedScore
-		}
-	}
-
-	m.lastCandidateMatched = false
-	return 0
-}
-
-const minScore = -10000
-
-// MatchedRanges returns matches ranges for the last scored string as a flattened array of
-// [begin, end) byte offset pairs.
-func (m *Matcher) MatchedRanges() []int {
-	if len(m.pattern) == 0 || !m.lastCandidateMatched {
-		return nil
-	}
-	i, j := m.lastCandidateLen, len(m.pattern)
-	if m.scores[i][j][0].val() < minScore/2 && m.scores[i][j][1].val() < minScore/2 {
-		return nil
-	}
-
-	var ret []int
-	k := m.bestK(i, j)
-	for i > 0 {
-		take := (k == 1)
-		k = m.scores[i][j][k].prevK()
-		if take {
-			if len(ret) == 0 || ret[len(ret)-1] != i {
-				ret = append(ret, i)
-				ret = append(ret, i-1)
-			} else {
-				ret[len(ret)-1] = i - 1
-			}
-			j--
-		}
-		i--
-	}
-	// Reverse slice.
-	for i := 0; i < len(ret)/2; i++ {
-		ret[i], ret[len(ret)-1-i] = ret[len(ret)-1-i], ret[i]
-	}
-	return ret
-}
-
-func (m *Matcher) match(candidate []byte, candidateLower []byte) bool {
-	i, j := 0, 0
-	for ; i < len(candidateLower) && j < len(m.patternLower); i++ {
-		if candidateLower[i] == m.patternLower[j] {
-			j++
-		}
-	}
-	if j != len(m.patternLower) {
-		return false
-	}
-
-	// The input passes the simple test against pattern, so it is time to classify its characters.
-	// Character roles are used below to find the last segment.
-	m.roles = RuneRoles(candidate, m.rolesBuf[:])
-
-	return true
-}
-
-func (m *Matcher) computeScore(candidate []byte, candidateLower []byte) int {
-	pattLen, candLen := len(m.pattern), len(candidate)
-
-	for j := 0; j <= len(m.pattern); j++ {
-		m.scores[0][j][0] = minScore << 1
-		m.scores[0][j][1] = minScore << 1
-	}
-	m.scores[0][0][0] = score(0, 0) // Start with 0.
-
-	segmentsLeft, lastSegStart := 1, 0
-	for i := 0; i < candLen; i++ {
-		if m.roles[i] == RSep {
-			segmentsLeft++
-			lastSegStart = i + 1
-		}
-	}
-
-	// A per-character bonus for a consecutive match.
-	consecutiveBonus := 2
-	wordIdx := 0 // Word count within segment.
-	for i := 1; i <= candLen; i++ {
-
-		role := m.roles[i-1]
-		isHead := role == RHead
-
-		if isHead {
-			wordIdx++
-		} else if role == RSep && segmentsLeft > 1 {
-			wordIdx = 0
-			segmentsLeft--
-		}
-
-		var skipPenalty int
-		if i == 1 || (i-1) == lastSegStart {
-			// Skipping the start of first or last segment.
-			skipPenalty++
-		}
-
-		for j := 0; j <= pattLen; j++ {
-			// By default, we don't have a match. Fill in the skip data.
-			m.scores[i][j][1] = minScore << 1
-
-			// Compute the skip score.
-			k := 0
-			if m.scores[i-1][j][0].val() < m.scores[i-1][j][1].val() {
-				k = 1
-			}
-
-			skipScore := m.scores[i-1][j][k].val()
-			// Do not penalize missing characters after the last matched segment.
-			if j != pattLen {
-				skipScore -= skipPenalty
-			}
-			m.scores[i][j][0] = score(skipScore, k)
-
-			if j == 0 || candidateLower[i-1] != m.patternLower[j-1] {
-				// Not a match.
-				continue
-			}
-			pRole := m.patternRoles[j-1]
-
-			if role == RTail && pRole == RHead {
-				if j > 1 {
-					// Not a match: a head in the pattern matches a tail character in the candidate.
-					continue
-				}
-				// Special treatment for the first character of the pattern. We allow
-				// matches in the middle of a word if they are long enough, at least
-				// min(3, pattern.length) characters.
-				if !bytes.HasPrefix(candidateLower[i-1:], m.patternShort) {
-					continue
-				}
-			}
-
-			// Compute the char score.
-			var charScore int
-			// Bonus 1: the char is in the candidate's last segment.
-			if segmentsLeft <= 1 {
-				charScore++
-			}
-			// Bonus 2: Case match or a Head in the pattern aligns with one in the word.
-			// Single-case patterns lack segmentation signals and we assume any character
-			// can be a head of a segment.
-			if candidate[i-1] == m.pattern[j-1] || role == RHead && (!m.caseSensitive || pRole == RHead) {
-				charScore++
-			}
-
-			// Penalty 1: pattern char is Head, candidate char is Tail.
-			if role == RTail && pRole == RHead {
-				charScore--
-			}
-			// Penalty 2: first pattern character matched in the middle of a word.
-			if j == 1 && role == RTail {
-				charScore -= 4
-			}
-
-			// Third dimension encodes whether there is a gap between the previous match and the current
-			// one.
-			for k := 0; k < 2; k++ {
-				sc := m.scores[i-1][j-1][k].val() + charScore
-
-				isConsecutive := k == 1 || i-1 == 0 || i-1 == lastSegStart
-				if isConsecutive {
-					// Bonus 3: a consecutive match. First character match also gets a bonus to
-					// ensure prefix final match score normalizes to 1.0.
-					// Logically, this is a part of charScore, but we have to compute it here because it
-					// only applies for consecutive matches (k == 1).
-					sc += consecutiveBonus
-				}
-				if k == 0 {
-					// Penalty 3: Matching inside a segment (and previous char wasn't matched). Penalize for the lack
-					// of alignment.
-					if role == RTail || role == RUCTail {
-						sc -= 3
-					}
-				}
-
-				if sc > m.scores[i][j][1].val() {
-					m.scores[i][j][1] = score(sc, k)
-				}
-			}
-		}
-	}
-
-	result := m.scores[len(candidate)][len(m.pattern)][m.bestK(len(candidate), len(m.pattern))].val()
-
-	return result
-}
-
-// ScoreTable returns the score table computed for the provided candidate. Used only for debugging.
-func (m *Matcher) ScoreTable(candidate string) string {
-	var buf bytes.Buffer
-
-	var line1, line2, separator bytes.Buffer
-	line1.WriteString("\t")
-	line2.WriteString("\t")
-	for j := 0; j < len(m.pattern); j++ {
-		line1.WriteString(fmt.Sprintf("%c\t\t", m.pattern[j]))
-		separator.WriteString("----------------")
-	}
-
-	buf.WriteString(line1.String())
-	buf.WriteString("\n")
-	buf.WriteString(separator.String())
-	buf.WriteString("\n")
-
-	for i := 1; i <= len(candidate); i++ {
-		line1.Reset()
-		line2.Reset()
-
-		line1.WriteString(fmt.Sprintf("%c\t", candidate[i-1]))
-		line2.WriteString("\t")
-
-		for j := 1; j <= len(m.pattern); j++ {
-			line1.WriteString(fmt.Sprintf("M%6d(%c)\t", m.scores[i][j][0].val(), dir(m.scores[i][j][0].prevK())))
-			line2.WriteString(fmt.Sprintf("H%6d(%c)\t", m.scores[i][j][1].val(), dir(m.scores[i][j][1].prevK())))
-		}
-		buf.WriteString(line1.String())
-		buf.WriteString("\n")
-		buf.WriteString(line2.String())
-		buf.WriteString("\n")
-		buf.WriteString(separator.String())
-		buf.WriteString("\n")
-	}
-
-	return buf.String()
-}
-
-func dir(prevK int) rune {
-	if prevK == 0 {
-		return 'M'
-	}
-	return 'H'
-}
-
-func (m *Matcher) poorMatch() bool {
-	if len(m.pattern) < 2 {
-		return false
-	}
-
-	i, j := m.lastCandidateLen, len(m.pattern)
-	k := m.bestK(i, j)
-
-	var counter, len int
-	for i > 0 {
-		take := (k == 1)
-		k = m.scores[i][j][k].prevK()
-		if take {
-			len++
-			if k == 0 && len < 3 && m.roles[i-1] == RTail {
-				// Short match in the middle of a word
-				counter++
-				if counter > 1 {
-					return true
-				}
-			}
-			j--
-		} else {
-			len = 0
-		}
-		i--
-	}
-	return false
-}
diff --git a/src/cmd/vendor/golang.org/x/tools/internal/lsp/fuzzy/symbol.go b/src/cmd/vendor/golang.org/x/tools/internal/lsp/fuzzy/symbol.go
deleted file mode 100644
index 073a4cd..0000000
--- a/src/cmd/vendor/golang.org/x/tools/internal/lsp/fuzzy/symbol.go
+++ /dev/null
@@ -1,237 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package fuzzy
-
-import (
-	"unicode"
-)
-
-// SymbolMatcher implements a fuzzy matching algorithm optimized for Go symbols
-// of the form:
-//
-//	example.com/path/to/package.object.field
-//
-// Knowing that we are matching symbols like this allows us to make the
-// following optimizations:
-//   - We can incorporate right-to-left relevance directly into the score
-//     calculation.
-//   - We can match from right to left, discarding leading bytes if the input is
-//     too long.
-//   - We just take the right-most match without losing too much precision. This
-//     allows us to use an O(n) algorithm.
-//   - We can operate directly on chunked strings; in many cases we will
-//     be storing the package path and/or package name separately from the
-//     symbol or identifiers, so doing this avoids allocating strings.
-//   - We can return the index of the right-most match, allowing us to trim
-//     irrelevant qualification.
-//
-// This implementation is experimental, serving as a reference fast algorithm
-// to compare to the fuzzy algorithm implemented by Matcher.
-type SymbolMatcher struct {
-	// Using buffers of length 256 is both a reasonable size for most qualified
-	// symbols, and makes it easy to avoid bounds checks by using uint8 indexes.
-	pattern     [256]rune
-	patternLen  uint8
-	inputBuffer [256]rune   // avoid allocating when considering chunks
-	roles       [256]uint32 // which roles does a rune play (word start, etc.)
-	segments    [256]uint8  // how many segments from the right is each rune
-}
-
-const (
-	segmentStart uint32 = 1 << iota
-	wordStart
-	separator
-)
-
-// NewSymbolMatcher creates a SymbolMatcher that may be used to match the given
-// search pattern.
-//
-// Currently this matcher only accepts case-insensitive fuzzy patterns.
-//
-// An empty pattern matches no input.
-func NewSymbolMatcher(pattern string) *SymbolMatcher {
-	m := &SymbolMatcher{}
-	for _, p := range pattern {
-		m.pattern[m.patternLen] = unicode.ToLower(p)
-		m.patternLen++
-		if m.patternLen == 255 || int(m.patternLen) == len(pattern) {
-			// break at 255 so that we can represent patternLen with a uint8.
-			break
-		}
-	}
-	return m
-}
-
-// Match looks for the right-most match of the search pattern within the symbol
-// represented by concatenating the given chunks, returning its offset and
-// score.
-//
-// If a match is found, the first return value will hold the absolute byte
-// offset within all chunks for the start of the symbol. In other words, the
-// index of the match within strings.Join(chunks, ""). If no match is found,
-// the first return value will be -1.
-//
-// The second return value will be the score of the match, which is always
-// between 0 and 1, inclusive. A score of 0 indicates no match.
-func (m *SymbolMatcher) Match(chunks []string) (int, float64) {
-	// Explicit behavior for an empty pattern.
-	//
-	// As a minor optimization, this also avoids nilness checks later on, since
-	// the compiler can prove that m != nil.
-	if m.patternLen == 0 {
-		return -1, 0
-	}
-
-	// First phase: populate the input buffer with lower-cased runes.
-	//
-	// We could also check for a forward match here, but since we'd have to write
-	// the entire input anyway this has negligible impact on performance.
-
-	var (
-		inputLen  = uint8(0)
-		modifiers = wordStart | segmentStart
-	)
-
-input:
-	for _, chunk := range chunks {
-		for _, r := range chunk {
-			if r == '.' || r == '/' {
-				modifiers |= separator
-			}
-			// optimization: avoid calls to unicode.ToLower, which can't be inlined.
-			l := r
-			if r <= unicode.MaxASCII {
-				if 'A' <= r && r <= 'Z' {
-					l = r + 'a' - 'A'
-				}
-			} else {
-				l = unicode.ToLower(r)
-			}
-			if l != r {
-				modifiers |= wordStart
-			}
-			m.inputBuffer[inputLen] = l
-			m.roles[inputLen] = modifiers
-			inputLen++
-			if m.roles[inputLen-1]&separator != 0 {
-				modifiers = wordStart | segmentStart
-			} else {
-				modifiers = 0
-			}
-			// TODO: we should prefer the right-most input if it overflows, rather
-			//       than the left-most as we're doing here.
-			if inputLen == 255 {
-				break input
-			}
-		}
-	}
-
-	// Second phase: find the right-most match, and count segments from the
-	// right.
-
-	var (
-		pi    = uint8(m.patternLen - 1) // pattern index
-		p     = m.pattern[pi]           // pattern rune
-		start = -1                      // start offset of match
-		rseg  = uint8(0)
-	)
-	const maxSeg = 3 // maximum number of segments from the right to count, for scoring purposes.
-
-	for ii := inputLen - 1; ; ii-- {
-		r := m.inputBuffer[ii]
-		if rseg < maxSeg && m.roles[ii]&separator != 0 {
-			rseg++
-		}
-		m.segments[ii] = rseg
-		if p == r {
-			if pi == 0 {
-				start = int(ii)
-				break
-			}
-			pi--
-			p = m.pattern[pi]
-		}
-		// Don't check ii >= 0 in the loop condition: ii is a uint8.
-		if ii == 0 {
-			break
-		}
-	}
-
-	if start < 0 {
-		// no match: skip scoring
-		return -1, 0
-	}
-
-	// Third phase: find the shortest match, and compute the score.
-
-	// Score is the average score for each character.
-	//
-	// A character score is the multiple of:
-	//   1. 1.0 if the character starts a segment, .8 if the character start a
-	//      mid-segment word, otherwise 0.6. This carries over to immediately
-	//      following characters.
-	//   2. For the final character match, the multiplier from (1) is reduced to
-	//     .8 if the next character in the input is a mid-segment word, or 0.6 if
-	//      the next character in the input is not a word or segment start. This
-	//      ensures that we favor whole-word or whole-segment matches over prefix
-	//      matches.
-	//   3. 1.0 if the character is part of the last segment, otherwise
-	//      1.0-.2*<segments from the right>, with a max segment count of 3.
-	//
-	// This is a very naive algorithm, but it is fast. There's lots of prior art
-	// here, and we should leverage it. For example, we could explicitly consider
-	// character distance, and exact matches of words or segments.
-	//
-	// Also note that this might not actually find the highest scoring match, as
-	// doing so could require a non-linear algorithm, depending on how the score
-	// is calculated.
-
-	pi = 0
-	p = m.pattern[pi]
-
-	const (
-		segStreak  = 1.0
-		wordStreak = 0.8
-		noStreak   = 0.6
-		perSegment = 0.2 // we count at most 3 segments above
-	)
-
-	streakBonus := noStreak
-	totScore := 0.0
-	for ii := uint8(start); ii < inputLen; ii++ {
-		r := m.inputBuffer[ii]
-		if r == p {
-			pi++
-			p = m.pattern[pi]
-			// Note: this could be optimized with some bit operations.
-			switch {
-			case m.roles[ii]&segmentStart != 0 && segStreak > streakBonus:
-				streakBonus = segStreak
-			case m.roles[ii]&wordStart != 0 && wordStreak > streakBonus:
-				streakBonus = wordStreak
-			}
-			finalChar := pi >= m.patternLen
-			// finalCost := 1.0
-			if finalChar && streakBonus > noStreak {
-				switch {
-				case ii == inputLen-1 || m.roles[ii+1]&segmentStart != 0:
-					// Full segment: no reduction
-				case m.roles[ii+1]&wordStart != 0:
-					streakBonus = wordStreak
-				default:
-					streakBonus = noStreak
-				}
-			}
-			totScore += streakBonus * (1.0 - float64(m.segments[ii])*perSegment)
-			if finalChar {
-				break
-			}
-		} else {
-			streakBonus = noStreak
-		}
-	}
-
-	return start, totScore / float64(m.patternLen)
-}
diff --git a/src/cmd/vendor/golang.org/x/tools/internal/typeparams/coretype.go b/src/cmd/vendor/golang.org/x/tools/internal/typeparams/coretype.go
new file mode 100644
index 0000000..993135e
--- /dev/null
+++ b/src/cmd/vendor/golang.org/x/tools/internal/typeparams/coretype.go
@@ -0,0 +1,122 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typeparams
+
+import (
+	"go/types"
+)
+
+// CoreType returns the core type of T or nil if T does not have a core type.
+//
+// See https://go.dev/ref/spec#Core_types for the definition of a core type.
+func CoreType(T types.Type) types.Type {
+	U := T.Underlying()
+	if _, ok := U.(*types.Interface); !ok {
+		return U // for non-interface types,
+	}
+
+	terms, err := _NormalTerms(U)
+	if len(terms) == 0 || err != nil {
+		// len(terms) -> empty type set of interface.
+		// err != nil => U is invalid, exceeds complexity bounds, or has an empty type set.
+		return nil // no core type.
+	}
+
+	U = terms[0].Type().Underlying()
+	var identical int // i in [0,identical) => Identical(U, terms[i].Type().Underlying())
+	for identical = 1; identical < len(terms); identical++ {
+		if !types.Identical(U, terms[identical].Type().Underlying()) {
+			break
+		}
+	}
+
+	if identical == len(terms) {
+		// https://go.dev/ref/spec#Core_types
+		// "There is a single type U which is the underlying type of all types in the type set of T"
+		return U
+	}
+	ch, ok := U.(*types.Chan)
+	if !ok {
+		return nil // no core type as identical < len(terms) and U is not a channel.
+	}
+	// https://go.dev/ref/spec#Core_types
+	// "the type chan E if T contains only bidirectional channels, or the type chan<- E or
+	// <-chan E depending on the direction of the directional channels present."
+	for chans := identical; chans < len(terms); chans++ {
+		curr, ok := terms[chans].Type().Underlying().(*types.Chan)
+		if !ok {
+			return nil
+		}
+		if !types.Identical(ch.Elem(), curr.Elem()) {
+			return nil // channel elements are not identical.
+		}
+		if ch.Dir() == types.SendRecv {
+			// ch is bidirectional. We can safely always use curr's direction.
+			ch = curr
+		} else if curr.Dir() != types.SendRecv && ch.Dir() != curr.Dir() {
+			// ch and curr are not bidirectional and not the same direction.
+			return nil
+		}
+	}
+	return ch
+}
+
+// _NormalTerms returns a slice of terms representing the normalized structural
+// type restrictions of a type, if any.
+//
+// For all types other than *types.TypeParam, *types.Interface, and
+// *types.Union, this is just a single term with Tilde() == false and
+// Type() == typ. For *types.TypeParam, *types.Interface, and *types.Union, see
+// below.
+//
+// Structural type restrictions of a type parameter are created via
+// non-interface types embedded in its constraint interface (directly, or via a
+// chain of interface embeddings). For example, in the declaration type
+// T[P interface{~int; m()}] int the structural restriction of the type
+// parameter P is ~int.
+//
+// With interface embedding and unions, the specification of structural type
+// restrictions may be arbitrarily complex. For example, consider the
+// following:
+//
+//  type A interface{ ~string|~[]byte }
+//
+//  type B interface{ int|string }
+//
+//  type C interface { ~string|~int }
+//
+//  type T[P interface{ A|B; C }] int
+//
+// In this example, the structural type restriction of P is ~string|int: A|B
+// expands to ~string|~[]byte|int|string, which reduces to ~string|~[]byte|int,
+// which when intersected with C (~string|~int) yields ~string|int.
+//
+// _NormalTerms computes these expansions and reductions, producing a
+// "normalized" form of the embeddings. A structural restriction is normalized
+// if it is a single union containing no interface terms, and is minimal in the
+// sense that removing any term changes the set of types satisfying the
+// constraint. It is left as a proof for the reader that, modulo sorting, there
+// is exactly one such normalized form.
+//
+// Because the minimal representation always takes this form, _NormalTerms
+// returns a slice of tilde terms corresponding to the terms of the union in
+// the normalized structural restriction. An error is returned if the type is
+// invalid, exceeds complexity bounds, or has an empty type set. In the latter
+// case, _NormalTerms returns ErrEmptyTypeSet.
+//
+// _NormalTerms makes no guarantees about the order of terms, except that it
+// is deterministic.
+func _NormalTerms(typ types.Type) ([]*Term, error) {
+	switch typ := typ.(type) {
+	case *TypeParam:
+		return StructuralTerms(typ)
+	case *Union:
+		return UnionTermSet(typ)
+	case *types.Interface:
+		return InterfaceTermSet(typ)
+	default:
+		return []*Term{NewTerm(false, typ)}, nil
+	}
+}
diff --git a/src/cmd/vendor/modules.txt b/src/cmd/vendor/modules.txt
index 4e4b5b6..6961b9b 100644
--- a/src/cmd/vendor/modules.txt
+++ b/src/cmd/vendor/modules.txt
@@ -1,5 +1,5 @@
-# github.com/google/pprof v0.0.0-20220517023622-154dc81eb7b0
-## explicit; go 1.17
+# github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26
+## explicit; go 1.18
 github.com/google/pprof/driver
 github.com/google/pprof/internal/binutils
 github.com/google/pprof/internal/driver
@@ -17,16 +17,13 @@
 # github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2
 ## explicit; go 1.12
 github.com/ianlancetaylor/demangle
-# golang.org/x/arch v0.0.0-20220412001346-fc48f9fe4c15
+# golang.org/x/arch v0.1.1-0.20221116201807-1bb480fc256a
 ## explicit; go 1.17
 golang.org/x/arch/arm/armasm
 golang.org/x/arch/arm64/arm64asm
 golang.org/x/arch/ppc64/ppc64asm
 golang.org/x/arch/x86/x86asm
-# golang.org/x/crypto v0.0.0-20220516162934-403b01795ae8
-## explicit; go 1.17
-golang.org/x/crypto/ed25519
-# golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4
+# golang.org/x/mod v0.7.0
 ## explicit; go 1.17
 golang.org/x/mod/internal/lazyregexp
 golang.org/x/mod/modfile
@@ -37,24 +34,23 @@
 golang.org/x/mod/sumdb/note
 golang.org/x/mod/sumdb/tlog
 golang.org/x/mod/zip
-# golang.org/x/sync v0.0.0-20220513210516-0976fa681c29
+# golang.org/x/sync v0.1.0
 ## explicit
 golang.org/x/sync/semaphore
-# golang.org/x/sys v0.0.0-20220614162138-6c1b26c55098
+# golang.org/x/sys v0.3.0
 ## explicit; go 1.17
 golang.org/x/sys/internal/unsafeheader
 golang.org/x/sys/plan9
 golang.org/x/sys/unix
 golang.org/x/sys/windows
-# golang.org/x/term v0.0.0-20220411215600-e5f449aeb171
+# golang.org/x/term v0.2.0
 ## explicit; go 1.17
 golang.org/x/term
-# golang.org/x/tools v0.1.11-0.20220516163903-1e55371df567
-## explicit; go 1.17
+# golang.org/x/tools v0.3.1-0.20230118190848-070db2996ebe
+## explicit; go 1.18
 golang.org/x/tools/cover
 golang.org/x/tools/go/analysis
 golang.org/x/tools/go/analysis/internal/analysisflags
-golang.org/x/tools/go/analysis/internal/facts
 golang.org/x/tools/go/analysis/passes/asmdecl
 golang.org/x/tools/go/analysis/passes/assign
 golang.org/x/tools/go/analysis/passes/atomic
@@ -81,6 +77,7 @@
 golang.org/x/tools/go/analysis/passes/structtag
 golang.org/x/tools/go/analysis/passes/testinggoroutine
 golang.org/x/tools/go/analysis/passes/tests
+golang.org/x/tools/go/analysis/passes/timeformat
 golang.org/x/tools/go/analysis/passes/unmarshal
 golang.org/x/tools/go/analysis/passes/unreachable
 golang.org/x/tools/go/analysis/passes/unsafeptr
@@ -92,5 +89,5 @@
 golang.org/x/tools/go/types/objectpath
 golang.org/x/tools/go/types/typeutil
 golang.org/x/tools/internal/analysisinternal
-golang.org/x/tools/internal/lsp/fuzzy
+golang.org/x/tools/internal/facts
 golang.org/x/tools/internal/typeparams
diff --git a/src/cmd/vet/main.go b/src/cmd/vet/main.go
index 7da8606..334179c 100644
--- a/src/cmd/vet/main.go
+++ b/src/cmd/vet/main.go
@@ -32,6 +32,7 @@
 	"golang.org/x/tools/go/analysis/passes/structtag"
 	"golang.org/x/tools/go/analysis/passes/testinggoroutine"
 	"golang.org/x/tools/go/analysis/passes/tests"
+	"golang.org/x/tools/go/analysis/passes/timeformat"
 	"golang.org/x/tools/go/analysis/passes/unmarshal"
 	"golang.org/x/tools/go/analysis/passes/unreachable"
 	"golang.org/x/tools/go/analysis/passes/unsafeptr"
@@ -65,6 +66,7 @@
 		structtag.Analyzer,
 		tests.Analyzer,
 		testinggoroutine.Analyzer,
+		timeformat.Analyzer,
 		unmarshal.Analyzer,
 		unreachable.Analyzer,
 		unsafeptr.Analyzer,
diff --git a/src/cmd/vet/vet_test.go b/src/cmd/vet/vet_test.go
index 714ee32..280ed8d 100644
--- a/src/cmd/vet/vet_test.go
+++ b/src/cmd/vet/vet_test.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package main_test
+package main
 
 import (
 	"bytes"
@@ -21,62 +21,46 @@
 	"testing"
 )
 
-const dataDir = "testdata"
-
-var binary string
-
-// We implement TestMain so remove the test binary when all is done.
+// TestMain executes the test binary as the vet command if
+// GO_VETTEST_IS_VET is set, and runs the tests otherwise.
 func TestMain(m *testing.M) {
-	os.Exit(testMain(m))
+	if os.Getenv("GO_VETTEST_IS_VET") != "" {
+		main()
+		os.Exit(0)
+	}
+
+	os.Setenv("GO_VETTEST_IS_VET", "1") // Set for subprocesses to inherit.
+	os.Exit(m.Run())
 }
 
-func testMain(m *testing.M) int {
-	dir, err := os.MkdirTemp("", "vet_test")
-	if err != nil {
-		fmt.Fprintln(os.Stderr, err)
-		return 1
-	}
-	defer os.RemoveAll(dir)
-	binary = filepath.Join(dir, "testvet.exe")
+// vetPath returns the path to the "vet" binary to run.
+func vetPath(t testing.TB) string {
+	t.Helper()
+	testenv.MustHaveExec(t)
 
-	return m.Run()
+	vetPathOnce.Do(func() {
+		vetExePath, vetPathErr = os.Executable()
+	})
+	if vetPathErr != nil {
+		t.Fatal(vetPathErr)
+	}
+	return vetExePath
 }
 
 var (
-	buildMu sync.Mutex // guards following
-	built   = false    // We have built the binary.
-	failed  = false    // We have failed to build the binary, don't try again.
+	vetPathOnce sync.Once
+	vetExePath  string
+	vetPathErr  error
 )
 
-func Build(t *testing.T) {
-	buildMu.Lock()
-	defer buildMu.Unlock()
-	if built {
-		return
-	}
-	if failed {
-		t.Skip("cannot run on this environment")
-	}
-	testenv.MustHaveGoBuild(t)
-	cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", binary)
-	output, err := cmd.CombinedOutput()
-	if err != nil {
-		failed = true
-		fmt.Fprintf(os.Stderr, "%s\n", output)
-		t.Fatal(err)
-	}
-	built = true
-}
-
 func vetCmd(t *testing.T, arg, pkg string) *exec.Cmd {
-	cmd := exec.Command(testenv.GoToolPath(t), "vet", "-vettool="+binary, arg, path.Join("cmd/vet/testdata", pkg))
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "vet", "-vettool="+vetPath(t), arg, path.Join("cmd/vet/testdata", pkg))
 	cmd.Env = os.Environ()
 	return cmd
 }
 
 func TestVet(t *testing.T) {
 	t.Parallel()
-	Build(t)
 	for _, pkg := range []string{
 		"asm",
 		"assign",
@@ -141,7 +125,7 @@
 	// That's fine for the builders, but causes commands like
 	// 'GOARCH=386 go test .' to fail.
 	// Instead, we ask the go command.
-	cmd := exec.Command(testenv.GoToolPath(t), "list", "-f", "{{context.CgoEnabled}}")
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "list", "-f", "{{context.CgoEnabled}}")
 	out, _ := cmd.CombinedOutput()
 	return string(out) == "true\n"
 }
@@ -165,7 +149,6 @@
 // TestTags verifies that the -tags argument controls which files to check.
 func TestTags(t *testing.T) {
 	t.Parallel()
-	Build(t)
 	for tag, wantFile := range map[string]int{
 		"testtag":     1, // file1
 		"x testtag y": 1,
@@ -269,7 +252,7 @@
 	if len(errs) == 1 {
 		return errs[0]
 	}
-	var buf bytes.Buffer
+	var buf strings.Builder
 	fmt.Fprintf(&buf, "\n")
 	for _, err := range errs {
 		fmt.Fprintf(&buf, "%s\n", err.Error())
@@ -337,7 +320,7 @@
 	errRx       = regexp.MustCompile(`// (?:GC_)?ERROR(NEXT)? (.*)`)
 	errAutoRx   = regexp.MustCompile(`// (?:GC_)?ERRORAUTO(NEXT)? (.*)`)
 	errQuotesRx = regexp.MustCompile(`"([^"]*)"`)
-	lineRx      = regexp.MustCompile(`LINE(([+-])([0-9]+))?`)
+	lineRx      = regexp.MustCompile(`LINE(([+-])(\d+))?`)
 )
 
 // wantedErrors parses expected errors from comments in a file.
diff --git a/src/compress/flate/deflate.go b/src/compress/flate/deflate.go
index 93efd7c..b53764b 100644
--- a/src/compress/flate/deflate.go
+++ b/src/compress/flate/deflate.go
@@ -297,7 +297,7 @@
 }
 
 // bulkHash4 will compute hashes using the same
-// algorithm as hash4
+// algorithm as hash4.
 func bulkHash4(b []byte, dst []uint32) {
 	if len(b) < minMatchLength {
 		return
diff --git a/src/compress/flate/huffman_bit_writer.go b/src/compress/flate/huffman_bit_writer.go
index 6a4e48e..0056375 100644
--- a/src/compress/flate/huffman_bit_writer.go
+++ b/src/compress/flate/huffman_bit_writer.go
@@ -387,15 +387,12 @@
 		case 16:
 			w.writeBits(int32(w.codegen[i]), 2)
 			i++
-			break
 		case 17:
 			w.writeBits(int32(w.codegen[i]), 3)
 			i++
-			break
 		case 18:
 			w.writeBits(int32(w.codegen[i]), 7)
 			i++
-			break
 		}
 	}
 }
diff --git a/src/compress/flate/huffman_code.go b/src/compress/flate/huffman_code.go
index a3fe80b..ade4c8f 100644
--- a/src/compress/flate/huffman_code.go
+++ b/src/compress/flate/huffman_code.go
@@ -60,7 +60,7 @@
 	return &huffmanEncoder{codes: make([]hcode, size)}
 }
 
-// Generates a HuffmanCode corresponding to the fixed literal table
+// Generates a HuffmanCode corresponding to the fixed literal table.
 func generateFixedLiteralEncoding() *huffmanEncoder {
 	h := newHuffmanEncoder(maxNumLit)
 	codes := h.codes
@@ -73,17 +73,14 @@
 			// size 8, 000110000  .. 10111111
 			bits = ch + 48
 			size = 8
-			break
 		case ch < 256:
 			// size 9, 110010000 .. 111111111
 			bits = ch + 400 - 144
 			size = 9
-			break
 		case ch < 280:
 			// size 7, 0000000 .. 0010111
 			bits = ch - 256
 			size = 7
-			break
 		default:
 			// size 8, 11000000 .. 11000111
 			bits = ch + 192 - 280
diff --git a/src/compress/flate/inflate.go b/src/compress/flate/inflate.go
index 4992139..7efd447 100644
--- a/src/compress/flate/inflate.go
+++ b/src/compress/flate/inflate.go
@@ -789,8 +789,8 @@
 // to read the uncompressed version of r.
 // If r does not also implement io.ByteReader,
 // the decompressor may read more data than necessary from r.
-// It is the caller's responsibility to call Close on the ReadCloser
-// when finished reading.
+// The reader returns io.EOF after the final block in the DEFLATE stream has
+// been encountered. Any trailing data after the final block is ignored.
 //
 // The ReadCloser returned by NewReader also implements Resetter.
 func NewReader(r io.Reader) io.ReadCloser {
diff --git a/src/compress/flate/token.go b/src/compress/flate/token.go
index ae01391..fc0e494 100644
--- a/src/compress/flate/token.go
+++ b/src/compress/flate/token.go
@@ -75,17 +75,17 @@
 	return token(matchType + xlength<<lengthShift + xoffset)
 }
 
-// Returns the literal of a literal token
+// Returns the literal of a literal token.
 func (t token) literal() uint32 { return uint32(t - literalType) }
 
-// Returns the extra offset of a match token
+// Returns the extra offset of a match token.
 func (t token) offset() uint32 { return uint32(t) & offsetMask }
 
 func (t token) length() uint32 { return uint32((t - matchType) >> lengthShift) }
 
 func lengthCode(len uint32) uint32 { return lengthCodes[len] }
 
-// Returns the offset code corresponding to a specific offset
+// Returns the offset code corresponding to a specific offset.
 func offsetCode(off uint32) uint32 {
 	if off < uint32(len(offsetCodes)) {
 		return offsetCodes[off]
diff --git a/src/context/context.go b/src/context/context.go
index 1070111..f3fe1a4 100644
--- a/src/context/context.go
+++ b/src/context/context.go
@@ -22,6 +22,12 @@
 // fires. The go vet tool checks that CancelFuncs are used on all
 // control-flow paths.
 //
+// The WithCancelCause function returns a CancelCauseFunc, which
+// takes an error and records it as the cancellation cause. Calling
+// Cause on the canceled context or any of its children retrieves
+// the cause. If no cause is specified, Cause(ctx) returns the same
+// value as ctx.Err().
+//
 // Programs that use Contexts should follow these rules to keep interfaces
 // consistent across packages and enable static analysis tools to check context
 // propagation:
@@ -230,21 +236,69 @@
 // Canceling this context releases resources associated with it, so code should
 // call cancel as soon as the operations running in this Context complete.
 func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
+	c := withCancel(parent)
+	return c, func() { c.cancel(true, Canceled, nil) }
+}
+
+// A CancelCauseFunc behaves like a CancelFunc but additionally sets the cancellation cause.
+// This cause can be retrieved by calling Cause on the canceled Context or on
+// any of its derived Contexts.
+//
+// If the context has already been canceled, CancelCauseFunc does not set the cause.
+// For example, if childContext is derived from parentContext:
+//   - if parentContext is canceled with cause1 before childContext is canceled with cause2,
+//     then Cause(parentContext) == Cause(childContext) == cause1
+//   - if childContext is canceled with cause2 before parentContext is canceled with cause1,
+//     then Cause(parentContext) == cause1 and Cause(childContext) == cause2
+type CancelCauseFunc func(cause error)
+
+// WithCancelCause behaves like WithCancel but returns a CancelCauseFunc instead of a CancelFunc.
+// Calling cancel with a non-nil error (the "cause") records that error in ctx;
+// it can then be retrieved using Cause(ctx).
+// Calling cancel with nil sets the cause to Canceled.
+//
+// Example use:
+//
+//	ctx, cancel := context.WithCancelCause(parent)
+//	cancel(myError)
+//	ctx.Err() // returns context.Canceled
+//	context.Cause(ctx) // returns myError
+func WithCancelCause(parent Context) (ctx Context, cancel CancelCauseFunc) {
+	c := withCancel(parent)
+	return c, func(cause error) { c.cancel(true, Canceled, cause) }
+}
+
+func withCancel(parent Context) *cancelCtx {
 	if parent == nil {
 		panic("cannot create context from nil parent")
 	}
 	c := newCancelCtx(parent)
-	propagateCancel(parent, &c)
-	return &c, func() { c.cancel(true, Canceled) }
+	propagateCancel(parent, c)
+	return c
+}
+
+// Cause returns a non-nil error explaining why c was canceled.
+// The first cancellation of c or one of its parents sets the cause.
+// If that cancellation happened via a call to CancelCauseFunc(err),
+// then Cause returns err.
+// Otherwise Cause(c) returns the same value as c.Err().
+// Cause returns nil if c has not been canceled yet.
+func Cause(c Context) error {
+	if cc, ok := c.Value(&cancelCtxKey).(*cancelCtx); ok {
+		cc.mu.Lock()
+		defer cc.mu.Unlock()
+		return cc.cause
+	}
+	return nil
 }
 
 // newCancelCtx returns an initialized cancelCtx.
-func newCancelCtx(parent Context) cancelCtx {
-	return cancelCtx{Context: parent}
+func newCancelCtx(parent Context) *cancelCtx {
+	return &cancelCtx{Context: parent}
 }
 
 // goroutines counts the number of goroutines ever created; for testing.
-var goroutines int32
+var goroutines atomic.Int32
 
 // propagateCancel arranges for child to be canceled when parent is.
 func propagateCancel(parent Context, child canceler) {
@@ -256,7 +310,7 @@
 	select {
 	case <-done:
 		// parent is already canceled
-		child.cancel(false, parent.Err())
+		child.cancel(false, parent.Err(), Cause(parent))
 		return
 	default:
 	}
@@ -265,7 +319,7 @@
 		p.mu.Lock()
 		if p.err != nil {
 			// parent has already been canceled
-			child.cancel(false, p.err)
+			child.cancel(false, p.err, p.cause)
 		} else {
 			if p.children == nil {
 				p.children = make(map[canceler]struct{})
@@ -274,11 +328,11 @@
 		}
 		p.mu.Unlock()
 	} else {
-		atomic.AddInt32(&goroutines, +1)
+		goroutines.Add(1)
 		go func() {
 			select {
 			case <-parent.Done():
-				child.cancel(false, parent.Err())
+				child.cancel(false, parent.Err(), Cause(parent))
 			case <-child.Done():
 			}
 		}()
@@ -326,7 +380,7 @@
 // A canceler is a context type that can be canceled directly. The
 // implementations are *cancelCtx and *timerCtx.
 type canceler interface {
-	cancel(removeFromParent bool, err error)
+	cancel(removeFromParent bool, err, cause error)
 	Done() <-chan struct{}
 }
 
@@ -346,6 +400,7 @@
 	done     atomic.Value          // of chan struct{}, created lazily, closed by first cancel call
 	children map[canceler]struct{} // set to nil by the first cancel call
 	err      error                 // set to non-nil by the first cancel call
+	cause    error                 // set to non-nil by the first cancel call
 }
 
 func (c *cancelCtx) Value(key any) any {
@@ -394,16 +449,21 @@
 
 // cancel closes c.done, cancels each of c's children, and, if
 // removeFromParent is true, removes c from its parent's children.
-func (c *cancelCtx) cancel(removeFromParent bool, err error) {
+// cancel sets c.cause to cause if this is the first time c is canceled.
+func (c *cancelCtx) cancel(removeFromParent bool, err, cause error) {
 	if err == nil {
 		panic("context: internal error: missing cancel error")
 	}
+	if cause == nil {
+		cause = err
+	}
 	c.mu.Lock()
 	if c.err != nil {
 		c.mu.Unlock()
 		return // already canceled
 	}
 	c.err = err
+	c.cause = cause
 	d, _ := c.done.Load().(chan struct{})
 	if d == nil {
 		c.done.Store(closedchan)
@@ -412,7 +472,7 @@
 	}
 	for child := range c.children {
 		// NOTE: acquiring the child's lock while holding parent's lock.
-		child.cancel(false, err)
+		child.cancel(false, err, cause)
 	}
 	c.children = nil
 	c.mu.Unlock()
@@ -446,24 +506,24 @@
 	propagateCancel(parent, c)
 	dur := time.Until(d)
 	if dur <= 0 {
-		c.cancel(true, DeadlineExceeded) // deadline has already passed
-		return c, func() { c.cancel(false, Canceled) }
+		c.cancel(true, DeadlineExceeded, nil) // deadline has already passed
+		return c, func() { c.cancel(false, Canceled, nil) }
 	}
 	c.mu.Lock()
 	defer c.mu.Unlock()
 	if c.err == nil {
 		c.timer = time.AfterFunc(dur, func() {
-			c.cancel(true, DeadlineExceeded)
+			c.cancel(true, DeadlineExceeded, nil)
 		})
 	}
-	return c, func() { c.cancel(true, Canceled) }
+	return c, func() { c.cancel(true, Canceled, nil) }
 }
 
 // A timerCtx carries a timer and a deadline. It embeds a cancelCtx to
 // implement Done and Err. It implements cancel by stopping its timer then
 // delegating to cancelCtx.cancel.
 type timerCtx struct {
-	cancelCtx
+	*cancelCtx
 	timer *time.Timer // Under cancelCtx.mu.
 
 	deadline time.Time
@@ -479,8 +539,8 @@
 		time.Until(c.deadline).String() + "])"
 }
 
-func (c *timerCtx) cancel(removeFromParent bool, err error) {
-	c.cancelCtx.cancel(false, err)
+func (c *timerCtx) cancel(removeFromParent bool, err, cause error) {
+	c.cancelCtx.cancel(false, err, cause)
 	if removeFromParent {
 		// Remove this timerCtx from its parent cancelCtx's children.
 		removeChild(c.cancelCtx.Context, c)
@@ -581,7 +641,7 @@
 			c = ctx.Context
 		case *timerCtx:
 			if key == &cancelCtxKey {
-				return &ctx.cancelCtx
+				return ctx.cancelCtx
 			}
 			c = ctx.Context
 		case *emptyCtx:
diff --git a/src/context/context_test.go b/src/context/context_test.go
index 8673c0f..eb5a86b 100644
--- a/src/context/context_test.go
+++ b/src/context/context_test.go
@@ -5,12 +5,12 @@
 package context
 
 import (
+	"errors"
 	"fmt"
 	"math/rand"
 	"runtime"
 	"strings"
 	"sync"
-	"sync/atomic"
 	"time"
 )
 
@@ -651,8 +651,9 @@
 }
 
 func XTestWithCancelCanceledParent(t testingT) {
-	parent, pcancel := WithCancel(Background())
-	pcancel()
+	parent, pcancel := WithCancelCause(Background())
+	cause := fmt.Errorf("Because!")
+	pcancel(cause)
 
 	c, _ := WithCancel(parent)
 	select {
@@ -663,6 +664,9 @@
 	if got, want := c.Err(), Canceled; got != want {
 		t.Errorf("child not canceled; got = %v, want = %v", got, want)
 	}
+	if got, want := Cause(c), cause; got != want {
+		t.Errorf("child has wrong cause; got = %v, want = %v", got, want)
+	}
 }
 
 func XTestWithValueChecksKey(t testingT) {
@@ -723,17 +727,17 @@
 }
 
 func XTestCustomContextGoroutines(t testingT) {
-	g := atomic.LoadInt32(&goroutines)
+	g := goroutines.Load()
 	checkNoGoroutine := func() {
 		t.Helper()
-		now := atomic.LoadInt32(&goroutines)
+		now := goroutines.Load()
 		if now != g {
 			t.Fatalf("%d goroutines created", now-g)
 		}
 	}
 	checkCreatedGoroutine := func() {
 		t.Helper()
-		now := atomic.LoadInt32(&goroutines)
+		now := goroutines.Load()
 		if now != g+1 {
 			t.Fatalf("%d goroutines created, want 1", now-g)
 		}
@@ -786,3 +790,167 @@
 	defer cancel7()
 	checkNoGoroutine()
 }
+
+func XTestCause(t testingT) {
+	var (
+		parentCause = fmt.Errorf("parentCause")
+		childCause  = fmt.Errorf("childCause")
+	)
+	for _, test := range []struct {
+		name  string
+		ctx   Context
+		err   error
+		cause error
+	}{
+		{
+			name:  "Background",
+			ctx:   Background(),
+			err:   nil,
+			cause: nil,
+		},
+		{
+			name:  "TODO",
+			ctx:   TODO(),
+			err:   nil,
+			cause: nil,
+		},
+		{
+			name: "WithCancel",
+			ctx: func() Context {
+				ctx, cancel := WithCancel(Background())
+				cancel()
+				return ctx
+			}(),
+			err:   Canceled,
+			cause: Canceled,
+		},
+		{
+			name: "WithCancelCause",
+			ctx: func() Context {
+				ctx, cancel := WithCancelCause(Background())
+				cancel(parentCause)
+				return ctx
+			}(),
+			err:   Canceled,
+			cause: parentCause,
+		},
+		{
+			name: "WithCancelCause nil",
+			ctx: func() Context {
+				ctx, cancel := WithCancelCause(Background())
+				cancel(nil)
+				return ctx
+			}(),
+			err:   Canceled,
+			cause: Canceled,
+		},
+		{
+			name: "WithCancelCause: parent cause before child",
+			ctx: func() Context {
+				ctx, cancelParent := WithCancelCause(Background())
+				ctx, cancelChild := WithCancelCause(ctx)
+				cancelParent(parentCause)
+				cancelChild(childCause)
+				return ctx
+			}(),
+			err:   Canceled,
+			cause: parentCause,
+		},
+		{
+			name: "WithCancelCause: parent cause after child",
+			ctx: func() Context {
+				ctx, cancelParent := WithCancelCause(Background())
+				ctx, cancelChild := WithCancelCause(ctx)
+				cancelChild(childCause)
+				cancelParent(parentCause)
+				return ctx
+			}(),
+			err:   Canceled,
+			cause: childCause,
+		},
+		{
+			name: "WithCancelCause: parent cause before nil",
+			ctx: func() Context {
+				ctx, cancelParent := WithCancelCause(Background())
+				ctx, cancelChild := WithCancel(ctx)
+				cancelParent(parentCause)
+				cancelChild()
+				return ctx
+			}(),
+			err:   Canceled,
+			cause: parentCause,
+		},
+		{
+			name: "WithCancelCause: parent cause after nil",
+			ctx: func() Context {
+				ctx, cancelParent := WithCancelCause(Background())
+				ctx, cancelChild := WithCancel(ctx)
+				cancelChild()
+				cancelParent(parentCause)
+				return ctx
+			}(),
+			err:   Canceled,
+			cause: Canceled,
+		},
+		{
+			name: "WithCancelCause: child cause after nil",
+			ctx: func() Context {
+				ctx, cancelParent := WithCancel(Background())
+				ctx, cancelChild := WithCancelCause(ctx)
+				cancelParent()
+				cancelChild(childCause)
+				return ctx
+			}(),
+			err:   Canceled,
+			cause: Canceled,
+		},
+		{
+			name: "WithCancelCause: child cause before nil",
+			ctx: func() Context {
+				ctx, cancelParent := WithCancel(Background())
+				ctx, cancelChild := WithCancelCause(ctx)
+				cancelChild(childCause)
+				cancelParent()
+				return ctx
+			}(),
+			err:   Canceled,
+			cause: childCause,
+		},
+		{
+			name: "WithTimeout",
+			ctx: func() Context {
+				ctx, cancel := WithTimeout(Background(), 0)
+				cancel()
+				return ctx
+			}(),
+			err:   DeadlineExceeded,
+			cause: DeadlineExceeded,
+		},
+	} {
+		if got, want := test.ctx.Err(), test.err; want != got {
+			t.Errorf("%s: ctx.Err() = %v want %v", test.name, got, want)
+		}
+		if got, want := Cause(test.ctx), test.cause; want != got {
+			t.Errorf("%s: Cause(ctx) = %v want %v", test.name, got, want)
+		}
+	}
+}
+
+func XTestCauseRace(t testingT) {
+	cause := errors.New("TestCauseRace")
+	ctx, cancel := WithCancelCause(Background())
+	go func() {
+		cancel(cause)
+	}()
+	for {
+		// Poll Cause, rather than waiting for Done, to test that
+		// access to the underlying cause is synchronized properly.
+		if err := Cause(ctx); err != nil {
+			if err != cause {
+				t.Errorf("Cause returned %v, want %v", err, cause)
+			}
+			break
+		}
+		runtime.Gosched()
+	}
+}
diff --git a/src/context/x_test.go b/src/context/x_test.go
index 00eca72..a2d814f 100644
--- a/src/context/x_test.go
+++ b/src/context/x_test.go
@@ -29,3 +29,5 @@
 func TestInvalidDerivedFail(t *testing.T)              { XTestInvalidDerivedFail(t) }
 func TestDeadlineExceededSupportsTimeout(t *testing.T) { XTestDeadlineExceededSupportsTimeout(t) }
 func TestCustomContextGoroutines(t *testing.T)         { XTestCustomContextGoroutines(t) }
+func TestCause(t *testing.T)                           { XTestCause(t) }
+func TestCauseRace(t *testing.T)                       { XTestCauseRace(t) }
diff --git a/src/crypto/aes/aes_gcm.go b/src/crypto/aes/aes_gcm.go
index ebae646..f77d279 100644
--- a/src/crypto/aes/aes_gcm.go
+++ b/src/crypto/aes/aes_gcm.go
@@ -8,7 +8,7 @@
 
 import (
 	"crypto/cipher"
-	subtleoverlap "crypto/internal/subtle"
+	"crypto/internal/alias"
 	"crypto/subtle"
 	"errors"
 )
@@ -114,7 +114,7 @@
 	gcmAesData(&g.productTable, data, &tagOut)
 
 	ret, out := sliceForAppend(dst, len(plaintext)+g.tagSize)
-	if subtleoverlap.InexactOverlap(out[:len(plaintext)], plaintext) {
+	if alias.InexactOverlap(out[:len(plaintext)], plaintext) {
 		panic("crypto/cipher: invalid buffer overlap")
 	}
 	if len(plaintext) > 0 {
@@ -167,7 +167,7 @@
 	gcmAesData(&g.productTable, data, &expectedTag)
 
 	ret, out := sliceForAppend(dst, len(ciphertext))
-	if subtleoverlap.InexactOverlap(out, ciphertext) {
+	if alias.InexactOverlap(out, ciphertext) {
 		panic("crypto/cipher: invalid buffer overlap")
 	}
 	if len(ciphertext) > 0 {
diff --git a/src/crypto/aes/asm_ppc64x.s b/src/crypto/aes/asm_ppc64x.s
index 5a7b6db..8ac97ec 100644
--- a/src/crypto/aes/asm_ppc64x.s
+++ b/src/crypto/aes/asm_ppc64x.s
@@ -48,7 +48,7 @@
 
 // For P9 instruction emulation
 #define ESPERM  V21  // Endian swapping permute into BE
-#define TMP2    V22  // Temporary for P8_STXVB16X/P8_STXV
+#define TMP2    V22  // Temporary for P8_STXVB16X/P8_STXVB16X
 
 // For {en,de}cryptBlockAsm
 #define BLK_INP    R3
@@ -69,8 +69,15 @@
 DATA ·rcon+0x48(SB)/8, $0x0000000000000000
 GLOBL ·rcon(SB), RODATA, $80
 
-// Emulate unaligned BE vector load/stores on LE targets
 #ifdef GOARCH_ppc64le
+#  ifdef GOPPC64_power9
+#define P8_LXVB16X(RA,RB,VT)  LXVB16X	(RA+RB), VT
+#define P8_STXVB16X(VS,RA,RB) STXVB16X	VS, (RA+RB)
+#define XXBRD_ON_LE(VA,VT)    XXBRD	VA, VT
+#  else
+// On POWER8/ppc64le, emulate the POWER9 instructions by loading unaligned
+// doublewords and byte-swapping each doubleword to emulate BE load/stores.
+#define NEEDS_ESPERM
 #define P8_LXVB16X(RA,RB,VT) \
 	LXVD2X	(RA+RB), VT \
 	VPERM	VT, VT, ESPERM, VT
@@ -79,19 +86,15 @@
 	VPERM	VS, VS, ESPERM, TMP2 \
 	STXVD2X	TMP2, (RA+RB)
 
-#define LXSDX_BE(RA,RB,VT) \
-	LXSDX	(RA+RB), VT \
-	VPERM	VT, VT, ESPERM, VT
+#define XXBRD_ON_LE(VA,VT) \
+	VPERM	VA, VA, ESPERM, VT
+
+#  endif // defined(GOPPC64_power9)
 #else
-#define P8_LXVB16X(RA,RB,VT) \
-	LXVD2X	(RA+RB), VT
-
-#define P8_STXVB16X(VS,RA,RB) \
-	STXVD2X	VS, (RA+RB)
-
-#define LXSDX_BE(RA,RB,VT) \
-	LXSDX	(RA+RB), VT
-#endif
+#define P8_LXVB16X(RA,RB,VT)  LXVD2X	(RA+RB), VT
+#define P8_STXVB16X(VS,RA,RB) STXVD2X	VS, (RA+RB)
+#define XXBRD_ON_LE(VA, VT)
+#endif // defined(GOARCH_ppc64le)
 
 // func setEncryptKeyAsm(nr int, key *byte, enc *uint32, dec *uint32)
 TEXT ·expandKeyAsm(SB), NOSPLIT|NOFRAME, $0
@@ -101,12 +104,12 @@
 	MOVD	enc+16(FP), OUTENC
 	MOVD	dec+24(FP), OUTDEC
 
-#ifdef GOARCH_ppc64le
-	MOVD	$·rcon(SB), PTR // PTR point to rcon addr
+#ifdef NEEDS_ESPERM
+	MOVD	$·rcon(SB), PTR // PTR points to rcon addr
 	LVX	(PTR), ESPERM
 	ADD	$0x10, PTR
 #else
-	MOVD	$·rcon+0x10(SB), PTR // PTR point to rcon addr (skipping permute vector)
+	MOVD	$·rcon+0x10(SB), PTR // PTR points to rcon addr (skipping permute vector)
 #endif
 
 	// Get key from memory and write aligned into VR
@@ -191,7 +194,8 @@
 	RET
 
 l192:
-	LXSDX_BE(INP, R0, IN1)                   // Load next 8 bytes into upper half of VSR in BE order.
+	LXSDX	(INP+R0), IN1                    // Load next 8 bytes into upper half of VSR.
+	XXBRD_ON_LE(IN1, IN1)                    // and convert to BE ordering on LE hosts.
 	MOVD	$4, CNT                          // li 7,4
 	STXVD2X	IN0, (R0+OUTENC)
 	STXVD2X	IN0, (R0+OUTDEC)
@@ -309,7 +313,7 @@
 	MOVD	xk+8(FP), R5   // Key pointer
 	MOVD	dst+16(FP), R3 // Dest pointer
 	MOVD	src+24(FP), R4 // Src pointer
-#ifdef GOARCH_ppc64le
+#ifdef NEEDS_ESPERM
 	MOVD	$·rcon(SB), R7
 	LVX	(R7), ESPERM   // Permute value for P8_ macros.
 #endif
@@ -404,7 +408,7 @@
 	MOVD	xk+8(FP), R5   // Key pointer
 	MOVD	dst+16(FP), R3 // Dest pointer
 	MOVD	src+24(FP), R4 // Src pointer
-#ifdef GOARCH_ppc64le
+#ifdef NEEDS_ESPERM
 	MOVD	$·rcon(SB), R7
 	LVX	(R7), ESPERM   // Permute value for P8_ macros.
 #endif
@@ -500,155 +504,172 @@
 #undef KEY
 #undef TMP
 
-// CBC encrypt or decrypt
-// R3 src
-// R4 dst
-// R5 len
-// R6 key
-// R7 iv
-// R8 enc=1 dec=0
-// Ported from: aes_p8_cbc_encrypt
-// Register usage:
-// R9: ROUNDS
-// R10: Index
-// V4: IV
-// V5: SRC
-// V7: DST
-
 #define INP R3
-#define OUT R4
+#define OUTP R4
 #define LEN R5
-#define KEY R6
-#define IVP R7
-#define ENC R8
-#define ROUNDS R9
-#define IDX R10
+#define KEYP R6
+#define ROUNDS R7
+#define IVP R8
+#define ENC R9
 
-#define RNDKEY0 V0
 #define INOUT V2
 #define TMP V3
-
 #define IVEC V4
 
-// Vector loads are done using LVX followed by
-// a VPERM using mask generated from previous
-// LVSL or LVSR instruction, to obtain the correct
-// bytes if address is unaligned.
+// Load the crypt key into VSRs.
+//
+// The expanded key is stored and loaded using
+// STXVD2X/LXVD2X. The in-memory byte ordering
+// depends on the endianness of the machine. The
+// expanded keys are generated by expandKeyAsm above.
+//
+// Rkeyp holds the key pointer. It is clobbered. Once
+// the expanded keys are loaded, it is not needed.
+//
+// R12,R14-R21 are scratch registers.
+// For keyp of 10, V6, V11-V20 hold the expanded key.
+// For keyp of 12, V6, V9-V20 hold the expanded key.
+// For keyp of 14, V6, V7-V20 hold the expanded key.
+#define LOAD_KEY(Rkeyp) \
+	MOVD	$16, R12 \
+	MOVD	$32, R14 \
+	MOVD	$48, R15 \
+	MOVD	$64, R16 \
+	MOVD	$80, R17 \
+	MOVD	$96, R18 \
+	MOVD	$112, R19 \
+	MOVD	$128, R20 \
+	MOVD	$144, R21 \
+	LXVD2X	(R0+Rkeyp), V6 \
+	ADD	$16, Rkeyp \
+	BEQ	CR1, L_start10 \
+	BEQ	CR2, L_start12 \
+	LXVD2X	(R0+Rkeyp), V7 \
+	LXVD2X	(R12+Rkeyp), V8 \
+	ADD	$32, Rkeyp \
+	L_start12: \
+	LXVD2X	(R0+Rkeyp), V9 \
+	LXVD2X	(R12+Rkeyp), V10 \
+	ADD	$32, Rkeyp \
+	L_start10: \
+	LXVD2X	(R0+Rkeyp), V11 \
+	LXVD2X	(R12+Rkeyp), V12 \
+	LXVD2X	(R14+Rkeyp), V13 \
+	LXVD2X	(R15+Rkeyp), V14 \
+	LXVD2X	(R16+Rkeyp), V15 \
+	LXVD2X	(R17+Rkeyp), V16 \
+	LXVD2X	(R18+Rkeyp), V17 \
+	LXVD2X	(R19+Rkeyp), V18 \
+	LXVD2X	(R20+Rkeyp), V19 \
+	LXVD2X	(R21+Rkeyp), V20
 
-// Encryption is done with VCIPHER and VCIPHERLAST
-// Decryption is done with VNCIPHER and VNCIPHERLAST
+// Perform aes cipher operation for keysize 10/12/14 using the keys
+// loaded by LOAD_KEY, and key size information held in CR1EQ/CR2EQ.
+//
+// Vxor is ideally V6 (Key[0-3]), but for slightly improved encrypting
+// performance V6 and IVEC can be swapped (xor is both associative and
+// commutative) during encryption:
+//
+//	VXOR INOUT, IVEC, INOUT
+//	VXOR INOUT, V6, INOUT
+//
+//	into
+//
+//	VXOR INOUT, V6, INOUT
+//	VXOR INOUT, IVEC, INOUT
+//
+#define CIPHER_BLOCK(Vin, Vxor, Vout, vcipher, vciphel, label10, label12) \
+	VXOR	Vin, Vxor, Vout \
+	BEQ	CR1, label10 \
+	BEQ	CR2, label12 \
+	vcipher	Vout, V7, Vout \
+	vcipher	Vout, V8, Vout \
+	label12: \
+	vcipher	Vout, V9, Vout \
+	vcipher	Vout, V10, Vout \
+	label10: \
+	vcipher	Vout, V11, Vout \
+	vcipher	Vout, V12, Vout \
+	vcipher	Vout, V13, Vout \
+	vcipher	Vout, V14, Vout \
+	vcipher	Vout, V15, Vout \
+	vcipher	Vout, V16, Vout \
+	vcipher	Vout, V17, Vout \
+	vcipher	Vout, V18, Vout \
+	vcipher	Vout, V19, Vout \
+	vciphel	Vout, V20, Vout \
 
-// Encrypt and decypt is done as follows:
-// - INOUT value is initialized in outer loop.
-// - ROUNDS value is adjusted for loop unrolling.
-// - Encryption/decryption is done in loop based on
-// adjusted ROUNDS value.
-// - Final INOUT value is encrypted/decrypted and stored.
+#define CLEAR_KEYS() \
+	VXOR	V6, V6, V6 \
+	VXOR	V7, V7, V7 \
+	VXOR	V8, V8, V8 \
+	VXOR	V9, V9, V9 \
+	VXOR	V10, V10, V10 \
+	VXOR	V11, V11, V11 \
+	VXOR	V12, V12, V12 \
+	VXOR	V13, V13, V13 \
+	VXOR	V14, V14, V14 \
+	VXOR	V15, V15, V15 \
+	VXOR	V16, V16, V16 \
+	VXOR	V17, V17, V17 \
+	VXOR	V18, V18, V18 \
+	VXOR	V19, V19, V19 \
+	VXOR	V20, V20, V20
 
-// Note: original implementation had an 8X version
-// for decryption which was omitted to avoid the
-// complexity.
-
-// func cryptBlocksChain(src, dst *byte, length int, key *uint32, iv *byte, enc int, nr int)
+//func cryptBlocksChain(src, dst *byte, length int, key *uint32, iv *byte, enc int, nr int)
 TEXT ·cryptBlocksChain(SB), NOSPLIT|NOFRAME, $0
 	MOVD	src+0(FP), INP
-	MOVD	dst+8(FP), OUT
+	MOVD	dst+8(FP), OUTP
 	MOVD	length+16(FP), LEN
-	MOVD	key+24(FP), KEY
+	MOVD	key+24(FP), KEYP
 	MOVD	iv+32(FP), IVP
 	MOVD	enc+40(FP), ENC
 	MOVD	nr+48(FP), ROUNDS
 
-#ifdef GOARCH_ppc64le
+#ifdef NEEDS_ESPERM
 	MOVD	$·rcon(SB), R11
 	LVX	(R11), ESPERM   // Permute value for P8_ macros.
 #endif
 
-	CMPU	LEN, $16    // cmpldi r5,16
-	BC	14, 0, LR   // bltlr-, return if len < 16.
-	CMPW	ENC, $0     // cmpwi r8,0
+	// Assume len > 0 && len % blockSize == 0.
+	CMPW	ENC, $0
+	P8_LXVB16X(IVP, R0, IVEC)
+	CMPU	ROUNDS, $10, CR1
+	CMPU	ROUNDS, $12, CR2 // Only sizes 10/12/14 are supported.
 
-	P8_LXVB16X(IVP, R0, IVEC) // load ivec in BE register order
+	// Setup key in VSRs, and set loop count in CTR.
+	LOAD_KEY(KEYP)
+	SRD	$4, LEN
+	MOVD	LEN, CTR
 
-	SRW	$1, ROUNDS  // rlwinm r9,r9,31,1,31
-	MOVD	$0, IDX     // li r10,0
-	ADD	$-1, ROUNDS // addi r9,r9,-1
-	BEQ	Lcbc_dec    // beq
-	PCALIGN	$16
+	BEQ	Lcbc_dec
 
-	// Outer loop: initialize encrypted value (INOUT)
-	// Load input (INPTAIL) ivec (IVEC)
+	PCALIGN $32
 Lcbc_enc:
-	P8_LXVB16X(INP, R0, INOUT)                 // load text in BE vreg order
-	ADD	$16, INP                           // addi r3,r3,16
-	MOVD	ROUNDS, CTR                        // mtctr r9
-	ADD	$-16, LEN                          // addi r5,r5,-16
-	LXVD2X	(KEY+IDX), RNDKEY0                 // load first xkey
-	ADD	$16, IDX                           // addi r10,r10,16
-	VXOR	INOUT, RNDKEY0, INOUT              // vxor v2,v2,v0
-	VXOR	INOUT, IVEC, INOUT                 // vxor v2,v2,v4
+	P8_LXVB16X(INP, R0, INOUT)
+	ADD	$16, INP
+	VXOR	INOUT, V6, INOUT
+	CIPHER_BLOCK(INOUT, IVEC, INOUT, VCIPHER, VCIPHERLAST, Lcbc_enc10, Lcbc_enc12)
+	VOR	INOUT, INOUT, IVEC // ciphertext (INOUT) is IVEC for next block.
+	P8_STXVB16X(INOUT, OUTP, R0)
+	ADD	$16, OUTP
+	BDNZ	Lcbc_enc
 
-	// Encryption loop of INOUT using RNDKEY0
-Loop_cbc_enc:
-	LXVD2X	(KEY+IDX), RNDKEY0                 // load next xkey
-	VCIPHER	INOUT, RNDKEY0, INOUT              // vcipher v2,v2,v1
-	ADD	$16, IDX                           // addi r10,r10,16
-	LXVD2X	(KEY+IDX), RNDKEY0                 // load next xkey
-	VCIPHER	INOUT, RNDKEY0, INOUT              // vcipher v2,v2,v1
-	ADD	$16, IDX                           // addi r10,r10,16
-	BDNZ Loop_cbc_enc
+	P8_STXVB16X(INOUT, IVP, R0)
+	CLEAR_KEYS()
+	RET
 
-	// Encrypt tail values and store INOUT
-	LXVD2X	(KEY+IDX), RNDKEY0                 // load next xkey
-	VCIPHER	INOUT, RNDKEY0, INOUT              // vcipher v2,v2,v1
-	ADD	$16, IDX                           // addi r10,r10,16
-	LXVD2X	(KEY+IDX), RNDKEY0                 // load final xkey
-	VCIPHERLAST	INOUT, RNDKEY0, IVEC       // vcipherlast v4,v2,v0
-	MOVD	$0, IDX                            // reset key index for next block
-	CMPU	LEN, $16                           // cmpldi r5,16
-	P8_STXVB16X(IVEC, OUT, R0)                 // store ciphertext in BE order
-	ADD	$16, OUT                           // addi r4,r4,16
-	BGE	Lcbc_enc                           // bge Lcbc_enc
-	BR	Lcbc_done                          // b Lcbc_done
-
-	// Outer loop: initialize decrypted value (INOUT)
-	// Load input (INPTAIL) ivec (IVEC)
+	PCALIGN $32
 Lcbc_dec:
-	P8_LXVB16X(INP, R0, TMP)                   // load ciphertext in BE vreg order
-	ADD	$16, INP                           // addi r3,r3,16
-	MOVD	ROUNDS, CTR                        // mtctr r9
-	ADD	$-16, LEN                          // addi r5,r5,-16
-	LXVD2X	(KEY+IDX), RNDKEY0                 // load first xkey
-	ADD	$16, IDX                           // addi r10,r10,16
-	VXOR	TMP, RNDKEY0, INOUT                // vxor v2,v3,v0
-	PCALIGN	$16
+	P8_LXVB16X(INP, R0, TMP)
+	ADD	$16, INP
+	CIPHER_BLOCK(TMP, V6, INOUT, VNCIPHER, VNCIPHERLAST, Lcbc_dec10, Lcbc_dec12)
+	VXOR	INOUT, IVEC, INOUT
+	VOR	TMP, TMP, IVEC // TMP is IVEC for next block.
+	P8_STXVB16X(INOUT, OUTP, R0)
+	ADD	$16, OUTP
+	BDNZ	Lcbc_dec
 
-	// Decryption loop of INOUT using RNDKEY0
-Loop_cbc_dec:
-	LXVD2X	(KEY+IDX), RNDKEY0                 // load next xkey
-	ADD	$16, IDX                           // addi r10,r10,16
-	VNCIPHER	INOUT, RNDKEY0, INOUT      // vncipher v2,v2,v1
-	LXVD2X	(KEY+IDX), RNDKEY0                 // load next xkey
-	ADD	$16, IDX                           // addi r10,r10,16
-	VNCIPHER	INOUT, RNDKEY0, INOUT      // vncipher v2,v2,v0
-	BDNZ Loop_cbc_dec
-
-	// Decrypt tail values and store INOUT
-	LXVD2X	(KEY+IDX), RNDKEY0                 // load next xkey
-	ADD	$16, IDX                           // addi r10,r10,16
-	VNCIPHER	INOUT, RNDKEY0, INOUT      // vncipher v2,v2,v1
-	LXVD2X	(KEY+IDX), RNDKEY0                 // load final xkey
-	MOVD	$0, IDX                            // li r10,0
-	VNCIPHERLAST	INOUT, RNDKEY0, INOUT      // vncipherlast v2,v2,v0
-	CMPU	LEN, $16                           // cmpldi r5,16
-	VXOR	INOUT, IVEC, INOUT                 // vxor v2,v2,v4
-	VOR	TMP, TMP, IVEC                     // vor v4,v3,v3
-	P8_STXVB16X(INOUT, OUT, R0)                // store text in BE order
-	ADD	$16, OUT                           // addi r4,r4,16
-	BGE	Lcbc_dec                           // bge
-
-Lcbc_done:
-	VXOR	RNDKEY0, RNDKEY0, RNDKEY0          // clear key register
-	P8_STXVB16X(IVEC, R0, IVP)                 // Save ivec in BE order for next round.
-	RET                                        // bclr 20,lt,0
-
+	P8_STXVB16X(IVEC, IVP, R0)
+	CLEAR_KEYS()
+	RET
diff --git a/src/crypto/aes/cbc_ppc64x.go b/src/crypto/aes/cbc_ppc64x.go
index 797023e..c23c371 100644
--- a/src/crypto/aes/cbc_ppc64x.go
+++ b/src/crypto/aes/cbc_ppc64x.go
@@ -8,7 +8,7 @@
 
 import (
 	"crypto/cipher"
-	"crypto/internal/subtle"
+	"crypto/internal/alias"
 )
 
 // Assert that aesCipherAsm implements the cbcEncAble and cbcDecAble interfaces.
@@ -54,7 +54,7 @@
 	if len(dst) < len(src) {
 		panic("crypto/cipher: output smaller than input")
 	}
-	if subtle.InexactOverlap(dst[:len(src)], src) {
+	if alias.InexactOverlap(dst[:len(src)], src) {
 		panic("crypto/cipher: invalid buffer overlap")
 	}
 	if len(src) > 0 {
diff --git a/src/crypto/aes/cbc_s390x.go b/src/crypto/aes/cbc_s390x.go
index 766247a..eaa21f8 100644
--- a/src/crypto/aes/cbc_s390x.go
+++ b/src/crypto/aes/cbc_s390x.go
@@ -6,7 +6,7 @@
 
 import (
 	"crypto/cipher"
-	"crypto/internal/subtle"
+	"crypto/internal/alias"
 )
 
 // Assert that aesCipherAsm implements the cbcEncAble and cbcDecAble interfaces.
@@ -50,7 +50,7 @@
 	if len(dst) < len(src) {
 		panic("crypto/cipher: output smaller than input")
 	}
-	if subtle.InexactOverlap(dst[:len(src)], src) {
+	if alias.InexactOverlap(dst[:len(src)], src) {
 		panic("crypto/cipher: invalid buffer overlap")
 	}
 	if len(src) > 0 {
diff --git a/src/crypto/aes/cipher.go b/src/crypto/aes/cipher.go
index db0ee38..183c169 100644
--- a/src/crypto/aes/cipher.go
+++ b/src/crypto/aes/cipher.go
@@ -6,8 +6,8 @@
 
 import (
 	"crypto/cipher"
+	"crypto/internal/alias"
 	"crypto/internal/boring"
-	"crypto/internal/subtle"
 	"strconv"
 )
 
@@ -62,7 +62,7 @@
 	if len(dst) < BlockSize {
 		panic("crypto/aes: output not full block")
 	}
-	if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
+	if alias.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
 		panic("crypto/aes: invalid buffer overlap")
 	}
 	encryptBlockGo(c.enc, dst, src)
@@ -75,7 +75,7 @@
 	if len(dst) < BlockSize {
 		panic("crypto/aes: output not full block")
 	}
-	if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
+	if alias.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
 		panic("crypto/aes: invalid buffer overlap")
 	}
 	decryptBlockGo(c.dec, dst, src)
diff --git a/src/crypto/aes/cipher_asm.go b/src/crypto/aes/cipher_asm.go
index 1482b22..90031c5 100644
--- a/src/crypto/aes/cipher_asm.go
+++ b/src/crypto/aes/cipher_asm.go
@@ -8,8 +8,8 @@
 
 import (
 	"crypto/cipher"
+	"crypto/internal/alias"
 	"crypto/internal/boring"
-	"crypto/internal/subtle"
 	"internal/cpu"
 	"internal/goarch"
 )
@@ -75,7 +75,7 @@
 	if len(dst) < BlockSize {
 		panic("crypto/aes: output not full block")
 	}
-	if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
+	if alias.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
 		panic("crypto/aes: invalid buffer overlap")
 	}
 	encryptBlockAsm(len(c.enc)/4-1, &c.enc[0], &dst[0], &src[0])
@@ -89,7 +89,7 @@
 	if len(dst) < BlockSize {
 		panic("crypto/aes: output not full block")
 	}
-	if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
+	if alias.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
 		panic("crypto/aes: invalid buffer overlap")
 	}
 	decryptBlockAsm(len(c.dec)/4-1, &c.dec[0], &dst[0], &src[0])
diff --git a/src/crypto/aes/cipher_s390x.go b/src/crypto/aes/cipher_s390x.go
index e357851..8dd3d8f 100644
--- a/src/crypto/aes/cipher_s390x.go
+++ b/src/crypto/aes/cipher_s390x.go
@@ -6,7 +6,7 @@
 
 import (
 	"crypto/cipher"
-	"crypto/internal/subtle"
+	"crypto/internal/alias"
 	"internal/cpu"
 )
 
@@ -69,7 +69,7 @@
 	if len(dst) < BlockSize {
 		panic("crypto/aes: output not full block")
 	}
-	if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
+	if alias.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
 		panic("crypto/aes: invalid buffer overlap")
 	}
 	cryptBlocks(c.function, &c.key[0], &dst[0], &src[0], BlockSize)
@@ -82,7 +82,7 @@
 	if len(dst) < BlockSize {
 		panic("crypto/aes: output not full block")
 	}
-	if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
+	if alias.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
 		panic("crypto/aes: invalid buffer overlap")
 	}
 	// The decrypt function code is equal to the function code + 128.
diff --git a/src/crypto/aes/ctr_s390x.go b/src/crypto/aes/ctr_s390x.go
index f5c33d5..0d3a58e 100644
--- a/src/crypto/aes/ctr_s390x.go
+++ b/src/crypto/aes/ctr_s390x.go
@@ -6,7 +6,7 @@
 
 import (
 	"crypto/cipher"
-	"crypto/internal/subtle"
+	"crypto/internal/alias"
 	"encoding/binary"
 )
 
@@ -69,7 +69,7 @@
 	if len(dst) < len(src) {
 		panic("crypto/cipher: output smaller than input")
 	}
-	if subtle.InexactOverlap(dst[:len(src)], src) {
+	if alias.InexactOverlap(dst[:len(src)], src) {
 		panic("crypto/cipher: invalid buffer overlap")
 	}
 	for len(src) > 0 {
diff --git a/src/crypto/aes/gcm_s390x.go b/src/crypto/aes/gcm_s390x.go
index 98d530a..d95f169 100644
--- a/src/crypto/aes/gcm_s390x.go
+++ b/src/crypto/aes/gcm_s390x.go
@@ -6,7 +6,7 @@
 
 import (
 	"crypto/cipher"
-	subtleoverlap "crypto/internal/subtle"
+	"crypto/internal/alias"
 	"crypto/subtle"
 	"encoding/binary"
 	"errors"
@@ -211,7 +211,7 @@
 	}
 
 	ret, out := sliceForAppend(dst, len(plaintext)+g.tagSize)
-	if subtleoverlap.InexactOverlap(out[:len(plaintext)], plaintext) {
+	if alias.InexactOverlap(out[:len(plaintext)], plaintext) {
 		panic("crypto/cipher: invalid buffer overlap")
 	}
 
@@ -260,7 +260,7 @@
 	g.auth(expectedTag[:], ciphertext, data, &tagMask)
 
 	ret, out := sliceForAppend(dst, len(ciphertext))
-	if subtleoverlap.InexactOverlap(out, ciphertext) {
+	if alias.InexactOverlap(out, ciphertext) {
 		panic("crypto/cipher: invalid buffer overlap")
 	}
 
@@ -312,7 +312,7 @@
 	}
 
 	ret, out := sliceForAppend(dst, len(plaintext)+g.tagSize)
-	if subtleoverlap.InexactOverlap(out[:len(plaintext)], plaintext) {
+	if alias.InexactOverlap(out[:len(plaintext)], plaintext) {
 		panic("crypto/cipher: invalid buffer overlap")
 	}
 
@@ -342,7 +342,7 @@
 	tag := ciphertext[len(ciphertext)-g.tagSize:]
 	ciphertext = ciphertext[:len(ciphertext)-g.tagSize]
 	ret, out := sliceForAppend(dst, len(ciphertext))
-	if subtleoverlap.InexactOverlap(out, ciphertext) {
+	if alias.InexactOverlap(out, ciphertext) {
 		panic("crypto/cipher: invalid buffer overlap")
 	}
 
diff --git a/src/crypto/boring/boring_test.go b/src/crypto/boring/boring_test.go
index 9e8fd35..33e5f1b 100644
--- a/src/crypto/boring/boring_test.go
+++ b/src/crypto/boring/boring_test.go
@@ -13,7 +13,7 @@
 )
 
 func TestEnabled(t *testing.T) {
-	supportedPlatform := runtime.GOOS == "linux" && runtime.GOARCH == "amd64"
+	supportedPlatform := runtime.GOOS == "linux" && (runtime.GOARCH == "amd64" || runtime.GOARCH == "arm64")
 	if supportedPlatform && !boring.Enabled() {
 		t.Error("Enabled returned false on a supported platform")
 	} else if !supportedPlatform && boring.Enabled() {
diff --git a/src/crypto/cipher/cbc.go b/src/crypto/cipher/cbc.go
index a719b61..51a1420 100644
--- a/src/crypto/cipher/cbc.go
+++ b/src/crypto/cipher/cbc.go
@@ -11,7 +11,11 @@
 
 package cipher
 
-import "crypto/internal/subtle"
+import (
+	"bytes"
+	"crypto/internal/alias"
+	"crypto/subtle"
+)
 
 type cbc struct {
 	b         Block
@@ -24,7 +28,7 @@
 	return &cbc{
 		b:         b,
 		blockSize: b.BlockSize(),
-		iv:        dup(iv),
+		iv:        bytes.Clone(iv),
 		tmp:       make([]byte, b.BlockSize()),
 	}
 }
@@ -72,7 +76,7 @@
 	if len(dst) < len(src) {
 		panic("crypto/cipher: output smaller than input")
 	}
-	if subtle.InexactOverlap(dst[:len(src)], src) {
+	if alias.InexactOverlap(dst[:len(src)], src) {
 		panic("crypto/cipher: invalid buffer overlap")
 	}
 
@@ -80,7 +84,7 @@
 
 	for len(src) > 0 {
 		// Write the xor to dst, then encrypt in place.
-		xorBytes(dst[:x.blockSize], src[:x.blockSize], iv)
+		subtle.XORBytes(dst[:x.blockSize], src[:x.blockSize], iv)
 		x.b.Encrypt(dst[:x.blockSize], dst[:x.blockSize])
 
 		// Move to the next block with this block as the next iv.
@@ -143,7 +147,7 @@
 	if len(dst) < len(src) {
 		panic("crypto/cipher: output smaller than input")
 	}
-	if subtle.InexactOverlap(dst[:len(src)], src) {
+	if alias.InexactOverlap(dst[:len(src)], src) {
 		panic("crypto/cipher: invalid buffer overlap")
 	}
 	if len(src) == 0 {
@@ -162,7 +166,7 @@
 	// Loop over all but the first block.
 	for start > 0 {
 		x.b.Decrypt(dst[start:end], src[start:end])
-		xorBytes(dst[start:end], dst[start:end], src[prev:start])
+		subtle.XORBytes(dst[start:end], dst[start:end], src[prev:start])
 
 		end = start
 		start = prev
@@ -171,7 +175,7 @@
 
 	// The first block is special because it uses the saved iv.
 	x.b.Decrypt(dst[start:end], src[start:end])
-	xorBytes(dst[start:end], dst[start:end], x.iv)
+	subtle.XORBytes(dst[start:end], dst[start:end], x.iv)
 
 	// Set the new iv to the first block we copied earlier.
 	x.iv, x.tmp = x.tmp, x.iv
diff --git a/src/crypto/cipher/cfb.go b/src/crypto/cipher/cfb.go
index 80c9bc2..aae3575 100644
--- a/src/crypto/cipher/cfb.go
+++ b/src/crypto/cipher/cfb.go
@@ -6,7 +6,10 @@
 
 package cipher
 
-import "crypto/internal/subtle"
+import (
+	"crypto/internal/alias"
+	"crypto/subtle"
+)
 
 type cfb struct {
 	b       Block
@@ -21,7 +24,7 @@
 	if len(dst) < len(src) {
 		panic("crypto/cipher: output smaller than input")
 	}
-	if subtle.InexactOverlap(dst[:len(src)], src) {
+	if alias.InexactOverlap(dst[:len(src)], src) {
 		panic("crypto/cipher: invalid buffer overlap")
 	}
 	for len(src) > 0 {
@@ -37,7 +40,7 @@
 			// able to match CTR/OFB performance.
 			copy(x.next[x.outUsed:], src)
 		}
-		n := xorBytes(dst, src, x.out[x.outUsed:])
+		n := subtle.XORBytes(dst, src, x.out[x.outUsed:])
 		if !x.decrypt {
 			copy(x.next[x.outUsed:], dst)
 		}
diff --git a/src/crypto/cipher/cipher.go b/src/crypto/cipher/cipher.go
index 7e1a4de..df6f596 100644
--- a/src/crypto/cipher/cipher.go
+++ b/src/crypto/cipher/cipher.go
@@ -59,11 +59,3 @@
 	// maintains state and does not reset at each CryptBlocks call.
 	CryptBlocks(dst, src []byte)
 }
-
-// Utility routines
-
-func dup(p []byte) []byte {
-	q := make([]byte, len(p))
-	copy(q, p)
-	return q
-}
diff --git a/src/crypto/cipher/ctr.go b/src/crypto/cipher/ctr.go
index cba028d..3ac0ff7 100644
--- a/src/crypto/cipher/ctr.go
+++ b/src/crypto/cipher/ctr.go
@@ -12,7 +12,11 @@
 
 package cipher
 
-import "crypto/internal/subtle"
+import (
+	"bytes"
+	"crypto/internal/alias"
+	"crypto/subtle"
+)
 
 type ctr struct {
 	b       Block
@@ -45,7 +49,7 @@
 	}
 	return &ctr{
 		b:       block,
-		ctr:     dup(iv),
+		ctr:     bytes.Clone(iv),
 		out:     make([]byte, 0, bufSize),
 		outUsed: 0,
 	}
@@ -76,14 +80,14 @@
 	if len(dst) < len(src) {
 		panic("crypto/cipher: output smaller than input")
 	}
-	if subtle.InexactOverlap(dst[:len(src)], src) {
+	if alias.InexactOverlap(dst[:len(src)], src) {
 		panic("crypto/cipher: invalid buffer overlap")
 	}
 	for len(src) > 0 {
 		if x.outUsed >= len(x.out)-x.b.BlockSize() {
 			x.refill()
 		}
-		n := xorBytes(dst, src, x.out[x.outUsed:])
+		n := subtle.XORBytes(dst, src, x.out[x.outUsed:])
 		dst = dst[n:]
 		src = src[n:]
 		x.outUsed += n
diff --git a/src/crypto/cipher/export_test.go b/src/crypto/cipher/export_test.go
index beb9bf5..5ecd67b 100644
--- a/src/crypto/cipher/export_test.go
+++ b/src/crypto/cipher/export_test.go
@@ -5,6 +5,5 @@
 package cipher
 
 // Export internal functions for testing.
-var XorBytes = xorBytes
 var NewCBCGenericEncrypter = newCBCGenericEncrypter
 var NewCBCGenericDecrypter = newCBCGenericDecrypter
diff --git a/src/crypto/cipher/gcm.go b/src/crypto/cipher/gcm.go
index 5b14c0a..477d26a 100644
--- a/src/crypto/cipher/gcm.go
+++ b/src/crypto/cipher/gcm.go
@@ -5,7 +5,7 @@
 package cipher
 
 import (
-	subtleoverlap "crypto/internal/subtle"
+	"crypto/internal/alias"
 	"crypto/subtle"
 	"encoding/binary"
 	"errors"
@@ -174,7 +174,7 @@
 	}
 
 	ret, out := sliceForAppend(dst, len(plaintext)+g.tagSize)
-	if subtleoverlap.InexactOverlap(out, plaintext) {
+	if alias.InexactOverlap(out, plaintext) {
 		panic("crypto/cipher: invalid buffer overlap")
 	}
 
@@ -225,7 +225,7 @@
 	g.auth(expectedTag[:], ciphertext, data, &tagMask)
 
 	ret, out := sliceForAppend(dst, len(ciphertext))
-	if subtleoverlap.InexactOverlap(out, ciphertext) {
+	if alias.InexactOverlap(out, ciphertext) {
 		panic("crypto/cipher: invalid buffer overlap")
 	}
 
@@ -373,7 +373,7 @@
 		g.cipher.Encrypt(mask[:], counter[:])
 		gcmInc32(counter)
 
-		xorWords(out, in, mask[:])
+		subtle.XORBytes(out, in, mask[:])
 		out = out[gcmBlockSize:]
 		in = in[gcmBlockSize:]
 	}
@@ -381,7 +381,7 @@
 	if len(in) > 0 {
 		g.cipher.Encrypt(mask[:], counter[:])
 		gcmInc32(counter)
-		xorBytes(out, in, mask[:])
+		subtle.XORBytes(out, in, mask[:])
 	}
 }
 
@@ -423,5 +423,5 @@
 	binary.BigEndian.PutUint64(out, y.low)
 	binary.BigEndian.PutUint64(out[8:], y.high)
 
-	xorWords(out, out, tagMask[:])
+	subtle.XORBytes(out, out, tagMask[:])
 }
diff --git a/src/crypto/cipher/ofb.go b/src/crypto/cipher/ofb.go
index fc47724..1195fdd 100644
--- a/src/crypto/cipher/ofb.go
+++ b/src/crypto/cipher/ofb.go
@@ -6,7 +6,10 @@
 
 package cipher
 
-import "crypto/internal/subtle"
+import (
+	"crypto/internal/alias"
+	"crypto/subtle"
+)
 
 type ofb struct {
 	b       Block
@@ -59,14 +62,14 @@
 	if len(dst) < len(src) {
 		panic("crypto/cipher: output smaller than input")
 	}
-	if subtle.InexactOverlap(dst[:len(src)], src) {
+	if alias.InexactOverlap(dst[:len(src)], src) {
 		panic("crypto/cipher: invalid buffer overlap")
 	}
 	for len(src) > 0 {
 		if x.outUsed >= len(x.out)-x.b.BlockSize() {
 			x.refill()
 		}
-		n := xorBytes(dst, src, x.out[x.outUsed:])
+		n := subtle.XORBytes(dst, src, x.out[x.outUsed:])
 		dst = dst[n:]
 		src = src[n:]
 		x.outUsed += n
diff --git a/src/crypto/cipher/xor_amd64.go b/src/crypto/cipher/xor_amd64.go
deleted file mode 100644
index a595acc..0000000
--- a/src/crypto/cipher/xor_amd64.go
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package cipher
-
-// xorBytes xors the bytes in a and b. The destination should have enough
-// space, otherwise xorBytes will panic. Returns the number of bytes xor'd.
-func xorBytes(dst, a, b []byte) int {
-	n := len(a)
-	if len(b) < n {
-		n = len(b)
-	}
-	if n == 0 {
-		return 0
-	}
-	_ = dst[n-1]
-	xorBytesSSE2(&dst[0], &a[0], &b[0], n) // amd64 must have SSE2
-	return n
-}
-
-func xorWords(dst, a, b []byte) {
-	xorBytes(dst, a, b)
-}
-
-//go:noescape
-func xorBytesSSE2(dst, a, b *byte, n int)
diff --git a/src/crypto/cipher/xor_amd64.s b/src/crypto/cipher/xor_amd64.s
deleted file mode 100644
index 780d37a..0000000
--- a/src/crypto/cipher/xor_amd64.s
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-
-// func xorBytesSSE2(dst, a, b *byte, n int)
-TEXT ·xorBytesSSE2(SB), NOSPLIT, $0
-	MOVQ  dst+0(FP), BX
-	MOVQ  a+8(FP), SI
-	MOVQ  b+16(FP), CX
-	MOVQ  n+24(FP), DX
-	TESTQ $15, DX            // AND 15 & len, if not zero jump to not_aligned.
-	JNZ   not_aligned
-
-aligned:
-	MOVQ $0, AX // position in slices
-
-loop16b:
-	MOVOU (SI)(AX*1), X0   // XOR 16byte forwards.
-	MOVOU (CX)(AX*1), X1
-	PXOR  X1, X0
-	MOVOU X0, (BX)(AX*1)
-	ADDQ  $16, AX
-	CMPQ  DX, AX
-	JNE   loop16b
-	RET
-
-loop_1b:
-	SUBQ  $1, DX           // XOR 1byte backwards.
-	MOVB  (SI)(DX*1), DI
-	MOVB  (CX)(DX*1), AX
-	XORB  AX, DI
-	MOVB  DI, (BX)(DX*1)
-	TESTQ $7, DX           // AND 7 & len, if not zero jump to loop_1b.
-	JNZ   loop_1b
-	CMPQ  DX, $0           // if len is 0, ret.
-	JE    ret
-	TESTQ $15, DX          // AND 15 & len, if zero jump to aligned.
-	JZ    aligned
-
-not_aligned:
-	TESTQ $7, DX           // AND $7 & len, if not zero jump to loop_1b.
-	JNE   loop_1b
-	SUBQ  $8, DX           // XOR 8bytes backwards.
-	MOVQ  (SI)(DX*1), DI
-	MOVQ  (CX)(DX*1), AX
-	XORQ  AX, DI
-	MOVQ  DI, (BX)(DX*1)
-	CMPQ  DX, $16          // if len is greater or equal 16 here, it must be aligned.
-	JGE   aligned
-
-ret:
-	RET
diff --git a/src/crypto/cipher/xor_arm64.go b/src/crypto/cipher/xor_arm64.go
deleted file mode 100644
index 35a785a..0000000
--- a/src/crypto/cipher/xor_arm64.go
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package cipher
-
-// xorBytes xors the bytes in a and b. The destination should have enough
-// space, otherwise xorBytes will panic. Returns the number of bytes xor'd.
-func xorBytes(dst, a, b []byte) int {
-	n := len(a)
-	if len(b) < n {
-		n = len(b)
-	}
-	if n == 0 {
-		return 0
-	}
-	// make sure dst has enough space
-	_ = dst[n-1]
-
-	xorBytesARM64(&dst[0], &a[0], &b[0], n)
-	return n
-}
-
-func xorWords(dst, a, b []byte) {
-	xorBytes(dst, a, b)
-}
-
-//go:noescape
-func xorBytesARM64(dst, a, b *byte, n int)
diff --git a/src/crypto/cipher/xor_arm64.s b/src/crypto/cipher/xor_arm64.s
deleted file mode 100644
index 669852d..0000000
--- a/src/crypto/cipher/xor_arm64.s
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-
-// func xorBytesARM64(dst, a, b *byte, n int)
-TEXT ·xorBytesARM64(SB), NOSPLIT|NOFRAME, $0
-	MOVD	dst+0(FP), R0
-	MOVD	a+8(FP), R1
-	MOVD	b+16(FP), R2
-	MOVD	n+24(FP), R3
-	CMP	$64, R3
-	BLT	tail
-loop_64:
-	VLD1.P	64(R1), [V0.B16, V1.B16, V2.B16, V3.B16]
-	VLD1.P	64(R2), [V4.B16, V5.B16, V6.B16, V7.B16]
-	VEOR	V0.B16, V4.B16, V4.B16
-	VEOR	V1.B16, V5.B16, V5.B16
-	VEOR	V2.B16, V6.B16, V6.B16
-	VEOR	V3.B16, V7.B16, V7.B16
-	VST1.P	[V4.B16, V5.B16, V6.B16, V7.B16], 64(R0)
-	SUBS	$64, R3
-	CMP	$64, R3
-	BGE	loop_64
-tail:
-	// quick end
-	CBZ	R3, end
-	TBZ	$5, R3, less_than32
-	VLD1.P	32(R1), [V0.B16, V1.B16]
-	VLD1.P	32(R2), [V2.B16, V3.B16]
-	VEOR	V0.B16, V2.B16, V2.B16
-	VEOR	V1.B16, V3.B16, V3.B16
-	VST1.P	[V2.B16, V3.B16], 32(R0)
-less_than32:
-	TBZ	$4, R3, less_than16
-	LDP.P	16(R1), (R11, R12)
-	LDP.P	16(R2), (R13, R14)
-	EOR	R11, R13, R13
-	EOR	R12, R14, R14
-	STP.P	(R13, R14), 16(R0)
-less_than16:
-	TBZ	$3, R3, less_than8
-	MOVD.P	8(R1), R11
-	MOVD.P	8(R2), R12
-	EOR	R11, R12, R12
-	MOVD.P	R12, 8(R0)
-less_than8:
-	TBZ	$2, R3, less_than4
-	MOVWU.P	4(R1), R13
-	MOVWU.P	4(R2), R14
-	EORW	R13, R14, R14
-	MOVWU.P	R14, 4(R0)
-less_than4:
-	TBZ	$1, R3, less_than2
-	MOVHU.P	2(R1), R15
-	MOVHU.P	2(R2), R16
-	EORW	R15, R16, R16
-	MOVHU.P	R16, 2(R0)
-less_than2:
-	TBZ	$0, R3, end
-	MOVBU	(R1), R17
-	MOVBU	(R2), R19
-	EORW	R17, R19, R19
-	MOVBU	R19, (R0)
-end:
-	RET
diff --git a/src/crypto/cipher/xor_generic.go b/src/crypto/cipher/xor_generic.go
deleted file mode 100644
index 43517a8..0000000
--- a/src/crypto/cipher/xor_generic.go
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build !amd64 && !ppc64 && !ppc64le && !arm64
-
-package cipher
-
-import (
-	"runtime"
-	"unsafe"
-)
-
-// xorBytes xors the bytes in a and b. The destination should have enough
-// space, otherwise xorBytes will panic. Returns the number of bytes xor'd.
-func xorBytes(dst, a, b []byte) int {
-	n := len(a)
-	if len(b) < n {
-		n = len(b)
-	}
-	if n == 0 {
-		return 0
-	}
-
-	switch {
-	case supportsUnaligned:
-		fastXORBytes(dst, a, b, n)
-	default:
-		// TODO(hanwen): if (dst, a, b) have common alignment
-		// we could still try fastXORBytes. It is not clear
-		// how often this happens, and it's only worth it if
-		// the block encryption itself is hardware
-		// accelerated.
-		safeXORBytes(dst, a, b, n)
-	}
-	return n
-}
-
-const wordSize = int(unsafe.Sizeof(uintptr(0)))
-const supportsUnaligned = runtime.GOARCH == "386" || runtime.GOARCH == "ppc64" || runtime.GOARCH == "ppc64le" || runtime.GOARCH == "s390x"
-
-// fastXORBytes xors in bulk. It only works on architectures that
-// support unaligned read/writes.
-// n needs to be smaller or equal than the length of a and b.
-func fastXORBytes(dst, a, b []byte, n int) {
-	// Assert dst has enough space
-	_ = dst[n-1]
-
-	w := n / wordSize
-	if w > 0 {
-		dw := *(*[]uintptr)(unsafe.Pointer(&dst))
-		aw := *(*[]uintptr)(unsafe.Pointer(&a))
-		bw := *(*[]uintptr)(unsafe.Pointer(&b))
-		for i := 0; i < w; i++ {
-			dw[i] = aw[i] ^ bw[i]
-		}
-	}
-
-	for i := (n - n%wordSize); i < n; i++ {
-		dst[i] = a[i] ^ b[i]
-	}
-}
-
-// n needs to be smaller or equal than the length of a and b.
-func safeXORBytes(dst, a, b []byte, n int) {
-	for i := 0; i < n; i++ {
-		dst[i] = a[i] ^ b[i]
-	}
-}
-
-// fastXORWords XORs multiples of 4 or 8 bytes (depending on architecture.)
-// The arguments are assumed to be of equal length.
-func fastXORWords(dst, a, b []byte) {
-	dw := *(*[]uintptr)(unsafe.Pointer(&dst))
-	aw := *(*[]uintptr)(unsafe.Pointer(&a))
-	bw := *(*[]uintptr)(unsafe.Pointer(&b))
-	n := len(b) / wordSize
-	for i := 0; i < n; i++ {
-		dw[i] = aw[i] ^ bw[i]
-	}
-}
-
-// fastXORWords XORs multiples of 4 or 8 bytes (depending on architecture.)
-// The slice arguments a and b are assumed to be of equal length.
-func xorWords(dst, a, b []byte) {
-	if supportsUnaligned {
-		fastXORWords(dst, a, b)
-	} else {
-		safeXORBytes(dst, a, b, len(b))
-	}
-}
diff --git a/src/crypto/cipher/xor_ppc64x.go b/src/crypto/cipher/xor_ppc64x.go
deleted file mode 100644
index f81eec5..0000000
--- a/src/crypto/cipher/xor_ppc64x.go
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build ppc64 || ppc64le
-
-package cipher
-
-// xorBytes xors the bytes in a and b. The destination should have enough
-// space, otherwise xorBytes will panic. Returns the number of bytes xor'd.
-func xorBytes(dst, a, b []byte) int {
-	n := len(a)
-	if len(b) < n {
-		n = len(b)
-	}
-	if n == 0 {
-		return 0
-	}
-	_ = dst[n-1]
-	xorBytesVSX(&dst[0], &a[0], &b[0], n)
-	return n
-}
-
-func xorWords(dst, a, b []byte) {
-	xorBytes(dst, a, b)
-}
-
-//go:noescape
-func xorBytesVSX(dst, a, b *byte, n int)
diff --git a/src/crypto/cipher/xor_ppc64x.s b/src/crypto/cipher/xor_ppc64x.s
deleted file mode 100644
index a2ec95c..0000000
--- a/src/crypto/cipher/xor_ppc64x.s
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build ppc64 || ppc64le
-
-#include "textflag.h"
-
-// func xorBytesVSX(dst, a, b *byte, n int)
-TEXT ·xorBytesVSX(SB), NOSPLIT, $0
-	MOVD	dst+0(FP), R3	// R3 = dst
-	MOVD	a+8(FP), R4	// R4 = a
-	MOVD	b+16(FP), R5	// R5 = b
-	MOVD	n+24(FP), R6	// R6 = n
-
-	CMPU	R6, $32, CR7	// Check if n ≥ 32 bytes
-	MOVD	R0, R8		// R8 = index
-	CMPU	R6, $8, CR6	// Check if 8 ≤ n < 32 bytes
-	BLT	CR6, small	// Smaller than 8
-	BLT	CR7, xor16	// Case for 16 ≤ n < 32 bytes
-
-	// Case for n ≥ 32 bytes
-preloop32:
-	SRD	$5, R6, R7	// Setup loop counter
-	MOVD	R7, CTR
-	MOVD	$16, R10
-	ANDCC	$31, R6, R9	// Check for tailing bytes for later
-loop32:
-	LXVD2X		(R4)(R8), VS32		// VS32 = a[i,...,i+15]
-	LXVD2X		(R4)(R10), VS34
-	LXVD2X		(R5)(R8), VS33		// VS33 = b[i,...,i+15]
-	LXVD2X		(R5)(R10), VS35
-	XXLXOR		VS32, VS33, VS32	// VS34 = a[] ^ b[]
-	XXLXOR		VS34, VS35, VS34
-	STXVD2X		VS32, (R3)(R8)		// Store to dst
-	STXVD2X		VS34, (R3)(R10)
-	ADD		$32, R8			// Update index
-	ADD		$32, R10
-	BC		16, 0, loop32		// bdnz loop16
-
-	BEQ		CR0, done
-
-	MOVD		R9, R6
-	CMP		R6, $8
-	BLT		small
-xor16:
-	CMP		R6, $16
-	BLT		xor8
-	LXVD2X		(R4)(R8), VS32
-	LXVD2X		(R5)(R8), VS33
-	XXLXOR		VS32, VS33, VS32
-	STXVD2X		VS32, (R3)(R8)
-	ADD		$16, R8
-	ADD		$-16, R6
-	CMP		R6, $8
-	BLT		small
-xor8:
-	// Case for 8 ≤ n < 16 bytes
-	MOVD    (R4)(R8), R14   // R14 = a[i,...,i+7]
-	MOVD    (R5)(R8), R15   // R15 = b[i,...,i+7]
-	XOR     R14, R15, R16   // R16 = a[] ^ b[]
-	SUB     $8, R6          // n = n - 8
-	MOVD    R16, (R3)(R8)   // Store to dst
-	ADD     $8, R8
-
-	// Check if we're finished
-	CMP     R6, R0
-	BGT     small
-	RET
-
-	// Case for n < 8 bytes and tailing bytes from the
-	// previous cases.
-small:
-	CMP	R6, R0
-	BEQ	done
-	MOVD	R6, CTR		// Setup loop counter
-
-loop:
-	MOVBZ	(R4)(R8), R14	// R14 = a[i]
-	MOVBZ	(R5)(R8), R15	// R15 = b[i]
-	XOR	R14, R15, R16	// R16 = a[i] ^ b[i]
-	MOVB	R16, (R3)(R8)	// Store to dst
-	ADD	$1, R8
-	BC	16, 0, loop	// bdnz loop
-
-done:
-	RET
diff --git a/src/crypto/cipher/xor_test.go b/src/crypto/cipher/xor_test.go
deleted file mode 100644
index 4f829e9..0000000
--- a/src/crypto/cipher/xor_test.go
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package cipher_test
-
-import (
-	"bytes"
-	"crypto/cipher"
-	"crypto/rand"
-	"fmt"
-	"io"
-	"testing"
-)
-
-func TestXOR(t *testing.T) {
-	for j := 1; j <= 1024; j++ {
-		if testing.Short() && j > 16 {
-			break
-		}
-		for alignP := 0; alignP < 2; alignP++ {
-			for alignQ := 0; alignQ < 2; alignQ++ {
-				for alignD := 0; alignD < 2; alignD++ {
-					p := make([]byte, j)[alignP:]
-					q := make([]byte, j)[alignQ:]
-					d1 := make([]byte, j+alignD)[alignD:]
-					d2 := make([]byte, j+alignD)[alignD:]
-					if _, err := io.ReadFull(rand.Reader, p); err != nil {
-						t.Fatal(err)
-					}
-					if _, err := io.ReadFull(rand.Reader, q); err != nil {
-						t.Fatal(err)
-					}
-					cipher.XorBytes(d1, p, q)
-					n := min(p, q)
-					for i := 0; i < n; i++ {
-						d2[i] = p[i] ^ q[i]
-					}
-					if !bytes.Equal(d1, d2) {
-						t.Logf("p: %#v", p)
-						t.Logf("q: %#v", q)
-						t.Logf("expect: %#v", d2)
-						t.Logf("result: %#v", d1)
-						t.Fatal("not equal")
-					}
-				}
-			}
-		}
-	}
-}
-
-func min(a, b []byte) int {
-	n := len(a)
-	if len(b) < n {
-		n = len(b)
-	}
-	return n
-}
-
-func BenchmarkXORBytes(b *testing.B) {
-	dst := make([]byte, 1<<15)
-	data0 := make([]byte, 1<<15)
-	data1 := make([]byte, 1<<15)
-	sizes := []int64{1 << 3, 1 << 7, 1 << 11, 1 << 15}
-	for _, size := range sizes {
-		b.Run(fmt.Sprintf("%dBytes", size), func(b *testing.B) {
-			s0 := data0[:size]
-			s1 := data1[:size]
-			b.SetBytes(int64(size))
-			for i := 0; i < b.N; i++ {
-				cipher.XorBytes(dst, s0, s1)
-			}
-		})
-	}
-}
diff --git a/src/crypto/des/block.go b/src/crypto/des/block.go
index c649dee..e029976 100644
--- a/src/crypto/des/block.go
+++ b/src/crypto/des/block.go
@@ -83,7 +83,7 @@
 
 var feistelBoxOnce sync.Once
 
-// general purpose function to perform DES block permutations
+// general purpose function to perform DES block permutations.
 func permuteBlock(src uint64, permutation []uint8) (block uint64) {
 	for position, n := range permutation {
 		bit := (src >> n) & 1
@@ -182,7 +182,7 @@
 	return block
 }
 
-// permuteInitialBlock is equivalent to the permutation defined
+// permuteFinalBlock is equivalent to the permutation defined
 // by finalPermutation.
 func permuteFinalBlock(block uint64) uint64 {
 	// Perform the same bit exchanges as permuteInitialBlock
@@ -209,7 +209,7 @@
 }
 
 // creates 16 28-bit blocks rotated according
-// to the rotation schedule
+// to the rotation schedule.
 func ksRotate(in uint32) (out []uint32) {
 	out = make([]uint32, 16)
 	last := in
@@ -223,7 +223,7 @@
 	return
 }
 
-// creates 16 56-bit subkeys from the original key
+// creates 16 56-bit subkeys from the original key.
 func (c *desCipher) generateSubkeys(keyBytes []byte) {
 	feistelBoxOnce.Do(initFeistelBox)
 
diff --git a/src/crypto/des/cipher.go b/src/crypto/des/cipher.go
index 9e6779c..ece764f 100644
--- a/src/crypto/des/cipher.go
+++ b/src/crypto/des/cipher.go
@@ -6,7 +6,7 @@
 
 import (
 	"crypto/cipher"
-	"crypto/internal/subtle"
+	"crypto/internal/alias"
 	"encoding/binary"
 	"strconv"
 )
@@ -45,7 +45,7 @@
 	if len(dst) < BlockSize {
 		panic("crypto/des: output not full block")
 	}
-	if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
+	if alias.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
 		panic("crypto/des: invalid buffer overlap")
 	}
 	encryptBlock(c.subkeys[:], dst, src)
@@ -58,7 +58,7 @@
 	if len(dst) < BlockSize {
 		panic("crypto/des: output not full block")
 	}
-	if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
+	if alias.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
 		panic("crypto/des: invalid buffer overlap")
 	}
 	decryptBlock(c.subkeys[:], dst, src)
@@ -91,7 +91,7 @@
 	if len(dst) < BlockSize {
 		panic("crypto/des: output not full block")
 	}
-	if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
+	if alias.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
 		panic("crypto/des: invalid buffer overlap")
 	}
 
@@ -126,7 +126,7 @@
 	if len(dst) < BlockSize {
 		panic("crypto/des: output not full block")
 	}
-	if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
+	if alias.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
 		panic("crypto/des: invalid buffer overlap")
 	}
 
diff --git a/src/crypto/ecdh/ecdh.go b/src/crypto/ecdh/ecdh.go
new file mode 100644
index 0000000..7442055
--- /dev/null
+++ b/src/crypto/ecdh/ecdh.go
@@ -0,0 +1,184 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package ecdh implements Elliptic Curve Diffie-Hellman over
+// NIST curves and Curve25519.
+package ecdh
+
+import (
+	"crypto"
+	"crypto/internal/boring"
+	"crypto/subtle"
+	"errors"
+	"io"
+	"sync"
+)
+
+type Curve interface {
+	// GenerateKey generates a new PrivateKey from rand.
+	GenerateKey(rand io.Reader) (*PrivateKey, error)
+
+	// NewPrivateKey checks that key is valid and returns a PrivateKey.
+	//
+	// For NIST curves, this follows SEC 1, Version 2.0, Section 2.3.6, which
+	// amounts to decoding the bytes as a fixed length big endian integer and
+	// checking that the result is lower than the order of the curve. The zero
+	// private key is also rejected, as the encoding of the corresponding public
+	// key would be irregular.
+	//
+	// For X25519, this only checks the scalar length.
+	NewPrivateKey(key []byte) (*PrivateKey, error)
+
+	// NewPublicKey checks that key is valid and returns a PublicKey.
+	//
+	// For NIST curves, this decodes an uncompressed point according to SEC 1,
+	// Version 2.0, Section 2.3.4. Compressed encodings and the point at
+	// infinity are rejected.
+	//
+	// For X25519, this only checks the u-coordinate length. Adversarially
+	// selected public keys can cause ECDH to return an error.
+	NewPublicKey(key []byte) (*PublicKey, error)
+
+	// ecdh performs a ECDH exchange and returns the shared secret. It's exposed
+	// as the PrivateKey.ECDH method.
+	//
+	// The private method also allow us to expand the ECDH interface with more
+	// methods in the future without breaking backwards compatibility.
+	ecdh(local *PrivateKey, remote *PublicKey) ([]byte, error)
+
+	// privateKeyToPublicKey converts a PrivateKey to a PublicKey. It's exposed
+	// as the PrivateKey.PublicKey method.
+	//
+	// This method always succeeds: for X25519, the zero key can't be
+	// constructed due to clamping; for NIST curves, it is rejected by
+	// NewPrivateKey.
+	privateKeyToPublicKey(*PrivateKey) *PublicKey
+}
+
+// PublicKey is an ECDH public key, usually a peer's ECDH share sent over the wire.
+//
+// These keys can be parsed with [crypto/x509.ParsePKIXPublicKey] and encoded
+// with [crypto/x509.MarshalPKIXPublicKey]. For NIST curves, they then need to
+// be converted with [crypto/ecdsa.PublicKey.ECDH] after parsing.
+type PublicKey struct {
+	curve     Curve
+	publicKey []byte
+	boring    *boring.PublicKeyECDH
+}
+
+// Bytes returns a copy of the encoding of the public key.
+func (k *PublicKey) Bytes() []byte {
+	// Copy the public key to a fixed size buffer that can get allocated on the
+	// caller's stack after inlining.
+	var buf [133]byte
+	return append(buf[:0], k.publicKey...)
+}
+
+// Equal returns whether x represents the same public key as k.
+//
+// Note that there can be equivalent public keys with different encodings which
+// would return false from this check but behave the same way as inputs to ECDH.
+//
+// This check is performed in constant time as long as the key types and their
+// curve match.
+func (k *PublicKey) Equal(x crypto.PublicKey) bool {
+	xx, ok := x.(*PublicKey)
+	if !ok {
+		return false
+	}
+	return k.curve == xx.curve &&
+		subtle.ConstantTimeCompare(k.publicKey, xx.publicKey) == 1
+}
+
+func (k *PublicKey) Curve() Curve {
+	return k.curve
+}
+
+// PrivateKey is an ECDH private key, usually kept secret.
+//
+// These keys can be parsed with [crypto/x509.ParsePKCS8PrivateKey] and encoded
+// with [crypto/x509.MarshalPKCS8PrivateKey]. For NIST curves, they then need to
+// be converted with [crypto/ecdsa.PrivateKey.ECDH] after parsing.
+type PrivateKey struct {
+	curve      Curve
+	privateKey []byte
+	boring     *boring.PrivateKeyECDH
+	// publicKey is set under publicKeyOnce, to allow loading private keys with
+	// NewPrivateKey without having to perform a scalar multiplication.
+	publicKey     *PublicKey
+	publicKeyOnce sync.Once
+}
+
+// ECDH performs a ECDH exchange and returns the shared secret. The PrivateKey
+// and PublicKey must use the same curve.
+//
+// For NIST curves, this performs ECDH as specified in SEC 1, Version 2.0,
+// Section 3.3.1, and returns the x-coordinate encoded according to SEC 1,
+// Version 2.0, Section 2.3.5. The result is never the point at infinity.
+//
+// For X25519, this performs ECDH as specified in RFC 7748, Section 6.1. If
+// the result is the all-zero value, ECDH returns an error.
+func (k *PrivateKey) ECDH(remote *PublicKey) ([]byte, error) {
+	if k.curve != remote.curve {
+		return nil, errors.New("crypto/ecdh: private key and public key curves do not match")
+	}
+	return k.curve.ecdh(k, remote)
+}
+
+// Bytes returns a copy of the encoding of the private key.
+func (k *PrivateKey) Bytes() []byte {
+	// Copy the private key to a fixed size buffer that can get allocated on the
+	// caller's stack after inlining.
+	var buf [66]byte
+	return append(buf[:0], k.privateKey...)
+}
+
+// Equal returns whether x represents the same private key as k.
+//
+// Note that there can be equivalent private keys with different encodings which
+// would return false from this check but behave the same way as inputs to ECDH.
+//
+// This check is performed in constant time as long as the key types and their
+// curve match.
+func (k *PrivateKey) Equal(x crypto.PrivateKey) bool {
+	xx, ok := x.(*PrivateKey)
+	if !ok {
+		return false
+	}
+	return k.curve == xx.curve &&
+		subtle.ConstantTimeCompare(k.privateKey, xx.privateKey) == 1
+}
+
+func (k *PrivateKey) Curve() Curve {
+	return k.curve
+}
+
+func (k *PrivateKey) PublicKey() *PublicKey {
+	k.publicKeyOnce.Do(func() {
+		if k.boring != nil {
+			// Because we already checked in NewPrivateKey that the key is valid,
+			// there should not be any possible errors from BoringCrypto,
+			// so we turn the error into a panic.
+			// (We can't return it anyhow.)
+			kpub, err := k.boring.PublicKey()
+			if err != nil {
+				panic("boringcrypto: " + err.Error())
+			}
+			k.publicKey = &PublicKey{
+				curve:     k.curve,
+				publicKey: kpub.Bytes(),
+				boring:    kpub,
+			}
+		} else {
+			k.publicKey = k.curve.privateKeyToPublicKey(k)
+		}
+	})
+	return k.publicKey
+}
+
+// Public implements the implicit interface of all standard library private
+// keys. See the docs of crypto.PrivateKey.
+func (k *PrivateKey) Public() crypto.PublicKey {
+	return k.PublicKey()
+}
diff --git a/src/crypto/ecdh/ecdh_test.go b/src/crypto/ecdh/ecdh_test.go
new file mode 100644
index 0000000..10da95a
--- /dev/null
+++ b/src/crypto/ecdh/ecdh_test.go
@@ -0,0 +1,525 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ecdh_test
+
+import (
+	"bytes"
+	"crypto"
+	"crypto/cipher"
+	"crypto/ecdh"
+	"crypto/rand"
+	"crypto/sha256"
+	"encoding/hex"
+	"fmt"
+	"internal/testenv"
+	"io"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"regexp"
+	"strings"
+	"testing"
+
+	"golang.org/x/crypto/chacha20"
+)
+
+// Check that PublicKey and PrivateKey implement the interfaces documented in
+// crypto.PublicKey and crypto.PrivateKey.
+var _ interface {
+	Equal(x crypto.PublicKey) bool
+} = &ecdh.PublicKey{}
+var _ interface {
+	Public() crypto.PublicKey
+	Equal(x crypto.PrivateKey) bool
+} = &ecdh.PrivateKey{}
+
+func TestECDH(t *testing.T) {
+	testAllCurves(t, func(t *testing.T, curve ecdh.Curve) {
+		aliceKey, err := curve.GenerateKey(rand.Reader)
+		if err != nil {
+			t.Fatal(err)
+		}
+		bobKey, err := curve.GenerateKey(rand.Reader)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		alicePubKey, err := curve.NewPublicKey(aliceKey.PublicKey().Bytes())
+		if err != nil {
+			t.Error(err)
+		}
+		if !bytes.Equal(aliceKey.PublicKey().Bytes(), alicePubKey.Bytes()) {
+			t.Error("encoded and decoded public keys are different")
+		}
+		if !aliceKey.PublicKey().Equal(alicePubKey) {
+			t.Error("encoded and decoded public keys are different")
+		}
+
+		alicePrivKey, err := curve.NewPrivateKey(aliceKey.Bytes())
+		if err != nil {
+			t.Error(err)
+		}
+		if !bytes.Equal(aliceKey.Bytes(), alicePrivKey.Bytes()) {
+			t.Error("encoded and decoded private keys are different")
+		}
+		if !aliceKey.Equal(alicePrivKey) {
+			t.Error("encoded and decoded private keys are different")
+		}
+
+		bobSecret, err := bobKey.ECDH(aliceKey.PublicKey())
+		if err != nil {
+			t.Fatal(err)
+		}
+		aliceSecret, err := aliceKey.ECDH(bobKey.PublicKey())
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		if !bytes.Equal(bobSecret, aliceSecret) {
+			t.Error("two ECDH computations came out different")
+		}
+	})
+}
+
+type countingReader struct {
+	r io.Reader
+	n int
+}
+
+func (r *countingReader) Read(p []byte) (int, error) {
+	n, err := r.r.Read(p)
+	r.n += n
+	return n, err
+}
+
+func TestGenerateKey(t *testing.T) {
+	testAllCurves(t, func(t *testing.T, curve ecdh.Curve) {
+		r := &countingReader{r: rand.Reader}
+		k, err := curve.GenerateKey(r)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		// GenerateKey does rejection sampling. If the masking works correctly,
+		// the probability of a rejection is 1-ord(G)/2^ceil(log2(ord(G))),
+		// which for all curves is small enough (at most 2^-32, for P-256) that
+		// a bit flip is more likely to make this test fail than bad luck.
+		// Account for the extra MaybeReadByte byte, too.
+		if got, expected := r.n, len(k.Bytes())+1; got > expected {
+			t.Errorf("expected GenerateKey to consume at most %v bytes, got %v", expected, got)
+		}
+	})
+}
+
+var vectors = map[ecdh.Curve]struct {
+	PrivateKey, PublicKey string
+	PeerPublicKey         string
+	SharedSecret          string
+}{
+	// NIST vectors from CAVS 14.1, ECC CDH Primitive (SP800-56A).
+	ecdh.P256(): {
+		PrivateKey: "7d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534",
+		PublicKey: "04ead218590119e8876b29146ff89ca61770c4edbbf97d38ce385ed281d8a6b230" +
+			"28af61281fd35e2fa7002523acc85a429cb06ee6648325389f59edfce1405141",
+		PeerPublicKey: "04700c48f77f56584c5cc632ca65640db91b6bacce3a4df6b42ce7cc838833d287" +
+			"db71e509e3fd9b060ddb20ba5c51dcc5948d46fbf640dfe0441782cab85fa4ac",
+		SharedSecret: "46fc62106420ff012e54a434fbdd2d25ccc5852060561e68040dd7778997bd7b",
+	},
+	ecdh.P384(): {
+		PrivateKey: "3cc3122a68f0d95027ad38c067916ba0eb8c38894d22e1b15618b6818a661774ad463b205da88cf699ab4d43c9cf98a1",
+		PublicKey: "049803807f2f6d2fd966cdd0290bd410c0190352fbec7ff6247de1302df86f25d34fe4a97bef60cff548355c015dbb3e5f" +
+			"ba26ca69ec2f5b5d9dad20cc9da711383a9dbe34ea3fa5a2af75b46502629ad54dd8b7d73a8abb06a3a3be47d650cc99",
+		PeerPublicKey: "04a7c76b970c3b5fe8b05d2838ae04ab47697b9eaf52e764592efda27fe7513272734466b400091adbf2d68c58e0c50066" +
+			"ac68f19f2e1cb879aed43a9969b91a0839c4c38a49749b661efedf243451915ed0905a32b060992b468c64766fc8437a",
+		SharedSecret: "5f9d29dc5e31a163060356213669c8ce132e22f57c9a04f40ba7fcead493b457e5621e766c40a2e3d4d6a04b25e533f1",
+	},
+	// For some reason all field elements in the test vector (both scalars and
+	// base field elements), but not the shared secret output, have two extra
+	// leading zero bytes (which in big-endian are irrelevant). Removed here.
+	ecdh.P521(): {
+		PrivateKey: "017eecc07ab4b329068fba65e56a1f8890aa935e57134ae0ffcce802735151f4eac6564f6ee9974c5e6887a1fefee5743ae2241bfeb95d5ce31ddcb6f9edb4d6fc47",
+		PublicKey: "0400602f9d0cf9e526b29e22381c203c48a886c2b0673033366314f1ffbcba240ba42f4ef38a76174635f91e6b4ed34275eb01c8467d05ca80315bf1a7bbd945f550a5" +
+			"01b7c85f26f5d4b2d7355cf6b02117659943762b6d1db5ab4f1dbc44ce7b2946eb6c7de342962893fd387d1b73d7a8672d1f236961170b7eb3579953ee5cdc88cd2d",
+		PeerPublicKey: "0400685a48e86c79f0f0875f7bc18d25eb5fc8c0b07e5da4f4370f3a9490340854334b1e1b87fa395464c60626124a4e70d0f785601d37c09870ebf176666877a2046d" +
+			"01ba52c56fc8776d9e8f5db4f0cc27636d0b741bbe05400697942e80b739884a83bde99e0f6716939e632bc8986fa18dccd443a348b6c3e522497955a4f3c302f676",
+		SharedSecret: "005fc70477c3e63bc3954bd0df3ea0d1f41ee21746ed95fc5e1fdf90930d5e136672d72cc770742d1711c3c3a4c334a0ad9759436a4d3c5bf6e74b9578fac148c831",
+	},
+	// X25519 test vector from RFC 7748, Section 6.1.
+	ecdh.X25519(): {
+		PrivateKey:    "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a",
+		PublicKey:     "8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a",
+		PeerPublicKey: "de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f",
+		SharedSecret:  "4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742",
+	},
+}
+
+func TestVectors(t *testing.T) {
+	testAllCurves(t, func(t *testing.T, curve ecdh.Curve) {
+		v := vectors[curve]
+		key, err := curve.NewPrivateKey(hexDecode(t, v.PrivateKey))
+		if err != nil {
+			t.Fatal(err)
+		}
+		if !bytes.Equal(key.PublicKey().Bytes(), hexDecode(t, v.PublicKey)) {
+			t.Error("public key derived from the private key does not match")
+		}
+		peer, err := curve.NewPublicKey(hexDecode(t, v.PeerPublicKey))
+		if err != nil {
+			t.Fatal(err)
+		}
+		secret, err := key.ECDH(peer)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if !bytes.Equal(secret, hexDecode(t, v.SharedSecret)) {
+			t.Errorf("shared secret does not match: %x %x %s %x", secret, sha256.Sum256(secret), v.SharedSecret,
+				sha256.Sum256(hexDecode(t, v.SharedSecret)))
+		}
+	})
+}
+
+func hexDecode(t *testing.T, s string) []byte {
+	b, err := hex.DecodeString(s)
+	if err != nil {
+		t.Fatal("invalid hex string:", s)
+	}
+	return b
+}
+
+func TestString(t *testing.T) {
+	testAllCurves(t, func(t *testing.T, curve ecdh.Curve) {
+		s := fmt.Sprintf("%s", curve)
+		if s[:1] != "P" && s[:1] != "X" {
+			t.Errorf("unexpected Curve string encoding: %q", s)
+		}
+	})
+}
+
+func TestX25519Failure(t *testing.T) {
+	identity := hexDecode(t, "0000000000000000000000000000000000000000000000000000000000000000")
+	lowOrderPoint := hexDecode(t, "e0eb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b800")
+	randomScalar := make([]byte, 32)
+	rand.Read(randomScalar)
+
+	t.Run("identity point", func(t *testing.T) { testX25519Failure(t, randomScalar, identity) })
+	t.Run("low order point", func(t *testing.T) { testX25519Failure(t, randomScalar, lowOrderPoint) })
+}
+
+func testX25519Failure(t *testing.T, private, public []byte) {
+	priv, err := ecdh.X25519().NewPrivateKey(private)
+	if err != nil {
+		t.Fatal(err)
+	}
+	pub, err := ecdh.X25519().NewPublicKey(public)
+	if err != nil {
+		t.Fatal(err)
+	}
+	secret, err := priv.ECDH(pub)
+	if err == nil {
+		t.Error("expected ECDH error")
+	}
+	if secret != nil {
+		t.Errorf("unexpected ECDH output: %x", secret)
+	}
+}
+
+var invalidPrivateKeys = map[ecdh.Curve][]string{
+	ecdh.P256(): {
+		// Bad lengths.
+		"",
+		"01",
+		"01010101010101010101010101010101010101010101010101010101010101",
+		"000101010101010101010101010101010101010101010101010101010101010101",
+		strings.Repeat("01", 200),
+		// Zero.
+		"0000000000000000000000000000000000000000000000000000000000000000",
+		// Order of the curve and above.
+		"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
+		"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552",
+		"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+	},
+	ecdh.P384(): {
+		// Bad lengths.
+		"",
+		"01",
+		"0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101",
+		"00010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101",
+		strings.Repeat("01", 200),
+		// Zero.
+		"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+		// Order of the curve and above.
+		"ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973",
+		"ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52974",
+		"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+	},
+	ecdh.P521(): {
+		// Bad lengths.
+		"",
+		"01",
+		"0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101",
+		"00010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101",
+		strings.Repeat("01", 200),
+		// Zero.
+		"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+		// Order of the curve and above.
+		"01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
+		"01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e9138640a",
+		"11fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
+		"03fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4a30d0f077e5f2cd6ff980291ee134ba0776b937113388f5d76df6e3d2270c812",
+	},
+	ecdh.X25519(): {
+		// X25519 only rejects bad lengths.
+		"",
+		"01",
+		"01010101010101010101010101010101010101010101010101010101010101",
+		"000101010101010101010101010101010101010101010101010101010101010101",
+		strings.Repeat("01", 200),
+	},
+}
+
+func TestNewPrivateKey(t *testing.T) {
+	testAllCurves(t, func(t *testing.T, curve ecdh.Curve) {
+		for _, input := range invalidPrivateKeys[curve] {
+			k, err := curve.NewPrivateKey(hexDecode(t, input))
+			if err == nil {
+				t.Errorf("unexpectedly accepted %q", input)
+			} else if k != nil {
+				t.Error("PrivateKey was not nil on error")
+			} else if strings.Contains(err.Error(), "boringcrypto") {
+				t.Errorf("boringcrypto error leaked out: %v", err)
+			}
+		}
+	})
+}
+
+var invalidPublicKeys = map[ecdh.Curve][]string{
+	ecdh.P256(): {
+		// Bad lengths.
+		"",
+		"04",
+		strings.Repeat("04", 200),
+		// Infinity.
+		"00",
+		// Compressed encodings.
+		"036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
+		"02e2534a3532d08fbba02dde659ee62bd0031fe2db785596ef509302446b030852",
+		// Points not on the curve.
+		"046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f6",
+		"0400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+	},
+	ecdh.P384(): {
+		// Bad lengths.
+		"",
+		"04",
+		strings.Repeat("04", 200),
+		// Infinity.
+		"00",
+		// Compressed encodings.
+		"03aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7",
+		"0208d999057ba3d2d969260045c55b97f089025959a6f434d651d207d19fb96e9e4fe0e86ebe0e64f85b96a9c75295df61",
+		// Points not on the curve.
+		"04aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab73617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e60",
+		"04000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+	},
+	ecdh.P521(): {
+		// Bad lengths.
+		"",
+		"04",
+		strings.Repeat("04", 200),
+		// Infinity.
+		"00",
+		// Compressed encodings.
+		"030035b5df64ae2ac204c354b483487c9070cdc61c891c5ff39afc06c5d55541d3ceac8659e24afe3d0750e8b88e9f078af066a1d5025b08e5a5e2fbc87412871902f3",
+		"0200c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
+		// Points not on the curve.
+		"0400c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16651",
+		"04000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+	},
+	ecdh.X25519(): {},
+}
+
+func TestNewPublicKey(t *testing.T) {
+	testAllCurves(t, func(t *testing.T, curve ecdh.Curve) {
+		for _, input := range invalidPublicKeys[curve] {
+			k, err := curve.NewPublicKey(hexDecode(t, input))
+			if err == nil {
+				t.Errorf("unexpectedly accepted %q", input)
+			} else if k != nil {
+				t.Error("PublicKey was not nil on error")
+			} else if strings.Contains(err.Error(), "boringcrypto") {
+				t.Errorf("boringcrypto error leaked out: %v", err)
+			}
+		}
+	})
+}
+
+func testAllCurves(t *testing.T, f func(t *testing.T, curve ecdh.Curve)) {
+	t.Run("P256", func(t *testing.T) { f(t, ecdh.P256()) })
+	t.Run("P384", func(t *testing.T) { f(t, ecdh.P384()) })
+	t.Run("P521", func(t *testing.T) { f(t, ecdh.P521()) })
+	t.Run("X25519", func(t *testing.T) { f(t, ecdh.X25519()) })
+}
+
+func BenchmarkECDH(b *testing.B) {
+	benchmarkAllCurves(b, func(b *testing.B, curve ecdh.Curve) {
+		c, err := chacha20.NewUnauthenticatedCipher(make([]byte, 32), make([]byte, 12))
+		if err != nil {
+			b.Fatal(err)
+		}
+		rand := cipher.StreamReader{
+			S: c, R: zeroReader,
+		}
+
+		peerKey, err := curve.GenerateKey(rand)
+		if err != nil {
+			b.Fatal(err)
+		}
+		peerShare := peerKey.PublicKey().Bytes()
+		b.ResetTimer()
+		b.ReportAllocs()
+
+		var allocationsSink byte
+
+		for i := 0; i < b.N; i++ {
+			key, err := curve.GenerateKey(rand)
+			if err != nil {
+				b.Fatal(err)
+			}
+			share := key.PublicKey().Bytes()
+			peerPubKey, err := curve.NewPublicKey(peerShare)
+			if err != nil {
+				b.Fatal(err)
+			}
+			secret, err := key.ECDH(peerPubKey)
+			if err != nil {
+				b.Fatal(err)
+			}
+			allocationsSink ^= secret[0] ^ share[0]
+		}
+	})
+}
+
+func benchmarkAllCurves(b *testing.B, f func(b *testing.B, curve ecdh.Curve)) {
+	b.Run("P256", func(b *testing.B) { f(b, ecdh.P256()) })
+	b.Run("P384", func(b *testing.B) { f(b, ecdh.P384()) })
+	b.Run("P521", func(b *testing.B) { f(b, ecdh.P521()) })
+	b.Run("X25519", func(b *testing.B) { f(b, ecdh.X25519()) })
+}
+
+type zr struct{}
+
+// Read replaces the contents of dst with zeros. It is safe for concurrent use.
+func (zr) Read(dst []byte) (n int, err error) {
+	for i := range dst {
+		dst[i] = 0
+	}
+	return len(dst), nil
+}
+
+var zeroReader = zr{}
+
+const linkerTestProgram = `
+package main
+import "crypto/ecdh"
+import "crypto/rand"
+func main() {
+	curve := ecdh.P384()
+	key, err := curve.GenerateKey(rand.Reader)
+	if err != nil { panic(err) }
+	_, err = curve.NewPublicKey(key.PublicKey().Bytes())
+	if err != nil { panic(err) }
+	_, err = curve.NewPrivateKey(key.Bytes())
+	if err != nil { panic(err) }
+	_, err = key.ECDH(key.PublicKey())
+	if err != nil { panic(err) }
+	println("OK")
+}
+`
+
+// TestLinker ensures that using one curve does not bring all other
+// implementations into the binary. This also guarantees that govulncheck can
+// avoid warning about a curve-specific vulnerability if that curve is not used.
+func TestLinker(t *testing.T) {
+	if testing.Short() {
+		t.Skip("test requires running 'go build'")
+	}
+	testenv.MustHaveGoBuild(t)
+
+	dir := t.TempDir()
+	hello := filepath.Join(dir, "hello.go")
+	err := os.WriteFile(hello, []byte(linkerTestProgram), 0664)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	run := func(args ...string) string {
+		cmd := exec.Command(args[0], args[1:]...)
+		cmd.Dir = dir
+		out, err := cmd.CombinedOutput()
+		if err != nil {
+			t.Fatalf("%v: %v\n%s", args, err, string(out))
+		}
+		return string(out)
+	}
+
+	goBin := testenv.GoToolPath(t)
+	run(goBin, "build", "-o", "hello.exe", "hello.go")
+	if out := run("./hello.exe"); out != "OK\n" {
+		t.Error("unexpected output:", out)
+	}
+
+	// List all text symbols under crypto/... and make sure there are some for
+	// P384, but none for the other curves.
+	var consistent bool
+	nm := run(goBin, "tool", "nm", "hello.exe")
+	for _, match := range regexp.MustCompile(`(?m)T (crypto/.*)$`).FindAllStringSubmatch(nm, -1) {
+		symbol := strings.ToLower(match[1])
+		if strings.Contains(symbol, "p384") {
+			consistent = true
+		}
+		if strings.Contains(symbol, "p224") || strings.Contains(symbol, "p256") || strings.Contains(symbol, "p521") {
+			t.Errorf("unexpected symbol in program using only ecdh.P384: %s", match[1])
+		}
+	}
+	if !consistent {
+		t.Error("no P384 symbols found in program using ecdh.P384, test is broken")
+	}
+}
+
+func TestMismatchedCurves(t *testing.T) {
+	curves := []struct {
+		name  string
+		curve ecdh.Curve
+	}{
+		{"P256", ecdh.P256()},
+		{"P384", ecdh.P384()},
+		{"P521", ecdh.P521()},
+		{"X25519", ecdh.X25519()},
+	}
+
+	for _, privCurve := range curves {
+		priv, err := privCurve.curve.GenerateKey(rand.Reader)
+		if err != nil {
+			t.Fatalf("failed to generate test key: %s", err)
+		}
+
+		for _, pubCurve := range curves {
+			if privCurve == pubCurve {
+				continue
+			}
+			t.Run(fmt.Sprintf("%s/%s", privCurve.name, pubCurve.name), func(t *testing.T) {
+				pub, err := pubCurve.curve.GenerateKey(rand.Reader)
+				if err != nil {
+					t.Fatalf("failed to generate test key: %s", err)
+				}
+				expected := "crypto/ecdh: private key and public key curves do not match"
+				_, err = priv.ECDH(pub.PublicKey())
+				if err.Error() != expected {
+					t.Fatalf("unexpected error: want %q, got %q", expected, err)
+				}
+			})
+		}
+	}
+}
diff --git a/src/crypto/ecdh/nist.go b/src/crypto/ecdh/nist.go
new file mode 100644
index 0000000..01354fa
--- /dev/null
+++ b/src/crypto/ecdh/nist.go
@@ -0,0 +1,275 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ecdh
+
+import (
+	"crypto/internal/boring"
+	"crypto/internal/nistec"
+	"crypto/internal/randutil"
+	"encoding/binary"
+	"errors"
+	"io"
+	"math/bits"
+)
+
+type nistCurve[Point nistPoint[Point]] struct {
+	name        string
+	newPoint    func() Point
+	scalarOrder []byte
+}
+
+// nistPoint is a generic constraint for the nistec Point types.
+type nistPoint[T any] interface {
+	Bytes() []byte
+	BytesX() ([]byte, error)
+	SetBytes([]byte) (T, error)
+	ScalarMult(T, []byte) (T, error)
+	ScalarBaseMult([]byte) (T, error)
+}
+
+func (c *nistCurve[Point]) String() string {
+	return c.name
+}
+
+var errInvalidPrivateKey = errors.New("crypto/ecdh: invalid private key")
+
+func (c *nistCurve[Point]) GenerateKey(rand io.Reader) (*PrivateKey, error) {
+	if boring.Enabled && rand == boring.RandReader {
+		key, bytes, err := boring.GenerateKeyECDH(c.name)
+		if err != nil {
+			return nil, err
+		}
+		return newBoringPrivateKey(c, key, bytes)
+	}
+
+	key := make([]byte, len(c.scalarOrder))
+	randutil.MaybeReadByte(rand)
+	for {
+		if _, err := io.ReadFull(rand, key); err != nil {
+			return nil, err
+		}
+
+		// Mask off any excess bits if the size of the underlying field is not a
+		// whole number of bytes, which is only the case for P-521. We use a
+		// pointer to the scalarOrder field because comparing generic and
+		// instantiated types is not supported.
+		if &c.scalarOrder[0] == &p521Order[0] {
+			key[0] &= 0b0000_0001
+		}
+
+		// In tests, rand will return all zeros and NewPrivateKey will reject
+		// the zero key as it generates the identity as a public key. This also
+		// makes this function consistent with crypto/elliptic.GenerateKey.
+		key[1] ^= 0x42
+
+		k, err := c.NewPrivateKey(key)
+		if err == errInvalidPrivateKey {
+			continue
+		}
+		return k, err
+	}
+}
+
+func (c *nistCurve[Point]) NewPrivateKey(key []byte) (*PrivateKey, error) {
+	if len(key) != len(c.scalarOrder) {
+		return nil, errors.New("crypto/ecdh: invalid private key size")
+	}
+	if isZero(key) || !isLess(key, c.scalarOrder) {
+		return nil, errInvalidPrivateKey
+	}
+	if boring.Enabled {
+		bk, err := boring.NewPrivateKeyECDH(c.name, key)
+		if err != nil {
+			return nil, err
+		}
+		return newBoringPrivateKey(c, bk, key)
+	}
+	k := &PrivateKey{
+		curve:      c,
+		privateKey: append([]byte{}, key...),
+	}
+	return k, nil
+}
+
+func newBoringPrivateKey(c Curve, bk *boring.PrivateKeyECDH, privateKey []byte) (*PrivateKey, error) {
+	k := &PrivateKey{
+		curve:      c,
+		boring:     bk,
+		privateKey: append([]byte(nil), privateKey...),
+	}
+	return k, nil
+}
+
+func (c *nistCurve[Point]) privateKeyToPublicKey(key *PrivateKey) *PublicKey {
+	boring.Unreachable()
+	if key.curve != c {
+		panic("crypto/ecdh: internal error: converting the wrong key type")
+	}
+	p, err := c.newPoint().ScalarBaseMult(key.privateKey)
+	if err != nil {
+		// This is unreachable because the only error condition of
+		// ScalarBaseMult is if the input is not the right size.
+		panic("crypto/ecdh: internal error: nistec ScalarBaseMult failed for a fixed-size input")
+	}
+	publicKey := p.Bytes()
+	if len(publicKey) == 1 {
+		// The encoding of the identity is a single 0x00 byte. This is
+		// unreachable because the only scalar that generates the identity is
+		// zero, which is rejected by NewPrivateKey.
+		panic("crypto/ecdh: internal error: nistec ScalarBaseMult returned the identity")
+	}
+	return &PublicKey{
+		curve:     key.curve,
+		publicKey: publicKey,
+	}
+}
+
+// isZero returns whether a is all zeroes in constant time.
+func isZero(a []byte) bool {
+	var acc byte
+	for _, b := range a {
+		acc |= b
+	}
+	return acc == 0
+}
+
+// isLess returns whether a < b, where a and b are big-endian buffers of the
+// same length and shorter than 72 bytes.
+func isLess(a, b []byte) bool {
+	if len(a) != len(b) {
+		panic("crypto/ecdh: internal error: mismatched isLess inputs")
+	}
+
+	// Copy the values into a fixed-size preallocated little-endian buffer.
+	// 72 bytes is enough for every scalar in this package, and having a fixed
+	// size lets us avoid heap allocations.
+	if len(a) > 72 {
+		panic("crypto/ecdh: internal error: isLess input too large")
+	}
+	bufA, bufB := make([]byte, 72), make([]byte, 72)
+	for i := range a {
+		bufA[i], bufB[i] = a[len(a)-i-1], b[len(b)-i-1]
+	}
+
+	// Perform a subtraction with borrow.
+	var borrow uint64
+	for i := 0; i < len(bufA); i += 8 {
+		limbA, limbB := binary.LittleEndian.Uint64(bufA[i:]), binary.LittleEndian.Uint64(bufB[i:])
+		_, borrow = bits.Sub64(limbA, limbB, borrow)
+	}
+
+	// If there is a borrow at the end of the operation, then a < b.
+	return borrow == 1
+}
+
+func (c *nistCurve[Point]) NewPublicKey(key []byte) (*PublicKey, error) {
+	// Reject the point at infinity and compressed encodings.
+	if len(key) == 0 || key[0] != 4 {
+		return nil, errors.New("crypto/ecdh: invalid public key")
+	}
+	k := &PublicKey{
+		curve:     c,
+		publicKey: append([]byte{}, key...),
+	}
+	if boring.Enabled {
+		bk, err := boring.NewPublicKeyECDH(c.name, k.publicKey)
+		if err != nil {
+			return nil, err
+		}
+		k.boring = bk
+	} else {
+		// SetBytes also checks that the point is on the curve.
+		if _, err := c.newPoint().SetBytes(key); err != nil {
+			return nil, err
+		}
+	}
+	return k, nil
+}
+
+func (c *nistCurve[Point]) ecdh(local *PrivateKey, remote *PublicKey) ([]byte, error) {
+	// Note that this function can't return an error, as NewPublicKey rejects
+	// invalid points and the point at infinity, and NewPrivateKey rejects
+	// invalid scalars and the zero value. BytesX returns an error for the point
+	// at infinity, but in a prime order group such as the NIST curves that can
+	// only be the result of a scalar multiplication if one of the inputs is the
+	// zero scalar or the point at infinity.
+
+	if boring.Enabled {
+		return boring.ECDH(local.boring, remote.boring)
+	}
+
+	boring.Unreachable()
+	p, err := c.newPoint().SetBytes(remote.publicKey)
+	if err != nil {
+		return nil, err
+	}
+	if _, err := p.ScalarMult(p, local.privateKey); err != nil {
+		return nil, err
+	}
+	return p.BytesX()
+}
+
+// P256 returns a Curve which implements NIST P-256 (FIPS 186-3, section D.2.3),
+// also known as secp256r1 or prime256v1.
+//
+// Multiple invocations of this function will return the same value, which can
+// be used for equality checks and switch statements.
+func P256() Curve { return p256 }
+
+var p256 = &nistCurve[*nistec.P256Point]{
+	name:        "P-256",
+	newPoint:    nistec.NewP256Point,
+	scalarOrder: p256Order,
+}
+
+var p256Order = []byte{
+	0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xbc, 0xe6, 0xfa, 0xad, 0xa7, 0x17, 0x9e, 0x84,
+	0xf3, 0xb9, 0xca, 0xc2, 0xfc, 0x63, 0x25, 0x51}
+
+// P384 returns a Curve which implements NIST P-384 (FIPS 186-3, section D.2.4),
+// also known as secp384r1.
+//
+// Multiple invocations of this function will return the same value, which can
+// be used for equality checks and switch statements.
+func P384() Curve { return p384 }
+
+var p384 = &nistCurve[*nistec.P384Point]{
+	name:        "P-384",
+	newPoint:    nistec.NewP384Point,
+	scalarOrder: p384Order,
+}
+
+var p384Order = []byte{
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xc7, 0x63, 0x4d, 0x81, 0xf4, 0x37, 0x2d, 0xdf,
+	0x58, 0x1a, 0x0d, 0xb2, 0x48, 0xb0, 0xa7, 0x7a,
+	0xec, 0xec, 0x19, 0x6a, 0xcc, 0xc5, 0x29, 0x73}
+
+// P521 returns a Curve which implements NIST P-521 (FIPS 186-3, section D.2.5),
+// also known as secp521r1.
+//
+// Multiple invocations of this function will return the same value, which can
+// be used for equality checks and switch statements.
+func P521() Curve { return p521 }
+
+var p521 = &nistCurve[*nistec.P521Point]{
+	name:        "P-521",
+	newPoint:    nistec.NewP521Point,
+	scalarOrder: p521Order,
+}
+
+var p521Order = []byte{0x01, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa,
+	0x51, 0x86, 0x87, 0x83, 0xbf, 0x2f, 0x96, 0x6b,
+	0x7f, 0xcc, 0x01, 0x48, 0xf7, 0x09, 0xa5, 0xd0,
+	0x3b, 0xb5, 0xc9, 0xb8, 0x89, 0x9c, 0x47, 0xae,
+	0xbb, 0x6f, 0xb7, 0x1e, 0x91, 0x38, 0x64, 0x09}
diff --git a/src/crypto/ecdh/x25519.go b/src/crypto/ecdh/x25519.go
new file mode 100644
index 0000000..dbc3ea9
--- /dev/null
+++ b/src/crypto/ecdh/x25519.go
@@ -0,0 +1,136 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ecdh
+
+import (
+	"crypto/internal/edwards25519/field"
+	"crypto/internal/randutil"
+	"errors"
+	"io"
+)
+
+var (
+	x25519PublicKeySize    = 32
+	x25519PrivateKeySize   = 32
+	x25519SharedSecretSize = 32
+)
+
+// X25519 returns a Curve which implements the X25519 function over Curve25519
+// (RFC 7748, Section 5).
+//
+// Multiple invocations of this function will return the same value, so it can
+// be used for equality checks and switch statements.
+func X25519() Curve { return x25519 }
+
+var x25519 = &x25519Curve{}
+
+type x25519Curve struct{}
+
+func (c *x25519Curve) String() string {
+	return "X25519"
+}
+
+func (c *x25519Curve) GenerateKey(rand io.Reader) (*PrivateKey, error) {
+	key := make([]byte, x25519PrivateKeySize)
+	randutil.MaybeReadByte(rand)
+	if _, err := io.ReadFull(rand, key); err != nil {
+		return nil, err
+	}
+	return c.NewPrivateKey(key)
+}
+
+func (c *x25519Curve) NewPrivateKey(key []byte) (*PrivateKey, error) {
+	if len(key) != x25519PrivateKeySize {
+		return nil, errors.New("crypto/ecdh: invalid private key size")
+	}
+	return &PrivateKey{
+		curve:      c,
+		privateKey: append([]byte{}, key...),
+	}, nil
+}
+
+func (c *x25519Curve) privateKeyToPublicKey(key *PrivateKey) *PublicKey {
+	if key.curve != c {
+		panic("crypto/ecdh: internal error: converting the wrong key type")
+	}
+	k := &PublicKey{
+		curve:     key.curve,
+		publicKey: make([]byte, x25519PublicKeySize),
+	}
+	x25519Basepoint := [32]byte{9}
+	x25519ScalarMult(k.publicKey, key.privateKey, x25519Basepoint[:])
+	return k
+}
+
+func (c *x25519Curve) NewPublicKey(key []byte) (*PublicKey, error) {
+	if len(key) != x25519PublicKeySize {
+		return nil, errors.New("crypto/ecdh: invalid public key")
+	}
+	return &PublicKey{
+		curve:     c,
+		publicKey: append([]byte{}, key...),
+	}, nil
+}
+
+func (c *x25519Curve) ecdh(local *PrivateKey, remote *PublicKey) ([]byte, error) {
+	out := make([]byte, x25519SharedSecretSize)
+	x25519ScalarMult(out, local.privateKey, remote.publicKey)
+	if isZero(out) {
+		return nil, errors.New("crypto/ecdh: bad X25519 remote ECDH input: low order point")
+	}
+	return out, nil
+}
+
+func x25519ScalarMult(dst, scalar, point []byte) {
+	var e [32]byte
+
+	copy(e[:], scalar[:])
+	e[0] &= 248
+	e[31] &= 127
+	e[31] |= 64
+
+	var x1, x2, z2, x3, z3, tmp0, tmp1 field.Element
+	x1.SetBytes(point[:])
+	x2.One()
+	x3.Set(&x1)
+	z3.One()
+
+	swap := 0
+	for pos := 254; pos >= 0; pos-- {
+		b := e[pos/8] >> uint(pos&7)
+		b &= 1
+		swap ^= int(b)
+		x2.Swap(&x3, swap)
+		z2.Swap(&z3, swap)
+		swap = int(b)
+
+		tmp0.Subtract(&x3, &z3)
+		tmp1.Subtract(&x2, &z2)
+		x2.Add(&x2, &z2)
+		z2.Add(&x3, &z3)
+		z3.Multiply(&tmp0, &x2)
+		z2.Multiply(&z2, &tmp1)
+		tmp0.Square(&tmp1)
+		tmp1.Square(&x2)
+		x3.Add(&z3, &z2)
+		z2.Subtract(&z3, &z2)
+		x2.Multiply(&tmp1, &tmp0)
+		tmp1.Subtract(&tmp1, &tmp0)
+		z2.Square(&z2)
+
+		z3.Mult32(&tmp1, 121666)
+		x3.Square(&x3)
+		tmp0.Add(&tmp0, &z3)
+		z3.Multiply(&x1, &z2)
+		z2.Multiply(&tmp1, &tmp0)
+	}
+
+	x2.Swap(&x3, swap)
+	z2.Swap(&z3, swap)
+
+	z2.Invert(&z2)
+	x2.Multiply(&x2, &z2)
+	copy(dst[:], x2.Bytes())
+}
diff --git a/src/crypto/ecdsa/boring.go b/src/crypto/ecdsa/boring.go
index 4495730..275c60b 100644
--- a/src/crypto/ecdsa/boring.go
+++ b/src/crypto/ecdsa/boring.go
@@ -11,7 +11,6 @@
 	"crypto/internal/boring/bbig"
 	"crypto/internal/boring/bcache"
 	"math/big"
-	"unsafe"
 )
 
 // Cached conversions from Go PublicKey/PrivateKey to BoringCrypto.
@@ -27,8 +26,8 @@
 // still matches before using the cached key. The theory is that the real
 // operations are significantly more expensive than the comparison.
 
-var pubCache bcache.Cache
-var privCache bcache.Cache
+var pubCache bcache.Cache[PublicKey, boringPub]
+var privCache bcache.Cache[PrivateKey, boringPriv]
 
 func init() {
 	pubCache.Register()
@@ -41,7 +40,7 @@
 }
 
 func boringPublicKey(pub *PublicKey) (*boring.PublicKeyECDSA, error) {
-	b := (*boringPub)(pubCache.Get(unsafe.Pointer(pub)))
+	b := pubCache.Get(pub)
 	if b != nil && publicKeyEqual(&b.orig, pub) {
 		return b.key, nil
 	}
@@ -53,7 +52,7 @@
 		return nil, err
 	}
 	b.key = key
-	pubCache.Put(unsafe.Pointer(pub), unsafe.Pointer(b))
+	pubCache.Put(pub, b)
 	return key, nil
 }
 
@@ -63,7 +62,7 @@
 }
 
 func boringPrivateKey(priv *PrivateKey) (*boring.PrivateKeyECDSA, error) {
-	b := (*boringPriv)(privCache.Get(unsafe.Pointer(priv)))
+	b := privCache.Get(priv)
 	if b != nil && privateKeyEqual(&b.orig, priv) {
 		return b.key, nil
 	}
@@ -75,7 +74,7 @@
 		return nil, err
 	}
 	b.key = key
-	privCache.Put(unsafe.Pointer(priv), unsafe.Pointer(b))
+	privCache.Put(priv, b)
 	return key, nil
 }
 
diff --git a/src/crypto/ecdsa/ecdsa.go b/src/crypto/ecdsa/ecdsa.go
index d0e52ad..68272af 100644
--- a/src/crypto/ecdsa/ecdsa.go
+++ b/src/crypto/ecdsa/ecdsa.go
@@ -20,38 +20,28 @@
 // [SEC 1, Version 2.0]: https://www.secg.org/sec1-v2.pdf
 
 import (
+	"bytes"
 	"crypto"
 	"crypto/aes"
 	"crypto/cipher"
+	"crypto/ecdh"
 	"crypto/elliptic"
+	"crypto/internal/bigmod"
 	"crypto/internal/boring"
 	"crypto/internal/boring/bbig"
+	"crypto/internal/nistec"
 	"crypto/internal/randutil"
 	"crypto/sha512"
+	"crypto/subtle"
 	"errors"
 	"io"
 	"math/big"
+	"sync"
 
 	"golang.org/x/crypto/cryptobyte"
 	"golang.org/x/crypto/cryptobyte/asn1"
 )
 
-// A invertible implements fast inverse in GF(N).
-type invertible interface {
-	// Inverse returns the inverse of k mod Params().N.
-	Inverse(k *big.Int) *big.Int
-}
-
-// A combinedMult implements fast combined multiplication for verification.
-type combinedMult interface {
-	// CombinedMult returns [s1]G + [s2]P where G is the generator.
-	CombinedMult(Px, Py *big.Int, s1, s2 []byte) (x, y *big.Int)
-}
-
-const (
-	aesIV = "IV for ECDSA CTR"
-)
-
 // PublicKey represents an ECDSA public key.
 type PublicKey struct {
 	elliptic.Curve
@@ -61,6 +51,20 @@
 // Any methods implemented on PublicKey might need to also be implemented on
 // PrivateKey, as the latter embeds the former and will expose its methods.
 
+// ECDH returns k as a [ecdh.PublicKey]. It returns an error if the key is
+// invalid according to the definition of [ecdh.Curve.NewPublicKey], or if the
+// Curve is not supported by crypto/ecdh.
+func (k *PublicKey) ECDH() (*ecdh.PublicKey, error) {
+	c := curveToECDH(k.Curve)
+	if c == nil {
+		return nil, errors.New("ecdsa: unsupported curve by crypto/ecdh")
+	}
+	if !k.Curve.IsOnCurve(k.X, k.Y) {
+		return nil, errors.New("ecdsa: invalid public key")
+	}
+	return c.NewPublicKey(elliptic.Marshal(k.Curve, k.X, k.Y))
+}
+
 // Equal reports whether pub and x have the same value.
 //
 // Two keys are only considered to have the same value if they have the same Curve value.
@@ -71,7 +75,7 @@
 	if !ok {
 		return false
 	}
-	return pub.X.Cmp(xx.X) == 0 && pub.Y.Cmp(xx.Y) == 0 &&
+	return bigIntEqual(pub.X, xx.X) && bigIntEqual(pub.Y, xx.Y) &&
 		// Standard library Curve implementations are singletons, so this check
 		// will work for those. Other Curves might be equivalent even if not
 		// singletons, but there is no definitive way to check for that, and
@@ -85,6 +89,34 @@
 	D *big.Int
 }
 
+// ECDH returns k as a [ecdh.PrivateKey]. It returns an error if the key is
+// invalid according to the definition of [ecdh.Curve.NewPrivateKey], or if the
+// Curve is not supported by crypto/ecdh.
+func (k *PrivateKey) ECDH() (*ecdh.PrivateKey, error) {
+	c := curveToECDH(k.Curve)
+	if c == nil {
+		return nil, errors.New("ecdsa: unsupported curve by crypto/ecdh")
+	}
+	size := (k.Curve.Params().N.BitLen() + 7) / 8
+	if k.D.BitLen() > size*8 {
+		return nil, errors.New("ecdsa: invalid private key")
+	}
+	return c.NewPrivateKey(k.D.FillBytes(make([]byte, size)))
+}
+
+func curveToECDH(c elliptic.Curve) ecdh.Curve {
+	switch c {
+	case elliptic.P256():
+		return ecdh.P256()
+	case elliptic.P384():
+		return ecdh.P384()
+	case elliptic.P521():
+		return ecdh.P521()
+	default:
+		return nil
+	}
+}
+
 // Public returns the public key corresponding to priv.
 func (priv *PrivateKey) Public() crypto.PublicKey {
 	return &priv.PublicKey
@@ -98,7 +130,13 @@
 	if !ok {
 		return false
 	}
-	return priv.PublicKey.Equal(&xx.PublicKey) && priv.D.Cmp(xx.D) == 0
+	return priv.PublicKey.Equal(&xx.PublicKey) && bigIntEqual(priv.D, xx.D)
+}
+
+// bigIntEqual reports whether a and b are equal leaking only their bit length
+// through timing side-channels.
+func bigIntEqual(a, b *big.Int) bool {
+	return subtle.ConstantTimeCompare(a.Bytes(), b.Bytes()) == 1
 }
 
 // Sign signs digest with priv, reading randomness from rand. The opts argument
@@ -109,51 +147,13 @@
 // where the private part is kept in, for example, a hardware module. Common
 // uses can use the SignASN1 function in this package directly.
 func (priv *PrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
-	if boring.Enabled && rand == boring.RandReader {
-		b, err := boringPrivateKey(priv)
-		if err != nil {
-			return nil, err
-		}
-		return boring.SignMarshalECDSA(b, digest)
-	}
-	boring.UnreachableExceptTests()
-
-	r, s, err := Sign(rand, priv, digest)
-	if err != nil {
-		return nil, err
-	}
-
-	var b cryptobyte.Builder
-	b.AddASN1(asn1.SEQUENCE, func(b *cryptobyte.Builder) {
-		b.AddASN1BigInt(r)
-		b.AddASN1BigInt(s)
-	})
-	return b.Bytes()
-}
-
-var one = new(big.Int).SetInt64(1)
-
-// randFieldElement returns a random element of the order of the given
-// curve using the procedure given in FIPS 186-4, Appendix B.5.1.
-func randFieldElement(c elliptic.Curve, rand io.Reader) (k *big.Int, err error) {
-	params := c.Params()
-	// Note that for P-521 this will actually be 63 bits more than the order, as
-	// division rounds down, but the extra bit is inconsequential.
-	b := make([]byte, params.N.BitLen()/8+8)
-	_, err = io.ReadFull(rand, b)
-	if err != nil {
-		return
-	}
-
-	k = new(big.Int).SetBytes(b)
-	n := new(big.Int).Sub(params.N, one)
-	k.Mod(k, n)
-	k.Add(k, one)
-	return
+	return SignASN1(rand, priv, digest)
 }
 
 // GenerateKey generates a public and private key pair.
 func GenerateKey(c elliptic.Curve, rand io.Reader) (*PrivateKey, error) {
+	randutil.MaybeReadByte(rand)
+
 	if boring.Enabled && rand == boring.RandReader {
 		x, y, d, err := boring.GenerateKeyECDSA(c.Params().Name)
 		if err != nil {
@@ -163,80 +163,246 @@
 	}
 	boring.UnreachableExceptTests()
 
-	k, err := randFieldElement(c, rand)
+	switch c.Params() {
+	case elliptic.P224().Params():
+		return generateNISTEC(p224(), rand)
+	case elliptic.P256().Params():
+		return generateNISTEC(p256(), rand)
+	case elliptic.P384().Params():
+		return generateNISTEC(p384(), rand)
+	case elliptic.P521().Params():
+		return generateNISTEC(p521(), rand)
+	default:
+		return generateLegacy(c, rand)
+	}
+}
+
+func generateNISTEC[Point nistPoint[Point]](c *nistCurve[Point], rand io.Reader) (*PrivateKey, error) {
+	k, Q, err := randomPoint(c, rand)
 	if err != nil {
 		return nil, err
 	}
 
 	priv := new(PrivateKey)
-	priv.PublicKey.Curve = c
-	priv.D = k
-	priv.PublicKey.X, priv.PublicKey.Y = c.ScalarBaseMult(k.Bytes())
+	priv.PublicKey.Curve = c.curve
+	priv.D = new(big.Int).SetBytes(k.Bytes(c.N))
+	priv.PublicKey.X, priv.PublicKey.Y, err = c.pointToAffine(Q)
+	if err != nil {
+		return nil, err
+	}
 	return priv, nil
 }
 
-// hashToInt converts a hash value to an integer. Per FIPS 186-4, Section 6.4,
-// we use the left-most bits of the hash to match the bit-length of the order of
-// the curve. This also performs Step 5 of SEC 1, Version 2.0, Section 4.1.3.
-func hashToInt(hash []byte, c elliptic.Curve) *big.Int {
-	orderBits := c.Params().N.BitLen()
-	orderBytes := (orderBits + 7) / 8
-	if len(hash) > orderBytes {
-		hash = hash[:orderBytes]
+// randomPoint returns a random scalar and the corresponding point using the
+// procedure given in FIPS 186-4, Appendix B.5.2 (rejection sampling).
+func randomPoint[Point nistPoint[Point]](c *nistCurve[Point], rand io.Reader) (k *bigmod.Nat, p Point, err error) {
+	k = bigmod.NewNat()
+	for {
+		b := make([]byte, c.N.Size())
+		if _, err = io.ReadFull(rand, b); err != nil {
+			return
+		}
+
+		// Mask off any excess bits to increase the chance of hitting a value in
+		// (0, N). These are the most dangerous lines in the package and maybe in
+		// the library: a single bit of bias in the selection of nonces would likely
+		// lead to key recovery, but no tests would fail. Look but DO NOT TOUCH.
+		if excess := len(b)*8 - c.N.BitLen(); excess > 0 {
+			// Just to be safe, assert that this only happens for the one curve that
+			// doesn't have a round number of bits.
+			if excess != 0 && c.curve.Params().Name != "P-521" {
+				panic("ecdsa: internal error: unexpectedly masking off bits")
+			}
+			b[0] >>= excess
+		}
+
+		// FIPS 186-4 makes us check k <= N - 2 and then add one.
+		// Checking 0 < k <= N - 1 is strictly equivalent.
+		// None of this matters anyway because the chance of selecting
+		// zero is cryptographically negligible.
+		if _, err = k.SetBytes(b, c.N); err == nil && k.IsZero() == 0 {
+			break
+		}
+
+		if testingOnlyRejectionSamplingLooped != nil {
+			testingOnlyRejectionSamplingLooped()
+		}
 	}
 
-	ret := new(big.Int).SetBytes(hash)
-	excess := len(hash)*8 - orderBits
-	if excess > 0 {
-		ret.Rsh(ret, uint(excess))
-	}
-	return ret
+	p, err = c.newPoint().ScalarBaseMult(k.Bytes(c.N))
+	return
 }
 
-// fermatInverse calculates the inverse of k in GF(P) using Fermat's method
-// (exponentiation modulo P - 2, per Euler's theorem). This has better
-// constant-time properties than Euclid's method (implemented in
-// math/big.Int.ModInverse and FIPS 186-4, Appendix C.1) although math/big
-// itself isn't strictly constant-time so it's not perfect.
-func fermatInverse(k, N *big.Int) *big.Int {
-	two := big.NewInt(2)
-	nMinus2 := new(big.Int).Sub(N, two)
-	return new(big.Int).Exp(k, nMinus2, N)
-}
+// testingOnlyRejectionSamplingLooped is called when rejection sampling in
+// randomPoint rejects a candidate for being higher than the modulus.
+var testingOnlyRejectionSamplingLooped func()
 
-var errZeroParam = errors.New("zero parameter")
+// errNoAsm is returned by signAsm and verifyAsm when the assembly
+// implementation is not available.
+var errNoAsm = errors.New("no assembly implementation available")
 
-// Sign signs a hash (which should be the result of hashing a larger message)
+// SignASN1 signs a hash (which should be the result of hashing a larger message)
 // using the private key, priv. If the hash is longer than the bit-length of the
 // private key's curve order, the hash will be truncated to that length. It
-// returns the signature as a pair of integers. Most applications should use
-// SignASN1 instead of dealing directly with r, s.
-func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error) {
+// returns the ASN.1 encoded signature.
+func SignASN1(rand io.Reader, priv *PrivateKey, hash []byte) ([]byte, error) {
 	randutil.MaybeReadByte(rand)
 
 	if boring.Enabled && rand == boring.RandReader {
 		b, err := boringPrivateKey(priv)
 		if err != nil {
-			return nil, nil, err
+			return nil, err
 		}
-		sig, err := boring.SignMarshalECDSA(b, hash)
-		if err != nil {
-			return nil, nil, err
-		}
-		var r, s big.Int
-		var inner cryptobyte.String
-		input := cryptobyte.String(sig)
-		if !input.ReadASN1(&inner, asn1.SEQUENCE) ||
-			!input.Empty() ||
-			!inner.ReadASN1Integer(&r) ||
-			!inner.ReadASN1Integer(&s) ||
-			!inner.Empty() {
-			return nil, nil, errors.New("invalid ASN.1 from boringcrypto")
-		}
-		return &r, &s, nil
+		return boring.SignMarshalECDSA(b, hash)
 	}
 	boring.UnreachableExceptTests()
 
+	csprng, err := mixedCSPRNG(rand, priv, hash)
+	if err != nil {
+		return nil, err
+	}
+
+	if sig, err := signAsm(priv, csprng, hash); err != errNoAsm {
+		return sig, err
+	}
+
+	switch priv.Curve.Params() {
+	case elliptic.P224().Params():
+		return signNISTEC(p224(), priv, csprng, hash)
+	case elliptic.P256().Params():
+		return signNISTEC(p256(), priv, csprng, hash)
+	case elliptic.P384().Params():
+		return signNISTEC(p384(), priv, csprng, hash)
+	case elliptic.P521().Params():
+		return signNISTEC(p521(), priv, csprng, hash)
+	default:
+		return signLegacy(priv, csprng, hash)
+	}
+}
+
+func signNISTEC[Point nistPoint[Point]](c *nistCurve[Point], priv *PrivateKey, csprng io.Reader, hash []byte) (sig []byte, err error) {
+	// SEC 1, Version 2.0, Section 4.1.3
+
+	k, R, err := randomPoint(c, csprng)
+	if err != nil {
+		return nil, err
+	}
+
+	// kInv = k⁻¹
+	kInv := bigmod.NewNat()
+	inverse(c, kInv, k)
+
+	Rx, err := R.BytesX()
+	if err != nil {
+		return nil, err
+	}
+	r, err := bigmod.NewNat().SetOverflowingBytes(Rx, c.N)
+	if err != nil {
+		return nil, err
+	}
+
+	// The spec wants us to retry here, but the chance of hitting this condition
+	// on a large prime-order group like the NIST curves we support is
+	// cryptographically negligible. If we hit it, something is awfully wrong.
+	if r.IsZero() == 1 {
+		return nil, errors.New("ecdsa: internal error: r is zero")
+	}
+
+	e := bigmod.NewNat()
+	hashToNat(c, e, hash)
+
+	s, err := bigmod.NewNat().SetBytes(priv.D.Bytes(), c.N)
+	if err != nil {
+		return nil, err
+	}
+	s.Mul(r, c.N)
+	s.Add(e, c.N)
+	s.Mul(kInv, c.N)
+
+	// Again, the chance of this happening is cryptographically negligible.
+	if s.IsZero() == 1 {
+		return nil, errors.New("ecdsa: internal error: s is zero")
+	}
+
+	return encodeSignature(r.Bytes(c.N), s.Bytes(c.N))
+}
+
+func encodeSignature(r, s []byte) ([]byte, error) {
+	var b cryptobyte.Builder
+	b.AddASN1(asn1.SEQUENCE, func(b *cryptobyte.Builder) {
+		addASN1IntBytes(b, r)
+		addASN1IntBytes(b, s)
+	})
+	return b.Bytes()
+}
+
+// addASN1IntBytes encodes in ASN.1 a positive integer represented as
+// a big-endian byte slice with zero or more leading zeroes.
+func addASN1IntBytes(b *cryptobyte.Builder, bytes []byte) {
+	for len(bytes) > 0 && bytes[0] == 0 {
+		bytes = bytes[1:]
+	}
+	if len(bytes) == 0 {
+		b.SetError(errors.New("invalid integer"))
+		return
+	}
+	b.AddASN1(asn1.INTEGER, func(c *cryptobyte.Builder) {
+		if bytes[0]&0x80 != 0 {
+			c.AddUint8(0)
+		}
+		c.AddBytes(bytes)
+	})
+}
+
+// inverse sets kInv to the inverse of k modulo the order of the curve.
+func inverse[Point nistPoint[Point]](c *nistCurve[Point], kInv, k *bigmod.Nat) {
+	if c.curve.Params().Name == "P-256" {
+		kBytes, err := nistec.P256OrdInverse(k.Bytes(c.N))
+		// Some platforms don't implement P256OrdInverse, and always return an error.
+		if err == nil {
+			_, err := kInv.SetBytes(kBytes, c.N)
+			if err != nil {
+				panic("ecdsa: internal error: P256OrdInverse produced an invalid value")
+			}
+			return
+		}
+	}
+
+	// Calculate the inverse of s in GF(N) using Fermat's method
+	// (exponentiation modulo P - 2, per Euler's theorem)
+	kInv.Exp(k, c.nMinus2, c.N)
+}
+
+// hashToNat sets e to the left-most bits of hash, according to
+// SEC 1, Section 4.1.3, point 5 and Section 4.1.4, point 3.
+func hashToNat[Point nistPoint[Point]](c *nistCurve[Point], e *bigmod.Nat, hash []byte) {
+	// ECDSA asks us to take the left-most log2(N) bits of hash, and use them as
+	// an integer modulo N. This is the absolute worst of all worlds: we still
+	// have to reduce, because the result might still overflow N, but to take
+	// the left-most bits for P-521 we have to do a right shift.
+	if size := c.N.Size(); len(hash) > size {
+		hash = hash[:size]
+		if excess := len(hash)*8 - c.N.BitLen(); excess > 0 {
+			hash = bytes.Clone(hash)
+			for i := len(hash) - 1; i >= 0; i-- {
+				hash[i] >>= excess
+				if i > 0 {
+					hash[i] |= hash[i-1] << (8 - excess)
+				}
+			}
+		}
+	}
+	_, err := e.SetOverflowingBytes(hash, c.N)
+	if err != nil {
+		panic("ecdsa: internal error: truncated hash is too long")
+	}
+}
+
+// mixedCSPRNG returns a CSPRNG that mixes entropy from rand with the message
+// and the private key, to protect the key in case rand fails. This is
+// equivalent in security to RFC 6979 deterministic nonce generation, but still
+// produces randomized signatures.
+func mixedCSPRNG(rand io.Reader, priv *PrivateKey, hash []byte) (io.Reader, error) {
 	// This implementation derives the nonce from an AES-CTR CSPRNG keyed by:
 	//
 	//    SHA2-512(priv.D || entropy || hash)[:32]
@@ -250,9 +416,8 @@
 
 	// Get 256 bits of entropy from rand.
 	entropy := make([]byte, 32)
-	_, err = io.ReadFull(rand, entropy)
-	if err != nil {
-		return
+	if _, err := io.ReadFull(rand, entropy); err != nil {
+		return nil, err
 	}
 
 	// Initialize an SHA-512 hash context; digest...
@@ -266,156 +431,22 @@
 	// Create an AES-CTR instance to use as a CSPRNG.
 	block, err := aes.NewCipher(key)
 	if err != nil {
-		return nil, nil, err
+		return nil, err
 	}
 
 	// Create a CSPRNG that xors a stream of zeros with
 	// the output of the AES-CTR instance.
-	csprng := &cipher.StreamReader{
+	const aesIV = "IV for ECDSA CTR"
+	return &cipher.StreamReader{
 		R: zeroReader,
 		S: cipher.NewCTR(block, []byte(aesIV)),
-	}
-
-	c := priv.PublicKey.Curve
-	return sign(priv, csprng, c, hash)
-}
-
-func signGeneric(priv *PrivateKey, csprng *cipher.StreamReader, c elliptic.Curve, hash []byte) (r, s *big.Int, err error) {
-	// SEC 1, Version 2.0, Section 4.1.3
-	N := c.Params().N
-	if N.Sign() == 0 {
-		return nil, nil, errZeroParam
-	}
-	var k, kInv *big.Int
-	for {
-		for {
-			k, err = randFieldElement(c, *csprng)
-			if err != nil {
-				r = nil
-				return
-			}
-
-			if in, ok := priv.Curve.(invertible); ok {
-				kInv = in.Inverse(k)
-			} else {
-				kInv = fermatInverse(k, N) // N != 0
-			}
-
-			r, _ = priv.Curve.ScalarBaseMult(k.Bytes())
-			r.Mod(r, N)
-			if r.Sign() != 0 {
-				break
-			}
-		}
-
-		e := hashToInt(hash, c)
-		s = new(big.Int).Mul(priv.D, r)
-		s.Add(s, e)
-		s.Mul(s, kInv)
-		s.Mod(s, N) // N != 0
-		if s.Sign() != 0 {
-			break
-		}
-	}
-
-	return
-}
-
-// SignASN1 signs a hash (which should be the result of hashing a larger message)
-// using the private key, priv. If the hash is longer than the bit-length of the
-// private key's curve order, the hash will be truncated to that length. It
-// returns the ASN.1 encoded signature.
-func SignASN1(rand io.Reader, priv *PrivateKey, hash []byte) ([]byte, error) {
-	return priv.Sign(rand, hash, nil)
-}
-
-// Verify verifies the signature in r, s of hash using the public key, pub. Its
-// return value records whether the signature is valid. Most applications should
-// use VerifyASN1 instead of dealing directly with r, s.
-func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool {
-	if boring.Enabled {
-		key, err := boringPublicKey(pub)
-		if err != nil {
-			return false
-		}
-		var b cryptobyte.Builder
-		b.AddASN1(asn1.SEQUENCE, func(b *cryptobyte.Builder) {
-			b.AddASN1BigInt(r)
-			b.AddASN1BigInt(s)
-		})
-		sig, err := b.Bytes()
-		if err != nil {
-			return false
-		}
-		return boring.VerifyECDSA(key, hash, sig)
-	}
-	boring.UnreachableExceptTests()
-
-	c := pub.Curve
-	N := c.Params().N
-
-	if r.Sign() <= 0 || s.Sign() <= 0 {
-		return false
-	}
-	if r.Cmp(N) >= 0 || s.Cmp(N) >= 0 {
-		return false
-	}
-	return verify(pub, c, hash, r, s)
-}
-
-func verifyGeneric(pub *PublicKey, c elliptic.Curve, hash []byte, r, s *big.Int) bool {
-	// SEC 1, Version 2.0, Section 4.1.4
-	e := hashToInt(hash, c)
-	var w *big.Int
-	N := c.Params().N
-	if in, ok := c.(invertible); ok {
-		w = in.Inverse(s)
-	} else {
-		w = new(big.Int).ModInverse(s, N)
-	}
-
-	u1 := e.Mul(e, w)
-	u1.Mod(u1, N)
-	u2 := w.Mul(r, w)
-	u2.Mod(u2, N)
-
-	// Check if implements S1*g + S2*p
-	var x, y *big.Int
-	if opt, ok := c.(combinedMult); ok {
-		x, y = opt.CombinedMult(pub.X, pub.Y, u1.Bytes(), u2.Bytes())
-	} else {
-		x1, y1 := c.ScalarBaseMult(u1.Bytes())
-		x2, y2 := c.ScalarMult(pub.X, pub.Y, u2.Bytes())
-		x, y = c.Add(x1, y1, x2, y2)
-	}
-
-	if x.Sign() == 0 && y.Sign() == 0 {
-		return false
-	}
-	x.Mod(x, N)
-	return x.Cmp(r) == 0
-}
-
-// VerifyASN1 verifies the ASN.1 encoded signature, sig, of hash using the
-// public key, pub. Its return value records whether the signature is valid.
-func VerifyASN1(pub *PublicKey, hash, sig []byte) bool {
-	var (
-		r, s  = &big.Int{}, &big.Int{}
-		inner cryptobyte.String
-	)
-	input := cryptobyte.String(sig)
-	if !input.ReadASN1(&inner, asn1.SEQUENCE) ||
-		!input.Empty() ||
-		!inner.ReadASN1Integer(r) ||
-		!inner.ReadASN1Integer(s) ||
-		!inner.Empty() {
-		return false
-	}
-	return Verify(pub, hash, r, s)
+	}, nil
 }
 
 type zr struct{}
 
+var zeroReader = zr{}
+
 // Read replaces the contents of dst with zeros. It is safe for concurrent use.
 func (zr) Read(dst []byte) (n int, err error) {
 	for i := range dst {
@@ -424,4 +455,206 @@
 	return len(dst), nil
 }
 
-var zeroReader = zr{}
+// VerifyASN1 verifies the ASN.1 encoded signature, sig, of hash using the
+// public key, pub. Its return value records whether the signature is valid.
+func VerifyASN1(pub *PublicKey, hash, sig []byte) bool {
+	if boring.Enabled {
+		key, err := boringPublicKey(pub)
+		if err != nil {
+			return false
+		}
+		return boring.VerifyECDSA(key, hash, sig)
+	}
+	boring.UnreachableExceptTests()
+
+	if err := verifyAsm(pub, hash, sig); err != errNoAsm {
+		return err == nil
+	}
+
+	switch pub.Curve.Params() {
+	case elliptic.P224().Params():
+		return verifyNISTEC(p224(), pub, hash, sig)
+	case elliptic.P256().Params():
+		return verifyNISTEC(p256(), pub, hash, sig)
+	case elliptic.P384().Params():
+		return verifyNISTEC(p384(), pub, hash, sig)
+	case elliptic.P521().Params():
+		return verifyNISTEC(p521(), pub, hash, sig)
+	default:
+		return verifyLegacy(pub, hash, sig)
+	}
+}
+
+func verifyNISTEC[Point nistPoint[Point]](c *nistCurve[Point], pub *PublicKey, hash, sig []byte) bool {
+	rBytes, sBytes, err := parseSignature(sig)
+	if err != nil {
+		return false
+	}
+
+	Q, err := c.pointFromAffine(pub.X, pub.Y)
+	if err != nil {
+		return false
+	}
+
+	// SEC 1, Version 2.0, Section 4.1.4
+
+	r, err := bigmod.NewNat().SetBytes(rBytes, c.N)
+	if err != nil || r.IsZero() == 1 {
+		return false
+	}
+	s, err := bigmod.NewNat().SetBytes(sBytes, c.N)
+	if err != nil || s.IsZero() == 1 {
+		return false
+	}
+
+	e := bigmod.NewNat()
+	hashToNat(c, e, hash)
+
+	// w = s⁻¹
+	w := bigmod.NewNat()
+	inverse(c, w, s)
+
+	// p₁ = [e * s⁻¹]G
+	p1, err := c.newPoint().ScalarBaseMult(e.Mul(w, c.N).Bytes(c.N))
+	if err != nil {
+		return false
+	}
+	// p₂ = [r * s⁻¹]Q
+	p2, err := Q.ScalarMult(Q, w.Mul(r, c.N).Bytes(c.N))
+	if err != nil {
+		return false
+	}
+	// BytesX returns an error for the point at infinity.
+	Rx, err := p1.Add(p1, p2).BytesX()
+	if err != nil {
+		return false
+	}
+
+	v, err := bigmod.NewNat().SetOverflowingBytes(Rx, c.N)
+	if err != nil {
+		return false
+	}
+
+	return v.Equal(r) == 1
+}
+
+func parseSignature(sig []byte) (r, s []byte, err error) {
+	var inner cryptobyte.String
+	input := cryptobyte.String(sig)
+	if !input.ReadASN1(&inner, asn1.SEQUENCE) ||
+		!input.Empty() ||
+		!inner.ReadASN1Integer(&r) ||
+		!inner.ReadASN1Integer(&s) ||
+		!inner.Empty() {
+		return nil, nil, errors.New("invalid ASN.1")
+	}
+	return r, s, nil
+}
+
+type nistCurve[Point nistPoint[Point]] struct {
+	newPoint func() Point
+	curve    elliptic.Curve
+	N        *bigmod.Modulus
+	nMinus2  []byte
+}
+
+// nistPoint is a generic constraint for the nistec Point types.
+type nistPoint[T any] interface {
+	Bytes() []byte
+	BytesX() ([]byte, error)
+	SetBytes([]byte) (T, error)
+	Add(T, T) T
+	ScalarMult(T, []byte) (T, error)
+	ScalarBaseMult([]byte) (T, error)
+}
+
+// pointFromAffine is used to convert the PublicKey to a nistec Point.
+func (curve *nistCurve[Point]) pointFromAffine(x, y *big.Int) (p Point, err error) {
+	bitSize := curve.curve.Params().BitSize
+	// Reject values that would not get correctly encoded.
+	if x.Sign() < 0 || y.Sign() < 0 {
+		return p, errors.New("negative coordinate")
+	}
+	if x.BitLen() > bitSize || y.BitLen() > bitSize {
+		return p, errors.New("overflowing coordinate")
+	}
+	// Encode the coordinates and let SetBytes reject invalid points.
+	byteLen := (bitSize + 7) / 8
+	buf := make([]byte, 1+2*byteLen)
+	buf[0] = 4 // uncompressed point
+	x.FillBytes(buf[1 : 1+byteLen])
+	y.FillBytes(buf[1+byteLen : 1+2*byteLen])
+	return curve.newPoint().SetBytes(buf)
+}
+
+// pointToAffine is used to convert a nistec Point to a PublicKey.
+func (curve *nistCurve[Point]) pointToAffine(p Point) (x, y *big.Int, err error) {
+	out := p.Bytes()
+	if len(out) == 1 && out[0] == 0 {
+		// This is the encoding of the point at infinity.
+		return nil, nil, errors.New("ecdsa: public key point is the infinity")
+	}
+	byteLen := (curve.curve.Params().BitSize + 7) / 8
+	x = new(big.Int).SetBytes(out[1 : 1+byteLen])
+	y = new(big.Int).SetBytes(out[1+byteLen:])
+	return x, y, nil
+}
+
+var p224Once sync.Once
+var _p224 *nistCurve[*nistec.P224Point]
+
+func p224() *nistCurve[*nistec.P224Point] {
+	p224Once.Do(func() {
+		_p224 = &nistCurve[*nistec.P224Point]{
+			newPoint: func() *nistec.P224Point { return nistec.NewP224Point() },
+		}
+		precomputeParams(_p224, elliptic.P224())
+	})
+	return _p224
+}
+
+var p256Once sync.Once
+var _p256 *nistCurve[*nistec.P256Point]
+
+func p256() *nistCurve[*nistec.P256Point] {
+	p256Once.Do(func() {
+		_p256 = &nistCurve[*nistec.P256Point]{
+			newPoint: func() *nistec.P256Point { return nistec.NewP256Point() },
+		}
+		precomputeParams(_p256, elliptic.P256())
+	})
+	return _p256
+}
+
+var p384Once sync.Once
+var _p384 *nistCurve[*nistec.P384Point]
+
+func p384() *nistCurve[*nistec.P384Point] {
+	p384Once.Do(func() {
+		_p384 = &nistCurve[*nistec.P384Point]{
+			newPoint: func() *nistec.P384Point { return nistec.NewP384Point() },
+		}
+		precomputeParams(_p384, elliptic.P384())
+	})
+	return _p384
+}
+
+var p521Once sync.Once
+var _p521 *nistCurve[*nistec.P521Point]
+
+func p521() *nistCurve[*nistec.P521Point] {
+	p521Once.Do(func() {
+		_p521 = &nistCurve[*nistec.P521Point]{
+			newPoint: func() *nistec.P521Point { return nistec.NewP521Point() },
+		}
+		precomputeParams(_p521, elliptic.P521())
+	})
+	return _p521
+}
+
+func precomputeParams[Point nistPoint[Point]](c *nistCurve[Point], curve elliptic.Curve) {
+	params := curve.Params()
+	c.curve = curve
+	c.N = bigmod.NewModulusFromBig(params.N)
+	c.nMinus2 = new(big.Int).Sub(params.N, big.NewInt(2)).Bytes()
+}
diff --git a/src/crypto/ecdsa/ecdsa_legacy.go b/src/crypto/ecdsa/ecdsa_legacy.go
new file mode 100644
index 0000000..12a40e4
--- /dev/null
+++ b/src/crypto/ecdsa/ecdsa_legacy.go
@@ -0,0 +1,188 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ecdsa
+
+import (
+	"crypto/elliptic"
+	"errors"
+	"io"
+	"math/big"
+
+	"golang.org/x/crypto/cryptobyte"
+	"golang.org/x/crypto/cryptobyte/asn1"
+)
+
+// This file contains a math/big implementation of ECDSA that is only used for
+// deprecated custom curves.
+
+func generateLegacy(c elliptic.Curve, rand io.Reader) (*PrivateKey, error) {
+	k, err := randFieldElement(c, rand)
+	if err != nil {
+		return nil, err
+	}
+
+	priv := new(PrivateKey)
+	priv.PublicKey.Curve = c
+	priv.D = k
+	priv.PublicKey.X, priv.PublicKey.Y = c.ScalarBaseMult(k.Bytes())
+	return priv, nil
+}
+
+// hashToInt converts a hash value to an integer. Per FIPS 186-4, Section 6.4,
+// we use the left-most bits of the hash to match the bit-length of the order of
+// the curve. This also performs Step 5 of SEC 1, Version 2.0, Section 4.1.3.
+func hashToInt(hash []byte, c elliptic.Curve) *big.Int {
+	orderBits := c.Params().N.BitLen()
+	orderBytes := (orderBits + 7) / 8
+	if len(hash) > orderBytes {
+		hash = hash[:orderBytes]
+	}
+
+	ret := new(big.Int).SetBytes(hash)
+	excess := len(hash)*8 - orderBits
+	if excess > 0 {
+		ret.Rsh(ret, uint(excess))
+	}
+	return ret
+}
+
+var errZeroParam = errors.New("zero parameter")
+
+// Sign signs a hash (which should be the result of hashing a larger message)
+// using the private key, priv. If the hash is longer than the bit-length of the
+// private key's curve order, the hash will be truncated to that length. It
+// returns the signature as a pair of integers. Most applications should use
+// SignASN1 instead of dealing directly with r, s.
+func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error) {
+	sig, err := SignASN1(rand, priv, hash)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	r, s = new(big.Int), new(big.Int)
+	var inner cryptobyte.String
+	input := cryptobyte.String(sig)
+	if !input.ReadASN1(&inner, asn1.SEQUENCE) ||
+		!input.Empty() ||
+		!inner.ReadASN1Integer(r) ||
+		!inner.ReadASN1Integer(s) ||
+		!inner.Empty() {
+		return nil, nil, errors.New("invalid ASN.1 from SignASN1")
+	}
+	return r, s, nil
+}
+
+func signLegacy(priv *PrivateKey, csprng io.Reader, hash []byte) (sig []byte, err error) {
+	c := priv.Curve
+
+	// SEC 1, Version 2.0, Section 4.1.3
+	N := c.Params().N
+	if N.Sign() == 0 {
+		return nil, errZeroParam
+	}
+	var k, kInv, r, s *big.Int
+	for {
+		for {
+			k, err = randFieldElement(c, csprng)
+			if err != nil {
+				return nil, err
+			}
+
+			kInv = new(big.Int).ModInverse(k, N)
+
+			r, _ = c.ScalarBaseMult(k.Bytes())
+			r.Mod(r, N)
+			if r.Sign() != 0 {
+				break
+			}
+		}
+
+		e := hashToInt(hash, c)
+		s = new(big.Int).Mul(priv.D, r)
+		s.Add(s, e)
+		s.Mul(s, kInv)
+		s.Mod(s, N) // N != 0
+		if s.Sign() != 0 {
+			break
+		}
+	}
+
+	return encodeSignature(r.Bytes(), s.Bytes())
+}
+
+// Verify verifies the signature in r, s of hash using the public key, pub. Its
+// return value records whether the signature is valid. Most applications should
+// use VerifyASN1 instead of dealing directly with r, s.
+func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool {
+	if r.Sign() <= 0 || s.Sign() <= 0 {
+		return false
+	}
+	sig, err := encodeSignature(r.Bytes(), s.Bytes())
+	if err != nil {
+		return false
+	}
+	return VerifyASN1(pub, hash, sig)
+}
+
+func verifyLegacy(pub *PublicKey, hash []byte, sig []byte) bool {
+	rBytes, sBytes, err := parseSignature(sig)
+	if err != nil {
+		return false
+	}
+	r, s := new(big.Int).SetBytes(rBytes), new(big.Int).SetBytes(sBytes)
+
+	c := pub.Curve
+	N := c.Params().N
+
+	if r.Sign() <= 0 || s.Sign() <= 0 {
+		return false
+	}
+	if r.Cmp(N) >= 0 || s.Cmp(N) >= 0 {
+		return false
+	}
+
+	// SEC 1, Version 2.0, Section 4.1.4
+	e := hashToInt(hash, c)
+	w := new(big.Int).ModInverse(s, N)
+
+	u1 := e.Mul(e, w)
+	u1.Mod(u1, N)
+	u2 := w.Mul(r, w)
+	u2.Mod(u2, N)
+
+	x1, y1 := c.ScalarBaseMult(u1.Bytes())
+	x2, y2 := c.ScalarMult(pub.X, pub.Y, u2.Bytes())
+	x, y := c.Add(x1, y1, x2, y2)
+
+	if x.Sign() == 0 && y.Sign() == 0 {
+		return false
+	}
+	x.Mod(x, N)
+	return x.Cmp(r) == 0
+}
+
+var one = new(big.Int).SetInt64(1)
+
+// randFieldElement returns a random element of the order of the given
+// curve using the procedure given in FIPS 186-4, Appendix B.5.2.
+func randFieldElement(c elliptic.Curve, rand io.Reader) (k *big.Int, err error) {
+	// See randomPoint for notes on the algorithm. This has to match, or s390x
+	// signatures will come out different from other architectures, which will
+	// break TLS recorded tests.
+	for {
+		N := c.Params().N
+		b := make([]byte, (N.BitLen()+7)/8)
+		if _, err = io.ReadFull(rand, b); err != nil {
+			return
+		}
+		if excess := len(b)*8 - N.BitLen(); excess > 0 {
+			b[0] >>= excess
+		}
+		k = new(big.Int).SetBytes(b)
+		if k.Sign() != 0 && k.Cmp(N) < 0 {
+			return
+		}
+	}
+}
diff --git a/src/crypto/ecdsa/ecdsa_noasm.go b/src/crypto/ecdsa/ecdsa_noasm.go
index 7fbca10..a72aa4b 100644
--- a/src/crypto/ecdsa/ecdsa_noasm.go
+++ b/src/crypto/ecdsa/ecdsa_noasm.go
@@ -6,16 +6,12 @@
 
 package ecdsa
 
-import (
-	"crypto/cipher"
-	"crypto/elliptic"
-	"math/big"
-)
+import "io"
 
-func sign(priv *PrivateKey, csprng *cipher.StreamReader, c elliptic.Curve, hash []byte) (r, s *big.Int, err error) {
-	return signGeneric(priv, csprng, c, hash)
+func verifyAsm(pub *PublicKey, hash []byte, sig []byte) error {
+	return errNoAsm
 }
 
-func verify(pub *PublicKey, c elliptic.Curve, hash []byte, r, s *big.Int) bool {
-	return verifyGeneric(pub, c, hash, r, s)
+func signAsm(priv *PrivateKey, csprng io.Reader, hash []byte) (sig []byte, err error) {
+	return nil, errNoAsm
 }
diff --git a/src/crypto/ecdsa/ecdsa_s390x.go b/src/crypto/ecdsa/ecdsa_s390x.go
index bd92579..49f645a 100644
--- a/src/crypto/ecdsa/ecdsa_s390x.go
+++ b/src/crypto/ecdsa/ecdsa_s390x.go
@@ -5,9 +5,10 @@
 package ecdsa
 
 import (
-	"crypto/cipher"
 	"crypto/elliptic"
+	"errors"
 	"internal/cpu"
+	"io"
 	"math/big"
 )
 
@@ -69,67 +70,20 @@
 	hashToInt(hash, c).FillBytes(dst)
 }
 
-func sign(priv *PrivateKey, csprng *cipher.StreamReader, c elliptic.Curve, hash []byte) (r, s *big.Int, err error) {
-	if functionCode, blockSize, ok := canUseKDSA(c); ok {
-		for {
-			var k *big.Int
-			k, err = randFieldElement(c, *csprng)
-			if err != nil {
-				return nil, nil, err
-			}
-
-			// The parameter block looks like the following for sign.
-			// 	+---------------------+
-			// 	|   Signature(R)      |
-			//	+---------------------+
-			//	|   Signature(S)      |
-			//	+---------------------+
-			//	|   Hashed Message    |
-			//	+---------------------+
-			//	|   Private Key       |
-			//	+---------------------+
-			//	|   Random Number     |
-			//	+---------------------+
-			//	|                     |
-			//	|        ...          |
-			//	|                     |
-			//	+---------------------+
-			// The common components(signatureR, signatureS, hashedMessage, privateKey and
-			// random number) each takes block size of bytes. The block size is different for
-			// different curves and is set by canUseKDSA function.
-			var params [4096]byte
-
-			// Copy content into the parameter block. In the sign case,
-			// we copy hashed message, private key and random number into
-			// the parameter block.
-			hashToBytes(params[2*blockSize:3*blockSize], hash, c)
-			priv.D.FillBytes(params[3*blockSize : 4*blockSize])
-			k.FillBytes(params[4*blockSize : 5*blockSize])
-			// Convert verify function code into a sign function code by adding 8.
-			// We also need to set the 'deterministic' bit in the function code, by
-			// adding 128, in order to stop the instruction using its own random number
-			// generator in addition to the random number we supply.
-			switch kdsa(functionCode+136, &params) {
-			case 0: // success
-				r = new(big.Int)
-				r.SetBytes(params[:blockSize])
-				s = new(big.Int)
-				s.SetBytes(params[blockSize : 2*blockSize])
-				return
-			case 1: // error
-				return nil, nil, errZeroParam
-			case 2: // retry
-				continue
-			}
-			panic("unreachable")
-		}
+func signAsm(priv *PrivateKey, csprng io.Reader, hash []byte) (sig []byte, err error) {
+	c := priv.Curve
+	functionCode, blockSize, ok := canUseKDSA(c)
+	if !ok {
+		return nil, errNoAsm
 	}
-	return signGeneric(priv, csprng, c, hash)
-}
+	for {
+		var k *big.Int
+		k, err = randFieldElement(c, csprng)
+		if err != nil {
+			return nil, err
+		}
 
-func verify(pub *PublicKey, c elliptic.Curve, hash []byte, r, s *big.Int) bool {
-	if functionCode, blockSize, ok := canUseKDSA(c); ok {
-		// The parameter block looks like the following for verify:
+		// The parameter block looks like the following for sign.
 		// 	+---------------------+
 		// 	|   Signature(R)      |
 		//	+---------------------+
@@ -137,28 +91,87 @@
 		//	+---------------------+
 		//	|   Hashed Message    |
 		//	+---------------------+
-		//	|   Public Key X      |
+		//	|   Private Key       |
 		//	+---------------------+
-		//	|   Public Key Y      |
+		//	|   Random Number     |
 		//	+---------------------+
 		//	|                     |
 		//	|        ...          |
 		//	|                     |
 		//	+---------------------+
-		// The common components(signatureR, signatureS, hashed message, public key X,
-		// and public key Y) each takes block size of bytes. The block size is different for
+		// The common components(signatureR, signatureS, hashedMessage, privateKey and
+		// random number) each takes block size of bytes. The block size is different for
 		// different curves and is set by canUseKDSA function.
 		var params [4096]byte
 
-		// Copy content into the parameter block. In the verify case,
-		// we copy signature (r), signature(s), hashed message, public key x component,
-		// and public key y component into the parameter block.
-		r.FillBytes(params[0*blockSize : 1*blockSize])
-		s.FillBytes(params[1*blockSize : 2*blockSize])
+		// Copy content into the parameter block. In the sign case,
+		// we copy hashed message, private key and random number into
+		// the parameter block.
 		hashToBytes(params[2*blockSize:3*blockSize], hash, c)
-		pub.X.FillBytes(params[3*blockSize : 4*blockSize])
-		pub.Y.FillBytes(params[4*blockSize : 5*blockSize])
-		return kdsa(functionCode, &params) == 0
+		priv.D.FillBytes(params[3*blockSize : 4*blockSize])
+		k.FillBytes(params[4*blockSize : 5*blockSize])
+		// Convert verify function code into a sign function code by adding 8.
+		// We also need to set the 'deterministic' bit in the function code, by
+		// adding 128, in order to stop the instruction using its own random number
+		// generator in addition to the random number we supply.
+		switch kdsa(functionCode+136, &params) {
+		case 0: // success
+			return encodeSignature(params[:blockSize], params[blockSize:2*blockSize])
+		case 1: // error
+			return nil, errZeroParam
+		case 2: // retry
+			continue
+		}
+		panic("unreachable")
 	}
-	return verifyGeneric(pub, c, hash, r, s)
+}
+
+func verifyAsm(pub *PublicKey, hash []byte, sig []byte) error {
+	c := pub.Curve
+	functionCode, blockSize, ok := canUseKDSA(c)
+	if !ok {
+		return errNoAsm
+	}
+
+	r, s, err := parseSignature(sig)
+	if err != nil {
+		return err
+	}
+	if len(r) > blockSize || len(s) > blockSize {
+		return errors.New("invalid signature")
+	}
+
+	// The parameter block looks like the following for verify:
+	// 	+---------------------+
+	// 	|   Signature(R)      |
+	//	+---------------------+
+	//	|   Signature(S)      |
+	//	+---------------------+
+	//	|   Hashed Message    |
+	//	+---------------------+
+	//	|   Public Key X      |
+	//	+---------------------+
+	//	|   Public Key Y      |
+	//	+---------------------+
+	//	|                     |
+	//	|        ...          |
+	//	|                     |
+	//	+---------------------+
+	// The common components(signatureR, signatureS, hashed message, public key X,
+	// and public key Y) each takes block size of bytes. The block size is different for
+	// different curves and is set by canUseKDSA function.
+	var params [4096]byte
+
+	// Copy content into the parameter block. In the verify case,
+	// we copy signature (r), signature(s), hashed message, public key x component,
+	// and public key y component into the parameter block.
+	copy(params[0*blockSize+blockSize-len(r):], r)
+	copy(params[1*blockSize+blockSize-len(s):], s)
+	hashToBytes(params[2*blockSize:3*blockSize], hash, c)
+	pub.X.FillBytes(params[3*blockSize : 4*blockSize])
+	pub.Y.FillBytes(params[4*blockSize : 5*blockSize])
+	if kdsa(functionCode, &params) != 0 {
+		return errors.New("invalid signature")
+	}
+	return nil
 }
diff --git a/src/crypto/ecdsa/ecdsa_test.go b/src/crypto/ecdsa/ecdsa_test.go
index 77a8134..95c78c8 100644
--- a/src/crypto/ecdsa/ecdsa_test.go
+++ b/src/crypto/ecdsa/ecdsa_test.go
@@ -6,6 +6,7 @@
 
 import (
 	"bufio"
+	"bytes"
 	"compress/bzip2"
 	"crypto/elliptic"
 	"crypto/rand"
@@ -30,6 +31,7 @@
 		{"P224", elliptic.P224()},
 		{"P384", elliptic.P384()},
 		{"P521", elliptic.P521()},
+		{"P256/Generic", genericParamsForCurve(elliptic.P256())},
 	}
 	if testing.Short() {
 		tests = tests[:1]
@@ -43,6 +45,15 @@
 	}
 }
 
+// genericParamsForCurve returns the dereferenced CurveParams for
+// the specified curve. This is used to avoid the logic for
+// upgrading a curve to its specific implementation, forcing
+// usage of the generic implementation.
+func genericParamsForCurve(c elliptic.Curve) *elliptic.CurveParams {
+	d := *(c.Params())
+	return &d
+}
+
 func TestKeyGeneration(t *testing.T) {
 	testAllCurves(t, testKeyGeneration)
 }
@@ -327,13 +338,172 @@
 	}
 }
 
+func TestRandomPoint(t *testing.T) {
+	t.Run("P-224", func(t *testing.T) { testRandomPoint(t, p224()) })
+	t.Run("P-256", func(t *testing.T) { testRandomPoint(t, p256()) })
+	t.Run("P-384", func(t *testing.T) { testRandomPoint(t, p384()) })
+	t.Run("P-521", func(t *testing.T) { testRandomPoint(t, p521()) })
+}
+
+func testRandomPoint[Point nistPoint[Point]](t *testing.T, c *nistCurve[Point]) {
+	t.Cleanup(func() { testingOnlyRejectionSamplingLooped = nil })
+	var loopCount int
+	testingOnlyRejectionSamplingLooped = func() { loopCount++ }
+
+	// A sequence of all ones will generate 2^N-1, which should be rejected.
+	// (Unless, for example, we are masking too many bits.)
+	r := io.MultiReader(bytes.NewReader(bytes.Repeat([]byte{0xff}, 100)), rand.Reader)
+	if k, p, err := randomPoint(c, r); err != nil {
+		t.Fatal(err)
+	} else if k.IsZero() == 1 {
+		t.Error("k is zero")
+	} else if p.Bytes()[0] != 4 {
+		t.Error("p is infinity")
+	}
+	if loopCount == 0 {
+		t.Error("overflow was not rejected")
+	}
+	loopCount = 0
+
+	// A sequence of all zeroes will generate zero, which should be rejected.
+	r = io.MultiReader(bytes.NewReader(bytes.Repeat([]byte{0}, 100)), rand.Reader)
+	if k, p, err := randomPoint(c, r); err != nil {
+		t.Fatal(err)
+	} else if k.IsZero() == 1 {
+		t.Error("k is zero")
+	} else if p.Bytes()[0] != 4 {
+		t.Error("p is infinity")
+	}
+	if loopCount == 0 {
+		t.Error("zero was not rejected")
+	}
+	loopCount = 0
+
+	// P-256 has a 2⁻³² chance or randomly hitting a rejection. For P-224 it's
+	// 2⁻¹¹², for P-384 it's 2⁻¹⁹⁴, and for P-521 it's 2⁻²⁶², so if we hit in
+	// tests, something is horribly wrong. (For example, we are masking the
+	// wrong bits.)
+	if c.curve == elliptic.P256() {
+		return
+	}
+	if k, p, err := randomPoint(c, rand.Reader); err != nil {
+		t.Fatal(err)
+	} else if k.IsZero() == 1 {
+		t.Error("k is zero")
+	} else if p.Bytes()[0] != 4 {
+		t.Error("p is infinity")
+	}
+	if loopCount > 0 {
+		t.Error("unexpected rejection")
+	}
+}
+
+func TestZeroSignature(t *testing.T) {
+	testAllCurves(t, testZeroSignature)
+}
+
+func testZeroSignature(t *testing.T, curve elliptic.Curve) {
+	privKey, err := GenerateKey(curve, rand.Reader)
+	if err != nil {
+		panic(err)
+	}
+
+	if Verify(&privKey.PublicKey, make([]byte, 64), big.NewInt(0), big.NewInt(0)) {
+		t.Errorf("Verify with r,s=0 succeeded: %T", curve)
+	}
+}
+
+func TestNegtativeSignature(t *testing.T) {
+	testAllCurves(t, testNegativeSignature)
+}
+
+func testNegativeSignature(t *testing.T, curve elliptic.Curve) {
+	zeroHash := make([]byte, 64)
+
+	privKey, err := GenerateKey(curve, rand.Reader)
+	if err != nil {
+		panic(err)
+	}
+	r, s, err := Sign(rand.Reader, privKey, zeroHash)
+	if err != nil {
+		panic(err)
+	}
+
+	r = r.Neg(r)
+	if Verify(&privKey.PublicKey, zeroHash, r, s) {
+		t.Errorf("Verify with r=-r succeeded: %T", curve)
+	}
+}
+
+func TestRPlusNSignature(t *testing.T) {
+	testAllCurves(t, testRPlusNSignature)
+}
+
+func testRPlusNSignature(t *testing.T, curve elliptic.Curve) {
+	zeroHash := make([]byte, 64)
+
+	privKey, err := GenerateKey(curve, rand.Reader)
+	if err != nil {
+		panic(err)
+	}
+	r, s, err := Sign(rand.Reader, privKey, zeroHash)
+	if err != nil {
+		panic(err)
+	}
+
+	r = r.Add(r, curve.Params().N)
+	if Verify(&privKey.PublicKey, zeroHash, r, s) {
+		t.Errorf("Verify with r=r+n succeeded: %T", curve)
+	}
+}
+
+func TestRMinusNSignature(t *testing.T) {
+	testAllCurves(t, testRMinusNSignature)
+}
+
+func testRMinusNSignature(t *testing.T, curve elliptic.Curve) {
+	zeroHash := make([]byte, 64)
+
+	privKey, err := GenerateKey(curve, rand.Reader)
+	if err != nil {
+		panic(err)
+	}
+	r, s, err := Sign(rand.Reader, privKey, zeroHash)
+	if err != nil {
+		panic(err)
+	}
+
+	r = r.Sub(r, curve.Params().N)
+	if Verify(&privKey.PublicKey, zeroHash, r, s) {
+		t.Errorf("Verify with r=r-n succeeded: %T", curve)
+	}
+}
+
+func randomPointForCurve(curve elliptic.Curve, rand io.Reader) error {
+	switch curve.Params() {
+	case elliptic.P224().Params():
+		_, _, err := randomPoint(p224(), rand)
+		return err
+	case elliptic.P256().Params():
+		_, _, err := randomPoint(p256(), rand)
+		return err
+	case elliptic.P384().Params():
+		_, _, err := randomPoint(p384(), rand)
+		return err
+	case elliptic.P521().Params():
+		_, _, err := randomPoint(p521(), rand)
+		return err
+	default:
+		panic("unknown curve")
+	}
+}
+
 func benchmarkAllCurves(b *testing.B, f func(*testing.B, elliptic.Curve)) {
 	tests := []struct {
 		name  string
 		curve elliptic.Curve
 	}{
 		{"P256", elliptic.P256()},
-		{"P224", elliptic.P224()},
 		{"P384", elliptic.P384()},
 		{"P521", elliptic.P521()},
 	}
@@ -347,7 +517,8 @@
 
 func BenchmarkSign(b *testing.B) {
 	benchmarkAllCurves(b, func(b *testing.B, curve elliptic.Curve) {
-		priv, err := GenerateKey(curve, rand.Reader)
+		r := bufio.NewReaderSize(rand.Reader, 1<<15)
+		priv, err := GenerateKey(curve, r)
 		if err != nil {
 			b.Fatal(err)
 		}
@@ -356,7 +527,7 @@
 		b.ReportAllocs()
 		b.ResetTimer()
 		for i := 0; i < b.N; i++ {
-			sig, err := SignASN1(rand.Reader, priv, hashed)
+			sig, err := SignASN1(r, priv, hashed)
 			if err != nil {
 				b.Fatal(err)
 			}
@@ -368,12 +539,13 @@
 
 func BenchmarkVerify(b *testing.B) {
 	benchmarkAllCurves(b, func(b *testing.B, curve elliptic.Curve) {
-		priv, err := GenerateKey(curve, rand.Reader)
+		r := bufio.NewReaderSize(rand.Reader, 1<<15)
+		priv, err := GenerateKey(curve, r)
 		if err != nil {
 			b.Fatal(err)
 		}
 		hashed := []byte("testing")
-		r, s, err := Sign(rand.Reader, priv, hashed)
+		sig, err := SignASN1(r, priv, hashed)
 		if err != nil {
 			b.Fatal(err)
 		}
@@ -381,7 +553,7 @@
 		b.ReportAllocs()
 		b.ResetTimer()
 		for i := 0; i < b.N; i++ {
-			if !Verify(&priv.PublicKey, hashed, r, s) {
+			if !VerifyASN1(&priv.PublicKey, hashed, sig) {
 				b.Fatal("verify failed")
 			}
 		}
@@ -390,10 +562,11 @@
 
 func BenchmarkGenerateKey(b *testing.B) {
 	benchmarkAllCurves(b, func(b *testing.B, curve elliptic.Curve) {
+		r := bufio.NewReaderSize(rand.Reader, 1<<15)
 		b.ReportAllocs()
 		b.ResetTimer()
 		for i := 0; i < b.N; i++ {
-			if _, err := GenerateKey(curve, rand.Reader); err != nil {
+			if _, err := GenerateKey(curve, r); err != nil {
 				b.Fatal(err)
 			}
 		}
diff --git a/src/crypto/ed25519/ed25519.go b/src/crypto/ed25519/ed25519.go
index d43dd12..a45d056 100644
--- a/src/crypto/ed25519/ed25519.go
+++ b/src/crypto/ed25519/ed25519.go
@@ -49,10 +49,10 @@
 	return bytes.Equal(pub, xx)
 }
 
-// PrivateKey is the type of Ed25519 private keys. It implements crypto.Signer.
+// PrivateKey is the type of Ed25519 private keys. It implements [crypto.Signer].
 type PrivateKey []byte
 
-// Public returns the PublicKey corresponding to priv.
+// Public returns the [PublicKey] corresponding to priv.
 func (priv PrivateKey) Public() crypto.PublicKey {
 	publicKey := make([]byte, PublicKeySize)
 	copy(publicKey, priv[32:])
@@ -72,26 +72,62 @@
 // interoperability with RFC 8032. RFC 8032's private keys correspond to seeds
 // in this package.
 func (priv PrivateKey) Seed() []byte {
-	seed := make([]byte, SeedSize)
-	copy(seed, priv[:32])
-	return seed
+	return bytes.Clone(priv[:SeedSize])
 }
 
-// Sign signs the given message with priv.
-// Ed25519 performs two passes over messages to be signed and therefore cannot
-// handle pre-hashed messages. Thus opts.HashFunc() must return zero to
-// indicate the message hasn't been hashed. This can be achieved by passing
-// crypto.Hash(0) as the value for opts.
+// Sign signs the given message with priv. rand is ignored.
+//
+// If opts.HashFunc() is [crypto.SHA512], the pre-hashed variant Ed25519ph is used
+// and message is expected to be a SHA-512 hash, otherwise opts.HashFunc() must
+// be [crypto.Hash](0) and the message must not be hashed, as Ed25519 performs two
+// passes over messages to be signed.
+//
+// A value of type [Options] can be used as opts, or crypto.Hash(0) or
+// crypto.SHA512 directly to select plain Ed25519 or Ed25519ph, respectively.
 func (priv PrivateKey) Sign(rand io.Reader, message []byte, opts crypto.SignerOpts) (signature []byte, err error) {
-	if opts.HashFunc() != crypto.Hash(0) {
-		return nil, errors.New("ed25519: cannot sign hashed message")
+	hash := opts.HashFunc()
+	context := ""
+	if opts, ok := opts.(*Options); ok {
+		context = opts.Context
 	}
-
-	return Sign(priv, message), nil
+	if l := len(context); l > 255 {
+		return nil, errors.New("ed25519: bad Ed25519ph context length: " + strconv.Itoa(l))
+	}
+	switch {
+	case hash == crypto.SHA512: // Ed25519ph
+		if l := len(message); l != sha512.Size {
+			return nil, errors.New("ed25519: bad Ed25519ph message hash length: " + strconv.Itoa(l))
+		}
+		signature := make([]byte, SignatureSize)
+		sign(signature, priv, message, domPrefixPh, context)
+		return signature, nil
+	case hash == crypto.Hash(0) && context != "": // Ed25519ctx
+		signature := make([]byte, SignatureSize)
+		sign(signature, priv, message, domPrefixCtx, context)
+		return signature, nil
+	case hash == crypto.Hash(0): // Ed25519
+		return Sign(priv, message), nil
+	default:
+		return nil, errors.New("ed25519: expected opts.HashFunc() zero (unhashed message, for standard Ed25519) or SHA-512 (for Ed25519ph)")
+	}
 }
 
+// Options can be used with [PrivateKey.Sign] or [VerifyWithOptions]
+// to select Ed25519 variants.
+type Options struct {
+	// Hash can be zero for regular Ed25519, or crypto.SHA512 for Ed25519ph.
+	Hash crypto.Hash
+
+	// Context, if not empty, selects Ed25519ctx or provides the context string
+	// for Ed25519ph. It can be at most 255 bytes in length.
+	Context string
+}
+
+// HashFunc returns o.Hash.
+func (o *Options) HashFunc() crypto.Hash { return o.Hash }
+
 // GenerateKey generates a public/private key pair using entropy from rand.
-// If rand is nil, crypto/rand.Reader will be used.
+// If rand is nil, [crypto/rand.Reader] will be used.
 func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) {
 	if rand == nil {
 		rand = cryptorand.Reader
@@ -110,7 +146,7 @@
 }
 
 // NewKeyFromSeed calculates a private key from a seed. It will panic if
-// len(seed) is not SeedSize. This function is provided for interoperability
+// len(seed) is not [SeedSize]. This function is provided for interoperability
 // with RFC 8032. RFC 8032's private keys correspond to seeds in this
 // package.
 func NewKeyFromSeed(seed []byte) PrivateKey {
@@ -139,16 +175,29 @@
 }
 
 // Sign signs the message with privateKey and returns a signature. It will
-// panic if len(privateKey) is not PrivateKeySize.
+// panic if len(privateKey) is not [PrivateKeySize].
 func Sign(privateKey PrivateKey, message []byte) []byte {
 	// Outline the function body so that the returned signature can be
 	// stack-allocated.
 	signature := make([]byte, SignatureSize)
-	sign(signature, privateKey, message)
+	sign(signature, privateKey, message, domPrefixPure, "")
 	return signature
 }
 
-func sign(signature, privateKey, message []byte) {
+// Domain separation prefixes used to disambiguate Ed25519/Ed25519ph/Ed25519ctx.
+// See RFC 8032, Section 2 and Section 5.1.
+const (
+	// domPrefixPure is empty for pure Ed25519.
+	domPrefixPure = ""
+	// domPrefixPh is dom2(phflag=1) for Ed25519ph. It must be followed by the
+	// uint8-length prefixed context.
+	domPrefixPh = "SigEd25519 no Ed25519 collisions\x01"
+	// domPrefixCtx is dom2(phflag=0) for Ed25519ctx. It must be followed by the
+	// uint8-length prefixed context.
+	domPrefixCtx = "SigEd25519 no Ed25519 collisions\x00"
+)
+
+func sign(signature, privateKey, message []byte, domPrefix, context string) {
 	if l := len(privateKey); l != PrivateKeySize {
 		panic("ed25519: bad private key length: " + strconv.Itoa(l))
 	}
@@ -162,6 +211,11 @@
 	prefix := h[32:]
 
 	mh := sha512.New()
+	if domPrefix != domPrefixPure {
+		mh.Write([]byte(domPrefix))
+		mh.Write([]byte{byte(len(context))})
+		mh.Write([]byte(context))
+	}
 	mh.Write(prefix)
 	mh.Write(message)
 	messageDigest := make([]byte, 0, sha512.Size)
@@ -174,6 +228,11 @@
 	R := (&edwards25519.Point{}).ScalarBaseMult(r)
 
 	kh := sha512.New()
+	if domPrefix != domPrefixPure {
+		kh.Write([]byte(domPrefix))
+		kh.Write([]byte{byte(len(context))})
+		kh.Write([]byte(context))
+	}
 	kh.Write(R.Bytes())
 	kh.Write(publicKey)
 	kh.Write(message)
@@ -191,8 +250,51 @@
 }
 
 // Verify reports whether sig is a valid signature of message by publicKey. It
-// will panic if len(publicKey) is not PublicKeySize.
+// will panic if len(publicKey) is not [PublicKeySize].
 func Verify(publicKey PublicKey, message, sig []byte) bool {
+	return verify(publicKey, message, sig, domPrefixPure, "")
+}
+
+// VerifyWithOptions reports whether sig is a valid signature of message by
+// publicKey. A valid signature is indicated by returning a nil error. It will
+// panic if len(publicKey) is not [PublicKeySize].
+//
+// If opts.Hash is [crypto.SHA512], the pre-hashed variant Ed25519ph is used and
+// message is expected to be a SHA-512 hash, otherwise opts.Hash must be
+// [crypto.Hash](0) and the message must not be hashed, as Ed25519 performs two
+// passes over messages to be signed.
+func VerifyWithOptions(publicKey PublicKey, message, sig []byte, opts *Options) error {
+	switch {
+	case opts.Hash == crypto.SHA512: // Ed25519ph
+		if l := len(message); l != sha512.Size {
+			return errors.New("ed25519: bad Ed25519ph message hash length: " + strconv.Itoa(l))
+		}
+		if l := len(opts.Context); l > 255 {
+			return errors.New("ed25519: bad Ed25519ph context length: " + strconv.Itoa(l))
+		}
+		if !verify(publicKey, message, sig, domPrefixPh, opts.Context) {
+			return errors.New("ed25519: invalid signature")
+		}
+		return nil
+	case opts.Hash == crypto.Hash(0) && opts.Context != "": // Ed25519ctx
+		if l := len(opts.Context); l > 255 {
+			return errors.New("ed25519: bad Ed25519ctx context length: " + strconv.Itoa(l))
+		}
+		if !verify(publicKey, message, sig, domPrefixCtx, opts.Context) {
+			return errors.New("ed25519: invalid signature")
+		}
+		return nil
+	case opts.Hash == crypto.Hash(0): // Ed25519
+		if !verify(publicKey, message, sig, domPrefixPure, "") {
+			return errors.New("ed25519: invalid signature")
+		}
+		return nil
+	default:
+		return errors.New("ed25519: expected opts.Hash zero (unhashed message, for standard Ed25519) or SHA-512 (for Ed25519ph)")
+	}
+}
+
+func verify(publicKey PublicKey, message, sig []byte, domPrefix, context string) bool {
 	if l := len(publicKey); l != PublicKeySize {
 		panic("ed25519: bad public key length: " + strconv.Itoa(l))
 	}
@@ -207,6 +309,11 @@
 	}
 
 	kh := sha512.New()
+	if domPrefix != domPrefixPure {
+		kh.Write([]byte(domPrefix))
+		kh.Write([]byte{byte(len(context))})
+		kh.Write([]byte(context))
+	}
 	kh.Write(sig[:32])
 	kh.Write(publicKey)
 	kh.Write(message)
diff --git a/src/crypto/ed25519/ed25519_test.go b/src/crypto/ed25519/ed25519_test.go
index 7c51817..47c8698 100644
--- a/src/crypto/ed25519/ed25519_test.go
+++ b/src/crypto/ed25519/ed25519_test.go
@@ -11,12 +11,37 @@
 	"crypto"
 	"crypto/internal/boring"
 	"crypto/rand"
+	"crypto/sha512"
 	"encoding/hex"
+	"internal/testenv"
+	"log"
 	"os"
 	"strings"
 	"testing"
 )
 
+func Example_ed25519ctx() {
+	pub, priv, err := GenerateKey(nil)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	msg := []byte("The quick brown fox jumps over the lazy dog")
+
+	sig, err := priv.Sign(nil, msg, &Options{
+		Context: "Example_ed25519ctx",
+	})
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	if err := VerifyWithOptions(pub, msg, sig, &Options{
+		Context: "Example_ed25519ctx",
+	}); err != nil {
+		log.Fatal("invalid signature")
+	}
+}
+
 type zeroReader struct{}
 
 func (zeroReader) Read(buf []byte) (int, error) {
@@ -42,6 +67,107 @@
 	}
 }
 
+func TestSignVerifyHashed(t *testing.T) {
+	// From RFC 8032, Section 7.3
+	key, _ := hex.DecodeString("833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42ec172b93ad5e563bf4932c70e1245034c35467ef2efd4d64ebf819683467e2bf")
+	expectedSig, _ := hex.DecodeString("98a70222f0b8121aa9d30f813d683f809e462b469c7ff87639499bb94e6dae4131f85042463c2a355a2003d062adf5aaa10b8c61e636062aaad11c2a26083406")
+	message, _ := hex.DecodeString("616263")
+
+	private := PrivateKey(key)
+	public := private.Public().(PublicKey)
+	hash := sha512.Sum512(message)
+	sig, err := private.Sign(nil, hash[:], crypto.SHA512)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !bytes.Equal(sig, expectedSig) {
+		t.Error("signature doesn't match test vector")
+	}
+	sig, err = private.Sign(nil, hash[:], &Options{Hash: crypto.SHA512})
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !bytes.Equal(sig, expectedSig) {
+		t.Error("signature doesn't match test vector")
+	}
+	if err := VerifyWithOptions(public, hash[:], sig, &Options{Hash: crypto.SHA512}); err != nil {
+		t.Errorf("valid signature rejected: %v", err)
+	}
+
+	if err := VerifyWithOptions(public, hash[:], sig, &Options{Hash: crypto.SHA256}); err == nil {
+		t.Errorf("expected error for wrong hash")
+	}
+
+	wrongHash := sha512.Sum512([]byte("wrong message"))
+	if VerifyWithOptions(public, wrongHash[:], sig, &Options{Hash: crypto.SHA512}) == nil {
+		t.Errorf("signature of different message accepted")
+	}
+
+	sig[0] ^= 0xff
+	if VerifyWithOptions(public, hash[:], sig, &Options{Hash: crypto.SHA512}) == nil {
+		t.Errorf("invalid signature accepted")
+	}
+	sig[0] ^= 0xff
+	sig[SignatureSize-1] ^= 0xff
+	if VerifyWithOptions(public, hash[:], sig, &Options{Hash: crypto.SHA512}) == nil {
+		t.Errorf("invalid signature accepted")
+	}
+
+	// The RFC provides no test vectors for Ed25519ph with context, so just sign
+	// and verify something.
+	sig, err = private.Sign(nil, hash[:], &Options{Hash: crypto.SHA512, Context: "123"})
+	if err != nil {
+		t.Fatal(err)
+	}
+	if err := VerifyWithOptions(public, hash[:], sig, &Options{Hash: crypto.SHA512, Context: "123"}); err != nil {
+		t.Errorf("valid signature rejected: %v", err)
+	}
+	if err := VerifyWithOptions(public, hash[:], sig, &Options{Hash: crypto.SHA512, Context: "321"}); err == nil {
+		t.Errorf("expected error for wrong context")
+	}
+	if err := VerifyWithOptions(public, hash[:], sig, &Options{Hash: crypto.SHA256, Context: "123"}); err == nil {
+		t.Errorf("expected error for wrong hash")
+	}
+}
+
+func TestSignVerifyContext(t *testing.T) {
+	// From RFC 8032, Section 7.2
+	key, _ := hex.DecodeString("0305334e381af78f141cb666f6199f57bc3495335a256a95bd2a55bf546663f6dfc9425e4f968f7f0c29f0259cf5f9aed6851c2bb4ad8bfb860cfee0ab248292")
+	expectedSig, _ := hex.DecodeString("55a4cc2f70a54e04288c5f4cd1e45a7bb520b36292911876cada7323198dd87a8b36950b95130022907a7fb7c4e9b2d5f6cca685a587b4b21f4b888e4e7edb0d")
+	message, _ := hex.DecodeString("f726936d19c800494e3fdaff20b276a8")
+	context := "foo"
+
+	private := PrivateKey(key)
+	public := private.Public().(PublicKey)
+	sig, err := private.Sign(nil, message, &Options{Context: context})
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !bytes.Equal(sig, expectedSig) {
+		t.Error("signature doesn't match test vector")
+	}
+	if err := VerifyWithOptions(public, message, sig, &Options{Context: context}); err != nil {
+		t.Errorf("valid signature rejected: %v", err)
+	}
+
+	if VerifyWithOptions(public, []byte("bar"), sig, &Options{Context: context}) == nil {
+		t.Errorf("signature of different message accepted")
+	}
+	if VerifyWithOptions(public, message, sig, &Options{Context: "bar"}) == nil {
+		t.Errorf("signature with different context accepted")
+	}
+
+	sig[0] ^= 0xff
+	if VerifyWithOptions(public, message, sig, &Options{Context: context}) == nil {
+		t.Errorf("invalid signature accepted")
+	}
+	sig[0] ^= 0xff
+	sig[SignatureSize-1] ^= 0xff
+	if VerifyWithOptions(public, message, sig, &Options{Context: context}) == nil {
+		t.Errorf("invalid signature accepted")
+	}
+}
+
 func TestCryptoSigner(t *testing.T) {
 	var zero zeroReader
 	public, private, _ := GenerateKey(zero)
@@ -65,6 +191,14 @@
 		t.Fatalf("error from Sign(): %s", err)
 	}
 
+	signature2, err := signer.Sign(zero, message, &Options{Hash: noHash})
+	if err != nil {
+		t.Fatalf("error from Sign(): %s", err)
+	}
+	if !bytes.Equal(signature, signature2) {
+		t.Errorf("signatures keys do not match")
+	}
+
 	if !Verify(public, message, signature) {
 		t.Errorf("Verify failed on signature from Sign()")
 	}
@@ -190,9 +324,8 @@
 	if boring.Enabled {
 		t.Skip("skipping allocations test with BoringCrypto")
 	}
-	if strings.HasSuffix(os.Getenv("GO_BUILDER_NAME"), "-noopt") {
-		t.Skip("skipping allocations test without relevant optimizations")
-	}
+	testenv.SkipIfOptimizationOff(t)
+
 	if allocs := testing.AllocsPerRun(100, func() {
 		seed := make([]byte, SeedSize)
 		message := []byte("Hello, world!")
diff --git a/src/crypto/elliptic/elliptic.go b/src/crypto/elliptic/elliptic.go
index 8c0b60b..6b07f5b 100644
--- a/src/crypto/elliptic/elliptic.go
+++ b/src/crypto/elliptic/elliptic.go
@@ -4,6 +4,9 @@
 
 // Package elliptic implements the standard NIST P-224, P-256, P-384, and P-521
 // elliptic curves over prime fields.
+//
+// The P224(), P256(), P384() and P521() values are necessary to use the crypto/ecdsa package.
+// Most other uses should migrate to the more efficient and safer crypto/ecdh package.
 package elliptic
 
 import (
@@ -23,16 +26,37 @@
 type Curve interface {
 	// Params returns the parameters for the curve.
 	Params() *CurveParams
+
 	// IsOnCurve reports whether the given (x,y) lies on the curve.
+	//
+	// Note: this is a low-level unsafe API. For ECDH, use the crypto/ecdh
+	// package. The NewPublicKey methods of NIST curves in crypto/ecdh accept
+	// the same encoding as the Unmarshal function, and perform on-curve checks.
 	IsOnCurve(x, y *big.Int) bool
-	// Add returns the sum of (x1,y1) and (x2,y2)
+
+	// Add returns the sum of (x1,y1) and (x2,y2).
+	//
+	// Note: this is a low-level unsafe API.
 	Add(x1, y1, x2, y2 *big.Int) (x, y *big.Int)
-	// Double returns 2*(x,y)
+
+	// Double returns 2*(x,y).
+	//
+	// Note: this is a low-level unsafe API.
 	Double(x1, y1 *big.Int) (x, y *big.Int)
-	// ScalarMult returns k*(Bx,By) where k is a number in big-endian form.
+
+	// ScalarMult returns k*(x,y) where k is an integer in big-endian form.
+	//
+	// Note: this is a low-level unsafe API. For ECDH, use the crypto/ecdh
+	// package. Most uses of ScalarMult can be replaced by a call to the ECDH
+	// methods of NIST curves in crypto/ecdh.
 	ScalarMult(x1, y1 *big.Int, k []byte) (x, y *big.Int)
+
 	// ScalarBaseMult returns k*G, where G is the base point of the group
 	// and k is an integer in big-endian form.
+	//
+	// Note: this is a low-level unsafe API. For ECDH, use the crypto/ecdh
+	// package. Most uses of ScalarBaseMult can be replaced by a call to the
+	// PrivateKey.PublicKey method in crypto/ecdh.
 	ScalarBaseMult(k []byte) (x, y *big.Int)
 }
 
@@ -40,6 +64,9 @@
 
 // GenerateKey returns a public/private key pair. The private key is
 // generated using the given reader, which must return random data.
+//
+// Note: for ECDH, use the GenerateKey methods of the crypto/ecdh package;
+// for ECDSA, use the GenerateKey function of the crypto/ecdsa package.
 func GenerateKey(curve Curve, rand io.Reader) (priv []byte, x, y *big.Int, err error) {
 	N := curve.Params().N
 	bitSize := N.BitLen()
@@ -71,6 +98,9 @@
 // Marshal converts a point on the curve into the uncompressed form specified in
 // SEC 1, Version 2.0, Section 2.3.3. If the point is not on the curve (or is
 // the conventional point at infinity), the behavior is undefined.
+//
+// Note: for ECDH, use the crypto/ecdh package. This function returns an
+// encoding equivalent to that of PublicKey.Bytes in crypto/ecdh.
 func Marshal(curve Curve, x, y *big.Int) []byte {
 	panicIfNotOnCurve(curve, x, y)
 
@@ -112,6 +142,9 @@
 // Unmarshal converts a point, serialized by Marshal, into an x, y pair. It is
 // an error if the point is not in uncompressed form, is not on the curve, or is
 // the point at infinity. On error, x = nil.
+//
+// Note: for ECDH, use the crypto/ecdh package. This function accepts an
+// encoding equivalent to that of the NewPublicKey methods in crypto/ecdh.
 func Unmarshal(curve Curve, data []byte) (x, y *big.Int) {
 	if c, ok := curve.(unmarshaler); ok {
 		return c.Unmarshal(data)
diff --git a/src/crypto/elliptic/nistec.go b/src/crypto/elliptic/nistec.go
index 9bb4600..d906c57 100644
--- a/src/crypto/elliptic/nistec.go
+++ b/src/crypto/elliptic/nistec.go
@@ -137,11 +137,10 @@
 }
 
 func (curve *nistCurve[Point]) pointFromAffine(x, y *big.Int) (p Point, err error) {
-	p = curve.newPoint()
 	// (0, 0) is by convention the point at infinity, which can't be represented
 	// in affine coordinates. See Issue 37294.
 	if x.Sign() == 0 && y.Sign() == 0 {
-		return p, nil
+		return curve.newPoint(), nil
 	}
 	// Reject values that would not get correctly encoded.
 	if x.Sign() < 0 || y.Sign() < 0 {
@@ -156,7 +155,7 @@
 	buf[0] = 4 // uncompressed point
 	x.FillBytes(buf[1 : 1+byteLen])
 	y.FillBytes(buf[1+byteLen : 1+2*byteLen])
-	return p.SetBytes(buf)
+	return curve.newPoint().SetBytes(buf)
 }
 
 func (curve *nistCurve[Point]) pointToAffine(p Point) (x, y *big.Int) {
diff --git a/src/crypto/elliptic/params.go b/src/crypto/elliptic/params.go
index 0ed929d..c4e9784 100644
--- a/src/crypto/elliptic/params.go
+++ b/src/crypto/elliptic/params.go
@@ -8,6 +8,9 @@
 
 // CurveParams contains the parameters of an elliptic curve and also provides
 // a generic, non-constant time implementation of Curve.
+//
+// Note: Custom curves (those not returned by P224(), P256(), P384(), and P521())
+// are not guaranteed to provide any security property.
 type CurveParams struct {
 	P       *big.Int // the order of the underlying field
 	N       *big.Int // the order of the base point
@@ -43,6 +46,12 @@
 	return x3
 }
 
+// IsOnCurve implements Curve.IsOnCurve.
+//
+// Note: the CurveParams methods are not guaranteed to
+// provide any security property. For ECDH, use the crypto/ecdh package.
+// For ECDSA, use the crypto/ecdsa package with a Curve value returned directly
+// from P224(), P256(), P384(), or P521().
 func (curve *CurveParams) IsOnCurve(x, y *big.Int) bool {
 	// If there is a dedicated constant-time implementation for this curve operation,
 	// use that instead of the generic one.
@@ -91,6 +100,12 @@
 	return
 }
 
+// Add implements Curve.Add.
+//
+// Note: the CurveParams methods are not guaranteed to
+// provide any security property. For ECDH, use the crypto/ecdh package.
+// For ECDSA, use the crypto/ecdsa package with a Curve value returned directly
+// from P224(), P256(), P384(), or P521().
 func (curve *CurveParams) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) {
 	// If there is a dedicated constant-time implementation for this curve operation,
 	// use that instead of the generic one.
@@ -183,6 +198,12 @@
 	return x3, y3, z3
 }
 
+// Double implements Curve.Double.
+//
+// Note: the CurveParams methods are not guaranteed to
+// provide any security property. For ECDH, use the crypto/ecdh package.
+// For ECDSA, use the crypto/ecdsa package with a Curve value returned directly
+// from P224(), P256(), P384(), or P521().
 func (curve *CurveParams) Double(x1, y1 *big.Int) (*big.Int, *big.Int) {
 	// If there is a dedicated constant-time implementation for this curve operation,
 	// use that instead of the generic one.
@@ -256,6 +277,12 @@
 	return x3, y3, z3
 }
 
+// ScalarMult implements Curve.ScalarMult.
+//
+// Note: the CurveParams methods are not guaranteed to
+// provide any security property. For ECDH, use the crypto/ecdh package.
+// For ECDSA, use the crypto/ecdsa package with a Curve value returned directly
+// from P224(), P256(), P384(), or P521().
 func (curve *CurveParams) ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big.Int) {
 	// If there is a dedicated constant-time implementation for this curve operation,
 	// use that instead of the generic one.
@@ -280,6 +307,12 @@
 	return curve.affineFromJacobian(x, y, z)
 }
 
+// ScalarBaseMult implements Curve.ScalarBaseMult.
+//
+// Note: the CurveParams methods are not guaranteed to
+// provide any security property. For ECDH, use the crypto/ecdh package.
+// For ECDSA, use the crypto/ecdsa package with a Curve value returned directly
+// from P224(), P256(), P384(), or P521().
 func (curve *CurveParams) ScalarBaseMult(k []byte) (*big.Int, *big.Int) {
 	// If there is a dedicated constant-time implementation for this curve operation,
 	// use that instead of the generic one.
diff --git a/src/crypto/internal/alias/alias.go b/src/crypto/internal/alias/alias.go
new file mode 100644
index 0000000..936cc25
--- /dev/null
+++ b/src/crypto/internal/alias/alias.go
@@ -0,0 +1,30 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package alias implements memory alaising tests.
+// This code also exists as golang.org/x/crypto/internal/alias.
+package alias
+
+import "unsafe"
+
+// AnyOverlap reports whether x and y share memory at any (not necessarily
+// corresponding) index. The memory beyond the slice length is ignored.
+func AnyOverlap(x, y []byte) bool {
+	return len(x) > 0 && len(y) > 0 &&
+		uintptr(unsafe.Pointer(&x[0])) <= uintptr(unsafe.Pointer(&y[len(y)-1])) &&
+		uintptr(unsafe.Pointer(&y[0])) <= uintptr(unsafe.Pointer(&x[len(x)-1]))
+}
+
+// InexactOverlap reports whether x and y share memory at any non-corresponding
+// index. The memory beyond the slice length is ignored. Note that x and y can
+// have different lengths and still not have any inexact overlap.
+//
+// InexactOverlap can be used to implement the requirements of the crypto/cipher
+// AEAD, Block, BlockMode and Stream interfaces.
+func InexactOverlap(x, y []byte) bool {
+	if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] {
+		return false
+	}
+	return AnyOverlap(x, y)
+}
diff --git a/src/crypto/internal/alias/alias_test.go b/src/crypto/internal/alias/alias_test.go
new file mode 100644
index 0000000..a68fb33
--- /dev/null
+++ b/src/crypto/internal/alias/alias_test.go
@@ -0,0 +1,46 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package alias
+
+import "testing"
+
+var a, b [100]byte
+
+var aliasingTests = []struct {
+	x, y                       []byte
+	anyOverlap, inexactOverlap bool
+}{
+	{a[:], b[:], false, false},
+	{a[:], b[:0], false, false},
+	{a[:], b[:50], false, false},
+	{a[40:50], a[50:60], false, false},
+	{a[40:50], a[60:70], false, false},
+	{a[:51], a[50:], true, true},
+	{a[:], a[:], true, false},
+	{a[:50], a[:60], true, false},
+	{a[:], nil, false, false},
+	{nil, nil, false, false},
+	{a[:], a[:0], false, false},
+	{a[:10], a[:10:20], true, false},
+	{a[:10], a[5:10:20], true, true},
+}
+
+func testAliasing(t *testing.T, i int, x, y []byte, anyOverlap, inexactOverlap bool) {
+	any := AnyOverlap(x, y)
+	if any != anyOverlap {
+		t.Errorf("%d: wrong AnyOverlap result, expected %v, got %v", i, anyOverlap, any)
+	}
+	inexact := InexactOverlap(x, y)
+	if inexact != inexactOverlap {
+		t.Errorf("%d: wrong InexactOverlap result, expected %v, got %v", i, inexactOverlap, any)
+	}
+}
+
+func TestAliasing(t *testing.T) {
+	for i, tt := range aliasingTests {
+		testAliasing(t, i, tt.x, tt.y, tt.anyOverlap, tt.inexactOverlap)
+		testAliasing(t, i, tt.y, tt.x, tt.anyOverlap, tt.inexactOverlap)
+	}
+}
diff --git a/src/crypto/internal/bigmod/_asm/go.mod b/src/crypto/internal/bigmod/_asm/go.mod
new file mode 100644
index 0000000..1ce2b5e
--- /dev/null
+++ b/src/crypto/internal/bigmod/_asm/go.mod
@@ -0,0 +1,12 @@
+module asm
+
+go 1.19
+
+require github.com/mmcloughlin/avo v0.4.0
+
+require (
+	golang.org/x/mod v0.4.2 // indirect
+	golang.org/x/sys v0.0.0-20211030160813-b3129d9d1021 // indirect
+	golang.org/x/tools v0.1.7 // indirect
+	golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
+)
diff --git a/src/crypto/internal/bigmod/_asm/go.sum b/src/crypto/internal/bigmod/_asm/go.sum
new file mode 100644
index 0000000..b4b5914
--- /dev/null
+++ b/src/crypto/internal/bigmod/_asm/go.sum
@@ -0,0 +1,32 @@
+github.com/mmcloughlin/avo v0.4.0 h1:jeHDRktVD+578ULxWpQHkilor6pkdLF7u7EiTzDbfcU=
+github.com/mmcloughlin/avo v0.4.0/go.mod h1:RW9BfYA3TgO9uCdNrKU2h6J8cPD8ZLznvfgHAeszb1s=
+github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
+golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
+golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211030160813-b3129d9d1021 h1:giLT+HuUP/gXYrG2Plg9WTjj4qhfgaW424ZIFog3rlk=
+golang.org/x/sys v0.0.0-20211030160813-b3129d9d1021/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.1.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ=
+golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
diff --git a/src/crypto/internal/bigmod/_asm/nat_amd64_asm.go b/src/crypto/internal/bigmod/_asm/nat_amd64_asm.go
new file mode 100644
index 0000000..5690f04
--- /dev/null
+++ b/src/crypto/internal/bigmod/_asm/nat_amd64_asm.go
@@ -0,0 +1,131 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	. "github.com/mmcloughlin/avo/build"
+	. "github.com/mmcloughlin/avo/operand"
+	. "github.com/mmcloughlin/avo/reg"
+)
+
+//go:generate go run . -out ../nat_amd64.s -stubs ../nat_amd64.go -pkg bigmod
+
+func main() {
+	Package("crypto/internal/bigmod")
+	ConstraintExpr("amd64,gc,!purego")
+
+	Implement("montgomeryLoop")
+	Pragma("noescape")
+
+	size := Load(Param("d").Len(), GP64())
+	d := Mem{Base: Load(Param("d").Base(), GP64())}
+	b := Mem{Base: Load(Param("b").Base(), GP64())}
+	m := Mem{Base: Load(Param("m").Base(), GP64())}
+	m0inv := Load(Param("m0inv"), GP64())
+
+	overflow := zero()
+	i := zero()
+	Label("outerLoop")
+
+	ai := Load(Param("a").Base(), GP64())
+	MOVQ(Mem{Base: ai}.Idx(i, 8), ai)
+
+	z := uint128{GP64(), GP64()}
+	mul64(z, b, ai)
+	add64(z, d)
+	f := GP64()
+	MOVQ(m0inv, f)
+	IMULQ(z.lo, f)
+	_MASK(f)
+	addMul64(z, m, f)
+	carry := shiftBy63(z)
+
+	j := zero()
+	INCQ(j)
+	JMP(LabelRef("innerLoopCondition"))
+	Label("innerLoop")
+
+	// z = d[j] + a[i] * b[j] + f * m[j] + carry
+	z = uint128{GP64(), GP64()}
+	mul64(z, b.Idx(j, 8), ai)
+	addMul64(z, m.Idx(j, 8), f)
+	add64(z, d.Idx(j, 8))
+	add64(z, carry)
+	// d[j-1] = z_lo & _MASK
+	storeMasked(z.lo, d.Idx(j, 8).Offset(-8))
+	// carry = z_hi<<1 | z_lo>>_W
+	MOVQ(shiftBy63(z), carry)
+
+	INCQ(j)
+	Label("innerLoopCondition")
+	CMPQ(size, j)
+	JGT(LabelRef("innerLoop"))
+
+	ADDQ(carry, overflow)
+	storeMasked(overflow, d.Idx(size, 8).Offset(-8))
+	SHRQ(Imm(63), overflow)
+
+	INCQ(i)
+	CMPQ(size, i)
+	JGT(LabelRef("outerLoop"))
+
+	Store(overflow, ReturnIndex(0))
+	RET()
+	Generate()
+}
+
+// zero zeroes a new register and returns it.
+func zero() Register {
+	r := GP64()
+	XORQ(r, r)
+	return r
+}
+
+// _MASK masks out the top bit of r.
+func _MASK(r Register) {
+	BTRQ(Imm(63), r)
+}
+
+type uint128 struct {
+	hi, lo GPVirtual
+}
+
+// storeMasked stores _MASK(src) in dst. It doesn't modify src.
+func storeMasked(src, dst Op) {
+	out := GP64()
+	MOVQ(src, out)
+	_MASK(out)
+	MOVQ(out, dst)
+}
+
+// shiftBy63 returns z >> 63. It reuses z.lo.
+func shiftBy63(z uint128) Register {
+	SHRQ(Imm(63), z.hi, z.lo)
+	result := z.lo
+	z.hi, z.lo = nil, nil
+	return result
+}
+
+// add64 sets r to r + a.
+func add64(r uint128, a Op) {
+	ADDQ(a, r.lo)
+	ADCQ(Imm(0), r.hi)
+}
+
+// mul64 sets r to a * b.
+func mul64(r uint128, a, b Op) {
+	MOVQ(a, RAX)
+	MULQ(b) // RDX, RAX = RAX * b
+	MOVQ(RAX, r.lo)
+	MOVQ(RDX, r.hi)
+}
+
+// addMul64 sets r to r + a * b.
+func addMul64(r uint128, a, b Op) {
+	MOVQ(a, RAX)
+	MULQ(b) // RDX, RAX = RAX * b
+	ADDQ(RAX, r.lo)
+	ADCQ(RDX, r.hi)
+}
diff --git a/src/crypto/internal/bigmod/nat.go b/src/crypto/internal/bigmod/nat.go
new file mode 100644
index 0000000..804316f
--- /dev/null
+++ b/src/crypto/internal/bigmod/nat.go
@@ -0,0 +1,703 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package bigmod
+
+import (
+	"errors"
+	"math/big"
+	"math/bits"
+)
+
+const (
+	// _W is the number of bits we use for our limbs.
+	_W = bits.UintSize - 1
+	// _MASK selects _W bits from a full machine word.
+	_MASK = (1 << _W) - 1
+)
+
+// choice represents a constant-time boolean. The value of choice is always
+// either 1 or 0. We use an int instead of bool in order to make decisions in
+// constant time by turning it into a mask.
+type choice uint
+
+func not(c choice) choice { return 1 ^ c }
+
+const yes = choice(1)
+const no = choice(0)
+
+// ctSelect returns x if on == 1, and y if on == 0. The execution time of this
+// function does not depend on its inputs. If on is any value besides 1 or 0,
+// the result is undefined.
+func ctSelect(on choice, x, y uint) uint {
+	// When on == 1, mask is 0b111..., otherwise mask is 0b000...
+	mask := -uint(on)
+	// When mask is all zeros, we just have y, otherwise, y cancels with itself.
+	return y ^ (mask & (y ^ x))
+}
+
+// ctEq returns 1 if x == y, and 0 otherwise. The execution time of this
+// function does not depend on its inputs.
+func ctEq(x, y uint) choice {
+	// If x != y, then either x - y or y - x will generate a carry.
+	_, c1 := bits.Sub(x, y, 0)
+	_, c2 := bits.Sub(y, x, 0)
+	return not(choice(c1 | c2))
+}
+
+// ctGeq returns 1 if x >= y, and 0 otherwise. The execution time of this
+// function does not depend on its inputs.
+func ctGeq(x, y uint) choice {
+	// If x < y, then x - y generates a carry.
+	_, carry := bits.Sub(x, y, 0)
+	return not(choice(carry))
+}
+
+// Nat represents an arbitrary natural number
+//
+// Each Nat has an announced length, which is the number of limbs it has stored.
+// Operations on this number are allowed to leak this length, but will not leak
+// any information about the values contained in those limbs.
+type Nat struct {
+	// limbs is a little-endian representation in base 2^W with
+	// W = bits.UintSize - 1. The top bit is always unset between operations.
+	//
+	// The top bit is left unset to optimize Montgomery multiplication, in the
+	// inner loop of exponentiation. Using fully saturated limbs would leave us
+	// working with 129-bit numbers on 64-bit platforms, wasting a lot of space,
+	// and thus time.
+	limbs []uint
+}
+
+// preallocTarget is the size in bits of the numbers used to implement the most
+// common and most performant RSA key size. It's also enough to cover some of
+// the operations of key sizes up to 4096.
+const preallocTarget = 2048
+const preallocLimbs = (preallocTarget + _W - 1) / _W
+
+// NewNat returns a new nat with a size of zero, just like new(Nat), but with
+// the preallocated capacity to hold a number of up to preallocTarget bits.
+// NewNat inlines, so the allocation can live on the stack.
+func NewNat() *Nat {
+	limbs := make([]uint, 0, preallocLimbs)
+	return &Nat{limbs}
+}
+
+// expand expands x to n limbs, leaving its value unchanged.
+func (x *Nat) expand(n int) *Nat {
+	if len(x.limbs) > n {
+		panic("bigmod: internal error: shrinking nat")
+	}
+	if cap(x.limbs) < n {
+		newLimbs := make([]uint, n)
+		copy(newLimbs, x.limbs)
+		x.limbs = newLimbs
+		return x
+	}
+	extraLimbs := x.limbs[len(x.limbs):n]
+	for i := range extraLimbs {
+		extraLimbs[i] = 0
+	}
+	x.limbs = x.limbs[:n]
+	return x
+}
+
+// reset returns a zero nat of n limbs, reusing x's storage if n <= cap(x.limbs).
+func (x *Nat) reset(n int) *Nat {
+	if cap(x.limbs) < n {
+		x.limbs = make([]uint, n)
+		return x
+	}
+	for i := range x.limbs {
+		x.limbs[i] = 0
+	}
+	x.limbs = x.limbs[:n]
+	return x
+}
+
+// set assigns x = y, optionally resizing x to the appropriate size.
+func (x *Nat) set(y *Nat) *Nat {
+	x.reset(len(y.limbs))
+	copy(x.limbs, y.limbs)
+	return x
+}
+
+// setBig assigns x = n, optionally resizing n to the appropriate size.
+//
+// The announced length of x is set based on the actual bit size of the input,
+// ignoring leading zeroes.
+func (x *Nat) setBig(n *big.Int) *Nat {
+	requiredLimbs := (n.BitLen() + _W - 1) / _W
+	x.reset(requiredLimbs)
+
+	outI := 0
+	shift := 0
+	limbs := n.Bits()
+	for i := range limbs {
+		xi := uint(limbs[i])
+		x.limbs[outI] |= (xi << shift) & _MASK
+		outI++
+		if outI == requiredLimbs {
+			return x
+		}
+		x.limbs[outI] = xi >> (_W - shift)
+		shift++ // this assumes bits.UintSize - _W = 1
+		if shift == _W {
+			shift = 0
+			outI++
+		}
+	}
+	return x
+}
+
+// Bytes returns x as a zero-extended big-endian byte slice. The size of the
+// slice will match the size of m.
+//
+// x must have the same size as m and it must be reduced modulo m.
+func (x *Nat) Bytes(m *Modulus) []byte {
+	bytes := make([]byte, m.Size())
+	shift := 0
+	outI := len(bytes) - 1
+	for _, limb := range x.limbs {
+		remainingBits := _W
+		for remainingBits >= 8 {
+			bytes[outI] |= byte(limb) << shift
+			consumed := 8 - shift
+			limb >>= consumed
+			remainingBits -= consumed
+			shift = 0
+			outI--
+			if outI < 0 {
+				return bytes
+			}
+		}
+		bytes[outI] = byte(limb)
+		shift = remainingBits
+	}
+	return bytes
+}
+
+// SetBytes assigns x = b, where b is a slice of big-endian bytes.
+// SetBytes returns an error if b >= m.
+//
+// The output will be resized to the size of m and overwritten.
+func (x *Nat) SetBytes(b []byte, m *Modulus) (*Nat, error) {
+	if err := x.setBytes(b, m); err != nil {
+		return nil, err
+	}
+	if x.cmpGeq(m.nat) == yes {
+		return nil, errors.New("input overflows the modulus")
+	}
+	return x, nil
+}
+
+// SetOverflowingBytes assigns x = b, where b is a slice of big-endian bytes. SetOverflowingBytes
+// returns an error if b has a longer bit length than m, but reduces overflowing
+// values up to 2^⌈log2(m)⌉ - 1.
+//
+// The output will be resized to the size of m and overwritten.
+func (x *Nat) SetOverflowingBytes(b []byte, m *Modulus) (*Nat, error) {
+	if err := x.setBytes(b, m); err != nil {
+		return nil, err
+	}
+	leading := _W - bitLen(x.limbs[len(x.limbs)-1])
+	if leading < m.leading {
+		return nil, errors.New("input overflows the modulus")
+	}
+	x.sub(x.cmpGeq(m.nat), m.nat)
+	return x, nil
+}
+
+func (x *Nat) setBytes(b []byte, m *Modulus) error {
+	outI := 0
+	shift := 0
+	x.resetFor(m)
+	for i := len(b) - 1; i >= 0; i-- {
+		bi := b[i]
+		x.limbs[outI] |= uint(bi) << shift
+		shift += 8
+		if shift >= _W {
+			shift -= _W
+			x.limbs[outI] &= _MASK
+			overflow := bi >> (8 - shift)
+			outI++
+			if outI >= len(x.limbs) {
+				if overflow > 0 || i > 0 {
+					return errors.New("input overflows the modulus")
+				}
+				break
+			}
+			x.limbs[outI] = uint(overflow)
+		}
+	}
+	return nil
+}
+
+// Equal returns 1 if x == y, and 0 otherwise.
+//
+// Both operands must have the same announced length.
+func (x *Nat) Equal(y *Nat) choice {
+	// Eliminate bounds checks in the loop.
+	size := len(x.limbs)
+	xLimbs := x.limbs[:size]
+	yLimbs := y.limbs[:size]
+
+	equal := yes
+	for i := 0; i < size; i++ {
+		equal &= ctEq(xLimbs[i], yLimbs[i])
+	}
+	return equal
+}
+
+// IsZero returns 1 if x == 0, and 0 otherwise.
+func (x *Nat) IsZero() choice {
+	// Eliminate bounds checks in the loop.
+	size := len(x.limbs)
+	xLimbs := x.limbs[:size]
+
+	zero := yes
+	for i := 0; i < size; i++ {
+		zero &= ctEq(xLimbs[i], 0)
+	}
+	return zero
+}
+
+// cmpGeq returns 1 if x >= y, and 0 otherwise.
+//
+// Both operands must have the same announced length.
+func (x *Nat) cmpGeq(y *Nat) choice {
+	// Eliminate bounds checks in the loop.
+	size := len(x.limbs)
+	xLimbs := x.limbs[:size]
+	yLimbs := y.limbs[:size]
+
+	var c uint
+	for i := 0; i < size; i++ {
+		c = (xLimbs[i] - yLimbs[i] - c) >> _W
+	}
+	// If there was a carry, then subtracting y underflowed, so
+	// x is not greater than or equal to y.
+	return not(choice(c))
+}
+
+// assign sets x <- y if on == 1, and does nothing otherwise.
+//
+// Both operands must have the same announced length.
+func (x *Nat) assign(on choice, y *Nat) *Nat {
+	// Eliminate bounds checks in the loop.
+	size := len(x.limbs)
+	xLimbs := x.limbs[:size]
+	yLimbs := y.limbs[:size]
+
+	for i := 0; i < size; i++ {
+		xLimbs[i] = ctSelect(on, yLimbs[i], xLimbs[i])
+	}
+	return x
+}
+
+// add computes x += y if on == 1, and does nothing otherwise. It returns the
+// carry of the addition regardless of on.
+//
+// Both operands must have the same announced length.
+func (x *Nat) add(on choice, y *Nat) (c uint) {
+	// Eliminate bounds checks in the loop.
+	size := len(x.limbs)
+	xLimbs := x.limbs[:size]
+	yLimbs := y.limbs[:size]
+
+	for i := 0; i < size; i++ {
+		res := xLimbs[i] + yLimbs[i] + c
+		xLimbs[i] = ctSelect(on, res&_MASK, xLimbs[i])
+		c = res >> _W
+	}
+	return
+}
+
+// sub computes x -= y if on == 1, and does nothing otherwise. It returns the
+// borrow of the subtraction regardless of on.
+//
+// Both operands must have the same announced length.
+func (x *Nat) sub(on choice, y *Nat) (c uint) {
+	// Eliminate bounds checks in the loop.
+	size := len(x.limbs)
+	xLimbs := x.limbs[:size]
+	yLimbs := y.limbs[:size]
+
+	for i := 0; i < size; i++ {
+		res := xLimbs[i] - yLimbs[i] - c
+		xLimbs[i] = ctSelect(on, res&_MASK, xLimbs[i])
+		c = res >> _W
+	}
+	return
+}
+
+// Modulus is used for modular arithmetic, precomputing relevant constants.
+//
+// Moduli are assumed to be odd numbers. Moduli can also leak the exact
+// number of bits needed to store their value, and are stored without padding.
+//
+// Their actual value is still kept secret.
+type Modulus struct {
+	// The underlying natural number for this modulus.
+	//
+	// This will be stored without any padding, and shouldn't alias with any
+	// other natural number being used.
+	nat     *Nat
+	leading int  // number of leading zeros in the modulus
+	m0inv   uint // -nat.limbs[0]⁻¹ mod _W
+	rr      *Nat // R*R for montgomeryRepresentation
+}
+
+// rr returns R*R with R = 2^(_W * n) and n = len(m.nat.limbs).
+func rr(m *Modulus) *Nat {
+	rr := NewNat().ExpandFor(m)
+	// R*R is 2^(2 * _W * n). We can safely get 2^(_W * (n - 1)) by setting the
+	// most significant limb to 1. We then get to R*R by shifting left by _W
+	// n + 1 times.
+	n := len(rr.limbs)
+	rr.limbs[n-1] = 1
+	for i := n - 1; i < 2*n; i++ {
+		rr.shiftIn(0, m) // x = x * 2^_W mod m
+	}
+	return rr
+}
+
+// minusInverseModW computes -x⁻¹ mod _W with x odd.
+//
+// This operation is used to precompute a constant involved in Montgomery
+// multiplication.
+func minusInverseModW(x uint) uint {
+	// Every iteration of this loop doubles the least-significant bits of
+	// correct inverse in y. The first three bits are already correct (1⁻¹ = 1,
+	// 3⁻¹ = 3, 5⁻¹ = 5, and 7⁻¹ = 7 mod 8), so doubling five times is enough
+	// for 61 bits (and wastes only one iteration for 31 bits).
+	//
+	// See https://crypto.stackexchange.com/a/47496.
+	y := x
+	for i := 0; i < 5; i++ {
+		y = y * (2 - x*y)
+	}
+	return (1 << _W) - (y & _MASK)
+}
+
+// NewModulusFromBig creates a new Modulus from a [big.Int].
+//
+// The Int must be odd. The number of significant bits must be leakable.
+func NewModulusFromBig(n *big.Int) *Modulus {
+	m := &Modulus{}
+	m.nat = NewNat().setBig(n)
+	m.leading = _W - bitLen(m.nat.limbs[len(m.nat.limbs)-1])
+	m.m0inv = minusInverseModW(m.nat.limbs[0])
+	m.rr = rr(m)
+	return m
+}
+
+// bitLen is a version of bits.Len that only leaks the bit length of n, but not
+// its value. bits.Len and bits.LeadingZeros use a lookup table for the
+// low-order bits on some architectures.
+func bitLen(n uint) int {
+	var len int
+	// We assume, here and elsewhere, that comparison to zero is constant time
+	// with respect to different non-zero values.
+	for n != 0 {
+		len++
+		n >>= 1
+	}
+	return len
+}
+
+// Size returns the size of m in bytes.
+func (m *Modulus) Size() int {
+	return (m.BitLen() + 7) / 8
+}
+
+// BitLen returns the size of m in bits.
+func (m *Modulus) BitLen() int {
+	return len(m.nat.limbs)*_W - int(m.leading)
+}
+
+// Nat returns m as a Nat. The return value must not be written to.
+func (m *Modulus) Nat() *Nat {
+	return m.nat
+}
+
+// shiftIn calculates x = x << _W + y mod m.
+//
+// This assumes that x is already reduced mod m, and that y < 2^_W.
+func (x *Nat) shiftIn(y uint, m *Modulus) *Nat {
+	d := NewNat().resetFor(m)
+
+	// Eliminate bounds checks in the loop.
+	size := len(m.nat.limbs)
+	xLimbs := x.limbs[:size]
+	dLimbs := d.limbs[:size]
+	mLimbs := m.nat.limbs[:size]
+
+	// Each iteration of this loop computes x = 2x + b mod m, where b is a bit
+	// from y. Effectively, it left-shifts x and adds y one bit at a time,
+	// reducing it every time.
+	//
+	// To do the reduction, each iteration computes both 2x + b and 2x + b - m.
+	// The next iteration (and finally the return line) will use either result
+	// based on whether the subtraction underflowed.
+	needSubtraction := no
+	for i := _W - 1; i >= 0; i-- {
+		carry := (y >> i) & 1
+		var borrow uint
+		for i := 0; i < size; i++ {
+			l := ctSelect(needSubtraction, dLimbs[i], xLimbs[i])
+
+			res := l<<1 + carry
+			xLimbs[i] = res & _MASK
+			carry = res >> _W
+
+			res = xLimbs[i] - mLimbs[i] - borrow
+			dLimbs[i] = res & _MASK
+			borrow = res >> _W
+		}
+		// See Add for how carry (aka overflow), borrow (aka underflow), and
+		// needSubtraction relate.
+		needSubtraction = ctEq(carry, borrow)
+	}
+	return x.assign(needSubtraction, d)
+}
+
+// Mod calculates out = x mod m.
+//
+// This works regardless how large the value of x is.
+//
+// The output will be resized to the size of m and overwritten.
+func (out *Nat) Mod(x *Nat, m *Modulus) *Nat {
+	out.resetFor(m)
+	// Working our way from the most significant to the least significant limb,
+	// we can insert each limb at the least significant position, shifting all
+	// previous limbs left by _W. This way each limb will get shifted by the
+	// correct number of bits. We can insert at least N - 1 limbs without
+	// overflowing m. After that, we need to reduce every time we shift.
+	i := len(x.limbs) - 1
+	// For the first N - 1 limbs we can skip the actual shifting and position
+	// them at the shifted position, which starts at min(N - 2, i).
+	start := len(m.nat.limbs) - 2
+	if i < start {
+		start = i
+	}
+	for j := start; j >= 0; j-- {
+		out.limbs[j] = x.limbs[i]
+		i--
+	}
+	// We shift in the remaining limbs, reducing modulo m each time.
+	for i >= 0 {
+		out.shiftIn(x.limbs[i], m)
+		i--
+	}
+	return out
+}
+
+// ExpandFor ensures out has the right size to work with operations modulo m.
+//
+// The announced size of out must be smaller than or equal to that of m.
+func (out *Nat) ExpandFor(m *Modulus) *Nat {
+	return out.expand(len(m.nat.limbs))
+}
+
+// resetFor ensures out has the right size to work with operations modulo m.
+//
+// out is zeroed and may start at any size.
+func (out *Nat) resetFor(m *Modulus) *Nat {
+	return out.reset(len(m.nat.limbs))
+}
+
+// Sub computes x = x - y mod m.
+//
+// The length of both operands must be the same as the modulus. Both operands
+// must already be reduced modulo m.
+func (x *Nat) Sub(y *Nat, m *Modulus) *Nat {
+	underflow := x.sub(yes, y)
+	// If the subtraction underflowed, add m.
+	x.add(choice(underflow), m.nat)
+	return x
+}
+
+// Add computes x = x + y mod m.
+//
+// The length of both operands must be the same as the modulus. Both operands
+// must already be reduced modulo m.
+func (x *Nat) Add(y *Nat, m *Modulus) *Nat {
+	overflow := x.add(yes, y)
+	underflow := not(x.cmpGeq(m.nat)) // x < m
+
+	// Three cases are possible:
+	//
+	//   - overflow = 0, underflow = 0
+	//
+	// In this case, addition fits in our limbs, but we can still subtract away
+	// m without an underflow, so we need to perform the subtraction to reduce
+	// our result.
+	//
+	//   - overflow = 0, underflow = 1
+	//
+	// The addition fits in our limbs, but we can't subtract m without
+	// underflowing. The result is already reduced.
+	//
+	//   - overflow = 1, underflow = 1
+	//
+	// The addition does not fit in our limbs, and the subtraction's borrow
+	// would cancel out with the addition's carry. We need to subtract m to
+	// reduce our result.
+	//
+	// The overflow = 1, underflow = 0 case is not possible, because y is at
+	// most m - 1, and if adding m - 1 overflows, then subtracting m must
+	// necessarily underflow.
+	needSubtraction := ctEq(overflow, uint(underflow))
+
+	x.sub(needSubtraction, m.nat)
+	return x
+}
+
+// montgomeryRepresentation calculates x = x * R mod m, with R = 2^(_W * n) and
+// n = len(m.nat.limbs).
+//
+// Faster Montgomery multiplication replaces standard modular multiplication for
+// numbers in this representation.
+//
+// This assumes that x is already reduced mod m.
+func (x *Nat) montgomeryRepresentation(m *Modulus) *Nat {
+	// A Montgomery multiplication (which computes a * b / R) by R * R works out
+	// to a multiplication by R, which takes the value out of the Montgomery domain.
+	return x.montgomeryMul(NewNat().set(x), m.rr, m)
+}
+
+// montgomeryReduction calculates x = x / R mod m, with R = 2^(_W * n) and
+// n = len(m.nat.limbs).
+//
+// This assumes that x is already reduced mod m.
+func (x *Nat) montgomeryReduction(m *Modulus) *Nat {
+	// By Montgomery multiplying with 1 not in Montgomery representation, we
+	// convert out back from Montgomery representation, because it works out to
+	// dividing by R.
+	t0 := NewNat().set(x)
+	t1 := NewNat().ExpandFor(m)
+	t1.limbs[0] = 1
+	return x.montgomeryMul(t0, t1, m)
+}
+
+// montgomeryMul calculates d = a * b / R mod m, with R = 2^(_W * n) and
+// n = len(m.nat.limbs), using the Montgomery Multiplication technique.
+//
+// All inputs should be the same length, not aliasing d, and already
+// reduced modulo m. d will be resized to the size of m and overwritten.
+func (d *Nat) montgomeryMul(a *Nat, b *Nat, m *Modulus) *Nat {
+	d.resetFor(m)
+	if len(a.limbs) != len(m.nat.limbs) || len(b.limbs) != len(m.nat.limbs) {
+		panic("bigmod: invalid montgomeryMul input")
+	}
+
+	// See https://bearssl.org/bigint.html#montgomery-reduction-and-multiplication
+	// for a description of the algorithm implemented mostly in montgomeryLoop.
+	// See Add for how overflow, underflow, and needSubtraction relate.
+	overflow := montgomeryLoop(d.limbs, a.limbs, b.limbs, m.nat.limbs, m.m0inv)
+	underflow := not(d.cmpGeq(m.nat)) // d < m
+	needSubtraction := ctEq(overflow, uint(underflow))
+	d.sub(needSubtraction, m.nat)
+
+	return d
+}
+
+func montgomeryLoopGeneric(d, a, b, m []uint, m0inv uint) (overflow uint) {
+	// Eliminate bounds checks in the loop.
+	size := len(d)
+	a = a[:size]
+	b = b[:size]
+	m = m[:size]
+
+	for _, ai := range a {
+		// This is an unrolled iteration of the loop below with j = 0.
+		hi, lo := bits.Mul(ai, b[0])
+		z_lo, c := bits.Add(d[0], lo, 0)
+		f := (z_lo * m0inv) & _MASK // (d[0] + a[i] * b[0]) * m0inv
+		z_hi, _ := bits.Add(0, hi, c)
+		hi, lo = bits.Mul(f, m[0])
+		z_lo, c = bits.Add(z_lo, lo, 0)
+		z_hi, _ = bits.Add(z_hi, hi, c)
+		carry := z_hi<<1 | z_lo>>_W
+
+		for j := 1; j < size; j++ {
+			// z = d[j] + a[i] * b[j] + f * m[j] + carry <= 2^(2W+1) - 2^(W+1) + 2^W
+			hi, lo := bits.Mul(ai, b[j])
+			z_lo, c := bits.Add(d[j], lo, 0)
+			z_hi, _ := bits.Add(0, hi, c)
+			hi, lo = bits.Mul(f, m[j])
+			z_lo, c = bits.Add(z_lo, lo, 0)
+			z_hi, _ = bits.Add(z_hi, hi, c)
+			z_lo, c = bits.Add(z_lo, carry, 0)
+			z_hi, _ = bits.Add(z_hi, 0, c)
+			d[j-1] = z_lo & _MASK
+			carry = z_hi<<1 | z_lo>>_W // carry <= 2^(W+1) - 2
+		}
+
+		z := overflow + carry // z <= 2^(W+1) - 1
+		d[size-1] = z & _MASK
+		overflow = z >> _W // overflow <= 1
+	}
+	return
+}
+
+// Mul calculates x *= y mod m.
+//
+// x and y must already be reduced modulo m, they must share its announced
+// length, and they may not alias.
+func (x *Nat) Mul(y *Nat, m *Modulus) *Nat {
+	// A Montgomery multiplication by a value out of the Montgomery domain
+	// takes the result out of Montgomery representation.
+	xR := NewNat().set(x).montgomeryRepresentation(m) // xR = x * R mod m
+	return x.montgomeryMul(xR, y, m)                  // x = xR * y / R mod m
+}
+
+// Exp calculates out = x^e mod m.
+//
+// The exponent e is represented in big-endian order. The output will be resized
+// to the size of m and overwritten. x must already be reduced modulo m.
+func (out *Nat) Exp(x *Nat, e []byte, m *Modulus) *Nat {
+	// We use a 4 bit window. For our RSA workload, 4 bit windows are faster
+	// than 2 bit windows, but use an extra 12 nats worth of scratch space.
+	// Using bit sizes that don't divide 8 are more complex to implement.
+
+	table := [(1 << 4) - 1]*Nat{ // table[i] = x ^ (i+1)
+		// newNat calls are unrolled so they are allocated on the stack.
+		NewNat(), NewNat(), NewNat(), NewNat(), NewNat(),
+		NewNat(), NewNat(), NewNat(), NewNat(), NewNat(),
+		NewNat(), NewNat(), NewNat(), NewNat(), NewNat(),
+	}
+	table[0].set(x).montgomeryRepresentation(m)
+	for i := 1; i < len(table); i++ {
+		table[i].montgomeryMul(table[i-1], table[0], m)
+	}
+
+	out.resetFor(m)
+	out.limbs[0] = 1
+	out.montgomeryRepresentation(m)
+	t0 := NewNat().ExpandFor(m)
+	t1 := NewNat().ExpandFor(m)
+	for _, b := range e {
+		for _, j := range []int{4, 0} {
+			// Square four times.
+			t1.montgomeryMul(out, out, m)
+			out.montgomeryMul(t1, t1, m)
+			t1.montgomeryMul(out, out, m)
+			out.montgomeryMul(t1, t1, m)
+
+			// Select x^k in constant time from the table.
+			k := uint((b >> j) & 0b1111)
+			for i := range table {
+				t0.assign(ctEq(k, uint(i+1)), table[i])
+			}
+
+			// Multiply by x^k, discarding the result if k = 0.
+			t1.montgomeryMul(out, t0, m)
+			out.assign(not(ctEq(k, 0)), t1)
+		}
+	}
+
+	return out.montgomeryReduction(m)
+}
diff --git a/src/crypto/internal/bigmod/nat_amd64.go b/src/crypto/internal/bigmod/nat_amd64.go
new file mode 100644
index 0000000..e947782
--- /dev/null
+++ b/src/crypto/internal/bigmod/nat_amd64.go
@@ -0,0 +1,8 @@
+// Code generated by command: go run nat_amd64_asm.go -out ../nat_amd64.s -stubs ../nat_amd64.go -pkg bigmod. DO NOT EDIT.
+
+//go:build amd64 && gc && !purego
+
+package bigmod
+
+//go:noescape
+func montgomeryLoop(d []uint, a []uint, b []uint, m []uint, m0inv uint) uint
diff --git a/src/crypto/internal/bigmod/nat_amd64.s b/src/crypto/internal/bigmod/nat_amd64.s
new file mode 100644
index 0000000..12b7629
--- /dev/null
+++ b/src/crypto/internal/bigmod/nat_amd64.s
@@ -0,0 +1,68 @@
+// Code generated by command: go run nat_amd64_asm.go -out ../nat_amd64.s -stubs ../nat_amd64.go -pkg bigmod. DO NOT EDIT.
+
+//go:build amd64 && gc && !purego
+
+// func montgomeryLoop(d []uint, a []uint, b []uint, m []uint, m0inv uint) uint
+TEXT ·montgomeryLoop(SB), $8-112
+	MOVQ d_len+8(FP), CX
+	MOVQ d_base+0(FP), BX
+	MOVQ b_base+48(FP), SI
+	MOVQ m_base+72(FP), DI
+	MOVQ m0inv+96(FP), R8
+	XORQ R9, R9
+	XORQ R10, R10
+
+outerLoop:
+	MOVQ  a_base+24(FP), R11
+	MOVQ  (R11)(R10*8), R11
+	MOVQ  (SI), AX
+	MULQ  R11
+	MOVQ  AX, R13
+	MOVQ  DX, R12
+	ADDQ  (BX), R13
+	ADCQ  $0x00, R12
+	MOVQ  R8, R14
+	IMULQ R13, R14
+	BTRQ  $0x3f, R14
+	MOVQ  (DI), AX
+	MULQ  R14
+	ADDQ  AX, R13
+	ADCQ  DX, R12
+	SHRQ  $0x3f, R12, R13
+	XORQ  R12, R12
+	INCQ  R12
+	JMP   innerLoopCondition
+
+innerLoop:
+	MOVQ (SI)(R12*8), AX
+	MULQ R11
+	MOVQ AX, BP
+	MOVQ DX, R15
+	MOVQ (DI)(R12*8), AX
+	MULQ R14
+	ADDQ AX, BP
+	ADCQ DX, R15
+	ADDQ (BX)(R12*8), BP
+	ADCQ $0x00, R15
+	ADDQ R13, BP
+	ADCQ $0x00, R15
+	MOVQ BP, AX
+	BTRQ $0x3f, AX
+	MOVQ AX, -8(BX)(R12*8)
+	SHRQ $0x3f, R15, BP
+	MOVQ BP, R13
+	INCQ R12
+
+innerLoopCondition:
+	CMPQ CX, R12
+	JGT  innerLoop
+	ADDQ R13, R9
+	MOVQ R9, AX
+	BTRQ $0x3f, AX
+	MOVQ AX, -8(BX)(CX*8)
+	SHRQ $0x3f, R9
+	INCQ R10
+	CMPQ CX, R10
+	JGT  outerLoop
+	MOVQ R9, ret+104(FP)
+	RET
diff --git a/src/crypto/internal/bigmod/nat_noasm.go b/src/crypto/internal/bigmod/nat_noasm.go
new file mode 100644
index 0000000..870b445
--- /dev/null
+++ b/src/crypto/internal/bigmod/nat_noasm.go
@@ -0,0 +1,11 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !amd64 || !gc || purego
+
+package bigmod
+
+func montgomeryLoop(d, a, b, m []uint, m0inv uint) uint {
+	return montgomeryLoopGeneric(d, a, b, m, m0inv)
+}
diff --git a/src/crypto/internal/bigmod/nat_test.go b/src/crypto/internal/bigmod/nat_test.go
new file mode 100644
index 0000000..6431d25
--- /dev/null
+++ b/src/crypto/internal/bigmod/nat_test.go
@@ -0,0 +1,412 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package bigmod
+
+import (
+	"math/big"
+	"math/bits"
+	"math/rand"
+	"reflect"
+	"testing"
+	"testing/quick"
+)
+
+// Generate generates an even nat. It's used by testing/quick to produce random
+// *nat values for quick.Check invocations.
+func (*Nat) Generate(r *rand.Rand, size int) reflect.Value {
+	limbs := make([]uint, size)
+	for i := 0; i < size; i++ {
+		limbs[i] = uint(r.Uint64()) & ((1 << _W) - 2)
+	}
+	return reflect.ValueOf(&Nat{limbs})
+}
+
+func testModAddCommutative(a *Nat, b *Nat) bool {
+	m := maxModulus(uint(len(a.limbs)))
+	aPlusB := new(Nat).set(a)
+	aPlusB.Add(b, m)
+	bPlusA := new(Nat).set(b)
+	bPlusA.Add(a, m)
+	return aPlusB.Equal(bPlusA) == 1
+}
+
+func TestModAddCommutative(t *testing.T) {
+	err := quick.Check(testModAddCommutative, &quick.Config{})
+	if err != nil {
+		t.Error(err)
+	}
+}
+
+func testModSubThenAddIdentity(a *Nat, b *Nat) bool {
+	m := maxModulus(uint(len(a.limbs)))
+	original := new(Nat).set(a)
+	a.Sub(b, m)
+	a.Add(b, m)
+	return a.Equal(original) == 1
+}
+
+func TestModSubThenAddIdentity(t *testing.T) {
+	err := quick.Check(testModSubThenAddIdentity, &quick.Config{})
+	if err != nil {
+		t.Error(err)
+	}
+}
+
+func testMontgomeryRoundtrip(a *Nat) bool {
+	one := &Nat{make([]uint, len(a.limbs))}
+	one.limbs[0] = 1
+	aPlusOne := new(big.Int).SetBytes(natBytes(a))
+	aPlusOne.Add(aPlusOne, big.NewInt(1))
+	m := NewModulusFromBig(aPlusOne)
+	monty := new(Nat).set(a)
+	monty.montgomeryRepresentation(m)
+	aAgain := new(Nat).set(monty)
+	aAgain.montgomeryMul(monty, one, m)
+	return a.Equal(aAgain) == 1
+}
+
+func TestMontgomeryRoundtrip(t *testing.T) {
+	err := quick.Check(testMontgomeryRoundtrip, &quick.Config{})
+	if err != nil {
+		t.Error(err)
+	}
+}
+
+func TestShiftIn(t *testing.T) {
+	if bits.UintSize != 64 {
+		t.Skip("examples are only valid in 64 bit")
+	}
+	examples := []struct {
+		m, x, expected []byte
+		y              uint64
+	}{{
+		m:        []byte{13},
+		x:        []byte{0},
+		y:        0x7FFF_FFFF_FFFF_FFFF,
+		expected: []byte{7},
+	}, {
+		m:        []byte{13},
+		x:        []byte{7},
+		y:        0x7FFF_FFFF_FFFF_FFFF,
+		expected: []byte{11},
+	}, {
+		m:        []byte{0x06, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d},
+		x:        make([]byte, 9),
+		y:        0x7FFF_FFFF_FFFF_FFFF,
+		expected: []byte{0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+	}, {
+		m:        []byte{0x06, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d},
+		x:        []byte{0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+		y:        0,
+		expected: []byte{0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08},
+	}}
+
+	for i, tt := range examples {
+		m := modulusFromBytes(tt.m)
+		got := natFromBytes(tt.x).ExpandFor(m).shiftIn(uint(tt.y), m)
+		if got.Equal(natFromBytes(tt.expected).ExpandFor(m)) != 1 {
+			t.Errorf("%d: got %x, expected %x", i, got, tt.expected)
+		}
+	}
+}
+
+func TestModulusAndNatSizes(t *testing.T) {
+	// These are 126 bit (2 * _W on 64-bit architectures) values, serialized as
+	// 128 bits worth of bytes. If leading zeroes are stripped, they fit in two
+	// limbs, if they are not, they fit in three. This can be a problem because
+	// modulus strips leading zeroes and nat does not.
+	m := modulusFromBytes([]byte{
+		0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff})
+	xb := []byte{0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}
+	natFromBytes(xb).ExpandFor(m) // must not panic for shrinking
+	NewNat().SetBytes(xb, m)
+}
+
+func TestSetBytes(t *testing.T) {
+	tests := []struct {
+		m, b []byte
+		fail bool
+	}{{
+		m: []byte{0xff, 0xff},
+		b: []byte{0x00, 0x01},
+	}, {
+		m:    []byte{0xff, 0xff},
+		b:    []byte{0xff, 0xff},
+		fail: true,
+	}, {
+		m: []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+		b: []byte{0x00, 0x01},
+	}, {
+		m: []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+		b: []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe},
+	}, {
+		m:    []byte{0xff, 0xff},
+		b:    []byte{0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+		fail: true,
+	}, {
+		m:    []byte{0xff, 0xff},
+		b:    []byte{0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+		fail: true,
+	}, {
+		m: []byte{0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+		b: []byte{0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe},
+	}, {
+		m:    []byte{0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+		b:    []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe},
+		fail: true,
+	}, {
+		m:    []byte{0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+		b:    []byte{0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+		fail: true,
+	}, {
+		m:    []byte{0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+		b:    []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe},
+		fail: true,
+	}, {
+		m:    []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd},
+		b:    []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+		fail: true,
+	}}
+
+	for i, tt := range tests {
+		m := modulusFromBytes(tt.m)
+		got, err := NewNat().SetBytes(tt.b, m)
+		if err != nil {
+			if !tt.fail {
+				t.Errorf("%d: unexpected error: %v", i, err)
+			}
+			continue
+		}
+		if err == nil && tt.fail {
+			t.Errorf("%d: unexpected success", i)
+			continue
+		}
+		if expected := natFromBytes(tt.b).ExpandFor(m); got.Equal(expected) != yes {
+			t.Errorf("%d: got %x, expected %x", i, got, expected)
+		}
+	}
+
+	f := func(xBytes []byte) bool {
+		m := maxModulus(uint(len(xBytes)*8/_W + 1))
+		got, err := NewNat().SetBytes(xBytes, m)
+		if err != nil {
+			return false
+		}
+		return got.Equal(natFromBytes(xBytes).ExpandFor(m)) == yes
+	}
+
+	err := quick.Check(f, &quick.Config{})
+	if err != nil {
+		t.Error(err)
+	}
+}
+
+func TestExpand(t *testing.T) {
+	sliced := []uint{1, 2, 3, 4}
+	examples := []struct {
+		in  []uint
+		n   int
+		out []uint
+	}{{
+		[]uint{1, 2},
+		4,
+		[]uint{1, 2, 0, 0},
+	}, {
+		sliced[:2],
+		4,
+		[]uint{1, 2, 0, 0},
+	}, {
+		[]uint{1, 2},
+		2,
+		[]uint{1, 2},
+	}}
+
+	for i, tt := range examples {
+		got := (&Nat{tt.in}).expand(tt.n)
+		if len(got.limbs) != len(tt.out) || got.Equal(&Nat{tt.out}) != 1 {
+			t.Errorf("%d: got %x, expected %x", i, got, tt.out)
+		}
+	}
+}
+
+func TestMod(t *testing.T) {
+	m := modulusFromBytes([]byte{0x06, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d})
+	x := natFromBytes([]byte{0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01})
+	out := new(Nat)
+	out.Mod(x, m)
+	expected := natFromBytes([]byte{0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09})
+	if out.Equal(expected) != 1 {
+		t.Errorf("%+v != %+v", out, expected)
+	}
+}
+
+func TestModSub(t *testing.T) {
+	m := modulusFromBytes([]byte{13})
+	x := &Nat{[]uint{6}}
+	y := &Nat{[]uint{7}}
+	x.Sub(y, m)
+	expected := &Nat{[]uint{12}}
+	if x.Equal(expected) != 1 {
+		t.Errorf("%+v != %+v", x, expected)
+	}
+	x.Sub(y, m)
+	expected = &Nat{[]uint{5}}
+	if x.Equal(expected) != 1 {
+		t.Errorf("%+v != %+v", x, expected)
+	}
+}
+
+func TestModAdd(t *testing.T) {
+	m := modulusFromBytes([]byte{13})
+	x := &Nat{[]uint{6}}
+	y := &Nat{[]uint{7}}
+	x.Add(y, m)
+	expected := &Nat{[]uint{0}}
+	if x.Equal(expected) != 1 {
+		t.Errorf("%+v != %+v", x, expected)
+	}
+	x.Add(y, m)
+	expected = &Nat{[]uint{7}}
+	if x.Equal(expected) != 1 {
+		t.Errorf("%+v != %+v", x, expected)
+	}
+}
+
+func TestExp(t *testing.T) {
+	m := modulusFromBytes([]byte{13})
+	x := &Nat{[]uint{3}}
+	out := &Nat{[]uint{0}}
+	out.Exp(x, []byte{12}, m)
+	expected := &Nat{[]uint{1}}
+	if out.Equal(expected) != 1 {
+		t.Errorf("%+v != %+v", out, expected)
+	}
+}
+
+func natBytes(n *Nat) []byte {
+	return n.Bytes(maxModulus(uint(len(n.limbs))))
+}
+
+func natFromBytes(b []byte) *Nat {
+	bb := new(big.Int).SetBytes(b)
+	return NewNat().setBig(bb)
+}
+
+func modulusFromBytes(b []byte) *Modulus {
+	bb := new(big.Int).SetBytes(b)
+	return NewModulusFromBig(bb)
+}
+
+// maxModulus returns the biggest modulus that can fit in n limbs.
+func maxModulus(n uint) *Modulus {
+	m := big.NewInt(1)
+	m.Lsh(m, n*_W)
+	m.Sub(m, big.NewInt(1))
+	return NewModulusFromBig(m)
+}
+
+func makeBenchmarkModulus() *Modulus {
+	return maxModulus(32)
+}
+
+func makeBenchmarkValue() *Nat {
+	x := make([]uint, 32)
+	for i := 0; i < 32; i++ {
+		x[i] = _MASK - 1
+	}
+	return &Nat{limbs: x}
+}
+
+func makeBenchmarkExponent() []byte {
+	e := make([]byte, 256)
+	for i := 0; i < 32; i++ {
+		e[i] = 0xFF
+	}
+	return e
+}
+
+func BenchmarkModAdd(b *testing.B) {
+	x := makeBenchmarkValue()
+	y := makeBenchmarkValue()
+	m := makeBenchmarkModulus()
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		x.Add(y, m)
+	}
+}
+
+func BenchmarkModSub(b *testing.B) {
+	x := makeBenchmarkValue()
+	y := makeBenchmarkValue()
+	m := makeBenchmarkModulus()
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		x.Sub(y, m)
+	}
+}
+
+func BenchmarkMontgomeryRepr(b *testing.B) {
+	x := makeBenchmarkValue()
+	m := makeBenchmarkModulus()
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		x.montgomeryRepresentation(m)
+	}
+}
+
+func BenchmarkMontgomeryMul(b *testing.B) {
+	x := makeBenchmarkValue()
+	y := makeBenchmarkValue()
+	out := makeBenchmarkValue()
+	m := makeBenchmarkModulus()
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		out.montgomeryMul(x, y, m)
+	}
+}
+
+func BenchmarkModMul(b *testing.B) {
+	x := makeBenchmarkValue()
+	y := makeBenchmarkValue()
+	m := makeBenchmarkModulus()
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		x.Mul(y, m)
+	}
+}
+
+func BenchmarkExpBig(b *testing.B) {
+	out := new(big.Int)
+	exponentBytes := makeBenchmarkExponent()
+	x := new(big.Int).SetBytes(exponentBytes)
+	e := new(big.Int).SetBytes(exponentBytes)
+	n := new(big.Int).SetBytes(exponentBytes)
+	one := new(big.Int).SetUint64(1)
+	n.Add(n, one)
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		out.Exp(x, e, n)
+	}
+}
+
+func BenchmarkExp(b *testing.B) {
+	x := makeBenchmarkValue()
+	e := makeBenchmarkExponent()
+	out := makeBenchmarkValue()
+	m := makeBenchmarkModulus()
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		out.Exp(x, e, m)
+	}
+}
diff --git a/src/crypto/internal/boring/Dockerfile b/src/crypto/internal/boring/Dockerfile
index 5bd7438..58eb028 100644
--- a/src/crypto/internal/boring/Dockerfile
+++ b/src/crypto/internal/boring/Dockerfile
@@ -2,43 +2,62 @@
 # Use of this source code is governed by a BSD-style
 # license that can be found in the LICENSE file.
 
-# This Docker image builds goboringcrypto_linux_amd64.syso according to the
-# Security Policy. To use it, build the image, run it, and then extract
-# /boring/godriver/goboringcrypto_linux_amd64.syso.
-#
-#   $ podman build -t goboring:140sp3678 .
-#   $ podman run -it --name goboring-140sp3678 goboring:140sp3678
-#   $ podman cp goboring-140sp3678:/boring/godriver/goboringcrypto_linux_amd64.syso syso
-#   $ sha256sum syso/goboringcrypto_linux_amd64.syso # compare to docker output
-#
-# The podman commands may need to run under sudo to work around a subuid/subgid bug.
+# Run this using build.sh.
 
-FROM ubuntu:focal
+ARG ubuntu=ubuntu
+FROM $ubuntu:focal
 
 RUN mkdir /boring
 WORKDIR /boring
 
-# Following 140sp3678.pdf [0] page 19, install clang 7.0.1, Go 1.12.7, and
-# Ninja 1.9.0, then download and verify BoringSSL.
-#
-# [0]: https://csrc.nist.gov/CSRC/media/projects/cryptographic-module-validation-program/documents/security-policies/140sp3678.pdf
+ENV LANG=C
+ENV LANGUAGE=
 
+# Following NIST submission draft dated July 3, 2021.
+# This corresponds to boringssl.googlesource.com/boringssl tag fips-20210429.
+ENV ClangV=12
 RUN apt-get update && \
-        apt-get install --no-install-recommends -y cmake xz-utils wget unzip ca-certificates clang-7
-RUN wget https://github.com/ninja-build/ninja/releases/download/v1.9.0/ninja-linux.zip && \
-        unzip ninja-linux.zip && \
-        rm ninja-linux.zip && \
-        mv ninja /usr/local/bin/
-RUN wget https://golang.org/dl/go1.12.7.linux-amd64.tar.gz && \
-        tar -C /usr/local -xzf go1.12.7.linux-amd64.tar.gz && \
-        rm go1.12.7.linux-amd64.tar.gz && \
-        ln -s /usr/local/go/bin/go /usr/local/bin/
+        apt-get install --no-install-recommends -y cmake xz-utils wget unzip ca-certificates clang-$ClangV python
 
-RUN wget https://commondatastorage.googleapis.com/chromium-boringssl-fips/boringssl-ae223d6138807a13006342edfeef32e813246b39.tar.xz
-RUN [ "$(sha256sum boringssl-ae223d6138807a13006342edfeef32e813246b39.tar.xz | awk '{print $1}')" = \
-        3b5fdf23274d4179c2077b5e8fa625d9debd7a390aac1d165b7e47234f648bb8 ]
+# Download, validate, unpack, build, and install Ninja.
+ENV NinjaV=1.10.2
+ENV NinjaH=ce35865411f0490368a8fc383f29071de6690cbadc27704734978221f25e2bed
+RUN \
+	wget https://github.com/ninja-build/ninja/archive/refs/tags/v$NinjaV.tar.gz && \
+	echo "$NinjaH v$NinjaV.tar.gz" >sha && sha256sum -c sha && \
+	tar -xzf v$NinjaV.tar.gz && \
+	rm v$NinjaV.tar.gz && \
+	cd ninja-$NinjaV && \
+	CC=clang-$ClangV CXX=clang++-$ClangV ./configure.py --bootstrap && \
+	mv ninja /usr/local/bin/
 
+# Download, validate, unpack, and install Go.
+ARG GOARCH
+ENV GoV=1.16.5
+ENV GoHamd64=b12c23023b68de22f74c0524f10b753e7b08b1504cb7e417eccebdd3fae49061
+ENV GoHarm64=d5446b46ef6f36fdffa852f73dfbbe78c1ddf010b99fa4964944b9ae8b4d6799
+RUN \
+	eval GoH=\${GoH$GOARCH} && \
+	wget https://golang.org/dl/go$GoV.linux-$GOARCH.tar.gz && \
+	echo "$GoH go$GoV.linux-$GOARCH.tar.gz" >sha && sha256sum -c sha && \
+	tar -C /usr/local -xzf go$GoV.linux-$GOARCH.tar.gz && \
+	rm go$GoV.linux-$GOARCH.tar.gz && \
+	ln -s /usr/local/go/bin/go /usr/local/bin/
+
+# Download, validate, and unpack BoringCrypto.
+ENV BoringV=853ca1ea1168dff08011e5d42d94609cc0ca2e27
+ENV BoringH=a4d069ccef6f3c7bc0c68de82b91414f05cb817494cd1ab483dcf3368883c7c2
+RUN \
+	wget https://commondatastorage.googleapis.com/chromium-boringssl-fips/boringssl-$BoringV.tar.xz && \
+	echo "$BoringH boringssl-$BoringV.tar.xz" >sha && sha256sum -c sha && \
+	tar xJf boringssl-$BoringV.tar.xz
+
+# Build BoringCrypto.
+ADD build-boring.sh /boring/build-boring.sh
+RUN /boring/build-boring.sh
+
+# Build Go BoringCrypto syso.
+# build.sh copies it back out of the Docker image.
 ADD goboringcrypto.h /boring/godriver/goboringcrypto.h
-ADD build.sh /boring/build.sh
-
-ENTRYPOINT ["/boring/build.sh"]
+ADD build-goboring.sh /boring/build-goboring.sh
+RUN /boring/build-goboring.sh
diff --git a/src/crypto/internal/boring/README.md b/src/crypto/internal/boring/README.md
new file mode 100644
index 0000000..ec02786
--- /dev/null
+++ b/src/crypto/internal/boring/README.md
@@ -0,0 +1,39 @@
+We have been working inside Google on a fork of Go that uses
+BoringCrypto (the core of [BoringSSL](https://boringssl.googlesource.com/boringssl/))
+for various crypto primitives, in furtherance of some work related to FIPS 140.
+We have heard that some external users of Go would be
+interested in this code as well, so we have published this code
+here in the main Go repository behind the setting GOEXPERIMENT=boringcrypto.
+
+Use of GOEXPERIMENT=boringcrypto outside Google is _unsupported_.
+This mode is not part of the [Go 1 compatibility rules](https://go.dev/doc/go1compat),
+and it may change incompatibly or break in other ways at any time.
+
+To be clear, we are not making any statements or representations about
+the suitability of this code in relation to the FIPS 140 standard.
+Interested users will have to evaluate for themselves whether the code
+is useful for their own purposes.
+
+---
+
+This directory holds the core of the BoringCrypto implementation
+as well as the build scripts for the module itself: syso/*.syso.
+
+syso/goboringcrypto_linux_amd64.syso is built with:
+
+	GOARCH=amd64 ./build.sh
+
+syso/goboringcrypto_linux_arm64.syso is built with:
+
+	GOARCH=arm64 ./build.sh
+
+Both run on an x86 Debian Linux system using Docker.
+For the arm64 build to run on an x86 system, you need
+
+	apt-get install qemu-user-static qemu-binfmt-support
+
+to allow the x86 kernel to run arm64 binaries via QEMU.
+
+See build.sh for more details about the build.
+
+
diff --git a/src/crypto/internal/boring/aes.go b/src/crypto/internal/boring/aes.go
index eaa1adc..6fae1d5 100644
--- a/src/crypto/internal/boring/aes.go
+++ b/src/crypto/internal/boring/aes.go
@@ -2,8 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build boringcrypto && linux && amd64 && !android && !cmd_go_bootstrap && !msan
-// +build boringcrypto,linux,amd64,!android,!cmd_go_bootstrap,!msan
+//go:build boringcrypto && linux && (amd64 || arm64) && !android && !cmd_go_bootstrap && !msan
 
 package boring
 
@@ -45,6 +44,7 @@
 */
 import "C"
 import (
+	"bytes"
 	"crypto/cipher"
 	"errors"
 	"runtime"
@@ -77,8 +77,7 @@
 var _ extraModes = (*aesCipher)(nil)
 
 func NewAESCipher(key []byte) (cipher.Block, error) {
-	c := &aesCipher{key: make([]byte, len(key))}
-	copy(c.key, key)
+	c := &aesCipher{key: bytes.Clone(key)}
 	// Note: 0 is success, contradicting the usual BoringCrypto convention.
 	if C._goboringcrypto_AES_set_decrypt_key((*C.uint8_t)(unsafe.Pointer(&c.key[0])), C.uint(8*len(c.key)), &c.dec) != 0 ||
 		C._goboringcrypto_AES_set_encrypt_key((*C.uint8_t)(unsafe.Pointer(&c.key[0])), C.uint(8*len(c.key)), &c.enc) != 0 {
diff --git a/src/crypto/internal/boring/bcache/cache.go b/src/crypto/internal/boring/bcache/cache.go
index c0b9d7b..7934d03 100644
--- a/src/crypto/internal/boring/bcache/cache.go
+++ b/src/crypto/internal/boring/bcache/cache.go
@@ -22,20 +22,18 @@
 // This means that clients need to be able to cope with cache entries
 // disappearing, but it also means that clients don't need to worry about
 // cache entries keeping the keys from being collected.
-//
-// TODO(rsc): Make Cache generic once consumers can handle that.
-type Cache struct {
-	// ptable is an atomic *[cacheSize]unsafe.Pointer,
-	// where each unsafe.Pointer is an atomic *cacheEntry.
+type Cache[K, V any] struct {
 	// The runtime atomically stores nil to ptable at the start of each GC.
-	ptable unsafe.Pointer
+	ptable atomic.Pointer[cacheTable[K, V]]
 }
 
+type cacheTable[K, V any] [cacheSize]atomic.Pointer[cacheEntry[K, V]]
+
 // A cacheEntry is a single entry in the linked list for a given hash table entry.
-type cacheEntry struct {
-	k    unsafe.Pointer // immutable once created
-	v    unsafe.Pointer // read and written atomically to allow updates
-	next *cacheEntry    // immutable once linked into table
+type cacheEntry[K, V any] struct {
+	k    *K                // immutable once created
+	v    atomic.Pointer[V] // read and written atomically to allow updates
+	next *cacheEntry[K, V] // immutable once linked into table
 }
 
 func registerCache(unsafe.Pointer) // provided by runtime
@@ -43,7 +41,7 @@
 // Register registers the cache with the runtime,
 // so that c.ptable can be cleared at the start of each GC.
 // Register must be called during package initialization.
-func (c *Cache) Register() {
+func (c *Cache[K, V]) Register() {
 	registerCache(unsafe.Pointer(&c.ptable))
 }
 
@@ -54,45 +52,45 @@
 
 // table returns a pointer to the current cache hash table,
 // coping with the possibility of the GC clearing it out from under us.
-func (c *Cache) table() *[cacheSize]unsafe.Pointer {
+func (c *Cache[K, V]) table() *cacheTable[K, V] {
 	for {
-		p := atomic.LoadPointer(&c.ptable)
+		p := c.ptable.Load()
 		if p == nil {
-			p = unsafe.Pointer(new([cacheSize]unsafe.Pointer))
-			if !atomic.CompareAndSwapPointer(&c.ptable, nil, p) {
+			p = new(cacheTable[K, V])
+			if !c.ptable.CompareAndSwap(nil, p) {
 				continue
 			}
 		}
-		return (*[cacheSize]unsafe.Pointer)(p)
+		return p
 	}
 }
 
 // Clear clears the cache.
 // The runtime does this automatically at each garbage collection;
 // this method is exposed only for testing.
-func (c *Cache) Clear() {
+func (c *Cache[K, V]) Clear() {
 	// The runtime does this at the start of every garbage collection
 	// (itself, not by calling this function).
-	atomic.StorePointer(&c.ptable, nil)
+	c.ptable.Store(nil)
 }
 
 // Get returns the cached value associated with v,
 // which is either the value v corresponding to the most recent call to Put(k, v)
 // or nil if that cache entry has been dropped.
-func (c *Cache) Get(k unsafe.Pointer) unsafe.Pointer {
-	head := &c.table()[uintptr(k)%cacheSize]
-	e := (*cacheEntry)(atomic.LoadPointer(head))
+func (c *Cache[K, V]) Get(k *K) *V {
+	head := &c.table()[uintptr(unsafe.Pointer(k))%cacheSize]
+	e := head.Load()
 	for ; e != nil; e = e.next {
 		if e.k == k {
-			return atomic.LoadPointer(&e.v)
+			return e.v.Load()
 		}
 	}
 	return nil
 }
 
 // Put sets the cached value associated with k to v.
-func (c *Cache) Put(k, v unsafe.Pointer) {
-	head := &c.table()[uintptr(k)%cacheSize]
+func (c *Cache[K, V]) Put(k *K, v *V) {
+	head := &c.table()[uintptr(unsafe.Pointer(k))%cacheSize]
 
 	// Strategy is to walk the linked list at head,
 	// same as in Get, to look for existing entry.
@@ -112,20 +110,21 @@
 	//
 	//  2. We only allocate the entry to be added once,
 	//     saving it in add for the next attempt.
-	var add, noK *cacheEntry
+	var add, noK *cacheEntry[K, V]
 	n := 0
 	for {
-		e := (*cacheEntry)(atomic.LoadPointer(head))
+		e := head.Load()
 		start := e
 		for ; e != nil && e != noK; e = e.next {
 			if e.k == k {
-				atomic.StorePointer(&e.v, v)
+				e.v.Store(v)
 				return
 			}
 			n++
 		}
 		if add == nil {
-			add = &cacheEntry{k, v, nil}
+			add = &cacheEntry[K, V]{k: k}
+			add.v.Store(v)
 		}
 		add.next = start
 		if n >= 1000 {
@@ -133,7 +132,7 @@
 			// throw it away to avoid quadratic lookup behavior.
 			add.next = nil
 		}
-		if atomic.CompareAndSwapPointer(head, unsafe.Pointer(start), unsafe.Pointer(add)) {
+		if head.CompareAndSwap(start, add) {
 			return
 		}
 		noK = start
diff --git a/src/crypto/internal/boring/bcache/cache_test.go b/src/crypto/internal/boring/bcache/cache_test.go
index 8b2cf3d..19458a1 100644
--- a/src/crypto/internal/boring/bcache/cache_test.go
+++ b/src/crypto/internal/boring/bcache/cache_test.go
@@ -10,31 +10,39 @@
 	"sync"
 	"sync/atomic"
 	"testing"
-	"unsafe"
 )
 
-var registeredCache Cache
+var registeredCache Cache[int, int32]
 
 func init() {
 	registeredCache.Register()
 }
 
+var seq atomic.Uint32
+
+func next[T int | int32]() *T {
+	x := new(T)
+	*x = T(seq.Add(1))
+	return x
+}
+
+func str[T int | int32](x *T) string {
+	if x == nil {
+		return "nil"
+	}
+	return fmt.Sprint(*x)
+}
+
 func TestCache(t *testing.T) {
 	// Use unregistered cache for functionality tests,
 	// to keep the runtime from clearing behind our backs.
-	c := new(Cache)
+	c := new(Cache[int, int32])
 
 	// Create many entries.
-	seq := uint32(0)
-	next := func() unsafe.Pointer {
-		x := new(int)
-		*x = int(atomic.AddUint32(&seq, 1))
-		return unsafe.Pointer(x)
-	}
-	m := make(map[unsafe.Pointer]unsafe.Pointer)
+	m := make(map[*int]*int32)
 	for i := 0; i < 10000; i++ {
-		k := next()
-		v := next()
+		k := next[int]()
+		v := next[int32]()
 		m[k] = v
 		c.Put(k, v)
 	}
@@ -42,7 +50,7 @@
 	// Overwrite a random 20% of those.
 	n := 0
 	for k := range m {
-		v := next()
+		v := next[int32]()
 		m[k] = v
 		c.Put(k, v)
 		if n++; n >= 2000 {
@@ -51,12 +59,6 @@
 	}
 
 	// Check results.
-	str := func(p unsafe.Pointer) string {
-		if p == nil {
-			return "nil"
-		}
-		return fmt.Sprint(*(*int)(p))
-	}
 	for k, v := range m {
 		if cv := c.Get(k); cv != v {
 			t.Fatalf("c.Get(%v) = %v, want %v", str(k), str(cv), str(v))
@@ -86,7 +88,7 @@
 	// Lists are discarded if they reach 1000 entries,
 	// and there are cacheSize list heads, so we should be
 	// able to do 100 * cacheSize entries with no problem at all.
-	c = new(Cache)
+	c = new(Cache[int, int32])
 	var barrier, wg sync.WaitGroup
 	const N = 100
 	barrier.Add(N)
@@ -96,9 +98,9 @@
 		go func() {
 			defer wg.Done()
 
-			m := make(map[unsafe.Pointer]unsafe.Pointer)
+			m := make(map[*int]*int32)
 			for j := 0; j < cacheSize; j++ {
-				k, v := next(), next()
+				k, v := next[int](), next[int32]()
 				m[k] = v
 				c.Put(k, v)
 			}
diff --git a/src/crypto/internal/boring/boring.go b/src/crypto/internal/boring/boring.go
index c560679..102380a 100644
--- a/src/crypto/internal/boring/boring.go
+++ b/src/crypto/internal/boring/boring.go
@@ -2,8 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build boringcrypto && linux && amd64 && !android && !cmd_go_bootstrap && !msan
-// +build boringcrypto,linux,amd64,!android,!cmd_go_bootstrap,!msan
+//go:build boringcrypto && linux && (amd64 || arm64) && !android && !cmd_go_bootstrap && !msan
 
 package boring
 
@@ -37,7 +36,7 @@
 	panic("boringcrypto: invalid code execution")
 }
 
-// provided by runtime to avoid os import
+// provided by runtime to avoid os import.
 func runtime_arg0() string
 
 func hasSuffix(s, t string) bool {
@@ -72,6 +71,10 @@
 	return C._goboringcrypto_BN_le2bn(wbase(x), C.size_t(len(x)*wordBytes), nil)
 }
 
+func bytesToBN(x []byte) *C.GO_BIGNUM {
+	return C._goboringcrypto_BN_bin2bn((*C.uint8_t)(&x[0]), C.size_t(len(x)), nil)
+}
+
 func bnToBig(bn *C.GO_BIGNUM) BigInt {
 	x := make(BigInt, (C._goboringcrypto_BN_num_bytes(bn)+wordBytes-1)/wordBytes)
 	if C._goboringcrypto_BN_bn2le_padded(wbase(x), C.size_t(len(x)*wordBytes), bn) == 0 {
diff --git a/src/crypto/internal/boring/build-boring.sh b/src/crypto/internal/boring/build-boring.sh
new file mode 100755
index 0000000..db49852
--- /dev/null
+++ b/src/crypto/internal/boring/build-boring.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+# Copyright 2020 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+# Do not run directly; run build.sh, which runs this in Docker.
+# This script builds boringssl, which has already been unpacked in /boring/boringssl.
+
+set -e
+id
+date
+cd /boring
+
+# Go requires -fPIC for linux/amd64 cgo builds.
+# Setting -fPIC only affects the compilation of the non-module code in libcrypto.a,
+# because the FIPS module itself is already built with -fPIC.
+echo '#!/bin/bash
+exec clang-'$ClangV' -DGOBORING -fPIC "$@"
+' >/usr/local/bin/clang
+echo '#!/bin/bash
+exec clang++-'$ClangV' -DGOBORING -fPIC "$@"
+' >/usr/local/bin/clang++
+chmod +x /usr/local/bin/clang /usr/local/bin/clang++
+
+# The BoringSSL tests use Go, and cgo would look for gcc.
+export CGO_ENABLED=0
+
+# Modify the support code crypto/mem.c (outside the FIPS module)
+# to not try to use weak symbols, because they don't work with some
+# Go toolchain / clang toolchain combinations.
+perl -p -i -e 's/defined.*ELF.*defined.*GNUC.*/$0 \&\& !defined(GOBORING)/' boringssl/crypto/mem.c
+
+# Verbatim instructions from BoringCrypto build docs.
+printf "set(CMAKE_C_COMPILER \"clang\")\nset(CMAKE_CXX_COMPILER \"clang++\")\n" >${HOME}/toolchain
+cd boringssl
+mkdir build && cd build && cmake -GNinja -DCMAKE_TOOLCHAIN_FILE=${HOME}/toolchain -DFIPS=1 -DCMAKE_BUILD_TYPE=Release ..
+ninja
+./crypto/crypto_test
+cd ../..
+
+if [ "$(./boringssl/build/tool/bssl isfips)" != 1 ]; then
+	echo "NOT FIPS"
+	exit 2
+fi
diff --git a/src/crypto/internal/boring/build-goboring.sh b/src/crypto/internal/boring/build-goboring.sh
new file mode 100755
index 0000000..4938b5e
--- /dev/null
+++ b/src/crypto/internal/boring/build-goboring.sh
@@ -0,0 +1,237 @@
+#!/bin/bash
+# Copyright 2020 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+# Do not run directly; run build.sh, which runs this in Docker.
+# This script builds goboringcrypto's syso, after boringssl has been built.
+
+export TERM=dumb
+
+set -e
+set -x
+id
+date
+export LANG=C
+unset LANGUAGE
+
+case $(uname -m) in
+x86_64)  export GOARCH=amd64 ;;
+aarch64) export GOARCH=arm64 ;;
+*)
+	echo 'unknown uname -m:' $(uname -m) >&2
+	exit 2
+esac
+
+export CGO_ENABLED=0
+
+# Build and run test C++ program to make sure goboringcrypto.h matches openssl/*.h.
+# Also collect list of checked symbols in syms.txt
+set -e
+cd /boring/godriver
+cat >goboringcrypto.cc <<'EOF'
+#include <cassert>
+#include "goboringcrypto0.h"
+#include "goboringcrypto1.h"
+#define check_size(t) if(sizeof(t) != sizeof(GO_ ## t)) {printf("sizeof(" #t ")=%d, but sizeof(GO_" #t ")=%d\n", (int)sizeof(t), (int)sizeof(GO_ ## t)); ret=1;}
+#define check_func(f) { auto x = f; x = _goboringcrypto_ ## f ; }
+#define check_value(n, v) if(n != v) {printf(#n "=%d, but goboringcrypto.h defines it as %d\n", (int)n, (int)v); ret=1;}
+int main() {
+int ret = 0;
+#include "goboringcrypto.x"
+return ret;
+}
+EOF
+
+cat >boringx.awk <<'EOF'
+BEGIN {
+	exitcode = 0
+}
+
+# Ignore comments, #includes, blank lines.
+/^\/\// || /^#/ || NF == 0 { next }
+
+# Ignore unchecked declarations.
+/\/\*unchecked/ { next }
+
+# Check enum values.
+!enum && ($1 == "enum" || $2 == "enum") && $NF == "{" {
+	enum = 1
+	next
+}
+enum && $1 == "};" {
+	enum = 0
+	next
+}
+enum && /^}.*;$/ {
+	enum = 0
+	next
+}
+enum && NF == 3 && $2 == "=" {
+	name = $1
+	sub(/^GO_/, "", name)
+	val = $3
+	sub(/,$/, "", val)
+	print "check_value(" name ", " val ")" > "goboringcrypto.x"
+	next
+}
+enum {
+	print FILENAME ":" NR ": unexpected line in enum: " $0 > "/dev/stderr"
+	exitcode = 1
+	next
+}
+
+# Check struct sizes.
+/^typedef struct / && $NF ~ /^GO_/ {
+	name = $NF
+	sub(/^GO_/, "", name)
+	sub(/;$/, "", name)
+	print "check_size(" name ")" > "goboringcrypto.x"
+	next
+}
+
+# Check function prototypes.
+/^(const )?[^ ]+ \**_goboringcrypto_.*\(/ {
+	name = $2
+	if($1 == "const")
+		name = $3
+	sub(/^\**_goboringcrypto_/, "", name)
+	sub(/\(.*/, "", name)
+	print "check_func(" name ")" > "goboringcrypto.x"
+	print name > "syms.txt"
+	next
+}
+
+{
+	print FILENAME ":" NR ": unexpected line: " $0 > "/dev/stderr"
+	exitcode = 1
+}
+
+END {
+	exit exitcode
+}
+EOF
+
+cat >boringh.awk <<'EOF'
+/^\/\/ #include/ {sub(/\/\//, ""); print > "goboringcrypto0.h"; next}
+/typedef struct|enum ([a-z_]+ )?{|^[ \t]/ {print >"goboringcrypto1.h";next}
+{gsub(/GO_/, ""); gsub(/enum go_/, "enum "); gsub(/go_point_conv/, "point_conv"); print >"goboringcrypto1.h"}
+EOF
+
+awk -f boringx.awk goboringcrypto.h # writes goboringcrypto.x
+awk -f boringh.awk goboringcrypto.h # writes goboringcrypto[01].h
+
+ls -l ../boringssl/include
+clang++ -std=c++11 -fPIC -I../boringssl/include -O2 -o a.out  goboringcrypto.cc
+./a.out || exit 2
+
+# clang implements u128 % u128 -> u128 by calling __umodti3,
+# which is in libgcc. To make the result self-contained even if linking
+# against a different compiler version, link our own __umodti3 into the syso.
+# This one is specialized so it only expects divisors below 2^64,
+# which is all BoringCrypto uses. (Otherwise it will seg fault.)
+cat >umod-amd64.s <<'EOF'
+# tu_int __umodti3(tu_int x, tu_int y)
+# x is rsi:rdi, y is rcx:rdx, return result is rdx:rax.
+.globl __umodti3
+__umodti3:
+	# specialized to u128 % u64, so verify that
+	test %rcx,%rcx
+	jne 1f
+
+	# save divisor
+	movq %rdx, %r8
+
+	# reduce top 64 bits mod divisor
+	movq %rsi, %rax
+	xorl %edx, %edx
+	divq %r8
+
+	# reduce full 128-bit mod divisor
+	# quotient fits in 64 bits because top 64 bits have been reduced < divisor.
+	# (even though we only care about the remainder, divq also computes
+	# the quotient, and it will trap if the quotient is too large.)
+	movq %rdi, %rax
+	divq %r8
+
+	# expand remainder to 128 for return
+	movq %rdx, %rax
+	xorl %edx, %edx
+	ret
+
+1:
+	# crash - only want 64-bit divisor
+	xorl %ecx, %ecx
+	movl %ecx, 0(%ecx)
+	jmp 1b
+
+.section .note.GNU-stack,"",@progbits
+EOF
+
+cat >umod-arm64.c <<'EOF'
+typedef unsigned int u128 __attribute__((mode(TI)));
+
+static u128 div(u128 x, u128 y, u128 *rp) {
+	int n = 0;
+	while((y>>(128-1)) != 1 && y < x) {
+		y<<=1;
+		n++;
+	}
+	u128 q = 0;
+	for(;; n--, y>>=1, q<<=1) {
+		if(x>=y) {
+			x -= y;
+			q |= 1;
+		}
+		if(n == 0)
+			break;
+	}
+	if(rp)
+		*rp = x;
+	return q;
+}
+
+u128 __umodti3(u128 x, u128 y) {
+	u128 r;
+	div(x, y, &r);
+	return r;
+}
+
+u128 __udivti3(u128 x, u128 y) {
+	return div(x, y, 0);
+}
+EOF
+
+extra=""
+case $GOARCH in
+amd64)
+	cp umod-amd64.s umod.s
+	clang -c -o umod.o umod.s
+	extra=umod.o
+	;;
+arm64)
+	cp umod-arm64.c umod.c
+	clang -c -o umod.o umod.c
+	extra=umod.o
+	;;
+esac
+
+# Prepare copy of libcrypto.a with only the checked functions renamed and exported.
+# All other symbols are left alone and hidden.
+echo BORINGSSL_bcm_power_on_self_test >>syms.txt
+awk '{print "_goboringcrypto_" $0 }' syms.txt >globals.txt
+awk '{print $0 " _goboringcrypto_" $0 }' syms.txt >renames.txt
+objcopy --globalize-symbol=BORINGSSL_bcm_power_on_self_test \
+	../boringssl/build/crypto/libcrypto.a libcrypto.a
+
+# Link together bcm.o and libcrypto.a into a single object.
+ld -r -nostdlib --whole-archive -o goboringcrypto.o libcrypto.a $extra
+
+echo __umodti3 _goboringcrypto___umodti3 >>renames.txt
+echo __udivti3 _goboringcrypto___udivti3 >>renames.txt
+objcopy --remove-section=.llvm_addrsig goboringcrypto.o goboringcrypto1.o # b/179161016
+objcopy --redefine-syms=renames.txt goboringcrypto1.o goboringcrypto2.o
+objcopy --keep-global-symbols=globals.txt --strip-unneeded goboringcrypto2.o goboringcrypto_linux_$GOARCH.syso
+
+# Done!
+ls -l goboringcrypto_linux_$GOARCH.syso
diff --git a/src/crypto/internal/boring/build.sh b/src/crypto/internal/boring/build.sh
index 31e98cb..ec960d7 100755
--- a/src/crypto/internal/boring/build.sh
+++ b/src/crypto/internal/boring/build.sh
@@ -1,196 +1,46 @@
 #!/bin/bash
-# Copyright 2020 The Go Authors. All rights reserved.
+# Copyright 2022 The Go Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style
 # license that can be found in the LICENSE file.
 
+# This shell script uses Docker to run build-boring.sh and build-goboring.sh,
+# which build goboringcrypto_linux_$GOARCH.syso according to the Security Policy.
+# Currently, amd64 and arm64 are permitted.
+
 set -e
-id
-date
-export LANG=C
-unset LANGUAGE
+set -o pipefail
 
-# Build BoringCrypto libcrypto.a.
-# Following https://csrc.nist.gov/CSRC/media/projects/cryptographic-module-validation-program/documents/security-policies/140sp3678.pdf page 19.
+GOARCH=${GOARCH:-$(go env GOARCH)}
+echo "# Building goboringcrypto_linux_$GOARCH.syso. Set GOARCH to override." >&2
 
-tar xJf boringssl-*z
-
-# Go requires -fPIC for linux/amd64 cgo builds.
-# Setting -fPIC only affects the compilation of the non-module code in libcrypto.a,
-# because the FIPS module itself is already built with -fPIC.
-echo '#!/bin/bash
-exec clang-7 -fPIC "$@"
-' >/usr/local/bin/clang
-echo '#!/bin/bash
-exec clang++-7 -fPIC "$@"
-' >/usr/local/bin/clang++
-chmod +x /usr/local/bin/clang /usr/local/bin/clang++
-
-# The BoringSSL tests use Go, and cgo would look for gcc.
-export CGO_ENABLED=0
-
-# Verbatim instructions from BoringCrypto build docs.
-printf "set(CMAKE_C_COMPILER \"clang\")\nset(CMAKE_CXX_COMPILER \"clang++\")\n" >${HOME}/toolchain
-cd boringssl
-mkdir build && cd build && cmake -GNinja -DCMAKE_TOOLCHAIN_FILE=${HOME}/toolchain -DFIPS=1 -DCMAKE_BUILD_TYPE=Release ..
-ninja
-ninja run_tests
-
-cd ../..
-
-if [ "$(./boringssl/build/tool/bssl isfips)" != 1 ]; then
-	echo "NOT FIPS"
-	exit 2
+if ! which docker >/dev/null; then
+	echo "# Docker not found. Inside Google, see go/installdocker." >&2
+	exit 1
 fi
 
-# Build and run test C++ program to make sure goboringcrypto.h matches openssl/*.h.
-# Also collect list of checked symbols in syms.txt
-set -x
-set -e
-cd godriver
-cat >goboringcrypto.cc <<'EOF'
-#include <cassert>
-#include "goboringcrypto0.h"
-#include "goboringcrypto1.h"
-#define check_size(t) if(sizeof(t) != sizeof(GO_ ## t)) {printf("sizeof(" #t ")=%d, but sizeof(GO_" #t ")=%d\n", (int)sizeof(t), (int)sizeof(GO_ ## t)); ret=1;}
-#define check_func(f) { auto x = f; x = _goboringcrypto_ ## f ; }
-#define check_value(n, v) if(n != v) {printf(#n "=%d, but goboringcrypto.h defines it as %d\n", (int)n, (int)v); ret=1;}
-int main() {
-int ret = 0;
-#include "goboringcrypto.x"
-return ret;
-}
-EOF
+platform=""
+buildargs=""
+case "$GOARCH" in
+amd64)
+	;;
+arm64)
+	if ! docker run --rm -t arm64v8/ubuntu:focal uname -m >/dev/null 2>&1; then
+		echo "# Docker cannot run arm64 binaries. Try:"
+		echo "	sudo apt-get install qemu binfmt-support qemu-user-static"
+		echo "	docker run --rm --privileged multiarch/qemu-user-static --reset -p yes"
+		echo "	docker run --rm -t arm64v8/ubuntu:focal uname -m"
+		exit 1
+	fi
+	platform="--platform linux/arm64/v8"
+	buildargs="--build-arg ubuntu=arm64v8/ubuntu"
+	;;
+*)
+	echo unknown GOARCH $GOARCH >&2
+	exit 2
+esac
 
-awk '
-BEGIN {
-	exitcode = 0
-}
-
-# Ignore comments, #includes, blank lines.
-/^\/\// || /^#/ || NF == 0 { next }
-
-# Ignore unchecked declarations.
-/\/\*unchecked/ { next }
-
-# Check enum values.
-!enum && $1 == "enum" && $NF == "{" {
-	enum = 1
-	next
-}
-enum && $1 == "};" {
-	enum = 0
-	next
-}
-enum && NF == 3 && $2 == "=" {
-	name = $1
-	sub(/^GO_/, "", name)
-	val = $3
-	sub(/,$/, "", val)
-	print "check_value(" name ", " val ")" > "goboringcrypto.x"
-	next
-}
-enum {
-	print FILENAME ":" NR ": unexpected line in enum: " $0 > "/dev/stderr"
-	exitcode = 1
-	next
-}
-
-# Check struct sizes.
-/^typedef struct / && $NF ~ /^GO_/ {
-	name = $NF
-	sub(/^GO_/, "", name)
-	sub(/;$/, "", name)
-	print "check_size(" name ")" > "goboringcrypto.x"
-	next
-}
-
-# Check function prototypes.
-/^(const )?[^ ]+ \**_goboringcrypto_.*\(/ {
-	name = $2
-	if($1 == "const")
-		name = $3
-	sub(/^\**_goboringcrypto_/, "", name)
-	sub(/\(.*/, "", name)
-	print "check_func(" name ")" > "goboringcrypto.x"
-	print name > "syms.txt"
-	next
-}
-
-{
-	print FILENAME ":" NR ": unexpected line: " $0 > "/dev/stderr"
-	exitcode = 1
-}
-
-END {
-	exit exitcode
-}
-' goboringcrypto.h
-
-cat goboringcrypto.h | awk '
-	/^\/\/ #include/ {sub(/\/\//, ""); print > "goboringcrypto0.h"; next}
-	/typedef struct|enum ([a-z_]+ )?{|^[ \t]/ {print;next}
-	{gsub(/GO_/, ""); gsub(/enum go_/, "enum "); print}
-' >goboringcrypto1.h
-clang++ -std=c++11 -fPIC -I../boringssl/include -O2 -o a.out  goboringcrypto.cc
-./a.out || exit 2
-
-# Prepare copy of libcrypto.a with only the checked functions renamed and exported.
-# All other symbols are left alone and hidden.
-echo BORINGSSL_bcm_power_on_self_test >>syms.txt
-awk '{print "_goboringcrypto_" $0 }' syms.txt >globals.txt
-awk '{print $0 " _goboringcrypto_" $0 }' syms.txt >renames.txt
-objcopy --globalize-symbol=BORINGSSL_bcm_power_on_self_test ../boringssl/build/crypto/libcrypto.a libcrypto.a
-
-# clang implements u128 % u128 -> u128 by calling __umodti3,
-# which is in libgcc. To make the result self-contained even if linking
-# against a different compiler version, link our own __umodti3 into the syso.
-# This one is specialized so it only expects divisors below 2^64,
-# which is all BoringCrypto uses. (Otherwise it will seg fault.)
-cat >umod.s <<'EOF'
-# tu_int __umodti3(tu_int x, tu_int y)
-# x is rsi:rdi, y is rcx:rdx, return result is rdx:rax.
-.globl __umodti3
-__umodti3:
-	# specialized to u128 % u64, so verify that
-	test %rcx,%rcx
-	jne 1f
-
-	# save divisor
-	movq %rdx, %r8
-
-	# reduce top 64 bits mod divisor
-	movq %rsi, %rax
-	xorl %edx, %edx
-	divq %r8
-
-	# reduce full 128-bit mod divisor
-	# quotient fits in 64 bits because top 64 bits have been reduced < divisor.
-	# (even though we only care about the remainder, divq also computes
-	# the quotient, and it will trap if the quotient is too large.)
-	movq %rdi, %rax
-	divq %r8
-
-	# expand remainder to 128 for return
-	movq %rdx, %rax
-	xorl %edx, %edx
-	ret
-
-1:
-	# crash - only want 64-bit divisor
-	xorl %ecx, %ecx
-	movl %ecx, 0(%ecx)
-	jmp 1b
-
-.section .note.GNU-stack,"",@progbits
-EOF
-clang -c -o umod.o umod.s
-
-ld -r -nostdlib --whole-archive -o goboringcrypto.o libcrypto.a umod.o
-echo __umodti3 _goboringcrypto___umodti3 >>renames.txt
-objcopy --remove-section=.llvm_addrsig goboringcrypto.o goboringcrypto1.o # b/179161016
-objcopy --redefine-syms=renames.txt goboringcrypto1.o goboringcrypto2.o
-objcopy --keep-global-symbols=globals.txt goboringcrypto2.o goboringcrypto_linux_amd64.syso
-
-# Done!
-ls -l goboringcrypto_linux_amd64.syso
-sha256sum goboringcrypto_linux_amd64.syso
+docker build $platform $buildargs --build-arg GOARCH=$GOARCH -t goboring:$GOARCH .
+id=$(docker create $platform goboring:$GOARCH)
+docker cp $id:/boring/godriver/goboringcrypto_linux_$GOARCH.syso ./syso
+docker rm $id
+ls -l ./syso/goboringcrypto_linux_$GOARCH.syso
diff --git a/src/crypto/internal/boring/div_test.c b/src/crypto/internal/boring/div_test.c
new file mode 100644
index 0000000..f909cc9
--- /dev/null
+++ b/src/crypto/internal/boring/div_test.c
@@ -0,0 +1,83 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file is a self-contained test for a copy of
+// the division algorithm in build-goboring.sh,
+// to verify that is correct. The real algorithm uses u128
+// but this copy uses u32 for easier testing.
+// s/32/128/g should be the only difference between the two.
+//
+// This is the dumbest possible division algorithm,
+// but any crypto code that depends on the speed of
+// division is equally dumb.
+
+//go:build ignore
+
+#include <stdio.h>
+#include <stdint.h>
+
+#define nelem(x) (sizeof(x)/sizeof((x)[0]))
+
+typedef uint32_t u32;
+
+static u32 div(u32 x, u32 y, u32 *rp) {
+	int n = 0;
+	while((y>>(32-1)) != 1 && y < x) {
+		y<<=1;
+		n++;
+	}
+	u32 q = 0;
+	for(;; n--, y>>=1, q<<=1) {
+		if(x>=y) {
+			x -= y;
+			q |= 1;
+		}
+		if(n == 0)
+			break;
+	}
+	if(rp)
+		*rp = x;
+	return q;
+}
+
+u32 tests[] = {
+	0,
+	1,
+	2,
+	3,
+	4,
+	5,
+	6,
+	7,
+	8,
+	9,
+	10,
+	11,
+	31,
+	0xFFF,
+	0x1000,
+	0x1001,
+	0xF0F0F0,
+	0xFFFFFF,
+	0x1000000,
+	0xF0F0F0F0,
+	0xFFFFFFFF,
+};
+
+int
+main(void)
+{
+	for(int i=0; i<nelem(tests); i++)
+	for(int j=0; j<nelem(tests); j++) {
+		u32 n = tests[i];
+		u32 d = tests[j];
+		if(d == 0)
+			continue;
+		u32 r;
+		u32 q = div(n, d, &r);
+		if(q != n/d || r != n%d)
+			printf("div(%x, %x) = %x, %x, want %x, %x\n", n, d, q, r, n/d, n%d);
+	}
+	return 0;
+}
diff --git a/src/crypto/internal/boring/ecdh.go b/src/crypto/internal/boring/ecdh.go
new file mode 100644
index 0000000..8f46d81
--- /dev/null
+++ b/src/crypto/internal/boring/ecdh.go
@@ -0,0 +1,224 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build boringcrypto && linux && (amd64 || arm64) && !android && !cmd_go_bootstrap && !msan
+
+package boring
+
+// #include "goboringcrypto.h"
+import "C"
+import (
+	"errors"
+	"runtime"
+	"unsafe"
+)
+
+type PublicKeyECDH struct {
+	curve string
+	key   *C.GO_EC_POINT
+	group *C.GO_EC_GROUP
+	bytes []byte
+}
+
+func (k *PublicKeyECDH) finalize() {
+	C._goboringcrypto_EC_POINT_free(k.key)
+}
+
+type PrivateKeyECDH struct {
+	curve string
+	key   *C.GO_EC_KEY
+}
+
+func (k *PrivateKeyECDH) finalize() {
+	C._goboringcrypto_EC_KEY_free(k.key)
+}
+
+func NewPublicKeyECDH(curve string, bytes []byte) (*PublicKeyECDH, error) {
+	if len(bytes) < 1 {
+		return nil, errors.New("NewPublicKeyECDH: missing key")
+	}
+
+	nid, err := curveNID(curve)
+	if err != nil {
+		return nil, err
+	}
+
+	group := C._goboringcrypto_EC_GROUP_new_by_curve_name(nid)
+	if group == nil {
+		return nil, fail("EC_GROUP_new_by_curve_name")
+	}
+	defer C._goboringcrypto_EC_GROUP_free(group)
+	key := C._goboringcrypto_EC_POINT_new(group)
+	if key == nil {
+		return nil, fail("EC_POINT_new")
+	}
+	ok := C._goboringcrypto_EC_POINT_oct2point(group, key, (*C.uint8_t)(unsafe.Pointer(&bytes[0])), C.size_t(len(bytes)), nil) != 0
+	if !ok {
+		C._goboringcrypto_EC_POINT_free(key)
+		return nil, errors.New("point not on curve")
+	}
+
+	k := &PublicKeyECDH{curve, key, group, append([]byte(nil), bytes...)}
+	// Note: Because of the finalizer, any time k.key is passed to cgo,
+	// that call must be followed by a call to runtime.KeepAlive(k),
+	// to make sure k is not collected (and finalized) before the cgo
+	// call returns.
+	runtime.SetFinalizer(k, (*PublicKeyECDH).finalize)
+	return k, nil
+}
+
+func (k *PublicKeyECDH) Bytes() []byte { return k.bytes }
+
+func NewPrivateKeyECDH(curve string, bytes []byte) (*PrivateKeyECDH, error) {
+	nid, err := curveNID(curve)
+	if err != nil {
+		return nil, err
+	}
+	key := C._goboringcrypto_EC_KEY_new_by_curve_name(nid)
+	if key == nil {
+		return nil, fail("EC_KEY_new_by_curve_name")
+	}
+	b := bytesToBN(bytes)
+	ok := b != nil && C._goboringcrypto_EC_KEY_set_private_key(key, b) != 0
+	if b != nil {
+		C._goboringcrypto_BN_free(b)
+	}
+	if !ok {
+		C._goboringcrypto_EC_KEY_free(key)
+		return nil, fail("EC_KEY_set_private_key")
+	}
+	k := &PrivateKeyECDH{curve, key}
+	// Note: Same as in NewPublicKeyECDH regarding finalizer and KeepAlive.
+	runtime.SetFinalizer(k, (*PrivateKeyECDH).finalize)
+	return k, nil
+}
+
+func (k *PrivateKeyECDH) PublicKey() (*PublicKeyECDH, error) {
+	defer runtime.KeepAlive(k)
+
+	group := C._goboringcrypto_EC_KEY_get0_group(k.key)
+	if group == nil {
+		return nil, fail("EC_KEY_get0_group")
+	}
+	kbig := C._goboringcrypto_EC_KEY_get0_private_key(k.key)
+	if kbig == nil {
+		return nil, fail("EC_KEY_get0_private_key")
+	}
+	pt := C._goboringcrypto_EC_POINT_new(group)
+	if pt == nil {
+		return nil, fail("EC_POINT_new")
+	}
+	if C._goboringcrypto_EC_POINT_mul(group, pt, kbig, nil, nil, nil) == 0 {
+		C._goboringcrypto_EC_POINT_free(pt)
+		return nil, fail("EC_POINT_mul")
+	}
+	bytes, err := pointBytesECDH(k.curve, group, pt)
+	if err != nil {
+		C._goboringcrypto_EC_POINT_free(pt)
+		return nil, err
+	}
+	pub := &PublicKeyECDH{k.curve, pt, group, bytes}
+	// Note: Same as in NewPublicKeyECDH regarding finalizer and KeepAlive.
+	runtime.SetFinalizer(pub, (*PublicKeyECDH).finalize)
+	return pub, nil
+}
+
+func pointBytesECDH(curve string, group *C.GO_EC_GROUP, pt *C.GO_EC_POINT) ([]byte, error) {
+	out := make([]byte, 1+2*curveSize(curve))
+	n := C._goboringcrypto_EC_POINT_point2oct(group, pt, C.GO_POINT_CONVERSION_UNCOMPRESSED, (*C.uint8_t)(unsafe.Pointer(&out[0])), C.size_t(len(out)), nil)
+	if int(n) != len(out) {
+		return nil, fail("EC_POINT_point2oct")
+	}
+	return out, nil
+}
+
+func ECDH(priv *PrivateKeyECDH, pub *PublicKeyECDH) ([]byte, error) {
+	group := C._goboringcrypto_EC_KEY_get0_group(priv.key)
+	if group == nil {
+		return nil, fail("EC_KEY_get0_group")
+	}
+	privBig := C._goboringcrypto_EC_KEY_get0_private_key(priv.key)
+	if privBig == nil {
+		return nil, fail("EC_KEY_get0_private_key")
+	}
+	pt := C._goboringcrypto_EC_POINT_new(group)
+	if pt == nil {
+		return nil, fail("EC_POINT_new")
+	}
+	defer C._goboringcrypto_EC_POINT_free(pt)
+	if C._goboringcrypto_EC_POINT_mul(group, pt, nil, pub.key, privBig, nil) == 0 {
+		return nil, fail("EC_POINT_mul")
+	}
+	out, err := xCoordBytesECDH(priv.curve, group, pt)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func xCoordBytesECDH(curve string, group *C.GO_EC_GROUP, pt *C.GO_EC_POINT) ([]byte, error) {
+	big := C._goboringcrypto_BN_new()
+	defer C._goboringcrypto_BN_free(big)
+	if C._goboringcrypto_EC_POINT_get_affine_coordinates_GFp(group, pt, big, nil, nil) == 0 {
+		return nil, fail("EC_POINT_get_affine_coordinates_GFp")
+	}
+	return bigBytesECDH(curve, big)
+}
+
+func bigBytesECDH(curve string, big *C.GO_BIGNUM) ([]byte, error) {
+	out := make([]byte, curveSize(curve))
+	if C._goboringcrypto_BN_bn2bin_padded((*C.uint8_t)(&out[0]), C.size_t(len(out)), big) == 0 {
+		return nil, fail("BN_bn2bin_padded")
+	}
+	return out, nil
+}
+
+func curveSize(curve string) int {
+	switch curve {
+	default:
+		panic("crypto/internal/boring: unknown curve " + curve)
+	case "P-256":
+		return 256 / 8
+	case "P-384":
+		return 384 / 8
+	case "P-521":
+		return (521 + 7) / 8
+	}
+}
+
+func GenerateKeyECDH(curve string) (*PrivateKeyECDH, []byte, error) {
+	nid, err := curveNID(curve)
+	if err != nil {
+		return nil, nil, err
+	}
+	key := C._goboringcrypto_EC_KEY_new_by_curve_name(nid)
+	if key == nil {
+		return nil, nil, fail("EC_KEY_new_by_curve_name")
+	}
+	if C._goboringcrypto_EC_KEY_generate_key_fips(key) == 0 {
+		C._goboringcrypto_EC_KEY_free(key)
+		return nil, nil, fail("EC_KEY_generate_key_fips")
+	}
+
+	group := C._goboringcrypto_EC_KEY_get0_group(key)
+	if group == nil {
+		C._goboringcrypto_EC_KEY_free(key)
+		return nil, nil, fail("EC_KEY_get0_group")
+	}
+	b := C._goboringcrypto_EC_KEY_get0_private_key(key)
+	if b == nil {
+		C._goboringcrypto_EC_KEY_free(key)
+		return nil, nil, fail("EC_KEY_get0_private_key")
+	}
+	bytes, err := bigBytesECDH(curve, b)
+	if err != nil {
+		C._goboringcrypto_EC_KEY_free(key)
+		return nil, nil, err
+	}
+
+	k := &PrivateKeyECDH{curve, key}
+	// Note: Same as in NewPublicKeyECDH regarding finalizer and KeepAlive.
+	runtime.SetFinalizer(k, (*PrivateKeyECDH).finalize)
+	return k, bytes, nil
+}
diff --git a/src/crypto/internal/boring/ecdsa.go b/src/crypto/internal/boring/ecdsa.go
index 884c4b7..e15f368 100644
--- a/src/crypto/internal/boring/ecdsa.go
+++ b/src/crypto/internal/boring/ecdsa.go
@@ -2,8 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build boringcrypto && linux && amd64 && !android && !cmd_go_bootstrap && !msan
-// +build boringcrypto,linux,amd64,!android,!cmd_go_bootstrap,!msan
+//go:build boringcrypto && linux && (amd64 || arm64) && !android && !cmd_go_bootstrap && !msan
 
 package boring
 
@@ -12,7 +11,6 @@
 import (
 	"errors"
 	"runtime"
-	"unsafe"
 )
 
 type ecdsaSignature struct {
@@ -125,7 +123,7 @@
 	size := C._goboringcrypto_ECDSA_size(priv.key)
 	sig := make([]byte, size)
 	var sigLen C.uint
-	if C._goboringcrypto_ECDSA_sign(0, base(hash), C.size_t(len(hash)), (*C.uint8_t)(unsafe.Pointer(&sig[0])), &sigLen, priv.key) == 0 {
+	if C._goboringcrypto_ECDSA_sign(0, base(hash), C.size_t(len(hash)), base(sig), &sigLen, priv.key) == 0 {
 		return nil, fail("ECDSA_sign")
 	}
 	runtime.KeepAlive(priv)
@@ -133,7 +131,7 @@
 }
 
 func VerifyECDSA(pub *PublicKeyECDSA, hash []byte, sig []byte) bool {
-	ok := C._goboringcrypto_ECDSA_verify(0, base(hash), C.size_t(len(hash)), (*C.uint8_t)(unsafe.Pointer(&sig[0])), C.size_t(len(sig)), pub.key) != 0
+	ok := C._goboringcrypto_ECDSA_verify(0, base(hash), C.size_t(len(hash)), base(sig), C.size_t(len(sig)), pub.key) != 0
 	runtime.KeepAlive(pub)
 	return ok
 }
diff --git a/src/crypto/internal/boring/fipstls/tls.go b/src/crypto/internal/boring/fipstls/tls.go
index 701700e..3bf1471 100644
--- a/src/crypto/internal/boring/fipstls/tls.go
+++ b/src/crypto/internal/boring/fipstls/tls.go
@@ -11,7 +11,7 @@
 
 import "sync/atomic"
 
-var required uint32
+var required atomic.Bool
 
 // Force forces crypto/tls to restrict TLS configurations to FIPS-approved settings.
 // By design, this call is impossible to undo (except in tests).
@@ -19,7 +19,7 @@
 // Note that this call has an effect even in programs using
 // standard crypto (that is, even when Enabled = false).
 func Force() {
-	atomic.StoreUint32(&required, 1)
+	required.Store(true)
 }
 
 // Abandon allows non-FIPS-approved settings.
@@ -36,7 +36,7 @@
 	if !hasSuffix(name, "_test") && !hasSuffix(name, ".test") && name != "NaClMain" && name != "" {
 		panic("fipstls: invalid use of Abandon in " + name)
 	}
-	atomic.StoreUint32(&required, 0)
+	required.Store(false)
 }
 
 // provided by runtime
@@ -48,5 +48,5 @@
 
 // Required reports whether FIPS-approved settings are required.
 func Required() bool {
-	return atomic.LoadUint32(&required) != 0
+	return required.Load()
 }
diff --git a/src/crypto/internal/boring/goboringcrypto.h b/src/crypto/internal/boring/goboringcrypto.h
index d6d99b1..2b11049 100644
--- a/src/crypto/internal/boring/goboringcrypto.h
+++ b/src/crypto/internal/boring/goboringcrypto.h
@@ -144,6 +144,7 @@
 GO_BIGNUM* _goboringcrypto_BN_le2bn(const uint8_t*, size_t, GO_BIGNUM*);
 size_t _goboringcrypto_BN_bn2bin(const GO_BIGNUM*, uint8_t*);
 int _goboringcrypto_BN_bn2le_padded(uint8_t*, size_t, const GO_BIGNUM*);
+int _goboringcrypto_BN_bn2bin_padded(uint8_t*, size_t, const GO_BIGNUM*);
 
 // #include <openssl/ec.h>
 /*unchecked (opaque)*/ typedef struct GO_EC_GROUP { char data[1]; } GO_EC_GROUP;
@@ -152,9 +153,21 @@
 
 /*unchecked (opaque)*/ typedef struct GO_EC_POINT { char data[1]; } GO_EC_POINT;
 GO_EC_POINT* _goboringcrypto_EC_POINT_new(const GO_EC_GROUP*);
+int _goboringcrypto_EC_POINT_mul(const GO_EC_GROUP*, GO_EC_POINT*, const GO_BIGNUM*, const GO_EC_POINT*, const GO_BIGNUM*, GO_BN_CTX*);
 void _goboringcrypto_EC_POINT_free(GO_EC_POINT*);
 int _goboringcrypto_EC_POINT_get_affine_coordinates_GFp(const GO_EC_GROUP*, const GO_EC_POINT*, GO_BIGNUM*, GO_BIGNUM*, GO_BN_CTX*);
 int _goboringcrypto_EC_POINT_set_affine_coordinates_GFp(const GO_EC_GROUP*, GO_EC_POINT*, const GO_BIGNUM*, const GO_BIGNUM*, GO_BN_CTX*);
+int _goboringcrypto_EC_POINT_oct2point(const GO_EC_GROUP*, GO_EC_POINT*, const uint8_t*, size_t, GO_BN_CTX*);
+GO_EC_POINT* _goboringcrypto_EC_POINT_dup(const GO_EC_POINT*, const GO_EC_GROUP*);
+int _goboringcrypto_EC_POINT_is_on_curve(const GO_EC_GROUP*, const GO_EC_POINT*, GO_BN_CTX*);
+#ifndef OPENSSL_HEADER_EC_H
+typedef enum {
+	GO_POINT_CONVERSION_COMPRESSED = 2,
+	GO_POINT_CONVERSION_UNCOMPRESSED = 4,
+	GO_POINT_CONVERSION_HYBRID = 6,
+} go_point_conversion_form_t;
+#endif
+size_t _goboringcrypto_EC_POINT_point2oct(const GO_EC_GROUP*, const GO_EC_POINT*, go_point_conversion_form_t, uint8_t*, size_t, GO_BN_CTX*);
 
 // #include <openssl/ec_key.h>
 /*unchecked (opaque)*/ typedef struct GO_EC_KEY { char data[1]; } GO_EC_KEY;
@@ -170,6 +183,9 @@
 const GO_EC_POINT* _goboringcrypto_EC_KEY_get0_public_key(const GO_EC_KEY*);
 // TODO: EC_KEY_check_fips?
 
+// #include <openssl/ecdh.h>
+int _goboringcrypto_ECDH_compute_key_fips(uint8_t*, size_t, const GO_EC_POINT*, const GO_EC_KEY*);
+
 // #include <openssl/ecdsa.h>
 typedef struct GO_ECDSA_SIG { char data[16]; } GO_ECDSA_SIG;
 GO_ECDSA_SIG* _goboringcrypto_ECDSA_SIG_new(void);
@@ -183,7 +199,7 @@
 // #include <openssl/rsa.h>
 
 // Note: order of struct fields here is unchecked.
-typedef struct GO_RSA { void *meth; GO_BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp; char data[160]; } GO_RSA;
+typedef struct GO_RSA { void *meth; GO_BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp; char data[168]; } GO_RSA;
 /*unchecked (opaque)*/ typedef struct GO_BN_GENCB { char data[1]; } GO_BN_GENCB;
 GO_RSA* _goboringcrypto_RSA_new(void);
 void _goboringcrypto_RSA_free(GO_RSA*);
diff --git a/src/crypto/internal/boring/hmac.go b/src/crypto/internal/boring/hmac.go
index c36fe6b..6241a65 100644
--- a/src/crypto/internal/boring/hmac.go
+++ b/src/crypto/internal/boring/hmac.go
@@ -2,14 +2,14 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build boringcrypto && linux && amd64 && !android && !cmd_go_bootstrap && !msan
-// +build boringcrypto,linux,amd64,!android,!cmd_go_bootstrap,!msan
+//go:build boringcrypto && linux && (amd64 || arm64) && !android && !cmd_go_bootstrap && !msan
 
 package boring
 
 // #include "goboringcrypto.h"
 import "C"
 import (
+	"bytes"
 	"crypto"
 	"hash"
 	"runtime"
@@ -68,8 +68,7 @@
 	}
 
 	// Note: Could hash down long keys here using EVP_Digest.
-	hkey := make([]byte, len(key))
-	copy(hkey, key)
+	hkey := bytes.Clone(key)
 	hmac := &boringHMAC{
 		md:        md,
 		size:      ch.Size(),
diff --git a/src/crypto/internal/boring/notboring.go b/src/crypto/internal/boring/notboring.go
index 53096a6..1c5e4c7 100644
--- a/src/crypto/internal/boring/notboring.go
+++ b/src/crypto/internal/boring/notboring.go
@@ -2,8 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build !boringcrypto || !linux || !amd64 || !cgo || android || cmd_go_bootstrap || msan
-// +build !boringcrypto !linux !amd64 !cgo android cmd_go_bootstrap msan
+//go:build !(boringcrypto && linux && (amd64 || arm64) && !android && !cmd_go_bootstrap && !msan && cgo)
 
 package boring
 
@@ -74,7 +73,7 @@
 type PublicKeyRSA struct{ _ int }
 type PrivateKeyRSA struct{ _ int }
 
-func DecryptRSAOAEP(h hash.Hash, priv *PrivateKeyRSA, ciphertext, label []byte) ([]byte, error) {
+func DecryptRSAOAEP(h, mgfHash hash.Hash, priv *PrivateKeyRSA, ciphertext, label []byte) ([]byte, error) {
 	panic("boringcrypto: not available")
 }
 func DecryptRSAPKCS1(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) {
@@ -83,7 +82,7 @@
 func DecryptRSANoPadding(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) {
 	panic("boringcrypto: not available")
 }
-func EncryptRSAOAEP(h hash.Hash, pub *PublicKeyRSA, msg, label []byte) ([]byte, error) {
+func EncryptRSAOAEP(h, mgfHash hash.Hash, pub *PublicKeyRSA, msg, label []byte) ([]byte, error) {
 	panic("boringcrypto: not available")
 }
 func EncryptRSAPKCS1(pub *PublicKeyRSA, msg []byte) ([]byte, error) {
@@ -111,3 +110,13 @@
 func VerifyRSAPSS(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte, saltLen int) error {
 	panic("boringcrypto: not available")
 }
+
+type PublicKeyECDH struct{}
+type PrivateKeyECDH struct{}
+
+func ECDH(*PrivateKeyECDH, *PublicKeyECDH) ([]byte, error)      { panic("boringcrypto: not available") }
+func GenerateKeyECDH(string) (*PrivateKeyECDH, []byte, error)   { panic("boringcrypto: not available") }
+func NewPrivateKeyECDH(string, []byte) (*PrivateKeyECDH, error) { panic("boringcrypto: not available") }
+func NewPublicKeyECDH(string, []byte) (*PublicKeyECDH, error)   { panic("boringcrypto: not available") }
+func (*PublicKeyECDH) Bytes() []byte                            { panic("boringcrypto: not available") }
+func (*PrivateKeyECDH) PublicKey() (*PublicKeyECDH, error)      { panic("boringcrypto: not available") }
diff --git a/src/crypto/internal/boring/rand.go b/src/crypto/internal/boring/rand.go
index d2e432e..7639c01 100644
--- a/src/crypto/internal/boring/rand.go
+++ b/src/crypto/internal/boring/rand.go
@@ -2,8 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build boringcrypto && linux && amd64 && !android && !cmd_go_bootstrap && !msan
-// +build boringcrypto,linux,amd64,!android,!cmd_go_bootstrap,!msan
+//go:build boringcrypto && linux && (amd64 || arm64) && !android && !cmd_go_bootstrap && !msan
 
 package boring
 
diff --git a/src/crypto/internal/boring/rsa.go b/src/crypto/internal/boring/rsa.go
index 64c83c2..fa693ea 100644
--- a/src/crypto/internal/boring/rsa.go
+++ b/src/crypto/internal/boring/rsa.go
@@ -2,8 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build boringcrypto && linux && amd64 && !android && !cmd_go_bootstrap && !msan
-// +build boringcrypto,linux,amd64,!android,!cmd_go_bootstrap,!msan
+//go:build boringcrypto && linux && (amd64 || arm64) && !android && !cmd_go_bootstrap && !msan
 
 package boring
 
@@ -110,7 +109,7 @@
 }
 
 func setupRSA(withKey func(func(*C.GO_RSA) C.int) C.int,
-	padding C.int, h hash.Hash, label []byte, saltLen int, ch crypto.Hash,
+	padding C.int, h, mgfHash hash.Hash, label []byte, saltLen int, ch crypto.Hash,
 	init func(*C.GO_EVP_PKEY_CTX) C.int) (pkey *C.GO_EVP_PKEY, ctx *C.GO_EVP_PKEY_CTX, err error) {
 	defer func() {
 		if err != nil {
@@ -149,9 +148,16 @@
 		if md == nil {
 			return nil, nil, errors.New("crypto/rsa: unsupported hash function")
 		}
+		mgfMD := hashToMD(mgfHash)
+		if mgfMD == nil {
+			return nil, nil, errors.New("crypto/rsa: unsupported hash function")
+		}
 		if C._goboringcrypto_EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md) == 0 {
 			return nil, nil, fail("EVP_PKEY_set_rsa_oaep_md")
 		}
+		if C._goboringcrypto_EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, mgfMD) == 0 {
+			return nil, nil, fail("EVP_PKEY_set_rsa_mgf1_md")
+		}
 		// ctx takes ownership of label, so malloc a copy for BoringCrypto to free.
 		clabel := (*C.uint8_t)(C._goboringcrypto_OPENSSL_malloc(C.size_t(len(label))))
 		if clabel == nil {
@@ -181,12 +187,12 @@
 }
 
 func cryptRSA(withKey func(func(*C.GO_RSA) C.int) C.int,
-	padding C.int, h hash.Hash, label []byte, saltLen int, ch crypto.Hash,
+	padding C.int, h, mgfHash hash.Hash, label []byte, saltLen int, ch crypto.Hash,
 	init func(*C.GO_EVP_PKEY_CTX) C.int,
 	crypt func(*C.GO_EVP_PKEY_CTX, *C.uint8_t, *C.size_t, *C.uint8_t, C.size_t) C.int,
 	in []byte) ([]byte, error) {
 
-	pkey, ctx, err := setupRSA(withKey, padding, h, label, saltLen, ch, init)
+	pkey, ctx, err := setupRSA(withKey, padding, h, mgfHash, label, saltLen, ch, init)
 	if err != nil {
 		return nil, err
 	}
@@ -204,28 +210,28 @@
 	return out[:outLen], nil
 }
 
-func DecryptRSAOAEP(h hash.Hash, priv *PrivateKeyRSA, ciphertext, label []byte) ([]byte, error) {
-	return cryptRSA(priv.withKey, C.GO_RSA_PKCS1_OAEP_PADDING, h, label, 0, 0, decryptInit, decrypt, ciphertext)
+func DecryptRSAOAEP(h, mgfHash hash.Hash, priv *PrivateKeyRSA, ciphertext, label []byte) ([]byte, error) {
+	return cryptRSA(priv.withKey, C.GO_RSA_PKCS1_OAEP_PADDING, h, mgfHash, label, 0, 0, decryptInit, decrypt, ciphertext)
 }
 
-func EncryptRSAOAEP(h hash.Hash, pub *PublicKeyRSA, msg, label []byte) ([]byte, error) {
-	return cryptRSA(pub.withKey, C.GO_RSA_PKCS1_OAEP_PADDING, h, label, 0, 0, encryptInit, encrypt, msg)
+func EncryptRSAOAEP(h, mgfHash hash.Hash, pub *PublicKeyRSA, msg, label []byte) ([]byte, error) {
+	return cryptRSA(pub.withKey, C.GO_RSA_PKCS1_OAEP_PADDING, h, mgfHash, label, 0, 0, encryptInit, encrypt, msg)
 }
 
 func DecryptRSAPKCS1(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) {
-	return cryptRSA(priv.withKey, C.GO_RSA_PKCS1_PADDING, nil, nil, 0, 0, decryptInit, decrypt, ciphertext)
+	return cryptRSA(priv.withKey, C.GO_RSA_PKCS1_PADDING, nil, nil, nil, 0, 0, decryptInit, decrypt, ciphertext)
 }
 
 func EncryptRSAPKCS1(pub *PublicKeyRSA, msg []byte) ([]byte, error) {
-	return cryptRSA(pub.withKey, C.GO_RSA_PKCS1_PADDING, nil, nil, 0, 0, encryptInit, encrypt, msg)
+	return cryptRSA(pub.withKey, C.GO_RSA_PKCS1_PADDING, nil, nil, nil, 0, 0, encryptInit, encrypt, msg)
 }
 
 func DecryptRSANoPadding(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) {
-	return cryptRSA(priv.withKey, C.GO_RSA_NO_PADDING, nil, nil, 0, 0, decryptInit, decrypt, ciphertext)
+	return cryptRSA(priv.withKey, C.GO_RSA_NO_PADDING, nil, nil, nil, 0, 0, decryptInit, decrypt, ciphertext)
 }
 
 func EncryptRSANoPadding(pub *PublicKeyRSA, msg []byte) ([]byte, error) {
-	return cryptRSA(pub.withKey, C.GO_RSA_NO_PADDING, nil, nil, 0, 0, encryptInit, encrypt, msg)
+	return cryptRSA(pub.withKey, C.GO_RSA_NO_PADDING, nil, nil, nil, 0, 0, encryptInit, encrypt, msg)
 }
 
 // These dumb wrappers work around the fact that cgo functions cannot be used as values directly.
@@ -246,14 +252,28 @@
 	return C._goboringcrypto_EVP_PKEY_encrypt(ctx, out, outLen, in, inLen)
 }
 
+var invalidSaltLenErr = errors.New("crypto/rsa: PSSOptions.SaltLength cannot be negative")
+
 func SignRSAPSS(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte, saltLen int) ([]byte, error) {
 	md := cryptoHashToMD(h)
 	if md == nil {
 		return nil, errors.New("crypto/rsa: unsupported hash function")
 	}
-	if saltLen == 0 {
-		saltLen = -1
+
+	// A salt length of -2 is valid in BoringSSL, but not in crypto/rsa, so reject
+	// it, and lengths < -2, before we convert to the BoringSSL sentinel values.
+	if saltLen <= -2 {
+		return nil, invalidSaltLenErr
 	}
+
+	// BoringSSL uses sentinel salt length values like we do, but the values don't
+	// fully match what we use. We both use -1 for salt length equal to hash length,
+	// but BoringSSL uses -2 to mean maximal size where we use 0. In the latter
+	// case convert to the BoringSSL version.
+	if saltLen == 0 {
+		saltLen = -2
+	}
+
 	var out []byte
 	var outLen C.size_t
 	if priv.withKey(func(key *C.GO_RSA) C.int {
@@ -272,9 +292,21 @@
 	if md == nil {
 		return errors.New("crypto/rsa: unsupported hash function")
 	}
-	if saltLen == 0 {
-		saltLen = -2 // auto-recover
+
+	// A salt length of -2 is valid in BoringSSL, but not in crypto/rsa, so reject
+	// it, and lengths < -2, before we convert to the BoringSSL sentinel values.
+	if saltLen <= -2 {
+		return invalidSaltLenErr
 	}
+
+	// BoringSSL uses sentinel salt length values like we do, but the values don't
+	// fully match what we use. We both use -1 for salt length equal to hash length,
+	// but BoringSSL uses -2 to mean maximal size where we use 0. In the latter
+	// case convert to the BoringSSL version.
+	if saltLen == 0 {
+		saltLen = -2
+	}
+
 	if pub.withKey(func(key *C.GO_RSA) C.int {
 		return C._goboringcrypto_RSA_verify_pss_mgf1(key, base(hashed), C.size_t(len(hashed)),
 			md, nil, C.int(saltLen), base(sig), C.size_t(len(sig)))
diff --git a/src/crypto/internal/boring/sha.go b/src/crypto/internal/boring/sha.go
index 15b50c9..cf82f3f 100644
--- a/src/crypto/internal/boring/sha.go
+++ b/src/crypto/internal/boring/sha.go
@@ -2,8 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build boringcrypto && linux && amd64 && !android && !cmd_go_bootstrap && !msan
-// +build boringcrypto,linux,amd64,!android,!cmd_go_bootstrap,!msan
+//go:build boringcrypto && linux && (amd64 || arm64) && !android && !cmd_go_bootstrap && !msan
 
 package boring
 
diff --git a/src/crypto/internal/boring/syso/goboringcrypto_linux_amd64.syso b/src/crypto/internal/boring/syso/goboringcrypto_linux_amd64.syso
index 72e6c17..6cea789 100644
--- a/src/crypto/internal/boring/syso/goboringcrypto_linux_amd64.syso
+++ b/src/crypto/internal/boring/syso/goboringcrypto_linux_amd64.syso
Binary files differ
diff --git a/src/crypto/internal/boring/syso/goboringcrypto_linux_arm64.syso b/src/crypto/internal/boring/syso/goboringcrypto_linux_arm64.syso
new file mode 100644
index 0000000..9659aa1
--- /dev/null
+++ b/src/crypto/internal/boring/syso/goboringcrypto_linux_arm64.syso
Binary files differ
diff --git a/src/crypto/internal/edwards25519/edwards25519_test.go b/src/crypto/internal/edwards25519/edwards25519_test.go
index 9bc33f9..307ae26 100644
--- a/src/crypto/internal/edwards25519/edwards25519_test.go
+++ b/src/crypto/internal/edwards25519/edwards25519_test.go
@@ -7,9 +7,8 @@
 import (
 	"crypto/internal/edwards25519/field"
 	"encoding/hex"
-	"os"
+	"internal/testenv"
 	"reflect"
-	"strings"
 	"testing"
 )
 
@@ -281,9 +280,8 @@
 var testAllocationsSink byte
 
 func TestAllocations(t *testing.T) {
-	if strings.HasSuffix(os.Getenv("GO_BUILDER_NAME"), "-noopt") {
-		t.Skip("skipping allocations test without relevant optimizations")
-	}
+	testenv.SkipIfOptimizationOff(t)
+
 	if allocs := testing.AllocsPerRun(100, func() {
 		p := NewIdentityPoint()
 		p.Add(p, NewGeneratorPoint())
@@ -302,3 +300,14 @@
 	}
 	return b
 }
+
+func BenchmarkEncodingDecoding(b *testing.B) {
+	p := new(Point).Set(dalekScalarBasepoint)
+	for i := 0; i < b.N; i++ {
+		buf := p.Bytes()
+		_, err := p.SetBytes(buf)
+		if err != nil {
+			b.Fatal(err)
+		}
+	}
+}
diff --git a/src/crypto/internal/edwards25519/field/_asm/go.mod b/src/crypto/internal/edwards25519/field/_asm/go.mod
index 1127ade..1ce2b5e 100644
--- a/src/crypto/internal/edwards25519/field/_asm/go.mod
+++ b/src/crypto/internal/edwards25519/field/_asm/go.mod
@@ -1,5 +1,12 @@
 module asm
 
-go 1.16
+go 1.19
 
-require github.com/mmcloughlin/avo v0.2.0
+require github.com/mmcloughlin/avo v0.4.0
+
+require (
+	golang.org/x/mod v0.4.2 // indirect
+	golang.org/x/sys v0.0.0-20211030160813-b3129d9d1021 // indirect
+	golang.org/x/tools v0.1.7 // indirect
+	golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
+)
diff --git a/src/crypto/internal/edwards25519/field/_asm/go.sum b/src/crypto/internal/edwards25519/field/_asm/go.sum
index dae4777..b4b5914 100644
--- a/src/crypto/internal/edwards25519/field/_asm/go.sum
+++ b/src/crypto/internal/edwards25519/field/_asm/go.sum
@@ -1,29 +1,30 @@
-github.com/mmcloughlin/avo v0.2.0 h1:6vhoSaKtxb6f4RiH+LK2qL6GSMpFzhEwJYTTSZNy09w=
-github.com/mmcloughlin/avo v0.2.0/go.mod h1:5tidO2Z9Z7N6X7UMcGg+1KTj51O8OxYDCMHxCZTVpEA=
-github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-golang.org/x/arch v0.0.0-20210405154355-08b684f594a5/go.mod h1:flIaEI6LNU6xOCD5PaJvn9wGP0agmIOqjrtsKGRguv4=
+github.com/mmcloughlin/avo v0.4.0 h1:jeHDRktVD+578ULxWpQHkilor6pkdLF7u7EiTzDbfcU=
+github.com/mmcloughlin/avo v0.4.0/go.mod h1:RW9BfYA3TgO9uCdNrKU2h6J8cPD8ZLznvfgHAeszb1s=
+github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
+golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
-golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
+golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 h1:F5Gozwx4I1xtr/sr/8CFbb57iKi3297KFs0QDbGN60A=
-golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211030160813-b3129d9d1021 h1:giLT+HuUP/gXYrG2Plg9WTjj4qhfgaW424ZIFog3rlk=
+golang.org/x/sys v0.0.0-20211030160813-b3129d9d1021/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY=
-golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
+golang.org/x/tools v0.1.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ=
+golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
diff --git a/src/crypto/internal/edwards25519/field/fe_amd64.s b/src/crypto/internal/edwards25519/field/fe_amd64.s
index 0aa1e86..60817ac 100644
--- a/src/crypto/internal/edwards25519/field/fe_amd64.s
+++ b/src/crypto/internal/edwards25519/field/fe_amd64.s
@@ -1,6 +1,6 @@
 // Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT.
 
-// +build amd64,gc,!purego
+//go:build amd64 && gc && !purego
 
 #include "textflag.h"
 
diff --git a/src/crypto/internal/edwards25519/field/fe_bench_test.go b/src/crypto/internal/edwards25519/field/fe_bench_test.go
index 77dc06c..84fdf05 100644
--- a/src/crypto/internal/edwards25519/field/fe_bench_test.go
+++ b/src/crypto/internal/edwards25519/field/fe_bench_test.go
@@ -7,30 +7,43 @@
 import "testing"
 
 func BenchmarkAdd(b *testing.B) {
-	var x, y Element
-	x.One()
-	y.Add(feOne, feOne)
+	x := new(Element).One()
+	y := new(Element).Add(x, x)
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		x.Add(&x, &y)
+		x.Add(x, y)
 	}
 }
 
 func BenchmarkMultiply(b *testing.B) {
-	var x, y Element
-	x.One()
-	y.Add(feOne, feOne)
+	x := new(Element).One()
+	y := new(Element).Add(x, x)
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		x.Multiply(&x, &y)
+		x.Multiply(x, y)
+	}
+}
+
+func BenchmarkSquare(b *testing.B) {
+	x := new(Element).Add(feOne, feOne)
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		x.Square(x)
+	}
+}
+
+func BenchmarkInvert(b *testing.B) {
+	x := new(Element).Add(feOne, feOne)
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		x.Invert(x)
 	}
 }
 
 func BenchmarkMult32(b *testing.B) {
-	var x Element
-	x.One()
+	x := new(Element).One()
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		x.Mult32(&x, 0xaa42aa42)
+		x.Mult32(x, 0xaa42aa42)
 	}
 }
diff --git a/src/crypto/internal/edwards25519/scalar.go b/src/crypto/internal/edwards25519/scalar.go
index 4530bc3..d34ecea 100644
--- a/src/crypto/internal/edwards25519/scalar.go
+++ b/src/crypto/internal/edwards25519/scalar.go
@@ -5,7 +5,6 @@
 package edwards25519
 
 import (
-	"crypto/subtle"
 	"encoding/binary"
 	"errors"
 )
@@ -21,55 +20,77 @@
 //
 // The zero value is a valid zero element.
 type Scalar struct {
-	// s is the Scalar value in little-endian. The value is always reduced
-	// modulo l between operations.
-	s [32]byte
+	// s is the scalar in the Montgomery domain, in the format of the
+	// fiat-crypto implementation.
+	s fiatScalarMontgomeryDomainFieldElement
 }
 
-var (
-	scZero = Scalar{[32]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}
-
-	scOne = Scalar{[32]byte{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}
-
-	scMinusOne = Scalar{[32]byte{236, 211, 245, 92, 26, 99, 18, 88, 214, 156, 247, 162, 222, 249, 222, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16}}
-)
+// The field implementation in scalar_fiat.go is generated by the fiat-crypto
+// project (https://github.com/mit-plv/fiat-crypto) at version v0.0.9 (23d2dbc)
+// from a formally verified model.
+//
+// fiat-crypto code comes under the following license.
+//
+//     Copyright (c) 2015-2020 The fiat-crypto Authors. All rights reserved.
+//
+//     Redistribution and use in source and binary forms, with or without
+//     modification, are permitted provided that the following conditions are
+//     met:
+//
+//         1. Redistributions of source code must retain the above copyright
+//         notice, this list of conditions and the following disclaimer.
+//
+//     THIS SOFTWARE IS PROVIDED BY the fiat-crypto authors "AS IS"
+//     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+//     THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+//     PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design,
+//     Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+//     EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+//     PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+//     PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+//     LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+//     NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+//     SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
 
 // NewScalar returns a new zero Scalar.
 func NewScalar() *Scalar {
 	return &Scalar{}
 }
 
-// MultiplyAdd sets s = x * y + z mod l, and returns s.
+// MultiplyAdd sets s = x * y + z mod l, and returns s. It is equivalent to
+// using Multiply and then Add.
 func (s *Scalar) MultiplyAdd(x, y, z *Scalar) *Scalar {
-	scMulAdd(&s.s, &x.s, &y.s, &z.s)
-	return s
+	// Make a copy of z in case it aliases s.
+	zCopy := new(Scalar).Set(z)
+	return s.Multiply(x, y).Add(s, zCopy)
 }
 
 // Add sets s = x + y mod l, and returns s.
 func (s *Scalar) Add(x, y *Scalar) *Scalar {
 	// s = 1 * x + y mod l
-	scMulAdd(&s.s, &scOne.s, &x.s, &y.s)
+	fiatScalarAdd(&s.s, &x.s, &y.s)
 	return s
 }
 
 // Subtract sets s = x - y mod l, and returns s.
 func (s *Scalar) Subtract(x, y *Scalar) *Scalar {
 	// s = -1 * y + x mod l
-	scMulAdd(&s.s, &scMinusOne.s, &y.s, &x.s)
+	fiatScalarSub(&s.s, &x.s, &y.s)
 	return s
 }
 
 // Negate sets s = -x mod l, and returns s.
 func (s *Scalar) Negate(x *Scalar) *Scalar {
 	// s = -1 * x + 0 mod l
-	scMulAdd(&s.s, &scMinusOne.s, &x.s, &scZero.s)
+	fiatScalarOpp(&s.s, &x.s)
 	return s
 }
 
 // Multiply sets s = x * y mod l, and returns s.
 func (s *Scalar) Multiply(x, y *Scalar) *Scalar {
 	// s = x * y + 0 mod l
-	scMulAdd(&s.s, &x.s, &y.s, &scZero.s)
+	fiatScalarMul(&s.s, &x.s, &y.s)
 	return s
 }
 
@@ -89,12 +110,48 @@
 	if len(x) != 64 {
 		return nil, errors.New("edwards25519: invalid SetUniformBytes input length")
 	}
-	var wideBytes [64]byte
-	copy(wideBytes[:], x[:])
-	scReduce(&s.s, &wideBytes)
+
+	// We have a value x of 512 bits, but our fiatScalarFromBytes function
+	// expects an input lower than l, which is a little over 252 bits.
+	//
+	// Instead of writing a reduction function that operates on wider inputs, we
+	// can interpret x as the sum of three shorter values a, b, and c.
+	//
+	//    x = a + b * 2^168 + c * 2^336  mod l
+	//
+	// We then precompute 2^168 and 2^336 modulo l, and perform the reduction
+	// with two multiplications and two additions.
+
+	s.setShortBytes(x[:21])
+	t := new(Scalar).setShortBytes(x[21:42])
+	s.Add(s, t.Multiply(t, scalarTwo168))
+	t.setShortBytes(x[42:])
+	s.Add(s, t.Multiply(t, scalarTwo336))
+
 	return s, nil
 }
 
+// scalarTwo168 and scalarTwo336 are 2^168 and 2^336 modulo l, encoded as a
+// fiatScalarMontgomeryDomainFieldElement, which is a little-endian 4-limb value
+// in the 2^256 Montgomery domain.
+var scalarTwo168 = &Scalar{s: [4]uint64{0x5b8ab432eac74798, 0x38afddd6de59d5d7,
+	0xa2c131b399411b7c, 0x6329a7ed9ce5a30}}
+var scalarTwo336 = &Scalar{s: [4]uint64{0xbd3d108e2b35ecc5, 0x5c3a3718bdf9c90b,
+	0x63aa97a331b4f2ee, 0x3d217f5be65cb5c}}
+
+// setShortBytes sets s = x mod l, where x is a little-endian integer shorter
+// than 32 bytes.
+func (s *Scalar) setShortBytes(x []byte) *Scalar {
+	if len(x) >= 32 {
+		panic("edwards25519: internal error: setShortBytes called with a long string")
+	}
+	var buf [32]byte
+	copy(buf[:], x)
+	fiatScalarFromBytes((*[4]uint64)(&s.s), &buf)
+	fiatScalarToMontgomery(&s.s, (*fiatScalarNonMontgomeryDomainFieldElement)(&s.s))
+	return s
+}
+
 // SetCanonicalBytes sets s = x, where x is a 32-byte little-endian encoding of
 // s, and returns s. If x is not a canonical encoding of s, SetCanonicalBytes
 // returns nil and an error, and the receiver is unchanged.
@@ -102,22 +159,31 @@
 	if len(x) != 32 {
 		return nil, errors.New("invalid scalar length")
 	}
-	ss := &Scalar{}
-	copy(ss.s[:], x)
-	if !isReduced(ss) {
+	if !isReduced(x) {
 		return nil, errors.New("invalid scalar encoding")
 	}
-	s.s = ss.s
+
+	fiatScalarFromBytes((*[4]uint64)(&s.s), (*[32]byte)(x))
+	fiatScalarToMontgomery(&s.s, (*fiatScalarNonMontgomeryDomainFieldElement)(&s.s))
+
 	return s, nil
 }
 
-// isReduced returns whether the given scalar is reduced modulo l.
-func isReduced(s *Scalar) bool {
-	for i := len(s.s) - 1; i >= 0; i-- {
+// scalarMinusOneBytes is l - 1 in little endian.
+var scalarMinusOneBytes = [32]byte{236, 211, 245, 92, 26, 99, 18, 88, 214, 156, 247, 162, 222, 249, 222, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16}
+
+// isReduced returns whether the given scalar in 32-byte little endian encoded
+// form is reduced modulo l.
+func isReduced(s []byte) bool {
+	if len(s) != 32 {
+		return false
+	}
+
+	for i := len(s) - 1; i >= 0; i-- {
 		switch {
-		case s.s[i] > scMinusOne.s[i]:
+		case s[i] > scalarMinusOneBytes[i]:
 			return false
-		case s.s[i] < scMinusOne.s[i]:
+		case s[i] < scalarMinusOneBytes[i]:
 			return true
 		}
 	}
@@ -143,804 +209,45 @@
 	if len(x) != 32 {
 		return nil, errors.New("edwards25519: invalid SetBytesWithClamping input length")
 	}
+
+	// We need to use the wide reduction from SetUniformBytes, since clamping
+	// sets the 2^254 bit, making the value higher than the order.
 	var wideBytes [64]byte
 	copy(wideBytes[:], x[:])
 	wideBytes[0] &= 248
 	wideBytes[31] &= 63
 	wideBytes[31] |= 64
-	scReduce(&s.s, &wideBytes)
-	return s, nil
+	return s.SetUniformBytes(wideBytes[:])
 }
 
 // Bytes returns the canonical 32-byte little-endian encoding of s.
 func (s *Scalar) Bytes() []byte {
-	buf := make([]byte, 32)
-	copy(buf, s.s[:])
-	return buf
+	// This function is outlined to make the allocations inline in the caller
+	// rather than happen on the heap.
+	var encoded [32]byte
+	return s.bytes(&encoded)
+}
+
+func (s *Scalar) bytes(out *[32]byte) []byte {
+	var ss fiatScalarNonMontgomeryDomainFieldElement
+	fiatScalarFromMontgomery(&ss, &s.s)
+	fiatScalarToBytes(out, (*[4]uint64)(&ss))
+	return out[:]
 }
 
 // Equal returns 1 if s and t are equal, and 0 otherwise.
 func (s *Scalar) Equal(t *Scalar) int {
-	return subtle.ConstantTimeCompare(s.s[:], t.s[:])
-}
-
-// scMulAdd and scReduce are ported from the public domain, “ref10”
-// implementation of ed25519 from SUPERCOP.
-
-func load3(in []byte) int64 {
-	r := int64(in[0])
-	r |= int64(in[1]) << 8
-	r |= int64(in[2]) << 16
-	return r
-}
-
-func load4(in []byte) int64 {
-	r := int64(in[0])
-	r |= int64(in[1]) << 8
-	r |= int64(in[2]) << 16
-	r |= int64(in[3]) << 24
-	return r
-}
-
-// Input:
-//
-//	a[0]+256*a[1]+...+256^31*a[31] = a
-//	b[0]+256*b[1]+...+256^31*b[31] = b
-//	c[0]+256*c[1]+...+256^31*c[31] = c
-//
-// Output:
-//
-//	s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l
-//	where l = 2^252 + 27742317777372353535851937790883648493.
-func scMulAdd(s, a, b, c *[32]byte) {
-	a0 := 2097151 & load3(a[:])
-	a1 := 2097151 & (load4(a[2:]) >> 5)
-	a2 := 2097151 & (load3(a[5:]) >> 2)
-	a3 := 2097151 & (load4(a[7:]) >> 7)
-	a4 := 2097151 & (load4(a[10:]) >> 4)
-	a5 := 2097151 & (load3(a[13:]) >> 1)
-	a6 := 2097151 & (load4(a[15:]) >> 6)
-	a7 := 2097151 & (load3(a[18:]) >> 3)
-	a8 := 2097151 & load3(a[21:])
-	a9 := 2097151 & (load4(a[23:]) >> 5)
-	a10 := 2097151 & (load3(a[26:]) >> 2)
-	a11 := (load4(a[28:]) >> 7)
-	b0 := 2097151 & load3(b[:])
-	b1 := 2097151 & (load4(b[2:]) >> 5)
-	b2 := 2097151 & (load3(b[5:]) >> 2)
-	b3 := 2097151 & (load4(b[7:]) >> 7)
-	b4 := 2097151 & (load4(b[10:]) >> 4)
-	b5 := 2097151 & (load3(b[13:]) >> 1)
-	b6 := 2097151 & (load4(b[15:]) >> 6)
-	b7 := 2097151 & (load3(b[18:]) >> 3)
-	b8 := 2097151 & load3(b[21:])
-	b9 := 2097151 & (load4(b[23:]) >> 5)
-	b10 := 2097151 & (load3(b[26:]) >> 2)
-	b11 := (load4(b[28:]) >> 7)
-	c0 := 2097151 & load3(c[:])
-	c1 := 2097151 & (load4(c[2:]) >> 5)
-	c2 := 2097151 & (load3(c[5:]) >> 2)
-	c3 := 2097151 & (load4(c[7:]) >> 7)
-	c4 := 2097151 & (load4(c[10:]) >> 4)
-	c5 := 2097151 & (load3(c[13:]) >> 1)
-	c6 := 2097151 & (load4(c[15:]) >> 6)
-	c7 := 2097151 & (load3(c[18:]) >> 3)
-	c8 := 2097151 & load3(c[21:])
-	c9 := 2097151 & (load4(c[23:]) >> 5)
-	c10 := 2097151 & (load3(c[26:]) >> 2)
-	c11 := (load4(c[28:]) >> 7)
-	var carry [23]int64
-
-	s0 := c0 + a0*b0
-	s1 := c1 + a0*b1 + a1*b0
-	s2 := c2 + a0*b2 + a1*b1 + a2*b0
-	s3 := c3 + a0*b3 + a1*b2 + a2*b1 + a3*b0
-	s4 := c4 + a0*b4 + a1*b3 + a2*b2 + a3*b1 + a4*b0
-	s5 := c5 + a0*b5 + a1*b4 + a2*b3 + a3*b2 + a4*b1 + a5*b0
-	s6 := c6 + a0*b6 + a1*b5 + a2*b4 + a3*b3 + a4*b2 + a5*b1 + a6*b0
-	s7 := c7 + a0*b7 + a1*b6 + a2*b5 + a3*b4 + a4*b3 + a5*b2 + a6*b1 + a7*b0
-	s8 := c8 + a0*b8 + a1*b7 + a2*b6 + a3*b5 + a4*b4 + a5*b3 + a6*b2 + a7*b1 + a8*b0
-	s9 := c9 + a0*b9 + a1*b8 + a2*b7 + a3*b6 + a4*b5 + a5*b4 + a6*b3 + a7*b2 + a8*b1 + a9*b0
-	s10 := c10 + a0*b10 + a1*b9 + a2*b8 + a3*b7 + a4*b6 + a5*b5 + a6*b4 + a7*b3 + a8*b2 + a9*b1 + a10*b0
-	s11 := c11 + a0*b11 + a1*b10 + a2*b9 + a3*b8 + a4*b7 + a5*b6 + a6*b5 + a7*b4 + a8*b3 + a9*b2 + a10*b1 + a11*b0
-	s12 := a1*b11 + a2*b10 + a3*b9 + a4*b8 + a5*b7 + a6*b6 + a7*b5 + a8*b4 + a9*b3 + a10*b2 + a11*b1
-	s13 := a2*b11 + a3*b10 + a4*b9 + a5*b8 + a6*b7 + a7*b6 + a8*b5 + a9*b4 + a10*b3 + a11*b2
-	s14 := a3*b11 + a4*b10 + a5*b9 + a6*b8 + a7*b7 + a8*b6 + a9*b5 + a10*b4 + a11*b3
-	s15 := a4*b11 + a5*b10 + a6*b9 + a7*b8 + a8*b7 + a9*b6 + a10*b5 + a11*b4
-	s16 := a5*b11 + a6*b10 + a7*b9 + a8*b8 + a9*b7 + a10*b6 + a11*b5
-	s17 := a6*b11 + a7*b10 + a8*b9 + a9*b8 + a10*b7 + a11*b6
-	s18 := a7*b11 + a8*b10 + a9*b9 + a10*b8 + a11*b7
-	s19 := a8*b11 + a9*b10 + a10*b9 + a11*b8
-	s20 := a9*b11 + a10*b10 + a11*b9
-	s21 := a10*b11 + a11*b10
-	s22 := a11 * b11
-	s23 := int64(0)
-
-	carry[0] = (s0 + (1 << 20)) >> 21
-	s1 += carry[0]
-	s0 -= carry[0] << 21
-	carry[2] = (s2 + (1 << 20)) >> 21
-	s3 += carry[2]
-	s2 -= carry[2] << 21
-	carry[4] = (s4 + (1 << 20)) >> 21
-	s5 += carry[4]
-	s4 -= carry[4] << 21
-	carry[6] = (s6 + (1 << 20)) >> 21
-	s7 += carry[6]
-	s6 -= carry[6] << 21
-	carry[8] = (s8 + (1 << 20)) >> 21
-	s9 += carry[8]
-	s8 -= carry[8] << 21
-	carry[10] = (s10 + (1 << 20)) >> 21
-	s11 += carry[10]
-	s10 -= carry[10] << 21
-	carry[12] = (s12 + (1 << 20)) >> 21
-	s13 += carry[12]
-	s12 -= carry[12] << 21
-	carry[14] = (s14 + (1 << 20)) >> 21
-	s15 += carry[14]
-	s14 -= carry[14] << 21
-	carry[16] = (s16 + (1 << 20)) >> 21
-	s17 += carry[16]
-	s16 -= carry[16] << 21
-	carry[18] = (s18 + (1 << 20)) >> 21
-	s19 += carry[18]
-	s18 -= carry[18] << 21
-	carry[20] = (s20 + (1 << 20)) >> 21
-	s21 += carry[20]
-	s20 -= carry[20] << 21
-	carry[22] = (s22 + (1 << 20)) >> 21
-	s23 += carry[22]
-	s22 -= carry[22] << 21
-
-	carry[1] = (s1 + (1 << 20)) >> 21
-	s2 += carry[1]
-	s1 -= carry[1] << 21
-	carry[3] = (s3 + (1 << 20)) >> 21
-	s4 += carry[3]
-	s3 -= carry[3] << 21
-	carry[5] = (s5 + (1 << 20)) >> 21
-	s6 += carry[5]
-	s5 -= carry[5] << 21
-	carry[7] = (s7 + (1 << 20)) >> 21
-	s8 += carry[7]
-	s7 -= carry[7] << 21
-	carry[9] = (s9 + (1 << 20)) >> 21
-	s10 += carry[9]
-	s9 -= carry[9] << 21
-	carry[11] = (s11 + (1 << 20)) >> 21
-	s12 += carry[11]
-	s11 -= carry[11] << 21
-	carry[13] = (s13 + (1 << 20)) >> 21
-	s14 += carry[13]
-	s13 -= carry[13] << 21
-	carry[15] = (s15 + (1 << 20)) >> 21
-	s16 += carry[15]
-	s15 -= carry[15] << 21
-	carry[17] = (s17 + (1 << 20)) >> 21
-	s18 += carry[17]
-	s17 -= carry[17] << 21
-	carry[19] = (s19 + (1 << 20)) >> 21
-	s20 += carry[19]
-	s19 -= carry[19] << 21
-	carry[21] = (s21 + (1 << 20)) >> 21
-	s22 += carry[21]
-	s21 -= carry[21] << 21
-
-	s11 += s23 * 666643
-	s12 += s23 * 470296
-	s13 += s23 * 654183
-	s14 -= s23 * 997805
-	s15 += s23 * 136657
-	s16 -= s23 * 683901
-	s23 = 0
-
-	s10 += s22 * 666643
-	s11 += s22 * 470296
-	s12 += s22 * 654183
-	s13 -= s22 * 997805
-	s14 += s22 * 136657
-	s15 -= s22 * 683901
-	s22 = 0
-
-	s9 += s21 * 666643
-	s10 += s21 * 470296
-	s11 += s21 * 654183
-	s12 -= s21 * 997805
-	s13 += s21 * 136657
-	s14 -= s21 * 683901
-	s21 = 0
-
-	s8 += s20 * 666643
-	s9 += s20 * 470296
-	s10 += s20 * 654183
-	s11 -= s20 * 997805
-	s12 += s20 * 136657
-	s13 -= s20 * 683901
-	s20 = 0
-
-	s7 += s19 * 666643
-	s8 += s19 * 470296
-	s9 += s19 * 654183
-	s10 -= s19 * 997805
-	s11 += s19 * 136657
-	s12 -= s19 * 683901
-	s19 = 0
-
-	s6 += s18 * 666643
-	s7 += s18 * 470296
-	s8 += s18 * 654183
-	s9 -= s18 * 997805
-	s10 += s18 * 136657
-	s11 -= s18 * 683901
-	s18 = 0
-
-	carry[6] = (s6 + (1 << 20)) >> 21
-	s7 += carry[6]
-	s6 -= carry[6] << 21
-	carry[8] = (s8 + (1 << 20)) >> 21
-	s9 += carry[8]
-	s8 -= carry[8] << 21
-	carry[10] = (s10 + (1 << 20)) >> 21
-	s11 += carry[10]
-	s10 -= carry[10] << 21
-	carry[12] = (s12 + (1 << 20)) >> 21
-	s13 += carry[12]
-	s12 -= carry[12] << 21
-	carry[14] = (s14 + (1 << 20)) >> 21
-	s15 += carry[14]
-	s14 -= carry[14] << 21
-	carry[16] = (s16 + (1 << 20)) >> 21
-	s17 += carry[16]
-	s16 -= carry[16] << 21
-
-	carry[7] = (s7 + (1 << 20)) >> 21
-	s8 += carry[7]
-	s7 -= carry[7] << 21
-	carry[9] = (s9 + (1 << 20)) >> 21
-	s10 += carry[9]
-	s9 -= carry[9] << 21
-	carry[11] = (s11 + (1 << 20)) >> 21
-	s12 += carry[11]
-	s11 -= carry[11] << 21
-	carry[13] = (s13 + (1 << 20)) >> 21
-	s14 += carry[13]
-	s13 -= carry[13] << 21
-	carry[15] = (s15 + (1 << 20)) >> 21
-	s16 += carry[15]
-	s15 -= carry[15] << 21
-
-	s5 += s17 * 666643
-	s6 += s17 * 470296
-	s7 += s17 * 654183
-	s8 -= s17 * 997805
-	s9 += s17 * 136657
-	s10 -= s17 * 683901
-	s17 = 0
-
-	s4 += s16 * 666643
-	s5 += s16 * 470296
-	s6 += s16 * 654183
-	s7 -= s16 * 997805
-	s8 += s16 * 136657
-	s9 -= s16 * 683901
-	s16 = 0
-
-	s3 += s15 * 666643
-	s4 += s15 * 470296
-	s5 += s15 * 654183
-	s6 -= s15 * 997805
-	s7 += s15 * 136657
-	s8 -= s15 * 683901
-	s15 = 0
-
-	s2 += s14 * 666643
-	s3 += s14 * 470296
-	s4 += s14 * 654183
-	s5 -= s14 * 997805
-	s6 += s14 * 136657
-	s7 -= s14 * 683901
-	s14 = 0
-
-	s1 += s13 * 666643
-	s2 += s13 * 470296
-	s3 += s13 * 654183
-	s4 -= s13 * 997805
-	s5 += s13 * 136657
-	s6 -= s13 * 683901
-	s13 = 0
-
-	s0 += s12 * 666643
-	s1 += s12 * 470296
-	s2 += s12 * 654183
-	s3 -= s12 * 997805
-	s4 += s12 * 136657
-	s5 -= s12 * 683901
-	s12 = 0
-
-	carry[0] = (s0 + (1 << 20)) >> 21
-	s1 += carry[0]
-	s0 -= carry[0] << 21
-	carry[2] = (s2 + (1 << 20)) >> 21
-	s3 += carry[2]
-	s2 -= carry[2] << 21
-	carry[4] = (s4 + (1 << 20)) >> 21
-	s5 += carry[4]
-	s4 -= carry[4] << 21
-	carry[6] = (s6 + (1 << 20)) >> 21
-	s7 += carry[6]
-	s6 -= carry[6] << 21
-	carry[8] = (s8 + (1 << 20)) >> 21
-	s9 += carry[8]
-	s8 -= carry[8] << 21
-	carry[10] = (s10 + (1 << 20)) >> 21
-	s11 += carry[10]
-	s10 -= carry[10] << 21
-
-	carry[1] = (s1 + (1 << 20)) >> 21
-	s2 += carry[1]
-	s1 -= carry[1] << 21
-	carry[3] = (s3 + (1 << 20)) >> 21
-	s4 += carry[3]
-	s3 -= carry[3] << 21
-	carry[5] = (s5 + (1 << 20)) >> 21
-	s6 += carry[5]
-	s5 -= carry[5] << 21
-	carry[7] = (s7 + (1 << 20)) >> 21
-	s8 += carry[7]
-	s7 -= carry[7] << 21
-	carry[9] = (s9 + (1 << 20)) >> 21
-	s10 += carry[9]
-	s9 -= carry[9] << 21
-	carry[11] = (s11 + (1 << 20)) >> 21
-	s12 += carry[11]
-	s11 -= carry[11] << 21
-
-	s0 += s12 * 666643
-	s1 += s12 * 470296
-	s2 += s12 * 654183
-	s3 -= s12 * 997805
-	s4 += s12 * 136657
-	s5 -= s12 * 683901
-	s12 = 0
-
-	carry[0] = s0 >> 21
-	s1 += carry[0]
-	s0 -= carry[0] << 21
-	carry[1] = s1 >> 21
-	s2 += carry[1]
-	s1 -= carry[1] << 21
-	carry[2] = s2 >> 21
-	s3 += carry[2]
-	s2 -= carry[2] << 21
-	carry[3] = s3 >> 21
-	s4 += carry[3]
-	s3 -= carry[3] << 21
-	carry[4] = s4 >> 21
-	s5 += carry[4]
-	s4 -= carry[4] << 21
-	carry[5] = s5 >> 21
-	s6 += carry[5]
-	s5 -= carry[5] << 21
-	carry[6] = s6 >> 21
-	s7 += carry[6]
-	s6 -= carry[6] << 21
-	carry[7] = s7 >> 21
-	s8 += carry[7]
-	s7 -= carry[7] << 21
-	carry[8] = s8 >> 21
-	s9 += carry[8]
-	s8 -= carry[8] << 21
-	carry[9] = s9 >> 21
-	s10 += carry[9]
-	s9 -= carry[9] << 21
-	carry[10] = s10 >> 21
-	s11 += carry[10]
-	s10 -= carry[10] << 21
-	carry[11] = s11 >> 21
-	s12 += carry[11]
-	s11 -= carry[11] << 21
-
-	s0 += s12 * 666643
-	s1 += s12 * 470296
-	s2 += s12 * 654183
-	s3 -= s12 * 997805
-	s4 += s12 * 136657
-	s5 -= s12 * 683901
-	s12 = 0
-
-	carry[0] = s0 >> 21
-	s1 += carry[0]
-	s0 -= carry[0] << 21
-	carry[1] = s1 >> 21
-	s2 += carry[1]
-	s1 -= carry[1] << 21
-	carry[2] = s2 >> 21
-	s3 += carry[2]
-	s2 -= carry[2] << 21
-	carry[3] = s3 >> 21
-	s4 += carry[3]
-	s3 -= carry[3] << 21
-	carry[4] = s4 >> 21
-	s5 += carry[4]
-	s4 -= carry[4] << 21
-	carry[5] = s5 >> 21
-	s6 += carry[5]
-	s5 -= carry[5] << 21
-	carry[6] = s6 >> 21
-	s7 += carry[6]
-	s6 -= carry[6] << 21
-	carry[7] = s7 >> 21
-	s8 += carry[7]
-	s7 -= carry[7] << 21
-	carry[8] = s8 >> 21
-	s9 += carry[8]
-	s8 -= carry[8] << 21
-	carry[9] = s9 >> 21
-	s10 += carry[9]
-	s9 -= carry[9] << 21
-	carry[10] = s10 >> 21
-	s11 += carry[10]
-	s10 -= carry[10] << 21
-
-	s[0] = byte(s0 >> 0)
-	s[1] = byte(s0 >> 8)
-	s[2] = byte((s0 >> 16) | (s1 << 5))
-	s[3] = byte(s1 >> 3)
-	s[4] = byte(s1 >> 11)
-	s[5] = byte((s1 >> 19) | (s2 << 2))
-	s[6] = byte(s2 >> 6)
-	s[7] = byte((s2 >> 14) | (s3 << 7))
-	s[8] = byte(s3 >> 1)
-	s[9] = byte(s3 >> 9)
-	s[10] = byte((s3 >> 17) | (s4 << 4))
-	s[11] = byte(s4 >> 4)
-	s[12] = byte(s4 >> 12)
-	s[13] = byte((s4 >> 20) | (s5 << 1))
-	s[14] = byte(s5 >> 7)
-	s[15] = byte((s5 >> 15) | (s6 << 6))
-	s[16] = byte(s6 >> 2)
-	s[17] = byte(s6 >> 10)
-	s[18] = byte((s6 >> 18) | (s7 << 3))
-	s[19] = byte(s7 >> 5)
-	s[20] = byte(s7 >> 13)
-	s[21] = byte(s8 >> 0)
-	s[22] = byte(s8 >> 8)
-	s[23] = byte((s8 >> 16) | (s9 << 5))
-	s[24] = byte(s9 >> 3)
-	s[25] = byte(s9 >> 11)
-	s[26] = byte((s9 >> 19) | (s10 << 2))
-	s[27] = byte(s10 >> 6)
-	s[28] = byte((s10 >> 14) | (s11 << 7))
-	s[29] = byte(s11 >> 1)
-	s[30] = byte(s11 >> 9)
-	s[31] = byte(s11 >> 17)
-}
-
-// Input:
-//
-//	s[0]+256*s[1]+...+256^63*s[63] = s
-//
-// Output:
-//
-//	s[0]+256*s[1]+...+256^31*s[31] = s mod l
-//	where l = 2^252 + 27742317777372353535851937790883648493.
-func scReduce(out *[32]byte, s *[64]byte) {
-	s0 := 2097151 & load3(s[:])
-	s1 := 2097151 & (load4(s[2:]) >> 5)
-	s2 := 2097151 & (load3(s[5:]) >> 2)
-	s3 := 2097151 & (load4(s[7:]) >> 7)
-	s4 := 2097151 & (load4(s[10:]) >> 4)
-	s5 := 2097151 & (load3(s[13:]) >> 1)
-	s6 := 2097151 & (load4(s[15:]) >> 6)
-	s7 := 2097151 & (load3(s[18:]) >> 3)
-	s8 := 2097151 & load3(s[21:])
-	s9 := 2097151 & (load4(s[23:]) >> 5)
-	s10 := 2097151 & (load3(s[26:]) >> 2)
-	s11 := 2097151 & (load4(s[28:]) >> 7)
-	s12 := 2097151 & (load4(s[31:]) >> 4)
-	s13 := 2097151 & (load3(s[34:]) >> 1)
-	s14 := 2097151 & (load4(s[36:]) >> 6)
-	s15 := 2097151 & (load3(s[39:]) >> 3)
-	s16 := 2097151 & load3(s[42:])
-	s17 := 2097151 & (load4(s[44:]) >> 5)
-	s18 := 2097151 & (load3(s[47:]) >> 2)
-	s19 := 2097151 & (load4(s[49:]) >> 7)
-	s20 := 2097151 & (load4(s[52:]) >> 4)
-	s21 := 2097151 & (load3(s[55:]) >> 1)
-	s22 := 2097151 & (load4(s[57:]) >> 6)
-	s23 := (load4(s[60:]) >> 3)
-
-	s11 += s23 * 666643
-	s12 += s23 * 470296
-	s13 += s23 * 654183
-	s14 -= s23 * 997805
-	s15 += s23 * 136657
-	s16 -= s23 * 683901
-	s23 = 0
-
-	s10 += s22 * 666643
-	s11 += s22 * 470296
-	s12 += s22 * 654183
-	s13 -= s22 * 997805
-	s14 += s22 * 136657
-	s15 -= s22 * 683901
-	s22 = 0
-
-	s9 += s21 * 666643
-	s10 += s21 * 470296
-	s11 += s21 * 654183
-	s12 -= s21 * 997805
-	s13 += s21 * 136657
-	s14 -= s21 * 683901
-	s21 = 0
-
-	s8 += s20 * 666643
-	s9 += s20 * 470296
-	s10 += s20 * 654183
-	s11 -= s20 * 997805
-	s12 += s20 * 136657
-	s13 -= s20 * 683901
-	s20 = 0
-
-	s7 += s19 * 666643
-	s8 += s19 * 470296
-	s9 += s19 * 654183
-	s10 -= s19 * 997805
-	s11 += s19 * 136657
-	s12 -= s19 * 683901
-	s19 = 0
-
-	s6 += s18 * 666643
-	s7 += s18 * 470296
-	s8 += s18 * 654183
-	s9 -= s18 * 997805
-	s10 += s18 * 136657
-	s11 -= s18 * 683901
-	s18 = 0
-
-	var carry [17]int64
-
-	carry[6] = (s6 + (1 << 20)) >> 21
-	s7 += carry[6]
-	s6 -= carry[6] << 21
-	carry[8] = (s8 + (1 << 20)) >> 21
-	s9 += carry[8]
-	s8 -= carry[8] << 21
-	carry[10] = (s10 + (1 << 20)) >> 21
-	s11 += carry[10]
-	s10 -= carry[10] << 21
-	carry[12] = (s12 + (1 << 20)) >> 21
-	s13 += carry[12]
-	s12 -= carry[12] << 21
-	carry[14] = (s14 + (1 << 20)) >> 21
-	s15 += carry[14]
-	s14 -= carry[14] << 21
-	carry[16] = (s16 + (1 << 20)) >> 21
-	s17 += carry[16]
-	s16 -= carry[16] << 21
-
-	carry[7] = (s7 + (1 << 20)) >> 21
-	s8 += carry[7]
-	s7 -= carry[7] << 21
-	carry[9] = (s9 + (1 << 20)) >> 21
-	s10 += carry[9]
-	s9 -= carry[9] << 21
-	carry[11] = (s11 + (1 << 20)) >> 21
-	s12 += carry[11]
-	s11 -= carry[11] << 21
-	carry[13] = (s13 + (1 << 20)) >> 21
-	s14 += carry[13]
-	s13 -= carry[13] << 21
-	carry[15] = (s15 + (1 << 20)) >> 21
-	s16 += carry[15]
-	s15 -= carry[15] << 21
-
-	s5 += s17 * 666643
-	s6 += s17 * 470296
-	s7 += s17 * 654183
-	s8 -= s17 * 997805
-	s9 += s17 * 136657
-	s10 -= s17 * 683901
-	s17 = 0
-
-	s4 += s16 * 666643
-	s5 += s16 * 470296
-	s6 += s16 * 654183
-	s7 -= s16 * 997805
-	s8 += s16 * 136657
-	s9 -= s16 * 683901
-	s16 = 0
-
-	s3 += s15 * 666643
-	s4 += s15 * 470296
-	s5 += s15 * 654183
-	s6 -= s15 * 997805
-	s7 += s15 * 136657
-	s8 -= s15 * 683901
-	s15 = 0
-
-	s2 += s14 * 666643
-	s3 += s14 * 470296
-	s4 += s14 * 654183
-	s5 -= s14 * 997805
-	s6 += s14 * 136657
-	s7 -= s14 * 683901
-	s14 = 0
-
-	s1 += s13 * 666643
-	s2 += s13 * 470296
-	s3 += s13 * 654183
-	s4 -= s13 * 997805
-	s5 += s13 * 136657
-	s6 -= s13 * 683901
-	s13 = 0
-
-	s0 += s12 * 666643
-	s1 += s12 * 470296
-	s2 += s12 * 654183
-	s3 -= s12 * 997805
-	s4 += s12 * 136657
-	s5 -= s12 * 683901
-	s12 = 0
-
-	carry[0] = (s0 + (1 << 20)) >> 21
-	s1 += carry[0]
-	s0 -= carry[0] << 21
-	carry[2] = (s2 + (1 << 20)) >> 21
-	s3 += carry[2]
-	s2 -= carry[2] << 21
-	carry[4] = (s4 + (1 << 20)) >> 21
-	s5 += carry[4]
-	s4 -= carry[4] << 21
-	carry[6] = (s6 + (1 << 20)) >> 21
-	s7 += carry[6]
-	s6 -= carry[6] << 21
-	carry[8] = (s8 + (1 << 20)) >> 21
-	s9 += carry[8]
-	s8 -= carry[8] << 21
-	carry[10] = (s10 + (1 << 20)) >> 21
-	s11 += carry[10]
-	s10 -= carry[10] << 21
-
-	carry[1] = (s1 + (1 << 20)) >> 21
-	s2 += carry[1]
-	s1 -= carry[1] << 21
-	carry[3] = (s3 + (1 << 20)) >> 21
-	s4 += carry[3]
-	s3 -= carry[3] << 21
-	carry[5] = (s5 + (1 << 20)) >> 21
-	s6 += carry[5]
-	s5 -= carry[5] << 21
-	carry[7] = (s7 + (1 << 20)) >> 21
-	s8 += carry[7]
-	s7 -= carry[7] << 21
-	carry[9] = (s9 + (1 << 20)) >> 21
-	s10 += carry[9]
-	s9 -= carry[9] << 21
-	carry[11] = (s11 + (1 << 20)) >> 21
-	s12 += carry[11]
-	s11 -= carry[11] << 21
-
-	s0 += s12 * 666643
-	s1 += s12 * 470296
-	s2 += s12 * 654183
-	s3 -= s12 * 997805
-	s4 += s12 * 136657
-	s5 -= s12 * 683901
-	s12 = 0
-
-	carry[0] = s0 >> 21
-	s1 += carry[0]
-	s0 -= carry[0] << 21
-	carry[1] = s1 >> 21
-	s2 += carry[1]
-	s1 -= carry[1] << 21
-	carry[2] = s2 >> 21
-	s3 += carry[2]
-	s2 -= carry[2] << 21
-	carry[3] = s3 >> 21
-	s4 += carry[3]
-	s3 -= carry[3] << 21
-	carry[4] = s4 >> 21
-	s5 += carry[4]
-	s4 -= carry[4] << 21
-	carry[5] = s5 >> 21
-	s6 += carry[5]
-	s5 -= carry[5] << 21
-	carry[6] = s6 >> 21
-	s7 += carry[6]
-	s6 -= carry[6] << 21
-	carry[7] = s7 >> 21
-	s8 += carry[7]
-	s7 -= carry[7] << 21
-	carry[8] = s8 >> 21
-	s9 += carry[8]
-	s8 -= carry[8] << 21
-	carry[9] = s9 >> 21
-	s10 += carry[9]
-	s9 -= carry[9] << 21
-	carry[10] = s10 >> 21
-	s11 += carry[10]
-	s10 -= carry[10] << 21
-	carry[11] = s11 >> 21
-	s12 += carry[11]
-	s11 -= carry[11] << 21
-
-	s0 += s12 * 666643
-	s1 += s12 * 470296
-	s2 += s12 * 654183
-	s3 -= s12 * 997805
-	s4 += s12 * 136657
-	s5 -= s12 * 683901
-	s12 = 0
-
-	carry[0] = s0 >> 21
-	s1 += carry[0]
-	s0 -= carry[0] << 21
-	carry[1] = s1 >> 21
-	s2 += carry[1]
-	s1 -= carry[1] << 21
-	carry[2] = s2 >> 21
-	s3 += carry[2]
-	s2 -= carry[2] << 21
-	carry[3] = s3 >> 21
-	s4 += carry[3]
-	s3 -= carry[3] << 21
-	carry[4] = s4 >> 21
-	s5 += carry[4]
-	s4 -= carry[4] << 21
-	carry[5] = s5 >> 21
-	s6 += carry[5]
-	s5 -= carry[5] << 21
-	carry[6] = s6 >> 21
-	s7 += carry[6]
-	s6 -= carry[6] << 21
-	carry[7] = s7 >> 21
-	s8 += carry[7]
-	s7 -= carry[7] << 21
-	carry[8] = s8 >> 21
-	s9 += carry[8]
-	s8 -= carry[8] << 21
-	carry[9] = s9 >> 21
-	s10 += carry[9]
-	s9 -= carry[9] << 21
-	carry[10] = s10 >> 21
-	s11 += carry[10]
-	s10 -= carry[10] << 21
-
-	out[0] = byte(s0 >> 0)
-	out[1] = byte(s0 >> 8)
-	out[2] = byte((s0 >> 16) | (s1 << 5))
-	out[3] = byte(s1 >> 3)
-	out[4] = byte(s1 >> 11)
-	out[5] = byte((s1 >> 19) | (s2 << 2))
-	out[6] = byte(s2 >> 6)
-	out[7] = byte((s2 >> 14) | (s3 << 7))
-	out[8] = byte(s3 >> 1)
-	out[9] = byte(s3 >> 9)
-	out[10] = byte((s3 >> 17) | (s4 << 4))
-	out[11] = byte(s4 >> 4)
-	out[12] = byte(s4 >> 12)
-	out[13] = byte((s4 >> 20) | (s5 << 1))
-	out[14] = byte(s5 >> 7)
-	out[15] = byte((s5 >> 15) | (s6 << 6))
-	out[16] = byte(s6 >> 2)
-	out[17] = byte(s6 >> 10)
-	out[18] = byte((s6 >> 18) | (s7 << 3))
-	out[19] = byte(s7 >> 5)
-	out[20] = byte(s7 >> 13)
-	out[21] = byte(s8 >> 0)
-	out[22] = byte(s8 >> 8)
-	out[23] = byte((s8 >> 16) | (s9 << 5))
-	out[24] = byte(s9 >> 3)
-	out[25] = byte(s9 >> 11)
-	out[26] = byte((s9 >> 19) | (s10 << 2))
-	out[27] = byte(s10 >> 6)
-	out[28] = byte((s10 >> 14) | (s11 << 7))
-	out[29] = byte(s11 >> 1)
-	out[30] = byte(s11 >> 9)
-	out[31] = byte(s11 >> 17)
+	var diff fiatScalarMontgomeryDomainFieldElement
+	fiatScalarSub(&diff, &s.s, &t.s)
+	var nonzero uint64
+	fiatScalarNonzero(&nonzero, (*[4]uint64)(&diff))
+	nonzero |= nonzero >> 32
+	nonzero |= nonzero >> 16
+	nonzero |= nonzero >> 8
+	nonzero |= nonzero >> 4
+	nonzero |= nonzero >> 2
+	nonzero |= nonzero >> 1
+	return int(^nonzero) & 1
 }
 
 // nonAdjacentForm computes a width-w non-adjacent form for this scalar.
@@ -950,7 +257,8 @@
 	// This implementation is adapted from the one
 	// in curve25519-dalek and is documented there:
 	// https://github.com/dalek-cryptography/curve25519-dalek/blob/f630041af28e9a405255f98a8a93adca18e4315b/src/scalar.rs#L800-L871
-	if s.s[31] > 127 {
+	b := s.Bytes()
+	if b[31] > 127 {
 		panic("scalar has high bit set illegally")
 	}
 	if w < 2 {
@@ -963,7 +271,7 @@
 	var digits [5]uint64
 
 	for i := 0; i < 4; i++ {
-		digits[i] = binary.LittleEndian.Uint64(s.s[i*8:])
+		digits[i] = binary.LittleEndian.Uint64(b[i*8:])
 	}
 
 	width := uint64(1 << w)
@@ -1011,7 +319,8 @@
 }
 
 func (s *Scalar) signedRadix16() [64]int8 {
-	if s.s[31] > 127 {
+	b := s.Bytes()
+	if b[31] > 127 {
 		panic("scalar has high bit set illegally")
 	}
 
@@ -1019,8 +328,8 @@
 
 	// Compute unsigned radix-16 digits:
 	for i := 0; i < 32; i++ {
-		digits[2*i] = int8(s.s[i] & 15)
-		digits[2*i+1] = int8((s.s[i] >> 4) & 15)
+		digits[2*i] = int8(b[i] & 15)
+		digits[2*i+1] = int8((b[i] >> 4) & 15)
 	}
 
 	// Recenter coefficients:
diff --git a/src/crypto/internal/edwards25519/scalar_alias_test.go b/src/crypto/internal/edwards25519/scalar_alias_test.go
index 827153b..4d83441 100644
--- a/src/crypto/internal/edwards25519/scalar_alias_test.go
+++ b/src/crypto/internal/edwards25519/scalar_alias_test.go
@@ -14,12 +14,12 @@
 		x1, v1 := x, x
 
 		// Calculate a reference f(x) without aliasing.
-		if out := f(&v, &x); out != &v || !isReduced(out) {
+		if out := f(&v, &x); out != &v || !isReduced(out.Bytes()) {
 			return false
 		}
 
 		// Test aliasing the argument and the receiver.
-		if out := f(&v1, &v1); out != &v1 || v1 != v || !isReduced(out) {
+		if out := f(&v1, &v1); out != &v1 || v1 != v || !isReduced(out.Bytes()) {
 			return false
 		}
 
@@ -31,39 +31,39 @@
 		x1, y1, v1 := x, y, Scalar{}
 
 		// Calculate a reference f(x, y) without aliasing.
-		if out := f(&v, &x, &y); out != &v || !isReduced(out) {
+		if out := f(&v, &x, &y); out != &v || !isReduced(out.Bytes()) {
 			return false
 		}
 
 		// Test aliasing the first argument and the receiver.
 		v1 = x
-		if out := f(&v1, &v1, &y); out != &v1 || v1 != v || !isReduced(out) {
+		if out := f(&v1, &v1, &y); out != &v1 || v1 != v || !isReduced(out.Bytes()) {
 			return false
 		}
 		// Test aliasing the second argument and the receiver.
 		v1 = y
-		if out := f(&v1, &x, &v1); out != &v1 || v1 != v || !isReduced(out) {
+		if out := f(&v1, &x, &v1); out != &v1 || v1 != v || !isReduced(out.Bytes()) {
 			return false
 		}
 
 		// Calculate a reference f(x, x) without aliasing.
-		if out := f(&v, &x, &x); out != &v || !isReduced(out) {
+		if out := f(&v, &x, &x); out != &v || !isReduced(out.Bytes()) {
 			return false
 		}
 
 		// Test aliasing the first argument and the receiver.
 		v1 = x
-		if out := f(&v1, &v1, &x); out != &v1 || v1 != v || !isReduced(out) {
+		if out := f(&v1, &v1, &x); out != &v1 || v1 != v || !isReduced(out.Bytes()) {
 			return false
 		}
 		// Test aliasing the second argument and the receiver.
 		v1 = x
-		if out := f(&v1, &x, &v1); out != &v1 || v1 != v || !isReduced(out) {
+		if out := f(&v1, &x, &v1); out != &v1 || v1 != v || !isReduced(out.Bytes()) {
 			return false
 		}
 		// Test aliasing both arguments and the receiver.
 		v1 = x
-		if out := f(&v1, &v1, &v1); out != &v1 || v1 != v || !isReduced(out) {
+		if out := f(&v1, &v1, &v1); out != &v1 || v1 != v || !isReduced(out.Bytes()) {
 			return false
 		}
 
@@ -71,7 +71,7 @@
 		return x == x1 && y == y1
 	}
 
-	for name, f := range map[string]any{
+	for name, f := range map[string]interface{}{
 		"Negate": func(v, x Scalar) bool {
 			return checkAliasingOneArg((*Scalar).Negate, v, x)
 		},
@@ -84,6 +84,21 @@
 		"Subtract": func(v, x, y Scalar) bool {
 			return checkAliasingTwoArgs((*Scalar).Subtract, v, x, y)
 		},
+		"MultiplyAdd1": func(v, x, y, fixed Scalar) bool {
+			return checkAliasingTwoArgs(func(v, x, y *Scalar) *Scalar {
+				return v.MultiplyAdd(&fixed, x, y)
+			}, v, x, y)
+		},
+		"MultiplyAdd2": func(v, x, y, fixed Scalar) bool {
+			return checkAliasingTwoArgs(func(v, x, y *Scalar) *Scalar {
+				return v.MultiplyAdd(x, &fixed, y)
+			}, v, x, y)
+		},
+		"MultiplyAdd3": func(v, x, y, fixed Scalar) bool {
+			return checkAliasingTwoArgs(func(v, x, y *Scalar) *Scalar {
+				return v.MultiplyAdd(x, y, &fixed)
+			}, v, x, y)
+		},
 	} {
 		err := quick.Check(f, &quick.Config{MaxCountScale: 1 << 5})
 		if err != nil {
diff --git a/src/crypto/internal/edwards25519/scalar_fiat.go b/src/crypto/internal/edwards25519/scalar_fiat.go
new file mode 100644
index 0000000..2e5782b
--- /dev/null
+++ b/src/crypto/internal/edwards25519/scalar_fiat.go
@@ -0,0 +1,1147 @@
+// Code generated by Fiat Cryptography. DO NOT EDIT.
+//
+// Autogenerated: word_by_word_montgomery --lang Go --cmovznz-by-mul --relax-primitive-carry-to-bitwidth 32,64 --public-function-case camelCase --public-type-case camelCase --private-function-case camelCase --private-type-case camelCase --doc-text-before-function-name '' --doc-newline-before-package-declaration --doc-prepend-header 'Code generated by Fiat Cryptography. DO NOT EDIT.' --package-name edwards25519 Scalar 64 '2^252 + 27742317777372353535851937790883648493' mul add sub opp nonzero from_montgomery to_montgomery to_bytes from_bytes
+//
+// curve description: Scalar
+//
+// machine_wordsize = 64 (from "64")
+//
+// requested operations: mul, add, sub, opp, nonzero, from_montgomery, to_montgomery, to_bytes, from_bytes
+//
+// m = 0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed (from "2^252 + 27742317777372353535851937790883648493")
+//
+//
+//
+// NOTE: In addition to the bounds specified above each function, all
+//
+//   functions synthesized for this Montgomery arithmetic require the
+//
+//   input to be strictly less than the prime modulus (m), and also
+//
+//   require the input to be in the unique saturated representation.
+//
+//   All functions also ensure that these two properties are true of
+//
+//   return values.
+//
+//
+//
+// Computed values:
+//
+//   eval z = z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192)
+//
+//   bytes_eval z = z[0] + (z[1] << 8) + (z[2] << 16) + (z[3] << 24) + (z[4] << 32) + (z[5] << 40) + (z[6] << 48) + (z[7] << 56) + (z[8] << 64) + (z[9] << 72) + (z[10] << 80) + (z[11] << 88) + (z[12] << 96) + (z[13] << 104) + (z[14] << 112) + (z[15] << 120) + (z[16] << 128) + (z[17] << 136) + (z[18] << 144) + (z[19] << 152) + (z[20] << 160) + (z[21] << 168) + (z[22] << 176) + (z[23] << 184) + (z[24] << 192) + (z[25] << 200) + (z[26] << 208) + (z[27] << 216) + (z[28] << 224) + (z[29] << 232) + (z[30] << 240) + (z[31] << 248)
+//
+//   twos_complement_eval z = let x1 := z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192) in
+//
+//                            if x1 & (2^256-1) < 2^255 then x1 & (2^256-1) else (x1 & (2^256-1)) - 2^256
+
+package edwards25519
+
+import "math/bits"
+
+type fiatScalarUint1 uint64 // We use uint64 instead of a more narrow type for performance reasons; see https://github.com/mit-plv/fiat-crypto/pull/1006#issuecomment-892625927
+type fiatScalarInt1 int64   // We use uint64 instead of a more narrow type for performance reasons; see https://github.com/mit-plv/fiat-crypto/pull/1006#issuecomment-892625927
+
+// The type fiatScalarMontgomeryDomainFieldElement is a field element in the Montgomery domain.
+//
+// Bounds: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
+type fiatScalarMontgomeryDomainFieldElement [4]uint64
+
+// The type fiatScalarNonMontgomeryDomainFieldElement is a field element NOT in the Montgomery domain.
+//
+// Bounds: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
+type fiatScalarNonMontgomeryDomainFieldElement [4]uint64
+
+// fiatScalarCmovznzU64 is a single-word conditional move.
+//
+// Postconditions:
+//
+//	out1 = (if arg1 = 0 then arg2 else arg3)
+//
+// Input Bounds:
+//
+//	arg1: [0x0 ~> 0x1]
+//	arg2: [0x0 ~> 0xffffffffffffffff]
+//	arg3: [0x0 ~> 0xffffffffffffffff]
+//
+// Output Bounds:
+//
+//	out1: [0x0 ~> 0xffffffffffffffff]
+func fiatScalarCmovznzU64(out1 *uint64, arg1 fiatScalarUint1, arg2 uint64, arg3 uint64) {
+	x1 := (uint64(arg1) * 0xffffffffffffffff)
+	x2 := ((x1 & arg3) | ((^x1) & arg2))
+	*out1 = x2
+}
+
+// fiatScalarMul multiplies two field elements in the Montgomery domain.
+//
+// Preconditions:
+//
+//	0 ≤ eval arg1 < m
+//	0 ≤ eval arg2 < m
+//
+// Postconditions:
+//
+//	eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) * eval (from_montgomery arg2)) mod m
+//	0 ≤ eval out1 < m
+func fiatScalarMul(out1 *fiatScalarMontgomeryDomainFieldElement, arg1 *fiatScalarMontgomeryDomainFieldElement, arg2 *fiatScalarMontgomeryDomainFieldElement) {
+	x1 := arg1[1]
+	x2 := arg1[2]
+	x3 := arg1[3]
+	x4 := arg1[0]
+	var x5 uint64
+	var x6 uint64
+	x6, x5 = bits.Mul64(x4, arg2[3])
+	var x7 uint64
+	var x8 uint64
+	x8, x7 = bits.Mul64(x4, arg2[2])
+	var x9 uint64
+	var x10 uint64
+	x10, x9 = bits.Mul64(x4, arg2[1])
+	var x11 uint64
+	var x12 uint64
+	x12, x11 = bits.Mul64(x4, arg2[0])
+	var x13 uint64
+	var x14 uint64
+	x13, x14 = bits.Add64(x12, x9, uint64(0x0))
+	var x15 uint64
+	var x16 uint64
+	x15, x16 = bits.Add64(x10, x7, uint64(fiatScalarUint1(x14)))
+	var x17 uint64
+	var x18 uint64
+	x17, x18 = bits.Add64(x8, x5, uint64(fiatScalarUint1(x16)))
+	x19 := (uint64(fiatScalarUint1(x18)) + x6)
+	var x20 uint64
+	_, x20 = bits.Mul64(x11, 0xd2b51da312547e1b)
+	var x22 uint64
+	var x23 uint64
+	x23, x22 = bits.Mul64(x20, 0x1000000000000000)
+	var x24 uint64
+	var x25 uint64
+	x25, x24 = bits.Mul64(x20, 0x14def9dea2f79cd6)
+	var x26 uint64
+	var x27 uint64
+	x27, x26 = bits.Mul64(x20, 0x5812631a5cf5d3ed)
+	var x28 uint64
+	var x29 uint64
+	x28, x29 = bits.Add64(x27, x24, uint64(0x0))
+	x30 := (uint64(fiatScalarUint1(x29)) + x25)
+	var x32 uint64
+	_, x32 = bits.Add64(x11, x26, uint64(0x0))
+	var x33 uint64
+	var x34 uint64
+	x33, x34 = bits.Add64(x13, x28, uint64(fiatScalarUint1(x32)))
+	var x35 uint64
+	var x36 uint64
+	x35, x36 = bits.Add64(x15, x30, uint64(fiatScalarUint1(x34)))
+	var x37 uint64
+	var x38 uint64
+	x37, x38 = bits.Add64(x17, x22, uint64(fiatScalarUint1(x36)))
+	var x39 uint64
+	var x40 uint64
+	x39, x40 = bits.Add64(x19, x23, uint64(fiatScalarUint1(x38)))
+	var x41 uint64
+	var x42 uint64
+	x42, x41 = bits.Mul64(x1, arg2[3])
+	var x43 uint64
+	var x44 uint64
+	x44, x43 = bits.Mul64(x1, arg2[2])
+	var x45 uint64
+	var x46 uint64
+	x46, x45 = bits.Mul64(x1, arg2[1])
+	var x47 uint64
+	var x48 uint64
+	x48, x47 = bits.Mul64(x1, arg2[0])
+	var x49 uint64
+	var x50 uint64
+	x49, x50 = bits.Add64(x48, x45, uint64(0x0))
+	var x51 uint64
+	var x52 uint64
+	x51, x52 = bits.Add64(x46, x43, uint64(fiatScalarUint1(x50)))
+	var x53 uint64
+	var x54 uint64
+	x53, x54 = bits.Add64(x44, x41, uint64(fiatScalarUint1(x52)))
+	x55 := (uint64(fiatScalarUint1(x54)) + x42)
+	var x56 uint64
+	var x57 uint64
+	x56, x57 = bits.Add64(x33, x47, uint64(0x0))
+	var x58 uint64
+	var x59 uint64
+	x58, x59 = bits.Add64(x35, x49, uint64(fiatScalarUint1(x57)))
+	var x60 uint64
+	var x61 uint64
+	x60, x61 = bits.Add64(x37, x51, uint64(fiatScalarUint1(x59)))
+	var x62 uint64
+	var x63 uint64
+	x62, x63 = bits.Add64(x39, x53, uint64(fiatScalarUint1(x61)))
+	var x64 uint64
+	var x65 uint64
+	x64, x65 = bits.Add64(uint64(fiatScalarUint1(x40)), x55, uint64(fiatScalarUint1(x63)))
+	var x66 uint64
+	_, x66 = bits.Mul64(x56, 0xd2b51da312547e1b)
+	var x68 uint64
+	var x69 uint64
+	x69, x68 = bits.Mul64(x66, 0x1000000000000000)
+	var x70 uint64
+	var x71 uint64
+	x71, x70 = bits.Mul64(x66, 0x14def9dea2f79cd6)
+	var x72 uint64
+	var x73 uint64
+	x73, x72 = bits.Mul64(x66, 0x5812631a5cf5d3ed)
+	var x74 uint64
+	var x75 uint64
+	x74, x75 = bits.Add64(x73, x70, uint64(0x0))
+	x76 := (uint64(fiatScalarUint1(x75)) + x71)
+	var x78 uint64
+	_, x78 = bits.Add64(x56, x72, uint64(0x0))
+	var x79 uint64
+	var x80 uint64
+	x79, x80 = bits.Add64(x58, x74, uint64(fiatScalarUint1(x78)))
+	var x81 uint64
+	var x82 uint64
+	x81, x82 = bits.Add64(x60, x76, uint64(fiatScalarUint1(x80)))
+	var x83 uint64
+	var x84 uint64
+	x83, x84 = bits.Add64(x62, x68, uint64(fiatScalarUint1(x82)))
+	var x85 uint64
+	var x86 uint64
+	x85, x86 = bits.Add64(x64, x69, uint64(fiatScalarUint1(x84)))
+	x87 := (uint64(fiatScalarUint1(x86)) + uint64(fiatScalarUint1(x65)))
+	var x88 uint64
+	var x89 uint64
+	x89, x88 = bits.Mul64(x2, arg2[3])
+	var x90 uint64
+	var x91 uint64
+	x91, x90 = bits.Mul64(x2, arg2[2])
+	var x92 uint64
+	var x93 uint64
+	x93, x92 = bits.Mul64(x2, arg2[1])
+	var x94 uint64
+	var x95 uint64
+	x95, x94 = bits.Mul64(x2, arg2[0])
+	var x96 uint64
+	var x97 uint64
+	x96, x97 = bits.Add64(x95, x92, uint64(0x0))
+	var x98 uint64
+	var x99 uint64
+	x98, x99 = bits.Add64(x93, x90, uint64(fiatScalarUint1(x97)))
+	var x100 uint64
+	var x101 uint64
+	x100, x101 = bits.Add64(x91, x88, uint64(fiatScalarUint1(x99)))
+	x102 := (uint64(fiatScalarUint1(x101)) + x89)
+	var x103 uint64
+	var x104 uint64
+	x103, x104 = bits.Add64(x79, x94, uint64(0x0))
+	var x105 uint64
+	var x106 uint64
+	x105, x106 = bits.Add64(x81, x96, uint64(fiatScalarUint1(x104)))
+	var x107 uint64
+	var x108 uint64
+	x107, x108 = bits.Add64(x83, x98, uint64(fiatScalarUint1(x106)))
+	var x109 uint64
+	var x110 uint64
+	x109, x110 = bits.Add64(x85, x100, uint64(fiatScalarUint1(x108)))
+	var x111 uint64
+	var x112 uint64
+	x111, x112 = bits.Add64(x87, x102, uint64(fiatScalarUint1(x110)))
+	var x113 uint64
+	_, x113 = bits.Mul64(x103, 0xd2b51da312547e1b)
+	var x115 uint64
+	var x116 uint64
+	x116, x115 = bits.Mul64(x113, 0x1000000000000000)
+	var x117 uint64
+	var x118 uint64
+	x118, x117 = bits.Mul64(x113, 0x14def9dea2f79cd6)
+	var x119 uint64
+	var x120 uint64
+	x120, x119 = bits.Mul64(x113, 0x5812631a5cf5d3ed)
+	var x121 uint64
+	var x122 uint64
+	x121, x122 = bits.Add64(x120, x117, uint64(0x0))
+	x123 := (uint64(fiatScalarUint1(x122)) + x118)
+	var x125 uint64
+	_, x125 = bits.Add64(x103, x119, uint64(0x0))
+	var x126 uint64
+	var x127 uint64
+	x126, x127 = bits.Add64(x105, x121, uint64(fiatScalarUint1(x125)))
+	var x128 uint64
+	var x129 uint64
+	x128, x129 = bits.Add64(x107, x123, uint64(fiatScalarUint1(x127)))
+	var x130 uint64
+	var x131 uint64
+	x130, x131 = bits.Add64(x109, x115, uint64(fiatScalarUint1(x129)))
+	var x132 uint64
+	var x133 uint64
+	x132, x133 = bits.Add64(x111, x116, uint64(fiatScalarUint1(x131)))
+	x134 := (uint64(fiatScalarUint1(x133)) + uint64(fiatScalarUint1(x112)))
+	var x135 uint64
+	var x136 uint64
+	x136, x135 = bits.Mul64(x3, arg2[3])
+	var x137 uint64
+	var x138 uint64
+	x138, x137 = bits.Mul64(x3, arg2[2])
+	var x139 uint64
+	var x140 uint64
+	x140, x139 = bits.Mul64(x3, arg2[1])
+	var x141 uint64
+	var x142 uint64
+	x142, x141 = bits.Mul64(x3, arg2[0])
+	var x143 uint64
+	var x144 uint64
+	x143, x144 = bits.Add64(x142, x139, uint64(0x0))
+	var x145 uint64
+	var x146 uint64
+	x145, x146 = bits.Add64(x140, x137, uint64(fiatScalarUint1(x144)))
+	var x147 uint64
+	var x148 uint64
+	x147, x148 = bits.Add64(x138, x135, uint64(fiatScalarUint1(x146)))
+	x149 := (uint64(fiatScalarUint1(x148)) + x136)
+	var x150 uint64
+	var x151 uint64
+	x150, x151 = bits.Add64(x126, x141, uint64(0x0))
+	var x152 uint64
+	var x153 uint64
+	x152, x153 = bits.Add64(x128, x143, uint64(fiatScalarUint1(x151)))
+	var x154 uint64
+	var x155 uint64
+	x154, x155 = bits.Add64(x130, x145, uint64(fiatScalarUint1(x153)))
+	var x156 uint64
+	var x157 uint64
+	x156, x157 = bits.Add64(x132, x147, uint64(fiatScalarUint1(x155)))
+	var x158 uint64
+	var x159 uint64
+	x158, x159 = bits.Add64(x134, x149, uint64(fiatScalarUint1(x157)))
+	var x160 uint64
+	_, x160 = bits.Mul64(x150, 0xd2b51da312547e1b)
+	var x162 uint64
+	var x163 uint64
+	x163, x162 = bits.Mul64(x160, 0x1000000000000000)
+	var x164 uint64
+	var x165 uint64
+	x165, x164 = bits.Mul64(x160, 0x14def9dea2f79cd6)
+	var x166 uint64
+	var x167 uint64
+	x167, x166 = bits.Mul64(x160, 0x5812631a5cf5d3ed)
+	var x168 uint64
+	var x169 uint64
+	x168, x169 = bits.Add64(x167, x164, uint64(0x0))
+	x170 := (uint64(fiatScalarUint1(x169)) + x165)
+	var x172 uint64
+	_, x172 = bits.Add64(x150, x166, uint64(0x0))
+	var x173 uint64
+	var x174 uint64
+	x173, x174 = bits.Add64(x152, x168, uint64(fiatScalarUint1(x172)))
+	var x175 uint64
+	var x176 uint64
+	x175, x176 = bits.Add64(x154, x170, uint64(fiatScalarUint1(x174)))
+	var x177 uint64
+	var x178 uint64
+	x177, x178 = bits.Add64(x156, x162, uint64(fiatScalarUint1(x176)))
+	var x179 uint64
+	var x180 uint64
+	x179, x180 = bits.Add64(x158, x163, uint64(fiatScalarUint1(x178)))
+	x181 := (uint64(fiatScalarUint1(x180)) + uint64(fiatScalarUint1(x159)))
+	var x182 uint64
+	var x183 uint64
+	x182, x183 = bits.Sub64(x173, 0x5812631a5cf5d3ed, uint64(0x0))
+	var x184 uint64
+	var x185 uint64
+	x184, x185 = bits.Sub64(x175, 0x14def9dea2f79cd6, uint64(fiatScalarUint1(x183)))
+	var x186 uint64
+	var x187 uint64
+	x186, x187 = bits.Sub64(x177, uint64(0x0), uint64(fiatScalarUint1(x185)))
+	var x188 uint64
+	var x189 uint64
+	x188, x189 = bits.Sub64(x179, 0x1000000000000000, uint64(fiatScalarUint1(x187)))
+	var x191 uint64
+	_, x191 = bits.Sub64(x181, uint64(0x0), uint64(fiatScalarUint1(x189)))
+	var x192 uint64
+	fiatScalarCmovznzU64(&x192, fiatScalarUint1(x191), x182, x173)
+	var x193 uint64
+	fiatScalarCmovznzU64(&x193, fiatScalarUint1(x191), x184, x175)
+	var x194 uint64
+	fiatScalarCmovznzU64(&x194, fiatScalarUint1(x191), x186, x177)
+	var x195 uint64
+	fiatScalarCmovznzU64(&x195, fiatScalarUint1(x191), x188, x179)
+	out1[0] = x192
+	out1[1] = x193
+	out1[2] = x194
+	out1[3] = x195
+}
+
+// fiatScalarAdd adds two field elements in the Montgomery domain.
+//
+// Preconditions:
+//
+//	0 ≤ eval arg1 < m
+//	0 ≤ eval arg2 < m
+//
+// Postconditions:
+//
+//	eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) + eval (from_montgomery arg2)) mod m
+//	0 ≤ eval out1 < m
+func fiatScalarAdd(out1 *fiatScalarMontgomeryDomainFieldElement, arg1 *fiatScalarMontgomeryDomainFieldElement, arg2 *fiatScalarMontgomeryDomainFieldElement) {
+	var x1 uint64
+	var x2 uint64
+	x1, x2 = bits.Add64(arg1[0], arg2[0], uint64(0x0))
+	var x3 uint64
+	var x4 uint64
+	x3, x4 = bits.Add64(arg1[1], arg2[1], uint64(fiatScalarUint1(x2)))
+	var x5 uint64
+	var x6 uint64
+	x5, x6 = bits.Add64(arg1[2], arg2[2], uint64(fiatScalarUint1(x4)))
+	var x7 uint64
+	var x8 uint64
+	x7, x8 = bits.Add64(arg1[3], arg2[3], uint64(fiatScalarUint1(x6)))
+	var x9 uint64
+	var x10 uint64
+	x9, x10 = bits.Sub64(x1, 0x5812631a5cf5d3ed, uint64(0x0))
+	var x11 uint64
+	var x12 uint64
+	x11, x12 = bits.Sub64(x3, 0x14def9dea2f79cd6, uint64(fiatScalarUint1(x10)))
+	var x13 uint64
+	var x14 uint64
+	x13, x14 = bits.Sub64(x5, uint64(0x0), uint64(fiatScalarUint1(x12)))
+	var x15 uint64
+	var x16 uint64
+	x15, x16 = bits.Sub64(x7, 0x1000000000000000, uint64(fiatScalarUint1(x14)))
+	var x18 uint64
+	_, x18 = bits.Sub64(uint64(fiatScalarUint1(x8)), uint64(0x0), uint64(fiatScalarUint1(x16)))
+	var x19 uint64
+	fiatScalarCmovznzU64(&x19, fiatScalarUint1(x18), x9, x1)
+	var x20 uint64
+	fiatScalarCmovznzU64(&x20, fiatScalarUint1(x18), x11, x3)
+	var x21 uint64
+	fiatScalarCmovznzU64(&x21, fiatScalarUint1(x18), x13, x5)
+	var x22 uint64
+	fiatScalarCmovznzU64(&x22, fiatScalarUint1(x18), x15, x7)
+	out1[0] = x19
+	out1[1] = x20
+	out1[2] = x21
+	out1[3] = x22
+}
+
+// fiatScalarSub subtracts two field elements in the Montgomery domain.
+//
+// Preconditions:
+//
+//	0 ≤ eval arg1 < m
+//	0 ≤ eval arg2 < m
+//
+// Postconditions:
+//
+//	eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) - eval (from_montgomery arg2)) mod m
+//	0 ≤ eval out1 < m
+func fiatScalarSub(out1 *fiatScalarMontgomeryDomainFieldElement, arg1 *fiatScalarMontgomeryDomainFieldElement, arg2 *fiatScalarMontgomeryDomainFieldElement) {
+	var x1 uint64
+	var x2 uint64
+	x1, x2 = bits.Sub64(arg1[0], arg2[0], uint64(0x0))
+	var x3 uint64
+	var x4 uint64
+	x3, x4 = bits.Sub64(arg1[1], arg2[1], uint64(fiatScalarUint1(x2)))
+	var x5 uint64
+	var x6 uint64
+	x5, x6 = bits.Sub64(arg1[2], arg2[2], uint64(fiatScalarUint1(x4)))
+	var x7 uint64
+	var x8 uint64
+	x7, x8 = bits.Sub64(arg1[3], arg2[3], uint64(fiatScalarUint1(x6)))
+	var x9 uint64
+	fiatScalarCmovznzU64(&x9, fiatScalarUint1(x8), uint64(0x0), 0xffffffffffffffff)
+	var x10 uint64
+	var x11 uint64
+	x10, x11 = bits.Add64(x1, (x9 & 0x5812631a5cf5d3ed), uint64(0x0))
+	var x12 uint64
+	var x13 uint64
+	x12, x13 = bits.Add64(x3, (x9 & 0x14def9dea2f79cd6), uint64(fiatScalarUint1(x11)))
+	var x14 uint64
+	var x15 uint64
+	x14, x15 = bits.Add64(x5, uint64(0x0), uint64(fiatScalarUint1(x13)))
+	var x16 uint64
+	x16, _ = bits.Add64(x7, (x9 & 0x1000000000000000), uint64(fiatScalarUint1(x15)))
+	out1[0] = x10
+	out1[1] = x12
+	out1[2] = x14
+	out1[3] = x16
+}
+
+// fiatScalarOpp negates a field element in the Montgomery domain.
+//
+// Preconditions:
+//
+//	0 ≤ eval arg1 < m
+//
+// Postconditions:
+//
+//	eval (from_montgomery out1) mod m = -eval (from_montgomery arg1) mod m
+//	0 ≤ eval out1 < m
+func fiatScalarOpp(out1 *fiatScalarMontgomeryDomainFieldElement, arg1 *fiatScalarMontgomeryDomainFieldElement) {
+	var x1 uint64
+	var x2 uint64
+	x1, x2 = bits.Sub64(uint64(0x0), arg1[0], uint64(0x0))
+	var x3 uint64
+	var x4 uint64
+	x3, x4 = bits.Sub64(uint64(0x0), arg1[1], uint64(fiatScalarUint1(x2)))
+	var x5 uint64
+	var x6 uint64
+	x5, x6 = bits.Sub64(uint64(0x0), arg1[2], uint64(fiatScalarUint1(x4)))
+	var x7 uint64
+	var x8 uint64
+	x7, x8 = bits.Sub64(uint64(0x0), arg1[3], uint64(fiatScalarUint1(x6)))
+	var x9 uint64
+	fiatScalarCmovznzU64(&x9, fiatScalarUint1(x8), uint64(0x0), 0xffffffffffffffff)
+	var x10 uint64
+	var x11 uint64
+	x10, x11 = bits.Add64(x1, (x9 & 0x5812631a5cf5d3ed), uint64(0x0))
+	var x12 uint64
+	var x13 uint64
+	x12, x13 = bits.Add64(x3, (x9 & 0x14def9dea2f79cd6), uint64(fiatScalarUint1(x11)))
+	var x14 uint64
+	var x15 uint64
+	x14, x15 = bits.Add64(x5, uint64(0x0), uint64(fiatScalarUint1(x13)))
+	var x16 uint64
+	x16, _ = bits.Add64(x7, (x9 & 0x1000000000000000), uint64(fiatScalarUint1(x15)))
+	out1[0] = x10
+	out1[1] = x12
+	out1[2] = x14
+	out1[3] = x16
+}
+
+// fiatScalarNonzero outputs a single non-zero word if the input is non-zero and zero otherwise.
+//
+// Preconditions:
+//
+//	0 ≤ eval arg1 < m
+//
+// Postconditions:
+//
+//	out1 = 0 ↔ eval (from_montgomery arg1) mod m = 0
+//
+// Input Bounds:
+//
+//	arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]]
+//
+// Output Bounds:
+//
+//	out1: [0x0 ~> 0xffffffffffffffff]
+func fiatScalarNonzero(out1 *uint64, arg1 *[4]uint64) {
+	x1 := (arg1[0] | (arg1[1] | (arg1[2] | arg1[3])))
+	*out1 = x1
+}
+
+// fiatScalarFromMontgomery translates a field element out of the Montgomery domain.
+//
+// Preconditions:
+//
+//	0 ≤ eval arg1 < m
+//
+// Postconditions:
+//
+//	eval out1 mod m = (eval arg1 * ((2^64)⁻¹ mod m)^4) mod m
+//	0 ≤ eval out1 < m
+func fiatScalarFromMontgomery(out1 *fiatScalarNonMontgomeryDomainFieldElement, arg1 *fiatScalarMontgomeryDomainFieldElement) {
+	x1 := arg1[0]
+	var x2 uint64
+	_, x2 = bits.Mul64(x1, 0xd2b51da312547e1b)
+	var x4 uint64
+	var x5 uint64
+	x5, x4 = bits.Mul64(x2, 0x1000000000000000)
+	var x6 uint64
+	var x7 uint64
+	x7, x6 = bits.Mul64(x2, 0x14def9dea2f79cd6)
+	var x8 uint64
+	var x9 uint64
+	x9, x8 = bits.Mul64(x2, 0x5812631a5cf5d3ed)
+	var x10 uint64
+	var x11 uint64
+	x10, x11 = bits.Add64(x9, x6, uint64(0x0))
+	var x13 uint64
+	_, x13 = bits.Add64(x1, x8, uint64(0x0))
+	var x14 uint64
+	var x15 uint64
+	x14, x15 = bits.Add64(uint64(0x0), x10, uint64(fiatScalarUint1(x13)))
+	var x16 uint64
+	var x17 uint64
+	x16, x17 = bits.Add64(x14, arg1[1], uint64(0x0))
+	var x18 uint64
+	_, x18 = bits.Mul64(x16, 0xd2b51da312547e1b)
+	var x20 uint64
+	var x21 uint64
+	x21, x20 = bits.Mul64(x18, 0x1000000000000000)
+	var x22 uint64
+	var x23 uint64
+	x23, x22 = bits.Mul64(x18, 0x14def9dea2f79cd6)
+	var x24 uint64
+	var x25 uint64
+	x25, x24 = bits.Mul64(x18, 0x5812631a5cf5d3ed)
+	var x26 uint64
+	var x27 uint64
+	x26, x27 = bits.Add64(x25, x22, uint64(0x0))
+	var x29 uint64
+	_, x29 = bits.Add64(x16, x24, uint64(0x0))
+	var x30 uint64
+	var x31 uint64
+	x30, x31 = bits.Add64((uint64(fiatScalarUint1(x17)) + (uint64(fiatScalarUint1(x15)) + (uint64(fiatScalarUint1(x11)) + x7))), x26, uint64(fiatScalarUint1(x29)))
+	var x32 uint64
+	var x33 uint64
+	x32, x33 = bits.Add64(x4, (uint64(fiatScalarUint1(x27)) + x23), uint64(fiatScalarUint1(x31)))
+	var x34 uint64
+	var x35 uint64
+	x34, x35 = bits.Add64(x5, x20, uint64(fiatScalarUint1(x33)))
+	var x36 uint64
+	var x37 uint64
+	x36, x37 = bits.Add64(x30, arg1[2], uint64(0x0))
+	var x38 uint64
+	var x39 uint64
+	x38, x39 = bits.Add64(x32, uint64(0x0), uint64(fiatScalarUint1(x37)))
+	var x40 uint64
+	var x41 uint64
+	x40, x41 = bits.Add64(x34, uint64(0x0), uint64(fiatScalarUint1(x39)))
+	var x42 uint64
+	_, x42 = bits.Mul64(x36, 0xd2b51da312547e1b)
+	var x44 uint64
+	var x45 uint64
+	x45, x44 = bits.Mul64(x42, 0x1000000000000000)
+	var x46 uint64
+	var x47 uint64
+	x47, x46 = bits.Mul64(x42, 0x14def9dea2f79cd6)
+	var x48 uint64
+	var x49 uint64
+	x49, x48 = bits.Mul64(x42, 0x5812631a5cf5d3ed)
+	var x50 uint64
+	var x51 uint64
+	x50, x51 = bits.Add64(x49, x46, uint64(0x0))
+	var x53 uint64
+	_, x53 = bits.Add64(x36, x48, uint64(0x0))
+	var x54 uint64
+	var x55 uint64
+	x54, x55 = bits.Add64(x38, x50, uint64(fiatScalarUint1(x53)))
+	var x56 uint64
+	var x57 uint64
+	x56, x57 = bits.Add64(x40, (uint64(fiatScalarUint1(x51)) + x47), uint64(fiatScalarUint1(x55)))
+	var x58 uint64
+	var x59 uint64
+	x58, x59 = bits.Add64((uint64(fiatScalarUint1(x41)) + (uint64(fiatScalarUint1(x35)) + x21)), x44, uint64(fiatScalarUint1(x57)))
+	var x60 uint64
+	var x61 uint64
+	x60, x61 = bits.Add64(x54, arg1[3], uint64(0x0))
+	var x62 uint64
+	var x63 uint64
+	x62, x63 = bits.Add64(x56, uint64(0x0), uint64(fiatScalarUint1(x61)))
+	var x64 uint64
+	var x65 uint64
+	x64, x65 = bits.Add64(x58, uint64(0x0), uint64(fiatScalarUint1(x63)))
+	var x66 uint64
+	_, x66 = bits.Mul64(x60, 0xd2b51da312547e1b)
+	var x68 uint64
+	var x69 uint64
+	x69, x68 = bits.Mul64(x66, 0x1000000000000000)
+	var x70 uint64
+	var x71 uint64
+	x71, x70 = bits.Mul64(x66, 0x14def9dea2f79cd6)
+	var x72 uint64
+	var x73 uint64
+	x73, x72 = bits.Mul64(x66, 0x5812631a5cf5d3ed)
+	var x74 uint64
+	var x75 uint64
+	x74, x75 = bits.Add64(x73, x70, uint64(0x0))
+	var x77 uint64
+	_, x77 = bits.Add64(x60, x72, uint64(0x0))
+	var x78 uint64
+	var x79 uint64
+	x78, x79 = bits.Add64(x62, x74, uint64(fiatScalarUint1(x77)))
+	var x80 uint64
+	var x81 uint64
+	x80, x81 = bits.Add64(x64, (uint64(fiatScalarUint1(x75)) + x71), uint64(fiatScalarUint1(x79)))
+	var x82 uint64
+	var x83 uint64
+	x82, x83 = bits.Add64((uint64(fiatScalarUint1(x65)) + (uint64(fiatScalarUint1(x59)) + x45)), x68, uint64(fiatScalarUint1(x81)))
+	x84 := (uint64(fiatScalarUint1(x83)) + x69)
+	var x85 uint64
+	var x86 uint64
+	x85, x86 = bits.Sub64(x78, 0x5812631a5cf5d3ed, uint64(0x0))
+	var x87 uint64
+	var x88 uint64
+	x87, x88 = bits.Sub64(x80, 0x14def9dea2f79cd6, uint64(fiatScalarUint1(x86)))
+	var x89 uint64
+	var x90 uint64
+	x89, x90 = bits.Sub64(x82, uint64(0x0), uint64(fiatScalarUint1(x88)))
+	var x91 uint64
+	var x92 uint64
+	x91, x92 = bits.Sub64(x84, 0x1000000000000000, uint64(fiatScalarUint1(x90)))
+	var x94 uint64
+	_, x94 = bits.Sub64(uint64(0x0), uint64(0x0), uint64(fiatScalarUint1(x92)))
+	var x95 uint64
+	fiatScalarCmovznzU64(&x95, fiatScalarUint1(x94), x85, x78)
+	var x96 uint64
+	fiatScalarCmovznzU64(&x96, fiatScalarUint1(x94), x87, x80)
+	var x97 uint64
+	fiatScalarCmovznzU64(&x97, fiatScalarUint1(x94), x89, x82)
+	var x98 uint64
+	fiatScalarCmovznzU64(&x98, fiatScalarUint1(x94), x91, x84)
+	out1[0] = x95
+	out1[1] = x96
+	out1[2] = x97
+	out1[3] = x98
+}
+
+// fiatScalarToMontgomery translates a field element into the Montgomery domain.
+//
+// Preconditions:
+//
+//	0 ≤ eval arg1 < m
+//
+// Postconditions:
+//
+//	eval (from_montgomery out1) mod m = eval arg1 mod m
+//	0 ≤ eval out1 < m
+func fiatScalarToMontgomery(out1 *fiatScalarMontgomeryDomainFieldElement, arg1 *fiatScalarNonMontgomeryDomainFieldElement) {
+	x1 := arg1[1]
+	x2 := arg1[2]
+	x3 := arg1[3]
+	x4 := arg1[0]
+	var x5 uint64
+	var x6 uint64
+	x6, x5 = bits.Mul64(x4, 0x399411b7c309a3d)
+	var x7 uint64
+	var x8 uint64
+	x8, x7 = bits.Mul64(x4, 0xceec73d217f5be65)
+	var x9 uint64
+	var x10 uint64
+	x10, x9 = bits.Mul64(x4, 0xd00e1ba768859347)
+	var x11 uint64
+	var x12 uint64
+	x12, x11 = bits.Mul64(x4, 0xa40611e3449c0f01)
+	var x13 uint64
+	var x14 uint64
+	x13, x14 = bits.Add64(x12, x9, uint64(0x0))
+	var x15 uint64
+	var x16 uint64
+	x15, x16 = bits.Add64(x10, x7, uint64(fiatScalarUint1(x14)))
+	var x17 uint64
+	var x18 uint64
+	x17, x18 = bits.Add64(x8, x5, uint64(fiatScalarUint1(x16)))
+	var x19 uint64
+	_, x19 = bits.Mul64(x11, 0xd2b51da312547e1b)
+	var x21 uint64
+	var x22 uint64
+	x22, x21 = bits.Mul64(x19, 0x1000000000000000)
+	var x23 uint64
+	var x24 uint64
+	x24, x23 = bits.Mul64(x19, 0x14def9dea2f79cd6)
+	var x25 uint64
+	var x26 uint64
+	x26, x25 = bits.Mul64(x19, 0x5812631a5cf5d3ed)
+	var x27 uint64
+	var x28 uint64
+	x27, x28 = bits.Add64(x26, x23, uint64(0x0))
+	var x30 uint64
+	_, x30 = bits.Add64(x11, x25, uint64(0x0))
+	var x31 uint64
+	var x32 uint64
+	x31, x32 = bits.Add64(x13, x27, uint64(fiatScalarUint1(x30)))
+	var x33 uint64
+	var x34 uint64
+	x33, x34 = bits.Add64(x15, (uint64(fiatScalarUint1(x28)) + x24), uint64(fiatScalarUint1(x32)))
+	var x35 uint64
+	var x36 uint64
+	x35, x36 = bits.Add64(x17, x21, uint64(fiatScalarUint1(x34)))
+	var x37 uint64
+	var x38 uint64
+	x38, x37 = bits.Mul64(x1, 0x399411b7c309a3d)
+	var x39 uint64
+	var x40 uint64
+	x40, x39 = bits.Mul64(x1, 0xceec73d217f5be65)
+	var x41 uint64
+	var x42 uint64
+	x42, x41 = bits.Mul64(x1, 0xd00e1ba768859347)
+	var x43 uint64
+	var x44 uint64
+	x44, x43 = bits.Mul64(x1, 0xa40611e3449c0f01)
+	var x45 uint64
+	var x46 uint64
+	x45, x46 = bits.Add64(x44, x41, uint64(0x0))
+	var x47 uint64
+	var x48 uint64
+	x47, x48 = bits.Add64(x42, x39, uint64(fiatScalarUint1(x46)))
+	var x49 uint64
+	var x50 uint64
+	x49, x50 = bits.Add64(x40, x37, uint64(fiatScalarUint1(x48)))
+	var x51 uint64
+	var x52 uint64
+	x51, x52 = bits.Add64(x31, x43, uint64(0x0))
+	var x53 uint64
+	var x54 uint64
+	x53, x54 = bits.Add64(x33, x45, uint64(fiatScalarUint1(x52)))
+	var x55 uint64
+	var x56 uint64
+	x55, x56 = bits.Add64(x35, x47, uint64(fiatScalarUint1(x54)))
+	var x57 uint64
+	var x58 uint64
+	x57, x58 = bits.Add64(((uint64(fiatScalarUint1(x36)) + (uint64(fiatScalarUint1(x18)) + x6)) + x22), x49, uint64(fiatScalarUint1(x56)))
+	var x59 uint64
+	_, x59 = bits.Mul64(x51, 0xd2b51da312547e1b)
+	var x61 uint64
+	var x62 uint64
+	x62, x61 = bits.Mul64(x59, 0x1000000000000000)
+	var x63 uint64
+	var x64 uint64
+	x64, x63 = bits.Mul64(x59, 0x14def9dea2f79cd6)
+	var x65 uint64
+	var x66 uint64
+	x66, x65 = bits.Mul64(x59, 0x5812631a5cf5d3ed)
+	var x67 uint64
+	var x68 uint64
+	x67, x68 = bits.Add64(x66, x63, uint64(0x0))
+	var x70 uint64
+	_, x70 = bits.Add64(x51, x65, uint64(0x0))
+	var x71 uint64
+	var x72 uint64
+	x71, x72 = bits.Add64(x53, x67, uint64(fiatScalarUint1(x70)))
+	var x73 uint64
+	var x74 uint64
+	x73, x74 = bits.Add64(x55, (uint64(fiatScalarUint1(x68)) + x64), uint64(fiatScalarUint1(x72)))
+	var x75 uint64
+	var x76 uint64
+	x75, x76 = bits.Add64(x57, x61, uint64(fiatScalarUint1(x74)))
+	var x77 uint64
+	var x78 uint64
+	x78, x77 = bits.Mul64(x2, 0x399411b7c309a3d)
+	var x79 uint64
+	var x80 uint64
+	x80, x79 = bits.Mul64(x2, 0xceec73d217f5be65)
+	var x81 uint64
+	var x82 uint64
+	x82, x81 = bits.Mul64(x2, 0xd00e1ba768859347)
+	var x83 uint64
+	var x84 uint64
+	x84, x83 = bits.Mul64(x2, 0xa40611e3449c0f01)
+	var x85 uint64
+	var x86 uint64
+	x85, x86 = bits.Add64(x84, x81, uint64(0x0))
+	var x87 uint64
+	var x88 uint64
+	x87, x88 = bits.Add64(x82, x79, uint64(fiatScalarUint1(x86)))
+	var x89 uint64
+	var x90 uint64
+	x89, x90 = bits.Add64(x80, x77, uint64(fiatScalarUint1(x88)))
+	var x91 uint64
+	var x92 uint64
+	x91, x92 = bits.Add64(x71, x83, uint64(0x0))
+	var x93 uint64
+	var x94 uint64
+	x93, x94 = bits.Add64(x73, x85, uint64(fiatScalarUint1(x92)))
+	var x95 uint64
+	var x96 uint64
+	x95, x96 = bits.Add64(x75, x87, uint64(fiatScalarUint1(x94)))
+	var x97 uint64
+	var x98 uint64
+	x97, x98 = bits.Add64(((uint64(fiatScalarUint1(x76)) + (uint64(fiatScalarUint1(x58)) + (uint64(fiatScalarUint1(x50)) + x38))) + x62), x89, uint64(fiatScalarUint1(x96)))
+	var x99 uint64
+	_, x99 = bits.Mul64(x91, 0xd2b51da312547e1b)
+	var x101 uint64
+	var x102 uint64
+	x102, x101 = bits.Mul64(x99, 0x1000000000000000)
+	var x103 uint64
+	var x104 uint64
+	x104, x103 = bits.Mul64(x99, 0x14def9dea2f79cd6)
+	var x105 uint64
+	var x106 uint64
+	x106, x105 = bits.Mul64(x99, 0x5812631a5cf5d3ed)
+	var x107 uint64
+	var x108 uint64
+	x107, x108 = bits.Add64(x106, x103, uint64(0x0))
+	var x110 uint64
+	_, x110 = bits.Add64(x91, x105, uint64(0x0))
+	var x111 uint64
+	var x112 uint64
+	x111, x112 = bits.Add64(x93, x107, uint64(fiatScalarUint1(x110)))
+	var x113 uint64
+	var x114 uint64
+	x113, x114 = bits.Add64(x95, (uint64(fiatScalarUint1(x108)) + x104), uint64(fiatScalarUint1(x112)))
+	var x115 uint64
+	var x116 uint64
+	x115, x116 = bits.Add64(x97, x101, uint64(fiatScalarUint1(x114)))
+	var x117 uint64
+	var x118 uint64
+	x118, x117 = bits.Mul64(x3, 0x399411b7c309a3d)
+	var x119 uint64
+	var x120 uint64
+	x120, x119 = bits.Mul64(x3, 0xceec73d217f5be65)
+	var x121 uint64
+	var x122 uint64
+	x122, x121 = bits.Mul64(x3, 0xd00e1ba768859347)
+	var x123 uint64
+	var x124 uint64
+	x124, x123 = bits.Mul64(x3, 0xa40611e3449c0f01)
+	var x125 uint64
+	var x126 uint64
+	x125, x126 = bits.Add64(x124, x121, uint64(0x0))
+	var x127 uint64
+	var x128 uint64
+	x127, x128 = bits.Add64(x122, x119, uint64(fiatScalarUint1(x126)))
+	var x129 uint64
+	var x130 uint64
+	x129, x130 = bits.Add64(x120, x117, uint64(fiatScalarUint1(x128)))
+	var x131 uint64
+	var x132 uint64
+	x131, x132 = bits.Add64(x111, x123, uint64(0x0))
+	var x133 uint64
+	var x134 uint64
+	x133, x134 = bits.Add64(x113, x125, uint64(fiatScalarUint1(x132)))
+	var x135 uint64
+	var x136 uint64
+	x135, x136 = bits.Add64(x115, x127, uint64(fiatScalarUint1(x134)))
+	var x137 uint64
+	var x138 uint64
+	x137, x138 = bits.Add64(((uint64(fiatScalarUint1(x116)) + (uint64(fiatScalarUint1(x98)) + (uint64(fiatScalarUint1(x90)) + x78))) + x102), x129, uint64(fiatScalarUint1(x136)))
+	var x139 uint64
+	_, x139 = bits.Mul64(x131, 0xd2b51da312547e1b)
+	var x141 uint64
+	var x142 uint64
+	x142, x141 = bits.Mul64(x139, 0x1000000000000000)
+	var x143 uint64
+	var x144 uint64
+	x144, x143 = bits.Mul64(x139, 0x14def9dea2f79cd6)
+	var x145 uint64
+	var x146 uint64
+	x146, x145 = bits.Mul64(x139, 0x5812631a5cf5d3ed)
+	var x147 uint64
+	var x148 uint64
+	x147, x148 = bits.Add64(x146, x143, uint64(0x0))
+	var x150 uint64
+	_, x150 = bits.Add64(x131, x145, uint64(0x0))
+	var x151 uint64
+	var x152 uint64
+	x151, x152 = bits.Add64(x133, x147, uint64(fiatScalarUint1(x150)))
+	var x153 uint64
+	var x154 uint64
+	x153, x154 = bits.Add64(x135, (uint64(fiatScalarUint1(x148)) + x144), uint64(fiatScalarUint1(x152)))
+	var x155 uint64
+	var x156 uint64
+	x155, x156 = bits.Add64(x137, x141, uint64(fiatScalarUint1(x154)))
+	x157 := ((uint64(fiatScalarUint1(x156)) + (uint64(fiatScalarUint1(x138)) + (uint64(fiatScalarUint1(x130)) + x118))) + x142)
+	var x158 uint64
+	var x159 uint64
+	x158, x159 = bits.Sub64(x151, 0x5812631a5cf5d3ed, uint64(0x0))
+	var x160 uint64
+	var x161 uint64
+	x160, x161 = bits.Sub64(x153, 0x14def9dea2f79cd6, uint64(fiatScalarUint1(x159)))
+	var x162 uint64
+	var x163 uint64
+	x162, x163 = bits.Sub64(x155, uint64(0x0), uint64(fiatScalarUint1(x161)))
+	var x164 uint64
+	var x165 uint64
+	x164, x165 = bits.Sub64(x157, 0x1000000000000000, uint64(fiatScalarUint1(x163)))
+	var x167 uint64
+	_, x167 = bits.Sub64(uint64(0x0), uint64(0x0), uint64(fiatScalarUint1(x165)))
+	var x168 uint64
+	fiatScalarCmovznzU64(&x168, fiatScalarUint1(x167), x158, x151)
+	var x169 uint64
+	fiatScalarCmovznzU64(&x169, fiatScalarUint1(x167), x160, x153)
+	var x170 uint64
+	fiatScalarCmovznzU64(&x170, fiatScalarUint1(x167), x162, x155)
+	var x171 uint64
+	fiatScalarCmovznzU64(&x171, fiatScalarUint1(x167), x164, x157)
+	out1[0] = x168
+	out1[1] = x169
+	out1[2] = x170
+	out1[3] = x171
+}
+
+// fiatScalarToBytes serializes a field element NOT in the Montgomery domain to bytes in little-endian order.
+//
+// Preconditions:
+//
+//	0 ≤ eval arg1 < m
+//
+// Postconditions:
+//
+//	out1 = map (λ x, ⌊((eval arg1 mod m) mod 2^(8 * (x + 1))) / 2^(8 * x)⌋) [0..31]
+//
+// Input Bounds:
+//
+//	arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0x1fffffffffffffff]]
+//
+// Output Bounds:
+//
+//	out1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0x1f]]
+func fiatScalarToBytes(out1 *[32]uint8, arg1 *[4]uint64) {
+	x1 := arg1[3]
+	x2 := arg1[2]
+	x3 := arg1[1]
+	x4 := arg1[0]
+	x5 := (uint8(x4) & 0xff)
+	x6 := (x4 >> 8)
+	x7 := (uint8(x6) & 0xff)
+	x8 := (x6 >> 8)
+	x9 := (uint8(x8) & 0xff)
+	x10 := (x8 >> 8)
+	x11 := (uint8(x10) & 0xff)
+	x12 := (x10 >> 8)
+	x13 := (uint8(x12) & 0xff)
+	x14 := (x12 >> 8)
+	x15 := (uint8(x14) & 0xff)
+	x16 := (x14 >> 8)
+	x17 := (uint8(x16) & 0xff)
+	x18 := uint8((x16 >> 8))
+	x19 := (uint8(x3) & 0xff)
+	x20 := (x3 >> 8)
+	x21 := (uint8(x20) & 0xff)
+	x22 := (x20 >> 8)
+	x23 := (uint8(x22) & 0xff)
+	x24 := (x22 >> 8)
+	x25 := (uint8(x24) & 0xff)
+	x26 := (x24 >> 8)
+	x27 := (uint8(x26) & 0xff)
+	x28 := (x26 >> 8)
+	x29 := (uint8(x28) & 0xff)
+	x30 := (x28 >> 8)
+	x31 := (uint8(x30) & 0xff)
+	x32 := uint8((x30 >> 8))
+	x33 := (uint8(x2) & 0xff)
+	x34 := (x2 >> 8)
+	x35 := (uint8(x34) & 0xff)
+	x36 := (x34 >> 8)
+	x37 := (uint8(x36) & 0xff)
+	x38 := (x36 >> 8)
+	x39 := (uint8(x38) & 0xff)
+	x40 := (x38 >> 8)
+	x41 := (uint8(x40) & 0xff)
+	x42 := (x40 >> 8)
+	x43 := (uint8(x42) & 0xff)
+	x44 := (x42 >> 8)
+	x45 := (uint8(x44) & 0xff)
+	x46 := uint8((x44 >> 8))
+	x47 := (uint8(x1) & 0xff)
+	x48 := (x1 >> 8)
+	x49 := (uint8(x48) & 0xff)
+	x50 := (x48 >> 8)
+	x51 := (uint8(x50) & 0xff)
+	x52 := (x50 >> 8)
+	x53 := (uint8(x52) & 0xff)
+	x54 := (x52 >> 8)
+	x55 := (uint8(x54) & 0xff)
+	x56 := (x54 >> 8)
+	x57 := (uint8(x56) & 0xff)
+	x58 := (x56 >> 8)
+	x59 := (uint8(x58) & 0xff)
+	x60 := uint8((x58 >> 8))
+	out1[0] = x5
+	out1[1] = x7
+	out1[2] = x9
+	out1[3] = x11
+	out1[4] = x13
+	out1[5] = x15
+	out1[6] = x17
+	out1[7] = x18
+	out1[8] = x19
+	out1[9] = x21
+	out1[10] = x23
+	out1[11] = x25
+	out1[12] = x27
+	out1[13] = x29
+	out1[14] = x31
+	out1[15] = x32
+	out1[16] = x33
+	out1[17] = x35
+	out1[18] = x37
+	out1[19] = x39
+	out1[20] = x41
+	out1[21] = x43
+	out1[22] = x45
+	out1[23] = x46
+	out1[24] = x47
+	out1[25] = x49
+	out1[26] = x51
+	out1[27] = x53
+	out1[28] = x55
+	out1[29] = x57
+	out1[30] = x59
+	out1[31] = x60
+}
+
+// fiatScalarFromBytes deserializes a field element NOT in the Montgomery domain from bytes in little-endian order.
+//
+// Preconditions:
+//
+//	0 ≤ bytes_eval arg1 < m
+//
+// Postconditions:
+//
+//	eval out1 mod m = bytes_eval arg1 mod m
+//	0 ≤ eval out1 < m
+//
+// Input Bounds:
+//
+//	arg1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0x1f]]
+//
+// Output Bounds:
+//
+//	out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0x1fffffffffffffff]]
+func fiatScalarFromBytes(out1 *[4]uint64, arg1 *[32]uint8) {
+	x1 := (uint64(arg1[31]) << 56)
+	x2 := (uint64(arg1[30]) << 48)
+	x3 := (uint64(arg1[29]) << 40)
+	x4 := (uint64(arg1[28]) << 32)
+	x5 := (uint64(arg1[27]) << 24)
+	x6 := (uint64(arg1[26]) << 16)
+	x7 := (uint64(arg1[25]) << 8)
+	x8 := arg1[24]
+	x9 := (uint64(arg1[23]) << 56)
+	x10 := (uint64(arg1[22]) << 48)
+	x11 := (uint64(arg1[21]) << 40)
+	x12 := (uint64(arg1[20]) << 32)
+	x13 := (uint64(arg1[19]) << 24)
+	x14 := (uint64(arg1[18]) << 16)
+	x15 := (uint64(arg1[17]) << 8)
+	x16 := arg1[16]
+	x17 := (uint64(arg1[15]) << 56)
+	x18 := (uint64(arg1[14]) << 48)
+	x19 := (uint64(arg1[13]) << 40)
+	x20 := (uint64(arg1[12]) << 32)
+	x21 := (uint64(arg1[11]) << 24)
+	x22 := (uint64(arg1[10]) << 16)
+	x23 := (uint64(arg1[9]) << 8)
+	x24 := arg1[8]
+	x25 := (uint64(arg1[7]) << 56)
+	x26 := (uint64(arg1[6]) << 48)
+	x27 := (uint64(arg1[5]) << 40)
+	x28 := (uint64(arg1[4]) << 32)
+	x29 := (uint64(arg1[3]) << 24)
+	x30 := (uint64(arg1[2]) << 16)
+	x31 := (uint64(arg1[1]) << 8)
+	x32 := arg1[0]
+	x33 := (x31 + uint64(x32))
+	x34 := (x30 + x33)
+	x35 := (x29 + x34)
+	x36 := (x28 + x35)
+	x37 := (x27 + x36)
+	x38 := (x26 + x37)
+	x39 := (x25 + x38)
+	x40 := (x23 + uint64(x24))
+	x41 := (x22 + x40)
+	x42 := (x21 + x41)
+	x43 := (x20 + x42)
+	x44 := (x19 + x43)
+	x45 := (x18 + x44)
+	x46 := (x17 + x45)
+	x47 := (x15 + uint64(x16))
+	x48 := (x14 + x47)
+	x49 := (x13 + x48)
+	x50 := (x12 + x49)
+	x51 := (x11 + x50)
+	x52 := (x10 + x51)
+	x53 := (x9 + x52)
+	x54 := (x7 + uint64(x8))
+	x55 := (x6 + x54)
+	x56 := (x5 + x55)
+	x57 := (x4 + x56)
+	x58 := (x3 + x57)
+	x59 := (x2 + x58)
+	x60 := (x1 + x59)
+	out1[0] = x39
+	out1[1] = x46
+	out1[2] = x53
+	out1[3] = x60
+}
diff --git a/src/crypto/internal/edwards25519/scalar_test.go b/src/crypto/internal/edwards25519/scalar_test.go
index 9d51b34..67bcdaf 100644
--- a/src/crypto/internal/edwards25519/scalar_test.go
+++ b/src/crypto/internal/edwards25519/scalar_test.go
@@ -14,34 +14,43 @@
 	"testing/quick"
 )
 
+var scOneBytes = [32]byte{1}
+var scOne, _ = new(Scalar).SetCanonicalBytes(scOneBytes[:])
+var scMinusOne, _ = new(Scalar).SetCanonicalBytes(scalarMinusOneBytes[:])
+
 // Generate returns a valid (reduced modulo l) Scalar with a distribution
 // weighted towards high, low, and edge values.
 func (Scalar) Generate(rand *mathrand.Rand, size int) reflect.Value {
-	s := scZero
+	var s [32]byte
 	diceRoll := rand.Intn(100)
 	switch {
 	case diceRoll == 0:
 	case diceRoll == 1:
-		s = scOne
+		s = scOneBytes
 	case diceRoll == 2:
-		s = scMinusOne
+		s = scalarMinusOneBytes
 	case diceRoll < 5:
 		// Generate a low scalar in [0, 2^125).
-		rand.Read(s.s[:16])
-		s.s[15] &= (1 << 5) - 1
+		rand.Read(s[:16])
+		s[15] &= (1 << 5) - 1
 	case diceRoll < 10:
 		// Generate a high scalar in [2^252, 2^252 + 2^124).
-		s.s[31] = 1 << 4
-		rand.Read(s.s[:16])
-		s.s[15] &= (1 << 4) - 1
+		s[31] = 1 << 4
+		rand.Read(s[:16])
+		s[15] &= (1 << 4) - 1
 	default:
 		// Generate a valid scalar in [0, l) by returning [0, 2^252) which has a
 		// negligibly different distribution (the former has a 2^-127.6 chance
 		// of being out of the latter range).
-		rand.Read(s.s[:])
-		s.s[31] &= (1 << 4) - 1
+		rand.Read(s[:])
+		s[31] &= (1 << 4) - 1
 	}
-	return reflect.ValueOf(s)
+
+	val := Scalar{}
+	fiatScalarFromBytes((*[4]uint64)(&val.s), &s)
+	fiatScalarToMontgomery(&val.s, (*fiatScalarNonMontgomeryDomainFieldElement)(&val.s))
+
+	return reflect.ValueOf(val)
 }
 
 // quickCheckConfig1024 will make each quickcheck test run (1024 * -quickchecks)
@@ -50,7 +59,7 @@
 
 func TestScalarGenerate(t *testing.T) {
 	f := func(sc Scalar) bool {
-		return isReduced(&sc)
+		return isReduced(sc.Bytes())
 	}
 	if err := quick.Check(f, quickCheckConfig1024); err != nil {
 		t.Errorf("generated unreduced scalar: %v", err)
@@ -64,7 +73,8 @@
 		if _, err := sc.SetCanonicalBytes(in[:]); err != nil {
 			return false
 		}
-		return bytes.Equal(in[:], sc.Bytes()) && isReduced(&sc)
+		repr := sc.Bytes()
+		return bytes.Equal(in[:], repr) && isReduced(repr)
 	}
 	if err := quick.Check(f1, quickCheckConfig1024); err != nil {
 		t.Errorf("failed bytes->scalar->bytes round-trip: %v", err)
@@ -80,7 +90,7 @@
 		t.Errorf("failed scalar->bytes->scalar round-trip: %v", err)
 	}
 
-	b := scMinusOne.s
+	b := scalarMinusOneBytes
 	b[31] += 1
 	s := scOne
 	if out, err := s.SetCanonicalBytes(b[:]); err == nil {
@@ -97,10 +107,11 @@
 	mod.Add(mod, new(big.Int).Lsh(big.NewInt(1), 252))
 	f := func(in [64]byte, sc Scalar) bool {
 		sc.SetUniformBytes(in[:])
-		if !isReduced(&sc) {
+		repr := sc.Bytes()
+		if !isReduced(repr) {
 			return false
 		}
-		scBig := bigIntFromLittleEndianBytes(sc.s[:])
+		scBig := bigIntFromLittleEndianBytes(repr[:])
 		inBig := bigIntFromLittleEndianBytes(in[:])
 		return inBig.Mod(inBig, mod).Cmp(scBig) == 0
 	}
@@ -159,7 +170,9 @@
 		t3.Multiply(&y, &z)
 		t2.Add(&t2, &t3)
 
-		return t1 == t2 && isReduced(&t1) && isReduced(&t3)
+		reprT1, reprT2 := t1.Bytes(), t2.Bytes()
+
+		return t1 == t2 && isReduced(reprT1) && isReduced(reprT2)
 	}
 
 	if err := quick.Check(multiplyDistributesOverAdd, quickCheckConfig1024); err != nil {
@@ -178,7 +191,7 @@
 		t2.Negate(&y)
 		t2.Add(&t2, &x)
 
-		return t1 == t2 && isReduced(&t1)
+		return t1 == t2 && isReduced(t1.Bytes())
 	}
 
 	if err := quick.Check(addLikeSubNeg, quickCheckConfig1024); err != nil {
@@ -187,12 +200,13 @@
 }
 
 func TestScalarNonAdjacentForm(t *testing.T) {
-	s := Scalar{[32]byte{
+	s, _ := (&Scalar{}).SetCanonicalBytes([]byte{
 		0x1a, 0x0e, 0x97, 0x8a, 0x90, 0xf6, 0x62, 0x2d,
 		0x37, 0x47, 0x02, 0x3f, 0x8a, 0xd8, 0x26, 0x4d,
 		0xa7, 0x58, 0xaa, 0x1b, 0x88, 0xe0, 0x40, 0xd1,
 		0x58, 0x9e, 0x7b, 0x7f, 0x23, 0x76, 0xef, 0x09,
-	}}
+	})
+
 	expectedNaf := [256]int8{
 		0, 13, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, -9, 0, 0, 0, 0, -11, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1,
 		0, 0, 0, 0, 9, 0, 0, 0, 0, -5, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 11, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0,
@@ -217,17 +231,19 @@
 
 func (notZeroScalar) Generate(rand *mathrand.Rand, size int) reflect.Value {
 	var s Scalar
-	for s == scZero {
+	var isNonZero uint64
+	for isNonZero == 0 {
 		s = Scalar{}.Generate(rand, size).Interface().(Scalar)
+		fiatScalarNonzero(&isNonZero, (*[4]uint64)(&s.s))
 	}
 	return reflect.ValueOf(notZeroScalar(s))
 }
 
 func TestScalarEqual(t *testing.T) {
-	if scOne.Equal(&scMinusOne) == 1 {
+	if scOne.Equal(scMinusOne) == 1 {
 		t.Errorf("scOne.Equal(&scMinusOne) is true")
 	}
-	if scMinusOne.Equal(&scMinusOne) == 0 {
+	if scMinusOne.Equal(scMinusOne) == 0 {
 		t.Errorf("scMinusOne.Equal(&scMinusOne) is false")
 	}
 }
diff --git a/src/crypto/internal/edwards25519/scalarmult_test.go b/src/crypto/internal/edwards25519/scalarmult_test.go
index 1760603..6c92ab3 100644
--- a/src/crypto/internal/edwards25519/scalarmult_test.go
+++ b/src/crypto/internal/edwards25519/scalarmult_test.go
@@ -15,7 +15,7 @@
 	quickCheckConfig32 = &quick.Config{MaxCountScale: 1 << 5}
 
 	// a random scalar generated using dalek.
-	dalekScalar = Scalar{[32]byte{219, 106, 114, 9, 174, 249, 155, 89, 69, 203, 201, 93, 92, 116, 234, 187, 78, 115, 103, 172, 182, 98, 62, 103, 187, 136, 13, 100, 248, 110, 12, 4}}
+	dalekScalar, _ = (&Scalar{}).SetCanonicalBytes([]byte{219, 106, 114, 9, 174, 249, 155, 89, 69, 203, 201, 93, 92, 116, 234, 187, 78, 115, 103, 172, 182, 98, 62, 103, 187, 136, 13, 100, 248, 110, 12, 4})
 	// the above, times the edwards25519 basepoint.
 	dalekScalarBasepoint, _ = new(Point).SetBytes([]byte{0xf4, 0xef, 0x7c, 0xa, 0x34, 0x55, 0x7b, 0x9f, 0x72, 0x3b, 0xb6, 0x1e, 0xf9, 0x46, 0x9, 0x91, 0x1c, 0xb9, 0xc0, 0x6c, 0x17, 0x28, 0x2d, 0x8b, 0x43, 0x2b, 0x5, 0x18, 0x6a, 0x54, 0x3e, 0x48})
 )
@@ -29,8 +29,8 @@
 	}
 	checkOnCurve(t, &p)
 
-	z = Scalar{[32]byte{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}
-	p.ScalarMult(&z, B)
+	scEight, _ := (&Scalar{}).SetCanonicalBytes([]byte{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})
+	p.ScalarMult(scEight, B)
 	if B.Equal(&p) != 1 {
 		t.Error("1*B != 1")
 	}
@@ -39,7 +39,7 @@
 
 func TestScalarMultVsDalek(t *testing.T) {
 	var p Point
-	p.ScalarMult(&dalekScalar, B)
+	p.ScalarMult(dalekScalar, B)
 	if dalekScalarBasepoint.Equal(&p) != 1 {
 		t.Error("Scalar mul does not match dalek")
 	}
@@ -48,7 +48,7 @@
 
 func TestBaseMultVsDalek(t *testing.T) {
 	var p Point
-	p.ScalarBaseMult(&dalekScalar)
+	p.ScalarBaseMult(dalekScalar)
 	if dalekScalarBasepoint.Equal(&p) != 1 {
 		t.Error("Scalar mul does not match dalek")
 	}
@@ -58,12 +58,12 @@
 func TestVarTimeDoubleBaseMultVsDalek(t *testing.T) {
 	var p Point
 	var z Scalar
-	p.VarTimeDoubleScalarBaseMult(&dalekScalar, B, &z)
+	p.VarTimeDoubleScalarBaseMult(dalekScalar, B, &z)
 	if dalekScalarBasepoint.Equal(&p) != 1 {
 		t.Error("VarTimeDoubleScalarBaseMult fails with b=0")
 	}
 	checkOnCurve(t, &p)
-	p.VarTimeDoubleScalarBaseMult(&z, B, &dalekScalar)
+	p.VarTimeDoubleScalarBaseMult(&z, B, dalekScalar)
 	if dalekScalarBasepoint.Equal(&p) != 1 {
 		t.Error("VarTimeDoubleScalarBaseMult fails with a=0")
 	}
@@ -188,7 +188,7 @@
 	var p Point
 
 	for i := 0; i < b.N; i++ {
-		p.ScalarBaseMult(&dalekScalar)
+		p.ScalarBaseMult(dalekScalar)
 	}
 }
 
@@ -196,7 +196,7 @@
 	var p Point
 
 	for i := 0; i < b.N; i++ {
-		p.ScalarMult(&dalekScalar, B)
+		p.ScalarMult(dalekScalar, B)
 	}
 }
 
@@ -204,6 +204,6 @@
 	var p Point
 
 	for i := 0; i < b.N; i++ {
-		p.VarTimeDoubleScalarBaseMult(&dalekScalar, B, &dalekScalar)
+		p.VarTimeDoubleScalarBaseMult(dalekScalar, B, dalekScalar)
 	}
 }
diff --git a/src/crypto/internal/edwards25519/tables.go b/src/crypto/internal/edwards25519/tables.go
index 5ca40f7..83234bb 100644
--- a/src/crypto/internal/edwards25519/tables.go
+++ b/src/crypto/internal/edwards25519/tables.go
@@ -38,7 +38,7 @@
 	tmpP3 := Point{}
 	tmpP1xP1 := projP1xP1{}
 	for i := 0; i < 7; i++ {
-		// Compute (i+1)*Q as Q + i*Q and convert to a ProjCached
+		// Compute (i+1)*Q as Q + i*Q and convert to a projCached
 		// This is needlessly complicated because the API has explicit
 		// receivers instead of creating stack objects and relying on RVO
 		v.points[i+1].FromP3(tmpP3.fromP1xP1(tmpP1xP1.Add(q, &v.points[i])))
@@ -53,7 +53,7 @@
 	tmpP3 := Point{}
 	tmpP1xP1 := projP1xP1{}
 	for i := 0; i < 7; i++ {
-		// Compute (i+1)*Q as Q + i*Q and convert to AffineCached
+		// Compute (i+1)*Q as Q + i*Q and convert to affineCached
 		v.points[i+1].FromP3(tmpP3.fromP1xP1(tmpP1xP1.AddAffine(q, &v.points[i])))
 	}
 }
diff --git a/src/crypto/internal/nistec/fiat/generate.go b/src/crypto/internal/nistec/fiat/generate.go
index 3b97307..db57021 100644
--- a/src/crypto/internal/nistec/fiat/generate.go
+++ b/src/crypto/internal/nistec/fiat/generate.go
@@ -182,12 +182,11 @@
 	return subtle.ConstantTimeCompare(eBytes, tBytes)
 }
 
-var {{ .Prefix }}ZeroEncoding = new({{ .Element }}).Bytes()
-
 // IsZero returns 1 if e == 0, and zero otherwise.
 func (e *{{ .Element }}) IsZero() int {
+	zero := make([]byte, {{ .Prefix }}ElementLen)
 	eBytes := e.Bytes()
-	return subtle.ConstantTimeCompare(eBytes, {{ .Prefix }}ZeroEncoding)
+	return subtle.ConstantTimeCompare(eBytes, zero)
 }
 
 // Set sets e = t, and returns e.
@@ -212,12 +211,6 @@
 	return out[:]
 }
 
-// {{ .Prefix }}MinusOneEncoding is the encoding of -1 mod p, so p - 1, the
-// highest canonical encoding. It is used by SetBytes to check for non-canonical
-// encodings such as p + k, 2p + k, etc.
-var {{ .Prefix }}MinusOneEncoding = new({{ .Element }}).Sub(
-	new({{ .Element }}), new({{ .Element }}).One()).Bytes()
-
 // SetBytes sets e = v, where v is a big-endian {{ .BytesLen }}-byte encoding, and returns e.
 // If v is not {{ .BytesLen }} bytes or it encodes a value higher than {{ .Prime }},
 // SetBytes returns nil and an error, and e is unchanged.
@@ -225,14 +218,20 @@
 	if len(v) != {{ .Prefix }}ElementLen {
 		return nil, errors.New("invalid {{ .Element }} encoding")
 	}
+
+	// Check for non-canonical encodings (p + k, 2p + k, etc.) by comparing to
+	// the encoding of -1 mod p, so p - 1, the highest canonical encoding.
+	var minusOneEncoding = new({{ .Element }}).Sub(
+		new({{ .Element }}), new({{ .Element }}).One()).Bytes()
 	for i := range v {
-		if v[i] < {{ .Prefix }}MinusOneEncoding[i] {
+		if v[i] < minusOneEncoding[i] {
 			break
 		}
-		if v[i] > {{ .Prefix }}MinusOneEncoding[i] {
+		if v[i] > minusOneEncoding[i] {
 			return nil, errors.New("invalid {{ .Element }} encoding")
 		}
 	}
+
 	var in [{{ .Prefix }}ElementLen]byte
 	copy(in[:], v)
 	{{ .Prefix }}InvertEndianness(in[:])
diff --git a/src/crypto/internal/nistec/fiat/p224.go b/src/crypto/internal/nistec/fiat/p224.go
index 4dddeb0..e1a78db 100644
--- a/src/crypto/internal/nistec/fiat/p224.go
+++ b/src/crypto/internal/nistec/fiat/p224.go
@@ -37,12 +37,11 @@
 	return subtle.ConstantTimeCompare(eBytes, tBytes)
 }
 
-var p224ZeroEncoding = new(P224Element).Bytes()
-
 // IsZero returns 1 if e == 0, and zero otherwise.
 func (e *P224Element) IsZero() int {
+	zero := make([]byte, p224ElementLen)
 	eBytes := e.Bytes()
-	return subtle.ConstantTimeCompare(eBytes, p224ZeroEncoding)
+	return subtle.ConstantTimeCompare(eBytes, zero)
 }
 
 // Set sets e = t, and returns e.
@@ -67,12 +66,6 @@
 	return out[:]
 }
 
-// p224MinusOneEncoding is the encoding of -1 mod p, so p - 1, the
-// highest canonical encoding. It is used by SetBytes to check for non-canonical
-// encodings such as p + k, 2p + k, etc.
-var p224MinusOneEncoding = new(P224Element).Sub(
-	new(P224Element), new(P224Element).One()).Bytes()
-
 // SetBytes sets e = v, where v is a big-endian 28-byte encoding, and returns e.
 // If v is not 28 bytes or it encodes a value higher than 2^224 - 2^96 + 1,
 // SetBytes returns nil and an error, and e is unchanged.
@@ -80,14 +73,20 @@
 	if len(v) != p224ElementLen {
 		return nil, errors.New("invalid P224Element encoding")
 	}
+
+	// Check for non-canonical encodings (p + k, 2p + k, etc.) by comparing to
+	// the encoding of -1 mod p, so p - 1, the highest canonical encoding.
+	var minusOneEncoding = new(P224Element).Sub(
+		new(P224Element), new(P224Element).One()).Bytes()
 	for i := range v {
-		if v[i] < p224MinusOneEncoding[i] {
+		if v[i] < minusOneEncoding[i] {
 			break
 		}
-		if v[i] > p224MinusOneEncoding[i] {
+		if v[i] > minusOneEncoding[i] {
 			return nil, errors.New("invalid P224Element encoding")
 		}
 	}
+
 	var in [p224ElementLen]byte
 	copy(in[:], v)
 	p224InvertEndianness(in[:])
diff --git a/src/crypto/internal/nistec/fiat/p224_invert.go b/src/crypto/internal/nistec/fiat/p224_invert.go
index 4163ed0..3cf5286 100644
--- a/src/crypto/internal/nistec/fiat/p224_invert.go
+++ b/src/crypto/internal/nistec/fiat/p224_invert.go
@@ -12,7 +12,7 @@
 func (e *P224Element) Invert(x *P224Element) *P224Element {
 	// Inversion is implemented as exponentiation with exponent p − 2.
 	// The sequence of 11 multiplications and 223 squarings is derived from the
-	// following addition chain generated with github.com/mmcloughlin/addchain v0.3.0.
+	// following addition chain generated with github.com/mmcloughlin/addchain v0.4.0.
 	//
 	//	_10     = 2*1
 	//	_11     = 1 + _10
diff --git a/src/crypto/internal/nistec/fiat/p256.go b/src/crypto/internal/nistec/fiat/p256.go
index dfdd0a7..7705904 100644
--- a/src/crypto/internal/nistec/fiat/p256.go
+++ b/src/crypto/internal/nistec/fiat/p256.go
@@ -37,12 +37,11 @@
 	return subtle.ConstantTimeCompare(eBytes, tBytes)
 }
 
-var p256ZeroEncoding = new(P256Element).Bytes()
-
 // IsZero returns 1 if e == 0, and zero otherwise.
 func (e *P256Element) IsZero() int {
+	zero := make([]byte, p256ElementLen)
 	eBytes := e.Bytes()
-	return subtle.ConstantTimeCompare(eBytes, p256ZeroEncoding)
+	return subtle.ConstantTimeCompare(eBytes, zero)
 }
 
 // Set sets e = t, and returns e.
@@ -67,12 +66,6 @@
 	return out[:]
 }
 
-// p256MinusOneEncoding is the encoding of -1 mod p, so p - 1, the
-// highest canonical encoding. It is used by SetBytes to check for non-canonical
-// encodings such as p + k, 2p + k, etc.
-var p256MinusOneEncoding = new(P256Element).Sub(
-	new(P256Element), new(P256Element).One()).Bytes()
-
 // SetBytes sets e = v, where v is a big-endian 32-byte encoding, and returns e.
 // If v is not 32 bytes or it encodes a value higher than 2^256 - 2^224 + 2^192 + 2^96 - 1,
 // SetBytes returns nil and an error, and e is unchanged.
@@ -80,14 +73,20 @@
 	if len(v) != p256ElementLen {
 		return nil, errors.New("invalid P256Element encoding")
 	}
+
+	// Check for non-canonical encodings (p + k, 2p + k, etc.) by comparing to
+	// the encoding of -1 mod p, so p - 1, the highest canonical encoding.
+	var minusOneEncoding = new(P256Element).Sub(
+		new(P256Element), new(P256Element).One()).Bytes()
 	for i := range v {
-		if v[i] < p256MinusOneEncoding[i] {
+		if v[i] < minusOneEncoding[i] {
 			break
 		}
-		if v[i] > p256MinusOneEncoding[i] {
+		if v[i] > minusOneEncoding[i] {
 			return nil, errors.New("invalid P256Element encoding")
 		}
 	}
+
 	var in [p256ElementLen]byte
 	copy(in[:], v)
 	p256InvertEndianness(in[:])
diff --git a/src/crypto/internal/nistec/fiat/p384.go b/src/crypto/internal/nistec/fiat/p384.go
index 5474d77..aed0c01 100644
--- a/src/crypto/internal/nistec/fiat/p384.go
+++ b/src/crypto/internal/nistec/fiat/p384.go
@@ -37,12 +37,11 @@
 	return subtle.ConstantTimeCompare(eBytes, tBytes)
 }
 
-var p384ZeroEncoding = new(P384Element).Bytes()
-
 // IsZero returns 1 if e == 0, and zero otherwise.
 func (e *P384Element) IsZero() int {
+	zero := make([]byte, p384ElementLen)
 	eBytes := e.Bytes()
-	return subtle.ConstantTimeCompare(eBytes, p384ZeroEncoding)
+	return subtle.ConstantTimeCompare(eBytes, zero)
 }
 
 // Set sets e = t, and returns e.
@@ -67,12 +66,6 @@
 	return out[:]
 }
 
-// p384MinusOneEncoding is the encoding of -1 mod p, so p - 1, the
-// highest canonical encoding. It is used by SetBytes to check for non-canonical
-// encodings such as p + k, 2p + k, etc.
-var p384MinusOneEncoding = new(P384Element).Sub(
-	new(P384Element), new(P384Element).One()).Bytes()
-
 // SetBytes sets e = v, where v is a big-endian 48-byte encoding, and returns e.
 // If v is not 48 bytes or it encodes a value higher than 2^384 - 2^128 - 2^96 + 2^32 - 1,
 // SetBytes returns nil and an error, and e is unchanged.
@@ -80,14 +73,20 @@
 	if len(v) != p384ElementLen {
 		return nil, errors.New("invalid P384Element encoding")
 	}
+
+	// Check for non-canonical encodings (p + k, 2p + k, etc.) by comparing to
+	// the encoding of -1 mod p, so p - 1, the highest canonical encoding.
+	var minusOneEncoding = new(P384Element).Sub(
+		new(P384Element), new(P384Element).One()).Bytes()
 	for i := range v {
-		if v[i] < p384MinusOneEncoding[i] {
+		if v[i] < minusOneEncoding[i] {
 			break
 		}
-		if v[i] > p384MinusOneEncoding[i] {
+		if v[i] > minusOneEncoding[i] {
 			return nil, errors.New("invalid P384Element encoding")
 		}
 	}
+
 	var in [p384ElementLen]byte
 	copy(in[:], v)
 	p384InvertEndianness(in[:])
diff --git a/src/crypto/internal/nistec/fiat/p384_invert.go b/src/crypto/internal/nistec/fiat/p384_invert.go
index 24169e9..31591ac 100644
--- a/src/crypto/internal/nistec/fiat/p384_invert.go
+++ b/src/crypto/internal/nistec/fiat/p384_invert.go
@@ -12,7 +12,7 @@
 func (e *P384Element) Invert(x *P384Element) *P384Element {
 	// Inversion is implemented as exponentiation with exponent p − 2.
 	// The sequence of 15 multiplications and 383 squarings is derived from the
-	// following addition chain generated with github.com/mmcloughlin/addchain v0.3.0.
+	// following addition chain generated with github.com/mmcloughlin/addchain v0.4.0.
 	//
 	//	_10     = 2*1
 	//	_11     = 1 + _10
diff --git a/src/crypto/internal/nistec/fiat/p521.go b/src/crypto/internal/nistec/fiat/p521.go
index 3d12117..43ac7d0 100644
--- a/src/crypto/internal/nistec/fiat/p521.go
+++ b/src/crypto/internal/nistec/fiat/p521.go
@@ -37,12 +37,11 @@
 	return subtle.ConstantTimeCompare(eBytes, tBytes)
 }
 
-var p521ZeroEncoding = new(P521Element).Bytes()
-
 // IsZero returns 1 if e == 0, and zero otherwise.
 func (e *P521Element) IsZero() int {
+	zero := make([]byte, p521ElementLen)
 	eBytes := e.Bytes()
-	return subtle.ConstantTimeCompare(eBytes, p521ZeroEncoding)
+	return subtle.ConstantTimeCompare(eBytes, zero)
 }
 
 // Set sets e = t, and returns e.
@@ -67,12 +66,6 @@
 	return out[:]
 }
 
-// p521MinusOneEncoding is the encoding of -1 mod p, so p - 1, the
-// highest canonical encoding. It is used by SetBytes to check for non-canonical
-// encodings such as p + k, 2p + k, etc.
-var p521MinusOneEncoding = new(P521Element).Sub(
-	new(P521Element), new(P521Element).One()).Bytes()
-
 // SetBytes sets e = v, where v is a big-endian 66-byte encoding, and returns e.
 // If v is not 66 bytes or it encodes a value higher than 2^521 - 1,
 // SetBytes returns nil and an error, and e is unchanged.
@@ -80,14 +73,20 @@
 	if len(v) != p521ElementLen {
 		return nil, errors.New("invalid P521Element encoding")
 	}
+
+	// Check for non-canonical encodings (p + k, 2p + k, etc.) by comparing to
+	// the encoding of -1 mod p, so p - 1, the highest canonical encoding.
+	var minusOneEncoding = new(P521Element).Sub(
+		new(P521Element), new(P521Element).One()).Bytes()
 	for i := range v {
-		if v[i] < p521MinusOneEncoding[i] {
+		if v[i] < minusOneEncoding[i] {
 			break
 		}
-		if v[i] > p521MinusOneEncoding[i] {
+		if v[i] > minusOneEncoding[i] {
 			return nil, errors.New("invalid P521Element encoding")
 		}
 	}
+
 	var in [p521ElementLen]byte
 	copy(in[:], v)
 	p521InvertEndianness(in[:])
diff --git a/src/crypto/internal/nistec/fiat/p521_invert.go b/src/crypto/internal/nistec/fiat/p521_invert.go
index 407711a..16c53e1 100644
--- a/src/crypto/internal/nistec/fiat/p521_invert.go
+++ b/src/crypto/internal/nistec/fiat/p521_invert.go
@@ -12,7 +12,7 @@
 func (e *P521Element) Invert(x *P521Element) *P521Element {
 	// Inversion is implemented as exponentiation with exponent p − 2.
 	// The sequence of 13 multiplications and 520 squarings is derived from the
-	// following addition chain generated with github.com/mmcloughlin/addchain v0.3.0.
+	// following addition chain generated with github.com/mmcloughlin/addchain v0.4.0.
 	//
 	//	_10       = 2*1
 	//	_11       = 1 + _10
diff --git a/src/crypto/internal/nistec/generate.go b/src/crypto/internal/nistec/generate.go
index 9e82693..0204bc1 100644
--- a/src/crypto/internal/nistec/generate.go
+++ b/src/crypto/internal/nistec/generate.go
@@ -73,7 +73,8 @@
 		p := strings.ToLower(c.P)
 		elementLen := (c.Params.BitSize + 7) / 8
 		B := fmt.Sprintf("%#v", c.Params.B.FillBytes(make([]byte, elementLen)))
-		G := fmt.Sprintf("%#v", elliptic.Marshal(c.Params, c.Params.Gx, c.Params.Gy))
+		Gx := fmt.Sprintf("%#v", c.Params.Gx.FillBytes(make([]byte, elementLen)))
+		Gy := fmt.Sprintf("%#v", c.Params.Gy.FillBytes(make([]byte, elementLen)))
 
 		log.Printf("Generating %s.go...", p)
 		f, err := os.Create(p + ".go")
@@ -83,7 +84,7 @@
 		defer f.Close()
 		buf := &bytes.Buffer{}
 		if err := t.Execute(buf, map[string]interface{}{
-			"P": c.P, "p": p, "B": B, "G": G,
+			"P": c.P, "p": p, "B": B, "Gx": Gx, "Gy": Gy,
 			"Element": c.Element, "ElementLen": elementLen,
 			"BuildTags": c.BuildTags,
 		}); err != nil {
@@ -157,10 +158,6 @@
 	"sync"
 )
 
-var {{.p}}B, _ = new({{.Element}}).SetBytes({{.B}})
-
-var {{.p}}G, _ = New{{.P}}Point().SetBytes({{.G}})
-
 // {{.p}}ElementLength is the length of an element of the base or scalar field,
 // which have the same bytes length for all NIST P curves.
 const {{.p}}ElementLength = {{ .ElementLen }}
@@ -181,13 +178,12 @@
 	}
 }
 
-// New{{.P}}Generator returns a new {{.P}}Point set to the canonical generator.
-func New{{.P}}Generator() *{{.P}}Point {
-	return (&{{.P}}Point{
-		x: new({{.Element}}),
-		y: new({{.Element}}),
-		z: new({{.Element}}),
-	}).Set({{.p}}G)
+// SetGenerator sets p to the canonical generator and returns p.
+func (p *{{.P}}Point) SetGenerator() *{{.P}}Point {
+	p.x.SetBytes({{.Gx}})
+	p.y.SetBytes({{.Gy}})
+	p.z.One()
+	return p
 }
 
 // Set sets p = q and returns p.
@@ -256,6 +252,17 @@
 	}
 }
 
+
+var _{{.p}}B *{{.Element}}
+var _{{.p}}BOnce sync.Once
+
+func {{.p}}B() *{{.Element}} {
+	_{{.p}}BOnce.Do(func() {
+		_{{.p}}B, _ = new({{.Element}}).SetBytes({{.B}})
+	})
+	return _{{.p}}B
+}
+
 // {{.p}}Polynomial sets y2 to x³ - 3x + b, and returns y2.
 func {{.p}}Polynomial(y2, x *{{.Element}}) *{{.Element}} {
 	y2.Square(x)
@@ -263,9 +270,9 @@
 
 	threeX := new({{.Element}}).Add(x, x)
 	threeX.Add(threeX, x)
-
 	y2.Sub(y2, threeX)
-	return y2.Add(y2, {{.p}}B)
+
+	return y2.Add(y2, {{.p}}B())
 }
 
 func {{.p}}CheckOnCurve(x, y *{{.Element}}) error {
@@ -303,6 +310,26 @@
 	return buf
 }
 
+// BytesX returns the encoding of the x-coordinate of p, as specified in SEC 1,
+// Version 2.0, Section 2.3.5, or an error if p is the point at infinity.
+func (p *{{.P}}Point) BytesX() ([]byte, error) {
+	// This function is outlined to make the allocations inline in the caller
+	// rather than happen on the heap.
+	var out [{{.p}}ElementLength]byte
+	return p.bytesX(&out)
+}
+
+func (p *{{.P}}Point) bytesX(out *[{{.p}}ElementLength]byte) ([]byte, error) {
+	if p.z.IsZero() == 1 {
+		return nil, errors.New("{{.P}} point is the point at infinity")
+	}
+
+	zinv := new({{.Element}}).Invert(p.z)
+	x := new({{.Element}}).Mul(p.x, zinv)
+
+	return append(out[:0], x.Bytes()...), nil
+}
+
 // BytesCompressed returns the compressed or infinity encoding of p, as
 // specified in SEC 1, Version 2.0, Section 2.3.3. Note that the encoding of the
 // point at infinity is shorter than all other encodings.
@@ -353,13 +380,13 @@
 	x3.Mul(x3, y3)                            // X3 := X3 * Y3
 	y3.Add(t0, t2)                            // Y3 := t0 + t2
 	y3.Sub(x3, y3)                            // Y3 := X3 - Y3
-	z3 := new({{.Element}}).Mul({{.p}}B, t2)  // Z3 := b * t2
+	z3 := new({{.Element}}).Mul({{.p}}B(), t2)  // Z3 := b * t2
 	x3.Sub(y3, z3)                            // X3 := Y3 - Z3
 	z3.Add(x3, x3)                            // Z3 := X3 + X3
 	x3.Add(x3, z3)                            // X3 := X3 + Z3
 	z3.Sub(t1, x3)                            // Z3 := t1 - X3
 	x3.Add(t1, x3)                            // X3 := t1 + X3
-	y3.Mul({{.p}}B, y3)                       // Y3 := b * Y3
+	y3.Mul({{.p}}B(), y3)                     // Y3 := b * Y3
 	t1.Add(t2, t2)                            // t1 := t2 + t2
 	t2.Add(t1, t2)                            // t2 := t1 + t2
 	y3.Sub(y3, t2)                            // Y3 := Y3 - t2
@@ -397,7 +424,7 @@
 	t3.Add(t3, t3)                           // t3 := t3 + t3
 	z3 := new({{.Element}}).Mul(p.x, p.z)    // Z3 := X * Z
 	z3.Add(z3, z3)                           // Z3 := Z3 + Z3
-	y3 := new({{.Element}}).Mul({{.p}}B, t2) // Y3 := b * t2
+	y3 := new({{.Element}}).Mul({{.p}}B(), t2) // Y3 := b * t2
 	y3.Sub(y3, z3)                           // Y3 := Y3 - Z3
 	x3 := new({{.Element}}).Add(y3, y3)      // X3 := Y3 + Y3
 	y3.Add(x3, y3)                           // Y3 := X3 + Y3
@@ -407,7 +434,7 @@
 	x3.Mul(x3, t3)                           // X3 := X3 * t3
 	t3.Add(t2, t2)                           // t3 := t2 + t2
 	t2.Add(t2, t3)                           // t2 := t2 + t3
-	z3.Mul({{.p}}B, z3)                      // Z3 := b * Z3
+	z3.Mul({{.p}}B(), z3)                    // Z3 := b * Z3
 	z3.Sub(z3, t2)                           // Z3 := Z3 - t2
 	z3.Sub(z3, t0)                           // Z3 := Z3 - t0
 	t3.Add(z3, z3)                           // t3 := Z3 + Z3
@@ -511,7 +538,7 @@
 func (p *{{.P}}Point) generatorTable() *[{{.p}}ElementLength * 2]{{.p}}Table {
 	{{.p}}GeneratorTableOnce.Do(func() {
 		{{.p}}GeneratorTable = new([{{.p}}ElementLength * 2]{{.p}}Table)
-		base := New{{.P}}Generator()
+		base := New{{.P}}Point().SetGenerator()
 		for i := 0; i < {{.p}}ElementLength*2; i++ {
 			{{.p}}GeneratorTable[i][0] = New{{.P}}Point().Set(base)
 			for j := 1; j < 15; j++ {
diff --git a/src/crypto/internal/nistec/nistec_test.go b/src/crypto/internal/nistec/nistec_test.go
index 1903f19..9103608 100644
--- a/src/crypto/internal/nistec/nistec_test.go
+++ b/src/crypto/internal/nistec/nistec_test.go
@@ -8,20 +8,19 @@
 	"bytes"
 	"crypto/elliptic"
 	"crypto/internal/nistec"
+	"fmt"
+	"internal/testenv"
 	"math/big"
 	"math/rand"
-	"os"
-	"strings"
 	"testing"
 )
 
 func TestAllocations(t *testing.T) {
-	if strings.HasSuffix(os.Getenv("GO_BUILDER_NAME"), "-noopt") {
-		t.Skip("skipping allocations test without relevant optimizations")
-	}
+	testenv.SkipIfOptimizationOff(t)
+
 	t.Run("P224", func(t *testing.T) {
 		if allocs := testing.AllocsPerRun(100, func() {
-			p := nistec.NewP224Generator()
+			p := nistec.NewP224Point().SetGenerator()
 			scalar := make([]byte, 28)
 			rand.Read(scalar)
 			p.ScalarBaseMult(scalar)
@@ -40,7 +39,7 @@
 	})
 	t.Run("P256", func(t *testing.T) {
 		if allocs := testing.AllocsPerRun(100, func() {
-			p := nistec.NewP256Generator()
+			p := nistec.NewP256Point().SetGenerator()
 			scalar := make([]byte, 32)
 			rand.Read(scalar)
 			p.ScalarBaseMult(scalar)
@@ -59,7 +58,7 @@
 	})
 	t.Run("P384", func(t *testing.T) {
 		if allocs := testing.AllocsPerRun(100, func() {
-			p := nistec.NewP384Generator()
+			p := nistec.NewP384Point().SetGenerator()
 			scalar := make([]byte, 48)
 			rand.Read(scalar)
 			p.ScalarBaseMult(scalar)
@@ -78,7 +77,7 @@
 	})
 	t.Run("P521", func(t *testing.T) {
 		if allocs := testing.AllocsPerRun(100, func() {
-			p := nistec.NewP521Generator()
+			p := nistec.NewP521Point().SetGenerator()
 			scalar := make([]byte, 66)
 			rand.Read(scalar)
 			p.ScalarBaseMult(scalar)
@@ -99,6 +98,7 @@
 
 type nistPoint[T any] interface {
 	Bytes() []byte
+	SetGenerator() T
 	SetBytes([]byte) (T, error)
 	Add(T, T) T
 	Double(T) T
@@ -108,21 +108,21 @@
 
 func TestEquivalents(t *testing.T) {
 	t.Run("P224", func(t *testing.T) {
-		testEquivalents(t, nistec.NewP224Point, nistec.NewP224Generator, elliptic.P224())
+		testEquivalents(t, nistec.NewP224Point, elliptic.P224())
 	})
 	t.Run("P256", func(t *testing.T) {
-		testEquivalents(t, nistec.NewP256Point, nistec.NewP256Generator, elliptic.P256())
+		testEquivalents(t, nistec.NewP256Point, elliptic.P256())
 	})
 	t.Run("P384", func(t *testing.T) {
-		testEquivalents(t, nistec.NewP384Point, nistec.NewP384Generator, elliptic.P384())
+		testEquivalents(t, nistec.NewP384Point, elliptic.P384())
 	})
 	t.Run("P521", func(t *testing.T) {
-		testEquivalents(t, nistec.NewP521Point, nistec.NewP521Generator, elliptic.P521())
+		testEquivalents(t, nistec.NewP521Point, elliptic.P521())
 	})
 }
 
-func testEquivalents[P nistPoint[P]](t *testing.T, newPoint, newGenerator func() P, c elliptic.Curve) {
-	p := newGenerator()
+func testEquivalents[P nistPoint[P]](t *testing.T, newPoint func() P, c elliptic.Curve) {
+	p := newPoint().SetGenerator()
 
 	elementSize := (c.Params().BitSize + 7) / 8
 	two := make([]byte, elementSize)
@@ -166,18 +166,98 @@
 	}
 }
 
+func TestScalarMult(t *testing.T) {
+	t.Run("P224", func(t *testing.T) {
+		testScalarMult(t, nistec.NewP224Point, elliptic.P224())
+	})
+	t.Run("P256", func(t *testing.T) {
+		testScalarMult(t, nistec.NewP256Point, elliptic.P256())
+	})
+	t.Run("P384", func(t *testing.T) {
+		testScalarMult(t, nistec.NewP384Point, elliptic.P384())
+	})
+	t.Run("P521", func(t *testing.T) {
+		testScalarMult(t, nistec.NewP521Point, elliptic.P521())
+	})
+}
+
+func testScalarMult[P nistPoint[P]](t *testing.T, newPoint func() P, c elliptic.Curve) {
+	G := newPoint().SetGenerator()
+	checkScalar := func(t *testing.T, scalar []byte) {
+		p1, err := newPoint().ScalarBaseMult(scalar)
+		fatalIfErr(t, err)
+		p2, err := newPoint().ScalarMult(G, scalar)
+		fatalIfErr(t, err)
+		if !bytes.Equal(p1.Bytes(), p2.Bytes()) {
+			t.Error("[k]G != ScalarBaseMult(k)")
+		}
+
+		d := new(big.Int).SetBytes(scalar)
+		d.Sub(c.Params().N, d)
+		d.Mod(d, c.Params().N)
+		g1, err := newPoint().ScalarBaseMult(d.FillBytes(make([]byte, len(scalar))))
+		fatalIfErr(t, err)
+		g1.Add(g1, p1)
+		if !bytes.Equal(g1.Bytes(), newPoint().Bytes()) {
+			t.Error("[N - k]G + [k]G != ∞")
+		}
+	}
+
+	byteLen := len(c.Params().N.Bytes())
+	bitLen := c.Params().N.BitLen()
+	t.Run("0", func(t *testing.T) { checkScalar(t, make([]byte, byteLen)) })
+	t.Run("1", func(t *testing.T) {
+		checkScalar(t, big.NewInt(1).FillBytes(make([]byte, byteLen)))
+	})
+	t.Run("N-1", func(t *testing.T) {
+		checkScalar(t, new(big.Int).Sub(c.Params().N, big.NewInt(1)).Bytes())
+	})
+	t.Run("N", func(t *testing.T) { checkScalar(t, c.Params().N.Bytes()) })
+	t.Run("N+1", func(t *testing.T) {
+		checkScalar(t, new(big.Int).Add(c.Params().N, big.NewInt(1)).Bytes())
+	})
+	t.Run("all1s", func(t *testing.T) {
+		s := new(big.Int).Lsh(big.NewInt(1), uint(bitLen))
+		s.Sub(s, big.NewInt(1))
+		checkScalar(t, s.Bytes())
+	})
+	if testing.Short() {
+		return
+	}
+	for i := 0; i < bitLen; i++ {
+		t.Run(fmt.Sprintf("1<<%d", i), func(t *testing.T) {
+			s := new(big.Int).Lsh(big.NewInt(1), uint(i))
+			checkScalar(t, s.FillBytes(make([]byte, byteLen)))
+		})
+	}
+	// Test N+1...N+32 since they risk overlapping with precomputed table values
+	// in the final additions.
+	for i := int64(2); i <= 32; i++ {
+		t.Run(fmt.Sprintf("N+%d", i), func(t *testing.T) {
+			checkScalar(t, new(big.Int).Add(c.Params().N, big.NewInt(i)).Bytes())
+		})
+	}
+}
+
+func fatalIfErr(t *testing.T, err error) {
+	t.Helper()
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
 func BenchmarkScalarMult(b *testing.B) {
 	b.Run("P224", func(b *testing.B) {
-		benchmarkScalarMult(b, nistec.NewP224Generator(), 28)
+		benchmarkScalarMult(b, nistec.NewP224Point().SetGenerator(), 28)
 	})
 	b.Run("P256", func(b *testing.B) {
-		benchmarkScalarMult(b, nistec.NewP256Generator(), 32)
+		benchmarkScalarMult(b, nistec.NewP256Point().SetGenerator(), 32)
 	})
 	b.Run("P384", func(b *testing.B) {
-		benchmarkScalarMult(b, nistec.NewP384Generator(), 48)
+		benchmarkScalarMult(b, nistec.NewP384Point().SetGenerator(), 48)
 	})
 	b.Run("P521", func(b *testing.B) {
-		benchmarkScalarMult(b, nistec.NewP521Generator(), 66)
+		benchmarkScalarMult(b, nistec.NewP521Point().SetGenerator(), 66)
 	})
 }
 
@@ -193,16 +273,16 @@
 
 func BenchmarkScalarBaseMult(b *testing.B) {
 	b.Run("P224", func(b *testing.B) {
-		benchmarkScalarBaseMult(b, nistec.NewP224Generator(), 28)
+		benchmarkScalarBaseMult(b, nistec.NewP224Point().SetGenerator(), 28)
 	})
 	b.Run("P256", func(b *testing.B) {
-		benchmarkScalarBaseMult(b, nistec.NewP256Generator(), 32)
+		benchmarkScalarBaseMult(b, nistec.NewP256Point().SetGenerator(), 32)
 	})
 	b.Run("P384", func(b *testing.B) {
-		benchmarkScalarBaseMult(b, nistec.NewP384Generator(), 48)
+		benchmarkScalarBaseMult(b, nistec.NewP384Point().SetGenerator(), 48)
 	})
 	b.Run("P521", func(b *testing.B) {
-		benchmarkScalarBaseMult(b, nistec.NewP521Generator(), 66)
+		benchmarkScalarBaseMult(b, nistec.NewP521Point().SetGenerator(), 66)
 	})
 }
 
diff --git a/src/crypto/internal/nistec/p224.go b/src/crypto/internal/nistec/p224.go
index 8d236b3..faa971d 100644
--- a/src/crypto/internal/nistec/p224.go
+++ b/src/crypto/internal/nistec/p224.go
@@ -13,10 +13,6 @@
 	"sync"
 )
 
-var p224B, _ = new(fiat.P224Element).SetBytes([]byte{0xb4, 0x5, 0xa, 0x85, 0xc, 0x4, 0xb3, 0xab, 0xf5, 0x41, 0x32, 0x56, 0x50, 0x44, 0xb0, 0xb7, 0xd7, 0xbf, 0xd8, 0xba, 0x27, 0xb, 0x39, 0x43, 0x23, 0x55, 0xff, 0xb4})
-
-var p224G, _ = NewP224Point().SetBytes([]byte{0x4, 0xb7, 0xe, 0xc, 0xbd, 0x6b, 0xb4, 0xbf, 0x7f, 0x32, 0x13, 0x90, 0xb9, 0x4a, 0x3, 0xc1, 0xd3, 0x56, 0xc2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xd6, 0x11, 0x5c, 0x1d, 0x21, 0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6, 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x7, 0x47, 0x64, 0x44, 0xd5, 0x81, 0x99, 0x85, 0x0, 0x7e, 0x34})
-
 // p224ElementLength is the length of an element of the base or scalar field,
 // which have the same bytes length for all NIST P curves.
 const p224ElementLength = 28
@@ -37,13 +33,12 @@
 	}
 }
 
-// NewP224Generator returns a new P224Point set to the canonical generator.
-func NewP224Generator() *P224Point {
-	return (&P224Point{
-		x: new(fiat.P224Element),
-		y: new(fiat.P224Element),
-		z: new(fiat.P224Element),
-	}).Set(p224G)
+// SetGenerator sets p to the canonical generator and returns p.
+func (p *P224Point) SetGenerator() *P224Point {
+	p.x.SetBytes([]byte{0xb7, 0xe, 0xc, 0xbd, 0x6b, 0xb4, 0xbf, 0x7f, 0x32, 0x13, 0x90, 0xb9, 0x4a, 0x3, 0xc1, 0xd3, 0x56, 0xc2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xd6, 0x11, 0x5c, 0x1d, 0x21})
+	p.y.SetBytes([]byte{0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6, 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x7, 0x47, 0x64, 0x44, 0xd5, 0x81, 0x99, 0x85, 0x0, 0x7e, 0x34})
+	p.z.One()
+	return p
 }
 
 // Set sets p = q and returns p.
@@ -112,6 +107,16 @@
 	}
 }
 
+var _p224B *fiat.P224Element
+var _p224BOnce sync.Once
+
+func p224B() *fiat.P224Element {
+	_p224BOnce.Do(func() {
+		_p224B, _ = new(fiat.P224Element).SetBytes([]byte{0xb4, 0x5, 0xa, 0x85, 0xc, 0x4, 0xb3, 0xab, 0xf5, 0x41, 0x32, 0x56, 0x50, 0x44, 0xb0, 0xb7, 0xd7, 0xbf, 0xd8, 0xba, 0x27, 0xb, 0x39, 0x43, 0x23, 0x55, 0xff, 0xb4})
+	})
+	return _p224B
+}
+
 // p224Polynomial sets y2 to x³ - 3x + b, and returns y2.
 func p224Polynomial(y2, x *fiat.P224Element) *fiat.P224Element {
 	y2.Square(x)
@@ -119,9 +124,9 @@
 
 	threeX := new(fiat.P224Element).Add(x, x)
 	threeX.Add(threeX, x)
-
 	y2.Sub(y2, threeX)
-	return y2.Add(y2, p224B)
+
+	return y2.Add(y2, p224B())
 }
 
 func p224CheckOnCurve(x, y *fiat.P224Element) error {
@@ -159,6 +164,26 @@
 	return buf
 }
 
+// BytesX returns the encoding of the x-coordinate of p, as specified in SEC 1,
+// Version 2.0, Section 2.3.5, or an error if p is the point at infinity.
+func (p *P224Point) BytesX() ([]byte, error) {
+	// This function is outlined to make the allocations inline in the caller
+	// rather than happen on the heap.
+	var out [p224ElementLength]byte
+	return p.bytesX(&out)
+}
+
+func (p *P224Point) bytesX(out *[p224ElementLength]byte) ([]byte, error) {
+	if p.z.IsZero() == 1 {
+		return nil, errors.New("P224 point is the point at infinity")
+	}
+
+	zinv := new(fiat.P224Element).Invert(p.z)
+	x := new(fiat.P224Element).Mul(p.x, zinv)
+
+	return append(out[:0], x.Bytes()...), nil
+}
+
 // BytesCompressed returns the compressed or infinity encoding of p, as
 // specified in SEC 1, Version 2.0, Section 2.3.3. Note that the encoding of the
 // point at infinity is shorter than all other encodings.
@@ -191,49 +216,49 @@
 	// Complete addition formula for a = -3 from "Complete addition formulas for
 	// prime order elliptic curves" (https://eprint.iacr.org/2015/1060), §A.2.
 
-	t0 := new(fiat.P224Element).Mul(p1.x, p2.x) // t0 := X1 * X2
-	t1 := new(fiat.P224Element).Mul(p1.y, p2.y) // t1 := Y1 * Y2
-	t2 := new(fiat.P224Element).Mul(p1.z, p2.z) // t2 := Z1 * Z2
-	t3 := new(fiat.P224Element).Add(p1.x, p1.y) // t3 := X1 + Y1
-	t4 := new(fiat.P224Element).Add(p2.x, p2.y) // t4 := X2 + Y2
-	t3.Mul(t3, t4)                              // t3 := t3 * t4
-	t4.Add(t0, t1)                              // t4 := t0 + t1
-	t3.Sub(t3, t4)                              // t3 := t3 - t4
-	t4.Add(p1.y, p1.z)                          // t4 := Y1 + Z1
-	x3 := new(fiat.P224Element).Add(p2.y, p2.z) // X3 := Y2 + Z2
-	t4.Mul(t4, x3)                              // t4 := t4 * X3
-	x3.Add(t1, t2)                              // X3 := t1 + t2
-	t4.Sub(t4, x3)                              // t4 := t4 - X3
-	x3.Add(p1.x, p1.z)                          // X3 := X1 + Z1
-	y3 := new(fiat.P224Element).Add(p2.x, p2.z) // Y3 := X2 + Z2
-	x3.Mul(x3, y3)                              // X3 := X3 * Y3
-	y3.Add(t0, t2)                              // Y3 := t0 + t2
-	y3.Sub(x3, y3)                              // Y3 := X3 - Y3
-	z3 := new(fiat.P224Element).Mul(p224B, t2)  // Z3 := b * t2
-	x3.Sub(y3, z3)                              // X3 := Y3 - Z3
-	z3.Add(x3, x3)                              // Z3 := X3 + X3
-	x3.Add(x3, z3)                              // X3 := X3 + Z3
-	z3.Sub(t1, x3)                              // Z3 := t1 - X3
-	x3.Add(t1, x3)                              // X3 := t1 + X3
-	y3.Mul(p224B, y3)                           // Y3 := b * Y3
-	t1.Add(t2, t2)                              // t1 := t2 + t2
-	t2.Add(t1, t2)                              // t2 := t1 + t2
-	y3.Sub(y3, t2)                              // Y3 := Y3 - t2
-	y3.Sub(y3, t0)                              // Y3 := Y3 - t0
-	t1.Add(y3, y3)                              // t1 := Y3 + Y3
-	y3.Add(t1, y3)                              // Y3 := t1 + Y3
-	t1.Add(t0, t0)                              // t1 := t0 + t0
-	t0.Add(t1, t0)                              // t0 := t1 + t0
-	t0.Sub(t0, t2)                              // t0 := t0 - t2
-	t1.Mul(t4, y3)                              // t1 := t4 * Y3
-	t2.Mul(t0, y3)                              // t2 := t0 * Y3
-	y3.Mul(x3, z3)                              // Y3 := X3 * Z3
-	y3.Add(y3, t2)                              // Y3 := Y3 + t2
-	x3.Mul(t3, x3)                              // X3 := t3 * X3
-	x3.Sub(x3, t1)                              // X3 := X3 - t1
-	z3.Mul(t4, z3)                              // Z3 := t4 * Z3
-	t1.Mul(t3, t0)                              // t1 := t3 * t0
-	z3.Add(z3, t1)                              // Z3 := Z3 + t1
+	t0 := new(fiat.P224Element).Mul(p1.x, p2.x)  // t0 := X1 * X2
+	t1 := new(fiat.P224Element).Mul(p1.y, p2.y)  // t1 := Y1 * Y2
+	t2 := new(fiat.P224Element).Mul(p1.z, p2.z)  // t2 := Z1 * Z2
+	t3 := new(fiat.P224Element).Add(p1.x, p1.y)  // t3 := X1 + Y1
+	t4 := new(fiat.P224Element).Add(p2.x, p2.y)  // t4 := X2 + Y2
+	t3.Mul(t3, t4)                               // t3 := t3 * t4
+	t4.Add(t0, t1)                               // t4 := t0 + t1
+	t3.Sub(t3, t4)                               // t3 := t3 - t4
+	t4.Add(p1.y, p1.z)                           // t4 := Y1 + Z1
+	x3 := new(fiat.P224Element).Add(p2.y, p2.z)  // X3 := Y2 + Z2
+	t4.Mul(t4, x3)                               // t4 := t4 * X3
+	x3.Add(t1, t2)                               // X3 := t1 + t2
+	t4.Sub(t4, x3)                               // t4 := t4 - X3
+	x3.Add(p1.x, p1.z)                           // X3 := X1 + Z1
+	y3 := new(fiat.P224Element).Add(p2.x, p2.z)  // Y3 := X2 + Z2
+	x3.Mul(x3, y3)                               // X3 := X3 * Y3
+	y3.Add(t0, t2)                               // Y3 := t0 + t2
+	y3.Sub(x3, y3)                               // Y3 := X3 - Y3
+	z3 := new(fiat.P224Element).Mul(p224B(), t2) // Z3 := b * t2
+	x3.Sub(y3, z3)                               // X3 := Y3 - Z3
+	z3.Add(x3, x3)                               // Z3 := X3 + X3
+	x3.Add(x3, z3)                               // X3 := X3 + Z3
+	z3.Sub(t1, x3)                               // Z3 := t1 - X3
+	x3.Add(t1, x3)                               // X3 := t1 + X3
+	y3.Mul(p224B(), y3)                          // Y3 := b * Y3
+	t1.Add(t2, t2)                               // t1 := t2 + t2
+	t2.Add(t1, t2)                               // t2 := t1 + t2
+	y3.Sub(y3, t2)                               // Y3 := Y3 - t2
+	y3.Sub(y3, t0)                               // Y3 := Y3 - t0
+	t1.Add(y3, y3)                               // t1 := Y3 + Y3
+	y3.Add(t1, y3)                               // Y3 := t1 + Y3
+	t1.Add(t0, t0)                               // t1 := t0 + t0
+	t0.Add(t1, t0)                               // t0 := t1 + t0
+	t0.Sub(t0, t2)                               // t0 := t0 - t2
+	t1.Mul(t4, y3)                               // t1 := t4 * Y3
+	t2.Mul(t0, y3)                               // t2 := t0 * Y3
+	y3.Mul(x3, z3)                               // Y3 := X3 * Z3
+	y3.Add(y3, t2)                               // Y3 := Y3 + t2
+	x3.Mul(t3, x3)                               // X3 := t3 * X3
+	x3.Sub(x3, t1)                               // X3 := X3 - t1
+	z3.Mul(t4, z3)                               // Z3 := t4 * Z3
+	t1.Mul(t3, t0)                               // t1 := t3 * t0
+	z3.Add(z3, t1)                               // Z3 := Z3 + t1
 
 	q.x.Set(x3)
 	q.y.Set(y3)
@@ -246,40 +271,40 @@
 	// Complete addition formula for a = -3 from "Complete addition formulas for
 	// prime order elliptic curves" (https://eprint.iacr.org/2015/1060), §A.2.
 
-	t0 := new(fiat.P224Element).Square(p.x)    // t0 := X ^ 2
-	t1 := new(fiat.P224Element).Square(p.y)    // t1 := Y ^ 2
-	t2 := new(fiat.P224Element).Square(p.z)    // t2 := Z ^ 2
-	t3 := new(fiat.P224Element).Mul(p.x, p.y)  // t3 := X * Y
-	t3.Add(t3, t3)                             // t3 := t3 + t3
-	z3 := new(fiat.P224Element).Mul(p.x, p.z)  // Z3 := X * Z
-	z3.Add(z3, z3)                             // Z3 := Z3 + Z3
-	y3 := new(fiat.P224Element).Mul(p224B, t2) // Y3 := b * t2
-	y3.Sub(y3, z3)                             // Y3 := Y3 - Z3
-	x3 := new(fiat.P224Element).Add(y3, y3)    // X3 := Y3 + Y3
-	y3.Add(x3, y3)                             // Y3 := X3 + Y3
-	x3.Sub(t1, y3)                             // X3 := t1 - Y3
-	y3.Add(t1, y3)                             // Y3 := t1 + Y3
-	y3.Mul(x3, y3)                             // Y3 := X3 * Y3
-	x3.Mul(x3, t3)                             // X3 := X3 * t3
-	t3.Add(t2, t2)                             // t3 := t2 + t2
-	t2.Add(t2, t3)                             // t2 := t2 + t3
-	z3.Mul(p224B, z3)                          // Z3 := b * Z3
-	z3.Sub(z3, t2)                             // Z3 := Z3 - t2
-	z3.Sub(z3, t0)                             // Z3 := Z3 - t0
-	t3.Add(z3, z3)                             // t3 := Z3 + Z3
-	z3.Add(z3, t3)                             // Z3 := Z3 + t3
-	t3.Add(t0, t0)                             // t3 := t0 + t0
-	t0.Add(t3, t0)                             // t0 := t3 + t0
-	t0.Sub(t0, t2)                             // t0 := t0 - t2
-	t0.Mul(t0, z3)                             // t0 := t0 * Z3
-	y3.Add(y3, t0)                             // Y3 := Y3 + t0
-	t0.Mul(p.y, p.z)                           // t0 := Y * Z
-	t0.Add(t0, t0)                             // t0 := t0 + t0
-	z3.Mul(t0, z3)                             // Z3 := t0 * Z3
-	x3.Sub(x3, z3)                             // X3 := X3 - Z3
-	z3.Mul(t0, t1)                             // Z3 := t0 * t1
-	z3.Add(z3, z3)                             // Z3 := Z3 + Z3
-	z3.Add(z3, z3)                             // Z3 := Z3 + Z3
+	t0 := new(fiat.P224Element).Square(p.x)      // t0 := X ^ 2
+	t1 := new(fiat.P224Element).Square(p.y)      // t1 := Y ^ 2
+	t2 := new(fiat.P224Element).Square(p.z)      // t2 := Z ^ 2
+	t3 := new(fiat.P224Element).Mul(p.x, p.y)    // t3 := X * Y
+	t3.Add(t3, t3)                               // t3 := t3 + t3
+	z3 := new(fiat.P224Element).Mul(p.x, p.z)    // Z3 := X * Z
+	z3.Add(z3, z3)                               // Z3 := Z3 + Z3
+	y3 := new(fiat.P224Element).Mul(p224B(), t2) // Y3 := b * t2
+	y3.Sub(y3, z3)                               // Y3 := Y3 - Z3
+	x3 := new(fiat.P224Element).Add(y3, y3)      // X3 := Y3 + Y3
+	y3.Add(x3, y3)                               // Y3 := X3 + Y3
+	x3.Sub(t1, y3)                               // X3 := t1 - Y3
+	y3.Add(t1, y3)                               // Y3 := t1 + Y3
+	y3.Mul(x3, y3)                               // Y3 := X3 * Y3
+	x3.Mul(x3, t3)                               // X3 := X3 * t3
+	t3.Add(t2, t2)                               // t3 := t2 + t2
+	t2.Add(t2, t3)                               // t2 := t2 + t3
+	z3.Mul(p224B(), z3)                          // Z3 := b * Z3
+	z3.Sub(z3, t2)                               // Z3 := Z3 - t2
+	z3.Sub(z3, t0)                               // Z3 := Z3 - t0
+	t3.Add(z3, z3)                               // t3 := Z3 + Z3
+	z3.Add(z3, t3)                               // Z3 := Z3 + t3
+	t3.Add(t0, t0)                               // t3 := t0 + t0
+	t0.Add(t3, t0)                               // t0 := t3 + t0
+	t0.Sub(t0, t2)                               // t0 := t0 - t2
+	t0.Mul(t0, z3)                               // t0 := t0 * Z3
+	y3.Add(y3, t0)                               // Y3 := Y3 + t0
+	t0.Mul(p.y, p.z)                             // t0 := Y * Z
+	t0.Add(t0, t0)                               // t0 := t0 + t0
+	z3.Mul(t0, z3)                               // Z3 := t0 * Z3
+	x3.Sub(x3, z3)                               // X3 := X3 - Z3
+	z3.Mul(t0, t1)                               // Z3 := t0 * t1
+	z3.Add(z3, z3)                               // Z3 := Z3 + Z3
+	z3.Add(z3, z3)                               // Z3 := Z3 + Z3
 
 	q.x.Set(x3)
 	q.y.Set(y3)
@@ -367,7 +392,7 @@
 func (p *P224Point) generatorTable() *[p224ElementLength * 2]p224Table {
 	p224GeneratorTableOnce.Do(func() {
 		p224GeneratorTable = new([p224ElementLength * 2]p224Table)
-		base := NewP224Generator()
+		base := NewP224Point().SetGenerator()
 		for i := 0; i < p224ElementLength*2; i++ {
 			p224GeneratorTable[i][0] = NewP224Point().Set(base)
 			for j := 1; j < 15; j++ {
diff --git a/src/crypto/internal/nistec/p224_sqrt.go b/src/crypto/internal/nistec/p224_sqrt.go
index 9a35cea..0c77579 100644
--- a/src/crypto/internal/nistec/p224_sqrt.go
+++ b/src/crypto/internal/nistec/p224_sqrt.go
@@ -12,9 +12,6 @@
 var p224GG *[96]fiat.P224Element
 var p224GGOnce sync.Once
 
-var p224MinusOne = new(fiat.P224Element).Sub(
-	new(fiat.P224Element), new(fiat.P224Element).One())
-
 // p224SqrtCandidate sets r to a square root candidate for x. r and x must not overlap.
 func p224SqrtCandidate(r, x *fiat.P224Element) {
 	// Since p = 1 mod 4, we can't use the exponentiation by (p + 1) / 4 like
@@ -120,6 +117,9 @@
 	//         v <- v*GG[n-i]
 	//         r <- r*GG[n-i-1]
 
+	var p224MinusOne = new(fiat.P224Element).Sub(
+		new(fiat.P224Element), new(fiat.P224Element).One())
+
 	for i := 96 - 1; i >= 1; i-- {
 		w := new(fiat.P224Element).Set(v)
 		for j := 0; j < i-1; j++ {
diff --git a/src/crypto/internal/nistec/p256.go b/src/crypto/internal/nistec/p256.go
index 353b428..3cfa5fb 100644
--- a/src/crypto/internal/nistec/p256.go
+++ b/src/crypto/internal/nistec/p256.go
@@ -15,10 +15,6 @@
 	"sync"
 )
 
-var p256B, _ = new(fiat.P256Element).SetBytes([]byte{0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7, 0xb3, 0xeb, 0xbd, 0x55, 0x76, 0x98, 0x86, 0xbc, 0x65, 0x1d, 0x6, 0xb0, 0xcc, 0x53, 0xb0, 0xf6, 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b})
-
-var p256G, _ = NewP256Point().SetBytes([]byte{0x4, 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x3, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0, 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96, 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0xf, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5})
-
 // p256ElementLength is the length of an element of the base or scalar field,
 // which have the same bytes length for all NIST P curves.
 const p256ElementLength = 32
@@ -39,13 +35,12 @@
 	}
 }
 
-// NewP256Generator returns a new P256Point set to the canonical generator.
-func NewP256Generator() *P256Point {
-	return (&P256Point{
-		x: new(fiat.P256Element),
-		y: new(fiat.P256Element),
-		z: new(fiat.P256Element),
-	}).Set(p256G)
+// SetGenerator sets p to the canonical generator and returns p.
+func (p *P256Point) SetGenerator() *P256Point {
+	p.x.SetBytes([]byte{0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x3, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0, 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96})
+	p.y.SetBytes([]byte{0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0xf, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5})
+	p.z.One()
+	return p
 }
 
 // Set sets p = q and returns p.
@@ -114,6 +109,16 @@
 	}
 }
 
+var _p256B *fiat.P256Element
+var _p256BOnce sync.Once
+
+func p256B() *fiat.P256Element {
+	_p256BOnce.Do(func() {
+		_p256B, _ = new(fiat.P256Element).SetBytes([]byte{0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7, 0xb3, 0xeb, 0xbd, 0x55, 0x76, 0x98, 0x86, 0xbc, 0x65, 0x1d, 0x6, 0xb0, 0xcc, 0x53, 0xb0, 0xf6, 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b})
+	})
+	return _p256B
+}
+
 // p256Polynomial sets y2 to x³ - 3x + b, and returns y2.
 func p256Polynomial(y2, x *fiat.P256Element) *fiat.P256Element {
 	y2.Square(x)
@@ -121,9 +126,9 @@
 
 	threeX := new(fiat.P256Element).Add(x, x)
 	threeX.Add(threeX, x)
-
 	y2.Sub(y2, threeX)
-	return y2.Add(y2, p256B)
+
+	return y2.Add(y2, p256B())
 }
 
 func p256CheckOnCurve(x, y *fiat.P256Element) error {
@@ -161,6 +166,26 @@
 	return buf
 }
 
+// BytesX returns the encoding of the x-coordinate of p, as specified in SEC 1,
+// Version 2.0, Section 2.3.5, or an error if p is the point at infinity.
+func (p *P256Point) BytesX() ([]byte, error) {
+	// This function is outlined to make the allocations inline in the caller
+	// rather than happen on the heap.
+	var out [p256ElementLength]byte
+	return p.bytesX(&out)
+}
+
+func (p *P256Point) bytesX(out *[p256ElementLength]byte) ([]byte, error) {
+	if p.z.IsZero() == 1 {
+		return nil, errors.New("P256 point is the point at infinity")
+	}
+
+	zinv := new(fiat.P256Element).Invert(p.z)
+	x := new(fiat.P256Element).Mul(p.x, zinv)
+
+	return append(out[:0], x.Bytes()...), nil
+}
+
 // BytesCompressed returns the compressed or infinity encoding of p, as
 // specified in SEC 1, Version 2.0, Section 2.3.3. Note that the encoding of the
 // point at infinity is shorter than all other encodings.
@@ -193,49 +218,49 @@
 	// Complete addition formula for a = -3 from "Complete addition formulas for
 	// prime order elliptic curves" (https://eprint.iacr.org/2015/1060), §A.2.
 
-	t0 := new(fiat.P256Element).Mul(p1.x, p2.x) // t0 := X1 * X2
-	t1 := new(fiat.P256Element).Mul(p1.y, p2.y) // t1 := Y1 * Y2
-	t2 := new(fiat.P256Element).Mul(p1.z, p2.z) // t2 := Z1 * Z2
-	t3 := new(fiat.P256Element).Add(p1.x, p1.y) // t3 := X1 + Y1
-	t4 := new(fiat.P256Element).Add(p2.x, p2.y) // t4 := X2 + Y2
-	t3.Mul(t3, t4)                              // t3 := t3 * t4
-	t4.Add(t0, t1)                              // t4 := t0 + t1
-	t3.Sub(t3, t4)                              // t3 := t3 - t4
-	t4.Add(p1.y, p1.z)                          // t4 := Y1 + Z1
-	x3 := new(fiat.P256Element).Add(p2.y, p2.z) // X3 := Y2 + Z2
-	t4.Mul(t4, x3)                              // t4 := t4 * X3
-	x3.Add(t1, t2)                              // X3 := t1 + t2
-	t4.Sub(t4, x3)                              // t4 := t4 - X3
-	x3.Add(p1.x, p1.z)                          // X3 := X1 + Z1
-	y3 := new(fiat.P256Element).Add(p2.x, p2.z) // Y3 := X2 + Z2
-	x3.Mul(x3, y3)                              // X3 := X3 * Y3
-	y3.Add(t0, t2)                              // Y3 := t0 + t2
-	y3.Sub(x3, y3)                              // Y3 := X3 - Y3
-	z3 := new(fiat.P256Element).Mul(p256B, t2)  // Z3 := b * t2
-	x3.Sub(y3, z3)                              // X3 := Y3 - Z3
-	z3.Add(x3, x3)                              // Z3 := X3 + X3
-	x3.Add(x3, z3)                              // X3 := X3 + Z3
-	z3.Sub(t1, x3)                              // Z3 := t1 - X3
-	x3.Add(t1, x3)                              // X3 := t1 + X3
-	y3.Mul(p256B, y3)                           // Y3 := b * Y3
-	t1.Add(t2, t2)                              // t1 := t2 + t2
-	t2.Add(t1, t2)                              // t2 := t1 + t2
-	y3.Sub(y3, t2)                              // Y3 := Y3 - t2
-	y3.Sub(y3, t0)                              // Y3 := Y3 - t0
-	t1.Add(y3, y3)                              // t1 := Y3 + Y3
-	y3.Add(t1, y3)                              // Y3 := t1 + Y3
-	t1.Add(t0, t0)                              // t1 := t0 + t0
-	t0.Add(t1, t0)                              // t0 := t1 + t0
-	t0.Sub(t0, t2)                              // t0 := t0 - t2
-	t1.Mul(t4, y3)                              // t1 := t4 * Y3
-	t2.Mul(t0, y3)                              // t2 := t0 * Y3
-	y3.Mul(x3, z3)                              // Y3 := X3 * Z3
-	y3.Add(y3, t2)                              // Y3 := Y3 + t2
-	x3.Mul(t3, x3)                              // X3 := t3 * X3
-	x3.Sub(x3, t1)                              // X3 := X3 - t1
-	z3.Mul(t4, z3)                              // Z3 := t4 * Z3
-	t1.Mul(t3, t0)                              // t1 := t3 * t0
-	z3.Add(z3, t1)                              // Z3 := Z3 + t1
+	t0 := new(fiat.P256Element).Mul(p1.x, p2.x)  // t0 := X1 * X2
+	t1 := new(fiat.P256Element).Mul(p1.y, p2.y)  // t1 := Y1 * Y2
+	t2 := new(fiat.P256Element).Mul(p1.z, p2.z)  // t2 := Z1 * Z2
+	t3 := new(fiat.P256Element).Add(p1.x, p1.y)  // t3 := X1 + Y1
+	t4 := new(fiat.P256Element).Add(p2.x, p2.y)  // t4 := X2 + Y2
+	t3.Mul(t3, t4)                               // t3 := t3 * t4
+	t4.Add(t0, t1)                               // t4 := t0 + t1
+	t3.Sub(t3, t4)                               // t3 := t3 - t4
+	t4.Add(p1.y, p1.z)                           // t4 := Y1 + Z1
+	x3 := new(fiat.P256Element).Add(p2.y, p2.z)  // X3 := Y2 + Z2
+	t4.Mul(t4, x3)                               // t4 := t4 * X3
+	x3.Add(t1, t2)                               // X3 := t1 + t2
+	t4.Sub(t4, x3)                               // t4 := t4 - X3
+	x3.Add(p1.x, p1.z)                           // X3 := X1 + Z1
+	y3 := new(fiat.P256Element).Add(p2.x, p2.z)  // Y3 := X2 + Z2
+	x3.Mul(x3, y3)                               // X3 := X3 * Y3
+	y3.Add(t0, t2)                               // Y3 := t0 + t2
+	y3.Sub(x3, y3)                               // Y3 := X3 - Y3
+	z3 := new(fiat.P256Element).Mul(p256B(), t2) // Z3 := b * t2
+	x3.Sub(y3, z3)                               // X3 := Y3 - Z3
+	z3.Add(x3, x3)                               // Z3 := X3 + X3
+	x3.Add(x3, z3)                               // X3 := X3 + Z3
+	z3.Sub(t1, x3)                               // Z3 := t1 - X3
+	x3.Add(t1, x3)                               // X3 := t1 + X3
+	y3.Mul(p256B(), y3)                          // Y3 := b * Y3
+	t1.Add(t2, t2)                               // t1 := t2 + t2
+	t2.Add(t1, t2)                               // t2 := t1 + t2
+	y3.Sub(y3, t2)                               // Y3 := Y3 - t2
+	y3.Sub(y3, t0)                               // Y3 := Y3 - t0
+	t1.Add(y3, y3)                               // t1 := Y3 + Y3
+	y3.Add(t1, y3)                               // Y3 := t1 + Y3
+	t1.Add(t0, t0)                               // t1 := t0 + t0
+	t0.Add(t1, t0)                               // t0 := t1 + t0
+	t0.Sub(t0, t2)                               // t0 := t0 - t2
+	t1.Mul(t4, y3)                               // t1 := t4 * Y3
+	t2.Mul(t0, y3)                               // t2 := t0 * Y3
+	y3.Mul(x3, z3)                               // Y3 := X3 * Z3
+	y3.Add(y3, t2)                               // Y3 := Y3 + t2
+	x3.Mul(t3, x3)                               // X3 := t3 * X3
+	x3.Sub(x3, t1)                               // X3 := X3 - t1
+	z3.Mul(t4, z3)                               // Z3 := t4 * Z3
+	t1.Mul(t3, t0)                               // t1 := t3 * t0
+	z3.Add(z3, t1)                               // Z3 := Z3 + t1
 
 	q.x.Set(x3)
 	q.y.Set(y3)
@@ -248,40 +273,40 @@
 	// Complete addition formula for a = -3 from "Complete addition formulas for
 	// prime order elliptic curves" (https://eprint.iacr.org/2015/1060), §A.2.
 
-	t0 := new(fiat.P256Element).Square(p.x)    // t0 := X ^ 2
-	t1 := new(fiat.P256Element).Square(p.y)    // t1 := Y ^ 2
-	t2 := new(fiat.P256Element).Square(p.z)    // t2 := Z ^ 2
-	t3 := new(fiat.P256Element).Mul(p.x, p.y)  // t3 := X * Y
-	t3.Add(t3, t3)                             // t3 := t3 + t3
-	z3 := new(fiat.P256Element).Mul(p.x, p.z)  // Z3 := X * Z
-	z3.Add(z3, z3)                             // Z3 := Z3 + Z3
-	y3 := new(fiat.P256Element).Mul(p256B, t2) // Y3 := b * t2
-	y3.Sub(y3, z3)                             // Y3 := Y3 - Z3
-	x3 := new(fiat.P256Element).Add(y3, y3)    // X3 := Y3 + Y3
-	y3.Add(x3, y3)                             // Y3 := X3 + Y3
-	x3.Sub(t1, y3)                             // X3 := t1 - Y3
-	y3.Add(t1, y3)                             // Y3 := t1 + Y3
-	y3.Mul(x3, y3)                             // Y3 := X3 * Y3
-	x3.Mul(x3, t3)                             // X3 := X3 * t3
-	t3.Add(t2, t2)                             // t3 := t2 + t2
-	t2.Add(t2, t3)                             // t2 := t2 + t3
-	z3.Mul(p256B, z3)                          // Z3 := b * Z3
-	z3.Sub(z3, t2)                             // Z3 := Z3 - t2
-	z3.Sub(z3, t0)                             // Z3 := Z3 - t0
-	t3.Add(z3, z3)                             // t3 := Z3 + Z3
-	z3.Add(z3, t3)                             // Z3 := Z3 + t3
-	t3.Add(t0, t0)                             // t3 := t0 + t0
-	t0.Add(t3, t0)                             // t0 := t3 + t0
-	t0.Sub(t0, t2)                             // t0 := t0 - t2
-	t0.Mul(t0, z3)                             // t0 := t0 * Z3
-	y3.Add(y3, t0)                             // Y3 := Y3 + t0
-	t0.Mul(p.y, p.z)                           // t0 := Y * Z
-	t0.Add(t0, t0)                             // t0 := t0 + t0
-	z3.Mul(t0, z3)                             // Z3 := t0 * Z3
-	x3.Sub(x3, z3)                             // X3 := X3 - Z3
-	z3.Mul(t0, t1)                             // Z3 := t0 * t1
-	z3.Add(z3, z3)                             // Z3 := Z3 + Z3
-	z3.Add(z3, z3)                             // Z3 := Z3 + Z3
+	t0 := new(fiat.P256Element).Square(p.x)      // t0 := X ^ 2
+	t1 := new(fiat.P256Element).Square(p.y)      // t1 := Y ^ 2
+	t2 := new(fiat.P256Element).Square(p.z)      // t2 := Z ^ 2
+	t3 := new(fiat.P256Element).Mul(p.x, p.y)    // t3 := X * Y
+	t3.Add(t3, t3)                               // t3 := t3 + t3
+	z3 := new(fiat.P256Element).Mul(p.x, p.z)    // Z3 := X * Z
+	z3.Add(z3, z3)                               // Z3 := Z3 + Z3
+	y3 := new(fiat.P256Element).Mul(p256B(), t2) // Y3 := b * t2
+	y3.Sub(y3, z3)                               // Y3 := Y3 - Z3
+	x3 := new(fiat.P256Element).Add(y3, y3)      // X3 := Y3 + Y3
+	y3.Add(x3, y3)                               // Y3 := X3 + Y3
+	x3.Sub(t1, y3)                               // X3 := t1 - Y3
+	y3.Add(t1, y3)                               // Y3 := t1 + Y3
+	y3.Mul(x3, y3)                               // Y3 := X3 * Y3
+	x3.Mul(x3, t3)                               // X3 := X3 * t3
+	t3.Add(t2, t2)                               // t3 := t2 + t2
+	t2.Add(t2, t3)                               // t2 := t2 + t3
+	z3.Mul(p256B(), z3)                          // Z3 := b * Z3
+	z3.Sub(z3, t2)                               // Z3 := Z3 - t2
+	z3.Sub(z3, t0)                               // Z3 := Z3 - t0
+	t3.Add(z3, z3)                               // t3 := Z3 + Z3
+	z3.Add(z3, t3)                               // Z3 := Z3 + t3
+	t3.Add(t0, t0)                               // t3 := t0 + t0
+	t0.Add(t3, t0)                               // t0 := t3 + t0
+	t0.Sub(t0, t2)                               // t0 := t0 - t2
+	t0.Mul(t0, z3)                               // t0 := t0 * Z3
+	y3.Add(y3, t0)                               // Y3 := Y3 + t0
+	t0.Mul(p.y, p.z)                             // t0 := Y * Z
+	t0.Add(t0, t0)                               // t0 := t0 + t0
+	z3.Mul(t0, z3)                               // Z3 := t0 * Z3
+	x3.Sub(x3, z3)                               // X3 := X3 - Z3
+	z3.Mul(t0, t1)                               // Z3 := t0 * t1
+	z3.Add(z3, z3)                               // Z3 := Z3 + Z3
+	z3.Add(z3, z3)                               // Z3 := Z3 + Z3
 
 	q.x.Set(x3)
 	q.y.Set(y3)
@@ -369,7 +394,7 @@
 func (p *P256Point) generatorTable() *[p256ElementLength * 2]p256Table {
 	p256GeneratorTableOnce.Do(func() {
 		p256GeneratorTable = new([p256ElementLength * 2]p256Table)
-		base := NewP256Generator()
+		base := NewP256Point().SetGenerator()
 		for i := 0; i < p256ElementLength*2; i++ {
 			p256GeneratorTable[i][0] = NewP256Point().Set(base)
 			for j := 1; j < 15; j++ {
diff --git a/src/crypto/internal/nistec/p256_asm.go b/src/crypto/internal/nistec/p256_asm.go
index bc443ba..99a22b8 100644
--- a/src/crypto/internal/nistec/p256_asm.go
+++ b/src/crypto/internal/nistec/p256_asm.go
@@ -52,15 +52,14 @@
 	}
 }
 
-// NewP256Generator returns a new P256Point set to the canonical generator.
-func NewP256Generator() *P256Point {
-	return &P256Point{
-		x: p256Element{0x79e730d418a9143c, 0x75ba95fc5fedb601,
-			0x79fb732b77622510, 0x18905f76a53755c6},
-		y: p256Element{0xddf25357ce95560a, 0x8b4ab8e4ba19e45c,
-			0xd2e88688dd21f325, 0x8571ff1825885d85},
-		z: p256One,
-	}
+// SetGenerator sets p to the canonical generator and returns p.
+func (p *P256Point) SetGenerator() *P256Point {
+	p.x = p256Element{0x79e730d418a9143c, 0x75ba95fc5fedb601,
+		0x79fb732b77622510, 0x18905f76a53755c6}
+	p.y = p256Element{0xddf25357ce95560a, 0x8b4ab8e4ba19e45c,
+		0xd2e88688dd21f325, 0x8571ff1825885d85}
+	p.z = p256One
+	return p
 }
 
 // Set sets p = q and returns p.
@@ -365,6 +364,21 @@
 // Montgomery domain (with R 2²⁵⁶) as four uint64 limbs in little-endian order.
 type p256OrdElement [4]uint64
 
+// p256OrdReduce ensures s is in the range [0, ord(G)-1].
+func p256OrdReduce(s *p256OrdElement) {
+	// Since 2 * ord(G) > 2²⁵⁶, we can just conditionally subtract ord(G),
+	// keeping the result if it doesn't underflow.
+	t0, b := bits.Sub64(s[0], 0xf3b9cac2fc632551, 0)
+	t1, b := bits.Sub64(s[1], 0xbce6faada7179e84, b)
+	t2, b := bits.Sub64(s[2], 0xffffffffffffffff, b)
+	t3, b := bits.Sub64(s[3], 0xffffffff00000000, b)
+	tMask := b - 1 // zero if subtraction underflowed
+	s[0] ^= (t0 ^ s[0]) & tMask
+	s[1] ^= (t1 ^ s[1]) & tMask
+	s[2] ^= (t2 ^ s[2]) & tMask
+	s[3] ^= (t3 ^ s[3]) & tMask
+}
+
 // Add sets q = p1 + p2, and returns q. The points may overlap.
 func (q *P256Point) Add(r1, r2 *P256Point) *P256Point {
 	var sum, double P256Point
@@ -394,6 +408,7 @@
 	}
 	scalarReversed := new(p256OrdElement)
 	p256OrdBigToLittle(scalarReversed, (*[32]byte)(scalar))
+	p256OrdReduce(scalarReversed)
 
 	r.p256BaseMult(scalarReversed)
 	return r, nil
@@ -408,6 +423,7 @@
 	}
 	scalarReversed := new(p256OrdElement)
 	p256OrdBigToLittle(scalarReversed, (*[32]byte)(scalar))
+	p256OrdReduce(scalarReversed)
 
 	r.Set(q).p256ScalarMult(scalarReversed)
 	return r, nil
@@ -479,6 +495,30 @@
 	p256FromMont(y, y)
 }
 
+// BytesX returns the encoding of the x-coordinate of p, as specified in SEC 1,
+// Version 2.0, Section 2.3.5, or an error if p is the point at infinity.
+func (p *P256Point) BytesX() ([]byte, error) {
+	// This function is outlined to make the allocations inline in the caller
+	// rather than happen on the heap.
+	var out [p256ElementLength]byte
+	return p.bytesX(&out)
+}
+
+func (p *P256Point) bytesX(out *[p256ElementLength]byte) ([]byte, error) {
+	if p.isInfinity() == 1 {
+		return nil, errors.New("P256 point is the point at infinity")
+	}
+
+	x := new(p256Element)
+	p256Inverse(x, &p.z)
+	p256Sqr(x, x, 1)
+	p256Mul(x, &p.x, x)
+	p256FromMont(x, x)
+	p256LittleToBig((*[32]byte)(out[:]), x)
+
+	return out[:], nil
+}
+
 // BytesCompressed returns the compressed or infinity encoding of p, as
 // specified in SEC 1, Version 2.0, Section 2.3.3. Note that the encoding of the
 // point at infinity is shorter than all other encodings.
diff --git a/src/crypto/internal/nistec/p256_asm_ordinv.go b/src/crypto/internal/nistec/p256_asm_ordinv.go
deleted file mode 100644
index 86a7a23..0000000
--- a/src/crypto/internal/nistec/p256_asm_ordinv.go
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build amd64 || arm64
-
-package nistec
-
-import "errors"
-
-// Montgomery multiplication modulo org(G). Sets res = in1 * in2 * R⁻¹.
-//
-//go:noescape
-func p256OrdMul(res, in1, in2 *p256OrdElement)
-
-// Montgomery square modulo org(G), repeated n times (n >= 1).
-//
-//go:noescape
-func p256OrdSqr(res, in *p256OrdElement, n int)
-
-func P256OrdInverse(k []byte) ([]byte, error) {
-	if len(k) != 32 {
-		return nil, errors.New("invalid scalar length")
-	}
-
-	x := new(p256OrdElement)
-	p256OrdBigToLittle(x, (*[32]byte)(k))
-
-	// Inversion is implemented as exponentiation by n - 2, per Fermat's little theorem.
-	//
-	// The sequence of 38 multiplications and 254 squarings is derived from
-	// https://briansmith.org/ecc-inversion-addition-chains-01#p256_scalar_inversion
-	_1 := new(p256OrdElement)
-	_11 := new(p256OrdElement)
-	_101 := new(p256OrdElement)
-	_111 := new(p256OrdElement)
-	_1111 := new(p256OrdElement)
-	_10101 := new(p256OrdElement)
-	_101111 := new(p256OrdElement)
-	t := new(p256OrdElement)
-
-	// This code operates in the Montgomery domain where R = 2²⁵⁶ mod n and n is
-	// the order of the scalar field. Elements in the Montgomery domain take the
-	// form a×R and p256OrdMul calculates (a × b × R⁻¹) mod n. RR is R in the
-	// domain, or R×R mod n, thus p256OrdMul(x, RR) gives x×R, i.e. converts x
-	// into the Montgomery domain.
-	RR := &p256OrdElement{0x83244c95be79eea2, 0x4699799c49bd6fa6,
-		0x2845b2392b6bec59, 0x66e12d94f3d95620}
-
-	p256OrdMul(_1, x, RR)      // _1
-	p256OrdSqr(x, _1, 1)       // _10
-	p256OrdMul(_11, x, _1)     // _11
-	p256OrdMul(_101, x, _11)   // _101
-	p256OrdMul(_111, x, _101)  // _111
-	p256OrdSqr(x, _101, 1)     // _1010
-	p256OrdMul(_1111, _101, x) // _1111
-
-	p256OrdSqr(t, x, 1)          // _10100
-	p256OrdMul(_10101, t, _1)    // _10101
-	p256OrdSqr(x, _10101, 1)     // _101010
-	p256OrdMul(_101111, _101, x) // _101111
-	p256OrdMul(x, _10101, x)     // _111111 = x6
-	p256OrdSqr(t, x, 2)          // _11111100
-	p256OrdMul(t, t, _11)        // _11111111 = x8
-	p256OrdSqr(x, t, 8)          // _ff00
-	p256OrdMul(x, x, t)          // _ffff = x16
-	p256OrdSqr(t, x, 16)         // _ffff0000
-	p256OrdMul(t, t, x)          // _ffffffff = x32
-
-	p256OrdSqr(x, t, 64)
-	p256OrdMul(x, x, t)
-	p256OrdSqr(x, x, 32)
-	p256OrdMul(x, x, t)
-
-	sqrs := []int{
-		6, 5, 4, 5, 5,
-		4, 3, 3, 5, 9,
-		6, 2, 5, 6, 5,
-		4, 5, 5, 3, 10,
-		2, 5, 5, 3, 7, 6}
-	muls := []*p256OrdElement{
-		_101111, _111, _11, _1111, _10101,
-		_101, _101, _101, _111, _101111,
-		_1111, _1, _1, _1111, _111,
-		_111, _111, _101, _11, _101111,
-		_11, _11, _11, _1, _10101, _1111}
-
-	for i, s := range sqrs {
-		p256OrdSqr(x, x, s)
-		p256OrdMul(x, x, muls[i])
-	}
-
-	// Montgomery multiplication by R⁻¹, or 1 outside the domain as R⁻¹×R = 1,
-	// converts a Montgomery value out of the domain.
-	one := &p256OrdElement{1}
-	p256OrdMul(x, x, one)
-
-	var xOut [32]byte
-	p256OrdLittleToBig(&xOut, x)
-	return xOut[:], nil
-}
diff --git a/src/crypto/internal/nistec/p256_asm_table_test.go b/src/crypto/internal/nistec/p256_asm_table_test.go
index 8707aeb..5b7246b 100644
--- a/src/crypto/internal/nistec/p256_asm_table_test.go
+++ b/src/crypto/internal/nistec/p256_asm_table_test.go
@@ -12,7 +12,7 @@
 )
 
 func TestP256PrecomputedTable(t *testing.T) {
-	base := NewP256Generator()
+	base := NewP256Point().SetGenerator()
 
 	for i := 0; i < 43; i++ {
 		t.Run(fmt.Sprintf("table[%d]", i), func(t *testing.T) {
diff --git a/src/crypto/internal/nistec/p256_ordinv.go b/src/crypto/internal/nistec/p256_ordinv.go
new file mode 100644
index 0000000..1274fb7
--- /dev/null
+++ b/src/crypto/internal/nistec/p256_ordinv.go
@@ -0,0 +1,102 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build amd64 || arm64
+
+package nistec
+
+import "errors"
+
+// Montgomery multiplication modulo org(G). Sets res = in1 * in2 * R⁻¹.
+//
+//go:noescape
+func p256OrdMul(res, in1, in2 *p256OrdElement)
+
+// Montgomery square modulo org(G), repeated n times (n >= 1).
+//
+//go:noescape
+func p256OrdSqr(res, in *p256OrdElement, n int)
+
+func P256OrdInverse(k []byte) ([]byte, error) {
+	if len(k) != 32 {
+		return nil, errors.New("invalid scalar length")
+	}
+
+	x := new(p256OrdElement)
+	p256OrdBigToLittle(x, (*[32]byte)(k))
+	p256OrdReduce(x)
+
+	// Inversion is implemented as exponentiation by n - 2, per Fermat's little theorem.
+	//
+	// The sequence of 38 multiplications and 254 squarings is derived from
+	// https://briansmith.org/ecc-inversion-addition-chains-01#p256_scalar_inversion
+	_1 := new(p256OrdElement)
+	_11 := new(p256OrdElement)
+	_101 := new(p256OrdElement)
+	_111 := new(p256OrdElement)
+	_1111 := new(p256OrdElement)
+	_10101 := new(p256OrdElement)
+	_101111 := new(p256OrdElement)
+	t := new(p256OrdElement)
+
+	// This code operates in the Montgomery domain where R = 2²⁵⁶ mod n and n is
+	// the order of the scalar field. Elements in the Montgomery domain take the
+	// form a×R and p256OrdMul calculates (a × b × R⁻¹) mod n. RR is R in the
+	// domain, or R×R mod n, thus p256OrdMul(x, RR) gives x×R, i.e. converts x
+	// into the Montgomery domain.
+	RR := &p256OrdElement{0x83244c95be79eea2, 0x4699799c49bd6fa6,
+		0x2845b2392b6bec59, 0x66e12d94f3d95620}
+
+	p256OrdMul(_1, x, RR)      // _1
+	p256OrdSqr(x, _1, 1)       // _10
+	p256OrdMul(_11, x, _1)     // _11
+	p256OrdMul(_101, x, _11)   // _101
+	p256OrdMul(_111, x, _101)  // _111
+	p256OrdSqr(x, _101, 1)     // _1010
+	p256OrdMul(_1111, _101, x) // _1111
+
+	p256OrdSqr(t, x, 1)          // _10100
+	p256OrdMul(_10101, t, _1)    // _10101
+	p256OrdSqr(x, _10101, 1)     // _101010
+	p256OrdMul(_101111, _101, x) // _101111
+	p256OrdMul(x, _10101, x)     // _111111 = x6
+	p256OrdSqr(t, x, 2)          // _11111100
+	p256OrdMul(t, t, _11)        // _11111111 = x8
+	p256OrdSqr(x, t, 8)          // _ff00
+	p256OrdMul(x, x, t)          // _ffff = x16
+	p256OrdSqr(t, x, 16)         // _ffff0000
+	p256OrdMul(t, t, x)          // _ffffffff = x32
+
+	p256OrdSqr(x, t, 64)
+	p256OrdMul(x, x, t)
+	p256OrdSqr(x, x, 32)
+	p256OrdMul(x, x, t)
+
+	sqrs := []int{
+		6, 5, 4, 5, 5,
+		4, 3, 3, 5, 9,
+		6, 2, 5, 6, 5,
+		4, 5, 5, 3, 10,
+		2, 5, 5, 3, 7, 6}
+	muls := []*p256OrdElement{
+		_101111, _111, _11, _1111, _10101,
+		_101, _101, _101, _111, _101111,
+		_1111, _1, _1, _1111, _111,
+		_111, _111, _101, _11, _101111,
+		_11, _11, _11, _1, _10101, _1111}
+
+	for i, s := range sqrs {
+		p256OrdSqr(x, x, s)
+		p256OrdMul(x, x, muls[i])
+	}
+
+	// Montgomery multiplication by R⁻¹, or 1 outside the domain as R⁻¹×R = 1,
+	// converts a Montgomery value out of the domain.
+	one := &p256OrdElement{1}
+	p256OrdMul(x, x, one)
+
+	var xOut [32]byte
+	p256OrdLittleToBig(&xOut, x)
+	return xOut[:], nil
+}
diff --git a/src/crypto/internal/nistec/p256_ordinv_noasm.go b/src/crypto/internal/nistec/p256_ordinv_noasm.go
new file mode 100644
index 0000000..213875c
--- /dev/null
+++ b/src/crypto/internal/nistec/p256_ordinv_noasm.go
@@ -0,0 +1,13 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !amd64 && !arm64
+
+package nistec
+
+import "errors"
+
+func P256OrdInverse(k []byte) ([]byte, error) {
+	return nil, errors.New("unimplemented")
+}
diff --git a/src/crypto/internal/nistec/p256_asm_ordinv_test.go b/src/crypto/internal/nistec/p256_ordinv_test.go
similarity index 100%
rename from src/crypto/internal/nistec/p256_asm_ordinv_test.go
rename to src/crypto/internal/nistec/p256_ordinv_test.go
diff --git a/src/crypto/internal/nistec/p384.go b/src/crypto/internal/nistec/p384.go
index 1a855cb..b452ec9 100644
--- a/src/crypto/internal/nistec/p384.go
+++ b/src/crypto/internal/nistec/p384.go
@@ -13,10 +13,6 @@
 	"sync"
 )
 
-var p384B, _ = new(fiat.P384Element).SetBytes([]byte{0xb3, 0x31, 0x2f, 0xa7, 0xe2, 0x3e, 0xe7, 0xe4, 0x98, 0x8e, 0x5, 0x6b, 0xe3, 0xf8, 0x2d, 0x19, 0x18, 0x1d, 0x9c, 0x6e, 0xfe, 0x81, 0x41, 0x12, 0x3, 0x14, 0x8, 0x8f, 0x50, 0x13, 0x87, 0x5a, 0xc6, 0x56, 0x39, 0x8d, 0x8a, 0x2e, 0xd1, 0x9d, 0x2a, 0x85, 0xc8, 0xed, 0xd3, 0xec, 0x2a, 0xef})
-
-var p384G, _ = NewP384Point().SetBytes([]byte{0x4, 0xaa, 0x87, 0xca, 0x22, 0xbe, 0x8b, 0x5, 0x37, 0x8e, 0xb1, 0xc7, 0x1e, 0xf3, 0x20, 0xad, 0x74, 0x6e, 0x1d, 0x3b, 0x62, 0x8b, 0xa7, 0x9b, 0x98, 0x59, 0xf7, 0x41, 0xe0, 0x82, 0x54, 0x2a, 0x38, 0x55, 0x2, 0xf2, 0x5d, 0xbf, 0x55, 0x29, 0x6c, 0x3a, 0x54, 0x5e, 0x38, 0x72, 0x76, 0xa, 0xb7, 0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e, 0x98, 0xbf, 0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c, 0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0, 0xa, 0x60, 0xb1, 0xce, 0x1d, 0x7e, 0x81, 0x9d, 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0xe, 0x5f})
-
 // p384ElementLength is the length of an element of the base or scalar field,
 // which have the same bytes length for all NIST P curves.
 const p384ElementLength = 48
@@ -37,13 +33,12 @@
 	}
 }
 
-// NewP384Generator returns a new P384Point set to the canonical generator.
-func NewP384Generator() *P384Point {
-	return (&P384Point{
-		x: new(fiat.P384Element),
-		y: new(fiat.P384Element),
-		z: new(fiat.P384Element),
-	}).Set(p384G)
+// SetGenerator sets p to the canonical generator and returns p.
+func (p *P384Point) SetGenerator() *P384Point {
+	p.x.SetBytes([]byte{0xaa, 0x87, 0xca, 0x22, 0xbe, 0x8b, 0x5, 0x37, 0x8e, 0xb1, 0xc7, 0x1e, 0xf3, 0x20, 0xad, 0x74, 0x6e, 0x1d, 0x3b, 0x62, 0x8b, 0xa7, 0x9b, 0x98, 0x59, 0xf7, 0x41, 0xe0, 0x82, 0x54, 0x2a, 0x38, 0x55, 0x2, 0xf2, 0x5d, 0xbf, 0x55, 0x29, 0x6c, 0x3a, 0x54, 0x5e, 0x38, 0x72, 0x76, 0xa, 0xb7})
+	p.y.SetBytes([]byte{0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e, 0x98, 0xbf, 0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c, 0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0, 0xa, 0x60, 0xb1, 0xce, 0x1d, 0x7e, 0x81, 0x9d, 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0xe, 0x5f})
+	p.z.One()
+	return p
 }
 
 // Set sets p = q and returns p.
@@ -112,6 +107,16 @@
 	}
 }
 
+var _p384B *fiat.P384Element
+var _p384BOnce sync.Once
+
+func p384B() *fiat.P384Element {
+	_p384BOnce.Do(func() {
+		_p384B, _ = new(fiat.P384Element).SetBytes([]byte{0xb3, 0x31, 0x2f, 0xa7, 0xe2, 0x3e, 0xe7, 0xe4, 0x98, 0x8e, 0x5, 0x6b, 0xe3, 0xf8, 0x2d, 0x19, 0x18, 0x1d, 0x9c, 0x6e, 0xfe, 0x81, 0x41, 0x12, 0x3, 0x14, 0x8, 0x8f, 0x50, 0x13, 0x87, 0x5a, 0xc6, 0x56, 0x39, 0x8d, 0x8a, 0x2e, 0xd1, 0x9d, 0x2a, 0x85, 0xc8, 0xed, 0xd3, 0xec, 0x2a, 0xef})
+	})
+	return _p384B
+}
+
 // p384Polynomial sets y2 to x³ - 3x + b, and returns y2.
 func p384Polynomial(y2, x *fiat.P384Element) *fiat.P384Element {
 	y2.Square(x)
@@ -119,9 +124,9 @@
 
 	threeX := new(fiat.P384Element).Add(x, x)
 	threeX.Add(threeX, x)
-
 	y2.Sub(y2, threeX)
-	return y2.Add(y2, p384B)
+
+	return y2.Add(y2, p384B())
 }
 
 func p384CheckOnCurve(x, y *fiat.P384Element) error {
@@ -159,6 +164,26 @@
 	return buf
 }
 
+// BytesX returns the encoding of the x-coordinate of p, as specified in SEC 1,
+// Version 2.0, Section 2.3.5, or an error if p is the point at infinity.
+func (p *P384Point) BytesX() ([]byte, error) {
+	// This function is outlined to make the allocations inline in the caller
+	// rather than happen on the heap.
+	var out [p384ElementLength]byte
+	return p.bytesX(&out)
+}
+
+func (p *P384Point) bytesX(out *[p384ElementLength]byte) ([]byte, error) {
+	if p.z.IsZero() == 1 {
+		return nil, errors.New("P384 point is the point at infinity")
+	}
+
+	zinv := new(fiat.P384Element).Invert(p.z)
+	x := new(fiat.P384Element).Mul(p.x, zinv)
+
+	return append(out[:0], x.Bytes()...), nil
+}
+
 // BytesCompressed returns the compressed or infinity encoding of p, as
 // specified in SEC 1, Version 2.0, Section 2.3.3. Note that the encoding of the
 // point at infinity is shorter than all other encodings.
@@ -191,49 +216,49 @@
 	// Complete addition formula for a = -3 from "Complete addition formulas for
 	// prime order elliptic curves" (https://eprint.iacr.org/2015/1060), §A.2.
 
-	t0 := new(fiat.P384Element).Mul(p1.x, p2.x) // t0 := X1 * X2
-	t1 := new(fiat.P384Element).Mul(p1.y, p2.y) // t1 := Y1 * Y2
-	t2 := new(fiat.P384Element).Mul(p1.z, p2.z) // t2 := Z1 * Z2
-	t3 := new(fiat.P384Element).Add(p1.x, p1.y) // t3 := X1 + Y1
-	t4 := new(fiat.P384Element).Add(p2.x, p2.y) // t4 := X2 + Y2
-	t3.Mul(t3, t4)                              // t3 := t3 * t4
-	t4.Add(t0, t1)                              // t4 := t0 + t1
-	t3.Sub(t3, t4)                              // t3 := t3 - t4
-	t4.Add(p1.y, p1.z)                          // t4 := Y1 + Z1
-	x3 := new(fiat.P384Element).Add(p2.y, p2.z) // X3 := Y2 + Z2
-	t4.Mul(t4, x3)                              // t4 := t4 * X3
-	x3.Add(t1, t2)                              // X3 := t1 + t2
-	t4.Sub(t4, x3)                              // t4 := t4 - X3
-	x3.Add(p1.x, p1.z)                          // X3 := X1 + Z1
-	y3 := new(fiat.P384Element).Add(p2.x, p2.z) // Y3 := X2 + Z2
-	x3.Mul(x3, y3)                              // X3 := X3 * Y3
-	y3.Add(t0, t2)                              // Y3 := t0 + t2
-	y3.Sub(x3, y3)                              // Y3 := X3 - Y3
-	z3 := new(fiat.P384Element).Mul(p384B, t2)  // Z3 := b * t2
-	x3.Sub(y3, z3)                              // X3 := Y3 - Z3
-	z3.Add(x3, x3)                              // Z3 := X3 + X3
-	x3.Add(x3, z3)                              // X3 := X3 + Z3
-	z3.Sub(t1, x3)                              // Z3 := t1 - X3
-	x3.Add(t1, x3)                              // X3 := t1 + X3
-	y3.Mul(p384B, y3)                           // Y3 := b * Y3
-	t1.Add(t2, t2)                              // t1 := t2 + t2
-	t2.Add(t1, t2)                              // t2 := t1 + t2
-	y3.Sub(y3, t2)                              // Y3 := Y3 - t2
-	y3.Sub(y3, t0)                              // Y3 := Y3 - t0
-	t1.Add(y3, y3)                              // t1 := Y3 + Y3
-	y3.Add(t1, y3)                              // Y3 := t1 + Y3
-	t1.Add(t0, t0)                              // t1 := t0 + t0
-	t0.Add(t1, t0)                              // t0 := t1 + t0
-	t0.Sub(t0, t2)                              // t0 := t0 - t2
-	t1.Mul(t4, y3)                              // t1 := t4 * Y3
-	t2.Mul(t0, y3)                              // t2 := t0 * Y3
-	y3.Mul(x3, z3)                              // Y3 := X3 * Z3
-	y3.Add(y3, t2)                              // Y3 := Y3 + t2
-	x3.Mul(t3, x3)                              // X3 := t3 * X3
-	x3.Sub(x3, t1)                              // X3 := X3 - t1
-	z3.Mul(t4, z3)                              // Z3 := t4 * Z3
-	t1.Mul(t3, t0)                              // t1 := t3 * t0
-	z3.Add(z3, t1)                              // Z3 := Z3 + t1
+	t0 := new(fiat.P384Element).Mul(p1.x, p2.x)  // t0 := X1 * X2
+	t1 := new(fiat.P384Element).Mul(p1.y, p2.y)  // t1 := Y1 * Y2
+	t2 := new(fiat.P384Element).Mul(p1.z, p2.z)  // t2 := Z1 * Z2
+	t3 := new(fiat.P384Element).Add(p1.x, p1.y)  // t3 := X1 + Y1
+	t4 := new(fiat.P384Element).Add(p2.x, p2.y)  // t4 := X2 + Y2
+	t3.Mul(t3, t4)                               // t3 := t3 * t4
+	t4.Add(t0, t1)                               // t4 := t0 + t1
+	t3.Sub(t3, t4)                               // t3 := t3 - t4
+	t4.Add(p1.y, p1.z)                           // t4 := Y1 + Z1
+	x3 := new(fiat.P384Element).Add(p2.y, p2.z)  // X3 := Y2 + Z2
+	t4.Mul(t4, x3)                               // t4 := t4 * X3
+	x3.Add(t1, t2)                               // X3 := t1 + t2
+	t4.Sub(t4, x3)                               // t4 := t4 - X3
+	x3.Add(p1.x, p1.z)                           // X3 := X1 + Z1
+	y3 := new(fiat.P384Element).Add(p2.x, p2.z)  // Y3 := X2 + Z2
+	x3.Mul(x3, y3)                               // X3 := X3 * Y3
+	y3.Add(t0, t2)                               // Y3 := t0 + t2
+	y3.Sub(x3, y3)                               // Y3 := X3 - Y3
+	z3 := new(fiat.P384Element).Mul(p384B(), t2) // Z3 := b * t2
+	x3.Sub(y3, z3)                               // X3 := Y3 - Z3
+	z3.Add(x3, x3)                               // Z3 := X3 + X3
+	x3.Add(x3, z3)                               // X3 := X3 + Z3
+	z3.Sub(t1, x3)                               // Z3 := t1 - X3
+	x3.Add(t1, x3)                               // X3 := t1 + X3
+	y3.Mul(p384B(), y3)                          // Y3 := b * Y3
+	t1.Add(t2, t2)                               // t1 := t2 + t2
+	t2.Add(t1, t2)                               // t2 := t1 + t2
+	y3.Sub(y3, t2)                               // Y3 := Y3 - t2
+	y3.Sub(y3, t0)                               // Y3 := Y3 - t0
+	t1.Add(y3, y3)                               // t1 := Y3 + Y3
+	y3.Add(t1, y3)                               // Y3 := t1 + Y3
+	t1.Add(t0, t0)                               // t1 := t0 + t0
+	t0.Add(t1, t0)                               // t0 := t1 + t0
+	t0.Sub(t0, t2)                               // t0 := t0 - t2
+	t1.Mul(t4, y3)                               // t1 := t4 * Y3
+	t2.Mul(t0, y3)                               // t2 := t0 * Y3
+	y3.Mul(x3, z3)                               // Y3 := X3 * Z3
+	y3.Add(y3, t2)                               // Y3 := Y3 + t2
+	x3.Mul(t3, x3)                               // X3 := t3 * X3
+	x3.Sub(x3, t1)                               // X3 := X3 - t1
+	z3.Mul(t4, z3)                               // Z3 := t4 * Z3
+	t1.Mul(t3, t0)                               // t1 := t3 * t0
+	z3.Add(z3, t1)                               // Z3 := Z3 + t1
 
 	q.x.Set(x3)
 	q.y.Set(y3)
@@ -246,40 +271,40 @@
 	// Complete addition formula for a = -3 from "Complete addition formulas for
 	// prime order elliptic curves" (https://eprint.iacr.org/2015/1060), §A.2.
 
-	t0 := new(fiat.P384Element).Square(p.x)    // t0 := X ^ 2
-	t1 := new(fiat.P384Element).Square(p.y)    // t1 := Y ^ 2
-	t2 := new(fiat.P384Element).Square(p.z)    // t2 := Z ^ 2
-	t3 := new(fiat.P384Element).Mul(p.x, p.y)  // t3 := X * Y
-	t3.Add(t3, t3)                             // t3 := t3 + t3
-	z3 := new(fiat.P384Element).Mul(p.x, p.z)  // Z3 := X * Z
-	z3.Add(z3, z3)                             // Z3 := Z3 + Z3
-	y3 := new(fiat.P384Element).Mul(p384B, t2) // Y3 := b * t2
-	y3.Sub(y3, z3)                             // Y3 := Y3 - Z3
-	x3 := new(fiat.P384Element).Add(y3, y3)    // X3 := Y3 + Y3
-	y3.Add(x3, y3)                             // Y3 := X3 + Y3
-	x3.Sub(t1, y3)                             // X3 := t1 - Y3
-	y3.Add(t1, y3)                             // Y3 := t1 + Y3
-	y3.Mul(x3, y3)                             // Y3 := X3 * Y3
-	x3.Mul(x3, t3)                             // X3 := X3 * t3
-	t3.Add(t2, t2)                             // t3 := t2 + t2
-	t2.Add(t2, t3)                             // t2 := t2 + t3
-	z3.Mul(p384B, z3)                          // Z3 := b * Z3
-	z3.Sub(z3, t2)                             // Z3 := Z3 - t2
-	z3.Sub(z3, t0)                             // Z3 := Z3 - t0
-	t3.Add(z3, z3)                             // t3 := Z3 + Z3
-	z3.Add(z3, t3)                             // Z3 := Z3 + t3
-	t3.Add(t0, t0)                             // t3 := t0 + t0
-	t0.Add(t3, t0)                             // t0 := t3 + t0
-	t0.Sub(t0, t2)                             // t0 := t0 - t2
-	t0.Mul(t0, z3)                             // t0 := t0 * Z3
-	y3.Add(y3, t0)                             // Y3 := Y3 + t0
-	t0.Mul(p.y, p.z)                           // t0 := Y * Z
-	t0.Add(t0, t0)                             // t0 := t0 + t0
-	z3.Mul(t0, z3)                             // Z3 := t0 * Z3
-	x3.Sub(x3, z3)                             // X3 := X3 - Z3
-	z3.Mul(t0, t1)                             // Z3 := t0 * t1
-	z3.Add(z3, z3)                             // Z3 := Z3 + Z3
-	z3.Add(z3, z3)                             // Z3 := Z3 + Z3
+	t0 := new(fiat.P384Element).Square(p.x)      // t0 := X ^ 2
+	t1 := new(fiat.P384Element).Square(p.y)      // t1 := Y ^ 2
+	t2 := new(fiat.P384Element).Square(p.z)      // t2 := Z ^ 2
+	t3 := new(fiat.P384Element).Mul(p.x, p.y)    // t3 := X * Y
+	t3.Add(t3, t3)                               // t3 := t3 + t3
+	z3 := new(fiat.P384Element).Mul(p.x, p.z)    // Z3 := X * Z
+	z3.Add(z3, z3)                               // Z3 := Z3 + Z3
+	y3 := new(fiat.P384Element).Mul(p384B(), t2) // Y3 := b * t2
+	y3.Sub(y3, z3)                               // Y3 := Y3 - Z3
+	x3 := new(fiat.P384Element).Add(y3, y3)      // X3 := Y3 + Y3
+	y3.Add(x3, y3)                               // Y3 := X3 + Y3
+	x3.Sub(t1, y3)                               // X3 := t1 - Y3
+	y3.Add(t1, y3)                               // Y3 := t1 + Y3
+	y3.Mul(x3, y3)                               // Y3 := X3 * Y3
+	x3.Mul(x3, t3)                               // X3 := X3 * t3
+	t3.Add(t2, t2)                               // t3 := t2 + t2
+	t2.Add(t2, t3)                               // t2 := t2 + t3
+	z3.Mul(p384B(), z3)                          // Z3 := b * Z3
+	z3.Sub(z3, t2)                               // Z3 := Z3 - t2
+	z3.Sub(z3, t0)                               // Z3 := Z3 - t0
+	t3.Add(z3, z3)                               // t3 := Z3 + Z3
+	z3.Add(z3, t3)                               // Z3 := Z3 + t3
+	t3.Add(t0, t0)                               // t3 := t0 + t0
+	t0.Add(t3, t0)                               // t0 := t3 + t0
+	t0.Sub(t0, t2)                               // t0 := t0 - t2
+	t0.Mul(t0, z3)                               // t0 := t0 * Z3
+	y3.Add(y3, t0)                               // Y3 := Y3 + t0
+	t0.Mul(p.y, p.z)                             // t0 := Y * Z
+	t0.Add(t0, t0)                               // t0 := t0 + t0
+	z3.Mul(t0, z3)                               // Z3 := t0 * Z3
+	x3.Sub(x3, z3)                               // X3 := X3 - Z3
+	z3.Mul(t0, t1)                               // Z3 := t0 * t1
+	z3.Add(z3, z3)                               // Z3 := Z3 + Z3
+	z3.Add(z3, z3)                               // Z3 := Z3 + Z3
 
 	q.x.Set(x3)
 	q.y.Set(y3)
@@ -367,7 +392,7 @@
 func (p *P384Point) generatorTable() *[p384ElementLength * 2]p384Table {
 	p384GeneratorTableOnce.Do(func() {
 		p384GeneratorTable = new([p384ElementLength * 2]p384Table)
-		base := NewP384Generator()
+		base := NewP384Point().SetGenerator()
 		for i := 0; i < p384ElementLength*2; i++ {
 			p384GeneratorTable[i][0] = NewP384Point().Set(base)
 			for j := 1; j < 15; j++ {
diff --git a/src/crypto/internal/nistec/p521.go b/src/crypto/internal/nistec/p521.go
index f285d57..a57ad24 100644
--- a/src/crypto/internal/nistec/p521.go
+++ b/src/crypto/internal/nistec/p521.go
@@ -13,10 +13,6 @@
 	"sync"
 )
 
-var p521B, _ = new(fiat.P521Element).SetBytes([]byte{0x0, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, 0x9a, 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85, 0x40, 0xee, 0xa2, 0xda, 0x72, 0x5b, 0x99, 0xb3, 0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1, 0x9, 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e, 0x93, 0x7b, 0x16, 0x52, 0xc0, 0xbd, 0x3b, 0xb1, 0xbf, 0x7, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c, 0x34, 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50, 0x3f, 0x0})
-
-var p521G, _ = NewP521Point().SetBytes([]byte{0x4, 0x0, 0xc6, 0x85, 0x8e, 0x6, 0xb7, 0x4, 0x4, 0xe9, 0xcd, 0x9e, 0x3e, 0xcb, 0x66, 0x23, 0x95, 0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x5, 0x3f, 0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d, 0x3d, 0xba, 0xa1, 0x4b, 0x5e, 0x77, 0xef, 0xe7, 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff, 0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a, 0x42, 0x9b, 0xf9, 0x7e, 0x7e, 0x31, 0xc2, 0xe5, 0xbd, 0x66, 0x1, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x4, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x1, 0x3f, 0xad, 0x7, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50})
-
 // p521ElementLength is the length of an element of the base or scalar field,
 // which have the same bytes length for all NIST P curves.
 const p521ElementLength = 66
@@ -37,13 +33,12 @@
 	}
 }
 
-// NewP521Generator returns a new P521Point set to the canonical generator.
-func NewP521Generator() *P521Point {
-	return (&P521Point{
-		x: new(fiat.P521Element),
-		y: new(fiat.P521Element),
-		z: new(fiat.P521Element),
-	}).Set(p521G)
+// SetGenerator sets p to the canonical generator and returns p.
+func (p *P521Point) SetGenerator() *P521Point {
+	p.x.SetBytes([]byte{0x0, 0xc6, 0x85, 0x8e, 0x6, 0xb7, 0x4, 0x4, 0xe9, 0xcd, 0x9e, 0x3e, 0xcb, 0x66, 0x23, 0x95, 0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x5, 0x3f, 0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d, 0x3d, 0xba, 0xa1, 0x4b, 0x5e, 0x77, 0xef, 0xe7, 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff, 0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a, 0x42, 0x9b, 0xf9, 0x7e, 0x7e, 0x31, 0xc2, 0xe5, 0xbd, 0x66})
+	p.y.SetBytes([]byte{0x1, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x4, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x1, 0x3f, 0xad, 0x7, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50})
+	p.z.One()
+	return p
 }
 
 // Set sets p = q and returns p.
@@ -112,6 +107,16 @@
 	}
 }
 
+var _p521B *fiat.P521Element
+var _p521BOnce sync.Once
+
+func p521B() *fiat.P521Element {
+	_p521BOnce.Do(func() {
+		_p521B, _ = new(fiat.P521Element).SetBytes([]byte{0x0, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, 0x9a, 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85, 0x40, 0xee, 0xa2, 0xda, 0x72, 0x5b, 0x99, 0xb3, 0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1, 0x9, 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e, 0x93, 0x7b, 0x16, 0x52, 0xc0, 0xbd, 0x3b, 0xb1, 0xbf, 0x7, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c, 0x34, 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50, 0x3f, 0x0})
+	})
+	return _p521B
+}
+
 // p521Polynomial sets y2 to x³ - 3x + b, and returns y2.
 func p521Polynomial(y2, x *fiat.P521Element) *fiat.P521Element {
 	y2.Square(x)
@@ -119,9 +124,9 @@
 
 	threeX := new(fiat.P521Element).Add(x, x)
 	threeX.Add(threeX, x)
-
 	y2.Sub(y2, threeX)
-	return y2.Add(y2, p521B)
+
+	return y2.Add(y2, p521B())
 }
 
 func p521CheckOnCurve(x, y *fiat.P521Element) error {
@@ -159,6 +164,26 @@
 	return buf
 }
 
+// BytesX returns the encoding of the x-coordinate of p, as specified in SEC 1,
+// Version 2.0, Section 2.3.5, or an error if p is the point at infinity.
+func (p *P521Point) BytesX() ([]byte, error) {
+	// This function is outlined to make the allocations inline in the caller
+	// rather than happen on the heap.
+	var out [p521ElementLength]byte
+	return p.bytesX(&out)
+}
+
+func (p *P521Point) bytesX(out *[p521ElementLength]byte) ([]byte, error) {
+	if p.z.IsZero() == 1 {
+		return nil, errors.New("P521 point is the point at infinity")
+	}
+
+	zinv := new(fiat.P521Element).Invert(p.z)
+	x := new(fiat.P521Element).Mul(p.x, zinv)
+
+	return append(out[:0], x.Bytes()...), nil
+}
+
 // BytesCompressed returns the compressed or infinity encoding of p, as
 // specified in SEC 1, Version 2.0, Section 2.3.3. Note that the encoding of the
 // point at infinity is shorter than all other encodings.
@@ -191,49 +216,49 @@
 	// Complete addition formula for a = -3 from "Complete addition formulas for
 	// prime order elliptic curves" (https://eprint.iacr.org/2015/1060), §A.2.
 
-	t0 := new(fiat.P521Element).Mul(p1.x, p2.x) // t0 := X1 * X2
-	t1 := new(fiat.P521Element).Mul(p1.y, p2.y) // t1 := Y1 * Y2
-	t2 := new(fiat.P521Element).Mul(p1.z, p2.z) // t2 := Z1 * Z2
-	t3 := new(fiat.P521Element).Add(p1.x, p1.y) // t3 := X1 + Y1
-	t4 := new(fiat.P521Element).Add(p2.x, p2.y) // t4 := X2 + Y2
-	t3.Mul(t3, t4)                              // t3 := t3 * t4
-	t4.Add(t0, t1)                              // t4 := t0 + t1
-	t3.Sub(t3, t4)                              // t3 := t3 - t4
-	t4.Add(p1.y, p1.z)                          // t4 := Y1 + Z1
-	x3 := new(fiat.P521Element).Add(p2.y, p2.z) // X3 := Y2 + Z2
-	t4.Mul(t4, x3)                              // t4 := t4 * X3
-	x3.Add(t1, t2)                              // X3 := t1 + t2
-	t4.Sub(t4, x3)                              // t4 := t4 - X3
-	x3.Add(p1.x, p1.z)                          // X3 := X1 + Z1
-	y3 := new(fiat.P521Element).Add(p2.x, p2.z) // Y3 := X2 + Z2
-	x3.Mul(x3, y3)                              // X3 := X3 * Y3
-	y3.Add(t0, t2)                              // Y3 := t0 + t2
-	y3.Sub(x3, y3)                              // Y3 := X3 - Y3
-	z3 := new(fiat.P521Element).Mul(p521B, t2)  // Z3 := b * t2
-	x3.Sub(y3, z3)                              // X3 := Y3 - Z3
-	z3.Add(x3, x3)                              // Z3 := X3 + X3
-	x3.Add(x3, z3)                              // X3 := X3 + Z3
-	z3.Sub(t1, x3)                              // Z3 := t1 - X3
-	x3.Add(t1, x3)                              // X3 := t1 + X3
-	y3.Mul(p521B, y3)                           // Y3 := b * Y3
-	t1.Add(t2, t2)                              // t1 := t2 + t2
-	t2.Add(t1, t2)                              // t2 := t1 + t2
-	y3.Sub(y3, t2)                              // Y3 := Y3 - t2
-	y3.Sub(y3, t0)                              // Y3 := Y3 - t0
-	t1.Add(y3, y3)                              // t1 := Y3 + Y3
-	y3.Add(t1, y3)                              // Y3 := t1 + Y3
-	t1.Add(t0, t0)                              // t1 := t0 + t0
-	t0.Add(t1, t0)                              // t0 := t1 + t0
-	t0.Sub(t0, t2)                              // t0 := t0 - t2
-	t1.Mul(t4, y3)                              // t1 := t4 * Y3
-	t2.Mul(t0, y3)                              // t2 := t0 * Y3
-	y3.Mul(x3, z3)                              // Y3 := X3 * Z3
-	y3.Add(y3, t2)                              // Y3 := Y3 + t2
-	x3.Mul(t3, x3)                              // X3 := t3 * X3
-	x3.Sub(x3, t1)                              // X3 := X3 - t1
-	z3.Mul(t4, z3)                              // Z3 := t4 * Z3
-	t1.Mul(t3, t0)                              // t1 := t3 * t0
-	z3.Add(z3, t1)                              // Z3 := Z3 + t1
+	t0 := new(fiat.P521Element).Mul(p1.x, p2.x)  // t0 := X1 * X2
+	t1 := new(fiat.P521Element).Mul(p1.y, p2.y)  // t1 := Y1 * Y2
+	t2 := new(fiat.P521Element).Mul(p1.z, p2.z)  // t2 := Z1 * Z2
+	t3 := new(fiat.P521Element).Add(p1.x, p1.y)  // t3 := X1 + Y1
+	t4 := new(fiat.P521Element).Add(p2.x, p2.y)  // t4 := X2 + Y2
+	t3.Mul(t3, t4)                               // t3 := t3 * t4
+	t4.Add(t0, t1)                               // t4 := t0 + t1
+	t3.Sub(t3, t4)                               // t3 := t3 - t4
+	t4.Add(p1.y, p1.z)                           // t4 := Y1 + Z1
+	x3 := new(fiat.P521Element).Add(p2.y, p2.z)  // X3 := Y2 + Z2
+	t4.Mul(t4, x3)                               // t4 := t4 * X3
+	x3.Add(t1, t2)                               // X3 := t1 + t2
+	t4.Sub(t4, x3)                               // t4 := t4 - X3
+	x3.Add(p1.x, p1.z)                           // X3 := X1 + Z1
+	y3 := new(fiat.P521Element).Add(p2.x, p2.z)  // Y3 := X2 + Z2
+	x3.Mul(x3, y3)                               // X3 := X3 * Y3
+	y3.Add(t0, t2)                               // Y3 := t0 + t2
+	y3.Sub(x3, y3)                               // Y3 := X3 - Y3
+	z3 := new(fiat.P521Element).Mul(p521B(), t2) // Z3 := b * t2
+	x3.Sub(y3, z3)                               // X3 := Y3 - Z3
+	z3.Add(x3, x3)                               // Z3 := X3 + X3
+	x3.Add(x3, z3)                               // X3 := X3 + Z3
+	z3.Sub(t1, x3)                               // Z3 := t1 - X3
+	x3.Add(t1, x3)                               // X3 := t1 + X3
+	y3.Mul(p521B(), y3)                          // Y3 := b * Y3
+	t1.Add(t2, t2)                               // t1 := t2 + t2
+	t2.Add(t1, t2)                               // t2 := t1 + t2
+	y3.Sub(y3, t2)                               // Y3 := Y3 - t2
+	y3.Sub(y3, t0)                               // Y3 := Y3 - t0
+	t1.Add(y3, y3)                               // t1 := Y3 + Y3
+	y3.Add(t1, y3)                               // Y3 := t1 + Y3
+	t1.Add(t0, t0)                               // t1 := t0 + t0
+	t0.Add(t1, t0)                               // t0 := t1 + t0
+	t0.Sub(t0, t2)                               // t0 := t0 - t2
+	t1.Mul(t4, y3)                               // t1 := t4 * Y3
+	t2.Mul(t0, y3)                               // t2 := t0 * Y3
+	y3.Mul(x3, z3)                               // Y3 := X3 * Z3
+	y3.Add(y3, t2)                               // Y3 := Y3 + t2
+	x3.Mul(t3, x3)                               // X3 := t3 * X3
+	x3.Sub(x3, t1)                               // X3 := X3 - t1
+	z3.Mul(t4, z3)                               // Z3 := t4 * Z3
+	t1.Mul(t3, t0)                               // t1 := t3 * t0
+	z3.Add(z3, t1)                               // Z3 := Z3 + t1
 
 	q.x.Set(x3)
 	q.y.Set(y3)
@@ -246,40 +271,40 @@
 	// Complete addition formula for a = -3 from "Complete addition formulas for
 	// prime order elliptic curves" (https://eprint.iacr.org/2015/1060), §A.2.
 
-	t0 := new(fiat.P521Element).Square(p.x)    // t0 := X ^ 2
-	t1 := new(fiat.P521Element).Square(p.y)    // t1 := Y ^ 2
-	t2 := new(fiat.P521Element).Square(p.z)    // t2 := Z ^ 2
-	t3 := new(fiat.P521Element).Mul(p.x, p.y)  // t3 := X * Y
-	t3.Add(t3, t3)                             // t3 := t3 + t3
-	z3 := new(fiat.P521Element).Mul(p.x, p.z)  // Z3 := X * Z
-	z3.Add(z3, z3)                             // Z3 := Z3 + Z3
-	y3 := new(fiat.P521Element).Mul(p521B, t2) // Y3 := b * t2
-	y3.Sub(y3, z3)                             // Y3 := Y3 - Z3
-	x3 := new(fiat.P521Element).Add(y3, y3)    // X3 := Y3 + Y3
-	y3.Add(x3, y3)                             // Y3 := X3 + Y3
-	x3.Sub(t1, y3)                             // X3 := t1 - Y3
-	y3.Add(t1, y3)                             // Y3 := t1 + Y3
-	y3.Mul(x3, y3)                             // Y3 := X3 * Y3
-	x3.Mul(x3, t3)                             // X3 := X3 * t3
-	t3.Add(t2, t2)                             // t3 := t2 + t2
-	t2.Add(t2, t3)                             // t2 := t2 + t3
-	z3.Mul(p521B, z3)                          // Z3 := b * Z3
-	z3.Sub(z3, t2)                             // Z3 := Z3 - t2
-	z3.Sub(z3, t0)                             // Z3 := Z3 - t0
-	t3.Add(z3, z3)                             // t3 := Z3 + Z3
-	z3.Add(z3, t3)                             // Z3 := Z3 + t3
-	t3.Add(t0, t0)                             // t3 := t0 + t0
-	t0.Add(t3, t0)                             // t0 := t3 + t0
-	t0.Sub(t0, t2)                             // t0 := t0 - t2
-	t0.Mul(t0, z3)                             // t0 := t0 * Z3
-	y3.Add(y3, t0)                             // Y3 := Y3 + t0
-	t0.Mul(p.y, p.z)                           // t0 := Y * Z
-	t0.Add(t0, t0)                             // t0 := t0 + t0
-	z3.Mul(t0, z3)                             // Z3 := t0 * Z3
-	x3.Sub(x3, z3)                             // X3 := X3 - Z3
-	z3.Mul(t0, t1)                             // Z3 := t0 * t1
-	z3.Add(z3, z3)                             // Z3 := Z3 + Z3
-	z3.Add(z3, z3)                             // Z3 := Z3 + Z3
+	t0 := new(fiat.P521Element).Square(p.x)      // t0 := X ^ 2
+	t1 := new(fiat.P521Element).Square(p.y)      // t1 := Y ^ 2
+	t2 := new(fiat.P521Element).Square(p.z)      // t2 := Z ^ 2
+	t3 := new(fiat.P521Element).Mul(p.x, p.y)    // t3 := X * Y
+	t3.Add(t3, t3)                               // t3 := t3 + t3
+	z3 := new(fiat.P521Element).Mul(p.x, p.z)    // Z3 := X * Z
+	z3.Add(z3, z3)                               // Z3 := Z3 + Z3
+	y3 := new(fiat.P521Element).Mul(p521B(), t2) // Y3 := b * t2
+	y3.Sub(y3, z3)                               // Y3 := Y3 - Z3
+	x3 := new(fiat.P521Element).Add(y3, y3)      // X3 := Y3 + Y3
+	y3.Add(x3, y3)                               // Y3 := X3 + Y3
+	x3.Sub(t1, y3)                               // X3 := t1 - Y3
+	y3.Add(t1, y3)                               // Y3 := t1 + Y3
+	y3.Mul(x3, y3)                               // Y3 := X3 * Y3
+	x3.Mul(x3, t3)                               // X3 := X3 * t3
+	t3.Add(t2, t2)                               // t3 := t2 + t2
+	t2.Add(t2, t3)                               // t2 := t2 + t3
+	z3.Mul(p521B(), z3)                          // Z3 := b * Z3
+	z3.Sub(z3, t2)                               // Z3 := Z3 - t2
+	z3.Sub(z3, t0)                               // Z3 := Z3 - t0
+	t3.Add(z3, z3)                               // t3 := Z3 + Z3
+	z3.Add(z3, t3)                               // Z3 := Z3 + t3
+	t3.Add(t0, t0)                               // t3 := t0 + t0
+	t0.Add(t3, t0)                               // t0 := t3 + t0
+	t0.Sub(t0, t2)                               // t0 := t0 - t2
+	t0.Mul(t0, z3)                               // t0 := t0 * Z3
+	y3.Add(y3, t0)                               // Y3 := Y3 + t0
+	t0.Mul(p.y, p.z)                             // t0 := Y * Z
+	t0.Add(t0, t0)                               // t0 := t0 + t0
+	z3.Mul(t0, z3)                               // Z3 := t0 * Z3
+	x3.Sub(x3, z3)                               // X3 := X3 - Z3
+	z3.Mul(t0, t1)                               // Z3 := t0 * t1
+	z3.Add(z3, z3)                               // Z3 := Z3 + Z3
+	z3.Add(z3, z3)                               // Z3 := Z3 + Z3
 
 	q.x.Set(x3)
 	q.y.Set(y3)
@@ -367,7 +392,7 @@
 func (p *P521Point) generatorTable() *[p521ElementLength * 2]p521Table {
 	p521GeneratorTableOnce.Do(func() {
 		p521GeneratorTable = new([p521ElementLength * 2]p521Table)
-		base := NewP521Generator()
+		base := NewP521Point().SetGenerator()
 		for i := 0; i < p521ElementLength*2; i++ {
 			p521GeneratorTable[i][0] = NewP521Point().Set(base)
 			for j := 1; j < 15; j++ {
diff --git a/src/crypto/internal/subtle/aliasing.go b/src/crypto/internal/subtle/aliasing.go
deleted file mode 100644
index 16e2fca..0000000
--- a/src/crypto/internal/subtle/aliasing.go
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build !appengine
-
-// Package subtle implements functions that are often useful in cryptographic
-// code but require careful thought to use correctly.
-//
-// This is a mirror of golang.org/x/crypto/internal/subtle.
-package subtle // import "crypto/internal/subtle"
-
-import "unsafe"
-
-// AnyOverlap reports whether x and y share memory at any (not necessarily
-// corresponding) index. The memory beyond the slice length is ignored.
-func AnyOverlap(x, y []byte) bool {
-	return len(x) > 0 && len(y) > 0 &&
-		uintptr(unsafe.Pointer(&x[0])) <= uintptr(unsafe.Pointer(&y[len(y)-1])) &&
-		uintptr(unsafe.Pointer(&y[0])) <= uintptr(unsafe.Pointer(&x[len(x)-1]))
-}
-
-// InexactOverlap reports whether x and y share memory at any non-corresponding
-// index. The memory beyond the slice length is ignored. Note that x and y can
-// have different lengths and still not have any inexact overlap.
-//
-// InexactOverlap can be used to implement the requirements of the crypto/cipher
-// AEAD, Block, BlockMode and Stream interfaces.
-func InexactOverlap(x, y []byte) bool {
-	if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] {
-		return false
-	}
-	return AnyOverlap(x, y)
-}
diff --git a/src/crypto/internal/subtle/aliasing_appengine.go b/src/crypto/internal/subtle/aliasing_appengine.go
deleted file mode 100644
index 90ac4b6..0000000
--- a/src/crypto/internal/subtle/aliasing_appengine.go
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build appengine
-
-// Package subtle implements functions that are often useful in cryptographic
-// code but require careful thought to use correctly.
-//
-// This is a mirror of golang.org/x/crypto/internal/subtle.
-package subtle // import "crypto/internal/subtle"
-
-// This is the Google App Engine standard variant based on reflect
-// because the unsafe package and cgo are disallowed.
-
-import "reflect"
-
-// AnyOverlap reports whether x and y share memory at any (not necessarily
-// corresponding) index. The memory beyond the slice length is ignored.
-func AnyOverlap(x, y []byte) bool {
-	return len(x) > 0 && len(y) > 0 &&
-		reflect.ValueOf(&x[0]).Pointer() <= reflect.ValueOf(&y[len(y)-1]).Pointer() &&
-		reflect.ValueOf(&y[0]).Pointer() <= reflect.ValueOf(&x[len(x)-1]).Pointer()
-}
-
-// InexactOverlap reports whether x and y share memory at any non-corresponding
-// index. The memory beyond the slice length is ignored. Note that x and y can
-// have different lengths and still not have any inexact overlap.
-//
-// InexactOverlap can be used to implement the requirements of the crypto/cipher
-// AEAD, Block, BlockMode and Stream interfaces.
-func InexactOverlap(x, y []byte) bool {
-	if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] {
-		return false
-	}
-	return AnyOverlap(x, y)
-}
diff --git a/src/crypto/internal/subtle/aliasing_test.go b/src/crypto/internal/subtle/aliasing_test.go
deleted file mode 100644
index f1e7238..0000000
--- a/src/crypto/internal/subtle/aliasing_test.go
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package subtle_test
-
-import (
-	"testing"
-
-	"crypto/internal/subtle"
-)
-
-var a, b [100]byte
-
-var aliasingTests = []struct {
-	x, y                       []byte
-	anyOverlap, inexactOverlap bool
-}{
-	{a[:], b[:], false, false},
-	{a[:], b[:0], false, false},
-	{a[:], b[:50], false, false},
-	{a[40:50], a[50:60], false, false},
-	{a[40:50], a[60:70], false, false},
-	{a[:51], a[50:], true, true},
-	{a[:], a[:], true, false},
-	{a[:50], a[:60], true, false},
-	{a[:], nil, false, false},
-	{nil, nil, false, false},
-	{a[:], a[:0], false, false},
-	{a[:10], a[:10:20], true, false},
-	{a[:10], a[5:10:20], true, true},
-}
-
-func testAliasing(t *testing.T, i int, x, y []byte, anyOverlap, inexactOverlap bool) {
-	any := subtle.AnyOverlap(x, y)
-	if any != anyOverlap {
-		t.Errorf("%d: wrong AnyOverlap result, expected %v, got %v", i, anyOverlap, any)
-	}
-	inexact := subtle.InexactOverlap(x, y)
-	if inexact != inexactOverlap {
-		t.Errorf("%d: wrong InexactOverlap result, expected %v, got %v", i, inexactOverlap, any)
-	}
-}
-
-func TestAliasing(t *testing.T) {
-	for i, tt := range aliasingTests {
-		testAliasing(t, i, tt.x, tt.y, tt.anyOverlap, tt.inexactOverlap)
-		testAliasing(t, i, tt.y, tt.x, tt.anyOverlap, tt.inexactOverlap)
-	}
-}
diff --git a/src/crypto/md5/md5.go b/src/crypto/md5/md5.go
index 0115784..ccee4ea 100644
--- a/src/crypto/md5/md5.go
+++ b/src/crypto/md5/md5.go
@@ -59,13 +59,13 @@
 func (d *digest) MarshalBinary() ([]byte, error) {
 	b := make([]byte, 0, marshaledSize)
 	b = append(b, magic...)
-	b = appendUint32(b, d.s[0])
-	b = appendUint32(b, d.s[1])
-	b = appendUint32(b, d.s[2])
-	b = appendUint32(b, d.s[3])
+	b = binary.BigEndian.AppendUint32(b, d.s[0])
+	b = binary.BigEndian.AppendUint32(b, d.s[1])
+	b = binary.BigEndian.AppendUint32(b, d.s[2])
+	b = binary.BigEndian.AppendUint32(b, d.s[3])
 	b = append(b, d.x[:d.nx]...)
 	b = b[:len(b)+len(d.x)-d.nx] // already zero
-	b = appendUint64(b, d.len)
+	b = binary.BigEndian.AppendUint64(b, d.len)
 	return b, nil
 }
 
@@ -87,18 +87,6 @@
 	return nil
 }
 
-func appendUint64(b []byte, x uint64) []byte {
-	var a [8]byte
-	binary.BigEndian.PutUint64(a[:], x)
-	return append(b, a[:]...)
-}
-
-func appendUint32(b []byte, x uint32) []byte {
-	var a [4]byte
-	binary.BigEndian.PutUint32(a[:], x)
-	return append(b, a[:]...)
-}
-
 func consumeUint64(b []byte) ([]byte, uint64) {
 	return b[8:], binary.BigEndian.Uint64(b[0:8])
 }
diff --git a/src/crypto/rand/rand_batched_test.go b/src/crypto/rand/rand_batched_test.go
index 8995377..02f4893 100644
--- a/src/crypto/rand/rand_batched_test.go
+++ b/src/crypto/rand/rand_batched_test.go
@@ -8,7 +8,6 @@
 
 import (
 	"bytes"
-	"encoding/binary"
 	"errors"
 	prand "math/rand"
 	"testing"
@@ -33,10 +32,6 @@
 }
 
 func TestBatchedBuffering(t *testing.T) {
-	var prandSeed [8]byte
-	Read(prandSeed[:])
-	prand.Seed(int64(binary.LittleEndian.Uint64(prandSeed[:])))
-
 	backingStore := make([]byte, 1<<23)
 	prand.Read(backingStore)
 	backingMarker := backingStore[:]
diff --git a/src/crypto/rand/rand_unix.go b/src/crypto/rand/rand_unix.go
index 746e90c..40fce36 100644
--- a/src/crypto/rand/rand_unix.go
+++ b/src/crypto/rand/rand_unix.go
@@ -34,7 +34,7 @@
 type reader struct {
 	f    io.Reader
 	mu   sync.Mutex
-	used uint32 // Atomic: 0 - never used, 1 - used, but f == nil, 2 - used, and f != nil
+	used atomic.Uint32 // Atomic: 0 - never used, 1 - used, but f == nil, 2 - used, and f != nil
 }
 
 // altGetRandom if non-nil specifies an OS-specific function to get
@@ -47,7 +47,7 @@
 
 func (r *reader) Read(b []byte) (n int, err error) {
 	boring.Unreachable()
-	if atomic.CompareAndSwapUint32(&r.used, 0, 1) {
+	if r.used.CompareAndSwap(0, 1) {
 		// First use of randomness. Start timer to warn about
 		// being blocked on entropy not being available.
 		t := time.AfterFunc(time.Minute, warnBlocked)
@@ -56,16 +56,16 @@
 	if altGetRandom != nil && altGetRandom(b) == nil {
 		return len(b), nil
 	}
-	if atomic.LoadUint32(&r.used) != 2 {
+	if r.used.Load() != 2 {
 		r.mu.Lock()
-		if atomic.LoadUint32(&r.used) != 2 {
+		if r.used.Load() != 2 {
 			f, err := os.Open(urandomDevice)
 			if err != nil {
 				r.mu.Unlock()
 				return 0, err
 			}
 			r.f = hideAgainReader{f}
-			atomic.StoreUint32(&r.used, 2)
+			r.used.Store(2)
 		}
 		r.mu.Unlock()
 	}
diff --git a/src/crypto/rc4/rc4.go b/src/crypto/rc4/rc4.go
index c2df0db..f08da0e 100644
--- a/src/crypto/rc4/rc4.go
+++ b/src/crypto/rc4/rc4.go
@@ -10,7 +10,7 @@
 package rc4
 
 import (
-	"crypto/internal/subtle"
+	"crypto/internal/alias"
 	"strconv"
 )
 
@@ -62,7 +62,7 @@
 	if len(src) == 0 {
 		return
 	}
-	if subtle.InexactOverlap(dst[:len(src)], src) {
+	if alias.InexactOverlap(dst[:len(src)], src) {
 		panic("crypto/rc4: invalid buffer overlap")
 	}
 	i, j := c.i, c.j
diff --git a/src/crypto/rsa/boring.go b/src/crypto/rsa/boring.go
index 9b1db56..b9f9d31 100644
--- a/src/crypto/rsa/boring.go
+++ b/src/crypto/rsa/boring.go
@@ -11,7 +11,6 @@
 	"crypto/internal/boring/bbig"
 	"crypto/internal/boring/bcache"
 	"math/big"
-	"unsafe"
 )
 
 // Cached conversions from Go PublicKey/PrivateKey to BoringCrypto.
@@ -32,8 +31,8 @@
 	orig PublicKey
 }
 
-var pubCache bcache.Cache
-var privCache bcache.Cache
+var pubCache bcache.Cache[PublicKey, boringPub]
+var privCache bcache.Cache[PrivateKey, boringPriv]
 
 func init() {
 	pubCache.Register()
@@ -41,7 +40,7 @@
 }
 
 func boringPublicKey(pub *PublicKey) (*boring.PublicKeyRSA, error) {
-	b := (*boringPub)(pubCache.Get(unsafe.Pointer(pub)))
+	b := pubCache.Get(pub)
 	if b != nil && publicKeyEqual(&b.orig, pub) {
 		return b.key, nil
 	}
@@ -53,7 +52,7 @@
 		return nil, err
 	}
 	b.key = key
-	pubCache.Put(unsafe.Pointer(pub), unsafe.Pointer(b))
+	pubCache.Put(pub, b)
 	return key, nil
 }
 
@@ -63,7 +62,7 @@
 }
 
 func boringPrivateKey(priv *PrivateKey) (*boring.PrivateKeyRSA, error) {
-	b := (*boringPriv)(privCache.Get(unsafe.Pointer(priv)))
+	b := privCache.Get(priv)
 	if b != nil && privateKeyEqual(&b.orig, priv) {
 		return b.key, nil
 	}
@@ -87,7 +86,7 @@
 		return nil, err
 	}
 	b.key = key
-	privCache.Put(unsafe.Pointer(priv), unsafe.Pointer(b))
+	privCache.Put(priv, b)
 	return key, nil
 }
 
diff --git a/src/crypto/rsa/boring_test.go b/src/crypto/rsa/boring_test.go
index 6223244..2234d07 100644
--- a/src/crypto/rsa/boring_test.go
+++ b/src/crypto/rsa/boring_test.go
@@ -13,6 +13,8 @@
 	"crypto"
 	"crypto/rand"
 	"encoding/asn1"
+	"encoding/hex"
+	"math/big"
 	"runtime"
 	"runtime/debug"
 	"sync"
@@ -128,3 +130,19 @@
 		wg.Wait()
 	}
 }
+
+func bigFromHex(hex string) *big.Int {
+	n, ok := new(big.Int).SetString(hex, 16)
+	if !ok {
+		panic("bad hex: " + hex)
+	}
+	return n
+}
+
+func fromHex(hexStr string) []byte {
+	s, err := hex.DecodeString(hexStr)
+	if err != nil {
+		panic(err)
+	}
+	return s
+}
diff --git a/src/crypto/rsa/example_test.go b/src/crypto/rsa/example_test.go
index ce5c2d9..d07ee7d 100644
--- a/src/crypto/rsa/example_test.go
+++ b/src/crypto/rsa/example_test.go
@@ -2,17 +2,17 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package rsa
+package rsa_test
 
 import (
 	"crypto"
 	"crypto/aes"
 	"crypto/cipher"
 	"crypto/rand"
+	"crypto/rsa"
 	"crypto/sha256"
 	"encoding/hex"
 	"fmt"
-	"io"
 	"os"
 )
 
@@ -36,21 +36,17 @@
 // a buffer that contains a random key. Thus, if the RSA result isn't
 // well-formed, the implementation uses a random key in constant time.
 func ExampleDecryptPKCS1v15SessionKey() {
-	// crypto/rand.Reader is a good source of entropy for blinding the RSA
-	// operation.
-	rng := rand.Reader
-
 	// The hybrid scheme should use at least a 16-byte symmetric key. Here
 	// we read the random key that will be used if the RSA decryption isn't
 	// well-formed.
 	key := make([]byte, 32)
-	if _, err := io.ReadFull(rng, key); err != nil {
+	if _, err := rand.Read(key); err != nil {
 		panic("RNG failure")
 	}
 
 	rsaCiphertext, _ := hex.DecodeString("aabbccddeeff")
 
-	if err := DecryptPKCS1v15SessionKey(rng, rsaPrivateKey, rsaCiphertext, key); err != nil {
+	if err := rsa.DecryptPKCS1v15SessionKey(nil, rsaPrivateKey, rsaCiphertext, key); err != nil {
 		// Any errors that result will be “public” – meaning that they
 		// can be determined without any secret information. (For
 		// instance, if the length of key is impossible given the RSA
@@ -86,10 +82,6 @@
 }
 
 func ExampleSignPKCS1v15() {
-	// crypto/rand.Reader is a good source of entropy for blinding the RSA
-	// operation.
-	rng := rand.Reader
-
 	message := []byte("message to be signed")
 
 	// Only small messages can be signed directly; thus the hash of a
@@ -99,7 +91,7 @@
 	// of writing (2016).
 	hashed := sha256.Sum256(message)
 
-	signature, err := SignPKCS1v15(rng, rsaPrivateKey, crypto.SHA256, hashed[:])
+	signature, err := rsa.SignPKCS1v15(nil, rsaPrivateKey, crypto.SHA256, hashed[:])
 	if err != nil {
 		fmt.Fprintf(os.Stderr, "Error from signing: %s\n", err)
 		return
@@ -119,7 +111,7 @@
 	// of writing (2016).
 	hashed := sha256.Sum256(message)
 
-	err := VerifyPKCS1v15(&rsaPrivateKey.PublicKey, crypto.SHA256, hashed[:], signature)
+	err := rsa.VerifyPKCS1v15(&rsaPrivateKey.PublicKey, crypto.SHA256, hashed[:], signature)
 	if err != nil {
 		fmt.Fprintf(os.Stderr, "Error from verification: %s\n", err)
 		return
@@ -136,7 +128,7 @@
 	// encryption function.
 	rng := rand.Reader
 
-	ciphertext, err := EncryptOAEP(sha256.New(), rng, &test2048Key.PublicKey, secretMessage, label)
+	ciphertext, err := rsa.EncryptOAEP(sha256.New(), rng, &test2048Key.PublicKey, secretMessage, label)
 	if err != nil {
 		fmt.Fprintf(os.Stderr, "Error from encryption: %s\n", err)
 		return
@@ -151,11 +143,7 @@
 	ciphertext, _ := hex.DecodeString("4d1ee10e8f286390258c51a5e80802844c3e6358ad6690b7285218a7c7ed7fc3a4c7b950fbd04d4b0239cc060dcc7065ca6f84c1756deb71ca5685cadbb82be025e16449b905c568a19c088a1abfad54bf7ecc67a7df39943ec511091a34c0f2348d04e058fcff4d55644de3cd1d580791d4524b92f3e91695582e6e340a1c50b6c6d78e80b4e42c5b4d45e479b492de42bbd39cc642ebb80226bb5200020d501b24a37bcc2ec7f34e596b4fd6b063de4858dbf5a4e3dd18e262eda0ec2d19dbd8e890d672b63d368768360b20c0b6b8592a438fa275e5fa7f60bef0dd39673fd3989cc54d2cb80c08fcd19dacbc265ee1c6014616b0e04ea0328c2a04e73460")
 	label := []byte("orders")
 
-	// crypto/rand.Reader is a good source of entropy for blinding the RSA
-	// operation.
-	rng := rand.Reader
-
-	plaintext, err := DecryptOAEP(sha256.New(), rng, test2048Key, ciphertext, label)
+	plaintext, err := rsa.DecryptOAEP(sha256.New(), nil, test2048Key, ciphertext, label)
 	if err != nil {
 		fmt.Fprintf(os.Stderr, "Error from decryption: %s\n", err)
 		return
diff --git a/src/crypto/rsa/pkcs1v15.go b/src/crypto/rsa/pkcs1v15.go
index ab19229..e51b9d2 100644
--- a/src/crypto/rsa/pkcs1v15.go
+++ b/src/crypto/rsa/pkcs1v15.go
@@ -11,12 +11,11 @@
 	"crypto/subtle"
 	"errors"
 	"io"
-	"math/big"
 )
 
 // This file implements encryption and decryption using PKCS #1 v1.5 padding.
 
-// PKCS1v15DecrypterOpts is for passing options to PKCS #1 v1.5 decryption using
+// PKCS1v15DecryptOptions is for passing options to PKCS #1 v1.5 decryption using
 // the crypto.Decrypter interface.
 type PKCS1v15DecryptOptions struct {
 	// SessionKeyLen is the length of the session key that is being
@@ -76,13 +75,11 @@
 		return boring.EncryptRSANoPadding(bkey, em)
 	}
 
-	m := new(big.Int).SetBytes(em)
-	c := encrypt(new(big.Int), pub, m)
-	return c.FillBytes(em), nil
+	return encrypt(pub, em)
 }
 
 // DecryptPKCS1v15 decrypts a plaintext using RSA and the padding scheme from PKCS #1 v1.5.
-// If random != nil, it uses RSA blinding to avoid timing side-channel attacks.
+// The random parameter is legacy and ignored, and it can be as nil.
 //
 // Note that whether this function returns an error or not discloses secret
 // information. If an attacker can cause this function to run repeatedly and
@@ -106,7 +103,7 @@
 		return out, nil
 	}
 
-	valid, out, index, err := decryptPKCS1v15(random, priv, ciphertext)
+	valid, out, index, err := decryptPKCS1v15(priv, ciphertext)
 	if err != nil {
 		return nil, err
 	}
@@ -117,7 +114,7 @@
 }
 
 // DecryptPKCS1v15SessionKey decrypts a session key using RSA and the padding scheme from PKCS #1 v1.5.
-// If random != nil, it uses RSA blinding to avoid timing side-channel attacks.
+// The random parameter is legacy and ignored, and it can be as nil.
 // It returns an error if the ciphertext is the wrong length or if the
 // ciphertext is greater than the public modulus. Otherwise, no error is
 // returned. If the padding is valid, the resulting plaintext message is copied
@@ -144,7 +141,7 @@
 		return ErrDecryption
 	}
 
-	valid, em, index, err := decryptPKCS1v15(random, priv, ciphertext)
+	valid, em, index, err := decryptPKCS1v15(priv, ciphertext)
 	if err != nil {
 		return err
 	}
@@ -160,13 +157,13 @@
 	return nil
 }
 
-// decryptPKCS1v15 decrypts ciphertext using priv and blinds the operation if
-// random is not nil. It returns one or zero in valid that indicates whether the
-// plaintext was correctly structured. In either case, the plaintext is
-// returned in em so that it may be read independently of whether it was valid
-// in order to maintain constant memory access patterns. If the plaintext was
-// valid then index contains the index of the original message in em.
-func decryptPKCS1v15(random io.Reader, priv *PrivateKey, ciphertext []byte) (valid int, em []byte, index int, err error) {
+// decryptPKCS1v15 decrypts ciphertext using priv. It returns one or zero in
+// valid that indicates whether the plaintext was correctly structured.
+// In either case, the plaintext is returned in em so that it may be read
+// independently of whether it was valid in order to maintain constant memory
+// access patterns. If the plaintext was valid then index contains the index of
+// the original message in em, to allow constant time padding removal.
+func decryptPKCS1v15(priv *PrivateKey, ciphertext []byte) (valid int, em []byte, index int, err error) {
 	k := priv.Size()
 	if k < 11 {
 		err = ErrDecryption
@@ -184,13 +181,10 @@
 			return
 		}
 	} else {
-		c := new(big.Int).SetBytes(ciphertext)
-		var m *big.Int
-		m, err = decrypt(random, priv, c)
+		em, err = decrypt(priv, ciphertext, noCheck)
 		if err != nil {
 			return
 		}
-		em = m.FillBytes(make([]byte, k))
 	}
 
 	firstByteIsZero := subtle.ConstantTimeByteEq(em[0], 0)
@@ -266,8 +260,7 @@
 // function. If hash is zero, hashed is signed directly. This isn't
 // advisable except for interoperability.
 //
-// If random is not nil then RSA blinding will be used to avoid timing
-// side-channel attacks.
+// The random parameter is legacy and ignored, and it can be as nil.
 //
 // This function is deterministic. Thus, if the set of possible
 // messages is small, an attacker may be able to build a map from
@@ -302,13 +295,7 @@
 	copy(em[k-tLen:k-hashLen], prefix)
 	copy(em[k-hashLen:k], hashed)
 
-	m := new(big.Int).SetBytes(em)
-	c, err := decryptAndCheck(random, priv, m)
-	if err != nil {
-		return nil, err
-	}
-
-	return c.FillBytes(em), nil
+	return decrypt(priv, em, withCheck)
 }
 
 // VerifyPKCS1v15 verifies an RSA PKCS #1 v1.5 signature.
@@ -346,9 +333,10 @@
 		return ErrVerification
 	}
 
-	c := new(big.Int).SetBytes(sig)
-	m := encrypt(new(big.Int), pub, c)
-	em := m.FillBytes(make([]byte, k))
+	em, err := encrypt(pub, sig)
+	if err != nil {
+		return ErrVerification
+	}
 	// EM = 0x00 || 0x01 || PS || 0x00 || T
 
 	ok := subtle.ConstantTimeByteEq(em[0], 0)
diff --git a/src/crypto/rsa/pkcs1v15_test.go b/src/crypto/rsa/pkcs1v15_test.go
index 69c509a..dfa1edd 100644
--- a/src/crypto/rsa/pkcs1v15_test.go
+++ b/src/crypto/rsa/pkcs1v15_test.go
@@ -2,18 +2,20 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package rsa
+package rsa_test
 
 import (
 	"bytes"
 	"crypto"
 	"crypto/rand"
+	. "crypto/rsa"
 	"crypto/sha1"
 	"crypto/sha256"
+	"crypto/x509"
 	"encoding/base64"
 	"encoding/hex"
+	"encoding/pem"
 	"io"
-	"math/big"
 	"testing"
 	"testing/quick"
 )
@@ -170,7 +172,7 @@
 	random := rand.Reader
 
 	b := make([]byte, 512)
-	err := nonZeroRandomBytes(b, random)
+	err := NonZeroRandomBytes(b, random)
 	if err != nil {
 		t.Errorf("returned error: %s", err)
 	}
@@ -276,34 +278,30 @@
 	}
 }
 
-// In order to generate new test vectors you'll need the PEM form of this key (and s/TESTING/PRIVATE/):
-// -----BEGIN RSA TESTING KEY-----
-// MIIBOgIBAAJBALKZD0nEffqM1ACuak0bijtqE2QrI/KLADv7l3kK3ppMyCuLKoF0
-// fd7Ai2KW5ToIwzFofvJcS/STa6HA5gQenRUCAwEAAQJBAIq9amn00aS0h/CrjXqu
-// /ThglAXJmZhOMPVn4eiu7/ROixi9sex436MaVeMqSNf7Ex9a8fRNfWss7Sqd9eWu
-// RTUCIQDasvGASLqmjeffBNLTXV2A5g4t+kLVCpsEIZAycV5GswIhANEPLmax0ME/
-// EO+ZJ79TJKN5yiGBRsv5yvx5UiHxajEXAiAhAol5N4EUyq6I9w1rYdhPMGpLfk7A
-// IU2snfRJ6Nq2CQIgFrPsWRCkV+gOYcajD17rEqmuLrdIRexpg8N1DOSXoJ8CIGlS
-// tAboUGBxTDq3ZroNism3DaMIbKPyYrAqhKov1h5V
-// -----END RSA TESTING KEY-----
+var rsaPrivateKey = parseKey(testingKey(`-----BEGIN RSA TESTING KEY-----
+MIIBOgIBAAJBALKZD0nEffqM1ACuak0bijtqE2QrI/KLADv7l3kK3ppMyCuLKoF0
+fd7Ai2KW5ToIwzFofvJcS/STa6HA5gQenRUCAwEAAQJBAIq9amn00aS0h/CrjXqu
+/ThglAXJmZhOMPVn4eiu7/ROixi9sex436MaVeMqSNf7Ex9a8fRNfWss7Sqd9eWu
+RTUCIQDasvGASLqmjeffBNLTXV2A5g4t+kLVCpsEIZAycV5GswIhANEPLmax0ME/
+EO+ZJ79TJKN5yiGBRsv5yvx5UiHxajEXAiAhAol5N4EUyq6I9w1rYdhPMGpLfk7A
+IU2snfRJ6Nq2CQIgFrPsWRCkV+gOYcajD17rEqmuLrdIRexpg8N1DOSXoJ8CIGlS
+tAboUGBxTDq3ZroNism3DaMIbKPyYrAqhKov1h5V
+-----END RSA TESTING KEY-----`))
 
-var rsaPrivateKey = &PrivateKey{
-	PublicKey: PublicKey{
-		N: fromBase10("9353930466774385905609975137998169297361893554149986716853295022578535724979677252958524466350471210367835187480748268864277464700638583474144061408845077"),
-		E: 65537,
-	},
-	D: fromBase10("7266398431328116344057699379749222532279343923819063639497049039389899328538543087657733766554155839834519529439851673014800261285757759040931985506583861"),
-	Primes: []*big.Int{
-		fromBase10("98920366548084643601728869055592650835572950932266967461790948584315647051443"),
-		fromBase10("94560208308847015747498523884063394671606671904944666360068158221458669711639"),
-	},
+func parsePublicKey(s string) *PublicKey {
+	p, _ := pem.Decode([]byte(s))
+	k, err := x509.ParsePKCS1PublicKey(p.Bytes)
+	if err != nil {
+		panic(err)
+	}
+	return k
 }
 
 func TestShortPKCS1v15Signature(t *testing.T) {
-	pub := &PublicKey{
-		E: 65537,
-		N: fromBase10("8272693557323587081220342447407965471608219912416565371060697606400726784709760494166080686904546560026343451112103559482851304715739629410219358933351333"),
-	}
+	pub := parsePublicKey(`-----BEGIN RSA PUBLIC KEY-----
+MEgCQQCd9BVzo775lkohasxjnefF1nCMcNoibqIWEVDe/K7M2GSoO4zlSQB+gkix
+O3AnTcdHB51iaZpWfxPSnew8yfulAgMBAAE=
+-----END RSA PUBLIC KEY-----`)
 	sig, err := hex.DecodeString("193a310d0dcf64094c6e3a00c8219b80ded70535473acff72c08e1222974bb24a93a535b1dc4c59fc0e65775df7ba2007dd20e9193f4c4025a18a7070aee93")
 	if err != nil {
 		t.Fatalf("failed to decode signature: %s", err)
diff --git a/src/crypto/rsa/pss.go b/src/crypto/rsa/pss.go
index 29e79bd..f7d23b5 100644
--- a/src/crypto/rsa/pss.go
+++ b/src/crypto/rsa/pss.go
@@ -13,7 +13,6 @@
 	"errors"
 	"hash"
 	"io"
-	"math/big"
 )
 
 // Per RFC 8017, Section 9.1
@@ -49,7 +48,7 @@
 	// 3.  If emLen < hLen + sLen + 2, output "encoding error" and stop.
 
 	if emLen < hLen+sLen+2 {
-		return nil, errors.New("crypto/rsa: key size too small for PSS signature")
+		return nil, ErrMessageTooLong
 	}
 
 	em := make([]byte, emLen)
@@ -208,7 +207,7 @@
 // Note that hashed must be the result of hashing the input message using the
 // given hash function. salt is a random sequence of bytes whose length will be
 // later used to verify the signature.
-func signPSSWithSalt(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed, salt []byte) ([]byte, error) {
+func signPSSWithSalt(priv *PrivateKey, hash crypto.Hash, hashed, salt []byte) ([]byte, error) {
 	emBits := priv.N.BitLen() - 1
 	em, err := emsaPSSEncode(hashed, emBits, salt, hash.New())
 	if err != nil {
@@ -220,7 +219,7 @@
 		if err != nil {
 			return nil, err
 		}
-		// Note: BoringCrypto takes care of the "AndCheck" part of "decryptAndCheck".
+		// Note: BoringCrypto always does decrypt "withCheck".
 		// (It's not just decrypt.)
 		s, err := boring.DecryptRSANoPadding(bkey, em)
 		if err != nil {
@@ -229,13 +228,20 @@
 		return s, nil
 	}
 
-	m := new(big.Int).SetBytes(em)
-	c, err := decryptAndCheck(rand, priv, m)
-	if err != nil {
-		return nil, err
+	// RFC 8017: "Note that the octet length of EM will be one less than k if
+	// modBits - 1 is divisible by 8 and equal to k otherwise, where k is the
+	// length in octets of the RSA modulus n." 🙄
+	//
+	// This is extremely annoying, as all other encrypt and decrypt inputs are
+	// always the exact same size as the modulus. Since it only happens for
+	// weird modulus sizes, fix it by padding inefficiently.
+	if emLen, k := len(em), priv.Size(); emLen < k {
+		emNew := make([]byte, k)
+		copy(emNew[k-emLen:], em)
+		em = emNew
 	}
-	s := make([]byte, priv.Size())
-	return c.FillBytes(s), nil
+
+	return decrypt(priv, em, withCheck)
 }
 
 const (
@@ -249,8 +255,8 @@
 
 // PSSOptions contains options for creating and verifying PSS signatures.
 type PSSOptions struct {
-	// SaltLength controls the length of the salt used in the PSS
-	// signature. It can either be a number of bytes, or one of the special
+	// SaltLength controls the length of the salt used in the PSS signature. It
+	// can either be a positive number of bytes, or one of the special
 	// PSSSaltLength constants.
 	SaltLength int
 
@@ -272,12 +278,23 @@
 	return opts.SaltLength
 }
 
+var invalidSaltLenErr = errors.New("crypto/rsa: PSSOptions.SaltLength cannot be negative")
+
 // SignPSS calculates the signature of digest using PSS.
 //
 // digest must be the result of hashing the input message using the given hash
 // function. The opts argument may be nil, in which case sensible defaults are
 // used. If opts.Hash is set, it overrides hash.
 func SignPSS(rand io.Reader, priv *PrivateKey, hash crypto.Hash, digest []byte, opts *PSSOptions) ([]byte, error) {
+	if boring.Enabled && rand == boring.RandReader {
+		bkey, err := boringPrivateKey(priv)
+		if err != nil {
+			return nil, err
+		}
+		return boring.SignRSAPSS(bkey, hash, digest, opts.saltLength())
+	}
+	boring.UnreachableExceptTests()
+
 	if opts != nil && opts.Hash != 0 {
 		hash = opts.Hash
 	}
@@ -286,24 +303,23 @@
 	switch saltLength {
 	case PSSSaltLengthAuto:
 		saltLength = (priv.N.BitLen()-1+7)/8 - 2 - hash.Size()
+		if saltLength < 0 {
+			return nil, ErrMessageTooLong
+		}
 	case PSSSaltLengthEqualsHash:
 		saltLength = hash.Size()
-	}
-
-	if boring.Enabled && rand == boring.RandReader {
-		bkey, err := boringPrivateKey(priv)
-		if err != nil {
-			return nil, err
+	default:
+		// If we get here saltLength is either > 0 or < -1, in the
+		// latter case we fail out.
+		if saltLength <= 0 {
+			return nil, invalidSaltLenErr
 		}
-		return boring.SignRSAPSS(bkey, hash, digest, saltLength)
 	}
-	boring.UnreachableExceptTests()
-
 	salt := make([]byte, saltLength)
 	if _, err := io.ReadFull(rand, salt); err != nil {
 		return nil, err
 	}
-	return signPSSWithSalt(rand, priv, hash, digest, salt)
+	return signPSSWithSalt(priv, hash, digest, salt)
 }
 
 // VerifyPSS verifies a PSS signature.
@@ -326,13 +342,31 @@
 	if len(sig) != pub.Size() {
 		return ErrVerification
 	}
-	s := new(big.Int).SetBytes(sig)
-	m := encrypt(new(big.Int), pub, s)
+	// Salt length must be either one of the special constants (-1 or 0)
+	// or otherwise positive. If it is < PSSSaltLengthEqualsHash (-1)
+	// we return an error.
+	if opts.saltLength() < PSSSaltLengthEqualsHash {
+		return invalidSaltLenErr
+	}
+
 	emBits := pub.N.BitLen() - 1
 	emLen := (emBits + 7) / 8
-	if m.BitLen() > emLen*8 {
+	em, err := encrypt(pub, sig)
+	if err != nil {
 		return ErrVerification
 	}
-	em := m.FillBytes(make([]byte, emLen))
+
+	// Like in signPSSWithSalt, deal with mismatches between emLen and the size
+	// of the modulus. The spec would have us wire emLen into the encoding
+	// function, but we'd rather always encode to the size of the modulus and
+	// then strip leading zeroes if necessary. This only happens for weird
+	// modulus sizes anyway.
+	for len(em) > emLen && len(em) > 0 {
+		if em[0] != 0 {
+			return ErrVerification
+		}
+		em = em[1:]
+	}
+
 	return emsaPSSVerify(digest, em, emBits, opts.saltLength(), hash.New())
 }
diff --git a/src/crypto/rsa/pss_test.go b/src/crypto/rsa/pss_test.go
index 51f9760..cf03e3c 100644
--- a/src/crypto/rsa/pss_test.go
+++ b/src/crypto/rsa/pss_test.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package rsa
+package rsa_test
 
 import (
 	"bufio"
@@ -10,6 +10,7 @@
 	"compress/bzip2"
 	"crypto"
 	"crypto/rand"
+	. "crypto/rsa"
 	"crypto/sha1"
 	"crypto/sha256"
 	"encoding/hex"
@@ -60,7 +61,7 @@
 	hash.Write(msg)
 	hashed := hash.Sum(nil)
 
-	encoded, err := emsaPSSEncode(hashed, 1023, salt, sha1.New())
+	encoded, err := EMSAPSSEncode(hashed, 1023, salt, sha1.New())
 	if err != nil {
 		t.Errorf("Error from emsaPSSEncode: %s\n", err)
 	}
@@ -68,7 +69,7 @@
 		t.Errorf("Bad encoding. got %x, want %x", encoded, expected)
 	}
 
-	if err = emsaPSSVerify(hashed, encoded, 1023, len(salt), sha1.New()); err != nil {
+	if err = EMSAPSSVerify(hashed, encoded, 1023, len(salt), sha1.New()); err != nil {
 		t.Errorf("Bad verification: %s", err)
 	}
 }
@@ -208,6 +209,9 @@
 		{PSSSaltLengthEqualsHash, 8, false},
 		{PSSSaltLengthAuto, PSSSaltLengthEqualsHash, false},
 		{8, 8, true},
+		{PSSSaltLengthAuto, 42, true},
+		{PSSSaltLengthAuto, 20, false},
+		{PSSSaltLengthAuto, -2, false},
 	}
 
 	hash := crypto.SHA1
@@ -232,7 +236,10 @@
 	}
 }
 
-func TestSignWithPSSSaltLengthAuto(t *testing.T) {
+func TestPSS513(t *testing.T) {
+	// See Issue 42741, and separately, RFC 8017: "Note that the octet length of
+	// EM will be one less than k if modBits - 1 is divisible by 8 and equal to
+	// k otherwise, where k is the length in octets of the RSA modulus n."
 	key, err := GenerateKey(rand.Reader, 513)
 	if err != nil {
 		t.Fatal(err)
@@ -245,8 +252,9 @@
 	if err != nil {
 		t.Fatal(err)
 	}
-	if len(signature) == 0 {
-		t.Fatal("empty signature returned")
+	err = VerifyPSS(&key.PublicKey, crypto.SHA256, digest[:], signature, nil)
+	if err != nil {
+		t.Error(err)
 	}
 }
 
@@ -273,3 +281,28 @@
 	}
 	return s
 }
+
+func TestInvalidPSSSaltLength(t *testing.T) {
+	key, err := GenerateKey(rand.Reader, 245)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	digest := sha256.Sum256([]byte("message"))
+	// We don't check the exact error matches, because crypto/rsa and crypto/internal/boring
+	// return two different error variables, which have the same content but are not equal.
+	if _, err := SignPSS(rand.Reader, key, crypto.SHA256, digest[:], &PSSOptions{
+		SaltLength: -2,
+		Hash:       crypto.SHA256,
+	}); err.Error() != InvalidSaltLenErr.Error() {
+		t.Fatalf("SignPSS unexpected error: got %v, want %v", err, InvalidSaltLenErr)
+	}
+
+	// We don't check the specific error here, because crypto/rsa and crypto/internal/boring
+	// return different errors, so we just check that _an error_ was returned.
+	if err := VerifyPSS(&key.PublicKey, crypto.SHA256, []byte{1, 2, 3}, make([]byte, 31), &PSSOptions{
+		SaltLength: -2,
+	}); err == nil {
+		t.Fatal("VerifyPSS unexpected success")
+	}
+}
diff --git a/src/crypto/rsa/rsa.go b/src/crypto/rsa/rsa.go
index c941124..11f87e8 100644
--- a/src/crypto/rsa/rsa.go
+++ b/src/crypto/rsa/rsa.go
@@ -19,16 +19,21 @@
 // over the public key primitive, the PrivateKey type implements the
 // Decrypter and Signer interfaces from the crypto package.
 //
-// The RSA operations in this package are not implemented using constant-time algorithms.
+// Operations in this package are implemented using constant-time algorithms,
+// except for [GenerateKey], [PrivateKey.Precompute], and [PrivateKey.Validate].
+// Every other operation only leaks the bit size of the involved values, which
+// all depend on the selected key size.
 package rsa
 
 import (
 	"crypto"
+	"crypto/internal/bigmod"
 	"crypto/internal/boring"
 	"crypto/internal/boring/bbig"
 	"crypto/internal/randutil"
 	"crypto/rand"
 	"crypto/subtle"
+	"encoding/binary"
 	"errors"
 	"hash"
 	"io"
@@ -36,7 +41,6 @@
 	"math/big"
 )
 
-var bigZero = big.NewInt(0)
 var bigOne = big.NewInt(1)
 
 // A PublicKey represents the public part of an RSA key.
@@ -68,6 +72,11 @@
 type OAEPOptions struct {
 	// Hash is the hash function that will be used when generating the mask.
 	Hash crypto.Hash
+
+	// MGFHash is the hash function used for MGF1.
+	// If zero, Hash is used instead.
+	MGFHash crypto.Hash
+
 	// Label is an arbitrary byte string that must be equal to the value
 	// used when encrypting.
 	Label []byte
@@ -103,8 +112,9 @@
 	D         *big.Int   // private exponent
 	Primes    []*big.Int // prime factors of N, has >= 2 elements.
 
-	// Precomputed contains precomputed values that speed up private
-	// operations, if available.
+	// Precomputed contains precomputed values that speed up RSA operations,
+	// if available. It must be generated by calling PrivateKey.Precompute and
+	// must not be modified.
 	Precomputed PrecomputedValues
 }
 
@@ -160,7 +170,11 @@
 
 	switch opts := opts.(type) {
 	case *OAEPOptions:
-		return DecryptOAEP(opts.Hash.New(), rand, priv, ciphertext, opts.Label)
+		if opts.MGFHash == 0 {
+			return decryptOAEP(opts.Hash.New(), opts.Hash.New(), rand, priv, ciphertext, opts.Label)
+		} else {
+			return decryptOAEP(opts.Hash.New(), opts.MGFHash.New(), rand, priv, ciphertext, opts.Label)
+		}
 
 	case *PKCS1v15DecryptOptions:
 		if l := opts.SessionKeyLen; l > 0 {
@@ -189,7 +203,14 @@
 	// historical accident, the CRT for the first two primes is handled
 	// differently in PKCS #1 and interoperability is sufficiently
 	// important that we mirror this.
+	//
+	// Note: these values are still filled in by Precompute for
+	// backwards compatibility but are not used. Multi-prime RSA is very rare,
+	// and is implemented by this package without CRT optimizations to limit
+	// complexity.
 	CRTValues []CRTValue
+
+	n, p, q *bigmod.Modulus // moduli for CRT with Montgomery precomputed constants
 }
 
 // CRTValue contains the precomputed Chinese remainder theorem values.
@@ -244,16 +265,24 @@
 }
 
 // GenerateMultiPrimeKey generates a multi-prime RSA keypair of the given bit
-// size and the given random source, as suggested in [1]. Although the public
-// keys are compatible (actually, indistinguishable) from the 2-prime case,
-// the private keys are not. Thus it may not be possible to export multi-prime
-// private keys in certain formats or to subsequently import them into other
-// code.
+// size and the given random source.
 //
-// Table 1 in [2] suggests maximum numbers of primes for a given size.
+// Table 1 in "[On the Security of Multi-prime RSA]" suggests maximum numbers of
+// primes for a given bit size.
 //
-// [1] US patent 4405829 (1972, expired)
-// [2] http://www.cacr.math.uwaterloo.ca/techreports/2006/cacr2006-16.pdf
+// Although the public keys are compatible (actually, indistinguishable) from
+// the 2-prime case, the private keys are not. Thus it may not be possible to
+// export multi-prime private keys in certain formats or to subsequently import
+// them into other code.
+//
+// This package does not implement CRT optimizations for multi-prime RSA, so the
+// keys with more than two primes will have worse performance.
+//
+// Note: The use of this function with a number of primes different from
+// two is not recommended for the above security, compatibility, and performance
+// reasons. Use GenerateKey instead.
+//
+// [On the Security of Multi-prime RSA]: http://www.cacr.math.uwaterloo.ca/techreports/2006/cacr2006-16.pdf
 func GenerateMultiPrimeKey(random io.Reader, nprimes int, bits int) (*PrivateKey, error) {
 	randutil.MaybeReadByte(random)
 
@@ -286,6 +315,9 @@
 				Dq:        Dq,
 				Qinv:      Qinv,
 				CRTValues: make([]CRTValue, 0), // non-nil, to match Precompute
+				n:         bigmod.NewModulusFromBig(N),
+				p:         bigmod.NewModulusFromBig(P),
+				q:         bigmod.NewModulusFromBig(Q),
 			},
 		}
 		return key, nil
@@ -415,15 +447,33 @@
 	}
 }
 
-// ErrMessageTooLong is returned when attempting to encrypt a message which is
-// too large for the size of the public key.
-var ErrMessageTooLong = errors.New("crypto/rsa: message too long for RSA public key size")
+// ErrMessageTooLong is returned when attempting to encrypt or sign a message
+// which is too large for the size of the key. When using SignPSS, this can also
+// be returned if the size of the salt is too large.
+var ErrMessageTooLong = errors.New("crypto/rsa: message too long for RSA key size")
 
-func encrypt(c *big.Int, pub *PublicKey, m *big.Int) *big.Int {
+func encrypt(pub *PublicKey, plaintext []byte) ([]byte, error) {
 	boring.Unreachable()
-	e := big.NewInt(int64(pub.E))
-	c.Exp(m, e, pub.N)
-	return c
+
+	N := bigmod.NewModulusFromBig(pub.N)
+	m, err := bigmod.NewNat().SetBytes(plaintext, N)
+	if err != nil {
+		return nil, err
+	}
+	e := intToBytes(pub.E)
+
+	return bigmod.NewNat().Exp(m, e, N).Bytes(N), nil
+}
+
+// intToBytes returns i as a big-endian slice of bytes with no leading zeroes,
+// leaking only the bit size of i through timing side-channels.
+func intToBytes(i int) []byte {
+	b := make([]byte, 8)
+	binary.BigEndian.PutUint64(b, uint64(i))
+	for len(b) > 1 && b[0] == 0 {
+		b = b[1:]
+	}
+	return b
 }
 
 // EncryptOAEP encrypts the given message with RSA-OAEP.
@@ -458,7 +508,7 @@
 		if err != nil {
 			return nil, err
 		}
-		return boring.EncryptRSAOAEP(hash, bkey, msg, label)
+		return boring.EncryptRSAOAEP(hash, hash, bkey, msg, label)
 	}
 	boring.UnreachableExceptTests()
 
@@ -491,12 +541,7 @@
 		return boring.EncryptRSANoPadding(bkey, em)
 	}
 
-	m := new(big.Int)
-	m.SetBytes(em)
-	c := encrypt(new(big.Int), pub, m)
-
-	out := make([]byte, k)
-	return c.FillBytes(out), nil
+	return encrypt(pub, em)
 }
 
 // ErrDecryption represents a failure to decrypt a message.
@@ -510,6 +555,13 @@
 // Precompute performs some calculations that speed up private key operations
 // in the future.
 func (priv *PrivateKey) Precompute() {
+	if priv.Precomputed.n == nil && len(priv.Primes) == 2 {
+		priv.Precomputed.n = bigmod.NewModulusFromBig(priv.N)
+		priv.Precomputed.p = bigmod.NewModulusFromBig(priv.Primes[0])
+		priv.Precomputed.q = bigmod.NewModulusFromBig(priv.Primes[1])
+	}
+
+	// Fill in the backwards-compatibility *big.Int values.
 	if priv.Precomputed.Dp != nil {
 		return
 	}
@@ -538,104 +590,64 @@
 	}
 }
 
-// decrypt performs an RSA decryption, resulting in a plaintext integer. If a
-// random source is given, RSA blinding is used.
-func decrypt(random io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int, err error) {
+const withCheck = true
+const noCheck = false
+
+// decrypt performs an RSA decryption of ciphertext into out. If check is true,
+// m^e is calculated and compared with ciphertext, in order to defend against
+// errors in the CRT computation.
+func decrypt(priv *PrivateKey, ciphertext []byte, check bool) ([]byte, error) {
 	if len(priv.Primes) <= 2 {
 		boring.Unreachable()
 	}
-	// TODO(agl): can we get away with reusing blinds?
-	if c.Cmp(priv.N) > 0 {
-		err = ErrDecryption
-		return
-	}
-	if priv.N.Sign() == 0 {
-		return nil, ErrDecryption
-	}
 
-	var ir *big.Int
-	if random != nil {
-		randutil.MaybeReadByte(random)
-
-		// Blinding enabled. Blinding involves multiplying c by r^e.
-		// Then the decryption operation performs (m^e * r^e)^d mod n
-		// which equals mr mod n. The factor of r can then be removed
-		// by multiplying by the multiplicative inverse of r.
-
-		var r *big.Int
-		ir = new(big.Int)
-		for {
-			r, err = rand.Int(random, priv.N)
-			if err != nil {
-				return
-			}
-			if r.Cmp(bigZero) == 0 {
-				r = bigOne
-			}
-			ok := ir.ModInverse(r, priv.N)
-			if ok != nil {
-				break
-			}
+	var (
+		err  error
+		m, c *bigmod.Nat
+		N    *bigmod.Modulus
+		t0   = bigmod.NewNat()
+	)
+	if priv.Precomputed.n == nil {
+		N = bigmod.NewModulusFromBig(priv.N)
+		c, err = bigmod.NewNat().SetBytes(ciphertext, N)
+		if err != nil {
+			return nil, ErrDecryption
 		}
-		bigE := big.NewInt(int64(priv.E))
-		rpowe := new(big.Int).Exp(r, bigE, priv.N) // N != 0
-		cCopy := new(big.Int).Set(c)
-		cCopy.Mul(cCopy, rpowe)
-		cCopy.Mod(cCopy, priv.N)
-		c = cCopy
-	}
-
-	if priv.Precomputed.Dp == nil {
-		m = new(big.Int).Exp(c, priv.D, priv.N)
+		m = bigmod.NewNat().Exp(c, priv.D.Bytes(), N)
 	} else {
-		// We have the precalculated values needed for the CRT.
-		m = new(big.Int).Exp(c, priv.Precomputed.Dp, priv.Primes[0])
-		m2 := new(big.Int).Exp(c, priv.Precomputed.Dq, priv.Primes[1])
-		m.Sub(m, m2)
-		if m.Sign() < 0 {
-			m.Add(m, priv.Primes[0])
+		N = priv.Precomputed.n
+		P, Q := priv.Precomputed.p, priv.Precomputed.q
+		Qinv, err := bigmod.NewNat().SetBytes(priv.Precomputed.Qinv.Bytes(), P)
+		if err != nil {
+			return nil, ErrDecryption
 		}
-		m.Mul(m, priv.Precomputed.Qinv)
-		m.Mod(m, priv.Primes[0])
-		m.Mul(m, priv.Primes[1])
-		m.Add(m, m2)
+		c, err = bigmod.NewNat().SetBytes(ciphertext, N)
+		if err != nil {
+			return nil, ErrDecryption
+		}
 
-		for i, values := range priv.Precomputed.CRTValues {
-			prime := priv.Primes[2+i]
-			m2.Exp(c, values.Exp, prime)
-			m2.Sub(m2, m)
-			m2.Mul(m2, values.Coeff)
-			m2.Mod(m2, prime)
-			if m2.Sign() < 0 {
-				m2.Add(m2, prime)
-			}
-			m2.Mul(m2, values.R)
-			m.Add(m, m2)
+		// m = c ^ Dp mod p
+		m = bigmod.NewNat().Exp(t0.Mod(c, P), priv.Precomputed.Dp.Bytes(), P)
+		// m2 = c ^ Dq mod q
+		m2 := bigmod.NewNat().Exp(t0.Mod(c, Q), priv.Precomputed.Dq.Bytes(), Q)
+		// m = m - m2 mod p
+		m.Sub(t0.Mod(m2, P), P)
+		// m = m * Qinv mod p
+		m.Mul(Qinv, P)
+		// m = m * q mod N
+		m.ExpandFor(N).Mul(t0.Mod(Q.Nat(), N), N)
+		// m = m + m2 mod N
+		m.Add(m2.ExpandFor(N), N)
+	}
+
+	if check {
+		c1 := bigmod.NewNat().Exp(m, intToBytes(priv.E), N)
+		if c1.Equal(c) != 1 {
+			return nil, ErrDecryption
 		}
 	}
 
-	if ir != nil {
-		// Unblind.
-		m.Mul(m, ir)
-		m.Mod(m, priv.N)
-	}
-
-	return
-}
-
-func decryptAndCheck(random io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int, err error) {
-	m, err = decrypt(random, priv, c)
-	if err != nil {
-		return nil, err
-	}
-
-	// In order to defend against errors in the CRT computation, m^e is
-	// calculated, which should match the original ciphertext.
-	check := encrypt(new(big.Int), &priv.PublicKey, m)
-	if c.Cmp(check) != 0 {
-		return nil, errors.New("rsa: internal error")
-	}
-	return m, nil
+	return m.Bytes(N), nil
 }
 
 // DecryptOAEP decrypts ciphertext using RSA-OAEP.
@@ -644,13 +656,15 @@
 // Encryption and decryption of a given message must use the same hash function
 // and sha256.New() is a reasonable choice.
 //
-// The random parameter, if not nil, is used to blind the private-key operation
-// and avoid timing side-channel attacks. Blinding is purely internal to this
-// function – the random data need not match that used when encrypting.
+// The random parameter is legacy and ignored, and it can be as nil.
 //
 // The label parameter must match the value given when encrypting. See
 // EncryptOAEP for details.
 func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext []byte, label []byte) ([]byte, error) {
+	return decryptOAEP(hash, hash, random, priv, ciphertext, label)
+}
+
+func decryptOAEP(hash, mgfHash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext []byte, label []byte) ([]byte, error) {
 	if err := checkPub(&priv.PublicKey); err != nil {
 		return nil, err
 	}
@@ -665,15 +679,14 @@
 		if err != nil {
 			return nil, err
 		}
-		out, err := boring.DecryptRSAOAEP(hash, bkey, ciphertext, label)
+		out, err := boring.DecryptRSAOAEP(hash, mgfHash, bkey, ciphertext, label)
 		if err != nil {
 			return nil, ErrDecryption
 		}
 		return out, nil
 	}
-	c := new(big.Int).SetBytes(ciphertext)
 
-	m, err := decrypt(random, priv, c)
+	em, err := decrypt(priv, ciphertext, noCheck)
 	if err != nil {
 		return nil, err
 	}
@@ -682,17 +695,13 @@
 	lHash := hash.Sum(nil)
 	hash.Reset()
 
-	// We probably leak the number of leading zeros.
-	// It's not clear that we can do anything about this.
-	em := m.FillBytes(make([]byte, k))
-
 	firstByteIsZero := subtle.ConstantTimeByteEq(em[0], 0)
 
 	seed := em[1 : hash.Size()+1]
 	db := em[hash.Size()+1:]
 
-	mgf1XOR(seed, hash, db)
-	mgf1XOR(db, hash, seed)
+	mgf1XOR(seed, mgfHash, db)
+	mgf1XOR(db, mgfHash, seed)
 
 	lHash2 := db[0:hash.Size()]
 
diff --git a/src/crypto/rsa/rsa_export_test.go b/src/crypto/rsa/rsa_export_test.go
new file mode 100644
index 0000000..70406de
--- /dev/null
+++ b/src/crypto/rsa/rsa_export_test.go
@@ -0,0 +1,10 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package rsa
+
+var NonZeroRandomBytes = nonZeroRandomBytes
+var EMSAPSSEncode = emsaPSSEncode
+var EMSAPSSVerify = emsaPSSVerify
+var InvalidSaltLenErr = invalidSaltLenErr
diff --git a/src/crypto/rsa/rsa_test.go b/src/crypto/rsa/rsa_test.go
index 766d9a9..3278a7f 100644
--- a/src/crypto/rsa/rsa_test.go
+++ b/src/crypto/rsa/rsa_test.go
@@ -2,21 +2,27 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package rsa
+package rsa_test
 
 import (
+	"bufio"
 	"bytes"
 	"crypto"
+	"crypto/internal/boring"
 	"crypto/rand"
+	. "crypto/rsa"
 	"crypto/sha1"
 	"crypto/sha256"
+	"crypto/x509"
+	"encoding/pem"
+	"flag"
 	"fmt"
+	"internal/testenv"
 	"math/big"
+	"strings"
 	"testing"
 )
 
-import "crypto/internal/boring"
-
 func TestKeyGeneration(t *testing.T) {
 	for _, size := range []int{128, 1024, 2048, 3072} {
 		priv, err := GenerateKey(rand.Reader, size)
@@ -92,17 +98,11 @@
 	// This is a key generated by `certtool --generate-privkey --bits 128`.
 	// It's such that de ≢ 1 mod φ(n), but is congruent mod the order of
 	// the group.
-	priv := &PrivateKey{
-		PublicKey: PublicKey{
-			N: fromBase10("290684273230919398108010081414538931343"),
-			E: 65537,
-		},
-		D: fromBase10("31877380284581499213530787347443987241"),
-		Primes: []*big.Int{
-			fromBase10("16775196964030542637"),
-			fromBase10("17328218193455850539"),
-		},
-	}
+	priv := parseKey(testingKey(`-----BEGIN RSA TESTING KEY-----
+MGECAQACEQDar8EuoZuSosYtE9SeXSyPAgMBAAECEBf7XDET8e6jjTcfO7y/sykC
+CQDozXjCjkBzLQIJAPB6MqNbZaQrAghbZTdQoko5LQIIUp9ZiKDdYjMCCCCpqzmX
+d8Y7
+-----END RSA TESTING KEY-----`))
 	testKeyBasics(t, priv)
 }
 
@@ -114,125 +114,501 @@
 		t.Errorf("private exponent too large")
 	}
 
+	msg := []byte("hi!")
+	enc, err := EncryptPKCS1v15(rand.Reader, &priv.PublicKey, msg)
+	if err != nil {
+		t.Errorf("EncryptPKCS1v15: %v", err)
+		return
+	}
+
+	dec, err := DecryptPKCS1v15(nil, priv, enc)
+	if err != nil {
+		t.Errorf("DecryptPKCS1v15: %v", err)
+		return
+	}
+	if !bytes.Equal(dec, msg) {
+		t.Errorf("got:%x want:%x (%+v)", dec, msg, priv)
+	}
+}
+
+func TestAllocations(t *testing.T) {
 	if boring.Enabled {
-		// Cannot call encrypt/decrypt directly. Test via PKCS1v15.
-		msg := []byte("hi!")
-		enc, err := EncryptPKCS1v15(rand.Reader, &priv.PublicKey, msg)
+		t.Skip("skipping allocations test with BoringCrypto")
+	}
+	testenv.SkipIfOptimizationOff(t)
+
+	m := []byte("Hello Gophers")
+	c, err := EncryptPKCS1v15(rand.Reader, &test2048Key.PublicKey, m)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if allocs := testing.AllocsPerRun(100, func() {
+		p, err := DecryptPKCS1v15(nil, test2048Key, c)
 		if err != nil {
-			t.Errorf("EncryptPKCS1v15: %v", err)
-			return
+			t.Fatal(err)
 		}
-		dec, err := DecryptPKCS1v15(rand.Reader, priv, enc)
+		if !bytes.Equal(p, m) {
+			t.Fatalf("unexpected output: %q", p)
+		}
+	}); allocs > 10 {
+		t.Errorf("expected less than 10 allocations, got %0.1f", allocs)
+	}
+}
+
+var allFlag = flag.Bool("all", false, "test all key sizes up to 2048")
+
+func TestEverything(t *testing.T) {
+	min := 32
+	max := 560 // any smaller than this and not all tests will run
+	if testing.Short() {
+		min = max
+	}
+	if *allFlag {
+		max = 2048
+	}
+	for size := min; size <= max; size++ {
+		size := size
+		t.Run(fmt.Sprintf("%d", size), func(t *testing.T) {
+			t.Parallel()
+			priv, err := GenerateKey(rand.Reader, size)
+			if err != nil {
+				t.Errorf("GenerateKey(%d): %v", size, err)
+			}
+			if bits := priv.N.BitLen(); bits != size {
+				t.Errorf("key too short (%d vs %d)", bits, size)
+			}
+			testEverything(t, priv)
+		})
+	}
+}
+
+func testEverything(t *testing.T, priv *PrivateKey) {
+	if err := priv.Validate(); err != nil {
+		t.Errorf("Validate() failed: %s", err)
+	}
+
+	msg := []byte("test")
+	enc, err := EncryptPKCS1v15(rand.Reader, &priv.PublicKey, msg)
+	if err == ErrMessageTooLong {
+		t.Log("key too small for EncryptPKCS1v15")
+	} else if err != nil {
+		t.Errorf("EncryptPKCS1v15: %v", err)
+	}
+	if err == nil {
+		dec, err := DecryptPKCS1v15(nil, priv, enc)
 		if err != nil {
 			t.Errorf("DecryptPKCS1v15: %v", err)
-			return
+		}
+		err = DecryptPKCS1v15SessionKey(nil, priv, enc, make([]byte, 4))
+		if err != nil {
+			t.Errorf("DecryptPKCS1v15SessionKey: %v", err)
 		}
 		if !bytes.Equal(dec, msg) {
 			t.Errorf("got:%x want:%x (%+v)", dec, msg, priv)
 		}
-		return
 	}
 
-	pub := &priv.PublicKey
-	m := big.NewInt(42)
-	c := encrypt(new(big.Int), pub, m)
+	label := []byte("label")
+	enc, err = EncryptOAEP(sha256.New(), rand.Reader, &priv.PublicKey, msg, label)
+	if err == ErrMessageTooLong {
+		t.Log("key too small for EncryptOAEP")
+	} else if err != nil {
+		t.Errorf("EncryptOAEP: %v", err)
+	}
+	if err == nil {
+		dec, err := DecryptOAEP(sha256.New(), nil, priv, enc, label)
+		if err != nil {
+			t.Errorf("DecryptOAEP: %v", err)
+		}
+		if !bytes.Equal(dec, msg) {
+			t.Errorf("got:%x want:%x (%+v)", dec, msg, priv)
+		}
+	}
 
-	m2, err := decrypt(nil, priv, c)
+	hash := sha256.Sum256(msg)
+	sig, err := SignPKCS1v15(nil, priv, crypto.SHA256, hash[:])
+	if err == ErrMessageTooLong {
+		t.Log("key too small for SignPKCS1v15")
+	} else if err != nil {
+		t.Errorf("SignPKCS1v15: %v", err)
+	}
+	if err == nil {
+		err = VerifyPKCS1v15(&priv.PublicKey, crypto.SHA256, hash[:], sig)
+		if err != nil {
+			t.Errorf("VerifyPKCS1v15: %v", err)
+		}
+		sig[1] ^= 0x80
+		err = VerifyPKCS1v15(&priv.PublicKey, crypto.SHA256, hash[:], sig)
+		if err == nil {
+			t.Errorf("VerifyPKCS1v15 success for tampered signature")
+		}
+		sig[1] ^= 0x80
+		hash[1] ^= 0x80
+		err = VerifyPKCS1v15(&priv.PublicKey, crypto.SHA256, hash[:], sig)
+		if err == nil {
+			t.Errorf("VerifyPKCS1v15 success for tampered message")
+		}
+		hash[1] ^= 0x80
+	}
+
+	opts := &PSSOptions{SaltLength: PSSSaltLengthAuto}
+	sig, err = SignPSS(rand.Reader, priv, crypto.SHA256, hash[:], opts)
+	if err == ErrMessageTooLong {
+		t.Log("key too small for SignPSS with PSSSaltLengthAuto")
+	} else if err != nil {
+		t.Errorf("SignPSS: %v", err)
+	}
+	if err == nil {
+		err = VerifyPSS(&priv.PublicKey, crypto.SHA256, hash[:], sig, opts)
+		if err != nil {
+			t.Errorf("VerifyPSS: %v", err)
+		}
+		sig[1] ^= 0x80
+		err = VerifyPSS(&priv.PublicKey, crypto.SHA256, hash[:], sig, opts)
+		if err == nil {
+			t.Errorf("VerifyPSS success for tampered signature")
+		}
+		sig[1] ^= 0x80
+		hash[1] ^= 0x80
+		err = VerifyPSS(&priv.PublicKey, crypto.SHA256, hash[:], sig, opts)
+		if err == nil {
+			t.Errorf("VerifyPSS success for tampered message")
+		}
+		hash[1] ^= 0x80
+	}
+
+	opts.SaltLength = PSSSaltLengthEqualsHash
+	sig, err = SignPSS(rand.Reader, priv, crypto.SHA256, hash[:], opts)
+	if err == ErrMessageTooLong {
+		t.Log("key too small for SignPSS with PSSSaltLengthEqualsHash")
+	} else if err != nil {
+		t.Errorf("SignPSS: %v", err)
+	}
+	if err == nil {
+		err = VerifyPSS(&priv.PublicKey, crypto.SHA256, hash[:], sig, opts)
+		if err != nil {
+			t.Errorf("VerifyPSS: %v", err)
+		}
+		sig[1] ^= 0x80
+		err = VerifyPSS(&priv.PublicKey, crypto.SHA256, hash[:], sig, opts)
+		if err == nil {
+			t.Errorf("VerifyPSS success for tampered signature")
+		}
+		sig[1] ^= 0x80
+		hash[1] ^= 0x80
+		err = VerifyPSS(&priv.PublicKey, crypto.SHA256, hash[:], sig, opts)
+		if err == nil {
+			t.Errorf("VerifyPSS success for tampered message")
+		}
+		hash[1] ^= 0x80
+	}
+
+	// Check that an input bigger than the modulus is handled correctly,
+	// whether it is longer than the byte size of the modulus or not.
+	c := bytes.Repeat([]byte{0xff}, priv.Size())
+	err = VerifyPSS(&priv.PublicKey, crypto.SHA256, hash[:], c, opts)
+	if err == nil {
+		t.Errorf("VerifyPSS accepted a large signature")
+	}
+	_, err = DecryptPKCS1v15(nil, priv, c)
+	if err == nil {
+		t.Errorf("DecryptPKCS1v15 accepted a large ciphertext")
+	}
+	c = append(c, 0xff)
+	err = VerifyPSS(&priv.PublicKey, crypto.SHA256, hash[:], c, opts)
+	if err == nil {
+		t.Errorf("VerifyPSS accepted a long signature")
+	}
+	_, err = DecryptPKCS1v15(nil, priv, c)
+	if err == nil {
+		t.Errorf("DecryptPKCS1v15 accepted a long ciphertext")
+	}
+}
+
+func testingKey(s string) string { return strings.ReplaceAll(s, "TESTING KEY", "PRIVATE KEY") }
+
+func parseKey(s string) *PrivateKey {
+	p, _ := pem.Decode([]byte(s))
+	k, err := x509.ParsePKCS1PrivateKey(p.Bytes)
 	if err != nil {
-		t.Errorf("error while decrypting: %s", err)
-		return
+		panic(err)
 	}
-	if m.Cmp(m2) != 0 {
-		t.Errorf("got:%v, want:%v (%+v)", m2, m, priv)
-	}
+	return k
+}
 
-	m3, err := decrypt(rand.Reader, priv, c)
+var test2048Key = parseKey(testingKey(`-----BEGIN RSA TESTING KEY-----
+MIIEnwIBAAKCAQBxY8hCshkKiXCUKydkrtQtQSRke28w4JotocDiVqou4k55DEDJ
+akvWbXXDcakV4HA8R2tOGgbxvTjFo8EK470w9O9ipapPUSrRRaBsSOlkaaIs6OYh
+4FLwZpqMNBVVEtguVUR/C34Y2pS9kRrHs6q+cGhDZolkWT7nGy5eSEvPDHg0EBq1
+1hu6HmPmI3r0BInONqJg2rcK3U++wk1lnbD3ysCZsKOqRUms3n/IWKeTqXXmz2XK
+J2t0NSXwiDmA9q0Gm+w0bXh3lzhtUP4MlzS+lnx9hK5bjzSbCUB5RXwMDG/uNMQq
+C4MmA4BPceSfMyAIFjdRLGy/K7gbb2viOYRtAgEDAoIBAEuX2tchZgcGSw1yGkMf
+OB4rbZhSSiCVvB5r1ew5xsnsNFCy1ducMo7zo9ehG2Pq9X2E8jQRWfZ+JdkX1gdC
+fiCjSkHDxt+LceDZFZ2F8O2bwXNF7sFAN0rvEbLNY44MkB7jgv9c/rs8YykLZy/N
+HH71mteZsO2Q1JoSHumFh99cwWHFhLxYh64qFeeH6Gqx6AM2YVBWHgs7OuKOvc8y
+zUbf8xftPht1kMwwDR1XySiEYtBtn74JflK3DcT8oxOuCZBuX6sMJHKbVP41zDj+
+FJZBmpAvNfCEYJUr1Hg+DpMLqLUg+D6v5vpliburbk9LxcKFZyyZ9QVe7GoqMLBu
+eGsCgYEAummUj4MMKWJC2mv5rj/dt2pj2/B2HtP2RLypai4et1/Ru9nNk8cjMLzC
+qXz6/RLuJ7/eD7asFS3y7EqxKxEmW0G8tTHjnzR/3wnpVipuWnwCDGU032HJVd13
+LMe51GH97qLzuDZjMCz+VlbCNdSslMgWWK0XmRnN7Yqxvh6ao2kCgYEAm7fTRBhF
+JtKcaJ7d8BQb9l8BNHfjayYOMq5CxoCyxa2pGBv/Mrnxv73Twp9Z/MP0ue5M5nZt
+GMovpP5cGdJLQ2w5p4H3opcuWeYW9Yyru2EyCEAI/hD/Td3QVP0ukc19BDuPl5Wg
+eIFs218uiVOU4pw3w+Et5B1PZ/F+ZLr5LGUCgYB8RmMKV11w7CyRnVEe1T56Ru09
+Svlp4qQt0xucHr8k6ovSkTO32hd10yxw/fyot0lv1T61JHK4yUydhyDHYMQ81n3O
+IUJqIv/qBpuOxvQ8UqwIQ3iU69uOk6TIhSaNlqlJwffQJEIgHf7kOdbOjchjMA7l
+yLpmETPzscvUFGcXmwKBgGfP4i1lg283EvBp6Uq4EqQ/ViL6l5zECXce1y8Ady5z
+xhASqiHRS9UpN9cU5qiCoyae3e75nhCGym3+6BE23Nede8UBT8G6HuaZZKOzHSeW
+IVrVW1QLVN6T4DioybaI/gLSX7pjwFBWSJI/dFuNDexoJS1AyUK+NO/2VEMnUMhD
+AoGAOsdn3Prnh/mjC95vraHCLap0bRBSexMdx77ImHgtFUUcSaT8DJHs+NZw1RdM
+SZA0J+zVQ8q7B11jIgz5hMz+chedwoRjTL7a8VRTKHFmmBH0zlEuV7L79w6HkRCQ
+VRg10GUN6heGLv0aOHbPdobcuVDH4sgOqpT1QnOuce34sQs=
+-----END RSA TESTING KEY-----`))
+
+var test3072Key = parseKey(testingKey(`-----BEGIN RSA TESTING KEY-----
+MIIG5AIBAAKCAYEAuvg7HHdVlr2kKZzRw9xs/uZqR6JK21izBdg8D52YPqEdMIhG
+BSuOrejT6HiDaJcyCkeNxj7E2dKWacIV4UytlPvDnSL9dQduytl31YQ01J5i20r3
+Kp1etZDEDltly1eVKcbdQTsr26oSQCojYYiYOj+q8w/rzH3WSEuMs04TMwxCR0CC
+nStVsNWw5zL45n26mxDgDdPK/i3OJTinTvPUDysB/V0c8tRaQ8U6YesmgSYGIMe0
+bx5l9k1RJbISGIipmS1IVdNAHSnxqJTUG+9k8SHzp5bvqPeiuVLMZeEdqPHwkNHW
+37LNO28nN+B0xhc4wvEFvggrMf58oO3oy16AzBsWDKSOQnsagc4gQtrJ4N4WOibT
+/LJB76RLoNyJ+Ov7Ue8ngqR3r3EM8I9AAkj2+3fo+DxcLuE9qOVnrHYFRqq+EYQe
+lKSg3Z0EHb7XF35xXeAFbpEXSVuidBRm+emgLkZ2n313hz6jUg3FdE3vLMYHvxly
+ROzgsz0cNOAH3jnXAgMBAAECggGBAILJqe/buk9cET3aqRGtW8FjRO0fJeYSQgjQ
+nhL+VsVYxqZwbSqosYIN4E46HxJG0YZHT3Fh7ynAGd+ZGN0lWjdhdhCxrUL0FBhp
+z13YwWwJ73UfF48DzoCL59lzLd30Qi+bIKLE1YUvjty7nUxY1MPKTbcBaBz/2alw
+z9eNwfhvlt1ozvVKnwK4OKtCCMKTKLnYMCL8CH+NYyq+Wqrr/Wcu2pF1VQ64ZPwL
+Ny/P4nttMdQ0Xo9sYD7PDvije+0VivsoT8ZatLt06fCwxEIue2uucIQjXCgO8Igm
+pZwBEWDfy+NHtTKrFpyKf357S8veDwdU14GjviY8JFH8Bg8PBn3i38635m0o7xMG
+pRlQi5x1zbHy4riOEjyjCIRVCKwKT5HEYNK5Uu3aQnlOV7CzxBLNp5lyioAIGOBC
+RKJabN5vbUqJjxaQ39tA29DtfA3+r30aMO+QzOl5hrjJV7A7ueV3dbjp+fDV0LPq
+QrJ68IvHPi3hfqVlP1UM2s4T69kcYQKBwQDoj+rZVb3Aq0JZ8LraR3nA1yFw4NfA
+SZ/Ne36rIySiy5z+qY9p6WRNLGLrusSIfmbmvStswAliIdh1cZTAUsIF5+kQvBQg
+VlxJW/nY5hTktIDOZPDaI77jid1iZLID3VXEm6dXY/Hv7DiUORudXAHoy6HZm2Jt
+kSkIplSeSfASqidj9Bv7V27ttCcMLu0ImdX4JyWoXkVuzBuxKAgiemtLS5IPN8tw
+m/o2lMaP8/sCMpXrlo2VS3TMsfJyRI/JGoMCgcEAzdAH1TKNeQ3ghzRdlw5NAs31
+VbcYzjz8HRkNhOsQCs++1ib7H2MZ3HPLpAa3mBJ+VfXO479G23yI7f2zpiUzRuVY
+cTMHw5Ln7FXfBro5eu/ruyNzKiWPElP8VK814HI5u5XqUU05BsQbe6AjSGHoU6P6
+PfSDzaw8hGW78GcZu4/EkZp/0TXW+1HUGgU+ObgmG+PnyIMHIt99i7qrOVbNmG9n
+uNwGwmfFzNqAtVLbLcVyBV5TR+Ze3ZAwjnVaH5MdAoHBAOg5ncd8KMjVuqHZEpyY
+tulraQcwXgCzBBHJ+YimxRSSwahCZOTbm768TeMaUtoBbnuF9nDXqgcFyQItct5B
+RWFkXITLakWINwtB/tEpnz9pRx3SCfeprhnENv7jkibtw5FZ5NYNBTAQ78aC6CJQ
+F9AAVxPWZ4kFZLYwcVrGdiYNJtxWjAKFIk3WkQ9HZIYsJ09ut9nSmP60bgqO8OCM
+4csEIUt06X7/IfGSylxAwytEnBPt+F9WQ8GLB5A3CmVERQKBwGmBR0Knk5aG4p7s
+3T1ee2QAqM+z+Odgo+1WtnN4/NROAwpNGVbRuqQkSDRhrSQr9s+iHtjpaS2C/b7i
+24FEeLDTSS9edZBwcqvYqWgNdwHqk/FvDs6ASoOewi+3UespIydihqf+6kjppx0M
+zomAh1S5LsMr4ZVBwhQtAtcOQ0a/QIlTpkpdS0OygwSDw45bNE3/2wYTBUl/QCCt
+JLFUKjkGgylkwaJPCDsnl+tb+jfQi87st8yX7/GsxPeCeRzOkQKBwGPcu2OgZfsl
+dMHz0LwKOEattrkDujpIoNxyTrBN4fX0RdhTgfRrqsEkrH/4XG5VTtc7K7sBgx7f
+IwP1uUAx5v16QDA1Z+oFBXwmI7atdKRM34kl1Q0i60z83ahgA/9bAsSpcA23LtM4
+u2PRX3YNXb9kUcSbod2tVfXyiu7wl6NlsYw5PeF8A8m7QicaeXR6t8NB02XqQ4k+
+BoyV2DVuoxSZKOMti0piQIIacSZWEbgyslwNxW99JRVfA2xKJGjUqA==
+-----END RSA TESTING KEY-----`))
+
+var test4096Key = parseKey(testingKey(`-----BEGIN RSA TESTING KEY-----
+MIIJKQIBAAKCAgEAwTmi+2MLTSm6GbsKksOHCMdIRsPwLlPtJQiMEjnKq4YEPSaC
+HXWQTza0KL/PySjhgw3Go5pC7epXlA9o1I+rbx4J3AwxC+xUUJqs3U0AETtzC1JD
+r3+/aP5KJzXp7IQXe1twEyHbQDCy3XUFhB0tZpIuAx82VSzMv4c6h6KPaES24ljd
+OxJJLPTYVECG2NbYBeKZPxyGNIkHn6/6rJDxnlICvLVBMrPaxsvN04ck55SRIglw
+MWmxpPTRFkMFERY7b2C33BuVICB8tXccvNwgtrNOmaWd6yjESZOYMyJQLi0QHMan
+ObuZw2PeUR+9gAE3R8/ji/i1VLYeVfC6TKzhziq5NKeBXzjSGOS7XyjvxrzypUco
+HiAUyVGKtouRFyOe4gr4xxZpljIEoN4TsBWSbM8GH6n5uFmEKvFnBR5KDRCwFfvI
+JudWm/oWptzQUyqRvzNtv4OgU9YVnx/fY3hyaD5ZnVZjUZzAjo3o8WSwmuTbZbJ1
+gX3pDRPw3g0naBm6rMEWPV4YR93be/mBERxWua6IrPPptRh9WYAJP4bkwk9V0F8U
+Ydk1URLeETAyFScNgukcKzpNw+OeCze2Blvrenf9goHefIpMzv4/ulEr7/v80ESq
+qd9CAwpz7cRe5+g18v5rFTEHESTCCq+rOFI5L59UX4VvE7CGOzcPLLZjlcMCAwEA
+AQKCAgB3/09UR0IxfYRxjlMWqg8mSHx+VhjG7KANq60xdGqE8wmW4F9V5DjmuNZR
+qC1mg9jpBpkh6R8/mZUiAh/cQgz5SPJekcOz3+TM2gIYvUUZbo4XrdMTHobEsYdj
+qnvHwpDCrxp/BzueNaAfIBl43pXfaVDh53RamSPeniCfMzlUS7g4AXACy2xeWwAt
+8pTL/UDTBtKc+x3talwts6A9oxYqeEvy3a3Lyx5G7zK39unYV896D9p5FWaZRuDC
+roRrBB+NH8ePDiIifYp1N6/FKf+29swNZ2kXLY4ZE2wl9V1OD/Y9qLEZjYQEb/UU
+9F0/LYIjOtvZhW83WJKmVIWeMI9Z4UooOztJJK0XOqSDsXVaEMgrF9D4E8BnKdWp
+ddM5E0nNXpLEV/SsoUyAMjArjImf8HjmJA45Px+BBGxdIv5PCyvUUD2R/6WbHOdh
+glH49I4SpVKGICV+qhLdSZkjWaItECwbsw5CeXrcOPjVCrNGOOKI8FdQN7S9JRiN
+Th6pTL1ezDUOx2Sq1M/h++ucd7akzsxm6my3leNYHxxyX7/PnQgUDyoXwQ1azAtB
+8PmMe7JAxuMjwFJJXn1Sgoq0ml0RkRkrj18+UMiz32qX8OtN+x44LkC7TnMNXqiA
+ohmzYy4WJRc3LyyTMWGrH00Zckc8oBvjf/rWy5X1nWz+DcuQIQKCAQEA6x92d8A9
+WR4qeHRY6zfHaaza8Z9vFUUUwebPxDy82Q6znu6nXNB/Q+OuhGohqcODUC8dj2qv
+7AyKdukzZzPTNSWNoSnr3c3nGpOzXxFntGOMFB83nmeoYGJEo3RertQO8QG2Dkis
+Ix9uKU6u2m5ijnH5cqHs2OcRbl2b+6mkRvPY2YxI0EqSXnMa1jpjeCKpZDW89iLU
+rm7x6vqyffqVaTt4PHj47p5QIUj8cRkVtAvUuIzM/R2g/epiytTo4iRM28rVLRnK
+28BtTtXZBT6Xy4UWX0fLSOUm2Hr1jiUJIc+Adb2h+zh69MBtBG6JRBiK7zwx7HxE
+c6sFzNvfMei99QKCAQEA0mHNpqmHuHb+wNdAEiKz4hCnYyuLDy+lZp/uQRkiODqV
+eUxAHRK1OP8yt45ZBxyaLcuRvAgK/ETg/QlYWUuAXvUWVGq9Ycv3WrpjUL0DHvuo
+rBfWTSiTNWH9sbDoCapiJMDe28ELBXVp1dCKuei/EReRHYg/vJn+GdPaZL60rlQg
+qCMou3jOXw94/Y05QcJQNkoLmVEEEwkbwrfXWvjShRbKNsv5kJydgPRfnsu5JSue
+Ydkx/Io4+4xz6vjfDDjgFFfvOJJjouFkYGWIDuT5JViIVBVK1F3XrkzOYUjoBzo7
+xDJkZrgNyNIpWXdzwfb8WTCJAOTHMk9DSB4lkk651wKCAQBKMTtovjidjm9IYy5L
+yuYZ6nmMFQswYwQRy4t0GNZeh80WMaiOGRyPh6DiF7tXnmIpQzTItJmemrZ2n0+h
+GTFka90tJdVPwFFUiZboQM3Alkj1cIRUb9Ep2Nhf27Ck6jVsx2VzTGtFCf3w+ush
+8gMXf89+5KmgKAnQEanO19EGspuSyjmPwHg/ZYLqZrJMjmN1Q5/E62jBQjEEPOdl
+6VSMSD/AlUu3wCz409cUuR2oGrOdKJDmrhrHBNb3ugdilKHMGUz7VlA015umbMR2
+azHq/qv4lOcIsYZ4eRRTLkybZqbagGREqaXi5XWBGIAoBLaSlyQJw4y2ExlZc2gS
+j6ahAoIBAQCwzdsL1mumHfMI050X4Kw2L3LNCBoMwCkL7xpHAT1d7fYSg39aL4+3
+f9j6pBmzvVjhZbRrRoMc8TH31XO3T5lptCV4+l+AIe8WA5BVmRNXZX2ia0IBhDj6
+4whW3eqTvOpQIvrnyfteMgeo1mLPzIdOcPTW0dtmwC/pOr7Obergmvj69NlVfDhL
+cXBn/diBqDDK/z1yMsDu0nfPE7tby8L4cGeu14s7+jLv3e/CP0mwsFChwOueZfdv
+h+EfNtoUpnPDBQeZDoXHrA40aP+ILOwpc5bWuzIw+VC6PfgvkBrXgBwcTZFNNh73
+h4+Sja3t84it1/k7lAjIAg70O8mthJXvAoIBAQDUUqWxqQN76gY2CPuXrwIvWvfP
+Z9U2Lv5ZTmY75L20CWRY0os0hAF68vCwxLpfeUMUTSokwa5L/l1gHwA2Zqm1977W
+9wV2Iiyqmkz9u3fu5YNOlezSoffOvAf/GUvSQ9HJ/VGqFdy2bC6NE81HRxojxeeY
+7ZmNlJrcsupyWmpUTpAd4cRVaCjcZQRoj+uIYCbgtV6/RD5VXHcPTd9wR7pjZPv7
+239qVdVU4ahkSZP6ikeN/wOEegWS0i/cKSgYmLBpWFGze3EKvHdEzurqPNCr5zo2
+jd7HGMtCpvqFx/7wUl09ac/kHeY+Ob2KduWinSPm5+jI6dPohnGx/wBEVCWh
+-----END RSA TESTING KEY-----`))
+
+func BenchmarkDecryptPKCS1v15(b *testing.B) {
+	b.Run("2048", func(b *testing.B) { benchmarkDecryptPKCS1v15(b, test2048Key) })
+	b.Run("3072", func(b *testing.B) { benchmarkDecryptPKCS1v15(b, test3072Key) })
+	b.Run("4096", func(b *testing.B) { benchmarkDecryptPKCS1v15(b, test4096Key) })
+}
+
+func benchmarkDecryptPKCS1v15(b *testing.B, k *PrivateKey) {
+	r := bufio.NewReaderSize(rand.Reader, 1<<15)
+
+	m := []byte("Hello Gophers")
+	c, err := EncryptPKCS1v15(r, &k.PublicKey, m)
 	if err != nil {
-		t.Errorf("error while decrypting (blind): %s", err)
-	}
-	if m.Cmp(m3) != 0 {
-		t.Errorf("(blind) got:%v, want:%v (%#v)", m3, m, priv)
-	}
-}
-
-func fromBase10(base10 string) *big.Int {
-	i, ok := new(big.Int).SetString(base10, 10)
-	if !ok {
-		panic("bad number: " + base10)
-	}
-	return i
-}
-
-var test2048Key *PrivateKey
-
-func init() {
-	test2048Key = &PrivateKey{
-		PublicKey: PublicKey{
-			N: fromBase10("14314132931241006650998084889274020608918049032671858325988396851334124245188214251956198731333464217832226406088020736932173064754214329009979944037640912127943488972644697423190955557435910767690712778463524983667852819010259499695177313115447116110358524558307947613422897787329221478860907963827160223559690523660574329011927531289655711860504630573766609239332569210831325633840174683944553667352219670930408593321661375473885147973879086994006440025257225431977751512374815915392249179976902953721486040787792801849818254465486633791826766873076617116727073077821584676715609985777563958286637185868165868520557"),
-			E: 3,
-		},
-		D: fromBase10("9542755287494004433998723259516013739278699355114572217325597900889416163458809501304132487555642811888150937392013824621448709836142886006653296025093941418628992648429798282127303704957273845127141852309016655778568546006839666463451542076964744073572349705538631742281931858219480985907271975884773482372966847639853897890615456605598071088189838676728836833012254065983259638538107719766738032720239892094196108713378822882383694456030043492571063441943847195939549773271694647657549658603365629458610273821292232646334717612674519997533901052790334279661754176490593041941863932308687197618671528035670452762731"),
-		Primes: []*big.Int{
-			fromBase10("130903255182996722426771613606077755295583329135067340152947172868415809027537376306193179624298874215608270802054347609836776473930072411958753044562214537013874103802006369634761074377213995983876788718033850153719421695468704276694983032644416930879093914927146648402139231293035971427838068945045019075433"),
-			fromBase10("109348945610485453577574767652527472924289229538286649661240938988020367005475727988253438647560958573506159449538793540472829815903949343191091817779240101054552748665267574271163617694640513549693841337820602726596756351006149518830932261246698766355347898158548465400674856021497190430791824869615170301029"),
-		},
-	}
-	test2048Key.Precompute()
-}
-
-func BenchmarkRSA2048Decrypt(b *testing.B) {
-	if boring.Enabled {
-		b.Skip("no raw decrypt in BoringCrypto")
+		b.Fatal(err)
 	}
 
-	b.StopTimer()
-
-	c := fromBase10("8472002792838218989464636159316973636630013835787202418124758118372358261975764365740026024610403138425986214991379012696600761514742817632790916315594342398720903716529235119816755589383377471752116975374952783629225022962092351886861518911824745188989071172097120352727368980275252089141512321893536744324822590480751098257559766328893767334861211872318961900897793874075248286439689249972315699410830094164386544311554704755110361048571142336148077772023880664786019636334369759624917224888206329520528064315309519262325023881707530002540634660750469137117568199824615333883758410040459705787022909848740188613313")
-
-	b.StartTimer()
-
+	b.ResetTimer()
+	var sink byte
 	for i := 0; i < b.N; i++ {
-		decrypt(nil, test2048Key, c)
+		p, err := DecryptPKCS1v15(r, k, c)
+		if err != nil {
+			b.Fatal(err)
+		}
+		if !bytes.Equal(p, m) {
+			b.Fatalf("unexpected output: %q", p)
+		}
+		sink ^= p[0]
 	}
 }
 
-func BenchmarkRSA2048Sign(b *testing.B) {
-	b.StopTimer()
-	hashed := sha256.Sum256([]byte("testing"))
-	b.StartTimer()
+func BenchmarkEncryptPKCS1v15(b *testing.B) {
+	b.Run("2048", func(b *testing.B) {
+		r := bufio.NewReaderSize(rand.Reader, 1<<15)
+		m := []byte("Hello Gophers")
 
-	for i := 0; i < b.N; i++ {
-		SignPKCS1v15(rand.Reader, test2048Key, crypto.SHA256, hashed[:])
-	}
+		var sink byte
+		for i := 0; i < b.N; i++ {
+			c, err := EncryptPKCS1v15(r, &test2048Key.PublicKey, m)
+			if err != nil {
+				b.Fatal(err)
+			}
+			sink ^= c[0]
+		}
+	})
 }
 
-func Benchmark3PrimeRSA2048Decrypt(b *testing.B) {
-	if boring.Enabled {
-		b.Skip("no raw decrypt in BoringCrypto")
-	}
+func BenchmarkDecryptOAEP(b *testing.B) {
+	b.Run("2048", func(b *testing.B) {
+		r := bufio.NewReaderSize(rand.Reader, 1<<15)
 
-	b.StopTimer()
-	priv := &PrivateKey{
-		PublicKey: PublicKey{
-			N: fromBase10("16346378922382193400538269749936049106320265317511766357599732575277382844051791096569333808598921852351577762718529818072849191122419410612033592401403764925096136759934497687765453905884149505175426053037420486697072448609022753683683718057795566811401938833367954642951433473337066311978821180526439641496973296037000052546108507805269279414789035461158073156772151892452251106173507240488993608650881929629163465099476849643165682709047462010581308719577053905787496296934240246311806555924593059995202856826239801816771116902778517096212527979497399966526283516447337775509777558018145573127308919204297111496233"),
-			E: 3,
-		},
-		D: fromBase10("10897585948254795600358846499957366070880176878341177571733155050184921896034527397712889205732614568234385175145686545381899460748279607074689061600935843283397424506622998458510302603922766336783617368686090042765718290914099334449154829375179958369993407724946186243249568928237086215759259909861748642124071874879861299389874230489928271621259294894142840428407196932444474088857746123104978617098858619445675532587787023228852383149557470077802718705420275739737958953794088728369933811184572620857678792001136676902250566845618813972833750098806496641114644760255910789397593428910198080271317419213080834885003"),
-		Primes: []*big.Int{
-			fromBase10("1025363189502892836833747188838978207017355117492483312747347695538428729137306368764177201532277413433182799108299960196606011786562992097313508180436744488171474690412562218914213688661311117337381958560443"),
-			fromBase10("3467903426626310123395340254094941045497208049900750380025518552334536945536837294961497712862519984786362199788654739924501424784631315081391467293694361474867825728031147665777546570788493758372218019373"),
-			fromBase10("4597024781409332673052708605078359346966325141767460991205742124888960305710298765592730135879076084498363772408626791576005136245060321874472727132746643162385746062759369754202494417496879741537284589047"),
-		},
-	}
-	priv.Precompute()
+		m := []byte("Hello Gophers")
+		c, err := EncryptOAEP(sha256.New(), r, &test2048Key.PublicKey, m, nil)
+		if err != nil {
+			b.Fatal(err)
+		}
 
-	c := fromBase10("8472002792838218989464636159316973636630013835787202418124758118372358261975764365740026024610403138425986214991379012696600761514742817632790916315594342398720903716529235119816755589383377471752116975374952783629225022962092351886861518911824745188989071172097120352727368980275252089141512321893536744324822590480751098257559766328893767334861211872318961900897793874075248286439689249972315699410830094164386544311554704755110361048571142336148077772023880664786019636334369759624917224888206329520528064315309519262325023881707530002540634660750469137117568199824615333883758410040459705787022909848740188613313")
+		b.ResetTimer()
+		var sink byte
+		for i := 0; i < b.N; i++ {
+			p, err := DecryptOAEP(sha256.New(), r, test2048Key, c, nil)
+			if err != nil {
+				b.Fatal(err)
+			}
+			if !bytes.Equal(p, m) {
+				b.Fatalf("unexpected output: %q", p)
+			}
+			sink ^= p[0]
+		}
+	})
+}
 
-	b.StartTimer()
+func BenchmarkEncryptOAEP(b *testing.B) {
+	b.Run("2048", func(b *testing.B) {
+		r := bufio.NewReaderSize(rand.Reader, 1<<15)
+		m := []byte("Hello Gophers")
 
-	for i := 0; i < b.N; i++ {
-		decrypt(nil, priv, c)
-	}
+		var sink byte
+		for i := 0; i < b.N; i++ {
+			c, err := EncryptOAEP(sha256.New(), r, &test2048Key.PublicKey, m, nil)
+			if err != nil {
+				b.Fatal(err)
+			}
+			sink ^= c[0]
+		}
+	})
+}
+
+func BenchmarkSignPKCS1v15(b *testing.B) {
+	b.Run("2048", func(b *testing.B) {
+		hashed := sha256.Sum256([]byte("testing"))
+
+		var sink byte
+		b.ResetTimer()
+		for i := 0; i < b.N; i++ {
+			s, err := SignPKCS1v15(rand.Reader, test2048Key, crypto.SHA256, hashed[:])
+			if err != nil {
+				b.Fatal(err)
+			}
+			sink ^= s[0]
+		}
+	})
+}
+
+func BenchmarkVerifyPKCS1v15(b *testing.B) {
+	b.Run("2048", func(b *testing.B) {
+		hashed := sha256.Sum256([]byte("testing"))
+		s, err := SignPKCS1v15(rand.Reader, test2048Key, crypto.SHA256, hashed[:])
+		if err != nil {
+			b.Fatal(err)
+		}
+
+		b.ResetTimer()
+		for i := 0; i < b.N; i++ {
+			err := VerifyPKCS1v15(&test2048Key.PublicKey, crypto.SHA256, hashed[:], s)
+			if err != nil {
+				b.Fatal(err)
+			}
+		}
+	})
+}
+
+func BenchmarkSignPSS(b *testing.B) {
+	b.Run("2048", func(b *testing.B) {
+		hashed := sha256.Sum256([]byte("testing"))
+
+		var sink byte
+		b.ResetTimer()
+		for i := 0; i < b.N; i++ {
+			s, err := SignPSS(rand.Reader, test2048Key, crypto.SHA256, hashed[:], nil)
+			if err != nil {
+				b.Fatal(err)
+			}
+			sink ^= s[0]
+		}
+	})
+}
+
+func BenchmarkVerifyPSS(b *testing.B) {
+	b.Run("2048", func(b *testing.B) {
+		hashed := sha256.Sum256([]byte("testing"))
+		s, err := SignPSS(rand.Reader, test2048Key, crypto.SHA256, hashed[:], nil)
+		if err != nil {
+			b.Fatal(err)
+		}
+
+		b.ResetTimer()
+		for i := 0; i < b.N; i++ {
+			err := VerifyPSS(&test2048Key.PublicKey, crypto.SHA256, hashed[:], s, nil)
+			if err != nil {
+				b.Fatal(err)
+			}
+		}
+	})
 }
 
 type testEncryptOAEPMessage struct {
@@ -303,6 +679,31 @@
 	}
 }
 
+func Test2DecryptOAEP(t *testing.T) {
+	random := rand.Reader
+
+	msg := []byte{0xed, 0x36, 0x90, 0x8d, 0xbe, 0xfc, 0x35, 0x40, 0x70, 0x4f, 0xf5, 0x9d, 0x6e, 0xc2, 0xeb, 0xf5, 0x27, 0xae, 0x65, 0xb0, 0x59, 0x29, 0x45, 0x25, 0x8c, 0xc1, 0x91, 0x22}
+	in := []byte{0x72, 0x26, 0x84, 0xc9, 0xcf, 0xd6, 0xa8, 0x96, 0x04, 0x3e, 0x34, 0x07, 0x2c, 0x4f, 0xe6, 0x52, 0xbe, 0x46, 0x3c, 0xcf, 0x79, 0x21, 0x09, 0x64, 0xe7, 0x33, 0x66, 0x9b, 0xf8, 0x14, 0x22, 0x43, 0xfe, 0x8e, 0x52, 0x8b, 0xe0, 0x5f, 0x98, 0xef, 0x54, 0xac, 0x6b, 0xc6, 0x26, 0xac, 0x5b, 0x1b, 0x4b, 0x7d, 0x2e, 0xd7, 0x69, 0x28, 0x5a, 0x2f, 0x4a, 0x95, 0x89, 0x6c, 0xc7, 0x53, 0x95, 0xc7, 0xd2, 0x89, 0x04, 0x6f, 0x94, 0x74, 0x9b, 0x09, 0x0d, 0xf4, 0x61, 0x2e, 0xab, 0x48, 0x57, 0x4a, 0xbf, 0x95, 0xcb, 0xff, 0x15, 0xe2, 0xa0, 0x66, 0x58, 0xf7, 0x46, 0xf8, 0xc7, 0x0b, 0xb5, 0x1e, 0xa7, 0xba, 0x36, 0xce, 0xdd, 0x36, 0x41, 0x98, 0x6e, 0x10, 0xf9, 0x3b, 0x70, 0xbb, 0xa1, 0xda, 0x00, 0x40, 0xd5, 0xa5, 0x3f, 0x87, 0x64, 0x32, 0x7c, 0xbc, 0x50, 0x52, 0x0e, 0x4f, 0x21, 0xbd}
+
+	n := new(big.Int)
+	d := new(big.Int)
+	n.SetString(testEncryptOAEPData[0].modulus, 16)
+	d.SetString(testEncryptOAEPData[0].d, 16)
+	priv := new(PrivateKey)
+	priv.PublicKey = PublicKey{N: n, E: testEncryptOAEPData[0].e}
+	priv.D = d
+	sha1 := crypto.SHA1
+	sha256 := crypto.SHA256
+
+	out, err := priv.Decrypt(random, in, &OAEPOptions{MGFHash: sha1, Hash: sha256})
+
+	if err != nil {
+		t.Errorf("error: %s", err)
+	} else if !bytes.Equal(out, msg) {
+		t.Errorf("bad result %#v (want %#v)", out, msg)
+	}
+}
+
 func TestEncryptDecryptOAEP(t *testing.T) {
 	sha256 := sha256.New()
 	n := new(big.Int)
diff --git a/src/crypto/sha1/issue15617_test.go b/src/crypto/sha1/issue15617_test.go
index df4e28f..116c78f 100644
--- a/src/crypto/sha1/issue15617_test.go
+++ b/src/crypto/sha1/issue15617_test.go
@@ -1,9 +1,9 @@
-//go:build amd64 && (linux || darwin)
-
 // Copyright 2016 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build amd64 && (linux || darwin)
+
 package sha1_test
 
 import (
diff --git a/src/crypto/sha1/sha1.go b/src/crypto/sha1/sha1.go
index 271852d..43ab72a 100644
--- a/src/crypto/sha1/sha1.go
+++ b/src/crypto/sha1/sha1.go
@@ -50,14 +50,14 @@
 func (d *digest) MarshalBinary() ([]byte, error) {
 	b := make([]byte, 0, marshaledSize)
 	b = append(b, magic...)
-	b = appendUint32(b, d.h[0])
-	b = appendUint32(b, d.h[1])
-	b = appendUint32(b, d.h[2])
-	b = appendUint32(b, d.h[3])
-	b = appendUint32(b, d.h[4])
+	b = binary.BigEndian.AppendUint32(b, d.h[0])
+	b = binary.BigEndian.AppendUint32(b, d.h[1])
+	b = binary.BigEndian.AppendUint32(b, d.h[2])
+	b = binary.BigEndian.AppendUint32(b, d.h[3])
+	b = binary.BigEndian.AppendUint32(b, d.h[4])
 	b = append(b, d.x[:d.nx]...)
-	b = b[:len(b)+len(d.x)-int(d.nx)] // already zero
-	b = appendUint64(b, d.len)
+	b = b[:len(b)+len(d.x)-d.nx] // already zero
+	b = binary.BigEndian.AppendUint64(b, d.len)
 	return b, nil
 }
 
@@ -80,18 +80,6 @@
 	return nil
 }
 
-func appendUint64(b []byte, x uint64) []byte {
-	var a [8]byte
-	binary.BigEndian.PutUint64(a[:], x)
-	return append(b, a[:]...)
-}
-
-func appendUint32(b []byte, x uint32) []byte {
-	var a [4]byte
-	binary.BigEndian.PutUint32(a[:], x)
-	return append(b, a[:]...)
-}
-
 func consumeUint64(b []byte) ([]byte, uint64) {
 	_ = b[7]
 	x := uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
@@ -166,18 +154,20 @@
 func (d *digest) checkSum() [Size]byte {
 	len := d.len
 	// Padding.  Add a 1 bit and 0 bits until 56 bytes mod 64.
-	var tmp [64]byte
+	var tmp [64 + 8]byte // padding + length buffer
 	tmp[0] = 0x80
+	var t uint64
 	if len%64 < 56 {
-		d.Write(tmp[0 : 56-len%64])
+		t = 56 - len%64
 	} else {
-		d.Write(tmp[0 : 64+56-len%64])
+		t = 64 + 56 - len%64
 	}
 
 	// Length in bits.
 	len <<= 3
-	binary.BigEndian.PutUint64(tmp[:], len)
-	d.Write(tmp[0:8])
+	padlen := tmp[:t+8]
+	binary.BigEndian.PutUint64(padlen[t:], len)
+	d.Write(padlen)
 
 	if d.nx != 0 {
 		panic("d.nx != 0")
diff --git a/src/crypto/sha256/sha256.go b/src/crypto/sha256/sha256.go
index e3c15e6..2deafbc 100644
--- a/src/crypto/sha256/sha256.go
+++ b/src/crypto/sha256/sha256.go
@@ -70,17 +70,17 @@
 	} else {
 		b = append(b, magic256...)
 	}
-	b = appendUint32(b, d.h[0])
-	b = appendUint32(b, d.h[1])
-	b = appendUint32(b, d.h[2])
-	b = appendUint32(b, d.h[3])
-	b = appendUint32(b, d.h[4])
-	b = appendUint32(b, d.h[5])
-	b = appendUint32(b, d.h[6])
-	b = appendUint32(b, d.h[7])
+	b = binary.BigEndian.AppendUint32(b, d.h[0])
+	b = binary.BigEndian.AppendUint32(b, d.h[1])
+	b = binary.BigEndian.AppendUint32(b, d.h[2])
+	b = binary.BigEndian.AppendUint32(b, d.h[3])
+	b = binary.BigEndian.AppendUint32(b, d.h[4])
+	b = binary.BigEndian.AppendUint32(b, d.h[5])
+	b = binary.BigEndian.AppendUint32(b, d.h[6])
+	b = binary.BigEndian.AppendUint32(b, d.h[7])
 	b = append(b, d.x[:d.nx]...)
-	b = b[:len(b)+len(d.x)-int(d.nx)] // already zero
-	b = appendUint64(b, d.len)
+	b = b[:len(b)+len(d.x)-d.nx] // already zero
+	b = binary.BigEndian.AppendUint64(b, d.len)
 	return b, nil
 }
 
@@ -106,18 +106,6 @@
 	return nil
 }
 
-func appendUint64(b []byte, x uint64) []byte {
-	var a [8]byte
-	binary.BigEndian.PutUint64(a[:], x)
-	return append(b, a[:]...)
-}
-
-func appendUint32(b []byte, x uint32) []byte {
-	var a [4]byte
-	binary.BigEndian.PutUint32(a[:], x)
-	return append(b, a[:]...)
-}
-
 func consumeUint64(b []byte) ([]byte, uint64) {
 	_ = b[7]
 	x := uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
@@ -226,18 +214,20 @@
 func (d *digest) checkSum() [Size]byte {
 	len := d.len
 	// Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
-	var tmp [64]byte
+	var tmp [64 + 8]byte // padding + length buffer
 	tmp[0] = 0x80
+	var t uint64
 	if len%64 < 56 {
-		d.Write(tmp[0 : 56-len%64])
+		t = 56 - len%64
 	} else {
-		d.Write(tmp[0 : 64+56-len%64])
+		t = 64 + 56 - len%64
 	}
 
 	// Length in bits.
 	len <<= 3
-	binary.BigEndian.PutUint64(tmp[:], len)
-	d.Write(tmp[0:8])
+	padlen := tmp[:t+8]
+	binary.BigEndian.PutUint64(padlen[t+0:], len)
+	d.Write(padlen)
 
 	if d.nx != 0 {
 		panic("d.nx != 0")
diff --git a/src/crypto/sha256/sha256block_ppc64x.s b/src/crypto/sha256/sha256block_ppc64x.s
index 617d42e..b229ef6 100644
--- a/src/crypto/sha256/sha256block_ppc64x.s
+++ b/src/crypto/sha256/sha256block_ppc64x.s
@@ -57,13 +57,31 @@
 #define CTX	R3
 #define INP	R4
 #define END	R5
-#define TBL	R6
-#define IDX	R7
+#define TBL	R6 // Pointer into kcon table
 #define LEN	R9
 #define TEMP	R12
 
-#define HEX00	R0
-#define HEX10	R10
+#define TBL_STRT	R7 // Pointer to start of kcon table.
+
+#define R_x000	R0
+#define R_x010	R8
+#define R_x020	R10
+#define R_x030	R11
+#define R_x040	R14
+#define R_x050	R15
+#define R_x060	R16
+#define R_x070	R17
+#define R_x080	R18
+#define R_x090	R19
+#define R_x0a0	R20
+#define R_x0b0	R21
+#define R_x0c0	R22
+#define R_x0d0	R23
+#define R_x0e0	R24
+#define R_x0f0	R25
+#define R_x100	R26
+#define R_x110	R27
+
 
 // V0-V7 are A-H
 // V8-V23 are used for the message schedule
@@ -73,7 +91,7 @@
 #define S1	V27
 #define s0	V28
 #define s1	V29
-#define LEMASK	V31	// Permutation control register for little endian
+#define LEMASK	V31 // Permutation control register for little endian
 
 // 4 copies of each Kt, to fill all 4 words of a vector register
 DATA  ·kcon+0x000(SB)/8, $0x428a2f98428a2f98
@@ -208,7 +226,7 @@
 DATA  ·kcon+0x408(SB)/8, $0x0000000000000000
 
 #ifdef GOARCH_ppc64le
-DATA  ·kcon+0x410(SB)/8, $0x1011121310111213	// permutation control vectors
+DATA  ·kcon+0x410(SB)/8, $0x1011121310111213 // permutation control vectors
 DATA  ·kcon+0x418(SB)/8, $0x1011121300010203
 DATA  ·kcon+0x420(SB)/8, $0x1011121310111213
 DATA  ·kcon+0x428(SB)/8, $0x0405060700010203
@@ -216,7 +234,7 @@
 DATA  ·kcon+0x438(SB)/8, $0x0405060700010203
 #else
 DATA  ·kcon+0x410(SB)/8, $0x1011121300010203
-DATA  ·kcon+0x418(SB)/8, $0x1011121310111213	// permutation control vectors
+DATA  ·kcon+0x418(SB)/8, $0x1011121310111213 // permutation control vectors
 DATA  ·kcon+0x420(SB)/8, $0x0405060700010203
 DATA  ·kcon+0x428(SB)/8, $0x1011121310111213
 DATA  ·kcon+0x430(SB)/8, $0x0001020304050607
@@ -225,7 +243,7 @@
 
 GLOBL ·kcon(SB), RODATA, $1088
 
-#define SHA256ROUND0(a, b, c, d, e, f, g, h, xi) \
+#define SHA256ROUND0(a, b, c, d, e, f, g, h, xi, idx) \
 	VSEL		g, f, e, FUNC; \
 	VSHASIGMAW	$15, e, $1, S1; \
 	VADDUWM		xi, h, h; \
@@ -237,11 +255,10 @@
 	VADDUWM		KI, g, g; \
 	VADDUWM		h, d, d; \
 	VADDUWM		FUNC, S0, S0; \
-	LVX		(TBL)(IDX), KI; \
-	ADD		$16, IDX; \
+	LVX		(TBL)(idx), KI; \
 	VADDUWM		S0, h, h
 
-#define SHA256ROUND1(a, b, c, d, e, f, g, h, xi, xj, xj_1, xj_9, xj_14) \
+#define SHA256ROUND1(a, b, c, d, e, f, g, h, xi, xj, xj_1, xj_9, xj_14, idx) \
 	VSHASIGMAW	$0, xj_1, $0, s0; \
 	VSEL		g, f, e, FUNC; \
 	VSHASIGMAW	$15, e, $1, S1; \
@@ -257,8 +274,7 @@
 	VADDUWM		h, d, d; \
 	VADDUWM		FUNC, S0, S0; \
 	VADDUWM		s0, xj, xj; \
-	LVX		(TBL)(IDX), KI; \
-	ADD		$16, IDX; \
+	LVX		(TBL)(idx), KI; \
 	VADDUWM		S0, h, h; \
 	VADDUWM		s1, xj, xj
 
@@ -281,18 +297,18 @@
 	CMP	INP, END
 	BEQ	end
 
-	MOVD	$·kcon(SB), TBL
-	MOVWZ	$0x10, HEX10
-	MOVWZ	$8, IDX
+	MOVD	$·kcon(SB), TBL_STRT
+	MOVD	$0x10, R_x010
 
 #ifdef GOARCH_ppc64le
-	LVSL	(IDX)(R0), LEMASK
+	MOVWZ	$8, TEMP
+	LVSL	(TEMP)(R0), LEMASK
 	VSPLTISB	$0x0F, KI
 	VXOR	KI, LEMASK, LEMASK
 #endif
 
-	LXVW4X	(CTX)(HEX00), VS32	// v0 = vs32
-	LXVW4X	(CTX)(HEX10), VS36	// v4 = vs36
+	LXVW4X	(CTX)(R_x000), V0
+	LXVW4X	(CTX)(R_x010), V4
 
 	// unpack the input values into vector registers
 	VSLDOI	$4, V0, V0, V1
@@ -302,12 +318,28 @@
 	VSLDOI	$8, V4, V4, V6
 	VSLDOI	$12, V4, V4, V7
 
-loop:
-	LVX	(TBL)(HEX00), KI
-	MOVWZ	$16, IDX
+	MOVD	$0x020, R_x020
+	MOVD	$0x030, R_x030
+	MOVD	$0x040, R_x040
+	MOVD	$0x050, R_x050
+	MOVD	$0x060, R_x060
+	MOVD	$0x070, R_x070
+	MOVD	$0x080, R_x080
+	MOVD	$0x090, R_x090
+	MOVD	$0x0a0, R_x0a0
+	MOVD	$0x0b0, R_x0b0
+	MOVD	$0x0c0, R_x0c0
+	MOVD	$0x0d0, R_x0d0
+	MOVD	$0x0e0, R_x0e0
+	MOVD	$0x0f0, R_x0f0
+	MOVD	$0x100, R_x100
+	MOVD	$0x110, R_x110
 
-	LXVD2X	(INP)(R0), VS40	// load v8 (=vs40) in advance
-	ADD	$16, INP
+loop:
+	MOVD	TBL_STRT, TBL
+	LVX	(TBL)(R_x000), KI
+
+	LXVD2X	(INP)(R_x000), V8 // load v8 in advance
 
 	// Offload to VSR24-31 (aka FPR24-31)
 	XXLOR	V0, V0, VS24
@@ -319,71 +351,70 @@
 	XXLOR	V6, V6, VS30
 	XXLOR	V7, V7, VS31
 
-	VADDUWM	KI, V7, V7	// h+K[i]
-	LVX	(TBL)(IDX), KI
-	ADD	$16, IDX
+	VADDUWM	KI, V7, V7        // h+K[i]
+	LVX	(TBL)(R_x010), KI
 
 	VPERMLE(V8, V8, LEMASK, V8)
-	SHA256ROUND0(V0, V1, V2, V3, V4, V5, V6, V7, V8)
+	SHA256ROUND0(V0, V1, V2, V3, V4, V5, V6, V7, V8, R_x020)
 	VSLDOI	$4, V8, V8, V9
-	SHA256ROUND0(V7, V0, V1, V2, V3, V4, V5, V6, V9)
+	SHA256ROUND0(V7, V0, V1, V2, V3, V4, V5, V6, V9, R_x030)
 	VSLDOI	$4, V9, V9, V10
-	SHA256ROUND0(V6, V7, V0, V1, V2, V3, V4, V5, V10)
-	LXVD2X	(INP)(R0), VS44	// load v12 (=vs44) in advance
-	ADD	$16, INP, INP
+	SHA256ROUND0(V6, V7, V0, V1, V2, V3, V4, V5, V10, R_x040)
+	LXVD2X	(INP)(R_x010), V12 // load v12 in advance
 	VSLDOI	$4, V10, V10, V11
-	SHA256ROUND0(V5, V6, V7, V0, V1, V2, V3, V4, V11)
+	SHA256ROUND0(V5, V6, V7, V0, V1, V2, V3, V4, V11, R_x050)
 	VPERMLE(V12, V12, LEMASK, V12)
-	SHA256ROUND0(V4, V5, V6, V7, V0, V1, V2, V3, V12)
+	SHA256ROUND0(V4, V5, V6, V7, V0, V1, V2, V3, V12, R_x060)
 	VSLDOI	$4, V12, V12, V13
-	SHA256ROUND0(V3, V4, V5, V6, V7, V0, V1, V2, V13)
+	SHA256ROUND0(V3, V4, V5, V6, V7, V0, V1, V2, V13, R_x070)
 	VSLDOI	$4, V13, V13, V14
-	SHA256ROUND0(V2, V3, V4, V5, V6, V7, V0, V1, V14)
-	LXVD2X	(INP)(R0), VS48	// load v16 (=vs48) in advance
-	ADD	$16, INP, INP
+	SHA256ROUND0(V2, V3, V4, V5, V6, V7, V0, V1, V14, R_x080)
+	LXVD2X	(INP)(R_x020), V16 // load v16 in advance
 	VSLDOI	$4, V14, V14, V15
-	SHA256ROUND0(V1, V2, V3, V4, V5, V6, V7, V0, V15)
+	SHA256ROUND0(V1, V2, V3, V4, V5, V6, V7, V0, V15, R_x090)
 	VPERMLE(V16, V16, LEMASK, V16)
-	SHA256ROUND0(V0, V1, V2, V3, V4, V5, V6, V7, V16)
+	SHA256ROUND0(V0, V1, V2, V3, V4, V5, V6, V7, V16, R_x0a0)
 	VSLDOI	$4, V16, V16, V17
-	SHA256ROUND0(V7, V0, V1, V2, V3, V4, V5, V6, V17)
+	SHA256ROUND0(V7, V0, V1, V2, V3, V4, V5, V6, V17, R_x0b0)
 	VSLDOI	$4, V17, V17, V18
-	SHA256ROUND0(V6, V7, V0, V1, V2, V3, V4, V5, V18)
+	SHA256ROUND0(V6, V7, V0, V1, V2, V3, V4, V5, V18, R_x0c0)
 	VSLDOI	$4, V18, V18, V19
-	LXVD2X	(INP)(R0), VS52	// load v20 (=vs52) in advance
-	ADD	$16, INP, INP
-	SHA256ROUND0(V5, V6, V7, V0, V1, V2, V3, V4, V19)
+	LXVD2X	(INP)(R_x030), V20 // load v20 in advance
+	SHA256ROUND0(V5, V6, V7, V0, V1, V2, V3, V4, V19, R_x0d0)
 	VPERMLE(V20, V20, LEMASK, V20)
-	SHA256ROUND0(V4, V5, V6, V7, V0, V1, V2, V3, V20)
+	SHA256ROUND0(V4, V5, V6, V7, V0, V1, V2, V3, V20, R_x0e0)
 	VSLDOI	$4, V20, V20, V21
-	SHA256ROUND0(V3, V4, V5, V6, V7, V0, V1, V2, V21)
+	SHA256ROUND0(V3, V4, V5, V6, V7, V0, V1, V2, V21, R_x0f0)
 	VSLDOI	$4, V21, V21, V22
-	SHA256ROUND0(V2, V3, V4, V5, V6, V7, V0, V1, V22)
+	SHA256ROUND0(V2, V3, V4, V5, V6, V7, V0, V1, V22, R_x100)
 	VSLDOI	$4, V22, V22, V23
-	SHA256ROUND1(V1, V2, V3, V4, V5, V6, V7, V0, V23, V8, V9, V17, V22)
+	SHA256ROUND1(V1, V2, V3, V4, V5, V6, V7, V0, V23, V8, V9, V17, V22, R_x110)
 
-	MOVWZ	$3, TEMP
-	MOVWZ	TEMP, CTR
+	MOVD	$3, TEMP
+	MOVD	TEMP, CTR
+	ADD	$0x120, TBL
+	ADD	$0x40, INP
 
 L16_xx:
-	SHA256ROUND1(V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V18, V23)
-	SHA256ROUND1(V7, V0, V1, V2, V3, V4, V5, V6, V9, V10, V11, V19, V8)
-	SHA256ROUND1(V6, V7, V0, V1, V2, V3, V4, V5, V10, V11, V12, V20, V9)
-	SHA256ROUND1(V5, V6, V7, V0, V1, V2, V3, V4, V11, V12, V13, V21, V10)
-	SHA256ROUND1(V4, V5, V6, V7, V0, V1, V2, V3, V12, V13, V14, V22, V11)
-	SHA256ROUND1(V3, V4, V5, V6, V7, V0, V1, V2, V13, V14, V15, V23, V12)
-	SHA256ROUND1(V2, V3, V4, V5, V6, V7, V0, V1, V14, V15, V16, V8, V13)
-	SHA256ROUND1(V1, V2, V3, V4, V5, V6, V7, V0, V15, V16, V17, V9, V14)
-	SHA256ROUND1(V0, V1, V2, V3, V4, V5, V6, V7, V16, V17, V18, V10, V15)
-	SHA256ROUND1(V7, V0, V1, V2, V3, V4, V5, V6, V17, V18, V19, V11, V16)
-	SHA256ROUND1(V6, V7, V0, V1, V2, V3, V4, V5, V18, V19, V20, V12, V17)
-	SHA256ROUND1(V5, V6, V7, V0, V1, V2, V3, V4, V19, V20, V21, V13, V18)
-	SHA256ROUND1(V4, V5, V6, V7, V0, V1, V2, V3, V20, V21, V22, V14, V19)
-	SHA256ROUND1(V3, V4, V5, V6, V7, V0, V1, V2, V21, V22, V23, V15, V20)
-	SHA256ROUND1(V2, V3, V4, V5, V6, V7, V0, V1, V22, V23, V8, V16, V21)
-	SHA256ROUND1(V1, V2, V3, V4, V5, V6, V7, V0, V23, V8, V9, V17, V22)
+	SHA256ROUND1(V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V18, V23, R_x000)
+	SHA256ROUND1(V7, V0, V1, V2, V3, V4, V5, V6, V9, V10, V11, V19, V8, R_x010)
+	SHA256ROUND1(V6, V7, V0, V1, V2, V3, V4, V5, V10, V11, V12, V20, V9, R_x020)
+	SHA256ROUND1(V5, V6, V7, V0, V1, V2, V3, V4, V11, V12, V13, V21, V10, R_x030)
+	SHA256ROUND1(V4, V5, V6, V7, V0, V1, V2, V3, V12, V13, V14, V22, V11, R_x040)
+	SHA256ROUND1(V3, V4, V5, V6, V7, V0, V1, V2, V13, V14, V15, V23, V12, R_x050)
+	SHA256ROUND1(V2, V3, V4, V5, V6, V7, V0, V1, V14, V15, V16, V8, V13, R_x060)
+	SHA256ROUND1(V1, V2, V3, V4, V5, V6, V7, V0, V15, V16, V17, V9, V14, R_x070)
+	SHA256ROUND1(V0, V1, V2, V3, V4, V5, V6, V7, V16, V17, V18, V10, V15, R_x080)
+	SHA256ROUND1(V7, V0, V1, V2, V3, V4, V5, V6, V17, V18, V19, V11, V16, R_x090)
+	SHA256ROUND1(V6, V7, V0, V1, V2, V3, V4, V5, V18, V19, V20, V12, V17, R_x0a0)
+	SHA256ROUND1(V5, V6, V7, V0, V1, V2, V3, V4, V19, V20, V21, V13, V18, R_x0b0)
+	SHA256ROUND1(V4, V5, V6, V7, V0, V1, V2, V3, V20, V21, V22, V14, V19, R_x0c0)
+	SHA256ROUND1(V3, V4, V5, V6, V7, V0, V1, V2, V21, V22, V23, V15, V20, R_x0d0)
+	SHA256ROUND1(V2, V3, V4, V5, V6, V7, V0, V1, V22, V23, V8, V16, V21, R_x0e0)
+	SHA256ROUND1(V1, V2, V3, V4, V5, V6, V7, V0, V23, V8, V9, V17, V22, R_x0f0)
+	ADD	$0x100, TBL
 
-	BC	0x10, 0, L16_xx		// bdnz
+	BDNZ	L16_xx
 
 	XXLOR	VS24, VS24, V10
 
@@ -406,17 +437,16 @@
 	CMPU	INP, END
 	BLT	loop
 
-	LVX	(TBL)(IDX), V8
-	ADD	$16, IDX
+	LVX	(TBL)(R_x000), V8
 	VPERM	V0, V1, KI, V0
-	LVX	(TBL)(IDX), V9
+	LVX	(TBL)(R_x010), V9
 	VPERM	V4, V5, KI, V4
 	VPERM	V0, V2, V8, V0
 	VPERM	V4, V6, V8, V4
 	VPERM	V0, V3, V9, V0
 	VPERM	V4, V7, V9, V4
-	STXVD2X	VS32, (CTX+HEX00)	// v0 = vs32
-	STXVD2X	VS36, (CTX+HEX10)	// v4 = vs36
+	STXVD2X	V0, (CTX+R_x000)
+	STXVD2X	V4, (CTX+R_x010)
 
 end:
 	RET
diff --git a/src/crypto/sha512/sha512.go b/src/crypto/sha512/sha512.go
index c800a29..9ae1b3a 100644
--- a/src/crypto/sha512/sha512.go
+++ b/src/crypto/sha512/sha512.go
@@ -153,17 +153,17 @@
 	default:
 		return nil, errors.New("crypto/sha512: invalid hash function")
 	}
-	b = appendUint64(b, d.h[0])
-	b = appendUint64(b, d.h[1])
-	b = appendUint64(b, d.h[2])
-	b = appendUint64(b, d.h[3])
-	b = appendUint64(b, d.h[4])
-	b = appendUint64(b, d.h[5])
-	b = appendUint64(b, d.h[6])
-	b = appendUint64(b, d.h[7])
+	b = binary.BigEndian.AppendUint64(b, d.h[0])
+	b = binary.BigEndian.AppendUint64(b, d.h[1])
+	b = binary.BigEndian.AppendUint64(b, d.h[2])
+	b = binary.BigEndian.AppendUint64(b, d.h[3])
+	b = binary.BigEndian.AppendUint64(b, d.h[4])
+	b = binary.BigEndian.AppendUint64(b, d.h[5])
+	b = binary.BigEndian.AppendUint64(b, d.h[6])
+	b = binary.BigEndian.AppendUint64(b, d.h[7])
 	b = append(b, d.x[:d.nx]...)
-	b = b[:len(b)+len(d.x)-int(d.nx)] // already zero
-	b = appendUint64(b, d.len)
+	b = b[:len(b)+len(d.x)-d.nx] // already zero
+	b = binary.BigEndian.AppendUint64(b, d.len)
 	return b, nil
 }
 
@@ -197,12 +197,6 @@
 	return nil
 }
 
-func appendUint64(b []byte, x uint64) []byte {
-	var a [8]byte
-	binary.BigEndian.PutUint64(a[:], x)
-	return append(b, a[:]...)
-}
-
 func consumeUint64(b []byte) ([]byte, uint64) {
 	_ = b[7]
 	x := uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
@@ -308,19 +302,23 @@
 func (d *digest) checkSum() [Size]byte {
 	// Padding. Add a 1 bit and 0 bits until 112 bytes mod 128.
 	len := d.len
-	var tmp [128]byte
+	var tmp [128 + 16]byte // padding + length buffer
 	tmp[0] = 0x80
+	var t uint64
 	if len%128 < 112 {
-		d.Write(tmp[0 : 112-len%128])
+		t = 112 - len%128
 	} else {
-		d.Write(tmp[0 : 128+112-len%128])
+		t = 128 + 112 - len%128
 	}
 
 	// Length in bits.
 	len <<= 3
-	binary.BigEndian.PutUint64(tmp[0:], 0) // upper 64 bits are always zero, because len variable has type uint64
-	binary.BigEndian.PutUint64(tmp[8:], len)
-	d.Write(tmp[0:16])
+	padlen := tmp[:t+16]
+	// Upper 64 bits are always zero, because len variable has type uint64,
+	// and tmp is already zeroed at that index, so we can skip updating it.
+	// binary.BigEndian.PutUint64(padlen[t+0:], 0)
+	binary.BigEndian.PutUint64(padlen[t+8:], len)
+	d.Write(padlen)
 
 	if d.nx != 0 {
 		panic("d.nx != 0")
diff --git a/src/crypto/sha512/sha512block_arm64.go b/src/crypto/sha512/sha512block_arm64.go
new file mode 100644
index 0000000..243eb5c
--- /dev/null
+++ b/src/crypto/sha512/sha512block_arm64.go
@@ -0,0 +1,18 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sha512
+
+import "internal/cpu"
+
+func block(dig *digest, p []byte) {
+	if cpu.ARM64.HasSHA512 {
+		blockAsm(dig, p)
+		return
+	}
+	blockGeneric(dig, p)
+}
+
+//go:noescape
+func blockAsm(dig *digest, p []byte)
diff --git a/src/crypto/sha512/sha512block_arm64.s b/src/crypto/sha512/sha512block_arm64.s
new file mode 100644
index 0000000..dfc35d6
--- /dev/null
+++ b/src/crypto/sha512/sha512block_arm64.s
@@ -0,0 +1,135 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Based on the Linux Kernel with the following comment:
+// Algorithm based on https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=fb87127bcefc17efab757606e1b1e333fd614dd0
+// Originally written by Ard Biesheuvel <[email protected]>
+
+#include "textflag.h"
+
+#define SHA512TRANS(i0, i1, i2, i3, i4, rc0, in0) \
+	VADD	in0.D2, rc0.D2, V5.D2 \
+	VEXT	$8, i3.B16, i2.B16, V6.B16 \
+	VEXT	$8, V5.B16, V5.B16, V5.B16 \
+	VEXT	$8, i2.B16, i1.B16, V7.B16 \
+	VADD	V5.D2, i3.D2, i3.D2 \
+
+#define SHA512ROUND(i0, i1, i2, i3, i4, rc0, rc1, in0, in1, in2, in3, in4) \
+	VLD1.P	16(R4), [rc1.D2] \
+	SHA512TRANS(i0, i1, i2, i3, i4, rc0, in0) \
+	VEXT	$8, in4.B16, in3.B16, V5.B16 \
+	SHA512SU0	in1.D2, in0.D2 \
+	SHA512H	V7.D2, V6, i3 \
+	SHA512SU1	V5.D2, in2.D2, in0.D2 \
+	VADD	i3.D2, i1.D2, i4.D2 \
+	SHA512H2	i0.D2, i1, i3
+
+#define SHA512ROUND_NO_UPDATE(i0, i1, i2, i3, i4, rc0, rc1, in0) \
+	VLD1.P	16(R4), [rc1.D2] \
+	SHA512TRANS(i0, i1, i2, i3, i4, rc0, in0) \
+	SHA512H	V7.D2, V6, i3 \
+	VADD	i3.D2, i1.D2, i4.D2 \
+	SHA512H2	i0.D2, i1, i3
+
+#define SHA512ROUND_LAST(i0, i1, i2, i3, i4, rc0, in0) \
+	SHA512TRANS(i0, i1, i2, i3, i4, rc0, in0) \
+	SHA512H	V7.D2, V6, i3 \
+	VADD	i3.D2, i1.D2, i4.D2 \
+	SHA512H2	i0.D2, i1, i3
+
+// func blockAsm(dig *digest, p []byte)
+TEXT ·blockAsm(SB),NOSPLIT,$0
+	MOVD	dig+0(FP), R0
+	MOVD	p_base+8(FP), R1
+	MOVD	p_len+16(FP), R2
+	MOVD	·_K+0(SB), R3
+
+	// long enough to prefetch
+	PRFM	(R3), PLDL3KEEP
+	// load digest
+	VLD1	(R0), [V8.D2, V9.D2, V10.D2, V11.D2]
+loop:
+	// load digest in V0-V3 keeping original in V8-V11
+	VMOV	V8.B16, V0.B16
+	VMOV	V9.B16, V1.B16
+	VMOV	V10.B16, V2.B16
+	VMOV	V11.B16, V3.B16
+
+	// load message data in V12-V19
+	VLD1.P	64(R1), [V12.D2, V13.D2, V14.D2, V15.D2]
+	VLD1.P	64(R1), [V16.D2, V17.D2, V18.D2, V19.D2]
+
+	// convert message into big endian format
+	VREV64	V12.B16, V12.B16
+	VREV64	V13.B16, V13.B16
+	VREV64	V14.B16, V14.B16
+	VREV64	V15.B16, V15.B16
+	VREV64	V16.B16, V16.B16
+	VREV64	V17.B16, V17.B16
+	VREV64	V18.B16, V18.B16
+	VREV64	V19.B16, V19.B16
+
+	MOVD	R3, R4
+	// load first 4 round consts in V20-V23
+	VLD1.P	64(R4), [V20.D2, V21.D2, V22.D2, V23.D2]
+
+	SHA512ROUND(V0, V1, V2, V3, V4, V20, V24, V12, V13, V19, V16, V17)
+	SHA512ROUND(V3, V0, V4, V2, V1, V21, V25, V13, V14, V12, V17, V18)
+	SHA512ROUND(V2, V3, V1, V4, V0, V22, V26, V14, V15, V13, V18, V19)
+	SHA512ROUND(V4, V2, V0, V1, V3, V23, V27, V15, V16, V14, V19, V12)
+	SHA512ROUND(V1, V4, V3, V0, V2, V24, V28, V16, V17, V15, V12, V13)
+
+	SHA512ROUND(V0, V1, V2, V3, V4, V25, V29, V17, V18, V16, V13, V14)
+	SHA512ROUND(V3, V0, V4, V2, V1, V26, V30, V18, V19, V17, V14, V15)
+	SHA512ROUND(V2, V3, V1, V4, V0, V27, V31, V19, V12, V18, V15, V16)
+	SHA512ROUND(V4, V2, V0, V1, V3, V28, V24, V12, V13, V19, V16, V17)
+	SHA512ROUND(V1, V4, V3, V0, V2, V29, V25, V13, V14, V12, V17, V18)
+
+	SHA512ROUND(V0, V1, V2, V3, V4, V30, V26, V14, V15, V13, V18, V19)
+	SHA512ROUND(V3, V0, V4, V2, V1, V31, V27, V15, V16, V14, V19, V12)
+	SHA512ROUND(V2, V3, V1, V4, V0, V24, V28, V16, V17, V15, V12, V13)
+	SHA512ROUND(V4, V2, V0, V1, V3, V25, V29, V17, V18, V16, V13, V14)
+	SHA512ROUND(V1, V4, V3, V0, V2, V26, V30, V18, V19, V17, V14, V15)
+
+	SHA512ROUND(V0, V1, V2, V3, V4, V27, V31, V19, V12, V18, V15, V16)
+	SHA512ROUND(V3, V0, V4, V2, V1, V28, V24, V12, V13, V19, V16, V17)
+	SHA512ROUND(V2, V3, V1, V4, V0, V29, V25, V13, V14, V12, V17, V18)
+	SHA512ROUND(V4, V2, V0, V1, V3, V30, V26, V14, V15, V13, V18, V19)
+	SHA512ROUND(V1, V4, V3, V0, V2, V31, V27, V15, V16, V14, V19, V12)
+
+	SHA512ROUND(V0, V1, V2, V3, V4, V24, V28, V16, V17, V15, V12, V13)
+	SHA512ROUND(V3, V0, V4, V2, V1, V25, V29, V17, V18, V16, V13, V14)
+	SHA512ROUND(V2, V3, V1, V4, V0, V26, V30, V18, V19, V17, V14, V15)
+	SHA512ROUND(V4, V2, V0, V1, V3, V27, V31, V19, V12, V18, V15, V16)
+	SHA512ROUND(V1, V4, V3, V0, V2, V28, V24, V12, V13, V19, V16, V17)
+
+	SHA512ROUND(V0, V1, V2, V3, V4, V29, V25, V13, V14, V12, V17, V18)
+	SHA512ROUND(V3, V0, V4, V2, V1, V30, V26, V14, V15, V13, V18, V19)
+	SHA512ROUND(V2, V3, V1, V4, V0, V31, V27, V15, V16, V14, V19, V12)
+	SHA512ROUND(V4, V2, V0, V1, V3, V24, V28, V16, V17, V15, V12, V13)
+	SHA512ROUND(V1, V4, V3, V0, V2, V25, V29, V17, V18, V16, V13, V14)
+
+	SHA512ROUND(V0, V1, V2, V3, V4, V26, V30, V18, V19, V17, V14, V15)
+	SHA512ROUND(V3, V0, V4, V2, V1, V27, V31, V19, V12, V18, V15, V16)
+
+	SHA512ROUND_NO_UPDATE(V2, V3, V1, V4, V0, V28, V24, V12)
+	SHA512ROUND_NO_UPDATE(V4, V2, V0, V1, V3, V29, V25, V13)
+	SHA512ROUND_NO_UPDATE(V1, V4, V3, V0, V2, V30, V26, V14)
+	SHA512ROUND_NO_UPDATE(V0, V1, V2, V3, V4, V31, V27, V15)
+
+	SHA512ROUND_LAST(V3, V0, V4, V2, V1, V24, V16)
+	SHA512ROUND_LAST(V2, V3, V1, V4, V0, V25, V17)
+	SHA512ROUND_LAST(V4, V2, V0, V1, V3, V26, V18)
+	SHA512ROUND_LAST(V1, V4, V3, V0, V2, V27, V19)
+
+	// add result to digest
+	VADD	V0.D2, V8.D2, V8.D2
+	VADD	V1.D2, V9.D2, V9.D2
+	VADD	V2.D2, V10.D2, V10.D2
+	VADD	V3.D2, V11.D2, V11.D2
+	SUB	$128, R2
+	CBNZ	R2, loop
+
+	VST1	[V8.D2, V9.D2, V10.D2, V11.D2], (R0)
+	RET
diff --git a/src/crypto/sha512/sha512block_generic.go b/src/crypto/sha512/sha512block_generic.go
index 9f0c2f2..02ecc2c 100644
--- a/src/crypto/sha512/sha512block_generic.go
+++ b/src/crypto/sha512/sha512block_generic.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build !amd64 && !s390x && !ppc64le && !ppc64
+//go:build !amd64 && !arm64 && !s390x && !ppc64le && !ppc64
 
 package sha512
 
diff --git a/src/crypto/subtle/xor.go b/src/crypto/subtle/xor.go
new file mode 100644
index 0000000..a8805ac
--- /dev/null
+++ b/src/crypto/subtle/xor.go
@@ -0,0 +1,24 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package subtle
+
+// XORBytes sets dst[i] = x[i] ^ y[i] for all i < n = min(len(x), len(y)),
+// returning n, the number of bytes written to dst.
+// If dst does not have length at least n,
+// XORBytes panics without writing anything to dst.
+func XORBytes(dst, x, y []byte) int {
+	n := len(x)
+	if len(y) < n {
+		n = len(y)
+	}
+	if n == 0 {
+		return 0
+	}
+	if n > len(dst) {
+		panic("subtle.XORBytes: dst too short")
+	}
+	xorBytes(&dst[0], &x[0], &y[0], n) // arch-specific
+	return n
+}
diff --git a/src/crypto/subtle/xor_amd64.go b/src/crypto/subtle/xor_amd64.go
new file mode 100644
index 0000000..3bb2f08
--- /dev/null
+++ b/src/crypto/subtle/xor_amd64.go
@@ -0,0 +1,10 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !purego
+
+package subtle
+
+//go:noescape
+func xorBytes(dst, a, b *byte, n int)
diff --git a/src/crypto/subtle/xor_amd64.s b/src/crypto/subtle/xor_amd64.s
new file mode 100644
index 0000000..8b04b58
--- /dev/null
+++ b/src/crypto/subtle/xor_amd64.s
@@ -0,0 +1,56 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !purego
+
+#include "textflag.h"
+
+// func xorBytes(dst, a, b *byte, n int)
+TEXT ·xorBytes(SB), NOSPLIT, $0
+	MOVQ  dst+0(FP), BX
+	MOVQ  a+8(FP), SI
+	MOVQ  b+16(FP), CX
+	MOVQ  n+24(FP), DX
+	TESTQ $15, DX            // AND 15 & len, if not zero jump to not_aligned.
+	JNZ   not_aligned
+
+aligned:
+	MOVQ $0, AX // position in slices
+
+loop16b:
+	MOVOU (SI)(AX*1), X0   // XOR 16byte forwards.
+	MOVOU (CX)(AX*1), X1
+	PXOR  X1, X0
+	MOVOU X0, (BX)(AX*1)
+	ADDQ  $16, AX
+	CMPQ  DX, AX
+	JNE   loop16b
+	RET
+
+loop_1b:
+	SUBQ  $1, DX           // XOR 1byte backwards.
+	MOVB  (SI)(DX*1), DI
+	MOVB  (CX)(DX*1), AX
+	XORB  AX, DI
+	MOVB  DI, (BX)(DX*1)
+	TESTQ $7, DX           // AND 7 & len, if not zero jump to loop_1b.
+	JNZ   loop_1b
+	CMPQ  DX, $0           // if len is 0, ret.
+	JE    ret
+	TESTQ $15, DX          // AND 15 & len, if zero jump to aligned.
+	JZ    aligned
+
+not_aligned:
+	TESTQ $7, DX           // AND $7 & len, if not zero jump to loop_1b.
+	JNE   loop_1b
+	SUBQ  $8, DX           // XOR 8bytes backwards.
+	MOVQ  (SI)(DX*1), DI
+	MOVQ  (CX)(DX*1), AX
+	XORQ  AX, DI
+	MOVQ  DI, (BX)(DX*1)
+	CMPQ  DX, $16          // if len is greater or equal 16 here, it must be aligned.
+	JGE   aligned
+
+ret:
+	RET
diff --git a/src/crypto/subtle/xor_arm64.go b/src/crypto/subtle/xor_arm64.go
new file mode 100644
index 0000000..65bab4c
--- /dev/null
+++ b/src/crypto/subtle/xor_arm64.go
@@ -0,0 +1,10 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !purego
+
+package subtle
+
+//go:noescape
+func xorBytes(dst, a, b *byte, n int)
diff --git a/src/crypto/subtle/xor_arm64.s b/src/crypto/subtle/xor_arm64.s
new file mode 100644
index 0000000..7632164
--- /dev/null
+++ b/src/crypto/subtle/xor_arm64.s
@@ -0,0 +1,69 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !purego
+
+#include "textflag.h"
+
+// func xorBytes(dst, a, b *byte, n int)
+TEXT ·xorBytes(SB), NOSPLIT|NOFRAME, $0
+	MOVD	dst+0(FP), R0
+	MOVD	a+8(FP), R1
+	MOVD	b+16(FP), R2
+	MOVD	n+24(FP), R3
+	CMP	$64, R3
+	BLT	tail
+loop_64:
+	VLD1.P	64(R1), [V0.B16, V1.B16, V2.B16, V3.B16]
+	VLD1.P	64(R2), [V4.B16, V5.B16, V6.B16, V7.B16]
+	VEOR	V0.B16, V4.B16, V4.B16
+	VEOR	V1.B16, V5.B16, V5.B16
+	VEOR	V2.B16, V6.B16, V6.B16
+	VEOR	V3.B16, V7.B16, V7.B16
+	VST1.P	[V4.B16, V5.B16, V6.B16, V7.B16], 64(R0)
+	SUBS	$64, R3
+	CMP	$64, R3
+	BGE	loop_64
+tail:
+	// quick end
+	CBZ	R3, end
+	TBZ	$5, R3, less_than32
+	VLD1.P	32(R1), [V0.B16, V1.B16]
+	VLD1.P	32(R2), [V2.B16, V3.B16]
+	VEOR	V0.B16, V2.B16, V2.B16
+	VEOR	V1.B16, V3.B16, V3.B16
+	VST1.P	[V2.B16, V3.B16], 32(R0)
+less_than32:
+	TBZ	$4, R3, less_than16
+	LDP.P	16(R1), (R11, R12)
+	LDP.P	16(R2), (R13, R14)
+	EOR	R11, R13, R13
+	EOR	R12, R14, R14
+	STP.P	(R13, R14), 16(R0)
+less_than16:
+	TBZ	$3, R3, less_than8
+	MOVD.P	8(R1), R11
+	MOVD.P	8(R2), R12
+	EOR	R11, R12, R12
+	MOVD.P	R12, 8(R0)
+less_than8:
+	TBZ	$2, R3, less_than4
+	MOVWU.P	4(R1), R13
+	MOVWU.P	4(R2), R14
+	EORW	R13, R14, R14
+	MOVWU.P	R14, 4(R0)
+less_than4:
+	TBZ	$1, R3, less_than2
+	MOVHU.P	2(R1), R15
+	MOVHU.P	2(R2), R16
+	EORW	R15, R16, R16
+	MOVHU.P	R16, 2(R0)
+less_than2:
+	TBZ	$0, R3, end
+	MOVBU	(R1), R17
+	MOVBU	(R2), R19
+	EORW	R17, R19, R19
+	MOVBU	R19, (R0)
+end:
+	RET
diff --git a/src/crypto/subtle/xor_generic.go b/src/crypto/subtle/xor_generic.go
new file mode 100644
index 0000000..482fcf9
--- /dev/null
+++ b/src/crypto/subtle/xor_generic.go
@@ -0,0 +1,58 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build (!amd64 && !arm64 && !ppc64 && !ppc64le) || purego
+
+package subtle
+
+import (
+	"runtime"
+	"unsafe"
+)
+
+const wordSize = unsafe.Sizeof(uintptr(0))
+
+const supportsUnaligned = runtime.GOARCH == "386" ||
+	runtime.GOARCH == "amd64" ||
+	runtime.GOARCH == "ppc64" ||
+	runtime.GOARCH == "ppc64le" ||
+	runtime.GOARCH == "s390x"
+
+func xorBytes(dstb, xb, yb *byte, n int) {
+	// xorBytes assembly is written using pointers and n. Back to slices.
+	dst := unsafe.Slice(dstb, n)
+	x := unsafe.Slice(xb, n)
+	y := unsafe.Slice(yb, n)
+
+	if supportsUnaligned || aligned(dstb, xb, yb) {
+		xorLoop(words(dst), words(x), words(y))
+		if uintptr(n)%wordSize == 0 {
+			return
+		}
+		done := n &^ int(wordSize-1)
+		dst = dst[done:]
+		x = x[done:]
+		y = y[done:]
+	}
+	xorLoop(dst, x, y)
+}
+
+// aligned reports whether dst, x, and y are all word-aligned pointers.
+func aligned(dst, x, y *byte) bool {
+	return (uintptr(unsafe.Pointer(dst))|uintptr(unsafe.Pointer(x))|uintptr(unsafe.Pointer(y)))&(wordSize-1) == 0
+}
+
+// words returns a []uintptr pointing at the same data as x,
+// with any trailing partial word removed.
+func words(x []byte) []uintptr {
+	return unsafe.Slice((*uintptr)(unsafe.Pointer(&x[0])), uintptr(len(x))/wordSize)
+}
+
+func xorLoop[T byte | uintptr](dst, x, y []T) {
+	x = x[:len(dst)] // remove bounds check in loop
+	y = y[:len(dst)] // remove bounds check in loop
+	for i := range dst {
+		dst[i] = x[i] ^ y[i]
+	}
+}
diff --git a/src/crypto/subtle/xor_ppc64x.go b/src/crypto/subtle/xor_ppc64x.go
new file mode 100644
index 0000000..760463c
--- /dev/null
+++ b/src/crypto/subtle/xor_ppc64x.go
@@ -0,0 +1,10 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build (ppc64 || ppc64le) && !purego
+
+package subtle
+
+//go:noescape
+func xorBytes(dst, a, b *byte, n int)
diff --git a/src/crypto/subtle/xor_ppc64x.s b/src/crypto/subtle/xor_ppc64x.s
new file mode 100644
index 0000000..72bb80d
--- /dev/null
+++ b/src/crypto/subtle/xor_ppc64x.s
@@ -0,0 +1,87 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build (ppc64 || ppc64le) && !purego
+
+#include "textflag.h"
+
+// func xorBytes(dst, a, b *byte, n int)
+TEXT ·xorBytes(SB), NOSPLIT, $0
+	MOVD	dst+0(FP), R3	// R3 = dst
+	MOVD	a+8(FP), R4	// R4 = a
+	MOVD	b+16(FP), R5	// R5 = b
+	MOVD	n+24(FP), R6	// R6 = n
+
+	CMPU	R6, $32, CR7	// Check if n ≥ 32 bytes
+	MOVD	R0, R8		// R8 = index
+	CMPU	R6, $8, CR6	// Check if 8 ≤ n < 32 bytes
+	BLT	CR6, small	// Smaller than 8
+	BLT	CR7, xor16	// Case for 16 ≤ n < 32 bytes
+
+	// Case for n ≥ 32 bytes
+preloop32:
+	SRD	$5, R6, R7	// Setup loop counter
+	MOVD	R7, CTR
+	MOVD	$16, R10
+	ANDCC	$31, R6, R9	// Check for tailing bytes for later
+loop32:
+	LXVD2X		(R4)(R8), VS32		// VS32 = a[i,...,i+15]
+	LXVD2X		(R4)(R10), VS34
+	LXVD2X		(R5)(R8), VS33		// VS33 = b[i,...,i+15]
+	LXVD2X		(R5)(R10), VS35
+	XXLXOR		VS32, VS33, VS32	// VS34 = a[] ^ b[]
+	XXLXOR		VS34, VS35, VS34
+	STXVD2X		VS32, (R3)(R8)		// Store to dst
+	STXVD2X		VS34, (R3)(R10)
+	ADD		$32, R8			// Update index
+	ADD		$32, R10
+	BC		16, 0, loop32		// bdnz loop16
+
+	BEQ		CR0, done
+
+	MOVD		R9, R6
+	CMP		R6, $8
+	BLT		small
+xor16:
+	CMP		R6, $16
+	BLT		xor8
+	LXVD2X		(R4)(R8), VS32
+	LXVD2X		(R5)(R8), VS33
+	XXLXOR		VS32, VS33, VS32
+	STXVD2X		VS32, (R3)(R8)
+	ADD		$16, R8
+	ADD		$-16, R6
+	CMP		R6, $8
+	BLT		small
+xor8:
+	// Case for 8 ≤ n < 16 bytes
+	MOVD    (R4)(R8), R14   // R14 = a[i,...,i+7]
+	MOVD    (R5)(R8), R15   // R15 = b[i,...,i+7]
+	XOR     R14, R15, R16   // R16 = a[] ^ b[]
+	SUB     $8, R6          // n = n - 8
+	MOVD    R16, (R3)(R8)   // Store to dst
+	ADD     $8, R8
+
+	// Check if we're finished
+	CMP     R6, R0
+	BGT     small
+	RET
+
+	// Case for n < 8 bytes and tailing bytes from the
+	// previous cases.
+small:
+	CMP	R6, R0
+	BEQ	done
+	MOVD	R6, CTR		// Setup loop counter
+
+loop:
+	MOVBZ	(R4)(R8), R14	// R14 = a[i]
+	MOVBZ	(R5)(R8), R15	// R15 = b[i]
+	XOR	R14, R15, R16	// R16 = a[i] ^ b[i]
+	MOVB	R16, (R3)(R8)	// Store to dst
+	ADD	$1, R8
+	BC	16, 0, loop	// bdnz loop
+
+done:
+	RET
diff --git a/src/crypto/subtle/xor_test.go b/src/crypto/subtle/xor_test.go
new file mode 100644
index 0000000..7d89b83
--- /dev/null
+++ b/src/crypto/subtle/xor_test.go
@@ -0,0 +1,106 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package subtle_test
+
+import (
+	"bytes"
+	"crypto/rand"
+	. "crypto/subtle"
+	"fmt"
+	"io"
+	"testing"
+)
+
+func TestXORBytes(t *testing.T) {
+	for n := 1; n <= 1024; n++ {
+		if n > 16 && testing.Short() {
+			n += n >> 3
+		}
+		for alignP := 0; alignP < 8; alignP++ {
+			for alignQ := 0; alignQ < 8; alignQ++ {
+				for alignD := 0; alignD < 8; alignD++ {
+					p := make([]byte, alignP+n, alignP+n+10)[alignP:]
+					q := make([]byte, alignQ+n, alignQ+n+10)[alignQ:]
+					if n&1 != 0 {
+						p = p[:n]
+					} else {
+						q = q[:n]
+					}
+					if _, err := io.ReadFull(rand.Reader, p); err != nil {
+						t.Fatal(err)
+					}
+					if _, err := io.ReadFull(rand.Reader, q); err != nil {
+						t.Fatal(err)
+					}
+
+					d := make([]byte, alignD+n, alignD+n+10)
+					for i := range d {
+						d[i] = 0xdd
+					}
+					want := make([]byte, len(d), cap(d))
+					copy(want[:cap(want)], d[:cap(d)])
+					for i := 0; i < n; i++ {
+						want[alignD+i] = p[i] ^ q[i]
+					}
+
+					if XORBytes(d[alignD:], p, q); !bytes.Equal(d, want) {
+						t.Fatalf("n=%d alignP=%d alignQ=%d alignD=%d:\n\tp = %x\n\tq = %x\n\td = %x\n\twant %x\n", n, alignP, alignQ, alignD, p, q, d, want)
+					}
+				}
+			}
+		}
+	}
+}
+
+func TestXorBytesPanic(t *testing.T) {
+	mustPanic(t, "subtle.XORBytes: dst too short", func() {
+		XORBytes(nil, make([]byte, 1), make([]byte, 1))
+	})
+	mustPanic(t, "subtle.XORBytes: dst too short", func() {
+		XORBytes(make([]byte, 1), make([]byte, 2), make([]byte, 3))
+	})
+}
+
+func min(a, b []byte) int {
+	n := len(a)
+	if len(b) < n {
+		n = len(b)
+	}
+	return n
+}
+
+func BenchmarkXORBytes(b *testing.B) {
+	dst := make([]byte, 1<<15)
+	data0 := make([]byte, 1<<15)
+	data1 := make([]byte, 1<<15)
+	sizes := []int64{1 << 3, 1 << 7, 1 << 11, 1 << 15}
+	for _, size := range sizes {
+		b.Run(fmt.Sprintf("%dBytes", size), func(b *testing.B) {
+			s0 := data0[:size]
+			s1 := data1[:size]
+			b.SetBytes(int64(size))
+			for i := 0; i < b.N; i++ {
+				XORBytes(dst, s0, s1)
+			}
+		})
+	}
+}
+
+func mustPanic(t *testing.T, expected string, f func()) {
+	t.Helper()
+	defer func() {
+		switch msg := recover().(type) {
+		case nil:
+			t.Errorf("expected panic(%q), but did not panic", expected)
+		case string:
+			if msg != expected {
+				t.Errorf("expected panic(%q), but got panic(%q)", expected, msg)
+			}
+		default:
+			t.Errorf("expected panic(%q), but got panic(%T%v)", expected, msg, msg)
+		}
+	}()
+	f()
+}
diff --git a/src/crypto/tls/boring_test.go b/src/crypto/tls/boring_test.go
index f743fc8..ba68f35 100644
--- a/src/crypto/tls/boring_test.go
+++ b/src/crypto/tls/boring_test.go
@@ -16,6 +16,7 @@
 	"crypto/x509/pkix"
 	"encoding/pem"
 	"fmt"
+	"internal/obscuretestdata"
 	"math/big"
 	"net"
 	"runtime"
@@ -268,7 +269,7 @@
 
 	go Client(c, clientConfig).Handshake()
 	srv := Server(s, testConfig)
-	msg, err := srv.readHandshake()
+	msg, err := srv.readHandshake(nil)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -311,7 +312,7 @@
 	// Set up some roots, intermediate CAs, and leaf certs with various algorithms.
 	// X_Y is X signed by Y.
 	R1 := boringCert(t, "R1", boringRSAKey(t, 2048), nil, boringCertCA|boringCertFIPSOK)
-	R2 := boringCert(t, "R2", boringRSAKey(t, 4096), nil, boringCertCA)
+	R2 := boringCert(t, "R2", boringRSAKey(t, 512), nil, boringCertCA)
 
 	M1_R1 := boringCert(t, "M1_R1", boringECDSAKey(t, elliptic.P256()), R1, boringCertCA|boringCertFIPSOK)
 	M2_R1 := boringCert(t, "M2_R1", boringECDSAKey(t, elliptic.P224()), R1, boringCertCA)
@@ -558,56 +559,56 @@
 )
 
 func init() {
-	block, _ := pem.Decode([]byte(`
------BEGIN CERTIFICATE-----
-MIIC/zCCAeegAwIBAgIRALHHX/kh4+4zMU9DarzBEcQwDQYJKoZIhvcNAQELBQAw
-EjEQMA4GA1UEChMHQWNtZSBDbzAeFw0xMTAxMDExNTA0MDVaFw0yMDEyMjkxNTA0
-MDVaMBIxEDAOBgNVBAoTB0FjbWUgQ28wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
-ggEKAoIBAQCf8fk0N6ieCBX4IOVIfKitt4kGcOQLeimCfsjqqHcysMIVGEtFSM6E
-4Ay141f/7IqdW0UtIqNb4PXhROID7yDxR284xL6XbCuv/t5hP3UcehYc3hmLiyVd
-MkZQiZWtfUUJf/1qOtM+ohNg59LRWp4d+6iX0la1JL3EwCIckkNjJ9hQbF7Pb2CS
-+ES9Yo55KAap8KOblpcR8MBSN38bqnwjfQdCXvOEOjam2HUxKzEFX5MA+fA0me4C
-ioCcCRLWKl+GoN9F8fABfoZ+T+2eal4DLuO95rXR8SrOIVBh3XFOr/RVhjtXcNVF
-ZKcvDt6d68V6jAKAYKm5nlj9GPpd4v+rAgMBAAGjUDBOMA4GA1UdDwEB/wQEAwIF
-oDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMBkGA1UdEQQSMBCC
-DmV4YW1wbGUuZ29sYW5nMA0GCSqGSIb3DQEBCwUAA4IBAQCOoYsVcFCBhboqe3WH
-dC6V7XXXECmnjh01r8h80yv0NR379nSD3cw2M+HKvaXysWqrl5hjGVKw0vtwD81r
-V4JzDu7IfIog5m8+QNC+7LqDZsz88vDKOrsoySVOmUCgmCKFXew+LA+eO/iQEJTr
-7ensddOeXJEp27Ed5vW+kmWW3Qmglc2Gwy8wFrMDIqnrnOzBA4oCnDEgtXJt0zog
-nRwbfEMAWi1aQRy5dT9KA3SP9mo5SeTFSzGGHiE4s4gHUe7jvsAFF2qgtD6+wH6s
-z9b6shxnC7g5IlBKhI7SVB/Uqt2ydJ+kH1YbjMcIq6NAM5eNMKgZuJr3+zwsSgwh
-GNaE
------END CERTIFICATE-----`))
+	block, _ := pem.Decode(obscuretestdata.Rot13([]byte(`
+-----ORTVA PREGVSVPNGR-----
+ZVVP/mPPNrrtNjVONtVENYUUK/xu4+4mZH9QnemORpDjQDLWXbMVuipANDRYODNj
+RwRDZN4TN1HRPuZUDJAgMFOQomNrSj0kZGNkZQRkAGN0ZQInSj0lZQRlZwxkAGN0
+ZQInZOVkRQNBOtAIONbGO0SwoJHtD28jttRvZN0TPFdTFVo3QDRONDHNN4VOQjNj
+ttRXNbVONDPs8sx0A6vrPOK4VBIVsXvgg4xTpBDYrvzPsfwddUplfZVITRgSFZ6R
+4Nl141s/7VdqJ0HgVdAo4CKuEBVQ7lQkE284kY6KoPhi/g5uC3HpruLp3uzYvlIq
+ZxMDvMJgsHHWs/1dBgZ+buAt59YEJc4q+6vK0yn1WY3RjPVpxxAwW9uDoS7Co2PF
++RF9Lb55XNnc8XBoycpE8ZOFA38odajwsDqPKiBRBwnz2UHkXmRSK5ZN+sN0zr4P
+vbPpPEYJXy+TbA9S8sNOsbM+G+2rny4QYhB95eKE8FeBVIOu3KSBe/EIuwgKpAIS
+MXpiQg6q68I6wNXNLXz5ayw9TCcq4i+eNtZONNTwHQOBZN4TN1HqQjRO/jDRNjVS
+bQNGOtAIUFHRQQNXOtteOtRSODpQNGNZOtAIUEZONs8RNwNNZOxTN1HqRDDFZOPP
+QzI4LJ1joTHhM29fLJ5aZN0TPFdTFVo3QDROPjHNN4VONDPBbLfIpSPOuobdr3JU
+qP6I7KKKRPzawu01e8u80li0AE379aFQ3pj2Z+UXinKlfJdey5uwTIXj0igjQ81e
+I4WmQh7VsVbt5z8+DAP+7YdQMfm88iQXBefblFIBzHPtzPXSKrj+YN+rB/vDRWGe
+7rafqqBrKWRc27Rq5iJ+xzJJ3Dztyp2Tjl8jSeZQVdaeaBmON4bPaQRtgKWg0mbt
+aEjosRZNJv1nDEl5qG9XN3FC9zb5FrGSFmTTUvR4f4tUHr7wifNSS2dtgQ6+jU6f
+m9o6fukaP7t5VyOXuV7FIO/Hdg2lqW+xU1LowZpVd6ANZ5rAZXtMhWe3+mjfFtju
+TAnR
+-----RAQ PREGVSVPNGR-----`)))
 	testRSA2048Certificate = block.Bytes
 
-	block, _ = pem.Decode([]byte(`
------BEGIN RSA PRIVATE KEY-----
-MIIEpAIBAAKCAQEAn/H5NDeonggV+CDlSHyorbeJBnDkC3opgn7I6qh3MrDCFRhL
-RUjOhOAMteNX/+yKnVtFLSKjW+D14UTiA+8g8UdvOMS+l2wrr/7eYT91HHoWHN4Z
-i4slXTJGUImVrX1FCX/9ajrTPqITYOfS0VqeHfuol9JWtSS9xMAiHJJDYyfYUGxe
-z29gkvhEvWKOeSgGqfCjm5aXEfDAUjd/G6p8I30HQl7zhDo2pth1MSsxBV+TAPnw
-NJnuAoqAnAkS1ipfhqDfRfHwAX6Gfk/tnmpeAy7jvea10fEqziFQYd1xTq/0VYY7
-V3DVRWSnLw7enevFeowCgGCpuZ5Y/Rj6XeL/qwIDAQABAoIBAQCNpMZifd/vg42h
-HdCvLuZaYS0R7SunFlpoXEsltGdLFsnp0IfoJZ/ugFQBSAIIfLwMumU6oXA1z7Uv
-98aIYV61DePrTCDVDFBsHbNmP8JAo8WtbusEbwd5zyoB7LYG2+clkJklWE73KqUq
-rmI+UJeyScl2Gin7ZTxBXz1WPBk9VwcnwkeaXpgASIBW23fhECM9gnYEEwaBez5T
-6Me8d1tHtYQv7vsKe7ro9w9/HKrRXejqYKK1LxkhfFriyV+m8LZJZn2nXOa6G3gF
-Nb8Qk1Uk5PUBENBmyMFJhT4M/uuSq4YtMrrO2gi8Q+fPhuGzc5SshYKRBp0W4P5r
-mtVCtEFRAoGBAMENBIFLrV2+HsGj0xYFasKov/QPe6HSTR1Hh2IZONp+oK4oszWE
-jBT4VcnITmpl6tC1Wy4GcrxjNgKIFZAj+1x1LUULdorXkuG8yr0tAhG9zNyfWsSy
-PrSovC0UVbzr8Jxxla+kQVxEQQqWQxPlEVuL8kXaIDA6Lyt1Hpua2LvPAoGBANQZ
-c6Lq2T7+BxLxNdi2m8kZzej5kgzBp/XdVsbFWRlebIX2KrFHsrHzT9PUk3DE1vZK
-M6pzTt94nQhWSkDgCaw1SohElJ3HFIFwcusF1SJAc3pQepd8ug6IYdlpDMLtBj/P
-/5P6BVUtgo05E4+I/T3iYatmglQxTtlZ0RkSV2llAoGBALOXkKFX7ahPvf0WksDh
-uTfuFOTPoowgQG0EpgW0wRdCxeg/JLic3lSD0gsttQV2WsRecryWcxaelRg10RmO
-38BbogmhaF4xvgsSvujOfiZTE8oK1T43M+6NKsIlML3YILbpU/9aJxPWy0s2DqDr
-cQJhZrlk+pzjBA7Bnf/URdwxAoGAKR/CNw14D+mrL3YLbbiCXiydqxVwxv5pdZdz
-8thi3TNcsWC4iGURdcVqbfUinVPdJiXe/Kac3WGCeRJaFVgbKAOxLti1RB5MkIhg
-D8eyupBqk4W1L1gkrxqsdj4TFlxkwMywjl2E2S4YyQ8PBt6V04DoVRZsIKzqz+PF
-UionPq0CgYBCYXvqioJhPewkOq/Y5wrDBeZW1FQK5QD9W5M8/5zxd4rdvJtjhbJp
-oOrtvMdrl6upy9Hz4BJD3FXwVFiPFE7jqeNqi0F21viLxBPMMD3UODF6LL5EyLiR
-9V4xVMS8KXxvg7rxsuqzMPscViaWUL6WNVBhsD2+92dHxSXzz5EJKQ==
------END RSA PRIVATE KEY-----`))
+	block, _ = pem.Decode(obscuretestdata.Rot13([]byte(`
+-----ORTVA EFN CEVINGR XRL-----
+ZVVRcNVONNXPNDRNa/U5AQrbattI+PQyFUlbeorWOaQxP3bcta7V6du3ZeQPSEuY
+EHwBuBNZgrAK/+lXaIgSYFXwJ+Q14HGvN+8t8HqiBZF+y2jee/7rLG91UUbJUA4M
+v4fyKGWTHVzIeK1SPK/9nweGCdVGLBsF0IdrUshby9WJgFF9kZNvUWWQLlsLHTkr
+m29txiuRiJXBrFtTdsPwz5nKRsQNHwq/T6c8V30UDy7muQb2cgu1ZFfkOI+GNCaj
+AWahNbdNaNxF1vcsudQsEsUjNK6Tsx/gazcrNl7wirn10sRdmvSDLq1kGd/0ILL7
+I3QIEJFaYj7rariSrbjPtTPchM5L/Ew6KrY/djVQNDNONbVONDPAcZMvsq/it42u
+UqPiYhMnLF0E7FhaSycbKRfygTqYSfac0VsbWM/htSDOFNVVsYjZhzH6bKN1m7Hi
+98nVLI61QrCeGPQIQSOfUoAzC8WNb8JgohfRojq5mlbO7YLT2+pyxWxyJR73XdHd
+ezV+HWrlFpy2Tva7MGkOKm1JCOx9IjpajxrnKctNFVOJ23suRPZ9taLRRjnOrm5G
+6Zr8q1gUgLDi7ifXr7eb9j9/UXeEKrwdLXX1YkxusSevlI+z8YMWMa2aKBn6T3tS
+Ao8Dx1Hx5CHORAOzlZSWuG4Z/hhFd4LgZeeB2tv8D+sCuhTmp5FfuLXEOc0J4C5e
+zgIPgRSENbTONZRAOVSYeI2+UfTw0kLSnfXbi/DCr6UFGE1Uu2VMBAc+bX4bfmJR
+wOG4IpaVGzcy6gP1Jl4TpekwAtXVSMNw+1k1YHHYqbeKxhT8le0gNuT9mAlsJfFl
+CeFbiP0HIome8Wkkyn+xDIkRDDdJDkCyRIhY8xKnVQN6Ylg1Uchn2YiCNbTONADM
+p6Yd2G7+OkYkAqv2z8xMmrw5xtmOc/KqIfoSJEyroVK2XeSUfeUmG9CHx3QR1iMX
+Z6cmGg94aDuJFxQtPnj1FbuRyW3USVSjphfS1FWNp3cDrcq8ht6VLqycQZYgOw/C
+/5C6OIHgtb05R4+V/G3vLngztyDkGgyM0ExFI2yyNbTONYBKxXSK7nuCis0JxfQu
+hGshSBGCbbjtDT0RctJ0jEqPkrt/WYvp3yFQ0tfggDI2JfErpelJpknryEt10EzB
+38OobtzunS4kitfFihwBsvMGR8bX1G43Z+6AXfVyZY3LVYocH/9nWkCJl0f2QdQe
+pDWuMeyx+cmwON7Oas/HEqjkNbTNXE/PAj14Q+zeY3LYoovPKvlqdkIjki5cqMqm
+8guv3GApfJP4vTHEqpIdosHvaICqWvKr/Xnp3JTPrEWnSItoXNBkYgv1EO5ZxVut
+Q8rlhcOdx4J1Y1txekdfqw4GSykxjZljwy2R2F4LlD8COg6I04QbIEMfVXmdm+CS
+HvbaCd0PtLOPLKidvbWuCrjxBd/L5jeQOrMJ1SDX5DQ9J5Z8/5mkq4eqiWgwuoWc
+bBegiZqey6hcl9Um4OWQ3SKjISvCSR7wdrAdv0S21ivYkOCZZQ3HBQS6YY5RlYvE
+9I4kIZF8XKkit7ekfhdmZCfpIvnJHY6JAIOufQ2+92qUkFKmm5RWXD==
+-----RAQ EFN CEVINGR XRL-----`)))
 	var err error
 	testRSA2048PrivateKey, err = x509.ParsePKCS1PrivateKey(block.Bytes)
 	if err != nil {
diff --git a/src/crypto/tls/cache.go b/src/crypto/tls/cache.go
new file mode 100644
index 0000000..fc8f2c0
--- /dev/null
+++ b/src/crypto/tls/cache.go
@@ -0,0 +1,95 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+	"crypto/x509"
+	"runtime"
+	"sync"
+	"sync/atomic"
+)
+
+type cacheEntry struct {
+	refs atomic.Int64
+	cert *x509.Certificate
+}
+
+// certCache implements an intern table for reference counted x509.Certificates,
+// implemented in a similar fashion to BoringSSL's CRYPTO_BUFFER_POOL. This
+// allows for a single x509.Certificate to be kept in memory and referenced from
+// multiple Conns. Returned references should not be mutated by callers. Certificates
+// are still safe to use after they are removed from the cache.
+//
+// Certificates are returned wrapped in a activeCert struct that should be held by
+// the caller. When references to the activeCert are freed, the number of references
+// to the certificate in the cache is decremented. Once the number of references
+// reaches zero, the entry is evicted from the cache.
+//
+// The main difference between this implementation and CRYPTO_BUFFER_POOL is that
+// CRYPTO_BUFFER_POOL is a more  generic structure which supports blobs of data,
+// rather than specific structures. Since we only care about x509.Certificates,
+// certCache is implemented as a specific cache, rather than a generic one.
+//
+// See https://boringssl.googlesource.com/boringssl/+/master/include/openssl/pool.h
+// and https://boringssl.googlesource.com/boringssl/+/master/crypto/pool/pool.c
+// for the BoringSSL reference.
+type certCache struct {
+	sync.Map
+}
+
+var clientCertCache = new(certCache)
+
+// activeCert is a handle to a certificate held in the cache. Once there are
+// no alive activeCerts for a given certificate, the certificate is removed
+// from the cache by a finalizer.
+type activeCert struct {
+	cert *x509.Certificate
+}
+
+// active increments the number of references to the entry, wraps the
+// certificate in the entry in a activeCert, and sets the finalizer.
+//
+// Note that there is a race between active and the finalizer set on the
+// returned activeCert, triggered if active is called after the ref count is
+// decremented such that refs may be > 0 when evict is called. We consider this
+// safe, since the caller holding an activeCert for an entry that is no longer
+// in the cache is fine, with the only side effect being the memory overhead of
+// there being more than one distinct reference to a certificate alive at once.
+func (cc *certCache) active(e *cacheEntry) *activeCert {
+	e.refs.Add(1)
+	a := &activeCert{e.cert}
+	runtime.SetFinalizer(a, func(_ *activeCert) {
+		if e.refs.Add(-1) == 0 {
+			cc.evict(e)
+		}
+	})
+	return a
+}
+
+// evict removes a cacheEntry from the cache.
+func (cc *certCache) evict(e *cacheEntry) {
+	cc.Delete(string(e.cert.Raw))
+}
+
+// newCert returns a x509.Certificate parsed from der. If there is already a copy
+// of the certificate in the cache, a reference to the existing certificate will
+// be returned. Otherwise, a fresh certificate will be added to the cache, and
+// the reference returned. The returned reference should not be mutated.
+func (cc *certCache) newCert(der []byte) (*activeCert, error) {
+	if entry, ok := cc.Load(string(der)); ok {
+		return cc.active(entry.(*cacheEntry)), nil
+	}
+
+	cert, err := x509.ParseCertificate(der)
+	if err != nil {
+		return nil, err
+	}
+
+	entry := &cacheEntry{cert: cert}
+	if entry, loaded := cc.LoadOrStore(string(der), entry); loaded {
+		return cc.active(entry.(*cacheEntry)), nil
+	}
+	return cc.active(entry), nil
+}
diff --git a/src/crypto/tls/cache_test.go b/src/crypto/tls/cache_test.go
new file mode 100644
index 0000000..2846734
--- /dev/null
+++ b/src/crypto/tls/cache_test.go
@@ -0,0 +1,117 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+	"encoding/pem"
+	"fmt"
+	"runtime"
+	"testing"
+	"time"
+)
+
+func TestCertCache(t *testing.T) {
+	cc := certCache{}
+	p, _ := pem.Decode([]byte(rsaCertPEM))
+	if p == nil {
+		t.Fatal("Failed to decode certificate")
+	}
+
+	certA, err := cc.newCert(p.Bytes)
+	if err != nil {
+		t.Fatalf("newCert failed: %s", err)
+	}
+	certB, err := cc.newCert(p.Bytes)
+	if err != nil {
+		t.Fatalf("newCert failed: %s", err)
+	}
+	if certA.cert != certB.cert {
+		t.Fatal("newCert returned a unique reference for a duplicate certificate")
+	}
+
+	if entry, ok := cc.Load(string(p.Bytes)); !ok {
+		t.Fatal("cache does not contain expected entry")
+	} else {
+		if refs := entry.(*cacheEntry).refs.Load(); refs != 2 {
+			t.Fatalf("unexpected number of references: got %d, want 2", refs)
+		}
+	}
+
+	timeoutRefCheck := func(t *testing.T, key string, count int64) {
+		t.Helper()
+		c := time.After(4 * time.Second)
+		for {
+			select {
+			case <-c:
+				t.Fatal("timed out waiting for expected ref count")
+			default:
+				e, ok := cc.Load(key)
+				if !ok && count != 0 {
+					t.Fatal("cache does not contain expected key")
+				} else if count == 0 && !ok {
+					return
+				}
+
+				if e.(*cacheEntry).refs.Load() == count {
+					return
+				}
+			}
+		}
+	}
+
+	// Keep certA alive until at least now, so that we can
+	// purposefully nil it and force the finalizer to be
+	// called.
+	runtime.KeepAlive(certA)
+	certA = nil
+	runtime.GC()
+
+	timeoutRefCheck(t, string(p.Bytes), 1)
+
+	// Keep certB alive until at least now, so that we can
+	// purposefully nil it and force the finalizer to be
+	// called.
+	runtime.KeepAlive(certB)
+	certB = nil
+	runtime.GC()
+
+	timeoutRefCheck(t, string(p.Bytes), 0)
+}
+
+func BenchmarkCertCache(b *testing.B) {
+	p, _ := pem.Decode([]byte(rsaCertPEM))
+	if p == nil {
+		b.Fatal("Failed to decode certificate")
+	}
+
+	cc := certCache{}
+	b.ReportAllocs()
+	b.ResetTimer()
+	// We expect that calling newCert additional times after
+	// the initial call should not cause additional allocations.
+	for extra := 0; extra < 4; extra++ {
+		b.Run(fmt.Sprint(extra), func(b *testing.B) {
+			actives := make([]*activeCert, extra+1)
+			b.ResetTimer()
+			for i := 0; i < b.N; i++ {
+				var err error
+				actives[0], err = cc.newCert(p.Bytes)
+				if err != nil {
+					b.Fatal(err)
+				}
+				for j := 0; j < extra; j++ {
+					actives[j+1], err = cc.newCert(p.Bytes)
+					if err != nil {
+						b.Fatal(err)
+					}
+				}
+				for j := 0; j < extra+1; j++ {
+					actives[j] = nil
+				}
+				runtime.GC()
+			}
+		})
+	}
+}
diff --git a/src/crypto/tls/cipher_suites.go b/src/crypto/tls/cipher_suites.go
index 9a1fa31..04e6dfe 100644
--- a/src/crypto/tls/cipher_suites.go
+++ b/src/crypto/tls/cipher_suites.go
@@ -473,7 +473,7 @@
 	return f.aead.Open(out, f.nonce[:], ciphertext, additionalData)
 }
 
-// xoredNonceAEAD wraps an AEAD by XORing in a fixed pattern to the nonce
+// xorNonceAEAD wraps an AEAD by XORing in a fixed pattern to the nonce
 // before each call.
 type xorNonceAEAD struct {
 	nonceMask [aeadNonceLength]byte
diff --git a/src/crypto/tls/common.go b/src/crypto/tls/common.go
index 1861efc..5394d64 100644
--- a/src/crypto/tls/common.go
+++ b/src/crypto/tls/common.go
@@ -246,6 +246,8 @@
 	// On the client side, it can't be empty. On the server side, it can be
 	// empty if Config.ClientAuth is not RequireAnyClientCert or
 	// RequireAndVerifyClientCert.
+	//
+	// PeerCertificates and its contents should not be modified.
 	PeerCertificates []*x509.Certificate
 
 	// VerifiedChains is a list of one or more chains where the first element is
@@ -255,6 +257,8 @@
 	// On the client side, it's set if Config.InsecureSkipVerify is false. On
 	// the server side, it's set if Config.ClientAuth is VerifyClientCertIfGiven
 	// (and the peer provided a certificate) or RequireAndVerifyClientCert.
+	//
+	// VerifiedChains and its contents should not be modified.
 	VerifiedChains [][]*x509.Certificate
 
 	// SignedCertificateTimestamps is a list of SCTs provided by the peer
@@ -554,6 +558,8 @@
 	// If GetCertificate is nil or returns nil, then the certificate is
 	// retrieved from NameToCertificate. If NameToCertificate is nil, the
 	// best element of Certificates will be used.
+	//
+	// Once a Certificate is returned it should not be modified.
 	GetCertificate func(*ClientHelloInfo) (*Certificate, error)
 
 	// GetClientCertificate, if not nil, is called when a server requests a
@@ -569,6 +575,8 @@
 	//
 	// GetClientCertificate may be called multiple times for the same
 	// connection if renegotiation occurs or if TLS 1.3 is in use.
+	//
+	// Once a Certificate is returned it should not be modified.
 	GetClientCertificate func(*CertificateRequestInfo) (*Certificate, error)
 
 	// GetConfigForClient, if not nil, is called after a ClientHello is
@@ -597,6 +605,8 @@
 	// setting InsecureSkipVerify, or (for a server) when ClientAuth is
 	// RequestClientCert or RequireAnyClientCert, then this callback will
 	// be considered but the verifiedChains argument will always be nil.
+	//
+	// verifiedChains and its contents should not be modified.
 	VerifyPeerCertificate func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error
 
 	// VerifyConnection, if not nil, is called after normal certificate
@@ -725,7 +735,7 @@
 
 	// mutex protects sessionTicketKeys and autoSessionTicketKeys.
 	mutex sync.RWMutex
-	// sessionTicketKeys contains zero or more ticket keys. If set, it means the
+	// sessionTicketKeys contains zero or more ticket keys. If set, it means
 	// the keys were set with SessionTicketKey or SetSessionTicketKeys. The
 	// first key is used for new tickets and any subsequent keys can be used to
 	// decrypt old tickets. The slice contents are not protected by the mutex
@@ -1338,7 +1348,7 @@
 		return nil
 	}
 
-	logLine := []byte(fmt.Sprintf("%s %x %x\n", label, clientRandom, secret))
+	logLine := fmt.Appendf(nil, "%s %x %x\n", label, clientRandom, secret)
 
 	writerMutex.Lock()
 	_, err := c.KeyLogWriter.Write(logLine)
@@ -1384,7 +1394,7 @@
 }
 
 type handshakeMessage interface {
-	marshal() []byte
+	marshal() ([]byte, error)
 	unmarshal([]byte) bool
 }
 
@@ -1483,3 +1493,18 @@
 	}
 	return false
 }
+
+// CertificateVerificationError is returned when certificate verification fails during the handshake.
+type CertificateVerificationError struct {
+	// UnverifiedCertificates and its contents should not be modified.
+	UnverifiedCertificates []*x509.Certificate
+	Err                    error
+}
+
+func (e *CertificateVerificationError) Error() string {
+	return fmt.Sprintf("tls: failed to verify certificate: %s", e.Err)
+}
+
+func (e *CertificateVerificationError) Unwrap() error {
+	return e.Err
+}
diff --git a/src/crypto/tls/conn.go b/src/crypto/tls/conn.go
index 1861a31..1eefb17 100644
--- a/src/crypto/tls/conn.go
+++ b/src/crypto/tls/conn.go
@@ -30,11 +30,10 @@
 	isClient    bool
 	handshakeFn func(context.Context) error // (*Conn).clientHandshake or serverHandshake
 
-	// handshakeStatus is 1 if the connection is currently transferring
+	// isHandshakeComplete is true if the connection is currently transferring
 	// application data (i.e. is not currently processing a handshake).
-	// handshakeStatus == 1 implies handshakeErr == nil.
-	// This field is only to be accessed with sync/atomic.
-	handshakeStatus uint32
+	// isHandshakeComplete is true implies handshakeErr == nil.
+	isHandshakeComplete atomic.Bool
 	// constant after handshake; protected by handshakeMutex
 	handshakeMutex sync.Mutex
 	handshakeErr   error   // error resulting from handshake
@@ -50,6 +49,9 @@
 	ocspResponse     []byte   // stapled OCSP response
 	scts             [][]byte // signed certificate timestamps from server
 	peerCertificates []*x509.Certificate
+	// activeCertHandles contains the cache handles to certificates in
+	// peerCertificates that are used to track active references.
+	activeCertHandles []*activeCert
 	// verifiedChains contains the certificate chains that we built, as
 	// opposed to the ones presented by the server.
 	verifiedChains [][]*x509.Certificate
@@ -110,10 +112,9 @@
 	// handshake, nor deliver application data. Protected by in.Mutex.
 	retryCount int
 
-	// activeCall is an atomic int32; the low bit is whether Close has
-	// been called. the rest of the bits are the number of goroutines
-	// in Conn.Write.
-	activeCall int32
+	// activeCall indicates whether Close has been call in the low bit.
+	// the rest of the bits are the number of goroutines in Conn.Write.
+	activeCall atomic.Int32
 
 	tmp [16]byte
 }
@@ -604,7 +605,7 @@
 	if c.in.err != nil {
 		return c.in.err
 	}
-	handshakeComplete := c.handshakeComplete()
+	handshakeComplete := c.isHandshakeComplete.Load()
 
 	// This function modifies c.rawInput, which owns the c.input memory.
 	if c.input.Len() != 0 {
@@ -1003,18 +1004,37 @@
 	return n, nil
 }
 
-// writeRecord writes a TLS record with the given type and payload to the
-// connection and updates the record layer state.
-func (c *Conn) writeRecord(typ recordType, data []byte) (int, error) {
+// writeHandshakeRecord writes a handshake message to the connection and updates
+// the record layer state. If transcript is non-nil the marshalled message is
+// written to it.
+func (c *Conn) writeHandshakeRecord(msg handshakeMessage, transcript transcriptHash) (int, error) {
 	c.out.Lock()
 	defer c.out.Unlock()
 
-	return c.writeRecordLocked(typ, data)
+	data, err := msg.marshal()
+	if err != nil {
+		return 0, err
+	}
+	if transcript != nil {
+		transcript.Write(data)
+	}
+
+	return c.writeRecordLocked(recordTypeHandshake, data)
+}
+
+// writeChangeCipherRecord writes a ChangeCipherSpec message to the connection and
+// updates the record layer state.
+func (c *Conn) writeChangeCipherRecord() error {
+	c.out.Lock()
+	defer c.out.Unlock()
+	_, err := c.writeRecordLocked(recordTypeChangeCipherSpec, []byte{1})
+	return err
 }
 
 // readHandshake reads the next handshake message from
-// the record layer.
-func (c *Conn) readHandshake() (any, error) {
+// the record layer. If transcript is non-nil, the message
+// is written to the passed transcriptHash.
+func (c *Conn) readHandshake(transcript transcriptHash) (any, error) {
 	for c.hand.Len() < 4 {
 		if err := c.readRecord(); err != nil {
 			return nil, err
@@ -1093,6 +1113,11 @@
 	if !m.unmarshal(data) {
 		return nil, c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
 	}
+
+	if transcript != nil {
+		transcript.Write(data)
+	}
+
 	return m, nil
 }
 
@@ -1109,15 +1134,15 @@
 func (c *Conn) Write(b []byte) (int, error) {
 	// interlock with Close below
 	for {
-		x := atomic.LoadInt32(&c.activeCall)
+		x := c.activeCall.Load()
 		if x&1 != 0 {
 			return 0, net.ErrClosed
 		}
-		if atomic.CompareAndSwapInt32(&c.activeCall, x, x+2) {
+		if c.activeCall.CompareAndSwap(x, x+2) {
 			break
 		}
 	}
-	defer atomic.AddInt32(&c.activeCall, -2)
+	defer c.activeCall.Add(-2)
 
 	if err := c.Handshake(); err != nil {
 		return 0, err
@@ -1130,7 +1155,7 @@
 		return 0, err
 	}
 
-	if !c.handshakeComplete() {
+	if !c.isHandshakeComplete.Load() {
 		return 0, alertInternalError
 	}
 
@@ -1168,7 +1193,7 @@
 		return errors.New("tls: internal error: unexpected renegotiation")
 	}
 
-	msg, err := c.readHandshake()
+	msg, err := c.readHandshake(nil)
 	if err != nil {
 		return err
 	}
@@ -1200,7 +1225,7 @@
 	c.handshakeMutex.Lock()
 	defer c.handshakeMutex.Unlock()
 
-	atomic.StoreUint32(&c.handshakeStatus, 0)
+	c.isHandshakeComplete.Store(false)
 	if c.handshakeErr = c.clientHandshake(context.Background()); c.handshakeErr == nil {
 		c.handshakes++
 	}
@@ -1214,7 +1239,7 @@
 		return c.handleRenegotiation()
 	}
 
-	msg, err := c.readHandshake()
+	msg, err := c.readHandshake(nil)
 	if err != nil {
 		return err
 	}
@@ -1250,7 +1275,11 @@
 		defer c.out.Unlock()
 
 		msg := &keyUpdateMsg{}
-		_, err := c.writeRecordLocked(recordTypeHandshake, msg.marshal())
+		msgBytes, err := msg.marshal()
+		if err != nil {
+			return err
+		}
+		_, err = c.writeRecordLocked(recordTypeHandshake, msgBytes)
 		if err != nil {
 			// Surface the error at the next write.
 			c.out.setErrorLocked(err)
@@ -1318,11 +1347,11 @@
 	// Interlock with Conn.Write above.
 	var x int32
 	for {
-		x = atomic.LoadInt32(&c.activeCall)
+		x = c.activeCall.Load()
 		if x&1 != 0 {
 			return net.ErrClosed
 		}
-		if atomic.CompareAndSwapInt32(&c.activeCall, x, x|1) {
+		if c.activeCall.CompareAndSwap(x, x|1) {
 			break
 		}
 	}
@@ -1337,7 +1366,7 @@
 	}
 
 	var alertErr error
-	if c.handshakeComplete() {
+	if c.isHandshakeComplete.Load() {
 		if err := c.closeNotify(); err != nil {
 			alertErr = fmt.Errorf("tls: failed to send closeNotify alert (but connection was closed anyway): %w", err)
 		}
@@ -1355,7 +1384,7 @@
 // called once the handshake has completed and does not call CloseWrite on the
 // underlying connection. Most callers should just use Close.
 func (c *Conn) CloseWrite() error {
-	if !c.handshakeComplete() {
+	if !c.isHandshakeComplete.Load() {
 		return errEarlyCloseWrite
 	}
 
@@ -1409,7 +1438,7 @@
 	// Fast sync/atomic-based exit if there is no handshake in flight and the
 	// last one succeeded without an error. Avoids the expensive context setup
 	// and mutex for most Read and Write calls.
-	if c.handshakeComplete() {
+	if c.isHandshakeComplete.Load() {
 		return nil
 	}
 
@@ -1452,7 +1481,7 @@
 	if err := c.handshakeErr; err != nil {
 		return err
 	}
-	if c.handshakeComplete() {
+	if c.isHandshakeComplete.Load() {
 		return nil
 	}
 
@@ -1468,10 +1497,10 @@
 		c.flush()
 	}
 
-	if c.handshakeErr == nil && !c.handshakeComplete() {
+	if c.handshakeErr == nil && !c.isHandshakeComplete.Load() {
 		c.handshakeErr = errors.New("tls: internal error: handshake should have had a result")
 	}
-	if c.handshakeErr != nil && c.handshakeComplete() {
+	if c.handshakeErr != nil && c.isHandshakeComplete.Load() {
 		panic("tls: internal error: handshake returned an error but is marked successful")
 	}
 
@@ -1487,7 +1516,7 @@
 
 func (c *Conn) connectionStateLocked() ConnectionState {
 	var state ConnectionState
-	state.HandshakeComplete = c.handshakeComplete()
+	state.HandshakeComplete = c.isHandshakeComplete.Load()
 	state.Version = c.vers
 	state.NegotiatedProtocol = c.clientProtocol
 	state.DidResume = c.didResume
@@ -1531,7 +1560,7 @@
 	if !c.isClient {
 		return errors.New("tls: VerifyHostname called on TLS server connection")
 	}
-	if !c.handshakeComplete() {
+	if !c.isHandshakeComplete.Load() {
 		return errors.New("tls: handshake has not yet been performed")
 	}
 	if len(c.verifiedChains) == 0 {
@@ -1539,7 +1568,3 @@
 	}
 	return c.peerCertificates[0].VerifyHostname(host)
 }
-
-func (c *Conn) handshakeComplete() bool {
-	return atomic.LoadUint32(&c.handshakeStatus) == 1
-}
diff --git a/src/crypto/tls/generate_cert.go b/src/crypto/tls/generate_cert.go
index 74509c9..cd4bfc5 100644
--- a/src/crypto/tls/generate_cert.go
+++ b/src/crypto/tls/generate_cert.go
@@ -156,7 +156,6 @@
 	keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
 	if err != nil {
 		log.Fatalf("Failed to open key.pem for writing: %v", err)
-		return
 	}
 	privBytes, err := x509.MarshalPKCS8PrivateKey(priv)
 	if err != nil {
diff --git a/src/crypto/tls/handshake_client.go b/src/crypto/tls/handshake_client.go
index e61e3eb..63d86b9 100644
--- a/src/crypto/tls/handshake_client.go
+++ b/src/crypto/tls/handshake_client.go
@@ -8,6 +8,7 @@
 	"bytes"
 	"context"
 	"crypto"
+	"crypto/ecdh"
 	"crypto/ecdsa"
 	"crypto/ed25519"
 	"crypto/rsa"
@@ -19,7 +20,6 @@
 	"io"
 	"net"
 	"strings"
-	"sync/atomic"
 	"time"
 )
 
@@ -36,7 +36,7 @@
 
 var testingOnlyForceClientHelloSignatureAlgorithms []SignatureScheme
 
-func (c *Conn) makeClientHello() (*clientHelloMsg, ecdheParameters, error) {
+func (c *Conn) makeClientHello() (*clientHelloMsg, *ecdh.PrivateKey, error) {
 	config := c.config
 	if len(config.ServerName) == 0 && !config.InsecureSkipVerify {
 		return nil, nil, errors.New("tls: either ServerName or InsecureSkipVerify must be specified in the tls.Config")
@@ -125,7 +125,7 @@
 		hello.supportedSignatureAlgorithms = testingOnlyForceClientHelloSignatureAlgorithms
 	}
 
-	var params ecdheParameters
+	var key *ecdh.PrivateKey
 	if hello.supportedVersions[0] == VersionTLS13 {
 		if hasAESGCMHardwareSupport {
 			hello.cipherSuites = append(hello.cipherSuites, defaultCipherSuitesTLS13...)
@@ -134,17 +134,17 @@
 		}
 
 		curveID := config.curvePreferences()[0]
-		if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok {
+		if _, ok := curveForCurveID(curveID); !ok {
 			return nil, nil, errors.New("tls: CurvePreferences includes unsupported curve")
 		}
-		params, err = generateECDHEParameters(config.rand(), curveID)
+		key, err = generateECDHEKey(config.rand(), curveID)
 		if err != nil {
 			return nil, nil, err
 		}
-		hello.keyShares = []keyShare{{group: curveID, data: params.PublicKey()}}
+		hello.keyShares = []keyShare{{group: curveID, data: key.PublicKey().Bytes()}}
 	}
 
-	return hello, params, nil
+	return hello, key, nil
 }
 
 func (c *Conn) clientHandshake(ctx context.Context) (err error) {
@@ -156,13 +156,16 @@
 	// need to be reset.
 	c.didResume = false
 
-	hello, ecdheParams, err := c.makeClientHello()
+	hello, ecdheKey, err := c.makeClientHello()
 	if err != nil {
 		return err
 	}
 	c.serverName = hello.serverName
 
-	cacheKey, session, earlySecret, binderKey := c.loadSession(hello)
+	cacheKey, session, earlySecret, binderKey, err := c.loadSession(hello)
+	if err != nil {
+		return err
+	}
 	if cacheKey != "" && session != nil {
 		defer func() {
 			// If we got a handshake failure when resuming a session, throw away
@@ -177,11 +180,12 @@
 		}()
 	}
 
-	if _, err := c.writeRecord(recordTypeHandshake, hello.marshal()); err != nil {
+	if _, err := c.writeHandshakeRecord(hello, nil); err != nil {
 		return err
 	}
 
-	msg, err := c.readHandshake()
+	// serverHelloMsg is not included in the transcript
+	msg, err := c.readHandshake(nil)
 	if err != nil {
 		return err
 	}
@@ -214,7 +218,7 @@
 			ctx:         ctx,
 			serverHello: serverHello,
 			hello:       hello,
-			ecdheParams: ecdheParams,
+			ecdheKey:    ecdheKey,
 			session:     session,
 			earlySecret: earlySecret,
 			binderKey:   binderKey,
@@ -246,9 +250,9 @@
 }
 
 func (c *Conn) loadSession(hello *clientHelloMsg) (cacheKey string,
-	session *ClientSessionState, earlySecret, binderKey []byte) {
+	session *ClientSessionState, earlySecret, binderKey []byte, err error) {
 	if c.config.SessionTicketsDisabled || c.config.ClientSessionCache == nil {
-		return "", nil, nil, nil
+		return "", nil, nil, nil, nil
 	}
 
 	hello.ticketSupported = true
@@ -263,14 +267,14 @@
 	// renegotiation is primarily used to allow a client to send a client
 	// certificate, which would be skipped if session resumption occurred.
 	if c.handshakes != 0 {
-		return "", nil, nil, nil
+		return "", nil, nil, nil, nil
 	}
 
 	// Try to resume a previously negotiated TLS session, if available.
 	cacheKey = clientSessionCacheKey(c.conn.RemoteAddr(), c.config)
 	session, ok := c.config.ClientSessionCache.Get(cacheKey)
 	if !ok || session == nil {
-		return cacheKey, nil, nil, nil
+		return cacheKey, nil, nil, nil, nil
 	}
 
 	// Check that version used for the previous session is still valid.
@@ -282,7 +286,7 @@
 		}
 	}
 	if !versOk {
-		return cacheKey, nil, nil, nil
+		return cacheKey, nil, nil, nil, nil
 	}
 
 	// Check that the cached server certificate is not expired, and that it's
@@ -291,16 +295,16 @@
 	if !c.config.InsecureSkipVerify {
 		if len(session.verifiedChains) == 0 {
 			// The original connection had InsecureSkipVerify, while this doesn't.
-			return cacheKey, nil, nil, nil
+			return cacheKey, nil, nil, nil, nil
 		}
 		serverCert := session.serverCertificates[0]
 		if c.config.time().After(serverCert.NotAfter) {
 			// Expired certificate, delete the entry.
 			c.config.ClientSessionCache.Put(cacheKey, nil)
-			return cacheKey, nil, nil, nil
+			return cacheKey, nil, nil, nil, nil
 		}
 		if err := serverCert.VerifyHostname(c.config.ServerName); err != nil {
-			return cacheKey, nil, nil, nil
+			return cacheKey, nil, nil, nil, nil
 		}
 	}
 
@@ -308,7 +312,7 @@
 		// In TLS 1.2 the cipher suite must match the resumed session. Ensure we
 		// are still offering it.
 		if mutualCipherSuite(hello.cipherSuites, session.cipherSuite) == nil {
-			return cacheKey, nil, nil, nil
+			return cacheKey, nil, nil, nil, nil
 		}
 
 		hello.sessionTicket = session.sessionTicket
@@ -318,14 +322,14 @@
 	// Check that the session ticket is not expired.
 	if c.config.time().After(session.useBy) {
 		c.config.ClientSessionCache.Put(cacheKey, nil)
-		return cacheKey, nil, nil, nil
+		return cacheKey, nil, nil, nil, nil
 	}
 
 	// In TLS 1.3 the KDF hash must match the resumed session. Ensure we
 	// offer at least one cipher suite with that hash.
 	cipherSuite := cipherSuiteTLS13ByID(session.cipherSuite)
 	if cipherSuite == nil {
-		return cacheKey, nil, nil, nil
+		return cacheKey, nil, nil, nil, nil
 	}
 	cipherSuiteOk := false
 	for _, offeredID := range hello.cipherSuites {
@@ -336,7 +340,7 @@
 		}
 	}
 	if !cipherSuiteOk {
-		return cacheKey, nil, nil, nil
+		return cacheKey, nil, nil, nil, nil
 	}
 
 	// Set the pre_shared_key extension. See RFC 8446, Section 4.2.11.1.
@@ -354,9 +358,15 @@
 	earlySecret = cipherSuite.extract(psk, nil)
 	binderKey = cipherSuite.deriveSecret(earlySecret, resumptionBinderLabel, nil)
 	transcript := cipherSuite.hash.New()
-	transcript.Write(hello.marshalWithoutBinders())
+	helloBytes, err := hello.marshalWithoutBinders()
+	if err != nil {
+		return "", nil, nil, nil, err
+	}
+	transcript.Write(helloBytes)
 	pskBinders := [][]byte{cipherSuite.finishedHash(binderKey, transcript)}
-	hello.updateBinders(pskBinders)
+	if err := hello.updateBinders(pskBinders); err != nil {
+		return "", nil, nil, nil, err
+	}
 
 	return
 }
@@ -401,8 +411,12 @@
 		hs.finishedHash.discardHandshakeBuffer()
 	}
 
-	hs.finishedHash.Write(hs.hello.marshal())
-	hs.finishedHash.Write(hs.serverHello.marshal())
+	if err := transcriptMsg(hs.hello, &hs.finishedHash); err != nil {
+		return err
+	}
+	if err := transcriptMsg(hs.serverHello, &hs.finishedHash); err != nil {
+		return err
+	}
 
 	c.buffering = true
 	c.didResume = isResume
@@ -455,7 +469,7 @@
 	}
 
 	c.ekm = ekmFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random)
-	atomic.StoreUint32(&c.handshakeStatus, 1)
+	c.isHandshakeComplete.Store(true)
 
 	return nil
 }
@@ -473,7 +487,7 @@
 func (hs *clientHandshakeState) doFullHandshake() error {
 	c := hs.c
 
-	msg, err := c.readHandshake()
+	msg, err := c.readHandshake(&hs.finishedHash)
 	if err != nil {
 		return err
 	}
@@ -482,9 +496,8 @@
 		c.sendAlert(alertUnexpectedMessage)
 		return unexpectedMessageError(certMsg, msg)
 	}
-	hs.finishedHash.Write(certMsg.marshal())
 
-	msg, err = c.readHandshake()
+	msg, err = c.readHandshake(&hs.finishedHash)
 	if err != nil {
 		return err
 	}
@@ -502,11 +515,10 @@
 			c.sendAlert(alertUnexpectedMessage)
 			return errors.New("tls: received unexpected CertificateStatus message")
 		}
-		hs.finishedHash.Write(cs.marshal())
 
 		c.ocspResponse = cs.response
 
-		msg, err = c.readHandshake()
+		msg, err = c.readHandshake(&hs.finishedHash)
 		if err != nil {
 			return err
 		}
@@ -535,14 +547,13 @@
 
 	skx, ok := msg.(*serverKeyExchangeMsg)
 	if ok {
-		hs.finishedHash.Write(skx.marshal())
 		err = keyAgreement.processServerKeyExchange(c.config, hs.hello, hs.serverHello, c.peerCertificates[0], skx)
 		if err != nil {
 			c.sendAlert(alertUnexpectedMessage)
 			return err
 		}
 
-		msg, err = c.readHandshake()
+		msg, err = c.readHandshake(&hs.finishedHash)
 		if err != nil {
 			return err
 		}
@@ -553,7 +564,6 @@
 	certReq, ok := msg.(*certificateRequestMsg)
 	if ok {
 		certRequested = true
-		hs.finishedHash.Write(certReq.marshal())
 
 		cri := certificateRequestInfoFromMsg(hs.ctx, c.vers, certReq)
 		if chainToSend, err = c.getClientCertificate(cri); err != nil {
@@ -561,7 +571,7 @@
 			return err
 		}
 
-		msg, err = c.readHandshake()
+		msg, err = c.readHandshake(&hs.finishedHash)
 		if err != nil {
 			return err
 		}
@@ -572,7 +582,6 @@
 		c.sendAlert(alertUnexpectedMessage)
 		return unexpectedMessageError(shd, msg)
 	}
-	hs.finishedHash.Write(shd.marshal())
 
 	// If the server requested a certificate then we have to send a
 	// Certificate message, even if it's empty because we don't have a
@@ -580,8 +589,7 @@
 	if certRequested {
 		certMsg = new(certificateMsg)
 		certMsg.certificates = chainToSend.Certificate
-		hs.finishedHash.Write(certMsg.marshal())
-		if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil {
+		if _, err := hs.c.writeHandshakeRecord(certMsg, &hs.finishedHash); err != nil {
 			return err
 		}
 	}
@@ -592,8 +600,7 @@
 		return err
 	}
 	if ckx != nil {
-		hs.finishedHash.Write(ckx.marshal())
-		if _, err := c.writeRecord(recordTypeHandshake, ckx.marshal()); err != nil {
+		if _, err := hs.c.writeHandshakeRecord(ckx, &hs.finishedHash); err != nil {
 			return err
 		}
 	}
@@ -629,7 +636,7 @@
 			}
 		}
 
-		signed := hs.finishedHash.hashForClientCertificate(sigType, sigHash, hs.masterSecret)
+		signed := hs.finishedHash.hashForClientCertificate(sigType, sigHash)
 		signOpts := crypto.SignerOpts(sigHash)
 		if sigType == signatureRSAPSS {
 			signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash}
@@ -640,8 +647,7 @@
 			return err
 		}
 
-		hs.finishedHash.Write(certVerify.marshal())
-		if _, err := c.writeRecord(recordTypeHandshake, certVerify.marshal()); err != nil {
+		if _, err := hs.c.writeHandshakeRecord(certVerify, &hs.finishedHash); err != nil {
 			return err
 		}
 	}
@@ -776,7 +782,10 @@
 		return err
 	}
 
-	msg, err := c.readHandshake()
+	// finishedMsg is included in the transcript, but not until after we
+	// check the client version, since the state before this message was
+	// sent is used during verification.
+	msg, err := c.readHandshake(nil)
 	if err != nil {
 		return err
 	}
@@ -792,7 +801,11 @@
 		c.sendAlert(alertHandshakeFailure)
 		return errors.New("tls: server's Finished message was incorrect")
 	}
-	hs.finishedHash.Write(serverFinished.marshal())
+
+	if err := transcriptMsg(serverFinished, &hs.finishedHash); err != nil {
+		return err
+	}
+
 	copy(out, verify)
 	return nil
 }
@@ -803,7 +816,7 @@
 	}
 
 	c := hs.c
-	msg, err := c.readHandshake()
+	msg, err := c.readHandshake(&hs.finishedHash)
 	if err != nil {
 		return err
 	}
@@ -812,7 +825,6 @@
 		c.sendAlert(alertUnexpectedMessage)
 		return unexpectedMessageError(sessionTicketMsg, msg)
 	}
-	hs.finishedHash.Write(sessionTicketMsg.marshal())
 
 	hs.session = &ClientSessionState{
 		sessionTicket:      sessionTicketMsg.ticket,
@@ -832,14 +844,13 @@
 func (hs *clientHandshakeState) sendFinished(out []byte) error {
 	c := hs.c
 
-	if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil {
+	if err := c.writeChangeCipherRecord(); err != nil {
 		return err
 	}
 
 	finished := new(finishedMsg)
 	finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret)
-	hs.finishedHash.Write(finished.marshal())
-	if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil {
+	if _, err := hs.c.writeHandshakeRecord(finished, &hs.finishedHash); err != nil {
 		return err
 	}
 	copy(out, finished.verifyData)
@@ -849,14 +860,16 @@
 // verifyServerCertificate parses and verifies the provided chain, setting
 // c.verifiedChains and c.peerCertificates or sending the appropriate alert.
 func (c *Conn) verifyServerCertificate(certificates [][]byte) error {
+	activeHandles := make([]*activeCert, len(certificates))
 	certs := make([]*x509.Certificate, len(certificates))
 	for i, asn1Data := range certificates {
-		cert, err := x509.ParseCertificate(asn1Data)
+		cert, err := clientCertCache.newCert(asn1Data)
 		if err != nil {
 			c.sendAlert(alertBadCertificate)
 			return errors.New("tls: failed to parse certificate from server: " + err.Error())
 		}
-		certs[i] = cert
+		activeHandles[i] = cert
+		certs[i] = cert.cert
 	}
 
 	if !c.config.InsecureSkipVerify {
@@ -874,7 +887,7 @@
 		c.verifiedChains, err = certs[0].Verify(opts)
 		if err != nil {
 			c.sendAlert(alertBadCertificate)
-			return err
+			return &CertificateVerificationError{UnverifiedCertificates: certs, Err: err}
 		}
 	}
 
@@ -886,6 +899,7 @@
 		return fmt.Errorf("tls: server's certificate contains an unsupported type of public key: %T", certs[0].PublicKey)
 	}
 
+	c.activeCertHandles = activeHandles
 	c.peerCertificates = certs
 
 	if c.config.VerifyPeerCertificate != nil {
diff --git a/src/crypto/tls/handshake_client_test.go b/src/crypto/tls/handshake_client_test.go
index 380de9f..749c9fc 100644
--- a/src/crypto/tls/handshake_client_test.go
+++ b/src/crypto/tls/handshake_client_test.go
@@ -1257,7 +1257,7 @@
 		cipherSuite:  TLS_RSA_WITH_AES_128_GCM_SHA256,
 		alpnProtocol: "how-about-this",
 	}
-	serverHelloBytes := serverHello.marshal()
+	serverHelloBytes := mustMarshal(t, serverHello)
 
 	s.Write([]byte{
 		byte(recordTypeHandshake),
@@ -1500,7 +1500,7 @@
 		random:      make([]byte, 32),
 		cipherSuite: TLS_RSA_WITH_AES_256_GCM_SHA384,
 	}
-	serverHelloBytes := serverHello.marshal()
+	serverHelloBytes := mustMarshal(t, serverHello)
 
 	s.Write([]byte{
 		byte(recordTypeHandshake),
diff --git a/src/crypto/tls/handshake_client_tls13.go b/src/crypto/tls/handshake_client_tls13.go
index c798986..fefba01 100644
--- a/src/crypto/tls/handshake_client_tls13.go
+++ b/src/crypto/tls/handshake_client_tls13.go
@@ -8,11 +8,11 @@
 	"bytes"
 	"context"
 	"crypto"
+	"crypto/ecdh"
 	"crypto/hmac"
 	"crypto/rsa"
 	"errors"
 	"hash"
-	"sync/atomic"
 	"time"
 )
 
@@ -21,7 +21,7 @@
 	ctx         context.Context
 	serverHello *serverHelloMsg
 	hello       *clientHelloMsg
-	ecdheParams ecdheParameters
+	ecdheKey    *ecdh.PrivateKey
 
 	session     *ClientSessionState
 	earlySecret []byte
@@ -36,7 +36,7 @@
 	trafficSecret []byte // client_application_traffic_secret_0
 }
 
-// handshake requires hs.c, hs.hello, hs.serverHello, hs.ecdheParams, and,
+// handshake requires hs.c, hs.hello, hs.serverHello, hs.ecdheKey, and,
 // optionally, hs.session, hs.earlySecret and hs.binderKey to be set.
 func (hs *clientHandshakeStateTLS13) handshake() error {
 	c := hs.c
@@ -53,7 +53,7 @@
 	}
 
 	// Consistency check on the presence of a keyShare and its parameters.
-	if hs.ecdheParams == nil || len(hs.hello.keyShares) != 1 {
+	if hs.ecdheKey == nil || len(hs.hello.keyShares) != 1 {
 		return c.sendAlert(alertInternalError)
 	}
 
@@ -62,7 +62,10 @@
 	}
 
 	hs.transcript = hs.suite.hash.New()
-	hs.transcript.Write(hs.hello.marshal())
+
+	if err := transcriptMsg(hs.hello, hs.transcript); err != nil {
+		return err
+	}
 
 	if bytes.Equal(hs.serverHello.random, helloRetryRequestRandom) {
 		if err := hs.sendDummyChangeCipherSpec(); err != nil {
@@ -73,7 +76,9 @@
 		}
 	}
 
-	hs.transcript.Write(hs.serverHello.marshal())
+	if err := transcriptMsg(hs.serverHello, hs.transcript); err != nil {
+		return err
+	}
 
 	c.buffering = true
 	if err := hs.processServerHello(); err != nil {
@@ -104,7 +109,7 @@
 		return err
 	}
 
-	atomic.StoreUint32(&c.handshakeStatus, 1)
+	c.isHandshakeComplete.Store(true)
 
 	return nil
 }
@@ -172,8 +177,7 @@
 	}
 	hs.sentDummyCCS = true
 
-	_, err := hs.c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
-	return err
+	return hs.c.writeChangeCipherRecord()
 }
 
 // processHelloRetryRequest handles the HRR in hs.serverHello, modifies and
@@ -188,7 +192,9 @@
 	hs.transcript.Reset()
 	hs.transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))})
 	hs.transcript.Write(chHash)
-	hs.transcript.Write(hs.serverHello.marshal())
+	if err := transcriptMsg(hs.serverHello, hs.transcript); err != nil {
+		return err
+	}
 
 	// The only HelloRetryRequest extensions we support are key_share and
 	// cookie, and clients must abort the handshake if the HRR would not result
@@ -222,21 +228,21 @@
 			c.sendAlert(alertIllegalParameter)
 			return errors.New("tls: server selected unsupported group")
 		}
-		if hs.ecdheParams.CurveID() == curveID {
+		if sentID, _ := curveIDForCurve(hs.ecdheKey.Curve()); sentID == curveID {
 			c.sendAlert(alertIllegalParameter)
 			return errors.New("tls: server sent an unnecessary HelloRetryRequest key_share")
 		}
-		if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok {
+		if _, ok := curveForCurveID(curveID); !ok {
 			c.sendAlert(alertInternalError)
 			return errors.New("tls: CurvePreferences includes unsupported curve")
 		}
-		params, err := generateECDHEParameters(c.config.rand(), curveID)
+		key, err := generateECDHEKey(c.config.rand(), curveID)
 		if err != nil {
 			c.sendAlert(alertInternalError)
 			return err
 		}
-		hs.ecdheParams = params
-		hs.hello.keyShares = []keyShare{{group: curveID, data: params.PublicKey()}}
+		hs.ecdheKey = key
+		hs.hello.keyShares = []keyShare{{group: curveID, data: key.PublicKey().Bytes()}}
 	}
 
 	hs.hello.raw = nil
@@ -253,10 +259,18 @@
 			transcript := hs.suite.hash.New()
 			transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))})
 			transcript.Write(chHash)
-			transcript.Write(hs.serverHello.marshal())
-			transcript.Write(hs.hello.marshalWithoutBinders())
+			if err := transcriptMsg(hs.serverHello, hs.transcript); err != nil {
+				return err
+			}
+			helloBytes, err := hs.hello.marshalWithoutBinders()
+			if err != nil {
+				return err
+			}
+			transcript.Write(helloBytes)
 			pskBinders := [][]byte{hs.suite.finishedHash(hs.binderKey, transcript)}
-			hs.hello.updateBinders(pskBinders)
+			if err := hs.hello.updateBinders(pskBinders); err != nil {
+				return err
+			}
 		} else {
 			// Server selected a cipher suite incompatible with the PSK.
 			hs.hello.pskIdentities = nil
@@ -264,12 +278,12 @@
 		}
 	}
 
-	hs.transcript.Write(hs.hello.marshal())
-	if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil {
+	if _, err := hs.c.writeHandshakeRecord(hs.hello, hs.transcript); err != nil {
 		return err
 	}
 
-	msg, err := c.readHandshake()
+	// serverHelloMsg is not included in the transcript
+	msg, err := c.readHandshake(nil)
 	if err != nil {
 		return err
 	}
@@ -310,7 +324,7 @@
 		c.sendAlert(alertIllegalParameter)
 		return errors.New("tls: server did not send a key share")
 	}
-	if hs.serverHello.serverShare.group != hs.ecdheParams.CurveID() {
+	if sentID, _ := curveIDForCurve(hs.ecdheKey.Curve()); hs.serverHello.serverShare.group != sentID {
 		c.sendAlert(alertIllegalParameter)
 		return errors.New("tls: server selected unsupported group")
 	}
@@ -348,8 +362,13 @@
 func (hs *clientHandshakeStateTLS13) establishHandshakeKeys() error {
 	c := hs.c
 
-	sharedKey := hs.ecdheParams.SharedKey(hs.serverHello.serverShare.data)
-	if sharedKey == nil {
+	peerKey, err := hs.ecdheKey.Curve().NewPublicKey(hs.serverHello.serverShare.data)
+	if err != nil {
+		c.sendAlert(alertIllegalParameter)
+		return errors.New("tls: invalid server key share")
+	}
+	sharedKey, err := hs.ecdheKey.ECDH(peerKey)
+	if err != nil {
 		c.sendAlert(alertIllegalParameter)
 		return errors.New("tls: invalid server key share")
 	}
@@ -358,6 +377,7 @@
 	if !hs.usingPSK {
 		earlySecret = hs.suite.extract(nil, nil)
 	}
+
 	handshakeSecret := hs.suite.extract(sharedKey,
 		hs.suite.deriveSecret(earlySecret, "derived", nil))
 
@@ -368,7 +388,7 @@
 		serverHandshakeTrafficLabel, hs.transcript)
 	c.in.setTrafficSecret(hs.suite, serverSecret)
 
-	err := c.config.writeKeyLog(keyLogLabelClientHandshake, hs.hello.random, clientSecret)
+	err = c.config.writeKeyLog(keyLogLabelClientHandshake, hs.hello.random, clientSecret)
 	if err != nil {
 		c.sendAlert(alertInternalError)
 		return err
@@ -388,7 +408,7 @@
 func (hs *clientHandshakeStateTLS13) readServerParameters() error {
 	c := hs.c
 
-	msg, err := c.readHandshake()
+	msg, err := c.readHandshake(hs.transcript)
 	if err != nil {
 		return err
 	}
@@ -398,7 +418,6 @@
 		c.sendAlert(alertUnexpectedMessage)
 		return unexpectedMessageError(encryptedExtensions, msg)
 	}
-	hs.transcript.Write(encryptedExtensions.marshal())
 
 	if err := checkALPN(hs.hello.alpnProtocols, encryptedExtensions.alpnProtocol); err != nil {
 		c.sendAlert(alertUnsupportedExtension)
@@ -427,18 +446,16 @@
 		return nil
 	}
 
-	msg, err := c.readHandshake()
+	msg, err := c.readHandshake(hs.transcript)
 	if err != nil {
 		return err
 	}
 
 	certReq, ok := msg.(*certificateRequestMsgTLS13)
 	if ok {
-		hs.transcript.Write(certReq.marshal())
-
 		hs.certReq = certReq
 
-		msg, err = c.readHandshake()
+		msg, err = c.readHandshake(hs.transcript)
 		if err != nil {
 			return err
 		}
@@ -453,7 +470,6 @@
 		c.sendAlert(alertDecodeError)
 		return errors.New("tls: received empty certificates message")
 	}
-	hs.transcript.Write(certMsg.marshal())
 
 	c.scts = certMsg.certificate.SignedCertificateTimestamps
 	c.ocspResponse = certMsg.certificate.OCSPStaple
@@ -462,7 +478,10 @@
 		return err
 	}
 
-	msg, err = c.readHandshake()
+	// certificateVerifyMsg is included in the transcript, but not until
+	// after we verify the handshake signature, since the state before
+	// this message was sent is used.
+	msg, err = c.readHandshake(nil)
 	if err != nil {
 		return err
 	}
@@ -493,7 +512,9 @@
 		return errors.New("tls: invalid signature by the server certificate: " + err.Error())
 	}
 
-	hs.transcript.Write(certVerify.marshal())
+	if err := transcriptMsg(certVerify, hs.transcript); err != nil {
+		return err
+	}
 
 	return nil
 }
@@ -501,7 +522,10 @@
 func (hs *clientHandshakeStateTLS13) readServerFinished() error {
 	c := hs.c
 
-	msg, err := c.readHandshake()
+	// finishedMsg is included in the transcript, but not until after we
+	// check the client version, since the state before this message was
+	// sent is used during verification.
+	msg, err := c.readHandshake(nil)
 	if err != nil {
 		return err
 	}
@@ -518,7 +542,9 @@
 		return errors.New("tls: invalid server finished hash")
 	}
 
-	hs.transcript.Write(finished.marshal())
+	if err := transcriptMsg(finished, hs.transcript); err != nil {
+		return err
+	}
 
 	// Derive secrets that take context through the server Finished.
 
@@ -567,8 +593,7 @@
 	certMsg.scts = hs.certReq.scts && len(cert.SignedCertificateTimestamps) > 0
 	certMsg.ocspStapling = hs.certReq.ocspStapling && len(cert.OCSPStaple) > 0
 
-	hs.transcript.Write(certMsg.marshal())
-	if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil {
+	if _, err := hs.c.writeHandshakeRecord(certMsg, hs.transcript); err != nil {
 		return err
 	}
 
@@ -605,8 +630,7 @@
 	}
 	certVerifyMsg.signature = sig
 
-	hs.transcript.Write(certVerifyMsg.marshal())
-	if _, err := c.writeRecord(recordTypeHandshake, certVerifyMsg.marshal()); err != nil {
+	if _, err := hs.c.writeHandshakeRecord(certVerifyMsg, hs.transcript); err != nil {
 		return err
 	}
 
@@ -620,8 +644,7 @@
 		verifyData: hs.suite.finishedHash(c.out.trafficSecret, hs.transcript),
 	}
 
-	hs.transcript.Write(finished.marshal())
-	if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil {
+	if _, err := hs.c.writeHandshakeRecord(finished, hs.transcript); err != nil {
 		return err
 	}
 
diff --git a/src/crypto/tls/handshake_messages.go b/src/crypto/tls/handshake_messages.go
index 7ab0f10..695aacf 100644
--- a/src/crypto/tls/handshake_messages.go
+++ b/src/crypto/tls/handshake_messages.go
@@ -5,6 +5,7 @@
 package tls
 
 import (
+	"errors"
 	"fmt"
 	"strings"
 
@@ -94,9 +95,181 @@
 	pskBinders                       [][]byte
 }
 
-func (m *clientHelloMsg) marshal() []byte {
+func (m *clientHelloMsg) marshal() ([]byte, error) {
 	if m.raw != nil {
-		return m.raw
+		return m.raw, nil
+	}
+
+	var exts cryptobyte.Builder
+	if len(m.serverName) > 0 {
+		// RFC 6066, Section 3
+		exts.AddUint16(extensionServerName)
+		exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+			exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+				exts.AddUint8(0) // name_type = host_name
+				exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+					exts.AddBytes([]byte(m.serverName))
+				})
+			})
+		})
+	}
+	if m.ocspStapling {
+		// RFC 4366, Section 3.6
+		exts.AddUint16(extensionStatusRequest)
+		exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+			exts.AddUint8(1)  // status_type = ocsp
+			exts.AddUint16(0) // empty responder_id_list
+			exts.AddUint16(0) // empty request_extensions
+		})
+	}
+	if len(m.supportedCurves) > 0 {
+		// RFC 4492, sections 5.1.1 and RFC 8446, Section 4.2.7
+		exts.AddUint16(extensionSupportedCurves)
+		exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+			exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+				for _, curve := range m.supportedCurves {
+					exts.AddUint16(uint16(curve))
+				}
+			})
+		})
+	}
+	if len(m.supportedPoints) > 0 {
+		// RFC 4492, Section 5.1.2
+		exts.AddUint16(extensionSupportedPoints)
+		exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+			exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
+				exts.AddBytes(m.supportedPoints)
+			})
+		})
+	}
+	if m.ticketSupported {
+		// RFC 5077, Section 3.2
+		exts.AddUint16(extensionSessionTicket)
+		exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+			exts.AddBytes(m.sessionTicket)
+		})
+	}
+	if len(m.supportedSignatureAlgorithms) > 0 {
+		// RFC 5246, Section 7.4.1.4.1
+		exts.AddUint16(extensionSignatureAlgorithms)
+		exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+			exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+				for _, sigAlgo := range m.supportedSignatureAlgorithms {
+					exts.AddUint16(uint16(sigAlgo))
+				}
+			})
+		})
+	}
+	if len(m.supportedSignatureAlgorithmsCert) > 0 {
+		// RFC 8446, Section 4.2.3
+		exts.AddUint16(extensionSignatureAlgorithmsCert)
+		exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+			exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+				for _, sigAlgo := range m.supportedSignatureAlgorithmsCert {
+					exts.AddUint16(uint16(sigAlgo))
+				}
+			})
+		})
+	}
+	if m.secureRenegotiationSupported {
+		// RFC 5746, Section 3.2
+		exts.AddUint16(extensionRenegotiationInfo)
+		exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+			exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
+				exts.AddBytes(m.secureRenegotiation)
+			})
+		})
+	}
+	if len(m.alpnProtocols) > 0 {
+		// RFC 7301, Section 3.1
+		exts.AddUint16(extensionALPN)
+		exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+			exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+				for _, proto := range m.alpnProtocols {
+					exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
+						exts.AddBytes([]byte(proto))
+					})
+				}
+			})
+		})
+	}
+	if m.scts {
+		// RFC 6962, Section 3.3.1
+		exts.AddUint16(extensionSCT)
+		exts.AddUint16(0) // empty extension_data
+	}
+	if len(m.supportedVersions) > 0 {
+		// RFC 8446, Section 4.2.1
+		exts.AddUint16(extensionSupportedVersions)
+		exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+			exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
+				for _, vers := range m.supportedVersions {
+					exts.AddUint16(vers)
+				}
+			})
+		})
+	}
+	if len(m.cookie) > 0 {
+		// RFC 8446, Section 4.2.2
+		exts.AddUint16(extensionCookie)
+		exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+			exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+				exts.AddBytes(m.cookie)
+			})
+		})
+	}
+	if len(m.keyShares) > 0 {
+		// RFC 8446, Section 4.2.8
+		exts.AddUint16(extensionKeyShare)
+		exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+			exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+				for _, ks := range m.keyShares {
+					exts.AddUint16(uint16(ks.group))
+					exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+						exts.AddBytes(ks.data)
+					})
+				}
+			})
+		})
+	}
+	if m.earlyData {
+		// RFC 8446, Section 4.2.10
+		exts.AddUint16(extensionEarlyData)
+		exts.AddUint16(0) // empty extension_data
+	}
+	if len(m.pskModes) > 0 {
+		// RFC 8446, Section 4.2.9
+		exts.AddUint16(extensionPSKModes)
+		exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+			exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
+				exts.AddBytes(m.pskModes)
+			})
+		})
+	}
+	if len(m.pskIdentities) > 0 { // pre_shared_key must be the last extension
+		// RFC 8446, Section 4.2.11
+		exts.AddUint16(extensionPreSharedKey)
+		exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+			exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+				for _, psk := range m.pskIdentities {
+					exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+						exts.AddBytes(psk.label)
+					})
+					exts.AddUint32(psk.obfuscatedTicketAge)
+				}
+			})
+			exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+				for _, binder := range m.pskBinders {
+					exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
+						exts.AddBytes(binder)
+					})
+				}
+			})
+		})
+	}
+	extBytes, err := exts.Bytes()
+	if err != nil {
+		return nil, err
 	}
 
 	var b cryptobyte.Builder
@@ -116,219 +289,53 @@
 			b.AddBytes(m.compressionMethods)
 		})
 
-		// If extensions aren't present, omit them.
-		var extensionsPresent bool
-		bWithoutExtensions := *b
-
-		b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-			if len(m.serverName) > 0 {
-				// RFC 6066, Section 3
-				b.AddUint16(extensionServerName)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-						b.AddUint8(0) // name_type = host_name
-						b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-							b.AddBytes([]byte(m.serverName))
-						})
-					})
-				})
-			}
-			if m.ocspStapling {
-				// RFC 4366, Section 3.6
-				b.AddUint16(extensionStatusRequest)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint8(1)  // status_type = ocsp
-					b.AddUint16(0) // empty responder_id_list
-					b.AddUint16(0) // empty request_extensions
-				})
-			}
-			if len(m.supportedCurves) > 0 {
-				// RFC 4492, sections 5.1.1 and RFC 8446, Section 4.2.7
-				b.AddUint16(extensionSupportedCurves)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-						for _, curve := range m.supportedCurves {
-							b.AddUint16(uint16(curve))
-						}
-					})
-				})
-			}
-			if len(m.supportedPoints) > 0 {
-				// RFC 4492, Section 5.1.2
-				b.AddUint16(extensionSupportedPoints)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
-						b.AddBytes(m.supportedPoints)
-					})
-				})
-			}
-			if m.ticketSupported {
-				// RFC 5077, Section 3.2
-				b.AddUint16(extensionSessionTicket)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddBytes(m.sessionTicket)
-				})
-			}
-			if len(m.supportedSignatureAlgorithms) > 0 {
-				// RFC 5246, Section 7.4.1.4.1
-				b.AddUint16(extensionSignatureAlgorithms)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-						for _, sigAlgo := range m.supportedSignatureAlgorithms {
-							b.AddUint16(uint16(sigAlgo))
-						}
-					})
-				})
-			}
-			if len(m.supportedSignatureAlgorithmsCert) > 0 {
-				// RFC 8446, Section 4.2.3
-				b.AddUint16(extensionSignatureAlgorithmsCert)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-						for _, sigAlgo := range m.supportedSignatureAlgorithmsCert {
-							b.AddUint16(uint16(sigAlgo))
-						}
-					})
-				})
-			}
-			if m.secureRenegotiationSupported {
-				// RFC 5746, Section 3.2
-				b.AddUint16(extensionRenegotiationInfo)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
-						b.AddBytes(m.secureRenegotiation)
-					})
-				})
-			}
-			if len(m.alpnProtocols) > 0 {
-				// RFC 7301, Section 3.1
-				b.AddUint16(extensionALPN)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-						for _, proto := range m.alpnProtocols {
-							b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
-								b.AddBytes([]byte(proto))
-							})
-						}
-					})
-				})
-			}
-			if m.scts {
-				// RFC 6962, Section 3.3.1
-				b.AddUint16(extensionSCT)
-				b.AddUint16(0) // empty extension_data
-			}
-			if len(m.supportedVersions) > 0 {
-				// RFC 8446, Section 4.2.1
-				b.AddUint16(extensionSupportedVersions)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
-						for _, vers := range m.supportedVersions {
-							b.AddUint16(vers)
-						}
-					})
-				})
-			}
-			if len(m.cookie) > 0 {
-				// RFC 8446, Section 4.2.2
-				b.AddUint16(extensionCookie)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-						b.AddBytes(m.cookie)
-					})
-				})
-			}
-			if len(m.keyShares) > 0 {
-				// RFC 8446, Section 4.2.8
-				b.AddUint16(extensionKeyShare)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-						for _, ks := range m.keyShares {
-							b.AddUint16(uint16(ks.group))
-							b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-								b.AddBytes(ks.data)
-							})
-						}
-					})
-				})
-			}
-			if m.earlyData {
-				// RFC 8446, Section 4.2.10
-				b.AddUint16(extensionEarlyData)
-				b.AddUint16(0) // empty extension_data
-			}
-			if len(m.pskModes) > 0 {
-				// RFC 8446, Section 4.2.9
-				b.AddUint16(extensionPSKModes)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
-						b.AddBytes(m.pskModes)
-					})
-				})
-			}
-			if len(m.pskIdentities) > 0 { // pre_shared_key must be the last extension
-				// RFC 8446, Section 4.2.11
-				b.AddUint16(extensionPreSharedKey)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-						for _, psk := range m.pskIdentities {
-							b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-								b.AddBytes(psk.label)
-							})
-							b.AddUint32(psk.obfuscatedTicketAge)
-						}
-					})
-					b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-						for _, binder := range m.pskBinders {
-							b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
-								b.AddBytes(binder)
-							})
-						}
-					})
-				})
-			}
-
-			extensionsPresent = len(b.BytesOrPanic()) > 2
-		})
-
-		if !extensionsPresent {
-			*b = bWithoutExtensions
+		if len(extBytes) > 0 {
+			b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+				b.AddBytes(extBytes)
+			})
 		}
 	})
 
-	m.raw = b.BytesOrPanic()
-	return m.raw
+	m.raw, err = b.Bytes()
+	return m.raw, err
 }
 
 // marshalWithoutBinders returns the ClientHello through the
 // PreSharedKeyExtension.identities field, according to RFC 8446, Section
 // 4.2.11.2. Note that m.pskBinders must be set to slices of the correct length.
-func (m *clientHelloMsg) marshalWithoutBinders() []byte {
+func (m *clientHelloMsg) marshalWithoutBinders() ([]byte, error) {
 	bindersLen := 2 // uint16 length prefix
 	for _, binder := range m.pskBinders {
 		bindersLen += 1 // uint8 length prefix
 		bindersLen += len(binder)
 	}
 
-	fullMessage := m.marshal()
-	return fullMessage[:len(fullMessage)-bindersLen]
+	fullMessage, err := m.marshal()
+	if err != nil {
+		return nil, err
+	}
+	return fullMessage[:len(fullMessage)-bindersLen], nil
 }
 
 // updateBinders updates the m.pskBinders field, if necessary updating the
 // cached marshaled representation. The supplied binders must have the same
 // length as the current m.pskBinders.
-func (m *clientHelloMsg) updateBinders(pskBinders [][]byte) {
+func (m *clientHelloMsg) updateBinders(pskBinders [][]byte) error {
 	if len(pskBinders) != len(m.pskBinders) {
-		panic("tls: internal error: pskBinders length mismatch")
+		return errors.New("tls: internal error: pskBinders length mismatch")
 	}
 	for i := range m.pskBinders {
 		if len(pskBinders[i]) != len(m.pskBinders[i]) {
-			panic("tls: internal error: pskBinders length mismatch")
+			return errors.New("tls: internal error: pskBinders length mismatch")
 		}
 	}
 	m.pskBinders = pskBinders
 	if m.raw != nil {
-		lenWithoutBinders := len(m.marshalWithoutBinders())
+		helloBytes, err := m.marshalWithoutBinders()
+		if err != nil {
+			return err
+		}
+		lenWithoutBinders := len(helloBytes)
 		b := cryptobyte.NewFixedBuilder(m.raw[:lenWithoutBinders])
 		b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
 			for _, binder := range m.pskBinders {
@@ -338,9 +345,11 @@
 			}
 		})
 		if out, err := b.Bytes(); err != nil || len(out) != len(m.raw) {
-			panic("tls: internal error: failed to update binders")
+			return errors.New("tls: internal error: failed to update binders")
 		}
 	}
+
+	return nil
 }
 
 func (m *clientHelloMsg) unmarshal(data []byte) bool {
@@ -618,9 +627,98 @@
 	selectedGroup CurveID
 }
 
-func (m *serverHelloMsg) marshal() []byte {
+func (m *serverHelloMsg) marshal() ([]byte, error) {
 	if m.raw != nil {
-		return m.raw
+		return m.raw, nil
+	}
+
+	var exts cryptobyte.Builder
+	if m.ocspStapling {
+		exts.AddUint16(extensionStatusRequest)
+		exts.AddUint16(0) // empty extension_data
+	}
+	if m.ticketSupported {
+		exts.AddUint16(extensionSessionTicket)
+		exts.AddUint16(0) // empty extension_data
+	}
+	if m.secureRenegotiationSupported {
+		exts.AddUint16(extensionRenegotiationInfo)
+		exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+			exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
+				exts.AddBytes(m.secureRenegotiation)
+			})
+		})
+	}
+	if len(m.alpnProtocol) > 0 {
+		exts.AddUint16(extensionALPN)
+		exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+			exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+				exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
+					exts.AddBytes([]byte(m.alpnProtocol))
+				})
+			})
+		})
+	}
+	if len(m.scts) > 0 {
+		exts.AddUint16(extensionSCT)
+		exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+			exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+				for _, sct := range m.scts {
+					exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+						exts.AddBytes(sct)
+					})
+				}
+			})
+		})
+	}
+	if m.supportedVersion != 0 {
+		exts.AddUint16(extensionSupportedVersions)
+		exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+			exts.AddUint16(m.supportedVersion)
+		})
+	}
+	if m.serverShare.group != 0 {
+		exts.AddUint16(extensionKeyShare)
+		exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+			exts.AddUint16(uint16(m.serverShare.group))
+			exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+				exts.AddBytes(m.serverShare.data)
+			})
+		})
+	}
+	if m.selectedIdentityPresent {
+		exts.AddUint16(extensionPreSharedKey)
+		exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+			exts.AddUint16(m.selectedIdentity)
+		})
+	}
+
+	if len(m.cookie) > 0 {
+		exts.AddUint16(extensionCookie)
+		exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+			exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+				exts.AddBytes(m.cookie)
+			})
+		})
+	}
+	if m.selectedGroup != 0 {
+		exts.AddUint16(extensionKeyShare)
+		exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+			exts.AddUint16(uint16(m.selectedGroup))
+		})
+	}
+	if len(m.supportedPoints) > 0 {
+		exts.AddUint16(extensionSupportedPoints)
+		exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+			exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
+				exts.AddBytes(m.supportedPoints)
+			})
+		})
+	}
+
+	extBytes, err := exts.Bytes()
+	if err != nil {
+		return nil, err
 	}
 
 	var b cryptobyte.Builder
@@ -634,104 +732,15 @@
 		b.AddUint16(m.cipherSuite)
 		b.AddUint8(m.compressionMethod)
 
-		// If extensions aren't present, omit them.
-		var extensionsPresent bool
-		bWithoutExtensions := *b
-
-		b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-			if m.ocspStapling {
-				b.AddUint16(extensionStatusRequest)
-				b.AddUint16(0) // empty extension_data
-			}
-			if m.ticketSupported {
-				b.AddUint16(extensionSessionTicket)
-				b.AddUint16(0) // empty extension_data
-			}
-			if m.secureRenegotiationSupported {
-				b.AddUint16(extensionRenegotiationInfo)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
-						b.AddBytes(m.secureRenegotiation)
-					})
-				})
-			}
-			if len(m.alpnProtocol) > 0 {
-				b.AddUint16(extensionALPN)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-						b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
-							b.AddBytes([]byte(m.alpnProtocol))
-						})
-					})
-				})
-			}
-			if len(m.scts) > 0 {
-				b.AddUint16(extensionSCT)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-						for _, sct := range m.scts {
-							b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-								b.AddBytes(sct)
-							})
-						}
-					})
-				})
-			}
-			if m.supportedVersion != 0 {
-				b.AddUint16(extensionSupportedVersions)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint16(m.supportedVersion)
-				})
-			}
-			if m.serverShare.group != 0 {
-				b.AddUint16(extensionKeyShare)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint16(uint16(m.serverShare.group))
-					b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-						b.AddBytes(m.serverShare.data)
-					})
-				})
-			}
-			if m.selectedIdentityPresent {
-				b.AddUint16(extensionPreSharedKey)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint16(m.selectedIdentity)
-				})
-			}
-
-			if len(m.cookie) > 0 {
-				b.AddUint16(extensionCookie)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-						b.AddBytes(m.cookie)
-					})
-				})
-			}
-			if m.selectedGroup != 0 {
-				b.AddUint16(extensionKeyShare)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint16(uint16(m.selectedGroup))
-				})
-			}
-			if len(m.supportedPoints) > 0 {
-				b.AddUint16(extensionSupportedPoints)
-				b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
-					b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
-						b.AddBytes(m.supportedPoints)
-					})
-				})
-			}
-
-			extensionsPresent = len(b.BytesOrPanic()) > 2
-		})
-
-		if !extensionsPresent {
-			*b = bWithoutExtensions
+		if len(extBytes) > 0 {
+			b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+				b.AddBytes(extBytes)
+			})
 		}
 	})
 
-	m.raw = b.BytesOrPanic()
-	return m.raw
+	m.raw, err = b.Bytes()
+	return m.raw, err
 }
 
 func (m *serverHelloMsg) unmarshal(data []byte) bool {
@@ -855,9 +864,9 @@
 	alpnProtocol string
 }
 
-func (m *encryptedExtensionsMsg) marshal() []byte {
+func (m *encryptedExtensionsMsg) marshal() ([]byte, error) {
 	if m.raw != nil {
-		return m.raw
+		return m.raw, nil
 	}
 
 	var b cryptobyte.Builder
@@ -877,8 +886,9 @@
 		})
 	})
 
-	m.raw = b.BytesOrPanic()
-	return m.raw
+	var err error
+	m.raw, err = b.Bytes()
+	return m.raw, err
 }
 
 func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool {
@@ -926,10 +936,10 @@
 
 type endOfEarlyDataMsg struct{}
 
-func (m *endOfEarlyDataMsg) marshal() []byte {
+func (m *endOfEarlyDataMsg) marshal() ([]byte, error) {
 	x := make([]byte, 4)
 	x[0] = typeEndOfEarlyData
-	return x
+	return x, nil
 }
 
 func (m *endOfEarlyDataMsg) unmarshal(data []byte) bool {
@@ -941,9 +951,9 @@
 	updateRequested bool
 }
 
-func (m *keyUpdateMsg) marshal() []byte {
+func (m *keyUpdateMsg) marshal() ([]byte, error) {
 	if m.raw != nil {
-		return m.raw
+		return m.raw, nil
 	}
 
 	var b cryptobyte.Builder
@@ -956,8 +966,9 @@
 		}
 	})
 
-	m.raw = b.BytesOrPanic()
-	return m.raw
+	var err error
+	m.raw, err = b.Bytes()
+	return m.raw, err
 }
 
 func (m *keyUpdateMsg) unmarshal(data []byte) bool {
@@ -989,9 +1000,9 @@
 	maxEarlyData uint32
 }
 
-func (m *newSessionTicketMsgTLS13) marshal() []byte {
+func (m *newSessionTicketMsgTLS13) marshal() ([]byte, error) {
 	if m.raw != nil {
-		return m.raw
+		return m.raw, nil
 	}
 
 	var b cryptobyte.Builder
@@ -1016,8 +1027,9 @@
 		})
 	})
 
-	m.raw = b.BytesOrPanic()
-	return m.raw
+	var err error
+	m.raw, err = b.Bytes()
+	return m.raw, err
 }
 
 func (m *newSessionTicketMsgTLS13) unmarshal(data []byte) bool {
@@ -1070,9 +1082,9 @@
 	certificateAuthorities           [][]byte
 }
 
-func (m *certificateRequestMsgTLS13) marshal() []byte {
+func (m *certificateRequestMsgTLS13) marshal() ([]byte, error) {
 	if m.raw != nil {
-		return m.raw
+		return m.raw, nil
 	}
 
 	var b cryptobyte.Builder
@@ -1131,8 +1143,9 @@
 		})
 	})
 
-	m.raw = b.BytesOrPanic()
-	return m.raw
+	var err error
+	m.raw, err = b.Bytes()
+	return m.raw, err
 }
 
 func (m *certificateRequestMsgTLS13) unmarshal(data []byte) bool {
@@ -1216,9 +1229,9 @@
 	certificates [][]byte
 }
 
-func (m *certificateMsg) marshal() (x []byte) {
+func (m *certificateMsg) marshal() ([]byte, error) {
 	if m.raw != nil {
-		return m.raw
+		return m.raw, nil
 	}
 
 	var i int
@@ -1227,7 +1240,7 @@
 	}
 
 	length := 3 + 3*len(m.certificates) + i
-	x = make([]byte, 4+length)
+	x := make([]byte, 4+length)
 	x[0] = typeCertificate
 	x[1] = uint8(length >> 16)
 	x[2] = uint8(length >> 8)
@@ -1248,7 +1261,7 @@
 	}
 
 	m.raw = x
-	return
+	return m.raw, nil
 }
 
 func (m *certificateMsg) unmarshal(data []byte) bool {
@@ -1295,9 +1308,9 @@
 	scts         bool
 }
 
-func (m *certificateMsgTLS13) marshal() []byte {
+func (m *certificateMsgTLS13) marshal() ([]byte, error) {
 	if m.raw != nil {
-		return m.raw
+		return m.raw, nil
 	}
 
 	var b cryptobyte.Builder
@@ -1315,8 +1328,9 @@
 		marshalCertificate(b, certificate)
 	})
 
-	m.raw = b.BytesOrPanic()
-	return m.raw
+	var err error
+	m.raw, err = b.Bytes()
+	return m.raw, err
 }
 
 func marshalCertificate(b *cryptobyte.Builder, certificate Certificate) {
@@ -1439,9 +1453,9 @@
 	key []byte
 }
 
-func (m *serverKeyExchangeMsg) marshal() []byte {
+func (m *serverKeyExchangeMsg) marshal() ([]byte, error) {
 	if m.raw != nil {
-		return m.raw
+		return m.raw, nil
 	}
 	length := len(m.key)
 	x := make([]byte, length+4)
@@ -1452,7 +1466,7 @@
 	copy(x[4:], m.key)
 
 	m.raw = x
-	return x
+	return x, nil
 }
 
 func (m *serverKeyExchangeMsg) unmarshal(data []byte) bool {
@@ -1469,9 +1483,9 @@
 	response []byte
 }
 
-func (m *certificateStatusMsg) marshal() []byte {
+func (m *certificateStatusMsg) marshal() ([]byte, error) {
 	if m.raw != nil {
-		return m.raw
+		return m.raw, nil
 	}
 
 	var b cryptobyte.Builder
@@ -1483,8 +1497,9 @@
 		})
 	})
 
-	m.raw = b.BytesOrPanic()
-	return m.raw
+	var err error
+	m.raw, err = b.Bytes()
+	return m.raw, err
 }
 
 func (m *certificateStatusMsg) unmarshal(data []byte) bool {
@@ -1503,10 +1518,10 @@
 
 type serverHelloDoneMsg struct{}
 
-func (m *serverHelloDoneMsg) marshal() []byte {
+func (m *serverHelloDoneMsg) marshal() ([]byte, error) {
 	x := make([]byte, 4)
 	x[0] = typeServerHelloDone
-	return x
+	return x, nil
 }
 
 func (m *serverHelloDoneMsg) unmarshal(data []byte) bool {
@@ -1518,9 +1533,9 @@
 	ciphertext []byte
 }
 
-func (m *clientKeyExchangeMsg) marshal() []byte {
+func (m *clientKeyExchangeMsg) marshal() ([]byte, error) {
 	if m.raw != nil {
-		return m.raw
+		return m.raw, nil
 	}
 	length := len(m.ciphertext)
 	x := make([]byte, length+4)
@@ -1531,7 +1546,7 @@
 	copy(x[4:], m.ciphertext)
 
 	m.raw = x
-	return x
+	return x, nil
 }
 
 func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool {
@@ -1552,9 +1567,9 @@
 	verifyData []byte
 }
 
-func (m *finishedMsg) marshal() []byte {
+func (m *finishedMsg) marshal() ([]byte, error) {
 	if m.raw != nil {
-		return m.raw
+		return m.raw, nil
 	}
 
 	var b cryptobyte.Builder
@@ -1563,8 +1578,9 @@
 		b.AddBytes(m.verifyData)
 	})
 
-	m.raw = b.BytesOrPanic()
-	return m.raw
+	var err error
+	m.raw, err = b.Bytes()
+	return m.raw, err
 }
 
 func (m *finishedMsg) unmarshal(data []byte) bool {
@@ -1586,9 +1602,9 @@
 	certificateAuthorities       [][]byte
 }
 
-func (m *certificateRequestMsg) marshal() (x []byte) {
+func (m *certificateRequestMsg) marshal() ([]byte, error) {
 	if m.raw != nil {
-		return m.raw
+		return m.raw, nil
 	}
 
 	// See RFC 4346, Section 7.4.4.
@@ -1603,7 +1619,7 @@
 		length += 2 + 2*len(m.supportedSignatureAlgorithms)
 	}
 
-	x = make([]byte, 4+length)
+	x := make([]byte, 4+length)
 	x[0] = typeCertificateRequest
 	x[1] = uint8(length >> 16)
 	x[2] = uint8(length >> 8)
@@ -1638,7 +1654,7 @@
 	}
 
 	m.raw = x
-	return
+	return m.raw, nil
 }
 
 func (m *certificateRequestMsg) unmarshal(data []byte) bool {
@@ -1724,9 +1740,9 @@
 	signature             []byte
 }
 
-func (m *certificateVerifyMsg) marshal() (x []byte) {
+func (m *certificateVerifyMsg) marshal() ([]byte, error) {
 	if m.raw != nil {
-		return m.raw
+		return m.raw, nil
 	}
 
 	var b cryptobyte.Builder
@@ -1740,8 +1756,9 @@
 		})
 	})
 
-	m.raw = b.BytesOrPanic()
-	return m.raw
+	var err error
+	m.raw, err = b.Bytes()
+	return m.raw, err
 }
 
 func (m *certificateVerifyMsg) unmarshal(data []byte) bool {
@@ -1764,15 +1781,15 @@
 	ticket []byte
 }
 
-func (m *newSessionTicketMsg) marshal() (x []byte) {
+func (m *newSessionTicketMsg) marshal() ([]byte, error) {
 	if m.raw != nil {
-		return m.raw
+		return m.raw, nil
 	}
 
 	// See RFC 5077, Section 3.3.
 	ticketLen := len(m.ticket)
 	length := 2 + 4 + ticketLen
-	x = make([]byte, 4+length)
+	x := make([]byte, 4+length)
 	x[0] = typeNewSessionTicket
 	x[1] = uint8(length >> 16)
 	x[2] = uint8(length >> 8)
@@ -1783,7 +1800,7 @@
 
 	m.raw = x
 
-	return
+	return m.raw, nil
 }
 
 func (m *newSessionTicketMsg) unmarshal(data []byte) bool {
@@ -1811,10 +1828,25 @@
 type helloRequestMsg struct {
 }
 
-func (*helloRequestMsg) marshal() []byte {
-	return []byte{typeHelloRequest, 0, 0, 0}
+func (*helloRequestMsg) marshal() ([]byte, error) {
+	return []byte{typeHelloRequest, 0, 0, 0}, nil
 }
 
 func (*helloRequestMsg) unmarshal(data []byte) bool {
 	return len(data) == 4
 }
+
+type transcriptHash interface {
+	Write([]byte) (int, error)
+}
+
+// transcriptMsg is a helper used to marshal and hash messages which typically
+// are not written to the wire, and as such aren't hashed during Conn.writeRecord.
+func transcriptMsg(msg handshakeMessage, h transcriptHash) error {
+	data, err := msg.marshal()
+	if err != nil {
+		return err
+	}
+	h.Write(data)
+	return nil
+}
diff --git a/src/crypto/tls/handshake_messages_test.go b/src/crypto/tls/handshake_messages_test.go
index c6fc8f2..206e2fb 100644
--- a/src/crypto/tls/handshake_messages_test.go
+++ b/src/crypto/tls/handshake_messages_test.go
@@ -38,6 +38,15 @@
 	&certificateMsgTLS13{},
 }
 
+func mustMarshal(t *testing.T, msg handshakeMessage) []byte {
+	t.Helper()
+	b, err := msg.marshal()
+	if err != nil {
+		t.Fatal(err)
+	}
+	return b
+}
+
 func TestMarshalUnmarshal(t *testing.T) {
 	rand := rand.New(rand.NewSource(time.Now().UnixNano()))
 
@@ -56,7 +65,7 @@
 			}
 
 			m1 := v.Interface().(handshakeMessage)
-			marshaled := m1.marshal()
+			marshaled := mustMarshal(t, m1)
 			m2 := iface.(handshakeMessage)
 			if !m2.unmarshal(marshaled) {
 				t.Errorf("#%d failed to unmarshal %#v %x", i, m1, marshaled)
@@ -409,12 +418,12 @@
 
 	var random [32]byte
 	sct := []byte{0x42, 0x42, 0x42, 0x42}
-	serverHello := serverHelloMsg{
+	serverHello := &serverHelloMsg{
 		vers:   VersionTLS12,
 		random: random[:],
 		scts:   [][]byte{sct},
 	}
-	serverHelloBytes := serverHello.marshal()
+	serverHelloBytes := mustMarshal(t, serverHello)
 
 	var serverHelloCopy serverHelloMsg
 	if !serverHelloCopy.unmarshal(serverHelloBytes) {
@@ -452,12 +461,12 @@
 	// not be zero length.
 
 	var random [32]byte
-	serverHello := serverHelloMsg{
+	serverHello := &serverHelloMsg{
 		vers:   VersionTLS12,
 		random: random[:],
 		scts:   [][]byte{nil},
 	}
-	serverHelloBytes := serverHello.marshal()
+	serverHelloBytes := mustMarshal(t, serverHello)
 
 	var serverHelloCopy serverHelloMsg
 	if serverHelloCopy.unmarshal(serverHelloBytes) {
diff --git a/src/crypto/tls/handshake_server.go b/src/crypto/tls/handshake_server.go
index 7606305..e22f284 100644
--- a/src/crypto/tls/handshake_server.go
+++ b/src/crypto/tls/handshake_server.go
@@ -16,7 +16,6 @@
 	"fmt"
 	"hash"
 	"io"
-	"sync/atomic"
 	"time"
 )
 
@@ -122,14 +121,16 @@
 	}
 
 	c.ekm = ekmFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random)
-	atomic.StoreUint32(&c.handshakeStatus, 1)
+	c.isHandshakeComplete.Store(true)
 
 	return nil
 }
 
 // readClientHello reads a ClientHello message and selects the protocol version.
 func (c *Conn) readClientHello(ctx context.Context) (*clientHelloMsg, error) {
-	msg, err := c.readHandshake()
+	// clientHelloMsg is included in the transcript, but we haven't initialized
+	// it yet. The respective handshake functions will record it themselves.
+	msg, err := c.readHandshake(nil)
 	if err != nil {
 		return nil, err
 	}
@@ -240,7 +241,7 @@
 
 	hs.ecdheOk = supportsECDHE(c.config, hs.clientHello.supportedCurves, hs.clientHello.supportedPoints)
 
-	if hs.ecdheOk {
+	if hs.ecdheOk && len(hs.clientHello.supportedPoints) > 0 {
 		// Although omitting the ec_point_formats extension is permitted, some
 		// old OpenSSL version will refuse to handshake if not present.
 		//
@@ -321,6 +322,13 @@
 			break
 		}
 	}
+	// Per RFC 8422, Section 5.1.2, if the Supported Point Formats extension is
+	// missing, uncompressed points are supported. If supportedPoints is empty,
+	// the extension must be missing, as an empty extension body is rejected by
+	// the parser. See https://go.dev/issue/49126.
+	if len(supportedPoints) == 0 {
+		supportsPointFormat = true
+	}
 
 	return supportsCurve && supportsPointFormat
 }
@@ -456,9 +464,10 @@
 	hs.hello.ticketSupported = hs.sessionState.usedOldKey
 	hs.finishedHash = newFinishedHash(c.vers, hs.suite)
 	hs.finishedHash.discardHandshakeBuffer()
-	hs.finishedHash.Write(hs.clientHello.marshal())
-	hs.finishedHash.Write(hs.hello.marshal())
-	if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil {
+	if err := transcriptMsg(hs.clientHello, &hs.finishedHash); err != nil {
+		return err
+	}
+	if _, err := hs.c.writeHandshakeRecord(hs.hello, &hs.finishedHash); err != nil {
 		return err
 	}
 
@@ -496,24 +505,23 @@
 		// certificates won't be used.
 		hs.finishedHash.discardHandshakeBuffer()
 	}
-	hs.finishedHash.Write(hs.clientHello.marshal())
-	hs.finishedHash.Write(hs.hello.marshal())
-	if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil {
+	if err := transcriptMsg(hs.clientHello, &hs.finishedHash); err != nil {
+		return err
+	}
+	if _, err := hs.c.writeHandshakeRecord(hs.hello, &hs.finishedHash); err != nil {
 		return err
 	}
 
 	certMsg := new(certificateMsg)
 	certMsg.certificates = hs.cert.Certificate
-	hs.finishedHash.Write(certMsg.marshal())
-	if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil {
+	if _, err := hs.c.writeHandshakeRecord(certMsg, &hs.finishedHash); err != nil {
 		return err
 	}
 
 	if hs.hello.ocspStapling {
 		certStatus := new(certificateStatusMsg)
 		certStatus.response = hs.cert.OCSPStaple
-		hs.finishedHash.Write(certStatus.marshal())
-		if _, err := c.writeRecord(recordTypeHandshake, certStatus.marshal()); err != nil {
+		if _, err := hs.c.writeHandshakeRecord(certStatus, &hs.finishedHash); err != nil {
 			return err
 		}
 	}
@@ -525,8 +533,7 @@
 		return err
 	}
 	if skx != nil {
-		hs.finishedHash.Write(skx.marshal())
-		if _, err := c.writeRecord(recordTypeHandshake, skx.marshal()); err != nil {
+		if _, err := hs.c.writeHandshakeRecord(skx, &hs.finishedHash); err != nil {
 			return err
 		}
 	}
@@ -552,15 +559,13 @@
 		if c.config.ClientCAs != nil {
 			certReq.certificateAuthorities = c.config.ClientCAs.Subjects()
 		}
-		hs.finishedHash.Write(certReq.marshal())
-		if _, err := c.writeRecord(recordTypeHandshake, certReq.marshal()); err != nil {
+		if _, err := hs.c.writeHandshakeRecord(certReq, &hs.finishedHash); err != nil {
 			return err
 		}
 	}
 
 	helloDone := new(serverHelloDoneMsg)
-	hs.finishedHash.Write(helloDone.marshal())
-	if _, err := c.writeRecord(recordTypeHandshake, helloDone.marshal()); err != nil {
+	if _, err := hs.c.writeHandshakeRecord(helloDone, &hs.finishedHash); err != nil {
 		return err
 	}
 
@@ -570,7 +575,7 @@
 
 	var pub crypto.PublicKey // public key for client auth, if any
 
-	msg, err := c.readHandshake()
+	msg, err := c.readHandshake(&hs.finishedHash)
 	if err != nil {
 		return err
 	}
@@ -583,7 +588,6 @@
 			c.sendAlert(alertUnexpectedMessage)
 			return unexpectedMessageError(certMsg, msg)
 		}
-		hs.finishedHash.Write(certMsg.marshal())
 
 		if err := c.processCertsFromClient(Certificate{
 			Certificate: certMsg.certificates,
@@ -594,7 +598,7 @@
 			pub = c.peerCertificates[0].PublicKey
 		}
 
-		msg, err = c.readHandshake()
+		msg, err = c.readHandshake(&hs.finishedHash)
 		if err != nil {
 			return err
 		}
@@ -612,7 +616,6 @@
 		c.sendAlert(alertUnexpectedMessage)
 		return unexpectedMessageError(ckx, msg)
 	}
-	hs.finishedHash.Write(ckx.marshal())
 
 	preMasterSecret, err := keyAgreement.processClientKeyExchange(c.config, hs.cert, ckx, c.vers)
 	if err != nil {
@@ -632,7 +635,10 @@
 	// to the client's certificate. This allows us to verify that the client is in
 	// possession of the private key of the certificate.
 	if len(c.peerCertificates) > 0 {
-		msg, err = c.readHandshake()
+		// certificateVerifyMsg is included in the transcript, but not until
+		// after we verify the handshake signature, since the state before
+		// this message was sent is used.
+		msg, err = c.readHandshake(nil)
 		if err != nil {
 			return err
 		}
@@ -661,13 +667,15 @@
 			}
 		}
 
-		signed := hs.finishedHash.hashForClientCertificate(sigType, sigHash, hs.masterSecret)
+		signed := hs.finishedHash.hashForClientCertificate(sigType, sigHash)
 		if err := verifyHandshakeSignature(sigType, pub, sigHash, signed, certVerify.signature); err != nil {
 			c.sendAlert(alertDecryptError)
 			return errors.New("tls: invalid signature by the client certificate: " + err.Error())
 		}
 
-		hs.finishedHash.Write(certVerify.marshal())
+		if err := transcriptMsg(certVerify, &hs.finishedHash); err != nil {
+			return err
+		}
 	}
 
 	hs.finishedHash.discardHandshakeBuffer()
@@ -707,7 +715,10 @@
 		return err
 	}
 
-	msg, err := c.readHandshake()
+	// finishedMsg is included in the transcript, but not until after we
+	// check the client version, since the state before this message was
+	// sent is used during verification.
+	msg, err := c.readHandshake(nil)
 	if err != nil {
 		return err
 	}
@@ -724,7 +735,10 @@
 		return errors.New("tls: client's Finished message is incorrect")
 	}
 
-	hs.finishedHash.Write(clientFinished.marshal())
+	if err := transcriptMsg(clientFinished, &hs.finishedHash); err != nil {
+		return err
+	}
+
 	copy(out, verify)
 	return nil
 }
@@ -758,14 +772,16 @@
 		masterSecret: hs.masterSecret,
 		certificates: certsFromClient,
 	}
-	var err error
-	m.ticket, err = c.encryptTicket(state.marshal())
+	stateBytes, err := state.marshal()
+	if err != nil {
+		return err
+	}
+	m.ticket, err = c.encryptTicket(stateBytes)
 	if err != nil {
 		return err
 	}
 
-	hs.finishedHash.Write(m.marshal())
-	if _, err := c.writeRecord(recordTypeHandshake, m.marshal()); err != nil {
+	if _, err := hs.c.writeHandshakeRecord(m, &hs.finishedHash); err != nil {
 		return err
 	}
 
@@ -775,14 +791,13 @@
 func (hs *serverHandshakeState) sendFinished(out []byte) error {
 	c := hs.c
 
-	if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil {
+	if err := c.writeChangeCipherRecord(); err != nil {
 		return err
 	}
 
 	finished := new(finishedMsg)
 	finished.verifyData = hs.finishedHash.serverSum(hs.masterSecret)
-	hs.finishedHash.Write(finished.marshal())
-	if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil {
+	if _, err := hs.c.writeHandshakeRecord(finished, &hs.finishedHash); err != nil {
 		return err
 	}
 
@@ -825,7 +840,7 @@
 		chains, err := certs[0].Verify(opts)
 		if err != nil {
 			c.sendAlert(alertBadCertificate)
-			return errors.New("tls: failed to verify client certificate: " + err.Error())
+			return &CertificateVerificationError{UnverifiedCertificates: certs, Err: err}
 		}
 
 		c.verifiedChains = chains
diff --git a/src/crypto/tls/handshake_server_test.go b/src/crypto/tls/handshake_server_test.go
index 5ff5270..04abdcc 100644
--- a/src/crypto/tls/handshake_server_test.go
+++ b/src/crypto/tls/handshake_server_test.go
@@ -8,7 +8,9 @@
 	"bytes"
 	"context"
 	"crypto"
+	"crypto/ecdh"
 	"crypto/elliptic"
+	"crypto/rand"
 	"crypto/x509"
 	"encoding/pem"
 	"errors"
@@ -22,14 +24,19 @@
 	"strings"
 	"testing"
 	"time"
-
-	"golang.org/x/crypto/curve25519"
 )
 
 func testClientHello(t *testing.T, serverConfig *Config, m handshakeMessage) {
 	testClientHelloFailure(t, serverConfig, m, "")
 }
 
+// testFatal is a hack to prevent the compiler from complaining that there is a
+// call to t.Fatal from a non-test goroutine
+func testFatal(t *testing.T, err error) {
+	t.Helper()
+	t.Fatal(err)
+}
+
 func testClientHelloFailure(t *testing.T, serverConfig *Config, m handshakeMessage, expectedSubStr string) {
 	c, s := localPipe(t)
 	go func() {
@@ -37,7 +44,9 @@
 		if ch, ok := m.(*clientHelloMsg); ok {
 			cli.vers = ch.vers
 		}
-		cli.writeRecord(recordTypeHandshake, m.marshal())
+		if _, err := cli.writeHandshakeRecord(m, nil); err != nil {
+			testFatal(t, err)
+		}
 		c.Close()
 	}()
 	ctx := context.Background()
@@ -194,7 +203,9 @@
 	go func() {
 		cli := Client(c, testConfig)
 		cli.vers = clientHello.vers
-		cli.writeRecord(recordTypeHandshake, clientHello.marshal())
+		if _, err := cli.writeHandshakeRecord(clientHello, nil); err != nil {
+			testFatal(t, err)
+		}
 
 		buf := make([]byte, 1024)
 		n, err := c.Read(buf)
@@ -253,8 +264,10 @@
 	go func() {
 		cli := Client(c, testConfig)
 		cli.vers = clientHello.vers
-		cli.writeRecord(recordTypeHandshake, clientHello.marshal())
-		reply, err := cli.readHandshake()
+		if _, err := cli.writeHandshakeRecord(clientHello, nil); err != nil {
+			testFatal(t, err)
+		}
+		reply, err := cli.readHandshake(nil)
 		c.Close()
 		if err != nil {
 			replyChan <- err
@@ -281,7 +294,7 @@
 
 func TestTLSPointFormats(t *testing.T) {
 	// Test that a Server returns the ec_point_format extension when ECC is
-	// negotiated, and not returned on RSA handshake.
+	// negotiated, and not on a RSA handshake or if ec_point_format is missing.
 	tests := []struct {
 		name                string
 		cipherSuites        []uint16
@@ -289,8 +302,11 @@
 		supportedPoints     []uint8
 		wantSupportedPoints bool
 	}{
-		{"ECC", []uint16{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA}, []CurveID{CurveP256}, []uint8{compressionNone}, true},
+		{"ECC", []uint16{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA}, []CurveID{CurveP256}, []uint8{pointFormatUncompressed}, true},
+		{"ECC without ec_point_format", []uint16{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA}, []CurveID{CurveP256}, nil, false},
+		{"ECC with extra values", []uint16{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA}, []CurveID{CurveP256}, []uint8{13, 37, pointFormatUncompressed, 42}, true},
 		{"RSA", []uint16{TLS_RSA_WITH_AES_256_GCM_SHA384}, nil, nil, false},
+		{"RSA with ec_point_format", []uint16{TLS_RSA_WITH_AES_256_GCM_SHA384}, nil, []uint8{pointFormatUncompressed}, false},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
@@ -308,8 +324,10 @@
 			go func() {
 				cli := Client(c, testConfig)
 				cli.vers = clientHello.vers
-				cli.writeRecord(recordTypeHandshake, clientHello.marshal())
-				reply, err := cli.readHandshake()
+				if _, err := cli.writeHandshakeRecord(clientHello, nil); err != nil {
+					testFatal(t, err)
+				}
+				reply, err := cli.readHandshake(nil)
 				c.Close()
 				if err != nil {
 					replyChan <- err
@@ -330,18 +348,8 @@
 				t.Fatalf("didn't get ServerHello message in reply. Got %v\n", reply)
 			}
 			if tt.wantSupportedPoints {
-				if len(serverHello.supportedPoints) < 1 {
-					t.Fatal("missing ec_point_format extension from server")
-				}
-				found := false
-				for _, p := range serverHello.supportedPoints {
-					if p == pointFormatUncompressed {
-						found = true
-						break
-					}
-				}
-				if !found {
-					t.Fatal("missing uncompressed format in ec_point_format extension from server")
+				if !bytes.Equal(serverHello.supportedPoints, []uint8{pointFormatUncompressed}) {
+					t.Fatal("incorrect ec_point_format extension from server")
 				}
 			} else {
 				if len(serverHello.supportedPoints) != 0 {
@@ -1433,7 +1441,9 @@
 	go func() {
 		cli := Client(c, testConfig)
 		cli.vers = clientHello.vers
-		cli.writeRecord(recordTypeHandshake, clientHello.marshal())
+		if _, err := cli.writeHandshakeRecord(clientHello, nil); err != nil {
+			testFatal(t, err)
+		}
 		c.Close()
 	}()
 	conn := Server(s, serverConfig)
@@ -1909,6 +1919,7 @@
 	for _, tc := range tests {
 		t.Run(tc.name, func(t *testing.T) {
 			hasAESGCMHardwareSupport = tc.serverHasAESGCM
+			pk, _ := ecdh.X25519().GenerateKey(rand.Reader)
 			hs := &serverHandshakeStateTLS13{
 				c: &Conn{
 					config: &Config{},
@@ -1918,7 +1929,7 @@
 					cipherSuites:       tc.clientCiphers,
 					supportedVersions:  []uint16{VersionTLS13},
 					compressionMethods: []uint8{compressionNone},
-					keyShares:          []keyShare{{group: X25519, data: curve25519.Basepoint}},
+					keyShares:          []keyShare{{group: X25519, data: pk.PublicKey().Bytes()}},
 				},
 			}
 
diff --git a/src/crypto/tls/handshake_server_tls13.go b/src/crypto/tls/handshake_server_tls13.go
index 03a477f..b7b568c 100644
--- a/src/crypto/tls/handshake_server_tls13.go
+++ b/src/crypto/tls/handshake_server_tls13.go
@@ -14,7 +14,6 @@
 	"errors"
 	"hash"
 	"io"
-	"sync/atomic"
 	"time"
 )
 
@@ -82,7 +81,7 @@
 		return err
 	}
 
-	atomic.StoreUint32(&c.handshakeStatus, 1)
+	c.isHandshakeComplete.Store(true)
 
 	return nil
 }
@@ -206,18 +205,23 @@
 		clientKeyShare = &hs.clientHello.keyShares[0]
 	}
 
-	if _, ok := curveForCurveID(selectedGroup); selectedGroup != X25519 && !ok {
+	if _, ok := curveForCurveID(selectedGroup); !ok {
 		c.sendAlert(alertInternalError)
 		return errors.New("tls: CurvePreferences includes unsupported curve")
 	}
-	params, err := generateECDHEParameters(c.config.rand(), selectedGroup)
+	key, err := generateECDHEKey(c.config.rand(), selectedGroup)
 	if err != nil {
 		c.sendAlert(alertInternalError)
 		return err
 	}
-	hs.hello.serverShare = keyShare{group: selectedGroup, data: params.PublicKey()}
-	hs.sharedKey = params.SharedKey(clientKeyShare.data)
-	if hs.sharedKey == nil {
+	hs.hello.serverShare = keyShare{group: selectedGroup, data: key.PublicKey().Bytes()}
+	peerKey, err := key.Curve().NewPublicKey(clientKeyShare.data)
+	if err != nil {
+		c.sendAlert(alertIllegalParameter)
+		return errors.New("tls: invalid client key share")
+	}
+	hs.sharedKey, err = key.ECDH(peerKey)
+	if err != nil {
 		c.sendAlert(alertIllegalParameter)
 		return errors.New("tls: invalid client key share")
 	}
@@ -302,7 +306,12 @@
 			c.sendAlert(alertInternalError)
 			return errors.New("tls: internal error: failed to clone hash")
 		}
-		transcript.Write(hs.clientHello.marshalWithoutBinders())
+		clientHelloBytes, err := hs.clientHello.marshalWithoutBinders()
+		if err != nil {
+			c.sendAlert(alertInternalError)
+			return err
+		}
+		transcript.Write(clientHelloBytes)
 		pskBinder := hs.suite.finishedHash(binderKey, transcript)
 		if !hmac.Equal(hs.clientHello.pskBinders[i], pskBinder) {
 			c.sendAlert(alertDecryptError)
@@ -393,8 +402,7 @@
 	}
 	hs.sentDummyCCS = true
 
-	_, err := hs.c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
-	return err
+	return hs.c.writeChangeCipherRecord()
 }
 
 func (hs *serverHandshakeStateTLS13) doHelloRetryRequest(selectedGroup CurveID) error {
@@ -402,7 +410,9 @@
 
 	// The first ClientHello gets double-hashed into the transcript upon a
 	// HelloRetryRequest. See RFC 8446, Section 4.4.1.
-	hs.transcript.Write(hs.clientHello.marshal())
+	if err := transcriptMsg(hs.clientHello, hs.transcript); err != nil {
+		return err
+	}
 	chHash := hs.transcript.Sum(nil)
 	hs.transcript.Reset()
 	hs.transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))})
@@ -418,8 +428,7 @@
 		selectedGroup:     selectedGroup,
 	}
 
-	hs.transcript.Write(helloRetryRequest.marshal())
-	if _, err := c.writeRecord(recordTypeHandshake, helloRetryRequest.marshal()); err != nil {
+	if _, err := hs.c.writeHandshakeRecord(helloRetryRequest, hs.transcript); err != nil {
 		return err
 	}
 
@@ -427,7 +436,8 @@
 		return err
 	}
 
-	msg, err := c.readHandshake()
+	// clientHelloMsg is not included in the transcript.
+	msg, err := c.readHandshake(nil)
 	if err != nil {
 		return err
 	}
@@ -518,9 +528,10 @@
 func (hs *serverHandshakeStateTLS13) sendServerParameters() error {
 	c := hs.c
 
-	hs.transcript.Write(hs.clientHello.marshal())
-	hs.transcript.Write(hs.hello.marshal())
-	if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil {
+	if err := transcriptMsg(hs.clientHello, hs.transcript); err != nil {
+		return err
+	}
+	if _, err := hs.c.writeHandshakeRecord(hs.hello, hs.transcript); err != nil {
 		return err
 	}
 
@@ -563,8 +574,7 @@
 	encryptedExtensions.alpnProtocol = selectedProto
 	c.clientProtocol = selectedProto
 
-	hs.transcript.Write(encryptedExtensions.marshal())
-	if _, err := c.writeRecord(recordTypeHandshake, encryptedExtensions.marshal()); err != nil {
+	if _, err := hs.c.writeHandshakeRecord(encryptedExtensions, hs.transcript); err != nil {
 		return err
 	}
 
@@ -593,8 +603,7 @@
 			certReq.certificateAuthorities = c.config.ClientCAs.Subjects()
 		}
 
-		hs.transcript.Write(certReq.marshal())
-		if _, err := c.writeRecord(recordTypeHandshake, certReq.marshal()); err != nil {
+		if _, err := hs.c.writeHandshakeRecord(certReq, hs.transcript); err != nil {
 			return err
 		}
 	}
@@ -605,8 +614,7 @@
 	certMsg.scts = hs.clientHello.scts && len(hs.cert.SignedCertificateTimestamps) > 0
 	certMsg.ocspStapling = hs.clientHello.ocspStapling && len(hs.cert.OCSPStaple) > 0
 
-	hs.transcript.Write(certMsg.marshal())
-	if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil {
+	if _, err := hs.c.writeHandshakeRecord(certMsg, hs.transcript); err != nil {
 		return err
 	}
 
@@ -637,8 +645,7 @@
 	}
 	certVerifyMsg.signature = sig
 
-	hs.transcript.Write(certVerifyMsg.marshal())
-	if _, err := c.writeRecord(recordTypeHandshake, certVerifyMsg.marshal()); err != nil {
+	if _, err := hs.c.writeHandshakeRecord(certVerifyMsg, hs.transcript); err != nil {
 		return err
 	}
 
@@ -652,8 +659,7 @@
 		verifyData: hs.suite.finishedHash(c.out.trafficSecret, hs.transcript),
 	}
 
-	hs.transcript.Write(finished.marshal())
-	if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil {
+	if _, err := hs.c.writeHandshakeRecord(finished, hs.transcript); err != nil {
 		return err
 	}
 
@@ -714,7 +720,9 @@
 	finishedMsg := &finishedMsg{
 		verifyData: hs.clientFinished,
 	}
-	hs.transcript.Write(finishedMsg.marshal())
+	if err := transcriptMsg(finishedMsg, hs.transcript); err != nil {
+		return err
+	}
 
 	if !hs.shouldSendSessionTickets() {
 		return nil
@@ -739,8 +747,12 @@
 			SignedCertificateTimestamps: c.scts,
 		},
 	}
-	var err error
-	m.label, err = c.encryptTicket(state.marshal())
+	stateBytes, err := state.marshal()
+	if err != nil {
+		c.sendAlert(alertInternalError)
+		return err
+	}
+	m.label, err = c.encryptTicket(stateBytes)
 	if err != nil {
 		return err
 	}
@@ -759,7 +771,7 @@
 	// ticket_nonce, which must be unique per connection, is always left at
 	// zero because we only ever send one ticket per connection.
 
-	if _, err := c.writeRecord(recordTypeHandshake, m.marshal()); err != nil {
+	if _, err := c.writeHandshakeRecord(m, nil); err != nil {
 		return err
 	}
 
@@ -784,7 +796,7 @@
 	// If we requested a client certificate, then the client must send a
 	// certificate message. If it's empty, no CertificateVerify is sent.
 
-	msg, err := c.readHandshake()
+	msg, err := c.readHandshake(hs.transcript)
 	if err != nil {
 		return err
 	}
@@ -794,7 +806,6 @@
 		c.sendAlert(alertUnexpectedMessage)
 		return unexpectedMessageError(certMsg, msg)
 	}
-	hs.transcript.Write(certMsg.marshal())
 
 	if err := c.processCertsFromClient(certMsg.certificate); err != nil {
 		return err
@@ -808,7 +819,10 @@
 	}
 
 	if len(certMsg.certificate.Certificate) != 0 {
-		msg, err = c.readHandshake()
+		// certificateVerifyMsg is included in the transcript, but not until
+		// after we verify the handshake signature, since the state before
+		// this message was sent is used.
+		msg, err = c.readHandshake(nil)
 		if err != nil {
 			return err
 		}
@@ -839,7 +853,9 @@
 			return errors.New("tls: invalid signature by the client certificate: " + err.Error())
 		}
 
-		hs.transcript.Write(certVerify.marshal())
+		if err := transcriptMsg(certVerify, hs.transcript); err != nil {
+			return err
+		}
 	}
 
 	// If we waited until the client certificates to send session tickets, we
@@ -854,7 +870,8 @@
 func (hs *serverHandshakeStateTLS13) readClientFinished() error {
 	c := hs.c
 
-	msg, err := c.readHandshake()
+	// finishedMsg is not included in the transcript.
+	msg, err := c.readHandshake(nil)
 	if err != nil {
 		return err
 	}
diff --git a/src/crypto/tls/key_agreement.go b/src/crypto/tls/key_agreement.go
index c28a64f..2c8c5b8 100644
--- a/src/crypto/tls/key_agreement.go
+++ b/src/crypto/tls/key_agreement.go
@@ -6,6 +6,7 @@
 
 import (
 	"crypto"
+	"crypto/ecdh"
 	"crypto/md5"
 	"crypto/rsa"
 	"crypto/sha1"
@@ -157,7 +158,7 @@
 type ecdheKeyAgreement struct {
 	version uint16
 	isRSA   bool
-	params  ecdheParameters
+	key     *ecdh.PrivateKey
 
 	// ckx and preMasterSecret are generated in processServerKeyExchange
 	// and returned in generateClientKeyExchange.
@@ -177,18 +178,18 @@
 	if curveID == 0 {
 		return nil, errors.New("tls: no supported elliptic curves offered")
 	}
-	if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok {
+	if _, ok := curveForCurveID(curveID); !ok {
 		return nil, errors.New("tls: CurvePreferences includes unsupported curve")
 	}
 
-	params, err := generateECDHEParameters(config.rand(), curveID)
+	key, err := generateECDHEKey(config.rand(), curveID)
 	if err != nil {
 		return nil, err
 	}
-	ka.params = params
+	ka.key = key
 
 	// See RFC 4492, Section 5.4.
-	ecdhePublic := params.PublicKey()
+	ecdhePublic := key.PublicKey().Bytes()
 	serverECDHEParams := make([]byte, 1+2+1+len(ecdhePublic))
 	serverECDHEParams[0] = 3 // named curve
 	serverECDHEParams[1] = byte(curveID >> 8)
@@ -259,8 +260,12 @@
 		return nil, errClientKeyExchange
 	}
 
-	preMasterSecret := ka.params.SharedKey(ckx.ciphertext[1:])
-	if preMasterSecret == nil {
+	peerKey, err := ka.key.Curve().NewPublicKey(ckx.ciphertext[1:])
+	if err != nil {
+		return nil, errClientKeyExchange
+	}
+	preMasterSecret, err := ka.key.ECDH(peerKey)
+	if err != nil {
 		return nil, errClientKeyExchange
 	}
 
@@ -288,22 +293,26 @@
 		return errServerKeyExchange
 	}
 
-	if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok {
+	if _, ok := curveForCurveID(curveID); !ok {
 		return errors.New("tls: server selected unsupported curve")
 	}
 
-	params, err := generateECDHEParameters(config.rand(), curveID)
+	key, err := generateECDHEKey(config.rand(), curveID)
 	if err != nil {
 		return err
 	}
-	ka.params = params
+	ka.key = key
 
-	ka.preMasterSecret = params.SharedKey(publicKey)
-	if ka.preMasterSecret == nil {
+	peerKey, err := key.Curve().NewPublicKey(publicKey)
+	if err != nil {
+		return errServerKeyExchange
+	}
+	ka.preMasterSecret, err = key.ECDH(peerKey)
+	if err != nil {
 		return errServerKeyExchange
 	}
 
-	ourPublicKey := params.PublicKey()
+	ourPublicKey := key.PublicKey().Bytes()
 	ka.ckx = new(clientKeyExchangeMsg)
 	ka.ckx.ciphertext = make([]byte, 1+len(ourPublicKey))
 	ka.ckx.ciphertext[0] = byte(len(ourPublicKey))
diff --git a/src/crypto/tls/key_schedule.go b/src/crypto/tls/key_schedule.go
index 3140169..ae8f80a 100644
--- a/src/crypto/tls/key_schedule.go
+++ b/src/crypto/tls/key_schedule.go
@@ -5,15 +5,14 @@
 package tls
 
 import (
-	"crypto/elliptic"
+	"crypto/ecdh"
 	"crypto/hmac"
 	"errors"
+	"fmt"
 	"hash"
 	"io"
-	"math/big"
 
 	"golang.org/x/crypto/cryptobyte"
-	"golang.org/x/crypto/curve25519"
 	"golang.org/x/crypto/hkdf"
 )
 
@@ -42,8 +41,24 @@
 	hkdfLabel.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
 		b.AddBytes(context)
 	})
+	hkdfLabelBytes, err := hkdfLabel.Bytes()
+	if err != nil {
+		// Rather than calling BytesOrPanic, we explicitly handle this error, in
+		// order to provide a reasonable error message. It should be basically
+		// impossible for this to panic, and routing errors back through the
+		// tree rooted in this function is quite painful. The labels are fixed
+		// size, and the context is either a fixed-length computed hash, or
+		// parsed from a field which has the same length limitation. As such, an
+		// error here is likely to only be caused during development.
+		//
+		// NOTE: another reasonable approach here might be to return a
+		// randomized slice if we encounter an error, which would break the
+		// connection, but avoid panicking. This would perhaps be safer but
+		// significantly more confusing to users.
+		panic(fmt.Errorf("failed to construct HKDF label: %s", err))
+	}
 	out := make([]byte, length)
-	n, err := hkdf.Expand(c.hash.New, secret, hkdfLabel.BytesOrPanic()).Read(out)
+	n, err := hkdf.Expand(c.hash.New, secret, hkdfLabelBytes).Read(out)
 	if err != nil || n != length {
 		panic("tls: HKDF-Expand-Label invocation failed unexpectedly")
 	}
@@ -101,99 +116,43 @@
 	}
 }
 
-// ecdheParameters implements Diffie-Hellman with either NIST curves or X25519,
+// generateECDHEKey returns a PrivateKey that implements Diffie-Hellman
 // according to RFC 8446, Section 4.2.8.2.
-type ecdheParameters interface {
-	CurveID() CurveID
-	PublicKey() []byte
-	SharedKey(peerPublicKey []byte) []byte
-}
-
-func generateECDHEParameters(rand io.Reader, curveID CurveID) (ecdheParameters, error) {
-	if curveID == X25519 {
-		privateKey := make([]byte, curve25519.ScalarSize)
-		if _, err := io.ReadFull(rand, privateKey); err != nil {
-			return nil, err
-		}
-		publicKey, err := curve25519.X25519(privateKey, curve25519.Basepoint)
-		if err != nil {
-			return nil, err
-		}
-		return &x25519Parameters{privateKey: privateKey, publicKey: publicKey}, nil
-	}
-
+func generateECDHEKey(rand io.Reader, curveID CurveID) (*ecdh.PrivateKey, error) {
 	curve, ok := curveForCurveID(curveID)
 	if !ok {
 		return nil, errors.New("tls: internal error: unsupported curve")
 	}
 
-	p := &nistParameters{curveID: curveID}
-	var err error
-	p.privateKey, p.x, p.y, err = elliptic.GenerateKey(curve, rand)
-	if err != nil {
-		return nil, err
-	}
-	return p, nil
+	return curve.GenerateKey(rand)
 }
 
-func curveForCurveID(id CurveID) (elliptic.Curve, bool) {
+func curveForCurveID(id CurveID) (ecdh.Curve, bool) {
 	switch id {
+	case X25519:
+		return ecdh.X25519(), true
 	case CurveP256:
-		return elliptic.P256(), true
+		return ecdh.P256(), true
 	case CurveP384:
-		return elliptic.P384(), true
+		return ecdh.P384(), true
 	case CurveP521:
-		return elliptic.P521(), true
+		return ecdh.P521(), true
 	default:
 		return nil, false
 	}
 }
 
-type nistParameters struct {
-	privateKey []byte
-	x, y       *big.Int // public key
-	curveID    CurveID
-}
-
-func (p *nistParameters) CurveID() CurveID {
-	return p.curveID
-}
-
-func (p *nistParameters) PublicKey() []byte {
-	curve, _ := curveForCurveID(p.curveID)
-	return elliptic.Marshal(curve, p.x, p.y)
-}
-
-func (p *nistParameters) SharedKey(peerPublicKey []byte) []byte {
-	curve, _ := curveForCurveID(p.curveID)
-	// Unmarshal also checks whether the given point is on the curve.
-	x, y := elliptic.Unmarshal(curve, peerPublicKey)
-	if x == nil {
-		return nil
+func curveIDForCurve(curve ecdh.Curve) (CurveID, bool) {
+	switch curve {
+	case ecdh.X25519():
+		return X25519, true
+	case ecdh.P256():
+		return CurveP256, true
+	case ecdh.P384():
+		return CurveP384, true
+	case ecdh.P521():
+		return CurveP521, true
+	default:
+		return 0, false
 	}
-
-	xShared, _ := curve.ScalarMult(x, y, p.privateKey)
-	sharedKey := make([]byte, (curve.Params().BitSize+7)/8)
-	return xShared.FillBytes(sharedKey)
-}
-
-type x25519Parameters struct {
-	privateKey []byte
-	publicKey  []byte
-}
-
-func (p *x25519Parameters) CurveID() CurveID {
-	return X25519
-}
-
-func (p *x25519Parameters) PublicKey() []byte {
-	return p.publicKey[:]
-}
-
-func (p *x25519Parameters) SharedKey(peerPublicKey []byte) []byte {
-	sharedKey, err := curve25519.X25519(p.privateKey, peerPublicKey)
-	if err != nil {
-		return nil
-	}
-	return sharedKey
 }
diff --git a/src/crypto/tls/link_test.go b/src/crypto/tls/link_test.go
index 8c392ff..454d370 100644
--- a/src/crypto/tls/link_test.go
+++ b/src/crypto/tls/link_test.go
@@ -36,8 +36,8 @@
 `,
 			bad: []string{
 				"tls.(*Conn)",
-				"type.crypto/tls.clientHandshakeState",
-				"type.crypto/tls.serverHandshakeState",
+				"type:crypto/tls.clientHandshakeState",
+				"type:crypto/tls.serverHandshakeState",
 			},
 		},
 		{
diff --git a/src/crypto/tls/prf.go b/src/crypto/tls/prf.go
index 13bfa00..b60166d 100644
--- a/src/crypto/tls/prf.go
+++ b/src/crypto/tls/prf.go
@@ -215,7 +215,7 @@
 
 // hashForClientCertificate returns the handshake messages so far, pre-hashed if
 // necessary, suitable for signing by a TLS client certificate.
-func (h finishedHash) hashForClientCertificate(sigType uint8, hashAlg crypto.Hash, masterSecret []byte) []byte {
+func (h finishedHash) hashForClientCertificate(sigType uint8, hashAlg crypto.Hash) []byte {
 	if (h.version >= VersionTLS12 || sigType == signatureEd25519) && h.buffer == nil {
 		panic("tls: handshake hash for a client certificate requested after discarding the handshake buffer")
 	}
diff --git a/src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-ECDSA b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-ECDSA
index c7fa530..d93f679 100644
--- a/src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-ECDSA
+++ b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-ECDSA
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 01 00 59 02 00 00  55 03 01 92 4c b7 e6 07  |....Y...U...L...|
-00000010  09 b4 4a 47 6a 29 c7 79  18 0d 43 37 86 26 21 5a  |..JGj).y..C7.&!Z|
-00000020  25 35 db 5f ae d0 20 0d  85 67 f7 20 75 e5 cb 25  |%5._.. ..g. u..%|
-00000030  4b 5d 95 87 78 00 fc 3f  78 26 e8 77 b5 0d d4 0e  |K]..x..?x&.w....|
-00000040  54 06 66 b4 14 dc 6b db  f2 af f3 2a c0 09 00 00  |T.f...k....*....|
+00000000  16 03 01 00 59 02 00 00  55 03 01 f1 70 ef e1 e5  |....Y...U...p...|
+00000010  96 73 83 d3 e2 b9 53 7e  81 ae 1d 40 24 5a ca f2  |.s....S~...@$Z..|
+00000020  06 b3 b6 01 e4 02 fb 81  bc d9 3d 20 1f 1a f0 b5  |..........= ....|
+00000030  b2 93 42 da 00 4d bf f6  dc 99 54 8d 3b 17 a4 74  |..B..M....T.;..t|
+00000040  ca 93 e1 5c a9 c4 d1 35  af f2 d8 f9 c0 09 00 00  |...\...5........|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  01 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
 00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
@@ -55,18 +55,18 @@
 00000240  13 83 0d 94 06 bb d4 37  7a f6 ec 7a c9 86 2e dd  |.......7z..z....|
 00000250  d7 11 69 7f 85 7c 56 de  fb 31 78 2b e4 c7 78 0d  |..i..|V..1x+..x.|
 00000260  ae cb be 9e 4e 36 24 31  7b 6a 0f 39 95 12 07 8f  |....N6$1{j.9....|
-00000270  2a 16 03 01 00 b5 0c 00  00 b1 03 00 1d 20 d7 b5  |*............ ..|
-00000280  51 8e b5 01 4f 02 2f 43  11 2b de 94 7d 82 e6 49  |Q...O./C.+..}..I|
-00000290  1b a6 ee a0 7f 12 35 a2  3a 62 46 ce 07 25 00 8b  |......5.:bF..%..|
-000002a0  30 81 88 02 42 00 83 45  db 03 db b9 74 ce 77 35  |0...B..E....t.w5|
-000002b0  1b e5 76 18 dc 3a d3 ee  32 18 f3 16 a6 c3 62 be  |..v..:..2.....b.|
-000002c0  46 47 40 80 2d a0 08 c5  1e 5a 4a 42 69 8c ee e5  |[email protected]...|
-000002d0  70 b5 71 30 2f 54 32 54  5f 5b 26 62 e1 81 52 9e  |p.q0/T2T_[&b..R.|
-000002e0  49 70 d4 81 e4 76 f1 02  42 01 70 f6 87 84 bb 58  |Ip...v..B.p....X|
-000002f0  5d e4 a1 72 87 d5 35 53  99 9c 3f 30 2b 80 7e c9  |]..r..5S..?0+.~.|
-00000300  79 eb d8 97 3c 82 ff 37  a5 8d 36 bc 27 c1 51 58  |y...<..7..6.'.QX|
-00000310  e6 2a 48 05 bf 9b a4 a5  b1 7f 77 b8 d9 3e 37 c6  |.*H.......w..>7.|
-00000320  67 ad ef 8c 72 ea f6 ba  bb af 00 16 03 01 00 0a  |g...r...........|
+00000270  2a 16 03 01 00 b5 0c 00  00 b1 03 00 1d 20 f0 8c  |*............ ..|
+00000280  cd 6a c2 7a ea f0 2b 4a  34 6d a9 3b 7a 29 5d 04  |.j.z..+J4m.;z)].|
+00000290  65 70 97 30 e7 10 6e c2  7e 50 c5 89 4a 3f 00 8b  |ep.0..n.~P..J?..|
+000002a0  30 81 88 02 42 00 be e2  67 30 f0 8a cb 63 6c 13  |0...B...g0...cl.|
+000002b0  e0 4e 88 52 6e bc e4 83  53 f4 18 75 b7 46 a5 46  |.N.Rn...S..u.F.F|
+000002c0  11 f1 4b f9 bd 58 4e 62  5c fb a8 f2 93 99 3c 94  |..K..XNb\.....<.|
+000002d0  18 1d 7a f1 74 bf 9d c6  fe 65 b1 bc 54 2b c7 ba  |..z.t....e..T+..|
+000002e0  f7 45 a8 0a 21 ad 23 02  42 01 c8 fd 48 62 e2 5e  |.E..!.#.B...Hb.^|
+000002f0  f1 9c 95 c0 28 c4 c5 04  31 e5 ba a5 3c 09 d9 d7  |....(...1...<...|
+00000300  43 aa 8c 35 26 ed 47 57  6d c6 15 86 50 3c 72 e1  |C..5&.GWm...P<r.|
+00000310  6f 2b 85 63 97 5e 20 58  fc cf 0c f9 37 27 42 fb  |o+.c.^ X....7'B.|
+00000320  cd ed c3 40 ac 5f d9 06  5c a3 27 16 03 01 00 0a  |...@._..\.'.....|
 00000330  0d 00 00 06 03 01 02 40  00 00 16 03 01 00 04 0e  |.......@........|
 00000340  00 00 00                                          |...|
 >>> Flow 3 (client to server)
@@ -106,29 +106,29 @@
 00000210  03 01 00 25 10 00 00 21  20 2f e5 7d a3 47 cd 62  |...%...! /.}.G.b|
 00000220  43 15 28 da ac 5f bb 29  07 30 ff f6 84 af c4 cf  |C.(.._.).0......|
 00000230  c2 ed 90 99 5f 58 cb 3b  74 16 03 01 00 91 0f 00  |...._X.;t.......|
-00000240  00 8d 00 8b 30 81 88 02  42 01 f0 c3 b2 6e e2 a3  |....0...B....n..|
-00000250  cd 76 02 7a d5 b5 66 fa  b6 66 4e 4b a0 17 d6 bd  |.v.z..f..fNK....|
-00000260  ec f6 8c 1f f9 b4 32 18  a9 ba 66 a8 67 a4 fa c8  |......2...f.g...|
-00000270  f7 73 5f 22 fb f2 22 e2  4d a1 f6 30 a2 55 76 51  |.s_"..".M..0.UvQ|
-00000280  b7 61 7d 13 68 0a 89 9d  34 31 46 02 42 01 fa 8b  |.a}.h...41F.B...|
-00000290  61 f6 91 8e 88 ca 84 e6  33 e0 da 92 7e ee 21 1c  |a.......3...~.!.|
-000002a0  df 47 c2 5d 07 d8 ae 1b  04 58 f9 50 16 13 74 ea  |.G.].....X.P..t.|
-000002b0  04 cc 18 2d 2b 9a 08 89  24 e8 b8 01 bb c6 84 6c  |...-+...$......l|
-000002c0  e6 9a c6 8a 44 74 1c 3a  79 0c e9 3c 11 ba 1b 14  |....Dt.:y..<....|
-000002d0  03 01 00 01 01 16 03 01  00 30 1d 4b df 00 de 1c  |.........0.K....|
-000002e0  b5 30 7b ea 64 a0 09 89  8c c5 be fc 9b 07 7e 45  |.0{.d.........~E|
-000002f0  27 00 e7 78 da 3e a3 04  97 87 b0 c2 17 32 01 91  |'..x.>.......2..|
-00000300  6e 66 7b dd 9e 28 bc cc  66 65                    |nf{..(..fe|
+00000240  00 8d 00 8b 30 81 88 02  42 01 4c 44 9a a6 7e 6e  |....0...B.LD..~n|
+00000250  8a f0 40 c0 63 cf 50 4d  1c 36 55 c2 ae 89 19 5a  |[email protected]|
+00000260  3f ef 2b 2e 0d 66 4f fe  c2 cb 17 86 7c a1 2c e9  |?.+..fO.....|.,.|
+00000270  d8 44 b6 45 36 cc 3a 29  74 19 3c 98 c1 f6 8f 9c  |.D.E6.:)t.<.....|
+00000280  bb 29 fa ae d5 73 de c8  b3 27 7f 02 42 01 86 c9  |.)...s...'..B...|
+00000290  9d e6 1d 45 8b 35 7d ee  7d de ce 4b 15 40 1e 26  |...E.5}.}..K.@.&|
+000002a0  95 eb 8e b2 6d ac a3 52  b3 fe bc 9d 2b 61 1a 41  |....m..R....+a.A|
+000002b0  5c b5 e5 c0 df 3f 5b 84  4b d6 b2 c5 3a 15 05 0d  |\....?[.K...:...|
+000002c0  3f 0a 6e d7 8d 49 35 50  67 3e 6e c5 a7 ba 84 14  |?.n..I5Pg>n.....|
+000002d0  03 01 00 01 01 16 03 01  00 30 91 e2 f5 b4 fc 0d  |.........0......|
+000002e0  43 92 f1 18 99 68 d8 4d  94 ab e0 87 60 e5 46 e3  |C....h.M....`.F.|
+000002f0  dd b8 0c b5 c6 5b 73 ba  ae e7 7f 0c 6d 6d 94 e7  |.....[s.....mm..|
+00000300  e2 21 c5 5c 0e b9 e6 c7  88 92                    |.!.\......|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 30 51 68 ca 97 63  |..........0Qh..c|
-00000010  c6 c0 24 1c 87 20 70 ac  f7 47 16 45 44 17 cc 92  |..$.. p..G.ED...|
-00000020  b3 6d 8b fa d1 3c b8 10  d7 da e4 a7 35 3c a2 d0  |.m...<......5<..|
-00000030  da 4b 50 e4 89 94 4b bc  20 6b e3                 |.KP...K. k.|
+00000000  14 03 01 00 01 01 16 03  01 00 30 24 93 c5 b1 d0  |..........0$....|
+00000010  bf 5e 5c 79 18 91 d4 c2  5d 82 bd b9 77 44 a8 75  |.^\y....]...wD.u|
+00000020  2a aa 22 c1 71 79 4c ad  7f 95 1f 94 b7 2b 5d cb  |*.".qyL......+].|
+00000030  85 57 0a 7e 55 f1 56 4b  98 da b8                 |.W.~U.VK...|
 >>> Flow 5 (client to server)
-00000000  17 03 01 00 20 fc fa 90  90 d0 51 0d 35 0f 6a 6d  |.... .....Q.5.jm|
-00000010  c2 32 ec 92 46 9f d7 e9  66 37 02 2a f6 c6 2e e2  |.2..F...f7.*....|
-00000020  13 aa fa fa d3 17 03 01  00 20 45 a9 36 19 7d a8  |......... E.6.}.|
-00000030  44 4c 8b aa 4e 47 c8 79  0c 97 a5 20 fa 6f 1f f7  |DL..NG.y... .o..|
-00000040  d3 bc d7 6d c2 67 23 c8  d6 05 15 03 01 00 20 f1  |...m.g#....... .|
-00000050  f1 ed f9 fc c2 f6 61 c8  42 9d c9 8a b0 d0 de d3  |......a.B.......|
-00000060  42 c7 04 64 eb 9e eb 58  3b c3 7d 0d 4d 16 d4     |B..d...X;.}.M..|
+00000000  17 03 01 00 20 21 19 00  1b 74 03 79 83 6a cf 87  |.... !...t.y.j..|
+00000010  c5 1f c6 e6 ff 1c 8d 9e  a9 2b 3c 7e e5 e0 d5 b5  |.........+<~....|
+00000020  c0 d5 1a 84 45 17 03 01  00 20 77 40 7e ac d0 9e  |....E.... w@~...|
+00000030  d1 86 73 26 d2 c6 a0 a4  94 9e d7 7e 28 59 5c b2  |..s&.......~(Y\.|
+00000040  9f 4d fa c5 c9 b7 a2 b2  b1 7b 15 03 01 00 20 59  |.M.......{.... Y|
+00000050  aa 2f 3f 2c 20 f1 15 ef  24 95 29 66 c0 48 78 00  |./?, ...$.)f.Hx.|
+00000060  19 d6 1e 95 af 83 03 6e  d8 c7 8e bb c3 54 02     |.......n.....T.|
diff --git a/src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-RSA b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-RSA
index 81e5191..afe6e10 100644
--- a/src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-RSA
+++ b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-RSA
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 01 00 59 02 00 00  55 03 01 ca 72 6a a1 69  |....Y...U...rj.i|
-00000010  18 a4 f8 76 4a c3 5c e8  d5 c1 fb 06 c6 9a 14 67  |...vJ.\........g|
-00000020  ce e4 f6 52 67 ab 64 48  28 5a 63 20 55 ea ff 87  |...Rg.dH(Zc U...|
-00000030  5a 78 5c cb 21 af 83 a5  ed 1b d3 2c 39 81 e5 ca  |Zx\.!......,9...|
-00000040  63 d2 5c 57 27 1d d0 f9  41 40 43 b0 c0 13 00 00  |c.\W'...A@C.....|
+00000000  16 03 01 00 59 02 00 00  55 03 01 b5 1a 96 ea d5  |....Y...U.......|
+00000010  01 ef fb 42 1d 49 e1 1b  7c e4 15 ec cc 7f b9 fc  |...B.I..|.......|
+00000020  22 e0 0b 1d 66 0e c8 d6  9b cd ec 20 d5 2b fe 9a  |"...f...... .+..|
+00000030  f7 e7 10 1c c4 15 10 f1  24 8d 8f f6 25 90 aa 1c  |........$...%...|
+00000040  10 c4 87 c6 36 23 5b 6a  c1 ae 20 5e c0 13 00 00  |....6#[j.. ^....|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  01 02 59 0b 00 02 55 00  02 52 00 02 4f 30 82 02  |..Y...U..R..O0..|
 00000070  4b 30 82 01 b4 a0 03 02  01 02 02 09 00 e8 f0 9d  |K0..............|
@@ -60,17 +60,17 @@
 00000290  77 8d 0c 1c f1 0f a1 d8  40 83 61 c9 4c 72 2b 9d  |[email protected]+.|
 000002a0  ae db 46 06 06 4d f4 c1  b3 3e c0 d1 bd 42 d4 db  |..F..M...>...B..|
 000002b0  fe 3d 13 60 84 5c 21 d3  3b e9 fa e7 16 03 01 00  |.=.`.\!.;.......|
-000002c0  aa 0c 00 00 a6 03 00 1d  20 e8 a5 9c e4 73 3d 75  |........ ....s=u|
-000002d0  0c 3e f2 de 21 9c 0f 91  b4 fd 94 f0 27 f6 d9 7d  |.>..!.......'..}|
-000002e0  cd 0c 4c 50 b0 47 db dd  12 00 80 04 c0 be d5 bb  |..LP.G..........|
-000002f0  e8 e2 a2 2e d9 2e 75 fa  b6 07 d0 f7 75 52 fb 2f  |......u.....uR./|
-00000300  50 cd 43 68 bd 42 11 6d  d6 9f a3 d1 00 fd a9 14  |P.Ch.B.m........|
-00000310  0c 2a dd 76 ea 73 21 52  00 3a 83 cf d7 07 c7 bd  |.*.v.s!R.:......|
-00000320  78 21 ce 35 80 b3 06 22  f1 96 a7 20 41 f8 aa 61  |x!.5..."... A..a|
-00000330  94 b4 77 d4 d9 92 f2 66  c5 1c d1 82 f3 b9 e2 9d  |..w....f........|
-00000340  a9 30 1c e2 4e ec 0d 32  3d 0d 61 22 c8 e5 95 9f  |.0..N..2=.a"....|
-00000350  cf 3e fc a8 c5 c3 f8 45  45 29 ea a7 e7 b7 a6 17  |.>.....EE)......|
-00000360  9e 5f 83 d4 b3 f0 da 31  73 94 f2 16 03 01 00 0a  |._.....1s.......|
+000002c0  aa 0c 00 00 a6 03 00 1d  20 87 d5 d1 27 70 92 d9  |........ ...'p..|
+000002d0  15 56 e4 fd a8 52 a9 a5  f6 db ab f5 e2 61 fa 5d  |.V...R.......a.]|
+000002e0  64 ba c2 ee 37 0b 53 cf  3c 00 80 71 cd eb 4b 1c  |d...7.S.<..q..K.|
+000002f0  f7 84 85 6a 20 5c c8 40  59 1c b0 8e 1b b6 b6 19  |...j \.@Y.......|
+00000300  f1 66 ad 7d 1d d5 58 da  c3 c4 dd 12 57 04 05 0d  |.f.}..X.....W...|
+00000310  79 46 20 0b 8c a3 49 95  e0 96 22 75 56 44 21 6b  |yF ...I..."uVD!k|
+00000320  42 17 ed 32 eb 9c f3 fd  b0 b3 08 da 61 7e f3 9b  |B..2........a~..|
+00000330  43 51 c0 09 e3 53 17 5d  84 3f c4 52 db 73 f9 d1  |CQ...S.].?.R.s..|
+00000340  21 0e 55 a4 bc a1 1b b6  3a 5a d1 cb 15 7e 8b a4  |!.U.....:Z...~..|
+00000350  fb 0f e7 7e 36 a7 1b a4  c0 1f 79 37 49 17 84 d3  |...~6.....y7I...|
+00000360  97 39 78 1f 55 77 e8 aa  37 2a 36 16 03 01 00 0a  |.9x.Uw..7*6.....|
 00000370  0d 00 00 06 03 01 02 40  00 00 16 03 01 00 04 0e  |.......@........|
 00000380  00 00 00                                          |...|
 >>> Flow 3 (client to server)
@@ -110,29 +110,29 @@
 00000210  03 01 00 25 10 00 00 21  20 2f e5 7d a3 47 cd 62  |...%...! /.}.G.b|
 00000220  43 15 28 da ac 5f bb 29  07 30 ff f6 84 af c4 cf  |C.(.._.).0......|
 00000230  c2 ed 90 99 5f 58 cb 3b  74 16 03 01 00 91 0f 00  |...._X.;t.......|
-00000240  00 8d 00 8b 30 81 88 02  42 00 9a b9 f6 98 e3 ed  |....0...B.......|
-00000250  ed 0d a3 0e 54 51 9f 73  d4 87 40 4e a9 39 4b 2d  |[email protected]|
-00000260  2a b9 4d 8d e3 46 c3 b6  39 f2 ca a9 c9 0f 79 c1  |*.M..F..9.....y.|
-00000270  0c 90 6f de 58 97 72 fc  a8 c1 4c 12 aa a4 85 57  |..o.X.r...L....W|
-00000280  50 7c a0 02 8a 12 c5 80  aa b6 39 02 42 00 9c b7  |P|........9.B...|
-00000290  95 b4 04 83 5b 3a e1 ac  da 78 86 11 f5 30 75 4a  |....[:...x...0uJ|
-000002a0  25 67 6c fd ef 5a d8 56  d3 60 93 cf 65 07 2b 1f  |%gl..Z.V.`..e.+.|
-000002b0  a9 40 a8 ba cd 0e 41 2d  10 43 a4 61 93 b7 0a 11  |[email protected]....|
-000002c0  78 d1 72 2b 20 07 49 5a  76 02 17 57 87 78 c7 14  |x.r+ .IZv..W.x..|
-000002d0  03 01 00 01 01 16 03 01  00 30 93 de 1b 64 0e 56  |.........0...d.V|
-000002e0  d9 a8 da f7 37 cb ac ac  3e f5 e2 f9 87 19 f2 79  |....7...>......y|
-000002f0  24 76 19 a4 a2 41 d6 9e  7d ca aa 3e 1d d7 22 dd  |$v...A..}..>..".|
-00000300  05 aa dd 74 03 db fd a2  de ee                    |...t......|
+00000240  00 8d 00 8b 30 81 88 02  42 01 e7 32 ab 5d d7 f8  |....0...B..2.]..|
+00000250  b6 25 f9 b6 e6 19 eb 20  75 99 90 bc 41 06 74 ce  |.%..... u...A.t.|
+00000260  92 31 fc 9e cd f3 b4 b1  b1 f7 1e d3 3c 5e 01 92  |.1..........<^..|
+00000270  a0 c6 24 05 6e 3b ba 6c  51 61 6c 11 fd fe d7 9f  |..$.n;.lQal.....|
+00000280  0b 16 b3 1a f7 20 fa b2  3d 92 c9 02 42 01 d7 dc  |..... ..=...B...|
+00000290  20 50 f6 91 a3 63 2a 79  37 d4 8b 71 0a 1e 73 f8  | P...c*y7..q..s.|
+000002a0  1e 1c 04 c5 c8 66 bc 5e  67 5e bb 94 76 87 23 12  |.....f.^g^..v.#.|
+000002b0  64 18 cb 09 66 58 f1 06  17 93 1e b9 83 67 9d 3d  |d...fX.......g.=|
+000002c0  39 0a fb 37 7b a9 bf d2  59 1a 49 0f 4c 10 df 14  |9..7{...Y.I.L...|
+000002d0  03 01 00 01 01 16 03 01  00 30 4f 0e ba fc 20 81  |.........0O... .|
+000002e0  73 58 e0 47 33 b9 5e c4  6a 10 c2 1a 42 c3 85 2b  |sX.G3.^.j...B..+|
+000002f0  20 38 80 5d 40 81 4a 78  40 d9 13 ac af b3 45 e7  | 8.]@[email protected].|
+00000300  1e 19 c6 b5 63 6e 9c 5c  8a 8d                    |....cn.\..|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 30 4d 4f d6 67 05  |..........0MO.g.|
-00000010  32 8c 16 cb 19 35 b3 b9  02 d8 5e 24 b6 c8 b7 3a  |2....5....^$...:|
-00000020  17 34 98 77 e1 73 e0 cd  a9 30 a8 15 60 8c f4 9a  |.4.w.s...0..`...|
-00000030  dc cf 7a fd 86 85 1c 2b  33 21 e8                 |..z....+3!.|
+00000000  14 03 01 00 01 01 16 03  01 00 30 c6 bb 74 56 db  |..........0..tV.|
+00000010  fd f7 a7 dd 3b a3 50 10  11 44 83 a1 c6 b1 6e 70  |....;.P..D....np|
+00000020  37 6e 68 b2 5a 45 6b fb  e9 9d 4e 68 cf ba ea af  |7nh.ZEk...Nh....|
+00000030  7d f6 65 ee 22 14 9e 5a  a7 85 65                 |}.e."..Z..e|
 >>> Flow 5 (client to server)
-00000000  17 03 01 00 20 b8 c5 17  b7 92 d8 93 7a b2 fd 4f  |.... .......z..O|
-00000010  15 d1 db b9 47 54 00 a0  f6 77 92 03 a8 89 e5 ba  |....GT...w......|
-00000020  cc eb d9 bd 27 17 03 01  00 20 57 d5 9a f6 36 b2  |....'.... W...6.|
-00000030  57 ba cd 64 77 36 b9 74  fb bd 95 51 03 61 e8 45  |W..dw6.t...Q.a.E|
-00000040  cb b8 35 f0 05 17 b3 08  c6 cb 15 03 01 00 20 28  |..5........... (|
-00000050  43 03 ab 3f e2 f5 d0 33  4c 7f 50 a4 ee 7b 46 e6  |C..?...3L.P..{F.|
-00000060  12 76 d0 fd c3 99 5c 63  a4 04 ea 4b e3 bd 99     |.v....\c...K...|
+00000000  17 03 01 00 20 c7 78 67  68 03 48 2e a5 c3 7a 0a  |.... .xgh.H...z.|
+00000010  56 73 14 02 12 f7 26 ac  48 19 3e e6 4b 0f ac d0  |Vs....&.H.>.K...|
+00000020  4e 74 dc 66 68 17 03 01  00 20 bf db fb e7 85 35  |Nt.fh.... .....5|
+00000030  50 4d 39 3f ab 25 95 30  4c 7a 20 d8 89 db 74 ff  |PM9?.%.0Lz ...t.|
+00000040  e6 e1 05 30 98 17 f3 93  8a 0d 15 03 01 00 20 f9  |...0.......... .|
+00000050  33 18 32 46 d3 28 46 a4  06 8c e1 9b 9b 1d d1 d8  |3.2F.(F.........|
+00000060  7b 9f 6c ad 5d 2a 36 10  2c dd f8 30 23 54 ac     |{.l.]*6.,..0#T.|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-ECDSA b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-ECDSA
index e1fb8a8..4b5a4ca 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-ECDSA
+++ b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-ECDSA
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 36 60 84 12 26  |....Y...U..6`..&|
-00000010  51 e4 32 33 26 ef c3 31  bf ea ac 27 0f c3 fb cb  |Q.23&..1...'....|
-00000020  05 89 af df 56 a9 3f 14  6e 5e 2c 20 ad 6e 60 2d  |....V.?.n^, .n`-|
-00000030  94 aa e5 73 22 eb 68 92  77 1c 6c cb f4 5a 14 f2  |...s".h.w.l..Z..|
-00000040  29 85 88 aa 2e 56 2a ad  80 e1 f0 b1 c0 09 00 00  |)....V*.........|
+00000000  16 03 03 00 59 02 00 00  55 03 03 8f fe 05 df f3  |....Y...U.......|
+00000010  02 70 ec 72 c4 3d 1e 52  c3 63 b8 1d dc e0 36 72  |.p.r.=.R.c....6r|
+00000020  8b 04 94 a5 45 fb 97 a5  0b e1 a7 20 9d fb e5 2b  |....E...... ...+|
+00000030  77 d7 1b da e8 d7 3e fe  c5 8f 4e b6 5a 40 29 02  |w.....>...N.Z@).|
+00000040  fd 08 46 4e 27 24 53 e1  de 88 8a 77 c0 09 00 00  |..FN'$S....w....|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 0e 0b 00 02 0a 00  02 07 00 02 04 30 82 02  |.............0..|
 00000070  00 30 82 01 62 02 09 00  b8 bf 2d 47 a0 d2 eb f4  |.0..b.....-G....|
@@ -55,18 +55,18 @@
 00000240  13 83 0d 94 06 bb d4 37  7a f6 ec 7a c9 86 2e dd  |.......7z..z....|
 00000250  d7 11 69 7f 85 7c 56 de  fb 31 78 2b e4 c7 78 0d  |..i..|V..1x+..x.|
 00000260  ae cb be 9e 4e 36 24 31  7b 6a 0f 39 95 12 07 8f  |....N6$1{j.9....|
-00000270  2a 16 03 03 00 b7 0c 00  00 b3 03 00 1d 20 87 2c  |*............ .,|
-00000280  f2 fd 8e b9 3d 5f 1c c8  bb 04 f5 1e 01 a8 ba d8  |....=_..........|
-00000290  b6 8e 61 78 15 9e 3b a7  da 96 8e 77 d7 70 04 03  |..ax..;....w.p..|
-000002a0  00 8b 30 81 88 02 42 01  dc e2 26 f9 18 39 da 7d  |..0...B...&..9.}|
-000002b0  bd a1 30 c6 6f dd cd aa  a0 4f 71 cf 42 76 61 ba  |..0.o....Oq.Bva.|
-000002c0  e7 9f 09 b5 05 f2 76 c7  db 2a 93 83 3b 0b 3a cf  |......v..*..;.:.|
-000002d0  60 96 24 c8 af de 2c db  5a 29 1c 62 67 28 e9 d7  |`.$...,.Z).bg(..|
-000002e0  57 5f 54 18 cc bf ee d1  d9 02 42 01 04 cf 67 0b  |W_T.......B...g.|
-000002f0  62 2c c2 17 a3 f4 f1 32  0f c5 b9 ae 3b 52 36 2b  |b,.....2....;R6+|
-00000300  f0 c0 60 49 08 e0 bf f5  7c 09 13 e4 b8 ba 08 c7  |..`I....|.......|
-00000310  ea 74 a0 f5 88 45 e4 35  f1 c5 4e df fe 45 bc ca  |.t...E.5..N..E..|
-00000320  9c 5f c8 84 66 13 8f b3  c9 7e b2 ba d6 16 03 03  |._..f....~......|
+00000270  2a 16 03 03 00 b7 0c 00  00 b3 03 00 1d 20 82 a8  |*............ ..|
+00000280  4b 0e 10 e1 2b a2 f6 9d  11 0a 4d 0b c0 2f 12 85  |K...+.....M../..|
+00000290  bc f3 e9 9f b4 50 50 fa  b1 a9 fd 35 d1 39 04 03  |.....PP....5.9..|
+000002a0  00 8b 30 81 88 02 42 01  b1 cb c7 7a 83 6a 95 5b  |..0...B....z.j.[|
+000002b0  09 4c 59 d6 9a 6b 9d 0c  e9 f5 22 1c 46 76 5b 4e  |.LY..k....".Fv[N|
+000002c0  3c 4a ac 81 b7 96 29 7c  e2 e8 08 e7 5f be 9d dc  |<J....)|...._...|
+000002d0  8d 9e 1d a1 84 4c 18 1a  8a 2d bd 97 de 26 70 14  |.....L...-...&p.|
+000002e0  11 74 49 4b e9 2e 59 30  9c 02 42 00 b5 9e 89 32  |.tIK..Y0..B....2|
+000002f0  45 02 71 19 6e 83 fc 26  26 b4 28 08 6a 7d d3 72  |E.q.n..&&.(.j}.r|
+00000300  4e ed 82 68 2f ad ff 39  5a ce 34 b8 e4 39 f2 f1  |N..h/..9Z.4..9..|
+00000310  60 5d 84 c4 da 4d 5a 33  f8 20 5a f2 7f aa 7e 18  |`]...MZ3. Z...~.|
+00000320  14 14 2a 68 a8 9d dd d0  ec e3 00 87 49 16 03 03  |..*h........I...|
 00000330  00 3a 0d 00 00 36 03 01  02 40 00 2e 04 03 05 03  |.:...6...@......|
 00000340  06 03 08 07 08 08 08 09  08 0a 08 0b 08 04 08 05  |................|
 00000350  08 06 04 01 05 01 06 01  03 03 02 03 03 01 02 01  |................|
@@ -108,32 +108,32 @@
 00000200  e4 fa cc b1 8a ce e2 23  a0 87 f0 e1 67 51 eb 16  |.......#....gQ..|
 00000210  03 03 00 25 10 00 00 21  20 2f e5 7d a3 47 cd 62  |...%...! /.}.G.b|
 00000220  43 15 28 da ac 5f bb 29  07 30 ff f6 84 af c4 cf  |C.(.._.).0......|
-00000230  c2 ed 90 99 5f 58 cb 3b  74 16 03 03 00 92 0f 00  |...._X.;t.......|
-00000240  00 8e 04 03 00 8a 30 81  87 02 42 01 8f ff aa 8c  |......0...B.....|
-00000250  bd 0c 94 39 34 e5 39 7b  d2 12 26 8e 94 4a fd 68  |...94.9{..&..J.h|
-00000260  f2 f5 5b 30 69 e1 42 3a  74 cd 9a 37 75 5c d2 a6  |..[0i.B:t..7u\..|
-00000270  c9 7b b1 83 c1 d9 c5 55  1a af 3d 19 64 02 43 c0  |.{.....U..=.d.C.|
-00000280  0a 1c 0e ff f4 42 85 fb  d1 aa a2 52 1a 02 41 2f  |.....B.....R..A/|
-00000290  c6 23 d7 37 f1 36 75 0c  0f b4 49 14 c4 b4 d9 28  |.#.7.6u...I....(|
-000002a0  c1 00 2d e4 d6 93 fd a0  f5 59 4e 45 0c a4 28 d4  |..-......YNE..(.|
-000002b0  dc aa 7b 0b 28 29 12 94  f6 db 8c 23 af 81 7e ab  |..{.().....#..~.|
-000002c0  fd 12 ba 11 27 b2 10 87  89 61 9f 5d 6d 18 79 c5  |....'....a.]m.y.|
-000002d0  14 03 03 00 01 01 16 03  03 00 40 00 00 00 00 00  |..........@.....|
-000002e0  00 00 00 00 00 00 00 00  00 00 00 2d 3e 6e 02 fb  |...........->n..|
-000002f0  50 cc 37 62 77 17 08 ef  71 e6 06 23 82 ba 97 b7  |P.7bw...q..#....|
-00000300  0f 38 f9 5e 05 63 4c c9  04 6e bd e4 78 76 32 3b  |.8.^.cL..n..xv2;|
-00000310  3a a7 9b de 30 ca ed fb  17 dc 40                 |:...0.....@|
+00000230  c2 ed 90 99 5f 58 cb 3b  74 16 03 03 00 93 0f 00  |...._X.;t.......|
+00000240  00 8f 04 03 00 8b 30 81  88 02 42 01 cd 6b 44 a0  |......0...B..kD.|
+00000250  80 3b f5 5d f0 99 24 dd  89 94 b9 96 34 e7 04 e7  |.;.]..$.....4...|
+00000260  38 72 64 36 5a e9 ac bc  e3 54 1b 75 69 e2 de 03  |8rd6Z....T.ui...|
+00000270  ce a9 2c 76 92 dd 6b 31  0a 93 10 57 69 8b e0 cf  |..,v..k1...Wi...|
+00000280  7d 75 e4 e1 a9 d2 d3 29  b6 a7 ff 86 d4 02 42 01  |}u.....)......B.|
+00000290  e4 d9 31 56 23 62 e6 c2  2d 57 8a 6f d3 3f 1f 4d  |..1V#b..-W.o.?.M|
+000002a0  ca 0e c0 60 53 55 1f fb  56 24 22 82 c0 fe d9 0b  |...`SU..V$".....|
+000002b0  9b de fb f2 d4 a6 e4 98  9f 2c 07 07 01 83 ab 93  |.........,......|
+000002c0  3e c6 02 41 e9 8b 8d 95  eb cf b9 0f b5 fb 2c 9f  |>..A..........,.|
+000002d0  90 14 03 03 00 01 01 16  03 03 00 40 00 00 00 00  |...........@....|
+000002e0  00 00 00 00 00 00 00 00  00 00 00 00 aa 12 12 09  |................|
+000002f0  c5 08 94 28 8d 59 f3 68  cc 02 69 47 fa cf 9c 81  |...(.Y.h..iG....|
+00000300  a6 a5 b5 c7 e7 26 45 4a  59 67 ca 0a ed 6c 58 38  |.....&EJYg...lX8|
+00000310  23 12 48 a9 3c 0c 26 00  78 58 db 21              |#.H.<.&.xX.!|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 40 19 62 a8 82 26  |[email protected]..&|
-00000010  0f 0c 84 b4 31 6a 5d 12  65 dc b9 bc de 5c cb 77  |....1j].e....\.w|
-00000020  5d 04 7e a8 10 1a a5 05  e5 ca 04 68 a2 81 ef f5  |].~........h....|
-00000030  ae 4e bd f1 f3 ba 3f 6a  81 ae 71 9a 2f 31 e2 79  |.N....?j..q./1.y|
-00000040  f1 4d 6c 0e a4 be 4b f7  80 6f 97                 |.Ml...K..o.|
+00000000  14 03 03 00 01 01 16 03  03 00 40 5a 63 b1 0f 47  |[email protected]|
+00000010  76 ac c4 69 62 82 63 77  8b 26 7b a9 8a 7d 3d fe  |v..ib.cw.&{..}=.|
+00000020  4a 04 b4 80 17 cc be 5e  9e b2 5d a3 2d 48 85 44  |J......^..].-H.D|
+00000030  7d db 62 77 31 27 18 b1  55 61 b3 64 6c d6 39 f7  |}.bw1'..Ua.dl.9.|
+00000040  f2 fe 7c 73 c8 3f 31 c9  78 83 8c                 |..|s.?1.x..|
 >>> Flow 5 (client to server)
 00000000  17 03 03 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-00000010  00 00 00 00 00 e9 f4 51  fe c1 02 35 de 6e 72 c3  |.......Q...5.nr.|
-00000020  58 f3 01 4a f0 9d f2 34  df fc 0e 93 ef 46 2e 45  |X..J...4.....F.E|
-00000030  5e 60 43 52 33 15 03 03  00 30 00 00 00 00 00 00  |^`CR3....0......|
-00000040  00 00 00 00 00 00 00 00  00 00 ac 82 d6 47 42 40  |.............GB@|
-00000050  d6 6c 6d e3 b6 c6 4a b7  83 ce 6f 3f 33 ad e7 eb  |.lm...J...o?3...|
-00000060  bf 59 82 50 8a 18 e3 13  46 6c                    |.Y.P....Fl|
+00000010  00 00 00 00 00 b9 a3 b6  37 76 c9 69 20 8d 97 e3  |........7v.i ...|
+00000020  0d f1 6e d4 6d 79 0b 64  4f a5 0d 30 ff 1c cd 56  |..n.my.dO..0...V|
+00000030  e7 ce 69 a6 48 15 03 03  00 30 00 00 00 00 00 00  |..i.H....0......|
+00000040  00 00 00 00 00 00 00 00  00 00 c6 3c 3b f2 09 05  |...........<;...|
+00000050  2c 4d 07 4f 95 34 29 ec  ef 3b b5 31 c6 a4 91 5e  |,M.O.4)..;.1...^|
+00000060  14 20 5b c5 34 19 f9 1d  22 63                    |. [.4..."c|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-RSA b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-RSA
index 7ae186d..36bddc2 100644
--- a/src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-RSA
+++ b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-RSA
@@ -16,11 +16,11 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 59 02 00 00  55 03 03 2a 52 95 57 8c  |....Y...U..*R.W.|
-00000010  55 3f d7 82 f0 3f af 57  a1 82 86 00 3a 6b c0 07  |U?...?.W....:k..|
-00000020  4d c3 0e 80 cc 37 2d 51  f4 d3 e2 20 4a f6 c9 8a  |M....7-Q... J...|
-00000030  d2 98 4a ff 22 66 11 da  6f 9a a0 17 b9 96 b0 86  |..J."f..o.......|
-00000040  29 e0 39 86 0a 00 42 78  30 60 61 99 c0 2f 00 00  |).9...Bx0`a../..|
+00000000  16 03 03 00 59 02 00 00  55 03 03 b8 f6 b1 71 c5  |....Y...U.....q.|
+00000010  d0 3f 36 fb 8a b9 15 35  ae c5 08 8e eb c6 d5 ad  |.?6....5........|
+00000020  a1 8a ff 65 2e 78 f5 2a  2b cb f7 20 26 1e c1 94  |...e.x.*+.. &...|
+00000030  85 a9 b1 ca 8d 5f 3f 00  6a 44 c9 ed 28 36 97 f2  |....._?.jD..(6..|
+00000040  7d 38 0a 56 75 a2 12 ac  34 ed 7e 14 c0 2f 00 00  |}8.Vu...4.~../..|
 00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
 00000060  03 02 59 0b 00 02 55 00  02 52 00 02 4f 30 82 02  |..Y...U..R..O0..|
 00000070  4b 30 82 01 b4 a0 03 02  01 02 02 09 00 e8 f0 9d  |K0..............|
@@ -60,17 +60,17 @@
 00000290  77 8d 0c 1c f1 0f a1 d8  40 83 61 c9 4c 72 2b 9d  |[email protected]+.|
 000002a0  ae db 46 06 06 4d f4 c1  b3 3e c0 d1 bd 42 d4 db  |..F..M...>...B..|
 000002b0  fe 3d 13 60 84 5c 21 d3  3b e9 fa e7 16 03 03 00  |.=.`.\!.;.......|
-000002c0  ac 0c 00 00 a8 03 00 1d  20 fa 3a 8f b7 50 10 38  |........ .:..P.8|
-000002d0  04 9d fb c4 e4 76 6d 93  86 b2 8a d7 5b 8f 8d 45  |.....vm.....[..E|
-000002e0  41 b7 ba 54 bc cc 7b 07  3c 08 04 00 80 a1 14 65  |A..T..{.<......e|
-000002f0  f6 48 29 ba 08 86 52 65  dd 08 ef b8 b8 77 ef fd  |.H)...Re.....w..|
-00000300  8a ca dc 37 f8 69 fa 04  69 73 84 07 b2 45 f0 a2  |...7.i..is...E..|
-00000310  8c 69 f7 7c 4c 5c 95 c5  66 80 ad 93 04 67 4b 3d  |.i.|L\..f....gK=|
-00000320  f8 53 a9 33 b3 c0 40 17  62 34 f0 f3 1e d2 23 93  |[email protected]....#.|
-00000330  29 52 bc f4 f0 72 58 b9  76 9c 7b 54 b0 d5 d1 ab  |)R...rX.v.{T....|
-00000340  b3 1b ae f7 f3 46 6a 07  7f f4 91 ee 46 d6 85 43  |.....Fj.....F..C|
-00000350  ea c6 f9 f5 47 89 85 39  72 35 af b4 03 e9 a2 ea  |....G..9r5......|
-00000360  a8 19 09 ea b3 d2 c2 38  59 65 d1 2c 18 16 03 03  |.......8Ye.,....|
+000002c0  ac 0c 00 00 a8 03 00 1d  20 9d 82 84 ba 8e 4b 7e  |........ .....K~|
+000002d0  bc f4 8e ab c1 31 68 42  cb 36 1d 64 60 55 74 11  |.....1hB.6.d`Ut.|
+000002e0  cf 63 d2 f4 c9 e7 a9 bf  7b 08 04 00 80 ce b2 06  |.c......{.......|
+000002f0  a3 54 1e fd f7 c4 a6 54  40 ea 74 8c e0 de ec aa  |[email protected].....|
+00000300  30 66 c3 e4 a9 7f 86 cc  f7 34 6b 55 a4 97 fd 6e  |0f.......4kU...n|
+00000310  3b 1f c4 e9 17 3c 6d 94  66 78 e0 1a ab 41 64 9b  |;....<m.fx...Ad.|
+00000320  2b 2e 14 99 96 68 aa ef  97 65 ea e7 72 28 9c 0f  |+....h...e..r(..|
+00000330  f9 11 57 b7 1f 31 54 87  1a 36 45 ec c1 0f 72 53  |..W..1T..6E...rS|
+00000340  56 a1 8d e4 d0 93 3e bb  77 8a 32 bd fb 07 0b ce  |V.....>.w.2.....|
+00000350  82 d3 a1 ab 6f 80 ac ac  4e da b7 7f 84 fe 3f 26  |....o...N.....?&|
+00000360  f4 d9 b9 b6 2b 68 1a cc  ef 31 97 22 bf 16 03 03  |....+h...1."....|
 00000370  00 3a 0d 00 00 36 03 01  02 40 00 2e 04 03 05 03  |.:...6...@......|
 00000380  06 03 08 07 08 08 08 09  08 0a 08 0b 08 04 08 05  |................|
 00000390  08 06 04 01 05 01 06 01  03 03 02 03 03 01 02 01  |................|
@@ -112,28 +112,28 @@
 00000200  e4 fa cc b1 8a ce e2 23  a0 87 f0 e1 67 51 eb 16  |.......#....gQ..|
 00000210  03 03 00 25 10 00 00 21  20 2f e5 7d a3 47 cd 62  |...%...! /.}.G.b|
 00000220  43 15 28 da ac 5f bb 29  07 30 ff f6 84 af c4 cf  |C.(.._.).0......|
-00000230  c2 ed 90 99 5f 58 cb 3b  74 16 03 03 00 91 0f 00  |...._X.;t.......|
-00000240  00 8d 04 03 00 89 30 81  86 02 41 63 34 72 b4 70  |......0...Ac4r.p|
-00000250  45 46 9c 3c 06 2c f5 ab  d4 dd a7 91 69 9c 65 0f  |EF.<.,......i.e.|
-00000260  4b d9 2d 90 3d d1 f2 4d  2a 6a 43 4f a7 fd b5 22  |K.-.=..M*jCO..."|
-00000270  83 61 e2 14 33 8c bc 8a  81 52 a1 f4 69 a7 12 c9  |.a..3....R..i...|
-00000280  c3 28 69 85 6d c1 b0 5d  d3 5e ac 4e 02 41 35 cd  |.(i.m..].^.N.A5.|
-00000290  3b c3 f6 ea 9e df 2a a1  ea 80 55 40 d2 13 d3 ff  |;.....*...U@....|
-000002a0  b2 59 bb a0 c7 10 67 6e  9b dc 6c 3c 97 08 07 e0  |.Y....gn..l<....|
-000002b0  db da 79 6b 0e 6c a0 23  13 b1 02 32 ab ee 62 69  |..yk.l.#...2..bi|
-000002c0  f9 d5 7f 24 2e 26 94 36  a4 36 53 63 dd 90 20 14  |...$.&.6.6Sc.. .|
-000002d0  03 03 00 01 01 16 03 03  00 28 00 00 00 00 00 00  |.........(......|
-000002e0  00 00 a7 30 0e b0 f7 ba  51 35 c9 4c c2 24 90 5e  |...0....Q5.L.$.^|
-000002f0  b2 59 57 5d 96 9d ad d1  1e 7d b0 35 09 9c c5 49  |.YW].....}.5...I|
-00000300  bd 82                                             |..|
+00000230  c2 ed 90 99 5f 58 cb 3b  74 16 03 03 00 93 0f 00  |...._X.;t.......|
+00000240  00 8f 04 03 00 8b 30 81  88 02 42 01 d0 ef 2f 75  |......0...B.../u|
+00000250  25 6e 4b 2a 16 21 c4 73  59 80 a8 c9 27 45 1b 06  |%nK*.!.sY...'E..|
+00000260  75 20 61 01 db aa c4 90  25 16 1b fb ec 92 54 f7  |u a.....%.....T.|
+00000270  16 9b 8c e0 34 48 3e 62  57 92 99 42 7f d1 35 09  |....4H>bW..B..5.|
+00000280  e1 55 4c 32 cc ed 9d 3e  18 25 1d 31 b8 02 42 01  |.UL2...>.%.1..B.|
+00000290  dd d8 20 b1 12 a2 7d 3b  6b 40 f3 db 59 2b 33 db  |.. ...};[email protected]+3.|
+000002a0  5f 85 4d b4 5f 6f 23 ae  d2 a2 74 2b 22 94 60 51  |_.M._o#...t+".`Q|
+000002b0  75 aa 66 88 2f 5a db f5  91 b2 7c f4 c4 e9 25 fa  |u.f./Z....|...%.|
+000002c0  f7 74 20 00 c3 08 22 8e  88 28 1c 72 4b 36 cd 03  |.t ..."..(.rK6..|
+000002d0  46 14 03 03 00 01 01 16  03 03 00 28 00 00 00 00  |F..........(....|
+000002e0  00 00 00 00 2c 30 d5 ee  d2 79 8c 68 62 7a c7 36  |....,0...y.hbz.6|
+000002f0  ce c9 39 25 4b 6d 3e 59  7d 42 21 72 65 00 41 45  |..9%Km>Y}B!re.AE|
+00000300  ba 47 88 64                                       |.G.d|
 >>> Flow 4 (server to client)
-00000000  14 03 03 00 01 01 16 03  03 00 28 09 ff 53 e8 0f  |..........(..S..|
-00000010  ad 86 30 ca 96 54 da 72  45 13 7a cd 51 f6 b3 a5  |..0..T.rE.z.Q...|
-00000020  27 4c 7c 26 81 6d 76 6f  19 8e f3 13 77 49 59 73  |'L|&.mvo....wIYs|
-00000030  4e 98 3e                                          |N.>|
+00000000  14 03 03 00 01 01 16 03  03 00 28 9c e9 30 06 da  |..........(..0..|
+00000010  ef 89 4a 77 db 17 d4 51  79 36 c1 97 45 8a b0 c9  |..Jw...Qy6..E...|
+00000020  b7 d4 69 8d fc f2 5e 1a  c8 e3 43 6c 7a b4 0a 40  |..i...^...Clz..@|
+00000030  ec 35 c9                                          |.5.|
 >>> Flow 5 (client to server)
-00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 99 7b 4c  |..............{L|
-00000010  1d 0a b1 89 0d ac fa a7  39 eb 9a ff 8f 06 60 d1  |........9.....`.|
-00000020  88 e8 ef 15 03 03 00 1a  00 00 00 00 00 00 00 02  |................|
-00000030  99 42 7f c8 35 79 f3 a0  10 5c 05 25 c1 ac ab aa  |.B..5y...\.%....|
-00000040  d5 9e                                             |..|
+00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 f2 3b 7e  |..............;~|
+00000010  59 d0 c1 2f 93 f8 8a 48  8d e6 f4 54 70 63 4a 2d  |Y../...H...TpcJ-|
+00000020  90 5d 9b 15 03 03 00 1a  00 00 00 00 00 00 00 02  |.]..............|
+00000030  42 1f 5c b2 d3 14 4d 6e  30 85 59 89 5a 34 80 00  |B.\...Mn0.Y.Z4..|
+00000040  fe ab                                             |..|
diff --git a/src/crypto/tls/testdata/Client-TLSv13-ClientCert-ECDSA-RSA b/src/crypto/tls/testdata/Client-TLSv13-ClientCert-ECDSA-RSA
index 251e339..bd8f6cd 100644
--- a/src/crypto/tls/testdata/Client-TLSv13-ClientCert-ECDSA-RSA
+++ b/src/crypto/tls/testdata/Client-TLSv13-ClientCert-ECDSA-RSA
@@ -16,124 +16,124 @@
 000000e0  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 000000f0  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74     |.........._X.;t|
 >>> Flow 2 (server to client)
-00000000  16 03 03 00 7a 02 00 00  76 03 03 ce 38 98 c9 b7  |....z...v...8...|
-00000010  f8 67 af 0d 29 52 88 a4  d0 c2 a8 10 c4 8e 80 26  |.g..)R.........&|
-00000020  43 84 0e 60 06 ce f0 b7  b1 cd 29 20 00 00 00 00  |C..`......) ....|
+00000000  16 03 03 00 7a 02 00 00  76 03 03 85 46 7d 9f 55  |....z...v...F}.U|
+00000010  82 34 10 06 5e 8d 60 5d  00 9d 28 cd 18 c2 18 ee  |.4..^.`]..(.....|
+00000020  cb 9a 63 ee 9a 30 7d 5d  87 3d 24 20 00 00 00 00  |..c..0}].=$ ....|
 00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
 00000040  00 00 00 00 00 00 00 00  00 00 00 00 13 03 00 00  |................|
-00000050  2e 00 2b 00 02 03 04 00  33 00 24 00 1d 00 20 aa  |..+.....3.$... .|
-00000060  00 03 6d 16 04 54 48 55  4d f9 04 e8 29 ca 9c 5d  |..m..THUM...)..]|
-00000070  14 94 a2 7a 2e 0a 4e 75  12 2d 63 cf 19 81 21 14  |...z..Nu.-c...!.|
-00000080  03 03 00 01 01 17 03 03  00 17 7b 90 e1 af 77 ca  |..........{...w.|
-00000090  a1 3b a6 e0 9f ea 4b f6  3f 45 a0 78 1c fb af 51  |.;....K.?E.x...Q|
-000000a0  30 17 03 03 00 42 ff 27  8b 9c fd 65 d7 b1 d4 43  |0....B.'...e...C|
-000000b0  eb 8f c3 ca b4 57 be 35  35 75 35 cf 43 73 d6 14  |.....W.55u5.Cs..|
-000000c0  7e 2d b4 f8 31 60 1b 35  2a 38 91 32 40 8b f0 ab  |~-..1`.5*8.2@...|
-000000d0  a8 b0 dc 2b db b9 63 92  28 dc f2 c2 95 d3 4a 63  |...+..c.(.....Jc|
-000000e0  69 e7 58 0c e5 9c d5 22  17 03 03 02 6d 7c 70 9b  |i.X...."....m|p.|
-000000f0  e1 81 3a 0d 6e 7f 5c 30  2e 09 1d 82 ac 48 a6 7e  |..:.n.\0.....H.~|
-00000100  03 ce d0 ce e2 e8 9e 8b  2b ee af 1a b1 6a 3a 27  |........+....j:'|
-00000110  04 53 73 d2 d4 28 68 19  96 3a 3d 89 df 2c e3 2b  |.Ss..(h..:=..,.+|
-00000120  45 c8 5e 60 42 b0 4d f2  9c 8a 8d 83 f6 97 e0 b0  |E.^`B.M.........|
-00000130  02 39 37 46 2b 07 28 8b  e8 d8 c2 e3 ba 58 9b dc  |.97F+.(......X..|
-00000140  62 c4 e6 cb b4 97 f0 67  2b b3 40 4b 64 3e 73 3f  |b......g+.@Kd>s?|
-00000150  a1 1f 6e fe 7f ba af 7d  bd c4 7c 37 60 c0 94 d6  |..n....}..|7`...|
-00000160  bc 14 70 a9 95 a6 b7 88  9d 50 cf 9f 36 0c 38 c4  |..p......P..6.8.|
-00000170  97 ba ea 43 16 e8 fd 72  22 3c 09 4a 97 1c 97 70  |...C...r"<.J...p|
-00000180  88 6d d4 f3 9d b9 5a f3  67 f5 7b da 3e ed 1a 66  |.m....Z.g.{.>..f|
-00000190  4c 62 50 ff cd 92 08 d8  5c 2e 11 de ea 44 16 91  |LbP.....\....D..|
-000001a0  3e 44 d7 8c dd 2a b4 c7  2b 4d 40 a2 f9 7e 49 a9  |>D...*..+M@..~I.|
-000001b0  d8 51 a1 27 b3 34 75 59  04 04 cd 52 d6 37 34 e6  |.Q.'.4uY...R.74.|
-000001c0  41 32 36 45 c0 65 fb 5c  e2 21 77 7f 35 db 9d 34  |A26E.e.\.!w.5..4|
-000001d0  0d 6e 9d a7 9e 00 ec e3  3e 9c 50 50 13 5b ad b9  |.n......>.PP.[..|
-000001e0  b3 47 44 f8 9b 12 ab 50  7f a7 df 35 c5 d6 78 3c  |.GD....P...5..x<|
-000001f0  c1 04 41 db 99 18 cd 8c  05 3f 08 ae 2b 41 c9 46  |..A......?..+A.F|
-00000200  16 9a e3 a9 5b d3 9c 00  56 0e e2 d1 da 6d 6b 20  |....[...V....mk |
-00000210  65 1b 55 1f 4f b1 eb 94  c6 48 e3 50 d6 14 c5 62  |e.U.O....H.P...b|
-00000220  5e fc d2 cf df f4 68 90  c9 bb 80 54 f3 f3 a3 78  |^.....h....T...x|
-00000230  af 1f 6f ef e1 d5 64 24  04 e5 d4 59 bc 4d 7b a0  |..o...d$...Y.M{.|
-00000240  1a 23 e1 81 b7 c4 bb 52  86 f4 2a 85 d2 d0 7a ed  |.#.....R..*...z.|
-00000250  c0 5d 27 07 4b df 52 c4  ea c8 c9 9c f0 48 35 71  |.]'.K.R......H5q|
-00000260  bd 04 65 65 47 e3 21 88  ff 08 6c 6a f3 6c dd 81  |..eeG.!...lj.l..|
-00000270  3f 50 21 66 34 49 07 a0  e0 6d 80 54 77 8b 27 81  |?P!f4I...m.Tw.'.|
-00000280  4f b9 59 60 0a b0 c7 00  6a 7b 26 33 f6 5e ad 37  |O.Y`....j{&3.^.7|
-00000290  bf ea 87 e4 3c e7 b8 20  b0 89 88 ac 5a a4 af f7  |....<.. ....Z...|
-000002a0  23 3c 0a d0 ab 74 fc 49  d2 e5 51 a7 a5 4e 21 5f  |#<...t.I..Q..N!_|
-000002b0  90 9a 65 36 9f e1 e3 9e  3d 67 d6 93 f1 b8 f0 4b  |..e6....=g.....K|
-000002c0  c6 d8 ca 50 fb cc 92 ab  47 b5 8c 21 02 4a ee 42  |...P....G..!.J.B|
-000002d0  35 a3 52 41 04 94 19 cd  23 c6 33 b0 84 0d 88 97  |5.RA....#.3.....|
-000002e0  5a e0 3e 4c 6d 99 ec 6d  11 3f 19 e7 77 60 3b de  |Z.>Lm..m.?..w`;.|
-000002f0  6d 04 b8 ab bc 83 4f 51  a5 ba 56 56 d6 e3 ff 0e  |m.....OQ..VV....|
-00000300  d5 4b 75 29 6a f9 4b c6  ef fd 62 25 89 76 f1 fd  |.Ku)j.K...b%.v..|
-00000310  84 3f e9 93 63 cf eb 47  85 b1 aa a2 4c 94 6b 99  |.?..c..G....L.k.|
-00000320  98 6e 1a 19 85 0b 90 d2  9f 0f ec d4 36 1e 22 a0  |.n..........6.".|
-00000330  4e 7f a1 ae 90 15 68 8a  48 c5 06 01 aa b9 56 cb  |N.....h.H.....V.|
-00000340  e0 62 53 d8 96 56 61 1d  81 96 b8 66 ae 94 c8 5f  |.bS..Va....f..._|
-00000350  86 47 fe ca 27 8d 7f 8e  f8 74 17 03 03 00 99 ac  |.G..'....t......|
-00000360  2b 09 0b 44 a5 33 27 19  86 59 ca 75 5c df 59 fc  |+..D.3'..Y.u\.Y.|
-00000370  34 57 08 11 4f d8 1a c6  7c 76 d5 0a 36 91 f2 3a  |4W..O...|v..6..:|
-00000380  d1 96 58 64 29 3a d1 05  e3 cb 6f ea 92 4a f6 3b  |..Xd):....o..J.;|
-00000390  54 4c 16 41 99 6e 0f e9  c3 9a ac a3 59 ee fa c9  |TL.A.n......Y...|
-000003a0  4d 58 ae 23 58 58 b5 b5  d6 6a dd b4 0c 24 bf e1  |MX.#XX...j...$..|
-000003b0  d4 16 53 f2 2d e1 78 d0  ea 70 59 ac a3 e4 e4 6f  |..S.-.x..pY....o|
-000003c0  65 93 28 ad e1 64 83 11  05 42 a3 a0 11 d5 f2 af  |e.(..d...B......|
-000003d0  7e 03 93 80 82 48 e0 84  2e 1c 50 98 65 22 49 f1  |~....H....P.e"I.|
-000003e0  df 41 03 83 b2 5c 1c 56  cb b7 f3 72 04 d6 09 cf  |.A...\.V...r....|
-000003f0  f9 3a 5d e8 35 80 b6 a2  17 03 03 00 35 b4 b5 c3  |.:].5.......5...|
-00000400  43 78 3d e8 eb 66 7d 1c  36 8e a1 9f 26 ab 5a aa  |Cx=..f}.6...&.Z.|
-00000410  63 b6 2f 7a a5 f6 7d 89  1e 5d c5 a1 bf b4 3b 4a  |c./z..}..]....;J|
-00000420  89 1f 96 74 e3 c4 d8 72  57 a5 c7 99 a9 f3 77 16  |...t...rW.....w.|
-00000430  f3 25                                             |.%|
+00000050  2e 00 2b 00 02 03 04 00  33 00 24 00 1d 00 20 15  |..+.....3.$... .|
+00000060  b8 ae de 9d dc 14 58 fe  01 5d 08 ed 41 ac c6 c7  |......X..]..A...|
+00000070  85 fe b1 a3 ae b6 8c 47  f3 e1 4e c5 f8 8b 48 14  |.......G..N...H.|
+00000080  03 03 00 01 01 17 03 03  00 17 d6 72 35 0b 81 34  |...........r5..4|
+00000090  42 89 f1 9b 31 94 72 af  0c 3c 45 36 96 26 71 e8  |B...1.r..<E6.&q.|
+000000a0  86 17 03 03 00 42 47 ed  30 6f 20 53 07 4f b2 c1  |.....BG.0o S.O..|
+000000b0  35 49 fa 5b d9 af 6c 0b  c3 71 7a f3 a8 5b 24 ba  |5I.[..l..qz..[$.|
+000000c0  59 dd 34 b7 02 07 63 5d  a1 ad ac 4c a2 58 e7 cd  |Y.4...c]...L.X..|
+000000d0  6d f7 23 4e e1 a9 af 75  23 93 37 25 59 7e fb 52  |m.#N...u#.7%Y~.R|
+000000e0  65 a4 e7 ea 0a df a7 ce  17 03 03 02 6d e5 aa db  |e...........m...|
+000000f0  1d 7e 55 0f b4 79 96 de  15 74 52 95 52 c8 ce d6  |.~U..y...tR.R...|
+00000100  85 a9 a8 6f 79 63 cf d7  3a 9e 38 d2 9d 0a 73 a0  |...oyc..:.8...s.|
+00000110  0b c3 f3 85 77 d3 63 16  9b 13 79 e6 61 96 08 57  |....w.c...y.a..W|
+00000120  ba 4a 64 b6 af 1a 98 22  a6 d9 20 82 2c 40 28 57  |.Jd....".. .,@(W|
+00000130  b8 95 d6 b4 94 46 8f 67  2d eb ee 02 74 d3 94 e7  |.....F.g-...t...|
+00000140  6e 5b 2f a9 7d a2 c2 aa  89 0c 43 c3 9d 92 6f 16  |n[/.}.....C...o.|
+00000150  27 84 d7 79 dd 4b 6a ed  9b fc cd d7 c0 c4 59 09  |'..y.Kj.......Y.|
+00000160  21 1f 83 67 e7 76 c8 ee  bf f5 79 87 a0 bd 14 6d  |!..g.v....y....m|
+00000170  db ac 06 04 c4 3b 3a a7  1e cb 22 d1 97 21 9d c2  |.....;:..."..!..|
+00000180  ee ed a8 41 f7 a0 6a a0  64 2f b0 0a 6f b7 78 b8  |...A..j.d/..o.x.|
+00000190  20 36 ed 7a e9 3c 26 cb  36 7d 3c ee 73 27 32 e7  | 6.z.<&.6}<.s'2.|
+000001a0  e7 fd 6e 27 d9 da ad 48  67 29 94 50 f5 0e 56 af  |..n'...Hg).P..V.|
+000001b0  e4 c5 1d d3 59 a4 de 59  d7 79 7a f3 10 36 fb ed  |....Y..Y.yz..6..|
+000001c0  b1 97 00 a4 dd 6e c2 65  19 0a 73 fe 2c 49 dc c5  |.....n.e..s.,I..|
+000001d0  df 19 53 c2 7e de 0b 2b  55 3d ca 0b 39 a4 77 c4  |..S.~..+U=..9.w.|
+000001e0  21 53 93 12 f0 9a 3a 3b  97 0c 93 80 50 23 80 9e  |!S....:;....P#..|
+000001f0  84 2e ef 22 2b c1 b3 dd  b1 55 38 76 9a d6 a6 f1  |..."+....U8v....|
+00000200  67 11 df d9 a0 8a 18 c6  68 ef d8 7b d7 36 4b 57  |g.......h..{.6KW|
+00000210  a7 bf 4e 77 a5 f6 4f 1e  be 6e 14 40 67 73 1c 20  |..Nw..O..n.@gs. |
+00000220  9f 17 30 b6 76 00 87 56  8c 2b 76 5f 04 46 5a a1  |..0.v..V.+v_.FZ.|
+00000230  0f fa 64 b3 fa da 4e 72  eb a7 95 c3 93 de 97 20  |..d...Nr....... |
+00000240  2d ea 06 84 aa f0 b6 5a  ac ea 64 06 2a 8c b0 eb  |-......Z..d.*...|
+00000250  58 0a e8 51 e1 34 c4 03  38 9f f7 fb ec 98 78 07  |X..Q.4..8.....x.|
+00000260  71 73 ad a5 d7 d5 d1 2d  95 b6 4f 7c 5a ee d9 f1  |qs.....-..O|Z...|
+00000270  fa e3 7d ae bd 31 98 27  31 07 f2 86 cf e5 8d 2c  |..}..1.'1......,|
+00000280  e8 55 40 69 b0 26 a3 51  e8 60 59 6f 66 bb 36 4f  |.U@i.&.Q.`Yof.6O|
+00000290  85 fc 36 d1 72 99 9d e1  83 ad ec 3f e8 90 a8 48  |..6.r......?...H|
+000002a0  f5 d1 41 30 59 4e 44 79  e4 de 6f 0d 37 61 01 bb  |..A0YNDy..o.7a..|
+000002b0  b8 7f ee c7 a2 35 c7 12  dc d3 ca 49 8d d9 3e d8  |.....5.....I..>.|
+000002c0  24 69 34 a4 8f 92 f2 77  61 cb b7 04 f8 02 25 9c  |$i4....wa.....%.|
+000002d0  88 ea c7 f0 13 3e 17 bc  ac 5a 80 c4 80 c6 b0 19  |.....>...Z......|
+000002e0  d3 73 b5 94 5a 27 df 08  05 23 6e 03 64 67 ab c8  |.s..Z'...#n.dg..|
+000002f0  63 7c 76 b3 92 39 ef 29  77 28 ec 6f 05 70 a6 2f  |c|v..9.)w(.o.p./|
+00000300  a0 d2 73 fd f9 cc 4f d7  6f 86 db 9a 02 84 8c 6c  |..s...O.o......l|
+00000310  39 3a 54 28 38 43 ca 0d  da 34 b5 d4 03 0c f8 c1  |9:T(8C...4......|
+00000320  8d 48 d0 63 c7 41 da 4c  db 0a 45 56 cf 6b 0b ca  |.H.c.A.L..EV.k..|
+00000330  2f a3 82 6e 8e 90 6f 8a  f2 41 33 c5 56 c5 15 bd  |/..n..o..A3.V...|
+00000340  c2 02 45 41 7a e7 2b 0d  15 82 a7 37 34 ea 19 c2  |..EAz.+....74...|
+00000350  8b 1d d4 17 9c 2d d4 c0  9d f3 17 03 03 00 99 37  |.....-.........7|
+00000360  6a b2 6e 07 32 19 45 80  7b 80 ef 93 b3 6e c3 19  |j.n.2.E.{....n..|
+00000370  4d fe 3e e9 7f e4 b9 37  d2 b0 83 56 f7 2f 9b 61  |M.>....7...V./.a|
+00000380  67 a1 65 b4 38 4b a1 06  c5 4a 20 44 37 26 d0 2a  |g.e.8K...J D7&.*|
+00000390  b7 96 1e 72 ef a8 5d fb  5a b8 ea 26 0e 4b 38 e0  |...r..].Z..&.K8.|
+000003a0  6a 3a ab 4a e3 b4 db 00  f8 30 e6 db 02 e4 cf 89  |j:.J.....0......|
+000003b0  5b 57 b8 b8 3e 0a 97 b4  61 9e 89 7d 76 b3 9f 51  |[W..>...a..}v..Q|
+000003c0  a0 b8 46 95 8b 2b b9 25  8e 39 29 f5 97 41 e6 f1  |..F..+.%.9)..A..|
+000003d0  f0 0c 8b 70 bc 63 a0 56  24 c0 fb 0d 44 7f d8 78  |...p.c.V$...D..x|
+000003e0  c0 d5 a2 b7 53 67 c5 6d  0f 37 25 3e dc 08 e2 50  |....Sg.m.7%>...P|
+000003f0  ca 28 c3 1b ec 28 26 0c  17 03 03 00 35 ef 63 88  |.(...(&.....5.c.|
+00000400  13 79 07 a1 28 af 88 6e  8c e4 ad b3 0a 28 2a ce  |.y..(..n.....(*.|
+00000410  db 0f 63 8a 16 95 ab 0a  01 51 4f 28 79 15 78 00  |..c......QO(y.x.|
+00000420  f9 7a a6 40 1b 39 98 d8  8d df 1b b9 ab 82 b9 59  |[email protected]|
+00000430  67 b9                                             |g.|
 >>> Flow 3 (client to server)
-00000000  14 03 03 00 01 01 17 03  03 02 1e 2e 1c 18 ac 6e  |...............n|
-00000010  bd d7 35 f8 21 6f 36 d7  13 94 53 3b 56 5d 03 8e  |..5.!o6...S;V]..|
-00000020  2d 92 fa cb 17 d3 75 55  13 84 9c aa be f7 34 9e  |-.....uU......4.|
-00000030  35 67 9b 90 bc 76 5d 65  c0 23 b0 04 d0 ba 15 b5  |5g...v]e.#......|
-00000040  30 70 4d 8d d2 38 73 0a  3a 58 c3 bc da a4 f5 ae  |0pM..8s.:X......|
-00000050  05 ee 0c 06 bd 06 fe ab  1b 31 cf 4d 46 63 cc ee  |.........1.MFc..|
-00000060  8f 8a 0d e9 32 50 4d a0  f6 f2 ce c5 be 41 c2 16  |....2PM......A..|
-00000070  a7 c3 b3 8a 5c 27 4a fd  37 2d 32 d9 76 25 27 12  |....\'J.7-2.v%'.|
-00000080  03 b9 e7 ef bc c8 59 e1  16 80 dc b2 16 ae 05 b6  |......Y.........|
-00000090  cf 8e 99 0d f8 ed 5a b1  bb c1 05 d5 35 fe fd 2d  |......Z.....5..-|
-000000a0  97 c6 19 d8 2d 1a a9 30  d1 4a 6d 27 45 93 5f 5d  |....-..0.Jm'E._]|
-000000b0  45 f4 98 a8 d8 88 27 8f  f2 ad 1e 24 6e c8 8f 12  |E.....'....$n...|
-000000c0  f7 32 b5 3d 3c e3 e0 32  56 4e 80 a8 5f 27 f0 d0  |.2.=<..2VN.._'..|
-000000d0  a1 c2 d0 22 2d 3a 36 0f  bd 7b 94 9f ca 8d c1 ea  |..."-:6..{......|
-000000e0  c6 1f d8 87 4a 75 bd 3e  0f ae 2f e1 78 ae 3f 00  |....Ju.>../.x.?.|
-000000f0  f4 3a 82 dd ec 3f 61 43  bf 4b f8 01 a3 32 df 13  |.:...?aC.K...2..|
-00000100  61 45 ca bb e0 9a 17 85  45 90 c6 fb 5d 79 1b 58  |aE......E...]y.X|
-00000110  54 ca 84 e9 a9 11 c4 74  82 f7 da e4 b3 4f 05 a1  |T......t.....O..|
-00000120  23 72 9f 63 b8 4c 55 e6  da 33 b9 1c b0 fe 28 72  |#r.c.LU..3....(r|
-00000130  f0 02 b6 ec 70 ae 27 d4  21 51 32 56 32 4e e7 7d  |....p.'.!Q2V2N.}|
-00000140  b8 0d 75 25 45 5c 68 83  4f e3 3e 8a 87 7c 06 81  |..u%E\h.O.>..|..|
-00000150  ac ff 23 44 0e bd e7 0a  76 64 45 c4 04 df 35 db  |..#D....vdE...5.|
-00000160  ab 8a 38 87 f5 e5 35 75  7a 92 85 3d 14 9e aa 19  |..8...5uz..=....|
-00000170  4d 94 25 8f c0 c3 37 ca  63 f3 dd 48 4a 6a 6b f5  |M.%...7.c..HJjk.|
-00000180  fa 52 67 30 ab ff 56 9f  58 bd cd 66 d4 83 85 d8  |.Rg0..V.X..f....|
-00000190  85 6c 6d 3c 56 e5 17 75  fc dc a7 3d ed 18 a1 3b  |.lm<V..u...=...;|
-000001a0  6c e6 54 95 75 38 77 77  90 34 81 cb 1c cb e9 04  |l.T.u8ww.4......|
-000001b0  c8 d2 12 04 36 a8 9b f6  9b 6a 81 8d f5 b1 e2 ca  |....6....j......|
-000001c0  31 37 27 f2 84 bd 5c 3a  1c 6c 64 83 35 94 89 ee  |17'...\:.ld.5...|
-000001d0  08 42 1d 05 52 67 e6 4d  7f bb d2 21 82 8c 15 6b  |.B..Rg.M...!...k|
-000001e0  e9 f9 6d bc b3 1f 5a df  b8 55 aa 9d f6 aa d2 7c  |..m...Z..U.....||
-000001f0  41 76 3b 1b b2 f5 b8 49  32 be bb f8 0e d3 74 be  |Av;....I2.....t.|
-00000200  eb 0d 9b e2 57 b6 ec e5  61 d7 09 80 a8 63 b4 cf  |....W...a....c..|
-00000210  bb 0a 14 9d 39 1c 08 58  22 c4 ae d5 4f 42 97 14  |....9..X"...OB..|
-00000220  71 e1 c0 a5 5e 8e 2f 89  27 17 03 03 00 a3 f0 96  |q...^./.'.......|
-00000230  d3 9e 8c 19 84 9a 42 d3  84 64 a6 89 40 6f d6 c9  |......B..d..@o..|
-00000240  50 90 bb 9d 16 90 9d fb  aa 85 28 ab 25 63 78 a9  |P.........(.%cx.|
-00000250  dd dc 35 03 73 08 26 2b  30 53 84 f8 74 66 f2 6f  |..5.s.&+0S..tf.o|
-00000260  d7 0a f0 e2 c4 10 a4 46  cf 77 ea cb b7 b7 a9 81  |.......F.w......|
-00000270  5f 09 4a 6a a5 16 a4 79  dc b0 c9 ae 5a ff 2a 7b  |_.Jj...y....Z.*{|
-00000280  3f bd 7a 15 b3 02 ad 3e  90 37 46 51 71 fc 6d d0  |?.z....>.7FQq.m.|
-00000290  9f 38 42 95 1a 88 ac 5f  83 a1 8a 59 59 62 cc 4a  |.8B...._...YYb.J|
-000002a0  57 d2 3e 1e 7e 1d c0 4d  41 23 85 5f 92 f4 63 16  |W.>.~..MA#._..c.|
-000002b0  df df 6e 3d d7 c1 e6 21  22 0f e1 13 82 29 a6 e3  |..n=...!"....)..|
-000002c0  f8 8c a4 a3 72 1d 61 c1  2a 9d a8 2d 13 8a 4f 87  |....r.a.*..-..O.|
-000002d0  91 17 03 03 00 35 9d 35  c8 ac 1e c6 46 8d e1 42  |.....5.5....F..B|
-000002e0  68 e5 79 77 64 15 e2 13  c0 70 1a 47 59 d0 1e c3  |h.ywd....p.GY...|
-000002f0  68 f7 5a fe 11 a2 3d e4  6e 2c b5 7d ea 98 e7 75  |h.Z...=.n,.}...u|
-00000300  7c 54 a4 35 9b 1f c9 ba  72 b1 94 17 03 03 00 17  ||T.5....r.......|
-00000310  a3 81 17 ac 97 a9 f0 91  b5 7a 04 38 ff fd 8e d3  |.........z.8....|
-00000320  d8 7b c4 40 7e d3 ea 17  03 03 00 13 a8 b1 06 94  |.{.@~...........|
-00000330  90 83 62 d5 be a8 23 d5  8b af 77 0d 90 13 98     |..b...#...w....|
+00000000  14 03 03 00 01 01 17 03  03 02 1e ad ee 84 48 28  |..............H(|
+00000010  bb dc e6 01 81 4c b3 55  85 2a 73 3a 34 d6 6b 3a  |.....L.U.*s:4.k:|
+00000020  c6 e7 6b da e8 97 dc 13  72 9c d4 03 e2 fc ec e0  |..k.....r.......|
+00000030  0b 00 09 a9 3c 85 19 79  80 a3 fc da 39 b1 13 90  |....<..y....9...|
+00000040  3e 0c be 19 5a be a9 ac  a5 46 a0 07 79 74 be 59  |>...Z....F..yt.Y|
+00000050  18 23 55 79 c0 29 3f 8c  37 d6 21 0c 64 57 4c f0  |.#Uy.)?.7.!.dWL.|
+00000060  a1 34 e0 52 f7 e5 3c af  48 b4 82 78 bd be 7c 90  |.4.R..<.H..x..|.|
+00000070  df 0e f3 46 84 6a e2 bb  88 aa 9a a0 ce 04 de 2b  |...F.j.........+|
+00000080  b3 17 78 e1 a0 bb 65 7f  c5 b3 a6 45 13 c6 11 e1  |..x...e....E....|
+00000090  e2 b4 ec 80 43 80 b6 a5  12 58 ac 5e 30 d3 a0 61  |....C....X.^0..a|
+000000a0  60 c2 90 36 aa 82 f7 ff  55 aa 4e 25 b3 29 5d 41  |`..6....U.N%.)]A|
+000000b0  67 4e 9c d4 f1 1d 55 f1  29 54 13 25 3c 04 41 8f  |gN....U.)T.%<.A.|
+000000c0  6b 9d 95 06 3f 04 84 55  dd 43 7a fb 9f 73 ff df  |k...?..U.Cz..s..|
+000000d0  3b da 12 3b 97 36 fa 51  0b ca c7 0b fb 6a 09 dd  |;..;.6.Q.....j..|
+000000e0  61 2a df 79 b3 66 90 45  76 3c 2b c6 98 42 5a 82  |a*.y.f.Ev<+..BZ.|
+000000f0  0e 93 cf 6f 2b 60 e4 66  67 ad 43 66 73 d2 8c 94  |...o+`.fg.Cfs...|
+00000100  7f 7a 97 d5 a1 8b 07 63  44 cb 51 18 ac 2a af 19  |.z.....cD.Q..*..|
+00000110  66 df ab 18 6f 2a bf fc  7a fa 64 52 c4 1e 91 71  |f...o*..z.dR...q|
+00000120  f1 f7 7f 79 e1 ed 07 3a  e1 08 07 d3 db 4d 74 76  |...y...:.....Mtv|
+00000130  db fa b9 b4 68 e3 d8 e7  8d ad 49 a7 1d 6d 7e 4e  |....h.....I..m~N|
+00000140  3a 6a d2 9a c3 b0 72 61  bb 72 b8 8d 98 58 6e 2e  |:j....ra.r...Xn.|
+00000150  20 f8 ab 4a df 96 c7 6c  fe 33 5b 76 b0 80 26 34  | ..J...l.3[v..&4|
+00000160  b9 5c 9a 79 50 d7 6a 29  25 11 20 4e 3c b6 a7 73  |.\.yP.j)%. N<..s|
+00000170  64 55 a6 8e 57 22 4a 98  5e 14 95 21 ff 8d 3f 05  |dU..W"J.^..!..?.|
+00000180  eb d9 30 8e f1 a3 56 3a  d8 6d 6e 07 de a2 62 ec  |..0...V:.mn...b.|
+00000190  e4 06 bb 96 ae a3 23 d0  bd fd c7 f3 ee 2f 21 3f  |......#....../!?|
+000001a0  8f 25 7a 4a fb 47 cf 78  db 74 35 c8 67 e6 f0 99  |.%zJ.G.x.t5.g...|
+000001b0  39 4e 1f 50 1a bc 64 2e  ae 8e b5 38 63 06 86 5a  |9N.P..d....8c..Z|
+000001c0  2b 1b b5 b9 a1 18 58 24  32 ce c9 de 66 ba 21 b3  |+.....X$2...f.!.|
+000001d0  d8 0f fa 3a 88 ac 6e 66  57 2c 45 5b 59 85 d4 b0  |...:..nfW,E[Y...|
+000001e0  ad 32 8c ef 0c 2a 51 1a  cc ca 6a 82 3e 70 41 cc  |.2...*Q...j.>pA.|
+000001f0  b8 80 db a0 48 22 47 49  a1 a5 d2 9a 80 dc 09 bc  |....H"GI........|
+00000200  c8 c7 dd 53 4b 44 2f 9a  75 06 b7 31 5e fd 74 f5  |...SKD/.u..1^.t.|
+00000210  d4 53 e2 90 dc b7 9a 13  ca 00 96 56 a1 1b dd 71  |.S.........V...q|
+00000220  54 25 77 fa 42 31 95 dd  ba 17 03 03 00 a3 9e 23  |T%w.B1.........#|
+00000230  96 bb c9 d5 30 f7 f4 a3  4c 33 a4 bd 2b 09 93 f5  |....0...L3..+...|
+00000240  04 02 a7 d7 9d 2e 00 5e  18 bc 18 de 1b 94 28 51  |.......^......(Q|
+00000250  4b cd 2c 15 0e 75 b1 59  12 96 8f eb cb b5 a4 4a  |K.,..u.Y.......J|
+00000260  ea c2 e0 1d 28 72 4b 8f  62 d3 7d f0 2f f1 c4 de  |....(rK.b.}./...|
+00000270  6a 6e dc 9c 43 80 c8 ae  99 86 97 de 67 58 d6 4c  |jn..C.......gX.L|
+00000280  91 74 dc c3 23 a5 32 9b  df f5 1e 64 15 04 7d df  |.t..#.2....d..}.|
+00000290  12 e4 40 52 77 5c a3 26  de 20 b6 92 a5 d8 18 cf  |..@Rw\.&. ......|
+000002a0  63 7e 9e 47 b8 ed db ee  b7 9d b6 1c e5 c0 ad 7f  |c~.G............|
+000002b0  d6 07 89 d8 b3 a0 2e 87  b9 81 0d 44 37 c2 c5 13  |...........D7...|
+000002c0  cc cb 70 87 e3 49 6e eb  66 79 76 37 4a f1 c4 4e  |..p..In.fyv7J..N|
+000002d0  82 17 03 03 00 35 52 42  2a a8 a5 7a eb 5f 32 d5  |.....5RB*..z._2.|
+000002e0  68 71 42 8b ce 62 f0 48  43 0b 0f b8 8c ed 16 f4  |hqB..b.HC.......|
+000002f0  64 7e d3 74 57 9d 83 00  ad bc 9b f8 ed bb 23 35  |d~.tW.........#5|
+00000300  07 e9 7c b2 a1 d6 76 d0  f5 ba 15 17 03 03 00 17  |..|...v.........|
+00000310  e2 3f a0 cb 23 fe 4c f1  aa cb 21 70 74 46 4f 10  |.?..#.L...!ptFO.|
+00000320  30 76 0a 72 49 09 65 17  03 03 00 13 ee 7b 9d 32  |0v.rI.e......{.2|
+00000330  ac d4 8a 40 99 1b 0a 23  f7 a4 c6 a6 ef 33 77     |...@...#.....3w|
diff --git a/src/crypto/tls/testdata/Server-TLSv10-ECDHE-ECDSA-AES b/src/crypto/tls/testdata/Server-TLSv10-ECDHE-ECDSA-AES
index 1132b39..c8f11ea 100644
--- a/src/crypto/tls/testdata/Server-TLSv10-ECDHE-ECDSA-AES
+++ b/src/crypto/tls/testdata/Server-TLSv10-ECDHE-ECDSA-AES
@@ -1,11 +1,10 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 63 01 00 00  5f 03 01 38 de f5 d6 ae  |....c..._..8....|
-00000010  46 71 e8 02 f2 45 88 b8  64 fb 6e 68 67 d1 7f e8  |Fq...E..d.nhg...|
-00000020  49 71 1e a9 ec 8e 54 06  bb 2b 16 00 00 04 c0 0a  |Iq....T..+......|
-00000030  00 ff 01 00 00 32 00 00  00 0e 00 0c 00 00 09 31  |.....2.........1|
-00000040  32 37 2e 30 2e 30 2e 31  00 0b 00 04 03 00 01 02  |27.0.0.1........|
-00000050  00 0a 00 0c 00 0a 00 1d  00 17 00 1e 00 19 00 18  |................|
-00000060  00 16 00 00 00 17 00 00                           |........|
+00000000  16 03 01 00 51 01 00 00  4d 03 01 8a c0 af 21 2c  |....Q...M.....!,|
+00000010  ff 48 d6 fd 10 92 4a 8c  84 c7 9e c3 90 3a f5 bf  |.H....J......:..|
+00000020  cd 36 1b 2f 96 8b 13 86  f1 ff 5e 00 00 04 c0 0a  |.6./......^.....|
+00000030  00 ff 01 00 00 20 00 0b  00 04 03 00 01 02 00 0a  |..... ..........|
+00000040  00 0c 00 0a 00 1d 00 17  00 1e 00 19 00 18 00 16  |................|
+00000050  00 00 00 17 00 00                                 |......|
 >>> Flow 2 (server to client)
 00000000  16 03 01 00 37 02 00 00  33 03 01 00 00 00 00 00  |....7...3.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
@@ -44,37 +43,37 @@
 00000220  0d 94 06 bb d4 37 7a f6  ec 7a c9 86 2e dd d7 11  |.....7z..z......|
 00000230  69 7f 85 7c 56 de fb 31  78 2b e4 c7 78 0d ae cb  |i..|V..1x+..x...|
 00000240  be 9e 4e 36 24 31 7b 6a  0f 39 95 12 07 8f 2a 16  |..N6$1{j.9....*.|
-00000250  03 01 00 b5 0c 00 00 b1  03 00 1d 20 2f e5 7d a3  |........... /.}.|
+00000250  03 01 00 b4 0c 00 00 b0  03 00 1d 20 2f e5 7d a3  |........... /.}.|
 00000260  47 cd 62 43 15 28 da ac  5f bb 29 07 30 ff f6 84  |G.bC.(.._.).0...|
-00000270  af c4 cf c2 ed 90 99 5f  58 cb 3b 74 00 8b 30 81  |......._X.;t..0.|
-00000280  88 02 42 01 ad 26 fd 16  9a 93 5f 87 ce 29 8c d2  |..B..&...._..)..|
-00000290  56 a7 d2 59 56 bd d3 1f  90 54 bd af 91 81 25 ff  |V..YV....T....%.|
-000002a0  66 74 57 16 2f 31 f2 5a  48 97 03 b9 41 4c 8e bb  |ftW./1.ZH...AL..|
-000002b0  87 31 ed 71 84 37 63 78  9f 0a c7 9d 5e f3 5a 53  |.1.q.7cx....^.ZS|
-000002c0  88 89 46 ba a7 02 42 00  92 74 15 1c 0e 1f 2f 95  |..F...B..t..../.|
-000002d0  e5 79 d5 e9 90 ce d8 96  0d fd b8 42 55 00 94 08  |.y.........BU...|
-000002e0  4e 47 a9 ea bd 67 0b 02  a6 9e 8b d3 09 e5 53 ea  |NG...g........S.|
-000002f0  03 22 2e 2d 78 2c 69 1d  28 ab 13 3d 0a 46 15 09  |.".-x,i.(..=.F..|
-00000300  b6 0b 74 69 2d 5a 96 bf  b6 16 03 01 00 04 0e 00  |..ti-Z..........|
-00000310  00 00                                             |..|
+00000270  af c4 cf c2 ed 90 99 5f  58 cb 3b 74 00 8a 30 81  |......._X.;t..0.|
+00000280  87 02 42 01 ea 1b 6f 67  3e cd 57 50 12 78 5a db  |..B...og>.WP.xZ.|
+00000290  06 12 77 04 9d df 0c b0  98 4b a7 e8 23 fb ad 46  |..w......K..#..F|
+000002a0  ef 9b 99 d3 02 4b 46 51  c4 49 2a ae 29 b4 a7 e5  |.....KFQ.I*.)...|
+000002b0  08 d0 db ce 28 af 21 43  37 d4 29 03 00 e3 5f 50  |....(.!C7.)..._P|
+000002c0  35 cd 0a 3f 9d 02 41 35  05 7c a0 ed 81 23 98 38  |5..?..A5.|...#.8|
+000002d0  af 2c 12 8f 59 94 77 c7  56 ef 0b db 60 d0 5b 72  |.,..Y.w.V...`.[r|
+000002e0  9e fd 2a 6c ea 1d af cb  ce 5b df 34 52 2a 4b 38  |..*l.....[.4R*K8|
+000002f0  48 81 2c 39 76 61 58 19  80 1b e0 eb fb 53 35 94  |H.,9vaX......S5.|
+00000300  55 ba a6 2b a2 b3 50 b4  16 03 01 00 04 0e 00 00  |U..+..P.........|
+00000310  00                                                |.|
 >>> Flow 3 (client to server)
-00000000  16 03 01 00 25 10 00 00  21 20 82 c0 dd 83 c2 45  |....%...! .....E|
-00000010  a2 bc 3a 2a ec ab 60 8e  02 e0 db 7c 59 83 c1 62  |..:*..`....|Y..b|
-00000020  c7 cc 61 1e de dc 40 e4  65 6c 14 03 01 00 01 01  |[email protected]......|
-00000030  16 03 01 00 30 3e 26 56  0b a2 10 47 00 55 27 21  |....0>&V...G.U'!|
-00000040  63 33 f2 7d 4b ba 77 5f  e7 a7 09 7a 1f 51 85 f2  |c3.}K.w_...z.Q..|
-00000050  46 a5 af 80 79 1a c7 72  bb 3d f9 dd 1d 83 05 22  |F...y..r.=....."|
-00000060  c9 6c dd 91 d9                                    |.l...|
+00000000  16 03 01 00 25 10 00 00  21 20 29 f2 f2 54 f4 ff  |....%...! )..T..|
+00000010  59 de df ab 55 18 04 cd  8c 27 28 7e 11 11 09 84  |Y...U....'(~....|
+00000020  18 e1 0f 09 70 f8 d7 13  a1 38 14 03 01 00 01 01  |....p....8......|
+00000030  16 03 01 00 30 d8 40 dc  30 cb d6 25 de 23 01 84  |[email protected]..%.#..|
+00000040  30 75 1c 17 bd f3 fe 7e  b4 cd 61 f3 55 c4 30 55  |0u.....~..a.U.0U|
+00000050  ee 43 6f f0 6b a7 0a ed  88 d9 d4 72 7c c7 c6 c7  |.Co.k......r|...|
+00000060  4d 2f 7b 9f 9b                                    |M/{..|
 >>> Flow 4 (server to client)
-00000000  14 03 01 00 01 01 16 03  01 00 30 38 fa fd 42 8f  |..........08..B.|
-00000010  80 5a 7c 33 d4 6c 72 f7  4e 2f 00 ab c2 86 58 9d  |.Z|3.lr.N/....X.|
-00000020  fc a5 43 fa ea 5b a1 ee  a9 df df 9d 90 4c c0 e3  |..C..[.......L..|
-00000030  10 09 c4 23 21 f9 e9 69  f5 f8 fa 17 03 01 00 20  |...#!..i....... |
-00000040  1e 57 17 e4 96 06 32 d4  00 a3 98 ed bd 1c 61 78  |.W....2.......ax|
-00000050  e7 0d 89 ec 84 c3 56 fa  75 73 87 6f 47 35 80 3f  |......V.us.oG5.?|
-00000060  17 03 01 00 30 4d 51 0a  dd 70 6d b0 c2 d1 46 5c  |....0MQ..pm...F\|
-00000070  b5 03 87 de e6 65 d3 e2  83 e0 33 f8 a2 0a 29 7f  |.....e....3...).|
-00000080  6c 24 2b 1f 7b 2b 53 19  21 e9 62 6c 31 75 9c be  |l$+.{+S.!.bl1u..|
-00000090  5b b0 3d 5b 1a 15 03 01  00 20 19 51 64 4b 5a 9b  |[.=[..... .QdKZ.|
-000000a0  c8 2a 1c e7 9e 29 d9 df  ad 1d 08 09 82 a3 b1 1d  |.*...)..........|
-000000b0  60 99 00 25 30 51 a1 72  b6 27                    |`..%0Q.r.'|
+00000000  14 03 01 00 01 01 16 03  01 00 30 60 b7 c0 a3 ba  |..........0`....|
+00000010  ad dd 52 99 15 7a f2 9e  10 21 02 7c 91 6d cf c9  |..R..z...!.|.m..|
+00000020  09 ab fe 9c b3 46 46 60  1c 24 66 3f b6 14 b1 51  |.....FF`.$f?...Q|
+00000030  ac 05 75 48 03 c1 e0 3a  c2 6d 5e 17 03 01 00 20  |..uH...:.m^.... |
+00000040  82 87 18 81 c3 24 55 8f  9c a3 49 fc 8a 8a 7a fe  |.....$U...I...z.|
+00000050  93 05 c9 7e 90 73 a4 b1  0a d7 3b 7d 72 1f fc 6c  |...~.s....;}r..l|
+00000060  17 03 01 00 30 1f 51 a5  44 2e 7a 40 12 43 28 c6  |[email protected](.|
+00000070  99 05 6d 92 d9 ed 0d f2  fb a7 48 a3 03 e9 34 b1  |..m.......H...4.|
+00000080  52 32 e1 be a9 7e bf b1  0e 1f b4 1c 3e 0a 9d d9  |R2...~......>...|
+00000090  90 10 4f 79 dd 15 03 01  00 20 57 98 fd dd 09 f9  |..Oy..... W.....|
+000000a0  c5 d9 33 24 1a b2 ed 56  ad 91 c9 25 2f ff ff 09  |..3$...V...%/...|
+000000b0  dc b0 2c 38 cc 70 1f cc  6f f4                    |..,8.p..o.|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-ECDHE-ECDSA-AES b/src/crypto/tls/testdata/Server-TLSv12-ECDHE-ECDSA-AES
index d7e6188..62f4311 100644
--- a/src/crypto/tls/testdata/Server-TLSv12-ECDHE-ECDSA-AES
+++ b/src/crypto/tls/testdata/Server-TLSv12-ECDHE-ECDSA-AES
@@ -1,14 +1,13 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 97 01 00 00  93 03 03 86 3b 10 1e 5f  |............;.._|
-00000010  81 eb 21 bd 77 47 61 e9  3f 82 85 14 91 8c ab 7d  |..!.wGa.?......}|
-00000020  84 bd b1 f0 06 20 8a 7b  06 d6 78 00 00 04 c0 0a  |..... .{..x.....|
-00000030  00 ff 01 00 00 66 00 00  00 0e 00 0c 00 00 09 31  |.....f.........1|
-00000040  32 37 2e 30 2e 30 2e 31  00 0b 00 04 03 00 01 02  |27.0.0.1........|
-00000050  00 0a 00 0c 00 0a 00 1d  00 17 00 1e 00 19 00 18  |................|
-00000060  00 16 00 00 00 17 00 00  00 0d 00 30 00 2e 04 03  |...........0....|
-00000070  05 03 06 03 08 07 08 08  08 09 08 0a 08 0b 08 04  |................|
-00000080  08 05 08 06 04 01 05 01  06 01 03 03 02 03 03 01  |................|
-00000090  02 01 03 02 02 02 04 02  05 02 06 02              |............|
+00000000  16 03 01 00 85 01 00 00  81 03 03 20 34 f0 4b 7a  |........... 4.Kz|
+00000010  4f ed 31 de 38 ef 33 2e  69 7d 74 35 e5 02 b9 bb  |O.1.8.3.i}t5....|
+00000020  bd 1a 5c 3a f2 57 f1 23  62 66 52 00 00 04 c0 0a  |..\:.W.#bfR.....|
+00000030  00 ff 01 00 00 54 00 0b  00 04 03 00 01 02 00 0a  |.....T..........|
+00000040  00 0c 00 0a 00 1d 00 17  00 1e 00 19 00 18 00 16  |................|
+00000050  00 00 00 17 00 00 00 0d  00 30 00 2e 04 03 05 03  |.........0......|
+00000060  06 03 08 07 08 08 08 09  08 0a 08 0b 08 04 08 05  |................|
+00000070  08 06 04 01 05 01 06 01  03 03 02 03 03 01 02 01  |................|
+00000080  03 02 02 02 04 02 05 02  06 02                    |..........|
 >>> Flow 2 (server to client)
 00000000  16 03 03 00 37 02 00 00  33 03 03 00 00 00 00 00  |....7...3.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
@@ -47,39 +46,39 @@
 00000220  0d 94 06 bb d4 37 7a f6  ec 7a c9 86 2e dd d7 11  |.....7z..z......|
 00000230  69 7f 85 7c 56 de fb 31  78 2b e4 c7 78 0d ae cb  |i..|V..1x+..x...|
 00000240  be 9e 4e 36 24 31 7b 6a  0f 39 95 12 07 8f 2a 16  |..N6$1{j.9....*.|
-00000250  03 03 00 b7 0c 00 00 b3  03 00 1d 20 2f e5 7d a3  |........... /.}.|
+00000250  03 03 00 b6 0c 00 00 b2  03 00 1d 20 2f e5 7d a3  |........... /.}.|
 00000260  47 cd 62 43 15 28 da ac  5f bb 29 07 30 ff f6 84  |G.bC.(.._.).0...|
-00000270  af c4 cf c2 ed 90 99 5f  58 cb 3b 74 04 03 00 8b  |......._X.;t....|
-00000280  30 81 88 02 42 01 c5 d1  36 97 5b 0e 5e a6 90 50  |0...B...6.[.^..P|
-00000290  a0 2e 80 b5 df d7 5a f6  95 0d a4 c6 f0 da 2e e7  |......Z.........|
-000002a0  91 79 9f 85 2e ef ca 66  3c f7 c4 7b bd 61 70 bb  |.y.....f<..{.ap.|
-000002b0  16 c5 aa 00 35 33 ae 58  00 b3 f1 fe 0f 77 52 23  |....53.X.....wR#|
-000002c0  f4 40 ba 4b c7 e5 43 02  42 01 64 af ab 8a 87 38  |[email protected]|
-000002d0  a1 7f b8 ae 84 0e a4 ff  ad 16 09 44 0b 65 67 70  |...........D.egp|
-000002e0  12 7f 1a 37 9a 1d 5e b7  3b 63 df f9 6b f1 b9 ba  |...7..^.;c..k...|
-000002f0  6b 35 8f b3 03 da 3d 61  00 3d 4e 75 b4 d0 92 d5  |k5....=a.=Nu....|
-00000300  ee 50 9d d7 f9 26 69 e6  ec cf 3b 16 03 03 00 04  |.P...&i...;.....|
-00000310  0e 00 00 00                                       |....|
+00000270  af c4 cf c2 ed 90 99 5f  58 cb 3b 74 04 03 00 8a  |......._X.;t....|
+00000280  30 81 87 02 41 21 2b cf  6b fc 8a 13 b6 21 8a 46  |0...A!+.k....!.F|
+00000290  fc 7c 56 7e 28 22 4d b2  c2 c8 45 92 cc 99 6a 3c  |.|V~("M...E...j<|
+000002a0  48 0f 16 95 6c 43 3d ea  bd ac 25 88 a3 35 0c 14  |H...lC=...%..5..|
+000002b0  c6 43 46 16 ec b5 57 76  86 1c 5a d1 52 44 3b 8c  |.CF...Wv..Z.RD;.|
+000002c0  e5 b3 46 3b 47 d8 02 42  01 ad a2 c3 4c 69 35 13  |..F;G..B....Li5.|
+000002d0  d7 66 37 63 c9 43 50 68  f6 ff 7f 7d be 7e 8d 89  |.f7c.CPh...}.~..|
+000002e0  db 57 3e 0f 51 c8 49 9b  3a e2 87 65 dd 28 21 9a  |.W>.Q.I.:..e.(!.|
+000002f0  c3 36 28 a4 e8 25 7b ae  8e 45 35 22 8f 2d 97 27  |.6(..%{..E5".-.'|
+00000300  fe b8 99 a9 c1 5f d8 8b  70 d3 16 03 03 00 04 0e  |....._..p.......|
+00000310  00 00 00                                          |...|
 >>> Flow 3 (client to server)
-00000000  16 03 03 00 25 10 00 00  21 20 54 db 5b a1 4c e0  |....%...! T.[.L.|
-00000010  0e 52 a2 45 e3 b4 ac 91  3d e1 de a9 3e eb 80 9e  |.R.E....=...>...|
-00000020  f5 04 7b fc 82 10 2f d9  d1 41 14 03 03 00 01 01  |..{.../..A......|
-00000030  16 03 03 00 40 47 68 cc  5e 68 3f 05 d6 f8 5c 11  |....@Gh.^h?...\.|
-00000040  08 a3 91 72 ae 4c 98 67  2f 45 ee 16 6b 8b 2d 28  |...r.L.g/E..k.-(|
-00000050  15 34 43 47 f9 46 f2 96  c2 85 d5 cc 03 e0 84 de  |.4CG.F..........|
-00000060  9c 03 fe bf c9 73 23 15  d0 0f 85 3a 76 db 9f 5d  |.....s#....:v..]|
-00000070  95 b7 de 9c c2                                    |.....|
+00000000  16 03 03 00 25 10 00 00  21 20 c4 25 45 6f 39 18  |....%...! .%Eo9.|
+00000010  b1 f6 0a b3 f7 3e 98 ed  63 ae bd 74 12 91 0d 81  |.....>..c..t....|
+00000020  84 71 13 3c a7 cf a5 d2  24 5f 14 03 03 00 01 01  |.q.<....$_......|
+00000030  16 03 03 00 40 27 8d 44  74 7a ae 8a 4e 1c f9 1b  |....@'.Dtz..N...|
+00000040  05 23 c4 89 57 27 4c dc  db 4a ae aa 08 74 00 55  |.#..W'L..J...t.U|
+00000050  f9 4e 63 02 75 24 ca fb  30 78 cc 82 8a 69 be ab  |.Nc.u$..0x...i..|
+00000060  10 9d 25 2d a8 b6 bb 64  6e 32 68 4b 0a 32 06 74  |..%-...dn2hK.2.t|
+00000070  26 5e bc 68 25                                    |&^.h%|
 >>> Flow 4 (server to client)
 00000000  14 03 03 00 01 01 16 03  03 00 40 00 00 00 00 00  |..........@.....|
-00000010  00 00 00 00 00 00 00 00  00 00 00 98 34 52 f3 44  |............4R.D|
-00000020  18 69 23 61 ef 8f e9 c0  88 9c ad 1f cb e4 8d 55  |.i#a...........U|
-00000030  bd bb 77 9c 65 9d 21 f0  54 4c 46 db 4f e6 e8 ab  |..w.e.!.TLF.O...|
-00000040  6b 1d 60 38 7f e0 2c 38  ef e7 43 17 03 03 00 40  |k.`8..,8..C....@|
+00000010  00 00 00 00 00 00 00 00  00 00 00 b0 cf 70 b3 00  |.............p..|
+00000020  89 e2 77 af 87 08 f5 2f  2c c8 75 ce 8a ed 30 d8  |..w..../,.u...0.|
+00000030  f7 44 f3 9d 8b 4c 42 7a  52 d0 c8 37 9b 45 46 1c  |.D...LBzR..7.EF.|
+00000040  56 3b ee 52 5d c4 72 04  13 49 aa 17 03 03 00 40  |V;.R].r..I.....@|
 00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000060  44 68 90 07 1e 8c 7f db  3e 3f 8c 28 e1 d7 41 38  |Dh......>?.(..A8|
-00000070  e2 78 04 e3 42 c2 a9 76  bb 0a ae b9 93 df 81 d7  |.x..B..v........|
-00000080  9b 0f 1d 44 19 79 ff 7c  21 8f 75 ca e2 82 cc c4  |...D.y.|!.u.....|
+00000060  ce c4 34 c2 d8 4e f5 db  d1 ff 6d 64 ae 39 6d 78  |..4..N....md.9mx|
+00000070  3c c4 57 32 d1 af 35 d3  b4 79 3c b4 bd a1 21 7b  |<.W2..5..y<...!{|
+00000080  1f ef b8 3c 97 37 18 e5  10 62 e8 3d 7d 12 f5 db  |...<.7...b.=}...|
 00000090  15 03 03 00 30 00 00 00  00 00 00 00 00 00 00 00  |....0...........|
-000000a0  00 00 00 00 00 82 1f e6  2c 3f c7 55 19 01 0b 62  |........,?.U...b|
-000000b0  1a 99 fc f8 d3 b0 38 21  41 92 1a d1 e0 43 96 da  |......8!A....C..|
-000000c0  80 4b 58 91 c8                                    |.KX..|
+000000a0  00 00 00 00 00 81 75 ae  71 18 61 61 ae 35 ce c8  |......u.q.aa.5..|
+000000b0  43 57 52 c9 68 5e 0d 63  c4 0e 7d 36 90 b2 f6 f6  |CWR.h^.c..}6....|
+000000c0  ea 72 3c d9 41                                    |.r<.A|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-ECDHE-ECDSA-AES b/src/crypto/tls/testdata/Server-TLSv13-ECDHE-ECDSA-AES
index d2b0250..22909cc 100644
--- a/src/crypto/tls/testdata/Server-TLSv13-ECDHE-ECDSA-AES
+++ b/src/crypto/tls/testdata/Server-TLSv13-ECDHE-ECDSA-AES
@@ -1,96 +1,94 @@
 >>> Flow 1 (client to server)
-00000000  16 03 01 00 dc 01 00 00  d8 03 03 90 bc cf 62 d0  |..............b.|
-00000010  bc 89 6b 84 ad 18 87 f5  9c 96 0e 02 3f ae a5 4b  |..k.........?..K|
-00000020  80 70 f8 54 47 b1 78 03  48 4d 06 20 ae 9e 3c 17  |.p.TG.x.HM. ..<.|
-00000030  1a c6 fa 52 84 da ea a9  9c 08 e7 10 65 3a 65 4e  |...R........e:eN|
-00000040  d1 65 61 40 bf 7c ee db  d4 f2 73 ff 00 04 13 01  |.ea@.|....s.....|
-00000050  00 ff 01 00 00 8b 00 00  00 0e 00 0c 00 00 09 31  |...............1|
-00000060  32 37 2e 30 2e 30 2e 31  00 0b 00 04 03 00 01 02  |27.0.0.1........|
-00000070  00 0a 00 0c 00 0a 00 1d  00 17 00 1e 00 19 00 18  |................|
-00000080  00 16 00 00 00 17 00 00  00 0d 00 1e 00 1c 04 03  |................|
-00000090  05 03 06 03 08 07 08 08  08 09 08 0a 08 0b 08 04  |................|
-000000a0  08 05 08 06 04 01 05 01  06 01 00 2b 00 03 02 03  |...........+....|
-000000b0  04 00 2d 00 02 01 01 00  33 00 26 00 24 00 1d 00  |..-.....3.&.$...|
-000000c0  20 ad 11 a7 07 20 9c cb  33 96 f4 0d 78 a1 89 55  | .... ..3...x..U|
-000000d0  6c af 70 f4 ac d6 cb d9  0d 1b 13 fa 50 de 68 17  |l.p.........P.h.|
-000000e0  1d                                                |.|
+00000000  16 03 01 00 ca 01 00 00  c6 03 03 30 09 bc 8e d5  |...........0....|
+00000010  59 36 2b f3 2b 0f 9d 32  ff 23 ba c7 4a 1f 50 e6  |Y6+.+..2.#..J.P.|
+00000020  32 bd 0e c3 f6 df b7 70  dc d5 0c 20 44 0e b7 7b  |2......p... D..{|
+00000030  a0 37 9f 1d 8d 7e 93 f7  c0 7d 25 d3 f8 e5 65 50  |.7...~...}%...eP|
+00000040  79 5e 4f 53 e5 67 40 f0  bf ad 4d f8 00 04 13 01  |y^[email protected].....|
+00000050  00 ff 01 00 00 79 00 0b  00 04 03 00 01 02 00 0a  |.....y..........|
+00000060  00 0c 00 0a 00 1d 00 17  00 1e 00 19 00 18 00 16  |................|
+00000070  00 00 00 17 00 00 00 0d  00 1e 00 1c 04 03 05 03  |................|
+00000080  06 03 08 07 08 08 08 09  08 0a 08 0b 08 04 08 05  |................|
+00000090  08 06 04 01 05 01 06 01  00 2b 00 03 02 03 04 00  |.........+......|
+000000a0  2d 00 02 01 01 00 33 00  26 00 24 00 1d 00 20 23  |-.....3.&.$... #|
+000000b0  23 ab 76 3d e8 d5 1b 9f  03 71 bc bf 3d 18 3a 86  |#.v=.....q..=.:.|
+000000c0  5d 59 ee ac b9 0a 2f f6  fc 5d 13 7b 3e 88 68     |]Y..../..].{>.h|
 >>> Flow 2 (server to client)
 00000000  16 03 03 00 7a 02 00 00  76 03 03 00 00 00 00 00  |....z...v.......|
 00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
-00000020  00 00 00 00 00 00 00 00  00 00 00 20 ae 9e 3c 17  |........... ..<.|
-00000030  1a c6 fa 52 84 da ea a9  9c 08 e7 10 65 3a 65 4e  |...R........e:eN|
-00000040  d1 65 61 40 bf 7c ee db  d4 f2 73 ff 13 01 00 00  |.ea@.|....s.....|
+00000020  00 00 00 00 00 00 00 00  00 00 00 20 44 0e b7 7b  |........... D..{|
+00000030  a0 37 9f 1d 8d 7e 93 f7  c0 7d 25 d3 f8 e5 65 50  |.7...~...}%...eP|
+00000040  79 5e 4f 53 e5 67 40 f0  bf ad 4d f8 13 01 00 00  |y^[email protected].....|
 00000050  2e 00 2b 00 02 03 04 00  33 00 24 00 1d 00 20 2f  |..+.....3.$... /|
 00000060  e5 7d a3 47 cd 62 43 15  28 da ac 5f bb 29 07 30  |.}.G.bC.(.._.).0|
 00000070  ff f6 84 af c4 cf c2 ed  90 99 5f 58 cb 3b 74 14  |.........._X.;t.|
-00000080  03 03 00 01 01 17 03 03  00 17 f1 16 14 8f 0a b5  |................|
-00000090  92 fa 55 d7 fb 6c 33 04  ae c6 ed 3b 90 27 e9 ae  |..U..l3....;.'..|
-000000a0  e8 17 03 03 02 22 ca b1  97 19 9d da 2e 1d 12 f4  |....."..........|
-000000b0  05 af 35 28 1e 85 9d 28  81 f0 5a 83 46 9c df f7  |..5(...(..Z.F...|
-000000c0  58 2e 30 fa b9 07 00 cf  fe 69 37 5e f2 75 a0 ef  |X.0......i7^.u..|
-000000d0  f3 ab 60 0b c5 09 72 bd  b4 42 2f 45 24 3e 82 d0  |..`...r..B/E$>..|
-000000e0  f1 a1 dd 3a de 6a b9 9d  85 2b 83 75 47 c9 d2 c3  |...:.j...+.uG...|
-000000f0  25 91 85 c2 a1 97 6a 62  dd aa 19 11 94 e2 6b f9  |%.....jb......k.|
-00000100  7d 5a bc 5e d4 64 bc 74  44 85 d1 7a eb 3a ef d5  |}Z.^.d.tD..z.:..|
-00000110  96 f4 22 64 61 2b 79 77  ac 8b 61 69 cc eb ad fd  |.."da+yw..ai....|
-00000120  38 5e 61 74 d9 4f 70 82  06 3b 3e f8 a8 53 7c e8  |8^at.Op..;>..S|.|
-00000130  9d 98 43 a1 af 86 ba d9  64 64 f0 e0 b0 8f 39 6b  |..C.....dd....9k|
-00000140  16 d6 92 09 8d 5b d0 34  f4 14 60 69 a0 28 73 3a  |.....[.4..`i.(s:|
-00000150  24 7f 81 4e 8b d1 50 49  1a c0 60 92 fd 02 47 6d  |$..N..PI..`...Gm|
-00000160  d8 97 62 b2 b4 57 8b d7  d1 b6 bf 19 40 cb 13 09  |..b..W......@...|
-00000170  ef d6 55 66 39 88 29 e0  14 2d 06 98 d6 b6 bf a6  |..Uf9.)..-......|
-00000180  04 10 47 d5 64 fe 38 69  db 33 a4 fc 12 de 83 5b  |..G.d.8i.3.....[|
-00000190  c9 8e 76 56 bc f7 dd ac  96 c6 a0 ed e5 43 0b 13  |..vV.........C..|
-000001a0  1e 78 94 18 fd 57 50 79  08 91 18 aa 84 63 4e 46  |.x...WPy.....cNF|
-000001b0  53 db e0 f3 9a 0b d6 13  20 36 aa 56 dd 7a 62 d9  |S....... 6.V.zb.|
-000001c0  3f f6 bd 87 74 3c 86 d1  94 a1 04 79 a8 54 e4 8e  |?...t<.....y.T..|
-000001d0  11 d6 52 42 5c 4b 77 18  b9 d7 db f7 48 9a 69 e1  |..RB\Kw.....H.i.|
-000001e0  2d b9 38 38 e4 e8 94 5e  b1 7e 2c 81 96 6a a0 ed  |-.88...^.~,..j..|
-000001f0  bb 35 6a 8c 93 f2 6d 38  70 df 79 54 d9 45 c8 b8  |.5j...m8p.yT.E..|
-00000200  b2 9c 0f 9f 70 34 8f ac  b3 08 f5 3e b1 d2 5a d7  |....p4.....>..Z.|
-00000210  7b ee f3 dc 9a d1 12 c3  77 24 76 9b bf 09 50 a7  |{.......w$v...P.|
-00000220  3c ab 7f 1f 99 b5 02 8c  ac 5e 85 cc 53 fd ca e0  |<........^..S...|
-00000230  c7 e2 41 08 fd cb b0 79  0c 8b 02 4f 80 92 c2 cd  |..A....y...O....|
-00000240  6c a1 aa 75 d2 4c d1 25  40 7c 14 41 a7 15 20 a3  |l..u.L.%@|.A.. .|
-00000250  a6 81 64 7c c0 c7 2d dd  82 84 ad 2a f4 06 f9 61  |..d|..-....*...a|
-00000260  23 1c dd c6 ef 72 da 6b  eb be 41 f0 b4 5f 9a 02  |#....r.k..A.._..|
-00000270  ee a8 f3 bb 05 48 ec 50  a3 ff f3 94 bb d8 a9 6d  |.....H.P.......m|
-00000280  92 49 7c bf a1 eb 55 26  08 26 d3 80 d6 cb 05 ea  |.I|...U&.&......|
-00000290  d1 db bf 97 3d 10 ff 4e  f6 05 33 23 68 95 31 42  |....=..N..3#h.1B|
-000002a0  5a d5 30 61 79 c4 88 7f  e1 be 28 ad 72 bb 78 36  |Z.0ay.....(.r.x6|
-000002b0  ba bb 38 75 fb 97 33 b6  28 8c a2 f4 46 fe 37 d8  |..8u..3.(...F.7.|
-000002c0  b0 67 63 97 c1 51 0c 61  17 03 03 00 a4 20 15 70  |.gc..Q.a..... .p|
-000002d0  7a 69 b1 33 c2 e1 f5 9c  2b b2 06 1e 01 a6 7f 03  |zi.3....+.......|
-000002e0  cd 00 13 02 3b 0c 2b 3f  85 d8 ed 6d 81 7e e9 b2  |....;.+?...m.~..|
-000002f0  b6 be 7b 77 51 30 dd b5  fc 93 08 91 9e 46 e2 85  |..{wQ0.......F..|
-00000300  74 3c 9a 04 26 86 b8 6c  98 99 57 7e 36 54 0d 90  |t<..&..l..W~6T..|
-00000310  4c 55 65 77 69 59 b2 e5  5b a3 19 4a b0 72 3d 91  |LUewiY..[..J.r=.|
-00000320  2e 5d 9b 8c 52 a1 e6 f5  22 c6 3c 0d 9b d8 9c b9  |.]..R...".<.....|
-00000330  cb 90 51 bc 16 69 06 30  22 16 62 08 3b 3f 05 99  |..Q..i.0".b.;?..|
-00000340  60 2a cc cf 29 f5 e1 b0  84 81 c8 63 00 d4 d4 13  |`*..)......c....|
-00000350  b5 5d 4c 63 8a 60 3e 44  24 03 30 85 91 4c 3d f2  |.]Lc.`>D$.0..L=.|
-00000360  2c c2 78 f2 c3 4c bb 90  60 0b 66 18 02 e7 5c 85  |,.x..L..`.f...\.|
-00000370  19 17 03 03 00 35 49 76  5f ff 32 3a 09 7a 4b f2  |.....5Iv_.2:.zK.|
-00000380  fe f3 38 b6 76 f4 12 f2  aa a3 ed b6 02 ab 0b b9  |..8.v...........|
-00000390  3b 9d 00 51 f1 5c 96 23  6b 49 f8 32 9f 74 30 32  |;..Q.\.#kI.2.t02|
-000003a0  4d af af ef d5 55 2c ff  2b a0 45 17 03 03 00 93  |M....U,.+.E.....|
-000003b0  6e e0 6a f9 44 af c0 af  95 ab 1e ff fd 97 38 f5  |n.j.D.........8.|
-000003c0  7b 24 70 da e2 4e 8b dc  9b 49 84 fe 73 0a b0 7e  |{$p..N...I..s..~|
-000003d0  cf 14 f7 8a 67 e7 74 bd  ee 82 93 c6 27 a2 bd 1e  |....g.t.....'...|
-000003e0  cb 71 06 af 65 dd f0 d9  91 81 b0 f8 21 34 48 d1  |.q..e.......!4H.|
-000003f0  c4 e0 e3 19 a8 b4 48 b7  3a be 52 e5 7c a8 a3 c2  |......H.:.R.|...|
-00000400  08 6c ac 66 4d 36 cf a1  9d 1f 72 c5 09 20 db 05  |.l.fM6....r.. ..|
-00000410  e5 0a 44 af 4a d8 32 38  19 7d 28 e3 05 23 99 66  |..D.J.28.}(..#.f|
-00000420  f6 ad 77 02 7e 00 67 c1  71 58 b9 89 3c 93 15 95  |..w.~.g.qX..<...|
-00000430  ee 38 e2 ea c0 73 fe da  e4 75 6d 38 ca 54 0b bf  |.8...s...um8.T..|
-00000440  f0 af 86                                          |...|
+00000080  03 03 00 01 01 17 03 03  00 17 2a db 0a 1b 36 73  |..........*...6s|
+00000090  de 3d 2f d9 c8 c0 2b 93  43 b3 a8 96 30 d2 bc 3d  |.=/...+.C...0..=|
+000000a0  f7 17 03 03 02 22 72 49  cc 6d 9e 7f f5 42 1c 8b  |....."rI.m...B..|
+000000b0  8a 0e 1b ad 71 f4 21 50  be ad 91 df e0 d4 a0 dc  |....q.!P........|
+000000c0  61 d2 eb 6a 39 f1 8d 31  66 9f 97 d9 b2 79 bf 10  |a..j9..1f....y..|
+000000d0  cc e1 2a 7f da 9f ff 10  22 a8 0b d6 26 c9 7c a4  |..*....."...&.|.|
+000000e0  51 8d a7 62 af 96 ec 01  72 7b 08 27 9f ff 1d a6  |Q..b....r{.'....|
+000000f0  26 54 6e 48 09 73 ac 7c  b2 bc a5 04 4e a2 41 66  |&TnH.s.|....N.Af|
+00000100  37 07 dd 7f 0d 8b 5b fa  84 a4 12 8b 44 9b b3 44  |7.....[.....D..D|
+00000110  71 bb 3a ce 95 8b a1 c5  e2 9f d2 86 0b 2b b2 43  |q.:..........+.C|
+00000120  aa 24 4c 69 0f c8 e8 7d  ff 53 2a 56 e8 dd 53 bf  |.$Li...}.S*V..S.|
+00000130  1b a7 fa 74 f2 c3 3d fa  11 b4 30 ce c0 9b 05 a5  |...t..=...0.....|
+00000140  13 b9 d1 1d a7 02 0a a6  36 31 b5 91 1f 5e 7f 65  |........61...^.e|
+00000150  24 48 3c ec fa d3 db 11  31 d1 c3 cd 47 b2 89 95  |$H<.....1...G...|
+00000160  80 55 25 1a 66 bf d9 ba  42 05 1d 20 b3 6e 09 bc  |.U%.f...B.. .n..|
+00000170  5f 1d 81 15 b2 54 c6 65  7e 75 35 e7 54 60 28 e1  |_....T.e~u5.T`(.|
+00000180  15 0e ee 51 09 3c c1 5b  ba 90 2e af 0a 85 40 0a  |...Q.<.[......@.|
+00000190  de 78 c8 c9 15 75 61 1f  75 a2 5c 80 d5 ed a5 71  |.x...ua.u.\....q|
+000001a0  a7 d8 21 f3 9c 84 f5 af  b1 5c 45 76 de a7 05 20  |..!......\Ev... |
+000001b0  7f c4 c4 71 b1 68 e0 a2  17 7f ac f8 c4 80 a8 89  |...q.h..........|
+000001c0  e8 35 68 ae 98 cf 2d 29  4e dc 84 45 21 d3 bb 0a  |.5h...-)N..E!...|
+000001d0  d8 c9 e1 41 48 b2 a8 53  31 5c 26 d0 28 9e 8e df  |...AH..S1\&.(...|
+000001e0  72 f2 ef f7 78 3d 7e b9  09 0c a4 e8 3e c5 a5 f6  |r...x=~.....>...|
+000001f0  e3 aa 32 1d da 98 7b 0a  f1 0a 42 f6 71 92 45 01  |..2...{...B.q.E.|
+00000200  e4 28 f3 c6 0f a2 cf c3  74 3b 09 f5 75 51 8e fa  |.(......t;..uQ..|
+00000210  6c 12 9e 80 2b 0a 87 fb  29 3d 0d a6 c4 7b c8 42  |l...+...)=...{.B|
+00000220  75 57 48 b3 78 20 2c b3  a1 d7 b7 6f 95 18 a2 bc  |uWH.x ,....o....|
+00000230  fd c9 22 d3 49 ae 5b 2a  ec b1 1a ff cd 38 3a bf  |..".I.[*.....8:.|
+00000240  45 e8 a8 fe 39 d5 f8 a2  89 73 7f 8f 2c 65 8a e6  |E...9....s..,e..|
+00000250  b7 20 f7 c9 5c 02 ea 33  4f f6 fc 68 2f d6 a0 d9  |. ..\..3O..h/...|
+00000260  73 10 38 35 ba d8 74 2d  cf 05 07 ee d4 fc 09 89  |s.85..t-........|
+00000270  0b 77 72 61 74 1f 16 8d  1f 29 3b 20 8d ef 99 b8  |.wrat....); ....|
+00000280  3d 80 24 5a 1d 32 9b 2e  50 4c 35 7e 4f c9 bc a7  |=.$Z.2..PL5~O...|
+00000290  6e ae 26 42 fb 4e c3 a8  7c 77 b4 c5 4c 1b 3a db  |n.&B.N..|w..L.:.|
+000002a0  cc 3f 44 fe ae d7 3f 42  5f ee 05 6a 1d 72 98 0e  |.?D...?B_..j.r..|
+000002b0  db 97 3c 11 06 c7 9e 5b  03 95 e0 52 09 54 39 b1  |..<....[...R.T9.|
+000002c0  13 19 f3 98 6c ed e3 ab  17 03 03 00 a3 49 60 43  |....l........I`C|
+000002d0  34 81 d3 6f fe c4 eb ac  49 64 51 9f 22 81 03 41  |4..o....IdQ."..A|
+000002e0  fd bc 4f 41 78 59 81 8a  82 b5 c3 06 79 8d d4 b2  |..OAxY......y...|
+000002f0  8b 9f 08 2b 09 ae 88 7d  bd 87 6a 40 19 b8 c7 1b  |...+...}..j@....|
+00000300  e1 55 69 8d 47 7a 49 66  fe 22 1f 95 c7 b5 15 ce  |.Ui.GzIf."......|
+00000310  6b d6 5b 37 45 57 72 ba  5f a3 62 49 13 80 b9 47  |k.[7EWr._.bI...G|
+00000320  9c e3 ce 6e a0 40 03 7d  41 4e 41 0d 21 ee e4 f6  |...n.@.}ANA.!...|
+00000330  71 74 12 48 1e d1 b2 80  82 b0 bf ff 07 61 04 82  |qt.H.........a..|
+00000340  db 4b 00 a1 11 97 48 1b  9b 13 b3 0e 5b 7f 99 f3  |.K....H.....[...|
+00000350  6f c1 a0 2f 41 d9 e2 30  f9 fa 0b 8a ef 6d d1 e1  |o../A..0.....m..|
+00000360  30 3d 07 5a 8a ef 8b a1  2b 44 c5 58 0d 3f 13 d7  |0=.Z....+D.X.?..|
+00000370  17 03 03 00 35 a2 fb e8  71 06 77 fa 70 66 75 01  |....5...q.w.pfu.|
+00000380  0a a0 d7 49 20 f0 8a f0  ea bf 79 20 68 46 02 43  |...I .....y hF.C|
+00000390  3c b9 cc c9 5f 1d c7 80  d8 58 f5 e3 94 6e 85 02  |<..._....X...n..|
+000003a0  c8 b2 4e a1 a2 43 b8 8d  ae 89 17 03 03 00 93 4a  |..N..C.........J|
+000003b0  dd 6b 37 b9 20 fa 51 b2  e2 60 a1 8e 08 40 bf c6  |.k7. .Q..`...@..|
+000003c0  25 22 9a 26 3a ec 35 aa  f2 26 9c bc 39 05 91 7b  |%".&:.5..&..9..{|
+000003d0  81 45 18 8d f7 f4 29 88  76 43 a8 63 e3 d3 59 d7  |.E....).vC.c..Y.|
+000003e0  2d 67 b3 4d 2f 6d c6 62  cf fd ac ed d6 80 04 57  |-g.M/m.b.......W|
+000003f0  b3 ac af 59 ce 35 43 94  1d 97 8c 2d 8d 89 b1 a7  |...Y.5C....-....|
+00000400  90 76 89 ec e4 0a 8f a9  9b 8d 22 02 8b 87 55 a4  |.v........"...U.|
+00000410  9b 55 da 85 a6 06 47 63  4c a2 1c 96 eb e1 77 35  |.U....GcL.....w5|
+00000420  71 0d 7e e5 78 ab 25 da  ee 5e ae 07 a9 ed 44 3a  |q.~.x.%..^....D:|
+00000430  75 ff 5c 4f 4e e5 01 27  7f 9e eb 63 db e2 85 70  |u.\ON..'...c...p|
+00000440  fc 99                                             |..|
 >>> Flow 3 (client to server)
-00000000  14 03 03 00 01 01 17 03  03 00 35 23 02 12 13 f1  |..........5#....|
-00000010  db fa 70 c0 92 85 8a d3  fa 80 1b 5c a6 22 ff 20  |..p........\.". |
-00000020  5d bf 1d 61 58 34 c0 48  6f e1 26 a6 bf bc 76 c7  |]..aX4.Ho.&...v.|
-00000030  8b da ee 54 64 30 c4 5c  b1 61 67 82 29 bb 3f 4b  |...Td0.\.ag.).?K|
+00000000  14 03 03 00 01 01 17 03  03 00 35 8c c8 26 94 66  |..........5..&.f|
+00000010  2e fd e0 4e bf b8 77 9d  12 d9 f6 9c 1b 15 c4 f1  |...N..w.........|
+00000020  39 f8 91 27 16 0c 34 ef  33 46 22 4e 19 d6 d0 d2  |9..'..4.3F"N....|
+00000030  ef 6b 57 91 f8 e4 17 fe  f9 ec f4 f1 ce c0 44 26  |.kW...........D&|
 >>> Flow 4 (server to client)
-00000000  17 03 03 00 1e 95 c0 53  e2 37 94 09 83 1e 7e 23  |.......S.7....~#|
-00000010  dc 9f 02 5e 91 19 b6 f9  72 0d 38 3f 25 ae b2 5f  |...^....r.8?%.._|
-00000020  4b f2 78 17 03 03 00 13  d2 ad 73 d6 f3 21 ab 7c  |K.x.......s..!.||
-00000030  02 dd 63 ff cf d7 34 ca  71 3d 70                 |..c...4.q=p|
+00000000  17 03 03 00 1e ab 4d 1a  04 59 10 8b ef f9 b5 8a  |......M..Y......|
+00000010  62 34 91 4e f9 cd 93 8c  7a 6d be d6 72 42 ad 45  |b4.N....zm..rB.E|
+00000020  21 f5 4e 17 03 03 00 13  1e bf bd 27 1a ad ab 1f  |!.N........'....|
+00000030  32 f5 99 95 dc 34 e3 eb  9c c1 1c                 |2....4.....|
diff --git a/src/crypto/tls/ticket.go b/src/crypto/tls/ticket.go
index 6c1d20d..b82ccd1 100644
--- a/src/crypto/tls/ticket.go
+++ b/src/crypto/tls/ticket.go
@@ -32,7 +32,7 @@
 	usedOldKey bool
 }
 
-func (m *sessionState) marshal() []byte {
+func (m *sessionState) marshal() ([]byte, error) {
 	var b cryptobyte.Builder
 	b.AddUint16(m.vers)
 	b.AddUint16(m.cipherSuite)
@@ -47,7 +47,7 @@
 			})
 		}
 	})
-	return b.BytesOrPanic()
+	return b.Bytes()
 }
 
 func (m *sessionState) unmarshal(data []byte) bool {
@@ -86,7 +86,7 @@
 	certificate      Certificate // CertificateEntry certificate_list<0..2^24-1>;
 }
 
-func (m *sessionStateTLS13) marshal() []byte {
+func (m *sessionStateTLS13) marshal() ([]byte, error) {
 	var b cryptobyte.Builder
 	b.AddUint16(VersionTLS13)
 	b.AddUint8(0) // revision
@@ -96,7 +96,7 @@
 		b.AddBytes(m.resumptionSecret)
 	})
 	marshalCertificate(&b, m.certificate)
-	return b.BytesOrPanic()
+	return b.Bytes()
 }
 
 func (m *sessionStateTLS13) unmarshal(data []byte) bool {
diff --git a/src/crypto/x509/boring.go b/src/crypto/x509/boring.go
index 4aae905..095b58c 100644
--- a/src/crypto/x509/boring.go
+++ b/src/crypto/x509/boring.go
@@ -21,12 +21,13 @@
 		return true
 	}
 
-	// The key must be RSA 2048, RSA 3072, or ECDSA P-256, P-384, or P-521.
+	// The key must be RSA 2048, RSA 3072, RSA 4096,
+	// or ECDSA P-256, P-384, P-521.
 	switch k := c.PublicKey.(type) {
 	default:
 		return false
 	case *rsa.PublicKey:
-		if size := k.N.BitLen(); size != 2048 && size != 3072 {
+		if size := k.N.BitLen(); size != 2048 && size != 3072 && size != 4096 {
 			return false
 		}
 	case *ecdsa.PublicKey:
diff --git a/src/crypto/x509/boring_test.go b/src/crypto/x509/boring_test.go
index 7010f44..33fd0ed 100644
--- a/src/crypto/x509/boring_test.go
+++ b/src/crypto/x509/boring_test.go
@@ -54,7 +54,8 @@
 
 func TestBoringAllowCert(t *testing.T) {
 	R1 := testBoringCert(t, "R1", boringRSAKey(t, 2048), nil, boringCertCA|boringCertFIPSOK)
-	R2 := testBoringCert(t, "R2", boringRSAKey(t, 4096), nil, boringCertCA)
+	R2 := testBoringCert(t, "R2", boringRSAKey(t, 512), nil, boringCertCA)
+	R3 := testBoringCert(t, "R3", boringRSAKey(t, 4096), nil, boringCertCA|boringCertFIPSOK)
 
 	M1_R1 := testBoringCert(t, "M1_R1", boringECDSAKey(t, elliptic.P256()), R1, boringCertCA|boringCertFIPSOK)
 	M2_R1 := testBoringCert(t, "M2_R1", boringECDSAKey(t, elliptic.P224()), R1, boringCertCA)
@@ -64,6 +65,9 @@
 	testBoringCert(t, "I_M1", I_R1.key, M1_R1, boringCertCA|boringCertFIPSOK)
 	testBoringCert(t, "I_M2", I_R1.key, M2_R1, boringCertCA|boringCertFIPSOK)
 
+	I_R3 := testBoringCert(t, "I_R3", boringRSAKey(t, 3072), R3, boringCertCA|boringCertFIPSOK)
+	testBoringCert(t, "I_R3", I_R3.key, R3, boringCertCA|boringCertFIPSOK)
+
 	testBoringCert(t, "L1_I", boringECDSAKey(t, elliptic.P384()), I_R1, boringCertLeaf|boringCertFIPSOK)
 	testBoringCert(t, "L2_I", boringRSAKey(t, 1024), I_R1, boringCertLeaf)
 }
diff --git a/src/crypto/x509/internal/macos/corefoundation.go b/src/crypto/x509/internal/macos/corefoundation.go
index 2677ff7..b4032a5 100644
--- a/src/crypto/x509/internal/macos/corefoundation.go
+++ b/src/crypto/x509/internal/macos/corefoundation.go
@@ -10,9 +10,9 @@
 package macOS
 
 import (
+	"bytes"
 	"errors"
 	"internal/abi"
-	"reflect"
 	"runtime"
 	"time"
 	"unsafe"
@@ -31,10 +31,8 @@
 func CFDataToSlice(data CFRef) []byte {
 	length := CFDataGetLength(data)
 	ptr := CFDataGetBytePtr(data)
-	src := (*[1 << 20]byte)(unsafe.Pointer(ptr))[:length:length]
-	out := make([]byte, length)
-	copy(out, src)
-	return out
+	src := unsafe.Slice((*byte)(unsafe.Pointer(ptr)), length)
+	return bytes.Clone(src)
 }
 
 // CFStringToString returns a Go string representation of the passed
@@ -49,7 +47,7 @@
 	return string(b)
 }
 
-// TimeToCFDateRef converts a time.Time into an apple CFDateRef
+// TimeToCFDateRef converts a time.Time into an apple CFDateRef.
 func TimeToCFDateRef(t time.Time) CFRef {
 	secs := t.Sub(time.Date(2001, 1, 1, 0, 0, 0, 0, time.UTC)).Seconds()
 	ref := CFDateCreate(secs)
@@ -64,7 +62,7 @@
 //go:cgo_import_dynamic x509_CFDataCreate CFDataCreate "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation"
 
 func BytesToCFData(b []byte) CFRef {
-	p := unsafe.Pointer((*reflect.SliceHeader)(unsafe.Pointer(&b)).Data)
+	p := unsafe.Pointer(unsafe.SliceData(b))
 	ret := syscall(abi.FuncPCABI0(x509_CFDataCreate_trampoline), kCFAllocatorDefault, uintptr(p), uintptr(len(b)), 0, 0, 0)
 	runtime.KeepAlive(p)
 	return CFRef(ret)
@@ -75,7 +73,7 @@
 
 // StringToCFString returns a copy of the UTF-8 contents of s as a new CFString.
 func StringToCFString(s string) CFString {
-	p := unsafe.Pointer((*reflect.StringHeader)(unsafe.Pointer(&s)).Data)
+	p := unsafe.Pointer(unsafe.StringData(s))
 	ret := syscall(abi.FuncPCABI0(x509_CFStringCreateWithBytes_trampoline), kCFAllocatorDefault, uintptr(p),
 		uintptr(len(s)), uintptr(kCFStringEncodingUTF8), 0 /* isExternalRepresentation */, 0)
 	runtime.KeepAlive(p)
@@ -188,6 +186,13 @@
 }
 func x509_CFErrorCopyDescription_trampoline()
 
+//go:cgo_import_dynamic x509_CFErrorGetCode CFErrorGetCode "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation"
+
+func CFErrorGetCode(errRef CFRef) int {
+	return int(syscall(abi.FuncPCABI0(x509_CFErrorGetCode_trampoline), uintptr(errRef), 0, 0, 0, 0, 0))
+}
+func x509_CFErrorGetCode_trampoline()
+
 //go:cgo_import_dynamic x509_CFStringCreateExternalRepresentation CFStringCreateExternalRepresentation "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation"
 
 func CFStringCreateExternalRepresentation(strRef CFRef) (CFRef, error) {
diff --git a/src/crypto/x509/internal/macos/corefoundation.s b/src/crypto/x509/internal/macos/corefoundation.s
index d69f72f..49cd084 100644
--- a/src/crypto/x509/internal/macos/corefoundation.s
+++ b/src/crypto/x509/internal/macos/corefoundation.s
@@ -37,5 +37,7 @@
 	JMP x509_CFDataCreate(SB)
 TEXT ·x509_CFErrorCopyDescription_trampoline(SB),NOSPLIT,$0-0
 	JMP x509_CFErrorCopyDescription(SB)
+TEXT ·x509_CFErrorGetCode_trampoline(SB),NOSPLIT,$0-0
+	JMP x509_CFErrorGetCode(SB)
 TEXT ·x509_CFStringCreateExternalRepresentation_trampoline(SB),NOSPLIT,$0-0
 	JMP x509_CFStringCreateExternalRepresentation(SB)
diff --git a/src/crypto/x509/internal/macos/security.go b/src/crypto/x509/internal/macos/security.go
index d8147ba..a6972c0 100644
--- a/src/crypto/x509/internal/macos/security.go
+++ b/src/crypto/x509/internal/macos/security.go
@@ -8,7 +8,6 @@
 
 import (
 	"errors"
-	"fmt"
 	"internal/abi"
 	"strconv"
 	"unsafe"
@@ -52,6 +51,15 @@
 	SecTrustSettingsDomainSystem
 )
 
+const (
+	// various macOS error codes that can be returned from
+	// SecTrustEvaluateWithError that we can map to Go cert
+	// verification error types.
+	ErrSecCertificateExpired = -67818
+	ErrSecHostNameMismatch   = -67602
+	ErrSecNotTrusted         = -67843
+)
+
 type OSStatus struct {
 	call   string
 	status int32
@@ -109,14 +117,6 @@
 }
 func x509_SecTrustSettingsCopyTrustSettings_trampoline()
 
-//go:cgo_import_dynamic x509_SecPolicyCopyProperties SecPolicyCopyProperties "/System/Library/Frameworks/Security.framework/Versions/A/Security"
-
-func SecPolicyCopyProperties(policy CFRef) CFRef {
-	ret := syscall(abi.FuncPCABI0(x509_SecPolicyCopyProperties_trampoline), uintptr(policy), 0, 0, 0, 0, 0)
-	return CFRef(ret)
-}
-func x509_SecPolicyCopyProperties_trampoline()
-
 //go:cgo_import_dynamic x509_SecTrustCreateWithCertificates SecTrustCreateWithCertificates "/System/Library/Frameworks/Security.framework/Versions/A/Security"
 
 func SecTrustCreateWithCertificates(certs CFRef, policies CFRef) (CFRef, error) {
@@ -147,14 +147,17 @@
 
 //go:cgo_import_dynamic x509_SecPolicyCreateSSL SecPolicyCreateSSL "/System/Library/Frameworks/Security.framework/Versions/A/Security"
 
-func SecPolicyCreateSSL(name string) CFRef {
+func SecPolicyCreateSSL(name string) (CFRef, error) {
 	var hostname CFString
 	if name != "" {
 		hostname = StringToCFString(name)
 		defer CFRelease(CFRef(hostname))
 	}
 	ret := syscall(abi.FuncPCABI0(x509_SecPolicyCreateSSL_trampoline), 1 /* true */, uintptr(hostname), 0, 0, 0, 0)
-	return CFRef(ret)
+	if ret == 0 {
+		return 0, OSStatus{"SecPolicyCreateSSL", int32(ret)}
+	}
+	return CFRef(ret), nil
 }
 func x509_SecPolicyCreateSSL_trampoline()
 
@@ -196,17 +199,18 @@
 
 //go:cgo_import_dynamic x509_SecTrustEvaluateWithError SecTrustEvaluateWithError "/System/Library/Frameworks/Security.framework/Versions/A/Security"
 
-func SecTrustEvaluateWithError(trustObj CFRef) error {
+func SecTrustEvaluateWithError(trustObj CFRef) (int, error) {
 	var errRef CFRef
 	ret := syscall(abi.FuncPCABI0(x509_SecTrustEvaluateWithError_trampoline), uintptr(trustObj), uintptr(unsafe.Pointer(&errRef)), 0, 0, 0, 0)
 	if int32(ret) != 1 {
 		errStr := CFErrorCopyDescription(errRef)
-		err := fmt.Errorf("x509: %s", CFStringToString(errStr))
+		err := errors.New(CFStringToString(errStr))
+		errCode := CFErrorGetCode(errRef)
 		CFRelease(errRef)
 		CFRelease(errStr)
-		return err
+		return errCode, err
 	}
-	return nil
+	return 0, nil
 }
 func x509_SecTrustEvaluateWithError_trampoline()
 
@@ -220,9 +224,12 @@
 
 //go:cgo_import_dynamic x509_SecTrustGetCertificateAtIndex SecTrustGetCertificateAtIndex "/System/Library/Frameworks/Security.framework/Versions/A/Security"
 
-func SecTrustGetCertificateAtIndex(trustObj CFRef, i int) CFRef {
+func SecTrustGetCertificateAtIndex(trustObj CFRef, i int) (CFRef, error) {
 	ret := syscall(abi.FuncPCABI0(x509_SecTrustGetCertificateAtIndex_trampoline), uintptr(trustObj), uintptr(i), 0, 0, 0, 0)
-	return CFRef(ret)
+	if ret == 0 {
+		return 0, OSStatus{"SecTrustGetCertificateAtIndex", int32(ret)}
+	}
+	return CFRef(ret), nil
 }
 func x509_SecTrustGetCertificateAtIndex_trampoline()
 
diff --git a/src/crypto/x509/internal/macos/security.s b/src/crypto/x509/internal/macos/security.s
index 36f814f..ed726f1 100644
--- a/src/crypto/x509/internal/macos/security.s
+++ b/src/crypto/x509/internal/macos/security.s
@@ -13,8 +13,6 @@
 	JMP	x509_SecTrustSettingsCopyCertificates(SB)
 TEXT ·x509_SecTrustSettingsCopyTrustSettings_trampoline(SB),NOSPLIT,$0-0
 	JMP	x509_SecTrustSettingsCopyTrustSettings(SB)
-TEXT ·x509_SecPolicyCopyProperties_trampoline(SB),NOSPLIT,$0-0
-	JMP	x509_SecPolicyCopyProperties(SB)
 TEXT ·x509_SecTrustCreateWithCertificates_trampoline(SB),NOSPLIT,$0-0
 	JMP x509_SecTrustCreateWithCertificates(SB)
 TEXT ·x509_SecCertificateCreateWithData_trampoline(SB),NOSPLIT,$0-0
diff --git a/src/crypto/x509/parser.go b/src/crypto/x509/parser.go
index a2d3d80..6ea3017 100644
--- a/src/crypto/x509/parser.go
+++ b/src/crypto/x509/parser.go
@@ -1,11 +1,13 @@
 // Copyright 2021 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
+
 package x509
 
 import (
 	"bytes"
 	"crypto/dsa"
+	"crypto/ecdh"
 	"crypto/ecdsa"
 	"crypto/ed25519"
 	"crypto/elliptic"
@@ -212,13 +214,15 @@
 	return ext, nil
 }
 
-func parsePublicKey(algo PublicKeyAlgorithm, keyData *publicKeyInfo) (any, error) {
+func parsePublicKey(keyData *publicKeyInfo) (any, error) {
+	oid := keyData.Algorithm.Algorithm
+	params := keyData.Algorithm.Parameters
 	der := cryptobyte.String(keyData.PublicKey.RightAlign())
-	switch algo {
-	case RSA:
+	switch {
+	case oid.Equal(oidPublicKeyRSA):
 		// RSA public keys must have a NULL in the parameters.
 		// See RFC 3279, Section 2.3.1.
-		if !bytes.Equal(keyData.Algorithm.Parameters.FullBytes, asn1.NullBytes) {
+		if !bytes.Equal(params.FullBytes, asn1.NullBytes) {
 			return nil, errors.New("x509: RSA key missing NULL parameters")
 		}
 
@@ -245,8 +249,8 @@
 			N: p.N,
 		}
 		return pub, nil
-	case ECDSA:
-		paramsDer := cryptobyte.String(keyData.Algorithm.Parameters.FullBytes)
+	case oid.Equal(oidPublicKeyECDSA):
+		paramsDer := cryptobyte.String(params.FullBytes)
 		namedCurveOID := new(asn1.ObjectIdentifier)
 		if !paramsDer.ReadASN1ObjectIdentifier(namedCurveOID) {
 			return nil, errors.New("x509: invalid ECDSA parameters")
@@ -265,17 +269,24 @@
 			Y:     y,
 		}
 		return pub, nil
-	case Ed25519:
+	case oid.Equal(oidPublicKeyEd25519):
 		// RFC 8410, Section 3
 		// > For all of the OIDs, the parameters MUST be absent.
-		if len(keyData.Algorithm.Parameters.FullBytes) != 0 {
+		if len(params.FullBytes) != 0 {
 			return nil, errors.New("x509: Ed25519 key encoded with illegal parameters")
 		}
 		if len(der) != ed25519.PublicKeySize {
 			return nil, errors.New("x509: wrong Ed25519 public key size")
 		}
 		return ed25519.PublicKey(der), nil
-	case DSA:
+	case oid.Equal(oidPublicKeyX25519):
+		// RFC 8410, Section 3
+		// > For all of the OIDs, the parameters MUST be absent.
+		if len(params.FullBytes) != 0 {
+			return nil, errors.New("x509: X25519 key encoded with illegal parameters")
+		}
+		return ecdh.X25519().NewPublicKey(der)
+	case oid.Equal(oidPublicKeyDSA):
 		y := new(big.Int)
 		if !der.ReadASN1Integer(y) {
 			return nil, errors.New("x509: invalid DSA public key")
@@ -288,7 +299,7 @@
 				G: new(big.Int),
 			},
 		}
-		paramsDer := cryptobyte.String(keyData.Algorithm.Parameters.FullBytes)
+		paramsDer := cryptobyte.String(params.FullBytes)
 		if !paramsDer.ReadASN1(&paramsDer, cryptobyte_asn1.SEQUENCE) ||
 			!paramsDer.ReadASN1Integer(pub.Parameters.P) ||
 			!paramsDer.ReadASN1Integer(pub.Parameters.Q) ||
@@ -301,7 +312,7 @@
 		}
 		return pub, nil
 	default:
-		return nil, nil
+		return nil, errors.New("x509: unknown public key algorithm")
 	}
 }
 
@@ -908,12 +919,14 @@
 	if !spki.ReadASN1BitString(&spk) {
 		return nil, errors.New("x509: malformed subjectPublicKey")
 	}
-	cert.PublicKey, err = parsePublicKey(cert.PublicKeyAlgorithm, &publicKeyInfo{
-		Algorithm: pkAI,
-		PublicKey: spk,
-	})
-	if err != nil {
-		return nil, err
+	if cert.PublicKeyAlgorithm != UnknownPublicKeyAlgorithm {
+		cert.PublicKey, err = parsePublicKey(&publicKeyInfo{
+			Algorithm: pkAI,
+			PublicKey: spk,
+		})
+		if err != nil {
+			return nil, err
+		}
 	}
 
 	if cert.Version > 1 {
diff --git a/src/crypto/x509/parser_test.go b/src/crypto/x509/parser_test.go
index d7cf7ea..b31f9cd 100644
--- a/src/crypto/x509/parser_test.go
+++ b/src/crypto/x509/parser_test.go
@@ -1,6 +1,7 @@
 // Copyright 2021 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
+
 package x509
 
 import (
diff --git a/src/crypto/x509/pkcs8.go b/src/crypto/x509/pkcs8.go
index d77efa3..2d085e0 100644
--- a/src/crypto/x509/pkcs8.go
+++ b/src/crypto/x509/pkcs8.go
@@ -5,6 +5,7 @@
 package x509
 
 import (
+	"crypto/ecdh"
 	"crypto/ecdsa"
 	"crypto/ed25519"
 	"crypto/rsa"
@@ -26,8 +27,9 @@
 
 // ParsePKCS8PrivateKey parses an unencrypted private key in PKCS #8, ASN.1 DER form.
 //
-// It returns a *rsa.PrivateKey, a *ecdsa.PrivateKey, or a ed25519.PrivateKey.
-// More types might be supported in the future.
+// It returns a *rsa.PrivateKey, a *ecdsa.PrivateKey, a ed25519.PrivateKey (not
+// a pointer), or a *ecdh.PrivateKey (for X25519). More types might be supported
+// in the future.
 //
 // This kind of key is commonly encoded in PEM blocks of type "PRIVATE KEY".
 func ParsePKCS8PrivateKey(der []byte) (key any, err error) {
@@ -74,6 +76,16 @@
 		}
 		return ed25519.NewKeyFromSeed(curvePrivateKey), nil
 
+	case privKey.Algo.Algorithm.Equal(oidPublicKeyX25519):
+		if l := len(privKey.Algo.Parameters.FullBytes); l != 0 {
+			return nil, errors.New("x509: invalid X25519 private key parameters")
+		}
+		var curvePrivateKey []byte
+		if _, err := asn1.Unmarshal(privKey.PrivateKey, &curvePrivateKey); err != nil {
+			return nil, fmt.Errorf("x509: invalid X25519 private key: %v", err)
+		}
+		return ecdh.X25519().NewPrivateKey(curvePrivateKey)
+
 	default:
 		return nil, fmt.Errorf("x509: PKCS#8 wrapping contained private key with unknown algorithm: %v", privKey.Algo.Algorithm)
 	}
@@ -81,8 +93,9 @@
 
 // MarshalPKCS8PrivateKey converts a private key to PKCS #8, ASN.1 DER form.
 //
-// The following key types are currently supported: *rsa.PrivateKey, *ecdsa.PrivateKey
-// and ed25519.PrivateKey. Unsupported key types result in an error.
+// The following key types are currently supported: *rsa.PrivateKey,
+// *ecdsa.PrivateKey, ed25519.PrivateKey (not a pointer), and *ecdh.PrivateKey.
+// Unsupported key types result in an error.
 //
 // This kind of key is commonly encoded in PEM blocks of type "PRIVATE KEY".
 func MarshalPKCS8PrivateKey(key any) ([]byte, error) {
@@ -101,19 +114,16 @@
 		if !ok {
 			return nil, errors.New("x509: unknown curve while marshaling to PKCS#8")
 		}
-
 		oidBytes, err := asn1.Marshal(oid)
 		if err != nil {
 			return nil, errors.New("x509: failed to marshal curve OID: " + err.Error())
 		}
-
 		privKey.Algo = pkix.AlgorithmIdentifier{
 			Algorithm: oidPublicKeyECDSA,
 			Parameters: asn1.RawValue{
 				FullBytes: oidBytes,
 			},
 		}
-
 		if privKey.PrivateKey, err = marshalECPrivateKeyWithOID(k, nil); err != nil {
 			return nil, errors.New("x509: failed to marshal EC private key while building PKCS#8: " + err.Error())
 		}
@@ -128,6 +138,35 @@
 		}
 		privKey.PrivateKey = curvePrivateKey
 
+	case *ecdh.PrivateKey:
+		if k.Curve() == ecdh.X25519() {
+			privKey.Algo = pkix.AlgorithmIdentifier{
+				Algorithm: oidPublicKeyX25519,
+			}
+			var err error
+			if privKey.PrivateKey, err = asn1.Marshal(k.Bytes()); err != nil {
+				return nil, fmt.Errorf("x509: failed to marshal private key: %v", err)
+			}
+		} else {
+			oid, ok := oidFromECDHCurve(k.Curve())
+			if !ok {
+				return nil, errors.New("x509: unknown curve while marshaling to PKCS#8")
+			}
+			oidBytes, err := asn1.Marshal(oid)
+			if err != nil {
+				return nil, errors.New("x509: failed to marshal curve OID: " + err.Error())
+			}
+			privKey.Algo = pkix.AlgorithmIdentifier{
+				Algorithm: oidPublicKeyECDSA,
+				Parameters: asn1.RawValue{
+					FullBytes: oidBytes,
+				},
+			}
+			if privKey.PrivateKey, err = marshalECDHPrivateKey(k); err != nil {
+				return nil, errors.New("x509: failed to marshal EC private key while building PKCS#8: " + err.Error())
+			}
+		}
+
 	default:
 		return nil, fmt.Errorf("x509: unknown key type while marshaling PKCS#8: %T", key)
 	}
diff --git a/src/crypto/x509/pkcs8_test.go b/src/crypto/x509/pkcs8_test.go
index aaceced..d032880 100644
--- a/src/crypto/x509/pkcs8_test.go
+++ b/src/crypto/x509/pkcs8_test.go
@@ -6,6 +6,7 @@
 
 import (
 	"bytes"
+	"crypto/ecdh"
 	"crypto/ecdsa"
 	"crypto/ed25519"
 	"crypto/elliptic"
@@ -49,6 +50,11 @@
 // From RFC 8410, Section 7.
 var pkcs8Ed25519PrivateKeyHex = `302e020100300506032b657004220420d4ee72dbf913584ad5b6d8f1f769f8ad3afe7c28cbf1d4fbe097a88f44755842`
 
+// Generated using:
+//
+//	openssl genpkey -algorithm x25519
+var pkcs8X25519PrivateKeyHex = `302e020100300506032b656e0422042068ff93a73c5adefd6d498b24e588fd4daa10924d992afed01b43ca5725025a6b`
+
 func TestPKCS8(t *testing.T) {
 	tests := []struct {
 		name    string
@@ -90,6 +96,11 @@
 			keyHex:  pkcs8Ed25519PrivateKeyHex,
 			keyType: reflect.TypeOf(ed25519.PrivateKey{}),
 		},
+		{
+			name:    "X25519 private key",
+			keyHex:  pkcs8X25519PrivateKeyHex,
+			keyType: reflect.TypeOf(&ecdh.PrivateKey{}),
+		},
 	}
 
 	for _, test := range tests {
@@ -120,6 +131,25 @@
 			t.Errorf("%s: marshaled PKCS#8 didn't match original: got %x, want %x", test.name, reserialised, derBytes)
 			continue
 		}
+
+		if ecKey, isEC := privKey.(*ecdsa.PrivateKey); isEC {
+			ecdhKey, err := ecKey.ECDH()
+			if err != nil {
+				if ecKey.Curve != elliptic.P224() {
+					t.Errorf("%s: failed to convert to ecdh: %s", test.name, err)
+				}
+				continue
+			}
+			reserialised, err := MarshalPKCS8PrivateKey(ecdhKey)
+			if err != nil {
+				t.Errorf("%s: failed to marshal into PKCS#8: %s", test.name, err)
+				continue
+			}
+			if !bytes.Equal(derBytes, reserialised) {
+				t.Errorf("%s: marshaled PKCS#8 didn't match original: got %x, want %x", test.name, reserialised, derBytes)
+				continue
+			}
+		}
 	}
 }
 
diff --git a/src/crypto/x509/root.go b/src/crypto/x509/root.go
index 91f4d29..d6b07a1 100644
--- a/src/crypto/x509/root.go
+++ b/src/crypto/x509/root.go
@@ -4,29 +4,69 @@
 
 package x509
 
-// To update the embedded iOS root store, update the -version
-// argument to the latest security_certificates version from
-// https://opensource.apple.com/source/security_certificates/
-// and run "go generate". See https://golang.org/issue/38843.
-//
-//go:generate go run root_ios_gen.go -version 55188.120.1.0.1
-
-import "sync"
+import (
+	"internal/godebug"
+	"sync"
+)
 
 var (
 	once           sync.Once
+	systemRootsMu  sync.RWMutex
 	systemRoots    *CertPool
 	systemRootsErr error
+	fallbacksSet   bool
 )
 
 func systemRootsPool() *CertPool {
 	once.Do(initSystemRoots)
+	systemRootsMu.RLock()
+	defer systemRootsMu.RUnlock()
 	return systemRoots
 }
 
 func initSystemRoots() {
+	systemRootsMu.Lock()
+	defer systemRootsMu.Unlock()
 	systemRoots, systemRootsErr = loadSystemRoots()
 	if systemRootsErr != nil {
 		systemRoots = nil
 	}
 }
+
+var forceFallback = godebug.New("x509usefallbackroots")
+
+// SetFallbackRoots sets the roots to use during certificate verification, if no
+// custom roots are specified and a platform verifier or a system certificate
+// pool is not available (for instance in a container which does not have a root
+// certificate bundle). SetFallbackRoots will panic if roots is nil.
+//
+// SetFallbackRoots may only be called once, if called multiple times it will
+// panic.
+//
+// The fallback behavior can be forced on all platforms, even when there is a
+// system certificate pool, by setting GODEBUG=x509usefallbackroots=1 (note that
+// on Windows and macOS this will disable usage of the platform verification
+// APIs and cause the pure Go verifier to be used). Setting
+// x509usefallbackroots=1 without calling SetFallbackRoots has no effect.
+func SetFallbackRoots(roots *CertPool) {
+	if roots == nil {
+		panic("roots must be non-nil")
+	}
+
+	// trigger initSystemRoots if it hasn't already been called before we
+	// take the lock
+	_ = systemRootsPool()
+
+	systemRootsMu.Lock()
+	defer systemRootsMu.Unlock()
+
+	if fallbacksSet {
+		panic("SetFallbackRoots has already been called")
+	}
+	fallbacksSet = true
+
+	if systemRoots != nil && (systemRoots.len() > 0 || systemRoots.systemPool) && forceFallback.Value() != "1" {
+		return
+	}
+	systemRoots, systemRootsErr = roots, nil
+}
diff --git a/src/crypto/x509/root_darwin.go b/src/crypto/x509/root_darwin.go
index 4759462..469e907 100644
--- a/src/crypto/x509/root_darwin.go
+++ b/src/crypto/x509/root_darwin.go
@@ -7,6 +7,7 @@
 import (
 	macOS "crypto/x509/internal/macos"
 	"errors"
+	"fmt"
 )
 
 func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) {
@@ -24,15 +25,19 @@
 				return nil, err
 			}
 			sc, err := macOS.SecCertificateCreateWithData(c.Raw)
-			if err == nil {
-				macOS.CFArrayAppendValue(certs, sc)
+			if err != nil {
+				return nil, err
 			}
+			macOS.CFArrayAppendValue(certs, sc)
 		}
 	}
 
 	policies := macOS.CFArrayCreateMutable()
 	defer macOS.ReleaseCFArray(policies)
-	sslPolicy := macOS.SecPolicyCreateSSL(opts.DNSName)
+	sslPolicy, err := macOS.SecPolicyCreateSSL(opts.DNSName)
+	if err != nil {
+		return nil, err
+	}
 	macOS.CFArrayAppendValue(policies, sslPolicy)
 
 	trustObj, err := macOS.SecTrustCreateWithCertificates(certs, policies)
@@ -54,14 +59,26 @@
 	// always enforce its SCT requirements, and there are still _some_ people
 	// using TLS or OCSP for that.
 
-	if err := macOS.SecTrustEvaluateWithError(trustObj); err != nil {
-		return nil, err
+	if ret, err := macOS.SecTrustEvaluateWithError(trustObj); err != nil {
+		switch ret {
+		case macOS.ErrSecCertificateExpired:
+			return nil, CertificateInvalidError{c, Expired, err.Error()}
+		case macOS.ErrSecHostNameMismatch:
+			return nil, HostnameError{c, opts.DNSName}
+		case macOS.ErrSecNotTrusted:
+			return nil, UnknownAuthorityError{Cert: c}
+		default:
+			return nil, fmt.Errorf("x509: %s", err)
+		}
 	}
 
 	chain := [][]*Certificate{{}}
 	numCerts := macOS.SecTrustGetCertificateCount(trustObj)
 	for i := 0; i < numCerts; i++ {
-		certRef := macOS.SecTrustGetCertificateAtIndex(trustObj, i)
+		certRef, err := macOS.SecTrustGetCertificateAtIndex(trustObj, i)
+		if err != nil {
+			return nil, err
+		}
 		cert, err := exportCertificate(certRef)
 		if err != nil {
 			return nil, err
diff --git a/src/crypto/x509/root_darwin_test.go b/src/crypto/x509/root_darwin_test.go
index 90a464f..299cecf 100644
--- a/src/crypto/x509/root_darwin_test.go
+++ b/src/crypto/x509/root_darwin_test.go
@@ -42,23 +42,23 @@
 		{
 			name:        "expired leaf",
 			host:        "expired.badssl.com",
-			expectedErr: "x509: “*.badssl.com” certificate is expired",
+			expectedErr: "x509: certificate has expired or is not yet valid: “*.badssl.com” certificate is expired",
 		},
 		{
 			name:        "wrong host for leaf",
 			host:        "wrong.host.badssl.com",
 			verifyName:  "wrong.host.badssl.com",
-			expectedErr: "x509: “*.badssl.com” certificate name does not match input",
+			expectedErr: "x509: certificate is valid for *.badssl.com, badssl.com, not wrong.host.badssl.com",
 		},
 		{
 			name:        "self-signed leaf",
 			host:        "self-signed.badssl.com",
-			expectedErr: "x509: “*.badssl.com” certificate is not trusted",
+			expectedErr: "x509: certificate signed by unknown authority",
 		},
 		{
 			name:        "untrusted root",
 			host:        "untrusted-root.badssl.com",
-			expectedErr: "x509: “BadSSL Untrusted Root Certificate Authority” certificate is not trusted",
+			expectedErr: "x509: certificate signed by unknown authority",
 		},
 		{
 			name:        "revoked leaf",
@@ -74,7 +74,7 @@
 			name:        "expired leaf (custom time)",
 			host:        "google.com",
 			verifyTime:  time.Time{}.Add(time.Hour),
-			expectedErr: "x509: “*.google.com” certificate is expired",
+			expectedErr: "x509: certificate has expired or is not yet valid: “*.google.com” certificate is expired",
 		},
 		{
 			name:       "valid chain (custom time)",
diff --git a/src/crypto/x509/root_test.go b/src/crypto/x509/root_test.go
new file mode 100644
index 0000000..94ee6a6
--- /dev/null
+++ b/src/crypto/x509/root_test.go
@@ -0,0 +1,108 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package x509
+
+import (
+	"testing"
+)
+
+func TestFallbackPanic(t *testing.T) {
+	defer func() {
+		if recover() == nil {
+			t.Fatal("Multiple calls to SetFallbackRoots should panic")
+		}
+	}()
+	SetFallbackRoots(nil)
+	SetFallbackRoots(nil)
+}
+
+func TestFallback(t *testing.T) {
+	// call systemRootsPool so that the sync.Once is triggered, and we can
+	// manipulate systemRoots without worrying about our working being overwritten
+	systemRootsPool()
+	if systemRoots != nil {
+		originalSystemRoots := *systemRoots
+		defer func() { systemRoots = &originalSystemRoots }()
+	}
+
+	tests := []struct {
+		name            string
+		systemRoots     *CertPool
+		systemPool      bool
+		poolContent     []*Certificate
+		forceFallback   bool
+		returnsFallback bool
+	}{
+		{
+			name:            "nil systemRoots",
+			returnsFallback: true,
+		},
+		{
+			name:            "empty systemRoots",
+			systemRoots:     NewCertPool(),
+			returnsFallback: true,
+		},
+		{
+			name:        "empty systemRoots system pool",
+			systemRoots: NewCertPool(),
+			systemPool:  true,
+		},
+		{
+			name:        "filled systemRoots system pool",
+			systemRoots: NewCertPool(),
+			poolContent: []*Certificate{{}},
+			systemPool:  true,
+		},
+		{
+			name:        "filled systemRoots",
+			systemRoots: NewCertPool(),
+			poolContent: []*Certificate{{}},
+		},
+		{
+			name:            "filled systemRoots, force fallback",
+			systemRoots:     NewCertPool(),
+			poolContent:     []*Certificate{{}},
+			forceFallback:   true,
+			returnsFallback: true,
+		},
+		{
+			name:            "filled systemRoot system pool, force fallback",
+			systemRoots:     NewCertPool(),
+			poolContent:     []*Certificate{{}},
+			systemPool:      true,
+			forceFallback:   true,
+			returnsFallback: true,
+		},
+	}
+
+	for _, tc := range tests {
+		t.Run(tc.name, func(t *testing.T) {
+			fallbacksSet = false
+			systemRoots = tc.systemRoots
+			if systemRoots != nil {
+				systemRoots.systemPool = tc.systemPool
+			}
+			for _, c := range tc.poolContent {
+				systemRoots.AddCert(c)
+			}
+			if tc.forceFallback {
+				t.Setenv("GODEBUG", "x509usefallbackroots=1")
+			} else {
+				t.Setenv("GODEBUG", "x509usefallbackroots=0")
+			}
+
+			fallbackPool := NewCertPool()
+			SetFallbackRoots(fallbackPool)
+
+			systemPoolIsFallback := systemRoots == fallbackPool
+
+			if tc.returnsFallback && !systemPoolIsFallback {
+				t.Error("systemRoots was not set to fallback pool")
+			} else if !tc.returnsFallback && systemPoolIsFallback {
+				t.Error("systemRoots was set to fallback pool when it shouldn't have been")
+			}
+		})
+	}
+}
diff --git a/src/crypto/x509/root_unix_test.go b/src/crypto/x509/root_unix_test.go
index 7197a0d..d5215b9 100644
--- a/src/crypto/x509/root_unix_test.go
+++ b/src/crypto/x509/root_unix_test.go
@@ -149,7 +149,7 @@
 	tmpDir := t.TempDir()
 
 	rootPEMs := []string{
-		geoTrustRoot,
+		gtsRoot,
 		googleLeaf,
 		startComRoot,
 	}
diff --git a/src/crypto/x509/root_windows.go b/src/crypto/x509/root_windows.go
index d65d876..76d6e6a 100644
--- a/src/crypto/x509/root_windows.go
+++ b/src/crypto/x509/root_windows.go
@@ -5,6 +5,7 @@
 package x509
 
 import (
+	"bytes"
 	"errors"
 	"syscall"
 	"unsafe"
@@ -69,15 +70,14 @@
 		return nil, errors.New("x509: invalid simple chain")
 	}
 
-	simpleChains := (*[1 << 20]*syscall.CertSimpleChain)(unsafe.Pointer(simpleChain))[:count:count]
+	simpleChains := unsafe.Slice(simpleChain, count)
 	lastChain := simpleChains[count-1]
-	elements := (*[1 << 20]*syscall.CertChainElement)(unsafe.Pointer(lastChain.Elements))[:lastChain.NumElements:lastChain.NumElements]
+	elements := unsafe.Slice(lastChain.Elements, lastChain.NumElements)
 	for i := 0; i < int(lastChain.NumElements); i++ {
 		// Copy the buf, since ParseCertificate does not create its own copy.
 		cert := elements[i].CertContext
-		encodedCert := (*[1 << 20]byte)(unsafe.Pointer(cert.EncodedCert))[:cert.Length:cert.Length]
-		buf := make([]byte, cert.Length)
-		copy(buf, encodedCert)
+		encodedCert := unsafe.Slice(cert.EncodedCert, cert.Length)
+		buf := bytes.Clone(encodedCert)
 		parsedCert, err := ParseCertificate(buf)
 		if err != nil {
 			return nil, err
@@ -258,8 +258,7 @@
 	}
 
 	if lqCtxCount := topCtx.LowerQualityChainCount; lqCtxCount > 0 {
-		lqCtxs := (*[1 << 20]*syscall.CertChainContext)(unsafe.Pointer(topCtx.LowerQualityChains))[:lqCtxCount:lqCtxCount]
-
+		lqCtxs := unsafe.Slice(topCtx.LowerQualityChains, lqCtxCount)
 		for _, ctx := range lqCtxs {
 			chain, err := verifyChain(c, ctx, opts)
 			if err == nil {
diff --git a/src/crypto/x509/sec1.go b/src/crypto/x509/sec1.go
index 8053ff5..027c17c 100644
--- a/src/crypto/x509/sec1.go
+++ b/src/crypto/x509/sec1.go
@@ -5,6 +5,7 @@
 package x509
 
 import (
+	"crypto/ecdh"
 	"crypto/ecdsa"
 	"crypto/elliptic"
 	"encoding/asn1"
@@ -51,9 +52,12 @@
 	return marshalECPrivateKeyWithOID(key, oid)
 }
 
-// marshalECPrivateKey marshals an EC private key into ASN.1, DER format and
+// marshalECPrivateKeyWithOID marshals an EC private key into ASN.1, DER format and
 // sets the curve ID to the given OID, or omits it if OID is nil.
 func marshalECPrivateKeyWithOID(key *ecdsa.PrivateKey, oid asn1.ObjectIdentifier) ([]byte, error) {
+	if !key.Curve.IsOnCurve(key.X, key.Y) {
+		return nil, errors.New("invalid elliptic key public key")
+	}
 	privateKey := make([]byte, (key.Curve.Params().N.BitLen()+7)/8)
 	return asn1.Marshal(ecPrivateKey{
 		Version:       1,
@@ -63,6 +67,16 @@
 	})
 }
 
+// marshalECPrivateKeyWithOID marshals an EC private key into ASN.1, DER format
+// suitable for NIST curves.
+func marshalECDHPrivateKey(key *ecdh.PrivateKey) ([]byte, error) {
+	return asn1.Marshal(ecPrivateKey{
+		Version:    1,
+		PrivateKey: key.Bytes(),
+		PublicKey:  asn1.BitString{Bytes: key.PublicKey().Bytes()},
+	})
+}
+
 // parseECPrivateKey parses an ASN.1 Elliptic Curve Private Key Structure.
 // The OID for the named curve may be provided from another source (such as
 // the PKCS8 container) - if it is provided then use this instead of the OID
diff --git a/src/crypto/x509/verify.go b/src/crypto/x509/verify.go
index c49335d..0b01f8b 100644
--- a/src/crypto/x509/verify.go
+++ b/src/crypto/x509/verify.go
@@ -745,6 +745,8 @@
 // Certificates that use SHA1WithRSA and ECDSAWithSHA1 signatures are not supported,
 // and will not be used to build chains.
 //
+// Certificates other than c in the returned chains should not be modified.
+//
 // WARNING: this function doesn't do any revocation checking.
 func (c *Certificate) Verify(opts VerifyOptions) (chains [][]*Certificate, err error) {
 	// Platform-specific verification needs the ASN.1 contents so
@@ -764,7 +766,10 @@
 
 	// Use platform verifiers, where available, if Roots is from SystemCertPool.
 	if runtime.GOOS == "windows" || runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
-		if opts.Roots == nil {
+		// Don't use the system verifier if the system pool was replaced with a non-system pool,
+		// i.e. if SetFallbackRoots was called with x509usefallbackroots=1.
+		systemPool := systemRootsPool()
+		if opts.Roots == nil && (systemPool == nil || systemPool.systemPool) {
 			return c.systemVerify(&opts)
 		}
 		if opts.Roots != nil && opts.Roots.systemPool {
@@ -920,6 +925,10 @@
 
 		err = candidate.isValid(certType, currentChain, opts)
 		if err != nil {
+			if hintErr == nil {
+				hintErr = err
+				hintCert = candidate
+			}
 			return
 		}
 
diff --git a/src/crypto/x509/verify_test.go b/src/crypto/x509/verify_test.go
index 7bc58d4..164c47f 100644
--- a/src/crypto/x509/verify_test.go
+++ b/src/crypto/x509/verify_test.go
@@ -43,33 +43,33 @@
 	{
 		name:          "Valid",
 		leaf:          googleLeaf,
-		intermediates: []string{giag2Intermediate},
-		roots:         []string{geoTrustRoot},
-		currentTime:   1395785200,
+		intermediates: []string{gtsIntermediate},
+		roots:         []string{gtsRoot},
+		currentTime:   1677615892,
 		dnsName:       "www.google.com",
 
 		expectedChains: [][]string{
-			{"Google", "Google Internet Authority", "GeoTrust"},
+			{"www.google.com", "GTS CA 1C3", "GTS Root R1"},
 		},
 	},
 	{
 		name:          "MixedCase",
 		leaf:          googleLeaf,
-		intermediates: []string{giag2Intermediate},
-		roots:         []string{geoTrustRoot},
-		currentTime:   1395785200,
+		intermediates: []string{gtsIntermediate},
+		roots:         []string{gtsRoot},
+		currentTime:   1677615892,
 		dnsName:       "WwW.GooGLE.coM",
 
 		expectedChains: [][]string{
-			{"Google", "Google Internet Authority", "GeoTrust"},
+			{"www.google.com", "GTS CA 1C3", "GTS Root R1"},
 		},
 	},
 	{
 		name:          "HostnameMismatch",
 		leaf:          googleLeaf,
-		intermediates: []string{giag2Intermediate},
-		roots:         []string{geoTrustRoot},
-		currentTime:   1395785200,
+		intermediates: []string{gtsIntermediate},
+		roots:         []string{gtsRoot},
+		currentTime:   1677615892,
 		dnsName:       "www.example.com",
 
 		errorCallback: expectHostnameError("certificate is valid for"),
@@ -77,9 +77,9 @@
 	{
 		name:          "IPMissing",
 		leaf:          googleLeaf,
-		intermediates: []string{giag2Intermediate},
-		roots:         []string{geoTrustRoot},
-		currentTime:   1395785200,
+		intermediates: []string{gtsIntermediate},
+		roots:         []string{gtsRoot},
+		currentTime:   1677615892,
 		dnsName:       "1.2.3.4",
 
 		errorCallback: expectHostnameError("doesn't contain any IP SANs"),
@@ -87,8 +87,8 @@
 	{
 		name:          "Expired",
 		leaf:          googleLeaf,
-		intermediates: []string{giag2Intermediate},
-		roots:         []string{geoTrustRoot},
+		intermediates: []string{gtsIntermediate},
+		roots:         []string{gtsRoot},
 		currentTime:   1,
 		dnsName:       "www.example.com",
 
@@ -97,8 +97,8 @@
 	{
 		name:        "MissingIntermediate",
 		leaf:        googleLeaf,
-		roots:       []string{geoTrustRoot},
-		currentTime: 1395785200,
+		roots:       []string{gtsRoot},
+		currentTime: 1677615892,
 		dnsName:     "www.google.com",
 
 		// Skip when using systemVerify, since Windows
@@ -109,13 +109,13 @@
 	{
 		name:          "RootInIntermediates",
 		leaf:          googleLeaf,
-		intermediates: []string{geoTrustRoot, giag2Intermediate},
-		roots:         []string{geoTrustRoot},
-		currentTime:   1395785200,
+		intermediates: []string{gtsRoot, gtsIntermediate},
+		roots:         []string{gtsRoot},
+		currentTime:   1677615892,
 		dnsName:       "www.google.com",
 
 		expectedChains: [][]string{
-			{"Google", "Google Internet Authority", "GeoTrust"},
+			{"www.google.com", "GTS CA 1C3", "GTS Root R1"},
 		},
 		// CAPI doesn't build the chain with the duplicated GeoTrust
 		// entry so the results don't match.
@@ -163,9 +163,9 @@
 	{
 		name:          "InvalidHash",
 		leaf:          googleLeafWithInvalidHash,
-		intermediates: []string{giag2Intermediate},
-		roots:         []string{geoTrustRoot},
-		currentTime:   1395785200,
+		intermediates: []string{gtsIntermediate},
+		roots:         []string{gtsRoot},
+		currentTime:   1677615892,
 		dnsName:       "www.google.com",
 
 		// The specific error message may not occur when using system
@@ -230,21 +230,20 @@
 		// Check that SHA-384 intermediates (which are popping up)
 		// work.
 		name:          "SHA-384",
-		leaf:          moipLeafCert,
-		intermediates: []string{comodoIntermediateSHA384, comodoRSAAuthority},
-		roots:         []string{addTrustRoot},
-		currentTime:   1397502195,
-		dnsName:       "api.moip.com.br",
+		leaf:          trustAsiaLeaf,
+		intermediates: []string{trustAsiaSHA384Intermediate},
+		roots:         []string{digicertRoot},
+		currentTime:   1558051200,
+		dnsName:       "tm.cn",
 
 		// CryptoAPI can find alternative validation paths.
 		systemLax: true,
 
 		expectedChains: [][]string{
 			{
-				"api.moip.com.br",
-				"COMODO RSA Extended Validation Secure Server CA",
-				"COMODO RSA Certification Authority",
-				"AddTrust External CA Root",
+				"tm.cn",
+				"TrustAsia ECC OV TLS Pro CA",
+				"DigiCert Global Root CA",
 			},
 		},
 	},
@@ -543,8 +542,8 @@
 func TestGoVerify(t *testing.T) {
 	// Temporarily enable SHA-1 verification since a number of test chains
 	// require it. TODO(filippo): regenerate test chains.
-	defer func(old bool) { debugAllowSHA1 = old }(debugAllowSHA1)
-	debugAllowSHA1 = true
+	t.Setenv("GODEBUG", "x509sha1=1")
+
 	for _, test := range verifyTests {
 		t.Run(test.name, func(t *testing.T) {
 			testVerify(t, test, false)
@@ -582,106 +581,135 @@
 	return strings.Join(name.Country, ",") + "/" + strings.Join(name.Organization, ",") + "/" + strings.Join(name.OrganizationalUnit, ",") + "/" + name.CommonName
 }
 
-const geoTrustRoot = `-----BEGIN CERTIFICATE-----
-MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
-MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
-YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG
-EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg
-R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9
-9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq
-fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv
-iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU
-1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+
-bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW
-MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA
-ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l
-uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn
-Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS
-tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF
-PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un
-hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV
-5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==
+const gtsIntermediate = `-----BEGIN CERTIFICATE-----
+MIIFljCCA36gAwIBAgINAgO8U1lrNMcY9QFQZjANBgkqhkiG9w0BAQsFADBHMQsw
+CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU
+MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMjAwODEzMDAwMDQyWhcNMjcwOTMwMDAw
+MDQyWjBGMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp
+Y2VzIExMQzETMBEGA1UEAxMKR1RTIENBIDFDMzCCASIwDQYJKoZIhvcNAQEBBQAD
+ggEPADCCAQoCggEBAPWI3+dijB43+DdCkH9sh9D7ZYIl/ejLa6T/belaI+KZ9hzp
+kgOZE3wJCor6QtZeViSqejOEH9Hpabu5dOxXTGZok3c3VVP+ORBNtzS7XyV3NzsX
+lOo85Z3VvMO0Q+sup0fvsEQRY9i0QYXdQTBIkxu/t/bgRQIh4JZCF8/ZK2VWNAcm
+BA2o/X3KLu/qSHw3TT8An4Pf73WELnlXXPxXbhqW//yMmqaZviXZf5YsBvcRKgKA
+gOtjGDxQSYflispfGStZloEAoPtR28p3CwvJlk/vcEnHXG0g/Zm0tOLKLnf9LdwL
+tmsTDIwZKxeWmLnwi/agJ7u2441Rj72ux5uxiZ0CAwEAAaOCAYAwggF8MA4GA1Ud
+DwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwEgYDVR0T
+AQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUinR/r4XN7pXNPZzQ4kYU83E1HScwHwYD
+VR0jBBgwFoAU5K8rJnEaK0gnhS9SZizv8IkTcT4waAYIKwYBBQUHAQEEXDBaMCYG
+CCsGAQUFBzABhhpodHRwOi8vb2NzcC5wa2kuZ29vZy9ndHNyMTAwBggrBgEFBQcw
+AoYkaHR0cDovL3BraS5nb29nL3JlcG8vY2VydHMvZ3RzcjEuZGVyMDQGA1UdHwQt
+MCswKaAnoCWGI2h0dHA6Ly9jcmwucGtpLmdvb2cvZ3RzcjEvZ3RzcjEuY3JsMFcG
+A1UdIARQME4wOAYKKwYBBAHWeQIFAzAqMCgGCCsGAQUFBwIBFhxodHRwczovL3Br
+aS5nb29nL3JlcG9zaXRvcnkvMAgGBmeBDAECATAIBgZngQwBAgIwDQYJKoZIhvcN
+AQELBQADggIBAIl9rCBcDDy+mqhXlRu0rvqrpXJxtDaV/d9AEQNMwkYUuxQkq/BQ
+cSLbrcRuf8/xam/IgxvYzolfh2yHuKkMo5uhYpSTld9brmYZCwKWnvy15xBpPnrL
+RklfRuFBsdeYTWU0AIAaP0+fbH9JAIFTQaSSIYKCGvGjRFsqUBITTcFTNvNCCK9U
++o53UxtkOCcXCb1YyRt8OS1b887U7ZfbFAO/CVMkH8IMBHmYJvJh8VNS/UKMG2Yr
+PxWhu//2m+OBmgEGcYk1KCTd4b3rGS3hSMs9WYNRtHTGnXzGsYZbr8w0xNPM1IER
+lQCh9BIiAfq0g3GvjLeMcySsN1PCAJA/Ef5c7TaUEDu9Ka7ixzpiO2xj2YC/WXGs
+Yye5TBeg2vZzFb8q3o/zpWwygTMD0IZRcZk0upONXbVRWPeyk+gB9lm+cZv9TSjO
+z23HFtz30dZGm6fKa+l3D/2gthsjgx0QGtkJAITgRNOidSOzNIb2ILCkXhAd4FJG
+AJ2xDx8hcFH1mt0G/FX0Kw4zd8NLQsLxdxP8c4CU6x+7Nz/OAipmsHMdMqUybDKw
+juDEI/9bfU1lcKwrmz3O2+BtjjKAvpafkmO8l7tdufThcV4q5O8DIrGKZTqPwJNl
+1IXNDw9bg1kWRxYtnCQ6yICmJhSFm/Y3m6xv+cXDBlHz4n/FsRC6UfTd
 -----END CERTIFICATE-----`
 
-const giag2Intermediate = `-----BEGIN CERTIFICATE-----
-MIIEBDCCAuygAwIBAgIDAjppMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
-MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
-YWwgQ0EwHhcNMTMwNDA1MTUxNTU1WhcNMTUwNDA0MTUxNTU1WjBJMQswCQYDVQQG
-EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy
-bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
-AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP
-VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv
-h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE
-ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ
-EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC
-DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB+zCB+DAfBgNVHSMEGDAWgBTAephojYn7
-qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wEgYD
-VR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMwMTAvoC2g
-K4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9ndGdsb2JhbC5jcmwwPQYI
-KwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwOi8vZ3RnbG9iYWwtb2NzcC5n
-ZW90cnVzdC5jb20wFwYDVR0gBBAwDjAMBgorBgEEAdZ5AgUBMA0GCSqGSIb3DQEB
-BQUAA4IBAQA21waAESetKhSbOHezI6B1WLuxfoNCunLaHtiONgaX4PCVOzf9G0JY
-/iLIa704XtE7JW4S615ndkZAkNoUyHgN7ZVm2o6Gb4ChulYylYbc3GrKBIxbf/a/
-zG+FA1jDaFETzf3I93k9mTXwVqO94FntT0QJo544evZG0R0SnU++0ED8Vf4GXjza
-HFa9llF7b1cq26KqltyMdMKVvvBulRP/F/A8rLIQjcxz++iPAsbw+zOzlTvjwsto
-WHPbqCRiOwY1nQ2pM714A5AuTHhdUDqB1O6gyHA43LL5Z/qHQF1hwFGPa4NrzQU6
-yuGnBXj8ytqU0CwIPX4WecigUCAkVDNx
+const gtsRoot = `-----BEGIN CERTIFICATE-----
+MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw
+CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU
+MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw
+MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp
+Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA
+A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo
+27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w
+Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw
+TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl
+qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH
+szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8
+Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk
+MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92
+wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p
+aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN
+VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID
+AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E
+FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb
+C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe
+QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy
+h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4
+7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J
+ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef
+MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/
+Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT
+6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ
+0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm
+2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb
+bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c
 -----END CERTIFICATE-----`
 
 const googleLeaf = `-----BEGIN CERTIFICATE-----
-MIIEdjCCA16gAwIBAgIIcR5k4dkoe04wDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UE
-BhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2dsZSBJbnRl
-cm5ldCBBdXRob3JpdHkgRzIwHhcNMTQwMzEyMDkzODMwWhcNMTQwNjEwMDAwMDAw
-WjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwN
-TW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UEAwwOd3d3
-Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC4zYCe
-m0oUBhwE0EwBr65eBOcgcQO2PaSIAB2dEP/c1EMX2tOy0ov8rk83ePhJ+MWdT1z6
-jge9X4zQQI8ZyA9qIiwrKBZOi8DNUvrqNZC7fJAVRrb9aX/99uYOJCypIbpmWG1q
-fhbHjJewhwf8xYPj71eU4rLG80a+DapWmphtfq3h52lDQIBzLVf1yYbyrTaELaz4
-NXF7HXb5YkId/gxIsSzM0aFUVu2o8sJcLYAsJqwfFKBKOMxUcn545nlspf0mTcWZ
-0APlbwsKznNs4/xCDwIxxWjjqgHrYAFl6y07i1gzbAOqdNEyR24p+3JWI8WZBlBI
-dk2KGj0W1fIfsvyxAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEFBQcDAQYI
-KwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYBBQUHAQEE
-XDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3J0
-MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9vY3NwMB0G
-A1UdDgQWBBTXD5Bx6iqT+dmEhbFL4OUoHyZn8zAMBgNVHRMBAf8EAjAAMB8GA1Ud
-IwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYKKwYBBAHW
-eQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB
-RzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCR3RJtHzgDh33b/MI1ugiki+nl8Ikj
-5larbJRE/rcA5oite+QJyAr6SU1gJJ/rRrK3ItVEHr9L621BCM7GSdoNMjB9MMcf
-tJAW0kYGJ+wqKm53wG/JaOADTnnq2Mt/j6F2uvjgN/ouns1nRHufIvd370N0LeH+
-orKqTuAPzXK7imQk6+OycYABbqCtC/9qmwRd8wwn7sF97DtYfK8WuNHtFalCAwyi
-8LxJJYJCLWoMhZ+V8GZm+FOex5qkQAjnZrtNlbQJ8ro4r+rpKXtmMFFhfa+7L+PA
-Kom08eUK8skxAzfDDijZPh10VtJ66uBoiDPdT+uCBehcBIcmSTrKjFGX
+MIIFUjCCBDqgAwIBAgIQERmRWTzVoz0SMeozw2RM3DANBgkqhkiG9w0BAQsFADBG
+MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM
+QzETMBEGA1UEAxMKR1RTIENBIDFDMzAeFw0yMzAxMDIwODE5MTlaFw0yMzAzMjcw
+ODE5MThaMBkxFzAVBgNVBAMTDnd3dy5nb29nbGUuY29tMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAq30odrKMT54TJikMKL8S+lwoCMT5geP0u9pWjk6a
+wdB6i3kO+UE4ijCAmhbcZKeKaLnGJ38weZNwB1ayabCYyX7hDiC/nRcZU49LX5+o
+55kDVaNn14YKkg2kCeX25HDxSwaOsNAIXKPTqiQL5LPvc4Twhl8HY51hhNWQrTEr
+N775eYbixEULvyVLq5BLbCOpPo8n0/MTjQ32ku1jQq3GIYMJC/Rf2VW5doF6t9zs
+KleflAN8OdKp0ME9OHg0T1P3yyb67T7n0SpisHbeG06AmQcKJF9g/9VPJtRf4l1Q
+WRPDC+6JUqzXCxAGmIRGZ7TNMxPMBW/7DRX6w8oLKVNb0wIDAQABo4ICZzCCAmMw
+DgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQC
+MAAwHQYDVR0OBBYEFBnboj3lf9+Xat4oEgo6ZtIMr8ZuMB8GA1UdIwQYMBaAFIp0
+f6+Fze6VzT2c0OJGFPNxNR0nMGoGCCsGAQUFBwEBBF4wXDAnBggrBgEFBQcwAYYb
+aHR0cDovL29jc3AucGtpLmdvb2cvZ3RzMWMzMDEGCCsGAQUFBzAChiVodHRwOi8v
+cGtpLmdvb2cvcmVwby9jZXJ0cy9ndHMxYzMuZGVyMBkGA1UdEQQSMBCCDnd3dy5n
+b29nbGUuY29tMCEGA1UdIAQaMBgwCAYGZ4EMAQIBMAwGCisGAQQB1nkCBQMwPAYD
+VR0fBDUwMzAxoC+gLYYraHR0cDovL2NybHMucGtpLmdvb2cvZ3RzMWMzL1FPdkow
+TjFzVDJBLmNybDCCAQQGCisGAQQB1nkCBAIEgfUEgfIA8AB2AHoyjFTYty22IOo4
+4FIe6YQWcDIThU070ivBOlejUutSAAABhXHHOiUAAAQDAEcwRQIgBUkikUIXdo+S
+3T8PP0/cvokhUlumRE3GRWGL4WRMLpcCIQDY+bwK384mZxyXGZ5lwNRTAPNzT8Fx
+1+//nbaGK3BQMAB2AOg+0No+9QY1MudXKLyJa8kD08vREWvs62nhd31tBr1uAAAB
+hXHHOfQAAAQDAEcwRQIgLoVydNfMFKV9IoZR+M0UuJ2zOqbxIRum7Sn9RMPOBGMC
+IQD1/BgzCSDTvYvco6kpB6ifKSbg5gcb5KTnYxQYwRW14TANBgkqhkiG9w0BAQsF
+AAOCAQEA2bQQu30e3OFu0bmvQHmcqYvXBu6tF6e5b5b+hj4O+Rn7BXTTmaYX3M6p
+MsfRH4YVJJMB/dc3PROR2VtnKFC6gAZX+RKM6nXnZhIlOdmQnonS1ecOL19PliUd
+VXbwKjXqAO0Ljd9y9oXaXnyPyHmUJNI5YXAcxE+XXiOZhcZuMYyWmoEKJQ/XlSga
+zWfTn1IcKhA3IC7A1n/5bkkWD1Xi1mdWFQ6DQDMp//667zz7pKOgFMlB93aPDjvI
+c78zEqNswn6xGKXpWF5xVwdFcsx9HKhJ6UAi2bQ/KQ1yb7LPUOR6wXXWrG1cLnNP
+i8eNLnKL9PXQ+5SwJFCzfEhcIZuhzg==
 -----END CERTIFICATE-----`
 
 // googleLeafWithInvalidHash is the same as googleLeaf, but the signature
 // algorithm in the certificate contains a nonsense OID.
 const googleLeafWithInvalidHash = `-----BEGIN CERTIFICATE-----
-MIIEdjCCA16gAwIBAgIIcR5k4dkoe04wDQYJKoZIhvcNAWAFBQAwSTELMAkGA1UE
-BhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2dsZSBJbnRl
-cm5ldCBBdXRob3JpdHkgRzIwHhcNMTQwMzEyMDkzODMwWhcNMTQwNjEwMDAwMDAw
-WjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwN
-TW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UEAwwOd3d3
-Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC4zYCe
-m0oUBhwE0EwBr65eBOcgcQO2PaSIAB2dEP/c1EMX2tOy0ov8rk83ePhJ+MWdT1z6
-jge9X4zQQI8ZyA9qIiwrKBZOi8DNUvrqNZC7fJAVRrb9aX/99uYOJCypIbpmWG1q
-fhbHjJewhwf8xYPj71eU4rLG80a+DapWmphtfq3h52lDQIBzLVf1yYbyrTaELaz4
-NXF7HXb5YkId/gxIsSzM0aFUVu2o8sJcLYAsJqwfFKBKOMxUcn545nlspf0mTcWZ
-0APlbwsKznNs4/xCDwIxxWjjqgHrYAFl6y07i1gzbAOqdNEyR24p+3JWI8WZBlBI
-dk2KGj0W1fIfsvyxAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEFBQcDAQYI
-KwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYBBQUHAQEE
-XDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3J0
-MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9vY3NwMB0G
-A1UdDgQWBBTXD5Bx6iqT+dmEhbFL4OUoHyZn8zAMBgNVHRMBAf8EAjAAMB8GA1Ud
-IwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYKKwYBBAHW
-eQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB
-RzIuY3JsMA0GCSqGSIb3DQFgBQUAA4IBAQCR3RJtHzgDh33b/MI1ugiki+nl8Ikj
-5larbJRE/rcA5oite+QJyAr6SU1gJJ/rRrK3ItVEHr9L621BCM7GSdoNMjB9MMcf
-tJAW0kYGJ+wqKm53wG/JaOADTnnq2Mt/j6F2uvjgN/ouns1nRHufIvd370N0LeH+
-orKqTuAPzXK7imQk6+OycYABbqCtC/9qmwRd8wwn7sF97DtYfK8WuNHtFalCAwyi
-8LxJJYJCLWoMhZ+V8GZm+FOex5qkQAjnZrtNlbQJ8ro4r+rpKXtmMFFhfa+7L+PA
-Kom08eUK8skxAzfDDijZPh10VtJ66uBoiDPdT+uCBehcBIcmSTrKjFGX
+MIIFUjCCBDqgAwIBAgIQERmRWTzVoz0SMeozw2RM3DANBgkqhkiG9w0BAQ4FADBG
+MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM
+QzETMBEGA1UEAxMKR1RTIENBIDFDMzAeFw0yMzAxMDIwODE5MTlaFw0yMzAzMjcw
+ODE5MThaMBkxFzAVBgNVBAMTDnd3dy5nb29nbGUuY29tMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAq30odrKMT54TJikMKL8S+lwoCMT5geP0u9pWjk6a
+wdB6i3kO+UE4ijCAmhbcZKeKaLnGJ38weZNwB1ayabCYyX7hDiC/nRcZU49LX5+o
+55kDVaNn14YKkg2kCeX25HDxSwaOsNAIXKPTqiQL5LPvc4Twhl8HY51hhNWQrTEr
+N775eYbixEULvyVLq5BLbCOpPo8n0/MTjQ32ku1jQq3GIYMJC/Rf2VW5doF6t9zs
+KleflAN8OdKp0ME9OHg0T1P3yyb67T7n0SpisHbeG06AmQcKJF9g/9VPJtRf4l1Q
+WRPDC+6JUqzXCxAGmIRGZ7TNMxPMBW/7DRX6w8oLKVNb0wIDAQABo4ICZzCCAmMw
+DgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQC
+MAAwHQYDVR0OBBYEFBnboj3lf9+Xat4oEgo6ZtIMr8ZuMB8GA1UdIwQYMBaAFIp0
+f6+Fze6VzT2c0OJGFPNxNR0nMGoGCCsGAQUFBwEBBF4wXDAnBggrBgEFBQcwAYYb
+aHR0cDovL29jc3AucGtpLmdvb2cvZ3RzMWMzMDEGCCsGAQUFBzAChiVodHRwOi8v
+cGtpLmdvb2cvcmVwby9jZXJ0cy9ndHMxYzMuZGVyMBkGA1UdEQQSMBCCDnd3dy5n
+b29nbGUuY29tMCEGA1UdIAQaMBgwCAYGZ4EMAQIBMAwGCisGAQQB1nkCBQMwPAYD
+VR0fBDUwMzAxoC+gLYYraHR0cDovL2NybHMucGtpLmdvb2cvZ3RzMWMzL1FPdkow
+TjFzVDJBLmNybDCCAQQGCisGAQQB1nkCBAIEgfUEgfIA8AB2AHoyjFTYty22IOo4
+4FIe6YQWcDIThU070ivBOlejUutSAAABhXHHOiUAAAQDAEcwRQIgBUkikUIXdo+S
+3T8PP0/cvokhUlumRE3GRWGL4WRMLpcCIQDY+bwK384mZxyXGZ5lwNRTAPNzT8Fx
+1+//nbaGK3BQMAB2AOg+0No+9QY1MudXKLyJa8kD08vREWvs62nhd31tBr1uAAAB
+hXHHOfQAAAQDAEcwRQIgLoVydNfMFKV9IoZR+M0UuJ2zOqbxIRum7Sn9RMPOBGMC
+IQD1/BgzCSDTvYvco6kpB6ifKSbg5gcb5KTnYxQYwRW14TANBgkqhkiG9w0BAQ4F
+AAOCAQEA2bQQu30e3OFu0bmvQHmcqYvXBu6tF6e5b5b+hj4O+Rn7BXTTmaYX3M6p
+MsfRH4YVJJMB/dc3PROR2VtnKFC6gAZX+RKM6nXnZhIlOdmQnonS1ecOL19PliUd
+VXbwKjXqAO0Ljd9y9oXaXnyPyHmUJNI5YXAcxE+XXiOZhcZuMYyWmoEKJQ/XlSga
+zWfTn1IcKhA3IC7A1n/5bkkWD1Xi1mdWFQ6DQDMp//667zz7pKOgFMlB93aPDjvI
+c78zEqNswn6xGKXpWF5xVwdFcsx9HKhJ6UAi2bQ/KQ1yb7LPUOR6wXXWrG1cLnNP
+i8eNLnKL9PXQ+5SwJFCzfEhcIZuhzg==
 -----END CERTIFICATE-----`
 
 const dnssecExpLeaf = `-----BEGIN CERTIFICATE-----
@@ -1095,136 +1123,81 @@
 HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
 -----END CERTIFICATE-----`
 
-var moipLeafCert = `-----BEGIN CERTIFICATE-----
-MIIGQDCCBSigAwIBAgIRAPe/cwh7CUWizo8mYSDavLIwDQYJKoZIhvcNAQELBQAw
-gZIxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO
-BgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMTgwNgYD
-VQQDEy9DT01PRE8gUlNBIEV4dGVuZGVkIFZhbGlkYXRpb24gU2VjdXJlIFNlcnZl
-ciBDQTAeFw0xMzA4MTUwMDAwMDBaFw0xNDA4MTUyMzU5NTlaMIIBQjEXMBUGA1UE
-BRMOMDg3MTg0MzEwMDAxMDgxEzARBgsrBgEEAYI3PAIBAxMCQlIxGjAYBgsrBgEE
-AYI3PAIBAhMJU2FvIFBhdWxvMR0wGwYDVQQPExRQcml2YXRlIE9yZ2FuaXphdGlv
-bjELMAkGA1UEBhMCQlIxETAPBgNVBBETCDAxNDUyMDAwMRIwEAYDVQQIEwlTYW8g
-UGF1bG8xEjAQBgNVBAcTCVNhbyBQYXVsbzEtMCsGA1UECRMkQXZlbmlkYSBCcmln
-YWRlaXJvIEZhcmlhIExpbWEgLCAyOTI3MR0wGwYDVQQKExRNb2lwIFBhZ2FtZW50
-b3MgUy5BLjENMAsGA1UECxMETU9JUDEYMBYGA1UECxMPU1NMIEJsaW5kYWRvIEVW
-MRgwFgYDVQQDEw9hcGkubW9pcC5jb20uYnIwggEiMA0GCSqGSIb3DQEBAQUAA4IB
-DwAwggEKAoIBAQDN0b9x6TrXXA9hPCF8/NjqGJ++2D4LO4ZiMFTjs0VwpXy2Y1Oe
-s74/HuiLGnAHxTmAtV7IpZMibiOcTxcnDYp9oEWkf+gR+hZvwFZwyOBC7wyb3SR3
-UvV0N1ZbEVRYpN9kuX/3vjDghjDmzzBwu8a/T+y5JTym5uiJlngVAWyh/RjtIvYi
-+NVkQMbyVlPGkoCe6c30pH8DKYuUCZU6DHjUsPTX3jAskqbhDSAnclX9iX0p2bmw
-KVBc+5Vh/2geyzDuquF0w+mNIYdU5h7uXvlmJnf3d2Cext5dxdL8/jezD3U0dAqI
-pYSKERbyxSkJWxdvRlhdpM9YXMJcpc88xNp1AgMBAAGjggHcMIIB2DAfBgNVHSME
-GDAWgBQ52v/KKBSKqHQTCLnkDqnS+n6daTAdBgNVHQ4EFgQU/lXuOa7DMExzZjRj
-LQWcMWGZY7swDgYDVR0PAQH/BAQDAgWgMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYw
-FAYIKwYBBQUHAwEGCCsGAQUFBwMCMEYGA1UdIAQ/MD0wOwYMKwYBBAGyMQECAQUB
-MCswKQYIKwYBBQUHAgEWHWh0dHBzOi8vc2VjdXJlLmNvbW9kby5jb20vQ1BTMFYG
-A1UdHwRPME0wS6BJoEeGRWh0dHA6Ly9jcmwuY29tb2RvY2EuY29tL0NPTU9ET1JT
-QUV4dGVuZGVkVmFsaWRhdGlvblNlY3VyZVNlcnZlckNBLmNybDCBhwYIKwYBBQUH
-AQEEezB5MFEGCCsGAQUFBzAChkVodHRwOi8vY3J0LmNvbW9kb2NhLmNvbS9DT01P
-RE9SU0FFeHRlbmRlZFZhbGlkYXRpb25TZWN1cmVTZXJ2ZXJDQS5jcnQwJAYIKwYB
-BQUHMAGGGGh0dHA6Ly9vY3NwLmNvbW9kb2NhLmNvbTAvBgNVHREEKDAmgg9hcGku
-bW9pcC5jb20uYnKCE3d3dy5hcGkubW9pcC5jb20uYnIwDQYJKoZIhvcNAQELBQAD
-ggEBAFoTmPlaDcf+nudhjXHwud8g7/LRyA8ucb+3/vfmgbn7FUc1eprF5sJS1mA+
-pbiTyXw4IxcJq2KUj0Nw3IPOe9k84mzh+XMmdCKH+QK3NWkE9Udz+VpBOBc0dlqC
-1RH5umStYDmuZg/8/r652eeQ5kUDcJyADfpKWBgDPYaGtwzKVT4h3Aok9SLXRHx6
-z/gOaMjEDMarMCMw4VUIG1pvNraZrG5oTaALPaIXXpd8VqbQYPudYJ6fR5eY3FeW
-H/ofbYFdRcuD26MfBFWE9VGGral9Fgo8sEHffho+UWhgApuQV4/l5fMzxB5YBXyQ
-jhuy8PqqZS9OuLilTeLu4a8z2JI=
+const digicertRoot = `-----BEGIN CERTIFICATE-----
+MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
+QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
+MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
+b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
+CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
+nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
+43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
+T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
+gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
+BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
+TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
+DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
+hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
+06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
+PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
+YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
+CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
 -----END CERTIFICATE-----`
 
-var comodoIntermediateSHA384 = `-----BEGIN CERTIFICATE-----
-MIIGDjCCA/agAwIBAgIQBqdDgNTr/tQ1taP34Wq92DANBgkqhkiG9w0BAQwFADCB
-hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
-A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV
-BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTIwMjEy
-MDAwMDAwWhcNMjcwMjExMjM1OTU5WjCBkjELMAkGA1UEBhMCR0IxGzAZBgNVBAgT
-EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR
-Q09NT0RPIENBIExpbWl0ZWQxODA2BgNVBAMTL0NPTU9ETyBSU0EgRXh0ZW5kZWQg
-VmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC
-AQ8AMIIBCgKCAQEAlVbeVLTf1QJJe9FbXKKyHo+cK2JMK40SKPMalaPGEP0p3uGf
-CzhAk9HvbpUQ/OGQF3cs7nU+e2PsYZJuTzurgElr3wDqAwB/L3XVKC/sVmePgIOj
-vdwDmZOLlJFWW6G4ajo/Br0OksxgnP214J9mMF/b5pTwlWqvyIqvgNnmiDkBfBzA
-xSr3e5Wg8narbZtyOTDr0VdVAZ1YEZ18bYSPSeidCfw8/QpKdhQhXBZzQCMZdMO6
-WAqmli7eNuWf0MLw4eDBYuPCGEUZUaoXHugjddTI0JYT/8ck0YwLJ66eetw6YWNg
-iJctXQUL5Tvrrs46R3N2qPos3cCHF+msMJn4HwIDAQABo4IBaTCCAWUwHwYDVR0j
-BBgwFoAUu69+Aj36pvE8hI6t7jiY7NkyMtQwHQYDVR0OBBYEFDna/8ooFIqodBMI
-ueQOqdL6fp1pMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMD4G
-A1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwczovL3NlY3VyZS5j
-b21vZG8uY29tL0NQUzBMBgNVHR8ERTBDMEGgP6A9hjtodHRwOi8vY3JsLmNvbW9k
-b2NhLmNvbS9DT01PRE9SU0FDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDBxBggr
-BgEFBQcBAQRlMGMwOwYIKwYBBQUHMAKGL2h0dHA6Ly9jcnQuY29tb2RvY2EuY29t
-L0NPTU9ET1JTQUFkZFRydXN0Q0EuY3J0MCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
-cC5jb21vZG9jYS5jb20wDQYJKoZIhvcNAQEMBQADggIBAERCnUFRK0iIXZebeV4R
-AUpSGXtBLMeJPNBy3IX6WK/VJeQT+FhlZ58N/1eLqYVeyqZLsKeyLeCMIs37/3mk
-jCuN/gI9JN6pXV/kD0fQ22YlPodHDK4ixVAihNftSlka9pOlk7DgG4HyVsTIEFPk
-1Hax0VtpS3ey4E/EhOfUoFDuPPpE/NBXueEoU/1Tzdy5H3pAvTA/2GzS8+cHnx8i
-teoiccsq8FZ8/qyo0QYPFBRSTP5kKwxpKrgNUG4+BAe/eiCL+O5lCeHHSQgyPQ0o
-fkkdt0rvAucNgBfIXOBhYsvss2B5JdoaZXOcOBCgJjqwyBZ9kzEi7nQLiMBciUEA
-KKlHMd99SUWa9eanRRrSjhMQ34Ovmw2tfn6dNVA0BM7pINae253UqNpktNEvWS5e
-ojZh1CSggjMziqHRbO9haKPl0latxf1eYusVqHQSTC8xjOnB3xBLAer2VBvNfzu9
-XJ/B288ByvK6YBIhMe2pZLiySVgXbVrXzYxtvp5/4gJYp9vDLVj2dAZqmvZh+fYA
-tmnYOosxWd2R5nwnI4fdAw+PKowegwFOAWEMUnNt/AiiuSpm5HZNMaBWm9lTjaK2
-jwLI5jqmBNFI+8NKAnb9L9K8E7bobTQk+p0pisehKxTxlgBzuRPpwLk6R1YCcYAn
-pLwltum95OmYdBbxN4SBB7SC
+const trustAsiaSHA384Intermediate = `-----BEGIN CERTIFICATE-----
+MIID9zCCAt+gAwIBAgIQC965p4OR4AKrGlsyW0XrDzANBgkqhkiG9w0BAQwFADBh
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
+QTAeFw0xODA0MjcxMjQyNTlaFw0yODA0MjcxMjQyNTlaMFoxCzAJBgNVBAYTAkNO
+MSUwIwYDVQQKExxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMSQwIgYDVQQD
+ExtUcnVzdEFzaWEgRUNDIE9WIFRMUyBQcm8gQ0EwdjAQBgcqhkjOPQIBBgUrgQQA
+IgNiAAQPIUn75M5BCQLKoPsSU2KTr3mDMh13usnAQ38XfKOzjXiyQ+W0inA7meYR
+xS+XMQgvnbCigEsKj3ErPIzO68uC9V/KdqMaXWBJp85Ws9A4KL92NB4Okbn5dp6v
+Qzy08PajggFeMIIBWjAdBgNVHQ4EFgQULdRyBx6HyIH/+LOvuexyH5p/3PwwHwYD
+VR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDgYDVR0PAQH/BAQDAgGGMB0G
+A1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEA
+MDcGCCsGAQUFBwEBBCswKTAnBggrBgEFBQcwAYYbaHR0cDovL29jc3AuZGlnaWNl
+cnQtY24uY29tMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jcmwuZGlnaWNlcnQt
+Y24uY29tL0RpZ2lDZXJ0R2xvYmFsUm9vdENBLmNybDBWBgNVHSAETzBNMDcGCWCG
+SAGG/WwBATAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20v
+Q1BTMAgGBmeBDAECAjAIBgZngQwBAgMwDQYJKoZIhvcNAQEMBQADggEBACVRufYd
+j81xUqngFCO+Pk8EYXie0pxHKsBZnOPygAyXKx+awUasKBAnHjmhoFPXaDGAP2oV
+OeZTWgwnURVr6wUCuTkz2/8Tgl1egC7OrVcHSa0fIIhaVo9/zRA/hr31xMG7LFBk
+GNd7jd06Up4f/UOGbcJsqJexc5QRcUeSwe1MiUDcTNiyCjZk74QCPdcfdFYM4xsa
+SlUpboB5vyT7jFePZ2v95CKjcr0EhiQ0gwxpdgoipZdfYTiMFGxCLsk6v8pUv7Tq
+PT/qadOGyC+PfLuZh1PtLp20mF06K+MzheCiv+w1NT5ofhmcObvukc68wvbvRFL6
+rRzZxAYN36q1SX8=
 -----END CERTIFICATE-----`
 
-const comodoRSAAuthority = `-----BEGIN CERTIFICATE-----
-MIIFdDCCBFygAwIBAgIQJ2buVutJ846r13Ci/ITeIjANBgkqhkiG9w0BAQwFADBv
-MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk
-ZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBF
-eHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFow
-gYUxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO
-BgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMSswKQYD
-VQQDEyJDT01PRE8gUlNBIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkq
-hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAkehUktIKVrGsDSTdxc9EZ3SZKzejfSNw
-AHG8U9/E+ioSj0t/EFa9n3Byt2F/yUsPF6c947AEYe7/EZfH9IY+Cvo+XPmT5jR6
-2RRr55yzhaCCenavcZDX7P0N+pxs+t+wgvQUfvm+xKYvT3+Zf7X8Z0NyvQwA1onr
-ayzT7Y+YHBSrfuXjbvzYqOSSJNpDa2K4Vf3qwbxstovzDo2a5JtsaZn4eEgwRdWt
-4Q08RWD8MpZRJ7xnw8outmvqRsfHIKCxH2XeSAi6pE6p8oNGN4Tr6MyBSENnTnIq
-m1y9TBsoilwie7SrmNnu4FGDwwlGTm0+mfqVF9p8M1dBPI1R7Qu2XK8sYxrfV8g/
-vOldxJuvRZnio1oktLqpVj3Pb6r/SVi+8Kj/9Lit6Tf7urj0Czr56ENCHonYhMsT
-8dm74YlguIwoVqwUHZwK53Hrzw7dPamWoUi9PPevtQ0iTMARgexWO/bTouJbt7IE
-IlKVgJNp6I5MZfGRAy1wdALqi2cVKWlSArvX31BqVUa/oKMoYX9w0MOiqiwhqkfO
-KJwGRXa/ghgntNWutMtQ5mv0TIZxMOmm3xaG4Nj/QN370EKIf6MzOi5cHkERgWPO
-GHFrK+ymircxXDpqR+DDeVnWIBqv8mqYqnK8V0rSS527EPywTEHl7R09XiidnMy/
-s1Hap0flhFMCAwEAAaOB9DCB8TAfBgNVHSMEGDAWgBStvZh6NLQm9/rEJlTvA73g
-JMtUGjAdBgNVHQ4EFgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQD
-AgGGMA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0gBAowCDAGBgRVHSAAMEQGA1UdHwQ9
-MDswOaA3oDWGM2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9BZGRUcnVzdEV4dGVy
-bmFsQ0FSb290LmNybDA1BggrBgEFBQcBAQQpMCcwJQYIKwYBBQUHMAGGGWh0dHA6
-Ly9vY3NwLnVzZXJ0cnVzdC5jb20wDQYJKoZIhvcNAQEMBQADggEBAGS/g/FfmoXQ
-zbihKVcN6Fr30ek+8nYEbvFScLsePP9NDXRqzIGCJdPDoCpdTPW6i6FtxFQJdcfj
-Jw5dhHk3QBN39bSsHNA7qxcS1u80GH4r6XnTq1dFDK8o+tDb5VCViLvfhVdpfZLY
-Uspzgb8c8+a4bmYRBbMelC1/kZWSWfFMzqORcUx8Rww7Cxn2obFshj5cqsQugsv5
-B5a6SE2Q8pTIqXOi6wZ7I53eovNNVZ96YUWYGGjHXkBrI/V5eu+MtWuLt29G9Hvx
-PUsE2JOAWVrgQSQdso8VYFhH2+9uRv0V9dlfmrPb2LjkQLPNlzmuhbsdjrzch5vR
-pu/xO28QOG8=
------END CERTIFICATE-----`
-
-const addTrustRoot = `-----BEGIN CERTIFICATE-----
-MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU
-MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs
-IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290
-MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux
-FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h
-bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v
-dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt
-H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9
-uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX
-mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX
-a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN
-E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0
-WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD
-VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0
-Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU
-cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx
-IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN
-AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH
-YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5
-6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC
-Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX
-c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a
-mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
+const trustAsiaLeaf = `-----BEGIN CERTIFICATE-----
+MIIEwTCCBEegAwIBAgIQBOjomZfHfhgz2bVYZVuf2DAKBggqhkjOPQQDAzBaMQsw
+CQYDVQQGEwJDTjElMCMGA1UEChMcVHJ1c3RBc2lhIFRlY2hub2xvZ2llcywgSW5j
+LjEkMCIGA1UEAxMbVHJ1c3RBc2lhIEVDQyBPViBUTFMgUHJvIENBMB4XDTE5MDUx
+NzAwMDAwMFoXDTIwMDcyODEyMDAwMFowgY0xCzAJBgNVBAYTAkNOMRIwEAYDVQQI
+DAnnpo/lu7rnnIExEjAQBgNVBAcMCeWOpumXqOW4gjEqMCgGA1UECgwh5Y6m6Zeo
+5Y+B546W5Y+B56eR5oqA5pyJ6ZmQ5YWs5Y+4MRgwFgYDVQQLDA/nn6Xor4bkuqfm
+nYPpg6gxEDAOBgNVBAMMByoudG0uY24wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC
+AARx/MDQ0oGnCLagQIzjIz57iqFYFmz4/W6gaU6N+GHBkzyvQU8aX02QkdlTTNYL
+TCoGFJxHB0XlZVSxrqoIPlNKo4ICuTCCArUwHwYDVR0jBBgwFoAULdRyBx6HyIH/
++LOvuexyH5p/3PwwHQYDVR0OBBYEFGTyf5adc5smW8NvDZyummJwZRLEMBkGA1Ud
+EQQSMBCCByoudG0uY26CBXRtLmNuMA4GA1UdDwEB/wQEAwIHgDAdBgNVHSUEFjAU
+BggrBgEFBQcDAQYIKwYBBQUHAwIwRgYDVR0fBD8wPTA7oDmgN4Y1aHR0cDovL2Ny
+bC5kaWdpY2VydC1jbi5jb20vVHJ1c3RBc2lhRUNDT1ZUTFNQcm9DQS5jcmwwTAYD
+VR0gBEUwQzA3BglghkgBhv1sAQEwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cu
+ZGlnaWNlcnQuY29tL0NQUzAIBgZngQwBAgIwfgYIKwYBBQUHAQEEcjBwMCcGCCsG
+AQUFBzABhhtodHRwOi8vb2NzcC5kaWdpY2VydC1jbi5jb20wRQYIKwYBBQUHMAKG
+OWh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LWNuLmNvbS9UcnVzdEFzaWFFQ0NPVlRM
+U1Byb0NBLmNydDAMBgNVHRMBAf8EAjAAMIIBAwYKKwYBBAHWeQIEAgSB9ASB8QDv
+AHUA7ku9t3XOYLrhQmkfq+GeZqMPfl+wctiDAMR7iXqo/csAAAFqxGMTnwAABAMA
+RjBEAiAz13zKEoyqd4e/96SK/fxfjl7uR+xhfoDZeyA1BvtfOwIgTY+8nJMGekv8
+leIVdW6AGh7oqH31CIGTAbNJJWzaSFYAdgCHdb/nWXz4jEOZX73zbv9WjUdWNv9K
+tWDBtOr/XqCDDwAAAWrEYxTCAAAEAwBHMEUCIQDlWm7+limbRiurcqUwXav3NSmx
+x/aMnolLbh6+f+b1XAIgQfinHwLw6pDr4R9UkndUsX8QFF4GXS3/IwRR8HCp+pIw
+CgYIKoZIzj0EAwMDaAAwZQIwHg8JmjRtcq+OgV0vVmdVBPqehi1sQJ9PZ+51CG+Z
+0GOu+2HwS/fyLRViwSc/MZoVAjEA7NgbgpPN4OIsZn2XjMGxemtVxGFS6ZR+1364
+EEeHB9vhZAEjQSePAfjR9aAGhXRa
 -----END CERTIFICATE-----`
 
 const selfSigned = `-----BEGIN CERTIFICATE-----
@@ -1508,33 +1481,36 @@
 -----END CERTIFICATE-----`
 
 var unknownAuthorityErrorTests = []struct {
+	name     string
 	cert     string
 	expected string
 }{
-	{selfSignedWithCommonName, "x509: certificate signed by unknown authority (possibly because of \"empty\" while trying to verify candidate authority certificate \"test\")"},
-	{selfSignedNoCommonNameWithOrgName, "x509: certificate signed by unknown authority (possibly because of \"empty\" while trying to verify candidate authority certificate \"ca\")"},
-	{selfSignedNoCommonNameNoOrgName, "x509: certificate signed by unknown authority (possibly because of \"empty\" while trying to verify candidate authority certificate \"serial:0\")"},
+	{"self-signed, cn", selfSignedWithCommonName, "x509: certificate signed by unknown authority (possibly because of \"empty\" while trying to verify candidate authority certificate \"test\")"},
+	{"self-signed, no cn, org", selfSignedNoCommonNameWithOrgName, "x509: certificate signed by unknown authority (possibly because of \"empty\" while trying to verify candidate authority certificate \"ca\")"},
+	{"self-signed, no cn, no org", selfSignedNoCommonNameNoOrgName, "x509: certificate signed by unknown authority (possibly because of \"empty\" while trying to verify candidate authority certificate \"serial:0\")"},
 }
 
 func TestUnknownAuthorityError(t *testing.T) {
 	for i, tt := range unknownAuthorityErrorTests {
-		der, _ := pem.Decode([]byte(tt.cert))
-		if der == nil {
-			t.Errorf("#%d: Unable to decode PEM block", i)
-		}
-		c, err := ParseCertificate(der.Bytes)
-		if err != nil {
-			t.Errorf("#%d: Unable to parse certificate -> %v", i, err)
-		}
-		uae := &UnknownAuthorityError{
-			Cert:     c,
-			hintErr:  fmt.Errorf("empty"),
-			hintCert: c,
-		}
-		actual := uae.Error()
-		if actual != tt.expected {
-			t.Errorf("#%d: UnknownAuthorityError.Error() response invalid actual: %s expected: %s", i, actual, tt.expected)
-		}
+		t.Run(tt.name, func(t *testing.T) {
+			der, _ := pem.Decode([]byte(tt.cert))
+			if der == nil {
+				t.Fatalf("#%d: Unable to decode PEM block", i)
+			}
+			c, err := ParseCertificate(der.Bytes)
+			if err != nil {
+				t.Fatalf("#%d: Unable to parse certificate -> %v", i, err)
+			}
+			uae := &UnknownAuthorityError{
+				Cert:     c,
+				hintErr:  fmt.Errorf("empty"),
+				hintCert: c,
+			}
+			actual := uae.Error()
+			if actual != tt.expected {
+				t.Errorf("#%d: UnknownAuthorityError.Error() response invalid actual: %s expected: %s", i, actual, tt.expected)
+			}
+		})
 	}
 }
 
@@ -1852,10 +1828,10 @@
 	opts := VerifyOptions{
 		Intermediates: NewCertPool(),
 		DNSName:       "www.google.com",
-		CurrentTime:   time.Unix(1395785200, 0),
+		CurrentTime:   time.Unix(1677615892, 0),
 	}
 
-	if ok := opts.Intermediates.AppendCertsFromPEM([]byte(giag2Intermediate)); !ok {
+	if ok := opts.Intermediates.AppendCertsFromPEM([]byte(gtsIntermediate)); !ok {
 		t.Fatalf("failed to parse intermediate")
 	}
 
@@ -1881,6 +1857,16 @@
 }
 
 func TestIssue51759(t *testing.T) {
+	if runtime.GOOS != "darwin" {
+		t.Skip("only affects darwin")
+	}
+	builder := testenv.Builder()
+	if builder == "" {
+		t.Skip("only run this test on the builders, as we have no reasonable way to gate tests on macOS versions elsewhere")
+	}
+	if builder == "darwin-amd64-10_14" || builder == "darwin-amd64-10_15" {
+		t.Skip("behavior only enforced in macOS 11 and after")
+	}
 	// badCertData contains a cert that we parse as valid
 	// but that macOS SecCertificateCreateWithData rejects.
 	const badCertData = "0\x82\x01U0\x82\x01\a\xa0\x03\x02\x01\x02\x02\x01\x020\x05\x06\x03+ep0R1P0N\x06\x03U\x04\x03\x13Gderpkey8dc58100b2493614ee1692831a461f3f4dd3f9b3b088e244f887f81b4906ac260\x1e\x17\r220112235755Z\x17\r220313235755Z0R1P0N\x06\x03U\x04\x03\x13Gderpkey8dc58100b2493614ee1692831a461f3f4dd3f9b3b088e244f887f81b4906ac260*0\x05\x06\x03+ep\x03!\x00bA\xd8e\xadW\xcb\xefZ\x89\xb5\"\x1eR\x9d\xba\x0e:\x1042Q@\u007f\xbd\xfb{ks\x04\xd1£\x020\x000\x05\x06\x03+ep\x03A\x00[\xa7\x06y\x86(\x94\x97\x9eLwA\x00\x01x\xaa\xbc\xbd Ê]\n(΅!ف0\xf5\x9a%I\x19<\xffo\xf1\xeaaf@\xb1\xa7\xaf\xfd\xe9R\xc7\x0f\x8d&\xd5\xfc\x0f;Ϙ\x82\x84a\xbc\r"
@@ -1891,9 +1877,10 @@
 
 	t.Run("leaf", func(t *testing.T) {
 		opts := VerifyOptions{}
+		expectedErr := "invalid leaf certificate"
 		_, err = badCert.Verify(opts)
-		if err == nil {
-			t.Fatal("expected error")
+		if err == nil || err.Error() != expectedErr {
+			t.Fatalf("unexpected error: want %q, got %q", expectedErr, err)
 		}
 	})
 
@@ -1907,9 +1894,10 @@
 			Intermediates: NewCertPool(),
 		}
 		opts.Intermediates.AddCert(badCert)
+		expectedErr := "SecCertificateCreateWithData: invalid certificate"
 		_, err = goodCert.Verify(opts)
-		if err == nil {
-			t.Fatal("expected error")
+		if err == nil || err.Error() != expectedErr {
+			t.Fatalf("unexpected error: want %q, got %q", expectedErr, err)
 		}
 	})
 }
diff --git a/src/crypto/x509/x509.go b/src/crypto/x509/x509.go
index 950f6d0..36229bb 100644
--- a/src/crypto/x509/x509.go
+++ b/src/crypto/x509/x509.go
@@ -2,12 +2,28 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Package x509 parses X.509-encoded keys and certificates.
+// Package x509 implements a subset of the X.509 standard.
+//
+// It allows parsing and generating certificates, certificate signing
+// requests, certificate revocation lists, and encoded public and private keys.
+// It provides a certificate verifier, complete with a chain builder.
+//
+// The package targets the X.509 technical profile defined by the IETF (RFC
+// 2459/3280/5280), and as further restricted by the CA/Browser Forum Baseline
+// Requirements. There is minimal support for features outside of these
+// profiles, as the primary goal of the package is to provide compatibility
+// with the publicly trusted TLS certificate ecosystem and its policies and
+// constraints.
+//
+// On macOS and Windows, certificate verification is handled by system APIs, but
+// the package aims to apply consistent validation rules across operating
+// systems.
 package x509
 
 import (
 	"bytes"
 	"crypto"
+	"crypto/ecdh"
 	"crypto/ecdsa"
 	"crypto/ed25519"
 	"crypto/elliptic"
@@ -44,12 +60,12 @@
 	BitString asn1.BitString
 }
 
-// ParsePKIXPublicKey parses a public key in PKIX, ASN.1 DER form.
-// The encoded public key is a SubjectPublicKeyInfo structure
-// (see RFC 5280, Section 4.1).
+// ParsePKIXPublicKey parses a public key in PKIX, ASN.1 DER form. The encoded
+// public key is a SubjectPublicKeyInfo structure (see RFC 5280, Section 4.1).
 //
-// It returns a *rsa.PublicKey, *dsa.PublicKey, *ecdsa.PublicKey, or
-// ed25519.PublicKey. More types might be supported in the future.
+// It returns a *rsa.PublicKey, *dsa.PublicKey, *ecdsa.PublicKey,
+// ed25519.PublicKey (not a pointer), or *ecdh.PublicKey (for X25519).
+// More types might be supported in the future.
 //
 // This kind of key is commonly encoded in PEM blocks of type "PUBLIC KEY".
 func ParsePKIXPublicKey(derBytes []byte) (pub any, err error) {
@@ -62,11 +78,7 @@
 	} else if len(rest) != 0 {
 		return nil, errors.New("x509: trailing data after ASN.1 of public-key")
 	}
-	algo := getPublicKeyAlgorithmFromOID(pki.Algorithm.Algorithm)
-	if algo == UnknownPublicKeyAlgorithm {
-		return nil, errors.New("x509: unknown public key algorithm")
-	}
-	return parsePublicKey(algo, &pki)
+	return parsePublicKey(&pki)
 }
 
 func marshalPublicKey(pub any) (publicKeyBytes []byte, publicKeyAlgorithm pkix.AlgorithmIdentifier, err error) {
@@ -84,11 +96,14 @@
 		// RFC 3279, Section 2.3.1.
 		publicKeyAlgorithm.Parameters = asn1.NullRawValue
 	case *ecdsa.PublicKey:
-		publicKeyBytes = elliptic.Marshal(pub.Curve, pub.X, pub.Y)
 		oid, ok := oidFromNamedCurve(pub.Curve)
 		if !ok {
 			return nil, pkix.AlgorithmIdentifier{}, errors.New("x509: unsupported elliptic curve")
 		}
+		if !pub.Curve.IsOnCurve(pub.X, pub.Y) {
+			return nil, pkix.AlgorithmIdentifier{}, errors.New("x509: invalid elliptic curve public key")
+		}
+		publicKeyBytes = elliptic.Marshal(pub.Curve, pub.X, pub.Y)
 		publicKeyAlgorithm.Algorithm = oidPublicKeyECDSA
 		var paramBytes []byte
 		paramBytes, err = asn1.Marshal(oid)
@@ -99,6 +114,23 @@
 	case ed25519.PublicKey:
 		publicKeyBytes = pub
 		publicKeyAlgorithm.Algorithm = oidPublicKeyEd25519
+	case *ecdh.PublicKey:
+		publicKeyBytes = pub.Bytes()
+		if pub.Curve() == ecdh.X25519() {
+			publicKeyAlgorithm.Algorithm = oidPublicKeyX25519
+		} else {
+			oid, ok := oidFromECDHCurve(pub.Curve())
+			if !ok {
+				return nil, pkix.AlgorithmIdentifier{}, errors.New("x509: unsupported elliptic curve")
+			}
+			publicKeyAlgorithm.Algorithm = oidPublicKeyECDSA
+			var paramBytes []byte
+			paramBytes, err = asn1.Marshal(oid)
+			if err != nil {
+				return
+			}
+			publicKeyAlgorithm.Parameters.FullBytes = paramBytes
+		}
 	default:
 		return nil, pkix.AlgorithmIdentifier{}, fmt.Errorf("x509: unsupported public key type: %T", pub)
 	}
@@ -110,8 +142,9 @@
 // The encoded public key is a SubjectPublicKeyInfo structure
 // (see RFC 5280, Section 4.1).
 //
-// The following key types are currently supported: *rsa.PublicKey, *ecdsa.PublicKey
-// and ed25519.PublicKey. Unsupported key types result in an error.
+// The following key types are currently supported: *rsa.PublicKey,
+// *ecdsa.PublicKey, ed25519.PublicKey (not a pointer), and *ecdh.PublicKey.
+// Unsupported key types result in an error.
 //
 // This kind of key is commonly encoded in PEM blocks of type "PUBLIC KEY".
 func MarshalPKIXPublicKey(pub any) ([]byte, error) {
@@ -138,7 +171,6 @@
 // These structures reflect the ASN.1 structure of X.509 certificates.:
 
 type certificate struct {
-	Raw                asn1.RawContent
 	TBSCertificate     tbsCertificate
 	SignatureAlgorithm pkix.AlgorithmIdentifier
 	SignatureValue     asn1.BitString
@@ -223,7 +255,7 @@
 const (
 	UnknownPublicKeyAlgorithm PublicKeyAlgorithm = iota
 	RSA
-	DSA // Unsupported.
+	DSA // Only supported for parsing.
 	ECDSA
 	Ed25519
 )
@@ -427,27 +459,34 @@
 	return UnknownSignatureAlgorithm
 }
 
-// RFC 3279, 2.3 Public Key Algorithms
-//
-//	pkcs-1 OBJECT IDENTIFIER ::== { iso(1) member-body(2) us(840)
-//		rsadsi(113549) pkcs(1) 1 }
-//
-// rsaEncryption OBJECT IDENTIFIER ::== { pkcs1-1 1 }
-//
-//	id-dsa OBJECT IDENTIFIER ::== { iso(1) member-body(2) us(840)
-//		x9-57(10040) x9cm(4) 1 }
-//
-// RFC 5480, 2.1.1 Unrestricted Algorithm Identifier and Parameters
-//
-//	id-ecPublicKey OBJECT IDENTIFIER ::= {
-//		iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 }
 var (
-	oidPublicKeyRSA     = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}
-	oidPublicKeyDSA     = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 1}
-	oidPublicKeyECDSA   = asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1}
-	oidPublicKeyEd25519 = oidSignatureEd25519
+	// RFC 3279, 2.3 Public Key Algorithms
+	//
+	//	pkcs-1 OBJECT IDENTIFIER ::== { iso(1) member-body(2) us(840)
+	//		rsadsi(113549) pkcs(1) 1 }
+	//
+	// rsaEncryption OBJECT IDENTIFIER ::== { pkcs1-1 1 }
+	//
+	//	id-dsa OBJECT IDENTIFIER ::== { iso(1) member-body(2) us(840)
+	//		x9-57(10040) x9cm(4) 1 }
+	oidPublicKeyRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}
+	oidPublicKeyDSA = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 1}
+	// RFC 5480, 2.1.1 Unrestricted Algorithm Identifier and Parameters
+	//
+	//	id-ecPublicKey OBJECT IDENTIFIER ::= {
+	//		iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 }
+	oidPublicKeyECDSA = asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1}
+	// RFC 8410, Section 3
+	//
+	//	id-X25519    OBJECT IDENTIFIER ::= { 1 3 101 110 }
+	//	id-Ed25519   OBJECT IDENTIFIER ::= { 1 3 101 112 }
+	oidPublicKeyX25519  = asn1.ObjectIdentifier{1, 3, 101, 110}
+	oidPublicKeyEd25519 = asn1.ObjectIdentifier{1, 3, 101, 112}
 )
 
+// getPublicKeyAlgorithmFromOID returns the exposed PublicKeyAlgorithm
+// identifier for public key types supported in certificates and CSRs. Marshal
+// and Parse functions may support a different set of public key types.
 func getPublicKeyAlgorithmFromOID(oid asn1.ObjectIdentifier) PublicKeyAlgorithm {
 	switch {
 	case oid.Equal(oidPublicKeyRSA):
@@ -514,6 +553,21 @@
 	return nil, false
 }
 
+func oidFromECDHCurve(curve ecdh.Curve) (asn1.ObjectIdentifier, bool) {
+	switch curve {
+	case ecdh.X25519():
+		return oidPublicKeyX25519, true
+	case ecdh.P256():
+		return oidNamedCurveP256, true
+	case ecdh.P384():
+		return oidNamedCurveP384, true
+	case ecdh.P521():
+		return oidNamedCurveP521, true
+	}
+
+	return nil, false
+}
+
 // KeyUsage represents the set of actions that are valid for a given key. It's
 // a bitmap of the KeyUsage* constants.
 type KeyUsage int
@@ -725,9 +779,6 @@
 // involves algorithms that are not currently implemented.
 var ErrUnsupportedAlgorithm = errors.New("x509: cannot verify signature: algorithm unimplemented")
 
-// debugAllowSHA1 allows SHA-1 signatures. See issue 41682.
-var debugAllowSHA1 = godebug.Get("x509sha1") == "1"
-
 // An InsecureAlgorithmError indicates that the SignatureAlgorithm used to
 // generate the signature is not secure, and the signature has been rejected.
 //
@@ -764,8 +815,10 @@
 	return oidInExtensions(oidExtensionSubjectAltName, c.Extensions)
 }
 
-// CheckSignatureFrom verifies that the signature on c is a valid signature
-// from parent. SHA1WithRSA and ECDSAWithSHA1 signatures are not supported.
+// CheckSignatureFrom verifies that the signature on c is a valid signature from parent.
+//
+// This is a low-level API that performs very limited checks, and not a full
+// path verifier. Most users should use [Certificate.Verify] instead.
 func (c *Certificate) CheckSignatureFrom(parent *Certificate) error {
 	// RFC 5280, 4.2.1.9:
 	// "If the basic constraints extension is not present in a version 3
@@ -785,13 +838,16 @@
 		return ErrUnsupportedAlgorithm
 	}
 
-	// TODO(agl): don't ignore the path length constraint.
-
-	return checkSignature(c.SignatureAlgorithm, c.RawTBSCertificate, c.Signature, parent.PublicKey, debugAllowSHA1)
+	return checkSignature(c.SignatureAlgorithm, c.RawTBSCertificate, c.Signature, parent.PublicKey, false)
 }
 
 // CheckSignature verifies that signature is a valid signature over signed from
 // c's public key.
+//
+// This is a low-level API that performs no validity checks on the certificate.
+//
+// [MD5WithRSA] signatures are rejected, while [SHA1WithRSA] and [ECDSAWithSHA1]
+// signatures are currently accepted.
 func (c *Certificate) CheckSignature(algo SignatureAlgorithm, signed, signature []byte) error {
 	return checkSignature(algo, signed, signature, c.PublicKey, true)
 }
@@ -813,6 +869,8 @@
 	return fmt.Errorf("x509: signature algorithm specifies an %s public key, but have public key of type %T", expectedPubKeyAlgo.String(), pubKey)
 }
 
+var x509sha1 = godebug.New("x509sha1")
+
 // checkSignature verifies that signature is a valid signature over signed from
 // a crypto.PublicKey.
 func checkSignature(algo SignatureAlgorithm, signed, signature []byte, publicKey crypto.PublicKey, allowSHA1 bool) (err error) {
@@ -834,7 +892,8 @@
 	case crypto.MD5:
 		return InsecureAlgorithmError(algo)
 	case crypto.SHA1:
-		if !allowSHA1 {
+		// SHA-1 signatures are mostly disabled. See go.dev/issue/41682.
+		if !allowSHA1 && x509sha1.Value() != "1" {
 			return InsecureAlgorithmError(algo)
 		}
 		fallthrough
@@ -973,7 +1032,7 @@
 	oidAuthorityInfoAccessIssuers = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 2}
 )
 
-// oidNotInExtensions reports whether an extension with the given oid exists in
+// oidInExtensions reports whether an extension with the given oid exists in
 // extensions.
 func oidInExtensions(oid asn1.ObjectIdentifier, extensions []pkix.Extension) bool {
 	for _, e := range extensions {
@@ -1504,6 +1563,9 @@
 	if err != nil {
 		return nil, err
 	}
+	if getPublicKeyAlgorithmFromOID(publicKeyAlgorithm.Algorithm) == UnknownPublicKeyAlgorithm {
+		return nil, fmt.Errorf("x509: unsupported public key type: %T", pub)
+	}
 
 	asn1Issuer, err := subjectBytes(parent)
 	if err != nil {
@@ -1585,7 +1647,6 @@
 	}
 
 	signedCert, err := asn1.Marshal(certificate{
-		nil,
 		c,
 		signatureAlgorithm,
 		asn1.BitString{Bytes: signature, BitLength: len(signature) * 8},
@@ -1815,18 +1876,13 @@
 	}
 
 	var ret []pkix.Extension
-	seenExts := make(map[string]bool)
+	requestedExts := make(map[string]bool)
 	for _, rawAttr := range rawAttributes {
 		var attr pkcs10Attribute
 		if rest, err := asn1.Unmarshal(rawAttr.FullBytes, &attr); err != nil || len(rest) != 0 || len(attr.Values) == 0 {
 			// Ignore attributes that don't parse.
 			continue
 		}
-		oidStr := attr.Id.String()
-		if seenExts[oidStr] {
-			return nil, errors.New("x509: certificate request contains duplicate extensions")
-		}
-		seenExts[oidStr] = true
 
 		if !attr.Id.Equal(oidExtensionRequest) {
 			continue
@@ -1836,7 +1892,6 @@
 		if _, err := asn1.Unmarshal(attr.Values[0].FullBytes, &extensions); err != nil {
 			return nil, err
 		}
-		requestedExts := make(map[string]bool)
 		for _, ext := range extensions {
 			oidStr := ext.Id.String()
 			if requestedExts[oidStr] {
@@ -2058,9 +2113,11 @@
 	}
 
 	var err error
-	out.PublicKey, err = parsePublicKey(out.PublicKeyAlgorithm, &in.TBSCSR.PublicKey)
-	if err != nil {
-		return nil, err
+	if out.PublicKeyAlgorithm != UnknownPublicKeyAlgorithm {
+		out.PublicKey, err = parsePublicKey(&in.TBSCSR.PublicKey)
+		if err != nil {
+			return nil, err
+		}
 	}
 
 	var subject pkix.RDNSequence
@@ -2148,6 +2205,29 @@
 	ExtraExtensions []pkix.Extension
 }
 
+// These structures reflect the ASN.1 structure of X.509 CRLs better than
+// the existing crypto/x509/pkix variants do. These mirror the existing
+// certificate structs in this file.
+//
+// Notably, we include issuer as an asn1.RawValue, mirroring the behavior of
+// tbsCertificate and allowing raw (unparsed) subjects to be passed cleanly.
+type certificateList struct {
+	TBSCertList        tbsCertificateList
+	SignatureAlgorithm pkix.AlgorithmIdentifier
+	SignatureValue     asn1.BitString
+}
+
+type tbsCertificateList struct {
+	Raw                 asn1.RawContent
+	Version             int `asn1:"optional,default:0"`
+	Signature           pkix.AlgorithmIdentifier
+	Issuer              asn1.RawValue
+	ThisUpdate          time.Time
+	NextUpdate          time.Time                 `asn1:"optional"`
+	RevokedCertificates []pkix.RevokedCertificate `asn1:"optional"`
+	Extensions          []pkix.Extension          `asn1:"tag:0,optional,explicit"`
+}
+
 // CreateRevocationList creates a new X.509 v2 Certificate Revocation List,
 // according to RFC 5280, based on template.
 //
@@ -2205,10 +2285,16 @@
 		return nil, err
 	}
 
-	tbsCertList := pkix.TBSCertificateList{
+	// Correctly use the issuer's subject sequence if one is specified.
+	issuerSubject, err := subjectBytes(issuer)
+	if err != nil {
+		return nil, err
+	}
+
+	tbsCertList := tbsCertificateList{
 		Version:    1, // v2
 		Signature:  signatureAlgorithm,
-		Issuer:     issuer.Subject.ToRDNSequence(),
+		Issuer:     asn1.RawValue{FullBytes: issuerSubject},
 		ThisUpdate: template.ThisUpdate.UTC(),
 		NextUpdate: template.NextUpdate.UTC(),
 		Extensions: []pkix.Extension{
@@ -2235,6 +2321,10 @@
 		return nil, err
 	}
 
+	// Optimization to only marshal this struct once, when signing and
+	// then embedding in certificateList below.
+	tbsCertList.Raw = tbsCertListContents
+
 	input := tbsCertListContents
 	if hashFunc != 0 {
 		h := hashFunc.New()
@@ -2254,7 +2344,7 @@
 		return nil, err
 	}
 
-	return asn1.Marshal(pkix.CertificateList{
+	return asn1.Marshal(certificateList{
 		TBSCertList:        tbsCertList,
 		SignatureAlgorithm: signatureAlgorithm,
 		SignatureValue:     asn1.BitString{Bytes: signature, BitLength: len(signature) * 8},
diff --git a/src/crypto/x509/x509_test.go b/src/crypto/x509/x509_test.go
index cba44f6..8846b00 100644
--- a/src/crypto/x509/x509_test.go
+++ b/src/crypto/x509/x509_test.go
@@ -8,6 +8,7 @@
 	"bytes"
 	"crypto"
 	"crypto/dsa"
+	"crypto/ecdh"
 	"crypto/ecdsa"
 	"crypto/ed25519"
 	"crypto/elliptic"
@@ -68,6 +69,20 @@
 	}
 }
 
+func TestMarshalInvalidPublicKey(t *testing.T) {
+	_, err := MarshalPKIXPublicKey(&ecdsa.PublicKey{})
+	if err == nil {
+		t.Errorf("expected error, got MarshalPKIXPublicKey success")
+	}
+	_, err = MarshalPKIXPublicKey(&ecdsa.PublicKey{
+		Curve: elliptic.P256(),
+		X:     big.NewInt(1), Y: big.NewInt(2),
+	})
+	if err == nil {
+		t.Errorf("expected error, got MarshalPKIXPublicKey success")
+	}
+}
+
 func testParsePKIXPublicKey(t *testing.T, pemBytes string) (pub any) {
 	block, _ := pem.Decode([]byte(pemBytes))
 	pub, err := ParsePKIXPublicKey(block.Bytes)
@@ -101,6 +116,13 @@
 			t.Errorf("Value returned from ParsePKIXPublicKey was not an Ed25519 public key")
 		}
 	})
+	t.Run("X25519", func(t *testing.T) {
+		pub := testParsePKIXPublicKey(t, pemX25519Key)
+		k, ok := pub.(*ecdh.PublicKey)
+		if !ok || k.Curve() != ecdh.X25519() {
+			t.Errorf("Value returned from ParsePKIXPublicKey was not an X25519 public key")
+		}
+	})
 }
 
 var pemPublicKey = `-----BEGIN PUBLIC KEY-----
@@ -139,6 +161,13 @@
 -----END PUBLIC KEY-----
 `
 
+// pemX25519Key was generated from pemX25519Key with "openssl pkey -pubout".
+var pemX25519Key = `
+-----BEGIN PUBLIC KEY-----
+MCowBQYDK2VuAyEA5yGXrH/6OzxuWEhEWS01/f4OP+Of3Yrddy6/J1kDTVM=
+-----END PUBLIC KEY-----
+`
+
 func TestPKIXMismatchPublicKeyFormat(t *testing.T) {
 
 	const pkcs1PublicKey = "308201080282010100817cfed98bcaa2e2a57087451c7674e0c675686dc33ff1268b0c2a6ee0202dec710858ee1c31bdf5e7783582e8ca800be45f3275c6576adc35d98e26e95bb88ca5beb186f853b8745d88bc9102c5f38753bcda519fb05948d5c77ac429255ff8aaf27d9f45d1586e95e2e9ba8a7cb771b8a09dd8c8fed3f933fd9b439bc9f30c475953418ef25f71a2b6496f53d94d39ce850aa0cc75d445b5f5b4f4ee4db78ab197a9a8d8a852f44529a007ac0ac23d895928d60ba538b16b0b087a7f903ed29770e215019b77eaecc360f35f7ab11b6d735978795b2c4a74e5bdea4dc6594cd67ed752a108e666729a753ab36d6c4f606f8760f507e1765be8cd744007e629020103"
@@ -1186,13 +1215,13 @@
 	X509v3 extensions:
 		X509v3 Key Usage: critical
 			Digital Signature, Certificate Sign, CRL Sign
-		X509v3 Extended Key Usage: 
+		X509v3 Extended Key Usage:
 			TLS Web Client Authentication, TLS Web Server Authentication, OCSP Signing
 		X509v3 Basic Constraints: critical
 			CA:TRUE
-		X509v3 Subject Key Identifier: 
+		X509v3 Subject Key Identifier:
 			B7:17:DA:16:EA:C5:ED:1F:18:49:44:D3:D2:E3:A0:35:0A:81:93:60
-		X509v3 Authority Key Identifier: 
+		X509v3 Authority Key Identifier:
 			keyid:B7:17:DA:16:EA:C5:ED:1F:18:49:44:D3:D2:E3:A0:35:0A:81:93:60
 
 Signature Algorithm: ED25519
@@ -1862,9 +1891,7 @@
 		t.Fatalf("certificate verification returned %v (%T), wanted InsecureAlgorithmError", err, err)
 	}
 
-	defer func(old bool) { debugAllowSHA1 = old }(debugAllowSHA1)
-	debugAllowSHA1 = true
-
+	t.Setenv("GODEBUG", "x509sha1=1")
 	if err = cert.CheckSignatureFrom(cert); err != nil {
 		t.Fatalf("SHA-1 certificate did not verify with GODEBUG=x509sha1=1: %v", err)
 	}
@@ -2407,6 +2434,18 @@
 	if err != nil {
 		t.Fatalf("Failed to generate Ed25519 key: %s", err)
 	}
+
+	// Generation command:
+	// openssl req -x509 -newkey rsa -keyout key.pem -out cert.pem -days 365 -nodes -subj '/C=US/ST=California/L=San Francisco/O=Internet Widgets, Inc./OU=WWW/CN=Root/[email protected]' -sha256 -addext basicConstraints=CA:TRUE -addext "keyUsage = digitalSignature, keyEncipherment, dataEncipherment, cRLSign, keyCertSign" -utf8
+	utf8CAStr := "MIIEITCCAwmgAwIBAgIUXHXy7NdtDv+ClaHvIvlwCYiI4a4wDQYJKoZIhvcNAQELBQAwgZoxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMR8wHQYDVQQKDBZJbnRlcm5ldCBXaWRnZXRzLCBJbmMuMQwwCgYDVQQLDANXV1cxDTALBgNVBAMMBFJvb3QxIDAeBgkqhkiG9w0BCQEWEWFkbWluQGV4YW1wbGUuY29tMB4XDTIyMDcwODE1MzgyMFoXDTIzMDcwODE1MzgyMFowgZoxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMR8wHQYDVQQKDBZJbnRlcm5ldCBXaWRnZXRzLCBJbmMuMQwwCgYDVQQLDANXV1cxDTALBgNVBAMMBFJvb3QxIDAeBgkqhkiG9w0BCQEWEWFkbWluQGV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmXvp0WNjsZzySWT7Ce5zewQNKq8ujeZGphJ44Vdrwut/b6TcC4iYENds5+7/3PYwBllp3K5TRpCcafSxdhJsvA7/zWlHHNRcJhJLNt9qsKWP6ukI2Iw6OmFMg6kJQ8f67RXkT8HR3v0UqE+lWrA0g+oRuj4erLtfOtSpnl4nsE/Rs2qxbELFWAf7F5qMqH4dUyveWKrNT8eI6YQN+wBg0MAjoKRvDJnBhuo+IvvXX8Aq1QWUcBGPK3or/Ehxy5f/gEmSUXyEU1Ht/vATt2op+eRaEEpBdGRvO+DrKjlcQV2XMN18A9LAX6hCzH43sGye87dj7RZ9yj+waOYNaM7kFQIDAQABo10wWzAdBgNVHQ4EFgQUtbSlrW4hGL2kNjviM6wcCRwvOEEwHwYDVR0jBBgwFoAUtbSlrW4hGL2kNjviM6wcCRwvOEEwDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAbYwDQYJKoZIhvcNAQELBQADggEBAAko82YNNI2n/45L3ya21vufP6nZihIOIxgcRPUMX+IDJZk16qsFdcLgH3KAP8uiVLn8sULuCj35HpViR4IcAk2d+DqfG11l8kY+e5P7nYsViRfy0AatF59/sYlWf+3RdmPXfL70x4mE9OqlMdDm0kR2obps8rng83VLDNvj3R5sBnQwdw6LKLGzaE+RiCTmkH0+P6vnbOJ33su9+9al1+HvJUg3UM1Xq5Bw7TE8DQTetMV3c2Q35RQaJB9pQ4blJOnW9hfnt8yQzU6TU1bU4mRctTm1o1f8btPqUpi+/blhi5MUJK0/myj1XD00pmyfp8QAFl1EfqmTMIBMLg633A0="
+	utf8CABytes, _ := base64.StdEncoding.DecodeString(utf8CAStr)
+	utf8CA, _ := ParseCertificate(utf8CABytes)
+
+	utf8KeyStr := "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCZe+nRY2OxnPJJZPsJ7nN7BA0qry6N5kamEnjhV2vC639vpNwLiJgQ12zn7v/c9jAGWWncrlNGkJxp9LF2Emy8Dv/NaUcc1FwmEks232qwpY/q6QjYjDo6YUyDqQlDx/rtFeRPwdHe/RSoT6VasDSD6hG6Ph6su1861KmeXiewT9GzarFsQsVYB/sXmoyofh1TK95Yqs1Px4jphA37AGDQwCOgpG8MmcGG6j4i+9dfwCrVBZRwEY8reiv8SHHLl/+ASZJRfIRTUe3+8BO3ain55FoQSkF0ZG874OsqOVxBXZcw3XwD0sBfqELMfjewbJ7zt2PtFn3KP7Bo5g1ozuQVAgMBAAECggEAIscjKiD9PAe2Fs9c2tk/LYazfRKI1/pv072nylfGwToffCq8+ZgP7PEDamKLc4QNScME685MbFbkOlYJyBlQriQv7lmGlY/A+Zd3l410XWaGf9IiAP91Sjk13zd0M/micApf23qtlXt/LMwvSadXnvRw4+SjirxCTdBWRt5K2/ZAN550v7bHFk1EZc3UBF6sOoNsjQWh9Ek79UmQYJBPiZDBHO7O2fh2GSIbUutTma+Tb2i1QUZzg+AG3cseF3p1i3uhNrCh+p+01bJSzGTQsRod2xpD1tpWwR3kIftCOmD1XnhpaBQi7PXjEuNbfucaftnoYj2ShDdmgD5RkkbTAQKBgQC8Ghu5MQ/yIeqXg9IpcSxuWtUEAEfK33/cC/IvuntgbNEnWQm5Lif4D6a9zjkxiCS+9HhrUu5U2EV8NxOyaqmtub3Np1Z5mPuI9oiZ119bjUJd4X+jKOTaePWvOv/rL/pTHYqzXohVMrXy+DaTIq4lOcv3n72SuhuTcKU95rhKtQKBgQDQ4t+HsRZd5fJzoCgRQhlNK3EbXQDv2zXqMW3GfpF7GaDP18I530inRURSJa++rvi7/MCFg/TXVS3QC4HXtbzTYTqhE+VHzSr+/OcsqpLE8b0jKBDv/SBkz811PUJDs3LsX31DT3K0zUpMpNSd/5SYTyJKef9L6mxmwlC1S2Yv4QKBgQC57SiYDdnQIRwrtZ2nXvlm/xttAAX2jqJoU9qIuNA4yHaYaRcGVowlUvsiw9OelQ6VPTpGA0wWy0src5lhkrKzSFRHEe+U89U1VVJCljLoYKFIAJvUH5jOJh/am/vYca0COMIfeAJUDHLyfcwb9XyiyRVGZzvP62tUelSq8gIZvQKBgCAHeaDzzWsudCO4ngwvZ3PGwnwgoaElqrmzRJLYG3SVtGvKOJTpINnNLDGwZ6dEaw1gLyEJ38QY4oJxEULDMiXzVasXQuPkmMAqhUP7D7A1JPw8C4TQ+mOa3XUppHx/CpMl/S4SA5OnmsnvyE5Fv0IveCGVXUkFtAN5rihuXEfhAoGANUkuGU3A0Upk2mzv0JTGP4H95JFG93cqnyPNrYs30M6RkZNgTW27yyr+Nhs4/cMdrg1AYTB0+6ItQWSDmYLs7JEbBE/8L8fdD1irIcygjIHE9nJh96TgZCt61kVGLE8758lOdmoB2rZOpGwi16QIhdQb+IyozYqfX+lQUojL/W0="
+	utf8KeyBytes, _ := base64.StdEncoding.DecodeString(utf8KeyStr)
+	utf8KeyRaw, _ := ParsePKCS8PrivateKey(utf8KeyBytes)
+	utf8Key := utf8KeyRaw.(crypto.Signer)
+
 	tests := []struct {
 		name          string
 		key           crypto.Signer
@@ -2675,6 +2714,16 @@
 				NextUpdate: time.Time{}.Add(time.Hour * 48),
 			},
 		},
+		{
+			name:   "valid CA with utf8 Subject fields including Email, empty list",
+			key:    utf8Key,
+			issuer: utf8CA,
+			template: &RevocationList{
+				Number:     big.NewInt(5),
+				ThisUpdate: time.Time{}.Add(time.Hour * 24),
+				NextUpdate: time.Time{}.Add(time.Hour * 48),
+			},
+		},
 	}
 
 	for _, tc := range tests {
@@ -2734,6 +2783,33 @@
 				t.Fatalf("Unexpected second extension: got %v, want %v",
 					parsedCRL.Extensions[1], crlExt)
 			}
+
+			// With Go 1.19's updated RevocationList, we can now directly compare
+			// the RawSubject of the certificate to RawIssuer on the parsed CRL.
+			// However, this doesn't work with our hacked issuers above (that
+			// aren't parsed from a proper DER bundle but are instead manually
+			// constructed). Prefer RawSubject when it is set.
+			if len(tc.issuer.RawSubject) > 0 {
+				issuerSubj, err := subjectBytes(tc.issuer)
+				if err != nil {
+					t.Fatalf("failed to get issuer subject: %s", err)
+				}
+				if !bytes.Equal(issuerSubj, parsedCRL.RawIssuer) {
+					t.Fatalf("Unexpected issuer subject; wanted: %v, got: %v", hex.EncodeToString(issuerSubj), hex.EncodeToString(parsedCRL.RawIssuer))
+				}
+			} else {
+				// When we hack our custom Subject in the test cases above,
+				// we don't set the additional fields (such as Names) in the
+				// hacked issuer. Round-trip a parsing of pkix.Name so that
+				// we add these missing fields for the comparison.
+				issuerRDN := tc.issuer.Subject.ToRDNSequence()
+				var caIssuer pkix.Name
+				caIssuer.FillFromRDNSequence(&issuerRDN)
+				if !reflect.DeepEqual(caIssuer, parsedCRL.Issuer) {
+					t.Fatalf("Expected issuer.Subject, parsedCRL.Issuer to be the same; wanted: %#v, got: %#v", caIssuer, parsedCRL.Issuer)
+				}
+			}
+
 			if len(parsedCRL.Extensions[2:]) == 0 && len(tc.template.ExtraExtensions) == 0 {
 				// If we don't have anything to check return early so we don't
 				// hit a [] != nil false positive below.
@@ -3456,8 +3532,7 @@
 }
 
 func TestDisableSHA1ForCertOnly(t *testing.T) {
-	defer func(old bool) { debugAllowSHA1 = old }(debugAllowSHA1)
-	debugAllowSHA1 = false
+	t.Setenv("GODEBUG", "")
 
 	tmpl := &Certificate{
 		SerialNumber:          big.NewInt(1),
@@ -3493,13 +3568,12 @@
 	if err != nil {
 		t.Fatalf("failed to generate test CRL: %s", err)
 	}
-	// TODO(rolandshoemaker): this should be ParseRevocationList once it lands
-	crl, err := ParseCRL(crlDER)
+	crl, err := ParseRevocationList(crlDER)
 	if err != nil {
 		t.Fatalf("failed to parse test CRL: %s", err)
 	}
 
-	if err = cert.CheckCRLSignature(crl); err != nil {
+	if err = crl.CheckSignatureFrom(cert); err != nil {
 		t.Errorf("unexpected error: %s", err)
 	}
 
@@ -3739,10 +3813,32 @@
 func TestDuplicateExtensionsCSR(t *testing.T) {
 	b, _ := pem.Decode([]byte(dupExtCSR))
 	if b == nil {
-		t.Fatalf("couldn't decode test certificate")
+		t.Fatalf("couldn't decode test CSR")
 	}
 	_, err := ParseCertificateRequest(b.Bytes)
 	if err == nil {
-		t.Fatal("ParseCertificate should fail when parsing certificate with duplicate extensions")
+		t.Fatal("ParseCertificateRequest should fail when parsing CSR with duplicate extensions")
+	}
+}
+
+const dupAttCSR = `-----BEGIN CERTIFICATE REQUEST-----
+MIIBbDCB1gIBADAPMQ0wCwYDVQQDEwR0ZXN0MIGfMA0GCSqGSIb3DQEBAQUAA4GN
+ADCBiQKBgQCj5Po3PKO/JNuxr+B+WNfMIzqqYztdlv+mTQhT0jOR5rTkUvxeeHH8
+YclryES2dOISjaUOTmOAr5GQIIdQl4Ql33Cp7ZR/VWcRn+qvTak0Yow+xVsDo0n4
+7IcvvP6CJ7FRoYBUakVczeXLxCjLwdyK16VGJM06eRzDLykPxpPwLQIDAQABoB4w
+DQYCKgMxBwwFdGVzdDEwDQYCKgMxBwwFdGVzdDIwDQYJKoZIhvcNAQELBQADgYEA
+UJ8hsHxtnIeqb2ufHnQFJO+wEJhx2Uxm/BTuzHOeffuQkwATez4skZ7SlX9exgb7
+6jRMRilqb4F7f8w+uDoqxRrA9zc8mwY16zPsyBhRet+ZGbj/ilgvGmtZ21qZZ/FU
+0pJFJIVLM3l49Onr5uIt5+hCWKwHlgE0nGpjKLR3cMg=
+-----END CERTIFICATE REQUEST-----`
+
+func TestDuplicateAttributesCSR(t *testing.T) {
+	b, _ := pem.Decode([]byte(dupAttCSR))
+	if b == nil {
+		t.Fatalf("couldn't decode test CSR")
+	}
+	_, err := ParseCertificateRequest(b.Bytes)
+	if err != nil {
+		t.Fatal("ParseCertificateRequest should succeed when parsing CSR with duplicate attributes")
 	}
 }
diff --git a/src/database/sql/convert.go b/src/database/sql/convert.go
index 4d9d070..32941cb 100644
--- a/src/database/sql/convert.go
+++ b/src/database/sql/convert.go
@@ -7,6 +7,7 @@
 package sql
 
 import (
+	"bytes"
 	"database/sql/driver"
 	"errors"
 	"fmt"
@@ -252,13 +253,13 @@
 			if d == nil {
 				return errNilPtr
 			}
-			*d = cloneBytes(s)
+			*d = bytes.Clone(s)
 			return nil
 		case *[]byte:
 			if d == nil {
 				return errNilPtr
 			}
-			*d = cloneBytes(s)
+			*d = bytes.Clone(s)
 			return nil
 		case *RawBytes:
 			if d == nil {
@@ -401,7 +402,7 @@
 	if sv.IsValid() && sv.Type().AssignableTo(dv.Type()) {
 		switch b := src.(type) {
 		case []byte:
-			dv.Set(reflect.ValueOf(cloneBytes(b)))
+			dv.Set(reflect.ValueOf(bytes.Clone(b)))
 		default:
 			dv.Set(sv)
 		}
@@ -486,15 +487,6 @@
 	return err
 }
 
-func cloneBytes(b []byte) []byte {
-	if b == nil {
-		return nil
-	}
-	c := make([]byte, len(b))
-	copy(c, b)
-	return c
-}
-
 func asString(src any) string {
 	switch v := src.(type) {
 	case string:
diff --git a/src/database/sql/sql.go b/src/database/sql/sql.go
index 854a895..ad17eb3 100644
--- a/src/database/sql/sql.go
+++ b/src/database/sql/sql.go
@@ -453,15 +453,14 @@
 // connection is returned to DB's idle connection pool. The pool size
 // can be controlled with SetMaxIdleConns.
 type DB struct {
-	// Atomic access only. At top of struct to prevent mis-alignment
-	// on 32-bit platforms. Of type time.Duration.
-	waitDuration int64 // Total time waited for new connections.
+	// Total time waited for new connections.
+	waitDuration atomic.Int64
 
 	connector driver.Connector
 	// numClosed is an atomic counter which represents a total number of
 	// closed connections. Stmt.openStmt checks it before cleaning closed
 	// connections in Stmt.css.
-	numClosed uint64
+	numClosed atomic.Uint64
 
 	mu           sync.Mutex    // protects following fields
 	freeConn     []*driverConn // free connections ordered by returnedAt oldest to newest
@@ -651,7 +650,7 @@
 	dc.db.maybeOpenNewConnections()
 	dc.db.mu.Unlock()
 
-	atomic.AddUint64(&dc.db.numClosed, 1)
+	dc.db.numClosed.Add(1)
 	return err
 }
 
@@ -846,17 +845,12 @@
 func (db *DB) PingContext(ctx context.Context) error {
 	var dc *driverConn
 	var err error
-	var isBadConn bool
-	for i := 0; i < maxBadConnRetries; i++ {
-		dc, err = db.conn(ctx, cachedOrNewConn)
-		isBadConn = errors.Is(err, driver.ErrBadConn)
-		if !isBadConn {
-			break
-		}
-	}
-	if isBadConn {
-		dc, err = db.conn(ctx, alwaysNewConn)
-	}
+
+	err = db.retry(func(strategy connReuseStrategy) error {
+		dc, err = db.conn(ctx, strategy)
+		return err
+	})
+
 	if err != nil {
 		return err
 	}
@@ -1176,7 +1170,7 @@
 
 // Stats returns database statistics.
 func (db *DB) Stats() DBStats {
-	wait := atomic.LoadInt64(&db.waitDuration)
+	wait := db.waitDuration.Load()
 
 	db.mu.Lock()
 	defer db.mu.Unlock()
@@ -1346,7 +1340,7 @@
 			delete(db.connRequests, reqKey)
 			db.mu.Unlock()
 
-			atomic.AddInt64(&db.waitDuration, int64(time.Since(waitStart)))
+			db.waitDuration.Add(int64(time.Since(waitStart)))
 
 			select {
 			default:
@@ -1357,7 +1351,7 @@
 			}
 			return nil, ctx.Err()
 		case ret, ok := <-req:
-			atomic.AddInt64(&db.waitDuration, int64(time.Since(waitStart)))
+			db.waitDuration.Add(int64(time.Since(waitStart)))
 
 			if !ok {
 				return nil, errDBClosed
@@ -1539,6 +1533,18 @@
 // connection to be opened.
 const maxBadConnRetries = 2
 
+func (db *DB) retry(fn func(strategy connReuseStrategy) error) error {
+	for i := int64(0); i < maxBadConnRetries; i++ {
+		err := fn(cachedOrNewConn)
+		// retry if err is driver.ErrBadConn
+		if err == nil || !errors.Is(err, driver.ErrBadConn) {
+			return err
+		}
+	}
+
+	return fn(alwaysNewConn)
+}
+
 // PrepareContext creates a prepared statement for later queries or executions.
 // Multiple queries or executions may be run concurrently from the
 // returned statement.
@@ -1550,17 +1556,12 @@
 func (db *DB) PrepareContext(ctx context.Context, query string) (*Stmt, error) {
 	var stmt *Stmt
 	var err error
-	var isBadConn bool
-	for i := 0; i < maxBadConnRetries; i++ {
-		stmt, err = db.prepare(ctx, query, cachedOrNewConn)
-		isBadConn = errors.Is(err, driver.ErrBadConn)
-		if !isBadConn {
-			break
-		}
-	}
-	if isBadConn {
-		return db.prepare(ctx, query, alwaysNewConn)
-	}
+
+	err = db.retry(func(strategy connReuseStrategy) error {
+		stmt, err = db.prepare(ctx, query, strategy)
+		return err
+	})
+
 	return stmt, err
 }
 
@@ -1617,7 +1618,7 @@
 	// the DB.
 	if cg == nil {
 		stmt.css = []connStmt{{dc, ds}}
-		stmt.lastNumClosed = atomic.LoadUint64(&db.numClosed)
+		stmt.lastNumClosed = db.numClosed.Load()
 		db.addDep(stmt, stmt)
 	}
 	return stmt, nil
@@ -1628,17 +1629,12 @@
 func (db *DB) ExecContext(ctx context.Context, query string, args ...any) (Result, error) {
 	var res Result
 	var err error
-	var isBadConn bool
-	for i := 0; i < maxBadConnRetries; i++ {
-		res, err = db.exec(ctx, query, args, cachedOrNewConn)
-		isBadConn = errors.Is(err, driver.ErrBadConn)
-		if !isBadConn {
-			break
-		}
-	}
-	if isBadConn {
-		return db.exec(ctx, query, args, alwaysNewConn)
-	}
+
+	err = db.retry(func(strategy connReuseStrategy) error {
+		res, err = db.exec(ctx, query, args, strategy)
+		return err
+	})
+
 	return res, err
 }
 
@@ -1703,17 +1699,12 @@
 func (db *DB) QueryContext(ctx context.Context, query string, args ...any) (*Rows, error) {
 	var rows *Rows
 	var err error
-	var isBadConn bool
-	for i := 0; i < maxBadConnRetries; i++ {
-		rows, err = db.query(ctx, query, args, cachedOrNewConn)
-		isBadConn = errors.Is(err, driver.ErrBadConn)
-		if !isBadConn {
-			break
-		}
-	}
-	if isBadConn {
-		return db.query(ctx, query, args, alwaysNewConn)
-	}
+
+	err = db.retry(func(strategy connReuseStrategy) error {
+		rows, err = db.query(ctx, query, args, strategy)
+		return err
+	})
+
 	return rows, err
 }
 
@@ -1840,17 +1831,12 @@
 func (db *DB) BeginTx(ctx context.Context, opts *TxOptions) (*Tx, error) {
 	var tx *Tx
 	var err error
-	var isBadConn bool
-	for i := 0; i < maxBadConnRetries; i++ {
-		tx, err = db.begin(ctx, opts, cachedOrNewConn)
-		isBadConn = errors.Is(err, driver.ErrBadConn)
-		if !isBadConn {
-			break
-		}
-	}
-	if isBadConn {
-		return db.begin(ctx, opts, alwaysNewConn)
-	}
+
+	err = db.retry(func(strategy connReuseStrategy) error {
+		tx, err = db.begin(ctx, opts, strategy)
+		return err
+	})
+
 	return tx, err
 }
 
@@ -1921,17 +1907,12 @@
 func (db *DB) Conn(ctx context.Context) (*Conn, error) {
 	var dc *driverConn
 	var err error
-	var isBadConn bool
-	for i := 0; i < maxBadConnRetries; i++ {
-		dc, err = db.conn(ctx, cachedOrNewConn)
-		isBadConn = errors.Is(err, driver.ErrBadConn)
-		if !isBadConn {
-			break
-		}
-	}
-	if isBadConn {
-		dc, err = db.conn(ctx, alwaysNewConn)
-	}
+
+	err = db.retry(func(strategy connReuseStrategy) error {
+		dc, err = db.conn(ctx, strategy)
+		return err
+	})
+
 	if err != nil {
 		return nil, err
 	}
@@ -2154,11 +2135,10 @@
 	// any held driverConn back to the pool.
 	releaseConn func(error)
 
-	// done transitions from 0 to 1 exactly once, on Commit
+	// done transitions from false to true exactly once, on Commit
 	// or Rollback. once done, all operations fail with
 	// ErrTxDone.
-	// Use atomic operations on value when checking value.
-	done int32
+	done atomic.Bool
 
 	// keepConnOnRollback is true if the driver knows
 	// how to reset the connection's session and if need be discard
@@ -2197,7 +2177,7 @@
 }
 
 func (tx *Tx) isDone() bool {
-	return atomic.LoadInt32(&tx.done) != 0
+	return tx.done.Load()
 }
 
 // ErrTxDone is returned by any operation that is performed on a transaction
@@ -2266,12 +2246,12 @@
 	select {
 	default:
 	case <-tx.ctx.Done():
-		if atomic.LoadInt32(&tx.done) == 1 {
+		if tx.done.Load() {
 			return ErrTxDone
 		}
 		return tx.ctx.Err()
 	}
-	if !atomic.CompareAndSwapInt32(&tx.done, 0, 1) {
+	if !tx.done.CompareAndSwap(false, true) {
 		return ErrTxDone
 	}
 
@@ -2299,7 +2279,7 @@
 // rollback aborts the transaction and optionally forces the pool to discard
 // the connection.
 func (tx *Tx) rollback(discardConn bool) error {
-	if !atomic.CompareAndSwapInt32(&tx.done, 0, 1) {
+	if !tx.done.CompareAndSwap(false, true) {
 		return ErrTxDone
 	}
 
@@ -2620,26 +2600,18 @@
 	defer s.closemu.RUnlock()
 
 	var res Result
-	strategy := cachedOrNewConn
-	for i := 0; i < maxBadConnRetries+1; i++ {
-		if i == maxBadConnRetries {
-			strategy = alwaysNewConn
-		}
+	err := s.db.retry(func(strategy connReuseStrategy) error {
 		dc, releaseConn, ds, err := s.connStmt(ctx, strategy)
 		if err != nil {
-			if errors.Is(err, driver.ErrBadConn) {
-				continue
-			}
-			return nil, err
+			return err
 		}
 
 		res, err = resultFromStatement(ctx, dc.ci, ds, args...)
 		releaseConn(err)
-		if !errors.Is(err, driver.ErrBadConn) {
-			return res, err
-		}
-	}
-	return nil, driver.ErrBadConn
+		return err
+	})
+
+	return res, err
 }
 
 // Exec executes a prepared statement with the given arguments and
@@ -2676,7 +2648,7 @@
 	if t > 10 {
 		t = 10
 	}
-	dbClosed := atomic.LoadUint64(&s.db.numClosed)
+	dbClosed := s.db.numClosed.Load()
 	if dbClosed-s.lastNumClosed < uint64(t) {
 		return
 	}
@@ -2768,24 +2740,19 @@
 	defer s.closemu.RUnlock()
 
 	var rowsi driver.Rows
-	strategy := cachedOrNewConn
-	for i := 0; i < maxBadConnRetries+1; i++ {
-		if i == maxBadConnRetries {
-			strategy = alwaysNewConn
-		}
+	var rows *Rows
+
+	err := s.db.retry(func(strategy connReuseStrategy) error {
 		dc, releaseConn, ds, err := s.connStmt(ctx, strategy)
 		if err != nil {
-			if errors.Is(err, driver.ErrBadConn) {
-				continue
-			}
-			return nil, err
+			return err
 		}
 
 		rowsi, err = rowsiFromStatement(ctx, dc.ci, ds, args...)
 		if err == nil {
 			// Note: ownership of ci passes to the *Rows, to be freed
 			// with releaseConn.
-			rows := &Rows{
+			rows = &Rows{
 				dc:    dc,
 				rowsi: rowsi,
 				// releaseConn set below
@@ -2805,15 +2772,14 @@
 				txctx = s.cg.txCtx()
 			}
 			rows.initContextClose(ctx, txctx)
-			return rows, nil
+			return nil
 		}
 
 		releaseConn(err)
-		if !errors.Is(err, driver.ErrBadConn) {
-			return nil, err
-		}
-	}
-	return nil, driver.ErrBadConn
+		return err
+	})
+
+	return rows, err
 }
 
 // Query executes a prepared query statement with the given arguments
@@ -3262,7 +3228,7 @@
 // select query will close any cursor *Rows if the parent *Rows is closed.
 //
 // If any of the first arguments implementing Scanner returns an error,
-// that error will be wrapped in the returned error
+// that error will be wrapped in the returned error.
 func (rs *Rows) Scan(dest ...any) error {
 	rs.closemu.RLock()
 
diff --git a/src/debug/buildinfo/buildinfo.go b/src/debug/buildinfo/buildinfo.go
index d1f4892..8bc5753 100644
--- a/src/debug/buildinfo/buildinfo.go
+++ b/src/debug/buildinfo/buildinfo.go
@@ -15,6 +15,7 @@
 	"debug/elf"
 	"debug/macho"
 	"debug/pe"
+	"debug/plan9obj"
 	"encoding/binary"
 	"errors"
 	"fmt"
@@ -130,6 +131,12 @@
 			return "", "", errUnrecognizedFormat
 		}
 		x = &xcoffExe{f}
+	case hasPlan9Magic(ident):
+		f, err := plan9obj.NewFile(r)
+		if err != nil {
+			return "", "", errUnrecognizedFormat
+		}
+		x = &plan9objExe{f}
 	default:
 		return "", "", errUnrecognizedFormat
 	}
@@ -157,7 +164,7 @@
 			data = data[i:]
 			break
 		}
-		data = data[(i+buildInfoAlign-1)&^buildInfoAlign:]
+		data = data[(i+buildInfoAlign-1)&^(buildInfoAlign-1):]
 	}
 
 	// Decode the blob.
@@ -185,8 +192,10 @@
 		var readPtr func([]byte) uint64
 		if ptrSize == 4 {
 			readPtr = func(b []byte) uint64 { return uint64(bo.Uint32(b)) }
-		} else {
+		} else if ptrSize == 8 {
 			readPtr = bo.Uint64
+		} else {
+			return "", "", errNotGoExe
 		}
 		vers = readString(x, ptrSize, readPtr, readPtr(data[16:]))
 		mod = readString(x, ptrSize, readPtr, readPtr(data[16+ptrSize:]))
@@ -205,6 +214,17 @@
 	return vers, mod, nil
 }
 
+func hasPlan9Magic(magic []byte) bool {
+	if len(magic) >= 4 {
+		m := binary.BigEndian.Uint32(magic)
+		switch m {
+		case plan9obj.Magic386, plan9obj.MagicAMD64, plan9obj.MagicARM:
+			return true
+		}
+	}
+	return false
+}
+
 func decodeString(data []byte) (s string, rest []byte) {
 	u, n := binary.Uvarint(data)
 	if n <= 0 || u >= uint64(len(data)-n) {
@@ -376,20 +396,20 @@
 
 func (x *xcoffExe) ReadData(addr, size uint64) ([]byte, error) {
 	for _, sect := range x.f.Sections {
-		if uint64(sect.VirtualAddress) <= addr && addr <= uint64(sect.VirtualAddress+sect.Size-1) {
-			n := uint64(sect.VirtualAddress+sect.Size) - addr
+		if sect.VirtualAddress <= addr && addr <= sect.VirtualAddress+sect.Size-1 {
+			n := sect.VirtualAddress + sect.Size - addr
 			if n > size {
 				n = size
 			}
 			data := make([]byte, n)
-			_, err := sect.ReadAt(data, int64(addr-uint64(sect.VirtualAddress)))
+			_, err := sect.ReadAt(data, int64(addr-sect.VirtualAddress))
 			if err != nil {
 				return nil, err
 			}
 			return data, nil
 		}
 	}
-	return nil, fmt.Errorf("address not mapped")
+	return nil, errors.New("address not mapped")
 }
 
 func (x *xcoffExe) DataStart() uint64 {
@@ -398,3 +418,34 @@
 	}
 	return 0
 }
+
+// plan9objExe is the Plan 9 a.out implementation of the exe interface.
+type plan9objExe struct {
+	f *plan9obj.File
+}
+
+func (x *plan9objExe) DataStart() uint64 {
+	if s := x.f.Section("data"); s != nil {
+		return uint64(s.Offset)
+	}
+	return 0
+}
+
+func (x *plan9objExe) ReadData(addr, size uint64) ([]byte, error) {
+	for _, sect := range x.f.Sections {
+		if uint64(sect.Offset) <= addr && addr <= uint64(sect.Offset+sect.Size-1) {
+			n := uint64(sect.Offset+sect.Size) - addr
+			if n > size {
+				n = size
+			}
+			data := make([]byte, n)
+			_, err := sect.ReadAt(data, int64(addr-uint64(sect.Offset)))
+			if err != nil {
+				return nil, err
+			}
+			return data, nil
+		}
+	}
+	return nil, errors.New("address not mapped")
+
+}
diff --git a/src/debug/buildinfo/buildinfo_test.go b/src/debug/buildinfo/buildinfo_test.go
index 0affc83..290e370 100644
--- a/src/debug/buildinfo/buildinfo_test.go
+++ b/src/debug/buildinfo/buildinfo_test.go
@@ -7,7 +7,10 @@
 import (
 	"bytes"
 	"debug/buildinfo"
+	"debug/pe"
+	"encoding/binary"
 	"flag"
+	"fmt"
 	"internal/testenv"
 	"os"
 	"os/exec"
@@ -53,7 +56,17 @@
 		platforms = append(platforms, runtimePlatform)
 	}
 
-	buildWithModules := func(t *testing.T, goos, goarch string) string {
+	buildModes := []string{"pie", "exe"}
+	if testenv.HasCGO() {
+		buildModes = append(buildModes, "c-shared")
+	}
+
+	// Keep in sync with src/cmd/go/internal/work/init.go:buildModeInit.
+	badmode := func(goos, goarch, buildmode string) string {
+		return fmt.Sprintf("-buildmode=%s not supported on %s/%s", buildmode, goos, goarch)
+	}
+
+	buildWithModules := func(t *testing.T, goos, goarch, buildmode string) string {
 		dir := t.TempDir()
 		gomodPath := filepath.Join(dir, "go.mod")
 		gomodData := []byte("module example.com/m\ngo 1.18\n")
@@ -66,18 +79,21 @@
 			t.Fatal(err)
 		}
 		outPath := filepath.Join(dir, path.Base(t.Name()))
-		cmd := exec.Command(testenv.GoToolPath(t), "build", "-o="+outPath)
+		cmd := exec.Command(testenv.GoToolPath(t), "build", "-o="+outPath, "-buildmode="+buildmode)
 		cmd.Dir = dir
 		cmd.Env = append(os.Environ(), "GO111MODULE=on", "GOOS="+goos, "GOARCH="+goarch)
-		stderr := &bytes.Buffer{}
+		stderr := &strings.Builder{}
 		cmd.Stderr = stderr
 		if err := cmd.Run(); err != nil {
-			t.Fatalf("failed building test file: %v\n%s", err, stderr.Bytes())
+			if badmodeMsg := badmode(goos, goarch, buildmode); strings.Contains(stderr.String(), badmodeMsg) {
+				t.Skip(badmodeMsg)
+			}
+			t.Fatalf("failed building test file: %v\n%s", err, stderr.String())
 		}
 		return outPath
 	}
 
-	buildWithGOPATH := func(t *testing.T, goos, goarch string) string {
+	buildWithGOPATH := func(t *testing.T, goos, goarch, buildmode string) string {
 		gopathDir := t.TempDir()
 		pkgDir := filepath.Join(gopathDir, "src/example.com/m")
 		if err := os.MkdirAll(pkgDir, 0777); err != nil {
@@ -89,13 +105,16 @@
 			t.Fatal(err)
 		}
 		outPath := filepath.Join(gopathDir, path.Base(t.Name()))
-		cmd := exec.Command(testenv.GoToolPath(t), "build", "-o="+outPath)
+		cmd := exec.Command(testenv.GoToolPath(t), "build", "-o="+outPath, "-buildmode="+buildmode)
 		cmd.Dir = pkgDir
 		cmd.Env = append(os.Environ(), "GO111MODULE=off", "GOPATH="+gopathDir, "GOOS="+goos, "GOARCH="+goarch)
-		stderr := &bytes.Buffer{}
+		stderr := &strings.Builder{}
 		cmd.Stderr = stderr
 		if err := cmd.Run(); err != nil {
-			t.Fatalf("failed building test file: %v\n%s", err, stderr.Bytes())
+			if badmodeMsg := badmode(goos, goarch, buildmode); strings.Contains(stderr.String(), badmodeMsg) {
+				t.Skip(badmodeMsg)
+			}
+			t.Fatalf("failed building test file: %v\n%s", err, stderr.String())
 		}
 		return outPath
 	}
@@ -134,20 +153,20 @@
 
 	cases := []struct {
 		name    string
-		build   func(t *testing.T, goos, goarch string) string
+		build   func(t *testing.T, goos, goarch, buildmode string) string
 		want    string
 		wantErr string
 	}{
 		{
 			name: "doesnotexist",
-			build: func(t *testing.T, goos, goarch string) string {
+			build: func(t *testing.T, goos, goarch, buildmode string) string {
 				return "doesnotexist.txt"
 			},
 			wantErr: "doesnotexist",
 		},
 		{
 			name: "empty",
-			build: func(t *testing.T, _, _ string) string {
+			build: func(t *testing.T, _, _, _ string) string {
 				dir := t.TempDir()
 				name := filepath.Join(dir, "empty")
 				if err := os.WriteFile(name, nil, 0666); err != nil {
@@ -167,8 +186,8 @@
 		},
 		{
 			name: "invalid_modules",
-			build: func(t *testing.T, goos, goarch string) string {
-				name := buildWithModules(t, goos, goarch)
+			build: func(t *testing.T, goos, goarch, buildmode string) string {
+				name := buildWithModules(t, goos, goarch, buildmode)
 				damageBuildInfo(t, name)
 				return name
 			},
@@ -183,8 +202,8 @@
 		},
 		{
 			name: "invalid_gopath",
-			build: func(t *testing.T, goos, goarch string) string {
-				name := buildWithGOPATH(t, goos, goarch)
+			build: func(t *testing.T, goos, goarch, buildmode string) string {
+				name := buildWithGOPATH(t, goos, goarch, buildmode)
 				damageBuildInfo(t, name)
 				return name
 			},
@@ -198,28 +217,113 @@
 			if p != runtimePlatform && !*flagAll {
 				t.Skipf("skipping platforms other than %s_%s because -all was not set", runtimePlatform.goos, runtimePlatform.goarch)
 			}
-			for _, tc := range cases {
-				tc := tc
-				t.Run(tc.name, func(t *testing.T) {
-					t.Parallel()
-					name := tc.build(t, p.goos, p.goarch)
-					if info, err := buildinfo.ReadFile(name); err != nil {
-						if tc.wantErr == "" {
-							t.Fatalf("unexpected error: %v", err)
-						} else if errMsg := err.Error(); !strings.Contains(errMsg, tc.wantErr) {
-							t.Fatalf("got error %q; want error containing %q", errMsg, tc.wantErr)
-						}
-					} else {
-						if tc.wantErr != "" {
-							t.Fatalf("unexpected success; want error containing %q", tc.wantErr)
-						}
-						got := info.String()
-						if clean := cleanOutputForComparison(string(got)); got != tc.want && clean != tc.want {
-							t.Fatalf("got:\n%s\nwant:\n%s", got, tc.want)
-						}
+			for _, mode := range buildModes {
+				mode := mode
+				t.Run(mode, func(t *testing.T) {
+					for _, tc := range cases {
+						tc := tc
+						t.Run(tc.name, func(t *testing.T) {
+							t.Parallel()
+							name := tc.build(t, p.goos, p.goarch, mode)
+							if info, err := buildinfo.ReadFile(name); err != nil {
+								if tc.wantErr == "" {
+									t.Fatalf("unexpected error: %v", err)
+								} else if errMsg := err.Error(); !strings.Contains(errMsg, tc.wantErr) {
+									t.Fatalf("got error %q; want error containing %q", errMsg, tc.wantErr)
+								}
+							} else {
+								if tc.wantErr != "" {
+									t.Fatalf("unexpected success; want error containing %q", tc.wantErr)
+								}
+								got := info.String()
+								if clean := cleanOutputForComparison(string(got)); got != tc.want && clean != tc.want {
+									t.Fatalf("got:\n%s\nwant:\n%s", got, tc.want)
+								}
+							}
+						})
 					}
 				})
 			}
 		})
 	}
 }
+
+// FuzzIssue57002 is a regression test for golang.org/issue/57002.
+//
+// The cause of issue 57002 is when pointerSize is not being checked,
+// the read can panic with slice bounds out of range
+func FuzzIssue57002(f *testing.F) {
+	// input from issue
+	f.Add([]byte{0x4d, 0x5a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x45, 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x20, 0x20, 0x20, 0x20, 0x0, 0x0, 0x0, 0x0, 0x20, 0x3f, 0x0, 0x20, 0x0, 0x0, 0x20, 0x20, 0x20, 0x20, 0x20, 0xff, 0x20, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb, 0x20, 0x20, 0x20, 0xfc, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x9, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x20, 0x20, 0x20, 0x20, 0x20, 0xef, 0x20, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf, 0x0, 0x2, 0x0, 0x20, 0x0, 0x0, 0x9, 0x0, 0x4, 0x0, 0x20, 0xf6, 0x0, 0xd3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x1, 0x0, 0x0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xa, 0x20, 0xa, 0x20, 0x20, 0x20, 0xff, 0x20, 0x20, 0xff, 0x20, 0x47, 0x6f, 0x20, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x69, 0x6e, 0x66, 0x3a, 0xde, 0xb5, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x7f, 0x7f, 0x7f, 0x20, 0xf4, 0xb2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x20, 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x20, 0x20, 0x20, 0x20, 0x0, 0x0, 0x0, 0x0, 0x20, 0x3f, 0x27, 0x20, 0x0, 0xd, 0x0, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0xff, 0x20, 0x20, 0xff, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0, 0x20, 0x20, 0x0, 0x0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5c, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20})
+	f.Fuzz(func(t *testing.T, input []byte) {
+		buildinfo.Read(bytes.NewReader(input))
+	})
+}
+
+// TestIssue54968 is a regression test for golang.org/issue/54968.
+//
+// The cause of issue 54968 is when the first buildInfoMagic is invalid, it
+// enters an infinite loop.
+func TestIssue54968(t *testing.T) {
+	t.Parallel()
+
+	const (
+		paddingSize    = 200
+		buildInfoAlign = 16
+	)
+	buildInfoMagic := []byte("\xff Go buildinf:")
+
+	// Construct a valid PE header.
+	var buf bytes.Buffer
+
+	buf.Write([]byte{'M', 'Z'})
+	buf.Write(bytes.Repeat([]byte{0}, 0x3c-2))
+	// At location 0x3c, the stub has the file offset to the PE signature.
+	binary.Write(&buf, binary.LittleEndian, int32(0x3c+4))
+
+	buf.Write([]byte{'P', 'E', 0, 0})
+
+	binary.Write(&buf, binary.LittleEndian, pe.FileHeader{NumberOfSections: 1})
+
+	sh := pe.SectionHeader32{
+		Name:             [8]uint8{'t', 0},
+		SizeOfRawData:    uint32(paddingSize + len(buildInfoMagic)),
+		PointerToRawData: uint32(buf.Len()),
+	}
+	sh.PointerToRawData = uint32(buf.Len() + binary.Size(sh))
+
+	binary.Write(&buf, binary.LittleEndian, sh)
+
+	start := buf.Len()
+	buf.Write(bytes.Repeat([]byte{0}, paddingSize+len(buildInfoMagic)))
+	data := buf.Bytes()
+
+	if _, err := pe.NewFile(bytes.NewReader(data)); err != nil {
+		t.Fatalf("need a valid PE header for the misaligned buildInfoMagic test: %s", err)
+	}
+
+	// Place buildInfoMagic after the header.
+	for i := 1; i < paddingSize-len(buildInfoMagic); i++ {
+		// Test only misaligned buildInfoMagic.
+		if i%buildInfoAlign == 0 {
+			continue
+		}
+
+		t.Run(fmt.Sprintf("start_at_%d", i), func(t *testing.T) {
+			d := data[:start]
+			// Construct intentionally-misaligned buildInfoMagic.
+			d = append(d, bytes.Repeat([]byte{0}, i)...)
+			d = append(d, buildInfoMagic...)
+			d = append(d, bytes.Repeat([]byte{0}, paddingSize-i)...)
+
+			_, err := buildinfo.Read(bytes.NewReader(d))
+
+			wantErr := "not a Go executable"
+			if err == nil {
+				t.Errorf("got error nil; want error containing %q", wantErr)
+			} else if errMsg := err.Error(); !strings.Contains(errMsg, wantErr) {
+				t.Errorf("got error %q; want error containing %q", errMsg, wantErr)
+			}
+		})
+	}
+}
diff --git a/src/debug/dwarf/entry.go b/src/debug/dwarf/entry.go
index 6f80d07..5bb4297 100644
--- a/src/debug/dwarf/entry.go
+++ b/src/debug/dwarf/entry.go
@@ -13,6 +13,7 @@
 import (
 	"encoding/binary"
 	"errors"
+	"fmt"
 	"strconv"
 )
 
@@ -33,7 +34,7 @@
 // a map from entry format ids to their descriptions
 type abbrevTable map[uint32]abbrev
 
-// ParseAbbrev returns the abbreviation table that starts at byte off
+// parseAbbrev returns the abbreviation table that starts at byte off
 // in the .debug_abbrev section.
 func (d *Data) parseAbbrev(off uint64, vers int) (abbrevTable, error) {
 	if m, ok := d.abbrevCache[off]; ok {
@@ -1103,6 +1104,9 @@
 }
 
 func (d *Data) dwarf2Ranges(u *unit, base uint64, ranges int64, ret [][2]uint64) ([][2]uint64, error) {
+	if ranges < 0 || ranges > int64(len(d.ranges)) {
+		return nil, fmt.Errorf("invalid range offset %d (max %d)", ranges, len(d.ranges))
+	}
 	buf := makeBuf(d, u, "ranges", Offset(ranges), d.ranges[ranges:])
 	for len(buf.data) > 0 {
 		low := buf.addr()
@@ -1125,6 +1129,9 @@
 // dwarf5Ranges interprets a debug_rnglists sequence, see DWARFv5 section
 // 2.17.3 (page 53).
 func (d *Data) dwarf5Ranges(u *unit, cu *Entry, base uint64, ranges int64, ret [][2]uint64) ([][2]uint64, error) {
+	if ranges < 0 || ranges > int64(len(d.rngLists)) {
+		return nil, fmt.Errorf("invalid rnglist offset %d (max %d)", ranges, len(d.ranges))
+	}
 	var addrBase int64
 	if cu != nil {
 		addrBase, _ = cu.Val(AttrAddrBase).(int64)
diff --git a/src/debug/dwarf/open.go b/src/debug/dwarf/open.go
index e94103a..994b726 100644
--- a/src/debug/dwarf/open.go
+++ b/src/debug/dwarf/open.go
@@ -2,9 +2,19 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Package dwarf provides access to DWARF debugging information loaded from
-// executable files, as defined in the DWARF 2.0 Standard at
-// http://dwarfstd.org/doc/dwarf-2.0.0.pdf
+/*
+Package dwarf provides access to DWARF debugging information loaded from
+executable files, as defined in the DWARF 2.0 Standard at
+http://dwarfstd.org/doc/dwarf-2.0.0.pdf.
+
+# Security
+
+This package is not designed to be hardened against adversarial inputs, and is
+outside the scope of https://go.dev/security/policy. In particular, only basic
+validation is done when parsing object files. As such, care should be taken when
+parsing untrusted inputs, as parsing malformed files may consume significant
+resources, or cause panics.
+*/
 package dwarf
 
 import (
diff --git a/src/debug/elf/elf.go b/src/debug/elf/elf.go
index 5b2e6d9..02cda16 100644
--- a/src/debug/elf/elf.go
+++ b/src/debug/elf/elf.go
@@ -735,7 +735,7 @@
 )
 
 var compressionStrings = []intName{
-	{0, "COMPRESS_ZLIB"},
+	{1, "COMPRESS_ZLIB"},
 	{0x60000000, "COMPRESS_LOOS"},
 	{0x6fffffff, "COMPRESS_HIOS"},
 	{0x70000000, "COMPRESS_LOPROC"},
@@ -2152,7 +2152,7 @@
 func (i R_MIPS) String() string   { return stringName(uint32(i), rmipsStrings, false) }
 func (i R_MIPS) GoString() string { return stringName(uint32(i), rmipsStrings, true) }
 
-// Relocation types for LARCH.
+// Relocation types for LoongArch.
 type R_LARCH int
 
 const (
@@ -2206,6 +2206,45 @@
 	R_LARCH_SUB24                      R_LARCH = 54
 	R_LARCH_SUB32                      R_LARCH = 55
 	R_LARCH_SUB64                      R_LARCH = 56
+	R_LARCH_GNU_VTINHERIT              R_LARCH = 57
+	R_LARCH_GNU_VTENTRY                R_LARCH = 58
+	R_LARCH_B16                        R_LARCH = 64
+	R_LARCH_B21                        R_LARCH = 65
+	R_LARCH_B26                        R_LARCH = 66
+	R_LARCH_ABS_HI20                   R_LARCH = 67
+	R_LARCH_ABS_LO12                   R_LARCH = 68
+	R_LARCH_ABS64_LO20                 R_LARCH = 69
+	R_LARCH_ABS64_HI12                 R_LARCH = 70
+	R_LARCH_PCALA_HI20                 R_LARCH = 71
+	R_LARCH_PCALA_LO12                 R_LARCH = 72
+	R_LARCH_PCALA64_LO20               R_LARCH = 73
+	R_LARCH_PCALA64_HI12               R_LARCH = 74
+	R_LARCH_GOT_PC_HI20                R_LARCH = 75
+	R_LARCH_GOT_PC_LO12                R_LARCH = 76
+	R_LARCH_GOT64_PC_LO20              R_LARCH = 77
+	R_LARCH_GOT64_PC_HI12              R_LARCH = 78
+	R_LARCH_GOT_HI20                   R_LARCH = 79
+	R_LARCH_GOT_LO12                   R_LARCH = 80
+	R_LARCH_GOT64_LO20                 R_LARCH = 81
+	R_LARCH_GOT64_HI12                 R_LARCH = 82
+	R_LARCH_TLS_LE_HI20                R_LARCH = 83
+	R_LARCH_TLS_LE_LO12                R_LARCH = 84
+	R_LARCH_TLS_LE64_LO20              R_LARCH = 85
+	R_LARCH_TLS_LE64_HI12              R_LARCH = 86
+	R_LARCH_TLS_IE_PC_HI20             R_LARCH = 87
+	R_LARCH_TLS_IE_PC_LO12             R_LARCH = 88
+	R_LARCH_TLS_IE64_PC_LO20           R_LARCH = 89
+	R_LARCH_TLS_IE64_PC_HI12           R_LARCH = 90
+	R_LARCH_TLS_IE_HI20                R_LARCH = 91
+	R_LARCH_TLS_IE_LO12                R_LARCH = 92
+	R_LARCH_TLS_IE64_LO20              R_LARCH = 93
+	R_LARCH_TLS_IE64_HI12              R_LARCH = 94
+	R_LARCH_TLS_LD_PC_HI20             R_LARCH = 95
+	R_LARCH_TLS_LD_HI20                R_LARCH = 96
+	R_LARCH_TLS_GD_PC_HI20             R_LARCH = 97
+	R_LARCH_TLS_GD_HI20                R_LARCH = 98
+	R_LARCH_32_PCREL                   R_LARCH = 99
+	R_LARCH_RELAX                      R_LARCH = 100
 )
 
 var rlarchStrings = []intName{
@@ -2259,6 +2298,45 @@
 	{54, "R_LARCH_SUB24"},
 	{55, "R_LARCH_SUB32"},
 	{56, "R_LARCH_SUB64"},
+	{57, "R_LARCH_GNU_VTINHERIT"},
+	{58, "R_LARCH_GNU_VTENTRY"},
+	{64, "R_LARCH_B16"},
+	{65, "R_LARCH_B21"},
+	{66, "R_LARCH_B26"},
+	{67, "R_LARCH_ABS_HI20"},
+	{68, "R_LARCH_ABS_LO12"},
+	{69, "R_LARCH_ABS64_LO20"},
+	{70, "R_LARCH_ABS64_HI12"},
+	{71, "R_LARCH_PCALA_HI20"},
+	{72, "R_LARCH_PCALA_LO12"},
+	{73, "R_LARCH_PCALA64_LO20"},
+	{74, "R_LARCH_PCALA64_HI12"},
+	{75, "R_LARCH_GOT_PC_HI20"},
+	{76, "R_LARCH_GOT_PC_LO12"},
+	{77, "R_LARCH_GOT64_PC_LO20"},
+	{78, "R_LARCH_GOT64_PC_HI12"},
+	{79, "R_LARCH_GOT_HI20"},
+	{80, "R_LARCH_GOT_LO12"},
+	{81, "R_LARCH_GOT64_LO20"},
+	{82, "R_LARCH_GOT64_HI12"},
+	{83, "R_LARCH_TLS_LE_HI20"},
+	{84, "R_LARCH_TLS_LE_LO12"},
+	{85, "R_LARCH_TLS_LE64_LO20"},
+	{86, "R_LARCH_TLS_LE64_HI12"},
+	{87, "R_LARCH_TLS_IE_PC_HI20"},
+	{88, "R_LARCH_TLS_IE_PC_LO12"},
+	{89, "R_LARCH_TLS_IE64_PC_LO20"},
+	{90, "R_LARCH_TLS_IE64_PC_HI12"},
+	{91, "R_LARCH_TLS_IE_HI20"},
+	{92, "R_LARCH_TLS_IE_LO12"},
+	{93, "R_LARCH_TLS_IE64_LO20"},
+	{94, "R_LARCH_TLS_IE64_HI12"},
+	{95, "R_LARCH_TLS_LD_PC_HI20"},
+	{96, "R_LARCH_TLS_LD_HI20"},
+	{97, "R_LARCH_TLS_GD_PC_HI20"},
+	{98, "R_LARCH_TLS_GD_HI20"},
+	{99, "R_LARCH_32_PCREL"},
+	{100, "R_LARCH_RELAX"},
 }
 
 func (i R_LARCH) String() string   { return stringName(uint32(i), rlarchStrings, false) }
@@ -2462,15 +2540,32 @@
 	R_PPC64_GOT16_LO           R_PPC64 = 15 // R_POWERPC_GOT16_LO
 	R_PPC64_GOT16_HI           R_PPC64 = 16 // R_POWERPC_GOT16_HI
 	R_PPC64_GOT16_HA           R_PPC64 = 17 // R_POWERPC_GOT16_HA
+	R_PPC64_COPY               R_PPC64 = 19 // R_POWERPC_COPY
+	R_PPC64_GLOB_DAT           R_PPC64 = 20 // R_POWERPC_GLOB_DAT
 	R_PPC64_JMP_SLOT           R_PPC64 = 21 // R_POWERPC_JMP_SLOT
 	R_PPC64_RELATIVE           R_PPC64 = 22 // R_POWERPC_RELATIVE
+	R_PPC64_UADDR32            R_PPC64 = 24 // R_POWERPC_UADDR32
+	R_PPC64_UADDR16            R_PPC64 = 25 // R_POWERPC_UADDR16
 	R_PPC64_REL32              R_PPC64 = 26 // R_POWERPC_REL32
+	R_PPC64_PLT32              R_PPC64 = 27 // R_POWERPC_PLT32
+	R_PPC64_PLTREL32           R_PPC64 = 28 // R_POWERPC_PLTREL32
+	R_PPC64_PLT16_LO           R_PPC64 = 29 // R_POWERPC_PLT16_LO
+	R_PPC64_PLT16_HI           R_PPC64 = 30 // R_POWERPC_PLT16_HI
+	R_PPC64_PLT16_HA           R_PPC64 = 31 // R_POWERPC_PLT16_HA
+	R_PPC64_SECTOFF            R_PPC64 = 33 // R_POWERPC_SECTOFF
+	R_PPC64_SECTOFF_LO         R_PPC64 = 34 // R_POWERPC_SECTOFF_LO
+	R_PPC64_SECTOFF_HI         R_PPC64 = 35 // R_POWERPC_SECTOFF_HI
+	R_PPC64_SECTOFF_HA         R_PPC64 = 36 // R_POWERPC_SECTOFF_HA
+	R_PPC64_REL30              R_PPC64 = 37 // R_POWERPC_ADDR30
 	R_PPC64_ADDR64             R_PPC64 = 38
 	R_PPC64_ADDR16_HIGHER      R_PPC64 = 39
 	R_PPC64_ADDR16_HIGHERA     R_PPC64 = 40
 	R_PPC64_ADDR16_HIGHEST     R_PPC64 = 41
 	R_PPC64_ADDR16_HIGHESTA    R_PPC64 = 42
+	R_PPC64_UADDR64            R_PPC64 = 43
 	R_PPC64_REL64              R_PPC64 = 44
+	R_PPC64_PLT64              R_PPC64 = 45
+	R_PPC64_PLTREL64           R_PPC64 = 46
 	R_PPC64_TOC16              R_PPC64 = 47
 	R_PPC64_TOC16_LO           R_PPC64 = 48
 	R_PPC64_TOC16_HI           R_PPC64 = 49
@@ -2486,7 +2581,7 @@
 	R_PPC64_GOT16_LO_DS        R_PPC64 = 59
 	R_PPC64_PLT16_LO_DS        R_PPC64 = 60
 	R_PPC64_SECTOFF_DS         R_PPC64 = 61
-	R_PPC64_SECTOFF_LO_DS      R_PPC64 = 61
+	R_PPC64_SECTOFF_LO_DS      R_PPC64 = 62
 	R_PPC64_TOC16_DS           R_PPC64 = 63
 	R_PPC64_TOC16_LO_DS        R_PPC64 = 64
 	R_PPC64_PLTGOT16_DS        R_PPC64 = 65
@@ -2543,6 +2638,41 @@
 	R_PPC64_REL24_NOTOC        R_PPC64 = 116
 	R_PPC64_ADDR64_LOCAL       R_PPC64 = 117
 	R_PPC64_ENTRY              R_PPC64 = 118
+	R_PPC64_PLTSEQ             R_PPC64 = 119
+	R_PPC64_PLTCALL            R_PPC64 = 120
+	R_PPC64_PLTSEQ_NOTOC       R_PPC64 = 121
+	R_PPC64_PLTCALL_NOTOC      R_PPC64 = 122
+	R_PPC64_PCREL_OPT          R_PPC64 = 123
+	R_PPC64_D34                R_PPC64 = 128
+	R_PPC64_D34_LO             R_PPC64 = 129
+	R_PPC64_D34_HI30           R_PPC64 = 130
+	R_PPC64_D34_HA30           R_PPC64 = 131
+	R_PPC64_PCREL34            R_PPC64 = 132
+	R_PPC64_GOT_PCREL34        R_PPC64 = 133
+	R_PPC64_PLT_PCREL34        R_PPC64 = 134
+	R_PPC64_PLT_PCREL34_NOTOC  R_PPC64 = 135
+	R_PPC64_ADDR16_HIGHER34    R_PPC64 = 136
+	R_PPC64_ADDR16_HIGHERA34   R_PPC64 = 137
+	R_PPC64_ADDR16_HIGHEST34   R_PPC64 = 138
+	R_PPC64_ADDR16_HIGHESTA34  R_PPC64 = 139
+	R_PPC64_REL16_HIGHER34     R_PPC64 = 140
+	R_PPC64_REL16_HIGHERA34    R_PPC64 = 141
+	R_PPC64_REL16_HIGHEST34    R_PPC64 = 142
+	R_PPC64_REL16_HIGHESTA34   R_PPC64 = 143
+	R_PPC64_D28                R_PPC64 = 144
+	R_PPC64_PCREL28            R_PPC64 = 145
+	R_PPC64_TPREL34            R_PPC64 = 146
+	R_PPC64_DTPREL34           R_PPC64 = 147
+	R_PPC64_GOT_TLSGD_PCREL34  R_PPC64 = 148
+	R_PPC64_GOT_TLSLD_PCREL34  R_PPC64 = 149
+	R_PPC64_GOT_TPREL_PCREL34  R_PPC64 = 150
+	R_PPC64_GOT_DTPREL_PCREL34 R_PPC64 = 151
+	R_PPC64_REL16_HIGH         R_PPC64 = 240
+	R_PPC64_REL16_HIGHA        R_PPC64 = 241
+	R_PPC64_REL16_HIGHER       R_PPC64 = 242
+	R_PPC64_REL16_HIGHERA      R_PPC64 = 243
+	R_PPC64_REL16_HIGHEST      R_PPC64 = 244
+	R_PPC64_REL16_HIGHESTA     R_PPC64 = 245
 	R_PPC64_REL16DX_HA         R_PPC64 = 246 // R_POWERPC_REL16DX_HA
 	R_PPC64_JMP_IREL           R_PPC64 = 247
 	R_PPC64_IRELATIVE          R_PPC64 = 248 // R_POWERPC_IRELATIVE
@@ -2550,6 +2680,8 @@
 	R_PPC64_REL16_LO           R_PPC64 = 250 // R_POWERPC_REL16_LO
 	R_PPC64_REL16_HI           R_PPC64 = 251 // R_POWERPC_REL16_HI
 	R_PPC64_REL16_HA           R_PPC64 = 252 // R_POWERPC_REL16_HA
+	R_PPC64_GNU_VTINHERIT      R_PPC64 = 253
+	R_PPC64_GNU_VTENTRY        R_PPC64 = 254
 )
 
 var rppc64Strings = []intName{
@@ -2571,15 +2703,32 @@
 	{15, "R_PPC64_GOT16_LO"},
 	{16, "R_PPC64_GOT16_HI"},
 	{17, "R_PPC64_GOT16_HA"},
+	{19, "R_PPC64_COPY"},
+	{20, "R_PPC64_GLOB_DAT"},
 	{21, "R_PPC64_JMP_SLOT"},
 	{22, "R_PPC64_RELATIVE"},
+	{24, "R_PPC64_UADDR32"},
+	{25, "R_PPC64_UADDR16"},
 	{26, "R_PPC64_REL32"},
+	{27, "R_PPC64_PLT32"},
+	{28, "R_PPC64_PLTREL32"},
+	{29, "R_PPC64_PLT16_LO"},
+	{30, "R_PPC64_PLT16_HI"},
+	{31, "R_PPC64_PLT16_HA"},
+	{33, "R_PPC64_SECTOFF"},
+	{34, "R_PPC64_SECTOFF_LO"},
+	{35, "R_PPC64_SECTOFF_HI"},
+	{36, "R_PPC64_SECTOFF_HA"},
+	{37, "R_PPC64_REL30"},
 	{38, "R_PPC64_ADDR64"},
 	{39, "R_PPC64_ADDR16_HIGHER"},
 	{40, "R_PPC64_ADDR16_HIGHERA"},
 	{41, "R_PPC64_ADDR16_HIGHEST"},
 	{42, "R_PPC64_ADDR16_HIGHESTA"},
+	{43, "R_PPC64_UADDR64"},
 	{44, "R_PPC64_REL64"},
+	{45, "R_PPC64_PLT64"},
+	{46, "R_PPC64_PLTREL64"},
 	{47, "R_PPC64_TOC16"},
 	{48, "R_PPC64_TOC16_LO"},
 	{49, "R_PPC64_TOC16_HI"},
@@ -2595,7 +2744,7 @@
 	{59, "R_PPC64_GOT16_LO_DS"},
 	{60, "R_PPC64_PLT16_LO_DS"},
 	{61, "R_PPC64_SECTOFF_DS"},
-	{61, "R_PPC64_SECTOFF_LO_DS"},
+	{62, "R_PPC64_SECTOFF_LO_DS"},
 	{63, "R_PPC64_TOC16_DS"},
 	{64, "R_PPC64_TOC16_LO_DS"},
 	{65, "R_PPC64_PLTGOT16_DS"},
@@ -2652,6 +2801,41 @@
 	{116, "R_PPC64_REL24_NOTOC"},
 	{117, "R_PPC64_ADDR64_LOCAL"},
 	{118, "R_PPC64_ENTRY"},
+	{119, "R_PPC64_PLTSEQ"},
+	{120, "R_PPC64_PLTCALL"},
+	{121, "R_PPC64_PLTSEQ_NOTOC"},
+	{122, "R_PPC64_PLTCALL_NOTOC"},
+	{123, "R_PPC64_PCREL_OPT"},
+	{128, "R_PPC64_D34"},
+	{129, "R_PPC64_D34_LO"},
+	{130, "R_PPC64_D34_HI30"},
+	{131, "R_PPC64_D34_HA30"},
+	{132, "R_PPC64_PCREL34"},
+	{133, "R_PPC64_GOT_PCREL34"},
+	{134, "R_PPC64_PLT_PCREL34"},
+	{135, "R_PPC64_PLT_PCREL34_NOTOC"},
+	{136, "R_PPC64_ADDR16_HIGHER34"},
+	{137, "R_PPC64_ADDR16_HIGHERA34"},
+	{138, "R_PPC64_ADDR16_HIGHEST34"},
+	{139, "R_PPC64_ADDR16_HIGHESTA34"},
+	{140, "R_PPC64_REL16_HIGHER34"},
+	{141, "R_PPC64_REL16_HIGHERA34"},
+	{142, "R_PPC64_REL16_HIGHEST34"},
+	{143, "R_PPC64_REL16_HIGHESTA34"},
+	{144, "R_PPC64_D28"},
+	{145, "R_PPC64_PCREL28"},
+	{146, "R_PPC64_TPREL34"},
+	{147, "R_PPC64_DTPREL34"},
+	{148, "R_PPC64_GOT_TLSGD_PCREL34"},
+	{149, "R_PPC64_GOT_TLSLD_PCREL34"},
+	{150, "R_PPC64_GOT_TPREL_PCREL34"},
+	{151, "R_PPC64_GOT_DTPREL_PCREL34"},
+	{240, "R_PPC64_REL16_HIGH"},
+	{241, "R_PPC64_REL16_HIGHA"},
+	{242, "R_PPC64_REL16_HIGHER"},
+	{243, "R_PPC64_REL16_HIGHERA"},
+	{244, "R_PPC64_REL16_HIGHEST"},
+	{245, "R_PPC64_REL16_HIGHESTA"},
 	{246, "R_PPC64_REL16DX_HA"},
 	{247, "R_PPC64_JMP_IREL"},
 	{248, "R_PPC64_IRELATIVE"},
@@ -2659,6 +2843,8 @@
 	{250, "R_PPC64_REL16_LO"},
 	{251, "R_PPC64_REL16_HI"},
 	{252, "R_PPC64_REL16_HA"},
+	{253, "R_PPC64_GNU_VTINHERIT"},
+	{254, "R_PPC64_GNU_VTENTRY"},
 }
 
 func (i R_PPC64) String() string   { return stringName(uint32(i), rppc64Strings, false) }
diff --git a/src/debug/elf/elf_test.go b/src/debug/elf/elf_test.go
index b8c310d..814c6bd 100644
--- a/src/debug/elf/elf_test.go
+++ b/src/debug/elf/elf_test.go
@@ -37,6 +37,7 @@
 	{R_SPARC_GOT22, "R_SPARC_GOT22"},
 	{ET_LOOS + 5, "ET_LOOS+5"},
 	{ProgFlag(0x50), "0x50"},
+	{COMPRESS_ZLIB + 1, "COMPRESS_ZLIB+1"},
 }
 
 func TestNames(t *testing.T) {
@@ -47,25 +48,3 @@
 		}
 	}
 }
-
-func TestNobitsSection(t *testing.T) {
-	const testdata = "testdata/gcc-amd64-linux-exec"
-	f, err := Open(testdata)
-	if err != nil {
-		t.Fatalf("could not read %s: %v", testdata, err)
-	}
-	defer f.Close()
-	bss := f.Section(".bss")
-	bssData, err := bss.Data()
-	if err != nil {
-		t.Fatalf("error reading .bss section: %v", err)
-	}
-	if g, w := uint64(len(bssData)), bss.Size; g != w {
-		t.Errorf(".bss section length mismatch: got %d, want %d", g, w)
-	}
-	for i := range bssData {
-		if bssData[i] != 0 {
-			t.Fatalf("unexpected non-zero byte at offset %d: %#x", i, bssData[i])
-		}
-	}
-}
diff --git a/src/debug/elf/file.go b/src/debug/elf/file.go
index 6bfcd2a..88b9576 100644
--- a/src/debug/elf/file.go
+++ b/src/debug/elf/file.go
@@ -2,7 +2,17 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Package elf implements access to ELF object files.
+/*
+Package elf implements access to ELF object files.
+
+# Security
+
+This package is not designed to be hardened against adversarial inputs, and is
+outside the scope of https://go.dev/security/policy. In particular, only basic
+validation is done when parsing object files. As such, care should be taken when
+parsing untrusted inputs, as parsing malformed files may consume significant
+resources, or cause panics.
+*/
 package elf
 
 import (
@@ -12,6 +22,7 @@
 	"encoding/binary"
 	"errors"
 	"fmt"
+	"internal/saferio"
 	"io"
 	"os"
 	"strings"
@@ -101,10 +112,10 @@
 // Data reads and returns the contents of the ELF section.
 // Even if the section is stored compressed in the ELF file,
 // Data returns uncompressed data.
+//
+// For an SHT_NOBITS section, Data always returns a non-nil error.
 func (s *Section) Data() ([]byte, error) {
-	dat := make([]byte, s.Size)
-	n, err := io.ReadFull(s.Open(), dat)
-	return dat[0:n], err
+	return saferio.ReadData(s.Open(), s.Size)
 }
 
 // stringTable reads and returns the string table given by the
@@ -119,9 +130,12 @@
 // Open returns a new ReadSeeker reading the ELF section.
 // Even if the section is stored compressed in the ELF file,
 // the ReadSeeker reads uncompressed data.
+//
+// For an SHT_NOBITS section, all calls to the opened reader
+// will return a non-nil error.
 func (s *Section) Open() io.ReadSeeker {
 	if s.Type == SHT_NOBITS {
-		return io.NewSectionReader(&zeroReader{}, 0, int64(s.Size))
+		return io.NewSectionReader(&nobitsSectionReader{}, 0, int64(s.Size))
 	}
 	if s.Flags&SHF_COMPRESSED == 0 {
 		return io.NewSectionReader(s.sr, 0, 1<<63-1)
@@ -340,6 +354,19 @@
 		return nil, &FormatError{0, "invalid ELF shstrndx", shstrndx}
 	}
 
+	var wantPhentsize, wantShentsize int
+	switch f.Class {
+	case ELFCLASS32:
+		wantPhentsize = 8 * 4
+		wantShentsize = 10 * 4
+	case ELFCLASS64:
+		wantPhentsize = 2*4 + 6*8
+		wantShentsize = 4*4 + 6*8
+	}
+	if phnum > 0 && phentsize < wantPhentsize {
+		return nil, &FormatError{0, "invalid ELF phentsize", phentsize}
+	}
+
 	// Read program headers
 	f.Progs = make([]*Prog, phnum)
 	for i := 0; i < phnum; i++ {
@@ -378,14 +405,74 @@
 				Align:  ph.Align,
 			}
 		}
+		if int64(p.Off) < 0 {
+			return nil, &FormatError{off, "invalid program header offset", p.Off}
+		}
+		if int64(p.Filesz) < 0 {
+			return nil, &FormatError{off, "invalid program header file size", p.Filesz}
+		}
 		p.sr = io.NewSectionReader(r, int64(p.Off), int64(p.Filesz))
 		p.ReaderAt = p.sr
 		f.Progs[i] = p
 	}
 
+	// If the number of sections is greater than or equal to SHN_LORESERVE
+	// (0xff00), shnum has the value zero and the actual number of section
+	// header table entries is contained in the sh_size field of the section
+	// header at index 0.
+	if shoff > 0 && shnum == 0 {
+		var typ, link uint32
+		sr.Seek(shoff, seekStart)
+		switch f.Class {
+		case ELFCLASS32:
+			sh := new(Section32)
+			if err := binary.Read(sr, f.ByteOrder, sh); err != nil {
+				return nil, err
+			}
+			shnum = int(sh.Size)
+			typ = sh.Type
+			link = sh.Link
+		case ELFCLASS64:
+			sh := new(Section64)
+			if err := binary.Read(sr, f.ByteOrder, sh); err != nil {
+				return nil, err
+			}
+			shnum = int(sh.Size)
+			typ = sh.Type
+			link = sh.Link
+		}
+		if SectionType(typ) != SHT_NULL {
+			return nil, &FormatError{shoff, "invalid type of the initial section", SectionType(typ)}
+		}
+
+		if shnum < int(SHN_LORESERVE) {
+			return nil, &FormatError{shoff, "invalid ELF shnum contained in sh_size", shnum}
+		}
+
+		// If the section name string table section index is greater than or
+		// equal to SHN_LORESERVE (0xff00), this member has the value
+		// SHN_XINDEX (0xffff) and the actual index of the section name
+		// string table section is contained in the sh_link field of the
+		// section header at index 0.
+		if shstrndx == int(SHN_XINDEX) {
+			shstrndx = int(link)
+			if shstrndx < int(SHN_LORESERVE) {
+				return nil, &FormatError{shoff, "invalid ELF shstrndx contained in sh_link", shstrndx}
+			}
+		}
+	}
+
+	if shnum > 0 && shentsize < wantShentsize {
+		return nil, &FormatError{0, "invalid ELF shentsize", shentsize}
+	}
+
 	// Read section headers
-	f.Sections = make([]*Section, shnum)
-	names := make([]uint32, shnum)
+	c := saferio.SliceCap((*Section)(nil), uint64(shnum))
+	if c < 0 {
+		return nil, &FormatError{0, "too many sections", shnum}
+	}
+	f.Sections = make([]*Section, 0, c)
+	names := make([]uint32, 0, c)
 	for i := 0; i < shnum; i++ {
 		off := shoff + int64(i)*int64(shentsize)
 		sr.Seek(off, seekStart)
@@ -396,7 +483,7 @@
 			if err := binary.Read(sr, f.ByteOrder, sh); err != nil {
 				return nil, err
 			}
-			names[i] = sh.Name
+			names = append(names, sh.Name)
 			s.SectionHeader = SectionHeader{
 				Type:      SectionType(sh.Type),
 				Flags:     SectionFlag(sh.Flags),
@@ -413,7 +500,7 @@
 			if err := binary.Read(sr, f.ByteOrder, sh); err != nil {
 				return nil, err
 			}
-			names[i] = sh.Name
+			names = append(names, sh.Name)
 			s.SectionHeader = SectionHeader{
 				Type:      SectionType(sh.Type),
 				Flags:     SectionFlag(sh.Flags),
@@ -461,7 +548,7 @@
 			}
 		}
 
-		f.Sections[i] = s
+		f.Sections = append(f.Sections, s)
 	}
 
 	if len(f.Sections) == 0 {
@@ -469,7 +556,16 @@
 	}
 
 	// Load section header string table.
-	shstrtab, err := f.Sections[shstrndx].Data()
+	if shstrndx == 0 {
+		// If the file has no section name string table,
+		// shstrndx holds the value SHN_UNDEF (0).
+		return f, nil
+	}
+	shstr := f.Sections[shstrndx]
+	if shstr.Type != SHT_STRTAB {
+		return nil, &FormatError{shoff + int64(shstrndx*shentsize), "invalid ELF section name string table type", shstr.Type}
+	}
+	shstrtab, err := shstr.Data()
 	if err != nil {
 		return nil, err
 	}
@@ -1213,10 +1309,7 @@
 		if err != nil && uint64(len(b)) < s.Size {
 			return nil, err
 		}
-		var (
-			dlen uint64
-			dbuf []byte
-		)
+		var dlen uint64
 		if len(b) >= 12 && string(b[:4]) == "ZLIB" {
 			dlen = binary.BigEndian.Uint64(b[4:12])
 			s.compressionOffset = 12
@@ -1242,18 +1335,17 @@
 			}
 		}
 		if dlen > 0 {
-			dbuf = make([]byte, dlen)
 			r, err := zlib.NewReader(bytes.NewBuffer(b[s.compressionOffset:]))
 			if err != nil {
 				return nil, err
 			}
-			if _, err := io.ReadFull(r, dbuf); err != nil {
+			b, err = saferio.ReadData(r, dlen)
+			if err != nil {
 				return nil, err
 			}
 			if err := r.Close(); err != nil {
 				return nil, err
 			}
-			b = dbuf
 		}
 
 		if f.Type == ET_EXEC {
@@ -1478,12 +1570,16 @@
 // gnuVersion adds Library and Version information to sym,
 // which came from offset i of the symbol table.
 func (f *File) gnuVersion(i int) (library string, version string) {
-	// Each entry is two bytes.
+	// Each entry is two bytes; skip undef entry at beginning.
 	i = (i + 1) * 2
 	if i >= len(f.gnuVersym) {
 		return
 	}
-	j := int(f.ByteOrder.Uint16(f.gnuVersym[i:]))
+	s := f.gnuVersym[i:]
+	if len(s) < 2 {
+		return
+	}
+	j := int(f.ByteOrder.Uint16(s))
 	if j < 2 || j >= len(f.gnuNeed) {
 		return
 	}
@@ -1546,11 +1642,8 @@
 	return all, nil
 }
 
-type zeroReader struct{}
+type nobitsSectionReader struct{}
 
-func (*zeroReader) ReadAt(p []byte, off int64) (n int, err error) {
-	for i := range p {
-		p[i] = 0
-	}
-	return len(p), nil
+func (*nobitsSectionReader) ReadAt(p []byte, off int64) (n int, err error) {
+	return 0, errors.New("unexpected read from SHT_NOBITS section")
 }
diff --git a/src/debug/elf/file_test.go b/src/debug/elf/file_test.go
index c0decdd..282e1fc 100644
--- a/src/debug/elf/file_test.go
+++ b/src/debug/elf/file_test.go
@@ -9,6 +9,7 @@
 	"compress/gzip"
 	"debug/dwarf"
 	"encoding/binary"
+	"fmt"
 	"io"
 	"math/rand"
 	"net"
@@ -230,7 +231,7 @@
 			continue
 		}
 		defer f.Close()
-		if !reflect.DeepEqual(f.FileHeader, tt.hdr) {
+		if f.FileHeader != tt.hdr {
 			t.Errorf("open %s:\n\thave %#v\n\twant %#v\n", tt.file, f.FileHeader, tt.hdr)
 			continue
 		}
@@ -238,18 +239,18 @@
 			if i >= len(tt.sections) {
 				break
 			}
-			sh := &tt.sections[i]
-			if !reflect.DeepEqual(&s.SectionHeader, sh) {
-				t.Errorf("open %s, section %d:\n\thave %#v\n\twant %#v\n", tt.file, i, &s.SectionHeader, sh)
+			sh := tt.sections[i]
+			if s.SectionHeader != sh {
+				t.Errorf("open %s, section %d:\n\thave %#v\n\twant %#v\n", tt.file, i, s.SectionHeader, sh)
 			}
 		}
 		for i, p := range f.Progs {
 			if i >= len(tt.progs) {
 				break
 			}
-			ph := &tt.progs[i]
-			if !reflect.DeepEqual(&p.ProgHeader, ph) {
-				t.Errorf("open %s, program %d:\n\thave %#v\n\twant %#v\n", tt.file, i, &p.ProgHeader, ph)
+			ph := tt.progs[i]
+			if p.ProgHeader != ph {
+				t.Errorf("open %s, program %d:\n\thave %#v\n\twant %#v\n", tt.file, i, p.ProgHeader, ph)
 			}
 		}
 		tn := len(tt.sections)
@@ -944,6 +945,275 @@
 	}
 }
 
+func TestNobitsSection(t *testing.T) {
+	const testdata = "testdata/gcc-amd64-linux-exec"
+	f, err := Open(testdata)
+	if err != nil {
+		t.Fatalf("could not read %s: %v", testdata, err)
+	}
+	defer f.Close()
+
+	wantError := "unexpected read from SHT_NOBITS section"
+	bss := f.Section(".bss")
+
+	_, err = bss.Data()
+	if err == nil || err.Error() != wantError {
+		t.Fatalf("bss.Data() got error %q, want error %q", err, wantError)
+	}
+
+	r := bss.Open()
+	p := make([]byte, 1)
+	_, err = r.Read(p)
+	if err == nil || err.Error() != wantError {
+		t.Fatalf("r.Read(p) got error %q, want error %q", err, wantError)
+	}
+}
+
+// TestLargeNumberOfSections tests the case that a file has greater than or
+// equal to 65280 (0xff00) sections.
+func TestLargeNumberOfSections(t *testing.T) {
+	// A file with >= 0xff00 sections is too big, so we will construct it on the
+	// fly. The original file "y.o" is generated by these commands:
+	// 1. generate "y.c":
+	//   for i in `seq 1 65288`; do
+	//     printf -v x "%04x" i;
+	//     echo "int var_$x __attribute__((section(\"section_$x\"))) = $i;"
+	//   done > y.c
+	// 2. compile: gcc -c y.c -m32
+	//
+	// $readelf -h y.o
+	// ELF Header:
+	//   Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
+	//   Class:                             ELF32
+	//   Data:                              2's complement, little endian
+	//   Version:                           1 (current)
+	//   OS/ABI:                            UNIX - System V
+	//   ABI Version:                       0
+	//   Type:                              REL (Relocatable file)
+	//   Machine:                           Intel 80386
+	//   Version:                           0x1
+	//   Entry point address:               0x0
+	//   Start of program headers:          0 (bytes into file)
+	//   Start of section headers:          3003468 (bytes into file)
+	//   Flags:                             0x0
+	//   Size of this header:               52 (bytes)
+	//   Size of program headers:           0 (bytes)
+	//   Number of program headers:         0
+	//   Size of section headers:           40 (bytes)
+	//   Number of section headers:         0 (65298)
+	//   Section header string table index: 65535 (65297)
+	//
+	// $readelf -S y.o
+	// There are 65298 section headers, starting at offset 0x2dd44c:
+	// Section Headers:
+	//   [Nr]    Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
+	//   [    0]                   NULL            00000000 000000 00ff12 00     65297   0  0
+	//   [    1] .text             PROGBITS        00000000 000034 000000 00  AX  0   0  1
+	//   [    2] .data             PROGBITS        00000000 000034 000000 00  WA  0   0  1
+	//   [    3] .bss              NOBITS          00000000 000034 000000 00  WA  0   0  1
+	//   [    4] section_0001      PROGBITS        00000000 000034 000004 00  WA  0   0  4
+	//   [    5] section_0002      PROGBITS        00000000 000038 000004 00  WA  0   0  4
+	//   [ section_0003 ~ section_ff06 truncated ]
+	//   [65290] section_ff07      PROGBITS        00000000 03fc4c 000004 00  WA  0   0  4
+	//   [65291] section_ff08      PROGBITS        00000000 03fc50 000004 00  WA  0   0  4
+	//   [65292] .comment          PROGBITS        00000000 03fc54 000027 01  MS  0   0  1
+	//   [65293] .note.GNU-stack   PROGBITS        00000000 03fc7b 000000 00      0   0  1
+	//   [65294] .symtab           SYMTAB          00000000 03fc7c 0ff0a0 10     65296   2  4
+	//   [65295] .symtab_shndx     SYMTAB SECTION  00000000 13ed1c 03fc28 04     65294   0  4
+	//   [65296] .strtab           STRTAB          00000000 17e944 08f74d 00      0   0  1
+	//   [65297] .shstrtab         STRTAB          00000000 20e091 0cf3bb 00      0   0  1
+
+	var buf bytes.Buffer
+
+	{
+		buf.Grow(0x55AF1C) // 3003468 + 40 * 65298
+
+		h := Header32{
+			Ident:     [16]byte{0x7F, 'E', 'L', 'F', 0x01, 0x01, 0x01},
+			Type:      1,
+			Machine:   3,
+			Version:   1,
+			Shoff:     0x2DD44C,
+			Ehsize:    0x34,
+			Shentsize: 0x28,
+			Shnum:     0,
+			Shstrndx:  0xFFFF,
+		}
+		binary.Write(&buf, binary.LittleEndian, h)
+
+		// Zero out sections [1]~[65294].
+		buf.Write(bytes.Repeat([]byte{0}, 0x13ED1C-binary.Size(h)))
+
+		// Write section [65295]. Section [65295] are all zeros except for the
+		// last 48 bytes.
+		buf.Write(bytes.Repeat([]byte{0}, 0x03FC28-12*4))
+		for i := 0; i < 12; i++ {
+			binary.Write(&buf, binary.LittleEndian, uint32(0xFF00|i))
+		}
+
+		// Write section [65296].
+		buf.Write([]byte{0})
+		buf.Write([]byte("y.c\x00"))
+		for i := 1; i <= 65288; i++ {
+			// var_0001 ~ var_ff08
+			name := fmt.Sprintf("var_%04x", i)
+			buf.Write([]byte(name))
+			buf.Write([]byte{0})
+		}
+
+		// Write section [65297].
+		buf.Write([]byte{0})
+		buf.Write([]byte(".symtab\x00"))
+		buf.Write([]byte(".strtab\x00"))
+		buf.Write([]byte(".shstrtab\x00"))
+		buf.Write([]byte(".text\x00"))
+		buf.Write([]byte(".data\x00"))
+		buf.Write([]byte(".bss\x00"))
+		for i := 1; i <= 65288; i++ {
+			// s_0001 ~ s_ff08
+			name := fmt.Sprintf("section_%04x", i)
+			buf.Write([]byte(name))
+			buf.Write([]byte{0})
+		}
+		buf.Write([]byte(".comment\x00"))
+		buf.Write([]byte(".note.GNU-stack\x00"))
+		buf.Write([]byte(".symtab_shndx\x00"))
+
+		// Write section header table.
+		// NULL
+		binary.Write(&buf, binary.LittleEndian, Section32{Name: 0, Size: 0xFF12, Link: 0xFF11})
+		// .text
+		binary.Write(&buf, binary.LittleEndian, Section32{
+			Name:      0x1B,
+			Type:      uint32(SHT_PROGBITS),
+			Flags:     uint32(uint32(SHF_ALLOC | SHF_EXECINSTR)),
+			Off:       0x34,
+			Addralign: 0x01,
+		})
+		// .data
+		binary.Write(&buf, binary.LittleEndian, Section32{
+			Name:      0x21,
+			Type:      uint32(SHT_PROGBITS),
+			Flags:     uint32(SHF_WRITE | SHF_ALLOC),
+			Off:       0x34,
+			Addralign: 0x01,
+		})
+		// .bss
+		binary.Write(&buf, binary.LittleEndian, Section32{
+			Name:      0x27,
+			Type:      uint32(SHT_NOBITS),
+			Flags:     uint32(SHF_WRITE | SHF_ALLOC),
+			Off:       0x34,
+			Addralign: 0x01,
+		})
+		// s_1 ~ s_65537
+		for i := 0; i < 65288; i++ {
+			s := Section32{
+				Name:      uint32(0x2C + i*13),
+				Type:      uint32(SHT_PROGBITS),
+				Flags:     uint32(SHF_WRITE | SHF_ALLOC),
+				Off:       uint32(0x34 + i*4),
+				Size:      0x04,
+				Addralign: 0x04,
+			}
+			binary.Write(&buf, binary.LittleEndian, s)
+		}
+		// .comment
+		binary.Write(&buf, binary.LittleEndian, Section32{
+			Name:      0x0CF394,
+			Type:      uint32(SHT_PROGBITS),
+			Flags:     uint32(SHF_MERGE | SHF_STRINGS),
+			Off:       0x03FC54,
+			Size:      0x27,
+			Addralign: 0x01,
+			Entsize:   0x01,
+		})
+		// .note.GNU-stack
+		binary.Write(&buf, binary.LittleEndian, Section32{
+			Name:      0x0CF39D,
+			Type:      uint32(SHT_PROGBITS),
+			Off:       0x03FC7B,
+			Addralign: 0x01,
+		})
+		// .symtab
+		binary.Write(&buf, binary.LittleEndian, Section32{
+			Name:      0x01,
+			Type:      uint32(SHT_SYMTAB),
+			Off:       0x03FC7C,
+			Size:      0x0FF0A0,
+			Link:      0xFF10,
+			Info:      0x02,
+			Addralign: 0x04,
+			Entsize:   0x10,
+		})
+		// .symtab_shndx
+		binary.Write(&buf, binary.LittleEndian, Section32{
+			Name:      0x0CF3AD,
+			Type:      uint32(SHT_SYMTAB_SHNDX),
+			Off:       0x13ED1C,
+			Size:      0x03FC28,
+			Link:      0xFF0E,
+			Addralign: 0x04,
+			Entsize:   0x04,
+		})
+		// .strtab
+		binary.Write(&buf, binary.LittleEndian, Section32{
+			Name:      0x09,
+			Type:      uint32(SHT_STRTAB),
+			Off:       0x17E944,
+			Size:      0x08F74D,
+			Addralign: 0x01,
+		})
+		// .shstrtab
+		binary.Write(&buf, binary.LittleEndian, Section32{
+			Name:      0x11,
+			Type:      uint32(SHT_STRTAB),
+			Off:       0x20E091,
+			Size:      0x0CF3BB,
+			Addralign: 0x01,
+		})
+	}
+
+	data := buf.Bytes()
+
+	f, err := NewFile(bytes.NewReader(data))
+	if err != nil {
+		t.Errorf("cannot create file from data: %v", err)
+	}
+	defer f.Close()
+
+	wantFileHeader := FileHeader{
+		Class:     ELFCLASS32,
+		Data:      ELFDATA2LSB,
+		Version:   EV_CURRENT,
+		OSABI:     ELFOSABI_NONE,
+		ByteOrder: binary.LittleEndian,
+		Type:      ET_REL,
+		Machine:   EM_386,
+	}
+	if f.FileHeader != wantFileHeader {
+		t.Errorf("\nhave %#v\nwant %#v\n", f.FileHeader, wantFileHeader)
+	}
+
+	wantSectionNum := 65298
+	if len(f.Sections) != wantSectionNum {
+		t.Errorf("len(Sections) = %d, want %d", len(f.Sections), wantSectionNum)
+	}
+
+	wantSectionHeader := SectionHeader{
+		Name:      "section_0007",
+		Type:      SHT_PROGBITS,
+		Flags:     SHF_WRITE + SHF_ALLOC,
+		Offset:    0x4c,
+		Size:      0x4,
+		Addralign: 0x4,
+		FileSize:  0x4,
+	}
+	if f.Sections[10].SectionHeader != wantSectionHeader {
+		t.Errorf("\nhave %#v\nwant %#v\n", f.Sections[10].SectionHeader, wantSectionHeader)
+	}
+}
+
 func TestIssue10996(t *testing.T) {
 	data := []byte("\u007fELF\x02\x01\x010000000000000" +
 		"\x010000000000000000000" +
diff --git a/src/debug/gosym/pclntab.go b/src/debug/gosym/pclntab.go
index 2ceea3d..a87e6cf 100644
--- a/src/debug/gosym/pclntab.go
+++ b/src/debug/gosym/pclntab.go
@@ -24,6 +24,7 @@
 	ver12
 	ver116
 	ver118
+	ver120
 )
 
 // A LineTable is a data structure mapping program counters to line numbers.
@@ -173,6 +174,7 @@
 	go12magic  = 0xfffffffb
 	go116magic = 0xfffffffa
 	go118magic = 0xfffffff0
+	go120magic = 0xfffffff1
 )
 
 // uintptr returns the pointer-sized value encoded at b.
@@ -229,6 +231,10 @@
 		t.binary, possibleVersion = binary.LittleEndian, ver118
 	case beMagic == go118magic:
 		t.binary, possibleVersion = binary.BigEndian, ver118
+	case leMagic == go120magic:
+		t.binary, possibleVersion = binary.LittleEndian, ver120
+	case beMagic == go120magic:
+		t.binary, possibleVersion = binary.BigEndian, ver120
 	default:
 		return
 	}
@@ -246,7 +252,7 @@
 	}
 
 	switch possibleVersion {
-	case ver118:
+	case ver118, ver120:
 		t.nfunctab = uint32(offset(0))
 		t.nfiletab = uint32(offset(1))
 		t.textStart = t.PC // use the start PC instead of reading from the table, which may be unrelocated
@@ -306,11 +312,12 @@
 		f.LineTable = t
 		f.FrameSize = int(info.deferreturn())
 		syms[i] = Sym{
-			Value:  f.Entry,
-			Type:   'T',
-			Name:   t.funcName(info.nameoff()),
-			GoType: 0,
-			Func:   f,
+			Value:     f.Entry,
+			Type:      'T',
+			Name:      t.funcName(info.nameOff()),
+			GoType:    0,
+			Func:      f,
+			goVersion: t.version,
 		}
 		f.Sym = &syms[i]
 	}
@@ -449,7 +456,7 @@
 	return f.t.uintptr(f.data)
 }
 
-func (f funcData) nameoff() uint32     { return f.field(1) }
+func (f funcData) nameOff() uint32     { return f.field(1) }
 func (f funcData) deferreturn() uint32 { return f.field(3) }
 func (f funcData) pcfile() uint32      { return f.field(5) }
 func (f funcData) pcln() uint32        { return f.field(6) }
@@ -527,7 +534,7 @@
 	fileStartPC := filePC
 	for t.step(&fp, &filePC, &fileVal, filePC == entry) {
 		fileIndex := fileVal
-		if t.version == ver116 || t.version == ver118 {
+		if t.version == ver116 || t.version == ver118 || t.version == ver120 {
 			fileIndex = int32(t.binary.Uint32(cutab[fileVal*4:]))
 		}
 		if fileIndex == filenum && fileStartPC < filePC {
@@ -626,7 +633,7 @@
 		entry := f.entryPC()
 		filetab := f.pcfile()
 		linetab := f.pcln()
-		if t.version == ver116 || t.version == ver118 {
+		if t.version == ver116 || t.version == ver118 || t.version == ver120 {
 			if f.cuOffset() == ^uint32(0) {
 				// skip functions without compilation unit (not real function, or linker generated)
 				continue
diff --git a/src/debug/gosym/pclntab_test.go b/src/debug/gosym/pclntab_test.go
index 04b5fcc..e380bb5 100644
--- a/src/debug/gosym/pclntab_test.go
+++ b/src/debug/gosym/pclntab_test.go
@@ -268,6 +268,20 @@
 	}
 }
 
+func TestSymVersion(t *testing.T) {
+	skipIfNotELF(t)
+
+	table := getTable(t)
+	if table.go12line == nil {
+		t.Skip("not relevant to Go 1.2+ symbol table")
+	}
+	for _, fn := range table.Funcs {
+		if fn.goVersion == verUnknown {
+			t.Fatalf("unexpected symbol version: %v", fn)
+		}
+	}
+}
+
 // read115Executable returns a hello world executable compiled by Go 1.15.
 //
 // The file was compiled in /tmp/hello.go:
diff --git a/src/debug/gosym/symtab.go b/src/debug/gosym/symtab.go
index afc6719..d87b312 100644
--- a/src/debug/gosym/symtab.go
+++ b/src/debug/gosym/symtab.go
@@ -27,6 +27,8 @@
 	GoType uint64
 	// If this symbol is a function symbol, the corresponding Func
 	Func *Func
+
+	goVersion version
 }
 
 // Static reports whether this symbol is static (not visible outside its file).
@@ -55,9 +57,16 @@
 func (s *Sym) PackageName() string {
 	name := s.nameWithoutInst()
 
-	// A prefix of "type." and "go." is a compiler-generated symbol that doesn't belong to any package.
-	// See variable reservedimports in cmd/compile/internal/gc/subr.go
-	if strings.HasPrefix(name, "go.") || strings.HasPrefix(name, "type.") {
+	// Since go1.20, a prefix of "type:" and "go:" is a compiler-generated symbol,
+	// they do not belong to any package.
+	//
+	// See cmd/compile/internal/base/link.go:ReservedImports variable.
+	if s.goVersion >= ver120 && (strings.HasPrefix(name, "go:") || strings.HasPrefix(name, "type:")) {
+		return ""
+	}
+
+	// For go1.18 and below, the prefix are "type." and "go." instead.
+	if s.goVersion <= ver118 && (strings.HasPrefix(name, "go.") || strings.HasPrefix(name, "type.")) {
 		return ""
 	}
 
@@ -350,6 +359,7 @@
 		ts.Type = s.typ
 		ts.Value = s.value
 		ts.GoType = s.gotype
+		ts.goVersion = pcln.version
 		switch s.typ {
 		default:
 			// rewrite name to use . instead of · (c2 b7)
diff --git a/src/debug/gosym/symtab_test.go b/src/debug/gosym/symtab_test.go
index da3c212..bb1f267 100644
--- a/src/debug/gosym/symtab_test.go
+++ b/src/debug/gosym/symtab_test.go
@@ -62,16 +62,26 @@
 }
 
 func TestIssue29551(t *testing.T) {
-	symNames := []string{
-		"type..eq.[9]debug/elf.intName",
-		"type..hash.debug/elf.ProgHeader",
-		"type..eq.runtime._panic",
-		"type..hash.struct { runtime.gList; runtime.n int32 }",
-		"go.(*struct { sync.Mutex; math/big.table [64]math/big",
+	tests := []struct {
+		sym     Sym
+		pkgName string
+	}{
+		{Sym{goVersion: ver120, Name: "type:.eq.[9]debug/elf.intName"}, ""},
+		{Sym{goVersion: ver120, Name: "type:.hash.debug/elf.ProgHeader"}, ""},
+		{Sym{goVersion: ver120, Name: "type:.eq.runtime._panic"}, ""},
+		{Sym{goVersion: ver120, Name: "type:.hash.struct { runtime.gList; runtime.n int32 }"}, ""},
+		{Sym{goVersion: ver120, Name: "go:(*struct { sync.Mutex; math/big.table [64]math/big"}, ""},
+		{Sym{goVersion: ver120, Name: "go.uber.org/zap/buffer.(*Buffer).AppendString"}, "go.uber.org/zap/buffer"},
+		{Sym{goVersion: ver118, Name: "type..eq.[9]debug/elf.intName"}, ""},
+		{Sym{goVersion: ver118, Name: "type..hash.debug/elf.ProgHeader"}, ""},
+		{Sym{goVersion: ver118, Name: "type..eq.runtime._panic"}, ""},
+		{Sym{goVersion: ver118, Name: "type..hash.struct { runtime.gList; runtime.n int32 }"}, ""},
+		{Sym{goVersion: ver118, Name: "go.(*struct { sync.Mutex; math/big.table [64]math/big"}, ""},
+		// unfortunate
+		{Sym{goVersion: ver118, Name: "go.uber.org/zap/buffer.(*Buffer).AppendString"}, ""},
 	}
 
-	for _, symName := range symNames {
-		s := Sym{Name: symName}
-		assertString(t, fmt.Sprintf("package of %q", s.Name), s.PackageName(), "")
+	for _, tc := range tests {
+		assertString(t, fmt.Sprintf("package of %q", tc.sym.Name), tc.sym.PackageName(), tc.pkgName)
 	}
 }
diff --git a/src/debug/macho/fat.go b/src/debug/macho/fat.go
index 6bd730d..679cefb 100644
--- a/src/debug/macho/fat.go
+++ b/src/debug/macho/fat.go
@@ -7,6 +7,7 @@
 import (
 	"encoding/binary"
 	"fmt"
+	"internal/saferio"
 	"io"
 	"os"
 )
@@ -79,15 +80,19 @@
 
 	// Combine the Cpu and SubCpu (both uint32) into a uint64 to make sure
 	// there are not duplicate architectures.
-	seenArches := make(map[uint64]bool, narch)
+	seenArches := make(map[uint64]bool)
 	// Make sure that all images are for the same MH_ type.
 	var machoType Type
 
 	// Following the fat_header comes narch fat_arch structs that index
 	// Mach-O images further in the file.
-	ff.Arches = make([]FatArch, narch)
+	c := saferio.SliceCap((*FatArch)(nil), uint64(narch))
+	if c < 0 {
+		return nil, &FormatError{offset, "too many images", nil}
+	}
+	ff.Arches = make([]FatArch, 0, c)
 	for i := uint32(0); i < narch; i++ {
-		fa := &ff.Arches[i]
+		var fa FatArch
 		err = binary.Read(sr, binary.BigEndian, &fa.FatArchHeader)
 		if err != nil {
 			return nil, &FormatError{offset, "invalid fat_arch header", nil}
@@ -115,6 +120,8 @@
 				return nil, &FormatError{offset, fmt.Sprintf("Mach-O type for architecture #%d (type=%#x) does not match first (type=%#x)", i, fa.Type, machoType), nil}
 			}
 		}
+
+		ff.Arches = append(ff.Arches, fa)
 	}
 
 	return &ff, nil
diff --git a/src/debug/macho/file.go b/src/debug/macho/file.go
index b57dba8..ecde25a 100644
--- a/src/debug/macho/file.go
+++ b/src/debug/macho/file.go
@@ -2,7 +2,17 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Package macho implements access to Mach-O object files.
+/*
+Package macho implements access to Mach-O object files.
+
+# Security
+
+This package is not designed to be hardened against adversarial inputs, and is
+outside the scope of https://go.dev/security/policy. In particular, only basic
+validation is done when parsing object files. As such, care should be taken when
+parsing untrusted inputs, as parsing malformed files may consume significant
+resources, or cause panics.
+*/
 package macho
 
 // High level access to low level data structures.
@@ -13,6 +23,7 @@
 	"debug/dwarf"
 	"encoding/binary"
 	"fmt"
+	"internal/saferio"
 	"io"
 	"os"
 	"strings"
@@ -73,12 +84,7 @@
 
 // Data reads and returns the contents of the segment.
 func (s *Segment) Data() ([]byte, error) {
-	dat := make([]byte, s.sr.Size())
-	n, err := s.sr.ReadAt(dat, 0)
-	if n == len(dat) {
-		err = nil
-	}
-	return dat[0:n], err
+	return saferio.ReadDataAt(s.sr, s.Filesz, 0)
 }
 
 // Open returns a new ReadSeeker reading the segment.
@@ -126,12 +132,7 @@
 
 // Data reads and returns the contents of the Mach-O section.
 func (s *Section) Data() ([]byte, error) {
-	dat := make([]byte, s.sr.Size())
-	n, err := s.sr.ReadAt(dat, 0)
-	if n == len(dat) {
-		err = nil
-	}
-	return dat[0:n], err
+	return saferio.ReadDataAt(s.sr, s.Size, 0)
 }
 
 // Open returns a new ReadSeeker reading the Mach-O section.
@@ -258,13 +259,17 @@
 	if f.Magic == Magic64 {
 		offset = fileHeaderSize64
 	}
-	dat := make([]byte, f.Cmdsz)
-	if _, err := r.ReadAt(dat, offset); err != nil {
+	dat, err := saferio.ReadDataAt(r, uint64(f.Cmdsz), offset)
+	if err != nil {
 		return nil, err
 	}
-	f.Loads = make([]Load, f.Ncmd)
+	c := saferio.SliceCap((*Load)(nil), uint64(f.Ncmd))
+	if c < 0 {
+		return nil, &FormatError{offset, "too many load commands", nil}
+	}
+	f.Loads = make([]Load, 0, c)
 	bo := f.ByteOrder
-	for i := range f.Loads {
+	for i := uint32(0); i < f.Ncmd; i++ {
 		// Each load command begins with uint32 command and length.
 		if len(dat) < 8 {
 			return nil, &FormatError{offset, "command block too small", nil}
@@ -279,7 +284,7 @@
 		var s *Segment
 		switch cmd {
 		default:
-			f.Loads[i] = LoadBytes(cmddat)
+			f.Loads = append(f.Loads, LoadBytes(cmddat))
 
 		case LoadCmdRpath:
 			var hdr RpathCmd
@@ -293,7 +298,7 @@
 			}
 			l.Path = cstring(cmddat[hdr.Path:])
 			l.LoadBytes = LoadBytes(cmddat)
-			f.Loads[i] = l
+			f.Loads = append(f.Loads, l)
 
 		case LoadCmdDylib:
 			var hdr DylibCmd
@@ -310,7 +315,7 @@
 			l.CurrentVersion = hdr.CurrentVersion
 			l.CompatVersion = hdr.CompatVersion
 			l.LoadBytes = LoadBytes(cmddat)
-			f.Loads[i] = l
+			f.Loads = append(f.Loads, l)
 
 		case LoadCmdSymtab:
 			var hdr SymtabCmd
@@ -328,15 +333,15 @@
 			} else {
 				symsz = 12
 			}
-			symdat := make([]byte, int(hdr.Nsyms)*symsz)
-			if _, err := r.ReadAt(symdat, int64(hdr.Symoff)); err != nil {
+			symdat, err := saferio.ReadDataAt(r, uint64(hdr.Nsyms)*uint64(symsz), int64(hdr.Symoff))
+			if err != nil {
 				return nil, err
 			}
 			st, err := f.parseSymtab(symdat, strtab, cmddat, &hdr, offset)
 			if err != nil {
 				return nil, err
 			}
-			f.Loads[i] = st
+			f.Loads = append(f.Loads, st)
 			f.Symtab = st
 
 		case LoadCmdDysymtab:
@@ -366,7 +371,7 @@
 			st.LoadBytes = LoadBytes(cmddat)
 			st.DysymtabCmd = hdr
 			st.IndirectSyms = x
-			f.Loads[i] = st
+			f.Loads = append(f.Loads, st)
 			f.Dysymtab = st
 
 		case LoadCmdSegment:
@@ -388,7 +393,7 @@
 			s.Prot = seg32.Prot
 			s.Nsect = seg32.Nsect
 			s.Flag = seg32.Flag
-			f.Loads[i] = s
+			f.Loads = append(f.Loads, s)
 			for i := 0; i < int(s.Nsect); i++ {
 				var sh32 Section32
 				if err := binary.Read(b, bo, &sh32); err != nil {
@@ -428,7 +433,7 @@
 			s.Prot = seg64.Prot
 			s.Nsect = seg64.Nsect
 			s.Flag = seg64.Flag
-			f.Loads[i] = s
+			f.Loads = append(f.Loads, s)
 			for i := 0; i < int(s.Nsect); i++ {
 				var sh64 Section64
 				if err := binary.Read(b, bo, &sh64); err != nil {
@@ -450,6 +455,12 @@
 			}
 		}
 		if s != nil {
+			if int64(s.Offset) < 0 {
+				return nil, &FormatError{offset, "invalid section offset", s.Offset}
+			}
+			if int64(s.Filesz) < 0 {
+				return nil, &FormatError{offset, "invalid section file size", s.Filesz}
+			}
 			s.sr = io.NewSectionReader(r, int64(s.Offset), int64(s.Filesz))
 			s.ReaderAt = s.sr
 		}
@@ -459,9 +470,13 @@
 
 func (f *File) parseSymtab(symdat, strtab, cmddat []byte, hdr *SymtabCmd, offset int64) (*Symtab, error) {
 	bo := f.ByteOrder
-	symtab := make([]Symbol, hdr.Nsyms)
+	c := saferio.SliceCap((*Symbol)(nil), uint64(hdr.Nsyms))
+	if c < 0 {
+		return nil, &FormatError{offset, "too many symbols", nil}
+	}
+	symtab := make([]Symbol, 0, c)
 	b := bytes.NewReader(symdat)
-	for i := range symtab {
+	for i := 0; i < int(hdr.Nsyms); i++ {
 		var n Nlist64
 		if f.Magic == Magic64 {
 			if err := binary.Read(b, bo, &n); err != nil {
@@ -478,7 +493,6 @@
 			n.Desc = n32.Desc
 			n.Value = uint64(n32.Value)
 		}
-		sym := &symtab[i]
 		if n.Name >= uint32(len(strtab)) {
 			return nil, &FormatError{offset, "invalid name in symbol table", n.Name}
 		}
@@ -487,11 +501,13 @@
 		if strings.Contains(name, ".") && name[0] == '_' {
 			name = name[1:]
 		}
-		sym.Name = name
-		sym.Type = n.Type
-		sym.Sect = n.Sect
-		sym.Desc = n.Desc
-		sym.Value = n.Value
+		symtab = append(symtab, Symbol{
+			Name:  name,
+			Type:  n.Type,
+			Sect:  n.Sect,
+			Desc:  n.Desc,
+			Value: n.Value,
+		})
 	}
 	st := new(Symtab)
 	st.LoadBytes = LoadBytes(cmddat)
@@ -510,8 +526,8 @@
 	sh.ReaderAt = sh.sr
 
 	if sh.Nreloc > 0 {
-		reldat := make([]byte, int(sh.Nreloc)*8)
-		if _, err := r.ReadAt(reldat, int64(sh.Reloff)); err != nil {
+		reldat, err := saferio.ReadDataAt(r, uint64(sh.Nreloc)*8, int64(sh.Reloff))
+		if err != nil {
 			return err
 		}
 		b := bytes.NewReader(reldat)
diff --git a/src/debug/pe/file.go b/src/debug/pe/file.go
index aa0955a..f8c922d 100644
--- a/src/debug/pe/file.go
+++ b/src/debug/pe/file.go
@@ -2,7 +2,17 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Package pe implements access to PE (Microsoft Windows Portable Executable) files.
+/*
+Package pe implements access to PE (Microsoft Windows Portable Executable) files.
+
+# Security
+
+This package is not designed to be hardened against adversarial inputs, and is
+outside the scope of https://go.dev/security/policy. In particular, only basic
+validation is done when parsing object files. As such, care should be taken when
+parsing untrusted inputs, as parsing malformed files may consume significant
+resources, or cause panics.
+*/
 package pe
 
 import (
@@ -90,6 +100,9 @@
 		IMAGE_FILE_MACHINE_ARM64,
 		IMAGE_FILE_MACHINE_ARMNT,
 		IMAGE_FILE_MACHINE_I386,
+		IMAGE_FILE_MACHINE_RISCV32,
+		IMAGE_FILE_MACHINE_RISCV64,
+		IMAGE_FILE_MACHINE_RISCV128,
 		IMAGE_FILE_MACHINE_UNKNOWN:
 		// ok
 	default:
@@ -322,7 +335,7 @@
 		return nil, nil
 	}
 
-	pe64 := f.Machine == IMAGE_FILE_MACHINE_AMD64 || f.Machine == IMAGE_FILE_MACHINE_ARM64
+	_, pe64 := f.OptionalHeader.(*OptionalHeader64)
 
 	// grab the number of data directory entries
 	var dd_length uint32
@@ -350,7 +363,10 @@
 	var ds *Section
 	ds = nil
 	for _, s := range f.Sections {
-		if s.VirtualAddress <= idd.VirtualAddress && idd.VirtualAddress < s.VirtualAddress+s.VirtualSize {
+		// We are using distance between s.VirtualAddress and idd.VirtualAddress
+		// to avoid potential overflow of uint32 caused by addition of s.VirtualSize
+		// to s.VirtualAddress.
+		if s.VirtualAddress <= idd.VirtualAddress && idd.VirtualAddress-s.VirtualAddress < s.VirtualSize {
 			ds = s
 			break
 		}
@@ -600,8 +616,8 @@
 // its size and number of data directories as seen in optional header.
 // It parses the given size of bytes and returns given number of data directories.
 func readDataDirectories(r io.ReadSeeker, sz uint16, n uint32) ([]DataDirectory, error) {
-	ddSz := binary.Size(DataDirectory{})
-	if uint32(sz) != n*uint32(ddSz) {
+	ddSz := uint64(binary.Size(DataDirectory{}))
+	if uint64(sz) != uint64(n)*ddSz {
 		return nil, fmt.Errorf("size of data directories(%d) is inconsistent with number of data directories(%d)", sz, n)
 	}
 
diff --git a/src/debug/pe/pe.go b/src/debug/pe/pe.go
index 9d55c40..51001bd 100644
--- a/src/debug/pe/pe.go
+++ b/src/debug/pe/pe.go
@@ -111,6 +111,9 @@
 	IMAGE_FILE_MACHINE_SH5         = 0x1a8
 	IMAGE_FILE_MACHINE_THUMB       = 0x1c2
 	IMAGE_FILE_MACHINE_WCEMIPSV2   = 0x169
+	IMAGE_FILE_MACHINE_RISCV32     = 0x5032
+	IMAGE_FILE_MACHINE_RISCV64     = 0x5064
+	IMAGE_FILE_MACHINE_RISCV128    = 0x5128
 )
 
 // IMAGE_DIRECTORY_ENTRY constants
diff --git a/src/debug/pe/section.go b/src/debug/pe/section.go
index ee59ded..fabb47a 100644
--- a/src/debug/pe/section.go
+++ b/src/debug/pe/section.go
@@ -7,6 +7,7 @@
 import (
 	"encoding/binary"
 	"fmt"
+	"internal/saferio"
 	"io"
 	"strconv"
 )
@@ -97,12 +98,7 @@
 
 // Data reads and returns the contents of the PE section s.
 func (s *Section) Data() ([]byte, error) {
-	dat := make([]byte, s.sr.Size())
-	n, err := s.sr.ReadAt(dat, 0)
-	if n == len(dat) {
-		err = nil
-	}
-	return dat[0:n], err
+	return saferio.ReadDataAt(s.sr, uint64(s.Size), 0)
 }
 
 // Open returns a new ReadSeeker reading the PE section s.
diff --git a/src/debug/pe/string.go b/src/debug/pe/string.go
index 6d9023d..a156bbe 100644
--- a/src/debug/pe/string.go
+++ b/src/debug/pe/string.go
@@ -8,6 +8,7 @@
 	"bytes"
 	"encoding/binary"
 	"fmt"
+	"internal/saferio"
 	"io"
 )
 
@@ -45,28 +46,7 @@
 	}
 	l -= 4
 
-	// If the string table is large, the file may be corrupt.
-	// Read in chunks to avoid crashing due to out of memory.
-	const chunk = 10 << 20 // 10M
-	var buf []byte
-	if l < chunk {
-		buf = make([]byte, l)
-		_, err = io.ReadFull(r, buf)
-	} else {
-		for l > 0 {
-			n := l
-			if n > chunk {
-				n = chunk
-			}
-			buf1 := make([]byte, n)
-			_, err = io.ReadFull(r, buf1)
-			if err != nil {
-				break
-			}
-			buf = append(buf, buf1...)
-			l -= n
-		}
-	}
+	buf, err := saferio.ReadData(r, uint64(l))
 	if err != nil {
 		return nil, fmt.Errorf("fail to read string table: %v", err)
 	}
diff --git a/src/debug/pe/symbol.go b/src/debug/pe/symbol.go
index 86a1fbc..b1654f8 100644
--- a/src/debug/pe/symbol.go
+++ b/src/debug/pe/symbol.go
@@ -6,7 +6,9 @@
 
 import (
 	"encoding/binary"
+	"errors"
 	"fmt"
+	"internal/saferio"
 	"io"
 	"unsafe"
 )
@@ -57,29 +59,35 @@
 	if err != nil {
 		return nil, fmt.Errorf("fail to seek to symbol table: %v", err)
 	}
-	syms := make([]COFFSymbol, fh.NumberOfSymbols)
+	c := saferio.SliceCap((*COFFSymbol)(nil), uint64(fh.NumberOfSymbols))
+	if c < 0 {
+		return nil, errors.New("too many symbols; file may be corrupt")
+	}
+	syms := make([]COFFSymbol, 0, c)
 	naux := 0
-	for k := range syms {
+	for k := uint32(0); k < fh.NumberOfSymbols; k++ {
+		var sym COFFSymbol
 		if naux == 0 {
 			// Read a primary symbol.
-			err = binary.Read(r, binary.LittleEndian, &syms[k])
+			err = binary.Read(r, binary.LittleEndian, &sym)
 			if err != nil {
 				return nil, fmt.Errorf("fail to read symbol table: %v", err)
 			}
 			// Record how many auxiliary symbols it has.
-			naux = int(syms[k].NumberOfAuxSymbols)
+			naux = int(sym.NumberOfAuxSymbols)
 		} else {
 			// Read an aux symbol. At the moment we assume all
 			// aux symbols are format 5 (obviously this doesn't always
 			// hold; more cases will be needed below if more aux formats
 			// are supported in the future).
 			naux--
-			aux := (*COFFSymbolAuxFormat5)(unsafe.Pointer(&syms[k]))
+			aux := (*COFFSymbolAuxFormat5)(unsafe.Pointer(&sym))
 			err = binary.Read(r, binary.LittleEndian, aux)
 			if err != nil {
 				return nil, fmt.Errorf("fail to read symbol table: %v", err)
 			}
 		}
+		syms = append(syms, sym)
 	}
 	if naux != 0 {
 		return nil, fmt.Errorf("fail to read symbol table: %d aux symbols unread", naux)
diff --git a/src/debug/plan9obj/file.go b/src/debug/plan9obj/file.go
index aa03429..ad74c72 100644
--- a/src/debug/plan9obj/file.go
+++ b/src/debug/plan9obj/file.go
@@ -2,13 +2,24 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Package plan9obj implements access to Plan 9 a.out object files.
+/*
+Package plan9obj implements access to Plan 9 a.out object files.
+
+# Security
+
+This package is not designed to be hardened against adversarial inputs, and is
+outside the scope of https://go.dev/security/policy. In particular, only basic
+validation is done when parsing object files. As such, care should be taken when
+parsing untrusted inputs, as parsing malformed files may consume significant
+resources, or cause panics.
+*/
 package plan9obj
 
 import (
 	"encoding/binary"
 	"errors"
 	"fmt"
+	"internal/saferio"
 	"io"
 	"os"
 )
@@ -55,12 +66,7 @@
 
 // Data reads and returns the contents of the Plan 9 a.out section.
 func (s *Section) Data() ([]byte, error) {
-	dat := make([]byte, s.sr.Size())
-	n, err := s.sr.ReadAt(dat, 0)
-	if n == len(dat) {
-		err = nil
-	}
-	return dat[0:n], err
+	return saferio.ReadDataAt(s.sr, uint64(s.Size), 0)
 }
 
 // Open returns a new ReadSeeker reading the Plan 9 a.out section.
@@ -216,6 +222,9 @@
 			p = p[4:]
 		}
 
+		if len(p) < 1 {
+			return &formatError{len(data), "unexpected EOF", nil}
+		}
 		typ := p[0] & 0x7F
 		s.typ = typ
 		p = p[1:]
@@ -251,7 +260,7 @@
 	return nil
 }
 
-// NewTable decodes the Go symbol table in data,
+// newTable decodes the Go symbol table in data,
 // returning an in-memory representation.
 func newTable(symtab []byte, ptrsz int) ([]Sym, error) {
 	var n int
diff --git a/src/encoding/ascii85/ascii85_test.go b/src/encoding/ascii85/ascii85_test.go
index 9e6b34e..578829e 100644
--- a/src/encoding/ascii85/ascii85_test.go
+++ b/src/encoding/ascii85/ascii85_test.go
@@ -75,7 +75,7 @@
 
 func TestEncoder(t *testing.T) {
 	for _, p := range pairs {
-		bb := &bytes.Buffer{}
+		bb := &strings.Builder{}
 		encoder := NewEncoder(bb)
 		encoder.Write([]byte(p.decoded))
 		encoder.Close()
@@ -86,7 +86,7 @@
 func TestEncoderBuffering(t *testing.T) {
 	input := []byte(bigtest.decoded)
 	for bs := 1; bs <= 12; bs++ {
-		bb := &bytes.Buffer{}
+		bb := &strings.Builder{}
 		encoder := NewEncoder(bb)
 		for pos := 0; pos < len(input); pos += bs {
 			end := pos + bs
diff --git a/src/encoding/asn1/asn1.go b/src/encoding/asn1/asn1.go
index c90bba4..2e32089 100644
--- a/src/encoding/asn1/asn1.go
+++ b/src/encoding/asn1/asn1.go
@@ -111,7 +111,7 @@
 	return
 }
 
-// parseInt treats the given bytes as a big-endian, signed integer and returns
+// parseInt32 treats the given bytes as a big-endian, signed integer and returns
 // the result.
 func parseInt32(bytes []byte) (int32, error) {
 	if err := checkInteger(bytes); err != nil {
@@ -162,7 +162,7 @@
 }
 
 // At returns the bit at the given index. If the index is out of range it
-// returns false.
+// returns 0.
 func (b BitString) At(i int) int {
 	if i < 0 || i >= b.BitLength {
 		return 0
@@ -660,7 +660,7 @@
 	timeType             = reflect.TypeOf(time.Time{})
 	rawValueType         = reflect.TypeOf(RawValue{})
 	rawContentsType      = reflect.TypeOf(RawContent(nil))
-	bigIntType           = reflect.TypeOf(new(big.Int))
+	bigIntType           = reflect.TypeOf((*big.Int)(nil))
 )
 
 // invalidLength reports whether offset + length > sliceLength, or if the
diff --git a/src/encoding/asn1/asn1_test.go b/src/encoding/asn1/asn1_test.go
index b1e05b9..90bdfcd 100644
--- a/src/encoding/asn1/asn1_test.go
+++ b/src/encoding/asn1/asn1_test.go
@@ -102,7 +102,7 @@
 		if (err == nil) != test.ok {
 			t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
 		}
-		if test.ok && int32(ret) != test.out {
+		if test.ok && ret != test.out {
 			t.Errorf("#%d: Bad result: %v (expected %v)", i, ret, test.out)
 		}
 	}
diff --git a/src/encoding/base32/base32.go b/src/encoding/base32/base32.go
index fa6e42e..41d343a 100644
--- a/src/encoding/base32/base32.go
+++ b/src/encoding/base32/base32.go
@@ -25,8 +25,25 @@
 }
 
 const (
-	StdPadding rune = '=' // Standard padding character
-	NoPadding  rune = -1  // No padding
+	StdPadding          rune = '=' // Standard padding character
+	NoPadding           rune = -1  // No padding
+	decodeMapInitialize      = "" +
+		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
 )
 
 const encodeStd = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
@@ -40,12 +57,10 @@
 	}
 
 	e := new(Encoding)
-	copy(e.encode[:], encoder)
 	e.padChar = StdPadding
+	copy(e.encode[:], encoder)
+	copy(e.decodeMap[:], decodeMapInitialize)
 
-	for i := 0; i < len(e.decodeMap); i++ {
-		e.decodeMap[i] = 0xFF
-	}
 	for i := 0; i < len(encoder); i++ {
 		e.decodeMap[encoder[i]] = byte(i)
 	}
diff --git a/src/encoding/base32/base32_test.go b/src/encoding/base32/base32_test.go
index 323d04e..8118531 100644
--- a/src/encoding/base32/base32_test.go
+++ b/src/encoding/base32/base32_test.go
@@ -60,7 +60,7 @@
 
 func TestEncoder(t *testing.T) {
 	for _, p := range pairs {
-		bb := &bytes.Buffer{}
+		bb := &strings.Builder{}
 		encoder := NewEncoder(StdEncoding, bb)
 		encoder.Write([]byte(p.decoded))
 		encoder.Close()
@@ -71,7 +71,7 @@
 func TestEncoderBuffering(t *testing.T) {
 	input := []byte(bigtest.decoded)
 	for bs := 1; bs <= 12; bs++ {
-		bb := &bytes.Buffer{}
+		bb := &strings.Builder{}
 		encoder := NewEncoder(StdEncoding, bb)
 		for pos := 0; pos < len(input); pos += bs {
 			end := pos + bs
@@ -268,7 +268,7 @@
 		decoder := NewDecoder(StdEncoding, &br)
 		dbuf := make([]byte, StdEncoding.DecodedLen(len(input)))
 		n, err := decoder.Read(dbuf)
-		testEqual(t, "Decoding of %q err = %v, expected %v", string(input), err, error(nil))
+		testEqual(t, "Decoding of %q err = %v, expected %v", input, err, error(nil))
 		n, err = decoder.Read(dbuf)
 		testEqual(t, "Read after EOF, n = %d, expected %d", n, 0)
 		testEqual(t, "Read after EOF, err = %v, expected %v", err, io.EOF)
@@ -737,7 +737,7 @@
 	for _, encoding := range encodings {
 		for _, testpair := range pairs {
 
-			var buf bytes.Buffer
+			var buf strings.Builder
 			encoder := NewEncoder(encoding, &buf)
 			encoder.Write([]byte(testpair.decoded))
 			encoder.Close()
diff --git a/src/encoding/base64/base64.go b/src/encoding/base64/base64.go
index 4a3e590..0e12d90 100644
--- a/src/encoding/base64/base64.go
+++ b/src/encoding/base64/base64.go
@@ -28,8 +28,25 @@
 }
 
 const (
-	StdPadding rune = '=' // Standard padding character
-	NoPadding  rune = -1  // No padding
+	StdPadding          rune = '=' // Standard padding character
+	NoPadding           rune = -1  // No padding
+	decodeMapInitialize      = "" +
+		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
 )
 
 const encodeStd = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
@@ -53,10 +70,8 @@
 	e := new(Encoding)
 	e.padChar = StdPadding
 	copy(e.encode[:], encoder)
+	copy(e.decodeMap[:], decodeMapInitialize)
 
-	for i := 0; i < len(e.decodeMap); i++ {
-		e.decodeMap[i] = 0xFF
-	}
 	for i := 0; i < len(encoder); i++ {
 		e.decodeMap[encoder[i]] = byte(i)
 	}
diff --git a/src/encoding/base64/base64_test.go b/src/encoding/base64/base64_test.go
index 57256a3..0ad88eb 100644
--- a/src/encoding/base64/base64_test.go
+++ b/src/encoding/base64/base64_test.go
@@ -119,7 +119,7 @@
 
 func TestEncoder(t *testing.T) {
 	for _, p := range pairs {
-		bb := &bytes.Buffer{}
+		bb := &strings.Builder{}
 		encoder := NewEncoder(StdEncoding, bb)
 		encoder.Write([]byte(p.decoded))
 		encoder.Close()
@@ -130,7 +130,7 @@
 func TestEncoderBuffering(t *testing.T) {
 	input := []byte(bigtest.decoded)
 	for bs := 1; bs <= 12; bs++ {
-		bb := &bytes.Buffer{}
+		bb := &strings.Builder{}
 		encoder := NewEncoder(StdEncoding, bb)
 		for pos := 0; pos < len(input); pos += bs {
 			end := pos + bs
@@ -504,6 +504,16 @@
 	}
 }
 
+func BenchmarkNewEncoding(b *testing.B) {
+	b.SetBytes(int64(len(Encoding{}.decodeMap)))
+	for i := 0; i < b.N; i++ {
+		e := NewEncoding(encodeStd)
+		for _, v := range e.decodeMap {
+			_ = v
+		}
+	}
+}
+
 func TestDecoderRaw(t *testing.T) {
 	source := "AAAAAA"
 	want := []byte{0, 0, 0, 0}
diff --git a/src/encoding/binary/varint.go b/src/encoding/binary/varint.go
index c807d15..18e1ff1 100644
--- a/src/encoding/binary/varint.go
+++ b/src/encoding/binary/varint.go
@@ -126,12 +126,18 @@
 var overflow = errors.New("binary: varint overflows a 64-bit integer")
 
 // ReadUvarint reads an encoded unsigned integer from r and returns it as a uint64.
+// The error is EOF only if no bytes were read.
+// If an EOF happens after reading some but not all the bytes,
+// ReadUvarint returns io.ErrUnexpectedEOF.
 func ReadUvarint(r io.ByteReader) (uint64, error) {
 	var x uint64
 	var s uint
 	for i := 0; i < MaxVarintLen64; i++ {
 		b, err := r.ReadByte()
 		if err != nil {
+			if i > 0 && err == io.EOF {
+				err = io.ErrUnexpectedEOF
+			}
 			return x, err
 		}
 		if b < 0x80 {
@@ -147,6 +153,9 @@
 }
 
 // ReadVarint reads an encoded signed integer from r and returns it as an int64.
+// The error is EOF only if no bytes were read.
+// If an EOF happens after reading some but not all the bytes,
+// ReadVarint returns io.ErrUnexpectedEOF.
 func ReadVarint(r io.ByteReader) (int64, error) {
 	ux, err := ReadUvarint(r) // ok to continue in presence of error
 	x := int64(ux >> 1)
diff --git a/src/encoding/binary/varint_test.go b/src/encoding/binary/varint_test.go
index 080a214..a3caea8 100644
--- a/src/encoding/binary/varint_test.go
+++ b/src/encoding/binary/varint_test.go
@@ -128,7 +128,11 @@
 		}
 
 		x, err := ReadUvarint(bytes.NewReader(buf))
-		if x != 0 || err != io.EOF {
+		wantErr := io.EOF
+		if i > 0 {
+			wantErr = io.ErrUnexpectedEOF
+		}
+		if x != 0 || err != wantErr {
 			t.Errorf("ReadUvarint(%v): got x = %d, err = %s", buf, x, err)
 		}
 	}
diff --git a/src/encoding/csv/reader.go b/src/encoding/csv/reader.go
index 90a37e6..b83208e 100644
--- a/src/encoding/csv/reader.go
+++ b/src/encoding/csv/reader.go
@@ -84,10 +84,12 @@
 
 // These are the errors that can be returned in ParseError.Err.
 var (
-	ErrTrailingComma = errors.New("extra delimiter at end of line") // Deprecated: No longer used.
-	ErrBareQuote     = errors.New("bare \" in non-quoted-field")
-	ErrQuote         = errors.New("extraneous or missing \" in quoted-field")
-	ErrFieldCount    = errors.New("wrong number of fields")
+	ErrBareQuote  = errors.New("bare \" in non-quoted-field")
+	ErrQuote      = errors.New("extraneous or missing \" in quoted-field")
+	ErrFieldCount = errors.New("wrong number of fields")
+
+	// Deprecated: ErrTrailingComma is no longer used.
+	ErrTrailingComma = errors.New("extra delimiter at end of line")
 )
 
 var errInvalidDelim = errors.New("csv: invalid field or comment delimiter")
@@ -142,7 +144,8 @@
 	// By default, each call to Read returns newly allocated memory owned by the caller.
 	ReuseRecord bool
 
-	TrailingComma bool // Deprecated: No longer used.
+	// Deprecated: TrailingComma is no longer used.
+	TrailingComma bool
 
 	r *bufio.Reader
 
diff --git a/src/encoding/csv/writer_test.go b/src/encoding/csv/writer_test.go
index ab28b0d..de02347 100644
--- a/src/encoding/csv/writer_test.go
+++ b/src/encoding/csv/writer_test.go
@@ -7,6 +7,7 @@
 import (
 	"bytes"
 	"errors"
+	"strings"
 	"testing"
 )
 
@@ -50,7 +51,7 @@
 
 func TestWrite(t *testing.T) {
 	for n, tt := range writeTests {
-		b := &bytes.Buffer{}
+		b := &strings.Builder{}
 		f := NewWriter(b)
 		f.UseCRLF = tt.UseCRLF
 		if tt.Comma != 0 {
diff --git a/src/encoding/gob/codec_test.go b/src/encoding/gob/codec_test.go
index 1ca9d87..54c356c 100644
--- a/src/encoding/gob/codec_test.go
+++ b/src/encoding/gob/codec_test.go
@@ -1467,7 +1467,7 @@
 		t.Skipf("disabled; run with -gob.fuzz to enable")
 	}
 
-	buf := new(bytes.Buffer)
+	buf := new(strings.Builder)
 	Register(OnTheFly{})
 	dt := newDT()
 	if err := NewEncoder(buf).Encode(dt); err != nil {
@@ -1527,3 +1527,69 @@
 		}
 	}
 }
+
+type LargeSliceByte struct {
+	S []byte
+}
+
+type LargeSliceInt8 struct {
+	S []int8
+}
+
+type StringPair struct {
+	A, B string
+}
+
+type LargeSliceStruct struct {
+	S []StringPair
+}
+
+func testEncodeDecode(t *testing.T, in, out any) {
+	t.Helper()
+	var b bytes.Buffer
+	err := NewEncoder(&b).Encode(in)
+	if err != nil {
+		t.Fatal("encode:", err)
+	}
+	err = NewDecoder(&b).Decode(out)
+	if err != nil {
+		t.Fatal("decode:", err)
+	}
+	if !reflect.DeepEqual(in, out) {
+		t.Errorf("output mismatch")
+	}
+}
+
+func TestLargeSlice(t *testing.T) {
+	t.Run("byte", func(t *testing.T) {
+		t.Parallel()
+		s := make([]byte, 10<<21)
+		for i := range s {
+			s[i] = byte(i)
+		}
+		st := &LargeSliceByte{S: s}
+		rt := &LargeSliceByte{}
+		testEncodeDecode(t, st, rt)
+	})
+	t.Run("int8", func(t *testing.T) {
+		t.Parallel()
+		s := make([]int8, 10<<21)
+		for i := range s {
+			s[i] = int8(i)
+		}
+		st := &LargeSliceInt8{S: s}
+		rt := &LargeSliceInt8{}
+		testEncodeDecode(t, st, rt)
+	})
+	t.Run("struct", func(t *testing.T) {
+		t.Parallel()
+		s := make([]StringPair, 1<<21)
+		for i := range s {
+			s[i].A = string(rune(i))
+			s[i].B = s[i].A
+		}
+		st := &LargeSliceStruct{S: s}
+		rt := &LargeSliceStruct{}
+		testEncodeDecode(t, st, rt)
+	})
+}
diff --git a/src/encoding/gob/dec_helpers.go b/src/encoding/gob/dec_helpers.go
index 26eb9e4..a09ac8f 100644
--- a/src/encoding/gob/dec_helpers.go
+++ b/src/encoding/gob/dec_helpers.go
@@ -67,6 +67,10 @@
 		if state.b.Len() == 0 {
 			errorf("decoding bool array or slice: length exceeds input size (%d elements)", length)
 		}
+		if i >= len(slice) {
+			// This is a slice that we only partially allocated.
+			growSlice(v, &slice, length)
+		}
 		slice[i] = state.decodeUint() != 0
 	}
 	return true
@@ -90,6 +94,10 @@
 		if state.b.Len() == 0 {
 			errorf("decoding complex64 array or slice: length exceeds input size (%d elements)", length)
 		}
+		if i >= len(slice) {
+			// This is a slice that we only partially allocated.
+			growSlice(v, &slice, length)
+		}
 		real := float32FromBits(state.decodeUint(), ovfl)
 		imag := float32FromBits(state.decodeUint(), ovfl)
 		slice[i] = complex(float32(real), float32(imag))
@@ -115,6 +123,10 @@
 		if state.b.Len() == 0 {
 			errorf("decoding complex128 array or slice: length exceeds input size (%d elements)", length)
 		}
+		if i >= len(slice) {
+			// This is a slice that we only partially allocated.
+			growSlice(v, &slice, length)
+		}
 		real := float64FromBits(state.decodeUint())
 		imag := float64FromBits(state.decodeUint())
 		slice[i] = complex(real, imag)
@@ -140,6 +152,10 @@
 		if state.b.Len() == 0 {
 			errorf("decoding float32 array or slice: length exceeds input size (%d elements)", length)
 		}
+		if i >= len(slice) {
+			// This is a slice that we only partially allocated.
+			growSlice(v, &slice, length)
+		}
 		slice[i] = float32(float32FromBits(state.decodeUint(), ovfl))
 	}
 	return true
@@ -163,6 +179,10 @@
 		if state.b.Len() == 0 {
 			errorf("decoding float64 array or slice: length exceeds input size (%d elements)", length)
 		}
+		if i >= len(slice) {
+			// This is a slice that we only partially allocated.
+			growSlice(v, &slice, length)
+		}
 		slice[i] = float64FromBits(state.decodeUint())
 	}
 	return true
@@ -186,6 +206,10 @@
 		if state.b.Len() == 0 {
 			errorf("decoding int array or slice: length exceeds input size (%d elements)", length)
 		}
+		if i >= len(slice) {
+			// This is a slice that we only partially allocated.
+			growSlice(v, &slice, length)
+		}
 		x := state.decodeInt()
 		// MinInt and MaxInt
 		if x < ^int64(^uint(0)>>1) || int64(^uint(0)>>1) < x {
@@ -214,6 +238,10 @@
 		if state.b.Len() == 0 {
 			errorf("decoding int16 array or slice: length exceeds input size (%d elements)", length)
 		}
+		if i >= len(slice) {
+			// This is a slice that we only partially allocated.
+			growSlice(v, &slice, length)
+		}
 		x := state.decodeInt()
 		if x < math.MinInt16 || math.MaxInt16 < x {
 			error_(ovfl)
@@ -241,6 +269,10 @@
 		if state.b.Len() == 0 {
 			errorf("decoding int32 array or slice: length exceeds input size (%d elements)", length)
 		}
+		if i >= len(slice) {
+			// This is a slice that we only partially allocated.
+			growSlice(v, &slice, length)
+		}
 		x := state.decodeInt()
 		if x < math.MinInt32 || math.MaxInt32 < x {
 			error_(ovfl)
@@ -268,6 +300,10 @@
 		if state.b.Len() == 0 {
 			errorf("decoding int64 array or slice: length exceeds input size (%d elements)", length)
 		}
+		if i >= len(slice) {
+			// This is a slice that we only partially allocated.
+			growSlice(v, &slice, length)
+		}
 		slice[i] = state.decodeInt()
 	}
 	return true
@@ -291,6 +327,10 @@
 		if state.b.Len() == 0 {
 			errorf("decoding int8 array or slice: length exceeds input size (%d elements)", length)
 		}
+		if i >= len(slice) {
+			// This is a slice that we only partially allocated.
+			growSlice(v, &slice, length)
+		}
 		x := state.decodeInt()
 		if x < math.MinInt8 || math.MaxInt8 < x {
 			error_(ovfl)
@@ -355,6 +395,10 @@
 		if state.b.Len() == 0 {
 			errorf("decoding uint array or slice: length exceeds input size (%d elements)", length)
 		}
+		if i >= len(slice) {
+			// This is a slice that we only partially allocated.
+			growSlice(v, &slice, length)
+		}
 		x := state.decodeUint()
 		/*TODO if math.MaxUint32 < x {
 			error_(ovfl)
@@ -382,6 +426,10 @@
 		if state.b.Len() == 0 {
 			errorf("decoding uint16 array or slice: length exceeds input size (%d elements)", length)
 		}
+		if i >= len(slice) {
+			// This is a slice that we only partially allocated.
+			growSlice(v, &slice, length)
+		}
 		x := state.decodeUint()
 		if math.MaxUint16 < x {
 			error_(ovfl)
@@ -409,6 +457,10 @@
 		if state.b.Len() == 0 {
 			errorf("decoding uint32 array or slice: length exceeds input size (%d elements)", length)
 		}
+		if i >= len(slice) {
+			// This is a slice that we only partially allocated.
+			growSlice(v, &slice, length)
+		}
 		x := state.decodeUint()
 		if math.MaxUint32 < x {
 			error_(ovfl)
@@ -436,6 +488,10 @@
 		if state.b.Len() == 0 {
 			errorf("decoding uint64 array or slice: length exceeds input size (%d elements)", length)
 		}
+		if i >= len(slice) {
+			// This is a slice that we only partially allocated.
+			growSlice(v, &slice, length)
+		}
 		slice[i] = state.decodeUint()
 	}
 	return true
@@ -459,6 +515,10 @@
 		if state.b.Len() == 0 {
 			errorf("decoding uintptr array or slice: length exceeds input size (%d elements)", length)
 		}
+		if i >= len(slice) {
+			// This is a slice that we only partially allocated.
+			growSlice(v, &slice, length)
+		}
 		x := state.decodeUint()
 		if uint64(^uintptr(0)) < x {
 			error_(ovfl)
@@ -467,3 +527,18 @@
 	}
 	return true
 }
+
+// growSlice is called for a slice that we only partially allocated,
+// to grow it up to length.
+func growSlice[E any](v reflect.Value, ps *[]E, length int) {
+	var zero E
+	s := *ps
+	s = append(s, zero)
+	cp := cap(s)
+	if cp > length {
+		cp = length
+	}
+	s = s[:cp]
+	v.Set(reflect.ValueOf(s))
+	*ps = s
+}
diff --git a/src/encoding/gob/decode.go b/src/encoding/gob/decode.go
index eea2924..f46a391 100644
--- a/src/encoding/gob/decode.go
+++ b/src/encoding/gob/decode.go
@@ -9,6 +9,7 @@
 import (
 	"encoding"
 	"errors"
+	"internal/saferio"
 	"io"
 	"math"
 	"math/bits"
@@ -57,17 +58,6 @@
 	d.offset += n
 }
 
-// Size grows the buffer to exactly n bytes, so d.Bytes() will
-// return a slice of length n. Existing data is first discarded.
-func (d *decBuffer) Size(n int) {
-	d.Reset()
-	if cap(d.data) < n {
-		d.data = make([]byte, n)
-	} else {
-		d.data = d.data[0:n]
-	}
-}
-
 func (d *decBuffer) ReadByte() (byte, error) {
 	if d.offset >= len(d.data) {
 		return 0, io.EOF
@@ -85,6 +75,12 @@
 	return d.data[d.offset:]
 }
 
+// SetBytes sets the buffer to the bytes, discarding any existing data.
+func (d *decBuffer) SetBytes(data []byte) {
+	d.data = data
+	d.offset = 0
+}
+
 func (d *decBuffer) Reset() {
 	d.data = d.data[0:0]
 	d.offset = 0
@@ -374,12 +370,40 @@
 		errorf("bad %s slice length: %d", value.Type(), n)
 	}
 	if value.Cap() < n {
-		value.Set(reflect.MakeSlice(value.Type(), n, n))
+		safe := saferio.SliceCap((*byte)(nil), uint64(n))
+		if safe < 0 {
+			errorf("%s slice too big: %d elements", value.Type(), n)
+		}
+		value.Set(reflect.MakeSlice(value.Type(), safe, safe))
+		ln := safe
+		i := 0
+		for i < n {
+			if i >= ln {
+				// We didn't allocate the entire slice,
+				// due to using saferio.SliceCap.
+				// Append a value to grow the slice.
+				// The slice is full, so this should
+				// bump up the capacity.
+				value.Set(reflect.Append(value, reflect.Zero(value.Type().Elem())))
+			}
+			// Copy into s up to the capacity or n,
+			// whichever is less.
+			ln = value.Cap()
+			if ln > n {
+				ln = n
+			}
+			value.SetLen(ln)
+			sub := value.Slice(i, ln)
+			if _, err := state.b.Read(sub.Bytes()); err != nil {
+				errorf("error decoding []byte at %d: %s", err, i)
+			}
+			i = ln
+		}
 	} else {
 		value.SetLen(n)
-	}
-	if _, err := state.b.Read(value.Bytes()); err != nil {
-		errorf("error decoding []byte: %s", err)
+		if _, err := state.b.Read(value.Bytes()); err != nil {
+			errorf("error decoding []byte: %s", err)
+		}
 	}
 }
 
@@ -454,11 +478,10 @@
 		if delta == 0 { // struct terminator is zero delta fieldnum
 			break
 		}
-		fieldnum := state.fieldnum + delta
-		if fieldnum >= len(engine.instr) {
+		if state.fieldnum >= len(engine.instr)-delta { // subtract to compare without overflow
 			error_(errRange)
-			break
 		}
+		fieldnum := state.fieldnum + delta
 		instr := &engine.instr[fieldnum]
 		var field reflect.Value
 		if instr.index != nil {
@@ -519,10 +542,22 @@
 	}
 	instr := &decInstr{elemOp, 0, nil, ovfl}
 	isPtr := value.Type().Elem().Kind() == reflect.Pointer
+	ln := value.Len()
 	for i := 0; i < length; i++ {
 		if state.b.Len() == 0 {
 			errorf("decoding array or slice: length exceeds input size (%d elements)", length)
 		}
+		if i >= ln {
+			// This is a slice that we only partially allocated.
+			// Grow it using append, up to length.
+			value.Set(reflect.Append(value, reflect.Zero(value.Type().Elem())))
+			cp := value.Cap()
+			if cp > length {
+				cp = length
+			}
+			value.SetLen(cp)
+			ln = cp
+		}
 		v := value.Index(i)
 		if isPtr {
 			v = decAlloc(v)
@@ -623,7 +658,11 @@
 		errorf("%s slice too big: %d elements of %d bytes", typ.Elem(), u, size)
 	}
 	if value.Cap() < n {
-		value.Set(reflect.MakeSlice(typ, n, n))
+		safe := saferio.SliceCap(reflect.Zero(reflect.PtrTo(typ.Elem())).Interface(), uint64(n))
+		if safe < 0 {
+			errorf("%s slice too big: %d elements of %d bytes", typ.Elem(), u, size)
+		}
+		value.Set(reflect.MakeSlice(typ, safe, safe))
 	} else {
 		value.SetLen(n)
 	}
@@ -1228,9 +1267,14 @@
 	}
 }
 
+const (
+	intBits     = 32 << (^uint(0) >> 63)
+	uintptrBits = 32 << (^uintptr(0) >> 63)
+)
+
 func init() {
 	var iop, uop decOp
-	switch reflect.TypeOf(int(0)).Bits() {
+	switch intBits {
 	case 32:
 		iop = decInt32
 		uop = decUint32
@@ -1244,7 +1288,7 @@
 	decOpTable[reflect.Uint] = uop
 
 	// Finally uintptr
-	switch reflect.TypeOf(uintptr(0)).Bits() {
+	switch uintptrBits {
 	case 32:
 		uop = decUint32
 	case 64:
diff --git a/src/encoding/gob/decoder.go b/src/encoding/gob/decoder.go
index 9c4257e..5b77adc 100644
--- a/src/encoding/gob/decoder.go
+++ b/src/encoding/gob/decoder.go
@@ -7,6 +7,7 @@
 import (
 	"bufio"
 	"errors"
+	"internal/saferio"
 	"io"
 	"reflect"
 	"sync"
@@ -98,8 +99,9 @@
 		panic("non-empty decoder buffer")
 	}
 	// Read the data
-	dec.buf.Size(nbytes)
-	_, dec.err = io.ReadFull(dec.r, dec.buf.Bytes())
+	var buf []byte
+	buf, dec.err = saferio.ReadData(dec.r, uint64(nbytes))
+	dec.buf.SetBytes(buf)
 	if dec.err == io.EOF {
 		dec.err = io.ErrUnexpectedEOF
 	}
diff --git a/src/encoding/gob/doc.go b/src/encoding/gob/doc.go
index 306d395..15473f1 100644
--- a/src/encoding/gob/doc.go
+++ b/src/encoding/gob/doc.go
@@ -276,6 +276,14 @@
 
 See "Gobs of data" for a design discussion of the gob wire format:
 https://blog.golang.org/gobs-of-data
+
+# Security
+
+This package is not designed to be hardened against adversarial inputs, and is
+outside the scope of https://go.dev/security/policy. In particular, the Decoder
+does only basic sanity checking on decoded input sizes, and its limits are not
+configurable. Care should be taken when decoding gob data from untrusted
+sources, which may consume significant resources.
 */
 package gob
 
diff --git a/src/encoding/gob/encode.go b/src/encoding/gob/encode.go
index 548d614..3843034 100644
--- a/src/encoding/gob/encode.go
+++ b/src/encoding/gob/encode.go
@@ -577,7 +577,7 @@
 			op = func(i *encInstr, state *encoderState, sv reflect.Value) {
 				state.update(i)
 				// indirect through info to delay evaluation for recursive structs
-				enc := info.encoder.Load().(*encEngine)
+				enc := info.encoder.Load()
 				state.enc.encodeStruct(state.b, enc, sv)
 			}
 		case reflect.Interface:
@@ -661,8 +661,8 @@
 	if err != nil {
 		error_(err)
 	}
-	enc, ok := info.encoder.Load().(*encEngine)
-	if !ok {
+	enc := info.encoder.Load()
+	if enc == nil {
 		enc = buildEncEngine(info, ut, building)
 	}
 	return enc
@@ -675,8 +675,8 @@
 	}
 	info.encInit.Lock()
 	defer info.encInit.Unlock()
-	enc, ok := info.encoder.Load().(*encEngine)
-	if !ok {
+	enc := info.encoder.Load()
+	if enc == nil {
 		if building == nil {
 			building = make(map[*typeInfo]bool)
 		}
diff --git a/src/encoding/gob/encoder_test.go b/src/encoding/gob/encoder_test.go
index 6934841..484be43 100644
--- a/src/encoding/gob/encoder_test.go
+++ b/src/encoding/gob/encoder_test.go
@@ -1265,3 +1265,16 @@
 		}
 	}
 }
+
+func TestDecoderOverflow(t *testing.T) {
+	// Issue 55337.
+	dec := NewDecoder(bytes.NewReader([]byte{
+		0x12, 0xff, 0xff, 0x2, 0x2, 0x20, 0x0, 0xf8, 0x7f, 0xff, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x20, 0x20, 0x20, 0x20,
+	}))
+	var r interface{}
+	err := dec.Decode(r)
+	if err == nil {
+		t.Fatalf("expected an error")
+	}
+}
diff --git a/src/encoding/gob/error.go b/src/encoding/gob/error.go
index 3c9515b..9c614e3 100644
--- a/src/encoding/gob/error.go
+++ b/src/encoding/gob/error.go
@@ -24,7 +24,7 @@
 	error_(fmt.Errorf("gob: "+format, args...))
 }
 
-// error wraps the argument error and uses it as the argument to panic.
+// error_ wraps the argument error and uses it as the argument to panic.
 func error_(err error) {
 	panic(gobError{err})
 }
diff --git a/src/encoding/gob/type.go b/src/encoding/gob/type.go
index 6e2c724..3114cb0 100644
--- a/src/encoding/gob/type.go
+++ b/src/encoding/gob/type.go
@@ -38,7 +38,7 @@
 
 var userTypeCache sync.Map // map[reflect.Type]*userTypeInfo
 
-// validType returns, and saves, the information associated with user-provided type rt.
+// validUserType returns, and saves, the information associated with user-provided type rt.
 // If the user type is not valid, err will be non-nil. To be used when the error handler
 // is not set up.
 func validUserType(rt reflect.Type) (*userTypeInfo, error) {
@@ -672,8 +672,8 @@
 
 type typeInfo struct {
 	id      typeId
-	encInit sync.Mutex   // protects creation of encoder
-	encoder atomic.Value // *encEngine
+	encInit sync.Mutex // protects creation of encoder
+	encoder atomic.Pointer[encEngine]
 	wire    *wireType
 }
 
diff --git a/src/encoding/hex/hex_test.go b/src/encoding/hex/hex_test.go
index 7593e20..a820fe7 100644
--- a/src/encoding/hex/hex_test.go
+++ b/src/encoding/hex/hex_test.go
@@ -188,7 +188,7 @@
 }
 
 func TestDumper_doubleclose(t *testing.T) {
-	var out bytes.Buffer
+	var out strings.Builder
 	dumper := Dumper(&out)
 
 	dumper.Write([]byte(`gopher`))
@@ -204,7 +204,7 @@
 }
 
 func TestDumper_earlyclose(t *testing.T) {
-	var out bytes.Buffer
+	var out strings.Builder
 	dumper := Dumper(&out)
 
 	dumper.Close()
diff --git a/src/encoding/json/bench_test.go b/src/encoding/json/bench_test.go
index 9560914..d3af0dc 100644
--- a/src/encoding/json/bench_test.go
+++ b/src/encoding/json/bench_test.go
@@ -18,6 +18,7 @@
 	"io"
 	"os"
 	"reflect"
+	"regexp"
 	"runtime"
 	"strings"
 	"sync"
@@ -99,6 +100,36 @@
 	b.SetBytes(int64(len(codeJSON)))
 }
 
+func BenchmarkCodeEncoderError(b *testing.B) {
+	b.ReportAllocs()
+	if codeJSON == nil {
+		b.StopTimer()
+		codeInit()
+		b.StartTimer()
+	}
+
+	// Trigger an error in Marshal with cyclic data.
+	type Dummy struct {
+		Name string
+		Next *Dummy
+	}
+	dummy := Dummy{Name: "Dummy"}
+	dummy.Next = &dummy
+
+	b.RunParallel(func(pb *testing.PB) {
+		enc := NewEncoder(io.Discard)
+		for pb.Next() {
+			if err := enc.Encode(&codeStruct); err != nil {
+				b.Fatal("Encode:", err)
+			}
+			if _, err := Marshal(dummy); err == nil {
+				b.Fatal("expect an error here")
+			}
+		}
+	})
+	b.SetBytes(int64(len(codeJSON)))
+}
+
 func BenchmarkCodeMarshal(b *testing.B) {
 	b.ReportAllocs()
 	if codeJSON == nil {
@@ -116,6 +147,35 @@
 	b.SetBytes(int64(len(codeJSON)))
 }
 
+func BenchmarkCodeMarshalError(b *testing.B) {
+	b.ReportAllocs()
+	if codeJSON == nil {
+		b.StopTimer()
+		codeInit()
+		b.StartTimer()
+	}
+
+	// Trigger an error in Marshal with cyclic data.
+	type Dummy struct {
+		Name string
+		Next *Dummy
+	}
+	dummy := Dummy{Name: "Dummy"}
+	dummy.Next = &dummy
+
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			if _, err := Marshal(&codeStruct); err != nil {
+				b.Fatal("Marshal:", err)
+			}
+			if _, err := Marshal(dummy); err == nil {
+				b.Fatal("expect an error here")
+			}
+		}
+	})
+	b.SetBytes(int64(len(codeJSON)))
+}
+
 func benchMarshalBytes(n int) func(*testing.B) {
 	sample := []byte("hello world")
 	// Use a struct pointer, to avoid an allocation when passing it as an
@@ -134,6 +194,36 @@
 	}
 }
 
+func benchMarshalBytesError(n int) func(*testing.B) {
+	sample := []byte("hello world")
+	// Use a struct pointer, to avoid an allocation when passing it as an
+	// interface parameter to Marshal.
+	v := &struct {
+		Bytes []byte
+	}{
+		bytes.Repeat(sample, (n/len(sample))+1)[:n],
+	}
+
+	// Trigger an error in Marshal with cyclic data.
+	type Dummy struct {
+		Name string
+		Next *Dummy
+	}
+	dummy := Dummy{Name: "Dummy"}
+	dummy.Next = &dummy
+
+	return func(b *testing.B) {
+		for i := 0; i < b.N; i++ {
+			if _, err := Marshal(v); err != nil {
+				b.Fatal("Marshal:", err)
+			}
+			if _, err := Marshal(dummy); err == nil {
+				b.Fatal("expect an error here")
+			}
+		}
+	}
+}
+
 func BenchmarkMarshalBytes(b *testing.B) {
 	b.ReportAllocs()
 	// 32 fits within encodeState.scratch.
@@ -145,6 +235,17 @@
 	b.Run("4096", benchMarshalBytes(4096))
 }
 
+func BenchmarkMarshalBytesError(b *testing.B) {
+	b.ReportAllocs()
+	// 32 fits within encodeState.scratch.
+	b.Run("32", benchMarshalBytesError(32))
+	// 256 doesn't fit in encodeState.scratch, but is small enough to
+	// allocate and avoid the slower base64.NewEncoder.
+	b.Run("256", benchMarshalBytesError(256))
+	// 4096 is large enough that we want to avoid allocating for it.
+	b.Run("4096", benchMarshalBytesError(4096))
+}
+
 func BenchmarkCodeDecoder(b *testing.B) {
 	b.ReportAllocs()
 	if codeJSON == nil {
@@ -408,3 +509,33 @@
 		}
 	})
 }
+
+func BenchmarkEncoderEncode(b *testing.B) {
+	b.ReportAllocs()
+	type T struct {
+		X, Y string
+	}
+	v := &T{"foo", "bar"}
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			if err := NewEncoder(io.Discard).Encode(v); err != nil {
+				b.Fatal(err)
+			}
+		}
+	})
+}
+
+func BenchmarkNumberIsValid(b *testing.B) {
+	s := "-61657.61667E+61673"
+	for i := 0; i < b.N; i++ {
+		isValidNumber(s)
+	}
+}
+
+func BenchmarkNumberIsValidRegexp(b *testing.B) {
+	var jsonNumberRegexp = regexp.MustCompile(`^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$`)
+	s := "-61657.61667E+61673"
+	for i := 0; i < b.N; i++ {
+		jsonNumberRegexp.MatchString(s)
+	}
+}
diff --git a/src/encoding/json/encode.go b/src/encoding/json/encode.go
index 5b67251..9d59b0f 100644
--- a/src/encoding/json/encode.go
+++ b/src/encoding/json/encode.go
@@ -156,6 +156,7 @@
 // an error.
 func Marshal(v any) ([]byte, error) {
 	e := newEncodeState()
+	defer encodeStatePool.Put(e)
 
 	err := e.marshal(v, encOpts{escapeHTML: true})
 	if err != nil {
@@ -163,8 +164,6 @@
 	}
 	buf := append([]byte(nil), e.Bytes()...)
 
-	encodeStatePool.Put(e)
-
 	return buf, nil
 }
 
diff --git a/src/encoding/json/encode_test.go b/src/encoding/json/encode_test.go
index 0b021f0..c1b9ed2 100644
--- a/src/encoding/json/encode_test.go
+++ b/src/encoding/json/encode_test.go
@@ -12,6 +12,7 @@
 	"math"
 	"reflect"
 	"regexp"
+	"runtime/debug"
 	"strconv"
 	"testing"
 	"unicode"
@@ -760,6 +761,41 @@
 	}
 }
 
+func TestMarshalErrorAndReuseEncodeState(t *testing.T) {
+	// Disable the GC temporarily to prevent encodeState's in Pool being cleaned away during the test.
+	percent := debug.SetGCPercent(-1)
+	defer debug.SetGCPercent(percent)
+
+	// Trigger an error in Marshal with cyclic data.
+	type Dummy struct {
+		Name string
+		Next *Dummy
+	}
+	dummy := Dummy{Name: "Dummy"}
+	dummy.Next = &dummy
+	if b, err := Marshal(dummy); err == nil {
+		t.Errorf("Marshal(dummy) = %#q; want error", b)
+	}
+
+	type Data struct {
+		A string
+		I int
+	}
+	data := Data{A: "a", I: 1}
+	b, err := Marshal(data)
+	if err != nil {
+		t.Errorf("Marshal(%v) = %v", data, err)
+	}
+
+	var data2 Data
+	if err := Unmarshal(b, &data2); err != nil {
+		t.Errorf("Unmarshal(%v) = %v", data2, err)
+	}
+	if data2 != data {
+		t.Errorf("expect: %v, but get: %v", data, data2)
+	}
+}
+
 func TestHTMLEscape(t *testing.T) {
 	var b, want bytes.Buffer
 	m := `{"M":"<html>foo &` + "\xe2\x80\xa8 \xe2\x80\xa9" + `</html>"}`
diff --git a/src/encoding/json/fold.go b/src/encoding/json/fold.go
index ab249b2..0f9b09d 100644
--- a/src/encoding/json/fold.go
+++ b/src/encoding/json/fold.go
@@ -97,10 +97,7 @@
 		t = t[size:]
 
 	}
-	if len(t) > 0 {
-		return false
-	}
-	return true
+	return len(t) == 0
 }
 
 // asciiEqualFold is a specialization of bytes.EqualFold for use when
diff --git a/src/encoding/json/fold_test.go b/src/encoding/json/fold_test.go
index 9fb9464..4daa359 100644
--- a/src/encoding/json/fold_test.go
+++ b/src/encoding/json/fold_test.go
@@ -52,9 +52,7 @@
 }
 
 func TestFoldAgainstUnicode(t *testing.T) {
-	const bufSize = 5
-	buf1 := make([]byte, 0, bufSize)
-	buf2 := make([]byte, 0, bufSize)
+	var buf1, buf2 []byte
 	var runes []rune
 	for i := 0x20; i <= 0x7f; i++ {
 		runes = append(runes, rune(i))
@@ -96,12 +94,8 @@
 				continue
 			}
 			for _, r2 := range runes {
-				buf1 := append(buf1[:0], 'x')
-				buf2 := append(buf2[:0], 'x')
-				buf1 = buf1[:1+utf8.EncodeRune(buf1[1:bufSize], r)]
-				buf2 = buf2[:1+utf8.EncodeRune(buf2[1:bufSize], r2)]
-				buf1 = append(buf1, 'x')
-				buf2 = append(buf2, 'x')
+				buf1 = append(utf8.AppendRune(append(buf1[:0], 'x'), r), 'x')
+				buf2 = append(utf8.AppendRune(append(buf2[:0], 'x'), r2), 'x')
 				want := bytes.EqualFold(buf1, buf2)
 				if got := ff.fold(buf1, buf2); got != want {
 					t.Errorf("%s(%q, %q) = %v; want %v", ff.name, buf1, buf2, got, want)
diff --git a/src/encoding/json/number_test.go b/src/encoding/json/number_test.go
index cc67018..c82e6de 100644
--- a/src/encoding/json/number_test.go
+++ b/src/encoding/json/number_test.go
@@ -116,18 +116,3 @@
 		}
 	}
 }
-
-func BenchmarkNumberIsValid(b *testing.B) {
-	s := "-61657.61667E+61673"
-	for i := 0; i < b.N; i++ {
-		isValidNumber(s)
-	}
-}
-
-func BenchmarkNumberIsValidRegexp(b *testing.B) {
-	var jsonNumberRegexp = regexp.MustCompile(`^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$`)
-	s := "-61657.61667E+61673"
-	for i := 0; i < b.N; i++ {
-		jsonNumberRegexp.MatchString(s)
-	}
-}
diff --git a/src/encoding/json/scanner.go b/src/encoding/json/scanner.go
index 22fc692..4c43f5f 100644
--- a/src/encoding/json/scanner.go
+++ b/src/encoding/json/scanner.go
@@ -594,7 +594,7 @@
 	return scanError
 }
 
-// quoteChar formats c as a quoted character literal
+// quoteChar formats c as a quoted character literal.
 func quoteChar(c byte) string {
 	// special cases - different from quoted strings
 	if c == '\'' {
diff --git a/src/encoding/json/stream.go b/src/encoding/json/stream.go
index b278ee4..1442ef2 100644
--- a/src/encoding/json/stream.go
+++ b/src/encoding/json/stream.go
@@ -202,7 +202,10 @@
 	if enc.err != nil {
 		return enc.err
 	}
+
 	e := newEncodeState()
+	defer encodeStatePool.Put(e)
+
 	err := e.marshal(v, encOpts{escapeHTML: enc.escapeHTML})
 	if err != nil {
 		return err
@@ -231,7 +234,6 @@
 	if _, err = enc.w.Write(b); err != nil {
 		enc.err = err
 	}
-	encodeStatePool.Put(e)
 	return err
 }
 
diff --git a/src/encoding/json/stream_test.go b/src/encoding/json/stream_test.go
index 0e156d9..97f9fbd 100644
--- a/src/encoding/json/stream_test.go
+++ b/src/encoding/json/stream_test.go
@@ -12,6 +12,7 @@
 	"net/http"
 	"net/http/httptest"
 	"reflect"
+	"runtime/debug"
 	"strings"
 	"testing"
 )
@@ -41,7 +42,7 @@
 
 func TestEncoder(t *testing.T) {
 	for i := 0; i <= len(streamTest); i++ {
-		var buf bytes.Buffer
+		var buf strings.Builder
 		enc := NewEncoder(&buf)
 		// Check that enc.SetIndent("", "") turns off indentation.
 		enc.SetIndent(">", ".")
@@ -59,6 +60,43 @@
 	}
 }
 
+func TestEncoderErrorAndReuseEncodeState(t *testing.T) {
+	// Disable the GC temporarily to prevent encodeState's in Pool being cleaned away during the test.
+	percent := debug.SetGCPercent(-1)
+	defer debug.SetGCPercent(percent)
+
+	// Trigger an error in Marshal with cyclic data.
+	type Dummy struct {
+		Name string
+		Next *Dummy
+	}
+	dummy := Dummy{Name: "Dummy"}
+	dummy.Next = &dummy
+
+	var buf bytes.Buffer
+	enc := NewEncoder(&buf)
+	if err := enc.Encode(dummy); err == nil {
+		t.Errorf("Encode(dummy) == nil; want error")
+	}
+
+	type Data struct {
+		A string
+		I int
+	}
+	data := Data{A: "a", I: 1}
+	if err := enc.Encode(data); err != nil {
+		t.Errorf("Marshal(%v) = %v", data, err)
+	}
+
+	var data2 Data
+	if err := Unmarshal(buf.Bytes(), &data2); err != nil {
+		t.Errorf("Unmarshal(%v) = %v", data2, err)
+	}
+	if data2 != data {
+		t.Errorf("expect: %v, but get: %v", data, data2)
+	}
+}
+
 var streamEncodedIndent = `0.1
 "hello"
 null
@@ -77,7 +115,7 @@
 `
 
 func TestEncoderIndent(t *testing.T) {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	enc := NewEncoder(&buf)
 	enc.SetIndent(">", ".")
 	for _, v := range streamTest {
@@ -147,7 +185,7 @@
 			`{"bar":"\"<html>foobar</html>\""}`,
 		},
 	} {
-		var buf bytes.Buffer
+		var buf strings.Builder
 		enc := NewEncoder(&buf)
 		if err := enc.Encode(tt.v); err != nil {
 			t.Errorf("Encode(%s): %s", tt.name, err)
@@ -309,21 +347,6 @@
 	}
 }
 
-func BenchmarkEncoderEncode(b *testing.B) {
-	b.ReportAllocs()
-	type T struct {
-		X, Y string
-	}
-	v := &T{"foo", "bar"}
-	b.RunParallel(func(pb *testing.PB) {
-		for pb.Next() {
-			if err := NewEncoder(io.Discard).Encode(v); err != nil {
-				b.Fatal(err)
-			}
-		}
-	})
-}
-
 type tokenStreamCase struct {
 	json      string
 	expTokens []any
diff --git a/src/encoding/pem/pem_test.go b/src/encoding/pem/pem_test.go
index c94b5ca..56a7754 100644
--- a/src/encoding/pem/pem_test.go
+++ b/src/encoding/pem/pem_test.go
@@ -192,7 +192,7 @@
 
 func TestLineBreaker(t *testing.T) {
 	for i, test := range lineBreakerTests {
-		buf := new(bytes.Buffer)
+		buf := new(strings.Builder)
 		var breaker lineBreaker
 		breaker.out = buf
 		_, err := breaker.Write([]byte(test.in))
@@ -206,13 +206,13 @@
 			continue
 		}
 
-		if string(buf.Bytes()) != test.out {
-			t.Errorf("#%d: got:%s want:%s", i, string(buf.Bytes()), test.out)
+		if got := buf.String(); got != test.out {
+			t.Errorf("#%d: got:%s want:%s", i, got, test.out)
 		}
 	}
 
 	for i, test := range lineBreakerTests {
-		buf := new(bytes.Buffer)
+		buf := new(strings.Builder)
 		var breaker lineBreaker
 		breaker.out = buf
 
@@ -229,8 +229,8 @@
 			continue
 		}
 
-		if string(buf.Bytes()) != test.out {
-			t.Errorf("#%d: (byte by byte) got:%s want:%s", i, string(buf.Bytes()), test.out)
+		if got := buf.String(); got != test.out {
+			t.Errorf("#%d: (byte by byte) got:%s want:%s", i, got, test.out)
 		}
 	}
 }
diff --git a/src/encoding/xml/marshal.go b/src/encoding/xml/marshal.go
index 01f673a..07b6042 100644
--- a/src/encoding/xml/marshal.go
+++ b/src/encoding/xml/marshal.go
@@ -8,6 +8,7 @@
 	"bufio"
 	"bytes"
 	"encoding"
+	"errors"
 	"fmt"
 	"io"
 	"reflect"
@@ -78,7 +79,11 @@
 // Marshal will return an error if asked to marshal a channel, function, or map.
 func Marshal(v any) ([]byte, error) {
 	var b bytes.Buffer
-	if err := NewEncoder(&b).Encode(v); err != nil {
+	enc := NewEncoder(&b)
+	if err := enc.Encode(v); err != nil {
+		return nil, err
+	}
+	if err := enc.Close(); err != nil {
 		return nil, err
 	}
 	return b.Bytes(), nil
@@ -129,6 +134,9 @@
 	if err := enc.Encode(v); err != nil {
 		return nil, err
 	}
+	if err := enc.Close(); err != nil {
+		return nil, err
+	}
 	return b.Bytes(), nil
 }
 
@@ -139,7 +147,7 @@
 
 // NewEncoder returns a new encoder that writes to w.
 func NewEncoder(w io.Writer) *Encoder {
-	e := &Encoder{printer{Writer: bufio.NewWriter(w)}}
+	e := &Encoder{printer{w: bufio.NewWriter(w)}}
 	e.p.encoder = e
 	return e
 }
@@ -163,7 +171,7 @@
 	if err != nil {
 		return err
 	}
-	return enc.p.Flush()
+	return enc.p.w.Flush()
 }
 
 // EncodeElement writes the XML encoding of v to the stream,
@@ -178,7 +186,7 @@
 	if err != nil {
 		return err
 	}
-	return enc.p.Flush()
+	return enc.p.w.Flush()
 }
 
 var (
@@ -224,7 +232,7 @@
 	case ProcInst:
 		// First token to be encoded which is also a ProcInst with target of xml
 		// is the xml declaration. The only ProcInst where target of xml is allowed.
-		if t.Target == "xml" && p.Buffered() != 0 {
+		if t.Target == "xml" && p.w.Buffered() != 0 {
 			return fmt.Errorf("xml: EncodeToken of ProcInst xml target only valid for xml declaration, first token encoded")
 		}
 		if !isNameString(t.Target) {
@@ -297,11 +305,18 @@
 // Flush flushes any buffered XML to the underlying writer.
 // See the EncodeToken documentation for details about when it is necessary.
 func (enc *Encoder) Flush() error {
-	return enc.p.Flush()
+	return enc.p.w.Flush()
+}
+
+// Close the Encoder, indicating that no more data will be written. It flushes
+// any buffered XML to the underlying writer and returns an error if the
+// written XML is invalid (e.g. by containing unclosed elements).
+func (enc *Encoder) Close() error {
+	return enc.p.Close()
 }
 
 type printer struct {
-	*bufio.Writer
+	w          *bufio.Writer
 	encoder    *Encoder
 	seq        int
 	indent     string
@@ -313,6 +328,8 @@
 	attrPrefix map[string]string // map name space -> prefix
 	prefixes   []string
 	tags       []Name
+	closed     bool
+	err        error
 }
 
 // createAttrPrefix finds the name space prefix attribute to use for the given name space,
@@ -961,6 +978,56 @@
 	return p.cachedWriteError()
 }
 
+// Write implements io.Writer
+func (p *printer) Write(b []byte) (n int, err error) {
+	if p.closed && p.err == nil {
+		p.err = errors.New("use of closed Encoder")
+	}
+	if p.err == nil {
+		n, p.err = p.w.Write(b)
+	}
+	return n, p.err
+}
+
+// WriteString implements io.StringWriter
+func (p *printer) WriteString(s string) (n int, err error) {
+	if p.closed && p.err == nil {
+		p.err = errors.New("use of closed Encoder")
+	}
+	if p.err == nil {
+		n, p.err = p.w.WriteString(s)
+	}
+	return n, p.err
+}
+
+// WriteByte implements io.ByteWriter
+func (p *printer) WriteByte(c byte) error {
+	if p.closed && p.err == nil {
+		p.err = errors.New("use of closed Encoder")
+	}
+	if p.err == nil {
+		p.err = p.w.WriteByte(c)
+	}
+	return p.err
+}
+
+// Close the Encoder, indicating that no more data will be written. It flushes
+// any buffered XML to the underlying writer and returns an error if the
+// written XML is invalid (e.g. by containing unclosed elements).
+func (p *printer) Close() error {
+	if p.closed {
+		return nil
+	}
+	p.closed = true
+	if err := p.w.Flush(); err != nil {
+		return err
+	}
+	if len(p.tags) > 0 {
+		return fmt.Errorf("unclosed tag <%s>", p.tags[len(p.tags)-1].Local)
+	}
+	return nil
+}
+
 // return the bufio Writer's cached write error
 func (p *printer) cachedWriteError() error {
 	_, err := p.Write(nil)
diff --git a/src/encoding/xml/marshal_test.go b/src/encoding/xml/marshal_test.go
index 3fe7e2d..f6bcc7f 100644
--- a/src/encoding/xml/marshal_test.go
+++ b/src/encoding/xml/marshal_test.go
@@ -1894,13 +1894,13 @@
 }
 
 func TestMarshalFlush(t *testing.T) {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	enc := NewEncoder(&buf)
 	if err := enc.EncodeToken(CharData("hello world")); err != nil {
 		t.Fatalf("enc.EncodeToken: %v", err)
 	}
 	if buf.Len() > 0 {
-		t.Fatalf("enc.EncodeToken caused actual write: %q", buf.Bytes())
+		t.Fatalf("enc.EncodeToken caused actual write: %q", buf.String())
 	}
 	if err := enc.Flush(); err != nil {
 		t.Fatalf("enc.Flush: %v", err)
@@ -2317,7 +2317,7 @@
 func TestEncodeToken(t *testing.T) {
 loop:
 	for i, tt := range encodeTokenTests {
-		var buf bytes.Buffer
+		var buf strings.Builder
 		enc := NewEncoder(&buf)
 		var err error
 		for j, tok := range tt.toks {
@@ -2437,7 +2437,7 @@
 
 // Issue 11719. EncodeToken used to silently eat tokens with an invalid type.
 func TestSimpleUseOfEncodeToken(t *testing.T) {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	enc := NewEncoder(&buf)
 	if err := enc.EncodeToken(&StartElement{Name: Name{"", "object1"}}); err == nil {
 		t.Errorf("enc.EncodeToken: pointer type should be rejected")
@@ -2531,3 +2531,61 @@
 		t.Fatalf("unexpected unmarshal result, want %q but got %q", proofXml, anotherXML)
 	}
 }
+
+var closeTests = []struct {
+	desc string
+	toks []Token
+	want string
+	err  string
+}{{
+	desc: "unclosed start element",
+	toks: []Token{
+		StartElement{Name{"", "foo"}, nil},
+	},
+	want: `<foo>`,
+	err:  "unclosed tag <foo>",
+}, {
+	desc: "closed element",
+	toks: []Token{
+		StartElement{Name{"", "foo"}, nil},
+		EndElement{Name{"", "foo"}},
+	},
+	want: `<foo></foo>`,
+}, {
+	desc: "directive",
+	toks: []Token{
+		Directive("foo"),
+	},
+	want: `<!foo>`,
+}}
+
+func TestClose(t *testing.T) {
+	for _, tt := range closeTests {
+		tt := tt
+		t.Run(tt.desc, func(t *testing.T) {
+			var out strings.Builder
+			enc := NewEncoder(&out)
+			for j, tok := range tt.toks {
+				if err := enc.EncodeToken(tok); err != nil {
+					t.Fatalf("token #%d: %v", j, err)
+				}
+			}
+			err := enc.Close()
+			switch {
+			case tt.err != "" && err == nil:
+				t.Error(" expected error; got none")
+			case tt.err == "" && err != nil:
+				t.Errorf(" got error: %v", err)
+			case tt.err != "" && err != nil && tt.err != err.Error():
+				t.Errorf(" error mismatch; got %v, want %v", err, tt.err)
+			}
+			if got := out.String(); got != tt.want {
+				t.Errorf("\ngot  %v\nwant %v", got, tt.want)
+			}
+			t.Log(enc.p.closed)
+			if err := enc.EncodeToken(Directive("foo")); err == nil {
+				t.Errorf("unexpected success when encoding after Close")
+			}
+		})
+	}
+}
diff --git a/src/encoding/xml/read.go b/src/encoding/xml/read.go
index a6fb665..43be08e 100644
--- a/src/encoding/xml/read.go
+++ b/src/encoding/xml/read.go
@@ -10,6 +10,7 @@
 	"errors"
 	"fmt"
 	"reflect"
+	"runtime"
 	"strconv"
 	"strings"
 )
@@ -308,14 +309,17 @@
 	textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
 )
 
-const maxUnmarshalDepth = 10000
+const (
+	maxUnmarshalDepth     = 10000
+	maxUnmarshalDepthWasm = 5000 // go.dev/issue/56498
+)
 
-var errExeceededMaxUnmarshalDepth = errors.New("exceeded max depth")
+var errUnmarshalDepth = errors.New("exceeded max depth")
 
 // Unmarshal a single XML element into val.
 func (d *Decoder) unmarshal(val reflect.Value, start *StartElement, depth int) error {
-	if depth >= maxUnmarshalDepth {
-		return errExeceededMaxUnmarshalDepth
+	if depth >= maxUnmarshalDepth || runtime.GOARCH == "wasm" && depth >= maxUnmarshalDepthWasm {
+		return errUnmarshalDepth
 	}
 	// Find start element if we need it.
 	if start == nil {
@@ -533,7 +537,7 @@
 			consumed := false
 			if sv.IsValid() {
 				// unmarshalPath can call unmarshal, so we need to pass the depth through so that
-				// we can continue to enforce the maximum recusion limit.
+				// we can continue to enforce the maximum recursion limit.
 				consumed, err = d.unmarshalPath(tinfo, sv, nil, &t, depth)
 				if err != nil {
 					return err
diff --git a/src/encoding/xml/read_test.go b/src/encoding/xml/read_test.go
index 35385c6..3e85fca 100644
--- a/src/encoding/xml/read_test.go
+++ b/src/encoding/xml/read_test.go
@@ -9,6 +9,7 @@
 	"errors"
 	"io"
 	"reflect"
+	"runtime"
 	"strings"
 	"testing"
 	"time"
@@ -1105,13 +1106,13 @@
 	err := Unmarshal(bytes.Repeat([]byte("<a>"), maxUnmarshalDepth+1), &n)
 	if err == nil {
 		t.Fatal("Unmarshal did not fail")
-	} else if !errors.Is(err, errExeceededMaxUnmarshalDepth) {
-		t.Fatalf("Unmarshal unexpected error: got %q, want %q", err, errExeceededMaxUnmarshalDepth)
+	} else if !errors.Is(err, errUnmarshalDepth) {
+		t.Fatalf("Unmarshal unexpected error: got %q, want %q", err, errUnmarshalDepth)
 	}
 }
 
 func TestCVE202230633(t *testing.T) {
-	if testing.Short() {
+	if testing.Short() || runtime.GOARCH == "wasm" {
 		t.Skip("test requires significant memory")
 	}
 	defer func() {
diff --git a/src/encoding/xml/typeinfo.go b/src/encoding/xml/typeinfo.go
index 6b399b9..2f123fd 100644
--- a/src/encoding/xml/typeinfo.go
+++ b/src/encoding/xml/typeinfo.go
@@ -292,7 +292,7 @@
 				conflicts = append(conflicts, i)
 			}
 		} else {
-			if newf.name == oldf.name {
+			if newf.name == oldf.name && newf.xmlns == oldf.xmlns {
 				conflicts = append(conflicts, i)
 			}
 		}
diff --git a/src/encoding/xml/xml.go b/src/encoding/xml/xml.go
index 4a8c154..1f3084e 100644
--- a/src/encoding/xml/xml.go
+++ b/src/encoding/xml/xml.go
@@ -80,21 +80,15 @@
 // the characters they represent.
 type CharData []byte
 
-func makeCopy(b []byte) []byte {
-	b1 := make([]byte, len(b))
-	copy(b1, b)
-	return b1
-}
-
 // Copy creates a new copy of CharData.
-func (c CharData) Copy() CharData { return CharData(makeCopy(c)) }
+func (c CharData) Copy() CharData { return CharData(bytes.Clone(c)) }
 
 // A Comment represents an XML comment of the form <!--comment-->.
 // The bytes do not include the <!-- and --> comment markers.
 type Comment []byte
 
 // Copy creates a new copy of Comment.
-func (c Comment) Copy() Comment { return Comment(makeCopy(c)) }
+func (c Comment) Copy() Comment { return Comment(bytes.Clone(c)) }
 
 // A ProcInst represents an XML processing instruction of the form <?target inst?>
 type ProcInst struct {
@@ -104,7 +98,7 @@
 
 // Copy creates a new copy of ProcInst.
 func (p ProcInst) Copy() ProcInst {
-	p.Inst = makeCopy(p.Inst)
+	p.Inst = bytes.Clone(p.Inst)
 	return p
 }
 
@@ -113,7 +107,7 @@
 type Directive []byte
 
 // Copy creates a new copy of Directive.
-func (d Directive) Copy() Directive { return Directive(makeCopy(d)) }
+func (d Directive) Copy() Directive { return Directive(bytes.Clone(d)) }
 
 // CopyToken returns a copy of a Token.
 func CopyToken(t Token) Token {
@@ -320,15 +314,14 @@
 			}
 		}
 
+		d.pushElement(t1.Name)
 		d.translate(&t1.Name, true)
 		for i := range t1.Attr {
 			d.translate(&t1.Attr[i].Name, false)
 		}
-		d.pushElement(t1.Name)
 		t = t1
 
 	case EndElement:
-		d.translate(&t1.Name, true)
 		if !d.popElement(&t1) {
 			return nil, d.err
 		}
@@ -501,6 +494,8 @@
 		return false
 	}
 
+	d.translate(&t.Name, true)
+
 	// Pop stack until a Start or EOF is on the top, undoing the
 	// translations that were associated with the element we just closed.
 	for d.stk != nil && d.stk.kind != stkStart && d.stk.kind != stkEOF {
@@ -1100,7 +1095,7 @@
 
 			if haveText {
 				d.buf.Truncate(before)
-				d.buf.Write([]byte(text))
+				d.buf.WriteString(text)
 				b0, b1 = 0, 0
 				continue Input
 			}
@@ -1168,7 +1163,7 @@
 		return
 	}
 	if strings.Count(s, ":") > 1 {
-		name.Local = s
+		return name, false
 	} else if space, local, ok := strings.Cut(s, ":"); !ok || space == "" || local == "" {
 		name.Local = s
 	} else {
diff --git a/src/encoding/xml/xml_test.go b/src/encoding/xml/xml_test.go
index 8f0d97b..30fb94d 100644
--- a/src/encoding/xml/xml_test.go
+++ b/src/encoding/xml/xml_test.go
@@ -894,7 +894,7 @@
 	input := []byte("A \x00 terminated string.")
 	expected := "A \uFFFD terminated string."
 
-	buff := new(bytes.Buffer)
+	buff := new(strings.Builder)
 	if err := EscapeText(buff, input); err != nil {
 		t.Fatalf("have %v, want nil", err)
 	}
@@ -916,6 +916,96 @@
 	}
 }
 
+func TestIssue8535(t *testing.T) {
+
+	type ExampleConflict struct {
+		XMLName  Name   `xml:"example"`
+		Link     string `xml:"link"`
+		AtomLink string `xml:"http://www.w3.org/2005/Atom link"` // Same name in a different name space
+	}
+	testCase := `<example>
+			<title>Example</title>
+			<link>http://example.com/default</link> <!-- not assigned -->
+			<link>http://example.com/home</link> <!-- not assigned -->
+			<ns:link xmlns:ns="http://www.w3.org/2005/Atom">http://example.com/ns</ns:link>
+		</example>`
+
+	var dest ExampleConflict
+	d := NewDecoder(strings.NewReader(testCase))
+	if err := d.Decode(&dest); err != nil {
+		t.Fatal(err)
+	}
+}
+
+func TestEncodeXMLNS(t *testing.T) {
+	testCases := []struct {
+		f    func() ([]byte, error)
+		want string
+		ok   bool
+	}{
+		{encodeXMLNS1, `<Test xmlns="http://example.com/ns"><Body>hello world</Body></Test>`, true},
+		{encodeXMLNS2, `<Test><body xmlns="http://example.com/ns">hello world</body></Test>`, true},
+		{encodeXMLNS3, `<Test xmlns="http://example.com/ns"><Body>hello world</Body></Test>`, true},
+		{encodeXMLNS4, `<Test xmlns="http://example.com/ns"><Body>hello world</Body></Test>`, false},
+	}
+
+	for i, tc := range testCases {
+		if b, err := tc.f(); err == nil {
+			if got, want := string(b), tc.want; got != want {
+				t.Errorf("%d: got %s, want %s \n", i, got, want)
+			}
+		} else {
+			t.Errorf("%d: marshal failed with %s", i, err)
+		}
+	}
+}
+
+func encodeXMLNS1() ([]byte, error) {
+
+	type T struct {
+		XMLName Name   `xml:"Test"`
+		Ns      string `xml:"xmlns,attr"`
+		Body    string
+	}
+
+	s := &T{Ns: "http://example.com/ns", Body: "hello world"}
+	return Marshal(s)
+}
+
+func encodeXMLNS2() ([]byte, error) {
+
+	type Test struct {
+		Body string `xml:"http://example.com/ns body"`
+	}
+
+	s := &Test{Body: "hello world"}
+	return Marshal(s)
+}
+
+func encodeXMLNS3() ([]byte, error) {
+
+	type Test struct {
+		XMLName Name `xml:"http://example.com/ns Test"`
+		Body    string
+	}
+
+	//s := &Test{XMLName: Name{"http://example.com/ns",""}, Body: "hello world"} is unusable as the "-" is missing
+	// as documentation states
+	s := &Test{Body: "hello world"}
+	return Marshal(s)
+}
+
+func encodeXMLNS4() ([]byte, error) {
+
+	type Test struct {
+		Ns   string `xml:"xmlns,attr"`
+		Body string
+	}
+
+	s := &Test{Ns: "http://example.com/ns", Body: "hello world"}
+	return Marshal(s)
+}
+
 func TestIssue11405(t *testing.T) {
 	testCases := []string{
 		"<root>",
@@ -969,6 +1059,75 @@
 	}
 }
 
+func TestIssue20396(t *testing.T) {
+
+	var attrError = UnmarshalError("XML syntax error on line 1: expected attribute name in element")
+
+	testCases := []struct {
+		s       string
+		wantErr error
+	}{
+		{`<a:te:st xmlns:a="abcd"/>`, // Issue 20396
+			UnmarshalError("XML syntax error on line 1: expected element name after <")},
+		{`<a:te=st xmlns:a="abcd"/>`, attrError},
+		{`<a:te&st xmlns:a="abcd"/>`, attrError},
+		{`<a:test xmlns:a="abcd"/>`, nil},
+		{`<a:te:st xmlns:a="abcd">1</a:te:st>`,
+			UnmarshalError("XML syntax error on line 1: expected element name after <")},
+		{`<a:te=st xmlns:a="abcd">1</a:te=st>`, attrError},
+		{`<a:te&st xmlns:a="abcd">1</a:te&st>`, attrError},
+		{`<a:test xmlns:a="abcd">1</a:test>`, nil},
+	}
+
+	var dest string
+	for _, tc := range testCases {
+		if got, want := Unmarshal([]byte(tc.s), &dest), tc.wantErr; got != want {
+			if got == nil {
+				t.Errorf("%s: Unexpected success, want %v", tc.s, want)
+			} else if want == nil {
+				t.Errorf("%s: Unexpected error, got %v", tc.s, got)
+			} else if got.Error() != want.Error() {
+				t.Errorf("%s: got %v, want %v", tc.s, got, want)
+			}
+		}
+	}
+}
+
+func TestIssue20685(t *testing.T) {
+	testCases := []struct {
+		s  string
+		ok bool
+	}{
+		{`<x:book xmlns:x="abcd" xmlns:y="abcd"><unclosetag>one</x:book>`, false},
+		{`<x:book xmlns:x="abcd" xmlns:y="abcd">one</x:book>`, true},
+		{`<x:book xmlns:x="abcd" xmlns:y="abcd">one</y:book>`, false},
+		{`<x:book xmlns:y="abcd" xmlns:x="abcd">one</y:book>`, false},
+		{`<x:book xmlns:x="abcd">one</y:book>`, false},
+		{`<x:book>one</y:book>`, false},
+		{`<xbook>one</ybook>`, false},
+	}
+	for _, tc := range testCases {
+		d := NewDecoder(strings.NewReader(tc.s))
+		var err error
+		for {
+			_, err = d.Token()
+			if err != nil {
+				if err == io.EOF {
+					err = nil
+				}
+				break
+			}
+		}
+		if err != nil && tc.ok {
+			t.Errorf("%q: Closing tag with namespace : expected no error, got %s", tc.s, err)
+			continue
+		}
+		if err == nil && !tc.ok {
+			t.Errorf("%q: Closing tag with namespace : expected error, got nil", tc.s)
+		}
+	}
+}
+
 func tokenMap(mapping func(t Token) Token) func(TokenReader) TokenReader {
 	return func(src TokenReader) TokenReader {
 		return mapper{
@@ -1103,9 +1262,7 @@
 
 func TestRoundTrip(t *testing.T) {
 	tests := map[string]string{
-		"leading colon":          `<::Test ::foo="bar"><:::Hello></:::Hello><Hello></Hello></::Test>`,
 		"trailing colon":         `<foo abc:="x"></foo>`,
-		"double colon":           `<x:y:foo></x:y:foo>`,
 		"comments in directives": `<!ENTITY x<!<!-- c1 [ " -->--x --> > <e></e> <!DOCTYPE xxx [ x<!-- c2 " -->--x ]>`,
 	}
 	for name, input := range tests {
diff --git a/src/errors/errors.go b/src/errors/errors.go
index f2fabac..8436f81 100644
--- a/src/errors/errors.go
+++ b/src/errors/errors.go
@@ -6,26 +6,29 @@
 //
 // The New function creates errors whose only content is a text message.
 //
-// The Unwrap, Is and As functions work on errors that may wrap other errors.
-// An error wraps another error if its type has the method
+// An error e wraps another error if e's type has one of the methods
 //
 //	Unwrap() error
+//	Unwrap() []error
 //
-// If e.Unwrap() returns a non-nil error w, then we say that e wraps w.
+// If e.Unwrap() returns a non-nil error w or a slice containing w,
+// then we say that e wraps w. A nil error returned from e.Unwrap()
+// indicates that e does not wrap any error. It is invalid for an
+// Unwrap method to return an []error containing a nil error value.
 //
-// Unwrap unpacks wrapped errors. If its argument's type has an
-// Unwrap method, it calls the method once. Otherwise, it returns nil.
+// An easy way to create wrapped errors is to call fmt.Errorf and apply
+// the %w verb to the error argument:
 //
-// A simple way to create wrapped errors is to call fmt.Errorf and apply the %w verb
-// to the error argument:
+//	wrapsErr := fmt.Errorf("... %w ...", ..., err, ...)
 //
-//	errors.Unwrap(fmt.Errorf("... %w ...", ..., err, ...))
+// Successive unwrapping of an error creates a tree. The Is and As
+// functions inspect an error's tree by examining first the error
+// itself followed by the tree of each of its children in turn
+// (pre-order, depth-first traversal).
 //
-// returns err.
-//
-// Is unwraps its first argument sequentially looking for an error that matches the
-// second. It reports whether it finds a match. It should be used in preference to
-// simple equality checks:
+// Is examines the tree of its first argument looking for an error that
+// matches the second. It reports whether it finds a match. It should be
+// used in preference to simple equality checks:
 //
 //	if errors.Is(err, fs.ErrExist)
 //
@@ -35,7 +38,7 @@
 //
 // because the former will succeed if err wraps fs.ErrExist.
 //
-// As unwraps its first argument sequentially looking for an error that can be
+// As examines the tree of its first argument looking for an error that can be
 // assigned to its second argument, which must be a pointer. If it succeeds, it
 // performs the assignment and returns true. Otherwise, it returns false. The form
 //
diff --git a/src/errors/errors_test.go b/src/errors/errors_test.go
index cf4df90..8b93f53 100644
--- a/src/errors/errors_test.go
+++ b/src/errors/errors_test.go
@@ -51,3 +51,21 @@
 	}
 	// Output: user "bimmler" (id 17) not found
 }
+
+func ExampleJoin() {
+	err1 := errors.New("err1")
+	err2 := errors.New("err2")
+	err := errors.Join(err1, err2)
+	fmt.Println(err)
+	if errors.Is(err, err1) {
+		fmt.Println("err is err1")
+	}
+	if errors.Is(err, err2) {
+		fmt.Println("err is err2")
+	}
+	// Output:
+	// err1
+	// err2
+	// err is err1
+	// err is err2
+}
diff --git a/src/errors/join.go b/src/errors/join.go
new file mode 100644
index 0000000..dc5a716
--- /dev/null
+++ b/src/errors/join.go
@@ -0,0 +1,51 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package errors
+
+// Join returns an error that wraps the given errors.
+// Any nil error values are discarded.
+// Join returns nil if errs contains no non-nil values.
+// The error formats as the concatenation of the strings obtained
+// by calling the Error method of each element of errs, with a newline
+// between each string.
+func Join(errs ...error) error {
+	n := 0
+	for _, err := range errs {
+		if err != nil {
+			n++
+		}
+	}
+	if n == 0 {
+		return nil
+	}
+	e := &joinError{
+		errs: make([]error, 0, n),
+	}
+	for _, err := range errs {
+		if err != nil {
+			e.errs = append(e.errs, err)
+		}
+	}
+	return e
+}
+
+type joinError struct {
+	errs []error
+}
+
+func (e *joinError) Error() string {
+	var b []byte
+	for i, err := range e.errs {
+		if i > 0 {
+			b = append(b, '\n')
+		}
+		b = append(b, err.Error()...)
+	}
+	return string(b)
+}
+
+func (e *joinError) Unwrap() []error {
+	return e.errs
+}
diff --git a/src/errors/join_test.go b/src/errors/join_test.go
new file mode 100644
index 0000000..4828dc4
--- /dev/null
+++ b/src/errors/join_test.go
@@ -0,0 +1,72 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package errors_test
+
+import (
+	"errors"
+	"reflect"
+	"testing"
+)
+
+func TestJoinReturnsNil(t *testing.T) {
+	if err := errors.Join(); err != nil {
+		t.Errorf("errors.Join() = %v, want nil", err)
+	}
+	if err := errors.Join(nil); err != nil {
+		t.Errorf("errors.Join(nil) = %v, want nil", err)
+	}
+	if err := errors.Join(nil, nil); err != nil {
+		t.Errorf("errors.Join(nil, nil) = %v, want nil", err)
+	}
+}
+
+func TestJoin(t *testing.T) {
+	err1 := errors.New("err1")
+	err2 := errors.New("err2")
+	for _, test := range []struct {
+		errs []error
+		want []error
+	}{{
+		errs: []error{err1},
+		want: []error{err1},
+	}, {
+		errs: []error{err1, err2},
+		want: []error{err1, err2},
+	}, {
+		errs: []error{err1, nil, err2},
+		want: []error{err1, err2},
+	}} {
+		got := errors.Join(test.errs...).(interface{ Unwrap() []error }).Unwrap()
+		if !reflect.DeepEqual(got, test.want) {
+			t.Errorf("Join(%v) = %v; want %v", test.errs, got, test.want)
+		}
+		if len(got) != cap(got) {
+			t.Errorf("Join(%v) returns errors with len=%v, cap=%v; want len==cap", test.errs, len(got), cap(got))
+		}
+	}
+}
+
+func TestJoinErrorMethod(t *testing.T) {
+	err1 := errors.New("err1")
+	err2 := errors.New("err2")
+	for _, test := range []struct {
+		errs []error
+		want string
+	}{{
+		errs: []error{err1},
+		want: "err1",
+	}, {
+		errs: []error{err1, err2},
+		want: "err1\nerr2",
+	}, {
+		errs: []error{err1, nil, err2},
+		want: "err1\nerr2",
+	}} {
+		got := errors.Join(test.errs...).Error()
+		if got != test.want {
+			t.Errorf("Join(%v).Error() = %q; want %q", test.errs, got, test.want)
+		}
+	}
+}
diff --git a/src/errors/wrap.go b/src/errors/wrap.go
index 263ae16..a719655 100644
--- a/src/errors/wrap.go
+++ b/src/errors/wrap.go
@@ -11,6 +11,8 @@
 // Unwrap returns the result of calling the Unwrap method on err, if err's
 // type contains an Unwrap method returning error.
 // Otherwise, Unwrap returns nil.
+//
+// Unwrap returns nil if the Unwrap method returns []error.
 func Unwrap(err error) error {
 	u, ok := err.(interface {
 		Unwrap() error
@@ -21,10 +23,11 @@
 	return u.Unwrap()
 }
 
-// Is reports whether any error in err's chain matches target.
+// Is reports whether any error in err's tree matches target.
 //
-// The chain consists of err itself followed by the sequence of errors obtained by
-// repeatedly calling Unwrap.
+// The tree consists of err itself, followed by the errors obtained by repeatedly
+// calling Unwrap. When err wraps multiple errors, Is examines err followed by a
+// depth-first traversal of its children.
 //
 // An error is considered to match a target if it is equal to that target or if
 // it implements a method Is(error) bool such that Is(target) returns true.
@@ -50,20 +53,31 @@
 		if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(target) {
 			return true
 		}
-		// TODO: consider supporting target.Is(err). This would allow
-		// user-definable predicates, but also may allow for coping with sloppy
-		// APIs, thereby making it easier to get away with them.
-		if err = Unwrap(err); err == nil {
+		switch x := err.(type) {
+		case interface{ Unwrap() error }:
+			err = x.Unwrap()
+			if err == nil {
+				return false
+			}
+		case interface{ Unwrap() []error }:
+			for _, err := range x.Unwrap() {
+				if Is(err, target) {
+					return true
+				}
+			}
+			return false
+		default:
 			return false
 		}
 	}
 }
 
-// As finds the first error in err's chain that matches target, and if one is found, sets
+// As finds the first error in err's tree that matches target, and if one is found, sets
 // target to that error value and returns true. Otherwise, it returns false.
 //
-// The chain consists of err itself followed by the sequence of errors obtained by
-// repeatedly calling Unwrap.
+// The tree consists of err itself, followed by the errors obtained by repeatedly
+// calling Unwrap. When err wraps multiple errors, As examines err followed by a
+// depth-first traversal of its children.
 //
 // An error matches target if the error's concrete value is assignable to the value
 // pointed to by target, or if the error has a method As(interface{}) bool such that
@@ -76,6 +90,9 @@
 // As panics if target is not a non-nil pointer to either a type that implements
 // error, or to any interface type.
 func As(err error, target any) bool {
+	if err == nil {
+		return false
+	}
 	if target == nil {
 		panic("errors: target cannot be nil")
 	}
@@ -88,7 +105,7 @@
 	if targetType.Kind() != reflectlite.Interface && !targetType.Implements(errorType) {
 		panic("errors: *target must be interface or implement error")
 	}
-	for err != nil {
+	for {
 		if reflectlite.TypeOf(err).AssignableTo(targetType) {
 			val.Elem().Set(reflectlite.ValueOf(err))
 			return true
@@ -96,9 +113,23 @@
 		if x, ok := err.(interface{ As(any) bool }); ok && x.As(target) {
 			return true
 		}
-		err = Unwrap(err)
+		switch x := err.(type) {
+		case interface{ Unwrap() error }:
+			err = x.Unwrap()
+			if err == nil {
+				return false
+			}
+		case interface{ Unwrap() []error }:
+			for _, err := range x.Unwrap() {
+				if As(err, target) {
+					return true
+				}
+			}
+			return false
+		default:
+			return false
+		}
 	}
-	return false
 }
 
 var errorType = reflectlite.TypeOf((*error)(nil)).Elem()
diff --git a/src/errors/wrap_test.go b/src/errors/wrap_test.go
index eb8314b..9efbe45 100644
--- a/src/errors/wrap_test.go
+++ b/src/errors/wrap_test.go
@@ -47,6 +47,17 @@
 		{&errorUncomparable{}, &errorUncomparable{}, false},
 		{errorUncomparable{}, err1, false},
 		{&errorUncomparable{}, err1, false},
+		{multiErr{}, err1, false},
+		{multiErr{err1, err3}, err1, true},
+		{multiErr{err3, err1}, err1, true},
+		{multiErr{err1, err3}, errors.New("x"), false},
+		{multiErr{err3, errb}, errb, true},
+		{multiErr{err3, errb}, erra, true},
+		{multiErr{err3, errb}, err1, true},
+		{multiErr{errb, err3}, err1, true},
+		{multiErr{poser}, err1, true},
+		{multiErr{poser}, err3, true},
+		{multiErr{nil}, nil, false},
 	}
 	for _, tc := range testCases {
 		t.Run("", func(t *testing.T) {
@@ -148,6 +159,41 @@
 		&timeout,
 		true,
 		errF,
+	}, {
+		multiErr{},
+		&errT,
+		false,
+		nil,
+	}, {
+		multiErr{errors.New("a"), errorT{"T"}},
+		&errT,
+		true,
+		errorT{"T"},
+	}, {
+		multiErr{errorT{"T"}, errors.New("a")},
+		&errT,
+		true,
+		errorT{"T"},
+	}, {
+		multiErr{errorT{"a"}, errorT{"b"}},
+		&errT,
+		true,
+		errorT{"a"},
+	}, {
+		multiErr{multiErr{errors.New("a"), errorT{"a"}}, errorT{"b"}},
+		&errT,
+		true,
+		errorT{"a"},
+	}, {
+		multiErr{wrapped{"path error", errF}},
+		&timeout,
+		true,
+		errF,
+	}, {
+		multiErr{nil},
+		&errT,
+		false,
+		nil,
 	}}
 	for i, tc := range testCases {
 		name := fmt.Sprintf("%d:As(Errorf(..., %v), %v)", i, tc.err, tc.target)
@@ -223,9 +269,13 @@
 }
 
 func (e wrapped) Error() string { return e.msg }
-
 func (e wrapped) Unwrap() error { return e.err }
 
+type multiErr []error
+
+func (m multiErr) Error() string   { return "multiError" }
+func (m multiErr) Unwrap() []error { return []error(m) }
+
 type errorUncomparable struct {
 	f []string
 }
diff --git a/src/expvar/expvar.go b/src/expvar/expvar.go
index 08cd055..300d8c2 100644
--- a/src/expvar/expvar.go
+++ b/src/expvar/expvar.go
@@ -67,26 +67,26 @@
 
 // Float is a 64-bit float variable that satisfies the Var interface.
 type Float struct {
-	f uint64
+	f atomic.Uint64
 }
 
 func (v *Float) Value() float64 {
-	return math.Float64frombits(atomic.LoadUint64(&v.f))
+	return math.Float64frombits(v.f.Load())
 }
 
 func (v *Float) String() string {
 	return strconv.FormatFloat(
-		math.Float64frombits(atomic.LoadUint64(&v.f)), 'g', -1, 64)
+		math.Float64frombits(v.f.Load()), 'g', -1, 64)
 }
 
 // Add adds delta to v.
 func (v *Float) Add(delta float64) {
 	for {
-		cur := atomic.LoadUint64(&v.f)
+		cur := v.f.Load()
 		curVal := math.Float64frombits(cur)
 		nxtVal := curVal + delta
 		nxt := math.Float64bits(nxtVal)
-		if atomic.CompareAndSwapUint64(&v.f, cur, nxt) {
+		if v.f.CompareAndSwap(cur, nxt) {
 			return
 		}
 	}
@@ -94,7 +94,7 @@
 
 // Set sets v to value.
 func (v *Float) Set(value float64) {
-	atomic.StoreUint64(&v.f, math.Float64bits(value))
+	v.f.Store(math.Float64bits(value))
 }
 
 // Map is a string-to-Var map variable that satisfies the Var interface.
diff --git a/src/expvar/expvar_test.go b/src/expvar/expvar_test.go
index 552bae8..ee98b5e 100644
--- a/src/expvar/expvar_test.go
+++ b/src/expvar/expvar_test.go
@@ -87,8 +87,8 @@
 func TestFloat(t *testing.T) {
 	RemoveAll()
 	reqs := NewFloat("requests-float")
-	if reqs.f != 0.0 {
-		t.Errorf("reqs.f = %v, want 0", reqs.f)
+	if reqs.f.Load() != 0.0 {
+		t.Errorf("reqs.f = %v, want 0", reqs.f.Load())
 	}
 	if reqs != Get("requests-float").(*Float) {
 		t.Errorf("Get() failed.")
diff --git a/src/flag/example_test.go b/src/flag/example_test.go
index 04a0d20..088447d 100644
--- a/src/flag/example_test.go
+++ b/src/flag/example_test.go
@@ -78,6 +78,8 @@
 	// to enable the flag package to see the flags defined there, one must
 	// execute, typically at the start of main (not init!):
 	//	flag.Parse()
-	// We don't run it here because this is not a main function and
-	// the testing suite has already parsed the flags.
+	// We don't call it here because this code is a function called "Example"
+	// that is part of the testing suite for the package, which has already
+	// parsed the flags. When viewed at pkg.go.dev, however, the function is
+	// renamed to "main" and it could be run as a standalone example.
 }
diff --git a/src/flag/flag.go b/src/flag/flag.go
index 9abf8d7..ef3cf29 100644
--- a/src/flag/flag.go
+++ b/src/flag/flag.go
@@ -550,9 +550,11 @@
 	}
 	// No explicit name, so use type if we can find one.
 	name = "value"
-	switch flag.Value.(type) {
+	switch fv := flag.Value.(type) {
 	case boolFlag:
-		name = ""
+		if fv.IsBoolFlag() {
+			name = ""
+		}
 	case *durationValue:
 		name = "duration"
 	case *float64Value:
@@ -1054,9 +1056,9 @@
 			break
 		}
 	}
-	m := f.formal
-	flag, alreadythere := m[name] // BUG
-	if !alreadythere {
+
+	flag, ok := f.formal[name]
+	if !ok {
 		if name == "help" || name == "h" { // special case for nice help message.
 			f.usage()
 			return false, ErrHelp
diff --git a/src/flag/flag_test.go b/src/flag/flag_test.go
index ca6ba5d..1755168 100644
--- a/src/flag/flag_test.go
+++ b/src/flag/flag_test.go
@@ -356,9 +356,34 @@
 	}
 }
 
+func TestUserDefinedBoolUsage(t *testing.T) {
+	var flags FlagSet
+	flags.Init("test", ContinueOnError)
+	var buf bytes.Buffer
+	flags.SetOutput(&buf)
+	var b boolFlagVar
+	flags.Var(&b, "b", "X")
+	b.count = 0
+	// b.IsBoolFlag() will return true and usage will look boolean.
+	flags.PrintDefaults()
+	got := buf.String()
+	want := "  -b\tX\n"
+	if got != want {
+		t.Errorf("false: want %q; got %q", want, got)
+	}
+	b.count = 4
+	// b.IsBoolFlag() will return false and usage will look non-boolean.
+	flags.PrintDefaults()
+	got = buf.String()
+	want = "  -b\tX\n  -b value\n    \tX\n"
+	if got != want {
+		t.Errorf("false: want %q; got %q", want, got)
+	}
+}
+
 func TestSetOutput(t *testing.T) {
 	var flags FlagSet
-	var buf bytes.Buffer
+	var buf strings.Builder
 	flags.SetOutput(&buf)
 	flags.Init("test", ContinueOnError)
 	flags.Parse([]string{"-unknown"})
@@ -488,7 +513,7 @@
 
 func TestPrintDefaults(t *testing.T) {
 	fs := NewFlagSet("print defaults test", ContinueOnError)
-	var buf bytes.Buffer
+	var buf strings.Builder
 	fs.SetOutput(&buf)
 	fs.Bool("A", false, "for bootstrapping, allow 'any' type")
 	fs.Bool("Alongflagname", false, "disable bounds checking")
@@ -531,7 +556,7 @@
 // Issue 20998: Usage should respect CommandLine.output.
 func TestUsageOutput(t *testing.T) {
 	ResetForTesting(DefaultUsage)
-	var buf bytes.Buffer
+	var buf strings.Builder
 	CommandLine.SetOutput(&buf)
 	defer func(old []string) { os.Args = old }(os.Args)
 	os.Args = []string{"app", "-i=1", "-unknown"}
@@ -726,7 +751,7 @@
 		testName := fmt.Sprintf("FlagSet.Var(&v, %q, \"\")", test.flag)
 
 		fs := NewFlagSet("", ContinueOnError)
-		buf := bytes.NewBuffer(nil)
+		buf := &strings.Builder{}
 		fs.SetOutput(buf)
 
 		mustPanic(t, testName, test.errorMsg, func() {
@@ -758,7 +783,7 @@
 		testName := fmt.Sprintf("flag redefined in FlagSet(%q)", test.flagSetName)
 
 		fs := NewFlagSet(test.flagSetName, ContinueOnError)
-		buf := bytes.NewBuffer(nil)
+		buf := &strings.Builder{}
 		fs.SetOutput(buf)
 
 		var v flagVar
diff --git a/src/fmt/errors.go b/src/fmt/errors.go
index 4f4daf1..1fbd39f 100644
--- a/src/fmt/errors.go
+++ b/src/fmt/errors.go
@@ -4,26 +4,48 @@
 
 package fmt
 
-import "errors"
+import (
+	"errors"
+	"sort"
+)
 
 // Errorf formats according to a format specifier and returns the string as a
 // value that satisfies error.
 //
 // If the format specifier includes a %w verb with an error operand,
-// the returned error will implement an Unwrap method returning the operand. It is
-// invalid to include more than one %w verb or to supply it with an operand
-// that does not implement the error interface. The %w verb is otherwise
-// a synonym for %v.
+// the returned error will implement an Unwrap method returning the operand.
+// If there is more than one %w verb, the returned error will implement an
+// Unwrap method returning a []error containing all the %w operands in the
+// order they appear in the arguments.
+// It is invalid to supply the %w verb with an operand that does not implement
+// the error interface. The %w verb is otherwise a synonym for %v.
 func Errorf(format string, a ...any) error {
 	p := newPrinter()
 	p.wrapErrs = true
 	p.doPrintf(format, a)
 	s := string(p.buf)
 	var err error
-	if p.wrappedErr == nil {
+	switch len(p.wrappedErrs) {
+	case 0:
 		err = errors.New(s)
-	} else {
-		err = &wrapError{s, p.wrappedErr}
+	case 1:
+		w := &wrapError{msg: s}
+		w.err, _ = a[p.wrappedErrs[0]].(error)
+		err = w
+	default:
+		if p.reordered {
+			sort.Ints(p.wrappedErrs)
+		}
+		var errs []error
+		for i, argNum := range p.wrappedErrs {
+			if i > 0 && p.wrappedErrs[i-1] == argNum {
+				continue
+			}
+			if e, ok := a[argNum].(error); ok {
+				errs = append(errs, e)
+			}
+		}
+		err = &wrapErrors{s, errs}
 	}
 	p.free()
 	return err
@@ -41,3 +63,16 @@
 func (e *wrapError) Unwrap() error {
 	return e.err
 }
+
+type wrapErrors struct {
+	msg  string
+	errs []error
+}
+
+func (e *wrapErrors) Error() string {
+	return e.msg
+}
+
+func (e *wrapErrors) Unwrap() []error {
+	return e.errs
+}
diff --git a/src/fmt/errors_test.go b/src/fmt/errors_test.go
index 481a7b8..4eb55fa 100644
--- a/src/fmt/errors_test.go
+++ b/src/fmt/errors_test.go
@@ -7,6 +7,7 @@
 import (
 	"errors"
 	"fmt"
+	"reflect"
 	"testing"
 )
 
@@ -20,6 +21,7 @@
 		err        error
 		wantText   string
 		wantUnwrap error
+		wantSplit  []error
 	}{{
 		err:        fmt.Errorf("%w", wrapped),
 		wantText:   "inner error",
@@ -53,11 +55,29 @@
 		err:      noVetErrorf("%w is not an error", "not-an-error"),
 		wantText: "%!w(string=not-an-error) is not an error",
 	}, {
-		err:      noVetErrorf("wrapped two errors: %w %w", errString("1"), errString("2")),
-		wantText: "wrapped two errors: 1 %!w(fmt_test.errString=2)",
+		err:       noVetErrorf("wrapped two errors: %w %w", errString("1"), errString("2")),
+		wantText:  "wrapped two errors: 1 2",
+		wantSplit: []error{errString("1"), errString("2")},
 	}, {
-		err:      noVetErrorf("wrapped three errors: %w %w %w", errString("1"), errString("2"), errString("3")),
-		wantText: "wrapped three errors: 1 %!w(fmt_test.errString=2) %!w(fmt_test.errString=3)",
+		err:       noVetErrorf("wrapped three errors: %w %w %w", errString("1"), errString("2"), errString("3")),
+		wantText:  "wrapped three errors: 1 2 3",
+		wantSplit: []error{errString("1"), errString("2"), errString("3")},
+	}, {
+		err:       noVetErrorf("wrapped nil error: %w %w %w", errString("1"), nil, errString("2")),
+		wantText:  "wrapped nil error: 1 %!w(<nil>) 2",
+		wantSplit: []error{errString("1"), errString("2")},
+	}, {
+		err:       noVetErrorf("wrapped one non-error: %w %w %w", errString("1"), "not-an-error", errString("3")),
+		wantText:  "wrapped one non-error: 1 %!w(string=not-an-error) 3",
+		wantSplit: []error{errString("1"), errString("3")},
+	}, {
+		err:       fmt.Errorf("wrapped errors out of order: %[3]w %[2]w %[1]w", errString("1"), errString("2"), errString("3")),
+		wantText:  "wrapped errors out of order: 3 2 1",
+		wantSplit: []error{errString("1"), errString("2"), errString("3")},
+	}, {
+		err:       fmt.Errorf("wrapped several times: %[1]w %[1]w %[2]w %[1]w", errString("1"), errString("2")),
+		wantText:  "wrapped several times: 1 1 2 1",
+		wantSplit: []error{errString("1"), errString("2")},
 	}, {
 		err:        fmt.Errorf("%w", nil),
 		wantText:   "%!w(<nil>)",
@@ -66,12 +86,22 @@
 		if got, want := errors.Unwrap(test.err), test.wantUnwrap; got != want {
 			t.Errorf("Formatted error: %v\nerrors.Unwrap() = %v, want %v", test.err, got, want)
 		}
+		if got, want := splitErr(test.err), test.wantSplit; !reflect.DeepEqual(got, want) {
+			t.Errorf("Formatted error: %v\nUnwrap() []error = %v, want %v", test.err, got, want)
+		}
 		if got, want := test.err.Error(), test.wantText; got != want {
 			t.Errorf("err.Error() = %q, want %q", got, want)
 		}
 	}
 }
 
+func splitErr(err error) []error {
+	if e, ok := err.(interface{ Unwrap() []error }); ok {
+		return e.Unwrap()
+	}
+	return nil
+}
+
 type errString string
 
 func (e errString) Error() string { return string(e) }
diff --git a/src/fmt/fmt_test.go b/src/fmt/fmt_test.go
index aaeac38..37d82ac 100644
--- a/src/fmt/fmt_test.go
+++ b/src/fmt/fmt_test.go
@@ -249,6 +249,7 @@
 	{"%.0c", '⌘', "⌘"}, // Specifying precision should have no effect.
 	{"%3c", '⌘', "  ⌘"},
 	{"%-3c", '⌘', "⌘  "},
+	{"%c", uint64(0x100000000), "\ufffd"},
 	// Runes that are not printable.
 	{"%c", '\U00000e00', "\u0e00"},
 	{"%c", '\U0010ffff', "\U0010ffff"},
@@ -1429,11 +1430,16 @@
 }{
 	{0, `Sprintf("")`, func() { Sprintf("") }},
 	{1, `Sprintf("xxx")`, func() { Sprintf("xxx") }},
-	{2, `Sprintf("%x")`, func() { Sprintf("%x", 7) }},
-	{2, `Sprintf("%s")`, func() { Sprintf("%s", "hello") }},
-	{3, `Sprintf("%x %x")`, func() { Sprintf("%x %x", 7, 112) }},
-	{2, `Sprintf("%g")`, func() { Sprintf("%g", float32(3.14159)) }}, // TODO: Can this be 1?
-	{1, `Fprintf(buf, "%s")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%s", "hello") }},
+	{0, `Sprintf("%x")`, func() { Sprintf("%x", 7) }},
+	{1, `Sprintf("%x")`, func() { Sprintf("%x", 1<<16) }},
+	{3, `Sprintf("%80000s")`, func() { Sprintf("%80000s", "hello") }}, // large buffer (>64KB)
+	{1, `Sprintf("%s")`, func() { Sprintf("%s", "hello") }},
+	{1, `Sprintf("%x %x")`, func() { Sprintf("%x %x", 7, 112) }},
+	{1, `Sprintf("%g")`, func() { Sprintf("%g", float32(3.14159)) }},
+	{0, `Fprintf(buf, "%s")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%s", "hello") }},
+	{0, `Fprintf(buf, "%x")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%x", 7) }},
+	{0, `Fprintf(buf, "%x")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%x", 1<<16) }},
+	{2, `Fprintf(buf, "%80000s")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%80000s", "hello") }}, // large buffer (>64KB)
 	// If the interface value doesn't need to allocate, amortized allocation overhead should be zero.
 	{0, `Fprintf(buf, "%x %x %x")`, func() {
 		mallocBuf.Reset()
diff --git a/src/fmt/format.go b/src/fmt/format.go
index bd00e5a..617f78f 100644
--- a/src/fmt/format.go
+++ b/src/fmt/format.go
@@ -461,13 +461,14 @@
 // fmtC formats an integer as a Unicode character.
 // If the character is not valid Unicode, it will print '\ufffd'.
 func (f *fmt) fmtC(c uint64) {
+	// Explicitly check whether c exceeds utf8.MaxRune since the conversion
+	// of a uint64 to a rune may lose precision that indicates an overflow.
 	r := rune(c)
 	if c > utf8.MaxRune {
 		r = utf8.RuneError
 	}
 	buf := f.intbuf[:0]
-	w := utf8.EncodeRune(buf[:utf8.UTFMax], r)
-	f.pad(buf[:w])
+	f.pad(utf8.AppendRune(buf, r))
 }
 
 // fmtQc formats an integer as a single-quoted, escaped Go character constant.
diff --git a/src/fmt/print.go b/src/fmt/print.go
index 2af7bd0..b3dd43c 100644
--- a/src/fmt/print.go
+++ b/src/fmt/print.go
@@ -9,6 +9,7 @@
 	"io"
 	"os"
 	"reflect"
+	"strconv"
 	"sync"
 	"unicode/utf8"
 )
@@ -71,6 +72,31 @@
 	GoString() string
 }
 
+// FormatString returns a string representing the fully qualified formatting
+// directive captured by the State, followed by the argument verb. (State does not
+// itself contain the verb.) The result has a leading percent sign followed by any
+// flags, the width, and the precision. Missing flags, width, and precision are
+// omitted. This function allows a Formatter to reconstruct the original
+// directive triggering the call to Format.
+func FormatString(state State, verb rune) string {
+	var tmp [16]byte // Use a local buffer.
+	b := append(tmp[:0], '%')
+	for _, c := range " +-#0" { // All known flags
+		if state.Flag(int(c)) { // The argument is an int for historical reasons.
+			b = append(b, byte(c))
+		}
+	}
+	if w, ok := state.Width(); ok {
+		b = strconv.AppendInt(b, int64(w), 10)
+	}
+	if p, ok := state.Precision(); ok {
+		b = append(b, '.')
+		b = strconv.AppendInt(b, int64(p), 10)
+	}
+	b = utf8.AppendRune(b, verb)
+	return string(b)
+}
+
 // Use simple []byte instead of bytes.Buffer to avoid large dependency.
 type buffer []byte
 
@@ -87,18 +113,7 @@
 }
 
 func (bp *buffer) writeRune(r rune) {
-	if r < utf8.RuneSelf {
-		*bp = append(*bp, byte(r))
-		return
-	}
-
-	b := *bp
-	n := len(b)
-	for n+utf8.UTFMax > cap(b) {
-		b = append(b, 0)
-	}
-	w := utf8.EncodeRune(b[n:n+utf8.UTFMax], r)
-	*bp = b[:n+w]
+	*bp = utf8.AppendRune(*bp, r)
 }
 
 // pp is used to store a printer's state and is reused with sync.Pool to avoid allocations.
@@ -124,8 +139,8 @@
 	erroring bool
 	// wrapErrs is set when the format string may contain a %w verb.
 	wrapErrs bool
-	// wrappedErr records the target of the %w verb.
-	wrappedErr error
+	// wrappedErrs records the targets of the %w verb.
+	wrappedErrs []int
 }
 
 var ppFree = sync.Pool{
@@ -146,18 +161,23 @@
 func (p *pp) free() {
 	// Proper usage of a sync.Pool requires each entry to have approximately
 	// the same memory cost. To obtain this property when the stored type
-	// contains a variably-sized buffer, we add a hard limit on the maximum buffer
-	// to place back in the pool.
+	// contains a variably-sized buffer, we add a hard limit on the maximum
+	// buffer to place back in the pool. If the buffer is larger than the
+	// limit, we drop the buffer and recycle just the printer.
 	//
-	// See https://golang.org/issue/23199
-	if cap(p.buf) > 64<<10 {
-		return
+	// See https://golang.org/issue/23199.
+	if cap(p.buf) > 64*1024 {
+		p.buf = nil
+	} else {
+		p.buf = p.buf[:0]
+	}
+	if cap(p.wrappedErrs) > 8 {
+		p.wrappedErrs = nil
 	}
 
-	p.buf = p.buf[:0]
 	p.arg = nil
 	p.value = reflect.Value{}
-	p.wrappedErr = nil
+	p.wrappedErrs = p.wrappedErrs[:0]
 	ppFree.Put(p)
 }
 
@@ -603,16 +623,12 @@
 		return
 	}
 	if verb == 'w' {
-		// It is invalid to use %w other than with Errorf, more than once,
-		// or with a non-error arg.
-		err, ok := p.arg.(error)
-		if !ok || !p.wrapErrs || p.wrappedErr != nil {
-			p.wrappedErr = nil
-			p.wrapErrs = false
+		// It is invalid to use %w other than with Errorf or with a non-error arg.
+		_, ok := p.arg.(error)
+		if !ok || !p.wrapErrs {
 			p.badVerb(verb)
 			return true
 		}
-		p.wrappedErr = err
 		// If the arg is a Formatter, pass 'v' as the verb to it.
 		verb = 'v'
 	}
@@ -1046,7 +1062,11 @@
 				// Fast path for common case of ascii lower case simple verbs
 				// without precision or width or argument indices.
 				if 'a' <= c && c <= 'z' && argNum < len(a) {
-					if c == 'v' {
+					switch c {
+					case 'w':
+						p.wrappedErrs = append(p.wrappedErrs, argNum)
+						fallthrough
+					case 'v':
 						// Go syntax
 						p.fmt.sharpV = p.fmt.sharp
 						p.fmt.sharp = false
@@ -1141,6 +1161,9 @@
 			p.badArgNum(verb)
 		case argNum >= len(a): // No argument left over to print for the current verb.
 			p.missingArg(verb)
+		case verb == 'w':
+			p.wrappedErrs = append(p.wrappedErrs, argNum)
+			fallthrough
 		case verb == 'v':
 			// Go syntax
 			p.fmt.sharpV = p.fmt.sharp
diff --git a/src/fmt/scan_test.go b/src/fmt/scan_test.go
index da0dfd1..e8c5769 100644
--- a/src/fmt/scan_test.go
+++ b/src/fmt/scan_test.go
@@ -52,6 +52,7 @@
 	uint16Val            uint16
 	uint32Val            uint32
 	uint64Val            uint64
+	uintptrVal           uintptr
 	float32Val           float32
 	float64Val           float64
 	stringVal            string
@@ -162,6 +163,7 @@
 	{"28\n", &uint16Val, uint16(28)},
 	{"29\n", &uint32Val, uint32(29)},
 	{"30\n", &uint64Val, uint64(30)},
+	{"31\n", &uintptrVal, uintptr(31)},
 	{"255\n", &uint8Val, uint8(255)},
 	{"32767\n", &int16Val, int16(32767)},
 	{"2.3\n", &float64Val, 2.3},
@@ -247,6 +249,7 @@
 	{"%d", "74\n", &uint16Val, uint16(74)},
 	{"%d", "75\n", &uint32Val, uint32(75)},
 	{"%d", "76\n", &uint64Val, uint64(76)},
+	{"%d", "77\n", &uintptrVal, uintptr(77)},
 	{"%b", "1001001\n", &uintVal, uint(73)},
 	{"%b", "100_1001\n", &uintVal, uint(4)},
 	{"%o", "075\n", &uintVal, uint(075)},
diff --git a/src/fmt/state_test.go b/src/fmt/state_test.go
new file mode 100644
index 0000000..fda660a
--- /dev/null
+++ b/src/fmt/state_test.go
@@ -0,0 +1,80 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package fmt_test
+
+import (
+	"fmt"
+	"testing"
+)
+
+type testState struct {
+	width   int
+	widthOK bool
+	prec    int
+	precOK  bool
+	flag    map[int]bool
+}
+
+var _ fmt.State = testState{}
+
+func (s testState) Write(b []byte) (n int, err error) {
+	panic("unimplemented")
+}
+
+func (s testState) Width() (wid int, ok bool) {
+	return s.width, s.widthOK
+}
+
+func (s testState) Precision() (prec int, ok bool) {
+	return s.prec, s.precOK
+}
+
+func (s testState) Flag(c int) bool {
+	return s.flag[c]
+}
+
+const NO = -1000
+
+func mkState(w, p int, flags string) testState {
+	s := testState{}
+	if w != NO {
+		s.width = w
+		s.widthOK = true
+	}
+	if p != NO {
+		s.prec = p
+		s.precOK = true
+	}
+	s.flag = make(map[int]bool)
+	for _, c := range flags {
+		s.flag[int(c)] = true
+	}
+	return s
+}
+
+func TestFormatString(t *testing.T) {
+	var tests = []struct {
+		width, prec int
+		flags       string
+		result      string
+	}{
+		{NO, NO, "", "%x"},
+		{NO, 3, "", "%.3x"},
+		{3, NO, "", "%3x"},
+		{7, 3, "", "%7.3x"},
+		{NO, NO, " +-#0", "% +-#0x"},
+		{7, 3, "+", "%+7.3x"},
+		{7, -3, "-", "%-7.-3x"},
+		{7, 3, " ", "% 7.3x"},
+		{7, 3, "#", "%#7.3x"},
+		{7, 3, "0", "%07.3x"},
+	}
+	for _, test := range tests {
+		got := fmt.FormatString(mkState(test.width, test.prec, test.flags), 'x')
+		if got != test.result {
+			t.Errorf("%v: got %s", test, got)
+		}
+	}
+}
diff --git a/src/go.mod b/src/go.mod
index 94380d6..4697da2 100644
--- a/src/go.mod
+++ b/src/go.mod
@@ -1,13 +1,13 @@
 module std
 
-go 1.19
+go 1.20
 
 require (
-	golang.org/x/crypto v0.0.0-20220516162934-403b01795ae8
-	golang.org/x/net v0.0.0-20220517181318-183a9ca12b87
+	golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a
+	golang.org/x/net v0.4.1-0.20230214201333-88ed8ca3307d
 )
 
 require (
-	golang.org/x/sys v0.0.0-20220614162138-6c1b26c55098 // indirect
-	golang.org/x/text v0.3.8-0.20220509174342-b4bca84b0361 // indirect
+	golang.org/x/sys v0.3.0 // indirect
+	golang.org/x/text v0.5.0 // indirect
 )
diff --git a/src/go.sum b/src/go.sum
index a54b056..625f207 100644
--- a/src/go.sum
+++ b/src/go.sum
@@ -1,8 +1,8 @@
-golang.org/x/crypto v0.0.0-20220516162934-403b01795ae8 h1:y+mHpWoQJNAHt26Nhh6JP7hvM71IRZureyvZhoVALIs=
-golang.org/x/crypto v0.0.0-20220516162934-403b01795ae8/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
-golang.org/x/net v0.0.0-20220517181318-183a9ca12b87 h1:cCR+9mKLOGyX4Zx+uBZDXEDAQsvKQ/XbW4vreG5v1jU=
-golang.org/x/net v0.0.0-20220517181318-183a9ca12b87/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/sys v0.0.0-20220614162138-6c1b26c55098 h1:PgOr27OhUx2IRqGJ2RxAWI4dJQ7bi9cSrB82uzFzfUA=
-golang.org/x/sys v0.0.0-20220614162138-6c1b26c55098/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/text v0.3.8-0.20220509174342-b4bca84b0361 h1:h+pU/hCb7sEApigI6eII3/Emx5ZHaFWS+nulUp0Az/k=
-golang.org/x/text v0.3.8-0.20220509174342-b4bca84b0361/go.mod h1:5O0TPrbzDRCcAYs9rc2W4CFPmVHJfNFe8tESfECPJPE=
+golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a h1:diz9pEYuTIuLMJLs3rGDkeaTsNyRs6duYdFyPAxzE/U=
+golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
+golang.org/x/net v0.4.1-0.20230214201333-88ed8ca3307d h1:KHU/KRz6+/yWyRHEC24m7T5gou5VSh62duch955ktBY=
+golang.org/x/net v0.4.1-0.20230214201333-88ed8ca3307d/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
+golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
+golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM=
+golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
diff --git a/src/go/ast/ast.go b/src/go/ast/ast.go
index 1e089b9..9baf72f 100644
--- a/src/go/ast/ast.go
+++ b/src/go/ast/ast.go
@@ -754,6 +754,7 @@
 		Key, Value Expr        // Key, Value may be nil
 		TokPos     token.Pos   // position of Tok; invalid if Key == nil
 		Tok        token.Token // ILLEGAL if Key == nil, ASSIGN, DEFINE
+		Range      token.Pos   // position of "range" keyword
 		X          Expr        // value to range over
 		Body       *BlockStmt
 	}
@@ -1035,17 +1036,24 @@
 // and Comment comments directly associated with nodes, the remaining comments
 // are "free-floating" (see also issues #18593, #20744).
 type File struct {
-	Doc        *CommentGroup   // associated documentation; or nil
-	Package    token.Pos       // position of "package" keyword
-	Name       *Ident          // package name
-	Decls      []Decl          // top-level declarations; or nil
-	Scope      *Scope          // package scope (this file only)
-	Imports    []*ImportSpec   // imports in this file
-	Unresolved []*Ident        // unresolved identifiers in this file
-	Comments   []*CommentGroup // list of all comments in the source file
+	Doc     *CommentGroup // associated documentation; or nil
+	Package token.Pos     // position of "package" keyword
+	Name    *Ident        // package name
+	Decls   []Decl        // top-level declarations; or nil
+
+	FileStart, FileEnd token.Pos       // start and end of entire file
+	Scope              *Scope          // package scope (this file only)
+	Imports            []*ImportSpec   // imports in this file
+	Unresolved         []*Ident        // unresolved identifiers in this file
+	Comments           []*CommentGroup // list of all comments in the source file
 }
 
+// Pos returns the position of the package declaration.
+// (Use FileStart for the start of the entire file.)
 func (f *File) Pos() token.Pos { return f.Package }
+
+// End returns the end of the last declaration in the file.
+// (Use FileEnd for the end of the entire file.)
 func (f *File) End() token.Pos {
 	if n := len(f.Decls); n > 0 {
 		return f.Decls[n-1].End()
diff --git a/src/go/ast/commentmap.go b/src/go/ast/commentmap.go
index 9f81493..4196e47 100644
--- a/src/go/ast/commentmap.go
+++ b/src/go/ast/commentmap.go
@@ -9,6 +9,7 @@
 	"fmt"
 	"go/token"
 	"sort"
+	"strings"
 )
 
 type byPos []*CommentGroup
@@ -311,7 +312,7 @@
 	}
 	sort.Sort(byInterval(nodes))
 
-	var buf bytes.Buffer
+	var buf strings.Builder
 	fmt.Fprintln(&buf, "CommentMap {")
 	for _, node := range nodes {
 		comment := cmap[node]
diff --git a/src/go/ast/commentmap_test.go b/src/go/ast/commentmap_test.go
index 281467c..f0faeed 100644
--- a/src/go/ast/commentmap_test.go
+++ b/src/go/ast/commentmap_test.go
@@ -7,12 +7,12 @@
 package ast_test
 
 import (
-	"bytes"
 	"fmt"
 	. "go/ast"
 	"go/parser"
 	"go/token"
 	"sort"
+	"strings"
 	"testing"
 )
 
@@ -94,7 +94,7 @@
 }
 
 func ctext(list []*CommentGroup) string {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	for _, g := range list {
 		buf.WriteString(g.Text())
 	}
diff --git a/src/go/ast/example_test.go b/src/go/ast/example_test.go
index e3013f6..c6904be 100644
--- a/src/go/ast/example_test.go
+++ b/src/go/ast/example_test.go
@@ -5,12 +5,12 @@
 package ast_test
 
 import (
-	"bytes"
 	"fmt"
 	"go/ast"
 	"go/format"
 	"go/parser"
 	"go/token"
+	"strings"
 )
 
 // This example demonstrates how to inspect the AST of a Go program.
@@ -126,15 +126,17 @@
 	//     47  .  .  .  }
 	//     48  .  .  }
 	//     49  .  }
-	//     50  .  Scope: *ast.Scope {
-	//     51  .  .  Objects: map[string]*ast.Object (len = 1) {
-	//     52  .  .  .  "main": *(obj @ 11)
-	//     53  .  .  }
-	//     54  .  }
-	//     55  .  Unresolved: []*ast.Ident (len = 1) {
-	//     56  .  .  0: *(obj @ 29)
-	//     57  .  }
-	//     58  }
+	//     50  .  FileStart: 1:1
+	//     51  .  FileEnd: 5:3
+	//     52  .  Scope: *ast.Scope {
+	//     53  .  .  Objects: map[string]*ast.Object (len = 1) {
+	//     54  .  .  .  "main": *(obj @ 11)
+	//     55  .  .  }
+	//     56  .  }
+	//     57  .  Unresolved: []*ast.Ident (len = 1) {
+	//     58  .  .  0: *(obj @ 29)
+	//     59  .  }
+	//     60  }
 }
 
 // This example illustrates how to remove a variable declaration
@@ -186,11 +188,11 @@
 	f.Comments = cmap.Filter(f).Comments()
 
 	// Print the modified AST.
-	var buf bytes.Buffer
+	var buf strings.Builder
 	if err := format.Node(&buf, fset, f); err != nil {
 		panic(err)
 	}
-	fmt.Printf("%s", buf.Bytes())
+	fmt.Printf("%s", buf.String())
 
 	// Output:
 	// // This is the package comment.
diff --git a/src/go/ast/filter.go b/src/go/ast/filter.go
index 2fc73c4..7d2a11e 100644
--- a/src/go/ast/filter.go
+++ b/src/go/ast/filter.go
@@ -340,6 +340,7 @@
 	ncomments := 0
 	ndecls := 0
 	filenames := make([]string, len(pkg.Files))
+	var minPos, maxPos token.Pos
 	i := 0
 	for filename, f := range pkg.Files {
 		filenames[i] = filename
@@ -349,6 +350,12 @@
 		}
 		ncomments += len(f.Comments)
 		ndecls += len(f.Decls)
+		if i == 0 || f.FileStart < minPos {
+			minPos = f.FileStart
+		}
+		if i == 0 || f.FileEnd > maxPos {
+			maxPos = f.FileEnd
+		}
 	}
 	sort.Strings(filenames)
 
@@ -484,5 +491,5 @@
 	}
 
 	// TODO(gri) need to compute unresolved identifiers!
-	return &File{doc, pos, NewIdent(pkg.Name), decls, pkg.Scope, imports, nil, comments}
+	return &File{doc, pos, NewIdent(pkg.Name), decls, minPos, maxPos, pkg.Scope, imports, nil, comments}
 }
diff --git a/src/go/ast/filter_test.go b/src/go/ast/filter_test.go
index 86f396b..d5cb0c2 100644
--- a/src/go/ast/filter_test.go
+++ b/src/go/ast/filter_test.go
@@ -7,11 +7,11 @@
 package ast_test
 
 import (
-	"bytes"
 	"go/ast"
 	"go/format"
 	"go/parser"
 	"go/token"
+	"strings"
 	"testing"
 )
 
@@ -73,7 +73,7 @@
 	merged := ast.MergePackageFiles(pkg, ast.FilterFuncDuplicates)
 
 	// pretty-print
-	var buf bytes.Buffer
+	var buf strings.Builder
 	if err := format.Node(&buf, fset, merged); err != nil {
 		t.Fatal(err)
 	}
diff --git a/src/go/ast/print_test.go b/src/go/ast/print_test.go
index 6691ccd..94b515b 100644
--- a/src/go/ast/print_test.go
+++ b/src/go/ast/print_test.go
@@ -5,7 +5,6 @@
 package ast
 
 import (
-	"bytes"
 	"strings"
 	"testing"
 )
@@ -84,7 +83,7 @@
 }
 
 func TestPrint(t *testing.T) {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	for _, test := range tests {
 		buf.Reset()
 		if err := Fprint(&buf, nil, test.x, nil); err != nil {
diff --git a/src/go/ast/scope.go b/src/go/ast/scope.go
index 02691f8..8882212 100644
--- a/src/go/ast/scope.go
+++ b/src/go/ast/scope.go
@@ -7,9 +7,9 @@
 package ast
 
 import (
-	"bytes"
 	"fmt"
 	"go/token"
+	"strings"
 )
 
 // A Scope maintains the set of named language entities declared
@@ -46,7 +46,7 @@
 
 // Debugging support
 func (s *Scope) String() string {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	fmt.Fprintf(&buf, "scope %p {", s)
 	if s != nil && len(s.Objects) > 0 {
 		fmt.Fprintln(&buf)
diff --git a/src/go/build/build.go b/src/go/build/build.go
index dfb37b8..420873c 100644
--- a/src/go/build/build.go
+++ b/src/go/build/build.go
@@ -13,6 +13,7 @@
 	"go/doc"
 	"go/token"
 	"internal/buildcfg"
+	"internal/godebug"
 	"internal/goroot"
 	"internal/goversion"
 	"io"
@@ -45,11 +46,11 @@
 	Dir string
 
 	CgoEnabled  bool   // whether cgo files are included
-	UseAllFiles bool   // use files regardless of +build lines, file names
+	UseAllFiles bool   // use files regardless of go:build lines, file names
 	Compiler    string // compiler to assume when computing target paths
 
 	// The build, tool, and release tags specify build constraints
-	// that should be considered satisfied when processing +build lines.
+	// that should be considered satisfied when processing go:build lines.
 	// Clients creating a new context may customize BuildTags, which
 	// defaults to empty, but it is usually an error to customize ToolTags or ReleaseTags.
 	// ToolTags defaults to build tags appropriate to the current Go toolchain configuration.
@@ -103,7 +104,7 @@
 
 	// ReadDir returns a slice of fs.FileInfo, sorted by Name,
 	// describing the content of the named directory.
-	// If ReadDir is nil, Import uses ioutil.ReadDir.
+	// If ReadDir is nil, Import uses os.ReadDir.
 	ReadDir func(dir string) ([]fs.FileInfo, error)
 
 	// OpenFile opens a file (not a directory) for reading.
@@ -179,10 +180,11 @@
 		root += sep
 	}
 	dir = filepath.Clean(dir)
-	if !strings.HasPrefix(dir, root) {
+	after, found := strings.CutPrefix(dir, root)
+	if !found {
 		return "", false
 	}
-	return filepath.ToSlash(dir[len(root):]), true
+	return filepath.ToSlash(after), true
 }
 
 // readDir calls ctxt.ReadDir (if not nil) or else os.ReadDir.
@@ -314,23 +316,16 @@
 	}
 	c.GOPATH = envOr("GOPATH", defaultGOPATH())
 	c.Compiler = runtime.Compiler
+	c.ToolTags = append(c.ToolTags, buildcfg.ToolTags...)
 
-	// For each experiment that has been enabled in the toolchain, define a
-	// build tag with the same name but prefixed by "goexperiment." which can be
-	// used for compiling alternative files for the experiment. This allows
-	// changes for the experiment, like extra struct fields in the runtime,
-	// without affecting the base non-experiment code at all.
-	for _, exp := range buildcfg.Experiment.Enabled() {
-		c.ToolTags = append(c.ToolTags, "goexperiment."+exp)
-	}
 	defaultToolTags = append([]string{}, c.ToolTags...) // our own private copy
 
 	// Each major Go release in the Go 1.x series adds a new
 	// "go1.x" release tag. That is, the go1.x tag is present in
 	// all releases >= Go 1.x. Code that requires Go 1.x or later
-	// should say "+build go1.x", and code that should only be
+	// should say "go:build go1.x", and code that should only be
 	// built before Go 1.x (perhaps it is the stub to use in that
-	// case) should say "+build !go1.x".
+	// case) should say "go:build !go1.x".
 	// The last element in ReleaseTags is the current release.
 	for i := 1; i <= goversion.Version; i++ {
 		c.ReleaseTags = append(c.ReleaseTags, "go1."+strconv.Itoa(i))
@@ -526,6 +521,8 @@
 	return name[i:]
 }
 
+var installgoroot = godebug.New("installgoroot")
+
 // Import returns details about the Go package named by the import path,
 // interpreting local import paths relative to the srcDir directory.
 // If the path is a local import path naming a package that can be imported
@@ -783,8 +780,14 @@
 		p.PkgRoot = ctxt.joinPath(p.Root, "pkg")
 		p.BinDir = ctxt.joinPath(p.Root, "bin")
 		if pkga != "" {
+			// Always set PkgTargetRoot. It might be used when building in shared
+			// mode.
 			p.PkgTargetRoot = ctxt.joinPath(p.Root, pkgtargetroot)
-			p.PkgObj = ctxt.joinPath(p.Root, pkga)
+
+			// Set the install target if applicable.
+			if !p.Goroot || (installgoroot.Value() == "all" && p.ImportPath != "unsafe" && p.ImportPath != "builtin") {
+				p.PkgObj = ctxt.joinPath(p.Root, pkga)
+			}
 		}
 	}
 
@@ -821,14 +824,14 @@
 	}
 
 	var badGoError error
-	badFiles := make(map[string]bool)
-	badFile := func(name string, err error) {
+	badGoFiles := make(map[string]bool)
+	badGoFile := func(name string, err error) {
 		if badGoError == nil {
 			badGoError = err
 		}
-		if !badFiles[name] {
+		if !badGoFiles[name] {
 			p.InvalidGoFiles = append(p.InvalidGoFiles, name)
-			badFiles[name] = true
+			badGoFiles[name] = true
 		}
 	}
 
@@ -857,8 +860,8 @@
 		ext := nameExt(name)
 
 		info, err := ctxt.matchFile(p.Dir, name, allTags, &p.BinaryOnly, fset)
-		if err != nil {
-			badFile(name, err)
+		if err != nil && strings.HasSuffix(name, ".go") {
+			badGoFile(name, err)
 			continue
 		}
 		if info == nil {
@@ -871,7 +874,6 @@
 			}
 			continue
 		}
-		data, filename := info.header, info.name
 
 		// Going to save the file. For non-Go files, can stop here.
 		switch ext {
@@ -888,8 +890,10 @@
 			continue
 		}
 
+		data, filename := info.header, info.name
+
 		if info.parseErr != nil {
-			badFile(name, info.parseErr)
+			badGoFile(name, info.parseErr)
 			// Fall through: we might still have a partial AST in info.parsed,
 			// and we want to list files with parse errors anyway.
 		}
@@ -917,7 +921,7 @@
 			// TODO(#45999): The choice of p.Name is arbitrary based on file iteration
 			// order. Instead of resolving p.Name arbitrarily, we should clear out the
 			// existing name and mark the existing files as also invalid.
-			badFile(name, &MultiplePackageError{
+			badGoFile(name, &MultiplePackageError{
 				Dir:      p.Dir,
 				Packages: []string{p.Name, pkg},
 				Files:    []string{firstFile, name},
@@ -933,12 +937,12 @@
 			if line != 0 {
 				com, err := strconv.Unquote(qcom)
 				if err != nil {
-					badFile(name, fmt.Errorf("%s:%d: cannot parse import comment", filename, line))
+					badGoFile(name, fmt.Errorf("%s:%d: cannot parse import comment", filename, line))
 				} else if p.ImportComment == "" {
 					p.ImportComment = com
 					firstCommentFile = name
 				} else if p.ImportComment != com {
-					badFile(name, fmt.Errorf("found import comments %q (%s) and %q (%s) in %s", p.ImportComment, firstCommentFile, com, name, p.Dir))
+					badGoFile(name, fmt.Errorf("found import comments %q (%s) and %q (%s) in %s", p.ImportComment, firstCommentFile, com, name, p.Dir))
 				}
 			}
 		}
@@ -948,13 +952,13 @@
 		for _, imp := range info.imports {
 			if imp.path == "C" {
 				if isTest {
-					badFile(name, fmt.Errorf("use of cgo in test %s not supported", filename))
+					badGoFile(name, fmt.Errorf("use of cgo in test %s not supported", filename))
 					continue
 				}
 				isCgo = true
 				if imp.doc != nil {
 					if err := ctxt.saveCgo(filename, p, imp.doc); err != nil {
-						badFile(name, err)
+						badGoFile(name, err)
 					}
 				}
 			}
@@ -1404,7 +1408,7 @@
 // If name denotes a Go program, matchFile reads until the end of the
 // imports and returns that section of the file in the fileInfo's header field,
 // even though it only considers text until the first non-comment
-// for +build lines.
+// for go:build lines.
 //
 // If allTags is non-nil, matchFile records any encountered build tag
 // by setting allTags[tag] = true.
@@ -1420,12 +1424,12 @@
 	}
 	ext := name[i:]
 
-	if !ctxt.goodOSArchFile(name, allTags) && !ctxt.UseAllFiles {
+	if ext != ".go" && fileListForExt(&dummyPkg, ext) == nil {
+		// skip
 		return nil, nil
 	}
 
-	if ext != ".go" && fileListForExt(&dummyPkg, ext) == nil {
-		// skip
+	if !ctxt.goodOSArchFile(name, allTags) && !ctxt.UseAllFiles {
 		return nil, nil
 	}
 
@@ -1451,10 +1455,10 @@
 	}
 	f.Close()
 	if err != nil {
-		return nil, fmt.Errorf("read %s: %v", info.name, err)
+		return info, fmt.Errorf("read %s: %v", info.name, err)
 	}
 
-	// Look for +build comments to accept or reject the file.
+	// Look for go:build comments to accept or reject the file.
 	ok, sawBinaryOnly, err := ctxt.shouldBuild(info.header, allTags)
 	if err != nil {
 		return nil, fmt.Errorf("%s: %v", name, err)
@@ -1490,15 +1494,11 @@
 }
 
 var (
-	bSlashSlash = []byte(slashSlash)
-	bStarSlash  = []byte(starSlash)
-	bSlashStar  = []byte(slashStar)
-	bPlusBuild  = []byte("+build")
+	plusBuild = []byte("+build")
 
 	goBuildComment = []byte("//go:build")
 
-	errGoBuildWithoutBuild = errors.New("//go:build comment without // +build comment")
-	errMultipleGoBuild     = errors.New("multiple //go:build comments")
+	errMultipleGoBuild = errors.New("multiple //go:build comments")
 )
 
 func isGoBuildComment(line []byte) bool {
@@ -1519,12 +1519,12 @@
 // The rule is that in the file's leading run of // comments
 // and blank lines, which must be followed by a blank line
 // (to avoid including a Go package clause doc comment),
-// lines beginning with '// +build' are taken as build directives.
+// lines beginning with '//go:build' are taken as build directives.
 //
 // The file is accepted only if each such line lists something
 // matching the file. For example:
 //
-//	// +build windows linux
+//	//go:build windows linux
 //
 // marks the file as applicable only on Windows and Linux.
 //
@@ -1562,7 +1562,7 @@
 				p = p[len(p):]
 			}
 			line = bytes.TrimSpace(line)
-			if !bytes.HasPrefix(line, bSlashSlash) || !bytes.Contains(line, bPlusBuild) {
+			if !bytes.HasPrefix(line, slashSlash) || !bytes.Contains(line, plusBuild) {
 				continue
 			}
 			text := string(line)
@@ -1583,7 +1583,7 @@
 func parseFileHeader(content []byte) (trimmed, goBuild []byte, sawBinaryOnly bool, err error) {
 	end := 0
 	p := content
-	ended := false       // found non-blank, non-// line, so stopped accepting // +build lines
+	ended := false       // found non-blank, non-// line, so stopped accepting //go:build lines
 	inSlashStar := false // in /* */ comment
 
 Lines:
@@ -1599,7 +1599,7 @@
 			// Remember position of most recent blank line.
 			// When we find the first non-blank, non-// line,
 			// this "end" position marks the latest file position
-			// where a // +build line can appear.
+			// where a //go:build line can appear.
 			// (It must appear _before_ a blank line before the non-blank, non-// line.
 			// Yes, that's confusing, which is part of why we moved to //go:build lines.)
 			// Note that ended==false here means that inSlashStar==false,
@@ -1631,12 +1631,12 @@
 				}
 				continue Lines
 			}
-			if bytes.HasPrefix(line, bSlashSlash) {
+			if bytes.HasPrefix(line, slashSlash) {
 				continue Lines
 			}
-			if bytes.HasPrefix(line, bSlashStar) {
+			if bytes.HasPrefix(line, slashStar) {
 				inSlashStar = true
-				line = bytes.TrimSpace(line[len(bSlashStar):])
+				line = bytes.TrimSpace(line[len(slashStar):])
 				continue Comments
 			}
 			// Found non-comment text.
diff --git a/src/go/build/build_test.go b/src/go/build/build_test.go
index 8fa17c7..2e60ecc 100644
--- a/src/go/build/build_test.go
+++ b/src/go/build/build_test.go
@@ -671,19 +671,6 @@
 	}
 }
 
-func TestImportDirTarget(t *testing.T) {
-	testenv.MustHaveGoBuild(t) // really must just have source
-	ctxt := Default
-	ctxt.GOPATH = ""
-	p, err := ctxt.ImportDir(filepath.Join(testenv.GOROOT(t), "src/path"), 0)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if p.PkgTargetRoot == "" || p.PkgObj == "" {
-		t.Errorf("p.PkgTargetRoot == %q, p.PkgObj == %q, want non-empty", p.PkgTargetRoot, p.PkgObj)
-	}
-}
-
 // TestIssue23594 prevents go/build from regressing and populating Package.Doc
 // from comments in test files.
 func TestIssue23594(t *testing.T) {
@@ -700,6 +687,22 @@
 	}
 }
 
+// TestIssue56509 tests that go/build does not add non-go files to InvalidGoFiles
+// when they have unparsable comments.
+func TestIssue56509(t *testing.T) {
+	// The directory testdata/bads contains a .s file that has an unparsable
+	// comment. (go/build parses initial comments in non-go files looking for
+	// //go:build or //+go build comments).
+	p, err := ImportDir("testdata/bads", 0)
+	if err == nil {
+		t.Fatalf("could not import testdata/bads: %v", err)
+	}
+
+	if len(p.InvalidGoFiles) != 0 {
+		t.Fatalf("incorrectly added non-go file to InvalidGoFiles")
+	}
+}
+
 // TestMissingImportErrorRepetition checks that when an unknown package is
 // imported, the package path is only shown once in the error.
 // Verifies golang.org/issue/34752.
@@ -788,3 +791,13 @@
 		t.Errorf("GoFiles = %v, want %v", p.GoFiles, wantFiles)
 	}
 }
+
+func TestAllTagsNonSourceFile(t *testing.T) {
+	p, err := Default.ImportDir("testdata/non_source_tags", 0)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if len(p.AllTags) > 0 {
+		t.Errorf("AllTags = %v, want empty", p.AllTags)
+	}
+}
diff --git a/src/go/build/deps_test.go b/src/go/build/deps_test.go
index 141fdb9..08452c7 100644
--- a/src/go/build/deps_test.go
+++ b/src/go/build/deps_test.go
@@ -1,4 +1,4 @@
-// Copyright 2012 The Go Authors. All rights reserved.
+// Copyright 2022 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
@@ -11,6 +11,7 @@
 	"bytes"
 	"fmt"
 	"go/token"
+	"internal/dag"
 	"internal/testenv"
 	"io/fs"
 	"os"
@@ -29,40 +30,9 @@
 // without prior discussion.
 // Negative assertions should almost never be removed.
 //
-// The general syntax of a rule is:
+// "a < b" means package b can import package a.
 //
-//	a, b < c, d;
-//
-// which means c and d come after a and b in the partial order
-// (that is, c and d can import a and b),
-// but doesn't provide a relative order between a vs b or c vs d.
-//
-// The rules can chain together, as in:
-//
-//	e < f, g < h;
-//
-// which is equivalent to
-//
-//	e < f, g;
-//	f, g < h;
-//
-// Except for the special bottom element "NONE", each name
-// must appear exactly once on the right-hand side of a rule.
-// That rule serves as the definition of the allowed dependencies
-// for that name. The definition must appear before any uses
-// of the name on the left-hand side of a rule. (That is, the
-// rules themselves must be ordered according to the partial
-// order, for easier reading by people.)
-//
-// Negative assertions double-check the partial order:
-//
-//	i !< j
-//
-// means that it must NOT be the case that i < j.
-// Negative assertions may appear anywhere in the rules,
-// even before i and j have been defined.
-//
-// Comments begin with #.
+// See `go doc internal/dag' for the full syntax.
 //
 // All-caps names are pseudo-names for specific points
 // in the dependency lattice.
@@ -70,9 +40,11 @@
 	# No dependencies allowed for any of these packages.
 	NONE
 	< constraints, container/list, container/ring,
-	  internal/cfg, internal/cpu, internal/goarch,
+	  internal/cfg, internal/coverage, internal/coverage/rtcov,
+	  internal/coverage/uleb128, internal/coverage/calloc,
+	  internal/cpu, internal/goarch,
 	  internal/goexperiment, internal/goos,
-	  internal/goversion, internal/nettrace,
+	  internal/goversion, internal/nettrace, internal/platform,
 	  unicode/utf8, unicode/utf16, unicode,
 	  unsafe;
 
@@ -82,7 +54,8 @@
 
 	# RUNTIME is the core runtime group of packages, all of them very light-weight.
 	internal/abi, internal/cpu, internal/goarch,
-	internal/goexperiment, internal/goos, unsafe
+	internal/coverage/rtcov, internal/goexperiment,
+	internal/goos, unsafe
 	< internal/bytealg
 	< internal/itoa
 	< internal/unsafeheader
@@ -94,6 +67,7 @@
 	< sync/atomic
 	< internal/race
 	< sync
+	< internal/godebug
 	< internal/reflectlite
 	< errors
 	< internal/oserror, math/bits
@@ -106,6 +80,9 @@
 	RUNTIME
 	< io;
 
+	RUNTIME
+	< arena;
+
 	syscall !< io;
 	reflect !< sort;
 
@@ -167,6 +144,7 @@
 	io/fs
 	< internal/testlog
 	< internal/poll
+	< internal/safefilepath
 	< os
 	< os/signal;
 
@@ -179,8 +157,6 @@
 	< path/filepath
 	< io/ioutil;
 
-	os < internal/godebug;
-
 	path/filepath, internal/godebug < os/exec;
 
 	io/ioutil, os/exec, os/signal
@@ -193,7 +169,7 @@
 
 	# FMT is OS (which includes string routines) plus reflect and fmt.
 	# It does not include package log, which should be avoided in core packages.
-	strconv, unicode
+	arena, strconv, unicode
 	< reflect;
 
 	os, reflect
@@ -208,7 +184,9 @@
 	# Misc packages needing only FMT.
 	FMT
 	< html,
+	  internal/dag,
 	  internal/goroot,
+	  internal/types/errors,
 	  mime/quotedprintable,
 	  net/internal/socktest,
 	  net/url,
@@ -216,6 +194,9 @@
 	  text/scanner,
 	  text/tabwriter;
 
+	io, reflect
+	< internal/saferio;
+
 	# encodings
 	# core ones do not use fmt.
 	io, strconv
@@ -229,7 +210,7 @@
 
 	fmt !< encoding/base32, encoding/base64;
 
-	FMT, encoding/base32, encoding/base64
+	FMT, encoding/base32, encoding/base64, internal/saferio
 	< encoding/ascii85, encoding/csv, encoding/gob, encoding/hex,
 	  encoding/json, encoding/pem, encoding/xml, mime;
 
@@ -269,7 +250,7 @@
 	< index/suffixarray;
 
 	# executable parsing
-	FMT, encoding/binary, compress/zlib
+	FMT, encoding/binary, compress/zlib, internal/saferio
 	< runtime/debug
 	< debug/dwarf
 	< debug/elf, debug/gosym, debug/macho, debug/pe, debug/plan9obj, internal/xcoff
@@ -297,7 +278,7 @@
 	math/big, go/token
 	< go/constant;
 
-	container/heap, go/constant, go/parser, regexp
+	container/heap, go/constant, go/parser, internal/types/errors, regexp
 	< go/types;
 
 	FMT, internal/goexperiment
@@ -327,7 +308,12 @@
 	< C
 	< runtime/cgo
 	< CGO
-	< runtime/race, runtime/msan, runtime/asan;
+	< runtime/msan, runtime/asan;
+
+	# runtime/race
+	NONE < runtime/race/internal/amd64v1;
+	NONE < runtime/race/internal/amd64v3;
+	CGO, runtime/race/internal/amd64v1, runtime/race/internal/amd64v3 < runtime/race;
 
 	# Bulk of the standard library must not use cgo.
 	# The prohibition stops at net and os/user.
@@ -407,33 +393,51 @@
 	hash, embed
 	< crypto
 	< crypto/subtle
-	< crypto/internal/subtle
-	< crypto/internal/nistec/fiat
-	< crypto/internal/nistec
-	< crypto/internal/edwards25519/field, golang.org/x/crypto/curve25519/internal/field
-	< crypto/internal/edwards25519
+	< crypto/internal/alias
 	< crypto/cipher;
 
 	crypto/cipher,
 	crypto/internal/boring/bcache
 	< crypto/internal/boring
-	< crypto/boring
+	< crypto/boring;
+
+	crypto/internal/alias
+	< crypto/internal/randutil
+	< crypto/internal/nistec/fiat
+	< crypto/internal/nistec
+	< crypto/internal/edwards25519/field
+	< crypto/internal/edwards25519;
+
+	crypto/boring
 	< crypto/aes, crypto/des, crypto/hmac, crypto/md5, crypto/rc4,
-	  crypto/sha1, crypto/sha256, crypto/sha512
+	  crypto/sha1, crypto/sha256, crypto/sha512;
+
+	crypto/boring, crypto/internal/edwards25519/field
+	< crypto/ecdh;
+
+	crypto/aes,
+	crypto/des,
+	crypto/ecdh,
+	crypto/hmac,
+	crypto/internal/edwards25519,
+	crypto/md5,
+	crypto/rc4,
+	crypto/sha1,
+	crypto/sha256,
+	crypto/sha512
 	< CRYPTO;
 
 	CGO, fmt, net !< CRYPTO;
 
 	# CRYPTO-MATH is core bignum-based crypto - no cgo, net; fmt now ok.
-	CRYPTO, FMT, math/big, embed
+	CRYPTO, FMT, math/big
 	< crypto/internal/boring/bbig
-	< crypto/internal/randutil
 	< crypto/rand
 	< crypto/ed25519
 	< encoding/asn1
 	< golang.org/x/crypto/cryptobyte/asn1
 	< golang.org/x/crypto/cryptobyte
-	< golang.org/x/crypto/curve25519
+	< crypto/internal/bigmod
 	< crypto/dsa, crypto/elliptic, crypto/rsa
 	< crypto/ecdsa
 	< CRYPTO-MATH;
@@ -442,6 +446,7 @@
 
 	# TLS, Prince of Dependencies.
 	CRYPTO-MATH, NET, container/list, encoding/hex, encoding/pem
+	< golang.org/x/crypto/internal/alias
 	< golang.org/x/crypto/internal/subtle
 	< golang.org/x/crypto/chacha20
 	< golang.org/x/crypto/internal/poly1305
@@ -548,14 +553,14 @@
 	internal/fuzz, internal/testlog, runtime/pprof, regexp
 	< testing/internal/testdeps;
 
-	OS, flag, testing, internal/cfg
+	OS, flag, testing, internal/cfg, internal/platform, internal/goroot
 	< internal/testenv;
 
 	OS, encoding/base64
 	< internal/obscuretestdata;
 
 	CGO, OS, fmt
-	< os/signal/internal/pty;
+	< internal/testpty;
 
 	NET, testing, math/rand
 	< golang.org/x/net/nettest;
@@ -568,6 +573,29 @@
 
 	FMT
 	< internal/diff, internal/txtar;
+
+	FMT, crypto/md5, encoding/binary, regexp, sort, text/tabwriter, unsafe,
+	internal/coverage, internal/coverage/uleb128
+	< internal/coverage/cmerge,
+	  internal/coverage/pods,
+	  internal/coverage/slicereader,
+	  internal/coverage/slicewriter;
+
+	internal/coverage/slicereader, internal/coverage/slicewriter
+	< internal/coverage/stringtab
+	< internal/coverage/decodecounter, internal/coverage/decodemeta,
+	  internal/coverage/encodecounter, internal/coverage/encodemeta;
+
+	internal/coverage/cmerge
+	< internal/coverage/cformat;
+
+	runtime/debug,
+	internal/coverage/calloc,
+	internal/coverage/cformat,
+	internal/coverage/decodecounter, internal/coverage/decodemeta,
+	internal/coverage/encodecounter, internal/coverage/encodemeta,
+	internal/coverage/pods
+	< runtime/coverage;
 `
 
 // listStdPkgs returns the same list of packages as "go list std".
@@ -626,11 +654,10 @@
 		if sawImport[pkg] == nil {
 			sawImport[pkg] = map[string]bool{}
 		}
-		ok := policy[pkg]
 		var bad []string
 		for _, imp := range imports {
 			sawImport[pkg][imp] = true
-			if !ok[imp] {
+			if !policy.HasEdge(pkg, imp) {
 				bad = append(bad, imp)
 			}
 		}
@@ -699,187 +726,12 @@
 }
 
 // depsPolicy returns a map m such that m[p][d] == true when p can import d.
-func depsPolicy(t *testing.T) map[string]map[string]bool {
-	allowed := map[string]map[string]bool{"NONE": {}}
-	disallowed := [][2][]string{}
-
-	parseDepsRules(t, func(deps []string, op string, users []string) {
-		if op == "!<" {
-			disallowed = append(disallowed, [2][]string{deps, users})
-			return
-		}
-		for _, u := range users {
-			if allowed[u] != nil {
-				t.Errorf("multiple deps lists for %s", u)
-			}
-			allowed[u] = make(map[string]bool)
-			for _, d := range deps {
-				if allowed[d] == nil {
-					t.Errorf("use of %s before its deps list", d)
-				}
-				allowed[u][d] = true
-			}
-		}
-	})
-
-	// Check for missing deps info.
-	for _, deps := range allowed {
-		for d := range deps {
-			if allowed[d] == nil {
-				t.Errorf("missing deps list for %s", d)
-			}
-		}
+func depsPolicy(t *testing.T) *dag.Graph {
+	g, err := dag.Parse(depsRules)
+	if err != nil {
+		t.Fatal(err)
 	}
-
-	// Complete transitive allowed deps.
-	for k := range allowed {
-		for i := range allowed {
-			for j := range allowed {
-				if i != k && k != j && allowed[i][k] && allowed[k][j] {
-					if i == j {
-						// Can only happen along with a "use of X before deps" error above,
-						// but this error is more specific - it makes clear that reordering the
-						// rules will not be enough to fix the problem.
-						t.Errorf("deps policy cycle: %s < %s < %s", j, k, i)
-					}
-					allowed[i][j] = true
-				}
-			}
-		}
-	}
-
-	// Check negative assertions against completed allowed deps.
-	for _, bad := range disallowed {
-		deps, users := bad[0], bad[1]
-		for _, d := range deps {
-			for _, u := range users {
-				if allowed[u][d] {
-					t.Errorf("deps policy incorrect: assertion failed: %s !< %s", d, u)
-				}
-			}
-		}
-	}
-
-	if t.Failed() {
-		t.FailNow()
-	}
-
-	return allowed
-}
-
-// parseDepsRules parses depsRules, calling save(deps, op, users)
-// for each deps < users or deps !< users rule
-// (op is "<" or "!<").
-func parseDepsRules(t *testing.T, save func(deps []string, op string, users []string)) {
-	p := &depsParser{t: t, lineno: 1, text: depsRules}
-
-	var prev []string
-	var op string
-	for {
-		list, tok := p.nextList()
-		if tok == "" {
-			if prev == nil {
-				break
-			}
-			p.syntaxError("unexpected EOF")
-		}
-		if prev != nil {
-			save(prev, op, list)
-		}
-		prev = list
-		if tok == ";" {
-			prev = nil
-			op = ""
-			continue
-		}
-		if tok != "<" && tok != "!<" {
-			p.syntaxError("missing <")
-		}
-		op = tok
-	}
-}
-
-// A depsParser parses the depsRules syntax described above.
-type depsParser struct {
-	t        *testing.T
-	lineno   int
-	lastWord string
-	text     string
-}
-
-// syntaxError reports a parsing error.
-func (p *depsParser) syntaxError(msg string) {
-	p.t.Fatalf("deps:%d: syntax error: %s near %s", p.lineno, msg, p.lastWord)
-}
-
-// nextList parses and returns a comma-separated list of names.
-func (p *depsParser) nextList() (list []string, token string) {
-	for {
-		tok := p.nextToken()
-		switch tok {
-		case "":
-			if len(list) == 0 {
-				return nil, ""
-			}
-			fallthrough
-		case ",", "<", "!<", ";":
-			p.syntaxError("bad list syntax")
-		}
-		list = append(list, tok)
-
-		tok = p.nextToken()
-		if tok != "," {
-			return list, tok
-		}
-	}
-}
-
-// nextToken returns the next token in the deps rules,
-// one of ";" "," "<" "!<" or a name.
-func (p *depsParser) nextToken() string {
-	for {
-		if p.text == "" {
-			return ""
-		}
-		switch p.text[0] {
-		case ';', ',', '<':
-			t := p.text[:1]
-			p.text = p.text[1:]
-			return t
-
-		case '!':
-			if len(p.text) < 2 || p.text[1] != '<' {
-				p.syntaxError("unexpected token !")
-			}
-			p.text = p.text[2:]
-			return "!<"
-
-		case '#':
-			i := strings.Index(p.text, "\n")
-			if i < 0 {
-				i = len(p.text)
-			}
-			p.text = p.text[i:]
-			continue
-
-		case '\n':
-			p.lineno++
-			fallthrough
-		case ' ', '\t':
-			p.text = p.text[1:]
-			continue
-
-		default:
-			i := strings.IndexAny(p.text, "!;,<#\n \t")
-			if i < 0 {
-				i = len(p.text)
-			}
-			t := p.text[:i]
-			p.text = p.text[i:]
-			p.lastWord = t
-			return t
-		}
-	}
+	return g
 }
 
 // TestStdlibLowercase tests that all standard library package names are
diff --git a/src/go/build/syslist.go b/src/go/build/syslist.go
index 35cffce..78ca565 100644
--- a/src/go/build/syslist.go
+++ b/src/go/build/syslist.go
@@ -33,7 +33,8 @@
 
 // unixOS is the set of GOOS values matched by the "unix" build tag.
 // This is not used for filename matching.
-// This list also appears in cmd/dist/build.go.
+// This list also appears in cmd/dist/build.go and
+// cmd/go/internal/imports/build.go.
 var unixOS = map[string]bool{
 	"aix":       true,
 	"android":   true,
diff --git a/src/go/build/testdata/bads/bad.s b/src/go/build/testdata/bads/bad.s
new file mode 100644
index 0000000..b670f82
--- /dev/null
+++ b/src/go/build/testdata/bads/bad.s
@@ -0,0 +1 @@
+;/
diff --git a/src/go/build/testdata/non_source_tags/non_source_tags.go b/src/go/build/testdata/non_source_tags/non_source_tags.go
new file mode 100644
index 0000000..068acc4
--- /dev/null
+++ b/src/go/build/testdata/non_source_tags/non_source_tags.go
@@ -0,0 +1,5 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package non_source_tags
diff --git a/src/go/build/testdata/non_source_tags/x_arm.go.ignore b/src/go/build/testdata/non_source_tags/x_arm.go.ignore
new file mode 100644
index 0000000..068acc4
--- /dev/null
+++ b/src/go/build/testdata/non_source_tags/x_arm.go.ignore
@@ -0,0 +1,5 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package non_source_tags
diff --git a/src/go/build/zcgo.go b/src/go/build/zcgo.go
index 21fbfdd..3240671 100644
--- a/src/go/build/zcgo.go
+++ b/src/go/build/zcgo.go
@@ -17,6 +17,7 @@
 	"freebsd/amd64": true,
 	"freebsd/arm": true,
 	"freebsd/arm64": true,
+	"freebsd/riscv64": true,
 	"illumos/amd64": true,
 	"ios/amd64": true,
 	"ios/arm64": true,
diff --git a/src/go/constant/value.go b/src/go/constant/value.go
index 36c29d8..ae300c7 100644
--- a/src/go/constant/value.go
+++ b/src/go/constant/value.go
@@ -200,7 +200,13 @@
 	// Use exact fmt formatting if in float64 range (common case):
 	// proceed if f doesn't underflow to 0 or overflow to inf.
 	if x, _ := f.Float64(); f.Sign() == 0 == (x == 0) && !math.IsInf(x, 0) {
-		return fmt.Sprintf("%.6g", x)
+		s := fmt.Sprintf("%.6g", x)
+		if !f.IsInt() && strings.IndexByte(s, '.') < 0 {
+			// f is not an integer, but its string representation
+			// doesn't reflect that. Use more digits. See issue 56220.
+			s = fmt.Sprintf("%g", x)
+		}
+		return s
 	}
 
 	// Out of float64 range. Do approximate manual to decimal
@@ -380,7 +386,14 @@
 func MakeBool(b bool) Value { return boolVal(b) }
 
 // MakeString returns the String value for s.
-func MakeString(s string) Value { return &stringVal{s: s} }
+func MakeString(s string) Value {
+	if s == "" {
+		return &emptyString // common case
+	}
+	return &stringVal{s: s}
+}
+
+var emptyString stringVal
 
 // MakeInt64 returns the Int value for x.
 func MakeInt64(x int64) Value { return int64Val(x) }
diff --git a/src/go/doc/comment/parse.go b/src/go/doc/comment/parse.go
index e8d844c..62a0f8f 100644
--- a/src/go/doc/comment/parse.go
+++ b/src/go/doc/comment/parse.go
@@ -851,9 +851,7 @@
 			return nil, false
 		}
 	}
-	if strings.HasPrefix(text, "*") {
-		text = text[1:]
-	}
+	text = strings.TrimPrefix(text, "*")
 	pkg, name, ok := splitDocName(text)
 	var recv string
 	if ok {
diff --git a/src/go/doc/comment/std_test.go b/src/go/doc/comment/std_test.go
index ae32dcd..89206e6 100644
--- a/src/go/doc/comment/std_test.go
+++ b/src/go/doc/comment/std_test.go
@@ -7,14 +7,13 @@
 import (
 	"internal/diff"
 	"internal/testenv"
-	"os/exec"
 	"sort"
 	"strings"
 	"testing"
 )
 
 func TestStd(t *testing.T) {
-	out, err := exec.Command(testenv.GoToolPath(t), "list", "std").CombinedOutput()
+	out, err := testenv.Command(t, testenv.GoToolPath(t), "list", "std").CombinedOutput()
 	if err != nil {
 		t.Fatalf("%v\n%s", err, out)
 	}
diff --git a/src/go/doc/comment_test.go b/src/go/doc/comment_test.go
index e1e5f15..004ae9d 100644
--- a/src/go/doc/comment_test.go
+++ b/src/go/doc/comment_test.go
@@ -24,12 +24,12 @@
 	pkg := New(pkgs["pkgdoc"], "testdata/pkgdoc", 0)
 
 	var (
-		input           = "[T] and [U] are types, and [T.M] is a method, but [V] is a broken link. [rand.Int] and [crand.Reader] are things.\n"
-		wantHTML        = `<p><a href="#T">T</a> and <a href="#U">U</a> are types, and <a href="#T.M">T.M</a> is a method, but [V] is a broken link. <a href="/math/rand#Int">rand.Int</a> and <a href="/crypto/rand#Reader">crand.Reader</a> are things.` + "\n"
-		wantOldHTML     = "<p>[T] and [U] are <i>types</i>, and [T.M] is a method, but [V] is a broken link. [rand.Int] and [crand.Reader] are things.\n"
-		wantMarkdown    = "[T](#T) and [U](#U) are types, and [T.M](#T.M) is a method, but \\[V] is a broken link. [rand.Int](/math/rand#Int) and [crand.Reader](/crypto/rand#Reader) are things.\n"
-		wantText        = "T and U are types, and T.M is a method, but [V] is a broken link. rand.Int and\ncrand.Reader are things.\n"
-		wantOldText     = "[T] and [U] are types, and [T.M] is a method, but [V] is a broken link.\n[rand.Int] and [crand.Reader] are things.\n"
+		input           = "[T] and [U] are types, and [T.M] is a method, but [V] is a broken link. [rand.Int] and [crand.Reader] are things. [G.M1] and [G.M2] are generic methods.\n"
+		wantHTML        = `<p><a href="#T">T</a> and <a href="#U">U</a> are types, and <a href="#T.M">T.M</a> is a method, but [V] is a broken link. <a href="/math/rand#Int">rand.Int</a> and <a href="/crypto/rand#Reader">crand.Reader</a> are things. <a href="#G.M1">G.M1</a> and <a href="#G.M2">G.M2</a> are generic methods.` + "\n"
+		wantOldHTML     = "<p>[T] and [U] are <i>types</i>, and [T.M] is a method, but [V] is a broken link. [rand.Int] and [crand.Reader] are things. [G.M1] and [G.M2] are generic methods.\n"
+		wantMarkdown    = "[T](#T) and [U](#U) are types, and [T.M](#T.M) is a method, but \\[V] is a broken link. [rand.Int](/math/rand#Int) and [crand.Reader](/crypto/rand#Reader) are things. [G.M1](#G.M1) and [G.M2](#G.M2) are generic methods.\n"
+		wantText        = "T and U are types, and T.M is a method, but [V] is a broken link. rand.Int and\ncrand.Reader are things. G.M1 and G.M2 are generic methods.\n"
+		wantOldText     = "[T] and [U] are types, and [T.M] is a method, but [V] is a broken link.\n[rand.Int] and [crand.Reader] are things. [G.M1] and [G.M2] are generic methods.\n"
 		wantSynopsis    = "T and U are types, and T.M is a method, but [V] is a broken link."
 		wantOldSynopsis = "[T] and [U] are types, and [T.M] is a method, but [V] is a broken link."
 	)
diff --git a/src/go/doc/doc.go b/src/go/doc/doc.go
index 651a2c1..eefadfa 100644
--- a/src/go/doc/doc.go
+++ b/src/go/doc/doc.go
@@ -76,7 +76,7 @@
 
 	// methods
 	// (for functions, these fields have the respective zero value)
-	Recv  string // actual   receiver "T" or "*T"
+	Recv  string // actual   receiver "T" or "*T" possibly followed by type parameters [P1, ..., Pn]
 	Orig  string // original receiver "T" or "*T"
 	Level int    // embedding level; 0 means not embedded
 
@@ -173,7 +173,11 @@
 func (p *Package) collectFuncs(funcs []*Func) {
 	for _, f := range funcs {
 		if f.Recv != "" {
-			p.syms[strings.TrimPrefix(f.Recv, "*")+"."+f.Name] = true
+			r := strings.TrimPrefix(f.Recv, "*")
+			if i := strings.IndexByte(r, '['); i >= 0 {
+				r = r[:i] // remove type parameters
+			}
+			p.syms[r+"."+f.Name] = true
 		} else {
 			p.syms[f.Name] = true
 		}
diff --git a/src/go/doc/example.go b/src/go/doc/example.go
index 6d0459e..65ca885 100644
--- a/src/go/doc/example.go
+++ b/src/go/doc/example.go
@@ -112,7 +112,7 @@
 
 var outputPrefix = lazyregexp.New(`(?i)^[[:space:]]*(unordered )?output:`)
 
-// Extracts the expected output and whether there was a valid output comment
+// Extracts the expected output and whether there was a valid output comment.
 func exampleOutput(b *ast.BlockStmt, comments []*ast.CommentGroup) (output string, unordered, ok bool) {
 	if _, last := lastComment(b, comments); last != nil {
 		// test that it begins with the correct prefix
diff --git a/src/go/doc/headscan.go b/src/go/doc/headscan.go
index f55ca75..82f5fed 100644
--- a/src/go/doc/headscan.go
+++ b/src/go/doc/headscan.go
@@ -16,7 +16,6 @@
 package main
 
 import (
-	"bytes"
 	"flag"
 	"fmt"
 	"go/doc"
@@ -46,7 +45,7 @@
 }
 
 func appendHeadings(list []string, comment string) []string {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	doc.ToHTML(&buf, comment, nil)
 	for s := buf.String(); s != ""; {
 		loc := html_h.FindStringIndex(s)
diff --git a/src/go/doc/reader.go b/src/go/doc/reader.go
index 492e039..8f9fda4 100644
--- a/src/go/doc/reader.go
+++ b/src/go/doc/reader.go
@@ -826,7 +826,7 @@
 func (d *data) Swap(i, j int)      { d.swap(i, j) }
 func (d *data) Less(i, j int) bool { return d.less(i, j) }
 
-// sortBy is a helper function for sorting
+// sortBy is a helper function for sorting.
 func sortBy(less func(i, j int) bool, swap func(i, j int), n int) {
 	sort.Sort(&data{n, swap, less})
 }
diff --git a/src/go/doc/testdata/benchmark.go b/src/go/doc/testdata/benchmark.go
index d27bf11..dbf6b4f 100644
--- a/src/go/doc/testdata/benchmark.go
+++ b/src/go/doc/testdata/benchmark.go
@@ -48,7 +48,7 @@
 // want to measure.
 func (b *B) StopTimer() {
 	if b.timerOn {
-		b.duration += time.Now().Sub(b.start)
+		b.duration += time.Since(b.start)
 		b.timerOn = false
 	}
 }
diff --git a/src/go/doc/testdata/example.go b/src/go/doc/testdata/example.go
index fdeda13..0b70339 100644
--- a/src/go/doc/testdata/example.go
+++ b/src/go/doc/testdata/example.go
@@ -59,7 +59,7 @@
 		// run example
 		t0 := time.Now()
 		eg.F()
-		dt := time.Now().Sub(t0)
+		dt := time.Since(t0)
 
 		// close pipe, restore stdout/stderr, get output
 		w.Close()
diff --git a/src/go/doc/testdata/pkgdoc/doc.go b/src/go/doc/testdata/pkgdoc/doc.go
index 61bd4e3..3f822c7 100644
--- a/src/go/doc/testdata/pkgdoc/doc.go
+++ b/src/go/doc/testdata/pkgdoc/doc.go
@@ -17,3 +17,8 @@
 
 var _ = rand.Int
 var _ = crand.Reader
+
+type G[T any] struct{ x T }
+
+func (g G[T]) M1() {}
+func (g *G[T]) M2() {}
diff --git a/src/go/doc/testdata/testing.go b/src/go/doc/testdata/testing.go
index 6365ffc..d3076c9 100644
--- a/src/go/doc/testdata/testing.go
+++ b/src/go/doc/testdata/testing.go
@@ -219,7 +219,7 @@
 	// a call to runtime.Goexit, record the duration and send
 	// a signal saying that the test is done.
 	defer func() {
-		t.duration = time.Now().Sub(t.start)
+		t.duration = time.Since(t.start)
 		t.signal <- t
 	}()
 
diff --git a/src/go/importer/importer_test.go b/src/go/importer/importer_test.go
index 1b8353e..142efd3 100644
--- a/src/go/importer/importer_test.go
+++ b/src/go/importer/importer_test.go
@@ -11,7 +11,6 @@
 	"internal/testenv"
 	"io"
 	"os"
-	"os/exec"
 	"strings"
 	"testing"
 )
@@ -25,15 +24,12 @@
 	testenv.MustHaveGoBuild(t)
 
 	const thePackage = "math/big"
-	out, err := exec.Command(testenv.GoToolPath(t), "list", "-f={{context.Compiler}}:{{.Target}}", thePackage).CombinedOutput()
+	out, err := testenv.Command(t, testenv.GoToolPath(t), "list", "-export", "-f={{context.Compiler}}:{{.Export}}", thePackage).CombinedOutput()
 	if err != nil {
 		t.Fatalf("go list %s: %v\n%s", thePackage, err, out)
 	}
-	target := strings.TrimSpace(string(out))
-	compiler, target, _ := strings.Cut(target, ":")
-	if !strings.HasSuffix(target, ".a") {
-		t.Fatalf("unexpected package %s target %q (not *.a)", thePackage, target)
-	}
+	export := strings.TrimSpace(string(out))
+	compiler, target, _ := strings.Cut(export, ":")
 
 	if compiler == "gccgo" {
 		t.Skip("golang.org/issue/22500")
diff --git a/src/go/internal/gccgoimporter/ar.go b/src/go/internal/gccgoimporter/ar.go
index 443aa26..9df7934 100644
--- a/src/go/internal/gccgoimporter/ar.go
+++ b/src/go/internal/gccgoimporter/ar.go
@@ -82,7 +82,7 @@
 		}
 		off += arHdrSize
 
-		if bytes.Compare(hdrBuf[arFmagOff:arFmagOff+arFmagSize], []byte(arfmag)) != 0 {
+		if !bytes.Equal(hdrBuf[arFmagOff:arFmagOff+arFmagSize], []byte(arfmag)) {
 			return nil, fmt.Errorf("archive header format header (%q)", hdrBuf[:])
 		}
 
@@ -92,7 +92,7 @@
 		}
 
 		fn := hdrBuf[arNameOff : arNameOff+arNameSize]
-		if fn[0] == '/' && (fn[1] == ' ' || fn[1] == '/' || bytes.Compare(fn[:8], []byte("/SYM64/ ")) == 0) {
+		if fn[0] == '/' && (fn[1] == ' ' || fn[1] == '/' || string(fn[:8]) == "/SYM64/ ") {
 			// Archive symbol table or extended name table,
 			// which we don't care about.
 		} else {
diff --git a/src/go/internal/gccgoimporter/importer_test.go b/src/go/internal/gccgoimporter/importer_test.go
index 8a7ee1a..76b4500 100644
--- a/src/go/internal/gccgoimporter/importer_test.go
+++ b/src/go/internal/gccgoimporter/importer_test.go
@@ -130,12 +130,12 @@
 		t.Skip("This test needs gccgo")
 	}
 
-	verout, err := exec.Command(gpath, "--version").CombinedOutput()
+	verout, err := testenv.Command(t, gpath, "--version").CombinedOutput()
 	if err != nil {
 		t.Logf("%s", verout)
 		t.Fatal(err)
 	}
-	vers := regexp.MustCompile(`([0-9]+)\.([0-9]+)`).FindSubmatch(verout)
+	vers := regexp.MustCompile(`(\d+)\.(\d+)`).FindSubmatch(verout)
 	if len(vers) == 0 {
 		t.Fatalf("could not find version number in %s", verout)
 	}
@@ -171,7 +171,7 @@
 		ofile := filepath.Join(tmpdir, test.pkgpath+".o")
 		afile := filepath.Join(artmpdir, "lib"+test.pkgpath+".a")
 
-		cmd := exec.Command(gpath, "-fgo-pkgpath="+test.pkgpath, "-c", "-o", ofile, gofile)
+		cmd := testenv.Command(t, gpath, "-fgo-pkgpath="+test.pkgpath, "-c", "-o", ofile, gofile)
 		out, err := cmd.CombinedOutput()
 		if err != nil {
 			t.Logf("%s", out)
@@ -180,7 +180,7 @@
 
 		runImporterTest(t, imp, initmap, &test)
 
-		cmd = exec.Command("ar", "cr", afile, ofile)
+		cmd = testenv.Command(t, "ar", "cr", afile, ofile)
 		out, err = cmd.CombinedOutput()
 		if err != nil {
 			t.Logf("%s", out)
diff --git a/src/go/internal/gccgoimporter/parser.go b/src/go/internal/gccgoimporter/parser.go
index 536083a..de9df0b 100644
--- a/src/go/internal/gccgoimporter/parser.go
+++ b/src/go/internal/gccgoimporter/parser.go
@@ -5,7 +5,6 @@
 package gccgoimporter
 
 import (
-	"bytes"
 	"errors"
 	"fmt"
 	"go/constant"
@@ -129,16 +128,16 @@
 	if p.tok == scanner.EOF {
 		p.error("unexpected EOF")
 	}
-	var buf bytes.Buffer
-	buf.WriteString(p.scanner.TokenText())
+	var b strings.Builder
+	b.WriteString(p.scanner.TokenText())
 	// This loop needs to examine each character before deciding whether to consume it. If we see a semicolon,
 	// we need to let it be consumed by p.next().
 	for ch := p.scanner.Peek(); ch != '\n' && ch != ';' && ch != scanner.EOF && p.scanner.Whitespace&(1<<uint(ch)) == 0; ch = p.scanner.Peek() {
-		buf.WriteRune(ch)
+		b.WriteRune(ch)
 		p.scanner.Next()
 	}
 	p.next()
-	return buf.String()
+	return b.String()
 }
 
 func (p *parser) next() {
diff --git a/src/go/internal/gcimporter/gcimporter.go b/src/go/internal/gcimporter/gcimporter.go
index 0b27a95..2140a9f 100644
--- a/src/go/internal/gcimporter/gcimporter.go
+++ b/src/go/internal/gcimporter/gcimporter.go
@@ -7,6 +7,7 @@
 
 import (
 	"bufio"
+	"bytes"
 	"fmt"
 	"go/build"
 	"go/token"
@@ -14,14 +15,57 @@
 	"internal/pkgbits"
 	"io"
 	"os"
+	"os/exec"
 	"path/filepath"
 	"strings"
+	"sync"
 )
 
 // debugging/development support
 const debug = false
 
-var pkgExts = [...]string{".a", ".o"}
+var exportMap sync.Map // package dir → func() (string, bool)
+
+// lookupGorootExport returns the location of the export data
+// (normally found in the build cache, but located in GOROOT/pkg
+// in prior Go releases) for the package located in pkgDir.
+//
+// (We use the package's directory instead of its import path
+// mainly to simplify handling of the packages in src/vendor
+// and cmd/vendor.)
+func lookupGorootExport(pkgDir string) (string, bool) {
+	f, ok := exportMap.Load(pkgDir)
+	if !ok {
+		var (
+			listOnce   sync.Once
+			exportPath string
+		)
+		f, _ = exportMap.LoadOrStore(pkgDir, func() (string, bool) {
+			listOnce.Do(func() {
+				cmd := exec.Command("go", "list", "-export", "-f", "{{.Export}}", pkgDir)
+				cmd.Dir = build.Default.GOROOT
+				var output []byte
+				output, err := cmd.Output()
+				if err != nil {
+					return
+				}
+
+				exports := strings.Split(string(bytes.TrimSpace(output)), "\n")
+				if len(exports) != 1 {
+					return
+				}
+
+				exportPath = exports[0]
+			})
+
+			return exportPath, exportPath != ""
+		})
+	}
+
+	return f.(func() (string, bool))()
+}
+
+var pkgExts = [...]string{".a", ".o"} // a file from the build cache will have no extension
 
 // FindPkg returns the filename and unique package id for an import
 // path based on package information provided by build.Import (using
@@ -43,10 +87,17 @@
 		}
 		bp, _ := build.Import(path, srcDir, build.FindOnly|build.AllowBinary)
 		if bp.PkgObj == "" {
-			id = path // make sure we have an id to print in error message
-			return
+			var ok bool
+			if bp.Goroot && bp.Dir != "" {
+				filename, ok = lookupGorootExport(bp.Dir)
+			}
+			if !ok {
+				id = path // make sure we have an id to print in error message
+				return
+			}
+		} else {
+			noext = strings.TrimSuffix(bp.PkgObj, ".a")
 		}
-		noext = strings.TrimSuffix(bp.PkgObj, ".a")
 		id = bp.ImportPath
 
 	case build.IsLocalImport(path):
@@ -68,6 +119,11 @@
 		}
 	}
 
+	if filename != "" {
+		if f, err := os.Stat(filename); err == nil && !f.IsDir() {
+			return
+		}
+	}
 	// try extensions
 	for _, ext := range pkgExts {
 		filename = noext + ext
diff --git a/src/go/internal/gcimporter/gcimporter_test.go b/src/go/internal/gcimporter/gcimporter_test.go
index b32de17..f2202ab 100644
--- a/src/go/internal/gcimporter/gcimporter_test.go
+++ b/src/go/internal/gcimporter/gcimporter_test.go
@@ -8,9 +8,11 @@
 	"bytes"
 	"fmt"
 	"internal/goexperiment"
+	"internal/goroot"
 	"internal/testenv"
 	"os"
 	"os/exec"
+	"path"
 	"path/filepath"
 	"runtime"
 	"strings"
@@ -32,26 +34,33 @@
 	os.Exit(m.Run())
 }
 
-// skipSpecialPlatforms causes the test to be skipped for platforms where
-// builders (build.golang.org) don't have access to compiled packages for
-// import.
-func skipSpecialPlatforms(t *testing.T) {
-	switch platform := runtime.GOOS + "-" + runtime.GOARCH; platform {
-	case "darwin-arm64":
-		t.Skipf("no compiled packages available for import on %s", platform)
-	}
-}
-
 // compile runs the compiler on filename, with dirname as the working directory,
 // and writes the output file to outdirname.
-func compile(t *testing.T, dirname, filename, outdirname string) string {
+// compile gives the resulting package a packagepath of testdata/<filebasename>.
+func compile(t *testing.T, dirname, filename, outdirname string, packagefiles map[string]string) string {
 	// filename must end with ".go"
-	if !strings.HasSuffix(filename, ".go") {
+	basename, ok := strings.CutSuffix(filepath.Base(filename), ".go")
+	if !ok {
 		t.Fatalf("filename doesn't end in .go: %s", filename)
 	}
-	basename := filepath.Base(filename)
-	outname := filepath.Join(outdirname, basename[:len(basename)-2]+"o")
-	cmd := exec.Command(testenv.GoToolPath(t), "tool", "compile", "-p", strings.TrimSuffix(outname, ".o"), "-o", outname, filename)
+	objname := basename + ".o"
+	outname := filepath.Join(outdirname, objname)
+
+	importcfgfile := os.DevNull
+	if len(packagefiles) > 0 {
+		importcfgfile = filepath.Join(outdirname, basename) + ".importcfg"
+		importcfg := new(bytes.Buffer)
+		fmt.Fprintf(importcfg, "# import config")
+		for k, v := range packagefiles {
+			fmt.Fprintf(importcfg, "\npackagefile %s=%s\n", k, v)
+		}
+		if err := os.WriteFile(importcfgfile, importcfg.Bytes(), 0655); err != nil {
+			t.Fatal(err)
+		}
+	}
+
+	pkgpath := path.Join("testdata", basename)
+	cmd := testenv.Command(t, testenv.GoToolPath(t), "tool", "compile", "-p", pkgpath, "-D", "testdata", "-importcfg", importcfgfile, "-o", outname, filename)
 	cmd.Dir = dirname
 	out, err := cmd.CombinedOutput()
 	if err != nil {
@@ -73,39 +82,8 @@
 	return pkg
 }
 
-const maxTime = 30 * time.Second
-
 var pkgExts = [...]string{".a", ".o"} // keep in sync with gcimporter.go
 
-func testDir(t *testing.T, dir string, endTime time.Time) (nimports int) {
-	dirname := filepath.Join(testenv.GOROOT(t), "pkg", runtime.GOOS+"_"+runtime.GOARCH, dir)
-	list, err := os.ReadDir(dirname)
-	if err != nil {
-		t.Fatalf("testDir(%s): %s", dirname, err)
-	}
-	for _, f := range list {
-		if time.Now().After(endTime) {
-			t.Log("testing time used up")
-			return
-		}
-		switch {
-		case !f.IsDir():
-			// try extensions
-			for _, ext := range pkgExts {
-				if strings.HasSuffix(f.Name(), ext) {
-					name := f.Name()[0 : len(f.Name())-len(ext)] // remove extension
-					if testPath(t, filepath.Join(dir, name), dir) != nil {
-						nimports++
-					}
-				}
-			}
-		case f.IsDir():
-			nimports += testDir(t, filepath.Join(dir, f.Name()), endTime)
-		}
-	}
-	return
-}
-
 func mktmpdir(t *testing.T) string {
 	tmpdir, err := os.MkdirTemp("", "gcimporter_test")
 	if err != nil {
@@ -124,6 +102,8 @@
 		t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
 	}
 
+	testenv.MustHaveGoBuild(t)
+
 	testfiles := map[string][]string{
 		"exports.go":  {"go/ast", "go/token"},
 		"generics.go": nil,
@@ -139,7 +119,16 @@
 		tmpdir := mktmpdir(t)
 		defer os.RemoveAll(tmpdir)
 
-		compile(t, "testdata", testfile, filepath.Join(tmpdir, "testdata"))
+		packageFiles := map[string]string{}
+		for _, pkg := range wantImports {
+			export, _ := FindPkg(pkg, "testdata")
+			if export == "" {
+				t.Fatalf("no export data found for %s", pkg)
+			}
+			packageFiles[pkg] = export
+		}
+
+		compile(t, "testdata", testfile, filepath.Join(tmpdir, "testdata"), packageFiles)
 		path := "./testdata/" + strings.TrimSuffix(testfile, ".go")
 
 		if pkg := testPath(t, path, tmpdir); pkg != nil {
@@ -157,11 +146,17 @@
 }
 
 func TestImportTypeparamTests(t *testing.T) {
+	if testing.Short() {
+		t.Skipf("in short mode, skipping test that requires export data for all of std")
+	}
+
 	// This package only handles gc export data.
 	if runtime.Compiler != "gc" {
 		t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
 	}
 
+	testenv.MustHaveGoBuild(t)
+
 	tmpdir := mktmpdir(t)
 	defer os.RemoveAll(tmpdir)
 
@@ -173,12 +168,15 @@
 		t.Fatal(err)
 	}
 
-	skip := map[string]string{
-		"equal.go":      "inconsistent embedded sorting", // TODO(rfindley): investigate this.
-		"nested.go":     "fails to compile",              // TODO(rfindley): investigate this.
-		"issue50417.go": "inconsistent interface member sorting",
-		"issue53419.go": "fails to compile",
-		"issue53477.go": "fails to compile",
+	var skip map[string]string
+	if !goexperiment.Unified {
+		// The Go 1.18 frontend still fails several cases.
+		skip = map[string]string{
+			"equal.go":      "inconsistent embedded sorting", // TODO(rfindley): investigate this.
+			"nested.go":     "fails to compile",              // TODO(rfindley): investigate this.
+			"issue47631.go": "can not handle local type declarations",
+			"issue55101.go": "fails to compile",
+		}
 	}
 
 	for _, entry := range list {
@@ -206,7 +204,11 @@
 
 			// Compile and import, and compare the resulting package with the package
 			// that was type-checked directly.
-			compile(t, rootDir, entry.Name(), filepath.Join(tmpdir, "testdata"))
+			pkgFiles, err := goroot.PkgfileMap()
+			if err != nil {
+				t.Fatal(err)
+			}
+			compile(t, rootDir, entry.Name(), filepath.Join(tmpdir, "testdata"), pkgFiles)
 			pkgName := strings.TrimSuffix(entry.Name(), ".go")
 			imported := importPkg(t, "./testdata/"+pkgName, tmpdir)
 			checked := checkFile(t, filename, src)
@@ -275,7 +277,7 @@
 }
 
 func TestVersionHandling(t *testing.T) {
-	skipSpecialPlatforms(t)
+	testenv.MustHaveGoBuild(t)
 
 	// This package only handles gc export data.
 	if runtime.Compiler != "gc" {
@@ -368,18 +370,39 @@
 }
 
 func TestImportStdLib(t *testing.T) {
-	skipSpecialPlatforms(t)
+	if testing.Short() {
+		t.Skip("the imports can be expensive, and this test is especially slow when the build cache is empty")
+	}
+	testenv.MustHaveGoBuild(t)
 
 	// This package only handles gc export data.
 	if runtime.Compiler != "gc" {
 		t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
 	}
 
-	dt := maxTime
-	if testing.Short() && testenv.Builder() == "" {
-		dt = 10 * time.Millisecond
+	// Get list of packages in stdlib. Filter out test-only packages with {{if .GoFiles}} check.
+	var stderr bytes.Buffer
+	cmd := exec.Command("go", "list", "-f", "{{if .GoFiles}}{{.ImportPath}}{{end}}", "std")
+	cmd.Stderr = &stderr
+	out, err := cmd.Output()
+	if err != nil {
+		t.Fatalf("failed to run go list to determine stdlib packages: %v\nstderr:\n%v", err, stderr.String())
 	}
-	nimports := testDir(t, "", time.Now().Add(dt)) // installed packages
+	pkgs := strings.Fields(string(out))
+
+	var nimports int
+	for _, pkg := range pkgs {
+		t.Run(pkg, func(t *testing.T) {
+			if testPath(t, pkg, filepath.Join(testenv.GOROOT(t), "src", path.Dir(pkg))) != nil {
+				nimports++
+			}
+		})
+	}
+	const minPkgs = 225 // 'GOOS=plan9 go1.18 list std | wc -l' reports 228; most other platforms have more.
+	if len(pkgs) < minPkgs {
+		t.Fatalf("too few packages (%d) were imported", nimports)
+	}
+
 	t.Logf("tested %d imports", nimports)
 }
 
@@ -408,7 +431,7 @@
 }
 
 func TestImportedTypes(t *testing.T) {
-	skipSpecialPlatforms(t)
+	testenv.MustHaveGoBuild(t)
 
 	// This package only handles gc export data.
 	if runtime.Compiler != "gc" {
@@ -461,14 +484,6 @@
 		return // not an interface
 	}
 
-	// The unified IR importer always sets interface method receiver
-	// parameters to point to the Interface type, rather than the Named.
-	// See #49906.
-	var want types.Type = named
-	if goexperiment.Unified {
-		want = iface
-	}
-
 	// check explicitly declared methods
 	for i := 0; i < iface.NumExplicitMethods(); i++ {
 		m := iface.ExplicitMethod(i)
@@ -477,8 +492,8 @@
 			t.Errorf("%s: missing receiver type", m)
 			continue
 		}
-		if recv.Type() != want {
-			t.Errorf("%s: got recv type %s; want %s", m, recv.Type(), want)
+		if recv.Type() != named {
+			t.Errorf("%s: got recv type %s; want %s", m, recv.Type(), named)
 		}
 	}
 
@@ -492,7 +507,7 @@
 }
 
 func TestIssue5815(t *testing.T) {
-	skipSpecialPlatforms(t)
+	testenv.MustHaveGoBuild(t)
 
 	// This package only handles gc export data.
 	if runtime.Compiler != "gc" {
@@ -521,7 +536,7 @@
 
 // Smoke test to ensure that imported methods get the correct package.
 func TestCorrectMethodPackage(t *testing.T) {
-	skipSpecialPlatforms(t)
+	testenv.MustHaveGoBuild(t)
 
 	// This package only handles gc export data.
 	if runtime.Compiler != "gc" {
@@ -545,7 +560,7 @@
 }
 
 func TestIssue13566(t *testing.T) {
-	skipSpecialPlatforms(t)
+	testenv.MustHaveGoBuild(t)
 
 	// This package only handles gc export data.
 	if runtime.Compiler != "gc" {
@@ -569,8 +584,14 @@
 	if err != nil {
 		t.Fatal(err)
 	}
-	compile(t, "testdata", "a.go", testoutdir)
-	compile(t, testoutdir, bpath, testoutdir)
+
+	jsonExport, _ := FindPkg("encoding/json", "testdata")
+	if jsonExport == "" {
+		t.Fatalf("no export data found for encoding/json")
+	}
+
+	compile(t, "testdata", "a.go", testoutdir, map[string]string{"encoding/json": jsonExport})
+	compile(t, testoutdir, bpath, testoutdir, map[string]string{"testdata/a": filepath.Join(testoutdir, "a.o")})
 
 	// import must succeed (test for issue at hand)
 	pkg := importPkg(t, "./testdata/b", tmpdir)
@@ -583,8 +604,32 @@
 	}
 }
 
+func TestTypeNamingOrder(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	// This package only handles gc export data.
+	if runtime.Compiler != "gc" {
+		t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
+	}
+
+	// On windows, we have to set the -D option for the compiler to avoid having a drive
+	// letter and an illegal ':' in the import path - just skip it (see also issue #3483).
+	if runtime.GOOS == "windows" {
+		t.Skip("avoid dealing with relative paths/drive letters on windows")
+	}
+
+	tmpdir := mktmpdir(t)
+	defer os.RemoveAll(tmpdir)
+	testoutdir := filepath.Join(tmpdir, "testdata")
+
+	compile(t, "testdata", "g.go", testoutdir, nil)
+
+	// import must succeed (test for issue at hand)
+	_ = importPkg(t, "./testdata/g", tmpdir)
+}
+
 func TestIssue13898(t *testing.T) {
-	skipSpecialPlatforms(t)
+	testenv.MustHaveGoBuild(t)
 
 	// This package only handles gc export data.
 	if runtime.Compiler != "gc" {
@@ -631,7 +676,7 @@
 }
 
 func TestIssue15517(t *testing.T) {
-	skipSpecialPlatforms(t)
+	testenv.MustHaveGoBuild(t)
 
 	// This package only handles gc export data.
 	if runtime.Compiler != "gc" {
@@ -647,7 +692,7 @@
 	tmpdir := mktmpdir(t)
 	defer os.RemoveAll(tmpdir)
 
-	compile(t, "testdata", "p.go", filepath.Join(tmpdir, "testdata"))
+	compile(t, "testdata", "p.go", filepath.Join(tmpdir, "testdata"), nil)
 
 	// Multiple imports of p must succeed without redeclaration errors.
 	// We use an import path that's not cleaned up so that the eventual
@@ -671,7 +716,7 @@
 }
 
 func TestIssue15920(t *testing.T) {
-	skipSpecialPlatforms(t)
+	testenv.MustHaveGoBuild(t)
 
 	// This package only handles gc export data.
 	if runtime.Compiler != "gc" {
@@ -688,7 +733,7 @@
 }
 
 func TestIssue20046(t *testing.T) {
-	skipSpecialPlatforms(t)
+	testenv.MustHaveGoBuild(t)
 
 	// This package only handles gc export data.
 	if runtime.Compiler != "gc" {
@@ -709,7 +754,7 @@
 	}
 }
 func TestIssue25301(t *testing.T) {
-	skipSpecialPlatforms(t)
+	testenv.MustHaveGoBuild(t)
 
 	// This package only handles gc export data.
 	if runtime.Compiler != "gc" {
@@ -726,7 +771,7 @@
 }
 
 func TestIssue25596(t *testing.T) {
-	skipSpecialPlatforms(t)
+	testenv.MustHaveGoBuild(t)
 
 	// This package only handles gc export data.
 	if runtime.Compiler != "gc" {
@@ -742,19 +787,38 @@
 	compileAndImportPkg(t, "issue25596")
 }
 
+func TestIssue57015(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	// This package only handles gc export data.
+	if runtime.Compiler != "gc" {
+		t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
+	}
+
+	// On windows, we have to set the -D option for the compiler to avoid having a drive
+	// letter and an illegal ':' in the import path - just skip it (see also issue #3483).
+	if runtime.GOOS == "windows" {
+		t.Skip("avoid dealing with relative paths/drive letters on windows")
+	}
+
+	compileAndImportPkg(t, "issue57015")
+}
+
 func importPkg(t *testing.T, path, srcDir string) *types.Package {
 	fset := token.NewFileSet()
 	pkg, err := Import(fset, make(map[string]*types.Package), path, srcDir, nil)
 	if err != nil {
+		t.Helper()
 		t.Fatal(err)
 	}
 	return pkg
 }
 
 func compileAndImportPkg(t *testing.T, name string) *types.Package {
+	t.Helper()
 	tmpdir := mktmpdir(t)
 	defer os.RemoveAll(tmpdir)
-	compile(t, "testdata", name+".go", filepath.Join(tmpdir, "testdata"))
+	compile(t, "testdata", name+".go", filepath.Join(tmpdir, "testdata"), nil)
 	return importPkg(t, "./testdata/"+name, tmpdir)
 }
 
@@ -762,6 +826,7 @@
 	if obj := scope.Lookup(name); obj != nil {
 		return obj
 	}
+	t.Helper()
 	t.Fatalf("%s not found", name)
 	return nil
 }
diff --git a/src/go/internal/gcimporter/iimport.go b/src/go/internal/gcimporter/iimport.go
index f9eaa0b..9e3c945 100644
--- a/src/go/internal/gcimporter/iimport.go
+++ b/src/go/internal/gcimporter/iimport.go
@@ -15,7 +15,9 @@
 	"go/constant"
 	"go/token"
 	"go/types"
+	"internal/saferio"
 	"io"
+	"math"
 	"math/big"
 	"sort"
 	"strings"
@@ -103,12 +105,16 @@
 		errorf("unknown iexport format version %d", version)
 	}
 
-	sLen := int64(r.uint64())
-	dLen := int64(r.uint64())
+	sLen := r.uint64()
+	dLen := r.uint64()
 
-	data := make([]byte, sLen+dLen)
-	if _, err := io.ReadFull(r, data); err != nil {
-		errorf("cannot read %d bytes of stringData and declData: %s", len(data), err)
+	if sLen > math.MaxUint64-dLen {
+		errorf("lengths out of range (%d, %d)", sLen, dLen)
+	}
+
+	data, err := saferio.ReadData(r, sLen+dLen)
+	if err != nil {
+		errorf("cannot read %d bytes of stringData and declData: %s", sLen+dLen, err)
 	}
 	stringData := data[:sLen]
 	declData := data[sLen:]
@@ -342,7 +348,7 @@
 
 	case 'T', 'U':
 		// Types can be recursive. We need to setup a stub
-		// declaration before recursing.
+		// declaration before recurring.
 		obj := types.NewTypeName(pos, r.currPkg, name, nil)
 		named := types.NewNamed(obj, nil, nil)
 		// Declare obj before calling r.tparamList, so the new type name is recognized
diff --git a/src/go/internal/gcimporter/support.go b/src/go/internal/gcimporter/support.go
index af3b6cb..7ed8c9a 100644
--- a/src/go/internal/gcimporter/support.go
+++ b/src/go/internal/gcimporter/support.go
@@ -167,3 +167,17 @@
 	idx     pkgbits.Index
 	derived bool
 }
+
+// See cmd/compile/internal/types.SplitVargenSuffix.
+func splitVargenSuffix(name string) (base, suffix string) {
+	i := len(name)
+	for i > 0 && name[i-1] >= '0' && name[i-1] <= '9' {
+		i--
+	}
+	const dot = "·"
+	if i >= len(dot) && name[i-len(dot):i] == dot {
+		i -= len(dot)
+		return name[:i], name[i:]
+	}
+	return name, ""
+}
diff --git a/src/go/internal/gcimporter/testdata/g.go b/src/go/internal/gcimporter/testdata/g.go
new file mode 100644
index 0000000..301c142
--- /dev/null
+++ b/src/go/internal/gcimporter/testdata/g.go
@@ -0,0 +1,23 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Input for TestTypeNamingOrder
+
+// ensures that the order in which "type A B" declarations are
+// processed is correct; this was a problem for unified IR imports.
+
+package g
+
+type Client struct {
+	common service
+	A      *AService
+	B      *BService
+}
+
+type service struct {
+	client *Client
+}
+
+type AService service
+type BService service
diff --git a/src/go/internal/gcimporter/testdata/issue57015.go b/src/go/internal/gcimporter/testdata/issue57015.go
new file mode 100644
index 0000000..b6be811
--- /dev/null
+++ b/src/go/internal/gcimporter/testdata/issue57015.go
@@ -0,0 +1,16 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package issue57015
+
+type E error
+
+type X[T any] struct {}
+
+func F() X[interface {
+	E
+}] {
+	panic(0)
+}
+
diff --git a/src/go/internal/gcimporter/ureader.go b/src/go/internal/gcimporter/ureader.go
index 3b14232..ffd8402 100644
--- a/src/go/internal/gcimporter/ureader.go
+++ b/src/go/internal/gcimporter/ureader.go
@@ -1,5 +1,3 @@
-// UNREVIEWED
-
 // Copyright 2021 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
@@ -31,6 +29,10 @@
 	// laterFns holds functions that need to be invoked at the end of
 	// import reading.
 	laterFns []func()
+
+	// ifaces holds a list of constructed Interfaces, which need to have
+	// Complete called after importing is done.
+	ifaces []*types.Interface
 }
 
 // later adds a function to be invoked at the end of import reading.
@@ -60,7 +62,7 @@
 
 	r := pr.newReader(pkgbits.RelocMeta, pkgbits.PublicRootIdx, pkgbits.SyncPublic)
 	pkg := r.pkg()
-	r.Bool() // has init
+	r.Bool() // TODO(mdempsky): Remove; was "has init"
 
 	for i, n := 0, r.Len(); i < n; i++ {
 		// As if r.obj(), but avoiding the Scope.Lookup call,
@@ -77,6 +79,10 @@
 		fn()
 	}
 
+	for _, iface := range pr.ifaces {
+		iface.Complete()
+	}
+
 	pkg.MarkComplete()
 	return pkg
 }
@@ -114,6 +120,17 @@
 	}
 }
 
+func (pr *pkgReader) tempReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader {
+	return &reader{
+		Decoder: pr.TempDecoder(k, idx, marker),
+		p:       pr,
+	}
+}
+
+func (pr *pkgReader) retireReader(r *reader) {
+	pr.RetireDecoder(&r.Decoder)
+}
+
 // @@@ Positions
 
 func (r *reader) pos() token.Pos {
@@ -138,26 +155,29 @@
 		return b
 	}
 
-	r := pr.newReader(pkgbits.RelocPosBase, idx, pkgbits.SyncPosBase)
+	var filename string
+	{
+		r := pr.tempReader(pkgbits.RelocPosBase, idx, pkgbits.SyncPosBase)
 
-	// Within types2, position bases have a lot more details (e.g.,
-	// keeping track of where //line directives appeared exactly).
-	//
-	// For go/types, we just track the file name.
+		// Within types2, position bases have a lot more details (e.g.,
+		// keeping track of where //line directives appeared exactly).
+		//
+		// For go/types, we just track the file name.
 
-	filename := r.String()
+		filename = r.String()
 
-	if r.Bool() { // file base
-		// Was: "b = token.NewTrimmedFileBase(filename, true)"
-	} else { // line base
-		pos := r.pos()
-		line := r.Uint()
-		col := r.Uint()
+		if r.Bool() { // file base
+			// Was: "b = token.NewTrimmedFileBase(filename, true)"
+		} else { // line base
+			pos := r.pos()
+			line := r.Uint()
+			col := r.Uint()
 
-		// Was: "b = token.NewLineBase(pos, filename, true, line, col)"
-		_, _, _ = pos, line, col
+			// Was: "b = token.NewLineBase(pos, filename, true, line, col)"
+			_, _, _ = pos, line, col
+		}
+		pr.retireReader(r)
 	}
-
 	b := filename
 	pr.posBases[idx] = b
 	return b
@@ -198,21 +218,49 @@
 	}
 
 	name := r.String()
-	height := r.Len()
 
-	// Was: "pkg := types.NewPackageHeight(path, name, height)"
-	pkg, _ := types.NewPackage(path, name), height
+	pkg := types.NewPackage(path, name)
 	r.p.imports[path] = pkg
 
 	imports := make([]*types.Package, r.Len())
 	for i := range imports {
 		imports[i] = r.pkg()
 	}
-	pkg.SetImports(imports)
+
+	// The documentation for (*types.Package).Imports requires
+	// flattening the import graph when reading from export data, as
+	// obviously incorrect as that is.
+	//
+	// TODO(mdempsky): Remove this if go.dev/issue/54096 is accepted.
+	pkg.SetImports(flattenImports(imports))
 
 	return pkg
 }
 
+// flattenImports returns the transitive closure of all imported
+// packages rooted from pkgs.
+func flattenImports(pkgs []*types.Package) []*types.Package {
+	var res []*types.Package
+	seen := make(map[*types.Package]struct{})
+	for _, pkg := range pkgs {
+		if _, ok := seen[pkg]; ok {
+			continue
+		}
+		seen[pkg] = struct{}{}
+		res = append(res, pkg)
+
+		// pkg.Imports() is already flattened.
+		for _, pkg := range pkg.Imports() {
+			if _, ok := seen[pkg]; ok {
+				continue
+			}
+			seen[pkg] = struct{}{}
+			res = append(res, pkg)
+		}
+	}
+	return res
+}
+
 // @@@ Types
 
 func (r *reader) typ() types.Type {
@@ -241,12 +289,15 @@
 		return typ
 	}
 
-	r := pr.newReader(pkgbits.RelocType, idx, pkgbits.SyncTypeIdx)
-	r.dict = dict
+	var typ types.Type
+	{
+		r := pr.tempReader(pkgbits.RelocType, idx, pkgbits.SyncTypeIdx)
+		r.dict = dict
 
-	typ := r.doTyp()
-	assert(typ != nil)
-
+		typ = r.doTyp()
+		assert(typ != nil)
+		pr.retireReader(r)
+	}
 	// See comment in pkgReader.typIdx explaining how this happens.
 	if prev := *where; prev != nil {
 		return prev
@@ -349,6 +400,16 @@
 	if implicit {
 		iface.MarkImplicit()
 	}
+
+	// We need to call iface.Complete(), but if there are any embedded
+	// defined types, then we may not have set their underlying
+	// interface type yet. So we need to defer calling Complete until
+	// after we've called SetUnderlying everywhere.
+	//
+	// TODO(mdempsky): After CL 424876 lands, it should be safe to call
+	// iface.Complete() immediately.
+	r.p.ifaces = append(r.p.ifaces, iface)
+
 	return iface
 }
 
@@ -402,18 +463,30 @@
 }
 
 func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types.Package, string) {
-	rname := pr.newReader(pkgbits.RelocName, idx, pkgbits.SyncObject1)
 
-	objPkg, objName := rname.qualifiedIdent()
-	assert(objName != "")
+	var objPkg *types.Package
+	var objName string
+	var tag pkgbits.CodeObj
+	{
+		rname := pr.tempReader(pkgbits.RelocName, idx, pkgbits.SyncObject1)
 
-	tag := pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj))
+		objPkg, objName = rname.qualifiedIdent()
+		assert(objName != "")
+
+		tag = pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj))
+		pr.retireReader(rname)
+	}
 
 	if tag == pkgbits.ObjStub {
 		assert(objPkg == nil || objPkg == types.Unsafe)
 		return objPkg, objName
 	}
 
+	// Ignore local types promoted to global scope (#55110).
+	if _, suffix := splitVargenSuffix(objName); suffix != "" {
+		return objPkg, objName
+	}
+
 	if objPkg.Scope().Lookup(objName) == nil {
 		dict := pr.objDictIdx(idx)
 
@@ -454,15 +527,32 @@
 
 			named.SetTypeParams(r.typeParamNames())
 
-			// TODO(mdempsky): Rewrite receiver types to underlying is an
-			// Interface? The go/types importer does this (I think because
-			// unit tests expected that), but cmd/compile doesn't care
-			// about it, so maybe we can avoid worrying about that here.
-			rhs := r.typ()
-			r.p.later(func() {
-				underlying := rhs.Underlying()
-				named.SetUnderlying(underlying)
-			})
+			underlying := r.typ().Underlying()
+
+			// If the underlying type is an interface, we need to
+			// duplicate its methods so we can replace the receiver
+			// parameter's type (#49906).
+			if iface, ok := underlying.(*types.Interface); ok && iface.NumExplicitMethods() != 0 {
+				methods := make([]*types.Func, iface.NumExplicitMethods())
+				for i := range methods {
+					fn := iface.ExplicitMethod(i)
+					sig := fn.Type().(*types.Signature)
+
+					recv := types.NewVar(fn.Pos(), fn.Pkg(), "", named)
+					methods[i] = types.NewFunc(fn.Pos(), fn.Pkg(), fn.Name(), types.NewSignature(recv, sig.Params(), sig.Results(), sig.Variadic()))
+				}
+
+				embeds := make([]types.Type, iface.NumEmbeddeds())
+				for i := range embeds {
+					embeds[i] = iface.EmbeddedType(i)
+				}
+
+				newIface := types.NewInterfaceType(methods, embeds)
+				r.p.ifaces = append(r.p.ifaces, newIface)
+				underlying = newIface
+			}
+
+			named.SetUnderlying(underlying)
 
 			for i, n := 0, r.Len(); i < n; i++ {
 				named.AddMethod(r.method())
@@ -479,25 +569,28 @@
 }
 
 func (pr *pkgReader) objDictIdx(idx pkgbits.Index) *readerDict {
-	r := pr.newReader(pkgbits.RelocObjDict, idx, pkgbits.SyncObject1)
 
 	var dict readerDict
 
-	if implicits := r.Len(); implicits != 0 {
-		errorf("unexpected object with %v implicit type parameter(s)", implicits)
-	}
+	{
+		r := pr.tempReader(pkgbits.RelocObjDict, idx, pkgbits.SyncObject1)
+		if implicits := r.Len(); implicits != 0 {
+			errorf("unexpected object with %v implicit type parameter(s)", implicits)
+		}
 
-	dict.bounds = make([]typeInfo, r.Len())
-	for i := range dict.bounds {
-		dict.bounds[i] = r.typInfo()
-	}
+		dict.bounds = make([]typeInfo, r.Len())
+		for i := range dict.bounds {
+			dict.bounds[i] = r.typInfo()
+		}
 
-	dict.derived = make([]derivedInfo, r.Len())
-	dict.derivedTypes = make([]types.Type, len(dict.derived))
-	for i := range dict.derived {
-		dict.derived[i] = derivedInfo{r.Reloc(pkgbits.RelocType), r.Bool()}
-	}
+		dict.derived = make([]derivedInfo, r.Len())
+		dict.derivedTypes = make([]types.Type, len(dict.derived))
+		for i := range dict.derived {
+			dict.derived[i] = derivedInfo{r.Reloc(pkgbits.RelocType), r.Bool()}
+		}
 
+		pr.retireReader(r)
+	}
 	// function references follow, but reader doesn't need those
 
 	return &dict
diff --git a/src/go/internal/srcimporter/srcimporter.go b/src/go/internal/srcimporter/srcimporter.go
index caf76a2..c964274 100644
--- a/src/go/internal/srcimporter/srcimporter.go
+++ b/src/go/internal/srcimporter/srcimporter.go
@@ -182,7 +182,7 @@
 				errors[i] = err // open provides operation and filename in error
 				return
 			}
-			files[i], errors[i] = parser.ParseFile(p.fset, filepath, src, 0)
+			files[i], errors[i] = parser.ParseFile(p.fset, filepath, src, parser.SkipObjectResolution)
 			src.Close() // ignore Close error - parsing may have succeeded which is all we need
 		}(i, p.joinPath(dir, filename))
 	}
@@ -240,7 +240,7 @@
 		return nil, fmt.Errorf("go tool cgo: %w", err)
 	}
 
-	return parser.ParseFile(p.fset, filepath.Join(tmpdir, "_cgo_gotypes.go"), nil, 0)
+	return parser.ParseFile(p.fset, filepath.Join(tmpdir, "_cgo_gotypes.go"), nil, parser.SkipObjectResolution)
 }
 
 // context-controlled file system operations
diff --git a/src/go/internal/srcimporter/srcimporter_test.go b/src/go/internal/srcimporter/srcimporter_test.go
index af39466..e877458 100644
--- a/src/go/internal/srcimporter/srcimporter_test.go
+++ b/src/go/internal/srcimporter/srcimporter_test.go
@@ -243,8 +243,10 @@
 	testenv.MustHaveGoBuild(t)
 	testenv.MustHaveCGO(t)
 
-	importer := New(&build.Default, token.NewFileSet(), make(map[string]*types.Package))
-	_, err := importer.ImportFrom("./misc/cgo/test", testenv.GOROOT(t), 0)
+	buildCtx := build.Default
+	buildCtx.Dir = filepath.Join(testenv.GOROOT(t), "misc")
+	importer := New(&buildCtx, token.NewFileSet(), make(map[string]*types.Package))
+	_, err := importer.ImportFrom("./cgo/test", buildCtx.Dir, 0)
 	if err != nil {
 		t.Fatalf("Import failed: %v", err)
 	}
diff --git a/src/go/internal/typeparams/common.go b/src/go/internal/typeparams/common.go
deleted file mode 100644
index 9b82e60..0000000
--- a/src/go/internal/typeparams/common.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package typeparams provides functions to work with type parameter data
-// stored in the AST, while these AST changes are guarded by a build
-// constraint.
-package typeparams
-
-// 'Hidden' parser modes to control the parsing of type-parameter related
-// features.
-const (
-	DisallowTypeSets = 1 << 29 // Disallow eliding 'interface' in constraint type sets.
-	DisallowParsing  = 1 << 30 // Disallow type parameters entirely.
-)
diff --git a/src/go/parser/error_test.go b/src/go/parser/error_test.go
index c3a8ec6..a4e17dd 100644
--- a/src/go/parser/error_test.go
+++ b/src/go/parser/error_test.go
@@ -24,7 +24,6 @@
 
 import (
 	"flag"
-	"go/internal/typeparams"
 	"go/scanner"
 	"go/token"
 	"os"
@@ -63,8 +62,9 @@
 // a regular expression that matches the expected error message.
 // The special form /* ERROR HERE "rx" */ must be used for error
 // messages that appear immediately after a token, rather than at
-// a token's position.
-var errRx = regexp.MustCompile(`^/\* *ERROR *(HERE)? *"([^"]*)" *\*/$`)
+// a token's position, and ERROR AFTER means after the comment
+// (e.g. at end of line).
+var errRx = regexp.MustCompile(`^/\* *ERROR *(HERE|AFTER)? *"([^"]*)" *\*/$`)
 
 // expectedErrors collects the regular expressions of ERROR comments found
 // in files and returns them as a map of error positions to error messages.
@@ -87,9 +87,12 @@
 		case token.COMMENT:
 			s := errRx.FindStringSubmatch(lit)
 			if len(s) == 3 {
-				pos := prev
 				if s[1] == "HERE" {
-					pos = here
+					pos = here // start of comment
+				} else if s[1] == "AFTER" {
+					pos += token.Pos(len(lit)) // end of comment
+				} else {
+					pos = prev // token prior to comment
 				}
 				errors[pos] = s[2]
 			}
@@ -189,9 +192,6 @@
 		t.Run(name, func(t *testing.T) {
 			if !d.IsDir() && !strings.HasPrefix(name, ".") && (strings.HasSuffix(name, ".src") || strings.HasSuffix(name, ".go2")) {
 				mode := DeclarationErrors | AllErrors
-				if !strings.HasSuffix(name, ".go2") {
-					mode |= typeparams.DisallowParsing
-				}
 				if *traceErrs {
 					mode |= Trace
 				}
diff --git a/src/go/parser/interface.go b/src/go/parser/interface.go
index d911c8e..73cb162 100644
--- a/src/go/parser/interface.go
+++ b/src/go/parser/interface.go
@@ -214,7 +214,7 @@
 
 	// parse expr
 	p.init(fset, filename, text, mode)
-	expr = p.parseRhsOrType()
+	expr = p.parseRhs()
 
 	// If a semicolon was inserted, consume it;
 	// report an error if there's more tokens.
diff --git a/src/go/parser/parser.go b/src/go/parser/parser.go
index d4ad36d..fac24df 100644
--- a/src/go/parser/parser.go
+++ b/src/go/parser/parser.go
@@ -21,9 +21,6 @@
 	"go/internal/typeparams"
 	"go/scanner"
 	"go/token"
-	"strconv"
-	"strings"
-	"unicode"
 )
 
 // The parser structure holds the parser's internal state.
@@ -79,9 +76,6 @@
 	p.next()
 }
 
-func (p *parser) allowGenerics() bool { return p.mode&typeparams.DisallowParsing == 0 }
-func (p *parser) allowTypeSets() bool { return p.mode&typeparams.DisallowTypeSets == 0 }
-
 // ----------------------------------------------------------------------------
 // Parsing support
 
@@ -219,7 +213,7 @@
 			// The comment is on same line as the previous token; it
 			// cannot be a lead comment but may be a line comment.
 			comment, endline = p.consumeCommentGroup(0)
-			if p.file.Line(p.pos) != endline || p.tok == token.EOF {
+			if p.file.Line(p.pos) != endline || p.tok == token.SEMICOLON || p.tok == token.EOF {
 				// The next token is on a different line, thus
 				// the last comment group is a line comment.
 				p.lineComment = comment
@@ -319,7 +313,8 @@
 	return p.expect(tok)
 }
 
-func (p *parser) expectSemi() {
+// expectSemi consumes a semicolon and returns the applicable line comment.
+func (p *parser) expectSemi() (comment *ast.CommentGroup) {
 	// semicolon is optional before a closing ')' or '}'
 	if p.tok != token.RPAREN && p.tok != token.RBRACE {
 		switch p.tok {
@@ -328,12 +323,22 @@
 			p.errorExpected(p.pos, "';'")
 			fallthrough
 		case token.SEMICOLON:
-			p.next()
+			if p.lit == ";" {
+				// explicit semicolon
+				p.next()
+				comment = p.lineComment // use following comments
+			} else {
+				// artificial semicolon
+				comment = p.lineComment // use preceding comments
+				p.next()
+			}
+			return comment
 		default:
 			p.errorExpected(p.pos, "';'")
 			p.advance(stmtStart)
 		}
 	}
+	return nil
 }
 
 func (p *parser) atComma(context string, follow token.Token) bool {
@@ -405,9 +410,10 @@
 }
 
 var declStart = map[token.Token]bool{
-	token.CONST: true,
-	token.TYPE:  true,
-	token.VAR:   true,
+	token.IMPORT: true,
+	token.CONST:  true,
+	token.TYPE:   true,
+	token.VAR:    true,
 }
 
 var exprEnd = map[token.Token]bool{
@@ -476,10 +482,10 @@
 		defer un(trace(p, "ExpressionList"))
 	}
 
-	list = append(list, p.checkExpr(p.parseExpr()))
+	list = append(list, p.parseExpr())
 	for p.tok == token.COMMA {
 		p.next()
-		list = append(list, p.checkExpr(p.parseExpr()))
+		list = append(list, p.parseExpr())
 	}
 
 	return
@@ -519,7 +525,7 @@
 	}
 
 	typ := p.parseTypeName(ident)
-	if p.tok == token.LBRACK && p.allowGenerics() {
+	if p.tok == token.LBRACK {
 		typ = p.parseTypeInstance(typ)
 	}
 
@@ -581,26 +587,20 @@
 		defer un(trace(p, "ArrayFieldOrTypeInstance"))
 	}
 
-	// TODO(gri) Should we allow a trailing comma in a type argument
-	//           list such as T[P,]? (We do in parseTypeInstance).
 	lbrack := p.expect(token.LBRACK)
+	trailingComma := token.NoPos // if valid, the position of a trailing comma preceding the ']'
 	var args []ast.Expr
-	var firstComma token.Pos
-	// TODO(rfindley): consider changing parseRhsOrType so that this function variable
-	// is not needed.
-	argparser := p.parseRhsOrType
-	if !p.allowGenerics() {
-		argparser = p.parseRhs
-	}
 	if p.tok != token.RBRACK {
 		p.exprLev++
-		args = append(args, argparser())
+		args = append(args, p.parseRhs())
 		for p.tok == token.COMMA {
-			if !firstComma.IsValid() {
-				firstComma = p.pos
-			}
+			comma := p.pos
 			p.next()
-			args = append(args, argparser())
+			if p.tok == token.RBRACK {
+				trailingComma = comma
+				break
+			}
+			args = append(args, p.parseRhs())
 		}
 		p.exprLev--
 	}
@@ -617,17 +617,12 @@
 		elt := p.tryIdentOrType()
 		if elt != nil {
 			// x [P]E
+			if trailingComma.IsValid() {
+				// Trailing commas are invalid in array type fields.
+				p.error(trailingComma, "unexpected comma; expecting ]")
+			}
 			return x, &ast.ArrayType{Lbrack: lbrack, Len: args[0], Elt: elt}
 		}
-		if !p.allowGenerics() {
-			p.error(rbrack, "missing element type in array type expression")
-			return nil, &ast.BadExpr{From: args[0].Pos(), To: args[0].End()}
-		}
-	}
-
-	if !p.allowGenerics() {
-		p.error(firstComma, "expected ']', found ','")
-		return x, &ast.BadExpr{From: args[0].Pos(), To: args[len(args)-1].End()}
 	}
 
 	// x[P], x[P1, P2], ...
@@ -643,7 +638,8 @@
 
 	var names []*ast.Ident
 	var typ ast.Expr
-	if p.tok == token.IDENT {
+	switch p.tok {
+	case token.IDENT:
 		name := p.parseIdent()
 		if p.tok == token.PERIOD || p.tok == token.STRING || p.tok == token.SEMICOLON || p.tok == token.RBRACE {
 			// embedded type
@@ -670,11 +666,46 @@
 				typ = p.parseType()
 			}
 		}
-	} else {
-		// embedded, possibly generic type
-		// (using the enclosing parentheses to distinguish it from a named field declaration)
-		// TODO(rFindley) confirm that this doesn't allow parenthesized embedded type
-		typ = p.parseType()
+	case token.MUL:
+		star := p.pos
+		p.next()
+		if p.tok == token.LPAREN {
+			// *(T)
+			p.error(p.pos, "cannot parenthesize embedded type")
+			p.next()
+			typ = p.parseQualifiedIdent(nil)
+			// expect closing ')' but no need to complain if missing
+			if p.tok == token.RPAREN {
+				p.next()
+			}
+		} else {
+			// *T
+			typ = p.parseQualifiedIdent(nil)
+		}
+		typ = &ast.StarExpr{Star: star, X: typ}
+
+	case token.LPAREN:
+		p.error(p.pos, "cannot parenthesize embedded type")
+		p.next()
+		if p.tok == token.MUL {
+			// (*T)
+			star := p.pos
+			p.next()
+			typ = &ast.StarExpr{Star: star, X: p.parseQualifiedIdent(nil)}
+		} else {
+			// (T)
+			typ = p.parseQualifiedIdent(nil)
+		}
+		// expect closing ')' but no need to complain if missing
+		if p.tok == token.RPAREN {
+			p.next()
+		}
+
+	default:
+		pos := p.pos
+		p.errorExpected(pos, "field name or embedded type")
+		p.advance(exprEnd)
+		typ = &ast.BadExpr{From: pos, To: p.pos}
 	}
 
 	var tag *ast.BasicLit
@@ -683,9 +714,9 @@
 		p.next()
 	}
 
-	p.expectSemi() // call before accessing p.linecomment
+	comment := p.expectSemi()
 
-	field := &ast.Field{Doc: doc, Names: names, Type: typ, Tag: tag, Comment: p.lineComment}
+	field := &ast.Field{Doc: doc, Names: names, Type: typ, Tag: tag, Comment: comment}
 	return field
 }
 
@@ -833,7 +864,7 @@
 	// Type parameters are the only parameter list closed by ']'.
 	tparams := closing == token.RBRACK
 	// Type set notation is ok in type parameter lists.
-	typeSetsOK := tparams && p.allowTypeSets()
+	typeSetsOK := tparams
 
 	pos := p.pos
 	if name0 != nil {
@@ -885,7 +916,7 @@
 			}
 		}
 		if tparams {
-			p.error(pos, "all type parameters must be named")
+			p.error(pos, "type parameters must be named")
 		}
 	} else if named != len(list) {
 		// some named => all must be named
@@ -913,7 +944,7 @@
 		}
 		if !ok {
 			if tparams {
-				p.error(missingName, "all type parameters must be named")
+				p.error(missingName, "type parameters must be named")
 			} else {
 				p.error(pos, "mixed named and unnamed parameters")
 			}
@@ -959,7 +990,7 @@
 		defer un(trace(p, "Parameters"))
 	}
 
-	if p.allowGenerics() && acceptTParams && p.tok == token.LBRACK {
+	if acceptTParams && p.tok == token.LBRACK {
 		opening := p.pos
 		p.next()
 		// [T any](params) syntax
@@ -1032,7 +1063,7 @@
 	x := p.parseTypeName(nil)
 	if ident, _ := x.(*ast.Ident); ident != nil {
 		switch {
-		case p.tok == token.LBRACK && p.allowGenerics():
+		case p.tok == token.LBRACK:
 			// generic method or embedded instantiated type
 			lbrack := p.pos
 			p.next()
@@ -1090,7 +1121,7 @@
 	} else {
 		// embedded, possibly instantiated type
 		typ = x
-		if p.tok == token.LBRACK && p.allowGenerics() {
+		if p.tok == token.LBRACK {
 			// embedded instantiated interface
 			typ = p.parseTypeInstance(typ)
 		}
@@ -1161,28 +1192,23 @@
 		switch {
 		case p.tok == token.IDENT:
 			f := p.parseMethodSpec()
-			if f.Names == nil && p.allowGenerics() {
+			if f.Names == nil {
 				f.Type = p.embeddedElem(f.Type)
 			}
-			p.expectSemi()
-			f.Comment = p.lineComment
+			f.Comment = p.expectSemi()
 			list = append(list, f)
-		case p.tok == token.TILDE && p.allowGenerics():
+		case p.tok == token.TILDE:
 			typ := p.embeddedElem(nil)
-			p.expectSemi()
-			comment := p.lineComment
+			comment := p.expectSemi()
 			list = append(list, &ast.Field{Type: typ, Comment: comment})
-		case p.allowGenerics():
+		default:
 			if t := p.tryIdentOrType(); t != nil {
 				typ := p.embeddedElem(t)
-				p.expectSemi()
-				comment := p.lineComment
+				comment := p.expectSemi()
 				list = append(list, &ast.Field{Type: typ, Comment: comment})
 			} else {
 				break parseElements
 			}
-		default:
-			break parseElements
 		}
 	}
 
@@ -1240,7 +1266,6 @@
 }
 
 func (p *parser) parseTypeInstance(typ ast.Expr) ast.Expr {
-	assert(p.allowGenerics(), "parseTypeInstance while not parsing type params")
 	if p.trace {
 		defer un(trace(p, "TypeInstance"))
 	}
@@ -1278,7 +1303,7 @@
 	switch p.tok {
 	case token.IDENT:
 		typ := p.parseTypeName(nil)
-		if p.tok == token.LBRACK && p.allowGenerics() {
+		if p.tok == token.LBRACK {
 			typ = p.parseTypeInstance(typ)
 		}
 		return typ
@@ -1290,8 +1315,7 @@
 	case token.MUL:
 		return p.parsePointerType()
 	case token.FUNC:
-		typ := p.parseFuncType()
-		return typ
+		return p.parseFuncType()
 	case token.INTERFACE:
 		return p.parseInterfaceType()
 	case token.MAP:
@@ -1371,7 +1395,7 @@
 }
 
 // parseOperand may return an expression or a raw type (incl. array
-// types of the form [...]T. Callers must verify the result.
+// types of the form [...]T). Callers must verify the result.
 func (p *parser) parseOperand() ast.Expr {
 	if p.trace {
 		defer un(trace(p, "Operand"))
@@ -1391,7 +1415,7 @@
 		lparen := p.pos
 		p.next()
 		p.exprLev++
-		x := p.parseRhsOrType() // types may be parenthesized: (some type)
+		x := p.parseRhs() // types may be parenthesized: (some type)
 		p.exprLev--
 		rparen := p.expect(token.RPAREN)
 		return &ast.ParenExpr{Lparen: lparen, X: x, Rparen: rparen}
@@ -1467,11 +1491,10 @@
 	var args []ast.Expr
 	var index [N]ast.Expr
 	var colons [N - 1]token.Pos
-	var firstComma token.Pos
 	if p.tok != token.COLON {
 		// We can't know if we have an index expression or a type instantiation;
 		// so even if we see a (named) type we are not going to be in type context.
-		index[0] = p.parseRhsOrType()
+		index[0] = p.parseRhs()
 	}
 	ncolons := 0
 	switch p.tok {
@@ -1486,7 +1509,6 @@
 			}
 		}
 	case token.COMMA:
-		firstComma = p.pos
 		// instance expression
 		args = append(args, index[0])
 		for p.tok == token.COMMA {
@@ -1505,14 +1527,14 @@
 		slice3 := false
 		if ncolons == 2 {
 			slice3 = true
-			// Check presence of 2nd and 3rd index here rather than during type-checking
+			// Check presence of middle and final index here rather than during type-checking
 			// to prevent erroneous programs from passing through gofmt (was issue 7305).
 			if index[1] == nil {
-				p.error(colons[0], "2nd index required in 3-index slice")
+				p.error(colons[0], "middle index required in 3-index slice")
 				index[1] = &ast.BadExpr{From: colons[0] + 1, To: colons[1]}
 			}
 			if index[2] == nil {
-				p.error(colons[1], "3rd index required in 3-index slice")
+				p.error(colons[1], "final index required in 3-index slice")
 				index[2] = &ast.BadExpr{From: colons[1] + 1, To: rbrack}
 			}
 		}
@@ -1524,11 +1546,6 @@
 		return &ast.IndexExpr{X: x, Lbrack: lbrack, Index: index[0], Rbrack: rbrack}
 	}
 
-	if !p.allowGenerics() {
-		p.error(firstComma, "expected ']' or ':', found ','")
-		return &ast.BadExpr{From: args[0].Pos(), To: args[len(args)-1].End()}
-	}
-
 	// instance expression
 	return typeparams.PackIndexExpr(x, lbrack, args, rbrack)
 }
@@ -1543,7 +1560,7 @@
 	var list []ast.Expr
 	var ellipsis token.Pos
 	for p.tok != token.RPAREN && p.tok != token.EOF && !ellipsis.IsValid() {
-		list = append(list, p.parseRhsOrType()) // builtins may expect a type: make(some type, ...)
+		list = append(list, p.parseRhs()) // builtins may expect a type: make(some type, ...)
 		if p.tok == token.ELLIPSIS {
 			ellipsis = p.pos
 			p.next()
@@ -1568,7 +1585,7 @@
 		return p.parseLiteralValue(nil)
 	}
 
-	x := p.checkExpr(p.parseExpr())
+	x := p.parseExpr()
 
 	return x
 }
@@ -1620,38 +1637,6 @@
 	return &ast.CompositeLit{Type: typ, Lbrace: lbrace, Elts: elts, Rbrace: rbrace}
 }
 
-// checkExpr checks that x is an expression (and not a type).
-func (p *parser) checkExpr(x ast.Expr) ast.Expr {
-	switch unparen(x).(type) {
-	case *ast.BadExpr:
-	case *ast.Ident:
-	case *ast.BasicLit:
-	case *ast.FuncLit:
-	case *ast.CompositeLit:
-	case *ast.ParenExpr:
-		panic("unreachable")
-	case *ast.SelectorExpr:
-	case *ast.IndexExpr:
-	case *ast.IndexListExpr:
-	case *ast.SliceExpr:
-	case *ast.TypeAssertExpr:
-		// If t.Type == nil we have a type assertion of the form
-		// y.(type), which is only allowed in type switch expressions.
-		// It's hard to exclude those but for the case where we are in
-		// a type switch. Instead be lenient and test this in the type
-		// checker.
-	case *ast.CallExpr:
-	case *ast.StarExpr:
-	case *ast.UnaryExpr:
-	case *ast.BinaryExpr:
-	default:
-		// all other nodes are not proper expressions
-		p.errorExpected(x.Pos(), "expression")
-		x = &ast.BadExpr{From: x.Pos(), To: p.safePos(x.End())}
-	}
-	return x
-}
-
 // If x is of the form (T), unparen returns unparen(T), otherwise it returns x.
 func unparen(x ast.Expr) ast.Expr {
 	if p, isParen := x.(*ast.ParenExpr); isParen {
@@ -1660,23 +1645,6 @@
 	return x
 }
 
-// checkExprOrType checks that x is an expression or a type
-// (and not a raw type such as [...]T).
-func (p *parser) checkExprOrType(x ast.Expr) ast.Expr {
-	switch t := unparen(x).(type) {
-	case *ast.ParenExpr:
-		panic("unreachable")
-	case *ast.ArrayType:
-		if len, isEllipsis := t.Len.(*ast.Ellipsis); isEllipsis {
-			p.error(len.Pos(), "expected array length, found '...'")
-			x = &ast.BadExpr{From: x.Pos(), To: p.safePos(x.End())}
-		}
-	}
-
-	// all other nodes are expressions or types
-	return x
-}
-
 func (p *parser) parsePrimaryExpr(x ast.Expr) ast.Expr {
 	if p.trace {
 		defer un(trace(p, "PrimaryExpr"))
@@ -1697,9 +1665,9 @@
 			p.next()
 			switch p.tok {
 			case token.IDENT:
-				x = p.parseSelector(p.checkExprOrType(x))
+				x = p.parseSelector(x)
 			case token.LPAREN:
-				x = p.parseTypeAssertion(p.checkExpr(x))
+				x = p.parseTypeAssertion(x)
 			default:
 				pos := p.pos
 				p.errorExpected(pos, "selector or type assertion")
@@ -1715,9 +1683,9 @@
 				x = &ast.SelectorExpr{X: x, Sel: sel}
 			}
 		case token.LBRACK:
-			x = p.parseIndexOrSliceOrInstance(p.checkExpr(x))
+			x = p.parseIndexOrSliceOrInstance(x)
 		case token.LPAREN:
-			x = p.parseCallOrConversion(p.checkExprOrType(x))
+			x = p.parseCallOrConversion(x)
 		case token.LBRACE:
 			// operand may have returned a parenthesized complit
 			// type; accept it but complain if we have a complit
@@ -1762,7 +1730,7 @@
 		pos, op := p.pos, p.tok
 		p.next()
 		x := p.parseUnaryExpr()
-		return &ast.UnaryExpr{OpPos: pos, Op: op, X: p.checkExpr(x)}
+		return &ast.UnaryExpr{OpPos: pos, Op: op, X: x}
 
 	case token.ARROW:
 		// channel type or receive expression
@@ -1808,14 +1776,14 @@
 		}
 
 		// <-(expr)
-		return &ast.UnaryExpr{OpPos: arrow, Op: token.ARROW, X: p.checkExpr(x)}
+		return &ast.UnaryExpr{OpPos: arrow, Op: token.ARROW, X: x}
 
 	case token.MUL:
 		// pointer type or unary "*" expression
 		pos := p.pos
 		p.next()
 		x := p.parseUnaryExpr()
-		return &ast.StarExpr{Star: pos, X: p.checkExprOrType(x)}
+		return &ast.StarExpr{Star: pos, X: x}
 	}
 
 	return p.parsePrimaryExpr(nil)
@@ -1831,10 +1799,9 @@
 
 // parseBinaryExpr parses a (possibly) binary expression.
 // If x is non-nil, it is used as the left operand.
-// If check is true, operands are checked to be valid expressions.
 //
 // TODO(rfindley): parseBinaryExpr has become overloaded. Consider refactoring.
-func (p *parser) parseBinaryExpr(x ast.Expr, prec1 int, check bool) ast.Expr {
+func (p *parser) parseBinaryExpr(x ast.Expr, prec1 int) ast.Expr {
 	if p.trace {
 		defer un(trace(p, "BinaryExpr"))
 	}
@@ -1854,38 +1821,24 @@
 			return x
 		}
 		pos := p.expect(op)
-		y := p.parseBinaryExpr(nil, oprec+1, check)
-		if check {
-			x = p.checkExpr(x)
-			y = p.checkExpr(y)
-		}
+		y := p.parseBinaryExpr(nil, oprec+1)
 		x = &ast.BinaryExpr{X: x, OpPos: pos, Op: op, Y: y}
 	}
 }
 
-// The result may be a type or even a raw type ([...]int). Callers must
-// check the result (using checkExpr or checkExprOrType), depending on
-// context.
+// The result may be a type or even a raw type ([...]int).
 func (p *parser) parseExpr() ast.Expr {
 	if p.trace {
 		defer un(trace(p, "Expression"))
 	}
 
-	return p.parseBinaryExpr(nil, token.LowestPrec+1, true)
+	return p.parseBinaryExpr(nil, token.LowestPrec+1)
 }
 
 func (p *parser) parseRhs() ast.Expr {
 	old := p.inRhs
 	p.inRhs = true
-	x := p.checkExpr(p.parseExpr())
-	p.inRhs = old
-	return x
-}
-
-func (p *parser) parseRhsOrType() ast.Expr {
-	old := p.inRhs
-	p.inRhs = true
-	x := p.checkExprOrType(p.parseExpr())
+	x := p.parseExpr()
 	p.inRhs = old
 	return x
 }
@@ -1930,11 +1883,7 @@
 		} else {
 			y = p.parseList(true)
 		}
-		as := &ast.AssignStmt{Lhs: x, TokPos: pos, Tok: tok, Rhs: y}
-		if tok == token.DEFINE {
-			p.checkAssignStmt(as)
-		}
-		return as, isRange
+		return &ast.AssignStmt{Lhs: x, TokPos: pos, Tok: tok, Rhs: y}, isRange
 	}
 
 	if len(x) > 1 {
@@ -1981,22 +1930,18 @@
 	return &ast.ExprStmt{X: x[0]}, false
 }
 
-func (p *parser) checkAssignStmt(as *ast.AssignStmt) {
-	for _, x := range as.Lhs {
-		if _, isIdent := x.(*ast.Ident); !isIdent {
-			p.errorExpected(x.Pos(), "identifier on left side of :=")
-		}
-	}
-}
-
 func (p *parser) parseCallExpr(callType string) *ast.CallExpr {
-	x := p.parseRhsOrType() // could be a conversion: (some type)(x)
+	x := p.parseRhs() // could be a conversion: (some type)(x)
+	if t := unparen(x); t != x {
+		p.error(x.Pos(), fmt.Sprintf("expression in %s must not be parenthesized", callType))
+		x = t
+	}
 	if call, isCall := x.(*ast.CallExpr); isCall {
 		return call
 	}
 	if _, isBad := x.(*ast.BadExpr); !isBad {
 		// only report error if it's a new one
-		p.error(p.safePos(x.End()), fmt.Sprintf("function must be invoked in %s statement", callType))
+		p.error(p.safePos(x.End()), fmt.Sprintf("expression in %s must be function call", callType))
 	}
 	return nil
 }
@@ -2067,7 +2012,7 @@
 		return nil
 	}
 	if es, isExpr := s.(*ast.ExprStmt); isExpr {
-		return p.checkExpr(es.X)
+		return es.X
 	}
 	found := "simple statement"
 	if _, isAss := s.(*ast.AssignStmt); isAss {
@@ -2095,7 +2040,7 @@
 		// accept potential variable declaration but complain
 		if p.tok == token.VAR {
 			p.next()
-			p.error(p.pos, "var declaration not allowed in 'IF' initializer")
+			p.error(p.pos, "var declaration not allowed in if initializer")
 		}
 		init, _ = p.parseSimpleStmt(basic)
 	}
@@ -2172,21 +2117,7 @@
 	return &ast.IfStmt{If: pos, Init: init, Cond: cond, Body: body, Else: else_}
 }
 
-func (p *parser) parseTypeList() (list []ast.Expr) {
-	if p.trace {
-		defer un(trace(p, "TypeList"))
-	}
-
-	list = append(list, p.parseType())
-	for p.tok == token.COMMA {
-		p.next()
-		list = append(list, p.parseType())
-	}
-
-	return
-}
-
-func (p *parser) parseCaseClause(typeSwitch bool) *ast.CaseClause {
+func (p *parser) parseCaseClause() *ast.CaseClause {
 	if p.trace {
 		defer un(trace(p, "CaseClause"))
 	}
@@ -2195,11 +2126,7 @@
 	var list []ast.Expr
 	if p.tok == token.CASE {
 		p.next()
-		if typeSwitch {
-			list = p.parseTypeList()
-		} else {
-			list = p.parseList(true)
-		}
+		list = p.parseList(true)
 	} else {
 		p.expect(token.DEFAULT)
 	}
@@ -2277,7 +2204,7 @@
 	lbrace := p.expect(token.LBRACE)
 	var list []ast.Stmt
 	for p.tok == token.CASE || p.tok == token.DEFAULT {
-		list = append(list, p.parseCaseClause(typeSwitch))
+		list = append(list, p.parseCaseClause())
 	}
 	rbrace := p.expect(token.RBRACE)
 	p.expectSemi()
@@ -2322,11 +2249,7 @@
 				pos := p.pos
 				p.next()
 				rhs := p.parseRhs()
-				as := &ast.AssignStmt{Lhs: lhs, TokPos: pos, Tok: tok, Rhs: []ast.Expr{rhs}}
-				if tok == token.DEFINE {
-					p.checkAssignStmt(as)
-				}
-				comm = as
+				comm = &ast.AssignStmt{Lhs: lhs, TokPos: pos, Tok: tok, Rhs: []ast.Expr{rhs}}
 			} else {
 				// lhs must be single receive operation
 				if len(lhs) > 1 {
@@ -2430,6 +2353,7 @@
 			Value:  value,
 			TokPos: as.TokPos,
 			Tok:    as.Tok,
+			Range:  as.Rhs[0].Pos(),
 			X:      x,
 			Body:   body,
 		}
@@ -2509,91 +2433,85 @@
 // ----------------------------------------------------------------------------
 // Declarations
 
-type parseSpecFunction func(doc *ast.CommentGroup, pos token.Pos, keyword token.Token, iota int) ast.Spec
+type parseSpecFunction func(doc *ast.CommentGroup, keyword token.Token, iota int) ast.Spec
 
-func isValidImport(lit string) bool {
-	const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD"
-	s, _ := strconv.Unquote(lit) // go/scanner returns a legal string literal
-	for _, r := range s {
-		if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) {
-			return false
-		}
-	}
-	return s != ""
-}
-
-func (p *parser) parseImportSpec(doc *ast.CommentGroup, _ token.Pos, _ token.Token, _ int) ast.Spec {
+func (p *parser) parseImportSpec(doc *ast.CommentGroup, _ token.Token, _ int) ast.Spec {
 	if p.trace {
 		defer un(trace(p, "ImportSpec"))
 	}
 
 	var ident *ast.Ident
 	switch p.tok {
+	case token.IDENT:
+		ident = p.parseIdent()
 	case token.PERIOD:
 		ident = &ast.Ident{NamePos: p.pos, Name: "."}
 		p.next()
-	case token.IDENT:
-		ident = p.parseIdent()
 	}
 
 	pos := p.pos
 	var path string
 	if p.tok == token.STRING {
 		path = p.lit
-		if !isValidImport(path) {
-			p.error(pos, "invalid import path: "+path)
-		}
+		p.next()
+	} else if p.tok.IsLiteral() {
+		p.error(pos, "import path must be a string")
 		p.next()
 	} else {
-		p.expect(token.STRING) // use expect() error handling
+		p.error(pos, "missing import path")
+		p.advance(exprEnd)
 	}
-	p.expectSemi() // call before accessing p.linecomment
+	comment := p.expectSemi()
 
 	// collect imports
 	spec := &ast.ImportSpec{
 		Doc:     doc,
 		Name:    ident,
 		Path:    &ast.BasicLit{ValuePos: pos, Kind: token.STRING, Value: path},
-		Comment: p.lineComment,
+		Comment: comment,
 	}
 	p.imports = append(p.imports, spec)
 
 	return spec
 }
 
-func (p *parser) parseValueSpec(doc *ast.CommentGroup, _ token.Pos, keyword token.Token, iota int) ast.Spec {
+func (p *parser) parseValueSpec(doc *ast.CommentGroup, keyword token.Token, iota int) ast.Spec {
 	if p.trace {
 		defer un(trace(p, keyword.String()+"Spec"))
 	}
 
-	pos := p.pos
 	idents := p.parseIdentList()
-	typ := p.tryIdentOrType()
+	var typ ast.Expr
 	var values []ast.Expr
-	// always permit optional initialization for more tolerant parsing
-	if p.tok == token.ASSIGN {
-		p.next()
-		values = p.parseList(true)
-	}
-	p.expectSemi() // call before accessing p.linecomment
-
 	switch keyword {
-	case token.VAR:
-		if typ == nil && values == nil {
-			p.error(pos, "missing variable type or initialization")
-		}
 	case token.CONST:
-		if values == nil && (iota == 0 || typ != nil) {
-			p.error(pos, "missing constant value")
+		// always permit optional type and initialization for more tolerant parsing
+		if p.tok != token.EOF && p.tok != token.SEMICOLON && p.tok != token.RPAREN {
+			typ = p.tryIdentOrType()
+			if p.tok == token.ASSIGN {
+				p.next()
+				values = p.parseList(true)
+			}
 		}
+	case token.VAR:
+		if p.tok != token.ASSIGN {
+			typ = p.parseType()
+		}
+		if p.tok == token.ASSIGN {
+			p.next()
+			values = p.parseList(true)
+		}
+	default:
+		panic("unreachable")
 	}
+	comment := p.expectSemi()
 
 	spec := &ast.ValueSpec{
 		Doc:     doc,
 		Names:   idents,
 		Type:    typ,
 		Values:  values,
-		Comment: p.lineComment,
+		Comment: comment,
 	}
 	return spec
 }
@@ -2616,7 +2534,7 @@
 	spec.Type = p.parseType()
 }
 
-func (p *parser) parseTypeSpec(doc *ast.CommentGroup, _ token.Pos, _ token.Token, _ int) ast.Spec {
+func (p *parser) parseTypeSpec(doc *ast.CommentGroup, _ token.Token, _ int) ast.Spec {
 	if p.trace {
 		defer un(trace(p, "TypeSpec"))
 	}
@@ -2624,7 +2542,7 @@
 	name := p.parseIdent()
 	spec := &ast.TypeSpec{Doc: doc, Name: name}
 
-	if p.tok == token.LBRACK && p.allowGenerics() {
+	if p.tok == token.LBRACK {
 		// spec.Name "[" ...
 		// array/slice type or type parameter list
 		lbrack := p.pos
@@ -2652,7 +2570,7 @@
 				// to parser.expr, and pass in name to parsePrimaryExpr.
 				p.exprLev++
 				lhs := p.parsePrimaryExpr(x)
-				x = p.parseBinaryExpr(lhs, token.LowestPrec+1, false)
+				x = p.parseBinaryExpr(lhs, token.LowestPrec+1)
 				p.exprLev--
 			}
 			// Analyze expression x. If we can split x into a type parameter
@@ -2686,8 +2604,7 @@
 		spec.Type = p.parseType()
 	}
 
-	p.expectSemi() // call before accessing p.linecomment
-	spec.Comment = p.lineComment
+	spec.Comment = p.expectSemi()
 
 	return spec
 }
@@ -2769,12 +2686,12 @@
 		lparen = p.pos
 		p.next()
 		for iota := 0; p.tok != token.RPAREN && p.tok != token.EOF; iota++ {
-			list = append(list, f(p.leadComment, pos, keyword, iota))
+			list = append(list, f(p.leadComment, keyword, iota))
 		}
 		rparen = p.expect(token.RPAREN)
 		p.expectSemi()
 	} else {
-		list = append(list, f(nil, pos, keyword, 0))
+		list = append(list, f(nil, keyword, 0))
 	}
 
 	return &ast.GenDecl{
@@ -2850,6 +2767,9 @@
 
 	var f parseSpecFunction
 	switch p.tok {
+	case token.IMPORT:
+		f = p.parseImportSpec
+
 	case token.CONST, token.VAR:
 		f = p.parseValueSpec
 
@@ -2909,19 +2829,28 @@
 
 		if p.mode&ImportsOnly == 0 {
 			// rest of package body
+			prev := token.IMPORT
 			for p.tok != token.EOF {
+				// Continue to accept import declarations for error tolerance, but complain.
+				if p.tok == token.IMPORT && prev != token.IMPORT {
+					p.error(p.pos, "imports must appear before other declarations")
+				}
+				prev = p.tok
+
 				decls = append(decls, p.parseDecl(declStart))
 			}
 		}
 	}
 
 	f := &ast.File{
-		Doc:      doc,
-		Package:  pos,
-		Name:     ident,
-		Decls:    decls,
-		Imports:  p.imports,
-		Comments: p.comments,
+		Doc:       doc,
+		Package:   pos,
+		Name:      ident,
+		Decls:     decls,
+		FileStart: token.Pos(p.file.Base()),
+		FileEnd:   token.Pos(p.file.Base() + p.file.Size()),
+		Imports:   p.imports,
+		Comments:  p.comments,
 	}
 	var declErr func(token.Pos, string)
 	if p.mode&DeclarationErrors != 0 {
diff --git a/src/go/parser/parser_test.go b/src/go/parser/parser_test.go
index 0c27892..153562d 100644
--- a/src/go/parser/parser_test.go
+++ b/src/go/parser/parser_test.go
@@ -5,7 +5,6 @@
 package parser
 
 import (
-	"bytes"
 	"fmt"
 	"go/ast"
 	"go/token"
@@ -298,7 +297,7 @@
 		"float " // s3a
 
 	// collect unresolved identifiers
-	var buf bytes.Buffer
+	var buf strings.Builder
 	for _, u := range f.Unresolved {
 		buf.WriteString(u.Name)
 		buf.WriteByte(' ')
@@ -310,51 +309,6 @@
 	}
 }
 
-var imports = map[string]bool{
-	`"a"`:        true,
-	"`a`":        true,
-	`"a/b"`:      true,
-	`"a.b"`:      true,
-	`"m\x61th"`:  true,
-	`"greek/αβ"`: true,
-	`""`:         false,
-
-	// Each of these pairs tests both `` vs "" strings
-	// and also use of invalid characters spelled out as
-	// escape sequences and written directly.
-	// For example `"\x00"` tests import "\x00"
-	// while "`\x00`" tests import `<actual-NUL-byte>`.
-	`"\x00"`:     false,
-	"`\x00`":     false,
-	`"\x7f"`:     false,
-	"`\x7f`":     false,
-	`"a!"`:       false,
-	"`a!`":       false,
-	`"a b"`:      false,
-	"`a b`":      false,
-	`"a\\b"`:     false,
-	"`a\\b`":     false,
-	"\"`a`\"":    false,
-	"`\"a\"`":    false,
-	`"\x80\x80"`: false,
-	"`\x80\x80`": false,
-	`"\xFFFD"`:   false,
-	"`\xFFFD`":   false,
-}
-
-func TestImports(t *testing.T) {
-	for path, isValid := range imports {
-		src := fmt.Sprintf("package p; import %s", path)
-		_, err := ParseFile(token.NewFileSet(), "", src, 0)
-		switch {
-		case err != nil && isValid:
-			t.Errorf("ParseFile(%s): got %v; expected no error", src, err)
-		case err == nil && !isValid:
-			t.Errorf("ParseFile(%s): got no error; expected one", src)
-		}
-	}
-}
-
 func TestCommentGroups(t *testing.T) {
 	f, err := ParseFile(token.NewFileSet(), "", `
 package p /* 1a */ /* 1b */      /* 1c */ // 1d
@@ -427,7 +381,7 @@
 
 // Don't use ast.CommentGroup.Text() - we want to see exact comment text.
 func commentText(c *ast.CommentGroup) string {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	if c != nil {
 		for _, c := range c.List {
 			buf.WriteString(c.Text)
@@ -461,6 +415,11 @@
 	F2 int  // F2 line comment
 	// f3 lead comment
 	f3 int  // f3 line comment
+
+	f4 int   /* not a line comment */ ;
+        f5 int ; // f5 line comment
+	f6 int ; /* f6 line comment */
+	f7 int ; /*f7a*/ /*f7b*/ //f7c
 }
 `, ParseComments)
 	if err != nil {
@@ -469,6 +428,11 @@
 	checkFieldComments(t, f, "T.F1", "/* F1 lead comment *///", "/* F1 */// line comment")
 	checkFieldComments(t, f, "T.F2", "// F2 lead// comment", "// F2 line comment")
 	checkFieldComments(t, f, "T.f3", "// f3 lead comment", "// f3 line comment")
+	checkFieldComments(t, f, "T.f4", "", "")
+	checkFieldComments(t, f, "T.f5", "", "// f5 line comment")
+	checkFieldComments(t, f, "T.f6", "", "/* f6 line comment */")
+	checkFieldComments(t, f, "T.f7", "", "/*f7a*//*f7b*///f7c")
+
 	ast.FileExports(f)
 	checkFieldComments(t, f, "T.F1", "/* F1 lead comment *///", "/* F1 */// line comment")
 	checkFieldComments(t, f, "T.F2", "// F2 lead// comment", "// F2 line comment")
@@ -524,6 +488,34 @@
 	}
 }
 
+func TestFileStartEndPos(t *testing.T) {
+	const src = `// Copyright
+
+//+build tag
+
+// Package p doc comment.
+package p
+
+var lastDecl int
+
+/* end of file */
+`
+	fset := token.NewFileSet()
+	f, err := ParseFile(fset, "file.go", src, 0)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// File{Start,End} spans the entire file, not just the declarations.
+	if got, want := fset.Position(f.FileStart).String(), "file.go:1:1"; got != want {
+		t.Errorf("for File.FileStart, got %s, want %s", got, want)
+	}
+	// The end position is the newline at the end of the /* end of file */ line.
+	if got, want := fset.Position(f.FileEnd).String(), "file.go:10:19"; got != want {
+		t.Errorf("for File.FileEnd, got %s, want %s", got, want)
+	}
+}
+
 // TestIncompleteSelection ensures that an incomplete selector
 // expression is parsed as a (blank) *ast.SelectorExpr, not a
 // *ast.BadExpr.
@@ -742,3 +734,33 @@
 		}
 	}
 }
+
+// proposal #50429
+func TestRangePos(t *testing.T) {
+	testcases := []string{
+		"package p; func _() { for range x {} }",
+		"package p; func _() { for i = range x {} }",
+		"package p; func _() { for i := range x {} }",
+		"package p; func _() { for k, v = range x {} }",
+		"package p; func _() { for k, v := range x {} }",
+	}
+
+	for _, src := range testcases {
+		fset := token.NewFileSet()
+		f, err := ParseFile(fset, src, src, 0)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		ast.Inspect(f, func(x ast.Node) bool {
+			switch s := x.(type) {
+			case *ast.RangeStmt:
+				pos := fset.Position(s.Range)
+				if pos.Offset != strings.Index(src, "range") {
+					t.Errorf("%s: got offset %v, want %v", src, pos.Offset, strings.Index(src, "range"))
+				}
+			}
+			return true
+		})
+	}
+}
diff --git a/src/go/parser/performance_test.go b/src/go/parser/performance_test.go
index 1249f35..1308f21 100644
--- a/src/go/parser/performance_test.go
+++ b/src/go/parser/performance_test.go
@@ -10,9 +10,7 @@
 	"testing"
 )
 
-// TODO(rfindley): use a testdata file or file from another package here, to
-// avoid a moving target.
-var src = readFile("parser.go")
+var src = readFile("../printer/nodes.go")
 
 func readFile(filename string) []byte {
 	data, err := os.ReadFile(filename)
diff --git a/src/go/parser/resolver_test.go b/src/go/parser/resolver_test.go
index 0c06c59..38739a3 100644
--- a/src/go/parser/resolver_test.go
+++ b/src/go/parser/resolver_test.go
@@ -7,7 +7,6 @@
 import (
 	"fmt"
 	"go/ast"
-	"go/internal/typeparams"
 	"go/scanner"
 	"go/token"
 	"os"
@@ -41,9 +40,6 @@
 			path := filepath.Join(dir, fi.Name())
 			src := readFile(path) // panics on failure
 			var mode Mode
-			if !strings.HasSuffix(path, ".go2") {
-				mode |= typeparams.DisallowParsing
-			}
 			file, err := ParseFile(fset, path, src, mode)
 			if err != nil {
 				t.Fatal(err)
diff --git a/src/go/parser/short_test.go b/src/go/parser/short_test.go
index d117f0d..f9575e1 100644
--- a/src/go/parser/short_test.go
+++ b/src/go/parser/short_test.go
@@ -6,10 +6,7 @@
 
 package parser
 
-import (
-	"go/internal/typeparams"
-	"testing"
-)
+import "testing"
 
 var valids = []string{
 	"package p\n",
@@ -52,9 +49,9 @@
 	`package p; type T = int`,
 	`package p; type (T = p.T; _ = struct{}; x = *T)`,
 	`package p; type T (*int)`,
-	`package p; type _ struct{ ((int)) }`,
-	`package p; type _ struct{ (*(int)) }`,
-	`package p; type _ struct{ ([]byte) }`, // disallowed by type-checker
+	`package p; type _ struct{ int }`,
+	`package p; type _ struct{ pkg.T }`,
+	`package p; type _ struct{ *pkg.T }`,
 	`package p; var _ = func()T(nil)`,
 	`package p; func _(T (P))`,
 	`package p; func _(T []E)`,
@@ -64,80 +61,65 @@
 	`package p; type _ struct{ f [n]E }`,
 	`package p; type _ struct{ f [a+b+c+d]E }`,
 	`package p; type I1 interface{}; type I2 interface{ I1 }`,
-}
 
-// validWithTParamsOnly holds source code examples that are valid if
-// parseTypeParams is set, but invalid if not. When checking with the
-// parseTypeParams set, errors are ignored.
-var validWithTParamsOnly = []string{
-	`package p; type _ []T[ /* ERROR "expected ';', found '\['" */ int]`,
-	`package p; type T[P any /* ERROR "expected ']', found any" */ ] struct { P }`,
-	`package p; type T[P comparable /* ERROR "expected ']', found comparable" */ ] struct { P }`,
-	`package p; type T[P comparable /* ERROR "expected ']', found comparable" */ [P]] struct { P }`,
-	`package p; type T[P1, /* ERROR "unexpected comma" */ P2 any] struct { P1; f []P2 }`,
-	`package p; func _[ /* ERROR "expected '\(', found '\['" */ T any]()()`,
+	// generic code
+	`package p; type _ []T[int]`,
+	`package p; type T[P any] struct { P }`,
+	`package p; type T[P comparable] struct { P }`,
+	`package p; type T[P comparable[P]] struct { P }`,
+	`package p; type T[P1, P2 any] struct { P1; f []P2 }`,
+	`package p; func _[T any]()()`,
 	`package p; func _(T (P))`,
-	`package p; func f[ /* ERROR "expected '\(', found '\['" */ A, B any](); func _() { _ = f[int, int] }`,
-	`package p; func _(x /* ERROR "mixed named and unnamed parameters" */ T[P1, P2, P3])`,
-	`package p; func _(x /* ERROR "mixed named and unnamed parameters" */ p.T[Q])`,
-	`package p; func _(p.T[ /* ERROR "missing ',' in parameter list" */ Q])`,
-	`package p; type _[A interface /* ERROR "expected ']', found 'interface'" */ {},] struct{}`,
-	`package p; type _[A interface /* ERROR "expected ']', found 'interface'" */ {}] struct{}`,
-	`package p; type _[A, /* ERROR "unexpected comma" */  B any,] struct{}`,
-	`package p; type _[A, /* ERROR "unexpected comma" */ B any] struct{}`,
-	`package p; type _[A any /* ERROR "expected ']', found any" */,] struct{}`,
-	`package p; type _[A any /* ERROR "expected ']', found any" */ ]struct{}`,
-	`package p; type _[A any /* ERROR "expected ']', found any" */ ] struct{ A }`,
-	`package p; func _[ /* ERROR "expected '\(', found '\['" */ T any]()`,
-	`package p; func _[ /* ERROR "expected '\(', found '\['" */ T any](x T)`,
-	`package p; func _[ /* ERROR "expected '\(', found '\['" */ T1, T2 any](x T)`,
-	`package p; func _[ /* ERROR "expected '\(', found '\['" */ A, B any](a A) B`,
-	`package p; func _[ /* ERROR "expected '\(', found '\['" */ A, B C](a A) B`,
-	`package p; func _[ /* ERROR "expected '\(', found '\['" */ A, B C[A, B]](a A) B`,
+	`package p; func f[A, B any](); func _() { _ = f[int, int] }`,
+	`package p; func _(x T[P1, P2, P3])`,
+	`package p; func _(x p.T[Q])`,
+	`package p; func _(p.T[Q])`,
+	`package p; type _[A interface{},] struct{}`,
+	`package p; type _[A interface{}] struct{}`,
+	`package p; type _[A,  B any,] struct{}`,
+	`package p; type _[A, B any] struct{}`,
+	`package p; type _[A any,] struct{}`,
+	`package p; type _[A any]struct{}`,
+	`package p; type _[A any] struct{ A }`,
+	`package p; func _[T any]()`,
+	`package p; func _[T any](x T)`,
+	`package p; func _[T1, T2 any](x T)`,
+	`package p; func _[A, B any](a A) B`,
+	`package p; func _[A, B C](a A) B`,
+	`package p; func _[A, B C[A, B]](a A) B`,
 
-	`package p; type _[A, /* ERROR "unexpected comma" */ B any] interface { _(a A) B }`,
-	`package p; type _[A, /* ERROR "unexpected comma" */ B C[A, B]] interface { _(a A) B }`,
-	`package p; func _[ /* ERROR "expected '\(', found '\['" */ T1, T2 interface{}](x T1) T2`,
-	`package p; func _[ /* ERROR "expected '\(', found '\['" */ T1 interface{ m() }, T2, T3 interface{}](x T1, y T3) T2`,
-	`package p; var _ = [ /* ERROR "expected expression" */ ]T[int]{}`,
-	`package p; var _ = [ /* ERROR "expected expression" */ 10]T[int]{}`,
-	`package p; var _ = func /* ERROR "expected expression" */ ()T[int]{}`,
-	`package p; var _ = map /* ERROR "expected expression" */ [T[int]]T[int]{}`,
-	`package p; var _ = chan /* ERROR "expected expression" */ T[int](x)`,
-	`package p; func _(_ T[ /* ERROR "missing ',' in parameter list" */ P], T P) T[P]`,
-	`package p; var _ T[ /* ERROR "expected ';', found '\['" */ chan int]`,
+	`package p; type _[A, B any] interface { _(a A) B }`,
+	`package p; type _[A, B C[A, B]] interface { _(a A) B }`,
+	`package p; func _[T1, T2 interface{}](x T1) T2`,
+	`package p; func _[T1 interface{ m() }, T2, T3 interface{}](x T1, y T3) T2`,
+	`package p; var _ = []T[int]{}`,
+	`package p; var _ = [10]T[int]{}`,
+	`package p; var _ = func()T[int]{}`,
+	`package p; var _ = map[T[int]]T[int]{}`,
+	`package p; var _ = chan T[int](x)`,
+	`package p; func _(_ T[P], T P) T[P]`,
+	`package p; var _ T[chan int]`,
 
-	// TODO(rfindley) this error message could be improved.
-	`package p; func (_ /* ERROR "mixed named and unnamed parameters" */ R[P]) _(x T)`,
-	`package p; func (_ /* ERROR "mixed named and unnamed parameters" */ R[ P, Q]) _(x T)`,
+	`package p; func (_ R[P]) _(x T)`,
+	`package p; func (_ R[ P, Q]) _(x T)`,
 
-	`package p; func (R[P] /* ERROR "missing element type" */ ) _()`,
-	`package p; func _(T[P] /* ERROR "missing element type" */ )`,
-	`package p; func _(T[P1, /* ERROR "expected ']', found ','" */ P2, P3 ])`,
-	`package p; func _(T[P] /* ERROR "missing element type" */ ) T[P]`,
-	`package p; type _ struct{ T[P] /* ERROR "missing element type" */ }`,
-	`package p; type _ struct{ T[struct /* ERROR "expected expression" */ {a, b, c int}] }`,
-	`package p; type _ interface{int| /* ERROR "expected ';'" */ float32; bool; m(); string;}`,
-	`package p; type I1[T any /* ERROR "expected ']', found any" */ ] interface{}; type I2 interface{ I1[int] }`,
-	`package p; type I1[T any /* ERROR "expected ']', found any" */ ] interface{}; type I2[T any] interface{ I1[T] }`,
-	`package p; type _ interface { N[ /* ERROR "expected ';', found '\['" */ T] }`,
-	`package p; type T[P any /* ERROR "expected ']'" */ ] = T0`,
+	`package p; func (R[P]) _()`,
+	`package p; func _(T[P])`,
+	`package p; func _(T[P1, P2, P3 ])`,
+	`package p; func _(T[P]) T[P]`,
+	`package p; type _ struct{ T[P]}`,
+	`package p; type _ struct{ T[struct{a, b, c int}] }`,
+	`package p; type _ interface{int|float32; bool; m(); string;}`,
+	`package p; type I1[T any] interface{}; type I2 interface{ I1[int] }`,
+	`package p; type I1[T any] interface{}; type I2[T any] interface{ I1[T] }`,
+	`package p; type _ interface { N[T] }`,
+	`package p; type T[P any] = T0`,
 }
 
 func TestValid(t *testing.T) {
-	t.Run("no tparams", func(t *testing.T) {
-		for _, src := range valids {
-			checkErrors(t, src, src, DeclarationErrors|AllErrors, false)
-		}
-	})
-	t.Run("tparams", func(t *testing.T) {
-		for _, src := range valids {
-			checkErrors(t, src, src, DeclarationErrors|AllErrors, false)
-		}
-		for _, src := range validWithTParamsOnly {
-			checkErrors(t, src, src, DeclarationErrors|AllErrors, false)
-		}
-	})
+	for _, src := range valids {
+		checkErrors(t, src, src, DeclarationErrors|AllErrors, false)
+	}
 }
 
 // TestSingle is useful to track down a problem with a single short test program.
@@ -159,57 +141,42 @@
 	`package p; func f() { switch t = /* ERROR "expected ':=', found '='" */ t.(type) {} };`,
 	`package p; func f() { switch t /* ERROR "expected switch expression" */ , t = t.(type) {} };`,
 	`package p; func f() { switch t /* ERROR "expected switch expression" */ = t.(type), t {} };`,
-	`package p; var a = [ /* ERROR "expected expression" */ 1]int;`,
-	`package p; var a = [ /* ERROR "expected expression" */ ...]int;`,
-	`package p; var a = struct /* ERROR "expected expression" */ {}`,
-	`package p; var a = func /* ERROR "expected expression" */ ();`,
-	`package p; var a = interface /* ERROR "expected expression" */ {}`,
-	`package p; var a = [ /* ERROR "expected expression" */ ]int`,
-	`package p; var a = map /* ERROR "expected expression" */ [int]int`,
-	`package p; var a = chan /* ERROR "expected expression" */ int;`,
-	`package p; var a = []int{[ /* ERROR "expected expression" */ ]int};`,
-	`package p; var a = ( /* ERROR "expected expression" */ []int);`,
-	`package p; var a = <- /* ERROR "expected expression" */ chan int;`,
-	`package p; func f() { select { case _ <- chan /* ERROR "expected expression" */ int: } };`,
 	`package p; func f() { _ = (<-<- /* ERROR "expected 'chan'" */ chan int)(nil) };`,
 	`package p; func f() { _ = (<-chan<-chan<-chan<-chan<-chan<- /* ERROR "expected channel type" */ int)(nil) };`,
-	`package p; func f() { var t []int; t /* ERROR "expected identifier on left side of :=" */ [0] := 0 };`,
 	`package p; func f() { if x := g(); x /* ERROR "expected boolean expression" */ = 0 {}};`,
 	`package p; func f() { _ = x = /* ERROR "expected '=='" */ 0 {}};`,
 	`package p; func f() { _ = 1 == func()int { var x bool; x = x = /* ERROR "expected '=='" */ true; return x }() };`,
 	`package p; func f() { var s []int; _ = s[] /* ERROR "expected operand" */ };`,
-	`package p; func f() { var s []int; _ = s[i:j: /* ERROR "3rd index required" */ ] };`,
-	`package p; func f() { var s []int; _ = s[i: /* ERROR "2nd index required" */ :k] };`,
-	`package p; func f() { var s []int; _ = s[i: /* ERROR "2nd index required" */ :] };`,
-	`package p; func f() { var s []int; _ = s[: /* ERROR "2nd index required" */ :] };`,
-	`package p; func f() { var s []int; _ = s[: /* ERROR "2nd index required" */ ::] };`,
+	`package p; func f() { var s []int; _ = s[i:j: /* ERROR "final index required" */ ] };`,
+	`package p; func f() { var s []int; _ = s[i: /* ERROR "middle index required" */ :k] };`,
+	`package p; func f() { var s []int; _ = s[i: /* ERROR "middle index required" */ :] };`,
+	`package p; func f() { var s []int; _ = s[: /* ERROR "middle index required" */ :] };`,
+	`package p; func f() { var s []int; _ = s[: /* ERROR "middle index required" */ ::] };`,
 	`package p; func f() { var s []int; _ = s[i:j:k: /* ERROR "expected ']'" */ l] };`,
 	`package p; func f() { for x /* ERROR "boolean or range expression" */ = []string {} }`,
 	`package p; func f() { for x /* ERROR "boolean or range expression" */ := []string {} }`,
 	`package p; func f() { for i /* ERROR "boolean or range expression" */ , x = []string {} }`,
 	`package p; func f() { for i /* ERROR "boolean or range expression" */ , x := []string {} }`,
-	`package p; func f() { go f /* ERROR HERE "function must be invoked" */ }`,
-	`package p; func f() { defer func() {} /* ERROR HERE "function must be invoked" */ }`,
+	`package p; func f() { go f /* ERROR HERE "must be function call" */ }`,
+	`package p; func f() { go ( /* ERROR "must not be parenthesized" */ f()) }`,
+	`package p; func f() { defer func() {} /* ERROR HERE "must be function call" */ }`,
+	`package p; func f() { defer ( /* ERROR "must not be parenthesized" */ f()) }`,
 	`package p; func f() { go func() { func() { f(x func /* ERROR "missing ','" */ (){}) } } }`,
 	`package p; func _() (type /* ERROR "found 'type'" */ T)(T)`,
 	`package p; func (type /* ERROR "found 'type'" */ T)(T) _()`,
 	`package p; type _[A+B, /* ERROR "unexpected comma" */ ] int`,
 
-	// TODO(rfindley): this error should be positioned on the ':'
-	`package p; var a = a[[]int:[ /* ERROR "expected expression" */ ]int];`,
-
-	// TODO(rfindley): the compiler error is better here: "cannot parenthesize embedded type"
-	// TODO(rfindley): confirm that parenthesized types should now be accepted.
-	// `package p; type I1 interface{}; type I2 interface{ (/* ERROR "expected '}', found '\('" */ I1) }`,
+	`package p; type _ struct{ [ /* ERROR "expected '}', found '\['" */ ]byte }`,
+	`package p; type _ struct{ ( /* ERROR "cannot parenthesize embedded type" */ int) }`,
+	`package p; type _ struct{ ( /* ERROR "cannot parenthesize embedded type" */ []byte) }`,
+	`package p; type _ struct{ *( /* ERROR "cannot parenthesize embedded type" */ int) }`,
+	`package p; type _ struct{ *( /* ERROR "cannot parenthesize embedded type" */ []byte) }`,
 
 	// issue 8656
 	`package p; func f() (a b string /* ERROR "missing ','" */ , ok bool)`,
 
 	// issue 9639
-	`package p; var x /* ERROR "missing variable type or initialization" */ , y, z;`,
-	`package p; const x /* ERROR "missing constant value" */ ;`,
-	`package p; const x /* ERROR "missing constant value" */ int;`,
-	`package p; const (x = 0; y; z /* ERROR "missing constant value" */ int);`,
+	`package p; var x, y, z; /* ERROR "expected type" */`,
 
 	// issue 12437
 	`package p; var _ = struct { x int, /* ERROR "expected ';', found ','" */ }{};`,
@@ -222,37 +189,16 @@
 	// issue 13475
 	`package p; func f() { if true {} else ; /* ERROR "expected if statement or block" */ }`,
 	`package p; func f() { if true {} else defer /* ERROR "expected if statement or block" */ f() }`,
-}
 
-// invalidNoTParamErrs holds invalid source code examples annotated with the
-// error messages produced when ParseTypeParams is not set.
-var invalidNoTParamErrs = []string{
-	`package p; type _[_ any /* ERROR "expected ']', found any" */ ] int; var _ = T[]{}`,
-	`package p; type T[P any /* ERROR "expected ']', found any" */ ] = T0`,
-	`package p; var _ func[ /* ERROR "expected '\(', found '\['" */ T any](T)`,
-	`package p; func _[ /* ERROR "expected '\(', found '\['" */ ]()`,
-	`package p; type _[A, /* ERROR "unexpected comma" */] struct{ A }`,
-	`package p; func _[ /* ERROR "expected '\(', found '\['" */ type P, *Q interface{}]()`,
-
-	`package p; func (T) _[ /* ERROR "expected '\(', found '\['" */ A, B any](a A) B`,
-	`package p; func (T) _[ /* ERROR "expected '\(', found '\['" */ A, B C](a A) B`,
-	`package p; func (T) _[ /* ERROR "expected '\(', found '\['" */ A, B C[A, B]](a A) B`,
-
-	`package p; func(*T[ /* ERROR "missing ',' in parameter list" */ e, e]) _()`,
-}
-
-// invalidTParamErrs holds invalid source code examples annotated with the
-// error messages produced when ParseTypeParams is set.
-var invalidTParamErrs = []string{
+	// generic code
 	`package p; type _[_ any] int; var _ = T[] /* ERROR "expected operand" */ {}`,
 	`package p; var _ func[ /* ERROR "must have no type parameters" */ T any](T)`,
 	`package p; func _[]/* ERROR "empty type parameter list" */()`,
 
 	// TODO(rfindley) a better location would be after the ']'
-	`package p; type _[A /* ERROR "all type parameters must be named" */ ,] struct{ A }`,
+	`package p; type _[A /* ERROR "type parameters must be named" */ ,] struct{ A }`,
 
-	// TODO(rfindley) this error is confusing.
-	`package p; func _[type /* ERROR "all type parameters must be named" */ P, *Q interface{}]()`,
+	`package p; func _[type /* ERROR "found 'type'" */ P, *Q interface{}]()`,
 
 	`package p; func (T) _[ /* ERROR "must have no type parameters" */ A, B any](a A) B`,
 	`package p; func (T) _[ /* ERROR "must have no type parameters" */ A, B C](a A) B`,
@@ -262,23 +208,7 @@
 }
 
 func TestInvalid(t *testing.T) {
-	t.Run("no tparams", func(t *testing.T) {
-		for _, src := range invalids {
-			checkErrors(t, src, src, DeclarationErrors|AllErrors|typeparams.DisallowParsing, true)
-		}
-		for _, src := range validWithTParamsOnly {
-			checkErrors(t, src, src, DeclarationErrors|AllErrors|typeparams.DisallowParsing, true)
-		}
-		for _, src := range invalidNoTParamErrs {
-			checkErrors(t, src, src, DeclarationErrors|AllErrors|typeparams.DisallowParsing, true)
-		}
-	})
-	t.Run("tparams", func(t *testing.T) {
-		for _, src := range invalids {
-			checkErrors(t, src, src, DeclarationErrors|AllErrors, true)
-		}
-		for _, src := range invalidTParamErrs {
-			checkErrors(t, src, src, DeclarationErrors|AllErrors, true)
-		}
-	})
+	for _, src := range invalids {
+		checkErrors(t, src, src, DeclarationErrors|AllErrors, true)
+	}
 }
diff --git a/src/go/parser/testdata/commas.src b/src/go/parser/testdata/commas.src
index e0603cf..2c52ae5 100644
--- a/src/go/parser/testdata/commas.src
+++ b/src/go/parser/testdata/commas.src
@@ -8,12 +8,12 @@
 package p
 
 var _ = []int{
-	0/* ERROR HERE "missing ','" */
+	0/* ERROR AFTER "missing ','" */
 }
 
 var _ = []int{
 	0,
 	1,
 	2,
-	3/* ERROR HERE "missing ','" */
+	3/* ERROR AFTER "missing ','" */
 }
diff --git a/src/go/parser/testdata/issue49175.go2 b/src/go/parser/testdata/issue49175.go2
index a5ad30f..cf1c83c 100644
--- a/src/go/parser/testdata/issue49175.go2
+++ b/src/go/parser/testdata/issue49175.go2
@@ -10,4 +10,4 @@
 func _[_ []t]() {}
 func _[_ [1]t]() {}
 
-type t [t /* ERROR "all type parameters must be named" */ [0]]t
+type t [t /* ERROR "type parameters must be named" */ [0]]t
diff --git a/src/go/parser/testdata/tparams.go2 b/src/go/parser/testdata/tparams.go2
index 28fd132..1a9a6c6 100644
--- a/src/go/parser/testdata/tparams.go2
+++ b/src/go/parser/testdata/tparams.go2
@@ -4,22 +4,29 @@
 
 package p
 
-type _[a /* ERROR "all type parameters must be named" */, b] struct{}
-type _[a t, b t, c /* ERROR "all type parameters must be named" */ ] struct{}
+type _[a /* ERROR "type parameters must be named" */, b] struct{}
+type _[a t, b t, c /* ERROR "type parameters must be named" */ ] struct{}
 type _ struct {
 	t [n]byte
 	t[a]
+	t[a,]
 	t[a, b]
+	t[a, b,]
+}
+type _ struct {
+	t [n, /* ERROR "unexpected comma; expecting ]" */ ]byte
 }
 type _ interface {
 	t[a]
+	t[a,]
 	m[ /* ERROR "method must have no type parameters" */ _ _, /* ERROR mixed */ _]()
 	t[a, b]
+	t[a, b,]
 }
 
 func _[] /* ERROR "empty type parameter list" */ ()
-func _[a /* ERROR "all type parameters must be named" */, b ]()
-func _[a t, b t, c /* ERROR "all type parameters must be named" */ ]()
+func _[a /* ERROR "type parameters must be named" */, b ]()
+func _[a t, b t, c /* ERROR "type parameters must be named" */ ]()
 
 // TODO(rfindley) incorrect error message (see existing TODO in parser)
 func f[a b, 0 /* ERROR "expected '\)', found 0" */ ] ()
diff --git a/src/go/parser/testdata/typeparams.src b/src/go/parser/testdata/typeparams.src
deleted file mode 100644
index 479cb96..0000000
--- a/src/go/parser/testdata/typeparams.src
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Test cases for error messages produced while parsing code that uses type
-// parameters, without ParseTypeParams being enabled.
-
-package p
-
-type List[E any /* ERROR "expected ']', found any" */ ] []E
-
-type Pair[L, /* ERROR "unexpected comma" */ R any] struct {
-	Left L
-	Right R
-}
-
-var _ = Pair[int, /* ERROR "expected ']' or ':', found ','" */ string]{}
diff --git a/src/go/printer/comment.go b/src/go/printer/comment.go
index 76dd31e..9012714 100644
--- a/src/go/printer/comment.go
+++ b/src/go/printer/comment.go
@@ -36,15 +36,16 @@
 		kind = "//"
 		var b strings.Builder
 		for _, c := range list {
-			if !strings.HasPrefix(c.Text, "//") {
+			after, found := strings.CutPrefix(c.Text, "//")
+			if !found {
 				return list
 			}
 			// Accumulate //go:build etc lines separately.
-			if isDirective(c.Text[2:]) {
+			if isDirective(after) {
 				directives = append(directives, c)
 				continue
 			}
-			b.WriteString(strings.TrimPrefix(c.Text[2:], " "))
+			b.WriteString(strings.TrimPrefix(after, " "))
 			b.WriteString("\n")
 		}
 		text = b.String()
diff --git a/src/go/printer/example_test.go b/src/go/printer/example_test.go
index 3081693..f7d72d1 100644
--- a/src/go/printer/example_test.go
+++ b/src/go/printer/example_test.go
@@ -12,12 +12,8 @@
 	"go/printer"
 	"go/token"
 	"strings"
-	"testing"
 )
 
-// Dummy test function so that godoc does not use the entire file as example.
-func Test(*testing.T) {}
-
 func parseFunc(filename, functionname string) (fun *ast.FuncDecl, fset *token.FileSet) {
 	fset = token.NewFileSet()
 	if file, err := parser.ParseFile(fset, filename, nil, 0); err == nil {
@@ -31,11 +27,11 @@
 	panic("function not found")
 }
 
-func ExampleFprint() {
+func printSelf() {
 	// Parse source file and extract the AST without comments for
 	// this function, with position information referring to the
 	// file set fset.
-	funcAST, fset := parseFunc("example_test.go", "ExampleFprint")
+	funcAST, fset := parseFunc("example_test.go", "printSelf")
 
 	// Print the function body into buffer buf.
 	// The file set is provided to the printer so that it knows
@@ -52,9 +48,13 @@
 
 	// Print the cleaned-up body text to stdout.
 	fmt.Println(s)
+}
 
-	// output:
-	// funcAST, fset := parseFunc("example_test.go", "ExampleFprint")
+func ExampleFprint() {
+	printSelf()
+
+	// Output:
+	// funcAST, fset := parseFunc("example_test.go", "printSelf")
 	//
 	// var buf bytes.Buffer
 	// printer.Fprint(&buf, fset, funcAST.Body)
diff --git a/src/go/printer/nodes.go b/src/go/printer/nodes.go
index c7cab46..e41ffc1 100644
--- a/src/go/printer/nodes.go
+++ b/src/go/printer/nodes.go
@@ -9,7 +9,6 @@
 package printer
 
 import (
-	"bytes"
 	"go/ast"
 	"go/token"
 	"math"
@@ -153,7 +152,8 @@
 			if i > 0 {
 				// use position of expression following the comma as
 				// comma position for correct comment placement
-				p.print(x.Pos(), token.COMMA, blank)
+				p.setPos(x.Pos())
+				p.print(token.COMMA, blank)
 			}
 			p.expr0(x, depth)
 		}
@@ -244,7 +244,7 @@
 			// comma position for correct comment placement, but
 			// only if the expression is on the same line.
 			if !needsLinebreak {
-				p.print(x.Pos())
+				p.setPos(x.Pos())
 			}
 			p.print(token.COMMA)
 			needsBlank := true
@@ -279,7 +279,8 @@
 			// can align if possible.
 			// (needsLinebreak is set if we started a new line before)
 			p.expr(pair.Key)
-			p.print(pair.Colon, token.COLON, vtab)
+			p.setPos(pair.Colon)
+			p.print(token.COLON, vtab)
 			p.expr(pair.Value)
 		} else {
 			p.expr0(x, depth)
@@ -332,7 +333,8 @@
 	if mode != funcParam {
 		openTok, closeTok = token.LBRACK, token.RBRACK
 	}
-	p.print(fields.Opening, openTok)
+	p.setPos(fields.Opening)
+	p.print(openTok)
 	if len(fields.List) > 0 {
 		prevLine := p.lineFor(fields.Opening)
 		ws := indent
@@ -349,7 +351,7 @@
 				// comma position for correct comma placement, but
 				// only if the next parameter is on the same line
 				if !needsLinebreak {
-					p.print(par.Pos())
+					p.setPos(par.Pos())
 				}
 				p.print(token.COMMA)
 			}
@@ -395,7 +397,8 @@
 		}
 	}
 
-	p.print(fields.Closing, closeTok)
+	p.setPos(fields.Closing)
+	p.print(closeTok)
 }
 
 // combinesWithName reports whether a name followed by the expression x
@@ -503,12 +506,16 @@
 		// possibly a one-line struct/interface
 		if len(list) == 0 {
 			// no blank between keyword and {} in this case
-			p.print(lbrace, token.LBRACE, rbrace, token.RBRACE)
+			p.setPos(lbrace)
+			p.print(token.LBRACE)
+			p.setPos(rbrace)
+			p.print(token.RBRACE)
 			return
 		} else if p.isOneLineFieldList(list) {
 			// small enough - print on one line
 			// (don't use identList and ignore source line breaks)
-			p.print(lbrace, token.LBRACE, blank)
+			p.setPos(lbrace)
+			p.print(token.LBRACE, blank)
 			f := list[0]
 			if isStruct {
 				for i, x := range f.Names {
@@ -532,13 +539,17 @@
 					p.expr(f.Type)
 				}
 			}
-			p.print(blank, rbrace, token.RBRACE)
+			p.print(blank)
+			p.setPos(rbrace)
+			p.print(token.RBRACE)
 			return
 		}
 	}
 	// hasComments || !srcIsOneLine
 
-	p.print(blank, lbrace, token.LBRACE, indent)
+	p.print(blank)
+	p.setPos(lbrace)
+	p.print(token.LBRACE, indent)
 	if hasComments || len(list) > 0 {
 		p.print(formfeed)
 	}
@@ -633,7 +644,9 @@
 		}
 
 	}
-	p.print(unindent, formfeed, rbrace, token.RBRACE)
+	p.print(unindent, formfeed)
+	p.setPos(rbrace)
+	p.print(token.RBRACE)
 }
 
 // ----------------------------------------------------------------------------
@@ -784,7 +797,8 @@
 	}
 	xline := p.pos.Line // before the operator (it may be on the next line!)
 	yline := p.lineFor(x.Y.Pos())
-	p.print(x.OpPos, x.Op)
+	p.setPos(x.OpPos)
+	p.print(x.Op)
 	if xline != yline && xline > 0 && yline > 0 {
 		// at least one line break, but respect an extra empty line
 		// in the source
@@ -808,7 +822,7 @@
 }
 
 func (p *printer) expr1(expr ast.Expr, prec1, depth int) {
-	p.print(expr.Pos())
+	p.setPos(expr.Pos())
 
 	switch x := expr.(type) {
 	case *ast.BadExpr:
@@ -826,7 +840,8 @@
 
 	case *ast.KeyValueExpr:
 		p.expr(x.Key)
-		p.print(x.Colon, token.COLON, blank)
+		p.setPos(x.Colon)
+		p.print(token.COLON, blank)
 		p.expr(x.Value)
 
 	case *ast.StarExpr:
@@ -867,7 +882,8 @@
 		p.print(x)
 
 	case *ast.FuncLit:
-		p.print(x.Type.Pos(), token.FUNC)
+		p.setPos(x.Type.Pos())
+		p.print(token.FUNC)
 		// See the comment in funcDecl about how the header size is computed.
 		startCol := p.out.Column - len("func")
 		p.signature(x.Type)
@@ -881,7 +897,8 @@
 		} else {
 			p.print(token.LPAREN)
 			p.expr0(x.X, reduceDepth(depth)) // parentheses undo one level of depth
-			p.print(x.Rparen, token.RPAREN)
+			p.setPos(x.Rparen)
+			p.print(token.RPAREN)
 		}
 
 	case *ast.SelectorExpr:
@@ -889,33 +906,41 @@
 
 	case *ast.TypeAssertExpr:
 		p.expr1(x.X, token.HighestPrec, depth)
-		p.print(token.PERIOD, x.Lparen, token.LPAREN)
+		p.print(token.PERIOD)
+		p.setPos(x.Lparen)
+		p.print(token.LPAREN)
 		if x.Type != nil {
 			p.expr(x.Type)
 		} else {
 			p.print(token.TYPE)
 		}
-		p.print(x.Rparen, token.RPAREN)
+		p.setPos(x.Rparen)
+		p.print(token.RPAREN)
 
 	case *ast.IndexExpr:
 		// TODO(gri): should treat[] like parentheses and undo one level of depth
 		p.expr1(x.X, token.HighestPrec, 1)
-		p.print(x.Lbrack, token.LBRACK)
+		p.setPos(x.Lbrack)
+		p.print(token.LBRACK)
 		p.expr0(x.Index, depth+1)
-		p.print(x.Rbrack, token.RBRACK)
+		p.setPos(x.Rbrack)
+		p.print(token.RBRACK)
 
 	case *ast.IndexListExpr:
 		// TODO(gri): as for IndexExpr, should treat [] like parentheses and undo
 		// one level of depth
 		p.expr1(x.X, token.HighestPrec, 1)
-		p.print(x.Lbrack, token.LBRACK)
+		p.setPos(x.Lbrack)
+		p.print(token.LBRACK)
 		p.exprList(x.Lbrack, x.Indices, depth+1, commaTerm, x.Rbrack, false)
-		p.print(x.Rbrack, token.RBRACK)
+		p.setPos(x.Rbrack)
+		p.print(token.RBRACK)
 
 	case *ast.SliceExpr:
 		// TODO(gri): should treat[] like parentheses and undo one level of depth
 		p.expr1(x.X, token.HighestPrec, 1)
-		p.print(x.Lbrack, token.LBRACK)
+		p.setPos(x.Lbrack)
+		p.print(token.LBRACK)
 		indices := []ast.Expr{x.Low, x.High}
 		if x.Max != nil {
 			indices = append(indices, x.Max)
@@ -951,7 +976,8 @@
 				p.expr0(x, depth+1)
 			}
 		}
-		p.print(x.Rbrack, token.RBRACK)
+		p.setPos(x.Rbrack)
+		p.print(token.RBRACK)
 
 	case *ast.CallExpr:
 		if len(x.Args) > 1 {
@@ -966,17 +992,20 @@
 		} else {
 			wasIndented = p.possibleSelectorExpr(x.Fun, token.HighestPrec, depth)
 		}
-		p.print(x.Lparen, token.LPAREN)
+		p.setPos(x.Lparen)
+		p.print(token.LPAREN)
 		if x.Ellipsis.IsValid() {
 			p.exprList(x.Lparen, x.Args, depth, 0, x.Ellipsis, false)
-			p.print(x.Ellipsis, token.ELLIPSIS)
+			p.setPos(x.Ellipsis)
+			p.print(token.ELLIPSIS)
 			if x.Rparen.IsValid() && p.lineFor(x.Ellipsis) < p.lineFor(x.Rparen) {
 				p.print(token.COMMA, formfeed)
 			}
 		} else {
 			p.exprList(x.Lparen, x.Args, depth, commaTerm, x.Rparen, false)
 		}
-		p.print(x.Rparen, token.RPAREN)
+		p.setPos(x.Rparen)
+		p.print(token.RPAREN)
 		if wasIndented {
 			p.print(unindent)
 		}
@@ -987,7 +1016,8 @@
 			p.expr1(x.Type, token.HighestPrec, depth)
 		}
 		p.level++
-		p.print(x.Lbrace, token.LBRACE)
+		p.setPos(x.Lbrace)
+		p.print(token.LBRACE)
 		p.exprList(x.Lbrace, x.Elts, 1, commaTerm, x.Rbrace, x.Incomplete)
 		// do not insert extra line break following a /*-style comment
 		// before the closing '}' as it might break the code if there
@@ -1000,7 +1030,9 @@
 		}
 		// need the initial indent to print lone comments with
 		// the proper level of indentation
-		p.print(indent, unindent, mode, x.Rbrace, token.RBRACE, mode)
+		p.print(indent, unindent, mode)
+		p.setPos(x.Rbrace)
+		p.print(token.RBRACE, mode)
 		p.level--
 
 	case *ast.Ellipsis:
@@ -1042,7 +1074,9 @@
 		case ast.RECV:
 			p.print(token.ARROW, token.CHAN) // x.Arrow and x.Pos() are the same
 		case ast.SEND:
-			p.print(token.CHAN, x.Arrow, token.ARROW)
+			p.print(token.CHAN)
+			p.setPos(x.Arrow)
+			p.print(token.ARROW)
 		}
 		p.print(blank)
 		p.expr(x.Value)
@@ -1126,13 +1160,16 @@
 	p.expr1(x.X, token.HighestPrec, depth)
 	p.print(token.PERIOD)
 	if line := p.lineFor(x.Sel.Pos()); p.pos.IsValid() && p.pos.Line < line {
-		p.print(indent, newline, x.Sel.Pos(), x.Sel)
+		p.print(indent, newline)
+		p.setPos(x.Sel.Pos())
+		p.print(x.Sel)
 		if !isMethod {
 			p.print(unindent)
 		}
 		return true
 	}
-	p.print(x.Sel.Pos(), x.Sel)
+	p.setPos(x.Sel.Pos())
+	p.print(x.Sel)
 	return false
 }
 
@@ -1190,10 +1227,12 @@
 
 // block prints an *ast.BlockStmt; it always spans at least two lines.
 func (p *printer) block(b *ast.BlockStmt, nindent int) {
-	p.print(b.Lbrace, token.LBRACE)
+	p.setPos(b.Lbrace)
+	p.print(token.LBRACE)
 	p.stmtList(b.List, nindent, true)
 	p.linebreak(p.lineFor(b.Rbrace), 1, ignore, true)
-	p.print(b.Rbrace, token.RBRACE)
+	p.setPos(b.Rbrace)
+	p.print(token.RBRACE)
 }
 
 func isTypeName(x ast.Expr) bool {
@@ -1308,7 +1347,7 @@
 }
 
 func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool) {
-	p.print(stmt.Pos())
+	p.setPos(stmt.Pos())
 
 	switch s := stmt.(type) {
 	case *ast.BadStmt:
@@ -1326,10 +1365,13 @@
 		// between (see writeWhitespace)
 		p.print(unindent)
 		p.expr(s.Label)
-		p.print(s.Colon, token.COLON, indent)
+		p.setPos(s.Colon)
+		p.print(token.COLON, indent)
 		if e, isEmpty := s.Stmt.(*ast.EmptyStmt); isEmpty {
 			if !nextIsRBrace {
-				p.print(newline, e.Pos(), token.SEMICOLON)
+				p.print(newline)
+				p.setPos(e.Pos())
+				p.print(token.SEMICOLON)
 				break
 			}
 		} else {
@@ -1344,13 +1386,16 @@
 	case *ast.SendStmt:
 		const depth = 1
 		p.expr0(s.Chan, depth)
-		p.print(blank, s.Arrow, token.ARROW, blank)
+		p.print(blank)
+		p.setPos(s.Arrow)
+		p.print(token.ARROW, blank)
 		p.expr0(s.Value, depth)
 
 	case *ast.IncDecStmt:
 		const depth = 1
 		p.expr0(s.X, depth+1)
-		p.print(s.TokPos, s.Tok)
+		p.setPos(s.TokPos)
+		p.print(s.Tok)
 
 	case *ast.AssignStmt:
 		var depth = 1
@@ -1358,7 +1403,9 @@
 			depth++
 		}
 		p.exprList(s.Pos(), s.Lhs, depth, 0, s.TokPos, false)
-		p.print(blank, s.TokPos, s.Tok, blank)
+		p.print(blank)
+		p.setPos(s.TokPos)
+		p.print(s.Tok, blank)
 		p.exprList(s.TokPos, s.Rhs, depth, 0, token.NoPos, false)
 
 	case *ast.GoStmt:
@@ -1425,7 +1472,8 @@
 		} else {
 			p.print(token.DEFAULT)
 		}
-		p.print(s.Colon, token.COLON)
+		p.setPos(s.Colon)
+		p.print(token.COLON)
 		p.stmtList(s.Body, 1, nextIsRBrace)
 
 	case *ast.SwitchStmt:
@@ -1452,7 +1500,8 @@
 		} else {
 			p.print(token.DEFAULT)
 		}
-		p.print(s.Colon, token.COLON)
+		p.setPos(s.Colon)
+		p.print(token.COLON)
 		p.stmtList(s.Body, 1, nextIsRBrace)
 
 	case *ast.SelectStmt:
@@ -1460,7 +1509,10 @@
 		body := s.Body
 		if len(body.List) == 0 && !p.commentBefore(p.posFor(body.Rbrace)) {
 			// print empty select statement w/o comments on one line
-			p.print(body.Lbrace, token.LBRACE, body.Rbrace, token.RBRACE)
+			p.setPos(body.Lbrace)
+			p.print(token.LBRACE)
+			p.setPos(body.Rbrace)
+			p.print(token.RBRACE)
 		} else {
 			p.block(body, 0)
 		}
@@ -1477,10 +1529,13 @@
 			if s.Value != nil {
 				// use position of value following the comma as
 				// comma position for correct comment placement
-				p.print(s.Value.Pos(), token.COMMA, blank)
+				p.setPos(s.Value.Pos())
+				p.print(token.COMMA, blank)
 				p.expr(s.Value)
 			}
-			p.print(blank, s.TokPos, s.Tok, blank)
+			p.print(blank)
+			p.setPos(s.TokPos)
+			p.print(s.Tok, blank)
 		}
 		p.print(token.RANGE, blank)
 		p.expr(stripParens(s.X))
@@ -1639,7 +1694,7 @@
 		}
 		p.expr(sanitizeImportPath(s.Path))
 		p.setComment(s.Comment)
-		p.print(s.EndPos)
+		p.setPos(s.EndPos)
 
 	case *ast.ValueSpec:
 		if n != 1 {
@@ -1681,11 +1736,13 @@
 
 func (p *printer) genDecl(d *ast.GenDecl) {
 	p.setComment(d.Doc)
-	p.print(d.Pos(), d.Tok, blank)
+	p.setPos(d.Pos())
+	p.print(d.Tok, blank)
 
 	if d.Lparen.IsValid() || len(d.Specs) > 1 {
 		// group of parenthesized declarations
-		p.print(d.Lparen, token.LPAREN)
+		p.setPos(d.Lparen)
+		p.print(token.LPAREN)
 		if n := len(d.Specs); n > 0 {
 			p.print(indent, formfeed)
 			if n > 1 && (d.Tok == token.CONST || d.Tok == token.VAR) {
@@ -1712,7 +1769,8 @@
 			}
 			p.print(unindent, formfeed)
 		}
-		p.print(d.Rparen, token.RPAREN)
+		p.setPos(d.Rparen)
+		p.print(token.RPAREN)
 
 	} else if len(d.Specs) > 0 {
 		// single declaration
@@ -1720,6 +1778,26 @@
 	}
 }
 
+// sizeCounter is an io.Writer which counts the number of bytes written,
+// as well as whether a newline character was seen.
+type sizeCounter struct {
+	hasNewline bool
+	size       int
+}
+
+func (c *sizeCounter) Write(p []byte) (int, error) {
+	if !c.hasNewline {
+		for _, b := range p {
+			if b == '\n' || b == '\f' {
+				c.hasNewline = true
+				break
+			}
+		}
+	}
+	c.size += len(p)
+	return len(p), nil
+}
+
 // nodeSize determines the size of n in chars after formatting.
 // The result is <= maxSize if the node fits on one line with at
 // most maxSize chars and the formatted output doesn't contain
@@ -1740,18 +1818,13 @@
 	// style so that we always get the same decision; print
 	// in RawFormat
 	cfg := Config{Mode: RawFormat}
-	var buf bytes.Buffer
-	if err := cfg.fprint(&buf, p.fset, n, p.nodeSizes); err != nil {
+	var counter sizeCounter
+	if err := cfg.fprint(&counter, p.fset, n, p.nodeSizes); err != nil {
 		return
 	}
-	if buf.Len() <= maxSize {
-		for _, ch := range buf.Bytes() {
-			switch ch {
-			case '\n', '\f':
-				return // does not fit in a single line
-			}
-		}
-		size = buf.Len() // n fits
+	if counter.size <= maxSize && !counter.hasNewline {
+		// n fits in a single line
+		size = counter.size
 		p.nodeSizes[n] = size
 	}
 	return
@@ -1811,7 +1884,9 @@
 
 	const maxSize = 100
 	if headerSize+p.bodySize(b, maxSize) <= maxSize {
-		p.print(sep, b.Lbrace, token.LBRACE)
+		p.print(sep)
+		p.setPos(b.Lbrace)
+		p.print(token.LBRACE)
 		if len(b.List) > 0 {
 			p.print(blank)
 			for i, s := range b.List {
@@ -1822,7 +1897,9 @@
 			}
 			p.print(blank)
 		}
-		p.print(noExtraLinebreak, b.Rbrace, token.RBRACE, noExtraLinebreak)
+		p.print(noExtraLinebreak)
+		p.setPos(b.Rbrace)
+		p.print(token.RBRACE, noExtraLinebreak)
 		return
 	}
 
@@ -1844,7 +1921,8 @@
 
 func (p *printer) funcDecl(d *ast.FuncDecl) {
 	p.setComment(d.Doc)
-	p.print(d.Pos(), token.FUNC, blank)
+	p.setPos(d.Pos())
+	p.print(token.FUNC, blank)
 	// We have to save startCol only after emitting FUNC; otherwise it can be on a
 	// different line (all whitespace preceding the FUNC is emitted only when the
 	// FUNC is emitted).
@@ -1861,7 +1939,8 @@
 func (p *printer) decl(decl ast.Decl) {
 	switch d := decl.(type) {
 	case *ast.BadDecl:
-		p.print(d.Pos(), "BadDecl")
+		p.setPos(d.Pos())
+		p.print("BadDecl")
 	case *ast.GenDecl:
 		p.genDecl(d)
 	case *ast.FuncDecl:
@@ -1914,7 +1993,8 @@
 
 func (p *printer) file(src *ast.File) {
 	p.setComment(src.Doc)
-	p.print(src.Pos(), token.PACKAGE, blank)
+	p.setPos(src.Pos())
+	p.print(token.PACKAGE, blank)
 	p.expr(src.Name)
 	p.declList(src.Decls)
 	p.print(newline)
diff --git a/src/go/printer/performance_test.go b/src/go/printer/performance_test.go
index ea6a98c..c58f6d4 100644
--- a/src/go/printer/performance_test.go
+++ b/src/go/printer/performance_test.go
@@ -11,6 +11,7 @@
 	"bytes"
 	"go/ast"
 	"go/parser"
+	"go/token"
 	"io"
 	"log"
 	"os"
@@ -18,12 +19,15 @@
 )
 
 var (
-	testfile *ast.File
-	testsize int64
+	fileNode *ast.File
+	fileSize int64
+
+	declNode ast.Decl
+	declSize int64
 )
 
-func testprint(out io.Writer, file *ast.File) {
-	if err := (&Config{TabIndent | UseSpaces | normalizeNumbers, 8, 0}).Fprint(out, fset, file); err != nil {
+func testprint(out io.Writer, node ast.Node) {
+	if err := (&Config{TabIndent | UseSpaces | normalizeNumbers, 8, 0}).Fprint(out, fset, node); err != nil {
 		log.Fatalf("print error: %s", err)
 	}
 }
@@ -48,17 +52,40 @@
 		log.Fatalf("print error: %s not idempotent", filename)
 	}
 
-	testfile = file
-	testsize = int64(len(src))
+	fileNode = file
+	fileSize = int64(len(src))
+
+	for _, decl := range file.Decls {
+		// The first global variable, which is pretty short:
+		//
+		//	var unresolved = new(ast.Object)
+		if decl, ok := decl.(*ast.GenDecl); ok && decl.Tok == token.VAR {
+			declNode = decl
+			declSize = int64(fset.Position(decl.End()).Offset - fset.Position(decl.Pos()).Offset)
+			break
+		}
+
+	}
 }
 
-func BenchmarkPrint(b *testing.B) {
-	if testfile == nil {
+func BenchmarkPrintFile(b *testing.B) {
+	if fileNode == nil {
 		initialize()
 	}
 	b.ReportAllocs()
-	b.SetBytes(testsize)
+	b.SetBytes(fileSize)
 	for i := 0; i < b.N; i++ {
-		testprint(io.Discard, testfile)
+		testprint(io.Discard, fileNode)
+	}
+}
+
+func BenchmarkPrintDecl(b *testing.B) {
+	if declNode == nil {
+		initialize()
+	}
+	b.ReportAllocs()
+	b.SetBytes(declSize)
+	for i := 0; i < b.N; i++ {
+		testprint(io.Discard, declNode)
 	}
 }
diff --git a/src/go/printer/printer.go b/src/go/printer/printer.go
index 244a19b..741e3f7 100644
--- a/src/go/printer/printer.go
+++ b/src/go/printer/printer.go
@@ -13,6 +13,7 @@
 	"io"
 	"os"
 	"strings"
+	"sync"
 	"text/tabwriter"
 	"unicode"
 )
@@ -94,16 +95,6 @@
 	cachedLine int // line corresponding to cachedPos
 }
 
-func (p *printer) init(cfg *Config, fset *token.FileSet, nodeSizes map[ast.Node]int) {
-	p.Config = *cfg
-	p.fset = fset
-	p.pos = token.Position{Line: 1, Column: 1}
-	p.out = token.Position{Line: 1, Column: 1}
-	p.wsbuf = make([]whiteSpace, 0, 16) // whitespace sequences are short
-	p.nodeSizes = nodeSizes
-	p.cachedPos = -1
-}
-
 func (p *printer) internalError(msg ...any) {
 	if debug {
 		fmt.Print(p.pos.String() + ": ")
@@ -886,6 +877,12 @@
 	return
 }
 
+func (p *printer) setPos(pos token.Pos) {
+	if pos.IsValid() {
+		p.pos = p.posFor(pos) // accurate position of next item
+	}
+}
+
 // print prints a list of "items" (roughly corresponding to syntactic
 // tokens, but also including whitespace and formatting information).
 // It is the only print function that should be called directly from
@@ -982,12 +979,6 @@
 			}
 			p.lastTok = x
 
-		case token.Pos:
-			if x.IsValid() {
-				p.pos = p.posFor(x) // accurate position of next item
-			}
-			continue
-
 		case string:
 			// incorrect AST - print error message
 			data = x
@@ -1049,7 +1040,7 @@
 	return
 }
 
-// getNode returns the ast.CommentGroup associated with n, if any.
+// getDoc returns the ast.CommentGroup associated with n, if any.
 func getDoc(n ast.Node) *ast.CommentGroup {
 	switch n := n.(type) {
 	case *ast.Field:
@@ -1324,11 +1315,47 @@
 	Indent   int  // default: 0 (all code is indented at least by this much)
 }
 
+var printerPool = sync.Pool{
+	New: func() any {
+		return &printer{
+			// Whitespace sequences are short.
+			wsbuf: make([]whiteSpace, 0, 16),
+			// We start the printer with a 16K output buffer, which is currently
+			// larger than about 80% of Go files in the standard library.
+			output: make([]byte, 0, 16<<10),
+		}
+	},
+}
+
+func newPrinter(cfg *Config, fset *token.FileSet, nodeSizes map[ast.Node]int) *printer {
+	p := printerPool.Get().(*printer)
+	*p = printer{
+		Config:    *cfg,
+		fset:      fset,
+		pos:       token.Position{Line: 1, Column: 1},
+		out:       token.Position{Line: 1, Column: 1},
+		wsbuf:     p.wsbuf[:0],
+		nodeSizes: nodeSizes,
+		cachedPos: -1,
+		output:    p.output[:0],
+	}
+	return p
+}
+
+func (p *printer) free() {
+	// Hard limit on buffer size; see https://golang.org/issue/23199.
+	if cap(p.output) > 64<<10 {
+		return
+	}
+
+	printerPool.Put(p)
+}
+
 // fprint implements Fprint and takes a nodesSizes map for setting up the printer state.
 func (cfg *Config) fprint(output io.Writer, fset *token.FileSet, node any, nodeSizes map[ast.Node]int) (err error) {
 	// print node
-	var p printer
-	p.init(cfg, fset, nodeSizes)
+	p := newPrinter(cfg, fset, nodeSizes)
+	defer p.free()
 	if err = p.printNode(node); err != nil {
 		return
 	}
diff --git a/src/go/scanner/example_test.go b/src/go/scanner/example_test.go
index 9004a4a..7493585 100644
--- a/src/go/scanner/example_test.go
+++ b/src/go/scanner/example_test.go
@@ -41,6 +41,6 @@
 	// 1:16	(	""
 	// 1:17	IDENT	"x"
 	// 1:18	)	""
-	// 1:20	;	"\n"
 	// 1:20	COMMENT	"// Euler"
+	// 1:28	;	"\n"
 }
diff --git a/src/go/scanner/scanner.go b/src/go/scanner/scanner.go
index 07e0758..16958d2 100644
--- a/src/go/scanner/scanner.go
+++ b/src/go/scanner/scanner.go
@@ -35,11 +35,12 @@
 	mode Mode         // scanning mode
 
 	// scanning state
-	ch         rune // current character
-	offset     int  // character offset
-	rdOffset   int  // reading offset (position after current character)
-	lineOffset int  // current line offset
-	insertSemi bool // insert a semicolon before next newline
+	ch         rune      // current character
+	offset     int       // character offset
+	rdOffset   int       // reading offset (position after current character)
+	lineOffset int       // current line offset
+	insertSemi bool      // insert a semicolon before next newline
+	nlPos      token.Pos // position of newline in preceding comment
 
 	// public state - ok to modify
 	ErrorCount int // number of errors encountered
@@ -154,11 +155,15 @@
 	s.error(offs, fmt.Sprintf(format, args...))
 }
 
-func (s *Scanner) scanComment() string {
+// scanComment returns the text of the comment and (if nonzero)
+// the offset of the first newline within it, which implies a
+// /*...*/ comment.
+func (s *Scanner) scanComment() (string, int) {
 	// initial '/' already consumed; s.ch == '/' || s.ch == '*'
 	offs := s.offset - 1 // position of initial '/'
 	next := -1           // position immediately following the comment; < 0 means invalid comment
 	numCR := 0
+	nlOffset := 0 // offset of first newline within /*...*/ comment
 
 	if s.ch == '/' {
 		//-style comment
@@ -184,6 +189,8 @@
 		ch := s.ch
 		if ch == '\r' {
 			numCR++
+		} else if ch == '\n' && nlOffset == 0 {
+			nlOffset = s.offset
 		}
 		s.next()
 		if ch == '*' && s.ch == '/' {
@@ -218,7 +225,7 @@
 		lit = stripCR(lit, lit[1] == '*')
 	}
 
-	return string(lit)
+	return string(lit), nlOffset
 }
 
 var prefix = []byte("line ")
@@ -295,50 +302,6 @@
 	return i + 1, int(n), err == nil
 }
 
-func (s *Scanner) findLineEnd() bool {
-	// initial '/' already consumed
-
-	defer func(offs int) {
-		// reset scanner state to where it was upon calling findLineEnd
-		s.ch = '/'
-		s.offset = offs
-		s.rdOffset = offs + 1
-		s.next() // consume initial '/' again
-	}(s.offset - 1)
-
-	// read ahead until a newline, EOF, or non-comment token is found
-	for s.ch == '/' || s.ch == '*' {
-		if s.ch == '/' {
-			//-style comment always contains a newline
-			return true
-		}
-		/*-style comment: look for newline */
-		s.next()
-		for s.ch >= 0 {
-			ch := s.ch
-			if ch == '\n' {
-				return true
-			}
-			s.next()
-			if ch == '*' && s.ch == '/' {
-				s.next()
-				break
-			}
-		}
-		s.skipWhitespace() // s.insertSemi is set
-		if s.ch < 0 || s.ch == '\n' {
-			return true
-		}
-		if s.ch != '/' {
-			// non-comment token
-			return false
-		}
-		s.next() // consume '/'
-	}
-
-	return false
-}
-
 func isLetter(ch rune) bool {
 	return 'a' <= lower(ch) && lower(ch) <= 'z' || ch == '_' || ch >= utf8.RuneSelf && unicode.IsLetter(ch)
 }
@@ -822,6 +785,14 @@
 // and thus relative to the file set.
 func (s *Scanner) Scan() (pos token.Pos, tok token.Token, lit string) {
 scanAgain:
+	if s.nlPos.IsValid() {
+		// Return artificial ';' token after /*...*/ comment
+		// containing newline, at position of first newline.
+		pos, tok, lit = s.nlPos, token.SEMICOLON, "\n"
+		s.nlPos = token.NoPos
+		return
+	}
+
 	s.skipWhitespace()
 
 	// current token start
@@ -849,7 +820,7 @@
 	default:
 		s.next() // always make progress
 		switch ch {
-		case -1:
+		case eof:
 			if s.insertSemi {
 				s.insertSemi = false // EOF consumed
 				return pos, token.SEMICOLON, "\n"
@@ -918,23 +889,23 @@
 		case '/':
 			if s.ch == '/' || s.ch == '*' {
 				// comment
-				if s.insertSemi && s.findLineEnd() {
-					// reset position to the beginning of the comment
-					s.ch = '/'
-					s.offset = s.file.Offset(pos)
-					s.rdOffset = s.offset + 1
-					s.insertSemi = false // newline consumed
-					return pos, token.SEMICOLON, "\n"
+				comment, nlOffset := s.scanComment()
+				if s.insertSemi && nlOffset != 0 {
+					// For /*...*/ containing \n, return
+					// COMMENT then artificial SEMICOLON.
+					s.nlPos = s.file.Pos(nlOffset)
+					s.insertSemi = false
+				} else {
+					insertSemi = s.insertSemi // preserve insertSemi info
 				}
-				comment := s.scanComment()
 				if s.mode&ScanComments == 0 {
 					// skip comment
-					s.insertSemi = false // newline consumed
 					goto scanAgain
 				}
 				tok = token.COMMENT
 				lit = comment
 			} else {
+				// division
 				tok = s.switch2(token.QUO, token.QUO_ASSIGN)
 			}
 		case '%':
diff --git a/src/go/scanner/scanner_test.go b/src/go/scanner/scanner_test.go
index de45e16..4f320ee 100644
--- a/src/go/scanner/scanner_test.go
+++ b/src/go/scanner/scanner_test.go
@@ -334,173 +334,171 @@
 	}
 }
 
-func checkSemi(t *testing.T, line string, mode Mode) {
-	var S Scanner
-	file := fset.AddFile("TestSemis", fset.Base(), len(line))
-	S.Init(file, []byte(line), nil, mode)
-	pos, tok, lit := S.Scan()
-	for tok != token.EOF {
-		if tok == token.ILLEGAL {
-			// the illegal token literal indicates what
-			// kind of semicolon literal to expect
-			semiLit := "\n"
-			if lit[0] == '#' {
-				semiLit = ";"
-			}
-			// next token must be a semicolon
-			semiPos := file.Position(pos)
-			semiPos.Offset++
-			semiPos.Column++
-			pos, tok, lit = S.Scan()
-			if tok == token.SEMICOLON {
-				if lit != semiLit {
-					t.Errorf(`bad literal for %q: got %q, expected %q`, line, lit, semiLit)
-				}
-				checkPos(t, line, pos, semiPos)
-			} else {
-				t.Errorf("bad token for %q: got %s, expected ;", line, tok)
-			}
-		} else if tok == token.SEMICOLON {
-			t.Errorf("bad token for %q: got ;, expected no ;", line)
+func checkSemi(t *testing.T, input, want string, mode Mode) {
+	if mode&ScanComments == 0 {
+		want = strings.ReplaceAll(want, "COMMENT ", "")
+		want = strings.ReplaceAll(want, " COMMENT", "") // if at end
+		want = strings.ReplaceAll(want, "COMMENT", "")  // if sole token
+	}
+
+	file := fset.AddFile("TestSemis", fset.Base(), len(input))
+	var scan Scanner
+	scan.Init(file, []byte(input), nil, mode)
+	var tokens []string
+	for {
+		pos, tok, lit := scan.Scan()
+		if tok == token.EOF {
+			break
 		}
-		pos, tok, lit = S.Scan()
+		if tok == token.SEMICOLON && lit != ";" {
+			// Artifical semicolon:
+			// assert that position is EOF or that of a newline.
+			off := file.Offset(pos)
+			if off != len(input) && input[off] != '\n' {
+				t.Errorf("scanning <<%s>>, got SEMICOLON at offset %d, want newline or EOF", input, off)
+			}
+		}
+		lit = tok.String() // "\n" => ";"
+		tokens = append(tokens, lit)
+	}
+	if got := strings.Join(tokens, " "); got != want {
+		t.Errorf("scanning <<%s>>, got [%s], want [%s]", input, got, want)
 	}
 }
 
-var lines = []string{
-	// # indicates a semicolon present in the source
-	// $ indicates an automatically inserted semicolon
-	"",
-	"\ufeff#;", // first BOM is ignored
-	"#;",
-	"foo$\n",
-	"123$\n",
-	"1.2$\n",
-	"'x'$\n",
-	`"x"` + "$\n",
-	"`x`$\n",
+var semicolonTests = [...]struct{ input, want string }{
+	{"", ""},
+	{"\ufeff;", ";"}, // first BOM is ignored
+	{";", ";"},
+	{"foo\n", "IDENT ;"},
+	{"123\n", "INT ;"},
+	{"1.2\n", "FLOAT ;"},
+	{"'x'\n", "CHAR ;"},
+	{`"x"` + "\n", "STRING ;"},
+	{"`x`\n", "STRING ;"},
 
-	"+\n",
-	"-\n",
-	"*\n",
-	"/\n",
-	"%\n",
+	{"+\n", "+"},
+	{"-\n", "-"},
+	{"*\n", "*"},
+	{"/\n", "/"},
+	{"%\n", "%"},
 
-	"&\n",
-	"|\n",
-	"^\n",
-	"<<\n",
-	">>\n",
-	"&^\n",
+	{"&\n", "&"},
+	{"|\n", "|"},
+	{"^\n", "^"},
+	{"<<\n", "<<"},
+	{">>\n", ">>"},
+	{"&^\n", "&^"},
 
-	"+=\n",
-	"-=\n",
-	"*=\n",
-	"/=\n",
-	"%=\n",
+	{"+=\n", "+="},
+	{"-=\n", "-="},
+	{"*=\n", "*="},
+	{"/=\n", "/="},
+	{"%=\n", "%="},
 
-	"&=\n",
-	"|=\n",
-	"^=\n",
-	"<<=\n",
-	">>=\n",
-	"&^=\n",
+	{"&=\n", "&="},
+	{"|=\n", "|="},
+	{"^=\n", "^="},
+	{"<<=\n", "<<="},
+	{">>=\n", ">>="},
+	{"&^=\n", "&^="},
 
-	"&&\n",
-	"||\n",
-	"<-\n",
-	"++$\n",
-	"--$\n",
+	{"&&\n", "&&"},
+	{"||\n", "||"},
+	{"<-\n", "<-"},
+	{"++\n", "++ ;"},
+	{"--\n", "-- ;"},
 
-	"==\n",
-	"<\n",
-	">\n",
-	"=\n",
-	"!\n",
+	{"==\n", "=="},
+	{"<\n", "<"},
+	{">\n", ">"},
+	{"=\n", "="},
+	{"!\n", "!"},
 
-	"!=\n",
-	"<=\n",
-	">=\n",
-	":=\n",
-	"...\n",
+	{"!=\n", "!="},
+	{"<=\n", "<="},
+	{">=\n", ">="},
+	{":=\n", ":="},
+	{"...\n", "..."},
 
-	"(\n",
-	"[\n",
-	"{\n",
-	",\n",
-	".\n",
+	{"(\n", "("},
+	{"[\n", "["},
+	{"{\n", "{"},
+	{",\n", ","},
+	{".\n", "."},
 
-	")$\n",
-	"]$\n",
-	"}$\n",
-	"#;\n",
-	":\n",
+	{")\n", ") ;"},
+	{"]\n", "] ;"},
+	{"}\n", "} ;"},
+	{";\n", ";"},
+	{":\n", ":"},
 
-	"break$\n",
-	"case\n",
-	"chan\n",
-	"const\n",
-	"continue$\n",
+	{"break\n", "break ;"},
+	{"case\n", "case"},
+	{"chan\n", "chan"},
+	{"const\n", "const"},
+	{"continue\n", "continue ;"},
 
-	"default\n",
-	"defer\n",
-	"else\n",
-	"fallthrough$\n",
-	"for\n",
+	{"default\n", "default"},
+	{"defer\n", "defer"},
+	{"else\n", "else"},
+	{"fallthrough\n", "fallthrough ;"},
+	{"for\n", "for"},
 
-	"func\n",
-	"go\n",
-	"goto\n",
-	"if\n",
-	"import\n",
+	{"func\n", "func"},
+	{"go\n", "go"},
+	{"goto\n", "goto"},
+	{"if\n", "if"},
+	{"import\n", "import"},
 
-	"interface\n",
-	"map\n",
-	"package\n",
-	"range\n",
-	"return$\n",
+	{"interface\n", "interface"},
+	{"map\n", "map"},
+	{"package\n", "package"},
+	{"range\n", "range"},
+	{"return\n", "return ;"},
 
-	"select\n",
-	"struct\n",
-	"switch\n",
-	"type\n",
-	"var\n",
+	{"select\n", "select"},
+	{"struct\n", "struct"},
+	{"switch\n", "switch"},
+	{"type\n", "type"},
+	{"var\n", "var"},
 
-	"foo$//comment\n",
-	"foo$//comment",
-	"foo$/*comment*/\n",
-	"foo$/*\n*/",
-	"foo$/*comment*/    \n",
-	"foo$/*\n*/    ",
+	{"foo//comment\n", "IDENT COMMENT ;"},
+	{"foo//comment", "IDENT COMMENT ;"},
+	{"foo/*comment*/\n", "IDENT COMMENT ;"},
+	{"foo/*\n*/", "IDENT COMMENT ;"},
+	{"foo/*comment*/    \n", "IDENT COMMENT ;"},
+	{"foo/*\n*/    ", "IDENT COMMENT ;"},
 
-	"foo    $// comment\n",
-	"foo    $// comment",
-	"foo    $/*comment*/\n",
-	"foo    $/*\n*/",
-	"foo    $/*  */ /* \n */ bar$/**/\n",
-	"foo    $/*0*/ /*1*/ /*2*/\n",
+	{"foo    // comment\n", "IDENT COMMENT ;"},
+	{"foo    // comment", "IDENT COMMENT ;"},
+	{"foo    /*comment*/\n", "IDENT COMMENT ;"},
+	{"foo    /*\n*/", "IDENT COMMENT ;"},
+	{"foo    /*  */ /* \n */ bar/**/\n", "IDENT COMMENT COMMENT ; IDENT COMMENT ;"},
+	{"foo    /*0*/ /*1*/ /*2*/\n", "IDENT COMMENT COMMENT COMMENT ;"},
 
-	"foo    $/*comment*/    \n",
-	"foo    $/*0*/ /*1*/ /*2*/    \n",
-	"foo	$/**/ /*-------------*/       /*----\n*/bar       $/*  \n*/baa$\n",
-	"foo    $/* an EOF terminates a line */",
-	"foo    $/* an EOF terminates a line */ /*",
-	"foo    $/* an EOF terminates a line */ //",
+	{"foo    /*comment*/    \n", "IDENT COMMENT ;"},
+	{"foo    /*0*/ /*1*/ /*2*/    \n", "IDENT COMMENT COMMENT COMMENT ;"},
+	{"foo	/**/ /*-------------*/       /*----\n*/bar       /*  \n*/baa\n", "IDENT COMMENT COMMENT COMMENT ; IDENT COMMENT ; IDENT ;"},
+	{"foo    /* an EOF terminates a line */", "IDENT COMMENT ;"},
+	{"foo    /* an EOF terminates a line */ /*", "IDENT COMMENT COMMENT ;"},
+	{"foo    /* an EOF terminates a line */ //", "IDENT COMMENT COMMENT ;"},
 
-	"package main$\n\nfunc main() {\n\tif {\n\t\treturn /* */ }$\n}$\n",
-	"package main$",
+	{"package main\n\nfunc main() {\n\tif {\n\t\treturn /* */ }\n}\n", "package IDENT ; func IDENT ( ) { if { return COMMENT } ; } ;"},
+	{"package main", "package IDENT ;"},
 }
 
-func TestSemis(t *testing.T) {
-	for _, line := range lines {
-		checkSemi(t, line, 0)
-		checkSemi(t, line, ScanComments)
+func TestSemicolons(t *testing.T) {
+	for _, test := range semicolonTests {
+		input, want := test.input, test.want
+		checkSemi(t, input, want, 0)
+		checkSemi(t, input, want, ScanComments)
 
 		// if the input ended in newlines, the input must tokenize the
 		// same with or without those newlines
-		for i := len(line) - 1; i >= 0 && line[i] == '\n'; i-- {
-			checkSemi(t, line[0:i], 0)
-			checkSemi(t, line[0:i], ScanComments)
+		for i := len(input) - 1; i >= 0 && input[i] == '\n'; i-- {
+			checkSemi(t, input[0:i], want, 0)
+			checkSemi(t, input[0:i], want, ScanComments)
 		}
 	}
 }
@@ -668,7 +666,7 @@
 	}
 }
 
-func TestStdErrorHander(t *testing.T) {
+func TestStdErrorHandler(t *testing.T) {
 	const src = "@\n" + // illegal character, cause an error
 		"@ @\n" + // two errors on the same line
 		"//line File2:20\n" +
diff --git a/src/go/token/position.go b/src/go/token/position.go
index b5a380a..cbc2ddb 100644
--- a/src/go/token/position.go
+++ b/src/go/token/position.go
@@ -245,7 +245,7 @@
 // information for line directives such as //line filename:line:column.
 func (f *File) AddLineColumnInfo(offset int, filename string, line, column int) {
 	f.mutex.Lock()
-	if i := len(f.infos); i == 0 || f.infos[i-1].Offset < offset && offset < f.size {
+	if i := len(f.infos); (i == 0 || f.infos[i-1].Offset < offset) && offset < f.size {
 		f.infos = append(f.infos, lineInfo{offset, filename, line, column})
 	}
 	f.mutex.Unlock()
@@ -286,7 +286,6 @@
 // possibly adjusted by //line comments; otherwise those comments are ignored.
 func (f *File) unpack(offset int, adjusted bool) (filename string, line, column int) {
 	f.mutex.Lock()
-	defer f.mutex.Unlock()
 	filename = f.name
 	if i := searchInts(f.lines, offset); i >= 0 {
 		line, column = i+1, offset-f.lines[i]+1
@@ -314,6 +313,9 @@
 			}
 		}
 	}
+	// TODO(mvdan): move Unlock back under Lock with a defer statement once
+	// https://go.dev/issue/38471 is fixed to remove the performance penalty.
+	f.mutex.Unlock()
 	return
 }
 
@@ -366,6 +368,9 @@
 // recently added file, plus one. Unless there is a need to extend an
 // interval later, using the FileSet.Base should be used as argument
 // for FileSet.AddFile.
+//
+// A File may be removed from a FileSet when it is no longer needed.
+// This may reduce memory usage in a long-running application.
 type FileSet struct {
 	mutex sync.RWMutex         // protects the file set
 	base  int                  // base offset for the next file
@@ -433,6 +438,25 @@
 	return f
 }
 
+// RemoveFile removes a file from the FileSet so that subsequent
+// queries for its Pos interval yield a negative result.
+// This reduces the memory usage of a long-lived FileSet that
+// encounters an unbounded stream of files.
+//
+// Removing a file that does not belong to the set has no effect.
+func (s *FileSet) RemoveFile(file *File) {
+	s.last.CompareAndSwap(file, nil) // clear last file cache
+
+	s.mutex.Lock()
+	defer s.mutex.Unlock()
+
+	if i := searchFiles(s.files, file.base); i >= 0 && s.files[i] == file {
+		last := &s.files[len(s.files)-1]
+		s.files = append(s.files[:i], s.files[i+1:]...)
+		*last = nil // don't prolong lifetime when popping last element
+	}
+}
+
 // Iterate calls f for the files in the file set in the order they were added
 // until f returns false.
 func (s *FileSet) Iterate(f func(*File) bool) {
diff --git a/src/go/token/position_test.go b/src/go/token/position_test.go
index 7d465df..65cb242 100644
--- a/src/go/token/position_test.go
+++ b/src/go/token/position_test.go
@@ -7,6 +7,7 @@
 import (
 	"fmt"
 	"math/rand"
+	"reflect"
 	"sync"
 	"testing"
 )
@@ -339,3 +340,138 @@
 		}
 	}
 }
+
+func TestRemoveFile(t *testing.T) {
+	contentA := []byte("this\nis\nfileA")
+	contentB := []byte("this\nis\nfileB")
+	fset := NewFileSet()
+	a := fset.AddFile("fileA", -1, len(contentA))
+	a.SetLinesForContent(contentA)
+	b := fset.AddFile("fileB", -1, len(contentB))
+	b.SetLinesForContent(contentB)
+
+	checkPos := func(pos Pos, want string) {
+		if got := fset.Position(pos).String(); got != want {
+			t.Errorf("Position(%d) = %s, want %s", pos, got, want)
+		}
+	}
+	checkNumFiles := func(want int) {
+		got := 0
+		fset.Iterate(func(*File) bool { got++; return true })
+		if got != want {
+			t.Errorf("Iterate called %d times, want %d", got, want)
+		}
+	}
+
+	apos3 := a.Pos(3)
+	bpos3 := b.Pos(3)
+	checkPos(apos3, "fileA:1:4")
+	checkPos(bpos3, "fileB:1:4")
+	checkNumFiles(2)
+
+	// After removal, queries on fileA fail.
+	fset.RemoveFile(a)
+	checkPos(apos3, "-")
+	checkPos(bpos3, "fileB:1:4")
+	checkNumFiles(1)
+
+	// idempotent / no effect
+	fset.RemoveFile(a)
+	checkPos(apos3, "-")
+	checkPos(bpos3, "fileB:1:4")
+	checkNumFiles(1)
+}
+
+func TestFileAddLineColumnInfo(t *testing.T) {
+	const (
+		filename = "test.go"
+		filesize = 100
+	)
+
+	tests := []struct {
+		name  string
+		infos []lineInfo
+		want  []lineInfo
+	}{
+		{
+			name: "normal",
+			infos: []lineInfo{
+				{Offset: 10, Filename: filename, Line: 2, Column: 1},
+				{Offset: 50, Filename: filename, Line: 3, Column: 1},
+				{Offset: 80, Filename: filename, Line: 4, Column: 2},
+			},
+			want: []lineInfo{
+				{Offset: 10, Filename: filename, Line: 2, Column: 1},
+				{Offset: 50, Filename: filename, Line: 3, Column: 1},
+				{Offset: 80, Filename: filename, Line: 4, Column: 2},
+			},
+		},
+		{
+			name: "offset1 == file size",
+			infos: []lineInfo{
+				{Offset: filesize, Filename: filename, Line: 2, Column: 1},
+			},
+			want: nil,
+		},
+		{
+			name: "offset1 > file size",
+			infos: []lineInfo{
+				{Offset: filesize + 1, Filename: filename, Line: 2, Column: 1},
+			},
+			want: nil,
+		},
+		{
+			name: "offset2 == file size",
+			infos: []lineInfo{
+				{Offset: 10, Filename: filename, Line: 2, Column: 1},
+				{Offset: filesize, Filename: filename, Line: 3, Column: 1},
+			},
+			want: []lineInfo{
+				{Offset: 10, Filename: filename, Line: 2, Column: 1},
+			},
+		},
+		{
+			name: "offset2 > file size",
+			infos: []lineInfo{
+				{Offset: 10, Filename: filename, Line: 2, Column: 1},
+				{Offset: filesize + 1, Filename: filename, Line: 3, Column: 1},
+			},
+			want: []lineInfo{
+				{Offset: 10, Filename: filename, Line: 2, Column: 1},
+			},
+		},
+		{
+			name: "offset2 == offset1",
+			infos: []lineInfo{
+				{Offset: 10, Filename: filename, Line: 2, Column: 1},
+				{Offset: 10, Filename: filename, Line: 3, Column: 1},
+			},
+			want: []lineInfo{
+				{Offset: 10, Filename: filename, Line: 2, Column: 1},
+			},
+		},
+		{
+			name: "offset2 < offset1",
+			infos: []lineInfo{
+				{Offset: 10, Filename: filename, Line: 2, Column: 1},
+				{Offset: 9, Filename: filename, Line: 3, Column: 1},
+			},
+			want: []lineInfo{
+				{Offset: 10, Filename: filename, Line: 2, Column: 1},
+			},
+		},
+	}
+
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			fs := NewFileSet()
+			f := fs.AddFile(filename, -1, filesize)
+			for _, info := range test.infos {
+				f.AddLineColumnInfo(info.Offset, info.Filename, info.Line, info.Column)
+			}
+			if !reflect.DeepEqual(f.infos, test.want) {
+				t.Errorf("\ngot %+v, \nwant %+v", f.infos, test.want)
+			}
+		})
+	}
+}
diff --git a/src/go/types/api.go b/src/go/types/api.go
index 5e7be29..eda41b3 100644
--- a/src/go/types/api.go
+++ b/src/go/types/api.go
@@ -31,6 +31,7 @@
 	"go/ast"
 	"go/constant"
 	"go/token"
+	. "internal/types/errors"
 )
 
 // An Error describes a type-checking error; it implements the error interface.
@@ -48,7 +49,7 @@
 	// to preview this feature may read go116code using reflection (see
 	// errorcodes_test.go), but beware that there is no guarantee of future
 	// compatibility.
-	go116code  errorCode
+	go116code  Code
 	go116start token.Pos
 	go116end   token.Pos
 }
@@ -166,6 +167,11 @@
 	// If DisableUnusedImportCheck is set, packages are not checked
 	// for unused imports.
 	DisableUnusedImportCheck bool
+
+	// If oldComparableSemantics is set, ordinary (non-type parameter)
+	// interfaces do not satisfy the comparable constraint.
+	// TODO(gri) remove this flag for Go 1.21
+	oldComparableSemantics bool
 }
 
 func srcimporter_setUsesCgo(conf *Config) {
@@ -424,7 +430,7 @@
 	if T.Underlying() == Typ[Invalid] {
 		return false
 	}
-	return (*Checker)(nil).newAssertableTo(V, T) == nil
+	return (*Checker)(nil).newAssertableTo(V, T)
 }
 
 // AssignableTo reports whether a value of type V is assignable to a variable
@@ -462,7 +468,15 @@
 	if V.Underlying() == Typ[Invalid] {
 		return false
 	}
-	return (*Checker)(nil).implements(V, T) == nil
+	return (*Checker)(nil).implements(V, T, false, nil)
+}
+
+// Satisfies reports whether type V satisfies the constraint T.
+//
+// The behavior of Satisfies is unspecified if V is Typ[Invalid] or an uninstantiated
+// generic type.
+func Satisfies(V Type, T *Interface) bool {
+	return (*Checker)(nil).implements(V, T, true, nil)
 }
 
 // Identical reports whether x and y are identical types.
diff --git a/src/go/types/api_test.go b/src/go/types/api_test.go
index db2ace5..98ef6c4 100644
--- a/src/go/types/api_test.go
+++ b/src/go/types/api_test.go
@@ -5,12 +5,10 @@
 package types_test
 
 import (
-	"bytes"
 	"errors"
 	"fmt"
 	"go/ast"
 	"go/importer"
-	"go/internal/typeparams"
 	"go/parser"
 	"go/token"
 	"internal/testenv"
@@ -23,62 +21,37 @@
 	. "go/types"
 )
 
-// pkgFor parses and type checks the package specified by path and source,
-// populating info if provided.
-//
-// If source begins with "package generic_" and type parameters are enabled,
-// generic code is permitted.
-func pkgFor(path, source string, info *Info) (*Package, error) {
-	mode := modeForSource(source)
-	return pkgForMode(path, source, info, mode)
+func parse(fset *token.FileSet, filename, src string) (*ast.File, error) {
+	return parser.ParseFile(fset, filename, src, 0)
 }
 
-func pkgForMode(path, source string, info *Info, mode parser.Mode) (*Package, error) {
-	fset := token.NewFileSet()
-	f, err := parser.ParseFile(fset, path, source, mode)
+func mustParse(fset *token.FileSet, filename, src string) *ast.File {
+	f, err := parse(fset, filename, src)
 	if err != nil {
+		panic(err) // so we don't need to pass *testing.T
+	}
+	return f
+}
+
+func typecheck(path, src string, info *Info) (*Package, error) {
+	fset := token.NewFileSet()
+	f, err := parse(fset, path, src)
+	if f == nil { // ignore errors unless f is nil
 		return nil, err
 	}
-	conf := Config{Importer: importer.Default()}
+	conf := Config{
+		Error:    func(err error) {}, // collect all errors
+		Importer: importer.Default(),
+	}
 	return conf.Check(f.Name.Name, fset, []*ast.File{f}, info)
 }
 
-func mustTypecheck(t testing.TB, path, source string, info *Info) string {
-	pkg, err := pkgFor(path, source, info)
+func mustTypecheck(path, src string, info *Info) *Package {
+	pkg, err := typecheck(path, src, info)
 	if err != nil {
-		name := path
-		if pkg != nil {
-			name = "package " + pkg.Name()
-		}
-		t.Fatalf("%s: didn't type-check (%s)", name, err)
+		panic(err) // so we don't need to pass *testing.T
 	}
-	return pkg.Name()
-}
-
-// genericPkg is a prefix for packages that should be type checked with
-// generics.
-const genericPkg = "package generic_"
-
-func modeForSource(src string) parser.Mode {
-	if !strings.HasPrefix(src, genericPkg) {
-		return typeparams.DisallowParsing
-	}
-	return 0
-}
-
-func mayTypecheck(t *testing.T, path, source string, info *Info) (string, error) {
-	fset := token.NewFileSet()
-	mode := modeForSource(source)
-	f, err := parser.ParseFile(fset, path, source, mode)
-	if f == nil { // ignore errors unless f is nil
-		t.Fatalf("%s: unable to parse: %s", path, err)
-	}
-	conf := Config{
-		Error:    func(err error) {},
-		Importer: importer.Default(),
-	}
-	pkg, err := conf.Check(f.Name.Name, fset, []*ast.File{f}, info)
-	return pkg.Name(), err
+	return pkg
 }
 
 func TestValuesInfo(t *testing.T) {
@@ -164,7 +137,7 @@
 		info := Info{
 			Types: make(map[ast.Expr]TypeAndValue),
 		}
-		name := mustTypecheck(t, "ValuesInfo", test.src, &info)
+		name := mustTypecheck("ValuesInfo", test.src, &info).Name()
 
 		// look for expression
 		var expr ast.Expr
@@ -349,69 +322,69 @@
 		{broken + `x5; func _() { var x map[string][...]int; x = map[string][...]int{"": {1,2,3}} }`, `x`, `map[string]invalid type`},
 
 		// parameterized functions
-		{genericPkg + `p0; func f[T any](T) {}; var _ = f[int]`, `f`, `func[T any](T)`},
-		{genericPkg + `p1; func f[T any](T) {}; var _ = f[int]`, `f[int]`, `func(int)`},
-		{genericPkg + `p2; func f[T any](T) {}; func _() { f(42) }`, `f`, `func(int)`},
-		{genericPkg + `p3; func f[T any](T) {}; func _() { f[int](42) }`, `f[int]`, `func(int)`},
-		{genericPkg + `p4; func f[T any](T) {}; func _() { f[int](42) }`, `f`, `func[T any](T)`},
-		{genericPkg + `p5; func f[T any](T) {}; func _() { f(42) }`, `f(42)`, `()`},
+		{`package p0; func f[T any](T) {}; var _ = f[int]`, `f`, `func[T any](T)`},
+		{`package p1; func f[T any](T) {}; var _ = f[int]`, `f[int]`, `func(int)`},
+		{`package p2; func f[T any](T) {}; func _() { f(42) }`, `f`, `func(int)`},
+		{`package p3; func f[T any](T) {}; func _() { f[int](42) }`, `f[int]`, `func(int)`},
+		{`package p4; func f[T any](T) {}; func _() { f[int](42) }`, `f`, `func[T any](T)`},
+		{`package p5; func f[T any](T) {}; func _() { f(42) }`, `f(42)`, `()`},
 
 		// type parameters
-		{genericPkg + `t0; type t[] int; var _ t`, `t`, `generic_t0.t`}, // t[] is a syntax error that is ignored in this test in favor of t
-		{genericPkg + `t1; type t[P any] int; var _ t[int]`, `t`, `generic_t1.t[P any]`},
-		{genericPkg + `t2; type t[P interface{}] int; var _ t[int]`, `t`, `generic_t2.t[P interface{}]`},
-		{genericPkg + `t3; type t[P, Q interface{}] int; var _ t[int, int]`, `t`, `generic_t3.t[P, Q interface{}]`},
-
-		// TODO (rFindley): compare with types2, which resolves the type broken_t4.t[P₁, Q₂ interface{m()}] here
-		{broken + `t4; type t[P, Q interface{ m() }] int; var _ t[int, int]`, `t`, `broken_t4.t`},
+		{`package t0; type t[] int; var _ t`, `t`, `t0.t`}, // t[] is a syntax error that is ignored in this test in favor of t
+		{`package t1; type t[P any] int; var _ t[int]`, `t`, `t1.t[P any]`},
+		{`package t2; type t[P interface{}] int; var _ t[int]`, `t`, `t2.t[P interface{}]`},
+		{`package t3; type t[P, Q interface{}] int; var _ t[int, int]`, `t`, `t3.t[P, Q interface{}]`},
+		{broken + `t4; type t[P, Q interface{ m() }] int; var _ t[int, int]`, `t`, `broken_t4.t[P, Q interface{m()}]`},
 
 		// instantiated types must be sanitized
-		{genericPkg + `g0; type t[P any] int; var x struct{ f t[int] }; var _ = x.f`, `x.f`, `generic_g0.t[int]`},
+		{`package g0; type t[P any] int; var x struct{ f t[int] }; var _ = x.f`, `x.f`, `g0.t[int]`},
 
 		// issue 45096
-		{genericPkg + `issue45096; func _[T interface{ ~int8 | ~int16 | ~int32  }](x T) { _ = x < 0 }`, `0`, `T`},
+		{`package issue45096; func _[T interface{ ~int8 | ~int16 | ~int32  }](x T) { _ = x < 0 }`, `0`, `T`},
 
 		// issue 47895
 		{`package p; import "unsafe"; type S struct { f int }; var s S; var _ = unsafe.Offsetof(s.f)`, `s.f`, `int`},
 
 		// issue 50093
-		{genericPkg + `u0a; func _[_ interface{int}]() {}`, `int`, `int`},
-		{genericPkg + `u1a; func _[_ interface{~int}]() {}`, `~int`, `~int`},
-		{genericPkg + `u2a; func _[_ interface{int|string}]() {}`, `int | string`, `int|string`},
-		{genericPkg + `u3a; func _[_ interface{int|string|~bool}]() {}`, `int | string | ~bool`, `int|string|~bool`},
-		{genericPkg + `u3a; func _[_ interface{int|string|~bool}]() {}`, `int | string`, `int|string`},
-		{genericPkg + `u3a; func _[_ interface{int|string|~bool}]() {}`, `~bool`, `~bool`},
-		{genericPkg + `u3a; func _[_ interface{int|string|~float64|~bool}]() {}`, `int | string | ~float64`, `int|string|~float64`},
+		{`package u0a; func _[_ interface{int}]() {}`, `int`, `int`},
+		{`package u1a; func _[_ interface{~int}]() {}`, `~int`, `~int`},
+		{`package u2a; func _[_ interface{int | string}]() {}`, `int | string`, `int | string`},
+		{`package u3a; func _[_ interface{int | string | ~bool}]() {}`, `int | string | ~bool`, `int | string | ~bool`},
+		{`package u3a; func _[_ interface{int | string | ~bool}]() {}`, `int | string`, `int | string`},
+		{`package u3a; func _[_ interface{int | string | ~bool}]() {}`, `~bool`, `~bool`},
+		{`package u3a; func _[_ interface{int | string | ~float64|~bool}]() {}`, `int | string | ~float64`, `int | string | ~float64`},
 
-		{genericPkg + `u0b; func _[_ int]() {}`, `int`, `int`},
-		{genericPkg + `u1b; func _[_ ~int]() {}`, `~int`, `~int`},
-		{genericPkg + `u2b; func _[_ int|string]() {}`, `int | string`, `int|string`},
-		{genericPkg + `u3b; func _[_ int|string|~bool]() {}`, `int | string | ~bool`, `int|string|~bool`},
-		{genericPkg + `u3b; func _[_ int|string|~bool]() {}`, `int | string`, `int|string`},
-		{genericPkg + `u3b; func _[_ int|string|~bool]() {}`, `~bool`, `~bool`},
-		{genericPkg + `u3b; func _[_ int|string|~float64|~bool]() {}`, `int | string | ~float64`, `int|string|~float64`},
+		{`package u0b; func _[_ int]() {}`, `int`, `int`},
+		{`package u1b; func _[_ ~int]() {}`, `~int`, `~int`},
+		{`package u2b; func _[_ int | string]() {}`, `int | string`, `int | string`},
+		{`package u3b; func _[_ int | string | ~bool]() {}`, `int | string | ~bool`, `int | string | ~bool`},
+		{`package u3b; func _[_ int | string | ~bool]() {}`, `int | string`, `int | string`},
+		{`package u3b; func _[_ int | string | ~bool]() {}`, `~bool`, `~bool`},
+		{`package u3b; func _[_ int | string | ~float64|~bool]() {}`, `int | string | ~float64`, `int | string | ~float64`},
 
-		{genericPkg + `u0c; type _ interface{int}`, `int`, `int`},
-		{genericPkg + `u1c; type _ interface{~int}`, `~int`, `~int`},
-		{genericPkg + `u2c; type _ interface{int|string}`, `int | string`, `int|string`},
-		{genericPkg + `u3c; type _ interface{int|string|~bool}`, `int | string | ~bool`, `int|string|~bool`},
-		{genericPkg + `u3c; type _ interface{int|string|~bool}`, `int | string`, `int|string`},
-		{genericPkg + `u3c; type _ interface{int|string|~bool}`, `~bool`, `~bool`},
-		{genericPkg + `u3c; type _ interface{int|string|~float64|~bool}`, `int | string | ~float64`, `int|string|~float64`},
+		{`package u0c; type _ interface{int}`, `int`, `int`},
+		{`package u1c; type _ interface{~int}`, `~int`, `~int`},
+		{`package u2c; type _ interface{int | string}`, `int | string`, `int | string`},
+		{`package u3c; type _ interface{int | string | ~bool}`, `int | string | ~bool`, `int | string | ~bool`},
+		{`package u3c; type _ interface{int | string | ~bool}`, `int | string`, `int | string`},
+		{`package u3c; type _ interface{int | string | ~bool}`, `~bool`, `~bool`},
+		{`package u3c; type _ interface{int | string | ~float64|~bool}`, `int | string | ~float64`, `int | string | ~float64`},
 	}
 
 	for _, test := range tests {
 		info := Info{Types: make(map[ast.Expr]TypeAndValue)}
 		var name string
 		if strings.HasPrefix(test.src, broken) {
-			var err error
-			name, err = mayTypecheck(t, "TypesInfo", test.src, &info)
+			pkg, err := typecheck("TypesInfo", test.src, &info)
 			if err == nil {
-				t.Errorf("package %s: expected to fail but passed", name)
+				t.Errorf("package %s: expected to fail but passed", pkg.Name())
 				continue
 			}
+			if pkg != nil {
+				name = pkg.Name()
+			}
 		} else {
-			name = mustTypecheck(t, "TypesInfo", test.src, &info)
+			name = mustTypecheck("TypesInfo", test.src, &info).Name()
 		}
 
 		// look for expression type
@@ -562,22 +535,22 @@
 				{`T`, []string{`string`}, `[]string`},
 			},
 		},
+		{`package issue51803; func foo[T any](T) {}; func _() { foo[int]( /* leave arg away on purpose */ ) }`,
+			[]testInst{{`foo`, []string{`int`}, `func(int)`}},
+		},
 	}
 
 	for _, test := range tests {
 		imports := make(testImporter)
-		conf := Config{Importer: imports}
+		conf := Config{
+			Importer: imports,
+			Error:    func(error) {}, // ignore errors
+		}
 		instMap := make(map[*ast.Ident]Instance)
 		useMap := make(map[*ast.Ident]Object)
 		makePkg := func(src string) *Package {
-			f, err := parser.ParseFile(fset, "p.go", src, 0)
-			if err != nil {
-				t.Fatal(err)
-			}
-			pkg, err := conf.Check("", fset, []*ast.File{f}, &Info{Instances: instMap, Uses: useMap})
-			if err != nil {
-				t.Fatal(err)
-			}
+			f := mustParse(fset, "p.go", src)
+			pkg, _ := conf.Check("", fset, []*ast.File{f}, &Info{Instances: instMap, Uses: useMap})
 			imports[pkg.Name()] = pkg
 			return pkg
 		}
@@ -663,16 +636,16 @@
 		{`package p5; func f() int { x, _ := 1, 2; return x }`, `_`, `var _ int`},
 
 		// Tests using generics.
-		{`package generic_g0; type x[T any] int`, `x`, `type generic_g0.x[T any] int`},
-		{`package generic_g1; func f[T any]() {}`, `f`, `func generic_g1.f[T any]()`},
-		{`package generic_g2; type x[T any] int; func (*x[_]) m() {}`, `m`, `func (*generic_g2.x[_]).m()`},
+		{`package g0; type x[T any] int`, `x`, `type g0.x[T any] int`},
+		{`package g1; func f[T any]() {}`, `f`, `func g1.f[T any]()`},
+		{`package g2; type x[T any] int; func (*x[_]) m() {}`, `m`, `func (*g2.x[_]).m()`},
 	}
 
 	for _, test := range tests {
 		info := Info{
 			Defs: make(map[*ast.Ident]Object),
 		}
-		name := mustTypecheck(t, "DefsInfo", test.src, &info)
+		name := mustTypecheck("DefsInfo", test.src, &info).Name()
 
 		// find object
 		var def Object
@@ -706,40 +679,40 @@
 		{`package p4; func _() { _ = f }; func f()`, `f`, `func p4.f()`},
 
 		// Tests using generics.
-		{`package generic_g0; func _[T any]() { _ = x }; const x = 42`, `x`, `const generic_g0.x untyped int`},
-		{`package generic_g1; func _[T any](x T) { }`, `T`, `type parameter T any`},
-		{`package generic_g2; type N[A any] int; var _ N[int]`, `N`, `type generic_g2.N[A any] int`},
-		{`package generic_g3; type N[A any] int; func (N[_]) m() {}`, `N`, `type generic_g3.N[A any] int`},
+		{`package g0; func _[T any]() { _ = x }; const x = 42`, `x`, `const g0.x untyped int`},
+		{`package g1; func _[T any](x T) { }`, `T`, `type parameter T any`},
+		{`package g2; type N[A any] int; var _ N[int]`, `N`, `type g2.N[A any] int`},
+		{`package g3; type N[A any] int; func (N[_]) m() {}`, `N`, `type g3.N[A any] int`},
 
 		// Uses of fields are instantiated.
-		{`package generic_s1; type N[A any] struct{ a A }; var f = N[int]{}.a`, `a`, `field a int`},
-		{`package generic_s1; type N[A any] struct{ a A }; func (r N[B]) m(b B) { r.a = b }`, `a`, `field a B`},
+		{`package s1; type N[A any] struct{ a A }; var f = N[int]{}.a`, `a`, `field a int`},
+		{`package s1; type N[A any] struct{ a A }; func (r N[B]) m(b B) { r.a = b }`, `a`, `field a B`},
 
 		// Uses of methods are uses of the instantiated method.
-		{`package generic_m0; type N[A any] int; func (r N[B]) m() { r.n() }; func (N[C]) n() {}`, `n`, `func (generic_m0.N[B]).n()`},
-		{`package generic_m1; type N[A any] int; func (r N[B]) m() { }; var f = N[int].m`, `m`, `func (generic_m1.N[int]).m()`},
-		{`package generic_m2; func _[A any](v interface{ m() A }) { v.m() }`, `m`, `func (interface).m() A`},
-		{`package generic_m3; func f[A any]() interface{ m() A } { return nil }; var _ = f[int]().m()`, `m`, `func (interface).m() int`},
-		{`package generic_m4; type T[A any] func() interface{ m() A }; var x T[int]; var y = x().m`, `m`, `func (interface).m() int`},
-		{`package generic_m5; type T[A any] interface{ m() A }; func _[B any](t T[B]) { t.m() }`, `m`, `func (generic_m5.T[B]).m() B`},
-		{`package generic_m6; type T[A any] interface{ m() }; func _[B any](t T[B]) { t.m() }`, `m`, `func (generic_m6.T[B]).m()`},
-		{`package generic_m7; type T[A any] interface{ m() A }; func _(t T[int]) { t.m() }`, `m`, `func (generic_m7.T[int]).m() int`},
-		{`package generic_m8; type T[A any] interface{ m() }; func _(t T[int]) { t.m() }`, `m`, `func (generic_m8.T[int]).m()`},
-		{`package generic_m9; type T[A any] interface{ m() }; func _(t T[int]) { _ = t.m }`, `m`, `func (generic_m9.T[int]).m()`},
+		{`package m0; type N[A any] int; func (r N[B]) m() { r.n() }; func (N[C]) n() {}`, `n`, `func (m0.N[B]).n()`},
+		{`package m1; type N[A any] int; func (r N[B]) m() { }; var f = N[int].m`, `m`, `func (m1.N[int]).m()`},
+		{`package m2; func _[A any](v interface{ m() A }) { v.m() }`, `m`, `func (interface).m() A`},
+		{`package m3; func f[A any]() interface{ m() A } { return nil }; var _ = f[int]().m()`, `m`, `func (interface).m() int`},
+		{`package m4; type T[A any] func() interface{ m() A }; var x T[int]; var y = x().m`, `m`, `func (interface).m() int`},
+		{`package m5; type T[A any] interface{ m() A }; func _[B any](t T[B]) { t.m() }`, `m`, `func (m5.T[B]).m() B`},
+		{`package m6; type T[A any] interface{ m() }; func _[B any](t T[B]) { t.m() }`, `m`, `func (m6.T[B]).m()`},
+		{`package m7; type T[A any] interface{ m() A }; func _(t T[int]) { t.m() }`, `m`, `func (m7.T[int]).m() int`},
+		{`package m8; type T[A any] interface{ m() }; func _(t T[int]) { t.m() }`, `m`, `func (m8.T[int]).m()`},
+		{`package m9; type T[A any] interface{ m() }; func _(t T[int]) { _ = t.m }`, `m`, `func (m9.T[int]).m()`},
 		{
-			`package generic_m10; type E[A any] interface{ m() }; type T[B any] interface{ E[B]; n() }; func _(t T[int]) { t.m() }`,
+			`package m10; type E[A any] interface{ m() }; type T[B any] interface{ E[B]; n() }; func _(t T[int]) { t.m() }`,
 			`m`,
-			`func (generic_m10.E[int]).m()`,
+			`func (m10.E[int]).m()`,
 		},
-		{`package generic_m11; type T[A any] interface{ m(); n() }; func _(t1 T[int], t2 T[string]) { t1.m(); t2.n() }`, `m`, `func (generic_m11.T[int]).m()`},
-		{`package generic_m12; type T[A any] interface{ m(); n() }; func _(t1 T[int], t2 T[string]) { t1.m(); t2.n() }`, `n`, `func (generic_m12.T[string]).n()`},
+		{`package m11; type T[A any] interface{ m(); n() }; func _(t1 T[int], t2 T[string]) { t1.m(); t2.n() }`, `m`, `func (m11.T[int]).m()`},
+		{`package m12; type T[A any] interface{ m(); n() }; func _(t1 T[int], t2 T[string]) { t1.m(); t2.n() }`, `n`, `func (m12.T[string]).n()`},
 	}
 
 	for _, test := range tests {
 		info := Info{
 			Uses: make(map[*ast.Ident]Object),
 		}
-		name := mustTypecheck(t, "UsesInfo", test.src, &info)
+		name := mustTypecheck("UsesInfo", test.src, &info).Name()
 
 		// find object
 		var use Object
@@ -772,10 +745,7 @@
 func (r *N[C]) n() {  }
 `
 	fset := token.NewFileSet()
-	f, err := parser.ParseFile(fset, "p.go", src, 0)
-	if err != nil {
-		t.Fatal(err)
-	}
+	f := mustParse(fset, "p.go", src)
 	info := Info{
 		Defs:       make(map[*ast.Ident]Object),
 		Uses:       make(map[*ast.Ident]Object),
@@ -868,22 +838,22 @@
 		{`package p10; type T struct{}; func (*T) f() {}`, "field: var  *p10.T"},
 
 		// Tests using generics.
-		{`package generic_f0; func f[T any](x int) {}`, ""}, // no Implicits entry
-		{`package generic_f1; func f[T any](int) {}`, "field: var  int"},
-		{`package generic_f2; func f[T any](T) {}`, "field: var  T"},
-		{`package generic_f3; func f[T any]() (complex64) { return 0 }`, "field: var  complex64"},
-		{`package generic_f4; func f[T any](t T) (T) { return t }`, "field: var  T"},
-		{`package generic_t0; type T[A any] struct{}; func (*T[_]) f() {}`, "field: var  *generic_t0.T[_]"},
-		{`package generic_t1; type T[A any] struct{}; func _(x interface{}) { switch t := x.(type) { case T[int]: _ = t } }`, "caseClause: var t generic_t1.T[int]"},
-		{`package generic_t2; type T[A any] struct{}; func _[P any](x interface{}) { switch t := x.(type) { case T[P]: _ = t } }`, "caseClause: var t generic_t2.T[P]"},
-		{`package generic_t3; func _[P any](x interface{}) { switch t := x.(type) { case P: _ = t } }`, "caseClause: var t P"},
+		{`package f0; func f[T any](x int) {}`, ""}, // no Implicits entry
+		{`package f1; func f[T any](int) {}`, "field: var  int"},
+		{`package f2; func f[T any](T) {}`, "field: var  T"},
+		{`package f3; func f[T any]() (complex64) { return 0 }`, "field: var  complex64"},
+		{`package f4; func f[T any](t T) (T) { return t }`, "field: var  T"},
+		{`package t0; type T[A any] struct{}; func (*T[_]) f() {}`, "field: var  *t0.T[_]"},
+		{`package t1; type T[A any] struct{}; func _(x interface{}) { switch t := x.(type) { case T[int]: _ = t } }`, "caseClause: var t t1.T[int]"},
+		{`package t2; type T[A any] struct{}; func _[P any](x interface{}) { switch t := x.(type) { case T[P]: _ = t } }`, "caseClause: var t t2.T[P]"},
+		{`package t3; func _[P any](x interface{}) { switch t := x.(type) { case P: _ = t } }`, "caseClause: var t P"},
 	}
 
 	for _, test := range tests {
 		info := Info{
 			Implicits: make(map[ast.Node]Object),
 		}
-		name := mustTypecheck(t, "ImplicitsInfo", test.src, &info)
+		name := mustTypecheck("ImplicitsInfo", test.src, &info).Name()
 
 		// the test cases expect at most one Implicits entry
 		if len(info.Implicits) > 1 {
@@ -915,7 +885,7 @@
 }
 
 func predString(tv TypeAndValue) string {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	pred := func(b bool, s string) {
 		if b {
 			if buf.Len() > 0 {
@@ -970,7 +940,7 @@
 
 		// values
 		{`package v0; var (a, b int; _ = a + b)`, `a + b`, `value`},
-		{`package v1; var _ = &[]int{1}`, `([]int literal)`, `value`},
+		{`package v1; var _ = &[]int{1}`, `[]int{…}`, `value`},
 		{`package v2; var _ = func(){}`, `(func() literal)`, `value`},
 		{`package v4; func f() { _ = f }`, `f`, `value`},
 		{`package v3; var _ *int = nil`, `nil`, `value, nil`},
@@ -1011,7 +981,7 @@
 
 	for _, test := range tests {
 		info := Info{Types: make(map[ast.Expr]TypeAndValue)}
-		name := mustTypecheck(t, "PredicatesInfo", test.src, &info)
+		name := mustTypecheck("PredicatesInfo", test.src, &info).Name()
 
 		// look for expression predicates
 		got := "<missing>"
@@ -1103,7 +1073,7 @@
 
 	for _, test := range tests {
 		info := Info{Scopes: make(map[ast.Node]*Scope)}
-		name := mustTypecheck(t, "ScopesInfo", test.src, &info)
+		name := mustTypecheck("ScopesInfo", test.src, &info).Name()
 
 		// number of scopes must match
 		if len(info.Scopes) != len(test.scopes) {
@@ -1291,7 +1261,7 @@
 
 	for _, test := range tests {
 		info := Info{}
-		name := mustTypecheck(t, "InitOrderInfo", test.src, &info)
+		name := mustTypecheck("InitOrderInfo", test.src, &info).Name()
 
 		// number of initializers must match
 		if len(info.InitOrder) != len(test.inits) {
@@ -1312,16 +1282,8 @@
 
 func TestMultiFileInitOrder(t *testing.T) {
 	fset := token.NewFileSet()
-	mustParse := func(src string) *ast.File {
-		f, err := parser.ParseFile(fset, "main", src, 0)
-		if err != nil {
-			t.Fatal(err)
-		}
-		return f
-	}
-
-	fileA := mustParse(`package main; var a = 1`)
-	fileB := mustParse(`package main; var b = 2`)
+	fileA := mustParse(fset, "", `package main; var a = 1`)
+	fileB := mustParse(fset, "", `package main; var b = 2`)
 
 	// The initialization order must not depend on the parse
 	// order of the files, only on the presentation order to
@@ -1359,10 +1321,7 @@
 
 	for i, src := range sources {
 		filename := fmt.Sprintf("sources%d", i)
-		f, err := parser.ParseFile(fset, filename, src, 0)
-		if err != nil {
-			t.Fatal(err)
-		}
+		f := mustParse(fset, filename, src)
 		if err := check.Files([]*ast.File{f}); err != nil {
 			t.Error(err)
 		}
@@ -1396,10 +1355,7 @@
 	imports := make(testImporter)
 	conf := Config{Importer: imports}
 	makePkg := func(path, src string) {
-		f, err := parser.ParseFile(fset, path+".go", src, 0)
-		if err != nil {
-			t.Fatal(err)
-		}
+		f := mustParse(fset, path+".go", src)
 		pkg, err := conf.Check(path, fset, []*ast.File{f}, &Info{Selections: selections})
 		if err != nil {
 			t.Fatal(err)
@@ -1577,10 +1533,7 @@
 		Importer: imports,
 	}
 	makePkg := func(path, src string) {
-		f, err := parser.ParseFile(fset, path, src, 0)
-		if err != nil {
-			t.Fatal(err)
-		}
+		f := mustParse(fset, path, src)
 		pkg, _ := conf.Check(path, fset, []*ast.File{f}, nil) // errors logged via conf.Error
 		imports[path] = pkg
 	}
@@ -1670,11 +1623,7 @@
 	}
 
 	for _, test := range tests {
-		pkg, err := pkgForMode("test", "package p;"+test.src, nil, 0)
-		if err != nil {
-			t.Errorf("%s: incorrect test case: %s", test.src, err)
-			continue
-		}
+		pkg := mustTypecheck("test", "package p;"+test.src, nil)
 
 		obj := pkg.Scope().Lookup("a")
 		if obj == nil {
@@ -1720,10 +1669,7 @@
 `
 
 	fset := token.NewFileSet()
-	f, err := parser.ParseFile(fset, "foo.go", src, 0)
-	if err != nil {
-		panic(err)
-	}
+	f := mustParse(fset, "foo.go", src)
 	pkg := NewPackage("pkg", f.Name.Name)
 	if err := NewChecker(nil, fset, pkg, nil).Files([]*ast.File{f}); err != nil {
 		panic(err)
@@ -1751,13 +1697,6 @@
 	fset := token.NewFileSet()
 	imports := make(testImporter)
 	conf := Config{Importer: imports}
-	mustParse := func(src string) *ast.File {
-		f, err := parser.ParseFile(fset, "dummy.go", src, parser.ParseComments)
-		if err != nil {
-			t.Fatal(err)
-		}
-		return f
-	}
 	var info Info
 	makePkg := func(path string, files ...*ast.File) {
 		var err error
@@ -1767,7 +1706,7 @@
 		}
 	}
 
-	makePkg("lib", mustParse("package lib; var X int"))
+	makePkg("lib", mustParse(fset, "", "package lib; var X int"))
 	// Each /*name=kind:line*/ comment makes the test look up the
 	// name at that point and checks that it resolves to a decl of
 	// the specified kind and line number.  "undef" means undefined.
@@ -1811,7 +1750,7 @@
 `
 
 	info.Uses = make(map[*ast.Ident]Object)
-	f := mustParse(mainSrc)
+	f := mustParse(fset, "", mainSrc)
 	makePkg("main", f)
 	mainScope := imports["main"].Scope()
 	rx := regexp.MustCompile(`^/\*(\w*)=([\w:]*)\*/$`)
@@ -1893,8 +1832,9 @@
 		{newDefined(new(Struct)), new(Struct), true},
 		{newDefined(Typ[Int]), new(Struct), false},
 		{Typ[UntypedInt], Typ[Int], true},
+		{NewSlice(Typ[Int]), NewArray(Typ[Int], 10), true},
+		{NewSlice(Typ[Int]), NewArray(Typ[Uint], 10), false},
 		{NewSlice(Typ[Int]), NewPointer(NewArray(Typ[Int], 10)), true},
-		{NewSlice(Typ[Int]), NewArray(Typ[Int], 10), false},
 		{NewSlice(Typ[Int]), NewPointer(NewArray(Typ[Uint], 10)), false},
 		// Untyped string values are not permitted by the spec, so the behavior below is undefined.
 		{Typ[UntypedString], Typ[String], true},
@@ -1962,11 +1902,7 @@
 	}
 
 	for _, test := range tests {
-		pkg, err := pkgForMode("test", "package p;"+test.src, nil, 0)
-		if err != nil {
-			t.Errorf("%s: incorrect test case: %s", test.src, err)
-			continue
-		}
+		pkg := mustTypecheck("test", "package p;"+test.src, nil)
 		X := pkg.Scope().Lookup("X")
 		Y := pkg.Scope().Lookup("Y")
 		if X == nil || Y == nil {
@@ -2040,10 +1976,7 @@
 func TestIssue15305(t *testing.T) {
 	const src = "package p; func f() int16; var _ = f(undef)"
 	fset := token.NewFileSet()
-	f, err := parser.ParseFile(fset, "issue15305.go", src, 0)
-	if err != nil {
-		t.Fatal(err)
-	}
+	f := mustParse(fset, "issue15305.go", src)
 	conf := Config{
 		Error: func(err error) {}, // allow errors
 	}
@@ -2079,20 +2012,14 @@
 		{`struct{x, y int; z complex128}{}`, `struct{x int; y int; z complex128}`},
 	} {
 		fset := token.NewFileSet()
-		f, err := parser.ParseFile(fset, test.lit, "package p; var _ = "+test.lit, 0)
-		if err != nil {
-			t.Fatalf("%s: %v", test.lit, err)
-		}
-
-		info := &Info{
-			Types: make(map[ast.Expr]TypeAndValue),
-		}
-		if _, err = new(Config).Check("p", fset, []*ast.File{f}, info); err != nil {
+		f := mustParse(fset, test.lit, "package p; var _ = "+test.lit)
+		types := make(map[ast.Expr]TypeAndValue)
+		if _, err := new(Config).Check("p", fset, []*ast.File{f}, &Info{Types: types}); err != nil {
 			t.Fatalf("%s: %v", test.lit, err)
 		}
 
 		cmptype := func(x ast.Expr, want string) {
-			tv, ok := info.Types[x]
+			tv, ok := types[x]
 			if !ok {
 				t.Errorf("%s: no Types entry found", test.lit)
 				return
@@ -2140,15 +2067,12 @@
 `
 
 	fset := token.NewFileSet()
-	f, err := parser.ParseFile(fset, "src", src, 0)
-	if err != nil {
-		t.Fatal(err)
-	}
+	f := mustParse(fset, "src", src)
 
 	info := &Info{
 		Defs: make(map[*ast.Ident]Object),
 	}
-	if _, err = new(Config).Check("p", fset, []*ast.File{f}, info); err != nil {
+	if _, err := new(Config).Check("p", fset, []*ast.File{f}, info); err != nil {
 		t.Fatal(err)
 	}
 
@@ -2202,10 +2126,7 @@
 func f(x T) T { return foo.F(x) }
 `
 	fset := token.NewFileSet()
-	f, err := parser.ParseFile(fset, "src", src, 0)
-	if err != nil {
-		t.Fatal(err)
-	}
+	f := mustParse(fset, "src", src)
 	files := []*ast.File{f}
 
 	// type-check using all possible importers
@@ -2260,10 +2181,7 @@
 func TestInstantiate(t *testing.T) {
 	// eventually we like more tests but this is a start
 	const src = "package p; type T[P any] *T[P]"
-	pkg, err := pkgForMode(".", src, nil, 0)
-	if err != nil {
-		t.Fatal(err)
-	}
+	pkg := mustTypecheck(".", src, nil)
 
 	// type T should have one type parameter
 	T := pkg.Scope().Lookup("T").Type().(*Named)
@@ -2298,14 +2216,11 @@
 
 	for _, test := range tests {
 		src := "package p; " + test.src
-		pkg, err := pkgForMode(".", src, nil, 0)
-		if err != nil {
-			t.Fatal(err)
-		}
+		pkg := mustTypecheck(".", src, nil)
 
 		T := pkg.Scope().Lookup("T").Type().(*Named)
 
-		_, err = Instantiate(nil, T, test.targs, true)
+		_, err := Instantiate(nil, T, test.targs, true)
 		if err == nil {
 			t.Fatalf("Instantiate(%v, %v) returned nil error, want non-nil", T, test.targs)
 		}
@@ -2340,10 +2255,7 @@
 	conf := Config{Importer: imports}
 	makePkg := func(src string) {
 		fset := token.NewFileSet()
-		f, err := parser.ParseFile(fset, "", src, 0)
-		if err != nil {
-			t.Fatal(err)
-		}
+		f := mustParse(fset, "", src)
 		name := f.Name.Name
 		pkg, err := conf.Check(name, fset, []*ast.File{f}, nil)
 		if err != nil {
@@ -2351,11 +2263,11 @@
 		}
 		imports[name] = pkg
 	}
-	makePkg(genericPkg + `lib; type T[P any] struct{}`)
-	makePkg(genericPkg + `a; import "generic_lib"; var A generic_lib.T[int]`)
-	makePkg(genericPkg + `b; import "generic_lib"; var B generic_lib.T[int]`)
-	a := imports["generic_a"].Scope().Lookup("A")
-	b := imports["generic_b"].Scope().Lookup("B")
+	makePkg(`package lib; type T[P any] struct{}`)
+	makePkg(`package a; import "lib"; var A lib.T[int]`)
+	makePkg(`package b; import "lib"; var B lib.T[int]`)
+	a := imports["a"].Scope().Lookup("A")
+	b := imports["b"].Scope().Lookup("B")
 	if !Identical(a.Type(), b.Type()) {
 		t.Errorf("mismatching types: a.A: %s, b.B: %s", a.Type(), b.Type())
 	}
@@ -2400,10 +2312,7 @@
 		Defs: make(map[*ast.Ident]Object),
 	}
 	fset := token.NewFileSet()
-	f, err := parser.ParseFile(fset, "p.go", src, 0)
-	if err != nil {
-		t.Fatal(err)
-	}
+	f := mustParse(fset, "p.go", src)
 	conf := Config{}
 	pkg, err := conf.Check(f.Name.Name, fset, []*ast.File{f}, info)
 	if err != nil {
@@ -2535,10 +2444,7 @@
 `
 
 	fset := token.NewFileSet()
-	f, err := parser.ParseFile(fset, "p.go", src, 0)
-	if err != nil {
-		t.Fatal(err)
-	}
+	f := mustParse(fset, "p.go", src)
 	conf := Config{Error: func(error) {}}
 	pkg, _ := conf.Check(f.Name.Name, fset, []*ast.File{f}, nil)
 
@@ -2633,10 +2539,7 @@
 func (V4) M()
 `
 
-	pkg, err := pkgFor("p.go", src, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
+	pkg := mustTypecheck("p.go", src, nil)
 
 	T := pkg.Scope().Lookup("T").Type().Underlying().(*Interface)
 	lookup := func(name string) (*Func, bool) {
diff --git a/src/go/types/assignments.go b/src/go/types/assignments.go
index 98d7563..4d5acb1 100644
--- a/src/go/types/assignments.go
+++ b/src/go/types/assignments.go
@@ -10,6 +10,7 @@
 	"fmt"
 	"go/ast"
 	"go/token"
+	. "internal/types/errors"
 	"strings"
 )
 
@@ -28,7 +29,8 @@
 		// ok
 	default:
 		// we may get here because of other problems (issue #39634, crash 12)
-		check.errorf(x, 0, "cannot assign %s to %s in %s", x, T, context)
+		// TODO(gri) do we need a new "generic" error code here?
+		check.errorf(x, IncompatibleAssign, "cannot assign %s to %s in %s", x, T, context)
 		return
 	}
 
@@ -41,7 +43,7 @@
 		// complex, or string constant."
 		if T == nil || isNonTypeParamInterface(T) {
 			if T == nil && x.typ == Typ[UntypedNil] {
-				check.errorf(x, _UntypedNil, "use of untyped nil in %s", context)
+				check.errorf(x, UntypedNilUse, "use of untyped nil in %s", context)
 				x.mode = invalid
 				return
 			}
@@ -51,12 +53,12 @@
 		if code != 0 {
 			msg := check.sprintf("cannot use %s as %s value in %s", x, target, context)
 			switch code {
-			case _TruncatedFloat:
+			case TruncatedFloat:
 				msg += " (truncated)"
-			case _NumericOverflow:
+			case NumericOverflow:
 				msg += " (overflows)"
 			default:
-				code = _IncompatibleAssign
+				code = IncompatibleAssign
 			}
 			check.error(x, code, msg)
 			x.mode = invalid
@@ -74,7 +76,7 @@
 
 	// A generic (non-instantiated) function value cannot be assigned to a variable.
 	if sig, _ := under(x.typ).(*Signature); sig != nil && sig.TypeParams().Len() > 0 {
-		check.errorf(x, _WrongTypeArgCount, "cannot use generic function %s without instantiation in %s", x, context)
+		check.errorf(x, WrongTypeArgCount, "cannot use generic function %s without instantiation in %s", x, context)
 	}
 
 	// spec: "If a left-hand side is the blank identifier, any typed or
@@ -84,20 +86,12 @@
 		return
 	}
 
-	reason := ""
-	if ok, code := x.assignableTo(check, T, &reason); !ok {
-		if compilerErrorMessages {
-			if reason != "" {
-				check.errorf(x, code, "cannot use %s as type %s in %s:\n\t%s", x, T, context, reason)
-			} else {
-				check.errorf(x, code, "cannot use %s as type %s in %s", x, T, context)
-			}
+	cause := ""
+	if ok, code := x.assignableTo(check, T, &cause); !ok {
+		if cause != "" {
+			check.errorf(x, code, "cannot use %s as %s value in %s: %s", x, T, context, cause)
 		} else {
-			if reason != "" {
-				check.errorf(x, code, "cannot use %s as %s value in %s: %s", x, T, context, reason)
-			} else {
-				check.errorf(x, code, "cannot use %s as %s value in %s", x, T, context)
-			}
+			check.errorf(x, code, "cannot use %s as %s value in %s", x, T, context)
 		}
 		x.mode = invalid
 	}
@@ -113,7 +107,7 @@
 
 	// rhs must be a constant
 	if x.mode != constant_ {
-		check.errorf(x, _InvalidConstInit, "%s is not constant", x)
+		check.errorf(x, InvalidConstInit, "%s is not constant", x)
 		if lhs.typ == nil {
 			lhs.typ = Typ[Invalid]
 		}
@@ -148,7 +142,7 @@
 		if isUntyped(typ) {
 			// convert untyped types to default types
 			if typ == Typ[UntypedNil] {
-				check.errorf(x, _UntypedNil, "use of untyped nil in %s", context)
+				check.errorf(x, UntypedNilUse, "use of untyped nil in %s", context)
 				lhs.typ = Typ[Invalid]
 				return nil
 			}
@@ -223,11 +217,11 @@
 			var op operand
 			check.expr(&op, sel.X)
 			if op.mode == mapindex {
-				check.errorf(&z, _UnaddressableFieldAssign, "cannot assign to struct field %s in map", ExprString(z.expr))
+				check.errorf(&z, UnaddressableFieldAssign, "cannot assign to struct field %s in map", ExprString(z.expr))
 				return nil
 			}
 		}
-		check.errorf(&z, _UnassignableOperand, "cannot assign to %s", &z)
+		check.errorf(&z, UnassignableOperand, "cannot assign to %s", &z)
 		return nil
 	}
 
@@ -305,11 +299,11 @@
 
 	if len(rhs) == 1 {
 		if call, _ := unparen(rhs0).(*ast.CallExpr); call != nil {
-			check.errorf(rhs0, _WrongAssignCount, "assignment mismatch: %s but %s returns %s", vars, call.Fun, vals)
+			check.errorf(rhs0, WrongAssignCount, "assignment mismatch: %s but %s returns %s", vars, call.Fun, vals)
 			return
 		}
 	}
-	check.errorf(rhs0, _WrongAssignCount, "assignment mismatch: %s but %s", vars, vals)
+	check.errorf(rhs0, WrongAssignCount, "assignment mismatch: %s but %s", vars, vals)
 }
 
 // If returnStmt != nil, initVars is called to type-check the assignment
@@ -320,7 +314,7 @@
 	if len(lhs) != len(rhs) {
 		// invalidate lhs
 		for _, obj := range lhs {
-			obj.used = true // avoid declared but not used errors
+			obj.used = true // avoid declared and not used errors
 			if obj.typ == nil {
 				obj.typ = Typ[Invalid]
 			}
@@ -340,17 +334,13 @@
 			} else if len(rhs) > 0 {
 				at = rhs[len(rhs)-1].expr // report at last value
 			}
-			err := newErrorf(at, _WrongResultCount, "%s return values", qualifier)
+			err := newErrorf(at, WrongResultCount, "%s return values", qualifier)
 			err.errorf(token.NoPos, "have %s", check.typesSummary(operandTypes(rhs), false))
 			err.errorf(token.NoPos, "want %s", check.typesSummary(varTypes(lhs), false))
 			check.report(err)
 			return
 		}
-		if compilerErrorMessages {
-			check.assignError(origRHS, len(lhs), len(rhs))
-		} else {
-			check.errorf(rhs[0], _WrongAssignCount, "cannot initialize %d variables with %d values", len(lhs), len(rhs))
-		}
+		check.assignError(origRHS, len(lhs), len(rhs))
 		return
 	}
 
@@ -384,11 +374,7 @@
 				return
 			}
 		}
-		if compilerErrorMessages {
-			check.assignError(origRHS, len(lhs), len(rhs))
-		} else {
-			check.errorf(rhs[0], _WrongAssignCount, "cannot assign %d values to %d variables", len(rhs), len(lhs))
-		}
+		check.assignError(origRHS, len(lhs), len(rhs))
 		return
 	}
 
@@ -420,7 +406,7 @@
 		if ident == nil {
 			check.useLHS(lhs)
 			// TODO(rFindley) this is redundant with a parser error. Consider omitting?
-			check.errorf(lhs, _BadDecl, "non-name %s on left side of :=", lhs)
+			check.errorf(lhs, BadDecl, "non-name %s on left side of :=", lhs)
 			hasErr = true
 			continue
 		}
@@ -428,7 +414,7 @@
 		name := ident.Name
 		if name != "_" {
 			if seen[name] {
-				check.errorf(lhs, _RepeatedDecl, "%s repeated on left side of :=", lhs)
+				check.errorf(lhs, RepeatedDecl, "%s repeated on left side of :=", lhs)
 				hasErr = true
 				continue
 			}
@@ -445,7 +431,7 @@
 			if obj, _ := alt.(*Var); obj != nil {
 				lhsVars[i] = obj
 			} else {
-				check.errorf(lhs, _UnassignableOperand, "cannot assign to %s", lhs)
+				check.errorf(lhs, UnassignableOperand, "cannot assign to %s", lhs)
 				hasErr = true
 			}
 			continue
@@ -473,7 +459,7 @@
 	check.processDelayed(top)
 
 	if len(newVars) == 0 && !hasErr {
-		check.softErrorf(pos, _NoNewVar, "no new variables on left side of :=")
+		check.softErrorf(pos, NoNewVar, "no new variables on left side of :=")
 		return
 	}
 
diff --git a/src/go/types/builtins.go b/src/go/types/builtins.go
index 463d814..d3bca60 100644
--- a/src/go/types/builtins.go
+++ b/src/go/types/builtins.go
@@ -10,6 +10,7 @@
 	"go/ast"
 	"go/constant"
 	"go/token"
+	. "internal/types/errors"
 )
 
 // builtin type-checks a call to the built-in specified by id and
@@ -20,9 +21,9 @@
 	// append is the only built-in that permits the use of ... for the last argument
 	bin := predeclaredFuncs[id]
 	if call.Ellipsis.IsValid() && id != _Append {
-		check.invalidOp(atPos(call.Ellipsis),
-			_InvalidDotDotDot,
-			"invalid use of ... with built-in %s", bin.name)
+		check.errorf(atPos(call.Ellipsis),
+			InvalidDotDotDot,
+			invalidOp+"invalid use of ... with built-in %s", bin.name)
 		check.use(call.Args...)
 		return
 	}
@@ -68,7 +69,7 @@
 			msg = "too many"
 		}
 		if msg != "" {
-			check.invalidOp(inNode(call, call.Rparen), _WrongArgCount, "%s arguments for %s (expected %d, found %d)", msg, call, bin.nargs, nargs)
+			check.errorf(inNode(call, call.Rparen), WrongArgCount, invalidOp+"%s arguments for %s (expected %d, found %d)", msg, call, bin.nargs, nargs)
 			return
 		}
 	}
@@ -99,7 +100,7 @@
 				cause = check.sprintf("have %s", x)
 			}
 			// don't use Checker.invalidArg here as it would repeat "argument" in the error message
-			check.errorf(x, _InvalidAppend, "first argument to append must be a slice; %s", cause)
+			check.errorf(x, InvalidAppend, "first argument to append must be a slice; %s", cause)
 			return
 		}
 
@@ -215,11 +216,11 @@
 		}
 
 		if mode == invalid && under(x.typ) != Typ[Invalid] {
-			code := _InvalidCap
+			code := InvalidCap
 			if id == _Len {
-				code = _InvalidLen
+				code = InvalidLen
 			}
-			check.invalidArg(x, code, "%s for %s", x, bin.name)
+			check.errorf(x, code, invalidArg+"%s for %s", x, bin.name)
 			return
 		}
 
@@ -232,16 +233,43 @@
 		x.typ = Typ[Int]
 		x.val = val
 
+	case _Clear:
+		// clear(m)
+		if !check.allowVersion(check.pkg, 1, 21) {
+			check.error(call.Fun, UnsupportedFeature, "clear requires go1.21 or later")
+			return
+		}
+
+		if !underIs(x.typ, func(u Type) bool {
+			switch u := u.(type) {
+			case *Map, *Slice:
+				return true
+			case *Pointer:
+				if _, ok := under(u.base).(*Array); ok {
+					return true
+				}
+			}
+			check.errorf(x, InvalidClear, invalidArg+"cannot clear %s: argument must be (or constrained by) map, slice, or array pointer", x)
+			return false
+		}) {
+			return
+		}
+
+		x.mode = novalue
+		if check.Types != nil {
+			check.recordBuiltinType(call.Fun, makeSig(nil, x.typ))
+		}
+
 	case _Close:
 		// close(c)
 		if !underIs(x.typ, func(u Type) bool {
 			uch, _ := u.(*Chan)
 			if uch == nil {
-				check.invalidOp(x, _InvalidClose, "cannot close non-channel %s", x)
+				check.errorf(x, InvalidClose, invalidOp+"cannot close non-channel %s", x)
 				return false
 			}
 			if uch.dir == RecvOnly {
-				check.invalidOp(x, _InvalidClose, "cannot close receive-only channel %s", x)
+				check.errorf(x, InvalidClose, invalidOp+"cannot close receive-only channel %s", x)
 				return false
 			}
 			return true
@@ -308,7 +336,7 @@
 
 		// both argument types must be identical
 		if !Identical(x.typ, y.typ) {
-			check.invalidArg(x, _InvalidComplex, "mismatched types %s and %s", x.typ, y.typ)
+			check.errorf(x, InvalidComplex, invalidArg+"mismatched types %s and %s", x.typ, y.typ)
 			return
 		}
 
@@ -330,7 +358,7 @@
 		}
 		resTyp := check.applyTypeFunc(f, x, id)
 		if resTyp == nil {
-			check.invalidArg(x, _InvalidComplex, "arguments have type %s, expected floating-point", x.typ)
+			check.errorf(x, InvalidComplex, invalidArg+"arguments have type %s, expected floating-point", x.typ)
 			return
 		}
 
@@ -363,12 +391,12 @@
 		src, _ := src0.(*Slice)
 
 		if dst == nil || src == nil {
-			check.invalidArg(x, _InvalidCopy, "copy expects slice arguments; found %s and %s", x, &y)
+			check.errorf(x, InvalidCopy, invalidArg+"copy expects slice arguments; found %s and %s", x, &y)
 			return
 		}
 
 		if !Identical(dst.elem, src.elem) {
-			check.errorf(x, _InvalidCopy, "arguments to copy %s and %s have different element types %s and %s", x, &y, dst.elem, src.elem)
+			check.errorf(x, InvalidCopy, "arguments to copy %s and %s have different element types %s and %s", x, &y, dst.elem, src.elem)
 			return
 		}
 
@@ -387,11 +415,11 @@
 		if !underIs(map_, func(u Type) bool {
 			map_, _ := u.(*Map)
 			if map_ == nil {
-				check.invalidArg(x, _InvalidDelete, "%s is not a map", x)
+				check.errorf(x, InvalidDelete, invalidArg+"%s is not a map", x)
 				return false
 			}
 			if key != nil && !Identical(map_.key, key) {
-				check.invalidArg(x, _InvalidDelete, "maps of %s must have identical key types", x)
+				check.errorf(x, InvalidDelete, invalidArg+"maps of %s must have identical key types", x)
 				return false
 			}
 			key = map_.key
@@ -458,11 +486,11 @@
 		}
 		resTyp := check.applyTypeFunc(f, x, id)
 		if resTyp == nil {
-			code := _InvalidImag
+			code := InvalidImag
 			if id == _Real {
-				code = _InvalidReal
+				code = InvalidReal
 			}
-			check.invalidArg(x, code, "argument has type %s, expected complex type", x.typ)
+			check.errorf(x, code, invalidArg+"argument has type %s, expected complex type", x.typ)
 			return
 		}
 
@@ -500,14 +528,14 @@
 		case *Map, *Chan:
 			min = 1
 		case nil:
-			check.errorf(arg0, _InvalidMake, "cannot make %s: no core type", arg0)
+			check.errorf(arg0, InvalidMake, "cannot make %s: no core type", arg0)
 			return
 		default:
-			check.invalidArg(arg0, _InvalidMake, "cannot make %s; type must be slice, map, or channel", arg0)
+			check.errorf(arg0, InvalidMake, invalidArg+"cannot make %s; type must be slice, map, or channel", arg0)
 			return
 		}
 		if nargs < min || min+1 < nargs {
-			check.invalidOp(call, _WrongArgCount, "%v expects %d or %d arguments; found %d", call, min, min+1, nargs)
+			check.errorf(call, WrongArgCount, invalidOp+"%v expects %d or %d arguments; found %d", call, min, min+1, nargs)
 			return
 		}
 
@@ -521,7 +549,7 @@
 			}
 		}
 		if len(sizes) == 2 && sizes[0] > sizes[1] {
-			check.invalidArg(call.Args[1], _SwappedMakeArgs, "length and capacity swapped")
+			check.error(call.Args[1], SwappedMakeArgs, invalidArg+"length and capacity swapped")
 			// safe to continue
 		}
 		x.mode = value
@@ -604,7 +632,7 @@
 	case _Add:
 		// unsafe.Add(ptr unsafe.Pointer, len IntegerType) unsafe.Pointer
 		if !check.allowVersion(check.pkg, 1, 17) {
-			check.errorf(call.Fun, _InvalidUnsafeAdd, "unsafe.Add requires go1.17 or later")
+			check.error(call.Fun, UnsupportedFeature, "unsafe.Add requires go1.17 or later")
 			return
 		}
 
@@ -615,7 +643,7 @@
 
 		var y operand
 		arg(&y, 1)
-		if !check.isValidIndex(&y, _InvalidUnsafeAdd, "length", true) {
+		if !check.isValidIndex(&y, InvalidUnsafeAdd, "length", true) {
 			return
 		}
 
@@ -650,7 +678,7 @@
 		arg0 := call.Args[0]
 		selx, _ := unparen(arg0).(*ast.SelectorExpr)
 		if selx == nil {
-			check.invalidArg(arg0, _BadOffsetofSyntax, "%s is not a selector expression", arg0)
+			check.errorf(arg0, BadOffsetofSyntax, invalidArg+"%s is not a selector expression", arg0)
 			check.use(arg0)
 			return
 		}
@@ -665,18 +693,18 @@
 		obj, index, indirect := LookupFieldOrMethod(base, false, check.pkg, sel)
 		switch obj.(type) {
 		case nil:
-			check.invalidArg(x, _MissingFieldOrMethod, "%s has no single field %s", base, sel)
+			check.errorf(x, MissingFieldOrMethod, invalidArg+"%s has no single field %s", base, sel)
 			return
 		case *Func:
 			// TODO(gri) Using derefStructPtr may result in methods being found
 			// that don't actually exist. An error either way, but the error
 			// message is confusing. See: https://play.golang.org/p/al75v23kUy ,
 			// but go/types reports: "invalid argument: x.m is a method value".
-			check.invalidArg(arg0, _InvalidOffsetof, "%s is a method value", arg0)
+			check.errorf(arg0, InvalidOffsetof, invalidArg+"%s is a method value", arg0)
 			return
 		}
 		if indirect {
-			check.invalidArg(x, _InvalidOffsetof, "field %s is embedded via a pointer in %s", sel, base)
+			check.errorf(x, InvalidOffsetof, invalidArg+"field %s is embedded via a pointer in %s", sel, base)
 			return
 		}
 
@@ -730,26 +758,87 @@
 	case _Slice:
 		// unsafe.Slice(ptr *T, len IntegerType) []T
 		if !check.allowVersion(check.pkg, 1, 17) {
-			check.errorf(call.Fun, _InvalidUnsafeSlice, "unsafe.Slice requires go1.17 or later")
+			check.error(call.Fun, UnsupportedFeature, "unsafe.Slice requires go1.17 or later")
 			return
 		}
 
-		typ, _ := under(x.typ).(*Pointer)
-		if typ == nil {
-			check.invalidArg(x, _InvalidUnsafeSlice, "%s is not a pointer", x)
+		ptr, _ := under(x.typ).(*Pointer) // TODO(gri) should this be coreType rather than under?
+		if ptr == nil {
+			check.errorf(x, InvalidUnsafeSlice, invalidArg+"%s is not a pointer", x)
 			return
 		}
 
 		var y operand
 		arg(&y, 1)
-		if !check.isValidIndex(&y, _InvalidUnsafeSlice, "length", false) {
+		if !check.isValidIndex(&y, InvalidUnsafeSlice, "length", false) {
 			return
 		}
 
 		x.mode = value
-		x.typ = NewSlice(typ.base)
+		x.typ = NewSlice(ptr.base)
 		if check.Types != nil {
-			check.recordBuiltinType(call.Fun, makeSig(x.typ, typ, y.typ))
+			check.recordBuiltinType(call.Fun, makeSig(x.typ, ptr, y.typ))
+		}
+
+	case _SliceData:
+		// unsafe.SliceData(slice []T) *T
+		if !check.allowVersion(check.pkg, 1, 20) {
+			check.error(call.Fun, UnsupportedFeature, "unsafe.SliceData requires go1.20 or later")
+			return
+		}
+
+		slice, _ := under(x.typ).(*Slice) // TODO(gri) should this be coreType rather than under?
+		if slice == nil {
+			check.errorf(x, InvalidUnsafeSliceData, invalidArg+"%s is not a slice", x)
+			return
+		}
+
+		x.mode = value
+		x.typ = NewPointer(slice.elem)
+		if check.Types != nil {
+			check.recordBuiltinType(call.Fun, makeSig(x.typ, slice))
+		}
+
+	case _String:
+		// unsafe.String(ptr *byte, len IntegerType) string
+		if !check.allowVersion(check.pkg, 1, 20) {
+			check.error(call.Fun, UnsupportedFeature, "unsafe.String requires go1.20 or later")
+			return
+		}
+
+		check.assignment(x, NewPointer(universeByte), "argument to unsafe.String")
+		if x.mode == invalid {
+			return
+		}
+
+		var y operand
+		arg(&y, 1)
+		if !check.isValidIndex(&y, InvalidUnsafeString, "length", false) {
+			return
+		}
+
+		x.mode = value
+		x.typ = Typ[String]
+		if check.Types != nil {
+			check.recordBuiltinType(call.Fun, makeSig(x.typ, NewPointer(universeByte), y.typ))
+		}
+
+	case _StringData:
+		// unsafe.StringData(str string) *byte
+		if !check.allowVersion(check.pkg, 1, 20) {
+			check.error(call.Fun, UnsupportedFeature, "unsafe.StringData requires go1.20 or later")
+			return
+		}
+
+		check.assignment(x, Typ[String], "argument to unsafe.StringData")
+		if x.mode == invalid {
+			return
+		}
+
+		x.mode = value
+		x.typ = NewPointer(universeByte)
+		if check.Types != nil {
+			check.recordBuiltinType(call.Fun, makeSig(x.typ, Typ[String]))
 		}
 
 	case _Assert:
@@ -757,15 +846,15 @@
 		// The result of assert is the value of pred if there is no error.
 		// Note: assert is only available in self-test mode.
 		if x.mode != constant_ || !isBoolean(x.typ) {
-			check.invalidArg(x, _Test, "%s is not a boolean constant", x)
+			check.errorf(x, Test, invalidArg+"%s is not a boolean constant", x)
 			return
 		}
 		if x.val.Kind() != constant.Bool {
-			check.errorf(x, _Test, "internal error: value of %s should be a boolean constant", x)
+			check.errorf(x, Test, "internal error: value of %s should be a boolean constant", x)
 			return
 		}
 		if !constant.BoolVal(x.val) {
-			check.errorf(call, _Test, "%v failed", call)
+			check.errorf(call, Test, "%v failed", call)
 			// compile-time assertion failure - safe to continue
 		}
 		// result is constant - no need to record signature
@@ -863,14 +952,14 @@
 		// type parameter for the result. It's not clear what the API
 		// implications are here. Report an error for 1.18 (see #50912),
 		// but continue type-checking.
-		var code errorCode
+		var code Code
 		switch id {
 		case _Real:
-			code = _InvalidReal
+			code = InvalidReal
 		case _Imag:
-			code = _InvalidImag
+			code = InvalidImag
 		case _Complex:
-			code = _InvalidComplex
+			code = InvalidComplex
 		default:
 			unreachable()
 		}
diff --git a/src/go/types/builtins_test.go b/src/go/types/builtins_test.go
index 7e967a3..fb71c48 100644
--- a/src/go/types/builtins_test.go
+++ b/src/go/types/builtins_test.go
@@ -42,6 +42,11 @@
 	{"len", `type S []byte; var s S; _ = len(s)`, `func(p.S) int`},
 	{"len", `var s P; _ = len(s)`, `func(P) int`},
 
+	{"clear", `var m map[float64]int; clear(m)`, `func(map[float64]int)`},
+	{"clear", `var s []byte; clear(s)`, `func([]byte)`},
+	{"clear", `var p *[10]int; clear(p)`, `func(*[10]int)`},
+	{"clear", `var s P; clear(s)`, `func(P)`},
+
 	{"close", `var c chan int; close(c)`, `func(chan int)`},
 	{"close", `var c chan<- chan string; close(c)`, `func(chan<- chan string)`},
 
@@ -129,6 +134,16 @@
 
 	{"Slice", `var p *int; _ = unsafe.Slice(p, 1)`, `func(*int, int) []int`},
 	{"Slice", `var p *byte; var n uintptr; _ = unsafe.Slice(p, n)`, `func(*byte, uintptr) []byte`},
+	{"Slice", `type B *byte; var b B; _ = unsafe.Slice(b, 0)`, `func(*byte, int) []byte`},
+
+	{"SliceData", "var s []int; _ = unsafe.SliceData(s)", `func([]int) *int`},
+	{"SliceData", "type S []int; var s S; _ = unsafe.SliceData(s)", `func([]int) *int`},
+
+	{"String", `var p *byte; _ = unsafe.String(p, 1)`, `func(*byte, int) string`},
+	{"String", `type B *byte; var b B; _ = unsafe.String(b, 0)`, `func(*byte, int) string`},
+
+	{"StringData", `var s string; _ = unsafe.StringData(s)`, `func(string) *byte`},
+	{"StringData", `_ = unsafe.StringData("foo")`, `func(string) *byte`},
 
 	{"assert", `assert(true)`, `invalid type`},                                    // constant
 	{"assert", `type B bool; const pred B = 1 < 2; assert(pred)`, `invalid type`}, // constant
diff --git a/src/go/types/call.go b/src/go/types/call.go
index c580885..db603b5 100644
--- a/src/go/types/call.go
+++ b/src/go/types/call.go
@@ -10,6 +10,7 @@
 	"go/ast"
 	"go/internal/typeparams"
 	"go/token"
+	. "internal/types/errors"
 	"strings"
 	"unicode"
 )
@@ -18,7 +19,7 @@
 // The operand x must be the evaluation of inst.X and its type must be a signature.
 func (check *Checker) funcInst(x *operand, ix *typeparams.IndexExpr) {
 	if !check.allowVersion(check.pkg, 1, 18) {
-		check.softErrorf(inNode(ix.Orig, ix.Lbrack), _UnsupportedFeature, "function instantiation requires go1.18 or later")
+		check.softErrorf(inNode(ix.Orig, ix.Lbrack), UnsupportedFeature, "function instantiation requires go1.18 or later")
 	}
 
 	targs := check.typeList(ix.Indices)
@@ -33,7 +34,7 @@
 	sig := x.typ.(*Signature)
 	got, want := len(targs), sig.TypeParams().Len()
 	if got > want {
-		check.errorf(ix.Indices[got-1], _WrongTypeArgCount, "got %d type arguments but want %d", got, want)
+		check.errorf(ix.Indices[got-1], WrongTypeArgCount, "got %d type arguments but want %d", got, want)
 		x.mode = invalid
 		x.expr = ix.Orig
 		return
@@ -52,10 +53,10 @@
 	assert(got == want)
 
 	// instantiate function signature
-	res := check.instantiateSignature(x.Pos(), sig, targs, ix.Indices)
-	assert(res.TypeParams().Len() == 0) // signature is not generic anymore
-	check.recordInstance(ix.Orig, targs, res)
-	x.typ = res
+	sig = check.instantiateSignature(x.Pos(), sig, targs, ix.Indices)
+	assert(sig.TypeParams().Len() == 0) // signature is not generic anymore
+	check.recordInstance(ix.Orig, targs, sig)
+	x.typ = sig
 	x.mode = value
 	x.expr = ix.Orig
 }
@@ -85,7 +86,7 @@
 			if i < len(xlist) {
 				pos = xlist[i].Pos()
 			}
-			check.softErrorf(atPos(pos), _InvalidTypeArg, "%s", err)
+			check.softErrorf(atPos(pos), InvalidTypeArg, "%s", err)
 		} else {
 			check.mono.recordInstance(check.pkg, pos, tparams, targs, xlist)
 		}
@@ -107,7 +108,6 @@
 		}
 		x.expr = call.Fun
 		check.record(x)
-
 	} else {
 		check.exprOrType(x, call.Fun, true)
 	}
@@ -129,17 +129,17 @@
 		x.mode = invalid
 		switch n := len(call.Args); n {
 		case 0:
-			check.errorf(inNode(call, call.Rparen), _WrongArgCount, "missing argument in conversion to %s", T)
+			check.errorf(inNode(call, call.Rparen), WrongArgCount, "missing argument in conversion to %s", T)
 		case 1:
 			check.expr(x, call.Args[0])
 			if x.mode != invalid {
 				if call.Ellipsis.IsValid() {
-					check.errorf(call.Args[0], _BadDotDotDotSyntax, "invalid use of ... in conversion to %s", T)
+					check.errorf(call.Args[0], BadDotDotDotSyntax, "invalid use of ... in conversion to %s", T)
 					break
 				}
 				if t, _ := under(T).(*Interface); t != nil && !isTypeParam(T) {
 					if !t.IsMethodSet() {
-						check.errorf(call, _MisplacedConstraintIface, "cannot use interface %s in conversion (contains specific type constraints or is comparable)", T)
+						check.errorf(call, MisplacedConstraintIface, "cannot use interface %s in conversion (contains specific type constraints or is comparable)", T)
 						break
 					}
 				}
@@ -147,7 +147,7 @@
 			}
 		default:
 			check.use(call.Args...)
-			check.errorf(call.Args[n-1], _WrongArgCount, "too many arguments in conversion to %s", T)
+			check.errorf(call.Args[n-1], WrongArgCount, "too many arguments in conversion to %s", T)
 		}
 		x.expr = call
 		return conversion
@@ -173,12 +173,15 @@
 	// a type parameter may be "called" if all types have the same signature
 	sig, _ := coreType(x.typ).(*Signature)
 	if sig == nil {
-		check.invalidOp(x, _InvalidCall, "cannot call non-function %s", x)
+		check.errorf(x, InvalidCall, invalidOp+"cannot call non-function %s", x)
 		x.mode = invalid
 		x.expr = call
 		return statement
 	}
 
+	// Capture wasGeneric before sig is potentially instantiated below.
+	wasGeneric := sig.TypeParams().Len() > 0
+
 	// evaluate type arguments, if any
 	var xlist []ast.Expr
 	var targs []Type
@@ -196,20 +199,39 @@
 		// check number of type arguments (got) vs number of type parameters (want)
 		got, want := len(targs), sig.TypeParams().Len()
 		if got > want {
-			check.errorf(xlist[want], _WrongTypeArgCount, "got %d type arguments but want %d", got, want)
+			check.errorf(xlist[want], WrongTypeArgCount, "got %d type arguments but want %d", got, want)
 			check.use(call.Args...)
 			x.mode = invalid
 			x.expr = call
 			return statement
 		}
+
+		// If sig is generic and all type arguments are provided, preempt function
+		// argument type inference by explicitly instantiating the signature. This
+		// ensures that we record accurate type information for sig, even if there
+		// is an error checking its arguments (for example, if an incorrect number
+		// of arguments is supplied).
+		if got == want && want > 0 {
+			if !check.allowVersion(check.pkg, 1, 18) {
+				check.softErrorf(inNode(call.Fun, ix.Lbrack), UnsupportedFeature, "function instantiation requires go1.18 or later")
+			}
+
+			sig = check.instantiateSignature(ix.Pos(), sig, targs, xlist)
+			assert(sig.TypeParams().Len() == 0) // signature is not generic anymore
+			check.recordInstance(ix.Orig, targs, sig)
+
+			// targs have been consumed; proceed with checking arguments of the
+			// non-generic signature.
+			targs = nil
+			xlist = nil
+		}
 	}
 
 	// evaluate arguments
 	args, _ := check.exprList(call.Args, false)
-	isGeneric := sig.TypeParams().Len() > 0
 	sig = check.arguments(call, sig, targs, args, xlist)
 
-	if isGeneric && sig.TypeParams().Len() == 0 {
+	if wasGeneric && sig.TypeParams().Len() == 0 {
 		// Update the recorded type of call.Fun to its instantiated type.
 		check.recordTypeAndValue(call.Fun, value, sig, nil)
 	}
@@ -292,7 +314,7 @@
 	for _, a := range args {
 		switch a.mode {
 		case typexpr:
-			check.errorf(a, 0, "%s used as value", a)
+			check.errorf(a, NotAnExpr, "%s used as value", a)
 			return
 		case invalid:
 			return
@@ -320,7 +342,7 @@
 			// variadic_func(a, b, c...)
 			if len(call.Args) == 1 && nargs > 1 {
 				// f()... is not permitted if f() is multi-valued
-				check.errorf(inNode(call, call.Ellipsis), _InvalidDotDotDot, "cannot use ... with %d-valued %s", nargs, call.Args[0])
+				check.errorf(inNode(call, call.Ellipsis), InvalidDotDotDot, "cannot use ... with %d-valued %s", nargs, call.Args[0])
 				return
 			}
 		} else {
@@ -347,7 +369,7 @@
 	} else {
 		if ddd {
 			// standard_func(a, b, c...)
-			check.errorf(inNode(call, call.Ellipsis), _NonVariadicDotDotDot, "cannot use ... in call to non-variadic %s", call.Fun)
+			check.errorf(inNode(call, call.Ellipsis), NonVariadicDotDotDot, "cannot use ... in call to non-variadic %s", call.Fun)
 			return
 		}
 		// standard_func(a, b, c)
@@ -368,7 +390,7 @@
 		if sig.params != nil {
 			params = sig.params.vars
 		}
-		err := newErrorf(at, _WrongArgCount, "%s arguments in call to %s", qualifier, call.Fun)
+		err := newErrorf(at, WrongArgCount, "%s arguments in call to %s", qualifier, call.Fun)
 		err.errorf(token.NoPos, "have %s", check.typesSummary(operandTypes(args), false))
 		err.errorf(token.NoPos, "want %s", check.typesSummary(varTypes(params), sig.variadic))
 		check.report(err)
@@ -381,9 +403,9 @@
 			switch call.Fun.(type) {
 			case *ast.IndexExpr, *ast.IndexListExpr:
 				ix := typeparams.UnpackIndexExpr(call.Fun)
-				check.softErrorf(inNode(call.Fun, ix.Lbrack), _UnsupportedFeature, "function instantiation requires go1.18 or later")
+				check.softErrorf(inNode(call.Fun, ix.Lbrack), UnsupportedFeature, "function instantiation requires go1.18 or later")
 			default:
-				check.softErrorf(inNode(call, call.Lparen), _UnsupportedFeature, "implicit function instantiation requires go1.18 or later")
+				check.softErrorf(inNode(call, call.Lparen), UnsupportedFeature, "implicit function instantiation requires go1.18 or later")
 			}
 		}
 		targs := check.infer(call, sig.TypeParams().list(), targs, sigParams, args)
@@ -428,7 +450,7 @@
 	"_Cmacro_", // function to evaluate the expanded expression
 }
 
-func (check *Checker) selector(x *operand, e *ast.SelectorExpr, def *Named) {
+func (check *Checker) selector(x *operand, e *ast.SelectorExpr, def *Named, wantType bool) {
 	// these must be declared before the "goto Error" statements
 	var (
 		obj      Object
@@ -469,7 +491,7 @@
 					}
 				}
 				if exp == nil {
-					check.errorf(e.Sel, _UndeclaredImportedName, "%s not declared by package C", sel)
+					check.errorf(e.Sel, UndeclaredImportedName, "undefined: %s", ast.Expr(e)) // cast to ast.Expr to silence vet
 					goto Error
 				}
 				check.objDecl(exp, nil)
@@ -477,12 +499,12 @@
 				exp = pkg.scope.Lookup(sel)
 				if exp == nil {
 					if !pkg.fake {
-						check.errorf(e.Sel, _UndeclaredImportedName, "%s not declared by package %s", sel, pkg.name)
+						check.errorf(e.Sel, UndeclaredImportedName, "undefined: %s", ast.Expr(e))
 					}
 					goto Error
 				}
 				if !exp.Exported() {
-					check.errorf(e.Sel, _UnexportedName, "%s not exported by package %s", sel, pkg.name)
+					check.errorf(e.Sel, UnexportedName, "%s not exported by package %s", sel, pkg.name)
 					// ok to continue
 				}
 			}
@@ -535,12 +557,31 @@
 		}
 	case builtin:
 		// types2 uses the position of '.' for the error
-		check.errorf(e.Sel, _UncalledBuiltin, "cannot select on %s", x)
+		check.errorf(e.Sel, UncalledBuiltin, "cannot select on %s", x)
 		goto Error
 	case invalid:
 		goto Error
 	}
 
+	// Avoid crashing when checking an invalid selector in a method declaration
+	// (i.e., where def is not set):
+	//
+	//   type S[T any] struct{}
+	//   type V = S[any]
+	//   func (fs *S[T]) M(x V.M) {}
+	//
+	// All codepaths below return a non-type expression. If we get here while
+	// expecting a type expression, it is an error.
+	//
+	// See issue #57522 for more details.
+	//
+	// TODO(rfindley): We should do better by refusing to check selectors in all cases where
+	// x.typ is incomplete.
+	if wantType {
+		check.errorf(e.Sel, NotAType, "%s is not a type", ast.Expr(e))
+		goto Error
+	}
+
 	obj, index, indirect = LookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, sel)
 	if obj == nil {
 		// Don't report another error if the underlying type was invalid (issue #49541).
@@ -550,12 +591,16 @@
 
 		if index != nil {
 			// TODO(gri) should provide actual type where the conflict happens
-			check.errorf(e.Sel, _AmbiguousSelector, "ambiguous selector %s.%s", x.expr, sel)
+			check.errorf(e.Sel, AmbiguousSelector, "ambiguous selector %s.%s", x.expr, sel)
 			goto Error
 		}
 
 		if indirect {
-			check.errorf(e.Sel, _InvalidMethodExpr, "cannot call pointer method %s on %s", sel, x.typ)
+			if x.mode == typexpr {
+				check.errorf(e.Sel, InvalidMethodExpr, "invalid method expression %s.%s (needs pointer receiver (*%s).%s)", x.typ, sel, x.typ, sel)
+			} else {
+				check.errorf(e.Sel, InvalidMethodExpr, "cannot call pointer method %s on %s", sel, x.typ)
+			}
 			goto Error
 		}
 
@@ -580,7 +625,7 @@
 				}
 			}
 		}
-		check.errorf(e.Sel, _MissingFieldOrMethod, "%s.%s undefined (%s)", x.expr, sel, why)
+		check.errorf(e.Sel, MissingFieldOrMethod, "%s.%s undefined (%s)", x.expr, sel, why)
 		goto Error
 	}
 
@@ -594,7 +639,7 @@
 		m, _ := obj.(*Func)
 		if m == nil {
 			// TODO(gri) should check if capitalization of sel matters and provide better error message in that case
-			check.errorf(e.Sel, _MissingFieldOrMethod, "%s.%s undefined (type %s has no method %s)", x.expr, sel, x.typ, sel)
+			check.errorf(e.Sel, MissingFieldOrMethod, "%s.%s undefined (type %s has no method %s)", x.expr, sel, x.typ, sel)
 			goto Error
 		}
 
@@ -602,7 +647,7 @@
 
 		sig := m.typ.(*Signature)
 		if sig.recv == nil {
-			check.error(e, _InvalidDeclCycle, "illegal cycle in method declaration")
+			check.error(e, InvalidDeclCycle, "illegal cycle in method declaration")
 			goto Error
 		}
 
diff --git a/src/go/types/check.go b/src/go/types/check.go
index b787c5c..50d8afe 100644
--- a/src/go/types/check.go
+++ b/src/go/types/check.go
@@ -12,16 +12,13 @@
 	"go/ast"
 	"go/constant"
 	"go/token"
+	. "internal/types/errors"
 )
 
 // debugging/development support
 const (
 	debug = false // leave on during development
 	trace = false // turn on for detailed type resolution traces
-
-	// TODO(rfindley): add compiler error message handling from types2, guarded
-	// behind this flag, so that we can keep the code in sync.
-	compilerErrorMessages = false // match compiler error messages
 )
 
 // exprInfo stores information about an untyped expression.
@@ -275,7 +272,7 @@
 			if name != "_" {
 				pkg.name = name
 			} else {
-				check.errorf(file.Name, _BlankPkgName, "invalid package name _")
+				check.error(file.Name, BlankPkgName, "invalid package name _")
 			}
 			fallthrough
 
@@ -283,7 +280,7 @@
 			check.files = append(check.files, file)
 
 		default:
-			check.errorf(atPos(file.Package), _MismatchedPkgName, "package %s; expected %s", name, pkg.name)
+			check.errorf(atPos(file.Package), MismatchedPkgName, "package %s; expected %s", name, pkg.name)
 			// ignore this file
 		}
 	}
diff --git a/src/go/types/check_test.go b/src/go/types/check_test.go
index 4684a6e..215a836 100644
--- a/src/go/types/check_test.go
+++ b/src/go/types/check_test.go
@@ -34,6 +34,7 @@
 	"internal/testenv"
 	"os"
 	"path/filepath"
+	"reflect"
 	"regexp"
 	"strings"
 	"testing"
@@ -44,13 +45,12 @@
 var (
 	haltOnError  = flag.Bool("halt", false, "halt on error")
 	verifyErrors = flag.Bool("verify", false, "verify errors (rather than list them) in TestManual")
-	goVersion    = flag.String("lang", "", "Go language version (e.g. \"go1.12\") for TestManual")
 )
 
 var fset = token.NewFileSet()
 
 // Positioned errors are of the form filename:line:column: message .
-var posMsgRx = regexp.MustCompile(`^(.*:[0-9]+:[0-9]+): *(?s)(.*)`)
+var posMsgRx = regexp.MustCompile(`^(.*:\d+:\d+): *(?s)(.*)`)
 
 // splitError splits an error's error message into a position string
 // and the actual error message. If there's no position information,
@@ -88,10 +88,8 @@
 
 // ERROR comments must start with text `ERROR "rx"` or `ERROR rx` where
 // rx is a regular expression that matches the expected error message.
-// Space around "rx" or rx is ignored. Use the form `ERROR HERE "rx"`
-// for error messages that are located immediately after rather than
-// at a token's position.
-var errRx = regexp.MustCompile(`^ *ERROR *(HERE)? *"?([^"]*)"?`)
+// Space around "rx" or rx is ignored.
+var errRx = regexp.MustCompile(`^ *ERROR *"?([^"]*)"?`)
 
 // errMap collects the regular expressions of ERROR comments found
 // in files and returns them as a map of error positions to error messages.
@@ -108,7 +106,6 @@
 		var s scanner.Scanner
 		s.Init(tok, src, nil, scanner.ScanComments)
 		var prev token.Pos // position of last non-comment, non-semicolon token
-		var here token.Pos // position immediately after the token at position prev
 
 	scanFile:
 		for {
@@ -120,13 +117,9 @@
 				if lit[1] == '*' {
 					lit = lit[:len(lit)-2] // strip trailing */
 				}
-				if s := errRx.FindStringSubmatch(lit[2:]); len(s) == 3 {
-					pos := prev
-					if s[1] == "HERE" {
-						pos = here
-					}
-					p := fset.Position(pos).String()
-					errmap[p] = append(errmap[p], strings.TrimSpace(s[2]))
+				if s := errRx.FindStringSubmatch(lit[2:]); len(s) == 2 {
+					p := fset.Position(prev).String()
+					errmap[p] = append(errmap[p], strings.TrimSpace(s[1]))
 				}
 			case token.SEMICOLON:
 				// ignore automatically inserted semicolon
@@ -136,13 +129,6 @@
 				fallthrough
 			default:
 				prev = pos
-				var l int // token length
-				if tok.IsLiteral() {
-					l = len(lit)
-				} else {
-					l = len(tok.String())
-				}
-				here = prev + token.Pos(l)
 			}
 		}
 	}
@@ -185,7 +171,7 @@
 
 // parseFlags parses flags from the first line of the given source
 // (from src if present, or by reading from the file) if the line
-// starts with "//" (line comment) followed by "-" (possiby with
+// starts with "//" (line comment) followed by "-" (possibly with
 // spaces between). Otherwise the line is ignored.
 func parseFlags(filename string, src []byte, flags *flag.FlagSet) error {
 	// If there is no src, read from the file.
@@ -231,21 +217,11 @@
 	flags := flag.NewFlagSet("", flag.PanicOnError)
 	flags.StringVar(&conf.GoVersion, "lang", "", "")
 	flags.BoolVar(&conf.FakeImportC, "fakeImportC", false, "")
+	flags.BoolVar(addrOldComparableSemantics(&conf), "oldComparableSemantics", false, "")
 	if err := parseFlags(filenames[0], srcs[0], flags); err != nil {
 		t.Fatal(err)
 	}
 
-	if manual && *goVersion != "" {
-		// goVersion overrides -lang for manual tests.
-		conf.GoVersion = *goVersion
-	}
-
-	// TODO(gri) remove this or use flag mechanism to set mode if still needed
-	if strings.HasSuffix(filenames[0], ".go1") {
-		// TODO(rfindley): re-enable this test by using GoVersion.
-		t.Skip("type params are enabled")
-	}
-
 	files, errlist := parseFiles(t, filenames, srcs, parser.AllErrors)
 
 	pkgName := "<no package>"
@@ -313,6 +289,17 @@
 	}
 }
 
+func readCode(err Error) int {
+	v := reflect.ValueOf(err)
+	return int(v.FieldByName("go116code").Int())
+}
+
+// addrOldComparableSemantics(conf) returns &conf.oldComparableSemantics (unexported field).
+func addrOldComparableSemantics(conf *Config) *bool {
+	v := reflect.Indirect(reflect.ValueOf(conf))
+	return (*bool)(v.FieldByName("oldComparableSemantics").Addr().UnsafePointer())
+}
+
 // TestManual is for manual testing of a package - either provided
 // as a list of filenames belonging to the package, or a directory
 // name containing the package files - after the test arguments
@@ -352,7 +339,7 @@
 }
 
 func TestLongConstants(t *testing.T) {
-	format := "package longconst\n\nconst _ = %s\nconst _ = %s // ERROR excessively long constant"
+	format := "package longconst\n\nconst _ = %s /* ERROR constant overflow */ \nconst _ = %s // ERROR excessively long constant"
 	src := fmt.Sprintf(format, strings.Repeat("1", 9999), strings.Repeat("1", 10001))
 	testFiles(t, nil, []string{"longconst.go"}, [][]byte{[]byte(src)}, false, nil)
 }
@@ -372,10 +359,14 @@
 	testFiles(t, &StdSizes{4, 4}, []string{"p.go"}, [][]byte{[]byte(src)}, false, nil)
 }
 
-func TestCheck(t *testing.T)     { DefPredeclaredTestFuncs(); testDirFiles(t, "testdata/check", false) }
-func TestSpec(t *testing.T)      { testDirFiles(t, "testdata/spec", false) }
-func TestExamples(t *testing.T)  { testDirFiles(t, "testdata/examples", false) }
-func TestFixedbugs(t *testing.T) { testDirFiles(t, "testdata/fixedbugs", false) }
+func TestCheck(t *testing.T) {
+	DefPredeclaredTestFuncs()
+	testDirFiles(t, "../../internal/types/testdata/check", false)
+}
+func TestSpec(t *testing.T)      { testDirFiles(t, "../../internal/types/testdata/spec", false) }
+func TestExamples(t *testing.T)  { testDirFiles(t, "../../internal/types/testdata/examples", false) }
+func TestFixedbugs(t *testing.T) { testDirFiles(t, "../../internal/types/testdata/fixedbugs", false) }
+func TestLocal(t *testing.T)     { testDirFiles(t, "testdata/local", false) }
 
 func testDirFiles(t *testing.T, dir string, manual bool) {
 	testenv.MustHaveGoBuild(t)
diff --git a/src/go/types/conversions.go b/src/go/types/conversions.go
index 362c8fd..3cdbedb 100644
--- a/src/go/types/conversions.go
+++ b/src/go/types/conversions.go
@@ -8,7 +8,7 @@
 
 import (
 	"go/constant"
-	"go/token"
+	. "internal/types/errors"
 	"unicode"
 )
 
@@ -58,7 +58,7 @@
 				return true
 			}
 			if !constConvertibleTo(u, nil) {
-				cause = check.sprintf("cannot convert %s to %s (in %s)", x, u, T)
+				cause = check.sprintf("cannot convert %s to type %s (in %s)", x, u, T)
 				return false
 			}
 			return true
@@ -71,22 +71,10 @@
 	}
 
 	if !ok {
-		// TODO(rfindley): use types2-style error reporting here.
-		if compilerErrorMessages {
-			if cause != "" {
-				// Add colon at end of line if we have a following cause.
-				err := newErrorf(x, _InvalidConversion, "cannot convert %s to type %s:", x, T)
-				err.errorf(token.NoPos, cause)
-				check.report(err)
-			} else {
-				check.errorf(x, _InvalidConversion, "cannot convert %s to type %s", x, T)
-			}
+		if cause != "" {
+			check.errorf(x, InvalidConversion, "cannot convert %s to type %s: %s", x, T, cause)
 		} else {
-			if cause != "" {
-				check.errorf(x, _InvalidConversion, "cannot convert %s to %s (%s)", x, T, cause)
-			} else {
-				check.errorf(x, _InvalidConversion, "cannot convert %s to %s", x, T)
-			}
+			check.errorf(x, InvalidConversion, "cannot convert %s to type %s", x, T)
 		}
 		x.mode = invalid
 		return
@@ -187,18 +175,33 @@
 		return true
 	}
 
-	// "V a slice, T is a pointer-to-array type,
+	// "V is a slice, T is an array or pointer-to-array type,
 	// and the slice and array types have identical element types."
 	if s, _ := Vu.(*Slice); s != nil {
-		if p, _ := Tu.(*Pointer); p != nil {
-			if a, _ := under(p.Elem()).(*Array); a != nil {
+		switch a := Tu.(type) {
+		case *Array:
+			if Identical(s.Elem(), a.Elem()) {
+				if check == nil || check.allowVersion(check.pkg, 1, 20) {
+					return true
+				}
+				// check != nil
+				if cause != nil {
+					// TODO(gri) consider restructuring versionErrorf so we can use it here and below
+					*cause = "conversion of slices to arrays requires go1.20 or later"
+				}
+				return false
+			}
+		case *Pointer:
+			if a, _ := under(a.Elem()).(*Array); a != nil {
 				if Identical(s.Elem(), a.Elem()) {
 					if check == nil || check.allowVersion(check.pkg, 1, 17) {
 						return true
 					}
+					// check != nil
 					if cause != nil {
 						*cause = "conversion of slices to array pointers requires go1.17 or later"
 					}
+					return false
 				}
 			}
 		}
@@ -234,7 +237,7 @@
 					return false // no specific types
 				}
 				if !x.convertibleTo(check, T.typ, cause) {
-					errorf("cannot convert %s (in %s) to %s (in %s)", V.typ, Vp, T.typ, Tp)
+					errorf("cannot convert %s (in %s) to type %s (in %s)", V.typ, Vp, T.typ, Tp)
 					return false
 				}
 				return true
@@ -248,7 +251,7 @@
 			}
 			x.typ = V.typ
 			if !x.convertibleTo(check, T, cause) {
-				errorf("cannot convert %s (in %s) to %s", V.typ, Vp, T)
+				errorf("cannot convert %s (in %s) to type %s", V.typ, Vp, T)
 				return false
 			}
 			return true
@@ -259,7 +262,7 @@
 				return false // no specific types
 			}
 			if !x.convertibleTo(check, T.typ, cause) {
-				errorf("cannot convert %s to %s (in %s)", x.typ, T.typ, Tp)
+				errorf("cannot convert %s to type %s (in %s)", x.typ, T.typ, Tp)
 				return false
 			}
 			return true
diff --git a/src/go/types/decl.go b/src/go/types/decl.go
index 829aee7..adc485c 100644
--- a/src/go/types/decl.go
+++ b/src/go/types/decl.go
@@ -5,11 +5,11 @@
 package types
 
 import (
-	"bytes"
 	"fmt"
 	"go/ast"
 	"go/constant"
 	"go/token"
+	. "internal/types/errors"
 )
 
 func (check *Checker) reportAltDecl(obj Object) {
@@ -17,7 +17,7 @@
 		// We use "other" rather than "previous" here because
 		// the first declaration seen may not be textually
 		// earlier in the source.
-		check.errorf(obj, _DuplicateDecl, "\tother declaration of %s", obj.Name()) // secondary error, \t indented
+		check.errorf(obj, DuplicateDecl, "\tother declaration of %s", obj.Name()) // secondary error, \t indented
 	}
 }
 
@@ -28,7 +28,7 @@
 	// binding."
 	if obj.Name() != "_" {
 		if alt := scope.Insert(obj); alt != nil {
-			check.errorf(obj, _DuplicateDecl, "%s redeclared in this block", obj.Name())
+			check.errorf(obj, DuplicateDecl, "%s redeclared in this block", obj.Name())
 			check.reportAltDecl(alt)
 			return
 		}
@@ -308,10 +308,7 @@
 	// may refer to imported types. See issue #50788.
 	// TODO(gri) Thus functionality is used elsewhere. Factor it out.
 	name := func(obj Object) string {
-		var buf bytes.Buffer
-		writePackage(&buf, obj.Pkg(), check.qualifier)
-		buf.WriteString(obj.Name())
-		return buf.String()
+		return packagePrefix(obj.Pkg(), check.qualifier) + obj.Name()
 	}
 
 	// TODO(gri) Should we start with the last (rather than the first) object in the cycle
@@ -325,13 +322,24 @@
 	if tname != nil && tname.IsAlias() {
 		check.validAlias(tname, Typ[Invalid])
 	}
-	if tname != nil && compilerErrorMessages {
-		check.errorf(obj, _InvalidDeclCycle, "invalid recursive type %s", objName)
+
+	// report a more concise error for self references
+	if len(cycle) == 1 {
+		if tname != nil {
+			check.errorf(obj, InvalidDeclCycle, "invalid recursive type: %s refers to itself", objName)
+		} else {
+			check.errorf(obj, InvalidDeclCycle, "invalid cycle in declaration: %s refers to itself", objName)
+		}
+		return
+	}
+
+	if tname != nil {
+		check.errorf(obj, InvalidDeclCycle, "invalid recursive type %s", objName)
 	} else {
-		check.errorf(obj, _InvalidDeclCycle, "illegal cycle in declaration of %s", objName)
+		check.errorf(obj, InvalidDeclCycle, "invalid cycle in declaration of %s", objName)
 	}
 	for range cycle {
-		check.errorf(obj, _InvalidDeclCycle, "\t%s refers to", objName) // secondary error, \t indented
+		check.errorf(obj, InvalidDeclCycle, "\t%s refers to", objName) // secondary error, \t indented
 		i++
 		if i >= len(cycle) {
 			i = 0
@@ -339,7 +347,7 @@
 		obj = cycle[i]
 		objName = name(obj)
 	}
-	check.errorf(obj, _InvalidDeclCycle, "\t%s", objName)
+	check.errorf(obj, InvalidDeclCycle, "\t%s", objName)
 }
 
 // firstInSrc reports the index of the object with the "smallest"
@@ -413,18 +421,18 @@
 					check.arityMatch(s, nil)
 					f(varDecl{s})
 				default:
-					check.invalidAST(s, "invalid token %s", d.Tok)
+					check.errorf(s, InvalidSyntaxTree, "invalid token %s", d.Tok)
 				}
 			case *ast.TypeSpec:
 				f(typeDecl{s})
 			default:
-				check.invalidAST(s, "unknown ast.Spec node %T", s)
+				check.errorf(s, InvalidSyntaxTree, "unknown ast.Spec node %T", s)
 			}
 		}
 	case *ast.FuncDecl:
 		f(funcDecl{d})
 	default:
-		check.invalidAST(d, "unknown ast.Decl node %T", d)
+		check.errorf(d, InvalidSyntaxTree, "unknown ast.Decl node %T", d)
 	}
 }
 
@@ -449,7 +457,7 @@
 			// don't report an error if the type is an invalid C (defined) type
 			// (issue #22090)
 			if under(t) != Typ[Invalid] {
-				check.errorf(typ, _InvalidConstType, "invalid constant type %s", t)
+				check.errorf(typ, InvalidConstType, "invalid constant type %s", t)
 			}
 			obj.typ = Typ[Invalid]
 			return
@@ -554,7 +562,7 @@
 		}
 		// If typ is local, an error was already reported where typ is specified/defined.
 		if check.isImportedConstraint(rhs) && !check.allowVersion(check.pkg, 1, 18) {
-			check.errorf(tdecl.Type, _UnsupportedFeature, "using type constraint %s requires go1.18 or later", rhs)
+			check.errorf(tdecl.Type, UnsupportedFeature, "using type constraint %s requires go1.18 or later", rhs)
 		}
 	}).describef(obj, "validType(%s)", obj.Name())
 
@@ -562,14 +570,14 @@
 	if alias && tdecl.TypeParams.NumFields() != 0 {
 		// The parser will ensure this but we may still get an invalid AST.
 		// Complain and continue as regular type definition.
-		check.error(atPos(tdecl.Assign), _BadDecl, "generic type cannot be alias")
+		check.error(atPos(tdecl.Assign), BadDecl, "generic type cannot be alias")
 		alias = false
 	}
 
 	// alias declaration
 	if alias {
 		if !check.allowVersion(check.pkg, 1, 9) {
-			check.errorf(atPos(tdecl.Assign), _BadDecl, "type aliases requires go1.9 or later")
+			check.error(atPos(tdecl.Assign), UnsupportedFeature, "type aliases requires go1.9 or later")
 		}
 
 		check.brokenAlias(obj)
@@ -605,7 +613,7 @@
 	// use its underlying type (like we do for any RHS in a type declaration), and its
 	// underlying type is an interface and the type declaration is well defined.
 	if isTypeParam(rhs) {
-		check.error(tdecl.Type, _MisplacedTypeParam, "cannot use a type parameter as RHS in type declaration")
+		check.error(tdecl.Type, MisplacedTypeParam, "cannot use a type parameter as RHS in type declaration")
 		named.underlying = Typ[Invalid]
 	}
 }
@@ -649,7 +657,7 @@
 				// the underlying type and thus type set of a type parameter is.
 				// But we may need some additional form of cycle detection within
 				// type parameter lists.
-				check.error(f.Type, _MisplacedTypeParam, "cannot use a type parameter as constraint")
+				check.error(f.Type, MisplacedTypeParam, "cannot use a type parameter as constraint")
 				bound = Typ[Invalid]
 			}
 		} else {
@@ -749,8 +757,11 @@
 		// to it must be unique."
 		assert(m.name != "_")
 		if alt := mset.insert(m); alt != nil {
-			check.errorf(m, _DuplicateMethod, "method %s already declared for %s", m.name, obj)
-			check.reportAltDecl(alt)
+			if alt.Pos().IsValid() {
+				check.errorf(m, DuplicateMethod, "method %s.%s already declared at %s", obj.Name(), m.name, alt.Pos())
+			} else {
+				check.errorf(m, DuplicateMethod, "method %s.%s already declared", obj.Name(), m.name)
+			}
 			continue
 		}
 
@@ -780,7 +791,7 @@
 
 					// For historical consistency, we report the primary error on the
 					// method, and the alt decl on the field.
-					check.errorf(alt, _DuplicateFieldAndMethod, "field and method with the same name %s", fld.name)
+					check.errorf(alt, DuplicateFieldAndMethod, "field and method with the same name %s", fld.name)
 					check.reportAltDecl(fld)
 				}
 			}
@@ -810,7 +821,7 @@
 	obj.color_ = saved
 
 	if fdecl.Type.TypeParams.NumFields() > 0 && fdecl.Body == nil {
-		check.softErrorf(fdecl.Name, _BadDecl, "parameterized function is missing function body")
+		check.softErrorf(fdecl.Name, BadDecl, "generic function is missing function body")
 	}
 
 	// function body must be type-checked after global declarations
@@ -920,7 +931,7 @@
 			check.typeDecl(obj, d.spec, nil)
 			check.pop().setColor(black)
 		default:
-			check.invalidAST(d.node(), "unknown ast.Decl node %T", d.node())
+			check.errorf(d.node(), InvalidSyntaxTree, "unknown ast.Decl node %T", d.node())
 		}
 	})
 }
diff --git a/src/go/types/errorcalls_test.go b/src/go/types/errorcalls_test.go
new file mode 100644
index 0000000..6d6bd60
--- /dev/null
+++ b/src/go/types/errorcalls_test.go
@@ -0,0 +1,53 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE ast.
+
+package types_test
+
+import (
+	"go/ast"
+	"go/token"
+	"testing"
+)
+
+const errorfMinArgCount = 4
+
+// TestErrorCalls makes sure that check.errorf calls have at least
+// errorfMinArgCount arguments (otherwise we should use check.error).
+func TestErrorCalls(t *testing.T) {
+	fset := token.NewFileSet()
+	files, err := pkgFiles(fset, ".")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	for _, file := range files {
+		ast.Inspect(file, func(n ast.Node) bool {
+			call, _ := n.(*ast.CallExpr)
+			if call == nil {
+				return true
+			}
+			selx, _ := call.Fun.(*ast.SelectorExpr)
+			if selx == nil {
+				return true
+			}
+			if !(isName(selx.X, "check") && isName(selx.Sel, "errorf")) {
+				return true
+			}
+			// check.errorf calls should have at least errorfMinArgCount arguments:
+			// position, code, format string, and arguments to format
+			if n := len(call.Args); n < errorfMinArgCount {
+				t.Errorf("%s: got %d arguments, want at least %d", fset.Position(call.Pos()), n, errorfMinArgCount)
+				return false
+			}
+			return true
+		})
+	}
+}
+
+func isName(n ast.Node, name string) bool {
+	if n, ok := n.(*ast.Ident); ok {
+		return n.Name == name
+	}
+	return false
+}
diff --git a/src/go/types/errorcodes.go b/src/go/types/errorcodes.go
deleted file mode 100644
index 64cf24c..0000000
--- a/src/go/types/errorcodes.go
+++ /dev/null
@@ -1,1392 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package types
-
-type errorCode int
-
-// This file defines the error codes that can be produced during type-checking.
-// Collectively, these codes provide an identifier that may be used to
-// implement special handling for certain types of errors.
-//
-// Error code values should not be changed: add new codes at the end.
-//
-// Error codes should be fine-grained enough that the exact nature of the error
-// can be easily determined, but coarse enough that they are not an
-// implementation detail of the type checking algorithm. As a rule-of-thumb,
-// errors should be considered equivalent if there is a theoretical refactoring
-// of the type checker in which they are emitted in exactly one place. For
-// example, the type checker emits different error messages for "too many
-// arguments" and "too few arguments", but one can imagine an alternative type
-// checker where this check instead just emits a single "wrong number of
-// arguments", so these errors should have the same code.
-//
-// Error code names should be as brief as possible while retaining accuracy and
-// distinctiveness. In most cases names should start with an adjective
-// describing the nature of the error (e.g. "invalid", "unused", "misplaced"),
-// and end with a noun identifying the relevant language object. For example,
-// "_DuplicateDecl" or "_InvalidSliceExpr". For brevity, naming follows the
-// convention that "bad" implies a problem with syntax, and "invalid" implies a
-// problem with types.
-
-const (
-	_ errorCode = iota
-
-	// _Test is reserved for errors that only apply while in self-test mode.
-	_Test
-
-	// _BlankPkgName occurs when a package name is the blank identifier "_".
-	//
-	// Per the spec:
-	//  "The PackageName must not be the blank identifier."
-	_BlankPkgName
-
-	// _MismatchedPkgName occurs when a file's package name doesn't match the
-	// package name already established by other files.
-	_MismatchedPkgName
-
-	// _InvalidPkgUse occurs when a package identifier is used outside of a
-	// selector expression.
-	//
-	// Example:
-	//  import "fmt"
-	//
-	//  var _ = fmt
-	_InvalidPkgUse
-
-	// _BadImportPath occurs when an import path is not valid.
-	_BadImportPath
-
-	// _BrokenImport occurs when importing a package fails.
-	//
-	// Example:
-	//  import "amissingpackage"
-	_BrokenImport
-
-	// _ImportCRenamed occurs when the special import "C" is renamed. "C" is a
-	// pseudo-package, and must not be renamed.
-	//
-	// Example:
-	//  import _ "C"
-	_ImportCRenamed
-
-	// _UnusedImport occurs when an import is unused.
-	//
-	// Example:
-	//  import "fmt"
-	//
-	//  func main() {}
-	_UnusedImport
-
-	// _InvalidInitCycle occurs when an invalid cycle is detected within the
-	// initialization graph.
-	//
-	// Example:
-	//  var x int = f()
-	//
-	//  func f() int { return x }
-	_InvalidInitCycle
-
-	// _DuplicateDecl occurs when an identifier is declared multiple times.
-	//
-	// Example:
-	//  var x = 1
-	//  var x = 2
-	_DuplicateDecl
-
-	// _InvalidDeclCycle occurs when a declaration cycle is not valid.
-	//
-	// Example:
-	//  type S struct {
-	//  	S
-	//  }
-	//
-	_InvalidDeclCycle
-
-	// _InvalidTypeCycle occurs when a cycle in type definitions results in a
-	// type that is not well-defined.
-	//
-	// Example:
-	//  import "unsafe"
-	//
-	//  type T [unsafe.Sizeof(T{})]int
-	_InvalidTypeCycle
-
-	// _InvalidConstInit occurs when a const declaration has a non-constant
-	// initializer.
-	//
-	// Example:
-	//  var x int
-	//  const _ = x
-	_InvalidConstInit
-
-	// _InvalidConstVal occurs when a const value cannot be converted to its
-	// target type.
-	//
-	// TODO(findleyr): this error code and example are not very clear. Consider
-	// removing it.
-	//
-	// Example:
-	//  const _ = 1 << "hello"
-	_InvalidConstVal
-
-	// _InvalidConstType occurs when the underlying type in a const declaration
-	// is not a valid constant type.
-	//
-	// Example:
-	//  const c *int = 4
-	_InvalidConstType
-
-	// _UntypedNil occurs when the predeclared (untyped) value nil is used to
-	// initialize a variable declared without an explicit type.
-	//
-	// Example:
-	//  var x = nil
-	_UntypedNil
-
-	// _WrongAssignCount occurs when the number of values on the right-hand side
-	// of an assignment or initialization expression does not match the number
-	// of variables on the left-hand side.
-	//
-	// Example:
-	//  var x = 1, 2
-	_WrongAssignCount
-
-	// _UnassignableOperand occurs when the left-hand side of an assignment is
-	// not assignable.
-	//
-	// Example:
-	//  func f() {
-	//  	const c = 1
-	//  	c = 2
-	//  }
-	_UnassignableOperand
-
-	// _NoNewVar occurs when a short variable declaration (':=') does not declare
-	// new variables.
-	//
-	// Example:
-	//  func f() {
-	//  	x := 1
-	//  	x := 2
-	//  }
-	_NoNewVar
-
-	// _MultiValAssignOp occurs when an assignment operation (+=, *=, etc) does
-	// not have single-valued left-hand or right-hand side.
-	//
-	// Per the spec:
-	//  "In assignment operations, both the left- and right-hand expression lists
-	//  must contain exactly one single-valued expression"
-	//
-	// Example:
-	//  func f() int {
-	//  	x, y := 1, 2
-	//  	x, y += 1
-	//  	return x + y
-	//  }
-	_MultiValAssignOp
-
-	// _InvalidIfaceAssign occurs when a value of type T is used as an
-	// interface, but T does not implement a method of the expected interface.
-	//
-	// Example:
-	//  type I interface {
-	//  	f()
-	//  }
-	//
-	//  type T int
-	//
-	//  var x I = T(1)
-	_InvalidIfaceAssign
-
-	// _InvalidChanAssign occurs when a chan assignment is invalid.
-	//
-	// Per the spec, a value x is assignable to a channel type T if:
-	//  "x is a bidirectional channel value, T is a channel type, x's type V and
-	//  T have identical element types, and at least one of V or T is not a
-	//  defined type."
-	//
-	// Example:
-	//  type T1 chan int
-	//  type T2 chan int
-	//
-	//  var x T1
-	//  // Invalid assignment because both types are named
-	//  var _ T2 = x
-	_InvalidChanAssign
-
-	// _IncompatibleAssign occurs when the type of the right-hand side expression
-	// in an assignment cannot be assigned to the type of the variable being
-	// assigned.
-	//
-	// Example:
-	//  var x []int
-	//  var _ int = x
-	_IncompatibleAssign
-
-	// _UnaddressableFieldAssign occurs when trying to assign to a struct field
-	// in a map value.
-	//
-	// Example:
-	//  func f() {
-	//  	m := make(map[string]struct{i int})
-	//  	m["foo"].i = 42
-	//  }
-	_UnaddressableFieldAssign
-
-	// _NotAType occurs when the identifier used as the underlying type in a type
-	// declaration or the right-hand side of a type alias does not denote a type.
-	//
-	// Example:
-	//  var S = 2
-	//
-	//  type T S
-	_NotAType
-
-	// _InvalidArrayLen occurs when an array length is not a constant value.
-	//
-	// Example:
-	//  var n = 3
-	//  var _ = [n]int{}
-	_InvalidArrayLen
-
-	// _BlankIfaceMethod occurs when a method name is '_'.
-	//
-	// Per the spec:
-	//  "The name of each explicitly specified method must be unique and not
-	//  blank."
-	//
-	// Example:
-	//  type T interface {
-	//  	_(int)
-	//  }
-	_BlankIfaceMethod
-
-	// _IncomparableMapKey occurs when a map key type does not support the == and
-	// != operators.
-	//
-	// Per the spec:
-	//  "The comparison operators == and != must be fully defined for operands of
-	//  the key type; thus the key type must not be a function, map, or slice."
-	//
-	// Example:
-	//  var x map[T]int
-	//
-	//  type T []int
-	_IncomparableMapKey
-
-	// _InvalidIfaceEmbed occurs when a non-interface type is embedded in an
-	// interface (for go 1.17 or earlier).
-	_InvalidIfaceEmbed
-
-	// _InvalidPtrEmbed occurs when an embedded field is of the pointer form *T,
-	// and T itself is itself a pointer, an unsafe.Pointer, or an interface.
-	//
-	// Per the spec:
-	//  "An embedded field must be specified as a type name T or as a pointer to
-	//  a non-interface type name *T, and T itself may not be a pointer type."
-	//
-	// Example:
-	//  type T *int
-	//
-	//  type S struct {
-	//  	*T
-	//  }
-	_InvalidPtrEmbed
-
-	// _BadRecv occurs when a method declaration does not have exactly one
-	// receiver parameter.
-	//
-	// Example:
-	//  func () _() {}
-	_BadRecv
-
-	// _InvalidRecv occurs when a receiver type expression is not of the form T
-	// or *T, or T is a pointer type.
-	//
-	// Example:
-	//  type T struct {}
-	//
-	//  func (**T) m() {}
-	_InvalidRecv
-
-	// _DuplicateFieldAndMethod occurs when an identifier appears as both a field
-	// and method name.
-	//
-	// Example:
-	//  type T struct {
-	//  	m int
-	//  }
-	//
-	//  func (T) m() {}
-	_DuplicateFieldAndMethod
-
-	// _DuplicateMethod occurs when two methods on the same receiver type have
-	// the same name.
-	//
-	// Example:
-	//  type T struct {}
-	//  func (T) m() {}
-	//  func (T) m(i int) int { return i }
-	_DuplicateMethod
-
-	// _InvalidBlank occurs when a blank identifier is used as a value or type.
-	//
-	// Per the spec:
-	//  "The blank identifier may appear as an operand only on the left-hand side
-	//  of an assignment."
-	//
-	// Example:
-	//  var x = _
-	_InvalidBlank
-
-	// _InvalidIota occurs when the predeclared identifier iota is used outside
-	// of a constant declaration.
-	//
-	// Example:
-	//  var x = iota
-	_InvalidIota
-
-	// _MissingInitBody occurs when an init function is missing its body.
-	//
-	// Example:
-	//  func init()
-	_MissingInitBody
-
-	// _InvalidInitSig occurs when an init function declares parameters or
-	// results.
-	//
-	// Deprecated: no longer emitted by the type checker. _InvalidInitDecl is
-	// used instead.
-	_InvalidInitSig
-
-	// _InvalidInitDecl occurs when init is declared as anything other than a
-	// function.
-	//
-	// Example:
-	//  var init = 1
-	//
-	// Example:
-	//  func init() int { return 1 }
-	_InvalidInitDecl
-
-	// _InvalidMainDecl occurs when main is declared as anything other than a
-	// function, in a main package.
-	_InvalidMainDecl
-
-	// _TooManyValues occurs when a function returns too many values for the
-	// expression context in which it is used.
-	//
-	// Example:
-	//  func ReturnTwo() (int, int) {
-	//  	return 1, 2
-	//  }
-	//
-	//  var x = ReturnTwo()
-	_TooManyValues
-
-	// _NotAnExpr occurs when a type expression is used where a value expression
-	// is expected.
-	//
-	// Example:
-	//  type T struct {}
-	//
-	//  func f() {
-	//  	T
-	//  }
-	_NotAnExpr
-
-	// _TruncatedFloat occurs when a float constant is truncated to an integer
-	// value.
-	//
-	// Example:
-	//  var _ int = 98.6
-	_TruncatedFloat
-
-	// _NumericOverflow occurs when a numeric constant overflows its target type.
-	//
-	// Example:
-	//  var x int8 = 1000
-	_NumericOverflow
-
-	// _UndefinedOp occurs when an operator is not defined for the type(s) used
-	// in an operation.
-	//
-	// Example:
-	//  var c = "a" - "b"
-	_UndefinedOp
-
-	// _MismatchedTypes occurs when operand types are incompatible in a binary
-	// operation.
-	//
-	// Example:
-	//  var a = "hello"
-	//  var b = 1
-	//  var c = a - b
-	_MismatchedTypes
-
-	// _DivByZero occurs when a division operation is provable at compile
-	// time to be a division by zero.
-	//
-	// Example:
-	//  const divisor = 0
-	//  var x int = 1/divisor
-	_DivByZero
-
-	// _NonNumericIncDec occurs when an increment or decrement operator is
-	// applied to a non-numeric value.
-	//
-	// Example:
-	//  func f() {
-	//  	var c = "c"
-	//  	c++
-	//  }
-	_NonNumericIncDec
-
-	// _UnaddressableOperand occurs when the & operator is applied to an
-	// unaddressable expression.
-	//
-	// Example:
-	//  var x = &1
-	_UnaddressableOperand
-
-	// _InvalidIndirection occurs when a non-pointer value is indirected via the
-	// '*' operator.
-	//
-	// Example:
-	//  var x int
-	//  var y = *x
-	_InvalidIndirection
-
-	// _NonIndexableOperand occurs when an index operation is applied to a value
-	// that cannot be indexed.
-	//
-	// Example:
-	//  var x = 1
-	//  var y = x[1]
-	_NonIndexableOperand
-
-	// _InvalidIndex occurs when an index argument is not of integer type,
-	// negative, or out-of-bounds.
-	//
-	// Example:
-	//  var s = [...]int{1,2,3}
-	//  var x = s[5]
-	//
-	// Example:
-	//  var s = []int{1,2,3}
-	//  var _ = s[-1]
-	//
-	// Example:
-	//  var s = []int{1,2,3}
-	//  var i string
-	//  var _ = s[i]
-	_InvalidIndex
-
-	// _SwappedSliceIndices occurs when constant indices in a slice expression
-	// are decreasing in value.
-	//
-	// Example:
-	//  var _ = []int{1,2,3}[2:1]
-	_SwappedSliceIndices
-
-	// _NonSliceableOperand occurs when a slice operation is applied to a value
-	// whose type is not sliceable, or is unaddressable.
-	//
-	// Example:
-	//  var x = [...]int{1, 2, 3}[:1]
-	//
-	// Example:
-	//  var x = 1
-	//  var y = 1[:1]
-	_NonSliceableOperand
-
-	// _InvalidSliceExpr occurs when a three-index slice expression (a[x:y:z]) is
-	// applied to a string.
-	//
-	// Example:
-	//  var s = "hello"
-	//  var x = s[1:2:3]
-	_InvalidSliceExpr
-
-	// _InvalidShiftCount occurs when the right-hand side of a shift operation is
-	// either non-integer, negative, or too large.
-	//
-	// Example:
-	//  var (
-	//  	x string
-	//  	y int = 1 << x
-	//  )
-	_InvalidShiftCount
-
-	// _InvalidShiftOperand occurs when the shifted operand is not an integer.
-	//
-	// Example:
-	//  var s = "hello"
-	//  var x = s << 2
-	_InvalidShiftOperand
-
-	// _InvalidReceive occurs when there is a channel receive from a value that
-	// is either not a channel, or is a send-only channel.
-	//
-	// Example:
-	//  func f() {
-	//  	var x = 1
-	//  	<-x
-	//  }
-	_InvalidReceive
-
-	// _InvalidSend occurs when there is a channel send to a value that is not a
-	// channel, or is a receive-only channel.
-	//
-	// Example:
-	//  func f() {
-	//  	var x = 1
-	//  	x <- "hello!"
-	//  }
-	_InvalidSend
-
-	// _DuplicateLitKey occurs when an index is duplicated in a slice, array, or
-	// map literal.
-	//
-	// Example:
-	//  var _ = []int{0:1, 0:2}
-	//
-	// Example:
-	//  var _ = map[string]int{"a": 1, "a": 2}
-	_DuplicateLitKey
-
-	// _MissingLitKey occurs when a map literal is missing a key expression.
-	//
-	// Example:
-	//  var _ = map[string]int{1}
-	_MissingLitKey
-
-	// _InvalidLitIndex occurs when the key in a key-value element of a slice or
-	// array literal is not an integer constant.
-	//
-	// Example:
-	//  var i = 0
-	//  var x = []string{i: "world"}
-	_InvalidLitIndex
-
-	// _OversizeArrayLit occurs when an array literal exceeds its length.
-	//
-	// Example:
-	//  var _ = [2]int{1,2,3}
-	_OversizeArrayLit
-
-	// _MixedStructLit occurs when a struct literal contains a mix of positional
-	// and named elements.
-	//
-	// Example:
-	//  var _ = struct{i, j int}{i: 1, 2}
-	_MixedStructLit
-
-	// _InvalidStructLit occurs when a positional struct literal has an incorrect
-	// number of values.
-	//
-	// Example:
-	//  var _ = struct{i, j int}{1,2,3}
-	_InvalidStructLit
-
-	// _MissingLitField occurs when a struct literal refers to a field that does
-	// not exist on the struct type.
-	//
-	// Example:
-	//  var _ = struct{i int}{j: 2}
-	_MissingLitField
-
-	// _DuplicateLitField occurs when a struct literal contains duplicated
-	// fields.
-	//
-	// Example:
-	//  var _ = struct{i int}{i: 1, i: 2}
-	_DuplicateLitField
-
-	// _UnexportedLitField occurs when a positional struct literal implicitly
-	// assigns an unexported field of an imported type.
-	_UnexportedLitField
-
-	// _InvalidLitField occurs when a field name is not a valid identifier.
-	//
-	// Example:
-	//  var _ = struct{i int}{1: 1}
-	_InvalidLitField
-
-	// _UntypedLit occurs when a composite literal omits a required type
-	// identifier.
-	//
-	// Example:
-	//  type outer struct{
-	//  	inner struct { i int }
-	//  }
-	//
-	//  var _ = outer{inner: {1}}
-	_UntypedLit
-
-	// _InvalidLit occurs when a composite literal expression does not match its
-	// type.
-	//
-	// Example:
-	//  type P *struct{
-	//  	x int
-	//  }
-	//  var _ = P {}
-	_InvalidLit
-
-	// _AmbiguousSelector occurs when a selector is ambiguous.
-	//
-	// Example:
-	//  type E1 struct { i int }
-	//  type E2 struct { i int }
-	//  type T struct { E1; E2 }
-	//
-	//  var x T
-	//  var _ = x.i
-	_AmbiguousSelector
-
-	// _UndeclaredImportedName occurs when a package-qualified identifier is
-	// undeclared by the imported package.
-	//
-	// Example:
-	//  import "go/types"
-	//
-	//  var _ = types.NotAnActualIdentifier
-	_UndeclaredImportedName
-
-	// _UnexportedName occurs when a selector refers to an unexported identifier
-	// of an imported package.
-	//
-	// Example:
-	//  import "reflect"
-	//
-	//  type _ reflect.flag
-	_UnexportedName
-
-	// _UndeclaredName occurs when an identifier is not declared in the current
-	// scope.
-	//
-	// Example:
-	//  var x T
-	_UndeclaredName
-
-	// _MissingFieldOrMethod occurs when a selector references a field or method
-	// that does not exist.
-	//
-	// Example:
-	//  type T struct {}
-	//
-	//  var x = T{}.f
-	_MissingFieldOrMethod
-
-	// _BadDotDotDotSyntax occurs when a "..." occurs in a context where it is
-	// not valid.
-	//
-	// Example:
-	//  var _ = map[int][...]int{0: {}}
-	_BadDotDotDotSyntax
-
-	// _NonVariadicDotDotDot occurs when a "..." is used on the final argument to
-	// a non-variadic function.
-	//
-	// Example:
-	//  func printArgs(s []string) {
-	//  	for _, a := range s {
-	//  		println(a)
-	//  	}
-	//  }
-	//
-	//  func f() {
-	//  	s := []string{"a", "b", "c"}
-	//  	printArgs(s...)
-	//  }
-	_NonVariadicDotDotDot
-
-	// _MisplacedDotDotDot occurs when a "..." is used somewhere other than the
-	// final argument in a function declaration.
-	//
-	// Example:
-	// 	func f(...int, int)
-	_MisplacedDotDotDot
-
-	_ // _InvalidDotDotDotOperand was removed.
-
-	// _InvalidDotDotDot occurs when a "..." is used in a non-variadic built-in
-	// function.
-	//
-	// Example:
-	//  var s = []int{1, 2, 3}
-	//  var l = len(s...)
-	_InvalidDotDotDot
-
-	// _UncalledBuiltin occurs when a built-in function is used as a
-	// function-valued expression, instead of being called.
-	//
-	// Per the spec:
-	//  "The built-in functions do not have standard Go types, so they can only
-	//  appear in call expressions; they cannot be used as function values."
-	//
-	// Example:
-	//  var _ = copy
-	_UncalledBuiltin
-
-	// _InvalidAppend occurs when append is called with a first argument that is
-	// not a slice.
-	//
-	// Example:
-	//  var _ = append(1, 2)
-	_InvalidAppend
-
-	// _InvalidCap occurs when an argument to the cap built-in function is not of
-	// supported type.
-	//
-	// See https://golang.org/ref/spec#Length_and_capacity for information on
-	// which underlying types are supported as arguments to cap and len.
-	//
-	// Example:
-	//  var s = 2
-	//  var x = cap(s)
-	_InvalidCap
-
-	// _InvalidClose occurs when close(...) is called with an argument that is
-	// not of channel type, or that is a receive-only channel.
-	//
-	// Example:
-	//  func f() {
-	//  	var x int
-	//  	close(x)
-	//  }
-	_InvalidClose
-
-	// _InvalidCopy occurs when the arguments are not of slice type or do not
-	// have compatible type.
-	//
-	// See https://golang.org/ref/spec#Appending_and_copying_slices for more
-	// information on the type requirements for the copy built-in.
-	//
-	// Example:
-	//  func f() {
-	//  	var x []int
-	//  	y := []int64{1,2,3}
-	//  	copy(x, y)
-	//  }
-	_InvalidCopy
-
-	// _InvalidComplex occurs when the complex built-in function is called with
-	// arguments with incompatible types.
-	//
-	// Example:
-	//  var _ = complex(float32(1), float64(2))
-	_InvalidComplex
-
-	// _InvalidDelete occurs when the delete built-in function is called with a
-	// first argument that is not a map.
-	//
-	// Example:
-	//  func f() {
-	//  	m := "hello"
-	//  	delete(m, "e")
-	//  }
-	_InvalidDelete
-
-	// _InvalidImag occurs when the imag built-in function is called with an
-	// argument that does not have complex type.
-	//
-	// Example:
-	//  var _ = imag(int(1))
-	_InvalidImag
-
-	// _InvalidLen occurs when an argument to the len built-in function is not of
-	// supported type.
-	//
-	// See https://golang.org/ref/spec#Length_and_capacity for information on
-	// which underlying types are supported as arguments to cap and len.
-	//
-	// Example:
-	//  var s = 2
-	//  var x = len(s)
-	_InvalidLen
-
-	// _SwappedMakeArgs occurs when make is called with three arguments, and its
-	// length argument is larger than its capacity argument.
-	//
-	// Example:
-	//  var x = make([]int, 3, 2)
-	_SwappedMakeArgs
-
-	// _InvalidMake occurs when make is called with an unsupported type argument.
-	//
-	// See https://golang.org/ref/spec#Making_slices_maps_and_channels for
-	// information on the types that may be created using make.
-	//
-	// Example:
-	//  var x = make(int)
-	_InvalidMake
-
-	// _InvalidReal occurs when the real built-in function is called with an
-	// argument that does not have complex type.
-	//
-	// Example:
-	//  var _ = real(int(1))
-	_InvalidReal
-
-	// _InvalidAssert occurs when a type assertion is applied to a
-	// value that is not of interface type.
-	//
-	// Example:
-	//  var x = 1
-	//  var _ = x.(float64)
-	_InvalidAssert
-
-	// _ImpossibleAssert occurs for a type assertion x.(T) when the value x of
-	// interface cannot have dynamic type T, due to a missing or mismatching
-	// method on T.
-	//
-	// Example:
-	//  type T int
-	//
-	//  func (t *T) m() int { return int(*t) }
-	//
-	//  type I interface { m() int }
-	//
-	//  var x I
-	//  var _ = x.(T)
-	_ImpossibleAssert
-
-	// _InvalidConversion occurs when the argument type cannot be converted to the
-	// target.
-	//
-	// See https://golang.org/ref/spec#Conversions for the rules of
-	// convertibility.
-	//
-	// Example:
-	//  var x float64
-	//  var _ = string(x)
-	_InvalidConversion
-
-	// _InvalidUntypedConversion occurs when an there is no valid implicit
-	// conversion from an untyped value satisfying the type constraints of the
-	// context in which it is used.
-	//
-	// Example:
-	//  var _ = 1 + new(int)
-	_InvalidUntypedConversion
-
-	// _BadOffsetofSyntax occurs when unsafe.Offsetof is called with an argument
-	// that is not a selector expression.
-	//
-	// Example:
-	//  import "unsafe"
-	//
-	//  var x int
-	//  var _ = unsafe.Offsetof(x)
-	_BadOffsetofSyntax
-
-	// _InvalidOffsetof occurs when unsafe.Offsetof is called with a method
-	// selector, rather than a field selector, or when the field is embedded via
-	// a pointer.
-	//
-	// Per the spec:
-	//
-	//  "If f is an embedded field, it must be reachable without pointer
-	//  indirections through fields of the struct. "
-	//
-	// Example:
-	//  import "unsafe"
-	//
-	//  type T struct { f int }
-	//  type S struct { *T }
-	//  var s S
-	//  var _ = unsafe.Offsetof(s.f)
-	//
-	// Example:
-	//  import "unsafe"
-	//
-	//  type S struct{}
-	//
-	//  func (S) m() {}
-	//
-	//  var s S
-	//  var _ = unsafe.Offsetof(s.m)
-	_InvalidOffsetof
-
-	// _UnusedExpr occurs when a side-effect free expression is used as a
-	// statement. Such a statement has no effect.
-	//
-	// Example:
-	//  func f(i int) {
-	//  	i*i
-	//  }
-	_UnusedExpr
-
-	// _UnusedVar occurs when a variable is declared but unused.
-	//
-	// Example:
-	//  func f() {
-	//  	x := 1
-	//  }
-	_UnusedVar
-
-	// _MissingReturn occurs when a function with results is missing a return
-	// statement.
-	//
-	// Example:
-	//  func f() int {}
-	_MissingReturn
-
-	// _WrongResultCount occurs when a return statement returns an incorrect
-	// number of values.
-	//
-	// Example:
-	//  func ReturnOne() int {
-	//  	return 1, 2
-	//  }
-	_WrongResultCount
-
-	// _OutOfScopeResult occurs when the name of a value implicitly returned by
-	// an empty return statement is shadowed in a nested scope.
-	//
-	// Example:
-	//  func factor(n int) (i int) {
-	//  	for i := 2; i < n; i++ {
-	//  		if n%i == 0 {
-	//  			return
-	//  		}
-	//  	}
-	//  	return 0
-	//  }
-	_OutOfScopeResult
-
-	// _InvalidCond occurs when an if condition is not a boolean expression.
-	//
-	// Example:
-	//  func checkReturn(i int) {
-	//  	if i {
-	//  		panic("non-zero return")
-	//  	}
-	//  }
-	_InvalidCond
-
-	// _InvalidPostDecl occurs when there is a declaration in a for-loop post
-	// statement.
-	//
-	// Example:
-	//  func f() {
-	//  	for i := 0; i < 10; j := 0 {}
-	//  }
-	_InvalidPostDecl
-
-	_ // _InvalidChanRange was removed.
-
-	// _InvalidIterVar occurs when two iteration variables are used while ranging
-	// over a channel.
-	//
-	// Example:
-	//  func f(c chan int) {
-	//  	for k, v := range c {
-	//  		println(k, v)
-	//  	}
-	//  }
-	_InvalidIterVar
-
-	// _InvalidRangeExpr occurs when the type of a range expression is not array,
-	// slice, string, map, or channel.
-	//
-	// Example:
-	//  func f(i int) {
-	//  	for j := range i {
-	//  		println(j)
-	//  	}
-	//  }
-	_InvalidRangeExpr
-
-	// _MisplacedBreak occurs when a break statement is not within a for, switch,
-	// or select statement of the innermost function definition.
-	//
-	// Example:
-	//  func f() {
-	//  	break
-	//  }
-	_MisplacedBreak
-
-	// _MisplacedContinue occurs when a continue statement is not within a for
-	// loop of the innermost function definition.
-	//
-	// Example:
-	//  func sumeven(n int) int {
-	//  	proceed := func() {
-	//  		continue
-	//  	}
-	//  	sum := 0
-	//  	for i := 1; i <= n; i++ {
-	//  		if i % 2 != 0 {
-	//  			proceed()
-	//  		}
-	//  		sum += i
-	//  	}
-	//  	return sum
-	//  }
-	_MisplacedContinue
-
-	// _MisplacedFallthrough occurs when a fallthrough statement is not within an
-	// expression switch.
-	//
-	// Example:
-	//  func typename(i interface{}) string {
-	//  	switch i.(type) {
-	//  	case int64:
-	//  		fallthrough
-	//  	case int:
-	//  		return "int"
-	//  	}
-	//  	return "unsupported"
-	//  }
-	_MisplacedFallthrough
-
-	// _DuplicateCase occurs when a type or expression switch has duplicate
-	// cases.
-	//
-	// Example:
-	//  func printInt(i int) {
-	//  	switch i {
-	//  	case 1:
-	//  		println("one")
-	//  	case 1:
-	//  		println("One")
-	//  	}
-	//  }
-	_DuplicateCase
-
-	// _DuplicateDefault occurs when a type or expression switch has multiple
-	// default clauses.
-	//
-	// Example:
-	//  func printInt(i int) {
-	//  	switch i {
-	//  	case 1:
-	//  		println("one")
-	//  	default:
-	//  		println("One")
-	//  	default:
-	//  		println("1")
-	//  	}
-	//  }
-	_DuplicateDefault
-
-	// _BadTypeKeyword occurs when a .(type) expression is used anywhere other
-	// than a type switch.
-	//
-	// Example:
-	//  type I interface {
-	//  	m()
-	//  }
-	//  var t I
-	//  var _ = t.(type)
-	_BadTypeKeyword
-
-	// _InvalidTypeSwitch occurs when .(type) is used on an expression that is
-	// not of interface type.
-	//
-	// Example:
-	//  func f(i int) {
-	//  	switch x := i.(type) {}
-	//  }
-	_InvalidTypeSwitch
-
-	// _InvalidExprSwitch occurs when a switch expression is not comparable.
-	//
-	// Example:
-	//  func _() {
-	//  	var a struct{ _ func() }
-	//  	switch a /* ERROR cannot switch on a */ {
-	//  	}
-	//  }
-	_InvalidExprSwitch
-
-	// _InvalidSelectCase occurs when a select case is not a channel send or
-	// receive.
-	//
-	// Example:
-	//  func checkChan(c <-chan int) bool {
-	//  	select {
-	//  	case c:
-	//  		return true
-	//  	default:
-	//  		return false
-	//  	}
-	//  }
-	_InvalidSelectCase
-
-	// _UndeclaredLabel occurs when an undeclared label is jumped to.
-	//
-	// Example:
-	//  func f() {
-	//  	goto L
-	//  }
-	_UndeclaredLabel
-
-	// _DuplicateLabel occurs when a label is declared more than once.
-	//
-	// Example:
-	//  func f() int {
-	//  L:
-	//  L:
-	//  	return 1
-	//  }
-	_DuplicateLabel
-
-	// _MisplacedLabel occurs when a break or continue label is not on a for,
-	// switch, or select statement.
-	//
-	// Example:
-	//  func f() {
-	//  L:
-	//  	a := []int{1,2,3}
-	//  	for _, e := range a {
-	//  		if e > 10 {
-	//  			break L
-	//  		}
-	//  		println(a)
-	//  	}
-	//  }
-	_MisplacedLabel
-
-	// _UnusedLabel occurs when a label is declared but not used.
-	//
-	// Example:
-	//  func f() {
-	//  L:
-	//  }
-	_UnusedLabel
-
-	// _JumpOverDecl occurs when a label jumps over a variable declaration.
-	//
-	// Example:
-	//  func f() int {
-	//  	goto L
-	//  	x := 2
-	//  L:
-	//  	x++
-	//  	return x
-	//  }
-	_JumpOverDecl
-
-	// _JumpIntoBlock occurs when a forward jump goes to a label inside a nested
-	// block.
-	//
-	// Example:
-	//  func f(x int) {
-	//  	goto L
-	//  	if x > 0 {
-	//  	L:
-	//  		print("inside block")
-	//  	}
-	// }
-	_JumpIntoBlock
-
-	// _InvalidMethodExpr occurs when a pointer method is called but the argument
-	// is not addressable.
-	//
-	// Example:
-	//  type T struct {}
-	//
-	//  func (*T) m() int { return 1 }
-	//
-	//  var _ = T.m(T{})
-	_InvalidMethodExpr
-
-	// _WrongArgCount occurs when too few or too many arguments are passed by a
-	// function call.
-	//
-	// Example:
-	//  func f(i int) {}
-	//  var x = f()
-	_WrongArgCount
-
-	// _InvalidCall occurs when an expression is called that is not of function
-	// type.
-	//
-	// Example:
-	//  var x = "x"
-	//  var y = x()
-	_InvalidCall
-
-	// _UnusedResults occurs when a restricted expression-only built-in function
-	// is suspended via go or defer. Such a suspension discards the results of
-	// these side-effect free built-in functions, and therefore is ineffectual.
-	//
-	// Example:
-	//  func f(a []int) int {
-	//  	defer len(a)
-	//  	return i
-	//  }
-	_UnusedResults
-
-	// _InvalidDefer occurs when a deferred expression is not a function call,
-	// for example if the expression is a type conversion.
-	//
-	// Example:
-	//  func f(i int) int {
-	//  	defer int32(i)
-	//  	return i
-	//  }
-	_InvalidDefer
-
-	// _InvalidGo occurs when a go expression is not a function call, for example
-	// if the expression is a type conversion.
-	//
-	// Example:
-	//  func f(i int) int {
-	//  	go int32(i)
-	//  	return i
-	//  }
-	_InvalidGo
-
-	// All codes below were added in Go 1.17.
-
-	// _BadDecl occurs when a declaration has invalid syntax.
-	_BadDecl
-
-	// _RepeatedDecl occurs when an identifier occurs more than once on the left
-	// hand side of a short variable declaration.
-	//
-	// Example:
-	//  func _() {
-	//  	x, y, y := 1, 2, 3
-	//  }
-	_RepeatedDecl
-
-	// _InvalidUnsafeAdd occurs when unsafe.Add is called with a
-	// length argument that is not of integer type.
-	//
-	// Example:
-	//  import "unsafe"
-	//
-	//  var p unsafe.Pointer
-	//  var _ = unsafe.Add(p, float64(1))
-	_InvalidUnsafeAdd
-
-	// _InvalidUnsafeSlice occurs when unsafe.Slice is called with a
-	// pointer argument that is not of pointer type or a length argument
-	// that is not of integer type, negative, or out of bounds.
-	//
-	// Example:
-	//  import "unsafe"
-	//
-	//  var x int
-	//  var _ = unsafe.Slice(x, 1)
-	//
-	// Example:
-	//  import "unsafe"
-	//
-	//  var x int
-	//  var _ = unsafe.Slice(&x, float64(1))
-	//
-	// Example:
-	//  import "unsafe"
-	//
-	//  var x int
-	//  var _ = unsafe.Slice(&x, -1)
-	//
-	// Example:
-	//  import "unsafe"
-	//
-	//  var x int
-	//  var _ = unsafe.Slice(&x, uint64(1) << 63)
-	_InvalidUnsafeSlice
-
-	// All codes below were added in Go 1.18.
-
-	// _UnsupportedFeature occurs when a language feature is used that is not
-	// supported at this Go version.
-	_UnsupportedFeature
-
-	// _NotAGenericType occurs when a non-generic type is used where a generic
-	// type is expected: in type or function instantiation.
-	//
-	// Example:
-	//  type T int
-	//
-	//  var _ T[int]
-	_NotAGenericType
-
-	// _WrongTypeArgCount occurs when a type or function is instantiated with an
-	// incorrent number of type arguments, including when a generic type or
-	// function is used without instantiation.
-	//
-	// Errors inolving failed type inference are assigned other error codes.
-	//
-	// Example:
-	//  type T[p any] int
-	//
-	//  var _ T[int, string]
-	//
-	// Example:
-	//  func f[T any]() {}
-	//
-	//  var x = f
-	_WrongTypeArgCount
-
-	// _CannotInferTypeArgs occurs when type or function type argument inference
-	// fails to infer all type arguments.
-	//
-	// Example:
-	//  func f[T any]() {}
-	//
-	//  func _() {
-	//  	f()
-	//  }
-	_CannotInferTypeArgs
-
-	// _InvalidTypeArg occurs when a type argument does not satisfy its
-	// corresponding type parameter constraints.
-	//
-	// Example:
-	//  type T[P ~int] struct{}
-	//
-	//  var _ T[string]
-	_InvalidTypeArg // arguments? InferenceFailed
-
-	// _InvalidInstanceCycle occurs when an invalid cycle is detected
-	// within the instantiation graph.
-	//
-	// Example:
-	//  func f[T any]() { f[*T]() }
-	_InvalidInstanceCycle
-
-	// _InvalidUnion occurs when an embedded union or approximation element is
-	// not valid.
-	//
-	// Example:
-	//  type _ interface {
-	//   	~int | interface{ m() }
-	//  }
-	_InvalidUnion
-
-	// _MisplacedConstraintIface occurs when a constraint-type interface is used
-	// outside of constraint position.
-	//
-	// Example:
-	//   type I interface { ~int }
-	//
-	//   var _ I
-	_MisplacedConstraintIface
-
-	// _InvalidMethodTypeParams occurs when methods have type parameters.
-	//
-	// It cannot be encountered with an AST parsed using go/parser.
-	_InvalidMethodTypeParams
-
-	// _MisplacedTypeParam occurs when a type parameter is used in a place where
-	// it is not permitted.
-	//
-	// Example:
-	//  type T[P any] P
-	//
-	// Example:
-	//  type T[P any] struct{ *P }
-	_MisplacedTypeParam
-)
diff --git a/src/go/types/errorcodes_test.go b/src/go/types/errorcodes_test.go
deleted file mode 100644
index 629eac4..0000000
--- a/src/go/types/errorcodes_test.go
+++ /dev/null
@@ -1,199 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package types_test
-
-import (
-	"fmt"
-	"go/ast"
-	"go/constant"
-	"go/importer"
-	"go/parser"
-	"go/token"
-	"reflect"
-	"strings"
-	"testing"
-
-	. "go/types"
-)
-
-func TestErrorCodeExamples(t *testing.T) {
-	walkCodes(t, func(name string, value int, spec *ast.ValueSpec) {
-		t.Run(name, func(t *testing.T) {
-			doc := spec.Doc.Text()
-			examples := strings.Split(doc, "Example:")
-			for i := 1; i < len(examples); i++ {
-				example := examples[i]
-				err := checkExample(t, example)
-				if err == nil {
-					t.Fatalf("no error in example #%d", i)
-				}
-				typerr, ok := err.(Error)
-				if !ok {
-					t.Fatalf("not a types.Error: %v", err)
-				}
-				if got := readCode(typerr); got != value {
-					t.Errorf("%s: example #%d returned code %d (%s), want %d", name, i, got, err, value)
-				}
-			}
-		})
-	})
-}
-
-func walkCodes(t *testing.T, f func(string, int, *ast.ValueSpec)) {
-	t.Helper()
-	fset := token.NewFileSet()
-	files, err := pkgFiles(fset, ".", parser.ParseComments) // from self_test.go
-	if err != nil {
-		t.Fatal(err)
-	}
-	conf := Config{Importer: importer.Default()}
-	info := &Info{
-		Types: make(map[ast.Expr]TypeAndValue),
-		Defs:  make(map[*ast.Ident]Object),
-		Uses:  make(map[*ast.Ident]Object),
-	}
-	_, err = conf.Check("types", fset, files, info)
-	if err != nil {
-		t.Fatal(err)
-	}
-	for _, file := range files {
-		for _, decl := range file.Decls {
-			decl, ok := decl.(*ast.GenDecl)
-			if !ok || decl.Tok != token.CONST {
-				continue
-			}
-			for _, spec := range decl.Specs {
-				spec, ok := spec.(*ast.ValueSpec)
-				if !ok || len(spec.Names) == 0 {
-					continue
-				}
-				obj := info.ObjectOf(spec.Names[0])
-				if named, ok := obj.Type().(*Named); ok && named.Obj().Name() == "errorCode" {
-					if len(spec.Names) != 1 {
-						t.Fatalf("bad Code declaration for %q: got %d names, want exactly 1", spec.Names[0].Name, len(spec.Names))
-					}
-					codename := spec.Names[0].Name
-					value := int(constant.Val(obj.(*Const).Val()).(int64))
-					f(codename, value, spec)
-				}
-			}
-		}
-	}
-}
-
-func readCode(err Error) int {
-	v := reflect.ValueOf(err)
-	return int(v.FieldByName("go116code").Int())
-}
-
-func checkExample(t *testing.T, example string) error {
-	t.Helper()
-	fset := token.NewFileSet()
-	src := fmt.Sprintf("package p\n\n%s", example)
-	file, err := parser.ParseFile(fset, "example.go", src, 0)
-	if err != nil {
-		t.Fatal(err)
-	}
-	conf := Config{
-		FakeImportC: true,
-		Importer:    importer.Default(),
-	}
-	_, err = conf.Check("example", fset, []*ast.File{file}, nil)
-	return err
-}
-
-func TestErrorCodeStyle(t *testing.T) {
-	// The set of error codes is large and intended to be self-documenting, so
-	// this test enforces some style conventions.
-	forbiddenInIdent := []string{
-		// use invalid instead
-		"illegal",
-		// words with a common short-form
-		"argument",
-		"assertion",
-		"assignment",
-		"boolean",
-		"channel",
-		"condition",
-		"declaration",
-		"expression",
-		"function",
-		"initial", // use init for initializer, initialization, etc.
-		"integer",
-		"interface",
-		"iterat", // use iter for iterator, iteration, etc.
-		"literal",
-		"operation",
-		"package",
-		"pointer",
-		"receiver",
-		"signature",
-		"statement",
-		"variable",
-	}
-	forbiddenInComment := []string{
-		// lhs and rhs should be spelled-out.
-		"lhs", "rhs",
-		// builtin should be hyphenated.
-		"builtin",
-		// Use dot-dot-dot.
-		"ellipsis",
-	}
-	nameHist := make(map[int]int)
-	longestName := ""
-	maxValue := 0
-
-	walkCodes(t, func(name string, value int, spec *ast.ValueSpec) {
-		if name == "_" {
-			return
-		}
-		nameHist[len(name)]++
-		if value > maxValue {
-			maxValue = value
-		}
-		if len(name) > len(longestName) {
-			longestName = name
-		}
-		if token.IsExported(name) {
-			// This is an experimental API, and errorCode values should not be
-			// exported.
-			t.Errorf("%q is exported", name)
-		}
-		if name[0] != '_' || !token.IsExported(name[1:]) {
-			t.Errorf("%q should start with _, followed by an exported identifier", name)
-		}
-		lower := strings.ToLower(name)
-		for _, bad := range forbiddenInIdent {
-			if strings.Contains(lower, bad) {
-				t.Errorf("%q contains forbidden word %q", name, bad)
-			}
-		}
-		doc := spec.Doc.Text()
-		if doc == "" {
-			t.Errorf("%q is undocumented", name)
-		} else if !strings.HasPrefix(doc, name) {
-			t.Errorf("doc for %q does not start with the error code name", name)
-		}
-		lowerComment := strings.ToLower(strings.TrimPrefix(doc, name))
-		for _, bad := range forbiddenInComment {
-			if strings.Contains(lowerComment, bad) {
-				t.Errorf("doc for %q contains forbidden word %q", name, bad)
-			}
-		}
-	})
-
-	if testing.Verbose() {
-		var totChars, totCount int
-		for chars, count := range nameHist {
-			totChars += chars * count
-			totCount += count
-		}
-		avg := float64(totChars) / float64(totCount)
-		fmt.Println()
-		fmt.Printf("%d error codes\n", totCount)
-		fmt.Printf("average length: %.2f chars\n", avg)
-		fmt.Printf("max length: %d (%s)\n", len(longestName), longestName)
-	}
-}
diff --git a/src/go/types/errors.go b/src/go/types/errors.go
index 964f377..b52019d 100644
--- a/src/go/types/errors.go
+++ b/src/go/types/errors.go
@@ -11,6 +11,7 @@
 	"fmt"
 	"go/ast"
 	"go/token"
+	. "internal/types/errors"
 	"runtime"
 	"strconv"
 	"strings"
@@ -36,7 +37,7 @@
 // To report an error_, call Checker.report.
 type error_ struct {
 	desc []errorDesc
-	code errorCode
+	code Code
 	soft bool // TODO(gri) eventually determine this from an error code
 }
 
@@ -62,7 +63,7 @@
 	if err.empty() {
 		return "no error"
 	}
-	var buf bytes.Buffer
+	var buf strings.Builder
 	for i := range err.desc {
 		p := &err.desc[i]
 		if i > 0 {
@@ -138,7 +139,7 @@
 	return sprintf(fset, qf, false, format, args...)
 }
 
-func sprintf(fset *token.FileSet, qf Qualifier, debug bool, format string, args ...any) string {
+func sprintf(fset *token.FileSet, qf Qualifier, tpSubscripts bool, format string, args ...any) string {
 	for i, arg := range args {
 		switch a := arg.(type) {
 		case nil:
@@ -162,26 +163,34 @@
 		case Object:
 			arg = ObjectString(a, qf)
 		case Type:
-			arg = typeString(a, qf, debug)
+			var buf bytes.Buffer
+			w := newTypeWriter(&buf, qf)
+			w.tpSubscripts = tpSubscripts
+			w.typ(a)
+			arg = buf.String()
 		case []Type:
 			var buf bytes.Buffer
+			w := newTypeWriter(&buf, qf)
+			w.tpSubscripts = tpSubscripts
 			buf.WriteByte('[')
 			for i, x := range a {
 				if i > 0 {
 					buf.WriteString(", ")
 				}
-				buf.WriteString(typeString(x, qf, debug))
+				w.typ(x)
 			}
 			buf.WriteByte(']')
 			arg = buf.String()
 		case []*TypeParam:
 			var buf bytes.Buffer
+			w := newTypeWriter(&buf, qf)
+			w.tpSubscripts = tpSubscripts
 			buf.WriteByte('[')
 			for i, x := range a {
 				if i > 0 {
 					buf.WriteString(", ")
 				}
-				buf.WriteString(typeString(x, qf, debug)) // use typeString so we get subscripts when debugging
+				w.typ(x)
 			}
 			buf.WriteByte(']')
 			arg = buf.String()
@@ -211,11 +220,19 @@
 		panic("empty error details")
 	}
 
+	msg := errp.msg(check.fset, check.qualifier)
+	switch errp.code {
+	case InvalidSyntaxTree:
+		msg = "invalid AST: " + msg
+	case 0:
+		panic("no error code provided")
+	}
+
 	span := spanOf(errp.desc[0].posn)
 	e := Error{
 		Fset:       check.fset,
 		Pos:        span.pos,
-		Msg:        errp.msg(check.fset, check.qualifier),
+		Msg:        msg,
 		Soft:       errp.soft,
 		go116code:  errp.code,
 		go116start: span.start,
@@ -262,51 +279,40 @@
 	f(err)
 }
 
+const (
+	invalidArg = "invalid argument: "
+	invalidOp  = "invalid operation: "
+)
+
 // newErrorf creates a new error_ for later reporting with check.report.
-func newErrorf(at positioner, code errorCode, format string, args ...any) *error_ {
+func newErrorf(at positioner, code Code, format string, args ...any) *error_ {
 	return &error_{
 		desc: []errorDesc{{at, format, args}},
 		code: code,
 	}
 }
 
-func (check *Checker) error(at positioner, code errorCode, msg string) {
+func (check *Checker) error(at positioner, code Code, msg string) {
 	check.report(newErrorf(at, code, msg))
 }
 
-func (check *Checker) errorf(at positioner, code errorCode, format string, args ...any) {
+func (check *Checker) errorf(at positioner, code Code, format string, args ...any) {
 	check.report(newErrorf(at, code, format, args...))
 }
 
-func (check *Checker) softErrorf(at positioner, code errorCode, format string, args ...any) {
+func (check *Checker) softErrorf(at positioner, code Code, format string, args ...any) {
 	err := newErrorf(at, code, format, args...)
 	err.soft = true
 	check.report(err)
 }
 
-func (check *Checker) versionErrorf(at positioner, code errorCode, goVersion string, format string, args ...interface{}) {
+func (check *Checker) versionErrorf(at positioner, goVersion string, format string, args ...interface{}) {
 	msg := check.sprintf(format, args...)
 	var err *error_
-	if compilerErrorMessages {
-		err = newErrorf(at, code, "%s requires %s or later (-lang was set to %s; check go.mod)", msg, goVersion, check.conf.GoVersion)
-	} else {
-		err = newErrorf(at, code, "%s requires %s or later", msg, goVersion)
-	}
+	err = newErrorf(at, UnsupportedFeature, "%s requires %s or later", msg, goVersion)
 	check.report(err)
 }
 
-func (check *Checker) invalidAST(at positioner, format string, args ...any) {
-	check.errorf(at, 0, "invalid AST: "+format, args...)
-}
-
-func (check *Checker) invalidArg(at positioner, code errorCode, format string, args ...any) {
-	check.errorf(at, code, "invalid argument: "+format, args...)
-}
-
-func (check *Checker) invalidOp(at positioner, code errorCode, format string, args ...any) {
-	check.errorf(at, code, "invalid operation: "+format, args...)
-}
-
 // The positioner interface is used to extract the position of type-checker
 // errors.
 type positioner interface {
@@ -370,15 +376,15 @@
 
 // stripAnnotations removes internal (type) annotations from s.
 func stripAnnotations(s string) string {
-	var b strings.Builder
+	var buf strings.Builder
 	for _, r := range s {
 		// strip #'s and subscript digits
 		if r < '₀' || '₀'+10 <= r { // '₀' == U+2080
-			b.WriteRune(r)
+			buf.WriteRune(r)
 		}
 	}
-	if b.Len() < len(s) {
-		return b.String()
+	if buf.Len() < len(s) {
+		return buf.String()
 	}
 	return s
 }
diff --git a/src/go/types/eval_test.go b/src/go/types/eval_test.go
index 6f5b548..b0745c1 100644
--- a/src/go/types/eval_test.go
+++ b/src/go/types/eval_test.go
@@ -12,7 +12,6 @@
 	"go/importer"
 	"go/parser"
 	"go/token"
-	"internal/goexperiment"
 	"internal/testenv"
 	"strings"
 	"testing"
@@ -209,7 +208,7 @@
 	// expr is an identifier or selector expression that is passed
 	// to CheckExpr at the position of the comment, and object is
 	// the string form of the object it denotes.
-	src := `
+	const src = `
 package p
 
 import "fmt"
@@ -236,13 +235,6 @@
 	return S{}
 }`
 
-	// The unified IR importer always sets interface method receiver
-	// parameters to point to the Interface type, rather than the Named.
-	// See #49906.
-	if goexperiment.Unified {
-		src = strings.ReplaceAll(src, "func (fmt.Stringer).", "func (interface).")
-	}
-
 	fset := token.NewFileSet()
 	f, err := parser.ParseFile(fset, "p", src, parser.ParseComments)
 	if err != nil {
diff --git a/src/go/types/example_test.go b/src/go/types/example_test.go
index 3c1bdb5..605e987 100644
--- a/src/go/types/example_test.go
+++ b/src/go/types/example_test.go
@@ -5,7 +5,7 @@
 // Only run where builders (build.golang.org) have
 // access to compiled packages for import.
 //
-//go:build !arm && !arm64
+//go:build !android && !ios && !js
 
 package types_test
 
@@ -16,7 +16,6 @@
 // from source, use golang.org/x/tools/go/loader.
 
 import (
-	"bytes"
 	"fmt"
 	"go/ast"
 	"go/format"
@@ -54,11 +53,7 @@
 func Unused() { {}; {{ var x int; _ = x }} } // make sure empty block scopes get printed
 `},
 	} {
-		f, err := parser.ParseFile(fset, file.name, file.input, 0)
-		if err != nil {
-			log.Fatal(err)
-		}
-		files = append(files, f)
+		files = append(files, mustParse(fset, file.name, file.input))
 	}
 
 	// Type-check a package consisting of these files.
@@ -72,9 +67,9 @@
 
 	// Print the tree of scopes.
 	// For determinism, we redact addresses.
-	var buf bytes.Buffer
+	var buf strings.Builder
 	pkg.Scope().WriteTo(&buf, 0, true)
-	rx := regexp.MustCompile(` 0x[a-fA-F0-9]*`)
+	rx := regexp.MustCompile(` 0x[a-fA-F\d]*`)
 	fmt.Println(rx.ReplaceAllString(buf.String(), ""))
 
 	// Output:
@@ -186,10 +181,7 @@
 	return fib(x-1) - fib(x-2)
 }`
 	fset := token.NewFileSet()
-	f, err := parser.ParseFile(fset, "fib.go", input, 0)
-	if err != nil {
-		log.Fatal(err)
-	}
+	f := mustParse(fset, "fib.go", input)
 
 	// Type-check the package.
 	// We create an empty map for each kind of input
@@ -233,7 +225,7 @@
 	fmt.Println("Types and Values of each expression:")
 	items = nil
 	for expr, tv := range info.Types {
-		var buf bytes.Buffer
+		var buf strings.Builder
 		posn := fset.Position(expr.Pos())
 		tvstr := tv.Type.String()
 		if tv.Value != nil {
@@ -328,7 +320,7 @@
 }
 
 func exprString(fset *token.FileSet, expr ast.Expr) string {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	format.Node(&buf, fset, expr)
 	return buf.String()
 }
diff --git a/src/go/types/expr.go b/src/go/types/expr.go
index 0e8dca3..aa90145 100644
--- a/src/go/types/expr.go
+++ b/src/go/types/expr.go
@@ -12,6 +12,7 @@
 	"go/constant"
 	"go/internal/typeparams"
 	"go/token"
+	. "internal/types/errors"
 	"math"
 )
 
@@ -74,11 +75,11 @@
 func (check *Checker) op(m opPredicates, x *operand, op token.Token) bool {
 	if pred := m[op]; pred != nil {
 		if !pred(x.typ) {
-			check.invalidOp(x, _UndefinedOp, "operator %s not defined on %s", op, x)
+			check.errorf(x, UndefinedOp, invalidOp+"operator %s not defined on %s", op, x)
 			return false
 		}
 	} else {
-		check.invalidAST(x, "unknown operator %s", op)
+		check.errorf(x, InvalidSyntaxTree, "unknown operator %s", op)
 		return false
 	}
 	return true
@@ -94,7 +95,7 @@
 		// TODO(gri) We should report exactly what went wrong. At the
 		//           moment we don't have the (go/constant) API for that.
 		//           See also TODO in go/constant/value.go.
-		check.errorf(atPos(opPos), _InvalidConstVal, "constant result is not representable")
+		check.error(atPos(opPos), InvalidConstVal, "constant result is not representable")
 		return
 	}
 
@@ -110,7 +111,11 @@
 	// Untyped integer values must not grow arbitrarily.
 	const prec = 512 // 512 is the constant precision
 	if x.val.Kind() == constant.Int && constant.BitLen(x.val) > prec {
-		check.errorf(atPos(opPos), _InvalidConstVal, "constant %s overflow", opName(x.expr))
+		op := opName(x.expr)
+		if op != "" {
+			op += " "
+		}
+		check.errorf(atPos(opPos), InvalidConstVal, "constant %soverflow", op)
 		x.val = constant.MakeUnknown()
 	}
 }
@@ -164,7 +169,7 @@
 		// spec: "As an exception to the addressability
 		// requirement x may also be a composite literal."
 		if _, ok := unparen(e.X).(*ast.CompositeLit); !ok && x.mode != variable {
-			check.invalidOp(x, _UnaddressableOperand, "cannot take address of %s", x)
+			check.errorf(x, UnaddressableOperand, invalidOp+"cannot take address of %s", x)
 			x.mode = invalid
 			return
 		}
@@ -175,18 +180,18 @@
 	case token.ARROW:
 		u := coreType(x.typ)
 		if u == nil {
-			check.invalidOp(x, _InvalidReceive, "cannot receive from %s: no core type", x)
+			check.errorf(x, InvalidReceive, invalidOp+"cannot receive from %s (no core type)", x)
 			x.mode = invalid
 			return
 		}
 		ch, _ := u.(*Chan)
 		if ch == nil {
-			check.invalidOp(x, _InvalidReceive, "cannot receive from non-channel %s", x)
+			check.errorf(x, InvalidReceive, invalidOp+"cannot receive from non-channel %s", x)
 			x.mode = invalid
 			return
 		}
 		if ch.dir == SendOnly {
-			check.invalidOp(x, _InvalidReceive, "cannot receive from send-only channel %s", x)
+			check.errorf(x, InvalidReceive, invalidOp+"cannot receive from send-only channel %s", x)
 			x.mode = invalid
 			return
 		}
@@ -198,7 +203,7 @@
 
 	case token.TILDE:
 		// Provide a better error position and message than what check.op below could do.
-		check.error(e, _UndefinedOp, "cannot use ~ outside of interface or type constraint")
+		check.error(e, UndefinedOp, "cannot use ~ outside of interface or type constraint")
 		x.mode = invalid
 		return
 	}
@@ -435,7 +440,7 @@
 // basic type typ.
 //
 // If no such representation is possible, it returns a non-zero error code.
-func (check *Checker) representation(x *operand, typ *Basic) (constant.Value, errorCode) {
+func (check *Checker) representation(x *operand, typ *Basic) (constant.Value, Code) {
 	assert(x.mode == constant_)
 	v := x.val
 	if !representableConst(x.val, check, typ, &v) {
@@ -448,22 +453,22 @@
 			// float   -> float   : overflows
 			//
 			if !isInteger(x.typ) && isInteger(typ) {
-				return nil, _TruncatedFloat
+				return nil, TruncatedFloat
 			} else {
-				return nil, _NumericOverflow
+				return nil, NumericOverflow
 			}
 		}
-		return nil, _InvalidConstVal
+		return nil, InvalidConstVal
 	}
 	return v, 0
 }
 
-func (check *Checker) invalidConversion(code errorCode, x *operand, target Type) {
-	msg := "cannot convert %s to %s"
+func (check *Checker) invalidConversion(code Code, x *operand, target Type) {
+	msg := "cannot convert %s to type %s"
 	switch code {
-	case _TruncatedFloat:
+	case TruncatedFloat:
 		msg = "%s truncated to %s"
-	case _NumericOverflow:
+	case NumericOverflow:
 		msg = "%s overflows %s"
 	}
 	check.errorf(x, code, msg, x, target)
@@ -575,11 +580,7 @@
 		// We already know from the shift check that it is representable
 		// as an integer if it is a constant.
 		if !allInteger(typ) {
-			if compilerErrorMessages {
-				check.invalidOp(x, _InvalidShiftOperand, "%s (shift of type %s)", parent, typ)
-			} else {
-				check.invalidOp(x, _InvalidShiftOperand, "shifted operand %s (type %s) must be integer", x, typ)
-			}
+			check.errorf(x, InvalidShiftOperand, invalidOp+"shifted operand %s (type %s) must be integer", x, typ)
 			return
 		}
 		// Even if we have an integer, if the value is a constant we
@@ -635,7 +636,7 @@
 //
 // If x is a constant operand, the returned constant.Value will be the
 // representation of x in this context.
-func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, constant.Value, errorCode) {
+func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, constant.Value, Code) {
 	if x.mode == invalid || isTyped(x.typ) || target == Typ[Invalid] {
 		return x.typ, nil, 0
 	}
@@ -649,7 +650,7 @@
 				return target, nil, 0
 			}
 		} else if xkind != tkind {
-			return nil, nil, _InvalidUntypedConversion
+			return nil, nil, InvalidUntypedConversion
 		}
 		return x.typ, nil, 0
 	}
@@ -670,28 +671,28 @@
 		switch x.typ.(*Basic).kind {
 		case UntypedBool:
 			if !isBoolean(target) {
-				return nil, nil, _InvalidUntypedConversion
+				return nil, nil, InvalidUntypedConversion
 			}
 		case UntypedInt, UntypedRune, UntypedFloat, UntypedComplex:
 			if !isNumeric(target) {
-				return nil, nil, _InvalidUntypedConversion
+				return nil, nil, InvalidUntypedConversion
 			}
 		case UntypedString:
 			// Non-constant untyped string values are not permitted by the spec and
 			// should not occur during normal typechecking passes, but this path is
 			// reachable via the AssignableTo API.
 			if !isString(target) {
-				return nil, nil, _InvalidUntypedConversion
+				return nil, nil, InvalidUntypedConversion
 			}
 		case UntypedNil:
 			// Unsafe.Pointer is a basic type that includes nil.
 			if !hasNil(target) {
-				return nil, nil, _InvalidUntypedConversion
+				return nil, nil, InvalidUntypedConversion
 			}
 			// Preserve the type of nil as UntypedNil: see #13061.
 			return Typ[UntypedNil], nil, 0
 		default:
-			return nil, nil, _InvalidUntypedConversion
+			return nil, nil, InvalidUntypedConversion
 		}
 	case *Interface:
 		if isTypeParam(target) {
@@ -702,7 +703,7 @@
 				t, _, _ := check.implicitTypeAndValue(x, u)
 				return t != nil
 			}) {
-				return nil, nil, _InvalidUntypedConversion
+				return nil, nil, InvalidUntypedConversion
 			}
 			// keep nil untyped (was bug #39755)
 			if x.isNil() {
@@ -719,23 +720,29 @@
 		}
 		// cannot assign untyped values to non-empty interfaces
 		if !u.Empty() {
-			return nil, nil, _InvalidUntypedConversion
+			return nil, nil, InvalidUntypedConversion
 		}
 		return Default(x.typ), nil, 0
 	case *Pointer, *Signature, *Slice, *Map, *Chan:
 		if !x.isNil() {
-			return nil, nil, _InvalidUntypedConversion
+			return nil, nil, InvalidUntypedConversion
 		}
 		// Keep nil untyped - see comment for interfaces, above.
 		return Typ[UntypedNil], nil, 0
 	default:
-		return nil, nil, _InvalidUntypedConversion
+		return nil, nil, InvalidUntypedConversion
 	}
 	return target, nil, 0
 }
 
 // If switchCase is true, the operator op is ignored.
 func (check *Checker) comparison(x, y *operand, op token.Token, switchCase bool) {
+	// Avoid spurious errors if any of the operands has an invalid type (issue #54405).
+	if x.typ == Typ[Invalid] || y.typ == Typ[Invalid] {
+		x.mode = invalid
+		return
+	}
+
 	if switchCase {
 		op = token.EQL
 	}
@@ -745,7 +752,7 @@
 
 	// spec: "In any comparison, the first operand must be assignable
 	// to the type of the second operand, or vice versa."
-	code := _MismatchedTypes
+	code := MismatchedTypes
 	ok, _ := x.assignableTo(check, y.typ, nil)
 	if !ok {
 		ok, _ = y.assignableTo(check, x.typ, nil)
@@ -755,17 +762,12 @@
 		// know after seeing the 2nd operand whether we have
 		// a type mismatch.
 		errOp = y
-		// For now, if we're not running the compiler, use the
-		// position of x to minimize changes to existing tests.
-		if !compilerErrorMessages {
-			errOp = x
-		}
 		cause = check.sprintf("mismatched types %s and %s", x.typ, y.typ)
 		goto Error
 	}
 
 	// check if comparison is defined for operands
-	code = _UndefinedOp
+	code = UndefinedOp
 	switch op {
 	case token.EQL, token.NEQ:
 		// spec: "The equality operators == and != apply to operands that are comparable."
@@ -847,11 +849,7 @@
 	if switchCase {
 		check.errorf(x, code, "invalid case %s in switch on %s (%s)", x.expr, y.expr, cause) // error position always at 1st operand
 	} else {
-		if compilerErrorMessages {
-			check.invalidOp(errOp, code, "%s %s %s (%s)", x.expr, op, y.expr, cause)
-		} else {
-			check.invalidOp(errOp, code, "cannot compare %s %s %s (%s)", x.expr, op, y.expr, cause)
-		}
+		check.errorf(errOp, code, invalidOp+"%s %s %s (%s)", x.expr, op, y.expr, cause)
 	}
 	x.mode = invalid
 }
@@ -912,7 +910,7 @@
 		// as an integer. Nothing to do.
 	} else {
 		// shift has no chance
-		check.invalidOp(x, _InvalidShiftOperand, "shifted operand %s must be integer", x)
+		check.errorf(x, InvalidShiftOperand, invalidOp+"shifted operand %s must be integer", x)
 		x.mode = invalid
 		return
 	}
@@ -922,11 +920,12 @@
 
 	// Check that constants are representable by uint, but do not convert them
 	// (see also issue #47243).
+	var yval constant.Value
 	if y.mode == constant_ {
 		// Provide a good error message for negative shift counts.
-		yval := constant.ToInt(y.val) // consider -1, 1.0, but not -1.1
+		yval = constant.ToInt(y.val) // consider -1, 1.0, but not -1.1
 		if yval.Kind() == constant.Int && constant.Sign(yval) < 0 {
-			check.invalidOp(y, _InvalidShiftCount, "negative shift count %s", y)
+			check.errorf(y, InvalidShiftCount, invalidOp+"negative shift count %s", y)
 			x.mode = invalid
 			return
 		}
@@ -945,7 +944,7 @@
 		switch {
 		case allInteger(y.typ):
 			if !allUnsigned(y.typ) && !check.allowVersion(check.pkg, 1, 13) {
-				check.invalidOp(y, _InvalidShiftCount, "signed shift count %s requires go1.13 or later", y)
+				check.errorf(y, UnsupportedFeature, invalidOp+"signed shift count %s requires go1.13 or later", y)
 				x.mode = invalid
 				return
 			}
@@ -958,7 +957,7 @@
 				return
 			}
 		default:
-			check.invalidOp(y, _InvalidShiftCount, "shift count %s must be integer", y)
+			check.errorf(y, InvalidShiftCount, invalidOp+"shift count %s must be integer", y)
 			x.mode = invalid
 			return
 		}
@@ -977,9 +976,9 @@
 			}
 			// rhs must be within reasonable bounds in constant shifts
 			const shiftBound = 1023 - 1 + 52 // so we can express smallestFloat64 (see issue #44057)
-			s, ok := constant.Uint64Val(y.val)
+			s, ok := constant.Uint64Val(yval)
 			if !ok || s > shiftBound {
-				check.invalidOp(y, _InvalidShiftCount, "invalid shift count %s", y)
+				check.errorf(y, InvalidShiftCount, invalidOp+"invalid shift count %s", y)
 				x.mode = invalid
 				return
 			}
@@ -1034,7 +1033,7 @@
 
 	// non-constant shift - lhs must be an integer
 	if !allInteger(x.typ) {
-		check.invalidOp(x, _InvalidShiftOperand, "shifted operand %s must be integer", x)
+		check.errorf(x, InvalidShiftOperand, invalidOp+"shifted operand %s must be integer", x)
 		x.mode = invalid
 		return
 	}
@@ -1085,26 +1084,50 @@
 		return
 	}
 
-	// TODO(gri) make canMix more efficient - called for each binary operation
-	canMix := func(x, y *operand) bool {
+	// mayConvert reports whether the operands x and y may
+	// possibly have matching types after converting one
+	// untyped operand to the type of the other.
+	// If mayConvert returns true, we try to convert the
+	// operands to each other's types, and if that fails
+	// we report a conversion failure.
+	// If mayConvert returns false, we continue without an
+	// attempt at conversion, and if the operand types are
+	// not compatible, we report a type mismatch error.
+	mayConvert := func(x, y *operand) bool {
+		// If both operands are typed, there's no need for an implicit conversion.
+		if isTyped(x.typ) && isTyped(y.typ) {
+			return false
+		}
+		// An untyped operand may convert to its default type when paired with an empty interface
+		// TODO(gri) This should only matter for comparisons (the only binary operation that is
+		//           valid with interfaces), but in that case the assignability check should take
+		//           care of the conversion. Verify and possibly eliminate this extra test.
 		if isNonTypeParamInterface(x.typ) || isNonTypeParamInterface(y.typ) {
 			return true
 		}
+		// A boolean type can only convert to another boolean type.
 		if allBoolean(x.typ) != allBoolean(y.typ) {
 			return false
 		}
+		// A string type can only convert to another string type.
 		if allString(x.typ) != allString(y.typ) {
 			return false
 		}
-		if x.isNil() && !hasNil(y.typ) {
-			return false
+		// Untyped nil can only convert to a type that has a nil.
+		if x.isNil() {
+			return hasNil(y.typ)
 		}
-		if y.isNil() && !hasNil(x.typ) {
+		if y.isNil() {
+			return hasNil(x.typ)
+		}
+		// An untyped operand cannot convert to a pointer.
+		// TODO(gri) generalize to type parameters
+		if isPointer(x.typ) || isPointer(y.typ) {
 			return false
 		}
 		return true
 	}
-	if canMix(x, &y) {
+	if mayConvert(x, &y) {
 		check.convertUntyped(x, y.typ)
 		if x.mode == invalid {
 			return
@@ -1130,9 +1153,9 @@
 				posn = e
 			}
 			if e != nil {
-				check.invalidOp(posn, _MismatchedTypes, "%s (mismatched types %s and %s)", e, x.typ, y.typ)
+				check.errorf(posn, MismatchedTypes, invalidOp+"%s (mismatched types %s and %s)", e, x.typ, y.typ)
 			} else {
-				check.invalidOp(posn, _MismatchedTypes, "%s %s= %s (mismatched types %s and %s)", lhs, op, rhs, x.typ, y.typ)
+				check.errorf(posn, MismatchedTypes, invalidOp+"%s %s= %s (mismatched types %s and %s)", lhs, op, rhs, x.typ, y.typ)
 			}
 		}
 		x.mode = invalid
@@ -1147,7 +1170,7 @@
 	if op == token.QUO || op == token.REM {
 		// check for zero divisor
 		if (x.mode == constant_ || allInteger(x.typ)) && y.mode == constant_ && constant.Sign(y.val) == 0 {
-			check.invalidOp(&y, _DivByZero, "division by zero")
+			check.error(&y, DivByZero, invalidOp+"division by zero")
 			x.mode = invalid
 			return
 		}
@@ -1157,7 +1180,7 @@
 			re, im := constant.Real(y.val), constant.Imag(y.val)
 			re2, im2 := constant.BinaryOp(re, token.MUL, re), constant.BinaryOp(im, token.MUL, im)
 			if constant.Sign(re2) == 0 && constant.Sign(im2) == 0 {
-				check.invalidOp(&y, _DivByZero, "division by zero")
+				check.error(&y, DivByZero, invalidOp+"division by zero")
 				x.mode = invalid
 				return
 			}
@@ -1239,7 +1262,7 @@
 		}
 	}
 	if what != "" {
-		check.errorf(x.expr, _WrongTypeArgCount, "cannot use generic %s %s without instantiation", what, x.expr)
+		check.errorf(x.expr, WrongTypeArgCount, "cannot use generic %s %s without instantiation", what, x.expr)
 		x.mode = invalid
 		x.typ = Typ[Invalid]
 	}
@@ -1263,7 +1286,7 @@
 	case *ast.Ellipsis:
 		// ellipses are handled explicitly where they are legal
 		// (array composite literals and parameter lists)
-		check.error(e, _BadDotDotDotSyntax, "invalid use of '...'")
+		check.error(e, BadDotDotDotSyntax, "invalid use of '...'")
 		goto Error
 
 	case *ast.BasicLit:
@@ -1281,7 +1304,7 @@
 			// allows for separators between all digits.
 			const limit = 10000
 			if len(e.Value) > limit {
-				check.errorf(e, _InvalidConstVal, "excessively long constant: %s... (%d chars)", e.Value[:10], len(e.Value))
+				check.errorf(e, InvalidConstVal, "excessively long constant: %s... (%d chars)", e.Value[:10], len(e.Value))
 				goto Error
 			}
 		}
@@ -1291,9 +1314,11 @@
 			// If we reach here it's because of number under-/overflow.
 			// TODO(gri) setConst (and in turn the go/constant package)
 			// should return an error describing the issue.
-			check.errorf(e, _InvalidConstVal, "malformed constant: %s", e.Value)
+			check.errorf(e, InvalidConstVal, "malformed constant: %s", e.Value)
 			goto Error
 		}
+		// Ensure that integer values don't overflow (issue #54280).
+		check.overflow(x, e.Pos())
 
 	case *ast.FuncLit:
 		if sig, ok := check.typ(e.Type).(*Signature); ok {
@@ -1314,7 +1339,7 @@
 			x.mode = value
 			x.typ = sig
 		} else {
-			check.invalidAST(e, "invalid function literal %s", e)
+			check.errorf(e, InvalidSyntaxTree, "invalid function literal %s", e)
 			goto Error
 		}
 
@@ -1344,13 +1369,13 @@
 			typ = hint
 			base, _ = deref(coreType(typ)) // *T implies &T{}
 			if base == nil {
-				check.errorf(e, _InvalidLit, "invalid composite literal element type %s: no core type", typ)
+				check.errorf(e, InvalidLit, "invalid composite literal element type %s (no core type)", typ)
 				goto Error
 			}
 
 		default:
 			// TODO(gri) provide better error messages depending on context
-			check.error(e, _UntypedLit, "missing type in composite literal")
+			check.error(e, UntypedLit, "missing type in composite literal")
 			goto Error
 		}
 
@@ -1359,12 +1384,15 @@
 			// Prevent crash if the struct referred to is not yet set up.
 			// See analogous comment for *Array.
 			if utyp.fields == nil {
-				check.error(e, _InvalidDeclCycle, "illegal cycle in type declaration")
+				check.error(e, InvalidTypeCycle, "invalid recursive type")
 				goto Error
 			}
 			if len(e.Elts) == 0 {
 				break
 			}
+			// Convention for error messages on invalid struct literals:
+			// we mention the struct type only if it clarifies the error
+			// (e.g., a duplicate field error doesn't need the struct type).
 			fields := utyp.fields
 			if _, ok := e.Elts[0].(*ast.KeyValueExpr); ok {
 				// all elements must have keys
@@ -1372,7 +1400,7 @@
 				for _, e := range e.Elts {
 					kv, _ := e.(*ast.KeyValueExpr)
 					if kv == nil {
-						check.error(e, _MixedStructLit, "mixture of field:value and value elements in struct literal")
+						check.error(e, MixedStructLit, "mixture of field:value and value elements in struct literal")
 						continue
 					}
 					key, _ := kv.Key.(*ast.Ident)
@@ -1380,12 +1408,12 @@
 					// so we don't drop information on the floor
 					check.expr(x, kv.Value)
 					if key == nil {
-						check.errorf(kv, _InvalidLitField, "invalid field name %s in struct literal", kv.Key)
+						check.errorf(kv, InvalidLitField, "invalid field name %s in struct literal", kv.Key)
 						continue
 					}
 					i := fieldIndex(utyp.fields, check.pkg, key.Name)
 					if i < 0 {
-						check.errorf(kv, _MissingLitField, "unknown field %s in struct literal", key.Name)
+						check.errorf(kv, MissingLitField, "unknown field %s in struct literal of type %s", key.Name, base)
 						continue
 					}
 					fld := fields[i]
@@ -1394,7 +1422,7 @@
 					check.assignment(x, etyp, "struct literal")
 					// 0 <= i < len(fields)
 					if visited[i] {
-						check.errorf(kv, _DuplicateLitField, "duplicate field name %s in struct literal", key.Name)
+						check.errorf(kv, DuplicateLitField, "duplicate field name %s in struct literal", key.Name)
 						continue
 					}
 					visited[i] = true
@@ -1403,27 +1431,27 @@
 				// no element must have a key
 				for i, e := range e.Elts {
 					if kv, _ := e.(*ast.KeyValueExpr); kv != nil {
-						check.error(kv, _MixedStructLit, "mixture of field:value and value elements in struct literal")
+						check.error(kv, MixedStructLit, "mixture of field:value and value elements in struct literal")
 						continue
 					}
 					check.expr(x, e)
 					if i >= len(fields) {
-						check.errorf(x, _InvalidStructLit, "too many values in %s{…}", base)
+						check.errorf(x, InvalidStructLit, "too many values in struct literal of type %s", base)
 						break // cannot continue
 					}
 					// i < len(fields)
 					fld := fields[i]
 					if !fld.Exported() && fld.pkg != check.pkg {
 						check.errorf(x,
-							_UnexportedLitField,
-							"implicit assignment to unexported field %s in %s literal", fld.name, typ)
+							UnexportedLitField,
+							"implicit assignment to unexported field %s in struct literal of type %s", fld.name, base)
 						continue
 					}
 					etyp := fld.typ
 					check.assignment(x, etyp, "struct literal")
 				}
 				if len(e.Elts) < len(fields) {
-					check.errorf(inNode(e, e.Rbrace), _InvalidStructLit, "too few values in %s{…}", base)
+					check.errorf(inNode(e, e.Rbrace), InvalidStructLit, "too few values in struct literal of type %s", base)
 					// ok to continue
 				}
 			}
@@ -1433,7 +1461,7 @@
 			// This is a stop-gap solution. Should use Checker.objPath to report entire
 			// path starting with earliest declaration in the source. TODO(gri) fix this.
 			if utyp.elem == nil {
-				check.error(e, _InvalidTypeCycle, "illegal cycle in type declaration")
+				check.error(e, InvalidTypeCycle, "invalid recursive type")
 				goto Error
 			}
 			n := check.indexedElts(e.Elts, utyp.elem, utyp.len)
@@ -1460,7 +1488,7 @@
 			// Prevent crash if the slice referred to is not yet set up.
 			// See analogous comment for *Array.
 			if utyp.elem == nil {
-				check.error(e, _InvalidTypeCycle, "illegal cycle in type declaration")
+				check.error(e, InvalidTypeCycle, "invalid recursive type")
 				goto Error
 			}
 			check.indexedElts(e.Elts, utyp.elem, -1)
@@ -1469,7 +1497,7 @@
 			// Prevent crash if the map referred to is not yet set up.
 			// See analogous comment for *Array.
 			if utyp.key == nil || utyp.elem == nil {
-				check.error(e, _InvalidTypeCycle, "illegal cycle in type declaration")
+				check.error(e, InvalidTypeCycle, "invalid recursive type")
 				goto Error
 			}
 			// If the map key type is an interface (but not a type parameter),
@@ -1480,7 +1508,7 @@
 			for _, e := range e.Elts {
 				kv, _ := e.(*ast.KeyValueExpr)
 				if kv == nil {
-					check.error(e, _MissingLitKey, "missing key in map literal")
+					check.error(e, MissingLitKey, "missing key in map literal")
 					continue
 				}
 				check.exprWithHint(x, kv.Key, utyp.key)
@@ -1504,7 +1532,7 @@
 						visited[xkey] = nil
 					}
 					if duplicate {
-						check.errorf(x, _DuplicateLitKey, "duplicate key %s in map literal", x.val)
+						check.errorf(x, DuplicateLitKey, "duplicate key %s in map literal", x.val)
 						continue
 					}
 				}
@@ -1526,7 +1554,7 @@
 			}
 			// if utyp is invalid, an error was reported before
 			if utyp != Typ[Invalid] {
-				check.errorf(e, _InvalidLit, "invalid composite literal type %s", typ)
+				check.errorf(e, InvalidLit, "invalid composite literal type %s", typ)
 				goto Error
 			}
 		}
@@ -1540,7 +1568,7 @@
 		return kind
 
 	case *ast.SelectorExpr:
-		check.selector(x, e, nil)
+		check.selector(x, e, nil, false)
 
 	case *ast.IndexExpr, *ast.IndexListExpr:
 		ix := typeparams.UnpackIndexExpr(e)
@@ -1564,18 +1592,18 @@
 		}
 		// TODO(gri) we may want to permit type assertions on type parameter values at some point
 		if isTypeParam(x.typ) {
-			check.invalidOp(x, _InvalidAssert, "cannot use type assertion on type parameter value %s", x)
+			check.errorf(x, InvalidAssert, invalidOp+"cannot use type assertion on type parameter value %s", x)
 			goto Error
 		}
 		if _, ok := under(x.typ).(*Interface); !ok {
-			check.invalidOp(x, _InvalidAssert, "%s is not an interface", x)
+			check.errorf(x, InvalidAssert, invalidOp+"%s is not an interface", x)
 			goto Error
 		}
 		// x.(type) expressions are handled explicitly in type switches
 		if e.Type == nil {
 			// Don't use invalidAST because this can occur in the AST produced by
 			// go/parser.
-			check.error(e, _BadTypeKeyword, "use of .(type) outside type switch")
+			check.error(e, BadTypeKeyword, "use of .(type) outside type switch")
 			goto Error
 		}
 		T := check.varType(e.Type)
@@ -1602,11 +1630,11 @@
 			if !underIs(x.typ, func(u Type) bool {
 				p, _ := u.(*Pointer)
 				if p == nil {
-					check.invalidOp(x, _InvalidIndirection, "cannot indirect %s", x)
+					check.errorf(x, InvalidIndirection, invalidOp+"cannot indirect %s", x)
 					return false
 				}
 				if base != nil && !Identical(p.base, base) {
-					check.invalidOp(x, _InvalidIndirection, "pointers of %s must have identical base types", x)
+					check.errorf(x, InvalidIndirection, invalidOp+"pointers of %s must have identical base types", x)
 					return false
 				}
 				base = p.base
@@ -1636,7 +1664,7 @@
 
 	case *ast.KeyValueExpr:
 		// key:value expressions are handled in composite literals
-		check.invalidAST(e, "no key:value expected")
+		check.error(e, InvalidSyntaxTree, "no key:value expected")
 		goto Error
 
 	case *ast.ArrayType, *ast.StructType, *ast.FuncType,
@@ -1712,14 +1740,14 @@
 		return // success
 	}
 
-	cause := check.missingMethodReason(T, x.typ, method, alt)
+	cause := check.missingMethodCause(T, x.typ, method, alt)
 
 	if typeSwitch {
-		check.errorf(e, _ImpossibleAssert, "impossible type switch case: %s\n\t%s cannot have dynamic type %s %s", e, x, T, cause)
+		check.errorf(e, ImpossibleAssert, "impossible type switch case: %s\n\t%s cannot have dynamic type %s %s", e, x, T, cause)
 		return
 	}
 
-	check.errorf(e, _ImpossibleAssert, "impossible type assertion: %s\n\t%s does not implement %s %s", e, T, x.typ, cause)
+	check.errorf(e, ImpossibleAssert, "impossible type assertion: %s\n\t%s does not implement %s %s", e, T, x.typ, cause)
 }
 
 // expr typechecks expression e and initializes x with the expression value.
@@ -1762,7 +1790,7 @@
 func (check *Checker) exclude(x *operand, modeset uint) {
 	if modeset&(1<<x.mode) != 0 {
 		var msg string
-		var code errorCode
+		var code Code
 		switch x.mode {
 		case novalue:
 			if modeset&(1<<typexpr) != 0 {
@@ -1770,13 +1798,13 @@
 			} else {
 				msg = "%s used as value or type"
 			}
-			code = _TooManyValues
+			code = TooManyValues
 		case builtin:
 			msg = "%s must be called"
-			code = _UncalledBuiltin
+			code = UncalledBuiltin
 		case typexpr:
 			msg = "%s is not an expression"
-			code = _NotAnExpr
+			code = NotAnExpr
 		default:
 			unreachable()
 		}
@@ -1791,11 +1819,7 @@
 		// tuple types are never named - no need for underlying type below
 		if t, ok := x.typ.(*Tuple); ok {
 			assert(t.Len() != 1)
-			if compilerErrorMessages {
-				check.errorf(x, _TooManyValues, "multiple-value %s in single-value context", x)
-			} else {
-				check.errorf(x, _TooManyValues, "%d-valued %s where single value is expected", t.Len(), x)
-			}
+			check.errorf(x, TooManyValues, "multiple-value %s in single-value context", x)
 			x.mode = invalid
 		}
 	}
diff --git a/src/go/types/exprstring.go b/src/go/types/exprstring.go
index 544cd84..3cdf30f 100644
--- a/src/go/types/exprstring.go
+++ b/src/go/types/exprstring.go
@@ -33,7 +33,7 @@
 
 	switch x := x.(type) {
 	default:
-		buf.WriteString(fmt.Sprintf("(ast: %T)", x)) // nil, ast.BadExpr, ast.KeyValueExpr
+		fmt.Fprintf(buf, "(ast: %T)", x) // nil, ast.BadExpr, ast.KeyValueExpr
 
 	case *ast.Ident:
 		buf.WriteString(x.Name)
@@ -53,9 +53,12 @@
 		buf.WriteString(" literal)") // shortened
 
 	case *ast.CompositeLit:
-		buf.WriteByte('(')
 		WriteExpr(buf, x.Type)
-		buf.WriteString(" literal)") // shortened
+		buf.WriteByte('{')
+		if len(x.Elts) > 0 {
+			buf.WriteString("…")
+		}
+		buf.WriteByte('}')
 
 	case *ast.ParenExpr:
 		buf.WriteByte('(')
diff --git a/src/go/types/exprstring_test.go b/src/go/types/exprstring_test.go
index 27cd532..604ceb9 100644
--- a/src/go/types/exprstring_test.go
+++ b/src/go/types/exprstring_test.go
@@ -25,7 +25,7 @@
 	// func and composite literals
 	{"func(){}", "(func() literal)"},
 	{"func(x int) complex128 {}", "(func(x int) complex128 literal)"},
-	{"[]int{1, 2, 3}", "([]int literal)"},
+	{"[]int{1, 2, 3}", "[]int{…}"},
 
 	// type expressions
 	dup("[1 << 10]byte"),
diff --git a/src/go/types/gotype.go b/src/go/types/gotype.go
index e8ff965..ee9c12c 100644
--- a/src/go/types/gotype.go
+++ b/src/go/types/gotype.go
@@ -180,7 +180,7 @@
 	errorCount++
 }
 
-// parse may be called concurrently
+// parse may be called concurrently.
 func parse(filename string, src any) (*ast.File, error) {
 	if *verbose {
 		fmt.Println(filename)
diff --git a/src/go/types/index.go b/src/go/types/index.go
index f963d31..45d591e 100644
--- a/src/go/types/index.go
+++ b/src/go/types/index.go
@@ -10,6 +10,7 @@
 	"go/ast"
 	"go/constant"
 	"go/internal/typeparams"
+	. "internal/types/errors"
 )
 
 // If e is a valid function instantiation, indexExpr returns true.
@@ -184,7 +185,7 @@
 
 	if !valid {
 		// types2 uses the position of '[' for the error
-		check.invalidOp(x, _NonIndexableOperand, "cannot index %s", x)
+		check.errorf(x, NonIndexableOperand, invalidOp+"cannot index %s", x)
 		x.mode = invalid
 		return false
 	}
@@ -217,7 +218,7 @@
 	length := int64(-1) // valid if >= 0
 	switch u := coreString(x.typ).(type) {
 	case nil:
-		check.invalidOp(x, _NonSliceableOperand, "cannot slice %s: %s has no core type", x, x.typ)
+		check.errorf(x, NonSliceableOperand, invalidOp+"cannot slice %s: %s has no core type", x, x.typ)
 		x.mode = invalid
 		return
 
@@ -228,7 +229,7 @@
 				if at == nil {
 					at = e // e.Index[2] should be present but be careful
 				}
-				check.invalidOp(at, _InvalidSliceExpr, "3-index slice of string")
+				check.error(at, InvalidSliceExpr, invalidOp+"3-index slice of string")
 				x.mode = invalid
 				return
 			}
@@ -247,7 +248,7 @@
 		valid = true
 		length = u.len
 		if x.mode != variable {
-			check.invalidOp(x, _NonSliceableOperand, "cannot slice %s (value not addressable)", x)
+			check.errorf(x, NonSliceableOperand, invalidOp+"cannot slice %s (value not addressable)", x)
 			x.mode = invalid
 			return
 		}
@@ -266,7 +267,7 @@
 	}
 
 	if !valid {
-		check.invalidOp(x, _NonSliceableOperand, "cannot slice %s", x)
+		check.errorf(x, NonSliceableOperand, invalidOp+"cannot slice %s", x)
 		x.mode = invalid
 		return
 	}
@@ -275,7 +276,7 @@
 
 	// spec: "Only the first index may be omitted; it defaults to 0."
 	if e.Slice3 && (e.High == nil || e.Max == nil) {
-		check.invalidAST(inNode(e, e.Rbrack), "2nd and 3rd index required in 3-index slice")
+		check.error(inNode(e, e.Rbrack), InvalidSyntaxTree, "2nd and 3rd index required in 3-index slice")
 		x.mode = invalid
 		return
 	}
@@ -317,7 +318,7 @@
 					// Because y >= 0, it must have been set from the expression
 					// when checking indices and thus e.Index[i+1+j] is not nil.
 					at := []ast.Expr{e.Low, e.High, e.Max}[i+1+j]
-					check.errorf(at, _SwappedSliceIndices, "invalid slice indices: %d < %d", y, x)
+					check.errorf(at, SwappedSliceIndices, "invalid slice indices: %d < %d", y, x)
 					break L // only report one error, ok to continue
 				}
 			}
@@ -330,12 +331,12 @@
 // is reported and the result is nil.
 func (check *Checker) singleIndex(expr *typeparams.IndexExpr) ast.Expr {
 	if len(expr.Indices) == 0 {
-		check.invalidAST(expr.Orig, "index expression %v with 0 indices", expr)
+		check.errorf(expr.Orig, InvalidSyntaxTree, "index expression %v with 0 indices", expr)
 		return nil
 	}
 	if len(expr.Indices) > 1 {
 		// TODO(rFindley) should this get a distinct error code?
-		check.invalidOp(expr.Indices[1], _InvalidIndex, "more than one index")
+		check.error(expr.Indices[1], InvalidIndex, invalidOp+"more than one index")
 	}
 	return expr.Indices[0]
 }
@@ -350,7 +351,7 @@
 
 	var x operand
 	check.expr(&x, index)
-	if !check.isValidIndex(&x, _InvalidIndex, "index", false) {
+	if !check.isValidIndex(&x, InvalidIndex, "index", false) {
 		return
 	}
 
@@ -365,7 +366,7 @@
 	v, ok := constant.Int64Val(x.val)
 	assert(ok)
 	if max >= 0 && v >= max {
-		check.invalidArg(&x, _InvalidIndex, "index %s out of bounds [0:%d]", x.val.String(), max)
+		check.errorf(&x, InvalidIndex, invalidArg+"index %s out of bounds [0:%d]", x.val.String(), max)
 		return
 	}
 
@@ -373,7 +374,7 @@
 	return x.typ, v
 }
 
-func (check *Checker) isValidIndex(x *operand, code errorCode, what string, allowNegative bool) bool {
+func (check *Checker) isValidIndex(x *operand, code Code, what string, allowNegative bool) bool {
 	if x.mode == invalid {
 		return false
 	}
@@ -386,20 +387,20 @@
 
 	// spec: "the index x must be of integer type or an untyped constant"
 	if !allInteger(x.typ) {
-		check.invalidArg(x, code, "%s %s must be integer", what, x)
+		check.errorf(x, code, invalidArg+"%s %s must be integer", what, x)
 		return false
 	}
 
 	if x.mode == constant_ {
 		// spec: "a constant index must be non-negative ..."
 		if !allowNegative && constant.Sign(x.val) < 0 {
-			check.invalidArg(x, code, "%s %s must not be negative", what, x)
+			check.errorf(x, code, invalidArg+"%s %s must not be negative", what, x)
 			return false
 		}
 
 		// spec: "... and representable by a value of type int"
 		if !representableConst(x.val, check, Typ[Int], &x.val) {
-			check.invalidArg(x, code, "%s %s overflows int", what, x)
+			check.errorf(x, code, invalidArg+"%s %s overflows int", what, x)
 			return false
 		}
 	}
@@ -424,12 +425,12 @@
 					index = i
 					validIndex = true
 				} else {
-					check.errorf(e, _InvalidLitIndex, "index %s must be integer constant", kv.Key)
+					check.errorf(e, InvalidLitIndex, "index %s must be integer constant", kv.Key)
 				}
 			}
 			eval = kv.Value
 		} else if length >= 0 && index >= length {
-			check.errorf(e, _OversizeArrayLit, "index %d is out of bounds (>= %d)", index, length)
+			check.errorf(e, OversizeArrayLit, "index %d is out of bounds (>= %d)", index, length)
 		} else {
 			validIndex = true
 		}
@@ -437,7 +438,7 @@
 		// if we have a valid index, check for duplicate entries
 		if validIndex {
 			if visited[index] {
-				check.errorf(e, _DuplicateLitKey, "duplicate index %d in array or slice literal", index)
+				check.errorf(e, DuplicateLitKey, "duplicate index %d in array or slice literal", index)
 			}
 			visited[index] = true
 		}
diff --git a/src/go/types/infer.go b/src/go/types/infer.go
index 768efbf..dc87902 100644
--- a/src/go/types/infer.go
+++ b/src/go/types/infer.go
@@ -10,6 +10,7 @@
 import (
 	"fmt"
 	"go/token"
+	. "internal/types/errors"
 	"strings"
 )
 
@@ -88,34 +89,22 @@
 		//    f(p)
 		//  }
 		//
-		// We can turn the first example into the second example by renaming type
-		// parameters in the original signature to give them a new identity. As an
-		// optimization, we do this only for self-recursive calls.
-
-		// We can detect if we are in a self-recursive call by comparing the
-		// identity of the first type parameter in the current function with the
-		// first type parameter in tparams. This works because type parameters are
-		// unique to their type parameter list.
-		selfRecursive := check.sig != nil && check.sig.tparams.Len() > 0 && tparams[0] == check.sig.tparams.At(0)
-
-		if selfRecursive {
-			// In self-recursive inference, rename the type parameters with new type
-			// parameters that are the same but for their pointer identity.
-			tparams2 := make([]*TypeParam, len(tparams))
-			for i, tparam := range tparams {
-				tname := NewTypeName(tparam.Obj().Pos(), tparam.Obj().Pkg(), tparam.Obj().Name(), nil)
-				tparams2[i] = NewTypeParam(tname, nil)
-				tparams2[i].index = tparam.index // == i
-			}
-
-			renameMap := makeRenameMap(tparams, tparams2)
-			for i, tparam := range tparams {
-				tparams2[i].bound = check.subst(posn.Pos(), tparam.bound, renameMap, nil, check.context())
-			}
-
-			tparams = tparams2
-			params = check.subst(posn.Pos(), params, renameMap, nil, check.context()).(*Tuple)
+		// We turn the first example into the second example by renaming type
+		// parameters in the original signature to give them a new identity.
+		tparams2 := make([]*TypeParam, len(tparams))
+		for i, tparam := range tparams {
+			tname := NewTypeName(tparam.Obj().Pos(), tparam.Obj().Pkg(), tparam.Obj().Name(), nil)
+			tparams2[i] = NewTypeParam(tname, nil)
+			tparams2[i].index = tparam.index // == i
 		}
+
+		renameMap := makeRenameMap(tparams, tparams2)
+		for i, tparam := range tparams {
+			tparams2[i].bound = check.subst(posn.Pos(), tparam.bound, renameMap, nil, check.context())
+		}
+
+		tparams = tparams2
+		params = check.subst(posn.Pos(), params, renameMap, nil, check.context()).(*Tuple)
 	}
 
 	// If we have more than 2 arguments, we may have arguments with named and unnamed types.
@@ -216,7 +205,7 @@
 				}
 			}
 			if allFailed {
-				check.errorf(arg, _CannotInferTypeArgs, "%s %s of %s does not match %s (cannot infer %s)", kind, targ, arg.expr, tpar, typeParamsString(tparams))
+				check.errorf(arg, CannotInferTypeArgs, "%s %s of %s does not match %s (cannot infer %s)", kind, targ, arg.expr, tpar, typeParamsString(tparams))
 				return
 			}
 		}
@@ -228,9 +217,9 @@
 		// _InvalidTypeArg). We can't differentiate these cases, so fall back on
 		// the more general _CannotInferTypeArgs.
 		if inferred != tpar {
-			check.errorf(arg, _CannotInferTypeArgs, "%s %s of %s does not match inferred type %s for %s", kind, targ, arg.expr, inferred, tpar)
+			check.errorf(arg, CannotInferTypeArgs, "%s %s of %s does not match inferred type %s for %s", kind, targ, arg.expr, inferred, tpar)
 		} else {
-			check.errorf(arg, _CannotInferTypeArgs, "%s %s of %s does not match %s", kind, targ, arg.expr, tpar)
+			check.errorf(arg, CannotInferTypeArgs, "%s %s of %s does not match %s", kind, targ, arg.expr, tpar)
 		}
 	}
 
@@ -320,7 +309,7 @@
 	// At least one type argument couldn't be inferred.
 	assert(index >= 0 && targs[index] == nil)
 	tpar := tparams[index]
-	check.errorf(posn, _CannotInferTypeArgs, "cannot infer %s (%v)", tpar.obj.name, tpar.obj.pos)
+	check.errorf(posn, CannotInferTypeArgs, "cannot infer %s (%v)", tpar.obj.name, tpar.obj.pos)
 	return nil
 }
 
@@ -339,16 +328,16 @@
 	}
 
 	// general case (n > 2)
-	var b strings.Builder
+	var buf strings.Builder
 	for i, tname := range list[:n-1] {
 		if i > 0 {
-			b.WriteString(", ")
+			buf.WriteString(", ")
 		}
-		b.WriteString(tname.obj.name)
+		buf.WriteString(tname.obj.name)
 	}
-	b.WriteString(", and ")
-	b.WriteString(list[n-1].obj.name)
-	return b.String()
+	buf.WriteString(", and ")
+	buf.WriteString(list[n-1].obj.name)
+	return buf.String()
 }
 
 // isParameterized reports whether typ contains any of the type parameters of tparams.
@@ -533,7 +522,7 @@
 						if core.tilde {
 							tilde = "~"
 						}
-						check.errorf(posn, _InvalidTypeArg, "%s does not match %s%s", tpar, tilde, core.typ)
+						check.errorf(posn, InvalidTypeArg, "%s does not match %s%s", tx, tilde, core.typ)
 						return nil, 0
 					}
 
@@ -578,7 +567,7 @@
 	}
 
 	// The data structure of each (provided or inferred) type represents a graph, where
-	// each node corresponds to a type and each (directed) vertice points to a component
+	// each node corresponds to a type and each (directed) vertex points to a component
 	// type. The substitution process described above repeatedly replaces type parameter
 	// nodes in these graphs with the graphs of the types the type parameters stand for,
 	// which creates a new (possibly bigger) graph for each type.
@@ -591,14 +580,14 @@
 	// Generally, cycles may occur across multiple type parameters and inferred types
 	// (for instance, consider [P interface{ *Q }, Q interface{ func(P) }]).
 	// We eliminate cycles by walking the graphs for all type parameters. If a cycle
-	// through a type parameter is detected, cycleFinder nils out the respectice type
+	// through a type parameter is detected, cycleFinder nils out the respective type
 	// which kills the cycle; this also means that the respective type could not be
 	// inferred.
 	//
 	// TODO(gri) If useful, we could report the respective cycle as an error. We don't
 	//           do this now because type inference will fail anyway, and furthermore,
 	//           constraints with cycles of this kind cannot currently be satisfied by
-	//           any user-suplied type. But should that change, reporting an error
+	//           any user-supplied type. But should that change, reporting an error
 	//           would be wrong.
 	w := cycleFinder{tparams, types, make(map[Type]bool)}
 	for _, t := range tparams {
diff --git a/src/go/types/initorder.go b/src/go/types/initorder.go
index 1118b58..9ee176f 100644
--- a/src/go/types/initorder.go
+++ b/src/go/types/initorder.go
@@ -7,6 +7,7 @@
 import (
 	"container/heap"
 	"fmt"
+	. "internal/types/errors"
 	"sort"
 )
 
@@ -152,14 +153,21 @@
 // reportCycle reports an error for the given cycle.
 func (check *Checker) reportCycle(cycle []Object) {
 	obj := cycle[0]
-	check.errorf(obj, _InvalidInitCycle, "initialization cycle for %s", obj.Name())
+
+	// report a more concise error for self references
+	if len(cycle) == 1 {
+		check.errorf(obj, InvalidInitCycle, "initialization cycle: %s refers to itself", obj.Name())
+		return
+	}
+
+	check.errorf(obj, InvalidInitCycle, "initialization cycle for %s", obj.Name())
 	// subtle loop: print cycle[i] for i = 0, n-1, n-2, ... 1 for len(cycle) = n
 	for i := len(cycle) - 1; i >= 0; i-- {
-		check.errorf(obj, _InvalidInitCycle, "\t%s refers to", obj.Name()) // secondary error, \t indented
+		check.errorf(obj, InvalidInitCycle, "\t%s refers to", obj.Name()) // secondary error, \t indented
 		obj = cycle[i]
 	}
 	// print cycle[0] again to close the cycle
-	check.errorf(obj, _InvalidInitCycle, "\t%s", obj.Name())
+	check.errorf(obj, InvalidInitCycle, "\t%s", obj.Name())
 }
 
 // ----------------------------------------------------------------------------
diff --git a/src/go/types/instantiate.go b/src/go/types/instantiate.go
index f750585..2cf48c1 100644
--- a/src/go/types/instantiate.go
+++ b/src/go/types/instantiate.go
@@ -11,6 +11,7 @@
 	"errors"
 	"fmt"
 	"go/token"
+	. "internal/types/errors"
 )
 
 // Instantiate instantiates the type orig with the given type arguments targs.
@@ -156,7 +157,7 @@
 	if ntargs != ntparams {
 		// TODO(gri) provide better error message
 		if check != nil {
-			check.errorf(atPos(pos), _WrongTypeArgCount, "got %d arguments but %d type parameters", ntargs, ntparams)
+			check.errorf(atPos(pos), WrongTypeArgCount, "got %d arguments but %d type parameters", ntargs, ntparams)
 			return false
 		}
 		panic(fmt.Sprintf("%v: got %d arguments but %d type parameters", pos, ntargs, ntparams))
@@ -174,44 +175,52 @@
 		// need to instantiate it with the type arguments with which we instantiated
 		// the parameterized type.
 		bound := check.subst(pos, tpar.bound, smap, nil, ctxt)
-		if err := check.implements(targs[i], bound); err != nil {
-			return i, err
+		var cause string
+		if !check.implements(targs[i], bound, true, &cause) {
+			return i, errors.New(cause)
 		}
 	}
 	return -1, nil
 }
 
-// implements checks if V implements T and reports an error if it doesn't.
-// The receiver may be nil if implements is called through an exported
-// API call such as AssignableTo.
-func (check *Checker) implements(V, T Type) error {
+// implements checks if V implements T. The receiver may be nil if implements
+// is called through an exported API call such as AssignableTo. If constraint
+// is set, T is a type constraint.
+//
+// If the provided cause is non-nil, it may be set to an error string
+// explaining why V does not implement (or satisfy, for constraints) T.
+func (check *Checker) implements(V, T Type, constraint bool, cause *string) bool {
 	Vu := under(V)
 	Tu := under(T)
 	if Vu == Typ[Invalid] || Tu == Typ[Invalid] {
-		return nil // avoid follow-on errors
+		return true // avoid follow-on errors
 	}
 	if p, _ := Vu.(*Pointer); p != nil && under(p.base) == Typ[Invalid] {
-		return nil // avoid follow-on errors (see issue #49541 for an example)
+		return true // avoid follow-on errors (see issue #49541 for an example)
 	}
 
-	errorf := func(format string, args ...any) error {
-		return errors.New(check.sprintf(format, args...))
+	verb := "implement"
+	if constraint {
+		verb = "satisfy"
 	}
 
 	Ti, _ := Tu.(*Interface)
 	if Ti == nil {
-		var cause string
-		if isInterfacePtr(Tu) {
-			cause = check.sprintf("type %s is pointer to interface, not interface", T)
-		} else {
-			cause = check.sprintf("%s is not an interface", T)
+		if cause != nil {
+			var detail string
+			if isInterfacePtr(Tu) {
+				detail = check.sprintf("type %s is pointer to interface, not interface", T)
+			} else {
+				detail = check.sprintf("%s is not an interface", T)
+			}
+			*cause = check.sprintf("%s does not %s %s (%s)", V, verb, T, detail)
 		}
-		return errorf("%s does not implement %s (%s)", V, T, cause)
+		return false
 	}
 
 	// Every type satisfies the empty interface.
 	if Ti.Empty() {
-		return nil
+		return true
 	}
 	// T is not the empty interface (i.e., the type set of T is restricted)
 
@@ -219,31 +228,67 @@
 	// (The empty set is a subset of any set.)
 	Vi, _ := Vu.(*Interface)
 	if Vi != nil && Vi.typeSet().IsEmpty() {
-		return nil
+		return true
 	}
 	// type set of V is not empty
 
 	// No type with non-empty type set satisfies the empty type set.
 	if Ti.typeSet().IsEmpty() {
-		return errorf("cannot implement %s (empty type set)", T)
+		if cause != nil {
+			*cause = check.sprintf("cannot %s %s (empty type set)", verb, T)
+		}
+		return false
 	}
 
 	// V must implement T's methods, if any.
 	if m, wrong := check.missingMethod(V, Ti, true); m != nil /* !Implements(V, Ti) */ {
-		return errorf("%s does not implement %s %s", V, T, check.missingMethodReason(V, T, m, wrong))
+		if cause != nil {
+			*cause = check.sprintf("%s does not %s %s %s", V, verb, T, check.missingMethodCause(V, T, m, wrong))
+		}
+		return false
 	}
 
-	// If T is comparable, V must be comparable.
-	// Remember as a pending error and report only if we don't have a more specific error.
-	var pending error
-	if Ti.IsComparable() && !comparable(V, false, nil, nil) {
-		pending = errorf("%s does not implement comparable", V)
+	// Only check comparability if we don't have a more specific error.
+	checkComparability := func() bool {
+		if !Ti.IsComparable() {
+			return true
+		}
+		// If T is comparable, V must be comparable.
+		// If V is strictly comparable, we're done.
+		if comparable(V, false /* strict comparability */, nil, nil) {
+			return true
+		}
+		// If check.conf.OldComparableSemantics is set (by the compiler or
+		// a test), we only consider strict comparability and we're done.
+		// TODO(gri) remove this check for Go 1.21
+		if check != nil && check.conf.oldComparableSemantics {
+			if cause != nil {
+				*cause = check.sprintf("%s does not %s comparable", V, verb)
+			}
+			return false
+		}
+		// For constraint satisfaction, use dynamic (spec) comparability
+		// so that ordinary, non-type parameter interfaces implement comparable.
+		if constraint && comparable(V, true /* spec comparability */, nil, nil) {
+			// V is comparable if we are at Go 1.20 or higher.
+			if check == nil || check.allowVersion(check.pkg, 1, 20) {
+				return true
+			}
+			if cause != nil {
+				*cause = check.sprintf("%s to %s comparable requires go1.20 or later", V, verb)
+			}
+			return false
+		}
+		if cause != nil {
+			*cause = check.sprintf("%s does not %s comparable", V, verb)
+		}
+		return false
 	}
 
 	// V must also be in the set of types of T, if any.
 	// Constraints with empty type sets were already excluded above.
 	if !Ti.typeSet().hasTerms() {
-		return pending // nothing to do
+		return checkComparability() // nothing to do
 	}
 
 	// If V is itself an interface, each of its possible types must be in the set
@@ -252,9 +297,12 @@
 	if Vi != nil {
 		if !Vi.typeSet().subsetOf(Ti.typeSet()) {
 			// TODO(gri) report which type is missing
-			return errorf("%s does not implement %s", V, T)
+			if cause != nil {
+				*cause = check.sprintf("%s does not %s %s", V, verb, T)
+			}
+			return false
 		}
-		return pending
+		return checkComparability()
 	}
 
 	// Otherwise, V's type must be included in the iface type set.
@@ -275,12 +323,44 @@
 		}
 		return false
 	}) {
-		if alt != nil {
-			return errorf("%s does not implement %s (possibly missing ~ for %s in constraint %s)", V, T, alt, T)
-		} else {
-			return errorf("%s does not implement %s (%s missing in %s)", V, T, V, Ti.typeSet().terms)
+		if cause != nil {
+			var detail string
+			switch {
+			case alt != nil:
+				detail = check.sprintf("possibly missing ~ for %s in %s", alt, T)
+			case mentions(Ti, V):
+				detail = check.sprintf("%s mentions %s, but %s is not in the type set of %s", T, V, V, T)
+			default:
+				detail = check.sprintf("%s missing in %s", V, Ti.typeSet().terms)
+			}
+			*cause = check.sprintf("%s does not %s %s (%s)", V, verb, T, detail)
 		}
+		return false
 	}
 
-	return pending
+	return checkComparability()
+}
+
+// mentions reports whether type T "mentions" typ in an (embedded) element or term
+// of T (whether typ is in the type set of T or not). For better error messages.
+func mentions(T, typ Type) bool {
+	switch T := T.(type) {
+	case *Interface:
+		for _, e := range T.embeddeds {
+			if mentions(e, typ) {
+				return true
+			}
+		}
+	case *Union:
+		for _, t := range T.terms {
+			if mentions(t.typ, typ) {
+				return true
+			}
+		}
+	default:
+		if Identical(T, typ) {
+			return true
+		}
+	}
+	return false
 }
diff --git a/src/go/types/instantiate_test.go b/src/go/types/instantiate_test.go
index 281c8bb..0b44a1a 100644
--- a/src/go/types/instantiate_test.go
+++ b/src/go/types/instantiate_test.go
@@ -109,10 +109,7 @@
 	}
 
 	for _, test := range tests {
-		pkg, err := pkgForMode(".", test.src, nil, 0)
-		if err != nil {
-			t.Fatal(err)
-		}
+		pkg := mustTypecheck(".", test.src, nil)
 
 		t.Run(pkg.Name(), func(t *testing.T) {
 			ctxt := NewContext()
@@ -139,14 +136,8 @@
 func TestInstantiateNonEquality(t *testing.T) {
 	const src = "package p; type T[P any] int"
 
-	pkg1, err := pkgForMode(".", src, nil, 0)
-	if err != nil {
-		t.Fatal(err)
-	}
-	pkg2, err := pkgForMode(".", src, nil, 0)
-	if err != nil {
-		t.Fatal(err)
-	}
+	pkg1 := mustTypecheck(".", src, nil)
+	pkg2 := mustTypecheck(".", src, nil)
 
 	// We consider T1 and T2 to be distinct types, so their instances should not
 	// be deduplicated by the context.
@@ -194,10 +185,7 @@
 
 	for _, test := range tests {
 		src := prefix + test.decl
-		pkg, err := pkgForMode(".", src, nil, 0)
-		if err != nil {
-			t.Fatal(err)
-		}
+		pkg := mustTypecheck(".", src, nil)
 		typ := NewPointer(pkg.Scope().Lookup("X").Type())
 		obj, _, _ := LookupFieldOrMethod(typ, false, pkg, "m")
 		m, _ := obj.(*Func)
@@ -219,10 +207,7 @@
 
 var _ T[int]
 `
-	pkg, err := pkgForMode(".", src, nil, 0)
-	if err != nil {
-		t.Fatal(err)
-	}
+	pkg := mustTypecheck(".", src, nil)
 	typ := pkg.Scope().Lookup("T").Type().(*Named)
 	obj, _, _ := LookupFieldOrMethod(typ, false, pkg, "m")
 	if obj == nil {
@@ -239,15 +224,15 @@
 
 // Copied from errors.go.
 func stripAnnotations(s string) string {
-	var b strings.Builder
+	var buf strings.Builder
 	for _, r := range s {
 		// strip #'s and subscript digits
 		if r < '₀' || '₀'+10 <= r { // '₀' == U+2080
-			b.WriteRune(r)
+			buf.WriteRune(r)
 		}
 	}
-	if b.Len() < len(s) {
-		return b.String()
+	if buf.Len() < len(s) {
+		return buf.String()
 	}
 	return s
 }
diff --git a/src/go/types/interface.go b/src/go/types/interface.go
index 52ae123..83538d2 100644
--- a/src/go/types/interface.go
+++ b/src/go/types/interface.go
@@ -7,6 +7,7 @@
 import (
 	"go/ast"
 	"go/token"
+	. "internal/types/errors"
 )
 
 // ----------------------------------------------------------------------------
@@ -173,7 +174,7 @@
 		// We have a method with name f.Names[0].
 		name := f.Names[0]
 		if name.Name == "_" {
-			check.errorf(name, _BlankIfaceMethod, "methods must have a unique non-blank name")
+			check.error(name, BlankIfaceMethod, "methods must have a unique non-blank name")
 			continue // ignore
 		}
 
@@ -181,7 +182,7 @@
 		sig, _ := typ.(*Signature)
 		if sig == nil {
 			if typ != Typ[Invalid] {
-				check.invalidAST(f.Type, "%s is not a method signature", typ)
+				check.errorf(f.Type, InvalidSyntaxTree, "%s is not a method signature", typ)
 			}
 			continue // ignore
 		}
@@ -194,7 +195,7 @@
 			if ftyp, _ := f.Type.(*ast.FuncType); ftyp != nil && ftyp.TypeParams != nil {
 				at = ftyp.TypeParams
 			}
-			check.errorf(at, _InvalidMethodTypeParams, "methods cannot have type parameters")
+			check.error(at, InvalidMethodTypeParams, "methods cannot have type parameters")
 		}
 
 		// use named receiver type if available (for better error messages)
diff --git a/src/go/types/issues_test.go b/src/go/types/issues_test.go
index bd98f48..b4845b1 100644
--- a/src/go/types/issues_test.go
+++ b/src/go/types/issues_test.go
@@ -7,13 +7,12 @@
 package types_test
 
 import (
-	"bytes"
 	"fmt"
 	"go/ast"
 	"go/importer"
-	"go/parser"
 	"go/token"
 	"internal/testenv"
+	"regexp"
 	"sort"
 	"strings"
 	"testing"
@@ -21,18 +20,11 @@
 	. "go/types"
 )
 
-func mustParse(t *testing.T, src string) *ast.File {
-	f, err := parser.ParseFile(fset, "", src, 0)
-	if err != nil {
-		t.Fatal(err)
-	}
-	return f
-}
 func TestIssue5770(t *testing.T) {
-	f := mustParse(t, `package p; type S struct{T}`)
+	f := mustParse(fset, "", `package p; type S struct{T}`)
 	conf := Config{Importer: importer.Default()}
 	_, err := conf.Check(f.Name.Name, fset, []*ast.File{f}, nil) // do not crash
-	want := "undeclared name: T"
+	const want = "undefined: T"
 	if err == nil || !strings.Contains(err.Error(), want) {
 		t.Errorf("got: %v; want: %s", err, want)
 	}
@@ -50,14 +42,8 @@
 	_ = (interface{})("foo")
 	_ = (interface{})(nil)
 )`
-	f := mustParse(t, src)
-
-	var conf Config
 	types := make(map[ast.Expr]TypeAndValue)
-	_, err := conf.Check(f.Name.Name, fset, []*ast.File{f}, &Info{Types: types})
-	if err != nil {
-		t.Fatal(err)
-	}
+	mustTypecheck("p", src, &Info{Types: types})
 
 	for x, tv := range types {
 		var want Type
@@ -95,14 +81,8 @@
 	return 0
 }
 `
-	f := mustParse(t, src)
-
-	var conf Config
 	types := make(map[ast.Expr]TypeAndValue)
-	_, err := conf.Check(f.Name.Name, fset, []*ast.File{f}, &Info{Types: types})
-	if err != nil {
-		t.Fatal(err)
-	}
+	mustTypecheck("p", src, &Info{Types: types})
 
 	want := Typ[Int]
 	n := 0
@@ -126,7 +106,7 @@
 func (T) m() (res bool) { return }
 type T struct{} // receiver type after method declaration
 `
-	f := mustParse(t, src)
+	f := mustParse(fset, "", src)
 
 	var conf Config
 	defs := make(map[*ast.Ident]Object)
@@ -157,7 +137,7 @@
         _, _, _ = x, y, z  // uses x, y, z
 }
 `
-	f := mustParse(t, src)
+	f := mustParse(fset, "", src)
 
 	const want = `L3 defs func p._()
 L4 defs const w untyped int
@@ -253,7 +233,7 @@
 }
 `
 	f := func(test, src string) {
-		f := mustParse(t, src)
+		f := mustParse(fset, "", src)
 		cfg := Config{Importer: importer.Default()}
 		info := Info{Uses: make(map[*ast.Ident]Object)}
 		_, err := cfg.Check("main", fset, []*ast.File{f}, &info)
@@ -283,17 +263,17 @@
 }
 
 func TestIssue22525(t *testing.T) {
-	f := mustParse(t, `package p; func f() { var a, b, c, d, e int }`)
+	f := mustParse(fset, "", `package p; func f() { var a, b, c, d, e int }`)
 
 	got := "\n"
 	conf := Config{Error: func(err error) { got += err.Error() + "\n" }}
 	conf.Check(f.Name.Name, fset, []*ast.File{f}, nil) // do not crash
 	want := `
-1:27: a declared but not used
-1:30: b declared but not used
-1:33: c declared but not used
-1:36: d declared but not used
-1:39: e declared but not used
+1:27: a declared and not used
+1:30: b declared and not used
+1:33: c declared and not used
+1:36: d declared and not used
+1:39: e declared and not used
 `
 	if got != want {
 		t.Errorf("got: %swant: %s", got, want)
@@ -313,7 +293,7 @@
 		`struct { *I }`,
 		`struct { a int; b Missing; *Missing }`,
 	} {
-		f := mustParse(t, prefix+src)
+		f := mustParse(fset, "", prefix+src)
 
 		cfg := Config{Importer: importer.Default(), Error: func(err error) {}}
 		info := &Info{Types: make(map[ast.Expr]TypeAndValue)}
@@ -350,7 +330,7 @@
 	// compute original file ASTs
 	var orig [len(sources)]*ast.File
 	for i, src := range sources {
-		orig[i] = mustParse(t, src)
+		orig[i] = mustParse(fset, "", src)
 	}
 
 	// run the test for all order permutations of the incoming files
@@ -424,12 +404,12 @@
 }
 
 func TestIssue29029(t *testing.T) {
-	f1 := mustParse(t, `package p; type A interface { M() }`)
-	f2 := mustParse(t, `package p; var B interface { A }`)
+	f1 := mustParse(fset, "", `package p; type A interface { M() }`)
+	f2 := mustParse(fset, "", `package p; var B interface { A }`)
 
 	// printInfo prints the *Func definitions recorded in info, one *Func per line.
 	printInfo := func(info *Info) string {
-		var buf bytes.Buffer
+		var buf strings.Builder
 		for _, obj := range info.Defs {
 			if fn, ok := obj.(*Func); ok {
 				fmt.Fprintln(&buf, fn)
@@ -471,12 +451,9 @@
 	const asrc = `package a; type I interface{ M() }; type T struct { F interface { I } }`
 	const bsrc = `package b; import "a"; type T struct { F interface { a.I } }; var _ = a.T(T{})`
 
-	a, err := pkgFor("a", asrc, nil)
-	if err != nil {
-		t.Fatalf("package %s failed to typecheck: %v", a.Name(), err)
-	}
+	a := mustTypecheck("a", asrc, nil)
 
-	bast := mustParse(t, bsrc)
+	bast := mustParse(fset, "", bsrc)
 	conf := Config{Importer: importHelper{pkg: a}}
 	b, err := conf.Check(bast.Name.Name, fset, []*ast.File{bast}, nil)
 	if err != nil {
@@ -519,7 +496,7 @@
 
 	var pkg *Package
 	for _, src := range sources {
-		f := mustParse(t, src)
+		f := mustParse(fset, "", src)
 		conf := Config{Importer: importHelper{pkg: pkg}}
 		res, err := conf.Check(f.Name.Name, fset, []*ast.File{f}, nil)
 		if err != nil {
@@ -579,6 +556,8 @@
 func TestIssue43124(t *testing.T) {
 	// TODO(rFindley) move this to testdata by enhancing support for importing.
 
+	testenv.MustHaveGoBuild(t) // The go command is needed for the importer to determine the locations of stdlib .a files.
+
 	// All involved packages have the same name (template). Error messages should
 	// disambiguate between text/template and html/template by printing the full
 	// path.
@@ -628,10 +607,7 @@
 `
 	)
 
-	a, err := pkgFor("a", asrc, nil)
-	if err != nil {
-		t.Fatalf("package a failed to typecheck: %v", err)
-	}
+	a := mustTypecheck("a", asrc, nil)
 	imp := importHelper{pkg: a, fallback: importer.Default()}
 
 	testFiles(t, nil, []string{"b.go"}, [][]byte{[]byte(bsrc)}, false, imp)
@@ -644,23 +620,235 @@
 	comparableType := Universe.Lookup("comparable").Type()
 
 	if !Comparable(anyType) {
-		t.Errorf("any is not a comparable type")
+		t.Error("any is not a comparable type")
 	}
 	if !Comparable(comparableType) {
-		t.Errorf("comparable is not a comparable type")
+		t.Error("comparable is not a comparable type")
 	}
 
 	if Implements(anyType, comparableType.Underlying().(*Interface)) {
-		t.Errorf("any implements comparable")
+		t.Error("any implements comparable")
 	}
 	if !Implements(comparableType, anyType.(*Interface)) {
-		t.Errorf("comparable does not implement any")
+		t.Error("comparable does not implement any")
 	}
 
 	if AssignableTo(anyType, comparableType) {
-		t.Errorf("any assignable to comparable")
+		t.Error("any assignable to comparable")
 	}
 	if !AssignableTo(comparableType, anyType) {
-		t.Errorf("comparable not assignable to any")
+		t.Error("comparable not assignable to any")
+	}
+}
+
+func TestIssue55030(t *testing.T) {
+	// makeSig makes the signature func(typ...)
+	makeSig := func(typ Type) {
+		par := NewVar(token.NoPos, nil, "", typ)
+		params := NewTuple(par)
+		NewSignatureType(nil, nil, nil, params, nil, true)
+	}
+
+	// makeSig must not panic for the following (example) types:
+	// []int
+	makeSig(NewSlice(Typ[Int]))
+
+	// string
+	makeSig(Typ[String])
+
+	// P where P's core type is string
+	{
+		P := NewTypeName(token.NoPos, nil, "P", nil) // [P string]
+		makeSig(NewTypeParam(P, NewInterfaceType(nil, []Type{Typ[String]})))
+	}
+
+	// P where P's core type is an (unnamed) slice
+	{
+		P := NewTypeName(token.NoPos, nil, "P", nil) // [P []int]
+		makeSig(NewTypeParam(P, NewInterfaceType(nil, []Type{NewSlice(Typ[Int])})))
+	}
+
+	// P where P's core type is bytestring (i.e., string or []byte)
+	{
+		t1 := NewTerm(true, Typ[String])             // ~string
+		t2 := NewTerm(false, NewSlice(Typ[Byte]))    // []byte
+		u := NewUnion([]*Term{t1, t2})               // ~string | []byte
+		P := NewTypeName(token.NoPos, nil, "P", nil) // [P ~string | []byte]
+		makeSig(NewTypeParam(P, NewInterfaceType(nil, []Type{u})))
+	}
+}
+
+func TestIssue51093(t *testing.T) {
+	// Each test stands for a conversion of the form P(val)
+	// where P is a type parameter with typ as constraint.
+	// The test ensures that P(val) has the correct type P
+	// and is not a constant.
+	var tests = []struct {
+		typ string
+		val string
+	}{
+		{"bool", "false"},
+		{"int", "-1"},
+		{"uint", "1.0"},
+		{"rune", "'a'"},
+		{"float64", "3.5"},
+		{"complex64", "1.25"},
+		{"string", "\"foo\""},
+
+		// some more complex constraints
+		{"~byte", "1"},
+		{"~int | ~float64 | complex128", "1"},
+		{"~uint64 | ~rune", "'X'"},
+	}
+
+	for _, test := range tests {
+		src := fmt.Sprintf("package p; func _[P %s]() { _ = P(%s) }", test.typ, test.val)
+		types := make(map[ast.Expr]TypeAndValue)
+		mustTypecheck("p", src, &Info{Types: types})
+
+		var n int
+		for x, tv := range types {
+			if x, _ := x.(*ast.CallExpr); x != nil {
+				// there must be exactly one CallExpr which is the P(val) conversion
+				n++
+				tpar, _ := tv.Type.(*TypeParam)
+				if tpar == nil {
+					t.Fatalf("%s: got type %s, want type parameter", ExprString(x), tv.Type)
+				}
+				if name := tpar.Obj().Name(); name != "P" {
+					t.Fatalf("%s: got type parameter name %s, want P", ExprString(x), name)
+				}
+				// P(val) must not be constant
+				if tv.Value != nil {
+					t.Errorf("%s: got constant value %s (%s), want no constant", ExprString(x), tv.Value, tv.Value.String())
+				}
+			}
+		}
+
+		if n != 1 {
+			t.Fatalf("%s: got %d CallExpr nodes; want 1", src, 1)
+		}
+	}
+}
+
+func TestIssue54258(t *testing.T) {
+
+	tests := []struct{ main, b, want string }{
+		{ //---------------------------------------------------------------
+			`package main
+import "b"
+type I0 interface {
+	M0(w struct{ f string })
+}
+var _ I0 = b.S{}
+`,
+			`package b
+type S struct{}
+func (S) M0(struct{ f string }) {}
+`,
+			`6:12: cannot use b[.]S{} [(]value of type b[.]S[)] as I0 value in variable declaration: b[.]S does not implement I0 [(]wrong type for method M0[)]
+.*have M0[(]struct{f string /[*] package b [*]/ }[)]
+.*want M0[(]struct{f string /[*] package main [*]/ }[)]`},
+
+		{ //---------------------------------------------------------------
+			`package main
+import "b"
+type I1 interface {
+	M1(struct{ string })
+}
+var _ I1 = b.S{}
+`,
+			`package b
+type S struct{}
+func (S) M1(struct{ string }) {}
+`,
+			`6:12: cannot use b[.]S{} [(]value of type b[.]S[)] as I1 value in variable declaration: b[.]S does not implement I1 [(]wrong type for method M1[)]
+.*have M1[(]struct{string /[*] package b [*]/ }[)]
+.*want M1[(]struct{string /[*] package main [*]/ }[)]`},
+
+		{ //---------------------------------------------------------------
+			`package main
+import "b"
+type I2 interface {
+	M2(y struct{ f struct{ f string } })
+}
+var _ I2 = b.S{}
+`,
+			`package b
+type S struct{}
+func (S) M2(struct{ f struct{ f string } }) {}
+`,
+			`6:12: cannot use b[.]S{} [(]value of type b[.]S[)] as I2 value in variable declaration: b[.]S does not implement I2 [(]wrong type for method M2[)]
+.*have M2[(]struct{f struct{f string} /[*] package b [*]/ }[)]
+.*want M2[(]struct{f struct{f string} /[*] package main [*]/ }[)]`},
+
+		{ //---------------------------------------------------------------
+			`package main
+import "b"
+type I3 interface {
+	M3(z struct{ F struct{ f string } })
+}
+var _ I3 = b.S{}
+`,
+			`package b
+type S struct{}
+func (S) M3(struct{ F struct{ f string } }) {}
+`,
+			`6:12: cannot use b[.]S{} [(]value of type b[.]S[)] as I3 value in variable declaration: b[.]S does not implement I3 [(]wrong type for method M3[)]
+.*have M3[(]struct{F struct{f string /[*] package b [*]/ }}[)]
+.*want M3[(]struct{F struct{f string /[*] package main [*]/ }}[)]`},
+
+		{ //---------------------------------------------------------------
+			`package main
+import "b"
+type I4 interface {
+	M4(_ struct { *string })
+}
+var _ I4 = b.S{}
+`,
+			`package b
+type S struct{}
+func (S) M4(struct { *string }) {}
+`,
+			`6:12: cannot use b[.]S{} [(]value of type b[.]S[)] as I4 value in variable declaration: b[.]S does not implement I4 [(]wrong type for method M4[)]
+.*have M4[(]struct{[*]string /[*] package b [*]/ }[)]
+.*want M4[(]struct{[*]string /[*] package main [*]/ }[)]`},
+
+		{ //---------------------------------------------------------------
+			`package main
+import "b"
+type t struct{ A int }
+type I5 interface {
+	M5(_ struct {b.S;t})
+}
+var _ I5 = b.S{}
+`,
+			`package b
+type S struct{}
+type t struct{ A int }
+func (S) M5(struct {S;t}) {}
+`,
+			`7:12: cannot use b[.]S{} [(]value of type b[.]S[)] as I5 value in variable declaration: b[.]S does not implement I5 [(]wrong type for method M5[)]
+.*have M5[(]struct{b[.]S; b[.]t}[)]
+.*want M5[(]struct{b[.]S; t}[)]`},
+	}
+
+	fset := token.NewFileSet()
+	test := func(main, b, want string) {
+		re := regexp.MustCompile(want)
+		bpkg := mustTypecheck("b", b, nil)
+		mast := mustParse(fset, "main.go", main)
+		conf := Config{Importer: importHelper{pkg: bpkg}}
+		_, err := conf.Check(mast.Name.Name, fset, []*ast.File{mast}, nil)
+		if err == nil {
+			t.Error("Expected failure, but it did not")
+		} else if got := err.Error(); !re.MatchString(got) {
+			t.Errorf("Wanted match for\n\t%s\n but got\n\t%s", want, got)
+		} else if testing.Verbose() {
+			t.Logf("Saw expected\n\t%s", err.Error())
+		}
+	}
+	for _, t := range tests {
+		test(t.main, t.b, t.want)
 	}
 }
diff --git a/src/go/types/labels.go b/src/go/types/labels.go
index f3b7f21..5ee941e 100644
--- a/src/go/types/labels.go
+++ b/src/go/types/labels.go
@@ -7,6 +7,7 @@
 import (
 	"go/ast"
 	"go/token"
+	. "internal/types/errors"
 )
 
 // labels checks correct label use in body.
@@ -22,15 +23,15 @@
 	// for the respective gotos.
 	for _, jmp := range fwdJumps {
 		var msg string
-		var code errorCode
+		var code Code
 		name := jmp.Label.Name
 		if alt := all.Lookup(name); alt != nil {
 			msg = "goto %s jumps into block"
 			alt.(*Label).used = true // avoid another error
-			code = _JumpIntoBlock
+			code = JumpIntoBlock
 		} else {
 			msg = "label %s not declared"
-			code = _UndeclaredLabel
+			code = UndeclaredLabel
 		}
 		check.errorf(jmp.Label, code, msg, name)
 	}
@@ -39,7 +40,7 @@
 	for name, obj := range all.elems {
 		obj = resolve(name, obj)
 		if lbl := obj.(*Label); !lbl.used {
-			check.softErrorf(lbl, _UnusedLabel, "label %s declared but not used", lbl.name)
+			check.softErrorf(lbl, UnusedLabel, "label %s declared and not used", lbl.name)
 		}
 	}
 }
@@ -137,7 +138,7 @@
 			if name := s.Label.Name; name != "_" {
 				lbl := NewLabel(s.Label.Pos(), check.pkg, name)
 				if alt := all.Insert(lbl); alt != nil {
-					check.softErrorf(lbl, _DuplicateLabel, "label %s already declared", name)
+					check.softErrorf(lbl, DuplicateLabel, "label %s already declared", name)
 					check.reportAltDecl(alt)
 					// ok to continue
 				} else {
@@ -154,7 +155,7 @@
 						if jumpsOverVarDecl(jmp) {
 							check.softErrorf(
 								jmp.Label,
-								_JumpOverDecl,
+								JumpOverDecl,
 								"goto %s jumps over variable declaration at line %d",
 								name,
 								check.fset.Position(varDeclPos).Line,
@@ -192,7 +193,7 @@
 					}
 				}
 				if !valid {
-					check.errorf(s.Label, _MisplacedLabel, "invalid break label %s", name)
+					check.errorf(s.Label, MisplacedLabel, "invalid break label %s", name)
 					return
 				}
 
@@ -207,7 +208,7 @@
 					}
 				}
 				if !valid {
-					check.errorf(s.Label, _MisplacedLabel, "invalid continue label %s", name)
+					check.errorf(s.Label, MisplacedLabel, "invalid continue label %s", name)
 					return
 				}
 
@@ -219,7 +220,7 @@
 				}
 
 			default:
-				check.invalidAST(s, "branch statement: %s %s", s.Tok, name)
+				check.errorf(s, InvalidSyntaxTree, "branch statement: %s %s", s.Tok, name)
 				return
 			}
 
diff --git a/src/go/types/lookup.go b/src/go/types/lookup.go
index 305b200..4eedcc2 100644
--- a/src/go/types/lookup.go
+++ b/src/go/types/lookup.go
@@ -261,10 +261,18 @@
 }
 
 type instanceLookup struct {
-	m map[*Named][]*Named
+	// buf is used to avoid allocating the map m in the common case of a small
+	// number of instances.
+	buf [3]*Named
+	m   map[*Named][]*Named
 }
 
 func (l *instanceLookup) lookup(inst *Named) *Named {
+	for _, t := range l.buf {
+		if t != nil && Identical(inst, t) {
+			return t
+		}
+	}
 	for _, t := range l.m[inst.Origin()] {
 		if Identical(inst, t) {
 			return t
@@ -274,6 +282,12 @@
 }
 
 func (l *instanceLookup) add(inst *Named) {
+	for i, t := range l.buf {
+		if t == nil {
+			l.buf[i] = inst
+			return
+		}
+	}
 	if l.m == nil {
 		l.m = make(map[*Named][]*Named)
 	}
@@ -364,32 +378,33 @@
 	return
 }
 
-// missingMethodReason returns a string giving the detailed reason for a missing method m,
-// where m is missing from V, but required by T. It puts the reason in parentheses,
+// missingMethodCause returns a string giving the detailed cause for a missing method m,
+// where m is missing from V, but required by T. It puts the cause in parentheses,
 // and may include more have/want info after that. If non-nil, alt is a relevant
 // method that matches in some way. It may have the correct name, but wrong type, or
 // it may have a pointer receiver, or it may have the correct name except wrong case.
 // check may be nil.
-func (check *Checker) missingMethodReason(V, T Type, m, alt *Func) string {
-	var mname string
-	if check != nil && compilerErrorMessages {
-		mname = m.Name() + " method"
-	} else {
-		mname = "method " + m.Name()
-	}
+func (check *Checker) missingMethodCause(V, T Type, m, alt *Func) string {
+	mname := "method " + m.Name()
 
 	if alt != nil {
 		if m.Name() != alt.Name() {
 			return check.sprintf("(missing %s)\n\t\thave %s\n\t\twant %s",
-				mname, check.funcString(alt), check.funcString(m))
+				mname, check.funcString(alt, false), check.funcString(m, false))
 		}
 
 		if Identical(m.typ, alt.typ) {
 			return check.sprintf("(%s has pointer receiver)", mname)
 		}
 
+		altS, mS := check.funcString(alt, false), check.funcString(m, false)
+		if altS == mS {
+			// Would tell the user that Foo isn't a Foo, add package information to disambiguate.  See #54258.
+			altS, mS = check.funcString(alt, true), check.funcString(m, true)
+		}
+
 		return check.sprintf("(wrong type for %s)\n\t\thave %s\n\t\twant %s",
-			mname, check.funcString(alt), check.funcString(m))
+			mname, altS, mS)
 	}
 
 	if isInterfacePtr(V) {
@@ -400,6 +415,11 @@
 		return "(" + check.interfacePtrError(T) + ")"
 	}
 
+	obj, _, _ := lookupFieldOrMethod(V, true /* auto-deref */, m.pkg, m.name, false)
+	if fld, _ := obj.(*Var); fld != nil {
+		return check.sprintf("(%s.%s is a field, not a method)", V, fld.Name())
+	}
+
 	return check.sprintf("(missing %s)", mname)
 }
 
@@ -417,14 +437,18 @@
 	return check.sprintf("type %s is pointer to interface, not interface", T)
 }
 
+// funcString returns a string of the form name + signature for f.
 // check may be nil.
-func (check *Checker) funcString(f *Func) string {
+func (check *Checker) funcString(f *Func, pkgInfo bool) string {
 	buf := bytes.NewBufferString(f.name)
 	var qf Qualifier
-	if check != nil {
+	if check != nil && !pkgInfo {
 		qf = check.qualifier
 	}
-	WriteSignature(buf, f.typ.(*Signature), qf)
+	w := newTypeWriter(buf, qf)
+	w.pkgInfo = pkgInfo
+	w.paramNames = false
+	w.signature(f.typ.(*Signature))
 	return buf.String()
 }
 
@@ -448,14 +472,14 @@
 // newAssertableTo reports whether a value of type V can be asserted to have type T.
 // It also implements behavior for interfaces that currently are only permitted
 // in constraint position (we have not yet defined that behavior in the spec).
-func (check *Checker) newAssertableTo(V *Interface, T Type) error {
+func (check *Checker) newAssertableTo(V *Interface, T Type) bool {
 	// no static check is required if T is an interface
 	// spec: "If T is an interface type, x.(T) asserts that the
 	//        dynamic type of x implements the interface T."
 	if IsInterface(T) {
-		return nil
+		return true
 	}
-	return check.implements(T, V)
+	return check.implements(T, V, false, nil)
 }
 
 // deref dereferences typ if it is a *Pointer and returns its base and true.
diff --git a/src/go/types/lookup_test.go b/src/go/types/lookup_test.go
new file mode 100644
index 0000000..d3ca58b
--- /dev/null
+++ b/src/go/types/lookup_test.go
@@ -0,0 +1,58 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types_test
+
+import (
+	"go/importer"
+	"go/token"
+	"path/filepath"
+	"runtime"
+	"testing"
+
+	. "go/types"
+)
+
+// BenchmarkLookupFieldOrMethod measures types.LookupFieldOrMethod performance.
+// LookupFieldOrMethod is a performance hotspot for both type-checking and
+// external API calls.
+func BenchmarkLookupFieldOrMethod(b *testing.B) {
+	// Choose an arbitrary, large package.
+	path := filepath.Join(runtime.GOROOT(), "src", "net", "http")
+
+	fset := token.NewFileSet()
+	files, err := pkgFiles(fset, path)
+	if err != nil {
+		b.Fatal(err)
+	}
+
+	conf := Config{
+		Importer: importer.Default(),
+	}
+
+	pkg, err := conf.Check("http", fset, files, nil)
+	if err != nil {
+		b.Fatal(err)
+	}
+
+	scope := pkg.Scope()
+	names := scope.Names()
+
+	// Look up an arbitrary name for each type referenced in the package scope.
+	lookup := func() {
+		for _, name := range names {
+			typ := scope.Lookup(name).Type()
+			LookupFieldOrMethod(typ, true, pkg, "m")
+		}
+	}
+
+	// Perform a lookup once, to ensure that any lazily-evaluated state is
+	// complete.
+	lookup()
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		lookup()
+	}
+}
diff --git a/src/go/types/methodset_test.go b/src/go/types/methodset_test.go
index 610329e..443994b 100644
--- a/src/go/types/methodset_test.go
+++ b/src/go/types/methodset_test.go
@@ -84,11 +84,7 @@
 	}
 
 	check := func(src string, methods []method, generic bool) {
-		pkg, err := pkgForMode("test", "package p;"+src, nil, 0)
-		if err != nil {
-			t.Errorf("%s: incorrect test case: %s", src, err)
-			return
-		}
+		pkg := mustTypecheck("test", "package p;"+src, nil)
 
 		scope := pkg.Scope()
 		if generic {
diff --git a/src/go/types/mono.go b/src/go/types/mono.go
index 84e1e97..cf3f5a8 100644
--- a/src/go/types/mono.go
+++ b/src/go/types/mono.go
@@ -7,6 +7,7 @@
 import (
 	"go/ast"
 	"go/token"
+	. "internal/types/errors"
 )
 
 // This file implements a check to validate that a Go package doesn't
@@ -138,7 +139,7 @@
 	// TODO(mdempsky): Pivot stack so we report the cycle from the top?
 
 	obj0 := check.mono.vertices[v].obj
-	check.errorf(obj0, _InvalidInstanceCycle, "instantiation cycle:")
+	check.error(obj0, InvalidInstanceCycle, "instantiation cycle:")
 
 	qf := RelativeTo(check.pkg)
 	for _, v := range stack {
@@ -149,9 +150,9 @@
 		default:
 			panic("unexpected type")
 		case *Named:
-			check.errorf(atPos(edge.pos), _InvalidInstanceCycle, "\t%s implicitly parameterized by %s", obj.Name(), TypeString(edge.typ, qf)) // secondary error, \t indented
+			check.errorf(atPos(edge.pos), InvalidInstanceCycle, "\t%s implicitly parameterized by %s", obj.Name(), TypeString(edge.typ, qf)) // secondary error, \t indented
 		case *TypeParam:
-			check.errorf(atPos(edge.pos), _InvalidInstanceCycle, "\t%s instantiated as %s", obj.Name(), TypeString(edge.typ, qf)) // secondary error, \t indented
+			check.errorf(atPos(edge.pos), InvalidInstanceCycle, "\t%s instantiated as %s", obj.Name(), TypeString(edge.typ, qf)) // secondary error, \t indented
 		}
 	}
 }
diff --git a/src/go/types/mono_test.go b/src/go/types/mono_test.go
index 5df3d49..02daa4f 100644
--- a/src/go/types/mono_test.go
+++ b/src/go/types/mono_test.go
@@ -5,7 +5,6 @@
 package types_test
 
 import (
-	"bytes"
 	"errors"
 	"fmt"
 	"go/ast"
@@ -25,7 +24,7 @@
 	}
 	files := []*ast.File{file}
 
-	var buf bytes.Buffer
+	var buf strings.Builder
 	conf := types.Config{
 		Error:    func(err error) { fmt.Fprintln(&buf, err) },
 		Importer: importer.Default(),
diff --git a/src/go/types/named_test.go b/src/go/types/named_test.go
index 0fe1741..92f17e5 100644
--- a/src/go/types/named_test.go
+++ b/src/go/types/named_test.go
@@ -6,7 +6,6 @@
 
 import (
 	"go/ast"
-	"go/parser"
 	"go/token"
 	"testing"
 
@@ -33,10 +32,7 @@
 
 type Inst = G[int]
 	`
-	pkg, err := pkgForMode("p", src, nil, 0)
-	if err != nil {
-		b.Fatal(err)
-	}
+	pkg := mustTypecheck("p", src, nil)
 
 	var (
 		T        = pkg.Scope().Lookup("T").Type()
@@ -111,10 +107,7 @@
 `
 
 	fset := token.NewFileSet()
-	f, err := parser.ParseFile(fset, "foo.go", src, 0)
-	if err != nil {
-		t.Fatal(err)
-	}
+	f := mustParse(fset, "foo.go", src)
 	pkg := NewPackage("p", f.Name.Name)
 	if err := NewChecker(nil, fset, pkg, nil).Files([]*ast.File{f}); err != nil {
 		t.Fatal(err)
diff --git a/src/go/types/object.go b/src/go/types/object.go
index f203b01..6e63948 100644
--- a/src/go/types/object.go
+++ b/src/go/types/object.go
@@ -469,7 +469,7 @@
 
 	// For package-level objects, qualify the name.
 	if obj.Pkg() != nil && obj.Pkg().scope.Lookup(obj.Name()) == obj {
-		writePackage(buf, obj.Pkg(), qf)
+		buf.WriteString(packagePrefix(obj.Pkg(), qf))
 	}
 	buf.WriteString(obj.Name())
 
@@ -510,9 +510,9 @@
 	WriteType(buf, typ, qf)
 }
 
-func writePackage(buf *bytes.Buffer, pkg *Package, qf Qualifier) {
+func packagePrefix(pkg *Package, qf Qualifier) string {
 	if pkg == nil {
-		return
+		return ""
 	}
 	var s string
 	if qf != nil {
@@ -521,9 +521,9 @@
 		s = pkg.Path()
 	}
 	if s != "" {
-		buf.WriteString(s)
-		buf.WriteByte('.')
+		s += "."
 	}
+	return s
 }
 
 // ObjectString returns the string form of obj.
@@ -561,7 +561,7 @@
 			buf.WriteByte(')')
 			buf.WriteByte('.')
 		} else if f.pkg != nil {
-			writePackage(buf, f.pkg, qf)
+			buf.WriteString(packagePrefix(f.pkg, qf))
 		}
 	}
 	buf.WriteString(f.name)
diff --git a/src/go/types/object_test.go b/src/go/types/object_test.go
index 47c7fcd..60e7a84 100644
--- a/src/go/types/object_test.go
+++ b/src/go/types/object_test.go
@@ -6,7 +6,6 @@
 
 import (
 	"go/ast"
-	"go/parser"
 	"go/token"
 	"internal/testenv"
 	"strings"
@@ -62,10 +61,7 @@
 
 	// type-check src
 	fset := token.NewFileSet()
-	f, err := parser.ParseFile(fset, "", src, 0)
-	if err != nil {
-		t.Fatalf("parse failed: %s", err)
-	}
+	f := mustParse(fset, "", src)
 	var conf Config
 	pkg, err := conf.Check(f.Name.Name, fset, []*ast.File{f}, nil)
 	if err != nil {
@@ -124,7 +120,7 @@
 
 	for _, test := range testObjects {
 		src := "package p; " + test.src
-		pkg, err := makePkg(src)
+		pkg, err := typecheck(filename, src, nil)
 		if err != nil {
 			t.Errorf("%s: %s", src, err)
 			continue
diff --git a/src/go/types/operand.go b/src/go/types/operand.go
index f9f109a..819c99e 100644
--- a/src/go/types/operand.go
+++ b/src/go/types/operand.go
@@ -11,6 +11,7 @@
 	"go/ast"
 	"go/constant"
 	"go/token"
+	. "internal/types/errors"
 )
 
 // An operandMode specifies the (addressing) mode of an operand.
@@ -161,7 +162,7 @@
 		if x.typ != Typ[Invalid] {
 			var intro string
 			if isGeneric(x.typ) {
-				intro = " of parameterized type "
+				intro = " of generic type "
 			} else {
 				intro = " of type "
 			}
@@ -170,6 +171,10 @@
 			if tpar, _ := x.typ.(*TypeParam); tpar != nil {
 				buf.WriteString(" constrained by ")
 				WriteType(&buf, tpar.bound, qf) // do not compute interface type sets here
+				// If we have the type set and it's empty, say so for better error messages.
+				if hasEmptyTypeset(tpar) {
+					buf.WriteString(" with empty type set")
+				}
 			}
 		} else {
 			buf.WriteString(" with invalid type")
@@ -223,12 +228,12 @@
 }
 
 // assignableTo reports whether x is assignable to a variable of type T. If the
-// result is false and a non-nil reason is provided, it may be set to a more
+// result is false and a non-nil cause is provided, it may be set to a more
 // detailed explanation of the failure (result != ""). The returned error code
 // is only valid if the (first) result is false. The check parameter may be nil
 // if assignableTo is invoked through an exported API call, i.e., when all
 // methods have been type-checked.
-func (x *operand) assignableTo(check *Checker, T Type, reason *string) (bool, errorCode) {
+func (x *operand) assignableTo(check *Checker, T Type, cause *string) (bool, Code) {
 	if x.mode == invalid || T == Typ[Invalid] {
 		return true, 0 // avoid spurious errors
 	}
@@ -260,10 +265,10 @@
 				// don't need to do anything special.
 				newType, _, _ := check.implicitTypeAndValue(x, t.typ)
 				return newType != nil
-			}), _IncompatibleAssign
+			}), IncompatibleAssign
 		}
 		newType, _, _ := check.implicitTypeAndValue(x, T)
-		return newType != nil, _IncompatibleAssign
+		return newType != nil, IncompatibleAssign
 	}
 	// Vu is typed
 
@@ -277,23 +282,20 @@
 	// T is an interface type and x implements T and T is not a type parameter.
 	// Also handle the case where T is a pointer to an interface.
 	if _, ok := Tu.(*Interface); ok && Tp == nil || isInterfacePtr(Tu) {
-		if err := check.implements(V, T); err != nil {
-			if reason != nil {
-				*reason = err.Error()
-			}
-			return false, _InvalidIfaceAssign
+		if !check.implements(V, T, false, cause) {
+			return false, InvalidIfaceAssign
 		}
 		return true, 0
 	}
 
 	// If V is an interface, check if a missing type assertion is the problem.
 	if Vi, _ := Vu.(*Interface); Vi != nil && Vp == nil {
-		if check.implements(T, V) == nil {
+		if check.implements(T, V, false, nil) {
 			// T implements V, so give hint about type assertion.
-			if reason != nil {
-				*reason = "need type assertion"
+			if cause != nil {
+				*cause = "need type assertion"
 			}
-			return false, _IncompatibleAssign
+			return false, IncompatibleAssign
 		}
 	}
 
@@ -302,22 +304,22 @@
 	// and at least one of V or T is not a named type.
 	if Vc, ok := Vu.(*Chan); ok && Vc.dir == SendRecv {
 		if Tc, ok := Tu.(*Chan); ok && Identical(Vc.elem, Tc.elem) {
-			return !hasName(V) || !hasName(T), _InvalidChanAssign
+			return !hasName(V) || !hasName(T), InvalidChanAssign
 		}
 	}
 
 	// optimization: if we don't have type parameters, we're done
 	if Vp == nil && Tp == nil {
-		return false, _IncompatibleAssign
+		return false, IncompatibleAssign
 	}
 
 	errorf := func(format string, args ...any) {
-		if check != nil && reason != nil {
+		if check != nil && cause != nil {
 			msg := check.sprintf(format, args...)
-			if *reason != "" {
-				msg += "\n\t" + *reason
+			if *cause != "" {
+				msg += "\n\t" + *cause
 			}
-			*reason = msg
+			*cause = msg
 		}
 	}
 
@@ -325,12 +327,12 @@
 	// x is assignable to each specific type in T's type set.
 	if !hasName(V) && Tp != nil {
 		ok := false
-		code := _IncompatibleAssign
+		code := IncompatibleAssign
 		Tp.is(func(T *term) bool {
 			if T == nil {
 				return false // no specific types
 			}
-			ok, code = x.assignableTo(check, T.typ, reason)
+			ok, code = x.assignableTo(check, T.typ, cause)
 			if !ok {
 				errorf("cannot assign %s to %s (in %s)", x.typ, T.typ, Tp)
 				return false
@@ -346,13 +348,13 @@
 	if Vp != nil && !hasName(T) {
 		x := *x // don't clobber outer x
 		ok := false
-		code := _IncompatibleAssign
+		code := IncompatibleAssign
 		Vp.is(func(V *term) bool {
 			if V == nil {
 				return false // no specific types
 			}
 			x.typ = V.typ
-			ok, code = x.assignableTo(check, T, reason)
+			ok, code = x.assignableTo(check, T, cause)
 			if !ok {
 				errorf("cannot assign %s (in %s) to %s", V.typ, Vp, T)
 				return false
@@ -362,5 +364,5 @@
 		return ok, code
 	}
 
-	return false, _IncompatibleAssign
+	return false, IncompatibleAssign
 }
diff --git a/src/go/types/package.go b/src/go/types/package.go
index 26385dc..2b72ff1 100644
--- a/src/go/types/package.go
+++ b/src/go/types/package.go
@@ -60,6 +60,9 @@
 // If pkg was loaded from export data, Imports includes packages that
 // provide package-level objects referenced by pkg. This may be more or
 // less than the set of packages directly imported by pkg's source code.
+//
+// If pkg uses cgo and the FakeImportC configuration option
+// was enabled, the imports list may contain a fake "C" package.
 func (pkg *Package) Imports() []*Package { return pkg.imports }
 
 // SetImports sets the list of explicitly imported packages to list.
diff --git a/src/go/types/predicates.go b/src/go/types/predicates.go
index aaf4dd5..e9a0e43 100644
--- a/src/go/types/predicates.go
+++ b/src/go/types/predicates.go
@@ -98,6 +98,18 @@
 	return ok
 }
 
+// hasEmptyTypeset reports whether t is a type parameter with an empty type set.
+// The function does not force the computation of the type set and so is safe to
+// use anywhere, but it may report a false negative if the type set has not been
+// computed yet.
+func hasEmptyTypeset(t Type) bool {
+	if tpar, _ := t.(*TypeParam); tpar != nil && tpar.bound != nil {
+		iface, _ := safeUnderlying(tpar.bound).(*Interface)
+		return iface != nil && iface.tset != nil && iface.tset.IsEmpty()
+	}
+	return false
+}
+
 // isGeneric reports whether a type is a generic, uninstantiated type
 // (generic signatures are not included).
 // TODO(gri) should we include signatures or assert that they are not present?
diff --git a/src/go/types/resolver.go b/src/go/types/resolver.go
index ae21c6d..075bd91 100644
--- a/src/go/types/resolver.go
+++ b/src/go/types/resolver.go
@@ -10,6 +10,7 @@
 	"go/constant"
 	"go/internal/typeparams"
 	"go/token"
+	. "internal/types/errors"
 	"sort"
 	"strconv"
 	"strings"
@@ -57,23 +58,23 @@
 		r = len(init.Values)
 	}
 
-	const code = _WrongAssignCount
+	const code = WrongAssignCount
 	switch {
 	case init == nil && r == 0:
 		// var decl w/o init expr
 		if s.Type == nil {
-			check.errorf(s, code, "missing type or init expr")
+			check.error(s, code, "missing type or init expr")
 		}
 	case l < r:
 		if l < len(s.Values) {
 			// init exprs from s
 			n := s.Values[l]
 			check.errorf(n, code, "extra init expr %s", n)
-			// TODO(gri) avoid declared but not used error here
+			// TODO(gri) avoid declared and not used error here
 		} else {
 			// init exprs "inherited"
 			check.errorf(s, code, "extra init expr at %s", check.fset.Position(init.Pos()))
-			// TODO(gri) avoid declared but not used error here
+			// TODO(gri) avoid declared and not used error here
 		}
 	case l > r && (init != nil || r != 1):
 		n := s.Names[r]
@@ -106,14 +107,14 @@
 	// spec: "A package-scope or file-scope identifier with name init
 	// may only be declared to be a function with this (func()) signature."
 	if ident.Name == "init" {
-		check.errorf(ident, _InvalidInitDecl, "cannot declare init - must be func")
+		check.error(ident, InvalidInitDecl, "cannot declare init - must be func")
 		return
 	}
 
 	// spec: "The main package must have package name main and declare
 	// a function main that takes no arguments and returns no value."
 	if ident.Name == "main" && check.pkg.name == "main" {
-		check.errorf(ident, _InvalidMainDecl, "cannot declare main - must be func")
+		check.error(ident, InvalidMainDecl, "cannot declare main - must be func")
 		return
 	}
 
@@ -171,7 +172,7 @@
 			imp = nil // create fake package below
 		}
 		if err != nil {
-			check.errorf(at, _BrokenImport, "could not import %s (%s)", path, err)
+			check.errorf(at, BrokenImport, "could not import %s (%s)", path, err)
 			if imp == nil {
 				// create a new fake package
 				// come up with a sensible package name (heuristic)
@@ -254,9 +255,12 @@
 			switch d := d.(type) {
 			case importDecl:
 				// import package
+				if d.spec.Path.Value == "" {
+					return // error reported by parser
+				}
 				path, err := validatedImportPath(d.spec.Path.Value)
 				if err != nil {
-					check.errorf(d.spec.Path, _BadImportPath, "invalid import path (%s)", err)
+					check.errorf(d.spec.Path, BadImportPath, "invalid import path (%s)", err)
 					return
 				}
 
@@ -271,13 +275,13 @@
 					name = d.spec.Name.Name
 					if path == "C" {
 						// match 1.17 cmd/compile (not prescribed by spec)
-						check.errorf(d.spec.Name, _ImportCRenamed, `cannot rename import "C"`)
+						check.error(d.spec.Name, ImportCRenamed, `cannot rename import "C"`)
 						return
 					}
 				}
 
 				if name == "init" {
-					check.errorf(d.spec, _InvalidInitDecl, "cannot import package as init - init must be a func")
+					check.error(d.spec, InvalidInitDecl, "cannot import package as init - init must be a func")
 					return
 				}
 
@@ -323,7 +327,7 @@
 							// the object may be imported into more than one file scope
 							// concurrently. See issue #32154.)
 							if alt := fileScope.Lookup(name); alt != nil {
-								check.errorf(d.spec.Name, _DuplicateDecl, "%s redeclared in this block", alt.Name())
+								check.errorf(d.spec.Name, DuplicateDecl, "%s redeclared in this block", alt.Name())
 								check.reportAltDecl(alt)
 							} else {
 								fileScope.insert(name, obj)
@@ -383,7 +387,7 @@
 				}
 			case typeDecl:
 				if d.spec.TypeParams.NumFields() != 0 && !check.allowVersion(pkg, 1, 18) {
-					check.softErrorf(d.spec.TypeParams.List[0], _UnsupportedFeature, "type parameters require go1.18 or later")
+					check.softErrorf(d.spec.TypeParams.List[0], UnsupportedFeature, "type parameter requires go1.18 or later")
 				}
 				obj := NewTypeName(d.spec.Name.Pos(), pkg, d.spec.Name.Name, nil)
 				check.declarePkgObj(d.spec.Name, obj, &declInfo{file: fileScope, tdecl: d.spec})
@@ -394,13 +398,13 @@
 				if d.decl.Recv.NumFields() == 0 {
 					// regular function
 					if d.decl.Recv != nil {
-						check.error(d.decl.Recv, _BadRecv, "method is missing receiver")
+						check.error(d.decl.Recv, BadRecv, "method has no receiver")
 						// treat as function
 					}
 					if name == "init" || (name == "main" && check.pkg.name == "main") {
-						code := _InvalidInitDecl
+						code := InvalidInitDecl
 						if name == "main" {
-							code = _InvalidMainDecl
+							code = InvalidMainDecl
 						}
 						if d.decl.Type.TypeParams.NumFields() != 0 {
 							check.softErrorf(d.decl.Type.TypeParams.List[0], code, "func %s must have no type parameters", name)
@@ -408,7 +412,7 @@
 						}
 						if t := d.decl.Type; t.Params.NumFields() != 0 || t.Results != nil {
 							// TODO(rFindley) Should this be a hard error?
-							check.softErrorf(d.decl, code, "func %s must have no arguments and no return values", name)
+							check.softErrorf(d.decl.Name, code, "func %s must have no arguments and no return values", name)
 						}
 					}
 					if name == "init" {
@@ -418,7 +422,7 @@
 						// init functions must have a body
 						if d.decl.Body == nil {
 							// TODO(gri) make this error message consistent with the others above
-							check.softErrorf(obj, _MissingInitBody, "missing function body")
+							check.softErrorf(obj, MissingInitBody, "missing function body")
 						}
 					} else {
 						check.declare(pkg.scope, d.decl.Name, obj, token.NoPos)
@@ -441,7 +445,7 @@
 					check.recordDef(d.decl.Name, obj)
 				}
 				if d.decl.Type.TypeParams.NumFields() != 0 && !check.allowVersion(pkg, 1, 18) && !hasTParamError {
-					check.softErrorf(d.decl.Type.TypeParams.List[0], _UnsupportedFeature, "type parameters require go1.18 or later")
+					check.softErrorf(d.decl.Type.TypeParams.List[0], UnsupportedFeature, "type parameter requires go1.18 or later")
 				}
 				info := &declInfo{file: fileScope, fdecl: d.decl}
 				// Methods are not package-level objects but we still track them in the
@@ -460,10 +464,10 @@
 			if alt := pkg.scope.Lookup(name); alt != nil {
 				obj = resolve(name, obj)
 				if pkg, ok := obj.(*PkgName); ok {
-					check.errorf(alt, _DuplicateDecl, "%s already declared through import of %s", alt.Name(), pkg.Imported())
+					check.errorf(alt, DuplicateDecl, "%s already declared through import of %s", alt.Name(), pkg.Imported())
 					check.reportAltDecl(pkg)
 				} else {
-					check.errorf(alt, _DuplicateDecl, "%s already declared through dot-import of %s", alt.Name(), obj.Pkg())
+					check.errorf(alt, DuplicateDecl, "%s already declared through dot-import of %s", alt.Name(), obj.Pkg())
 					// TODO(gri) dot-imported objects don't have a position; reportAltDecl won't print anything
 					check.reportAltDecl(obj)
 				}
@@ -526,9 +530,9 @@
 				case *ast.BadExpr:
 					// ignore - error already reported by parser
 				case nil:
-					check.invalidAST(ix.Orig, "parameterized receiver contains nil parameters")
+					check.error(ix.Orig, InvalidSyntaxTree, "parameterized receiver contains nil parameters")
 				default:
-					check.errorf(arg, _BadDecl, "receiver type parameter %s must be an identifier", arg)
+					check.errorf(arg, BadDecl, "receiver type parameter %s must be an identifier", arg)
 				}
 				if par == nil {
 					par = &ast.Ident{NamePos: arg.Pos(), Name: "_"}
@@ -703,9 +707,9 @@
 		elem = elem[i+1:]
 	}
 	if obj.name == "" || obj.name == "." || obj.name == elem {
-		check.softErrorf(obj, _UnusedImport, "%q imported but not used", path)
+		check.softErrorf(obj, UnusedImport, "%q imported and not used", path)
 	} else {
-		check.softErrorf(obj, _UnusedImport, "%q imported but not used as %s", path, obj.name)
+		check.softErrorf(obj, UnusedImport, "%q imported as %s and not used", path, obj.name)
 	}
 }
 
diff --git a/src/go/types/resolver_test.go b/src/go/types/resolver_test.go
index 4bb63b6..376ecfb 100644
--- a/src/go/types/resolver_test.go
+++ b/src/go/types/resolver_test.go
@@ -8,7 +8,6 @@
 	"fmt"
 	"go/ast"
 	"go/importer"
-	"go/parser"
 	"go/token"
 	"internal/testenv"
 	"sort"
@@ -121,11 +120,7 @@
 	fset := token.NewFileSet()
 	var files []*ast.File
 	for i, src := range sources {
-		f, err := parser.ParseFile(fset, fmt.Sprintf("sources[%d]", i), src, parser.DeclarationErrors)
-		if err != nil {
-			t.Fatal(err)
-		}
-		files = append(files, f)
+		files = append(files, mustParse(fset, fmt.Sprintf("sources[%d]", i), src))
 	}
 
 	// resolve and type-check package AST
diff --git a/src/go/types/scope.go b/src/go/types/scope.go
index 010727e..fc42ce6 100644
--- a/src/go/types/scope.go
+++ b/src/go/types/scope.go
@@ -7,7 +7,6 @@
 package types
 
 import (
-	"bytes"
 	"fmt"
 	"go/token"
 	"io"
@@ -233,7 +232,7 @@
 
 // String returns a string representation of the scope, for debugging.
 func (s *Scope) String() string {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	s.WriteTo(&buf, 0, false)
 	return buf.String()
 }
diff --git a/src/go/types/self_test.go b/src/go/types/self_test.go
index a1af85f..a63f2b7 100644
--- a/src/go/types/self_test.go
+++ b/src/go/types/self_test.go
@@ -9,6 +9,7 @@
 	"go/importer"
 	"go/parser"
 	"go/token"
+	"internal/testenv"
 	"path"
 	"path/filepath"
 	"testing"
@@ -18,8 +19,10 @@
 )
 
 func TestSelf(t *testing.T) {
+	testenv.MustHaveGoBuild(t) // The Go command is needed for the importer to determine the locations of stdlib .a files.
+
 	fset := token.NewFileSet()
-	files, err := pkgFiles(fset, ".", 0)
+	files, err := pkgFiles(fset, ".")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -32,6 +35,8 @@
 }
 
 func BenchmarkCheck(b *testing.B) {
+	testenv.MustHaveGoBuild(b) // The Go command is needed for the importer to determine the locations of stdlib .a files.
+
 	for _, p := range []string{
 		"net/http",
 		"go/parser",
@@ -61,7 +66,7 @@
 
 func runbench(b *testing.B, path string, ignoreFuncBodies, writeInfo bool) {
 	fset := token.NewFileSet()
-	files, err := pkgFiles(fset, path, 0)
+	files, err := pkgFiles(fset, path)
 	if err != nil {
 		b.Fatal(err)
 	}
@@ -98,7 +103,7 @@
 	b.ReportMetric(float64(lines)*float64(b.N)/time.Since(start).Seconds(), "lines/s")
 }
 
-func pkgFiles(fset *token.FileSet, path string, mode parser.Mode) ([]*ast.File, error) {
+func pkgFiles(fset *token.FileSet, path string) ([]*ast.File, error) {
 	filenames, err := pkgFilenames(path) // from stdlib_test.go
 	if err != nil {
 		return nil, err
@@ -106,7 +111,7 @@
 
 	var files []*ast.File
 	for _, filename := range filenames {
-		file, err := parser.ParseFile(fset, filename, nil, mode)
+		file, err := parser.ParseFile(fset, filename, nil, 0)
 		if err != nil {
 			return nil, err
 		}
diff --git a/src/go/types/signature.go b/src/go/types/signature.go
index 82177a1..83460ea 100644
--- a/src/go/types/signature.go
+++ b/src/go/types/signature.go
@@ -5,8 +5,10 @@
 package types
 
 import (
+	"fmt"
 	"go/ast"
 	"go/token"
+	. "internal/types/errors"
 )
 
 // ----------------------------------------------------------------------------
@@ -41,16 +43,18 @@
 // NewSignatureType creates a new function type for the given receiver,
 // receiver type parameters, type parameters, parameters, and results. If
 // variadic is set, params must hold at least one parameter and the last
-// parameter must be of unnamed slice type. If recv is non-nil, typeParams must
-// be empty. If recvTypeParams is non-empty, recv must be non-nil.
+// parameter's core type must be of unnamed slice or bytestring type.
+// If recv is non-nil, typeParams must be empty. If recvTypeParams is
+// non-empty, recv must be non-nil.
 func NewSignatureType(recv *Var, recvTypeParams, typeParams []*TypeParam, params, results *Tuple, variadic bool) *Signature {
 	if variadic {
 		n := params.Len()
 		if n == 0 {
 			panic("variadic function must have at least one parameter")
 		}
-		if _, ok := params.At(n - 1).typ.(*Slice); !ok {
-			panic("variadic parameter must be of unnamed slice type")
+		core := coreString(params.At(n - 1).typ)
+		if _, ok := core.(*Slice); !ok && !isString(core) {
+			panic(fmt.Sprintf("got %s, want variadic parameter with unnamed slice type or string as core type", core.String()))
 		}
 	}
 	sig := &Signature{recv: recv, params: params, results: results, variadic: variadic}
@@ -158,7 +162,7 @@
 				// may lead to follow-on errors (see issues #51339, #51343).
 				// TODO(gri) find a better solution
 				got := measure(len(tparams), "type parameter")
-				check.errorf(recvPar, _BadRecv, "got %s, but receiver base type declares %d", got, len(recvTParams))
+				check.errorf(recvPar, BadRecv, "got %s, but receiver base type declares %d", got, len(recvTParams))
 			}
 		}
 	}
@@ -169,7 +173,7 @@
 		// (A separate check is needed when type-checking interface method signatures because
 		// they don't have a receiver specification.)
 		if recvPar != nil {
-			check.errorf(ftyp.TypeParams, _InvalidMethodTypeParams, "methods cannot have type parameters")
+			check.error(ftyp.TypeParams, InvalidMethodTypeParams, "methods cannot have type parameters")
 		}
 	}
 
@@ -181,7 +185,7 @@
 	params, variadic := check.collectParams(scope, ftyp.Params, true)
 	results, _ := check.collectParams(scope, ftyp.Results, false)
 	scope.squash(func(obj, alt Object) {
-		check.errorf(obj, _DuplicateDecl, "%s redeclared in this block", obj.Name())
+		check.errorf(obj, DuplicateDecl, "%s redeclared in this block", obj.Name())
 		check.reportAltDecl(alt)
 	})
 
@@ -196,7 +200,7 @@
 			recv = NewParam(token.NoPos, nil, "", Typ[Invalid]) // ignore recv below
 		default:
 			// more than one receiver
-			check.error(recvList[len(recvList)-1], _InvalidRecv, "method must have exactly one receiver")
+			check.error(recvList[len(recvList)-1], InvalidRecv, "method has multiple receivers")
 			fallthrough // continue with first receiver
 		case 1:
 			recv = recvList[0]
@@ -219,11 +223,11 @@
 				// The receiver type may be an instantiated type referred to
 				// by an alias (which cannot have receiver parameters for now).
 				if T.TypeArgs() != nil && sig.RecvTypeParams() == nil {
-					check.errorf(recv, _InvalidRecv, "cannot define new methods on instantiated type %s", rtyp)
+					check.errorf(recv, InvalidRecv, "cannot define new methods on instantiated type %s", rtyp)
 					break
 				}
 				if T.obj.pkg != check.pkg {
-					check.errorf(recv, _InvalidRecv, "cannot define new methods on non-local type %s", rtyp)
+					check.errorf(recv, InvalidRecv, "cannot define new methods on non-local type %s", rtyp)
 					break
 				}
 				var cause string
@@ -241,12 +245,12 @@
 					unreachable()
 				}
 				if cause != "" {
-					check.errorf(recv, _InvalidRecv, "invalid receiver type %s (%s)", rtyp, cause)
+					check.errorf(recv, InvalidRecv, "invalid receiver type %s (%s)", rtyp, cause)
 				}
 			case *Basic:
-				check.errorf(recv, _InvalidRecv, "cannot define new methods on non-local type %s", rtyp)
+				check.errorf(recv, InvalidRecv, "cannot define new methods on non-local type %s", rtyp)
 			default:
-				check.errorf(recv, _InvalidRecv, "invalid receiver type %s", recv.typ)
+				check.errorf(recv, InvalidRecv, "invalid receiver type %s", recv.typ)
 			}
 		}).describef(recv, "validate receiver %s", recv)
 	}
@@ -271,7 +275,7 @@
 			if variadicOk && i == len(list.List)-1 && len(field.Names) <= 1 {
 				variadic = true
 			} else {
-				check.softErrorf(t, _MisplacedDotDotDot, "can only use ... with final parameter in list")
+				check.softErrorf(t, MisplacedDotDotDot, "can only use ... with final parameter in list")
 				// ignore ... and continue
 			}
 		}
@@ -282,7 +286,7 @@
 			// named parameter
 			for _, name := range field.Names {
 				if name.Name == "" {
-					check.invalidAST(name, "anonymous parameter")
+					check.error(name, InvalidSyntaxTree, "anonymous parameter")
 					// ok to continue
 				}
 				par := NewParam(name.Pos(), check.pkg, name.Name, typ)
@@ -300,7 +304,7 @@
 	}
 
 	if named && anonymous {
-		check.invalidAST(list, "list contains both named and anonymous parameters")
+		check.error(list, InvalidSyntaxTree, "list contains both named and anonymous parameters")
 		// ok to continue
 	}
 
diff --git a/src/go/types/sizes_test.go b/src/go/types/sizes_test.go
index 740072f..09ac9e2 100644
--- a/src/go/types/sizes_test.go
+++ b/src/go/types/sizes_test.go
@@ -9,9 +9,9 @@
 import (
 	"go/ast"
 	"go/importer"
-	"go/parser"
 	"go/token"
 	"go/types"
+	"internal/testenv"
 	"testing"
 )
 
@@ -21,17 +21,9 @@
 }
 
 func findStructTypeConfig(t *testing.T, src string, conf *types.Config) *types.Struct {
-	fset := token.NewFileSet()
-	f, err := parser.ParseFile(fset, "x.go", src, 0)
-	if err != nil {
-		t.Fatal(err)
-	}
-	info := types.Info{Types: make(map[ast.Expr]types.TypeAndValue)}
-	_, err = conf.Check("x", fset, []*ast.File{f}, &info)
-	if err != nil {
-		t.Fatal(err)
-	}
-	for _, tv := range info.Types {
+	types_ := make(map[ast.Expr]types.TypeAndValue)
+	mustTypecheck("x", src, &types.Info{Types: types_})
+	for _, tv := range types_ {
 		if ts, ok := tv.Type.(*types.Struct); ok {
 			return ts
 		}
@@ -95,16 +87,13 @@
 const _ = unsafe.Offsetof(struct{ x int64 }{}.x)
 `
 	fset := token.NewFileSet()
-	f, err := parser.ParseFile(fset, "x.go", src, 0)
-	if err != nil {
-		t.Fatal(err)
-	}
+	f := mustParse(fset, "x.go", src)
 	info := types.Info{Types: make(map[ast.Expr]types.TypeAndValue)}
 	conf := types.Config{
 		Importer: importer.Default(),
 		Sizes:    &types.StdSizes{WordSize: 8, MaxAlign: 8},
 	}
-	_, err = conf.Check("x", fset, []*ast.File{f}, &info)
+	_, err := conf.Check("x", fset, []*ast.File{f}, &info)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -116,6 +105,8 @@
 
 // Issue #53884.
 func TestAtomicAlign(t *testing.T) {
+	testenv.MustHaveGoBuild(t) // The Go command is needed for the importer to determine the locations of stdlib .a files.
+
 	const src = `
 package main
 
diff --git a/src/go/types/stdlib_test.go b/src/go/types/stdlib_test.go
index d75729a..c0c9fcf 100644
--- a/src/go/types/stdlib_test.go
+++ b/src/go/types/stdlib_test.go
@@ -40,7 +40,7 @@
 
 	pkgCount := 0
 	duration := walkPkgDirs(filepath.Join(testenv.GOROOT(t), "src"), func(dir string, filenames []string) {
-		typecheck(t, dir, filenames)
+		typecheckFiles(t, dir, filenames)
 		pkgCount++
 	}, t.Error)
 
@@ -199,6 +199,18 @@
 		"issue48230.go",  // go/types doesn't check validity of //go:xxx directives
 		"issue49767.go",  // go/types does not have constraints on channel element size
 		"issue49814.go",  // go/types does not have constraints on array size
+		"issue56103.go",  // anonymous interface cycles; will be a type checker error in 1.22
+
+		// These tests requires runtime/cgo.Incomplete, which is only available on some platforms.
+		// However, go/types does not know about build constraints.
+		"bug514.go",
+		"issue40954.go",
+		"issue42032.go",
+		"issue42076.go",
+		"issue46903.go",
+		"issue51733.go",
+		"notinheap2.go",
+		"notinheap3.go",
 	)
 }
 
@@ -214,10 +226,11 @@
 
 	// See #46027: some imports are missing for this submodule.
 	"crypto/internal/edwards25519/field/_asm": true,
+	"crypto/internal/bigmod/_asm":             true,
 }
 
-// typecheck typechecks the given package files.
-func typecheck(t *testing.T, path string, filenames []string) {
+// typecheckFiles typechecks the given package files.
+func typecheckFiles(t *testing.T, path string, filenames []string) {
 	fset := token.NewFileSet()
 
 	// parse package files
diff --git a/src/go/types/stmt.go b/src/go/types/stmt.go
index 0fab707..ac6255d 100644
--- a/src/go/types/stmt.go
+++ b/src/go/types/stmt.go
@@ -10,6 +10,7 @@
 	"go/ast"
 	"go/constant"
 	"go/token"
+	. "internal/types/errors"
 	"sort"
 )
 
@@ -47,7 +48,7 @@
 	}
 
 	if sig.results.Len() > 0 && !check.isTerminating(body, "") {
-		check.error(atPos(body.Rbrace), _MissingReturn, "missing return")
+		check.error(atPos(body.Rbrace), MissingReturn, "missing return")
 	}
 
 	// spec: "Implementation restriction: A compiler may make it illegal to
@@ -67,7 +68,7 @@
 		return unused[i].pos < unused[j].pos
 	})
 	for _, v := range unused {
-		check.softErrorf(v, _UnusedVar, "%s declared but not used", v.name)
+		check.softErrorf(v, UnusedVar, "%s declared and not used", v.name)
 	}
 
 	for _, scope := range scope.children {
@@ -138,11 +139,11 @@
 				d = s
 			}
 		default:
-			check.invalidAST(s, "case/communication clause expected")
+			check.error(s, InvalidSyntaxTree, "case/communication clause expected")
 		}
 		if d != nil {
 			if first != nil {
-				check.errorf(d, _DuplicateDefault, "multiple defaults (first at %s)", check.fset.Position(first.Pos()))
+				check.errorf(d, DuplicateDefault, "multiple defaults (first at %s)", check.fset.Position(first.Pos()))
 			} else {
 				first = d
 			}
@@ -171,17 +172,17 @@
 func (check *Checker) suspendedCall(keyword string, call *ast.CallExpr) {
 	var x operand
 	var msg string
-	var code errorCode
+	var code Code
 	switch check.rawExpr(&x, call, nil, false) {
 	case conversion:
 		msg = "requires function call, not conversion"
-		code = _InvalidDefer
+		code = InvalidDefer
 		if keyword == "go" {
-			code = _InvalidGo
+			code = InvalidGo
 		}
 	case expression:
 		msg = "discards result of"
-		code = _UnusedResults
+		code = UnusedResults
 	case statement:
 		return
 	default:
@@ -259,8 +260,8 @@
 			// (quadratic algorithm, but these lists tend to be very short)
 			for _, vt := range seen[val] {
 				if Identical(v.typ, vt.typ) {
-					check.errorf(&v, _DuplicateCase, "duplicate case %s in expression switch", &v)
-					check.error(atPos(vt.pos), _DuplicateCase, "\tprevious case") // secondary error, \t indented
+					check.errorf(&v, DuplicateCase, "duplicate case %s in expression switch", &v)
+					check.error(atPos(vt.pos), DuplicateCase, "\tprevious case") // secondary error, \t indented
 					continue L
 				}
 			}
@@ -303,8 +304,8 @@
 				if T != nil {
 					Ts = TypeString(T, check.qualifier)
 				}
-				check.errorf(e, _DuplicateCase, "duplicate case %s in type switch", Ts)
-				check.error(other, _DuplicateCase, "\tprevious case") // secondary error, \t indented
+				check.errorf(e, DuplicateCase, "duplicate case %s in type switch", Ts)
+				check.error(other, DuplicateCase, "\tprevious case") // secondary error, \t indented
 				continue L
 			}
 		}
@@ -344,6 +345,7 @@
 // 				Ts = TypeString(T, check.qualifier)
 // 			}
 // 			var err error_
+//			err.code = DuplicateCase
 // 			err.errorf(e, "duplicate case %s in type switch", Ts)
 // 			err.errorf(other, "previous case")
 // 			check.report(&err)
@@ -394,20 +396,20 @@
 		var x operand
 		kind := check.rawExpr(&x, s.X, nil, false)
 		var msg string
-		var code errorCode
+		var code Code
 		switch x.mode {
 		default:
 			if kind == statement {
 				return
 			}
 			msg = "is not used"
-			code = _UnusedExpr
+			code = UnusedExpr
 		case builtin:
 			msg = "must be called"
-			code = _UncalledBuiltin
+			code = UncalledBuiltin
 		case typexpr:
 			msg = "is not an expression"
-			code = _NotAnExpr
+			code = NotAnExpr
 		}
 		check.errorf(&x, code, "%s %s", &x, msg)
 
@@ -420,16 +422,16 @@
 		}
 		u := coreType(ch.typ)
 		if u == nil {
-			check.invalidOp(inNode(s, s.Arrow), _InvalidSend, "cannot send to %s: no core type", &ch)
+			check.errorf(inNode(s, s.Arrow), InvalidSend, invalidOp+"cannot send to %s: no core type", &ch)
 			return
 		}
 		uch, _ := u.(*Chan)
 		if uch == nil {
-			check.invalidOp(inNode(s, s.Arrow), _InvalidSend, "cannot send to non-channel %s", &ch)
+			check.errorf(inNode(s, s.Arrow), InvalidSend, invalidOp+"cannot send to non-channel %s", &ch)
 			return
 		}
 		if uch.dir == RecvOnly {
-			check.invalidOp(inNode(s, s.Arrow), _InvalidSend, "cannot send to receive-only channel %s", &ch)
+			check.errorf(inNode(s, s.Arrow), InvalidSend, invalidOp+"cannot send to receive-only channel %s", &ch)
 			return
 		}
 		check.assignment(&val, uch.elem, "send")
@@ -442,7 +444,7 @@
 		case token.DEC:
 			op = token.SUB
 		default:
-			check.invalidAST(inNode(s, s.TokPos), "unknown inc/dec operation %s", s.Tok)
+			check.errorf(inNode(s, s.TokPos), InvalidSyntaxTree, "unknown inc/dec operation %s", s.Tok)
 			return
 		}
 
@@ -452,7 +454,7 @@
 			return
 		}
 		if !allNumeric(x.typ) {
-			check.invalidOp(s.X, _NonNumericIncDec, "%s%s (non-numeric type %s)", s.X, s.Tok, x.typ)
+			check.errorf(s.X, NonNumericIncDec, invalidOp+"%s%s (non-numeric type %s)", s.X, s.Tok, x.typ)
 			return
 		}
 
@@ -467,7 +469,7 @@
 		switch s.Tok {
 		case token.ASSIGN, token.DEFINE:
 			if len(s.Lhs) == 0 {
-				check.invalidAST(s, "missing lhs in assignment")
+				check.error(s, InvalidSyntaxTree, "missing lhs in assignment")
 				return
 			}
 			if s.Tok == token.DEFINE {
@@ -480,12 +482,12 @@
 		default:
 			// assignment operations
 			if len(s.Lhs) != 1 || len(s.Rhs) != 1 {
-				check.errorf(inNode(s, s.TokPos), _MultiValAssignOp, "assignment operation %s requires single-valued expressions", s.Tok)
+				check.errorf(inNode(s, s.TokPos), MultiValAssignOp, "assignment operation %s requires single-valued expressions", s.Tok)
 				return
 			}
 			op := assignOp(s.Tok)
 			if op == token.ILLEGAL {
-				check.invalidAST(atPos(s.TokPos), "unknown assignment operation %s", s.Tok)
+				check.errorf(atPos(s.TokPos), InvalidSyntaxTree, "unknown assignment operation %s", s.Tok)
 				return
 			}
 			var x operand
@@ -512,8 +514,8 @@
 			// with the same name as a result parameter is in scope at the place of the return."
 			for _, obj := range res.vars {
 				if alt := check.lookup(obj.name); alt != nil && alt != obj {
-					check.errorf(s, _OutOfScopeResult, "result parameter %s not in scope at return", obj.name)
-					check.errorf(alt, _OutOfScopeResult, "\tinner declaration of %s", obj)
+					check.errorf(s, OutOfScopeResult, "result parameter %s not in scope at return", obj.name)
+					check.errorf(alt, OutOfScopeResult, "\tinner declaration of %s", obj)
 					// ok to continue
 				}
 			}
@@ -533,11 +535,11 @@
 		switch s.Tok {
 		case token.BREAK:
 			if ctxt&breakOk == 0 {
-				check.error(s, _MisplacedBreak, "break not in for, switch, or select statement")
+				check.error(s, MisplacedBreak, "break not in for, switch, or select statement")
 			}
 		case token.CONTINUE:
 			if ctxt&continueOk == 0 {
-				check.error(s, _MisplacedContinue, "continue not in for statement")
+				check.error(s, MisplacedContinue, "continue not in for statement")
 			}
 		case token.FALLTHROUGH:
 			if ctxt&fallthroughOk == 0 {
@@ -550,10 +552,10 @@
 				default:
 					msg = "fallthrough statement out of place"
 				}
-				check.error(s, _MisplacedFallthrough, msg)
+				check.error(s, MisplacedFallthrough, msg)
 			}
 		default:
-			check.invalidAST(s, "branch statement: %s", s.Tok)
+			check.errorf(s, InvalidSyntaxTree, "branch statement: %s", s.Tok)
 		}
 
 	case *ast.BlockStmt:
@@ -570,7 +572,7 @@
 		var x operand
 		check.expr(&x, s.Cond)
 		if x.mode != invalid && !allBoolean(x.typ) {
-			check.error(s.Cond, _InvalidCond, "non-boolean condition in if statement")
+			check.error(s.Cond, InvalidCond, "non-boolean condition in if statement")
 		}
 		check.stmt(inner, s.Body)
 		// The parser produces a correct AST but if it was modified
@@ -581,7 +583,7 @@
 		case *ast.IfStmt, *ast.BlockStmt:
 			check.stmt(inner, s.Else)
 		default:
-			check.invalidAST(s.Else, "invalid else branch in if statement")
+			check.error(s.Else, InvalidSyntaxTree, "invalid else branch in if statement")
 		}
 
 	case *ast.SwitchStmt:
@@ -597,7 +599,7 @@
 			// (as a compiler would), we get all the relevant checks.
 			check.assignment(&x, nil, "switch expression")
 			if x.mode != invalid && !Comparable(x.typ) && !hasNil(x.typ) {
-				check.errorf(&x, _InvalidExprSwitch, "cannot switch on %s (%s is not comparable)", &x, x.typ)
+				check.errorf(&x, InvalidExprSwitch, "cannot switch on %s (%s is not comparable)", &x, x.typ)
 				x.mode = invalid
 			}
 		} else {
@@ -615,7 +617,7 @@
 		for i, c := range s.Body.List {
 			clause, _ := c.(*ast.CaseClause)
 			if clause == nil {
-				check.invalidAST(c, "incorrect expression switch case")
+				check.error(c, InvalidSyntaxTree, "incorrect expression switch case")
 				continue
 			}
 			check.caseValues(&x, clause.List, seen)
@@ -652,20 +654,20 @@
 			rhs = guard.X
 		case *ast.AssignStmt:
 			if len(guard.Lhs) != 1 || guard.Tok != token.DEFINE || len(guard.Rhs) != 1 {
-				check.invalidAST(s, "incorrect form of type switch guard")
+				check.error(s, InvalidSyntaxTree, "incorrect form of type switch guard")
 				return
 			}
 
 			lhs, _ = guard.Lhs[0].(*ast.Ident)
 			if lhs == nil {
-				check.invalidAST(s, "incorrect form of type switch guard")
+				check.error(s, InvalidSyntaxTree, "incorrect form of type switch guard")
 				return
 			}
 
 			if lhs.Name == "_" {
 				// _ := x.(type) is an invalid short variable declaration
-				check.softErrorf(lhs, _NoNewVar, "no new variable on left side of :=")
-				lhs = nil // avoid declared but not used error below
+				check.softErrorf(lhs, NoNewVar, "no new variable on left side of :=")
+				lhs = nil // avoid declared and not used error below
 			} else {
 				check.recordDef(lhs, nil) // lhs variable is implicitly declared in each cause clause
 			}
@@ -673,14 +675,14 @@
 			rhs = guard.Rhs[0]
 
 		default:
-			check.invalidAST(s, "incorrect form of type switch guard")
+			check.error(s, InvalidSyntaxTree, "incorrect form of type switch guard")
 			return
 		}
 
 		// rhs must be of the form: expr.(type) and expr must be an ordinary interface
 		expr, _ := rhs.(*ast.TypeAssertExpr)
 		if expr == nil || expr.Type != nil {
-			check.invalidAST(s, "incorrect form of type switch guard")
+			check.error(s, InvalidSyntaxTree, "incorrect form of type switch guard")
 			return
 		}
 		var x operand
@@ -691,12 +693,12 @@
 		// TODO(gri) we may want to permit type switches on type parameter values at some point
 		var sx *operand // switch expression against which cases are compared against; nil if invalid
 		if isTypeParam(x.typ) {
-			check.errorf(&x, _InvalidTypeSwitch, "cannot use type switch on type parameter value %s", &x)
+			check.errorf(&x, InvalidTypeSwitch, "cannot use type switch on type parameter value %s", &x)
 		} else {
 			if _, ok := under(x.typ).(*Interface); ok {
 				sx = &x
 			} else {
-				check.errorf(&x, _InvalidTypeSwitch, "%s is not an interface", &x)
+				check.errorf(&x, InvalidTypeSwitch, "%s is not an interface", &x)
 			}
 		}
 
@@ -707,7 +709,7 @@
 		for _, s := range s.Body.List {
 			clause, _ := s.(*ast.CaseClause)
 			if clause == nil {
-				check.invalidAST(s, "incorrect type switch case")
+				check.error(s, InvalidSyntaxTree, "incorrect type switch case")
 				continue
 			}
 			// Check each type in this type switch case.
@@ -730,7 +732,7 @@
 				}
 				check.declare(check.scope, nil, obj, scopePos)
 				check.recordImplicit(clause, obj)
-				// For the "declared but not used" error, all lhs variables act as
+				// For the "declared and not used" error, all lhs variables act as
 				// one; i.e., if any one of them is 'used', all of them are 'used'.
 				// Collect them for later analysis.
 				lhsVars = append(lhsVars, obj)
@@ -749,7 +751,7 @@
 				v.used = true // avoid usage error when checking entire function
 			}
 			if !used {
-				check.softErrorf(lhs, _UnusedVar, "%s declared but not used", lhs.Name)
+				check.softErrorf(lhs, UnusedVar, "%s declared and not used", lhs.Name)
 			}
 		}
 
@@ -786,7 +788,7 @@
 			}
 
 			if !valid {
-				check.error(clause.Comm, _InvalidSelectCase, "select case must be send or receive (possibly with assignment)")
+				check.error(clause.Comm, InvalidSelectCase, "select case must be send or receive (possibly with assignment)")
 				continue
 			}
 
@@ -808,17 +810,17 @@
 			var x operand
 			check.expr(&x, s.Cond)
 			if x.mode != invalid && !allBoolean(x.typ) {
-				check.error(s.Cond, _InvalidCond, "non-boolean condition in for statement")
+				check.error(s.Cond, InvalidCond, "non-boolean condition in for statement")
 			}
 		}
 		check.simpleStmt(s.Post)
 		// spec: "The init statement may be a short variable
 		// declaration, but the post statement must not."
 		if s, _ := s.Post.(*ast.AssignStmt); s != nil && s.Tok == token.DEFINE {
-			check.softErrorf(s, _InvalidPostDecl, "cannot declare in post statement")
+			check.softErrorf(s, InvalidPostDecl, "cannot declare in post statement")
 			// Don't call useLHS here because we want to use the lhs in
 			// this erroneous statement so that we don't get errors about
-			// these lhs variables being declared but not used.
+			// these lhs variables being declared and not used.
 			check.use(s.Lhs...) // avoid follow-up errors
 		}
 		check.stmt(inner, s.Body)
@@ -841,7 +843,7 @@
 				cause = check.sprintf("%s has no core type", x.typ)
 			case *Chan:
 				if s.Value != nil {
-					check.softErrorf(s.Value, _InvalidIterVar, "range over %s permits only one iteration variable", &x)
+					check.softErrorf(s.Value, InvalidIterVar, "range over %s permits only one iteration variable", &x)
 					// ok to continue
 				}
 				if t.dir == SendOnly {
@@ -851,9 +853,9 @@
 			key, val = rangeKeyVal(u)
 			if key == nil || cause != "" {
 				if cause == "" {
-					check.softErrorf(&x, _InvalidRangeExpr, "cannot range over %s", &x)
+					check.softErrorf(&x, InvalidRangeExpr, "cannot range over %s", &x)
 				} else {
-					check.softErrorf(&x, _InvalidRangeExpr, "cannot range over %s (%s)", &x, cause)
+					check.softErrorf(&x, InvalidRangeExpr, "cannot range over %s (%s)", &x, cause)
 				}
 				// ok to continue
 			}
@@ -891,7 +893,7 @@
 						vars = append(vars, obj)
 					}
 				} else {
-					check.invalidAST(lhs, "cannot declare %s", lhs)
+					check.errorf(lhs, InvalidSyntaxTree, "cannot declare %s", lhs)
 					obj = NewVar(lhs.Pos(), check.pkg, "_", nil) // dummy variable
 				}
 
@@ -914,7 +916,7 @@
 					check.declare(check.scope, nil /* recordDef already called */, obj, scopePos)
 				}
 			} else {
-				check.error(inNode(s, s.TokPos), _NoNewVar, "no new variables on left side of :=")
+				check.error(inNode(s, s.TokPos), NoNewVar, "no new variables on left side of :=")
 			}
 		} else {
 			// ordinary assignment
@@ -934,7 +936,7 @@
 		check.stmt(inner, s.Body)
 
 	default:
-		check.invalidAST(s, "invalid statement")
+		check.error(s, InvalidSyntaxTree, "invalid statement")
 	}
 }
 
diff --git a/src/go/types/struct.go b/src/go/types/struct.go
index d6c5634..2ed0e6d 100644
--- a/src/go/types/struct.go
+++ b/src/go/types/struct.go
@@ -7,6 +7,7 @@
 import (
 	"go/ast"
 	"go/token"
+	. "internal/types/errors"
 	"strconv"
 )
 
@@ -124,7 +125,7 @@
 			pos := f.Type.Pos()
 			name := embeddedFieldIdent(f.Type)
 			if name == nil {
-				check.invalidAST(f.Type, "embedded field type %s has no name", f.Type)
+				check.errorf(f.Type, InvalidSyntaxTree, "embedded field type %s has no name", f.Type)
 				name = ast.NewIdent("_")
 				name.NamePos = pos
 				addInvalid(name, pos)
@@ -151,20 +152,20 @@
 					}
 					// unsafe.Pointer is treated like a regular pointer
 					if u.kind == UnsafePointer {
-						check.error(embeddedPos, _InvalidPtrEmbed, "embedded field type cannot be unsafe.Pointer")
+						check.error(embeddedPos, InvalidPtrEmbed, "embedded field type cannot be unsafe.Pointer")
 					}
 				case *Pointer:
-					check.error(embeddedPos, _InvalidPtrEmbed, "embedded field type cannot be a pointer")
+					check.error(embeddedPos, InvalidPtrEmbed, "embedded field type cannot be a pointer")
 				case *Interface:
 					if isTypeParam(t) {
 						// The error code here is inconsistent with other error codes for
 						// invalid embedding, because this restriction may be relaxed in the
 						// future, and so it did not warrant a new error code.
-						check.error(embeddedPos, _MisplacedTypeParam, "embedded field type cannot be a (pointer to a) type parameter")
+						check.error(embeddedPos, MisplacedTypeParam, "embedded field type cannot be a (pointer to a) type parameter")
 						break
 					}
 					if isPtr {
-						check.error(embeddedPos, _InvalidPtrEmbed, "embedded field type cannot be a pointer to an interface")
+						check.error(embeddedPos, InvalidPtrEmbed, "embedded field type cannot be a pointer to an interface")
 					}
 				}
 			}).describef(embeddedPos, "check embedded type %s", embeddedTyp)
@@ -197,7 +198,7 @@
 
 func (check *Checker) declareInSet(oset *objset, pos token.Pos, obj Object) bool {
 	if alt := oset.insert(obj); alt != nil {
-		check.errorf(atPos(pos), _DuplicateDecl, "%s redeclared", obj.Name())
+		check.errorf(atPos(pos), DuplicateDecl, "%s redeclared", obj.Name())
 		check.reportAltDecl(alt)
 		return false
 	}
@@ -211,7 +212,7 @@
 				return val
 			}
 		}
-		check.invalidAST(t, "incorrect tag syntax: %q", t.Value)
+		check.errorf(t, InvalidSyntaxTree, "incorrect tag syntax: %q", t.Value)
 	}
 	return ""
 }
diff --git a/src/go/types/subst.go b/src/go/types/subst.go
index 42f3619..5a49c04 100644
--- a/src/go/types/subst.go
+++ b/src/go/types/subst.go
@@ -6,7 +6,9 @@
 
 package types
 
-import "go/token"
+import (
+	"go/token"
+)
 
 type substMap map[*TypeParam]Type
 
@@ -262,7 +264,7 @@
 		return subst.smap.lookup(t)
 
 	default:
-		panic("unimplemented")
+		unreachable()
 	}
 
 	return typ
diff --git a/src/go/types/termlist.go b/src/go/types/termlist.go
index 6d08ddb..83a02ee 100644
--- a/src/go/types/termlist.go
+++ b/src/go/types/termlist.go
@@ -4,7 +4,7 @@
 
 package types
 
-import "bytes"
+import "strings"
 
 // A termlist represents the type set represented by the union
 // t1 ∪ y2 ∪ ... tn of the type sets of the terms t1 to tn.
@@ -17,15 +17,18 @@
 // It is in normal form.
 var allTermlist = termlist{new(term)}
 
+// termSep is the separator used between individual terms.
+const termSep = " | "
+
 // String prints the termlist exactly (without normalization).
 func (xl termlist) String() string {
 	if len(xl) == 0 {
 		return "∅"
 	}
-	var buf bytes.Buffer
+	var buf strings.Builder
 	for i, x := range xl {
 		if i > 0 {
-			buf.WriteString(" | ")
+			buf.WriteString(termSep)
 		}
 		buf.WriteString(x.String())
 	}
diff --git a/src/go/types/testdata/check/builtins0.go b/src/go/types/testdata/check/builtins0.go
deleted file mode 100644
index 8a4c207..0000000
--- a/src/go/types/testdata/check/builtins0.go
+++ /dev/null
@@ -1,902 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// builtin calls
-
-package builtins
-
-import "unsafe"
-
-func f0() {}
-
-func append1() {
-	var b byte
-	var x int
-	var s []byte
-	_ = append() // ERROR not enough arguments
-	_ = append("foo" /* ERROR must be a slice */ )
-	_ = append(nil /* ERROR must be a slice */ , s)
-	_ = append(x /* ERROR must be a slice */ , s)
-	_ = append(s)
-	_ = append(s, nil...)
-	append /* ERROR not used */ (s)
-
-	_ = append(s, b)
-	_ = append(s, x /* ERROR cannot use x */ )
-	_ = append(s, s /* ERROR cannot use s */ )
-	_ = append(s...) /* ERROR not enough arguments */
-	_ = append(s, b, s /* ERROR too many arguments */ ...)
-	_ = append(s, 1, 2, 3)
-	_ = append(s, 1, 2, 3, x /* ERROR cannot use x */ , 5, 6, 6)
-	_ = append(s, 1, 2 /* ERROR too many arguments */, s...)
-	_ = append([]interface{}(nil), 1, 2, "foo", x, 3.1425, false)
-
-	type S []byte
-	type T string
-	var t T
-	_ = append(s, "foo" /* ERROR cannot use .* in argument to append */ )
-	_ = append(s, "foo"...)
-	_ = append(S(s), "foo" /* ERROR cannot use .* in argument to append */ )
-	_ = append(S(s), "foo"...)
-	_ = append(s, t /* ERROR cannot use t */ )
-	_ = append(s, t...)
-	_ = append(s, T("foo")...)
-	_ = append(S(s), t /* ERROR cannot use t */ )
-	_ = append(S(s), t...)
-	_ = append(S(s), T("foo")...)
-	_ = append([]string{}, t /* ERROR cannot use t */ , "foo")
-	_ = append([]T{}, t, "foo")
-}
-
-// from the spec
-func append2() {
-	s0 := []int{0, 0}
-	s1 := append(s0, 2)                // append a single element     s1 == []int{0, 0, 2}
-	s2 := append(s1, 3, 5, 7)          // append multiple elements    s2 == []int{0, 0, 2, 3, 5, 7}
-	s3 := append(s2, s0...)            // append a slice              s3 == []int{0, 0, 2, 3, 5, 7, 0, 0}
-	s4 := append(s3[3:6], s3[2:]...)   // append overlapping slice    s4 == []int{3, 5, 7, 2, 3, 5, 7, 0, 0}
-
-	var t []interface{}
-	t = append(t, 42, 3.1415, "foo")   //                             t == []interface{}{42, 3.1415, "foo"}
-
-	var b []byte
-	b = append(b, "bar"...)            // append string contents      b == []byte{'b', 'a', 'r' }
-
-	_ = s4
-}
-
-func append3() {
-	f1 := func() (s []int) { return }
-	f2 := func() (s []int, x int) { return }
-	f3 := func() (s []int, x, y int) { return }
-	f5 := func() (s []interface{}, x int, y float32, z string, b bool) { return }
-	ff := func() (int, float32) { return 0, 0 }
-	_ = append(f0 /* ERROR used as value */ ())
-	_ = append(f1())
-	_ = append(f2())
-	_ = append(f3())
-	_ = append(f5())
-	_ = append(ff /* ERROR must be a slice */ ()) // TODO(gri) better error message
-}
-
-func cap1() {
-	var a [10]bool
-	var p *[20]int
-	var c chan string
-	_ = cap() // ERROR not enough arguments
-	_ = cap(1, 2) // ERROR too many arguments
-	_ = cap(42 /* ERROR invalid */)
-	const _3 = cap(a)
-	assert(_3 == 10)
-	const _4 = cap(p)
-	assert(_4 == 20)
-	_ = cap(c)
-	cap /* ERROR not used */ (c)
-
-	// issue 4744
-	type T struct{ a [10]int }
-	const _ = cap(((*T)(nil)).a)
-
-	var s [][]byte
-	_ = cap(s)
-	_ = cap(s... /* ERROR invalid use of \.\.\. */ )
-}
-
-func cap2() {
-	f1a := func() (a [10]int) { return }
-	f1s := func() (s []int) { return }
-	f2 := func() (s []int, x int) { return }
-	_ = cap(f0 /* ERROR used as value */ ())
-	_ = cap(f1a())
-	_ = cap(f1s())
-	_ = cap(f2()) // ERROR too many arguments
-}
-
-// test cases for issue 7387
-func cap3() {
-	var f = func() int { return 0 }
-	var x = f()
-	const (
-		_ = cap([4]int{})
-		_ = cap([4]int{x})
-		_ = cap /* ERROR not constant */ ([4]int{f()})
-		_ = cap /* ERROR not constant */ ([4]int{cap([]int{})})
-		_ = cap([4]int{cap([4]int{})})
-	)
-	var y float64
-	var z complex128
-	const (
-		_ = cap([4]float64{})
-		_ = cap([4]float64{y})
-		_ = cap([4]float64{real(2i)})
-		_ = cap /* ERROR not constant */ ([4]float64{real(z)})
-	)
-	var ch chan [10]int
-	const (
-		_ = cap /* ERROR not constant */ (<-ch)
-		_ = cap /* ERROR not constant */ ([4]int{(<-ch)[0]})
-	)
-}
-
-func close1() {
-	var c chan int
-	var r <-chan int
-	close() // ERROR not enough arguments
-	close(1, 2) // ERROR too many arguments
-	close(42 /* ERROR cannot close non-channel */)
-	close(r /* ERROR receive-only channel */)
-	close(c)
-	_ = close /* ERROR used as value */ (c)
-
-	var s []chan int
-	close(s... /* ERROR invalid use of \.\.\. */ )
-}
-
-func close2() {
-	f1 := func() (ch chan int) { return }
-	f2 := func() (ch chan int, x int) { return }
-	close(f0 /* ERROR used as value */ ())
-	close(f1())
-	close(f2()) // ERROR too many arguments
-}
-
-func complex1() {
-	var i32 int32
-	var f32 float32
-	var f64 float64
-	var c64 complex64
-	var c128 complex128
-	_ = complex() // ERROR not enough arguments
-	_ = complex(1) // ERROR not enough arguments
-	_ = complex(true /* ERROR mismatched types */ , 0)
-	_ = complex(i32 /* ERROR expected floating-point */ , 0)
-	_ = complex("foo" /* ERROR mismatched types */ , 0)
-	_ = complex(c64 /* ERROR expected floating-point */ , 0)
-	_ = complex(0 /* ERROR mismatched types */ , true)
-	_ = complex(0 /* ERROR expected floating-point */ , i32)
-	_ = complex(0 /* ERROR mismatched types */ , "foo")
-	_ = complex(0 /* ERROR expected floating-point */ , c64)
-	_ = complex(f32, f32)
-	_ = complex(f32, 1)
-	_ = complex(f32, 1.0)
-	_ = complex(f32, 'a')
-	_ = complex(f64, f64)
-	_ = complex(f64, 1)
-	_ = complex(f64, 1.0)
-	_ = complex(f64, 'a')
-	_ = complex(f32 /* ERROR mismatched types */ , f64)
-	_ = complex(f64 /* ERROR mismatched types */ , f32)
-	_ = complex(1, 1)
-	_ = complex(1, 1.1)
-	_ = complex(1, 'a')
-	complex /* ERROR not used */ (1, 2)
-
-	var _ complex64 = complex(f32, f32)
-	var _ complex64 = complex /* ERROR cannot use .* in variable declaration */ (f64, f64)
-
-	var _ complex128 = complex /* ERROR cannot use .* in variable declaration */ (f32, f32)
-	var _ complex128 = complex(f64, f64)
-
-	// untyped constants
-	const _ int = complex(1, 0)
-	const _ float32 = complex(1, 0)
-	const _ complex64 = complex(1, 0)
-	const _ complex128 = complex(1, 0)
-	const _ = complex(0i, 0i)
-	const _ = complex(0i, 0)
-	const _ int = 1.0 + complex(1, 0i)
-
-	const _ int = complex /* ERROR int */ (1.1, 0)
-	const _ float32 = complex /* ERROR float32 */ (1, 2)
-
-	// untyped values
-	var s uint
-	_ = complex(1 /* ERROR integer */ <<s, 0)
-	const _ = complex /* ERROR not constant */ (1 /* ERROR integer */ <<s, 0)
-	var _ int = complex /* ERROR cannot use .* in variable declaration */ (1 /* ERROR integer */ <<s, 0)
-
-	// floating-point argument types must be identical
-	type F32 float32
-	type F64 float64
-	var x32 F32
-	var x64 F64
-	c64 = complex(x32, x32)
-	_ = complex(x32 /* ERROR mismatched types */ , f32)
-	_ = complex(f32 /* ERROR mismatched types */ , x32)
-	c128 = complex(x64, x64)
-	_ = c128
-	_ = complex(x64 /* ERROR mismatched types */ , f64)
-	_ = complex(f64 /* ERROR mismatched types */ , x64)
-
-	var t []float32
-	_ = complex(t... /* ERROR invalid use of \.\.\. */ )
-}
-
-func complex2() {
-	f1 := func() (x float32) { return }
-	f2 := func() (x, y float32) { return }
-	f3 := func() (x, y, z float32) { return }
-	_ = complex(f0 /* ERROR used as value */ ())
-	_ = complex(f1()) // ERROR not enough arguments
-	_ = complex(f2())
-	_ = complex(f3()) // ERROR too many arguments
-}
-
-func copy1() {
-	copy() // ERROR not enough arguments
-	copy("foo") // ERROR not enough arguments
-	copy([ /* ERROR copy expects slice arguments */ ...]int{}, []int{})
-	copy([ /* ERROR copy expects slice arguments */ ]int{}, [...]int{})
-	copy([ /* ERROR different element types */ ]int8{}, "foo")
-
-	// spec examples
-	var a = [...]int{0, 1, 2, 3, 4, 5, 6, 7}
-	var s = make([]int, 6)
-	var b = make([]byte, 5)
-	n1 := copy(s, a[0:])            // n1 == 6, s == []int{0, 1, 2, 3, 4, 5}
-	n2 := copy(s, s[2:])            // n2 == 4, s == []int{2, 3, 4, 5, 4, 5}
-	n3 := copy(b, "Hello, World!")  // n3 == 5, b == []byte("Hello")
-	_, _, _ = n1, n2, n3
-
-	var t [][]int
-	copy(t, t)
-	copy(t /* ERROR copy expects slice arguments */ , nil)
-	copy(nil /* ERROR copy expects slice arguments */ , t)
-	copy(nil /* ERROR copy expects slice arguments */ , nil)
-	copy(t... /* ERROR invalid use of \.\.\. */ )
-}
-
-func copy2() {
-	f1 := func() (a []int) { return }
-	f2 := func() (a, b []int) { return }
-	f3 := func() (a, b, c []int) { return }
-	copy(f0 /* ERROR used as value */ ())
-	copy(f1()) // ERROR not enough arguments
-	copy(f2())
-	copy(f3()) // ERROR too many arguments
-}
-
-func delete1() {
-	var m map[string]int
-	var s string
-	delete() // ERROR not enough arguments
-	delete(1) // ERROR not enough arguments
-	delete(1, 2, 3) // ERROR too many arguments
-	delete(m, 0 /* ERROR cannot use */)
-	delete(m, s)
-	_ = delete /* ERROR used as value */ (m, s)
-
-	var t []map[string]string
-	delete(t... /* ERROR invalid use of \.\.\. */ )
-}
-
-func delete2() {
-	f1 := func() (m map[string]int) { return }
-	f2 := func() (m map[string]int, k string) { return }
-	f3 := func() (m map[string]int, k string, x float32) { return }
-	delete(f0 /* ERROR used as value */ ())
-	delete(f1()) // ERROR not enough arguments
-	delete(f2())
-	delete(f3()) // ERROR too many arguments
-}
-
-func imag1() {
-	var f32 float32
-	var f64 float64
-	var c64 complex64
-	var c128 complex128
-	_ = imag() // ERROR not enough arguments
-	_ = imag(1, 2) // ERROR too many arguments
-	_ = imag(10)
-	_ = imag(2.7182818)
-	_ = imag("foo" /* ERROR expected complex */)
-	_ = imag('a')
-	const _5 = imag(1 + 2i)
-	assert(_5 == 2)
-	f32 = _5
-	f64 = _5
-	const _6 = imag(0i)
-	assert(_6 == 0)
-	f32 = imag(c64)
-	f64 = imag(c128)
-	f32 = imag /* ERROR cannot use .* in assignment */ (c128)
-	f64 = imag /* ERROR cannot use .* in assignment */ (c64)
-	imag /* ERROR not used */ (c64)
-	_, _ = f32, f64
-
-	// complex type may not be predeclared
-	type C64 complex64
-	type C128 complex128
-	var x64 C64
-	var x128 C128
-	f32 = imag(x64)
-	f64 = imag(x128)
-
-	var a []complex64
-	_ = imag(a... /* ERROR invalid use of \.\.\. */ )
-
-	// if argument is untyped, result is untyped
-	const _ byte = imag(1.2 + 3i)
-	const _ complex128 = imag(1.2 + 3i)
-
-	// lhs constant shift operands are typed as complex128
-	var s uint
-	_ = imag(1 /* ERROR must be integer */ << s)
-}
-
-func imag2() {
-	f1 := func() (x complex128) { return }
-	f2 := func() (x, y complex128) { return }
-	_ = imag(f0 /* ERROR used as value */ ())
-	_ = imag(f1())
-	_ = imag(f2()) // ERROR too many arguments
-}
-
-func len1() {
-	const c = "foobar"
-	var a [10]bool
-	var p *[20]int
-	var m map[string]complex128
-	_ = len() // ERROR not enough arguments
-	_ = len(1, 2) // ERROR too many arguments
-	_ = len(42 /* ERROR invalid */)
-	const _3 = len(c)
-	assert(_3 == 6)
-	const _4 = len(a)
-	assert(_4 == 10)
-	const _5 = len(p)
-	assert(_5 == 20)
-	_ = len(m)
-	len /* ERROR not used */ (c)
-
-	// esoteric case
-	var t string
-	var hash map[interface{}][]*[10]int
-	const n = len /* ERROR not constant */ (hash[recover()][len(t)])
-	assert(n == 10) // ok because n has unknown value and no error is reported
-	var ch <-chan int
-	const nn = len /* ERROR not constant */ (hash[<-ch][len(t)])
-
-	// issue 4744
-	type T struct{ a [10]int }
-	const _ = len(((*T)(nil)).a)
-
-	var s [][]byte
-	_ = len(s)
-	_ = len(s... /* ERROR invalid use of \.\.\. */ )
-}
-
-func len2() {
-	f1 := func() (x []int) { return }
-	f2 := func() (x, y []int) { return }
-	_ = len(f0 /* ERROR used as value */ ())
-	_ = len(f1())
-	_ = len(f2()) // ERROR too many arguments
-}
-
-// test cases for issue 7387
-func len3() {
-	var f = func() int { return 0 }
-	var x = f()
-	const (
-		_ = len([4]int{})
-		_ = len([4]int{x})
-		_ = len /* ERROR not constant */ ([4]int{f()})
-		_ = len /* ERROR not constant */ ([4]int{len([]int{})})
-		_ = len([4]int{len([4]int{})})
-	)
-	var y float64
-	var z complex128
-	const (
-		_ = len([4]float64{})
-		_ = len([4]float64{y})
-		_ = len([4]float64{real(2i)})
-		_ = len /* ERROR not constant */ ([4]float64{real(z)})
-	)
-	var ch chan [10]int
-	const (
-		_ = len /* ERROR not constant */ (<-ch)
-		_ = len /* ERROR not constant */ ([4]int{(<-ch)[0]})
-	)
-}
-
-func make1() {
-	var n int
-	var m float32
-	var s uint
-
-	_ = make() // ERROR not enough arguments
-	_ = make(1 /* ERROR not a type */)
-	_ = make(int /* ERROR cannot make */)
-
-	// slices
-	_ = make/* ERROR arguments */ ([]int)
-	_ = make/* ERROR arguments */ ([]int, 2, 3, 4)
-	_ = make([]int, int /* ERROR not an expression */)
-	_ = make([]int, 10, float32 /* ERROR not an expression */)
-	_ = make([]int, "foo" /* ERROR cannot convert */)
-	_ = make([]int, 10, 2.3 /* ERROR truncated */)
-	_ = make([]int, 5, 10.0)
-	_ = make([]int, 0i)
-	_ = make([]int, 1.0)
-	_ = make([]int, 1.0<<s)
-	_ = make([]int, 1.1 /* ERROR int */ <<s)
-	_ = make([]int, - /* ERROR must not be negative */ 1, 10)
-	_ = make([]int, 0, - /* ERROR must not be negative */ 1)
-	_ = make([]int, - /* ERROR must not be negative */ 1, - /* ERROR must not be negative */ 1)
-	_ = make([]int, 1 /* ERROR overflows */ <<100, 1 /* ERROR overflows */ <<100)
-	_ = make([]int, 10 /* ERROR length and capacity swapped */ , 9)
-	_ = make([]int, 1 /* ERROR overflows */ <<100, 12345)
-	_ = make([]int, m /* ERROR must be integer */ )
-        _ = &make /* ERROR cannot take address */ ([]int, 0)
-
-	// maps
-	_ = make /* ERROR arguments */ (map[int]string, 10, 20)
-	_ = make(map[int]float32, int /* ERROR not an expression */)
-	_ = make(map[int]float32, "foo" /* ERROR cannot convert */)
-	_ = make(map[int]float32, 10)
-	_ = make(map[int]float32, n)
-	_ = make(map[int]float32, int64(n))
-	_ = make(map[string]bool, 10.0)
-	_ = make(map[string]bool, 10.0<<s)
-        _ = &make /* ERROR cannot take address */ (map[string]bool)
-
-	// channels
-	_ = make /* ERROR arguments */ (chan int, 10, 20)
-	_ = make(chan int, int /* ERROR not an expression */)
-	_ = make(chan<- int, "foo" /* ERROR cannot convert */)
-	_ = make(chan int, - /* ERROR must not be negative */ 10)
-	_ = make(<-chan float64, 10)
-	_ = make(chan chan int, n)
-	_ = make(chan string, int64(n))
-	_ = make(chan bool, 10.0)
-	_ = make(chan bool, 10.0<<s)
-        _ = &make /* ERROR cannot take address */ (chan bool)
-
-	make /* ERROR not used */ ([]int, 10)
-
-	var t []int
-	_ = make([]int, t[0], t[1])
-	_ = make([]int, t... /* ERROR invalid use of \.\.\. */ )
-}
-
-func make2() {
-	f1 /* ERROR not used */ := func() (x []int) { return }
-	_ = make(f0 /* ERROR not a type */ ())
-	_ = make(f1 /* ERROR not a type */ ())
-}
-
-func new1() {
-	_ = new() // ERROR not enough arguments
-	_ = new(1, 2) // ERROR too many arguments
-	_ = new("foo" /* ERROR not a type */)
-	p := new(float64)
-	_ = new(struct{ x, y int })
-	q := new(*float64)
-	_ = *p == **q
-	new /* ERROR not used */ (int)
-        _ = &new /* ERROR cannot take address */ (int)
-
-	_ = new(int... /* ERROR invalid use of \.\.\. */ )
-}
-
-func new2() {
-	f1 /* ERROR not used */ := func() (x []int) { return }
-	_ = new(f0 /* ERROR not a type */ ())
-	_ = new(f1 /* ERROR not a type */ ())
-}
-
-func panic1() {
-	panic() // ERROR not enough arguments
-	panic(1, 2) // ERROR too many arguments
-	panic(0)
-	panic("foo")
-	panic(false)
-	panic(1<<10)
-	panic(1 << /* ERROR constant shift overflow */ 1000)
-	_ = panic /* ERROR used as value */ (0)
-
-	var s []byte
-	panic(s)
-	panic(s... /* ERROR invalid use of \.\.\. */ )
-}
-
-func panic2() {
-	f1 := func() (x int) { return }
-	f2 := func() (x, y int) { return }
-	panic(f0 /* ERROR used as value */ ())
-	panic(f1())
-	panic(f2()) // ERROR too many arguments
-}
-
-func print1() {
-	print()
-	print(1)
-	print(1, 2)
-	print("foo")
-	print(2.718281828)
-	print(false)
-	print(1<<10)
-	print(1 << /* ERROR constant shift overflow */ 1000)
-	println(nil /* ERROR untyped nil */ )
-
-	var s []int
-	print(s... /* ERROR invalid use of \.\.\. */ )
-	_ = print /* ERROR used as value */ ()
-}
-
-func print2() {
-	f1 := func() (x int) { return }
-	f2 := func() (x, y int) { return }
-	f3 := func() (x int, y float32, z string) { return }
-	print(f0 /* ERROR used as value */ ())
-	print(f1())
-	print(f2())
-	print(f3())
-}
-
-func println1() {
-	println()
-	println(1)
-	println(1, 2)
-	println("foo")
-	println(2.718281828)
-	println(false)
-	println(1<<10)
-	println(1 << /* ERROR constant shift overflow */ 1000)
-	println(nil /* ERROR untyped nil */ )
-
-	var s []int
-	println(s... /* ERROR invalid use of \.\.\. */ )
-	_ = println /* ERROR used as value */ ()
-}
-
-func println2() {
-	f1 := func() (x int) { return }
-	f2 := func() (x, y int) { return }
-	f3 := func() (x int, y float32, z string) { return }
-	println(f0 /* ERROR used as value */ ())
-	println(f1())
-	println(f2())
-	println(f3())
-}
-
-func real1() {
-	var f32 float32
-	var f64 float64
-	var c64 complex64
-	var c128 complex128
-	_ = real() // ERROR not enough arguments
-	_ = real(1, 2) // ERROR too many arguments
-	_ = real(10)
-	_ = real(2.7182818)
-	_ = real("foo" /* ERROR expected complex */)
-	const _5 = real(1 + 2i)
-	assert(_5 == 1)
-	f32 = _5
-	f64 = _5
-	const _6 = real(0i)
-	assert(_6 == 0)
-	f32 = real(c64)
-	f64 = real(c128)
-	f32 = real /* ERROR cannot use .* in assignment */ (c128)
-	f64 = real /* ERROR cannot use .* in assignment */ (c64)
-	real /* ERROR not used */ (c64)
-
-	// complex type may not be predeclared
-	type C64 complex64
-	type C128 complex128
-	var x64 C64
-	var x128 C128
-	f32 = imag(x64)
-	f64 = imag(x128)
-	_, _ = f32, f64
-
-	var a []complex64
-	_ = real(a... /* ERROR invalid use of \.\.\. */ )
-
-	// if argument is untyped, result is untyped
-	const _ byte = real(1 + 2.3i)
-	const _ complex128 = real(1 + 2.3i)
-
-	// lhs constant shift operands are typed as complex128
-	var s uint
-	_ = real(1 /* ERROR must be integer */ << s)
-}
-
-func real2() {
-	f1 := func() (x complex128) { return }
-	f2 := func() (x, y complex128) { return }
-	_ = real(f0 /* ERROR used as value */ ())
-	_ = real(f1())
-	_ = real(f2()) // ERROR too many arguments
-}
-
-func recover1() {
-	_ = recover()
-	_ = recover(10) // ERROR too many arguments
-	recover()
-
-	var s []int
-	recover(s... /* ERROR invalid use of \.\.\. */ )
-}
-
-func recover2() {
-	f1 := func() (x int) { return }
-	f2 := func() (x, y int) { return }
-	_ = recover(f0 /* ERROR used as value */ ())
-	_ = recover(f1()) // ERROR too many arguments
-	_ = recover(f2()) // ERROR too many arguments
-}
-
-// assuming types.DefaultPtrSize == 8
-type S0 struct{      // offset
-	a bool       //  0
-	b rune       //  4
-	c *int       //  8
-	d bool       // 16
-	e complex128 // 24
-}                    // 40
-
-type S1 struct{   // offset
-	x float32 //  0
-	y string  //  8
-	z *S1     // 24
-	S0        // 32
-}                 // 72
-
-type S2 struct{ // offset
-	*S1     //  0
-}               //  8
-
-type S3 struct { // offset
-	a int64  //  0
-	b int32  //  8
-}                // 12
-
-type S4 struct { // offset
-	S3       //  0
-	int32    // 12
-}                // 16
-
-type S5 struct {   // offset
-	a [3]int32 //  0
-	b int32    // 12
-}                  // 16
-
-func (S2) m() {}
-
-func Alignof1() {
-	var x int
-	_ = unsafe.Alignof() // ERROR not enough arguments
-	_ = unsafe.Alignof(1, 2) // ERROR too many arguments
-	_ = unsafe.Alignof(int /* ERROR not an expression */)
-	_ = unsafe.Alignof(42)
-	_ = unsafe.Alignof(new(struct{}))
-	_ = unsafe.Alignof(1<<10)
-	_ = unsafe.Alignof(1 << /* ERROR constant shift overflow */ 1000)
-	_ = unsafe.Alignof(nil /* ERROR "untyped nil */ )
-	unsafe /* ERROR not used */ .Alignof(x)
-
-	var y S0
-	assert(unsafe.Alignof(y.a) == 1)
-	assert(unsafe.Alignof(y.b) == 4)
-	assert(unsafe.Alignof(y.c) == 8)
-	assert(unsafe.Alignof(y.d) == 1)
-	assert(unsafe.Alignof(y.e) == 8)
-
-	var s []byte
-	_ = unsafe.Alignof(s)
-	_ = unsafe.Alignof(s... /* ERROR invalid use of \.\.\. */ )
-}
-
-func Alignof2() {
-	f1 := func() (x int32) { return }
-	f2 := func() (x, y int32) { return }
-	_ = unsafe.Alignof(f0 /* ERROR used as value */ ())
-	assert(unsafe.Alignof(f1()) == 4)
-	_ = unsafe.Alignof(f2()) // ERROR too many arguments
-}
-
-func Offsetof1() {
-	var x struct{ f int }
-	_ = unsafe.Offsetof() // ERROR not enough arguments
-	_ = unsafe.Offsetof(1, 2) // ERROR too many arguments
-	_ = unsafe.Offsetof(int /* ERROR not a selector expression */ )
-	_ = unsafe.Offsetof(x /* ERROR not a selector expression */ )
-	_ = unsafe.Offsetof(nil /* ERROR not a selector expression */ )
-	_ = unsafe.Offsetof(x.f)
-	_ = unsafe.Offsetof((x.f))
-	_ = unsafe.Offsetof((((((((x))).f)))))
-	unsafe /* ERROR not used */ .Offsetof(x.f)
-
-	var y0 S0
-	assert(unsafe.Offsetof(y0.a) == 0)
-	assert(unsafe.Offsetof(y0.b) == 4)
-	assert(unsafe.Offsetof(y0.c) == 8)
-	assert(unsafe.Offsetof(y0.d) == 16)
-	assert(unsafe.Offsetof(y0.e) == 24)
-
-	var y1 S1
-	assert(unsafe.Offsetof(y1.x) == 0)
-	assert(unsafe.Offsetof(y1.y) == 8)
-	assert(unsafe.Offsetof(y1.z) == 24)
-	assert(unsafe.Offsetof(y1.S0) == 32)
-
-	assert(unsafe.Offsetof(y1.S0.a) == 0) // relative to S0
-	assert(unsafe.Offsetof(y1.a) == 32)   // relative to S1
-	assert(unsafe.Offsetof(y1.b) == 36)   // relative to S1
-	assert(unsafe.Offsetof(y1.c) == 40)   // relative to S1
-	assert(unsafe.Offsetof(y1.d) == 48)   // relative to S1
-	assert(unsafe.Offsetof(y1.e) == 56)   // relative to S1
-
-	var y1p *S1
-	assert(unsafe.Offsetof(y1p.S0) == 32)
-
-	type P *S1
-	var p P = y1p
-	assert(unsafe.Offsetof(p.S0) == 32)
-
-	var y2 S2
-	assert(unsafe.Offsetof(y2.S1) == 0)
-	_ = unsafe.Offsetof(y2 /* ERROR embedded via a pointer */ .x)
-	_ = unsafe.Offsetof(y2 /* ERROR method value */ .m)
-
-	var s []byte
-	_ = unsafe.Offsetof(s... /* ERROR invalid use of \.\.\. */ )
-}
-
-func Offsetof2() {
-	f1 := func() (x int32) { return }
-	f2 := func() (x, y int32) { return }
-	_ = unsafe.Offsetof(f0 /* ERROR not a selector expression */ ())
-	_ = unsafe.Offsetof(f1 /* ERROR not a selector expression */ ())
-	_ = unsafe.Offsetof(f2 /* ERROR not a selector expression */ ())
-}
-
-func Sizeof1() {
-	var x int
-	_ = unsafe.Sizeof() // ERROR not enough arguments
-	_ = unsafe.Sizeof(1, 2) // ERROR too many arguments
-	_ = unsafe.Sizeof(int /* ERROR not an expression */)
-	_ = unsafe.Sizeof(42)
-	_ = unsafe.Sizeof(new(complex128))
-	_ = unsafe.Sizeof(1<<10)
-	_ = unsafe.Sizeof(1 << /* ERROR constant shift overflow */ 1000)
-	_ = unsafe.Sizeof(nil /* ERROR untyped nil */ )
-	unsafe /* ERROR not used */ .Sizeof(x)
-
-	// basic types have size guarantees
-	assert(unsafe.Sizeof(byte(0)) == 1)
-	assert(unsafe.Sizeof(uint8(0)) == 1)
-	assert(unsafe.Sizeof(int8(0)) == 1)
-	assert(unsafe.Sizeof(uint16(0)) == 2)
-	assert(unsafe.Sizeof(int16(0)) == 2)
-	assert(unsafe.Sizeof(uint32(0)) == 4)
-	assert(unsafe.Sizeof(int32(0)) == 4)
-	assert(unsafe.Sizeof(float32(0)) == 4)
-	assert(unsafe.Sizeof(uint64(0)) == 8)
-	assert(unsafe.Sizeof(int64(0)) == 8)
-	assert(unsafe.Sizeof(float64(0)) == 8)
-	assert(unsafe.Sizeof(complex64(0)) == 8)
-	assert(unsafe.Sizeof(complex128(0)) == 16)
-
-	var y0 S0
-	assert(unsafe.Sizeof(y0.a) == 1)
-	assert(unsafe.Sizeof(y0.b) == 4)
-	assert(unsafe.Sizeof(y0.c) == 8)
-	assert(unsafe.Sizeof(y0.d) == 1)
-	assert(unsafe.Sizeof(y0.e) == 16)
-	assert(unsafe.Sizeof(y0) == 40)
-
-	var y1 S1
-	assert(unsafe.Sizeof(y1) == 72)
-
-	var y2 S2
-	assert(unsafe.Sizeof(y2) == 8)
-
-	var y3 S3
-	assert(unsafe.Sizeof(y3) == 12)
-
-	var y4 S4
-	assert(unsafe.Sizeof(y4) == 16)
-
-	var y5 S5
-	assert(unsafe.Sizeof(y5) == 16)
-
-	var a3 [10]S3
-	assert(unsafe.Sizeof(a3) == 156)
-
-	// test case for issue 5670
-	type T struct {
-		a int32
-		_ int32
-		c int32
-	}
-	assert(unsafe.Sizeof(T{}) == 12)
-
-	var s []byte
-	_ = unsafe.Sizeof(s)
-	_ = unsafe.Sizeof(s... /* ERROR invalid use of \.\.\. */ )
-}
-
-func Sizeof2() {
-	f1 := func() (x int64) { return }
-	f2 := func() (x, y int64) { return }
-	_ = unsafe.Sizeof(f0 /* ERROR used as value */ ())
-	assert(unsafe.Sizeof(f1()) == 8)
-	_ = unsafe.Sizeof(f2()) // ERROR too many arguments
-}
-
-// self-testing only
-func assert1() {
-	var x int
-	assert() /* ERROR not enough arguments */
-	assert(1, 2) /* ERROR too many arguments */
-	assert("foo" /* ERROR boolean constant */ )
-	assert(x /* ERROR boolean constant */)
-	assert(true)
-	assert /* ERROR failed */ (false)
-	_ = assert(true)
-
-	var s []byte
-	assert(s... /* ERROR invalid use of \.\.\. */ )
-}
-
-func assert2() {
-	f1 := func() (x bool) { return }
-	f2 := func() (x bool) { return }
-	assert(f0 /* ERROR used as value */ ())
-	assert(f1 /* ERROR boolean constant */ ())
-	assert(f2 /* ERROR boolean constant */ ())
-}
-
-// self-testing only
-func trace1() {
-	// Uncomment the code below to test trace - will produce console output
-	// _ = trace /* ERROR no value */ ()
-	// _ = trace(1)
-	// _ = trace(true, 1.2, '\'', "foo", 42i, "foo" <= "bar")
-
-	var s []byte
-	trace(s... /* ERROR invalid use of \.\.\. */ )
-}
-
-func trace2() {
-	f1 := func() (x int) { return }
-	f2 := func() (x int, y string) { return }
-	f3 := func() (x int, y string, z []int) { return }
-	_ = f1
-	_ = f2
-	_ = f3
-	// Uncomment the code below to test trace - will produce console output
-	// trace(f0())
-	// trace(f1())
-	// trace(f2())
-	// trace(f3())
-	// trace(f0(), 1)
-	// trace(f1(), 1, 2)
-	// trace(f2(), 1, 2, 3)
-	// trace(f3(), 1, 2, 3, 4)
-}
diff --git a/src/go/types/testdata/check/builtins1.go b/src/go/types/testdata/check/builtins1.go
deleted file mode 100644
index 8615973..0000000
--- a/src/go/types/testdata/check/builtins1.go
+++ /dev/null
@@ -1,274 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file tests built-in calls on generic types.
-
-package builtins
-
-import "unsafe"
-
-// close
-
-type C0 interface{ int }
-type C1 interface{ chan int }
-type C2 interface{ chan int | <-chan int }
-type C3 interface{ chan int | chan float32 }
-type C4 interface{ chan int | chan<- int }
-type C5[T any] interface{ ~chan T | chan<- T }
-
-func _[T any](ch T) {
-	close(ch /* ERROR cannot close non-channel */)
-}
-
-func _[T C0](ch T) {
-	close(ch /* ERROR cannot close non-channel */)
-}
-
-func _[T C1](ch T) {
-	close(ch)
-}
-
-func _[T C2](ch T) {
-	close(ch /* ERROR cannot close receive-only channel */)
-}
-
-func _[T C3](ch T) {
-	close(ch)
-}
-
-func _[T C4](ch T) {
-	close(ch)
-}
-
-func _[T C5[X], X any](ch T) {
-	close(ch)
-}
-
-// copy
-
-func _[T any](x, y T) {
-	copy(x /* ERROR copy expects slice arguments */ , y)
-}
-
-func _[T ~[]byte](x, y T) {
-	copy(x, y)
-	copy(x, "foo")
-	copy("foo" /* ERROR expects slice arguments */ , y)
-
-	var x2 []byte
-	copy(x2, y) // element types are identical
-	copy(y, x2) // element types are identical
-
-	type myByte byte
-	var x3 []myByte
-	copy(x3 /* ERROR different element types */ , y)
-	copy(y /* ERROR different element types */ , x3)
-}
-
-func _[T ~[]E, E any](x T, y []E) {
-	copy(x, y)
-	copy(x /* ERROR different element types */ , "foo")
-}
-
-func _[T ~string](x []byte, y T) {
-	copy(x, y)
-	copy(y /* ERROR expects slice arguments */ , x)
-}
-
-func _[T ~[]byte|~string](x T, y []byte) {
-	copy(x /* ERROR expects slice arguments */ , y)
-	copy(y, x)
-}
-
-type L0 []int
-type L1 []int
-
-func _[T L0 | L1](x, y T) {
-	copy(x, y)
-}
-
-// delete
-
-type M0 interface{ int }
-type M1 interface{ map[string]int }
-type M2 interface { map[string]int | map[string]float64 }
-type M3 interface{ map[string]int | map[rune]int }
-type M4[K comparable, V any] interface{ map[K]V | map[rune]V }
-
-func _[T any](m T) {
-	delete(m /* ERROR not a map */, "foo")
-}
-
-func _[T M0](m T) {
-	delete(m /* ERROR not a map */, "foo")
-}
-
-func _[T M1](m T) {
-	delete(m, "foo")
-}
-
-func _[T M2](m T) {
-	delete(m, "foo")
-	delete(m, 0 /* ERROR cannot use .* as string */)
-}
-
-func _[T M3](m T) {
-	delete(m /* ERROR must have identical key types */, "foo")
-}
-
-func _[T M4[rune, V], V any](m T) {
-	delete(m, 'k')
-}
-
-func _[T M4[K, V], K comparable, V any](m T) {
-	delete(m /* ERROR must have identical key types */, "foo")
-}
-
-// make
-
-type myChan chan int
-
-func _[
-	S1 ~[]int,
-	S2 ~[]int | ~chan int,
-
-	M1 ~map[string]int,
-	M2 ~map[string]int | ~chan int,
-
-	C1 ~chan int,
-	C2 ~chan int | ~chan string,
-	C3 chan int | myChan, // single underlying type
-]() {
-	type S0 []int
-	_ = make([]int, 10)
-	_ = make(S0, 10)
-	_ = make(S1, 10)
-	_ = make() /* ERROR not enough arguments */
-	_ = make /* ERROR expects 2 or 3 arguments */ (S1)
-	_ = make(S1, 10, 20)
-	_ = make /* ERROR expects 2 or 3 arguments */ (S1, 10, 20, 30)
-	_ = make(S2 /* ERROR cannot make S2: no core type */ , 10)
-
-	type M0 map[string]int
-	_ = make(map[string]int)
-	_ = make(M0)
-	_ = make(M1)
-	_ = make(M1, 10)
-	_ = make/* ERROR expects 1 or 2 arguments */(M1, 10, 20)
-	_ = make(M2 /* ERROR cannot make M2: no core type */ )
-
-	type C0 chan int
-	_ = make(chan int)
-	_ = make(C0)
-	_ = make(C1)
-	_ = make(C1, 10)
-	_ = make/* ERROR expects 1 or 2 arguments */(C1, 10, 20)
-	_ = make(C2 /* ERROR cannot make C2: no core type */ )
-	_ = make(C3)
-}
-
-// unsafe.Alignof
-
-func _[T comparable]() {
-	var (
-		b int64
-		a [10]T
-		s struct{ f T }
-		p *T
-		l []T
-		f func(T)
-		i interface{ m() T }
-		c chan T
-		m map[T]T
-		t T
-	)
-
-	const bb = unsafe.Alignof(b)
-	assert(bb == 8)
-	const _ = unsafe /* ERROR not constant */ .Alignof(a)
-	const _ = unsafe /* ERROR not constant */ .Alignof(s)
-	const pp = unsafe.Alignof(p)
-	assert(pp == 8)
-	const ll = unsafe.Alignof(l)
-	assert(ll == 8)
-	const ff = unsafe.Alignof(f)
-	assert(ff == 8)
-	const ii = unsafe.Alignof(i)
-	assert(ii == 8)
-	const cc = unsafe.Alignof(c)
-	assert(cc == 8)
-	const mm = unsafe.Alignof(m)
-	assert(mm == 8)
-	const _ = unsafe /* ERROR not constant */ .Alignof(t)
-}
-
-// unsafe.Offsetof
-
-func _[T comparable]() {
-	var (
-		b struct{ _, f int64 }
-		a struct{ _, f [10]T }
-		s struct{ _, f struct{ f T } }
-		p struct{ _, f *T }
-		l struct{ _, f []T }
-		f struct{ _, f func(T) }
-		i struct{ _, f interface{ m() T } }
-		c struct{ _, f chan T }
-		m struct{ _, f map[T]T }
-		t struct{ _, f T }
-	)
-
-	const bb = unsafe.Offsetof(b.f)
-	assert(bb == 8)
-	const _ = unsafe /* ERROR not constant */ .Alignof(a)
-	const _ = unsafe /* ERROR not constant */ .Alignof(s)
-	const pp = unsafe.Offsetof(p.f)
-	assert(pp == 8)
-	const ll = unsafe.Offsetof(l.f)
-	assert(ll == 24)
-	const ff = unsafe.Offsetof(f.f)
-	assert(ff == 8)
-	const ii = unsafe.Offsetof(i.f)
-	assert(ii == 16)
-	const cc = unsafe.Offsetof(c.f)
-	assert(cc == 8)
-	const mm = unsafe.Offsetof(m.f)
-	assert(mm == 8)
-	const _ = unsafe /* ERROR not constant */ .Alignof(t)
-}
-
-// unsafe.Sizeof
-
-func _[T comparable]() {
-	var (
-		b int64
-		a [10]T
-		s struct{ f T }
-		p *T
-		l []T
-		f func(T)
-		i interface{ m() T }
-		c chan T
-		m map[T]T
-		t T
-	)
-
-	const bb = unsafe.Sizeof(b)
-	assert(bb == 8)
-	const _ = unsafe /* ERROR not constant */ .Alignof(a)
-	const _ = unsafe /* ERROR not constant */ .Alignof(s)
-	const pp = unsafe.Sizeof(p)
-	assert(pp == 8)
-	const ll = unsafe.Sizeof(l)
-	assert(ll == 24)
-	const ff = unsafe.Sizeof(f)
-	assert(ff == 8)
-	const ii = unsafe.Sizeof(i)
-	assert(ii == 16)
-	const cc = unsafe.Sizeof(c)
-	assert(cc == 8)
-	const mm = unsafe.Sizeof(m)
-	assert(mm == 8)
-	const _ = unsafe /* ERROR not constant */ .Alignof(t)
-}
diff --git a/src/go/types/testdata/check/const0.go b/src/go/types/testdata/check/const0.go
deleted file mode 100644
index 229c248..0000000
--- a/src/go/types/testdata/check/const0.go
+++ /dev/null
@@ -1,382 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// constant declarations
-
-package const0
-
-import "unsafe"
-
-// constants declarations must be initialized by constants
-var x = 0
-const c0 = x /* ERROR "not constant" */
-
-// typed constants must have constant types
-const _ interface /* ERROR invalid constant type */ {} = 0
-
-func _ () {
-	const _ interface /* ERROR invalid constant type */ {} = 0
-	for i := 0; i < 10; i++ {} // don't crash with non-nil iota here
-}
-
-// untyped constants
-const (
-	// boolean values
-	ub0 = false
-	ub1 = true
-	ub2 = 2 < 1
-	ub3 = ui1 == uf1
-	ub4 = true /* ERROR "mismatched types untyped bool and untyped int" */ == 0
-
-	// integer values
-	ui0 = 0
-	ui1 = 1
-	ui2 = 42
-	ui3 = 3141592653589793238462643383279502884197169399375105820974944592307816406286
-	ui4 = -10
-
-	ui5 = ui0 + ui1
-	ui6 = ui1 - ui1
-	ui7 = ui2 * ui1
-	ui8 = ui3 / ui3
-	ui9 = ui3 % ui3
-
-	ui10 = 1 / 0 /* ERROR "division by zero" */
-	ui11 = ui1 / 0 /* ERROR "division by zero" */
-	ui12 = ui3 / ui0 /* ERROR "division by zero" */
-	ui13 = 1 % 0 /* ERROR "division by zero" */
-	ui14 = ui1 % 0 /* ERROR "division by zero" */
-	ui15 = ui3 % ui0 /* ERROR "division by zero" */
-
-	ui16 = ui2 & ui3
-	ui17 = ui2 | ui3
-	ui18 = ui2 ^ ui3
-	ui19 = 1 /* ERROR "invalid operation" */ % 1.0
-
-	// floating point values
-	uf0 = 0.
-	uf1 = 1.
-	uf2 = 4.2e1
-	uf3 = 3.141592653589793238462643383279502884197169399375105820974944592307816406286
-	uf4 = 1e-1
-
-	uf5 = uf0 + uf1
-	uf6 = uf1 - uf1
-	uf7 = uf2 * uf1
-	uf8 = uf3 / uf3
-	uf9 = uf3 /* ERROR "not defined" */ % uf3
-
-	uf10 = 1 / 0 /* ERROR "division by zero" */
-	uf11 = uf1 / 0 /* ERROR "division by zero" */
-	uf12 = uf3 / uf0 /* ERROR "division by zero" */
-
-	uf16 = uf2 /* ERROR "not defined" */ & uf3
-	uf17 = uf2 /* ERROR "not defined" */ | uf3
-	uf18 = uf2 /* ERROR "not defined" */ ^ uf3
-
-	// complex values
-	uc0 = 0.i
-	uc1 = 1.i
-	uc2 = 4.2e1i
-	uc3 = 3.141592653589793238462643383279502884197169399375105820974944592307816406286i
-	uc4 = 1e-1i
-
-	uc5 = uc0 + uc1
-	uc6 = uc1 - uc1
-	uc7 = uc2 * uc1
-	uc8 = uc3 / uc3
-	uc9 = uc3 /* ERROR "not defined" */ % uc3
-
-	uc10 = 1 / 0 /* ERROR "division by zero" */
-	uc11 = uc1 / 0 /* ERROR "division by zero" */
-	uc12 = uc3 / uc0 /* ERROR "division by zero" */
-
-	uc16 = uc2 /* ERROR "not defined" */ & uc3
-	uc17 = uc2 /* ERROR "not defined" */ | uc3
-	uc18 = uc2 /* ERROR "not defined" */ ^ uc3
-)
-
-type (
-	mybool bool
-	myint int
-	myfloat float64
-	mycomplex complex128
-)
-
-// typed constants
-const (
-	// boolean values
-	tb0 bool = false
-	tb1 bool = true
-	tb2 mybool = 2 < 1
-	tb3 mybool = ti1 /* ERROR "mismatched types" */ == tf1
-
-	// integer values
-	ti0 int8 = ui0
-	ti1 int32 = ui1
-	ti2 int64 = ui2
-	ti3 myint = ui3 /* ERROR "overflows" */
-	ti4 myint = ui4
-
-	ti5 = ti0 /* ERROR "mismatched types" */ + ti1
-	ti6 = ti1 - ti1
-	ti7 = ti2 /* ERROR "mismatched types" */ * ti1
-	ti8 = ti3 / ti3
-	ti9 = ti3 % ti3
-
-	ti10 = 1 / 0 /* ERROR "division by zero" */
-	ti11 = ti1 / 0 /* ERROR "division by zero" */
-	ti12 = ti3 /* ERROR "mismatched types" */ / ti0
-	ti13 = 1 % 0 /* ERROR "division by zero" */
-	ti14 = ti1 % 0 /* ERROR "division by zero" */
-	ti15 = ti3 /* ERROR "mismatched types" */ % ti0
-
-	ti16 = ti2 /* ERROR "mismatched types" */ & ti3
-	ti17 = ti2 /* ERROR "mismatched types" */ | ti4
-	ti18 = ti2 ^ ti5 // no mismatched types error because the type of ti5 is unknown
-
-	// floating point values
-	tf0 float32 = 0.
-	tf1 float32 = 1.
-	tf2 float64 = 4.2e1
-	tf3 myfloat = 3.141592653589793238462643383279502884197169399375105820974944592307816406286
-	tf4 myfloat = 1e-1
-
-	tf5 = tf0 + tf1
-	tf6 = tf1 - tf1
-	tf7 = tf2 /* ERROR "mismatched types" */ * tf1
-	tf8 = tf3 / tf3
-	tf9 = tf3 /* ERROR "not defined" */ % tf3
-
-	tf10 = 1 / 0 /* ERROR "division by zero" */
-	tf11 = tf1 / 0 /* ERROR "division by zero" */
-	tf12 = tf3 /* ERROR "mismatched types" */ / tf0
-
-	tf16 = tf2 /* ERROR "mismatched types" */ & tf3
-	tf17 = tf2 /* ERROR "mismatched types" */ | tf3
-	tf18 = tf2 /* ERROR "mismatched types" */ ^ tf3
-
-	// complex values
-	tc0 = 0.i
-	tc1 = 1.i
-	tc2 = 4.2e1i
-	tc3 = 3.141592653589793238462643383279502884197169399375105820974944592307816406286i
-	tc4 = 1e-1i
-
-	tc5 = tc0 + tc1
-	tc6 = tc1 - tc1
-	tc7 = tc2 * tc1
-	tc8 = tc3 / tc3
-	tc9 = tc3 /* ERROR "not defined" */ % tc3
-
-	tc10 = 1 / 0 /* ERROR "division by zero" */
-	tc11 = tc1 / 0 /* ERROR "division by zero" */
-	tc12 = tc3 / tc0 /* ERROR "division by zero" */
-
-	tc16 = tc2 /* ERROR "not defined" */ & tc3
-	tc17 = tc2 /* ERROR "not defined" */ | tc3
-	tc18 = tc2 /* ERROR "not defined" */ ^ tc3
-)
-
-// initialization cycles
-const (
-	a /* ERROR "initialization cycle" */ = a
-	b /* ERROR "initialization cycle" */ , c /* ERROR "initialization cycle" */, d, e = e, d, c, b // TODO(gri) should only have one cycle error
-	f float64 = d
-)
-
-// multiple initialization
-const (
-	a1, a2, a3 = 7, 3.1415926, "foo"
-	b1, b2, b3 = b3, b1, 42
-	c1, c2, c3  /* ERROR "missing init expr for c3" */ = 1, 2
-	d1, d2, d3 = 1, 2, 3, 4 /* ERROR "extra init expr 4" */
-	_p0 = assert(a1 == 7)
-	_p1 = assert(a2 == 3.1415926)
-	_p2 = assert(a3 == "foo")
-	_p3 = assert(b1 == 42)
-	_p4 = assert(b2 == 42)
-	_p5 = assert(b3 == 42)
-)
-
-func _() {
-	const (
-		a1, a2, a3 = 7, 3.1415926, "foo"
-		b1, b2, b3 = b3, b1, 42
-		c1, c2, c3  /* ERROR "missing init expr for c3" */ = 1, 2
-		d1, d2, d3 = 1, 2, 3, 4 /* ERROR "extra init expr 4" */
-		_p0 = assert(a1 == 7)
-		_p1 = assert(a2 == 3.1415926)
-		_p2 = assert(a3 == "foo")
-		_p3 = assert(b1 == 42)
-		_p4 = assert(b2 == 42)
-		_p5 = assert(b3 == 42)
-	)
-}
-
-// iota
-const (
-	iota0 = iota
-	iota1 = iota
-	iota2 = iota*2
-	_a0 = assert(iota0 == 0)
-	_a1 = assert(iota1 == 1)
-	_a2 = assert(iota2 == 4)
-	iota6 = iota*3
-
-	iota7
-	iota8
-	_a3 = assert(iota7 == 21)
-	_a4 = assert(iota8 == 24)
-)
-
-const (
-	_b0 = iota
-	_b1 = assert(iota + iota2 == 5)
-	_b2 = len([iota]int{}) // iota may appear in a type!
-	_b3 = assert(_b2 == 2)
-	_b4 = len(A{})
-)
-
-type A [iota /* ERROR "cannot use iota" */ ]int
-
-// constant expressions with operands across different
-// constant declarations must use the right iota values
-const (
-	_c0 = iota
-	_c1
-	_c2
-	_x = _c2 + _d1 + _e0 // 3
-)
-
-const (
-	_d0 = iota
-	_d1
-)
-
-const (
-	_e0 = iota
-)
-
-var _ = assert(_x == 3)
-
-// special cases
-const (
-	_n0 = nil /* ERROR "not constant" */
-	_n1 = [ /* ERROR "not constant" */ ]int{}
-)
-
-// iotas must not be usable in expressions outside constant declarations
-type _ [iota /* ERROR "iota outside constant decl" */ ]byte
-var _ = iota /* ERROR "iota outside constant decl" */
-func _() {
-	_ = iota /* ERROR "iota outside constant decl" */
-	const _ = iota
-	_ = iota /* ERROR "iota outside constant decl" */
-}
-
-func _() {
-	iota := 123
-	const x = iota /* ERROR "is not constant" */
-	var y = iota
-	_ = y
-}
-
-// iotas are usable inside closures in constant declarations (#22345)
-const (
-	_ = iota
-	_ = len([iota]byte{})
-	_ = unsafe.Sizeof(iota)
-	_ = unsafe.Sizeof(func() { _ = iota })
-	_ = unsafe.Sizeof(func() { var _ = iota })
-	_ = unsafe.Sizeof(func() { const _ = iota })
-	_ = unsafe.Sizeof(func() { type _ [iota]byte })
-	_ = unsafe.Sizeof(func() { func() int { return iota }() })
-)
-
-// verify inner and outer const declarations have distinct iotas
-const (
-	zero = iota
-	one  = iota
-	_    = unsafe.Sizeof(func() {
-		var x [iota]int // [2]int
-		const (
-			Zero = iota
-			One
-			Two
-			_ = unsafe.Sizeof([iota-1]int{} == x) // assert types are equal
-			_ = unsafe.Sizeof([Two]int{} == x)    // assert types are equal
-		)
-		var z [iota]int                           // [2]int
-		_ = unsafe.Sizeof([2]int{} == z)          // assert types are equal
-	})
-	three = iota // the sequence continues
-)
-var _ [three]int = [3]int{} // assert 'three' has correct value
-
-var (
-	_ = iota /* ERROR "iota outside constant decl" */
-	_ = unsafe.Sizeof(iota  /* ERROR "iota outside constant decl" */ )
-	_ = unsafe.Sizeof(func() { _ = iota /* ERROR "iota outside constant decl" */ })
-	_ = unsafe.Sizeof(func() { var _ = iota /* ERROR "iota outside constant decl" */ })
-	_ = unsafe.Sizeof(func() { type _ [iota /* ERROR "iota outside constant decl" */ ]byte })
-	_ = unsafe.Sizeof(func() { func() int { return iota /* ERROR "iota outside constant decl" */ }() })
-)
-
-// constant arithmetic precision and rounding must lead to expected (integer) results
-var _ = []int64{
-	0.0005 * 1e9,
-	0.001 * 1e9,
-	0.005 * 1e9,
-	0.01 * 1e9,
-	0.05 * 1e9,
-	0.1 * 1e9,
-	0.5 * 1e9,
-	1 * 1e9,
-	5 * 1e9,
-}
-
-const _ = unsafe.Sizeof(func() {
-	const _ = 0
-	_ = iota
-
-	const (
-	   zero = iota
-	   one
-	)
-	assert(one == 1)
-	assert(iota == 0)
-})
-
-// issue #52438
-const i1 = iota
-const i2 = iota
-const i3 = iota
-
-func _() {
-	assert(i1 == 0)
-	assert(i2 == 0)
-	assert(i3 == 0)
-
-	const i4 = iota
-	const i5 = iota
-	const i6 = iota
-
-	assert(i4 == 0)
-	assert(i5 == 0)
-	assert(i6 == 0)
-}
-
-// untyped constants must not get arbitrarily large
-const prec = 512 // internal maximum precision for integers
-const maxInt = (1<<(prec/2) - 1) * (1<<(prec/2) + 1) // == 1<<prec - 1
-
-const _ = maxInt + /* ERROR constant addition overflow */ 1
-const _ = -maxInt - /* ERROR constant subtraction overflow */ 1
-const _ = maxInt ^ /* ERROR constant bitwise XOR overflow */ -1
-const _ = maxInt * /* ERROR constant multiplication overflow */ 2
-const _ = maxInt << /* ERROR constant shift overflow */ 2
-const _ = 1 << /* ERROR constant shift overflow */ prec
-
-const _ = ^ /* ERROR constant bitwise complement overflow */ maxInt
diff --git a/src/go/types/testdata/check/constdecl.go b/src/go/types/testdata/check/constdecl.go
deleted file mode 100644
index f7a9dd4..0000000
--- a/src/go/types/testdata/check/constdecl.go
+++ /dev/null
@@ -1,163 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package constdecl
-
-import "math"
-import "unsafe"
-
-var v int
-
-// Const decls must be initialized by constants.
-const _ = v /* ERROR "not constant" */
-const _ = math /* ERROR "not constant" */ .Sin(0)
-const _ = int /* ERROR "not an expression" */
-
-func _() {
-	const _ = v /* ERROR "not constant" */
-	const _ = math /* ERROR "not constant" */ .Sin(0)
-	const _ = int /* ERROR "not an expression" */
-}
-
-// Identifier and expression arity must match.
-// The first error message is produced by the parser.
-// In a real-world scenario, the type-checker would not be run
-// in this case and the 2nd error message would not appear.
-const _ /* ERROR "missing constant value" */ /* ERROR "missing init expr for _" */
-const _ = 1, 2 /* ERROR "extra init expr 2" */
-
-const _ /* ERROR "missing constant value" */ /* ERROR "missing init expr for _" */ int
-const _ int = 1, 2 /* ERROR "extra init expr 2" */
-
-const (
-	_ /* ERROR "missing constant value" */ /* ERROR "missing init expr for _" */
-	_ = 1, 2 /* ERROR "extra init expr 2" */
-
-	_ /* ERROR "missing constant value" */ /* ERROR "missing init expr for _" */ int
-	_ int = 1, 2 /* ERROR "extra init expr 2" */
-)
-
-const (
-	_ = 1
-	_
-	_, _ /* ERROR "missing init expr for _" */
-	_
-)
-
-const (
-	_, _ = 1, 2
-	_, _
-	_ /* ERROR "extra init expr at" */
-	_, _
-	_, _, _ /* ERROR "missing init expr for _" */
-	_, _
-)
-
-func _() {
-	const _ /* ERROR "missing constant value" */ /* ERROR "missing init expr for _" */
-	const _ = 1, 2 /* ERROR "extra init expr 2" */
-
-	const _ /* ERROR "missing constant value" */ /* ERROR "missing init expr for _" */ int
-	const _ int = 1, 2 /* ERROR "extra init expr 2" */
-
-	const (
-		_ /* ERROR "missing constant value" */ /* ERROR "missing init expr for _" */
-		_ = 1, 2 /* ERROR "extra init expr 2" */
-
-		_ /* ERROR "missing constant value" */ /* ERROR "missing init expr for _" */ int
-		_ int = 1, 2 /* ERROR "extra init expr 2" */
-	)
-
-	const (
-		_ = 1
-		_
-		_, _ /* ERROR "missing init expr for _" */
-		_
-	)
-
-	const (
-		_, _ = 1, 2
-		_, _
-		_ /* ERROR "extra init expr at" */
-		_, _
-		_, _, _ /* ERROR "missing init expr for _" */
-		_, _
-	)
-}
-
-// Test case for constant with invalid initialization.
-// Caused panic because the constant value was not set up (gri - 7/8/2014).
-func _() {
-	const (
-	    x string = missing /* ERROR "undeclared name" */
-	    y = x + ""
-	)
-}
-
-// Test case for constants depending on function literals (see also #22992).
-const A /* ERROR initialization cycle */ = unsafe.Sizeof(func() { _ = A })
-
-func _() {
-	// The function literal below must not see a.
-	const a = unsafe.Sizeof(func() { _ = a /* ERROR "undeclared name" */ })
-	const b = unsafe.Sizeof(func() { _ = a })
-
-	// The function literal below must not see x, y, or z.
-	const x, y, z = 0, 1, unsafe.Sizeof(func() { _ = x /* ERROR "undeclared name" */ + y /* ERROR "undeclared name" */ + z /* ERROR "undeclared name" */ })
-}
-
-// Test cases for errors in inherited constant initialization expressions.
-// Errors related to inherited initialization expressions must appear at
-// the constant identifier being declared, not at the original expression
-// (issues #42991, #42992).
-const (
-	_ byte = 255 + iota
-	/* some gap */
-	_ // ERROR overflows
-	/* some gap */
-	/* some gap */ _ /* ERROR overflows */; _ /* ERROR overflows */
-	/* some gap */
-	_ = 255 + iota
-	_ = byte /* ERROR overflows */ (255) + iota
-	_ /* ERROR overflows */
-)
-
-// Test cases from issue.
-const (
-	ok = byte(iota + 253)
-	bad
-	barn
-	bard // ERROR cannot convert
-)
-
-const (
-	c = len([1 - iota]int{})
-	d
-	e // ERROR invalid array length
-	f // ERROR invalid array length
-)
-
-// Test that identifiers in implicit (omitted) RHS
-// expressions of constant declarations are resolved
-// in the correct context; see issues #49157, #53585.
-const X = 2
-
-func _() {
-	const (
-		A    = iota // 0
-		iota = iota // 1
-		B           // 1 (iota is declared locally on prev. line)
-		C           // 1
-	)
-	assert(A == 0 && B == 1 && C == 1)
-
-	const (
-		X = X + X
-		Y
-		Z = iota
-	)
-	assert(X == 4 && Y == 8 && Z == 1)
-}
-
-// TODO(gri) move extra tests from testdata/const0.src into here
diff --git a/src/go/types/testdata/check/cycles0.go b/src/go/types/testdata/check/cycles0.go
deleted file mode 100644
index 27b6111..0000000
--- a/src/go/types/testdata/check/cycles0.go
+++ /dev/null
@@ -1,175 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package cycles
-
-import "unsafe"
-
-type (
-	T0 int
-	T1 /* ERROR cycle */ T1
-	T2 *T2
-
-	T3 /* ERROR cycle */ T4
-	T4 T5
-	T5 T3
-
-	T6 T7
-	T7 *T8
-	T8 T6
-
-	// arrays
-	A0 /* ERROR cycle */ [10]A0
-	A1 [10]*A1
-
-	A2 /* ERROR cycle */ [10]A3
-	A3 [10]A4
-	A4 A2
-
-	A5 [10]A6
-	A6 *A5
-
-	// slices
-	L0 []L0
-
-	// structs
-	S0 /* ERROR cycle */ struct{ _ S0 }
-	S1 /* ERROR cycle */ struct{ S1 }
-	S2 struct{ _ *S2 }
-	S3 struct{ *S3 }
-
-	S4 /* ERROR cycle */ struct{ S5 }
-	S5 struct{ S6 }
-	S6 S4
-
-	// pointers
-	P0 *P0
-	PP *struct{ PP.f /* ERROR no field or method f */ }
-
-	// functions
-	F0 func(F0)
-	F1 func() F1
-	F2 func(F2) F2
-
-	// interfaces
-	I0 /* ERROR cycle */ interface{ I0 }
-
-	I1 /* ERROR cycle */ interface{ I2 }
-	I2 interface{ I3 }
-	I3 interface{ I1 }
-
-	I4 interface{ f(I4) }
-
-	// testcase for issue 5090
-	I5 interface{ f(I6) }
-	I6 interface{ I5 }
-
-	// maps
-	M0 map[M0 /* ERROR incomparable map key */ ]M0
-
-	// channels
-	C0 chan C0
-)
-
-// test case for issue #34771
-type (
-	AA /* ERROR cycle */ B
-	B C
-	C [10]D
-	D E
-	E AA
-)
-
-func _() {
-	type (
-		t1 /* ERROR cycle */ t1
-		t2 *t2
-
-		t3 t4 /* ERROR undeclared */
-		t4 t5 /* ERROR undeclared */
-		t5 t3
-
-		// arrays
-		a0 /* ERROR cycle */ [10]a0
-		a1 [10]*a1
-
-		// slices
-		l0 []l0
-
-		// structs
-		s0 /* ERROR cycle */ struct{ _ s0 }
-		s1 /* ERROR cycle */ struct{ s1 }
-		s2 struct{ _ *s2 }
-		s3 struct{ *s3 }
-
-		// pointers
-		p0 *p0
-
-		// functions
-		f0 func(f0)
-		f1 func() f1
-		f2 func(f2) f2
-
-		// interfaces
-		i0 /* ERROR cycle */ interface{ i0 }
-
-		// maps
-		m0 map[m0 /* ERROR incomparable map key */ ]m0
-
-		// channels
-		c0 chan c0
-	)
-}
-
-// test cases for issue 6667
-
-type A [10]map[A /* ERROR incomparable map key */ ]bool
-
-type S struct {
-	m map[S /* ERROR incomparable map key */ ]bool
-}
-
-// test cases for issue 7236
-// (cycle detection must not be dependent on starting point of resolution)
-
-type (
-	P1 *T9
-	T9 /* ERROR cycle */ T9
-
-	T10 /* ERROR cycle */ T10
-	P2 *T10
-)
-
-func (T11) m() {}
-
-type T11 /* ERROR cycle */ struct{ T11 }
-
-type T12 /* ERROR cycle */ struct{ T12 }
-
-func (*T12) m() {}
-
-type (
-	P3 *T13
-	T13 /* ERROR cycle */ T13
-)
-
-// test cases for issue 18643
-// (type cycle detection when non-type expressions are involved)
-type (
-	T14 [len(T14 /* ERROR cycle */ {})]int
-	T15 [][len(T15 /* ERROR cycle */ {})]int
-	T16 map[[len(T16 /* ERROR cycle */ {1:2})]int]int
-	T17 map[int][len(T17 /* ERROR cycle */ {1:2})]int
-)
-
-// Test case for types depending on function literals (see also #22992).
-type T20 chan [unsafe.Sizeof(func(ch T20){ _ = <-ch })]byte
-type T22 = chan [unsafe.Sizeof(func(ch T20){ _ = <-ch })]byte
-
-func _() {
-	type T0 func(T0)
-	type T1 /* ERROR cycle */ = func(T1)
-	type T2 chan [unsafe.Sizeof(func(ch T2){ _ = <-ch })]byte
-	type T3 /* ERROR cycle */ = chan [unsafe.Sizeof(func(ch T3){ _ = <-ch })]byte
-}
diff --git a/src/go/types/testdata/check/cycles2.go b/src/go/types/testdata/check/cycles2.go
deleted file mode 100644
index 1a7f40a..0000000
--- a/src/go/types/testdata/check/cycles2.go
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-import "unsafe"
-
-// Test case for issue 5090
-
-type t interface {
-	f(u)
-}
-
-type u interface {
-	t
-}
-
-func _() {
-	var t t
-	var u u
-
-	t.f(t)
-	t.f(u)
-
-	u.f(t)
-	u.f(u)
-}
-
-
-// Test case for issues #6589, #33656.
-
-type A interface {
-	a() interface {
-		AB
-	}
-}
-
-type B interface {
-	b() interface {
-		AB
-	}
-}
-
-type AB interface {
-	a() interface {
-		A
-		B
-	}
-	b() interface {
-		A
-		B
-	}
-}
-
-var x AB
-var y interface {
-	A
-	B
-}
-
-var _ = x == y
-
-
-// Test case for issue 6638.
-
-type T interface {
-	m() [T(nil).m /* ERROR undefined */ ()[0]]int
-}
-
-// Variations of this test case.
-
-type T1 /* ERROR cycle */ interface {
-	m() [x1.m()[0]]int
-}
-
-var x1 T1
-
-type T2 /* ERROR cycle */ interface {
-	m() [len(x2.m())]int
-}
-
-var x2 T2
-
-type T3 /* ERROR cycle */ interface {
-	m() [unsafe.Sizeof(x3.m)]int
-}
-
-var x3 T3
-
-type T4 /* ERROR cycle */ interface {
-	m() [unsafe.Sizeof(cast4(x4.m))]int // cast is invalid but we have a cycle, so all bets are off
-}
-
-var x4 T4
-var _ = cast4(x4.m)
-
-type cast4 func()
diff --git a/src/go/types/testdata/check/cycles3.go b/src/go/types/testdata/check/cycles3.go
deleted file mode 100644
index 5e89b62..0000000
--- a/src/go/types/testdata/check/cycles3.go
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-import "unsafe"
-
-var (
-	_ A = A(nil).a().b().c().d().e().f()
-	_ A = A(nil).b().c().d().e().f()
-	_ A = A(nil).c().d().e().f()
-	_ A = A(nil).d().e().f()
-	_ A = A(nil).e().f()
-	_ A = A(nil).f()
-	_ A = A(nil)
-)
-
-type (
-	A interface {
-		a() B
-		B
-	}
-
-	B interface {
-		b() C
-		C
-	}
-
-	C interface {
-		c() D
-		D
-	}
-
-	D interface {
-		d() E
-		E
-	}
-
-	E interface {
-		e() F
-		F
-	}
-
-	F interface {
-		f() A
-	}
-)
-
-type (
-	U /* ERROR cycle */ interface {
-		V
-	}
-
-	V interface {
-		v() [unsafe.Sizeof(u)]int
-	}
-)
-
-var u U
diff --git a/src/go/types/testdata/check/cycles5.go b/src/go/types/testdata/check/cycles5.go
deleted file mode 100644
index c932ef9..0000000
--- a/src/go/types/testdata/check/cycles5.go
+++ /dev/null
@@ -1,200 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-import "unsafe"
-
-// test case from issue #18395
-
-type (
-	A interface { B }
-	B interface { C }
-	C interface { D; F() A }
-	D interface { G() B }
-)
-
-var _ = A(nil).G // G must be found
-
-
-// test case from issue #21804
-
-type sourceBridge interface {
-	listVersions() ([]Version, error)
-}
-
-type Constraint interface {
-	copyTo(*ConstraintMsg)
-}
-
-type ConstraintMsg struct{}
-
-func (m *ConstraintMsg) asUnpairedVersion() UnpairedVersion {
-	return nil
-}
-
-type Version interface {
-	Constraint
-}
-
-type UnpairedVersion interface {
-	Version
-}
-
-var _ Constraint = UnpairedVersion(nil)
-
-
-// derived test case from issue #21804
-
-type (
-	_ interface{ m(B1) }
-	A1 interface{ a(D1) }
-	B1 interface{ A1 }
-	C1 interface{ B1 }
-	D1 interface{ C1 }
-)
-
-var _ A1 = C1(nil)
-
-
-// derived test case from issue #22701
-
-func F(x I4) interface{} {
-	return x.Method()
-}
-
-type Unused interface {
-	RefersToI1(a I1)
-}
-
-type I1 interface {
-	I2
-	I3
-}
-
-type I2 interface {
-	RefersToI4() I4
-}
-
-type I3 interface {
-	Method() interface{}
-}
-
-type I4 interface {
-	I1
-}
-
-
-// check embedding of error interface
-
-type Error interface{ error }
-
-var err Error
-var _ = err.Error()
-
-
-// more esoteric cases
-
-type (
-	T1 interface { T2 }
-	T2 /* ERROR cycle */ T2
-)
-
-type (
-	T3 interface { T4 }
-	T4 /* ERROR cycle */ T5
-	T5 = T6
-	T6 = T7
-	T7 = T4
-)
-
-
-// arbitrary code may appear inside an interface
-
-const n = unsafe.Sizeof(func(){})
-
-type I interface {
-	m([unsafe.Sizeof(func() { I.m(nil, [n]byte{}) })]byte)
-}
-
-
-// test cases for varias alias cycles
-
-type T10 /* ERROR cycle */ = *T10                 // issue #25141
-type T11 /* ERROR cycle */ = interface{ f(T11) }  // issue #23139
-
-// issue #18640
-type (
-	aa = bb
-	bb struct {
-		*aa
-	}
-)
-
-type (
-	a struct{ *b }
-	b = c
-	c struct{ *b /* ERROR invalid use of type alias */ }
-)
-
-// issue #24939
-type (
-	_ interface {
-		M(P)
-	}
-
-	M interface {
-		F() P // ERROR invalid use of type alias
-	}
-
-	P = interface {
-		I() M
-	}
-)
-
-// issue #8699
-type T12 /* ERROR cycle */ [len(a12)]int
-var a12 = makeArray()
-func makeArray() (res T12) { return }
-
-// issue #20770
-var r /* ERROR cycle */ = newReader()
-func newReader() r
-
-// variations of the theme of #8699 and #20770
-var arr /* ERROR cycle */ = f()
-func f() [len(arr)]int
-
-// issue #25790
-func ff(ff /* ERROR not a type */ )
-func gg((gg /* ERROR not a type */ ))
-
-type T13 /* ERROR cycle */ [len(b13)]int
-var b13 T13
-
-func g1() [unsafe.Sizeof(g1)]int
-func g2() [unsafe.Sizeof(x2)]int
-var x2 = g2
-
-// verify that we get the correct sizes for the functions above
-// (note: assert is statically evaluated in go/types test mode)
-func init() {
-	assert(unsafe.Sizeof(g1) == 8)
-	assert(unsafe.Sizeof(x2) == 8)
-}
-
-func h() [h /* ERROR no value */ ()[0]]int { panic(0) }
-
-var c14 /* ERROR cycle */ T14
-type T14 [uintptr(unsafe.Sizeof(&c14))]byte
-
-// issue #34333
-type T15 /* ERROR cycle */ struct {
-	f func() T16
-	b T16
-}
-
-type T16 struct {
-	T15
-}
\ No newline at end of file
diff --git a/src/go/types/testdata/check/decls0.go b/src/go/types/testdata/check/decls0.go
deleted file mode 100644
index d8fcef0..0000000
--- a/src/go/types/testdata/check/decls0.go
+++ /dev/null
@@ -1,210 +0,0 @@
-// -lang=go1.17
-
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// type declarations
-
-package p // don't permit non-interface elements in interfaces
-
-import "unsafe"
-
-const pi = 3.1415
-
-type (
-	N undeclared /* ERROR "undeclared" */
-	B bool
-	I int32
-	A [10]P
-	T struct {
-		x, y P
-	}
-	P *T
-	R (*R)
-	F func(A) I
-	Y interface {
-		f(A) I
-	}
-	S [](((P)))
-	M map[I]F
-	C chan<- I
-
-	// blank types must be typechecked
-	_ pi /* ERROR "not a type" */
-	_ struct{}
-	_ struct{ pi /* ERROR "not a type" */ }
-)
-
-
-// declarations of init
-const _, init /* ERROR "cannot declare init" */ , _ = 0, 1, 2
-type init /* ERROR "cannot declare init" */ struct{}
-var _, init /* ERROR "cannot declare init" */ int
-
-func init() {}
-func init /* ERROR "missing function body" */ ()
-
-func _() { const init = 0 }
-func _() { type init int }
-func _() { var init int; _ = init }
-
-// invalid array types
-type (
-	iA0 [... /* ERROR "invalid use of '...'" */ ]byte
-	// The error message below could be better. At the moment
-	// we believe an integer that is too large is not an integer.
-	// But at least we get an error.
-	iA1 [1 /* ERROR "must be integer" */ <<100]int
-	iA2 [- /* ERROR "invalid array length" */ 1]complex128
-	iA3 ["foo" /* ERROR "must be integer" */ ]string
-	iA4 [float64 /* ERROR "must be integer" */ (0)]int
-)
-
-
-type (
-	p1 pi.foo /* ERROR "no field or method foo" */
-	p2 unsafe.Pointer
-)
-
-
-type (
-	Pi pi /* ERROR "not a type" */
-
-	a /* ERROR "illegal cycle" */ a
-	a /* ERROR "redeclared" */ int
-
-	b /* ERROR "illegal cycle" */ c
-	c d
-	d e
-	e b
-
-	t *t
-
-	U V
-	V *W
-	W U
-
-	P1 *S2
-	P2 P1
-
-	S0 struct {
-	}
-	S1 struct {
-		a, b, c int
-		u, v, a /* ERROR "redeclared" */ float32
-	}
-	S2 struct {
-		S0 // embedded field
-		S0 /* ERROR "redeclared" */ int
-	}
-	S3 struct {
-		x S2
-	}
-	S4/* ERROR "illegal cycle" */ struct {
-		S4
-	}
-	S5 /* ERROR "illegal cycle" */ struct {
-		S6
-	}
-	S6 struct {
-		field S7
-	}
-	S7 struct {
-		S5
-	}
-
-	L1 []L1
-	L2 []int
-
-	A1 [10.0]int
-	A2 /* ERROR "illegal cycle" */ [10]A2
-	A3 /* ERROR "illegal cycle" */ [10]struct {
-		x A4
-	}
-	A4 [10]A3
-
-	F1 func()
-	F2 func(x, y, z float32)
-	F3 func(x, y, x /* ERROR "redeclared" */ float32)
-	F4 func() (x, y, x /* ERROR "redeclared" */ float32)
-	F5 func(x int) (x /* ERROR "redeclared" */ float32)
-	F6 func(x ...int)
-
-	I1 interface{}
-	I2 interface {
-		m1()
-	}
-	I3 interface {
-		m1()
-		m1 /* ERROR "duplicate method" */ ()
-	}
-	I4 interface {
-		m1(x, y, x /* ERROR "redeclared" */ float32)
-		m2() (x, y, x /* ERROR "redeclared" */ float32)
-		m3(x int) (x /* ERROR "redeclared" */ float32)
-	}
-	I5 interface {
-		m1(I5)
-	}
-	I6 interface {
-		S0 /* ERROR "non-interface type S0" */
-	}
-	I7 interface {
-		I1
-		I1
-	}
-	I8 /* ERROR "illegal cycle" */ interface {
-		I8
-	}
-	I9 /* ERROR "illegal cycle" */ interface {
-		I10
-	}
-	I10 interface {
-		I11
-	}
-	I11 interface {
-		I9
-	}
-
-	C1 chan int
-	C2 <-chan int
-	C3 chan<- C3
-	C4 chan C5
-	C5 chan C6
-	C6 chan C4
-
-	M1 map[Last]string
-	M2 map[string]M2
-
-	Last int
-)
-
-// cycles in function/method declarations
-// (test cases for issues #5217, #25790 and variants)
-func f1(x f1 /* ERROR "not a type" */ ) {}
-func f2(x *f2 /* ERROR "not a type" */ ) {}
-func f3() (x f3 /* ERROR "not a type" */ ) { return }
-func f4() (x *f4 /* ERROR "not a type" */ ) { return }
-// TODO(#43215) this should be detected as a cycle error
-func f5([unsafe.Sizeof(f5)]int) {}
-
-func (S0) m1 (x S0 /* ERROR illegal cycle in method declaration */ .m1) {}
-func (S0) m2 (x *S0 /* ERROR illegal cycle in method declaration */ .m2) {}
-func (S0) m3 () (x S0 /* ERROR illegal cycle in method declaration */ .m3) { return }
-func (S0) m4 () (x *S0 /* ERROR illegal cycle in method declaration */ .m4) { return }
-
-// interfaces may not have any blank methods
-type BlankI interface {
-	_ /* ERROR "methods must have a unique non-blank name" */ ()
-	_ /* ERROR "methods must have a unique non-blank name" */ (float32) int
-	m()
-}
-
-// non-interface types may have multiple blank methods
-type BlankT struct{}
-
-func (BlankT) _() {}
-func (BlankT) _(int) {}
-func (BlankT) _() int { return 0 }
-func (BlankT) _(int) int { return 0}
diff --git a/src/go/types/testdata/check/decls1.go b/src/go/types/testdata/check/decls1.go
deleted file mode 100644
index 6fe349b..0000000
--- a/src/go/types/testdata/check/decls1.go
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// variable declarations
-
-package decls1
-
-import (
-	"math"
-)
-
-// Global variables without initialization
-var (
-	a, b bool
-	c byte
-	d uint8
-	r rune
-	i int
-	j, k, l int
-	x, y float32
-	xx, yy float64
-	u, v complex64
-	uu, vv complex128
-	s, t string
-	array []byte
-	iface interface{}
-
-	blank _ /* ERROR "cannot use _" */
-)
-
-// Global variables with initialization
-var (
-	s1 = i + j
-	s2 = i /* ERROR "mismatched types" */ + x
-	s3 = c + d
-	s4 = s + t
-	s5 = s /* ERROR "invalid operation" */ / t
-	s6 = array[t1]
-	s7 = array[x /* ERROR "integer" */]
-	s8 = &a
-	s10 = &42 /* ERROR "cannot take address" */
-	s11 = &v
-	s12 = -(u + *t11) / *&v
-	s13 = a /* ERROR "shifted operand" */ << d
-	s14 = i << j
-	s18 = math.Pi * 10.0
-	s19 = s1 /* ERROR "cannot call" */ ()
- 	s20 = f0 /* ERROR "no value" */ ()
-	s21 = f6(1, s1, i)
-	s22 = f6(1, s1, uu /* ERROR "cannot use .* in argument" */ )
-
-	t1 int = i + j
-	t2 int = i /* ERROR "mismatched types" */ + x
-	t3 int = c /* ERROR "cannot use .* variable declaration" */ + d
-	t4 string = s + t
-	t5 string = s /* ERROR "invalid operation" */ / t
-	t6 byte = array[t1]
-	t7 byte = array[x /* ERROR "must be integer" */]
-	t8 *int = & /* ERROR "cannot use .* variable declaration" */ a
-	t10 *int = &42 /* ERROR "cannot take address" */
-	t11 *complex64 = &v
-	t12 complex64 = -(u + *t11) / *&v
-	t13 int = a /* ERROR "shifted operand" */ << d
-	t14 int = i << j
-	t15 math /* ERROR "not in selector" */
-	t16 math.xxx /* ERROR "not declared" */
-	t17 math /* ERROR "not a type" */ .Pi
-	t18 float64 = math.Pi * 10.0
-	t19 int = t1 /* ERROR "cannot call" */ ()
-	t20 int = f0 /* ERROR "no value" */ ()
-	t21 int = a /* ERROR "cannot use .* variable declaration" */
-)
-
-// Various more complex expressions
-var (
-	u1 = x /* ERROR "not an interface" */ .(int)
-	u2 = iface.([]int)
-	u3 = iface.(a /* ERROR "not a type" */ )
-	u4, ok = iface.(int)
-	u5, ok2, ok3 = iface /* ERROR "cannot initialize" */ .(int)
-)
-
-// Constant expression initializations
-var (
-	v1 = 1 /* ERROR "mismatched types untyped int and untyped string" */ + "foo"
-	v2 = c + 255
-	v3 = c + 256 /* ERROR "overflows" */
-	v4 = r + 2147483647
-	v5 = r + 2147483648 /* ERROR "overflows" */
-	v6 = 42
-	v7 = v6 + 9223372036854775807
-	v8 = v6 + 9223372036854775808 /* ERROR "overflows" */
-	v9 = i + 1 << 10
-	v10 byte = 1024 /* ERROR "overflows" */
-	v11 = xx/yy*yy - xx
-	v12 = true && false
-	v13 = nil /* ERROR "use of untyped nil" */
-	v14 string = 257 // ERROR cannot use 257 .* as string value in variable declaration$
-	v15 int8 = 257 // ERROR cannot use 257 .* as int8 value in variable declaration .*overflows
-)
-
-// Multiple assignment expressions
-var (
-	m1a, m1b = 1, 2
-	m2a, m2b, m2c /* ERROR "missing init expr for m2c" */ = 1, 2
-	m3a, m3b = 1, 2, 3 /* ERROR "extra init expr 3" */
-)
-
-func _() {
-	var (
-		m1a, m1b = 1, 2
-		m2a, m2b, m2c /* ERROR "missing init expr for m2c" */ = 1, 2
-		m3a, m3b = 1, 2, 3 /* ERROR "extra init expr 3" */
-	)
-
-	_, _ = m1a, m1b
-	_, _, _ = m2a, m2b, m2c
-	_, _ = m3a, m3b
-}
-
-// Declaration of parameters and results
-func f0() {}
-func f1(a /* ERROR "not a type" */) {}
-func f2(a, b, c d /* ERROR "not a type" */) {}
-
-func f3() int { return 0 }
-func f4() a /* ERROR "not a type" */ { return 0 }
-func f5() (a, b, c d /* ERROR "not a type" */) { return }
-
-func f6(a, b, c int) complex128 { return 0 }
-
-// Declaration of receivers
-type T struct{}
-
-func (T) m0() {}
-func (*T) m1() {}
-func (x T) m2() {}
-func (x *T) m3() {}
-
-// Initialization functions
-func init() {}
-func /* ERROR "no arguments and no return values" */ init(int) {}
-func /* ERROR "no arguments and no return values" */ init() int { return 0 }
-func /* ERROR "no arguments and no return values" */ init(int) int { return 0 }
-func (T) init(int) int { return 0 }
diff --git a/src/go/types/testdata/check/decls2/decls2a.go b/src/go/types/testdata/check/decls2/decls2a.go
deleted file mode 100644
index 9dff173..0000000
--- a/src/go/types/testdata/check/decls2/decls2a.go
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// method declarations
-
-package decls2
-
-import "time"
-import "unsafe"
-
-// T1 declared before its methods.
-type T1 struct{
-	f int
-}
-
-func (T1) m() {}
-func (T1) m /* ERROR "already declared" */ () {}
-func (x *T1) f /* ERROR "field and method" */ () {}
-
-// Conflict between embedded field and method name,
-// with the embedded field being a basic type.
-type T1b struct {
-	int
-}
-
-func (T1b) int /* ERROR "field and method" */ () {}
-
-type T1c struct {
-	time.Time
-}
-
-func (T1c) Time /* ERROR "field and method" */ () int { return 0 }
-
-// Disabled for now: LookupFieldOrMethod will find Pointer even though
-// it's double-declared (it would cost extra in the common case to verify
-// this). But the MethodSet computation will not find it due to the name
-// collision caused by the double-declaration, leading to an internal
-// inconsistency while we are verifying one computation against the other.
-// var _ = T1c{}.Pointer
-
-// T2's method declared before the type.
-func (*T2) f /* ERROR "field and method" */ () {}
-
-type T2 struct {
-	f int
-}
-
-// Methods declared without a declared type.
-func (undeclared /* ERROR "undeclared" */) m() {}
-func (x *undeclared /* ERROR "undeclared" */) m() {}
-
-func (pi /* ERROR "not a type" */) m1() {}
-func (x pi /* ERROR "not a type" */) m2() {}
-func (x *pi /* ERROR "not a type" */ ) m3() {}
-
-// Blank types.
-type _ struct { m int }
-type _ struct { m int }
-
-func (_ /* ERROR "cannot use _" */) m() {}
-func m(_ /* ERROR "cannot use _" */) {}
-
-// Methods with receiver base type declared in another file.
-func (T3) m1() {}
-func (*T3) m2() {}
-func (x T3) m3() {}
-func (x *T3) f /* ERROR "field and method" */ () {}
-
-// Methods of non-struct type.
-type T4 func()
-
-func (self T4) m() func() { return self }
-
-// Methods associated with an interface.
-type T5 interface {
-	m() int
-}
-
-func (T5 /* ERROR "invalid receiver" */ ) m1() {}
-func (T5 /* ERROR "invalid receiver" */ ) m2() {}
-
-// Methods associated with a named pointer type.
-type ptr *int
-func (ptr /* ERROR "invalid receiver" */ ) _() {}
-func (* /* ERROR "invalid receiver" */ ptr) _() {}
-
-// Methods with zero or multiple receivers.
-func ( /* ERROR "missing receiver" */ ) _() {}
-func (T3, * /* ERROR "exactly one receiver" */ T3) _() {}
-func (T3, T3, T3 /* ERROR "exactly one receiver" */ ) _() {}
-func (a, b /* ERROR "exactly one receiver" */ T3) _() {}
-func (a, b, c /* ERROR "exactly one receiver" */ T3) _() {}
-
-// Methods associated with non-local or unnamed types.
-func (int /* ERROR "cannot define new methods on non-local type int" */ ) m() {}
-func ([ /* ERROR "invalid receiver" */ ]int) m() {}
-func (time /* ERROR "cannot define new methods on non-local type time\.Time" */ .Time) m() {}
-func (* /* ERROR "cannot define new methods on non-local type time\.Time" */ time.Time) m() {}
-func (x /* ERROR "invalid receiver" */ interface{}) m() {}
-
-// Unsafe.Pointer is treated like a pointer when used as receiver type.
-type UP unsafe.Pointer
-func (UP /* ERROR "invalid" */ ) m1() {}
-func (* /* ERROR "invalid" */ UP) m2() {}
-
-// Double declarations across package files
-const c_double = 0
-type t_double int
-var v_double int
-func f_double() {}
diff --git a/src/go/types/testdata/check/decls2/decls2b.go b/src/go/types/testdata/check/decls2/decls2b.go
deleted file mode 100644
index 5c55750..0000000
--- a/src/go/types/testdata/check/decls2/decls2b.go
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// method declarations
-
-package decls2
-
-import "io"
-
-const pi = 3.1415
-
-func (T1) m /* ERROR "already declared" */ () {}
-func (T2) m(io.Writer) {}
-
-type T3 struct {
-	f *T3
-}
-
-type T6 struct {
-	x int
-}
-
-func (t *T6) m1() int {
-	return t.x
-}
-
-func f() {
-	var t *T6
-	t.m1()
-}
-
-// Double declarations across package files
-const c_double /* ERROR "redeclared" */ = 0
-type t_double  /* ERROR "redeclared" */ int
-var v_double /* ERROR "redeclared" */ int
-func f_double /* ERROR "redeclared" */ () {}
-
-// Blank methods need to be type-checked.
-// Verify by checking that errors are reported.
-func (T /* ERROR "undeclared" */ ) _() {}
-func (T1) _(undeclared /* ERROR "undeclared" */ ) {}
-func (T1) _() int { return "foo" /* ERROR "cannot use .* in return statement" */ }
-
-// Methods with undeclared receiver type can still be checked.
-// Verify by checking that errors are reported.
-func (Foo /* ERROR "undeclared" */ ) m() {}
-func (Foo /* ERROR "undeclared" */ ) m(undeclared /* ERROR "undeclared" */ ) {}
-func (Foo /* ERROR "undeclared" */ ) m() int { return "foo" /* ERROR "cannot use .* in return statement" */ }
-
-func (Foo /* ERROR "undeclared" */ ) _() {}
-func (Foo /* ERROR "undeclared" */ ) _(undeclared /* ERROR "undeclared" */ ) {}
-func (Foo /* ERROR "undeclared" */ ) _() int { return "foo" /* ERROR "cannot use .* in return statement" */ }
-
-// Receiver declarations are regular parameter lists;
-// receiver types may use parentheses, and the list
-// may have a trailing comma.
-type T7 struct {}
-
-func (T7) m1() {}
-func ((T7)) m2() {}
-func ((*T7)) m3() {}
-func (x *(T7),) m4() {}
-func (x (*(T7)),) m5() {}
-func (x ((*((T7)))),) m6() {}
-
-// Check that methods with parenthesized receiver are actually present (issue #23130).
-var (
-	_ = T7.m1
-	_ = T7.m2
-	_ = (*T7).m3
-	_ = (*T7).m4
-	_ = (*T7).m5
-	_ = (*T7).m6
-)
diff --git a/src/go/types/testdata/check/decls3.go b/src/go/types/testdata/check/decls3.go
deleted file mode 100644
index 745175c..0000000
--- a/src/go/types/testdata/check/decls3.go
+++ /dev/null
@@ -1,309 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// embedded types
-
-package decls3
-
-import "unsafe"
-import "fmt"
-
-// fields with the same name at the same level cancel each other out
-
-func _() {
-	type (
-		T1 struct { X int }
-		T2 struct { X int }
-		T3 struct { T1; T2 } // X is embedded twice at the same level via T1->X, T2->X
-	)
-
-	var t T3
-	_ = t.X /* ERROR "ambiguous selector t.X" */
-}
-
-func _() {
-	type (
-		T1 struct { X int }
-		T2 struct { T1 }
-		T3 struct { T1 }
-		T4 struct { T2; T3 } // X is embedded twice at the same level via T2->T1->X, T3->T1->X
-	)
-
-	var t T4
-	_ = t.X /* ERROR "ambiguous selector t.X" */
-}
-
-func issue4355() {
-	type (
-	    T1 struct {X int}
-	    T2 struct {T1}
-	    T3 struct {T2}
-	    T4 struct {T2}
-	    T5 struct {T3; T4} // X is embedded twice at the same level via T3->T2->T1->X, T4->T2->T1->X
-	)
-
-	var t T5
-	_ = t.X /* ERROR "ambiguous selector t.X" */
-}
-
-func _() {
-	type State int
-	type A struct{ State }
-	type B struct{ fmt.State }
-	type T struct{ A; B }
-
-	var t T
-	_ = t.State /* ERROR "ambiguous selector t.State" */
-}
-
-// Embedded fields can be predeclared types.
-
-func _() {
-	type T0 struct{
-		int
-		float32
-		f int
-	}
-	var x T0
-	_ = x.int
-	_ = x.float32
-	_ = x.f
-
-	type T1 struct{
-		T0
-	}
-	var y T1
-	_ = y.int
-	_ = y.float32
-	_ = y.f
-}
-
-// Restrictions on embedded field types.
-
-func _() {
-	type I1 interface{}
-	type I2 interface{}
-	type P1 *int
-	type P2 *int
-	type UP unsafe.Pointer
-
-	type T1 struct {
-		I1
-		* /* ERROR "cannot be a pointer to an interface" */ I2
-		* /* ERROR "cannot be a pointer to an interface" */ error
-		P1 /* ERROR "cannot be a pointer" */
-		* /* ERROR "cannot be a pointer" */ P2
-	}
-
-	// unsafe.Pointers are treated like regular pointers when embedded
-	type T2 struct {
-		unsafe /* ERROR "cannot be unsafe.Pointer" */ .Pointer
-		*/* ERROR "cannot be unsafe.Pointer" */ /* ERROR "Pointer redeclared" */ unsafe.Pointer
-		UP /* ERROR "cannot be unsafe.Pointer" */
-		* /* ERROR "cannot be unsafe.Pointer" */  /* ERROR "UP redeclared" */ UP
-	}
-}
-
-// Named types that are pointers.
-
-type S struct{ x int }
-func (*S) m() {}
-type P *S
-
-func _() {
-	var s *S
-	_ = s.x
-	_ = s.m
-
-	var p P
-	_ = p.x
-	_ = p.m /* ERROR "no field or method" */
-	_ = P.m /* ERROR "no field or method" */
-}
-
-// Borrowed from the FieldByName test cases in reflect/all_test.go.
-
-type D1 struct {
-	d int
-}
-type D2 struct {
-	d int
-}
-
-type S0 struct {
-	A, B, C int
-	D1
-	D2
-}
-
-type S1 struct {
-	B int
-	S0
-}
-
-type S2 struct {
-	A int
-	*S1
-}
-
-type S1x struct {
-	S1
-}
-
-type S1y struct {
-	S1
-}
-
-type S3 struct {
-	S1x
-	S2
-	D, E int
-	*S1y
-}
-
-type S4 struct {
-	*S4
-	A int
-}
-
-// The X in S6 and S7 annihilate, but they also block the X in S8.S9.
-type S5 struct {
-	S6
-	S7
-	S8
-}
-
-type S6 struct {
-	X int
-}
-
-type S7 S6
-
-type S8 struct {
-	S9
-}
-
-type S9 struct {
-	X int
-	Y int
-}
-
-// The X in S11.S6 and S12.S6 annihilate, but they also block the X in S13.S8.S9.
-type S10 struct {
-	S11
-	S12
-	S13
-}
-
-type S11 struct {
-	S6
-}
-
-type S12 struct {
-	S6
-}
-
-type S13 struct {
-	S8
-}
-
-func _() {
-	_ = struct{}{}.Foo /* ERROR "no field or method" */
-	_ = S0{}.A
-	_ = S0{}.D /* ERROR "no field or method" */
-	_ = S1{}.A
-	_ = S1{}.B
-	_ = S1{}.S0
-	_ = S1{}.C
-	_ = S2{}.A
-	_ = S2{}.S1
-	_ = S2{}.B
-	_ = S2{}.C
-	_ = S2{}.D /* ERROR "no field or method" */
-	_ = S3{}.S1 /* ERROR "ambiguous selector \(S3 literal\).S1" */
-	_ = S3{}.A
-	_ = S3{}.B /* ERROR "ambiguous selector" \(S3 literal\).B */
-	_ = S3{}.D
-	_ = S3{}.E
-	_ = S4{}.A
-	_ = S4{}.B /* ERROR "no field or method" */
-	_ = S5{}.X /* ERROR "ambiguous selector \(S5 literal\).X" */
-	_ = S5{}.Y
-	_ = S10{}.X /* ERROR "ambiguous selector \(S10 literal\).X" */
-	_ = S10{}.Y
-}
-
-// Borrowed from the FieldByName benchmark in reflect/all_test.go.
-
-type R0 struct {
-	*R1
-	*R2
-	*R3
-	*R4
-}
-
-type R1 struct {
-	*R5
-	*R6
-	*R7
-	*R8
-}
-
-type R2 R1
-type R3 R1
-type R4 R1
-
-type R5 struct {
-	*R9
-	*R10
-	*R11
-	*R12
-}
-
-type R6 R5
-type R7 R5
-type R8 R5
-
-type R9 struct {
-	*R13
-	*R14
-	*R15
-	*R16
-}
-
-type R10 R9
-type R11 R9
-type R12 R9
-
-type R13 struct {
-	*R17
-	*R18
-	*R19
-	*R20
-}
-
-type R14 R13
-type R15 R13
-type R16 R13
-
-type R17 struct {
-	*R21
-	*R22
-	*R23
-	*R24
-}
-
-type R18 R17
-type R19 R17
-type R20 R17
-
-type R21 struct {
-	X int
-}
-
-type R22 R21
-type R23 R21
-type R24 R21
-
-var _ = R0{}.X /* ERROR "ambiguous selector \(R0 literal\).X" */
\ No newline at end of file
diff --git a/src/go/types/testdata/check/decls4.go b/src/go/types/testdata/check/decls4.go
deleted file mode 100644
index 8a9a6ff..0000000
--- a/src/go/types/testdata/check/decls4.go
+++ /dev/null
@@ -1,199 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// type aliases
-
-package decls4
-
-type (
-	T0 [10]int
-	T1 []byte
-	T2 struct {
-		x int
-	}
-	T3 interface{
-		m() T2
-	}
-	T4 func(int, T0) chan T2
-)
-
-type (
-	Ai = int
-	A0 = T0
-	A1 = T1
-	A2 = T2
-	A3 = T3
-	A4 = T4
-
-	A10 = [10]int
-	A11 = []byte
-	A12 = struct {
-		x int
-	}
-	A13 = interface{
-		m() A2
-	}
-	A14 = func(int, A0) chan A2
-)
-
-// check assignment compatibility due to equality of types
-var (
-	xi_ int
-	ai Ai = xi_
-
-	x0 T0
-	a0 A0 = x0
-
-	x1 T1
-	a1 A1 = x1
-
-	x2 T2
-	a2 A2 = x2
-
-	x3 T3
-	a3 A3 = x3
-
-	x4 T4
-	a4 A4 = x4
-)
-
-// alias receiver types
-func (Ai /* ERROR "cannot define new methods on non-local type int" */) m1() {}
-func (T0) m1() {}
-func (A0) m1 /* ERROR already declared */ () {}
-func (A0) m2 () {}
-func (A3 /* ERROR invalid receiver */ ) m1 () {}
-func (A10 /* ERROR invalid receiver */ ) m1() {}
-
-// x0 has methods m1, m2 declared via receiver type names T0 and A0
-var _ interface{ m1(); m2() } = x0
-
-// alias receiver types (test case for issue #23042)
-type T struct{}
-
-var (
-	_ = T.m
-	_ = T{}.m
-	_ interface{m()} = T{}
-)
-
-var (
-	_ = T.n
-	_ = T{}.n
-	_ interface{m(); n()} = T{}
-)
-
-type U = T
-func (U) m() {}
-
-// alias receiver types (long type declaration chains)
-type (
-	V0 = V1
-	V1 = (V2)
-	V2 = ((V3))
-	V3 = T
-)
-
-func (V0) m /* ERROR already declared */ () {}
-func (V1) n() {}
-
-// alias receiver types (invalid due to cycles)
-type (
-	W0 /* ERROR illegal cycle */ = W1
-	W1 = (W2)
-	W2 = ((W0))
-)
-
-func (W0) m() {} // no error expected (due to above cycle error)
-func (W1) n() {}
-
-// alias receiver types (invalid due to builtin underlying type)
-type (
-	B0 = B1
-	B1 = B2
-	B2 = int
-)
-
-func (B0 /* ERROR cannot define new methods on non-local type int */ ) m() {}
-func (B1 /* ERROR cannot define new methods on non-local type int */ ) n() {}
-
-// cycles
-type (
-	C2 /* ERROR illegal cycle */ = C2
-	C3 /* ERROR illegal cycle */ = C4
-	C4 = C3
-	C5 struct {
-		f *C6
-	}
-	C6 = C5
-	C7 /* ERROR illegal cycle */  struct {
-		f C8
-	}
-	C8 = C7
-)
-
-// embedded fields
-var (
-	s0 struct { T0 }
-	s1 struct { A0 } = s0 /* ERROR cannot use */ // embedded field names are different
-)
-
-// embedding and lookup of fields and methods
-func _(s struct{A0}) { s.A0 = x0 }
-
-type eX struct{xf int}
-
-func (eX) xm()
-
-type eY = struct{eX} // field/method set of eY includes xf, xm
-
-type eZ = *struct{eX} // field/method set of eZ includes xf, xm
-
-type eA struct {
-	eX // eX contributes xf, xm to eA
-}
-
-type eA2 struct {
-	*eX // *eX contributes xf, xm to eA
-}
-
-type eB struct {
-	eY // eY contributes xf, xm to eB
-}
-
-type eB2 struct {
-	*eY // *eY contributes xf, xm to eB
-}
-
-type eC struct {
-	eZ // eZ contributes xf, xm to eC
-}
-
-var (
-	_ = eA{}.xf
-	_ = eA{}.xm
-	_ = eA2{}.xf
-	_ = eA2{}.xm
-	_ = eB{}.xf
-	_ = eB{}.xm
-	_ = eB2{}.xf
-	_ = eB2{}.xm
-	_ = eC{}.xf
-	_ = eC{}.xm
-)
-
-// ambiguous selectors due to embedding via type aliases
-type eD struct {
-	eY
-	eZ
-}
-
-var (
-	_ = eD{}.xf /* ERROR ambiguous selector \(eD literal\).xf */
-	_ = eD{}.xm /* ERROR ambiguous selector \(eD literal\).xm */
-)
-
-var (
-	_ interface{ xm() } = eD /* ERROR missing method xm */ {}
-)
\ No newline at end of file
diff --git a/src/go/types/testdata/check/errors.go b/src/go/types/testdata/check/errors.go
deleted file mode 100644
index 7cdc5fb..0000000
--- a/src/go/types/testdata/check/errors.go
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package errors
-
-// Testing precise operand formatting in error messages
-// (matching messages are regular expressions, hence the \'s).
-func f(x int, m map[string]int) {
-	// no values
-	_ = f /* ERROR f\(0, m\) \(no value\) used as value */ (0, m)
-
-	// built-ins
-	_ = println // ERROR println \(built-in\) must be called
-
-	// types
-	_ = complex128 // ERROR complex128 \(type\) is not an expression
-
-	// constants
-	const c1 = 991
-	const c2 float32 = 0.5
-	const c3 = "foo"
-	0 // ERROR 0 \(untyped int constant\) is not used
-	0.5 // ERROR 0.5 \(untyped float constant\) is not used
-	"foo" // ERROR "foo" \(untyped string constant\) is not used
-	c1 // ERROR c1 \(untyped int constant 991\) is not used
-	c2 // ERROR c2 \(constant 0.5 of type float32\) is not used
-	c1 /* ERROR c1 \+ c2 \(constant 991.5 of type float32\) is not used */ + c2
-	c3 // ERROR c3 \(untyped string constant "foo"\) is not used
-
-	// variables
-	x // ERROR x \(variable of type int\) is not used
-
-	// values
-	nil // ERROR nil is not used
-	( /* ERROR \(\*int\)\(nil\) \(value of type \*int\) is not used */ *int)(nil)
-	x /* ERROR x != x \(untyped bool value\) is not used */ != x
-	x /* ERROR x \+ x \(value of type int\) is not used */ + x
-
-	// value, ok's
-	const s = "foo"
-	m /* ERROR m\[s\] \(map index expression of type int\) is not used */ [s]
-}
-
-// Valid ERROR comments can have a variety of forms.
-func _() {
-	0 /* ERROR "0 .* is not used" */
-	0 /* ERROR 0 .* is not used */
-	0 // ERROR "0 .* is not used"
-	0 // ERROR 0 .* is not used
-}
-
-// Don't report spurious errors as a consequence of earlier errors.
-// Add more tests as needed.
-func _() {
-	if err := foo /* ERROR undeclared */ (); err != nil /* no error here */ {}
-}
-
-// Use unqualified names for package-local objects.
-type T struct{}
-var _ int = T /* ERROR value of type T */ {} // use T in error message rather then errors.T
-
-// Don't report errors containing "invalid type" (issue #24182).
-func _(x *missing /* ERROR undeclared name: missing */ ) {
-	x.m() // there shouldn't be an error here referring to *invalid type
-}
diff --git a/src/go/types/testdata/check/expr0.go b/src/go/types/testdata/check/expr0.go
deleted file mode 100644
index 1992377..0000000
--- a/src/go/types/testdata/check/expr0.go
+++ /dev/null
@@ -1,187 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// unary expressions
-
-package expr0 
-
-type mybool bool
-
-var (
-	// bool
-	b0 = true
-	b1 bool = b0
-	b2 = !true
-	b3 = !b1
-	b4 bool = !true
-	b5 bool = !b4
-	b6 = +b0 /* ERROR "not defined" */
-	b7 = -b0 /* ERROR "not defined" */
-	b8 = ^b0 /* ERROR "not defined" */
-	b9 = *b0 /* ERROR "cannot indirect" */
-	b10 = &true /* ERROR "cannot take address" */
-	b11 = &b0
-	b12 = <-b0 /* ERROR "cannot receive" */
-	b13 = & & /* ERROR "cannot take address" */ b0
-
-	// byte
-	_ = byte(0)
-	_ = byte(- /* ERROR "cannot convert" */ 1)
-	_ = - /* ERROR "-byte\(1\) \(constant -1 of type byte\) overflows byte" */ byte(1) // test for issue 11367
-	_ = byte /* ERROR "overflows byte" */ (0) - byte(1)
-
-	// int
-	i0 = 1
-	i1 int = i0
-	i2 = +1
-	i3 = +i0
-	i4 int = +1
-	i5 int = +i4
-	i6 = -1
-	i7 = -i0
-	i8 int = -1
-	i9 int = -i4
-	i10 = !i0 /* ERROR "not defined" */
-	i11 = ^1
-	i12 = ^i0
-	i13 int = ^1
-	i14 int = ^i4
-	i15 = *i0 /* ERROR "cannot indirect" */
-	i16 = &i0
-	i17 = *i16
-	i18 = <-i16 /* ERROR "cannot receive" */
-
-	// uint
-	u0 = uint(1)
-	u1 uint = u0
-	u2 = +1
-	u3 = +u0
-	u4 uint = +1
-	u5 uint = +u4
-	u6 = -1
-	u7 = -u0
-	u8 uint = - /* ERROR "overflows" */ 1
-	u9 uint = -u4
-	u10 = !u0 /* ERROR "not defined" */
-	u11 = ^1
-	u12 = ^i0
-	u13 uint = ^ /* ERROR "overflows" */ 1
-	u14 uint = ^u4
-	u15 = *u0 /* ERROR "cannot indirect" */
-	u16 = &u0
-	u17 = *u16
-	u18 = <-u16 /* ERROR "cannot receive" */
-	u19 = ^uint(0)
-
-	// float64
-	f0 = float64(1)
-	f1 float64 = f0
-	f2 = +1
-	f3 = +f0
-	f4 float64 = +1
-	f5 float64 = +f4
-	f6 = -1
-	f7 = -f0
-	f8 float64 = -1
-	f9 float64 = -f4
-	f10 = !f0 /* ERROR "not defined" */
-	f11 = ^1
-	f12 = ^i0
-	f13 float64 = ^1
-	f14 float64 = ^f4 /* ERROR "not defined" */
-	f15 = *f0 /* ERROR "cannot indirect" */
-	f16 = &f0
-	f17 = *u16
-	f18 = <-u16 /* ERROR "cannot receive" */
-
-	// complex128
-	c0 = complex128(1)
-	c1 complex128 = c0
-	c2 = +1
-	c3 = +c0
-	c4 complex128 = +1
-	c5 complex128 = +c4
-	c6 = -1
-	c7 = -c0
-	c8 complex128 = -1
-	c9 complex128 = -c4
-	c10 = !c0 /* ERROR "not defined" */
-	c11 = ^1
-	c12 = ^i0
-	c13 complex128 = ^1
-	c14 complex128 = ^c4 /* ERROR "not defined" */
-	c15 = *c0 /* ERROR "cannot indirect" */
-	c16 = &c0
-	c17 = *u16
-	c18 = <-u16 /* ERROR "cannot receive" */
-
-	// string
-	s0 = "foo"
-	s1 = +"foo" /* ERROR "not defined" */
-	s2 = -s0 /* ERROR "not defined" */
-	s3 = !s0 /* ERROR "not defined" */
-	s4 = ^s0 /* ERROR "not defined" */
-	s5 = *s4
-	s6 = &s4
-	s7 = *s6
-	s8 = <-s7
-
-	// channel
-	ch chan int
-	rc <-chan float64
-	sc chan <- string
-	ch0 = +ch /* ERROR "not defined" */
-	ch1 = -ch /* ERROR "not defined" */
-	ch2 = !ch /* ERROR "not defined" */
-	ch3 = ^ch /* ERROR "not defined" */
-	ch4 = *ch /* ERROR "cannot indirect" */
-	ch5 = &ch
-	ch6 = *ch5
-	ch7 = <-ch
-	ch8 = <-rc
-	ch9 = <-sc /* ERROR "cannot receive" */
-	ch10, ok = <-ch
-	// ok is of type bool
-	ch11, myok = <-ch
-	_ mybool = myok /* ERROR "cannot use .* in variable declaration" */
-)
-
-// address of composite literals
-type T struct{x, y int}
-
-func f() T { return T{} }
-
-var (
-	_ = &T{1, 2}
-	_ = &[...]int{}
-	_ = &[]int{}
-	_ = &[]int{}
-	_ = &map[string]T{}
-	_ = &(T{1, 2})
-	_ = &((((T{1, 2}))))
-	_ = &f /* ERROR "cannot take address" */ ()
-)
-
-// recursive pointer types
-type P *P
-
-var (
-	p1 P = new(P)
-	p2 P = *p1
-	p3 P = &p2
-)
-
-func g() (a, b int) { return }
-
-func _() {
-	_ = -g /* ERROR 2-valued g */ ()
-	_ = <-g /* ERROR 2-valued g */ ()
-}
-
-// ~ is accepted as unary operator only permitted in interface type elements
-var (
-	_ = ~ /* ERROR cannot use ~ outside of interface or type constraint */ 0
-	_ = ~ /* ERROR cannot use ~ outside of interface or type constraint */ "foo"
-	_ = ~ /* ERROR cannot use ~ outside of interface or type constraint */ i0
-)
diff --git a/src/go/types/testdata/check/expr1.go b/src/go/types/testdata/check/expr1.go
deleted file mode 100644
index 42b95fb..0000000
--- a/src/go/types/testdata/check/expr1.go
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// binary expressions
-
-package expr1
-
-type mybool bool
-
-func _(x, y bool, z mybool) {
-	x = x || y
-	x = x || true
-	x = x || false
-	x = x && y
-	x = x && true
-	x = x && false
-
-	z = z /* ERROR mismatched types */ || y
-	z = z || true
-	z = z || false
-	z = z /* ERROR mismatched types */ && y
-	z = z && true
-	z = z && false
-}
-
-type myint int
-
-func _(x, y int, z myint) {
-	x = x + 1
-	x = x + 1.0
-	x = x + 1.1 // ERROR truncated to int
-	x = x + y
-	x = x - y
-	x = x * y
-	x = x / y
-	x = x % y
-	x = x << y
-	x = x >> y
-
-	z = z + 1
-	z = z + 1.0
-	z = z + 1.1 // ERROR truncated to int
-	z = z /* ERROR mismatched types */ + y
-	z = z /* ERROR mismatched types */ - y
-	z = z /* ERROR mismatched types */ * y
-	z = z /* ERROR mismatched types */ / y
-	z = z /* ERROR mismatched types */ % y
-	z = z << y
-	z = z >> y
-}
-
-type myuint uint
-
-func _(x, y uint, z myuint) {
-	x = x + 1
-	x = x + - /* ERROR overflows uint */ 1
-	x = x + 1.0
-	x = x + 1.1 // ERROR truncated to uint
-	x = x + y
-	x = x - y
-	x = x * y
-	x = x / y
-	x = x % y
-	x = x << y
-	x = x >> y
-
-	z = z + 1
-	z = x + - /* ERROR overflows uint */ 1
-	z = z + 1.0
-	z = z + 1.1 // ERROR truncated to uint
-	z = z /* ERROR mismatched types */ + y
-	z = z /* ERROR mismatched types */ - y
-	z = z /* ERROR mismatched types */ * y
-	z = z /* ERROR mismatched types */ / y
-	z = z /* ERROR mismatched types */ % y
-	z = z << y
-	z = z >> y
-}
-
-type myfloat64 float64
-
-func _(x, y float64, z myfloat64) {
-	x = x + 1
-	x = x + -1
-	x = x + 1.0
-	x = x + 1.1
-	x = x + y
-	x = x - y
-	x = x * y
-	x = x / y
-	x = x /* ERROR not defined */ % y
-	x = x /* ERROR operand x .* must be integer */ << y
-	x = x /* ERROR operand x .* must be integer */ >> y
-
-	z = z + 1
-	z = z + -1
-	z = z + 1.0
-	z = z + 1.1
-	z = z /* ERROR mismatched types */ + y
-	z = z /* ERROR mismatched types */ - y
-	z = z /* ERROR mismatched types */ * y
-	z = z /* ERROR mismatched types */ / y
-	z = z /* ERROR mismatched types */ % y
-	z = z /* ERROR operand z .* must be integer */ << y
-	z = z /* ERROR operand z .* must be integer */ >> y
-}
-
-type mystring string
-
-func _(x, y string, z mystring) {
-	x = x + "foo"
-	x = x /* ERROR not defined */ - "foo"
-	x = x /* ERROR mismatched types string and untyped int */ + 1
-	x = x + y
-	x = x /* ERROR not defined */ - y
-	x = x /* ERROR mismatched types string and untyped int */* 10
-}
-
-func f() (a, b int) { return }
-
-func _(x int) {
-	_ = f /* ERROR 2-valued f */ () + 1
-	_ = x + f /* ERROR 2-valued f */ ()
-	_ = f /* ERROR 2-valued f */ () + f
-	_ = f /* ERROR 2-valued f */ () + f /* ERROR 2-valued f */ ()
-}
diff --git a/src/go/types/testdata/check/expr2.go b/src/go/types/testdata/check/expr2.go
deleted file mode 100644
index 6133dbb..0000000
--- a/src/go/types/testdata/check/expr2.go
+++ /dev/null
@@ -1,260 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// comparisons
-
-package expr2
-
-func _bool() {
-	const t = true == true
-	const f = true == false
-	_ = t /* ERROR cannot compare */ < f
-	_ = 0 /* ERROR mismatched types untyped int and untyped bool */ == t
-	var b bool
-	var x, y float32
-	b = x < y
-	_ = b
-	_ = struct{b bool}{x < y}
-}
-
-// corner cases
-var (
-	v0 = nil == nil // ERROR operator == not defined on untyped nil
-)
-
-func arrays() {
-	// basics
-	var a, b [10]int
-	_ = a == b
-	_ = a != b
-	_ = a /* ERROR < not defined */ < b
-	_ = a /* ERROR cannot compare.*mismatched types */ == nil
-
-	type C [10]int
-	var c C
-	_ = a == c
-
-	type D [10]int
-	var d D
-	_ = c /* ERROR mismatched types */ == d
-
-	var e [10]func() int
-	_ = e /* ERROR \[10\]func\(\) int cannot be compared */ == e
-}
-
-func structs() {
-	// basics
-	var s, t struct {
-		x int
-		a [10]float32
-		_ bool
-	}
-	_ = s == t
-	_ = s != t
-	_ = s /* ERROR < not defined */ < t
-	_ = s /* ERROR cannot compare.*mismatched types */ == nil
-
-	type S struct {
-		x int
-		a [10]float32
-		_ bool
-	}
-	type T struct {
-		x int
-		a [10]float32
-		_ bool
-	}
-	var ss S
-	var tt T
-	_ = s == ss
-	_ = ss /* ERROR mismatched types */ == tt
-
-	var u struct {
-		x int
-		a [10]map[string]int
-	}
-	_ = u /* ERROR cannot compare */ == u
-}
-
-func pointers() {
-	// nil
-	_ = nil == nil // ERROR operator == not defined on untyped nil
-	_ = nil != nil // ERROR operator != not defined on untyped nil
-	_ = nil /* ERROR < not defined */ < nil
-	_ = nil /* ERROR <= not defined */ <= nil
-	_ = nil /* ERROR > not defined */ > nil
-	_ = nil /* ERROR >= not defined */ >= nil
-
-	// basics
-	var p, q *int
-	_ = p == q
-	_ = p != q
-
-	_ = p == nil
-	_ = p != nil
-	_ = nil == q
-	_ = nil != q
-
-	_ = p /* ERROR < not defined */ < q
-	_ = p /* ERROR <= not defined */ <= q
-	_ = p /* ERROR > not defined */ > q
-	_ = p /* ERROR >= not defined */ >= q
-
-	// various element types
-	type (
-		S1 struct{}
-		S2 struct{}
-		P1 *S1
-		P2 *S2
-	)
-	var (
-		ps1 *S1
-		ps2 *S2
-		p1 P1
-		p2 P2
-	)
-	_ = ps1 == ps1
-	_ = ps1 /* ERROR mismatched types */ == ps2
-	_ = ps2 /* ERROR mismatched types */ == ps1
-
-	_ = p1 == p1
-	_ = p1 /* ERROR mismatched types */ == p2
-
-	_ = p1 == ps1
-}
-
-func channels() {
-	// basics
-	var c, d chan int
-	_ = c == d
-	_ = c != d
-	_ = c == nil
-	_ = c /* ERROR < not defined */ < d
-
-	// various element types (named types)
-	type (
-		C1 chan int
-		C1r <-chan int
-		C1s chan<- int
-		C2 chan float32
-	)
-	var (
-		c1 C1
-		c1r C1r
-		c1s C1s
-		c1a chan int
-		c2 C2
-	)
-	_ = c1 == c1
-	_ = c1 /* ERROR mismatched types */ == c1r
-	_ = c1 /* ERROR mismatched types */ == c1s
-	_ = c1r /* ERROR mismatched types */ == c1s
-	_ = c1 == c1a
-	_ = c1a == c1
-	_ = c1 /* ERROR mismatched types */ == c2
-	_ = c1a /* ERROR mismatched types */ == c2
-
-	// various element types (unnamed types)
-	var (
-		d1 chan int
-		d1r <-chan int
-		d1s chan<- int
-		d1a chan<- int
-		d2 chan float32
-	)
-	_ = d1 == d1
-	_ = d1 == d1r
-	_ = d1 == d1s
-	_ = d1r /* ERROR mismatched types */ == d1s
-	_ = d1 == d1a
-	_ = d1a == d1
-	_ = d1 /* ERROR mismatched types */ == d2
-	_ = d1a /* ERROR mismatched types */ == d2
-}
-
-// for interfaces test
-type S1 struct{}
-type S11 struct{}
-type S2 struct{}
-func (*S1) m() int
-func (*S11) m() int
-func (*S11) n()
-func (*S2) m() float32
-
-func interfaces() {
-	// basics
-	var i, j interface{ m() int }
-	_ = i == j
-	_ = i != j
-	_ = i == nil
-	_ = i /* ERROR < not defined */ < j
-
-	// various interfaces
-	var ii interface { m() int; n() }
-	var k interface { m() float32 }
-	_ = i == ii
-	_ = i /* ERROR mismatched types */ == k
-
-	// interfaces vs values
-	var s1 S1
-	var s11 S11
-	var s2 S2
-
-	_ = i == 0 /* ERROR cannot convert */
-	_ = i /* ERROR mismatched types */ == s1
-	_ = i == &s1
-	_ = i == &s11
-
-	_ = i /* ERROR mismatched types */ == s2
-	_ = i /* ERROR mismatched types */ == &s2
-
-	// issue #28164
-	// testcase from issue
-	_ = interface{}(nil) == [ /* ERROR slice can only be compared to nil */ ]int(nil)
-
-	// related cases
-	var e interface{}
-	var s []int
-	var x int
-	_ = e == s // ERROR slice can only be compared to nil
-	_ = s /* ERROR slice can only be compared to nil */ == e
-	_ = e /* ERROR operator < not defined on interface */ < x
-	_ = x < e // ERROR operator < not defined on interface
-}
-
-func slices() {
-	// basics
-	var s []int
-	_ = s == nil
-	_ = s != nil
-	_ = s /* ERROR < not defined */ < nil
-
-	// slices are not otherwise comparable
-	_ = s /* ERROR slice can only be compared to nil */ == s
-	_ = s /* ERROR < not defined */ < s
-}
-
-func maps() {
-	// basics
-	var m map[string]int
-	_ = m == nil
-	_ = m != nil
-	_ = m /* ERROR < not defined */ < nil
-
-	// maps are not otherwise comparable
-	_ = m /* ERROR map can only be compared to nil */ == m
-	_ = m /* ERROR < not defined */ < m
-}
-
-func funcs() {
-	// basics
-	var f func(int) float32
-	_ = f == nil
-	_ = f != nil
-	_ = f /* ERROR < not defined */ < nil
-
-	// funcs are not otherwise comparable
-	_ = f /* ERROR func can only be compared to nil */ == f
-	_ = f /* ERROR < not defined */ < f
-}
diff --git a/src/go/types/testdata/check/expr3.go b/src/go/types/testdata/check/expr3.go
deleted file mode 100644
index b8f96dc..0000000
--- a/src/go/types/testdata/check/expr3.go
+++ /dev/null
@@ -1,564 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package expr3
-
-import "time"
-
-func indexes() {
-	_ = 1 /* ERROR "cannot index" */ [0]
-	_ = indexes /* ERROR "cannot index" */ [0]
-	_ = ( /* ERROR "cannot slice" */ 12 + 3)[1:2]
-
-	var a [10]int
-	_ = a[true /* ERROR "cannot convert" */ ]
-	_ = a["foo" /* ERROR "cannot convert" */ ]
-	_ = a[1.1 /* ERROR "truncated" */ ]
-	_ = a[1.0]
-	_ = a[- /* ERROR "negative" */ 1]
-	_ = a[- /* ERROR "negative" */ 1 :]
-	_ = a[: - /* ERROR "negative" */ 1]
-	_ = a[: /* ERROR "2nd index required" */ : /* ERROR "3rd index required" */ ]
-	_ = a[0: /* ERROR "2nd index required" */ : /* ERROR "3rd index required" */ ]
-	_ = a[0: /* ERROR "2nd index required" */ :10]
-	_ = a[:10:10]
-
-	var a0 int
-	a0 = a[0]
-	_ = a0
-	var a1 int32
-	a1 = a /* ERROR "cannot use .* in assignment" */ [1]
-	_ = a1
-
-	_ = a[9]
-	_ = a[10 /* ERROR "index .* out of bounds" */ ]
-	_ = a[1 /* ERROR "overflows" */ <<100]
-	_ = a[1<< /* ERROR "constant shift overflow" */ 1000] // no out-of-bounds follow-on error
-	_ = a[10:]
-	_ = a[:10]
-	_ = a[10:10]
-	_ = a[11 /* ERROR "index .* out of bounds" */ :]
-	_ = a[: 11 /* ERROR "index .* out of bounds" */ ]
-	_ = a[: 1 /* ERROR "overflows" */ <<100]
-	_ = a[:10:10]
-	_ = a[:11 /* ERROR "index .* out of bounds" */ :10]
-	_ = a[:10:11 /* ERROR "index .* out of bounds" */ ]
-	_ = a[10:0 /* ERROR "invalid slice indices" */ :10]
-	_ = a[0:10:0 /* ERROR "invalid slice indices" */ ]
-	_ = a[10:0 /* ERROR "invalid slice indices" */:0]
-	_ = &a /* ERROR "cannot take address" */ [:10]
-
-	pa := &a
-	_ = pa[9]
-	_ = pa[10 /* ERROR "index .* out of bounds" */ ]
-	_ = pa[1 /* ERROR "overflows" */ <<100]
-	_ = pa[10:]
-	_ = pa[:10]
-	_ = pa[10:10]
-	_ = pa[11 /* ERROR "index .* out of bounds" */ :]
-	_ = pa[: 11 /* ERROR "index .* out of bounds" */ ]
-	_ = pa[: 1 /* ERROR "overflows" */ <<100]
-	_ = pa[:10:10]
-	_ = pa[:11 /* ERROR "index .* out of bounds" */ :10]
-	_ = pa[:10:11 /* ERROR "index .* out of bounds" */ ]
-	_ = pa[10:0 /* ERROR "invalid slice indices" */ :10]
-	_ = pa[0:10:0 /* ERROR "invalid slice indices" */ ]
-	_ = pa[10:0 /* ERROR "invalid slice indices" */ :0]
-	_ = &pa /* ERROR "cannot take address" */ [:10]
-
-	var b [0]int
-	_ = b[0 /* ERROR "index .* out of bounds" */ ]
-	_ = b[:]
-	_ = b[0:]
-	_ = b[:0]
-	_ = b[0:0]
-	_ = b[0:0:0]
-	_ = b[1 /* ERROR "index .* out of bounds" */ :0:0]
-
-	var s []int
-	_ = s[- /* ERROR "negative" */ 1]
-	_ = s[- /* ERROR "negative" */ 1 :]
-	_ = s[: - /* ERROR "negative" */ 1]
-	_ = s[0]
-	_ = s[1:2]
-	_ = s[2:1 /* ERROR "invalid slice indices" */ ]
-	_ = s[2:]
-	_ = s[: 1 /* ERROR "overflows" */ <<100]
-	_ = s[1 /* ERROR "overflows" */ <<100 :]
-	_ = s[1 /* ERROR "overflows" */ <<100 : 1 /* ERROR "overflows" */ <<100]
-	_ = s[: /* ERROR "2nd index required" */ :  /* ERROR "3rd index required" */ ]
-	_ = s[:10:10]
-	_ = s[10:0 /* ERROR "invalid slice indices" */ :10]
-	_ = s[0:10:0 /* ERROR "invalid slice indices" */ ]
-	_ = s[10:0 /* ERROR "invalid slice indices" */ :0]
-	_ = &s /* ERROR "cannot take address" */ [:10]
-
-	var m map[string]int
-	_ = m[0 /* ERROR "cannot use .* in map index" */ ]
-	_ = m /* ERROR "cannot slice" */ ["foo" : "bar"]
-	_ = m["foo"]
-	// ok is of type bool
-	type mybool bool
-	var ok mybool
-	_, ok = m["bar"]
-	_ = ok
-	_ = m/* ERROR "mismatched types int and untyped string" */[0 /* ERROR "cannot use 0" */ ] + "foo"
-
-	var t string
-	_ = t[- /* ERROR "negative" */ 1]
-	_ = t[- /* ERROR "negative" */ 1 :]
-	_ = t[: - /* ERROR "negative" */ 1]
-	_ = t[1:2:3 /* ERROR "3-index slice of string" */ ]
-	_ = "foo"[1:2:3 /* ERROR "3-index slice of string" */ ]
-	var t0 byte
-	t0 = t[0]
-	_ = t0
-	var t1 rune
-	t1 = t /* ERROR "cannot use .* in assignment" */ [2]
-	_ = t1
-	_ = ("foo" + "bar")[5]
-	_ = ("foo" + "bar")[6 /* ERROR "index .* out of bounds" */ ]
-
-	const c = "foo"
-	_ = c[- /* ERROR "negative" */ 1]
-	_ = c[- /* ERROR "negative" */ 1 :]
-	_ = c[: - /* ERROR "negative" */ 1]
-	var c0 byte
-	c0 = c[0]
-	_ = c0
-	var c2 float32
-	c2 = c /* ERROR "cannot use .* in assignment" */ [2]
-	_ = c[3 /* ERROR "index .* out of bounds" */ ]
-	_ = ""[0 /* ERROR "index .* out of bounds" */ ]
-	_ = c2
-
-	_ = s[1<<30] // no compile-time error here
-
-	// issue 4913
-	type mystring string
-	var ss string
-	var ms mystring
-	var i, j int
-	ss = "foo"[1:2]
-	ss = "foo"[i:j]
-	ms = "foo" /* ERROR "cannot use .* in assignment" */ [1:2]
-	ms = "foo" /* ERROR "cannot use .* in assignment" */ [i:j]
-	_, _ = ss, ms
-}
-
-type T struct {
-	x int
-	y func()
-}
-
-func (*T) m() {}
-
-func method_expressions() {
-	_ = T.a /* ERROR "no field or method" */
-	_ = T.x /* ERROR "has no method" */
-	_ = T.m /* ERROR "cannot call pointer method m on T" */
-	_ = (*T).m
-
-	var f func(*T) = T.m /* ERROR "cannot call pointer method m on T" */
-	var g func(*T) = (*T).m
-	_, _ = f, g
-
-	_ = T.y /* ERROR "has no method" */
-	_ = (*T).y /* ERROR "has no method" */
-}
-
-func struct_literals() {
-	type T0 struct {
-		a, b, c int
-	}
-
-	type T1 struct {
-		T0
-		a, b int
-		u float64
-		s string
-	}
-
-	// keyed elements
-	_ = T1{}
-	_ = T1{a: 0, 1 /* ERROR "mixture of .* elements" */ }
-	_ = T1{aa /* ERROR "unknown field" */ : 0}
-	_ = T1{1 /* ERROR "invalid field name" */ : 0}
-	_ = T1{a: 0, s: "foo", u: 0, a /* ERROR "duplicate field" */: 10}
-	_ = T1{a: "foo" /* ERROR "cannot use .* in struct literal" */ }
-	_ = T1{c /* ERROR "unknown field" */ : 0}
-	_ = T1{T0: { /* ERROR "missing type" */ }} // struct literal element type may not be elided
-	_ = T1{T0: T0{}}
-	_ = T1{T0 /* ERROR "invalid field name" */ .a: 0}
-
-	// unkeyed elements
-	_ = T0{1, 2, 3}
-	_ = T0{1, b /* ERROR "mixture" */ : 2, 3}
-	_ = T0{1, 2} /* ERROR "too few values" */
-	_ = T0{1, 2, 3, 4  /* ERROR "too many values" */ }
-	_ = T0{1, "foo" /* ERROR "cannot use .* in struct literal" */, 3.4  /* ERROR "cannot use .*\(truncated\)" */}
-
-	// invalid type
-	type P *struct{
-		x int
-	}
-	_ = P /* ERROR "invalid composite literal type" */ {}
-
-	// unexported fields
-	_ = time.Time{}
-	_ = time.Time{sec /* ERROR "unknown field" */ : 0}
-	_ = time.Time{
-		0 /* ERROR implicit assignment to unexported field wall in time.Time literal */,
-		0 /* ERROR implicit assignment */ ,
-		nil /* ERROR implicit assignment */ ,
-	}
-}
-
-func array_literals() {
-	type A0 [0]int
-	_ = A0{}
-	_ = A0{0 /* ERROR "index .* out of bounds" */}
-	_ = A0{0 /* ERROR "index .* out of bounds" */ : 0}
-
-	type A1 [10]int
-	_ = A1{}
-	_ = A1{0, 1, 2}
-	_ = A1{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
-	_ = A1{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 /* ERROR "index .* out of bounds" */ }
-	_ = A1{- /* ERROR "negative" */ 1: 0}
-	_ = A1{8: 8, 9}
-	_ = A1{8: 8, 9, 10 /* ERROR "index .* out of bounds" */ }
-	_ = A1{0, 1, 2, 0 /* ERROR "duplicate index" */ : 0, 3: 3, 4}
-	_ = A1{5: 5, 6, 7, 3: 3, 4}
-	_ = A1{5: 5, 6, 7, 3: 3, 4, 5 /* ERROR "duplicate index" */ }
-	_ = A1{10 /* ERROR "index .* out of bounds" */ : 10, 10 /* ERROR "index .* out of bounds" */ : 10}
-	_ = A1{5: 5, 6, 7, 3: 3, 1 /* ERROR "overflows" */ <<100: 4, 5 /* ERROR "duplicate index" */ }
-	_ = A1{5: 5, 6, 7, 4: 4, 1 /* ERROR "overflows" */ <<100: 4}
-	_ = A1{2.0}
-	_ = A1{2.1 /* ERROR "truncated" */ }
-	_ = A1{"foo" /* ERROR "cannot use .* in array or slice literal" */ }
-
-	// indices must be integer constants
-	i := 1
-	const f = 2.1
-	const s = "foo"
-	_ = A1{i /* ERROR "index i must be integer constant" */ : 0}
-	_ = A1{f /* ERROR "truncated" */ : 0}
-	_ = A1{s /* ERROR "cannot convert" */ : 0}
-
-	a0 := [...]int{}
-	assert(len(a0) == 0)
-
-	a1 := [...]int{0, 1, 2}
-	assert(len(a1) == 3)
-	var a13 [3]int
-	var a14 [4]int
-	a13 = a1
-	a14 = a1 /* ERROR "cannot use .* in assignment" */
-	_, _ = a13, a14
-
-	a2 := [...]int{- /* ERROR "negative" */ 1: 0}
-	_ = a2
-
-	a3 := [...]int{0, 1, 2, 0 /* ERROR "duplicate index" */ : 0, 3: 3, 4}
-	assert(len(a3) == 5) // somewhat arbitrary
-
-	a4 := [...]complex128{0, 1, 2, 1<<10-2: -1i, 1i, 400: 10, 12, 14}
-	assert(len(a4) == 1024)
-
-	// composite literal element types may be elided
-	type T []int
-	_ = [10]T{T{}, {}, 5: T{1, 2, 3}, 7: {1, 2, 3}}
-	a6 := [...]T{T{}, {}, 5: T{1, 2, 3}, 7: {1, 2, 3}}
-	assert(len(a6) == 8)
-
-	// recursively so
-	_ = [10][10]T{{}, [10]T{{}}, {{1, 2, 3}}}
-
-	// from the spec
-	type Point struct { x, y float32 }
-	_ = [...]Point{Point{1.5, -3.5}, Point{0, 0}}
-	_ = [...]Point{{1.5, -3.5}, {0, 0}}
-	_ = [][]int{[]int{1, 2, 3}, []int{4, 5}}
-	_ = [][]int{{1, 2, 3}, {4, 5}}
-	_ = [...]*Point{&Point{1.5, -3.5}, &Point{0, 0}}
-	_ = [...]*Point{{1.5, -3.5}, {0, 0}}
-}
-
-func slice_literals() {
-	type S0 []int
-	_ = S0{}
-	_ = S0{0, 1, 2}
-	_ = S0{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
-	_ = S0{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
-	_ = S0{- /* ERROR "negative" */ 1: 0}
-	_ = S0{8: 8, 9}
-	_ = S0{8: 8, 9, 10}
-	_ = S0{0, 1, 2, 0 /* ERROR "duplicate index" */ : 0, 3: 3, 4}
-	_ = S0{5: 5, 6, 7, 3: 3, 4}
-	_ = S0{5: 5, 6, 7, 3: 3, 4, 5 /* ERROR "duplicate index" */ }
-	_ = S0{10: 10, 10 /* ERROR "duplicate index" */ : 10}
-	_ = S0{5: 5, 6, 7, 3: 3, 1 /* ERROR "overflows" */ <<100: 4, 5 /* ERROR "duplicate index" */ }
-	_ = S0{5: 5, 6, 7, 4: 4, 1 /* ERROR "overflows" */ <<100: 4}
-	_ = S0{2.0}
-	_ = S0{2.1 /* ERROR "truncated" */ }
-	_ = S0{"foo" /* ERROR "cannot use .* in array or slice literal" */ }
-
-	// indices must be resolved correctly
-	const index1 = 1
-	_ = S0{index1: 1}
-	_ = S0{index2: 2}
-	_ = S0{index3 /* ERROR "undeclared name" */ : 3}
-
-	// indices must be integer constants
-	i := 1
-	const f = 2.1
-	const s = "foo"
-	_ = S0{i /* ERROR "index i must be integer constant" */ : 0}
-	_ = S0{f /* ERROR "truncated" */ : 0}
-	_ = S0{s /* ERROR "cannot convert" */ : 0}
-
-	// composite literal element types may be elided
-	type T []int
-	_ = []T{T{}, {}, 5: T{1, 2, 3}, 7: {1, 2, 3}}
-	_ = [][]int{{1, 2, 3}, {4, 5}}
-
-	// recursively so
-	_ = [][]T{{}, []T{{}}, {{1, 2, 3}}}
-
-	// issue 17954
-	type T0 *struct { s string }
-	_ = []T0{{}}
-	_ = []T0{{"foo"}}
-
-	type T1 *struct{ int }
-	_ = []T1{}
-	_ = []T1{{0}, {1}, {2}}
-
-	type T2 T1
-	_ = []T2{}
-	_ = []T2{{0}, {1}, {2}}
-
-	_ = map[T0]T2{}
-	_ = map[T0]T2{{}: {}}
-}
-
-const index2 int = 2
-
-type N int
-func (N) f() {}
-
-func map_literals() {
-	type M0 map[string]int
-	type M1 map[bool]int
-	type M2 map[*int]int
-
-	_ = M0{}
-	_ = M0{1 /* ERROR "missing key" */ }
-	_ = M0{1 /* ERROR "cannot use .* in map literal" */ : 2}
-	_ = M0{"foo": "bar" /* ERROR "cannot use .* in map literal" */ }
-	_ = M0{"foo": 1, "bar": 2, "foo" /* ERROR "duplicate key" */ : 3 }
-
-	_ = map[interface{}]int{2: 1, 2 /* ERROR "duplicate key" */ : 1}
-	_ = map[interface{}]int{int(2): 1, int16(2): 1}
-	_ = map[interface{}]int{int16(2): 1, int16 /* ERROR "duplicate key" */ (2): 1}
-
-	type S string
-
-	_ = map[interface{}]int{"a": 1, "a" /* ERROR "duplicate key" */ : 1}
-	_ = map[interface{}]int{"a": 1, S("a"): 1}
-	_ = map[interface{}]int{S("a"): 1, S /* ERROR "duplicate key" */ ("a"): 1}
-	_ = map[interface{}]int{1.0: 1, 1.0 /* ERROR "duplicate key" */: 1}
-	_ = map[interface{}]int{int64(-1): 1, int64 /* ERROR "duplicate key" */ (-1) : 1}
-	_ = map[interface{}]int{^uint64(0): 1, ^ /* ERROR "duplicate key" */ uint64(0): 1}
-	_ = map[interface{}]int{complex(1,2): 1, complex /* ERROR "duplicate key" */ (1,2) : 1}
-
-	type I interface {
-		f()
-	}
-
-	_ = map[I]int{N(0): 1, N(2): 1}
-	_ = map[I]int{N(2): 1, N /* ERROR "duplicate key" */ (2): 1}
-
-	// map keys must be resolved correctly
-	key1 := "foo"
-	_ = M0{key1: 1}
-	_ = M0{key2: 2}
-	_ = M0{key3 /* ERROR "undeclared name" */ : 2}
-
-	var value int
-	_ = M1{true: 1, false: 0}
-	_ = M2{nil: 0, &value: 1}
-
-	// composite literal element types may be elided
-	type T [2]int
-	_ = map[int]T{0: T{3, 4}, 1: {5, 6}}
-
-	// recursively so
-	_ = map[int][]T{0: {}, 1: {{}, T{1, 2}}}
-
-	// composite literal key types may be elided
-	_ = map[T]int{T{3, 4}: 0, {5, 6}: 1}
-
-	// recursively so
-	_ = map[[2]T]int{{}: 0, {{}}: 1, [2]T{{}}: 2, {T{1, 2}}: 3}
-
-	// composite literal element and key types may be elided
-	_ = map[T]T{{}: {}, {1, 2}: T{3, 4}, T{4, 5}: {}}
-	_ = map[T]M0{{} : {}, T{1, 2}: M0{"foo": 0}, {1, 3}: {"foo": 1}}
-
-	// recursively so
-	_ = map[[2]T][]T{{}: {}, {{}}: {{}, T{1, 2}}, [2]T{{}}: nil, {T{1, 2}}: {{}, {}}}
-
-	// from the spec
-	type Point struct { x, y float32 }
-	_ = map[string]Point{"orig": {0, 0}}
-	_ = map[*Point]string{{0, 0}: "orig"}
-
-	// issue 17954
-	type T0 *struct{ s string }
-	type T1 *struct{ int }
-	type T2 T1
-
-	_ = map[T0]T2{}
-	_ = map[T0]T2{{}: {}}
-}
-
-var key2 string = "bar"
-
-type I interface {
-	m()
-}
-
-type I2 interface {
-	m(int)
-}
-
-type T1 struct{}
-type T2 struct{}
-
-func (T2) m(int) {}
-
-type mybool bool
-
-func type_asserts() {
-	var x int
-	_ = x /* ERROR "not an interface" */ .(int)
-
-	var e interface{}
-	var ok bool
-	x, ok = e.(int)
-	_ = ok
-
-	// ok value is of type bool
-	var myok mybool
-	_, myok = e.(int)
-	_ = myok
-
-	var t I
-	_ = t /* ERROR "use of .* outside type switch" */ .(type)
-	_ = t /* ERROR "m has pointer receiver" */ .(T)
-	_ = t.(*T)
-	_ = t /* ERROR "missing method m" */ .(T1)
-	_ = t /* ERROR "wrong type for method m" */ .(T2)
-	_ = t /* STRICT "wrong type for method m" */ .(I2) // only an error in strict mode (issue 8561)
-
-	// e doesn't statically have an m, but may have one dynamically.
-	_ = e.(I2)
-}
-
-func f0() {}
-func f1(x int) {}
-func f2(u float32, s string) {}
-func fs(s []byte) {}
-func fv(x ...int) {}
-func fi(x ... interface{}) {}
-func (T) fm(x ...int)
-
-func g0() {}
-func g1() int { return 0}
-func g2() (u float32, s string) { return }
-func gs() []byte { return nil }
-
-func _calls() {
-	var x int
-	var y float32
-	var s []int
-
-	f0()
-	_ = f0 /* ERROR "used as value" */ ()
-	f0(g0 /* ERROR "too many arguments" */ )
-
-	f1(0)
-	f1(x)
-	f1(10.0)
-	f1() /* ERROR "not enough arguments in call to f1\n\thave \(\)\n\twant \(int\)" */
-	f1(x, y /* ERROR "too many arguments in call to f1\n\thave \(int, float32\)\n\twant \(int\)" */ )
-	f1(s /* ERROR "cannot use .* in argument" */ )
-	f1(x ... /* ERROR "cannot use ..." */ )
-	f1(g0 /* ERROR "used as value" */ ())
-	f1(g1())
-	f1(g2 /* ERROR "too many arguments in call to f1\n\thave \(float32, string\)\n\twant \(int\)" */ ())
-
-	f2() /* ERROR "not enough arguments in call to f2\n\thave \(\)\n\twant \(float32, string\)" */
-	f2(3.14) /* ERROR "not enough arguments in call to f2\n\thave \(number\)\n\twant \(float32, string\)" */
-	f2(3.14, "foo")
-	f2(x /* ERROR "cannot use .* in argument" */ , "foo")
-	f2(g0 /* ERROR "used as value" */ ())
-	f2(g1()) /* ERROR "not enough arguments in call to f2\n\thave \(int\)\n\twant \(float32, string\)" */
-	f2(g2())
-
-	fs() /* ERROR "not enough arguments" */
-	fs(g0 /* ERROR "used as value" */ ())
-	fs(g1 /* ERROR "cannot use .* in argument" */ ())
-	fs(g2 /* ERROR "too many arguments" */ ())
-	fs(gs())
-
-	fv()
-	fv(1, 2.0, x)
-	fv(s /* ERROR "cannot use .* in argument" */ )
-	fv(s...)
-	fv(x /* ERROR "cannot use" */ ...)
-	fv(1, s /* ERROR "too many arguments" */ ...)
-	fv(gs /* ERROR "cannot use .* in argument" */ ())
-	fv(gs /* ERROR "cannot use .* in argument" */ ()...)
-
-	var t T
-	t.fm()
-	t.fm(1, 2.0, x)
-	t.fm(s /* ERROR "cannot use .* in argument" */ )
-	t.fm(g1())
-	t.fm(1, s /* ERROR "too many arguments" */ ...)
-	t.fm(gs /* ERROR "cannot use .* in argument" */ ())
-	t.fm(gs /* ERROR "cannot use .* in argument" */ ()...)
-
-	T.fm(t, )
-	T.fm(t, 1, 2.0, x)
-	T.fm(t, s /* ERROR "cannot use .* in argument" */ )
-	T.fm(t, g1())
-	T.fm(t, 1, s /* ERROR "too many arguments" */ ...)
-	T.fm(t, gs /* ERROR "cannot use .* in argument" */ ())
-	T.fm(t, gs /* ERROR "cannot use .* in argument" */ ()...)
-
-	var i interface{ fm(x ...int) } = t
-	i.fm()
-	i.fm(1, 2.0, x)
-	i.fm(s /* ERROR "cannot use .* in argument" */ )
-	i.fm(g1())
-	i.fm(1, s /* ERROR "too many arguments" */ ...)
-	i.fm(gs /* ERROR "cannot use .* in argument" */ ())
-	i.fm(gs /* ERROR "cannot use .* in argument" */ ()...)
-
-	fi()
-	fi(1, 2.0, x, 3.14, "foo")
-	fi(g2())
-	fi(0, g2)
-	fi(0, g2 /* ERROR "2-valued g2" */ ())
-}
-
-func issue6344() {
-	type T []interface{}
-	var x T
-	fi(x...) // ... applies also to named slices
-}
diff --git a/src/go/types/testdata/check/go1_12.go b/src/go/types/testdata/check/go1_12.go
deleted file mode 100644
index 14c2d58..0000000
--- a/src/go/types/testdata/check/go1_12.go
+++ /dev/null
@@ -1,37 +0,0 @@
-// -lang=go1.12
-
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Check Go language version-specific errors.
-
-package p
-
-// numeric literals
-const (
-	_ = 1_000 // ERROR "underscores in numeric literals requires go1.13 or later"
-	_ = 0b111 // ERROR "binary literals requires go1.13 or later"
-	_ = 0o567 // ERROR "0o/0O-style octal literals requires go1.13 or later"
-	_ = 0xabc // ok
-	_ = 0x0p1 // ERROR "hexadecimal floating-point literals requires go1.13 or later"
-
-	_ = 0B111 // ERROR "binary"
-	_ = 0O567 // ERROR "octal"
-	_ = 0Xabc // ok
-	_ = 0X0P1 // ERROR "hexadecimal floating-point"
-
-	_ = 1_000i // ERROR "underscores"
-	_ = 0b111i // ERROR "binary"
-	_ = 0o567i // ERROR "octal"
-	_ = 0xabci // ERROR "hexadecimal floating-point"
-	_ = 0x0p1i // ERROR "hexadecimal floating-point"
-)
-
-// signed shift counts
-var (
-	s int
-	_ = 1 << s // ERROR "invalid operation: signed shift count s \(variable of type int\) requires go1.13 or later"
-	_ = 1 >> s // ERROR "signed shift count"
-)
-
diff --git a/src/go/types/testdata/check/go1_13.go b/src/go/types/testdata/check/go1_13.go
deleted file mode 100644
index 5c52dfe..0000000
--- a/src/go/types/testdata/check/go1_13.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// -lang=go1.13
-
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Check Go language version-specific errors.
-
-package p
-
-// interface embedding
-
-type I interface { m() }
-
-type _ interface {
-	m()
-	I // ERROR "duplicate method m"
-}
-
-type _ interface {
-	I
-	I // ERROR "duplicate method m"
-}
-
diff --git a/src/go/types/testdata/check/go1_8.go b/src/go/types/testdata/check/go1_8.go
deleted file mode 100644
index 5d57cdc..0000000
--- a/src/go/types/testdata/check/go1_8.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// -lang=go1.8
-
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Check Go language version-specific errors.
-
-package p
-
-// type alias declarations
-type any = /* ERROR type aliases requires go1.9 or later */ interface{}
-
diff --git a/src/go/types/testdata/check/importdecl0/importdecl0a.go b/src/go/types/testdata/check/importdecl0/importdecl0a.go
deleted file mode 100644
index 5ceb96e..0000000
--- a/src/go/types/testdata/check/importdecl0/importdecl0a.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package importdecl0
-
-import ()
-
-import (
-	// we can have multiple blank imports (was bug)
-	_ "math"
-	_ "net/rpc"
-	init /* ERROR "cannot import package as init" */ "fmt"
-	// reflect defines a type "flag" which shows up in the gc export data
-	"reflect"
-	. /* ERROR "imported but not used" */ "reflect"
-)
-
-import "math" /* ERROR "imported but not used" */
-import m /* ERROR "imported but not used as m" */ "math"
-import _ "math"
-
-import (
-	"math/big" /* ERROR "imported but not used" */
-	b /* ERROR "imported but not used" */ "math/big"
-	_ "math/big"
-)
-
-import "fmt"
-import f1 "fmt"
-import f2 "fmt"
-
-// reflect.flag must not be visible in this package
-type flag int
-type _ reflect.flag /* ERROR "not exported" */
-
-// imported package name may conflict with local objects
-type reflect /* ERROR "reflect already declared" */ int
-
-// dot-imported exported objects may conflict with local objects
-type Value /* ERROR "Value already declared through dot-import of package reflect" */ struct{}
-
-var _ = fmt.Println // use "fmt"
-
-func _() {
-	f1.Println() // use "fmt"
-}
-
-func _() {
-	_ = func() {
-		f2.Println() // use "fmt"
-	}
-}
diff --git a/src/go/types/testdata/check/importdecl0/importdecl0b.go b/src/go/types/testdata/check/importdecl0/importdecl0b.go
deleted file mode 100644
index 5569042..0000000
--- a/src/go/types/testdata/check/importdecl0/importdecl0b.go
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package importdecl0
-
-import "math"
-import m "math"
-
-import . "testing" // declares T in file scope
-import . /* ERROR .unsafe. imported but not used */ "unsafe"
-import . "fmt"     // declares Println in file scope
-
-import (
-	// TODO(gri) At the moment, 2 errors are reported because both go/parser
-	// and the type checker report it. Eventually, this test should not be
-	// done by the parser anymore.
-	"" /* ERROR invalid import path */ /* ERROR invalid import path */
-	"a!b" /* ERROR invalid import path */ /* ERROR invalid import path */
-	"abc\xffdef" /* ERROR invalid import path */ /* ERROR invalid import path */
-)
-
-// using "math" in this file doesn't affect its use in other files
-const Pi0 = math.Pi
-const Pi1 = m.Pi
-
-type _ T // use "testing"
-
-func _() func() interface{} {
-	return func() interface{} {
-		return Println // use "fmt"
-	}
-}
diff --git a/src/go/types/testdata/check/importdecl1/importdecl1b.go b/src/go/types/testdata/check/importdecl1/importdecl1b.go
deleted file mode 100644
index 43a7bcd..0000000
--- a/src/go/types/testdata/check/importdecl1/importdecl1b.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package importdecl1
-
-import . /* ERROR .unsafe. imported but not used */ "unsafe"
-
-type B interface {
-	A
-}
diff --git a/src/go/types/testdata/check/init0.go b/src/go/types/testdata/check/init0.go
deleted file mode 100644
index 6e8746a..0000000
--- a/src/go/types/testdata/check/init0.go
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// initialization cycles
-
-package init0
-
-// initialization cycles (we don't know the types)
-const (
-	s0 /* ERROR initialization cycle */ = s0
-
-	x0 /* ERROR initialization cycle */ = y0
-	y0 = x0
-
-	a0 = b0
-	b0 /* ERROR initialization cycle */ = c0
-	c0 = d0
-	d0 = b0
-)
-
-var (
-	s1 /* ERROR initialization cycle */ = s1
-
-	x1 /* ERROR initialization cycle */ = y1
-	y1 = x1
-
-	a1 = b1
-	b1 /* ERROR initialization cycle */ = c1
-	c1 = d1
-	d1 = b1
-)
-
-// initialization cycles (we know the types)
-const (
-	s2 /* ERROR initialization cycle */ int = s2
-
-	x2 /* ERROR initialization cycle */ int = y2
-	y2 = x2
-
-	a2 = b2
-	b2 /* ERROR initialization cycle */ int = c2
-	c2 = d2
-	d2 = b2
-)
-
-var (
-	s3 /* ERROR initialization cycle */ int = s3
-
-	x3 /* ERROR initialization cycle */ int = y3
-	y3 = x3
-
-	a3 = b3
-	b3 /* ERROR initialization cycle */ int = c3
-	c3 = d3
-	d3 = b3
-)
-
-// cycles via struct fields
-
-type S1 struct {
-	f int
-}
-const cx3 S1 /* ERROR invalid constant type */ = S1{cx3.f}
-var vx3 /* ERROR initialization cycle */ S1 = S1{vx3.f}
-
-// cycles via functions
-
-var x4 = x5
-var x5 /* ERROR initialization cycle */ = f1()
-func f1() int { return x5*10 }
-
-var x6, x7 /* ERROR initialization cycle */ = f2()
-var x8 = x7
-func f2() (int, int) { return f3() + f3(), 0 }
-func f3() int { return x8 }
-
-// cycles via function literals
-
-var x9 /* ERROR initialization cycle */ = func() int { return x9 }()
-
-var x10 /* ERROR initialization cycle */ = f4()
-
-func f4() int {
-	_ = func() {
-		_ = x10
-	}
-	return 0
-}
-
-// cycles via method expressions
-
-type T1 struct{}
-
-func (T1) m() bool { _ = x11; return false }
-
-var x11 /* ERROR initialization cycle */ = T1.m(T1{})
-
-// cycles via method values
-
-type T2 struct{}
-
-func (T2) m() bool { _ = x12; return false }
-
-var t1 T2
-var x12 /* ERROR initialization cycle */ = t1.m
diff --git a/src/go/types/testdata/check/issues0.go b/src/go/types/testdata/check/issues0.go
deleted file mode 100644
index 6943796..0000000
--- a/src/go/types/testdata/check/issues0.go
+++ /dev/null
@@ -1,373 +0,0 @@
-// -lang=go1.17
-
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p // don't permit non-interface elements in interfaces
-
-import (
-	"fmt"
-	syn "regexp/syntax"
-	t1 "text/template"
-	t2 "html/template"
-)
-
-func issue7035() {
-	type T struct{ X int }
-	_ = func() {
-		fmt.Println() // must refer to imported fmt rather than the fmt below
-	}
-	fmt := new(T)
-	_ = fmt.X
-}
-
-func issue8066() {
-	const (
-		_ = float32(340282356779733661637539395458142568447)
-		_ = float32(340282356779733661637539395458142568448 /* ERROR cannot convert */ )
-	)
-}
-
-// Check that a missing identifier doesn't lead to a spurious error cascade.
-func issue8799a() {
-	x, ok := missing /* ERROR undeclared */ ()
-	_ = !ok
-	_ = x
-}
-
-func issue8799b(x int, ok bool) {
-	x, ok = missing /* ERROR undeclared */ ()
-	_ = !ok
-	_ = x
-}
-
-func issue9182() {
-	type Point C /* ERROR undeclared */ .Point
-	// no error for composite literal based on unknown type
-	_ = Point{x: 1, y: 2}
-}
-
-func f0() (a []int)         { return }
-func f1() (a []int, b int)  { return }
-func f2() (a, b []int)      { return }
-
-func append_([]int, ...int) {}
-
-func issue9473(a []int, b ...int) {
-	// variadic builtin function
-	_ = append(f0())
-	_ = append(f0(), f0()...)
-	_ = append(f1())
-	_ = append(f2 /* ERROR cannot use .* in argument */ ())
-	_ = append(f2()... /* ERROR cannot use ... */ )
-	_ = append(f0(), f1 /* ERROR 2-valued f1 */ ())
-	_ = append(f0(), f2 /* ERROR 2-valued f2 */ ())
-	_ = append(f0(), f1 /* ERROR 2-valued f1 */ ()...)
-	_ = append(f0(), f2 /* ERROR 2-valued f2 */ ()...)
-
-	// variadic user-defined function
-	append_(f0())
-	append_(f0(), f0()...)
-	append_(f1())
-	append_(f2 /* ERROR cannot use .* in argument */ ())
-	append_(f2()... /* ERROR cannot use ... */ )
-	append_(f0(), f1 /* ERROR 2-valued f1 */ ())
-	append_(f0(), f2 /* ERROR 2-valued f2 */ ())
-	append_(f0(), f1 /* ERROR 2-valued f1 */ ()...)
-	append_(f0(), f2 /* ERROR 2-valued f2 */ ()...)
-}
-
-// Check that embedding a non-interface type in an interface results in a good error message.
-func issue10979() {
-	type _ interface {
-		int /* ERROR non-interface type int */
-	}
-	type T struct{}
-	type _ interface {
-		T /* ERROR non-interface type T */
-	}
-	type _ interface {
-		nosuchtype /* ERROR undeclared name: nosuchtype */
-	}
-	type _ interface {
-		fmt.Nosuchtype /* ERROR Nosuchtype not declared by package fmt */
-	}
-	type _ interface {
-		nosuchpkg /* ERROR undeclared name: nosuchpkg */ .Nosuchtype
-	}
-	type I interface {
-		I.m /* ERROR no field or method m */
-		m()
-	}
-}
-
-// issue11347
-// These should not crash.
-var a1, b1 /* ERROR cycle */ , c1 /* ERROR cycle */ b1 = 0 > 0<<""[""[c1]]>c1
-var a2, b2 /* ERROR cycle */ = 0 /* ERROR cannot initialize */ /* ERROR cannot initialize */ > 0<<""[b2]
-var a3, b3 /* ERROR cycle */ = int /* ERROR cannot initialize */ /* ERROR cannot initialize */ (1<<""[b3])
-
-// issue10260
-// Check that error messages explain reason for interface assignment failures.
-type (
-	I0 interface{}
-	I1 interface{ foo() }
-	I2 interface{ foo(x int) }
-	T0 struct{}
-	T1 struct{}
-	T2 struct{}
-)
-
-func (*T1) foo() {}
-func (*T2) foo(x int) {}
-
-func issue10260() {
-	var (
-		i0 I0
-		i1 I1
-		i2 I2
-		t0 *T0
-		t1 *T1
-		t2 *T2
-	)
-
-	var x I1
-	x = T1 /* ERROR cannot use \(T1 literal\) .* as I1 value in assignment: T1 does not implement I1 \(method foo has pointer receiver\) */ {}
-	_ = x /* ERROR impossible type assertion: x\.\(T1\)\n\tT1 does not implement I1 \(method foo has pointer receiver\) */ .(T1)
-
-	T1{}.foo /* ERROR cannot call pointer method foo on T1 */ ()
-	x.Foo /* ERROR "x.Foo undefined \(type I1 has no field or method Foo, but does have foo\)" */ ()
-
-	_ = i2 /* ERROR impossible type assertion: i2\.\(\*T1\)\n\t\*T1 does not implement I2 \(wrong type for method foo\)\n\t\thave foo\(\)\n\t\twant foo\(x int\) */ .(*T1)
-
-	i1 = i0 /* ERROR cannot use i0 .* as I1 value in assignment: I0 does not implement I1 \(missing method foo\) */
-	i1 = t0 /* ERROR .* t0 .* as I1 .*: \*T0 does not implement I1 \(missing method foo\) */
-	i1 = i2 /* ERROR .* i2 .* as I1 .*: I2 does not implement I1 \(wrong type for method foo\)\n\t\thave foo\(x int\)\n\t\twant foo\(\) */
-	i1 = t2 /* ERROR .* t2 .* as I1 .*: \*T2 does not implement I1 \(wrong type for method foo\)\n\t\thave foo\(x int\)\n\t\twant foo\(\) */
-	i2 = i1 /* ERROR .* i1 .* as I2 .*: I1 does not implement I2 \(wrong type for method foo\)\n\t\thave foo\(\)\n\t\twant foo\(x int\) */
-	i2 = t1 /* ERROR .* t1 .* as I2 .*: \*T1 does not implement I2 \(wrong type for method foo\)\n\t\thave foo\(\)\n\t\twant foo\(x int\) */
-
-	_ = func() I1 { return i0 /* ERROR cannot use i0 .* as I1 value in return statement: I0 does not implement I1 \(missing method foo\) */ }
-	_ = func() I1 { return t0 /* ERROR .* t0 .* as I1 .*: \*T0 does not implement I1 \(missing method foo\) */ }
-	_ = func() I1 { return i2 /* ERROR .* i2 .* as I1 .*: I2 does not implement I1 \(wrong type for method foo\)\n\t\thave foo\(x int\)\n\t\twant foo\(\) */ }
-	_ = func() I1 { return t2 /* ERROR .* t2 .* as I1 .*: \*T2 does not implement I1 \(wrong type for method foo\)\n\t\thave foo\(x int\)\n\t\twant foo\(\) */ }
-	_ = func() I2 { return i1 /* ERROR .* i1 .* as I2 .*: I1 does not implement I2 \(wrong type for method foo\)\n\t\thave foo\(\)\n\t\twant foo\(x int\) */ }
-	_ = func() I2 { return t1 /* ERROR .* t1 .* as I2 .*: \*T1 does not implement I2 \(wrong type for method foo\)\n\t\thave foo\(\)\n\t\twant foo\(x int\) */ }
-
-	// a few more - less exhaustive now
-
-	f := func(I1, I2){}
-	f(i0 /* ERROR missing method foo */ , i1 /* ERROR wrong type for method foo */ )
-
-	_ = [...]I1{i0 /* ERROR cannot use i0 .* as I1 value in array or slice literal: I0 does not implement I1 \(missing method foo\) */ }
-	_ = [...]I1{i2 /* ERROR cannot use i2 .* as I1 value in array or slice literal: I2 does not implement I1 \(wrong type for method foo\)\n\t\thave foo\(x int\)\n\t\twant foo\(\) */ }
-	_ = []I1{i0 /* ERROR missing method foo */ }
-	_ = []I1{i2 /* ERROR wrong type for method foo */ }
-	_ = map[int]I1{0: i0 /* ERROR missing method foo */ }
-	_ = map[int]I1{0: i2 /* ERROR wrong type for method foo */ }
-
-	make(chan I1) <- i0 /* ERROR missing method foo */
-	make(chan I1) <- i2 /* ERROR wrong type for method foo */
-}
-
-// Check that constants representable as integers are in integer form
-// before being used in operations that are only defined on integers.
-func issue14229() {
-	// from the issue
-	const _ = int64(-1<<63) % 1e6
-
-	// related
-	const (
-		a int = 3
-		b = 4.0
-		_ = a / b
-		_ = a % b
-		_ = b / a
-		_ = b % a
-	)
-}
-
-// Check that in a n:1 variable declaration with type and initialization
-// expression the type is distributed to all variables of the lhs before
-// the initialization expression assignment is checked.
-func issue15755() {
-	// from issue
-	var i interface{}
-	type b bool
-	var x, y b = i.(b)
-	_ = x == y
-
-	// related: we should see an error since the result of f1 is ([]int, int)
-	var u, v []int = f1 /* ERROR cannot use f1 */ ()
-	_ = u
-	_ = v
-}
-
-// Test that we don't get "declared but not used"
-// errors in the context of invalid/C objects.
-func issue20358() {
-	var F C /* ERROR "undeclared" */ .F
-	var A C /* ERROR "undeclared" */ .A
-	var S C /* ERROR "undeclared" */ .S
-	type T C /* ERROR "undeclared" */ .T
-	type P C /* ERROR "undeclared" */ .P
-
-	// these variables must be "used" even though
-	// the LHS expressions/types below in which
-	// context they are used are unknown/invalid
-	var f, a, s1, s2, s3, t, p int
-
-	_ = F(f)
-	_ = A[a]
-	_ = S[s1:s2:s3]
-	_ = T{t}
-	_ = P{f: p}
-}
-
-// Test that we don't declare lhs variables in short variable
-// declarations before we type-check function literals on the
-// rhs.
-func issue24026() {
-	f := func() int { f(0) /* must refer to outer f */; return 0 }
-	_ = f
-
-	_ = func() {
-		f := func() { _ = f() /* must refer to outer f */ }
-		_ = f
-	}
-
-	// b and c must not be visible inside function literal
-	a := 0
-	a, b, c := func() (int, int, int) {
-		return a, b /* ERROR undeclared */ , c /* ERROR undeclared */
-	}()
-	_, _ = b, c
-}
-
-func f(int) {} // for issue24026
-
-// Test that we don't report a "missing return statement" error
-// (due to incorrect context when type-checking interfaces).
-func issue24140(x interface{}) int {
-        switch x.(type) {
-        case interface{}:
-                return 0
-        default:
-                panic(0)
-        }
-}
-
-// Test that we don't crash when the 'if' condition is missing.
-func issue25438() {
-	if { /* ERROR missing condition */ }
-	if x := 0; /* ERROR missing condition */ { _ = x }
-	if
-	{ /* ERROR missing condition */ }
-}
-
-// Test that we can embed alias type names in interfaces.
-type issue25301 interface {
-	E
-}
-
-type E = interface {
-	m()
-}
-
-// Test case from issue.
-// cmd/compile reports a cycle as well.
-type issue25301b /* ERROR cycle */ = interface {
-	m() interface{ issue25301b }
-}
-
-type issue25301c interface {
-	notE // ERROR non-interface type struct\{\}
-}
-
-type notE = struct{}
-
-// Test that method declarations don't introduce artificial cycles
-// (issue #26124).
-const CC TT = 1
-type TT int
-func (TT) MM() [CC]TT
-
-// Reduced test case from issue #26124.
-const preloadLimit LNumber = 128
-type LNumber float64
-func (LNumber) assertFunction() *LFunction
-type LFunction struct {
-	GFunction LGFunction
-}
-type LGFunction func(*LState)
-type LState struct {
-	reg *registry
-}
-type registry struct {
-	alloc *allocator
-}
-type allocator struct {
-	_ [int(preloadLimit)]int
-}
-
-// Test that we don't crash when type-checking composite literals
-// containing errors in the type.
-var issue27346 = [][n /* ERROR undeclared */ ]int{
-	0: {},
-}
-
-var issue22467 = map[int][... /* ERROR invalid use of ... */ ]int{0: {}}
-
-// Test that invalid use of ... in parameter lists is recognized
-// (issue #28281).
-func issue28281a(int, int, ...int)
-func issue28281b(a, b int, c ...int)
-func issue28281c(a, b, c ... /* ERROR can only use ... with final parameter */ int)
-func issue28281d(... /* ERROR can only use ... with final parameter */ int, int)
-func issue28281e(a, b, c  ... /* ERROR can only use ... with final parameter */ int, d int)
-func issue28281f(... /* ERROR can only use ... with final parameter */ int, ... /* ERROR can only use ... with final parameter */ int, int)
-func (... /* ERROR can only use ... with final parameter */ TT) f()
-func issue28281g() (... /* ERROR can only use ... with final parameter */ TT)
-
-// Issue #26234: Make various field/method lookup errors easier to read by matching cmd/compile's output
-func issue26234a(f *syn.Prog) {
-	// The error message below should refer to the actual package name (syntax)
-	// not the local package name (syn).
-	f.foo /* ERROR f\.foo undefined \(type \*syntax\.Prog has no field or method foo\) */
-}
-
-type T struct {
-	x int
-	E1
-	E2
-}
-
-type E1 struct{ f int }
-type E2 struct{ f int }
-
-func issue26234b(x T) {
-	_ = x.f /* ERROR ambiguous selector x.f */
-}
-
-func issue26234c() {
-	T.x /* ERROR T.x undefined \(type T has no method x\) */ ()
-}
-
-func issue35895() {
-	// T is defined in this package, don't qualify its name with the package name.
-	var _ T = 0 // ERROR cannot use 0 \(untyped int constant\) as T
-
-	// There is only one package with name syntax imported, only use the (global) package name in error messages.
-	var _ *syn.Prog = 0 // ERROR cannot use 0 \(untyped int constant\) as \*syntax.Prog
-
-	// Because both t1 and t2 have the same global package name (template),
-	// qualify packages with full path name in this case.
-	var _ t1.Template = t2 /* ERROR cannot use .* \(value of type .html/template.\.Template\) as .text/template.\.Template */ .Template{}
-}
-
-func issue42989(s uint) {
-	var m map[int]string
-	delete(m, 1<<s)
-	delete(m, 1.<<s)
-}
diff --git a/src/go/types/testdata/check/issues1.go b/src/go/types/testdata/check/issues1.go
deleted file mode 100644
index 41a19ad..0000000
--- a/src/go/types/testdata/check/issues1.go
+++ /dev/null
@@ -1,250 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file contains regression tests for bugs found.
-
-package p
-
-import "io"
-import "context"
-
-func eql[T comparable](x, y T) bool {
-	return x == y
-}
-
-func _[X comparable, Y interface{comparable; m()}]() {
-	var x X
-	var y Y
-	eql(x, y /* ERROR does not match */ ) // interfaces of different types
-	eql(x, x)
-	eql(y, y)
-	eql(y, nil /* ERROR cannot use nil as Y value in argument to eql */ )
-	eql[io /* ERROR does not implement comparable */ .Reader](nil, nil)
-}
-
-// If we have a receiver of pointer to type parameter type (below: *T)
-// we don't have any methods, like for interfaces.
-type C[T any] interface {
-    m()
-}
-
-// using type bound C
-func _[T C[T]](x *T) {
-	x.m /* ERROR x\.m undefined */ ()
-}
-
-// using an interface literal as bound
-func _[T interface{ m() }](x *T) {
-	x.m /* ERROR x\.m undefined */ ()
-}
-
-func f2[_ interface{ m1(); m2() }]() {}
-
-type T struct{}
-func (T) m1()
-func (*T) m2()
-
-func _() {
-	f2[T /* ERROR m2 has pointer receiver */ ]()
-	f2[*T]()
-}
-
-// When a type parameter is used as an argument to instantiate a parameterized
-// type, the type argument's type set must be a subset of the instantiated type
-// parameter's type set.
-type T1[P interface{~uint}] struct{}
-
-func _[P any]() {
-    _ = T1[P /* ERROR P does not implement interface{~uint} */ ]{}
-}
-
-// This is the original (simplified) program causing the same issue.
-type Unsigned interface {
-	~uint
-}
-
-type T2[U Unsigned] struct {
-    s U
-}
-
-func (u T2[U]) Add1() U {
-    return u.s + 1
-}
-
-func NewT2[U any]() T2[U /* ERROR U does not implement Unsigned */ ] {
-    return T2[U /* ERROR U does not implement Unsigned */ ]{}
-}
-
-func _() {
-    u := NewT2[string]()
-    _ = u.Add1()
-}
-
-// When we encounter an instantiated type such as Elem[T] we must
-// not "expand" the instantiation when the type to be instantiated
-// (Elem in this case) is not yet fully set up.
-type Elem[T any] struct {
-	next *Elem[T]
-	list *List[T]
-}
-
-type List[T any] struct {
-	root Elem[T]
-}
-
-func (l *List[T]) Init() {
-	l.root.next = &l.root
-}
-
-// This is the original program causing the same issue.
-type Element2[TElem any] struct {
-	next, prev *Element2[TElem]
-	list *List2[TElem]
-	Value TElem
-}
-
-type List2[TElem any] struct {
-	root Element2[TElem]
-	len  int
-}
-
-func (l *List2[TElem]) Init() *List2[TElem] {
-	l.root.next = &l.root
-	l.root.prev = &l.root
-	l.len = 0
-	return l
-}
-
-// Self-recursive instantiations must work correctly.
-type A[P any] struct { _ *A[P] }
-
-type AB[P any] struct { _ *BA[P] }
-type BA[P any] struct { _ *AB[P] }
-
-// And a variation that also caused a problem with an
-// unresolved underlying type.
-type Element3[TElem any] struct {
-	next, prev *Element3[TElem]
-	list *List3[TElem]
-	Value TElem
-}
-
-func (e *Element3[TElem]) Next() *Element3[TElem] {
-	if p := e.next; e.list != nil && p != &e.list.root {
-		return p
-	}
-	return nil
-}
-
-type List3[TElem any] struct {
-	root Element3[TElem]
-	len  int
-}
-
-// Infinite generic type declarations must lead to an error.
-type inf1[T any] struct{ _ inf1 /* ERROR illegal cycle */ [T] }
-type inf2[T any] struct{ inf2 /* ERROR illegal cycle */ [T] }
-
-// The implementation of conversions T(x) between integers and floating-point
-// numbers checks that both T and x have either integer or floating-point
-// type. When the type of T or x is a type parameter, the respective simple
-// predicate disjunction in the implementation was wrong because if a type set
-// contains both an integer and a floating-point type, the type parameter is
-// neither an integer or a floating-point number.
-func convert[T1, T2 interface{~int | ~uint | ~float32}](v T1) T2 {
-	return T2(v)
-}
-
-func _() {
-	convert[int, uint](5)
-}
-
-// When testing binary operators, for +, the operand types must either be
-// both numeric, or both strings. The implementation had the same problem
-// with this check as the conversion issue above (issue #39623).
-
-func issue39623[T interface{~int | ~string}](x, y T) T {
-	return x + y
-}
-
-// Simplified, from https://go2goplay.golang.org/p/efS6x6s-9NI:
-func Sum[T interface{~int | ~string}](s []T) (sum T) {
-	for _, v := range s {
-		sum += v
-	}
-	return
-}
-
-// Assignability of an unnamed pointer type to a type parameter that
-// has a matching underlying type.
-func _[T interface{}, PT interface{~*T}] (x T) PT {
-    return &x
-}
-
-// Indexing of type parameters containing type parameters in their constraint terms:
-func at[T interface{ ~[]E }, E interface{}](x T, i int) E {
-        return x[i]
-}
-
-// Conversion of a local type to a type parameter.
-func _[T interface{~int}](x T) {
-	type myint int
-	var _ int = int(x)
-	var _ T = 42
-	var _ T = T(myint(42))
-}
-
-// Indexing a type parameter with an array type bound checks length.
-// (Example by mdempsky@.)
-func _[T interface { ~[10]int }](x T) {
-	_ = x[9] // ok
-	_ = x[20 /* ERROR out of bounds */ ]
-}
-
-// Pointer indirection of a type parameter.
-func _[T interface{ ~*int }](p T) int {
-	return *p
-}
-
-// Channel sends and receives on type parameters.
-func _[T interface{ ~chan int }](ch T) int {
-	ch <- 0
-	return <- ch
-}
-
-// Calling of a generic variable.
-func _[T interface{ ~func() }](f T) {
-	f()
-	go f()
-}
-
-type F1 func()
-type F2 func()
-func _[T interface{ func()|F1|F2 }](f T) {
-	f()
-	go f()
-}
-
-// We must compare against the (possibly underlying) types of term list
-// elements when checking if a constraint is satisfied by a type.
-// The underlying type of each term must be computed after the
-// interface has been instantiated as its constraint may contain
-// a type parameter that was substituted with a defined type.
-// Test case from an (originally) failing example.
-
-type sliceOf[E any] interface{ ~[]E }
-
-func append[T interface{}, S sliceOf[T], T2 interface{}](s S, t ...T2) S { panic(0) }
-
-var f           func()
-var cancelSlice []context.CancelFunc
-var _ = append[context.CancelFunc, []context.CancelFunc, context.CancelFunc](cancelSlice, f)
-
-// A generic function must be instantiated with a type, not a value.
-
-func g[T any](T) T { panic(0) }
-
-var _ = g[int]
-var _ = g[nil /* ERROR is not a type */ ]
-var _ = g(0)
diff --git a/src/go/types/testdata/check/labels.go b/src/go/types/testdata/check/labels.go
deleted file mode 100644
index 9f42406..0000000
--- a/src/go/types/testdata/check/labels.go
+++ /dev/null
@@ -1,207 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file is a modified concatenation of the files
-// $GOROOT/test/label.go and $GOROOT/test/label1.go.
-
-package labels
-
-var x int
-
-func f0() {
-L1 /* ERROR "label L1 declared but not used" */ :
-	for {
-	}
-L2 /* ERROR "label L2 declared but not used" */ :
-	select {
-	}
-L3 /* ERROR "label L3 declared but not used" */ :
-	switch {
-	}
-L4 /* ERROR "label L4 declared but not used" */ :
-	if true {
-	}
-L5 /* ERROR "label L5 declared but not used" */ :
-	f0()
-L6:
-	f0()
-L6 /* ERROR "label L6 already declared" */ :
-	f0()
-	if x == 20 {
-		goto L6
-	}
-
-L7:
-	for {
-		break L7
-		break L8 /* ERROR "invalid break label L8" */
-	}
-
-// A label must be directly associated with a switch, select, or
-// for statement; it cannot be the label of a labeled statement.
-
-L7a /* ERROR "declared but not used" */ : L7b:
-	for {
-		break L7a /* ERROR "invalid break label L7a" */
-		continue L7a /* ERROR "invalid continue label L7a" */
-		continue L7b
-	}
-
-L8:
-	for {
-		if x == 21 {
-			continue L8
-			continue L7 /* ERROR "invalid continue label L7" */
-		}
-	}
-
-L9:
-	switch {
-	case true:
-		break L9
-	defalt /* ERROR "label defalt declared but not used" */ :
-	}
-
-L10:
-	select {
-	default:
-		break L10
-		break L9 /* ERROR "invalid break label L9" */
-	}
-
-	goto L10a
-L10a: L10b:
-	select {
-	default:
-		break L10a /* ERROR "invalid break label L10a" */
-		break L10b
-		continue L10b /* ERROR "invalid continue label L10b" */
-	}
-}
-
-func f1() {
-L1:
-	for {
-		if x == 0 {
-			break L1
-		}
-		if x == 1 {
-			continue L1
-		}
-		goto L1
-	}
-
-L2:
-	select {
-	default:
-		if x == 0 {
-			break L2
-		}
-		if x == 1 {
-			continue L2 /* ERROR "invalid continue label L2" */
-		}
-		goto L2
-	}
-
-L3:
-	switch {
-	case x > 10:
-		if x == 11 {
-			break L3
-		}
-		if x == 12 {
-			continue L3 /* ERROR "invalid continue label L3" */
-		}
-		goto L3
-	}
-
-L4:
-	if true {
-		if x == 13 {
-			break L4 /* ERROR "invalid break label L4" */
-		}
-		if x == 14 {
-			continue L4 /* ERROR "invalid continue label L4" */
-		}
-		if x == 15 {
-			goto L4
-		}
-	}
-
-L5:
-	f1()
-	if x == 16 {
-		break L5 /* ERROR "invalid break label L5" */
-	}
-	if x == 17 {
-		continue L5 /* ERROR "invalid continue label L5" */
-	}
-	if x == 18 {
-		goto L5
-	}
-
-	for {
-		if x == 19 {
-			break L1 /* ERROR "invalid break label L1" */
-		}
-		if x == 20 {
-			continue L1 /* ERROR "invalid continue label L1" */
-		}
-		if x == 21 {
-			goto L1
-		}
-	}
-}
-
-// Additional tests not in the original files.
-
-func f2() {
-L1 /* ERROR "label L1 declared but not used" */ :
-	if x == 0 {
-		for {
-			continue L1 /* ERROR "invalid continue label L1" */
-		}
-	}
-}
-
-func f3() {
-L1:
-L2:
-L3:
-	for {
-		break L1 /* ERROR "invalid break label L1" */
-		break L2 /* ERROR "invalid break label L2" */
-		break L3
-		continue L1 /* ERROR "invalid continue label L1" */
-		continue L2 /* ERROR "invalid continue label L2" */
-		continue L3
-		goto L1
-		goto L2
-		goto L3
-	}
-}
-
-// Blank labels are never declared.
-
-func f4() {
-_:
-_: // multiple blank labels are ok
-	goto _ /* ERROR "label _ not declared" */
-}
-
-func f5() {
-_:
-	for {
-		break _ /* ERROR "invalid break label _" */
-		continue _ /* ERROR "invalid continue label _" */
-	}
-}
-
-func f6() {
-_:
-	switch {
-	default:
-		break _ /* ERROR "invalid break label _" */
-	}
-}
diff --git a/src/go/types/testdata/check/main0.go b/src/go/types/testdata/check/main0.go
deleted file mode 100644
index f892938..0000000
--- a/src/go/types/testdata/check/main0.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-func main()
-func /* ERROR "no arguments and no return values" */ main /* ERROR redeclared */ (int)
-func /* ERROR "no arguments and no return values" */ main /* ERROR redeclared */ () int
diff --git a/src/go/types/testdata/check/methodsets.go b/src/go/types/testdata/check/methodsets.go
deleted file mode 100644
index b0eb14c..0000000
--- a/src/go/types/testdata/check/methodsets.go
+++ /dev/null
@@ -1,214 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package methodsets
-
-type T0 struct {}
-
-func (T0) v0() {}
-func (*T0) p0() {}
-
-type T1 struct {} // like T0 with different method names
-
-func (T1) v1() {}
-func (*T1) p1() {}
-
-type T2 interface {
-	v2()
-	p2()
-}
-
-type T3 struct {
-	T0
-	*T1
-	T2
-}
-
-// Method expressions
-func _() {
-	var (
-		_ func(T0) = T0.v0
-		_ = T0.p0 /* ERROR "cannot call pointer method p0 on T0" */
-
-		_ func (*T0) = (*T0).v0
-		_ func (*T0) = (*T0).p0
-
-		// T1 is like T0
-
-		_ func(T2) = T2.v2
-		_ func(T2) = T2.p2
-
-		_ func(T3) = T3.v0
-		_ func(T3) = T3.p0 /* ERROR "cannot call pointer method p0 on T3" */
-		_ func(T3) = T3.v1
-		_ func(T3) = T3.p1
-		_ func(T3) = T3.v2
-		_ func(T3) = T3.p2
-
-		_ func(*T3) = (*T3).v0
-		_ func(*T3) = (*T3).p0
-		_ func(*T3) = (*T3).v1
-		_ func(*T3) = (*T3).p1
-		_ func(*T3) = (*T3).v2
-		_ func(*T3) = (*T3).p2
-	)
-}
-
-// Method values with addressable receivers
-func _() {
-	var (
-		v0 T0
-		_ func() = v0.v0
-		_ func() = v0.p0
-	)
-
-	var (
-		p0 *T0
-		_ func() = p0.v0
-		_ func() = p0.p0
-	)
-
-	// T1 is like T0
-
-	var (
-		v2 T2
-		_ func() = v2.v2
-		_ func() = v2.p2
-	)
-
-	var (
-		v4 T3
-		_ func() = v4.v0
-		_ func() = v4.p0
-		_ func() = v4.v1
-		_ func() = v4.p1
-		_ func() = v4.v2
-		_ func() = v4.p2
-	)
-
-	var (
-		p4 *T3
-		_ func() = p4.v0
-		_ func() = p4.p0
-		_ func() = p4.v1
-		_ func() = p4.p1
-		_ func() = p4.v2
-		_ func() = p4.p2
-	)
-}
-
-// Method calls with addressable receivers
-func _() {
-	var v0 T0
-	v0.v0()
-	v0.p0()
-
-	var p0 *T0
-	p0.v0()
-	p0.p0()
-
-	// T1 is like T0
-
-	var v2 T2
-	v2.v2()
-	v2.p2()
-
-	var v4 T3
-	v4.v0()
-	v4.p0()
-	v4.v1()
-	v4.p1()
-	v4.v2()
-	v4.p2()
-
-	var p4 *T3
-	p4.v0()
-	p4.p0()
-	p4.v1()
-	p4.p1()
-	p4.v2()
-	p4.p2()
-}
-
-// Method values with value receivers
-func _() {
-	var (
-		_ func() = T0{}.v0
-		_ func() = T0{}.p0 /* ERROR "cannot call pointer method p0 on T0" */
-
-		_ func() = (&T0{}).v0
-		_ func() = (&T0{}).p0
-
-		// T1 is like T0
-
-		// no values for T2
-
-		_ func() = T3{}.v0
-		_ func() = T3{}.p0 /* ERROR "cannot call pointer method p0 on T3" */
-		_ func() = T3{}.v1
-		_ func() = T3{}.p1
-		_ func() = T3{}.v2
-		_ func() = T3{}.p2
-
-		_ func() = (&T3{}).v0
-		_ func() = (&T3{}).p0
-		_ func() = (&T3{}).v1
-		_ func() = (&T3{}).p1
-		_ func() = (&T3{}).v2
-		_ func() = (&T3{}).p2
-	)
-}
-
-// Method calls with value receivers
-func _() {
-	T0{}.v0()
-	T0{}.p0 /* ERROR "cannot call pointer method p0 on T0" */ ()
-
-	(&T0{}).v0()
-	(&T0{}).p0()
-
-	// T1 is like T0
-
-	// no values for T2
-
-	T3{}.v0()
-	T3{}.p0 /* ERROR "cannot call pointer method p0 on T3" */ ()
-	T3{}.v1()
-	T3{}.p1()
-	T3{}.v2()
-	T3{}.p2()
-
-	(&T3{}).v0()
-	(&T3{}).p0()
-	(&T3{}).v1()
-	(&T3{}).p1()
-	(&T3{}).v2()
-	(&T3{}).p2()
-}
-
-// *T has no methods if T is an interface type
-func issue5918() {
-	var (
-		err error
-		_ = err.Error()
-		_ func() string = err.Error
-		_ func(error) string = error.Error
-
-		perr = &err
-		_ = perr.Error /* ERROR "type \*error is pointer to interface, not interface" */ ()
-		_ func() string = perr.Error /* ERROR "type \*error is pointer to interface, not interface" */
-		_ func(*error) string = (*error).Error /* ERROR "type \*error is pointer to interface, not interface" */
-	)
-
-	type T *interface{ m() int }
-	var (
-		x T
-		_ = (*x).m()
-		_ = (*x).m
-
-		_ = x.m /* ERROR "type T is pointer to interface, not interface" */ ()
-		_ = x.m /* ERROR "type T is pointer to interface, not interface" */
-		_ = T.m /* ERROR "type T is pointer to interface, not interface" */
-	)
-}
diff --git a/src/go/types/testdata/check/shifts.go b/src/go/types/testdata/check/shifts.go
deleted file mode 100644
index 16a67ae..0000000
--- a/src/go/types/testdata/check/shifts.go
+++ /dev/null
@@ -1,397 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package shifts
-
-func shifts0() {
-	// basic constant shifts
-	const (
-		s = 10
-		_ = 0<<0
-		_ = 1<<s
-		_ = 1<<- /* ERROR "negative shift count" */ 1
-		// For the test below we may decide to convert to int
-		// rather than uint and then report a negative shift
-		// count instead, which might be a better error. The
-		// (minor) difference is that this would restrict the
-		// shift count range by half (from all uint values to
-		// the positive int values).
-		// This depends on the exact spec wording which is not
-		// done yet.
-		// TODO(gri) revisit and adjust when spec change is done
-		_ = 1<<- /* ERROR "negative shift count" */ 1.0
-		_ = 1<<1075 /* ERROR "invalid shift" */
-		_ = 2.0<<1
-		_ = 1<<1.0
-		_ = 1<<(1+0i)
-
-		_ int = 2<<s
-		_ float32 = 2<<s
-		_ complex64 = 2<<s
-
-		_ int = 2.0<<s
-		_ float32 = 2.0<<s
-		_ complex64 = 2.0<<s
-
-		_ int = 'a'<<s
-		_ float32 = 'a'<<s
-		_ complex64 = 'a'<<s
-	)
-}
-
-func shifts1() {
-	// basic non-constant shifts
-	var (
-		i int
-		u uint
-
-		_ = 1<<0
-		_ = 1<<i
-		_ = 1<<u
-		_ = 1<<"foo" /* ERROR "cannot convert" */
-		_ = i<<0
-		_ = i<<- /* ERROR "negative shift count" */ 1
-		_ = i<<1.0
-		_ = 1<<(1+0i)
-		_ = 1 /* ERROR "overflows" */ <<100
-
-		_ uint = 1 << 0
-		_ uint = 1 << u
-		_ float32 = 1 /* ERROR "must be integer" */ << u
-
-		// issue #14822
-		_ = 1<<( /* ERROR "overflows uint" */ 1<<64)
-		_ = 1<<( /* ERROR "invalid shift count" */ 1<<64-1)
-
-		// issue #43697
-		_ = u<<( /* ERROR "overflows uint" */ 1<<64)
-		_ = u<<(1<<64-1)
-	)
-}
-
-func shifts2() {
-	// from the spec
-	var (
-		s uint = 33
-		i = 1<<s           // 1 has type int
-		j int32 = 1<<s     // 1 has type int32; j == 0
-		k = uint64(1<<s)   // 1 has type uint64; k == 1<<33
-		m int = 1.0<<s     // 1.0 has type int
-		n = 1.0<<s != i    // 1.0 has type int; n == false if ints are 32bits in size
-		o = 1<<s == 2<<s   // 1 and 2 have type int; o == true if ints are 32bits in size
-		p = 1<<s == 1<<33  // illegal if ints are 32bits in size: 1 has type int, but 1<<33 overflows int
-		u = 1.0 /* ERROR "must be integer" */ <<s         // illegal: 1.0 has type float64, cannot shift
-		u1 = 1.0 /* ERROR "must be integer" */ <<s != 0   // illegal: 1.0 has type float64, cannot shift
-		u2 = 1 /* ERROR "must be integer" */ <<s != 1.0   // illegal: 1 has type float64, cannot shift
-		v float32 = 1 /* ERROR "must be integer" */ <<s   // illegal: 1 has type float32, cannot shift
-		w int64 = 1.0<<33  // 1.0<<33 is a constant shift expression
-	)
-	_, _, _, _, _, _, _, _, _, _, _, _ = i, j, k, m, n, o, p, u, u1, u2, v, w
-}
-
-func shifts3(a int16, b float32) {
-	// random tests
-	var (
-		s uint = 11
-		u = 1 /* ERROR "must be integer" */ <<s + 1.0
-		v complex128 = 1 /* ERROR "must be integer" */ << s + 1.0 /* ERROR "must be integer" */ << s + 1
-	)
-	x := 1.0 /* ERROR "must be integer" */ <<s + 1
-	shifts3(1.0 << s, 1 /* ERROR "must be integer" */ >> s)
-	_, _, _ = u, v, x
-}
-
-func shifts4() {
-	// shifts in comparisons w/ untyped operands
-	var s uint
-
-	_ = 1<<s == 1
-	_ = 1 /* ERROR "integer" */ <<s == 1.
-	_ = 1. /* ERROR "integer" */ <<s == 1
-	_ = 1. /* ERROR "integer" */ <<s == 1.
-
-	_ = 1<<s + 1 == 1
-	_ = 1 /* ERROR "integer" */ <<s + 1 == 1.
-	_ = 1 /* ERROR "integer" */ <<s + 1. == 1
-	_ = 1 /* ERROR "integer" */ <<s + 1. == 1.
-	_ = 1. /* ERROR "integer" */ <<s + 1 == 1
-	_ = 1. /* ERROR "integer" */ <<s + 1 == 1.
-	_ = 1. /* ERROR "integer" */ <<s + 1. == 1
-	_ = 1. /* ERROR "integer" */ <<s + 1. == 1.
-
-	_ = 1<<s == 1<<s
-	_ = 1 /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s
-	_ = 1. /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s
-	_ = 1. /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s
-
-	_ = 1<<s + 1<<s == 1
-	_ = 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1.
-	_ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1
-	_ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1.
-	_ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1
-	_ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1.
-	_ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1
-	_ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1.
-
-	_ = 1<<s + 1<<s == 1<<s + 1<<s
-	_ = 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
-	_ = 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
-	_ = 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
-	_ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
-	_ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
-	_ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
-	_ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
-	_ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
-	_ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
-	_ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
-	_ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
-	_ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
-	_ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
-	_ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
-	_ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
-}
-
-func shifts5() {
-	// shifts in comparisons w/ typed operands
-	var s uint
-	var x int
-
-	_ = 1<<s == x
-	_ = 1.<<s == x
-	_ = 1.1 /* ERROR "int" */ <<s == x
-
-	_ = 1<<s + x == 1
-	_ = 1<<s + x == 1.
-	_ = 1<<s + x == 1.1 /* ERROR "int" */
-	_ = 1.<<s + x == 1
-	_ = 1.<<s + x == 1.
-	_ = 1.<<s + x == 1.1 /* ERROR "int" */
-	_ = 1.1 /* ERROR "int" */ <<s + x == 1
-	_ = 1.1 /* ERROR "int" */ <<s + x == 1.
-	_ = 1.1 /* ERROR "int" */ <<s + x == 1.1
-
-	_ = 1<<s == x<<s
-	_ = 1.<<s == x<<s
-	_ = 1.1  /* ERROR "int" */ <<s == x<<s
-}
-
-func shifts6() {
-	// shifts as operands in non-arithmetic operations and as arguments
-	var a [10]int
-	var s uint
-
-	_ = a[1<<s]
-	_ = a[1.0]
-	_ = a[1.0<<s]
-
-	_ = make([]int, 1.0)
-	_ = make([]int, 1.0<<s)
-	_ = make([]int, 1.1 /* ERROR "must be integer" */ <<s)
-
-	_ = float32(1)
-	_ = float32(1 /* ERROR "must be integer" */ <<s)
-	_ = float32(1.0)
-	_ = float32(1.0 /* ERROR "must be integer" */ <<s)
-	_ = float32(1.1 /* ERROR "must be integer" */ <<s)
-
-	_ = int32(0x80000000 /* ERROR "overflows int32" */ << s)
-	// TODO(rfindley) Eliminate the redundant error here.
-	_ = int32(( /* ERROR "truncated to int32" */ 0x80000000 /* ERROR "truncated to int32" */ + 0i) << s)
-
-	_ = int(1+0i<<0)
-	_ = int((1+0i)<<s)
-	_ = int(1.0<<s)
-	_ = int(complex(1, 0)<<s)
-	_ = int(float32/* ERROR "must be integer" */(1.0) <<s)
-	_ = int(1.1 /* ERROR must be integer */ <<s)
-	_ = int(( /* ERROR "must be integer" */ 1+1i)  <<s)
-
-	_ = complex(1 /* ERROR "must be integer" */ <<s, 0)
-
-	var b []int
-	_ = append(b, 1<<s)
-	_ = append(b, 1.0<<s)
-	_ = append(b, (1+0i)<<s)
-	_ = append(b, 1.1 /* ERROR "must be integer" */ <<s)
-	_ = append(b, (1 + 0i) <<s)
-	_ = append(b, ( /* ERROR "must be integer" */ 1 + 1i)  <<s)
-
-	_ = complex(1.0 /* ERROR "must be integer" */ <<s, 0)
-	_ = complex(1.1 /* ERROR "must be integer" */ <<s, 0)
-	_ = complex(0, 1.0 /* ERROR "must be integer" */ <<s)
-	_ = complex(0, 1.1 /* ERROR "must be integer" */ <<s)
-
-	// TODO(gri) The delete below is not type-checked correctly yet.
-	// var m1 map[int]string
-	// delete(m1, 1<<s)
-}
-
-func shifts7() {
-	// shifts of shifts
-	var s uint
-	var x int
-	_ = x
-
-	_ = 1<<(1<<s)
-	_ = 1<<(1.<<s)
-	_ = 1. /* ERROR "integer" */ <<(1<<s)
-	_ = 1. /* ERROR "integer" */ <<(1.<<s)
-
-	x = 1<<(1<<s)
-	x = 1<<(1.<<s)
-	x = 1.<<(1<<s)
-	x = 1.<<(1.<<s)
-
-	_ = (1<<s)<<(1<<s)
-	_ = (1<<s)<<(1.<<s)
-	_ = ( /* ERROR "integer" */ 1.<<s)<<(1<<s)
-	_ = ( /* ERROR "integer" */ 1.<<s)<<(1.<<s)
-
-	x = (1<<s)<<(1<<s)
-	x = (1<<s)<<(1.<<s)
-	x = ( /* ERROR "integer" */ 1.<<s)<<(1<<s)
-	x = ( /* ERROR "integer" */ 1.<<s)<<(1.<<s)
-}
-
-func shifts8() {
-	// shift examples from shift discussion: better error messages
-	var s uint
-	_ = 1.0 /* ERROR "shifted operand 1.0 \(type float64\) must be integer" */ <<s == 1
-	_ = 1.0 /* ERROR "shifted operand 1.0 \(type float64\) must be integer" */ <<s == 1.0
-	_ = 1 /* ERROR "shifted operand 1 \(type float64\) must be integer" */ <<s == 1.0
-	_ = 1 /* ERROR "shifted operand 1 \(type float64\) must be integer" */ <<s + 1.0 == 1
-	_ = 1 /* ERROR "shifted operand 1 \(type float64\) must be integer" */ <<s + 1.1 == 1
-	_ = 1 /* ERROR "shifted operand 1 \(type float64\) must be integer" */ <<s + 1 == 1.0
-
-	// additional cases
-	_ = complex(1.0 /* ERROR "shifted operand 1.0 \(type float64\) must be integer" */ <<s, 1)
-	_ = complex(1.0, 1 /* ERROR "shifted operand 1 \(type float64\) must be integer" */ <<s)
-
-	_ = int(1.<<s)
-	_ = int(1.1 /* ERROR "shifted operand .* must be integer" */ <<s)
-	_ = float32(1 /* ERROR "shifted operand .* must be integer" */ <<s)
-	_ = float32(1. /* ERROR "shifted operand .* must be integer" */ <<s)
-	_ = float32(1.1 /* ERROR "shifted operand .* must be integer" */ <<s)
-	// TODO(gri) the error messages for these two are incorrect - disabled for now
-	// _ = complex64(1<<s)
-	// _ = complex64(1.<<s)
-	_ = complex64(1.1 /* ERROR "shifted operand .* must be integer" */ <<s)
-}
-
-func shifts9() {
-	// various originally failing snippets of code from the std library
-	// from src/compress/lzw/reader.go:90
-	{
-		var d struct {
-			bits     uint32
-			width    uint
-		}
-		_ = uint16(d.bits & (1<<d.width - 1))
-	}
-
-	// from src/debug/dwarf/buf.go:116
-	{
-		var ux uint64
-		var bits uint
-		x := int64(ux)
-		if x&(1<<(bits-1)) != 0 {}
-	}
-
-	// from src/encoding/asn1/asn1.go:160
-	{
-		var bytes []byte
-		if bytes[len(bytes)-1]&((1<<bytes[0])-1) != 0 {}
-	}
-
-	// from src/math/big/rat.go:140
-	{
-		var exp int
-		var mantissa uint64
-		shift := uint64(-1022 - (exp - 1)) // [1..53)
-		_ = mantissa & (1<<shift - 1)
-	}
-
-	// from src/net/interface.go:51
-	{
-		type Flags uint
-		var f Flags
-		var i int
-		if f&(1<<uint(i)) != 0 {}
-	}
-
-	// from src/runtime/softfloat64.go:234
-	{
-		var gm uint64
-		var shift uint
-		_ = gm & (1<<shift - 1)
-	}
-
-	// from src/strconv/atof.go:326
-	{
-		var mant uint64
-		var mantbits uint
-		if mant == 2<<mantbits {}
-	}
-
-	// from src/route_bsd.go:82
-	{
-		var Addrs int32
-		const rtaRtMask = 1
-		var i uint
-		if Addrs&rtaRtMask&(1<<i) == 0 {}
-	}
-
-	// from src/text/scanner/scanner.go:540
-	{
-		var s struct { Whitespace uint64 }
-		var ch rune
-		for s.Whitespace&(1<<uint(ch)) != 0 {}
-	}
-}
-
-func issue5895() {
-	var x = 'a' << 1 // type of x must be rune
-	var _ rune = x
-}
-
-func issue11325() {
-	var _ = 0 >> 1.1 /* ERROR "truncated to uint" */ // example from issue 11325
-	_ = 0 >> 1.1 /* ERROR "truncated to uint" */
-	_ = 0 << 1.1 /* ERROR "truncated to uint" */
-	_ = 0 >> 1.
-	_ = 1 >> 1.1 /* ERROR "truncated to uint" */
-	_ = 1 >> 1.
-	_ = 1. >> 1
-	_ = 1. >> 1.
-	_ = 1.1 /* ERROR "must be integer" */ >> 1
-}
-
-func issue11594() {
-	var _ = complex64 /* ERROR "must be integer" */ (1) << 2 // example from issue 11594
-	_ = float32 /* ERROR "must be integer" */ (0) << 1
-	_ = float64 /* ERROR "must be integer" */ (0) >> 2
-	_ = complex64 /* ERROR "must be integer" */ (0) << 3
-	_ = complex64 /* ERROR "must be integer" */ (0) >> 4
-}
-
-func issue21727() {
-	var s uint
-	var a = make([]int, 1<<s + 1.2 /* ERROR "truncated to int" */ )
-	var _ = a[1<<s - 2.3 /* ERROR "truncated to int" */ ]
-	var _ int = 1<<s + 3.4 /* ERROR "truncated to int" */
-	var _ = string(1 /* ERROR shifted operand 1 .* must be integer */ << s)
-	var _ = string(1.0 /* ERROR "cannot convert" */ << s)
-}
-
-func issue22969() {
-	var s uint
-	var a []byte
-	_ = a[0xffffffffffffffff /* ERROR "overflows int" */ <<s] // example from issue 22969
-	_ = make([]int, 0xffffffffffffffff /* ERROR "overflows int" */ << s)
-	_ = make([]int, 0, 0xffffffffffffffff /* ERROR "overflows int" */ << s)
-	var _ byte = 0x100 /* ERROR "overflows byte" */ << s
-	var _ int8 = 0xff /* ERROR "overflows int8" */ << s
-	var _ int16 = 0xffff /* ERROR "overflows int16" */ << s
-	var _ int32 = 0x80000000 /* ERROR "overflows int32" */ << s
-}
diff --git a/src/go/types/testdata/check/stmt0.go b/src/go/types/testdata/check/stmt0.go
deleted file mode 100644
index 0f164d3..0000000
--- a/src/go/types/testdata/check/stmt0.go
+++ /dev/null
@@ -1,992 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// statements
-
-package stmt0
-
-func assignments0() (int, int) {
-	var a, b, c int
-	var ch chan int
-	f0 := func() {}
-	f1 := func() int { return 1 }
-	f2 := func() (int, int) { return 1, 2 }
-	f3 := func() (int, int, int) { return 1, 2, 3 }
-
-	a, b, c = 1, 2, 3
-	a, b, c = 1 /* ERROR "cannot assign [1-9]+ values to [1-9]+ variables" */ , 2
-	a, b, c = 1 /* ERROR "cannot assign [1-9]+ values to [1-9]+ variables" */ , 2, 3, 4
-	_, _, _ = a, b, c
-
-	a = f0 /* ERROR "used as value" */ ()
-	a = f1()
-	a = f2 /* ERROR "cannot assign [1-9]+ values to [1-9]+ variables" */ ()
-	a, b = f2()
-	a, b, c = f2 /* ERROR "cannot assign [1-9]+ values to [1-9]+ variables" */ ()
-	a, b, c = f3()
-	a, b = f3 /* ERROR "cannot assign [1-9]+ values to [1-9]+ variables" */ ()
-
-	a, b, c = <- /* ERROR "cannot assign [1-9]+ values to [1-9]+ variables" */ ch
-
-	return /* ERROR "not enough return values\n\thave \(\)\n\twant \(int, int\)" */
-	return 1 /* ERROR "not enough return values\n\thave \(number\)\n\twant \(int, int\)" */
-	return 1, 2
-	return 1, 2, 3 /* ERROR "too many return values\n\thave \(number, number, number\)\n\twant \(int, int\)" */
-}
-
-func assignments1() {
-	b, i, f, c, s := false, 1, 1.0, 1i, "foo"
-	b = i /* ERROR "cannot use .* in assignment" */
-	i = f /* ERROR "cannot use .* in assignment" */
-	f = c /* ERROR "cannot use .* in assignment" */
-	c = s /* ERROR "cannot use .* in assignment" */
-	s = b /* ERROR "cannot use .* in assignment" */
-
-	v0, v1, v2 := 1 /* ERROR "cannot initialize" */ , 2, 3, 4
-	_, _, _ = v0, v1, v2
-
-	b = true
-
-	i += 1
-	i /* ERROR "mismatched types int and untyped string" */+= "foo"
-
-	f -= 1
-	f /= 0
-	f = float32(0)/0 /* ERROR "division by zero" */
-	f /* ERROR "mismatched types float64 and untyped string" */-= "foo"
-
-	c *= 1
-	c /= 0
-
-	s += "bar"
-	s /* ERROR "mismatched types string and untyped int" */+= 1
-
-	var u64 uint64
-	u64 += 1<<u64
-
-	undeclared /* ERROR "undeclared" */ = 991
-
-	// test cases for issue 5800
-	var (
-		_ int = nil /* ERROR "cannot use nil as int value in variable declaration" */
-		_ [10]int = nil /* ERROR "cannot use nil as \[10\]int value in variable declaration" */
-		_ []byte = nil
-		_ struct{} = nil /* ERROR "cannot use nil as struct{} value in variable declaration" */
-		_ func() = nil
-		_ map[int]string = nil
-		_ chan int = nil
-	)
-
-	// test cases for issue 5500
-	_ = func() (int, bool) {
-		var m map[int]int
-		return m /* ERROR "not enough return values" */ [0]
-	}
-
-	g := func(int, bool){}
-	var m map[int]int
-	g(m[0]) /* ERROR "not enough arguments" */
-
-	// assignments to _
-	_ = nil /* ERROR "use of untyped nil" */
-	_ = 1  << /* ERROR constant shift overflow */ 1000
-	(_) = 0
-}
-
-func assignments2() {
-	type mybool bool
-	var m map[string][]bool
-	var s []bool
-	var b bool
-	var d mybool
-	_ = s
-	_ = b
-	_ = d
-
-	// assignments to map index expressions are ok
-	s, b = m["foo"]
-	_, d = m["bar"]
-	m["foo"] = nil
-	m["foo"] = nil /* ERROR cannot assign [1-9]+ values to [1-9]+ variables */ , false
-	_ = append(m["foo"])
-	_ = append(m["foo"], true)
-
-	var c chan int
-	_, b = <-c
-	_, d = <-c
-	<- /* ERROR cannot assign */ c = 0
-	<-c = 0 /* ERROR cannot assign [1-9]+ values to [1-9]+ variables */ , false
-
-	var x interface{}
-	_, b = x.(int)
-	x /* ERROR cannot assign */ .(int) = 0
-	x.(int) = 0 /* ERROR cannot assign [1-9]+ values to [1-9]+ variables */ , false
-
-	assignments2 /* ERROR used as value */ () = nil
-	int /* ERROR not an expression */ = 0
-}
-
-func issue6487() {
-	type S struct{x int}
-	_ = &S /* ERROR "cannot take address" */ {}.x
-	_ = &( /* ERROR "cannot take address" */ S{}.x)
-	_ = (&S{}).x
-	S /* ERROR "cannot assign" */ {}.x = 0
-	(&S{}).x = 0
-
-	type M map[string]S
-	var m M
-	m /* ERROR "cannot assign to struct field" */ ["foo"].x = 0
-	_ = &( /* ERROR "cannot take address" */ m["foo"].x)
-	_ = &m /* ERROR "cannot take address" */ ["foo"].x
-}
-
-func issue6766a() {
-	a, a /* ERROR a repeated on left side of := */ := 1, 2
-	_ = a
-	a, b, b /* ERROR b repeated on left side of := */ := 1, 2, 3
-	_ = b
-	c, c /* ERROR c repeated on left side of := */, b := 1, 2, 3
-	_ = c
-	a, b := /* ERROR no new variables */ 1, 2
-}
-
-func shortVarDecls1() {
-	const c = 0
-	type d int
-	a, b, c /* ERROR "cannot assign" */ , d /* ERROR "cannot assign" */  := 1, "zwei", 3.0, 4
-	var _ int = a // a is of type int
-	var _ string = b // b is of type string
-}
-
-func incdecs() {
-	const c = 3.14
-	c /* ERROR "cannot assign" */ ++
-	s := "foo"
-	s /* ERROR "invalid operation" */ --
-	3.14 /* ERROR "cannot assign" */ ++
-	var (
-		x int
-		y float32
-		z complex128
-	)
-	x++
-	y--
-	z++
-}
-
-func sends() {
-	var ch chan int
-	var rch <-chan int
-	var x int
-	x <- /* ERROR "cannot send" */ x
-	rch <- /* ERROR "cannot send" */ x
-	ch <- "foo" /* ERROR "cannot use .* in send" */
-	ch <- x
-}
-
-func selects() {
-	select {}
-	var (
-		ch chan int
-		sc chan <- bool
-	)
-	select {
-	case <-ch:
-	case (<-ch):
-	case t := <-ch:
-		_ = t
-	case t := (<-ch):
-		_ = t
-	case t, ok := <-ch:
-		_, _ = t, ok
-	case t, ok := (<-ch):
-		_, _ = t, ok
-	case <-sc /* ERROR "cannot receive from send-only channel" */ :
-	}
-	select {
-	default:
-	default /* ERROR "multiple defaults" */ :
-	}
-	select {
-	case a, b := <-ch:
-		_, b = a, b
-	case x /* ERROR send or receive */ :
-	case a /* ERROR send or receive */ := ch:
-	}
-
-	// test for issue 9570: ch2 in second case falsely resolved to
-	// ch2 declared in body of first case
-	ch1 := make(chan int)
-	ch2 := make(chan int)
-	select {
-	case <-ch1:
-		var ch2 /* ERROR ch2 declared but not used */ chan bool
-	case i := <-ch2:
-		print(i + 1)
-	}
-}
-
-func gos() {
-	go 1 /* ERROR HERE "function must be invoked" */
-	go int /* ERROR "go requires function call, not conversion" */ (0)
-	go gos()
-	var c chan int
-	go close(c)
-	go len /* ERROR "go discards result" */ (c)
-}
-
-func defers() {
-	defer 1 /* ERROR HERE "function must be invoked" */
-	defer int /* ERROR "defer requires function call, not conversion" */ (0)
-	defer defers()
-	var c chan int
-	defer close(c)
-	defer len /* ERROR "defer discards result" */ (c)
-}
-
-func breaks() {
-	var x, y int
-
-	break /* ERROR "break" */
-	{
-		break /* ERROR "break" */
-	}
-	if x < y {
-		break /* ERROR "break" */
-	}
-
-	switch x {
-	case 0:
-		break
-	case 1:
-		if x == y {
-			break
-		}
-	default:
-		break
-		break
-	}
-
-	var z interface{}
-	switch z.(type) {
-	case int:
-		break
-	}
-
-	for {
-		break
-	}
-
-	var a []int
-	for _ = range a {
-		break
-	}
-
-	for {
-		if x == y {
-			break
-		}
-	}
-
-	var ch chan int
-	select {
-	case <-ch:
-		break
-	}
-
-	select {
-	case <-ch:
-		if x == y {
-			break
-		}
-	default:
-		break
-	}
-}
-
-func continues() {
-	var x, y int
-
-	continue /* ERROR "continue" */
-	{
-		continue /* ERROR "continue" */
-	}
-
-	if x < y {
-		continue /* ERROR "continue" */
-	}
-
-	switch x {
-	case 0:
-		continue /* ERROR "continue" */
-	}
-
-	var z interface{}
-	switch z.(type) {
-	case int:
-		continue /* ERROR "continue" */
-	}
-
-	var ch chan int
-	select {
-	case <-ch:
-		continue /* ERROR "continue" */
-	}
-
-	for i := 0; i < 10; i++ {
-		continue
-		if x < y {
-			continue
-			break
-		}
-		switch x {
-		case y:
-			continue
-		default:
-			break
-		}
-		select {
-		case <-ch:
-			continue
-		}
-	}
-
-	var a []int
-	for _ = range a {
-		continue
-		if x < y {
-			continue
-			break
-		}
-		switch x {
-		case y:
-			continue
-		default:
-			break
-		}
-		select {
-		case <-ch:
-			continue
-		}
-	}
-}
-
-func returns0() {
-	return
-	return 0 /* ERROR too many return values */
-}
-
-func returns1(x float64) (int, *float64) {
-	return 0, &x
-	return /* ERROR not enough return values */
-	return "foo" /* ERROR "cannot .* in return statement" */, x /* ERROR "cannot use .* in return statement" */
-	return 0, &x, 1 /* ERROR too many return values */
-}
-
-func returns2() (a, b int) {
-	return
-	return 1, "foo" /* ERROR cannot use .* in return statement */
-	return 1, 2, 3 /* ERROR too many return values */
-	{
-		type a int
-		return 1, 2
-		return /* ERROR a not in scope at return */
-	}
-}
-
-func returns3() (_ int) {
-	return
-	{
-		var _ int // blank (_) identifiers never shadow since they are in no scope
-		return
-	}
-}
-
-func switches0() {
-	var x int
-
-	switch x {
-	}
-
-	switch x {
-	default:
-	default /* ERROR "multiple defaults" */ :
-	}
-
-	switch {
-	case 1  /* ERROR "cannot convert" */ :
-	}
-
-	true := "false"
-	_ = true
-	// A tagless switch is equivalent to the bool
-        // constant true, not the identifier 'true'.
-	switch {
-	case "false" /* ERROR "cannot convert" */:
-	}
-
-	switch int32(x) {
-	case 1, 2:
-	case x /* ERROR "invalid case x in switch on int32\(x\) \(mismatched types int and int32\)" */ :
-	}
-
-	switch x {
-	case 1 /* ERROR "overflows" */ << 100:
-	}
-
-	switch x {
-	case 1:
-	case 1 /* ERROR "duplicate case" */ :
-	case ( /* ERROR "duplicate case" */ 1):
-	case 2, 3, 4:
-	case 5, 1 /* ERROR "duplicate case" */ :
-	}
-
-	switch uint64(x) {
-	case 1<<64 - 1:
-	case 1 /* ERROR duplicate case */ <<64 - 1:
-	case 2, 3, 4:
-	case 5, 1 /* ERROR duplicate case */ <<64 - 1:
-	}
-
-	var y32 float32
-	switch y32 {
-	case 1.1:
-	case 11/10: // integer division!
-	case 11. /* ERROR duplicate case */ /10:
-	case 2, 3.0, 4.1:
-	case 5.2, 1.10 /* ERROR duplicate case */ :
-	}
-
-	var y64 float64
-	switch y64 {
-	case 1.1:
-	case 11/10: // integer division!
-	case 11. /* ERROR duplicate case */ /10:
-	case 2, 3.0, 4.1:
-	case 5.2, 1.10 /* ERROR duplicate case */ :
-	}
-
-	var s string
-	switch s {
-	case "foo":
-	case "foo" /* ERROR duplicate case */ :
-	case "f" /* ERROR duplicate case */ + "oo":
-	case "abc", "def", "ghi":
-	case "jkl", "foo" /* ERROR duplicate case */ :
-	}
-
-	type T int
-	type F float64
-	type S string
-	type B bool
-	var i interface{}
-	switch i {
-	case nil:
-	case nil: // no duplicate detection
-	case (*int)(nil):
-	case (*int)(nil): // do duplicate detection
-	case 1:
-	case byte(1):
-	case int /* ERROR duplicate case */ (1):
-	case T(1):
-	case 1.0:
-	case F(1.0):
-	case F /* ERROR duplicate case */ (1.0):
-	case "hello":
-	case S("hello"):
-	case S /* ERROR duplicate case */ ("hello"):
-	case 1==1, B(false):
-	case false, B(2==2):
-	}
-
-	// switch on array
-	var a [3]int
-	switch a {
-	case [3]int{1, 2, 3}:
-	case [3]int{1, 2, 3}: // no duplicate detection
-	case [ /* ERROR "mismatched types */ 4]int{4, 5, 6}:
-	}
-
-	// switch on channel
-	var c1, c2 chan int
-	switch c1 {
-	case nil:
-	case c1:
-	case c2:
-	case c1, c2: // no duplicate detection
-	}
-}
-
-func switches1() {
-	fallthrough /* ERROR "fallthrough statement out of place" */
-
-	var x int
-	switch x {
-	case 0:
-		fallthrough /* ERROR "fallthrough statement out of place" */
-		break
-	case 1:
-		fallthrough
-	case 2:
-		fallthrough; ; ; // trailing empty statements are ok
-	case 3:
-	default:
-		fallthrough; ;
-	case 4:
-		fallthrough /* ERROR "cannot fallthrough final case in switch" */
-	}
-
-	var y interface{}
-	switch y.(type) {
-	case int:
-		fallthrough /* ERROR "cannot fallthrough in type switch" */ ; ; ;
-	default:
-	}
-
-	switch x {
-	case 0:
-		if x == 0 {
-			fallthrough /* ERROR "fallthrough statement out of place" */
-		}
-	}
-
-	switch x {
-	case 0:
-		goto L1
-		L1: fallthrough; ;
-	case 1:
-		goto L2
-		goto L3
-		goto L4
-		L2: L3: L4: fallthrough
-	default:
-	}
-
-	switch x {
-	case 0:
-		goto L5
-		L5: fallthrough
-	default:
-		goto L6
-		goto L7
-		goto L8
-		L6: L7: L8: fallthrough /* ERROR "cannot fallthrough final case in switch" */
-	}
-
-	switch x {
-	case 0:
-		fallthrough; ;
-	case 1:
-		{
-			fallthrough /* ERROR "fallthrough statement out of place" */
-		}
-	case 2:
-		fallthrough
-	case 3:
-		fallthrough /* ERROR "fallthrough statement out of place" */
-		{ /* empty block is not an empty statement */ }; ;
-	default:
-		fallthrough /* ERROR "cannot fallthrough final case in switch" */
-	}
-
-	switch x {
-	case 0:
-		{
-			fallthrough /* ERROR "fallthrough statement out of place" */
-		}
-	}
-}
-
-func switches2() {
-	// untyped nil is not permitted as switch expression
-	switch nil /* ERROR "use of untyped nil" */ {
-	case 1, 2, "foo": // don't report additional errors here
-	}
-
-	// untyped constants are converted to default types
-	switch 1<<63-1 {
-	}
-	switch 1 /* ERROR "cannot use .* as int value.*\(overflows\)" */ << 63 {
-	}
-	var x int
-	switch 1.0 {
-	case 1.0, 2.0, x /* ERROR "mismatched types int and float64" */ :
-	}
-	switch x {
-	case 1.0:
-	}
-
-	// untyped bools become of type bool
-	type B bool
-	var b B = true
-	switch x == x {
-	case b /* ERROR "mismatched types B and bool" */ :
-	}
-	switch {
-	case b /* ERROR "mismatched types B and bool" */ :
-	}
-}
-
-func issue11667() {
-	switch 9223372036854775808 /* ERROR "cannot use .* as int value.*\(overflows\)" */ {
-	}
-	switch 9223372036854775808 /* ERROR "cannot use .* as int value.*\(overflows\)" */ {
-	case 9223372036854775808:
-	}
-	var x int
-	switch x {
-	case 9223372036854775808 /* ERROR "overflows int" */ :
-	}
-	var y float64
-	switch y {
-	case 9223372036854775808:
-	}
-}
-
-func issue11687() {
-	f := func() (_, _ int) { return }
-	switch f /* ERROR "2-valued f" */ () {
-	}
-	var x int
-	switch f /* ERROR "2-valued f" */ () {
-	case x:
-	}
-	switch x {
-	case f /* ERROR "2-valued f" */ ():
-	}
-}
-
-type I interface {
-	m()
-}
-
-type I2 interface {
-	m(int)
-}
-
-type T struct{}
-type T1 struct{}
-type T2 struct{}
-
-func (T) m() {}
-func (T2) m(int) {}
-
-func typeswitches() {
-	var i int
-	var x interface{}
-
-	switch x.(type) {}
-	switch (x /* ERROR "outside type switch" */ .(type)) {}
-
-	switch x.(type) {
-	default:
-	default /* ERROR "multiple defaults" */ :
-	}
-
-	switch x /* ERROR "declared but not used" */ := x.(type) {}
-	switch _ /* ERROR "no new variable on left side of :=" */ := x.(type) {}
-
-	switch x := x.(type) {
-	case int:
-		var y int = x
-		_ = y
-	}
-
-	switch x /* ERROR "x declared but not used" */ := i /* ERROR "not an interface" */ .(type) {}
-
-	switch t := x.(type) {
-	case nil:
-		var v bool = t /* ERROR "cannot use .* in variable declaration" */
-		_ = v
-	case int:
-		var v int = t
-		_ = v
-	case float32, complex64:
-		var v float32 = t /* ERROR "cannot use .* in variable declaration" */
-		_ = v
-	default:
-		var v float32 = t /* ERROR "cannot use .* in variable declaration" */
-		_ = v
-	}
-
-	var t I
-	switch t.(type) {
-	case T:
-	case T1 /* ERROR "missing method m" */ :
-	case T2 /* ERROR "wrong type for method m" */ :
-	case I2 /* STRICT "wrong type for method m" */ : // only an error in strict mode (issue 8561)
-	}
-
-
-	{
-		x := 1
-		v := 2
-		switch v /* ERROR "v [(]variable of type int[)] is not an interface" */ .(type) {
-		case int:
-			println(x)
-			println(x / 0 /* ERROR "invalid operation: division by zero" */)
-		case 1 /* ERROR "expected type, found 1" */:
-		}
-	}
-}
-
-// Test that each case clause uses the correct type of the variable
-// declared by the type switch (issue 5504).
-func typeswitch0() {
-	switch y := interface{}(nil).(type) {
-	case int:
-		func() int { return y + 0 }()
-	case float32:
-		func() float32 { return y }()
-	}
-}
-
-// Test correct scope setup.
-// (no redeclaration errors expected in the type switch)
-func typeswitch1() {
-	var t I
-	switch t := t; t := t.(type) {
-	case nil:
-		var _ I = t
-	case T:
-		var _ T = t
-	default:
-		var _ I = t
-	}
-}
-
-// Test correct typeswitch against interface types.
-type A interface { a() }
-type B interface { b() }
-type C interface { a(int) }
-
-func typeswitch2() {
-	switch A(nil).(type) {
-	case A:
-	case B:
-	case C /* STRICT "cannot have dynamic type" */: // only an error in strict mode (issue 8561)
-	}
-}
-
-func typeswitch3(x interface{}) {
-	switch x.(type) {
-	case int:
-	case float64:
-	case int /* ERROR duplicate case */ :
-	}
-
-	switch x.(type) {
-	case nil:
-	case int:
-	case nil /* ERROR duplicate case */ , nil /* ERROR duplicate case */ :
-	}
-
-	type F func(int)
-	switch x.(type) {
-	case nil:
-	case int, func(int):
-	case float32, func /* ERROR duplicate case */ (x int):
-	case F:
-	}
-}
-
-func fors1() {
-	for {}
-	var i string
-	_ = i
-	for i := 0; i < 10; i++ {}
-	for i := 0; i < 10; j /* ERROR cannot declare */ := 0 {}
-}
-
-func rangeloops1() {
-	var (
-		x int
-		a [10]float32
-		b []string
-		p *[10]complex128
-		pp **[10]complex128
-		s string
-		m map[int]bool
-		c chan int
-		sc chan<- int
-		rc <-chan int
-	)
-
-	for range x /* ERROR "cannot range over" */ {}
-	for _ = range x /* ERROR "cannot range over" */ {}
-	for i := range x /* ERROR "cannot range over" */ {}
-
-	for range a {}
-	for i := range a {
-		var ii int
-		ii = i
-		_ = ii
-	}
-	for i, x := range a {
-		var ii int
-		ii = i
-		_ = ii
-		var xx float64
-		xx = x /* ERROR "cannot use .* in assignment" */
-		_ = xx
-	}
-	var ii int
-	var xx float32
-	for ii, xx = range a {}
-	_, _ = ii, xx
-
-	for range b {}
-	for i := range b {
-		var ii int
-		ii = i
-		_ = ii
-	}
-	for i, x := range b {
-		var ii int
-		ii = i
-		_ = ii
-		var xx string
-		xx = x
-		_ = xx
-	}
-
-	for range s {}
-	for i := range s {
-		var ii int
-		ii = i
-		_ = ii
-	}
-	for i, x := range s {
-		var ii int
-		ii = i
-		_ = ii
-		var xx rune
-		xx = x
-		_ = xx
-	}
-
-	for range p {}
-	for _, x := range p {
-		var xx complex128
-		xx = x
-		_ = xx
-	}
-
-	for range pp /* ERROR "cannot range over" */ {}
-	for _, x := range pp /* ERROR "cannot range over" */ {}
-
-	for range m {}
-	for k := range m {
-		var kk int32
-		kk = k /* ERROR "cannot use .* in assignment" */
-		_ = kk
-	}
-	for k, v := range m {
-		var kk int
-		kk = k
-		_ = kk
-		if v {}
-	}
-
-	for range c {}
-	for _, _ /* ERROR "only one iteration variable" */ = range c {}
-	for e := range c {
-		var ee int
-		ee = e
-		_ = ee
-	}
-	for _ = range sc /* ERROR "cannot range over" */ {}
-	for _ = range rc {}
-
-	// constant strings
-	const cs = "foo"
-	for range cs {}
-	for range "" {}
-	for i, x := range cs { _, _ = i, x }
-	for i, x := range "" {
-		var ii int
-		ii = i
-		_ = ii
-		var xx rune
-		xx = x
-		_ = xx
-	}
-}
-
-func rangeloops2() {
-	type I int
-	type R rune
-
-	var a [10]int
-	var i I
-	_ = i
-	for i /* ERROR cannot use .* in assignment */ = range a {}
-	for i /* ERROR cannot use .* in assignment */ = range &a {}
-	for i /* ERROR cannot use .* in assignment */ = range a[:] {}
-
-	var s string
-	var r R
-	_ = r
-	for i /* ERROR cannot use .* in assignment */ = range s {}
-	for i /* ERROR cannot use .* in assignment */ = range "foo" {}
-	for _, r /* ERROR cannot use .* in assignment */ = range s {}
-	for _, r /* ERROR cannot use .* in assignment */ = range "foo" {}
-}
-
-func issue6766b() {
-	for _ := /* ERROR no new variables */ range "" {}
-	for a, a /* ERROR redeclared */ := range "" { _ = a }
-	var a int
-	_ = a
-	for a, a /* ERROR redeclared */ := range []int{1, 2, 3} { _ = a }
-}
-
-// Test that despite errors in the range clause,
-// the loop body is still type-checked (and thus
-// errors reported).
-func issue10148() {
-	for y /* ERROR declared but not used */ := range "" {
-		_ = "" /* ERROR mismatched types untyped string and untyped int */ + 1
-	}
-	for range 1 /* ERROR cannot range over 1 */ {
-		_ = "" /* ERROR mismatched types untyped string and untyped int */ + 1
-	}
-	for y := range 1 /* ERROR cannot range over 1 */ {
-		_ = "" /* ERROR mismatched types untyped string and untyped int */ + 1
-	}
-}
-
-func labels0() {
-	goto L0
-	goto L1
-	L0:
-	L1:
-	L1 /* ERROR "already declared" */ :
-	if true {
-		goto L2
-		L2:
-		L0 /* ERROR "already declared" */ :
-	}
-	_ = func() {
-		goto L0
-		goto L1
-		goto L2
-		L0:
-		L1:
-		L2:
-	}
-}
-
-func expression_statements(ch chan int) {
-	expression_statements(ch)
-	<-ch
-	println()
-
-	0 /* ERROR "not used" */
-	1 /* ERROR "not used" */ +2
-	cap /* ERROR "not used" */ (ch)
-	println /* ERROR "must be called" */
-}
diff --git a/src/go/types/testdata/check/todos.go b/src/go/types/testdata/check/todos.go
deleted file mode 100644
index 09e9b4c..0000000
--- a/src/go/types/testdata/check/todos.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file is meant as "dumping ground" for tests
-// of not yet implemented features. It will grow and
-// shrink over time.
-
-package p
-
-// When using []'s instead of ()'s for type parameters
-// we don't need extra parentheses for some composite
-// literal types.
-type T1[P any] struct{}
-type T2[P, Q any] struct{}
-
-func _() {
-   _ = []T1[int]{}            // ok if we use []'s
-   _ = [](T1[int]){}
-   _ = []T2[int, string]{}    // ok if we use []'s
-   _ = [](T2[int, string]){}
-}
diff --git a/src/go/types/testdata/check/typeinst0.go b/src/go/types/testdata/check/typeinst0.go
deleted file mode 100644
index 6423cb8..0000000
--- a/src/go/types/testdata/check/typeinst0.go
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type myInt int
-
-// Parameterized type declarations
-
-// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
-type T1[P any] P // ERROR cannot use a type parameter as RHS in type declaration
-
-type T2[P any] struct {
-        f P
-        g int // int should still be in scope chain
-}
-
-type List[P any] []P
-
-// Alias type declarations cannot have type parameters.
-// Issue #46477 proposses to change that.
-type A1[P any] = /* ERROR cannot be alias */ struct{}
-
-// Pending clarification of #46477 we disallow aliases
-// of generic types.
-type A2 = List // ERROR cannot use generic type
-var _ A2[int]
-var _ A2
-
-type A3 = List[int]
-var _ A3
-
-// Parameterized type instantiations
-
-var x int
-type _ x /* ERROR not a type */ [int]
-
-type _ int /* ERROR not a generic type */ [] // ERROR expected type argument list
-type _ myInt /* ERROR not a generic type */ [] // ERROR expected type argument list
-
-// TODO(gri) better error messages
-type _ T1[] // ERROR expected type argument list
-type _ T1[x /* ERROR not a type */ ]
-type _ T1 /* ERROR got 2 arguments but 1 type parameters */ [int, float32]
-
-var _ T2[int] = T2[int]{}
-
-var _ List[int] = []int{1, 2, 3}
-var _ List[[]int] = [][]int{{1, 2, 3}}
-var _ List[List[List[int]]]
-
-// Parameterized types containing parameterized types
-
-type T3[P any] List[P]
-
-var _ T3[int] = T3[int](List[int]{1, 2, 3})
-
-// Self-recursive generic types are not permitted
-
-type self1[P any] self1 /* ERROR illegal cycle */ [P]
-type self2[P any] *self2[P] // this is ok
diff --git a/src/go/types/testdata/check/typeinst1.go b/src/go/types/testdata/check/typeinst1.go
deleted file mode 100644
index e7b4539..0000000
--- a/src/go/types/testdata/check/typeinst1.go
+++ /dev/null
@@ -1,282 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type List[E any] []E
-var _ List[List[List[int]]]
-var _ List[List[List[int]]] = []List[List[int]]{}
-
-type (
-	T1[P1 any] struct {
-		f1 T2[P1, float32]
-	}
-
-	T2[P2, P3 any] struct {
-		f2 P2
-		f3 P3
-	}
-)
-
-func _() {
-	var x1 T1[int]
-	var x2 T2[int, float32]
-
-	x1.f1.f2 = 0
-	x1.f1 = x2
-}
-
-type T3[P any] T1[T2[P, P]]
-
-func _() {
-	var x1 T3[int]
-	var x2 T2[int, int]
-	x1.f1.f2 = x2
-}
-
-func f[P any] (x P) List[P] {
-	return List[P]{x}
-}
-
-var (
-	_ []int = f(0)
-	_ []float32 = f[float32](10)
-	_ List[complex128] = f(1i)
-	_ []List[int] = f(List[int]{})
-        _ List[List[int]] = []List[int]{}
-        _ = []List[int]{}
-)
-
-// Parameterized types with methods
-
-func (l List[E]) Head() (_ E, _ bool) {
-	if len(l) > 0 {
-		return l[0], true
-	}
-	return
-}
-
-// A test case for instantiating types with other types (extracted from map.go2)
-
-type Pair[K any] struct {
-	key K
-}
-
-type Receiver[T any] struct {
-	values T
-}
-
-type Iterator[K any] struct {
-	r Receiver[Pair[K]]
-}
-
-func Values [T any] (r Receiver[T]) T {
-        return r.values
-}
-
-func (it Iterator[K]) Next() K {
-        return Values[Pair[K]](it.r).key
-}
-
-// A more complex test case testing type bounds (extracted from linalg.go2 and reduced to essence)
-
-type NumericAbs[T any] interface {
-	Abs() T
-}
-
-func AbsDifference[T NumericAbs[T]](x T) { panic(0) }
-
-// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
-// type OrderedAbs[T any] T
-// 
-// func (a OrderedAbs[T]) Abs() OrderedAbs[T]
-// 
-// func OrderedAbsDifference[T any](x T) {
-// 	AbsDifference(OrderedAbs[T](x))
-// }
-
-// same code, reduced to essence
-
-func g[P interface{ m() P }](x P) { panic(0) }
-
-// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
-// type T4[P any] P
-// 
-// func (_ T4[P]) m() T4[P]
-// 
-// func _[Q any](x Q) {
-// 	g(T4[Q](x))
-// }
-
-// Another test case that caused  problems in the past
-
-type T5[_ interface { a() }, _ interface{}] struct{}
-
-type A[P any] struct{ x P }
-
-func (_ A[P]) a() {}
-
-var _ T5[A[int], int]
-
-// Invoking methods with parameterized receiver types uses
-// type inference to determine the actual type arguments matching
-// the receiver type parameters from the actual receiver argument.
-// Go does implicit address-taking and dereferenciation depending
-// on the actual receiver and the method's receiver type. To make
-// type inference work, the type-checker matches "pointer-ness"
-// of the actual receiver and the method's receiver type.
-// The following code tests this mechanism.
-
-type R1[A any] struct{}
-func (_ R1[A]) vm()
-func (_ *R1[A]) pm()
-
-func _[T any](r R1[T], p *R1[T]) {
-	r.vm()
-	r.pm()
-	p.vm()
-	p.pm()
-}
-
-type R2[A, B any] struct{}
-func (_ R2[A, B]) vm()
-func (_ *R2[A, B]) pm()
-
-func _[T any](r R2[T, int], p *R2[string, T]) {
-	r.vm()
-	r.pm()
-	p.vm()
-	p.pm()
-}
-
-// It is ok to have multiple embedded unions.
-type _ interface {
-	m0()
-	~int | ~string | ~bool
-	~float32 | ~float64
-	m1()
-	m2()
-	~complex64 | ~complex128
-	~rune
-}
-
-// Type sets may contain each type at most once.
-type _ interface {
-	~int|~ /* ERROR overlapping terms ~int */ int
-	~int|int /* ERROR overlapping terms int */
-	int|int /* ERROR overlapping terms int */
-}
-
-type _ interface {
-	~struct{f int} | ~struct{g int} | ~ /* ERROR overlapping terms */ struct{f int}
-}
-
-// Interface term lists can contain any type, incl. *Named types.
-// Verify that we use the underlying type(s) of the type(s) in the
-// term list when determining if an operation is permitted.
-
-type MyInt int
-func add1[T interface{MyInt}](x T) T {
-	return x + 1
-}
-
-type MyString string
-func double[T interface{MyInt|MyString}](x T) T {
-	return x + x
-}
-
-// Embedding of interfaces with term lists leads to interfaces
-// with term lists that are the intersection of the embedded
-// term lists.
-
-type E0 interface {
-	~int | ~bool | ~string
-}
-
-type E1 interface {
-	~int | ~float64 | ~string
-}
-
-type E2 interface {
-	~float64
-}
-
-type I0 interface {
-	E0
-}
-
-func f0[T I0]() {}
-var _ = f0[int]
-var _ = f0[bool]
-var _ = f0[string]
-var _ = f0[float64 /* ERROR does not implement I0 */ ]
-
-type I01 interface {
-	E0
-	E1
-}
-
-func f01[T I01]() {}
-var _ = f01[int]
-var _ = f01[bool /* ERROR does not implement I0 */ ]
-var _ = f01[string]
-var _ = f01[float64 /* ERROR does not implement I0 */ ]
-
-type I012 interface {
-	E0
-	E1
-	E2
-}
-
-func f012[T I012]() {}
-var _ = f012[int /* ERROR cannot implement I012.*empty type set */ ]
-var _ = f012[bool /* ERROR cannot implement I012.*empty type set */ ]
-var _ = f012[string /* ERROR cannot implement I012.*empty type set */ ]
-var _ = f012[float64 /* ERROR cannot implement I012.*empty type set */ ]
-
-type I12 interface {
-	E1
-	E2
-}
-
-func f12[T I12]() {}
-var _ = f12[int /* ERROR does not implement I12 */ ]
-var _ = f12[bool /* ERROR does not implement I12 */ ]
-var _ = f12[string /* ERROR does not implement I12 */ ]
-var _ = f12[float64]
-
-type I0_ interface {
-	E0
-	~int
-}
-
-func f0_[T I0_]() {}
-var _ = f0_[int]
-var _ = f0_[bool /* ERROR does not implement I0_ */ ]
-var _ = f0_[string /* ERROR does not implement I0_ */ ]
-var _ = f0_[float64 /* ERROR does not implement I0_ */ ]
-
-// Using a function instance as a type is an error.
-var _ f0 // ERROR not a type
-var _ f0 /* ERROR not a type */ [int]
-
-// Empty type sets can only be satisfied by empty type sets.
-type none interface {
-	// force an empty type set
-        int
-        string
-}
-
-func ff[T none]() {}
-func gg[T any]() {}
-func hh[T ~int]() {}
-
-func _[T none]() {
-	_ = ff[int /* ERROR cannot implement none \(empty type set\) */ ]
-	_ = ff[T]  // pathological but ok because T's type set is empty, too
-	_ = gg[int]
-	_ = gg[T]
-	_ = hh[int]
-	_ = hh[T]
-}
diff --git a/src/go/types/testdata/check/typeparams.go b/src/go/types/testdata/check/typeparams.go
deleted file mode 100644
index 199828f..0000000
--- a/src/go/types/testdata/check/typeparams.go
+++ /dev/null
@@ -1,508 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-// import "io" // for type assertion tests
-
-var _ any // ok to use any anywhere
-func _[_ any, _ interface{any}](any) {
-        var _ any
-}
-
-func identity[T any](x T) T { return x }
-
-func _[_ any](x int) int { panic(0) }
-func _[T any](T /* ERROR redeclared */ T)() {}
-func _[T, T /* ERROR redeclared */ any]() {}
-
-// Constraints (incl. any) may be parenthesized.
-func _[_ (any)]() {}
-func _[_ (interface{})]() {}
-
-func reverse[T any](list []T) []T {
-        rlist := make([]T, len(list))
-        i := len(list)
-        for _, x := range list {
-                i--
-                rlist[i] = x
-        }
-        return rlist
-}
-
-var _ = reverse /* ERROR cannot use generic function reverse */
-var _ = reverse[int, float32 /* ERROR got 2 type arguments */ ] ([]int{1, 2, 3})
-var _ = reverse[int]([ /* ERROR cannot use */ ]float32{1, 2, 3})
-var f = reverse[chan int]
-var _ = f(0 /* ERROR cannot use 0 .* as \[\]chan int */ )
-
-func swap[A, B any](a A, b B) (B, A) { return b, a }
-
-var _ = swap /* ERROR single value is expected */ [int, float32](1, 2)
-var f32, i = swap[int, float32](swap[float32, int](1, 2))
-var _ float32 = f32
-var _ int = i
-
-func swapswap[A, B any](a A, b B) (A, B) {
-        return swap[B, A](b, a)
-}
-
-type F[A, B any] func(A, B) (B, A)
-
-func min[T interface{ ~int }](x, y T) T {
-        if x < y {
-                return x
-        }
-        return y
-}
-
-func _[T interface{~int | ~float32}](x, y T) bool { return x < y }
-func _[T any](x, y T) bool { return x /* ERROR cannot compare */ < y }
-func _[T interface{~int | ~float32 | ~bool}](x, y T) bool { return x /* ERROR cannot compare */ < y }
-
-func _[T C1[T]](x, y T) bool { return x /* ERROR cannot compare */ < y }
-func _[T C2[T]](x, y T) bool { return x < y }
-
-type C1[T any] interface{}
-type C2[T any] interface{ ~int | ~float32 }
-
-func new[T any]() *T {
-        var x T
-        return &x
-}
-
-var _ = new /* ERROR cannot use generic function new */
-var _ *int = new[int]()
-
-func _[T any](map[T /* ERROR incomparable map key type T \(missing comparable constraint\) */]int) {} // w/o constraint we don't know if T is comparable
-
-func f1[T1 any](struct{T1 /* ERROR cannot be a .* type parameter */ }) int { panic(0) }
-var _ = f1[int](struct{T1}{})
-type T1 = int
-
-func f2[t1 any](struct{t1 /* ERROR cannot be a .* type parameter */ ; x float32}) int { panic(0) }
-var _ = f2[t1](struct{t1; x float32}{})
-type t1 = int
-
-
-func f3[A, B, C any](A, struct{x B}, func(A, struct{x B}, *C)) int { panic(0) }
-
-var _ = f3[int, rune, bool](1, struct{x rune}{}, nil)
-
-// indexing
-
-func _[T any] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
-func _[T interface{ ~int }] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
-func _[T interface{ ~string }] (x T, i int) { _ = x[i] }
-func _[T interface{ ~[]int }] (x T, i int) { _ = x[i] }
-func _[T interface{ ~[10]int | ~*[20]int | ~map[int]int }] (x T, i int) { _ = x /* ERROR cannot index */ [i] } // map and non-map types
-func _[T interface{ ~string | ~[]byte }] (x T, i int) { _ = x[i] }
-func _[T interface{ ~[]int | ~[1]rune }] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
-func _[T interface{ ~string | ~[]rune }] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
-
-// indexing with various combinations of map types in type sets (see issue #42616)
-func _[T interface{ ~[]E | ~map[int]E }, E any](x T, i int) { _ = x /* ERROR cannot index */ [i] } // map and non-map types
-func _[T interface{ ~[]E }, E any](x T, i int) { _ = &x[i] }
-func _[T interface{ ~map[int]E }, E any](x T, i int) { _, _ = x[i] } // comma-ok permitted
-func _[T interface{ ~map[int]E }, E any](x T, i int) { _ = &x /* ERROR cannot take address */ [i] }
-func _[T interface{ ~map[int]E | ~map[uint]E }, E any](x T, i int) { _ = x /* ERROR cannot index */ [i] } // different map element types
-func _[T interface{ ~[]E | ~map[string]E }, E any](x T, i int) { _ = x /* ERROR cannot index */ [i] } // map and non-map types
-
-// indexing with various combinations of array and other types in type sets
-func _[T interface{ [10]int }](x T, i int) { _ = x[i]; _ = x[9]; _ = x[10 /* ERROR out of bounds */ ] }
-func _[T interface{ [10]byte | string }](x T, i int) { _ = x[i]; _ = x[9]; _ = x[10 /* ERROR out of bounds */ ] }
-func _[T interface{ [10]int | *[20]int | []int }](x T, i int) { _ = x[i]; _ = x[9]; _ = x[10 /* ERROR out of bounds */ ] }
-
-// indexing with strings and non-variable arrays (assignment not permitted)
-func _[T string](x T) { _ = x[0]; x /* ERROR cannot assign */ [0] = 0 }
-func _[T []byte | string](x T) { x /* ERROR cannot assign */ [0] = 0 }
-func _[T [10]byte]() { f := func() (x T) { return }; f /* ERROR cannot assign */ ()[0] = 0 }
-func _[T [10]byte]() { f := func() (x *T) { return }; f /* ERROR cannot index */ ()[0] = 0 }
-func _[T [10]byte]() { f := func() (x *T) { return }; (*f())[0] = 0 }
-func _[T *[10]byte]() { f := func() (x T) { return }; f()[0] = 0 }
-
-// slicing
-
-func _[T interface{ ~[10]E }, E any] (x T, i, j, k int) { var _ []E = x[i:j] }
-func _[T interface{ ~[10]E }, E any] (x T, i, j, k int) { var _ []E = x[i:j:k] }
-func _[T interface{ ~[]byte }] (x T, i, j, k int) { var _ T = x[i:j] }
-func _[T interface{ ~[]byte }] (x T, i, j, k int) { var _ T = x[i:j:k] }
-func _[T interface{ ~string }] (x T, i, j, k int) { var _ T = x[i:j] }
-func _[T interface{ ~string }] (x T, i, j, k int) { var _ T = x[i:j:k /* ERROR 3-index slice of string */ ] }
-
-type myByte1 []byte
-type myByte2 []byte
-func _[T interface{ []byte | myByte1 | myByte2 }] (x T, i, j, k int) { var _ T = x[i:j:k] }
-func _[T interface{ []byte | myByte1 | []int }] (x T, i, j, k int) { var _ T = x /* ERROR no core type */ [i:j:k] }
-
-func _[T interface{ []byte | myByte1 | myByte2 | string }] (x T, i, j, k int) { var _ T = x[i:j] }
-func _[T interface{ []byte | myByte1 | myByte2 | string }] (x T, i, j, k int) { var _ T = x[i:j:k /* ERROR 3-index slice of string */ ] }
-func _[T interface{ []byte | myByte1 | []int | string }] (x T, i, j, k int) { var _ T = x /* ERROR no core type */ [i:j] }
-
-// len/cap built-ins
-
-func _[T any](x T) { _ = len(x /* ERROR invalid argument */ ) }
-func _[T interface{ ~int }](x T) { _ = len(x /* ERROR invalid argument */ ) }
-func _[T interface{ ~string | ~[]byte | ~int }](x T) { _ = len(x /* ERROR invalid argument */ ) }
-func _[T interface{ ~string }](x T) { _ = len(x) }
-func _[T interface{ ~[10]int }](x T) { _ = len(x) }
-func _[T interface{ ~[]byte }](x T) { _ = len(x) }
-func _[T interface{ ~map[int]int }](x T) { _ = len(x) }
-func _[T interface{ ~chan int }](x T) { _ = len(x) }
-func _[T interface{ ~string | ~[]byte | ~chan int }](x T) { _ = len(x) }
-
-func _[T any](x T) { _ = cap(x /* ERROR invalid argument */ ) }
-func _[T interface{ ~int }](x T) { _ = cap(x /* ERROR invalid argument */ ) }
-func _[T interface{ ~string | ~[]byte | ~int }](x T) { _ = cap(x /* ERROR invalid argument */ ) }
-func _[T interface{ ~string }](x T) { _ = cap(x /* ERROR invalid argument */ ) }
-func _[T interface{ ~[10]int }](x T) { _ = cap(x) }
-func _[T interface{ ~[]byte }](x T) { _ = cap(x) }
-func _[T interface{ ~map[int]int }](x T) { _ = cap(x /* ERROR invalid argument */ ) }
-func _[T interface{ ~chan int }](x T) { _ = cap(x) }
-func _[T interface{ ~[]byte | ~chan int }](x T) { _ = cap(x) }
-
-// range iteration
-
-func _[T interface{}](x T) {
-        for range x /* ERROR cannot range */ {}
-}
-
-type myString string
-
-func _[
-        B1 interface{ string },
-        B2 interface{ string | myString },
-
-        C1 interface{ chan int },
-        C2 interface{ chan int | <-chan int },
-        C3 interface{ chan<- int },
-
-        S1 interface{ []int },
-        S2 interface{ []int | [10]int },
-
-        A1 interface{ [10]int },
-        A2 interface{ [10]int | []int },
-
-        P1 interface{ *[10]int },
-        P2 interface{ *[10]int | *[]int },
-
-        M1 interface{ map[string]int },
-        M2 interface{ map[string]int | map[string]string },
-]() {
-        var b0 string
-        for range b0 {}
-        for _ = range b0 {}
-        for _, _ = range b0 {}
-
-        var b1 B1
-        for range b1 {}
-        for _ = range b1 {}
-        for _, _ = range b1 {}
-
-        var b2 B2
-        for range b2 {}
-
-        var c0 chan int
-        for range c0 {}
-        for _ = range c0 {}
-        for _, _ /* ERROR permits only one iteration variable */ = range c0 {}
-
-        var c1 C1
-        for range c1 {}
-        for _ = range c1 {}
-        for _, _ /* ERROR permits only one iteration variable */ = range c1 {}
-
-        var c2 C2
-        for range c2 {}
-
-        var c3 C3
-        for range c3 /* ERROR receive from send-only channel */ {}
-
-        var s0 []int
-        for range s0 {}
-        for _ = range s0 {}
-        for _, _ = range s0 {}
-
-        var s1 S1
-        for range s1 {}
-        for _ = range s1 {}
-        for _, _ = range s1 {}
-
-        var s2 S2
-        for range s2 /* ERROR cannot range over s2.*no core type */ {}
-
-        var a0 []int
-        for range a0 {}
-        for _ = range a0 {}
-        for _, _ = range a0 {}
-
-        var a1 A1
-        for range a1 {}
-        for _ = range a1 {}
-        for _, _ = range a1 {}
-
-        var a2 A2
-        for range a2 /* ERROR cannot range over a2.*no core type */ {}
-
-        var p0 *[10]int
-        for range p0 {}
-        for _ = range p0 {}
-        for _, _ = range p0 {}
-
-        var p1 P1
-        for range p1 {}
-        for _ = range p1 {}
-        for _, _ = range p1 {}
-
-        var p2 P2
-        for range p2 /* ERROR cannot range over p2.*no core type */ {}
-
-        var m0 map[string]int
-        for range m0 {}
-        for _ = range m0 {}
-        for _, _ = range m0 {}
-
-        var m1 M1
-        for range m1 {}
-        for _ = range m1 {}
-        for _, _ = range m1 {}
-
-        var m2 M2
-        for range m2 /* ERROR cannot range over m2.*no core type */ {}
-}
-
-// type inference checks
-
-var _ = new /* ERROR cannot infer T */ ()
-
-func f4[A, B, C any](A, B) C { panic(0) }
-
-var _ = f4 /* ERROR cannot infer C */ (1, 2)
-var _ = f4[int, float32, complex128](1, 2)
-
-func f5[A, B, C any](A, []*B, struct{f []C}) int { panic(0) }
-
-var _ = f5[int, float32, complex128](0, nil, struct{f []complex128}{})
-var _ = f5 /* ERROR cannot infer */ (0, nil, struct{f []complex128}{})
-var _ = f5(0, []*float32{new[float32]()}, struct{f []complex128}{})
-
-func f6[A any](A, []A) int { panic(0) }
-
-var _ = f6(0, nil)
-
-func f6nil[A any](A) int { panic(0) }
-
-var _ = f6nil /* ERROR cannot infer */ (nil)
-
-// type inference with variadic functions
-
-func f7[T any](...T) T { panic(0) }
-
-var _ int = f7 /* ERROR cannot infer T */ ()
-var _ int = f7(1)
-var _ int = f7(1, 2)
-var _ int = f7([]int{}...)
-var _ int = f7 /* ERROR cannot use */ ([]float64{}...)
-var _ float64 = f7([]float64{}...)
-var _ = f7[float64](1, 2.3)
-var _ = f7(float64(1), 2.3)
-var _ = f7(1, 2.3 /* ERROR does not match */ )
-var _ = f7(1.2, 3 /* ERROR does not match */ )
-
-func f8[A, B any](A, B, ...B) int { panic(0) }
-
-var _ = f8(1) /* ERROR not enough arguments */
-var _ = f8(1, 2.3)
-var _ = f8(1, 2.3, 3.4, 4.5)
-var _ = f8(1, 2.3, 3.4, 4 /* ERROR does not match */ )
-var _ = f8[int, float64](1, 2.3, 3.4, 4)
-
-var _ = f8[int, float64](0, 0, nil...) // test case for #18268
-
-// init functions cannot have type parameters
-
-func init() {}
-func init[_ /* ERROR func init must have no type parameters */ any]() {}
-func init[P /* ERROR func init must have no type parameters */ any]() {}
-
-type T struct {}
-
-func (T) m1() {}
-func (T) m2[ /* ERROR method must have no type parameters */ _ any]() {}
-func (T) m3[ /* ERROR method must have no type parameters */ P any]() {}
-
-// type inference across parameterized types
-
-type S1[P any] struct { f P }
-
-func f9[P any](x S1[P]) {}
-
-func _() {
-        f9[int](S1[int]{42})
-	f9(S1[int]{42})
-}
-
-type S2[A, B, C any] struct{}
-
-func f10[X, Y, Z any](a S2[X, int, Z], b S2[X, Y, bool]) {}
-
-func _[P any]() {
-        f10[int, float32, string](S2[int, int, string]{}, S2[int, float32, bool]{})
-        f10(S2[int, int, string]{}, S2[int, float32, bool]{})
-        f10(S2[P, int, P]{}, S2[P, float32, bool]{})
-}
-
-// corner case for type inference
-// (was bug: after instanting f11, the type-checker didn't mark f11 as non-generic)
-
-func f11[T any]() {}
-
-func _() {
-	f11[int]()
-}
-
-// the previous example was extracted from
-
-// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
-// func f12[T interface{m() T}]() {}
-// 
-// type A[T any] T
-// 
-// func (a A[T]) m() A[T]
-// 
-// func _[T any]() {
-// 	f12[A[T]]()
-// }
-
-// method expressions
-
-func (_ S1[P]) m()
-
-func _() {
-	m := S1[int].m
-	m(struct { f int }{42})
-}
-
-func _[T any] (x T) {
-        m := S1[T].m
-        m(S1[T]{x})
-}
-
-type I1[A any] interface {
-        m1(A)
-}
-
-var _ I1[int] = r1[int]{}
-
-type r1[T any] struct{}
-
-func (_ r1[T]) m1(T)
-
-type I2[A, B any] interface {
-        m1(A)
-        m2(A) B
-}
-
-var _ I2[int, float32] = R2[int, float32]{}
-
-type R2[P, Q any] struct{}
-
-func (_ R2[X, Y]) m1(X)
-func (_ R2[X, Y]) m2(X) Y
-
-// type assertions and type switches over generic types
-// NOTE: These are currently disabled because it's unclear what the correct
-// approach is, and one can always work around by assigning the variable to
-// an interface first.
-
-// // ReadByte1 corresponds to the ReadByte example in the draft design.
-// func ReadByte1[T io.Reader](r T) (byte, error) {
-// 	if br, ok := r.(io.ByteReader); ok {
-// 		return br.ReadByte()
-// 	}
-// 	var b [1]byte
-// 	_, err := r.Read(b[:])
-// 	return b[0], err
-// }
-//
-// // ReadBytes2 is like ReadByte1 but uses a type switch instead.
-// func ReadByte2[T io.Reader](r T) (byte, error) {
-//         switch br := r.(type) {
-//         case io.ByteReader:
-//                 return br.ReadByte()
-//         }
-// 	var b [1]byte
-// 	_, err := r.Read(b[:])
-// 	return b[0], err
-// }
-//
-// // type assertions and type switches over generic types are strict
-// type I3 interface {
-//         m(int)
-// }
-//
-// type I4 interface {
-//         m() int // different signature from I3.m
-// }
-//
-// func _[T I3](x I3, p T) {
-//         // type assertions and type switches over interfaces are not strict
-//         _ = x.(I4)
-//         switch x.(type) {
-//         case I4:
-//         }
-// 
-//         // type assertions and type switches over generic types are strict
-//         _ = p /* ERROR cannot have dynamic type I4 */.(I4)
-//         switch p.(type) {
-//         case I4 /* ERROR cannot have dynamic type I4 */ :
-//         }
-// }
-
-// type assertions and type switches over generic types lead to errors for now
-
-func _[T any](x T) {
-	_ = x /* ERROR cannot use type assertion */ .(int)
-	switch x /* ERROR cannot use type switch */ .(type) {
-	}
-
-	// work-around
-	var t interface{} = x
-	_ = t.(int)
-	switch t.(type) {
-	}
-}
-
-func _[T interface{~int}](x T) {
-	_ = x /* ERROR cannot use type assertion */ .(int)
-	switch x /* ERROR cannot use type switch */ .(type) {
-	}
-
-	// work-around
-	var t interface{} = x
-	_ = t.(int)
-	switch t.(type) {
-	}
-}
-
-// error messages related to type bounds mention those bounds
-type C[P any] interface{}
-
-func _[P C[P]] (x P) {
-	x.m /* ERROR x.m undefined */ ()
-}
-
-type I interface {}
-
-func _[P I] (x P) {
-	x.m /* ERROR type P has no field or method m */ ()
-}
-
-func _[P interface{}] (x P) {
-	x.m /* ERROR type P has no field or method m */ ()
-}
-
-func _[P any] (x P) {
-	x.m /* ERROR type P has no field or method m */ ()
-}
diff --git a/src/go/types/testdata/check/vardecl.go b/src/go/types/testdata/check/vardecl.go
deleted file mode 100644
index 56abf97..0000000
--- a/src/go/types/testdata/check/vardecl.go
+++ /dev/null
@@ -1,206 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package vardecl
-
-// Prerequisites.
-import "math"
-func f() {}
-func g() (x, y int) { return }
-var m map[string]int
-
-// Var decls must have a type or an initializer.
-var _ int
-var _, _ int
-
-// The first error message is produced by the parser.
-// In a real-world scenario, the type-checker would not be run
-// in this case and the 2nd error message would not appear.
-var _ /* ERROR "missing variable type" */ /* ERROR "missing type or init expr" */
-var _ /* ERROR "missing variable type" */ /* ERROR "missing type or init expr" */, _
-var _ /* ERROR "missing variable type" */ /* ERROR "missing type or init expr" */, _, _
-
-// The initializer must be an expression.
-var _ = int /* ERROR "not an expression" */
-var _ = f /* ERROR "used as value" */ ()
-
-// Identifier and expression arity must match.
-var _, _ = 1, 2
-var _ = 1, 2 /* ERROR "extra init expr 2" */
-var _, _ = 1 /* ERROR "cannot initialize [0-9]+ variables with [0-9]+ values" */
-var _, _, _ /* ERROR "missing init expr for _" */ = 1, 2
-
-var _ = g /* ERROR "2-valued g" */ ()
-var _, _ = g()
-var _, _, _ = g /* ERROR "cannot initialize [0-9]+ variables with [0-9]+ values" */ ()
-
-var _ = m["foo"]
-var _, _ = m["foo"]
-var _, _, _ = m  /* ERROR "cannot initialize [0-9]+ variables with [0-9]+ values" */ ["foo"]
-
-var _, _ int = 1, 2
-var _ int = 1, 2 /* ERROR "extra init expr 2" */
-var _, _ int = 1 /* ERROR "cannot initialize [0-9]+ variables with [0-9]+ values" */
-var _, _, _ /* ERROR "missing init expr for _" */ int = 1, 2
-
-var (
-	_, _ = 1, 2
-	_ = 1, 2 /* ERROR "extra init expr 2" */
-	_, _ = 1 /* ERROR "cannot initialize [0-9]+ variables with [0-9]+ values" */
-	_, _, _ /* ERROR "missing init expr for _" */ = 1, 2
-
-	_ = g /* ERROR "2-valued g" */ ()
-	_, _ = g()
-	_, _, _ = g /* ERROR "cannot initialize [0-9]+ variables with [0-9]+ values" */ ()
-
-	_ = m["foo"]
-	_, _ = m["foo"]
-	_, _, _ = m /* ERROR "cannot initialize [0-9]+ variables with [0-9]+ values" */ ["foo"]
-
-	_, _ int = 1, 2
-	_ int = 1, 2 /* ERROR "extra init expr 2" */
-	_, _ int = 1 /* ERROR "cannot initialize [0-9]+ variables with [0-9]+ values" */
-	_, _, _ /* ERROR "missing init expr for _" */ int = 1, 2
-)
-
-// Variables declared in function bodies must be 'used'.
-type T struct{}
-func (r T) _(a, b, c int) (u, v, w int) {
-	var x1 /* ERROR "declared but not used" */ int
-	var x2 /* ERROR "declared but not used" */ int
-	x1 = 1
-	(x2) = 2
-
-	y1 /* ERROR "declared but not used" */ := 1
-	y2 /* ERROR "declared but not used" */ := 2
-	y1 = 1
-	(y1) = 2
-
-	{
-		var x1 /* ERROR "declared but not used" */ int
-		var x2 /* ERROR "declared but not used" */ int
-		x1 = 1
-		(x2) = 2
-
-		y1 /* ERROR "declared but not used" */ := 1
-		y2 /* ERROR "declared but not used" */ := 2
-		y1 = 1
-		(y1) = 2
-	}
-
-	if x /* ERROR "declared but not used" */ := 0; a < b {}
-
-	switch x /* ERROR "declared but not used" */, y := 0, 1; a {
-	case 0:
-		_ = y
-	case 1:
-		x /* ERROR "declared but not used" */ := 0
-	}
-
-	var t interface{}
-	switch t /* ERROR "declared but not used" */ := t.(type) {}
-
-	switch t /* ERROR "declared but not used" */ := t.(type) {
-	case int:
-	}
-
-	switch t /* ERROR "declared but not used" */ := t.(type) {
-	case int:
-	case float32, complex64:
-		t = nil
-	}
-
-	switch t := t.(type) {
-	case int:
-	case float32, complex64:
-		_ = t
-	}
-
-	switch t := t.(type) {
-	case int:
-	case float32:
-	case string:
-		_ = func() string {
-			return t
-		}
-	}
-
-	switch t := t; t /* ERROR "declared but not used" */ := t.(type) {}
-
-	var z1 /* ERROR "declared but not used" */ int
-	var z2 int
-	_ = func(a, b, c int) (u, v, w int) {
-		z1 = a
-		(z1) = b
-		a = z2
-		return
-	}
-
-	var s []int
-	var i /* ERROR "declared but not used" */ , j int
-	for i, j = range s {
-		_ = j
-	}
-
-	for i, j /* ERROR "declared but not used" */ := range s {
-		_ = func() int {
-			return i
-		}
-	}
-	return
-}
-
-// Unused variables in function literals must lead to only one error (issue #22524).
-func _() {
-	_ = func() {
-		var x /* ERROR declared but not used */ int
-	}
-}
-
-// Invalid (unused) expressions must not lead to spurious "declared but not used errors"
-func _() {
-	var a, b, c int
-	var x, y int
-	x, y = a /* ERROR cannot assign [0-9]+ values to [0-9]+ variables */ , b, c
-	_ = x
-	_ = y
-}
-
-func _() {
-	var x int
-	return x /* ERROR too many return values */
-	return math /* ERROR too many return values */ .Sin(0)
-}
-
-func _() int {
-	var x, y int
-	return x, y /* ERROR too many return values */
-}
-
-// Short variable declarations must declare at least one new non-blank variable.
-func _() {
-	_ := /* ERROR no new variables */ 0
-	_, a := 0, 1
-	_, a := /* ERROR no new variables */ 0, 1
-	_, a, b := 0, 1, 2
-	_, _, _ := /* ERROR no new variables */ 0, 1, 2
-
-	_ = a
-	_ = b
-}
-
-// Test case for variables depending on function literals (see also #22992).
-var A /* ERROR initialization cycle */ = func() int { return A }()
-
-func _() {
-	// The function literal below must not see a.
-	var a = func() int { return a /* ERROR "undeclared name" */ }()
-	var _ = func() int { return a }()
-
-	// The function literal below must not see x, y, or z.
-	var x, y, z = 0, 1, func() int { return x /* ERROR "undeclared name" */ + y /* ERROR "undeclared name" */ + z /* ERROR "undeclared name" */ }()
-	_, _, _ = x, y, z
-}
-
-// TODO(gri) consolidate other var decl checks in this file
\ No newline at end of file
diff --git a/src/go/types/testdata/examples/functions.go b/src/go/types/testdata/examples/functions.go
deleted file mode 100644
index 1d30075..0000000
--- a/src/go/types/testdata/examples/functions.go
+++ /dev/null
@@ -1,218 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file shows some examples of type-parameterized functions.
-
-package p
-
-// Reverse is a generic function that takes a []T argument and
-// reverses that slice in place.
-func Reverse[T any](list []T) {
-	i := 0
-	j := len(list)-1
-	for i < j {
-		list[i], list[j] = list[j], list[i]
-		i++
-		j--
-	}
-}
-
-func _() {
-	// Reverse can be called with an explicit type argument.
-	Reverse[int](nil)
-	Reverse[string]([]string{"foo", "bar"})
-	Reverse[struct{x, y int}]([]struct{x, y int}{{1, 2}, {2, 3}, {3, 4}})
-
-	// Since the type parameter is used for an incoming argument,
-	// it can be inferred from the provided argument's type.
-	Reverse([]string{"foo", "bar"})
-	Reverse([]struct{x, y int}{{1, 2}, {2, 3}, {3, 4}})
-
-	// But the incoming argument must have a type, even if it's a
-	// default type. An untyped nil won't work.
-	// Reverse(nil) // this won't type-check
-
-	// A typed nil will work, though.
-	Reverse([]int(nil))
-}
-
-// Certain functions, such as the built-in `new` could be written using
-// type parameters.
-func new[T any]() *T {
-	var x T
-	return &x
-}
-
-// When calling our own `new`, we need to pass the type parameter
-// explicitly since there is no (value) argument from which the
-// result type could be inferred. We don't try to infer the
-// result type from the assignment to keep things simple and
-// easy to understand.
-var _ = new[int]()
-var _ *float64 = new[float64]() // the result type is indeed *float64
-
-// A function may have multiple type parameters, of course.
-func foo[A, B, C any](a A, b []B, c *C) B {
-	// do something here
-	return b[0]
-}
-
-// As before, we can pass type parameters explicitly.
-var s = foo[int, string, float64](1, []string{"first"}, new[float64]())
-
-// Or we can use type inference.
-var _ float64 = foo(42, []float64{1.0}, &s)
-
-// Type inference works in a straight-forward manner even
-// for variadic functions.
-func variadic[A, B any](A, B, ...B) int { panic(0) }
-
-// var _ = variadic(1) // ERROR not enough arguments
-var _ = variadic(1, 2.3)
-var _ = variadic(1, 2.3, 3.4, 4.5)
-var _ = variadic[int, float64](1, 2.3, 3.4, 4)
-
-// Type inference also works in recursive function calls where
-// the inferred type is the type parameter of the caller.
-func f1[T any](x T) {
-	f1(x)
-}
-
-func f2a[T any](x, y T) {
-	f2a(x, y)
-}
-
-func f2b[T any](x, y T) {
-	f2b(y, x)
-}
-
-func g2a[P, Q any](x P, y Q) {
-	g2a(x, y)
-}
-
-func g2b[P, Q any](x P, y Q) {
-	g2b(y, x)
-}
-
-// Here's an example of a recursive function call with variadic
-// arguments and type inference inferring the type parameter of
-// the caller (i.e., itself).
-func max[T interface{ ~int }](x ...T) T {
-	var x0 T
-	if len(x) > 0 {
-		x0 = x[0]
-	}
-	if len(x) > 1 {
-		x1 := max(x[1:]...)
-		if x1 > x0 {
-			return x1
-		}
-	}
-	return x0
-}
-
-// When inferring channel types, the channel direction is ignored
-// for the purpose of type inference. Once the type has been in-
-// fered, the usual parameter passing rules are applied.
-// Thus even if a type can be inferred successfully, the function
-// call may not be valid.
-
-func fboth[T any](chan T) {}
-func frecv[T any](<-chan T) {}
-func fsend[T any](chan<- T) {}
-
-func _() {
-	var both chan int
-	var recv <-chan int
-	var send chan<-int
-
-	fboth(both)
-	fboth(recv /* ERROR cannot use */ )
-	fboth(send /* ERROR cannot use */ )
-
-	frecv(both)
-	frecv(recv)
-	frecv(send /* ERROR cannot use */ )
-
-	fsend(both)
-	fsend(recv /* ERROR cannot use */)
-	fsend(send)
-}
-
-func ffboth[T any](func(chan T)) {}
-func ffrecv[T any](func(<-chan T)) {}
-func ffsend[T any](func(chan<- T)) {}
-
-func _() {
-	var both func(chan int)
-	var recv func(<-chan int)
-	var send func(chan<- int)
-
-	ffboth(both)
-	ffboth(recv /* ERROR cannot use */ )
-	ffboth(send /* ERROR cannot use */ )
-
-	ffrecv(both /* ERROR cannot use */ )
-	ffrecv(recv)
-	ffrecv(send /* ERROR cannot use */ )
-
-	ffsend(both /* ERROR cannot use */ )
-	ffsend(recv /* ERROR cannot use */ )
-	ffsend(send)
-}
-
-// When inferring elements of unnamed composite parameter types,
-// if the arguments are defined types, use their underlying types.
-// Even though the matching types are not exactly structurally the
-// same (one is a type literal, the other a named type), because
-// assignment is permitted, parameter passing is permitted as well,
-// so type inference should be able to handle these cases well.
-
-func g1[T any]([]T) {}
-func g2[T any]([]T, T) {}
-func g3[T any](*T, ...T) {}
-
-func _() {
-	type intSlize []int
-	g1([]int{})
-	g1(intSlize{})
-	g2(nil, 0)
-
-	type myString string
-	var s1 string
-	g3(nil, "1", myString("2"), "3")
-	g3(& /* ERROR does not match */ s1, "1", myString("2"), "3")
-
-	type myStruct struct{x int}
-	var s2 myStruct
-	g3(nil, struct{x int}{}, myStruct{})
-	g3(&s2, struct{x int}{}, myStruct{})
-	g3(nil, myStruct{}, struct{x int}{})
-	g3(&s2, myStruct{}, struct{x int}{})
-}
-
-// Here's a realistic example.
-
-func append[T any](s []T, t ...T) []T { panic(0) }
-
-func _() {
-	var f func()
-	type Funcs []func()
-	var funcs Funcs
-	_ = append(funcs, f)
-}
-
-// Generic type declarations cannot have empty type parameter lists
-// (that would indicate a slice type). Thus, generic functions cannot
-// have empty type parameter lists, either. This is a syntax error.
-
-func h[] /* ERROR empty type parameter list */ () {}
-
-func _() {
-	h /* ERROR cannot index */ [] /* ERROR operand */ ()
-}
-
-// Parameterized functions must have a function body.
-
-func _ /* ERROR missing function body */ [P any]()
diff --git a/src/go/types/testdata/examples/inference.go b/src/go/types/testdata/examples/inference.go
deleted file mode 100644
index e59a544..0000000
--- a/src/go/types/testdata/examples/inference.go
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file shows some examples of type inference.
-
-package p
-
-type Ordered interface {
-	~int|~float64|~string
-}
-
-func min[T Ordered](x, y T) T { panic(0) }
-
-func _() {
-	// min can be called with explicit instantiation.
-	_ = min[int](1, 2)
-
-	// Alternatively, the type argument can be inferred from
-	// one of the arguments. Untyped arguments will be considered
-	// last.
-	var x int
-	_ = min(x, x)
-	_ = min(x, 1)
-	_ = min(x, 1.0)
-	_ = min(1, 2)
-	_ = min(1, 2.3 /* ERROR default type float64 .* does not match */ )
-
-	var y float64
-	_ = min(1, y)
-	_ = min(1.2, y)
-	_ = min(1.2, 3.4)
-	_ = min(1.2, 3 /* ERROR default type int .* does not match */ )
-
-	var s string
-	_ = min(s, "foo")
-	_ = min("foo", "bar")
-}
-
-func mixed[T1, T2, T3 any](T1, T2, T3) {}
-
-func _() {
-	// mixed can be called with explicit instantiation.
-	mixed[int, string, bool](0, "", false)
-
-	// Alternatively, partial type arguments may be provided
-	// (from left to right), and the other may be inferred.
-	mixed[int, string](0, "", false)
-	mixed[int](0, "", false)
-	mixed(0, "", false)
-
-	// Provided type arguments always take precedence over
-	// inferred types.
-	mixed[int, string](1.1 /* ERROR cannot use 1.1 */ , "", false)
-}
-
-func related1[Slice interface{~[]Elem}, Elem any](s Slice, e Elem) {}
-
-func _() {
-	// related1 can be called with explicit instantiation.
-	var si []int
-	related1[[]int, int](si, 0)
-
-	// Alternatively, the 2nd type argument can be inferred
-	// from the first one through constraint type inference.
-	var ss []string
-	_ = related1[[]string]
-	related1[[]string](ss, "foo")
-
-	// A type argument inferred from another explicitly provided
-	// type argument overrides whatever value argument type is given.
-	related1[[]string](ss, 0 /* ERROR cannot use 0 */ )
-
-	// A type argument may be inferred from a value argument
-	// and then help infer another type argument via constraint
-	// type inference.
-	related1(si, 0)
-	related1(si, "foo" /* ERROR cannot use "foo" */ )
-}
-
-func related2[Elem any, Slice interface{[]Elem}](e Elem, s Slice) {}
-
-func _() {
-	// related2 can be called with explicit instantiation.
-	var si []int
-	related2[int, []int](0, si)
-
-	// Alternatively, the 2nd type argument can be inferred
-	// from the first one through constraint type inference.
-	var ss []string
-	_ = related2[string]
-	related2[string]("foo", ss)
-
-	// A type argument may be inferred from a value argument
-	// and then help infer another type argument via constraint
-	// type inference. Untyped arguments are always considered
-	// last.
-	related2(1.2, []float64{})
-	related2(1.0, []int{})
-	related2 /* ERROR does not implement */ (float64(1.0), []int{}) // TODO(gri) fix error position
-}
-
-type List[P any] []P
-
-func related3[Elem any, Slice []Elem | List[Elem]]() Slice { return nil }
-
-func _() {
-	// related3 can be instantiated explicitly
-	related3[int, []int]()
-	related3[byte, List[byte]]()
-
-	// The 2nd type argument cannot be inferred from the first
-	// one because there's two possible choices: []Elem and
-	// List[Elem].
-	related3 /* ERROR cannot infer Slice */ [int]()
-}
diff --git a/src/go/types/testdata/examples/types.go b/src/go/types/testdata/examples/types.go
deleted file mode 100644
index 1e83f89..0000000
--- a/src/go/types/testdata/examples/types.go
+++ /dev/null
@@ -1,321 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file shows some examples of generic types.
-
-package p
-
-// List is just what it says - a slice of E elements.
-type List[E any] []E
-
-// A generic (parameterized) type must always be instantiated
-// before it can be used to designate the type of a variable
-// (including a struct field, or function parameter); though
-// for the latter cases, the provided type may be another type
-// parameter. So:
-var _ List[byte] = []byte{}
-
-// A generic binary tree might be declared as follows.
-type Tree[E any] struct {
-	left, right *Tree[E]
-	payload E
-}
-
-// A simple instantiation of Tree:
-var root1 Tree[int]
-
-// The actual type parameter provided may be a generic type itself:
-var root2 Tree[List[int]]
-
-// A couple of more complex examples.
-// We don't need extra parentheses around the element type of the slices on
-// the right (unlike when we use ()'s rather than []'s for type parameters).
-var _ List[List[int]] = []List[int]{}
-var _ List[List[List[Tree[int]]]] = []List[List[Tree[int]]]{}
-
-// Type parameters act like type aliases when used in generic types
-// in the sense that we can "emulate" a specific type instantiation
-// with type aliases.
-type T1[P any] struct {
-	f P
-}
-
-type T2[P any] struct {
-	f struct {
-		g P
-	}
-}
-
-var x1 T1[struct{ g int }]
-var x2 T2[int]
-
-func _() {
-	// This assignment is invalid because the types of x1, x2 are T1(...)
-	// and T2(...) respectively, which are two different defined types.
-	x1 = x2 // ERROR assignment
-
-	// This assignment is valid because the types of x1.f and x2.f are
-	// both struct { g int }; the type parameters act like type aliases
-	// and their actual names don't come into play here.
-	x1.f = x2.f
-}
-
-// We can verify this behavior using type aliases instead:
-type T1a struct {
-	f A1
-}
-type A1 = struct { g int }
-
-type T2a struct {
-	f struct {
-		g A2
-	}
-}
-type A2 = int
-
-var x1a T1a
-var x2a T2a
-
-func _() {
-	x1a = x2a // ERROR assignment
-	x1a.f = x2a.f
-}
-
-// Another interesting corner case are generic types that don't use
-// their type arguments. For instance:
-type T[P any] struct{}
-
-var xint T[int]
-var xbool T[bool]
-
-// Are these two variables of the same type? After all, their underlying
-// types are identical. We consider them to be different because each type
-// instantiation creates a new named type, in this case T<int> and T<bool>
-// even if their underlying types are identical. This is sensible because
-// we might still have methods that have different signatures or behave
-// differently depending on the type arguments, and thus we can't possibly
-// consider such types identical. Consequently:
-func _() {
-	xint = xbool // ERROR assignment
-}
-
-// Generic types cannot be used without instantiation.
-var _ T // ERROR cannot use generic type T
-var _ = T /* ERROR cannot use generic type T */ (0)
-
-// In type context, generic (parameterized) types cannot be parenthesized before
-// being instantiated. See also NOTES entry from 12/4/2019.
-var _ (T /* ERROR cannot use generic type T */ )[ /* ERROR expected ';' */ int]
-
-// All types may be parameterized, including interfaces.
-type I1[T any] interface{
-	m1(T)
-}
-
-// There is no such thing as a variadic generic type.
-type _[T ... /* ERROR invalid use of ... */ any] struct{}
-
-// Generic interfaces may be embedded as one would expect.
-type I2 interface {
-	I1(int)     // method!
-	I1[string]  // embedded I1
-}
-
-func _() {
-	var x I2
-	x.I1(0)
-	x.m1("foo")
-}
-
-type I0 interface {
-	m0()
-}
-
-type I3 interface {
-	I0
-	I1[bool]
-	m(string)
-}
-
-func _() {
-	var x I3
-	x.m0()
-	x.m1(true)
-	x.m("foo")
-}
-
-// We accept parenthesized embedded struct fields so we can distinguish between
-// a named field with a parenthesized type foo (T) and an embedded parameterized
-// type (foo(T)), similarly to interface embedding.
-// They still need to be valid embedded types after the parentheses are stripped
-// (i.e., in contrast to interfaces, we cannot embed a struct literal). The name
-// of the embedded field is derived as before, after stripping parentheses.
-// (7/14/2020: See comment above. We probably will revert this generalized ability
-// if we go with [] for type parameters.)
-type _ struct {
-	int8
-	*int16
-	*List[int]
-
-	int8 /* ERROR int8 redeclared */
-	* /* ERROR List redeclared */ List[int]
-}
-
-// Issue #45639: We don't allow this anymore. Keep this code
-//               in case we decide to revisit this decision.
-//
-// It's possible to declare local types whose underlying types
-// are type parameters. As with ordinary type definitions, the
-// types underlying properties are "inherited" but the methods
-// are not.
-//func _[T interface{ m(); ~int }]() {
-//	type L T
-//	var x L
-//
-//	// m is not defined on L (it is not "inherited" from
-//	// its underlying type).
-//	x.m /* ERROR x.m undefined */ ()
-//
-//	// But the properties of T, such that as that it supports
-//	// the operations of the types given by its type bound,
-//	// are also the properties of L.
-//	x++
-//	_ = x - x
-//
-//	// On the other hand, if we define a local alias for T,
-//	// that alias stands for T as expected.
-//	type A = T
-//	var y A
-//	y.m()
-//	_ = y < 0
-//}
-
-// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
-// // It is not permitted to declare a local type whose underlying
-// // type is a type parameter not declared by that type declaration.
-// func _[T any]() {
-// 	type _ T         // ERROR cannot use function type parameter T as RHS in type declaration
-// 	type _ [_ any] T // ERROR cannot use function type parameter T as RHS in type declaration
-// }
-
-// As a special case, an explicit type argument may be omitted
-// from a type parameter bound if the type bound expects exactly
-// one type argument. In that case, the type argument is the
-// respective type parameter to which the type bound applies.
-// Note: We may not permit this syntactic sugar at first.
-// Note: This is now disabled. All examples below are adjusted.
-type Adder[T any] interface {
-	Add(T) T
-}
-
-// We don't need to explicitly instantiate the Adder bound
-// if we have exactly one type parameter.
-func Sum[T Adder[T]](list []T) T {
-	var sum T
-	for _, x := range list {
-		sum = sum.Add(x)
-	}
-	return sum
-}
-
-// Valid and invalid variations.
-type B0 any
-type B1[_ any] any
-type B2[_, _ any] any
-
-func _[T1 B0]() {}
-func _[T1 B1[T1]]() {}
-func _[T1 B2 /* ERROR cannot use generic type .* without instantiation */ ]() {}
-
-func _[T1, T2 B0]() {}
-func _[T1 B1[T1], T2 B1[T2]]() {}
-func _[T1, T2 B2 /* ERROR cannot use generic type .* without instantiation */ ]() {}
-
-func _[T1 B0, T2 B1[T2]]() {} // here B1 applies to T2
-
-// When the type argument is left away, the type bound is
-// instantiated for each type parameter with that type
-// parameter.
-// Note: We may not permit this syntactic sugar at first.
-func _[A Adder[A], B Adder[B], C Adder[A]]() {
-	var a A // A's type bound is Adder[A]
-	a = a.Add(a)
-	var b B // B's type bound is Adder[B]
-	b = b.Add(b)
-	var c C // C's type bound is Adder[A]
-	a = c.Add(a)
-}
-
-// The type of variables (incl. parameters and return values) cannot
-// be an interface with type constraints or be/embed comparable.
-type I interface {
-	~int
-}
-
-var (
-	_ interface /* ERROR contains type constraints */ {~int}
-	_ I /* ERROR contains type constraints */
-)
-
-func _(I /* ERROR contains type constraints */ )
-func _(x, y, z I /* ERROR contains type constraints */ )
-func _() I /* ERROR contains type constraints */
-
-func _() {
-	var _ I /* ERROR contains type constraints */
-}
-
-type C interface {
-	comparable
-}
-
-var _ comparable /* ERROR comparable */
-var _ C /* ERROR comparable */
-
-func _(_ comparable /* ERROR comparable */ , _ C /* ERROR comparable */ )
-
-func _() {
-	var _ comparable /* ERROR comparable */
-	var _ C /* ERROR comparable */
-}
-
-// Type parameters are never const types, i.e., it's
-// not possible to declare a constant of type parameter type.
-// (If a type set contains just a single const type, we could
-// allow it, but such type sets don't make much sense in the
-// first place.)
-func _[T interface {~int|~float64}]() {
-	// not valid
-	const _ = T /* ERROR not constant */ (0)
-	const _ T /* ERROR invalid constant type T */ = 1
-
-	// valid
-	var _ = T(0)
-	var _ T = 1
-	_ = T(0)
-}
-
-// It is possible to create composite literals of type parameter
-// type as long as it's possible to create a composite literal
-// of the core type of the type parameter's constraint.
-func _[P interface{ ~[]int }]() P {
-	return P{}
-	return P{1, 2, 3}
-}
-
-func _[P interface{ ~[]E }, E interface{ map[string]P } ]() P {
-	x := P{}
-	return P{{}}
-	return P{E{}}
-	return P{E{"foo": x}}
-	return P{{"foo": x}, {}}
-}
-
-// This is a degenerate case with a singleton type set, but we can create
-// composite literals even if the core type is a defined type.
-type MyInts []int
-
-func _[P MyInts]() P {
-	return P{}
-}
diff --git a/src/go/types/testdata/examples/typesets.go b/src/go/types/testdata/examples/typesets.go
deleted file mode 100644
index fcddf1f..0000000
--- a/src/go/types/testdata/examples/typesets.go
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file shows some examples of constraint literals with elided interfaces.
-// These examples are permitted if proposal issue #48424 is accepted.
-
-package p
-
-// Constraint type sets of the form T, ~T, or A|B may omit the interface.
-type (
-	_[T int] struct{}
-	_[T ~int] struct{}
-	_[T int|string] struct{}
-	_[T ~int|~string] struct{}
-)
-
-func min[T int|string](x, y T) T {
-	if x < y {
-		return x
-	}
-	return y
-}
-
-func lookup[M ~map[K]V, K comparable, V any](m M, k K) V {
-	return m[k]
-}
-
-func deref[P ~*E, E any](p P) E {
-	return *p
-}
-
-func _() int {
-	p := new(int)
-	return deref(p)
-}
-
-func addrOfCopy[V any, P *V](v V) P {
-	return &v
-}
-
-func _() *int {
-	return addrOfCopy(0)
-}
-
-// A type parameter may not be embedded in an interface;
-// so it can also not be used as a constraint.
-func _[A any, B A /* ERROR cannot use a type parameter as constraint */ ]() {}
-
-// Error messages refer to the type constraint as it appears in the source.
-// (No implicit interface should be exposed.)
-func _[T string](x T) T {
-	return x /* ERROR constrained by string */ * x
-}
-
-func _[T int|string](x T) T {
-	return x /* ERROR constrained by int|string */ * x
-}
diff --git a/src/go/types/testdata/fixedbugs/issue39634.go b/src/go/types/testdata/fixedbugs/issue39634.go
deleted file mode 100644
index ce84299..0000000
--- a/src/go/types/testdata/fixedbugs/issue39634.go
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Examples adjusted to match new [T any] syntax for type parameters.
-// Also, previously permitted empty type parameter lists and instantiations
-// are now syntax errors.
-
-package p
-
-// crash 1
-type nt1[_ any]interface{g /* ERROR undeclared name */ }
-type ph1[e nt1[e],g(d /* ERROR undeclared name */ )]s /* ERROR undeclared name */
-func(*ph1[e,e /* ERROR redeclared */ ])h(d /* ERROR undeclared name */ )
-
-// crash 2
-// Disabled: empty []'s are now syntax errors. This example leads to too many follow-on errors.
-// type Numeric2 interface{t2 /* ERROR not a type */ }
-// func t2[T Numeric2](s[]T){0 /* ERROR not a type */ []{s /* ERROR cannot index */ [0][0]}}
-
-// crash 3
-type t3 *interface{ t3.p /* ERROR no field or method p */ }
-
-// crash 4
-type Numeric4 interface{t4 /* ERROR not a type */ }
-func t4[T Numeric4](s[]T){if( /* ERROR non-boolean */ 0){*s /* ERROR cannot indirect */ [0]}}
-
-// crash 7
-type foo7 interface { bar() }
-type x7[A any] struct{ foo7 }
-func main7() { var _ foo7 = x7[int]{} }
-
-// crash 8
-type foo8[A any] interface { ~A /* ERROR cannot be a type parameter */ }
-func bar8[A foo8[A]](a A) {}
-
-// crash 9
-type foo9[A any] interface { foo9 /* ERROR illegal cycle */ [A] }
-func _() { var _ = new(foo9[int]) }
-
-// crash 12
-var u /* ERROR cycle */ , i [func /* ERROR used as value */ /* ERROR used as value */ (u, c /* ERROR undeclared */ /* ERROR undeclared */ ) {}(0, len /* ERROR must be called */ /* ERROR must be called */ )]c /* ERROR undeclared */ /* ERROR undeclared */
-
-// crash 15
-func y15() { var a /* ERROR declared but not used */ interface{ p() } = G15[string]{} }
-type G15[X any] s /* ERROR undeclared name */
-func (G15 /* ERROR generic type .* without instantiation */ ) p()
-
-// crash 16
-type Foo16[T any] r16 /* ERROR not a type */
-func r16[T any]() Foo16[Foo16[T]] { panic(0) }
-
-// crash 17
-type Y17 interface{ c() }
-type Z17 interface {
-	c() Y17
-	Y17 /* ERROR duplicate method */
-}
-func F17[T Z17](T) {}
-
-// crash 18
-type o18[T any] []func(_ o18[[]_ /* ERROR cannot use _ */ ])
-
-// crash 19
-type Z19 [][[]Z19{}[0][0]]c19 /* ERROR undeclared */
-
-// crash 20
-type Z20 /* ERROR illegal cycle */ interface{ Z20 }
-func F20[t Z20]() { F20(t /* ERROR invalid composite literal type */ {}) }
-
-// crash 21
-type Z21 /* ERROR illegal cycle */ interface{ Z21 }
-func F21[T Z21]() { ( /* ERROR not used */ F21[Z21]) }
-
-// crash 24
-type T24[P any] P // ERROR cannot use a type parameter as RHS in type declaration
-func (r T24[P]) m() { T24 /* ERROR without instantiation */ .m() }
-
-// crash 25
-type T25[A any] int
-func (t T25[A]) m1() {}
-var x T25 /* ERROR without instantiation */ .m1
-
-// crash 26
-type T26 = interface{ F26[ /* ERROR interface method must have no type parameters */ Z any]() }
-// The error messages on the line below differ from types2 because for backward
-// compatibility go/parser must produce an IndexExpr with BadExpr index for the
-// expression F26[].
-func F26[Z any]() T26 { return F26[] /* ERROR operand */ }
-
-// crash 27
-func e27[T any]() interface{ x27 /* ERROR not a type */ } { panic(0) }
-func x27() { e27 /* ERROR cannot infer T */ () }
diff --git a/src/go/types/testdata/fixedbugs/issue39693.go b/src/go/types/testdata/fixedbugs/issue39693.go
deleted file mode 100644
index ec76419..0000000
--- a/src/go/types/testdata/fixedbugs/issue39693.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type Number1 interface {
-	// embedding non-interface types is permitted
-	int
-	float64
-}
-
-func Add[T Number1](a, b T) T {
-	return a /* ERROR not defined */ + b
-}
-
-type Number2 interface {
-	int|float64
-}
-
-func Add2[T Number2](a, b T) T {
-	return a + b
-}
diff --git a/src/go/types/testdata/fixedbugs/issue39754.go b/src/go/types/testdata/fixedbugs/issue39754.go
deleted file mode 100644
index 9edd239..0000000
--- a/src/go/types/testdata/fixedbugs/issue39754.go
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.

-// Use of this source code is governed by a BSD-style

-// license that can be found in the LICENSE file.

-

-package p

-

-type Optional[T any] struct {}

-

-func (_ Optional[T]) Val() (T, bool)

-

-type Box[T any] interface {

-	Val() (T, bool)

-}

-

-func f[V interface{}, A, B Box[V]]() {}

-

-func _() {

-	f[int, Optional[int], Optional[int]]()

-	_ = f[int, Optional[int], Optional /* ERROR does not implement Box */ [string]]

-	_ = f[int, Optional[int], Optional /* ERROR Optional.* does not implement Box.* */ [string]]

-}

diff --git a/src/go/types/testdata/fixedbugs/issue39938.go b/src/go/types/testdata/fixedbugs/issue39938.go
deleted file mode 100644
index 6bc9284..0000000
--- a/src/go/types/testdata/fixedbugs/issue39938.go
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-// All but E2 and E5 provide an "indirection" and break infinite expansion of a type.
-type E0[P any] []P
-type E1[P any] *P
-type E2[P any] struct{ _ P }
-type E3[P any] struct{ _ *P }
-type E5[P any] struct{ _ [10]P }
-
-type T0 struct {
-        _ E0[T0]
-}
-
-type T0_ struct {
-        E0[T0_]
-}
-
-type T1 struct {
-        _ E1[T1]
-}
-
-type T2 /* ERROR illegal cycle */ struct {
-        _ E2[T2]
-}
-
-type T3 struct {
-        _ E3[T3]
-}
-
-type T4 /* ERROR illegal cycle */ [10]E5[T4]
-
-type T5 struct {
-	_ E0[E2[T5]]
-}
-
-type T6 struct {
-	_ E0[E2[E0[E1[E2[[10]T6]]]]]
-}
-
-type T7 struct {
-	_ E0[[10]E2[E0[E2[E2[T7]]]]]
-}
-
-type T8 struct {
-	_ E0[[]E2[E0[E2[E2[T8]]]]]
-}
-
-type T9 /* ERROR illegal cycle */ [10]E2[E5[E2[T9]]]
-
-type T10 [10]E2[E5[E2[func(T10)]]]
diff --git a/src/go/types/testdata/fixedbugs/issue40350.go b/src/go/types/testdata/fixedbugs/issue40350.go
deleted file mode 100644
index 7ffd551..0000000
--- a/src/go/types/testdata/fixedbugs/issue40350.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type number interface {
-	~float64 | ~int | ~int32
-	float64 | ~int32
-}
-
-func f[T number]() {}
-
-func _() {
-	_ = f[int /* ERROR int does not implement number \(int missing in float64 | ~int32\)*/]
-}
diff --git a/src/go/types/testdata/fixedbugs/issue41124.go b/src/go/types/testdata/fixedbugs/issue41124.go
deleted file mode 100644
index 4550dd7..0000000
--- a/src/go/types/testdata/fixedbugs/issue41124.go
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-// Test case from issue.
-
-type Nat /* ERROR cycle */ interface {
-	Zero|Succ
-}
-
-type Zero struct{}
-type Succ struct{
-	Nat // Nat contains type constraints but is invalid, so no error
-}
-
-// Struct tests.
-
-type I1 interface {
-	comparable
-}
-
-type I2 interface {
-	~int
-}
-
-type I3 interface {
-	I1
-	I2
-}
-
-type _ struct {
-	f I1 // ERROR interface is .* comparable
-}
-
-type _ struct {
-	comparable // ERROR interface is .* comparable
-}
-
-type _ struct{
-	I1 // ERROR interface is .* comparable
-}
-
-type _ struct{
-	I2 // ERROR interface contains type constraints
-}
-
-type _ struct{
-	I3 // ERROR interface contains type constraints
-}
-
-// General composite types.
-
-type (
-	_ [10]I1 // ERROR interface is .* comparable
-	_ [10]I2 // ERROR interface contains type constraints
-
-	_ []I1 // ERROR interface is .* comparable
-	_ []I2 // ERROR interface contains type constraints
-
-	_ *I3 // ERROR interface contains type constraints
-	_ map[I1 /* ERROR interface is .* comparable */ ]I2 // ERROR interface contains type constraints
-	_ chan I3 // ERROR interface contains type constraints
-	_ func(I1 /* ERROR interface is .* comparable */ )
-	_ func() I2 // ERROR interface contains type constraints
-)
-
-// Other cases.
-
-var _ = [...]I3 /* ERROR interface contains type constraints */ {}
-
-func _(x interface{}) {
-	_ = x.(I3 /* ERROR interface contains type constraints */ )
-}
-
-type T1[_ any] struct{}
-type T3[_, _, _ any] struct{}
-var _ T1[I2 /* ERROR interface contains type constraints */ ]
-var _ T3[int, I2 /* ERROR interface contains type constraints */ , float32]
-
-func f1[_ any]() int { panic(0) }
-var _ = f1[I2 /* ERROR interface contains type constraints */ ]()
-func f3[_, _, _ any]() int { panic(0) }
-var _ = f3[int, I2 /* ERROR interface contains type constraints */ , float32]()
-
-func _(x interface{}) {
-	switch x.(type) {
-	case I2 /* ERROR interface contains type constraints */ :
-	}
-}
diff --git a/src/go/types/testdata/fixedbugs/issue42987.go b/src/go/types/testdata/fixedbugs/issue42987.go
deleted file mode 100644
index 6060ec8..0000000
--- a/src/go/types/testdata/fixedbugs/issue42987.go
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Check that there is only one error (no follow-on errors).
-
-package p
-// TODO(rFindley) This is a parser error, but in types2 it is a type checking
-//                error. We could probably do without this check in the parser.
-var _ = [... /* ERROR expected array length, found '...' */ ]byte("foo")
diff --git a/src/go/types/testdata/fixedbugs/issue43087.go b/src/go/types/testdata/fixedbugs/issue43087.go
deleted file mode 100644
index ef37b4a..0000000
--- a/src/go/types/testdata/fixedbugs/issue43087.go
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func _() {
-	a, b, b /* ERROR b repeated on left side of := */ := 1, 2, 3
-	_ = a
-	_ = b
-}
-
-func _() {
-	a, _, _ := 1, 2, 3 // multiple _'s ok
-	_ = a
-}
-
-func _() {
-	var b int
-	a, b, b /* ERROR b repeated on left side of := */ := 1, 2, 3
-	_ = a
-	_ = b
-}
-
-func _() {
-	var a []int
-	a /* ERROR expected identifier */ /* ERROR non-name .* on left side of := */ [0], b := 1, 2
-	_ = a
-	_ = b
-}
-
-func _() {
-	var a int
-	a, a /* ERROR a repeated on left side of := */ := 1, 2
-	_ = a
-}
-
-func _() {
-	var a, b int
-	a, b := /* ERROR no new variables on left side of := */ 1, 2
-	_ = a
-	_ = b
-}
diff --git a/src/go/types/testdata/fixedbugs/issue43109.go b/src/go/types/testdata/fixedbugs/issue43109.go
deleted file mode 100644
index a4533c9..0000000
--- a/src/go/types/testdata/fixedbugs/issue43109.go
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Ensure there is no "imported but not used" error
-// if a package wasn't imported in the first place.
-
-package p
-
-import . "/foo" // ERROR could not import \/foo
diff --git a/src/go/types/testdata/fixedbugs/issue43190.go b/src/go/types/testdata/fixedbugs/issue43190.go
deleted file mode 100644
index 96acb3a..0000000
--- a/src/go/types/testdata/fixedbugs/issue43190.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Most of the errors below are actually produced by the parser, but we check
-// them here for consistency with the types2 tests.
-
-package p
-
-import ; /* ERROR invalid import path */ /* ERROR expected 'STRING' */
-import // ERROR expected ';'
-var _ int
-import /* ERROR expected declaration */ .;
-
-import ()
-import (.)
-import (
-	"fmt"
-	.
-)
-
-var _ = fmt /* ERROR "undeclared name" */ .Println
diff --git a/src/go/types/testdata/fixedbugs/issue43527.go b/src/go/types/testdata/fixedbugs/issue43527.go
deleted file mode 100644
index 2955c26..0000000
--- a/src/go/types/testdata/fixedbugs/issue43527.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-const L = 10
-
-type (
-	_        [L]struct{}
-	_        [A /* ERROR undeclared name A for array length */ ]struct{}
-	_        [B /* ERROR invalid array length B */ ]struct{}
-	_[A any] struct{}
-
-	B int
-)
diff --git a/src/go/types/testdata/fixedbugs/issue43671.go b/src/go/types/testdata/fixedbugs/issue43671.go
deleted file mode 100644
index 3c78f85..0000000
--- a/src/go/types/testdata/fixedbugs/issue43671.go
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type C0 interface{ int }
-type C1 interface{ chan int }
-type C2 interface{ chan int | <-chan int }
-type C3 interface{ chan int | chan float32 }
-type C4 interface{ chan int | chan<- int }
-type C5[T any] interface{ ~chan T | <-chan T }
-
-func _[T any](ch T) {
-	<-ch // ERROR cannot receive from ch .* no core type
-}
-
-func _[T C0](ch T) {
-	<-ch // ERROR cannot receive from non-channel ch
-}
-
-func _[T C1](ch T) {
-	<-ch
-}
-
-func _[T C2](ch T) {
-	<-ch
-}
-
-func _[T C3](ch T) {
-	<-ch // ERROR cannot receive from ch .* no core type
-}
-
-func _[T C4](ch T) {
-	<-ch // ERROR cannot receive from send-only channel
-}
-
-func _[T C5[X], X any](ch T, x X) {
-	x = <-ch
-}
-
-// test case from issue, slightly modified
-type RecvChan[T any] interface {
-	~chan T | ~<-chan T
-}
-
-func _[T any, C RecvChan[T]](ch C) T {
-	return <-ch
-}
-
-func f[T any, C interface{ chan T }](ch C) T {
-	return <-ch
-}
-
-func _(ch chan int) {
-	var x int = f(ch) // test constraint type inference for this case
-	_ = x
-}
diff --git a/src/go/types/testdata/fixedbugs/issue45550.go b/src/go/types/testdata/fixedbugs/issue45550.go
deleted file mode 100644
index 3eeaca0..0000000
--- a/src/go/types/testdata/fixedbugs/issue45550.go
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type Builder /* ERROR illegal cycle */ [T interface{ struct{ Builder[T] } }] struct{}
-type myBuilder struct {
-	Builder[myBuilder]
-}
diff --git a/src/go/types/testdata/fixedbugs/issue45635.go b/src/go/types/testdata/fixedbugs/issue45635.go
deleted file mode 100644
index fc50797..0000000
--- a/src/go/types/testdata/fixedbugs/issue45635.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-func main() {
-	some /* ERROR "undeclared name" */ [int, int]()
-}
-
-type N[T any] struct{}
-
-var _ N [] // ERROR expected type argument list
-
-type I interface {
-	~[]int
-}
-
-func _[T I](i, j int) {
-	var m map[int]int
-	_ = m[i, j /* ERROR "more than one index" */ ]
-
-	var a [3]int
-	_ = a[i, j /* ERROR "more than one index" */ ]
-
-	var s []int
-	_ = s[i, j /* ERROR "more than one index" */ ]
-
-	var t T
-	_ = t[i, j /* ERROR "more than one index" */ ]
-}
diff --git a/src/go/types/testdata/fixedbugs/issue45920.go b/src/go/types/testdata/fixedbugs/issue45920.go
deleted file mode 100644
index a0e2d0c..0000000
--- a/src/go/types/testdata/fixedbugs/issue45920.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func f1[T any, C chan T | <-chan T](ch C) {}
-
-func _(ch chan int)   { f1(ch) }
-func _(ch <-chan int) { f1(ch) }
-func _(ch chan<- int) { f1 /* ERROR chan<- int does not implement chan int\|<-chan int */ (ch) }
-
-func f2[T any, C chan T | chan<- T](ch C) {}
-
-func _(ch chan int)   { f2(ch) }
-func _(ch <-chan int) { f2 /* ERROR <-chan int does not implement chan int\|chan<- int */ (ch) }
-func _(ch chan<- int) { f2(ch) }
diff --git a/src/go/types/testdata/fixedbugs/issue45985.go b/src/go/types/testdata/fixedbugs/issue45985.go
deleted file mode 100644
index 9a0f5e3..0000000
--- a/src/go/types/testdata/fixedbugs/issue45985.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package issue45985
-
-func app[S interface{ ~[]T }, T any](s S, e T) S {
-    return append(s, e)
-}
-
-func _() {
-	_ = app/* ERROR "S does not match" */[int]
-}
diff --git a/src/go/types/testdata/fixedbugs/issue46275.go b/src/go/types/testdata/fixedbugs/issue46275.go
deleted file mode 100644
index 0ebde31..0000000
--- a/src/go/types/testdata/fixedbugs/issue46275.go
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package issue46275
-
-type N[T any] struct {
-        *N[T]
-        t T
-}
-
-func (n *N[T]) Elem() T {
-        return n.t
-}
-
-type I interface {
-        Elem() string
-}
-
-func _() {
-        var n1 *N[string]
-        var _ I = n1
-        type NS N[string]
-        var n2 *NS
-        var _ I = n2
-}
-
diff --git a/src/go/types/testdata/fixedbugs/issue46404.go1 b/src/go/types/testdata/fixedbugs/issue46404.go1
deleted file mode 100644
index db604bc..0000000
--- a/src/go/types/testdata/fixedbugs/issue46404.go1
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package issue46404
-
-// Check that we don't type check t[_] as an instantiation.
-type t [t /* ERROR not a type */ [_]]_ // ERROR cannot use
diff --git a/src/go/types/testdata/fixedbugs/issue46461.go b/src/go/types/testdata/fixedbugs/issue46461.go
deleted file mode 100644
index 4432402..0000000
--- a/src/go/types/testdata/fixedbugs/issue46461.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-// test case 1
-type T /* ERROR illegal cycle */ [U interface{ M() T[U] }] int
-
-type X int
-
-func (X) M() T[X] { return 0 }
-
-// test case 2
-type A /* ERROR illegal cycle */ [T interface{ A[T] }] interface{}
-
-// test case 3
-type A2 /* ERROR illegal cycle */ [U interface{ A2[U] }] interface{ M() A2[U] }
-
-type I interface{ A2[I]; M() A2[I] }
diff --git a/src/go/types/testdata/fixedbugs/issue47411.go b/src/go/types/testdata/fixedbugs/issue47411.go
deleted file mode 100644
index db5fb32..0000000
--- a/src/go/types/testdata/fixedbugs/issue47411.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func f[_ comparable]() {}
-func g[_ interface{interface{comparable; ~int|~string}}]() {}
-
-func _[P comparable,
-        Q interface{ comparable; ~int|~string },
-        R any,                               // not comparable
-        S interface{ comparable; ~func() },  // not comparable
-]() {
-        _ = f[int]
-        _ = f[P]
-        _ = f[Q]
-        _ = f[func /* ERROR does not implement comparable */ ()]
-        _ = f[R /* ERROR R does not implement comparable */ ]
-
-        _ = g[int]
-        _ = g[P /* ERROR P does not implement interface{interface{comparable; ~int\|~string} */ ]
-        _ = g[Q]
-        _ = g[func /* ERROR func\(\) does not implement interface{interface{comparable; ~int\|~string}} */ ()]
-        _ = g[R /* ERROR R does not implement interface{interface{comparable; ~int\|~string} */ ]
-}
diff --git a/src/go/types/testdata/fixedbugs/issue47796.go b/src/go/types/testdata/fixedbugs/issue47796.go
deleted file mode 100644
index 6667ba4..0000000
--- a/src/go/types/testdata/fixedbugs/issue47796.go
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-// parameterized types with self-recursive constraints
-type (
-	T1 /* ERROR illegal cycle */ [P T1[P]]                            interface{}
-	T2 /* ERROR illegal cycle */ [P, Q T2[P, Q]]                      interface{}
-	T3[P T2[P, Q], Q interface{ ~string }] interface{}
-
-	T4a /* ERROR illegal cycle */ [P T4a[P]]                                                        interface{ ~int }
-	T4b /* ERROR illegal cycle */ [P T4b[int]]                                                      interface{ ~int }
-	T4c /* ERROR illegal cycle */ [P T4c[string]] interface{ ~int }
-
-	// mutually recursive constraints
-	T5 /* ERROR illegal cycle */ [P T6[P]] interface{ int }
-	T6[P T5[P]] interface{ int }
-)
-
-// verify that constraints are checked as expected
-var (
-	_ T1[int]
-	_ T2[int, string]
-	_ T3[int, string]
-)
-
-// test case from issue
-
-type Eq /* ERROR illegal cycle */ [a Eq[a]] interface {
-	Equal(that a) bool
-}
diff --git a/src/go/types/testdata/fixedbugs/issue47818.go b/src/go/types/testdata/fixedbugs/issue47818.go
deleted file mode 100644
index 2db095c..0000000
--- a/src/go/types/testdata/fixedbugs/issue47818.go
+++ /dev/null
@@ -1,59 +0,0 @@
-// -lang=go1.17
-
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Parser accepts type parameters but the type checker
-// needs to report any operations that are not permitted
-// before Go 1.18.
-
-package p
-
-type T[P /* ERROR type parameters require go1\.18 or later */ any /* ERROR predeclared any requires go1\.18 or later */ ] struct{}
-
-// for init (and main, but we're not in package main) we should only get one error
-func init[P /* ERROR func init must have no type parameters */ any /* ERROR predeclared any requires go1\.18 or later */ ]()   {}
-func main[P /* ERROR type parameters require go1\.18 or later */ any /* ERROR predeclared any requires go1\.18 or later */ ]() {}
-
-func f[P /* ERROR type parameters require go1\.18 or later */ any /* ERROR predeclared any requires go1\.18 or later */ ](x P) {
-	var _ T[ /* ERROR type instantiation requires go1\.18 or later */ int]
-	var _ (T[ /* ERROR type instantiation requires go1\.18 or later */ int])
-	_ = T[ /* ERROR type instantiation requires go1\.18 or later */ int]{}
-	_ = T[ /* ERROR type instantiation requires go1\.18 or later */ int](struct{}{})
-}
-
-func (T[ /* ERROR type instantiation requires go1\.18 or later */ P]) g(x int) {
-	f[ /* ERROR function instantiation requires go1\.18 or later */ int](0)     // explicit instantiation
-	(f[ /* ERROR function instantiation requires go1\.18 or later */ int])(0)   // parentheses (different code path)
-	f( /* ERROR implicit function instantiation requires go1\.18 or later */ x) // implicit instantiation
-}
-
-type C1 interface {
-	comparable // ERROR predeclared comparable requires go1\.18 or later
-}
-
-type C2 interface {
-	comparable // ERROR predeclared comparable requires go1\.18 or later
-	int        // ERROR embedding non-interface type int requires go1\.18 or later
-	~ /* ERROR embedding interface element ~int requires go1\.18 or later */ int
-	int /* ERROR embedding interface element int\|~string requires go1\.18 or later */ | ~string
-}
-
-type _ interface {
-	// errors for these were reported with their declaration
-	C1
-	C2
-}
-
-type (
-	_ comparable // ERROR predeclared comparable requires go1\.18 or later
-	// errors for these were reported with their declaration
-	_ C1
-	_ C2
-
-	_ = comparable // ERROR predeclared comparable requires go1\.18 or later
-	// errors for these were reported with their declaration
-	_ = C1
-	_ = C2
-)
diff --git a/src/go/types/testdata/fixedbugs/issue48529.go b/src/go/types/testdata/fixedbugs/issue48529.go
deleted file mode 100644
index a3653fa..0000000
--- a/src/go/types/testdata/fixedbugs/issue48529.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type T /* ERROR illegal cycle */ [U interface{ M() T[U, int] }] int
-
-type X int
-
-func (X) M() T[X] { return 0 }
diff --git a/src/go/types/testdata/fixedbugs/issue48582.go b/src/go/types/testdata/fixedbugs/issue48582.go
deleted file mode 100644
index c12091b..0000000
--- a/src/go/types/testdata/fixedbugs/issue48582.go
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type N /* ERROR cycle */ interface {
-	int | N
-}
-
-type A /* ERROR cycle */ interface {
-	int | B
-}
-
-type B interface {
-	int | A
-}
-
-type S /* ERROR cycle */ struct {
-	I // ERROR interface contains type constraints
-}
-
-type I interface {
-	int | S
-}
-
-type P interface {
-	*P // ERROR interface contains type constraints
-}
diff --git a/src/go/types/testdata/fixedbugs/issue48695.go b/src/go/types/testdata/fixedbugs/issue48695.go
deleted file mode 100644
index 2d9e6a5..0000000
--- a/src/go/types/testdata/fixedbugs/issue48695.go
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func g[P interface{~func(T) P}, T any](P) {}
-
-func _() {
-	type F func(int) F
-	var f F
-	g(f)
-	_ = g[F]
-}
diff --git a/src/go/types/testdata/fixedbugs/issue48819.go b/src/go/types/testdata/fixedbugs/issue48819.go
deleted file mode 100644
index 9262110..0000000
--- a/src/go/types/testdata/fixedbugs/issue48819.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-import "unsafe"
-
-type T /* ERROR illegal cycle in declaration of T */ struct {
-	T
-}
-
-func _(t T) {
-	_ = unsafe.Sizeof(t) // should not go into infinite recursion here
-}
diff --git a/src/go/types/testdata/fixedbugs/issue48951.go b/src/go/types/testdata/fixedbugs/issue48951.go
deleted file mode 100644
index a936528..0000000
--- a/src/go/types/testdata/fixedbugs/issue48951.go
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type (
-        A1[P any] [10]A1 /* ERROR illegal cycle */ [P]
-        A2[P any] [10]A2 /* ERROR illegal cycle */ [*P]
-        A3[P any] [10]*A3[P]
-
-        L1[P any] []L1[P]
-
-        S1[P any] struct{ f S1 /* ERROR illegal cycle */ [P] }
-        S2[P any] struct{ f S2 /* ERROR illegal cycle */ [*P] } // like example in issue
-        S3[P any] struct{ f *S3[P] }
-
-        I1[P any] interface{ I1 /* ERROR illegal cycle */ [P] }
-        I2[P any] interface{ I2 /* ERROR illegal cycle */ [*P] }
-        I3[P any] interface{ *I3 /* ERROR interface contains type constraints */ [P] }
-)
diff --git a/src/go/types/testdata/fixedbugs/issue48962.go b/src/go/types/testdata/fixedbugs/issue48962.go
deleted file mode 100644
index 4270da1..0000000
--- a/src/go/types/testdata/fixedbugs/issue48962.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type T0[P any] struct {
-	f P
-}
-
-type T1 /* ERROR illegal cycle */ struct {
-	_ T0[T1]
-}
diff --git a/src/go/types/testdata/fixedbugs/issue49005.go b/src/go/types/testdata/fixedbugs/issue49005.go
deleted file mode 100644
index 7083dc9..0000000
--- a/src/go/types/testdata/fixedbugs/issue49005.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type T1 interface{ M() }
-
-func F1() T1
-
-var _ = F1().(*X1 /* ERROR undeclared name: X1 */)
-
-func _() {
-	switch F1().(type) {
-	case *X1 /* ERROR undeclared name: X1 */ :
-	}
-}
-
-type T2 interface{ M() }
-
-func F2() T2
-
-var _ = F2 /* ERROR impossible type assertion: F2\(\)\.\(\*X2\)\n\t\*X2 does not implement T2 \(missing method M\) */ ().(*X2)
-
-type X2 struct{}
-
-func _() {
-	switch F2().(type) {
-	case * /* ERROR impossible type switch case: \*X2\n\tF2\(\) \(value of type T2\) cannot have dynamic type \*X2 \(missing method M\) */ X2:
-	}
-}
diff --git a/src/go/types/testdata/fixedbugs/issue49043.go b/src/go/types/testdata/fixedbugs/issue49043.go
deleted file mode 100644
index a360457..0000000
--- a/src/go/types/testdata/fixedbugs/issue49043.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-// The example from the issue.
-type (
-	N[P any] M /* ERROR illegal cycle */ [P]
-	M[P any] N /* ERROR illegal cycle */ [P]
-)
-
-// A slightly more complicated case.
-type (
-	A[P any] B /* ERROR illegal cycle */ [P]
-	B[P any] C[P]
-	C[P any] A[P]
-)
-
-// Confusing but valid (note that `type T *T` is valid).
-type (
-	N1[P any] *M1[P]
-	M1[P any] *N1[P]
-)
diff --git a/src/go/types/testdata/fixedbugs/issue49112.go b/src/go/types/testdata/fixedbugs/issue49112.go
deleted file mode 100644
index 61b757c..0000000
--- a/src/go/types/testdata/fixedbugs/issue49112.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func f[P int](P) {}
-
-func _() {
-        _ = f[int]
-        _ = f[[ /* ERROR \[\]int does not implement int */ ]int]
-
-        f(0)
-        f/* ERROR \[\]int does not implement int */ ([]int{})
-}
diff --git a/src/go/types/testdata/fixedbugs/issue49179.go b/src/go/types/testdata/fixedbugs/issue49179.go
deleted file mode 100644
index d4c8a89..0000000
--- a/src/go/types/testdata/fixedbugs/issue49179.go
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func f1[P int | string]()            {}
-func f2[P ~int | string | float64]() {}
-func f3[P int](x P)                  {}
-
-type myInt int
-type myFloat float64
-
-func _() {
-	_ = f1[int]
-	_ = f1[myInt /* ERROR possibly missing ~ for int in constraint int\|string */]
-	_ = f2[myInt]
-	_ = f2[myFloat /* ERROR possibly missing ~ for float64 in constraint int\|string|float64 */]
-	var x myInt
-	f3 /* ERROR myInt does not implement int \(possibly missing ~ for int in constraint int\) */ (x)
-}
-
-// test case from the issue
-
-type SliceConstraint[T any] interface {
-	[]T
-}
-
-func Map[S SliceConstraint[E], E any](s S, f func(E) E) S {
-	return s
-}
-
-type MySlice []int
-
-func f(s MySlice) {
-	Map[MySlice /* ERROR MySlice does not implement SliceConstraint\[int\] \(possibly missing ~ for \[\]int in constraint SliceConstraint\[int\]\) */, int](s, nil)
-}
diff --git a/src/go/types/testdata/fixedbugs/issue49247.go b/src/go/types/testdata/fixedbugs/issue49247.go
deleted file mode 100644
index 3f25e0e..0000000
--- a/src/go/types/testdata/fixedbugs/issue49247.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type integer interface {
-	~int | ~int8 | ~int16 | ~int32 | ~int64 |
-		~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
-}
-
-func Add1024[T integer](s []T) {
-	for i, v := range s {
-		s[i] = v + 1024 // ERROR cannot convert 1024 \(untyped int constant\) to T
-	}
-}
-
-func f[T interface{ int8 }]() {
-	println(T(1024 /* ERROR cannot convert 1024 \(untyped int value\) to T */))
-}
diff --git a/src/go/types/testdata/fixedbugs/issue49276.go b/src/go/types/testdata/fixedbugs/issue49276.go
deleted file mode 100644
index 8839087..0000000
--- a/src/go/types/testdata/fixedbugs/issue49276.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-import "unsafe"
-
-type S /* ERROR illegal cycle in declaration of S */ struct {
-	_ [unsafe.Sizeof(s)]byte
-}
-
-var s S
-
-// Since f is a pointer, this case could be valid.
-// But it's pathological and not worth the expense.
-type T struct {
-	f *[unsafe.Sizeof(T /* ERROR illegal cycle in type declaration */ {})]int
-}
-
-// a mutually recursive case using unsafe.Sizeof
-type (
-	A1 struct {
-		_ [unsafe.Sizeof(B1{})]int
-	}
-
-	B1 struct {
-		_ [unsafe.Sizeof(A1 /* ERROR illegal cycle in type declaration */ {})]int
-	}
-)
-
-// a mutually recursive case using len
-type (
-	A2 struct {
-		f [len(B2{}.f)]int
-	}
-
-	B2 struct {
-		f [len(A2 /* ERROR illegal cycle in type declaration */ {}.f)]int
-	}
-)
-
-// test case from issue
-type a struct {
-	_ [42 - unsafe.Sizeof(a /* ERROR illegal cycle in type declaration */ {})]byte
-}
diff --git a/src/go/types/testdata/fixedbugs/issue49296.go b/src/go/types/testdata/fixedbugs/issue49296.go
deleted file mode 100644
index 0ad71ef..0000000
--- a/src/go/types/testdata/fixedbugs/issue49296.go
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func _[
-        T0 any,
-        T1 []int,
-        T2 ~float64 | ~complex128 | chan int,
-]() {
-	// TODO(rfindley): the types2 error here is clearer.
-        _ = T0(nil /* ERROR cannot convert nil to T0 */ )
-        _ = T1(1 /* ERROR cannot convert 1 .* to T1 */ )
-        _ = T2(2 /* ERROR cannot convert 2 .* to T2 */ )
-}
-
-// test case from issue
-func f[T interface{[]int}]() {
-	_ = T(1 /* ERROR cannot convert */ )
-}
diff --git a/src/go/types/testdata/fixedbugs/issue49439.go b/src/go/types/testdata/fixedbugs/issue49439.go
deleted file mode 100644
index 6cc838b..0000000
--- a/src/go/types/testdata/fixedbugs/issue49439.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-import "unsafe"
-
-type T0 /* ERROR illegal cycle */ [P T0[P]] struct{}
-
-type T1 /* ERROR illegal cycle */ [P T2[P]] struct{}
-type T2[P T1[P]] struct{}
-
-type T3 /* ERROR illegal cycle */ [P interface{ ~struct{ f T3[int] } }] struct{}
-
-// valid cycle in M
-type N[P M[P]] struct{}
-type M[Q any] struct { F *M[Q] }
-
-// "crazy" case
-type TC[P [unsafe.Sizeof(func() {
-        type T [P [unsafe.Sizeof(func(){})]byte] struct{}
-})]byte] struct{}
-
-// test case from issue
-type X /* ERROR illegal cycle */ [T any, PT X[T]] interface{}
diff --git a/src/go/types/testdata/fixedbugs/issue49482.go b/src/go/types/testdata/fixedbugs/issue49482.go
deleted file mode 100644
index d5c52dc..0000000
--- a/src/go/types/testdata/fixedbugs/issue49482.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-// The following is OK, per the special handling for type literals discussed in issue #49482.
-type _[P *struct{}] struct{}
-type _[P *int,] int
-type _[P (*int),] int
-
-const P = 2 // declare P to avoid noisy 'undeclared name' errors below.
-
-// The following parse as invalid array types due to parsing ambiguitiues.
-type _ [P *int /* ERROR "int \(type\) is not an expression" */ ]int
-type _ [P /* ERROR non-function P */ (*int)]int
-
-// Adding a trailing comma or an enclosing interface resolves the ambiguity.
-type _[P *int,] int
-type _[P (*int),] int
-type _[P interface{*int}] int
-type _[P interface{(*int)}] int
-
-// The following parse correctly as valid generic types.
-type _[P *struct{} | int] struct{}
-type _[P *struct{} | ~int] struct{}
diff --git a/src/go/types/testdata/fixedbugs/issue49579.go b/src/go/types/testdata/fixedbugs/issue49579.go
deleted file mode 100644
index 07748bd..0000000
--- a/src/go/types/testdata/fixedbugs/issue49579.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type I[F any] interface {
-	Q(*F)
-}
-
-func G[F any]() I[any] {
-	return g /* ERROR cannot use \(g\[F\] literal\) .* as I\[any\] value in return statement: g\[F\] does not implement I\[any\] \(method Q has pointer receiver\) */ [F]{}
-}
-
-type g[F any] struct{}
-
-func (*g[F]) Q(*any) {}
diff --git a/src/go/types/testdata/fixedbugs/issue49739.go b/src/go/types/testdata/fixedbugs/issue49739.go
deleted file mode 100644
index 46b1e71..0000000
--- a/src/go/types/testdata/fixedbugs/issue49739.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Verify that we get an empty type set (not just an error)
-// when using an invalid ~A.
-
-package p
-
-type A int
-type C interface {
-	~ /* ERROR invalid use of ~ */ A
-}
-
-func f[_ C]()              {}
-func g[_ interface{ C }]() {}
-func h[_ C | int]()        {}
-
-func _() {
-	_ = f[int /* ERROR cannot implement C \(empty type set\) */]
-	_ = g[int /* ERROR cannot implement interface{C} \(empty type set\) */]
-	_ = h[int]
-}
diff --git a/src/go/types/testdata/fixedbugs/issue50417.go b/src/go/types/testdata/fixedbugs/issue50417.go
deleted file mode 100644
index 2caef1b..0000000
--- a/src/go/types/testdata/fixedbugs/issue50417.go
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Field accesses through type parameters are disabled
-// until we have a more thorough understanding of the
-// implications on the spec. See issue #51576.
-
-package p
-
-type Sf struct {
-        f int
-}
-
-func f0[P Sf](p P) {
-        _ = p.f // ERROR p\.f undefined
-        p.f /* ERROR p\.f undefined */ = 0
-}
-
-func f0t[P ~struct{f int}](p P) {
-        _ = p.f // ERROR p\.f undefined
-        p.f /* ERROR p\.f undefined */ = 0
-}
-
-var _ = f0[Sf]
-var _ = f0t[Sf]
-
-var _ = f0[Sm /* ERROR does not implement */ ]
-var _ = f0t[Sm /* ERROR does not implement */ ]
-
-func f1[P interface{ Sf; m() }](p P) {
-        _ = p.f // ERROR p\.f undefined
-        p.f /* ERROR p\.f undefined */ = 0
-        p.m()
-}
-
-var _ = f1[Sf /* ERROR missing method m */ ]
-var _ = f1[Sm /* ERROR does not implement */ ]
-
-type Sm struct {}
-
-func (Sm) m() {}
-
-type Sfm struct {
-        f int
-}
-
-func (Sfm) m() {}
-
-func f2[P interface{ Sfm; m() }](p P) {
-        _ = p.f // ERROR p\.f undefined
-        p.f /* ERROR p\.f undefined */ = 0
-        p.m()
-}
-
-var _ = f2[Sfm]
-
-// special case: core type is a named pointer type
-
-type PSfm *Sfm
-
-func f3[P interface{ PSfm }](p P) {
-        _ = p.f // ERROR p\.f undefined
-        p.f /* ERROR p\.f undefined */ = 0
-        p.m /* ERROR type P has no field or method m */ ()
-}
-
-var _ = f3[PSfm]
diff --git a/src/go/types/testdata/fixedbugs/issue50646.go b/src/go/types/testdata/fixedbugs/issue50646.go
deleted file mode 100644
index 3bdba11..0000000
--- a/src/go/types/testdata/fixedbugs/issue50646.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func f1[_ comparable]()              {}
-func f2[_ interface{ comparable }]() {}
-
-type T interface{ m() }
-
-func _[P comparable, Q ~int, R any]() {
-	_ = f1[int]
-	_ = f1[T /* ERROR T does not implement comparable */ ]
-	_ = f1[any /* ERROR any does not implement comparable */ ]
-	_ = f1[P]
-	_ = f1[Q]
-	_ = f1[R /* ERROR R does not implement comparable */]
-
-	_ = f2[int]
-	_ = f2[T /* ERROR T does not implement comparable */ ]
-	_ = f2[any /* ERROR any does not implement comparable */ ]
-	_ = f2[P]
-	_ = f2[Q]
-	_ = f2[R /* ERROR R does not implement comparable */]
-}
diff --git a/src/go/types/testdata/fixedbugs/issue50782.go b/src/go/types/testdata/fixedbugs/issue50782.go
deleted file mode 100644
index fd1ab11..0000000
--- a/src/go/types/testdata/fixedbugs/issue50782.go
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Field accesses through type parameters are disabled
-// until we have a more thorough understanding of the
-// implications on the spec. See issue #51576.
-
-package p
-
-// The first example from the issue.
-type Numeric interface {
-	~int | ~int8 | ~int16 | ~int32 | ~int64
-}
-
-// numericAbs matches numeric types with an Abs method.
-type numericAbs[T Numeric] interface {
-	~struct{ Value T }
-	Abs() T
-}
-
-// AbsDifference computes the absolute value of the difference of
-// a and b, where the absolute value is determined by the Abs method.
-func absDifference[T numericAbs[T /* ERROR T does not implement Numeric */]](a, b T) T {
-	// Field accesses are not permitted for now. Keep an error so
-	// we can find and fix this code once the situation changes.
-	return a.Value // ERROR a\.Value undefined
-	// TODO: The error below should probably be positioned on the '-'.
-	// d := a /* ERROR "invalid operation: operator - not defined" */ .Value - b.Value
-	// return d.Abs()
-}
-
-// The second example from the issue.
-type T[P int] struct{ f P }
-
-func _[P T[P /* ERROR "P does not implement int" */ ]]() {}
-
-// Additional tests
-func _[P T[T /* ERROR "T\[P\] does not implement int" */ [P /* ERROR "P does not implement int" */ ]]]() {}
-func _[P T[Q /* ERROR "Q does not implement int" */ ], Q T[P /* ERROR "P does not implement int" */ ]]() {}
-func _[P T[Q], Q int]() {}
-
-type C[P comparable] struct{ f P }
-func _[P C[C[P]]]() {}
-func _[P C[C /* ERROR "C\[Q\] does not implement comparable" */ [Q /* ERROR "Q does not implement comparable" */]], Q func()]() {}
-func _[P [10]C[P]]() {}
-func _[P struct{ f C[C[P]]}]() {}
diff --git a/src/go/types/testdata/fixedbugs/issue50929.go b/src/go/types/testdata/fixedbugs/issue50929.go
deleted file mode 100644
index 3629ecf..0000000
--- a/src/go/types/testdata/fixedbugs/issue50929.go
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file is tested when running "go test -run Manual"
-// without source arguments. Use for one-off debugging.
-
-package p
-
-import "fmt"
-
-type F[A, B any] int
-
-func G[A, B any](F[A, B]) {
-}
-
-func _() {
-	// TODO(gri) only report one error below (issue #50932)
-	var x F /* ERROR got 1 arguments but 2 type parameters */ [int]
-	G(x /* ERROR does not match */)
-}
-
-// test case from issue
-// (lots of errors but doesn't crash anymore)
-
-type RC[G any, RG any] interface {
-	~[]RG
-}
-
-type RG[G any] struct{}
-
-type RSC[G any] []*RG[G]
-
-type M[Rc RC[G, RG], G any, RG any] struct {
-	Fn func(Rc)
-}
-
-type NFn[Rc RC[G, RG], G any, RG any] func(Rc)
-
-func NC[Rc RC[G, RG], G any, RG any](nFn NFn[Rc, G, RG]) {
-	var empty Rc
-	nFn(empty)
-}
-
-func NSG[G any](c RSC[G]) {
-	fmt.Println(c)
-}
-
-func MMD[Rc RC /* ERROR got 1 arguments */ [RG], RG any, G any]() M /* ERROR got 2 arguments */ [Rc, RG] {
-
-	var nFn NFn /* ERROR got 2 arguments */ [Rc, RG]
-
-	var empty Rc
-	switch any(empty).(type) {
-	case BC /* ERROR undeclared name: BC */ :
-
-	case RSC[G]:
-		nFn = NSG /* ERROR cannot use NSG\[G\] */ [G]
-	}
-
-	return M /* ERROR got 2 arguments */ [Rc, RG]{
-		Fn: func(rc Rc) {
-			NC(nFn /* ERROR does not match */ )
-		},
-	}
-
-	return M /* ERROR got 2 arguments */ [Rc, RG]{}
-}
diff --git a/src/go/types/testdata/fixedbugs/issue51257.go b/src/go/types/testdata/fixedbugs/issue51257.go
deleted file mode 100644
index 8a3eb32..0000000
--- a/src/go/types/testdata/fixedbugs/issue51257.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func f[_ comparable]() {}
-
-type S1 struct{ x int }
-type S2 struct{ x any }
-type S3 struct{ x [10]interface{ m() } }
-
-func _[P1 comparable, P2 S2]() {
-	_ = f[S1]
-	_ = f[S2 /* ERROR S2 does not implement comparable */ ]
-	_ = f[S3 /* ERROR S3 does not implement comparable */ ]
-
-	type L1 struct { x P1 }
-	type L2 struct { x P2 }
-	_ = f[L1]
-	_ = f[L2 /* ERROR L2 does not implement comparable */ ]
-}
-
-
-// example from issue
-
-type Set[T comparable] map[T]struct{}
-
-func NewSetFromSlice[T comparable](items []T) *Set[T] {
-	s := Set[T]{}
-
-	for _, item := range items {
-		s[item] = struct{}{}
-	}
-
-	return &s
-}
-
-type T struct{ x any }
-
-func main() {
-	NewSetFromSlice /* ERROR T does not implement comparable */ ([]T{
-		{"foo"},
-		{5},
-	})
-}
diff --git a/src/go/types/testdata/fixedbugs/issue51335.go b/src/go/types/testdata/fixedbugs/issue51335.go
deleted file mode 100644
index 0b5a1af..0000000
--- a/src/go/types/testdata/fixedbugs/issue51335.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type S1 struct{}
-type S2 struct{}
-
-func _[P *S1|*S2]() {
-	_= []P{{ /* ERROR invalid composite literal element type P: no core type */ }}
-}
-
-func _[P *S1|S1]() {
-	_= []P{{ /* ERROR invalid composite literal element type P: no core type */ }}
-}
diff --git a/src/go/types/testdata/fixedbugs/issue51376.go b/src/go/types/testdata/fixedbugs/issue51376.go
deleted file mode 100644
index d51607b..0000000
--- a/src/go/types/testdata/fixedbugs/issue51376.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type Map map[string]int
-
-func f[M ~map[K]V, K comparable, V any](M) {}
-func g[M map[K]V, K comparable, V any](M) {}
-
-func _[M1 ~map[K]V, M2 map[K]V, K comparable, V any]() {
-        var m1 M1
-        f(m1)
-        g /* ERROR M1 does not implement map\[K\]V */ (m1) // M1 has tilde
-
-        var m2 M2
-        f(m2)
-        g(m2) // M1 does not have tilde
-
-        var m3 Map
-        f(m3)
-        g /* ERROR Map does not implement map\[string\]int */ (m3) // M in g does not have tilde
-}
diff --git a/src/go/types/testdata/fixedbugs/issue51472.go b/src/go/types/testdata/fixedbugs/issue51472.go
deleted file mode 100644
index 3126770..0000000
--- a/src/go/types/testdata/fixedbugs/issue51472.go
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func _[T comparable](x T) {
-        _ = x == x
-}
-
-func _[T interface{interface{comparable}}](x T) {
-        _ = x == x
-}
-
-func _[T interface{comparable; interface{comparable}}](x T) {
-        _ = x == x
-}
-
-func _[T interface{comparable; ~int}](x T) {
-        _ = x == x
-}
-
-func _[T interface{comparable; ~[]byte}](x T) {
-        _ = x /* ERROR cannot compare */ == x
-}
-
-// TODO(gri) The error message here should be better. See issue #51525.
-func _[T interface{comparable; ~int; ~string}](x T) {
-        _ = x /* ERROR cannot compare */ == x
-}
-
-// TODO(gri) The error message here should be better. See issue #51525.
-func _[T interface{~int; ~string}](x T) {
-        _ = x /* ERROR cannot compare */ == x
-}
-
-func _[T interface{comparable; interface{~int}; interface{int|float64}}](x T) {
-        _ = x == x
-}
-
-func _[T interface{interface{comparable; ~int}; interface{~float64; comparable; m()}}](x T) {
-        _ = x /* ERROR cannot compare */ == x
-}
-
-// test case from issue
-
-func f[T interface{comparable; []byte|string}](x T) {
-        _ = x == x
-}
-
-func _(s []byte) {
-	f /* ERROR \[\]byte does not implement interface{comparable; \[\]byte\|string} */ (s)
-        _ = f[[ /* ERROR does not implement */ ]byte]
-}
diff --git a/src/go/types/testdata/fixedbugs/issue51509.go b/src/go/types/testdata/fixedbugs/issue51509.go
deleted file mode 100644
index 5ae4717..0000000
--- a/src/go/types/testdata/fixedbugs/issue51509.go
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type T /* ERROR illegal cycle */ T.x
diff --git a/src/go/types/testdata/fixedbugs/issue51525.go b/src/go/types/testdata/fixedbugs/issue51525.go
deleted file mode 100644
index af1d1e6..0000000
--- a/src/go/types/testdata/fixedbugs/issue51525.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-func _[T interface {
-	int
-	string
-}](x T) {
-	_ = x /* ERROR empty type set */ == x
-}
-
-func _[T interface{ int | []byte }](x T) {
-	_ = x /* ERROR incomparable types in type set */ == x
-}
diff --git a/src/go/types/testdata/fixedbugs/issue51658.go b/src/go/types/testdata/fixedbugs/issue51658.go
deleted file mode 100644
index 04ce6a9..0000000
--- a/src/go/types/testdata/fixedbugs/issue51658.go
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type F { // ERROR expected type
-	float64
-} // ERROR expected declaration
-
-func _[T F | int](x T) {
-	_ = x == 0 // don't crash when recording type of 0
-}
-
-// test case from issue
-
-type FloatType { // ERROR expected type
-	float32 | float64
-} // ERROR expected declaration
-
-type IntegerType interface {
-	int8 | int16 | int32 | int64 | int |
-		uint8 | uint16 | uint32 | uint64 | uint
-}
-
-type ComplexType interface {
-	complex64 | complex128
-}
-
-type Number interface {
-	FloatType | IntegerType | ComplexType
-}
-
-func GetDefaultNumber[T Number](value, defaultValue T) T {
-	if value == 0 {
-		return defaultValue
-	}
-	return value
-}
diff --git a/src/go/types/testdata/fixedbugs/issue51877.go b/src/go/types/testdata/fixedbugs/issue51877.go
deleted file mode 100644
index 06f054b..0000000
--- a/src/go/types/testdata/fixedbugs/issue51877.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-type S struct {
-	f1 int
-	f2 bool
-}
-
-var (
-	_ = S{0}                    /* ERROR too few values in S{…} */
-	_ = struct{ f1, f2 int }{0} /* ERROR too few values in struct{f1 int; f2 int}{…} */
-
-	_ = S{0, true, "foo" /* ERROR too many values in S{…} */}
-	_ = struct{ f1, f2 int }{0, 1, 2 /* ERROR too many values in struct{f1 int; f2 int}{…} */}
-)
diff --git a/src/go/types/testdata/fixedbugs/issue52698.go b/src/go/types/testdata/fixedbugs/issue52698.go
deleted file mode 100644
index 3babc21..0000000
--- a/src/go/types/testdata/fixedbugs/issue52698.go
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-// sanity check
-type T[P any] struct {
-	_ P
-}
-
-type S /* ERROR illegal cycle */ struct {
-	_ T[S]
-}
-
-// simplified test
-var _ B[A]
-
-type A struct {
-	_ B[string]
-}
-
-type B[P any] struct {
-	_ C[P]
-}
-
-type C[P any] struct {
-	_ P
-}
-
-// test case from issue
-type T23 interface {
-	~struct {
-		Field0 T13[T15]
-	}
-}
-
-type T1[P1 interface {
-}] struct {
-	Field2 P1
-}
-
-type T13[P2 interface {
-}] struct {
-	Field2 T1[P2]
-}
-
-type T15 struct {
-	Field0 T13[string]
-}
diff --git a/src/go/types/testdata/fixedbugs/issue52915.go b/src/go/types/testdata/fixedbugs/issue52915.go
deleted file mode 100644
index 2c38e5b..0000000
--- a/src/go/types/testdata/fixedbugs/issue52915.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package p
-
-import "unsafe"
-
-type T[P any] struct {
-	T /* ERROR illegal cycle */ [P]
-}
-
-func _[P any]() {
-	_ = unsafe.Sizeof(T[int]{})
-	_ = unsafe.Sizeof(struct{ T[int] }{})
-
-	_ = unsafe.Sizeof(T[P]{})
-	_ = unsafe.Sizeof(struct{ T[P] }{})
-}
-
-// TODO(gri) This is a follow-on error due to T[int] being invalid.
-//           We should try to avoid it.
-const _ = unsafe /* ERROR not constant */ .Sizeof(T[int]{})
diff --git a/src/go/types/testdata/local/issue47996.go b/src/go/types/testdata/local/issue47996.go
new file mode 100644
index 0000000..4d28920
--- /dev/null
+++ b/src/go/types/testdata/local/issue47996.go
@@ -0,0 +1,9 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+// don't crash
+// TODO(gri) make this test work for go/types
+// func T[P] m() {}
diff --git a/src/go/types/testdata/local/shifts.go b/src/go/types/testdata/local/shifts.go
new file mode 100644
index 0000000..cf847d3
--- /dev/null
+++ b/src/go/types/testdata/local/shifts.go
@@ -0,0 +1,27 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// The following shift tests are disabled in the shared
+// testdata/check/shifts.go file because they don't work
+// correctly with types2 at the moment. See issue #52080.
+// Make sure we keep testing them with go/types.
+//
+// TODO(gri) Once #52080 is fixed, this file can be
+//           deleted in favor of the re-enabled tests
+//           in the shared file.
+
+package p
+
+func _() {
+	var s uint
+
+	_ = int32(0x80000000 /* ERROR "overflows int32" */ << s)
+	// TODO(rfindley) Eliminate the redundant error here.
+	_ = int32(( /* ERROR "truncated to int32" */ 0x80000000 /* ERROR "truncated to int32" */ + 0i) << s)
+
+	_ = int(1 + 0i<<0)
+	_ = int((1 + 0i) << s)
+	_ = int(1.0 << s)
+	_ = int(complex(1, 0) << s)
+}
diff --git a/src/go/types/testdata/spec/assignability.go b/src/go/types/testdata/spec/assignability.go
deleted file mode 100644
index d5f6ab4..0000000
--- a/src/go/types/testdata/spec/assignability.go
+++ /dev/null
@@ -1,266 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package assignability
-
-// See the end of this package for the declarations
-// of the types and variables used in these tests.
-
-// "x's type is identical to T"
-func _[TP any](X TP) {
-	b = b
-	a = a
-	l = l
-	s = s
-	p = p
-	f = f
-	i = i
-	m = m
-	c = c
-	d = d
-
-	B = B
-	A = A
-	L = L
-	S = S
-	P = P
-	F = F
-	I = I
-	M = M
-	C = C
-	D = D
-	X = X
-}
-
-// "x's type V and T have identical underlying types
-// and at least one of V or T is not a named type."
-// (here a named type is a type with a name)
-func _[TP1, TP2 Interface](X1 TP1, X2 TP2) {
-	b = B // ERROR cannot use B .* as int value
-	a = A
-	l = L
-	s = S
-	p = P
-	f = F
-	i = I
-	m = M
-	c = C
-	d = D
-
-	B = b // ERROR cannot use b .* as Basic value
-	A = a
-	L = l
-	S = s
-	P = p
-	F = f
-	I = i
-	M = m
-	C = c
-	D = d
-	X1 = i  // ERROR cannot use i .* as TP1 value
-	X1 = X2 // ERROR cannot use X2 .* as TP1 value
-}
-
-// "T is an interface type and x implements T and T is not a type parameter"
-func _[TP Interface](X TP) {
-	i = d // ERROR missing method m
-	i = D
-	i = X
-	X = i // ERROR cannot use i .* as TP value
-}
-
-// "x is a bidirectional channel value, T is a channel type, x's type V and T have identical element types, and at least one of V or T is not a named type"
-// (here a named type is a type with a name)
-type (
-	_SendChan = chan<- int
-	_RecvChan = <-chan int
-
-	SendChan _SendChan
-	RecvChan _RecvChan
-)
-
-func _[
-	_CC ~_Chan,
-	_SC ~_SendChan,
-	_RC ~_RecvChan,
-
-	CC Chan,
-	SC SendChan,
-	RC RecvChan,
-]() {
-	var (
-		_ _SendChan = c
-		_ _RecvChan = c
-		_ _Chan = c
-
-		_ _SendChan = C
-		_ _RecvChan = C
-		_ _Chan = C
-
-		_ SendChan = c
-		_ RecvChan = c
-		_ Chan = c
-
-		_ SendChan = C // ERROR cannot use C .* as SendChan value
-		_ RecvChan = C // ERROR cannot use C .* as RecvChan value
-		_ Chan = C
-		_ Chan = make /* ERROR cannot use make\(chan Basic\) .* as Chan value */ (chan Basic)
-	)
-
-	var (
-		_ _CC = C // ERROR cannot use C .* as _CC value
-		_ _SC = C // ERROR cannot use C .* as _SC value
-		_ _RC = C // ERROR cannot use C .* as _RC value
-
-		_ CC = _CC /* ERROR cannot use _CC\(nil\) .* as CC value */ (nil)
-		_ SC = _CC /* ERROR cannot use _CC\(nil\) .* as SC value */ (nil)
-		_ RC = _CC /* ERROR cannot use _CC\(nil\) .* as RC value */ (nil)
-
-		_ CC = C // ERROR cannot use C .* as CC value
-		_ SC = C // ERROR cannot use C .* as SC value
-		_ RC = C // ERROR cannot use C .* as RC value
-	)
-}
-
-// "x's type V is not a named type and T is a type parameter, and x is assignable to each specific type in T's type set."
-func _[
-	TP0 any,
-	TP1 ~_Chan,
-	TP2 ~chan int | ~chan byte,
-]() {
-	var (
-		_ TP0 = c // ERROR cannot use c .* as TP0 value
-		_ TP0 = C // ERROR cannot use C .* as TP0 value
-		_ TP1 = c
-		_ TP1 = C // ERROR cannot use C .* as TP1 value
-		_ TP2 = c // ERROR .* cannot assign chan int to chan byte
-	)
-}
-
-// "x's type V is a type parameter and T is not a named type, and values x' of each specific type in V's type set are assignable to T."
-func _[
-	TP0 Interface,
-	TP1 ~_Chan,
-	TP2 ~chan int | ~chan byte,
-](X0 TP0, X1 TP1, X2 TP2) {
-	i = X0
-	I = X0
-	c = X1
-	C = X1 // ERROR cannot use X1 .* as Chan value
-	c = X2 // ERROR .* cannot assign chan byte \(in TP2\) to chan int
-}
-
-// "x is the predeclared identifier nil and T is a pointer, function, slice, map, channel, or interface type"
-// TODO(rfindley) error messages about untyped nil diverge from types2 here.
-// Consider aligning them.
-func _[TP Interface](X TP) {
-	b = nil // ERROR cannot use nil
-	a = nil // ERROR cannot use nil
-	l = nil
-	s = nil // ERROR cannot use nil
-	p = nil
-	f = nil
-	i = nil
-	m = nil
-	c = nil
-	d = nil // ERROR cannot use nil
-
-	B = nil // ERROR cannot use nil
-	A = nil // ERROR cannot use nil
-	L = nil
-	S = nil // ERROR cannot use nil
-	P = nil
-	F = nil
-	I = nil
-	M = nil
-	C = nil
-	D = nil // ERROR cannot use nil
-	X = nil // ERROR cannot use nil
-}
-
-// "x is an untyped constant representable by a value of type T"
-func _[
-	Int8 ~int8,
-	Int16 ~int16,
-	Int32 ~int32,
-	Int64 ~int64,
-        Int8_16 ~int8 | ~int16,
-](
-	i8 Int8,
-	i16 Int16,
-	i32 Int32,
-	i64 Int64,
-        i8_16 Int8_16,
-) {
-	b = 42
-	b = 42.0
-	// etc.
-
-	i8 = -1 << 7
-	i8 = 1<<7 - 1
-	i16 = -1 << 15
-	i16 = 1<<15 - 1
-	i32 = -1 << 31
-	i32 = 1<<31 - 1
-	i64 = -1 << 63
-	i64 = 1<<63 - 1
-
-	i8_16 = -1 << 7
-	i8_16 = 1<<7 - 1
-	i8_16 = - /* ERROR cannot use .* as Int8_16 */ 1 << 15
-	i8_16 = 1 /* ERROR cannot use .* as Int8_16 */ <<15 - 1
-}
-
-// proto-types for tests
-
-type (
-	_Basic     = int
-	_Array     = [10]int
-	_Slice     = []int
-	_Struct    = struct{ f int }
-	_Pointer   = *int
-	_Func      = func(x int) string
-	_Interface = interface{ m() int }
-	_Map       = map[string]int
-	_Chan      = chan int
-
-	Basic     _Basic
-	Array     _Array
-	Slice     _Slice
-	Struct    _Struct
-	Pointer   _Pointer
-	Func      _Func
-	Interface _Interface
-	Map       _Map
-	Chan      _Chan
-	Defined   _Struct
-)
-
-func (Defined) m() int
-
-// proto-variables for tests
-
-var (
-	b _Basic
-	a _Array
-	l _Slice
-	s _Struct
-	p _Pointer
-	f _Func
-	i _Interface
-	m _Map
-	c _Chan
-	d _Struct
-
-	B Basic
-	A Array
-	L Slice
-	S Struct
-	P Pointer
-	F Func
-	I Interface
-	M Map
-	C Chan
-	D Defined
-)
diff --git a/src/go/types/testdata/spec/comparisons.go b/src/go/types/testdata/spec/comparisons.go
deleted file mode 100644
index 2a7598a..0000000
--- a/src/go/types/testdata/spec/comparisons.go
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package comparisons
-
-type (
-	B int // basic type representative
-	A [10]func()
-	L []byte
-	S struct{ f []byte }
-	P *S
-	F func()
-	I interface{}
-	M map[string]int
-	C chan int
-)
-
-var (
-	b B
-	a A
-	l L
-	s S
-	p P
-	f F
-	i I
-	m M
-	c C
-)
-
-func _() {
-	_ = nil == nil // ERROR operator == not defined on untyped nil
-	_ = b == b
-	_ = a /* ERROR \[10\]func\(\) cannot be compared */ == a
-	_ = l /* ERROR slice can only be compared to nil */ == l
-	_ = s /* ERROR struct containing \[\]byte cannot be compared */ == s
-	_ = p == p
-	_ = f /* ERROR func can only be compared to nil */ == f
-	_ = i == i
-	_ = m /* ERROR map can only be compared to nil */ == m
-	_ = c == c
-
-	_ = b /* ERROR mismatched types */ == nil
-	_ = a /* ERROR mismatched types */ == nil
-	_ = l == nil
-	_ = s /* ERROR mismatched types */ == nil
-	_ = p == nil
-	_ = f == nil
-	_ = i == nil
-	_ = m == nil
-	_ = c == nil
-
-	_ = nil /* ERROR operator < not defined on untyped nil */ < nil
-	_ = b < b
-	_ = a /* ERROR operator < not defined on array */ < a
-	_ = l /* ERROR operator < not defined on slice */ < l
-	_ = s /* ERROR operator < not defined on struct */ < s
-	_ = p /* ERROR operator < not defined on pointer */ < p
-	_ = f /* ERROR operator < not defined on func */ < f
-	_ = i /* ERROR operator < not defined on interface */ < i
-	_ = m /* ERROR operator < not defined on map */ < m
-	_ = c /* ERROR operator < not defined on chan */ < c
-}
-
-func _[
-	B int,
-	A [10]func(),
-	L []byte,
-	S struct{ f []byte },
-	P *S,
-	F func(),
-	I interface{},
-	J comparable,
-	M map[string]int,
-	C chan int,
-](
-	b B,
-	a A,
-	l L,
-	s S,
-	p P,
-	f F,
-	i I,
-	j J,
-	m M,
-	c C,
-) {
-	_ = b == b
-	_ = a /* ERROR incomparable types in type set */ == a
-	_ = l /* ERROR incomparable types in type set */ == l
-	_ = s /* ERROR incomparable types in type set */ == s
-	_ = p == p
-	_ = f /* ERROR incomparable types in type set */ == f
-	_ = i /* ERROR incomparable types in type set */ == i
-	_ = j == j
-	_ = m /* ERROR incomparable types in type set */ == m
-	_ = c == c
-
-	_ = b /* ERROR mismatched types */ == nil
-	_ = a /* ERROR mismatched types */ == nil
-	_ = l == nil
-	_ = s /* ERROR mismatched types */ == nil
-	_ = p == nil
-	_ = f == nil
-	_ = i /* ERROR mismatched types */ == nil
-	_ = j /* ERROR mismatched types */ == nil
-	_ = m == nil
-	_ = c == nil
-
-	_ = b < b
-	_ = a /* ERROR type parameter A is not comparable with < */ < a
-	_ = l /* ERROR type parameter L is not comparable with < */ < l
-	_ = s /* ERROR type parameter S is not comparable with < */ < s
-	_ = p /* ERROR type parameter P is not comparable with < */ < p
-	_ = f /* ERROR type parameter F is not comparable with < */ < f
-	_ = i /* ERROR type parameter I is not comparable with < */ < i
-	_ = j /* ERROR type parameter J is not comparable with < */ < j
-	_ = m /* ERROR type parameter M is not comparable with < */ < m
-	_ = c /* ERROR type parameter C is not comparable with < */ < c
-}
diff --git a/src/go/types/testdata/spec/conversions.go b/src/go/types/testdata/spec/conversions.go
deleted file mode 100644
index e54403c..0000000
--- a/src/go/types/testdata/spec/conversions.go
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package conversions
-
-import "unsafe"
-
-// constant conversions
-
-func _[T ~byte]() T { return 255 }
-func _[T ~byte]() T { return 256 /* ERROR cannot use 256 .* as T value */ }
-
-func _[T ~byte]() {
-	const _ = T /* ERROR T\(0\) .* is not constant */ (0)
-	var _ T = 255
-	var _ T = 256 // ERROR cannot use 256 .* as T value
-}
-
-func _[T ~string]() T { return T('a') }
-func _[T ~int | ~string]() T { return T('a') }
-func _[T ~byte | ~int | ~string]() T { return T(256 /* ERROR cannot convert 256 .* to T */ ) }
-
-// implicit conversions never convert to string
-func _[T ~string]() {
-	var _ string = 0 // ERROR cannot use .* as string value
-	var _ T = 0 // ERROR cannot use .* as T value
-}
-
-// failing const conversions of constants to type parameters report a cause
-func _[
-	T1 any,
-	T2 interface{ m() },
-	T3 ~int | ~float64 | ~bool,
-	T4 ~int | ~string,
-]() {
-	// TODO(rfindley): align the error formatting here with types2.
-	_ = T1(0 /* ERROR cannot convert 0 .* to T1.*T1 does not contain specific types */ )
-	_ = T2(1 /* ERROR cannot convert 1 .* to T2.*T2 does not contain specific types */ )
-	_ = T3(2 /* ERROR cannot convert 2 .* to T3.*cannot convert 2 .* to bool \(in T3\) */ )
-	_ = T4(3.14 /* ERROR cannot convert 3.14 .* to T4.*cannot convert 3.14 .* to int \(in T4\) */ )
-}
-
-// "x is assignable to T"
-// - tested via assignability tests
-
-// "x's type and T have identical underlying types if tags are ignored"
-
-func _[X ~int, T ~int](x X) T { return T(x) }
-func _[X struct{f int "foo"}, T struct{f int "bar"}](x X) T { return T(x) }
-
-type Foo struct{f int "foo"}
-type Bar struct{f int "bar"}
-type Far struct{f float64 }
-
-func _[X Foo, T Bar](x X) T { return T(x) }
-func _[X Foo|Bar, T Bar](x X) T { return T(x) }
-func _[X Foo, T Foo|Bar](x X) T { return T(x) }
-func _[X Foo, T Far](x X) T { return T(x /* ERROR cannot convert x \(variable of type X constrained by Foo\) to T.*cannot convert Foo \(in X\) to Far \(in T\) */ ) }
-
-// "x's type and T are unnamed pointer types and their pointer base types
-// have identical underlying types if tags are ignored"
-
-func _[X ~*Foo, T ~*Bar](x X) T { return T(x) }
-func _[X ~*Foo|~*Bar, T ~*Bar](x X) T { return T(x) }
-func _[X ~*Foo, T ~*Foo|~*Bar](x X) T { return T(x) }
-func _[X ~*Foo, T ~*Far](x X) T { return T(x /* ERROR cannot convert x \(variable of type X constrained by ~\*Foo\) to T.*cannot convert \*Foo \(in X\) to \*Far \(in T\) */ ) }
-
-// Verify that the defined types in constraints are considered for the rule above.
-
-type (
-	B int
-	C int
-	X0 *B
-	T0 *C
-)
-
-func _(x X0) T0 { return T0(x /* ERROR cannot convert */ ) } // non-generic reference
-func _[X X0, T T0](x X) T { return T(x /* ERROR cannot convert */ ) }
-func _[T T0](x X0) T { return T(x /* ERROR cannot convert */ ) }
-func _[X X0](x X) T0 { return T0(x /* ERROR cannot convert */ ) }
-
-// "x's type and T are both integer or floating point types"
-
-func _[X Integer, T Integer](x X) T { return T(x) }
-func _[X Unsigned, T Integer](x X) T { return T(x) }
-func _[X Float, T Integer](x X) T { return T(x) }
-
-func _[X Integer, T Unsigned](x X) T { return T(x) }
-func _[X Unsigned, T Unsigned](x X) T { return T(x) }
-func _[X Float, T Unsigned](x X) T { return T(x) }
-
-func _[X Integer, T Float](x X) T { return T(x) }
-func _[X Unsigned, T Float](x X) T { return T(x) }
-func _[X Float, T Float](x X) T { return T(x) }
-
-func _[X, T Integer|Unsigned|Float](x X) T { return T(x) }
-func _[X, T Integer|~string](x X) T { return T(x /* ERROR cannot convert x \(variable of type X constrained by Integer\|~string\) to T.*cannot convert string \(in X\) to int \(in T\) */ ) }
-
-// "x's type and T are both complex types"
-
-func _[X, T Complex](x X) T { return T(x) }
-func _[X, T Float|Complex](x X) T { return T(x /* ERROR cannot convert x \(variable of type X constrained by Float\|Complex\) to T.*cannot convert float32 \(in X\) to complex64 \(in T\) */ ) }
-
-// "x is an integer or a slice of bytes or runes and T is a string type"
-
-type myInt int
-type myString string
-
-func _[T ~string](x int) T { return T(x) }
-func _[T ~string](x myInt) T { return T(x) }
-func _[X Integer](x X) string { return string(x) }
-func _[X Integer](x X) myString { return myString(x) }
-func _[X Integer](x X) *string { return (*string)(x /* ERROR cannot convert x \(variable of type X constrained by Integer\) to \*string.*cannot convert int \(in X\) to \*string */ ) }
-
-func _[T ~string](x []byte) T { return T(x) }
-func _[T ~string](x []rune) T { return T(x) }
-func _[X ~[]byte, T ~string](x X) T { return T(x) }
-func _[X ~[]rune, T ~string](x X) T { return T(x) }
-func _[X Integer|~[]byte|~[]rune, T ~string](x X) T { return T(x) }
-func _[X Integer|~[]byte|~[]rune, T ~*string](x X) T { return T(x /* ERROR cannot convert x \(variable of type X constrained by Integer\|~\[\]byte\|~\[\]rune\) to T.*cannot convert int \(in X\) to \*string \(in T\) */ ) }
-
-// "x is a string and T is a slice of bytes or runes"
-
-func _[T ~[]byte](x string) T { return T(x) }
-func _[T ~[]rune](x string) T { return T(x) }
-func _[T ~[]rune](x *string) T { return T(x /* ERROR cannot convert x \(variable of type \*string\) to T.*cannot convert \*string to \[\]rune \(in T\) */ ) }
-
-func _[X ~string, T ~[]byte](x X) T { return T(x) }
-func _[X ~string, T ~[]rune](x X) T { return T(x) }
-func _[X ~string, T ~[]byte|~[]rune](x X) T { return T(x) }
-func _[X ~*string, T ~[]byte|~[]rune](x X) T { return T(x /* ERROR cannot convert x \(variable of type X constrained by ~\*string\) to T.*cannot convert \*string \(in X\) to \[\]byte \(in T\) */ ) }
-
-// package unsafe:
-// "any pointer or value of underlying type uintptr can be converted into a unsafe.Pointer"
-
-type myUintptr uintptr
-
-func _[X ~uintptr](x X) unsafe.Pointer { return unsafe.Pointer(x) }
-func _[T unsafe.Pointer](x myUintptr) T { return T(x) }
-func _[T unsafe.Pointer](x int64) T { return T(x /* ERROR cannot convert x \(variable of type int64\) to T.*cannot convert int64 to unsafe\.Pointer \(in T\) */ ) }
-
-// "and vice versa"
-
-func _[T ~uintptr](x unsafe.Pointer) T { return T(x) }
-func _[X unsafe.Pointer](x X) uintptr { return uintptr(x) }
-func _[X unsafe.Pointer](x X) myUintptr { return myUintptr(x) }
-func _[X unsafe.Pointer](x X) int64 { return int64(x /* ERROR cannot convert x \(variable of type X constrained by unsafe\.Pointer\) to int64.*cannot convert unsafe\.Pointer \(in X\) to int64 */ ) }
-
-// "x is a slice, T is a pointer-to-array type,
-// and the slice and array types have identical element types."
-
-func _[X ~[]E, T ~*[10]E, E any](x X) T { return T(x) }
-func _[X ~[]E, T ~[10]E, E any](x X) T { return T(x /* ERROR cannot convert x \(variable of type X constrained by ~\[\]E\) to T.*cannot convert \[\]E \(in X\) to \[10\]E \(in T\) */ ) }
-
-// ----------------------------------------------------------------------------
-// The following declarations can be replaced by the exported types of the
-// constraints package once all builders support importing interfaces with
-// type constraints.
-
-type Signed interface {
-	~int | ~int8 | ~int16 | ~int32 | ~int64
-}
-
-type Unsigned interface {
-	~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
-}
-
-type Integer interface {
-	Signed | Unsigned
-}
-
-type Float interface {
-	~float32 | ~float64
-}
-
-type Complex interface {
-	~complex64 | ~complex128
-}
diff --git a/src/go/types/typeset.go b/src/go/types/typeset.go
index 08ff191..d68446d 100644
--- a/src/go/types/typeset.go
+++ b/src/go/types/typeset.go
@@ -5,10 +5,11 @@
 package types
 
 import (
-	"bytes"
 	"fmt"
 	"go/token"
+	. "internal/types/errors"
 	"sort"
+	"strings"
 )
 
 // ----------------------------------------------------------------------------
@@ -71,7 +72,7 @@
 	hasMethods := len(s.methods) > 0
 	hasTerms := s.hasTerms()
 
-	var buf bytes.Buffer
+	var buf strings.Builder
 	buf.WriteByte('{')
 	if s.comparable {
 		buf.WriteString("comparable")
@@ -229,8 +230,8 @@
 				panic(fmt.Sprintf("%v: duplicate method %s", m.pos, m.name))
 			}
 			// check != nil
-			check.errorf(atPos(pos), _DuplicateDecl, "duplicate method %s", m.name)
-			check.errorf(atPos(mpos[other.(*Func)]), _DuplicateDecl, "\tother declaration of %s", m.name) // secondary error, \t indented
+			check.errorf(atPos(pos), DuplicateDecl, "duplicate method %s", m.name)
+			check.errorf(atPos(mpos[other.(*Func)]), DuplicateDecl, "\tother declaration of %s", m.name) // secondary error, \t indented
 		default:
 			// We have a duplicate method name in an embedded (not explicitly declared) method.
 			// Check method signatures after all types are computed (issue #33656).
@@ -245,8 +246,8 @@
 			// check != nil
 			check.later(func() {
 				if !check.allowVersion(m.pkg, 1, 14) || !Identical(m.typ, other.Type()) {
-					check.errorf(atPos(pos), _DuplicateDecl, "duplicate method %s", m.name)
-					check.errorf(atPos(mpos[other.(*Func)]), _DuplicateDecl, "\tother declaration of %s", m.name) // secondary error, \t indented
+					check.errorf(atPos(pos), DuplicateDecl, "duplicate method %s", m.name)
+					check.errorf(atPos(mpos[other.(*Func)]), DuplicateDecl, "\tother declaration of %s", m.name) // secondary error, \t indented
 				}
 			}).describef(atPos(pos), "duplicate method check for %s", m.name)
 		}
@@ -276,7 +277,7 @@
 			tset := computeInterfaceTypeSet(check, pos, u)
 			// If typ is local, an error was already reported where typ is specified/defined.
 			if check != nil && check.isImportedConstraint(typ) && !check.allowVersion(check.pkg, 1, 18) {
-				check.errorf(atPos(pos), _UnsupportedFeature, "embedding constraint interface %s requires go1.18 or later", typ)
+				check.errorf(atPos(pos), UnsupportedFeature, "embedding constraint interface %s requires go1.18 or later", typ)
 				continue
 			}
 			comparable = tset.comparable
@@ -286,7 +287,7 @@
 			terms = tset.terms
 		case *Union:
 			if check != nil && !check.allowVersion(check.pkg, 1, 18) {
-				check.errorf(atPos(pos), _InvalidIfaceEmbed, "embedding interface element %s requires go1.18 or later", u)
+				check.errorf(atPos(pos), UnsupportedFeature, "embedding interface element %s requires go1.18 or later", u)
 				continue
 			}
 			tset := computeUnionTypeSet(check, unionSets, pos, u)
@@ -301,7 +302,7 @@
 				continue
 			}
 			if check != nil && !check.allowVersion(check.pkg, 1, 18) {
-				check.errorf(atPos(pos), _InvalidIfaceEmbed, "embedding non-interface type %s requires go1.18 or later", typ)
+				check.errorf(atPos(pos), UnsupportedFeature, "embedding non-interface type %s requires go1.18 or later", typ)
 				continue
 			}
 			terms = termlist{{false, typ}}
@@ -349,7 +350,7 @@
 		i := 0
 		for _, t := range terms {
 			assert(t.typ != nil)
-			if Comparable(t.typ) {
+			if comparable(t.typ, false /* strictly comparable */, nil, nil) {
 				terms[i] = t
 				i++
 			}
@@ -421,7 +422,7 @@
 		allTerms = allTerms.union(terms)
 		if len(allTerms) > maxTermCount {
 			if check != nil {
-				check.errorf(atPos(pos), _InvalidUnion, "cannot handle more than %d union terms (implementation limitation)", maxTermCount)
+				check.errorf(atPos(pos), InvalidUnion, "cannot handle more than %d union terms (implementation limitation)", maxTermCount)
 			}
 			unionSets[utyp] = &invalidTypeSet
 			return unionSets[utyp]
diff --git a/src/go/types/typestring.go b/src/go/types/typestring.go
index 5a2e2c1..cfeb7eb 100644
--- a/src/go/types/typestring.go
+++ b/src/go/types/typestring.go
@@ -46,14 +46,8 @@
 // The Qualifier controls the printing of
 // package-level objects, and may be nil.
 func TypeString(typ Type, qf Qualifier) string {
-	return typeString(typ, qf, false)
-}
-
-func typeString(typ Type, qf Qualifier, debug bool) string {
 	var buf bytes.Buffer
-	w := newTypeWriter(&buf, qf)
-	w.debug = debug
-	w.typ(typ)
+	WriteType(&buf, typ, qf)
 	return buf.String()
 }
 
@@ -65,29 +59,30 @@
 }
 
 // WriteSignature writes the representation of the signature sig to buf,
-// without a leading "func" keyword.
-// The Qualifier controls the printing of
-// package-level objects, and may be nil.
+// without a leading "func" keyword. The Qualifier controls the printing
+// of package-level objects, and may be nil.
 func WriteSignature(buf *bytes.Buffer, sig *Signature, qf Qualifier) {
 	newTypeWriter(buf, qf).signature(sig)
 }
 
 type typeWriter struct {
-	buf     *bytes.Buffer
-	seen    map[Type]bool
-	qf      Qualifier
-	ctxt    *Context       // if non-nil, we are type hashing
-	tparams *TypeParamList // local type parameters
-	debug   bool           // if true, write debug annotations
+	buf          *bytes.Buffer
+	seen         map[Type]bool
+	qf           Qualifier
+	ctxt         *Context       // if non-nil, we are type hashing
+	tparams      *TypeParamList // local type parameters
+	paramNames   bool           // if set, write function parameter names, otherwise, write types only
+	tpSubscripts bool           // if set, write type parameter indices as subscripts
+	pkgInfo      bool           // package-annotate first unexported-type field to avoid confusing type description
 }
 
 func newTypeWriter(buf *bytes.Buffer, qf Qualifier) *typeWriter {
-	return &typeWriter{buf, make(map[Type]bool), qf, nil, nil, false}
+	return &typeWriter{buf, make(map[Type]bool), qf, nil, nil, true, false, false}
 }
 
 func newTypeHasher(buf *bytes.Buffer, ctxt *Context) *typeWriter {
 	assert(ctxt != nil)
-	return &typeWriter{buf, make(map[Type]bool), nil, ctxt, nil, false}
+	return &typeWriter{buf, make(map[Type]bool), nil, ctxt, nil, false, false, false}
 }
 
 func (w *typeWriter) byte(b byte) {
@@ -154,6 +149,16 @@
 			if i > 0 {
 				w.byte(';')
 			}
+
+			// If disambiguating one struct for another, look for the first unexported field.
+			// Do this first in case of nested structs; tag the first-outermost field.
+			pkgAnnotate := false
+			if w.qf == nil && w.pkgInfo && !token.IsExported(f.name) {
+				// note for embedded types, type name is field name, and "string" etc are lower case hence unexported.
+				pkgAnnotate = true
+				w.pkgInfo = false // only tag once
+			}
+
 			// This doesn't do the right thing for embedded type
 			// aliases where we should print the alias name, not
 			// the aliased type (see issue #44410).
@@ -162,6 +167,11 @@
 				w.byte(' ')
 			}
 			w.typ(f.typ)
+			if pkgAnnotate {
+				w.string(" /* package ")
+				w.string(f.pkg.Path())
+				w.string(" */ ")
+			}
 			if tag := t.Tag(i); tag != "" {
 				w.byte(' ')
 				// TODO(rfindley) If tag contains blanks, replacing them with '#'
@@ -192,7 +202,7 @@
 		}
 		for i, t := range t.terms {
 			if i > 0 {
-				w.byte('|')
+				w.string(termSep)
 			}
 			if t.tilde {
 				w.byte('~')
@@ -305,7 +315,7 @@
 			w.string(fmt.Sprintf("$%d", i))
 		} else {
 			w.string(t.obj.name)
-			if w.debug || w.ctxt != nil {
+			if w.tpSubscripts || w.ctxt != nil {
 				w.string(subscript(t.id))
 			}
 		}
@@ -394,9 +404,7 @@
 }
 
 func (w *typeWriter) typeName(obj *TypeName) {
-	if obj.pkg != nil {
-		writePackage(w.buf, obj.pkg, w.qf)
-	}
+	w.string(packagePrefix(obj.pkg, w.qf))
 	w.string(obj.name)
 }
 
@@ -408,7 +416,7 @@
 				w.byte(',')
 			}
 			// parameter names are ignored for type identity and thus type hashes
-			if w.ctxt == nil && v.name != "" {
+			if w.ctxt == nil && v.name != "" && w.paramNames {
 				w.string(v.name)
 				w.byte(' ')
 			}
diff --git a/src/go/types/typestring_test.go b/src/go/types/typestring_test.go
index b7b8435..e73f241 100644
--- a/src/go/types/typestring_test.go
+++ b/src/go/types/typestring_test.go
@@ -5,10 +5,6 @@
 package types_test
 
 import (
-	"go/ast"
-	"go/importer"
-	"go/parser"
-	"go/token"
 	"internal/testenv"
 	"testing"
 
@@ -17,17 +13,6 @@
 
 const filename = "<src>"
 
-func makePkg(src string) (*Package, error) {
-	fset := token.NewFileSet()
-	file, err := parser.ParseFile(fset, filename, src, parser.DeclarationErrors)
-	if err != nil {
-		return nil, err
-	}
-	// use the package name as package path
-	conf := Config{Importer: importer.Default()}
-	return conf.Check(file.Name.Name, fset, []*ast.File{file}, nil)
-}
-
 type testEntry struct {
 	src, str string
 }
@@ -95,8 +80,8 @@
 	dup("interface{}"),
 	dup("interface{m()}"),
 	dup(`interface{String() string; m(int) float32}`),
-	dup("interface{int|float32|complex128}"),
-	dup("interface{int|~float32|~complex128}"),
+	dup("interface{int | float32 | complex128}"),
+	dup("interface{int | ~float32 | ~complex128}"),
 	dup("any"),
 	dup("interface{comparable}"),
 	// TODO(gri) adjust test for EvalCompositeTest
@@ -125,6 +110,7 @@
 }
 
 func TestTypeString(t *testing.T) {
+	// The Go command is needed for the importer to determine the locations of stdlib .a files.
 	testenv.MustHaveGoBuild(t)
 
 	var tests []testEntry
@@ -133,7 +119,7 @@
 
 	for _, test := range tests {
 		src := `package p; import "io"; type _ io.Writer; type T ` + test.src
-		pkg, err := makePkg(src)
+		pkg, err := typecheck(filename, src, nil)
 		if err != nil {
 			t.Errorf("%s: %s", src, err)
 			continue
@@ -151,8 +137,8 @@
 }
 
 func TestQualifiedTypeString(t *testing.T) {
-	p, _ := pkgFor("p.go", "package p; type T int", nil)
-	q, _ := pkgFor("q.go", "package q", nil)
+	p := mustTypecheck("p.go", "package p; type T int", nil)
+	q := mustTypecheck("q.go", "package q", nil)
 
 	pT := p.Scope().Lookup("T").Type()
 	for _, test := range []struct {
diff --git a/src/go/types/typexpr.go b/src/go/types/typexpr.go
index b02929d..03817dd 100644
--- a/src/go/types/typexpr.go
+++ b/src/go/types/typexpr.go
@@ -11,6 +11,7 @@
 	"go/ast"
 	"go/constant"
 	"go/internal/typeparams"
+	. "internal/types/errors"
 	"strings"
 )
 
@@ -35,15 +36,15 @@
 				x.mode = typexpr
 				x.typ = tpar
 			} else {
-				check.error(e, _InvalidBlank, "cannot use _ as value or type")
+				check.error(e, InvalidBlank, "cannot use _ as value or type")
 			}
 		} else {
-			check.errorf(e, _UndeclaredName, "undeclared name: %s", e.Name)
+			check.errorf(e, UndeclaredName, "undefined: %s", e.Name)
 		}
 		return
 	case universeAny, universeComparable:
 		if !check.allowVersion(check.pkg, 1, 18) {
-			check.versionErrorf(e, _UndeclaredName, "go1.18", "predeclared %s", e.Name)
+			check.versionErrorf(e, "go1.18", "predeclared %s", e.Name)
 			return // avoid follow-on errors
 		}
 	}
@@ -74,7 +75,7 @@
 
 	switch obj := obj.(type) {
 	case *PkgName:
-		check.errorf(e, _InvalidPkgUse, "use of package %s not in selector", obj.name)
+		check.errorf(e, InvalidPkgUse, "use of package %s not in selector", obj.name)
 		return
 
 	case *Const:
@@ -84,7 +85,7 @@
 		}
 		if obj == universeIota {
 			if check.iota == nil {
-				check.errorf(e, _InvalidIota, "cannot use iota outside constant declaration")
+				check.error(e, InvalidIota, "cannot use iota outside constant declaration")
 				return
 			}
 			x.val = check.iota
@@ -96,7 +97,7 @@
 
 	case *TypeName:
 		if check.isBrokenAlias(obj) {
-			check.errorf(e, _InvalidDeclCycle, "invalid use of type alias %s in recursive type (see issue #50729)", obj.name)
+			check.errorf(e, InvalidDeclCycle, "invalid use of type alias %s in recursive type (see issue #50729)", obj.name)
 			return
 		}
 		x.mode = typexpr
@@ -163,9 +164,9 @@
 			tset := computeInterfaceTypeSet(check, e.Pos(), t) // TODO(gri) is this the correct position?
 			if !tset.IsMethodSet() {
 				if tset.comparable {
-					check.softErrorf(e, _MisplacedConstraintIface, "cannot use type %s outside a type constraint: interface is (or embeds) comparable", typ)
+					check.softErrorf(e, MisplacedConstraintIface, "cannot use type %s outside a type constraint: interface is (or embeds) comparable", typ)
 				} else {
-					check.softErrorf(e, _MisplacedConstraintIface, "cannot use type %s outside a type constraint: interface contains type constraints", typ)
+					check.softErrorf(e, MisplacedConstraintIface, "cannot use type %s outside a type constraint: interface contains type constraints", typ)
 				}
 			}
 		}
@@ -180,7 +181,7 @@
 	typ := check.typInternal(e, def)
 	assert(isTyped(typ))
 	if isGeneric(typ) {
-		check.errorf(e, _WrongTypeArgCount, "cannot use generic type %s without instantiation", typ)
+		check.errorf(e, WrongTypeArgCount, "cannot use generic type %s without instantiation", typ)
 		typ = Typ[Invalid]
 	}
 	check.recordTypeAndValue(e, typexpr, typ, nil)
@@ -188,14 +189,14 @@
 }
 
 // genericType is like typ but the type must be an (uninstantiated) generic
-// type. If reason is non-nil and the type expression was a valid type but not
-// generic, reason will be populated with a message describing the error.
-func (check *Checker) genericType(e ast.Expr, reason *string) Type {
+// type. If cause is non-nil and the type expression was a valid type but not
+// generic, cause will be populated with a message describing the error.
+func (check *Checker) genericType(e ast.Expr, cause *string) Type {
 	typ := check.typInternal(e, nil)
 	assert(isTyped(typ))
 	if typ != Typ[Invalid] && !isGeneric(typ) {
-		if reason != nil {
-			*reason = check.sprintf("%s is not a generic type", typ)
+		if cause != nil {
+			*cause = check.sprintf("%s is not a generic type", typ)
 		}
 		typ = Typ[Invalid]
 	}
@@ -248,14 +249,14 @@
 		case invalid:
 			// ignore - error reported before
 		case novalue:
-			check.errorf(&x, _NotAType, "%s used as type", &x)
+			check.errorf(&x, NotAType, "%s used as type", &x)
 		default:
-			check.errorf(&x, _NotAType, "%s is not a type", &x)
+			check.errorf(&x, NotAType, "%s is not a type", &x)
 		}
 
 	case *ast.SelectorExpr:
 		var x operand
-		check.selector(&x, e, def)
+		check.selector(&x, e, def, true)
 
 		switch x.mode {
 		case typexpr:
@@ -265,15 +266,15 @@
 		case invalid:
 			// ignore - error reported before
 		case novalue:
-			check.errorf(&x, _NotAType, "%s used as type", &x)
+			check.errorf(&x, NotAType, "%s used as type", &x)
 		default:
-			check.errorf(&x, _NotAType, "%s is not a type", &x)
+			check.errorf(&x, NotAType, "%s is not a type", &x)
 		}
 
 	case *ast.IndexExpr, *ast.IndexListExpr:
 		ix := typeparams.UnpackIndexExpr(e)
 		if !check.allowVersion(check.pkg, 1, 18) {
-			check.softErrorf(inNode(e, ix.Lbrack), _UnsupportedFeature, "type instantiation requires go1.18 or later")
+			check.softErrorf(inNode(e, ix.Lbrack), UnsupportedFeature, "type instantiation requires go1.18 or later")
 		}
 		return check.instantiatedType(ix, def)
 
@@ -292,16 +293,24 @@
 
 		typ := new(Array)
 		def.setUnderlying(typ)
-		typ.len = check.arrayLength(e.Len)
+		// Provide a more specific error when encountering a [...] array
+		// rather than leaving it to the handling of the ... expression.
+		if _, ok := e.Len.(*ast.Ellipsis); ok {
+			check.error(e.Len, BadDotDotDotSyntax, "invalid use of [...] array (outside a composite literal)")
+			typ.len = -1
+		} else {
+			typ.len = check.arrayLength(e.Len)
+		}
 		typ.elem = check.varType(e.Elt)
 		if typ.len >= 0 {
 			return typ
 		}
+		// report error if we encountered [...]
 
 	case *ast.Ellipsis:
 		// dots are handled explicitly where they are legal
 		// (array composite literals and parameter lists)
-		check.error(e, _InvalidDotDotDot, "invalid use of '...'")
+		check.error(e, InvalidDotDotDot, "invalid use of '...'")
 		check.use(e.Elt)
 
 	case *ast.StructType:
@@ -348,7 +357,7 @@
 				if isTypeParam(typ.key) {
 					why = " (missing comparable constraint)"
 				}
-				check.errorf(e.Key, _IncomparableMapKey, "incomparable map key type %s%s", typ.key, why)
+				check.errorf(e.Key, IncomparableMapKey, "invalid map key type %s%s", typ.key, why)
 			}
 		}).describef(e.Key, "check map key %s", typ.key)
 
@@ -367,7 +376,7 @@
 		case ast.RECV:
 			dir = RecvOnly
 		default:
-			check.invalidAST(e, "unknown channel direction %d", e.Dir)
+			check.errorf(e, InvalidSyntaxTree, "unknown channel direction %d", e.Dir)
 			// ok to continue
 		}
 
@@ -376,7 +385,8 @@
 		return typ
 
 	default:
-		check.errorf(e0, _NotAType, "%s is not a type", e0)
+		check.errorf(e0, NotAType, "%s is not a type", e0)
+		check.use(e0)
 	}
 
 	typ := Typ[Invalid]
@@ -395,10 +405,10 @@
 		}()
 	}
 
-	var reason string
-	gtyp := check.genericType(ix.X, &reason)
-	if reason != "" {
-		check.invalidOp(ix.Orig, _NotAGenericType, "%s (%s)", ix.Orig, reason)
+	var cause string
+	gtyp := check.genericType(ix.X, &cause)
+	if cause != "" {
+		check.errorf(ix.Orig, NotAGenericType, invalidOp+"%s (%s)", ix.Orig, cause)
 	}
 	if gtyp == Typ[Invalid] {
 		return gtyp // error already reported
@@ -434,7 +444,7 @@
 				if i < len(ix.Indices) {
 					pos = ix.Indices[i].Pos()
 				}
-				check.softErrorf(atPos(pos), _InvalidTypeArg, err.Error())
+				check.softErrorf(atPos(pos), InvalidTypeArg, err.Error())
 			} else {
 				check.mono.recordInstance(check.pkg, ix.Pos(), inst.TypeParams().list(), inst.TypeArgs().list(), ix.Indices)
 			}
@@ -460,11 +470,11 @@
 	if name, _ := e.(*ast.Ident); name != nil {
 		obj := check.lookup(name.Name)
 		if obj == nil {
-			check.errorf(name, _InvalidArrayLen, "undeclared name %s for array length", name.Name)
+			check.errorf(name, InvalidArrayLen, "undefined array length %s or missing type constraint", name.Name)
 			return -1
 		}
 		if _, ok := obj.(*Const); !ok {
-			check.errorf(name, _InvalidArrayLen, "invalid array length %s", name.Name)
+			check.errorf(name, InvalidArrayLen, "invalid array length %s", name.Name)
 			return -1
 		}
 	}
@@ -473,7 +483,7 @@
 	check.expr(&x, e)
 	if x.mode != constant_ {
 		if x.mode != invalid {
-			check.errorf(&x, _InvalidArrayLen, "array length %s must be constant", &x)
+			check.errorf(&x, InvalidArrayLen, "array length %s must be constant", &x)
 		}
 		return -1
 	}
@@ -484,13 +494,13 @@
 				if n, ok := constant.Int64Val(val); ok && n >= 0 {
 					return n
 				}
-				check.errorf(&x, _InvalidArrayLen, "invalid array length %s", &x)
+				check.errorf(&x, InvalidArrayLen, "invalid array length %s", &x)
 				return -1
 			}
 		}
 	}
 
-	check.errorf(&x, _InvalidArrayLen, "array length %s must be integer", &x)
+	check.errorf(&x, InvalidArrayLen, "array length %s must be integer", &x)
 	return -1
 }
 
diff --git a/src/go/types/union.go b/src/go/types/union.go
index 37a3489..9509afe 100644
--- a/src/go/types/union.go
+++ b/src/go/types/union.go
@@ -7,6 +7,7 @@
 import (
 	"go/ast"
 	"go/token"
+	. "internal/types/errors"
 )
 
 // ----------------------------------------------------------------------------
@@ -67,7 +68,7 @@
 		}
 		if len(terms) >= maxTermCount {
 			if u != Typ[Invalid] {
-				check.errorf(x, _InvalidUnion, "cannot handle more than %d union terms (implementation limitation)", maxTermCount)
+				check.errorf(x, InvalidUnion, "cannot handle more than %d union terms (implementation limitation)", maxTermCount)
 				u = Typ[Invalid]
 			}
 		} else {
@@ -97,12 +98,12 @@
 			f, _ := u.(*Interface)
 			if t.tilde {
 				if f != nil {
-					check.errorf(tlist[i], _InvalidUnion, "invalid use of ~ (%s is an interface)", t.typ)
+					check.errorf(tlist[i], InvalidUnion, "invalid use of ~ (%s is an interface)", t.typ)
 					continue // don't report another error for t
 				}
 
 				if !Identical(u, t.typ) {
-					check.errorf(tlist[i], _InvalidUnion, "invalid use of ~ (underlying type of %s is %s)", t.typ, u)
+					check.errorf(tlist[i], InvalidUnion, "invalid use of ~ (underlying type of %s is %s)", t.typ, u)
 					continue
 				}
 			}
@@ -115,11 +116,11 @@
 				tset := f.typeSet()
 				switch {
 				case tset.NumMethods() != 0:
-					check.errorf(tlist[i], _InvalidUnion, "cannot use %s in union (%s contains methods)", t, t)
+					check.errorf(tlist[i], InvalidUnion, "cannot use %s in union (%s contains methods)", t, t)
 				case t.typ == universeComparable.Type():
-					check.error(tlist[i], _InvalidUnion, "cannot use comparable in union")
+					check.error(tlist[i], InvalidUnion, "cannot use comparable in union")
 				case tset.comparable:
-					check.errorf(tlist[i], _InvalidUnion, "cannot use %s in union (%s embeds comparable)", t, t)
+					check.errorf(tlist[i], InvalidUnion, "cannot use %s in union (%s embeds comparable)", t, t)
 				}
 				continue // terms with interface types are not subject to the no-overlap rule
 			}
@@ -127,7 +128,7 @@
 			// Report overlapping (non-disjoint) terms such as
 			// a|a, a|~a, ~a|~a, and ~a|A (where under(A) == a).
 			if j := overlappingTerm(terms[:i], t); j >= 0 {
-				check.softErrorf(tlist[i], _InvalidUnion, "overlapping terms %s and %s", t, terms[j])
+				check.softErrorf(tlist[i], InvalidUnion, "overlapping terms %s and %s", t, terms[j])
 			}
 		}
 	}).describef(uexpr, "check term validity %s", uexpr)
@@ -150,9 +151,9 @@
 	// and since the underlying type is an interface the embedding is well defined.
 	if isTypeParam(typ) {
 		if tilde {
-			check.errorf(x, _MisplacedTypeParam, "type in term %s cannot be a type parameter", tx)
+			check.errorf(x, MisplacedTypeParam, "type in term %s cannot be a type parameter", tx)
 		} else {
-			check.error(x, _MisplacedTypeParam, "term cannot be a type parameter")
+			check.error(x, MisplacedTypeParam, "term cannot be a type parameter")
 		}
 		typ = Typ[Invalid]
 	}
diff --git a/src/go/types/universe.go b/src/go/types/universe.go
index 8ac48e5..9103fca 100644
--- a/src/go/types/universe.go
+++ b/src/go/types/universe.go
@@ -146,6 +146,7 @@
 	// universe scope
 	_Append builtinId = iota
 	_Cap
+	_Clear
 	_Close
 	_Complex
 	_Copy
@@ -166,6 +167,9 @@
 	_Offsetof
 	_Sizeof
 	_Slice
+	_SliceData
+	_String
+	_StringData
 
 	// testing support
 	_Assert
@@ -180,6 +184,7 @@
 }{
 	_Append:  {"append", 1, true, expression},
 	_Cap:     {"cap", 1, false, expression},
+	_Clear:   {"clear", 1, false, statement},
 	_Close:   {"close", 1, false, statement},
 	_Complex: {"complex", 2, false, expression},
 	_Copy:    {"copy", 2, false, statement},
@@ -194,11 +199,14 @@
 	_Real:    {"real", 1, false, expression},
 	_Recover: {"recover", 0, false, statement},
 
-	_Add:      {"Add", 2, false, expression},
-	_Alignof:  {"Alignof", 1, false, expression},
-	_Offsetof: {"Offsetof", 1, false, expression},
-	_Sizeof:   {"Sizeof", 1, false, expression},
-	_Slice:    {"Slice", 2, false, expression},
+	_Add:        {"Add", 2, false, expression},
+	_Alignof:    {"Alignof", 1, false, expression},
+	_Offsetof:   {"Offsetof", 1, false, expression},
+	_Sizeof:     {"Sizeof", 1, false, expression},
+	_Slice:      {"Slice", 2, false, expression},
+	_SliceData:  {"SliceData", 1, false, expression},
+	_String:     {"String", 2, false, expression},
+	_StringData: {"StringData", 1, false, expression},
 
 	_Assert: {"assert", 1, false, statement},
 	_Trace:  {"trace", 0, true, statement},
diff --git a/src/go/types/validtype.go b/src/go/types/validtype.go
index 34c9533..d62c398 100644
--- a/src/go/types/validtype.go
+++ b/src/go/types/validtype.go
@@ -76,11 +76,32 @@
 		// embedded in itself, indicating an invalid recursive type.
 		for _, e := range nest {
 			if Identical(e, t) {
-				// t cannot be in an imported package otherwise that package
-				// would have reported a type cycle and couldn't have been
-				// imported in the first place.
+				// We have a cycle. If t != t.Origin() then t is an instance of
+				// the generic type t.Origin(). Because t is in the nest, t must
+				// occur within the definition (RHS) of the generic type t.Origin(),
+				// directly or indirectly, after expansion of the RHS.
+				// Therefore t.Origin() must be invalid, no matter how it is
+				// instantiated since the instantiation t of t.Origin() happens
+				// inside t.Origin()'s RHS and thus is always the same and always
+				// present.
+				// Therefore we can mark the underlying of both t and t.Origin()
+				// as invalid. If t is not an instance of a generic type, t and
+				// t.Origin() are the same.
+				// Furthermore, because we check all types in a package for validity
+				// before type checking is complete, any exported type that is invalid
+				// will have an invalid underlying type and we can't reach here with
+				// such a type (invalid types are excluded above).
+				// Thus, if we reach here with a type t, both t and t.Origin() (if
+				// different in the first place) must be from the current package;
+				// they cannot have been imported.
+				// Therefore it is safe to change their underlying types; there is
+				// no chance for a race condition (the types of the current package
+				// are not yet available to other goroutines).
 				assert(t.obj.pkg == check.pkg)
-				t.underlying = Typ[Invalid] // t is in the current package (no race possibility)
+				assert(t.Origin().obj.pkg == check.pkg)
+				t.underlying = Typ[Invalid]
+				t.Origin().underlying = Typ[Invalid]
+
 				// Find the starting point of the cycle and report it.
 				// Because each type in nest must also appear in path (see invariant below),
 				// type t must be in path since it was found in nest. But not every type in path
@@ -177,7 +198,7 @@
 //         nest = A[A[string]]->B[P]
 //         path = A[A[string]]->B[P]
 //
-// Eventutally we reach the type parameter P of type B (P₂):
+// Eventually we reach the type parameter P of type B (P₂):
 //
 //   P₂
 //         nest = A[A[string]]->B[P]
diff --git a/src/go/types/version.go b/src/go/types/version.go
index 1546941..3958ec9 100644
--- a/src/go/types/version.go
+++ b/src/go/types/version.go
@@ -8,6 +8,7 @@
 	"fmt"
 	"go/ast"
 	"go/token"
+	. "internal/types/errors"
 	"regexp"
 	"strconv"
 	"strings"
@@ -22,7 +23,7 @@
 	}
 	// len(s) > 2
 	if strings.Contains(s, "_") {
-		check.errorf(lit, _InvalidLit, "underscores in numeric literals requires go1.13 or later")
+		check.error(lit, UnsupportedFeature, "underscores in numeric literals requires go1.13 or later")
 		return
 	}
 	if s[0] != '0' {
@@ -30,15 +31,15 @@
 	}
 	radix := s[1]
 	if radix == 'b' || radix == 'B' {
-		check.errorf(lit, _InvalidLit, "binary literals requires go1.13 or later")
+		check.error(lit, UnsupportedFeature, "binary literals requires go1.13 or later")
 		return
 	}
 	if radix == 'o' || radix == 'O' {
-		check.errorf(lit, _InvalidLit, "0o/0O-style octal literals requires go1.13 or later")
+		check.error(lit, UnsupportedFeature, "0o/0O-style octal literals requires go1.13 or later")
 		return
 	}
 	if lit.Kind != token.INT && (radix == 'x' || radix == 'X') {
-		check.errorf(lit, _InvalidLit, "hexadecimal floating-point literals requires go1.13 or later")
+		check.error(lit, UnsupportedFeature, "hexadecimal floating-point literals requires go1.13 or later")
 	}
 }
 
@@ -79,4 +80,4 @@
 }
 
 // goVersionRx matches a Go version string, e.g. "go1.12".
-var goVersionRx = regexp.MustCompile(`^go([1-9][0-9]*)\.(0|[1-9][0-9]*)$`)
+var goVersionRx = regexp.MustCompile(`^go([1-9]\d*)\.(0|[1-9]\d*)$`)
diff --git a/src/hash/crc32/crc32.go b/src/hash/crc32/crc32.go
index f330fdb..e828089 100644
--- a/src/hash/crc32/crc32.go
+++ b/src/hash/crc32/crc32.go
@@ -76,16 +76,14 @@
 // using this polynomial.
 var castagnoliTable *Table
 var castagnoliTable8 *slicing8Table
-var castagnoliArchImpl bool
 var updateCastagnoli func(crc uint32, p []byte) uint32
 var castagnoliOnce sync.Once
-var haveCastagnoli uint32
+var haveCastagnoli atomic.Bool
 
 func castagnoliInit() {
 	castagnoliTable = simpleMakeTable(Castagnoli)
-	castagnoliArchImpl = archAvailableCastagnoli()
 
-	if castagnoliArchImpl {
+	if archAvailableCastagnoli() {
 		archInitCastagnoli()
 		updateCastagnoli = archUpdateCastagnoli
 	} else {
@@ -96,7 +94,7 @@
 		}
 	}
 
-	atomic.StoreUint32(&haveCastagnoli, 1)
+	haveCastagnoli.Store(true)
 }
 
 // IEEETable is the table for the IEEE polynomial.
@@ -104,14 +102,11 @@
 
 // ieeeTable8 is the slicing8Table for IEEE
 var ieeeTable8 *slicing8Table
-var ieeeArchImpl bool
 var updateIEEE func(crc uint32, p []byte) uint32
 var ieeeOnce sync.Once
 
 func ieeeInit() {
-	ieeeArchImpl = archAvailableIEEE()
-
-	if ieeeArchImpl {
+	if archAvailableIEEE() {
 		archInitIEEE()
 		updateIEEE = archUpdateIEEE
 	} else {
@@ -133,8 +128,9 @@
 	case Castagnoli:
 		castagnoliOnce.Do(castagnoliInit)
 		return castagnoliTable
+	default:
+		return simpleMakeTable(poly)
 	}
-	return simpleMakeTable(poly)
 }
 
 // digest represents the partial evaluation of a checksum.
@@ -210,32 +206,31 @@
 	return uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
 }
 
-// Update returns the result of adding the bytes in p to the crc.
-func Update(crc uint32, tab *Table, p []byte) uint32 {
+func update(crc uint32, tab *Table, p []byte, checkInitIEEE bool) uint32 {
 	switch {
-	case atomic.LoadUint32(&haveCastagnoli) != 0 && tab == castagnoliTable:
+	case haveCastagnoli.Load() && tab == castagnoliTable:
 		return updateCastagnoli(crc, p)
 	case tab == IEEETable:
-		// Unfortunately, because IEEETable is exported, IEEE may be used without a
-		// call to MakeTable. We have to make sure it gets initialized in that case.
-		ieeeOnce.Do(ieeeInit)
+		if checkInitIEEE {
+			ieeeOnce.Do(ieeeInit)
+		}
 		return updateIEEE(crc, p)
 	default:
 		return simpleUpdate(crc, tab, p)
 	}
 }
 
+// Update returns the result of adding the bytes in p to the crc.
+func Update(crc uint32, tab *Table, p []byte) uint32 {
+	// Unfortunately, because IEEETable is exported, IEEE may be used without a
+	// call to MakeTable. We have to make sure it gets initialized in that case.
+	return update(crc, tab, p, true)
+}
+
 func (d *digest) Write(p []byte) (n int, err error) {
-	switch {
-	case atomic.LoadUint32(&haveCastagnoli) != 0 && d.tab == castagnoliTable:
-		d.crc = updateCastagnoli(d.crc, p)
-	case d.tab == IEEETable:
-		// We only create digest objects through New() which takes care of
-		// initialization in this case.
-		d.crc = updateIEEE(d.crc, p)
-	default:
-		d.crc = simpleUpdate(d.crc, d.tab, p)
-	}
+	// We only create digest objects through New() which takes care of
+	// initialization in this case.
+	d.crc = update(d.crc, d.tab, p, false)
 	return len(p), nil
 }
 
diff --git a/src/hash/crc32/crc32_arm64.s b/src/hash/crc32/crc32_arm64.s
index 53274c5..85a113f 100644
--- a/src/hash/crc32/crc32_arm64.s
+++ b/src/hash/crc32/crc32_arm64.s
@@ -12,19 +12,22 @@
 	MOVD	p+8(FP), R13  // data pointer
 	MOVD	p_len+16(FP), R11  // len(p)
 
-	CMP	$8, R11
-	BLT	less_than_8
-
 update:
-	MOVD.P	8(R13), R10
+	CMP	$16, R11
+	BLT	less_than_16
+	LDP.P	16(R13), (R8, R10)
+	CRC32CX	R8, R9
 	CRC32CX	R10, R9
-	SUB	$8, R11
-
-	CMP	$8, R11
-	BLT	less_than_8
+	SUB	$16, R11
 
 	JMP	update
 
+less_than_16:
+	TBZ	$3, R11, less_than_8
+
+	MOVD.P	8(R13), R10
+	CRC32CX	R10, R9
+
 less_than_8:
 	TBZ	$2, R11, less_than_4
 
@@ -55,19 +58,22 @@
 	MOVD	p+8(FP), R13  // data pointer
 	MOVD	p_len+16(FP), R11  // len(p)
 
-	CMP	$8, R11
-	BLT	less_than_8
-
 update:
-	MOVD.P	8(R13), R10
+	CMP	$16, R11
+	BLT	less_than_16
+	LDP.P	16(R13), (R8, R10)
+	CRC32X	R8, R9
 	CRC32X	R10, R9
-	SUB	$8, R11
-
-	CMP	$8, R11
-	BLT	less_than_8
+	SUB	$16, R11
 
 	JMP	update
 
+less_than_16:
+	TBZ $3, R11, less_than_8
+
+	MOVD.P	8(R13), R10
+	CRC32X	R10, R9
+
 less_than_8:
 	TBZ	$2, R11, less_than_4
 
diff --git a/src/hash/crc32/crc32_ppc64le.go b/src/hash/crc32/crc32_ppc64le.go
index dcd3235..c22e38e 100644
--- a/src/hash/crc32/crc32_ppc64le.go
+++ b/src/hash/crc32/crc32_ppc64le.go
@@ -18,7 +18,7 @@
 //go:noescape
 func ppc64SlicingUpdateBy8(crc uint32, table8 *slicing8Table, p []byte) uint32
 
-// this function requires the buffer to be 16 byte aligned and > 16 bytes long
+// this function requires the buffer to be 16 byte aligned and > 16 bytes long.
 //
 //go:noescape
 func vectorCrc32(crc uint32, poly uint32, p []byte) uint32
diff --git a/src/hash/crc32/crc32_test.go b/src/hash/crc32/crc32_test.go
index cbb869d..f084612 100644
--- a/src/hash/crc32/crc32_test.go
+++ b/src/hash/crc32/crc32_test.go
@@ -329,11 +329,14 @@
 	h.Reset()
 	h.Write(data)
 	h.Sum(in)
+	// Avoid further allocations
+	in = in[:0]
 
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		h.Reset()
 		h.Write(data)
 		h.Sum(in)
+		in = in[:0]
 	}
 }
diff --git a/src/hash/crc64/crc64.go b/src/hash/crc64/crc64.go
index 063c63c..26b2573 100644
--- a/src/hash/crc64/crc64.go
+++ b/src/hash/crc64/crc64.go
@@ -163,7 +163,9 @@
 		} else if *tab == slicing8TableISO[0] {
 			helperTable = slicing8TableISO
 			// For smaller sizes creating extended table takes too much time
-		} else if len(p) > 16384 {
+		} else if len(p) >= 2048 {
+			// According to the tests between various x86 and arm CPUs, 2k is a reasonable
+			// threshold for now. This may change in the future.
 			helperTable = makeSlicingBy8Table(tab)
 		} else {
 			break
diff --git a/src/hash/maphash/maphash.go b/src/hash/maphash/maphash.go
index dfacd02..690068a 100644
--- a/src/hash/maphash/maphash.go
+++ b/src/hash/maphash/maphash.go
@@ -13,7 +13,6 @@
 package maphash
 
 import (
-	"internal/unsafeheader"
 	"unsafe"
 )
 
@@ -72,11 +71,11 @@
 		panic("maphash: use of uninitialized Seed")
 	}
 	for len(s) > bufSize {
-		p := (*byte)((*unsafeheader.String)(unsafe.Pointer(&s)).Data)
+		p := (*byte)(unsafe.StringData(s))
 		state = rthash(p, bufSize, state)
 		s = s[bufSize:]
 	}
-	p := (*byte)((*unsafeheader.String)(unsafe.Pointer(&s)).Data)
+	p := (*byte)(unsafe.StringData(s))
 	return rthash(p, len(s), state)
 }
 
@@ -190,7 +189,7 @@
 	if len(s) > bufSize {
 		h.initSeed()
 		for len(s) > bufSize {
-			ptr := (*byte)((*unsafeheader.String)(unsafe.Pointer(&s)).Data)
+			ptr := (*byte)(unsafe.StringData(s))
 			h.state.s = rthash(ptr, bufSize, h.state.s)
 			s = s[bufSize:]
 		}
diff --git a/src/hash/maphash/smhasher_test.go b/src/hash/maphash/smhasher_test.go
index 6e6f298..27cedc4 100644
--- a/src/hash/maphash/smhasher_test.go
+++ b/src/hash/maphash/smhasher_test.go
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !race
+
 package maphash
 
 import (
@@ -18,6 +20,9 @@
 // https://code.google.com/p/smhasher/
 // This code is a port of some of the Smhasher tests to Go.
 
+// Note: due to the long running time of these tests, they are
+// currently disabled in -race mode.
+
 var fixedSeed = MakeSeed()
 
 // Sanity checks.
diff --git a/src/html/template/clone_test.go b/src/html/template/clone_test.go
index 7cb1b9c..e4f6f78 100644
--- a/src/html/template/clone_test.go
+++ b/src/html/template/clone_test.go
@@ -5,7 +5,6 @@
 package template
 
 import (
-	"bytes"
 	"errors"
 	"fmt"
 	"io"
@@ -22,7 +21,7 @@
 		t.Fatal(err)
 	}
 	added := Must(root.AddParseTree("b", tree["b"]))
-	b := new(bytes.Buffer)
+	b := new(strings.Builder)
 	err = added.ExecuteTemplate(b, "a", "1>0")
 	if err != nil {
 		t.Fatal(err)
@@ -39,7 +38,7 @@
 	// In the t2 template, it will be in a JavaScript context.
 	// In the t3 template, it will be in a CSS context.
 	const tmpl = `{{define "a"}}{{template "lhs"}}{{.}}{{template "rhs"}}{{end}}`
-	b := new(bytes.Buffer)
+	b := new(strings.Builder)
 
 	// Create an incomplete template t0.
 	t0 := Must(New("t0").Parse(tmpl))
diff --git a/src/html/template/content.go b/src/html/template/content.go
index b104267..49d2f26 100644
--- a/src/html/template/content.go
+++ b/src/html/template/content.go
@@ -134,7 +134,7 @@
 
 // indirectToStringerOrError returns the value, after dereferencing as many times
 // as necessary to reach the base type (or nil) or an implementation of fmt.Stringer
-// or error,
+// or error.
 func indirectToStringerOrError(a any) any {
 	if a == nil {
 		return nil
diff --git a/src/html/template/content_test.go b/src/html/template/content_test.go
index f4af2f2..d1d8d2d 100644
--- a/src/html/template/content_test.go
+++ b/src/html/template/content_test.go
@@ -385,7 +385,7 @@
 		tmpl := Must(New("x").Parse(test.input))
 		pre := strings.Index(test.input, "{{.}}")
 		post := len(test.input) - (pre + 5)
-		var b bytes.Buffer
+		var b strings.Builder
 		for i, x := range data {
 			b.Reset()
 			if err := tmpl.Execute(&b, x); err != nil {
@@ -419,7 +419,7 @@
 
 func TestStringer(t *testing.T) {
 	s := &myStringer{3}
-	b := new(bytes.Buffer)
+	b := new(strings.Builder)
 	tmpl := Must(New("x").Parse("{{.}}"))
 	if err := tmpl.Execute(b, s); err != nil {
 		t.Fatal(err)
diff --git a/src/html/template/escape_test.go b/src/html/template/escape_test.go
index 58f3f27..12add07 100644
--- a/src/html/template/escape_test.go
+++ b/src/html/template/escape_test.go
@@ -688,7 +688,7 @@
 			t.Errorf("%s: tree not set properly", test.name)
 			continue
 		}
-		b := new(bytes.Buffer)
+		b := new(strings.Builder)
 		if err := tmpl.Execute(b, data); err != nil {
 			t.Errorf("%s: template execution failed: %s", test.name, err)
 			continue
@@ -735,7 +735,7 @@
 		},
 	} {
 		tmpl := Must(New("").Parse(test.input))
-		b := new(bytes.Buffer)
+		b := new(strings.Builder)
 		if err := tmpl.Execute(b, data); err != nil {
 			t.Errorf("%s: template execution failed: %s", test.desc, err)
 			continue
@@ -877,7 +877,7 @@
 			t.Errorf("error parsing %q: %v", source, err)
 			continue
 		}
-		var b bytes.Buffer
+		var b strings.Builder
 
 		if err := tmpl.ExecuteTemplate(&b, "main", data); err != nil {
 			t.Errorf("%q executing %v", err.Error(), tmpl.Lookup("main"))
@@ -1828,7 +1828,7 @@
 	bp := &b
 	bpp := &bp
 	tmpl := Must(New("t").Parse(`{{.}}`))
-	var buf bytes.Buffer
+	var buf strings.Builder
 	err := tmpl.Execute(&buf, ap)
 	if err != nil {
 		t.Errorf("Unexpected error: %s", err)
@@ -1871,7 +1871,7 @@
 				t.Errorf("panicked: %v\n", panicValue)
 			}
 		}()
-		var b bytes.Buffer
+		var b strings.Builder
 		tmpl.Execute(&b, Issue7379(0))
 		return b.String()
 	}
@@ -1904,7 +1904,7 @@
 		Parse(`{{define "main"}}<body>{{template "hello"}}</body>{{end}}`))
 	Must(tmpl.
 		Parse(`{{define "hello"}}Hello, {{"Ladies & Gentlemen!"}}{{end}}`))
-	got := new(bytes.Buffer)
+	got := new(strings.Builder)
 	var err error
 	// Ensure that "hello" produces the same output when executed twice.
 	want := "Hello, Ladies &amp; Gentlemen!"
@@ -1947,7 +1947,7 @@
 	t1 := Must(New("foo").Parse(`<a href="{{.}}">link1</a>`))
 	t2 := Must(t1.New("foo").Parse(`bar`))
 
-	var b bytes.Buffer
+	var b strings.Builder
 	const wantError = `template: "foo" is an incomplete or empty template`
 	if err := t1.Execute(&b, "javascript:alert(1)"); err == nil {
 		t.Fatal("expected error executing t1")
@@ -1976,7 +1976,7 @@
 	if _, err := tpl.AddParseTree("bar", tpl.Tree); err != nil {
 		t.Fatalf("AddParseTree error: %v", err)
 	}
-	var b1, b2 bytes.Buffer
+	var b1, b2 strings.Builder
 	if err := tpl.ExecuteTemplate(&b1, "foo", data); err != nil {
 		t.Fatalf(`ExecuteTemplate failed for "foo": %v`, err)
 	}
diff --git a/src/html/template/exec_test.go b/src/html/template/exec_test.go
index f042cf5..1ec346f 100644
--- a/src/html/template/exec_test.go
+++ b/src/html/template/exec_test.go
@@ -764,7 +764,7 @@
 }
 
 func testExecute(execTests []execTest, template *Template, t *testing.T) {
-	b := new(bytes.Buffer)
+	b := new(strings.Builder)
 	funcs := FuncMap{
 		"add":         add,
 		"count":       count,
@@ -856,7 +856,7 @@
 		if err != nil {
 			t.Fatalf("delim %q text %q parse err %s", left, text, err)
 		}
-		var b = new(bytes.Buffer)
+		var b = new(strings.Builder)
 		err = tmpl.Execute(b, value)
 		if err != nil {
 			t.Fatalf("delim %q exec err %s", left, err)
@@ -997,7 +997,7 @@
 	if err != nil {
 		t.Fatal("parse error:", err)
 	}
-	var b bytes.Buffer
+	var b strings.Builder
 	const expect = "[1[2[3[4]][5[6]]][7[8[9]][10[11]]]]"
 	// First by looking up the template.
 	err = tmpl.Lookup("tree").Execute(&b, tree)
@@ -1207,7 +1207,7 @@
 }
 
 func TestComparison(t *testing.T) {
-	b := new(bytes.Buffer)
+	b := new(strings.Builder)
 	var cmpStruct = struct {
 		Uthree, Ufour  uint
 		NegOne, Three  int
@@ -1255,7 +1255,7 @@
 	if err != nil {
 		t.Fatal(err)
 	}
-	var b bytes.Buffer
+	var b strings.Builder
 	// By default, just get "<no value>" // NOTE: not in html/template, get empty string
 	err = tmpl.Execute(&b, data)
 	if err != nil {
@@ -1424,7 +1424,7 @@
 		t.Fatal(err)
 	}
 
-	var buf bytes.Buffer
+	var buf strings.Builder
 	if err := tmpl.Execute(&buf, "hello"); err != nil {
 		t.Fatal(err)
 	}
@@ -1530,7 +1530,7 @@
 	}
 	for _, text := range texts {
 		tmpl := Must(New("tmpl").Parse(text))
-		var buf bytes.Buffer
+		var buf strings.Builder
 		err := tmpl.Execute(&buf, reflect.ValueOf([]V{{1}}))
 		if err != nil {
 			t.Fatalf("%s: Execute: %v", text, err)
@@ -1586,7 +1586,7 @@
 
 	for _, tt := range tests {
 		tmpl := Must(New("tmpl").Parse(tt.text))
-		var buf bytes.Buffer
+		var buf strings.Builder
 		err := tmpl.Execute(&buf, map[string]any{
 			"PlusOne": func(n int) int {
 				return n + 1
@@ -1681,7 +1681,7 @@
 	t.Skip("broken in html/template")
 
 	// A simple value with no arguments is fine.
-	var b bytes.Buffer
+	var b strings.Builder
 	const text = "{{ (.)  }}"
 	tmpl, err := New("").Parse(text)
 	if err != nil {
diff --git a/src/html/template/html.go b/src/html/template/html.go
index 46e9d93..bcca0b5 100644
--- a/src/html/template/html.go
+++ b/src/html/template/html.go
@@ -176,7 +176,7 @@
 // stripTags takes a snippet of HTML and returns only the text content.
 // For example, `<b>&iexcl;Hi!</b> <script>...</script>` -> `&iexcl;Hi! `.
 func stripTags(html string) string {
-	var b bytes.Buffer
+	var b strings.Builder
 	s, c, i, allText := []byte(html), context{}, 0, true
 	// Using the transition funcs helps us avoid mangling
 	// `<div title="1>2">` or `I <3 Ponies!`.
diff --git a/src/html/template/js_test.go b/src/html/template/js_test.go
index 56579d8..580cb0a 100644
--- a/src/html/template/js_test.go
+++ b/src/html/template/js_test.go
@@ -5,7 +5,6 @@
 package template
 
 import (
-	"bytes"
 	"math"
 	"strings"
 	"testing"
@@ -321,7 +320,7 @@
 
 		// Escape it rune by rune to make sure that any
 		// fast-path checking does not break escaping.
-		var buf bytes.Buffer
+		var buf strings.Builder
 		for _, c := range input {
 			buf.WriteString(test.escaper(string(c)))
 		}
diff --git a/src/html/template/multi_test.go b/src/html/template/multi_test.go
index 6535ab6..2105086 100644
--- a/src/html/template/multi_test.go
+++ b/src/html/template/multi_test.go
@@ -8,8 +8,8 @@
 
 import (
 	"archive/zip"
-	"bytes"
 	"os"
+	"strings"
 	"testing"
 	"text/template/parse"
 )
@@ -245,7 +245,7 @@
 				t.Fatal(err)
 			}
 		}
-		buf := &bytes.Buffer{}
+		buf := &strings.Builder{}
 		if err := m.Execute(buf, c.in); err != nil {
 			t.Error(i, err)
 			continue
@@ -280,7 +280,7 @@
 				t.Fatal(err)
 			}
 		}
-		var buf bytes.Buffer
+		var buf strings.Builder
 		res.Execute(&buf, 0)
 		if buf.String() != "stylesheet" {
 			t.Fatalf("iteration %d: got %q; expected %q", i, buf.String(), "stylesheet")
diff --git a/src/html/template/template_test.go b/src/html/template/template_test.go
index 99a1091..96d8013 100644
--- a/src/html/template/template_test.go
+++ b/src/html/template/template_test.go
@@ -26,7 +26,7 @@
 
 	const want = "stuff"
 	parsed := Must(clone.Parse(want))
-	var buf bytes.Buffer
+	var buf strings.Builder
 	err = parsed.Execute(&buf, nil)
 	if err != nil {
 		t.Fatal(err)
@@ -207,7 +207,7 @@
 }
 
 func (c *testCase) mustExecute(t *Template, val any, want string) {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	err := t.Execute(&buf, val)
 	if err != nil {
 		c.t.Fatalf("execute: %v", err)
diff --git a/src/html/template/url.go b/src/html/template/url.go
index 9d0be39..7820561 100644
--- a/src/html/template/url.go
+++ b/src/html/template/url.go
@@ -5,7 +5,6 @@
 package template
 
 import (
-	"bytes"
 	"fmt"
 	"strings"
 )
@@ -76,7 +75,7 @@
 	if t == contentTypeURL {
 		norm = true
 	}
-	var b bytes.Buffer
+	var b strings.Builder
 	if processURLOnto(s, norm, &b) {
 		return b.String()
 	}
@@ -85,7 +84,7 @@
 
 // processURLOnto appends a normalized URL corresponding to its input to b
 // and reports whether the appended content differs from s.
-func processURLOnto(s string, norm bool, b *bytes.Buffer) bool {
+func processURLOnto(s string, norm bool, b *strings.Builder) bool {
 	b.Grow(len(s) + 16)
 	written := 0
 	// The byte loop below assumes that all URLs use UTF-8 as the
@@ -149,7 +148,7 @@
 	case contentTypeURL:
 		// Normalizing gets rid of all HTML whitespace
 		// which separate the image URL from its metadata.
-		var b bytes.Buffer
+		var b strings.Builder
 		if processURLOnto(s, true, &b) {
 			s = b.String()
 		}
@@ -157,7 +156,7 @@
 		return strings.ReplaceAll(s, ",", "%2c")
 	}
 
-	var b bytes.Buffer
+	var b strings.Builder
 	written := 0
 	for i := 0; i < len(s); i++ {
 		if s[i] == ',' {
@@ -183,7 +182,7 @@
 	return (c < 0x80) && 0 != (htmlSpaceAndASCIIAlnumBytes[c>>3]&(1<<uint(c&0x7)))
 }
 
-func filterSrcsetElement(s string, left int, right int, b *bytes.Buffer) {
+func filterSrcsetElement(s string, left int, right int, b *strings.Builder) {
 	start := left
 	for start < right && isHTMLSpace(s[start]) {
 		start++
diff --git a/src/image/format.go b/src/image/format.go
index a53b8f9..51d7ad9 100644
--- a/src/image/format.go
+++ b/src/image/format.go
@@ -55,7 +55,7 @@
 	return bufio.NewReader(r)
 }
 
-// Match reports whether magic matches b. Magic may contain "?" wildcards.
+// match reports whether magic matches b. Magic may contain "?" wildcards.
 func match(magic string, b []byte) bool {
 	if len(magic) != len(b) {
 		return false
@@ -68,7 +68,7 @@
 	return true
 }
 
-// Sniff determines the format of r's data.
+// sniff determines the format of r's data.
 func sniff(r reader) format {
 	formats, _ := atomicFormats.Load().([]format)
 	for _, f := range formats {
diff --git a/src/image/gif/fuzz_test.go b/src/image/gif/fuzz_test.go
index 3ddf15d..a4bc06e 100644
--- a/src/image/gif/fuzz_test.go
+++ b/src/image/gif/fuzz_test.go
@@ -14,6 +14,10 @@
 )
 
 func FuzzDecode(f *testing.F) {
+	if testing.Short() {
+		f.Skip("Skipping in short mode")
+	}
+
 	testdata, err := os.ReadDir("../testdata")
 	if err != nil {
 		f.Fatalf("failed to read testdata directory: %s", err)
diff --git a/src/image/gif/reader.go b/src/image/gif/reader.go
index 9e8268c..0867b10 100644
--- a/src/image/gif/reader.go
+++ b/src/image/gif/reader.go
@@ -250,6 +250,10 @@
 				return err
 			}
 
+			if !keepAllFrames && len(d.image) == 1 {
+				return nil
+			}
+
 		case sTrailer:
 			if len(d.image) == 0 {
 				return fmt.Errorf("gif: missing image data")
diff --git a/src/image/gif/reader_test.go b/src/image/gif/reader_test.go
index 5eec5ec..a7f943a 100644
--- a/src/image/gif/reader_test.go
+++ b/src/image/gif/reader_test.go
@@ -379,7 +379,7 @@
 
 func TestUnexpectedEOF(t *testing.T) {
 	for i := len(testGIF) - 1; i >= 0; i-- {
-		_, err := Decode(bytes.NewReader(testGIF[:i]))
+		_, err := DecodeAll(bytes.NewReader(testGIF[:i]))
 		if err == errNotEnough {
 			continue
 		}
diff --git a/src/image/jpeg/dct_test.go b/src/image/jpeg/dct_test.go
index 845e758..ed5b73d 100644
--- a/src/image/jpeg/dct_test.go
+++ b/src/image/jpeg/dct_test.go
@@ -5,10 +5,10 @@
 package jpeg
 
 import (
-	"bytes"
 	"fmt"
 	"math"
 	"math/rand"
+	"strings"
 	"testing"
 )
 
@@ -181,7 +181,7 @@
 }
 
 func (b *block) String() string {
-	s := bytes.NewBuffer(nil)
+	s := &strings.Builder{}
 	fmt.Fprintf(s, "{\n")
 	for y := 0; y < 8; y++ {
 		fmt.Fprintf(s, "\t")
diff --git a/src/image/jpeg/fuzz_test.go b/src/image/jpeg/fuzz_test.go
index 716f06f..bd534a9 100644
--- a/src/image/jpeg/fuzz_test.go
+++ b/src/image/jpeg/fuzz_test.go
@@ -14,6 +14,10 @@
 )
 
 func FuzzDecode(f *testing.F) {
+	if testing.Short() {
+		f.Skip("Skipping in short mode")
+	}
+
 	testdata, err := os.ReadDir("../testdata")
 	if err != nil {
 		f.Fatalf("failed to read testdata directory: %s", err)
diff --git a/src/image/jpeg/reader_test.go b/src/image/jpeg/reader_test.go
index 6fdb6c4..02a2eb6 100644
--- a/src/image/jpeg/reader_test.go
+++ b/src/image/jpeg/reader_test.go
@@ -177,7 +177,7 @@
 }
 
 func pixString(pix []byte, stride, x, y int) string {
-	s := bytes.NewBuffer(nil)
+	s := &strings.Builder{}
 	for j := 0; j < 8; j++ {
 		fmt.Fprintf(s, "\t")
 		for i := 0; i < 8; i++ {
diff --git a/src/image/jpeg/writer_test.go b/src/image/jpeg/writer_test.go
index abd5e32..3414770 100644
--- a/src/image/jpeg/writer_test.go
+++ b/src/image/jpeg/writer_test.go
@@ -13,6 +13,7 @@
 	"io"
 	"math/rand"
 	"os"
+	"strings"
 	"testing"
 )
 
@@ -82,7 +83,7 @@
 	}
 	if bad {
 		names := [nQuantIndex]string{"Luminance", "Chrominance"}
-		buf := &bytes.Buffer{}
+		buf := &strings.Builder{}
 		for i, name := range names {
 			fmt.Fprintf(buf, "// %s.\n{\n", name)
 			for zig := 0; zig < blockSize; zig++ {
diff --git a/src/image/png/fuzz_test.go b/src/image/png/fuzz_test.go
index 22b3ef0..4b63945 100644
--- a/src/image/png/fuzz_test.go
+++ b/src/image/png/fuzz_test.go
@@ -14,6 +14,10 @@
 )
 
 func FuzzDecode(f *testing.F) {
+	if testing.Short() {
+		f.Skip("Skipping in short mode")
+	}
+
 	testdata, err := os.ReadDir("../testdata")
 	if err != nil {
 		f.Fatalf("failed to read testdata directory: %s", err)
diff --git a/src/image/png/reader.go b/src/image/png/reader.go
index 95b507c..3a71734 100644
--- a/src/image/png/reader.go
+++ b/src/image/png/reader.go
@@ -51,6 +51,10 @@
 	return cbP1 <= cb && cb <= cbP8
 }
 
+func cbTrueColor(cb int) bool {
+	return cb == cbTC8 || cb == cbTC16
+}
+
 // Filter type, as per the PNG spec.
 const (
 	ftNone    = 0
@@ -870,7 +874,7 @@
 	return d.verifyChecksum()
 }
 
-func (d *decoder) parseChunk() error {
+func (d *decoder) parseChunk(configOnly bool) error {
 	// Read the length and chunk type.
 	if _, err := io.ReadFull(d.r, d.tmp[:8]); err != nil {
 		return err
@@ -898,6 +902,10 @@
 			if d.stage != dsSeenPLTE {
 				return chunkOrderError
 			}
+		} else if cbTrueColor(d.cb) {
+			if d.stage != dsSeenIHDR && d.stage != dsSeenPLTE {
+				return chunkOrderError
+			}
 		} else if d.stage != dsSeenIHDR {
 			return chunkOrderError
 		}
@@ -915,6 +923,9 @@
 			break
 		}
 		d.stage = dsSeenIDAT
+		if configOnly {
+			return nil
+		}
 		return d.parseIDAT(length)
 	case "IEND":
 		if d.stage != dsSeenIDAT {
@@ -974,7 +985,7 @@
 		return nil, err
 	}
 	for d.stage != dsSeenIEND {
-		if err := d.parseChunk(); err != nil {
+		if err := d.parseChunk(false); err != nil {
 			if err == io.EOF {
 				err = io.ErrUnexpectedEOF
 			}
@@ -997,21 +1008,26 @@
 		}
 		return image.Config{}, err
 	}
+
 	for {
-		if err := d.parseChunk(); err != nil {
+		if err := d.parseChunk(true); err != nil {
 			if err == io.EOF {
 				err = io.ErrUnexpectedEOF
 			}
 			return image.Config{}, err
 		}
-		paletted := cbPaletted(d.cb)
-		if d.stage == dsSeenIHDR && !paletted {
-			break
-		}
-		if d.stage == dsSeenPLTE && paletted {
-			break
+
+		if cbPaletted(d.cb) {
+			if d.stage >= dsSeentRNS {
+				break
+			}
+		} else {
+			if d.stage >= dsSeenIHDR {
+				break
+			}
 		}
 	}
+
 	var cm color.Model
 	switch d.cb {
 	case cbG1, cbG2, cbG4, cbG8:
diff --git a/src/image/png/reader_test.go b/src/image/png/reader_test.go
index 3937685..ccf30b2 100644
--- a/src/image/png/reader_test.go
+++ b/src/image/png/reader_test.go
@@ -783,6 +783,59 @@
 	}
 }
 
+func TestDecodePalettedWithTransparency(t *testing.T) {
+	// These bytes come from https://go.dev/issue/54325
+	//
+	// Per the PNG spec, a PLTE chunk contains 3 (not 4) bytes per palette
+	// entry: RGB (not RGBA). The alpha value comes from the optional tRNS
+	// chunk. Here, the PLTE chunk (0x50, 0x4c, 0x54, 0x45, etc) has 16 entries
+	// (0x30 = 48 bytes) and the tRNS chunk (0x74, 0x52, 0x4e, 0x53, etc) has 1
+	// entry (0x01 = 1 byte) that sets the first palette entry's alpha to zero.
+	//
+	// Both Decode and DecodeConfig should pick up that the first palette
+	// entry's alpha is zero.
+	src := []byte{
+		0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
+		0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x04, 0x03, 0x00, 0x00, 0x00, 0x81, 0x54, 0x67,
+		0xc7, 0x00, 0x00, 0x00, 0x30, 0x50, 0x4c, 0x54, 0x45, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0e,
+		0x00, 0x23, 0x27, 0x7b, 0xb1, 0x2d, 0x0a, 0x49, 0x3f, 0x19, 0x78, 0x5f, 0xcd, 0xe4, 0x69, 0x69,
+		0xe4, 0x71, 0x59, 0x53, 0x80, 0x11, 0x14, 0x8b, 0x00, 0xa9, 0x8d, 0x95, 0xcb, 0x99, 0x2f, 0x6b,
+		0xd7, 0x29, 0x91, 0xd7, 0x7b, 0xba, 0xff, 0xe3, 0xd7, 0x13, 0xc6, 0xd3, 0x58, 0x00, 0x00, 0x00,
+		0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0xfd, 0x49, 0x44,
+		0x41, 0x54, 0x28, 0xcf, 0x63, 0x60, 0x00, 0x83, 0x55, 0x0c, 0x68, 0x60, 0x9d, 0x02, 0x9a, 0x80,
+		0xde, 0x23, 0x74, 0x15, 0xef, 0x50, 0x94, 0x70, 0x2d, 0xd2, 0x7b, 0x87, 0xa2, 0x84, 0xeb, 0xee,
+		0xbb, 0x77, 0x6f, 0x51, 0x94, 0xe8, 0xbd, 0x7d, 0xf7, 0xee, 0x12, 0xb2, 0x80, 0xd2, 0x3d, 0x54,
+		0x01, 0x26, 0x10, 0x1f, 0x59, 0x40, 0x0f, 0xc8, 0xd7, 0x7e, 0x84, 0x70, 0x1c, 0xd7, 0xba, 0xb7,
+		0x4a, 0xda, 0xda, 0x77, 0x11, 0xf6, 0xac, 0x5a, 0xa5, 0xf4, 0xf9, 0xbf, 0xfd, 0x3d, 0x24, 0x6b,
+		0x98, 0x94, 0xf4, 0xff, 0x7f, 0x52, 0x42, 0x16, 0x30, 0x0e, 0xd9, 0xed, 0x6a, 0x8c, 0xec, 0x10,
+		0x65, 0x53, 0x97, 0x60, 0x23, 0x64, 0x1d, 0x8a, 0x2e, 0xc6, 0x2e, 0x42, 0x08, 0x3d, 0x4c, 0xca,
+		0x81, 0xc1, 0x82, 0xa6, 0xa2, 0x46, 0x08, 0x3d, 0x4a, 0xa1, 0x82, 0xc6, 0x82, 0xa1, 0x4a, 0x08,
+		0x3d, 0xfa, 0xa6, 0x81, 0xa1, 0xa2, 0xc1, 0x9f, 0x10, 0x66, 0xd4, 0x2b, 0x87, 0x0a, 0x86, 0x1a,
+		0x7d, 0x57, 0x80, 0x9b, 0x99, 0xaf, 0x62, 0x1a, 0x1a, 0xec, 0xf0, 0x0d, 0x66, 0x2a, 0x7b, 0x5a,
+		0xba, 0xd2, 0x64, 0x63, 0x4b, 0xa6, 0xb2, 0xb4, 0x02, 0xa8, 0x12, 0xb5, 0x24, 0xa5, 0x99, 0x2e,
+		0x33, 0x95, 0xd4, 0x92, 0x10, 0xee, 0xd0, 0x59, 0xb9, 0x6a, 0xd6, 0x21, 0x24, 0xb7, 0x33, 0x9d,
+		0x01, 0x01, 0x64, 0xbf, 0xac, 0x59, 0xb2, 0xca, 0xeb, 0x14, 0x92, 0x80, 0xd6, 0x9a, 0x53, 0x4a,
+		0x6b, 0x4e, 0x2d, 0x42, 0x52, 0xa1, 0x73, 0x28, 0x54, 0xe7, 0x90, 0x6a, 0x00, 0x92, 0x92, 0x45,
+		0xa1, 0x40, 0x84, 0x2c, 0xe0, 0xc4, 0xa0, 0xb2, 0x28, 0x14, 0xc1, 0x67, 0xe9, 0x50, 0x60, 0x60,
+		0xea, 0x70, 0x40, 0x12, 0x00, 0x79, 0x54, 0x09, 0x22, 0x00, 0x00, 0x30, 0xf3, 0x52, 0x87, 0xc6,
+		0xe4, 0xbd, 0x70, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
+	}
+
+	cfg, err := DecodeConfig(bytes.NewReader(src))
+	if err != nil {
+		t.Fatalf("DecodeConfig: %v", err)
+	} else if _, _, _, alpha := cfg.ColorModel.(color.Palette)[0].RGBA(); alpha != 0 {
+		t.Errorf("DecodeConfig: got %d, want 0", alpha)
+	}
+
+	img, err := Decode(bytes.NewReader(src))
+	if err != nil {
+		t.Fatalf("Decode: %v", err)
+	} else if _, _, _, alpha := img.ColorModel().(color.Palette)[0].RGBA(); alpha != 0 {
+		t.Errorf("Decode: got %d, want 0", alpha)
+	}
+}
+
 func benchmarkDecode(b *testing.B, filename string, bytesPerPixel int) {
 	data, err := os.ReadFile(filename)
 	if err != nil {
diff --git a/src/image/png/writer.go b/src/image/png/writer.go
index cbcdb9e..0d747da 100644
--- a/src/image/png/writer.go
+++ b/src/image/png/writer.go
@@ -450,6 +450,36 @@
 			if nrgba != nil {
 				offset := (y - b.Min.Y) * nrgba.Stride
 				copy(cr[0][1:], nrgba.Pix[offset:offset+b.Dx()*4])
+			} else if rgba != nil {
+				dst := cr[0][1:]
+				src := rgba.Pix[rgba.PixOffset(b.Min.X, y):rgba.PixOffset(b.Max.X, y)]
+				for ; len(src) >= 4; dst, src = dst[4:], src[4:] {
+					d := (*[4]byte)(dst)
+					s := (*[4]byte)(src)
+					if s[3] == 0x00 {
+						d[0] = 0
+						d[1] = 0
+						d[2] = 0
+						d[3] = 0
+					} else if s[3] == 0xff {
+						copy(d[:], s[:])
+					} else {
+						// This code does the same as color.NRGBAModel.Convert(
+						// rgba.At(x, y)).(color.NRGBA) but with no extra memory
+						// allocations or interface/function call overhead.
+						//
+						// The multiplier m combines 0x101 (which converts
+						// 8-bit color to 16-bit color) and 0xffff (which, when
+						// combined with the division-by-a, converts from
+						// alpha-premultiplied to non-alpha-premultiplied).
+						const m = 0x101 * 0xffff
+						a := uint32(s[3]) * 0x101
+						d[0] = uint8((uint32(s[0]) * m / a) >> 8)
+						d[1] = uint8((uint32(s[1]) * m / a) >> 8)
+						d[2] = uint8((uint32(s[2]) * m / a) >> 8)
+						d[3] = s[3]
+					}
+				}
 			} else {
 				// Convert from image.Image (which is alpha-premultiplied) to PNG's non-alpha-premultiplied.
 				for x := b.Min.X; x < b.Max.X; x++ {
diff --git a/src/image/png/writer_test.go b/src/image/png/writer_test.go
index 47aa861..6dac8ec 100644
--- a/src/image/png/writer_test.go
+++ b/src/image/png/writer_test.go
@@ -11,6 +11,7 @@
 	"fmt"
 	"image"
 	"image/color"
+	"image/draw"
 	"io"
 	"testing"
 )
@@ -29,7 +30,7 @@
 			r0, g0, b0, a0 := c0.RGBA()
 			r1, g1, b1, a1 := c1.RGBA()
 			if r0 != r1 || g0 != g1 || b0 != b1 || a0 != a1 {
-				return fmt.Errorf("colors differ at (%d, %d): %v vs %v", x, y, c0, c1)
+				return fmt.Errorf("colors differ at (%d, %d): %T%v vs %T%v", x, y, c0, c0, c1, c1)
 			}
 		}
 	}
@@ -45,6 +46,13 @@
 	return Decode(&b)
 }
 
+func convertToNRGBA(m image.Image) *image.NRGBA {
+	b := m.Bounds()
+	ret := image.NewNRGBA(b)
+	draw.Draw(ret, b, m, b.Min, draw.Src)
+	return ret
+}
+
 func TestWriter(t *testing.T) {
 	// The filenames variable is declared in reader_test.go.
 	names := filenames
@@ -227,6 +235,49 @@
 	}
 }
 
+func TestWriteRGBA(t *testing.T) {
+	const width, height = 640, 480
+	transparentImg := image.NewRGBA(image.Rect(0, 0, width, height))
+	opaqueImg := image.NewRGBA(image.Rect(0, 0, width, height))
+	mixedImg := image.NewRGBA(image.Rect(0, 0, width, height))
+	translucentImg := image.NewRGBA(image.Rect(0, 0, width, height))
+	for y := 0; y < height; y++ {
+		for x := 0; x < width; x++ {
+			opaqueColor := color.RGBA{uint8(x), uint8(y), uint8(y + x), 255}
+			translucentColor := color.RGBA{uint8(x) % 128, uint8(y) % 128, uint8(y+x) % 128, 128}
+			opaqueImg.Set(x, y, opaqueColor)
+			translucentImg.Set(x, y, translucentColor)
+			if y%2 == 0 {
+				mixedImg.Set(x, y, opaqueColor)
+			}
+		}
+	}
+
+	testCases := []struct {
+		name string
+		img  image.Image
+	}{
+		{"Transparent RGBA", transparentImg},
+		{"Opaque RGBA", opaqueImg},
+		{"50/50 Transparent/Opaque RGBA", mixedImg},
+		{"RGBA with variable alpha", translucentImg},
+	}
+
+	for _, tc := range testCases {
+		t.Run(tc.name, func(t *testing.T) {
+			m0 := tc.img
+			m1, err := encodeDecode(m0)
+			if err != nil {
+				t.Fatal(err)
+			}
+			err = diff(convertToNRGBA(m0), m1)
+			if err != nil {
+				t.Error(err)
+			}
+		})
+	}
+}
+
 func BenchmarkEncodeGray(b *testing.B) {
 	img := image.NewGray(image.Rect(0, 0, 640, 480))
 	b.SetBytes(640 * 480 * 1)
@@ -329,11 +380,25 @@
 }
 
 func BenchmarkEncodeRGBA(b *testing.B) {
-	img := image.NewRGBA(image.Rect(0, 0, 640, 480))
+	const width, height = 640, 480
+	img := image.NewRGBA(image.Rect(0, 0, width, height))
+	for y := 0; y < height; y++ {
+		for x := 0; x < width; x++ {
+			percent := (x + y) % 100
+			switch {
+			case percent < 10: // 10% of pixels are translucent (have alpha >0 and <255)
+				img.Set(x, y, color.NRGBA{uint8(x), uint8(y), uint8(x * y), uint8(percent)})
+			case percent < 40: // 30% of pixels are transparent (have alpha == 0)
+				img.Set(x, y, color.NRGBA{uint8(x), uint8(y), uint8(x * y), 0})
+			default: // 60% of pixels are opaque (have alpha == 255)
+				img.Set(x, y, color.NRGBA{uint8(x), uint8(y), uint8(x * y), 255})
+			}
+		}
+	}
 	if img.Opaque() {
 		b.Fatal("expected image not to be opaque")
 	}
-	b.SetBytes(640 * 480 * 4)
+	b.SetBytes(width * height * 4)
 	b.ReportAllocs()
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
diff --git a/src/internal/abi/abi_generic.go b/src/internal/abi/abi_generic.go
index d5803e7..76ef2e2 100644
--- a/src/internal/abi/abi_generic.go
+++ b/src/internal/abi/abi_generic.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build !goexperiment.regabiargs && !amd64 && !arm64 && !ppc64 && !ppc64le
+//go:build !goexperiment.regabiargs && !amd64 && !arm64 && !ppc64 && !ppc64le && !riscv64
 
 package abi
 
diff --git a/src/internal/abi/abi_riscv64.go b/src/internal/abi/abi_riscv64.go
index 1656820..2bcd9d6 100644
--- a/src/internal/abi/abi_riscv64.go
+++ b/src/internal/abi/abi_riscv64.go
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build goexperiment.regabiargs
-
 package abi
 
 const (
diff --git a/src/internal/abi/abi_test.go b/src/internal/abi/abi_test.go
index 51d26f6..f0d8dce 100644
--- a/src/internal/abi/abi_test.go
+++ b/src/internal/abi/abi_test.go
@@ -42,6 +42,9 @@
 	symabi := filepath.Join(tmpdir, "symabi")
 	obj := filepath.Join(tmpdir, "x.o")
 
+	importcfgfile := filepath.Join(tmpdir, "hello.importcfg")
+	testenv.WriteImportcfg(t, importcfgfile, nil)
+
 	// parse assembly code for symabi.
 	cmd := exec.Command(testenv.GoToolPath(t), "tool", "asm", "-gensymabis", "-o", symabi, asmSrc)
 	out, err := cmd.CombinedOutput()
@@ -50,7 +53,7 @@
 	}
 
 	// compile go code.
-	cmd = exec.Command(testenv.GoToolPath(t), "tool", "compile", "-p=p", "-symabis", symabi, "-o", obj, goSrc)
+	cmd = exec.Command(testenv.GoToolPath(t), "tool", "compile", "-importcfg="+importcfgfile, "-p=p", "-symabis", symabi, "-o", obj, goSrc)
 	out, err = cmd.CombinedOutput()
 	if err == nil {
 		t.Fatalf("go tool compile did not fail")
diff --git a/src/internal/buildcfg/cfg.go b/src/internal/buildcfg/cfg.go
index 1066d0c..a0736aa 100644
--- a/src/internal/buildcfg/cfg.go
+++ b/src/internal/buildcfg/cfg.go
@@ -30,6 +30,7 @@
 	GOMIPS64 = gomips64()
 	GOPPC64  = goppc64()
 	GOWASM   = gowasm()
+	ToolTags = toolTags()
 	GO_LDSO  = defaultGO_LDSO
 	Version  = version
 )
@@ -109,14 +110,16 @@
 		return 8
 	case "power9":
 		return 9
+	case "power10":
+		return 10
 	}
-	Error = fmt.Errorf("invalid GOPPC64: must be power8, power9")
+	Error = fmt.Errorf("invalid GOPPC64: must be power8, power9, power10")
 	return int(defaultGOPPC64[len("power")] - '0')
 }
 
 type gowasmFeatures struct {
-	SignExt bool
 	SatConv bool
+	SignExt bool
 }
 
 func (f gowasmFeatures) String() string {
@@ -149,3 +152,83 @@
 func Getgoextlinkenabled() string {
 	return envOr("GO_EXTLINK_ENABLED", defaultGO_EXTLINK_ENABLED)
 }
+
+func toolTags() []string {
+	tags := experimentTags()
+	tags = append(tags, gogoarchTags()...)
+	return tags
+}
+
+func experimentTags() []string {
+	var list []string
+	// For each experiment that has been enabled in the toolchain, define a
+	// build tag with the same name but prefixed by "goexperiment." which can be
+	// used for compiling alternative files for the experiment. This allows
+	// changes for the experiment, like extra struct fields in the runtime,
+	// without affecting the base non-experiment code at all.
+	for _, exp := range Experiment.Enabled() {
+		list = append(list, "goexperiment."+exp)
+	}
+	return list
+}
+
+// GOGOARCH returns the name and value of the GO$GOARCH setting.
+// For example, if GOARCH is "amd64" it might return "GOAMD64", "v2".
+func GOGOARCH() (name, value string) {
+	switch GOARCH {
+	case "386":
+		return "GO386", GO386
+	case "amd64":
+		return "GOAMD64", fmt.Sprintf("v%d", GOAMD64)
+	case "arm":
+		return "GOARM", fmt.Sprintf("%d", GOARM)
+	case "mips", "mipsle":
+		return "GOMIPS", GOMIPS
+	case "mips64", "mips64le":
+		return "GOMIPS64", GOMIPS64
+	case "ppc64", "ppc64le":
+		return "GOPPC64", fmt.Sprintf("power%d", GOPPC64)
+	case "wasm":
+		return "GOWASM", GOWASM.String()
+	}
+	return "", ""
+}
+
+func gogoarchTags() []string {
+	switch GOARCH {
+	case "386":
+		return []string{GOARCH + "." + GO386}
+	case "amd64":
+		var list []string
+		for i := 1; i <= GOAMD64; i++ {
+			list = append(list, fmt.Sprintf("%s.v%d", GOARCH, i))
+		}
+		return list
+	case "arm":
+		var list []string
+		for i := 5; i <= GOARM; i++ {
+			list = append(list, fmt.Sprintf("%s.%d", GOARCH, i))
+		}
+		return list
+	case "mips", "mipsle":
+		return []string{GOARCH + "." + GOMIPS}
+	case "mips64", "mips64le":
+		return []string{GOARCH + "." + GOMIPS64}
+	case "ppc64", "ppc64le":
+		var list []string
+		for i := 8; i <= GOPPC64; i++ {
+			list = append(list, fmt.Sprintf("%s.power%d", GOARCH, i))
+		}
+		return list
+	case "wasm":
+		var list []string
+		if GOWASM.SatConv {
+			list = append(list, GOARCH+".satconv")
+		}
+		if GOWASM.SignExt {
+			list = append(list, GOARCH+".signext")
+		}
+		return list
+	}
+	return nil
+}
diff --git a/src/internal/buildcfg/exp.go b/src/internal/buildcfg/exp.go
index 8c35214..71f8f56 100644
--- a/src/internal/buildcfg/exp.go
+++ b/src/internal/buildcfg/exp.go
@@ -62,16 +62,16 @@
 	// always on.
 	var regabiSupported, regabiAlwaysOn bool
 	switch goarch {
-	case "amd64", "arm64", "ppc64le", "ppc64":
+	case "amd64", "arm64", "ppc64le", "ppc64", "riscv64":
 		regabiAlwaysOn = true
 		regabiSupported = true
-	case "riscv64":
-		regabiSupported = true
 	}
 
 	baseline := goexperiment.Flags{
-		RegabiWrappers: regabiSupported,
-		RegabiArgs:     regabiSupported,
+		RegabiWrappers:   regabiSupported,
+		RegabiArgs:       regabiSupported,
+		Unified:          true,
+		CoverageRedesign: true,
 	}
 
 	// Start with the statically enabled set of experiments.
diff --git a/src/internal/buildcfg/zbootstrap.go b/src/internal/buildcfg/zbootstrap.go
index 815ca8e..e498723 100644
--- a/src/internal/buildcfg/zbootstrap.go
+++ b/src/internal/buildcfg/zbootstrap.go
@@ -12,7 +12,7 @@
 const defaultGOPPC64 = `power8`
 const defaultGOEXPERIMENT = ``
 const defaultGO_EXTLINK_ENABLED = ``
-const defaultGO_LDSO = `/lib64/ld-linux-x86-64.so.2`
-const version = `go1.19`
+const defaultGO_LDSO = ``
+const version = `go1.20.2`
 const defaultGOOS = runtime.GOOS
 const defaultGOARCH = runtime.GOARCH
diff --git a/src/internal/bytealg/compare_amd64.s b/src/internal/bytealg/compare_amd64.s
index 4ccaca5..fdd015f 100644
--- a/src/internal/bytealg/compare_amd64.s
+++ b/src/internal/bytealg/compare_amd64.s
@@ -3,6 +3,7 @@
 // license that can be found in the LICENSE file.
 
 #include "go_asm.h"
+#include "asm_amd64.h"
 #include "textflag.h"
 
 TEXT ·Compare<ABIInternal>(SB),NOSPLIT,$0-56
@@ -44,9 +45,13 @@
 
 	CMPQ	R8, $63
 	JBE	loop
+#ifndef hasAVX2
 	CMPB	internal∕cpu·X86+const_offsetX86HasAVX2(SB), $1
 	JEQ     big_loop_avx2
 	JMP	big_loop
+#else
+	JMP	big_loop_avx2
+#endif
 loop:
 	CMPQ	R8, $16
 	JBE	_0through16
@@ -155,6 +160,7 @@
 	RET
 
 	// this works for >= 64 bytes of data.
+#ifndef hasAVX2
 big_loop:
 	MOVOU	(SI), X0
 	MOVOU	(DI), X1
@@ -190,6 +196,7 @@
 	CMPQ	R8, $64
 	JBE	loop
 	JMP	big_loop
+#endif
 
 	// Compare 64-bytes per loop iteration.
 	// Loop is unrolled and uses AVX2.
diff --git a/src/internal/bytealg/compare_riscv64.s b/src/internal/bytealg/compare_riscv64.s
index 7d2f8d6..44a743d 100644
--- a/src/internal/bytealg/compare_riscv64.s
+++ b/src/internal/bytealg/compare_riscv64.s
@@ -6,13 +6,6 @@
 #include "textflag.h"
 
 TEXT ·Compare<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-56
-#ifndef GOEXPERIMENT_regabiargs
-	MOV	a_base+0(FP), X10
-	MOV	a_len+8(FP), X11
-	MOV	b_base+24(FP), X12
-	MOV	b_len+32(FP), X13
-	MOV	$ret+48(FP), X14
-#else
 	// X10 = a_base
 	// X11 = a_len
 	// X12 = a_cap (unused)
@@ -21,17 +14,9 @@
 	// X15 = b_cap (unused)
 	MOV	X13, X12
 	MOV	X14, X13
-#endif
 	JMP	compare<>(SB)
 
 TEXT runtime·cmpstring<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-40
-#ifndef GOEXPERIMENT_regabiargs
-	MOV	a_base+0(FP), X10
-	MOV	a_len+8(FP), X11
-	MOV	b_base+16(FP), X12
-	MOV	b_len+24(FP), X13
-	MOV	$ret+32(FP), X14
-#endif
 	// X10 = a_base
 	// X11 = a_len
 	// X12 = b_base
@@ -58,8 +43,8 @@
 	BLT	X5, X6, loop4_check
 
 	// Check alignment - if alignment differs we have to do one byte at a time.
-	AND	$3, X10, X7
-	AND	$3, X12, X8
+	AND	$7, X10, X7
+	AND	$7, X12, X8
 	BNE	X7, X8, loop4_check
 	BEQZ	X7, loop32_check
 
@@ -199,7 +184,4 @@
 	SLTU	X8, X9, X6
 cmp_ret:
 	SUB	X5, X6, X10
-#ifndef GOEXPERIMENT_regabiargs
-	MOV	X10, (X14)
-#endif
 	RET
diff --git a/src/internal/bytealg/count_amd64.s b/src/internal/bytealg/count_amd64.s
index fa864c4..efb17f8 100644
--- a/src/internal/bytealg/count_amd64.s
+++ b/src/internal/bytealg/count_amd64.s
@@ -3,12 +3,15 @@
 // license that can be found in the LICENSE file.
 
 #include "go_asm.h"
+#include "asm_amd64.h"
 #include "textflag.h"
 
 TEXT ·Count(SB),NOSPLIT,$0-40
+#ifndef hasPOPCNT
 	CMPB	internal∕cpu·X86+const_offsetX86HasPOPCNT(SB), $1
 	JEQ	2(PC)
 	JMP	·countGeneric(SB)
+#endif
 	MOVQ	b_base+0(FP), SI
 	MOVQ	b_len+8(FP), BX
 	MOVB	c+24(FP), AL
@@ -16,9 +19,11 @@
 	JMP	countbody<>(SB)
 
 TEXT ·CountString(SB),NOSPLIT,$0-32
+#ifndef hasPOPCNT
 	CMPB	internal∕cpu·X86+const_offsetX86HasPOPCNT(SB), $1
 	JEQ	2(PC)
 	JMP	·countGenericString(SB)
+#endif
 	MOVQ	s_base+0(FP), SI
 	MOVQ	s_len+8(FP), BX
 	MOVB	c+16(FP), AL
@@ -151,8 +156,10 @@
 	RET
 
 avx2:
+#ifndef hasAVX2
 	CMPB   internal∕cpu·X86+const_offsetX86HasAVX2(SB), $1
 	JNE sse
+#endif
 	MOVD AX, X0
 	LEAQ -32(SI)(BX*1), R11
 	VPBROADCASTB  X0, Y1
diff --git a/src/internal/bytealg/count_riscv64.s b/src/internal/bytealg/count_riscv64.s
index a15d07d..d123cbd 100644
--- a/src/internal/bytealg/count_riscv64.s
+++ b/src/internal/bytealg/count_riscv64.s
@@ -6,17 +6,11 @@
 #include "textflag.h"
 
 TEXT ·Count<ABIInternal>(SB),NOSPLIT,$0-40
-#ifndef GOEXPERIMENT_regabiargs
-	MOV	b_base+0(FP), X10
-	MOV	b_len+8(FP), X11
-	MOVBU	c+24(FP), X12	// byte to count
-#else
 	// X10 = b_base
 	// X11 = b_len
 	// X12 = b_cap (unused)
 	// X13 = byte to count (want in X12)
 	AND	$0xff, X13, X12
-#endif
 	MOV	ZERO, X14	// count
 	ADD	X10, X11	// end
 
@@ -29,19 +23,10 @@
 	JMP	loop
 
 done:
-#ifndef GOEXPERIMENT_regabiargs
-	MOV	X14, ret+32(FP)
-#else
 	MOV	X14, X10
-#endif
 	RET
 
 TEXT ·CountString<ABIInternal>(SB),NOSPLIT,$0-32
-#ifndef GOEXPERIMENT_regabiargs
-	MOV	s_base+0(FP), X10
-	MOV	s_len+8(FP), X11
-	MOVBU	c+16(FP), X12	// byte to count
-#endif
 	// X10 = s_base
 	// X11 = s_len
 	// X12 = byte to count
@@ -58,9 +43,5 @@
 	JMP	loop
 
 done:
-#ifndef GOEXPERIMENT_regabiargs
-	MOV	X14, ret+24(FP)
-#else
 	MOV	X14, X10
-#endif
 	RET
diff --git a/src/internal/bytealg/equal_amd64.s b/src/internal/bytealg/equal_amd64.s
index dd46e2e..d178a33 100644
--- a/src/internal/bytealg/equal_amd64.s
+++ b/src/internal/bytealg/equal_amd64.s
@@ -3,6 +3,7 @@
 // license that can be found in the LICENSE file.
 
 #include "go_asm.h"
+#include "asm_amd64.h"
 #include "textflag.h"
 
 // memequal(a, b unsafe.Pointer, size uintptr) bool
@@ -46,6 +47,7 @@
 	JB	small
 	CMPQ	BX, $64
 	JB	bigloop
+#ifndef hasAVX2
 	CMPB	internal∕cpu·X86+const_offsetX86HasAVX2(SB), $1
 	JE	hugeloop_avx2
 
@@ -76,6 +78,7 @@
 	JEQ	hugeloop
 	XORQ	AX, AX	// return 0
 	RET
+#endif
 
 	// 64 bytes at a time using ymm registers
 hugeloop_avx2:
diff --git a/src/internal/bytealg/equal_riscv64.s b/src/internal/bytealg/equal_riscv64.s
index 77202d6..3834083 100644
--- a/src/internal/bytealg/equal_riscv64.s
+++ b/src/internal/bytealg/equal_riscv64.s
@@ -9,12 +9,6 @@
 
 // func memequal(a, b unsafe.Pointer, size uintptr) bool
 TEXT runtime·memequal<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-25
-#ifndef GOEXPERIMENT_regabiargs
-	MOV	a+0(FP), X10
-	MOV	b+8(FP), X11
-	MOV	size+16(FP), X12
-	MOV	$ret+24(FP), X13
-#endif
 	// X10 = a_base
 	// X11 = b_base
 	// X12 = size
@@ -23,11 +17,6 @@
 // func memequal_varlen(a, b unsafe.Pointer) bool
 TEXT runtime·memequal_varlen<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-17
 	MOV	8(CTXT), X12    // compiler stores size at offset 8 in the closure
-#ifndef GOEXPERIMENT_regabiargs
-	MOV	a+0(FP), X10
-	MOV	b+8(FP), X11
-	MOV	$ret+16(FP), X13
-#endif
 	// X10 = a_base
 	// X11 = b_base
 	JMP	memequal<>(SB)
@@ -42,8 +31,8 @@
 	BLT	X12, X23, loop4_check
 
 	// Check alignment - if alignment differs we have to do one byte at a time.
-	AND	$3, X10, X9
-	AND	$3, X11, X19
+	AND	$7, X10, X9
+	AND	$7, X11, X19
 	BNE	X9, X19, loop4_check
 	BEQZ	X9, loop32_check
 
@@ -128,17 +117,8 @@
 	JMP	loop1
 
 not_eq:
-#ifndef GOEXPERIMENT_regabiargs
-	MOVB	ZERO, (X13)
-#else
 	MOVB	ZERO, X10
-#endif
 	RET
 eq:
-#ifndef GOEXPERIMENT_regabiargs
 	MOV	$1, X10
-	MOVB	X10, (X13)
-#else
-	MOV	$1, X10
-#endif
 	RET
diff --git a/src/internal/bytealg/index_amd64.s b/src/internal/bytealg/index_amd64.s
index 6193b57..0431491 100644
--- a/src/internal/bytealg/index_amd64.s
+++ b/src/internal/bytealg/index_amd64.s
@@ -233,8 +233,10 @@
 	VZEROUPPER
 	JMP success
 sse42:
+#ifndef hasSSE42
 	CMPB internal∕cpu·X86+const_offsetX86HasSSE42(SB), $1
 	JNE no_sse42
+#endif
 	CMPQ AX, $12
 	// PCMPESTRI is slower than normal compare,
 	// so using it makes sense only if we advance 4+ bytes per compare
diff --git a/src/internal/bytealg/index_ppc64x.s b/src/internal/bytealg/index_ppc64x.s
index 38442ce..26205ce 100644
--- a/src/internal/bytealg/index_ppc64x.s
+++ b/src/internal/bytealg/index_ppc64x.s
@@ -614,7 +614,7 @@
 next4:
 	VSPLTISB $0, V10            // Clear
 	MOVD     $3, R9             // Number of bytes beyond 16
-	LXVB16X  (R7)(R9), V3       // Load 16 bytes @R7 into V2
+	LXVB16X  (R7)(R9), V3       // Load 16 bytes @R7 into V3
 	VSLDOI   $13, V3, V10, V3   // Shift left last 3 bytes
 	VSLDOI   $1, V2, V3, V4     // V4=(V2:V3)<<1
 	VSLDOI   $2, V2, V3, V9     // V9=(V2:V3)<<2
@@ -654,13 +654,13 @@
 
 	ADD $19, R7, R9    // To check 4 indices per iteration, need at least 16+3 bytes
 	CMP R9, LASTBYTE
-	BGT index2to16tail
-
 	// At least 16 bytes of string left
 	// Mask the number of bytes in sep
 	VSPLTISB $0, V10            // Clear
-	MOVD     $3, R17            // Number of bytes beyond 16
+	BGT index2to16tail
 
+	MOVD     $3, R17            // Number of bytes beyond 16
+	PCALIGN  $32
 index2to16loop:
 	LXVB16X  (R7)(R0), V1       // Load next 16 bytes of string into V1 from R7
 	LXVB16X  (R7)(R17), V5      // Load next 16 bytes of string into V5 from R7+3
@@ -720,14 +720,15 @@
 	ADD        $1, R7          // Not found, try next partial string
 	CMP        R7, LASTSTR     // Check for end of string
 	BGT        notfound        // If at end, then not found
-	VSLDOI     $1, V1, V25, V1 // Shift string left by 1 byte
+	VOR        V1, V1, V4      // save remaining string
+	VSLDOI     $1, V1, V25, V1 // Shift string left by 1 byte for 17th byte
 	VAND       V1, SEPMASK, V2 // Just compare size of sep
 	VCMPEQUBCC V0, V2, V3      // Compare sep and partial string
 	BLT        CR6, found      // Found
 	ADD        $1, R7          // Not found, try next partial string
 	CMP        R7, LASTSTR     // Check for end of string
 	BGT        notfound        // If at end, then not found
-	VSLDOI     $1, V1, V25, V1 // Shift string left by 1 byte
+	VSLDOI     $2, V4, V25, V1 // Shift saved string left by 2 bytes for 18th byte
 	BR         index2to16next  // Check the remaining partial string in index2to16next
 
 short:
@@ -737,7 +738,7 @@
 	MTVSRD   R10, V8           // Set up shift
 	VSLDOI   $8, V8, V8, V8
 	VSLO     V1, V8, V1        // Shift by start byte
-
+	PCALIGN  $32
 index2to16next:
 	VAND       V1, SEPMASK, V2 // Just compare size of sep
 	VCMPEQUBCC V0, V2, V3      // Compare sep and partial string
diff --git a/src/internal/bytealg/indexbyte_amd64.s b/src/internal/bytealg/indexbyte_amd64.s
index f78093c..1ca70e3 100644
--- a/src/internal/bytealg/indexbyte_amd64.s
+++ b/src/internal/bytealg/indexbyte_amd64.s
@@ -115,8 +115,10 @@
 	RET
 
 avx2:
+#ifndef hasAVX2
 	CMPB   internal∕cpu·X86+const_offsetX86HasAVX2(SB), $1
 	JNE sse
+#endif
 	MOVD AX, X0
 	LEAQ -32(SI)(BX*1), R11
 	VPBROADCASTB  X0, Y1
diff --git a/src/internal/bytealg/indexbyte_riscv64.s b/src/internal/bytealg/indexbyte_riscv64.s
index a203965..8be78ed 100644
--- a/src/internal/bytealg/indexbyte_riscv64.s
+++ b/src/internal/bytealg/indexbyte_riscv64.s
@@ -6,11 +6,6 @@
 #include "textflag.h"
 
 TEXT ·IndexByte<ABIInternal>(SB),NOSPLIT,$0-40
-#ifndef GOEXPERIMENT_regabiargs
-	MOV	b_base+0(FP), X10
-	MOV	b_len+8(FP), X11
-	MOVBU	c+24(FP), X13	// byte to find
-#endif
 	// X10 = b_base
 	// X11 = b_len
 	// X12 = b_cap (unused)
@@ -27,24 +22,13 @@
 	BNE	X13, X14, loop
 
 	SUB	X12, X10		// remove base
-#ifndef GOEXPERIMENT_regabiargs
-	MOV	X10, ret+32(FP)
-#endif
 	RET
 
 notfound:
 	MOV	$-1, X10
-#ifndef GOEXPERIMENT_regabiargs
-	MOV	X10, ret+32(FP)
-#endif
 	RET
 
 TEXT ·IndexByteString<ABIInternal>(SB),NOSPLIT,$0-32
-#ifndef GOEXPERIMENT_regabiargs
-	MOV	s_base+0(FP), X10
-	MOV	s_len+8(FP), X11
-	MOVBU	c+16(FP), X12	// byte to find
-#endif
 	// X10 = b_base
 	// X11 = b_len
 	// X12 = byte to find
@@ -60,14 +44,8 @@
 	BNE	X12, X14, loop
 
 	SUB	X13, X10		// remove base
-#ifndef GOEXPERIMENT_regabiargs
-	MOV	X10, ret+24(FP)
-#endif
 	RET
 
 notfound:
 	MOV	$-1, X10
-#ifndef GOEXPERIMENT_regabiargs
-	MOV	X10, ret+24(FP)
-#endif
 	RET
diff --git a/src/internal/coverage/calloc/batchcounteralloc.go b/src/internal/coverage/calloc/batchcounteralloc.go
new file mode 100644
index 0000000..2b6495d
--- /dev/null
+++ b/src/internal/coverage/calloc/batchcounteralloc.go
@@ -0,0 +1,29 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package calloc
+
+// This package contains a simple "batch" allocator for allocating
+// coverage counters (slices of uint32 basically), for working with
+// coverage data files. Collections of counter arrays tend to all be
+// live/dead over the same time period, so a good fit for batch
+// allocation.
+
+type BatchCounterAlloc struct {
+	pool []uint32
+}
+
+func (ca *BatchCounterAlloc) AllocateCounters(n int) []uint32 {
+	const chunk = 8192
+	if n > cap(ca.pool) {
+		siz := chunk
+		if n > chunk {
+			siz = n
+		}
+		ca.pool = make([]uint32, siz)
+	}
+	rv := ca.pool[:n]
+	ca.pool = ca.pool[n:]
+	return rv
+}
diff --git a/src/internal/coverage/cformat/fmt_test.go b/src/internal/coverage/cformat/fmt_test.go
new file mode 100644
index 0000000..4d6da44
--- /dev/null
+++ b/src/internal/coverage/cformat/fmt_test.go
@@ -0,0 +1,92 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cformat_test
+
+import (
+	"internal/coverage"
+	"internal/coverage/cformat"
+	"strings"
+	"testing"
+)
+
+func TestBasics(t *testing.T) {
+	fm := cformat.NewFormatter(coverage.CtrModeAtomic)
+	fm.SetPackage("my/pack")
+
+	mku := func(stl, enl, nx uint32) coverage.CoverableUnit {
+		return coverage.CoverableUnit{
+			StLine:  stl,
+			EnLine:  enl,
+			NxStmts: nx,
+		}
+	}
+	fn1units := []coverage.CoverableUnit{
+		mku(10, 11, 2),
+		mku(15, 11, 1),
+	}
+	fn2units := []coverage.CoverableUnit{
+		mku(20, 25, 3),
+		mku(30, 31, 2),
+		mku(33, 40, 7),
+	}
+	fn3units := []coverage.CoverableUnit{
+		mku(99, 100, 1),
+	}
+	for k, u := range fn1units {
+		fm.AddUnit("p.go", "f1", false, u, uint32(k))
+	}
+	for k, u := range fn2units {
+		fm.AddUnit("q.go", "f2", false, u, 0)
+		fm.AddUnit("q.go", "f2", false, u, uint32(k))
+	}
+	for _, u := range fn3units {
+		fm.AddUnit("lit.go", "f3", true, u, 0)
+	}
+
+	var b1, b2, b3 strings.Builder
+	if err := fm.EmitTextual(&b1); err != nil {
+		t.Fatalf("EmitTextual returned %v", err)
+	}
+	wantText := strings.TrimSpace(`
+mode: atomic
+lit.go:99.0,100.0 1 0
+p.go:10.0,11.0 2 0
+p.go:15.0,11.0 1 1
+q.go:20.0,25.0 3 0
+q.go:30.0,31.0 2 1
+q.go:33.0,40.0 7 2`)
+	gotText := strings.TrimSpace(b1.String())
+	if wantText != gotText {
+		t.Errorf("emit text: got:\n%s\nwant:\n%s\n", gotText, wantText)
+	}
+
+	if err := fm.EmitPercent(&b2, "", false); err != nil {
+		t.Fatalf("EmitPercent returned %v", err)
+	}
+	wantPercent := strings.TrimSpace(`
+my/pack	coverage: 62.5% of statements
+`)
+	gotPercent := strings.TrimSpace(b2.String())
+	if wantPercent != gotPercent {
+		t.Errorf("emit percent: got:\n%s\nwant:\n%s\n", gotPercent, wantPercent)
+	}
+
+	if err := fm.EmitFuncs(&b3); err != nil {
+		t.Fatalf("EmitFuncs returned %v", err)
+	}
+	wantFuncs := strings.TrimSpace(`
+p.go:10:	f1		33.3%
+q.go:20:	f2		75.0%
+total		(statements)	62.5%`)
+	gotFuncs := strings.TrimSpace(b3.String())
+	if wantFuncs != gotFuncs {
+		t.Errorf("emit funcs: got:\n%s\nwant:\n%s\n", gotFuncs, wantFuncs)
+	}
+	if false {
+		t.Logf("text is %s\n", b1.String())
+		t.Logf("perc is %s\n", b2.String())
+		t.Logf("funcs is %s\n", b3.String())
+	}
+}
diff --git a/src/internal/coverage/cformat/format.go b/src/internal/coverage/cformat/format.go
new file mode 100644
index 0000000..a8276ff
--- /dev/null
+++ b/src/internal/coverage/cformat/format.go
@@ -0,0 +1,340 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cformat
+
+// This package provides apis for producing human-readable summaries
+// of coverage data (e.g. a coverage percentage for a given package or
+// set of packages) and for writing data in the legacy test format
+// emitted by "go test -coverprofile=<outfile>".
+//
+// The model for using these apis is to create a Formatter object,
+// then make a series of calls to SetPackage and AddUnit passing in
+// data read from coverage meta-data and counter-data files. E.g.
+//
+//		myformatter := cformat.NewFormatter()
+//		...
+//		for each package P in meta-data file: {
+//			myformatter.SetPackage(P)
+//			for each function F in P: {
+//				for each coverable unit U in F: {
+//					myformatter.AddUnit(U)
+//				}
+//			}
+//		}
+//		myformatter.EmitPercent(os.Stdout, "")
+//		myformatter.EmitTextual(somefile)
+//
+// These apis are linked into tests that are built with "-cover", and
+// called at the end of test execution to produce text output or
+// emit coverage percentages.
+
+import (
+	"fmt"
+	"internal/coverage"
+	"internal/coverage/cmerge"
+	"io"
+	"sort"
+	"text/tabwriter"
+)
+
+type Formatter struct {
+	// Maps import path to package state.
+	pm map[string]*pstate
+	// Records current package being visited.
+	pkg string
+	// Pointer to current package state.
+	p *pstate
+	// Counter mode.
+	cm coverage.CounterMode
+}
+
+// pstate records package-level coverage data state:
+// - a table of functions (file/fname/literal)
+// - a map recording the index/ID of each func encountered so far
+// - a table storing execution count for the coverable units in each func
+type pstate struct {
+	// slice of unique functions
+	funcs []fnfile
+	// maps function to index in slice above (index acts as function ID)
+	funcTable map[fnfile]uint32
+
+	// A table storing coverage counts for each coverable unit.
+	unitTable map[extcu]uint32
+}
+
+// extcu encapsulates a coverable unit within some function.
+type extcu struct {
+	fnfid uint32 // index into p.funcs slice
+	coverage.CoverableUnit
+}
+
+// fnfile is a function-name/file-name tuple.
+type fnfile struct {
+	file  string
+	fname string
+	lit   bool
+}
+
+func NewFormatter(cm coverage.CounterMode) *Formatter {
+	return &Formatter{
+		pm: make(map[string]*pstate),
+		cm: cm,
+	}
+}
+
+// SetPackage tells the formatter that we're about to visit the
+// coverage data for the package with the specified import path.
+// Note that it's OK to call SetPackage more than once with the
+// same import path; counter data values will be accumulated.
+func (fm *Formatter) SetPackage(importpath string) {
+	if importpath == fm.pkg {
+		return
+	}
+	fm.pkg = importpath
+	ps, ok := fm.pm[importpath]
+	if !ok {
+		ps = new(pstate)
+		fm.pm[importpath] = ps
+		ps.unitTable = make(map[extcu]uint32)
+		ps.funcTable = make(map[fnfile]uint32)
+	}
+	fm.p = ps
+}
+
+// AddUnit passes info on a single coverable unit (file, funcname,
+// literal flag, range of lines, and counter value) to the formatter.
+// Counter values will be accumulated where appropriate.
+func (fm *Formatter) AddUnit(file string, fname string, isfnlit bool, unit coverage.CoverableUnit, count uint32) {
+	if fm.p == nil {
+		panic("AddUnit invoked before SetPackage")
+	}
+	fkey := fnfile{file: file, fname: fname, lit: isfnlit}
+	idx, ok := fm.p.funcTable[fkey]
+	if !ok {
+		idx = uint32(len(fm.p.funcs))
+		fm.p.funcs = append(fm.p.funcs, fkey)
+		fm.p.funcTable[fkey] = idx
+	}
+	ukey := extcu{fnfid: idx, CoverableUnit: unit}
+	pcount := fm.p.unitTable[ukey]
+	var result uint32
+	if fm.cm == coverage.CtrModeSet {
+		if count != 0 || pcount != 0 {
+			result = 1
+		}
+	} else {
+		// Use saturating arithmetic.
+		result, _ = cmerge.SaturatingAdd(pcount, count)
+	}
+	fm.p.unitTable[ukey] = result
+}
+
+// sortUnits sorts a slice of extcu objects in a package according to
+// source position information (e.g. file and line). Note that we don't
+// include function name as part of the sorting criteria, the thinking
+// being that is better to provide things in the original source order.
+func (p *pstate) sortUnits(units []extcu) {
+	sort.Slice(units, func(i, j int) bool {
+		ui := units[i]
+		uj := units[j]
+		ifile := p.funcs[ui.fnfid].file
+		jfile := p.funcs[uj.fnfid].file
+		if ifile != jfile {
+			return ifile < jfile
+		}
+		// NB: not taking function literal flag into account here (no
+		// need, since other fields are guaranteed to be distinct).
+		if units[i].StLine != units[j].StLine {
+			return units[i].StLine < units[j].StLine
+		}
+		if units[i].EnLine != units[j].EnLine {
+			return units[i].EnLine < units[j].EnLine
+		}
+		if units[i].StCol != units[j].StCol {
+			return units[i].StCol < units[j].StCol
+		}
+		if units[i].EnCol != units[j].EnCol {
+			return units[i].EnCol < units[j].EnCol
+		}
+		return units[i].NxStmts < units[j].NxStmts
+	})
+}
+
+// EmitTextual writes the accumulated coverage data in the legacy
+// cmd/cover text format to the writer 'w'. We sort the data items by
+// importpath, source file, and line number before emitting (this sorting
+// is not explicitly mandated by the format, but seems like a good idea
+// for repeatable/deterministic dumps).
+func (fm *Formatter) EmitTextual(w io.Writer) error {
+	if fm.cm == coverage.CtrModeInvalid {
+		panic("internal error, counter mode unset")
+	}
+	if _, err := fmt.Fprintf(w, "mode: %s\n", fm.cm.String()); err != nil {
+		return err
+	}
+	pkgs := make([]string, 0, len(fm.pm))
+	for importpath := range fm.pm {
+		pkgs = append(pkgs, importpath)
+	}
+	sort.Strings(pkgs)
+	for _, importpath := range pkgs {
+		p := fm.pm[importpath]
+		units := make([]extcu, 0, len(p.unitTable))
+		for u := range p.unitTable {
+			units = append(units, u)
+		}
+		p.sortUnits(units)
+		for _, u := range units {
+			count := p.unitTable[u]
+			file := p.funcs[u.fnfid].file
+			if _, err := fmt.Fprintf(w, "%s:%d.%d,%d.%d %d %d\n",
+				file, u.StLine, u.StCol,
+				u.EnLine, u.EnCol, u.NxStmts, count); err != nil {
+				return err
+			}
+		}
+	}
+	return nil
+}
+
+// EmitPercent writes out a "percentage covered" string to the writer 'w'.
+func (fm *Formatter) EmitPercent(w io.Writer, covpkgs string, noteEmpty bool) error {
+	pkgs := make([]string, 0, len(fm.pm))
+	for importpath := range fm.pm {
+		pkgs = append(pkgs, importpath)
+	}
+	sort.Strings(pkgs)
+	seenPkg := false
+	for _, importpath := range pkgs {
+		seenPkg = true
+		p := fm.pm[importpath]
+		var totalStmts, coveredStmts uint64
+		for unit, count := range p.unitTable {
+			nx := uint64(unit.NxStmts)
+			totalStmts += nx
+			if count != 0 {
+				coveredStmts += nx
+			}
+		}
+		if _, err := fmt.Fprintf(w, "\t%s\t", importpath); err != nil {
+			return err
+		}
+		if totalStmts == 0 {
+			if _, err := fmt.Fprintf(w, "coverage: [no statements]\n"); err != nil {
+				return err
+			}
+		} else {
+			if _, err := fmt.Fprintf(w, "coverage: %.1f%% of statements%s\n", 100*float64(coveredStmts)/float64(totalStmts), covpkgs); err != nil {
+				return err
+			}
+		}
+	}
+	if noteEmpty && !seenPkg {
+		if _, err := fmt.Fprintf(w, "coverage: [no statements]\n"); err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+// EmitFuncs writes out a function-level summary to the writer 'w'. A
+// note on handling function literals: although we collect coverage
+// data for unnamed literals, it probably does not make sense to
+// include them in the function summary since there isn't any good way
+// to name them (this is also consistent with the legacy cmd/cover
+// implementation). We do want to include their counts in the overall
+// summary however.
+func (fm *Formatter) EmitFuncs(w io.Writer) error {
+	if fm.cm == coverage.CtrModeInvalid {
+		panic("internal error, counter mode unset")
+	}
+	perc := func(covered, total uint64) float64 {
+		if total == 0 {
+			total = 1
+		}
+		return 100.0 * float64(covered) / float64(total)
+	}
+	tabber := tabwriter.NewWriter(w, 1, 8, 1, '\t', 0)
+	defer tabber.Flush()
+	allStmts := uint64(0)
+	covStmts := uint64(0)
+
+	pkgs := make([]string, 0, len(fm.pm))
+	for importpath := range fm.pm {
+		pkgs = append(pkgs, importpath)
+	}
+	sort.Strings(pkgs)
+
+	// Emit functions for each package, sorted by import path.
+	for _, importpath := range pkgs {
+		p := fm.pm[importpath]
+		if len(p.unitTable) == 0 {
+			continue
+		}
+		units := make([]extcu, 0, len(p.unitTable))
+		for u := range p.unitTable {
+			units = append(units, u)
+		}
+
+		// Within a package, sort the units, then walk through the
+		// sorted array. Each time we hit a new function, emit the
+		// summary entry for the previous function, then make one last
+		// emit call at the end of the loop.
+		p.sortUnits(units)
+		fname := ""
+		ffile := ""
+		flit := false
+		var fline uint32
+		var cstmts, tstmts uint64
+		captureFuncStart := func(u extcu) {
+			fname = p.funcs[u.fnfid].fname
+			ffile = p.funcs[u.fnfid].file
+			flit = p.funcs[u.fnfid].lit
+			fline = u.StLine
+		}
+		emitFunc := func(u extcu) error {
+			// Don't emit entries for function literals (see discussion
+			// in function header comment above).
+			if !flit {
+				if _, err := fmt.Fprintf(tabber, "%s:%d:\t%s\t%.1f%%\n",
+					ffile, fline, fname, perc(cstmts, tstmts)); err != nil {
+					return err
+				}
+			}
+			captureFuncStart(u)
+			allStmts += tstmts
+			covStmts += cstmts
+			tstmts = 0
+			cstmts = 0
+			return nil
+		}
+		for k, u := range units {
+			if k == 0 {
+				captureFuncStart(u)
+			} else {
+				if fname != p.funcs[u.fnfid].fname {
+					// New function; emit entry for previous one.
+					if err := emitFunc(u); err != nil {
+						return err
+					}
+				}
+			}
+			tstmts += uint64(u.NxStmts)
+			count := p.unitTable[u]
+			if count != 0 {
+				cstmts += uint64(u.NxStmts)
+			}
+		}
+		if err := emitFunc(extcu{}); err != nil {
+			return err
+		}
+	}
+	if _, err := fmt.Fprintf(tabber, "%s\t%s\t%.1f%%\n",
+		"total", "(statements)", perc(covStmts, allStmts)); err != nil {
+		return err
+	}
+	return nil
+}
diff --git a/src/internal/coverage/cmddefs.go b/src/internal/coverage/cmddefs.go
new file mode 100644
index 0000000..b30c37a
--- /dev/null
+++ b/src/internal/coverage/cmddefs.go
@@ -0,0 +1,73 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package coverage
+
+// CoverPkgConfig is a bundle of information passed from the Go
+// command to the cover command during "go build -cover" runs. The
+// Go command creates and fills in a struct as below, then passes
+// file containing the encoded JSON for the struct to the "cover"
+// tool when instrumenting the source files in a Go package.
+type CoverPkgConfig struct {
+	// File into which cmd/cover should emit summary info
+	// when instrumentation is complete.
+	OutConfig string
+
+	// Import path for the package being instrumented.
+	PkgPath string
+
+	// Package name.
+	PkgName string
+
+	// Instrumentation granularity: one of "perfunc" or "perblock" (default)
+	Granularity string
+
+	// Module path for this package (empty if no go.mod in use)
+	ModulePath string
+
+	// Local mode indicates we're doing a coverage build or test of a
+	// package selected via local import path, e.g. "./..." or
+	// "./foo/bar" as opposed to a non-relative import path. See the
+	// corresponding field in cmd/go's PackageInternal struct for more
+	// info.
+	Local bool
+}
+
+// CoverFixupConfig contains annotations/notes generated by the
+// cmd/cover tool (during instrumentation) to be passed on to the
+// compiler when the instrumented code is compiled. The cmd/cover tool
+// creates a struct of this type, JSON-encodes it, and emits the
+// result to a file, which the Go command then passes to the compiler
+// when the instrumented package is built.
+type CoverFixupConfig struct {
+	// Name of the variable (created by cmd/cover) containing the
+	// encoded meta-data for the package.
+	MetaVar string
+
+	// Length of the meta-data.
+	MetaLen int
+
+	// Hash computed by cmd/cover of the meta-data.
+	MetaHash string
+
+	// Instrumentation strategy. For now this is always set to
+	// "normal", but in the future we may add new values (for example,
+	// if panic paths are instrumented, or if the instrumenter
+	// eliminates redundant counters).
+	Strategy string
+
+	// Prefix assigned to the names of counter variables generated
+	// during instrumentation by cmd/cover.
+	CounterPrefix string
+
+	// Name chosen for the package ID variable generated during
+	// instrumentation.
+	PkgIdVar string
+
+	// Counter mode (e.g. set/count/atomic)
+	CounterMode string
+
+	// Counter granularity (perblock or perfunc).
+	CounterGranularity string
+}
diff --git a/src/internal/coverage/cmerge/merge.go b/src/internal/coverage/cmerge/merge.go
new file mode 100644
index 0000000..c482b8b
--- /dev/null
+++ b/src/internal/coverage/cmerge/merge.go
@@ -0,0 +1,104 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cmerge
+
+// package cmerge provides a few small utility APIs for helping
+// with merging of counter data for a given function.
+
+import (
+	"fmt"
+	"internal/coverage"
+	"math"
+)
+
+// Merger provides state and methods to help manage the process of
+// merging together coverage counter data for a given function, for
+// tools that need to implicitly merge counter as they read multiple
+// coverage counter data files.
+type Merger struct {
+	cmode    coverage.CounterMode
+	cgran    coverage.CounterGranularity
+	overflow bool
+}
+
+// MergeCounters takes the counter values in 'src' and merges them
+// into 'dst' according to the correct counter mode.
+func (m *Merger) MergeCounters(dst, src []uint32) (error, bool) {
+	if len(src) != len(dst) {
+		return fmt.Errorf("merging counters: len(dst)=%d len(src)=%d", len(dst), len(src)), false
+	}
+	if m.cmode == coverage.CtrModeSet {
+		for i := 0; i < len(src); i++ {
+			if src[i] != 0 {
+				dst[i] = 1
+			}
+		}
+	} else {
+		for i := 0; i < len(src); i++ {
+			dst[i] = m.SaturatingAdd(dst[i], src[i])
+		}
+	}
+	ovf := m.overflow
+	m.overflow = false
+	return nil, ovf
+}
+
+// Saturating add does a saturating addition of 'dst' and 'src',
+// returning added value or math.MaxUint32 if there is an overflow.
+// Overflows are recorded in case the client needs to track them.
+func (m *Merger) SaturatingAdd(dst, src uint32) uint32 {
+	result, overflow := SaturatingAdd(dst, src)
+	if overflow {
+		m.overflow = true
+	}
+	return result
+}
+
+// Saturating add does a saturing addition of 'dst' and 'src',
+// returning added value or math.MaxUint32 plus an overflow flag.
+func SaturatingAdd(dst, src uint32) (uint32, bool) {
+	d, s := uint64(dst), uint64(src)
+	sum := d + s
+	overflow := false
+	if uint64(uint32(sum)) != sum {
+		overflow = true
+		sum = math.MaxUint32
+	}
+	return uint32(sum), overflow
+}
+
+// SetModeAndGranularity records the counter mode and granularity for
+// the current merge. In the specific case of merging across coverage
+// data files from different binaries, where we're combining data from
+// more than one meta-data file, we need to check for mode/granularity
+// clashes.
+func (cm *Merger) SetModeAndGranularity(mdf string, cmode coverage.CounterMode, cgran coverage.CounterGranularity) error {
+	// Collect counter mode and granularity so as to detect clashes.
+	if cm.cmode != coverage.CtrModeInvalid {
+		if cm.cmode != cmode {
+			return fmt.Errorf("counter mode clash while reading meta-data file %s: previous file had %s, new file has %s", mdf, cm.cmode.String(), cmode.String())
+		}
+		if cm.cgran != cgran {
+			return fmt.Errorf("counter granularity clash while reading meta-data file %s: previous file had %s, new file has %s", mdf, cm.cgran.String(), cgran.String())
+		}
+	}
+	cm.cmode = cmode
+	cm.cgran = cgran
+	return nil
+}
+
+func (cm *Merger) ResetModeAndGranularity() {
+	cm.cmode = coverage.CtrModeInvalid
+	cm.cgran = coverage.CtrGranularityInvalid
+	cm.overflow = false
+}
+
+func (cm *Merger) Mode() coverage.CounterMode {
+	return cm.cmode
+}
+
+func (cm *Merger) Granularity() coverage.CounterGranularity {
+	return cm.cgran
+}
diff --git a/src/internal/coverage/cmerge/merge_test.go b/src/internal/coverage/cmerge/merge_test.go
new file mode 100644
index 0000000..e45589f
--- /dev/null
+++ b/src/internal/coverage/cmerge/merge_test.go
@@ -0,0 +1,105 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cmerge_test
+
+import (
+	"fmt"
+	"internal/coverage"
+	"internal/coverage/cmerge"
+	"testing"
+)
+
+func TestClash(t *testing.T) {
+	m := &cmerge.Merger{}
+	err := m.SetModeAndGranularity("mdf1.data", coverage.CtrModeSet, coverage.CtrGranularityPerBlock)
+	if err != nil {
+		t.Fatalf("unexpected clash")
+	}
+	err = m.SetModeAndGranularity("mdf1.data", coverage.CtrModeSet, coverage.CtrGranularityPerBlock)
+	if err != nil {
+		t.Fatalf("unexpected clash")
+	}
+	err = m.SetModeAndGranularity("mdf1.data", coverage.CtrModeCount, coverage.CtrGranularityPerBlock)
+	if err == nil {
+		t.Fatalf("expected mode clash, not found")
+	}
+	err = m.SetModeAndGranularity("mdf1.data", coverage.CtrModeSet, coverage.CtrGranularityPerFunc)
+	if err == nil {
+		t.Fatalf("expected granularity clash, not found")
+	}
+	m.ResetModeAndGranularity()
+	err = m.SetModeAndGranularity("mdf1.data", coverage.CtrModeCount, coverage.CtrGranularityPerFunc)
+	if err != nil {
+		t.Fatalf("unexpected clash after reset")
+	}
+}
+
+func TestBasic(t *testing.T) {
+	scenarios := []struct {
+		cmode         coverage.CounterMode
+		cgran         coverage.CounterGranularity
+		src, dst, res []uint32
+		iters         int
+		merr          bool
+		overflow      bool
+	}{
+		{
+			cmode:    coverage.CtrModeSet,
+			cgran:    coverage.CtrGranularityPerBlock,
+			src:      []uint32{1, 0, 1},
+			dst:      []uint32{1, 1, 0},
+			res:      []uint32{1, 1, 1},
+			iters:    2,
+			overflow: false,
+		},
+		{
+			cmode:    coverage.CtrModeCount,
+			cgran:    coverage.CtrGranularityPerBlock,
+			src:      []uint32{1, 0, 3},
+			dst:      []uint32{5, 7, 0},
+			res:      []uint32{6, 7, 3},
+			iters:    1,
+			overflow: false,
+		},
+		{
+			cmode:    coverage.CtrModeCount,
+			cgran:    coverage.CtrGranularityPerBlock,
+			src:      []uint32{4294967200, 0, 3},
+			dst:      []uint32{4294967001, 7, 0},
+			res:      []uint32{4294967295, 7, 3},
+			iters:    1,
+			overflow: true,
+		},
+	}
+
+	for k, scenario := range scenarios {
+		var err error
+		var ovf bool
+		m := &cmerge.Merger{}
+		mdf := fmt.Sprintf("file%d", k)
+		err = m.SetModeAndGranularity(mdf, scenario.cmode, scenario.cgran)
+		if err != nil {
+			t.Fatalf("case %d SetModeAndGranularity failed: %v", k, err)
+		}
+		for i := 0; i < scenario.iters; i++ {
+			err, ovf = m.MergeCounters(scenario.dst, scenario.src)
+			if ovf != scenario.overflow {
+				t.Fatalf("case %d overflow mismatch: got %v want %v", k, ovf, scenario.overflow)
+			}
+			if !scenario.merr && err != nil {
+				t.Fatalf("case %d unexpected err %v", k, err)
+			}
+			if scenario.merr && err == nil {
+				t.Fatalf("case %d expected err, not received", k)
+			}
+			for i := range scenario.dst {
+				if scenario.dst[i] != scenario.res[i] {
+					t.Fatalf("case %d: bad merge at %d got %d want %d",
+						k, i, scenario.dst[i], scenario.res[i])
+				}
+			}
+		}
+	}
+}
diff --git a/src/internal/coverage/decodecounter/decodecounterfile.go b/src/internal/coverage/decodecounter/decodecounterfile.go
new file mode 100644
index 0000000..fce060a
--- /dev/null
+++ b/src/internal/coverage/decodecounter/decodecounterfile.go
@@ -0,0 +1,373 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package decodecounter
+
+import (
+	"encoding/binary"
+	"fmt"
+	"internal/coverage"
+	"internal/coverage/slicereader"
+	"internal/coverage/stringtab"
+	"io"
+	"os"
+	"strconv"
+	"unsafe"
+)
+
+// This file contains helpers for reading counter data files created
+// during the executions of a coverage-instrumented binary.
+
+type CounterDataReader struct {
+	stab     *stringtab.Reader
+	args     map[string]string
+	osargs   []string
+	goarch   string // GOARCH setting from run that produced counter data
+	goos     string // GOOS setting from run that produced counter data
+	mr       io.ReadSeeker
+	hdr      coverage.CounterFileHeader
+	ftr      coverage.CounterFileFooter
+	shdr     coverage.CounterSegmentHeader
+	u32b     []byte
+	u8b      []byte
+	fcnCount uint32
+	segCount uint32
+	debug    bool
+}
+
+func NewCounterDataReader(fn string, rs io.ReadSeeker) (*CounterDataReader, error) {
+	cdr := &CounterDataReader{
+		mr:   rs,
+		u32b: make([]byte, 4),
+		u8b:  make([]byte, 1),
+	}
+	// Read header
+	if err := binary.Read(rs, binary.LittleEndian, &cdr.hdr); err != nil {
+		return nil, err
+	}
+	if cdr.debug {
+		fmt.Fprintf(os.Stderr, "=-= counter file header: %+v\n", cdr.hdr)
+	}
+	if !checkMagic(cdr.hdr.Magic) {
+		return nil, fmt.Errorf("invalid magic string: not a counter data file")
+	}
+	if cdr.hdr.Version > coverage.CounterFileVersion {
+		return nil, fmt.Errorf("version data incompatibility: reader is %d data is %d", coverage.CounterFileVersion, cdr.hdr.Version)
+	}
+
+	// Read footer.
+	if err := cdr.readFooter(); err != nil {
+		return nil, err
+	}
+	// Seek back to just past the file header.
+	hsz := int64(unsafe.Sizeof(cdr.hdr))
+	if _, err := cdr.mr.Seek(hsz, io.SeekStart); err != nil {
+		return nil, err
+	}
+	// Read preamble for first segment.
+	if err := cdr.readSegmentPreamble(); err != nil {
+		return nil, err
+	}
+	return cdr, nil
+}
+
+func checkMagic(v [4]byte) bool {
+	g := coverage.CovCounterMagic
+	return v[0] == g[0] && v[1] == g[1] && v[2] == g[2] && v[3] == g[3]
+}
+
+func (cdr *CounterDataReader) readFooter() error {
+	ftrSize := int64(unsafe.Sizeof(cdr.ftr))
+	if _, err := cdr.mr.Seek(-ftrSize, io.SeekEnd); err != nil {
+		return err
+	}
+	if err := binary.Read(cdr.mr, binary.LittleEndian, &cdr.ftr); err != nil {
+		return err
+	}
+	if !checkMagic(cdr.ftr.Magic) {
+		return fmt.Errorf("invalid magic string (not a counter data file)")
+	}
+	if cdr.ftr.NumSegments == 0 {
+		return fmt.Errorf("invalid counter data file (no segments)")
+	}
+	return nil
+}
+
+// readSegmentPreamble reads and consumes the segment header, segment string
+// table, and segment args table.
+func (cdr *CounterDataReader) readSegmentPreamble() error {
+	// Read segment header.
+	if err := binary.Read(cdr.mr, binary.LittleEndian, &cdr.shdr); err != nil {
+		return err
+	}
+	if cdr.debug {
+		fmt.Fprintf(os.Stderr, "=-= read counter segment header: %+v", cdr.shdr)
+		fmt.Fprintf(os.Stderr, " FcnEntries=0x%x StrTabLen=0x%x ArgsLen=0x%x\n",
+			cdr.shdr.FcnEntries, cdr.shdr.StrTabLen, cdr.shdr.ArgsLen)
+	}
+
+	// Read string table and args.
+	if err := cdr.readStringTable(); err != nil {
+		return err
+	}
+	if err := cdr.readArgs(); err != nil {
+		return err
+	}
+	// Seek past any padding to bring us up to a 4-byte boundary.
+	if of, err := cdr.mr.Seek(0, io.SeekCurrent); err != nil {
+		return err
+	} else {
+		rem := of % 4
+		if rem != 0 {
+			pad := 4 - rem
+			if _, err := cdr.mr.Seek(pad, io.SeekCurrent); err != nil {
+				return err
+			}
+		}
+	}
+	return nil
+}
+
+func (cdr *CounterDataReader) readStringTable() error {
+	b := make([]byte, cdr.shdr.StrTabLen)
+	nr, err := cdr.mr.Read(b)
+	if err != nil {
+		return err
+	}
+	if nr != int(cdr.shdr.StrTabLen) {
+		return fmt.Errorf("error: short read on string table")
+	}
+	slr := slicereader.NewReader(b, false /* not readonly */)
+	cdr.stab = stringtab.NewReader(slr)
+	cdr.stab.Read()
+	return nil
+}
+
+func (cdr *CounterDataReader) readArgs() error {
+	b := make([]byte, cdr.shdr.ArgsLen)
+	nr, err := cdr.mr.Read(b)
+	if err != nil {
+		return err
+	}
+	if nr != int(cdr.shdr.ArgsLen) {
+		return fmt.Errorf("error: short read on args table")
+	}
+	slr := slicereader.NewReader(b, false /* not readonly */)
+	sget := func() (string, error) {
+		kidx := slr.ReadULEB128()
+		if int(kidx) >= cdr.stab.Entries() {
+			return "", fmt.Errorf("malformed string table ref")
+		}
+		return cdr.stab.Get(uint32(kidx)), nil
+	}
+	nents := slr.ReadULEB128()
+	cdr.args = make(map[string]string, int(nents))
+	for i := uint64(0); i < nents; i++ {
+		k, errk := sget()
+		if errk != nil {
+			return errk
+		}
+		v, errv := sget()
+		if errv != nil {
+			return errv
+		}
+		if _, ok := cdr.args[k]; ok {
+			return fmt.Errorf("malformed args table")
+		}
+		cdr.args[k] = v
+	}
+	if argcs, ok := cdr.args["argc"]; ok {
+		argc, err := strconv.Atoi(argcs)
+		if err != nil {
+			return fmt.Errorf("malformed argc in counter data file args section")
+		}
+		cdr.osargs = make([]string, 0, argc)
+		for i := 0; i < argc; i++ {
+			arg := cdr.args[fmt.Sprintf("argv%d", i)]
+			cdr.osargs = append(cdr.osargs, arg)
+		}
+	}
+	if goos, ok := cdr.args["GOOS"]; ok {
+		cdr.goos = goos
+	}
+	if goarch, ok := cdr.args["GOARCH"]; ok {
+		cdr.goarch = goarch
+	}
+	return nil
+}
+
+// OsArgs returns the program arguments (saved from os.Args during
+// the run of the instrumented binary) read from the counter
+// data file. Not all coverage data files will have os.Args values;
+// for example, if a data file is produced by merging coverage
+// data from two distinct runs, no os args will be available (an
+// empty list is returned).
+func (cdr *CounterDataReader) OsArgs() []string {
+	return cdr.osargs
+}
+
+// Goos returns the GOOS setting in effect for the "-cover" binary
+// that produced this counter data file. The GOOS value may be
+// empty in the case where the counter data file was produced
+// from a merge in which more than one GOOS value was present.
+func (cdr *CounterDataReader) Goos() string {
+	return cdr.goos
+}
+
+// Goarch returns the GOARCH setting in effect for the "-cover" binary
+// that produced this counter data file. The GOARCH value may be
+// empty in the case where the counter data file was produced
+// from a merge in which more than one GOARCH value was present.
+func (cdr *CounterDataReader) Goarch() string {
+	return cdr.goarch
+}
+
+// FuncPayload encapsulates the counter data payload for a single
+// function as read from a counter data file.
+type FuncPayload struct {
+	PkgIdx   uint32
+	FuncIdx  uint32
+	Counters []uint32
+}
+
+// NumSegments returns the number of execution segments in the file.
+func (cdr *CounterDataReader) NumSegments() uint32 {
+	return cdr.ftr.NumSegments
+}
+
+// BeginNextSegment sets up the the reader to read the next segment,
+// returning TRUE if we do have another segment to read, or FALSE
+// if we're done with all the segments (also an error if
+// something went wrong).
+func (cdr *CounterDataReader) BeginNextSegment() (bool, error) {
+	if cdr.segCount >= cdr.ftr.NumSegments {
+		return false, nil
+	}
+	cdr.segCount++
+	cdr.fcnCount = 0
+	// Seek past footer from last segment.
+	ftrSize := int64(unsafe.Sizeof(cdr.ftr))
+	if _, err := cdr.mr.Seek(ftrSize, io.SeekCurrent); err != nil {
+		return false, err
+	}
+	// Read preamble for this segment.
+	if err := cdr.readSegmentPreamble(); err != nil {
+		return false, err
+	}
+	return true, nil
+}
+
+// NumFunctionsInSegment returns the number of live functions
+// in the currently selected segment.
+func (cdr *CounterDataReader) NumFunctionsInSegment() uint32 {
+	return uint32(cdr.shdr.FcnEntries)
+}
+
+const supportDeadFunctionsInCounterData = false
+
+// NextFunc reads data for the next function in this current segment
+// into "p", returning TRUE if the read was successful or FALSE
+// if we've read all the functions already (also an error if
+// something went wrong with the read or we hit a premature
+// EOF).
+func (cdr *CounterDataReader) NextFunc(p *FuncPayload) (bool, error) {
+	if cdr.fcnCount >= uint32(cdr.shdr.FcnEntries) {
+		return false, nil
+	}
+	cdr.fcnCount++
+	var rdu32 func() (uint32, error)
+	if cdr.hdr.CFlavor == coverage.CtrULeb128 {
+		rdu32 = func() (uint32, error) {
+			var shift uint
+			var value uint64
+			for {
+				_, err := cdr.mr.Read(cdr.u8b)
+				if err != nil {
+					return 0, err
+				}
+				b := cdr.u8b[0]
+				value |= (uint64(b&0x7F) << shift)
+				if b&0x80 == 0 {
+					break
+				}
+				shift += 7
+			}
+			return uint32(value), nil
+		}
+	} else if cdr.hdr.CFlavor == coverage.CtrRaw {
+		if cdr.hdr.BigEndian {
+			rdu32 = func() (uint32, error) {
+				n, err := cdr.mr.Read(cdr.u32b)
+				if err != nil {
+					return 0, err
+				}
+				if n != 4 {
+					return 0, io.EOF
+				}
+				return binary.BigEndian.Uint32(cdr.u32b), nil
+			}
+		} else {
+			rdu32 = func() (uint32, error) {
+				n, err := cdr.mr.Read(cdr.u32b)
+				if err != nil {
+					return 0, err
+				}
+				if n != 4 {
+					return 0, io.EOF
+				}
+				return binary.LittleEndian.Uint32(cdr.u32b), nil
+			}
+		}
+	} else {
+		panic("internal error: unknown counter flavor")
+	}
+
+	// Alternative/experimental path: one way we could handling writing
+	// out counter data would be to just memcpy the counter segment
+	// out to a file, meaning that a region in the counter memory
+	// corresponding to a dead (never-executed) function would just be
+	// zeroes. The code path below handles this case.
+	var nc uint32
+	var err error
+	if supportDeadFunctionsInCounterData {
+		for {
+			nc, err = rdu32()
+			if err == io.EOF {
+				return false, io.EOF
+			} else if err != nil {
+				break
+			}
+			if nc != 0 {
+				break
+			}
+		}
+	} else {
+		nc, err = rdu32()
+	}
+	if err != nil {
+		return false, err
+	}
+
+	// Read package and func indices.
+	p.PkgIdx, err = rdu32()
+	if err != nil {
+		return false, err
+	}
+	p.FuncIdx, err = rdu32()
+	if err != nil {
+		return false, err
+	}
+	if cap(p.Counters) < 1024 {
+		p.Counters = make([]uint32, 0, 1024)
+	}
+	p.Counters = p.Counters[:0]
+	for i := uint32(0); i < nc; i++ {
+		v, err := rdu32()
+		if err != nil {
+			return false, err
+		}
+		p.Counters = append(p.Counters, v)
+	}
+	return true, nil
+}
diff --git a/src/internal/coverage/decodemeta/decode.go b/src/internal/coverage/decodemeta/decode.go
new file mode 100644
index 0000000..71f1c56
--- /dev/null
+++ b/src/internal/coverage/decodemeta/decode.go
@@ -0,0 +1,128 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package decodemeta
+
+// This package contains APIs and helpers for decoding a single package's
+// meta data "blob" emitted by the compiler when coverage instrumentation
+// is turned on.
+
+import (
+	"encoding/binary"
+	"fmt"
+	"internal/coverage"
+	"internal/coverage/slicereader"
+	"internal/coverage/stringtab"
+	"os"
+)
+
+// See comments in the encodecovmeta package for details on the format.
+
+type CoverageMetaDataDecoder struct {
+	r      *slicereader.Reader
+	hdr    coverage.MetaSymbolHeader
+	strtab *stringtab.Reader
+	tmp    []byte
+	debug  bool
+}
+
+func NewCoverageMetaDataDecoder(b []byte, readonly bool) (*CoverageMetaDataDecoder, error) {
+	slr := slicereader.NewReader(b, readonly)
+	x := &CoverageMetaDataDecoder{
+		r:   slr,
+		tmp: make([]byte, 0, 256),
+	}
+	if err := x.readHeader(); err != nil {
+		return nil, err
+	}
+	if err := x.readStringTable(); err != nil {
+		return nil, err
+	}
+	return x, nil
+}
+
+func (d *CoverageMetaDataDecoder) readHeader() error {
+	if err := binary.Read(d.r, binary.LittleEndian, &d.hdr); err != nil {
+		return err
+	}
+	if d.debug {
+		fmt.Fprintf(os.Stderr, "=-= after readHeader: %+v\n", d.hdr)
+	}
+	return nil
+}
+
+func (d *CoverageMetaDataDecoder) readStringTable() error {
+	// Seek to the correct location to read the string table.
+	stringTableLocation := int64(coverage.CovMetaHeaderSize + 4*d.hdr.NumFuncs)
+	d.r.SeekTo(stringTableLocation)
+
+	// Read the table itself.
+	d.strtab = stringtab.NewReader(d.r)
+	d.strtab.Read()
+	return nil
+}
+
+func (d *CoverageMetaDataDecoder) PackagePath() string {
+	return d.strtab.Get(d.hdr.PkgPath)
+}
+
+func (d *CoverageMetaDataDecoder) PackageName() string {
+	return d.strtab.Get(d.hdr.PkgName)
+}
+
+func (d *CoverageMetaDataDecoder) ModulePath() string {
+	return d.strtab.Get(d.hdr.ModulePath)
+}
+
+func (d *CoverageMetaDataDecoder) NumFuncs() uint32 {
+	return d.hdr.NumFuncs
+}
+
+// ReadFunc reads the coverage meta-data for the function with index
+// 'findex', filling it into the FuncDesc pointed to by 'f'.
+func (d *CoverageMetaDataDecoder) ReadFunc(fidx uint32, f *coverage.FuncDesc) error {
+	if fidx >= d.hdr.NumFuncs {
+		return fmt.Errorf("illegal function index")
+	}
+
+	// Seek to the correct location to read the function offset and read it.
+	funcOffsetLocation := int64(coverage.CovMetaHeaderSize + 4*fidx)
+	d.r.SeekTo(funcOffsetLocation)
+	foff := d.r.ReadUint32()
+
+	// Check assumptions
+	if foff < uint32(funcOffsetLocation) || foff > d.hdr.Length {
+		return fmt.Errorf("malformed func offset %d", foff)
+	}
+
+	// Seek to the correct location to read the function.
+	d.r.SeekTo(int64(foff))
+
+	// Preamble containing number of units, file, and function.
+	numUnits := uint32(d.r.ReadULEB128())
+	fnameidx := uint32(d.r.ReadULEB128())
+	fileidx := uint32(d.r.ReadULEB128())
+
+	f.Srcfile = d.strtab.Get(fileidx)
+	f.Funcname = d.strtab.Get(fnameidx)
+
+	// Now the units
+	f.Units = f.Units[:0]
+	if cap(f.Units) < int(numUnits) {
+		f.Units = make([]coverage.CoverableUnit, 0, numUnits)
+	}
+	for k := uint32(0); k < numUnits; k++ {
+		f.Units = append(f.Units,
+			coverage.CoverableUnit{
+				StLine:  uint32(d.r.ReadULEB128()),
+				StCol:   uint32(d.r.ReadULEB128()),
+				EnLine:  uint32(d.r.ReadULEB128()),
+				EnCol:   uint32(d.r.ReadULEB128()),
+				NxStmts: uint32(d.r.ReadULEB128()),
+			})
+	}
+	lit := d.r.ReadULEB128()
+	f.Lit = lit != 0
+	return nil
+}
diff --git a/src/internal/coverage/decodemeta/decodefile.go b/src/internal/coverage/decodemeta/decodefile.go
new file mode 100644
index 0000000..6580dd5
--- /dev/null
+++ b/src/internal/coverage/decodemeta/decodefile.go
@@ -0,0 +1,223 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package decodemeta
+
+// This package contains APIs and helpers for reading and decoding
+// meta-data output files emitted by the runtime when a
+// coverage-instrumented binary executes. A meta-data file contains
+// top-level info (counter mode, number of packages) and then a
+// separate self-contained meta-data section for each Go package.
+
+import (
+	"bufio"
+	"crypto/md5"
+	"encoding/binary"
+	"fmt"
+	"internal/coverage"
+	"internal/coverage/slicereader"
+	"internal/coverage/stringtab"
+	"io"
+	"os"
+)
+
+// CoverageMetaFileReader provides state and methods for reading
+// a meta-data file from a code coverage run.
+type CoverageMetaFileReader struct {
+	f          *os.File
+	hdr        coverage.MetaFileHeader
+	tmp        []byte
+	pkgOffsets []uint64
+	pkgLengths []uint64
+	strtab     *stringtab.Reader
+	fileRdr    *bufio.Reader
+	fileView   []byte
+	debug      bool
+}
+
+// NewCoverageMetaFileReader returns a new helper object for reading
+// the coverage meta-data output file 'f'. The param 'fileView' is a
+// read-only slice containing the contents of 'f' obtained by mmap'ing
+// the file read-only; 'fileView' may be nil, in which case the helper
+// will read the contents of the file using regular file Read
+// operations.
+func NewCoverageMetaFileReader(f *os.File, fileView []byte) (*CoverageMetaFileReader, error) {
+	r := &CoverageMetaFileReader{
+		f:        f,
+		fileView: fileView,
+		tmp:      make([]byte, 256),
+	}
+
+	if err := r.readFileHeader(); err != nil {
+		return nil, err
+	}
+	return r, nil
+}
+
+func (r *CoverageMetaFileReader) readFileHeader() error {
+	var err error
+
+	r.fileRdr = bufio.NewReader(r.f)
+
+	// Read file header.
+	if err := binary.Read(r.fileRdr, binary.LittleEndian, &r.hdr); err != nil {
+		return err
+	}
+
+	// Verify magic string
+	m := r.hdr.Magic
+	g := coverage.CovMetaMagic
+	if m[0] != g[0] || m[1] != g[1] || m[2] != g[2] || m[3] != g[3] {
+		return fmt.Errorf("invalid meta-data file magic string")
+	}
+
+	// Vet the version. If this is a meta-data file from the future,
+	// we won't be able to read it.
+	if r.hdr.Version > coverage.MetaFileVersion {
+		return fmt.Errorf("meta-data file withn unknown version %d (expected %d)", r.hdr.Version, coverage.MetaFileVersion)
+	}
+
+	// Read package offsets for good measure
+	r.pkgOffsets = make([]uint64, r.hdr.Entries)
+	for i := uint64(0); i < r.hdr.Entries; i++ {
+		if r.pkgOffsets[i], err = r.rdUint64(); err != nil {
+			return err
+		}
+		if r.pkgOffsets[i] > r.hdr.TotalLength {
+			return fmt.Errorf("insane pkg offset %d: %d > totlen %d",
+				i, r.pkgOffsets[i], r.hdr.TotalLength)
+		}
+	}
+	r.pkgLengths = make([]uint64, r.hdr.Entries)
+	for i := uint64(0); i < r.hdr.Entries; i++ {
+		if r.pkgLengths[i], err = r.rdUint64(); err != nil {
+			return err
+		}
+		if r.pkgLengths[i] > r.hdr.TotalLength {
+			return fmt.Errorf("insane pkg length %d: %d > totlen %d",
+				i, r.pkgLengths[i], r.hdr.TotalLength)
+		}
+	}
+
+	// Read string table.
+	b := make([]byte, r.hdr.StrTabLength)
+	nr, err := r.fileRdr.Read(b)
+	if err != nil {
+		return err
+	}
+	if nr != int(r.hdr.StrTabLength) {
+		return fmt.Errorf("error: short read on string table")
+	}
+	slr := slicereader.NewReader(b, false /* not readonly */)
+	r.strtab = stringtab.NewReader(slr)
+	r.strtab.Read()
+
+	if r.debug {
+		fmt.Fprintf(os.Stderr, "=-= read-in header is: %+v\n", *r)
+	}
+
+	return nil
+}
+
+func (r *CoverageMetaFileReader) rdUint64() (uint64, error) {
+	r.tmp = r.tmp[:0]
+	r.tmp = append(r.tmp, make([]byte, 8)...)
+	n, err := r.fileRdr.Read(r.tmp)
+	if err != nil {
+		return 0, err
+	}
+	if n != 8 {
+		return 0, fmt.Errorf("premature end of file on read")
+	}
+	v := binary.LittleEndian.Uint64(r.tmp)
+	return v, nil
+}
+
+// NumPackages returns the number of packages for which this file
+// contains meta-data.
+func (r *CoverageMetaFileReader) NumPackages() uint64 {
+	return r.hdr.Entries
+}
+
+// CounterMode returns the counter mode (set, count, atomic) used
+// when building for coverage for the program that produce this
+// meta-data file.
+func (r *CoverageMetaFileReader) CounterMode() coverage.CounterMode {
+	return r.hdr.CMode
+}
+
+// CounterMode returns the counter granularity (single counter per
+// function, or counter per block) selected when building for coverage
+// for the program that produce this meta-data file.
+func (r *CoverageMetaFileReader) CounterGranularity() coverage.CounterGranularity {
+	return r.hdr.CGranularity
+}
+
+// FileHash returns the hash computed for all of the package meta-data
+// blobs. Coverage counter data files refer to this hash, and the
+// hash will be encoded into the meta-data file name.
+func (r *CoverageMetaFileReader) FileHash() [16]byte {
+	return r.hdr.MetaFileHash
+}
+
+// GetPackageDecoder requests a decoder object for the package within
+// the meta-data file whose index is 'pkIdx'. If the
+// CoverageMetaFileReader was set up with a read-only file view, a
+// pointer into that file view will be returned, otherwise the buffer
+// 'payloadbuf' will be written to (or if it is not of sufficient
+// size, a new buffer will be allocated). Return value is the decoder,
+// a byte slice with the encoded meta-data, and an error.
+func (r *CoverageMetaFileReader) GetPackageDecoder(pkIdx uint32, payloadbuf []byte) (*CoverageMetaDataDecoder, []byte, error) {
+	pp, err := r.GetPackagePayload(pkIdx, payloadbuf)
+	if r.debug {
+		fmt.Fprintf(os.Stderr, "=-= pkidx=%d payload length is %d hash=%s\n",
+			pkIdx, len(pp), fmt.Sprintf("%x", md5.Sum(pp)))
+	}
+	if err != nil {
+		return nil, nil, err
+	}
+	mdd, err := NewCoverageMetaDataDecoder(pp, r.fileView != nil)
+	if err != nil {
+		return nil, nil, err
+	}
+	return mdd, pp, nil
+}
+
+// GetPackagePayload returns the raw (encoded) meta-data payload for the
+// package with index 'pkIdx'. As with GetPackageDecoder, if the
+// CoverageMetaFileReader was set up with a read-only file view, a
+// pointer into that file view will be returned, otherwise the buffer
+// 'payloadbuf' will be written to (or if it is not of sufficient
+// size, a new buffer will be allocated). Return value is the decoder,
+// a byte slice with the encoded meta-data, and an error.
+func (r *CoverageMetaFileReader) GetPackagePayload(pkIdx uint32, payloadbuf []byte) ([]byte, error) {
+
+	// Determine correct offset/length.
+	if uint64(pkIdx) >= r.hdr.Entries {
+		return nil, fmt.Errorf("GetPackagePayload: illegal pkg index %d", pkIdx)
+	}
+	off := r.pkgOffsets[pkIdx]
+	len := r.pkgLengths[pkIdx]
+
+	if r.debug {
+		fmt.Fprintf(os.Stderr, "=-= for pk %d, off=%d len=%d\n", pkIdx, off, len)
+	}
+
+	if r.fileView != nil {
+		return r.fileView[off : off+len], nil
+	}
+
+	payload := payloadbuf[:0]
+	if cap(payload) < int(len) {
+		payload = make([]byte, 0, len)
+	}
+	payload = append(payload, make([]byte, len)...)
+	if _, err := r.f.Seek(int64(off), io.SeekStart); err != nil {
+		return nil, err
+	}
+	if _, err := io.ReadFull(r.f, payload); err != nil {
+		return nil, err
+	}
+	return payload, nil
+}
diff --git a/src/internal/coverage/defs.go b/src/internal/coverage/defs.go
new file mode 100644
index 0000000..4a41f57
--- /dev/null
+++ b/src/internal/coverage/defs.go
@@ -0,0 +1,374 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package coverage
+
+// Types and constants related to the output files files written
+// by code coverage tooling. When a coverage-instrumented binary
+// is run, it emits two output files: a meta-data output file, and
+// a counter data output file.
+
+//.....................................................................
+//
+// Meta-data definitions:
+//
+// The meta-data file is composed of a file header, a series of
+// meta-data blobs/sections (one per instrumented package), and an offsets
+// area storing the offsets of each section. Format of the meta-data
+// file looks like:
+//
+// --header----------
+//  | magic: [4]byte magic string
+//  | version
+//  | total length of meta-data file in bytes
+//  | numPkgs: number of package entries in file
+//  | hash: [16]byte hash of entire meta-data payload
+//  | offset to string table section
+//  | length of string table
+//  | number of entries in string table
+//  | counter mode
+//  | counter granularity
+//  --package offsets table------
+//  <offset to pkg 0>
+//  <offset to pkg 1>
+//  ...
+//  --package lengths table------
+//  <length of pkg 0>
+//  <length of pkg 1>
+//  ...
+//  --string table------
+//  <uleb128 len> 8
+//  <data> "somestring"
+//  ...
+//  --package payloads------
+//  <meta-symbol for pkg 0>
+//  <meta-symbol for pkg 1>
+//  ...
+//
+// Each package payload is a stand-alone blob emitted by the compiler,
+// and does not depend on anything else in the meta-data file. In
+// particular, each blob has it's own string table. Note that the
+// file-level string table is expected to be very short (most strings
+// will be in the meta-data blobs themselves).
+
+// CovMetaMagic holds the magic string for a meta-data file.
+var CovMetaMagic = [4]byte{'\x00', '\x63', '\x76', '\x6d'}
+
+// MetaFilePref is a prefix used when emitting meta-data files; these
+// files are of the form "covmeta.<hash>", where hash is a hash
+// computed from the hashes of all the package meta-data symbols in
+// the program.
+const MetaFilePref = "covmeta"
+
+// MetaFileVersion contains the current (most recent) meta-data file version.
+const MetaFileVersion = 1
+
+// MetaFileHeader stores file header information for a meta-data file.
+type MetaFileHeader struct {
+	Magic        [4]byte
+	Version      uint32
+	TotalLength  uint64
+	Entries      uint64
+	MetaFileHash [16]byte
+	StrTabOffset uint32
+	StrTabLength uint32
+	CMode        CounterMode
+	CGranularity CounterGranularity
+	_            [6]byte // padding
+}
+
+// MetaSymbolHeader stores header information for a single
+// meta-data blob, e.g. the coverage meta-data payload
+// computed for a given Go package.
+type MetaSymbolHeader struct {
+	Length     uint32 // size of meta-symbol payload in bytes
+	PkgName    uint32 // string table index
+	PkgPath    uint32 // string table index
+	ModulePath uint32 // string table index
+	MetaHash   [16]byte
+	_          byte    // currently unused
+	_          [3]byte // padding
+	NumFiles   uint32
+	NumFuncs   uint32
+}
+
+const CovMetaHeaderSize = 16 + 4 + 4 + 4 + 4 + 4 + 4 + 4 // keep in sync with above
+
+// As an example, consider the following Go package:
+//
+// 01: package p
+// 02:
+// 03: var v, w, z int
+// 04:
+// 05: func small(x, y int) int {
+// 06:   v++
+// 07:   // comment
+// 08:   if y == 0 {
+// 09:     return x
+// 10:   }
+// 11:   return (x << 1) ^ (9 / y)
+// 12: }
+// 13:
+// 14: func Medium(q, r int) int {
+// 15:   s1 := small(q, r)
+// 16:   z += s1
+// 17:   s2 := small(r, q)
+// 18:   w -= s2
+// 19:   return w + z
+// 20: }
+//
+// The meta-data blob for the single package above might look like the
+// following:
+//
+// -- MetaSymbolHeader header----------
+//  | size: size of this blob in bytes
+//  | packagepath: <path to p>
+//  | modulepath: <modpath for p>
+//  | nfiles: 1
+//  | nfunctions: 2
+//  --func offsets table------
+//  <offset to func 0>
+//  <offset to func 1>
+//  --string table (contains all files and functions)------
+//  | <uleb128 len> 4
+//  | <data> "p.go"
+//  | <uleb128 len> 5
+//  | <data> "small"
+//  | <uleb128 len> 6
+//  | <data> "Medium"
+//  --func 0------
+//  | <uleb128> num units: 3
+//  | <uleb128> func name: S1 (index into string table)
+//  | <uleb128> file: S0 (index into string table)
+//  | <unit 0>:  S0   L6     L8    2
+//  | <unit 1>:  S0   L9     L9    1
+//  | <unit 2>:  S0   L11    L11   1
+//  --func 1------
+//  | <uleb128> num units: 1
+//  | <uleb128> func name: S2 (index into string table)
+//  | <uleb128> file: S0 (index into string table)
+//  | <unit 0>:  S0   L15    L19   5
+//  ---end-----------
+
+// The following types and constants used by the meta-data encoder/decoder.
+
+// FuncDesc encapsulates the meta-data definitions for a single Go function.
+// This version assumes that we're looking at a function before inlining;
+// if we want to capture a post-inlining view of the world, the
+// representations of source positions would need to be a good deal more
+// complicated.
+type FuncDesc struct {
+	Funcname string
+	Srcfile  string
+	Units    []CoverableUnit
+	Lit      bool // true if this is a function literal
+}
+
+// CoverableUnit describes the source characteristics of a single
+// program unit for which we want to gather coverage info. Coverable
+// units are either "simple" or "intraline"; a "simple" coverable unit
+// corresponds to a basic block (region of straight-line code with no
+// jumps or control transfers). An "intraline" unit corresponds to a
+// logical clause nested within some other simple unit. A simple unit
+// will have a zero Parent value; for an intraline unit NxStmts will
+// be zero and and Parent will be set to 1 plus the index of the
+// containing simple statement. Example:
+//
+//	L7:   q := 1
+//	L8:   x := (y == 101 || launch() == false)
+//	L9:   r := x * 2
+//
+// For the code above we would have three simple units (one for each
+// line), then an intraline unit describing the "launch() == false"
+// clause in line 8, with Parent pointing to the index of the line 8
+// unit in the units array.
+//
+// Note: in the initial version of the coverage revamp, only simple
+// units will be in use.
+type CoverableUnit struct {
+	StLine, StCol uint32
+	EnLine, EnCol uint32
+	NxStmts       uint32
+	Parent        uint32
+}
+
+// CounterMode tracks the "flavor" of the coverage counters being
+// used in a given coverage-instrumented program.
+type CounterMode uint8
+
+const (
+	CtrModeInvalid  CounterMode = iota
+	CtrModeSet                  // "set" mode
+	CtrModeCount                // "count" mode
+	CtrModeAtomic               // "atomic" mode
+	CtrModeRegOnly              // registration-only pseudo-mode
+	CtrModeTestMain             // testmain pseudo-mode
+)
+
+func (cm CounterMode) String() string {
+	switch cm {
+	case CtrModeSet:
+		return "set"
+	case CtrModeCount:
+		return "count"
+	case CtrModeAtomic:
+		return "atomic"
+	case CtrModeRegOnly:
+		return "regonly"
+	case CtrModeTestMain:
+		return "testmain"
+	}
+	return "<invalid>"
+}
+
+func ParseCounterMode(mode string) CounterMode {
+	var cm CounterMode
+	switch mode {
+	case "set":
+		cm = CtrModeSet
+	case "count":
+		cm = CtrModeCount
+	case "atomic":
+		cm = CtrModeAtomic
+	case "regonly":
+		cm = CtrModeRegOnly
+	case "testmain":
+		cm = CtrModeTestMain
+	default:
+		cm = CtrModeInvalid
+	}
+	return cm
+}
+
+// CounterGranularity tracks the granularity of the coverage counters being
+// used in a given coverage-instrumented program.
+type CounterGranularity uint8
+
+const (
+	CtrGranularityInvalid CounterGranularity = iota
+	CtrGranularityPerBlock
+	CtrGranularityPerFunc
+)
+
+func (cm CounterGranularity) String() string {
+	switch cm {
+	case CtrGranularityPerBlock:
+		return "perblock"
+	case CtrGranularityPerFunc:
+		return "perfunc"
+	}
+	return "<invalid>"
+}
+
+//.....................................................................
+//
+// Counter data definitions:
+//
+
+// A counter data file is composed of a file header followed by one or
+// more "segments" (each segment representing a given run or partial
+// run of a give binary) followed by a footer.
+
+// CovCounterMagic holds the magic string for a coverage counter-data file.
+var CovCounterMagic = [4]byte{'\x00', '\x63', '\x77', '\x6d'}
+
+// CounterFileVersion stores the most recent counter data file version.
+const CounterFileVersion = 1
+
+// CounterFileHeader stores files header information for a counter-data file.
+type CounterFileHeader struct {
+	Magic     [4]byte
+	Version   uint32
+	MetaHash  [16]byte
+	CFlavor   CounterFlavor
+	BigEndian bool
+	_         [6]byte // padding
+}
+
+// CounterSegmentHeader encapsulates information about a specific
+// segment in a counter data file, which at the moment contains
+// counters data from a single execution of a coverage-instrumented
+// program. Following the segment header will be the string table and
+// args table, and then (possibly) padding bytes to bring the byte
+// size of the preamble up to a multiple of 4. Immediately following
+// that will be the counter payloads.
+//
+// The "args" section of a segment is used to store annotations
+// describing where the counter data came from; this section is
+// basically a series of key-value pairs (can be thought of as an
+// encoded 'map[string]string'). At the moment we only write os.Args()
+// data to this section, using pairs of the form "argc=<integer>",
+// "argv0=<os.Args[0]>", "argv1=<os.Args[1]>", and so on. In the
+// future the args table may also include things like GOOS/GOARCH
+// values, and/or tags indicating which tests were run to generate the
+// counter data.
+type CounterSegmentHeader struct {
+	FcnEntries uint64
+	StrTabLen  uint32
+	ArgsLen    uint32
+}
+
+// CounterFileFooter appears at the tail end of a counter data file,
+// and stores the number of segments it contains.
+type CounterFileFooter struct {
+	Magic       [4]byte
+	_           [4]byte // padding
+	NumSegments uint32
+	_           [4]byte // padding
+}
+
+// CounterFilePref is the file prefix used when emitting coverage data
+// output files. CounterFileTemplate describes the format of the file
+// name: prefix followed by meta-file hash followed by process ID
+// followed by emit UnixNanoTime.
+const CounterFilePref = "covcounters"
+const CounterFileTempl = "%s.%x.%d.%d"
+const CounterFileRegexp = `^%s\.(\S+)\.(\d+)\.(\d+)+$`
+
+// CounterFlavor describes how function and counters are
+// stored/represented in the counter section of the file.
+type CounterFlavor uint8
+
+const (
+	// "Raw" representation: all values (pkg ID, func ID, num counters,
+	// and counters themselves) are stored as uint32's.
+	CtrRaw CounterFlavor = iota + 1
+
+	// "ULeb" representation: all values (pkg ID, func ID, num counters,
+	// and counters themselves) are stored with ULEB128 encoding.
+	CtrULeb128
+)
+
+func Round4(x int) int {
+	return (x + 3) &^ 3
+}
+
+//.....................................................................
+//
+// Runtime counter data definitions.
+//
+
+// At runtime within a coverage-instrumented program, the "counters"
+// object we associated with instrumented function can be thought of
+// as a struct of the following form:
+//
+// struct {
+//     numCtrs uint32
+//     pkgid uint32
+//     funcid uint32
+//     counterArray [numBlocks]uint32
+// }
+//
+// where "numCtrs" is the number of blocks / coverable units within the
+// function, "pkgid" is the unique index assigned to this package by
+// the runtime, "funcid" is the index of this function within its containing
+// package, and "counterArray" stores the actual counters.
+//
+// The counter variable itself is created not as a struct but as a flat
+// array of uint32's; we then use the offsets below to index into it.
+
+const NumCtrsOffset = 0
+const PkgIdOffset = 1
+const FuncIdOffset = 2
+const FirstCtrOffset = 3
diff --git a/src/internal/coverage/encodecounter/encode.go b/src/internal/coverage/encodecounter/encode.go
new file mode 100644
index 0000000..8db4f51
--- /dev/null
+++ b/src/internal/coverage/encodecounter/encode.go
@@ -0,0 +1,284 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package encodecounter
+
+import (
+	"bufio"
+	"encoding/binary"
+	"fmt"
+	"internal/coverage"
+	"internal/coverage/slicewriter"
+	"internal/coverage/stringtab"
+	"internal/coverage/uleb128"
+	"io"
+	"os"
+	"sort"
+)
+
+// This package contains APIs and helpers for encoding initial portions
+// of the counter data files emitted at runtime when coverage instrumentation
+// is enabled.  Counter data files may contain multiple segments; the file
+// header and first segment are written via the "Write" method below, and
+// additional segments can then be added using "AddSegment".
+
+type CoverageDataWriter struct {
+	stab    *stringtab.Writer
+	w       *bufio.Writer
+	tmp     []byte
+	cflavor coverage.CounterFlavor
+	segs    uint32
+	debug   bool
+}
+
+func NewCoverageDataWriter(w io.Writer, flav coverage.CounterFlavor) *CoverageDataWriter {
+	r := &CoverageDataWriter{
+		stab: &stringtab.Writer{},
+		w:    bufio.NewWriter(w),
+
+		tmp:     make([]byte, 64),
+		cflavor: flav,
+	}
+	r.stab.InitWriter()
+	r.stab.Lookup("")
+	return r
+}
+
+// CounterVisitor describes a helper object used during counter file
+// writing; when writing counter data files, clients pass a
+// CounterVisitor to the write/emit routines. The writers will then
+// first invoke the visitor's NumFuncs() method to find out how many
+// function's worth of data to write, then it will invoke VisitFuncs.
+// The expectation is that the VisitFuncs method will then invoke the
+// callback "f" with data for each function to emit to the file.
+type CounterVisitor interface {
+	NumFuncs() (int, error)
+	VisitFuncs(f CounterVisitorFn) error
+}
+
+// CounterVisitorFn describes a callback function invoked when writing
+// coverage counter data.
+type CounterVisitorFn func(pkid uint32, funcid uint32, counters []uint32) error
+
+// Write writes the contents of the count-data file to the writer
+// previously supplied to NewCoverageDataWriter. Returns an error
+// if something went wrong somewhere with the write.
+func (cfw *CoverageDataWriter) Write(metaFileHash [16]byte, args map[string]string, visitor CounterVisitor) error {
+	if err := cfw.writeHeader(metaFileHash); err != nil {
+		return err
+	}
+	return cfw.AppendSegment(args, visitor)
+}
+
+func padToFourByteBoundary(ws *slicewriter.WriteSeeker) error {
+	sz := len(ws.BytesWritten())
+	zeros := []byte{0, 0, 0, 0}
+	rem := uint32(sz) % 4
+	if rem != 0 {
+		pad := zeros[:(4 - rem)]
+		if nw, err := ws.Write(pad); err != nil {
+			return err
+		} else if nw != len(pad) {
+			return fmt.Errorf("error: short write")
+		}
+	}
+	return nil
+}
+
+func (cfw *CoverageDataWriter) writeSegmentPreamble(args map[string]string, visitor CounterVisitor) error {
+	var csh coverage.CounterSegmentHeader
+	if nf, err := visitor.NumFuncs(); err != nil {
+		return err
+	} else {
+		csh.FcnEntries = uint64(nf)
+	}
+
+	// Write string table and args to a byte slice (since we need
+	// to capture offsets at various points), then emit the slice
+	// once we are done.
+	cfw.stab.Freeze()
+	ws := &slicewriter.WriteSeeker{}
+	if err := cfw.stab.Write(ws); err != nil {
+		return err
+	}
+	csh.StrTabLen = uint32(len(ws.BytesWritten()))
+
+	akeys := make([]string, 0, len(args))
+	for k := range args {
+		akeys = append(akeys, k)
+	}
+	sort.Strings(akeys)
+
+	wrULEB128 := func(v uint) error {
+		cfw.tmp = cfw.tmp[:0]
+		cfw.tmp = uleb128.AppendUleb128(cfw.tmp, v)
+		if _, err := ws.Write(cfw.tmp); err != nil {
+			return err
+		}
+		return nil
+	}
+
+	// Count of arg pairs.
+	if err := wrULEB128(uint(len(args))); err != nil {
+		return err
+	}
+	// Arg pairs themselves.
+	for _, k := range akeys {
+		ki := uint(cfw.stab.Lookup(k))
+		if err := wrULEB128(ki); err != nil {
+			return err
+		}
+		v := args[k]
+		vi := uint(cfw.stab.Lookup(v))
+		if err := wrULEB128(vi); err != nil {
+			return err
+		}
+	}
+	if err := padToFourByteBoundary(ws); err != nil {
+		return err
+	}
+	csh.ArgsLen = uint32(len(ws.BytesWritten())) - csh.StrTabLen
+
+	if cfw.debug {
+		fmt.Fprintf(os.Stderr, "=-= counter segment header: %+v", csh)
+		fmt.Fprintf(os.Stderr, " FcnEntries=0x%x StrTabLen=0x%x ArgsLen=0x%x\n",
+			csh.FcnEntries, csh.StrTabLen, csh.ArgsLen)
+	}
+
+	// At this point we can now do the actual write.
+	if err := binary.Write(cfw.w, binary.LittleEndian, csh); err != nil {
+		return err
+	}
+	if err := cfw.writeBytes(ws.BytesWritten()); err != nil {
+		return err
+	}
+	return nil
+}
+
+// AppendSegment appends a new segment to a counter data, with a new
+// args section followed by a payload of counter data clauses.
+func (cfw *CoverageDataWriter) AppendSegment(args map[string]string, visitor CounterVisitor) error {
+	cfw.stab = &stringtab.Writer{}
+	cfw.stab.InitWriter()
+	cfw.stab.Lookup("")
+
+	var err error
+	for k, v := range args {
+		cfw.stab.Lookup(k)
+		cfw.stab.Lookup(v)
+	}
+
+	if err = cfw.writeSegmentPreamble(args, visitor); err != nil {
+		return err
+	}
+	if err = cfw.writeCounters(visitor); err != nil {
+		return err
+	}
+	if err = cfw.writeFooter(); err != nil {
+		return err
+	}
+	if err := cfw.w.Flush(); err != nil {
+		return fmt.Errorf("write error: %v", err)
+	}
+	cfw.stab = nil
+	return nil
+}
+
+func (cfw *CoverageDataWriter) writeHeader(metaFileHash [16]byte) error {
+	// Emit file header.
+	ch := coverage.CounterFileHeader{
+		Magic:     coverage.CovCounterMagic,
+		Version:   coverage.CounterFileVersion,
+		MetaHash:  metaFileHash,
+		CFlavor:   cfw.cflavor,
+		BigEndian: false,
+	}
+	if err := binary.Write(cfw.w, binary.LittleEndian, ch); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (cfw *CoverageDataWriter) writeBytes(b []byte) error {
+	if len(b) == 0 {
+		return nil
+	}
+	nw, err := cfw.w.Write(b)
+	if err != nil {
+		return fmt.Errorf("error writing counter data: %v", err)
+	}
+	if len(b) != nw {
+		return fmt.Errorf("error writing counter data: short write")
+	}
+	return nil
+}
+
+func (cfw *CoverageDataWriter) writeCounters(visitor CounterVisitor) error {
+	// Notes:
+	// - this version writes everything little-endian, which means
+	//   a call is needed to encode every value (expensive)
+	// - we may want to move to a model in which we just blast out
+	//   all counters, or possibly mmap the file and do the write
+	//   implicitly.
+	ctrb := make([]byte, 4)
+	wrval := func(val uint32) error {
+		var buf []byte
+		var towr int
+		if cfw.cflavor == coverage.CtrRaw {
+			binary.LittleEndian.PutUint32(ctrb, val)
+			buf = ctrb
+			towr = 4
+		} else if cfw.cflavor == coverage.CtrULeb128 {
+			cfw.tmp = cfw.tmp[:0]
+			cfw.tmp = uleb128.AppendUleb128(cfw.tmp, uint(val))
+			buf = cfw.tmp
+			towr = len(buf)
+		} else {
+			panic("internal error: bad counter flavor")
+		}
+		if sz, err := cfw.w.Write(buf); err != nil {
+			return err
+		} else if sz != towr {
+			return fmt.Errorf("writing counters: short write")
+		}
+		return nil
+	}
+
+	// Write out entries for each live function.
+	emitter := func(pkid uint32, funcid uint32, counters []uint32) error {
+		if err := wrval(uint32(len(counters))); err != nil {
+			return err
+		}
+
+		if err := wrval(pkid); err != nil {
+			return err
+		}
+
+		if err := wrval(funcid); err != nil {
+			return err
+		}
+		for _, val := range counters {
+			if err := wrval(val); err != nil {
+				return err
+			}
+		}
+		return nil
+	}
+	if err := visitor.VisitFuncs(emitter); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (cfw *CoverageDataWriter) writeFooter() error {
+	cfw.segs++
+	cf := coverage.CounterFileFooter{
+		Magic:       coverage.CovCounterMagic,
+		NumSegments: cfw.segs,
+	}
+	if err := binary.Write(cfw.w, binary.LittleEndian, cf); err != nil {
+		return err
+	}
+	return nil
+}
diff --git a/src/internal/coverage/encodemeta/encode.go b/src/internal/coverage/encodemeta/encode.go
new file mode 100644
index 0000000..d211c7c
--- /dev/null
+++ b/src/internal/coverage/encodemeta/encode.go
@@ -0,0 +1,215 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package encodemeta
+
+// This package contains APIs and helpers for encoding the meta-data
+// "blob" for a single Go package, created when coverage
+// instrumentation is turned on.
+
+import (
+	"bytes"
+	"crypto/md5"
+	"encoding/binary"
+	"fmt"
+	"hash"
+	"internal/coverage"
+	"internal/coverage/stringtab"
+	"internal/coverage/uleb128"
+	"io"
+	"os"
+)
+
+type CoverageMetaDataBuilder struct {
+	stab    stringtab.Writer
+	funcs   []funcDesc
+	tmp     []byte // temp work slice
+	h       hash.Hash
+	pkgpath uint32
+	pkgname uint32
+	modpath uint32
+	debug   bool
+	werr    error
+}
+
+func NewCoverageMetaDataBuilder(pkgpath string, pkgname string, modulepath string) (*CoverageMetaDataBuilder, error) {
+	if pkgpath == "" {
+		return nil, fmt.Errorf("invalid empty package path")
+	}
+	x := &CoverageMetaDataBuilder{
+		tmp: make([]byte, 0, 256),
+		h:   md5.New(),
+	}
+	x.stab.InitWriter()
+	x.stab.Lookup("")
+	x.pkgpath = x.stab.Lookup(pkgpath)
+	x.pkgname = x.stab.Lookup(pkgname)
+	x.modpath = x.stab.Lookup(modulepath)
+	io.WriteString(x.h, pkgpath)
+	io.WriteString(x.h, pkgname)
+	io.WriteString(x.h, modulepath)
+	return x, nil
+}
+
+func h32(x uint32, h hash.Hash, tmp []byte) {
+	tmp = tmp[:0]
+	tmp = append(tmp, []byte{0, 0, 0, 0}...)
+	binary.LittleEndian.PutUint32(tmp, x)
+	h.Write(tmp)
+}
+
+type funcDesc struct {
+	encoded []byte
+}
+
+// AddFunc registers a new function with the meta data builder.
+func (b *CoverageMetaDataBuilder) AddFunc(f coverage.FuncDesc) uint {
+	hashFuncDesc(b.h, &f, b.tmp)
+	fd := funcDesc{}
+	b.tmp = b.tmp[:0]
+	b.tmp = uleb128.AppendUleb128(b.tmp, uint(len(f.Units)))
+	b.tmp = uleb128.AppendUleb128(b.tmp, uint(b.stab.Lookup(f.Funcname)))
+	b.tmp = uleb128.AppendUleb128(b.tmp, uint(b.stab.Lookup(f.Srcfile)))
+	for _, u := range f.Units {
+		b.tmp = uleb128.AppendUleb128(b.tmp, uint(u.StLine))
+		b.tmp = uleb128.AppendUleb128(b.tmp, uint(u.StCol))
+		b.tmp = uleb128.AppendUleb128(b.tmp, uint(u.EnLine))
+		b.tmp = uleb128.AppendUleb128(b.tmp, uint(u.EnCol))
+		b.tmp = uleb128.AppendUleb128(b.tmp, uint(u.NxStmts))
+	}
+	lit := uint(0)
+	if f.Lit {
+		lit = 1
+	}
+	b.tmp = uleb128.AppendUleb128(b.tmp, lit)
+	fd.encoded = bytes.Clone(b.tmp)
+	rv := uint(len(b.funcs))
+	b.funcs = append(b.funcs, fd)
+	return rv
+}
+
+func (b *CoverageMetaDataBuilder) emitFuncOffsets(w io.WriteSeeker, off int64) int64 {
+	nFuncs := len(b.funcs)
+	var foff int64 = coverage.CovMetaHeaderSize + int64(b.stab.Size()) + int64(nFuncs)*4
+	for idx := 0; idx < nFuncs; idx++ {
+		b.wrUint32(w, uint32(foff))
+		foff += int64(len(b.funcs[idx].encoded))
+	}
+	return off + (int64(len(b.funcs)) * 4)
+}
+
+func (b *CoverageMetaDataBuilder) emitFunc(w io.WriteSeeker, off int64, f funcDesc) (int64, error) {
+	ew := len(f.encoded)
+	if nw, err := w.Write(f.encoded); err != nil {
+		return 0, err
+	} else if ew != nw {
+		return 0, fmt.Errorf("short write emitting coverage meta-data")
+	}
+	return off + int64(ew), nil
+}
+
+func (b *CoverageMetaDataBuilder) reportWriteError(err error) {
+	if b.werr != nil {
+		b.werr = err
+	}
+}
+
+func (b *CoverageMetaDataBuilder) wrUint32(w io.WriteSeeker, v uint32) {
+	b.tmp = b.tmp[:0]
+	b.tmp = append(b.tmp, []byte{0, 0, 0, 0}...)
+	binary.LittleEndian.PutUint32(b.tmp, v)
+	if nw, err := w.Write(b.tmp); err != nil {
+		b.reportWriteError(err)
+	} else if nw != 4 {
+		b.reportWriteError(fmt.Errorf("short write"))
+	}
+}
+
+// Emit writes the meta-data accumulated so far in this builder to 'w'.
+// Returns a hash of the meta-data payload and an error.
+func (b *CoverageMetaDataBuilder) Emit(w io.WriteSeeker) ([16]byte, error) {
+	// Emit header.  Length will initially be zero, we'll
+	// back-patch it later.
+	var digest [16]byte
+	copy(digest[:], b.h.Sum(nil))
+	mh := coverage.MetaSymbolHeader{
+		// hash and length initially zero, will be back-patched
+		PkgPath:    uint32(b.pkgpath),
+		PkgName:    uint32(b.pkgname),
+		ModulePath: uint32(b.modpath),
+		NumFiles:   uint32(b.stab.Nentries()),
+		NumFuncs:   uint32(len(b.funcs)),
+		MetaHash:   digest,
+	}
+	if b.debug {
+		fmt.Fprintf(os.Stderr, "=-= writing header: %+v\n", mh)
+	}
+	if err := binary.Write(w, binary.LittleEndian, mh); err != nil {
+		return digest, fmt.Errorf("error writing meta-file header: %v", err)
+	}
+	off := int64(coverage.CovMetaHeaderSize)
+
+	// Write function offsets section
+	off = b.emitFuncOffsets(w, off)
+
+	// Check for any errors up to this point.
+	if b.werr != nil {
+		return digest, b.werr
+	}
+
+	// Write string table.
+	if err := b.stab.Write(w); err != nil {
+		return digest, err
+	}
+	off += int64(b.stab.Size())
+
+	// Write functions
+	for _, f := range b.funcs {
+		var err error
+		off, err = b.emitFunc(w, off, f)
+		if err != nil {
+			return digest, err
+		}
+	}
+
+	// Back-patch the length.
+	totalLength := uint32(off)
+	if _, err := w.Seek(0, io.SeekStart); err != nil {
+		return digest, err
+	}
+	b.wrUint32(w, totalLength)
+	if b.werr != nil {
+		return digest, b.werr
+	}
+	return digest, nil
+}
+
+// HashFuncDesc computes an md5 sum of a coverage.FuncDesc and returns
+// a digest for it.
+func HashFuncDesc(f *coverage.FuncDesc) [16]byte {
+	h := md5.New()
+	tmp := make([]byte, 0, 32)
+	hashFuncDesc(h, f, tmp)
+	var r [16]byte
+	copy(r[:], h.Sum(nil))
+	return r
+}
+
+// hashFuncDesc incorporates a given function 'f' into the hash 'h'.
+func hashFuncDesc(h hash.Hash, f *coverage.FuncDesc, tmp []byte) {
+	io.WriteString(h, f.Funcname)
+	io.WriteString(h, f.Srcfile)
+	for _, u := range f.Units {
+		h32(u.StLine, h, tmp)
+		h32(u.StCol, h, tmp)
+		h32(u.EnLine, h, tmp)
+		h32(u.EnCol, h, tmp)
+		h32(u.NxStmts, h, tmp)
+	}
+	lit := uint32(0)
+	if f.Lit {
+		lit = 1
+	}
+	h32(lit, h, tmp)
+}
diff --git a/src/internal/coverage/encodemeta/encodefile.go b/src/internal/coverage/encodemeta/encodefile.go
new file mode 100644
index 0000000..38ae46e
--- /dev/null
+++ b/src/internal/coverage/encodemeta/encodefile.go
@@ -0,0 +1,132 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package encodemeta
+
+import (
+	"bufio"
+	"crypto/md5"
+	"encoding/binary"
+	"fmt"
+	"internal/coverage"
+	"internal/coverage/stringtab"
+	"io"
+	"os"
+	"unsafe"
+)
+
+// This package contains APIs and helpers for writing out a meta-data
+// file (composed of a file header, offsets/lengths, and then a series of
+// meta-data blobs emitted by the compiler, one per Go package).
+
+type CoverageMetaFileWriter struct {
+	stab   stringtab.Writer
+	mfname string
+	w      *bufio.Writer
+	tmp    []byte
+	debug  bool
+}
+
+func NewCoverageMetaFileWriter(mfname string, w io.Writer) *CoverageMetaFileWriter {
+	r := &CoverageMetaFileWriter{
+		mfname: mfname,
+		w:      bufio.NewWriter(w),
+		tmp:    make([]byte, 64),
+	}
+	r.stab.InitWriter()
+	r.stab.Lookup("")
+	return r
+}
+
+func (m *CoverageMetaFileWriter) Write(finalHash [16]byte, blobs [][]byte, mode coverage.CounterMode, granularity coverage.CounterGranularity) error {
+	mhsz := uint64(unsafe.Sizeof(coverage.MetaFileHeader{}))
+	stSize := m.stab.Size()
+	stOffset := mhsz + uint64(16*len(blobs))
+	preambleLength := stOffset + uint64(stSize)
+
+	if m.debug {
+		fmt.Fprintf(os.Stderr, "=+= sizeof(MetaFileHeader)=%d\n", mhsz)
+		fmt.Fprintf(os.Stderr, "=+= preambleLength=%d stSize=%d\n", preambleLength, stSize)
+	}
+
+	// Compute total size
+	tlen := preambleLength
+	for i := 0; i < len(blobs); i++ {
+		tlen += uint64(len(blobs[i]))
+	}
+
+	// Emit header
+	mh := coverage.MetaFileHeader{
+		Magic:        coverage.CovMetaMagic,
+		Version:      coverage.MetaFileVersion,
+		TotalLength:  tlen,
+		Entries:      uint64(len(blobs)),
+		MetaFileHash: finalHash,
+		StrTabOffset: uint32(stOffset),
+		StrTabLength: stSize,
+		CMode:        mode,
+		CGranularity: granularity,
+	}
+	var err error
+	if err = binary.Write(m.w, binary.LittleEndian, mh); err != nil {
+		return fmt.Errorf("error writing %s: %v", m.mfname, err)
+	}
+
+	if m.debug {
+		fmt.Fprintf(os.Stderr, "=+= len(blobs) is %d\n", mh.Entries)
+	}
+
+	// Emit package offsets section followed by package lengths section.
+	off := preambleLength
+	off2 := mhsz
+	buf := make([]byte, 8)
+	for _, blob := range blobs {
+		binary.LittleEndian.PutUint64(buf, off)
+		if _, err = m.w.Write(buf); err != nil {
+			return fmt.Errorf("error writing %s: %v", m.mfname, err)
+		}
+		if m.debug {
+			fmt.Fprintf(os.Stderr, "=+= pkg offset %d 0x%x\n", off, off)
+		}
+		off += uint64(len(blob))
+		off2 += 8
+	}
+	for _, blob := range blobs {
+		bl := uint64(len(blob))
+		binary.LittleEndian.PutUint64(buf, bl)
+		if _, err = m.w.Write(buf); err != nil {
+			return fmt.Errorf("error writing %s: %v", m.mfname, err)
+		}
+		if m.debug {
+			fmt.Fprintf(os.Stderr, "=+= pkg len %d 0x%x\n", bl, bl)
+		}
+		off2 += 8
+	}
+
+	// Emit string table
+	if err = m.stab.Write(m.w); err != nil {
+		return err
+	}
+
+	// Now emit blobs themselves.
+	for k, blob := range blobs {
+		if m.debug {
+			fmt.Fprintf(os.Stderr, "=+= writing blob %d len %d at off=%d hash %s\n", k, len(blob), off2, fmt.Sprintf("%x", md5.Sum(blob)))
+		}
+		if _, err = m.w.Write(blob); err != nil {
+			return fmt.Errorf("error writing %s: %v", m.mfname, err)
+		}
+		if m.debug {
+			fmt.Fprintf(os.Stderr, "=+= wrote package payload of %d bytes\n",
+				len(blob))
+		}
+		off2 += uint64(len(blob))
+	}
+
+	// Flush writer, and we're done.
+	if err = m.w.Flush(); err != nil {
+		return fmt.Errorf("error writing %s: %v", m.mfname, err)
+	}
+	return nil
+}
diff --git a/src/internal/coverage/pkid.go b/src/internal/coverage/pkid.go
new file mode 100644
index 0000000..8ddd44d
--- /dev/null
+++ b/src/internal/coverage/pkid.go
@@ -0,0 +1,80 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package coverage
+
+// Building the runtime package with coverage instrumentation enabled
+// is tricky.  For all other packages, you can be guaranteed that
+// the package init function is run before any functions are executed,
+// but this invariant is not maintained for packages such as "runtime",
+// "internal/cpu", etc. To handle this, hard-code the package ID for
+// the set of packages whose functions may be running before the
+// init function of the package is complete.
+//
+// Hardcoding is unfortunate because it means that the tool that does
+// coverage instrumentation has to keep a list of runtime packages,
+// meaning that if someone makes changes to the pkg "runtime"
+// dependencies, unexpected behavior will result for coverage builds.
+// The coverage runtime will detect and report the unexpected
+// behavior; look for an error of this form:
+//
+//    internal error in coverage meta-data tracking:
+//    list of hard-coded runtime package IDs needs revising.
+//    registered list:
+//    slot: 0 path='internal/cpu'  hard-coded id: 1
+//    slot: 1 path='internal/goarch'  hard-coded id: 2
+//    slot: 2 path='runtime/internal/atomic'  hard-coded id: 3
+//    slot: 3 path='internal/goos'
+//    slot: 4 path='runtime/internal/sys'  hard-coded id: 5
+//    slot: 5 path='internal/abi'  hard-coded id: 4
+//    slot: 6 path='runtime/internal/math'  hard-coded id: 6
+//    slot: 7 path='internal/bytealg'  hard-coded id: 7
+//    slot: 8 path='internal/goexperiment'
+//    slot: 9 path='runtime/internal/syscall'  hard-coded id: 8
+//    slot: 10 path='runtime'  hard-coded id: 9
+//    fatal error: runtime.addCovMeta
+//
+// For the error above, the hard-coded list is missing "internal/goos"
+// and "internal/goexperiment" ; the developer in question will need
+// to copy the list above into "rtPkgs" below.
+//
+// Note: this strategy assumes that the list of dependencies of
+// package runtime is fixed, and doesn't vary depending on OS/arch. If
+// this were to be the case, we would need a table of some sort below
+// as opposed to a fixed list.
+
+var rtPkgs = [...]string{
+	"internal/cpu",
+	"internal/goarch",
+	"runtime/internal/atomic",
+	"internal/goos",
+	"runtime/internal/sys",
+	"internal/abi",
+	"runtime/internal/math",
+	"internal/bytealg",
+	"internal/goexperiment",
+	"runtime/internal/syscall",
+	"runtime",
+}
+
+// Scoping note: the constants and apis in this file are internal
+// only, not expected to ever be exposed outside of the runtime (unlike
+// other coverage file formats and APIs, which will likely be shared
+// at some point).
+
+// NotHardCoded is a package pseudo-ID indicating that a given package
+// is not part of the runtime and doesn't require a hard-coded ID.
+const NotHardCoded = -1
+
+// HardCodedPkgID returns the hard-coded ID for the specified package
+// path, or -1 if we don't use a hard-coded ID. Hard-coded IDs start
+// at -2 and decrease as we go down the list.
+func HardCodedPkgID(pkgpath string) int {
+	for k, p := range rtPkgs {
+		if p == pkgpath {
+			return (0 - k) - 2
+		}
+	}
+	return NotHardCoded
+}
diff --git a/src/internal/coverage/pods/pods.go b/src/internal/coverage/pods/pods.go
new file mode 100644
index 0000000..432c7b6
--- /dev/null
+++ b/src/internal/coverage/pods/pods.go
@@ -0,0 +1,194 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pods
+
+import (
+	"fmt"
+	"internal/coverage"
+	"os"
+	"path/filepath"
+	"regexp"
+	"sort"
+	"strconv"
+)
+
+// Pod encapsulates a set of files emitted during the executions of a
+// coverage-instrumented binary. Each pod contains a single meta-data
+// file, and then 0 or more counter data files that refer to that
+// meta-data file. Pods are intended to simplify processing of
+// coverage output files in the case where we have several coverage
+// output directories containing output files derived from more
+// than one instrumented executable. In the case where the files that
+// make up a pod are spread out across multiple directories, each
+// element of the "Origins" field below will be populated with the
+// index of the originating directory for the corresponding counter
+// data file (within the slice of input dirs handed to CollectPods).
+// The ProcessIDs field will be populated with the process ID of each
+// data file in the CounterDataFiles slice.
+type Pod struct {
+	MetaFile         string
+	CounterDataFiles []string
+	Origins          []int
+	ProcessIDs       []int
+}
+
+// CollectPods visits the files contained within the directories in
+// the list 'dirs', collects any coverage-related files, partitions
+// them into pods, and returns a list of the pods to the caller, along
+// with an error if something went wrong during directory/file
+// reading.
+//
+// CollectPods skips over any file that is not related to coverage
+// (e.g. avoids looking at things that are not meta-data files or
+// counter-data files). CollectPods also skips over 'orphaned' counter
+// data files (e.g. counter data files for which we can't find the
+// corresponding meta-data file). If "warn" is true, CollectPods will
+// issue warnings to stderr when it encounters non-fatal problems (for
+// orphans or a directory with no meta-data files).
+func CollectPods(dirs []string, warn bool) ([]Pod, error) {
+	files := []string{}
+	dirIndices := []int{}
+	for k, dir := range dirs {
+		dents, err := os.ReadDir(dir)
+		if err != nil {
+			return nil, err
+		}
+		for _, e := range dents {
+			if e.IsDir() {
+				continue
+			}
+			files = append(files, filepath.Join(dir, e.Name()))
+			dirIndices = append(dirIndices, k)
+		}
+	}
+	return collectPodsImpl(files, dirIndices, warn), nil
+}
+
+// CollectPodsFromFiles functions the same as "CollectPods" but
+// operates on an explicit list of files instead of a directory.
+func CollectPodsFromFiles(files []string, warn bool) []Pod {
+	return collectPodsImpl(files, nil, warn)
+}
+
+type fileWithAnnotations struct {
+	file   string
+	origin int
+	pid    int
+}
+
+type protoPod struct {
+	mf       string
+	elements []fileWithAnnotations
+}
+
+// collectPodsImpl examines the specified list of files and picks out
+// subsets that correspond to coverage pods. The first stage in this
+// process is collecting a set { M1, M2, ... MN } where each M_k is a
+// distinct coverage meta-data file. We then create a single pod for
+// each meta-data file M_k, then find all of the counter data files
+// that refer to that meta-data file (recall that the counter data
+// file name incorporates the meta-data hash), and add the counter
+// data file to the appropriate pod.
+//
+// This process is complicated by the fact that we need to keep track
+// of directory indices for counter data files. Here is an example to
+// motivate:
+//
+//	directory 1:
+//
+// M1   covmeta.9bbf1777f47b3fcacb05c38b035512d6
+// C1   covcounters.9bbf1777f47b3fcacb05c38b035512d6.1677673.1662138360208416486
+// C2   covcounters.9bbf1777f47b3fcacb05c38b035512d6.1677637.1662138359974441782
+//
+//	directory 2:
+//
+// M2   covmeta.9bbf1777f47b3fcacb05c38b035512d6
+// C3   covcounters.9bbf1777f47b3fcacb05c38b035512d6.1677445.1662138360208416480
+// C4   covcounters.9bbf1777f47b3fcacb05c38b035512d6.1677677.1662138359974441781
+// M3   covmeta.a723844208cea2ae80c63482c78b2245
+// C5   covcounters.a723844208cea2ae80c63482c78b2245.3677445.1662138360208416480
+// C6   covcounters.a723844208cea2ae80c63482c78b2245.1877677.1662138359974441781
+//
+// In these two directories we have three meta-data files, but only
+// two are distinct, meaning that we'll wind up with two pods. The
+// first pod (with meta-file M1) will have four counter data files
+// (C1, C2, C3, C4) and the second pod will have two counter data files
+// (C5, C6).
+func collectPodsImpl(files []string, dirIndices []int, warn bool) []Pod {
+	metaRE := regexp.MustCompile(fmt.Sprintf(`^%s\.(\S+)$`, coverage.MetaFilePref))
+	mm := make(map[string]protoPod)
+	for _, f := range files {
+		base := filepath.Base(f)
+		if m := metaRE.FindStringSubmatch(base); m != nil {
+			tag := m[1]
+			// We need to allow for the possibility of duplicate
+			// meta-data files. If we hit this case, use the
+			// first encountered as the canonical version.
+			if _, ok := mm[tag]; !ok {
+				mm[tag] = protoPod{mf: f}
+			}
+			// FIXME: should probably check file length and hash here for
+			// the duplicate.
+		}
+	}
+	counterRE := regexp.MustCompile(fmt.Sprintf(coverage.CounterFileRegexp, coverage.CounterFilePref))
+	for k, f := range files {
+		base := filepath.Base(f)
+		if m := counterRE.FindStringSubmatch(base); m != nil {
+			tag := m[1] // meta hash
+			pid, err := strconv.Atoi(m[2])
+			if err != nil {
+				continue
+			}
+			if v, ok := mm[tag]; ok {
+				idx := -1
+				if dirIndices != nil {
+					idx = dirIndices[k]
+				}
+				fo := fileWithAnnotations{file: f, origin: idx, pid: pid}
+				v.elements = append(v.elements, fo)
+				mm[tag] = v
+			} else {
+				if warn {
+					warning("skipping orphaned counter file: %s", f)
+				}
+			}
+		}
+	}
+	if len(mm) == 0 {
+		if warn {
+			warning("no coverage data files found")
+		}
+		return nil
+	}
+	pods := make([]Pod, 0, len(mm))
+	for _, p := range mm {
+		sort.Slice(p.elements, func(i, j int) bool {
+			return p.elements[i].file < p.elements[j].file
+		})
+		pod := Pod{
+			MetaFile:         p.mf,
+			CounterDataFiles: make([]string, 0, len(p.elements)),
+			Origins:          make([]int, 0, len(p.elements)),
+			ProcessIDs:       make([]int, 0, len(p.elements)),
+		}
+		for _, e := range p.elements {
+			pod.CounterDataFiles = append(pod.CounterDataFiles, e.file)
+			pod.Origins = append(pod.Origins, e.origin)
+			pod.ProcessIDs = append(pod.ProcessIDs, e.pid)
+		}
+		pods = append(pods, pod)
+	}
+	sort.Slice(pods, func(i, j int) bool {
+		return pods[i].MetaFile < pods[j].MetaFile
+	})
+	return pods
+}
+
+func warning(s string, a ...interface{}) {
+	fmt.Fprintf(os.Stderr, "warning: ")
+	fmt.Fprintf(os.Stderr, s, a...)
+	fmt.Fprintf(os.Stderr, "\n")
+}
diff --git a/src/internal/coverage/pods/pods_test.go b/src/internal/coverage/pods/pods_test.go
new file mode 100644
index 0000000..28914c5
--- /dev/null
+++ b/src/internal/coverage/pods/pods_test.go
@@ -0,0 +1,142 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pods_test
+
+import (
+	"crypto/md5"
+	"fmt"
+	"internal/coverage"
+	"internal/coverage/pods"
+	"os"
+	"path/filepath"
+	"runtime"
+	"testing"
+)
+
+func TestPodCollection(t *testing.T) {
+	//testenv.MustHaveGoBuild(t)
+
+	mkdir := func(d string, perm os.FileMode) string {
+		dp := filepath.Join(t.TempDir(), d)
+		if err := os.Mkdir(dp, perm); err != nil {
+			t.Fatal(err)
+		}
+		return dp
+	}
+
+	mkfile := func(d string, fn string) string {
+		fp := filepath.Join(d, fn)
+		if err := os.WriteFile(fp, []byte("foo"), 0666); err != nil {
+			t.Fatal(err)
+		}
+		return fp
+	}
+
+	mkmeta := func(dir string, tag string) string {
+		hash := md5.Sum([]byte(tag))
+		fn := fmt.Sprintf("%s.%x", coverage.MetaFilePref, hash)
+		return mkfile(dir, fn)
+	}
+
+	mkcounter := func(dir string, tag string, nt int) string {
+		hash := md5.Sum([]byte(tag))
+		dummyPid := int(42)
+		fn := fmt.Sprintf(coverage.CounterFileTempl, coverage.CounterFilePref, hash, dummyPid, nt)
+		return mkfile(dir, fn)
+	}
+
+	trim := func(path string) string {
+		b := filepath.Base(path)
+		d := filepath.Dir(path)
+		db := filepath.Base(d)
+		return db + "/" + b
+	}
+
+	podToString := func(p pods.Pod) string {
+		rv := trim(p.MetaFile) + " [\n"
+		for k, df := range p.CounterDataFiles {
+			rv += trim(df)
+			if p.Origins != nil {
+				rv += fmt.Sprintf(" o:%d", p.Origins[k])
+			}
+			rv += "\n"
+		}
+		return rv + "]"
+	}
+
+	// Create a couple of directories.
+	o1 := mkdir("o1", 0777)
+	o2 := mkdir("o2", 0777)
+
+	// Add some random files (not coverage related)
+	mkfile(o1, "blah.txt")
+	mkfile(o1, "something.exe")
+
+	// Add a meta-data file with two counter files to first dir.
+	mkmeta(o1, "m1")
+	mkcounter(o1, "m1", 1)
+	mkcounter(o1, "m1", 2)
+	mkcounter(o1, "m1", 2)
+
+	// Add a counter file with no associated meta file.
+	mkcounter(o1, "orphan", 9)
+
+	// Add a meta-data file with three counter files to second dir.
+	mkmeta(o2, "m2")
+	mkcounter(o2, "m2", 1)
+	mkcounter(o2, "m2", 2)
+	mkcounter(o2, "m2", 3)
+
+	// Add a duplicate of the first meta-file and a corresponding
+	// counter file to the second dir. This is intended to capture
+	// the scenario where we have two different runs of the same
+	// coverage-instrumented binary, but with the output files
+	// sent to separate directories.
+	mkmeta(o2, "m1")
+	mkcounter(o2, "m1", 11)
+
+	// Collect pods.
+	podlist, err := pods.CollectPods([]string{o1, o2}, true)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// Verify pods
+	if len(podlist) != 2 {
+		t.Fatalf("expected 2 pods got %d pods", len(podlist))
+	}
+
+	for k, p := range podlist {
+		t.Logf("%d: mf=%s\n", k, p.MetaFile)
+	}
+
+	expected := []string{
+		`o1/covmeta.ae7be26cdaa742ca148068d5ac90eaca [
+o1/covcounters.ae7be26cdaa742ca148068d5ac90eaca.42.1 o:0
+o1/covcounters.ae7be26cdaa742ca148068d5ac90eaca.42.2 o:0
+o2/covcounters.ae7be26cdaa742ca148068d5ac90eaca.42.11 o:1
+]`,
+		`o2/covmeta.aaf2f89992379705dac844c0a2a1d45f [
+o2/covcounters.aaf2f89992379705dac844c0a2a1d45f.42.1 o:1
+o2/covcounters.aaf2f89992379705dac844c0a2a1d45f.42.2 o:1
+o2/covcounters.aaf2f89992379705dac844c0a2a1d45f.42.3 o:1
+]`,
+	}
+	for k, exp := range expected {
+		got := podToString(podlist[k])
+		if exp != got {
+			t.Errorf("pod %d: expected:\n%s\ngot:\n%s", k, exp, got)
+		}
+	}
+
+	// Check handling of bad/unreadable dir.
+	if runtime.GOOS == "linux" {
+		dbad := "/dev/null"
+		_, err = pods.CollectPods([]string{dbad}, true)
+		if err == nil {
+			t.Errorf("exected error due to unreadable dir")
+		}
+	}
+}
diff --git a/src/internal/coverage/rtcov/rtcov.go b/src/internal/coverage/rtcov/rtcov.go
new file mode 100644
index 0000000..bbb93ac
--- /dev/null
+++ b/src/internal/coverage/rtcov/rtcov.go
@@ -0,0 +1,34 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package rtcov
+
+// This package contains types whose structure is shared between
+// the runtime package and the "runtime/coverage" package.
+
+// CovMetaBlob is a container for holding the meta-data symbol (an
+// RODATA variable) for an instrumented Go package. Here "p" points to
+// the symbol itself, "len" is the length of the sym in bytes, and
+// "hash" is an md5sum for the sym computed by the compiler. When
+// the init function for a coverage-instrumented package executes, it
+// will make a call into the runtime which will create a covMetaBlob
+// object for the package and chain it onto a global list.
+type CovMetaBlob struct {
+	P                  *byte
+	Len                uint32
+	Hash               [16]byte
+	PkgPath            string
+	PkgID              int
+	CounterMode        uint8 // coverage.CounterMode
+	CounterGranularity uint8 // coverage.CounterGranularity
+}
+
+// CovCounterBlob is a container for encapsulating a counter section
+// (BSS variable) for an instrumented Go module. Here "counters"
+// points to the counter payload and "len" is the number of uint32
+// entries in the section.
+type CovCounterBlob struct {
+	Counters *uint32
+	Len      uint64
+}
diff --git a/src/internal/coverage/slicereader/slicereader.go b/src/internal/coverage/slicereader/slicereader.go
new file mode 100644
index 0000000..3d117ba
--- /dev/null
+++ b/src/internal/coverage/slicereader/slicereader.go
@@ -0,0 +1,98 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package slicereader
+
+import (
+	"encoding/binary"
+	"unsafe"
+)
+
+// This file contains the helper "SliceReader", a utility for
+// reading values from a byte slice that may or may not be backed
+// by a read-only mmap'd region.
+
+type Reader struct {
+	b        []byte
+	readonly bool
+	off      int64
+}
+
+func NewReader(b []byte, readonly bool) *Reader {
+	r := Reader{
+		b:        b,
+		readonly: readonly,
+	}
+	return &r
+}
+
+func (r *Reader) Read(b []byte) (int, error) {
+	amt := len(b)
+	toread := r.b[r.off:]
+	if len(toread) < amt {
+		amt = len(toread)
+	}
+	copy(b, toread)
+	r.off += int64(amt)
+	return amt, nil
+}
+
+func (r *Reader) SeekTo(off int64) {
+	r.off = off
+}
+
+func (r *Reader) Offset() int64 {
+	return r.off
+}
+
+func (r *Reader) ReadUint8() uint8 {
+	rv := uint8(r.b[int(r.off)])
+	r.off += 1
+	return rv
+}
+
+func (r *Reader) ReadUint32() uint32 {
+	end := int(r.off) + 4
+	rv := binary.LittleEndian.Uint32(r.b[int(r.off):end:end])
+	r.off += 4
+	return rv
+}
+
+func (r *Reader) ReadUint64() uint64 {
+	end := int(r.off) + 8
+	rv := binary.LittleEndian.Uint64(r.b[int(r.off):end:end])
+	r.off += 8
+	return rv
+}
+
+func (r *Reader) ReadULEB128() (value uint64) {
+	var shift uint
+
+	for {
+		b := r.b[r.off]
+		r.off++
+		value |= (uint64(b&0x7F) << shift)
+		if b&0x80 == 0 {
+			break
+		}
+		shift += 7
+	}
+	return
+}
+
+func (r *Reader) ReadString(len int64) string {
+	b := r.b[r.off : r.off+len]
+	r.off += len
+	if r.readonly {
+		return toString(b) // backed by RO memory, ok to make unsafe string
+	}
+	return string(b)
+}
+
+func toString(b []byte) string {
+	if len(b) == 0 {
+		return ""
+	}
+	return unsafe.String(&b[0], len(b))
+}
diff --git a/src/internal/coverage/slicereader/slr_test.go b/src/internal/coverage/slicereader/slr_test.go
new file mode 100644
index 0000000..2f7cef0
--- /dev/null
+++ b/src/internal/coverage/slicereader/slr_test.go
@@ -0,0 +1,92 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package slicereader
+
+import (
+	"encoding/binary"
+	"testing"
+)
+
+func TestSliceReader(t *testing.T) {
+	b := []byte{}
+
+	bt := make([]byte, 4)
+	e32 := uint32(1030507)
+	binary.LittleEndian.PutUint32(bt, e32)
+	b = append(b, bt...)
+
+	bt = make([]byte, 8)
+	e64 := uint64(907050301)
+	binary.LittleEndian.PutUint64(bt, e64)
+	b = append(b, bt...)
+
+	b = appendUleb128(b, uint(e32))
+	b = appendUleb128(b, uint(e64))
+	b = appendUleb128(b, 6)
+	s1 := "foobar"
+	s1b := []byte(s1)
+	b = append(b, s1b...)
+	b = appendUleb128(b, 9)
+	s2 := "bazbasher"
+	s2b := []byte(s2)
+	b = append(b, s2b...)
+
+	readStr := func(slr *Reader) string {
+		len := slr.ReadULEB128()
+		return slr.ReadString(int64(len))
+	}
+
+	for i := 0; i < 2; i++ {
+		slr := NewReader(b, i == 0)
+		g32 := slr.ReadUint32()
+		if g32 != e32 {
+			t.Fatalf("slr.ReadUint32() got %d want %d", g32, e32)
+		}
+		g64 := slr.ReadUint64()
+		if g64 != e64 {
+			t.Fatalf("slr.ReadUint64() got %d want %d", g64, e64)
+		}
+		g32 = uint32(slr.ReadULEB128())
+		if g32 != e32 {
+			t.Fatalf("slr.ReadULEB128() got %d want %d", g32, e32)
+		}
+		g64 = slr.ReadULEB128()
+		if g64 != e64 {
+			t.Fatalf("slr.ReadULEB128() got %d want %d", g64, e64)
+		}
+		gs1 := readStr(slr)
+		if gs1 != s1 {
+			t.Fatalf("readStr got %s want %s", gs1, s1)
+		}
+		gs2 := readStr(slr)
+		if gs2 != s2 {
+			t.Fatalf("readStr got %s want %s", gs2, s2)
+		}
+		slr.SeekTo(4)
+		off := slr.Offset()
+		if off != 4 {
+			t.Fatalf("Offset(0 returned %d wanted 4", off)
+		}
+		g64 = slr.ReadUint64()
+		if g64 != e64 {
+			t.Fatalf("post-seek slr.ReadUint64() got %d want %d", g64, e64)
+		}
+	}
+}
+
+func appendUleb128(b []byte, v uint) []byte {
+	for {
+		c := uint8(v & 0x7f)
+		v >>= 7
+		if v != 0 {
+			c |= 0x80
+		}
+		b = append(b, c)
+		if c&0x80 == 0 {
+			break
+		}
+	}
+	return b
+}
diff --git a/src/internal/coverage/slicewriter/slicewriter.go b/src/internal/coverage/slicewriter/slicewriter.go
new file mode 100644
index 0000000..3522bf5
--- /dev/null
+++ b/src/internal/coverage/slicewriter/slicewriter.go
@@ -0,0 +1,80 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package slicewriter
+
+import (
+	"fmt"
+	"io"
+)
+
+// WriteSeeker is a helper object that implements the io.WriteSeeker
+// interface. Clients can create a WriteSeeker, make a series of Write
+// calls to add data to it (and possibly Seek calls to update
+// previously written portions), then finally invoke BytesWritten() to
+// get a pointer to the constructed byte slice.
+type WriteSeeker struct {
+	payload []byte
+	off     int64
+}
+
+func (sws *WriteSeeker) Write(p []byte) (n int, err error) {
+	amt := len(p)
+	towrite := sws.payload[sws.off:]
+	if len(towrite) < amt {
+		sws.payload = append(sws.payload, make([]byte, amt-len(towrite))...)
+		towrite = sws.payload[sws.off:]
+	}
+	copy(towrite, p)
+	sws.off += int64(amt)
+	return amt, nil
+}
+
+// Seek repositions the read/write position of the WriteSeeker within
+// its internally maintained slice. Note that it is not possible to
+// expand the size of the slice using SEEK_SET; trying to seek outside
+// the slice will result in an error.
+func (sws *WriteSeeker) Seek(offset int64, whence int) (int64, error) {
+	switch whence {
+	case io.SeekStart:
+		if sws.off != offset && (offset < 0 || offset >= int64(len(sws.payload))) {
+			return 0, fmt.Errorf("invalid seek: new offset %d (out of range [0 %d]", offset, len(sws.payload))
+		}
+		sws.off = offset
+		return offset, nil
+	case io.SeekCurrent:
+		newoff := sws.off + offset
+		if newoff != sws.off && (newoff < 0 || newoff >= int64(len(sws.payload))) {
+			return 0, fmt.Errorf("invalid seek: new offset %d (out of range [0 %d]", newoff, len(sws.payload))
+		}
+		sws.off += offset
+		return sws.off, nil
+	case io.SeekEnd:
+		newoff := int64(len(sws.payload)) + offset
+		if newoff != sws.off && (newoff < 0 || newoff >= int64(len(sws.payload))) {
+			return 0, fmt.Errorf("invalid seek: new offset %d (out of range [0 %d]", newoff, len(sws.payload))
+		}
+		sws.off = newoff
+		return sws.off, nil
+	}
+	// other modes not supported
+	return 0, fmt.Errorf("unsupported seek mode %d", whence)
+}
+
+// BytesWritten returns the underlying byte slice for the WriteSeeker,
+// containing the data written to it via Write/Seek calls.
+func (sws *WriteSeeker) BytesWritten() []byte {
+	return sws.payload
+}
+
+func (sws *WriteSeeker) Read(p []byte) (n int, err error) {
+	amt := len(p)
+	toread := sws.payload[sws.off:]
+	if len(toread) < amt {
+		amt = len(toread)
+	}
+	copy(p, toread)
+	sws.off += int64(amt)
+	return amt, nil
+}
diff --git a/src/internal/coverage/slicewriter/slw_test.go b/src/internal/coverage/slicewriter/slw_test.go
new file mode 100644
index 0000000..f4e75f4
--- /dev/null
+++ b/src/internal/coverage/slicewriter/slw_test.go
@@ -0,0 +1,131 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package slicewriter
+
+import (
+	"io"
+	"testing"
+)
+
+func TestSliceWriter(t *testing.T) {
+
+	sleq := func(t *testing.T, got []byte, want []byte) {
+		t.Helper()
+		if len(got) != len(want) {
+			t.Fatalf("bad length got %d want %d", len(got), len(want))
+		}
+		for i := range got {
+			if got[i] != want[i] {
+				t.Fatalf("bad read at %d got %d want %d", i, got[i], want[i])
+			}
+		}
+	}
+
+	wf := func(t *testing.T, ws *WriteSeeker, p []byte) {
+		t.Helper()
+		nw, werr := ws.Write(p)
+		if werr != nil {
+			t.Fatalf("unexpected write error: %v", werr)
+		}
+		if nw != len(p) {
+			t.Fatalf("wrong amount written want %d got %d", len(p), nw)
+		}
+	}
+
+	rf := func(t *testing.T, ws *WriteSeeker, p []byte) {
+		t.Helper()
+		b := make([]byte, len(p))
+		nr, rerr := ws.Read(b)
+		if rerr != nil {
+			t.Fatalf("unexpected read error: %v", rerr)
+		}
+		if nr != len(p) {
+			t.Fatalf("wrong amount read want %d got %d", len(p), nr)
+		}
+		sleq(t, b, p)
+	}
+
+	sk := func(t *testing.T, ws *WriteSeeker, offset int64, whence int) {
+		t.Helper()
+		_, err := ws.Seek(offset, whence)
+		if err != nil {
+			t.Fatalf("unexpected seek error: %v", err)
+		}
+	}
+
+	wp1 := []byte{1, 2}
+	ws := &WriteSeeker{}
+
+	// write some stuff
+	wf(t, ws, wp1)
+	// check that BytesWritten returns what we wrote.
+	sleq(t, ws.BytesWritten(), wp1)
+	// offset is at end of slice, so reading should return zero bytes.
+	rf(t, ws, []byte{})
+
+	// write some more stuff
+	wp2 := []byte{7, 8, 9}
+	wf(t, ws, wp2)
+	// check that BytesWritten returns what we expect.
+	wpex := []byte{1, 2, 7, 8, 9}
+	sleq(t, ws.BytesWritten(), wpex)
+	rf(t, ws, []byte{})
+
+	// seeks and reads.
+	sk(t, ws, 1, io.SeekStart)
+	rf(t, ws, []byte{2, 7})
+	sk(t, ws, -2, io.SeekCurrent)
+	rf(t, ws, []byte{2, 7})
+	sk(t, ws, -4, io.SeekEnd)
+	rf(t, ws, []byte{2, 7})
+
+	// seek back and overwrite
+	sk(t, ws, 1, io.SeekStart)
+	wf(t, ws, []byte{9, 11})
+	wpex = []byte{1, 9, 11, 8, 9}
+	sleq(t, ws.BytesWritten(), wpex)
+
+	// seeks on empty writer.
+	ws2 := &WriteSeeker{}
+	sk(t, ws2, 0, io.SeekStart)
+	sk(t, ws2, 0, io.SeekCurrent)
+	sk(t, ws2, 0, io.SeekEnd)
+
+	// check for seek errors.
+	_, err := ws.Seek(-1, io.SeekStart)
+	if err == nil {
+		t.Fatalf("expected error on invalid -1 seek")
+	}
+	_, err = ws.Seek(int64(len(ws.BytesWritten())), io.SeekStart)
+	if err == nil {
+		t.Fatalf("expected error on invalid %d seek", len(ws.BytesWritten()))
+	}
+
+	ws.Seek(0, io.SeekStart)
+	_, err = ws.Seek(-1, io.SeekCurrent)
+	if err == nil {
+		t.Fatalf("expected error on invalid -1 seek")
+	}
+	_, err = ws.Seek(int64(len(ws.BytesWritten())), io.SeekCurrent)
+	if err == nil {
+		t.Fatalf("expected error on invalid %d seek", len(ws.BytesWritten()))
+	}
+
+	_, err = ws.Seek(1, io.SeekEnd)
+	if err == nil {
+		t.Fatalf("expected error on invalid 1 seek")
+	}
+	bsamt := int64(-1*len(ws.BytesWritten()) - 1)
+	_, err = ws.Seek(bsamt, io.SeekEnd)
+	if err == nil {
+		t.Fatalf("expected error on invalid %d seek", bsamt)
+	}
+
+	// bad seek mode
+	_, err = ws.Seek(-1, io.SeekStart+9)
+	if err == nil {
+		t.Fatalf("expected error on invalid seek mode")
+	}
+}
diff --git a/src/internal/coverage/stringtab/stringtab.go b/src/internal/coverage/stringtab/stringtab.go
new file mode 100644
index 0000000..156c8ad
--- /dev/null
+++ b/src/internal/coverage/stringtab/stringtab.go
@@ -0,0 +1,139 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package stringtab
+
+import (
+	"fmt"
+	"internal/coverage/slicereader"
+	"internal/coverage/uleb128"
+	"io"
+)
+
+// This package implements string table writer and reader utilities,
+// for use in emitting and reading/decoding coverage meta-data and
+// counter-data files.
+
+// Writer implements a string table writing utility.
+type Writer struct {
+	stab   map[string]uint32
+	strs   []string
+	tmp    []byte
+	frozen bool
+}
+
+// InitWriter initializes a stringtab.Writer.
+func (stw *Writer) InitWriter() {
+	stw.stab = make(map[string]uint32)
+	stw.tmp = make([]byte, 64)
+}
+
+// Nentries returns the number of strings interned so far.
+func (stw *Writer) Nentries() uint32 {
+	return uint32(len(stw.strs))
+}
+
+// Lookup looks up string 's' in the writer's table, adding
+// a new entry if need be, and returning an index into the table.
+func (stw *Writer) Lookup(s string) uint32 {
+	if idx, ok := stw.stab[s]; ok {
+		return idx
+	}
+	if stw.frozen {
+		panic("internal error: string table previously frozen")
+	}
+	idx := uint32(len(stw.strs))
+	stw.stab[s] = idx
+	stw.strs = append(stw.strs, s)
+	return idx
+}
+
+// Size computes the memory in bytes needed for the serialized
+// version of a stringtab.Writer.
+func (stw *Writer) Size() uint32 {
+	rval := uint32(0)
+	stw.tmp = stw.tmp[:0]
+	stw.tmp = uleb128.AppendUleb128(stw.tmp, uint(len(stw.strs)))
+	rval += uint32(len(stw.tmp))
+	for _, s := range stw.strs {
+		stw.tmp = stw.tmp[:0]
+		slen := uint(len(s))
+		stw.tmp = uleb128.AppendUleb128(stw.tmp, slen)
+		rval += uint32(len(stw.tmp)) + uint32(slen)
+	}
+	return rval
+}
+
+// Write writes the string table in serialized form to the specified
+// io.Writer.
+func (stw *Writer) Write(w io.Writer) error {
+	wr128 := func(v uint) error {
+		stw.tmp = stw.tmp[:0]
+		stw.tmp = uleb128.AppendUleb128(stw.tmp, v)
+		if nw, err := w.Write(stw.tmp); err != nil {
+			return fmt.Errorf("writing string table: %v", err)
+		} else if nw != len(stw.tmp) {
+			return fmt.Errorf("short write emitting stringtab uleb")
+		}
+		return nil
+	}
+	if err := wr128(uint(len(stw.strs))); err != nil {
+		return err
+	}
+	for _, s := range stw.strs {
+		if err := wr128(uint(len(s))); err != nil {
+			return err
+		}
+		if nw, err := w.Write([]byte(s)); err != nil {
+			return fmt.Errorf("writing string table: %v", err)
+		} else if nw != len([]byte(s)) {
+			return fmt.Errorf("short write emitting stringtab")
+		}
+	}
+	return nil
+}
+
+// Freeze sends a signal to the writer that no more additions are
+// allowed, only lookups of existing strings (if a lookup triggers
+// addition, a panic will result). Useful as a mechanism for
+// "finalizing" a string table prior to writing it out.
+func (stw *Writer) Freeze() {
+	stw.frozen = true
+}
+
+// Reader is a helper for reading a string table previously
+// serialized by a Writer.Write call.
+type Reader struct {
+	r    *slicereader.Reader
+	strs []string
+}
+
+// NewReader creates a stringtab.Reader to read the contents
+// of a string table from 'r'.
+func NewReader(r *slicereader.Reader) *Reader {
+	str := &Reader{
+		r: r,
+	}
+	return str
+}
+
+// Read reads/decodes a string table using the reader provided.
+func (str *Reader) Read() {
+	numEntries := int(str.r.ReadULEB128())
+	str.strs = make([]string, 0, numEntries)
+	for idx := 0; idx < numEntries; idx++ {
+		slen := str.r.ReadULEB128()
+		str.strs = append(str.strs, str.r.ReadString(int64(slen)))
+	}
+}
+
+// Entries returns the number of decoded entries in a string table.
+func (str *Reader) Entries() int {
+	return len(str.strs)
+}
+
+// Get returns string 'idx' within the string table.
+func (str *Reader) Get(idx uint32) string {
+	return str.strs[idx]
+}
diff --git a/src/internal/coverage/test/counter_test.go b/src/internal/coverage/test/counter_test.go
new file mode 100644
index 0000000..3fc111e
--- /dev/null
+++ b/src/internal/coverage/test/counter_test.go
@@ -0,0 +1,241 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package test
+
+import (
+	"fmt"
+	"internal/coverage"
+	"internal/coverage/decodecounter"
+	"internal/coverage/encodecounter"
+	"io"
+	"os"
+	"path/filepath"
+	"testing"
+)
+
+type ctrVis struct {
+	funcs []decodecounter.FuncPayload
+}
+
+func (v *ctrVis) NumFuncs() (int, error) {
+	return len(v.funcs), nil
+}
+
+func (v *ctrVis) VisitFuncs(f encodecounter.CounterVisitorFn) error {
+	for _, fn := range v.funcs {
+		if err := f(fn.PkgIdx, fn.FuncIdx, fn.Counters); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func mkfunc(p uint32, f uint32, c []uint32) decodecounter.FuncPayload {
+	return decodecounter.FuncPayload{
+		PkgIdx:   p,
+		FuncIdx:  f,
+		Counters: c,
+	}
+}
+
+func TestCounterDataWriterReader(t *testing.T) {
+	flavors := []coverage.CounterFlavor{
+		coverage.CtrRaw,
+		coverage.CtrULeb128,
+	}
+
+	isDead := func(fp decodecounter.FuncPayload) bool {
+		for _, v := range fp.Counters {
+			if v != 0 {
+				return false
+			}
+		}
+		return true
+	}
+
+	funcs := []decodecounter.FuncPayload{
+		mkfunc(0, 0, []uint32{13, 14, 15}),
+		mkfunc(0, 1, []uint32{16, 17}),
+		mkfunc(1, 0, []uint32{18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 976543, 7}),
+	}
+	writeVisitor := &ctrVis{funcs: funcs}
+
+	for kf, flav := range flavors {
+
+		t.Logf("testing flavor %d\n", flav)
+
+		// Open a counter data file in preparation for emitting data.
+		d := t.TempDir()
+		cfpath := filepath.Join(d, fmt.Sprintf("covcounters.hash.0.%d", kf))
+		of, err := os.OpenFile(cfpath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
+		if err != nil {
+			t.Fatalf("opening covcounters: %v", err)
+		}
+
+		// Perform the encode and write.
+		cdfw := encodecounter.NewCoverageDataWriter(of, flav)
+		if cdfw == nil {
+			t.Fatalf("NewCoverageDataWriter failed")
+		}
+		finalHash := [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0}
+		args := map[string]string{"argc": "3", "argv0": "arg0", "argv1": "arg1", "argv2": "arg_________2"}
+		if err := cdfw.Write(finalHash, args, writeVisitor); err != nil {
+			t.Fatalf("counter file Write failed: %v", err)
+		}
+		if err := of.Close(); err != nil {
+			t.Fatalf("closing covcounters: %v", err)
+		}
+		cdfw = nil
+
+		// Decode the same file.
+		var cdr *decodecounter.CounterDataReader
+		inf, err := os.Open(cfpath)
+		defer func() {
+			if err := inf.Close(); err != nil {
+				t.Fatalf("close failed with: %v", err)
+			}
+		}()
+
+		if err != nil {
+			t.Fatalf("reopening covcounters file: %v", err)
+		}
+		if cdr, err = decodecounter.NewCounterDataReader(cfpath, inf); err != nil {
+			t.Fatalf("opening covcounters for read: %v", err)
+		}
+		decodedArgs := cdr.OsArgs()
+		aWant := "[arg0 arg1 arg_________2]"
+		aGot := fmt.Sprintf("%+v", decodedArgs)
+		if aWant != aGot {
+			t.Errorf("reading decoded args, got %s want %s", aGot, aWant)
+		}
+		for i := range funcs {
+			if isDead(funcs[i]) {
+				continue
+			}
+			var fp decodecounter.FuncPayload
+			if ok, err := cdr.NextFunc(&fp); err != nil {
+				t.Fatalf("reading func %d: %v", i, err)
+			} else if !ok {
+				t.Fatalf("reading func %d: bad return", i)
+			}
+			got := fmt.Sprintf("%+v", fp)
+			want := fmt.Sprintf("%+v", funcs[i])
+			if got != want {
+				t.Errorf("cdr.NextFunc iter %d\ngot  %+v\nwant %+v", i, got, want)
+			}
+		}
+		var dummy decodecounter.FuncPayload
+		if ok, err := cdr.NextFunc(&dummy); err != nil {
+			t.Fatalf("reading func after loop: %v", err)
+		} else if ok {
+			t.Fatalf("reading func after loop: expected EOF")
+		}
+	}
+}
+
+func TestCounterDataAppendSegment(t *testing.T) {
+	d := t.TempDir()
+	cfpath := filepath.Join(d, "covcounters.hash2.0")
+	of, err := os.OpenFile(cfpath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
+	if err != nil {
+		t.Fatalf("opening covcounters: %v", err)
+	}
+
+	const numSegments = 2
+
+	// Write a counter with with multiple segments.
+	args := map[string]string{"argc": "1", "argv0": "prog.exe"}
+	allfuncs := [][]decodecounter.FuncPayload{}
+	ctrs := []uint32{}
+	q := uint32(0)
+	var cdfw *encodecounter.CoverageDataWriter
+	for idx := 0; idx < numSegments; idx++ {
+		args[fmt.Sprintf("seg%d", idx)] = "x"
+		q += 7
+		ctrs = append(ctrs, q)
+		funcs := []decodecounter.FuncPayload{}
+		for k := 0; k < idx+1; k++ {
+			c := make([]uint32, len(ctrs))
+			copy(c, ctrs)
+			funcs = append(funcs, mkfunc(uint32(idx), uint32(k), c))
+		}
+		allfuncs = append(allfuncs, funcs)
+
+		writeVisitor := &ctrVis{funcs: funcs}
+
+		if idx == 0 {
+			// Perform the encode and write.
+			cdfw = encodecounter.NewCoverageDataWriter(of, coverage.CtrRaw)
+			if cdfw == nil {
+				t.Fatalf("NewCoverageDataWriter failed")
+			}
+			finalHash := [16]byte{1, 2}
+			if err := cdfw.Write(finalHash, args, writeVisitor); err != nil {
+				t.Fatalf("counter file Write failed: %v", err)
+			}
+		} else {
+			if err := cdfw.AppendSegment(args, writeVisitor); err != nil {
+				t.Fatalf("counter file AppendSegment failed: %v", err)
+			}
+		}
+	}
+	if err := of.Close(); err != nil {
+		t.Fatalf("closing covcounters: %v", err)
+	}
+
+	// Read the result file.
+	var cdr *decodecounter.CounterDataReader
+	inf, err := os.Open(cfpath)
+	defer func() {
+		if err := inf.Close(); err != nil {
+			t.Fatalf("close failed with: %v", err)
+		}
+	}()
+
+	if err != nil {
+		t.Fatalf("reopening covcounters file: %v", err)
+	}
+	if cdr, err = decodecounter.NewCounterDataReader(cfpath, inf); err != nil {
+		t.Fatalf("opening covcounters for read: %v", err)
+	}
+	ns := cdr.NumSegments()
+	if ns != numSegments {
+		t.Fatalf("got %d segments want %d", ns, numSegments)
+	}
+	if len(allfuncs) != numSegments {
+		t.Fatalf("expected %d got %d", numSegments, len(allfuncs))
+	}
+
+	for sidx := 0; sidx < int(ns); sidx++ {
+		if off, err := inf.Seek(0, io.SeekCurrent); err != nil {
+			t.Fatalf("Seek failed: %v", err)
+		} else {
+			t.Logf("sidx=%d off=%d\n", sidx, off)
+		}
+
+		if sidx != 0 {
+			if ok, err := cdr.BeginNextSegment(); err != nil {
+				t.Fatalf("BeginNextSegment failed: %v", err)
+			} else if !ok {
+				t.Fatalf("BeginNextSegment return %v on iter %d",
+					ok, sidx)
+			}
+		}
+		funcs := allfuncs[sidx]
+		for i := range funcs {
+			var fp decodecounter.FuncPayload
+			if ok, err := cdr.NextFunc(&fp); err != nil {
+				t.Fatalf("reading func %d: %v", i, err)
+			} else if !ok {
+				t.Fatalf("reading func %d: bad return", i)
+			}
+			got := fmt.Sprintf("%+v", fp)
+			want := fmt.Sprintf("%+v", funcs[i])
+			if got != want {
+				t.Errorf("cdr.NextFunc iter %d\ngot  %+v\nwant %+v", i, got, want)
+			}
+		}
+	}
+}
diff --git a/src/internal/coverage/test/roundtrip_test.go b/src/internal/coverage/test/roundtrip_test.go
new file mode 100644
index 0000000..614f56e
--- /dev/null
+++ b/src/internal/coverage/test/roundtrip_test.go
@@ -0,0 +1,331 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package test
+
+import (
+	"fmt"
+	"internal/coverage"
+	"internal/coverage/decodemeta"
+	"internal/coverage/encodemeta"
+	"internal/coverage/slicewriter"
+	"io"
+	"os"
+	"path/filepath"
+	"testing"
+)
+
+func cmpFuncDesc(want, got coverage.FuncDesc) string {
+	swant := fmt.Sprintf("%+v", want)
+	sgot := fmt.Sprintf("%+v", got)
+	if swant == sgot {
+		return ""
+	}
+	return fmt.Sprintf("wanted %q got %q", swant, sgot)
+}
+
+func TestMetaDataEmptyPackage(t *testing.T) {
+	// Make sure that encoding/decoding works properly with packages
+	// that don't actually have any functions.
+	p := "empty/package"
+	pn := "package"
+	mp := "m"
+	b, err := encodemeta.NewCoverageMetaDataBuilder(p, pn, mp)
+	if err != nil {
+		t.Fatalf("making builder: %v", err)
+	}
+	drws := &slicewriter.WriteSeeker{}
+	b.Emit(drws)
+	drws.Seek(0, io.SeekStart)
+	dec, err := decodemeta.NewCoverageMetaDataDecoder(drws.BytesWritten(), false)
+	if err != nil {
+		t.Fatalf("making decoder: %v", err)
+	}
+	nf := dec.NumFuncs()
+	if nf != 0 {
+		t.Errorf("dec.NumFuncs(): got %d want %d", nf, 0)
+	}
+	pp := dec.PackagePath()
+	if pp != p {
+		t.Errorf("dec.PackagePath(): got %s want %s", pp, p)
+	}
+	ppn := dec.PackageName()
+	if ppn != pn {
+		t.Errorf("dec.PackageName(): got %s want %s", ppn, pn)
+	}
+	pmp := dec.ModulePath()
+	if pmp != mp {
+		t.Errorf("dec.ModulePath(): got %s want %s", pmp, mp)
+	}
+}
+
+func TestMetaDataEncoderDecoder(t *testing.T) {
+	// Test encode path.
+	pp := "foo/bar/pkg"
+	pn := "pkg"
+	mp := "barmod"
+	b, err := encodemeta.NewCoverageMetaDataBuilder(pp, pn, mp)
+	if err != nil {
+		t.Fatalf("making builder: %v", err)
+	}
+	f1 := coverage.FuncDesc{
+		Funcname: "func",
+		Srcfile:  "foo.go",
+		Units: []coverage.CoverableUnit{
+			coverage.CoverableUnit{StLine: 1, StCol: 2, EnLine: 3, EnCol: 4, NxStmts: 5},
+			coverage.CoverableUnit{StLine: 6, StCol: 7, EnLine: 8, EnCol: 9, NxStmts: 10},
+		},
+	}
+	idx := b.AddFunc(f1)
+	if idx != 0 {
+		t.Errorf("b.AddFunc(f1) got %d want %d", idx, 0)
+	}
+
+	f2 := coverage.FuncDesc{
+		Funcname: "xfunc",
+		Srcfile:  "bar.go",
+		Units: []coverage.CoverableUnit{
+			coverage.CoverableUnit{StLine: 1, StCol: 2, EnLine: 3, EnCol: 4, NxStmts: 5},
+			coverage.CoverableUnit{StLine: 6, StCol: 7, EnLine: 8, EnCol: 9, NxStmts: 10},
+			coverage.CoverableUnit{StLine: 11, StCol: 12, EnLine: 13, EnCol: 14, NxStmts: 15},
+		},
+	}
+	idx = b.AddFunc(f2)
+	if idx != 1 {
+		t.Errorf("b.AddFunc(f2) got %d want %d", idx, 0)
+	}
+
+	// Emit into a writer.
+	drws := &slicewriter.WriteSeeker{}
+	b.Emit(drws)
+
+	// Test decode path.
+	drws.Seek(0, io.SeekStart)
+	dec, err := decodemeta.NewCoverageMetaDataDecoder(drws.BytesWritten(), false)
+	if err != nil {
+		t.Fatalf("NewCoverageMetaDataDecoder error: %v", err)
+	}
+	nf := dec.NumFuncs()
+	if nf != 2 {
+		t.Errorf("dec.NumFuncs(): got %d want %d", nf, 2)
+	}
+
+	gotpp := dec.PackagePath()
+	if gotpp != pp {
+		t.Errorf("packagepath: got %s want %s", gotpp, pp)
+	}
+	gotpn := dec.PackageName()
+	if gotpn != pn {
+		t.Errorf("packagename: got %s want %s", gotpn, pn)
+	}
+
+	cases := []coverage.FuncDesc{f1, f2}
+	for i := uint32(0); i < uint32(len(cases)); i++ {
+		var fn coverage.FuncDesc
+		if err := dec.ReadFunc(i, &fn); err != nil {
+			t.Fatalf("err reading function %d: %v", i, err)
+		}
+		res := cmpFuncDesc(cases[i], fn)
+		if res != "" {
+			t.Errorf("ReadFunc(%d): %s", i, res)
+		}
+	}
+}
+
+func createFuncs(i int) []coverage.FuncDesc {
+	res := []coverage.FuncDesc{}
+	lc := uint32(1)
+	for fi := 0; fi < i+1; fi++ {
+		units := []coverage.CoverableUnit{}
+		for ui := 0; ui < (fi+1)*(i+1); ui++ {
+			units = append(units,
+				coverage.CoverableUnit{StLine: lc, StCol: lc + 1,
+					EnLine: lc + 2, EnCol: lc + 3, NxStmts: lc + 4,
+				})
+			lc += 5
+		}
+		f := coverage.FuncDesc{
+			Funcname: fmt.Sprintf("func_%d_%d", i, fi),
+			Srcfile:  fmt.Sprintf("foo_%d.go", i),
+			Units:    units,
+		}
+		res = append(res, f)
+	}
+	return res
+}
+
+func createBlob(t *testing.T, i int) []byte {
+	nomodule := ""
+	b, err := encodemeta.NewCoverageMetaDataBuilder("foo/pkg", "pkg", nomodule)
+	if err != nil {
+		t.Fatalf("making builder: %v", err)
+	}
+
+	funcs := createFuncs(i)
+	for _, f := range funcs {
+		b.AddFunc(f)
+	}
+	drws := &slicewriter.WriteSeeker{}
+	b.Emit(drws)
+	return drws.BytesWritten()
+}
+
+func createMetaDataBlobs(t *testing.T, nb int) [][]byte {
+	res := [][]byte{}
+	for i := 0; i < nb; i++ {
+		res = append(res, createBlob(t, i))
+	}
+	return res
+}
+
+func TestMetaDataWriterReader(t *testing.T) {
+	d := t.TempDir()
+
+	// Emit a meta-file...
+	mfpath := filepath.Join(d, "covmeta.hash.0")
+	of, err := os.OpenFile(mfpath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
+	if err != nil {
+		t.Fatalf("opening covmeta: %v", err)
+	}
+	//t.Logf("meta-file path is %s", mfpath)
+	blobs := createMetaDataBlobs(t, 7)
+	gran := coverage.CtrGranularityPerBlock
+	mfw := encodemeta.NewCoverageMetaFileWriter(mfpath, of)
+	finalHash := [16]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
+	err = mfw.Write(finalHash, blobs, coverage.CtrModeAtomic, gran)
+	if err != nil {
+		t.Fatalf("writing meta-file: %v", err)
+	}
+	if err = of.Close(); err != nil {
+		t.Fatalf("closing meta-file: %v", err)
+	}
+
+	// ... then read it back in, first time without setting fileView,
+	// second time setting it.
+	for k := 0; k < 2; k++ {
+		var fileView []byte
+
+		inf, err := os.Open(mfpath)
+		if err != nil {
+			t.Fatalf("open() on meta-file: %v", err)
+		}
+
+		if k != 0 {
+			// Use fileview to exercise different paths in reader.
+			fi, err := os.Stat(mfpath)
+			if err != nil {
+				t.Fatalf("stat() on meta-file: %v", err)
+			}
+			fileView = make([]byte, fi.Size())
+			if _, err := inf.Read(fileView); err != nil {
+				t.Fatalf("read() on meta-file: %v", err)
+			}
+			if _, err := inf.Seek(int64(0), io.SeekStart); err != nil {
+				t.Fatalf("seek() on meta-file: %v", err)
+			}
+		}
+
+		mfr, err := decodemeta.NewCoverageMetaFileReader(inf, fileView)
+		if err != nil {
+			t.Fatalf("k=%d NewCoverageMetaFileReader failed with: %v", k, err)
+		}
+		np := mfr.NumPackages()
+		if np != 7 {
+			t.Fatalf("k=%d wanted 7 packages got %d", k, np)
+		}
+		md := mfr.CounterMode()
+		wmd := coverage.CtrModeAtomic
+		if md != wmd {
+			t.Fatalf("k=%d wanted mode %d got %d", k, wmd, md)
+		}
+		gran := mfr.CounterGranularity()
+		wgran := coverage.CtrGranularityPerBlock
+		if gran != wgran {
+			t.Fatalf("k=%d wanted gran %d got %d", k, wgran, gran)
+		}
+
+		payload := []byte{}
+		for pi := 0; pi < int(np); pi++ {
+			var pd *decodemeta.CoverageMetaDataDecoder
+			var err error
+			pd, payload, err = mfr.GetPackageDecoder(uint32(pi), payload)
+			if err != nil {
+				t.Fatalf("GetPackageDecoder(%d) failed with: %v", pi, err)
+			}
+			efuncs := createFuncs(pi)
+			nf := pd.NumFuncs()
+			if len(efuncs) != int(nf) {
+				t.Fatalf("decoding pk %d wanted %d funcs got %d",
+					pi, len(efuncs), nf)
+			}
+			var f coverage.FuncDesc
+			for fi := 0; fi < int(nf); fi++ {
+				if err := pd.ReadFunc(uint32(fi), &f); err != nil {
+					t.Fatalf("ReadFunc(%d) pk %d got error %v",
+						fi, pi, err)
+				}
+				res := cmpFuncDesc(efuncs[fi], f)
+				if res != "" {
+					t.Errorf("ReadFunc(%d) pk %d: %s", fi, pi, res)
+				}
+			}
+		}
+		inf.Close()
+	}
+}
+
+func TestMetaDataDecodeLitFlagIssue57942(t *testing.T) {
+
+	// Encode a package with a few functions. The funcs alternate
+	// between regular functions and function literals.
+	pp := "foo/bar/pkg"
+	pn := "pkg"
+	mp := "barmod"
+	b, err := encodemeta.NewCoverageMetaDataBuilder(pp, pn, mp)
+	if err != nil {
+		t.Fatalf("making builder: %v", err)
+	}
+	const NF = 6
+	const NCU = 1
+	ln := uint32(10)
+	wantfds := []coverage.FuncDesc{}
+	for fi := uint32(0); fi < NF; fi++ {
+		fis := fmt.Sprintf("%d", fi)
+		fd := coverage.FuncDesc{
+			Funcname: "func" + fis,
+			Srcfile:  "foo" + fis + ".go",
+			Units: []coverage.CoverableUnit{
+				coverage.CoverableUnit{StLine: ln + 1, StCol: 2, EnLine: ln + 3, EnCol: 4, NxStmts: fi + 2},
+			},
+			Lit: (fi % 2) == 0,
+		}
+		wantfds = append(wantfds, fd)
+		b.AddFunc(fd)
+	}
+
+	// Emit into a writer.
+	drws := &slicewriter.WriteSeeker{}
+	b.Emit(drws)
+
+	// Decode the result.
+	drws.Seek(0, io.SeekStart)
+	dec, err := decodemeta.NewCoverageMetaDataDecoder(drws.BytesWritten(), false)
+	if err != nil {
+		t.Fatalf("making decoder: %v", err)
+	}
+	nf := dec.NumFuncs()
+	if nf != NF {
+		t.Fatalf("decoder number of functions: got %d want %d", nf, NF)
+	}
+	var fn coverage.FuncDesc
+	for i := uint32(0); i < uint32(NF); i++ {
+		if err := dec.ReadFunc(i, &fn); err != nil {
+			t.Fatalf("err reading function %d: %v", i, err)
+		}
+		res := cmpFuncDesc(wantfds[i], fn)
+		if res != "" {
+			t.Errorf("ReadFunc(%d): %s", i, res)
+		}
+	}
+}
diff --git a/src/internal/coverage/uleb128/uleb128.go b/src/internal/coverage/uleb128/uleb128.go
new file mode 100644
index 0000000..e5cd92a
--- /dev/null
+++ b/src/internal/coverage/uleb128/uleb128.go
@@ -0,0 +1,20 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package uleb128
+
+func AppendUleb128(b []byte, v uint) []byte {
+	for {
+		c := uint8(v & 0x7f)
+		v >>= 7
+		if v != 0 {
+			c |= 0x80
+		}
+		b = append(b, c)
+		if c&0x80 == 0 {
+			break
+		}
+	}
+	return b
+}
diff --git a/src/internal/cpu/cpu.go b/src/internal/cpu/cpu.go
index ae23b59..aef9fb3 100644
--- a/src/internal/cpu/cpu.go
+++ b/src/internal/cpu/cpu.go
@@ -37,6 +37,7 @@
 	HasPCLMULQDQ bool
 	HasPOPCNT    bool
 	HasRDTSCP    bool
+	HasSHA       bool
 	HasSSE3      bool
 	HasSSSE3     bool
 	HasSSE41     bool
@@ -61,11 +62,12 @@
 	HasPMULL     bool
 	HasSHA1      bool
 	HasSHA2      bool
+	HasSHA512    bool
 	HasCRC32     bool
 	HasATOMICS   bool
 	HasCPUID     bool
 	IsNeoverseN1 bool
-	IsZeus       bool
+	IsNeoverseV1 bool
 	_            CacheLinePad
 }
 
diff --git a/src/internal/cpu/cpu_arm64.go b/src/internal/cpu/cpu_arm64.go
index f64d9e4..85210aa 100644
--- a/src/internal/cpu/cpu_arm64.go
+++ b/src/internal/cpu/cpu_arm64.go
@@ -4,7 +4,10 @@
 
 package cpu
 
-const CacheLinePadSize = 64
+// CacheLinePadSize is used to prevent false sharing of cache lines.
+// We choose 128 because Apple Silicon, a.k.a. M1, has 128-byte cache line size.
+// It doesn't cost much and is much more future-proof.
+const CacheLinePadSize = 128
 
 func doinit() {
 	options = []option{
@@ -12,11 +15,12 @@
 		{Name: "pmull", Feature: &ARM64.HasPMULL},
 		{Name: "sha1", Feature: &ARM64.HasSHA1},
 		{Name: "sha2", Feature: &ARM64.HasSHA2},
+		{Name: "sha512", Feature: &ARM64.HasSHA512},
 		{Name: "crc32", Feature: &ARM64.HasCRC32},
 		{Name: "atomics", Feature: &ARM64.HasATOMICS},
 		{Name: "cpuid", Feature: &ARM64.HasCPUID},
 		{Name: "isNeoverseN1", Feature: &ARM64.IsNeoverseN1},
-		{Name: "isZeus", Feature: &ARM64.IsZeus},
+		{Name: "isNeoverseV1", Feature: &ARM64.IsNeoverseV1},
 	}
 
 	// arm64 uses different ways to detect CPU features at runtime depending on the operating system.
@@ -26,3 +30,41 @@
 func getisar0() uint64
 
 func getMIDR() uint64
+
+func extractBits(data uint64, start, end uint) uint {
+	return (uint)(data>>start) & ((1 << (end - start + 1)) - 1)
+}
+
+func parseARM64SystemRegisters(isar0 uint64) {
+	// ID_AA64ISAR0_EL1
+	switch extractBits(isar0, 4, 7) {
+	case 1:
+		ARM64.HasAES = true
+	case 2:
+		ARM64.HasAES = true
+		ARM64.HasPMULL = true
+	}
+
+	switch extractBits(isar0, 8, 11) {
+	case 1:
+		ARM64.HasSHA1 = true
+	}
+
+	switch extractBits(isar0, 12, 15) {
+	case 1:
+		ARM64.HasSHA2 = true
+	case 2:
+		ARM64.HasSHA2 = true
+		ARM64.HasSHA512 = true
+	}
+
+	switch extractBits(isar0, 16, 19) {
+	case 1:
+		ARM64.HasCRC32 = true
+	}
+
+	switch extractBits(isar0, 20, 23) {
+	case 2:
+		ARM64.HasATOMICS = true
+	}
+}
diff --git a/src/internal/cpu/cpu_arm64_darwin.go b/src/internal/cpu/cpu_arm64_darwin.go
index 730e14c..60beadd 100644
--- a/src/internal/cpu/cpu_arm64_darwin.go
+++ b/src/internal/cpu/cpu_arm64_darwin.go
@@ -9,6 +9,7 @@
 func osInit() {
 	ARM64.HasATOMICS = sysctlEnabled([]byte("hw.optional.armv8_1_atomics\x00"))
 	ARM64.HasCRC32 = sysctlEnabled([]byte("hw.optional.armv8_crc32\x00"))
+	ARM64.HasSHA512 = sysctlEnabled([]byte("hw.optional.armv8_2_sha512\x00"))
 
 	// There are no hw.optional sysctl values for the below features on Mac OS 11.0
 	// to detect their supported state dynamically. Assume the CPU features that
diff --git a/src/internal/cpu/cpu_arm64_freebsd.go b/src/internal/cpu/cpu_arm64_freebsd.go
index c25e021..96ed359 100644
--- a/src/internal/cpu/cpu_arm64_freebsd.go
+++ b/src/internal/cpu/cpu_arm64_freebsd.go
@@ -10,36 +10,5 @@
 	// Retrieve info from system register ID_AA64ISAR0_EL1.
 	isar0 := getisar0()
 
-	// ID_AA64ISAR0_EL1
-	switch extractBits(isar0, 4, 7) {
-	case 1:
-		ARM64.HasAES = true
-	case 2:
-		ARM64.HasAES = true
-		ARM64.HasPMULL = true
-	}
-
-	switch extractBits(isar0, 8, 11) {
-	case 1:
-		ARM64.HasSHA1 = true
-	}
-
-	switch extractBits(isar0, 12, 15) {
-	case 1, 2:
-		ARM64.HasSHA2 = true
-	}
-
-	switch extractBits(isar0, 16, 19) {
-	case 1:
-		ARM64.HasCRC32 = true
-	}
-
-	switch extractBits(isar0, 20, 23) {
-	case 2:
-		ARM64.HasATOMICS = true
-	}
-}
-
-func extractBits(data uint64, start, end uint) uint {
-	return (uint)(data>>start) & ((1 << (end - start + 1)) - 1)
+	parseARM64SystemRegisters(isar0)
 }
diff --git a/src/internal/cpu/cpu_arm64_hwcap.go b/src/internal/cpu/cpu_arm64_hwcap.go
index 0baa39f..0fb5fb5 100644
--- a/src/internal/cpu/cpu_arm64_hwcap.go
+++ b/src/internal/cpu/cpu_arm64_hwcap.go
@@ -52,7 +52,7 @@
 			ARM64.IsNeoverseN1 = true
 		}
 		if implementor == 'A' && part_num == 0xd40 {
-			ARM64.IsZeus = true
+			ARM64.IsNeoverseV1 = true
 		}
 	}
 }
diff --git a/src/internal/cpu/cpu_arm64_openbsd.go b/src/internal/cpu/cpu_arm64_openbsd.go
new file mode 100644
index 0000000..1259309
--- /dev/null
+++ b/src/internal/cpu/cpu_arm64_openbsd.go
@@ -0,0 +1,28 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build arm64
+
+package cpu
+
+const (
+	// From OpenBSD's sys/sysctl.h.
+	_CTL_MACHDEP = 7
+
+	// From OpenBSD's machine/cpu.h.
+	_CPU_ID_AA64ISAR0 = 2
+	_CPU_ID_AA64ISAR1 = 3
+)
+
+//go:noescape
+func sysctlUint64(mib []uint32) (uint64, bool)
+
+func osInit() {
+	// Get ID_AA64ISAR0 from sysctl.
+	isar0, ok := sysctlUint64([]uint32{_CTL_MACHDEP, _CPU_ID_AA64ISAR0})
+	if !ok {
+		return
+	}
+	parseARM64SystemRegisters(isar0)
+}
diff --git a/src/internal/cpu/cpu_arm64_other.go b/src/internal/cpu/cpu_arm64_other.go
index d313648..44592cf 100644
--- a/src/internal/cpu/cpu_arm64_other.go
+++ b/src/internal/cpu/cpu_arm64_other.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build arm64 && !linux && !freebsd && !android && (!darwin || ios)
+//go:build arm64 && !linux && !freebsd && !android && (!darwin || ios) && !openbsd
 
 package cpu
 
diff --git a/src/internal/cpu/cpu_test.go b/src/internal/cpu/cpu_test.go
index c95cd51..5aa277f 100644
--- a/src/internal/cpu/cpu_test.go
+++ b/src/internal/cpu/cpu_test.go
@@ -48,7 +48,7 @@
 func TestAllCapabilitiesDisabled(t *testing.T) {
 	MustHaveDebugOptionsSupport(t)
 
-	if godebug.Get("cpu.all") != "off" {
+	if godebug.New("cpu.all").Value() != "off" {
 		t.Skipf("skipping test: GODEBUG=cpu.all=off not set")
 	}
 
diff --git a/src/internal/cpu/cpu_x86.go b/src/internal/cpu/cpu_x86.go
index 6fd979a..96b8ef9 100644
--- a/src/internal/cpu/cpu_x86.go
+++ b/src/internal/cpu/cpu_x86.go
@@ -39,6 +39,7 @@
 	cpuid_BMI2 = 1 << 8
 	cpuid_ERMS = 1 << 9
 	cpuid_ADX  = 1 << 19
+	cpuid_SHA  = 1 << 29
 
 	// edx bits for CPUID 0x80000001
 	cpuid_RDTSCP = 1 << 27
@@ -53,6 +54,7 @@
 		{Name: "erms", Feature: &X86.HasERMS},
 		{Name: "pclmulqdq", Feature: &X86.HasPCLMULQDQ},
 		{Name: "rdtscp", Feature: &X86.HasRDTSCP},
+		{Name: "sha", Feature: &X86.HasSHA},
 	}
 	level := getGOAMD64level()
 	if level < 2 {
@@ -125,6 +127,7 @@
 	X86.HasBMI2 = isSet(ebx7, cpuid_BMI2)
 	X86.HasERMS = isSet(ebx7, cpuid_ERMS)
 	X86.HasADX = isSet(ebx7, cpuid_ADX)
+	X86.HasSHA = isSet(ebx7, cpuid_SHA)
 
 	var maxExtendedInformation uint32
 	maxExtendedInformation, _, _, _ = cpuid(0x80000000, 0)
diff --git a/src/internal/cpu/cpu_x86_test.go b/src/internal/cpu/cpu_x86_test.go
index 43d6b21..d7be430 100644
--- a/src/internal/cpu/cpu_x86_test.go
+++ b/src/internal/cpu/cpu_x86_test.go
@@ -28,7 +28,7 @@
 func TestSSE3DebugOption(t *testing.T) {
 	MustHaveDebugOptionsSupport(t)
 
-	if godebug.Get("cpu.sse3") != "off" {
+	if godebug.New("cpu.sse3").Value() != "off" {
 		t.Skipf("skipping test: GODEBUG=cpu.sse3=off not set")
 	}
 
diff --git a/src/internal/dag/alg.go b/src/internal/dag/alg.go
new file mode 100644
index 0000000..8800279
--- /dev/null
+++ b/src/internal/dag/alg.go
@@ -0,0 +1,63 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package dag
+
+// Transpose reverses all edges in g.
+func (g *Graph) Transpose() {
+	old := g.edges
+
+	g.edges = make(map[string]map[string]bool)
+	for _, n := range g.Nodes {
+		g.edges[n] = make(map[string]bool)
+	}
+
+	for from, tos := range old {
+		for to := range tos {
+			g.edges[to][from] = true
+		}
+	}
+}
+
+// Topo returns a topological sort of g. This function is deterministic.
+func (g *Graph) Topo() []string {
+	topo := make([]string, 0, len(g.Nodes))
+	marks := make(map[string]bool)
+
+	var visit func(n string)
+	visit = func(n string) {
+		if marks[n] {
+			return
+		}
+		for _, to := range g.Edges(n) {
+			visit(to)
+		}
+		marks[n] = true
+		topo = append(topo, n)
+	}
+	for _, root := range g.Nodes {
+		visit(root)
+	}
+	for i, j := 0, len(topo)-1; i < j; i, j = i+1, j-1 {
+		topo[i], topo[j] = topo[j], topo[i]
+	}
+	return topo
+}
+
+// TransitiveReduction removes edges from g that are transitively
+// reachable. g must be transitively closed.
+func (g *Graph) TransitiveReduction() {
+	// For i -> j -> k, if i -> k exists, delete it.
+	for _, i := range g.Nodes {
+		for _, j := range g.Nodes {
+			if g.HasEdge(i, j) {
+				for _, k := range g.Nodes {
+					if g.HasEdge(j, k) {
+						g.DelEdge(i, k)
+					}
+				}
+			}
+		}
+	}
+}
diff --git a/src/internal/dag/alg_test.go b/src/internal/dag/alg_test.go
new file mode 100644
index 0000000..e5ea8b6
--- /dev/null
+++ b/src/internal/dag/alg_test.go
@@ -0,0 +1,46 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package dag
+
+import (
+	"reflect"
+	"strings"
+	"testing"
+)
+
+func TestTranspose(t *testing.T) {
+	g := mustParse(t, diamond)
+	g.Transpose()
+	wantEdges(t, g, "a->b a->c a->d b->d c->d")
+}
+
+func TestTopo(t *testing.T) {
+	g := mustParse(t, diamond)
+	got := g.Topo()
+	// "d" is the root, so it's first.
+	//
+	// "c" and "b" could be in either order, but Topo is
+	// deterministic in reverse node definition order.
+	//
+	// "a" is a leaf.
+	wantNodes := strings.Fields("d c b a")
+	if !reflect.DeepEqual(wantNodes, got) {
+		t.Fatalf("want topo sort %v, got %v", wantNodes, got)
+	}
+}
+
+func TestTransitiveReduction(t *testing.T) {
+	t.Run("diamond", func(t *testing.T) {
+		g := mustParse(t, diamond)
+		g.TransitiveReduction()
+		wantEdges(t, g, "b->a c->a d->b d->c")
+	})
+	t.Run("chain", func(t *testing.T) {
+		const chain = `NONE < a < b < c < d; a, d < e;`
+		g := mustParse(t, chain)
+		g.TransitiveReduction()
+		wantEdges(t, g, "e->d d->c c->b b->a")
+	})
+}
diff --git a/src/internal/dag/parse.go b/src/internal/dag/parse.go
new file mode 100644
index 0000000..9d5b918
--- /dev/null
+++ b/src/internal/dag/parse.go
@@ -0,0 +1,314 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package dag implements a language for expressing directed acyclic
+// graphs.
+//
+// The general syntax of a rule is:
+//
+//	a, b < c, d;
+//
+// which means c and d come after a and b in the partial order
+// (that is, there are edges from c and d to a and b),
+// but doesn't provide a relative order between a vs b or c vs d.
+//
+// The rules can chain together, as in:
+//
+//	e < f, g < h;
+//
+// which is equivalent to
+//
+//	e < f, g;
+//	f, g < h;
+//
+// Except for the special bottom element "NONE", each name
+// must appear exactly once on the right-hand side of any rule.
+// That rule serves as the definition of the allowed successor
+// for that name. The definition must appear before any uses
+// of the name on the left-hand side of a rule. (That is, the
+// rules themselves must be ordered according to the partial
+// order, for easier reading by people.)
+//
+// Negative assertions double-check the partial order:
+//
+//	i !< j
+//
+// means that it must NOT be the case that i < j.
+// Negative assertions may appear anywhere in the rules,
+// even before i and j have been defined.
+//
+// Comments begin with #.
+package dag
+
+import (
+	"fmt"
+	"sort"
+	"strings"
+)
+
+type Graph struct {
+	Nodes   []string
+	byLabel map[string]int
+	edges   map[string]map[string]bool
+}
+
+func newGraph() *Graph {
+	return &Graph{byLabel: map[string]int{}, edges: map[string]map[string]bool{}}
+}
+
+func (g *Graph) addNode(label string) bool {
+	if _, ok := g.byLabel[label]; ok {
+		return false
+	}
+	g.byLabel[label] = len(g.Nodes)
+	g.Nodes = append(g.Nodes, label)
+	g.edges[label] = map[string]bool{}
+	return true
+}
+
+func (g *Graph) AddEdge(from, to string) {
+	g.edges[from][to] = true
+}
+
+func (g *Graph) DelEdge(from, to string) {
+	delete(g.edges[from], to)
+}
+
+func (g *Graph) HasEdge(from, to string) bool {
+	return g.edges[from] != nil && g.edges[from][to]
+}
+
+func (g *Graph) Edges(from string) []string {
+	edges := make([]string, 0, 16)
+	for k := range g.edges[from] {
+		edges = append(edges, k)
+	}
+	sort.Slice(edges, func(i, j int) bool { return g.byLabel[edges[i]] < g.byLabel[edges[j]] })
+	return edges
+}
+
+// Parse parses the DAG language and returns the transitive closure of
+// the described graph. In the returned graph, there is an edge from "b"
+// to "a" if b < a (or a > b) in the partial order.
+func Parse(dag string) (*Graph, error) {
+	g := newGraph()
+	disallowed := []rule{}
+
+	rules, err := parseRules(dag)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: Add line numbers to errors.
+	var errors []string
+	errorf := func(format string, a ...any) {
+		errors = append(errors, fmt.Sprintf(format, a...))
+	}
+	for _, r := range rules {
+		if r.op == "!<" {
+			disallowed = append(disallowed, r)
+			continue
+		}
+		for _, def := range r.def {
+			if def == "NONE" {
+				errorf("NONE cannot be a predecessor")
+				continue
+			}
+			if !g.addNode(def) {
+				errorf("multiple definitions for %s", def)
+			}
+			for _, less := range r.less {
+				if less == "NONE" {
+					continue
+				}
+				if _, ok := g.byLabel[less]; !ok {
+					errorf("use of %s before its definition", less)
+				} else {
+					g.AddEdge(def, less)
+				}
+			}
+		}
+	}
+
+	// Check for missing definition.
+	for _, tos := range g.edges {
+		for to := range tos {
+			if g.edges[to] == nil {
+				errorf("missing definition for %s", to)
+			}
+		}
+	}
+
+	// Complete transitive closure.
+	for _, k := range g.Nodes {
+		for _, i := range g.Nodes {
+			for _, j := range g.Nodes {
+				if i != k && k != j && g.HasEdge(i, k) && g.HasEdge(k, j) {
+					if i == j {
+						// Can only happen along with a "use of X before deps" error above,
+						// but this error is more specific - it makes clear that reordering the
+						// rules will not be enough to fix the problem.
+						errorf("graph cycle: %s < %s < %s", j, k, i)
+					}
+					g.AddEdge(i, j)
+				}
+			}
+		}
+	}
+
+	// Check negative assertions against completed allowed graph.
+	for _, bad := range disallowed {
+		for _, less := range bad.less {
+			for _, def := range bad.def {
+				if g.HasEdge(def, less) {
+					errorf("graph edge assertion failed: %s !< %s", less, def)
+				}
+			}
+		}
+	}
+
+	if len(errors) > 0 {
+		return nil, fmt.Errorf("%s", strings.Join(errors, "\n"))
+	}
+
+	return g, nil
+}
+
+// A rule is a line in the DAG language where "less < def" or "less !< def".
+type rule struct {
+	less []string
+	op   string // Either "<" or "!<"
+	def  []string
+}
+
+type syntaxError string
+
+func (e syntaxError) Error() string {
+	return string(e)
+}
+
+// parseRules parses the rules of a DAG.
+func parseRules(rules string) (out []rule, err error) {
+	defer func() {
+		e := recover()
+		switch e := e.(type) {
+		case nil:
+			return
+		case syntaxError:
+			err = e
+		default:
+			panic(e)
+		}
+	}()
+	p := &rulesParser{lineno: 1, text: rules}
+
+	var prev []string
+	var op string
+	for {
+		list, tok := p.nextList()
+		if tok == "" {
+			if prev == nil {
+				break
+			}
+			p.syntaxError("unexpected EOF")
+		}
+		if prev != nil {
+			out = append(out, rule{prev, op, list})
+		}
+		prev = list
+		if tok == ";" {
+			prev = nil
+			op = ""
+			continue
+		}
+		if tok != "<" && tok != "!<" {
+			p.syntaxError("missing <")
+		}
+		op = tok
+	}
+
+	return out, err
+}
+
+// A rulesParser parses the depsRules syntax described above.
+type rulesParser struct {
+	lineno   int
+	lastWord string
+	text     string
+}
+
+// syntaxError reports a parsing error.
+func (p *rulesParser) syntaxError(msg string) {
+	panic(syntaxError(fmt.Sprintf("parsing graph: line %d: syntax error: %s near %s", p.lineno, msg, p.lastWord)))
+}
+
+// nextList parses and returns a comma-separated list of names.
+func (p *rulesParser) nextList() (list []string, token string) {
+	for {
+		tok := p.nextToken()
+		switch tok {
+		case "":
+			if len(list) == 0 {
+				return nil, ""
+			}
+			fallthrough
+		case ",", "<", "!<", ";":
+			p.syntaxError("bad list syntax")
+		}
+		list = append(list, tok)
+
+		tok = p.nextToken()
+		if tok != "," {
+			return list, tok
+		}
+	}
+}
+
+// nextToken returns the next token in the deps rules,
+// one of ";" "," "<" "!<" or a name.
+func (p *rulesParser) nextToken() string {
+	for {
+		if p.text == "" {
+			return ""
+		}
+		switch p.text[0] {
+		case ';', ',', '<':
+			t := p.text[:1]
+			p.text = p.text[1:]
+			return t
+
+		case '!':
+			if len(p.text) < 2 || p.text[1] != '<' {
+				p.syntaxError("unexpected token !")
+			}
+			p.text = p.text[2:]
+			return "!<"
+
+		case '#':
+			i := strings.Index(p.text, "\n")
+			if i < 0 {
+				i = len(p.text)
+			}
+			p.text = p.text[i:]
+			continue
+
+		case '\n':
+			p.lineno++
+			fallthrough
+		case ' ', '\t':
+			p.text = p.text[1:]
+			continue
+
+		default:
+			i := strings.IndexAny(p.text, "!;,<#\n \t")
+			if i < 0 {
+				i = len(p.text)
+			}
+			t := p.text[:i]
+			p.text = p.text[i:]
+			p.lastWord = t
+			return t
+		}
+	}
+}
diff --git a/src/internal/dag/parse_test.go b/src/internal/dag/parse_test.go
new file mode 100644
index 0000000..b2520c3
--- /dev/null
+++ b/src/internal/dag/parse_test.go
@@ -0,0 +1,61 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package dag
+
+import (
+	"reflect"
+	"strings"
+	"testing"
+)
+
+const diamond = `
+NONE < a < b, c < d;
+`
+
+func mustParse(t *testing.T, dag string) *Graph {
+	t.Helper()
+	g, err := Parse(dag)
+	if err != nil {
+		t.Fatal(err)
+	}
+	return g
+}
+
+func wantEdges(t *testing.T, g *Graph, edges string) {
+	t.Helper()
+
+	wantEdges := strings.Fields(edges)
+	wantEdgeMap := make(map[string]bool)
+	for _, e := range wantEdges {
+		wantEdgeMap[e] = true
+	}
+
+	for _, n1 := range g.Nodes {
+		for _, n2 := range g.Nodes {
+			got := g.HasEdge(n1, n2)
+			want := wantEdgeMap[n1+"->"+n2]
+			if got && want {
+				t.Logf("%s->%s", n1, n2)
+			} else if got && !want {
+				t.Errorf("%s->%s present but not expected", n1, n2)
+			} else if want && !got {
+				t.Errorf("%s->%s missing but expected", n1, n2)
+			}
+		}
+	}
+}
+
+func TestParse(t *testing.T) {
+	// Basic smoke test for graph parsing.
+	g := mustParse(t, diamond)
+
+	wantNodes := strings.Fields("a b c d")
+	if !reflect.DeepEqual(wantNodes, g.Nodes) {
+		t.Fatalf("want nodes %v, got %v", wantNodes, g.Nodes)
+	}
+
+	// Parse returns the transitive closure, so it adds d->a.
+	wantEdges(t, g, "b->a c->a d->a d->b d->c")
+}
diff --git a/src/internal/fmtsort/sort_test.go b/src/internal/fmtsort/sort_test.go
index 11befca..cddcf70 100644
--- a/src/internal/fmtsort/sort_test.go
+++ b/src/internal/fmtsort/sort_test.go
@@ -147,7 +147,7 @@
 		}
 		b.WriteString(sprintKey(key))
 		b.WriteRune(':')
-		b.WriteString(fmt.Sprint(om.Value[i]))
+		fmt.Fprint(b, om.Value[i])
 	}
 	return b.String()
 }
diff --git a/src/internal/fuzz/counters_supported.go b/src/internal/fuzz/counters_supported.go
index 7ef553a..79e27d2 100644
--- a/src/internal/fuzz/counters_supported.go
+++ b/src/internal/fuzz/counters_supported.go
@@ -7,7 +7,6 @@
 package fuzz
 
 import (
-	"internal/unsafeheader"
 	"unsafe"
 )
 
@@ -18,12 +17,5 @@
 func coverage() []byte {
 	addr := unsafe.Pointer(&_counters)
 	size := uintptr(unsafe.Pointer(&_ecounters)) - uintptr(addr)
-
-	var res []byte
-	*(*unsafeheader.Slice)(unsafe.Pointer(&res)) = unsafeheader.Slice{
-		Data: addr,
-		Len:  int(size),
-		Cap:  int(size),
-	}
-	return res
+	return unsafe.Slice((*byte)(addr), int(size))
 }
diff --git a/src/internal/fuzz/counters_unsupported.go b/src/internal/fuzz/counters_unsupported.go
index bf28157..028065c 100644
--- a/src/internal/fuzz/counters_unsupported.go
+++ b/src/internal/fuzz/counters_unsupported.go
@@ -6,7 +6,7 @@
 // the instrumentation is OS specific, but only amd64 and arm64 are
 // supported in the runtime. See src/runtime/libfuzzer*.
 //
-// If you update this constraint, also update cmd/internal/sys.FuzzInstrumeted.
+// If you update this constraint, also update internal/platform.FuzzInstrumeted.
 //
 //go:build !((darwin || linux || windows || freebsd) && (amd64 || arm64))
 
diff --git a/src/internal/fuzz/coverage.go b/src/internal/fuzz/coverage.go
index 88f98a1..0c5e17e 100644
--- a/src/internal/fuzz/coverage.go
+++ b/src/internal/fuzz/coverage.go
@@ -9,7 +9,7 @@
 	"math/bits"
 )
 
-// ResetCovereage sets all of the counters for each edge of the instrumented
+// ResetCoverage sets all of the counters for each edge of the instrumented
 // source code to 0.
 func ResetCoverage() {
 	cov := coverage()
@@ -67,7 +67,7 @@
 }
 
 // isCoverageSubset returns true if all the base coverage bits are set in
-// snapshot
+// snapshot.
 func isCoverageSubset(base, snapshot []byte) bool {
 	for i, v := range base {
 		if v&snapshot[i] != v {
diff --git a/src/internal/fuzz/encoding.go b/src/internal/fuzz/encoding.go
index c2eed70..270ef7a 100644
--- a/src/internal/fuzz/encoding.go
+++ b/src/internal/fuzz/encoding.go
@@ -338,7 +338,7 @@
 	}
 }
 
-// parseInt returns an unsigned integer of value val and type typ.
+// parseUint returns an unsigned integer of value val and type typ.
 func parseUint(val, typ string) (any, error) {
 	switch typ {
 	case "uint":
diff --git a/src/internal/fuzz/fuzz.go b/src/internal/fuzz/fuzz.go
index 3ccf747..7d4fe06 100644
--- a/src/internal/fuzz/fuzz.go
+++ b/src/internal/fuzz/fuzz.go
@@ -8,20 +8,19 @@
 package fuzz
 
 import (
+	"bytes"
 	"context"
 	"crypto/sha256"
 	"errors"
 	"fmt"
 	"internal/godebug"
 	"io"
-	"io/ioutil"
 	"math/bits"
 	"os"
 	"path/filepath"
 	"reflect"
 	"runtime"
 	"strings"
-	"sync"
 	"time"
 )
 
@@ -776,8 +775,7 @@
 		warmup:  c.warmupRun(),
 	}
 	if c.coverageMask != nil {
-		input.coverageData = make([]byte, len(c.coverageMask))
-		copy(input.coverageData, c.coverageMask)
+		input.coverageData = bytes.Clone(c.coverageMask)
 	}
 	if input.warmup {
 		// No fuzzing will occur, but it should count toward the limit set by
@@ -963,7 +961,7 @@
 // be saved in a MalformedCorpusError and returned, along with the most recent
 // error.
 func ReadCorpus(dir string, types []reflect.Type) ([]CorpusEntry, error) {
-	files, err := ioutil.ReadDir(dir)
+	files, err := os.ReadDir(dir)
 	if os.IsNotExist(err) {
 		return nil, nil // No corpus to read
 	} else if err != nil {
@@ -981,7 +979,7 @@
 			continue
 		}
 		filename := filepath.Join(dir, file.Name())
-		data, err := ioutil.ReadFile(filename)
+		data, err := os.ReadFile(filename)
 		if err != nil {
 			return nil, fmt.Errorf("failed to read corpus file: %v", err)
 		}
@@ -1033,12 +1031,12 @@
 // writeToCorpus will not rewrite it. writeToCorpus sets entry.Path to the new
 // file that was just written or an error if it failed.
 func writeToCorpus(entry *CorpusEntry, dir string) (err error) {
-	sum := fmt.Sprintf("%x", sha256.Sum256(entry.Data))
+	sum := fmt.Sprintf("%x", sha256.Sum256(entry.Data))[:16]
 	entry.Path = filepath.Join(dir, sum)
 	if err := os.MkdirAll(dir, 0777); err != nil {
 		return err
 	}
-	if err := ioutil.WriteFile(entry.Path, entry.Data, 0666); err != nil {
+	if err := os.WriteFile(entry.Path, entry.Data, 0666); err != nil {
 		os.Remove(entry.Path) // remove partially written file
 		return err
 	}
@@ -1078,14 +1076,8 @@
 	uint64(0),
 }
 
-var (
-	debugInfo     bool
-	debugInfoOnce sync.Once
-)
+var debugInfo = godebug.New("fuzzdebug").Value() == "1"
 
 func shouldPrintDebugInfo() bool {
-	debugInfoOnce.Do(func() {
-		debugInfo = godebug.Get("fuzzdebug") == "1"
-	})
 	return debugInfo
 }
diff --git a/src/internal/fuzz/mem.go b/src/internal/fuzz/mem.go
index a5c3b02..4155e4e 100644
--- a/src/internal/fuzz/mem.go
+++ b/src/internal/fuzz/mem.go
@@ -5,8 +5,8 @@
 package fuzz
 
 import (
+	"bytes"
 	"fmt"
-	"io/ioutil"
 	"os"
 	"unsafe"
 )
@@ -65,7 +65,7 @@
 // it into memory. The file will be removed when the Close method is called.
 func sharedMemTempFile(size int) (m *sharedMem, err error) {
 	// Create a temporary file.
-	f, err := ioutil.TempFile("", "fuzz-*")
+	f, err := os.CreateTemp("", "fuzz-*")
 	if err != nil {
 		return nil, err
 	}
@@ -103,9 +103,7 @@
 // valueCopy returns a copy of the value stored in shared memory.
 func (m *sharedMem) valueCopy() []byte {
 	ref := m.valueRef()
-	b := make([]byte, len(ref))
-	copy(b, ref)
-	return b
+	return bytes.Clone(ref)
 }
 
 // setValue copies the data in b into the shared memory buffer and sets
diff --git a/src/internal/fuzz/mutator.go b/src/internal/fuzz/mutator.go
index e26ae5a..bb96066 100644
--- a/src/internal/fuzz/mutator.go
+++ b/src/internal/fuzz/mutator.go
@@ -8,7 +8,6 @@
 	"encoding/binary"
 	"fmt"
 	"math"
-	"reflect"
 	"unsafe"
 )
 
@@ -265,9 +264,7 @@
 func (m *mutator) mutateBytes(ptrB *[]byte) {
 	b := *ptrB
 	defer func() {
-		oldHdr := (*reflect.SliceHeader)(unsafe.Pointer(ptrB))
-		newHdr := (*reflect.SliceHeader)(unsafe.Pointer(&b))
-		if oldHdr.Data != newHdr.Data {
+		if unsafe.SliceData(*ptrB) != unsafe.SliceData(b) {
 			panic("data moved to new address")
 		}
 		*ptrB = b
diff --git a/src/internal/fuzz/queue.go b/src/internal/fuzz/queue.go
index 42a8379..195d6eb 100644
--- a/src/internal/fuzz/queue.go
+++ b/src/internal/fuzz/queue.go
@@ -9,7 +9,7 @@
 // For now, this is a simple ring buffer
 // (https://en.wikipedia.org/wiki/Circular_buffer).
 //
-// TODO(golang.org/issue/46224): use a priotization algorithm based on input
+// TODO(golang.org/issue/46224): use a prioritization algorithm based on input
 // size, previous duration, coverage, and any other metrics that seem useful.
 type queue struct {
 	// elems holds a ring buffer.
diff --git a/src/internal/fuzz/sys_unimplemented.go b/src/internal/fuzz/sys_unimplemented.go
index f84dae6..8687c1f 100644
--- a/src/internal/fuzz/sys_unimplemented.go
+++ b/src/internal/fuzz/sys_unimplemented.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// If you update this constraint, also update cmd/internal/sys.FuzzSupported.
+// If you update this constraint, also update internal/platform.FuzzSupported.
 //
 //go:build !darwin && !freebsd && !linux && !windows
 
diff --git a/src/internal/fuzz/sys_windows.go b/src/internal/fuzz/sys_windows.go
index 9c006b0..aa85be7 100644
--- a/src/internal/fuzz/sys_windows.go
+++ b/src/internal/fuzz/sys_windows.go
@@ -8,7 +8,6 @@
 	"fmt"
 	"os"
 	"os/exec"
-	"reflect"
 	"syscall"
 	"unsafe"
 )
@@ -51,11 +50,7 @@
 		return nil, err
 	}
 
-	var region []byte
-	header := (*reflect.SliceHeader)(unsafe.Pointer(&region))
-	header.Data = addr
-	header.Len = size
-	header.Cap = size
+	region := unsafe.Slice((*byte)(unsafe.Pointer(addr)), size)
 	return &sharedMem{
 		f:             f,
 		region:        region,
diff --git a/src/internal/fuzz/trace.go b/src/internal/fuzz/trace.go
index 5e3cccc..a15c370 100644
--- a/src/internal/fuzz/trace.go
+++ b/src/internal/fuzz/trace.go
@@ -21,15 +21,15 @@
 //go:linkname libfuzzerHookStrCmp runtime.libfuzzerHookStrCmp
 //go:linkname libfuzzerHookEqualFold runtime.libfuzzerHookEqualFold
 
-func libfuzzerTraceCmp1(arg0, arg1 uint8, fakePC int)  {}
-func libfuzzerTraceCmp2(arg0, arg1 uint16, fakePC int) {}
-func libfuzzerTraceCmp4(arg0, arg1 uint32, fakePC int) {}
-func libfuzzerTraceCmp8(arg0, arg1 uint64, fakePC int) {}
+func libfuzzerTraceCmp1(arg0, arg1 uint8, fakePC uint)  {}
+func libfuzzerTraceCmp2(arg0, arg1 uint16, fakePC uint) {}
+func libfuzzerTraceCmp4(arg0, arg1 uint32, fakePC uint) {}
+func libfuzzerTraceCmp8(arg0, arg1 uint64, fakePC uint) {}
 
-func libfuzzerTraceConstCmp1(arg0, arg1 uint8, fakePC int)  {}
-func libfuzzerTraceConstCmp2(arg0, arg1 uint16, fakePC int) {}
-func libfuzzerTraceConstCmp4(arg0, arg1 uint32, fakePC int) {}
-func libfuzzerTraceConstCmp8(arg0, arg1 uint64, fakePC int) {}
+func libfuzzerTraceConstCmp1(arg0, arg1 uint8, fakePC uint)  {}
+func libfuzzerTraceConstCmp2(arg0, arg1 uint16, fakePC uint) {}
+func libfuzzerTraceConstCmp4(arg0, arg1 uint32, fakePC uint) {}
+func libfuzzerTraceConstCmp8(arg0, arg1 uint64, fakePC uint) {}
 
-func libfuzzerHookStrCmp(arg0, arg1 string, fakePC int)    {}
-func libfuzzerHookEqualFold(arg0, arg1 string, fakePC int) {}
+func libfuzzerHookStrCmp(arg0, arg1 string, fakePC uint)    {}
+func libfuzzerHookEqualFold(arg0, arg1 string, fakePC uint) {}
diff --git a/src/internal/fuzz/worker.go b/src/internal/fuzz/worker.go
index 6e4c4e2..467c39b 100644
--- a/src/internal/fuzz/worker.go
+++ b/src/internal/fuzz/worker.go
@@ -12,7 +12,6 @@
 	"errors"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"os"
 	"os/exec"
 	"reflect"
@@ -793,7 +792,7 @@
 
 func (ws *workerServer) minimize(ctx context.Context, args minimizeArgs) (resp minimizeResponse) {
 	start := time.Now()
-	defer func() { resp.Duration = time.Now().Sub(start) }()
+	defer func() { resp.Duration = time.Since(start) }()
 	mem := <-ws.memMu
 	defer func() { ws.memMu <- mem }()
 	vals, err := unmarshalCorpusFile(mem.valueCopy())
@@ -958,7 +957,7 @@
 
 	// Drain fuzzOut and close it. When the server exits, the kernel will close
 	// its end of fuzzOut, and we'll get EOF.
-	if _, err := io.Copy(ioutil.Discard, wc.fuzzOut); err != nil {
+	if _, err := io.Copy(io.Discard, wc.fuzzOut); err != nil {
 		wc.fuzzOut.Close()
 		return err
 	}
diff --git a/src/internal/godebug/godebug.go b/src/internal/godebug/godebug.go
index ac434e5..dbcd980 100644
--- a/src/internal/godebug/godebug.go
+++ b/src/internal/godebug/godebug.go
@@ -2,33 +2,163 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Package godebug parses the GODEBUG environment variable.
+// Package godebug makes the settings in the $GODEBUG environment variable
+// available to other packages. These settings are often used for compatibility
+// tweaks, when we need to change a default behavior but want to let users
+// opt back in to the original. For example GODEBUG=http2server=0 disables
+// HTTP/2 support in the net/http server.
+//
+// In typical usage, code should declare a Setting as a global
+// and then call Value each time the current setting value is needed:
+//
+//	var http2server = godebug.New("http2server")
+//
+//	func ServeConn(c net.Conn) {
+//		if http2server.Value() == "0" {
+//			disallow HTTP/2
+//			...
+//		}
+//		...
+//	}
 package godebug
 
-import "os"
+import (
+	"sync"
+	"sync/atomic"
+	_ "unsafe" // go:linkname
+)
 
-// Get returns the value for the provided GODEBUG key.
-func Get(key string) string {
-	return get(os.Getenv("GODEBUG"), key)
+// A Setting is a single setting in the $GODEBUG environment variable.
+type Setting struct {
+	name  string
+	once  sync.Once
+	value *atomic.Pointer[string]
 }
 
-// get returns the value part of key=value in s (a GODEBUG value).
-func get(s, key string) string {
-	for i := 0; i < len(s)-len(key)-1; i++ {
-		if i > 0 && s[i-1] != ',' {
-			continue
+// New returns a new Setting for the $GODEBUG setting with the given name.
+func New(name string) *Setting {
+	return &Setting{name: name}
+}
+
+// Name returns the name of the setting.
+func (s *Setting) Name() string {
+	return s.name
+}
+
+// String returns a printable form for the setting: name=value.
+func (s *Setting) String() string {
+	return s.name + "=" + s.Value()
+}
+
+// cache is a cache of all the GODEBUG settings,
+// a locked map[string]*atomic.Pointer[string].
+//
+// All Settings with the same name share a single
+// *atomic.Pointer[string], so that when GODEBUG
+// changes only that single atomic string pointer
+// needs to be updated.
+//
+// A name appears in the values map either if it is the
+// name of a Setting for which Value has been called
+// at least once, or if the name has ever appeared in
+// a name=value pair in the $GODEBUG environment variable.
+// Once entered into the map, the name is never removed.
+var cache sync.Map // name string -> value *atomic.Pointer[string]
+
+var empty string
+
+// Value returns the current value for the GODEBUG setting s.
+//
+// Value maintains an internal cache that is synchronized
+// with changes to the $GODEBUG environment variable,
+// making Value efficient to call as frequently as needed.
+// Clients should therefore typically not attempt their own
+// caching of Value's result.
+func (s *Setting) Value() string {
+	s.once.Do(func() {
+		v, ok := cache.Load(s.name)
+		if !ok {
+			p := new(atomic.Pointer[string])
+			p.Store(&empty)
+			v, _ = cache.LoadOrStore(s.name, p)
 		}
-		afterKey := s[i+len(key):]
-		if afterKey[0] != '=' || s[i:i+len(key)] != key {
-			continue
+		s.value = v.(*atomic.Pointer[string])
+	})
+	return *s.value.Load()
+}
+
+// setUpdate is provided by package runtime.
+// It calls update(def, env), where def is the default GODEBUG setting
+// and env is the current value of the $GODEBUG environment variable.
+// After that first call, the runtime calls update(def, env)
+// again each time the environment variable changes
+// (due to use of os.Setenv, for example).
+//
+//go:linkname setUpdate
+func setUpdate(update func(string, string))
+
+func init() {
+	setUpdate(update)
+}
+
+var updateMu sync.Mutex
+
+// update records an updated GODEBUG setting.
+// def is the default GODEBUG setting for the running binary,
+// and env is the current value of the $GODEBUG environment variable.
+func update(def, env string) {
+	updateMu.Lock()
+	defer updateMu.Unlock()
+
+	// Update all the cached values, creating new ones as needed.
+	// We parse the environment variable first, so that any settings it has
+	// are already locked in place (did[name] = true) before we consider
+	// the defaults.
+	did := make(map[string]bool)
+	parse(did, env)
+	parse(did, def)
+
+	// Clear any cached values that are no longer present.
+	cache.Range(func(name, v any) bool {
+		if !did[name.(string)] {
+			v.(*atomic.Pointer[string]).Store(&empty)
 		}
-		val := afterKey[1:]
-		for i, b := range val {
-			if b == ',' {
-				return val[:i]
+		return true
+	})
+}
+
+// parse parses the GODEBUG setting string s,
+// which has the form k=v,k2=v2,k3=v3.
+// Later settings override earlier ones.
+// Parse only updates settings k=v for which did[k] = false.
+// It also sets did[k] = true for settings that it updates.
+func parse(did map[string]bool, s string) {
+	// Scan the string backward so that later settings are used
+	// and earlier settings are ignored.
+	// Note that a forward scan would cause cached values
+	// to temporarily use the ignored value before being
+	// updated to the "correct" one.
+	end := len(s)
+	eq := -1
+	for i := end - 1; i >= -1; i-- {
+		if i == -1 || s[i] == ',' {
+			if eq >= 0 {
+				name, value := s[i+1:eq], s[eq+1:end]
+				if !did[name] {
+					did[name] = true
+					v, ok := cache.Load(name)
+					if !ok {
+						p := new(atomic.Pointer[string])
+						p.Store(&empty)
+						v, _ = cache.LoadOrStore(name, p)
+					}
+					v.(*atomic.Pointer[string]).Store(&value)
+				}
 			}
+			eq = -1
+			end = i
+		} else if s[i] == '=' {
+			eq = i
 		}
-		return val
 	}
-	return ""
 }
diff --git a/src/internal/godebug/godebug_test.go b/src/internal/godebug/godebug_test.go
index 41b9117..319229d 100644
--- a/src/internal/godebug/godebug_test.go
+++ b/src/internal/godebug/godebug_test.go
@@ -2,33 +2,38 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package godebug
+package godebug_test
 
-import "testing"
+import (
+	. "internal/godebug"
+	"testing"
+)
 
 func TestGet(t *testing.T) {
+	foo := New("foo")
 	tests := []struct {
 		godebug string
-		key     string
+		setting *Setting
 		want    string
 	}{
-		{"", "", ""},
-		{"", "foo", ""},
-		{"foo=bar", "foo", "bar"},
-		{"foo=bar,after=x", "foo", "bar"},
-		{"before=x,foo=bar,after=x", "foo", "bar"},
-		{"before=x,foo=bar", "foo", "bar"},
-		{",,,foo=bar,,,", "foo", "bar"},
-		{"foodecoy=wrong,foo=bar", "foo", "bar"},
-		{"foo=", "foo", ""},
-		{"foo", "foo", ""},
-		{",foo", "foo", ""},
-		{"foo=bar,baz", "loooooooong", ""},
+		{"", New(""), ""},
+		{"", foo, ""},
+		{"foo=bar", foo, "bar"},
+		{"foo=bar,after=x", foo, "bar"},
+		{"before=x,foo=bar,after=x", foo, "bar"},
+		{"before=x,foo=bar", foo, "bar"},
+		{",,,foo=bar,,,", foo, "bar"},
+		{"foodecoy=wrong,foo=bar", foo, "bar"},
+		{"foo=", foo, ""},
+		{"foo", foo, ""},
+		{",foo", foo, ""},
+		{"foo=bar,baz", New("loooooooong"), ""},
 	}
 	for _, tt := range tests {
-		got := get(tt.godebug, tt.key)
+		t.Setenv("GODEBUG", tt.godebug)
+		got := tt.setting.Value()
 		if got != tt.want {
-			t.Errorf("get(%q, %q) = %q; want %q", tt.godebug, tt.key, got, tt.want)
+			t.Errorf("get(%q, %q) = %q; want %q", tt.godebug, tt.setting.Name(), got, tt.want)
 		}
 	}
 }
diff --git a/src/internal/goexperiment/exp_arenas_off.go b/src/internal/goexperiment/exp_arenas_off.go
new file mode 100644
index 0000000..9e40ebc
--- /dev/null
+++ b/src/internal/goexperiment/exp_arenas_off.go
@@ -0,0 +1,9 @@
+// Code generated by mkconsts.go. DO NOT EDIT.
+
+//go:build !goexperiment.arenas
+// +build !goexperiment.arenas
+
+package goexperiment
+
+const Arenas = false
+const ArenasInt = 0
diff --git a/src/internal/goexperiment/exp_arenas_on.go b/src/internal/goexperiment/exp_arenas_on.go
new file mode 100644
index 0000000..92ef748
--- /dev/null
+++ b/src/internal/goexperiment/exp_arenas_on.go
@@ -0,0 +1,9 @@
+// Code generated by mkconsts.go. DO NOT EDIT.
+
+//go:build goexperiment.arenas
+// +build goexperiment.arenas
+
+package goexperiment
+
+const Arenas = true
+const ArenasInt = 1
diff --git a/src/internal/goexperiment/exp_coverageredesign_off.go b/src/internal/goexperiment/exp_coverageredesign_off.go
new file mode 100644
index 0000000..95d3a6c
--- /dev/null
+++ b/src/internal/goexperiment/exp_coverageredesign_off.go
@@ -0,0 +1,9 @@
+// Code generated by mkconsts.go. DO NOT EDIT.
+
+//go:build !goexperiment.coverageredesign
+// +build !goexperiment.coverageredesign
+
+package goexperiment
+
+const CoverageRedesign = false
+const CoverageRedesignInt = 0
diff --git a/src/internal/goexperiment/exp_coverageredesign_on.go b/src/internal/goexperiment/exp_coverageredesign_on.go
new file mode 100644
index 0000000..330a234
--- /dev/null
+++ b/src/internal/goexperiment/exp_coverageredesign_on.go
@@ -0,0 +1,9 @@
+// Code generated by mkconsts.go. DO NOT EDIT.
+
+//go:build goexperiment.coverageredesign
+// +build goexperiment.coverageredesign
+
+package goexperiment
+
+const CoverageRedesign = true
+const CoverageRedesignInt = 1
diff --git a/src/internal/goexperiment/exp_pagetrace_off.go b/src/internal/goexperiment/exp_pagetrace_off.go
new file mode 100644
index 0000000..789e883
--- /dev/null
+++ b/src/internal/goexperiment/exp_pagetrace_off.go
@@ -0,0 +1,9 @@
+// Code generated by mkconsts.go. DO NOT EDIT.
+
+//go:build !goexperiment.pagetrace
+// +build !goexperiment.pagetrace
+
+package goexperiment
+
+const PageTrace = false
+const PageTraceInt = 0
diff --git a/src/internal/goexperiment/exp_pagetrace_on.go b/src/internal/goexperiment/exp_pagetrace_on.go
new file mode 100644
index 0000000..ea72b54
--- /dev/null
+++ b/src/internal/goexperiment/exp_pagetrace_on.go
@@ -0,0 +1,9 @@
+// Code generated by mkconsts.go. DO NOT EDIT.
+
+//go:build goexperiment.pagetrace
+// +build goexperiment.pagetrace
+
+package goexperiment
+
+const PageTrace = true
+const PageTraceInt = 1
diff --git a/src/internal/goexperiment/flags.go b/src/internal/goexperiment/flags.go
index 20d9c2d..02e7443 100644
--- a/src/internal/goexperiment/flags.go
+++ b/src/internal/goexperiment/flags.go
@@ -86,4 +86,18 @@
 	// has been broken out to its own experiment that is disabled
 	// by default.
 	HeapMinimum512KiB bool
+
+	// CoverageRedesign enables the new compiler-based code coverage
+	// tooling.
+	CoverageRedesign bool
+
+	// Arenas causes the "arena" standard library package to be visible
+	// to the outside world.
+	Arenas bool
+
+	// PageTrace enables GODEBUG=pagetrace=/path/to/result. This feature
+	// is a GOEXPERIMENT due to a security risk with setuid binaries:
+	// this compels the Go runtime to write to some arbitrary file, which
+	// may be exploited.
+	PageTrace bool
 }
diff --git a/src/internal/goos/nonunix.go b/src/internal/goos/nonunix.go
new file mode 100644
index 0000000..2ba5c85
--- /dev/null
+++ b/src/internal/goos/nonunix.go
@@ -0,0 +1,9 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !unix
+
+package goos
+
+const IsUnix = false
diff --git a/src/internal/goos/unix.go b/src/internal/goos/unix.go
new file mode 100644
index 0000000..6cfd5ef
--- /dev/null
+++ b/src/internal/goos/unix.go
@@ -0,0 +1,9 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build unix
+
+package goos
+
+const IsUnix = true
diff --git a/src/internal/goroot/importcfg.go b/src/internal/goroot/importcfg.go
new file mode 100644
index 0000000..e324073
--- /dev/null
+++ b/src/internal/goroot/importcfg.go
@@ -0,0 +1,66 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package goroot
+
+import (
+	"bytes"
+	"fmt"
+	"os/exec"
+	"strings"
+	"sync"
+)
+
+// Importcfg returns an importcfg file to be passed to the
+// Go compiler that contains the cached paths for the .a files for the
+// standard library.
+func Importcfg() (string, error) {
+	var icfg bytes.Buffer
+
+	m, err := PkgfileMap()
+	if err != nil {
+		return "", err
+	}
+	fmt.Fprintf(&icfg, "# import config")
+	for importPath, export := range m {
+		fmt.Fprintf(&icfg, "\npackagefile %s=%s", importPath, export)
+	}
+	s := icfg.String()
+	return s, nil
+}
+
+var (
+	stdlibPkgfileMap map[string]string
+	stdlibPkgfileErr error
+	once             sync.Once
+)
+
+// PkgfileMap returns a map of package paths to the location on disk
+// of the .a file for the package.
+// The caller must not modify the map.
+func PkgfileMap() (map[string]string, error) {
+	once.Do(func() {
+		m := make(map[string]string)
+		output, err := exec.Command("go", "list", "-export", "-e", "-f", "{{.ImportPath}} {{.Export}}", "std", "cmd").Output()
+		if err != nil {
+			stdlibPkgfileErr = err
+		}
+		for _, line := range strings.Split(string(output), "\n") {
+			if line == "" {
+				continue
+			}
+			sp := strings.SplitN(line, " ", 2)
+			if len(sp) != 2 {
+				stdlibPkgfileErr = fmt.Errorf("determining pkgfile map: invalid line in go list output: %q", line)
+				return
+			}
+			importPath, export := sp[0], sp[1]
+			if export != "" {
+				m[importPath] = export
+			}
+		}
+		stdlibPkgfileMap = m
+	})
+	return stdlibPkgfileMap, stdlibPkgfileErr
+}
diff --git a/src/internal/goversion/goversion.go b/src/internal/goversion/goversion.go
index da33e68..e9ecf8e 100644
--- a/src/internal/goversion/goversion.go
+++ b/src/internal/goversion/goversion.go
@@ -9,4 +9,4 @@
 //
 // It should be updated at the start of each development cycle to be
 // the version of the next Go 1.x release. See golang.org/issue/40705.
-const Version = 19
+const Version = 20
diff --git a/src/internal/intern/intern.go b/src/internal/intern/intern.go
index c7639b4..0e6852f 100644
--- a/src/internal/intern/intern.go
+++ b/src/internal/intern/intern.go
@@ -66,10 +66,12 @@
 	valSafe = safeMap()         // non-nil in safe+leaky mode
 )
 
+var intern = godebug.New("intern")
+
 // safeMap returns a non-nil map if we're in safe-but-leaky mode,
 // as controlled by GODEBUG=intern=leaky
 func safeMap() map[key]*Value {
-	if godebug.Get("intern") == "leaky" {
+	if intern.Value() == "leaky" {
 		return map[key]*Value{}
 	}
 	return nil
diff --git a/src/internal/obscuretestdata/obscuretestdata.go b/src/internal/obscuretestdata/obscuretestdata.go
index 5ea2cdf..d54d3f6 100644
--- a/src/internal/obscuretestdata/obscuretestdata.go
+++ b/src/internal/obscuretestdata/obscuretestdata.go
@@ -13,6 +13,21 @@
 	"os"
 )
 
+// Rot13 returns the rot13 encoding or decoding of its input.
+func Rot13(data []byte) []byte {
+	out := make([]byte, len(data))
+	copy(out, data)
+	for i, c := range out {
+		switch {
+		case 'A' <= c && c <= 'M' || 'a' <= c && c <= 'm':
+			out[i] = c + 13
+		case 'N' <= c && c <= 'Z' || 'n' <= c && c <= 'z':
+			out[i] = c - 13
+		}
+	}
+	return out
+}
+
 // DecodeToTempFile decodes the named file to a temporary location.
 // If successful, it returns the path of the decoded file.
 // The caller is responsible for ensuring that the temporary file is removed.
diff --git a/src/internal/pkgbits/decoder.go b/src/internal/pkgbits/decoder.go
index 0b5fd97..4fe024d 100644
--- a/src/internal/pkgbits/decoder.go
+++ b/src/internal/pkgbits/decoder.go
@@ -6,9 +6,11 @@
 
 import (
 	"encoding/binary"
+	"errors"
 	"fmt"
 	"go/constant"
 	"go/token"
+	"io"
 	"math/big"
 	"os"
 	"runtime"
@@ -18,6 +20,12 @@
 // A PkgDecoder provides methods for decoding a package's Unified IR
 // export data.
 type PkgDecoder struct {
+	// version is the file format version.
+	version uint32
+
+	// sync indicates whether the file uses sync markers.
+	sync bool
+
 	// pkgPath is the package path for the package to be decoded.
 	//
 	// TODO(mdempsky): Remove; unneeded since CL 391014.
@@ -45,6 +53,8 @@
 	// For example, section K's end positions start at elemEndsEnds[K-1]
 	// (or 0, if K==0) and end at elemEndsEnds[K].
 	elemEndsEnds [numRelocs]uint32
+
+	scratchRelocEnt []RelocEnt
 }
 
 // PkgPath returns the package path for the package
@@ -52,6 +62,9 @@
 // TODO(mdempsky): Remove; unneeded since CL 391014.
 func (pr *PkgDecoder) PkgPath() string { return pr.pkgPath }
 
+// SyncMarkers reports whether pr uses sync markers.
+func (pr *PkgDecoder) SyncMarkers() bool { return pr.sync }
+
 // NewPkgDecoder returns a PkgDecoder initialized to read the Unified
 // IR export data from input. pkgPath is the package path for the
 // compilation unit that produced the export data.
@@ -67,16 +80,25 @@
 
 	r := strings.NewReader(input)
 
-	var version uint32
-	assert(binary.Read(r, binary.LittleEndian, &version) == nil)
-	assert(version == 0)
+	assert(binary.Read(r, binary.LittleEndian, &pr.version) == nil)
+
+	switch pr.version {
+	default:
+		panic(fmt.Errorf("unsupported version: %v", pr.version))
+	case 0:
+		// no flags
+	case 1:
+		var flags uint32
+		assert(binary.Read(r, binary.LittleEndian, &flags) == nil)
+		pr.sync = flags&flagSyncMarkers != 0
+	}
 
 	assert(binary.Read(r, binary.LittleEndian, pr.elemEndsEnds[:]) == nil)
 
 	pr.elemEnds = make([]uint32, pr.elemEndsEnds[len(pr.elemEndsEnds)-1])
 	assert(binary.Read(r, binary.LittleEndian, pr.elemEnds[:]) == nil)
 
-	pos, err := r.Seek(0, os.SEEK_CUR)
+	pos, err := r.Seek(0, io.SeekCurrent)
 	assert(err == nil)
 
 	pr.elemData = input[pos:]
@@ -146,6 +168,21 @@
 	return r
 }
 
+// TempDecoder returns a Decoder for the given (section, index) pair,
+// and decodes the given SyncMarker from the element bitstream.
+// If possible the Decoder should be RetireDecoder'd when it is no longer
+// needed, this will avoid heap allocations.
+func (pr *PkgDecoder) TempDecoder(k RelocKind, idx Index, marker SyncMarker) Decoder {
+	r := pr.TempDecoderRaw(k, idx)
+	r.Sync(marker)
+	return r
+}
+
+func (pr *PkgDecoder) RetireDecoder(d *Decoder) {
+	pr.scratchRelocEnt = d.Relocs
+	d.Relocs = nil
+}
+
 // NewDecoderRaw returns a Decoder for the given (section, index) pair.
 //
 // Most callers should use NewDecoder instead.
@@ -156,9 +193,7 @@
 		Idx:    idx,
 	}
 
-	// TODO(mdempsky) r.data.Reset(...) after #44505 is resolved.
-	r.Data = *strings.NewReader(pr.DataIdx(k, idx))
-
+	r.Data.Reset(pr.DataIdx(k, idx))
 	r.Sync(SyncRelocs)
 	r.Relocs = make([]RelocEnt, r.Len())
 	for i := range r.Relocs {
@@ -169,6 +204,30 @@
 	return r
 }
 
+func (pr *PkgDecoder) TempDecoderRaw(k RelocKind, idx Index) Decoder {
+	r := Decoder{
+		common: pr,
+		k:      k,
+		Idx:    idx,
+	}
+
+	r.Data.Reset(pr.DataIdx(k, idx))
+	r.Sync(SyncRelocs)
+	l := r.Len()
+	if cap(pr.scratchRelocEnt) >= l {
+		r.Relocs = pr.scratchRelocEnt[:l]
+		pr.scratchRelocEnt = nil
+	} else {
+		r.Relocs = make([]RelocEnt, l)
+	}
+	for i := range r.Relocs {
+		r.Sync(SyncReloc)
+		r.Relocs[i] = RelocEnt{RelocKind(r.Len()), Index(r.Len())}
+	}
+
+	return r
+}
+
 // A Decoder provides methods for decoding an individual element's
 // bitstream data.
 type Decoder struct {
@@ -188,11 +247,39 @@
 }
 
 func (r *Decoder) rawUvarint() uint64 {
-	x, err := binary.ReadUvarint(&r.Data)
+	x, err := readUvarint(&r.Data)
 	r.checkErr(err)
 	return x
 }
 
+// readUvarint is a type-specialized copy of encoding/binary.ReadUvarint.
+// This avoids the interface conversion and thus has better escape properties,
+// which flows up the stack.
+func readUvarint(r *strings.Reader) (uint64, error) {
+	var x uint64
+	var s uint
+	for i := 0; i < binary.MaxVarintLen64; i++ {
+		b, err := r.ReadByte()
+		if err != nil {
+			if i > 0 && err == io.EOF {
+				err = io.ErrUnexpectedEOF
+			}
+			return x, err
+		}
+		if b < 0x80 {
+			if i == binary.MaxVarintLen64-1 && b > 1 {
+				return x, overflow
+			}
+			return x | uint64(b)<<s, nil
+		}
+		x |= uint64(b&0x7f) << s
+		s += 7
+	}
+	return x, overflow
+}
+
+var overflow = errors.New("pkgbits: readUvarint overflows a 64-bit integer")
+
 func (r *Decoder) rawVarint() int64 {
 	ux := r.rawUvarint()
 
@@ -215,11 +302,11 @@
 //
 // If EnableSync is false, then Sync is a no-op.
 func (r *Decoder) Sync(mWant SyncMarker) {
-	if !EnableSync {
+	if !r.common.sync {
 		return
 	}
 
-	pos, _ := r.Data.Seek(0, os.SEEK_CUR) // TODO(mdempsky): io.SeekCurrent after #44505 is resolved
+	pos, _ := r.Data.Seek(0, io.SeekCurrent)
 	mHave := SyncMarker(r.rawUvarint())
 	writerPCs := make([]int, r.rawUvarint())
 	for i := range writerPCs {
@@ -391,8 +478,12 @@
 // PeekPkgPath returns the package path for the specified package
 // index.
 func (pr *PkgDecoder) PeekPkgPath(idx Index) string {
-	r := pr.NewDecoder(RelocPkg, idx, SyncPkgDef)
-	path := r.String()
+	var path string
+	{
+		r := pr.TempDecoder(RelocPkg, idx, SyncPkgDef)
+		path = r.String()
+		pr.RetireDecoder(&r)
+	}
 	if path == "" {
 		path = pr.pkgPath
 	}
@@ -402,14 +493,23 @@
 // PeekObj returns the package path, object name, and CodeObj for the
 // specified object index.
 func (pr *PkgDecoder) PeekObj(idx Index) (string, string, CodeObj) {
-	r := pr.NewDecoder(RelocName, idx, SyncObject1)
-	r.Sync(SyncSym)
-	r.Sync(SyncPkg)
-	path := pr.PeekPkgPath(r.Reloc(RelocPkg))
-	name := r.String()
+	var ridx Index
+	var name string
+	var rcode int
+	{
+		r := pr.TempDecoder(RelocName, idx, SyncObject1)
+		r.Sync(SyncSym)
+		r.Sync(SyncPkg)
+		ridx = r.Reloc(RelocPkg)
+		name = r.String()
+		rcode = r.Code(SyncCodeObj)
+		pr.RetireDecoder(&r)
+	}
+
+	path := pr.PeekPkgPath(ridx)
 	assert(name != "")
 
-	tag := CodeObj(r.Code(SyncCodeObj))
+	tag := CodeObj(rcode)
 
 	return path, name, tag
 }
diff --git a/src/internal/pkgbits/encoder.go b/src/internal/pkgbits/encoder.go
index 1326a13..70a2cba 100644
--- a/src/internal/pkgbits/encoder.go
+++ b/src/internal/pkgbits/encoder.go
@@ -12,8 +12,20 @@
 	"io"
 	"math/big"
 	"runtime"
+	"strings"
 )
 
+// currentVersion is the current version number.
+//
+//   - v0: initial prototype
+//
+//   - v1: adds the flags uint32 word
+//
+// TODO(mdempsky): For the next version bump:
+//   - remove the legacy "has init" bool from the public root
+//   - remove obj's "derived func instance" bool
+const currentVersion uint32 = 1
+
 // A PkgEncoder provides methods for encoding a package's Unified IR
 // export data.
 type PkgEncoder struct {
@@ -25,15 +37,21 @@
 	// elems[RelocString][stringsIdx[s]] == s (if present).
 	stringsIdx map[string]Index
 
+	// syncFrames is the number of frames to write at each sync
+	// marker. A negative value means sync markers are omitted.
 	syncFrames int
 }
 
+// SyncMarkers reports whether pw uses sync markers.
+func (pw *PkgEncoder) SyncMarkers() bool { return pw.syncFrames >= 0 }
+
 // NewPkgEncoder returns an initialized PkgEncoder.
 //
 // syncFrames is the number of caller frames that should be serialized
 // at Sync points. Serializing additional frames results in larger
 // export data files, but can help diagnosing desync errors in
-// higher-level Unified IR reader/writer code.
+// higher-level Unified IR reader/writer code. If syncFrames is
+// negative, then sync markers are omitted entirely.
 func NewPkgEncoder(syncFrames int) PkgEncoder {
 	return PkgEncoder{
 		stringsIdx: make(map[string]Index),
@@ -51,7 +69,13 @@
 		assert(binary.Write(out, binary.LittleEndian, x) == nil)
 	}
 
-	writeUint32(0) // version
+	writeUint32(currentVersion)
+
+	var flags uint32
+	if pw.SyncMarkers() {
+		flags |= flagSyncMarkers
+	}
+	writeUint32(flags)
 
 	// Write elemEndsEnds.
 	var sum uint32
@@ -128,8 +152,9 @@
 type Encoder struct {
 	p *PkgEncoder
 
-	Relocs []RelocEnt
-	Data   bytes.Buffer // accumulated element bitstream data
+	Relocs   []RelocEnt
+	RelocMap map[RelocEnt]uint32
+	Data     bytes.Buffer // accumulated element bitstream data
 
 	encodingRelocHeader bool
 
@@ -139,7 +164,7 @@
 
 // Flush finalizes the element's bitstream and returns its Index.
 func (w *Encoder) Flush() Index {
-	var sb bytes.Buffer // TODO(mdempsky): strings.Builder after #44505 is resolved
+	var sb strings.Builder
 
 	// Backup the data so we write the relocations at the front.
 	var tmp bytes.Buffer
@@ -191,20 +216,23 @@
 }
 
 func (w *Encoder) rawReloc(r RelocKind, idx Index) int {
-	// TODO(mdempsky): Use map for lookup; this takes quadratic time.
-	for i, rEnt := range w.Relocs {
-		if rEnt.Kind == r && rEnt.Idx == idx {
-			return i
+	e := RelocEnt{r, idx}
+	if w.RelocMap != nil {
+		if i, ok := w.RelocMap[e]; ok {
+			return int(i)
 		}
+	} else {
+		w.RelocMap = make(map[RelocEnt]uint32)
 	}
 
 	i := len(w.Relocs)
-	w.Relocs = append(w.Relocs, RelocEnt{r, idx})
+	w.RelocMap[e] = uint32(i)
+	w.Relocs = append(w.Relocs, e)
 	return i
 }
 
 func (w *Encoder) Sync(m SyncMarker) {
-	if !EnableSync {
+	if !w.p.SyncMarkers() {
 		return
 	}
 
@@ -297,8 +325,14 @@
 // section (if not already present), and then writing a relocation
 // into the element bitstream.
 func (w *Encoder) String(s string) {
+	w.StringRef(w.p.StringIdx(s))
+}
+
+// StringRef writes a reference to the given index, which must be a
+// previously encoded string value.
+func (w *Encoder) StringRef(idx Index) {
 	w.Sync(SyncString)
-	w.Reloc(RelocString, w.p.StringIdx(s))
+	w.Reloc(RelocString, idx)
 }
 
 // Strings encodes and writes a variable-length slice of strings into
diff --git a/src/internal/pkgbits/flags.go b/src/internal/pkgbits/flags.go
new file mode 100644
index 0000000..6542227
--- /dev/null
+++ b/src/internal/pkgbits/flags.go
@@ -0,0 +1,9 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkgbits
+
+const (
+	flagSyncMarkers = 1 << iota // file format contains sync markers
+)
diff --git a/src/internal/pkgbits/frames_go1.go b/src/internal/pkgbits/frames_go1.go
deleted file mode 100644
index 5294f6a..0000000
--- a/src/internal/pkgbits/frames_go1.go
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build !go1.7
-// +build !go1.7
-
-// TODO(mdempsky): Remove after #44505 is resolved
-
-package pkgbits
-
-import "runtime"
-
-func walkFrames(pcs []uintptr, visit frameVisitor) {
-	for _, pc := range pcs {
-		fn := runtime.FuncForPC(pc)
-		file, line := fn.FileLine(pc)
-
-		visit(file, line, fn.Name(), pc-fn.Entry())
-	}
-}
diff --git a/src/internal/pkgbits/frames_go17.go b/src/internal/pkgbits/frames_go17.go
deleted file mode 100644
index 2324ae7..0000000
--- a/src/internal/pkgbits/frames_go17.go
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build go1.7
-// +build go1.7
-
-package pkgbits
-
-import "runtime"
-
-// walkFrames calls visit for each call frame represented by pcs.
-//
-// pcs should be a slice of PCs, as returned by runtime.Callers.
-func walkFrames(pcs []uintptr, visit frameVisitor) {
-	if len(pcs) == 0 {
-		return
-	}
-
-	frames := runtime.CallersFrames(pcs)
-	for {
-		frame, more := frames.Next()
-		visit(frame.File, frame.Line, frame.Function, frame.PC-frame.Entry)
-		if !more {
-			return
-		}
-	}
-}
diff --git a/src/internal/pkgbits/reloc.go b/src/internal/pkgbits/reloc.go
index 7a8f04a..fcdfb97 100644
--- a/src/internal/pkgbits/reloc.go
+++ b/src/internal/pkgbits/reloc.go
@@ -5,11 +5,11 @@
 package pkgbits
 
 // A RelocKind indicates a particular section within a unified IR export.
-type RelocKind int
+type RelocKind int32
 
 // An Index represents a bitstream element index within a particular
 // section.
-type Index int
+type Index int32
 
 // A relocEnt (relocation entry) is an entry in an element's local
 // reference table.
diff --git a/src/internal/pkgbits/sync.go b/src/internal/pkgbits/sync.go
index 4b9ea48..1520b73 100644
--- a/src/internal/pkgbits/sync.go
+++ b/src/internal/pkgbits/sync.go
@@ -6,20 +6,10 @@
 
 import (
 	"fmt"
+	"runtime"
 	"strings"
 )
 
-// EnableSync controls whether sync markers are written into unified
-// IR's export data format and also whether they're expected when
-// reading them back in. They're inessential to the correct
-// functioning of unified IR, but are helpful during development to
-// detect mistakes.
-//
-// When sync is enabled, writer stack frames will also be included in
-// the export data. Currently, a fixed number of frames are included,
-// controlled by -d=syncframes (default 0).
-const EnableSync = true
-
 // fmtFrames formats a backtrace for reporting reader/writer desyncs.
 func fmtFrames(pcs ...uintptr) []string {
 	res := make([]string, 0, len(pcs))
@@ -34,6 +24,24 @@
 
 type frameVisitor func(file string, line int, name string, offset uintptr)
 
+// walkFrames calls visit for each call frame represented by pcs.
+//
+// pcs should be a slice of PCs, as returned by runtime.Callers.
+func walkFrames(pcs []uintptr, visit frameVisitor) {
+	if len(pcs) == 0 {
+		return
+	}
+
+	frames := runtime.CallersFrames(pcs)
+	for {
+		frame, more := frames.Next()
+		visit(frame.File, frame.Line, frame.Function, frame.PC-frame.Entry)
+		if !more {
+			return
+		}
+	}
+}
+
 // SyncMarker is an enum type that represents markers that may be
 // written to export data to ensure the reader and writer stay
 // synchronized.
@@ -90,6 +98,7 @@
 	SyncExprs
 	SyncExpr
 	SyncExprType
+	SyncAssign
 	SyncOp
 	SyncFuncLit
 	SyncCompLit
@@ -120,4 +129,8 @@
 	SyncStmtsEnd
 	SyncLabel
 	SyncOptLabel
+
+	SyncMultiExpr
+	SyncRType
+	SyncConvRTTI
 )
diff --git a/src/internal/pkgbits/syncmarker_string.go b/src/internal/pkgbits/syncmarker_string.go
index 39db9ed..4a5b0ca 100644
--- a/src/internal/pkgbits/syncmarker_string.go
+++ b/src/internal/pkgbits/syncmarker_string.go
@@ -45,39 +45,40 @@
 	_ = x[SyncExprs-35]
 	_ = x[SyncExpr-36]
 	_ = x[SyncExprType-37]
-	_ = x[SyncOp-38]
-	_ = x[SyncFuncLit-39]
-	_ = x[SyncCompLit-40]
-	_ = x[SyncDecl-41]
-	_ = x[SyncFuncBody-42]
-	_ = x[SyncOpenScope-43]
-	_ = x[SyncCloseScope-44]
-	_ = x[SyncCloseAnotherScope-45]
-	_ = x[SyncDeclNames-46]
-	_ = x[SyncDeclName-47]
-	_ = x[SyncStmts-48]
-	_ = x[SyncBlockStmt-49]
-	_ = x[SyncIfStmt-50]
-	_ = x[SyncForStmt-51]
-	_ = x[SyncSwitchStmt-52]
-	_ = x[SyncRangeStmt-53]
-	_ = x[SyncCaseClause-54]
-	_ = x[SyncCommClause-55]
-	_ = x[SyncSelectStmt-56]
-	_ = x[SyncDecls-57]
-	_ = x[SyncLabeledStmt-58]
-	_ = x[SyncUseObjLocal-59]
-	_ = x[SyncAddLocal-60]
-	_ = x[SyncLinkname-61]
-	_ = x[SyncStmt1-62]
-	_ = x[SyncStmtsEnd-63]
-	_ = x[SyncLabel-64]
-	_ = x[SyncOptLabel-65]
+	_ = x[SyncAssign-38]
+	_ = x[SyncOp-39]
+	_ = x[SyncFuncLit-40]
+	_ = x[SyncCompLit-41]
+	_ = x[SyncDecl-42]
+	_ = x[SyncFuncBody-43]
+	_ = x[SyncOpenScope-44]
+	_ = x[SyncCloseScope-45]
+	_ = x[SyncCloseAnotherScope-46]
+	_ = x[SyncDeclNames-47]
+	_ = x[SyncDeclName-48]
+	_ = x[SyncStmts-49]
+	_ = x[SyncBlockStmt-50]
+	_ = x[SyncIfStmt-51]
+	_ = x[SyncForStmt-52]
+	_ = x[SyncSwitchStmt-53]
+	_ = x[SyncRangeStmt-54]
+	_ = x[SyncCaseClause-55]
+	_ = x[SyncCommClause-56]
+	_ = x[SyncSelectStmt-57]
+	_ = x[SyncDecls-58]
+	_ = x[SyncLabeledStmt-59]
+	_ = x[SyncUseObjLocal-60]
+	_ = x[SyncAddLocal-61]
+	_ = x[SyncLinkname-62]
+	_ = x[SyncStmt1-63]
+	_ = x[SyncStmtsEnd-64]
+	_ = x[SyncLabel-65]
+	_ = x[SyncOptLabel-66]
 }
 
-const _SyncMarker_name = "EOFBoolInt64Uint64StringValueValRelocsRelocUseRelocPublicPosPosBaseObjectObject1PkgPkgDefMethodTypeTypeIdxTypeParamNamesSignatureParamsParamCodeObjSymLocalIdentSelectorPrivateFuncExtVarExtTypeExtPragmaExprListExprsExprAssertTypeOpFuncLitCompLitDeclFuncBodyOpenScopeCloseScopeCloseAnotherScopeDeclNamesDeclNameStmtsBlockStmtIfStmtForStmtSwitchStmtRangeStmtCaseClauseCommClauseSelectStmtDeclsLabeledStmtUseObjLocalAddLocalLinknameStmt1StmtsEndLabelOptLabel"
+const _SyncMarker_name = "EOFBoolInt64Uint64StringValueValRelocsRelocUseRelocPublicPosPosBaseObjectObject1PkgPkgDefMethodTypeTypeIdxTypeParamNamesSignatureParamsParamCodeObjSymLocalIdentSelectorPrivateFuncExtVarExtTypeExtPragmaExprListExprsExprExprTypeAssignOpFuncLitCompLitDeclFuncBodyOpenScopeCloseScopeCloseAnotherScopeDeclNamesDeclNameStmtsBlockStmtIfStmtForStmtSwitchStmtRangeStmtCaseClauseCommClauseSelectStmtDeclsLabeledStmtUseObjLocalAddLocalLinknameStmt1StmtsEndLabelOptLabel"
 
-var _SyncMarker_index = [...]uint16{0, 3, 7, 12, 18, 24, 29, 32, 38, 43, 51, 57, 60, 67, 73, 80, 83, 89, 95, 99, 106, 120, 129, 135, 140, 147, 150, 160, 168, 175, 182, 188, 195, 201, 209, 214, 218, 228, 230, 237, 244, 248, 256, 265, 275, 292, 301, 309, 314, 323, 329, 336, 346, 355, 365, 375, 385, 390, 401, 412, 420, 428, 433, 441, 446, 454}
+var _SyncMarker_index = [...]uint16{0, 3, 7, 12, 18, 24, 29, 32, 38, 43, 51, 57, 60, 67, 73, 80, 83, 89, 95, 99, 106, 120, 129, 135, 140, 147, 150, 160, 168, 175, 182, 188, 195, 201, 209, 214, 218, 226, 232, 234, 241, 248, 252, 260, 269, 279, 296, 305, 313, 318, 327, 333, 340, 350, 359, 369, 379, 389, 394, 405, 416, 424, 432, 437, 445, 450, 458}
 
 func (i SyncMarker) String() string {
 	i -= 1
diff --git a/src/internal/platform/supported.go b/src/internal/platform/supported.go
new file mode 100644
index 0000000..86c9f07
--- /dev/null
+++ b/src/internal/platform/supported.go
@@ -0,0 +1,168 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package platform
+
+// RaceDetectorSupported reports whether goos/goarch supports the race
+// detector. There is a copy of this function in cmd/dist/test.go.
+// Race detector only supports 48-bit VMA on arm64. But it will always
+// return true for arm64, because we don't have VMA size information during
+// the compile time.
+func RaceDetectorSupported(goos, goarch string) bool {
+	switch goos {
+	case "linux":
+		return goarch == "amd64" || goarch == "ppc64le" || goarch == "arm64" || goarch == "s390x"
+	case "darwin":
+		return goarch == "amd64" || goarch == "arm64"
+	case "freebsd", "netbsd", "openbsd", "windows":
+		return goarch == "amd64"
+	default:
+		return false
+	}
+}
+
+// MSanSupported reports whether goos/goarch supports the memory
+// sanitizer option.
+// There is a copy of this function in misc/cgo/testsanitizers/cc_test.go.
+func MSanSupported(goos, goarch string) bool {
+	switch goos {
+	case "linux":
+		return goarch == "amd64" || goarch == "arm64"
+	case "freebsd":
+		return goarch == "amd64"
+	default:
+		return false
+	}
+}
+
+// ASanSupported reports whether goos/goarch supports the address
+// sanitizer option.
+// There is a copy of this function in misc/cgo/testsanitizers/cc_test.go.
+func ASanSupported(goos, goarch string) bool {
+	switch goos {
+	case "linux":
+		return goarch == "arm64" || goarch == "amd64" || goarch == "riscv64" || goarch == "ppc64le"
+	default:
+		return false
+	}
+}
+
+// FuzzSupported reports whether goos/goarch supports fuzzing
+// ('go test -fuzz=.').
+func FuzzSupported(goos, goarch string) bool {
+	switch goos {
+	case "darwin", "freebsd", "linux", "windows":
+		return true
+	default:
+		return false
+	}
+}
+
+// FuzzInstrumented reports whether fuzzing on goos/goarch uses coverage
+// instrumentation. (FuzzInstrumented implies FuzzSupported.)
+func FuzzInstrumented(goos, goarch string) bool {
+	switch goarch {
+	case "amd64", "arm64":
+		// TODO(#14565): support more architectures.
+		return FuzzSupported(goos, goarch)
+	default:
+		return false
+	}
+}
+
+// MustLinkExternal reports whether goos/goarch requires external linking.
+func MustLinkExternal(goos, goarch string) bool {
+	switch goos {
+	case "android":
+		if goarch != "arm64" {
+			return true
+		}
+	case "ios":
+		if goarch == "arm64" {
+			return true
+		}
+	}
+	return false
+}
+
+// BuildModeSupported reports whether goos/goarch supports the given build mode
+// using the given compiler.
+func BuildModeSupported(compiler, buildmode, goos, goarch string) bool {
+	if compiler == "gccgo" {
+		return true
+	}
+
+	platform := goos + "/" + goarch
+
+	switch buildmode {
+	case "archive":
+		return true
+
+	case "c-archive":
+		// TODO(bcmills): This seems dubious.
+		// Do we really support c-archive mode on js/wasm‽
+		return platform != "linux/ppc64"
+
+	case "c-shared":
+		switch platform {
+		case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/ppc64le", "linux/riscv64", "linux/s390x",
+			"android/amd64", "android/arm", "android/arm64", "android/386",
+			"freebsd/amd64",
+			"darwin/amd64", "darwin/arm64",
+			"windows/amd64", "windows/386", "windows/arm64":
+			return true
+		}
+		return false
+
+	case "default":
+		return true
+
+	case "exe":
+		return true
+
+	case "pie":
+		switch platform {
+		case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/riscv64", "linux/s390x",
+			"android/amd64", "android/arm", "android/arm64", "android/386",
+			"freebsd/amd64",
+			"darwin/amd64", "darwin/arm64",
+			"ios/amd64", "ios/arm64",
+			"aix/ppc64",
+			"windows/386", "windows/amd64", "windows/arm", "windows/arm64":
+			return true
+		}
+		return false
+
+	case "shared":
+		switch platform {
+		case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x":
+			return true
+		}
+		return false
+
+	case "plugin":
+		switch platform {
+		case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/s390x", "linux/ppc64le",
+			"android/amd64", "android/arm", "android/arm64", "android/386",
+			"darwin/amd64", "darwin/arm64",
+			"freebsd/amd64":
+			return true
+		}
+		return false
+
+	default:
+		return false
+	}
+}
+
+func InternalLinkPIESupported(goos, goarch string) bool {
+	switch goos + "/" + goarch {
+	case "darwin/amd64", "darwin/arm64",
+		"linux/amd64", "linux/arm64", "linux/ppc64le",
+		"android/arm64",
+		"windows-amd64", "windows-386", "windows-arm":
+		return true
+	}
+	return false
+}
diff --git a/src/internal/poll/copy_file_range_linux.go b/src/internal/poll/copy_file_range_linux.go
index 5b9e5d4..ba33f51 100644
--- a/src/internal/poll/copy_file_range_linux.go
+++ b/src/internal/poll/copy_file_range_linux.go
@@ -6,66 +6,34 @@
 
 import (
 	"internal/syscall/unix"
-	"sync/atomic"
+	"sync"
 	"syscall"
 )
 
-var copyFileRangeSupported int32 = -1 // accessed atomically
+var (
+	kernelVersion53Once sync.Once
+	kernelVersion53     bool
+)
 
 const maxCopyFileRangeRound = 1 << 30
 
-func kernelVersion() (major int, minor int) {
-	var uname syscall.Utsname
-	if err := syscall.Uname(&uname); err != nil {
-		return
-	}
-
-	rl := uname.Release
-	var values [2]int
-	vi := 0
-	value := 0
-	for _, c := range rl {
-		if '0' <= c && c <= '9' {
-			value = (value * 10) + int(c-'0')
-		} else {
-			// Note that we're assuming N.N.N here.  If we see anything else we are likely to
-			// mis-parse it.
-			values[vi] = value
-			vi++
-			if vi >= len(values) {
-				break
-			}
-			value = 0
-		}
-	}
-	switch vi {
-	case 0:
-		return 0, 0
-	case 1:
-		return values[0], 0
-	case 2:
-		return values[0], values[1]
-	}
-	return
-}
-
 // CopyFileRange copies at most remain bytes of data from src to dst, using
 // the copy_file_range system call. dst and src must refer to regular files.
 func CopyFileRange(dst, src *FD, remain int64) (written int64, handled bool, err error) {
-	if supported := atomic.LoadInt32(&copyFileRangeSupported); supported == 0 {
-		return 0, false, nil
-	} else if supported == -1 {
-		major, minor := kernelVersion()
+	kernelVersion53Once.Do(func() {
+		major, minor := unix.KernelVersion()
+		// copy_file_range(2) is broken in various ways on kernels older than 5.3,
+		// see issue #42400 and
+		// https://man7.org/linux/man-pages/man2/copy_file_range.2.html#VERSIONS
 		if major > 5 || (major == 5 && minor >= 3) {
-			atomic.StoreInt32(&copyFileRangeSupported, 1)
-		} else {
-			// copy_file_range(2) is broken in various ways on kernels older than 5.3,
-			// see issue #42400 and
-			// https://man7.org/linux/man-pages/man2/copy_file_range.2.html#VERSIONS
-			atomic.StoreInt32(&copyFileRangeSupported, 0)
-			return 0, false, nil
+			kernelVersion53 = true
 		}
+	})
+
+	if !kernelVersion53 {
+		return 0, false, nil
 	}
+
 	for remain > 0 {
 		max := remain
 		if max > maxCopyFileRangeRound {
@@ -82,10 +50,6 @@
 			// any data, so we can tell the caller that we
 			// couldn't handle the transfer and let them fall
 			// back to more generic code.
-			//
-			// Seeing ENOSYS also means that we will not try to
-			// use copy_file_range(2) again.
-			atomic.StoreInt32(&copyFileRangeSupported, 0)
 			return 0, false, nil
 		case syscall.EXDEV, syscall.EINVAL, syscall.EIO, syscall.EOPNOTSUPP, syscall.EPERM:
 			// Prior to Linux 5.3, it was not possible to
diff --git a/src/internal/poll/errno_windows.go b/src/internal/poll/errno_windows.go
index 3679aa8..6381479 100644
--- a/src/internal/poll/errno_windows.go
+++ b/src/internal/poll/errno_windows.go
@@ -15,7 +15,7 @@
 	errERROR_IO_PENDING error = syscall.Errno(syscall.ERROR_IO_PENDING)
 )
 
-// ErrnoErr returns common boxed Errno values, to prevent
+// errnoErr returns common boxed Errno values, to prevent
 // allocations at runtime.
 func errnoErr(e syscall.Errno) error {
 	switch e {
diff --git a/src/internal/poll/export_test.go b/src/internal/poll/export_test.go
index 02664d9..66d7c32 100644
--- a/src/internal/poll/export_test.go
+++ b/src/internal/poll/export_test.go
@@ -10,26 +10,26 @@
 
 var Consume = consume
 
-type FDMutex struct {
+type XFDMutex struct {
 	fdMutex
 }
 
-func (mu *FDMutex) Incref() bool {
+func (mu *XFDMutex) Incref() bool {
 	return mu.incref()
 }
 
-func (mu *FDMutex) IncrefAndClose() bool {
+func (mu *XFDMutex) IncrefAndClose() bool {
 	return mu.increfAndClose()
 }
 
-func (mu *FDMutex) Decref() bool {
+func (mu *XFDMutex) Decref() bool {
 	return mu.decref()
 }
 
-func (mu *FDMutex) RWLock(read bool) bool {
+func (mu *XFDMutex) RWLock(read bool) bool {
 	return mu.rwlock(read)
 }
 
-func (mu *FDMutex) RWUnlock(read bool) bool {
+func (mu *XFDMutex) RWUnlock(read bool) bool {
 	return mu.rwunlock(read)
 }
diff --git a/src/internal/poll/fcntl_libc.go b/src/internal/poll/fcntl_libc.go
index 13614dc..529b8e1 100644
--- a/src/internal/poll/fcntl_libc.go
+++ b/src/internal/poll/fcntl_libc.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build aix || darwin || solaris
+//go:build aix || darwin || (openbsd && !mips64) || solaris
 
 package poll
 
diff --git a/src/internal/poll/fcntl_syscall.go b/src/internal/poll/fcntl_syscall.go
index accff5e..bbfc8a8 100644
--- a/src/internal/poll/fcntl_syscall.go
+++ b/src/internal/poll/fcntl_syscall.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build dragonfly || freebsd || linux || netbsd || openbsd
+//go:build dragonfly || freebsd || linux || netbsd || (openbsd && mips64)
 
 package poll
 
diff --git a/src/internal/poll/fd_mutex_test.go b/src/internal/poll/fd_mutex_test.go
index 3029b9a..62f9531 100644
--- a/src/internal/poll/fd_mutex_test.go
+++ b/src/internal/poll/fd_mutex_test.go
@@ -14,7 +14,7 @@
 )
 
 func TestMutexLock(t *testing.T) {
-	var mu FDMutex
+	var mu XFDMutex
 
 	if !mu.Incref() {
 		t.Fatal("broken")
@@ -39,7 +39,7 @@
 }
 
 func TestMutexClose(t *testing.T) {
-	var mu FDMutex
+	var mu XFDMutex
 	if !mu.IncrefAndClose() {
 		t.Fatal("broken")
 	}
@@ -60,7 +60,7 @@
 
 func TestMutexCloseUnblock(t *testing.T) {
 	c := make(chan bool, 4)
-	var mu FDMutex
+	var mu XFDMutex
 	mu.RWLock(true)
 	for i := 0; i < 4; i++ {
 		go func() {
@@ -104,7 +104,7 @@
 		f()
 	}
 
-	var mu FDMutex
+	var mu XFDMutex
 	ensurePanics(func() { mu.Decref() })
 	ensurePanics(func() { mu.RWUnlock(true) })
 	ensurePanics(func() { mu.RWUnlock(false) })
@@ -137,7 +137,7 @@
 		}
 	}()
 
-	var mu1 FDMutex
+	var mu1 XFDMutex
 	for i := 0; i < 1<<21; i++ {
 		mu1.Incref()
 	}
@@ -152,7 +152,7 @@
 	}
 	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(P))
 	done := make(chan bool, P)
-	var mu FDMutex
+	var mu XFDMutex
 	var readState [2]uint64
 	var writeState [2]uint64
 	for p := 0; p < P; p++ {
diff --git a/src/internal/poll/fd_plan9.go b/src/internal/poll/fd_plan9.go
index 0b5b937..0fdf4f6 100644
--- a/src/internal/poll/fd_plan9.go
+++ b/src/internal/poll/fd_plan9.go
@@ -12,12 +12,6 @@
 	"time"
 )
 
-type atomicBool int32
-
-func (b *atomicBool) isSet() bool { return atomic.LoadInt32((*int32)(b)) != 0 }
-func (b *atomicBool) setFalse()   { atomic.StoreInt32((*int32)(b), 0) }
-func (b *atomicBool) setTrue()    { atomic.StoreInt32((*int32)(b), 1) }
-
 type FD struct {
 	// Lock sysfd and serialize access to Read and Write methods.
 	fdmu fdMutex
@@ -31,8 +25,8 @@
 	waio      *asyncIO
 	rtimer    *time.Timer
 	wtimer    *time.Timer
-	rtimedout atomicBool // set true when read deadline has been reached
-	wtimedout atomicBool // set true when write deadline has been reached
+	rtimedout atomic.Bool // set true when read deadline has been reached
+	wtimedout atomic.Bool // set true when write deadline has been reached
 
 	// Whether this is a normal file.
 	// On Plan 9 we do not use this package for ordinary files,
@@ -70,7 +64,7 @@
 		return 0, nil
 	}
 	fd.rmu.Lock()
-	if fd.rtimedout.isSet() {
+	if fd.rtimedout.Load() {
 		fd.rmu.Unlock()
 		return 0, ErrDeadlineExceeded
 	}
@@ -94,7 +88,7 @@
 	}
 	defer fd.writeUnlock()
 	fd.wmu.Lock()
-	if fd.wtimedout.isSet() {
+	if fd.wtimedout.Load() {
 		fd.wmu.Unlock()
 		return 0, ErrDeadlineExceeded
 	}
@@ -128,12 +122,12 @@
 	if mode == 'r' || mode == 'r'+'w' {
 		fd.rmu.Lock()
 		defer fd.rmu.Unlock()
-		fd.rtimedout.setFalse()
+		fd.rtimedout.Store(false)
 	}
 	if mode == 'w' || mode == 'r'+'w' {
 		fd.wmu.Lock()
 		defer fd.wmu.Unlock()
-		fd.wtimedout.setFalse()
+		fd.wtimedout.Store(false)
 	}
 	if t.IsZero() || d < 0 {
 		// Stop timer
@@ -154,7 +148,7 @@
 		if mode == 'r' || mode == 'r'+'w' {
 			fd.rtimer = time.AfterFunc(d, func() {
 				fd.rmu.Lock()
-				fd.rtimedout.setTrue()
+				fd.rtimedout.Store(true)
 				if fd.raio != nil {
 					fd.raio.Cancel()
 				}
@@ -164,7 +158,7 @@
 		if mode == 'w' || mode == 'r'+'w' {
 			fd.wtimer = time.AfterFunc(d, func() {
 				fd.wmu.Lock()
-				fd.wtimedout.setTrue()
+				fd.wtimedout.Store(true)
 				if fd.waio != nil {
 					fd.waio.Cancel()
 				}
@@ -175,13 +169,13 @@
 	if !t.IsZero() && d < 0 {
 		// Interrupt current I/O operation
 		if mode == 'r' || mode == 'r'+'w' {
-			fd.rtimedout.setTrue()
+			fd.rtimedout.Store(true)
 			if fd.raio != nil {
 				fd.raio.Cancel()
 			}
 		}
 		if mode == 'w' || mode == 'r'+'w' {
-			fd.wtimedout.setTrue()
+			fd.wtimedout.Store(true)
 			if fd.waio != nil {
 				fd.waio.Cancel()
 			}
diff --git a/src/internal/poll/fd_poll_runtime.go b/src/internal/poll/fd_poll_runtime.go
index 4d3cc78..0a2e76d 100644
--- a/src/internal/poll/fd_poll_runtime.go
+++ b/src/internal/poll/fd_poll_runtime.go
@@ -23,7 +23,7 @@
 func runtime_pollOpen(fd uintptr) (uintptr, int)
 func runtime_pollClose(ctx uintptr)
 func runtime_pollWait(ctx uintptr, mode int) int
-func runtime_pollWaitCanceled(ctx uintptr, mode int) int
+func runtime_pollWaitCanceled(ctx uintptr, mode int)
 func runtime_pollReset(ctx uintptr, mode int) int
 func runtime_pollSetDeadline(ctx uintptr, d int64, mode int)
 func runtime_pollUnblock(ctx uintptr)
diff --git a/src/internal/poll/fd_windows.go b/src/internal/poll/fd_windows.go
index 1ca281b..3a4a74f 100644
--- a/src/internal/poll/fd_windows.go
+++ b/src/internal/poll/fd_windows.go
@@ -268,7 +268,6 @@
 	kindNet fileKind = iota
 	kindFile
 	kindConsole
-	kindDir
 	kindPipe
 )
 
@@ -286,12 +285,10 @@
 	}
 
 	switch net {
-	case "file":
+	case "file", "dir":
 		fd.kind = kindFile
 	case "console":
 		fd.kind = kindConsole
-	case "dir":
-		fd.kind = kindDir
 	case "pipe":
 		fd.kind = kindPipe
 	case "tcp", "tcp4", "tcp6",
@@ -371,8 +368,6 @@
 	case kindNet:
 		// The net package uses the CloseFunc variable for testing.
 		err = CloseFunc(fd.Sysfd)
-	case kindDir:
-		err = syscall.FindClose(fd.Sysfd)
 	default:
 		err = syscall.CloseHandle(fd.Sysfd)
 	}
@@ -500,8 +495,7 @@
 					}
 				}
 			}
-			n := utf8.EncodeRune(buf[len(buf):cap(buf)], r)
-			buf = buf[:len(buf)+n]
+			buf = utf8.AppendRune(buf, r)
 		}
 		fd.readbyte = buf
 		fd.readbyteOffset = 0
@@ -1009,15 +1003,6 @@
 	return syscall.Seek(fd.Sysfd, offset, whence)
 }
 
-// FindNextFile wraps syscall.FindNextFile.
-func (fd *FD) FindNextFile(data *syscall.Win32finddata) error {
-	if err := fd.incref(); err != nil {
-		return err
-	}
-	defer fd.decref()
-	return syscall.FindNextFile(fd.Sysfd, data)
-}
-
 // Fchmod updates syscall.ByHandleFileInformation.Fileattributes when needed.
 func (fd *FD) Fchmod(mode uint32) error {
 	if err := fd.incref(); err != nil {
diff --git a/src/internal/poll/fd_writev_darwin.go b/src/internal/poll/fd_writev_darwin.go
deleted file mode 100644
index b5b8998..0000000
--- a/src/internal/poll/fd_writev_darwin.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build darwin
-
-package poll
-
-import (
-	"syscall"
-	_ "unsafe" // for go:linkname
-)
-
-// Implemented in syscall/syscall_darwin.go.
-//
-//go:linkname writev syscall.writev
-func writev(fd int, iovecs []syscall.Iovec) (uintptr, error)
diff --git a/src/internal/poll/fd_writev_illumos.go b/src/internal/poll/fd_writev_illumos.go
deleted file mode 100644
index 79190c2..0000000
--- a/src/internal/poll/fd_writev_illumos.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build illumos
-
-package poll
-
-import (
-	"internal/syscall/unix"
-	"syscall"
-)
-
-func writev(fd int, iovecs []syscall.Iovec) (uintptr, error) {
-	return unix.Writev(fd, iovecs)
-}
diff --git a/src/internal/poll/fd_writev_libc.go b/src/internal/poll/fd_writev_libc.go
new file mode 100644
index 0000000..0a60473
--- /dev/null
+++ b/src/internal/poll/fd_writev_libc.go
@@ -0,0 +1,15 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || darwin || (openbsd && !mips64) || solaris
+
+package poll
+
+import (
+	"syscall"
+	_ "unsafe" // for go:linkname
+)
+
+//go:linkname writev syscall.writev
+func writev(fd int, iovecs []syscall.Iovec) (uintptr, error)
diff --git a/src/internal/poll/fd_writev_unix.go b/src/internal/poll/fd_writev_unix.go
index aa96d10..005638b 100644
--- a/src/internal/poll/fd_writev_unix.go
+++ b/src/internal/poll/fd_writev_unix.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build dragonfly || freebsd || linux || netbsd || openbsd
+//go:build dragonfly || freebsd || linux || netbsd || (openbsd && mips64)
 
 package poll
 
diff --git a/src/internal/poll/file_plan9.go b/src/internal/poll/file_plan9.go
new file mode 100644
index 0000000..57dc0c6
--- /dev/null
+++ b/src/internal/poll/file_plan9.go
@@ -0,0 +1,42 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package poll
+
+// Expose fdMutex for use by the os package on Plan 9.
+// On Plan 9 we don't want to use async I/O for file operations,
+// but we still want the locking semantics that fdMutex provides.
+
+// FDMutex is an exported fdMutex, only for Plan 9.
+type FDMutex struct {
+	fdmu fdMutex
+}
+
+func (fdmu *FDMutex) Incref() bool {
+	return fdmu.fdmu.incref()
+}
+
+func (fdmu *FDMutex) Decref() bool {
+	return fdmu.fdmu.decref()
+}
+
+func (fdmu *FDMutex) IncrefAndClose() bool {
+	return fdmu.fdmu.increfAndClose()
+}
+
+func (fdmu *FDMutex) ReadLock() bool {
+	return fdmu.fdmu.rwlock(true)
+}
+
+func (fdmu *FDMutex) ReadUnlock() bool {
+	return fdmu.fdmu.rwunlock(true)
+}
+
+func (fdmu *FDMutex) WriteLock() bool {
+	return fdmu.fdmu.rwlock(false)
+}
+
+func (fdmu *FDMutex) WriteUnlock() bool {
+	return fdmu.fdmu.rwunlock(false)
+}
diff --git a/src/internal/poll/iovec_illumos.go b/src/internal/poll/iovec_illumos.go
deleted file mode 100644
index 00a65d7..0000000
--- a/src/internal/poll/iovec_illumos.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build illumos
-
-package poll
-
-import (
-	"syscall"
-	"unsafe"
-)
-
-func newIovecWithBase(base *byte) syscall.Iovec {
-	return syscall.Iovec{Base: (*int8)(unsafe.Pointer(base))}
-}
diff --git a/src/internal/poll/iovec_solaris.go b/src/internal/poll/iovec_solaris.go
new file mode 100644
index 0000000..e68f833
--- /dev/null
+++ b/src/internal/poll/iovec_solaris.go
@@ -0,0 +1,14 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package poll
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+func newIovecWithBase(base *byte) syscall.Iovec {
+	return syscall.Iovec{Base: (*int8)(unsafe.Pointer(base))}
+}
diff --git a/src/internal/poll/iovec_unix.go b/src/internal/poll/iovec_unix.go
index c150084..3f2833e 100644
--- a/src/internal/poll/iovec_unix.go
+++ b/src/internal/poll/iovec_unix.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd
+//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd
 
 package poll
 
diff --git a/src/internal/poll/sendfile_linux.go b/src/internal/poll/sendfile_linux.go
index 6e78523..cc31969 100644
--- a/src/internal/poll/sendfile_linux.go
+++ b/src/internal/poll/sendfile_linux.go
@@ -11,18 +11,21 @@
 const maxSendfileSize int = 4 << 20
 
 // SendFile wraps the sendfile system call.
-func SendFile(dstFD *FD, src int, remain int64) (int64, error) {
+func SendFile(dstFD *FD, src int, remain int64) (int64, error, bool) {
 	if err := dstFD.writeLock(); err != nil {
-		return 0, err
+		return 0, err, false
 	}
 	defer dstFD.writeUnlock()
 	if err := dstFD.pd.prepareWrite(dstFD.isFile); err != nil {
-		return 0, err
+		return 0, err, false
 	}
 
 	dst := dstFD.Sysfd
-	var written int64
-	var err error
+	var (
+		written int64
+		err     error
+		handled = true
+	)
 	for remain > 0 {
 		n := maxSendfileSize
 		if int64(n) > remain {
@@ -48,8 +51,9 @@
 			// support) and syscall.EINVAL (fd types which
 			// don't implement sendfile)
 			err = err1
+			handled = false
 			break
 		}
 	}
-	return written, err
+	return written, err, handled
 }
diff --git a/src/internal/poll/sock_cloexec.go b/src/internal/poll/sock_cloexec.go
index e106b28..f5be2aa 100644
--- a/src/internal/poll/sock_cloexec.go
+++ b/src/internal/poll/sock_cloexec.go
@@ -5,7 +5,7 @@
 // This file implements accept for platforms that provide a fast path for
 // setting SetNonblock and CloseOnExec.
 
-//go:build dragonfly || freebsd || linux || netbsd || openbsd || solaris
+//go:build dragonfly || freebsd || (linux && !arm) || netbsd || openbsd || solaris
 
 package poll
 
@@ -15,36 +15,8 @@
 // descriptor as nonblocking and close-on-exec.
 func accept(s int) (int, syscall.Sockaddr, string, error) {
 	ns, sa, err := Accept4Func(s, syscall.SOCK_NONBLOCK|syscall.SOCK_CLOEXEC)
-	// On Linux the accept4 system call was introduced in 2.6.28
-	// kernel and on FreeBSD it was introduced in 10 kernel. If we
-	// get an ENOSYS error on both Linux and FreeBSD, or EINVAL
-	// error on Linux, fall back to using accept.
-	switch err {
-	case nil:
-		return ns, sa, "", nil
-	default: // errors other than the ones listed
-		return -1, sa, "accept4", err
-	case syscall.ENOSYS: // syscall missing
-	case syscall.EINVAL: // some Linux use this instead of ENOSYS
-	case syscall.EACCES: // some Linux use this instead of ENOSYS
-	case syscall.EFAULT: // some Linux use this instead of ENOSYS
-	}
-
-	// See ../syscall/exec_unix.go for description of ForkLock.
-	// It is probably okay to hold the lock across syscall.Accept
-	// because we have put fd.sysfd into non-blocking mode.
-	// However, a call to the File method will put it back into
-	// blocking mode. We can't take that risk, so no use of ForkLock here.
-	ns, sa, err = AcceptFunc(s)
-	if err == nil {
-		syscall.CloseOnExec(ns)
-	}
 	if err != nil {
-		return -1, nil, "accept", err
-	}
-	if err = syscall.SetNonblock(ns, true); err != nil {
-		CloseFunc(ns)
-		return -1, nil, "setnonblock", err
+		return -1, sa, "accept4", err
 	}
 	return ns, sa, "", nil
 }
diff --git a/src/internal/poll/sock_cloexec_accept.go b/src/internal/poll/sock_cloexec_accept.go
new file mode 100644
index 0000000..4b86de5
--- /dev/null
+++ b/src/internal/poll/sock_cloexec_accept.go
@@ -0,0 +1,51 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements accept for platforms that provide a fast path for
+// setting SetNonblock and CloseOnExec, but don't necessarily have accept4.
+// This is the code we used for accept in Go 1.17 and earlier.
+// On Linux the accept4 system call was introduced in 2.6.28 kernel,
+// and our minimum requirement is 2.6.32, so we simplified the function.
+// Unfortunately, on ARM accept4 wasn't added until 2.6.36, so for ARM
+// only we continue using the older code.
+
+//go:build linux && arm
+
+package poll
+
+import "syscall"
+
+// Wrapper around the accept system call that marks the returned file
+// descriptor as nonblocking and close-on-exec.
+func accept(s int) (int, syscall.Sockaddr, string, error) {
+	ns, sa, err := Accept4Func(s, syscall.SOCK_NONBLOCK|syscall.SOCK_CLOEXEC)
+	switch err {
+	case nil:
+		return ns, sa, "", nil
+	default: // errors other than the ones listed
+		return -1, sa, "accept4", err
+	case syscall.ENOSYS: // syscall missing
+	case syscall.EINVAL: // some Linux use this instead of ENOSYS
+	case syscall.EACCES: // some Linux use this instead of ENOSYS
+	case syscall.EFAULT: // some Linux use this instead of ENOSYS
+	}
+
+	// See ../syscall/exec_unix.go for description of ForkLock.
+	// It is probably okay to hold the lock across syscall.Accept
+	// because we have put fd.sysfd into non-blocking mode.
+	// However, a call to the File method will put it back into
+	// blocking mode. We can't take that risk, so no use of ForkLock here.
+	ns, sa, err = AcceptFunc(s)
+	if err == nil {
+		syscall.CloseOnExec(ns)
+	}
+	if err != nil {
+		return -1, nil, "accept", err
+	}
+	if err = syscall.SetNonblock(ns, true); err != nil {
+		CloseFunc(ns)
+		return -1, nil, "setnonblock", err
+	}
+	return ns, sa, "", nil
+}
diff --git a/src/internal/poll/splice_linux.go b/src/internal/poll/splice_linux.go
index 43eec04..96cbe4a 100644
--- a/src/internal/poll/splice_linux.go
+++ b/src/internal/poll/splice_linux.go
@@ -5,10 +5,8 @@
 package poll
 
 import (
-	"internal/syscall/unix"
 	"runtime"
 	"sync"
-	"sync/atomic"
 	"syscall"
 	"unsafe"
 )
@@ -19,7 +17,9 @@
 
 	// maxSpliceSize is the maximum amount of data Splice asks
 	// the kernel to move in a single call to splice(2).
-	maxSpliceSize = 4 << 20
+	// We use 1MB as Splice writes data through a pipe, and 1MB is the default maximum pipe buffer size,
+	// which is determined by /proc/sys/fs/pipe-max-size.
+	maxSpliceSize = 1 << 20
 )
 
 // Splice transfers at most remain bytes of data from src to dst, using the
@@ -207,40 +207,21 @@
 	splicePipePool.Put(p)
 }
 
-var disableSplice unsafe.Pointer
-
 // newPipe sets up a pipe for a splice operation.
-func newPipe() (sp *splicePipe) {
-	p := (*bool)(atomic.LoadPointer(&disableSplice))
-	if p != nil && *p {
-		return nil
-	}
-
+func newPipe() *splicePipe {
 	var fds [2]int
-	// pipe2 was added in 2.6.27 and our minimum requirement is 2.6.23, so it
-	// might not be implemented. Falling back to pipe is possible, but prior to
-	// 2.6.29 splice returns -EAGAIN instead of 0 when the connection is
-	// closed.
-	const flags = syscall.O_CLOEXEC | syscall.O_NONBLOCK
-	if err := syscall.Pipe2(fds[:], flags); err != nil {
+	if err := syscall.Pipe2(fds[:], syscall.O_CLOEXEC|syscall.O_NONBLOCK); err != nil {
 		return nil
 	}
 
-	sp = &splicePipe{splicePipeFields: splicePipeFields{rfd: fds[0], wfd: fds[1]}}
+	// Splice will loop writing maxSpliceSize bytes from the source to the pipe,
+	// and then write those bytes from the pipe to the destination.
+	// Set the pipe buffer size to maxSpliceSize to optimize that.
+	// Ignore errors here, as a smaller buffer size will work,
+	// although it will require more system calls.
+	fcntl(fds[0], syscall.F_SETPIPE_SZ, maxSpliceSize)
 
-	if p == nil {
-		p = new(bool)
-		defer atomic.StorePointer(&disableSplice, unsafe.Pointer(p))
-
-		// F_GETPIPE_SZ was added in 2.6.35, which does not have the -EAGAIN bug.
-		if _, _, errno := syscall.Syscall(unix.FcntlSyscall, uintptr(fds[0]), syscall.F_GETPIPE_SZ, 0); errno != 0 {
-			*p = true
-			destroyPipe(sp)
-			return nil
-		}
-	}
-
-	return
+	return &splicePipe{splicePipeFields: splicePipeFields{rfd: fds[0], wfd: fds[1]}}
 }
 
 // destroyPipe destroys a pipe.
diff --git a/src/internal/poll/writev.go b/src/internal/poll/writev.go
index cd600b6..75c8b64 100644
--- a/src/internal/poll/writev.go
+++ b/src/internal/poll/writev.go
@@ -2,12 +2,13 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build darwin || dragonfly || freebsd || illumos || linux || netbsd || openbsd
+//go:build unix
 
 package poll
 
 import (
 	"io"
+	"runtime"
 	"syscall"
 )
 
@@ -29,6 +30,10 @@
 	// 1024 and this seems conservative enough for now. Darwin's
 	// UIO_MAXIOV also seems to be 1024.
 	maxVec := 1024
+	if runtime.GOOS == "aix" || runtime.GOOS == "solaris" {
+		// IOV_MAX is set to XOPEN_IOV_MAX on AIX and Solaris.
+		maxVec = 16
+	}
 
 	var n int64
 	var err error
diff --git a/src/internal/profile/encode.go b/src/internal/profile/encode.go
index af31933..77d77f1 100644
--- a/src/internal/profile/encode.go
+++ b/src/internal/profile/encode.go
@@ -175,7 +175,7 @@
 		if err != nil {
 			return err
 		}
-		if *&m.(*Profile).stringTable[0] != "" {
+		if m.(*Profile).stringTable[0] != "" {
 			return errors.New("string_table[0] must be ''")
 		}
 		return nil
diff --git a/src/internal/profile/filter.go b/src/internal/profile/filter.go
index 9cad866..141dd1f 100644
--- a/src/internal/profile/filter.go
+++ b/src/internal/profile/filter.go
@@ -130,8 +130,8 @@
 	return
 }
 
-// focusedTag checks a sample against focus and ignore regexps.
-// Returns whether the focus/ignore regexps match any tags
+// focusedSample checks a sample against focus and ignore regexps.
+// Returns whether the focus/ignore regexps match any tags.
 func focusedSample(s *Sample, focus, ignore TagMatch) (fm, im bool) {
 	fm = focus == nil
 	for key, vals := range s.Label {
diff --git a/src/internal/profile/legacy_profile.go b/src/internal/profile/legacy_profile.go
index fee4209..b102c95 100644
--- a/src/internal/profile/legacy_profile.go
+++ b/src/internal/profile/legacy_profile.go
@@ -192,14 +192,6 @@
 		}
 	}
 
-	// Subtract the offset from the start of the main mapping if it
-	// ends up at a recognizable start address.
-	const expectedStart = 0x400000
-	if m := p.Mapping[0]; m.Start-m.Offset == expectedStart {
-		m.Start = expectedStart
-		m.Offset = 0
-	}
-
 	for _, l := range p.Location {
 		if a := l.Address; a != 0 {
 			for _, m := range p.Mapping {
@@ -730,7 +722,7 @@
 	var l string
 	var err error
 	// Parse text of the form "attribute = value" before the samples.
-	const delimiter = "="
+	const delimiter = '='
 	for {
 		l, err = r.ReadString('\n')
 		if err != nil {
@@ -754,10 +746,13 @@
 			break
 		}
 
-		key, val, ok := strings.Cut(l, delimiter)
-		if !ok {
+		index := strings.IndexByte(l, delimiter)
+		if index < 0 {
 			break
 		}
+		key := l[:index]
+		val := l[index+1:]
+
 		key, val = strings.TrimSpace(key), strings.TrimSpace(val)
 		var err error
 		switch key {
@@ -1031,7 +1026,7 @@
 
 	var attrs []string
 	var r *strings.Replacer
-	const delimiter = "="
+	const delimiter = '='
 	for {
 		l, err := b.ReadString('\n')
 		if err != nil {
@@ -1054,7 +1049,10 @@
 			if err == errUnrecognized {
 				// Recognize assignments of the form: attr=value, and replace
 				// $attr with value on subsequent mappings.
-				if attr, value, ok := strings.Cut(l, delimiter); ok {
+				idx := strings.IndexByte(l, delimiter)
+				if idx >= 0 {
+					attr := l[:idx]
+					value := l[idx+1:]
 					attrs = append(attrs, "$"+strings.TrimSpace(attr), strings.TrimSpace(value))
 					r = strings.NewReplacer(attrs...)
 				}
diff --git a/src/internal/profile/proto.go b/src/internal/profile/proto.go
index 52cf1ef..58ff0ad 100644
--- a/src/internal/profile/proto.go
+++ b/src/internal/profile/proto.go
@@ -136,13 +136,6 @@
 	}
 }
 
-func encodeStringOpt(b *buffer, tag int, x string) {
-	if x == "" {
-		return
-	}
-	encodeString(b, tag, x)
-}
-
 func encodeBool(b *buffer, tag int, x bool) {
 	if x {
 		encodeUint64(b, tag, 1)
@@ -152,7 +145,7 @@
 }
 
 func encodeBoolOpt(b *buffer, tag int, x bool) {
-	if x == false {
+	if !x {
 		return
 	}
 	encodeBool(b, tag, x)
diff --git a/src/internal/profile/proto_test.go b/src/internal/profile/proto_test.go
index c2613fc..46c6d83 100644
--- a/src/internal/profile/proto_test.go
+++ b/src/internal/profile/proto_test.go
@@ -1,3 +1,7 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
 package profile
 
 import (
diff --git a/src/internal/reflectlite/type.go b/src/internal/reflectlite/type.go
index 21e3c12..43440b1 100644
--- a/src/internal/reflectlite/type.go
+++ b/src/internal/reflectlite/type.go
@@ -6,10 +6,7 @@
 // any package except for "runtime" and "unsafe".
 package reflectlite
 
-import (
-	"internal/unsafeheader"
-	"unsafe"
-)
+import "unsafe"
 
 // Type is the representation of a Go type.
 //
@@ -341,27 +338,21 @@
 	}
 }
 
-func (n name) name() (s string) {
+func (n name) name() string {
 	if n.bytes == nil {
-		return
+		return ""
 	}
 	i, l := n.readVarint(1)
-	hdr := (*unsafeheader.String)(unsafe.Pointer(&s))
-	hdr.Data = unsafe.Pointer(n.data(1+i, "non-empty string"))
-	hdr.Len = l
-	return
+	return unsafe.String(n.data(1+i, "non-empty string"), l)
 }
 
-func (n name) tag() (s string) {
+func (n name) tag() string {
 	if !n.hasTag() {
 		return ""
 	}
 	i, l := n.readVarint(1)
 	i2, l2 := n.readVarint(1 + i + l)
-	hdr := (*unsafeheader.String)(unsafe.Pointer(&s))
-	hdr.Data = unsafe.Pointer(n.data(1+i+l+i2, "non-empty string"))
-	hdr.Len = l2
-	return
+	return unsafe.String(n.data(1+i+l+i2, "non-empty string"), l2)
 }
 
 func (n name) pkgPath() string {
diff --git a/src/internal/safefilepath/path.go b/src/internal/safefilepath/path.go
new file mode 100644
index 0000000..0f0a270
--- /dev/null
+++ b/src/internal/safefilepath/path.go
@@ -0,0 +1,21 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package safefilepath manipulates operating-system file paths.
+package safefilepath
+
+import (
+	"errors"
+)
+
+var errInvalidPath = errors.New("invalid path")
+
+// FromFS converts a slash-separated path into an operating-system path.
+//
+// FromFS returns an error if the path cannot be represented by the operating
+// system. For example, paths containing '\' and ':' characters are rejected
+// on Windows.
+func FromFS(path string) (string, error) {
+	return fromFS(path)
+}
diff --git a/src/internal/safefilepath/path_other.go b/src/internal/safefilepath/path_other.go
new file mode 100644
index 0000000..974e775
--- /dev/null
+++ b/src/internal/safefilepath/path_other.go
@@ -0,0 +1,23 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !windows
+
+package safefilepath
+
+import "runtime"
+
+func fromFS(path string) (string, error) {
+	if runtime.GOOS == "plan9" {
+		if len(path) > 0 && path[0] == '#' {
+			return "", errInvalidPath
+		}
+	}
+	for i := range path {
+		if path[i] == 0 {
+			return "", errInvalidPath
+		}
+	}
+	return path, nil
+}
diff --git a/src/internal/safefilepath/path_test.go b/src/internal/safefilepath/path_test.go
new file mode 100644
index 0000000..dc662c1
--- /dev/null
+++ b/src/internal/safefilepath/path_test.go
@@ -0,0 +1,88 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package safefilepath_test
+
+import (
+	"internal/safefilepath"
+	"os"
+	"path/filepath"
+	"runtime"
+	"testing"
+)
+
+type PathTest struct {
+	path, result string
+}
+
+const invalid = ""
+
+var fspathtests = []PathTest{
+	{".", "."},
+	{"/a/b/c", "/a/b/c"},
+	{"a\x00b", invalid},
+}
+
+var winreservedpathtests = []PathTest{
+	{`a\b`, `a\b`},
+	{`a:b`, `a:b`},
+	{`a/b:c`, `a/b:c`},
+	{`NUL`, `NUL`},
+	{`./com1`, `./com1`},
+	{`a/nul/b`, `a/nul/b`},
+}
+
+// Whether a reserved name with an extension is reserved or not varies by
+// Windows version.
+var winreservedextpathtests = []PathTest{
+	{"nul.txt", "nul.txt"},
+	{"a/nul.txt/b", "a/nul.txt/b"},
+}
+
+var plan9reservedpathtests = []PathTest{
+	{`#c`, `#c`},
+}
+
+func TestFromFS(t *testing.T) {
+	switch runtime.GOOS {
+	case "windows":
+		if canWriteFile(t, "NUL") {
+			t.Errorf("can unexpectedly write a file named NUL on Windows")
+		}
+		if canWriteFile(t, "nul.txt") {
+			fspathtests = append(fspathtests, winreservedextpathtests...)
+		} else {
+			winreservedpathtests = append(winreservedpathtests, winreservedextpathtests...)
+		}
+		for i := range winreservedpathtests {
+			winreservedpathtests[i].result = invalid
+		}
+		for i := range fspathtests {
+			fspathtests[i].result = filepath.FromSlash(fspathtests[i].result)
+		}
+	case "plan9":
+		for i := range plan9reservedpathtests {
+			plan9reservedpathtests[i].result = invalid
+		}
+	}
+	tests := fspathtests
+	tests = append(tests, winreservedpathtests...)
+	tests = append(tests, plan9reservedpathtests...)
+	for _, test := range tests {
+		got, err := safefilepath.FromFS(test.path)
+		if (got == "") != (err != nil) {
+			t.Errorf(`FromFS(%q) = %q, %v; want "" only if err != nil`, test.path, got, err)
+		}
+		if got != test.result {
+			t.Errorf("FromFS(%q) = %q, %v; want %q", test.path, got, err, test.result)
+		}
+	}
+}
+
+func canWriteFile(t *testing.T, name string) bool {
+	path := filepath.Join(t.TempDir(), name)
+	os.WriteFile(path, []byte("ok"), 0666)
+	b, _ := os.ReadFile(path)
+	return string(b) == "ok"
+}
diff --git a/src/internal/safefilepath/path_windows.go b/src/internal/safefilepath/path_windows.go
new file mode 100644
index 0000000..909c150
--- /dev/null
+++ b/src/internal/safefilepath/path_windows.go
@@ -0,0 +1,95 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package safefilepath
+
+import (
+	"syscall"
+	"unicode/utf8"
+)
+
+func fromFS(path string) (string, error) {
+	if !utf8.ValidString(path) {
+		return "", errInvalidPath
+	}
+	for len(path) > 1 && path[0] == '/' && path[1] == '/' {
+		path = path[1:]
+	}
+	containsSlash := false
+	for p := path; p != ""; {
+		// Find the next path element.
+		i := 0
+		dot := -1
+		for i < len(p) && p[i] != '/' {
+			switch p[i] {
+			case 0, '\\', ':':
+				return "", errInvalidPath
+			case '.':
+				if dot < 0 {
+					dot = i
+				}
+			}
+			i++
+		}
+		part := p[:i]
+		if i < len(p) {
+			containsSlash = true
+			p = p[i+1:]
+		} else {
+			p = ""
+		}
+		// Trim the extension and look for a reserved name.
+		base := part
+		if dot >= 0 {
+			base = part[:dot]
+		}
+		if isReservedName(base) {
+			if dot < 0 {
+				return "", errInvalidPath
+			}
+			// The path element is a reserved name with an extension.
+			// Some Windows versions consider this a reserved name,
+			// while others do not. Use FullPath to see if the name is
+			// reserved.
+			if p, _ := syscall.FullPath(part); len(p) >= 4 && p[:4] == `\\.\` {
+				return "", errInvalidPath
+			}
+		}
+	}
+	if containsSlash {
+		// We can't depend on strings, so substitute \ for / manually.
+		buf := []byte(path)
+		for i, b := range buf {
+			if b == '/' {
+				buf[i] = '\\'
+			}
+		}
+		path = string(buf)
+	}
+	return path, nil
+}
+
+// isReservedName reports if name is a Windows reserved device name.
+// It does not detect names with an extension, which are also reserved on some Windows versions.
+//
+// For details, search for PRN in
+// https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file.
+func isReservedName(name string) bool {
+	if 3 <= len(name) && len(name) <= 4 {
+		switch string([]byte{toUpper(name[0]), toUpper(name[1]), toUpper(name[2])}) {
+		case "CON", "PRN", "AUX", "NUL":
+			return len(name) == 3
+		case "COM", "LPT":
+			return len(name) == 4 && '1' <= name[3] && name[3] <= '9'
+		}
+	}
+	return false
+}
+
+func toUpper(c byte) byte {
+	if 'a' <= c && c <= 'z' {
+		return c - ('a' - 'A')
+	}
+	return c
+}
diff --git a/src/internal/saferio/io.go b/src/internal/saferio/io.go
new file mode 100644
index 0000000..66cc044
--- /dev/null
+++ b/src/internal/saferio/io.go
@@ -0,0 +1,135 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package saferio provides I/O functions that avoid allocating large
+// amounts of memory unnecessarily. This is intended for packages that
+// read data from an [io.Reader] where the size is part of the input
+// data but the input may be corrupt, or may be provided by an
+// untrustworthy attacker.
+package saferio
+
+import (
+	"io"
+	"reflect"
+)
+
+// chunk is an arbitrary limit on how much memory we are willing
+// to allocate without concern.
+const chunk = 10 << 20 // 10M
+
+// ReadData reads n bytes from the input stream, but avoids allocating
+// all n bytes if n is large. This avoids crashing the program by
+// allocating all n bytes in cases where n is incorrect.
+//
+// The error is io.EOF only if no bytes were read.
+// If an io.EOF happens after reading some but not all the bytes,
+// ReadData returns io.ErrUnexpectedEOF.
+func ReadData(r io.Reader, n uint64) ([]byte, error) {
+	if int64(n) < 0 || n != uint64(int(n)) {
+		// n is too large to fit in int, so we can't allocate
+		// a buffer large enough. Treat this as a read failure.
+		return nil, io.ErrUnexpectedEOF
+	}
+
+	if n < chunk {
+		buf := make([]byte, n)
+		_, err := io.ReadFull(r, buf)
+		if err != nil {
+			return nil, err
+		}
+		return buf, nil
+	}
+
+	var buf []byte
+	buf1 := make([]byte, chunk)
+	for n > 0 {
+		next := n
+		if next > chunk {
+			next = chunk
+		}
+		_, err := io.ReadFull(r, buf1[:next])
+		if err != nil {
+			if len(buf) > 0 && err == io.EOF {
+				err = io.ErrUnexpectedEOF
+			}
+			return nil, err
+		}
+		buf = append(buf, buf1[:next]...)
+		n -= next
+	}
+	return buf, nil
+}
+
+// ReadDataAt reads n bytes from the input stream at off, but avoids
+// allocating all n bytes if n is large. This avoids crashing the program
+// by allocating all n bytes in cases where n is incorrect.
+func ReadDataAt(r io.ReaderAt, n uint64, off int64) ([]byte, error) {
+	if int64(n) < 0 || n != uint64(int(n)) {
+		// n is too large to fit in int, so we can't allocate
+		// a buffer large enough. Treat this as a read failure.
+		return nil, io.ErrUnexpectedEOF
+	}
+
+	if n < chunk {
+		buf := make([]byte, n)
+		_, err := r.ReadAt(buf, off)
+		if err != nil {
+			// io.SectionReader can return EOF for n == 0,
+			// but for our purposes that is a success.
+			if err != io.EOF || n > 0 {
+				return nil, err
+			}
+		}
+		return buf, nil
+	}
+
+	var buf []byte
+	buf1 := make([]byte, chunk)
+	for n > 0 {
+		next := n
+		if next > chunk {
+			next = chunk
+		}
+		_, err := r.ReadAt(buf1[:next], off)
+		if err != nil {
+			return nil, err
+		}
+		buf = append(buf, buf1[:next]...)
+		n -= next
+		off += int64(next)
+	}
+	return buf, nil
+}
+
+// SliceCap returns the capacity to use when allocating a slice.
+// After the slice is allocated with the capacity, it should be
+// built using append. This will avoid allocating too much memory
+// if the capacity is large and incorrect.
+//
+// A negative result means that the value is always too big.
+//
+// The element type is described by passing a pointer to a value of that type.
+// This would ideally use generics, but this code is built with
+// the bootstrap compiler which need not support generics.
+// We use a pointer so that we can handle slices of interface type.
+func SliceCap(v any, c uint64) int {
+	if int64(c) < 0 || c != uint64(int(c)) {
+		return -1
+	}
+	typ := reflect.TypeOf(v)
+	if typ.Kind() != reflect.Ptr {
+		panic("SliceCap called with non-pointer type")
+	}
+	size := uint64(typ.Elem().Size())
+	if size > 0 && c > (1<<64-1)/size {
+		return -1
+	}
+	if c*size > chunk {
+		c = uint64(chunk / size)
+		if c == 0 {
+			c = 1
+		}
+	}
+	return int(c)
+}
diff --git a/src/internal/saferio/io_test.go b/src/internal/saferio/io_test.go
new file mode 100644
index 0000000..356c9eb
--- /dev/null
+++ b/src/internal/saferio/io_test.go
@@ -0,0 +1,136 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package saferio
+
+import (
+	"bytes"
+	"io"
+	"testing"
+)
+
+func TestReadData(t *testing.T) {
+	const count = 100
+	input := bytes.Repeat([]byte{'a'}, count)
+
+	t.Run("small", func(t *testing.T) {
+		got, err := ReadData(bytes.NewReader(input), count)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if !bytes.Equal(got, input) {
+			t.Errorf("got %v, want %v", got, input)
+		}
+	})
+
+	t.Run("large", func(t *testing.T) {
+		_, err := ReadData(bytes.NewReader(input), 10<<30)
+		if err == nil {
+			t.Error("large read succeeded unexpectedly")
+		}
+	})
+
+	t.Run("maxint", func(t *testing.T) {
+		_, err := ReadData(bytes.NewReader(input), 1<<62)
+		if err == nil {
+			t.Error("large read succeeded unexpectedly")
+		}
+	})
+
+	t.Run("small-EOF", func(t *testing.T) {
+		_, err := ReadData(bytes.NewReader(nil), chunk-1)
+		if err != io.EOF {
+			t.Errorf("ReadData = %v, want io.EOF", err)
+		}
+	})
+
+	t.Run("large-EOF", func(t *testing.T) {
+		_, err := ReadData(bytes.NewReader(nil), chunk+1)
+		if err != io.EOF {
+			t.Errorf("ReadData = %v, want io.EOF", err)
+		}
+	})
+
+	t.Run("large-UnexpectedEOF", func(t *testing.T) {
+		_, err := ReadData(bytes.NewReader(make([]byte, chunk)), chunk+1)
+		if err != io.ErrUnexpectedEOF {
+			t.Errorf("ReadData = %v, want io.ErrUnexpectedEOF", err)
+		}
+	})
+}
+
+func TestReadDataAt(t *testing.T) {
+	const count = 100
+	input := bytes.Repeat([]byte{'a'}, count)
+
+	t.Run("small", func(t *testing.T) {
+		got, err := ReadDataAt(bytes.NewReader(input), count, 0)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if !bytes.Equal(got, input) {
+			t.Errorf("got %v, want %v", got, input)
+		}
+	})
+
+	t.Run("large", func(t *testing.T) {
+		_, err := ReadDataAt(bytes.NewReader(input), 10<<30, 0)
+		if err == nil {
+			t.Error("large read succeeded unexpectedly")
+		}
+	})
+
+	t.Run("maxint", func(t *testing.T) {
+		_, err := ReadDataAt(bytes.NewReader(input), 1<<62, 0)
+		if err == nil {
+			t.Error("large read succeeded unexpectedly")
+		}
+	})
+
+	t.Run("SectionReader", func(t *testing.T) {
+		// Reading 0 bytes from an io.SectionReader at the end
+		// of the section will return EOF, but ReadDataAt
+		// should succeed and return 0 bytes.
+		sr := io.NewSectionReader(bytes.NewReader(input), 0, 0)
+		got, err := ReadDataAt(sr, 0, 0)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if len(got) > 0 {
+			t.Errorf("got %d bytes, expected 0", len(got))
+		}
+	})
+}
+
+func TestSliceCap(t *testing.T) {
+	t.Run("small", func(t *testing.T) {
+		c := SliceCap((*int)(nil), 10)
+		if c != 10 {
+			t.Errorf("got capacity %d, want %d", c, 10)
+		}
+	})
+
+	t.Run("large", func(t *testing.T) {
+		c := SliceCap((*byte)(nil), 1<<30)
+		if c < 0 {
+			t.Error("SliceCap failed unexpectedly")
+		} else if c == 1<<30 {
+			t.Errorf("got capacity %d which is too high", c)
+		}
+	})
+
+	t.Run("maxint", func(t *testing.T) {
+		c := SliceCap((*byte)(nil), 1<<63)
+		if c >= 0 {
+			t.Errorf("SliceCap returned %d, expected failure", c)
+		}
+	})
+
+	t.Run("overflow", func(t *testing.T) {
+		c := SliceCap((*int64)(nil), 1<<62)
+		if c >= 0 {
+			t.Errorf("SliceCap returned %d, expected failure", c)
+		}
+	})
+}
diff --git a/src/internal/singleflight/singleflight.go b/src/internal/singleflight/singleflight.go
index 07b3f40..d0e6d2f 100644
--- a/src/internal/singleflight/singleflight.go
+++ b/src/internal/singleflight/singleflight.go
@@ -65,10 +65,8 @@
 }
 
 // DoChan is like Do but returns a channel that will receive the
-// results when they are ready. The second result is true if the function
-// will eventually be called, false if it will not (because there is
-// a pending request with this key).
-func (g *Group) DoChan(key string, fn func() (any, error)) (<-chan Result, bool) {
+// results when they are ready.
+func (g *Group) DoChan(key string, fn func() (any, error)) <-chan Result {
 	ch := make(chan Result, 1)
 	g.mu.Lock()
 	if g.m == nil {
@@ -78,7 +76,7 @@
 		c.dups++
 		c.chans = append(c.chans, ch)
 		g.mu.Unlock()
-		return ch, false
+		return ch
 	}
 	c := &call{chans: []chan<- Result{ch}}
 	c.wg.Add(1)
@@ -87,16 +85,18 @@
 
 	go g.doCall(c, key, fn)
 
-	return ch, true
+	return ch
 }
 
 // doCall handles the single call for a key.
 func (g *Group) doCall(c *call, key string, fn func() (any, error)) {
 	c.val, c.err = fn()
-	c.wg.Done()
 
 	g.mu.Lock()
-	delete(g.m, key)
+	c.wg.Done()
+	if g.m[key] == c {
+		delete(g.m, key)
+	}
 	for _, ch := range c.chans {
 		ch <- Result{c.val, c.err, c.dups > 0}
 	}
diff --git a/src/internal/singleflight/singleflight_test.go b/src/internal/singleflight/singleflight_test.go
index c231037..a13893d 100644
--- a/src/internal/singleflight/singleflight_test.go
+++ b/src/internal/singleflight/singleflight_test.go
@@ -44,9 +44,9 @@
 	var g Group
 	var wg1, wg2 sync.WaitGroup
 	c := make(chan string, 1)
-	var calls int32
+	var calls atomic.Int32
 	fn := func() (any, error) {
-		if atomic.AddInt32(&calls, 1) == 1 {
+		if calls.Add(1) == 1 {
 			// First invocation.
 			wg1.Done()
 		}
@@ -81,7 +81,106 @@
 	// least reached the line before the Do.
 	c <- "bar"
 	wg2.Wait()
-	if got := atomic.LoadInt32(&calls); got <= 0 || got >= n {
+	if got := calls.Load(); got <= 0 || got >= n {
 		t.Errorf("number of calls = %d; want over 0 and less than %d", got, n)
 	}
 }
+
+func TestForgetUnshared(t *testing.T) {
+	var g Group
+
+	var firstStarted, firstFinished sync.WaitGroup
+
+	firstStarted.Add(1)
+	firstFinished.Add(1)
+
+	key := "key"
+	firstCh := make(chan struct{})
+	go func() {
+		g.Do(key, func() (i interface{}, e error) {
+			firstStarted.Done()
+			<-firstCh
+			firstFinished.Done()
+			return
+		})
+	}()
+
+	firstStarted.Wait()
+	g.ForgetUnshared(key) // from this point no two function using same key should be executed concurrently
+
+	secondCh := make(chan struct{})
+	go func() {
+		g.Do(key, func() (i interface{}, e error) {
+			// Notify that we started
+			secondCh <- struct{}{}
+			<-secondCh
+			return 2, nil
+		})
+	}()
+
+	<-secondCh
+
+	resultCh := g.DoChan(key, func() (i interface{}, e error) {
+		panic("third must not be started")
+	})
+
+	if g.ForgetUnshared(key) {
+		t.Errorf("Before first goroutine finished, key %q is shared, should return false", key)
+	}
+
+	close(firstCh)
+	firstFinished.Wait()
+
+	if g.ForgetUnshared(key) {
+		t.Errorf("After first goroutine finished, key %q is still shared, should return false", key)
+	}
+
+	secondCh <- struct{}{}
+
+	if result := <-resultCh; result.Val != 2 {
+		t.Errorf("We should receive result produced by second call, expected: 2, got %d", result.Val)
+	}
+}
+
+func TestDoAndForgetUnsharedRace(t *testing.T) {
+	t.Parallel()
+
+	var g Group
+	key := "key"
+	d := time.Millisecond
+	for {
+		var calls, shared atomic.Int64
+		const n = 1000
+		var wg sync.WaitGroup
+		wg.Add(n)
+		for i := 0; i < n; i++ {
+			go func() {
+				g.Do(key, func() (interface{}, error) {
+					time.Sleep(d)
+					return calls.Add(1), nil
+				})
+				if !g.ForgetUnshared(key) {
+					shared.Add(1)
+				}
+				wg.Done()
+			}()
+		}
+		wg.Wait()
+
+		if calls.Load() != 1 {
+			// The goroutines didn't park in g.Do in time,
+			// so the key was re-added and may have been shared after the call.
+			// Try again with more time to park.
+			d *= 2
+			continue
+		}
+
+		// All of the Do calls ended up sharing the first
+		// invocation, so the key should have been unused
+		// (and therefore unshared) when they returned.
+		if shared.Load() > 0 {
+			t.Errorf("after a single shared Do, ForgetUnshared returned false %d times", shared.Load())
+		}
+		break
+	}
+}
diff --git a/src/internal/syscall/unix/asm_darwin.s b/src/internal/syscall/unix/asm_darwin.s
index 8fbdc1d..8662c28 100644
--- a/src/internal/syscall/unix/asm_darwin.s
+++ b/src/internal/syscall/unix/asm_darwin.s
@@ -4,5 +4,21 @@
 
 #include "textflag.h"
 
-TEXT ·libc_getentropy_trampoline(SB),NOSPLIT,$0-0
-	JMP	libc_getentropy(SB)
+TEXT ·libc_getentropy_trampoline(SB),NOSPLIT,$0-0; JMP libc_getentropy(SB)
+TEXT ·libc_getaddrinfo_trampoline(SB),NOSPLIT,$0-0; JMP libc_getaddrinfo(SB)
+TEXT ·libc_freeaddrinfo_trampoline(SB),NOSPLIT,$0-0; JMP libc_freeaddrinfo(SB)
+TEXT ·libc_getnameinfo_trampoline(SB),NOSPLIT,$0-0; JMP libc_getnameinfo(SB)
+TEXT ·libc_gai_strerror_trampoline(SB),NOSPLIT,$0-0; JMP libc_gai_strerror(SB)
+TEXT ·libresolv_res_9_ninit_trampoline(SB),NOSPLIT,$0-0; JMP libresolv_res_9_ninit(SB)
+TEXT ·libresolv_res_9_nclose_trampoline(SB),NOSPLIT,$0-0; JMP libresolv_res_9_nclose(SB)
+TEXT ·libresolv_res_9_nsearch_trampoline(SB),NOSPLIT,$0-0; JMP libresolv_res_9_nsearch(SB)
+TEXT ·libc_grantpt_trampoline(SB),NOSPLIT,$0-0; JMP libc_grantpt(SB)
+TEXT ·libc_unlockpt_trampoline(SB),NOSPLIT,$0-0; JMP libc_unlockpt(SB)
+TEXT ·libc_ptsname_r_trampoline(SB),NOSPLIT,$0-0; JMP libc_ptsname_r(SB)
+TEXT ·libc_posix_openpt_trampoline(SB),NOSPLIT,$0-0; JMP libc_posix_openpt(SB)
+TEXT ·libc_getgrouplist_trampoline(SB),NOSPLIT,$0-0; JMP libc_getgrouplist(SB)
+TEXT ·libc_getpwnam_r_trampoline(SB),NOSPLIT,$0-0; JMP libc_getpwnam_r(SB)
+TEXT ·libc_getpwuid_r_trampoline(SB),NOSPLIT,$0-0; JMP libc_getpwuid_r(SB)
+TEXT ·libc_getgrnam_r_trampoline(SB),NOSPLIT,$0-0; JMP libc_getgrnam_r(SB)
+TEXT ·libc_getgrgid_r_trampoline(SB),NOSPLIT,$0-0; JMP libc_getgrgid_r(SB)
+TEXT ·libc_sysconf_trampoline(SB),NOSPLIT,$0-0; JMP libc_sysconf(SB)
diff --git a/src/internal/syscall/unix/at.go b/src/internal/syscall/unix/at.go
index 965162e..cfb6e41 100644
--- a/src/internal/syscall/unix/at.go
+++ b/src/internal/syscall/unix/at.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build linux || openbsd || netbsd || dragonfly
+//go:build dragonfly || freebsd || linux || netbsd || (openbsd && mips64)
 
 package unix
 
@@ -12,7 +12,6 @@
 )
 
 func Unlinkat(dirfd int, path string, flags int) error {
-	var p *byte
 	p, err := syscall.BytePtrFromString(path)
 	if err != nil {
 		return err
@@ -27,7 +26,6 @@
 }
 
 func Openat(dirfd int, path string, flags int, perm uint32) (int, error) {
-	var p *byte
 	p, err := syscall.BytePtrFromString(path)
 	if err != nil {
 		return 0, err
diff --git a/src/internal/syscall/unix/at_darwin.go b/src/internal/syscall/unix/at_darwin.go
deleted file mode 100644
index a88a27e..0000000
--- a/src/internal/syscall/unix/at_darwin.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package unix
-
-import (
-	"syscall"
-	_ "unsafe" // for linkname
-)
-
-func Unlinkat(dirfd int, path string, flags int) error {
-	return unlinkat(dirfd, path, flags)
-}
-
-func Openat(dirfd int, path string, flags int, perm uint32) (int, error) {
-	return openat(dirfd, path, flags, perm)
-}
-
-func Fstatat(dirfd int, path string, stat *syscall.Stat_t, flags int) error {
-	return fstatat(dirfd, path, stat, flags)
-}
-
-//go:linkname unlinkat syscall.unlinkat
-func unlinkat(dirfd int, path string, flags int) error
-
-//go:linkname openat syscall.openat
-func openat(dirfd int, path string, flags int, perm uint32) (int, error)
-
-//go:linkname fstatat syscall.fstatat
-func fstatat(dirfd int, path string, stat *syscall.Stat_t, flags int) error
diff --git a/src/internal/syscall/unix/at_freebsd.go b/src/internal/syscall/unix/at_freebsd.go
deleted file mode 100644
index e171f4d..0000000
--- a/src/internal/syscall/unix/at_freebsd.go
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package unix
-
-import (
-	"syscall"
-	"unsafe"
-)
-
-const (
-	AT_REMOVEDIR        = 0x800
-	AT_SYMLINK_NOFOLLOW = 0x200
-)
-
-func Unlinkat(dirfd int, path string, flags int) error {
-	p, err := syscall.BytePtrFromString(path)
-	if err != nil {
-		return err
-	}
-
-	_, _, errno := syscall.Syscall(syscall.SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(p)), uintptr(flags))
-	if errno != 0 {
-		return errno
-	}
-
-	return nil
-}
-
-func Openat(dirfd int, path string, flags int, perm uint32) (int, error) {
-	p, err := syscall.BytePtrFromString(path)
-	if err != nil {
-		return 0, err
-	}
-
-	fd, _, errno := syscall.Syscall6(syscall.SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(p)), uintptr(flags), uintptr(perm), 0, 0)
-	if errno != 0 {
-		return 0, errno
-	}
-
-	return int(fd), nil
-}
-
-func Fstatat(dirfd int, path string, stat *syscall.Stat_t, flags int) error {
-	return syscall.Fstatat(dirfd, path, stat, flags)
-}
diff --git a/src/internal/syscall/unix/at_fstatat.go b/src/internal/syscall/unix/at_fstatat.go
index 25318d2..8f25fe9 100644
--- a/src/internal/syscall/unix/at_fstatat.go
+++ b/src/internal/syscall/unix/at_fstatat.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build (linux && !loong64) || openbsd || netbsd || dragonfly
+//go:build dragonfly || (linux && !loong64) || netbsd || (openbsd && mips64)
 
 package unix
 
diff --git a/src/internal/syscall/unix/at_fstatat2.go b/src/internal/syscall/unix/at_fstatat2.go
new file mode 100644
index 0000000..8d20e1a
--- /dev/null
+++ b/src/internal/syscall/unix/at_fstatat2.go
@@ -0,0 +1,13 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build freebsd || (linux && loong64)
+
+package unix
+
+import "syscall"
+
+func Fstatat(dirfd int, path string, stat *syscall.Stat_t, flags int) error {
+	return syscall.Fstatat(dirfd, path, stat, flags)
+}
diff --git a/src/internal/syscall/unix/at_libc2.go b/src/internal/syscall/unix/at_libc2.go
new file mode 100644
index 0000000..93d0cf4
--- /dev/null
+++ b/src/internal/syscall/unix/at_libc2.go
@@ -0,0 +1,33 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build darwin || (openbsd && !mips64)
+
+package unix
+
+import (
+	"syscall"
+	_ "unsafe" // for linkname
+)
+
+func Unlinkat(dirfd int, path string, flags int) error {
+	return unlinkat(dirfd, path, flags)
+}
+
+func Openat(dirfd int, path string, flags int, perm uint32) (int, error) {
+	return openat(dirfd, path, flags, perm)
+}
+
+func Fstatat(dirfd int, path string, stat *syscall.Stat_t, flags int) error {
+	return fstatat(dirfd, path, stat, flags)
+}
+
+//go:linkname unlinkat syscall.unlinkat
+func unlinkat(dirfd int, path string, flags int) error
+
+//go:linkname openat syscall.openat
+func openat(dirfd int, path string, flags int, perm uint32) (int, error)
+
+//go:linkname fstatat syscall.fstatat
+func fstatat(dirfd int, path string, stat *syscall.Stat_t, flags int) error
diff --git a/src/internal/syscall/unix/at_statx.go b/src/internal/syscall/unix/at_statx.go
deleted file mode 100644
index 230d697..0000000
--- a/src/internal/syscall/unix/at_statx.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build linux && loong64
-
-package unix
-
-import (
-	"syscall"
-)
-
-func Fstatat(dirfd int, path string, stat *syscall.Stat_t, flags int) error {
-	return syscall.Fstatat(dirfd, path, stat, flags)
-}
diff --git a/src/internal/syscall/unix/at_sysnum_freebsd.go b/src/internal/syscall/unix/at_sysnum_freebsd.go
new file mode 100644
index 0000000..adfbbcb
--- /dev/null
+++ b/src/internal/syscall/unix/at_sysnum_freebsd.go
@@ -0,0 +1,15 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package unix
+
+import "syscall"
+
+const (
+	AT_REMOVEDIR        = 0x800
+	AT_SYMLINK_NOFOLLOW = 0x200
+
+	unlinkatTrap uintptr = syscall.SYS_UNLINKAT
+	openatTrap   uintptr = syscall.SYS_OPENAT
+)
diff --git a/src/internal/syscall/unix/at_sysnum_linux.go b/src/internal/syscall/unix/at_sysnum_linux.go
index fa7cd75..b9b8495 100644
--- a/src/internal/syscall/unix/at_sysnum_linux.go
+++ b/src/internal/syscall/unix/at_sysnum_linux.go
@@ -9,5 +9,9 @@
 const unlinkatTrap uintptr = syscall.SYS_UNLINKAT
 const openatTrap uintptr = syscall.SYS_OPENAT
 
-const AT_REMOVEDIR = 0x200
-const AT_SYMLINK_NOFOLLOW = 0x100
+const (
+	AT_EACCESS          = 0x200
+	AT_FDCWD            = -0x64
+	AT_REMOVEDIR        = 0x200
+	AT_SYMLINK_NOFOLLOW = 0x100
+)
diff --git a/src/internal/syscall/unix/constants.go b/src/internal/syscall/unix/constants.go
new file mode 100644
index 0000000..e324589
--- /dev/null
+++ b/src/internal/syscall/unix/constants.go
@@ -0,0 +1,13 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build unix
+
+package unix
+
+const (
+	R_OK = 0x4
+	W_OK = 0x2
+	X_OK = 0x1
+)
diff --git a/src/internal/syscall/unix/eaccess_linux.go b/src/internal/syscall/unix/eaccess_linux.go
new file mode 100644
index 0000000..5695a5e
--- /dev/null
+++ b/src/internal/syscall/unix/eaccess_linux.go
@@ -0,0 +1,11 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package unix
+
+import "syscall"
+
+func Eaccess(path string, mode uint32) error {
+	return syscall.Faccessat(AT_FDCWD, path, mode, AT_EACCESS)
+}
diff --git a/src/internal/syscall/unix/eaccess_other.go b/src/internal/syscall/unix/eaccess_other.go
new file mode 100644
index 0000000..23be118
--- /dev/null
+++ b/src/internal/syscall/unix/eaccess_other.go
@@ -0,0 +1,13 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build unix && !linux
+
+package unix
+
+import "syscall"
+
+func Eaccess(path string, mode uint32) error {
+	return syscall.ENOSYS
+}
diff --git a/src/internal/syscall/unix/getentropy_darwin.go b/src/internal/syscall/unix/getentropy_darwin.go
index 7bab1f2..834099f 100644
--- a/src/internal/syscall/unix/getentropy_darwin.go
+++ b/src/internal/syscall/unix/getentropy_darwin.go
@@ -8,7 +8,6 @@
 
 import (
 	"internal/abi"
-	"syscall"
 	"unsafe"
 )
 
@@ -27,6 +26,3 @@
 	}
 	return nil
 }
-
-//go:linkname syscall_syscall syscall.syscall
-func syscall_syscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)
diff --git a/src/internal/syscall/unix/getentropy_openbsd.go b/src/internal/syscall/unix/getentropy_openbsd.go
index d5caa80..ad0914d 100644
--- a/src/internal/syscall/unix/getentropy_openbsd.go
+++ b/src/internal/syscall/unix/getentropy_openbsd.go
@@ -1,25 +1,17 @@
-// Copyright 2016 The Go Authors. All rights reserved.
+// Copyright 2022 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build openbsd && !mips64
+
 package unix
 
-import (
-	"syscall"
-	"unsafe"
-)
-
-// getentropy(2)'s syscall number, from /usr/src/sys/kern/syscalls.master
-const entropyTrap uintptr = 7
+import _ "unsafe" // for linkname
 
 // GetEntropy calls the OpenBSD getentropy system call.
 func GetEntropy(p []byte) error {
-	_, _, errno := syscall.Syscall(entropyTrap,
-		uintptr(unsafe.Pointer(&p[0])),
-		uintptr(len(p)),
-		0)
-	if errno != 0 {
-		return errno
-	}
-	return nil
+	return getentropy(p)
 }
+
+//go:linkname getentropy syscall.getentropy
+func getentropy(p []byte) error
diff --git a/src/internal/syscall/unix/getentropy_openbsd_mips64.go b/src/internal/syscall/unix/getentropy_openbsd_mips64.go
new file mode 100644
index 0000000..d5caa80
--- /dev/null
+++ b/src/internal/syscall/unix/getentropy_openbsd_mips64.go
@@ -0,0 +1,25 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package unix
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+// getentropy(2)'s syscall number, from /usr/src/sys/kern/syscalls.master
+const entropyTrap uintptr = 7
+
+// GetEntropy calls the OpenBSD getentropy system call.
+func GetEntropy(p []byte) error {
+	_, _, errno := syscall.Syscall(entropyTrap,
+		uintptr(unsafe.Pointer(&p[0])),
+		uintptr(len(p)),
+		0)
+	if errno != 0 {
+		return errno
+	}
+	return nil
+}
diff --git a/src/internal/syscall/unix/kernel_version_linux.go b/src/internal/syscall/unix/kernel_version_linux.go
new file mode 100644
index 0000000..71e8aa4
--- /dev/null
+++ b/src/internal/syscall/unix/kernel_version_linux.go
@@ -0,0 +1,42 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package unix
+
+import (
+	"syscall"
+)
+
+// KernelVersion returns major and minor kernel version numbers, parsed from
+// the syscall.Uname's Release field, or 0, 0 if the version can't be obtained
+// or parsed.
+//
+// Currently only implemented for Linux.
+func KernelVersion() (major, minor int) {
+	var uname syscall.Utsname
+	if err := syscall.Uname(&uname); err != nil {
+		return
+	}
+
+	var (
+		values    [2]int
+		value, vi int
+	)
+	for _, c := range uname.Release {
+		if '0' <= c && c <= '9' {
+			value = (value * 10) + int(c-'0')
+		} else {
+			// Note that we're assuming N.N.N here.
+			// If we see anything else, we are likely to mis-parse it.
+			values[vi] = value
+			vi++
+			if vi >= len(values) {
+				break
+			}
+			value = 0
+		}
+	}
+
+	return values[0], values[1]
+}
diff --git a/src/internal/syscall/unix/kernel_version_other.go b/src/internal/syscall/unix/kernel_version_other.go
new file mode 100644
index 0000000..00af9f2
--- /dev/null
+++ b/src/internal/syscall/unix/kernel_version_other.go
@@ -0,0 +1,11 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !linux
+
+package unix
+
+func KernelVersion() (major int, minor int) {
+	return 0, 0
+}
diff --git a/src/internal/syscall/unix/net_darwin.go b/src/internal/syscall/unix/net_darwin.go
new file mode 100644
index 0000000..b9da4f1
--- /dev/null
+++ b/src/internal/syscall/unix/net_darwin.go
@@ -0,0 +1,161 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package unix
+
+import (
+	"internal/abi"
+	"syscall"
+	"unsafe"
+)
+
+const (
+	AI_CANONNAME = 0x2
+	AI_ALL       = 0x100
+	AI_V4MAPPED  = 0x800
+	AI_MASK      = 0x1407
+
+	EAI_AGAIN    = 2
+	EAI_NONAME   = 8
+	EAI_SYSTEM   = 11
+	EAI_OVERFLOW = 14
+
+	NI_NAMEREQD = 4
+)
+
+type Addrinfo struct {
+	Flags     int32
+	Family    int32
+	Socktype  int32
+	Protocol  int32
+	Addrlen   uint32
+	Canonname *byte
+	Addr      *syscall.RawSockaddr
+	Next      *Addrinfo
+}
+
+//go:cgo_ldflag "-lresolv"
+
+//go:cgo_import_dynamic libc_getaddrinfo getaddrinfo "/usr/lib/libSystem.B.dylib"
+func libc_getaddrinfo_trampoline()
+
+func Getaddrinfo(hostname, servname *byte, hints *Addrinfo, res **Addrinfo) (int, error) {
+	gerrno, _, errno := syscall_syscall6(abi.FuncPCABI0(libc_getaddrinfo_trampoline),
+		uintptr(unsafe.Pointer(hostname)),
+		uintptr(unsafe.Pointer(servname)),
+		uintptr(unsafe.Pointer(hints)),
+		uintptr(unsafe.Pointer(res)),
+		0,
+		0)
+	var err error
+	if errno != 0 {
+		err = errno
+	}
+	return int(gerrno), err
+}
+
+//go:cgo_import_dynamic libc_freeaddrinfo freeaddrinfo "/usr/lib/libSystem.B.dylib"
+func libc_freeaddrinfo_trampoline()
+
+func Freeaddrinfo(ai *Addrinfo) {
+	syscall_syscall6(abi.FuncPCABI0(libc_freeaddrinfo_trampoline),
+		uintptr(unsafe.Pointer(ai)),
+		0, 0, 0, 0, 0)
+}
+
+//go:cgo_import_dynamic libc_getnameinfo getnameinfo "/usr/lib/libSystem.B.dylib"
+func libc_getnameinfo_trampoline()
+
+func Getnameinfo(sa *syscall.RawSockaddr, salen int, host *byte, hostlen int, serv *byte, servlen int, flags int) (int, error) {
+	gerrno, _, errno := syscall_syscall9(abi.FuncPCABI0(libc_getnameinfo_trampoline),
+		uintptr(unsafe.Pointer(sa)),
+		uintptr(salen),
+		uintptr(unsafe.Pointer(host)),
+		uintptr(hostlen),
+		uintptr(unsafe.Pointer(serv)),
+		uintptr(servlen),
+		uintptr(flags),
+		0,
+		0)
+	var err error
+	if errno != 0 {
+		err = errno
+	}
+	return int(gerrno), err
+}
+
+//go:cgo_import_dynamic libc_gai_strerror gai_strerror "/usr/lib/libSystem.B.dylib"
+func libc_gai_strerror_trampoline()
+
+func GaiStrerror(ecode int) string {
+	r1, _, _ := syscall_syscall(abi.FuncPCABI0(libc_gai_strerror_trampoline),
+		uintptr(ecode),
+		0, 0)
+	return GoString((*byte)(unsafe.Pointer(r1)))
+}
+
+// Implemented in the runtime package.
+func gostring(*byte) string
+
+func GoString(p *byte) string {
+	return gostring(p)
+}
+
+//go:linkname syscall_syscall syscall.syscall
+func syscall_syscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)
+
+//go:linkname syscall_syscallPtr syscall.syscallPtr
+func syscall_syscallPtr(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)
+
+//go:linkname syscall_syscall6 syscall.syscall6
+func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
+
+//go:linkname syscall_syscall6X syscall.syscall6X
+func syscall_syscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
+
+//go:linkname syscall_syscall9 syscall.syscall9
+func syscall_syscall9(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
+
+type ResState struct {
+	unexported [70]uintptr
+}
+
+//go:cgo_import_dynamic libresolv_res_9_ninit res_9_ninit "/usr/lib/libresolv.9.dylib"
+func libresolv_res_9_ninit_trampoline()
+
+func ResNinit(state *ResState) error {
+	_, _, errno := syscall_syscall(abi.FuncPCABI0(libresolv_res_9_ninit_trampoline),
+		uintptr(unsafe.Pointer(state)),
+		0, 0)
+	if errno != 0 {
+		return errno
+	}
+	return nil
+}
+
+//go:cgo_import_dynamic libresolv_res_9_nclose res_9_nclose "/usr/lib/libresolv.9.dylib"
+func libresolv_res_9_nclose_trampoline()
+
+func ResNclose(state *ResState) {
+	syscall_syscall(abi.FuncPCABI0(libresolv_res_9_nclose_trampoline),
+		uintptr(unsafe.Pointer(state)),
+		0, 0)
+}
+
+//go:cgo_import_dynamic libresolv_res_9_nsearch res_9_nsearch "/usr/lib/libresolv.9.dylib"
+func libresolv_res_9_nsearch_trampoline()
+
+func ResNsearch(state *ResState, dname *byte, class, typ int, ans *byte, anslen int) (int, error) {
+	r1, _, errno := syscall_syscall6(abi.FuncPCABI0(libresolv_res_9_nsearch_trampoline),
+		uintptr(unsafe.Pointer(state)),
+		uintptr(unsafe.Pointer(dname)),
+		uintptr(class),
+		uintptr(typ),
+		uintptr(unsafe.Pointer(ans)),
+		uintptr(anslen))
+	if errno != 0 {
+		return 0, errno
+	}
+	return int(int32(r1)), nil
+}
diff --git a/src/internal/syscall/unix/nonblocking.go b/src/internal/syscall/unix/nonblocking.go
index 9e5f0fb..a0becd1 100644
--- a/src/internal/syscall/unix/nonblocking.go
+++ b/src/internal/syscall/unix/nonblocking.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build dragonfly || freebsd || linux || netbsd || openbsd
+//go:build dragonfly || freebsd || linux || netbsd || (openbsd && mips64)
 
 package unix
 
diff --git a/src/internal/syscall/unix/nonblocking_libc.go b/src/internal/syscall/unix/nonblocking_libc.go
index 8494071..bff6684 100644
--- a/src/internal/syscall/unix/nonblocking_libc.go
+++ b/src/internal/syscall/unix/nonblocking_libc.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build aix || darwin || solaris
+//go:build aix || darwin || (openbsd && !mips64) || solaris
 
 package unix
 
diff --git a/src/internal/syscall/unix/pty_darwin.go b/src/internal/syscall/unix/pty_darwin.go
new file mode 100644
index 0000000..b43321a
--- /dev/null
+++ b/src/internal/syscall/unix/pty_darwin.go
@@ -0,0 +1,65 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package unix
+
+import (
+	"internal/abi"
+	"unsafe"
+)
+
+//go:cgo_import_dynamic libc_grantpt grantpt "/usr/lib/libSystem.B.dylib"
+func libc_grantpt_trampoline()
+
+func Grantpt(fd int) error {
+	_, _, errno := syscall_syscall6(abi.FuncPCABI0(libc_grantpt_trampoline), uintptr(fd), 0, 0, 0, 0, 0)
+	if errno != 0 {
+		return errno
+	}
+	return nil
+}
+
+//go:cgo_import_dynamic libc_unlockpt unlockpt "/usr/lib/libSystem.B.dylib"
+func libc_unlockpt_trampoline()
+
+func Unlockpt(fd int) error {
+	_, _, errno := syscall_syscall6(abi.FuncPCABI0(libc_unlockpt_trampoline), uintptr(fd), 0, 0, 0, 0, 0)
+	if errno != 0 {
+		return errno
+	}
+	return nil
+}
+
+//go:cgo_import_dynamic libc_ptsname_r ptsname_r "/usr/lib/libSystem.B.dylib"
+func libc_ptsname_r_trampoline()
+
+func Ptsname(fd int) (string, error) {
+	buf := make([]byte, 256)
+	_, _, errno := syscall_syscall6(abi.FuncPCABI0(libc_ptsname_r_trampoline),
+		uintptr(fd),
+		uintptr(unsafe.Pointer(&buf[0])),
+		uintptr(len(buf)-1),
+		0, 0, 0)
+	if errno != 0 {
+		return "", errno
+	}
+	for i, c := range buf {
+		if c == 0 {
+			buf = buf[:i]
+			break
+		}
+	}
+	return string(buf), nil
+}
+
+//go:cgo_import_dynamic libc_posix_openpt posix_openpt "/usr/lib/libSystem.B.dylib"
+func libc_posix_openpt_trampoline()
+
+func PosixOpenpt(flag int) (fd int, err error) {
+	ufd, _, errno := syscall_syscall6(abi.FuncPCABI0(libc_posix_openpt_trampoline), uintptr(flag), 0, 0, 0, 0, 0)
+	if errno != 0 {
+		return -1, errno
+	}
+	return int(ufd), nil
+}
diff --git a/src/internal/syscall/unix/user_darwin.go b/src/internal/syscall/unix/user_darwin.go
new file mode 100644
index 0000000..d05acda
--- /dev/null
+++ b/src/internal/syscall/unix/user_darwin.go
@@ -0,0 +1,121 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package unix
+
+import (
+	"internal/abi"
+	"syscall"
+	"unsafe"
+)
+
+//go:cgo_import_dynamic libc_getgrouplist getgrouplist "/usr/lib/libSystem.B.dylib"
+func libc_getgrouplist_trampoline()
+
+func Getgrouplist(name *byte, gid uint32, gids *uint32, n *int32) error {
+	_, _, errno := syscall_syscall6(abi.FuncPCABI0(libc_getgrouplist_trampoline),
+		uintptr(unsafe.Pointer(name)), uintptr(gid), uintptr(unsafe.Pointer(gids)),
+		uintptr(unsafe.Pointer(n)), 0, 0)
+	if errno != 0 {
+		return errno
+	}
+	return nil
+}
+
+const (
+	SC_GETGR_R_SIZE_MAX = 0x46
+	SC_GETPW_R_SIZE_MAX = 0x47
+)
+
+type Passwd struct {
+	Name   *byte
+	Passwd *byte
+	Uid    uint32 // uid_t
+	Gid    uint32 // gid_t
+	Change int64  // time_t
+	Class  *byte
+	Gecos  *byte
+	Dir    *byte
+	Shell  *byte
+	Expire int64 // time_t
+}
+
+type Group struct {
+	Name   *byte
+	Passwd *byte
+	Gid    uint32 // gid_t
+	Mem    **byte
+}
+
+//go:cgo_import_dynamic libc_getpwnam_r getpwnam_r  "/usr/lib/libSystem.B.dylib"
+func libc_getpwnam_r_trampoline()
+
+func Getpwnam(name *byte, pwd *Passwd, buf *byte, size uintptr, result **Passwd) syscall.Errno {
+	// Note: Returns an errno as its actual result, not in global errno.
+	errno, _, _ := syscall_syscall6(abi.FuncPCABI0(libc_getpwnam_r_trampoline),
+		uintptr(unsafe.Pointer(name)),
+		uintptr(unsafe.Pointer(pwd)),
+		uintptr(unsafe.Pointer(buf)),
+		size,
+		uintptr(unsafe.Pointer(result)),
+		0)
+	return syscall.Errno(errno)
+}
+
+//go:cgo_import_dynamic libc_getpwuid_r getpwuid_r  "/usr/lib/libSystem.B.dylib"
+func libc_getpwuid_r_trampoline()
+
+func Getpwuid(uid uint32, pwd *Passwd, buf *byte, size uintptr, result **Passwd) syscall.Errno {
+	// Note: Returns an errno as its actual result, not in global errno.
+	errno, _, _ := syscall_syscall6(abi.FuncPCABI0(libc_getpwuid_r_trampoline),
+		uintptr(uid),
+		uintptr(unsafe.Pointer(pwd)),
+		uintptr(unsafe.Pointer(buf)),
+		size,
+		uintptr(unsafe.Pointer(result)),
+		0)
+	return syscall.Errno(errno)
+}
+
+//go:cgo_import_dynamic libc_getgrnam_r getgrnam_r  "/usr/lib/libSystem.B.dylib"
+func libc_getgrnam_r_trampoline()
+
+func Getgrnam(name *byte, grp *Group, buf *byte, size uintptr, result **Group) syscall.Errno {
+	// Note: Returns an errno as its actual result, not in global errno.
+	errno, _, _ := syscall_syscall6(abi.FuncPCABI0(libc_getgrnam_r_trampoline),
+		uintptr(unsafe.Pointer(name)),
+		uintptr(unsafe.Pointer(grp)),
+		uintptr(unsafe.Pointer(buf)),
+		size,
+		uintptr(unsafe.Pointer(result)),
+		0)
+	return syscall.Errno(errno)
+}
+
+//go:cgo_import_dynamic libc_getgrgid_r getgrgid_r  "/usr/lib/libSystem.B.dylib"
+func libc_getgrgid_r_trampoline()
+
+func Getgrgid(gid uint32, grp *Group, buf *byte, size uintptr, result **Group) syscall.Errno {
+	// Note: Returns an errno as its actual result, not in global errno.
+	errno, _, _ := syscall_syscall6(abi.FuncPCABI0(libc_getgrgid_r_trampoline),
+		uintptr(gid),
+		uintptr(unsafe.Pointer(grp)),
+		uintptr(unsafe.Pointer(buf)),
+		size,
+		uintptr(unsafe.Pointer(result)),
+		0)
+	return syscall.Errno(errno)
+}
+
+//go:cgo_import_dynamic libc_sysconf sysconf "/usr/lib/libSystem.B.dylib"
+func libc_sysconf_trampoline()
+
+func Sysconf(key int32) int64 {
+	val, _, errno := syscall_syscall6X(abi.FuncPCABI0(libc_sysconf_trampoline),
+		uintptr(key), 0, 0, 0, 0, 0)
+	if errno != 0 {
+		return -1
+	}
+	return int64(val)
+}
diff --git a/src/internal/syscall/unix/writev_illumos.go b/src/internal/syscall/unix/writev_illumos.go
deleted file mode 100644
index ee31be1..0000000
--- a/src/internal/syscall/unix/writev_illumos.go
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build illumos
-
-package unix
-
-import (
-	"syscall"
-	"unsafe"
-)
-
-//go:cgo_import_dynamic libc_writev writev "libc.so"
-
-//go:linkname procwritev libc_writev
-
-var procwritev uintptr
-
-func Writev(fd int, iovs []syscall.Iovec) (uintptr, error) {
-	var p *syscall.Iovec
-	if len(iovs) > 0 {
-		p = &iovs[0]
-	}
-	n, _, errno := syscall6(uintptr(unsafe.Pointer(&procwritev)), 3, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(len(iovs)), 0, 0, 0)
-	if errno != 0 {
-		return 0, errno
-	}
-	return n, nil
-}
diff --git a/src/internal/syscall/windows/memory_windows.go b/src/internal/syscall/windows/memory_windows.go
index ba30f92..8fb34cf 100644
--- a/src/internal/syscall/windows/memory_windows.go
+++ b/src/internal/syscall/windows/memory_windows.go
@@ -5,12 +5,20 @@
 package windows
 
 type MemoryBasicInformation struct {
-	BaseAddress       uintptr
-	AllocationBase    uintptr
+	// A pointer to the base address of the region of pages.
+	BaseAddress uintptr
+	// A pointer to the base address of a range of pages allocated by the VirtualAlloc function.
+	// The page pointed to by the BaseAddress member is contained within this allocation range.
+	AllocationBase uintptr
+	// The memory protection option when the region was initially allocated
 	AllocationProtect uint32
 	PartitionId       uint16
-	RegionSize        uintptr
-	State             uint32
-	Protect           uint32
-	Type              uint32
+	// The size of the region beginning at the base address in which all pages have identical attributes, in bytes.
+	RegionSize uintptr
+	// The state of the pages in the region.
+	State uint32
+	// The access protection of the pages in the region.
+	Protect uint32
+	// The type of pages in the region.
+	Type uint32
 }
diff --git a/src/internal/syscall/windows/syscall_windows.go b/src/internal/syscall/windows/syscall_windows.go
index b37085e..8ace2a2 100644
--- a/src/internal/syscall/windows/syscall_windows.go
+++ b/src/internal/syscall/windows/syscall_windows.go
@@ -5,7 +5,6 @@
 package windows
 
 import (
-	"internal/unsafeheader"
 	"sync"
 	"syscall"
 	"unicode/utf16"
@@ -26,16 +25,13 @@
 		n++
 	}
 	// Turn *uint16 into []uint16.
-	var s []uint16
-	hdr := (*unsafeheader.Slice)(unsafe.Pointer(&s))
-	hdr.Data = unsafe.Pointer(p)
-	hdr.Cap = n
-	hdr.Len = n
+	s := unsafe.Slice(p, n)
 	// Decode []uint16 into string.
 	return string(utf16.Decode(s))
 }
 
 const (
+	ERROR_BAD_LENGTH             syscall.Errno = 24
 	ERROR_SHARING_VIOLATION      syscall.Errno = 32
 	ERROR_LOCK_VIOLATION         syscall.Errno = 33
 	ERROR_NOT_SUPPORTED          syscall.Errno = 50
@@ -157,6 +153,32 @@
 //sys	VirtualQuery(address uintptr, buffer *MemoryBasicInformation, length uintptr) (err error) = kernel32.VirtualQuery
 
 const (
+	// flags for CreateToolhelp32Snapshot
+	TH32CS_SNAPMODULE   = 0x08
+	TH32CS_SNAPMODULE32 = 0x10
+)
+
+const MAX_MODULE_NAME32 = 255
+
+type ModuleEntry32 struct {
+	Size         uint32
+	ModuleID     uint32
+	ProcessID    uint32
+	GlblcntUsage uint32
+	ProccntUsage uint32
+	ModBaseAddr  uintptr
+	ModBaseSize  uint32
+	ModuleHandle syscall.Handle
+	Module       [MAX_MODULE_NAME32 + 1]uint16
+	ExePath      [syscall.MAX_PATH]uint16
+}
+
+const SizeofModuleEntry32 = unsafe.Sizeof(ModuleEntry32{})
+
+//sys	Module32First(snapshot syscall.Handle, moduleEntry *ModuleEntry32) (err error) = kernel32.Module32FirstW
+//sys	Module32Next(snapshot syscall.Handle, moduleEntry *ModuleEntry32) (err error) = kernel32.Module32NextW
+
+const (
 	WSA_FLAG_OVERLAPPED        = 0x01
 	WSA_FLAG_NO_HANDLE_INHERIT = 0x80
 
diff --git a/src/internal/syscall/windows/zsyscall_windows.go b/src/internal/syscall/windows/zsyscall_windows.go
index 962607a..afd64e3 100644
--- a/src/internal/syscall/windows/zsyscall_windows.go
+++ b/src/internal/syscall/windows/zsyscall_windows.go
@@ -62,6 +62,8 @@
 	procGetFinalPathNameByHandleW    = modkernel32.NewProc("GetFinalPathNameByHandleW")
 	procGetModuleFileNameW           = modkernel32.NewProc("GetModuleFileNameW")
 	procLockFileEx                   = modkernel32.NewProc("LockFileEx")
+	procModule32FirstW               = modkernel32.NewProc("Module32FirstW")
+	procModule32NextW                = modkernel32.NewProc("Module32NextW")
 	procMoveFileExW                  = modkernel32.NewProc("MoveFileExW")
 	procMultiByteToWideChar          = modkernel32.NewProc("MultiByteToWideChar")
 	procSetFileInformationByHandle   = modkernel32.NewProc("SetFileInformationByHandle")
@@ -225,6 +227,22 @@
 	return
 }
 
+func Module32First(snapshot syscall.Handle, moduleEntry *ModuleEntry32) (err error) {
+	r1, _, e1 := syscall.Syscall(procModule32FirstW.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(moduleEntry)), 0)
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func Module32Next(snapshot syscall.Handle, moduleEntry *ModuleEntry32) (err error) {
+	r1, _, e1 := syscall.Syscall(procModule32NextW.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(moduleEntry)), 0)
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
 func MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) {
 	r1, _, e1 := syscall.Syscall(procMoveFileExW.Addr(), 3, uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)), uintptr(flags))
 	if r1 == 0 {
diff --git a/src/internal/testenv/exec.go b/src/internal/testenv/exec.go
new file mode 100644
index 0000000..77de59c
--- /dev/null
+++ b/src/internal/testenv/exec.go
@@ -0,0 +1,175 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package testenv
+
+import (
+	"context"
+	"os"
+	"os/exec"
+	"runtime"
+	"strconv"
+	"strings"
+	"sync"
+	"testing"
+	"time"
+)
+
+// HasExec reports whether the current system can start new processes
+// using os.StartProcess or (more commonly) exec.Command.
+func HasExec() bool {
+	switch runtime.GOOS {
+	case "js", "ios":
+		return false
+	}
+	return true
+}
+
+// MustHaveExec checks that the current system can start new processes
+// using os.StartProcess or (more commonly) exec.Command.
+// If not, MustHaveExec calls t.Skip with an explanation.
+func MustHaveExec(t testing.TB) {
+	if !HasExec() {
+		t.Skipf("skipping test: cannot exec subprocess on %s/%s", runtime.GOOS, runtime.GOARCH)
+	}
+}
+
+var execPaths sync.Map // path -> error
+
+// MustHaveExecPath checks that the current system can start the named executable
+// using os.StartProcess or (more commonly) exec.Command.
+// If not, MustHaveExecPath calls t.Skip with an explanation.
+func MustHaveExecPath(t testing.TB, path string) {
+	MustHaveExec(t)
+
+	err, found := execPaths.Load(path)
+	if !found {
+		_, err = exec.LookPath(path)
+		err, _ = execPaths.LoadOrStore(path, err)
+	}
+	if err != nil {
+		t.Skipf("skipping test: %s: %s", path, err)
+	}
+}
+
+// CleanCmdEnv will fill cmd.Env with the environment, excluding certain
+// variables that could modify the behavior of the Go tools such as
+// GODEBUG and GOTRACEBACK.
+func CleanCmdEnv(cmd *exec.Cmd) *exec.Cmd {
+	if cmd.Env != nil {
+		panic("environment already set")
+	}
+	for _, env := range os.Environ() {
+		// Exclude GODEBUG from the environment to prevent its output
+		// from breaking tests that are trying to parse other command output.
+		if strings.HasPrefix(env, "GODEBUG=") {
+			continue
+		}
+		// Exclude GOTRACEBACK for the same reason.
+		if strings.HasPrefix(env, "GOTRACEBACK=") {
+			continue
+		}
+		cmd.Env = append(cmd.Env, env)
+	}
+	return cmd
+}
+
+// CommandContext is like exec.CommandContext, but:
+//   - skips t if the platform does not support os/exec,
+//   - sends SIGQUIT (if supported by the platform) instead of SIGKILL
+//     in its Cancel function
+//   - if the test has a deadline, adds a Context timeout and WaitDelay
+//     for an arbitrary grace period before the test's deadline expires,
+//   - fails the test if the command does not complete before the test's deadline, and
+//   - sets a Cleanup function that verifies that the test did not leak a subprocess.
+func CommandContext(t testing.TB, ctx context.Context, name string, args ...string) *exec.Cmd {
+	t.Helper()
+	MustHaveExec(t)
+
+	var (
+		cancelCtx   context.CancelFunc
+		gracePeriod time.Duration // unlimited unless the test has a deadline (to allow for interactive debugging)
+	)
+
+	if t, ok := t.(interface {
+		testing.TB
+		Deadline() (time.Time, bool)
+	}); ok {
+		if td, ok := t.Deadline(); ok {
+			// Start with a minimum grace period, just long enough to consume the
+			// output of a reasonable program after it terminates.
+			gracePeriod = 100 * time.Millisecond
+			if s := os.Getenv("GO_TEST_TIMEOUT_SCALE"); s != "" {
+				scale, err := strconv.Atoi(s)
+				if err != nil {
+					t.Fatalf("invalid GO_TEST_TIMEOUT_SCALE: %v", err)
+				}
+				gracePeriod *= time.Duration(scale)
+			}
+
+			// If time allows, increase the termination grace period to 5% of the
+			// test's remaining time.
+			testTimeout := time.Until(td)
+			if gp := testTimeout / 20; gp > gracePeriod {
+				gracePeriod = gp
+			}
+
+			// When we run commands that execute subprocesses, we want to reserve two
+			// grace periods to clean up: one for the delay between the first
+			// termination signal being sent (via the Cancel callback when the Context
+			// expires) and the process being forcibly terminated (via the WaitDelay
+			// field), and a second one for the delay becween the process being
+			// terminated and and the test logging its output for debugging.
+			//
+			// (We want to ensure that the test process itself has enough time to
+			// log the output before it is also terminated.)
+			cmdTimeout := testTimeout - 2*gracePeriod
+
+			if cd, ok := ctx.Deadline(); !ok || time.Until(cd) > cmdTimeout {
+				// Either ctx doesn't have a deadline, or its deadline would expire
+				// after (or too close before) the test has already timed out.
+				// Add a shorter timeout so that the test will produce useful output.
+				ctx, cancelCtx = context.WithTimeout(ctx, cmdTimeout)
+			}
+		}
+	}
+
+	cmd := exec.CommandContext(ctx, name, args...)
+	cmd.Cancel = func() error {
+		if cancelCtx != nil && ctx.Err() == context.DeadlineExceeded {
+			// The command timed out due to running too close to the test's deadline.
+			// There is no way the test did that intentionally — it's too close to the
+			// wire! — so mark it as a test failure. That way, if the test expects the
+			// command to fail for some other reason, it doesn't have to distinguish
+			// between that reason and a timeout.
+			t.Errorf("test timed out while running command: %v", cmd)
+		} else {
+			// The command is being terminated due to ctx being canceled, but
+			// apparently not due to an explicit test deadline that we added.
+			// Log that information in case it is useful for diagnosing a failure,
+			// but don't actually fail the test because of it.
+			t.Logf("%v: terminating command: %v", ctx.Err(), cmd)
+		}
+		return cmd.Process.Signal(Sigquit)
+	}
+	cmd.WaitDelay = gracePeriod
+
+	t.Cleanup(func() {
+		if cancelCtx != nil {
+			cancelCtx()
+		}
+		if cmd.Process != nil && cmd.ProcessState == nil {
+			t.Errorf("command was started, but test did not wait for it to complete: %v", cmd)
+		}
+	})
+
+	return cmd
+}
+
+// Command is like exec.Command, but applies the same changes as
+// testenv.CommandContext (with a default Context).
+func Command(t testing.TB, name string, args ...string) *exec.Cmd {
+	t.Helper()
+	return CommandContext(t, context.Background(), name, args...)
+}
diff --git a/src/internal/testenv/noopt.go b/src/internal/testenv/noopt.go
new file mode 100644
index 0000000..ae2a3d0
--- /dev/null
+++ b/src/internal/testenv/noopt.go
@@ -0,0 +1,12 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build noopt
+
+package testenv
+
+// OptimizationOff reports whether optimization is disabled.
+func OptimizationOff() bool {
+	return true
+}
diff --git a/src/internal/testenv/opt.go b/src/internal/testenv/opt.go
new file mode 100644
index 0000000..1bb96f7
--- /dev/null
+++ b/src/internal/testenv/opt.go
@@ -0,0 +1,12 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !noopt
+
+package testenv
+
+// OptimizationOff reports whether optimization is disabled.
+func OptimizationOff() bool {
+	return false
+}
diff --git a/src/internal/testenv/testenv.go b/src/internal/testenv/testenv.go
index 1feb630..6a28b25 100644
--- a/src/internal/testenv/testenv.go
+++ b/src/internal/testenv/testenv.go
@@ -11,11 +11,12 @@
 package testenv
 
 import (
-	"bytes"
 	"errors"
 	"flag"
 	"fmt"
 	"internal/cfg"
+	"internal/goroot"
+	"internal/platform"
 	"os"
 	"os/exec"
 	"path/filepath"
@@ -24,7 +25,6 @@
 	"strings"
 	"sync"
 	"testing"
-	"time"
 )
 
 // Builder reports the name of the builder running this test
@@ -215,16 +215,6 @@
 	return goBin, nil
 }
 
-// HasExec reports whether the current system can start new processes
-// using os.StartProcess or (more commonly) exec.Command.
-func HasExec() bool {
-	switch runtime.GOOS {
-	case "js", "ios":
-		return false
-	}
-	return true
-}
-
 // HasSrc reports whether the entire source tree is available under GOROOT.
 func HasSrc() bool {
 	switch runtime.GOOS {
@@ -234,33 +224,6 @@
 	return true
 }
 
-// MustHaveExec checks that the current system can start new processes
-// using os.StartProcess or (more commonly) exec.Command.
-// If not, MustHaveExec calls t.Skip with an explanation.
-func MustHaveExec(t testing.TB) {
-	if !HasExec() {
-		t.Skipf("skipping test: cannot exec subprocess on %s/%s", runtime.GOOS, runtime.GOARCH)
-	}
-}
-
-var execPaths sync.Map // path -> error
-
-// MustHaveExecPath checks that the current system can start the named executable
-// using os.StartProcess or (more commonly) exec.Command.
-// If not, MustHaveExecPath calls t.Skip with an explanation.
-func MustHaveExecPath(t testing.TB, path string) {
-	MustHaveExec(t)
-
-	err, found := execPaths.Load(path)
-	if !found {
-		_, err = exec.LookPath(path)
-		err, _ = execPaths.LoadOrStore(path, err)
-	}
-	if err != nil {
-		t.Skipf("skipping test: %s: %s", path, err)
-	}
-}
-
 // HasExternalNetwork reports whether the current system can use
 // external (non-localhost) networks.
 func HasExternalNetwork() bool {
@@ -295,19 +258,8 @@
 
 // CanInternalLink reports whether the current system can link programs with
 // internal linking.
-// (This is the opposite of cmd/internal/sys.MustLinkExternal. Keep them in sync.)
 func CanInternalLink() bool {
-	switch runtime.GOOS {
-	case "android":
-		if runtime.GOARCH != "arm64" {
-			return false
-		}
-	case "ios":
-		if runtime.GOARCH == "arm64" {
-			return false
-		}
-	}
-	return true
+	return !platform.MustLinkExternal(runtime.GOOS, runtime.GOARCH)
 }
 
 // MustInternalLink checks that the current system can link programs with internal
@@ -366,28 +318,6 @@
 	}
 }
 
-// CleanCmdEnv will fill cmd.Env with the environment, excluding certain
-// variables that could modify the behavior of the Go tools such as
-// GODEBUG and GOTRACEBACK.
-func CleanCmdEnv(cmd *exec.Cmd) *exec.Cmd {
-	if cmd.Env != nil {
-		panic("environment already set")
-	}
-	for _, env := range os.Environ() {
-		// Exclude GODEBUG from the environment to prevent its output
-		// from breaking tests that are trying to parse other command output.
-		if strings.HasPrefix(env, "GODEBUG=") {
-			continue
-		}
-		// Exclude GOTRACEBACK for the same reason.
-		if strings.HasPrefix(env, "GOTRACEBACK=") {
-			continue
-		}
-		cmd.Env = append(cmd.Env, env)
-	}
-	return cmd
-}
-
 // CPUIsSlow reports whether the CPU running the test is suspected to be slow.
 func CPUIsSlow() bool {
 	switch runtime.GOARCH {
@@ -408,58 +338,27 @@
 	}
 }
 
-// RunWithTimeout runs cmd and returns its combined output. If the
-// subprocess exits with a non-zero status, it will log that status
-// and return a non-nil error, but this is not considered fatal.
-func RunWithTimeout(t testing.TB, cmd *exec.Cmd) ([]byte, error) {
-	args := cmd.Args
-	if args == nil {
-		args = []string{cmd.Path}
+// SkipIfOptimizationOff skips t if optimization is disabled.
+func SkipIfOptimizationOff(t testing.TB) {
+	if OptimizationOff() {
+		t.Helper()
+		t.Skip("skipping test with optimization disabled")
 	}
+}
 
-	var b bytes.Buffer
-	cmd.Stdout = &b
-	cmd.Stderr = &b
-	if err := cmd.Start(); err != nil {
-		t.Fatalf("starting %s: %v", args, err)
+// WriteImportcfg writes an importcfg file used by the compiler or linker to
+// dstPath containing entries for the packages in std and cmd in addition
+// to the package to package file mappings in additionalPackageFiles.
+func WriteImportcfg(t testing.TB, dstPath string, additionalPackageFiles map[string]string) {
+	importcfg, err := goroot.Importcfg()
+	for k, v := range additionalPackageFiles {
+		importcfg += fmt.Sprintf("\npackagefile %s=%s", k, v)
 	}
-
-	// If the process doesn't complete within 1 minute,
-	// assume it is hanging and kill it to get a stack trace.
-	p := cmd.Process
-	done := make(chan bool)
-	go func() {
-		scale := 1
-		// This GOARCH/GOOS test is copied from cmd/dist/test.go.
-		// TODO(iant): Have cmd/dist update the environment variable.
-		if runtime.GOARCH == "arm" || runtime.GOOS == "windows" {
-			scale = 2
-		}
-		if s := os.Getenv("GO_TEST_TIMEOUT_SCALE"); s != "" {
-			if sc, err := strconv.Atoi(s); err == nil {
-				scale = sc
-			}
-		}
-
-		select {
-		case <-done:
-		case <-time.After(time.Duration(scale) * time.Minute):
-			p.Signal(Sigquit)
-			// If SIGQUIT doesn't do it after a little
-			// while, kill the process.
-			select {
-			case <-done:
-			case <-time.After(time.Duration(scale) * 30 * time.Second):
-				p.Signal(os.Kill)
-			}
-		}
-	}()
-
-	err := cmd.Wait()
 	if err != nil {
-		t.Logf("%s exit status: %v", args, err)
+		t.Fatalf("preparing the importcfg failed: %s", err)
 	}
-	close(done)
-
-	return b.Bytes(), err
+	err = os.WriteFile(dstPath, []byte(importcfg), 0655)
+	if err != nil {
+		t.Fatalf("writing the importcfg failed: %s", err)
+	}
 }
diff --git a/src/internal/testenv/testenv_test.go b/src/internal/testenv/testenv_test.go
new file mode 100644
index 0000000..ebc27f1
--- /dev/null
+++ b/src/internal/testenv/testenv_test.go
@@ -0,0 +1,53 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package testenv_test
+
+import (
+	"internal/testenv"
+	"os"
+	"path/filepath"
+	"runtime"
+	"testing"
+)
+
+func TestGoToolLocation(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	var exeSuffix string
+	if runtime.GOOS == "windows" {
+		exeSuffix = ".exe"
+	}
+
+	// Tests are defined to run within their package source directory,
+	// and this package's source directory is $GOROOT/src/internal/testenv.
+	// The 'go' command is installed at $GOROOT/bin/go, so if the environment
+	// is correct then testenv.GoTool() should be identical to ../../../bin/go.
+
+	relWant := "../../../bin/go" + exeSuffix
+	absWant, err := filepath.Abs(relWant)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	wantInfo, err := os.Stat(absWant)
+	if err != nil {
+		t.Fatal(err)
+	}
+	t.Logf("found go tool at %q (%q)", relWant, absWant)
+
+	goTool, err := testenv.GoTool()
+	if err != nil {
+		t.Fatalf("testenv.GoTool(): %v", err)
+	}
+	t.Logf("testenv.GoTool() = %q", goTool)
+
+	gotInfo, err := os.Stat(goTool)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !os.SameFile(wantInfo, gotInfo) {
+		t.Fatalf("%q is not the same file as %q", absWant, goTool)
+	}
+}
diff --git a/src/internal/testpty/pty.go b/src/internal/testpty/pty.go
new file mode 100644
index 0000000..f0b2a33
--- /dev/null
+++ b/src/internal/testpty/pty.go
@@ -0,0 +1,38 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package testpty is a simple pseudo-terminal package for Unix systems,
+// implemented by calling C functions via cgo.
+package testpty
+
+import (
+	"errors"
+	"fmt"
+	"os"
+)
+
+type PtyError struct {
+	FuncName    string
+	ErrorString string
+	Errno       error
+}
+
+func ptyError(name string, err error) *PtyError {
+	return &PtyError{name, err.Error(), err}
+}
+
+func (e *PtyError) Error() string {
+	return fmt.Sprintf("%s: %s", e.FuncName, e.ErrorString)
+}
+
+func (e *PtyError) Unwrap() error { return e.Errno }
+
+var ErrNotSupported = errors.New("testpty.Open not implemented on this platform")
+
+// Open returns a control pty and the name of the linked process tty.
+//
+// If Open is not implemented on this platform, it returns ErrNotSupported.
+func Open() (pty *os.File, processTTY string, err error) {
+	return open()
+}
diff --git a/src/internal/testpty/pty_cgo.go b/src/internal/testpty/pty_cgo.go
new file mode 100644
index 0000000..1db6a92
--- /dev/null
+++ b/src/internal/testpty/pty_cgo.go
@@ -0,0 +1,34 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build cgo && (aix || dragonfly || freebsd || (linux && !android) || netbsd || openbsd)
+
+package testpty
+
+/*
+#define _XOPEN_SOURCE 600
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+*/
+import "C"
+
+import "os"
+
+func open() (pty *os.File, processTTY string, err error) {
+	m, err := C.posix_openpt(C.O_RDWR)
+	if err != nil {
+		return nil, "", ptyError("posix_openpt", err)
+	}
+	if _, err := C.grantpt(m); err != nil {
+		C.close(m)
+		return nil, "", ptyError("grantpt", err)
+	}
+	if _, err := C.unlockpt(m); err != nil {
+		C.close(m)
+		return nil, "", ptyError("unlockpt", err)
+	}
+	processTTY = C.GoString(C.ptsname(m))
+	return os.NewFile(uintptr(m), "pty"), processTTY, nil
+}
diff --git a/src/internal/testpty/pty_darwin.go b/src/internal/testpty/pty_darwin.go
new file mode 100644
index 0000000..f29517c
--- /dev/null
+++ b/src/internal/testpty/pty_darwin.go
@@ -0,0 +1,32 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package testpty
+
+import (
+	"internal/syscall/unix"
+	"os"
+	"syscall"
+)
+
+func open() (pty *os.File, processTTY string, err error) {
+	m, err := unix.PosixOpenpt(syscall.O_RDWR)
+	if err != nil {
+		return nil, "", ptyError("posix_openpt", err)
+	}
+	if err := unix.Grantpt(m); err != nil {
+		syscall.Close(m)
+		return nil, "", ptyError("grantpt", err)
+	}
+	if err := unix.Unlockpt(m); err != nil {
+		syscall.Close(m)
+		return nil, "", ptyError("unlockpt", err)
+	}
+	processTTY, err = unix.Ptsname(m)
+	if err != nil {
+		syscall.Close(m)
+		return nil, "", ptyError("ptsname", err)
+	}
+	return os.NewFile(uintptr(m), "pty"), processTTY, nil
+}
diff --git a/src/internal/testpty/pty_none.go b/src/internal/testpty/pty_none.go
new file mode 100644
index 0000000..4f9e2b7
--- /dev/null
+++ b/src/internal/testpty/pty_none.go
@@ -0,0 +1,13 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !(cgo && (aix || dragonfly || freebsd || (linux && !android) || netbsd || openbsd)) && !darwin
+
+package testpty
+
+import "os"
+
+func open() (pty *os.File, processTTY string, err error) {
+	return nil, "", ErrNotSupported
+}
diff --git a/src/internal/trace/goroutines.go b/src/internal/trace/goroutines.go
index 5da90e0..4b4f13d 100644
--- a/src/internal/trace/goroutines.go
+++ b/src/internal/trace/goroutines.go
@@ -172,7 +172,7 @@
 			// of the active region. For ease handling of this
 			// case, we create a fake region description with the
 			// task id. This isn't strictly necessary as this
-			// goroutine may not be assosciated with the task, but
+			// goroutine may not be associated with the task, but
 			// it can be convenient to see all children created
 			// during a region.
 			if creatorG := gs[ev.G]; creatorG != nil && len(creatorG.gdesc.activeRegions) > 0 {
@@ -187,7 +187,7 @@
 			gs[g.ID] = g
 		case EvGoStart, EvGoStartLabel:
 			g := gs[ev.G]
-			if g.PC == 0 {
+			if g.PC == 0 && len(ev.Stk) > 0 {
 				g.PC = ev.Stk[0].PC
 				g.Name = ev.Stk[0].Fn
 			}
@@ -353,5 +353,6 @@
 func IsSystemGoroutine(entryFn string) bool {
 	// This mimics runtime.isSystemGoroutine as closely as
 	// possible.
-	return entryFn != "runtime.main" && strings.HasPrefix(entryFn, "runtime.")
+	// Also, locked g in extra M (with empty entryFn) is system goroutine.
+	return entryFn == "" || entryFn != "runtime.main" && strings.HasPrefix(entryFn, "runtime.")
 }
diff --git a/src/internal/trace/parser.go b/src/internal/trace/parser.go
index 866fe8c..b091a85 100644
--- a/src/internal/trace/parser.go
+++ b/src/internal/trace/parser.go
@@ -973,7 +973,7 @@
 
 func (ev *Event) String() string {
 	desc := EventDescriptions[ev.Type]
-	w := new(bytes.Buffer)
+	w := new(strings.Builder)
 	fmt.Fprintf(w, "%v %v p=%v g=%v off=%v", ev.Ts, desc.Name, ev.P, ev.G, ev.Off)
 	for i, a := range desc.Args {
 		fmt.Fprintf(w, " %v=%v", a, ev.Args[i])
diff --git a/src/internal/txtar/archive.go b/src/internal/txtar/archive.go
index 81b3145..fd95f1e 100644
--- a/src/internal/txtar/archive.go
+++ b/src/internal/txtar/archive.go
@@ -34,7 +34,7 @@
 import (
 	"bytes"
 	"fmt"
-	"io/ioutil"
+	"os"
 	"strings"
 )
 
@@ -66,7 +66,7 @@
 
 // ParseFile parses the named file as an archive.
 func ParseFile(file string) (*Archive, error) {
-	data, err := ioutil.ReadFile(file)
+	data, err := os.ReadFile(file)
 	if err != nil {
 		return nil, err
 	}
diff --git a/src/internal/types/errors/codes.go b/src/internal/types/errors/codes.go
new file mode 100644
index 0000000..acddcbb
--- /dev/null
+++ b/src/internal/types/errors/codes.go
@@ -0,0 +1,1442 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package errors
+
+type Code int
+
+// This file defines the error codes that can be produced during type-checking.
+// Collectively, these codes provide an identifier that may be used to
+// implement special handling for certain types of errors.
+//
+// Error code values should not be changed: add new codes at the end.
+//
+// Error codes should be fine-grained enough that the exact nature of the error
+// can be easily determined, but coarse enough that they are not an
+// implementation detail of the type checking algorithm. As a rule-of-thumb,
+// errors should be considered equivalent if there is a theoretical refactoring
+// of the type checker in which they are emitted in exactly one place. For
+// example, the type checker emits different error messages for "too many
+// arguments" and "too few arguments", but one can imagine an alternative type
+// checker where this check instead just emits a single "wrong number of
+// arguments", so these errors should have the same code.
+//
+// Error code names should be as brief as possible while retaining accuracy and
+// distinctiveness. In most cases names should start with an adjective
+// describing the nature of the error (e.g. "invalid", "unused", "misplaced"),
+// and end with a noun identifying the relevant language object. For example,
+// "_DuplicateDecl" or "_InvalidSliceExpr". For brevity, naming follows the
+// convention that "bad" implies a problem with syntax, and "invalid" implies a
+// problem with types.
+
+const (
+	// InvalidSyntaxTree occurs if an invalid syntax tree is provided
+	// to the type checker. It should never happen.
+	InvalidSyntaxTree Code = -1
+)
+
+const (
+	// The zero Code value indicates an unset (invalid) error code.
+	_ Code = iota
+
+	// Test is reserved for errors that only apply while in self-test mode.
+	Test
+
+	// BlankPkgName occurs when a package name is the blank identifier "_".
+	//
+	// Per the spec:
+	//  "The PackageName must not be the blank identifier."
+	//
+	// Example:
+	//  package _
+	BlankPkgName
+
+	// MismatchedPkgName occurs when a file's package name doesn't match the
+	// package name already established by other files.
+	MismatchedPkgName
+
+	// InvalidPkgUse occurs when a package identifier is used outside of a
+	// selector expression.
+	//
+	// Example:
+	//  import "fmt"
+	//
+	//  var _ = fmt
+	InvalidPkgUse
+
+	// BadImportPath occurs when an import path is not valid.
+	BadImportPath
+
+	// BrokenImport occurs when importing a package fails.
+	//
+	// Example:
+	//  import "amissingpackage"
+	BrokenImport
+
+	// ImportCRenamed occurs when the special import "C" is renamed. "C" is a
+	// pseudo-package, and must not be renamed.
+	//
+	// Example:
+	//  import _ "C"
+	ImportCRenamed
+
+	// UnusedImport occurs when an import is unused.
+	//
+	// Example:
+	//  import "fmt"
+	//
+	//  func main() {}
+	UnusedImport
+
+	// InvalidInitCycle occurs when an invalid cycle is detected within the
+	// initialization graph.
+	//
+	// Example:
+	//  var x int = f()
+	//
+	//  func f() int { return x }
+	InvalidInitCycle
+
+	// DuplicateDecl occurs when an identifier is declared multiple times.
+	//
+	// Example:
+	//  var x = 1
+	//  var x = 2
+	DuplicateDecl
+
+	// InvalidDeclCycle occurs when a declaration cycle is not valid.
+	//
+	// Example:
+	//  type S struct {
+	//  	S
+	//  }
+	//
+	InvalidDeclCycle
+
+	// InvalidTypeCycle occurs when a cycle in type definitions results in a
+	// type that is not well-defined.
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  type T [unsafe.Sizeof(T{})]int
+	InvalidTypeCycle
+
+	// InvalidConstInit occurs when a const declaration has a non-constant
+	// initializer.
+	//
+	// Example:
+	//  var x int
+	//  const _ = x
+	InvalidConstInit
+
+	// InvalidConstVal occurs when a const value cannot be converted to its
+	// target type.
+	//
+	// TODO(findleyr): this error code and example are not very clear. Consider
+	// removing it.
+	//
+	// Example:
+	//  const _ = 1 << "hello"
+	InvalidConstVal
+
+	// InvalidConstType occurs when the underlying type in a const declaration
+	// is not a valid constant type.
+	//
+	// Example:
+	//  const c *int = 4
+	InvalidConstType
+
+	// UntypedNilUse occurs when the predeclared (untyped) value nil is used to
+	// initialize a variable declared without an explicit type.
+	//
+	// Example:
+	//  var x = nil
+	UntypedNilUse
+
+	// WrongAssignCount occurs when the number of values on the right-hand side
+	// of an assignment or initialization expression does not match the number
+	// of variables on the left-hand side.
+	//
+	// Example:
+	//  var x = 1, 2
+	WrongAssignCount
+
+	// UnassignableOperand occurs when the left-hand side of an assignment is
+	// not assignable.
+	//
+	// Example:
+	//  func f() {
+	//  	const c = 1
+	//  	c = 2
+	//  }
+	UnassignableOperand
+
+	// NoNewVar occurs when a short variable declaration (':=') does not declare
+	// new variables.
+	//
+	// Example:
+	//  func f() {
+	//  	x := 1
+	//  	x := 2
+	//  }
+	NoNewVar
+
+	// MultiValAssignOp occurs when an assignment operation (+=, *=, etc) does
+	// not have single-valued left-hand or right-hand side.
+	//
+	// Per the spec:
+	//  "In assignment operations, both the left- and right-hand expression lists
+	//  must contain exactly one single-valued expression"
+	//
+	// Example:
+	//  func f() int {
+	//  	x, y := 1, 2
+	//  	x, y += 1
+	//  	return x + y
+	//  }
+	MultiValAssignOp
+
+	// InvalidIfaceAssign occurs when a value of type T is used as an
+	// interface, but T does not implement a method of the expected interface.
+	//
+	// Example:
+	//  type I interface {
+	//  	f()
+	//  }
+	//
+	//  type T int
+	//
+	//  var x I = T(1)
+	InvalidIfaceAssign
+
+	// InvalidChanAssign occurs when a chan assignment is invalid.
+	//
+	// Per the spec, a value x is assignable to a channel type T if:
+	//  "x is a bidirectional channel value, T is a channel type, x's type V and
+	//  T have identical element types, and at least one of V or T is not a
+	//  defined type."
+	//
+	// Example:
+	//  type T1 chan int
+	//  type T2 chan int
+	//
+	//  var x T1
+	//  // Invalid assignment because both types are named
+	//  var _ T2 = x
+	InvalidChanAssign
+
+	// IncompatibleAssign occurs when the type of the right-hand side expression
+	// in an assignment cannot be assigned to the type of the variable being
+	// assigned.
+	//
+	// Example:
+	//  var x []int
+	//  var _ int = x
+	IncompatibleAssign
+
+	// UnaddressableFieldAssign occurs when trying to assign to a struct field
+	// in a map value.
+	//
+	// Example:
+	//  func f() {
+	//  	m := make(map[string]struct{i int})
+	//  	m["foo"].i = 42
+	//  }
+	UnaddressableFieldAssign
+
+	// NotAType occurs when the identifier used as the underlying type in a type
+	// declaration or the right-hand side of a type alias does not denote a type.
+	//
+	// Example:
+	//  var S = 2
+	//
+	//  type T S
+	NotAType
+
+	// InvalidArrayLen occurs when an array length is not a constant value.
+	//
+	// Example:
+	//  var n = 3
+	//  var _ = [n]int{}
+	InvalidArrayLen
+
+	// BlankIfaceMethod occurs when a method name is '_'.
+	//
+	// Per the spec:
+	//  "The name of each explicitly specified method must be unique and not
+	//  blank."
+	//
+	// Example:
+	//  type T interface {
+	//  	_(int)
+	//  }
+	BlankIfaceMethod
+
+	// IncomparableMapKey occurs when a map key type does not support the == and
+	// != operators.
+	//
+	// Per the spec:
+	//  "The comparison operators == and != must be fully defined for operands of
+	//  the key type; thus the key type must not be a function, map, or slice."
+	//
+	// Example:
+	//  var x map[T]int
+	//
+	//  type T []int
+	IncomparableMapKey
+
+	// InvalidIfaceEmbed occurs when a non-interface type is embedded in an
+	// interface (for go 1.17 or earlier).
+	_ // not used anymore
+
+	// InvalidPtrEmbed occurs when an embedded field is of the pointer form *T,
+	// and T itself is itself a pointer, an unsafe.Pointer, or an interface.
+	//
+	// Per the spec:
+	//  "An embedded field must be specified as a type name T or as a pointer to
+	//  a non-interface type name *T, and T itself may not be a pointer type."
+	//
+	// Example:
+	//  type T *int
+	//
+	//  type S struct {
+	//  	*T
+	//  }
+	InvalidPtrEmbed
+
+	// BadRecv occurs when a method declaration does not have exactly one
+	// receiver parameter.
+	//
+	// Example:
+	//  func () _() {}
+	BadRecv
+
+	// InvalidRecv occurs when a receiver type expression is not of the form T
+	// or *T, or T is a pointer type.
+	//
+	// Example:
+	//  type T struct {}
+	//
+	//  func (**T) m() {}
+	InvalidRecv
+
+	// DuplicateFieldAndMethod occurs when an identifier appears as both a field
+	// and method name.
+	//
+	// Example:
+	//  type T struct {
+	//  	m int
+	//  }
+	//
+	//  func (T) m() {}
+	DuplicateFieldAndMethod
+
+	// DuplicateMethod occurs when two methods on the same receiver type have
+	// the same name.
+	//
+	// Example:
+	//  type T struct {}
+	//  func (T) m() {}
+	//  func (T) m(i int) int { return i }
+	DuplicateMethod
+
+	// InvalidBlank occurs when a blank identifier is used as a value or type.
+	//
+	// Per the spec:
+	//  "The blank identifier may appear as an operand only on the left-hand side
+	//  of an assignment."
+	//
+	// Example:
+	//  var x = _
+	InvalidBlank
+
+	// InvalidIota occurs when the predeclared identifier iota is used outside
+	// of a constant declaration.
+	//
+	// Example:
+	//  var x = iota
+	InvalidIota
+
+	// MissingInitBody occurs when an init function is missing its body.
+	//
+	// Example:
+	//  func init()
+	MissingInitBody
+
+	// InvalidInitSig occurs when an init function declares parameters or
+	// results.
+	//
+	// Deprecated: no longer emitted by the type checker. _InvalidInitDecl is
+	// used instead.
+	InvalidInitSig
+
+	// InvalidInitDecl occurs when init is declared as anything other than a
+	// function.
+	//
+	// Example:
+	//  var init = 1
+	//
+	// Example:
+	//  func init() int { return 1 }
+	InvalidInitDecl
+
+	// InvalidMainDecl occurs when main is declared as anything other than a
+	// function, in a main package.
+	InvalidMainDecl
+
+	// TooManyValues occurs when a function returns too many values for the
+	// expression context in which it is used.
+	//
+	// Example:
+	//  func ReturnTwo() (int, int) {
+	//  	return 1, 2
+	//  }
+	//
+	//  var x = ReturnTwo()
+	TooManyValues
+
+	// NotAnExpr occurs when a type expression is used where a value expression
+	// is expected.
+	//
+	// Example:
+	//  type T struct {}
+	//
+	//  func f() {
+	//  	T
+	//  }
+	NotAnExpr
+
+	// TruncatedFloat occurs when a float constant is truncated to an integer
+	// value.
+	//
+	// Example:
+	//  var _ int = 98.6
+	TruncatedFloat
+
+	// NumericOverflow occurs when a numeric constant overflows its target type.
+	//
+	// Example:
+	//  var x int8 = 1000
+	NumericOverflow
+
+	// UndefinedOp occurs when an operator is not defined for the type(s) used
+	// in an operation.
+	//
+	// Example:
+	//  var c = "a" - "b"
+	UndefinedOp
+
+	// MismatchedTypes occurs when operand types are incompatible in a binary
+	// operation.
+	//
+	// Example:
+	//  var a = "hello"
+	//  var b = 1
+	//  var c = a - b
+	MismatchedTypes
+
+	// DivByZero occurs when a division operation is provable at compile
+	// time to be a division by zero.
+	//
+	// Example:
+	//  const divisor = 0
+	//  var x int = 1/divisor
+	DivByZero
+
+	// NonNumericIncDec occurs when an increment or decrement operator is
+	// applied to a non-numeric value.
+	//
+	// Example:
+	//  func f() {
+	//  	var c = "c"
+	//  	c++
+	//  }
+	NonNumericIncDec
+
+	// UnaddressableOperand occurs when the & operator is applied to an
+	// unaddressable expression.
+	//
+	// Example:
+	//  var x = &1
+	UnaddressableOperand
+
+	// InvalidIndirection occurs when a non-pointer value is indirected via the
+	// '*' operator.
+	//
+	// Example:
+	//  var x int
+	//  var y = *x
+	InvalidIndirection
+
+	// NonIndexableOperand occurs when an index operation is applied to a value
+	// that cannot be indexed.
+	//
+	// Example:
+	//  var x = 1
+	//  var y = x[1]
+	NonIndexableOperand
+
+	// InvalidIndex occurs when an index argument is not of integer type,
+	// negative, or out-of-bounds.
+	//
+	// Example:
+	//  var s = [...]int{1,2,3}
+	//  var x = s[5]
+	//
+	// Example:
+	//  var s = []int{1,2,3}
+	//  var _ = s[-1]
+	//
+	// Example:
+	//  var s = []int{1,2,3}
+	//  var i string
+	//  var _ = s[i]
+	InvalidIndex
+
+	// SwappedSliceIndices occurs when constant indices in a slice expression
+	// are decreasing in value.
+	//
+	// Example:
+	//  var _ = []int{1,2,3}[2:1]
+	SwappedSliceIndices
+
+	// NonSliceableOperand occurs when a slice operation is applied to a value
+	// whose type is not sliceable, or is unaddressable.
+	//
+	// Example:
+	//  var x = [...]int{1, 2, 3}[:1]
+	//
+	// Example:
+	//  var x = 1
+	//  var y = 1[:1]
+	NonSliceableOperand
+
+	// InvalidSliceExpr occurs when a three-index slice expression (a[x:y:z]) is
+	// applied to a string.
+	//
+	// Example:
+	//  var s = "hello"
+	//  var x = s[1:2:3]
+	InvalidSliceExpr
+
+	// InvalidShiftCount occurs when the right-hand side of a shift operation is
+	// either non-integer, negative, or too large.
+	//
+	// Example:
+	//  var (
+	//  	x string
+	//  	y int = 1 << x
+	//  )
+	InvalidShiftCount
+
+	// InvalidShiftOperand occurs when the shifted operand is not an integer.
+	//
+	// Example:
+	//  var s = "hello"
+	//  var x = s << 2
+	InvalidShiftOperand
+
+	// InvalidReceive occurs when there is a channel receive from a value that
+	// is either not a channel, or is a send-only channel.
+	//
+	// Example:
+	//  func f() {
+	//  	var x = 1
+	//  	<-x
+	//  }
+	InvalidReceive
+
+	// InvalidSend occurs when there is a channel send to a value that is not a
+	// channel, or is a receive-only channel.
+	//
+	// Example:
+	//  func f() {
+	//  	var x = 1
+	//  	x <- "hello!"
+	//  }
+	InvalidSend
+
+	// DuplicateLitKey occurs when an index is duplicated in a slice, array, or
+	// map literal.
+	//
+	// Example:
+	//  var _ = []int{0:1, 0:2}
+	//
+	// Example:
+	//  var _ = map[string]int{"a": 1, "a": 2}
+	DuplicateLitKey
+
+	// MissingLitKey occurs when a map literal is missing a key expression.
+	//
+	// Example:
+	//  var _ = map[string]int{1}
+	MissingLitKey
+
+	// InvalidLitIndex occurs when the key in a key-value element of a slice or
+	// array literal is not an integer constant.
+	//
+	// Example:
+	//  var i = 0
+	//  var x = []string{i: "world"}
+	InvalidLitIndex
+
+	// OversizeArrayLit occurs when an array literal exceeds its length.
+	//
+	// Example:
+	//  var _ = [2]int{1,2,3}
+	OversizeArrayLit
+
+	// MixedStructLit occurs when a struct literal contains a mix of positional
+	// and named elements.
+	//
+	// Example:
+	//  var _ = struct{i, j int}{i: 1, 2}
+	MixedStructLit
+
+	// InvalidStructLit occurs when a positional struct literal has an incorrect
+	// number of values.
+	//
+	// Example:
+	//  var _ = struct{i, j int}{1,2,3}
+	InvalidStructLit
+
+	// MissingLitField occurs when a struct literal refers to a field that does
+	// not exist on the struct type.
+	//
+	// Example:
+	//  var _ = struct{i int}{j: 2}
+	MissingLitField
+
+	// DuplicateLitField occurs when a struct literal contains duplicated
+	// fields.
+	//
+	// Example:
+	//  var _ = struct{i int}{i: 1, i: 2}
+	DuplicateLitField
+
+	// UnexportedLitField occurs when a positional struct literal implicitly
+	// assigns an unexported field of an imported type.
+	UnexportedLitField
+
+	// InvalidLitField occurs when a field name is not a valid identifier.
+	//
+	// Example:
+	//  var _ = struct{i int}{1: 1}
+	InvalidLitField
+
+	// UntypedLit occurs when a composite literal omits a required type
+	// identifier.
+	//
+	// Example:
+	//  type outer struct{
+	//  	inner struct { i int }
+	//  }
+	//
+	//  var _ = outer{inner: {1}}
+	UntypedLit
+
+	// InvalidLit occurs when a composite literal expression does not match its
+	// type.
+	//
+	// Example:
+	//  type P *struct{
+	//  	x int
+	//  }
+	//  var _ = P {}
+	InvalidLit
+
+	// AmbiguousSelector occurs when a selector is ambiguous.
+	//
+	// Example:
+	//  type E1 struct { i int }
+	//  type E2 struct { i int }
+	//  type T struct { E1; E2 }
+	//
+	//  var x T
+	//  var _ = x.i
+	AmbiguousSelector
+
+	// UndeclaredImportedName occurs when a package-qualified identifier is
+	// undeclared by the imported package.
+	//
+	// Example:
+	//  import "go/types"
+	//
+	//  var _ = types.NotAnActualIdentifier
+	UndeclaredImportedName
+
+	// UnexportedName occurs when a selector refers to an unexported identifier
+	// of an imported package.
+	//
+	// Example:
+	//  import "reflect"
+	//
+	//  type _ reflect.flag
+	UnexportedName
+
+	// UndeclaredName occurs when an identifier is not declared in the current
+	// scope.
+	//
+	// Example:
+	//  var x T
+	UndeclaredName
+
+	// MissingFieldOrMethod occurs when a selector references a field or method
+	// that does not exist.
+	//
+	// Example:
+	//  type T struct {}
+	//
+	//  var x = T{}.f
+	MissingFieldOrMethod
+
+	// BadDotDotDotSyntax occurs when a "..." occurs in a context where it is
+	// not valid.
+	//
+	// Example:
+	//  var _ = map[int][...]int{0: {}}
+	BadDotDotDotSyntax
+
+	// NonVariadicDotDotDot occurs when a "..." is used on the final argument to
+	// a non-variadic function.
+	//
+	// Example:
+	//  func printArgs(s []string) {
+	//  	for _, a := range s {
+	//  		println(a)
+	//  	}
+	//  }
+	//
+	//  func f() {
+	//  	s := []string{"a", "b", "c"}
+	//  	printArgs(s...)
+	//  }
+	NonVariadicDotDotDot
+
+	// MisplacedDotDotDot occurs when a "..." is used somewhere other than the
+	// final argument in a function declaration.
+	//
+	// Example:
+	// 	func f(...int, int)
+	MisplacedDotDotDot
+
+	_ // InvalidDotDotDotOperand was removed.
+
+	// InvalidDotDotDot occurs when a "..." is used in a non-variadic built-in
+	// function.
+	//
+	// Example:
+	//  var s = []int{1, 2, 3}
+	//  var l = len(s...)
+	InvalidDotDotDot
+
+	// UncalledBuiltin occurs when a built-in function is used as a
+	// function-valued expression, instead of being called.
+	//
+	// Per the spec:
+	//  "The built-in functions do not have standard Go types, so they can only
+	//  appear in call expressions; they cannot be used as function values."
+	//
+	// Example:
+	//  var _ = copy
+	UncalledBuiltin
+
+	// InvalidAppend occurs when append is called with a first argument that is
+	// not a slice.
+	//
+	// Example:
+	//  var _ = append(1, 2)
+	InvalidAppend
+
+	// InvalidCap occurs when an argument to the cap built-in function is not of
+	// supported type.
+	//
+	// See https://golang.org/ref/spec#Length_and_capacity for information on
+	// which underlying types are supported as arguments to cap and len.
+	//
+	// Example:
+	//  var s = 2
+	//  var x = cap(s)
+	InvalidCap
+
+	// InvalidClose occurs when close(...) is called with an argument that is
+	// not of channel type, or that is a receive-only channel.
+	//
+	// Example:
+	//  func f() {
+	//  	var x int
+	//  	close(x)
+	//  }
+	InvalidClose
+
+	// InvalidCopy occurs when the arguments are not of slice type or do not
+	// have compatible type.
+	//
+	// See https://golang.org/ref/spec#Appending_and_copying_slices for more
+	// information on the type requirements for the copy built-in.
+	//
+	// Example:
+	//  func f() {
+	//  	var x []int
+	//  	y := []int64{1,2,3}
+	//  	copy(x, y)
+	//  }
+	InvalidCopy
+
+	// InvalidComplex occurs when the complex built-in function is called with
+	// arguments with incompatible types.
+	//
+	// Example:
+	//  var _ = complex(float32(1), float64(2))
+	InvalidComplex
+
+	// InvalidDelete occurs when the delete built-in function is called with a
+	// first argument that is not a map.
+	//
+	// Example:
+	//  func f() {
+	//  	m := "hello"
+	//  	delete(m, "e")
+	//  }
+	InvalidDelete
+
+	// InvalidImag occurs when the imag built-in function is called with an
+	// argument that does not have complex type.
+	//
+	// Example:
+	//  var _ = imag(int(1))
+	InvalidImag
+
+	// InvalidLen occurs when an argument to the len built-in function is not of
+	// supported type.
+	//
+	// See https://golang.org/ref/spec#Length_and_capacity for information on
+	// which underlying types are supported as arguments to cap and len.
+	//
+	// Example:
+	//  var s = 2
+	//  var x = len(s)
+	InvalidLen
+
+	// SwappedMakeArgs occurs when make is called with three arguments, and its
+	// length argument is larger than its capacity argument.
+	//
+	// Example:
+	//  var x = make([]int, 3, 2)
+	SwappedMakeArgs
+
+	// InvalidMake occurs when make is called with an unsupported type argument.
+	//
+	// See https://golang.org/ref/spec#Making_slices_maps_and_channels for
+	// information on the types that may be created using make.
+	//
+	// Example:
+	//  var x = make(int)
+	InvalidMake
+
+	// InvalidReal occurs when the real built-in function is called with an
+	// argument that does not have complex type.
+	//
+	// Example:
+	//  var _ = real(int(1))
+	InvalidReal
+
+	// InvalidAssert occurs when a type assertion is applied to a
+	// value that is not of interface type.
+	//
+	// Example:
+	//  var x = 1
+	//  var _ = x.(float64)
+	InvalidAssert
+
+	// ImpossibleAssert occurs for a type assertion x.(T) when the value x of
+	// interface cannot have dynamic type T, due to a missing or mismatching
+	// method on T.
+	//
+	// Example:
+	//  type T int
+	//
+	//  func (t *T) m() int { return int(*t) }
+	//
+	//  type I interface { m() int }
+	//
+	//  var x I
+	//  var _ = x.(T)
+	ImpossibleAssert
+
+	// InvalidConversion occurs when the argument type cannot be converted to the
+	// target.
+	//
+	// See https://golang.org/ref/spec#Conversions for the rules of
+	// convertibility.
+	//
+	// Example:
+	//  var x float64
+	//  var _ = string(x)
+	InvalidConversion
+
+	// InvalidUntypedConversion occurs when there is no valid implicit
+	// conversion from an untyped value satisfying the type constraints of the
+	// context in which it is used.
+	//
+	// Example:
+	//  var _ = 1 + []int{}
+	InvalidUntypedConversion
+
+	// BadOffsetofSyntax occurs when unsafe.Offsetof is called with an argument
+	// that is not a selector expression.
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  var x int
+	//  var _ = unsafe.Offsetof(x)
+	BadOffsetofSyntax
+
+	// InvalidOffsetof occurs when unsafe.Offsetof is called with a method
+	// selector, rather than a field selector, or when the field is embedded via
+	// a pointer.
+	//
+	// Per the spec:
+	//
+	//  "If f is an embedded field, it must be reachable without pointer
+	//  indirections through fields of the struct. "
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  type T struct { f int }
+	//  type S struct { *T }
+	//  var s S
+	//  var _ = unsafe.Offsetof(s.f)
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  type S struct{}
+	//
+	//  func (S) m() {}
+	//
+	//  var s S
+	//  var _ = unsafe.Offsetof(s.m)
+	InvalidOffsetof
+
+	// UnusedExpr occurs when a side-effect free expression is used as a
+	// statement. Such a statement has no effect.
+	//
+	// Example:
+	//  func f(i int) {
+	//  	i*i
+	//  }
+	UnusedExpr
+
+	// UnusedVar occurs when a variable is declared but unused.
+	//
+	// Example:
+	//  func f() {
+	//  	x := 1
+	//  }
+	UnusedVar
+
+	// MissingReturn occurs when a function with results is missing a return
+	// statement.
+	//
+	// Example:
+	//  func f() int {}
+	MissingReturn
+
+	// WrongResultCount occurs when a return statement returns an incorrect
+	// number of values.
+	//
+	// Example:
+	//  func ReturnOne() int {
+	//  	return 1, 2
+	//  }
+	WrongResultCount
+
+	// OutOfScopeResult occurs when the name of a value implicitly returned by
+	// an empty return statement is shadowed in a nested scope.
+	//
+	// Example:
+	//  func factor(n int) (i int) {
+	//  	for i := 2; i < n; i++ {
+	//  		if n%i == 0 {
+	//  			return
+	//  		}
+	//  	}
+	//  	return 0
+	//  }
+	OutOfScopeResult
+
+	// InvalidCond occurs when an if condition is not a boolean expression.
+	//
+	// Example:
+	//  func checkReturn(i int) {
+	//  	if i {
+	//  		panic("non-zero return")
+	//  	}
+	//  }
+	InvalidCond
+
+	// InvalidPostDecl occurs when there is a declaration in a for-loop post
+	// statement.
+	//
+	// Example:
+	//  func f() {
+	//  	for i := 0; i < 10; j := 0 {}
+	//  }
+	InvalidPostDecl
+
+	_ // InvalidChanRange was removed.
+
+	// InvalidIterVar occurs when two iteration variables are used while ranging
+	// over a channel.
+	//
+	// Example:
+	//  func f(c chan int) {
+	//  	for k, v := range c {
+	//  		println(k, v)
+	//  	}
+	//  }
+	InvalidIterVar
+
+	// InvalidRangeExpr occurs when the type of a range expression is not array,
+	// slice, string, map, or channel.
+	//
+	// Example:
+	//  func f(i int) {
+	//  	for j := range i {
+	//  		println(j)
+	//  	}
+	//  }
+	InvalidRangeExpr
+
+	// MisplacedBreak occurs when a break statement is not within a for, switch,
+	// or select statement of the innermost function definition.
+	//
+	// Example:
+	//  func f() {
+	//  	break
+	//  }
+	MisplacedBreak
+
+	// MisplacedContinue occurs when a continue statement is not within a for
+	// loop of the innermost function definition.
+	//
+	// Example:
+	//  func sumeven(n int) int {
+	//  	proceed := func() {
+	//  		continue
+	//  	}
+	//  	sum := 0
+	//  	for i := 1; i <= n; i++ {
+	//  		if i % 2 != 0 {
+	//  			proceed()
+	//  		}
+	//  		sum += i
+	//  	}
+	//  	return sum
+	//  }
+	MisplacedContinue
+
+	// MisplacedFallthrough occurs when a fallthrough statement is not within an
+	// expression switch.
+	//
+	// Example:
+	//  func typename(i interface{}) string {
+	//  	switch i.(type) {
+	//  	case int64:
+	//  		fallthrough
+	//  	case int:
+	//  		return "int"
+	//  	}
+	//  	return "unsupported"
+	//  }
+	MisplacedFallthrough
+
+	// DuplicateCase occurs when a type or expression switch has duplicate
+	// cases.
+	//
+	// Example:
+	//  func printInt(i int) {
+	//  	switch i {
+	//  	case 1:
+	//  		println("one")
+	//  	case 1:
+	//  		println("One")
+	//  	}
+	//  }
+	DuplicateCase
+
+	// DuplicateDefault occurs when a type or expression switch has multiple
+	// default clauses.
+	//
+	// Example:
+	//  func printInt(i int) {
+	//  	switch i {
+	//  	case 1:
+	//  		println("one")
+	//  	default:
+	//  		println("One")
+	//  	default:
+	//  		println("1")
+	//  	}
+	//  }
+	DuplicateDefault
+
+	// BadTypeKeyword occurs when a .(type) expression is used anywhere other
+	// than a type switch.
+	//
+	// Example:
+	//  type I interface {
+	//  	m()
+	//  }
+	//  var t I
+	//  var _ = t.(type)
+	BadTypeKeyword
+
+	// InvalidTypeSwitch occurs when .(type) is used on an expression that is
+	// not of interface type.
+	//
+	// Example:
+	//  func f(i int) {
+	//  	switch x := i.(type) {}
+	//  }
+	InvalidTypeSwitch
+
+	// InvalidExprSwitch occurs when a switch expression is not comparable.
+	//
+	// Example:
+	//  func _() {
+	//  	var a struct{ _ func() }
+	//  	switch a /* ERROR cannot switch on a */ {
+	//  	}
+	//  }
+	InvalidExprSwitch
+
+	// InvalidSelectCase occurs when a select case is not a channel send or
+	// receive.
+	//
+	// Example:
+	//  func checkChan(c <-chan int) bool {
+	//  	select {
+	//  	case c:
+	//  		return true
+	//  	default:
+	//  		return false
+	//  	}
+	//  }
+	InvalidSelectCase
+
+	// UndeclaredLabel occurs when an undeclared label is jumped to.
+	//
+	// Example:
+	//  func f() {
+	//  	goto L
+	//  }
+	UndeclaredLabel
+
+	// DuplicateLabel occurs when a label is declared more than once.
+	//
+	// Example:
+	//  func f() int {
+	//  L:
+	//  L:
+	//  	return 1
+	//  }
+	DuplicateLabel
+
+	// MisplacedLabel occurs when a break or continue label is not on a for,
+	// switch, or select statement.
+	//
+	// Example:
+	//  func f() {
+	//  L:
+	//  	a := []int{1,2,3}
+	//  	for _, e := range a {
+	//  		if e > 10 {
+	//  			break L
+	//  		}
+	//  		println(a)
+	//  	}
+	//  }
+	MisplacedLabel
+
+	// UnusedLabel occurs when a label is declared and not used.
+	//
+	// Example:
+	//  func f() {
+	//  L:
+	//  }
+	UnusedLabel
+
+	// JumpOverDecl occurs when a label jumps over a variable declaration.
+	//
+	// Example:
+	//  func f() int {
+	//  	goto L
+	//  	x := 2
+	//  L:
+	//  	x++
+	//  	return x
+	//  }
+	JumpOverDecl
+
+	// JumpIntoBlock occurs when a forward jump goes to a label inside a nested
+	// block.
+	//
+	// Example:
+	//  func f(x int) {
+	//  	goto L
+	//  	if x > 0 {
+	//  	L:
+	//  		print("inside block")
+	//  	}
+	// }
+	JumpIntoBlock
+
+	// InvalidMethodExpr occurs when a pointer method is called but the argument
+	// is not addressable.
+	//
+	// Example:
+	//  type T struct {}
+	//
+	//  func (*T) m() int { return 1 }
+	//
+	//  var _ = T.m(T{})
+	InvalidMethodExpr
+
+	// WrongArgCount occurs when too few or too many arguments are passed by a
+	// function call.
+	//
+	// Example:
+	//  func f(i int) {}
+	//  var x = f()
+	WrongArgCount
+
+	// InvalidCall occurs when an expression is called that is not of function
+	// type.
+	//
+	// Example:
+	//  var x = "x"
+	//  var y = x()
+	InvalidCall
+
+	// UnusedResults occurs when a restricted expression-only built-in function
+	// is suspended via go or defer. Such a suspension discards the results of
+	// these side-effect free built-in functions, and therefore is ineffectual.
+	//
+	// Example:
+	//  func f(a []int) int {
+	//  	defer len(a)
+	//  	return i
+	//  }
+	UnusedResults
+
+	// InvalidDefer occurs when a deferred expression is not a function call,
+	// for example if the expression is a type conversion.
+	//
+	// Example:
+	//  func f(i int) int {
+	//  	defer int32(i)
+	//  	return i
+	//  }
+	InvalidDefer
+
+	// InvalidGo occurs when a go expression is not a function call, for example
+	// if the expression is a type conversion.
+	//
+	// Example:
+	//  func f(i int) int {
+	//  	go int32(i)
+	//  	return i
+	//  }
+	InvalidGo
+
+	// All codes below were added in Go 1.17.
+
+	// BadDecl occurs when a declaration has invalid syntax.
+	BadDecl
+
+	// RepeatedDecl occurs when an identifier occurs more than once on the left
+	// hand side of a short variable declaration.
+	//
+	// Example:
+	//  func _() {
+	//  	x, y, y := 1, 2, 3
+	//  }
+	RepeatedDecl
+
+	// InvalidUnsafeAdd occurs when unsafe.Add is called with a
+	// length argument that is not of integer type.
+	// It also occurs if it is used in a package compiled for a
+	// language version before go1.17.
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  var p unsafe.Pointer
+	//  var _ = unsafe.Add(p, float64(1))
+	InvalidUnsafeAdd
+
+	// InvalidUnsafeSlice occurs when unsafe.Slice is called with a
+	// pointer argument that is not of pointer type or a length argument
+	// that is not of integer type, negative, or out of bounds.
+	// It also occurs if it is used in a package compiled for a language
+	// version before go1.17.
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  var x int
+	//  var _ = unsafe.Slice(x, 1)
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  var x int
+	//  var _ = unsafe.Slice(&x, float64(1))
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  var x int
+	//  var _ = unsafe.Slice(&x, -1)
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  var x int
+	//  var _ = unsafe.Slice(&x, uint64(1) << 63)
+	InvalidUnsafeSlice
+
+	// All codes below were added in Go 1.18.
+
+	// UnsupportedFeature occurs when a language feature is used that is not
+	// supported at this Go version.
+	UnsupportedFeature
+
+	// NotAGenericType occurs when a non-generic type is used where a generic
+	// type is expected: in type or function instantiation.
+	//
+	// Example:
+	//  type T int
+	//
+	//  var _ T[int]
+	NotAGenericType
+
+	// WrongTypeArgCount occurs when a type or function is instantiated with an
+	// incorrent number of type arguments, including when a generic type or
+	// function is used without instantiation.
+	//
+	// Errors inolving failed type inference are assigned other error codes.
+	//
+	// Example:
+	//  type T[p any] int
+	//
+	//  var _ T[int, string]
+	//
+	// Example:
+	//  func f[T any]() {}
+	//
+	//  var x = f
+	WrongTypeArgCount
+
+	// CannotInferTypeArgs occurs when type or function type argument inference
+	// fails to infer all type arguments.
+	//
+	// Example:
+	//  func f[T any]() {}
+	//
+	//  func _() {
+	//  	f()
+	//  }
+	CannotInferTypeArgs
+
+	// InvalidTypeArg occurs when a type argument does not satisfy its
+	// corresponding type parameter constraints.
+	//
+	// Example:
+	//  type T[P ~int] struct{}
+	//
+	//  var _ T[string]
+	InvalidTypeArg // arguments? InferenceFailed
+
+	// InvalidInstanceCycle occurs when an invalid cycle is detected
+	// within the instantiation graph.
+	//
+	// Example:
+	//  func f[T any]() { f[*T]() }
+	InvalidInstanceCycle
+
+	// InvalidUnion occurs when an embedded union or approximation element is
+	// not valid.
+	//
+	// Example:
+	//  type _ interface {
+	//   	~int | interface{ m() }
+	//  }
+	InvalidUnion
+
+	// MisplacedConstraintIface occurs when a constraint-type interface is used
+	// outside of constraint position.
+	//
+	// Example:
+	//   type I interface { ~int }
+	//
+	//   var _ I
+	MisplacedConstraintIface
+
+	// InvalidMethodTypeParams occurs when methods have type parameters.
+	//
+	// It cannot be encountered with an AST parsed using go/parser.
+	InvalidMethodTypeParams
+
+	// MisplacedTypeParam occurs when a type parameter is used in a place where
+	// it is not permitted.
+	//
+	// Example:
+	//  type T[P any] P
+	//
+	// Example:
+	//  type T[P any] struct{ *P }
+	MisplacedTypeParam
+
+	// InvalidUnsafeSliceData occurs when unsafe.SliceData is called with
+	// an argument that is not of slice type. It also occurs if it is used
+	// in a package compiled for a language version before go1.20.
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  var x int
+	//  var _ = unsafe.SliceData(x)
+	InvalidUnsafeSliceData
+
+	// InvalidUnsafeString occurs when unsafe.String is called with
+	// a length argument that is not of integer type, negative, or
+	// out of bounds. It also occurs if it is used in a package
+	// compiled for a language version before go1.20.
+	//
+	// Example:
+	//  import "unsafe"
+	//
+	//  var b [10]byte
+	//  var _ = unsafe.String(&b[0], -1)
+	InvalidUnsafeString
+
+	// InvalidUnsafeStringData occurs if it is used in a package
+	// compiled for a language version before go1.20.
+	_ // not used anymore
+
+	// InvalidClear occurs when clear is called with an argument
+	// that is not of map, slice, or pointer-to-array type.
+	//
+	// Example:
+	//  func _(x int) {
+	//  	clear(x)
+	//  }
+	InvalidClear
+)
diff --git a/src/internal/types/errors/codes_test.go b/src/internal/types/errors/codes_test.go
new file mode 100644
index 0000000..2490ade
--- /dev/null
+++ b/src/internal/types/errors/codes_test.go
@@ -0,0 +1,197 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package errors_test
+
+import (
+	"fmt"
+	"go/ast"
+	"go/constant"
+	"go/importer"
+	"go/parser"
+	"go/token"
+	"internal/testenv"
+	"reflect"
+	"strings"
+	"testing"
+
+	. "go/types"
+)
+
+func TestErrorCodeExamples(t *testing.T) {
+	testenv.MustHaveGoBuild(t) // go command needed to resolve std .a files for importer.Default().
+
+	walkCodes(t, func(name string, value int, spec *ast.ValueSpec) {
+		t.Run(name, func(t *testing.T) {
+			doc := spec.Doc.Text()
+			examples := strings.Split(doc, "Example:")
+			for i := 1; i < len(examples); i++ {
+				example := strings.TrimSpace(examples[i])
+				err := checkExample(t, example)
+				if err == nil {
+					t.Fatalf("no error in example #%d", i)
+				}
+				typerr, ok := err.(Error)
+				if !ok {
+					t.Fatalf("not a types.Error: %v", err)
+				}
+				if got := readCode(typerr); got != value {
+					t.Errorf("%s: example #%d returned code %d (%s), want %d", name, i, got, err, value)
+				}
+			}
+		})
+	})
+}
+
+func walkCodes(t *testing.T, f func(string, int, *ast.ValueSpec)) {
+	t.Helper()
+	fset := token.NewFileSet()
+	file, err := parser.ParseFile(fset, "codes.go", nil, parser.ParseComments)
+	if err != nil {
+		t.Fatal(err)
+	}
+	conf := Config{Importer: importer.Default()}
+	info := &Info{
+		Types: make(map[ast.Expr]TypeAndValue),
+		Defs:  make(map[*ast.Ident]Object),
+		Uses:  make(map[*ast.Ident]Object),
+	}
+	_, err = conf.Check("types", fset, []*ast.File{file}, info)
+	if err != nil {
+		t.Fatal(err)
+	}
+	for _, decl := range file.Decls {
+		decl, ok := decl.(*ast.GenDecl)
+		if !ok || decl.Tok != token.CONST {
+			continue
+		}
+		for _, spec := range decl.Specs {
+			spec, ok := spec.(*ast.ValueSpec)
+			if !ok || len(spec.Names) == 0 {
+				continue
+			}
+			obj := info.ObjectOf(spec.Names[0])
+			if named, ok := obj.Type().(*Named); ok && named.Obj().Name() == "Code" {
+				if len(spec.Names) != 1 {
+					t.Fatalf("bad Code declaration for %q: got %d names, want exactly 1", spec.Names[0].Name, len(spec.Names))
+				}
+				codename := spec.Names[0].Name
+				value := int(constant.Val(obj.(*Const).Val()).(int64))
+				f(codename, value, spec)
+			}
+		}
+	}
+}
+
+func readCode(err Error) int {
+	v := reflect.ValueOf(err)
+	return int(v.FieldByName("go116code").Int())
+}
+
+func checkExample(t *testing.T, example string) error {
+	t.Helper()
+	fset := token.NewFileSet()
+	if !strings.HasPrefix(example, "package") {
+		example = "package p\n\n" + example
+	}
+	file, err := parser.ParseFile(fset, "example.go", example, 0)
+	if err != nil {
+		t.Fatal(err)
+	}
+	conf := Config{
+		FakeImportC: true,
+		Importer:    importer.Default(),
+	}
+	_, err = conf.Check("example", fset, []*ast.File{file}, nil)
+	return err
+}
+
+func TestErrorCodeStyle(t *testing.T) {
+	// The set of error codes is large and intended to be self-documenting, so
+	// this test enforces some style conventions.
+	forbiddenInIdent := []string{
+		// use invalid instead
+		"illegal",
+		// words with a common short-form
+		"argument",
+		"assertion",
+		"assignment",
+		"boolean",
+		"channel",
+		"condition",
+		"declaration",
+		"expression",
+		"function",
+		"initial", // use init for initializer, initialization, etc.
+		"integer",
+		"interface",
+		"iterat", // use iter for iterator, iteration, etc.
+		"literal",
+		"operation",
+		"package",
+		"pointer",
+		"receiver",
+		"signature",
+		"statement",
+		"variable",
+	}
+	forbiddenInComment := []string{
+		// lhs and rhs should be spelled-out.
+		"lhs", "rhs",
+		// builtin should be hyphenated.
+		"builtin",
+		// Use dot-dot-dot.
+		"ellipsis",
+	}
+	nameHist := make(map[int]int)
+	longestName := ""
+	maxValue := 0
+
+	walkCodes(t, func(name string, value int, spec *ast.ValueSpec) {
+		if name == "_" {
+			return
+		}
+		nameHist[len(name)]++
+		if value > maxValue {
+			maxValue = value
+		}
+		if len(name) > len(longestName) {
+			longestName = name
+		}
+		if !token.IsExported(name) {
+			t.Errorf("%q is not exported", name)
+		}
+		lower := strings.ToLower(name)
+		for _, bad := range forbiddenInIdent {
+			if strings.Contains(lower, bad) {
+				t.Errorf("%q contains forbidden word %q", name, bad)
+			}
+		}
+		doc := spec.Doc.Text()
+		if doc == "" {
+			t.Errorf("%q is undocumented", name)
+		} else if !strings.HasPrefix(doc, name) {
+			t.Errorf("doc for %q does not start with the error code name", name)
+		}
+		lowerComment := strings.ToLower(strings.TrimPrefix(doc, name))
+		for _, bad := range forbiddenInComment {
+			if strings.Contains(lowerComment, bad) {
+				t.Errorf("doc for %q contains forbidden word %q", name, bad)
+			}
+		}
+	})
+
+	if testing.Verbose() {
+		var totChars, totCount int
+		for chars, count := range nameHist {
+			totChars += chars * count
+			totCount += count
+		}
+		avg := float64(totChars) / float64(totCount)
+		fmt.Println()
+		fmt.Printf("%d error codes\n", totCount)
+		fmt.Printf("average length: %.2f chars\n", avg)
+		fmt.Printf("max length: %d (%s)\n", len(longestName), longestName)
+	}
+}
diff --git a/src/go/types/testdata/check/blank.go b/src/internal/types/testdata/check/blank.go
similarity index 100%
rename from src/go/types/testdata/check/blank.go
rename to src/internal/types/testdata/check/blank.go
diff --git a/src/internal/types/testdata/check/builtins0.go b/src/internal/types/testdata/check/builtins0.go
new file mode 100644
index 0000000..308f70b
--- /dev/null
+++ b/src/internal/types/testdata/check/builtins0.go
@@ -0,0 +1,967 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// builtin calls
+
+package builtins
+
+import "unsafe"
+
+func f0() {}
+
+func append1() {
+	var b byte
+	var x int
+	var s []byte
+	_ = append() // ERROR not enough arguments
+	_ = append("foo" /* ERROR must be a slice */ )
+	_ = append(nil /* ERROR must be a slice */ , s)
+	_ = append(x /* ERROR must be a slice */ , s)
+	_ = append(s)
+	_ = append(s, nil...)
+	append /* ERROR not used */ (s)
+
+	_ = append(s, b)
+	_ = append(s, x /* ERROR cannot use x */ )
+	_ = append(s, s /* ERROR cannot use s */ )
+	_ = append(s...) /* ERROR not enough arguments */
+	_ = append(s, b, s /* ERROR too many arguments */ ...)
+	_ = append(s, 1, 2, 3)
+	_ = append(s, 1, 2, 3, x /* ERROR cannot use x */ , 5, 6, 6)
+	_ = append(s, 1, 2 /* ERROR too many arguments */, s...)
+	_ = append([]interface{}(nil), 1, 2, "foo", x, 3.1425, false)
+
+	type S []byte
+	type T string
+	var t T
+	_ = append(s, "foo" /* ERROR cannot use .* in argument to append */ )
+	_ = append(s, "foo"...)
+	_ = append(S(s), "foo" /* ERROR cannot use .* in argument to append */ )
+	_ = append(S(s), "foo"...)
+	_ = append(s, t /* ERROR cannot use t */ )
+	_ = append(s, t...)
+	_ = append(s, T("foo")...)
+	_ = append(S(s), t /* ERROR cannot use t */ )
+	_ = append(S(s), t...)
+	_ = append(S(s), T("foo")...)
+	_ = append([]string{}, t /* ERROR cannot use t */ , "foo")
+	_ = append([]T{}, t, "foo")
+}
+
+// from the spec
+func append2() {
+	s0 := []int{0, 0}
+	s1 := append(s0, 2)                // append a single element     s1 == []int{0, 0, 2}
+	s2 := append(s1, 3, 5, 7)          // append multiple elements    s2 == []int{0, 0, 2, 3, 5, 7}
+	s3 := append(s2, s0...)            // append a slice              s3 == []int{0, 0, 2, 3, 5, 7, 0, 0}
+	s4 := append(s3[3:6], s3[2:]...)   // append overlapping slice    s4 == []int{3, 5, 7, 2, 3, 5, 7, 0, 0}
+
+	var t []interface{}
+	t = append(t, 42, 3.1415, "foo")   //                             t == []interface{}{42, 3.1415, "foo"}
+
+	var b []byte
+	b = append(b, "bar"...)            // append string contents      b == []byte{'b', 'a', 'r' }
+
+	_ = s4
+}
+
+func append3() {
+	f1 := func() (s []int) { return }
+	f2 := func() (s []int, x int) { return }
+	f3 := func() (s []int, x, y int) { return }
+	f5 := func() (s []interface{}, x int, y float32, z string, b bool) { return }
+	ff := func() (int, float32) { return 0, 0 }
+	_ = append(f0 /* ERROR used as value */ ())
+	_ = append(f1())
+	_ = append(f2())
+	_ = append(f3())
+	_ = append(f5())
+	_ = append(ff /* ERROR must be a slice */ ()) // TODO(gri) better error message
+}
+
+func cap1() {
+	var a [10]bool
+	var p *[20]int
+	var c chan string
+	_ = cap() // ERROR not enough arguments
+	_ = cap(1, 2) // ERROR too many arguments
+	_ = cap(42 /* ERROR invalid */)
+	const _3 = cap(a)
+	assert(_3 == 10)
+	const _4 = cap(p)
+	assert(_4 == 20)
+	_ = cap(c)
+	cap /* ERROR not used */ (c)
+
+	// issue 4744
+	type T struct{ a [10]int }
+	const _ = cap(((*T)(nil)).a)
+
+	var s [][]byte
+	_ = cap(s)
+	_ = cap(s... /* ERROR invalid use of \.\.\. */ )
+}
+
+func cap2() {
+	f1a := func() (a [10]int) { return }
+	f1s := func() (s []int) { return }
+	f2 := func() (s []int, x int) { return }
+	_ = cap(f0 /* ERROR used as value */ ())
+	_ = cap(f1a())
+	_ = cap(f1s())
+	_ = cap(f2()) // ERROR too many arguments
+}
+
+// test cases for issue 7387
+func cap3() {
+	var f = func() int { return 0 }
+	var x = f()
+	const (
+		_ = cap([4]int{})
+		_ = cap([4]int{x})
+		_ = cap /* ERROR not constant */ ([4]int{f()})
+		_ = cap /* ERROR not constant */ ([4]int{cap([]int{})})
+		_ = cap([4]int{cap([4]int{})})
+	)
+	var y float64
+	var z complex128
+	const (
+		_ = cap([4]float64{})
+		_ = cap([4]float64{y})
+		_ = cap([4]float64{real(2i)})
+		_ = cap /* ERROR not constant */ ([4]float64{real(z)})
+	)
+	var ch chan [10]int
+	const (
+		_ = cap /* ERROR not constant */ (<-ch)
+		_ = cap /* ERROR not constant */ ([4]int{(<-ch)[0]})
+	)
+}
+
+func clear1() {
+	var a [10]int
+	var m map[float64]string
+	var s []byte
+	clear(a /* ERROR cannot clear a */)
+	clear(&a)
+	clear(m)
+	clear(s)
+	clear([]int{})
+}
+
+func close1() {
+	var c chan int
+	var r <-chan int
+	close() // ERROR not enough arguments
+	close(1, 2) // ERROR too many arguments
+	close(42 /* ERROR cannot close non-channel */)
+	close(r /* ERROR receive-only channel */)
+	close(c)
+	_ = close /* ERROR used as value */ (c)
+
+	var s []chan int
+	close(s... /* ERROR invalid use of \.\.\. */ )
+}
+
+func close2() {
+	f1 := func() (ch chan int) { return }
+	f2 := func() (ch chan int, x int) { return }
+	close(f0 /* ERROR used as value */ ())
+	close(f1())
+	close(f2()) // ERROR too many arguments
+}
+
+func complex1() {
+	var i32 int32
+	var f32 float32
+	var f64 float64
+	var c64 complex64
+	var c128 complex128
+	_ = complex() // ERROR not enough arguments
+	_ = complex(1) // ERROR not enough arguments
+	_ = complex(true /* ERROR mismatched types */ , 0)
+	_ = complex(i32 /* ERROR expected floating-point */ , 0)
+	_ = complex("foo" /* ERROR mismatched types */ , 0)
+	_ = complex(c64 /* ERROR expected floating-point */ , 0)
+	_ = complex(0 /* ERROR mismatched types */ , true)
+	_ = complex(0 /* ERROR expected floating-point */ , i32)
+	_ = complex(0 /* ERROR mismatched types */ , "foo")
+	_ = complex(0 /* ERROR expected floating-point */ , c64)
+	_ = complex(f32, f32)
+	_ = complex(f32, 1)
+	_ = complex(f32, 1.0)
+	_ = complex(f32, 'a')
+	_ = complex(f64, f64)
+	_ = complex(f64, 1)
+	_ = complex(f64, 1.0)
+	_ = complex(f64, 'a')
+	_ = complex(f32 /* ERROR mismatched types */ , f64)
+	_ = complex(f64 /* ERROR mismatched types */ , f32)
+	_ = complex(1, 1)
+	_ = complex(1, 1.1)
+	_ = complex(1, 'a')
+	complex /* ERROR not used */ (1, 2)
+
+	var _ complex64 = complex(f32, f32)
+	var _ complex64 = complex /* ERROR cannot use .* in variable declaration */ (f64, f64)
+
+	var _ complex128 = complex /* ERROR cannot use .* in variable declaration */ (f32, f32)
+	var _ complex128 = complex(f64, f64)
+
+	// untyped constants
+	const _ int = complex(1, 0)
+	const _ float32 = complex(1, 0)
+	const _ complex64 = complex(1, 0)
+	const _ complex128 = complex(1, 0)
+	const _ = complex(0i, 0i)
+	const _ = complex(0i, 0)
+	const _ int = 1.0 + complex(1, 0i)
+
+	const _ int = complex /* ERROR int */ (1.1, 0)
+	const _ float32 = complex /* ERROR float32 */ (1, 2)
+
+	// untyped values
+	var s uint
+	_ = complex(1 /* ERROR integer */ <<s, 0)
+	const _ = complex /* ERROR not constant */ (1 /* ERROR integer */ <<s, 0)
+	var _ int = complex /* ERROR cannot use .* in variable declaration */ (1 /* ERROR integer */ <<s, 0)
+
+	// floating-point argument types must be identical
+	type F32 float32
+	type F64 float64
+	var x32 F32
+	var x64 F64
+	c64 = complex(x32, x32)
+	_ = complex(x32 /* ERROR mismatched types */ , f32)
+	_ = complex(f32 /* ERROR mismatched types */ , x32)
+	c128 = complex(x64, x64)
+	_ = c128
+	_ = complex(x64 /* ERROR mismatched types */ , f64)
+	_ = complex(f64 /* ERROR mismatched types */ , x64)
+
+	var t []float32
+	_ = complex(t... /* ERROR invalid use of \.\.\. */ )
+}
+
+func complex2() {
+	f1 := func() (x float32) { return }
+	f2 := func() (x, y float32) { return }
+	f3 := func() (x, y, z float32) { return }
+	_ = complex(f0 /* ERROR used as value */ ())
+	_ = complex(f1()) // ERROR not enough arguments
+	_ = complex(f2())
+	_ = complex(f3()) // ERROR too many arguments
+}
+
+func copy1() {
+	copy() // ERROR not enough arguments
+	copy("foo") // ERROR not enough arguments
+	copy([ /* ERROR copy expects slice arguments */ ...]int{}, []int{})
+	copy([ /* ERROR copy expects slice arguments */ ]int{}, [...]int{})
+	copy([ /* ERROR different element types */ ]int8{}, "foo")
+
+	// spec examples
+	var a = [...]int{0, 1, 2, 3, 4, 5, 6, 7}
+	var s = make([]int, 6)
+	var b = make([]byte, 5)
+	n1 := copy(s, a[0:])            // n1 == 6, s == []int{0, 1, 2, 3, 4, 5}
+	n2 := copy(s, s[2:])            // n2 == 4, s == []int{2, 3, 4, 5, 4, 5}
+	n3 := copy(b, "Hello, World!")  // n3 == 5, b == []byte("Hello")
+	_, _, _ = n1, n2, n3
+
+	var t [][]int
+	copy(t, t)
+	copy(t /* ERROR copy expects slice arguments */ , nil)
+	copy(nil /* ERROR copy expects slice arguments */ , t)
+	copy(nil /* ERROR copy expects slice arguments */ , nil)
+	copy(t... /* ERROR invalid use of \.\.\. */ )
+}
+
+func copy2() {
+	f1 := func() (a []int) { return }
+	f2 := func() (a, b []int) { return }
+	f3 := func() (a, b, c []int) { return }
+	copy(f0 /* ERROR used as value */ ())
+	copy(f1()) // ERROR not enough arguments
+	copy(f2())
+	copy(f3()) // ERROR too many arguments
+}
+
+func delete1() {
+	var m map[string]int
+	var s string
+	delete() // ERROR not enough arguments
+	delete(1) // ERROR not enough arguments
+	delete(1, 2, 3) // ERROR too many arguments
+	delete(m, 0 /* ERROR cannot use */)
+	delete(m, s)
+	_ = delete /* ERROR used as value */ (m, s)
+
+	var t []map[string]string
+	delete(t... /* ERROR invalid use of \.\.\. */ )
+}
+
+func delete2() {
+	f1 := func() (m map[string]int) { return }
+	f2 := func() (m map[string]int, k string) { return }
+	f3 := func() (m map[string]int, k string, x float32) { return }
+	delete(f0 /* ERROR used as value */ ())
+	delete(f1()) // ERROR not enough arguments
+	delete(f2())
+	delete(f3()) // ERROR too many arguments
+}
+
+func imag1() {
+	var f32 float32
+	var f64 float64
+	var c64 complex64
+	var c128 complex128
+	_ = imag() // ERROR not enough arguments
+	_ = imag(1, 2) // ERROR too many arguments
+	_ = imag(10)
+	_ = imag(2.7182818)
+	_ = imag("foo" /* ERROR expected complex */)
+	_ = imag('a')
+	const _5 = imag(1 + 2i)
+	assert(_5 == 2)
+	f32 = _5
+	f64 = _5
+	const _6 = imag(0i)
+	assert(_6 == 0)
+	f32 = imag(c64)
+	f64 = imag(c128)
+	f32 = imag /* ERROR cannot use .* in assignment */ (c128)
+	f64 = imag /* ERROR cannot use .* in assignment */ (c64)
+	imag /* ERROR not used */ (c64)
+	_, _ = f32, f64
+
+	// complex type may not be predeclared
+	type C64 complex64
+	type C128 complex128
+	var x64 C64
+	var x128 C128
+	f32 = imag(x64)
+	f64 = imag(x128)
+
+	var a []complex64
+	_ = imag(a... /* ERROR invalid use of \.\.\. */ )
+
+	// if argument is untyped, result is untyped
+	const _ byte = imag(1.2 + 3i)
+	const _ complex128 = imag(1.2 + 3i)
+
+	// lhs constant shift operands are typed as complex128
+	var s uint
+	_ = imag(1 /* ERROR must be integer */ << s)
+}
+
+func imag2() {
+	f1 := func() (x complex128) { return }
+	f2 := func() (x, y complex128) { return }
+	_ = imag(f0 /* ERROR used as value */ ())
+	_ = imag(f1())
+	_ = imag(f2()) // ERROR too many arguments
+}
+
+func len1() {
+	const c = "foobar"
+	var a [10]bool
+	var p *[20]int
+	var m map[string]complex128
+	_ = len() // ERROR not enough arguments
+	_ = len(1, 2) // ERROR too many arguments
+	_ = len(42 /* ERROR invalid */)
+	const _3 = len(c)
+	assert(_3 == 6)
+	const _4 = len(a)
+	assert(_4 == 10)
+	const _5 = len(p)
+	assert(_5 == 20)
+	_ = len(m)
+	len /* ERROR not used */ (c)
+
+	// esoteric case
+	var t string
+	var hash map[interface{}][]*[10]int
+	const n = len /* ERROR not constant */ (hash[recover()][len(t)])
+	assert(n == 10) // ok because n has unknown value and no error is reported
+	var ch <-chan int
+	const nn = len /* ERROR not constant */ (hash[<-ch][len(t)])
+
+	// issue 4744
+	type T struct{ a [10]int }
+	const _ = len(((*T)(nil)).a)
+
+	var s [][]byte
+	_ = len(s)
+	_ = len(s... /* ERROR invalid use of \.\.\. */ )
+}
+
+func len2() {
+	f1 := func() (x []int) { return }
+	f2 := func() (x, y []int) { return }
+	_ = len(f0 /* ERROR used as value */ ())
+	_ = len(f1())
+	_ = len(f2()) // ERROR too many arguments
+}
+
+// test cases for issue 7387
+func len3() {
+	var f = func() int { return 0 }
+	var x = f()
+	const (
+		_ = len([4]int{})
+		_ = len([4]int{x})
+		_ = len /* ERROR not constant */ ([4]int{f()})
+		_ = len /* ERROR not constant */ ([4]int{len([]int{})})
+		_ = len([4]int{len([4]int{})})
+	)
+	var y float64
+	var z complex128
+	const (
+		_ = len([4]float64{})
+		_ = len([4]float64{y})
+		_ = len([4]float64{real(2i)})
+		_ = len /* ERROR not constant */ ([4]float64{real(z)})
+	)
+	var ch chan [10]int
+	const (
+		_ = len /* ERROR not constant */ (<-ch)
+		_ = len /* ERROR not constant */ ([4]int{(<-ch)[0]})
+	)
+}
+
+func make1() {
+	var n int
+	var m float32
+	var s uint
+
+	_ = make() // ERROR not enough arguments
+	_ = make(1 /* ERROR not a type */)
+	_ = make(int /* ERROR cannot make */)
+
+	// slices
+	_ = make/* ERROR arguments */ ([]int)
+	_ = make/* ERROR arguments */ ([]int, 2, 3, 4)
+	_ = make([]int, int /* ERROR not an expression */)
+	_ = make([]int, 10, float32 /* ERROR not an expression */)
+	_ = make([]int, "foo" /* ERROR cannot convert */)
+	_ = make([]int, 10, 2.3 /* ERROR truncated */)
+	_ = make([]int, 5, 10.0)
+	_ = make([]int, 0i)
+	_ = make([]int, 1.0)
+	_ = make([]int, 1.0<<s)
+	_ = make([]int, 1.1 /* ERROR int */ <<s)
+	_ = make([]int, - /* ERROR must not be negative */ 1, 10)
+	_ = make([]int, 0, - /* ERROR must not be negative */ 1)
+	_ = make([]int, - /* ERROR must not be negative */ 1, - /* ERROR must not be negative */ 1)
+	_ = make([]int, 1 /* ERROR overflows */ <<100, 1 /* ERROR overflows */ <<100)
+	_ = make([]int, 10 /* ERROR length and capacity swapped */ , 9)
+	_ = make([]int, 1 /* ERROR overflows */ <<100, 12345)
+	_ = make([]int, m /* ERROR must be integer */ )
+        _ = &make /* ERROR cannot take address */ ([]int, 0)
+
+	// maps
+	_ = make /* ERROR arguments */ (map[int]string, 10, 20)
+	_ = make(map[int]float32, int /* ERROR not an expression */)
+	_ = make(map[int]float32, "foo" /* ERROR cannot convert */)
+	_ = make(map[int]float32, 10)
+	_ = make(map[int]float32, n)
+	_ = make(map[int]float32, int64(n))
+	_ = make(map[string]bool, 10.0)
+	_ = make(map[string]bool, 10.0<<s)
+        _ = &make /* ERROR cannot take address */ (map[string]bool)
+
+	// channels
+	_ = make /* ERROR arguments */ (chan int, 10, 20)
+	_ = make(chan int, int /* ERROR not an expression */)
+	_ = make(chan<- int, "foo" /* ERROR cannot convert */)
+	_ = make(chan int, - /* ERROR must not be negative */ 10)
+	_ = make(<-chan float64, 10)
+	_ = make(chan chan int, n)
+	_ = make(chan string, int64(n))
+	_ = make(chan bool, 10.0)
+	_ = make(chan bool, 10.0<<s)
+        _ = &make /* ERROR cannot take address */ (chan bool)
+
+	make /* ERROR not used */ ([]int, 10)
+
+	var t []int
+	_ = make([]int, t[0], t[1])
+	_ = make([]int, t... /* ERROR invalid use of \.\.\. */ )
+}
+
+func make2() {
+	f1 := func() (x []int) { return }
+	_ = make(f0 /* ERROR not a type */ ())
+	_ = make(f1 /* ERROR not a type */ ())
+}
+
+func new1() {
+	_ = new() // ERROR not enough arguments
+	_ = new(1, 2) // ERROR too many arguments
+	_ = new("foo" /* ERROR not a type */)
+	p := new(float64)
+	_ = new(struct{ x, y int })
+	q := new(*float64)
+	_ = *p == **q
+	new /* ERROR not used */ (int)
+        _ = &new /* ERROR cannot take address */ (int)
+
+	_ = new(int... /* ERROR invalid use of \.\.\. */ )
+}
+
+func new2() {
+	f1 := func() (x []int) { return }
+	_ = new(f0 /* ERROR not a type */ ())
+	_ = new(f1 /* ERROR not a type */ ())
+}
+
+func panic1() {
+	panic() // ERROR not enough arguments
+	panic(1, 2) // ERROR too many arguments
+	panic(0)
+	panic("foo")
+	panic(false)
+	panic(1<<10)
+	panic(1 << /* ERROR constant shift overflow */ 1000)
+	_ = panic /* ERROR used as value */ (0)
+
+	var s []byte
+	panic(s)
+	panic(s... /* ERROR invalid use of \.\.\. */ )
+}
+
+func panic2() {
+	f1 := func() (x int) { return }
+	f2 := func() (x, y int) { return }
+	panic(f0 /* ERROR used as value */ ())
+	panic(f1())
+	panic(f2()) // ERROR too many arguments
+}
+
+func print1() {
+	print()
+	print(1)
+	print(1, 2)
+	print("foo")
+	print(2.718281828)
+	print(false)
+	print(1<<10)
+	print(1 << /* ERROR constant shift overflow */ 1000)
+	println(nil /* ERROR untyped nil */ )
+
+	var s []int
+	print(s... /* ERROR invalid use of \.\.\. */ )
+	_ = print /* ERROR used as value */ ()
+}
+
+func print2() {
+	f1 := func() (x int) { return }
+	f2 := func() (x, y int) { return }
+	f3 := func() (x int, y float32, z string) { return }
+	print(f0 /* ERROR used as value */ ())
+	print(f1())
+	print(f2())
+	print(f3())
+}
+
+func println1() {
+	println()
+	println(1)
+	println(1, 2)
+	println("foo")
+	println(2.718281828)
+	println(false)
+	println(1<<10)
+	println(1 << /* ERROR constant shift overflow */ 1000)
+	println(nil /* ERROR untyped nil */ )
+
+	var s []int
+	println(s... /* ERROR invalid use of \.\.\. */ )
+	_ = println /* ERROR used as value */ ()
+}
+
+func println2() {
+	f1 := func() (x int) { return }
+	f2 := func() (x, y int) { return }
+	f3 := func() (x int, y float32, z string) { return }
+	println(f0 /* ERROR used as value */ ())
+	println(f1())
+	println(f2())
+	println(f3())
+}
+
+func real1() {
+	var f32 float32
+	var f64 float64
+	var c64 complex64
+	var c128 complex128
+	_ = real() // ERROR not enough arguments
+	_ = real(1, 2) // ERROR too many arguments
+	_ = real(10)
+	_ = real(2.7182818)
+	_ = real("foo" /* ERROR expected complex */)
+	const _5 = real(1 + 2i)
+	assert(_5 == 1)
+	f32 = _5
+	f64 = _5
+	const _6 = real(0i)
+	assert(_6 == 0)
+	f32 = real(c64)
+	f64 = real(c128)
+	f32 = real /* ERROR cannot use .* in assignment */ (c128)
+	f64 = real /* ERROR cannot use .* in assignment */ (c64)
+	real /* ERROR not used */ (c64)
+
+	// complex type may not be predeclared
+	type C64 complex64
+	type C128 complex128
+	var x64 C64
+	var x128 C128
+	f32 = imag(x64)
+	f64 = imag(x128)
+	_, _ = f32, f64
+
+	var a []complex64
+	_ = real(a... /* ERROR invalid use of \.\.\. */ )
+
+	// if argument is untyped, result is untyped
+	const _ byte = real(1 + 2.3i)
+	const _ complex128 = real(1 + 2.3i)
+
+	// lhs constant shift operands are typed as complex128
+	var s uint
+	_ = real(1 /* ERROR must be integer */ << s)
+}
+
+func real2() {
+	f1 := func() (x complex128) { return }
+	f2 := func() (x, y complex128) { return }
+	_ = real(f0 /* ERROR used as value */ ())
+	_ = real(f1())
+	_ = real(f2()) // ERROR too many arguments
+}
+
+func recover1() {
+	_ = recover()
+	_ = recover(10) // ERROR too many arguments
+	recover()
+
+	var s []int
+	recover(s... /* ERROR invalid use of \.\.\. */ )
+}
+
+func recover2() {
+	f1 := func() (x int) { return }
+	f2 := func() (x, y int) { return }
+	_ = recover(f0 /* ERROR used as value */ ())
+	_ = recover(f1()) // ERROR too many arguments
+	_ = recover(f2()) // ERROR too many arguments
+}
+
+// assuming types.DefaultPtrSize == 8
+type S0 struct{      // offset
+	a bool       //  0
+	b rune       //  4
+	c *int       //  8
+	d bool       // 16
+	e complex128 // 24
+}                    // 40
+
+type S1 struct{   // offset
+	x float32 //  0
+	y string  //  8
+	z *S1     // 24
+	S0        // 32
+}                 // 72
+
+type S2 struct{ // offset
+	*S1     //  0
+}               //  8
+
+type S3 struct { // offset
+	a int64  //  0
+	b int32  //  8
+}                // 12
+
+type S4 struct { // offset
+	S3       //  0
+	int32    // 12
+}                // 16
+
+type S5 struct {   // offset
+	a [3]int32 //  0
+	b int32    // 12
+}                  // 16
+
+func (S2) m() {}
+
+func Alignof1() {
+	var x int
+	_ = unsafe.Alignof() // ERROR not enough arguments
+	_ = unsafe.Alignof(1, 2) // ERROR too many arguments
+	_ = unsafe.Alignof(int /* ERROR not an expression */)
+	_ = unsafe.Alignof(42)
+	_ = unsafe.Alignof(new(struct{}))
+	_ = unsafe.Alignof(1<<10)
+	_ = unsafe.Alignof(1 << /* ERROR constant shift overflow */ 1000)
+	_ = unsafe.Alignof(nil /* ERROR "untyped nil */ )
+	unsafe /* ERROR not used */ .Alignof(x)
+
+	var y S0
+	assert(unsafe.Alignof(y.a) == 1)
+	assert(unsafe.Alignof(y.b) == 4)
+	assert(unsafe.Alignof(y.c) == 8)
+	assert(unsafe.Alignof(y.d) == 1)
+	assert(unsafe.Alignof(y.e) == 8)
+
+	var s []byte
+	_ = unsafe.Alignof(s)
+	_ = unsafe.Alignof(s... /* ERROR invalid use of \.\.\. */ )
+}
+
+func Alignof2() {
+	f1 := func() (x int32) { return }
+	f2 := func() (x, y int32) { return }
+	_ = unsafe.Alignof(f0 /* ERROR used as value */ ())
+	assert(unsafe.Alignof(f1()) == 4)
+	_ = unsafe.Alignof(f2()) // ERROR too many arguments
+}
+
+func Offsetof1() {
+	var x struct{ f int }
+	_ = unsafe.Offsetof() // ERROR not enough arguments
+	_ = unsafe.Offsetof(1, 2) // ERROR too many arguments
+	_ = unsafe.Offsetof(int /* ERROR not a selector expression */ )
+	_ = unsafe.Offsetof(x /* ERROR not a selector expression */ )
+	_ = unsafe.Offsetof(nil /* ERROR not a selector expression */ )
+	_ = unsafe.Offsetof(x.f)
+	_ = unsafe.Offsetof((x.f))
+	_ = unsafe.Offsetof((((((((x))).f)))))
+	unsafe /* ERROR not used */ .Offsetof(x.f)
+
+	var y0 S0
+	assert(unsafe.Offsetof(y0.a) == 0)
+	assert(unsafe.Offsetof(y0.b) == 4)
+	assert(unsafe.Offsetof(y0.c) == 8)
+	assert(unsafe.Offsetof(y0.d) == 16)
+	assert(unsafe.Offsetof(y0.e) == 24)
+
+	var y1 S1
+	assert(unsafe.Offsetof(y1.x) == 0)
+	assert(unsafe.Offsetof(y1.y) == 8)
+	assert(unsafe.Offsetof(y1.z) == 24)
+	assert(unsafe.Offsetof(y1.S0) == 32)
+
+	assert(unsafe.Offsetof(y1.S0.a) == 0) // relative to S0
+	assert(unsafe.Offsetof(y1.a) == 32)   // relative to S1
+	assert(unsafe.Offsetof(y1.b) == 36)   // relative to S1
+	assert(unsafe.Offsetof(y1.c) == 40)   // relative to S1
+	assert(unsafe.Offsetof(y1.d) == 48)   // relative to S1
+	assert(unsafe.Offsetof(y1.e) == 56)   // relative to S1
+
+	var y1p *S1
+	assert(unsafe.Offsetof(y1p.S0) == 32)
+
+	type P *S1
+	var p P = y1p
+	assert(unsafe.Offsetof(p.S0) == 32)
+
+	var y2 S2
+	assert(unsafe.Offsetof(y2.S1) == 0)
+	_ = unsafe.Offsetof(y2 /* ERROR embedded via a pointer */ .x)
+	_ = unsafe.Offsetof(y2 /* ERROR method value */ .m)
+
+	var s []byte
+	_ = unsafe.Offsetof(s... /* ERROR invalid use of \.\.\. */ )
+}
+
+func Offsetof2() {
+	f1 := func() (x int32) { return }
+	f2 := func() (x, y int32) { return }
+	_ = unsafe.Offsetof(f0 /* ERROR not a selector expression */ ())
+	_ = unsafe.Offsetof(f1 /* ERROR not a selector expression */ ())
+	_ = unsafe.Offsetof(f2 /* ERROR not a selector expression */ ())
+}
+
+func Sizeof1() {
+	var x int
+	_ = unsafe.Sizeof() // ERROR not enough arguments
+	_ = unsafe.Sizeof(1, 2) // ERROR too many arguments
+	_ = unsafe.Sizeof(int /* ERROR not an expression */)
+	_ = unsafe.Sizeof(42)
+	_ = unsafe.Sizeof(new(complex128))
+	_ = unsafe.Sizeof(1<<10)
+	_ = unsafe.Sizeof(1 << /* ERROR constant shift overflow */ 1000)
+	_ = unsafe.Sizeof(nil /* ERROR untyped nil */ )
+	unsafe /* ERROR not used */ .Sizeof(x)
+
+	// basic types have size guarantees
+	assert(unsafe.Sizeof(byte(0)) == 1)
+	assert(unsafe.Sizeof(uint8(0)) == 1)
+	assert(unsafe.Sizeof(int8(0)) == 1)
+	assert(unsafe.Sizeof(uint16(0)) == 2)
+	assert(unsafe.Sizeof(int16(0)) == 2)
+	assert(unsafe.Sizeof(uint32(0)) == 4)
+	assert(unsafe.Sizeof(int32(0)) == 4)
+	assert(unsafe.Sizeof(float32(0)) == 4)
+	assert(unsafe.Sizeof(uint64(0)) == 8)
+	assert(unsafe.Sizeof(int64(0)) == 8)
+	assert(unsafe.Sizeof(float64(0)) == 8)
+	assert(unsafe.Sizeof(complex64(0)) == 8)
+	assert(unsafe.Sizeof(complex128(0)) == 16)
+
+	var y0 S0
+	assert(unsafe.Sizeof(y0.a) == 1)
+	assert(unsafe.Sizeof(y0.b) == 4)
+	assert(unsafe.Sizeof(y0.c) == 8)
+	assert(unsafe.Sizeof(y0.d) == 1)
+	assert(unsafe.Sizeof(y0.e) == 16)
+	assert(unsafe.Sizeof(y0) == 40)
+
+	var y1 S1
+	assert(unsafe.Sizeof(y1) == 72)
+
+	var y2 S2
+	assert(unsafe.Sizeof(y2) == 8)
+
+	var y3 S3
+	assert(unsafe.Sizeof(y3) == 12)
+
+	var y4 S4
+	assert(unsafe.Sizeof(y4) == 16)
+
+	var y5 S5
+	assert(unsafe.Sizeof(y5) == 16)
+
+	var a3 [10]S3
+	assert(unsafe.Sizeof(a3) == 156)
+
+	// test case for issue 5670
+	type T struct {
+		a int32
+		_ int32
+		c int32
+	}
+	assert(unsafe.Sizeof(T{}) == 12)
+
+	var s []byte
+	_ = unsafe.Sizeof(s)
+	_ = unsafe.Sizeof(s... /* ERROR invalid use of \.\.\. */ )
+}
+
+func Sizeof2() {
+	f1 := func() (x int64) { return }
+	f2 := func() (x, y int64) { return }
+	_ = unsafe.Sizeof(f0 /* ERROR used as value */ ())
+	assert(unsafe.Sizeof(f1()) == 8)
+	_ = unsafe.Sizeof(f2()) // ERROR too many arguments
+}
+
+func Slice1() {
+	var x int
+	unsafe.Slice()        // ERROR not enough arguments
+	unsafe.Slice(1, 2, 3) // ERROR too many arguments
+	unsafe.Slice(1 /* ERROR is not a pointer */ , 2)
+	unsafe.Slice(nil /* ERROR nil is not a pointer */ , 0)
+	unsafe.Slice(&x, "foo" /* ERROR cannot convert .* to type int */ )
+	unsafe.Slice(&x, 1.2 /* ERROR truncated to int */ )
+	unsafe.Slice(&x, - /* ERROR must not be negative */ 1)
+	unsafe /* ERROR not used */ .Slice(&x, 0)
+	var _ []byte = unsafe /* ERROR value of type \[\]int */ .Slice(&x, 0)
+
+	var _ []int = unsafe.Slice(&x, 0)
+	_ = unsafe.Slice(&x, 1.0)
+	_ = unsafe.Slice((*int)(nil), 0)
+}
+
+func SliceData1() {
+	var s []int
+	unsafe.SliceData(0 /* ERROR not a slice */)
+	unsafe /* ERROR not used */ .SliceData(s)
+
+	type S []int
+	_ = unsafe.SliceData(s)
+	_ = unsafe.SliceData(S{})
+}
+
+func String1() {
+	var b byte
+	unsafe.String()        // ERROR not enough arguments
+	unsafe.String(1, 2, 3) // ERROR too many arguments
+	unsafe.String(1 /* ERROR cannot use 1 */ , 2)
+	unsafe.String(&b, "foo" /* ERROR cannot convert .* to type int */ )
+	unsafe.String(&b, 1.2 /* ERROR truncated to int */ )
+	unsafe.String(&b, - /* ERROR must not be negative */ 1)
+	unsafe /* ERROR not used */ .String(&b, 0)
+	var _ []byte = unsafe /* ERROR value of type string */ .String(&b, 0)
+
+	var _ string = unsafe.String(&b, 0)
+	_ = unsafe.String(&b, 1.0)
+	_ = unsafe.String(nil, 0) // here we allow nil as ptr argument (in contrast to unsafe.Slice)
+}
+
+func StringData1() {
+	var s string
+	type S string
+	unsafe.StringData(0 /* ERROR cannot use 0 */)
+	unsafe.StringData(S /* ERROR cannot use S */ ("foo"))
+	unsafe /* ERROR not used */ .StringData(s)
+
+	_ = unsafe.StringData(s)
+	_ = unsafe.StringData("foo")
+}
+
+// self-testing only
+func assert1() {
+	var x int
+	assert() /* ERROR not enough arguments */
+	assert(1, 2) /* ERROR too many arguments */
+	assert("foo" /* ERROR boolean constant */ )
+	assert(x /* ERROR boolean constant */)
+	assert(true)
+	assert /* ERROR failed */ (false)
+	_ = assert(true)
+
+	var s []byte
+	assert(s... /* ERROR invalid use of \.\.\. */ )
+}
+
+func assert2() {
+	f1 := func() (x bool) { return }
+	f2 := func() (x bool) { return }
+	assert(f0 /* ERROR used as value */ ())
+	assert(f1 /* ERROR boolean constant */ ())
+	assert(f2 /* ERROR boolean constant */ ())
+}
+
+// self-testing only
+func trace1() {
+	// Uncomment the code below to test trace - will produce console output
+	// _ = trace /* ERROR no value */ ()
+	// _ = trace(1)
+	// _ = trace(true, 1.2, '\'', "foo", 42i, "foo" <= "bar")
+
+	var s []byte
+	trace(s... /* ERROR invalid use of \.\.\. */ )
+}
+
+func trace2() {
+	f1 := func() (x int) { return }
+	f2 := func() (x int, y string) { return }
+	f3 := func() (x int, y string, z []int) { return }
+	_ = f1
+	_ = f2
+	_ = f3
+	// Uncomment the code below to test trace - will produce console output
+	// trace(f0())
+	// trace(f1())
+	// trace(f2())
+	// trace(f3())
+	// trace(f0(), 1)
+	// trace(f1(), 1, 2)
+	// trace(f2(), 1, 2, 3)
+	// trace(f3(), 1, 2, 3, 4)
+}
diff --git a/src/internal/types/testdata/check/builtins1.go b/src/internal/types/testdata/check/builtins1.go
new file mode 100644
index 0000000..3348861
--- /dev/null
+++ b/src/internal/types/testdata/check/builtins1.go
@@ -0,0 +1,288 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file tests built-in calls on generic types.
+
+package builtins
+
+import "unsafe"
+
+// clear
+
+func _[T any](x T) {
+	clear(x /* ERROR cannot clear x */)
+}
+
+func _[T ~map[int]string | ~[]byte | ~*[10]int](x T) {
+	clear(x)
+}
+
+func _[T ~map[int]string | ~[]byte | ~*[10]int | string](x T) {
+	clear(x /* ERROR cannot clear x */)
+}
+
+// close
+
+type C0 interface{ int }
+type C1 interface{ chan int }
+type C2 interface{ chan int | <-chan int }
+type C3 interface{ chan int | chan float32 }
+type C4 interface{ chan int | chan<- int }
+type C5[T any] interface{ ~chan T | chan<- T }
+
+func _[T any](ch T) {
+	close(ch /* ERROR cannot close non-channel */)
+}
+
+func _[T C0](ch T) {
+	close(ch /* ERROR cannot close non-channel */)
+}
+
+func _[T C1](ch T) {
+	close(ch)
+}
+
+func _[T C2](ch T) {
+	close(ch /* ERROR cannot close receive-only channel */)
+}
+
+func _[T C3](ch T) {
+	close(ch)
+}
+
+func _[T C4](ch T) {
+	close(ch)
+}
+
+func _[T C5[X], X any](ch T) {
+	close(ch)
+}
+
+// copy
+
+func _[T any](x, y T) {
+	copy(x /* ERROR copy expects slice arguments */ , y)
+}
+
+func _[T ~[]byte](x, y T) {
+	copy(x, y)
+	copy(x, "foo")
+	copy("foo" /* ERROR expects slice arguments */ , y)
+
+	var x2 []byte
+	copy(x2, y) // element types are identical
+	copy(y, x2) // element types are identical
+
+	type myByte byte
+	var x3 []myByte
+	copy(x3 /* ERROR different element types */ , y)
+	copy(y /* ERROR different element types */ , x3)
+}
+
+func _[T ~[]E, E any](x T, y []E) {
+	copy(x, y)
+	copy(x /* ERROR different element types */ , "foo")
+}
+
+func _[T ~string](x []byte, y T) {
+	copy(x, y)
+	copy(y /* ERROR expects slice arguments */ , x)
+}
+
+func _[T ~[]byte|~string](x T, y []byte) {
+	copy(x /* ERROR expects slice arguments */ , y)
+	copy(y, x)
+}
+
+type L0 []int
+type L1 []int
+
+func _[T L0 | L1](x, y T) {
+	copy(x, y)
+}
+
+// delete
+
+type M0 interface{ int }
+type M1 interface{ map[string]int }
+type M2 interface { map[string]int | map[string]float64 }
+type M3 interface{ map[string]int | map[rune]int }
+type M4[K comparable, V any] interface{ map[K]V | map[rune]V }
+
+func _[T any](m T) {
+	delete(m /* ERROR not a map */, "foo")
+}
+
+func _[T M0](m T) {
+	delete(m /* ERROR not a map */, "foo")
+}
+
+func _[T M1](m T) {
+	delete(m, "foo")
+}
+
+func _[T M2](m T) {
+	delete(m, "foo")
+	delete(m, 0 /* ERROR cannot use .* as string */)
+}
+
+func _[T M3](m T) {
+	delete(m /* ERROR must have identical key types */, "foo")
+}
+
+func _[T M4[rune, V], V any](m T) {
+	delete(m, 'k')
+}
+
+func _[T M4[K, V], K comparable, V any](m T) {
+	delete(m /* ERROR must have identical key types */, "foo")
+}
+
+// make
+
+type myChan chan int
+
+func _[
+	S1 ~[]int,
+	S2 ~[]int | ~chan int,
+
+	M1 ~map[string]int,
+	M2 ~map[string]int | ~chan int,
+
+	C1 ~chan int,
+	C2 ~chan int | ~chan string,
+	C3 chan int | myChan, // single underlying type
+]() {
+	type S0 []int
+	_ = make([]int, 10)
+	_ = make(S0, 10)
+	_ = make(S1, 10)
+	_ = make() /* ERROR not enough arguments */
+	_ = make /* ERROR expects 2 or 3 arguments */ (S1)
+	_ = make(S1, 10, 20)
+	_ = make /* ERROR expects 2 or 3 arguments */ (S1, 10, 20, 30)
+	_ = make(S2 /* ERROR cannot make S2: no core type */ , 10)
+
+	type M0 map[string]int
+	_ = make(map[string]int)
+	_ = make(M0)
+	_ = make(M1)
+	_ = make(M1, 10)
+	_ = make/* ERROR expects 1 or 2 arguments */(M1, 10, 20)
+	_ = make(M2 /* ERROR cannot make M2: no core type */ )
+
+	type C0 chan int
+	_ = make(chan int)
+	_ = make(C0)
+	_ = make(C1)
+	_ = make(C1, 10)
+	_ = make/* ERROR expects 1 or 2 arguments */(C1, 10, 20)
+	_ = make(C2 /* ERROR cannot make C2: no core type */ )
+	_ = make(C3)
+}
+
+// unsafe.Alignof
+
+func _[T comparable]() {
+	var (
+		b int64
+		a [10]T
+		s struct{ f T }
+		p *T
+		l []T
+		f func(T)
+		i interface{ m() T }
+		c chan T
+		m map[T]T
+		t T
+	)
+
+	const bb = unsafe.Alignof(b)
+	assert(bb == 8)
+	const _ = unsafe /* ERROR not constant */ .Alignof(a)
+	const _ = unsafe /* ERROR not constant */ .Alignof(s)
+	const pp = unsafe.Alignof(p)
+	assert(pp == 8)
+	const ll = unsafe.Alignof(l)
+	assert(ll == 8)
+	const ff = unsafe.Alignof(f)
+	assert(ff == 8)
+	const ii = unsafe.Alignof(i)
+	assert(ii == 8)
+	const cc = unsafe.Alignof(c)
+	assert(cc == 8)
+	const mm = unsafe.Alignof(m)
+	assert(mm == 8)
+	const _ = unsafe /* ERROR not constant */ .Alignof(t)
+}
+
+// unsafe.Offsetof
+
+func _[T comparable]() {
+	var (
+		b struct{ _, f int64 }
+		a struct{ _, f [10]T }
+		s struct{ _, f struct{ f T } }
+		p struct{ _, f *T }
+		l struct{ _, f []T }
+		f struct{ _, f func(T) }
+		i struct{ _, f interface{ m() T } }
+		c struct{ _, f chan T }
+		m struct{ _, f map[T]T }
+		t struct{ _, f T }
+	)
+
+	const bb = unsafe.Offsetof(b.f)
+	assert(bb == 8)
+	const _ = unsafe /* ERROR not constant */ .Alignof(a)
+	const _ = unsafe /* ERROR not constant */ .Alignof(s)
+	const pp = unsafe.Offsetof(p.f)
+	assert(pp == 8)
+	const ll = unsafe.Offsetof(l.f)
+	assert(ll == 24)
+	const ff = unsafe.Offsetof(f.f)
+	assert(ff == 8)
+	const ii = unsafe.Offsetof(i.f)
+	assert(ii == 16)
+	const cc = unsafe.Offsetof(c.f)
+	assert(cc == 8)
+	const mm = unsafe.Offsetof(m.f)
+	assert(mm == 8)
+	const _ = unsafe /* ERROR not constant */ .Alignof(t)
+}
+
+// unsafe.Sizeof
+
+func _[T comparable]() {
+	var (
+		b int64
+		a [10]T
+		s struct{ f T }
+		p *T
+		l []T
+		f func(T)
+		i interface{ m() T }
+		c chan T
+		m map[T]T
+		t T
+	)
+
+	const bb = unsafe.Sizeof(b)
+	assert(bb == 8)
+	const _ = unsafe /* ERROR not constant */ .Alignof(a)
+	const _ = unsafe /* ERROR not constant */ .Alignof(s)
+	const pp = unsafe.Sizeof(p)
+	assert(pp == 8)
+	const ll = unsafe.Sizeof(l)
+	assert(ll == 24)
+	const ff = unsafe.Sizeof(f)
+	assert(ff == 8)
+	const ii = unsafe.Sizeof(i)
+	assert(ii == 16)
+	const cc = unsafe.Sizeof(c)
+	assert(cc == 8)
+	const mm = unsafe.Sizeof(m)
+	assert(mm == 8)
+	const _ = unsafe /* ERROR not constant */ .Alignof(t)
+}
diff --git a/src/go/types/testdata/check/chans.go b/src/internal/types/testdata/check/chans.go
similarity index 100%
rename from src/go/types/testdata/check/chans.go
rename to src/internal/types/testdata/check/chans.go
diff --git a/src/go/types/testdata/check/compliterals.go b/src/internal/types/testdata/check/compliterals.go
similarity index 100%
rename from src/go/types/testdata/check/compliterals.go
rename to src/internal/types/testdata/check/compliterals.go
diff --git a/src/internal/types/testdata/check/const0.go b/src/internal/types/testdata/check/const0.go
new file mode 100644
index 0000000..402e6cf
--- /dev/null
+++ b/src/internal/types/testdata/check/const0.go
@@ -0,0 +1,382 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// constant declarations
+
+package const0
+
+import "unsafe"
+
+// constants declarations must be initialized by constants
+var x = 0
+const c0 = x /* ERROR "not constant" */
+
+// typed constants must have constant types
+const _ interface /* ERROR invalid constant type */ {} = 0
+
+func _ () {
+	const _ interface /* ERROR invalid constant type */ {} = 0
+	for i := 0; i < 10; i++ {} // don't crash with non-nil iota here
+}
+
+// untyped constants
+const (
+	// boolean values
+	ub0 = false
+	ub1 = true
+	ub2 = 2 < 1
+	ub3 = ui1 == uf1
+	ub4 = true == 0 /* ERROR "mismatched types untyped bool and untyped int" */
+
+	// integer values
+	ui0 = 0
+	ui1 = 1
+	ui2 = 42
+	ui3 = 3141592653589793238462643383279502884197169399375105820974944592307816406286
+	ui4 = -10
+
+	ui5 = ui0 + ui1
+	ui6 = ui1 - ui1
+	ui7 = ui2 * ui1
+	ui8 = ui3 / ui3
+	ui9 = ui3 % ui3
+
+	ui10 = 1 / 0 /* ERROR "division by zero" */
+	ui11 = ui1 / 0 /* ERROR "division by zero" */
+	ui12 = ui3 / ui0 /* ERROR "division by zero" */
+	ui13 = 1 % 0 /* ERROR "division by zero" */
+	ui14 = ui1 % 0 /* ERROR "division by zero" */
+	ui15 = ui3 % ui0 /* ERROR "division by zero" */
+
+	ui16 = ui2 & ui3
+	ui17 = ui2 | ui3
+	ui18 = ui2 ^ ui3
+	ui19 = 1 /* ERROR "invalid operation" */ % 1.0
+
+	// floating point values
+	uf0 = 0.
+	uf1 = 1.
+	uf2 = 4.2e1
+	uf3 = 3.141592653589793238462643383279502884197169399375105820974944592307816406286
+	uf4 = 1e-1
+
+	uf5 = uf0 + uf1
+	uf6 = uf1 - uf1
+	uf7 = uf2 * uf1
+	uf8 = uf3 / uf3
+	uf9 = uf3 /* ERROR "not defined" */ % uf3
+
+	uf10 = 1 / 0 /* ERROR "division by zero" */
+	uf11 = uf1 / 0 /* ERROR "division by zero" */
+	uf12 = uf3 / uf0 /* ERROR "division by zero" */
+
+	uf16 = uf2 /* ERROR "not defined" */ & uf3
+	uf17 = uf2 /* ERROR "not defined" */ | uf3
+	uf18 = uf2 /* ERROR "not defined" */ ^ uf3
+
+	// complex values
+	uc0 = 0.i
+	uc1 = 1.i
+	uc2 = 4.2e1i
+	uc3 = 3.141592653589793238462643383279502884197169399375105820974944592307816406286i
+	uc4 = 1e-1i
+
+	uc5 = uc0 + uc1
+	uc6 = uc1 - uc1
+	uc7 = uc2 * uc1
+	uc8 = uc3 / uc3
+	uc9 = uc3 /* ERROR "not defined" */ % uc3
+
+	uc10 = 1 / 0 /* ERROR "division by zero" */
+	uc11 = uc1 / 0 /* ERROR "division by zero" */
+	uc12 = uc3 / uc0 /* ERROR "division by zero" */
+
+	uc16 = uc2 /* ERROR "not defined" */ & uc3
+	uc17 = uc2 /* ERROR "not defined" */ | uc3
+	uc18 = uc2 /* ERROR "not defined" */ ^ uc3
+)
+
+type (
+	mybool bool
+	myint int
+	myfloat float64
+	mycomplex complex128
+)
+
+// typed constants
+const (
+	// boolean values
+	tb0 bool = false
+	tb1 bool = true
+	tb2 mybool = 2 < 1
+	tb3 mybool = ti1 == tf1 /* ERROR "mismatched types" */
+
+	// integer values
+	ti0 int8 = ui0
+	ti1 int32 = ui1
+	ti2 int64 = ui2
+	ti3 myint = ui3 /* ERROR "overflows" */
+	ti4 myint = ui4
+
+	ti5 = ti0 /* ERROR "mismatched types" */ + ti1
+	ti6 = ti1 - ti1
+	ti7 = ti2 /* ERROR "mismatched types" */ * ti1
+	ti8 = ti3 / ti3
+	ti9 = ti3 % ti3
+
+	ti10 = 1 / 0 /* ERROR "division by zero" */
+	ti11 = ti1 / 0 /* ERROR "division by zero" */
+	ti12 = ti3 /* ERROR "mismatched types" */ / ti0
+	ti13 = 1 % 0 /* ERROR "division by zero" */
+	ti14 = ti1 % 0 /* ERROR "division by zero" */
+	ti15 = ti3 /* ERROR "mismatched types" */ % ti0
+
+	ti16 = ti2 /* ERROR "mismatched types" */ & ti3
+	ti17 = ti2 /* ERROR "mismatched types" */ | ti4
+	ti18 = ti2 ^ ti5 // no mismatched types error because the type of ti5 is unknown
+
+	// floating point values
+	tf0 float32 = 0.
+	tf1 float32 = 1.
+	tf2 float64 = 4.2e1
+	tf3 myfloat = 3.141592653589793238462643383279502884197169399375105820974944592307816406286
+	tf4 myfloat = 1e-1
+
+	tf5 = tf0 + tf1
+	tf6 = tf1 - tf1
+	tf7 = tf2 /* ERROR "mismatched types" */ * tf1
+	tf8 = tf3 / tf3
+	tf9 = tf3 /* ERROR "not defined" */ % tf3
+
+	tf10 = 1 / 0 /* ERROR "division by zero" */
+	tf11 = tf1 / 0 /* ERROR "division by zero" */
+	tf12 = tf3 /* ERROR "mismatched types" */ / tf0
+
+	tf16 = tf2 /* ERROR "mismatched types" */ & tf3
+	tf17 = tf2 /* ERROR "mismatched types" */ | tf3
+	tf18 = tf2 /* ERROR "mismatched types" */ ^ tf3
+
+	// complex values
+	tc0 = 0.i
+	tc1 = 1.i
+	tc2 = 4.2e1i
+	tc3 = 3.141592653589793238462643383279502884197169399375105820974944592307816406286i
+	tc4 = 1e-1i
+
+	tc5 = tc0 + tc1
+	tc6 = tc1 - tc1
+	tc7 = tc2 * tc1
+	tc8 = tc3 / tc3
+	tc9 = tc3 /* ERROR "not defined" */ % tc3
+
+	tc10 = 1 / 0 /* ERROR "division by zero" */
+	tc11 = tc1 / 0 /* ERROR "division by zero" */
+	tc12 = tc3 / tc0 /* ERROR "division by zero" */
+
+	tc16 = tc2 /* ERROR "not defined" */ & tc3
+	tc17 = tc2 /* ERROR "not defined" */ | tc3
+	tc18 = tc2 /* ERROR "not defined" */ ^ tc3
+)
+
+// initialization cycles
+const (
+	a /* ERROR "initialization cycle" */ = a
+	b /* ERROR "initialization cycle" */ , c /* ERROR "initialization cycle" */, d, e = e, d, c, b // TODO(gri) should only have one cycle error
+	f float64 = d
+)
+
+// multiple initialization
+const (
+	a1, a2, a3 = 7, 3.1415926, "foo"
+	b1, b2, b3 = b3, b1, 42
+	c1, c2, c3  /* ERROR "missing init expr for c3" */ = 1, 2
+	d1, d2, d3 = 1, 2, 3, 4 /* ERROR "extra init expr 4" */
+	_p0 = assert(a1 == 7)
+	_p1 = assert(a2 == 3.1415926)
+	_p2 = assert(a3 == "foo")
+	_p3 = assert(b1 == 42)
+	_p4 = assert(b2 == 42)
+	_p5 = assert(b3 == 42)
+)
+
+func _() {
+	const (
+		a1, a2, a3 = 7, 3.1415926, "foo"
+		b1, b2, b3 = b3, b1, 42
+		c1, c2, c3  /* ERROR "missing init expr for c3" */ = 1, 2
+		d1, d2, d3 = 1, 2, 3, 4 /* ERROR "extra init expr 4" */
+		_p0 = assert(a1 == 7)
+		_p1 = assert(a2 == 3.1415926)
+		_p2 = assert(a3 == "foo")
+		_p3 = assert(b1 == 42)
+		_p4 = assert(b2 == 42)
+		_p5 = assert(b3 == 42)
+	)
+}
+
+// iota
+const (
+	iota0 = iota
+	iota1 = iota
+	iota2 = iota*2
+	_a0 = assert(iota0 == 0)
+	_a1 = assert(iota1 == 1)
+	_a2 = assert(iota2 == 4)
+	iota6 = iota*3
+
+	iota7
+	iota8
+	_a3 = assert(iota7 == 21)
+	_a4 = assert(iota8 == 24)
+)
+
+const (
+	_b0 = iota
+	_b1 = assert(iota + iota2 == 5)
+	_b2 = len([iota]int{}) // iota may appear in a type!
+	_b3 = assert(_b2 == 2)
+	_b4 = len(A{})
+)
+
+type A [iota /* ERROR "cannot use iota" */ ]int
+
+// constant expressions with operands across different
+// constant declarations must use the right iota values
+const (
+	_c0 = iota
+	_c1
+	_c2
+	_x = _c2 + _d1 + _e0 // 3
+)
+
+const (
+	_d0 = iota
+	_d1
+)
+
+const (
+	_e0 = iota
+)
+
+var _ = assert(_x == 3)
+
+// special cases
+const (
+	_n0 = nil /* ERROR "not constant" */
+	_n1 = [ /* ERROR "not constant" */ ]int{}
+)
+
+// iotas must not be usable in expressions outside constant declarations
+type _ [iota /* ERROR "iota outside constant decl" */ ]byte
+var _ = iota /* ERROR "iota outside constant decl" */
+func _() {
+	_ = iota /* ERROR "iota outside constant decl" */
+	const _ = iota
+	_ = iota /* ERROR "iota outside constant decl" */
+}
+
+func _() {
+	iota := 123
+	const x = iota /* ERROR "is not constant" */
+	var y = iota
+	_ = y
+}
+
+// iotas are usable inside closures in constant declarations (#22345)
+const (
+	_ = iota
+	_ = len([iota]byte{})
+	_ = unsafe.Sizeof(iota)
+	_ = unsafe.Sizeof(func() { _ = iota })
+	_ = unsafe.Sizeof(func() { var _ = iota })
+	_ = unsafe.Sizeof(func() { const _ = iota })
+	_ = unsafe.Sizeof(func() { type _ [iota]byte })
+	_ = unsafe.Sizeof(func() { func() int { return iota }() })
+)
+
+// verify inner and outer const declarations have distinct iotas
+const (
+	zero = iota
+	one  = iota
+	_    = unsafe.Sizeof(func() {
+		var x [iota]int // [2]int
+		const (
+			Zero = iota
+			One
+			Two
+			_ = unsafe.Sizeof([iota-1]int{} == x) // assert types are equal
+			_ = unsafe.Sizeof([Two]int{} == x)    // assert types are equal
+		)
+		var z [iota]int                           // [2]int
+		_ = unsafe.Sizeof([2]int{} == z)          // assert types are equal
+	})
+	three = iota // the sequence continues
+)
+var _ [three]int = [3]int{} // assert 'three' has correct value
+
+var (
+	_ = iota /* ERROR "iota outside constant decl" */
+	_ = unsafe.Sizeof(iota  /* ERROR "iota outside constant decl" */ )
+	_ = unsafe.Sizeof(func() { _ = iota /* ERROR "iota outside constant decl" */ })
+	_ = unsafe.Sizeof(func() { var _ = iota /* ERROR "iota outside constant decl" */ })
+	_ = unsafe.Sizeof(func() { type _ [iota /* ERROR "iota outside constant decl" */ ]byte })
+	_ = unsafe.Sizeof(func() { func() int { return iota /* ERROR "iota outside constant decl" */ }() })
+)
+
+// constant arithmetic precision and rounding must lead to expected (integer) results
+var _ = []int64{
+	0.0005 * 1e9,
+	0.001 * 1e9,
+	0.005 * 1e9,
+	0.01 * 1e9,
+	0.05 * 1e9,
+	0.1 * 1e9,
+	0.5 * 1e9,
+	1 * 1e9,
+	5 * 1e9,
+}
+
+const _ = unsafe.Sizeof(func() {
+	const _ = 0
+	_ = iota
+
+	const (
+	   zero = iota
+	   one
+	)
+	assert(one == 1)
+	assert(iota == 0)
+})
+
+// issue #52438
+const i1 = iota
+const i2 = iota
+const i3 = iota
+
+func _() {
+	assert(i1 == 0)
+	assert(i2 == 0)
+	assert(i3 == 0)
+
+	const i4 = iota
+	const i5 = iota
+	const i6 = iota
+
+	assert(i4 == 0)
+	assert(i5 == 0)
+	assert(i6 == 0)
+}
+
+// untyped constants must not get arbitrarily large
+const prec = 512 // internal maximum precision for integers
+const maxInt = (1<<(prec/2) - 1) * (1<<(prec/2) + 1) // == 1<<prec - 1
+
+const _ = maxInt + /* ERROR constant addition overflow */ 1
+const _ = -maxInt - /* ERROR constant subtraction overflow */ 1
+const _ = maxInt ^ /* ERROR constant bitwise XOR overflow */ -1
+const _ = maxInt * /* ERROR constant multiplication overflow */ 2
+const _ = maxInt << /* ERROR constant shift overflow */ 2
+const _ = 1 << /* ERROR constant shift overflow */ prec
+
+const _ = ^ /* ERROR constant bitwise complement overflow */ maxInt
diff --git a/src/go/types/testdata/check/const1.go b/src/internal/types/testdata/check/const1.go
similarity index 100%
rename from src/go/types/testdata/check/const1.go
rename to src/internal/types/testdata/check/const1.go
diff --git a/src/internal/types/testdata/check/constdecl.go b/src/internal/types/testdata/check/constdecl.go
new file mode 100644
index 0000000..faa9b9d
--- /dev/null
+++ b/src/internal/types/testdata/check/constdecl.go
@@ -0,0 +1,160 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package constdecl
+
+import "math"
+import "unsafe"
+
+var v int
+
+// Const decls must be initialized by constants.
+const _ = v /* ERROR "not constant" */
+const _ = math /* ERROR "not constant" */ .Sin(0)
+const _ = int /* ERROR "not an expression" */
+
+func _() {
+	const _ = v /* ERROR "not constant" */
+	const _ = math /* ERROR "not constant" */ .Sin(0)
+	const _ = int /* ERROR "not an expression" */
+}
+
+// Identifier and expression arity must match.
+const _ /* ERROR "missing init expr for _" */
+const _ = 1, 2 /* ERROR "extra init expr 2" */
+
+const _ /* ERROR "missing init expr for _" */ int
+const _ int = 1, 2 /* ERROR "extra init expr 2" */
+
+const (
+	_ /* ERROR "missing init expr for _" */
+	_ = 1, 2 /* ERROR "extra init expr 2" */
+
+	_ /* ERROR "missing init expr for _" */ int
+	_ int = 1, 2 /* ERROR "extra init expr 2" */
+)
+
+const (
+	_ = 1
+	_
+	_, _ /* ERROR "missing init expr for _" */
+	_
+)
+
+const (
+	_, _ = 1, 2
+	_, _
+	_ /* ERROR "extra init expr at" */
+	_, _
+	_, _, _ /* ERROR "missing init expr for _" */
+	_, _
+)
+
+func _() {
+	const _ /* ERROR "missing init expr for _" */
+	const _ = 1, 2 /* ERROR "extra init expr 2" */
+
+	const _ /* ERROR "missing init expr for _" */ int
+	const _ int = 1, 2 /* ERROR "extra init expr 2" */
+
+	const (
+		_ /* ERROR "missing init expr for _" */
+		_ = 1, 2 /* ERROR "extra init expr 2" */
+
+		_ /* ERROR "missing init expr for _" */ int
+		_ int = 1, 2 /* ERROR "extra init expr 2" */
+	)
+
+	const (
+		_ = 1
+		_
+		_, _ /* ERROR "missing init expr for _" */
+		_
+	)
+
+	const (
+		_, _ = 1, 2
+		_, _
+		_ /* ERROR "extra init expr at" */
+		_, _
+		_, _, _ /* ERROR "missing init expr for _" */
+		_, _
+	)
+}
+
+// Test case for constant with invalid initialization.
+// Caused panic because the constant value was not set up (gri - 7/8/2014).
+func _() {
+	const (
+	    x string = missing /* ERROR "undefined" */
+	    y = x + ""
+	)
+}
+
+// Test case for constants depending on function literals (see also #22992).
+const A /* ERROR initialization cycle */ = unsafe.Sizeof(func() { _ = A })
+
+func _() {
+	// The function literal below must not see a.
+	const a = unsafe.Sizeof(func() { _ = a /* ERROR "undefined" */ })
+	const b = unsafe.Sizeof(func() { _ = a })
+
+	// The function literal below must not see x, y, or z.
+	const x, y, z = 0, 1, unsafe.Sizeof(func() { _ = x /* ERROR "undefined" */ + y /* ERROR "undefined" */ + z /* ERROR "undefined" */ })
+}
+
+// Test cases for errors in inherited constant initialization expressions.
+// Errors related to inherited initialization expressions must appear at
+// the constant identifier being declared, not at the original expression
+// (issues #42991, #42992).
+const (
+	_ byte = 255 + iota
+	/* some gap */
+	_ // ERROR overflows
+	/* some gap */
+	/* some gap */ _ /* ERROR overflows */; _ /* ERROR overflows */
+	/* some gap */
+	_ = 255 + iota
+	_ = byte /* ERROR overflows */ (255) + iota
+	_ /* ERROR overflows */
+)
+
+// Test cases from issue.
+const (
+	ok = byte(iota + 253)
+	bad
+	barn
+	bard // ERROR cannot convert
+)
+
+const (
+	c = len([1 - iota]int{})
+	d
+	e // ERROR invalid array length
+	f // ERROR invalid array length
+)
+
+// Test that identifiers in implicit (omitted) RHS
+// expressions of constant declarations are resolved
+// in the correct context; see issues #49157, #53585.
+const X = 2
+
+func _() {
+	const (
+		A    = iota // 0
+		iota = iota // 1
+		B           // 1 (iota is declared locally on prev. line)
+		C           // 1
+	)
+	assert(A == 0 && B == 1 && C == 1)
+
+	const (
+		X = X + X
+		Y
+		Z = iota
+	)
+	assert(X == 4 && Y == 8 && Z == 1)
+}
+
+// TODO(gri) move extra tests from testdata/const0.src into here
diff --git a/src/go/types/testdata/check/conversions0.go b/src/internal/types/testdata/check/conversions0.go
similarity index 100%
rename from src/go/types/testdata/check/conversions0.go
rename to src/internal/types/testdata/check/conversions0.go
diff --git a/src/go/types/testdata/check/conversions1.go b/src/internal/types/testdata/check/conversions1.go
similarity index 100%
rename from src/go/types/testdata/check/conversions1.go
rename to src/internal/types/testdata/check/conversions1.go
diff --git a/src/internal/types/testdata/check/cycles0.go b/src/internal/types/testdata/check/cycles0.go
new file mode 100644
index 0000000..7c00c7d
--- /dev/null
+++ b/src/internal/types/testdata/check/cycles0.go
@@ -0,0 +1,175 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cycles
+
+import "unsafe"
+
+type (
+	T0 int
+	T1 /* ERROR invalid recursive type: T1 refers to itself */ T1
+	T2 *T2
+
+	T3 /* ERROR invalid recursive type */ T4
+	T4 T5
+	T5 T3
+
+	T6 T7
+	T7 *T8
+	T8 T6
+
+	// arrays
+	A0 /* ERROR invalid recursive type */ [10]A0
+	A1 [10]*A1
+
+	A2 /* ERROR invalid recursive type */ [10]A3
+	A3 [10]A4
+	A4 A2
+
+	A5 [10]A6
+	A6 *A5
+
+	// slices
+	L0 []L0
+
+	// structs
+	S0 /* ERROR invalid recursive type: S0 refers to itself */ struct{ _ S0 }
+	S1 /* ERROR invalid recursive type: S1 refers to itself */ struct{ S1 }
+	S2 struct{ _ *S2 }
+	S3 struct{ *S3 }
+
+	S4 /* ERROR invalid recursive type */ struct{ S5 }
+	S5 struct{ S6 }
+	S6 S4
+
+	// pointers
+	P0 *P0
+	PP *struct{ PP.f /* ERROR PP.f is not a type */ }
+
+	// functions
+	F0 func(F0)
+	F1 func() F1
+	F2 func(F2) F2
+
+	// interfaces
+	I0 /* ERROR invalid recursive type: I0 refers to itself */ interface{ I0 }
+
+	I1 /* ERROR invalid recursive type */ interface{ I2 }
+	I2 interface{ I3 }
+	I3 interface{ I1 }
+
+	I4 interface{ f(I4) }
+
+	// testcase for issue 5090
+	I5 interface{ f(I6) }
+	I6 interface{ I5 }
+
+	// maps
+	M0 map[M0 /* ERROR invalid map key */ ]M0
+
+	// channels
+	C0 chan C0
+)
+
+// test case for issue #34771
+type (
+	AA /* ERROR invalid recursive type */ B
+	B C
+	C [10]D
+	D E
+	E AA
+)
+
+func _() {
+	type (
+		t1 /* ERROR invalid recursive type: t1 refers to itself */ t1
+		t2 *t2
+
+		t3 t4 /* ERROR undefined */
+		t4 t5 /* ERROR undefined */
+		t5 t3
+
+		// arrays
+		a0 /* ERROR invalid recursive type: a0 refers to itself */ [10]a0
+		a1 [10]*a1
+
+		// slices
+		l0 []l0
+
+		// structs
+		s0 /* ERROR invalid recursive type: s0 refers to itself */ struct{ _ s0 }
+		s1 /* ERROR invalid recursive type: s1 refers to itself */ struct{ s1 }
+		s2 struct{ _ *s2 }
+		s3 struct{ *s3 }
+
+		// pointers
+		p0 *p0
+
+		// functions
+		f0 func(f0)
+		f1 func() f1
+		f2 func(f2) f2
+
+		// interfaces
+		i0 /* ERROR invalid recursive type: i0 refers to itself */ interface{ i0 }
+
+		// maps
+		m0 map[m0 /* ERROR invalid map key */ ]m0
+
+		// channels
+		c0 chan c0
+	)
+}
+
+// test cases for issue 6667
+
+type A [10]map[A /* ERROR invalid map key */ ]bool
+
+type S struct {
+	m map[S /* ERROR invalid map key */ ]bool
+}
+
+// test cases for issue 7236
+// (cycle detection must not be dependent on starting point of resolution)
+
+type (
+	P1 *T9
+	T9 /* ERROR invalid recursive type: T9 refers to itself */ T9
+
+	T10 /* ERROR invalid recursive type: T10 refers to itself */ T10
+	P2 *T10
+)
+
+func (T11) m() {}
+
+type T11 /* ERROR invalid recursive type: T11 refers to itself */ struct{ T11 }
+
+type T12 /* ERROR invalid recursive type: T12 refers to itself */ struct{ T12 }
+
+func (*T12) m() {}
+
+type (
+	P3 *T13
+	T13 /* ERROR invalid recursive type */ T13
+)
+
+// test cases for issue 18643
+// (type cycle detection when non-type expressions are involved)
+type (
+	T14 [len(T14 /* ERROR invalid recursive type */ {})]int
+	T15 [][len(T15 /* ERROR invalid recursive type */ {})]int
+	T16 map[[len(T16 /* ERROR invalid recursive type */ {1:2})]int]int
+	T17 map[int][len(T17 /* ERROR invalid recursive type */ {1:2})]int
+)
+
+// Test case for types depending on function literals (see also #22992).
+type T20 chan [unsafe.Sizeof(func(ch T20){ _ = <-ch })]byte
+type T22 = chan [unsafe.Sizeof(func(ch T20){ _ = <-ch })]byte
+
+func _() {
+	type T0 func(T0)
+	type T1 /* ERROR invalid recursive type */ = func(T1)
+	type T2 chan [unsafe.Sizeof(func(ch T2){ _ = <-ch })]byte
+	type T3 /* ERROR invalid recursive type */ = chan [unsafe.Sizeof(func(ch T3){ _ = <-ch })]byte
+}
diff --git a/src/go/types/testdata/check/cycles1.go b/src/internal/types/testdata/check/cycles1.go
similarity index 100%
rename from src/go/types/testdata/check/cycles1.go
rename to src/internal/types/testdata/check/cycles1.go
diff --git a/src/internal/types/testdata/check/cycles2.go b/src/internal/types/testdata/check/cycles2.go
new file mode 100644
index 0000000..8480b29
--- /dev/null
+++ b/src/internal/types/testdata/check/cycles2.go
@@ -0,0 +1,98 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+import "unsafe"
+
+// Test case for issue 5090
+
+type t interface {
+	f(u)
+}
+
+type u interface {
+	t
+}
+
+func _() {
+	var t t
+	var u u
+
+	t.f(t)
+	t.f(u)
+
+	u.f(t)
+	u.f(u)
+}
+
+
+// Test case for issues #6589, #33656.
+
+type A interface {
+	a() interface {
+		AB
+	}
+}
+
+type B interface {
+	b() interface {
+		AB
+	}
+}
+
+type AB interface {
+	a() interface {
+		A
+		B
+	}
+	b() interface {
+		A
+		B
+	}
+}
+
+var x AB
+var y interface {
+	A
+	B
+}
+
+var _ = x == y
+
+
+// Test case for issue 6638.
+
+type T interface {
+	m() [T(nil).m /* ERROR undefined */ ()[0]]int
+}
+
+// Variations of this test case.
+
+type T1 /* ERROR invalid recursive type */ interface {
+	m() [x1.m()[0]]int
+}
+
+var x1 T1
+
+type T2 /* ERROR invalid recursive type */ interface {
+	m() [len(x2.m())]int
+}
+
+var x2 T2
+
+type T3 /* ERROR invalid recursive type */ interface {
+	m() [unsafe.Sizeof(x3.m)]int
+}
+
+var x3 T3
+
+type T4 /* ERROR invalid recursive type */ interface {
+	m() [unsafe.Sizeof(cast4(x4.m))]int // cast is invalid but we have a cycle, so all bets are off
+}
+
+var x4 T4
+var _ = cast4(x4.m)
+
+type cast4 func()
diff --git a/src/internal/types/testdata/check/cycles3.go b/src/internal/types/testdata/check/cycles3.go
new file mode 100644
index 0000000..4330551
--- /dev/null
+++ b/src/internal/types/testdata/check/cycles3.go
@@ -0,0 +1,60 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+import "unsafe"
+
+var (
+	_ A = A(nil).a().b().c().d().e().f()
+	_ A = A(nil).b().c().d().e().f()
+	_ A = A(nil).c().d().e().f()
+	_ A = A(nil).d().e().f()
+	_ A = A(nil).e().f()
+	_ A = A(nil).f()
+	_ A = A(nil)
+)
+
+type (
+	A interface {
+		a() B
+		B
+	}
+
+	B interface {
+		b() C
+		C
+	}
+
+	C interface {
+		c() D
+		D
+	}
+
+	D interface {
+		d() E
+		E
+	}
+
+	E interface {
+		e() F
+		F
+	}
+
+	F interface {
+		f() A
+	}
+)
+
+type (
+	U /* ERROR invalid recursive type */ interface {
+		V
+	}
+
+	V interface {
+		v() [unsafe.Sizeof(u)]int
+	}
+)
+
+var u U
diff --git a/src/go/types/testdata/check/cycles4.go b/src/internal/types/testdata/check/cycles4.go
similarity index 100%
rename from src/go/types/testdata/check/cycles4.go
rename to src/internal/types/testdata/check/cycles4.go
diff --git a/src/internal/types/testdata/check/cycles5.go b/src/internal/types/testdata/check/cycles5.go
new file mode 100644
index 0000000..5e0d191
--- /dev/null
+++ b/src/internal/types/testdata/check/cycles5.go
@@ -0,0 +1,200 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+import "unsafe"
+
+// test case from issue #18395
+
+type (
+	A interface { B }
+	B interface { C }
+	C interface { D; F() A }
+	D interface { G() B }
+)
+
+var _ = A(nil).G // G must be found
+
+
+// test case from issue #21804
+
+type sourceBridge interface {
+	listVersions() ([]Version, error)
+}
+
+type Constraint interface {
+	copyTo(*ConstraintMsg)
+}
+
+type ConstraintMsg struct{}
+
+func (m *ConstraintMsg) asUnpairedVersion() UnpairedVersion {
+	return nil
+}
+
+type Version interface {
+	Constraint
+}
+
+type UnpairedVersion interface {
+	Version
+}
+
+var _ Constraint = UnpairedVersion(nil)
+
+
+// derived test case from issue #21804
+
+type (
+	_ interface{ m(B1) }
+	A1 interface{ a(D1) }
+	B1 interface{ A1 }
+	C1 interface{ B1 }
+	D1 interface{ C1 }
+)
+
+var _ A1 = C1(nil)
+
+
+// derived test case from issue #22701
+
+func F(x I4) interface{} {
+	return x.Method()
+}
+
+type Unused interface {
+	RefersToI1(a I1)
+}
+
+type I1 interface {
+	I2
+	I3
+}
+
+type I2 interface {
+	RefersToI4() I4
+}
+
+type I3 interface {
+	Method() interface{}
+}
+
+type I4 interface {
+	I1
+}
+
+
+// check embedding of error interface
+
+type Error interface{ error }
+
+var err Error
+var _ = err.Error()
+
+
+// more esoteric cases
+
+type (
+	T1 interface { T2 }
+	T2 /* ERROR invalid recursive type */ T2
+)
+
+type (
+	T3 interface { T4 }
+	T4 /* ERROR invalid recursive type */ T5
+	T5 = T6
+	T6 = T7
+	T7 = T4
+)
+
+
+// arbitrary code may appear inside an interface
+
+const n = unsafe.Sizeof(func(){})
+
+type I interface {
+	m([unsafe.Sizeof(func() { I.m(nil, [n]byte{}) })]byte)
+}
+
+
+// test cases for varias alias cycles
+
+type T10 /* ERROR invalid recursive type */ = *T10                 // issue #25141
+type T11 /* ERROR invalid recursive type */ = interface{ f(T11) }  // issue #23139
+
+// issue #18640
+type (
+	aa = bb
+	bb struct {
+		*aa
+	}
+)
+
+type (
+	a struct{ *b }
+	b = c
+	c struct{ *b /* ERROR invalid use of type alias */ }
+)
+
+// issue #24939
+type (
+	_ interface {
+		M(P)
+	}
+
+	M interface {
+		F() P // ERROR invalid use of type alias
+	}
+
+	P = interface {
+		I() M
+	}
+)
+
+// issue #8699
+type T12 /* ERROR invalid recursive type */ [len(a12)]int
+var a12 = makeArray()
+func makeArray() (res T12) { return }
+
+// issue #20770
+var r /* ERROR invalid cycle in declaration of r */ = newReader()
+func newReader() r
+
+// variations of the theme of #8699 and #20770
+var arr /* ERROR cycle */ = f()
+func f() [len(arr)]int
+
+// issue #25790
+func ff(ff /* ERROR not a type */ )
+func gg((gg /* ERROR not a type */ ))
+
+type T13 /* ERROR invalid recursive type T13 */ [len(b13)]int
+var b13 T13
+
+func g1() [unsafe.Sizeof(g1)]int
+func g2() [unsafe.Sizeof(x2)]int
+var x2 = g2
+
+// verify that we get the correct sizes for the functions above
+// (note: assert is statically evaluated in go/types test mode)
+func init() {
+	assert(unsafe.Sizeof(g1) == 8)
+	assert(unsafe.Sizeof(x2) == 8)
+}
+
+func h() [h /* ERROR no value */ ()[0]]int { panic(0) }
+
+var c14 /* ERROR cycle */ T14
+type T14 [uintptr(unsafe.Sizeof(&c14))]byte
+
+// issue #34333
+type T15 /* ERROR invalid recursive type T15 */ struct {
+	f func() T16
+	b T16
+}
+
+type T16 struct {
+	T15
+}
\ No newline at end of file
diff --git a/src/internal/types/testdata/check/decls0.go b/src/internal/types/testdata/check/decls0.go
new file mode 100644
index 0000000..868b318
--- /dev/null
+++ b/src/internal/types/testdata/check/decls0.go
@@ -0,0 +1,210 @@
+// -lang=go1.17
+
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// type declarations
+
+package p // don't permit non-interface elements in interfaces
+
+import "unsafe"
+
+const pi = 3.1415
+
+type (
+	N undefined /* ERROR "undefined" */
+	B bool
+	I int32
+	A [10]P
+	T struct {
+		x, y P
+	}
+	P *T
+	R (*R)
+	F func(A) I
+	Y interface {
+		f(A) I
+	}
+	S [](((P)))
+	M map[I]F
+	C chan<- I
+
+	// blank types must be typechecked
+	_ pi /* ERROR "not a type" */
+	_ struct{}
+	_ struct{ pi /* ERROR "not a type" */ }
+)
+
+
+// declarations of init
+const _, init /* ERROR "cannot declare init" */ , _ = 0, 1, 2
+type init /* ERROR "cannot declare init" */ struct{}
+var _, init /* ERROR "cannot declare init" */ int
+
+func init() {}
+func init /* ERROR "missing function body" */ ()
+
+func _() { const init = 0 }
+func _() { type init int }
+func _() { var init int; _ = init }
+
+// invalid array types
+type (
+	iA0 [... /* ERROR "invalid use of \[...\] array" */ ]byte
+	// The error message below could be better. At the moment
+	// we believe an integer that is too large is not an integer.
+	// But at least we get an error.
+	iA1 [1 /* ERROR "must be integer" */ <<100]int
+	iA2 [- /* ERROR "invalid array length" */ 1]complex128
+	iA3 ["foo" /* ERROR "must be integer" */ ]string
+	iA4 [float64 /* ERROR "must be integer" */ (0)]int
+)
+
+
+type (
+	p1 pi.foo /* ERROR "pi.foo is not a type" */
+	p2 unsafe.Pointer
+)
+
+
+type (
+	Pi pi /* ERROR "not a type" */
+
+	a /* ERROR "invalid recursive type" */ a
+	a /* ERROR "redeclared" */ int
+
+	b /* ERROR "invalid recursive type" */ c
+	c d
+	d e
+	e b
+
+	t *t
+
+	U V
+	V *W
+	W U
+
+	P1 *S2
+	P2 P1
+
+	S0 struct {
+	}
+	S1 struct {
+		a, b, c int
+		u, v, a /* ERROR "redeclared" */ float32
+	}
+	S2 struct {
+		S0 // embedded field
+		S0 /* ERROR "redeclared" */ int
+	}
+	S3 struct {
+		x S2
+	}
+	S4/* ERROR "invalid recursive type" */ struct {
+		S4
+	}
+	S5 /* ERROR "invalid recursive type" */ struct {
+		S6
+	}
+	S6 struct {
+		field S7
+	}
+	S7 struct {
+		S5
+	}
+
+	L1 []L1
+	L2 []int
+
+	A1 [10.0]int
+	A2 /* ERROR "invalid recursive type" */ [10]A2
+	A3 /* ERROR "invalid recursive type" */ [10]struct {
+		x A4
+	}
+	A4 [10]A3
+
+	F1 func()
+	F2 func(x, y, z float32)
+	F3 func(x, y, x /* ERROR "redeclared" */ float32)
+	F4 func() (x, y, x /* ERROR "redeclared" */ float32)
+	F5 func(x int) (x /* ERROR "redeclared" */ float32)
+	F6 func(x ...int)
+
+	I1 interface{}
+	I2 interface {
+		m1()
+	}
+	I3 interface {
+		m1()
+		m1 /* ERROR "duplicate method" */ ()
+	}
+	I4 interface {
+		m1(x, y, x /* ERROR "redeclared" */ float32)
+		m2() (x, y, x /* ERROR "redeclared" */ float32)
+		m3(x int) (x /* ERROR "redeclared" */ float32)
+	}
+	I5 interface {
+		m1(I5)
+	}
+	I6 interface {
+		S0 /* ERROR "non-interface type S0" */
+	}
+	I7 interface {
+		I1
+		I1
+	}
+	I8 /* ERROR "invalid recursive type" */ interface {
+		I8
+	}
+	I9 /* ERROR "invalid recursive type" */ interface {
+		I10
+	}
+	I10 interface {
+		I11
+	}
+	I11 interface {
+		I9
+	}
+
+	C1 chan int
+	C2 <-chan int
+	C3 chan<- C3
+	C4 chan C5
+	C5 chan C6
+	C6 chan C4
+
+	M1 map[Last]string
+	M2 map[string]M2
+
+	Last int
+)
+
+// cycles in function/method declarations
+// (test cases for issues #5217, #25790 and variants)
+func f1(x f1 /* ERROR "not a type" */ ) {}
+func f2(x *f2 /* ERROR "not a type" */ ) {}
+func f3() (x f3 /* ERROR "not a type" */ ) { return }
+func f4() (x *f4 /* ERROR "not a type" */ ) { return }
+// TODO(#43215) this should be detected as a cycle error
+func f5([unsafe.Sizeof(f5)]int) {}
+
+func (S0) m1 (x S0.m1 /* ERROR S0.m1 is not a type */ ) {}
+func (S0) m2 (x *S0.m2 /* ERROR S0.m2 is not a type */ ) {}
+func (S0) m3 () (x S0.m3 /* ERROR S0.m3 is not a type */ ) { return }
+func (S0) m4 () (x *S0.m4 /* ERROR S0.m4 is not a type */ ) { return }
+
+// interfaces may not have any blank methods
+type BlankI interface {
+	_ /* ERROR "methods must have a unique non-blank name" */ ()
+	_ /* ERROR "methods must have a unique non-blank name" */ (float32) int
+	m()
+}
+
+// non-interface types may have multiple blank methods
+type BlankT struct{}
+
+func (BlankT) _() {}
+func (BlankT) _(int) {}
+func (BlankT) _() int { return 0 }
+func (BlankT) _(int) int { return 0}
diff --git a/src/internal/types/testdata/check/decls1.go b/src/internal/types/testdata/check/decls1.go
new file mode 100644
index 0000000..b232fc8
--- /dev/null
+++ b/src/internal/types/testdata/check/decls1.go
@@ -0,0 +1,146 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// variable declarations
+
+package decls1
+
+import (
+	"math"
+)
+
+// Global variables without initialization
+var (
+	a, b bool
+	c byte
+	d uint8
+	r rune
+	i int
+	j, k, l int
+	x, y float32
+	xx, yy float64
+	u, v complex64
+	uu, vv complex128
+	s, t string
+	array []byte
+	iface interface{}
+
+	blank _ /* ERROR "cannot use _" */
+)
+
+// Global variables with initialization
+var (
+	s1 = i + j
+	s2 = i /* ERROR "mismatched types" */ + x
+	s3 = c + d
+	s4 = s + t
+	s5 = s /* ERROR "invalid operation" */ / t
+	s6 = array[t1]
+	s7 = array[x /* ERROR "integer" */]
+	s8 = &a
+	s10 = &42 /* ERROR "cannot take address" */
+	s11 = &v
+	s12 = -(u + *t11) / *&v
+	s13 = a /* ERROR "shifted operand" */ << d
+	s14 = i << j
+	s18 = math.Pi * 10.0
+	s19 = s1 /* ERROR "cannot call" */ ()
+ 	s20 = f0 /* ERROR "no value" */ ()
+	s21 = f6(1, s1, i)
+	s22 = f6(1, s1, uu /* ERROR "cannot use .* in argument" */ )
+
+	t1 int = i + j
+	t2 int = i /* ERROR "mismatched types" */ + x
+	t3 int = c /* ERROR "cannot use .* variable declaration" */ + d
+	t4 string = s + t
+	t5 string = s /* ERROR "invalid operation" */ / t
+	t6 byte = array[t1]
+	t7 byte = array[x /* ERROR "must be integer" */]
+	t8 *int = & /* ERROR "cannot use .* variable declaration" */ a
+	t10 *int = &42 /* ERROR "cannot take address" */
+	t11 *complex64 = &v
+	t12 complex64 = -(u + *t11) / *&v
+	t13 int = a /* ERROR "shifted operand" */ << d
+	t14 int = i << j
+	t15 math /* ERROR "not in selector" */
+	t16 math.xxx /* ERROR "undefined" */
+	t17 math /* ERROR "not a type" */ .Pi
+	t18 float64 = math.Pi * 10.0
+	t19 int = t1 /* ERROR "cannot call" */ ()
+	t20 int = f0 /* ERROR "no value" */ ()
+	t21 int = a /* ERROR "cannot use .* variable declaration" */
+)
+
+// Various more complex expressions
+var (
+	u1 = x /* ERROR "not an interface" */ .(int)
+	u2 = iface.([]int)
+	u3 = iface.(a /* ERROR "not a type" */ )
+	u4, ok = iface.(int)
+	u5, ok2, ok3 = iface /* ERROR "assignment mismatch" */ .(int)
+)
+
+// Constant expression initializations
+var (
+	v1 = 1 /* ERROR "mismatched types untyped int and untyped string" */ + "foo"
+	v2 = c + 255
+	v3 = c + 256 /* ERROR "overflows" */
+	v4 = r + 2147483647
+	v5 = r + 2147483648 /* ERROR "overflows" */
+	v6 = 42
+	v7 = v6 + 9223372036854775807
+	v8 = v6 + 9223372036854775808 /* ERROR "overflows" */
+	v9 = i + 1 << 10
+	v10 byte = 1024 /* ERROR "overflows" */
+	v11 = xx/yy*yy - xx
+	v12 = true && false
+	v13 = nil /* ERROR "use of untyped nil" */
+	v14 string = 257 // ERROR cannot use 257 .* as string value in variable declaration$
+	v15 int8 = 257 // ERROR cannot use 257 .* as int8 value in variable declaration .*overflows
+)
+
+// Multiple assignment expressions
+var (
+	m1a, m1b = 1, 2
+	m2a, m2b, m2c /* ERROR "missing init expr for m2c" */ = 1, 2
+	m3a, m3b = 1, 2, 3 /* ERROR "extra init expr 3" */
+)
+
+func _() {
+	var (
+		m1a, m1b = 1, 2
+		m2a, m2b, m2c /* ERROR "missing init expr for m2c" */ = 1, 2
+		m3a, m3b = 1, 2, 3 /* ERROR "extra init expr 3" */
+	)
+
+	_, _ = m1a, m1b
+	_, _, _ = m2a, m2b, m2c
+	_, _ = m3a, m3b
+}
+
+// Declaration of parameters and results
+func f0() {}
+func f1(a /* ERROR "not a type" */) {}
+func f2(a, b, c d /* ERROR "not a type" */) {}
+
+func f3() int { return 0 }
+func f4() a /* ERROR "not a type" */ { return 0 }
+func f5() (a, b, c d /* ERROR "not a type" */) { return }
+
+func f6(a, b, c int) complex128 { return 0 }
+
+// Declaration of receivers
+type T struct{}
+
+func (T) m0() {}
+func (*T) m1() {}
+func (x T) m2() {}
+func (x *T) m3() {}
+
+// Initialization functions
+func init() {}
+func init /* ERROR "no arguments and no return values" */ (int) {}
+func init /* ERROR "no arguments and no return values" */ () int { return 0 }
+func init /* ERROR "no arguments and no return values" */ (int) int { return 0 }
+func (T) init(int) int { return 0 }
diff --git a/src/internal/types/testdata/check/decls2/decls2a.go b/src/internal/types/testdata/check/decls2/decls2a.go
new file mode 100644
index 0000000..731405b
--- /dev/null
+++ b/src/internal/types/testdata/check/decls2/decls2a.go
@@ -0,0 +1,111 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// method declarations
+
+package decls2
+
+import "time"
+import "unsafe"
+
+// T1 declared before its methods.
+type T1 struct{
+	f int
+}
+
+func (T1) m() {}
+func (T1) m /* ERROR "already declared" */ () {}
+func (x *T1) f /* ERROR "field and method" */ () {}
+
+// Conflict between embedded field and method name,
+// with the embedded field being a basic type.
+type T1b struct {
+	int
+}
+
+func (T1b) int /* ERROR "field and method" */ () {}
+
+type T1c struct {
+	time.Time
+}
+
+func (T1c) Time /* ERROR "field and method" */ () int { return 0 }
+
+// Disabled for now: LookupFieldOrMethod will find Pointer even though
+// it's double-declared (it would cost extra in the common case to verify
+// this). But the MethodSet computation will not find it due to the name
+// collision caused by the double-declaration, leading to an internal
+// inconsistency while we are verifying one computation against the other.
+// var _ = T1c{}.Pointer
+
+// T2's method declared before the type.
+func (*T2) f /* ERROR "field and method" */ () {}
+
+type T2 struct {
+	f int
+}
+
+// Methods declared without a declared type.
+func (undefined /* ERROR "undefined" */) m() {}
+func (x *undefined /* ERROR "undefined" */) m() {}
+
+func (pi /* ERROR "not a type" */) m1() {}
+func (x pi /* ERROR "not a type" */) m2() {}
+func (x *pi /* ERROR "not a type" */ ) m3() {}
+
+// Blank types.
+type _ struct { m int }
+type _ struct { m int }
+
+func (_ /* ERROR "cannot use _" */) m() {}
+func m(_ /* ERROR "cannot use _" */) {}
+
+// Methods with receiver base type declared in another file.
+func (T3) m1() {}
+func (*T3) m2() {}
+func (x T3) m3() {}
+func (x *T3) f /* ERROR "field and method" */ () {}
+
+// Methods of non-struct type.
+type T4 func()
+
+func (self T4) m() func() { return self }
+
+// Methods associated with an interface.
+type T5 interface {
+	m() int
+}
+
+func (T5 /* ERROR "invalid receiver" */ ) m1() {}
+func (T5 /* ERROR "invalid receiver" */ ) m2() {}
+
+// Methods associated with a named pointer type.
+type ptr *int
+func (ptr /* ERROR "invalid receiver" */ ) _() {}
+func (* /* ERROR "invalid receiver" */ ptr) _() {}
+
+// Methods with zero or multiple receivers.
+func ( /* ERROR "method has no receiver" */ ) _() {}
+func (T3, * /* ERROR "method has multiple receivers" */ T3) _() {}
+func (T3, T3, T3 /* ERROR "method has multiple receivers" */ ) _() {}
+func (a, b /* ERROR "method has multiple receivers" */ T3) _() {}
+func (a, b, c /* ERROR "method has multiple receivers" */ T3) _() {}
+
+// Methods associated with non-local or unnamed types.
+func (int /* ERROR "cannot define new methods on non-local type int" */ ) m() {}
+func ([ /* ERROR "invalid receiver" */ ]int) m() {}
+func (time /* ERROR "cannot define new methods on non-local type time\.Time" */ .Time) m() {}
+func (* /* ERROR "cannot define new methods on non-local type time\.Time" */ time.Time) m() {}
+func (x /* ERROR "invalid receiver" */ interface{}) m() {}
+
+// Unsafe.Pointer is treated like a pointer when used as receiver type.
+type UP unsafe.Pointer
+func (UP /* ERROR "invalid" */ ) m1() {}
+func (* /* ERROR "invalid" */ UP) m2() {}
+
+// Double declarations across package files
+const c_double = 0
+type t_double int
+var v_double int
+func f_double() {}
diff --git a/src/internal/types/testdata/check/decls2/decls2b.go b/src/internal/types/testdata/check/decls2/decls2b.go
new file mode 100644
index 0000000..d4c5861
--- /dev/null
+++ b/src/internal/types/testdata/check/decls2/decls2b.go
@@ -0,0 +1,75 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// method declarations
+
+package decls2
+
+import "io"
+
+const pi = 3.1415
+
+func (T1) m /* ERROR "already declared" */ () {}
+func (T2) m(io.Writer) {}
+
+type T3 struct {
+	f *T3
+}
+
+type T6 struct {
+	x int
+}
+
+func (t *T6) m1() int {
+	return t.x
+}
+
+func f() {
+	var t *T6
+	t.m1()
+}
+
+// Double declarations across package files
+const c_double /* ERROR "redeclared" */ = 0
+type t_double  /* ERROR "redeclared" */ int
+var v_double /* ERROR "redeclared" */ int
+func f_double /* ERROR "redeclared" */ () {}
+
+// Blank methods need to be type-checked.
+// Verify by checking that errors are reported.
+func (T /* ERROR "undefined" */ ) _() {}
+func (T1) _(undefined /* ERROR "undefined" */ ) {}
+func (T1) _() int { return "foo" /* ERROR "cannot use .* in return statement" */ }
+
+// Methods with undefined receiver type can still be checked.
+// Verify by checking that errors are reported.
+func (Foo /* ERROR "undefined" */ ) m() {}
+func (Foo /* ERROR "undefined" */ ) m(undefined /* ERROR "undefined" */ ) {}
+func (Foo /* ERROR "undefined" */ ) m() int { return "foo" /* ERROR "cannot use .* in return statement" */ }
+
+func (Foo /* ERROR "undefined" */ ) _() {}
+func (Foo /* ERROR "undefined" */ ) _(undefined /* ERROR "undefined" */ ) {}
+func (Foo /* ERROR "undefined" */ ) _() int { return "foo" /* ERROR "cannot use .* in return statement" */ }
+
+// Receiver declarations are regular parameter lists;
+// receiver types may use parentheses, and the list
+// may have a trailing comma.
+type T7 struct {}
+
+func (T7) m1() {}
+func ((T7)) m2() {}
+func ((*T7)) m3() {}
+func (x *(T7),) m4() {}
+func (x (*(T7)),) m5() {}
+func (x ((*((T7)))),) m6() {}
+
+// Check that methods with parenthesized receiver are actually present (issue #23130).
+var (
+	_ = T7.m1
+	_ = T7.m2
+	_ = (*T7).m3
+	_ = (*T7).m4
+	_ = (*T7).m5
+	_ = (*T7).m6
+)
diff --git a/src/internal/types/testdata/check/decls3.go b/src/internal/types/testdata/check/decls3.go
new file mode 100644
index 0000000..01d4ffe
--- /dev/null
+++ b/src/internal/types/testdata/check/decls3.go
@@ -0,0 +1,309 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// embedded types
+
+package decls3
+
+import "unsafe"
+import "fmt"
+
+// fields with the same name at the same level cancel each other out
+
+func _() {
+	type (
+		T1 struct { X int }
+		T2 struct { X int }
+		T3 struct { T1; T2 } // X is embedded twice at the same level via T1->X, T2->X
+	)
+
+	var t T3
+	_ = t.X /* ERROR "ambiguous selector t.X" */
+}
+
+func _() {
+	type (
+		T1 struct { X int }
+		T2 struct { T1 }
+		T3 struct { T1 }
+		T4 struct { T2; T3 } // X is embedded twice at the same level via T2->T1->X, T3->T1->X
+	)
+
+	var t T4
+	_ = t.X /* ERROR "ambiguous selector t.X" */
+}
+
+func issue4355() {
+	type (
+	    T1 struct {X int}
+	    T2 struct {T1}
+	    T3 struct {T2}
+	    T4 struct {T2}
+	    T5 struct {T3; T4} // X is embedded twice at the same level via T3->T2->T1->X, T4->T2->T1->X
+	)
+
+	var t T5
+	_ = t.X /* ERROR "ambiguous selector t.X" */
+}
+
+func _() {
+	type State int
+	type A struct{ State }
+	type B struct{ fmt.State }
+	type T struct{ A; B }
+
+	var t T
+	_ = t.State /* ERROR "ambiguous selector t.State" */
+}
+
+// Embedded fields can be predeclared types.
+
+func _() {
+	type T0 struct{
+		int
+		float32
+		f int
+	}
+	var x T0
+	_ = x.int
+	_ = x.float32
+	_ = x.f
+
+	type T1 struct{
+		T0
+	}
+	var y T1
+	_ = y.int
+	_ = y.float32
+	_ = y.f
+}
+
+// Restrictions on embedded field types.
+
+func _() {
+	type I1 interface{}
+	type I2 interface{}
+	type P1 *int
+	type P2 *int
+	type UP unsafe.Pointer
+
+	type T1 struct {
+		I1
+		* /* ERROR "cannot be a pointer to an interface" */ I2
+		* /* ERROR "cannot be a pointer to an interface" */ error
+		P1 /* ERROR "cannot be a pointer" */
+		* /* ERROR "cannot be a pointer" */ P2
+	}
+
+	// unsafe.Pointers are treated like regular pointers when embedded
+	type T2 struct {
+		unsafe /* ERROR "cannot be unsafe.Pointer" */ .Pointer
+		*/* ERROR "cannot be unsafe.Pointer" */ /* ERROR "Pointer redeclared" */ unsafe.Pointer
+		UP /* ERROR "cannot be unsafe.Pointer" */
+		* /* ERROR "cannot be unsafe.Pointer" */  /* ERROR "UP redeclared" */ UP
+	}
+}
+
+// Named types that are pointers.
+
+type S struct{ x int }
+func (*S) m() {}
+type P *S
+
+func _() {
+	var s *S
+	_ = s.x
+	_ = s.m
+
+	var p P
+	_ = p.x
+	_ = p.m /* ERROR "no field or method" */
+	_ = P.m /* ERROR "no field or method" */
+}
+
+// Borrowed from the FieldByName test cases in reflect/all_test.go.
+
+type D1 struct {
+	d int
+}
+type D2 struct {
+	d int
+}
+
+type S0 struct {
+	A, B, C int
+	D1
+	D2
+}
+
+type S1 struct {
+	B int
+	S0
+}
+
+type S2 struct {
+	A int
+	*S1
+}
+
+type S1x struct {
+	S1
+}
+
+type S1y struct {
+	S1
+}
+
+type S3 struct {
+	S1x
+	S2
+	D, E int
+	*S1y
+}
+
+type S4 struct {
+	*S4
+	A int
+}
+
+// The X in S6 and S7 annihilate, but they also block the X in S8.S9.
+type S5 struct {
+	S6
+	S7
+	S8
+}
+
+type S6 struct {
+	X int
+}
+
+type S7 S6
+
+type S8 struct {
+	S9
+}
+
+type S9 struct {
+	X int
+	Y int
+}
+
+// The X in S11.S6 and S12.S6 annihilate, but they also block the X in S13.S8.S9.
+type S10 struct {
+	S11
+	S12
+	S13
+}
+
+type S11 struct {
+	S6
+}
+
+type S12 struct {
+	S6
+}
+
+type S13 struct {
+	S8
+}
+
+func _() {
+	_ = struct{}{}.Foo /* ERROR "no field or method" */
+	_ = S0{}.A
+	_ = S0{}.D /* ERROR "no field or method" */
+	_ = S1{}.A
+	_ = S1{}.B
+	_ = S1{}.S0
+	_ = S1{}.C
+	_ = S2{}.A
+	_ = S2{}.S1
+	_ = S2{}.B
+	_ = S2{}.C
+	_ = S2{}.D /* ERROR "no field or method" */
+	_ = S3{}.S1 /* ERROR "ambiguous selector S3{}.S1" */
+	_ = S3{}.A
+	_ = S3{}.B /* ERROR "ambiguous selector" S3{}.B */
+	_ = S3{}.D
+	_ = S3{}.E
+	_ = S4{}.A
+	_ = S4{}.B /* ERROR "no field or method" */
+	_ = S5{}.X /* ERROR "ambiguous selector S5{}.X" */
+	_ = S5{}.Y
+	_ = S10{}.X /* ERROR "ambiguous selector S10{}.X" */
+	_ = S10{}.Y
+}
+
+// Borrowed from the FieldByName benchmark in reflect/all_test.go.
+
+type R0 struct {
+	*R1
+	*R2
+	*R3
+	*R4
+}
+
+type R1 struct {
+	*R5
+	*R6
+	*R7
+	*R8
+}
+
+type R2 R1
+type R3 R1
+type R4 R1
+
+type R5 struct {
+	*R9
+	*R10
+	*R11
+	*R12
+}
+
+type R6 R5
+type R7 R5
+type R8 R5
+
+type R9 struct {
+	*R13
+	*R14
+	*R15
+	*R16
+}
+
+type R10 R9
+type R11 R9
+type R12 R9
+
+type R13 struct {
+	*R17
+	*R18
+	*R19
+	*R20
+}
+
+type R14 R13
+type R15 R13
+type R16 R13
+
+type R17 struct {
+	*R21
+	*R22
+	*R23
+	*R24
+}
+
+type R18 R17
+type R19 R17
+type R20 R17
+
+type R21 struct {
+	X int
+}
+
+type R22 R21
+type R23 R21
+type R24 R21
+
+var _ = R0{}.X /* ERROR "ambiguous selector R0{}.X" */
\ No newline at end of file
diff --git a/src/internal/types/testdata/check/decls4.go b/src/internal/types/testdata/check/decls4.go
new file mode 100644
index 0000000..c1294ee
--- /dev/null
+++ b/src/internal/types/testdata/check/decls4.go
@@ -0,0 +1,199 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// type aliases
+
+package decls4
+
+type (
+	T0 [10]int
+	T1 []byte
+	T2 struct {
+		x int
+	}
+	T3 interface{
+		m() T2
+	}
+	T4 func(int, T0) chan T2
+)
+
+type (
+	Ai = int
+	A0 = T0
+	A1 = T1
+	A2 = T2
+	A3 = T3
+	A4 = T4
+
+	A10 = [10]int
+	A11 = []byte
+	A12 = struct {
+		x int
+	}
+	A13 = interface{
+		m() A2
+	}
+	A14 = func(int, A0) chan A2
+)
+
+// check assignment compatibility due to equality of types
+var (
+	xi_ int
+	ai Ai = xi_
+
+	x0 T0
+	a0 A0 = x0
+
+	x1 T1
+	a1 A1 = x1
+
+	x2 T2
+	a2 A2 = x2
+
+	x3 T3
+	a3 A3 = x3
+
+	x4 T4
+	a4 A4 = x4
+)
+
+// alias receiver types
+func (Ai /* ERROR "cannot define new methods on non-local type int" */) m1() {}
+func (T0) m1() {}
+func (A0) m1 /* ERROR already declared */ () {}
+func (A0) m2 () {}
+func (A3 /* ERROR invalid receiver */ ) m1 () {}
+func (A10 /* ERROR invalid receiver */ ) m1() {}
+
+// x0 has methods m1, m2 declared via receiver type names T0 and A0
+var _ interface{ m1(); m2() } = x0
+
+// alias receiver types (test case for issue #23042)
+type T struct{}
+
+var (
+	_ = T.m
+	_ = T{}.m
+	_ interface{m()} = T{}
+)
+
+var (
+	_ = T.n
+	_ = T{}.n
+	_ interface{m(); n()} = T{}
+)
+
+type U = T
+func (U) m() {}
+
+// alias receiver types (long type declaration chains)
+type (
+	V0 = V1
+	V1 = (V2)
+	V2 = ((V3))
+	V3 = T
+)
+
+func (V0) m /* ERROR already declared */ () {}
+func (V1) n() {}
+
+// alias receiver types (invalid due to cycles)
+type (
+	W0 /* ERROR invalid recursive type */ = W1
+	W1 = (W2)
+	W2 = ((W0))
+)
+
+func (W0) m() {} // no error expected (due to above cycle error)
+func (W1) n() {}
+
+// alias receiver types (invalid due to builtin underlying type)
+type (
+	B0 = B1
+	B1 = B2
+	B2 = int
+)
+
+func (B0 /* ERROR cannot define new methods on non-local type int */ ) m() {}
+func (B1 /* ERROR cannot define new methods on non-local type int */ ) n() {}
+
+// cycles
+type (
+	C2 /* ERROR invalid recursive type */ = C2
+	C3 /* ERROR invalid recursive type */ = C4
+	C4 = C3
+	C5 struct {
+		f *C6
+	}
+	C6 = C5
+	C7 /* ERROR invalid recursive type */  struct {
+		f C8
+	}
+	C8 = C7
+)
+
+// embedded fields
+var (
+	s0 struct { T0 }
+	s1 struct { A0 } = s0 /* ERROR cannot use */ // embedded field names are different
+)
+
+// embedding and lookup of fields and methods
+func _(s struct{A0}) { s.A0 = x0 }
+
+type eX struct{xf int}
+
+func (eX) xm()
+
+type eY = struct{eX} // field/method set of eY includes xf, xm
+
+type eZ = *struct{eX} // field/method set of eZ includes xf, xm
+
+type eA struct {
+	eX // eX contributes xf, xm to eA
+}
+
+type eA2 struct {
+	*eX // *eX contributes xf, xm to eA
+}
+
+type eB struct {
+	eY // eY contributes xf, xm to eB
+}
+
+type eB2 struct {
+	*eY // *eY contributes xf, xm to eB
+}
+
+type eC struct {
+	eZ // eZ contributes xf, xm to eC
+}
+
+var (
+	_ = eA{}.xf
+	_ = eA{}.xm
+	_ = eA2{}.xf
+	_ = eA2{}.xm
+	_ = eB{}.xf
+	_ = eB{}.xm
+	_ = eB2{}.xf
+	_ = eB2{}.xm
+	_ = eC{}.xf
+	_ = eC{}.xm
+)
+
+// ambiguous selectors due to embedding via type aliases
+type eD struct {
+	eY
+	eZ
+}
+
+var (
+	_ = eD{}.xf /* ERROR ambiguous selector eD{}.xf */
+	_ = eD{}.xm /* ERROR ambiguous selector eD{}.xm */
+)
+
+var (
+	_ interface{ xm() } = eD /* ERROR missing method xm */ {}
+)
\ No newline at end of file
diff --git a/src/go/types/testdata/check/decls5.go b/src/internal/types/testdata/check/decls5.go
similarity index 100%
rename from src/go/types/testdata/check/decls5.go
rename to src/internal/types/testdata/check/decls5.go
diff --git a/src/internal/types/testdata/check/errors.go b/src/internal/types/testdata/check/errors.go
new file mode 100644
index 0000000..b3ab8af
--- /dev/null
+++ b/src/internal/types/testdata/check/errors.go
@@ -0,0 +1,66 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package errors
+
+// Testing precise operand formatting in error messages
+// (matching messages are regular expressions, hence the \'s).
+func f(x int, m map[string]int) {
+	// no values
+	_ = f /* ERROR f\(0, m\) \(no value\) used as value */ (0, m)
+
+	// built-ins
+	_ = println // ERROR println \(built-in\) must be called
+
+	// types
+	_ = complex128 // ERROR complex128 \(type\) is not an expression
+
+	// constants
+	const c1 = 991
+	const c2 float32 = 0.5
+	const c3 = "foo"
+	0 // ERROR 0 \(untyped int constant\) is not used
+	0.5 // ERROR 0.5 \(untyped float constant\) is not used
+	"foo" // ERROR "foo" \(untyped string constant\) is not used
+	c1 // ERROR c1 \(untyped int constant 991\) is not used
+	c2 // ERROR c2 \(constant 0.5 of type float32\) is not used
+	c1 /* ERROR c1 \+ c2 \(constant 991.5 of type float32\) is not used */ + c2
+	c3 // ERROR c3 \(untyped string constant "foo"\) is not used
+
+	// variables
+	x // ERROR x \(variable of type int\) is not used
+
+	// values
+	nil // ERROR nil is not used
+	( /* ERROR \(\*int\)\(nil\) \(value of type \*int\) is not used */ *int)(nil)
+	x /* ERROR x != x \(untyped bool value\) is not used */ != x
+	x /* ERROR x \+ x \(value of type int\) is not used */ + x
+
+	// value, ok's
+	const s = "foo"
+	m /* ERROR m\[s\] \(map index expression of type int\) is not used */ [s]
+}
+
+// Valid ERROR comments can have a variety of forms.
+func _() {
+	0 /* ERROR "0 .* is not used" */
+	0 /* ERROR 0 .* is not used */
+	0 // ERROR "0 .* is not used"
+	0 // ERROR 0 .* is not used
+}
+
+// Don't report spurious errors as a consequence of earlier errors.
+// Add more tests as needed.
+func _() {
+	if err := foo /* ERROR undefined */ (); err != nil /* no error here */ {}
+}
+
+// Use unqualified names for package-local objects.
+type T struct{}
+var _ int = T /* ERROR value of type T */ {} // use T in error message rather then errors.T
+
+// Don't report errors containing "invalid type" (issue #24182).
+func _(x *missing /* ERROR undefined: missing */ ) {
+	x.m() // there shouldn't be an error here referring to *invalid type
+}
diff --git a/src/internal/types/testdata/check/expr0.go b/src/internal/types/testdata/check/expr0.go
new file mode 100644
index 0000000..dd86eca
--- /dev/null
+++ b/src/internal/types/testdata/check/expr0.go
@@ -0,0 +1,187 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// unary expressions
+
+package expr0 
+
+type mybool bool
+
+var (
+	// bool
+	b0 = true
+	b1 bool = b0
+	b2 = !true
+	b3 = !b1
+	b4 bool = !true
+	b5 bool = !b4
+	b6 = +b0 /* ERROR "not defined" */
+	b7 = -b0 /* ERROR "not defined" */
+	b8 = ^b0 /* ERROR "not defined" */
+	b9 = *b0 /* ERROR "cannot indirect" */
+	b10 = &true /* ERROR "cannot take address" */
+	b11 = &b0
+	b12 = <-b0 /* ERROR "cannot receive" */
+	b13 = & & /* ERROR "cannot take address" */ b0
+
+	// byte
+	_ = byte(0)
+	_ = byte(- /* ERROR "cannot convert" */ 1)
+	_ = - /* ERROR "-byte\(1\) \(constant -1 of type byte\) overflows byte" */ byte(1) // test for issue 11367
+	_ = byte /* ERROR "overflows byte" */ (0) - byte(1)
+
+	// int
+	i0 = 1
+	i1 int = i0
+	i2 = +1
+	i3 = +i0
+	i4 int = +1
+	i5 int = +i4
+	i6 = -1
+	i7 = -i0
+	i8 int = -1
+	i9 int = -i4
+	i10 = !i0 /* ERROR "not defined" */
+	i11 = ^1
+	i12 = ^i0
+	i13 int = ^1
+	i14 int = ^i4
+	i15 = *i0 /* ERROR "cannot indirect" */
+	i16 = &i0
+	i17 = *i16
+	i18 = <-i16 /* ERROR "cannot receive" */
+
+	// uint
+	u0 = uint(1)
+	u1 uint = u0
+	u2 = +1
+	u3 = +u0
+	u4 uint = +1
+	u5 uint = +u4
+	u6 = -1
+	u7 = -u0
+	u8 uint = - /* ERROR "overflows" */ 1
+	u9 uint = -u4
+	u10 = !u0 /* ERROR "not defined" */
+	u11 = ^1
+	u12 = ^i0
+	u13 uint = ^ /* ERROR "overflows" */ 1
+	u14 uint = ^u4
+	u15 = *u0 /* ERROR "cannot indirect" */
+	u16 = &u0
+	u17 = *u16
+	u18 = <-u16 /* ERROR "cannot receive" */
+	u19 = ^uint(0)
+
+	// float64
+	f0 = float64(1)
+	f1 float64 = f0
+	f2 = +1
+	f3 = +f0
+	f4 float64 = +1
+	f5 float64 = +f4
+	f6 = -1
+	f7 = -f0
+	f8 float64 = -1
+	f9 float64 = -f4
+	f10 = !f0 /* ERROR "not defined" */
+	f11 = ^1
+	f12 = ^i0
+	f13 float64 = ^1
+	f14 float64 = ^f4 /* ERROR "not defined" */
+	f15 = *f0 /* ERROR "cannot indirect" */
+	f16 = &f0
+	f17 = *u16
+	f18 = <-u16 /* ERROR "cannot receive" */
+
+	// complex128
+	c0 = complex128(1)
+	c1 complex128 = c0
+	c2 = +1
+	c3 = +c0
+	c4 complex128 = +1
+	c5 complex128 = +c4
+	c6 = -1
+	c7 = -c0
+	c8 complex128 = -1
+	c9 complex128 = -c4
+	c10 = !c0 /* ERROR "not defined" */
+	c11 = ^1
+	c12 = ^i0
+	c13 complex128 = ^1
+	c14 complex128 = ^c4 /* ERROR "not defined" */
+	c15 = *c0 /* ERROR "cannot indirect" */
+	c16 = &c0
+	c17 = *u16
+	c18 = <-u16 /* ERROR "cannot receive" */
+
+	// string
+	s0 = "foo"
+	s1 = +"foo" /* ERROR "not defined" */
+	s2 = -s0 /* ERROR "not defined" */
+	s3 = !s0 /* ERROR "not defined" */
+	s4 = ^s0 /* ERROR "not defined" */
+	s5 = *s4
+	s6 = &s4
+	s7 = *s6
+	s8 = <-s7
+
+	// channel
+	ch chan int
+	rc <-chan float64
+	sc chan <- string
+	ch0 = +ch /* ERROR "not defined" */
+	ch1 = -ch /* ERROR "not defined" */
+	ch2 = !ch /* ERROR "not defined" */
+	ch3 = ^ch /* ERROR "not defined" */
+	ch4 = *ch /* ERROR "cannot indirect" */
+	ch5 = &ch
+	ch6 = *ch5
+	ch7 = <-ch
+	ch8 = <-rc
+	ch9 = <-sc /* ERROR "cannot receive" */
+	ch10, ok = <-ch
+	// ok is of type bool
+	ch11, myok = <-ch
+	_ mybool = myok /* ERROR "cannot use .* in variable declaration" */
+)
+
+// address of composite literals
+type T struct{x, y int}
+
+func f() T { return T{} }
+
+var (
+	_ = &T{1, 2}
+	_ = &[...]int{}
+	_ = &[]int{}
+	_ = &[]int{}
+	_ = &map[string]T{}
+	_ = &(T{1, 2})
+	_ = &((((T{1, 2}))))
+	_ = &f /* ERROR "cannot take address" */ ()
+)
+
+// recursive pointer types
+type P *P
+
+var (
+	p1 P = new(P)
+	p2 P = *p1
+	p3 P = &p2
+)
+
+func g() (a, b int) { return }
+
+func _() {
+	_ = -g /* ERROR multiple-value g */ ()
+	_ = <-g /* ERROR multiple-value g */ ()
+}
+
+// ~ is accepted as unary operator only permitted in interface type elements
+var (
+	_ = ~ /* ERROR cannot use ~ outside of interface or type constraint */ 0
+	_ = ~ /* ERROR cannot use ~ outside of interface or type constraint */ "foo"
+	_ = ~ /* ERROR cannot use ~ outside of interface or type constraint */ i0
+)
diff --git a/src/internal/types/testdata/check/expr1.go b/src/internal/types/testdata/check/expr1.go
new file mode 100644
index 0000000..49e8bae
--- /dev/null
+++ b/src/internal/types/testdata/check/expr1.go
@@ -0,0 +1,127 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// binary expressions
+
+package expr1
+
+type mybool bool
+
+func _(x, y bool, z mybool) {
+	x = x || y
+	x = x || true
+	x = x || false
+	x = x && y
+	x = x && true
+	x = x && false
+
+	z = z /* ERROR mismatched types */ || y
+	z = z || true
+	z = z || false
+	z = z /* ERROR mismatched types */ && y
+	z = z && true
+	z = z && false
+}
+
+type myint int
+
+func _(x, y int, z myint) {
+	x = x + 1
+	x = x + 1.0
+	x = x + 1.1 // ERROR truncated to int
+	x = x + y
+	x = x - y
+	x = x * y
+	x = x / y
+	x = x % y
+	x = x << y
+	x = x >> y
+
+	z = z + 1
+	z = z + 1.0
+	z = z + 1.1 // ERROR truncated to int
+	z = z /* ERROR mismatched types */ + y
+	z = z /* ERROR mismatched types */ - y
+	z = z /* ERROR mismatched types */ * y
+	z = z /* ERROR mismatched types */ / y
+	z = z /* ERROR mismatched types */ % y
+	z = z << y
+	z = z >> y
+}
+
+type myuint uint
+
+func _(x, y uint, z myuint) {
+	x = x + 1
+	x = x + - /* ERROR overflows uint */ 1
+	x = x + 1.0
+	x = x + 1.1 // ERROR truncated to uint
+	x = x + y
+	x = x - y
+	x = x * y
+	x = x / y
+	x = x % y
+	x = x << y
+	x = x >> y
+
+	z = z + 1
+	z = x + - /* ERROR overflows uint */ 1
+	z = z + 1.0
+	z = z + 1.1 // ERROR truncated to uint
+	z = z /* ERROR mismatched types */ + y
+	z = z /* ERROR mismatched types */ - y
+	z = z /* ERROR mismatched types */ * y
+	z = z /* ERROR mismatched types */ / y
+	z = z /* ERROR mismatched types */ % y
+	z = z << y
+	z = z >> y
+}
+
+type myfloat64 float64
+
+func _(x, y float64, z myfloat64) {
+	x = x + 1
+	x = x + -1
+	x = x + 1.0
+	x = x + 1.1
+	x = x + y
+	x = x - y
+	x = x * y
+	x = x / y
+	x = x /* ERROR not defined */ % y
+	x = x /* ERROR operand x .* must be integer */ << y
+	x = x /* ERROR operand x .* must be integer */ >> y
+
+	z = z + 1
+	z = z + -1
+	z = z + 1.0
+	z = z + 1.1
+	z = z /* ERROR mismatched types */ + y
+	z = z /* ERROR mismatched types */ - y
+	z = z /* ERROR mismatched types */ * y
+	z = z /* ERROR mismatched types */ / y
+	z = z /* ERROR mismatched types */ % y
+	z = z /* ERROR operand z .* must be integer */ << y
+	z = z /* ERROR operand z .* must be integer */ >> y
+}
+
+type mystring string
+
+func _(x, y string, z mystring) {
+	x = x + "foo"
+	x = x /* ERROR not defined */ - "foo"
+	x = x /* ERROR mismatched types string and untyped int */ + 1
+	x = x + y
+	x = x /* ERROR not defined */ - y
+	x = x /* ERROR mismatched types string and untyped int */* 10
+}
+
+func f() (a, b int) { return }
+
+func _(x int) {
+	_ = f /* ERROR multiple-value f */ () + 1
+	_ = x + f /* ERROR multiple-value f */ ()
+	_ = f /* ERROR multiple-value f */ () + f
+	_ = f /* ERROR multiple-value f */ () + f /* ERROR multiple-value f */ ()
+}
diff --git a/src/internal/types/testdata/check/expr2.go b/src/internal/types/testdata/check/expr2.go
new file mode 100644
index 0000000..1929664
--- /dev/null
+++ b/src/internal/types/testdata/check/expr2.go
@@ -0,0 +1,260 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// comparisons
+
+package expr2
+
+func _bool() {
+	const t = true == true
+	const f = true == false
+	_ = t /* ERROR operator .* not defined */ < f
+	_ = 0 == t /* ERROR mismatched types untyped int and untyped bool */
+	var b bool
+	var x, y float32
+	b = x < y
+	_ = b
+	_ = struct{b bool}{x < y}
+}
+
+// corner cases
+var (
+	v0 = nil == nil // ERROR operator == not defined on untyped nil
+)
+
+func arrays() {
+	// basics
+	var a, b [10]int
+	_ = a == b
+	_ = a != b
+	_ = a /* ERROR < not defined */ < b
+	_ = a == nil /* ERROR mismatched types */
+
+	type C [10]int
+	var c C
+	_ = a == c
+
+	type D [10]int
+	var d D
+	_ = c == d /* ERROR mismatched types */
+
+	var e [10]func() int
+	_ = e /* ERROR \[10\]func\(\) int cannot be compared */ == e
+}
+
+func structs() {
+	// basics
+	var s, t struct {
+		x int
+		a [10]float32
+		_ bool
+	}
+	_ = s == t
+	_ = s != t
+	_ = s /* ERROR < not defined */ < t
+	_ = s == nil /* ERROR mismatched types */
+
+	type S struct {
+		x int
+		a [10]float32
+		_ bool
+	}
+	type T struct {
+		x int
+		a [10]float32
+		_ bool
+	}
+	var ss S
+	var tt T
+	_ = s == ss
+	_ = ss == tt /* ERROR mismatched types */
+
+	var u struct {
+		x int
+		a [10]map[string]int
+	}
+	_ = u /* ERROR cannot be compared */ == u
+}
+
+func pointers() {
+	// nil
+	_ = nil == nil // ERROR operator == not defined on untyped nil
+	_ = nil != nil // ERROR operator != not defined on untyped nil
+	_ = nil /* ERROR < not defined */ < nil
+	_ = nil /* ERROR <= not defined */ <= nil
+	_ = nil /* ERROR > not defined */ > nil
+	_ = nil /* ERROR >= not defined */ >= nil
+
+	// basics
+	var p, q *int
+	_ = p == q
+	_ = p != q
+
+	_ = p == nil
+	_ = p != nil
+	_ = nil == q
+	_ = nil != q
+
+	_ = p /* ERROR < not defined */ < q
+	_ = p /* ERROR <= not defined */ <= q
+	_ = p /* ERROR > not defined */ > q
+	_ = p /* ERROR >= not defined */ >= q
+
+	// various element types
+	type (
+		S1 struct{}
+		S2 struct{}
+		P1 *S1
+		P2 *S2
+	)
+	var (
+		ps1 *S1
+		ps2 *S2
+		p1 P1
+		p2 P2
+	)
+	_ = ps1 == ps1
+	_ = ps1 == ps2 /* ERROR mismatched types */
+	_ = ps2 == ps1 /* ERROR mismatched types */
+
+	_ = p1 == p1
+	_ = p1 == p2 /* ERROR mismatched types */
+
+	_ = p1 == ps1
+}
+
+func channels() {
+	// basics
+	var c, d chan int
+	_ = c == d
+	_ = c != d
+	_ = c == nil
+	_ = c /* ERROR < not defined */ < d
+
+	// various element types (named types)
+	type (
+		C1 chan int
+		C1r <-chan int
+		C1s chan<- int
+		C2 chan float32
+	)
+	var (
+		c1 C1
+		c1r C1r
+		c1s C1s
+		c1a chan int
+		c2 C2
+	)
+	_ = c1 == c1
+	_ = c1 == c1r /* ERROR mismatched types */
+	_ = c1 == c1s /* ERROR mismatched types */
+	_ = c1r == c1s /* ERROR mismatched types */
+	_ = c1 == c1a
+	_ = c1a == c1
+	_ = c1 == c2 /* ERROR mismatched types */
+	_ = c1a == c2 /* ERROR mismatched types */
+
+	// various element types (unnamed types)
+	var (
+		d1 chan int
+		d1r <-chan int
+		d1s chan<- int
+		d1a chan<- int
+		d2 chan float32
+	)
+	_ = d1 == d1
+	_ = d1 == d1r
+	_ = d1 == d1s
+	_ = d1r == d1s /* ERROR mismatched types */
+	_ = d1 == d1a
+	_ = d1a == d1
+	_ = d1 == d2 /* ERROR mismatched types */
+	_ = d1a == d2 /* ERROR mismatched types */
+}
+
+// for interfaces test
+type S1 struct{}
+type S11 struct{}
+type S2 struct{}
+func (*S1) m() int
+func (*S11) m() int
+func (*S11) n()
+func (*S2) m() float32
+
+func interfaces() {
+	// basics
+	var i, j interface{ m() int }
+	_ = i == j
+	_ = i != j
+	_ = i == nil
+	_ = i /* ERROR < not defined */ < j
+
+	// various interfaces
+	var ii interface { m() int; n() }
+	var k interface { m() float32 }
+	_ = i == ii
+	_ = i == k /* ERROR mismatched types */
+
+	// interfaces vs values
+	var s1 S1
+	var s11 S11
+	var s2 S2
+
+	_ = i == 0 /* ERROR cannot convert */
+	_ = i == s1 /* ERROR mismatched types */
+	_ = i == &s1
+	_ = i == &s11
+
+	_ = i == s2 /* ERROR mismatched types */
+	_ = i == & /* ERROR mismatched types */ s2
+
+	// issue #28164
+	// testcase from issue
+	_ = interface{}(nil) == [ /* ERROR slice can only be compared to nil */ ]int(nil)
+
+	// related cases
+	var e interface{}
+	var s []int
+	var x int
+	_ = e == s // ERROR slice can only be compared to nil
+	_ = s /* ERROR slice can only be compared to nil */ == e
+	_ = e /* ERROR operator < not defined on interface */ < x
+	_ = x < e // ERROR operator < not defined on interface
+}
+
+func slices() {
+	// basics
+	var s []int
+	_ = s == nil
+	_ = s != nil
+	_ = s /* ERROR < not defined */ < nil
+
+	// slices are not otherwise comparable
+	_ = s /* ERROR slice can only be compared to nil */ == s
+	_ = s /* ERROR < not defined */ < s
+}
+
+func maps() {
+	// basics
+	var m map[string]int
+	_ = m == nil
+	_ = m != nil
+	_ = m /* ERROR < not defined */ < nil
+
+	// maps are not otherwise comparable
+	_ = m /* ERROR map can only be compared to nil */ == m
+	_ = m /* ERROR < not defined */ < m
+}
+
+func funcs() {
+	// basics
+	var f func(int) float32
+	_ = f == nil
+	_ = f != nil
+	_ = f /* ERROR < not defined */ < nil
+
+	// funcs are not otherwise comparable
+	_ = f /* ERROR func can only be compared to nil */ == f
+	_ = f /* ERROR < not defined */ < f
+}
diff --git a/src/internal/types/testdata/check/expr3.go b/src/internal/types/testdata/check/expr3.go
new file mode 100644
index 0000000..2da5984
--- /dev/null
+++ b/src/internal/types/testdata/check/expr3.go
@@ -0,0 +1,564 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package expr3
+
+import "time"
+
+func indexes() {
+	_ = 1 /* ERROR "cannot index" */ [0]
+	_ = indexes /* ERROR "cannot index" */ [0]
+	_ = ( /* ERROR "cannot slice" */ 12 + 3)[1:2]
+
+	var a [10]int
+	_ = a[true /* ERROR "cannot convert" */ ]
+	_ = a["foo" /* ERROR "cannot convert" */ ]
+	_ = a[1.1 /* ERROR "truncated" */ ]
+	_ = a[1.0]
+	_ = a[- /* ERROR "negative" */ 1]
+	_ = a[- /* ERROR "negative" */ 1 :]
+	_ = a[: - /* ERROR "negative" */ 1]
+	_ = a[: /* ERROR "middle index required" */ : /* ERROR "final index required" */ ]
+	_ = a[0: /* ERROR "middle index required" */ : /* ERROR "final index required" */ ]
+	_ = a[0: /* ERROR "middle index required" */ :10]
+	_ = a[:10:10]
+
+	var a0 int
+	a0 = a[0]
+	_ = a0
+	var a1 int32
+	a1 = a /* ERROR "cannot use .* in assignment" */ [1]
+	_ = a1
+
+	_ = a[9]
+	_ = a[10 /* ERROR "index .* out of bounds" */ ]
+	_ = a[1 /* ERROR "overflows" */ <<100]
+	_ = a[1<< /* ERROR "constant shift overflow" */ 1000] // no out-of-bounds follow-on error
+	_ = a[10:]
+	_ = a[:10]
+	_ = a[10:10]
+	_ = a[11 /* ERROR "index .* out of bounds" */ :]
+	_ = a[: 11 /* ERROR "index .* out of bounds" */ ]
+	_ = a[: 1 /* ERROR "overflows" */ <<100]
+	_ = a[:10:10]
+	_ = a[:11 /* ERROR "index .* out of bounds" */ :10]
+	_ = a[:10:11 /* ERROR "index .* out of bounds" */ ]
+	_ = a[10:0 /* ERROR "invalid slice indices" */ :10]
+	_ = a[0:10:0 /* ERROR "invalid slice indices" */ ]
+	_ = a[10:0 /* ERROR "invalid slice indices" */:0]
+	_ = &a /* ERROR "cannot take address" */ [:10]
+
+	pa := &a
+	_ = pa[9]
+	_ = pa[10 /* ERROR "index .* out of bounds" */ ]
+	_ = pa[1 /* ERROR "overflows" */ <<100]
+	_ = pa[10:]
+	_ = pa[:10]
+	_ = pa[10:10]
+	_ = pa[11 /* ERROR "index .* out of bounds" */ :]
+	_ = pa[: 11 /* ERROR "index .* out of bounds" */ ]
+	_ = pa[: 1 /* ERROR "overflows" */ <<100]
+	_ = pa[:10:10]
+	_ = pa[:11 /* ERROR "index .* out of bounds" */ :10]
+	_ = pa[:10:11 /* ERROR "index .* out of bounds" */ ]
+	_ = pa[10:0 /* ERROR "invalid slice indices" */ :10]
+	_ = pa[0:10:0 /* ERROR "invalid slice indices" */ ]
+	_ = pa[10:0 /* ERROR "invalid slice indices" */ :0]
+	_ = &pa /* ERROR "cannot take address" */ [:10]
+
+	var b [0]int
+	_ = b[0 /* ERROR "index .* out of bounds" */ ]
+	_ = b[:]
+	_ = b[0:]
+	_ = b[:0]
+	_ = b[0:0]
+	_ = b[0:0:0]
+	_ = b[1 /* ERROR "index .* out of bounds" */ :0:0]
+
+	var s []int
+	_ = s[- /* ERROR "negative" */ 1]
+	_ = s[- /* ERROR "negative" */ 1 :]
+	_ = s[: - /* ERROR "negative" */ 1]
+	_ = s[0]
+	_ = s[1:2]
+	_ = s[2:1 /* ERROR "invalid slice indices" */ ]
+	_ = s[2:]
+	_ = s[: 1 /* ERROR "overflows" */ <<100]
+	_ = s[1 /* ERROR "overflows" */ <<100 :]
+	_ = s[1 /* ERROR "overflows" */ <<100 : 1 /* ERROR "overflows" */ <<100]
+	_ = s[: /* ERROR "middle index required" */ :  /* ERROR "final index required" */ ]
+	_ = s[:10:10]
+	_ = s[10:0 /* ERROR "invalid slice indices" */ :10]
+	_ = s[0:10:0 /* ERROR "invalid slice indices" */ ]
+	_ = s[10:0 /* ERROR "invalid slice indices" */ :0]
+	_ = &s /* ERROR "cannot take address" */ [:10]
+
+	var m map[string]int
+	_ = m[0 /* ERROR "cannot use .* in map index" */ ]
+	_ = m /* ERROR "cannot slice" */ ["foo" : "bar"]
+	_ = m["foo"]
+	// ok is of type bool
+	type mybool bool
+	var ok mybool
+	_, ok = m["bar"]
+	_ = ok
+	_ = m/* ERROR "mismatched types int and untyped string" */[0 /* ERROR "cannot use 0" */ ] + "foo"
+
+	var t string
+	_ = t[- /* ERROR "negative" */ 1]
+	_ = t[- /* ERROR "negative" */ 1 :]
+	_ = t[: - /* ERROR "negative" */ 1]
+	_ = t[1:2:3 /* ERROR "3-index slice of string" */ ]
+	_ = "foo"[1:2:3 /* ERROR "3-index slice of string" */ ]
+	var t0 byte
+	t0 = t[0]
+	_ = t0
+	var t1 rune
+	t1 = t /* ERROR "cannot use .* in assignment" */ [2]
+	_ = t1
+	_ = ("foo" + "bar")[5]
+	_ = ("foo" + "bar")[6 /* ERROR "index .* out of bounds" */ ]
+
+	const c = "foo"
+	_ = c[- /* ERROR "negative" */ 1]
+	_ = c[- /* ERROR "negative" */ 1 :]
+	_ = c[: - /* ERROR "negative" */ 1]
+	var c0 byte
+	c0 = c[0]
+	_ = c0
+	var c2 float32
+	c2 = c /* ERROR "cannot use .* in assignment" */ [2]
+	_ = c[3 /* ERROR "index .* out of bounds" */ ]
+	_ = ""[0 /* ERROR "index .* out of bounds" */ ]
+	_ = c2
+
+	_ = s[1<<30] // no compile-time error here
+
+	// issue 4913
+	type mystring string
+	var ss string
+	var ms mystring
+	var i, j int
+	ss = "foo"[1:2]
+	ss = "foo"[i:j]
+	ms = "foo" /* ERROR "cannot use .* in assignment" */ [1:2]
+	ms = "foo" /* ERROR "cannot use .* in assignment" */ [i:j]
+	_, _ = ss, ms
+}
+
+type T struct {
+	x int
+	y func()
+}
+
+func (*T) m() {}
+
+func method_expressions() {
+	_ = T.a /* ERROR "no field or method" */
+	_ = T.x /* ERROR "has no method" */
+	_ = T.m /* ERROR "invalid method expression T\.m \(needs pointer receiver \(\*T\)\.m\)" */
+	_ = (*T).m
+
+	var f func(*T) = T.m /* ERROR "invalid method expression T\.m \(needs pointer receiver \(\*T\)\.m\)" */
+	var g func(*T) = (*T).m
+	_, _ = f, g
+
+	_ = T.y /* ERROR "has no method" */
+	_ = (*T).y /* ERROR "has no method" */
+}
+
+func struct_literals() {
+	type T0 struct {
+		a, b, c int
+	}
+
+	type T1 struct {
+		T0
+		a, b int
+		u float64
+		s string
+	}
+
+	// keyed elements
+	_ = T1{}
+	_ = T1{a: 0, 1 /* ERROR "mixture of .* elements" */ }
+	_ = T1{aa /* ERROR "unknown field" */ : 0}
+	_ = T1{1 /* ERROR "invalid field name" */ : 0}
+	_ = T1{a: 0, s: "foo", u: 0, a /* ERROR "duplicate field" */: 10}
+	_ = T1{a: "foo" /* ERROR "cannot use .* in struct literal" */ }
+	_ = T1{c /* ERROR "unknown field" */ : 0}
+	_ = T1{T0: { /* ERROR "missing type" */ }} // struct literal element type may not be elided
+	_ = T1{T0: T0{}}
+	_ = T1{T0 /* ERROR "invalid field name" */ .a: 0}
+
+	// unkeyed elements
+	_ = T0{1, 2, 3}
+	_ = T0{1, b /* ERROR "mixture" */ : 2, 3}
+	_ = T0{1, 2} /* ERROR "too few values" */
+	_ = T0{1, 2, 3, 4  /* ERROR "too many values" */ }
+	_ = T0{1, "foo" /* ERROR "cannot use .* in struct literal" */, 3.4  /* ERROR "cannot use .*\(truncated\)" */}
+
+	// invalid type
+	type P *struct{
+		x int
+	}
+	_ = P /* ERROR "invalid composite literal type" */ {}
+
+	// unexported fields
+	_ = time.Time{}
+	_ = time.Time{sec /* ERROR "unknown field" */ : 0}
+	_ = time.Time{
+		0 /* ERROR implicit assignment to unexported field wall in struct literal */,
+		0 /* ERROR implicit assignment */ ,
+		nil /* ERROR implicit assignment */ ,
+	}
+}
+
+func array_literals() {
+	type A0 [0]int
+	_ = A0{}
+	_ = A0{0 /* ERROR "index .* out of bounds" */}
+	_ = A0{0 /* ERROR "index .* out of bounds" */ : 0}
+
+	type A1 [10]int
+	_ = A1{}
+	_ = A1{0, 1, 2}
+	_ = A1{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
+	_ = A1{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 /* ERROR "index .* out of bounds" */ }
+	_ = A1{- /* ERROR "negative" */ 1: 0}
+	_ = A1{8: 8, 9}
+	_ = A1{8: 8, 9, 10 /* ERROR "index .* out of bounds" */ }
+	_ = A1{0, 1, 2, 0 /* ERROR "duplicate index" */ : 0, 3: 3, 4}
+	_ = A1{5: 5, 6, 7, 3: 3, 4}
+	_ = A1{5: 5, 6, 7, 3: 3, 4, 5 /* ERROR "duplicate index" */ }
+	_ = A1{10 /* ERROR "index .* out of bounds" */ : 10, 10 /* ERROR "index .* out of bounds" */ : 10}
+	_ = A1{5: 5, 6, 7, 3: 3, 1 /* ERROR "overflows" */ <<100: 4, 5 /* ERROR "duplicate index" */ }
+	_ = A1{5: 5, 6, 7, 4: 4, 1 /* ERROR "overflows" */ <<100: 4}
+	_ = A1{2.0}
+	_ = A1{2.1 /* ERROR "truncated" */ }
+	_ = A1{"foo" /* ERROR "cannot use .* in array or slice literal" */ }
+
+	// indices must be integer constants
+	i := 1
+	const f = 2.1
+	const s = "foo"
+	_ = A1{i /* ERROR "index i must be integer constant" */ : 0}
+	_ = A1{f /* ERROR "truncated" */ : 0}
+	_ = A1{s /* ERROR "cannot convert" */ : 0}
+
+	a0 := [...]int{}
+	assert(len(a0) == 0)
+
+	a1 := [...]int{0, 1, 2}
+	assert(len(a1) == 3)
+	var a13 [3]int
+	var a14 [4]int
+	a13 = a1
+	a14 = a1 /* ERROR "cannot use .* in assignment" */
+	_, _ = a13, a14
+
+	a2 := [...]int{- /* ERROR "negative" */ 1: 0}
+	_ = a2
+
+	a3 := [...]int{0, 1, 2, 0 /* ERROR "duplicate index" */ : 0, 3: 3, 4}
+	assert(len(a3) == 5) // somewhat arbitrary
+
+	a4 := [...]complex128{0, 1, 2, 1<<10-2: -1i, 1i, 400: 10, 12, 14}
+	assert(len(a4) == 1024)
+
+	// composite literal element types may be elided
+	type T []int
+	_ = [10]T{T{}, {}, 5: T{1, 2, 3}, 7: {1, 2, 3}}
+	a6 := [...]T{T{}, {}, 5: T{1, 2, 3}, 7: {1, 2, 3}}
+	assert(len(a6) == 8)
+
+	// recursively so
+	_ = [10][10]T{{}, [10]T{{}}, {{1, 2, 3}}}
+
+	// from the spec
+	type Point struct { x, y float32 }
+	_ = [...]Point{Point{1.5, -3.5}, Point{0, 0}}
+	_ = [...]Point{{1.5, -3.5}, {0, 0}}
+	_ = [][]int{[]int{1, 2, 3}, []int{4, 5}}
+	_ = [][]int{{1, 2, 3}, {4, 5}}
+	_ = [...]*Point{&Point{1.5, -3.5}, &Point{0, 0}}
+	_ = [...]*Point{{1.5, -3.5}, {0, 0}}
+}
+
+func slice_literals() {
+	type S0 []int
+	_ = S0{}
+	_ = S0{0, 1, 2}
+	_ = S0{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
+	_ = S0{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
+	_ = S0{- /* ERROR "negative" */ 1: 0}
+	_ = S0{8: 8, 9}
+	_ = S0{8: 8, 9, 10}
+	_ = S0{0, 1, 2, 0 /* ERROR "duplicate index" */ : 0, 3: 3, 4}
+	_ = S0{5: 5, 6, 7, 3: 3, 4}
+	_ = S0{5: 5, 6, 7, 3: 3, 4, 5 /* ERROR "duplicate index" */ }
+	_ = S0{10: 10, 10 /* ERROR "duplicate index" */ : 10}
+	_ = S0{5: 5, 6, 7, 3: 3, 1 /* ERROR "overflows" */ <<100: 4, 5 /* ERROR "duplicate index" */ }
+	_ = S0{5: 5, 6, 7, 4: 4, 1 /* ERROR "overflows" */ <<100: 4}
+	_ = S0{2.0}
+	_ = S0{2.1 /* ERROR "truncated" */ }
+	_ = S0{"foo" /* ERROR "cannot use .* in array or slice literal" */ }
+
+	// indices must be resolved correctly
+	const index1 = 1
+	_ = S0{index1: 1}
+	_ = S0{index2: 2}
+	_ = S0{index3 /* ERROR "undefined" */ : 3}
+
+	// indices must be integer constants
+	i := 1
+	const f = 2.1
+	const s = "foo"
+	_ = S0{i /* ERROR "index i must be integer constant" */ : 0}
+	_ = S0{f /* ERROR "truncated" */ : 0}
+	_ = S0{s /* ERROR "cannot convert" */ : 0}
+
+	// composite literal element types may be elided
+	type T []int
+	_ = []T{T{}, {}, 5: T{1, 2, 3}, 7: {1, 2, 3}}
+	_ = [][]int{{1, 2, 3}, {4, 5}}
+
+	// recursively so
+	_ = [][]T{{}, []T{{}}, {{1, 2, 3}}}
+
+	// issue 17954
+	type T0 *struct { s string }
+	_ = []T0{{}}
+	_ = []T0{{"foo"}}
+
+	type T1 *struct{ int }
+	_ = []T1{}
+	_ = []T1{{0}, {1}, {2}}
+
+	type T2 T1
+	_ = []T2{}
+	_ = []T2{{0}, {1}, {2}}
+
+	_ = map[T0]T2{}
+	_ = map[T0]T2{{}: {}}
+}
+
+const index2 int = 2
+
+type N int
+func (N) f() {}
+
+func map_literals() {
+	type M0 map[string]int
+	type M1 map[bool]int
+	type M2 map[*int]int
+
+	_ = M0{}
+	_ = M0{1 /* ERROR "missing key" */ }
+	_ = M0{1 /* ERROR "cannot use .* in map literal" */ : 2}
+	_ = M0{"foo": "bar" /* ERROR "cannot use .* in map literal" */ }
+	_ = M0{"foo": 1, "bar": 2, "foo" /* ERROR "duplicate key" */ : 3 }
+
+	_ = map[interface{}]int{2: 1, 2 /* ERROR "duplicate key" */ : 1}
+	_ = map[interface{}]int{int(2): 1, int16(2): 1}
+	_ = map[interface{}]int{int16(2): 1, int16 /* ERROR "duplicate key" */ (2): 1}
+
+	type S string
+
+	_ = map[interface{}]int{"a": 1, "a" /* ERROR "duplicate key" */ : 1}
+	_ = map[interface{}]int{"a": 1, S("a"): 1}
+	_ = map[interface{}]int{S("a"): 1, S /* ERROR "duplicate key" */ ("a"): 1}
+	_ = map[interface{}]int{1.0: 1, 1.0 /* ERROR "duplicate key" */: 1}
+	_ = map[interface{}]int{int64(-1): 1, int64 /* ERROR "duplicate key" */ (-1) : 1}
+	_ = map[interface{}]int{^uint64(0): 1, ^ /* ERROR "duplicate key" */ uint64(0): 1}
+	_ = map[interface{}]int{complex(1,2): 1, complex /* ERROR "duplicate key" */ (1,2) : 1}
+
+	type I interface {
+		f()
+	}
+
+	_ = map[I]int{N(0): 1, N(2): 1}
+	_ = map[I]int{N(2): 1, N /* ERROR "duplicate key" */ (2): 1}
+
+	// map keys must be resolved correctly
+	key1 := "foo"
+	_ = M0{key1: 1}
+	_ = M0{key2: 2}
+	_ = M0{key3 /* ERROR "undefined" */ : 2}
+
+	var value int
+	_ = M1{true: 1, false: 0}
+	_ = M2{nil: 0, &value: 1}
+
+	// composite literal element types may be elided
+	type T [2]int
+	_ = map[int]T{0: T{3, 4}, 1: {5, 6}}
+
+	// recursively so
+	_ = map[int][]T{0: {}, 1: {{}, T{1, 2}}}
+
+	// composite literal key types may be elided
+	_ = map[T]int{T{3, 4}: 0, {5, 6}: 1}
+
+	// recursively so
+	_ = map[[2]T]int{{}: 0, {{}}: 1, [2]T{{}}: 2, {T{1, 2}}: 3}
+
+	// composite literal element and key types may be elided
+	_ = map[T]T{{}: {}, {1, 2}: T{3, 4}, T{4, 5}: {}}
+	_ = map[T]M0{{} : {}, T{1, 2}: M0{"foo": 0}, {1, 3}: {"foo": 1}}
+
+	// recursively so
+	_ = map[[2]T][]T{{}: {}, {{}}: {{}, T{1, 2}}, [2]T{{}}: nil, {T{1, 2}}: {{}, {}}}
+
+	// from the spec
+	type Point struct { x, y float32 }
+	_ = map[string]Point{"orig": {0, 0}}
+	_ = map[*Point]string{{0, 0}: "orig"}
+
+	// issue 17954
+	type T0 *struct{ s string }
+	type T1 *struct{ int }
+	type T2 T1
+
+	_ = map[T0]T2{}
+	_ = map[T0]T2{{}: {}}
+}
+
+var key2 string = "bar"
+
+type I interface {
+	m()
+}
+
+type I2 interface {
+	m(int)
+}
+
+type T1 struct{}
+type T2 struct{}
+
+func (T2) m(int) {}
+
+type mybool bool
+
+func type_asserts() {
+	var x int
+	_ = x /* ERROR "not an interface" */ .(int)
+
+	var e interface{}
+	var ok bool
+	x, ok = e.(int)
+	_ = ok
+
+	// ok value is of type bool
+	var myok mybool
+	_, myok = e.(int)
+	_ = myok
+
+	var t I
+	_ = t /* ERROR "use of .* outside type switch" */ .(type)
+	_ = t /* ERROR "m has pointer receiver" */ .(T)
+	_ = t.(*T)
+	_ = t /* ERROR "missing method m" */ .(T1)
+	_ = t /* ERROR "wrong type for method m" */ .(T2)
+	_ = t /* STRICT "wrong type for method m" */ .(I2) // only an error in strict mode (issue 8561)
+
+	// e doesn't statically have an m, but may have one dynamically.
+	_ = e.(I2)
+}
+
+func f0() {}
+func f1(x int) {}
+func f2(u float32, s string) {}
+func fs(s []byte) {}
+func fv(x ...int) {}
+func fi(x ... interface{}) {}
+func (T) fm(x ...int)
+
+func g0() {}
+func g1() int { return 0}
+func g2() (u float32, s string) { return }
+func gs() []byte { return nil }
+
+func _calls() {
+	var x int
+	var y float32
+	var s []int
+
+	f0()
+	_ = f0 /* ERROR "used as value" */ ()
+	f0(g0 /* ERROR "too many arguments" */ )
+
+	f1(0)
+	f1(x)
+	f1(10.0)
+	f1() /* ERROR "not enough arguments in call to f1\n\thave \(\)\n\twant \(int\)" */
+	f1(x, y /* ERROR "too many arguments in call to f1\n\thave \(int, float32\)\n\twant \(int\)" */ )
+	f1(s /* ERROR "cannot use .* in argument" */ )
+	f1(x ... /* ERROR "cannot use ..." */ )
+	f1(g0 /* ERROR "used as value" */ ())
+	f1(g1())
+	f1(g2 /* ERROR "too many arguments in call to f1\n\thave \(float32, string\)\n\twant \(int\)" */ ())
+
+	f2() /* ERROR "not enough arguments in call to f2\n\thave \(\)\n\twant \(float32, string\)" */
+	f2(3.14) /* ERROR "not enough arguments in call to f2\n\thave \(number\)\n\twant \(float32, string\)" */
+	f2(3.14, "foo")
+	f2(x /* ERROR "cannot use .* in argument" */ , "foo")
+	f2(g0 /* ERROR "used as value" */ ())
+	f2(g1()) /* ERROR "not enough arguments in call to f2\n\thave \(int\)\n\twant \(float32, string\)" */
+	f2(g2())
+
+	fs() /* ERROR "not enough arguments" */
+	fs(g0 /* ERROR "used as value" */ ())
+	fs(g1 /* ERROR "cannot use .* in argument" */ ())
+	fs(g2 /* ERROR "too many arguments" */ ())
+	fs(gs())
+
+	fv()
+	fv(1, 2.0, x)
+	fv(s /* ERROR "cannot use .* in argument" */ )
+	fv(s...)
+	fv(x /* ERROR "cannot use" */ ...)
+	fv(1, s /* ERROR "too many arguments" */ ...)
+	fv(gs /* ERROR "cannot use .* in argument" */ ())
+	fv(gs /* ERROR "cannot use .* in argument" */ ()...)
+
+	var t T
+	t.fm()
+	t.fm(1, 2.0, x)
+	t.fm(s /* ERROR "cannot use .* in argument" */ )
+	t.fm(g1())
+	t.fm(1, s /* ERROR "too many arguments" */ ...)
+	t.fm(gs /* ERROR "cannot use .* in argument" */ ())
+	t.fm(gs /* ERROR "cannot use .* in argument" */ ()...)
+
+	T.fm(t, )
+	T.fm(t, 1, 2.0, x)
+	T.fm(t, s /* ERROR "cannot use .* in argument" */ )
+	T.fm(t, g1())
+	T.fm(t, 1, s /* ERROR "too many arguments" */ ...)
+	T.fm(t, gs /* ERROR "cannot use .* in argument" */ ())
+	T.fm(t, gs /* ERROR "cannot use .* in argument" */ ()...)
+
+	var i interface{ fm(x ...int) } = t
+	i.fm()
+	i.fm(1, 2.0, x)
+	i.fm(s /* ERROR "cannot use .* in argument" */ )
+	i.fm(g1())
+	i.fm(1, s /* ERROR "too many arguments" */ ...)
+	i.fm(gs /* ERROR "cannot use .* in argument" */ ())
+	i.fm(gs /* ERROR "cannot use .* in argument" */ ()...)
+
+	fi()
+	fi(1, 2.0, x, 3.14, "foo")
+	fi(g2())
+	fi(0, g2)
+	fi(0, g2 /* ERROR "multiple-value g2" */ ())
+}
+
+func issue6344() {
+	type T []interface{}
+	var x T
+	fi(x...) // ... applies also to named slices
+}
diff --git a/src/go/types/testdata/check/funcinference.go b/src/internal/types/testdata/check/funcinference.go
similarity index 100%
rename from src/go/types/testdata/check/funcinference.go
rename to src/internal/types/testdata/check/funcinference.go
diff --git a/src/cmd/compile/internal/types2/testdata/check/go1_12.go b/src/internal/types/testdata/check/go1_12.go
similarity index 100%
rename from src/cmd/compile/internal/types2/testdata/check/go1_12.go
rename to src/internal/types/testdata/check/go1_12.go
diff --git a/src/cmd/compile/internal/types2/testdata/check/go1_13.go b/src/internal/types/testdata/check/go1_13.go
similarity index 100%
rename from src/cmd/compile/internal/types2/testdata/check/go1_13.go
rename to src/internal/types/testdata/check/go1_13.go
diff --git a/src/go/types/testdata/check/go1_16.go b/src/internal/types/testdata/check/go1_16.go
similarity index 100%
rename from src/go/types/testdata/check/go1_16.go
rename to src/internal/types/testdata/check/go1_16.go
diff --git a/src/internal/types/testdata/check/go1_19.go b/src/internal/types/testdata/check/go1_19.go
new file mode 100644
index 0000000..f899d93
--- /dev/null
+++ b/src/internal/types/testdata/check/go1_19.go
@@ -0,0 +1,15 @@
+// -lang=go1.19
+
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check Go language version-specific errors.
+
+package p
+
+type Slice []byte
+type Array [8]byte
+
+var s Slice
+var p = (Array)(s /* ERROR requires go1.20 or later */)
diff --git a/src/internal/types/testdata/check/go1_8.go b/src/internal/types/testdata/check/go1_8.go
new file mode 100644
index 0000000..99f2fd4
--- /dev/null
+++ b/src/internal/types/testdata/check/go1_8.go
@@ -0,0 +1,12 @@
+// -lang=go1.8
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check Go language version-specific errors.
+
+package p
+
+// type alias declarations
+type any = /* ERROR type aliases requires go1.9 or later */ interface{}
diff --git a/src/go/types/testdata/check/gotos.go b/src/internal/types/testdata/check/gotos.go
similarity index 100%
rename from src/go/types/testdata/check/gotos.go
rename to src/internal/types/testdata/check/gotos.go
diff --git a/src/go/types/testdata/check/importC.go b/src/internal/types/testdata/check/importC.go
similarity index 100%
rename from src/go/types/testdata/check/importC.go
rename to src/internal/types/testdata/check/importC.go
diff --git a/src/internal/types/testdata/check/importdecl0/importdecl0a.go b/src/internal/types/testdata/check/importdecl0/importdecl0a.go
new file mode 100644
index 0000000..d514ae4
--- /dev/null
+++ b/src/internal/types/testdata/check/importdecl0/importdecl0a.go
@@ -0,0 +1,53 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package importdecl0
+
+import ()
+
+import (
+	// we can have multiple blank imports (was bug)
+	_ "math"
+	_ "net/rpc"
+	init /* ERROR "cannot import package as init" */ "fmt"
+	// reflect defines a type "flag" which shows up in the gc export data
+	"reflect"
+	. /* ERROR "imported and not used" */ "reflect"
+)
+
+import "math" /* ERROR "imported and not used" */
+import m /* ERROR "imported as m and not used" */ "math"
+import _ "math"
+
+import (
+	"math/big" /* ERROR "imported and not used" */
+	b /* ERROR "imported as b and not used" */ "math/big"
+	_ "math/big"
+)
+
+import "fmt"
+import f1 "fmt"
+import f2 "fmt"
+
+// reflect.flag must not be visible in this package
+type flag int
+type _ reflect.flag /* ERROR "not exported" */
+
+// imported package name may conflict with local objects
+type reflect /* ERROR "reflect already declared" */ int
+
+// dot-imported exported objects may conflict with local objects
+type Value /* ERROR "Value already declared through dot-import of package reflect" */ struct{}
+
+var _ = fmt.Println // use "fmt"
+
+func _() {
+	f1.Println() // use "fmt"
+}
+
+func _() {
+	_ = func() {
+		f2.Println() // use "fmt"
+	}
+}
diff --git a/src/internal/types/testdata/check/importdecl0/importdecl0b.go b/src/internal/types/testdata/check/importdecl0/importdecl0b.go
new file mode 100644
index 0000000..904faff
--- /dev/null
+++ b/src/internal/types/testdata/check/importdecl0/importdecl0b.go
@@ -0,0 +1,30 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package importdecl0
+
+import "math"
+import m "math"
+
+import . "testing" // declares T in file scope
+import . /* ERROR .unsafe. imported and not used */ "unsafe"
+import . "fmt"     // declares Println in file scope
+
+import (
+	"" /* ERROR invalid import path */
+	"a!b" /* ERROR invalid import path */
+	"abc\xffdef" /* ERROR invalid import path */
+)
+
+// using "math" in this file doesn't affect its use in other files
+const Pi0 = math.Pi
+const Pi1 = m.Pi
+
+type _ T // use "testing"
+
+func _() func() interface{} {
+	return func() interface{} {
+		return Println // use "fmt"
+	}
+}
diff --git a/src/go/types/testdata/check/importdecl1/importdecl1a.go b/src/internal/types/testdata/check/importdecl1/importdecl1a.go
similarity index 100%
rename from src/go/types/testdata/check/importdecl1/importdecl1a.go
rename to src/internal/types/testdata/check/importdecl1/importdecl1a.go
diff --git a/src/internal/types/testdata/check/importdecl1/importdecl1b.go b/src/internal/types/testdata/check/importdecl1/importdecl1b.go
new file mode 100644
index 0000000..ce8b983
--- /dev/null
+++ b/src/internal/types/testdata/check/importdecl1/importdecl1b.go
@@ -0,0 +1,11 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package importdecl1
+
+import . /* ERROR .unsafe. imported and not used */ "unsafe"
+
+type B interface {
+	A
+}
diff --git a/src/internal/types/testdata/check/init0.go b/src/internal/types/testdata/check/init0.go
new file mode 100644
index 0000000..5159a17
--- /dev/null
+++ b/src/internal/types/testdata/check/init0.go
@@ -0,0 +1,106 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// initialization cycles
+
+package init0
+
+// initialization cycles (we don't know the types)
+const (
+	s0 /* ERROR initialization cycle: s0 refers to itself */ = s0
+
+	x0 /* ERROR initialization cycle for x0 */ = y0
+	y0 = x0
+
+	a0 = b0
+	b0 /* ERROR initialization cycle for b0 */ = c0
+	c0 = d0
+	d0 = b0
+)
+
+var (
+	s1 /* ERROR initialization cycle: s1 refers to itself */ = s1
+
+	x1 /* ERROR initialization cycle for x1 */ = y1
+	y1 = x1
+
+	a1 = b1
+	b1 /* ERROR initialization cycle for b1 */ = c1
+	c1 = d1
+	d1 = b1
+)
+
+// initialization cycles (we know the types)
+const (
+	s2 /* ERROR initialization cycle: s2 refers to itself */ int = s2
+
+	x2 /* ERROR initialization cycle for x2 */ int = y2
+	y2 = x2
+
+	a2 = b2
+	b2 /* ERROR initialization cycle for b2 */ int = c2
+	c2 = d2
+	d2 = b2
+)
+
+var (
+	s3 /* ERROR initialization cycle: s3 refers to itself */ int = s3
+
+	x3 /* ERROR initialization cycle for x3 */ int = y3
+	y3 = x3
+
+	a3 = b3
+	b3 /* ERROR initialization cycle for b3 */ int = c3
+	c3 = d3
+	d3 = b3
+)
+
+// cycles via struct fields
+
+type S1 struct {
+	f int
+}
+const cx3 S1 /* ERROR invalid constant type */ = S1{cx3.f}
+var vx3 /* ERROR initialization cycle: vx3 refers to itself */ S1 = S1{vx3.f}
+
+// cycles via functions
+
+var x4 = x5
+var x5 /* ERROR initialization cycle for x5 */ = f1()
+func f1() int { return x5*10 }
+
+var x6, x7 /* ERROR initialization cycle */ = f2()
+var x8 = x7
+func f2() (int, int) { return f3() + f3(), 0 }
+func f3() int { return x8 }
+
+// cycles via function literals
+
+var x9 /* ERROR initialization cycle: x9 refers to itself */ = func() int { return x9 }()
+
+var x10 /* ERROR initialization cycle for x10 */ = f4()
+
+func f4() int {
+	_ = func() {
+		_ = x10
+	}
+	return 0
+}
+
+// cycles via method expressions
+
+type T1 struct{}
+
+func (T1) m() bool { _ = x11; return false }
+
+var x11 /* ERROR initialization cycle for x11 */ = T1.m(T1{})
+
+// cycles via method values
+
+type T2 struct{}
+
+func (T2) m() bool { _ = x12; return false }
+
+var t1 T2
+var x12 /* ERROR initialization cycle for x12 */ = t1.m
diff --git a/src/go/types/testdata/check/init1.go b/src/internal/types/testdata/check/init1.go
similarity index 100%
rename from src/go/types/testdata/check/init1.go
rename to src/internal/types/testdata/check/init1.go
diff --git a/src/go/types/testdata/check/init2.go b/src/internal/types/testdata/check/init2.go
similarity index 100%
rename from src/go/types/testdata/check/init2.go
rename to src/internal/types/testdata/check/init2.go
diff --git a/src/go/types/testdata/check/issue25008/issue25008a.go b/src/internal/types/testdata/check/issue25008/issue25008a.go
similarity index 100%
rename from src/go/types/testdata/check/issue25008/issue25008a.go
rename to src/internal/types/testdata/check/issue25008/issue25008a.go
diff --git a/src/go/types/testdata/check/issue25008/issue25008b.go b/src/internal/types/testdata/check/issue25008/issue25008b.go
similarity index 100%
rename from src/go/types/testdata/check/issue25008/issue25008b.go
rename to src/internal/types/testdata/check/issue25008/issue25008b.go
diff --git a/src/internal/types/testdata/check/issues0.go b/src/internal/types/testdata/check/issues0.go
new file mode 100644
index 0000000..4a66641
--- /dev/null
+++ b/src/internal/types/testdata/check/issues0.go
@@ -0,0 +1,373 @@
+// -lang=go1.17
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p // don't permit non-interface elements in interfaces
+
+import (
+	"fmt"
+	syn "regexp/syntax"
+	t1 "text/template"
+	t2 "html/template"
+)
+
+func issue7035() {
+	type T struct{ X int }
+	_ = func() {
+		fmt.Println() // must refer to imported fmt rather than the fmt below
+	}
+	fmt := new(T)
+	_ = fmt.X
+}
+
+func issue8066() {
+	const (
+		_ = float32(340282356779733661637539395458142568447)
+		_ = float32(340282356779733661637539395458142568448 /* ERROR cannot convert */ )
+	)
+}
+
+// Check that a missing identifier doesn't lead to a spurious error cascade.
+func issue8799a() {
+	x, ok := missing /* ERROR undefined */ ()
+	_ = !ok
+	_ = x
+}
+
+func issue8799b(x int, ok bool) {
+	x, ok = missing /* ERROR undefined */ ()
+	_ = !ok
+	_ = x
+}
+
+func issue9182() {
+	type Point C /* ERROR undefined */ .Point
+	// no error for composite literal based on unknown type
+	_ = Point{x: 1, y: 2}
+}
+
+func f0() (a []int)         { return }
+func f1() (a []int, b int)  { return }
+func f2() (a, b []int)      { return }
+
+func append_([]int, ...int) {}
+
+func issue9473(a []int, b ...int) {
+	// variadic builtin function
+	_ = append(f0())
+	_ = append(f0(), f0()...)
+	_ = append(f1())
+	_ = append(f2 /* ERROR cannot use .* in argument */ ())
+	_ = append(f2()... /* ERROR cannot use ... */ )
+	_ = append(f0(), f1 /* ERROR multiple-value f1 */ ())
+	_ = append(f0(), f2 /* ERROR multiple-value f2 */ ())
+	_ = append(f0(), f1 /* ERROR multiple-value f1 */ ()...)
+	_ = append(f0(), f2 /* ERROR multiple-value f2 */ ()...)
+
+	// variadic user-defined function
+	append_(f0())
+	append_(f0(), f0()...)
+	append_(f1())
+	append_(f2 /* ERROR cannot use .* in argument */ ())
+	append_(f2()... /* ERROR cannot use ... */ )
+	append_(f0(), f1 /* ERROR multiple-value f1 */ ())
+	append_(f0(), f2 /* ERROR multiple-value f2 */ ())
+	append_(f0(), f1 /* ERROR multiple-value f1 */ ()...)
+	append_(f0(), f2 /* ERROR multiple-value f2 */ ()...)
+}
+
+// Check that embedding a non-interface type in an interface results in a good error message.
+func issue10979() {
+	type _ interface {
+		int /* ERROR non-interface type int */
+	}
+	type T struct{}
+	type _ interface {
+		T /* ERROR non-interface type T */
+	}
+	type _ interface {
+		nosuchtype /* ERROR undefined: nosuchtype */
+	}
+	type _ interface {
+		fmt.Nosuchtype /* ERROR undefined: fmt\.Nosuchtype */
+	}
+	type _ interface {
+		nosuchpkg /* ERROR undefined: nosuchpkg */ .Nosuchtype
+	}
+	type I interface {
+		I.m /* ERROR I.m is not a type */
+		m()
+	}
+}
+
+// issue11347
+// These should not crash.
+var a1, b1 /* ERROR cycle */ , c1 /* ERROR cycle */ b1 = 0 > 0<<""[""[c1]]>c1
+var a2, b2 /* ERROR cycle */ = 0 /* ERROR assignment mismatch */ /* ERROR assignment mismatch */ > 0<<""[b2]
+var a3, b3 /* ERROR cycle */ = int /* ERROR assignment mismatch */ /* ERROR assignment mismatch */ (1<<""[b3])
+
+// issue10260
+// Check that error messages explain reason for interface assignment failures.
+type (
+	I0 interface{}
+	I1 interface{ foo() }
+	I2 interface{ foo(x int) }
+	T0 struct{}
+	T1 struct{}
+	T2 struct{}
+)
+
+func (*T1) foo() {}
+func (*T2) foo(x int) {}
+
+func issue10260() {
+	var (
+		i0 I0
+		i1 I1
+		i2 I2
+		t0 *T0
+		t1 *T1
+		t2 *T2
+	)
+
+	var x I1
+	x = T1 /* ERROR cannot use T1{} .* as I1 value in assignment: T1 does not implement I1 \(method foo has pointer receiver\) */ {}
+	_ = x /* ERROR impossible type assertion: x\.\(T1\)\n\tT1 does not implement I1 \(method foo has pointer receiver\) */ .(T1)
+
+	T1{}.foo /* ERROR cannot call pointer method foo on T1 */ ()
+	x.Foo /* ERROR "x.Foo undefined \(type I1 has no field or method Foo, but does have foo\)" */ ()
+
+	_ = i2 /* ERROR impossible type assertion: i2\.\(\*T1\)\n\t\*T1 does not implement I2 \(wrong type for method foo\)\n\t\thave foo\(\)\n\t\twant foo\(int\) */ .(*T1)
+
+	i1 = i0 /* ERROR cannot use i0 .* as I1 value in assignment: I0 does not implement I1 \(missing method foo\) */
+	i1 = t0 /* ERROR .* t0 .* as I1 .*: \*T0 does not implement I1 \(missing method foo\) */
+	i1 = i2 /* ERROR .* i2 .* as I1 .*: I2 does not implement I1 \(wrong type for method foo\)\n\t\thave foo\(int\)\n\t\twant foo\(\) */
+	i1 = t2 /* ERROR .* t2 .* as I1 .*: \*T2 does not implement I1 \(wrong type for method foo\)\n\t\thave foo\(int\)\n\t\twant foo\(\) */
+	i2 = i1 /* ERROR .* i1 .* as I2 .*: I1 does not implement I2 \(wrong type for method foo\)\n\t\thave foo\(\)\n\t\twant foo\(int\) */
+	i2 = t1 /* ERROR .* t1 .* as I2 .*: \*T1 does not implement I2 \(wrong type for method foo\)\n\t\thave foo\(\)\n\t\twant foo\(int\) */
+
+	_ = func() I1 { return i0 /* ERROR cannot use i0 .* as I1 value in return statement: I0 does not implement I1 \(missing method foo\) */ }
+	_ = func() I1 { return t0 /* ERROR .* t0 .* as I1 .*: \*T0 does not implement I1 \(missing method foo\) */ }
+	_ = func() I1 { return i2 /* ERROR .* i2 .* as I1 .*: I2 does not implement I1 \(wrong type for method foo\)\n\t\thave foo\(int\)\n\t\twant foo\(\) */ }
+	_ = func() I1 { return t2 /* ERROR .* t2 .* as I1 .*: \*T2 does not implement I1 \(wrong type for method foo\)\n\t\thave foo\(int\)\n\t\twant foo\(\) */ }
+	_ = func() I2 { return i1 /* ERROR .* i1 .* as I2 .*: I1 does not implement I2 \(wrong type for method foo\)\n\t\thave foo\(\)\n\t\twant foo\(int\) */ }
+	_ = func() I2 { return t1 /* ERROR .* t1 .* as I2 .*: \*T1 does not implement I2 \(wrong type for method foo\)\n\t\thave foo\(\)\n\t\twant foo\(int\) */ }
+
+	// a few more - less exhaustive now
+
+	f := func(I1, I2){}
+	f(i0 /* ERROR missing method foo */ , i1 /* ERROR wrong type for method foo */ )
+
+	_ = [...]I1{i0 /* ERROR cannot use i0 .* as I1 value in array or slice literal: I0 does not implement I1 \(missing method foo\) */ }
+	_ = [...]I1{i2 /* ERROR cannot use i2 .* as I1 value in array or slice literal: I2 does not implement I1 \(wrong type for method foo\)\n\t\thave foo\(int\)\n\t\twant foo\(\) */ }
+	_ = []I1{i0 /* ERROR missing method foo */ }
+	_ = []I1{i2 /* ERROR wrong type for method foo */ }
+	_ = map[int]I1{0: i0 /* ERROR missing method foo */ }
+	_ = map[int]I1{0: i2 /* ERROR wrong type for method foo */ }
+
+	make(chan I1) <- i0 /* ERROR missing method foo */
+	make(chan I1) <- i2 /* ERROR wrong type for method foo */
+}
+
+// Check that constants representable as integers are in integer form
+// before being used in operations that are only defined on integers.
+func issue14229() {
+	// from the issue
+	const _ = int64(-1<<63) % 1e6
+
+	// related
+	const (
+		a int = 3
+		b = 4.0
+		_ = a / b
+		_ = a % b
+		_ = b / a
+		_ = b % a
+	)
+}
+
+// Check that in a n:1 variable declaration with type and initialization
+// expression the type is distributed to all variables of the lhs before
+// the initialization expression assignment is checked.
+func issue15755() {
+	// from issue
+	var i interface{}
+	type b bool
+	var x, y b = i.(b)
+	_ = x == y
+
+	// related: we should see an error since the result of f1 is ([]int, int)
+	var u, v []int = f1 /* ERROR cannot use f1 */ ()
+	_ = u
+	_ = v
+}
+
+// Test that we don't get "declared and not used"
+// errors in the context of invalid/C objects.
+func issue20358() {
+	var F C /* ERROR "undefined" */ .F
+	var A C /* ERROR "undefined" */ .A
+	var S C /* ERROR "undefined" */ .S
+	type T C /* ERROR "undefined" */ .T
+	type P C /* ERROR "undefined" */ .P
+
+	// these variables must be "used" even though
+	// the LHS expressions/types below in which
+	// context they are used are unknown/invalid
+	var f, a, s1, s2, s3, t, p int
+
+	_ = F(f)
+	_ = A[a]
+	_ = S[s1:s2:s3]
+	_ = T{t}
+	_ = P{f: p}
+}
+
+// Test that we don't declare lhs variables in short variable
+// declarations before we type-check function literals on the
+// rhs.
+func issue24026() {
+	f := func() int { f(0) /* must refer to outer f */; return 0 }
+	_ = f
+
+	_ = func() {
+		f := func() { _ = f() /* must refer to outer f */ }
+		_ = f
+	}
+
+	// b and c must not be visible inside function literal
+	a := 0
+	a, b, c := func() (int, int, int) {
+		return a, b /* ERROR undefined */ , c /* ERROR undefined */
+	}()
+	_, _ = b, c
+}
+
+func f(int) {} // for issue24026
+
+// Test that we don't report a "missing return statement" error
+// (due to incorrect context when type-checking interfaces).
+func issue24140(x interface{}) int {
+        switch x.(type) {
+        case interface{}:
+                return 0
+        default:
+                panic(0)
+        }
+}
+
+// Test that we don't crash when the 'if' condition is missing.
+func issue25438() {
+	if { /* ERROR missing condition */ }
+	if x := 0; /* ERROR missing condition */ { _ = x }
+	if
+	{ /* ERROR missing condition */ }
+}
+
+// Test that we can embed alias type names in interfaces.
+type issue25301 interface {
+	E
+}
+
+type E = interface {
+	m()
+}
+
+// Test case from issue.
+// cmd/compile reports a cycle as well.
+type issue25301b /* ERROR invalid recursive type */ = interface {
+	m() interface{ issue25301b }
+}
+
+type issue25301c interface {
+	notE // ERROR non-interface type struct\{\}
+}
+
+type notE = struct{}
+
+// Test that method declarations don't introduce artificial cycles
+// (issue #26124).
+const CC TT = 1
+type TT int
+func (TT) MM() [CC]TT
+
+// Reduced test case from issue #26124.
+const preloadLimit LNumber = 128
+type LNumber float64
+func (LNumber) assertFunction() *LFunction
+type LFunction struct {
+	GFunction LGFunction
+}
+type LGFunction func(*LState)
+type LState struct {
+	reg *registry
+}
+type registry struct {
+	alloc *allocator
+}
+type allocator struct {
+	_ [int(preloadLimit)]int
+}
+
+// Test that we don't crash when type-checking composite literals
+// containing errors in the type.
+var issue27346 = [][n /* ERROR undefined */ ]int{
+	0: {},
+}
+
+var issue22467 = map[int][... /* ERROR invalid use of ... */ ]int{0: {}}
+
+// Test that invalid use of ... in parameter lists is recognized
+// (issue #28281).
+func issue28281a(int, int, ...int)
+func issue28281b(a, b int, c ...int)
+func issue28281c(a, b, c ... /* ERROR can only use ... with final parameter */ int)
+func issue28281d(... /* ERROR can only use ... with final parameter */ int, int)
+func issue28281e(a, b, c  ... /* ERROR can only use ... with final parameter */ int, d int)
+func issue28281f(... /* ERROR can only use ... with final parameter */ int, ... /* ERROR can only use ... with final parameter */ int, int)
+func (... /* ERROR can only use ... with final parameter */ TT) f()
+func issue28281g() (... /* ERROR can only use ... with final parameter */ TT)
+
+// Issue #26234: Make various field/method lookup errors easier to read by matching cmd/compile's output
+func issue26234a(f *syn.Prog) {
+	// The error message below should refer to the actual package name (syntax)
+	// not the local package name (syn).
+	f.foo /* ERROR f\.foo undefined \(type \*syntax\.Prog has no field or method foo\) */
+}
+
+type T struct {
+	x int
+	E1
+	E2
+}
+
+type E1 struct{ f int }
+type E2 struct{ f int }
+
+func issue26234b(x T) {
+	_ = x.f /* ERROR ambiguous selector x.f */
+}
+
+func issue26234c() {
+	T.x /* ERROR T.x undefined \(type T has no method x\) */ ()
+}
+
+func issue35895() {
+	// T is defined in this package, don't qualify its name with the package name.
+	var _ T = 0 // ERROR cannot use 0 \(untyped int constant\) as T
+
+	// There is only one package with name syntax imported, only use the (global) package name in error messages.
+	var _ *syn.Prog = 0 // ERROR cannot use 0 \(untyped int constant\) as \*syntax.Prog
+
+	// Because both t1 and t2 have the same global package name (template),
+	// qualify packages with full path name in this case.
+	var _ t1.Template = t2 /* ERROR cannot use .* \(value of type .html/template.\.Template\) as .text/template.\.Template */ .Template{}
+}
+
+func issue42989(s uint) {
+	var m map[int]string
+	delete(m, 1<<s)
+	delete(m, 1.<<s)
+}
diff --git a/src/internal/types/testdata/check/issues1.go b/src/internal/types/testdata/check/issues1.go
new file mode 100644
index 0000000..2f3414d
--- /dev/null
+++ b/src/internal/types/testdata/check/issues1.go
@@ -0,0 +1,252 @@
+// -oldComparableSemantics
+
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains regression tests for bugs found.
+
+package p
+
+import "io"
+import "context"
+
+func eql[T comparable](x, y T) bool {
+	return x == y
+}
+
+func _[X comparable, Y interface{comparable; m()}]() {
+	var x X
+	var y Y
+	eql(x, y /* ERROR does not match */ ) // interfaces of different types
+	eql(x, x)
+	eql(y, y)
+	eql(y, nil /* ERROR cannot use nil as Y value in argument to eql */ )
+	eql[io /* ERROR does not satisfy comparable */ .Reader](nil, nil)
+}
+
+// If we have a receiver of pointer to type parameter type (below: *T)
+// we don't have any methods, like for interfaces.
+type C[T any] interface {
+    m()
+}
+
+// using type bound C
+func _[T C[T]](x *T) {
+	x.m /* ERROR x\.m undefined */ ()
+}
+
+// using an interface literal as bound
+func _[T interface{ m() }](x *T) {
+	x.m /* ERROR x\.m undefined */ ()
+}
+
+func f2[_ interface{ m1(); m2() }]() {}
+
+type T struct{}
+func (T) m1()
+func (*T) m2()
+
+func _() {
+	f2[T /* ERROR m2 has pointer receiver */ ]()
+	f2[*T]()
+}
+
+// When a type parameter is used as an argument to instantiate a parameterized
+// type, the type argument's type set must be a subset of the instantiated type
+// parameter's type set.
+type T1[P interface{~uint}] struct{}
+
+func _[P any]() {
+    _ = T1[P /* ERROR P does not satisfy interface{~uint} */ ]{}
+}
+
+// This is the original (simplified) program causing the same issue.
+type Unsigned interface {
+	~uint
+}
+
+type T2[U Unsigned] struct {
+    s U
+}
+
+func (u T2[U]) Add1() U {
+    return u.s + 1
+}
+
+func NewT2[U any]() T2[U /* ERROR U does not satisfy Unsigned */ ] {
+    return T2[U /* ERROR U does not satisfy Unsigned */ ]{}
+}
+
+func _() {
+    u := NewT2[string]()
+    _ = u.Add1()
+}
+
+// When we encounter an instantiated type such as Elem[T] we must
+// not "expand" the instantiation when the type to be instantiated
+// (Elem in this case) is not yet fully set up.
+type Elem[T any] struct {
+	next *Elem[T]
+	list *List[T]
+}
+
+type List[T any] struct {
+	root Elem[T]
+}
+
+func (l *List[T]) Init() {
+	l.root.next = &l.root
+}
+
+// This is the original program causing the same issue.
+type Element2[TElem any] struct {
+	next, prev *Element2[TElem]
+	list *List2[TElem]
+	Value TElem
+}
+
+type List2[TElem any] struct {
+	root Element2[TElem]
+	len  int
+}
+
+func (l *List2[TElem]) Init() *List2[TElem] {
+	l.root.next = &l.root
+	l.root.prev = &l.root
+	l.len = 0
+	return l
+}
+
+// Self-recursive instantiations must work correctly.
+type A[P any] struct { _ *A[P] }
+
+type AB[P any] struct { _ *BA[P] }
+type BA[P any] struct { _ *AB[P] }
+
+// And a variation that also caused a problem with an
+// unresolved underlying type.
+type Element3[TElem any] struct {
+	next, prev *Element3[TElem]
+	list *List3[TElem]
+	Value TElem
+}
+
+func (e *Element3[TElem]) Next() *Element3[TElem] {
+	if p := e.next; e.list != nil && p != &e.list.root {
+		return p
+	}
+	return nil
+}
+
+type List3[TElem any] struct {
+	root Element3[TElem]
+	len  int
+}
+
+// Infinite generic type declarations must lead to an error.
+type inf1[T any] struct{ _ inf1 /* ERROR invalid recursive type */ [T] }
+type inf2[T any] struct{ inf2 /* ERROR invalid recursive type */ [T] }
+
+// The implementation of conversions T(x) between integers and floating-point
+// numbers checks that both T and x have either integer or floating-point
+// type. When the type of T or x is a type parameter, the respective simple
+// predicate disjunction in the implementation was wrong because if a type set
+// contains both an integer and a floating-point type, the type parameter is
+// neither an integer or a floating-point number.
+func convert[T1, T2 interface{~int | ~uint | ~float32}](v T1) T2 {
+	return T2(v)
+}
+
+func _() {
+	convert[int, uint](5)
+}
+
+// When testing binary operators, for +, the operand types must either be
+// both numeric, or both strings. The implementation had the same problem
+// with this check as the conversion issue above (issue #39623).
+
+func issue39623[T interface{~int | ~string}](x, y T) T {
+	return x + y
+}
+
+// Simplified, from https://go2goplay.golang.org/p/efS6x6s-9NI:
+func Sum[T interface{~int | ~string}](s []T) (sum T) {
+	for _, v := range s {
+		sum += v
+	}
+	return
+}
+
+// Assignability of an unnamed pointer type to a type parameter that
+// has a matching underlying type.
+func _[T interface{}, PT interface{~*T}] (x T) PT {
+    return &x
+}
+
+// Indexing of type parameters containing type parameters in their constraint terms:
+func at[T interface{ ~[]E }, E interface{}](x T, i int) E {
+        return x[i]
+}
+
+// Conversion of a local type to a type parameter.
+func _[T interface{~int}](x T) {
+	type myint int
+	var _ int = int(x)
+	var _ T = 42
+	var _ T = T(myint(42))
+}
+
+// Indexing a type parameter with an array type bound checks length.
+// (Example by mdempsky@.)
+func _[T interface { ~[10]int }](x T) {
+	_ = x[9] // ok
+	_ = x[20 /* ERROR out of bounds */ ]
+}
+
+// Pointer indirection of a type parameter.
+func _[T interface{ ~*int }](p T) int {
+	return *p
+}
+
+// Channel sends and receives on type parameters.
+func _[T interface{ ~chan int }](ch T) int {
+	ch <- 0
+	return <- ch
+}
+
+// Calling of a generic variable.
+func _[T interface{ ~func() }](f T) {
+	f()
+	go f()
+}
+
+type F1 func()
+type F2 func()
+func _[T interface{ func()|F1|F2 }](f T) {
+	f()
+	go f()
+}
+
+// We must compare against the (possibly underlying) types of term list
+// elements when checking if a constraint is satisfied by a type.
+// The underlying type of each term must be computed after the
+// interface has been instantiated as its constraint may contain
+// a type parameter that was substituted with a defined type.
+// Test case from an (originally) failing example.
+
+type sliceOf[E any] interface{ ~[]E }
+
+func append[T interface{}, S sliceOf[T], T2 interface{}](s S, t ...T2) S { panic(0) }
+
+var f           func()
+var cancelSlice []context.CancelFunc
+var _ = append[context.CancelFunc, []context.CancelFunc, context.CancelFunc](cancelSlice, f)
+
+// A generic function must be instantiated with a type, not a value.
+
+func g[T any](T) T { panic(0) }
+
+var _ = g[int]
+var _ = g[nil /* ERROR is not a type */ ]
+var _ = g(0)
diff --git a/src/internal/types/testdata/check/labels.go b/src/internal/types/testdata/check/labels.go
new file mode 100644
index 0000000..5948952
--- /dev/null
+++ b/src/internal/types/testdata/check/labels.go
@@ -0,0 +1,207 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file is a modified concatenation of the files
+// $GOROOT/test/label.go and $GOROOT/test/label1.go.
+
+package labels
+
+var x int
+
+func f0() {
+L1 /* ERROR "label L1 declared and not used" */ :
+	for {
+	}
+L2 /* ERROR "label L2 declared and not used" */ :
+	select {
+	}
+L3 /* ERROR "label L3 declared and not used" */ :
+	switch {
+	}
+L4 /* ERROR "label L4 declared and not used" */ :
+	if true {
+	}
+L5 /* ERROR "label L5 declared and not used" */ :
+	f0()
+L6:
+	f0()
+L6 /* ERROR "label L6 already declared" */ :
+	f0()
+	if x == 20 {
+		goto L6
+	}
+
+L7:
+	for {
+		break L7
+		break L8 /* ERROR "invalid break label L8" */
+	}
+
+// A label must be directly associated with a switch, select, or
+// for statement; it cannot be the label of a labeled statement.
+
+L7a /* ERROR "declared and not used" */ : L7b:
+	for {
+		break L7a /* ERROR "invalid break label L7a" */
+		continue L7a /* ERROR "invalid continue label L7a" */
+		continue L7b
+	}
+
+L8:
+	for {
+		if x == 21 {
+			continue L8
+			continue L7 /* ERROR "invalid continue label L7" */
+		}
+	}
+
+L9:
+	switch {
+	case true:
+		break L9
+	defalt /* ERROR "label defalt declared and not used" */ :
+	}
+
+L10:
+	select {
+	default:
+		break L10
+		break L9 /* ERROR "invalid break label L9" */
+	}
+
+	goto L10a
+L10a: L10b:
+	select {
+	default:
+		break L10a /* ERROR "invalid break label L10a" */
+		break L10b
+		continue L10b /* ERROR "invalid continue label L10b" */
+	}
+}
+
+func f1() {
+L1:
+	for {
+		if x == 0 {
+			break L1
+		}
+		if x == 1 {
+			continue L1
+		}
+		goto L1
+	}
+
+L2:
+	select {
+	default:
+		if x == 0 {
+			break L2
+		}
+		if x == 1 {
+			continue L2 /* ERROR "invalid continue label L2" */
+		}
+		goto L2
+	}
+
+L3:
+	switch {
+	case x > 10:
+		if x == 11 {
+			break L3
+		}
+		if x == 12 {
+			continue L3 /* ERROR "invalid continue label L3" */
+		}
+		goto L3
+	}
+
+L4:
+	if true {
+		if x == 13 {
+			break L4 /* ERROR "invalid break label L4" */
+		}
+		if x == 14 {
+			continue L4 /* ERROR "invalid continue label L4" */
+		}
+		if x == 15 {
+			goto L4
+		}
+	}
+
+L5:
+	f1()
+	if x == 16 {
+		break L5 /* ERROR "invalid break label L5" */
+	}
+	if x == 17 {
+		continue L5 /* ERROR "invalid continue label L5" */
+	}
+	if x == 18 {
+		goto L5
+	}
+
+	for {
+		if x == 19 {
+			break L1 /* ERROR "invalid break label L1" */
+		}
+		if x == 20 {
+			continue L1 /* ERROR "invalid continue label L1" */
+		}
+		if x == 21 {
+			goto L1
+		}
+	}
+}
+
+// Additional tests not in the original files.
+
+func f2() {
+L1 /* ERROR "label L1 declared and not used" */ :
+	if x == 0 {
+		for {
+			continue L1 /* ERROR "invalid continue label L1" */
+		}
+	}
+}
+
+func f3() {
+L1:
+L2:
+L3:
+	for {
+		break L1 /* ERROR "invalid break label L1" */
+		break L2 /* ERROR "invalid break label L2" */
+		break L3
+		continue L1 /* ERROR "invalid continue label L1" */
+		continue L2 /* ERROR "invalid continue label L2" */
+		continue L3
+		goto L1
+		goto L2
+		goto L3
+	}
+}
+
+// Blank labels are never declared.
+
+func f4() {
+_:
+_: // multiple blank labels are ok
+	goto _ /* ERROR "label _ not declared" */
+}
+
+func f5() {
+_:
+	for {
+		break _ /* ERROR "invalid break label _" */
+		continue _ /* ERROR "invalid continue label _" */
+	}
+}
+
+func f6() {
+_:
+	switch {
+	default:
+		break _ /* ERROR "invalid break label _" */
+	}
+}
diff --git a/src/go/types/testdata/check/linalg.go b/src/internal/types/testdata/check/linalg.go
similarity index 100%
rename from src/go/types/testdata/check/linalg.go
rename to src/internal/types/testdata/check/linalg.go
diff --git a/src/go/types/testdata/check/literals.go b/src/internal/types/testdata/check/literals.go
similarity index 100%
rename from src/go/types/testdata/check/literals.go
rename to src/internal/types/testdata/check/literals.go
diff --git a/src/internal/types/testdata/check/main0.go b/src/internal/types/testdata/check/main0.go
new file mode 100644
index 0000000..132a5fe
--- /dev/null
+++ b/src/internal/types/testdata/check/main0.go
@@ -0,0 +1,9 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func main()
+func main /* ERROR "no arguments and no return values" */ /* ERROR redeclared */ (int)
+func main /* ERROR "no arguments and no return values" */ /* ERROR redeclared */ () int
diff --git a/src/go/types/testdata/check/main1.go b/src/internal/types/testdata/check/main1.go
similarity index 100%
rename from src/go/types/testdata/check/main1.go
rename to src/internal/types/testdata/check/main1.go
diff --git a/src/go/types/testdata/check/map0.go b/src/internal/types/testdata/check/map0.go
similarity index 100%
rename from src/go/types/testdata/check/map0.go
rename to src/internal/types/testdata/check/map0.go
diff --git a/src/go/types/testdata/check/map1.go b/src/internal/types/testdata/check/map1.go
similarity index 100%
rename from src/go/types/testdata/check/map1.go
rename to src/internal/types/testdata/check/map1.go
diff --git a/src/internal/types/testdata/check/methodsets.go b/src/internal/types/testdata/check/methodsets.go
new file mode 100644
index 0000000..d145bc0
--- /dev/null
+++ b/src/internal/types/testdata/check/methodsets.go
@@ -0,0 +1,214 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package methodsets
+
+type T0 struct {}
+
+func (T0) v0() {}
+func (*T0) p0() {}
+
+type T1 struct {} // like T0 with different method names
+
+func (T1) v1() {}
+func (*T1) p1() {}
+
+type T2 interface {
+	v2()
+	p2()
+}
+
+type T3 struct {
+	T0
+	*T1
+	T2
+}
+
+// Method expressions
+func _() {
+	var (
+		_ func(T0) = T0.v0
+		_ = T0.p0 /* ERROR invalid method expression T0\.p0 \(needs pointer receiver \(\*T0\)\.p0\) */
+
+		_ func (*T0) = (*T0).v0
+		_ func (*T0) = (*T0).p0
+
+		// T1 is like T0
+
+		_ func(T2) = T2.v2
+		_ func(T2) = T2.p2
+
+		_ func(T3) = T3.v0
+		_ func(T3) = T3.p0 /* ERROR invalid method expression T3\.p0 \(needs pointer receiver \(\*T3\)\.p0\) */
+		_ func(T3) = T3.v1
+		_ func(T3) = T3.p1
+		_ func(T3) = T3.v2
+		_ func(T3) = T3.p2
+
+		_ func(*T3) = (*T3).v0
+		_ func(*T3) = (*T3).p0
+		_ func(*T3) = (*T3).v1
+		_ func(*T3) = (*T3).p1
+		_ func(*T3) = (*T3).v2
+		_ func(*T3) = (*T3).p2
+	)
+}
+
+// Method values with addressable receivers
+func _() {
+	var (
+		v0 T0
+		_ func() = v0.v0
+		_ func() = v0.p0
+	)
+
+	var (
+		p0 *T0
+		_ func() = p0.v0
+		_ func() = p0.p0
+	)
+
+	// T1 is like T0
+
+	var (
+		v2 T2
+		_ func() = v2.v2
+		_ func() = v2.p2
+	)
+
+	var (
+		v4 T3
+		_ func() = v4.v0
+		_ func() = v4.p0
+		_ func() = v4.v1
+		_ func() = v4.p1
+		_ func() = v4.v2
+		_ func() = v4.p2
+	)
+
+	var (
+		p4 *T3
+		_ func() = p4.v0
+		_ func() = p4.p0
+		_ func() = p4.v1
+		_ func() = p4.p1
+		_ func() = p4.v2
+		_ func() = p4.p2
+	)
+}
+
+// Method calls with addressable receivers
+func _() {
+	var v0 T0
+	v0.v0()
+	v0.p0()
+
+	var p0 *T0
+	p0.v0()
+	p0.p0()
+
+	// T1 is like T0
+
+	var v2 T2
+	v2.v2()
+	v2.p2()
+
+	var v4 T3
+	v4.v0()
+	v4.p0()
+	v4.v1()
+	v4.p1()
+	v4.v2()
+	v4.p2()
+
+	var p4 *T3
+	p4.v0()
+	p4.p0()
+	p4.v1()
+	p4.p1()
+	p4.v2()
+	p4.p2()
+}
+
+// Method values with value receivers
+func _() {
+	var (
+		_ func() = T0{}.v0
+		_ func() = T0{}.p0 /* ERROR "cannot call pointer method p0 on T0" */
+
+		_ func() = (&T0{}).v0
+		_ func() = (&T0{}).p0
+
+		// T1 is like T0
+
+		// no values for T2
+
+		_ func() = T3{}.v0
+		_ func() = T3{}.p0 /* ERROR "cannot call pointer method p0 on T3" */
+		_ func() = T3{}.v1
+		_ func() = T3{}.p1
+		_ func() = T3{}.v2
+		_ func() = T3{}.p2
+
+		_ func() = (&T3{}).v0
+		_ func() = (&T3{}).p0
+		_ func() = (&T3{}).v1
+		_ func() = (&T3{}).p1
+		_ func() = (&T3{}).v2
+		_ func() = (&T3{}).p2
+	)
+}
+
+// Method calls with value receivers
+func _() {
+	T0{}.v0()
+	T0{}.p0 /* ERROR "cannot call pointer method p0 on T0" */ ()
+
+	(&T0{}).v0()
+	(&T0{}).p0()
+
+	// T1 is like T0
+
+	// no values for T2
+
+	T3{}.v0()
+	T3{}.p0 /* ERROR "cannot call pointer method p0 on T3" */ ()
+	T3{}.v1()
+	T3{}.p1()
+	T3{}.v2()
+	T3{}.p2()
+
+	(&T3{}).v0()
+	(&T3{}).p0()
+	(&T3{}).v1()
+	(&T3{}).p1()
+	(&T3{}).v2()
+	(&T3{}).p2()
+}
+
+// *T has no methods if T is an interface type
+func issue5918() {
+	var (
+		err error
+		_ = err.Error()
+		_ func() string = err.Error
+		_ func(error) string = error.Error
+
+		perr = &err
+		_ = perr.Error /* ERROR "type \*error is pointer to interface, not interface" */ ()
+		_ func() string = perr.Error /* ERROR "type \*error is pointer to interface, not interface" */
+		_ func(*error) string = (*error).Error /* ERROR "type \*error is pointer to interface, not interface" */
+	)
+
+	type T *interface{ m() int }
+	var (
+		x T
+		_ = (*x).m()
+		_ = (*x).m
+
+		_ = x.m /* ERROR "type T is pointer to interface, not interface" */ ()
+		_ = x.m /* ERROR "type T is pointer to interface, not interface" */
+		_ = T.m /* ERROR "type T is pointer to interface, not interface" */
+	)
+}
diff --git a/src/internal/types/testdata/check/shifts.go b/src/internal/types/testdata/check/shifts.go
new file mode 100644
index 0000000..5cd0182
--- /dev/null
+++ b/src/internal/types/testdata/check/shifts.go
@@ -0,0 +1,399 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package shifts
+
+func shifts0() {
+	// basic constant shifts
+	const (
+		s = 10
+		_ = 0<<0
+		_ = 1<<s
+		_ = 1<<- /* ERROR "negative shift count" */ 1
+		// For the test below we may decide to convert to int
+		// rather than uint and then report a negative shift
+		// count instead, which might be a better error. The
+		// (minor) difference is that this would restrict the
+		// shift count range by half (from all uint values to
+		// the positive int values).
+		// This depends on the exact spec wording which is not
+		// done yet.
+		// TODO(gri) revisit and adjust when spec change is done
+		_ = 1<<- /* ERROR "negative shift count" */ 1.0
+		_ = 1<<1075 /* ERROR "invalid shift" */
+		_ = 2.0<<1
+		_ = 1<<1.0
+		_ = 1<<(1+0i)
+
+		_ int = 2<<s
+		_ float32 = 2<<s
+		_ complex64 = 2<<s
+
+		_ int = 2.0<<s
+		_ float32 = 2.0<<s
+		_ complex64 = 2.0<<s
+
+		_ int = 'a'<<s
+		_ float32 = 'a'<<s
+		_ complex64 = 'a'<<s
+	)
+}
+
+func shifts1() {
+	// basic non-constant shifts
+	var (
+		i int
+		u uint
+
+		_ = 1<<0
+		_ = 1<<i
+		_ = 1<<u
+		_ = 1<<"foo" /* ERROR "cannot convert" */
+		_ = i<<0
+		_ = i<<- /* ERROR "negative shift count" */ 1
+		_ = i<<1.0
+		_ = 1<<(1+0i)
+		_ = 1 /* ERROR "overflows" */ <<100
+
+		_ uint = 1 << 0
+		_ uint = 1 << u
+		_ float32 = 1 /* ERROR "must be integer" */ << u
+
+		// issue #14822
+		_ = 1<<( /* ERROR "overflows uint" */ 1<<64)
+		_ = 1<<( /* ERROR "invalid shift count" */ 1<<64-1)
+
+		// issue #43697
+		_ = u<<( /* ERROR "overflows uint" */ 1<<64)
+		_ = u<<(1<<64-1)
+	)
+}
+
+func shifts2() {
+	// from the spec
+	var (
+		s uint = 33
+		i = 1<<s           // 1 has type int
+		j int32 = 1<<s     // 1 has type int32; j == 0
+		k = uint64(1<<s)   // 1 has type uint64; k == 1<<33
+		m int = 1.0<<s     // 1.0 has type int
+		n = 1.0<<s != i    // 1.0 has type int; n == false if ints are 32bits in size
+		o = 1<<s == 2<<s   // 1 and 2 have type int; o == true if ints are 32bits in size
+		p = 1<<s == 1<<33  // illegal if ints are 32bits in size: 1 has type int, but 1<<33 overflows int
+		u = 1.0 /* ERROR "must be integer" */ <<s         // illegal: 1.0 has type float64, cannot shift
+		u1 = 1.0 /* ERROR "must be integer" */ <<s != 0   // illegal: 1.0 has type float64, cannot shift
+		u2 = 1 /* ERROR "must be integer" */ <<s != 1.0   // illegal: 1 has type float64, cannot shift
+		v float32 = 1 /* ERROR "must be integer" */ <<s   // illegal: 1 has type float32, cannot shift
+		w int64 = 1.0<<33  // 1.0<<33 is a constant shift expression
+	)
+	_, _, _, _, _, _, _, _, _, _, _, _ = i, j, k, m, n, o, p, u, u1, u2, v, w
+}
+
+func shifts3(a int16, b float32) {
+	// random tests
+	var (
+		s uint = 11
+		u = 1 /* ERROR "must be integer" */ <<s + 1.0
+		v complex128 = 1 /* ERROR "must be integer" */ << s + 1.0 /* ERROR "must be integer" */ << s + 1
+	)
+	x := 1.0 /* ERROR "must be integer" */ <<s + 1
+	shifts3(1.0 << s, 1 /* ERROR "must be integer" */ >> s)
+	_, _, _ = u, v, x
+}
+
+func shifts4() {
+	// shifts in comparisons w/ untyped operands
+	var s uint
+
+	_ = 1<<s == 1
+	_ = 1 /* ERROR "integer" */ <<s == 1.
+	_ = 1. /* ERROR "integer" */ <<s == 1
+	_ = 1. /* ERROR "integer" */ <<s == 1.
+
+	_ = 1<<s + 1 == 1
+	_ = 1 /* ERROR "integer" */ <<s + 1 == 1.
+	_ = 1 /* ERROR "integer" */ <<s + 1. == 1
+	_ = 1 /* ERROR "integer" */ <<s + 1. == 1.
+	_ = 1. /* ERROR "integer" */ <<s + 1 == 1
+	_ = 1. /* ERROR "integer" */ <<s + 1 == 1.
+	_ = 1. /* ERROR "integer" */ <<s + 1. == 1
+	_ = 1. /* ERROR "integer" */ <<s + 1. == 1.
+
+	_ = 1<<s == 1<<s
+	_ = 1 /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s
+	_ = 1. /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s
+	_ = 1. /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s
+
+	_ = 1<<s + 1<<s == 1
+	_ = 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1.
+	_ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1
+	_ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1.
+	_ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1
+	_ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1.
+	_ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1
+	_ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1.
+
+	_ = 1<<s + 1<<s == 1<<s + 1<<s
+	_ = 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
+	_ = 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
+	_ = 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
+	_ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
+	_ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
+	_ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
+	_ = 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
+	_ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
+	_ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
+	_ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
+	_ = 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
+	_ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
+	_ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1 /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
+	_ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1 /* ERROR "integer" */ <<s
+	_ = 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s == 1. /* ERROR "integer" */ <<s + 1. /* ERROR "integer" */ <<s
+}
+
+func shifts5() {
+	// shifts in comparisons w/ typed operands
+	var s uint
+	var x int
+
+	_ = 1<<s == x
+	_ = 1.<<s == x
+	_ = 1.1 /* ERROR "int" */ <<s == x
+
+	_ = 1<<s + x == 1
+	_ = 1<<s + x == 1.
+	_ = 1<<s + x == 1.1 /* ERROR "int" */
+	_ = 1.<<s + x == 1
+	_ = 1.<<s + x == 1.
+	_ = 1.<<s + x == 1.1 /* ERROR "int" */
+	_ = 1.1 /* ERROR "int" */ <<s + x == 1
+	_ = 1.1 /* ERROR "int" */ <<s + x == 1.
+	_ = 1.1 /* ERROR "int" */ <<s + x == 1.1
+
+	_ = 1<<s == x<<s
+	_ = 1.<<s == x<<s
+	_ = 1.1  /* ERROR "int" */ <<s == x<<s
+}
+
+func shifts6() {
+	// shifts as operands in non-arithmetic operations and as arguments
+	var a [10]int
+	var s uint
+
+	_ = a[1<<s]
+	_ = a[1.0]
+	_ = a[1.0<<s]
+
+	_ = make([]int, 1.0)
+	_ = make([]int, 1.0<<s)
+	_ = make([]int, 1.1 /* ERROR "must be integer" */ <<s)
+
+	_ = float32(1)
+	_ = float32(1 /* ERROR "must be integer" */ <<s)
+	_ = float32(1.0)
+	_ = float32(1.0 /* ERROR "must be integer" */ <<s)
+	_ = float32(1.1 /* ERROR "must be integer" */ <<s)
+
+	// TODO(gri) Re-enable these tests once types2 has the go/types fixes.
+	//           Issue #52080.
+	// _ = int32(0x80000000 /* ERROR "overflows int32" */ << s)
+	// TODO(rfindley) Eliminate the redundant error here.
+	// _ = int32(( /* ERROR "truncated to int32" */ 0x80000000 /* ERROR "truncated to int32" */ + 0i) << s)
+
+	_ = int(1+0i<<0)
+	// _ = int((1+0i)<<s)
+	// _ = int(1.0<<s)
+	// _ = int(complex(1, 0)<<s)
+	_ = int(float32/* ERROR "must be integer" */(1.0) <<s)
+	_ = int(1.1 /* ERROR must be integer */ <<s)
+	_ = int(( /* ERROR "must be integer" */ 1+1i)  <<s)
+
+	_ = complex(1 /* ERROR "must be integer" */ <<s, 0)
+
+	var b []int
+	_ = append(b, 1<<s)
+	_ = append(b, 1.0<<s)
+	_ = append(b, (1+0i)<<s)
+	_ = append(b, 1.1 /* ERROR "must be integer" */ <<s)
+	_ = append(b, (1 + 0i) <<s)
+	_ = append(b, ( /* ERROR "must be integer" */ 1 + 1i)  <<s)
+
+	_ = complex(1.0 /* ERROR "must be integer" */ <<s, 0)
+	_ = complex(1.1 /* ERROR "must be integer" */ <<s, 0)
+	_ = complex(0, 1.0 /* ERROR "must be integer" */ <<s)
+	_ = complex(0, 1.1 /* ERROR "must be integer" */ <<s)
+
+	// TODO(gri) The delete below is not type-checked correctly yet.
+	// var m1 map[int]string
+	// delete(m1, 1<<s)
+}
+
+func shifts7() {
+	// shifts of shifts
+	var s uint
+	var x int
+	_ = x
+
+	_ = 1<<(1<<s)
+	_ = 1<<(1.<<s)
+	_ = 1. /* ERROR "integer" */ <<(1<<s)
+	_ = 1. /* ERROR "integer" */ <<(1.<<s)
+
+	x = 1<<(1<<s)
+	x = 1<<(1.<<s)
+	x = 1.<<(1<<s)
+	x = 1.<<(1.<<s)
+
+	_ = (1<<s)<<(1<<s)
+	_ = (1<<s)<<(1.<<s)
+	_ = ( /* ERROR "integer" */ 1.<<s)<<(1<<s)
+	_ = ( /* ERROR "integer" */ 1.<<s)<<(1.<<s)
+
+	x = (1<<s)<<(1<<s)
+	x = (1<<s)<<(1.<<s)
+	x = ( /* ERROR "integer" */ 1.<<s)<<(1<<s)
+	x = ( /* ERROR "integer" */ 1.<<s)<<(1.<<s)
+}
+
+func shifts8() {
+	// shift examples from shift discussion: better error messages
+	var s uint
+	_ = 1.0 /* ERROR "shifted operand 1.0 \(type float64\) must be integer" */ <<s == 1
+	_ = 1.0 /* ERROR "shifted operand 1.0 \(type float64\) must be integer" */ <<s == 1.0
+	_ = 1 /* ERROR "shifted operand 1 \(type float64\) must be integer" */ <<s == 1.0
+	_ = 1 /* ERROR "shifted operand 1 \(type float64\) must be integer" */ <<s + 1.0 == 1
+	_ = 1 /* ERROR "shifted operand 1 \(type float64\) must be integer" */ <<s + 1.1 == 1
+	_ = 1 /* ERROR "shifted operand 1 \(type float64\) must be integer" */ <<s + 1 == 1.0
+
+	// additional cases
+	_ = complex(1.0 /* ERROR "shifted operand 1.0 \(type float64\) must be integer" */ <<s, 1)
+	_ = complex(1.0, 1 /* ERROR "shifted operand 1 \(type float64\) must be integer" */ <<s)
+
+	_ = int(1.<<s)
+	_ = int(1.1 /* ERROR "shifted operand .* must be integer" */ <<s)
+	_ = float32(1 /* ERROR "shifted operand .* must be integer" */ <<s)
+	_ = float32(1. /* ERROR "shifted operand .* must be integer" */ <<s)
+	_ = float32(1.1 /* ERROR "shifted operand .* must be integer" */ <<s)
+	// TODO(gri) the error messages for these two are incorrect - disabled for now
+	// _ = complex64(1<<s)
+	// _ = complex64(1.<<s)
+	_ = complex64(1.1 /* ERROR "shifted operand .* must be integer" */ <<s)
+}
+
+func shifts9() {
+	// various originally failing snippets of code from the std library
+	// from src/compress/lzw/reader.go:90
+	{
+		var d struct {
+			bits     uint32
+			width    uint
+		}
+		_ = uint16(d.bits & (1<<d.width - 1))
+	}
+
+	// from src/debug/dwarf/buf.go:116
+	{
+		var ux uint64
+		var bits uint
+		x := int64(ux)
+		if x&(1<<(bits-1)) != 0 {}
+	}
+
+	// from src/encoding/asn1/asn1.go:160
+	{
+		var bytes []byte
+		if bytes[len(bytes)-1]&((1<<bytes[0])-1) != 0 {}
+	}
+
+	// from src/math/big/rat.go:140
+	{
+		var exp int
+		var mantissa uint64
+		shift := uint64(-1022 - (exp - 1)) // [1..53)
+		_ = mantissa & (1<<shift - 1)
+	}
+
+	// from src/net/interface.go:51
+	{
+		type Flags uint
+		var f Flags
+		var i int
+		if f&(1<<uint(i)) != 0 {}
+	}
+
+	// from src/runtime/softfloat64.go:234
+	{
+		var gm uint64
+		var shift uint
+		_ = gm & (1<<shift - 1)
+	}
+
+	// from src/strconv/atof.go:326
+	{
+		var mant uint64
+		var mantbits uint
+		if mant == 2<<mantbits {}
+	}
+
+	// from src/route_bsd.go:82
+	{
+		var Addrs int32
+		const rtaRtMask = 1
+		var i uint
+		if Addrs&rtaRtMask&(1<<i) == 0 {}
+	}
+
+	// from src/text/scanner/scanner.go:540
+	{
+		var s struct { Whitespace uint64 }
+		var ch rune
+		for s.Whitespace&(1<<uint(ch)) != 0 {}
+	}
+}
+
+func issue5895() {
+	var x = 'a' << 1 // type of x must be rune
+	var _ rune = x
+}
+
+func issue11325() {
+	var _ = 0 >> 1.1 /* ERROR "truncated to uint" */ // example from issue 11325
+	_ = 0 >> 1.1 /* ERROR "truncated to uint" */
+	_ = 0 << 1.1 /* ERROR "truncated to uint" */
+	_ = 0 >> 1.
+	_ = 1 >> 1.1 /* ERROR "truncated to uint" */
+	_ = 1 >> 1.
+	_ = 1. >> 1
+	_ = 1. >> 1.
+	_ = 1.1 /* ERROR "must be integer" */ >> 1
+}
+
+func issue11594() {
+	var _ = complex64 /* ERROR "must be integer" */ (1) << 2 // example from issue 11594
+	_ = float32 /* ERROR "must be integer" */ (0) << 1
+	_ = float64 /* ERROR "must be integer" */ (0) >> 2
+	_ = complex64 /* ERROR "must be integer" */ (0) << 3
+	_ = complex64 /* ERROR "must be integer" */ (0) >> 4
+}
+
+func issue21727() {
+	var s uint
+	var a = make([]int, 1<<s + 1.2 /* ERROR "truncated to int" */ )
+	var _ = a[1<<s - 2.3 /* ERROR "truncated to int" */ ]
+	var _ int = 1<<s + 3.4 /* ERROR "truncated to int" */
+	var _ = string(1 /* ERROR shifted operand 1 .* must be integer */ << s)
+	var _ = string(1.0 /* ERROR "cannot convert" */ << s)
+}
+
+func issue22969() {
+	var s uint
+	var a []byte
+	_ = a[0xffffffffffffffff /* ERROR "overflows int" */ <<s] // example from issue 22969
+	_ = make([]int, 0xffffffffffffffff /* ERROR "overflows int" */ << s)
+	_ = make([]int, 0, 0xffffffffffffffff /* ERROR "overflows int" */ << s)
+	var _ byte = 0x100 /* ERROR "overflows byte" */ << s
+	var _ int8 = 0xff /* ERROR "overflows int8" */ << s
+	var _ int16 = 0xffff /* ERROR "overflows int16" */ << s
+	var _ int32 = 0x80000000 /* ERROR "overflows int32" */ << s
+}
diff --git a/src/go/types/testdata/check/slices.go b/src/internal/types/testdata/check/slices.go
similarity index 100%
rename from src/go/types/testdata/check/slices.go
rename to src/internal/types/testdata/check/slices.go
diff --git a/src/internal/types/testdata/check/stmt0.go b/src/internal/types/testdata/check/stmt0.go
new file mode 100644
index 0000000..c456aac
--- /dev/null
+++ b/src/internal/types/testdata/check/stmt0.go
@@ -0,0 +1,994 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// statements
+
+package stmt0
+
+func assignments0() (int, int) {
+	var a, b, c int
+	var ch chan int
+	f0 := func() {}
+	f1 := func() int { return 1 }
+	f2 := func() (int, int) { return 1, 2 }
+	f3 := func() (int, int, int) { return 1, 2, 3 }
+
+	a, b, c = 1, 2, 3
+	a, b, c = 1 /* ERROR "assignment mismatch: 3 variables but 2 values" */ , 2
+	a, b, c = 1 /* ERROR "assignment mismatch: 3 variables but 4 values" */ , 2, 3, 4
+	_, _, _ = a, b, c
+
+	a = f0 /* ERROR "used as value" */ ()
+	a = f1()
+	a = f2 /* ERROR "assignment mismatch: 1 variable but f2 returns 2 values" */ ()
+	a, b = f2()
+	a, b, c = f2 /* ERROR "assignment mismatch: 3 variables but f2 returns 2 values" */ ()
+	a, b, c = f3()
+	a, b = f3 /* ERROR "assignment mismatch: 2 variables but f3 returns 3 values" */ ()
+
+	a, b, c = <- /* ERROR "assignment mismatch: 3 variables but 1 value" */ ch
+
+	return /* ERROR "not enough return values\n\thave \(\)\n\twant \(int, int\)" */
+	return 1 /* ERROR "not enough return values\n\thave \(number\)\n\twant \(int, int\)" */
+	return 1, 2
+	return 1, 2, 3 /* ERROR "too many return values\n\thave \(number, number, number\)\n\twant \(int, int\)" */
+}
+
+func assignments1() {
+	b, i, f, c, s := false, 1, 1.0, 1i, "foo"
+	b = i /* ERROR "cannot use .* in assignment" */
+	i = f /* ERROR "cannot use .* in assignment" */
+	f = c /* ERROR "cannot use .* in assignment" */
+	c = s /* ERROR "cannot use .* in assignment" */
+	s = b /* ERROR "cannot use .* in assignment" */
+
+	v0, v1, v2 := 1 /* ERROR "assignment mismatch" */ , 2, 3, 4
+	_, _, _ = v0, v1, v2
+
+	b = true
+
+	i += 1
+	i /* ERROR "mismatched types int and untyped string" */+= "foo"
+
+	f -= 1
+	f /= 0
+	f = float32(0)/0 /* ERROR "division by zero" */
+	f /* ERROR "mismatched types float64 and untyped string" */-= "foo"
+
+	c *= 1
+	c /= 0
+
+	s += "bar"
+	s /* ERROR "mismatched types string and untyped int" */+= 1
+
+	var u64 uint64
+	u64 += 1<<u64
+
+	undefined /* ERROR "undefined" */ = 991
+
+	// test cases for issue 5800
+	var (
+		_ int = nil /* ERROR "cannot use nil as int value in variable declaration" */
+		_ [10]int = nil /* ERROR "cannot use nil as \[10\]int value in variable declaration" */
+		_ []byte = nil
+		_ struct{} = nil /* ERROR "cannot use nil as struct{} value in variable declaration" */
+		_ func() = nil
+		_ map[int]string = nil
+		_ chan int = nil
+	)
+
+	// test cases for issue 5500
+	_ = func() (int, bool) {
+		var m map[int]int
+		return m /* ERROR "not enough return values" */ [0]
+	}
+
+	g := func(int, bool){}
+	var m map[int]int
+	g(m[0]) /* ERROR "not enough arguments" */
+
+	// assignments to _
+	_ = nil /* ERROR "use of untyped nil" */
+	_ = 1  << /* ERROR constant shift overflow */ 1000
+	(_) = 0
+}
+
+func assignments2() {
+	type mybool bool
+	var m map[string][]bool
+	var s []bool
+	var b bool
+	var d mybool
+	_ = s
+	_ = b
+	_ = d
+
+	// assignments to map index expressions are ok
+	s, b = m["foo"]
+	_, d = m["bar"]
+	m["foo"] = nil
+	m["foo"] = nil /* ERROR assignment mismatch: 1 variable but 2 values */ , false
+	_ = append(m["foo"])
+	_ = append(m["foo"], true)
+
+	var c chan int
+	_, b = <-c
+	_, d = <-c
+	<- /* ERROR cannot assign */ c = 0
+	<-c = 0 /* ERROR assignment mismatch: 1 variable but 2 values */ , false
+
+	var x interface{}
+	_, b = x.(int)
+	x /* ERROR cannot assign */ .(int) = 0
+	x.(int) = 0 /* ERROR assignment mismatch: 1 variable but 2 values */ , false
+
+	assignments2 /* ERROR used as value */ () = nil
+	int /* ERROR not an expression */ = 0
+}
+
+func issue6487() {
+	type S struct{x int}
+	_ = &S /* ERROR "cannot take address" */ {}.x
+	_ = &( /* ERROR "cannot take address" */ S{}.x)
+	_ = (&S{}).x
+	S /* ERROR "cannot assign" */ {}.x = 0
+	(&S{}).x = 0
+
+	type M map[string]S
+	var m M
+	m /* ERROR "cannot assign to struct field" */ ["foo"].x = 0
+	_ = &( /* ERROR "cannot take address" */ m["foo"].x)
+	_ = &m /* ERROR "cannot take address" */ ["foo"].x
+}
+
+func issue6766a() {
+	a, a /* ERROR a repeated on left side of := */ := 1, 2
+	_ = a
+	a, b, b /* ERROR b repeated on left side of := */ := 1, 2, 3
+	_ = b
+	c, c /* ERROR c repeated on left side of := */, b := 1, 2, 3
+	_ = c
+	a, b := /* ERROR no new variables */ 1, 2
+}
+
+func shortVarDecls1() {
+	const c = 0
+	type d int
+	a, b, c /* ERROR "cannot assign" */ , d /* ERROR "cannot assign" */  := 1, "zwei", 3.0, 4
+	var _ int = a // a is of type int
+	var _ string = b // b is of type string
+}
+
+func incdecs() {
+	const c = 3.14
+	c /* ERROR "cannot assign" */ ++
+	s := "foo"
+	s /* ERROR "invalid operation" */ --
+	3.14 /* ERROR "cannot assign" */ ++
+	var (
+		x int
+		y float32
+		z complex128
+	)
+	x++
+	y--
+	z++
+}
+
+func sends() {
+	var ch chan int
+	var rch <-chan int
+	var x int
+	x <- /* ERROR "cannot send" */ x
+	rch <- /* ERROR "cannot send" */ x
+	ch <- "foo" /* ERROR "cannot use .* in send" */
+	ch <- x
+}
+
+func selects() {
+	select {}
+	var (
+		ch chan int
+		sc chan <- bool
+	)
+	select {
+	case <-ch:
+	case (<-ch):
+	case t := <-ch:
+		_ = t
+	case t := (<-ch):
+		_ = t
+	case t, ok := <-ch:
+		_, _ = t, ok
+	case t, ok := (<-ch):
+		_, _ = t, ok
+	case <-sc /* ERROR "cannot receive from send-only channel" */ :
+	}
+	select {
+	default:
+	default /* ERROR "multiple defaults" */ :
+	}
+	select {
+	case a, b := <-ch:
+		_, b = a, b
+	case x /* ERROR send or receive */ :
+	case a /* ERROR send or receive */ := ch:
+	}
+
+	// test for issue 9570: ch2 in second case falsely resolved to
+	// ch2 declared in body of first case
+	ch1 := make(chan int)
+	ch2 := make(chan int)
+	select {
+	case <-ch1:
+		var ch2 /* ERROR ch2 declared and not used */ chan bool
+	case i := <-ch2:
+		print(i + 1)
+	}
+}
+
+func gos() {
+	go 1; /* ERROR "must be function call" */
+	go int /* ERROR "go requires function call, not conversion" */ (0)
+	go ( /* ERROR expression in go must not be parenthesized */ gos())
+	go gos()
+	var c chan int
+	go close(c)
+	go len /* ERROR "go discards result" */ (c)
+}
+
+func defers() {
+	defer 1; /* ERROR "must be function call" */
+	defer int /* ERROR "defer requires function call, not conversion" */ (0)
+	defer ( /* ERROR expression in defer must not be parenthesized */ defers())
+	defer defers()
+	var c chan int
+	defer close(c)
+	defer len /* ERROR "defer discards result" */ (c)
+}
+
+func breaks() {
+	var x, y int
+
+	break /* ERROR "break" */
+	{
+		break /* ERROR "break" */
+	}
+	if x < y {
+		break /* ERROR "break" */
+	}
+
+	switch x {
+	case 0:
+		break
+	case 1:
+		if x == y {
+			break
+		}
+	default:
+		break
+		break
+	}
+
+	var z interface{}
+	switch z.(type) {
+	case int:
+		break
+	}
+
+	for {
+		break
+	}
+
+	var a []int
+	for _ = range a {
+		break
+	}
+
+	for {
+		if x == y {
+			break
+		}
+	}
+
+	var ch chan int
+	select {
+	case <-ch:
+		break
+	}
+
+	select {
+	case <-ch:
+		if x == y {
+			break
+		}
+	default:
+		break
+	}
+}
+
+func continues() {
+	var x, y int
+
+	continue /* ERROR "continue" */
+	{
+		continue /* ERROR "continue" */
+	}
+
+	if x < y {
+		continue /* ERROR "continue" */
+	}
+
+	switch x {
+	case 0:
+		continue /* ERROR "continue" */
+	}
+
+	var z interface{}
+	switch z.(type) {
+	case int:
+		continue /* ERROR "continue" */
+	}
+
+	var ch chan int
+	select {
+	case <-ch:
+		continue /* ERROR "continue" */
+	}
+
+	for i := 0; i < 10; i++ {
+		continue
+		if x < y {
+			continue
+			break
+		}
+		switch x {
+		case y:
+			continue
+		default:
+			break
+		}
+		select {
+		case <-ch:
+			continue
+		}
+	}
+
+	var a []int
+	for _ = range a {
+		continue
+		if x < y {
+			continue
+			break
+		}
+		switch x {
+		case y:
+			continue
+		default:
+			break
+		}
+		select {
+		case <-ch:
+			continue
+		}
+	}
+}
+
+func returns0() {
+	return
+	return 0 /* ERROR too many return values */
+}
+
+func returns1(x float64) (int, *float64) {
+	return 0, &x
+	return /* ERROR not enough return values */
+	return "foo" /* ERROR "cannot .* in return statement" */, x /* ERROR "cannot use .* in return statement" */
+	return 0, &x, 1 /* ERROR too many return values */
+}
+
+func returns2() (a, b int) {
+	return
+	return 1, "foo" /* ERROR cannot use .* in return statement */
+	return 1, 2, 3 /* ERROR too many return values */
+	{
+		type a int
+		return 1, 2
+		return /* ERROR a not in scope at return */
+	}
+}
+
+func returns3() (_ int) {
+	return
+	{
+		var _ int // blank (_) identifiers never shadow since they are in no scope
+		return
+	}
+}
+
+func switches0() {
+	var x int
+
+	switch x {
+	}
+
+	switch x {
+	default:
+	default /* ERROR "multiple defaults" */ :
+	}
+
+	switch {
+	case 1  /* ERROR "cannot convert" */ :
+	}
+
+	true := "false"
+	_ = true
+	// A tagless switch is equivalent to the bool
+        // constant true, not the identifier 'true'.
+	switch {
+	case "false" /* ERROR "cannot convert" */:
+	}
+
+	switch int32(x) {
+	case 1, 2:
+	case x /* ERROR "invalid case x in switch on int32\(x\) \(mismatched types int and int32\)" */ :
+	}
+
+	switch x {
+	case 1 /* ERROR "overflows" */ << 100:
+	}
+
+	switch x {
+	case 1:
+	case 1 /* ERROR "duplicate case" */ :
+	case ( /* ERROR "duplicate case" */ 1):
+	case 2, 3, 4:
+	case 5, 1 /* ERROR "duplicate case" */ :
+	}
+
+	switch uint64(x) {
+	case 1<<64 - 1:
+	case 1 /* ERROR duplicate case */ <<64 - 1:
+	case 2, 3, 4:
+	case 5, 1 /* ERROR duplicate case */ <<64 - 1:
+	}
+
+	var y32 float32
+	switch y32 {
+	case 1.1:
+	case 11/10: // integer division!
+	case 11. /* ERROR duplicate case */ /10:
+	case 2, 3.0, 4.1:
+	case 5.2, 1.10 /* ERROR duplicate case */ :
+	}
+
+	var y64 float64
+	switch y64 {
+	case 1.1:
+	case 11/10: // integer division!
+	case 11. /* ERROR duplicate case */ /10:
+	case 2, 3.0, 4.1:
+	case 5.2, 1.10 /* ERROR duplicate case */ :
+	}
+
+	var s string
+	switch s {
+	case "foo":
+	case "foo" /* ERROR duplicate case */ :
+	case "f" /* ERROR duplicate case */ + "oo":
+	case "abc", "def", "ghi":
+	case "jkl", "foo" /* ERROR duplicate case */ :
+	}
+
+	type T int
+	type F float64
+	type S string
+	type B bool
+	var i interface{}
+	switch i {
+	case nil:
+	case nil: // no duplicate detection
+	case (*int)(nil):
+	case (*int)(nil): // do duplicate detection
+	case 1:
+	case byte(1):
+	case int /* ERROR duplicate case */ (1):
+	case T(1):
+	case 1.0:
+	case F(1.0):
+	case F /* ERROR duplicate case */ (1.0):
+	case "hello":
+	case S("hello"):
+	case S /* ERROR duplicate case */ ("hello"):
+	case 1==1, B(false):
+	case false, B(2==2):
+	}
+
+	// switch on array
+	var a [3]int
+	switch a {
+	case [3]int{1, 2, 3}:
+	case [3]int{1, 2, 3}: // no duplicate detection
+	case [ /* ERROR "mismatched types */ 4]int{4, 5, 6}:
+	}
+
+	// switch on channel
+	var c1, c2 chan int
+	switch c1 {
+	case nil:
+	case c1:
+	case c2:
+	case c1, c2: // no duplicate detection
+	}
+}
+
+func switches1() {
+	fallthrough /* ERROR "fallthrough statement out of place" */
+
+	var x int
+	switch x {
+	case 0:
+		fallthrough /* ERROR "fallthrough statement out of place" */
+		break
+	case 1:
+		fallthrough
+	case 2:
+		fallthrough; ; ; // trailing empty statements are ok
+	case 3:
+	default:
+		fallthrough; ;
+	case 4:
+		fallthrough /* ERROR "cannot fallthrough final case in switch" */
+	}
+
+	var y interface{}
+	switch y.(type) {
+	case int:
+		fallthrough /* ERROR "cannot fallthrough in type switch" */ ; ; ;
+	default:
+	}
+
+	switch x {
+	case 0:
+		if x == 0 {
+			fallthrough /* ERROR "fallthrough statement out of place" */
+		}
+	}
+
+	switch x {
+	case 0:
+		goto L1
+		L1: fallthrough; ;
+	case 1:
+		goto L2
+		goto L3
+		goto L4
+		L2: L3: L4: fallthrough
+	default:
+	}
+
+	switch x {
+	case 0:
+		goto L5
+		L5: fallthrough
+	default:
+		goto L6
+		goto L7
+		goto L8
+		L6: L7: L8: fallthrough /* ERROR "cannot fallthrough final case in switch" */
+	}
+
+	switch x {
+	case 0:
+		fallthrough; ;
+	case 1:
+		{
+			fallthrough /* ERROR "fallthrough statement out of place" */
+		}
+	case 2:
+		fallthrough
+	case 3:
+		fallthrough /* ERROR "fallthrough statement out of place" */
+		{ /* empty block is not an empty statement */ }; ;
+	default:
+		fallthrough /* ERROR "cannot fallthrough final case in switch" */
+	}
+
+	switch x {
+	case 0:
+		{
+			fallthrough /* ERROR "fallthrough statement out of place" */
+		}
+	}
+}
+
+func switches2() {
+	// untyped nil is not permitted as switch expression
+	switch nil /* ERROR "use of untyped nil" */ {
+	case 1, 2, "foo": // don't report additional errors here
+	}
+
+	// untyped constants are converted to default types
+	switch 1<<63-1 {
+	}
+	switch 1 /* ERROR "cannot use .* as int value.*\(overflows\)" */ << 63 {
+	}
+	var x int
+	switch 1.0 {
+	case 1.0, 2.0, x /* ERROR "mismatched types int and float64" */ :
+	}
+	switch x {
+	case 1.0:
+	}
+
+	// untyped bools become of type bool
+	type B bool
+	var b B = true
+	switch x == x {
+	case b /* ERROR "mismatched types B and bool" */ :
+	}
+	switch {
+	case b /* ERROR "mismatched types B and bool" */ :
+	}
+}
+
+func issue11667() {
+	switch 9223372036854775808 /* ERROR "cannot use .* as int value.*\(overflows\)" */ {
+	}
+	switch 9223372036854775808 /* ERROR "cannot use .* as int value.*\(overflows\)" */ {
+	case 9223372036854775808:
+	}
+	var x int
+	switch x {
+	case 9223372036854775808 /* ERROR "overflows int" */ :
+	}
+	var y float64
+	switch y {
+	case 9223372036854775808:
+	}
+}
+
+func issue11687() {
+	f := func() (_, _ int) { return }
+	switch f /* ERROR "multiple-value f" */ () {
+	}
+	var x int
+	switch f /* ERROR "multiple-value f" */ () {
+	case x:
+	}
+	switch x {
+	case f /* ERROR "multiple-value f" */ ():
+	}
+}
+
+type I interface {
+	m()
+}
+
+type I2 interface {
+	m(int)
+}
+
+type T struct{}
+type T1 struct{}
+type T2 struct{}
+
+func (T) m() {}
+func (T2) m(int) {}
+
+func typeswitches() {
+	var i int
+	var x interface{}
+
+	switch x.(type) {}
+	switch (x /* ERROR "outside type switch" */ .(type)) {}
+
+	switch x.(type) {
+	default:
+	default /* ERROR "multiple defaults" */ :
+	}
+
+	switch x /* ERROR "declared and not used" */ := x.(type) {}
+	switch _ /* ERROR "no new variable on left side of :=" */ := x.(type) {}
+
+	switch x := x.(type) {
+	case int:
+		var y int = x
+		_ = y
+	}
+
+	switch x /* ERROR "x declared and not used" */ := i /* ERROR "not an interface" */ .(type) {}
+
+	switch t := x.(type) {
+	case nil:
+		var v bool = t /* ERROR "cannot use .* in variable declaration" */
+		_ = v
+	case int:
+		var v int = t
+		_ = v
+	case float32, complex64:
+		var v float32 = t /* ERROR "cannot use .* in variable declaration" */
+		_ = v
+	default:
+		var v float32 = t /* ERROR "cannot use .* in variable declaration" */
+		_ = v
+	}
+
+	var t I
+	switch t.(type) {
+	case T:
+	case T1 /* ERROR "missing method m" */ :
+	case T2 /* ERROR "wrong type for method m" */ :
+	case I2 /* STRICT "wrong type for method m" */ : // only an error in strict mode (issue 8561)
+	}
+
+
+	{
+		x := 1
+		v := 2
+		switch v /* ERROR "v [(]variable of type int[)] is not an interface" */ .(type) {
+		case int:
+			println(x)
+			println(x / 0 /* ERROR "invalid operation: division by zero" */)
+		case 1 /* ERROR "1 is not a type" */:
+		}
+	}
+}
+
+// Test that each case clause uses the correct type of the variable
+// declared by the type switch (issue 5504).
+func typeswitch0() {
+	switch y := interface{}(nil).(type) {
+	case int:
+		func() int { return y + 0 }()
+	case float32:
+		func() float32 { return y }()
+	}
+}
+
+// Test correct scope setup.
+// (no redeclaration errors expected in the type switch)
+func typeswitch1() {
+	var t I
+	switch t := t; t := t.(type) {
+	case nil:
+		var _ I = t
+	case T:
+		var _ T = t
+	default:
+		var _ I = t
+	}
+}
+
+// Test correct typeswitch against interface types.
+type A interface { a() }
+type B interface { b() }
+type C interface { a(int) }
+
+func typeswitch2() {
+	switch A(nil).(type) {
+	case A:
+	case B:
+	case C /* STRICT "cannot have dynamic type" */: // only an error in strict mode (issue 8561)
+	}
+}
+
+func typeswitch3(x interface{}) {
+	switch x.(type) {
+	case int:
+	case float64:
+	case int /* ERROR duplicate case */ :
+	}
+
+	switch x.(type) {
+	case nil:
+	case int:
+	case nil /* ERROR duplicate case */ , nil /* ERROR duplicate case */ :
+	}
+
+	type F func(int)
+	switch x.(type) {
+	case nil:
+	case int, func(int):
+	case float32, func /* ERROR duplicate case */ (x int):
+	case F:
+	}
+}
+
+func fors1() {
+	for {}
+	var i string
+	_ = i
+	for i := 0; i < 10; i++ {}
+	for i := 0; i < 10; j /* ERROR cannot declare */ := 0 {}
+}
+
+func rangeloops1() {
+	var (
+		x int
+		a [10]float32
+		b []string
+		p *[10]complex128
+		pp **[10]complex128
+		s string
+		m map[int]bool
+		c chan int
+		sc chan<- int
+		rc <-chan int
+	)
+
+	for range x /* ERROR "cannot range over" */ {}
+	for _ = range x /* ERROR "cannot range over" */ {}
+	for i := range x /* ERROR "cannot range over" */ {}
+
+	for range a {}
+	for i := range a {
+		var ii int
+		ii = i
+		_ = ii
+	}
+	for i, x := range a {
+		var ii int
+		ii = i
+		_ = ii
+		var xx float64
+		xx = x /* ERROR "cannot use .* in assignment" */
+		_ = xx
+	}
+	var ii int
+	var xx float32
+	for ii, xx = range a {}
+	_, _ = ii, xx
+
+	for range b {}
+	for i := range b {
+		var ii int
+		ii = i
+		_ = ii
+	}
+	for i, x := range b {
+		var ii int
+		ii = i
+		_ = ii
+		var xx string
+		xx = x
+		_ = xx
+	}
+
+	for range s {}
+	for i := range s {
+		var ii int
+		ii = i
+		_ = ii
+	}
+	for i, x := range s {
+		var ii int
+		ii = i
+		_ = ii
+		var xx rune
+		xx = x
+		_ = xx
+	}
+
+	for range p {}
+	for _, x := range p {
+		var xx complex128
+		xx = x
+		_ = xx
+	}
+
+	for range pp /* ERROR "cannot range over" */ {}
+	for _, x := range pp /* ERROR "cannot range over" */ {}
+
+	for range m {}
+	for k := range m {
+		var kk int32
+		kk = k /* ERROR "cannot use .* in assignment" */
+		_ = kk
+	}
+	for k, v := range m {
+		var kk int
+		kk = k
+		_ = kk
+		if v {}
+	}
+
+	for range c {}
+	for _, _ /* ERROR "only one iteration variable" */ = range c {}
+	for e := range c {
+		var ee int
+		ee = e
+		_ = ee
+	}
+	for _ = range sc /* ERROR "cannot range over" */ {}
+	for _ = range rc {}
+
+	// constant strings
+	const cs = "foo"
+	for range cs {}
+	for range "" {}
+	for i, x := range cs { _, _ = i, x }
+	for i, x := range "" {
+		var ii int
+		ii = i
+		_ = ii
+		var xx rune
+		xx = x
+		_ = xx
+	}
+}
+
+func rangeloops2() {
+	type I int
+	type R rune
+
+	var a [10]int
+	var i I
+	_ = i
+	for i /* ERROR cannot use .* in assignment */ = range a {}
+	for i /* ERROR cannot use .* in assignment */ = range &a {}
+	for i /* ERROR cannot use .* in assignment */ = range a[:] {}
+
+	var s string
+	var r R
+	_ = r
+	for i /* ERROR cannot use .* in assignment */ = range s {}
+	for i /* ERROR cannot use .* in assignment */ = range "foo" {}
+	for _, r /* ERROR cannot use .* in assignment */ = range s {}
+	for _, r /* ERROR cannot use .* in assignment */ = range "foo" {}
+}
+
+func issue6766b() {
+	for _ := /* ERROR no new variables */ range "" {}
+	for a, a /* ERROR redeclared */ := range "" { _ = a }
+	var a int
+	_ = a
+	for a, a /* ERROR redeclared */ := range []int{1, 2, 3} { _ = a }
+}
+
+// Test that despite errors in the range clause,
+// the loop body is still type-checked (and thus
+// errors reported).
+func issue10148() {
+	for y /* ERROR declared and not used */ := range "" {
+		_ = "" /* ERROR mismatched types untyped string and untyped int */ + 1
+	}
+	for range 1 /* ERROR cannot range over 1 */ {
+		_ = "" /* ERROR mismatched types untyped string and untyped int */ + 1
+	}
+	for y := range 1 /* ERROR cannot range over 1 */ {
+		_ = "" /* ERROR mismatched types untyped string and untyped int */ + 1
+	}
+}
+
+func labels0() {
+	goto L0
+	goto L1
+	L0:
+	L1:
+	L1 /* ERROR "already declared" */ :
+	if true {
+		goto L2
+		L2:
+		L0 /* ERROR "already declared" */ :
+	}
+	_ = func() {
+		goto L0
+		goto L1
+		goto L2
+		L0:
+		L1:
+		L2:
+	}
+}
+
+func expression_statements(ch chan int) {
+	expression_statements(ch)
+	<-ch
+	println()
+
+	0 /* ERROR "not used" */
+	1 /* ERROR "not used" */ +2
+	cap /* ERROR "not used" */ (ch)
+	println /* ERROR "must be called" */
+}
diff --git a/src/go/types/testdata/check/stmt1.go b/src/internal/types/testdata/check/stmt1.go
similarity index 100%
rename from src/go/types/testdata/check/stmt1.go
rename to src/internal/types/testdata/check/stmt1.go
diff --git a/src/go/types/testdata/check/typeinference.go b/src/internal/types/testdata/check/typeinference.go
similarity index 100%
rename from src/go/types/testdata/check/typeinference.go
rename to src/internal/types/testdata/check/typeinference.go
diff --git a/src/internal/types/testdata/check/typeinst0.go b/src/internal/types/testdata/check/typeinst0.go
new file mode 100644
index 0000000..c21cb53
--- /dev/null
+++ b/src/internal/types/testdata/check/typeinst0.go
@@ -0,0 +1,62 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type myInt int
+
+// Parameterized type declarations
+
+// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
+type T1[P any] P // ERROR cannot use a type parameter as RHS in type declaration
+
+type T2[P any] struct {
+        f P
+        g int // int should still be in scope chain
+}
+
+type List[P any] []P
+
+// Alias type declarations cannot have type parameters.
+// Issue #46477 proposses to change that.
+type A1[P any] = /* ERROR cannot be alias */ struct{}
+
+// Pending clarification of #46477 we disallow aliases
+// of generic types.
+type A2 = List // ERROR cannot use generic type
+var _ A2[int]
+var _ A2
+
+type A3 = List[int]
+var _ A3
+
+// Parameterized type instantiations
+
+var x int
+type _ x /* ERROR not a type */ [int]
+
+type _ int /* ERROR not a generic type */ [] // ERROR expected type argument list
+type _ myInt /* ERROR not a generic type */ [] // ERROR expected type argument list
+
+// TODO(gri) better error messages
+type _ T1[] // ERROR expected type argument list
+type _ T1[x /* ERROR not a type */ ]
+type _ T1 /* ERROR got 2 arguments but 1 type parameters */ [int, float32]
+
+var _ T2[int] = T2[int]{}
+
+var _ List[int] = []int{1, 2, 3}
+var _ List[[]int] = [][]int{{1, 2, 3}}
+var _ List[List[List[int]]]
+
+// Parameterized types containing parameterized types
+
+type T3[P any] List[P]
+
+var _ T3[int] = T3[int](List[int]{1, 2, 3})
+
+// Self-recursive generic types are not permitted
+
+type self1[P any] self1 /* ERROR invalid recursive type */ [P]
+type self2[P any] *self2[P] // this is ok
diff --git a/src/internal/types/testdata/check/typeinst1.go b/src/internal/types/testdata/check/typeinst1.go
new file mode 100644
index 0000000..e7bb247
--- /dev/null
+++ b/src/internal/types/testdata/check/typeinst1.go
@@ -0,0 +1,282 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type List[E any] []E
+var _ List[List[List[int]]]
+var _ List[List[List[int]]] = []List[List[int]]{}
+
+type (
+	T1[P1 any] struct {
+		f1 T2[P1, float32]
+	}
+
+	T2[P2, P3 any] struct {
+		f2 P2
+		f3 P3
+	}
+)
+
+func _() {
+	var x1 T1[int]
+	var x2 T2[int, float32]
+
+	x1.f1.f2 = 0
+	x1.f1 = x2
+}
+
+type T3[P any] T1[T2[P, P]]
+
+func _() {
+	var x1 T3[int]
+	var x2 T2[int, int]
+	x1.f1.f2 = x2
+}
+
+func f[P any] (x P) List[P] {
+	return List[P]{x}
+}
+
+var (
+	_ []int = f(0)
+	_ []float32 = f[float32](10)
+	_ List[complex128] = f(1i)
+	_ []List[int] = f(List[int]{})
+        _ List[List[int]] = []List[int]{}
+        _ = []List[int]{}
+)
+
+// Parameterized types with methods
+
+func (l List[E]) Head() (_ E, _ bool) {
+	if len(l) > 0 {
+		return l[0], true
+	}
+	return
+}
+
+// A test case for instantiating types with other types (extracted from map.go2)
+
+type Pair[K any] struct {
+	key K
+}
+
+type Receiver[T any] struct {
+	values T
+}
+
+type Iterator[K any] struct {
+	r Receiver[Pair[K]]
+}
+
+func Values [T any] (r Receiver[T]) T {
+        return r.values
+}
+
+func (it Iterator[K]) Next() K {
+        return Values[Pair[K]](it.r).key
+}
+
+// A more complex test case testing type bounds (extracted from linalg.go2 and reduced to essence)
+
+type NumericAbs[T any] interface {
+	Abs() T
+}
+
+func AbsDifference[T NumericAbs[T]](x T) { panic(0) }
+
+// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
+// type OrderedAbs[T any] T
+// 
+// func (a OrderedAbs[T]) Abs() OrderedAbs[T]
+// 
+// func OrderedAbsDifference[T any](x T) {
+// 	AbsDifference(OrderedAbs[T](x))
+// }
+
+// same code, reduced to essence
+
+func g[P interface{ m() P }](x P) { panic(0) }
+
+// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
+// type T4[P any] P
+// 
+// func (_ T4[P]) m() T4[P]
+// 
+// func _[Q any](x Q) {
+// 	g(T4[Q](x))
+// }
+
+// Another test case that caused  problems in the past
+
+type T5[_ interface { a() }, _ interface{}] struct{}
+
+type A[P any] struct{ x P }
+
+func (_ A[P]) a() {}
+
+var _ T5[A[int], int]
+
+// Invoking methods with parameterized receiver types uses
+// type inference to determine the actual type arguments matching
+// the receiver type parameters from the actual receiver argument.
+// Go does implicit address-taking and dereferenciation depending
+// on the actual receiver and the method's receiver type. To make
+// type inference work, the type-checker matches "pointer-ness"
+// of the actual receiver and the method's receiver type.
+// The following code tests this mechanism.
+
+type R1[A any] struct{}
+func (_ R1[A]) vm()
+func (_ *R1[A]) pm()
+
+func _[T any](r R1[T], p *R1[T]) {
+	r.vm()
+	r.pm()
+	p.vm()
+	p.pm()
+}
+
+type R2[A, B any] struct{}
+func (_ R2[A, B]) vm()
+func (_ *R2[A, B]) pm()
+
+func _[T any](r R2[T, int], p *R2[string, T]) {
+	r.vm()
+	r.pm()
+	p.vm()
+	p.pm()
+}
+
+// It is ok to have multiple embedded unions.
+type _ interface {
+	m0()
+	~int | ~string | ~bool
+	~float32 | ~float64
+	m1()
+	m2()
+	~complex64 | ~complex128
+	~rune
+}
+
+// Type sets may contain each type at most once.
+type _ interface {
+	~int|~ /* ERROR overlapping terms ~int */ int
+	~int|int /* ERROR overlapping terms int */
+	int|int /* ERROR overlapping terms int */
+}
+
+type _ interface {
+	~struct{f int} | ~struct{g int} | ~ /* ERROR overlapping terms */ struct{f int}
+}
+
+// Interface term lists can contain any type, incl. *Named types.
+// Verify that we use the underlying type(s) of the type(s) in the
+// term list when determining if an operation is permitted.
+
+type MyInt int
+func add1[T interface{MyInt}](x T) T {
+	return x + 1
+}
+
+type MyString string
+func double[T interface{MyInt|MyString}](x T) T {
+	return x + x
+}
+
+// Embedding of interfaces with term lists leads to interfaces
+// with term lists that are the intersection of the embedded
+// term lists.
+
+type E0 interface {
+	~int | ~bool | ~string
+}
+
+type E1 interface {
+	~int | ~float64 | ~string
+}
+
+type E2 interface {
+	~float64
+}
+
+type I0 interface {
+	E0
+}
+
+func f0[T I0]() {}
+var _ = f0[int]
+var _ = f0[bool]
+var _ = f0[string]
+var _ = f0[float64 /* ERROR does not satisfy I0 */ ]
+
+type I01 interface {
+	E0
+	E1
+}
+
+func f01[T I01]() {}
+var _ = f01[int]
+var _ = f01[bool /* ERROR does not satisfy I0 */ ]
+var _ = f01[string]
+var _ = f01[float64 /* ERROR does not satisfy I0 */ ]
+
+type I012 interface {
+	E0
+	E1
+	E2
+}
+
+func f012[T I012]() {}
+var _ = f012[int /* ERROR cannot satisfy I012.*empty type set */ ]
+var _ = f012[bool /* ERROR cannot satisfy I012.*empty type set */ ]
+var _ = f012[string /* ERROR cannot satisfy I012.*empty type set */ ]
+var _ = f012[float64 /* ERROR cannot satisfy I012.*empty type set */ ]
+
+type I12 interface {
+	E1
+	E2
+}
+
+func f12[T I12]() {}
+var _ = f12[int /* ERROR does not satisfy I12 */ ]
+var _ = f12[bool /* ERROR does not satisfy I12 */ ]
+var _ = f12[string /* ERROR does not satisfy I12 */ ]
+var _ = f12[float64]
+
+type I0_ interface {
+	E0
+	~int
+}
+
+func f0_[T I0_]() {}
+var _ = f0_[int]
+var _ = f0_[bool /* ERROR does not satisfy I0_ */ ]
+var _ = f0_[string /* ERROR does not satisfy I0_ */ ]
+var _ = f0_[float64 /* ERROR does not satisfy I0_ */ ]
+
+// Using a function instance as a type is an error.
+var _ f0 // ERROR not a type
+var _ f0 /* ERROR not a type */ [int]
+
+// Empty type sets can only be satisfied by empty type sets.
+type none interface {
+	// force an empty type set
+        int
+        string
+}
+
+func ff[T none]() {}
+func gg[T any]() {}
+func hh[T ~int]() {}
+
+func _[T none]() {
+	_ = ff[int /* ERROR cannot satisfy none \(empty type set\) */ ]
+	_ = ff[T]  // pathological but ok because T's type set is empty, too
+	_ = gg[int]
+	_ = gg[T]
+	_ = hh[int]
+	_ = hh[T]
+}
diff --git a/src/go/types/testdata/check/typeinstcycles.go b/src/internal/types/testdata/check/typeinstcycles.go
similarity index 100%
rename from src/go/types/testdata/check/typeinstcycles.go
rename to src/internal/types/testdata/check/typeinstcycles.go
diff --git a/src/internal/types/testdata/check/typeparams.go b/src/internal/types/testdata/check/typeparams.go
new file mode 100644
index 0000000..0e440d8
--- /dev/null
+++ b/src/internal/types/testdata/check/typeparams.go
@@ -0,0 +1,508 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+// import "io" // for type assertion tests
+
+var _ any // ok to use any anywhere
+func _[_ any, _ interface{any}](any) {
+        var _ any
+}
+
+func identity[T any](x T) T { return x }
+
+func _[_ any](x int) int { panic(0) }
+func _[T any](T /* ERROR redeclared */ T)() {}
+func _[T, T /* ERROR redeclared */ any]() {}
+
+// Constraints (incl. any) may be parenthesized.
+func _[_ (any)]() {}
+func _[_ (interface{})]() {}
+
+func reverse[T any](list []T) []T {
+        rlist := make([]T, len(list))
+        i := len(list)
+        for _, x := range list {
+                i--
+                rlist[i] = x
+        }
+        return rlist
+}
+
+var _ = reverse /* ERROR cannot use generic function reverse */
+var _ = reverse[int, float32 /* ERROR got 2 type arguments */ ] ([]int{1, 2, 3})
+var _ = reverse[int]([ /* ERROR cannot use */ ]float32{1, 2, 3})
+var f = reverse[chan int]
+var _ = f(0 /* ERROR cannot use 0 .* as \[\]chan int */ )
+
+func swap[A, B any](a A, b B) (B, A) { return b, a }
+
+var _ = swap /* ERROR multiple-value */ [int, float32](1, 2)
+var f32, i = swap[int, float32](swap[float32, int](1, 2))
+var _ float32 = f32
+var _ int = i
+
+func swapswap[A, B any](a A, b B) (A, B) {
+        return swap[B, A](b, a)
+}
+
+type F[A, B any] func(A, B) (B, A)
+
+func min[T interface{ ~int }](x, y T) T {
+        if x < y {
+                return x
+        }
+        return y
+}
+
+func _[T interface{~int | ~float32}](x, y T) bool { return x < y }
+func _[T any](x, y T) bool { return x /* ERROR type parameter T is not comparable */ < y }
+func _[T interface{~int | ~float32 | ~bool}](x, y T) bool { return x /* ERROR type parameter T is not comparable */ < y }
+
+func _[T C1[T]](x, y T) bool { return x /* ERROR type parameter T is not comparable */ < y }
+func _[T C2[T]](x, y T) bool { return x < y }
+
+type C1[T any] interface{}
+type C2[T any] interface{ ~int | ~float32 }
+
+func new[T any]() *T {
+        var x T
+        return &x
+}
+
+var _ = new /* ERROR cannot use generic function new */
+var _ *int = new[int]()
+
+func _[T any](map[T /* ERROR invalid map key type T \(missing comparable constraint\) */]int) {} // w/o constraint we don't know if T is comparable
+
+func f1[T1 any](struct{T1 /* ERROR cannot be a .* type parameter */ }) int { panic(0) }
+var _ = f1[int](struct{T1}{})
+type T1 = int
+
+func f2[t1 any](struct{t1 /* ERROR cannot be a .* type parameter */ ; x float32}) int { panic(0) }
+var _ = f2[t1](struct{t1; x float32}{})
+type t1 = int
+
+
+func f3[A, B, C any](A, struct{x B}, func(A, struct{x B}, *C)) int { panic(0) }
+
+var _ = f3[int, rune, bool](1, struct{x rune}{}, nil)
+
+// indexing
+
+func _[T any] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
+func _[T interface{ ~int }] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
+func _[T interface{ ~string }] (x T, i int) { _ = x[i] }
+func _[T interface{ ~[]int }] (x T, i int) { _ = x[i] }
+func _[T interface{ ~[10]int | ~*[20]int | ~map[int]int }] (x T, i int) { _ = x /* ERROR cannot index */ [i] } // map and non-map types
+func _[T interface{ ~string | ~[]byte }] (x T, i int) { _ = x[i] }
+func _[T interface{ ~[]int | ~[1]rune }] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
+func _[T interface{ ~string | ~[]rune }] (x T, i int) { _ = x /* ERROR "cannot index" */ [i] }
+
+// indexing with various combinations of map types in type sets (see issue #42616)
+func _[T interface{ ~[]E | ~map[int]E }, E any](x T, i int) { _ = x /* ERROR cannot index */ [i] } // map and non-map types
+func _[T interface{ ~[]E }, E any](x T, i int) { _ = &x[i] }
+func _[T interface{ ~map[int]E }, E any](x T, i int) { _, _ = x[i] } // comma-ok permitted
+func _[T interface{ ~map[int]E }, E any](x T, i int) { _ = &x /* ERROR cannot take address */ [i] }
+func _[T interface{ ~map[int]E | ~map[uint]E }, E any](x T, i int) { _ = x /* ERROR cannot index */ [i] } // different map element types
+func _[T interface{ ~[]E | ~map[string]E }, E any](x T, i int) { _ = x /* ERROR cannot index */ [i] } // map and non-map types
+
+// indexing with various combinations of array and other types in type sets
+func _[T interface{ [10]int }](x T, i int) { _ = x[i]; _ = x[9]; _ = x[10 /* ERROR out of bounds */ ] }
+func _[T interface{ [10]byte | string }](x T, i int) { _ = x[i]; _ = x[9]; _ = x[10 /* ERROR out of bounds */ ] }
+func _[T interface{ [10]int | *[20]int | []int }](x T, i int) { _ = x[i]; _ = x[9]; _ = x[10 /* ERROR out of bounds */ ] }
+
+// indexing with strings and non-variable arrays (assignment not permitted)
+func _[T string](x T) { _ = x[0]; x /* ERROR cannot assign */ [0] = 0 }
+func _[T []byte | string](x T) { x /* ERROR cannot assign */ [0] = 0 }
+func _[T [10]byte]() { f := func() (x T) { return }; f /* ERROR cannot assign */ ()[0] = 0 }
+func _[T [10]byte]() { f := func() (x *T) { return }; f /* ERROR cannot index */ ()[0] = 0 }
+func _[T [10]byte]() { f := func() (x *T) { return }; (*f())[0] = 0 }
+func _[T *[10]byte]() { f := func() (x T) { return }; f()[0] = 0 }
+
+// slicing
+
+func _[T interface{ ~[10]E }, E any] (x T, i, j, k int) { var _ []E = x[i:j] }
+func _[T interface{ ~[10]E }, E any] (x T, i, j, k int) { var _ []E = x[i:j:k] }
+func _[T interface{ ~[]byte }] (x T, i, j, k int) { var _ T = x[i:j] }
+func _[T interface{ ~[]byte }] (x T, i, j, k int) { var _ T = x[i:j:k] }
+func _[T interface{ ~string }] (x T, i, j, k int) { var _ T = x[i:j] }
+func _[T interface{ ~string }] (x T, i, j, k int) { var _ T = x[i:j:k /* ERROR 3-index slice of string */ ] }
+
+type myByte1 []byte
+type myByte2 []byte
+func _[T interface{ []byte | myByte1 | myByte2 }] (x T, i, j, k int) { var _ T = x[i:j:k] }
+func _[T interface{ []byte | myByte1 | []int }] (x T, i, j, k int) { var _ T = x /* ERROR no core type */ [i:j:k] }
+
+func _[T interface{ []byte | myByte1 | myByte2 | string }] (x T, i, j, k int) { var _ T = x[i:j] }
+func _[T interface{ []byte | myByte1 | myByte2 | string }] (x T, i, j, k int) { var _ T = x[i:j:k /* ERROR 3-index slice of string */ ] }
+func _[T interface{ []byte | myByte1 | []int | string }] (x T, i, j, k int) { var _ T = x /* ERROR no core type */ [i:j] }
+
+// len/cap built-ins
+
+func _[T any](x T) { _ = len(x /* ERROR invalid argument */ ) }
+func _[T interface{ ~int }](x T) { _ = len(x /* ERROR invalid argument */ ) }
+func _[T interface{ ~string | ~[]byte | ~int }](x T) { _ = len(x /* ERROR invalid argument */ ) }
+func _[T interface{ ~string }](x T) { _ = len(x) }
+func _[T interface{ ~[10]int }](x T) { _ = len(x) }
+func _[T interface{ ~[]byte }](x T) { _ = len(x) }
+func _[T interface{ ~map[int]int }](x T) { _ = len(x) }
+func _[T interface{ ~chan int }](x T) { _ = len(x) }
+func _[T interface{ ~string | ~[]byte | ~chan int }](x T) { _ = len(x) }
+
+func _[T any](x T) { _ = cap(x /* ERROR invalid argument */ ) }
+func _[T interface{ ~int }](x T) { _ = cap(x /* ERROR invalid argument */ ) }
+func _[T interface{ ~string | ~[]byte | ~int }](x T) { _ = cap(x /* ERROR invalid argument */ ) }
+func _[T interface{ ~string }](x T) { _ = cap(x /* ERROR invalid argument */ ) }
+func _[T interface{ ~[10]int }](x T) { _ = cap(x) }
+func _[T interface{ ~[]byte }](x T) { _ = cap(x) }
+func _[T interface{ ~map[int]int }](x T) { _ = cap(x /* ERROR invalid argument */ ) }
+func _[T interface{ ~chan int }](x T) { _ = cap(x) }
+func _[T interface{ ~[]byte | ~chan int }](x T) { _ = cap(x) }
+
+// range iteration
+
+func _[T interface{}](x T) {
+        for range x /* ERROR cannot range */ {}
+}
+
+type myString string
+
+func _[
+        B1 interface{ string },
+        B2 interface{ string | myString },
+
+        C1 interface{ chan int },
+        C2 interface{ chan int | <-chan int },
+        C3 interface{ chan<- int },
+
+        S1 interface{ []int },
+        S2 interface{ []int | [10]int },
+
+        A1 interface{ [10]int },
+        A2 interface{ [10]int | []int },
+
+        P1 interface{ *[10]int },
+        P2 interface{ *[10]int | *[]int },
+
+        M1 interface{ map[string]int },
+        M2 interface{ map[string]int | map[string]string },
+]() {
+        var b0 string
+        for range b0 {}
+        for _ = range b0 {}
+        for _, _ = range b0 {}
+
+        var b1 B1
+        for range b1 {}
+        for _ = range b1 {}
+        for _, _ = range b1 {}
+
+        var b2 B2
+        for range b2 {}
+
+        var c0 chan int
+        for range c0 {}
+        for _ = range c0 {}
+        for _, _ /* ERROR permits only one iteration variable */ = range c0 {}
+
+        var c1 C1
+        for range c1 {}
+        for _ = range c1 {}
+        for _, _ /* ERROR permits only one iteration variable */ = range c1 {}
+
+        var c2 C2
+        for range c2 {}
+
+        var c3 C3
+        for range c3 /* ERROR receive from send-only channel */ {}
+
+        var s0 []int
+        for range s0 {}
+        for _ = range s0 {}
+        for _, _ = range s0 {}
+
+        var s1 S1
+        for range s1 {}
+        for _ = range s1 {}
+        for _, _ = range s1 {}
+
+        var s2 S2
+        for range s2 /* ERROR cannot range over s2.*no core type */ {}
+
+        var a0 []int
+        for range a0 {}
+        for _ = range a0 {}
+        for _, _ = range a0 {}
+
+        var a1 A1
+        for range a1 {}
+        for _ = range a1 {}
+        for _, _ = range a1 {}
+
+        var a2 A2
+        for range a2 /* ERROR cannot range over a2.*no core type */ {}
+
+        var p0 *[10]int
+        for range p0 {}
+        for _ = range p0 {}
+        for _, _ = range p0 {}
+
+        var p1 P1
+        for range p1 {}
+        for _ = range p1 {}
+        for _, _ = range p1 {}
+
+        var p2 P2
+        for range p2 /* ERROR cannot range over p2.*no core type */ {}
+
+        var m0 map[string]int
+        for range m0 {}
+        for _ = range m0 {}
+        for _, _ = range m0 {}
+
+        var m1 M1
+        for range m1 {}
+        for _ = range m1 {}
+        for _, _ = range m1 {}
+
+        var m2 M2
+        for range m2 /* ERROR cannot range over m2.*no core type */ {}
+}
+
+// type inference checks
+
+var _ = new /* ERROR cannot infer T */ ()
+
+func f4[A, B, C any](A, B) C { panic(0) }
+
+var _ = f4 /* ERROR cannot infer C */ (1, 2)
+var _ = f4[int, float32, complex128](1, 2)
+
+func f5[A, B, C any](A, []*B, struct{f []C}) int { panic(0) }
+
+var _ = f5[int, float32, complex128](0, nil, struct{f []complex128}{})
+var _ = f5 /* ERROR cannot infer */ (0, nil, struct{f []complex128}{})
+var _ = f5(0, []*float32{new[float32]()}, struct{f []complex128}{})
+
+func f6[A any](A, []A) int { panic(0) }
+
+var _ = f6(0, nil)
+
+func f6nil[A any](A) int { panic(0) }
+
+var _ = f6nil /* ERROR cannot infer */ (nil)
+
+// type inference with variadic functions
+
+func f7[T any](...T) T { panic(0) }
+
+var _ int = f7 /* ERROR cannot infer T */ ()
+var _ int = f7(1)
+var _ int = f7(1, 2)
+var _ int = f7([]int{}...)
+var _ int = f7 /* ERROR cannot use */ ([]float64{}...)
+var _ float64 = f7([]float64{}...)
+var _ = f7[float64](1, 2.3)
+var _ = f7(float64(1), 2.3)
+var _ = f7(1, 2.3 /* ERROR does not match */ )
+var _ = f7(1.2, 3 /* ERROR does not match */ )
+
+func f8[A, B any](A, B, ...B) int { panic(0) }
+
+var _ = f8(1) /* ERROR not enough arguments */
+var _ = f8(1, 2.3)
+var _ = f8(1, 2.3, 3.4, 4.5)
+var _ = f8(1, 2.3, 3.4, 4 /* ERROR does not match */ )
+var _ = f8[int, float64](1, 2.3, 3.4, 4)
+
+var _ = f8[int, float64](0, 0, nil...) // test case for #18268
+
+// init functions cannot have type parameters
+
+func init() {}
+func init[_ /* ERROR func init must have no type parameters */ any]() {}
+func init[P /* ERROR func init must have no type parameters */ any]() {}
+
+type T struct {}
+
+func (T) m1() {}
+func (T) m2[ /* ERROR method must have no type parameters */ _ any]() {}
+func (T) m3[ /* ERROR method must have no type parameters */ P any]() {}
+
+// type inference across parameterized types
+
+type S1[P any] struct { f P }
+
+func f9[P any](x S1[P]) {}
+
+func _() {
+        f9[int](S1[int]{42})
+	f9(S1[int]{42})
+}
+
+type S2[A, B, C any] struct{}
+
+func f10[X, Y, Z any](a S2[X, int, Z], b S2[X, Y, bool]) {}
+
+func _[P any]() {
+        f10[int, float32, string](S2[int, int, string]{}, S2[int, float32, bool]{})
+        f10(S2[int, int, string]{}, S2[int, float32, bool]{})
+        f10(S2[P, int, P]{}, S2[P, float32, bool]{})
+}
+
+// corner case for type inference
+// (was bug: after instanting f11, the type-checker didn't mark f11 as non-generic)
+
+func f11[T any]() {}
+
+func _() {
+	f11[int]()
+}
+
+// the previous example was extracted from
+
+// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
+// func f12[T interface{m() T}]() {}
+// 
+// type A[T any] T
+// 
+// func (a A[T]) m() A[T]
+// 
+// func _[T any]() {
+// 	f12[A[T]]()
+// }
+
+// method expressions
+
+func (_ S1[P]) m()
+
+func _() {
+	m := S1[int].m
+	m(struct { f int }{42})
+}
+
+func _[T any] (x T) {
+        m := S1[T].m
+        m(S1[T]{x})
+}
+
+type I1[A any] interface {
+        m1(A)
+}
+
+var _ I1[int] = r1[int]{}
+
+type r1[T any] struct{}
+
+func (_ r1[T]) m1(T)
+
+type I2[A, B any] interface {
+        m1(A)
+        m2(A) B
+}
+
+var _ I2[int, float32] = R2[int, float32]{}
+
+type R2[P, Q any] struct{}
+
+func (_ R2[X, Y]) m1(X)
+func (_ R2[X, Y]) m2(X) Y
+
+// type assertions and type switches over generic types
+// NOTE: These are currently disabled because it's unclear what the correct
+// approach is, and one can always work around by assigning the variable to
+// an interface first.
+
+// // ReadByte1 corresponds to the ReadByte example in the draft design.
+// func ReadByte1[T io.Reader](r T) (byte, error) {
+// 	if br, ok := r.(io.ByteReader); ok {
+// 		return br.ReadByte()
+// 	}
+// 	var b [1]byte
+// 	_, err := r.Read(b[:])
+// 	return b[0], err
+// }
+//
+// // ReadBytes2 is like ReadByte1 but uses a type switch instead.
+// func ReadByte2[T io.Reader](r T) (byte, error) {
+//         switch br := r.(type) {
+//         case io.ByteReader:
+//                 return br.ReadByte()
+//         }
+// 	var b [1]byte
+// 	_, err := r.Read(b[:])
+// 	return b[0], err
+// }
+//
+// // type assertions and type switches over generic types are strict
+// type I3 interface {
+//         m(int)
+// }
+//
+// type I4 interface {
+//         m() int // different signature from I3.m
+// }
+//
+// func _[T I3](x I3, p T) {
+//         // type assertions and type switches over interfaces are not strict
+//         _ = x.(I4)
+//         switch x.(type) {
+//         case I4:
+//         }
+//
+//         // type assertions and type switches over generic types are strict
+//         _ = p /* ERROR cannot have dynamic type I4 */.(I4)
+//         switch p.(type) {
+//         case I4 /* ERROR cannot have dynamic type I4 */ :
+//         }
+// }
+
+// type assertions and type switches over generic types lead to errors for now
+
+func _[T any](x T) {
+	_ = x /* ERROR cannot use type assertion */ .(int)
+	switch x /* ERROR cannot use type switch */ .(type) {
+	}
+
+	// work-around
+	var t interface{} = x
+	_ = t.(int)
+	switch t.(type) {
+	}
+}
+
+func _[T interface{~int}](x T) {
+	_ = x /* ERROR cannot use type assertion */ .(int)
+	switch x /* ERROR cannot use type switch */ .(type) {
+	}
+
+	// work-around
+	var t interface{} = x
+	_ = t.(int)
+	switch t.(type) {
+	}
+}
+
+// error messages related to type bounds mention those bounds
+type C[P any] interface{}
+
+func _[P C[P]] (x P) {
+	x.m /* ERROR x.m undefined */ ()
+}
+
+type I interface {}
+
+func _[P I] (x P) {
+	x.m /* ERROR type P has no field or method m */ ()
+}
+
+func _[P interface{}] (x P) {
+	x.m /* ERROR type P has no field or method m */ ()
+}
+
+func _[P any] (x P) {
+	x.m /* ERROR type P has no field or method m */ ()
+}
diff --git a/src/go/types/testdata/check/unions.go b/src/internal/types/testdata/check/unions.go
similarity index 100%
rename from src/go/types/testdata/check/unions.go
rename to src/internal/types/testdata/check/unions.go
diff --git a/src/internal/types/testdata/check/vardecl.go b/src/internal/types/testdata/check/vardecl.go
new file mode 100644
index 0000000..5b68adb
--- /dev/null
+++ b/src/internal/types/testdata/check/vardecl.go
@@ -0,0 +1,215 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package vardecl
+
+// Prerequisites.
+import "math"
+func f() {}
+func g() (x, y int) { return }
+var m map[string]int
+
+// Var decls must have a type or an initializer.
+var _ int
+var _, _ int
+
+var _; /* ERROR "expected type" */
+var _, _; /* ERROR "expected type" */
+var _, _, _; /* ERROR "expected type" */
+
+// The initializer must be an expression.
+var _ = int /* ERROR "not an expression" */
+var _ = f /* ERROR "used as value" */ ()
+
+// Identifier and expression arity must match.
+var _, _ = 1, 2
+var _ = 1, 2 /* ERROR "extra init expr 2" */
+var _, _ = 1 /* ERROR "assignment mismatch: [1-9]+ variables but.*[1-9]+ value(s)?" */
+var _, _, _ /* ERROR "missing init expr for _" */ = 1, 2
+
+var _ = g /* ERROR "multiple-value g" */ ()
+var _, _ = g()
+var _, _, _ = g /* ERROR "assignment mismatch: [1-9]+ variables but.*[1-9]+ value(s)?" */ ()
+
+var _ = m["foo"]
+var _, _ = m["foo"]
+var _, _, _ = m  /* ERROR "assignment mismatch: [1-9]+ variables but.*[1-9]+ value(s)?" */ ["foo"]
+
+var _, _ int = 1, 2
+var _ int = 1, 2 /* ERROR "extra init expr 2" */
+var _, _ int = 1 /* ERROR "assignment mismatch: [1-9]+ variables but.*[1-9]+ value(s)?" */
+var _, _, _ /* ERROR "missing init expr for _" */ int = 1, 2
+
+var (
+	_, _ = 1, 2
+	_ = 1, 2 /* ERROR "extra init expr 2" */
+	_, _ = 1 /* ERROR "assignment mismatch: [1-9]+ variables but.*[1-9]+ value(s)?" */
+	_, _, _ /* ERROR "missing init expr for _" */ = 1, 2
+
+	_ = g /* ERROR "multiple-value g" */ ()
+	_, _ = g()
+	_, _, _ = g /* ERROR "assignment mismatch: [1-9]+ variables but.*[1-9]+ value(s)?" */ ()
+
+	_ = m["foo"]
+	_, _ = m["foo"]
+	_, _, _ = m /* ERROR "assignment mismatch: [1-9]+ variables but.*[1-9]+ value(s)?" */ ["foo"]
+
+	_, _ int = 1, 2
+	_ int = 1, 2 /* ERROR "extra init expr 2" */
+	_, _ int = 1 /* ERROR "assignment mismatch: [1-9]+ variables but.*[1-9]+ value(s)?" */
+	_, _, _ /* ERROR "missing init expr for _" */ int = 1, 2
+)
+
+// Variables declared in function bodies must be 'used'.
+type T struct{}
+func (r T) _(a, b, c int) (u, v, w int) {
+	var x1 /* ERROR "declared and not used" */ int
+	var x2 /* ERROR "declared and not used" */ int
+	x1 = 1
+	(x2) = 2
+
+	y1 /* ERROR "declared and not used" */ := 1
+	y2 /* ERROR "declared and not used" */ := 2
+	y1 = 1
+	(y1) = 2
+
+	{
+		var x1 /* ERROR "declared and not used" */ int
+		var x2 /* ERROR "declared and not used" */ int
+		x1 = 1
+		(x2) = 2
+
+		y1 /* ERROR "declared and not used" */ := 1
+		y2 /* ERROR "declared and not used" */ := 2
+		y1 = 1
+		(y1) = 2
+	}
+
+	if x /* ERROR "declared and not used" */ := 0; a < b {}
+
+	switch x /* ERROR "declared and not used" */, y := 0, 1; a {
+	case 0:
+		_ = y
+	case 1:
+		x /* ERROR "declared and not used" */ := 0
+	}
+
+	var t interface{}
+	switch t /* ERROR "declared and not used" */ := t.(type) {}
+
+	switch t /* ERROR "declared and not used" */ := t.(type) {
+	case int:
+	}
+
+	switch t /* ERROR "declared and not used" */ := t.(type) {
+	case int:
+	case float32, complex64:
+		t = nil
+	}
+
+	switch t := t.(type) {
+	case int:
+	case float32, complex64:
+		_ = t
+	}
+
+	switch t := t.(type) {
+	case int:
+	case float32:
+	case string:
+		_ = func() string {
+			return t
+		}
+	}
+
+	switch t := t; t /* ERROR "declared and not used" */ := t.(type) {}
+
+	var z1 /* ERROR "declared and not used" */ int
+	var z2 int
+	_ = func(a, b, c int) (u, v, w int) {
+		z1 = a
+		(z1) = b
+		a = z2
+		return
+	}
+
+	var s []int
+	var i /* ERROR "declared and not used" */ , j int
+	for i, j = range s {
+		_ = j
+	}
+
+	for i, j /* ERROR "declared and not used" */ := range s {
+		_ = func() int {
+			return i
+		}
+	}
+	return
+}
+
+// Unused variables in function literals must lead to only one error (issue #22524).
+func _() {
+	_ = func() {
+		var x /* ERROR declared and not used */ int
+	}
+}
+
+// Invalid variable declarations must not lead to "declared and not used errors".
+// TODO(gri) enable these tests once go/types follows types2 logic for declared and not used variables
+// func _() {
+//	var a x                        // DISABLED_ERROR undefined: x
+//	var b = x                      // DISABLED_ERROR undefined: x
+//	var c int = x                  // DISABLED_ERROR undefined: x
+//	var d, e, f x                  /* DISABLED_ERROR x */ /* DISABLED_ERROR x */ /* DISABLED_ERROR x */
+//	var g, h, i = x, x, x          /* DISABLED_ERROR x */ /* DISABLED_ERROR x */ /* DISABLED_ERROR x */
+//	var j, k, l float32 = x, x, x  /* DISABLED_ERROR x */ /* DISABLED_ERROR x */ /* DISABLED_ERROR x */
+//	// but no "declared and not used" errors
+// }
+
+// Invalid (unused) expressions must not lead to spurious "declared and not used errors".
+func _() {
+	var a, b, c int
+	var x, y int
+	x, y = a /* ERROR "assignment mismatch: [1-9]+ variables but.*[1-9]+ value(s)?" */ , b, c
+	_ = x
+	_ = y
+}
+
+func _() {
+	var x int
+	return x /* ERROR too many return values */
+	return math /* ERROR too many return values */ .Sin(0)
+}
+
+func _() int {
+	var x, y int
+	return x, y /* ERROR too many return values */
+}
+
+// Short variable declarations must declare at least one new non-blank variable.
+func _() {
+	_ := /* ERROR no new variables */ 0
+	_, a := 0, 1
+	_, a := /* ERROR no new variables */ 0, 1
+	_, a, b := 0, 1, 2
+	_, _, _ := /* ERROR no new variables */ 0, 1, 2
+
+	_ = a
+	_ = b
+}
+
+// Test case for variables depending on function literals (see also #22992).
+var A /* ERROR initialization cycle */ = func() int { return A }()
+
+func _() {
+	// The function literal below must not see a.
+	var a = func() int { return a /* ERROR "undefined" */ }()
+	var _ = func() int { return a }()
+
+	// The function literal below must not see x, y, or z.
+	var x, y, z = 0, 1, func() int { return x /* ERROR "undefined" */ + y /* ERROR "undefined" */ + z /* ERROR "undefined" */ }()
+	_, _, _ = x, y, z
+}
+
+// TODO(gri) consolidate other var decl checks in this file
\ No newline at end of file
diff --git a/src/go/types/testdata/examples/constraints.go b/src/internal/types/testdata/examples/constraints.go
similarity index 100%
rename from src/go/types/testdata/examples/constraints.go
rename to src/internal/types/testdata/examples/constraints.go
diff --git a/src/internal/types/testdata/examples/functions.go b/src/internal/types/testdata/examples/functions.go
new file mode 100644
index 0000000..47e1c35
--- /dev/null
+++ b/src/internal/types/testdata/examples/functions.go
@@ -0,0 +1,219 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file shows some examples of type-parameterized functions.
+
+package p
+
+// Reverse is a generic function that takes a []T argument and
+// reverses that slice in place.
+func Reverse[T any](list []T) {
+	i := 0
+	j := len(list)-1
+	for i < j {
+		list[i], list[j] = list[j], list[i]
+		i++
+		j--
+	}
+}
+
+func _() {
+	// Reverse can be called with an explicit type argument.
+	Reverse[int](nil)
+	Reverse[string]([]string{"foo", "bar"})
+	Reverse[struct{x, y int}]([]struct{x, y int}{{1, 2}, {2, 3}, {3, 4}})
+
+	// Since the type parameter is used for an incoming argument,
+	// it can be inferred from the provided argument's type.
+	Reverse([]string{"foo", "bar"})
+	Reverse([]struct{x, y int}{{1, 2}, {2, 3}, {3, 4}})
+
+	// But the incoming argument must have a type, even if it's a
+	// default type. An untyped nil won't work.
+	// Reverse(nil) // this won't type-check
+
+	// A typed nil will work, though.
+	Reverse([]int(nil))
+}
+
+// Certain functions, such as the built-in `new` could be written using
+// type parameters.
+func new[T any]() *T {
+	var x T
+	return &x
+}
+
+// When calling our own `new`, we need to pass the type parameter
+// explicitly since there is no (value) argument from which the
+// result type could be inferred. We don't try to infer the
+// result type from the assignment to keep things simple and
+// easy to understand.
+var _ = new[int]()
+var _ *float64 = new[float64]() // the result type is indeed *float64
+
+// A function may have multiple type parameters, of course.
+func foo[A, B, C any](a A, b []B, c *C) B {
+	// do something here
+	return b[0]
+}
+
+// As before, we can pass type parameters explicitly.
+var s = foo[int, string, float64](1, []string{"first"}, new[float64]())
+
+// Or we can use type inference.
+var _ float64 = foo(42, []float64{1.0}, &s)
+
+// Type inference works in a straight-forward manner even
+// for variadic functions.
+func variadic[A, B any](A, B, ...B) int { panic(0) }
+
+// var _ = variadic(1) // ERROR not enough arguments
+var _ = variadic(1, 2.3)
+var _ = variadic(1, 2.3, 3.4, 4.5)
+var _ = variadic[int, float64](1, 2.3, 3.4, 4)
+
+// Type inference also works in recursive function calls where
+// the inferred type is the type parameter of the caller.
+func f1[T any](x T) {
+	f1(x)
+}
+
+func f2a[T any](x, y T) {
+	f2a(x, y)
+}
+
+func f2b[T any](x, y T) {
+	f2b(y, x)
+}
+
+func g2a[P, Q any](x P, y Q) {
+	g2a(x, y)
+}
+
+func g2b[P, Q any](x P, y Q) {
+	g2b(y, x)
+}
+
+// Here's an example of a recursive function call with variadic
+// arguments and type inference inferring the type parameter of
+// the caller (i.e., itself).
+func max[T interface{ ~int }](x ...T) T {
+	var x0 T
+	if len(x) > 0 {
+		x0 = x[0]
+	}
+	if len(x) > 1 {
+		x1 := max(x[1:]...)
+		if x1 > x0 {
+			return x1
+		}
+	}
+	return x0
+}
+
+// When inferring channel types, the channel direction is ignored
+// for the purpose of type inference. Once the type has been in-
+// fered, the usual parameter passing rules are applied.
+// Thus even if a type can be inferred successfully, the function
+// call may not be valid.
+
+func fboth[T any](chan T) {}
+func frecv[T any](<-chan T) {}
+func fsend[T any](chan<- T) {}
+
+func _() {
+	var both chan int
+	var recv <-chan int
+	var send chan<-int
+
+	fboth(both)
+	fboth(recv /* ERROR cannot use */ )
+	fboth(send /* ERROR cannot use */ )
+
+	frecv(both)
+	frecv(recv)
+	frecv(send /* ERROR cannot use */ )
+
+	fsend(both)
+	fsend(recv /* ERROR cannot use */)
+	fsend(send)
+}
+
+func ffboth[T any](func(chan T)) {}
+func ffrecv[T any](func(<-chan T)) {}
+func ffsend[T any](func(chan<- T)) {}
+
+func _() {
+	var both func(chan int)
+	var recv func(<-chan int)
+	var send func(chan<- int)
+
+	ffboth(both)
+	ffboth(recv /* ERROR cannot use */ )
+	ffboth(send /* ERROR cannot use */ )
+
+	ffrecv(both /* ERROR cannot use */ )
+	ffrecv(recv)
+	ffrecv(send /* ERROR cannot use */ )
+
+	ffsend(both /* ERROR cannot use */ )
+	ffsend(recv /* ERROR cannot use */ )
+	ffsend(send)
+}
+
+// When inferring elements of unnamed composite parameter types,
+// if the arguments are defined types, use their underlying types.
+// Even though the matching types are not exactly structurally the
+// same (one is a type literal, the other a named type), because
+// assignment is permitted, parameter passing is permitted as well,
+// so type inference should be able to handle these cases well.
+
+func g1[T any]([]T) {}
+func g2[T any]([]T, T) {}
+func g3[T any](*T, ...T) {}
+
+func _() {
+	type intSlize []int
+	g1([]int{})
+	g1(intSlize{})
+	g2(nil, 0)
+
+	type myString string
+	var s1 string
+	g3(nil, "1", myString("2"), "3")
+	g3(& /* ERROR does not match */ s1, "1", myString("2"), "3")
+	_ = s1
+
+	type myStruct struct{x int}
+	var s2 myStruct
+	g3(nil, struct{x int}{}, myStruct{})
+	g3(&s2, struct{x int}{}, myStruct{})
+	g3(nil, myStruct{}, struct{x int}{})
+	g3(&s2, myStruct{}, struct{x int}{})
+}
+
+// Here's a realistic example.
+
+func append[T any](s []T, t ...T) []T { panic(0) }
+
+func _() {
+	var f func()
+	type Funcs []func()
+	var funcs Funcs
+	_ = append(funcs, f)
+}
+
+// Generic type declarations cannot have empty type parameter lists
+// (that would indicate a slice type). Thus, generic functions cannot
+// have empty type parameter lists, either. This is a syntax error.
+
+func h[] /* ERROR empty type parameter list */ () {}
+
+func _() {
+	h /* ERROR cannot index */ [] /* ERROR operand */ ()
+}
+
+// Generic functions must have a function body.
+
+func _ /* ERROR generic function is missing function body */ [P any]()
diff --git a/src/internal/types/testdata/examples/inference.go b/src/internal/types/testdata/examples/inference.go
new file mode 100644
index 0000000..073df9c
--- /dev/null
+++ b/src/internal/types/testdata/examples/inference.go
@@ -0,0 +1,116 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file shows some examples of type inference.
+
+package p
+
+type Ordered interface {
+	~int | ~float64 | ~string
+}
+
+func min[T Ordered](x, y T) T { panic(0) }
+
+func _() {
+	// min can be called with explicit instantiation.
+	_ = min[int](1, 2)
+
+	// Alternatively, the type argument can be inferred from
+	// one of the arguments. Untyped arguments will be considered
+	// last.
+	var x int
+	_ = min(x, x)
+	_ = min(x, 1)
+	_ = min(x, 1.0)
+	_ = min(1, 2)
+	_ = min(1, 2.3 /* ERROR default type float64 .* does not match */)
+
+	var y float64
+	_ = min(1, y)
+	_ = min(1.2, y)
+	_ = min(1.2, 3.4)
+	_ = min(1.2, 3 /* ERROR default type int .* does not match */)
+
+	var s string
+	_ = min(s, "foo")
+	_ = min("foo", "bar")
+}
+
+func mixed[T1, T2, T3 any](T1, T2, T3) {}
+
+func _() {
+	// mixed can be called with explicit instantiation.
+	mixed[int, string, bool](0, "", false)
+
+	// Alternatively, partial type arguments may be provided
+	// (from left to right), and the other may be inferred.
+	mixed[int, string](0, "", false)
+	mixed[int](0, "", false)
+	mixed(0, "", false)
+
+	// Provided type arguments always take precedence over
+	// inferred types.
+	mixed[int, string](1.1 /* ERROR cannot use 1.1 */, "", false)
+}
+
+func related1[Slice interface{ ~[]Elem }, Elem any](s Slice, e Elem) {}
+
+func _() {
+	// related1 can be called with explicit instantiation.
+	var si []int
+	related1[[]int, int](si, 0)
+
+	// Alternatively, the 2nd type argument can be inferred
+	// from the first one through constraint type inference.
+	var ss []string
+	_ = related1[[]string]
+	related1[[]string](ss, "foo")
+
+	// A type argument inferred from another explicitly provided
+	// type argument overrides whatever value argument type is given.
+	related1[[]string](ss, 0 /* ERROR cannot use 0 */)
+
+	// A type argument may be inferred from a value argument
+	// and then help infer another type argument via constraint
+	// type inference.
+	related1(si, 0)
+	related1(si, "foo" /* ERROR cannot use "foo" */)
+}
+
+func related2[Elem any, Slice interface{ []Elem }](e Elem, s Slice) {}
+
+func _() {
+	// related2 can be called with explicit instantiation.
+	var si []int
+	related2[int, []int](0, si)
+
+	// Alternatively, the 2nd type argument can be inferred
+	// from the first one through constraint type inference.
+	var ss []string
+	_ = related2[string]
+	related2[string]("foo", ss)
+
+	// A type argument may be inferred from a value argument
+	// and then help infer another type argument via constraint
+	// type inference. Untyped arguments are always considered
+	// last.
+	related2(1.2, []float64{})
+	related2(1.0, []int{})
+	related2 /* ERROR does not satisfy */ (float64(1.0), []int{}) // TODO(gri) fix error position
+}
+
+type List[P any] []P
+
+func related3[Elem any, Slice []Elem | List[Elem]]() Slice { return nil }
+
+func _() {
+	// related3 can be instantiated explicitly
+	related3[int, []int]()
+	related3[byte, List[byte]]()
+
+	// The 2nd type argument cannot be inferred from the first
+	// one because there's two possible choices: []Elem and
+	// List[Elem].
+	related3 /* ERROR cannot infer Slice */ [int]()
+}
diff --git a/src/go/types/testdata/examples/methods.go b/src/internal/types/testdata/examples/methods.go
similarity index 100%
rename from src/go/types/testdata/examples/methods.go
rename to src/internal/types/testdata/examples/methods.go
diff --git a/src/go/types/testdata/examples/operations.go b/src/internal/types/testdata/examples/operations.go
similarity index 100%
rename from src/go/types/testdata/examples/operations.go
rename to src/internal/types/testdata/examples/operations.go
diff --git a/src/internal/types/testdata/examples/types.go b/src/internal/types/testdata/examples/types.go
new file mode 100644
index 0000000..052d168
--- /dev/null
+++ b/src/internal/types/testdata/examples/types.go
@@ -0,0 +1,315 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file shows some examples of generic types.
+
+package p
+
+// List is just what it says - a slice of E elements.
+type List[E any] []E
+
+// A generic (parameterized) type must always be instantiated
+// before it can be used to designate the type of a variable
+// (including a struct field, or function parameter); though
+// for the latter cases, the provided type may be another type
+// parameter. So:
+var _ List[byte] = []byte{}
+
+// A generic binary tree might be declared as follows.
+type Tree[E any] struct {
+	left, right *Tree[E]
+	payload E
+}
+
+// A simple instantiation of Tree:
+var root1 Tree[int]
+
+// The actual type parameter provided may be a generic type itself:
+var root2 Tree[List[int]]
+
+// A couple of more complex examples.
+// We don't need extra parentheses around the element type of the slices on
+// the right (unlike when we use ()'s rather than []'s for type parameters).
+var _ List[List[int]] = []List[int]{}
+var _ List[List[List[Tree[int]]]] = []List[List[Tree[int]]]{}
+
+// Type parameters act like type aliases when used in generic types
+// in the sense that we can "emulate" a specific type instantiation
+// with type aliases.
+type T1[P any] struct {
+	f P
+}
+
+type T2[P any] struct {
+	f struct {
+		g P
+	}
+}
+
+var x1 T1[struct{ g int }]
+var x2 T2[int]
+
+func _() {
+	// This assignment is invalid because the types of x1, x2 are T1(...)
+	// and T2(...) respectively, which are two different defined types.
+	x1 = x2 // ERROR assignment
+
+	// This assignment is valid because the types of x1.f and x2.f are
+	// both struct { g int }; the type parameters act like type aliases
+	// and their actual names don't come into play here.
+	x1.f = x2.f
+}
+
+// We can verify this behavior using type aliases instead:
+type T1a struct {
+	f A1
+}
+type A1 = struct { g int }
+
+type T2a struct {
+	f struct {
+		g A2
+	}
+}
+type A2 = int
+
+var x1a T1a
+var x2a T2a
+
+func _() {
+	x1a = x2a // ERROR assignment
+	x1a.f = x2a.f
+}
+
+// Another interesting corner case are generic types that don't use
+// their type arguments. For instance:
+type T[P any] struct{}
+
+var xint T[int]
+var xbool T[bool]
+
+// Are these two variables of the same type? After all, their underlying
+// types are identical. We consider them to be different because each type
+// instantiation creates a new named type, in this case T<int> and T<bool>
+// even if their underlying types are identical. This is sensible because
+// we might still have methods that have different signatures or behave
+// differently depending on the type arguments, and thus we can't possibly
+// consider such types identical. Consequently:
+func _() {
+	xint = xbool // ERROR assignment
+}
+
+// Generic types cannot be used without instantiation.
+var _ T // ERROR cannot use generic type T
+var _ = T /* ERROR cannot use generic type T */ (0)
+
+// In type context, generic (parameterized) types cannot be parenthesized before
+// being instantiated. See also NOTES entry from 12/4/2019.
+var _ (T /* ERROR cannot use generic type T */ )[ /* ERROR unexpected \[|expected ';' */ int]
+
+// All types may be parameterized, including interfaces.
+type I1[T any] interface{
+	m1(T)
+}
+
+// There is no such thing as a variadic generic type.
+type _[T ... /* ERROR invalid use of ... */ any] struct{}
+
+// Generic interfaces may be embedded as one would expect.
+type I2 interface {
+	I1(int)     // method!
+	I1[string]  // embedded I1
+}
+
+func _() {
+	var x I2
+	x.I1(0)
+	x.m1("foo")
+}
+
+type I0 interface {
+	m0()
+}
+
+type I3 interface {
+	I0
+	I1[bool]
+	m(string)
+}
+
+func _() {
+	var x I3
+	x.m0()
+	x.m1(true)
+	x.m("foo")
+}
+
+type _ struct {
+	( /* ERROR cannot parenthesize */ int8)
+	( /* ERROR cannot parenthesize */ *int16)
+	*( /* ERROR cannot parenthesize */ int32)
+	List[int]
+
+	int8 /* ERROR int8 redeclared */
+	* /* ERROR int16 redeclared */ int16
+	List /* ERROR List redeclared */ [int]
+}
+
+// Issue #45639: We don't allow this anymore. Keep this code
+//               in case we decide to revisit this decision.
+//
+// It's possible to declare local types whose underlying types
+// are type parameters. As with ordinary type definitions, the
+// types underlying properties are "inherited" but the methods
+// are not.
+// func _[T interface{ m(); ~int }]() {
+// 	type L T
+// 	var x L
+// 
+// 	// m is not defined on L (it is not "inherited" from
+// 	// its underlying type).
+// 	x.m /* ERROR x.m undefined */ ()
+// 
+// 	// But the properties of T, such that as that it supports
+// 	// the operations of the types given by its type bound,
+// 	// are also the properties of L.
+// 	x++
+// 	_ = x - x
+// 
+// 	// On the other hand, if we define a local alias for T,
+// 	// that alias stands for T as expected.
+// 	type A = T
+// 	var y A
+// 	y.m()
+// 	_ = y < 0
+// }
+
+// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
+// // It is not permitted to declare a local type whose underlying
+// // type is a type parameter not declared by that type declaration.
+// func _[T any]() {
+// 	type _ T         // ERROR cannot use function type parameter T as RHS in type declaration
+// 	type _ [_ any] T // ERROR cannot use function type parameter T as RHS in type declaration
+// }
+
+// As a special case, an explicit type argument may be omitted
+// from a type parameter bound if the type bound expects exactly
+// one type argument. In that case, the type argument is the
+// respective type parameter to which the type bound applies.
+// Note: We may not permit this syntactic sugar at first.
+// Note: This is now disabled. All examples below are adjusted.
+type Adder[T any] interface {
+	Add(T) T
+}
+
+// We don't need to explicitly instantiate the Adder bound
+// if we have exactly one type parameter.
+func Sum[T Adder[T]](list []T) T {
+	var sum T
+	for _, x := range list {
+		sum = sum.Add(x)
+	}
+	return sum
+}
+
+// Valid and invalid variations.
+type B0 any
+type B1[_ any] any
+type B2[_, _ any] any
+
+func _[T1 B0]() {}
+func _[T1 B1[T1]]() {}
+func _[T1 B2 /* ERROR cannot use generic type .* without instantiation */ ]() {}
+
+func _[T1, T2 B0]() {}
+func _[T1 B1[T1], T2 B1[T2]]() {}
+func _[T1, T2 B2 /* ERROR cannot use generic type .* without instantiation */ ]() {}
+
+func _[T1 B0, T2 B1[T2]]() {} // here B1 applies to T2
+
+// When the type argument is left away, the type bound is
+// instantiated for each type parameter with that type
+// parameter.
+// Note: We may not permit this syntactic sugar at first.
+func _[A Adder[A], B Adder[B], C Adder[A]]() {
+	var a A // A's type bound is Adder[A]
+	a = a.Add(a)
+	var b B // B's type bound is Adder[B]
+	b = b.Add(b)
+	var c C // C's type bound is Adder[A]
+	a = c.Add(a)
+}
+
+// The type of variables (incl. parameters and return values) cannot
+// be an interface with type constraints or be/embed comparable.
+type I interface {
+	~int
+}
+
+var (
+	_ interface /* ERROR contains type constraints */ {~int}
+	_ I /* ERROR contains type constraints */
+)
+
+func _(I /* ERROR contains type constraints */ )
+func _(x, y, z I /* ERROR contains type constraints */ )
+func _() I /* ERROR contains type constraints */
+
+func _() {
+	var _ I /* ERROR contains type constraints */
+}
+
+type C interface {
+	comparable
+}
+
+var _ comparable /* ERROR comparable */
+var _ C /* ERROR comparable */
+
+func _(_ comparable /* ERROR comparable */ , _ C /* ERROR comparable */ )
+
+func _() {
+	var _ comparable /* ERROR comparable */
+	var _ C /* ERROR comparable */
+}
+
+// Type parameters are never const types, i.e., it's
+// not possible to declare a constant of type parameter type.
+// (If a type set contains just a single const type, we could
+// allow it, but such type sets don't make much sense in the
+// first place.)
+func _[T interface{~int|~float64}]() {
+	// not valid
+	const _ = T /* ERROR not constant */ (0)
+	const _ T /* ERROR invalid constant type T */ = 1
+
+	// valid
+	var _ = T(0)
+	var _ T = 1
+	_ = T(0)
+}
+
+// It is possible to create composite literals of type parameter
+// type as long as it's possible to create a composite literal
+// of the core type of the type parameter's constraint.
+func _[P interface{ ~[]int }]() P {
+	return P{}
+	return P{1, 2, 3}
+}
+
+func _[P interface{ ~[]E }, E interface{ map[string]P } ]() P {
+	x := P{}
+	return P{{}}
+	return P{E{}}
+	return P{E{"foo": x}}
+	return P{{"foo": x}, {}}
+}
+
+// This is a degenerate case with a singleton type set, but we can create
+// composite literals even if the core type is a defined type.
+type MyInts []int
+
+func _[P MyInts]() P {
+	return P{}
+}
diff --git a/src/internal/types/testdata/examples/typesets.go b/src/internal/types/testdata/examples/typesets.go
new file mode 100644
index 0000000..a50beb9
--- /dev/null
+++ b/src/internal/types/testdata/examples/typesets.go
@@ -0,0 +1,59 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file shows some examples of constraint literals with elided interfaces.
+// These examples are permitted if proposal issue #48424 is accepted.
+
+package p
+
+// Constraint type sets of the form T, ~T, or A|B may omit the interface.
+type (
+	_[T int]            struct{}
+	_[T ~int]           struct{}
+	_[T int | string]   struct{}
+	_[T ~int | ~string] struct{}
+)
+
+func min[T int | string](x, y T) T {
+	if x < y {
+		return x
+	}
+	return y
+}
+
+func lookup[M ~map[K]V, K comparable, V any](m M, k K) V {
+	return m[k]
+}
+
+func deref[P ~*E, E any](p P) E {
+	return *p
+}
+
+func _() int {
+	p := new(int)
+	return deref(p)
+}
+
+func addrOfCopy[V any, P *V](v V) P {
+	return &v
+}
+
+func _() *int {
+	return addrOfCopy(0)
+}
+
+// A type parameter may not be embedded in an interface;
+// so it can also not be used as a constraint.
+func _[A any, B A /* ERROR cannot use a type parameter as constraint */]()    {}
+func _[A any, B, C A /* ERROR cannot use a type parameter as constraint */]() {}
+
+// Error messages refer to the type constraint as it appears in the source.
+// (No implicit interface should be exposed.)
+func _[T string](x T) T {
+	return x /* ERROR constrained by string */ * x
+}
+
+func _[T int | string](x T) T {
+	return x /* ERROR constrained by int|string */ * x
+}
diff --git a/src/internal/types/testdata/fixedbugs/54942.go b/src/internal/types/testdata/fixedbugs/54942.go
new file mode 100644
index 0000000..f2e733b
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/54942.go
@@ -0,0 +1,38 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+import (
+	"context"
+	"database/sql"
+)
+
+type I interface {
+	m(int, int, *int, int)
+}
+
+type T struct{}
+
+func (_ *T) m(a, b, c, d int) {}
+
+var _ I = new /* ERROR have m\(int, int, int, int\)\n\t\twant m\(int, int, \*int, int\) */ (T)
+
+// (slightly modified) test case from issue
+
+type Result struct {
+	Value string
+}
+
+type Executor interface {
+	Execute(context.Context, sql.Stmt, int, []sql.NamedArg, int) (Result, error)
+}
+
+type myExecutor struct{}
+
+func (_ *myExecutor) Execute(ctx context.Context, stmt sql.Stmt, maxrows int, args []sql.NamedArg, urgency int) (*Result, error) {
+	return &Result{}, nil
+}
+
+var ex Executor = new /* ERROR have Execute\(context\.Context, sql\.Stmt, int, \[\]sql\.NamedArg, int\) \(\*Result, error\)\n\t\twant Execute\(context\.Context, sql\.Stmt, int, \[\]sql\.NamedArg, int\) \(Result, error\) */ (myExecutor)
diff --git a/src/go/types/testdata/fixedbugs/issue20583.go b/src/internal/types/testdata/fixedbugs/issue20583.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue20583.go
rename to src/internal/types/testdata/fixedbugs/issue20583.go
diff --git a/src/go/types/testdata/fixedbugs/issue23203a.go b/src/internal/types/testdata/fixedbugs/issue23203a.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue23203a.go
rename to src/internal/types/testdata/fixedbugs/issue23203a.go
diff --git a/src/go/types/testdata/fixedbugs/issue23203b.go b/src/internal/types/testdata/fixedbugs/issue23203b.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue23203b.go
rename to src/internal/types/testdata/fixedbugs/issue23203b.go
diff --git a/src/go/types/testdata/fixedbugs/issue25838.go b/src/internal/types/testdata/fixedbugs/issue25838.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue25838.go
rename to src/internal/types/testdata/fixedbugs/issue25838.go
diff --git a/src/go/types/testdata/fixedbugs/issue26390.go b/src/internal/types/testdata/fixedbugs/issue26390.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue26390.go
rename to src/internal/types/testdata/fixedbugs/issue26390.go
diff --git a/src/go/types/testdata/fixedbugs/issue28251.go b/src/internal/types/testdata/fixedbugs/issue28251.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue28251.go
rename to src/internal/types/testdata/fixedbugs/issue28251.go
diff --git a/src/internal/types/testdata/fixedbugs/issue39634.go b/src/internal/types/testdata/fixedbugs/issue39634.go
new file mode 100644
index 0000000..6ee1548
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue39634.go
@@ -0,0 +1,90 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Examples adjusted to match new [T any] syntax for type parameters.
+// Also, previously permitted empty type parameter lists and instantiations
+// are now syntax errors.
+
+package p
+
+// crash 1
+type nt1[_ any]interface{g /* ERROR undefined */ }
+type ph1[e nt1[e],g(d /* ERROR undefined */ )]s /* ERROR undefined */
+func(*ph1[e,e /* ERROR redeclared */ ])h(d /* ERROR undefined */ )
+
+// crash 2
+// Disabled: empty []'s are now syntax errors. This example leads to too many follow-on errors.
+// type Numeric2 interface{t2 /* ERROR not a type */ }
+// func t2[T Numeric2](s[]T){0 /* ERROR not a type */ []{s /* ERROR cannot index */ [0][0]}}
+
+// crash 3
+type t3 *interface{ t3.p /* ERROR t3.p is not a type */ }
+
+// crash 4
+type Numeric4 interface{t4 /* ERROR not a type */ }
+func t4[T Numeric4](s[]T){if( /* ERROR non-boolean */ 0){*s /* ERROR cannot indirect */ [0]}}
+
+// crash 7
+type foo7 interface { bar() }
+type x7[A any] struct{ foo7 }
+func main7() { var _ foo7 = x7[int]{} }
+
+// crash 8
+type foo8[A any] interface { ~A /* ERROR cannot be a type parameter */ }
+func bar8[A foo8[A]](a A) {}
+
+// crash 9
+type foo9[A any] interface { foo9 /* ERROR invalid recursive type */ [A] }
+func _() { var _ = new(foo9[int]) }
+
+// crash 12
+var u /* ERROR cycle */ , i [func /* ERROR used as value */ /* ERROR used as value */ (u, c /* ERROR undefined */ /* ERROR undefined */ ) {}(0, len /* ERROR must be called */ /* ERROR must be called */ )]c /* ERROR undefined */ /* ERROR undefined */
+
+// crash 15
+func y15() { var a /* ERROR declared and not used */ interface{ p() } = G15[string]{} }
+type G15[X any] s /* ERROR undefined */
+func (G15 /* ERROR generic type .* without instantiation */ ) p()
+
+// crash 16
+type Foo16[T any] r16 /* ERROR not a type */
+func r16[T any]() Foo16[Foo16[T]] { panic(0) }
+
+// crash 17
+type Y17 interface{ c() }
+type Z17 interface {
+	c() Y17
+	Y17 /* ERROR duplicate method */
+}
+func F17[T Z17](T) {}
+
+// crash 18
+type o18[T any] []func(_ o18[[]_ /* ERROR cannot use _ */ ])
+
+// crash 19
+type Z19 [][[]Z19{}[0][0]]c19 /* ERROR undefined */
+
+// crash 20
+type Z20 /* ERROR invalid recursive type */ interface{ Z20 }
+func F20[t Z20]() { F20(t /* ERROR invalid composite literal type */ {}) }
+
+// crash 21
+type Z21 /* ERROR invalid recursive type */ interface{ Z21 }
+func F21[T Z21]() { ( /* ERROR not used */ F21[Z21]) }
+
+// crash 24
+type T24[P any] P // ERROR cannot use a type parameter as RHS in type declaration
+func (r T24[P]) m() { T24 /* ERROR without instantiation */ .m() }
+
+// crash 25
+type T25[A any] int
+func (t T25[A]) m1() {}
+var x T25 /* ERROR without instantiation */ .m1
+
+// crash 26
+type T26 = interface{ F26[ /* ERROR interface method must have no type parameters */ Z any]() }
+func F26[Z any]() T26 { return F26[] /* ERROR operand */ }
+
+// crash 27
+func e27[T any]() interface{ x27 /* ERROR not a type */ } { panic(0) }
+func x27() { e27 /* ERROR cannot infer T */ () }
diff --git a/src/go/types/testdata/fixedbugs/issue39664.go b/src/internal/types/testdata/fixedbugs/issue39664.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue39664.go
rename to src/internal/types/testdata/fixedbugs/issue39664.go
diff --git a/src/go/types/testdata/fixedbugs/issue39680.go b/src/internal/types/testdata/fixedbugs/issue39680.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue39680.go
rename to src/internal/types/testdata/fixedbugs/issue39680.go
diff --git a/src/internal/types/testdata/fixedbugs/issue39693.go b/src/internal/types/testdata/fixedbugs/issue39693.go
new file mode 100644
index 0000000..496754d
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue39693.go
@@ -0,0 +1,23 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type Number1 interface {
+	// embedding non-interface types is permitted
+	int
+	float64
+}
+
+func Add1[T Number1](a, b T) T {
+	return a /* ERROR not defined */ + b
+}
+
+type Number2 interface {
+	int | float64
+}
+
+func Add2[T Number2](a, b T) T {
+	return a + b
+}
diff --git a/src/go/types/testdata/fixedbugs/issue39699.go b/src/internal/types/testdata/fixedbugs/issue39699.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue39699.go
rename to src/internal/types/testdata/fixedbugs/issue39699.go
diff --git a/src/go/types/testdata/fixedbugs/issue39711.go b/src/internal/types/testdata/fixedbugs/issue39711.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue39711.go
rename to src/internal/types/testdata/fixedbugs/issue39711.go
diff --git a/src/go/types/testdata/fixedbugs/issue39723.go b/src/internal/types/testdata/fixedbugs/issue39723.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue39723.go
rename to src/internal/types/testdata/fixedbugs/issue39723.go
diff --git a/src/go/types/testdata/fixedbugs/issue39725.go b/src/internal/types/testdata/fixedbugs/issue39725.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue39725.go
rename to src/internal/types/testdata/fixedbugs/issue39725.go
diff --git a/src/internal/types/testdata/fixedbugs/issue39754.go b/src/internal/types/testdata/fixedbugs/issue39754.go
new file mode 100644
index 0000000..97365e2
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue39754.go
@@ -0,0 +1,21 @@
+// Copyright 2020 The Go Authors. All rights reserved.

+// Use of this source code is governed by a BSD-style

+// license that can be found in the LICENSE file.

+

+package p

+

+type Optional[T any] struct {}

+

+func (_ Optional[T]) Val() (T, bool)

+

+type Box[T any] interface {

+	Val() (T, bool)

+}

+

+func f[V interface{}, A, B Box[V]]() {}

+

+func _() {

+	f[int, Optional[int], Optional[int]]()

+	_ = f[int, Optional[int], Optional /* ERROR does not satisfy Box */ [string]]

+	_ = f[int, Optional[int], Optional /* ERROR Optional.* does not satisfy Box.* */ [string]]

+}

diff --git a/src/go/types/testdata/fixedbugs/issue39755.go b/src/internal/types/testdata/fixedbugs/issue39755.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue39755.go
rename to src/internal/types/testdata/fixedbugs/issue39755.go
diff --git a/src/go/types/testdata/fixedbugs/issue39768.go b/src/internal/types/testdata/fixedbugs/issue39768.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue39768.go
rename to src/internal/types/testdata/fixedbugs/issue39768.go
diff --git a/src/internal/types/testdata/fixedbugs/issue39938.go b/src/internal/types/testdata/fixedbugs/issue39938.go
new file mode 100644
index 0000000..633698d
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue39938.go
@@ -0,0 +1,54 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+// All but E2 and E5 provide an "indirection" and break infinite expansion of a type.
+type E0[P any] []P
+type E1[P any] *P
+type E2[P any] struct{ _ P }
+type E3[P any] struct{ _ *P }
+type E5[P any] struct{ _ [10]P }
+
+type T0 struct {
+        _ E0[T0]
+}
+
+type T0_ struct {
+        E0[T0_]
+}
+
+type T1 struct {
+        _ E1[T1]
+}
+
+type T2 /* ERROR invalid recursive type */ struct {
+        _ E2[T2]
+}
+
+type T3 struct {
+        _ E3[T3]
+}
+
+type T4 /* ERROR invalid recursive type */ [10]E5[T4]
+
+type T5 struct {
+	_ E0[E2[T5]]
+}
+
+type T6 struct {
+	_ E0[E2[E0[E1[E2[[10]T6]]]]]
+}
+
+type T7 struct {
+	_ E0[[10]E2[E0[E2[E2[T7]]]]]
+}
+
+type T8 struct {
+	_ E0[[]E2[E0[E2[E2[T8]]]]]
+}
+
+type T9 /* ERROR invalid recursive type */ [10]E2[E5[E2[T9]]]
+
+type T10 [10]E2[E5[E2[func(T10)]]]
diff --git a/src/go/types/testdata/fixedbugs/issue39948.go b/src/internal/types/testdata/fixedbugs/issue39948.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue39948.go
rename to src/internal/types/testdata/fixedbugs/issue39948.go
diff --git a/src/go/types/testdata/fixedbugs/issue39976.go b/src/internal/types/testdata/fixedbugs/issue39976.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue39976.go
rename to src/internal/types/testdata/fixedbugs/issue39976.go
diff --git a/src/go/types/testdata/fixedbugs/issue39982.go b/src/internal/types/testdata/fixedbugs/issue39982.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue39982.go
rename to src/internal/types/testdata/fixedbugs/issue39982.go
diff --git a/src/go/types/testdata/fixedbugs/issue40038.go b/src/internal/types/testdata/fixedbugs/issue40038.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue40038.go
rename to src/internal/types/testdata/fixedbugs/issue40038.go
diff --git a/src/go/types/testdata/fixedbugs/issue40056.go b/src/internal/types/testdata/fixedbugs/issue40056.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue40056.go
rename to src/internal/types/testdata/fixedbugs/issue40056.go
diff --git a/src/go/types/testdata/fixedbugs/issue40057.go b/src/internal/types/testdata/fixedbugs/issue40057.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue40057.go
rename to src/internal/types/testdata/fixedbugs/issue40057.go
diff --git a/src/go/types/testdata/fixedbugs/issue40301.go b/src/internal/types/testdata/fixedbugs/issue40301.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue40301.go
rename to src/internal/types/testdata/fixedbugs/issue40301.go
diff --git a/src/internal/types/testdata/fixedbugs/issue40350.go b/src/internal/types/testdata/fixedbugs/issue40350.go
new file mode 100644
index 0000000..08eb426
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue40350.go
@@ -0,0 +1,16 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type number interface {
+	~float64 | ~int | ~int32
+	float64 | ~int32
+}
+
+func f[T number]() {}
+
+func _() {
+	_ = f[int /* ERROR int does not satisfy number \(number mentions int, but int is not in the type set of number\)*/]
+}
diff --git a/src/go/types/testdata/fixedbugs/issue40684.go b/src/internal/types/testdata/fixedbugs/issue40684.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue40684.go
rename to src/internal/types/testdata/fixedbugs/issue40684.go
diff --git a/src/go/types/testdata/fixedbugs/issue40789.go b/src/internal/types/testdata/fixedbugs/issue40789.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue40789.go
rename to src/internal/types/testdata/fixedbugs/issue40789.go
diff --git a/src/internal/types/testdata/fixedbugs/issue41124.go b/src/internal/types/testdata/fixedbugs/issue41124.go
new file mode 100644
index 0000000..80d1ff4
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue41124.go
@@ -0,0 +1,91 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+// Test case from issue.
+
+type Nat /* ERROR invalid recursive type */ interface {
+	Zero|Succ
+}
+
+type Zero struct{}
+type Succ struct{
+	Nat // Nat contains type constraints but is invalid, so no error
+}
+
+// Struct tests.
+
+type I1 interface {
+	comparable
+}
+
+type I2 interface {
+	~int
+}
+
+type I3 interface {
+	I1
+	I2
+}
+
+type _ struct {
+	f I1 // ERROR interface is .* comparable
+}
+
+type _ struct {
+	comparable // ERROR interface is .* comparable
+}
+
+type _ struct{
+	I1 // ERROR interface is .* comparable
+}
+
+type _ struct{
+	I2 // ERROR interface contains type constraints
+}
+
+type _ struct{
+	I3 // ERROR interface contains type constraints
+}
+
+// General composite types.
+
+type (
+	_ [10]I1 // ERROR interface is .* comparable
+	_ [10]I2 // ERROR interface contains type constraints
+
+	_ []I1 // ERROR interface is .* comparable
+	_ []I2 // ERROR interface contains type constraints
+
+	_ *I3 // ERROR interface contains type constraints
+	_ map[I1 /* ERROR interface is .* comparable */ ]I2 // ERROR interface contains type constraints
+	_ chan I3 // ERROR interface contains type constraints
+	_ func(I1 /* ERROR interface is .* comparable */ )
+	_ func() I2 // ERROR interface contains type constraints
+)
+
+// Other cases.
+
+var _ = [...]I3 /* ERROR interface contains type constraints */ {}
+
+func _(x interface{}) {
+	_ = x.(I3 /* ERROR interface contains type constraints */ )
+}
+
+type T1[_ any] struct{}
+type T3[_, _, _ any] struct{}
+var _ T1[I2 /* ERROR interface contains type constraints */ ]
+var _ T3[int, I2 /* ERROR interface contains type constraints */ , float32]
+
+func f1[_ any]() int { panic(0) }
+var _ = f1[I2 /* ERROR interface contains type constraints */ ]()
+func f3[_, _, _ any]() int { panic(0) }
+var _ = f3[int, I2 /* ERROR interface contains type constraints */ , float32]()
+
+func _(x interface{}) {
+	switch x.(type) {
+	case I2 /* ERROR interface contains type constraints */ :
+	}
+}
diff --git a/src/go/types/testdata/fixedbugs/issue42695.go b/src/internal/types/testdata/fixedbugs/issue42695.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue42695.go
rename to src/internal/types/testdata/fixedbugs/issue42695.go
diff --git a/src/go/types/testdata/fixedbugs/issue42758.go b/src/internal/types/testdata/fixedbugs/issue42758.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue42758.go
rename to src/internal/types/testdata/fixedbugs/issue42758.go
diff --git a/src/go/types/testdata/fixedbugs/issue42881.go b/src/internal/types/testdata/fixedbugs/issue42881.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue42881.go
rename to src/internal/types/testdata/fixedbugs/issue42881.go
diff --git a/src/internal/types/testdata/fixedbugs/issue42987.go b/src/internal/types/testdata/fixedbugs/issue42987.go
new file mode 100644
index 0000000..f58c63f
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue42987.go
@@ -0,0 +1,8 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check that there is only one error (no follow-on errors).
+
+package p
+var _ = [ ... /* ERROR invalid use of \[...\] array */ ]byte("foo")
\ No newline at end of file
diff --git a/src/go/types/testdata/fixedbugs/issue43056.go b/src/internal/types/testdata/fixedbugs/issue43056.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue43056.go
rename to src/internal/types/testdata/fixedbugs/issue43056.go
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43087.go b/src/internal/types/testdata/fixedbugs/issue43087.go
similarity index 100%
rename from src/cmd/compile/internal/types2/testdata/fixedbugs/issue43087.go
rename to src/internal/types/testdata/fixedbugs/issue43087.go
diff --git a/src/internal/types/testdata/fixedbugs/issue43109.go b/src/internal/types/testdata/fixedbugs/issue43109.go
new file mode 100644
index 0000000..f242f16
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue43109.go
@@ -0,0 +1,10 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Ensure there is no "imported and not used" error
+// if a package wasn't imported in the first place.
+
+package p
+
+import . "/foo" // ERROR could not import \/foo
diff --git a/src/go/types/testdata/fixedbugs/issue43110.go b/src/internal/types/testdata/fixedbugs/issue43110.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue43110.go
rename to src/internal/types/testdata/fixedbugs/issue43110.go
diff --git a/src/go/types/testdata/fixedbugs/issue43124.go b/src/internal/types/testdata/fixedbugs/issue43124.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue43124.go
rename to src/internal/types/testdata/fixedbugs/issue43124.go
diff --git a/src/go/types/testdata/fixedbugs/issue43125.go b/src/internal/types/testdata/fixedbugs/issue43125.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue43125.go
rename to src/internal/types/testdata/fixedbugs/issue43125.go
diff --git a/src/internal/types/testdata/fixedbugs/issue43190.go b/src/internal/types/testdata/fixedbugs/issue43190.go
new file mode 100644
index 0000000..d1b46b5
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue43190.go
@@ -0,0 +1,31 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// The errors below are produced by the parser, but we check
+// them here for consistency with the types2 tests.
+
+package p
+
+import ; // ERROR missing import path
+import "" // ERROR invalid import path \(empty string\)
+import
+var /* ERROR missing import path */ _ int
+import .; //  ERROR missing import path
+import 'x' // ERROR import path must be a string
+var _ int
+import /* ERROR imports must appear before other declarations */ _ "math"
+
+// Don't repeat previous error for each immediately following import ...
+import ()
+import (.) // ERROR missing import path
+import (
+	"fmt"
+	.
+) // ERROR missing import path
+
+// ... but remind with error again if we start a new import section after
+// other declarations
+var _ = fmt.Println
+import /* ERROR imports must appear before other declarations */ _ "math"
+import _ "math"
diff --git a/src/internal/types/testdata/fixedbugs/issue43527.go b/src/internal/types/testdata/fixedbugs/issue43527.go
new file mode 100644
index 0000000..b515100
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue43527.go
@@ -0,0 +1,16 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+const L = 10
+
+type (
+	_        [L]struct{}
+	_        [A /* ERROR undefined array length A or missing type constraint */ ]struct{}
+	_        [B /* ERROR invalid array length B */ ]struct{}
+	_[A any] struct{}
+
+	B int
+)
diff --git a/src/internal/types/testdata/fixedbugs/issue43671.go b/src/internal/types/testdata/fixedbugs/issue43671.go
new file mode 100644
index 0000000..6879aec
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue43671.go
@@ -0,0 +1,58 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type C0 interface{ int }
+type C1 interface{ chan int }
+type C2 interface{ chan int | <-chan int }
+type C3 interface{ chan int | chan float32 }
+type C4 interface{ chan int | chan<- int }
+type C5[T any] interface{ ~chan T | <-chan T }
+
+func _[T any](ch T) {
+	<-ch // ERROR cannot receive from ch .* \(no core type\)
+}
+
+func _[T C0](ch T) {
+	<-ch // ERROR cannot receive from non-channel ch
+}
+
+func _[T C1](ch T) {
+	<-ch
+}
+
+func _[T C2](ch T) {
+	<-ch
+}
+
+func _[T C3](ch T) {
+	<-ch // ERROR cannot receive from ch .* \(no core type\)
+}
+
+func _[T C4](ch T) {
+	<-ch // ERROR cannot receive from send-only channel
+}
+
+func _[T C5[X], X any](ch T, x X) {
+	x = <-ch
+}
+
+// test case from issue, slightly modified
+type RecvChan[T any] interface {
+	~chan T | ~<-chan T
+}
+
+func _[T any, C RecvChan[T]](ch C) T {
+	return <-ch
+}
+
+func f[T any, C interface{ chan T }](ch C) T {
+	return <-ch
+}
+
+func _(ch chan int) {
+	var x int = f(ch) // test constraint type inference for this case
+	_ = x
+}
diff --git a/src/go/types/testdata/fixedbugs/issue44688.go b/src/internal/types/testdata/fixedbugs/issue44688.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue44688.go
rename to src/internal/types/testdata/fixedbugs/issue44688.go
diff --git a/src/go/types/testdata/fixedbugs/issue44799.go b/src/internal/types/testdata/fixedbugs/issue44799.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue44799.go
rename to src/internal/types/testdata/fixedbugs/issue44799.go
diff --git a/src/go/types/testdata/fixedbugs/issue45114.go b/src/internal/types/testdata/fixedbugs/issue45114.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue45114.go
rename to src/internal/types/testdata/fixedbugs/issue45114.go
diff --git a/src/go/types/testdata/fixedbugs/issue45548.go b/src/internal/types/testdata/fixedbugs/issue45548.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue45548.go
rename to src/internal/types/testdata/fixedbugs/issue45548.go
diff --git a/src/internal/types/testdata/fixedbugs/issue45550.go b/src/internal/types/testdata/fixedbugs/issue45550.go
new file mode 100644
index 0000000..498b1eb
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue45550.go
@@ -0,0 +1,10 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type Builder /* ERROR invalid recursive type */ [T interface{ struct{ Builder[T] } }] struct{}
+type myBuilder struct {
+	Builder[myBuilder]
+}
diff --git a/src/internal/types/testdata/fixedbugs/issue45635.go b/src/internal/types/testdata/fixedbugs/issue45635.go
new file mode 100644
index 0000000..af05ff0
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue45635.go
@@ -0,0 +1,31 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func main() {
+	some /* ERROR "undefined" */ [int, int]()
+}
+
+type N[T any] struct{}
+
+var _ N [] // ERROR expected type argument list
+
+type I interface {
+	~[]int
+}
+
+func _[T I](i, j int) {
+	var m map[int]int
+	_ = m[i, j /* ERROR "more than one index" */ ]
+
+	var a [3]int
+	_ = a[i, j /* ERROR "more than one index" */ ]
+
+	var s []int
+	_ = s[i, j /* ERROR "more than one index" */ ]
+
+	var t T
+	_ = t[i, j /* ERROR "more than one index" */ ]
+}
diff --git a/src/go/types/testdata/fixedbugs/issue45639.go b/src/internal/types/testdata/fixedbugs/issue45639.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue45639.go
rename to src/internal/types/testdata/fixedbugs/issue45639.go
diff --git a/src/internal/types/testdata/fixedbugs/issue45920.go b/src/internal/types/testdata/fixedbugs/issue45920.go
new file mode 100644
index 0000000..0a281c5
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue45920.go
@@ -0,0 +1,17 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func f1[T any, C chan T | <-chan T](ch C) {}
+
+func _(ch chan int)   { f1(ch) }
+func _(ch <-chan int) { f1(ch) }
+func _(ch chan<- int) { f1 /* ERROR chan<- int does not satisfy chan int \| <-chan int */ (ch) }
+
+func f2[T any, C chan T | chan<- T](ch C) {}
+
+func _(ch chan int)   { f2(ch) }
+func _(ch <-chan int) { f2 /* ERROR <-chan int does not satisfy chan int \| chan<- int */ (ch) }
+func _(ch chan<- int) { f2(ch) }
diff --git a/src/internal/types/testdata/fixedbugs/issue45985.go b/src/internal/types/testdata/fixedbugs/issue45985.go
new file mode 100644
index 0000000..ae04ce2
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue45985.go
@@ -0,0 +1,13 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package issue45985
+
+func app[S interface{ ~[]T }, T any](s S, e T) S {
+	return append(s, e)
+}
+
+func _() {
+	_ = app /* ERROR "int does not match" */ [int]
+}
diff --git a/src/go/types/testdata/fixedbugs/issue46090.go b/src/internal/types/testdata/fixedbugs/issue46090.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue46090.go
rename to src/internal/types/testdata/fixedbugs/issue46090.go
diff --git a/src/internal/types/testdata/fixedbugs/issue46275.go b/src/internal/types/testdata/fixedbugs/issue46275.go
new file mode 100644
index 0000000..0862d5b
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue46275.go
@@ -0,0 +1,26 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package issue46275
+
+type N[T any] struct {
+	*N[T]
+	t T
+}
+
+func (n *N[T]) Elem() T {
+	return n.t
+}
+
+type I interface {
+	Elem() string
+}
+
+func _() {
+	var n1 *N[string]
+	var _ I = n1
+	type NS N[string]
+	var n2 *NS
+	var _ I = n2
+}
diff --git a/src/go/types/testdata/fixedbugs/issue46403.go b/src/internal/types/testdata/fixedbugs/issue46403.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue46403.go
rename to src/internal/types/testdata/fixedbugs/issue46403.go
diff --git a/src/internal/types/testdata/fixedbugs/issue46404.go b/src/internal/types/testdata/fixedbugs/issue46404.go
new file mode 100644
index 0000000..e3c93f6
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue46404.go
@@ -0,0 +1,10 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package issue46404
+
+// TODO(gri) re-enable this test with matching errors
+//           between go/types and types2
+// Check that we don't type check t[_] as an instantiation.
+// type t [t /* type parameters must be named */ /* not a generic type */ [_]]_ // cannot use
diff --git a/src/internal/types/testdata/fixedbugs/issue46461.go b/src/internal/types/testdata/fixedbugs/issue46461.go
new file mode 100644
index 0000000..fce06f7
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue46461.go
@@ -0,0 +1,20 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+// test case 1
+type T /* ERROR invalid recursive type */ [U interface{ M() T[U] }] int
+
+type X int
+
+func (X) M() T[X] { return 0 }
+
+// test case 2
+type A /* ERROR invalid recursive type */ [T interface{ A[T] }] interface{}
+
+// test case 3
+type A2 /* ERROR invalid recursive type */ [U interface{ A2[U] }] interface{ M() A2[U] }
+
+type I interface{ A2[I]; M() A2[I] }
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue46583.go b/src/internal/types/testdata/fixedbugs/issue46583.go
similarity index 100%
rename from src/cmd/compile/internal/types2/testdata/fixedbugs/issue46583.go
rename to src/internal/types/testdata/fixedbugs/issue46583.go
diff --git a/src/go/types/testdata/fixedbugs/issue47031.go b/src/internal/types/testdata/fixedbugs/issue47031.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue47031.go
rename to src/internal/types/testdata/fixedbugs/issue47031.go
diff --git a/src/go/types/testdata/fixedbugs/issue47115.go b/src/internal/types/testdata/fixedbugs/issue47115.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue47115.go
rename to src/internal/types/testdata/fixedbugs/issue47115.go
diff --git a/src/go/types/testdata/fixedbugs/issue47127.go b/src/internal/types/testdata/fixedbugs/issue47127.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue47127.go
rename to src/internal/types/testdata/fixedbugs/issue47127.go
diff --git a/src/internal/types/testdata/fixedbugs/issue47411.go b/src/internal/types/testdata/fixedbugs/issue47411.go
new file mode 100644
index 0000000..33b169a
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue47411.go
@@ -0,0 +1,26 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func f[_ comparable]() {}
+func g[_ interface{interface{comparable; ~int|~string}}]() {}
+
+func _[P comparable,
+        Q interface{ comparable; ~int|~string },
+        R any,                               // not comparable
+        S interface{ comparable; ~func() },  // not comparable
+]() {
+        _ = f[int]
+        _ = f[P]
+        _ = f[Q]
+        _ = f[func /* ERROR does not satisfy comparable */ ()]
+        _ = f[R /* ERROR R does not satisfy comparable */ ]
+
+        _ = g[int]
+        _ = g[P /* ERROR P does not satisfy interface{interface{comparable; ~int \| ~string} */ ]
+        _ = g[Q]
+        _ = g[func /* ERROR func\(\) does not satisfy interface{interface{comparable; ~int \| ~string}} */ ()]
+        _ = g[R /* ERROR R does not satisfy interface{interface{comparable; ~int \| ~string} */ ]
+}
diff --git a/src/go/types/testdata/fixedbugs/issue47747.go b/src/internal/types/testdata/fixedbugs/issue47747.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue47747.go
rename to src/internal/types/testdata/fixedbugs/issue47747.go
diff --git a/src/internal/types/testdata/fixedbugs/issue47796.go b/src/internal/types/testdata/fixedbugs/issue47796.go
new file mode 100644
index 0000000..4c59106
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue47796.go
@@ -0,0 +1,33 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+// parameterized types with self-recursive constraints
+type (
+	T1 /* ERROR invalid recursive type */ [P T1[P]]                            interface{}
+	T2 /* ERROR invalid recursive type */ [P, Q T2[P, Q]]                      interface{}
+	T3[P T2[P, Q], Q interface{ ~string }] interface{}
+
+	T4a /* ERROR invalid recursive type */ [P T4a[P]]                                                        interface{ ~int }
+	T4b /* ERROR invalid recursive type */ [P T4b[int]]                                                      interface{ ~int }
+	T4c /* ERROR invalid recursive type */ [P T4c[string]] interface{ ~int }
+
+	// mutually recursive constraints
+	T5 /* ERROR invalid recursive type */ [P T6[P]] interface{ int }
+	T6[P T5[P]] interface{ int }
+)
+
+// verify that constraints are checked as expected
+var (
+	_ T1[int]
+	_ T2[int, string]
+	_ T3[int, string]
+)
+
+// test case from issue
+
+type Eq /* ERROR invalid recursive type */ [a Eq[a]] interface {
+	Equal(that a) bool
+}
diff --git a/src/internal/types/testdata/fixedbugs/issue47818.go b/src/internal/types/testdata/fixedbugs/issue47818.go
new file mode 100644
index 0000000..e9b0adb
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue47818.go
@@ -0,0 +1,61 @@
+// -lang=go1.17
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Parser accepts type parameters but the type checker
+// needs to report any operations that are not permitted
+// before Go 1.18.
+
+package p
+
+type T[P /* ERROR type parameter requires go1\.18 or later */ any /* ERROR predeclared any requires go1\.18 or later */] struct{}
+
+// for init (and main, but we're not in package main) we should only get one error
+func init[P /* ERROR func init must have no type parameters */ any /* ERROR predeclared any requires go1\.18 or later */]() {
+}
+func main[P /* ERROR type parameter requires go1\.18 or later */ any /* ERROR predeclared any requires go1\.18 or later */]() {
+}
+
+func f[P /* ERROR type parameter requires go1\.18 or later */ any /* ERROR predeclared any requires go1\.18 or later */](x P) {
+	var _ T[ /* ERROR type instantiation requires go1\.18 or later */ int]
+	var _ (T[ /* ERROR type instantiation requires go1\.18 or later */ int])
+	_ = T[ /* ERROR type instantiation requires go1\.18 or later */ int]{}
+	_ = T[ /* ERROR type instantiation requires go1\.18 or later */ int](struct{}{})
+}
+
+func (T[ /* ERROR type instantiation requires go1\.18 or later */ P]) g(x int) {
+	f[ /* ERROR function instantiation requires go1\.18 or later */ int](0)     // explicit instantiation
+	(f[ /* ERROR function instantiation requires go1\.18 or later */ int])(0)   // parentheses (different code path)
+	f( /* ERROR implicit function instantiation requires go1\.18 or later */ x) // implicit instantiation
+}
+
+type C1 interface {
+	comparable // ERROR predeclared comparable requires go1\.18 or later
+}
+
+type C2 interface {
+	comparable // ERROR predeclared comparable requires go1\.18 or later
+	int        // ERROR embedding non-interface type int requires go1\.18 or later
+	~ /* ERROR embedding interface element ~int requires go1\.18 or later */ int
+	int /* ERROR embedding interface element int \| ~string requires go1\.18 or later */ | ~string
+}
+
+type _ interface {
+	// errors for these were reported with their declaration
+	C1
+	C2
+}
+
+type (
+	_ comparable // ERROR predeclared comparable requires go1\.18 or later
+	// errors for these were reported with their declaration
+	_ C1
+	_ C2
+
+	_ = comparable // ERROR predeclared comparable requires go1\.18 or later
+	// errors for these were reported with their declaration
+	_ = C1
+	_ = C2
+)
diff --git a/src/go/types/testdata/fixedbugs/issue47887.go b/src/internal/types/testdata/fixedbugs/issue47887.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue47887.go
rename to src/internal/types/testdata/fixedbugs/issue47887.go
diff --git a/src/go/types/testdata/fixedbugs/issue47968.go b/src/internal/types/testdata/fixedbugs/issue47968.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue47968.go
rename to src/internal/types/testdata/fixedbugs/issue47968.go
diff --git a/src/go/types/testdata/fixedbugs/issue48008.go b/src/internal/types/testdata/fixedbugs/issue48008.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue48008.go
rename to src/internal/types/testdata/fixedbugs/issue48008.go
diff --git a/src/go/types/testdata/fixedbugs/issue48018.go b/src/internal/types/testdata/fixedbugs/issue48018.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue48018.go
rename to src/internal/types/testdata/fixedbugs/issue48018.go
diff --git a/src/go/types/testdata/fixedbugs/issue48048.go b/src/internal/types/testdata/fixedbugs/issue48048.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue48048.go
rename to src/internal/types/testdata/fixedbugs/issue48048.go
diff --git a/src/go/types/testdata/fixedbugs/issue48082.go b/src/internal/types/testdata/fixedbugs/issue48082.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue48082.go
rename to src/internal/types/testdata/fixedbugs/issue48082.go
diff --git a/src/go/types/testdata/fixedbugs/issue48083.go b/src/internal/types/testdata/fixedbugs/issue48083.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue48083.go
rename to src/internal/types/testdata/fixedbugs/issue48083.go
diff --git a/src/go/types/testdata/fixedbugs/issue48136.go b/src/internal/types/testdata/fixedbugs/issue48136.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue48136.go
rename to src/internal/types/testdata/fixedbugs/issue48136.go
diff --git a/src/go/types/testdata/fixedbugs/issue48234.go b/src/internal/types/testdata/fixedbugs/issue48234.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue48234.go
rename to src/internal/types/testdata/fixedbugs/issue48234.go
diff --git a/src/go/types/testdata/fixedbugs/issue48312.go b/src/internal/types/testdata/fixedbugs/issue48312.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue48312.go
rename to src/internal/types/testdata/fixedbugs/issue48312.go
diff --git a/src/go/types/testdata/fixedbugs/issue48472.go b/src/internal/types/testdata/fixedbugs/issue48472.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue48472.go
rename to src/internal/types/testdata/fixedbugs/issue48472.go
diff --git a/src/internal/types/testdata/fixedbugs/issue48529.go b/src/internal/types/testdata/fixedbugs/issue48529.go
new file mode 100644
index 0000000..d7a70b1
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue48529.go
@@ -0,0 +1,11 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type T /* ERROR invalid recursive type */ [U interface{ M() T[U, int] }] int
+
+type X int
+
+func (X) M() T[X] { return 0 }
diff --git a/src/internal/types/testdata/fixedbugs/issue48582.go b/src/internal/types/testdata/fixedbugs/issue48582.go
new file mode 100644
index 0000000..9e1d526
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue48582.go
@@ -0,0 +1,29 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type N /* ERROR invalid recursive type */ interface {
+	int | N
+}
+
+type A /* ERROR invalid recursive type */ interface {
+	int | B
+}
+
+type B interface {
+	int | A
+}
+
+type S /* ERROR invalid recursive type */ struct {
+	I // ERROR interface contains type constraints
+}
+
+type I interface {
+	int | S
+}
+
+type P interface {
+	*P // ERROR interface contains type constraints
+}
diff --git a/src/go/types/testdata/fixedbugs/issue48619.go b/src/internal/types/testdata/fixedbugs/issue48619.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue48619.go
rename to src/internal/types/testdata/fixedbugs/issue48619.go
diff --git a/src/go/types/testdata/fixedbugs/issue48656.go b/src/internal/types/testdata/fixedbugs/issue48656.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue48656.go
rename to src/internal/types/testdata/fixedbugs/issue48656.go
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue48695.go b/src/internal/types/testdata/fixedbugs/issue48695.go
similarity index 100%
rename from src/cmd/compile/internal/types2/testdata/fixedbugs/issue48695.go
rename to src/internal/types/testdata/fixedbugs/issue48695.go
diff --git a/src/go/types/testdata/fixedbugs/issue48703.go b/src/internal/types/testdata/fixedbugs/issue48703.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue48703.go
rename to src/internal/types/testdata/fixedbugs/issue48703.go
diff --git a/src/go/types/testdata/fixedbugs/issue48712.go b/src/internal/types/testdata/fixedbugs/issue48712.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue48712.go
rename to src/internal/types/testdata/fixedbugs/issue48712.go
diff --git a/src/internal/types/testdata/fixedbugs/issue48819.go b/src/internal/types/testdata/fixedbugs/issue48819.go
new file mode 100644
index 0000000..5d61803
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue48819.go
@@ -0,0 +1,15 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+import "unsafe"
+
+type T /* ERROR invalid recursive type: T refers to itself */ struct {
+	T
+}
+
+func _(t T) {
+	_ = unsafe.Sizeof(t) // should not go into infinite recursion here
+}
diff --git a/src/go/types/testdata/fixedbugs/issue48827.go b/src/internal/types/testdata/fixedbugs/issue48827.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue48827.go
rename to src/internal/types/testdata/fixedbugs/issue48827.go
diff --git a/src/internal/types/testdata/fixedbugs/issue48951.go b/src/internal/types/testdata/fixedbugs/issue48951.go
new file mode 100644
index 0000000..c94b027
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue48951.go
@@ -0,0 +1,21 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type (
+        A1[P any] [10]A1 /* ERROR invalid recursive type */ [P]
+        A2[P any] [10]A2 /* ERROR invalid recursive type */ [*P]
+        A3[P any] [10]*A3[P]
+
+        L1[P any] []L1[P]
+
+        S1[P any] struct{ f S1 /* ERROR invalid recursive type */ [P] }
+        S2[P any] struct{ f S2 /* ERROR invalid recursive type */ [*P] } // like example in issue
+        S3[P any] struct{ f *S3[P] }
+
+        I1[P any] interface{ I1 /* ERROR invalid recursive type */ [P] }
+        I2[P any] interface{ I2 /* ERROR invalid recursive type */ [*P] }
+        I3[P any] interface{ *I3 /* ERROR interface contains type constraints */ [P] }
+)
diff --git a/src/internal/types/testdata/fixedbugs/issue48962.go b/src/internal/types/testdata/fixedbugs/issue48962.go
new file mode 100644
index 0000000..05c681d
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue48962.go
@@ -0,0 +1,13 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type T0[P any] struct {
+	f P
+}
+
+type T1 /* ERROR invalid recursive type */ struct {
+	_ T0[T1]
+}
diff --git a/src/go/types/testdata/fixedbugs/issue48974.go b/src/internal/types/testdata/fixedbugs/issue48974.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue48974.go
rename to src/internal/types/testdata/fixedbugs/issue48974.go
diff --git a/src/go/types/testdata/fixedbugs/issue49003.go b/src/internal/types/testdata/fixedbugs/issue49003.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue49003.go
rename to src/internal/types/testdata/fixedbugs/issue49003.go
diff --git a/src/internal/types/testdata/fixedbugs/issue49005.go b/src/internal/types/testdata/fixedbugs/issue49005.go
new file mode 100644
index 0000000..5f551b9
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue49005.go
@@ -0,0 +1,31 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type T1 interface{ M() }
+
+func F1() T1
+
+var _ = F1().(*X1 /* ERROR undefined: X1 */)
+
+func _() {
+	switch F1().(type) {
+	case *X1 /* ERROR undefined: X1 */ :
+	}
+}
+
+type T2 interface{ M() }
+
+func F2() T2
+
+var _ = F2 /* ERROR impossible type assertion: F2\(\)\.\(\*X2\)\n\t\*X2 does not implement T2 \(missing method M\) */ ().(*X2)
+
+type X2 struct{}
+
+func _() {
+	switch F2().(type) {
+	case * /* ERROR impossible type switch case: \*X2\n\tF2\(\) \(value of type T2\) cannot have dynamic type \*X2 \(missing method M\) */ X2:
+	}
+}
diff --git a/src/internal/types/testdata/fixedbugs/issue49043.go b/src/internal/types/testdata/fixedbugs/issue49043.go
new file mode 100644
index 0000000..3971cf8
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue49043.go
@@ -0,0 +1,24 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+// The example from the issue.
+type (
+	N[P any] M /* ERROR invalid recursive type */ [P]
+	M[P any] N[P]
+)
+
+// A slightly more complicated case.
+type (
+	A[P any] B /* ERROR invalid recursive type */ [P]
+	B[P any] C[P]
+	C[P any] A[P]
+)
+
+// Confusing but valid (note that `type T *T` is valid).
+type (
+	N1[P any] *M1[P]
+	M1[P any] *N1[P]
+)
diff --git a/src/internal/types/testdata/fixedbugs/issue49112.go b/src/internal/types/testdata/fixedbugs/issue49112.go
new file mode 100644
index 0000000..dea2608
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue49112.go
@@ -0,0 +1,15 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func f[P int](P) {}
+
+func _() {
+        _ = f[int]
+        _ = f[[ /* ERROR \[\]int does not satisfy int */ ]int]
+
+        f(0)
+        f/* ERROR \[\]int does not satisfy int */ ([]int{})
+}
diff --git a/src/internal/types/testdata/fixedbugs/issue49179.go b/src/internal/types/testdata/fixedbugs/issue49179.go
new file mode 100644
index 0000000..2ddfa33
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue49179.go
@@ -0,0 +1,37 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func f1[P int | string]()            {}
+func f2[P ~int | string | float64]() {}
+func f3[P int](x P)                  {}
+
+type myInt int
+type myFloat float64
+
+func _() {
+	_ = f1[int]
+	_ = f1[myInt /* ERROR possibly missing ~ for int in int \| string */]
+	_ = f2[myInt]
+	_ = f2[myFloat /* ERROR possibly missing ~ for float64 in ~int \| string \| float64 */]
+	var x myInt
+	f3 /* ERROR myInt does not satisfy int \(possibly missing ~ for int in int\) */ (x)
+}
+
+// test case from the issue
+
+type SliceConstraint[T any] interface {
+	[]T
+}
+
+func Map[S SliceConstraint[E], E any](s S, f func(E) E) S {
+	return s
+}
+
+type MySlice []int
+
+func f(s MySlice) {
+	Map[MySlice /* ERROR MySlice does not satisfy SliceConstraint\[int\] \(possibly missing ~ for \[\]int in SliceConstraint\[int\]\) */, int](s, nil)
+}
diff --git a/src/go/types/testdata/fixedbugs/issue49242.go b/src/internal/types/testdata/fixedbugs/issue49242.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue49242.go
rename to src/internal/types/testdata/fixedbugs/issue49242.go
diff --git a/src/internal/types/testdata/fixedbugs/issue49247.go b/src/internal/types/testdata/fixedbugs/issue49247.go
new file mode 100644
index 0000000..5be6001
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue49247.go
@@ -0,0 +1,20 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type integer interface {
+	~int | ~int8 | ~int16 | ~int32 | ~int64 |
+		~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
+}
+
+func Add1024[T integer](s []T) {
+	for i, v := range s {
+		s[i] = v + 1024 // ERROR cannot convert 1024 \(untyped int constant\) to type T
+	}
+}
+
+func f[T interface{ int8 }]() {
+	println(T(1024 /* ERROR cannot convert 1024 \(untyped int value\) to type T */))
+}
diff --git a/src/internal/types/testdata/fixedbugs/issue49276.go b/src/internal/types/testdata/fixedbugs/issue49276.go
new file mode 100644
index 0000000..ab5794a
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue49276.go
@@ -0,0 +1,46 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+import "unsafe"
+
+type S /* ERROR invalid recursive type S */ struct {
+	_ [unsafe.Sizeof(s)]byte
+}
+
+var s S
+
+// Since f is a pointer, this case could be valid.
+// But it's pathological and not worth the expense.
+type T struct {
+	f *[unsafe.Sizeof(T /* ERROR invalid recursive type */ {})]int
+}
+
+// a mutually recursive case using unsafe.Sizeof
+type (
+	A1 struct {
+		_ [unsafe.Sizeof(B1{})]int
+	}
+
+	B1 struct {
+		_ [unsafe.Sizeof(A1 /* ERROR invalid recursive type */ {})]int
+	}
+)
+
+// a mutually recursive case using len
+type (
+	A2 struct {
+		f [len(B2{}.f)]int
+	}
+
+	B2 struct {
+		f [len(A2 /* ERROR invalid recursive type */ {}.f)]int
+	}
+)
+
+// test case from issue
+type a struct {
+	_ [42 - unsafe.Sizeof(a /* ERROR invalid recursive type */ {})]byte
+}
diff --git a/src/internal/types/testdata/fixedbugs/issue49296.go b/src/internal/types/testdata/fixedbugs/issue49296.go
new file mode 100644
index 0000000..98ad6f5
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue49296.go
@@ -0,0 +1,20 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func _[
+        T0 any,
+        T1 []int,
+        T2 ~float64 | ~complex128 | chan int,
+]() {
+        _ = T0(nil /* ERROR cannot convert nil to type T0 */ )
+        _ = T1(1 /* ERROR cannot convert 1 .* to type T1 */ )
+        _ = T2(2 /* ERROR cannot convert 2 .* to type T2 */ )
+}
+
+// test case from issue
+func f[T interface{[]int}]() {
+	_ = T(1 /* ERROR cannot convert */ )
+}
diff --git a/src/internal/types/testdata/fixedbugs/issue49439.go b/src/internal/types/testdata/fixedbugs/issue49439.go
new file mode 100644
index 0000000..b8ad495
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue49439.go
@@ -0,0 +1,26 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+import "unsafe"
+
+type T0 /* ERROR invalid recursive type */ [P T0[P]] struct{}
+
+type T1 /* ERROR invalid recursive type */ [P T2[P]] struct{}
+type T2[P T1[P]] struct{}
+
+type T3 /* ERROR invalid recursive type */ [P interface{ ~struct{ f T3[int] } }] struct{}
+
+// valid cycle in M
+type N[P M[P]] struct{}
+type M[Q any] struct { F *M[Q] }
+
+// "crazy" case
+type TC[P [unsafe.Sizeof(func() {
+        type T [P [unsafe.Sizeof(func(){})]byte] struct{}
+})]byte] struct{}
+
+// test case from issue
+type X /* ERROR invalid recursive type */ [T any, PT X[T]] interface{}
diff --git a/src/internal/types/testdata/fixedbugs/issue49482.go b/src/internal/types/testdata/fixedbugs/issue49482.go
new file mode 100644
index 0000000..2b9e748
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue49482.go
@@ -0,0 +1,26 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+// The following is OK, per the special handling for type literals discussed in issue #49482.
+type _[P *struct{}] struct{}
+type _[P *int,] int
+type _[P (*int),] int
+
+const P = 2 // declare P to avoid noisy 'undefined' errors below.
+
+// The following parse as invalid array types due to parsing ambiguitiues.
+type _ [P *int /* ERROR "int \(type\) is not an expression" */ ]int
+type _ [P /* ERROR non-function P */ (*int)]int
+
+// Adding a trailing comma or an enclosing interface resolves the ambiguity.
+type _[P *int,] int
+type _[P (*int),] int
+type _[P interface{*int}] int
+type _[P interface{(*int)}] int
+
+// The following parse correctly as valid generic types.
+type _[P *struct{} | int] struct{}
+type _[P *struct{} | ~int] struct{}
diff --git a/src/go/types/testdata/fixedbugs/issue49541.go b/src/internal/types/testdata/fixedbugs/issue49541.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue49541.go
rename to src/internal/types/testdata/fixedbugs/issue49541.go
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue49579.go b/src/internal/types/testdata/fixedbugs/issue49579.go
similarity index 100%
rename from src/cmd/compile/internal/types2/testdata/fixedbugs/issue49579.go
rename to src/internal/types/testdata/fixedbugs/issue49579.go
diff --git a/src/go/types/testdata/fixedbugs/issue49592.go b/src/internal/types/testdata/fixedbugs/issue49592.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue49592.go
rename to src/internal/types/testdata/fixedbugs/issue49592.go
diff --git a/src/go/types/testdata/fixedbugs/issue49602.go b/src/internal/types/testdata/fixedbugs/issue49602.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue49602.go
rename to src/internal/types/testdata/fixedbugs/issue49602.go
diff --git a/src/go/types/testdata/fixedbugs/issue49705.go b/src/internal/types/testdata/fixedbugs/issue49705.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue49705.go
rename to src/internal/types/testdata/fixedbugs/issue49705.go
diff --git a/src/go/types/testdata/fixedbugs/issue49735.go b/src/internal/types/testdata/fixedbugs/issue49735.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue49735.go
rename to src/internal/types/testdata/fixedbugs/issue49735.go
diff --git a/src/internal/types/testdata/fixedbugs/issue49739.go b/src/internal/types/testdata/fixedbugs/issue49739.go
new file mode 100644
index 0000000..7feb563
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue49739.go
@@ -0,0 +1,23 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Verify that we get an empty type set (not just an error)
+// when using an invalid ~A.
+
+package p
+
+type A int
+type C interface {
+	~ /* ERROR invalid use of ~ */ A
+}
+
+func f[_ C]()              {}
+func g[_ interface{ C }]() {}
+func h[_ C | int]()        {}
+
+func _() {
+	_ = f[int /* ERROR cannot satisfy C \(empty type set\) */]
+	_ = g[int /* ERROR cannot satisfy interface{C} \(empty type set\) */]
+	_ = h[int]
+}
diff --git a/src/go/types/testdata/fixedbugs/issue49864.go b/src/internal/types/testdata/fixedbugs/issue49864.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue49864.go
rename to src/internal/types/testdata/fixedbugs/issue49864.go
diff --git a/src/go/types/testdata/fixedbugs/issue50259.go b/src/internal/types/testdata/fixedbugs/issue50259.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue50259.go
rename to src/internal/types/testdata/fixedbugs/issue50259.go
diff --git a/src/go/types/testdata/fixedbugs/issue50276.go b/src/internal/types/testdata/fixedbugs/issue50276.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue50276.go
rename to src/internal/types/testdata/fixedbugs/issue50276.go
diff --git a/src/go/types/testdata/fixedbugs/issue50281.go b/src/internal/types/testdata/fixedbugs/issue50281.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue50281.go
rename to src/internal/types/testdata/fixedbugs/issue50281.go
diff --git a/src/go/types/testdata/fixedbugs/issue50321.go b/src/internal/types/testdata/fixedbugs/issue50321.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue50321.go
rename to src/internal/types/testdata/fixedbugs/issue50321.go
diff --git a/src/internal/types/testdata/fixedbugs/issue50372.go b/src/internal/types/testdata/fixedbugs/issue50372.go
new file mode 100644
index 0000000..4c9b65a
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue50372.go
@@ -0,0 +1,27 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func _(s []int) {
+        var i, j, k, l int
+        _, _, _, _ = i, j, k, l
+
+        for range s {}
+        for i = range s {}
+        for i, j = range s {}
+        for i, j, k /* ERROR range clause permits at most two iteration variables|at most 2 expressions */ = range s {}
+        for i, j, k, l /* ERROR range clause permits at most two iteration variables|at most 2 expressions */ = range s {}
+}
+
+func _(s chan int) {
+        var i, j, k, l int
+        _, _, _, _ = i, j, k, l
+
+        for range s {}
+        for i = range s {}
+        for i, j /* ERROR range over .* permits only one iteration variable */ = range s {}
+        for i, j, k /* ERROR range over .* permits only one iteration variable|at most 2 expressions */ = range s {}
+        for i, j, k, l /* ERROR range over .* permits only one iteration variable|at most 2 expressions */ = range s {}
+}
diff --git a/src/internal/types/testdata/fixedbugs/issue50417.go b/src/internal/types/testdata/fixedbugs/issue50417.go
new file mode 100644
index 0000000..69ebf31
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue50417.go
@@ -0,0 +1,68 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Field accesses through type parameters are disabled
+// until we have a more thorough understanding of the
+// implications on the spec. See issue #51576.
+
+package p
+
+type Sf struct {
+        f int
+}
+
+func f0[P Sf](p P) {
+        _ = p.f // ERROR p\.f undefined
+        p.f /* ERROR p\.f undefined */ = 0
+}
+
+func f0t[P ~struct{f int}](p P) {
+        _ = p.f // ERROR p\.f undefined
+        p.f /* ERROR p\.f undefined */ = 0
+}
+
+var _ = f0[Sf]
+var _ = f0t[Sf]
+
+var _ = f0[Sm /* ERROR does not satisfy */ ]
+var _ = f0t[Sm /* ERROR does not satisfy */ ]
+
+func f1[P interface{ Sf; m() }](p P) {
+        _ = p.f // ERROR p\.f undefined
+        p.f /* ERROR p\.f undefined */ = 0
+        p.m()
+}
+
+var _ = f1[Sf /* ERROR missing method m */ ]
+var _ = f1[Sm /* ERROR does not satisfy */ ]
+
+type Sm struct {}
+
+func (Sm) m() {}
+
+type Sfm struct {
+        f int
+}
+
+func (Sfm) m() {}
+
+func f2[P interface{ Sfm; m() }](p P) {
+        _ = p.f // ERROR p\.f undefined
+        p.f /* ERROR p\.f undefined */ = 0
+        p.m()
+}
+
+var _ = f2[Sfm]
+
+// special case: core type is a named pointer type
+
+type PSfm *Sfm
+
+func f3[P interface{ PSfm }](p P) {
+        _ = p.f // ERROR p\.f undefined
+        p.f /* ERROR p\.f undefined */ = 0
+        p.m /* ERROR type P has no field or method m */ ()
+}
+
+var _ = f3[PSfm]
diff --git a/src/go/types/testdata/fixedbugs/issue50426.go b/src/internal/types/testdata/fixedbugs/issue50426.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue50426.go
rename to src/internal/types/testdata/fixedbugs/issue50426.go
diff --git a/src/go/types/testdata/fixedbugs/issue50427.go b/src/internal/types/testdata/fixedbugs/issue50427.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue50427.go
rename to src/internal/types/testdata/fixedbugs/issue50427.go
diff --git a/src/go/types/testdata/fixedbugs/issue50450.go b/src/internal/types/testdata/fixedbugs/issue50450.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue50450.go
rename to src/internal/types/testdata/fixedbugs/issue50450.go
diff --git a/src/go/types/testdata/fixedbugs/issue50516.go b/src/internal/types/testdata/fixedbugs/issue50516.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue50516.go
rename to src/internal/types/testdata/fixedbugs/issue50516.go
diff --git a/src/internal/types/testdata/fixedbugs/issue50646.go b/src/internal/types/testdata/fixedbugs/issue50646.go
new file mode 100644
index 0000000..ed7261c
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue50646.go
@@ -0,0 +1,28 @@
+// -oldComparableSemantics
+
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func f1[_ comparable]()              {}
+func f2[_ interface{ comparable }]() {}
+
+type T interface{ m() }
+
+func _[P comparable, Q ~int, R any]() {
+	_ = f1[int]
+	_ = f1[T /* ERROR T does not satisfy comparable */ ]
+	_ = f1[any /* ERROR any does not satisfy comparable */ ]
+	_ = f1[P]
+	_ = f1[Q]
+	_ = f1[R /* ERROR R does not satisfy comparable */]
+
+	_ = f2[int]
+	_ = f2[T /* ERROR T does not satisfy comparable */ ]
+	_ = f2[any /* ERROR any does not satisfy comparable */ ]
+	_ = f2[P]
+	_ = f2[Q]
+	_ = f2[R /* ERROR R does not satisfy comparable */]
+}
diff --git a/src/go/types/testdata/fixedbugs/issue50729.go b/src/internal/types/testdata/fixedbugs/issue50729.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue50729.go
rename to src/internal/types/testdata/fixedbugs/issue50729.go
diff --git a/src/go/types/testdata/fixedbugs/issue50755.go b/src/internal/types/testdata/fixedbugs/issue50755.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue50755.go
rename to src/internal/types/testdata/fixedbugs/issue50755.go
diff --git a/src/go/types/testdata/fixedbugs/issue50779.go b/src/internal/types/testdata/fixedbugs/issue50779.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue50779.go
rename to src/internal/types/testdata/fixedbugs/issue50779.go
diff --git a/src/internal/types/testdata/fixedbugs/issue50782.go b/src/internal/types/testdata/fixedbugs/issue50782.go
new file mode 100644
index 0000000..0e7b712
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue50782.go
@@ -0,0 +1,47 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Field accesses through type parameters are disabled
+// until we have a more thorough understanding of the
+// implications on the spec. See issue #51576.
+
+package p
+
+// The first example from the issue.
+type Numeric interface {
+	~int | ~int8 | ~int16 | ~int32 | ~int64
+}
+
+// numericAbs matches numeric types with an Abs method.
+type numericAbs[T Numeric] interface {
+	~struct{ Value T }
+	Abs() T
+}
+
+// AbsDifference computes the absolute value of the difference of
+// a and b, where the absolute value is determined by the Abs method.
+func absDifference[T numericAbs[T /* ERROR T does not satisfy Numeric */]](a, b T) T {
+	// Field accesses are not permitted for now. Keep an error so
+	// we can find and fix this code once the situation changes.
+	return a.Value // ERROR a\.Value undefined
+	// TODO: The error below should probably be positioned on the '-'.
+	// d := a /* ERROR "invalid operation: operator - not defined" */ .Value - b.Value
+	// return d.Abs()
+}
+
+// The second example from the issue.
+type T[P int] struct{ f P }
+
+func _[P T[P /* ERROR "P does not satisfy int" */ ]]() {}
+
+// Additional tests
+func _[P T[T /* ERROR "T\[P\] does not satisfy int" */ [P /* ERROR "P does not satisfy int" */ ]]]() {}
+func _[P T[Q /* ERROR "Q does not satisfy int" */ ], Q T[P /* ERROR "P does not satisfy int" */ ]]() {}
+func _[P T[Q], Q int]() {}
+
+type C[P comparable] struct{ f P }
+func _[P C[C[P]]]() {}
+func _[P C[C /* ERROR "C\[Q\] does not satisfy comparable" */ [Q /* ERROR "Q does not satisfy comparable" */]], Q func()]() {}
+func _[P [10]C[P]]() {}
+func _[P struct{ f C[C[P]]}]() {}
diff --git a/src/go/types/testdata/fixedbugs/issue50816.go b/src/internal/types/testdata/fixedbugs/issue50816.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue50816.go
rename to src/internal/types/testdata/fixedbugs/issue50816.go
diff --git a/src/go/types/testdata/fixedbugs/issue50833.go b/src/internal/types/testdata/fixedbugs/issue50833.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue50833.go
rename to src/internal/types/testdata/fixedbugs/issue50833.go
diff --git a/src/go/types/testdata/fixedbugs/issue50912.go b/src/internal/types/testdata/fixedbugs/issue50912.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue50912.go
rename to src/internal/types/testdata/fixedbugs/issue50912.go
diff --git a/src/go/types/testdata/fixedbugs/issue50918.go b/src/internal/types/testdata/fixedbugs/issue50918.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue50918.go
rename to src/internal/types/testdata/fixedbugs/issue50918.go
diff --git a/src/internal/types/testdata/fixedbugs/issue50929.go b/src/internal/types/testdata/fixedbugs/issue50929.go
new file mode 100644
index 0000000..45e0751
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue50929.go
@@ -0,0 +1,68 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file is tested when running "go test -run Manual"
+// without source arguments. Use for one-off debugging.
+
+package p
+
+import "fmt"
+
+type F[A, B any] int
+
+func G[A, B any](F[A, B]) {
+}
+
+func _() {
+	// TODO(gri) only report one error below (issue #50932)
+	var x F /* ERROR got 1 arguments but 2 type parameters */ [int]
+	G(x /* ERROR does not match */)
+}
+
+// test case from issue
+// (lots of errors but doesn't crash anymore)
+
+type RC[G any, RG any] interface {
+	~[]RG
+}
+
+type RG[G any] struct{}
+
+type RSC[G any] []*RG[G]
+
+type M[Rc RC[G, RG], G any, RG any] struct {
+	Fn func(Rc)
+}
+
+type NFn[Rc RC[G, RG], G any, RG any] func(Rc)
+
+func NC[Rc RC[G, RG], G any, RG any](nFn NFn[Rc, G, RG]) {
+	var empty Rc
+	nFn(empty)
+}
+
+func NSG[G any](c RSC[G]) {
+	fmt.Println(c)
+}
+
+func MMD[Rc RC /* ERROR got 1 arguments */ [RG], RG any, G any]() M /* ERROR got 2 arguments */ [Rc, RG] {
+
+	var nFn NFn /* ERROR got 2 arguments */ [Rc, RG]
+
+	var empty Rc
+	switch any(empty).(type) {
+	case BC /* ERROR undefined: BC */ :
+
+	case RSC[G]:
+		nFn = NSG /* ERROR cannot use NSG\[G\] */ [G]
+	}
+
+	return M /* ERROR got 2 arguments */ [Rc, RG]{
+		Fn: func(rc Rc) {
+			NC(nFn /* ERROR does not match */ )
+		},
+	}
+
+	return M /* ERROR got 2 arguments */ [Rc, RG]{}
+}
diff --git a/src/go/types/testdata/fixedbugs/issue50965.go b/src/internal/types/testdata/fixedbugs/issue50965.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue50965.go
rename to src/internal/types/testdata/fixedbugs/issue50965.go
diff --git a/src/internal/types/testdata/fixedbugs/issue51025.go b/src/internal/types/testdata/fixedbugs/issue51025.go
new file mode 100644
index 0000000..207b06e
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue51025.go
@@ -0,0 +1,38 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+var _ interface{ m() } = struct /* ERROR m is a field, not a method */ {
+	m func()
+}{}
+
+var _ interface{ m() } = & /* ERROR m is a field, not a method */ struct {
+	m func()
+}{}
+
+var _ interface{ M() } = struct /* ERROR missing method M */ {
+	m func()
+}{}
+
+var _ interface{ M() } = & /* ERROR missing method M */ struct {
+	m func()
+}{}
+
+// test case from issue
+type I interface{ m() }
+type T struct{ m func() }
+type M struct{}
+
+func (M) m() {}
+
+func _() {
+	var t T
+	var m M
+	var i I
+
+	i = m
+	i = t // ERROR m is a field, not a method
+	_ = i
+}
diff --git a/src/go/types/testdata/fixedbugs/issue51048.go b/src/internal/types/testdata/fixedbugs/issue51048.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue51048.go
rename to src/internal/types/testdata/fixedbugs/issue51048.go
diff --git a/src/go/types/testdata/fixedbugs/issue51145.go b/src/internal/types/testdata/fixedbugs/issue51145.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue51145.go
rename to src/internal/types/testdata/fixedbugs/issue51145.go
diff --git a/src/go/types/testdata/fixedbugs/issue51158.go b/src/internal/types/testdata/fixedbugs/issue51158.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue51158.go
rename to src/internal/types/testdata/fixedbugs/issue51158.go
diff --git a/src/go/types/testdata/fixedbugs/issue51229.go b/src/internal/types/testdata/fixedbugs/issue51229.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue51229.go
rename to src/internal/types/testdata/fixedbugs/issue51229.go
diff --git a/src/go/types/testdata/fixedbugs/issue51232.go b/src/internal/types/testdata/fixedbugs/issue51232.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue51232.go
rename to src/internal/types/testdata/fixedbugs/issue51232.go
diff --git a/src/go/types/testdata/fixedbugs/issue51233.go b/src/internal/types/testdata/fixedbugs/issue51233.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue51233.go
rename to src/internal/types/testdata/fixedbugs/issue51233.go
diff --git a/src/internal/types/testdata/fixedbugs/issue51257.go b/src/internal/types/testdata/fixedbugs/issue51257.go
new file mode 100644
index 0000000..be4b81f
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue51257.go
@@ -0,0 +1,48 @@
+// -oldComparableSemantics
+
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func f[_ comparable]() {}
+
+type S1 struct{ x int }
+type S2 struct{ x any }
+type S3 struct{ x [10]interface{ m() } }
+
+func _[P1 comparable, P2 S2]() {
+	_ = f[S1]
+	_ = f[S2 /* ERROR S2 does not satisfy comparable */ ]
+	_ = f[S3 /* ERROR S3 does not satisfy comparable */ ]
+
+	type L1 struct { x P1 }
+	type L2 struct { x P2 }
+	_ = f[L1]
+	_ = f[L2 /* ERROR L2 does not satisfy comparable */ ]
+}
+
+
+// example from issue
+
+type Set[T comparable] map[T]struct{}
+
+func NewSetFromSlice[T comparable](items []T) *Set[T] {
+	s := Set[T]{}
+
+	for _, item := range items {
+		s[item] = struct{}{}
+	}
+
+	return &s
+}
+
+type T struct{ x any }
+
+func main() {
+	NewSetFromSlice /* ERROR T does not satisfy comparable */ ([]T{
+		{"foo"},
+		{5},
+	})
+}
diff --git a/src/internal/types/testdata/fixedbugs/issue51335.go b/src/internal/types/testdata/fixedbugs/issue51335.go
new file mode 100644
index 0000000..35135cd
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue51335.go
@@ -0,0 +1,16 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type S1 struct{}
+type S2 struct{}
+
+func _[P *S1|*S2]() {
+	_= []P{{ /* ERROR invalid composite literal element type P \(no core type\) */ }}
+}
+
+func _[P *S1|S1]() {
+	_= []P{{ /* ERROR invalid composite literal element type P \(no core type\) */ }}
+}
diff --git a/src/go/types/testdata/fixedbugs/issue51339.go b/src/internal/types/testdata/fixedbugs/issue51339.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue51339.go
rename to src/internal/types/testdata/fixedbugs/issue51339.go
diff --git a/src/go/types/testdata/fixedbugs/issue51360.go b/src/internal/types/testdata/fixedbugs/issue51360.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue51360.go
rename to src/internal/types/testdata/fixedbugs/issue51360.go
diff --git a/src/internal/types/testdata/fixedbugs/issue51376.go b/src/internal/types/testdata/fixedbugs/issue51376.go
new file mode 100644
index 0000000..3801d68
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue51376.go
@@ -0,0 +1,24 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type Map map[string]int
+
+func f[M ~map[K]V, K comparable, V any](M) {}
+func g[M map[K]V, K comparable, V any](M) {}
+
+func _[M1 ~map[K]V, M2 map[K]V, K comparable, V any]() {
+        var m1 M1
+        f(m1)
+        g /* ERROR M1 does not satisfy map\[K\]V */ (m1) // M1 has tilde
+
+        var m2 M2
+        f(m2)
+        g(m2) // M1 does not have tilde
+
+        var m3 Map
+        f(m3)
+        g /* ERROR Map does not satisfy map\[string\]int */ (m3) // M in g does not have tilde
+}
diff --git a/src/go/types/testdata/fixedbugs/issue51386.go b/src/internal/types/testdata/fixedbugs/issue51386.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue51386.go
rename to src/internal/types/testdata/fixedbugs/issue51386.go
diff --git a/src/go/types/testdata/fixedbugs/issue51437.go b/src/internal/types/testdata/fixedbugs/issue51437.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue51437.go
rename to src/internal/types/testdata/fixedbugs/issue51437.go
diff --git a/src/internal/types/testdata/fixedbugs/issue51472.go b/src/internal/types/testdata/fixedbugs/issue51472.go
new file mode 100644
index 0000000..a0f9e9c
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue51472.go
@@ -0,0 +1,54 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func _[T comparable](x T) {
+        _ = x == x
+}
+
+func _[T interface{interface{comparable}}](x T) {
+        _ = x == x
+}
+
+func _[T interface{comparable; interface{comparable}}](x T) {
+        _ = x == x
+}
+
+func _[T interface{comparable; ~int}](x T) {
+        _ = x == x
+}
+
+func _[T interface{comparable; ~[]byte}](x T) {
+        _ = x /* ERROR empty type set */ == x
+}
+
+// TODO(gri) The error message here should be better. See issue #51525.
+func _[T interface{comparable; ~int; ~string}](x T) {
+        _ = x /* ERROR empty type set */ == x
+}
+
+// TODO(gri) The error message here should be better. See issue #51525.
+func _[T interface{~int; ~string}](x T) {
+        _ = x /* ERROR empty type set */ == x
+}
+
+func _[T interface{comparable; interface{~int}; interface{int|float64}}](x T) {
+        _ = x == x
+}
+
+func _[T interface{interface{comparable; ~int}; interface{~float64; comparable; m()}}](x T) {
+        _ = x /* ERROR empty type set */ == x
+}
+
+// test case from issue
+
+func f[T interface{comparable; []byte|string}](x T) {
+        _ = x == x
+}
+
+func _(s []byte) {
+	f /* ERROR \[\]byte does not satisfy interface{comparable; \[\]byte \| string} */ (s)
+        _ = f[[ /* ERROR does not satisfy */ ]byte]
+}
diff --git a/src/internal/types/testdata/fixedbugs/issue51509.go b/src/internal/types/testdata/fixedbugs/issue51509.go
new file mode 100644
index 0000000..64f5d7e
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue51509.go
@@ -0,0 +1,7 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type T /* ERROR invalid recursive type */ T.x
diff --git a/src/internal/types/testdata/fixedbugs/issue51525.go b/src/internal/types/testdata/fixedbugs/issue51525.go
new file mode 100644
index 0000000..5856905
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue51525.go
@@ -0,0 +1,20 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func _[T interface {
+	int
+	string
+}](x T) {
+	_ = x /* ERROR empty type set */ == x
+	_ = x /* ERROR empty type set */ + x
+	<-x /* ERROR empty type set */
+	x <- /* ERROR empty type set */ 0
+	close(x /* ERROR empty type set */)
+}
+
+func _[T interface{ int | []byte }](x T) {
+	_ = x /* ERROR incomparable types in type set */ == x
+}
diff --git a/src/go/types/testdata/fixedbugs/issue51533.go b/src/internal/types/testdata/fixedbugs/issue51533.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue51533.go
rename to src/internal/types/testdata/fixedbugs/issue51533.go
diff --git a/src/go/types/testdata/fixedbugs/issue51578.go b/src/internal/types/testdata/fixedbugs/issue51578.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue51578.go
rename to src/internal/types/testdata/fixedbugs/issue51578.go
diff --git a/src/go/types/testdata/fixedbugs/issue51593.go b/src/internal/types/testdata/fixedbugs/issue51593.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue51593.go
rename to src/internal/types/testdata/fixedbugs/issue51593.go
diff --git a/src/go/types/testdata/fixedbugs/issue51607.go b/src/internal/types/testdata/fixedbugs/issue51607.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue51607.go
rename to src/internal/types/testdata/fixedbugs/issue51607.go
diff --git a/src/go/types/testdata/fixedbugs/issue51610.go b/src/internal/types/testdata/fixedbugs/issue51610.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue51610.go
rename to src/internal/types/testdata/fixedbugs/issue51610.go
diff --git a/src/go/types/testdata/fixedbugs/issue51616.go b/src/internal/types/testdata/fixedbugs/issue51616.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue51616.go
rename to src/internal/types/testdata/fixedbugs/issue51616.go
diff --git a/src/internal/types/testdata/fixedbugs/issue51658.go b/src/internal/types/testdata/fixedbugs/issue51658.go
new file mode 100644
index 0000000..f32051c
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue51658.go
@@ -0,0 +1,43 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This test checks syntax errors which differ between
+// go/parser and the syntax package.
+// TODO: consolidate eventually
+
+package p
+
+type F { // ERROR expected type|type declaration
+	float64
+} // ERROR expected declaration|non-declaration statement
+
+func _[T F | int](x T) {
+	_ = x == 0 // don't crash when recording type of 0
+}
+
+// test case from issue
+
+type FloatType { // ERROR expected type|type declaration
+	float32 | float64
+} // ERROR expected declaration|non-declaration statement
+
+type IntegerType interface {
+	int8 | int16 | int32 | int64 | int |
+		uint8 | uint16 | uint32 | uint64 | uint
+}
+
+type ComplexType interface {
+	complex64 | complex128
+}
+
+type Number interface {
+	FloatType | IntegerType | ComplexType
+}
+
+func GetDefaultNumber[T Number](value, defaultValue T) T {
+	if value == 0 {
+		return defaultValue
+	}
+	return value
+}
diff --git a/src/internal/types/testdata/fixedbugs/issue51877.go b/src/internal/types/testdata/fixedbugs/issue51877.go
new file mode 100644
index 0000000..c93242a
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue51877.go
@@ -0,0 +1,18 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type S struct {
+	f1 int
+	f2 bool
+}
+
+var (
+	_ = S{0}                    /* ERROR too few values in struct literal */
+	_ = struct{ f1, f2 int }{0} /* ERROR too few values in struct literal */
+
+	_ = S{0, true, "foo" /* ERROR too many values in struct literal */}
+	_ = struct{ f1, f2 int }{0, 1, 2 /* ERROR too many values in struct literal */}
+)
diff --git a/src/go/types/testdata/fixedbugs/issue52031.go b/src/internal/types/testdata/fixedbugs/issue52031.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue52031.go
rename to src/internal/types/testdata/fixedbugs/issue52031.go
diff --git a/src/go/types/testdata/fixedbugs/issue52401.go b/src/internal/types/testdata/fixedbugs/issue52401.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue52401.go
rename to src/internal/types/testdata/fixedbugs/issue52401.go
diff --git a/src/go/types/testdata/fixedbugs/issue52529.go b/src/internal/types/testdata/fixedbugs/issue52529.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue52529.go
rename to src/internal/types/testdata/fixedbugs/issue52529.go
diff --git a/src/internal/types/testdata/fixedbugs/issue52698.go b/src/internal/types/testdata/fixedbugs/issue52698.go
new file mode 100644
index 0000000..ca794f8
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue52698.go
@@ -0,0 +1,62 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+// correctness check: ensure that cycles through generic instantiations are detected
+type T[P any] struct {
+	_ P
+}
+
+type S /* ERROR invalid recursive type */ struct {
+	_ T[S]
+}
+
+// simplified test 1
+
+var _ A1[A1[string]]
+
+type A1[P any] struct {
+	_ B1[P]
+}
+
+type B1[P any] struct {
+	_ P
+}
+
+// simplified test 2
+var _ B2[A2]
+
+type A2 struct {
+	_ B2[string]
+}
+
+type B2[P any] struct {
+	_ C2[P]
+}
+
+type C2[P any] struct {
+	_ P
+}
+
+// test case from issue
+type T23 interface {
+	~struct {
+		Field0 T13[T15]
+	}
+}
+
+type T1[P1 interface {
+}] struct {
+	Field2 P1
+}
+
+type T13[P2 interface {
+}] struct {
+	Field2 T1[P2]
+}
+
+type T15 struct {
+	Field0 T13[string]
+}
diff --git a/src/internal/types/testdata/fixedbugs/issue52915.go b/src/internal/types/testdata/fixedbugs/issue52915.go
new file mode 100644
index 0000000..6c43386
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue52915.go
@@ -0,0 +1,23 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+import "unsafe"
+
+type T[P any] struct {
+	T /* ERROR   invalid recursive type */ [P]
+}
+
+func _[P any]() {
+	_ = unsafe.Sizeof(T[int]{})
+	_ = unsafe.Sizeof(struct{ T[int] }{})
+
+	_ = unsafe.Sizeof(T[P]{})
+	_ = unsafe.Sizeof(struct{ T[P] }{})
+}
+
+// TODO(gri) This is a follow-on error due to T[int] being invalid.
+//           We should try to avoid it.
+const _ = unsafe /* ERROR not constant */ .Sizeof(T[int]{})
diff --git a/src/internal/types/testdata/fixedbugs/issue53358.go b/src/internal/types/testdata/fixedbugs/issue53358.go
new file mode 100644
index 0000000..774136f
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue53358.go
@@ -0,0 +1,19 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type A struct{}
+
+func (*A) m() int { return 0 }
+
+var _ = A.m /* ERROR invalid method expression A\.m \(needs pointer receiver \(\*A\)\.m\) */ ()
+var _ = (*A).m(nil)
+
+type B struct{ A }
+
+var _ = B.m // ERROR invalid method expression B\.m \(needs pointer receiver \(\*B\)\.m\)
+var _ = (*B).m
+
+var _ = struct{ A }.m // ERROR invalid method expression struct{A}\.m \(needs pointer receiver \(\*struct{A}\)\.m\)
diff --git a/src/internal/types/testdata/fixedbugs/issue54280.go b/src/internal/types/testdata/fixedbugs/issue54280.go
new file mode 100644
index 0000000..e83e1a1
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue54280.go
@@ -0,0 +1,7 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+const C = 912_345_678_901_234_567_890_123_456_789_012_345_678_901_234_567_890_912_345_678_901_234_567_890_123_456_789_012_345_678_901_234_567_890_912_345_678_901_234_567_890_123_456_789_012_345_678_901_234_567_890_912 // ERROR constant overflow
diff --git a/src/internal/types/testdata/fixedbugs/issue54405.go b/src/internal/types/testdata/fixedbugs/issue54405.go
new file mode 100644
index 0000000..611d830
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue54405.go
@@ -0,0 +1,16 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test that we don't see spurious errors for ==
+// for values with invalid types due to prior errors.
+
+package p
+
+var x struct {
+	f *NotAType /* ERROR undefined */
+}
+var _ = x.f == nil // no error expected here
+
+var y *NotAType  /* ERROR undefined */
+var _ = y == nil // no error expected here
diff --git a/src/internal/types/testdata/fixedbugs/issue56351.go b/src/internal/types/testdata/fixedbugs/issue56351.go
new file mode 100644
index 0000000..d7d04b0
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue56351.go
@@ -0,0 +1,11 @@
+// -lang=go1.20
+
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func _(s []int) {
+	clear /* ERROR clear requires go1\.21 or later */ (s)
+}
diff --git a/src/internal/types/testdata/fixedbugs/issue56425.go b/src/internal/types/testdata/fixedbugs/issue56425.go
new file mode 100644
index 0000000..d85733f
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue56425.go
@@ -0,0 +1,8 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+const s float32 = 0
+var _ = 0 << s
diff --git a/src/internal/types/testdata/fixedbugs/issue56665.go b/src/internal/types/testdata/fixedbugs/issue56665.go
new file mode 100644
index 0000000..11786b9
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue56665.go
@@ -0,0 +1,30 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+// Example from the issue:
+type A[T any] interface {
+	*T
+}
+
+type B[T any] interface {
+	B /* ERROR invalid recursive type */ [*T]
+}
+
+type C[T any, U B[U]] interface {
+	*T
+}
+
+// Simplified reproducer:
+type X[T any] interface {
+	X /* ERROR invalid recursive type */ [*T]
+}
+
+var _ X[int]
+
+// A related example that doesn't go through interfaces.
+type A2[P any] [10]A2 /* ERROR invalid recursive type */ [*P]
+
+var _ A2[int]
diff --git a/src/internal/types/testdata/fixedbugs/issue57155.go b/src/internal/types/testdata/fixedbugs/issue57155.go
new file mode 100644
index 0000000..ec9fb2b
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue57155.go
@@ -0,0 +1,14 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func f[P *Q, Q any](p P, q Q) {
+	func() {
+		_ = f[P]
+		f(p, q)
+		f[P](p, q)
+		f[P, Q](p, q)
+	}()
+}
diff --git a/src/internal/types/testdata/fixedbugs/issue57160.go b/src/internal/types/testdata/fixedbugs/issue57160.go
new file mode 100644
index 0000000..446d019
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue57160.go
@@ -0,0 +1,10 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func _(x *int) {
+	_ = 0 < x // ERROR "invalid operation"
+	_ = x < 0 // ERROR "invalid operation"
+}
diff --git a/src/internal/types/testdata/fixedbugs/issue57486.go b/src/internal/types/testdata/fixedbugs/issue57486.go
new file mode 100644
index 0000000..43ba1b0
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue57486.go
@@ -0,0 +1,29 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type C1 interface {
+	comparable
+}
+
+type C2 interface {
+	comparable
+	[2]any | int
+}
+
+func G1[T C1](t T) { _ = t == t }
+func G2[T C2](t T) { _ = t == t }
+
+func F1[V [2]any](v V) {
+	_ = G1[V /* ERROR "V does not satisfy comparable" */]
+	_ = G1[[2]any]
+	_ = G1[int]
+}
+
+func F2[V [2]any](v V) {
+	_ = G2[V /* ERROR "V does not satisfy C2" */]
+	_ = G2[[ /* ERROR "\[2\]any does not satisfy C2 \(C2 mentions \[2\]any, but \[2\]any is not in the type set of C2\)" */ 2]any]
+	_ = G2[int]
+}
diff --git a/src/internal/types/testdata/fixedbugs/issue57500.go b/src/internal/types/testdata/fixedbugs/issue57500.go
new file mode 100644
index 0000000..abdcb5e
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue57500.go
@@ -0,0 +1,16 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type C interface {
+	comparable
+	[2]any | int
+}
+
+func f[T C]() {}
+
+func _() {
+	_ = f[[ /* ERROR \[2\]any does not satisfy C \(C mentions \[2\]any, but \[2\]any is not in the type set of C\) */ 2]any]
+}
diff --git a/src/internal/types/testdata/fixedbugs/issue57522.go b/src/internal/types/testdata/fixedbugs/issue57522.go
new file mode 100644
index 0000000..d83e5b2
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue57522.go
@@ -0,0 +1,24 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+// A simplified version of the code in the original report.
+type S[T any] struct{}
+var V = S[any]{}
+func (fs *S[T]) M(V.M /* ERROR "V.M is not a type" */) {}
+
+// Other minimal reproducers.
+type S1[T any] V1.M /* ERROR "V1.M is not a type" */
+type V1 = S1[any]
+
+type S2[T any] struct{}
+type V2 = S2[any]
+func (fs *S2[T]) M(x V2.M /* ERROR "V2.M is not a type" */ ) {}
+
+// The following still panics, as the selector is reached from check.expr
+// rather than check.typexpr. TODO(rfindley): fix this.
+// type X[T any] int
+// func (X[T]) M(x [X[int].M]int) {}
+
diff --git a/src/go/types/testdata/fixedbugs/issue6977.go b/src/internal/types/testdata/fixedbugs/issue6977.go
similarity index 100%
rename from src/go/types/testdata/fixedbugs/issue6977.go
rename to src/internal/types/testdata/fixedbugs/issue6977.go
diff --git a/src/internal/types/testdata/spec/assignability.go b/src/internal/types/testdata/spec/assignability.go
new file mode 100644
index 0000000..0ab8eb3
--- /dev/null
+++ b/src/internal/types/testdata/spec/assignability.go
@@ -0,0 +1,264 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package assignability
+
+// See the end of this package for the declarations
+// of the types and variables used in these tests.
+
+// "x's type is identical to T"
+func _[TP any](X TP) {
+	b = b
+	a = a
+	l = l
+	s = s
+	p = p
+	f = f
+	i = i
+	m = m
+	c = c
+	d = d
+
+	B = B
+	A = A
+	L = L
+	S = S
+	P = P
+	F = F
+	I = I
+	M = M
+	C = C
+	D = D
+	X = X
+}
+
+// "x's type V and T have identical underlying types
+// and at least one of V or T is not a named type."
+// (here a named type is a type with a name)
+func _[TP1, TP2 Interface](X1 TP1, X2 TP2) {
+	b = B // ERROR cannot use B .* as int value
+	a = A
+	l = L
+	s = S
+	p = P
+	f = F
+	i = I
+	m = M
+	c = C
+	d = D
+
+	B = b // ERROR cannot use b .* as Basic value
+	A = a
+	L = l
+	S = s
+	P = p
+	F = f
+	I = i
+	M = m
+	C = c
+	D = d
+	X1 = i  // ERROR cannot use i .* as TP1 value
+	X1 = X2 // ERROR cannot use X2 .* as TP1 value
+}
+
+// "T is an interface type and x implements T and T is not a type parameter"
+func _[TP Interface](X TP) {
+	i = d // ERROR missing method m
+	i = D
+	i = X
+	X = i // ERROR cannot use i .* as TP value
+}
+
+// "x is a bidirectional channel value, T is a channel type, x's type V and T have identical element types, and at least one of V or T is not a named type"
+// (here a named type is a type with a name)
+type (
+	_SendChan = chan<- int
+	_RecvChan = <-chan int
+
+	SendChan _SendChan
+	RecvChan _RecvChan
+)
+
+func _[
+	_CC ~_Chan,
+	_SC ~_SendChan,
+	_RC ~_RecvChan,
+
+	CC Chan,
+	SC SendChan,
+	RC RecvChan,
+]() {
+	var (
+		_ _SendChan = c
+		_ _RecvChan = c
+		_ _Chan     = c
+
+		_ _SendChan = C
+		_ _RecvChan = C
+		_ _Chan     = C
+
+		_ SendChan = c
+		_ RecvChan = c
+		_ Chan     = c
+
+		_ SendChan = C // ERROR cannot use C .* as SendChan value
+		_ RecvChan = C // ERROR cannot use C .* as RecvChan value
+		_ Chan     = C
+		_ Chan     = make /* ERROR cannot use make\(chan Basic\) .* as Chan value */ (chan Basic)
+	)
+
+	var (
+		_ _CC = C // ERROR cannot use C .* as _CC value
+		_ _SC = C // ERROR cannot use C .* as _SC value
+		_ _RC = C // ERROR cannot use C .* as _RC value
+
+		_ CC = _CC /* ERROR cannot use _CC\(nil\) .* as CC value */ (nil)
+		_ SC = _CC /* ERROR cannot use _CC\(nil\) .* as SC value */ (nil)
+		_ RC = _CC /* ERROR cannot use _CC\(nil\) .* as RC value */ (nil)
+
+		_ CC = C // ERROR cannot use C .* as CC value
+		_ SC = C // ERROR cannot use C .* as SC value
+		_ RC = C // ERROR cannot use C .* as RC value
+	)
+}
+
+// "x's type V is not a named type and T is a type parameter, and x is assignable to each specific type in T's type set."
+func _[
+	TP0 any,
+	TP1 ~_Chan,
+	TP2 ~chan int | ~chan byte,
+]() {
+	var (
+		_ TP0 = c // ERROR cannot use c .* as TP0 value
+		_ TP0 = C // ERROR cannot use C .* as TP0 value
+		_ TP1 = c
+		_ TP1 = C // ERROR cannot use C .* as TP1 value
+		_ TP2 = c // ERROR .* cannot assign chan int to chan byte
+	)
+}
+
+// "x's type V is a type parameter and T is not a named type, and values x' of each specific type in V's type set are assignable to T."
+func _[
+	TP0 Interface,
+	TP1 ~_Chan,
+	TP2 ~chan int | ~chan byte,
+](X0 TP0, X1 TP1, X2 TP2) {
+	i = X0
+	I = X0
+	c = X1
+	C = X1 // ERROR cannot use X1 .* as Chan value
+	c = X2 // ERROR .* cannot assign chan byte \(in TP2\) to chan int
+}
+
+// "x is the predeclared identifier nil and T is a pointer, function, slice, map, channel, or interface type"
+func _[TP Interface](X TP) {
+	b = nil // ERROR cannot use nil
+	a = nil // ERROR cannot use nil
+	l = nil
+	s = nil // ERROR cannot use nil
+	p = nil
+	f = nil
+	i = nil
+	m = nil
+	c = nil
+	d = nil // ERROR cannot use nil
+
+	B = nil // ERROR cannot use nil
+	A = nil // ERROR cannot use nil
+	L = nil
+	S = nil // ERROR cannot use nil
+	P = nil
+	F = nil
+	I = nil
+	M = nil
+	C = nil
+	D = nil // ERROR cannot use nil
+	X = nil // ERROR cannot use nil
+}
+
+// "x is an untyped constant representable by a value of type T"
+func _[
+	Int8 ~int8,
+	Int16 ~int16,
+	Int32 ~int32,
+	Int64 ~int64,
+	Int8_16 ~int8 | ~int16,
+](
+	i8 Int8,
+	i16 Int16,
+	i32 Int32,
+	i64 Int64,
+	i8_16 Int8_16,
+) {
+	b = 42
+	b = 42.0
+	// etc.
+
+	i8 = -1 << 7
+	i8 = 1<<7 - 1
+	i16 = -1 << 15
+	i16 = 1<<15 - 1
+	i32 = -1 << 31
+	i32 = 1<<31 - 1
+	i64 = -1 << 63
+	i64 = 1<<63 - 1
+
+	i8_16 = -1 << 7
+	i8_16 = 1<<7 - 1
+	i8_16 = - /* ERROR cannot use .* as Int8_16 */ 1 << 15
+	i8_16 = 1 /* ERROR cannot use .* as Int8_16 */ <<15 - 1
+}
+
+// proto-types for tests
+
+type (
+	_Basic     = int
+	_Array     = [10]int
+	_Slice     = []int
+	_Struct    = struct{ f int }
+	_Pointer   = *int
+	_Func      = func(x int) string
+	_Interface = interface{ m() int }
+	_Map       = map[string]int
+	_Chan      = chan int
+
+	Basic     _Basic
+	Array     _Array
+	Slice     _Slice
+	Struct    _Struct
+	Pointer   _Pointer
+	Func      _Func
+	Interface _Interface
+	Map       _Map
+	Chan      _Chan
+	Defined   _Struct
+)
+
+func (Defined) m() int
+
+// proto-variables for tests
+
+var (
+	b _Basic
+	a _Array
+	l _Slice
+	s _Struct
+	p _Pointer
+	f _Func
+	i _Interface
+	m _Map
+	c _Chan
+	d _Struct
+
+	B Basic
+	A Array
+	L Slice
+	S Struct
+	P Pointer
+	F Func
+	I Interface
+	M Map
+	C Chan
+	D Defined
+)
diff --git a/src/internal/types/testdata/spec/comparable.go b/src/internal/types/testdata/spec/comparable.go
new file mode 100644
index 0000000..f407c35
--- /dev/null
+++ b/src/internal/types/testdata/spec/comparable.go
@@ -0,0 +1,26 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func f1[_ comparable]()              {}
+func f2[_ interface{ comparable }]() {}
+
+type T interface{ m() }
+
+func _[P comparable, Q ~int, R any]() {
+	_ = f1[int]
+	_ = f1[T /* T does satisfy comparable */]
+	_ = f1[any /* any does satisfy comparable */]
+	_ = f1[P]
+	_ = f1[Q]
+	_ = f1[R /* ERROR R does not satisfy comparable */]
+
+	_ = f2[int]
+	_ = f2[T /* T does satisfy comparable */]
+	_ = f2[any /* any does satisfy comparable */]
+	_ = f2[P]
+	_ = f2[Q]
+	_ = f2[R /* ERROR R does not satisfy comparable */]
+}
diff --git a/src/internal/types/testdata/spec/comparable1.19.go b/src/internal/types/testdata/spec/comparable1.19.go
new file mode 100644
index 0000000..dc1c5fa
--- /dev/null
+++ b/src/internal/types/testdata/spec/comparable1.19.go
@@ -0,0 +1,28 @@
+// -lang=go1.19
+
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func f1[_ comparable]()              {}
+func f2[_ interface{ comparable }]() {}
+
+type T interface{ m() }
+
+func _[P comparable, Q ~int, R any]() {
+	_ = f1[int]
+	_ = f1[T /* ERROR T to satisfy comparable requires go1\.20 or later */]
+	_ = f1[any /* ERROR any to satisfy comparable requires go1\.20 or later */]
+	_ = f1[P]
+	_ = f1[Q]
+	_ = f1[R /* ERROR R does not satisfy comparable */]
+
+	_ = f2[int]
+	_ = f2[T /* ERROR T to satisfy comparable requires go1\.20 or later */]
+	_ = f2[any /* ERROR any to satisfy comparable requires go1\.20 or later */]
+	_ = f2[P]
+	_ = f2[Q]
+	_ = f2[R /* ERROR R does not satisfy comparable */]
+}
diff --git a/src/internal/types/testdata/spec/comparisons.go b/src/internal/types/testdata/spec/comparisons.go
new file mode 100644
index 0000000..886e78c
--- /dev/null
+++ b/src/internal/types/testdata/spec/comparisons.go
@@ -0,0 +1,120 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package comparisons
+
+type (
+	B int // basic type representative
+	A [10]func()
+	L []byte
+	S struct{ f []byte }
+	P *S
+	F func()
+	I interface{}
+	M map[string]int
+	C chan int
+)
+
+var (
+	b B
+	a A
+	l L
+	s S
+	p P
+	f F
+	i I
+	m M
+	c C
+)
+
+func _() {
+	_ = nil == nil // ERROR operator == not defined on untyped nil
+	_ = b == b
+	_ = a /* ERROR \[10\]func\(\) cannot be compared */ == a
+	_ = l /* ERROR slice can only be compared to nil */ == l
+	_ = s /* ERROR struct containing \[\]byte cannot be compared */ == s
+	_ = p == p
+	_ = f /* ERROR func can only be compared to nil */ == f
+	_ = i == i
+	_ = m /* ERROR map can only be compared to nil */ == m
+	_ = c == c
+
+	_ = b == nil /* ERROR mismatched types */
+	_ = a == nil /* ERROR mismatched types */
+	_ = l == nil
+	_ = s == nil /* ERROR mismatched types */
+	_ = p == nil
+	_ = f == nil
+	_ = i == nil
+	_ = m == nil
+	_ = c == nil
+
+	_ = nil /* ERROR operator < not defined on untyped nil */ < nil
+	_ = b < b
+	_ = a /* ERROR operator < not defined on array */ < a
+	_ = l /* ERROR operator < not defined on slice */ < l
+	_ = s /* ERROR operator < not defined on struct */ < s
+	_ = p /* ERROR operator < not defined on pointer */ < p
+	_ = f /* ERROR operator < not defined on func */ < f
+	_ = i /* ERROR operator < not defined on interface */ < i
+	_ = m /* ERROR operator < not defined on map */ < m
+	_ = c /* ERROR operator < not defined on chan */ < c
+}
+
+func _[
+	B int,
+	A [10]func(),
+	L []byte,
+	S struct{ f []byte },
+	P *S,
+	F func(),
+	I interface{},
+	J comparable,
+	M map[string]int,
+	C chan int,
+](
+	b B,
+	a A,
+	l L,
+	s S,
+	p P,
+	f F,
+	i I,
+	j J,
+	m M,
+	c C,
+) {
+	_ = b == b
+	_ = a /* ERROR incomparable types in type set */ == a
+	_ = l /* ERROR incomparable types in type set */ == l
+	_ = s /* ERROR incomparable types in type set */ == s
+	_ = p == p
+	_ = f /* ERROR incomparable types in type set */ == f
+	_ = i /* ERROR incomparable types in type set */ == i
+	_ = j == j
+	_ = m /* ERROR incomparable types in type set */ == m
+	_ = c == c
+
+	_ = b == nil /* ERROR mismatched types */
+	_ = a == nil /* ERROR mismatched types */
+	_ = l == nil
+	_ = s == nil /* ERROR mismatched types */
+	_ = p == nil
+	_ = f == nil
+	_ = i == nil /* ERROR mismatched types */
+	_ = j == nil /* ERROR mismatched types */
+	_ = m == nil
+	_ = c == nil
+
+	_ = b < b
+	_ = a /* ERROR type parameter A is not comparable with < */ < a
+	_ = l /* ERROR type parameter L is not comparable with < */ < l
+	_ = s /* ERROR type parameter S is not comparable with < */ < s
+	_ = p /* ERROR type parameter P is not comparable with < */ < p
+	_ = f /* ERROR type parameter F is not comparable with < */ < f
+	_ = i /* ERROR type parameter I is not comparable with < */ < i
+	_ = j /* ERROR type parameter J is not comparable with < */ < j
+	_ = m /* ERROR type parameter M is not comparable with < */ < m
+	_ = c /* ERROR type parameter C is not comparable with < */ < c
+}
diff --git a/src/internal/types/testdata/spec/conversions.go b/src/internal/types/testdata/spec/conversions.go
new file mode 100644
index 0000000..fc014fc
--- /dev/null
+++ b/src/internal/types/testdata/spec/conversions.go
@@ -0,0 +1,208 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package conversions
+
+import "unsafe"
+
+// constant conversions
+
+func _[T ~byte]() T { return 255 }
+func _[T ~byte]() T { return 256 /* ERROR cannot use 256 .* as T value */ }
+
+func _[T ~byte]() {
+	const _ = T /* ERROR T\(0\) .* is not constant */ (0)
+	var _ T = 255
+	var _ T = 256 // ERROR cannot use 256 .* as T value
+}
+
+func _[T ~string]() T                { return T('a') }
+func _[T ~int | ~string]() T         { return T('a') }
+func _[T ~byte | ~int | ~string]() T { return T(256 /* ERROR cannot convert 256 .* to type T */) }
+
+// implicit conversions never convert to string
+func _[T ~string]() {
+	var _ string = 0 // ERROR cannot use .* as string value
+	var _ T = 0      // ERROR cannot use .* as T value
+}
+
+// failing const conversions of constants to type parameters report a cause
+func _[
+	T1 any,
+	T2 interface{ m() },
+	T3 ~int | ~float64 | ~bool,
+	T4 ~int | ~string,
+]() {
+	_ = T1(0 /* ERROR cannot convert 0 .* to type T1: T1 does not contain specific types */)
+	_ = T2(1 /* ERROR cannot convert 1 .* to type T2: T2 does not contain specific types */)
+	_ = T3(2 /* ERROR cannot convert 2 .* to type T3: cannot convert 2 .* to type bool \(in T3\) */)
+	_ = T4(3.14 /* ERROR cannot convert 3.14 .* to type T4: cannot convert 3.14 .* to type int \(in T4\) */)
+}
+
+// "x is assignable to T"
+// - tested via assignability tests
+
+// "x's type and T have identical underlying types if tags are ignored"
+
+func _[X ~int, T ~int](x X) T { return T(x) }
+func _[X struct {
+	f int "foo"
+}, T struct {
+	f int "bar"
+}](x X) T {
+	return T(x)
+}
+
+type Foo struct {
+	f int "foo"
+}
+type Bar struct {
+	f int "bar"
+}
+type Far struct{ f float64 }
+
+func _[X Foo, T Bar](x X) T       { return T(x) }
+func _[X Foo | Bar, T Bar](x X) T { return T(x) }
+func _[X Foo, T Foo | Bar](x X) T { return T(x) }
+func _[X Foo, T Far](x X) T {
+	return T(x /* ERROR cannot convert x \(variable of type X constrained by Foo\) to type T: cannot convert Foo \(in X\) to type Far \(in T\) */)
+}
+
+// "x's type and T are unnamed pointer types and their pointer base types
+// have identical underlying types if tags are ignored"
+
+func _[X ~*Foo, T ~*Bar](x X) T         { return T(x) }
+func _[X ~*Foo | ~*Bar, T ~*Bar](x X) T { return T(x) }
+func _[X ~*Foo, T ~*Foo | ~*Bar](x X) T { return T(x) }
+func _[X ~*Foo, T ~*Far](x X) T {
+	return T(x /* ERROR cannot convert x \(variable of type X constrained by ~\*Foo\) to type T: cannot convert \*Foo \(in X\) to type \*Far \(in T\) */)
+}
+
+// Verify that the defined types in constraints are considered for the rule above.
+
+type (
+	B  int
+	C  int
+	X0 *B
+	T0 *C
+)
+
+func _(x X0) T0           { return T0(x /* ERROR cannot convert */) } // non-generic reference
+func _[X X0, T T0](x X) T { return T(x /* ERROR cannot convert */) }
+func _[T T0](x X0) T      { return T(x /* ERROR cannot convert */) }
+func _[X X0](x X) T0      { return T0(x /* ERROR cannot convert */) }
+
+// "x's type and T are both integer or floating point types"
+
+func _[X Integer, T Integer](x X) T  { return T(x) }
+func _[X Unsigned, T Integer](x X) T { return T(x) }
+func _[X Float, T Integer](x X) T    { return T(x) }
+
+func _[X Integer, T Unsigned](x X) T  { return T(x) }
+func _[X Unsigned, T Unsigned](x X) T { return T(x) }
+func _[X Float, T Unsigned](x X) T    { return T(x) }
+
+func _[X Integer, T Float](x X) T  { return T(x) }
+func _[X Unsigned, T Float](x X) T { return T(x) }
+func _[X Float, T Float](x X) T    { return T(x) }
+
+func _[X, T Integer | Unsigned | Float](x X) T { return T(x) }
+func _[X, T Integer | ~string](x X) T {
+	return T(x /* ERROR cannot convert x \(variable of type X constrained by Integer \| ~string\) to type T: cannot convert string \(in X\) to type int \(in T\) */)
+}
+
+// "x's type and T are both complex types"
+
+func _[X, T Complex](x X) T { return T(x) }
+func _[X, T Float | Complex](x X) T {
+	return T(x /* ERROR cannot convert x \(variable of type X constrained by Float \| Complex\) to type T: cannot convert float32 \(in X\) to type complex64 \(in T\) */)
+}
+
+// "x is an integer or a slice of bytes or runes and T is a string type"
+
+type myInt int
+type myString string
+
+func _[T ~string](x int) T      { return T(x) }
+func _[T ~string](x myInt) T    { return T(x) }
+func _[X Integer](x X) string   { return string(x) }
+func _[X Integer](x X) myString { return myString(x) }
+func _[X Integer](x X) *string {
+	return (*string)(x /* ERROR cannot convert x \(variable of type X constrained by Integer\) to type \*string: cannot convert int \(in X\) to type \*string */)
+}
+
+func _[T ~string](x []byte) T                           { return T(x) }
+func _[T ~string](x []rune) T                           { return T(x) }
+func _[X ~[]byte, T ~string](x X) T                     { return T(x) }
+func _[X ~[]rune, T ~string](x X) T                     { return T(x) }
+func _[X Integer | ~[]byte | ~[]rune, T ~string](x X) T { return T(x) }
+func _[X Integer | ~[]byte | ~[]rune, T ~*string](x X) T {
+	return T(x /* ERROR cannot convert x \(variable of type X constrained by Integer \| ~\[\]byte \| ~\[\]rune\) to type T: cannot convert int \(in X\) to type \*string \(in T\) */)
+}
+
+// "x is a string and T is a slice of bytes or runes"
+
+func _[T ~[]byte](x string) T { return T(x) }
+func _[T ~[]rune](x string) T { return T(x) }
+func _[T ~[]rune](x *string) T {
+	return T(x /* ERROR cannot convert x \(variable of type \*string\) to type T: cannot convert \*string to type \[\]rune \(in T\) */)
+}
+
+func _[X ~string, T ~[]byte](x X) T           { return T(x) }
+func _[X ~string, T ~[]rune](x X) T           { return T(x) }
+func _[X ~string, T ~[]byte | ~[]rune](x X) T { return T(x) }
+func _[X ~*string, T ~[]byte | ~[]rune](x X) T {
+	return T(x /* ERROR cannot convert x \(variable of type X constrained by ~\*string\) to type T: cannot convert \*string \(in X\) to type \[\]byte \(in T\) */)
+}
+
+// package unsafe:
+// "any pointer or value of underlying type uintptr can be converted into a unsafe.Pointer"
+
+type myUintptr uintptr
+
+func _[X ~uintptr](x X) unsafe.Pointer  { return unsafe.Pointer(x) }
+func _[T unsafe.Pointer](x myUintptr) T { return T(x) }
+func _[T unsafe.Pointer](x int64) T {
+	return T(x /* ERROR cannot convert x \(variable of type int64\) to type T: cannot convert int64 to type unsafe\.Pointer \(in T\) */)
+}
+
+// "and vice versa"
+
+func _[T ~uintptr](x unsafe.Pointer) T  { return T(x) }
+func _[X unsafe.Pointer](x X) uintptr   { return uintptr(x) }
+func _[X unsafe.Pointer](x X) myUintptr { return myUintptr(x) }
+func _[X unsafe.Pointer](x X) int64 {
+	return int64(x /* ERROR cannot convert x \(variable of type X constrained by unsafe\.Pointer\) to type int64: cannot convert unsafe\.Pointer \(in X\) to type int64 */)
+}
+
+// "x is a slice, T is an array or pointer-to-array type,
+// and the slice and array types have identical element types."
+
+func _[X ~[]E, T ~[10]E, E any](x X) T  { return T(x) }
+func _[X ~[]E, T ~*[10]E, E any](x X) T { return T(x) }
+
+// ----------------------------------------------------------------------------
+// The following declarations can be replaced by the exported types of the
+// constraints package once all builders support importing interfaces with
+// type constraints.
+
+type Signed interface {
+	~int | ~int8 | ~int16 | ~int32 | ~int64
+}
+
+type Unsigned interface {
+	~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
+}
+
+type Integer interface {
+	Signed | Unsigned
+}
+
+type Float interface {
+	~float32 | ~float64
+}
+
+type Complex interface {
+	~complex64 | ~complex128
+}
diff --git a/src/internal/types/testdata/spec/oldcomparable.go b/src/internal/types/testdata/spec/oldcomparable.go
new file mode 100644
index 0000000..081d972
--- /dev/null
+++ b/src/internal/types/testdata/spec/oldcomparable.go
@@ -0,0 +1,28 @@
+// -oldComparableSemantics
+
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func f1[_ comparable]()              {}
+func f2[_ interface{ comparable }]() {}
+
+type T interface{ m() }
+
+func _[P comparable, Q ~int, R any]() {
+	_ = f1[int]
+	_ = f1[T /* ERROR T does not satisfy comparable */]
+	_ = f1[any /* ERROR any does not satisfy comparable */]
+	_ = f1[P]
+	_ = f1[Q]
+	_ = f1[R /* ERROR R does not satisfy comparable */]
+
+	_ = f2[int]
+	_ = f2[T /* ERROR T does not satisfy comparable */]
+	_ = f2[any /* ERROR any does not satisfy comparable */]
+	_ = f2[P]
+	_ = f2[Q]
+	_ = f2[R /* ERROR R does not satisfy comparable */]
+}
diff --git a/src/internal/xcoff/ar.go b/src/internal/xcoff/ar.go
index 0fb410f..2b432d5 100644
--- a/src/internal/xcoff/ar.go
+++ b/src/internal/xcoff/ar.go
@@ -123,7 +123,7 @@
 	}
 
 	var fhdr bigarFileHeader
-	if _, err := sr.Seek(0, os.SEEK_SET); err != nil {
+	if _, err := sr.Seek(0, io.SeekStart); err != nil {
 		return nil, err
 	}
 	if err := binary.Read(sr, binary.BigEndian, &fhdr); err != nil {
@@ -151,7 +151,7 @@
 		// The member header is normally 2 bytes larger. But it's easier
 		// to read the name if the header is read without _ar_nam.
 		// However, AIAFMAG must be read afterward.
-		if _, err := sr.Seek(off, os.SEEK_SET); err != nil {
+		if _, err := sr.Seek(off, io.SeekStart); err != nil {
 			return nil, err
 		}
 
@@ -183,7 +183,7 @@
 		fileoff := off + AR_HSZ_BIG + namlen
 		if fileoff&1 != 0 {
 			fileoff++
-			if _, err := sr.Seek(1, os.SEEK_CUR); err != nil {
+			if _, err := sr.Seek(1, io.SeekCurrent); err != nil {
 				return nil, err
 			}
 		}
diff --git a/src/internal/xcoff/file.go b/src/internal/xcoff/file.go
index 05e4fd5..e859de9 100644
--- a/src/internal/xcoff/file.go
+++ b/src/internal/xcoff/file.go
@@ -9,6 +9,7 @@
 	"debug/dwarf"
 	"encoding/binary"
 	"fmt"
+	"internal/saferio"
 	"io"
 	"os"
 	"strings"
@@ -167,7 +168,7 @@
 	f.TargetMachine = magic
 
 	// Read XCOFF file header
-	if _, err := sr.Seek(0, os.SEEK_SET); err != nil {
+	if _, err := sr.Seek(0, io.SeekStart); err != nil {
 		return nil, err
 	}
 	var nscns uint16
@@ -204,7 +205,7 @@
 
 	// Read string table (located right after symbol table).
 	offset := symptr + uint64(nsyms)*SYMESZ
-	if _, err := sr.Seek(int64(offset), os.SEEK_SET); err != nil {
+	if _, err := sr.Seek(int64(offset), io.SeekStart); err != nil {
 		return nil, err
 	}
 	// The first 4 bytes contain the length (in bytes).
@@ -213,17 +214,15 @@
 		return nil, err
 	}
 	if l > 4 {
-		if _, err := sr.Seek(int64(offset), os.SEEK_SET); err != nil {
+		st, err := saferio.ReadDataAt(sr, uint64(l), int64(offset))
+		if err != nil {
 			return nil, err
 		}
-		f.StringTable = make([]byte, l)
-		if _, err := io.ReadFull(sr, f.StringTable); err != nil {
-			return nil, err
-		}
+		f.StringTable = st
 	}
 
 	// Read section headers
-	if _, err := sr.Seek(int64(hdrsz)+int64(opthdr), os.SEEK_SET); err != nil {
+	if _, err := sr.Seek(int64(hdrsz)+int64(opthdr), io.SeekStart); err != nil {
 		return nil, err
 	}
 	f.Sections = make([]*Section, nscns)
@@ -269,7 +268,7 @@
 	var idxToSym = make(map[int]*Symbol)
 
 	// Read symbol table
-	if _, err := sr.Seek(int64(symptr), os.SEEK_SET); err != nil {
+	if _, err := sr.Seek(int64(symptr), io.SeekStart); err != nil {
 		return nil, err
 	}
 	f.Symbols = make([]*Symbol, 0)
@@ -284,6 +283,9 @@
 				return nil, err
 			}
 			numaux = int(se.Nnumaux)
+			if numaux < 0 {
+				return nil, fmt.Errorf("malformed symbol table, invalid number of aux symbols")
+			}
 			sym.SectionNumber = int(se.Nscnum)
 			sym.StorageClass = int(se.Nsclass)
 			sym.Value = uint64(se.Nvalue)
@@ -304,6 +306,9 @@
 				return nil, err
 			}
 			numaux = int(se.Nnumaux)
+			if numaux < 0 {
+				return nil, fmt.Errorf("malformed symbol table, invalid number of aux symbols")
+			}
 			sym.SectionNumber = int(se.Nscnum)
 			sym.StorageClass = int(se.Nsclass)
 			sym.Value = se.Nvalue
@@ -355,7 +360,7 @@
 
 		// Read csect auxiliary entry (by convention, it is the last).
 		if !needAuxFcn {
-			if _, err := sr.Seek(int64(numaux-1)*SYMESZ, os.SEEK_CUR); err != nil {
+			if _, err := sr.Seek(int64(numaux-1)*SYMESZ, io.SeekCurrent); err != nil {
 				return nil, err
 			}
 		}
@@ -382,7 +387,7 @@
 		f.Symbols = append(f.Symbols, sym)
 	skip:
 		i += numaux // Skip auxiliary entries
-		if _, err := sr.Seek(int64(numaux)*SYMESZ, os.SEEK_CUR); err != nil {
+		if _, err := sr.Seek(int64(numaux)*SYMESZ, io.SeekCurrent); err != nil {
 			return nil, err
 		}
 	}
@@ -397,7 +402,7 @@
 		if sect.Relptr == 0 {
 			continue
 		}
-		if _, err := sr.Seek(int64(sect.Relptr), os.SEEK_SET); err != nil {
+		if _, err := sr.Seek(int64(sect.Relptr), io.SeekStart); err != nil {
 			return nil, err
 		}
 		for i := uint32(0); i < sect.Nreloc; i++ {
@@ -508,7 +513,7 @@
 // Library name pattern is either path/base/member or base/member
 func (f *File) readImportIDs(s *Section) ([]string, error) {
 	// Read loader header
-	if _, err := s.sr.Seek(0, os.SEEK_SET); err != nil {
+	if _, err := s.sr.Seek(0, io.SeekStart); err != nil {
 		return nil, err
 	}
 	var istlen uint32
@@ -534,7 +539,7 @@
 	}
 
 	// Read loader import file ID table
-	if _, err := s.sr.Seek(int64(impoff), os.SEEK_SET); err != nil {
+	if _, err := s.sr.Seek(int64(impoff), io.SeekStart); err != nil {
 		return nil, err
 	}
 	table := make([]byte, istlen)
@@ -577,7 +582,7 @@
 		return nil, nil
 	}
 	// Read loader header
-	if _, err := s.sr.Seek(0, os.SEEK_SET); err != nil {
+	if _, err := s.sr.Seek(0, io.SeekStart); err != nil {
 		return nil, err
 	}
 	var stlen uint32
@@ -606,7 +611,7 @@
 	}
 
 	// Read loader section string table
-	if _, err := s.sr.Seek(int64(stoff), os.SEEK_SET); err != nil {
+	if _, err := s.sr.Seek(int64(stoff), io.SeekStart); err != nil {
 		return nil, err
 	}
 	st := make([]byte, stlen)
@@ -621,7 +626,7 @@
 	}
 
 	// Read loader symbol table
-	if _, err := s.sr.Seek(int64(symoff), os.SEEK_SET); err != nil {
+	if _, err := s.sr.Seek(int64(symoff), io.SeekStart); err != nil {
 		return nil, err
 	}
 	all := make([]ImportedSymbol, 0)
diff --git a/src/io/example_test.go b/src/io/example_test.go
index 419e449..818020e 100644
--- a/src/io/example_test.go
+++ b/src/io/example_test.go
@@ -5,7 +5,6 @@
 package io_test
 
 import (
-	"bytes"
 	"fmt"
 	"io"
 	"log"
@@ -239,7 +238,7 @@
 func ExampleMultiWriter() {
 	r := strings.NewReader("some io.Reader stream to be read\n")
 
-	var buf1, buf2 bytes.Buffer
+	var buf1, buf2 strings.Builder
 	w := io.MultiWriter(&buf1, &buf2)
 
 	if _, err := io.Copy(w, r); err != nil {
diff --git a/src/io/export_test.go b/src/io/export_test.go
index fa3e8e7..06853f9 100644
--- a/src/io/export_test.go
+++ b/src/io/export_test.go
@@ -6,3 +6,5 @@
 
 // exported for test
 var ErrInvalidWrite = errInvalidWrite
+var ErrWhence = errWhence
+var ErrOffset = errOffset
diff --git a/src/io/fs/walk.go b/src/io/fs/walk.go
index 3780079..cff2610 100644
--- a/src/io/fs/walk.go
+++ b/src/io/fs/walk.go
@@ -14,6 +14,11 @@
 // as an error by any function.
 var SkipDir = errors.New("skip this directory")
 
+// SkipAll is used as a return value from WalkDirFuncs to indicate that
+// all remaining files and directories are to be skipped. It is not returned
+// as an error by any function.
+var SkipAll = errors.New("skip everything and stop the walk")
+
 // WalkDirFunc is the type of the function called by WalkDir to visit
 // each file or directory.
 //
@@ -27,8 +32,10 @@
 // The error result returned by the function controls how WalkDir
 // continues. If the function returns the special value SkipDir, WalkDir
 // skips the current directory (path if d.IsDir() is true, otherwise
-// path's parent directory). Otherwise, if the function returns a non-nil
-// error, WalkDir stops entirely and returns that error.
+// path's parent directory). If the function returns the special value
+// SkipAll, WalkDir skips all remaining files and directories. Otherwise,
+// if the function returns a non-nil error, WalkDir stops entirely and
+// returns that error.
 //
 // The err argument reports an error related to path, signaling that
 // WalkDir will not walk into that directory. The function can decide how
@@ -47,15 +54,16 @@
 // ReadDir. In this second case, the function is called twice with the
 // path of the directory: the first call is before the directory read is
 // attempted and has err set to nil, giving the function a chance to
-// return SkipDir and avoid the ReadDir entirely. The second call is
-// after a failed ReadDir and reports the error from ReadDir.
+// return SkipDir or SkipAll and avoid the ReadDir entirely. The second call
+// is after a failed ReadDir and reports the error from ReadDir.
 // (If ReadDir succeeds, there is no second call.)
 //
 // The differences between WalkDirFunc compared to filepath.WalkFunc are:
 //
 //   - The second argument has type fs.DirEntry instead of fs.FileInfo.
 //   - The function is called before reading a directory, to allow SkipDir
-//     to bypass the directory read entirely.
+//     or SkipAll to bypass the directory read entirely or skip all remaining
+//     files and directories respectively.
 //   - If a directory read fails, the function is called a second time
 //     for that directory to report the error.
 type WalkDirFunc func(path string, d DirEntry, err error) error
@@ -113,7 +121,7 @@
 	} else {
 		err = walkDir(fsys, root, &statDirEntry{info}, fn)
 	}
-	if err == SkipDir {
+	if err == SkipDir || err == SkipAll {
 		return nil
 	}
 	return err
diff --git a/src/io/fs/walk_test.go b/src/io/fs/walk_test.go
index 04358be..40f4e1a 100644
--- a/src/io/fs/walk_test.go
+++ b/src/io/fs/walk_test.go
@@ -53,7 +53,7 @@
 	}
 }
 
-func makeTree(t *testing.T) FS {
+func makeTree() FS {
 	fsys := fstest.MapFS{}
 	walkTree(tree, tree.name, func(path string, n *Node) {
 		if n.entries == nil {
@@ -65,17 +65,6 @@
 	return fsys
 }
 
-func markTree(n *Node) { walkTree(n, "", func(path string, n *Node) { n.mark++ }) }
-
-func checkMarks(t *testing.T, report bool) {
-	walkTree(tree, tree.name, func(path string, n *Node) {
-		if n.mark != 1 && report {
-			t.Errorf("node %s mark = %d; expected 1", path, n.mark)
-		}
-		n.mark = 0
-	})
-}
-
 // Assumes that each node name is unique. Good enough for a test.
 // If clear is true, any incoming error is cleared before return. The errors
 // are always accumulated, though.
@@ -108,7 +97,7 @@
 	}
 	defer os.Chdir(origDir)
 
-	fsys := makeTree(t)
+	fsys := makeTree()
 	errors := make([]error, 0, 10)
 	clear := true
 	markFn := func(path string, entry DirEntry, err error) error {
@@ -122,7 +111,12 @@
 	if len(errors) != 0 {
 		t.Fatalf("unexpected errors: %s", errors)
 	}
-	checkMarks(t, true)
+	walkTree(tree, tree.name, func(path string, n *Node) {
+		if n.mark != 1 {
+			t.Errorf("node %s mark = %d; expected 1", path, n.mark)
+		}
+		n.mark = 0
+	})
 }
 
 func TestIssue51617(t *testing.T) {
diff --git a/src/io/io.go b/src/io/io.go
index 9d4c0d2..630ab73 100644
--- a/src/io/io.go
+++ b/src/io/io.go
@@ -555,6 +555,46 @@
 // Size returns the size of the section in bytes.
 func (s *SectionReader) Size() int64 { return s.limit - s.base }
 
+// An OffsetWriter maps writes at offset base to offset base+off in the underlying writer.
+type OffsetWriter struct {
+	w    WriterAt
+	base int64 // the original offset
+	off  int64 // the current offset
+}
+
+// NewOffsetWriter returns an OffsetWriter that writes to w
+// starting at offset off.
+func NewOffsetWriter(w WriterAt, off int64) *OffsetWriter {
+	return &OffsetWriter{w, off, off}
+}
+
+func (o *OffsetWriter) Write(p []byte) (n int, err error) {
+	n, err = o.w.WriteAt(p, o.off)
+	o.off += int64(n)
+	return
+}
+
+func (o *OffsetWriter) WriteAt(p []byte, off int64) (n int, err error) {
+	off += o.base
+	return o.w.WriteAt(p, off)
+}
+
+func (o *OffsetWriter) Seek(offset int64, whence int) (int64, error) {
+	switch whence {
+	default:
+		return 0, errWhence
+	case SeekStart:
+		offset += o.base
+	case SeekCurrent:
+		offset += o.off
+	}
+	if offset < o.base {
+		return 0, errOffset
+	}
+	o.off = offset
+	return offset - o.base, nil
+}
+
 // TeeReader returns a Reader that writes to w what it reads from r.
 // All reads from r performed through it are matched with
 // corresponding writes to w. There is no internal buffering -
diff --git a/src/io/io_test.go b/src/io/io_test.go
index a51a1fa..35db15c 100644
--- a/src/io/io_test.go
+++ b/src/io/io_test.go
@@ -9,7 +9,10 @@
 	"errors"
 	"fmt"
 	. "io"
+	"os"
 	"strings"
+	"sync"
+	"sync/atomic"
 	"testing"
 )
 
@@ -492,3 +495,177 @@
 		}
 	}
 }
+
+func TestOffsetWriter_Seek(t *testing.T) {
+	tmpfilename := "TestOffsetWriter_Seek"
+	tmpfile, err := os.CreateTemp(t.TempDir(), tmpfilename)
+	if err != nil || tmpfile == nil {
+		t.Fatalf("CreateTemp(%s) failed: %v", tmpfilename, err)
+	}
+	defer tmpfile.Close()
+	w := NewOffsetWriter(tmpfile, 0)
+
+	// Should throw error errWhence if whence is not valid
+	t.Run("errWhence", func(t *testing.T) {
+		for _, whence := range []int{-3, -2, -1, 3, 4, 5} {
+			var offset int64 = 0
+			gotOff, gotErr := w.Seek(offset, whence)
+			if gotOff != 0 || gotErr != ErrWhence {
+				t.Errorf("For whence %d, offset %d, OffsetWriter.Seek got: (%d, %v), want: (%d, %v)",
+					whence, offset, gotOff, gotErr, 0, ErrWhence)
+			}
+		}
+	})
+
+	// Should throw error errOffset if offset is negative
+	t.Run("errOffset", func(t *testing.T) {
+		for _, whence := range []int{SeekStart, SeekCurrent} {
+			for offset := int64(-3); offset < 0; offset++ {
+				gotOff, gotErr := w.Seek(offset, whence)
+				if gotOff != 0 || gotErr != ErrOffset {
+					t.Errorf("For whence %d, offset %d, OffsetWriter.Seek got: (%d, %v), want: (%d, %v)",
+						whence, offset, gotOff, gotErr, 0, ErrOffset)
+				}
+			}
+		}
+	})
+
+	// Normal tests
+	t.Run("normal", func(t *testing.T) {
+		tests := []struct {
+			offset    int64
+			whence    int
+			returnOff int64
+		}{
+			// keep in order
+			{whence: SeekStart, offset: 1, returnOff: 1},
+			{whence: SeekStart, offset: 2, returnOff: 2},
+			{whence: SeekStart, offset: 3, returnOff: 3},
+			{whence: SeekCurrent, offset: 1, returnOff: 4},
+			{whence: SeekCurrent, offset: 2, returnOff: 6},
+			{whence: SeekCurrent, offset: 3, returnOff: 9},
+		}
+		for idx, tt := range tests {
+			gotOff, gotErr := w.Seek(tt.offset, tt.whence)
+			if gotOff != tt.returnOff || gotErr != nil {
+				t.Errorf("%d:: For whence %d, offset %d, OffsetWriter.Seek got: (%d, %v), want: (%d, <nil>)",
+					idx+1, tt.whence, tt.offset, gotOff, gotErr, tt.returnOff)
+			}
+		}
+	})
+}
+
+func TestOffsetWriter_WriteAt(t *testing.T) {
+	const content = "0123456789ABCDEF"
+	contentSize := int64(len(content))
+	tmpdir, err := os.MkdirTemp(t.TempDir(), "TestOffsetWriter_WriteAt")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	work := func(off, at int64) {
+		position := fmt.Sprintf("off_%d_at_%d", off, at)
+		tmpfile, err := os.CreateTemp(tmpdir, position)
+		if err != nil || tmpfile == nil {
+			t.Fatalf("CreateTemp(%s) failed: %v", position, err)
+		}
+		defer tmpfile.Close()
+
+		var writeN int64
+		var wg sync.WaitGroup
+		// Concurrent writes, one byte at a time
+		for step, value := range []byte(content) {
+			wg.Add(1)
+			go func(wg *sync.WaitGroup, tmpfile *os.File, value byte, off, at int64, step int) {
+				defer wg.Done()
+
+				w := NewOffsetWriter(tmpfile, off)
+				n, e := w.WriteAt([]byte{value}, at+int64(step))
+				if e != nil {
+					t.Errorf("WriteAt failed. off: %d, at: %d, step: %d\n error: %v", off, at, step, e)
+				}
+				atomic.AddInt64(&writeN, int64(n))
+			}(&wg, tmpfile, value, off, at, step)
+		}
+		wg.Wait()
+
+		// Read one more byte to reach EOF
+		buf := make([]byte, contentSize+1)
+		readN, err := tmpfile.ReadAt(buf, off+at)
+		if err != EOF {
+			t.Fatalf("ReadAt failed: %v", err)
+		}
+		readContent := string(buf[:contentSize])
+		if writeN != int64(readN) || writeN != contentSize || readContent != content {
+			t.Fatalf("%s:: WriteAt(%s, %d) error. \ngot n: %v, content: %s \nexpected n: %v, content: %v",
+				position, content, at, readN, readContent, contentSize, content)
+		}
+	}
+	for off := int64(0); off < 2; off++ {
+		for at := int64(0); at < 2; at++ {
+			work(off, at)
+		}
+	}
+}
+
+func TestOffsetWriter_Write(t *testing.T) {
+	const content = "0123456789ABCDEF"
+	contentSize := len(content)
+	tmpdir := t.TempDir()
+
+	makeOffsetWriter := func(name string) (*OffsetWriter, *os.File) {
+		tmpfilename := "TestOffsetWriter_Write_" + name
+		tmpfile, err := os.CreateTemp(tmpdir, tmpfilename)
+		if err != nil || tmpfile == nil {
+			t.Fatalf("CreateTemp(%s) failed: %v", tmpfilename, err)
+		}
+		return NewOffsetWriter(tmpfile, 0), tmpfile
+	}
+	checkContent := func(name string, f *os.File) {
+		// Read one more byte to reach EOF
+		buf := make([]byte, contentSize+1)
+		readN, err := f.ReadAt(buf, 0)
+		if err != EOF {
+			t.Fatalf("ReadAt failed, err: %v", err)
+		}
+		readContent := string(buf[:contentSize])
+		if readN != contentSize || readContent != content {
+			t.Fatalf("%s error. \ngot n: %v, content: %s \nexpected n: %v, content: %v",
+				name, readN, readContent, contentSize, content)
+		}
+	}
+
+	var name string
+	name = "Write"
+	t.Run(name, func(t *testing.T) {
+		// Write directly (off: 0, at: 0)
+		// Write content to file
+		w, f := makeOffsetWriter(name)
+		defer f.Close()
+		for _, value := range []byte(content) {
+			n, err := w.Write([]byte{value})
+			if err != nil {
+				t.Fatalf("Write failed, n: %d, err: %v", n, err)
+			}
+		}
+		checkContent(name, f)
+
+		// Copy -> Write
+		// Copy file f to file f2
+		name = "Copy"
+		w2, f2 := makeOffsetWriter(name)
+		defer f2.Close()
+		Copy(w2, f)
+		checkContent(name, f2)
+	})
+
+	// Copy -> WriteTo -> Write
+	// Note: strings.Reader implements the io.WriterTo interface.
+	name = "Write_Of_Copy_WriteTo"
+	t.Run(name, func(t *testing.T) {
+		w, f := makeOffsetWriter(name)
+		defer f.Close()
+		Copy(w, strings.NewReader(content))
+		checkContent(name, f)
+	})
+}
diff --git a/src/io/multi_test.go b/src/io/multi_test.go
index 679312c..7a24a8a 100644
--- a/src/io/multi_test.go
+++ b/src/io/multi_test.go
@@ -228,7 +228,7 @@
 
 // Test that MultiWriter copies the input slice and is insulated from future modification.
 func TestMultiWriterCopy(t *testing.T) {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	slice := []Writer{&buf}
 	w := MultiWriter(slice...)
 	slice[0] = nil
diff --git a/src/log/log.go b/src/log/log.go
index f7e48d5..566535f 100644
--- a/src/log/log.go
+++ b/src/log/log.go
@@ -54,12 +54,12 @@
 // the Writer's Write method. A Logger can be used simultaneously from
 // multiple goroutines; it guarantees to serialize access to the Writer.
 type Logger struct {
-	mu        sync.Mutex // ensures atomic writes; protects the following fields
-	prefix    string     // prefix on each line to identify the logger (but see Lmsgprefix)
-	flag      int        // properties
-	out       io.Writer  // destination for output
-	buf       []byte     // for accumulating text to write
-	isDiscard int32      // atomic boolean: whether out == io.Discard
+	mu        sync.Mutex  // ensures atomic writes; protects the following fields
+	prefix    string      // prefix on each line to identify the logger (but see Lmsgprefix)
+	flag      int         // properties
+	out       io.Writer   // destination for output
+	buf       []byte      // for accumulating text to write
+	isDiscard atomic.Bool // whether out == io.Discard
 }
 
 // New creates a new Logger. The out variable sets the
@@ -70,7 +70,7 @@
 func New(out io.Writer, prefix string, flag int) *Logger {
 	l := &Logger{out: out, prefix: prefix, flag: flag}
 	if out == io.Discard {
-		l.isDiscard = 1
+		l.isDiscard.Store(true)
 	}
 	return l
 }
@@ -80,11 +80,7 @@
 	l.mu.Lock()
 	defer l.mu.Unlock()
 	l.out = w
-	isDiscard := int32(0)
-	if w == io.Discard {
-		isDiscard = 1
-	}
-	atomic.StoreInt32(&l.isDiscard, isDiscard)
+	l.isDiscard.Store(w == io.Discard)
 }
 
 var std = New(os.Stderr, "", LstdFlags)
@@ -202,7 +198,7 @@
 // Printf calls l.Output to print to the logger.
 // Arguments are handled in the manner of fmt.Printf.
 func (l *Logger) Printf(format string, v ...any) {
-	if atomic.LoadInt32(&l.isDiscard) != 0 {
+	if l.isDiscard.Load() {
 		return
 	}
 	l.Output(2, fmt.Sprintf(format, v...))
@@ -211,7 +207,7 @@
 // Print calls l.Output to print to the logger.
 // Arguments are handled in the manner of fmt.Print.
 func (l *Logger) Print(v ...any) {
-	if atomic.LoadInt32(&l.isDiscard) != 0 {
+	if l.isDiscard.Load() {
 		return
 	}
 	l.Output(2, fmt.Sprint(v...))
@@ -220,7 +216,7 @@
 // Println calls l.Output to print to the logger.
 // Arguments are handled in the manner of fmt.Println.
 func (l *Logger) Println(v ...any) {
-	if atomic.LoadInt32(&l.isDiscard) != 0 {
+	if l.isDiscard.Load() {
 		return
 	}
 	l.Output(2, fmt.Sprintln(v...))
@@ -339,7 +335,7 @@
 // Print calls Output to print to the standard logger.
 // Arguments are handled in the manner of fmt.Print.
 func Print(v ...any) {
-	if atomic.LoadInt32(&std.isDiscard) != 0 {
+	if std.isDiscard.Load() {
 		return
 	}
 	std.Output(2, fmt.Sprint(v...))
@@ -348,7 +344,7 @@
 // Printf calls Output to print to the standard logger.
 // Arguments are handled in the manner of fmt.Printf.
 func Printf(format string, v ...any) {
-	if atomic.LoadInt32(&std.isDiscard) != 0 {
+	if std.isDiscard.Load() {
 		return
 	}
 	std.Output(2, fmt.Sprintf(format, v...))
@@ -357,7 +353,7 @@
 // Println calls Output to print to the standard logger.
 // Arguments are handled in the manner of fmt.Println.
 func Println(v ...any) {
-	if atomic.LoadInt32(&std.isDiscard) != 0 {
+	if std.isDiscard.Load() {
 		return
 	}
 	std.Output(2, fmt.Sprintln(v...))
diff --git a/src/log/log_test.go b/src/log/log_test.go
index 938ed42..f2ef165 100644
--- a/src/log/log_test.go
+++ b/src/log/log_test.go
@@ -53,7 +53,7 @@
 
 // Test using Println("hello", 23, "world") or using Printf("hello %d world", 23)
 func testPrint(t *testing.T, flag int, prefix string, pattern string, useFormat bool) {
-	buf := new(bytes.Buffer)
+	buf := new(strings.Builder)
 	SetOutput(buf)
 	SetFlags(flag)
 	SetPrefix(prefix)
@@ -90,7 +90,7 @@
 
 func TestOutput(t *testing.T) {
 	const testString = "test"
-	var b bytes.Buffer
+	var b strings.Builder
 	l := New(&b, "", 0)
 	l.Println(testString)
 	if expect := testString + "\n"; b.String() != expect {
@@ -143,7 +143,7 @@
 }
 
 func TestUTCFlag(t *testing.T) {
-	var b bytes.Buffer
+	var b strings.Builder
 	l := New(&b, "Test:", LstdFlags)
 	l.SetFlags(Ldate | Ltime | LUTC)
 	// Verify a log message looks right in the right time zone. Quantize to the second only.
@@ -167,7 +167,7 @@
 }
 
 func TestEmptyPrintCreatesLine(t *testing.T) {
-	var b bytes.Buffer
+	var b strings.Builder
 	l := New(&b, "Header:", LstdFlags)
 	l.Print()
 	l.Println("non-empty")
diff --git a/src/log/syslog/syslog.go b/src/log/syslog/syslog.go
index 8c6ba72..03e5263 100644
--- a/src/log/syslog/syslog.go
+++ b/src/log/syslog/syslog.go
@@ -255,7 +255,7 @@
 
 	if w.conn != nil {
 		if n, err := w.write(pr, s); err == nil {
-			return n, err
+			return n, nil
 		}
 	}
 	if err := w.connect(); err != nil {
diff --git a/src/make.bash b/src/make.bash
index ab2ce19..c07f39b 100755
--- a/src/make.bash
+++ b/src/make.bash
@@ -67,9 +67,14 @@
 # timing information to this file. Useful for profiling where the
 # time goes when these scripts run.
 #
-# GOROOT_BOOTSTRAP: A working Go tree >= Go 1.4 for bootstrap.
+# GOROOT_BOOTSTRAP: A working Go tree >= Go 1.17.13 for bootstrap.
 # If $GOROOT_BOOTSTRAP/bin/go is missing, $(go env GOROOT) is
-# tried for all "go" in $PATH. $HOME/go1.4 by default.
+# tried for all "go" in $PATH. By default, one of $HOME/go1.17.13,
+# $HOME/sdk/go1.17.13, or $HOME/go1.4, whichever exists, in that order.
+# We still check $HOME/go1.4 to allow for build scripts that still hard-code
+# that name even though they put newer Go toolchains there.
+
+bootgo=1.17.13
 
 set -e
 
@@ -133,15 +138,6 @@
 	export CGO_ENABLED=0
 fi
 
-# Test which linker/loader our system is using, if GO_LDSO is not set.
-if [ -z "$GO_LDSO" ] && type readelf >/dev/null 2>&1; then
-	if echo "int main() { return 0; }" | ${CC:-cc} -o ./test-musl-ldso -x c - >/dev/null 2>&1; then
-		LDSO=$(readelf -l ./test-musl-ldso | grep 'interpreter:' | sed -e 's/^.*interpreter: \(.*\)[]]/\1/') >/dev/null 2>&1
-		[ -z "$LDSO" ] || export GO_LDSO="$LDSO"
-		rm -f ./test-musl-ldso
-	fi
-fi
-
 # Clean old generated file that will cause problems in the build.
 rm -f ./runtime/runtime_defs.go
 
@@ -158,7 +154,7 @@
 goroot_bootstrap_set=${GOROOT_BOOTSTRAP+"true"}
 if [ -z "$GOROOT_BOOTSTRAP" ]; then
 	GOROOT_BOOTSTRAP="$HOME/go1.4"
-	for d in sdk/go1.17 go1.17; do
+	for d in sdk/go$bootgo go$bootgo; do
 		if [ -d "$HOME/$d" ]; then
 			GOROOT_BOOTSTRAP="$HOME/$d"
 		fi
@@ -181,7 +177,7 @@
 done; unset IFS
 if [ ! -x "$GOROOT_BOOTSTRAP/bin/go" ]; then
 	echo "ERROR: Cannot find $GOROOT_BOOTSTRAP/bin/go." >&2
-	echo "Set \$GOROOT_BOOTSTRAP to a working Go tree >= Go 1.4." >&2
+	echo "Set \$GOROOT_BOOTSTRAP to a working Go tree >= Go $bootgo." >&2
 	exit 1
 fi
 # Get the exact bootstrap toolchain version to help with debugging.
@@ -194,7 +190,7 @@
 fi
 if [ "$GOROOT_BOOTSTRAP" = "$GOROOT" ]; then
 	echo "ERROR: \$GOROOT_BOOTSTRAP must not be set to \$GOROOT" >&2
-	echo "Set \$GOROOT_BOOTSTRAP to a working Go tree >= Go 1.4." >&2
+	echo "Set \$GOROOT_BOOTSTRAP to a working Go tree >= Go $bootgo." >&2
 	exit 1
 fi
 rm -f cmd/dist/dist
@@ -222,7 +218,7 @@
 
 # Run dist bootstrap to complete make.bash.
 # Bootstrap installs a proper cmd/dist, built with the new toolchain.
-# Throw ours, built with Go 1.4, away after bootstrap.
+# Throw ours, built with the bootstrap toolchain, away after bootstrap.
 ./cmd/dist/dist bootstrap -a $vflag $GO_DISTFLAGS "$@"
 rm -f ./cmd/dist/dist
 
diff --git a/src/make.bat b/src/make.bat
index 8f43470..104fb48 100644
--- a/src/make.bat
+++ b/src/make.bat
@@ -80,8 +80,10 @@
 		)

 	)

 )

-if "x%GOROOT_BOOTSTRAP%"=="x" if exist "%HOMEDRIVE%%HOMEPATH%\go1.17" set GOROOT_BOOTSTRAP=%HOMEDRIVE%%HOMEPATH%\go1.17

-if "x%GOROOT_BOOTSTRAP%"=="x" if exist "%HOMEDRIVE%%HOMEPATH%\sdk\go1.17" set GOROOT_BOOTSTRAP=%HOMEDRIVE%%HOMEPATH%\sdk\go1.17

+

+set bootgo=1.17.13

+if "x%GOROOT_BOOTSTRAP%"=="x" if exist "%HOMEDRIVE%%HOMEPATH%\go%bootgo%" set GOROOT_BOOTSTRAP=%HOMEDRIVE%%HOMEPATH%\go%bootgo%

+if "x%GOROOT_BOOTSTRAP%"=="x" if exist "%HOMEDRIVE%%HOMEPATH%\sdk\go%bootgo%" set GOROOT_BOOTSTRAP=%HOMEDRIVE%%HOMEPATH%\sdk\go%bootgo%

 if "x%GOROOT_BOOTSTRAP%"=="x" set GOROOT_BOOTSTRAP=%HOMEDRIVE%%HOMEPATH%\Go1.4

 

 :bootstrapset

@@ -89,14 +91,16 @@
 set GOROOT=%GOROOT_TEMP%

 set GOROOT_TEMP=

 

-echo Building Go cmd/dist using %GOROOT_BOOTSTRAP%

-if x%vflag==x-v echo cmd/dist

 setlocal

-set GOROOT=%GOROOT_BOOTSTRAP%

 set GOOS=

 set GOARCH=

-set GOBIN=

 set GOEXPERIMENT=

+for /f "tokens=*" %%g IN ('"%GOROOT_BOOTSTRAP%\bin\go" version') do (set GOROOT_BOOTSTRAP_VERSION=%%g)

+set GOROOT_BOOTSTRAP_VERSION=%GOROOT_BOOTSTRAP_VERSION:go version =%

+echo Building Go cmd/dist using %GOROOT_BOOTSTRAP%. (%GOROOT_BOOTSTRAP_VERSION%)

+if x%vflag==x-v echo cmd/dist

+set GOROOT=%GOROOT_BOOTSTRAP%

+set GOBIN=

 set GO111MODULE=off

 set GOENV=off

 set GOFLAGS=

@@ -126,7 +130,7 @@
 

 :: Run dist bootstrap to complete make.bash.

 :: Bootstrap installs a proper cmd/dist, built with the new toolchain.

-:: Throw ours, built with Go 1.4, away after bootstrap.

+:: Throw ours, built with the bootstrap toolchain, away after bootstrap.

 .\cmd\dist\dist.exe bootstrap -a %vflag% %bootstrapflags%

 if errorlevel 1 goto fail

 del .\cmd\dist\dist.exe

@@ -145,7 +149,7 @@
 

 :bootstrapfail

 echo ERROR: Cannot find %GOROOT_BOOTSTRAP%\bin\go.exe

-echo Set GOROOT_BOOTSTRAP to a working Go tree ^>= Go 1.4.

+echo Set GOROOT_BOOTSTRAP to a working Go tree ^>= Go %bootgo%.

 

 :fail

 set GOBUILDFAIL=1

diff --git a/src/make.rc b/src/make.rc
index 4597403..e17ee31 100755
--- a/src/make.rc
+++ b/src/make.rc
@@ -47,12 +47,13 @@
 	shift
 }
 
+bootgo = 1.17.13
 GOROOT = `{cd .. && pwd}
 goroot_bootstrap_set = 'true'
 if(! ~ $#GOROOT_BOOTSTRAP 1){
 	goroot_bootstrap_set = 'false'
 	GOROOT_BOOTSTRAP = $home/go1.4
-	for(d in sdk/go1.17 go1.17)
+	for(d in sdk/go$bootgo go$bootgo)
 		if(test -d $home/$d)
 			GOROOT_BOOTSTRAP = $home/$d
 }
@@ -72,16 +73,20 @@
 }
 if(! test -x $GOROOT_BOOTSTRAP/bin/go){
 	echo 'ERROR: Cannot find '$GOROOT_BOOTSTRAP'/bin/go.' >[1=2]
-	echo 'Set $GOROOT_BOOTSTRAP to a working Go tree >= Go 1.4.' >[1=2]
+	echo 'Set $GOROOT_BOOTSTRAP to a working Go tree >= Go '$bootgo'.' >[1=2]
 	exit bootstrap
 }
 if(~ $GOROOT_BOOTSTRAP $GOROOT){
 	echo 'ERROR: $GOROOT_BOOTSTRAP must not be set to $GOROOT' >[1=2]
-	echo 'Set $GOROOT_BOOTSTRAP to a working Go tree >= Go 1.4.' >[1=2]
+	echo 'Set $GOROOT_BOOTSTRAP to a working Go tree >= Go '$bootgo'.' >[1=2]
 	exit bootstrap
 }
 
-echo 'Building Go cmd/dist using '^$GOROOT_BOOTSTRAP
+# Get the exact bootstrap toolchain version to help with debugging.
+# We clear GOOS and GOARCH to avoid an ominous but harmless warning if
+# the bootstrap doesn't support them.
+GOROOT_BOOTSTRAP_VERSION=`{GOOS='' GOARCH='' GOEXPERIMENT='' $GOROOT_BOOTSTRAP/bin/go version | sed 's/go version //'}
+echo 'Building Go cmd/dist using '$GOROOT_BOOTSTRAP'. ('$"GOROOT_BOOTSTRAP_VERSION')'
 if(~ $#vflag 1)
 	echo cmd/dist
 GOROOT=$GOROOT_BOOTSTRAP GOOS='' GOARCH='' GOEXPERIMENT='' GO111MODULE=off GOENV=off GOFLAGS='' $GOROOT_BOOTSTRAP/bin/go build -o cmd/dist/dist ./cmd/dist
@@ -101,7 +106,7 @@
 
 # Run dist bootstrap to complete make.bash.
 # Bootstrap installs a proper cmd/dist, built with the new toolchain.
-# Throw ours, built with Go 1.4, away after bootstrap.
+# Throw ours, built with the bootstrap toolchain, away after bootstrap.
 ./cmd/dist/dist bootstrap -a $vflag $*
 rm -f ./cmd/dist/dist
 
diff --git a/src/math/big/arith_decl.go b/src/math/big/arith_decl.go
index 301aa55..9b254f2 100644
--- a/src/math/big/arith_decl.go
+++ b/src/math/big/arith_decl.go
@@ -8,11 +8,27 @@
 package big
 
 // implemented in arith_$GOARCH.s
+
+//go:noescape
 func addVV(z, x, y []Word) (c Word)
+
+//go:noescape
 func subVV(z, x, y []Word) (c Word)
+
+//go:noescape
 func addVW(z, x []Word, y Word) (c Word)
+
+//go:noescape
 func subVW(z, x []Word, y Word) (c Word)
+
+//go:noescape
 func shlVU(z, x []Word, s uint) (c Word)
+
+//go:noescape
 func shrVU(z, x []Word, s uint) (c Word)
+
+//go:noescape
 func mulAddVWW(z, x []Word, y, r Word) (c Word)
+
+//go:noescape
 func addMulVVW(z, x []Word, y Word) (c Word)
diff --git a/src/math/big/arith_ppc64x.s b/src/math/big/arith_ppc64x.s
index a83696a..5fdbf40 100644
--- a/src/math/big/arith_ppc64x.s
+++ b/src/math/big/arith_ppc64x.s
@@ -44,6 +44,8 @@
 	// for small values of z_len (0.90x in the worst case), but
 	// gain significant performance as z_len increases (up to
 	// 1.45x).
+
+	PCALIGN $32
 loop:
 	MOVD  8(R8), R11      // R11 = x[i]
 	MOVD  16(R8), R12     // R12 = x[i+1]
@@ -131,6 +133,8 @@
 	// for small values of z_len (0.92x in the worst case), but
 	// gain significant performance as z_len increases (up to
 	// 1.45x).
+
+	PCALIGN $32
 loop:
 	MOVD  8(R8), R11      // R11 = x[i]
 	MOVD  16(R8), R12     // R12 = x[i+1]
@@ -212,6 +216,7 @@
 	CMP   R0, R9
 	MOVD  R9, CTR		// Set up the loop counter
 	BEQ   tail		// If R9 = 0, we can't use the loop
+	PCALIGN $32
 
 loop:
 	MOVD  8(R8), R20	// R20 = x[i]
@@ -288,6 +293,8 @@
 	// The loop here is almost the same as the one used in s390x, but
 	// we don't need to capture CA every iteration because we've already
 	// done that above.
+
+	PCALIGN $32
 loop:
 	MOVD  8(R8), R20
 	MOVD  16(R8), R21
@@ -358,6 +365,7 @@
 	CMP     R5, R0          // iterate from i=len(z)-1 to 0
 	BEQ     loopexit        // Already at end?
 	MOVD	0(R15),R10	// x[i]
+	PCALIGN $32
 shloop:
 	SLD     R9, R10, R10    // x[i]<<s
 	MOVDU   -8(R15), R14
@@ -520,6 +528,7 @@
 	CMP     R0, R14
 	MOVD    R14, CTR          // Set up the loop counter
 	BEQ     tail              // If R9 = 0, we can't use the loop
+	PCALIGN $32
 
 loop:
 	MOVD    8(R8), R20        // R20 = x[i]
@@ -602,6 +611,7 @@
 	MOVD R0, R4		// R4 = c = 0
 	MOVD R22, CTR		// Initialize loop counter
 	BEQ  done
+	PCALIGN $32
 
 loop:
 	MOVD  (R8)(R3), R20	// Load x[i]
diff --git a/src/math/big/arith_test.go b/src/math/big/arith_test.go
index e530dd9..64225bb 100644
--- a/src/math/big/arith_test.go
+++ b/src/math/big/arith_test.go
@@ -370,7 +370,7 @@
 func TestIssue31084(t *testing.T) {
 	// compute 10^n via 5^n << n.
 	const n = 165
-	p := nat(nil).expNN(nat{5}, nat{n}, nil)
+	p := nat(nil).expNN(nat{5}, nat{n}, nil, false)
 	p = p.shl(p, n)
 	got := string(p.utoa(10))
 	want := "1" + strings.Repeat("0", n)
diff --git a/src/math/big/int.go b/src/math/big/int.go
index ec168f8..76d6eb9 100644
--- a/src/math/big/int.go
+++ b/src/math/big/int.go
@@ -35,6 +35,9 @@
 //	 0 if x == 0
 //	+1 if x >  0
 func (x *Int) Sign() int {
+	// This function is used in cryptographic operations. It must not leak
+	// anything but the Int's sign and bit size through side-channels. Any
+	// changes must be reviewed by a security expert.
 	if len(x.abs) == 0 {
 		return 0
 	}
@@ -65,7 +68,20 @@
 
 // NewInt allocates and returns a new Int set to x.
 func NewInt(x int64) *Int {
-	return new(Int).SetInt64(x)
+	// This code is arranged to be inlineable and produce
+	// zero allocations when inlined. See issue 29951.
+	u := uint64(x)
+	if x < 0 {
+		u = -u
+	}
+	var abs []Word
+	if x == 0 {
+	} else if _W == 32 && u>>32 != 0 {
+		abs = []Word{Word(u), Word(u >> 32)}
+	} else {
+		abs = []Word{Word(u)}
+	}
+	return &Int{neg: x < 0, abs: abs}
 }
 
 // Set sets z to x and returns z.
@@ -83,6 +99,9 @@
 // Bits is intended to support implementation of missing low-level Int
 // functionality outside this package; it should be avoided otherwise.
 func (x *Int) Bits() []Word {
+	// This function is used in cryptographic operations. It must not leak
+	// anything but the Int's sign and bit size through side-channels. Any
+	// changes must be reviewed by a security expert.
 	return x.abs
 }
 
@@ -192,16 +211,46 @@
 	return z
 }
 
-// Binomial sets z to the binomial coefficient of (n, k) and returns z.
+// Binomial sets z to the binomial coefficient C(n, k) and returns z.
 func (z *Int) Binomial(n, k int64) *Int {
-	// reduce the number of multiplications by reducing k
-	if n/2 < k && k <= n {
-		k = n - k // Binomial(n, k) == Binomial(n, n-k)
+	if k > n {
+		return z.SetInt64(0)
 	}
-	var a, b Int
-	a.MulRange(n-k+1, n)
-	b.MulRange(1, k)
-	return z.Quo(&a, &b)
+	// reduce the number of multiplications by reducing k
+	if k > n-k {
+		k = n - k // C(n, k) == C(n, n-k)
+	}
+	// C(n, k) == n * (n-1) * ... * (n-k+1) / k * (k-1) * ... * 1
+	//         == n * (n-1) * ... * (n-k+1) / 1 * (1+1) * ... * k
+	//
+	// Using the multiplicative formula produces smaller values
+	// at each step, requiring fewer allocations and computations:
+	//
+	// z = 1
+	// for i := 0; i < k; i = i+1 {
+	//     z *= n-i
+	//     z /= i+1
+	// }
+	//
+	// finally to avoid computing i+1 twice per loop:
+	//
+	// z = 1
+	// i := 0
+	// for i < k {
+	//     z *= n-i
+	//     i++
+	//     z /= i
+	// }
+	var N, K, i, t Int
+	N.SetInt64(n)
+	K.SetInt64(k)
+	z.Set(intOne)
+	for i.Cmp(&K) < 0 {
+		z.Mul(z, t.Sub(&N, &i))
+		i.Add(&i, intOne)
+		z.Quo(z, &i)
+	}
+	return z
 }
 
 // Quo sets z to the quotient x/y for y != 0 and returns z.
@@ -444,6 +493,9 @@
 //
 // To use a fixed length slice, or a preallocated one, use FillBytes.
 func (x *Int) Bytes() []byte {
+	// This function is used in cryptographic operations. It must not leak
+	// anything but the Int's sign and bit size through side-channels. Any
+	// changes must be reviewed by a security expert.
 	buf := make([]byte, len(x.abs)*_S)
 	return buf[x.abs.bytes(buf):]
 }
@@ -464,6 +516,9 @@
 // BitLen returns the length of the absolute value of x in bits.
 // The bit length of 0 is 0.
 func (x *Int) BitLen() int {
+	// This function is used in cryptographic operations. It must not leak
+	// anything but the Int's sign and bit size through side-channels. Any
+	// changes must be reviewed by a security expert.
 	return x.abs.bitLen()
 }
 
@@ -480,6 +535,14 @@
 // Modular exponentiation of inputs of a particular size is not a
 // cryptographically constant-time operation.
 func (z *Int) Exp(x, y, m *Int) *Int {
+	return z.exp(x, y, m, false)
+}
+
+func (z *Int) expSlow(x, y, m *Int) *Int {
+	return z.exp(x, y, m, true)
+}
+
+func (z *Int) exp(x, y, m *Int, slow bool) *Int {
 	// See Knuth, volume 2, section 4.6.3.
 	xWords := x.abs
 	if y.neg {
@@ -503,7 +566,7 @@
 		mWords = m.abs // m.abs may be nil for m == 0
 	}
 
-	z.abs = z.abs.expNN(xWords, yWords, mWords)
+	z.abs = z.abs.expNN(xWords, yWords, mWords, slow)
 	z.neg = len(z.abs) > 0 && x.neg && len(yWords) > 0 && yWords[0]&1 == 1 // 0 has no sign
 	if z.neg && len(mWords) > 0 {
 		// make modulus result positive
@@ -620,7 +683,7 @@
 // where the signs of u0, u1, v0, v1 are given by even
 // For even == true: u0, v1 >= 0 && u1, v0 <= 0
 // For even == false: u0, v1 <= 0 && u1, v0 >= 0
-// q, r, s, t are temporary variables to avoid allocations in the multiplication
+// q, r, s, t are temporary variables to avoid allocations in the multiplication.
 func lehmerUpdate(A, B, q, r, s, t *Int, u0, u1, v0, v1 Word, even bool) {
 
 	t.abs = t.abs.setWord(u0)
@@ -644,7 +707,7 @@
 }
 
 // euclidUpdate performs a single step of the Euclidean GCD algorithm
-// if extended is true, it also updates the cosequence Ua, Ub
+// if extended is true, it also updates the cosequence Ua, Ub.
 func euclidUpdate(A, B, Ua, Ub, q, r, s, t *Int, extended bool) {
 	q, r = q.QuoRem(A, B, r)
 
@@ -836,6 +899,11 @@
 	return z
 }
 
+func (z nat) modInverse(g, n nat) nat {
+	// TODO(rsc): ModInverse should be implemented in terms of this function.
+	return (&Int{abs: z}).ModInverse(&Int{abs: g}, &Int{abs: n}).abs
+}
+
 // Jacobi returns the Jacobi symbol (x/y), either +1, -1, or 0.
 // The y argument must be an odd integer.
 func Jacobi(x, y *Int) int {
diff --git a/src/math/big/int_test.go b/src/math/big/int_test.go
index 3c85573..53cd399 100644
--- a/src/math/big/int_test.go
+++ b/src/math/big/int_test.go
@@ -8,6 +8,8 @@
 	"bytes"
 	"encoding/hex"
 	"fmt"
+	"internal/testenv"
+	"math"
 	"math/rand"
 	"strconv"
 	"strings"
@@ -92,7 +94,7 @@
 		t.Errorf("%s%v is not normalized", msg, z)
 	}
 	if (&z).Cmp(a.z) != 0 {
-		t.Errorf("%s%+v\n\tgot z = %v; want %v", msg, a, &z, a.z)
+		t.Errorf("%v %s %v\n\tgot z = %v; want %v", a.x, msg, a.y, &z, a.z)
 	}
 }
 
@@ -659,6 +661,41 @@
 	}
 }
 
+func BenchmarkExpMont(b *testing.B) {
+	x, _ := new(Int).SetString("297778224889315382157302278696111964193", 0)
+	y, _ := new(Int).SetString("2548977943381019743024248146923164919440527843026415174732254534318292492375775985739511369575861449426580651447974311336267954477239437734832604782764979371984246675241012538135715981292390886872929238062252506842498360562303324154310849745753254532852868768268023732398278338025070694508489163836616810661033068070127919590264734220833816416141878688318329193389865030063416339367925710474801991305827284114894677717927892032165200876093838921477120036402410731159852999623461591709308405270748511350289172153076023215", 0)
+	var mods = []struct {
+		name string
+		val  string
+	}{
+		{"Odd", "0x82828282828200FFFF28FF2B218281FF82828282828200FFFF28FF2B218281FF82828282828200FFFF28FF2B218281FF"},
+		{"Even1", "0x82828282828200FFFF28FF2B218281FF82828282828200FFFF28FF2B218281FF82828282828200FFFF28FF2B218281FE"},
+		{"Even2", "0x82828282828200FFFF28FF2B218281FF82828282828200FFFF28FF2B218281FF82828282828200FFFF28FF2B218281FC"},
+		{"Even3", "0x82828282828200FFFF28FF2B218281FF82828282828200FFFF28FF2B218281FF82828282828200FFFF28FF2B218281F8"},
+		{"Even4", "0x82828282828200FFFF28FF2B218281FF82828282828200FFFF28FF2B218281FF82828282828200FFFF28FF2B218281F0"},
+		{"Even8", "0x82828282828200FFFF28FF2B218281FF82828282828200FFFF28FF2B218281FF82828282828200FFFF28FF2B21828100"},
+		{"Even32", "0x82828282828200FFFF28FF2B218281FF82828282828200FFFF28FF2B218281FF82828282828200FFFF28FF2B00000000"},
+		{"Even64", "0x82828282828200FFFF28FF2B218281FF82828282828200FFFF28FF2B218281FF82828282828200FF0000000000000000"},
+		{"Even96", "0x82828282828200FFFF28FF2B218281FF82828282828200FFFF28FF2B218281FF82828283000000000000000000000000"},
+		{"Even128", "0x82828282828200FFFF28FF2B218281FF82828282828200FFFF28FF2B218281FF00000000000000000000000000000000"},
+		{"Even255", "0x82828282828200FFFF28FF2B218281FF8000000000000000000000000000000000000000000000000000000000000000"},
+		{"SmallEven1", "0x7E"},
+		{"SmallEven2", "0x7C"},
+		{"SmallEven3", "0x78"},
+		{"SmallEven4", "0x70"},
+	}
+	for _, mod := range mods {
+		n, _ := new(Int).SetString(mod.val, 0)
+		out := new(Int)
+		b.Run(mod.name, func(b *testing.B) {
+			b.ReportAllocs()
+			for i := 0; i < b.N; i++ {
+				out.Exp(x, y, n)
+			}
+		})
+	}
+}
+
 func BenchmarkExp2(b *testing.B) {
 	x, _ := new(Int).SetString("2", 0)
 	y, _ := new(Int).SetString("0xAC6BDB41324A9A9BF166DE5E1389582FAF72B6651987EE07FC3192943DB56050A37329CBB4A099ED8193E0757767A13DD52312AB4B03310DCD7F48A9DA04FD50E8083969EDB767B0CF6095179A163AB3661A05FBD5FAAAE82918A9962F0B93B855F97993EC975EEAA80D740ADBF4FF747359D041D5C33EA71D281E446B14773BCA97B43A23FB801676BD207A436C6481F1D2B9078717461A5B9D32E688F87748544523B524B0D57D5EA77A2775D2ECFA032CFBDBF52FB3786160279004E57AE6AF874E7303CE53299CCC041C7BC308D82A5698F3A8D0C38271AE35F8E9DBFBB694B5C803D89F7AE435DE236D525F54759B65E372FCD68EF20FA7111F9E4AFF72", 0)
@@ -1894,3 +1931,27 @@
 		})
 	}
 }
+
+func TestNewIntMinInt64(t *testing.T) {
+	// Test for uint64 cast in NewInt.
+	want := int64(math.MinInt64)
+	if got := NewInt(want).Int64(); got != want {
+		t.Fatalf("wanted %d, got %d", want, got)
+	}
+}
+
+func TestNewIntAllocs(t *testing.T) {
+	testenv.SkipIfOptimizationOff(t)
+	for _, n := range []int64{0, 7, -7, 1 << 30, -1 << 30, 1 << 50, -1 << 50} {
+		x := NewInt(3)
+		got := testing.AllocsPerRun(100, func() {
+			// NewInt should inline, and all its allocations
+			// can happen on the stack. Passing the result of NewInt
+			// to Add should not cause any of those allocations to escape.
+			x.Add(x, NewInt(n))
+		})
+		if got != 0 {
+			t.Errorf("x.Add(x, NewInt(%d)), wanted 0 allocations, got %f", n, got)
+		}
+	}
+}
diff --git a/src/math/big/intconv.go b/src/math/big/intconv.go
index a3a4023..04e8c24 100644
--- a/src/math/big/intconv.go
+++ b/src/math/big/intconv.go
@@ -40,7 +40,7 @@
 	return x.Text(10)
 }
 
-// write count copies of text to s
+// write count copies of text to s.
 func writeMultiple(s fmt.State, text string, count int) {
 	if len(text) > 0 {
 		b := []byte(text)
diff --git a/src/math/big/nat.go b/src/math/big/nat.go
index 5cc42b8..90ce6d1 100644
--- a/src/math/big/nat.go
+++ b/src/math/big/nat.go
@@ -40,6 +40,10 @@
 	natTen  = nat{10}
 )
 
+func (z nat) String() string {
+	return "0x" + string(z.itoa(false, 16))
+}
+
 func (z nat) clear() {
 	for i := range z {
 		z[i] = 0
@@ -642,6 +646,9 @@
 		z = new(nat)
 	}
 	*z = z.make(n)
+	if n > 0 {
+		(*z)[0] = 0xfedcb // break code expecting zero
+	}
 	return z
 }
 
@@ -651,10 +658,24 @@
 
 var natPool sync.Pool
 
-// Length of x in bits. x must be normalized.
+// bitLen returns the length of x in bits.
+// Unlike most methods, it works even if x is not normalized.
 func (x nat) bitLen() int {
+	// This function is used in cryptographic operations. It must not leak
+	// anything but the Int's sign and bit size through side-channels. Any
+	// changes must be reviewed by a security expert.
 	if i := len(x) - 1; i >= 0 {
-		return i*_W + bits.Len(uint(x[i]))
+		// bits.Len uses a lookup table for the low-order bits on some
+		// architectures. Neutralize any input-dependent behavior by setting all
+		// bits after the first one bit.
+		top := uint(x[i])
+		top |= top >> 1
+		top |= top >> 2
+		top |= top >> 4
+		top |= top >> 8
+		top |= top >> 16
+		top |= top >> 16 >> 16 // ">> 32" doesn't compile on 32-bit architectures
+		return i*_W + bits.Len(top)
 	}
 	return 0
 }
@@ -673,6 +694,18 @@
 	return i*_W + uint(bits.TrailingZeros(uint(x[i])))
 }
 
+// isPow2 returns i, true when x == 2**i and 0, false otherwise.
+func (x nat) isPow2() (uint, bool) {
+	var i uint
+	for x[i] == 0 {
+		i++
+	}
+	if i == uint(len(x))-1 && x[i]&(x[i]-1) == 0 {
+		return i*_W + uint(bits.TrailingZeros(uint(x[i]))), true
+	}
+	return 0, false
+}
+
 func same(x, y nat) bool {
 	return len(x) == len(y) && len(x) > 0 && &x[0] == &y[0]
 }
@@ -803,6 +836,20 @@
 	return z.norm()
 }
 
+// trunc returns z = x mod 2ⁿ.
+func (z nat) trunc(x nat, n uint) nat {
+	w := (n + _W - 1) / _W
+	if uint(len(x)) < w {
+		return z.set(x)
+	}
+	z = z.make(int(w))
+	copy(z, x)
+	if n%_W != 0 {
+		z[len(z)-1] &= 1<<(n%_W) - 1
+	}
+	return z.norm()
+}
+
 func (z nat) andNot(x, y nat) nat {
 	m := len(x)
 	n := len(y)
@@ -896,7 +943,7 @@
 
 // If m != 0 (i.e., len(m) != 0), expNN sets z to x**y mod m;
 // otherwise it sets z to x**y. The result is the value of z.
-func (z nat) expNN(x, y, m nat) nat {
+func (z nat) expNN(x, y, m nat, slow bool) nat {
 	if alias(z, x) || alias(z, y) {
 		// We cannot allow in-place modification of x or y.
 		z = nil
@@ -914,31 +961,48 @@
 	}
 	// y > 0
 
-	// x**1 mod m == x mod m
-	if len(y) == 1 && y[0] == 1 && len(m) != 0 {
-		_, z = nat(nil).div(z, x, m)
-		return z
+	// 0**y = 0
+	if len(x) == 0 {
+		return z.setWord(0)
+	}
+	// x > 0
+
+	// 1**y = 1
+	if len(x) == 1 && x[0] == 1 {
+		return z.setWord(1)
+	}
+	// x > 1
+
+	// x**1 == x
+	if len(y) == 1 && y[0] == 1 {
+		if len(m) != 0 {
+			return z.rem(x, m)
+		}
+		return z.set(x)
 	}
 	// y > 1
 
 	if len(m) != 0 {
 		// We likely end up being as long as the modulus.
 		z = z.make(len(m))
-	}
-	z = z.set(x)
 
-	// If the base is non-trivial and the exponent is large, we use
-	// 4-bit, windowed exponentiation. This involves precomputing 14 values
-	// (x^2...x^15) but then reduces the number of multiply-reduces by a
-	// third. Even for a 32-bit exponent, this reduces the number of
-	// operations. Uses Montgomery method for odd moduli.
-	if x.cmp(natOne) > 0 && len(y) > 1 && len(m) > 0 {
-		if m[0]&1 == 1 {
-			return z.expNNMontgomery(x, y, m)
+		// If the exponent is large, we use the Montgomery method for odd values,
+		// and a 4-bit, windowed exponentiation for powers of two,
+		// and a CRT-decomposed Montgomery method for the remaining values
+		// (even values times non-trivial odd values, which decompose into one
+		// instance of each of the first two cases).
+		if len(y) > 1 && !slow {
+			if m[0]&1 == 1 {
+				return z.expNNMontgomery(x, y, m)
+			}
+			if logM, ok := m.isPow2(); ok {
+				return z.expNNWindowed(x, y, logM)
+			}
+			return z.expNNMontgomeryEven(x, y, m)
 		}
-		return z.expNNWindowed(x, y, m)
 	}
 
+	z = z.set(x)
 	v := y[len(y)-1] // v > 0 because y is normalized and y > 0
 	shift := nlz(v) + 1
 	v <<= shift
@@ -995,66 +1059,151 @@
 	return z.norm()
 }
 
-// expNNWindowed calculates x**y mod m using a fixed, 4-bit window.
-func (z nat) expNNWindowed(x, y, m nat) nat {
-	// zz and r are used to avoid allocating in mul and div as otherwise
+// expNNMontgomeryEven calculates x**y mod m where m = m1 × m2 for m1 = 2ⁿ and m2 odd.
+// It uses two recursive calls to expNN for x**y mod m1 and x**y mod m2
+// and then uses the Chinese Remainder Theorem to combine the results.
+// The recursive call using m1 will use expNNWindowed,
+// while the recursive call using m2 will use expNNMontgomery.
+// For more details, see Ç. K. Koç, “Montgomery Reduction with Even Modulus”,
+// IEE Proceedings: Computers and Digital Techniques, 141(5) 314-316, September 1994.
+// http://www.people.vcu.edu/~jwang3/CMSC691/j34monex.pdf
+func (z nat) expNNMontgomeryEven(x, y, m nat) nat {
+	// Split m = m₁ × m₂ where m₁ = 2ⁿ
+	n := m.trailingZeroBits()
+	m1 := nat(nil).shl(natOne, n)
+	m2 := nat(nil).shr(m, n)
+
+	// We want z = x**y mod m.
+	// z₁ = x**y mod m1 = (x**y mod m) mod m1 = z mod m1
+	// z₂ = x**y mod m2 = (x**y mod m) mod m2 = z mod m2
+	// (We are using the math/big convention for names here,
+	// where the computation is z = x**y mod m, so its parts are z1 and z2.
+	// The paper is computing x = a**e mod n; it refers to these as x2 and z1.)
+	z1 := nat(nil).expNN(x, y, m1, false)
+	z2 := nat(nil).expNN(x, y, m2, false)
+
+	// Reconstruct z from z₁, z₂ using CRT, using algorithm from paper,
+	// which uses only a single modInverse (and an easy one at that).
+	//	p = (z₁ - z₂) × m₂⁻¹ (mod m₁)
+	//	z = z₂ + p × m₂
+	// The final addition is in range because:
+	//	z = z₂ + p × m₂
+	//	  ≤ z₂ + (m₁-1) × m₂
+	//	  < m₂ + (m₁-1) × m₂
+	//	  = m₁ × m₂
+	//	  = m.
+	z = z.set(z2)
+
+	// Compute (z₁ - z₂) mod m1 [m1 == 2**n] into z1.
+	z1 = z1.subMod2N(z1, z2, n)
+
+	// Reuse z2 for p = (z₁ - z₂) [in z1] * m2⁻¹ (mod m₁ [= 2ⁿ]).
+	m2inv := nat(nil).modInverse(m2, m1)
+	z2 = z2.mul(z1, m2inv)
+	z2 = z2.trunc(z2, n)
+
+	// Reuse z1 for p * m2.
+	z = z.add(z, z1.mul(z2, m2))
+
+	return z
+}
+
+// expNNWindowed calculates x**y mod m using a fixed, 4-bit window,
+// where m = 2**logM.
+func (z nat) expNNWindowed(x, y nat, logM uint) nat {
+	if len(y) <= 1 {
+		panic("big: misuse of expNNWindowed")
+	}
+	if x[0]&1 == 0 {
+		// len(y) > 1, so y  > logM.
+		// x is even, so x**y is a multiple of 2**y which is a multiple of 2**logM.
+		return z.setWord(0)
+	}
+	if logM == 1 {
+		return z.setWord(1)
+	}
+
+	// zz is used to avoid allocating in mul as otherwise
 	// the arguments would alias.
-	var zz, r nat
+	w := int((logM + _W - 1) / _W)
+	zzp := getNat(w)
+	zz := *zzp
 
 	const n = 4
 	// powers[i] contains x^i.
-	var powers [1 << n]nat
-	powers[0] = natOne
-	powers[1] = x
+	var powers [1 << n]*nat
+	for i := range powers {
+		powers[i] = getNat(w)
+	}
+	*powers[0] = powers[0].set(natOne)
+	*powers[1] = powers[1].trunc(x, logM)
 	for i := 2; i < 1<<n; i += 2 {
-		p2, p, p1 := &powers[i/2], &powers[i], &powers[i+1]
+		p2, p, p1 := powers[i/2], powers[i], powers[i+1]
 		*p = p.sqr(*p2)
-		zz, r = zz.div(r, *p, m)
-		*p, r = r, *p
+		*p = p.trunc(*p, logM)
 		*p1 = p1.mul(*p, x)
-		zz, r = zz.div(r, *p1, m)
-		*p1, r = r, *p1
+		*p1 = p1.trunc(*p1, logM)
 	}
 
+	// Because phi(2**logM) = 2**(logM-1), x**(2**(logM-1)) = 1,
+	// so we can compute x**(y mod 2**(logM-1)) instead of x**y.
+	// That is, we can throw away all but the bottom logM-1 bits of y.
+	// Instead of allocating a new y, we start reading y at the right word
+	// and truncate it appropriately at the start of the loop.
+	i := len(y) - 1
+	mtop := int((logM - 2) / _W) // -2 because the top word of N bits is the (N-1)/W'th word.
+	mmask := ^Word(0)
+	if mbits := (logM - 1) & (_W - 1); mbits != 0 {
+		mmask = (1 << mbits) - 1
+	}
+	if i > mtop {
+		i = mtop
+	}
+	advance := false
 	z = z.setWord(1)
-
-	for i := len(y) - 1; i >= 0; i-- {
+	for ; i >= 0; i-- {
 		yi := y[i]
+		if i == mtop {
+			yi &= mmask
+		}
 		for j := 0; j < _W; j += n {
-			if i != len(y)-1 || j != 0 {
+			if advance {
+				// Account for use of 4 bits in previous iteration.
 				// Unrolled loop for significant performance
 				// gain. Use go test -bench=".*" in crypto/rsa
 				// to check performance before making changes.
 				zz = zz.sqr(z)
 				zz, z = z, zz
-				zz, r = zz.div(r, z, m)
-				z, r = r, z
+				z = z.trunc(z, logM)
 
 				zz = zz.sqr(z)
 				zz, z = z, zz
-				zz, r = zz.div(r, z, m)
-				z, r = r, z
+				z = z.trunc(z, logM)
 
 				zz = zz.sqr(z)
 				zz, z = z, zz
-				zz, r = zz.div(r, z, m)
-				z, r = r, z
+				z = z.trunc(z, logM)
 
 				zz = zz.sqr(z)
 				zz, z = z, zz
-				zz, r = zz.div(r, z, m)
-				z, r = r, z
+				z = z.trunc(z, logM)
 			}
 
-			zz = zz.mul(z, powers[yi>>(_W-n)])
+			zz = zz.mul(z, *powers[yi>>(_W-n)])
 			zz, z = z, zz
-			zz, r = zz.div(r, z, m)
-			z, r = r, z
+			z = z.trunc(z, logM)
 
 			yi <<= n
+			advance = true
 		}
 	}
 
+	*zzp = zz
+	putNat(zzp)
+	for i := range powers {
+		putNat(powers[i])
+	}
+
 	return z.norm()
 }
 
@@ -1156,6 +1305,9 @@
 // cannot be represented in buf, bytes panics. The number i of unused
 // bytes at the beginning of buf is returned as result.
 func (z nat) bytes(buf []byte) (i int) {
+	// This function is used in cryptographic operations. It must not leak
+	// anything but the Int's sign and bit size through side-channels. Any
+	// changes must be reviewed by a security expert.
 	i = len(buf)
 	for _, d := range z {
 		for j := 0; j < _S; j++ {
@@ -1242,3 +1394,36 @@
 		z1, z2 = z2, z1
 	}
 }
+
+// subMod2N returns z = (x - y) mod 2ⁿ.
+func (z nat) subMod2N(x, y nat, n uint) nat {
+	if uint(x.bitLen()) > n {
+		if alias(z, x) {
+			// ok to overwrite x in place
+			x = x.trunc(x, n)
+		} else {
+			x = nat(nil).trunc(x, n)
+		}
+	}
+	if uint(y.bitLen()) > n {
+		if alias(z, y) {
+			// ok to overwrite y in place
+			y = y.trunc(y, n)
+		} else {
+			y = nat(nil).trunc(y, n)
+		}
+	}
+	if x.cmp(y) >= 0 {
+		return z.sub(x, y)
+	}
+	// x - y < 0; x - y mod 2ⁿ = x - y + 2ⁿ = 2ⁿ - (y - x) = 1 + 2ⁿ-1 - (y - x) = 1 + ^(y - x).
+	z = z.sub(y, x)
+	for uint(len(z))*_W < n {
+		z = append(z, 0)
+	}
+	for i := range z {
+		z[i] = ^z[i]
+	}
+	z = z.trunc(z, n)
+	return z.add(z, natOne)
+}
diff --git a/src/math/big/nat_test.go b/src/math/big/nat_test.go
index 0850818..b84a7be 100644
--- a/src/math/big/nat_test.go
+++ b/src/math/big/nat_test.go
@@ -523,6 +523,12 @@
 		"444747819283133684179",
 		"42",
 	},
+	{"375", "249", "388", "175"},
+	{"375", "18446744073709551801", "388", "175"},
+	{"0", "0x40000000000000", "0x200", "0"},
+	{"0xeffffff900002f00", "0x40000000000000", "0x200", "0"},
+	{"5", "1435700818", "72", "49"},
+	{"0xffff", "0x300030003000300030003000300030003000302a3000300030003000300030003000300030003000300030003000300030003030623066307f3030783062303430383064303630343036", "0x300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0xa3f94c08b0b90e87af637cacc9383f7ea032352b8961fc036a52b659b6c9b33491b335ffd74c927f64ddd62cfca0001"},
 }
 
 func TestExpNN(t *testing.T) {
@@ -536,13 +542,29 @@
 			m = natFromString(test.m)
 		}
 
-		z := nat(nil).expNN(x, y, m)
+		z := nat(nil).expNN(x, y, m, false)
 		if z.cmp(out) != 0 {
 			t.Errorf("#%d got %s want %s", i, z.utoa(10), out.utoa(10))
 		}
 	}
 }
 
+func FuzzExpMont(f *testing.F) {
+	f.Fuzz(func(t *testing.T, x1, x2, x3, y1, y2, y3, m1, m2, m3 uint) {
+		if m1 == 0 && m2 == 0 && m3 == 0 {
+			return
+		}
+		x := new(Int).SetBits([]Word{Word(x1), Word(x2), Word(x3)})
+		y := new(Int).SetBits([]Word{Word(y1), Word(y2), Word(y3)})
+		m := new(Int).SetBits([]Word{Word(m1), Word(m2), Word(m3)})
+		out := new(Int).Exp(x, y, m)
+		want := new(Int).expSlow(x, y, m)
+		if out.Cmp(want) != 0 {
+			t.Errorf("x = %#x\ny=%#x\nz=%#x\nout=%#x\nwant=%#x\ndc: 16o 16i %X %X %X |p", x, y, m, out, want, x, y, m)
+		}
+	})
+}
+
 func BenchmarkExp3Power(b *testing.B) {
 	const x = 3
 	for _, y := range []Word{
@@ -733,6 +755,54 @@
 	}
 }
 
+var subMod2NTests = []struct {
+	x string
+	y string
+	n uint
+	z string
+}{
+	{"1", "2", 0, "0"},
+	{"1", "0", 1, "1"},
+	{"0", "1", 1, "1"},
+	{"3", "5", 3, "6"},
+	{"5", "3", 3, "2"},
+	// 2^65, 2^66-1, 2^65 - (2^66-1) + 2^67
+	{"36893488147419103232", "73786976294838206463", 67, "110680464442257309697"},
+	// 2^66-1, 2^65, 2^65-1
+	{"73786976294838206463", "36893488147419103232", 67, "36893488147419103231"},
+}
+
+func TestNatSubMod2N(t *testing.T) {
+	for _, mode := range []string{"noalias", "aliasX", "aliasY"} {
+		t.Run(mode, func(t *testing.T) {
+			for _, tt := range subMod2NTests {
+				x0 := natFromString(tt.x)
+				y0 := natFromString(tt.y)
+				want := natFromString(tt.z)
+				x := nat(nil).set(x0)
+				y := nat(nil).set(y0)
+				var z nat
+				switch mode {
+				case "aliasX":
+					z = x
+				case "aliasY":
+					z = y
+				}
+				z = z.subMod2N(x, y, tt.n)
+				if z.cmp(want) != 0 {
+					t.Fatalf("subMod2N(%d, %d, %d) = %d, want %d", x0, y0, tt.n, z, want)
+				}
+				if mode != "aliasX" && x.cmp(x0) != 0 {
+					t.Fatalf("subMod2N(%d, %d, %d) modified x", x0, y0, tt.n)
+				}
+				if mode != "aliasY" && y.cmp(y0) != 0 {
+					t.Fatalf("subMod2N(%d, %d, %d) modified y", x0, y0, tt.n)
+				}
+			}
+		})
+	}
+}
+
 func BenchmarkNatSetBytes(b *testing.B) {
 	const maxLength = 128
 	lengths := []int{
diff --git a/src/math/big/natconv.go b/src/math/big/natconv.go
index 21fdab5..ce94f2c 100644
--- a/src/math/big/natconv.go
+++ b/src/math/big/natconv.go
@@ -452,10 +452,10 @@
 
 // expWW computes x**y
 func (z nat) expWW(x, y Word) nat {
-	return z.expNN(nat(nil).setWord(x), nat(nil).setWord(y), nil)
+	return z.expNN(nat(nil).setWord(x), nat(nil).setWord(y), nil, false)
 }
 
-// construct table of powers of bb*leafSize to use in subdivisions
+// construct table of powers of bb*leafSize to use in subdivisions.
 func divisors(m int, b Word, ndigits int, bb Word) []divisor {
 	// only compute table when recursive conversion is enabled and x is large
 	if leafSize == 0 || m <= leafSize {
diff --git a/src/math/big/natdiv.go b/src/math/big/natdiv.go
index 882bb6d..14233a2 100644
--- a/src/math/big/natdiv.go
+++ b/src/math/big/natdiv.go
@@ -500,6 +500,19 @@
 
 import "math/bits"
 
+// rem returns r such that r = u%v.
+// It uses z as the storage for r.
+func (z nat) rem(u, v nat) (r nat) {
+	if alias(z, u) {
+		z = nil
+	}
+	qp := getNat(0)
+	q, r := qp.div(z, u, v)
+	*qp = q
+	putNat(qp)
+	return r
+}
+
 // div returns q, r such that q = ⌊u/v⌋ and r = u%v = u - q·v.
 // It uses z and z2 as the storage for q and r.
 func (z nat) div(z2, u, v nat) (q, r nat) {
diff --git a/src/math/big/prime.go b/src/math/big/prime.go
index d9a5f1e..26688bb 100644
--- a/src/math/big/prime.go
+++ b/src/math/big/prime.go
@@ -103,7 +103,7 @@
 			x = x.random(rand, nm3, nm3Len)
 			x = x.add(x, natTwo)
 		}
-		y = y.expNN(x, q, n)
+		y = y.expNN(x, q, n, false)
 		if y.cmp(natOne) == 0 || y.cmp(nm1) == 0 {
 			continue
 		}
@@ -141,7 +141,7 @@
 //
 // Jacobsen, "Pseudoprime Statistics, Tables, and Data", http://ntheory.org/pseudoprimes.html.
 //
-// Nicely, "The Baillie-PSW Primality Test", http://www.trnicely.net/misc/bpsw.html.
+// Nicely, "The Baillie-PSW Primality Test", https://web.archive.org/web/20191121062007/http://www.trnicely.net/misc/bpsw.html.
 // (Note that Nicely's definition of the "extra strong" test gives the wrong Jacobi condition,
 // as pointed out by Jacobsen.)
 //
diff --git a/src/math/big/ratconv.go b/src/math/big/ratconv.go
index 794a51d..8537a67 100644
--- a/src/math/big/ratconv.go
+++ b/src/math/big/ratconv.go
@@ -178,7 +178,7 @@
 		if n > 1e6 {
 			return nil, false // avoid excessively large exponents
 		}
-		pow5 := z.b.abs.expNN(natFive, nat(nil).setWord(Word(n)), nil) // use underlying array of z.b.abs
+		pow5 := z.b.abs.expNN(natFive, nat(nil).setWord(Word(n)), nil, false) // use underlying array of z.b.abs
 		if exp5 > 0 {
 			z.a.abs = z.a.abs.mul(z.a.abs, pow5)
 			z.b.abs = z.b.abs.setWord(1)
@@ -346,7 +346,7 @@
 
 	p := natOne
 	if prec > 0 {
-		p = nat(nil).expNN(natTen, nat(nil).setUint64(uint64(prec)), nil)
+		p = nat(nil).expNN(natTen, nat(nil).setUint64(uint64(prec)), nil, false)
 	}
 
 	r = r.mul(r, p)
diff --git a/src/math/big/ratmarsh.go b/src/math/big/ratmarsh.go
index 56102e8..b69c59d 100644
--- a/src/math/big/ratmarsh.go
+++ b/src/math/big/ratmarsh.go
@@ -10,6 +10,7 @@
 	"encoding/binary"
 	"errors"
 	"fmt"
+	"math"
 )
 
 // Gob codec version. Permits backward-compatible changes to the encoding.
@@ -53,8 +54,12 @@
 		return fmt.Errorf("Rat.GobDecode: encoding version %d not supported", b>>1)
 	}
 	const j = 1 + 4
-	i := j + binary.BigEndian.Uint32(buf[j-4:j])
-	if len(buf) < int(i) {
+	ln := binary.BigEndian.Uint32(buf[j-4 : j])
+	if uint64(ln) > math.MaxInt-j {
+		return errors.New("Rat.GobDecode: invalid length")
+	}
+	i := j + int(ln)
+	if len(buf) < i {
 		return errors.New("Rat.GobDecode: buffer too small")
 	}
 	z.a.neg = b&1 != 0
diff --git a/src/math/big/ratmarsh_test.go b/src/math/big/ratmarsh_test.go
index 55a9878..15c933e 100644
--- a/src/math/big/ratmarsh_test.go
+++ b/src/math/big/ratmarsh_test.go
@@ -128,6 +128,7 @@
 	for _, tc := range [][]byte{
 		[]byte{0x2},
 		[]byte{0x2, 0x0, 0x0, 0x0, 0xff},
+		[]byte{0x2, 0xff, 0xff, 0xff, 0xff},
 	} {
 		err := NewRat(1, 2).GobDecode(tc)
 		if err == nil {
diff --git a/src/math/bits/bits.go b/src/math/bits/bits.go
index 65452fe..c1c7b79 100644
--- a/src/math/bits/bits.go
+++ b/src/math/bits/bits.go
@@ -6,6 +6,12 @@
 
 // Package bits implements bit counting and manipulation
 // functions for the predeclared unsigned integer types.
+//
+// Functions in this package may be implemented directly by
+// the compiler, for better performance. For those functions
+// the code in this package will not be used. Which
+// functions are implemented by the compiler depends on the
+// architecture and the Go release.
 package bits
 
 const uintSize = 32 << (^uint(0) >> 63) // 32 or 64
@@ -510,10 +516,6 @@
 // half in parameter hi and the lower half in parameter lo.
 // Div64 panics for y == 0 (division by zero) or y <= hi (quotient overflow).
 func Div64(hi, lo, y uint64) (quo, rem uint64) {
-	const (
-		two32  = 1 << 32
-		mask32 = two32 - 1
-	)
 	if y == 0 {
 		panic(divideError)
 	}
@@ -521,9 +523,18 @@
 		panic(overflowError)
 	}
 
+	// If high part is zero, we can directly return the results.
+	if hi == 0 {
+		return lo / y, lo % y
+	}
+
 	s := uint(LeadingZeros64(y))
 	y <<= s
 
+	const (
+		two32  = 1 << 32
+		mask32 = two32 - 1
+	)
 	yn1 := y >> 32
 	yn0 := y & mask32
 	un32 := hi<<s | lo>>(64-s)
diff --git a/src/math/cmplx/sin.go b/src/math/cmplx/sin.go
index febac0e..51cf405 100644
--- a/src/math/cmplx/sin.go
+++ b/src/math/cmplx/sin.go
@@ -172,7 +172,7 @@
 	return complex(c*ch, s*sh)
 }
 
-// calculate sinh and cosh
+// calculate sinh and cosh.
 func sinhcosh(x float64) (sh, ch float64) {
 	if math.Abs(x) <= 0.5 {
 		return math.Sinh(x), math.Cosh(x)
diff --git a/src/math/const.go b/src/math/const.go
index 5ea935f..b15e50e 100644
--- a/src/math/const.go
+++ b/src/math/const.go
@@ -39,19 +39,19 @@
 const (
 	intSize = 32 << (^uint(0) >> 63) // 32 or 64
 
-	MaxInt    = 1<<(intSize-1) - 1
-	MinInt    = -1 << (intSize - 1)
-	MaxInt8   = 1<<7 - 1
-	MinInt8   = -1 << 7
-	MaxInt16  = 1<<15 - 1
-	MinInt16  = -1 << 15
-	MaxInt32  = 1<<31 - 1
-	MinInt32  = -1 << 31
-	MaxInt64  = 1<<63 - 1
-	MinInt64  = -1 << 63
-	MaxUint   = 1<<intSize - 1
-	MaxUint8  = 1<<8 - 1
-	MaxUint16 = 1<<16 - 1
-	MaxUint32 = 1<<32 - 1
-	MaxUint64 = 1<<64 - 1
+	MaxInt    = 1<<(intSize-1) - 1  // MaxInt32 or MaxInt64 depending on intSize.
+	MinInt    = -1 << (intSize - 1) // MinInt32 or MinInt64 depending on intSize.
+	MaxInt8   = 1<<7 - 1            // 127
+	MinInt8   = -1 << 7             // -128
+	MaxInt16  = 1<<15 - 1           // 32767
+	MinInt16  = -1 << 15            // -32768
+	MaxInt32  = 1<<31 - 1           // 2147483647
+	MinInt32  = -1 << 31            // -2147483648
+	MaxInt64  = 1<<63 - 1           // 9223372036854775807
+	MinInt64  = -1 << 63            // -9223372036854775808
+	MaxUint   = 1<<intSize - 1      // MaxUint32 or MaxUint64 depending on intSize.
+	MaxUint8  = 1<<8 - 1            // 255
+	MaxUint16 = 1<<16 - 1           // 65535
+	MaxUint32 = 1<<32 - 1           // 4294967295
+	MaxUint64 = 1<<64 - 1           // 18446744073709551615
 )
diff --git a/src/math/hypot.go b/src/math/hypot.go
index 4e79de0..6ae70c1 100644
--- a/src/math/hypot.go
+++ b/src/math/hypot.go
@@ -25,14 +25,14 @@
 }
 
 func hypot(p, q float64) float64 {
+	p, q = Abs(p), Abs(q)
 	// special cases
 	switch {
-	case IsInf(p, 0) || IsInf(q, 0):
+	case IsInf(p, 1) || IsInf(q, 1):
 		return Inf(1)
 	case IsNaN(p) || IsNaN(q):
 		return NaN()
 	}
-	p, q = Abs(p), Abs(q)
 	if p < q {
 		p, q = q, p
 	}
diff --git a/src/math/logb.go b/src/math/logb.go
index 04ba3e9..1a46464 100644
--- a/src/math/logb.go
+++ b/src/math/logb.go
@@ -44,7 +44,7 @@
 	return ilogb(x)
 }
 
-// logb returns the binary exponent of x. It assumes x is finite and
+// ilogb returns the binary exponent of x. It assumes x is finite and
 // non-zero.
 func ilogb(x float64) int {
 	x, exp := normalize(x)
diff --git a/src/math/rand/auto_test.go b/src/math/rand/auto_test.go
new file mode 100644
index 0000000..b057370
--- /dev/null
+++ b/src/math/rand/auto_test.go
@@ -0,0 +1,40 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package rand_test
+
+import (
+	. "math/rand"
+	"testing"
+)
+
+// This test is first, in its own file with an alphabetically early name,
+// to try to make sure that it runs early. It has the best chance of
+// detecting deterministic seeding if it's the first test that runs.
+
+func TestAuto(t *testing.T) {
+	// Pull out 10 int64s from the global source
+	// and then check that they don't appear in that
+	// order in the deterministic Seed(1) result.
+	var out []int64
+	for i := 0; i < 10; i++ {
+		out = append(out, Int63())
+	}
+
+	// Look for out in Seed(1)'s output.
+	// Strictly speaking, we should look for them in order,
+	// but this is good enough and not significantly more
+	// likely to have a false positive.
+	Seed(1)
+	found := 0
+	for i := 0; i < 1000; i++ {
+		x := Int63()
+		if x == out[found] {
+			found++
+			if found == len(out) {
+				t.Fatalf("found unseeded output in Seed(1) output")
+			}
+		}
+	}
+}
diff --git a/src/math/rand/example_test.go b/src/math/rand/example_test.go
index f691e39..d656f47 100644
--- a/src/math/rand/example_test.go
+++ b/src/math/rand/example_test.go
@@ -16,10 +16,6 @@
 // the output of the random number generator when given a fixed seed.
 
 func Example() {
-	// Seeding with the same value results in the same random sequence each run.
-	// For different numbers, seed with a different value, such as
-	// time.Now().UnixNano(), which yields a constantly-changing number.
-	rand.Seed(42)
 	answers := []string{
 		"It is certain",
 		"It is decidedly so",
@@ -43,7 +39,6 @@
 		"Very doubtful",
 	}
 	fmt.Println("Magic 8-Ball says:", answers[rand.Intn(len(answers))])
-	// Output: Magic 8-Ball says: As I see it yes
 }
 
 // This example shows the use of each of the methods on a *Rand.
@@ -116,9 +111,6 @@
 		words[i], words[j] = words[j], words[i]
 	})
 	fmt.Println(words)
-
-	// Output:
-	// [mouth my the of runs corners from ink]
 }
 
 func ExampleShuffle_slicesInUnison() {
@@ -132,26 +124,10 @@
 	for i := range numbers {
 		fmt.Printf("%c: %c\n", letters[i], numbers[i])
 	}
-
-	// Output:
-	// C: 3
-	// D: 4
-	// A: 1
-	// E: 5
-	// B: 2
 }
 
 func ExampleIntn() {
-	// Seeding with the same value results in the same random sequence each run.
-	// For different numbers, seed with a different value, such as
-	// time.Now().UnixNano(), which yields a constantly-changing number.
-	rand.Seed(86)
 	fmt.Println(rand.Intn(100))
 	fmt.Println(rand.Intn(100))
 	fmt.Println(rand.Intn(100))
-
-	// Output:
-	// 42
-	// 76
-	// 30
 }
diff --git a/src/math/rand/rand.go b/src/math/rand/rand.go
index 4cce3da..77d7e86 100644
--- a/src/math/rand/rand.go
+++ b/src/math/rand/rand.go
@@ -5,22 +5,28 @@
 // Package rand implements pseudo-random number generators unsuitable for
 // security-sensitive work.
 //
-// Random numbers are generated by a Source. Top-level functions, such as
-// Float64 and Int, use a default shared Source that produces a deterministic
-// sequence of values each time a program is run. Use the Seed function to
-// initialize the default Source if different behavior is required for each run.
-// The default Source is safe for concurrent use by multiple goroutines, but
-// Sources created by NewSource are not.
+// Random numbers are generated by a [Source], usually wrapped in a [Rand].
+// Both types should be used by a single goroutine at a time: sharing among
+// multiple goroutines requires some kind of synchronization.
+//
+// Top-level functions, such as [Float64] and [Int],
+// are safe for concurrent use by multiple goroutines.
 //
 // This package's outputs might be easily predictable regardless of how it's
 // seeded. For random numbers suitable for security-sensitive work, see the
 // crypto/rand package.
 package rand
 
-import "sync"
+import (
+	"internal/godebug"
+	"sync"
+	_ "unsafe" // for go:linkname
+)
 
 // A Source represents a source of uniformly-distributed
 // pseudo-random int64 values in the range [0, 1<<63).
+//
+// A Source is not safe for concurrent use by multiple goroutines.
 type Source interface {
 	Int63() int64
 	Seed(seed int64)
@@ -40,7 +46,12 @@
 // NewSource returns a new pseudo-random Source seeded with the given value.
 // Unlike the default Source used by top-level functions, this source is not
 // safe for concurrent use by multiple goroutines.
+// The returned Source implements Source64.
 func NewSource(seed int64) Source {
+	return newSource(seed)
+}
+
+func newSource(seed int64) *rngSource {
 	var rng rngSource
 	rng.Seed(seed)
 	return &rng
@@ -290,16 +301,26 @@
  * Top-level convenience functions
  */
 
-var globalRand = New(&lockedSource{src: NewSource(1).(*rngSource)})
-
-// Type assert that globalRand's source is a lockedSource whose src is a *rngSource.
-var _ *rngSource = globalRand.src.(*lockedSource).src
+var globalRand = New(new(lockedSource))
 
 // Seed uses the provided seed value to initialize the default Source to a
-// deterministic state. If Seed is not called, the generator behaves as
-// if seeded by Seed(1). Seed values that have the same remainder when
+// deterministic state. Seed values that have the same remainder when
 // divided by 2³¹-1 generate the same pseudo-random sequence.
 // Seed, unlike the Rand.Seed method, is safe for concurrent use.
+//
+// If Seed is not called, the generator is seeded randomly at program startup.
+//
+// Prior to Go 1.20, the generator was seeded like Seed(1) at program startup.
+// To force the old behavior, call Seed(1) at program startup.
+// Alternately, set GODEBUG=randautoseed=0 in the environment
+// before making any calls to functions in this package.
+//
+// Deprecated: Programs that call Seed and then expect a specific sequence
+// of results from the global random source (using functions such as Int)
+// can be broken when a dependency changes how much it consumes
+// from the global random source. To avoid such breakages, programs
+// that need a specific result sequence should use NewRand(NewSource(seed))
+// to obtain a random generator that other packages cannot access.
 func Seed(seed int64) { globalRand.Seed(seed) }
 
 // Int63 returns a non-negative pseudo-random 63-bit integer as an int64
@@ -356,6 +377,8 @@
 // Read generates len(p) random bytes from the default Source and
 // writes them into p. It always returns len(p) and a nil error.
 // Read, unlike the Rand.Read method, is safe for concurrent use.
+//
+// Deprecated: For almost all use cases, crypto/rand.Read is more appropriate.
 func Read(p []byte) (n int, err error) { return globalRand.Read(p) }
 
 // NormFloat64 returns a normally distributed float64 in the range
@@ -378,42 +401,72 @@
 func ExpFloat64() float64 { return globalRand.ExpFloat64() }
 
 type lockedSource struct {
-	lk  sync.Mutex
-	src *rngSource
+	lk sync.Mutex
+	s  *rngSource // nil if not yet allocated
+}
+
+//go:linkname fastrand64
+func fastrand64() uint64
+
+var randautoseed = godebug.New("randautoseed")
+
+// source returns r.s, allocating and seeding it if needed.
+// The caller must have locked r.
+func (r *lockedSource) source() *rngSource {
+	if r.s == nil {
+		var seed int64
+		if randautoseed.Value() == "0" {
+			seed = 1
+		} else {
+			seed = int64(fastrand64())
+		}
+		r.s = newSource(seed)
+	}
+	return r.s
 }
 
 func (r *lockedSource) Int63() (n int64) {
 	r.lk.Lock()
-	n = r.src.Int63()
+	n = r.source().Int63()
 	r.lk.Unlock()
 	return
 }
 
 func (r *lockedSource) Uint64() (n uint64) {
 	r.lk.Lock()
-	n = r.src.Uint64()
+	n = r.source().Uint64()
 	r.lk.Unlock()
 	return
 }
 
 func (r *lockedSource) Seed(seed int64) {
 	r.lk.Lock()
-	r.src.Seed(seed)
+	r.seed(seed)
 	r.lk.Unlock()
 }
 
 // seedPos implements Seed for a lockedSource without a race condition.
 func (r *lockedSource) seedPos(seed int64, readPos *int8) {
 	r.lk.Lock()
-	r.src.Seed(seed)
+	r.seed(seed)
 	*readPos = 0
 	r.lk.Unlock()
 }
 
+// seed seeds the underlying source.
+// The caller must have locked r.lk.
+func (r *lockedSource) seed(seed int64) {
+	if r.s == nil {
+		r.s = newSource(seed)
+	} else {
+		r.s.Seed(seed)
+	}
+}
+
 // read implements Read for a lockedSource without a race condition.
 func (r *lockedSource) read(p []byte, readVal *int64, readPos *int8) (n int, err error) {
 	r.lk.Lock()
-	n, err = read(p, r.src, readVal, readPos)
+	n, err = read(p, r.source(), readVal, readPos)
 	r.lk.Unlock()
 	return
 }
diff --git a/src/math/sqrt.go b/src/math/sqrt.go
index b6d80c2..54929eb 100644
--- a/src/math/sqrt.go
+++ b/src/math/sqrt.go
@@ -91,15 +91,10 @@
 //	Sqrt(x < 0) = NaN
 //	Sqrt(NaN) = NaN
 func Sqrt(x float64) float64 {
-	if haveArchSqrt {
-		return archSqrt(x)
-	}
 	return sqrt(x)
 }
 
-// Note: Sqrt is implemented in assembly on some systems.
-// Others have assembly stubs that jump to func sqrt below.
-// On systems where Sqrt is a single instruction, the compiler
+// Note: On systems where Sqrt is a single instruction, the compiler
 // may turn a direct call into a direct use of that instruction instead.
 
 func sqrt(x float64) float64 {
diff --git a/src/math/sqrt_386.s b/src/math/sqrt_386.s
deleted file mode 100644
index 90aec13..0000000
--- a/src/math/sqrt_386.s
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-
-// func archSqrt(x float64) float64
-TEXT ·archSqrt(SB),NOSPLIT,$0
-	FMOVD   x+0(FP),F0
-	FSQRT
-	FMOVDP  F0,ret+8(FP)
-	RET
diff --git a/src/math/sqrt_amd64.s b/src/math/sqrt_amd64.s
deleted file mode 100644
index c3b110e..0000000
--- a/src/math/sqrt_amd64.s
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-
-// func archSqrt(x float64) float64
-TEXT ·archSqrt(SB), NOSPLIT, $0
-	XORPS  X0, X0 // break dependency
-	SQRTSD x+0(FP), X0
-	MOVSD  X0, ret+8(FP)
-	RET
diff --git a/src/math/sqrt_arm.s b/src/math/sqrt_arm.s
deleted file mode 100644
index 64792ec..0000000
--- a/src/math/sqrt_arm.s
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-
-// func archSqrt(x float64) float64
-TEXT ·archSqrt(SB),NOSPLIT,$0
-	MOVB	runtime·goarm(SB), R11
-	CMP	$5, R11
-	BEQ	arm5
-	MOVD	x+0(FP),F0
-	SQRTD	F0,F0
-	MOVD	F0,ret+8(FP)
-	RET
-arm5:
-	// Tail call to Go implementation.
-	// Can't use JMP, as in softfloat mode SQRTD is rewritten
-	// to a CALL, which makes this function have a frame.
-	RET	·sqrt(SB)
diff --git a/src/math/sqrt_arm64.s b/src/math/sqrt_arm64.s
deleted file mode 100644
index 36ba41a..0000000
--- a/src/math/sqrt_arm64.s
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-
-// func archSqrt(x float64) float64
-TEXT ·archSqrt(SB),NOSPLIT,$0
-	FMOVD	x+0(FP), F0
-	FSQRTD	F0, F0
-	FMOVD	F0, ret+8(FP)
-	RET
diff --git a/src/math/sqrt_asm.go b/src/math/sqrt_asm.go
deleted file mode 100644
index 2cec1a5..0000000
--- a/src/math/sqrt_asm.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build 386 || amd64 || arm64 || arm || mips || mipsle || ppc64 || ppc64le || s390x || riscv64 || wasm
-
-package math
-
-const haveArchSqrt = true
-
-func archSqrt(x float64) float64
diff --git a/src/math/sqrt_mipsx.s b/src/math/sqrt_mipsx.s
deleted file mode 100644
index 291d4af..0000000
--- a/src/math/sqrt_mipsx.s
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build mips || mipsle
-// +build mips mipsle
-
-#include "textflag.h"
-
-// func archSqrt(x float64) float64
-TEXT ·archSqrt(SB),NOSPLIT,$0
-#ifdef GOMIPS_softfloat
-	JMP ·sqrt(SB)
-#else
-	MOVD	x+0(FP), F0
-	SQRTD	F0, F0
-	MOVD	F0, ret+8(FP)
-#endif
-	RET
diff --git a/src/math/sqrt_noasm.go b/src/math/sqrt_noasm.go
deleted file mode 100644
index 3979622..0000000
--- a/src/math/sqrt_noasm.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build !386 && !amd64 && !arm64 && !arm && !mips && !mipsle && !ppc64 && !ppc64le && !s390x && !riscv64 && !wasm
-
-package math
-
-const haveArchSqrt = false
-
-func archSqrt(x float64) float64 {
-	panic("not implemented")
-}
diff --git a/src/math/sqrt_ppc64x.s b/src/math/sqrt_ppc64x.s
deleted file mode 100644
index c929da2..0000000
--- a/src/math/sqrt_ppc64x.s
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build ppc64 || ppc64le
-// +build ppc64 ppc64le
-
-#include "textflag.h"
-
-// func archSqrt(x float64) float64
-TEXT ·archSqrt(SB),NOSPLIT,$0
-	FMOVD	x+0(FP), F0
-	FSQRT	F0, F0
-	FMOVD	F0, ret+8(FP)
-	RET
diff --git a/src/math/sqrt_riscv64.s b/src/math/sqrt_riscv64.s
deleted file mode 100644
index 0dbdbc9..0000000
--- a/src/math/sqrt_riscv64.s
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-
-// func archSqrt(x float64) float64
-TEXT ·archSqrt(SB),NOSPLIT,$0
-	MOVD	x+0(FP), F0
-	FSQRTD	F0, F0
-	MOVD	F0, ret+8(FP)
-	RET
diff --git a/src/math/sqrt_s390x.s b/src/math/sqrt_s390x.s
deleted file mode 100644
index fa31f75..0000000
--- a/src/math/sqrt_s390x.s
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-
-// func archSqrt(x float64) float64
-TEXT ·archSqrt(SB),NOSPLIT,$0
-	FMOVD x+0(FP), F1
-	FSQRT F1, F1
-	FMOVD F1, ret+8(FP)
-	RET
diff --git a/src/math/sqrt_wasm.s b/src/math/sqrt_wasm.s
deleted file mode 100644
index fa6799d..0000000
--- a/src/math/sqrt_wasm.s
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "textflag.h"
-
-TEXT ·archSqrt(SB),NOSPLIT,$0
-	Get SP
-	F64Load x+0(FP)
-	F64Sqrt
-	F64Store ret+8(FP)
-	RET
diff --git a/src/mime/mediatype.go b/src/mime/mediatype.go
index 6c1b095..bc8d417 100644
--- a/src/mime/mediatype.go
+++ b/src/mime/mediatype.go
@@ -180,8 +180,8 @@
 				pmap = continuation[baseName]
 			}
 		}
-		if _, exists := pmap[key]; exists {
-			// Duplicate parameter name is bogus.
+		if v, exists := pmap[key]; exists && v != value {
+			// Duplicate parameter names are incorrect, but we allow them if they are equal.
 			return "", nil, errors.New("mime: duplicate parameter name")
 		}
 		pmap[key] = value
diff --git a/src/mime/mediatype_test.go b/src/mime/mediatype_test.go
index 079c080..1458cdb 100644
--- a/src/mime/mediatype_test.go
+++ b/src/mime/mediatype_test.go
@@ -407,8 +407,11 @@
 			`message/external-body`,
 			m("access-type", "URL", "url", "ftp://cs.utk.edu/pub/moore/bulk-mailer/bulk-mailer.tar"),
 		},
-	}
 
+		// Issue #48866: duplicate parameters containing equal values should be allowed
+		{`text; charset=utf-8; charset=utf-8; format=fixed`, "text", m("charset", "utf-8", "format", "fixed")},
+		{`text; charset=utf-8; format=flowed; charset=utf-8`, "text", m("charset", "utf-8", "format", "flowed")},
+	}
 	for _, test := range tests {
 		mt, params, err := ParseMediaType(test.in)
 		if err != nil {
diff --git a/src/mime/multipart/formdata.go b/src/mime/multipart/formdata.go
index fca5f9e..41bc886 100644
--- a/src/mime/multipart/formdata.go
+++ b/src/mime/multipart/formdata.go
@@ -7,6 +7,7 @@
 import (
 	"bytes"
 	"errors"
+	"internal/godebug"
 	"io"
 	"math"
 	"net/textproto"
@@ -31,25 +32,61 @@
 	return r.readForm(maxMemory)
 }
 
+var multipartFiles = godebug.New("multipartfiles")
+
 func (r *Reader) readForm(maxMemory int64) (_ *Form, err error) {
 	form := &Form{make(map[string][]string), make(map[string][]*FileHeader)}
+	var (
+		file    *os.File
+		fileOff int64
+	)
+	numDiskFiles := 0
+	combineFiles := multipartFiles.Value() != "distinct"
 	defer func() {
+		if file != nil {
+			if cerr := file.Close(); err == nil {
+				err = cerr
+			}
+		}
+		if combineFiles && numDiskFiles > 1 {
+			for _, fhs := range form.File {
+				for _, fh := range fhs {
+					fh.tmpshared = true
+				}
+			}
+		}
 		if err != nil {
 			form.RemoveAll()
+			if file != nil {
+				os.Remove(file.Name())
+			}
 		}
 	}()
 
-	// Reserve an additional 10 MB for non-file parts.
-	maxValueBytes := maxMemory + int64(10<<20)
-	if maxValueBytes <= 0 {
+	// maxFileMemoryBytes is the maximum bytes of file data we will store in memory.
+	// Data past this limit is written to disk.
+	// This limit strictly applies to content, not metadata (filenames, MIME headers, etc.),
+	// since metadata is always stored in memory, not disk.
+	//
+	// maxMemoryBytes is the maximum bytes we will store in memory, including file content,
+	// non-file part values, metdata, and map entry overhead.
+	//
+	// We reserve an additional 10 MB in maxMemoryBytes for non-file data.
+	//
+	// The relationship between these parameters, as well as the overly-large and
+	// unconfigurable 10 MB added on to maxMemory, is unfortunate but difficult to change
+	// within the constraints of the API as documented.
+	maxFileMemoryBytes := maxMemory
+	maxMemoryBytes := maxMemory + int64(10<<20)
+	if maxMemoryBytes <= 0 {
 		if maxMemory < 0 {
-			maxValueBytes = 0
+			maxMemoryBytes = 0
 		} else {
-			maxValueBytes = math.MaxInt64
+			maxMemoryBytes = math.MaxInt64
 		}
 	}
 	for {
-		p, err := r.NextPart()
+		p, err := r.nextPart(false, maxMemoryBytes)
 		if err == io.EOF {
 			break
 		}
@@ -63,16 +100,27 @@
 		}
 		filename := p.FileName()
 
+		// Multiple values for the same key (one map entry, longer slice) are cheaper
+		// than the same number of values for different keys (many map entries), but
+		// using a consistent per-value cost for overhead is simpler.
+		maxMemoryBytes -= int64(len(name))
+		maxMemoryBytes -= 100 // map overhead
+		if maxMemoryBytes < 0 {
+			// We can't actually take this path, since nextPart would already have
+			// rejected the MIME headers for being too large. Check anyway.
+			return nil, ErrMessageTooLarge
+		}
+
 		var b bytes.Buffer
 
 		if filename == "" {
 			// value, store as string in memory
-			n, err := io.CopyN(&b, p, maxValueBytes+1)
+			n, err := io.CopyN(&b, p, maxMemoryBytes+1)
 			if err != nil && err != io.EOF {
 				return nil, err
 			}
-			maxValueBytes -= n
-			if maxValueBytes < 0 {
+			maxMemoryBytes -= n
+			if maxMemoryBytes < 0 {
 				return nil, ErrMessageTooLarge
 			}
 			form.Value[name] = append(form.Value[name], b.String())
@@ -80,35 +128,45 @@
 		}
 
 		// file, store in memory or on disk
+		maxMemoryBytes -= mimeHeaderSize(p.Header)
+		if maxMemoryBytes < 0 {
+			return nil, ErrMessageTooLarge
+		}
 		fh := &FileHeader{
 			Filename: filename,
 			Header:   p.Header,
 		}
-		n, err := io.CopyN(&b, p, maxMemory+1)
+		n, err := io.CopyN(&b, p, maxFileMemoryBytes+1)
 		if err != nil && err != io.EOF {
 			return nil, err
 		}
-		if n > maxMemory {
-			// too big, write to disk and flush buffer
-			file, err := os.CreateTemp("", "multipart-")
-			if err != nil {
-				return nil, err
+		if n > maxFileMemoryBytes {
+			if file == nil {
+				file, err = os.CreateTemp(r.tempDir, "multipart-")
+				if err != nil {
+					return nil, err
+				}
 			}
+			numDiskFiles++
 			size, err := io.Copy(file, io.MultiReader(&b, p))
-			if cerr := file.Close(); err == nil {
-				err = cerr
-			}
 			if err != nil {
-				os.Remove(file.Name())
 				return nil, err
 			}
 			fh.tmpfile = file.Name()
 			fh.Size = size
+			fh.tmpoff = fileOff
+			fileOff += size
+			if !combineFiles {
+				if err := file.Close(); err != nil {
+					return nil, err
+				}
+				file = nil
+			}
 		} else {
 			fh.content = b.Bytes()
 			fh.Size = int64(len(fh.content))
-			maxMemory -= n
-			maxValueBytes -= n
+			maxFileMemoryBytes -= n
+			maxMemoryBytes -= n
 		}
 		form.File[name] = append(form.File[name], fh)
 	}
@@ -116,6 +174,17 @@
 	return form, nil
 }
 
+func mimeHeaderSize(h textproto.MIMEHeader) (size int64) {
+	for k, vs := range h {
+		size += int64(len(k))
+		size += 100 // map entry overhead
+		for _, v := range vs {
+			size += int64(len(v))
+		}
+	}
+	return size
+}
+
 // Form is a parsed multipart form.
 // Its File parts are stored either in memory or on disk,
 // and are accessible via the *FileHeader's Open method.
@@ -133,7 +202,7 @@
 		for _, fh := range fhs {
 			if fh.tmpfile != "" {
 				e := os.Remove(fh.tmpfile)
-				if e != nil && err == nil {
+				if e != nil && !errors.Is(e, os.ErrNotExist) && err == nil {
 					err = e
 				}
 			}
@@ -148,15 +217,25 @@
 	Header   textproto.MIMEHeader
 	Size     int64
 
-	content []byte
-	tmpfile string
+	content   []byte
+	tmpfile   string
+	tmpoff    int64
+	tmpshared bool
 }
 
 // Open opens and returns the FileHeader's associated File.
 func (fh *FileHeader) Open() (File, error) {
 	if b := fh.content; b != nil {
 		r := io.NewSectionReader(bytes.NewReader(b), 0, int64(len(b)))
-		return sectionReadCloser{r}, nil
+		return sectionReadCloser{r, nil}, nil
+	}
+	if fh.tmpshared {
+		f, err := os.Open(fh.tmpfile)
+		if err != nil {
+			return nil, err
+		}
+		r := io.NewSectionReader(f, fh.tmpoff, fh.Size)
+		return sectionReadCloser{r, f}, nil
 	}
 	return os.Open(fh.tmpfile)
 }
@@ -175,8 +254,12 @@
 
 type sectionReadCloser struct {
 	*io.SectionReader
+	io.Closer
 }
 
 func (rc sectionReadCloser) Close() error {
+	if rc.Closer != nil {
+		return rc.Closer.Close()
+	}
 	return nil
 }
diff --git a/src/mime/multipart/formdata_test.go b/src/mime/multipart/formdata_test.go
index e3a3a3e..8a862be 100644
--- a/src/mime/multipart/formdata_test.go
+++ b/src/mime/multipart/formdata_test.go
@@ -6,8 +6,10 @@
 
 import (
 	"bytes"
+	"fmt"
 	"io"
 	"math"
+	"net/textproto"
 	"os"
 	"strings"
 	"testing"
@@ -92,7 +94,7 @@
 	if err != nil {
 		t.Fatal("opening file:", err)
 	}
-	b := new(bytes.Buffer)
+	b := new(strings.Builder)
 	_, err = io.Copy(b, f)
 	if err != nil {
 		t.Fatal("copying contents:", err)
@@ -208,8 +210,8 @@
 		maxMemory int64
 		err       error
 	}{
-		{"smaller", 50, nil},
-		{"exact-fit", 25, nil},
+		{"smaller", 50 + int64(len("largetext")) + 100, nil},
+		{"exact-fit", 25 + int64(len("largetext")) + 100, nil},
 		{"too-large", 0, ErrMessageTooLarge},
 	}
 	for _, tc := range testCases {
@@ -224,7 +226,7 @@
 				defer f.RemoveAll()
 			}
 			if tc.err != err {
-				t.Fatalf("ReadForm error - got: %v; expected: %v", tc.err, err)
+				t.Fatalf("ReadForm error - got: %v; expected: %v", err, tc.err)
 			}
 			if err == nil {
 				if g := f.Value["largetext"][0]; g != largeTextValue {
@@ -234,3 +236,135 @@
 		})
 	}
 }
+
+// TestReadForm_MetadataTooLarge verifies that we account for the size of field names,
+// MIME headers, and map entry overhead while limiting the memory consumption of parsed forms.
+func TestReadForm_MetadataTooLarge(t *testing.T) {
+	for _, test := range []struct {
+		name string
+		f    func(*Writer)
+	}{{
+		name: "large name",
+		f: func(fw *Writer) {
+			name := strings.Repeat("a", 10<<20)
+			w, _ := fw.CreateFormField(name)
+			w.Write([]byte("value"))
+		},
+	}, {
+		name: "large MIME header",
+		f: func(fw *Writer) {
+			h := make(textproto.MIMEHeader)
+			h.Set("Content-Disposition", `form-data; name="a"`)
+			h.Set("X-Foo", strings.Repeat("a", 10<<20))
+			w, _ := fw.CreatePart(h)
+			w.Write([]byte("value"))
+		},
+	}, {
+		name: "many parts",
+		f: func(fw *Writer) {
+			for i := 0; i < 110000; i++ {
+				w, _ := fw.CreateFormField("f")
+				w.Write([]byte("v"))
+			}
+		},
+	}} {
+		t.Run(test.name, func(t *testing.T) {
+			var buf bytes.Buffer
+			fw := NewWriter(&buf)
+			test.f(fw)
+			if err := fw.Close(); err != nil {
+				t.Fatal(err)
+			}
+			fr := NewReader(&buf, fw.Boundary())
+			_, err := fr.ReadForm(0)
+			if err != ErrMessageTooLarge {
+				t.Errorf("fr.ReadForm() = %v, want ErrMessageTooLarge", err)
+			}
+		})
+	}
+}
+
+// TestReadForm_ManyFiles_Combined tests that a multipart form containing many files only
+// results in a single on-disk file.
+func TestReadForm_ManyFiles_Combined(t *testing.T) {
+	const distinct = false
+	testReadFormManyFiles(t, distinct)
+}
+
+// TestReadForm_ManyFiles_Distinct tests that setting GODEBUG=multipartfiles=distinct
+// results in every file in a multipart form being placed in a distinct on-disk file.
+func TestReadForm_ManyFiles_Distinct(t *testing.T) {
+	t.Setenv("GODEBUG", "multipartfiles=distinct")
+	const distinct = true
+	testReadFormManyFiles(t, distinct)
+}
+
+func testReadFormManyFiles(t *testing.T, distinct bool) {
+	var buf bytes.Buffer
+	fw := NewWriter(&buf)
+	const numFiles = 10
+	for i := 0; i < numFiles; i++ {
+		name := fmt.Sprint(i)
+		w, err := fw.CreateFormFile(name, name)
+		if err != nil {
+			t.Fatal(err)
+		}
+		w.Write([]byte(name))
+	}
+	if err := fw.Close(); err != nil {
+		t.Fatal(err)
+	}
+	fr := NewReader(&buf, fw.Boundary())
+	fr.tempDir = t.TempDir()
+	form, err := fr.ReadForm(0)
+	if err != nil {
+		t.Fatal(err)
+	}
+	for i := 0; i < numFiles; i++ {
+		name := fmt.Sprint(i)
+		if got := len(form.File[name]); got != 1 {
+			t.Fatalf("form.File[%q] has %v entries, want 1", name, got)
+		}
+		fh := form.File[name][0]
+		file, err := fh.Open()
+		if err != nil {
+			t.Fatalf("form.File[%q].Open() = %v", name, err)
+		}
+		if distinct {
+			if _, ok := file.(*os.File); !ok {
+				t.Fatalf("form.File[%q].Open: %T, want *os.File", name, file)
+			}
+		}
+		got, err := io.ReadAll(file)
+		file.Close()
+		if string(got) != name || err != nil {
+			t.Fatalf("read form.File[%q]: %q, %v; want %q, nil", name, string(got), err, name)
+		}
+	}
+	dir, err := os.Open(fr.tempDir)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer dir.Close()
+	names, err := dir.Readdirnames(0)
+	if err != nil {
+		t.Fatal(err)
+	}
+	wantNames := 1
+	if distinct {
+		wantNames = numFiles
+	}
+	if len(names) != wantNames {
+		t.Fatalf("temp dir contains %v files; want 1", len(names))
+	}
+	if err := form.RemoveAll(); err != nil {
+		t.Fatalf("form.RemoveAll() = %v", err)
+	}
+	names, err = dir.Readdirnames(0)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if len(names) != 0 {
+		t.Fatalf("temp dir contains %v files; want 0", len(names))
+	}
+}
diff --git a/src/mime/multipart/multipart.go b/src/mime/multipart/multipart.go
index aa05ac8..86ea926 100644
--- a/src/mime/multipart/multipart.go
+++ b/src/mime/multipart/multipart.go
@@ -128,12 +128,12 @@
 	return n, r.err
 }
 
-func newPart(mr *Reader, rawPart bool) (*Part, error) {
+func newPart(mr *Reader, rawPart bool, maxMIMEHeaderSize int64) (*Part, error) {
 	bp := &Part{
 		Header: make(map[string][]string),
 		mr:     mr,
 	}
-	if err := bp.populateHeaders(); err != nil {
+	if err := bp.populateHeaders(maxMIMEHeaderSize); err != nil {
 		return nil, err
 	}
 	bp.r = partReader{bp}
@@ -149,12 +149,16 @@
 	return bp, nil
 }
 
-func (p *Part) populateHeaders() error {
+func (p *Part) populateHeaders(maxMIMEHeaderSize int64) error {
 	r := textproto.NewReader(p.mr.bufReader)
-	header, err := r.ReadMIMEHeader()
+	header, err := readMIMEHeader(r, maxMIMEHeaderSize)
 	if err == nil {
 		p.Header = header
 	}
+	// TODO: Add a distinguishable error to net/textproto.
+	if err != nil && err.Error() == "message too large" {
+		err = ErrMessageTooLarge
+	}
 	return err
 }
 
@@ -311,6 +315,7 @@
 // isn't supported.
 type Reader struct {
 	bufReader *bufio.Reader
+	tempDir   string // used in tests
 
 	currentPart *Part
 	partsRead   int
@@ -321,6 +326,10 @@
 	dashBoundary     []byte // "--boundary"
 }
 
+// maxMIMEHeaderSize is the maximum size of a MIME header we will parse,
+// including header keys, values, and map overhead.
+const maxMIMEHeaderSize = 10 << 20
+
 // NextPart returns the next part in the multipart or an error.
 // When there are no more parts, the error io.EOF is returned.
 //
@@ -328,7 +337,7 @@
 // has a value of "quoted-printable", that header is instead
 // hidden and the body is transparently decoded during Read calls.
 func (r *Reader) NextPart() (*Part, error) {
-	return r.nextPart(false)
+	return r.nextPart(false, maxMIMEHeaderSize)
 }
 
 // NextRawPart returns the next part in the multipart or an error.
@@ -337,10 +346,10 @@
 // Unlike NextPart, it does not have special handling for
 // "Content-Transfer-Encoding: quoted-printable".
 func (r *Reader) NextRawPart() (*Part, error) {
-	return r.nextPart(true)
+	return r.nextPart(true, maxMIMEHeaderSize)
 }
 
-func (r *Reader) nextPart(rawPart bool) (*Part, error) {
+func (r *Reader) nextPart(rawPart bool, maxMIMEHeaderSize int64) (*Part, error) {
 	if r.currentPart != nil {
 		r.currentPart.Close()
 	}
@@ -360,12 +369,12 @@
 			return nil, io.EOF
 		}
 		if err != nil {
-			return nil, fmt.Errorf("multipart: NextPart: %v", err)
+			return nil, fmt.Errorf("multipart: NextPart: %w", err)
 		}
 
 		if r.isBoundaryDelimiterLine(line) {
 			r.partsRead++
-			bp, err := newPart(r, rawPart)
+			bp, err := newPart(r, rawPart, maxMIMEHeaderSize)
 			if err != nil {
 				return nil, err
 			}
diff --git a/src/mime/multipart/multipart_test.go b/src/mime/multipart/multipart_test.go
index e043e36..e0cb768 100644
--- a/src/mime/multipart/multipart_test.go
+++ b/src/mime/multipart/multipart_test.go
@@ -126,7 +126,7 @@
 func testMultipart(t *testing.T, r io.Reader, onlyNewlines bool) {
 	t.Parallel()
 	reader := NewReader(r, "MyBoundary")
-	buf := new(bytes.Buffer)
+	buf := new(strings.Builder)
 
 	// Part1
 	part, err := reader.NextPart()
@@ -416,7 +416,7 @@
 		if err != nil {
 			t.Fatalf("didn't get a part")
 		}
-		var buf bytes.Buffer
+		var buf strings.Builder
 		n, err := io.Copy(&buf, part)
 		if err != nil {
 			t.Errorf("error reading part: %v\nread so far: %q", err, buf.String())
@@ -446,7 +446,7 @@
 	if te, ok := part.Header["Content-Transfer-Encoding"]; ok {
 		t.Errorf("unexpected Content-Transfer-Encoding of %q", te)
 	}
-	var buf bytes.Buffer
+	var buf strings.Builder
 	_, err = io.Copy(&buf, part)
 	if err != nil {
 		t.Error(err)
@@ -484,7 +484,7 @@
 	if _, ok := part.Header["Content-Transfer-Encoding"]; !ok {
 		t.Errorf("missing Content-Transfer-Encoding")
 	}
-	var buf bytes.Buffer
+	var buf strings.Builder
 	_, err = io.Copy(&buf, part)
 	if err != nil {
 		t.Error(err)
@@ -993,7 +993,7 @@
 			formData("foo", "bar"),
 		},
 	}
-	var buf bytes.Buffer
+	var buf strings.Builder
 	w := NewWriter(&buf)
 	for _, p := range t.want {
 		pw, err := w.CreatePart(p.header)
diff --git a/src/mime/multipart/readmimeheader.go b/src/mime/multipart/readmimeheader.go
new file mode 100644
index 0000000..6836928
--- /dev/null
+++ b/src/mime/multipart/readmimeheader.go
@@ -0,0 +1,14 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+package multipart
+
+import (
+	"net/textproto"
+	_ "unsafe" // for go:linkname
+)
+
+// readMIMEHeader is defined in package net/textproto.
+//
+//go:linkname readMIMEHeader net/textproto.readMIMEHeader
+func readMIMEHeader(r *textproto.Reader, lim int64) (textproto.MIMEHeader, error)
diff --git a/src/mime/multipart/writer_test.go b/src/mime/multipart/writer_test.go
index cfc0f09..9e0f131 100644
--- a/src/mime/multipart/writer_test.go
+++ b/src/mime/multipart/writer_test.go
@@ -98,7 +98,7 @@
 		{"(boundary)", true},
 	}
 	for i, tt := range tests {
-		var b bytes.Buffer
+		var b strings.Builder
 		w := NewWriter(&b)
 		err := w.SetBoundary(tt.b)
 		got := err == nil
@@ -145,7 +145,7 @@
 }
 
 func TestSortedHeader(t *testing.T) {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	w := NewWriter(&buf)
 	if err := w.SetBoundary("MIMEBOUNDARY"); err != nil {
 		t.Fatalf("Error setting mime boundary: %v", err)
diff --git a/src/mime/quotedprintable/reader_test.go b/src/mime/quotedprintable/reader_test.go
index 19e9fea..0af1e5f 100644
--- a/src/mime/quotedprintable/reader_test.go
+++ b/src/mime/quotedprintable/reader_test.go
@@ -6,7 +6,6 @@
 
 import (
 	"bufio"
-	"bytes"
 	"errors"
 	"flag"
 	"fmt"
@@ -69,7 +68,7 @@
 			want: "accept UTF-8 right quotation mark: ’"},
 	}
 	for _, tt := range tests {
-		var buf bytes.Buffer
+		var buf strings.Builder
 		_, err := io.Copy(&buf, NewReader(strings.NewReader(tt.in)))
 		if got := buf.String(); got != tt.want {
 			t.Errorf("for %q, got %q; want %q", tt.in, got, tt.want)
@@ -114,7 +113,7 @@
 		}
 	}
 
-	var buf bytes.Buffer
+	var buf strings.Builder
 	res := make(map[string]int)
 	n := 6
 	if testing.Short() {
diff --git a/src/mime/quotedprintable/writer_test.go b/src/mime/quotedprintable/writer_test.go
index 42de0f3..07411fe 100644
--- a/src/mime/quotedprintable/writer_test.go
+++ b/src/mime/quotedprintable/writer_test.go
@@ -91,7 +91,7 @@
 	}
 
 	for _, tt := range tests {
-		buf := new(bytes.Buffer)
+		buf := new(strings.Builder)
 		w := NewWriter(buf)
 
 		want := tt.want
diff --git a/src/mime/type_test.go b/src/mime/type_test.go
index f10e634..d8368e8 100644
--- a/src/mime/type_test.go
+++ b/src/mime/type_test.go
@@ -14,7 +14,10 @@
 func setMimeInit(fn func()) (cleanup func()) {
 	once = sync.Once{}
 	testInitMime = fn
-	return func() { testInitMime = nil }
+	return func() {
+		testInitMime = nil
+		once = sync.Once{}
+	}
 }
 
 func clearMimeTypes() {
diff --git a/src/mime/type_unix_test.go b/src/mime/type_unix_test.go
index 2e8f273..7b8db79 100644
--- a/src/mime/type_unix_test.go
+++ b/src/mime/type_unix_test.go
@@ -11,6 +11,7 @@
 )
 
 func initMimeUnixTest(t *testing.T) {
+	once.Do(initMime)
 	err := loadMimeGlobsFile("testdata/test.types.globs2")
 	if err != nil {
 		t.Fatal(err)
diff --git a/src/net/addrselect.go b/src/net/addrselect.go
index 59380b9..4f07032 100644
--- a/src/net/addrselect.go
+++ b/src/net/addrselect.go
@@ -6,7 +6,10 @@
 
 package net
 
-import "sort"
+import (
+	"net/netip"
+	"sort"
+)
 
 func sortByRFC6724(addrs []IPAddr) {
 	if len(addrs) < 2 {
@@ -15,14 +18,15 @@
 	sortByRFC6724withSrcs(addrs, srcAddrs(addrs))
 }
 
-func sortByRFC6724withSrcs(addrs []IPAddr, srcs []IP) {
+func sortByRFC6724withSrcs(addrs []IPAddr, srcs []netip.Addr) {
 	if len(addrs) != len(srcs) {
 		panic("internal error")
 	}
 	addrAttr := make([]ipAttr, len(addrs))
 	srcAttr := make([]ipAttr, len(srcs))
 	for i, v := range addrs {
-		addrAttr[i] = ipAttrOf(v.IP)
+		addrAttrIP, _ := netip.AddrFromSlice(v.IP)
+		addrAttr[i] = ipAttrOf(addrAttrIP)
 		srcAttr[i] = ipAttrOf(srcs[i])
 	}
 	sort.Stable(&byRFC6724{
@@ -33,11 +37,11 @@
 	})
 }
 
-// srcsAddrs tries to UDP-connect to each address to see if it has a
+// srcAddrs tries to UDP-connect to each address to see if it has a
 // route. (This doesn't send any packets). The destination port
 // number is irrelevant.
-func srcAddrs(addrs []IPAddr) []IP {
-	srcs := make([]IP, len(addrs))
+func srcAddrs(addrs []IPAddr) []netip.Addr {
+	srcs := make([]netip.Addr, len(addrs))
 	dst := UDPAddr{Port: 9}
 	for i := range addrs {
 		dst.IP = addrs[i].IP
@@ -45,7 +49,7 @@
 		c, err := DialUDP("udp", nil, &dst)
 		if err == nil {
 			if src, ok := c.LocalAddr().(*UDPAddr); ok {
-				srcs[i] = src.IP
+				srcs[i], _ = netip.AddrFromSlice(src.IP)
 			}
 			c.Close()
 		}
@@ -59,8 +63,8 @@
 	Label      uint8
 }
 
-func ipAttrOf(ip IP) ipAttr {
-	if ip == nil {
+func ipAttrOf(ip netip.Addr) ipAttr {
+	if !ip.IsValid() {
 		return ipAttr{}
 	}
 	match := rfc6724policyTable.Classify(ip)
@@ -74,7 +78,7 @@
 type byRFC6724 struct {
 	addrs    []IPAddr // addrs to sort
 	addrAttr []ipAttr
-	srcs     []IP // or nil if unreachable
+	srcs     []netip.Addr // or not valid addr if unreachable
 	srcAttr  []ipAttr
 }
 
@@ -108,13 +112,13 @@
 	// If DB is known to be unreachable or if Source(DB) is undefined, then
 	// prefer DA.  Similarly, if DA is known to be unreachable or if
 	// Source(DA) is undefined, then prefer DB.
-	if SourceDA == nil && SourceDB == nil {
+	if !SourceDA.IsValid() && !SourceDB.IsValid() {
 		return false // "equal"
 	}
-	if SourceDB == nil {
+	if !SourceDB.IsValid() {
 		return preferDA
 	}
-	if SourceDA == nil {
+	if !SourceDA.IsValid() {
 		return preferDB
 	}
 
@@ -184,7 +188,7 @@
 		return preferDB
 	}
 
-	// Rule 9: Use longest matching prefix.
+	// Rule 9: Use the longest matching prefix.
 	// When DA and DB belong to the same address family (both are IPv6 or
 	// both are IPv4 [but see below]): If CommonPrefixLen(Source(DA), DA) >
 	// CommonPrefixLen(Source(DB), DB), then prefer DA.  Similarly, if
@@ -212,7 +216,7 @@
 }
 
 type policyTableEntry struct {
-	Prefix     *IPNet
+	Prefix     netip.Prefix
 	Precedence uint8
 	Label      uint8
 }
@@ -220,90 +224,75 @@
 type policyTable []policyTableEntry
 
 // RFC 6724 section 2.1.
+// Items are sorted by the size of their Prefix.Mask.Size,
 var rfc6724policyTable = policyTable{
 	{
-		Prefix:     mustCIDR("::1/128"),
+		// "::1/128"
+		Prefix:     netip.PrefixFrom(netip.AddrFrom16([16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01}), 128),
 		Precedence: 50,
 		Label:      0,
 	},
 	{
-		Prefix:     mustCIDR("::/0"),
-		Precedence: 40,
-		Label:      1,
-	},
-	{
+		// "::ffff:0:0/96"
 		// IPv4-compatible, etc.
-		Prefix:     mustCIDR("::ffff:0:0/96"),
+		Prefix:     netip.PrefixFrom(netip.AddrFrom16([16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff}), 96),
 		Precedence: 35,
 		Label:      4,
 	},
 	{
-		// 6to4
-		Prefix:     mustCIDR("2002::/16"),
-		Precedence: 30,
-		Label:      2,
-	},
-	{
-		// Teredo
-		Prefix:     mustCIDR("2001::/32"),
-		Precedence: 5,
-		Label:      5,
-	},
-	{
-		Prefix:     mustCIDR("fc00::/7"),
-		Precedence: 3,
-		Label:      13,
-	},
-	{
-		Prefix:     mustCIDR("::/96"),
+		// "::/96"
+		Prefix:     netip.PrefixFrom(netip.AddrFrom16([16]byte{}), 96),
 		Precedence: 1,
 		Label:      3,
 	},
 	{
-		Prefix:     mustCIDR("fec0::/10"),
+		// "2001::/32"
+		// Teredo
+		Prefix:     netip.PrefixFrom(netip.AddrFrom16([16]byte{0x20, 0x01}), 32),
+		Precedence: 5,
+		Label:      5,
+	},
+	{
+		// "2002::/16"
+		// 6to4
+		Prefix:     netip.PrefixFrom(netip.AddrFrom16([16]byte{0x20, 0x02}), 16),
+		Precedence: 30,
+		Label:      2,
+	},
+	{
+		// "3ffe::/16"
+		Prefix:     netip.PrefixFrom(netip.AddrFrom16([16]byte{0x3f, 0xfe}), 16),
+		Precedence: 1,
+		Label:      12,
+	},
+	{
+		// "fec0::/10"
+		Prefix:     netip.PrefixFrom(netip.AddrFrom16([16]byte{0xfe, 0xc0}), 10),
 		Precedence: 1,
 		Label:      11,
 	},
 	{
-		Prefix:     mustCIDR("3ffe::/16"),
-		Precedence: 1,
-		Label:      12,
+		// "fc00::/7"
+		Prefix:     netip.PrefixFrom(netip.AddrFrom16([16]byte{0xfc}), 7),
+		Precedence: 3,
+		Label:      13,
 	},
-}
-
-func init() {
-	sort.Sort(sort.Reverse(byMaskLength(rfc6724policyTable)))
-}
-
-// byMaskLength sorts policyTableEntry by the size of their Prefix.Mask.Size,
-// from smallest mask, to largest.
-type byMaskLength []policyTableEntry
-
-func (s byMaskLength) Len() int      { return len(s) }
-func (s byMaskLength) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
-func (s byMaskLength) Less(i, j int) bool {
-	isize, _ := s[i].Prefix.Mask.Size()
-	jsize, _ := s[j].Prefix.Mask.Size()
-	return isize < jsize
-}
-
-// mustCIDR calls ParseCIDR and panics on any error, or if the network
-// is not IPv6.
-func mustCIDR(s string) *IPNet {
-	ip, ipNet, err := ParseCIDR(s)
-	if err != nil {
-		panic(err.Error())
-	}
-	if len(ip) != IPv6len {
-		panic("unexpected IP length")
-	}
-	return ipNet
+	{
+		// "::/0"
+		Prefix:     netip.PrefixFrom(netip.AddrFrom16([16]byte{}), 0),
+		Precedence: 40,
+		Label:      1,
+	},
 }
 
 // Classify returns the policyTableEntry of the entry with the longest
 // matching prefix that contains ip.
 // The table t must be sorted from largest mask size to smallest.
-func (t policyTable) Classify(ip IP) policyTableEntry {
+func (t policyTable) Classify(ip netip.Addr) policyTableEntry {
+	// Prefix.Contains() will not match an IPv6 prefix for an IPv4 address.
+	if ip.Is4() {
+		ip = netip.AddrFrom16(ip.As16())
+	}
 	for _, ent := range t {
 		if ent.Prefix.Contains(ip) {
 			return ent
@@ -324,17 +313,18 @@
 	scopeGlobal         scope = 0xe
 )
 
-func classifyScope(ip IP) scope {
+func classifyScope(ip netip.Addr) scope {
 	if ip.IsLoopback() || ip.IsLinkLocalUnicast() {
 		return scopeLinkLocal
 	}
-	ipv6 := len(ip) == IPv6len && ip.To4() == nil
+	ipv6 := ip.Is6() && !ip.Is4In6()
+	ipv6AsBytes := ip.As16()
 	if ipv6 && ip.IsMulticast() {
-		return scope(ip[1] & 0xf)
+		return scope(ipv6AsBytes[1] & 0xf)
 	}
 	// Site-local addresses are defined in RFC 3513 section 2.5.6
 	// (and deprecated in RFC 3879).
-	if ipv6 && ip[0] == 0xfe && ip[1]&0xc0 == 0xc0 {
+	if ipv6 && ipv6AsBytes[0] == 0xfe && ipv6AsBytes[1]&0xc0 == 0xc0 {
 		return scopeSiteLocal
 	}
 	return scopeGlobal
@@ -350,30 +340,28 @@
 // If a and b are different IP versions, 0 is returned.
 //
 // See https://tools.ietf.org/html/rfc6724#section-2.2
-func commonPrefixLen(a, b IP) (cpl int) {
-	if a4 := a.To4(); a4 != nil {
-		a = a4
-	}
+func commonPrefixLen(a netip.Addr, b IP) (cpl int) {
 	if b4 := b.To4(); b4 != nil {
 		b = b4
 	}
-	if len(a) != len(b) {
+	aAsSlice := a.AsSlice()
+	if len(aAsSlice) != len(b) {
 		return 0
 	}
 	// If IPv6, only up to the prefix (first 64 bits)
-	if len(a) > 8 {
-		a = a[:8]
+	if len(aAsSlice) > 8 {
+		aAsSlice = aAsSlice[:8]
 		b = b[:8]
 	}
-	for len(a) > 0 {
-		if a[0] == b[0] {
+	for len(aAsSlice) > 0 {
+		if aAsSlice[0] == b[0] {
 			cpl += 8
-			a = a[1:]
+			aAsSlice = aAsSlice[1:]
 			b = b[1:]
 			continue
 		}
 		bits := 8
-		ab, bb := a[0], b[0]
+		ab, bb := aAsSlice[0], b[0]
 		for {
 			ab >>= 1
 			bb >>= 1
diff --git a/src/net/addrselect_test.go b/src/net/addrselect_test.go
index 2894d5d..7e8134d 100644
--- a/src/net/addrselect_test.go
+++ b/src/net/addrselect_test.go
@@ -7,6 +7,7 @@
 package net
 
 import (
+	"net/netip"
 	"reflect"
 	"testing"
 )
@@ -14,7 +15,7 @@
 func TestSortByRFC6724(t *testing.T) {
 	tests := []struct {
 		in      []IPAddr
-		srcs    []IP
+		srcs    []netip.Addr
 		want    []IPAddr
 		reverse bool // also test it starting backwards
 	}{
@@ -26,9 +27,9 @@
 				{IP: ParseIP("2001:db8:1::1")},
 				{IP: ParseIP("198.51.100.121")},
 			},
-			srcs: []IP{
-				ParseIP("2001:db8:1::2"),
-				ParseIP("169.254.13.78"),
+			srcs: []netip.Addr{
+				netip.MustParseAddr("2001:db8:1::2"),
+				netip.MustParseAddr("169.254.13.78"),
 			},
 			want: []IPAddr{
 				{IP: ParseIP("2001:db8:1::1")},
@@ -43,9 +44,9 @@
 				{IP: ParseIP("2001:db8:1::1")},
 				{IP: ParseIP("198.51.100.121")},
 			},
-			srcs: []IP{
-				ParseIP("fe80::1"),
-				ParseIP("198.51.100.117"),
+			srcs: []netip.Addr{
+				netip.MustParseAddr("fe80::1"),
+				netip.MustParseAddr("198.51.100.117"),
 			},
 			want: []IPAddr{
 				{IP: ParseIP("198.51.100.121")},
@@ -60,9 +61,9 @@
 				{IP: ParseIP("2001:db8:1::1")},
 				{IP: ParseIP("10.1.2.3")},
 			},
-			srcs: []IP{
-				ParseIP("2001:db8:1::2"),
-				ParseIP("10.1.2.4"),
+			srcs: []netip.Addr{
+				netip.MustParseAddr("2001:db8:1::2"),
+				netip.MustParseAddr("10.1.2.4"),
 			},
 			want: []IPAddr{
 				{IP: ParseIP("2001:db8:1::1")},
@@ -77,9 +78,9 @@
 				{IP: ParseIP("2001:db8:1::1")},
 				{IP: ParseIP("fe80::1")},
 			},
-			srcs: []IP{
-				ParseIP("2001:db8:1::2"),
-				ParseIP("fe80::2"),
+			srcs: []netip.Addr{
+				netip.MustParseAddr("2001:db8:1::2"),
+				netip.MustParseAddr("fe80::2"),
 			},
 			want: []IPAddr{
 				{IP: ParseIP("fe80::1")},
@@ -99,13 +100,13 @@
 				{IP: ParseIP("23.23.134.56")},
 				{IP: ParseIP("23.21.50.150")},
 			},
-			srcs: []IP{
-				ParseIP("10.2.3.4"),
-				ParseIP("10.2.3.4"),
-				ParseIP("10.2.3.4"),
-				ParseIP("10.2.3.4"),
-				ParseIP("10.2.3.4"),
-				ParseIP("10.2.3.4"),
+			srcs: []netip.Addr{
+				netip.MustParseAddr("10.2.3.4"),
+				netip.MustParseAddr("10.2.3.4"),
+				netip.MustParseAddr("10.2.3.4"),
+				netip.MustParseAddr("10.2.3.4"),
+				netip.MustParseAddr("10.2.3.4"),
+				netip.MustParseAddr("10.2.3.4"),
 			},
 			want: []IPAddr{
 				{IP: ParseIP("54.83.193.112")},
@@ -121,7 +122,7 @@
 	for i, tt := range tests {
 		inCopy := make([]IPAddr, len(tt.in))
 		copy(inCopy, tt.in)
-		srcCopy := make([]IP, len(tt.in))
+		srcCopy := make([]netip.Addr, len(tt.in))
 		copy(srcCopy, tt.srcs)
 		sortByRFC6724withSrcs(inCopy, srcCopy)
 		if !reflect.DeepEqual(inCopy, tt.want) {
@@ -145,39 +146,100 @@
 
 }
 
+func TestRFC6724PolicyTableOrder(t *testing.T) {
+	for i := 0; i < len(rfc6724policyTable)-1; i++ {
+		if !(rfc6724policyTable[i].Prefix.Bits() >= rfc6724policyTable[i+1].Prefix.Bits()) {
+			t.Errorf("rfc6724policyTable item number %d sorted in wrong order = %d bits, next item = %d bits;", i, rfc6724policyTable[i].Prefix.Bits(), rfc6724policyTable[i+1].Prefix.Bits())
+		}
+	}
+}
+
+func TestRFC6724PolicyTableContent(t *testing.T) {
+	expectedRfc6724policyTable := policyTable{
+		{
+			Prefix:     netip.MustParsePrefix("::1/128"),
+			Precedence: 50,
+			Label:      0,
+		},
+		{
+			Prefix:     netip.MustParsePrefix("::ffff:0:0/96"),
+			Precedence: 35,
+			Label:      4,
+		},
+		{
+			Prefix:     netip.MustParsePrefix("::/96"),
+			Precedence: 1,
+			Label:      3,
+		},
+		{
+			Prefix:     netip.MustParsePrefix("2001::/32"),
+			Precedence: 5,
+			Label:      5,
+		},
+		{
+			Prefix:     netip.MustParsePrefix("2002::/16"),
+			Precedence: 30,
+			Label:      2,
+		},
+		{
+			Prefix:     netip.MustParsePrefix("3ffe::/16"),
+			Precedence: 1,
+			Label:      12,
+		},
+		{
+			Prefix:     netip.MustParsePrefix("fec0::/10"),
+			Precedence: 1,
+			Label:      11,
+		},
+		{
+			Prefix:     netip.MustParsePrefix("fc00::/7"),
+			Precedence: 3,
+			Label:      13,
+		},
+		{
+			Prefix:     netip.MustParsePrefix("::/0"),
+			Precedence: 40,
+			Label:      1,
+		},
+	}
+	if !reflect.DeepEqual(rfc6724policyTable, expectedRfc6724policyTable) {
+		t.Errorf("rfc6724policyTable has wrong contend = %v; want %v", rfc6724policyTable, expectedRfc6724policyTable)
+	}
+}
+
 func TestRFC6724PolicyTableClassify(t *testing.T) {
 	tests := []struct {
-		ip   IP
+		ip   netip.Addr
 		want policyTableEntry
 	}{
 		{
-			ip: ParseIP("127.0.0.1"),
+			ip: netip.MustParseAddr("127.0.0.1"),
 			want: policyTableEntry{
-				Prefix:     &IPNet{IP: ParseIP("::ffff:0:0"), Mask: CIDRMask(96, 128)},
+				Prefix:     netip.MustParsePrefix("::ffff:0:0/96"),
 				Precedence: 35,
 				Label:      4,
 			},
 		},
 		{
-			ip: ParseIP("2601:645:8002:a500:986f:1db8:c836:bd65"),
+			ip: netip.MustParseAddr("2601:645:8002:a500:986f:1db8:c836:bd65"),
 			want: policyTableEntry{
-				Prefix:     &IPNet{IP: ParseIP("::"), Mask: CIDRMask(0, 128)},
+				Prefix:     netip.MustParsePrefix("::/0"),
 				Precedence: 40,
 				Label:      1,
 			},
 		},
 		{
-			ip: ParseIP("::1"),
+			ip: netip.MustParseAddr("::1"),
 			want: policyTableEntry{
-				Prefix:     &IPNet{IP: ParseIP("::1"), Mask: CIDRMask(128, 128)},
+				Prefix:     netip.MustParsePrefix("::1/128"),
 				Precedence: 50,
 				Label:      0,
 			},
 		},
 		{
-			ip: ParseIP("2002::ab12"),
+			ip: netip.MustParseAddr("2002::ab12"),
 			want: policyTableEntry{
-				Prefix:     &IPNet{IP: ParseIP("2002::"), Mask: CIDRMask(16, 128)},
+				Prefix:     netip.MustParsePrefix("2002::/16"),
 				Precedence: 30,
 				Label:      2,
 			},
@@ -193,24 +255,24 @@
 
 func TestRFC6724ClassifyScope(t *testing.T) {
 	tests := []struct {
-		ip   IP
+		ip   netip.Addr
 		want scope
 	}{
-		{ParseIP("127.0.0.1"), scopeLinkLocal},   // rfc6724#section-3.2
-		{ParseIP("::1"), scopeLinkLocal},         // rfc4007#section-4
-		{ParseIP("169.254.1.2"), scopeLinkLocal}, // rfc6724#section-3.2
-		{ParseIP("fec0::1"), scopeSiteLocal},
-		{ParseIP("8.8.8.8"), scopeGlobal},
+		{netip.MustParseAddr("127.0.0.1"), scopeLinkLocal},   // rfc6724#section-3.2
+		{netip.MustParseAddr("::1"), scopeLinkLocal},         // rfc4007#section-4
+		{netip.MustParseAddr("169.254.1.2"), scopeLinkLocal}, // rfc6724#section-3.2
+		{netip.MustParseAddr("fec0::1"), scopeSiteLocal},
+		{netip.MustParseAddr("8.8.8.8"), scopeGlobal},
 
-		{ParseIP("ff02::"), scopeLinkLocal},  // IPv6 multicast
-		{ParseIP("ff05::"), scopeSiteLocal},  // IPv6 multicast
-		{ParseIP("ff04::"), scopeAdminLocal}, // IPv6 multicast
-		{ParseIP("ff0e::"), scopeGlobal},     // IPv6 multicast
+		{netip.MustParseAddr("ff02::"), scopeLinkLocal},  // IPv6 multicast
+		{netip.MustParseAddr("ff05::"), scopeSiteLocal},  // IPv6 multicast
+		{netip.MustParseAddr("ff04::"), scopeAdminLocal}, // IPv6 multicast
+		{netip.MustParseAddr("ff0e::"), scopeGlobal},     // IPv6 multicast
 
-		{IPv4(0xe0, 0, 0, 0), scopeGlobal},       // IPv4 link-local multicast as 16 bytes
-		{IPv4(0xe0, 2, 2, 2), scopeGlobal},       // IPv4 global multicast as 16 bytes
-		{IPv4(0xe0, 0, 0, 0).To4(), scopeGlobal}, // IPv4 link-local multicast as 4 bytes
-		{IPv4(0xe0, 2, 2, 2).To4(), scopeGlobal}, // IPv4 global multicast as 4 bytes
+		{netip.AddrFrom16([16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xe0, 0, 0, 0}), scopeGlobal}, // IPv4 link-local multicast as 16 bytes
+		{netip.AddrFrom16([16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xe0, 2, 2, 2}), scopeGlobal}, // IPv4 global multicast as 16 bytes
+		{netip.AddrFrom4([4]byte{0xe0, 0, 0, 0}), scopeGlobal},                                       // IPv4 link-local multicast as 4 bytes
+		{netip.AddrFrom4([4]byte{0xe0, 2, 2, 2}), scopeGlobal},                                       // IPv4 global multicast as 4 bytes
 	}
 	for i, tt := range tests {
 		got := classifyScope(tt.ip)
@@ -222,22 +284,23 @@
 
 func TestRFC6724CommonPrefixLength(t *testing.T) {
 	tests := []struct {
-		a, b IP
+		a    netip.Addr
+		b    IP
 		want int
 	}{
-		{ParseIP("fe80::1"), ParseIP("fe80::2"), 64},
-		{ParseIP("fe81::1"), ParseIP("fe80::2"), 15},
-		{ParseIP("127.0.0.1"), ParseIP("fe80::1"), 0}, // diff size
-		{IPv4(1, 2, 3, 4), IP{1, 2, 3, 4}, 32},
-		{IP{1, 2, 255, 255}, IP{1, 2, 0, 0}, 16},
-		{IP{1, 2, 127, 255}, IP{1, 2, 0, 0}, 17},
-		{IP{1, 2, 63, 255}, IP{1, 2, 0, 0}, 18},
-		{IP{1, 2, 31, 255}, IP{1, 2, 0, 0}, 19},
-		{IP{1, 2, 15, 255}, IP{1, 2, 0, 0}, 20},
-		{IP{1, 2, 7, 255}, IP{1, 2, 0, 0}, 21},
-		{IP{1, 2, 3, 255}, IP{1, 2, 0, 0}, 22},
-		{IP{1, 2, 1, 255}, IP{1, 2, 0, 0}, 23},
-		{IP{1, 2, 0, 255}, IP{1, 2, 0, 0}, 24},
+		{netip.MustParseAddr("fe80::1"), ParseIP("fe80::2"), 64},
+		{netip.MustParseAddr("fe81::1"), ParseIP("fe80::2"), 15},
+		{netip.MustParseAddr("127.0.0.1"), ParseIP("fe80::1"), 0}, // diff size
+		{netip.AddrFrom4([4]byte{1, 2, 3, 4}), IP{1, 2, 3, 4}, 32},
+		{netip.AddrFrom4([4]byte{1, 2, 255, 255}), IP{1, 2, 0, 0}, 16},
+		{netip.AddrFrom4([4]byte{1, 2, 127, 255}), IP{1, 2, 0, 0}, 17},
+		{netip.AddrFrom4([4]byte{1, 2, 63, 255}), IP{1, 2, 0, 0}, 18},
+		{netip.AddrFrom4([4]byte{1, 2, 31, 255}), IP{1, 2, 0, 0}, 19},
+		{netip.AddrFrom4([4]byte{1, 2, 15, 255}), IP{1, 2, 0, 0}, 20},
+		{netip.AddrFrom4([4]byte{1, 2, 7, 255}), IP{1, 2, 0, 0}, 21},
+		{netip.AddrFrom4([4]byte{1, 2, 3, 255}), IP{1, 2, 0, 0}, 22},
+		{netip.AddrFrom4([4]byte{1, 2, 1, 255}), IP{1, 2, 0, 0}, 23},
+		{netip.AddrFrom4([4]byte{1, 2, 0, 255}), IP{1, 2, 0, 0}, 24},
 	}
 	for i, tt := range tests {
 		got := commonPrefixLen(tt.a, tt.b)
diff --git a/src/net/cgo_bsd.go b/src/net/cgo_bsd.go
index 1456289..082e91f 100644
--- a/src/net/cgo_bsd.go
+++ b/src/net/cgo_bsd.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build cgo && !netgo && (darwin || dragonfly || freebsd)
+//go:build cgo && !netgo && (dragonfly || freebsd)
 
 package net
 
diff --git a/src/net/cgo_darwin.go b/src/net/cgo_darwin.go
new file mode 100644
index 0000000..129dd93
--- /dev/null
+++ b/src/net/cgo_darwin.go
@@ -0,0 +1,9 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package net
+
+import "internal/syscall/unix"
+
+const cgoAddrInfoFlags = (unix.AI_CANONNAME | unix.AI_V4MAPPED | unix.AI_ALL) & unix.AI_MASK
diff --git a/src/net/cgo_resnew.go b/src/net/cgo_resnew.go
index fa6e687..3f21c5c 100644
--- a/src/net/cgo_resnew.go
+++ b/src/net/cgo_resnew.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build cgo && !netgo && (darwin || (linux && !android) || netbsd || solaris)
+//go:build cgo && !netgo && ((linux && !android) || netbsd || solaris)
 
 package net
 
diff --git a/src/net/cgo_sockold.go b/src/net/cgo_sockold.go
index 4d9869d..d0a99e0 100644
--- a/src/net/cgo_sockold.go
+++ b/src/net/cgo_sockold.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build cgo && !netgo && (aix || darwin || dragonfly || freebsd || netbsd || openbsd)
+//go:build cgo && !netgo && (aix || dragonfly || freebsd || netbsd || openbsd)
 
 package net
 
diff --git a/src/net/cgo_stub.go b/src/net/cgo_stub.go
index 298d829..c901d4b 100644
--- a/src/net/cgo_stub.go
+++ b/src/net/cgo_stub.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build !cgo || netgo
+//go:build (!cgo && !darwin) || netgo
 
 package net
 
diff --git a/src/net/cgo_unix.go b/src/net/cgo_unix.go
index 71d9056..6a2c369 100644
--- a/src/net/cgo_unix.go
+++ b/src/net/cgo_unix.go
@@ -2,29 +2,22 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build cgo && !netgo && unix
+// This file is called cgo_unix.go, but to allow syscalls-to-libc-based
+// implementations to share the code, it does not use cgo directly.
+// Instead of C.foo it uses _C_foo, which is defined in either
+// cgo_unix_cgo.go or cgo_unix_syscall.go
+
+//go:build !netgo && ((cgo && unix) || darwin)
 
 package net
 
-/*
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <unistd.h>
-#include <string.h>
-
-// If nothing else defined EAI_OVERFLOW, make sure it has a value.
-#ifndef EAI_OVERFLOW
-#define EAI_OVERFLOW -12
-#endif
-*/
-import "C"
-
 import (
 	"context"
+	"errors"
 	"syscall"
 	"unsafe"
+
+	"golang.org/x/net/dns/dnsmessage"
 )
 
 // An addrinfoErrno represents a getaddrinfo, getnameinfo-specific
@@ -32,8 +25,8 @@
 // by convention.
 type addrinfoErrno int
 
-func (eai addrinfoErrno) Error() string   { return C.GoString(C.gai_strerror(C.int(eai))) }
-func (eai addrinfoErrno) Temporary() bool { return eai == C.EAI_AGAIN }
+func (eai addrinfoErrno) Error() string   { return _C_gai_strerror(_C_int(eai)) }
+func (eai addrinfoErrno) Temporary() bool { return eai == _C_EAI_AGAIN }
 func (eai addrinfoErrno) Timeout() bool   { return false }
 
 type portLookupResult struct {
@@ -61,23 +54,23 @@
 }
 
 func cgoLookupPort(ctx context.Context, network, service string) (port int, err error, completed bool) {
-	var hints C.struct_addrinfo
+	var hints _C_struct_addrinfo
 	switch network {
 	case "": // no hints
 	case "tcp", "tcp4", "tcp6":
-		hints.ai_socktype = C.SOCK_STREAM
-		hints.ai_protocol = C.IPPROTO_TCP
+		*_C_ai_socktype(&hints) = _C_SOCK_STREAM
+		*_C_ai_protocol(&hints) = _C_IPPROTO_TCP
 	case "udp", "udp4", "udp6":
-		hints.ai_socktype = C.SOCK_DGRAM
-		hints.ai_protocol = C.IPPROTO_UDP
+		*_C_ai_socktype(&hints) = _C_SOCK_DGRAM
+		*_C_ai_protocol(&hints) = _C_IPPROTO_UDP
 	default:
 		return 0, &DNSError{Err: "unknown network", Name: network + "/" + service}, true
 	}
 	switch ipVersion(network) {
 	case '4':
-		hints.ai_family = C.AF_INET
+		*_C_ai_family(&hints) = _C_AF_INET
 	case '6':
-		hints.ai_family = C.AF_INET6
+		*_C_ai_family(&hints) = _C_AF_INET6
 	}
 	if ctx.Done() == nil {
 		port, err := cgoLookupServicePort(&hints, network, service)
@@ -95,19 +88,19 @@
 	}
 }
 
-func cgoLookupServicePort(hints *C.struct_addrinfo, network, service string) (port int, err error) {
+func cgoLookupServicePort(hints *_C_struct_addrinfo, network, service string) (port int, err error) {
 	cservice := make([]byte, len(service)+1)
 	copy(cservice, service)
 	// Lowercase the C service name.
 	for i, b := range cservice[:len(service)] {
 		cservice[i] = lowerASCII(b)
 	}
-	var res *C.struct_addrinfo
-	gerrno, err := C.getaddrinfo(nil, (*C.char)(unsafe.Pointer(&cservice[0])), hints, &res)
+	var res *_C_struct_addrinfo
+	gerrno, err := _C_getaddrinfo(nil, (*_C_char)(unsafe.Pointer(&cservice[0])), hints, &res)
 	if gerrno != 0 {
 		isTemporary := false
 		switch gerrno {
-		case C.EAI_SYSTEM:
+		case _C_EAI_SYSTEM:
 			if err == nil { // see golang.org/issue/6232
 				err = syscall.EMFILE
 			}
@@ -117,16 +110,16 @@
 		}
 		return 0, &DNSError{Err: err.Error(), Name: network + "/" + service, IsTemporary: isTemporary}
 	}
-	defer C.freeaddrinfo(res)
+	defer _C_freeaddrinfo(res)
 
-	for r := res; r != nil; r = r.ai_next {
-		switch r.ai_family {
-		case C.AF_INET:
-			sa := (*syscall.RawSockaddrInet4)(unsafe.Pointer(r.ai_addr))
+	for r := res; r != nil; r = *_C_ai_next(r) {
+		switch *_C_ai_family(r) {
+		case _C_AF_INET:
+			sa := (*syscall.RawSockaddrInet4)(unsafe.Pointer(*_C_ai_addr(r)))
 			p := (*[2]byte)(unsafe.Pointer(&sa.Port))
 			return int(p[0])<<8 | int(p[1]), nil
-		case C.AF_INET6:
-			sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(r.ai_addr))
+		case _C_AF_INET6:
+			sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(*_C_ai_addr(r)))
 			p := (*[2]byte)(unsafe.Pointer(&sa.Port))
 			return int(p[0])<<8 | int(p[1]), nil
 		}
@@ -134,7 +127,7 @@
 	return 0, &DNSError{Err: "unknown port", Name: network + "/" + service}
 }
 
-func cgoPortLookup(result chan<- portLookupResult, hints *C.struct_addrinfo, network, service string) {
+func cgoPortLookup(result chan<- portLookupResult, hints *_C_struct_addrinfo, network, service string) {
 	port, err := cgoLookupServicePort(hints, network, service)
 	result <- portLookupResult{port, err}
 }
@@ -143,29 +136,29 @@
 	acquireThread()
 	defer releaseThread()
 
-	var hints C.struct_addrinfo
-	hints.ai_flags = cgoAddrInfoFlags
-	hints.ai_socktype = C.SOCK_STREAM
-	hints.ai_family = C.AF_UNSPEC
+	var hints _C_struct_addrinfo
+	*_C_ai_flags(&hints) = cgoAddrInfoFlags
+	*_C_ai_socktype(&hints) = _C_SOCK_STREAM
+	*_C_ai_family(&hints) = _C_AF_UNSPEC
 	switch ipVersion(network) {
 	case '4':
-		hints.ai_family = C.AF_INET
+		*_C_ai_family(&hints) = _C_AF_INET
 	case '6':
-		hints.ai_family = C.AF_INET6
+		*_C_ai_family(&hints) = _C_AF_INET6
 	}
 
 	h := make([]byte, len(name)+1)
 	copy(h, name)
-	var res *C.struct_addrinfo
-	gerrno, err := C.getaddrinfo((*C.char)(unsafe.Pointer(&h[0])), nil, &hints, &res)
+	var res *_C_struct_addrinfo
+	gerrno, err := _C_getaddrinfo((*_C_char)(unsafe.Pointer(&h[0])), nil, &hints, &res)
 	if gerrno != 0 {
 		isErrorNoSuchHost := false
 		isTemporary := false
 		switch gerrno {
-		case C.EAI_SYSTEM:
+		case _C_EAI_SYSTEM:
 			if err == nil {
 				// err should not be nil, but sometimes getaddrinfo returns
-				// gerrno == C.EAI_SYSTEM with err == nil on Linux.
+				// gerrno == _C_EAI_SYSTEM with err == nil on Linux.
 				// The report claims that it happens when we have too many
 				// open files, so use syscall.EMFILE (too many open files in system).
 				// Most system calls would return ENFILE (too many open files),
@@ -173,7 +166,7 @@
 				// comes up again. golang.org/issue/6232.
 				err = syscall.EMFILE
 			}
-		case C.EAI_NONAME:
+		case _C_EAI_NONAME:
 			err = errNoSuchHost
 			isErrorNoSuchHost = true
 		default:
@@ -183,10 +176,10 @@
 
 		return nil, "", &DNSError{Err: err.Error(), Name: name, IsNotFound: isErrorNoSuchHost, IsTemporary: isTemporary}
 	}
-	defer C.freeaddrinfo(res)
+	defer _C_freeaddrinfo(res)
 
 	if res != nil {
-		cname = C.GoString(res.ai_canonname)
+		cname = _C_GoString(*_C_ai_canonname(res))
 		if cname == "" {
 			cname = name
 		}
@@ -194,18 +187,18 @@
 			cname += "."
 		}
 	}
-	for r := res; r != nil; r = r.ai_next {
+	for r := res; r != nil; r = *_C_ai_next(r) {
 		// We only asked for SOCK_STREAM, but check anyhow.
-		if r.ai_socktype != C.SOCK_STREAM {
+		if *_C_ai_socktype(r) != _C_SOCK_STREAM {
 			continue
 		}
-		switch r.ai_family {
-		case C.AF_INET:
-			sa := (*syscall.RawSockaddrInet4)(unsafe.Pointer(r.ai_addr))
+		switch *_C_ai_family(r) {
+		case _C_AF_INET:
+			sa := (*syscall.RawSockaddrInet4)(unsafe.Pointer(*_C_ai_addr(r)))
 			addr := IPAddr{IP: copyIP(sa.Addr[:])}
 			addrs = append(addrs, addr)
-		case C.AF_INET6:
-			sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(r.ai_addr))
+		case _C_AF_INET6:
+			sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(*_C_ai_addr(r)))
 			addr := IPAddr{IP: copyIP(sa.Addr[:]), Zone: zoneCache.name(int(sa.Scope_id))}
 			addrs = append(addrs, addr)
 		}
@@ -233,21 +226,6 @@
 	}
 }
 
-func cgoLookupCNAME(ctx context.Context, name string) (cname string, err error, completed bool) {
-	if ctx.Done() == nil {
-		_, cname, err = cgoLookupIPCNAME("ip", name)
-		return cname, err, true
-	}
-	result := make(chan ipLookupResult, 1)
-	go cgoIPLookup(result, "ip", name)
-	select {
-	case r := <-result:
-		return r.cname, r.err, true
-	case <-ctx.Done():
-		return "", mapErr(ctx.Err()), false
-	}
-}
-
 // These are roughly enough for the following:
 //
 //	 Source		Encoding			Maximum length of single name entry
@@ -288,7 +266,7 @@
 	}
 }
 
-func cgoLookupAddrPTR(addr string, sa *C.struct_sockaddr, salen C.socklen_t) (names []string, err error) {
+func cgoLookupAddrPTR(addr string, sa *_C_struct_sockaddr, salen _C_socklen_t) (names []string, err error) {
 	acquireThread()
 	defer releaseThread()
 
@@ -297,14 +275,14 @@
 	for l := nameinfoLen; l <= maxNameinfoLen; l *= 2 {
 		b = make([]byte, l)
 		gerrno, err = cgoNameinfoPTR(b, sa, salen)
-		if gerrno == 0 || gerrno != C.EAI_OVERFLOW {
+		if gerrno == 0 || gerrno != _C_EAI_OVERFLOW {
 			break
 		}
 	}
 	if gerrno != 0 {
 		isTemporary := false
 		switch gerrno {
-		case C.EAI_SYSTEM:
+		case _C_EAI_SYSTEM:
 			if err == nil { // see golang.org/issue/6232
 				err = syscall.EMFILE
 			}
@@ -323,26 +301,112 @@
 	return []string{absDomainName(string(b))}, nil
 }
 
-func cgoReverseLookup(result chan<- reverseLookupResult, addr string, sa *C.struct_sockaddr, salen C.socklen_t) {
+func cgoReverseLookup(result chan<- reverseLookupResult, addr string, sa *_C_struct_sockaddr, salen _C_socklen_t) {
 	names, err := cgoLookupAddrPTR(addr, sa, salen)
 	result <- reverseLookupResult{names, err}
 }
 
-func cgoSockaddr(ip IP, zone string) (*C.struct_sockaddr, C.socklen_t) {
+func cgoSockaddr(ip IP, zone string) (*_C_struct_sockaddr, _C_socklen_t) {
 	if ip4 := ip.To4(); ip4 != nil {
-		return cgoSockaddrInet4(ip4), C.socklen_t(syscall.SizeofSockaddrInet4)
+		return cgoSockaddrInet4(ip4), _C_socklen_t(syscall.SizeofSockaddrInet4)
 	}
 	if ip6 := ip.To16(); ip6 != nil {
-		return cgoSockaddrInet6(ip6, zoneCache.index(zone)), C.socklen_t(syscall.SizeofSockaddrInet6)
+		return cgoSockaddrInet6(ip6, zoneCache.index(zone)), _C_socklen_t(syscall.SizeofSockaddrInet6)
 	}
 	return nil, 0
 }
 
-func copyIP(x IP) IP {
-	if len(x) < 16 {
-		return x.To16()
+func cgoLookupCNAME(ctx context.Context, name string) (cname string, err error, completed bool) {
+	resources, err := resSearch(ctx, name, int(dnsmessage.TypeCNAME), int(dnsmessage.ClassINET))
+	if err != nil {
+		return
 	}
-	y := make(IP, len(x))
-	copy(y, x)
-	return y
+	cname, err = parseCNAMEFromResources(resources)
+	if err != nil {
+		return "", err, false
+	}
+	return cname, nil, true
+}
+
+// resSearch will make a call to the 'res_nsearch' routine in the C library
+// and parse the output as a slice of DNS resources.
+func resSearch(ctx context.Context, hostname string, rtype, class int) ([]dnsmessage.Resource, error) {
+	if ctx.Done() == nil {
+		return cgoResSearch(hostname, rtype, class)
+	}
+
+	type result struct {
+		res []dnsmessage.Resource
+		err error
+	}
+
+	res := make(chan result, 1)
+	go func() {
+		r, err := cgoResSearch(hostname, rtype, class)
+		res <- result{
+			res: r,
+			err: err,
+		}
+	}()
+
+	select {
+	case res := <-res:
+		return res.res, res.err
+	case <-ctx.Done():
+		return nil, mapErr(ctx.Err())
+	}
+}
+
+func cgoResSearch(hostname string, rtype, class int) ([]dnsmessage.Resource, error) {
+	acquireThread()
+	defer releaseThread()
+
+	state := (*_C_struct___res_state)(_C_malloc(unsafe.Sizeof(_C_struct___res_state{})))
+	defer _C_free(unsafe.Pointer(state))
+	if err := _C_res_ninit(state); err != nil {
+		return nil, errors.New("res_ninit failure: " + err.Error())
+	}
+	defer _C_res_nclose(state)
+
+	// Some res_nsearch implementations (like macOS) do not set errno.
+	// They set h_errno, which is not per-thread and useless to us.
+	// res_nsearch returns the size of the DNS response packet.
+	// But if the DNS response packet contains failure-like response codes,
+	// res_search returns -1 even though it has copied the packet into buf,
+	// giving us no way to find out how big the packet is.
+	// For now, we are willing to take res_search's word that there's nothing
+	// useful in the response, even though there *is* a response.
+	bufSize := maxDNSPacketSize
+	buf := (*_C_uchar)(_C_malloc(uintptr(bufSize)))
+	defer _C_free(unsafe.Pointer(buf))
+
+	s := _C_CString(hostname)
+	defer _C_FreeCString(s)
+
+	var size int
+	for {
+		size, _ = _C_res_nsearch(state, s, class, rtype, buf, bufSize)
+		if size <= 0 || size > 0xffff {
+			return nil, errors.New("res_nsearch failure")
+		}
+		if size <= bufSize {
+			break
+		}
+
+		// Allocate a bigger buffer to fit the entire msg.
+		_C_free(unsafe.Pointer(buf))
+		bufSize = size
+		buf = (*_C_uchar)(_C_malloc(uintptr(bufSize)))
+	}
+
+	var p dnsmessage.Parser
+	if _, err := p.Start(unsafe.Slice((*byte)(unsafe.Pointer(buf)), size)); err != nil {
+		return nil, err
+	}
+	p.SkipAllQuestions()
+	resources, err := p.AllAnswers()
+	if err != nil {
+		return nil, err
+	}
+	return resources, nil
 }
diff --git a/src/net/cgo_unix_cgo.go b/src/net/cgo_unix_cgo.go
new file mode 100644
index 0000000..97427e6
--- /dev/null
+++ b/src/net/cgo_unix_cgo.go
@@ -0,0 +1,76 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build cgo && !netgo && unix && !darwin
+
+package net
+
+/*
+#cgo CFLAGS: -fno-stack-protector
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+
+// If nothing else defined EAI_OVERFLOW, make sure it has a value.
+#ifndef EAI_OVERFLOW
+#define EAI_OVERFLOW -12
+#endif
+*/
+import "C"
+import "unsafe"
+
+const (
+	_C_AF_INET      = C.AF_INET
+	_C_AF_INET6     = C.AF_INET6
+	_C_AF_UNSPEC    = C.AF_UNSPEC
+	_C_EAI_AGAIN    = C.EAI_AGAIN
+	_C_EAI_NONAME   = C.EAI_NONAME
+	_C_EAI_OVERFLOW = C.EAI_OVERFLOW
+	_C_EAI_SYSTEM   = C.EAI_SYSTEM
+	_C_IPPROTO_TCP  = C.IPPROTO_TCP
+	_C_IPPROTO_UDP  = C.IPPROTO_UDP
+	_C_SOCK_DGRAM   = C.SOCK_DGRAM
+	_C_SOCK_STREAM  = C.SOCK_STREAM
+)
+
+type (
+	_C_char            = C.char
+	_C_uchar           = C.uchar
+	_C_int             = C.int
+	_C_uint            = C.uint
+	_C_socklen_t       = C.socklen_t
+	_C_struct_addrinfo = C.struct_addrinfo
+	_C_struct_sockaddr = C.struct_sockaddr
+)
+
+func _C_GoString(p *_C_char) string      { return C.GoString(p) }
+func _C_CString(s string) *_C_char       { return C.CString(s) }
+func _C_FreeCString(p *_C_char)          { C.free(unsafe.Pointer(p)) }
+func _C_malloc(n uintptr) unsafe.Pointer { return C.malloc(C.size_t(n)) }
+func _C_free(p unsafe.Pointer)           { C.free(p) }
+
+func _C_ai_addr(ai *_C_struct_addrinfo) **_C_struct_sockaddr { return &ai.ai_addr }
+func _C_ai_canonname(ai *_C_struct_addrinfo) **_C_char       { return &ai.ai_canonname }
+func _C_ai_family(ai *_C_struct_addrinfo) *_C_int            { return &ai.ai_family }
+func _C_ai_flags(ai *_C_struct_addrinfo) *_C_int             { return &ai.ai_flags }
+func _C_ai_next(ai *_C_struct_addrinfo) **_C_struct_addrinfo { return &ai.ai_next }
+func _C_ai_protocol(ai *_C_struct_addrinfo) *_C_int          { return &ai.ai_protocol }
+func _C_ai_socktype(ai *_C_struct_addrinfo) *_C_int          { return &ai.ai_socktype }
+
+func _C_freeaddrinfo(ai *_C_struct_addrinfo) {
+	C.freeaddrinfo(ai)
+}
+
+func _C_gai_strerror(eai _C_int) string {
+	return C.GoString(C.gai_strerror(eai))
+}
+
+func _C_getaddrinfo(hostname, servname *_C_char, hints *_C_struct_addrinfo, res **_C_struct_addrinfo) (int, error) {
+	x, err := C.getaddrinfo(hostname, servname, hints, res)
+	return int(x), err
+}
diff --git a/src/net/cgo_unix_cgo_res.go b/src/net/cgo_unix_cgo_res.go
new file mode 100644
index 0000000..37bbc9a
--- /dev/null
+++ b/src/net/cgo_unix_cgo_res.go
@@ -0,0 +1,38 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// res_search, for cgo systems where that is thread-safe.
+
+//go:build cgo && !netgo && (linux || openbsd)
+
+package net
+
+/*
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <string.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+
+#cgo !android,!openbsd LDFLAGS: -lresolv
+*/
+import "C"
+
+type _C_struct___res_state = struct{}
+
+func _C_res_ninit(state *_C_struct___res_state) error {
+	return nil
+}
+
+func _C_res_nclose(state *_C_struct___res_state) {
+	return
+}
+
+func _C_res_nsearch(state *_C_struct___res_state, dname *_C_char, class, typ int, ans *_C_uchar, anslen int) (int, error) {
+	x, err := C.res_search(dname, C.int(class), C.int(typ), ans, C.int(anslen))
+	return int(x), err
+}
diff --git a/src/net/cgo_unix_cgo_resn.go b/src/net/cgo_unix_cgo_resn.go
new file mode 100644
index 0000000..4a5ff16
--- /dev/null
+++ b/src/net/cgo_unix_cgo_resn.go
@@ -0,0 +1,39 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// res_nsearch, for cgo systems where that's available.
+
+//go:build cgo && !netgo && unix && !(darwin || linux || openbsd)
+
+package net
+
+/*
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <string.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+
+#cgo !aix,!dragonfly,!freebsd LDFLAGS: -lresolv
+*/
+import "C"
+
+type _C_struct___res_state = C.struct___res_state
+
+func _C_res_ninit(state *_C_struct___res_state) error {
+	_, err := C.res_ninit(state)
+	return err
+}
+
+func _C_res_nclose(state *_C_struct___res_state) {
+	C.res_nclose(state)
+}
+
+func _C_res_nsearch(state *_C_struct___res_state, dname *_C_char, class, typ int, ans *_C_uchar, anslen int) (int, error) {
+	x, err := C.res_nsearch(state, dname, C.int(class), C.int(typ), ans, C.int(anslen))
+	return int(x), err
+}
diff --git a/src/net/cgo_unix_syscall.go b/src/net/cgo_unix_syscall.go
new file mode 100644
index 0000000..0d20a52
--- /dev/null
+++ b/src/net/cgo_unix_syscall.go
@@ -0,0 +1,109 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !netgo && darwin
+
+package net
+
+import (
+	"internal/syscall/unix"
+	"runtime"
+	"syscall"
+	"unsafe"
+)
+
+const (
+	_C_AF_INET      = syscall.AF_INET
+	_C_AF_INET6     = syscall.AF_INET6
+	_C_AF_UNSPEC    = syscall.AF_UNSPEC
+	_C_EAI_AGAIN    = unix.EAI_AGAIN
+	_C_EAI_NONAME   = unix.EAI_NONAME
+	_C_EAI_OVERFLOW = unix.EAI_OVERFLOW
+	_C_EAI_SYSTEM   = unix.EAI_SYSTEM
+	_C_IPPROTO_TCP  = syscall.IPPROTO_TCP
+	_C_IPPROTO_UDP  = syscall.IPPROTO_UDP
+	_C_SOCK_DGRAM   = syscall.SOCK_DGRAM
+	_C_SOCK_STREAM  = syscall.SOCK_STREAM
+)
+
+type (
+	_C_char               = byte
+	_C_int                = int32
+	_C_uchar              = byte
+	_C_uint               = uint32
+	_C_socklen_t          = int
+	_C_struct___res_state = unix.ResState
+	_C_struct_addrinfo    = unix.Addrinfo
+	_C_struct_sockaddr    = syscall.RawSockaddr
+)
+
+func _C_GoString(p *_C_char) string {
+	return unix.GoString(p)
+}
+
+func _C_CString(s string) *_C_char {
+	p := make([]byte, len(s)+1)
+	copy(p, s)
+	return &p[0]
+}
+
+func _C_FreeCString(p *_C_char) { _C_free(unsafe.Pointer(p)) }
+func _C_free(p unsafe.Pointer)  { runtime.KeepAlive(p) }
+
+func _C_malloc(n uintptr) unsafe.Pointer {
+	if n <= 0 {
+		n = 1
+	}
+	return unsafe.Pointer(&make([]byte, n)[0])
+}
+
+func _C_ai_addr(ai *_C_struct_addrinfo) **_C_struct_sockaddr { return &ai.Addr }
+func _C_ai_canonname(ai *_C_struct_addrinfo) **_C_char       { return &ai.Canonname }
+func _C_ai_family(ai *_C_struct_addrinfo) *_C_int            { return &ai.Family }
+func _C_ai_flags(ai *_C_struct_addrinfo) *_C_int             { return &ai.Flags }
+func _C_ai_next(ai *_C_struct_addrinfo) **_C_struct_addrinfo { return &ai.Next }
+func _C_ai_protocol(ai *_C_struct_addrinfo) *_C_int          { return &ai.Protocol }
+func _C_ai_socktype(ai *_C_struct_addrinfo) *_C_int          { return &ai.Socktype }
+
+func _C_freeaddrinfo(ai *_C_struct_addrinfo) {
+	unix.Freeaddrinfo(ai)
+}
+
+func _C_gai_strerror(eai _C_int) string {
+	return unix.GaiStrerror(int(eai))
+}
+
+func _C_getaddrinfo(hostname, servname *byte, hints *_C_struct_addrinfo, res **_C_struct_addrinfo) (int, error) {
+	return unix.Getaddrinfo(hostname, servname, hints, res)
+}
+
+func _C_res_ninit(state *_C_struct___res_state) error {
+	unix.ResNinit(state)
+	return nil
+}
+
+func _C_res_nsearch(state *_C_struct___res_state, dname *_C_char, class, typ int, ans *_C_char, anslen int) (int, error) {
+	return unix.ResNsearch(state, dname, class, typ, ans, anslen)
+}
+
+func _C_res_nclose(state *_C_struct___res_state) {
+	unix.ResNclose(state)
+}
+
+func cgoNameinfoPTR(b []byte, sa *syscall.RawSockaddr, salen int) (int, error) {
+	gerrno, err := unix.Getnameinfo(sa, salen, &b[0], len(b), nil, 0, unix.NI_NAMEREQD)
+	return int(gerrno), err
+}
+
+func cgoSockaddrInet4(ip IP) *syscall.RawSockaddr {
+	sa := syscall.RawSockaddrInet4{Len: syscall.SizeofSockaddrInet4, Family: syscall.AF_INET}
+	copy(sa.Addr[:], ip)
+	return (*syscall.RawSockaddr)(unsafe.Pointer(&sa))
+}
+
+func cgoSockaddrInet6(ip IP, zone int) *syscall.RawSockaddr {
+	sa := syscall.RawSockaddrInet6{Len: syscall.SizeofSockaddrInet6, Family: syscall.AF_INET6, Scope_id: uint32(zone)}
+	copy(sa.Addr[:], ip)
+	return (*syscall.RawSockaddr)(unsafe.Pointer(&sa))
+}
diff --git a/src/net/cgo_unix_test.go b/src/net/cgo_unix_test.go
index af9f9dc..86726dd 100644
--- a/src/net/cgo_unix_test.go
+++ b/src/net/cgo_unix_test.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build cgo && !netgo && unix
+//go:build (cgo || darwin) && !netgo && unix
 
 package net
 
diff --git a/src/net/conf.go b/src/net/conf.go
index b08bbc7..4119604 100644
--- a/src/net/conf.go
+++ b/src/net/conf.go
@@ -28,9 +28,6 @@
 
 	goos          string // the runtime.GOOS, to ease testing
 	dnsDebugLevel int
-
-	nss    *nssConf
-	resolv *dnsConfig
 }
 
 var (
@@ -112,20 +109,6 @@
 		return
 	}
 
-	if runtime.GOOS != "openbsd" {
-		confVal.nss = parseNSSConfFile("/etc/nsswitch.conf")
-	}
-
-	confVal.resolv = dnsReadConfig("/etc/resolv.conf")
-	if confVal.resolv.err != nil && !os.IsNotExist(confVal.resolv.err) &&
-		!os.IsPermission(confVal.resolv.err) {
-		// If we can't read the resolv.conf file, assume it
-		// had something important in it and defer to cgo.
-		// libc's resolver might then fail too, but at least
-		// it wasn't our fault.
-		confVal.forceCgoLookupHost = true
-	}
-
 	if _, err := os.Stat("/etc/mdns.allow"); err == nil {
 		confVal.hasMDNSAllow = true
 	}
@@ -134,12 +117,14 @@
 // canUseCgo reports whether calling cgo functions is allowed
 // for non-hostname lookups.
 func (c *conf) canUseCgo() bool {
-	return c.hostLookupOrder(nil, "") == hostLookupCgo
+	ret, _ := c.hostLookupOrder(nil, "")
+	return ret == hostLookupCgo
 }
 
 // hostLookupOrder determines which strategy to use to resolve hostname.
 // The provided Resolver is optional. nil means to not consider its options.
-func (c *conf) hostLookupOrder(r *Resolver, hostname string) (ret hostLookupOrder) {
+// It also returns dnsConfig when it was used to determine the lookup order.
+func (c *conf) hostLookupOrder(r *Resolver, hostname string) (ret hostLookupOrder, dnsConfig *dnsConfig) {
 	if c.dnsDebugLevel > 1 {
 		defer func() {
 			print("go package net: hostLookupOrder(", hostname, ") = ", ret.String(), "\n")
@@ -158,16 +143,26 @@
 			fallbackOrder = hostLookupFilesDNS
 		}
 	}
-	if c.goos == "windows" || c.goos == "plan9" {
-		return fallbackOrder
-	}
-	if c.forceCgoLookupHost || c.resolv.unknownOpt || c.goos == "android" {
-		return fallbackOrder
+	if c.forceCgoLookupHost || c.goos == "android" || c.goos == "windows" || c.goos == "plan9" {
+		return fallbackOrder, nil
 	}
 	if bytealg.IndexByteString(hostname, '\\') != -1 || bytealg.IndexByteString(hostname, '%') != -1 {
 		// Don't deal with special form hostnames with backslashes
 		// or '%'.
-		return fallbackOrder
+		return fallbackOrder, nil
+	}
+
+	conf := getSystemDNSConfig()
+	if conf.err != nil && !os.IsNotExist(conf.err) && !os.IsPermission(conf.err) {
+		// If we can't read the resolv.conf file, assume it
+		// had something important in it and defer to cgo.
+		// libc's resolver might then fail too, but at least
+		// it wasn't our fault.
+		return fallbackOrder, conf
+	}
+
+	if conf.unknownOpt {
+		return fallbackOrder, conf
 	}
 
 	// OpenBSD is unique and doesn't use nsswitch.conf.
@@ -176,39 +171,40 @@
 		// OpenBSD's resolv.conf manpage says that a non-existent
 		// resolv.conf means "lookup" defaults to only "files",
 		// without DNS lookups.
-		if os.IsNotExist(c.resolv.err) {
-			return hostLookupFiles
+		if os.IsNotExist(conf.err) {
+			return hostLookupFiles, conf
 		}
-		lookup := c.resolv.lookup
+
+		lookup := conf.lookup
 		if len(lookup) == 0 {
 			// https://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man5/resolv.conf.5
 			// "If the lookup keyword is not used in the
 			// system's resolv.conf file then the assumed
 			// order is 'bind file'"
-			return hostLookupDNSFiles
+			return hostLookupDNSFiles, conf
 		}
 		if len(lookup) < 1 || len(lookup) > 2 {
-			return fallbackOrder
+			return fallbackOrder, conf
 		}
 		switch lookup[0] {
 		case "bind":
 			if len(lookup) == 2 {
 				if lookup[1] == "file" {
-					return hostLookupDNSFiles
+					return hostLookupDNSFiles, conf
 				}
-				return fallbackOrder
+				return fallbackOrder, conf
 			}
-			return hostLookupDNS
+			return hostLookupDNS, conf
 		case "file":
 			if len(lookup) == 2 {
 				if lookup[1] == "bind" {
-					return hostLookupFilesDNS
+					return hostLookupFilesDNS, conf
 				}
-				return fallbackOrder
+				return fallbackOrder, conf
 			}
-			return hostLookupFiles
+			return hostLookupFiles, conf
 		default:
-			return fallbackOrder
+			return fallbackOrder, conf
 		}
 	}
 
@@ -221,43 +217,44 @@
 		// because Go's native resolver doesn't do mDNS or
 		// similar local resolution mechanisms, assume that
 		// libc might (via Avahi, etc) and use cgo.
-		return fallbackOrder
+		return fallbackOrder, conf
 	}
 
-	nss := c.nss
+	nss := getSystemNSS()
 	srcs := nss.sources["hosts"]
 	// If /etc/nsswitch.conf doesn't exist or doesn't specify any
 	// sources for "hosts", assume Go's DNS will work fine.
 	if os.IsNotExist(nss.err) || (nss.err == nil && len(srcs) == 0) {
 		if c.goos == "solaris" {
 			// illumos defaults to "nis [NOTFOUND=return] files"
-			return fallbackOrder
+			return fallbackOrder, conf
 		}
-		return hostLookupFilesDNS
+
+		return hostLookupFilesDNS, conf
 	}
 	if nss.err != nil {
 		// We failed to parse or open nsswitch.conf, so
 		// conservatively assume we should use cgo if it's
 		// available.
-		return fallbackOrder
+		return fallbackOrder, conf
 	}
 
 	var mdnsSource, filesSource, dnsSource bool
 	var first string
 	for _, src := range srcs {
 		if src.source == "myhostname" {
-			if isLocalhost(hostname) || isGateway(hostname) {
-				return fallbackOrder
+			if isLocalhost(hostname) || isGateway(hostname) || isOutbound(hostname) {
+				return fallbackOrder, conf
 			}
 			hn, err := getHostname()
 			if err != nil || stringsEqualFold(hostname, hn) {
-				return fallbackOrder
+				return fallbackOrder, conf
 			}
 			continue
 		}
 		if src.source == "files" || src.source == "dns" {
 			if !src.standardCriteria() {
-				return fallbackOrder // non-standard; let libc deal with it.
+				return fallbackOrder, conf // non-standard; let libc deal with it.
 			}
 			if src.source == "files" {
 				filesSource = true
@@ -277,14 +274,14 @@
 			continue
 		}
 		// Some source we don't know how to deal with.
-		return fallbackOrder
+		return fallbackOrder, conf
 	}
 
 	// We don't parse mdns.allow files. They're rare. If one
 	// exists, it might list other TLDs (besides .local) or even
 	// '*', so just let libc deal with it.
 	if mdnsSource && c.hasMDNSAllow {
-		return fallbackOrder
+		return fallbackOrder, conf
 	}
 
 	// Cases where Go can handle it without cgo and C thread
@@ -292,20 +289,22 @@
 	switch {
 	case filesSource && dnsSource:
 		if first == "files" {
-			return hostLookupFilesDNS
+			return hostLookupFilesDNS, conf
 		} else {
-			return hostLookupDNSFiles
+			return hostLookupDNSFiles, conf
 		}
 	case filesSource:
-		return hostLookupFiles
+		return hostLookupFiles, conf
 	case dnsSource:
-		return hostLookupDNS
+		return hostLookupDNS, conf
 	}
 
 	// Something weird. Let libc deal with it.
-	return fallbackOrder
+	return fallbackOrder, conf
 }
 
+var netdns = godebug.New("netdns")
+
 // goDebugNetDNS parses the value of the GODEBUG "netdns" value.
 // The netdns value can be of the form:
 //
@@ -319,7 +318,7 @@
 //
 // etc.
 func goDebugNetDNS() (dnsMode string, debugLevel int) {
-	goDebug := godebug.Get("netdns")
+	goDebug := netdns.Value()
 	parsePart := func(s string) {
 		if s == "" {
 			return
@@ -348,5 +347,11 @@
 // isGateway reports whether h should be considered a "gateway"
 // name for the myhostname NSS module.
 func isGateway(h string) bool {
-	return stringsEqualFold(h, "gateway")
+	return stringsEqualFold(h, "_gateway")
+}
+
+// isOutbound reports whether h should be considered a "outbound"
+// name for the myhostname NSS module.
+func isOutbound(h string) bool {
+	return stringsEqualFold(h, "_outbound")
 }
diff --git a/src/net/conf_test.go b/src/net/conf_test.go
index 5ae7055..3736709 100644
--- a/src/net/conf_test.go
+++ b/src/net/conf_test.go
@@ -2,14 +2,15 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
+//go:build unix
 
 package net
 
 import (
 	"io/fs"
-	"strings"
+	"os"
 	"testing"
+	"time"
 )
 
 type nssHostTest struct {
@@ -18,7 +19,19 @@
 	want      hostLookupOrder
 }
 
-func nssStr(s string) *nssConf { return parseNSSConf(strings.NewReader(s)) }
+func nssStr(t *testing.T, s string) *nssConf {
+	f, err := os.CreateTemp(t.TempDir(), "nss")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if _, err := f.WriteString(s); err != nil {
+		t.Fatal(err)
+	}
+	if err := f.Close(); err != nil {
+		t.Fatal(err)
+	}
+	return parseNSSConfFile(f.Name())
+}
 
 // represents a dnsConfig returned by parsing a nonexistent resolv.conf
 var defaultResolvConf = &dnsConfig{
@@ -33,16 +46,18 @@
 	tests := []struct {
 		name      string
 		c         *conf
+		nss       *nssConf
 		resolver  *Resolver
+		resolv    *dnsConfig
 		hostTests []nssHostTest
 	}{
 		{
 			name: "force",
 			c: &conf{
 				forceCgoLookupHost: true,
-				nss:                nssStr("foo: bar"),
-				resolv:             defaultResolvConf,
 			},
+			resolv: defaultResolvConf,
+			nss:    nssStr(t, "foo: bar"),
 			hostTests: []nssHostTest{
 				{"foo.local", "myhostname", hostLookupCgo},
 				{"google.com", "myhostname", hostLookupCgo},
@@ -51,10 +66,10 @@
 		{
 			name: "netgo_dns_before_files",
 			c: &conf{
-				netGo:  true,
-				nss:    nssStr("hosts: dns files"),
-				resolv: defaultResolvConf,
+				netGo: true,
 			},
+			resolv: defaultResolvConf,
+			nss:    nssStr(t, "hosts: dns files"),
 			hostTests: []nssHostTest{
 				{"x.com", "myhostname", hostLookupDNSFiles},
 			},
@@ -62,20 +77,19 @@
 		{
 			name: "netgo_fallback_on_cgo",
 			c: &conf{
-				netGo:  true,
-				nss:    nssStr("hosts: dns files something_custom"),
-				resolv: defaultResolvConf,
+				netGo: true,
 			},
+			resolv: defaultResolvConf,
+			nss:    nssStr(t, "hosts: dns files something_custom"),
 			hostTests: []nssHostTest{
 				{"x.com", "myhostname", hostLookupFilesDNS},
 			},
 		},
 		{
-			name: "ubuntu_trusty_avahi",
-			c: &conf{
-				nss:    nssStr("hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4"),
-				resolv: defaultResolvConf,
-			},
+			name:   "ubuntu_trusty_avahi",
+			c:      &conf{},
+			resolv: defaultResolvConf,
+			nss:    nssStr(t, "hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4"),
 			hostTests: []nssHostTest{
 				{"foo.local", "myhostname", hostLookupCgo},
 				{"foo.local.", "myhostname", hostLookupCgo},
@@ -87,36 +101,36 @@
 		{
 			name: "freebsdlinux_no_resolv_conf",
 			c: &conf{
-				goos:   "freebsd",
-				nss:    nssStr("foo: bar"),
-				resolv: defaultResolvConf,
+				goos: "freebsd",
 			},
+			resolv:    defaultResolvConf,
+			nss:       nssStr(t, "foo: bar"),
 			hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupFilesDNS}},
 		},
 		// On OpenBSD, no resolv.conf means no DNS.
 		{
 			name: "openbsd_no_resolv_conf",
 			c: &conf{
-				goos:   "openbsd",
-				resolv: defaultResolvConf,
+				goos: "openbsd",
 			},
+			resolv:    defaultResolvConf,
 			hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupFiles}},
 		},
 		{
 			name: "solaris_no_nsswitch",
 			c: &conf{
-				goos:   "solaris",
-				nss:    &nssConf{err: fs.ErrNotExist},
-				resolv: defaultResolvConf,
+				goos: "solaris",
 			},
+			resolv:    defaultResolvConf,
+			nss:       &nssConf{err: fs.ErrNotExist},
 			hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupCgo}},
 		},
 		{
 			name: "openbsd_lookup_bind_file",
 			c: &conf{
-				goos:   "openbsd",
-				resolv: &dnsConfig{lookup: []string{"bind", "file"}},
+				goos: "openbsd",
 			},
+			resolv: &dnsConfig{lookup: []string{"bind", "file"}},
 			hostTests: []nssHostTest{
 				{"google.com", "myhostname", hostLookupDNSFiles},
 				{"foo.local", "myhostname", hostLookupDNSFiles},
@@ -125,86 +139,84 @@
 		{
 			name: "openbsd_lookup_file_bind",
 			c: &conf{
-				goos:   "openbsd",
-				resolv: &dnsConfig{lookup: []string{"file", "bind"}},
+				goos: "openbsd",
 			},
+			resolv:    &dnsConfig{lookup: []string{"file", "bind"}},
 			hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupFilesDNS}},
 		},
 		{
 			name: "openbsd_lookup_bind",
 			c: &conf{
-				goos:   "openbsd",
-				resolv: &dnsConfig{lookup: []string{"bind"}},
+				goos: "openbsd",
 			},
+			resolv:    &dnsConfig{lookup: []string{"bind"}},
 			hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupDNS}},
 		},
 		{
 			name: "openbsd_lookup_file",
 			c: &conf{
-				goos:   "openbsd",
-				resolv: &dnsConfig{lookup: []string{"file"}},
+				goos: "openbsd",
 			},
+			resolv:    &dnsConfig{lookup: []string{"file"}},
 			hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupFiles}},
 		},
 		{
 			name: "openbsd_lookup_yp",
 			c: &conf{
-				goos:   "openbsd",
-				resolv: &dnsConfig{lookup: []string{"file", "bind", "yp"}},
+				goos: "openbsd",
 			},
+			resolv:    &dnsConfig{lookup: []string{"file", "bind", "yp"}},
 			hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupCgo}},
 		},
 		{
 			name: "openbsd_lookup_two",
 			c: &conf{
-				goos:   "openbsd",
-				resolv: &dnsConfig{lookup: []string{"file", "foo"}},
+				goos: "openbsd",
 			},
+			resolv:    &dnsConfig{lookup: []string{"file", "foo"}},
 			hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupCgo}},
 		},
 		{
 			name: "openbsd_lookup_empty",
 			c: &conf{
-				goos:   "openbsd",
-				resolv: &dnsConfig{lookup: nil},
+				goos: "openbsd",
 			},
+			resolv:    &dnsConfig{lookup: nil},
 			hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupDNSFiles}},
 		},
 		{
 			name: "linux_no_nsswitch.conf",
 			c: &conf{
-				goos:   "linux",
-				nss:    &nssConf{err: fs.ErrNotExist},
-				resolv: defaultResolvConf,
+				goos: "linux",
 			},
+			resolv:    defaultResolvConf,
+			nss:       &nssConf{err: fs.ErrNotExist},
 			hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupFilesDNS}},
 		},
 		{
 			name: "linux_empty_nsswitch.conf",
 			c: &conf{
-				goos:   "linux",
-				nss:    nssStr(""),
-				resolv: defaultResolvConf,
+				goos: "linux",
 			},
+			resolv:    defaultResolvConf,
+			nss:       nssStr(t, ""),
 			hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupFilesDNS}},
 		},
 		{
-			name: "files_mdns_dns",
-			c: &conf{
-				nss:    nssStr("hosts: files mdns dns"),
-				resolv: defaultResolvConf,
-			},
+			name:   "files_mdns_dns",
+			c:      &conf{},
+			resolv: defaultResolvConf,
+			nss:    nssStr(t, "hosts: files mdns dns"),
 			hostTests: []nssHostTest{
 				{"x.com", "myhostname", hostLookupFilesDNS},
 				{"x.local", "myhostname", hostLookupCgo},
 			},
 		},
 		{
-			name: "dns_special_hostnames",
-			c: &conf{
-				nss:    nssStr("hosts: dns"),
-				resolv: defaultResolvConf,
-			},
+			name:   "dns_special_hostnames",
+			c:      &conf{},
+			resolv: defaultResolvConf,
+			nss:    nssStr(t, "hosts: dns"),
 			hostTests: []nssHostTest{
 				{"x.com", "myhostname", hostLookupDNS},
 				{"x\\.com", "myhostname", hostLookupCgo},     // punt on weird glibc escape
@@ -214,21 +226,20 @@
 		{
 			name: "mdns_allow",
 			c: &conf{
-				nss:          nssStr("hosts: files mdns dns"),
-				resolv:       defaultResolvConf,
 				hasMDNSAllow: true,
 			},
+			resolv: defaultResolvConf,
+			nss:    nssStr(t, "hosts: files mdns dns"),
 			hostTests: []nssHostTest{
 				{"x.com", "myhostname", hostLookupCgo},
 				{"x.local", "myhostname", hostLookupCgo},
 			},
 		},
 		{
-			name: "files_dns",
-			c: &conf{
-				nss:    nssStr("hosts: files dns"),
-				resolv: defaultResolvConf,
-			},
+			name:   "files_dns",
+			c:      &conf{},
+			resolv: defaultResolvConf,
+			nss:    nssStr(t, "hosts: files dns"),
 			hostTests: []nssHostTest{
 				{"x.com", "myhostname", hostLookupFilesDNS},
 				{"x", "myhostname", hostLookupFilesDNS},
@@ -236,11 +247,10 @@
 			},
 		},
 		{
-			name: "dns_files",
-			c: &conf{
-				nss:    nssStr("hosts: dns files"),
-				resolv: defaultResolvConf,
-			},
+			name:   "dns_files",
+			c:      &conf{},
+			resolv: defaultResolvConf,
+			nss:    nssStr(t, "hosts: dns files"),
 			hostTests: []nssHostTest{
 				{"x.com", "myhostname", hostLookupDNSFiles},
 				{"x", "myhostname", hostLookupDNSFiles},
@@ -248,29 +258,29 @@
 			},
 		},
 		{
-			name: "something_custom",
-			c: &conf{
-				nss:    nssStr("hosts: dns files something_custom"),
-				resolv: defaultResolvConf,
-			},
+			name:   "something_custom",
+			c:      &conf{},
+			resolv: defaultResolvConf,
+			nss:    nssStr(t, "hosts: dns files something_custom"),
 			hostTests: []nssHostTest{
 				{"x.com", "myhostname", hostLookupCgo},
 			},
 		},
 		{
-			name: "myhostname",
-			c: &conf{
-				nss:    nssStr("hosts: files dns myhostname"),
-				resolv: defaultResolvConf,
-			},
+			name:   "myhostname",
+			c:      &conf{},
+			resolv: defaultResolvConf,
+			nss:    nssStr(t, "hosts: files dns myhostname"),
 			hostTests: []nssHostTest{
 				{"x.com", "myhostname", hostLookupFilesDNS},
 				{"myhostname", "myhostname", hostLookupCgo},
 				{"myHostname", "myhostname", hostLookupCgo},
 				{"myhostname.dot", "myhostname.dot", hostLookupCgo},
 				{"myHostname.dot", "myhostname.dot", hostLookupCgo},
-				{"gateway", "myhostname", hostLookupCgo},
-				{"Gateway", "myhostname", hostLookupCgo},
+				{"_gateway", "myhostname", hostLookupCgo},
+				{"_Gateway", "myhostname", hostLookupCgo},
+				{"_outbound", "myhostname", hostLookupCgo},
+				{"_Outbound", "myhostname", hostLookupCgo},
 				{"localhost", "myhostname", hostLookupCgo},
 				{"Localhost", "myhostname", hostLookupCgo},
 				{"anything.localhost", "myhostname", hostLookupCgo},
@@ -284,11 +294,10 @@
 			},
 		},
 		{
-			name: "ubuntu14.04.02",
-			c: &conf{
-				nss:    nssStr("hosts: files myhostname mdns4_minimal [NOTFOUND=return] dns mdns4"),
-				resolv: defaultResolvConf,
-			},
+			name:   "ubuntu14.04.02",
+			c:      &conf{},
+			resolv: defaultResolvConf,
+			nss:    nssStr(t, "hosts: files myhostname mdns4_minimal [NOTFOUND=return] dns mdns4"),
 			hostTests: []nssHostTest{
 				{"x.com", "myhostname", hostLookupFilesDNS},
 				{"somehostname", "myhostname", hostLookupFilesDNS},
@@ -300,32 +309,30 @@
 		// non-standard but redundant notfound=return for the
 		// files.
 		{
-			name: "debian_squeeze",
-			c: &conf{
-				nss:    nssStr("hosts: dns [success=return notfound=continue unavail=continue tryagain=continue] files [notfound=return]"),
-				resolv: defaultResolvConf,
-			},
+			name:   "debian_squeeze",
+			c:      &conf{},
+			resolv: defaultResolvConf,
+			nss:    nssStr(t, "hosts: dns [success=return notfound=continue unavail=continue tryagain=continue] files [notfound=return]"),
 			hostTests: []nssHostTest{
 				{"x.com", "myhostname", hostLookupDNSFiles},
 				{"somehostname", "myhostname", hostLookupDNSFiles},
 			},
 		},
 		{
-			name: "resolv.conf-unknown",
-			c: &conf{
-				nss:    nssStr("foo: bar"),
-				resolv: &dnsConfig{servers: defaultNS, ndots: 1, timeout: 5, attempts: 2, unknownOpt: true},
-			},
+			name:      "resolv.conf-unknown",
+			c:         &conf{},
+			resolv:    &dnsConfig{servers: defaultNS, ndots: 1, timeout: 5, attempts: 2, unknownOpt: true},
+			nss:       nssStr(t, "foo: bar"),
 			hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupCgo}},
 		},
 		// Android should always use cgo.
 		{
 			name: "android",
 			c: &conf{
-				goos:   "android",
-				nss:    nssStr(""),
-				resolv: defaultResolvConf,
+				goos: "android",
 			},
+			resolv: defaultResolvConf,
+			nss:    nssStr(t, ""),
 			hostTests: []nssHostTest{
 				{"x.com", "myhostname", hostLookupCgo},
 			},
@@ -337,10 +344,10 @@
 			c: &conf{
 				goos:               "darwin",
 				forceCgoLookupHost: true, // always true for darwin
-				resolv:             defaultResolvConf,
-				nss:                nssStr(""),
 				netCgo:             true,
 			},
+			resolv: defaultResolvConf,
+			nss:    nssStr(t, ""),
 			hostTests: []nssHostTest{
 				{"localhost", "myhostname", hostLookupFilesDNS},
 			},
@@ -349,18 +356,36 @@
 
 	origGetHostname := getHostname
 	defer func() { getHostname = origGetHostname }()
+	defer setSystemNSS(getSystemNSS(), 0)
+	conf, err := newResolvConfTest()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer conf.teardown()
 
 	for _, tt := range tests {
+		if !conf.forceUpdateConf(tt.resolv, time.Now().Add(time.Hour)) {
+			t.Errorf("%s: failed to change resolv config", tt.name)
+		}
 		for _, ht := range tt.hostTests {
 			getHostname = func() (string, error) { return ht.localhost, nil }
+			setSystemNSS(tt.nss, time.Hour)
 
-			gotOrder := tt.c.hostLookupOrder(tt.resolver, ht.host)
+			gotOrder, _ := tt.c.hostLookupOrder(tt.resolver, ht.host)
 			if gotOrder != ht.want {
 				t.Errorf("%s: hostLookupOrder(%q) = %v; want %v", tt.name, ht.host, gotOrder, ht.want)
 			}
 		}
 	}
+}
 
+func setSystemNSS(nss *nssConf, addDur time.Duration) {
+	nssConfig.mu.Lock()
+	nssConfig.nssConf = nss
+	nssConfig.mu.Unlock()
+	nssConfig.acquireSema()
+	nssConfig.lastChecked = time.Now().Add(addDur)
+	nssConfig.releaseSema()
 }
 
 func TestSystemConf(t *testing.T) {
diff --git a/src/net/dial.go b/src/net/dial.go
index c538342..85ec557 100644
--- a/src/net/dial.go
+++ b/src/net/dial.go
@@ -95,7 +95,19 @@
 	// Network and address parameters passed to Control method are not
 	// necessarily the ones passed to Dial. For example, passing "tcp" to Dial
 	// will cause the Control function to be called with "tcp4" or "tcp6".
+	//
+	// Control is ignored if ControlContext is not nil.
 	Control func(network, address string, c syscall.RawConn) error
+
+	// If ControlContext is not nil, it is called after creating the network
+	// connection but before actually dialing.
+	//
+	// Network and address parameters passed to Control method are not
+	// necessarily the ones passed to Dial. For example, passing "tcp" to Dial
+	// will cause the Control function to be called with "tcp4" or "tcp6".
+	//
+	// If ControlContext is not nil, Control is ignored.
+	ControlContext func(ctx context.Context, network, address string, c syscall.RawConn) error
 }
 
 func (d *Dialer) dualStack() bool { return d.FallbackDelay >= 0 }
@@ -425,21 +437,7 @@
 		primaries = addrs
 	}
 
-	c, err := sd.dialParallel(ctx, primaries, fallbacks)
-	if err != nil {
-		return nil, err
-	}
-
-	if tc, ok := c.(*TCPConn); ok && d.KeepAlive >= 0 {
-		setKeepAlive(tc.fd, true)
-		ka := d.KeepAlive
-		if d.KeepAlive == 0 {
-			ka = defaultTCPKeepAlive
-		}
-		setKeepAlivePeriod(tc.fd, ka)
-		testHookSetKeepAlive(ka)
-	}
-	return c, nil
+	return sd.dialParallel(ctx, primaries, fallbacks)
 }
 
 // dialParallel races two copies of dialSerial, giving the first a
diff --git a/src/net/dial_test.go b/src/net/dial_test.go
index 1256867..b04607e 100644
--- a/src/net/dial_test.go
+++ b/src/net/dial_test.go
@@ -17,6 +17,7 @@
 	"runtime"
 	"strings"
 	"sync"
+	"syscall"
 	"testing"
 	"time"
 )
@@ -171,7 +172,7 @@
 	if err == nil {
 		c.Close()
 	}
-	elapsed := time.Now().Sub(startTime)
+	elapsed := time.Since(startTime)
 	t.Logf("dialClosedPort: measured delay %v", elapsed)
 	return elapsed
 }
@@ -366,7 +367,7 @@
 
 		startTime := time.Now()
 		c, err := d.Dial("tcp", JoinHostPort("slow6loopback4", dss.port))
-		elapsed := time.Now().Sub(startTime)
+		elapsed := time.Since(startTime)
 		if err == nil {
 			c.Close()
 		} else if tt.dualstack {
@@ -939,6 +940,36 @@
 	})
 }
 
+func TestDialerControlContext(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9":
+		t.Skipf("%s does not have full support of socktest", runtime.GOOS)
+	}
+	t.Run("StreamDial", func(t *testing.T) {
+		for i, network := range []string{"tcp", "tcp4", "tcp6", "unix", "unixpacket"} {
+			if !testableNetwork(network) {
+				continue
+			}
+			ln := newLocalListener(t, network)
+			defer ln.Close()
+			var id int
+			d := Dialer{ControlContext: func(ctx context.Context, network string, address string, c syscall.RawConn) error {
+				id = ctx.Value("id").(int)
+				return controlOnConnSetup(network, address, c)
+			}}
+			c, err := d.DialContext(context.WithValue(context.Background(), "id", i+1), network, ln.Addr().String())
+			if err != nil {
+				t.Error(err)
+				continue
+			}
+			if id != i+1 {
+				t.Errorf("got id %d, want %d", id, i+1)
+			}
+			c.Close()
+		}
+	})
+}
+
 // mustHaveExternalNetwork is like testenv.MustHaveExternalNetwork
 // except that it won't skip testing on non-mobile builders.
 func mustHaveExternalNetwork(t *testing.T) {
diff --git a/src/net/dnsclient_unix.go b/src/net/dnsclient_unix.go
index 088c81a..20da8f1 100644
--- a/src/net/dnsclient_unix.go
+++ b/src/net/dnsclient_unix.go
@@ -22,6 +22,7 @@
 	"os"
 	"runtime"
 	"sync"
+	"sync/atomic"
 	"time"
 
 	"golang.org/x/net/dns/dnsmessage"
@@ -51,10 +52,9 @@
 	errServerTemporarilyMisbehaving = errors.New("server misbehaving")
 )
 
-func newRequest(q dnsmessage.Question) (id uint16, udpReq, tcpReq []byte, err error) {
+func newRequest(q dnsmessage.Question, ad bool) (id uint16, udpReq, tcpReq []byte, err error) {
 	id = uint16(randInt())
-	b := dnsmessage.NewBuilder(make([]byte, 2, 514), dnsmessage.Header{ID: id, RecursionDesired: true})
-	b.EnableCompression()
+	b := dnsmessage.NewBuilder(make([]byte, 2, 514), dnsmessage.Header{ID: id, RecursionDesired: true, AuthenticData: ad})
 	if err := b.StartQuestions(); err != nil {
 		return 0, nil, nil, err
 	}
@@ -158,9 +158,9 @@
 }
 
 // exchange sends a query on the connection and hopes for a response.
-func (r *Resolver) exchange(ctx context.Context, server string, q dnsmessage.Question, timeout time.Duration, useTCP bool) (dnsmessage.Parser, dnsmessage.Header, error) {
+func (r *Resolver) exchange(ctx context.Context, server string, q dnsmessage.Question, timeout time.Duration, useTCP, ad bool) (dnsmessage.Parser, dnsmessage.Header, error) {
 	q.Class = dnsmessage.ClassINET
-	id, udpReq, tcpReq, err := newRequest(q)
+	id, udpReq, tcpReq, err := newRequest(q, ad)
 	if err != nil {
 		return dnsmessage.Parser{}, dnsmessage.Header{}, errCannotMarshalDNSMessage
 	}
@@ -274,7 +274,7 @@
 		for j := uint32(0); j < sLen; j++ {
 			server := cfg.servers[(serverOffset+j)%sLen]
 
-			p, h, err := r.exchange(ctx, server, q, cfg.timeout, cfg.useTCP)
+			p, h, err := r.exchange(ctx, server, q, cfg.timeout, cfg.useTCP, cfg.trustAD)
 			if err != nil {
 				dnsErr := &DNSError{
 					Err:    err.Error(),
@@ -343,20 +343,21 @@
 	ch          chan struct{} // guards lastChecked and modTime
 	lastChecked time.Time     // last time resolv.conf was checked
 
-	mu        sync.RWMutex // protects dnsConfig
-	dnsConfig *dnsConfig   // parsed resolv.conf structure used in lookups
+	dnsConfig atomic.Pointer[dnsConfig] // parsed resolv.conf structure used in lookups
 }
 
 var resolvConf resolverConfig
 
+func getSystemDNSConfig() *dnsConfig {
+	resolvConf.tryUpdate("/etc/resolv.conf")
+	return resolvConf.dnsConfig.Load()
+}
+
 // init initializes conf and is only called via conf.initOnce.
 func (conf *resolverConfig) init() {
 	// Set dnsConfig and lastChecked so we don't parse
 	// resolv.conf twice the first time.
-	conf.dnsConfig = systemConf().resolv
-	if conf.dnsConfig == nil {
-		conf.dnsConfig = dnsReadConfig("/etc/resolv.conf")
-	}
+	conf.dnsConfig.Store(dnsReadConfig("/etc/resolv.conf"))
 	conf.lastChecked = time.Now()
 
 	// Prepare ch so that only one update of resolverConfig may
@@ -370,6 +371,10 @@
 func (conf *resolverConfig) tryUpdate(name string) {
 	conf.initOnce.Do(conf.init)
 
+	if conf.dnsConfig.Load().noReload {
+		return
+	}
+
 	// Ensure only one update at a time checks resolv.conf.
 	if !conf.tryAcquireSema() {
 		return
@@ -394,15 +399,13 @@
 		if fi, err := os.Stat(name); err == nil {
 			mtime = fi.ModTime()
 		}
-		if mtime.Equal(conf.dnsConfig.mtime) {
+		if mtime.Equal(conf.dnsConfig.Load().mtime) {
 			return
 		}
 	}
 
 	dnsConf := dnsReadConfig(name)
-	conf.mu.Lock()
-	conf.dnsConfig = dnsConf
-	conf.mu.Unlock()
+	conf.dnsConfig.Store(dnsConf)
 }
 
 func (conf *resolverConfig) tryAcquireSema() bool {
@@ -418,7 +421,7 @@
 	<-conf.ch
 }
 
-func (r *Resolver) lookup(ctx context.Context, name string, qtype dnsmessage.Type) (dnsmessage.Parser, string, error) {
+func (r *Resolver) lookup(ctx context.Context, name string, qtype dnsmessage.Type, conf *dnsConfig) (dnsmessage.Parser, string, error) {
 	if !isDomainName(name) {
 		// We used to use "invalid domain name" as the error,
 		// but that is a detail of the specific lookup mechanism.
@@ -427,10 +430,11 @@
 		// For consistency with libc resolvers, report no such host.
 		return dnsmessage.Parser{}, "", &DNSError{Err: errNoSuchHost.Error(), Name: name, IsNotFound: true}
 	}
-	resolvConf.tryUpdate("/etc/resolv.conf")
-	resolvConf.mu.RLock()
-	conf := resolvConf.dnsConfig
-	resolvConf.mu.RUnlock()
+
+	if conf == nil {
+		conf = getSystemDNSConfig()
+	}
+
 	var (
 		p      dnsmessage.Parser
 		server string
@@ -482,7 +486,7 @@
 	// Check name length (see isDomainName).
 	l := len(name)
 	rooted := l > 0 && name[l-1] == '.'
-	if l > 254 || l == 254 && rooted {
+	if l > 254 || l == 254 && !rooted {
 		return nil
 	}
 
@@ -543,25 +547,19 @@
 	return "hostLookupOrder=" + itoa.Itoa(int(o)) + "??"
 }
 
-// goLookupHost is the native Go implementation of LookupHost.
-// Used only if cgoLookupHost refuses to handle the request
-// (that is, only if cgoLookupHost is the stub in cgo_stub.go).
-// Normally we let cgo use the C library resolver instead of
-// depending on our lookup code, so that Go and C get the same
-// answers.
-func (r *Resolver) goLookupHost(ctx context.Context, name string) (addrs []string, err error) {
-	return r.goLookupHostOrder(ctx, name, hostLookupFilesDNS)
-}
-
-func (r *Resolver) goLookupHostOrder(ctx context.Context, name string, order hostLookupOrder) (addrs []string, err error) {
+func (r *Resolver) goLookupHostOrder(ctx context.Context, name string, order hostLookupOrder, conf *dnsConfig) (addrs []string, err error) {
 	if order == hostLookupFilesDNS || order == hostLookupFiles {
 		// Use entries from /etc/hosts if they match.
-		addrs = lookupStaticHost(name)
-		if len(addrs) > 0 || order == hostLookupFiles {
+		addrs, _ = lookupStaticHost(name)
+		if len(addrs) > 0 {
 			return
 		}
+
+		if order == hostLookupFiles {
+			return nil, &DNSError{Err: errNoSuchHost.Error(), Name: name, IsNotFound: true}
+		}
 	}
-	ips, _, err := r.goLookupIPCNAMEOrder(ctx, "ip", name, order)
+	ips, _, err := r.goLookupIPCNAMEOrder(ctx, "ip", name, order, conf)
 	if err != nil {
 		return
 	}
@@ -573,8 +571,9 @@
 }
 
 // lookup entries from /etc/hosts
-func goLookupIPFiles(name string) (addrs []IPAddr) {
-	for _, haddr := range lookupStaticHost(name) {
+func goLookupIPFiles(name string) (addrs []IPAddr, canonical string) {
+	addr, canonical := lookupStaticHost(name)
+	for _, haddr := range addr {
 		haddr, zone := splitHostZone(haddr)
 		if ip := ParseIP(haddr); ip != nil {
 			addr := IPAddr{IP: ip, Zone: zone}
@@ -582,39 +581,55 @@
 		}
 	}
 	sortByRFC6724(addrs)
-	return
+	return addrs, canonical
 }
 
 // goLookupIP is the native Go implementation of LookupIP.
 // The libc versions are in cgo_*.go.
 func (r *Resolver) goLookupIP(ctx context.Context, network, host string) (addrs []IPAddr, err error) {
-	order := systemConf().hostLookupOrder(r, host)
-	addrs, _, err = r.goLookupIPCNAMEOrder(ctx, network, host, order)
+	order, conf := systemConf().hostLookupOrder(r, host)
+	addrs, _, err = r.goLookupIPCNAMEOrder(ctx, network, host, order, conf)
 	return
 }
 
-func (r *Resolver) goLookupIPCNAMEOrder(ctx context.Context, network, name string, order hostLookupOrder) (addrs []IPAddr, cname dnsmessage.Name, err error) {
+func (r *Resolver) goLookupIPCNAMEOrder(ctx context.Context, network, name string, order hostLookupOrder, conf *dnsConfig) (addrs []IPAddr, cname dnsmessage.Name, err error) {
 	if order == hostLookupFilesDNS || order == hostLookupFiles {
-		addrs = goLookupIPFiles(name)
-		if len(addrs) > 0 || order == hostLookupFiles {
-			return addrs, dnsmessage.Name{}, nil
+		var canonical string
+		addrs, canonical = goLookupIPFiles(name)
+
+		if len(addrs) > 0 {
+			var err error
+			cname, err = dnsmessage.NewName(canonical)
+			if err != nil {
+				return nil, dnsmessage.Name{}, err
+			}
+			return addrs, cname, nil
+		}
+
+		if order == hostLookupFiles {
+			return nil, dnsmessage.Name{}, &DNSError{Err: errNoSuchHost.Error(), Name: name, IsNotFound: true}
 		}
 	}
+
 	if !isDomainName(name) {
 		// See comment in func lookup above about use of errNoSuchHost.
 		return nil, dnsmessage.Name{}, &DNSError{Err: errNoSuchHost.Error(), Name: name, IsNotFound: true}
 	}
-	resolvConf.tryUpdate("/etc/resolv.conf")
-	resolvConf.mu.RLock()
-	conf := resolvConf.dnsConfig
-	resolvConf.mu.RUnlock()
 	type result struct {
 		p      dnsmessage.Parser
 		server string
 		error
 	}
+
+	if conf == nil {
+		conf = getSystemDNSConfig()
+	}
+
 	lane := make(chan result, 1)
 	qtypes := []dnsmessage.Type{dnsmessage.TypeA, dnsmessage.TypeAAAA}
+	if network == "CNAME" {
+		qtypes = append(qtypes, dnsmessage.TypeCNAME)
+	}
 	switch ipVersion(network) {
 	case '4':
 		qtypes = []dnsmessage.Type{dnsmessage.TypeA}
@@ -670,7 +685,7 @@
 			// We asked for recursion, so it should have included all the
 			// answers we need in this one packet.
 			//
-			// Further, RFC 1035 section 4.3.1 says that "the recursive
+			// Further, RFC 1034 section 4.3.1 says that "the recursive
 			// response to a query will be... The answer to the query,
 			// possibly preface by one or more CNAME RRs that specify
 			// aliases encountered on the way to an answer."
@@ -704,6 +719,9 @@
 						break loop
 					}
 					addrs = append(addrs, IPAddr{IP: IP(a.A[:])})
+					if cname.Length == 0 && h.Name.Length != 0 {
+						cname = h.Name
+					}
 
 				case dnsmessage.TypeAAAA:
 					aaaa, err := result.p.AAAAResource()
@@ -716,6 +734,23 @@
 						break loop
 					}
 					addrs = append(addrs, IPAddr{IP: IP(aaaa.AAAA[:])})
+					if cname.Length == 0 && h.Name.Length != 0 {
+						cname = h.Name
+					}
+
+				case dnsmessage.TypeCNAME:
+					c, err := result.p.CNAMEResource()
+					if err != nil {
+						lastErr = &DNSError{
+							Err:    "cannot marshal DNS message",
+							Name:   name,
+							Server: result.server,
+						}
+						break loop
+					}
+					if cname.Length == 0 && c.CNAME.Length > 0 {
+						cname = c.CNAME
+					}
 
 				default:
 					if err := result.p.SkipAnswer(); err != nil {
@@ -728,9 +763,6 @@
 					}
 					continue
 				}
-				if cname.Length == 0 && h.Name.Length != 0 {
-					cname = h.Name
-				}
 			}
 		}
 		if hitStrictError {
@@ -740,7 +772,7 @@
 			addrs = nil
 			break
 		}
-		if len(addrs) > 0 {
+		if len(addrs) > 0 || network == "CNAME" && cname.Length > 0 {
 			break
 		}
 	}
@@ -751,11 +783,20 @@
 		lastErr.Name = name
 	}
 	sortByRFC6724(addrs)
-	if len(addrs) == 0 {
+	if len(addrs) == 0 && !(network == "CNAME" && cname.Length > 0) {
 		if order == hostLookupDNSFiles {
-			addrs = goLookupIPFiles(name)
+			var canonical string
+			addrs, canonical = goLookupIPFiles(name)
+			if len(addrs) > 0 {
+				var err error
+				cname, err = dnsmessage.NewName(canonical)
+				if err != nil {
+					return nil, dnsmessage.Name{}, err
+				}
+				return addrs, cname, nil
+			}
 		}
-		if len(addrs) == 0 && lastErr != nil {
+		if lastErr != nil {
 			return nil, dnsmessage.Name{}, lastErr
 		}
 	}
@@ -763,9 +804,8 @@
 }
 
 // goLookupCNAME is the native Go (non-cgo) implementation of LookupCNAME.
-func (r *Resolver) goLookupCNAME(ctx context.Context, host string) (string, error) {
-	order := systemConf().hostLookupOrder(r, host)
-	_, cname, err := r.goLookupIPCNAMEOrder(ctx, "ip", host, order)
+func (r *Resolver) goLookupCNAME(ctx context.Context, host string, order hostLookupOrder, conf *dnsConfig) (string, error) {
+	_, cname, err := r.goLookupIPCNAMEOrder(ctx, "CNAME", host, order, conf)
 	return cname.String(), err
 }
 
@@ -774,7 +814,7 @@
 // only if cgoLookupPTR is the stub in cgo_stub.go).
 // Normally we let cgo use the C library resolver instead of depending
 // on our lookup code, so that Go and C get the same answers.
-func (r *Resolver) goLookupPTR(ctx context.Context, addr string) ([]string, error) {
+func (r *Resolver) goLookupPTR(ctx context.Context, addr string, conf *dnsConfig) ([]string, error) {
 	names := lookupStaticAddr(addr)
 	if len(names) > 0 {
 		return names, nil
@@ -783,7 +823,7 @@
 	if err != nil {
 		return nil, err
 	}
-	p, server, err := r.lookup(ctx, arpa, dnsmessage.TypePTR)
+	p, server, err := r.lookup(ctx, arpa, dnsmessage.TypePTR, conf)
 	if err != nil {
 		return nil, err
 	}
diff --git a/src/net/dnsclient_unix_test.go b/src/net/dnsclient_unix_test.go
index 415c53e..3ba19eb 100644
--- a/src/net/dnsclient_unix_test.go
+++ b/src/net/dnsclient_unix_test.go
@@ -12,7 +12,9 @@
 	"fmt"
 	"os"
 	"path"
+	"path/filepath"
 	"reflect"
+	"runtime"
 	"strings"
 	"sync"
 	"sync/atomic"
@@ -79,7 +81,7 @@
 	for _, tt := range dnsTransportFallbackTests {
 		ctx, cancel := context.WithCancel(context.Background())
 		defer cancel()
-		_, h, err := r.exchange(ctx, tt.server, tt.question, time.Second, useUDPOrTCP)
+		_, h, err := r.exchange(ctx, tt.server, tt.question, time.Second, useUDPOrTCP, false)
 		if err != nil {
 			t.Error(err)
 			continue
@@ -135,7 +137,7 @@
 	for _, tt := range specialDomainNameTests {
 		ctx, cancel := context.WithCancel(context.Background())
 		defer cancel()
-		_, h, err := r.exchange(ctx, server, tt.question, 3*time.Second, useUDPOrTCP)
+		_, h, err := r.exchange(ctx, server, tt.question, 3*time.Second, useUDPOrTCP, false)
 		if err != nil {
 			t.Error(err)
 			continue
@@ -247,7 +249,7 @@
 	return conf, nil
 }
 
-func (conf *resolvConfTest) writeAndUpdate(lines []string) error {
+func (conf *resolvConfTest) write(lines []string) error {
 	f, err := os.OpenFile(conf.path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0600)
 	if err != nil {
 		return err
@@ -257,32 +259,42 @@
 		return err
 	}
 	f.Close()
-	if err := conf.forceUpdate(conf.path, time.Now().Add(time.Hour)); err != nil {
+	return nil
+}
+
+func (conf *resolvConfTest) writeAndUpdate(lines []string) error {
+	return conf.writeAndUpdateWithLastCheckedTime(lines, time.Now().Add(time.Hour))
+}
+
+func (conf *resolvConfTest) writeAndUpdateWithLastCheckedTime(lines []string, lastChecked time.Time) error {
+	if err := conf.write(lines); err != nil {
 		return err
 	}
-	return nil
+	return conf.forceUpdate(conf.path, lastChecked)
 }
 
 func (conf *resolvConfTest) forceUpdate(name string, lastChecked time.Time) error {
 	dnsConf := dnsReadConfig(name)
-	conf.mu.Lock()
-	conf.dnsConfig = dnsConf
-	conf.mu.Unlock()
+	if !conf.forceUpdateConf(dnsConf, lastChecked) {
+		return fmt.Errorf("tryAcquireSema for %s failed", name)
+	}
+	return nil
+}
+
+func (conf *resolvConfTest) forceUpdateConf(c *dnsConfig, lastChecked time.Time) bool {
+	conf.dnsConfig.Store(c)
 	for i := 0; i < 5; i++ {
 		if conf.tryAcquireSema() {
 			conf.lastChecked = lastChecked
 			conf.releaseSema()
-			return nil
+			return true
 		}
 	}
-	return fmt.Errorf("tryAcquireSema for %s failed", name)
+	return false
 }
 
 func (conf *resolvConfTest) servers() []string {
-	conf.mu.RLock()
-	servers := conf.dnsConfig.servers
-	conf.mu.RUnlock()
-	return servers
+	return conf.dnsConfig.Load().servers
 }
 
 func (conf *resolvConfTest) teardown() error {
@@ -598,16 +610,15 @@
 
 	for _, order := range []hostLookupOrder{hostLookupFilesDNS, hostLookupDNSFiles} {
 		name := fmt.Sprintf("order %v", order)
-
 		// First ensure that we get an error when contacting a non-existent host.
-		_, _, err := r.goLookupIPCNAMEOrder(context.Background(), "ip", "notarealhost", order)
+		_, _, err := r.goLookupIPCNAMEOrder(context.Background(), "ip", "notarealhost", order, nil)
 		if err == nil {
 			t.Errorf("%s: expected error while looking up name not in hosts file", name)
 			continue
 		}
 
 		// Now check that we get an address when the name appears in the hosts file.
-		addrs, _, err := r.goLookupIPCNAMEOrder(context.Background(), "ip", "thor", order) // entry is in "testdata/hosts"
+		addrs, _, err := r.goLookupIPCNAMEOrder(context.Background(), "ip", "thor", order, nil) // entry is in "testdata/hosts"
 		if err != nil {
 			t.Errorf("%s: expected to successfully lookup host entry", name)
 			continue
@@ -1380,7 +1391,7 @@
 
 	for _, strict := range []bool{true, false} {
 		r := Resolver{StrictErrors: strict, Dial: fake.DialContext}
-		p, _, err := r.lookup(context.Background(), name, dnsmessage.TypeTXT)
+		p, _, err := r.lookup(context.Background(), name, dnsmessage.TypeTXT, nil)
 		var wantErr error
 		var wantRRs int
 		if strict {
@@ -1431,9 +1442,7 @@
 func lookupWithFake(fake fakeDNSServer, name string, typ dnsmessage.Type) error {
 	r := Resolver{PreferGo: true, Dial: fake.DialContext}
 
-	resolvConf.mu.RLock()
-	conf := resolvConf.dnsConfig
-	resolvConf.mu.RUnlock()
+	conf := resolvConf.dnsConfig.Load()
 
 	ctx, cancel := context.WithCancel(context.Background())
 	defer cancel()
@@ -1593,7 +1602,7 @@
 	}
 	r := Resolver{PreferGo: true, Dial: fake.DialContext}
 	ctx := context.Background()
-	_, _, err := r.exchange(ctx, "0.0.0.0", mustQuestion("com.", dnsmessage.TypeALL, dnsmessage.ClassINET), time.Second, useUDPOrTCP)
+	_, _, err := r.exchange(ctx, "0.0.0.0", mustQuestion("com.", dnsmessage.TypeALL, dnsmessage.ClassINET), time.Second, useUDPOrTCP, false)
 	if err != nil {
 		t.Fatal("exhange failed:", err)
 	}
@@ -1746,7 +1755,7 @@
 	r := Resolver{PreferGo: true, Dial: fake.DialContext}
 	ctx, cancel := context.WithCancel(context.Background())
 	defer cancel()
-	_, _, err := r.exchange(ctx, "0.0.0.0", mustQuestion("com.", dnsmessage.TypeALL, dnsmessage.ClassINET), time.Second, useTCPOnly)
+	_, _, err := r.exchange(ctx, "0.0.0.0", mustQuestion("com.", dnsmessage.TypeALL, dnsmessage.ClassINET), time.Second, useTCPOnly, false)
 	if err != nil {
 		t.Fatal("exchange failed:", err)
 	}
@@ -2162,6 +2171,56 @@
 	}
 }
 
+func TestGoLookupIPCNAMEOrderHostsAliasesFilesOnlyMode(t *testing.T) {
+	defer func(orig string) { testHookHostsPath = orig }(testHookHostsPath)
+	testHookHostsPath = "testdata/aliases"
+	mode := hostLookupFiles
+
+	for _, v := range lookupStaticHostAliasesTest {
+		testGoLookupIPCNAMEOrderHostsAliases(t, mode, v.lookup, absDomainName(v.res))
+	}
+}
+
+func TestGoLookupIPCNAMEOrderHostsAliasesFilesDNSMode(t *testing.T) {
+	defer func(orig string) { testHookHostsPath = orig }(testHookHostsPath)
+	testHookHostsPath = "testdata/aliases"
+	mode := hostLookupFilesDNS
+
+	for _, v := range lookupStaticHostAliasesTest {
+		testGoLookupIPCNAMEOrderHostsAliases(t, mode, v.lookup, absDomainName(v.res))
+	}
+}
+
+var goLookupIPCNAMEOrderDNSFilesModeTests = []struct {
+	lookup, res string
+}{
+	// 127.0.1.1
+	{"invalid.invalid", "invalid.test"},
+}
+
+func TestGoLookupIPCNAMEOrderHostsAliasesDNSFilesMode(t *testing.T) {
+	defer func(orig string) { testHookHostsPath = orig }(testHookHostsPath)
+	testHookHostsPath = "testdata/aliases"
+	mode := hostLookupDNSFiles
+
+	for _, v := range goLookupIPCNAMEOrderDNSFilesModeTests {
+		testGoLookupIPCNAMEOrderHostsAliases(t, mode, v.lookup, absDomainName(v.res))
+	}
+}
+
+func testGoLookupIPCNAMEOrderHostsAliases(t *testing.T, mode hostLookupOrder, lookup, lookupRes string) {
+	ins := []string{lookup, absDomainName(lookup), strings.ToLower(lookup), strings.ToUpper(lookup)}
+	for _, in := range ins {
+		_, res, err := goResolver.goLookupIPCNAMEOrder(context.Background(), "ip", in, mode, nil)
+		if err != nil {
+			t.Errorf("expected err == nil, but got error: %v", err)
+		}
+		if res.String() != lookupRes {
+			t.Errorf("goLookupIPCNAMEOrder(%v): got %v, want %v", in, res, lookupRes)
+		}
+	}
+}
+
 // Test that we advertise support for a larger DNS packet size.
 // This isn't a great test as it just tests the dnsmessage package
 // against itself.
@@ -2216,3 +2275,322 @@
 		t.Errorf("lookup failed: %v", err)
 	}
 }
+
+func TestLongDNSNames(t *testing.T) {
+	const longDNSsuffix = ".go.dev."
+	const longDNSsuffixNoEndingDot = ".go.dev"
+
+	var longDNSPrefix = strings.Repeat("verylongdomainlabel.", 20)
+
+	var longDNSNamesTests = []struct {
+		req  string
+		fail bool
+	}{
+		{req: longDNSPrefix[:255-len(longDNSsuffix)] + longDNSsuffix, fail: true},
+		{req: longDNSPrefix[:254-len(longDNSsuffix)] + longDNSsuffix},
+		{req: longDNSPrefix[:253-len(longDNSsuffix)] + longDNSsuffix},
+
+		{req: longDNSPrefix[:253-len(longDNSsuffixNoEndingDot)] + longDNSsuffixNoEndingDot},
+		{req: longDNSPrefix[:254-len(longDNSsuffixNoEndingDot)] + longDNSsuffixNoEndingDot, fail: true},
+	}
+
+	fake := fakeDNSServer{
+		rh: func(_, _ string, q dnsmessage.Message, _ time.Time) (dnsmessage.Message, error) {
+			r := dnsmessage.Message{
+				Header: dnsmessage.Header{
+					ID:       q.Header.ID,
+					Response: true,
+					RCode:    dnsmessage.RCodeSuccess,
+				},
+				Questions: q.Questions,
+				Answers: []dnsmessage.Resource{
+					{
+						Header: dnsmessage.ResourceHeader{
+							Name:  q.Questions[0].Name,
+							Type:  q.Questions[0].Type,
+							Class: dnsmessage.ClassINET,
+						},
+					},
+				},
+			}
+
+			switch q.Questions[0].Type {
+			case dnsmessage.TypeA:
+				r.Answers[0].Body = &dnsmessage.AResource{A: TestAddr}
+			case dnsmessage.TypeAAAA:
+				r.Answers[0].Body = &dnsmessage.AAAAResource{AAAA: TestAddr6}
+			case dnsmessage.TypeTXT:
+				r.Answers[0].Body = &dnsmessage.TXTResource{TXT: []string{"."}}
+			case dnsmessage.TypeMX:
+				r.Answers[0].Body = &dnsmessage.MXResource{
+					MX: dnsmessage.MustNewName("go.dev."),
+				}
+			case dnsmessage.TypeNS:
+				r.Answers[0].Body = &dnsmessage.NSResource{
+					NS: dnsmessage.MustNewName("go.dev."),
+				}
+			case dnsmessage.TypeSRV:
+				r.Answers[0].Body = &dnsmessage.SRVResource{
+					Target: dnsmessage.MustNewName("go.dev."),
+				}
+			case dnsmessage.TypeCNAME:
+				r.Answers[0].Body = &dnsmessage.CNAMEResource{
+					CNAME: dnsmessage.MustNewName("fake.cname."),
+				}
+			default:
+				panic("unknown dnsmessage type")
+			}
+
+			return r, nil
+		},
+	}
+
+	r := &Resolver{PreferGo: true, Dial: fake.DialContext}
+
+	methodTests := []string{"CNAME", "Host", "IP", "IPAddr", "MX", "NS", "NetIP", "SRV", "TXT"}
+	query := func(t string, req string) error {
+		switch t {
+		case "CNAME":
+			_, err := r.LookupCNAME(context.Background(), req)
+			return err
+		case "Host":
+			_, err := r.LookupHost(context.Background(), req)
+			return err
+		case "IP":
+			_, err := r.LookupIP(context.Background(), "ip", req)
+			return err
+		case "IPAddr":
+			_, err := r.LookupIPAddr(context.Background(), req)
+			return err
+		case "MX":
+			_, err := r.LookupMX(context.Background(), req)
+			return err
+		case "NS":
+			_, err := r.LookupNS(context.Background(), req)
+			return err
+		case "NetIP":
+			_, err := r.LookupNetIP(context.Background(), "ip", req)
+			return err
+		case "SRV":
+			const service = "service"
+			const proto = "proto"
+			req = req[len(service)+len(proto)+4:]
+			_, _, err := r.LookupSRV(context.Background(), service, proto, req)
+			return err
+		case "TXT":
+			_, err := r.LookupTXT(context.Background(), req)
+			return err
+		}
+		panic("unknown query method")
+	}
+
+	for i, v := range longDNSNamesTests {
+		for _, testName := range methodTests {
+			err := query(testName, v.req)
+			if v.fail {
+				if err == nil {
+					t.Errorf("%v: Lookup%v: unexpected success", i, testName)
+					break
+				}
+
+				expectedErr := DNSError{Err: errNoSuchHost.Error(), Name: v.req, IsNotFound: true}
+				var dnsErr *DNSError
+				errors.As(err, &dnsErr)
+				if dnsErr == nil || *dnsErr != expectedErr {
+					t.Errorf("%v: Lookup%v: unexpected error: %v", i, testName, err)
+				}
+				break
+			}
+			if err != nil {
+				t.Errorf("%v: Lookup%v: unexpected error: %v", i, testName, err)
+			}
+		}
+	}
+}
+
+func TestDNSTrustAD(t *testing.T) {
+	fake := fakeDNSServer{
+		rh: func(_, _ string, q dnsmessage.Message, _ time.Time) (dnsmessage.Message, error) {
+			if q.Questions[0].Name.String() == "notrustad.go.dev." && q.Header.AuthenticData {
+				t.Error("unexpected AD bit")
+			}
+
+			if q.Questions[0].Name.String() == "trustad.go.dev." && !q.Header.AuthenticData {
+				t.Error("expected AD bit")
+			}
+
+			r := dnsmessage.Message{
+				Header: dnsmessage.Header{
+					ID:       q.Header.ID,
+					Response: true,
+					RCode:    dnsmessage.RCodeSuccess,
+				},
+				Questions: q.Questions,
+			}
+			if q.Questions[0].Type == dnsmessage.TypeA {
+				r.Answers = []dnsmessage.Resource{
+					{
+						Header: dnsmessage.ResourceHeader{
+							Name:   q.Questions[0].Name,
+							Type:   dnsmessage.TypeA,
+							Class:  dnsmessage.ClassINET,
+							Length: 4,
+						},
+						Body: &dnsmessage.AResource{
+							A: TestAddr,
+						},
+					},
+				}
+			}
+
+			return r, nil
+		}}
+
+	r := &Resolver{PreferGo: true, Dial: fake.DialContext}
+
+	conf, err := newResolvConfTest()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer conf.teardown()
+
+	err = conf.writeAndUpdate([]string{"nameserver 127.0.0.1"})
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if _, err := r.LookupIPAddr(context.Background(), "notrustad.go.dev"); err != nil {
+		t.Errorf("lookup failed: %v", err)
+	}
+
+	err = conf.writeAndUpdate([]string{"nameserver 127.0.0.1", "options trust-ad"})
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if _, err := r.LookupIPAddr(context.Background(), "trustad.go.dev"); err != nil {
+		t.Errorf("lookup failed: %v", err)
+	}
+}
+
+func TestDNSConfigNoReload(t *testing.T) {
+	r := &Resolver{PreferGo: true, Dial: func(ctx context.Context, network, address string) (Conn, error) {
+		if address != "192.0.2.1:53" {
+			return nil, errors.New("configuration unexpectedly changed")
+		}
+		return fakeDNSServerSuccessful.DialContext(ctx, network, address)
+	}}
+
+	conf, err := newResolvConfTest()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer conf.teardown()
+
+	err = conf.writeAndUpdateWithLastCheckedTime([]string{"nameserver 192.0.2.1", "options no-reload"}, time.Now().Add(-time.Hour))
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if _, err = r.LookupHost(context.Background(), "go.dev"); err != nil {
+		t.Fatal(err)
+	}
+
+	err = conf.write([]string{"nameserver 192.0.2.200"})
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if _, err = r.LookupHost(context.Background(), "go.dev"); err != nil {
+		t.Fatal(err)
+	}
+}
+
+func TestLookupOrderFilesNoSuchHost(t *testing.T) {
+	defer func(orig string) { testHookHostsPath = orig }(testHookHostsPath)
+	if runtime.GOOS != "openbsd" {
+		defer setSystemNSS(getSystemNSS(), 0)
+		setSystemNSS(nssStr(t, "hosts: files"), time.Hour)
+	}
+
+	conf, err := newResolvConfTest()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer conf.teardown()
+
+	resolvConf := dnsConfig{servers: defaultNS}
+	if runtime.GOOS == "openbsd" {
+		// Set error to ErrNotExist, so that the hostLookupOrder
+		// returns hostLookupFiles for openbsd.
+		resolvConf.err = os.ErrNotExist
+	}
+
+	if !conf.forceUpdateConf(&resolvConf, time.Now().Add(time.Hour)) {
+		t.Fatal("failed to update resolv config")
+	}
+
+	tmpFile := filepath.Join(t.TempDir(), "hosts")
+	if err := os.WriteFile(tmpFile, []byte{}, 0660); err != nil {
+		t.Fatal(err)
+	}
+	testHookHostsPath = tmpFile
+
+	const testName = "test.invalid"
+
+	order, _ := systemConf().hostLookupOrder(DefaultResolver, testName)
+	if order != hostLookupFiles {
+		// skip test for systems which do not return hostLookupFiles
+		t.Skipf("hostLookupOrder did not return hostLookupFiles")
+	}
+
+	var lookupTests = []struct {
+		name   string
+		lookup func(name string) error
+	}{
+		{
+			name: "Host",
+			lookup: func(name string) error {
+				_, err = DefaultResolver.LookupHost(context.Background(), name)
+				return err
+			},
+		},
+		{
+			name: "IP",
+			lookup: func(name string) error {
+				_, err = DefaultResolver.LookupIP(context.Background(), "ip", name)
+				return err
+			},
+		},
+		{
+			name: "IPAddr",
+			lookup: func(name string) error {
+				_, err = DefaultResolver.LookupIPAddr(context.Background(), name)
+				return err
+			},
+		},
+		{
+			name: "NetIP",
+			lookup: func(name string) error {
+				_, err = DefaultResolver.LookupNetIP(context.Background(), "ip", name)
+				return err
+			},
+		},
+	}
+
+	for _, v := range lookupTests {
+		err := v.lookup(testName)
+
+		if err == nil {
+			t.Errorf("Lookup%v: unexpected success", v.name)
+			continue
+		}
+
+		expectedErr := DNSError{Err: errNoSuchHost.Error(), Name: testName, IsNotFound: true}
+		var dnsErr *DNSError
+		errors.As(err, &dnsErr)
+		if dnsErr == nil || *dnsErr != expectedErr {
+			t.Errorf("Lookup%v: unexpected error: %v", v.name, err)
+		}
+	}
+}
diff --git a/src/net/dnsconfig.go b/src/net/dnsconfig.go
index 091b548..c86a70b 100644
--- a/src/net/dnsconfig.go
+++ b/src/net/dnsconfig.go
@@ -29,6 +29,8 @@
 	soffset       uint32        // used by serverOffset
 	singleRequest bool          // use sequential A and AAAA queries instead of parallel queries
 	useTCP        bool          // force usage of TCP for DNS resolutions
+	trustAD       bool          // add AD flag to queries
+	noReload      bool          // do not check for config file updates
 }
 
 // serverOffset returns an offset that can be used to determine
diff --git a/src/net/dnsconfig_unix.go b/src/net/dnsconfig_unix.go
index 94cd09e..8f6ae34 100644
--- a/src/net/dnsconfig_unix.go
+++ b/src/net/dnsconfig_unix.go
@@ -64,9 +64,13 @@
 			}
 
 		case "search": // set search path to given servers
-			conf.search = make([]string, len(f)-1)
-			for i := 0; i < len(conf.search); i++ {
-				conf.search[i] = ensureRooted(f[i+1])
+			conf.search = make([]string, 0, len(f)-1)
+			for i := 1; i < len(f); i++ {
+				name := ensureRooted(f[i])
+				if name == "." {
+					continue
+				}
+				conf.search = append(conf.search, name)
 			}
 
 		case "options": // magic options
@@ -109,6 +113,13 @@
 					// https://www.freebsd.org/cgi/man.cgi?query=resolv.conf&sektion=5&manpath=freebsd-release-ports
 					// https://man.openbsd.org/resolv.conf.5
 					conf.useTCP = true
+				case s == "trust-ad":
+					conf.trustAD = true
+				case s == "edns0":
+					// We use EDNS by default.
+					// Ignore this option.
+				case s == "no-reload":
+					conf.noReload = true
 				default:
 					conf.unknownOpt = true
 				}
diff --git a/src/net/dnsconfig_unix_test.go b/src/net/dnsconfig_unix_test.go
index 513f624..0aae2ba 100644
--- a/src/net/dnsconfig_unix_test.go
+++ b/src/net/dnsconfig_unix_test.go
@@ -53,6 +53,16 @@
 		},
 	},
 	{
+		name: "testdata/search-single-dot-resolv.conf",
+		want: &dnsConfig{
+			servers:  []string{"8.8.8.8:53"},
+			search:   []string{},
+			ndots:    1,
+			timeout:  5 * time.Second,
+			attempts: 2,
+		},
+	},
+	{
 		name: "testdata/empty-resolv.conf",
 		want: &dnsConfig{
 			servers:  defaultNS,
@@ -166,13 +176,17 @@
 	getHostname = func() (string, error) { return "host.domain.local", nil }
 
 	for _, tt := range dnsReadConfigTests {
+		want := *tt.want
+		if len(want.search) == 0 {
+			want.search = dnsDefaultSearch()
+		}
 		conf := dnsReadConfig(tt.name)
 		if conf.err != nil {
 			t.Fatal(conf.err)
 		}
 		conf.mtime = time.Time{}
-		if !reflect.DeepEqual(conf, tt.want) {
-			t.Errorf("%s:\ngot: %+v\nwant: %+v", tt.name, conf, tt.want)
+		if !reflect.DeepEqual(conf, &want) {
+			t.Errorf("%s:\ngot: %+v\nwant: %+v", tt.name, conf, want)
 		}
 	}
 }
@@ -259,8 +273,13 @@
 			t.Fatal(conf.err)
 		}
 
+		suffixList := tt.want.search
+		if len(suffixList) == 0 {
+			suffixList = dnsDefaultSearch()
+		}
+
 		var shortestSuffix int
-		for _, suffix := range tt.want.search {
+		for _, suffix := range suffixList {
 			if shortestSuffix == 0 || len(suffix) < shortestSuffix {
 				shortestSuffix = len(suffix)
 			}
diff --git a/src/net/fcntl_libc_test.go b/src/net/fcntl_libc_test.go
index 78892e3..5858865 100644
--- a/src/net/fcntl_libc_test.go
+++ b/src/net/fcntl_libc_test.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build aix || darwin || solaris
+//go:build aix || darwin || (openbsd && !mips64) || solaris
 
 package net
 
diff --git a/src/net/fcntl_syscall_test.go b/src/net/fcntl_syscall_test.go
index 2d1f7e2..b9ac1d3 100644
--- a/src/net/fcntl_syscall_test.go
+++ b/src/net/fcntl_syscall_test.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build dragonfly || freebsd || linux || netbsd || openbsd
+//go:build dragonfly || freebsd || linux || netbsd || (openbsd && mips64)
 
 package net
 
diff --git a/src/net/file_plan9.go b/src/net/file_plan9.go
index dfb23d2..64aabf9 100644
--- a/src/net/file_plan9.go
+++ b/src/net/file_plan9.go
@@ -100,7 +100,7 @@
 
 	switch fd.laddr.(type) {
 	case *TCPAddr:
-		return newTCPConn(fd), nil
+		return newTCPConn(fd, defaultTCPKeepAlive, testHookSetKeepAlive), nil
 	case *UDPAddr:
 		return newUDPConn(fd), nil
 	}
diff --git a/src/net/file_unix.go b/src/net/file_unix.go
index 0df67db..8b9fc38 100644
--- a/src/net/file_unix.go
+++ b/src/net/file_unix.go
@@ -74,7 +74,7 @@
 	}
 	switch fd.laddr.(type) {
 	case *TCPAddr:
-		return newTCPConn(fd), nil
+		return newTCPConn(fd, defaultTCPKeepAlive, testHookSetKeepAlive), nil
 	case *UDPAddr:
 		return newUDPConn(fd), nil
 	case *IPAddr:
diff --git a/src/net/hosts.go b/src/net/hosts.go
index e604031..dbf8fea 100644
--- a/src/net/hosts.go
+++ b/src/net/hosts.go
@@ -28,6 +28,11 @@
 	return ip.String() + "%" + zone
 }
 
+type byName struct {
+	addrs         []string
+	canonicalName string
+}
+
 // hosts contains known host entries.
 var hosts struct {
 	sync.Mutex
@@ -36,7 +41,7 @@
 	// name. It would be part of DNS labels, a FQDN or an absolute
 	// FQDN.
 	// For now the key is converted to lower case for convenience.
-	byName map[string][]string
+	byName map[string]byName
 
 	// Key for the list of host names must be a literal IP address
 	// including IPv6 address with zone identifier.
@@ -62,8 +67,9 @@
 		return
 	}
 
-	hs := make(map[string][]string)
+	hs := make(map[string]byName)
 	is := make(map[string][]string)
+
 	var file *file
 	if file, _ = open(hp); file == nil {
 		return
@@ -81,13 +87,32 @@
 		if addr == "" {
 			continue
 		}
+
+		var canonical string
 		for i := 1; i < len(f); i++ {
 			name := absDomainName(f[i])
 			h := []byte(f[i])
 			lowerASCIIBytes(h)
 			key := absDomainName(string(h))
-			hs[key] = append(hs[key], addr)
+
+			if i == 1 {
+				canonical = key
+			}
+
 			is[addr] = append(is[addr], name)
+
+			if v, ok := hs[key]; ok {
+				hs[key] = byName{
+					addrs:         append(v.addrs, addr),
+					canonicalName: v.canonicalName,
+				}
+				continue
+			}
+
+			hs[key] = byName{
+				addrs:         []string{addr},
+				canonicalName: canonical,
+			}
 		}
 	}
 	// Update the data cache.
@@ -100,8 +125,8 @@
 	file.close()
 }
 
-// lookupStaticHost looks up the addresses for the given host from /etc/hosts.
-func lookupStaticHost(host string) []string {
+// lookupStaticHost looks up the addresses and the canonical name for the given host from /etc/hosts.
+func lookupStaticHost(host string) ([]string, string) {
 	hosts.Lock()
 	defer hosts.Unlock()
 	readHosts()
@@ -111,13 +136,13 @@
 			lowerASCIIBytes(lowerHost)
 			host = string(lowerHost)
 		}
-		if ips, ok := hosts.byName[absDomainName(host)]; ok {
-			ipsCp := make([]string, len(ips))
-			copy(ipsCp, ips)
-			return ipsCp
+		if byName, ok := hosts.byName[absDomainName(host)]; ok {
+			ipsCp := make([]string, len(byName.addrs))
+			copy(ipsCp, byName.addrs)
+			return ipsCp, byName.canonicalName
 		}
 	}
-	return nil
+	return nil, ""
 }
 
 // lookupStaticAddr looks up the hosts for the given address from /etc/hosts.
diff --git a/src/net/hosts_test.go b/src/net/hosts_test.go
index 7291914..b3f189e 100644
--- a/src/net/hosts_test.go
+++ b/src/net/hosts_test.go
@@ -72,7 +72,7 @@
 func testStaticHost(t *testing.T, hostsPath string, ent staticHostEntry) {
 	ins := []string{ent.in, absDomainName(ent.in), strings.ToLower(ent.in), strings.ToUpper(ent.in)}
 	for _, in := range ins {
-		addrs := lookupStaticHost(in)
+		addrs, _ := lookupStaticHost(in)
 		if !reflect.DeepEqual(addrs, ent.out) {
 			t.Errorf("%s, lookupStaticHost(%s) = %v; want %v", hostsPath, in, addrs, ent.out)
 		}
@@ -157,7 +157,7 @@
 	ent := staticHostEntry{"localhost", []string{"127.0.0.1", "127.0.0.2", "127.0.0.3"}}
 	testStaticHost(t, testHookHostsPath, ent)
 	// Modify the addresses return by lookupStaticHost.
-	addrs := lookupStaticHost(ent.in)
+	addrs, _ := lookupStaticHost(ent.in)
 	for i := range addrs {
 		addrs[i] += "junk"
 	}
@@ -173,3 +173,42 @@
 	}
 	testStaticAddr(t, testHookHostsPath, ent)
 }
+
+var lookupStaticHostAliasesTest = []struct {
+	lookup, res string
+}{
+	// 127.0.0.1
+	{"test", "test"},
+	// 127.0.0.2
+	{"test2.example.com", "test2.example.com"},
+	{"2.test", "test2.example.com"},
+	// 127.0.0.3
+	{"test3.example.com", "3.test"},
+	{"3.test", "3.test"},
+	// 127.0.0.4
+	{"example.com", "example.com"},
+	// 127.0.0.5
+	{"test5.example.com", "test4.example.com"},
+	{"5.test", "test4.example.com"},
+	{"4.test", "test4.example.com"},
+	{"test4.example.com", "test4.example.com"},
+}
+
+func TestLookupStaticHostAliases(t *testing.T) {
+	defer func(orig string) { testHookHostsPath = orig }(testHookHostsPath)
+
+	testHookHostsPath = "testdata/aliases"
+	for _, ent := range lookupStaticHostAliasesTest {
+		testLookupStaticHostAliases(t, ent.lookup, absDomainName(ent.res))
+	}
+}
+
+func testLookupStaticHostAliases(t *testing.T, lookup, lookupRes string) {
+	ins := []string{lookup, absDomainName(lookup), strings.ToLower(lookup), strings.ToUpper(lookup)}
+	for _, in := range ins {
+		_, res := lookupStaticHost(in)
+		if res != lookupRes {
+			t.Errorf("lookupStaticHost(%v): got %v, want %v", in, res, lookupRes)
+		}
+	}
+}
diff --git a/src/net/http/cgi/child.go b/src/net/http/cgi/child.go
index bdb35a6..1411f0b 100644
--- a/src/net/http/cgi/child.go
+++ b/src/net/http/cgi/child.go
@@ -82,10 +82,12 @@
 
 	// Copy "HTTP_FOO_BAR" variables to "Foo-Bar" Headers
 	for k, v := range params {
-		if !strings.HasPrefix(k, "HTTP_") || k == "HTTP_HOST" {
+		if k == "HTTP_HOST" {
 			continue
 		}
-		r.Header.Add(strings.ReplaceAll(k[5:], "_", "-"), v)
+		if after, found := strings.CutPrefix(k, "HTTP_"); found {
+			r.Header.Add(strings.ReplaceAll(after, "_", "-"), v)
+		}
 	}
 
 	uriStr := params["REQUEST_URI"]
diff --git a/src/net/http/cgi/host.go b/src/net/http/cgi/host.go
index 0d43e14..349dda1 100644
--- a/src/net/http/cgi/host.go
+++ b/src/net/http/cgi/host.go
@@ -138,7 +138,6 @@
 
 	env := []string{
 		"SERVER_SOFTWARE=go",
-		"SERVER_NAME=" + req.Host,
 		"SERVER_PROTOCOL=HTTP/1.1",
 		"HTTP_HOST=" + req.Host,
 		"GATEWAY_INTERFACE=CGI/1.1",
@@ -158,6 +157,12 @@
 		env = append(env, "REMOTE_ADDR="+req.RemoteAddr, "REMOTE_HOST="+req.RemoteAddr)
 	}
 
+	if hostDomain, _, err := net.SplitHostPort(req.Host); err == nil {
+		env = append(env, "SERVER_NAME="+hostDomain)
+	} else {
+		env = append(env, "SERVER_NAME="+req.Host)
+	}
+
 	if req.TLS != nil {
 		env = append(env, "HTTPS=on")
 	}
diff --git a/src/net/http/cgi/host_test.go b/src/net/http/cgi/host_test.go
index f8abc88..860e9b3 100644
--- a/src/net/http/cgi/host_test.go
+++ b/src/net/http/cgi/host_test.go
@@ -8,7 +8,6 @@
 
 import (
 	"bufio"
-	"bytes"
 	"fmt"
 	"io"
 	"net"
@@ -114,7 +113,7 @@
 		"param-a":               "b",
 		"param-foo":             "bar",
 		"env-GATEWAY_INTERFACE": "CGI/1.1",
-		"env-HTTP_HOST":         "example.com",
+		"env-HTTP_HOST":         "example.com:80",
 		"env-PATH_INFO":         "",
 		"env-QUERY_STRING":      "foo=bar&a=b",
 		"env-REMOTE_ADDR":       "1.2.3.4",
@@ -128,7 +127,7 @@
 		"env-SERVER_PORT":       "80",
 		"env-SERVER_SOFTWARE":   "go",
 	}
-	replay := runCgiTest(t, h, "GET /test.cgi?foo=bar&a=b HTTP/1.0\nHost: example.com\n\n", expectedMap)
+	replay := runCgiTest(t, h, "GET /test.cgi?foo=bar&a=b HTTP/1.0\nHost: example.com:80\n\n", expectedMap)
 
 	if expected, got := "text/html", replay.Header().Get("Content-Type"); got != expected {
 		t.Errorf("got a Content-Type of %q; expected %q", got, expected)
@@ -540,7 +539,7 @@
 
 func TestHandlerStderr(t *testing.T) {
 	check(t)
-	var stderr bytes.Buffer
+	var stderr strings.Builder
 	h := &Handler{
 		Path:   "testdata/test.cgi",
 		Root:   "/test.cgi",
diff --git a/src/net/http/client.go b/src/net/http/client.go
index 992817c..122e8d0 100644
--- a/src/net/http/client.go
+++ b/src/net/http/client.go
@@ -23,6 +23,7 @@
 	"sort"
 	"strings"
 	"sync"
+	"sync/atomic"
 	"time"
 )
 
@@ -361,7 +362,7 @@
 	initialReqCancel := req.Cancel // the user's original Request.Cancel, if any
 
 	var cancelCtx func()
-	if oldCtx := req.Context(); timeBeforeContextDeadline(deadline, oldCtx) {
+	if timeBeforeContextDeadline(deadline, oldCtx) {
 		req.ctx, cancelCtx = context.WithDeadline(oldCtx, deadline)
 	}
 
@@ -391,7 +392,7 @@
 	}
 
 	timer := time.NewTimer(time.Until(deadline))
-	var timedOut atomicBool
+	var timedOut atomic.Bool
 
 	go func() {
 		select {
@@ -399,14 +400,14 @@
 			doCancel()
 			timer.Stop()
 		case <-timer.C:
-			timedOut.setTrue()
+			timedOut.Store(true)
 			doCancel()
 		case <-stopTimerCh:
 			timer.Stop()
 		}
 	}()
 
-	return stopTimer, timedOut.isSet
+	return stopTimer, timedOut.Load
 }
 
 // See 2 (end of page 4) https://www.ietf.org/rfc/rfc2617.txt
@@ -498,7 +499,7 @@
 }
 
 // redirectBehavior describes what should happen when the
-// client encounters a 3xx status code from the server
+// client encounters a 3xx status code from the server.
 func redirectBehavior(reqMethod string, resp *Response, ireq *Request) (redirectMethod string, shouldRedirect, includeBody bool) {
 	switch resp.StatusCode {
 	case 301, 302, 303:
diff --git a/src/net/http/client_test.go b/src/net/http/client_test.go
index 5e5bf8f..8b53c41 100644
--- a/src/net/http/client_test.go
+++ b/src/net/http/client_test.go
@@ -67,11 +67,9 @@
 	return len(p), nil
 }
 
-func TestClient(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
-	ts := httptest.NewServer(robotsTxtHandler)
-	defer ts.Close()
+func TestClient(t *testing.T) { run(t, testClient) }
+func testClient(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, robotsTxtHandler).ts
 
 	c := ts.Client()
 	r, err := c.Get(ts.URL)
@@ -87,14 +85,9 @@
 	}
 }
 
-func TestClientHead_h1(t *testing.T) { testClientHead(t, h1Mode) }
-func TestClientHead_h2(t *testing.T) { testClientHead(t, h2Mode) }
-
-func testClientHead(t *testing.T, h2 bool) {
-	defer afterTest(t)
-	cst := newClientServerTest(t, h2, robotsTxtHandler)
-	defer cst.close()
-
+func TestClientHead(t *testing.T) { run(t, testClientHead) }
+func testClientHead(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, robotsTxtHandler)
 	r, err := cst.c.Head(cst.ts.URL)
 	if err != nil {
 		t.Fatal(err)
@@ -200,11 +193,10 @@
 	}
 }
 
-func TestClientRedirects(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
+func TestClientRedirects(t *testing.T) { run(t, testClientRedirects) }
+func testClientRedirects(t *testing.T, mode testMode) {
 	var ts *httptest.Server
-	ts = httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts = newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		n, _ := strconv.Atoi(r.FormValue("n"))
 		// Test Referer header. (7 is arbitrary position to test at)
 		if n == 7 {
@@ -217,8 +209,7 @@
 			return
 		}
 		fmt.Fprintf(w, "n=%d", n)
-	}))
-	defer ts.Close()
+	})).ts
 
 	c := ts.Client()
 	_, err := c.Get(ts.URL)
@@ -299,13 +290,11 @@
 }
 
 // Tests that Client redirects' contexts are derived from the original request's context.
-func TestClientRedirectContext(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestClientRedirectsContext(t *testing.T) { run(t, testClientRedirectsContext) }
+func testClientRedirectsContext(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		Redirect(w, r, "/", StatusTemporaryRedirect)
-	}))
-	defer ts.Close()
+	})).ts
 
 	ctx, cancel := context.WithCancel(context.Background())
 	c := ts.Client()
@@ -373,7 +362,9 @@
 		`POST /?code=404 "c404"`,
 	}
 	want := strings.Join(wantSegments, "\n")
-	testRedirectsByMethod(t, "POST", postRedirectTests, want)
+	run(t, func(t *testing.T, mode testMode) {
+		testRedirectsByMethod(t, mode, "POST", postRedirectTests, want)
+	})
 }
 
 func TestDeleteRedirects(t *testing.T) {
@@ -410,17 +401,18 @@
 		`DELETE /?code=404 "c404"`,
 	}
 	want := strings.Join(wantSegments, "\n")
-	testRedirectsByMethod(t, "DELETE", deleteRedirectTests, want)
+	run(t, func(t *testing.T, mode testMode) {
+		testRedirectsByMethod(t, mode, "DELETE", deleteRedirectTests, want)
+	})
 }
 
-func testRedirectsByMethod(t *testing.T, method string, table []redirectTest, want string) {
-	defer afterTest(t)
+func testRedirectsByMethod(t *testing.T, mode testMode, method string, table []redirectTest, want string) {
 	var log struct {
 		sync.Mutex
 		bytes.Buffer
 	}
 	var ts *httptest.Server
-	ts = httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts = newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		log.Lock()
 		slurp, _ := io.ReadAll(r.Body)
 		fmt.Fprintf(&log.Buffer, "%s %s %q", r.Method, r.RequestURI, slurp)
@@ -445,8 +437,7 @@
 			}
 			w.WriteHeader(code)
 		}
-	}))
-	defer ts.Close()
+	})).ts
 
 	c := ts.Client()
 	for _, tt := range table {
@@ -491,12 +482,11 @@
 	}
 }
 
-func TestClientRedirectUseResponse(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
+func TestClientRedirectUseResponse(t *testing.T) { run(t, testClientRedirectUseResponse) }
+func testClientRedirectUseResponse(t *testing.T, mode testMode) {
 	const body = "Hello, world."
 	var ts *httptest.Server
-	ts = httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts = newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		if strings.Contains(r.URL.Path, "/other") {
 			io.WriteString(w, "wrong body")
 		} else {
@@ -504,8 +494,7 @@
 			w.WriteHeader(StatusFound)
 			io.WriteString(w, body)
 		}
-	}))
-	defer ts.Close()
+	})).ts
 
 	c := ts.Client()
 	c.CheckRedirect = func(req *Request, via []*Request) error {
@@ -533,18 +522,16 @@
 
 // Issues 17773 and 49281: don't follow a 3xx if the response doesn't
 // have a Location header.
-func TestClientRedirectNoLocation(t *testing.T) {
+func TestClientRedirectNoLocation(t *testing.T) { run(t, testClientRedirectNoLocation) }
+func testClientRedirectNoLocation(t *testing.T, mode testMode) {
 	for _, code := range []int{301, 308} {
 		t.Run(fmt.Sprint(code), func(t *testing.T) {
 			setParallel(t)
-			defer afterTest(t)
-			ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+			cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 				w.Header().Set("Foo", "Bar")
 				w.WriteHeader(code)
 			}))
-			defer ts.Close()
-			c := ts.Client()
-			res, err := c.Get(ts.URL)
+			res, err := cst.c.Get(cst.ts.URL)
 			if err != nil {
 				t.Fatal(err)
 			}
@@ -560,15 +547,13 @@
 }
 
 // Don't follow a 307/308 if we can't resent the request body.
-func TestClientRedirect308NoGetBody(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
+func TestClientRedirect308NoGetBody(t *testing.T) { run(t, testClientRedirect308NoGetBody) }
+func testClientRedirect308NoGetBody(t *testing.T, mode testMode) {
 	const fakeURL = "https://localhost:1234/" // won't be hit
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		w.Header().Set("Location", fakeURL)
 		w.WriteHeader(308)
-	}))
-	defer ts.Close()
+	})).ts
 	req, err := NewRequest("POST", ts.URL, strings.NewReader("some body"))
 	if err != nil {
 		t.Fatal(err)
@@ -659,12 +644,10 @@
 	return j.perURL[u.Host]
 }
 
-func TestRedirectCookiesJar(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
+func TestRedirectCookiesJar(t *testing.T) { run(t, testRedirectCookiesJar) }
+func testRedirectCookiesJar(t *testing.T, mode testMode) {
 	var ts *httptest.Server
-	ts = httptest.NewServer(echoCookiesRedirectHandler)
-	defer ts.Close()
+	ts = newClientServerTest(t, mode, echoCookiesRedirectHandler).ts
 	c := ts.Client()
 	c.Jar = new(TestJar)
 	u, _ := url.Parse(ts.URL)
@@ -696,9 +679,9 @@
 	}
 }
 
-func TestJarCalls(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestJarCalls(t *testing.T) { run(t, testJarCalls, []testMode{http1Mode}) }
+func testJarCalls(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		pathSuffix := r.RequestURI[1:]
 		if r.RequestURI == "/nosetcookie" {
 			return // don't set cookies for this path
@@ -707,8 +690,7 @@
 		if r.RequestURI == "/" {
 			Redirect(w, r, "http://secondhost.fake/secondpath", 302)
 		}
-	}))
-	defer ts.Close()
+	})).ts
 	jar := new(RecordingJar)
 	c := ts.Client()
 	c.Jar = jar
@@ -757,20 +739,16 @@
 	fmt.Fprintf(&j.log, format, args...)
 }
 
-func TestStreamingGet_h1(t *testing.T) { testStreamingGet(t, h1Mode) }
-func TestStreamingGet_h2(t *testing.T) { testStreamingGet(t, h2Mode) }
-
-func testStreamingGet(t *testing.T, h2 bool) {
-	defer afterTest(t)
+func TestStreamingGet(t *testing.T) { run(t, testStreamingGet) }
+func testStreamingGet(t *testing.T, mode testMode) {
 	say := make(chan string)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		w.(Flusher).Flush()
 		for str := range say {
 			w.Write([]byte(str))
 			w.(Flusher).Flush()
 		}
 	}))
-	defer cst.close()
 
 	c := cst.c
 	res, err := c.Get(cst.ts.URL)
@@ -811,11 +789,10 @@
 
 // TestClientWrites verifies that client requests are buffered and we
 // don't send a TCP packet per line of the http request + body.
-func TestClientWrites(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-	}))
-	defer ts.Close()
+func TestClientWrites(t *testing.T) { run(t, testClientWrites, []testMode{http1Mode}) }
+func testClientWrites(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
+	})).ts
 
 	writes := 0
 	dialer := func(netz string, addr string) (net.Conn, error) {
@@ -847,11 +824,12 @@
 }
 
 func TestClientInsecureTransport(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
-	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	run(t, testClientInsecureTransport, []testMode{https1Mode, http2Mode})
+}
+func testClientInsecureTransport(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		w.Write([]byte("Hello"))
-	}))
+	})).ts
 	errc := make(chanWriter, 10) // but only expecting 1
 	ts.Config.ErrorLog = log.New(errc, "", 0)
 	defer ts.Close()
@@ -898,15 +876,15 @@
 }
 
 func TestClientWithCorrectTLSServerName(t *testing.T) {
-	defer afterTest(t)
-
+	run(t, testClientWithCorrectTLSServerName, []testMode{https1Mode, http2Mode})
+}
+func testClientWithCorrectTLSServerName(t *testing.T, mode testMode) {
 	const serverName = "example.com"
-	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		if r.TLS.ServerName != serverName {
 			t.Errorf("expected client to set ServerName %q, got: %q", serverName, r.TLS.ServerName)
 		}
-	}))
-	defer ts.Close()
+	})).ts
 
 	c := ts.Client()
 	c.Transport.(*Transport).TLSClientConfig.ServerName = serverName
@@ -916,9 +894,10 @@
 }
 
 func TestClientWithIncorrectTLSServerName(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
-	defer ts.Close()
+	run(t, testClientWithIncorrectTLSServerName, []testMode{https1Mode, http2Mode})
+}
+func testClientWithIncorrectTLSServerName(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {})).ts
 	errc := make(chanWriter, 10) // but only expecting 1
 	ts.Config.ErrorLog = log.New(errc, "", 0)
 
@@ -951,11 +930,12 @@
 //
 // The httptest.Server has a cert with "example.com" as its name.
 func TestTransportUsesTLSConfigServerName(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	run(t, testTransportUsesTLSConfigServerName, []testMode{https1Mode, http2Mode})
+}
+func testTransportUsesTLSConfigServerName(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		w.Write([]byte("Hello"))
-	}))
-	defer ts.Close()
+	})).ts
 
 	c := ts.Client()
 	tr := c.Transport.(*Transport)
@@ -971,11 +951,12 @@
 }
 
 func TestResponseSetsTLSConnectionState(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	run(t, testResponseSetsTLSConnectionState, []testMode{https1Mode})
+}
+func testResponseSetsTLSConnectionState(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		w.Write([]byte("Hello"))
-	}))
-	defer ts.Close()
+	})).ts
 
 	c := ts.Client()
 	tr := c.Transport.(*Transport)
@@ -1001,10 +982,11 @@
 // to determine that the server is speaking HTTP.
 // See golang.org/issue/11111.
 func TestHTTPSClientDetectsHTTPServer(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
+	run(t, testHTTPSClientDetectsHTTPServer, []testMode{http1Mode})
+}
+func testHTTPSClientDetectsHTTPServer(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {})).ts
 	ts.Config.ErrorLog = quietLog
-	defer ts.Close()
 
 	_, err := Get(strings.Replace(ts.URL, "http", "https", 1))
 	if got := err.Error(); !strings.Contains(got, "HTTP response to HTTPS client") {
@@ -1013,22 +995,13 @@
 }
 
 // Verify Response.ContentLength is populated. https://golang.org/issue/4126
-func TestClientHeadContentLength_h1(t *testing.T) {
-	testClientHeadContentLength(t, h1Mode)
-}
-
-func TestClientHeadContentLength_h2(t *testing.T) {
-	testClientHeadContentLength(t, h2Mode)
-}
-
-func testClientHeadContentLength(t *testing.T, h2 bool) {
-	defer afterTest(t)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestClientHeadContentLength(t *testing.T) { run(t, testClientHeadContentLength) }
+func testClientHeadContentLength(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		if v := r.FormValue("cl"); v != "" {
 			w.Header().Set("Content-Length", v)
 		}
 	}))
-	defer cst.close()
 	tests := []struct {
 		suffix string
 		want   int64
@@ -1056,11 +1029,10 @@
 	}
 }
 
-func TestEmptyPasswordAuth(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
+func TestEmptyPasswordAuth(t *testing.T) { run(t, testEmptyPasswordAuth) }
+func testEmptyPasswordAuth(t *testing.T, mode testMode) {
 	gopher := "gopher"
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		auth := r.Header.Get("Authorization")
 		if strings.HasPrefix(auth, "Basic ") {
 			encoded := auth[6:]
@@ -1076,7 +1048,7 @@
 		} else {
 			t.Errorf("Invalid auth %q", auth)
 		}
-	}))
+	})).ts
 	defer ts.Close()
 	req, err := NewRequest("GET", ts.URL, nil)
 	if err != nil {
@@ -1205,19 +1177,14 @@
 	}
 }
 
-func TestClientTimeout_h1(t *testing.T) { testClientTimeout(t, h1Mode) }
-func TestClientTimeout_h2(t *testing.T) { testClientTimeout(t, h2Mode) }
-
-func testClientTimeout(t *testing.T, h2 bool) {
-	setParallel(t)
-	defer afterTest(t)
-
+func TestClientTimeout(t *testing.T) { run(t, testClientTimeout) }
+func testClientTimeout(t *testing.T, mode testMode) {
 	var (
 		mu           sync.Mutex
 		nonce        string // a unique per-request string
 		sawSlowNonce bool   // true if the handler saw /slow?nonce=<nonce>
 	)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		_ = r.ParseForm()
 		if r.URL.Path == "/" {
 			Redirect(w, r, "/slow?nonce="+r.Form.Get("nonce"), StatusFound)
@@ -1238,7 +1205,6 @@
 			return
 		}
 	}))
-	defer cst.close()
 
 	// Try to trigger a timeout after reading part of the response body.
 	// The initial timeout is emprically usually long enough on a decently fast
@@ -1272,6 +1238,9 @@
 				t.Logf("timeout before response received")
 				continue
 			}
+			if runtime.GOOS == "windows" && strings.HasPrefix(runtime.GOARCH, "arm") {
+				testenv.SkipFlaky(t, 43120)
+			}
 			t.Fatal(err)
 		}
 
@@ -1305,18 +1274,13 @@
 	}
 }
 
-func TestClientTimeout_Headers_h1(t *testing.T) { testClientTimeout_Headers(t, h1Mode) }
-func TestClientTimeout_Headers_h2(t *testing.T) { testClientTimeout_Headers(t, h2Mode) }
-
 // Client.Timeout firing before getting to the body
-func testClientTimeout_Headers(t *testing.T, h2 bool) {
-	setParallel(t)
-	defer afterTest(t)
+func TestClientTimeout_Headers(t *testing.T) { run(t, testClientTimeout_Headers) }
+func testClientTimeout_Headers(t *testing.T, mode testMode) {
 	donec := make(chan bool, 1)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		<-donec
 	}), optQuietLog)
-	defer cst.close()
 	// Note that we use a channel send here and not a close.
 	// The race detector doesn't know that we're waiting for a timeout
 	// and thinks that the waitgroup inside httptest.Server is added to concurrently
@@ -1352,18 +1316,15 @@
 
 // Issue 16094: if Client.Timeout is set but not hit, a Timeout error shouldn't be
 // returned.
-func TestClientTimeoutCancel(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
-
+func TestClientTimeoutCancel(t *testing.T) { run(t, testClientTimeoutCancel) }
+func testClientTimeoutCancel(t *testing.T, mode testMode) {
 	testDone := make(chan struct{})
 	ctx, cancel := context.WithCancel(context.Background())
 
-	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		w.(Flusher).Flush()
 		<-testDone
 	}))
-	defer cst.close()
 	defer close(testDone)
 
 	cst.c.Timeout = 1 * time.Hour
@@ -1380,18 +1341,12 @@
 	}
 }
 
-func TestClientTimeoutDoesNotExpire_h1(t *testing.T) { testClientTimeoutDoesNotExpire(t, h1Mode) }
-func TestClientTimeoutDoesNotExpire_h2(t *testing.T) { testClientTimeoutDoesNotExpire(t, h2Mode) }
-
 // Issue 49366: if Client.Timeout is set but not hit, no error should be returned.
-func testClientTimeoutDoesNotExpire(t *testing.T, h2 bool) {
-	setParallel(t)
-	defer afterTest(t)
-
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestClientTimeoutDoesNotExpire(t *testing.T) { run(t, testClientTimeoutDoesNotExpire) }
+func testClientTimeoutDoesNotExpire(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		w.Write([]byte("body"))
 	}))
-	defer cst.close()
 
 	cst.c.Timeout = 1 * time.Hour
 	req, _ := NewRequest("GET", cst.ts.URL, nil)
@@ -1407,19 +1362,15 @@
 	}
 }
 
-func TestClientRedirectEatsBody_h1(t *testing.T) { testClientRedirectEatsBody(t, h1Mode) }
-func TestClientRedirectEatsBody_h2(t *testing.T) { testClientRedirectEatsBody(t, h2Mode) }
-func testClientRedirectEatsBody(t *testing.T, h2 bool) {
-	setParallel(t)
-	defer afterTest(t)
+func TestClientRedirectEatsBody_h1(t *testing.T) { run(t, testClientRedirectEatsBody) }
+func testClientRedirectEatsBody(t *testing.T, mode testMode) {
 	saw := make(chan string, 2)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		saw <- r.RemoteAddr
 		if r.URL.Path == "/" {
 			Redirect(w, r, "/foo", StatusFound) // which includes a body
 		}
 	}))
-	defer cst.close()
 
 	res, err := cst.c.Get(cst.ts.URL)
 	if err != nil {
@@ -1519,13 +1470,14 @@
 }
 
 // Issue 4800: copy (some) headers when Client follows a redirect.
-func TestClientCopyHeadersOnRedirect(t *testing.T) {
+func TestClientCopyHeadersOnRedirect(t *testing.T) { run(t, testClientCopyHeadersOnRedirect) }
+func testClientCopyHeadersOnRedirect(t *testing.T, mode testMode) {
 	const (
 		ua   = "some-agent/1.2"
 		xfoo = "foo-val"
 	)
 	var ts2URL string
-	ts1 := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts1 := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		want := Header{
 			"User-Agent":      []string{ua},
 			"X-Foo":           []string{xfoo},
@@ -1540,12 +1492,10 @@
 		} else {
 			w.Header().Set("Result", "ok")
 		}
-	}))
-	defer ts1.Close()
-	ts2 := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	})).ts
+	ts2 := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		Redirect(w, r, ts1.URL, StatusFound)
-	}))
-	defer ts2.Close()
+	})).ts
 	ts2URL = ts2.URL
 
 	c := ts1.Client()
@@ -1580,22 +1530,24 @@
 }
 
 // Issue 22233: copy host when Client follows a relative redirect.
-func TestClientCopyHostOnRedirect(t *testing.T) {
+func TestClientCopyHostOnRedirect(t *testing.T) { run(t, testClientCopyHostOnRedirect) }
+func testClientCopyHostOnRedirect(t *testing.T, mode testMode) {
 	// Virtual hostname: should not receive any request.
-	virtual := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	virtual := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		t.Errorf("Virtual host received request %v", r.URL)
 		w.WriteHeader(403)
 		io.WriteString(w, "should not see this response")
-	}))
+	})).ts
 	defer virtual.Close()
 	virtualHost := strings.TrimPrefix(virtual.URL, "http://")
+	virtualHost = strings.TrimPrefix(virtualHost, "https://")
 	t.Logf("Virtual host is %v", virtualHost)
 
 	// Actual hostname: should not receive any request.
 	const wantBody = "response body"
 	var tsURL string
 	var tsHost string
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		switch r.URL.Path {
 		case "/":
 			// Relative redirect.
@@ -1627,10 +1579,10 @@
 			t.Errorf("Serving unexpected path %q", r.URL.Path)
 			w.WriteHeader(404)
 		}
-	}))
-	defer ts.Close()
+	})).ts
 	tsURL = ts.URL
 	tsHost = strings.TrimPrefix(ts.URL, "http://")
+	tsHost = strings.TrimPrefix(tsHost, "https://")
 	t.Logf("Server host is %v", tsHost)
 
 	c := ts.Client()
@@ -1650,7 +1602,8 @@
 }
 
 // Issue 17494: cookies should be altered when Client follows redirects.
-func TestClientAltersCookiesOnRedirect(t *testing.T) {
+func TestClientAltersCookiesOnRedirect(t *testing.T) { run(t, testClientAltersCookiesOnRedirect) }
+func testClientAltersCookiesOnRedirect(t *testing.T, mode testMode) {
 	cookieMap := func(cs []*Cookie) map[string][]string {
 		m := make(map[string][]string)
 		for _, c := range cs {
@@ -1659,7 +1612,7 @@
 		return m
 	}
 
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		var want map[string][]string
 		got := cookieMap(r.Cookies())
 
@@ -1714,8 +1667,7 @@
 		if !reflect.DeepEqual(got, want) {
 			t.Errorf("redirect %s, Cookie = %v, want %v", c.Value, got, want)
 		}
-	}))
-	defer ts.Close()
+	})).ts
 
 	jar, _ := cookiejar.New(nil)
 	c := ts.Client()
@@ -1787,10 +1739,8 @@
 	}
 }
 
-func TestClientRedirectTypes(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
-
+func TestClientRedirectTypes(t *testing.T) { run(t, testClientRedirectTypes) }
+func testClientRedirectTypes(t *testing.T, mode testMode) {
 	tests := [...]struct {
 		method       string
 		serverStatus int
@@ -1835,11 +1785,10 @@
 
 	handlerc := make(chan HandlerFunc, 1)
 
-	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(rw ResponseWriter, req *Request) {
 		h := <-handlerc
 		h(rw, req)
-	}))
-	defer ts.Close()
+	})).ts
 
 	c := ts.Client()
 	for i, tt := range tests {
@@ -1895,18 +1844,16 @@
 
 // Issue 18239: make sure the Transport doesn't retry requests with bodies
 // if Request.GetBody is not defined.
-func TestTransportBodyReadError(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestTransportBodyReadError(t *testing.T) { run(t, testTransportBodyReadError) }
+func testTransportBodyReadError(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		if r.URL.Path == "/ping" {
 			return
 		}
 		buf := make([]byte, 1)
 		n, err := r.Body.Read(buf)
 		w.Header().Set("X-Body-Read", fmt.Sprintf("%v, %v", n, err))
-	}))
-	defer ts.Close()
+	})).ts
 	c := ts.Client()
 	tr := c.Transport.(*Transport)
 
@@ -1990,22 +1937,13 @@
 	c.Get("https://example.tld/")
 }
 
-func TestClientDoCanceledVsTimeout_h1(t *testing.T) {
-	testClientDoCanceledVsTimeout(t, h1Mode)
-}
-
-func TestClientDoCanceledVsTimeout_h2(t *testing.T) {
-	testClientDoCanceledVsTimeout(t, h2Mode)
-}
-
 // Issue 33545: lock-in the behavior promised by Client.Do's
 // docs about request cancellation vs timing out.
-func testClientDoCanceledVsTimeout(t *testing.T, h2 bool) {
-	defer afterTest(t)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestClientDoCanceledVsTimeout(t *testing.T) { run(t, testClientDoCanceledVsTimeout) }
+func testClientDoCanceledVsTimeout(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		w.Write([]byte("Hello, World!"))
 	}))
-	defer cst.close()
 
 	cases := []string{"timeout", "canceled"}
 
@@ -2081,13 +2019,11 @@
 }
 
 // Issue 40382: Client calls Close multiple times on Request.Body.
-func TestClientCallsCloseOnlyOnce(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
-	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestClientCallsCloseOnlyOnce(t *testing.T) { run(t, testClientCallsCloseOnlyOnce) }
+func testClientCallsCloseOnlyOnce(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		w.WriteHeader(StatusNoContent)
 	}))
-	defer cst.close()
 
 	// Issue occurred non-deterministically: needed to occur after a successful
 	// write (into TCP buffer) but before end of body.
@@ -2137,17 +2073,15 @@
 	return nil
 }
 
-func TestProbeZeroLengthBody(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
+func TestProbeZeroLengthBody(t *testing.T) { run(t, testProbeZeroLengthBody) }
+func testProbeZeroLengthBody(t *testing.T, mode testMode) {
 	reqc := make(chan struct{})
-	cst := newClientServerTest(t, false, HandlerFunc(func(w ResponseWriter, r *Request) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		close(reqc)
 		if _, err := io.Copy(w, r.Body); err != nil {
 			t.Errorf("error copying request body: %v", err)
 		}
 	}))
-	defer cst.close()
 
 	bodyr, bodyw := io.Pipe()
 	var gotBody string
diff --git a/src/net/http/clientserver_test.go b/src/net/http/clientserver_test.go
index b472ca4..da5671d 100644
--- a/src/net/http/clientserver_test.go
+++ b/src/net/http/clientserver_test.go
@@ -35,8 +35,65 @@
 	"time"
 )
 
+type testMode string
+
+const (
+	http1Mode  = testMode("h1")     // HTTP/1.1
+	https1Mode = testMode("https1") // HTTPS/1.1
+	http2Mode  = testMode("h2")     // HTTP/2
+)
+
+type testNotParallelOpt struct{}
+
+var (
+	testNotParallel = testNotParallelOpt{}
+)
+
+type TBRun[T any] interface {
+	testing.TB
+	Run(string, func(T)) bool
+}
+
+// run runs a client/server test in a variety of test configurations.
+//
+// Tests execute in HTTP/1.1 and HTTP/2 modes by default.
+// To run in a different set of configurations, pass a []testMode option.
+//
+// Tests call t.Parallel() by default.
+// To disable parallel execution, pass the testNotParallel option.
+func run[T TBRun[T]](t T, f func(t T, mode testMode), opts ...any) {
+	t.Helper()
+	modes := []testMode{http1Mode, http2Mode}
+	parallel := true
+	for _, opt := range opts {
+		switch opt := opt.(type) {
+		case []testMode:
+			modes = opt
+		case testNotParallelOpt:
+			parallel = false
+		default:
+			t.Fatalf("unknown option type %T", opt)
+		}
+	}
+	if t, ok := any(t).(*testing.T); ok && parallel {
+		setParallel(t)
+	}
+	for _, mode := range modes {
+		t.Run(string(mode), func(t T) {
+			t.Helper()
+			if t, ok := any(t).(*testing.T); ok && parallel {
+				setParallel(t)
+			}
+			t.Cleanup(func() {
+				afterTest(t)
+			})
+			f(t, mode)
+		})
+	}
+}
+
 type clientServerTest struct {
-	t  *testing.T
+	t  testing.TB
 	h2 bool
 	h  Handler
 	ts *httptest.Server
@@ -69,11 +126,6 @@
 	return "http"
 }
 
-const (
-	h1Mode = false
-	h2Mode = true
-)
-
 var optQuietLog = func(ts *httptest.Server) {
 	ts.Config.ErrorLog = quietLog
 }
@@ -84,23 +136,33 @@
 	}
 }
 
-func newClientServerTest(t *testing.T, h2 bool, h Handler, opts ...any) *clientServerTest {
-	if h2 {
+// newClientServerTest creates and starts an httptest.Server.
+//
+// The mode parameter selects the implementation to test:
+// HTTP/1, HTTP/2, etc. Tests using newClientServerTest should use
+// the 'run' function, which will start a subtests for each tested mode.
+//
+// The vararg opts parameter can include functions to configure the
+// test server or transport.
+//
+//	func(*httptest.Server) // run before starting the server
+//	func(*http.Transport)
+func newClientServerTest(t testing.TB, mode testMode, h Handler, opts ...any) *clientServerTest {
+	if mode == http2Mode {
 		CondSkipHTTP2(t)
 	}
 	cst := &clientServerTest{
 		t:  t,
-		h2: h2,
+		h2: mode == http2Mode,
 		h:  h,
-		tr: &Transport{},
 	}
-	cst.c = &Client{Transport: cst.tr}
 	cst.ts = httptest.NewUnstartedServer(h)
 
+	var transportFuncs []func(*Transport)
 	for _, opt := range opts {
 		switch opt := opt.(type) {
 		case func(*Transport):
-			opt(cst.tr)
+			transportFuncs = append(transportFuncs, opt)
 		case func(*httptest.Server):
 			opt(cst.ts)
 		default:
@@ -108,60 +170,97 @@
 		}
 	}
 
-	if !h2 {
-		cst.ts.Start()
-		return cst
+	if cst.ts.Config.ErrorLog == nil {
+		cst.ts.Config.ErrorLog = log.New(testLogWriter{t}, "", 0)
 	}
-	ExportHttp2ConfigureServer(cst.ts.Config, nil)
-	cst.ts.TLS = cst.ts.Config.TLSConfig
-	cst.ts.StartTLS()
 
-	cst.tr.TLSClientConfig = &tls.Config{
-		InsecureSkipVerify: true,
+	switch mode {
+	case http1Mode:
+		cst.ts.Start()
+	case https1Mode:
+		cst.ts.StartTLS()
+	case http2Mode:
+		ExportHttp2ConfigureServer(cst.ts.Config, nil)
+		cst.ts.TLS = cst.ts.Config.TLSConfig
+		cst.ts.StartTLS()
+	default:
+		t.Fatalf("unknown test mode %v", mode)
 	}
-	if err := ExportHttp2ConfigureTransport(cst.tr); err != nil {
-		t.Fatal(err)
+	cst.c = cst.ts.Client()
+	cst.tr = cst.c.Transport.(*Transport)
+	if mode == http2Mode {
+		if err := ExportHttp2ConfigureTransport(cst.tr); err != nil {
+			t.Fatal(err)
+		}
 	}
+	for _, f := range transportFuncs {
+		f(cst.tr)
+	}
+	t.Cleanup(func() {
+		cst.close()
+	})
 	return cst
 }
 
+type testLogWriter struct {
+	t testing.TB
+}
+
+func (w testLogWriter) Write(b []byte) (int, error) {
+	w.t.Logf("server log: %v", strings.TrimSpace(string(b)))
+	return len(b), nil
+}
+
 // Testing the newClientServerTest helper itself.
 func TestNewClientServerTest(t *testing.T) {
+	run(t, testNewClientServerTest, []testMode{http1Mode, https1Mode, http2Mode})
+}
+func testNewClientServerTest(t *testing.T, mode testMode) {
 	var got struct {
 		sync.Mutex
-		log []string
+		proto  string
+		hasTLS bool
 	}
 	h := HandlerFunc(func(w ResponseWriter, r *Request) {
 		got.Lock()
 		defer got.Unlock()
-		got.log = append(got.log, r.Proto)
+		got.proto = r.Proto
+		got.hasTLS = r.TLS != nil
 	})
-	for _, v := range [2]bool{false, true} {
-		cst := newClientServerTest(t, v, h)
-		if _, err := cst.c.Head(cst.ts.URL); err != nil {
-			t.Fatal(err)
-		}
-		cst.close()
+	cst := newClientServerTest(t, mode, h)
+	if _, err := cst.c.Head(cst.ts.URL); err != nil {
+		t.Fatal(err)
 	}
-	got.Lock() // no need to unlock
-	if want := []string{"HTTP/1.1", "HTTP/2.0"}; !reflect.DeepEqual(got.log, want) {
-		t.Errorf("got %q; want %q", got.log, want)
+	var wantProto string
+	var wantTLS bool
+	switch mode {
+	case http1Mode:
+		wantProto = "HTTP/1.1"
+		wantTLS = false
+	case https1Mode:
+		wantProto = "HTTP/1.1"
+		wantTLS = true
+	case http2Mode:
+		wantProto = "HTTP/2.0"
+		wantTLS = true
+	}
+	if got.proto != wantProto {
+		t.Errorf("req.Proto = %q, want %q", got.proto, wantProto)
+	}
+	if got.hasTLS != wantTLS {
+		t.Errorf("req.TLS set: %v, want %v", got.hasTLS, wantTLS)
 	}
 }
 
-func TestChunkedResponseHeaders_h1(t *testing.T) { testChunkedResponseHeaders(t, h1Mode) }
-func TestChunkedResponseHeaders_h2(t *testing.T) { testChunkedResponseHeaders(t, h2Mode) }
-
-func testChunkedResponseHeaders(t *testing.T, h2 bool) {
-	defer afterTest(t)
+func TestChunkedResponseHeaders(t *testing.T) { run(t, testChunkedResponseHeaders) }
+func testChunkedResponseHeaders(t *testing.T, mode testMode) {
 	log.SetOutput(io.Discard) // is noisy otherwise
 	defer log.SetOutput(os.Stderr)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		w.Header().Set("Content-Length", "intentional gibberish") // we check that this is deleted
 		w.(Flusher).Flush()
 		fmt.Fprintf(w, "I am a chunked response.")
 	}))
-	defer cst.close()
 
 	res, err := cst.c.Get(cst.ts.URL)
 	if err != nil {
@@ -172,7 +271,7 @@
 		t.Errorf("expected ContentLength of %d; got %d", e, g)
 	}
 	wantTE := []string{"chunked"}
-	if h2 {
+	if mode == http2Mode {
 		wantTE = nil
 	}
 	if !reflect.DeepEqual(res.TransferEncoding, wantTE) {
@@ -204,9 +303,9 @@
 
 func (tt h12Compare) run(t *testing.T) {
 	setParallel(t)
-	cst1 := newClientServerTest(t, false, HandlerFunc(tt.Handler), tt.Opts...)
+	cst1 := newClientServerTest(t, http1Mode, HandlerFunc(tt.Handler), tt.Opts...)
 	defer cst1.close()
-	cst2 := newClientServerTest(t, true, HandlerFunc(tt.Handler), tt.Opts...)
+	cst2 := newClientServerTest(t, http2Mode, HandlerFunc(tt.Handler), tt.Opts...)
 	defer cst2.close()
 
 	res1, err := tt.reqFunc()(cst1.c, cst1.ts.URL)
@@ -459,12 +558,9 @@
 // Test304Responses verifies that 304s don't declare that they're
 // chunking in their response headers and aren't allowed to produce
 // output.
-func Test304Responses_h1(t *testing.T) { test304Responses(t, h1Mode) }
-func Test304Responses_h2(t *testing.T) { test304Responses(t, h2Mode) }
-
-func test304Responses(t *testing.T, h2 bool) {
-	defer afterTest(t)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+func Test304Responses(t *testing.T) { run(t, test304Responses) }
+func test304Responses(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		w.WriteHeader(StatusNotModified)
 		_, err := w.Write([]byte("illegal body"))
 		if err != ErrBodyNotAllowed {
@@ -528,20 +624,17 @@
 
 // Tests that closing the Request.Cancel channel also while still
 // reading the response body. Issue 13159.
-func TestCancelRequestMidBody_h1(t *testing.T) { testCancelRequestMidBody(t, h1Mode) }
-func TestCancelRequestMidBody_h2(t *testing.T) { testCancelRequestMidBody(t, h2Mode) }
-func testCancelRequestMidBody(t *testing.T, h2 bool) {
-	defer afterTest(t)
+func TestCancelRequestMidBody(t *testing.T) { run(t, testCancelRequestMidBody) }
+func testCancelRequestMidBody(t *testing.T, mode testMode) {
 	unblock := make(chan bool)
 	didFlush := make(chan bool, 1)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		io.WriteString(w, "Hello")
 		w.(Flusher).Flush()
 		didFlush <- true
 		<-unblock
 		io.WriteString(w, ", world.")
 	}))
-	defer cst.close()
 	defer close(unblock)
 
 	req, _ := NewRequest("GET", cst.ts.URL, nil)
@@ -577,12 +670,9 @@
 }
 
 // Tests that clients can send trailers to a server and that the server can read them.
-func TestTrailersClientToServer_h1(t *testing.T) { testTrailersClientToServer(t, h1Mode) }
-func TestTrailersClientToServer_h2(t *testing.T) { testTrailersClientToServer(t, h2Mode) }
-
-func testTrailersClientToServer(t *testing.T, h2 bool) {
-	defer afterTest(t)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestTrailersClientToServer(t *testing.T) { run(t, testTrailersClientToServer) }
+func testTrailersClientToServer(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		var decl []string
 		for k := range r.Trailer {
 			decl = append(decl, k)
@@ -605,7 +695,6 @@
 				r.Trailer.Get("Client-Trailer-B"))
 		}
 	}))
-	defer cst.close()
 
 	var req *Request
 	req, _ = NewRequest("POST", cst.ts.URL, io.MultiReader(
@@ -632,15 +721,20 @@
 }
 
 // Tests that servers send trailers to a client and that the client can read them.
-func TestTrailersServerToClient_h1(t *testing.T)       { testTrailersServerToClient(t, h1Mode, false) }
-func TestTrailersServerToClient_h2(t *testing.T)       { testTrailersServerToClient(t, h2Mode, false) }
-func TestTrailersServerToClient_Flush_h1(t *testing.T) { testTrailersServerToClient(t, h1Mode, true) }
-func TestTrailersServerToClient_Flush_h2(t *testing.T) { testTrailersServerToClient(t, h2Mode, true) }
+func TestTrailersServerToClient(t *testing.T) {
+	run(t, func(t *testing.T, mode testMode) {
+		testTrailersServerToClient(t, mode, false)
+	})
+}
+func TestTrailersServerToClientFlush(t *testing.T) {
+	run(t, func(t *testing.T, mode testMode) {
+		testTrailersServerToClient(t, mode, true)
+	})
+}
 
-func testTrailersServerToClient(t *testing.T, h2, flush bool) {
-	defer afterTest(t)
+func testTrailersServerToClient(t *testing.T, mode testMode, flush bool) {
 	const body = "Some body"
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		w.Header().Set("Trailer", "Server-Trailer-A, Server-Trailer-B")
 		w.Header().Add("Trailer", "Server-Trailer-C")
 
@@ -657,7 +751,6 @@
 		w.Header().Set("Server-Trailer-C", "valuec") // skipping B
 		w.Header().Set("Server-Trailer-NotDeclared", "should be omitted")
 	}))
-	defer cst.close()
 
 	res, err := cst.c.Get(cst.ts.URL)
 	if err != nil {
@@ -668,7 +761,7 @@
 		"Content-Type": {"text/plain; charset=utf-8"},
 	}
 	wantLen := -1
-	if h2 && !flush {
+	if mode == http2Mode && !flush {
 		// In HTTP/1.1, any use of trailers forces HTTP/1.1
 		// chunking and a flush at the first write. That's
 		// unnecessary with HTTP/2's framing, so the server
@@ -708,16 +801,12 @@
 }
 
 // Don't allow a Body.Read after Body.Close. Issue 13648.
-func TestResponseBodyReadAfterClose_h1(t *testing.T) { testResponseBodyReadAfterClose(t, h1Mode) }
-func TestResponseBodyReadAfterClose_h2(t *testing.T) { testResponseBodyReadAfterClose(t, h2Mode) }
-
-func testResponseBodyReadAfterClose(t *testing.T, h2 bool) {
-	defer afterTest(t)
+func TestResponseBodyReadAfterClose(t *testing.T) { run(t, testResponseBodyReadAfterClose) }
+func testResponseBodyReadAfterClose(t *testing.T, mode testMode) {
 	const body = "Some body"
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		io.WriteString(w, body)
 	}))
-	defer cst.close()
 	res, err := cst.c.Get(cst.ts.URL)
 	if err != nil {
 		t.Fatal(err)
@@ -729,13 +818,11 @@
 	}
 }
 
-func TestConcurrentReadWriteReqBody_h1(t *testing.T) { testConcurrentReadWriteReqBody(t, h1Mode) }
-func TestConcurrentReadWriteReqBody_h2(t *testing.T) { testConcurrentReadWriteReqBody(t, h2Mode) }
-func testConcurrentReadWriteReqBody(t *testing.T, h2 bool) {
-	defer afterTest(t)
+func TestConcurrentReadWriteReqBody(t *testing.T) { run(t, testConcurrentReadWriteReqBody) }
+func testConcurrentReadWriteReqBody(t *testing.T, mode testMode) {
 	const reqBody = "some request body"
 	const resBody = "some response body"
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		var wg sync.WaitGroup
 		wg.Add(2)
 		didRead := make(chan bool, 1)
@@ -754,7 +841,7 @@
 		// Write in another goroutine.
 		go func() {
 			defer wg.Done()
-			if !h2 {
+			if mode != http2Mode {
 				// our HTTP/1 implementation intentionally
 				// doesn't permit writes during read (mostly
 				// due to it being undefined); if that is ever
@@ -765,7 +852,6 @@
 		}()
 		wg.Wait()
 	}))
-	defer cst.close()
 	req, _ := NewRequest("POST", cst.ts.URL, strings.NewReader(reqBody))
 	req.Header.Add("Expect", "100-continue") // just to complicate things
 	res, err := cst.c.Do(req)
@@ -782,15 +868,12 @@
 	}
 }
 
-func TestConnectRequest_h1(t *testing.T) { testConnectRequest(t, h1Mode) }
-func TestConnectRequest_h2(t *testing.T) { testConnectRequest(t, h2Mode) }
-func testConnectRequest(t *testing.T, h2 bool) {
-	defer afterTest(t)
+func TestConnectRequest(t *testing.T) { run(t, testConnectRequest) }
+func testConnectRequest(t *testing.T, mode testMode) {
 	gotc := make(chan *Request, 1)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		gotc <- r
 	}))
-	defer cst.close()
 
 	u, err := url.Parse(cst.ts.URL)
 	if err != nil {
@@ -840,17 +923,14 @@
 	}
 }
 
-func TestTransportUserAgent_h1(t *testing.T) { testTransportUserAgent(t, h1Mode) }
-func TestTransportUserAgent_h2(t *testing.T) { testTransportUserAgent(t, h2Mode) }
-func testTransportUserAgent(t *testing.T, h2 bool) {
-	defer afterTest(t)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestTransportUserAgent(t *testing.T) { run(t, testTransportUserAgent) }
+func testTransportUserAgent(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		fmt.Fprintf(w, "%q", r.Header["User-Agent"])
 	}))
-	defer cst.close()
 
 	either := func(a, b string) string {
-		if h2 {
+		if mode == http2Mode {
 			return b
 		}
 		return a
@@ -901,19 +981,22 @@
 	}
 }
 
-func TestStarRequestFoo_h1(t *testing.T)     { testStarRequest(t, "FOO", h1Mode) }
-func TestStarRequestFoo_h2(t *testing.T)     { testStarRequest(t, "FOO", h2Mode) }
-func TestStarRequestOptions_h1(t *testing.T) { testStarRequest(t, "OPTIONS", h1Mode) }
-func TestStarRequestOptions_h2(t *testing.T) { testStarRequest(t, "OPTIONS", h2Mode) }
-func testStarRequest(t *testing.T, method string, h2 bool) {
-	defer afterTest(t)
+func TestStarRequestMethod(t *testing.T) {
+	for _, method := range []string{"FOO", "OPTIONS"} {
+		t.Run(method, func(t *testing.T) {
+			run(t, func(t *testing.T, mode testMode) {
+				testStarRequest(t, method, mode)
+			})
+		})
+	}
+}
+func testStarRequest(t *testing.T, method string, mode testMode) {
 	gotc := make(chan *Request, 1)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		w.Header().Set("foo", "bar")
 		gotc <- r
 		w.(Flusher).Flush()
 	}))
-	defer cst.close()
 
 	u, err := url.Parse(cst.ts.URL)
 	if err != nil {
@@ -972,9 +1055,10 @@
 
 // Issue 13957
 func TestTransportDiscardsUnneededConns(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
-	cst := newClientServerTest(t, h2Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
+	run(t, testTransportDiscardsUnneededConns, []testMode{http2Mode})
+}
+func testTransportDiscardsUnneededConns(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		fmt.Fprintf(w, "Hello, %v", r.RemoteAddr)
 	}))
 	defer cst.close()
@@ -1058,20 +1142,19 @@
 }
 
 // tests that Transport doesn't retain a pointer to the provided request.
-func TestTransportGCRequest_Body_h1(t *testing.T)   { testTransportGCRequest(t, h1Mode, true) }
-func TestTransportGCRequest_Body_h2(t *testing.T)   { testTransportGCRequest(t, h2Mode, true) }
-func TestTransportGCRequest_NoBody_h1(t *testing.T) { testTransportGCRequest(t, h1Mode, false) }
-func TestTransportGCRequest_NoBody_h2(t *testing.T) { testTransportGCRequest(t, h2Mode, false) }
-func testTransportGCRequest(t *testing.T, h2, body bool) {
-	setParallel(t)
-	defer afterTest(t)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestTransportGCRequest(t *testing.T) {
+	run(t, func(t *testing.T, mode testMode) {
+		t.Run("Body", func(t *testing.T) { testTransportGCRequest(t, mode, true) })
+		t.Run("NoBody", func(t *testing.T) { testTransportGCRequest(t, mode, false) })
+	})
+}
+func testTransportGCRequest(t *testing.T, mode testMode, body bool) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		io.ReadAll(r.Body)
 		if body {
 			io.WriteString(w, "Hello.")
 		}
 	}))
-	defer cst.close()
 
 	didGC := make(chan struct{})
 	(func() {
@@ -1103,19 +1186,11 @@
 	}
 }
 
-func TestTransportRejectsInvalidHeaders_h1(t *testing.T) {
-	testTransportRejectsInvalidHeaders(t, h1Mode)
-}
-func TestTransportRejectsInvalidHeaders_h2(t *testing.T) {
-	testTransportRejectsInvalidHeaders(t, h2Mode)
-}
-func testTransportRejectsInvalidHeaders(t *testing.T, h2 bool) {
-	setParallel(t)
-	defer afterTest(t)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestTransportRejectsInvalidHeaders(t *testing.T) { run(t, testTransportRejectsInvalidHeaders) }
+func testTransportRejectsInvalidHeaders(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		fmt.Fprintf(w, "Handler saw headers: %q", r.Header)
 	}), optQuietLog)
-	defer cst.close()
 	cst.tr.DisableKeepAlives = true
 
 	tests := []struct {
@@ -1161,27 +1236,22 @@
 	}
 }
 
-func TestInterruptWithPanic_h1(t *testing.T)     { testInterruptWithPanic(t, h1Mode, "boom") }
-func TestInterruptWithPanic_h2(t *testing.T)     { testInterruptWithPanic(t, h2Mode, "boom") }
-func TestInterruptWithPanic_nil_h1(t *testing.T) { testInterruptWithPanic(t, h1Mode, nil) }
-func TestInterruptWithPanic_nil_h2(t *testing.T) { testInterruptWithPanic(t, h2Mode, nil) }
-func TestInterruptWithPanic_ErrAbortHandler_h1(t *testing.T) {
-	testInterruptWithPanic(t, h1Mode, ErrAbortHandler)
+func TestInterruptWithPanic(t *testing.T) {
+	run(t, func(t *testing.T, mode testMode) {
+		t.Run("boom", func(t *testing.T) { testInterruptWithPanic(t, mode, "boom") })
+		t.Run("nil", func(t *testing.T) { testInterruptWithPanic(t, mode, nil) })
+		t.Run("ErrAbortHandler", func(t *testing.T) { testInterruptWithPanic(t, mode, ErrAbortHandler) })
+	})
 }
-func TestInterruptWithPanic_ErrAbortHandler_h2(t *testing.T) {
-	testInterruptWithPanic(t, h2Mode, ErrAbortHandler)
-}
-func testInterruptWithPanic(t *testing.T, h2 bool, panicValue any) {
-	setParallel(t)
+func testInterruptWithPanic(t *testing.T, mode testMode, panicValue any) {
 	const msg = "hello"
-	defer afterTest(t)
 
 	testDone := make(chan struct{})
 	defer close(testDone)
 
 	var errorLog lockedBytesBuffer
 	gotHeaders := make(chan bool, 1)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		io.WriteString(w, msg)
 		w.(Flusher).Flush()
 
@@ -1193,7 +1263,6 @@
 	}), func(ts *httptest.Server) {
 		ts.Config.ErrorLog = log.New(&errorLog, "", 0)
 	})
-	defer cst.close()
 	res, err := cst.c.Get(cst.ts.URL)
 	if err != nil {
 		t.Fatal(err)
@@ -1274,15 +1343,11 @@
 }
 
 // Issue 14607
-func TestCloseIdleConnections_h1(t *testing.T) { testCloseIdleConnections(t, h1Mode) }
-func TestCloseIdleConnections_h2(t *testing.T) { testCloseIdleConnections(t, h2Mode) }
-func testCloseIdleConnections(t *testing.T, h2 bool) {
-	setParallel(t)
-	defer afterTest(t)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestCloseIdleConnections(t *testing.T) { run(t, testCloseIdleConnections) }
+func testCloseIdleConnections(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		w.Header().Set("X-Addr", r.RemoteAddr)
 	}))
-	defer cst.close()
 	get := func() string {
 		res, err := cst.c.Get(cst.ts.URL)
 		if err != nil {
@@ -1320,15 +1385,11 @@
 	return 0, io.EOF
 }
 
-func TestNoSniffExpectRequestBody_h1(t *testing.T) { testNoSniffExpectRequestBody(t, h1Mode) }
-func TestNoSniffExpectRequestBody_h2(t *testing.T) { testNoSniffExpectRequestBody(t, h2Mode) }
-
-func testNoSniffExpectRequestBody(t *testing.T, h2 bool) {
-	defer afterTest(t)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestNoSniffExpectRequestBody(t *testing.T) { run(t, testNoSniffExpectRequestBody) }
+func testNoSniffExpectRequestBody(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		w.WriteHeader(StatusUnauthorized)
 	}))
-	defer cst.close()
 
 	// Set ExpectContinueTimeout non-zero so RoundTrip won't try to write it.
 	cst.tr.ExpectContinueTimeout = 10 * time.Second
@@ -1349,18 +1410,15 @@
 	}
 }
 
-func TestServerUndeclaredTrailers_h1(t *testing.T) { testServerUndeclaredTrailers(t, h1Mode) }
-func TestServerUndeclaredTrailers_h2(t *testing.T) { testServerUndeclaredTrailers(t, h2Mode) }
-func testServerUndeclaredTrailers(t *testing.T, h2 bool) {
-	defer afterTest(t)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestServerUndeclaredTrailers(t *testing.T) { run(t, testServerUndeclaredTrailers) }
+func testServerUndeclaredTrailers(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		w.Header().Set("Foo", "Bar")
 		w.Header().Set("Trailer:Foo", "Baz")
 		w.(Flusher).Flush()
 		w.Header().Add("Trailer:Foo", "Baz2")
 		w.Header().Set("Trailer:Bar", "Quux")
 	}))
-	defer cst.close()
 	res, err := cst.c.Get(cst.ts.URL)
 	if err != nil {
 		t.Fatal(err)
@@ -1381,8 +1439,10 @@
 }
 
 func TestBadResponseAfterReadingBody(t *testing.T) {
-	defer afterTest(t)
-	cst := newClientServerTest(t, false, HandlerFunc(func(w ResponseWriter, r *Request) {
+	run(t, testBadResponseAfterReadingBody, []testMode{http1Mode})
+}
+func testBadResponseAfterReadingBody(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		_, err := io.Copy(io.Discard, r.Body)
 		if err != nil {
 			t.Fatal(err)
@@ -1394,7 +1454,6 @@
 		defer c.Close()
 		fmt.Fprintln(c, "some bogus crap")
 	}))
-	defer cst.close()
 
 	closes := 0
 	res, err := cst.c.Post(cst.ts.URL, "text/plain", countCloseReader{&closes, strings.NewReader("hello")})
@@ -1407,12 +1466,10 @@
 	}
 }
 
-func TestWriteHeader0_h1(t *testing.T) { testWriteHeader0(t, h1Mode) }
-func TestWriteHeader0_h2(t *testing.T) { testWriteHeader0(t, h2Mode) }
-func testWriteHeader0(t *testing.T, h2 bool) {
-	defer afterTest(t)
+func TestWriteHeader0(t *testing.T) { run(t, testWriteHeader0) }
+func testWriteHeader0(t *testing.T, mode testMode) {
 	gotpanic := make(chan bool, 1)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		defer close(gotpanic)
 		defer func() {
 			if e := recover(); e != nil {
@@ -1431,7 +1488,6 @@
 		}()
 		w.WriteHeader(0)
 	}))
-	defer cst.close()
 	res, err := cst.c.Get(cst.ts.URL)
 	if err != nil {
 		t.Fatal(err)
@@ -1446,15 +1502,17 @@
 
 // Issue 23010: don't be super strict checking WriteHeader's code if
 // it's not even valid to call WriteHeader then anyway.
-func TestWriteHeaderNoCodeCheck_h1(t *testing.T)       { testWriteHeaderAfterWrite(t, h1Mode, false) }
-func TestWriteHeaderNoCodeCheck_h1hijack(t *testing.T) { testWriteHeaderAfterWrite(t, h1Mode, true) }
-func TestWriteHeaderNoCodeCheck_h2(t *testing.T)       { testWriteHeaderAfterWrite(t, h2Mode, false) }
-func testWriteHeaderAfterWrite(t *testing.T, h2, hijack bool) {
-	setParallel(t)
-	defer afterTest(t)
-
+func TestWriteHeaderNoCodeCheck(t *testing.T) {
+	run(t, func(t *testing.T, mode testMode) {
+		testWriteHeaderAfterWrite(t, mode, false)
+	})
+}
+func TestWriteHeaderNoCodeCheck_h1hijack(t *testing.T) {
+	testWriteHeaderAfterWrite(t, http1Mode, true)
+}
+func testWriteHeaderAfterWrite(t *testing.T, mode testMode, hijack bool) {
 	var errorLog lockedBytesBuffer
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		if hijack {
 			conn, _, _ := w.(Hijacker).Hijack()
 			defer conn.Close()
@@ -1470,7 +1528,6 @@
 	}), func(ts *httptest.Server) {
 		ts.Config.ErrorLog = log.New(&errorLog, "", 0)
 	})
-	defer cst.close()
 	res, err := cst.c.Get(cst.ts.URL)
 	if err != nil {
 		t.Fatal(err)
@@ -1485,7 +1542,7 @@
 	}
 
 	// Also check the stderr output:
-	if h2 {
+	if mode == http2Mode {
 		// TODO: also emit this log message for HTTP/2?
 		// We historically haven't, so don't check.
 		return
@@ -1501,14 +1558,14 @@
 }
 
 func TestBidiStreamReverseProxy(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
-	backend := newClientServerTest(t, h2Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
+	run(t, testBidiStreamReverseProxy, []testMode{http2Mode})
+}
+func testBidiStreamReverseProxy(t *testing.T, mode testMode) {
+	backend := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		if _, err := io.Copy(w, r.Body); err != nil {
 			log.Printf("bidi backend copy: %v", err)
 		}
 	}))
-	defer backend.close()
 
 	backURL, err := url.Parse(backend.ts.URL)
 	if err != nil {
@@ -1516,10 +1573,9 @@
 	}
 	rp := httputil.NewSingleHostReverseProxy(backURL)
 	rp.Transport = backend.tr
-	proxy := newClientServerTest(t, h2Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
+	proxy := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		rp.ServeHTTP(w, r)
 	}))
-	defer proxy.close()
 
 	bodyRes := make(chan any, 1) // error or hash.Hash
 	pr, pw := io.Pipe()
@@ -1586,15 +1642,10 @@
 	}.run(t)
 }
 
-func TestIdentityTransferEncoding_h1(t *testing.T) { testIdentityTransferEncoding(t, h1Mode) }
-func TestIdentityTransferEncoding_h2(t *testing.T) { testIdentityTransferEncoding(t, h2Mode) }
-
-func testIdentityTransferEncoding(t *testing.T, h2 bool) {
-	setParallel(t)
-	defer afterTest(t)
-
+func TestIdentityTransferEncoding(t *testing.T) { run(t, testIdentityTransferEncoding) }
+func testIdentityTransferEncoding(t *testing.T, mode testMode) {
 	const body = "body"
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		gotBody, _ := io.ReadAll(r.Body)
 		if got, want := string(gotBody), body; got != want {
 			t.Errorf("got request body = %q; want %q", got, want)
@@ -1604,7 +1655,6 @@
 		w.(Flusher).Flush()
 		io.WriteString(w, body)
 	}))
-	defer cst.close()
 	req, _ := NewRequest("GET", cst.ts.URL, strings.NewReader(body))
 	res, err := cst.c.Do(req)
 	if err != nil {
@@ -1620,14 +1670,11 @@
 	}
 }
 
-func TestEarlyHintsRequest_h1(t *testing.T) { testEarlyHintsRequest(t, h1Mode) }
-func TestEarlyHintsRequest_h2(t *testing.T) { testEarlyHintsRequest(t, h2Mode) }
-func testEarlyHintsRequest(t *testing.T, h2 bool) {
-	defer afterTest(t)
-
+func TestEarlyHintsRequest(t *testing.T) { run(t, testEarlyHintsRequest) }
+func testEarlyHintsRequest(t *testing.T, mode testMode) {
 	var wg sync.WaitGroup
 	wg.Add(1)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		h := w.Header()
 
 		h.Add("Content-Length", "123") // must be ignored
@@ -1642,7 +1689,6 @@
 
 		w.Write([]byte("Hello"))
 	}))
-	defer cst.close()
 
 	checkLinkHeaders := func(t *testing.T, expected, got []string) {
 		t.Helper()
diff --git a/src/net/http/cookie.go b/src/net/http/cookie.go
index 9cb0804..912fde6 100644
--- a/src/net/http/cookie.go
+++ b/src/net/http/cookie.go
@@ -73,6 +73,7 @@
 		if !ok {
 			continue
 		}
+		name = textproto.TrimString(name)
 		if !isCookieNameValid(name) {
 			continue
 		}
@@ -246,7 +247,7 @@
 	if !isCookieNameValid(c.Name) {
 		return errors.New("http: invalid Cookie.Name")
 	}
-	if !validCookieExpires(c.Expires) {
+	if !c.Expires.IsZero() && !validCookieExpires(c.Expires) {
 		return errors.New("http: invalid Cookie.Expires")
 	}
 	for i := 0; i < len(c.Value); i++ {
@@ -272,7 +273,7 @@
 // readCookies parses all "Cookie" values from the header h and
 // returns the successfully parsed Cookies.
 //
-// if filter isn't empty, only cookies of that name are returned
+// if filter isn't empty, only cookies of that name are returned.
 func readCookies(h Header, filter string) []*Cookie {
 	lines := h["Cookie"]
 	if len(lines) == 0 {
@@ -291,6 +292,7 @@
 				continue
 			}
 			name, val, _ := strings.Cut(part, "=")
+			name = textproto.TrimString(name)
 			if !isCookieNameValid(name) {
 				continue
 			}
diff --git a/src/net/http/cookie_test.go b/src/net/http/cookie_test.go
index ccc5f98..e5bd46a 100644
--- a/src/net/http/cookie_test.go
+++ b/src/net/http/cookie_test.go
@@ -5,7 +5,6 @@
 package http
 
 import (
-	"bytes"
 	"encoding/json"
 	"fmt"
 	"log"
@@ -151,7 +150,7 @@
 
 func TestWriteSetCookies(t *testing.T) {
 	defer log.SetOutput(os.Stderr)
-	var logbuf bytes.Buffer
+	var logbuf strings.Builder
 	log.SetOutput(&logbuf)
 
 	for i, tt := range writeSetCookiesTests {
@@ -352,6 +351,12 @@
 		Header{"Set-Cookie": {`special-8=","`}},
 		[]*Cookie{{Name: "special-8", Value: ",", Raw: `special-8=","`}},
 	},
+	// Make sure we can properly read back the Set-Cookie headers
+	// for names containing spaces:
+	{
+		Header{"Set-Cookie": {`special-9 =","`}},
+		[]*Cookie{{Name: "special-9", Value: ",", Raw: `special-9 =","`}},
+	},
 
 	// TODO(bradfitz): users have reported seeing this in the
 	// wild, but do browsers handle it? RFC 6265 just says "don't
@@ -476,7 +481,7 @@
 
 func TestCookieSanitizeValue(t *testing.T) {
 	defer log.SetOutput(os.Stderr)
-	var logbuf bytes.Buffer
+	var logbuf strings.Builder
 	log.SetOutput(&logbuf)
 
 	tests := []struct {
@@ -508,7 +513,7 @@
 
 func TestCookieSanitizePath(t *testing.T) {
 	defer log.SetOutput(os.Stderr)
-	var logbuf bytes.Buffer
+	var logbuf strings.Builder
 	log.SetOutput(&logbuf)
 
 	tests := []struct {
@@ -536,11 +541,14 @@
 	}{
 		{nil, false},
 		{&Cookie{Name: ""}, false},
-		{&Cookie{Name: "invalid-expires"}, false},
 		{&Cookie{Name: "invalid-value", Value: "foo\"bar"}, false},
 		{&Cookie{Name: "invalid-path", Path: "/foo;bar/"}, false},
 		{&Cookie{Name: "invalid-domain", Domain: "example.com:80"}, false},
-		{&Cookie{Name: "valid", Value: "foo", Path: "/bar", Domain: "example.com", Expires: time.Unix(0, 0)}, true},
+		{&Cookie{Name: "invalid-expiry", Value: "", Expires: time.Date(1600, 1, 1, 1, 1, 1, 1, time.UTC)}, false},
+		{&Cookie{Name: "valid-empty"}, true},
+		{&Cookie{Name: "valid-expires", Value: "foo", Path: "/bar", Domain: "example.com", Expires: time.Unix(0, 0)}, true},
+		{&Cookie{Name: "valid-max-age", Value: "foo", Path: "/bar", Domain: "example.com", MaxAge: 60}, true},
+		{&Cookie{Name: "valid-all-fields", Value: "foo", Path: "/bar", Domain: "example.com", Expires: time.Unix(0, 0), MaxAge: 0}, true},
 	}
 
 	for _, tt := range tests {
diff --git a/src/net/http/cookiejar/jar.go b/src/net/http/cookiejar/jar.go
index 87c38ce..3d0ad19 100644
--- a/src/net/http/cookiejar/jar.go
+++ b/src/net/http/cookiejar/jar.go
@@ -214,8 +214,8 @@
 		if len(s[i].Path) != len(s[j].Path) {
 			return len(s[i].Path) > len(s[j].Path)
 		}
-		if !s[i].Creation.Equal(s[j].Creation) {
-			return s[i].Creation.Before(s[j].Creation)
+		if ret := s[i].Creation.Compare(s[j].Creation); ret != 0 {
+			return ret < 0
 		}
 		return s[i].seqNum < s[j].seqNum
 	})
@@ -465,7 +465,7 @@
 		// dot in the domain-attribute before processing the cookie.
 		//
 		// Most browsers don't do that for IP addresses, only curl
-		// version 7.54) and and IE (version 11) do not reject a
+		// version 7.54) and IE (version 11) do not reject a
 		//     Set-Cookie: a=1; domain=.127.0.0.1
 		// This leading dot is optional and serves only as hint for
 		// humans to indicate that a cookie with "domain=.bbc.co.uk"
diff --git a/src/net/http/export_test.go b/src/net/http/export_test.go
index 205ca83..fb5ab93 100644
--- a/src/net/http/export_test.go
+++ b/src/net/http/export_test.go
@@ -60,7 +60,7 @@
 	}
 }
 
-func CondSkipHTTP2(t *testing.T) {
+func CondSkipHTTP2(t testing.TB) {
 	if omitBundledHTTP2 {
 		t.Skip("skipping HTTP/2 test when nethttpomithttp2 build tag in use")
 	}
@@ -72,8 +72,6 @@
 )
 
 func SetReadLoopBeforeNextReadHook(f func()) {
-	testHookMu.Lock()
-	defer testHookMu.Unlock()
 	unnilTestHook(&f)
 	testHookReadLoopBeforeNextRead = f
 }
diff --git a/src/net/http/fs.go b/src/net/http/fs.go
index 4f144eb..8345904 100644
--- a/src/net/http/fs.go
+++ b/src/net/http/fs.go
@@ -9,6 +9,7 @@
 import (
 	"errors"
 	"fmt"
+	"internal/safefilepath"
 	"io"
 	"io/fs"
 	"mime"
@@ -69,14 +70,15 @@
 // Open implements FileSystem using os.Open, opening files for reading rooted
 // and relative to the directory d.
 func (d Dir) Open(name string) (File, error) {
-	if filepath.Separator != '/' && strings.ContainsRune(name, filepath.Separator) {
-		return nil, errors.New("http: invalid character in file path")
+	path, err := safefilepath.FromFS(path.Clean("/" + name))
+	if err != nil {
+		return nil, errors.New("http: invalid or unsafe file path")
 	}
 	dir := string(d)
 	if dir == "" {
 		dir = "."
 	}
-	fullName := filepath.Join(dir, filepath.FromSlash(path.Clean("/"+name)))
+	fullName := filepath.Join(dir, path)
 	f, err := os.Open(fullName)
 	if err != nil {
 		return nil, mapOpenError(err, fullName, filepath.Separator, os.Stat)
@@ -254,81 +256,95 @@
 		Error(w, err.Error(), StatusInternalServerError)
 		return
 	}
+	if size < 0 {
+		// Should never happen but just to be sure
+		Error(w, "negative content size computed", StatusInternalServerError)
+		return
+	}
 
 	// handle Content-Range header.
 	sendSize := size
 	var sendContent io.Reader = content
-	if size >= 0 {
-		ranges, err := parseRange(rangeReq, size)
-		if err != nil {
-			if err == errNoOverlap {
-				w.Header().Set("Content-Range", fmt.Sprintf("bytes */%d", size))
-			}
+	ranges, err := parseRange(rangeReq, size)
+	switch err {
+	case nil:
+	case errNoOverlap:
+		if size == 0 {
+			// Some clients add a Range header to all requests to
+			// limit the size of the response. If the file is empty,
+			// ignore the range header and respond with a 200 rather
+			// than a 416.
+			ranges = nil
+			break
+		}
+		w.Header().Set("Content-Range", fmt.Sprintf("bytes */%d", size))
+		fallthrough
+	default:
+		Error(w, err.Error(), StatusRequestedRangeNotSatisfiable)
+		return
+	}
+
+	if sumRangesSize(ranges) > size {
+		// The total number of bytes in all the ranges
+		// is larger than the size of the file by
+		// itself, so this is probably an attack, or a
+		// dumb client. Ignore the range request.
+		ranges = nil
+	}
+	switch {
+	case len(ranges) == 1:
+		// RFC 7233, Section 4.1:
+		// "If a single part is being transferred, the server
+		// generating the 206 response MUST generate a
+		// Content-Range header field, describing what range
+		// of the selected representation is enclosed, and a
+		// payload consisting of the range.
+		// ...
+		// A server MUST NOT generate a multipart response to
+		// a request for a single range, since a client that
+		// does not request multiple parts might not support
+		// multipart responses."
+		ra := ranges[0]
+		if _, err := content.Seek(ra.start, io.SeekStart); err != nil {
 			Error(w, err.Error(), StatusRequestedRangeNotSatisfiable)
 			return
 		}
-		if sumRangesSize(ranges) > size {
-			// The total number of bytes in all the ranges
-			// is larger than the size of the file by
-			// itself, so this is probably an attack, or a
-			// dumb client. Ignore the range request.
-			ranges = nil
-		}
-		switch {
-		case len(ranges) == 1:
-			// RFC 7233, Section 4.1:
-			// "If a single part is being transferred, the server
-			// generating the 206 response MUST generate a
-			// Content-Range header field, describing what range
-			// of the selected representation is enclosed, and a
-			// payload consisting of the range.
-			// ...
-			// A server MUST NOT generate a multipart response to
-			// a request for a single range, since a client that
-			// does not request multiple parts might not support
-			// multipart responses."
-			ra := ranges[0]
-			if _, err := content.Seek(ra.start, io.SeekStart); err != nil {
-				Error(w, err.Error(), StatusRequestedRangeNotSatisfiable)
-				return
-			}
-			sendSize = ra.length
-			code = StatusPartialContent
-			w.Header().Set("Content-Range", ra.contentRange(size))
-		case len(ranges) > 1:
-			sendSize = rangesMIMESize(ranges, ctype, size)
-			code = StatusPartialContent
+		sendSize = ra.length
+		code = StatusPartialContent
+		w.Header().Set("Content-Range", ra.contentRange(size))
+	case len(ranges) > 1:
+		sendSize = rangesMIMESize(ranges, ctype, size)
+		code = StatusPartialContent
 
-			pr, pw := io.Pipe()
-			mw := multipart.NewWriter(pw)
-			w.Header().Set("Content-Type", "multipart/byteranges; boundary="+mw.Boundary())
-			sendContent = pr
-			defer pr.Close() // cause writing goroutine to fail and exit if CopyN doesn't finish.
-			go func() {
-				for _, ra := range ranges {
-					part, err := mw.CreatePart(ra.mimeHeader(ctype, size))
-					if err != nil {
-						pw.CloseWithError(err)
-						return
-					}
-					if _, err := content.Seek(ra.start, io.SeekStart); err != nil {
-						pw.CloseWithError(err)
-						return
-					}
-					if _, err := io.CopyN(part, content, ra.length); err != nil {
-						pw.CloseWithError(err)
-						return
-					}
+		pr, pw := io.Pipe()
+		mw := multipart.NewWriter(pw)
+		w.Header().Set("Content-Type", "multipart/byteranges; boundary="+mw.Boundary())
+		sendContent = pr
+		defer pr.Close() // cause writing goroutine to fail and exit if CopyN doesn't finish.
+		go func() {
+			for _, ra := range ranges {
+				part, err := mw.CreatePart(ra.mimeHeader(ctype, size))
+				if err != nil {
+					pw.CloseWithError(err)
+					return
 				}
-				mw.Close()
-				pw.Close()
-			}()
-		}
+				if _, err := content.Seek(ra.start, io.SeekStart); err != nil {
+					pw.CloseWithError(err)
+					return
+				}
+				if _, err := io.CopyN(part, content, ra.length); err != nil {
+					pw.CloseWithError(err)
+					return
+				}
+			}
+			mw.Close()
+			pw.Close()
+		}()
+	}
 
-		w.Header().Set("Accept-Ranges", "bytes")
-		if w.Header().Get("Content-Encoding") == "" {
-			w.Header().Set("Content-Length", strconv.FormatInt(sendSize, 10))
-		}
+	w.Header().Set("Accept-Ranges", "bytes")
+	if w.Header().Get("Content-Encoding") == "" {
+		w.Header().Set("Content-Length", strconv.FormatInt(sendSize, 10))
 	}
 
 	w.WriteHeader(code)
@@ -431,7 +447,7 @@
 	// The Last-Modified header truncates sub-second precision so
 	// the modtime needs to be truncated too.
 	modtime = modtime.Truncate(time.Second)
-	if modtime.Before(t) || modtime.Equal(t) {
+	if ret := modtime.Compare(t); ret <= 0 {
 		return condTrue
 	}
 	return condFalse
@@ -482,7 +498,7 @@
 	// The Last-Modified header truncates sub-second precision so
 	// the modtime needs to be truncated too.
 	modtime = modtime.Truncate(time.Second)
-	if modtime.Before(t) || modtime.Equal(t) {
+	if ret := modtime.Compare(t); ret <= 0 {
 		return condFalse
 	}
 	return condTrue
@@ -642,7 +658,6 @@
 			defer ff.Close()
 			dd, err := ff.Stat()
 			if err == nil {
-				name = index
 				d = dd
 				f = ff
 			}
@@ -818,6 +833,7 @@
 
 // FS converts fsys to a FileSystem implementation,
 // for use with FileServer and NewFileTransport.
+// The files provided by fsys must implement io.Seeker.
 func FS(fsys fs.FS) FileSystem {
 	return ioFS{fsys}
 }
@@ -842,12 +858,22 @@
 }
 
 func (f *fileHandler) ServeHTTP(w ResponseWriter, r *Request) {
-	upath := r.URL.Path
-	if !strings.HasPrefix(upath, "/") {
-		upath = "/" + upath
-		r.URL.Path = upath
+	const options = MethodOptions + ", " + MethodGet + ", " + MethodHead
+
+	switch r.Method {
+	case MethodGet, MethodHead:
+		if !strings.HasPrefix(r.URL.Path, "/") {
+			r.URL.Path = "/" + r.URL.Path
+		}
+		serveFile(w, r, f.root, path.Clean(r.URL.Path), true)
+
+	case MethodOptions:
+		w.Header().Set("Allow", options)
+
+	default:
+		w.Header().Set("Allow", options)
+		Error(w, "read-only", StatusMethodNotAllowed)
 	}
-	serveFile(w, r, f.root, path.Clean(upath), true)
 }
 
 // httpRange specifies the byte range to be sent to the client.
diff --git a/src/net/http/fs_test.go b/src/net/http/fs_test.go
index 4be561c..74f7a80 100644
--- a/src/net/http/fs_test.go
+++ b/src/net/http/fs_test.go
@@ -24,6 +24,7 @@
 	"reflect"
 	"regexp"
 	"runtime"
+	"sort"
 	"strings"
 	"testing"
 	"time"
@@ -67,13 +68,11 @@
 	{r: "bytes=100-1000", code: StatusRequestedRangeNotSatisfiable},
 }
 
-func TestServeFile(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestServeFile(t *testing.T) { run(t, testServeFile) }
+func testServeFile(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		ServeFile(w, r, "testdata/file")
-	}))
-	defer ts.Close()
+	})).ts
 	c := ts.Client()
 
 	var err error
@@ -219,6 +218,27 @@
 	}
 }
 
+// Tests that ranges are ignored with serving empty content. (Issue 54794)
+func TestServeContentWithEmptyContentIgnoreRanges(t *testing.T) {
+	for _, r := range []string{
+		"bytes=0-128",
+		"bytes=1-",
+	} {
+		rec := httptest.NewRecorder()
+		req := httptest.NewRequest("GET", "/", nil)
+		req.Header.Set("Range", r)
+		ServeContent(rec, req, "nothing", time.Now(), bytes.NewReader(nil))
+		res := rec.Result()
+		if res.StatusCode != 200 {
+			t.Errorf("code = %v; want 200", res.Status)
+		}
+		bodyLen := rec.Body.Len()
+		if bodyLen != 0 {
+			t.Errorf("body.Len() = %v; want 0", res.Status)
+		}
+	}
+}
+
 var fsRedirectTestData = []struct {
 	original, redirect string
 }{
@@ -227,13 +247,12 @@
 	{"/test/testdata/file/", "/test/testdata/file"},
 }
 
-func TestFSRedirect(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(StripPrefix("/test", FileServer(Dir("."))))
-	defer ts.Close()
+func TestFSRedirect(t *testing.T) { run(t, testFSRedirect) }
+func testFSRedirect(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, StripPrefix("/test", FileServer(Dir(".")))).ts
 
 	for _, data := range fsRedirectTestData {
-		res, err := Get(ts.URL + data.original)
+		res, err := ts.Client().Get(ts.URL + data.original)
 		if err != nil {
 			t.Fatal(err)
 		}
@@ -277,8 +296,8 @@
 	}
 }
 
-func TestFileServerEscapesNames(t *testing.T) {
-	defer afterTest(t)
+func TestFileServerEscapesNames(t *testing.T) { run(t, testFileServerEscapesNames) }
+func testFileServerEscapesNames(t *testing.T, mode testMode) {
 	const dirListPrefix = "<pre>\n"
 	const dirListSuffix = "\n</pre>\n"
 	tests := []struct {
@@ -303,11 +322,10 @@
 		fs[fmt.Sprintf("/%d/%s", i, test.name)] = testFile
 	}
 
-	ts := httptest.NewServer(FileServer(&fs))
-	defer ts.Close()
+	ts := newClientServerTest(t, mode, FileServer(&fs)).ts
 	for i, test := range tests {
 		url := fmt.Sprintf("%s/%d", ts.URL, i)
-		res, err := Get(url)
+		res, err := ts.Client().Get(url)
 		if err != nil {
 			t.Fatalf("test %q: Get: %v", test.name, err)
 		}
@@ -326,8 +344,8 @@
 	}
 }
 
-func TestFileServerSortsNames(t *testing.T) {
-	defer afterTest(t)
+func TestFileServerSortsNames(t *testing.T) { run(t, testFileServerSortsNames) }
+func testFileServerSortsNames(t *testing.T, mode testMode) {
 	const contents = "I am a fake file"
 	dirMod := time.Unix(123, 0).UTC()
 	fileMod := time.Unix(1000000000, 0).UTC()
@@ -350,10 +368,9 @@
 		},
 	}
 
-	ts := httptest.NewServer(FileServer(&fs))
-	defer ts.Close()
+	ts := newClientServerTest(t, mode, FileServer(&fs)).ts
 
-	res, err := Get(ts.URL)
+	res, err := ts.Client().Get(ts.URL)
 	if err != nil {
 		t.Fatalf("Get: %v", err)
 	}
@@ -376,16 +393,15 @@
 	}
 }
 
-func TestFileServerImplicitLeadingSlash(t *testing.T) {
-	defer afterTest(t)
+func TestFileServerImplicitLeadingSlash(t *testing.T) { run(t, testFileServerImplicitLeadingSlash) }
+func testFileServerImplicitLeadingSlash(t *testing.T, mode testMode) {
 	tempDir := t.TempDir()
 	if err := os.WriteFile(filepath.Join(tempDir, "foo.txt"), []byte("Hello world"), 0644); err != nil {
 		t.Fatalf("WriteFile: %v", err)
 	}
-	ts := httptest.NewServer(StripPrefix("/bar/", FileServer(Dir(tempDir))))
-	defer ts.Close()
+	ts := newClientServerTest(t, mode, StripPrefix("/bar/", FileServer(Dir(tempDir)))).ts
 	get := func(suffix string) string {
-		res, err := Get(ts.URL + suffix)
+		res, err := ts.Client().Get(ts.URL + suffix)
 		if err != nil {
 			t.Fatalf("Get %s: %v", suffix, err)
 		}
@@ -404,6 +420,46 @@
 	}
 }
 
+func TestFileServerMethodOptions(t *testing.T) { run(t, testFileServerMethodOptions) }
+func testFileServerMethodOptions(t *testing.T, mode testMode) {
+	const want = "GET, HEAD, OPTIONS"
+	ts := newClientServerTest(t, mode, FileServer(Dir("."))).ts
+
+	tests := []struct {
+		method     string
+		wantStatus int
+	}{
+		{MethodOptions, StatusOK},
+
+		{MethodDelete, StatusMethodNotAllowed},
+		{MethodPut, StatusMethodNotAllowed},
+		{MethodPost, StatusMethodNotAllowed},
+	}
+
+	for _, test := range tests {
+		req, err := NewRequest(test.method, ts.URL, nil)
+		if err != nil {
+			t.Fatal(err)
+		}
+		res, err := ts.Client().Do(req)
+		if err != nil {
+			t.Fatal(err)
+		}
+		defer res.Body.Close()
+
+		if res.StatusCode != test.wantStatus {
+			t.Errorf("%s got status %q, want code %d", test.method, res.Status, test.wantStatus)
+		}
+
+		a := strings.Split(res.Header.Get("Allow"), ", ")
+		sort.Strings(a)
+		got := strings.Join(a, ", ")
+		if got != want {
+			t.Errorf("%s got Allow header %q, want %q", test.method, got, want)
+		}
+	}
+}
+
 func TestDirJoin(t *testing.T) {
 	if runtime.GOOS == "windows" {
 		t.Skip("skipping test on windows")
@@ -454,10 +510,10 @@
 	test(Dir("./"))
 }
 
-func TestServeFileContentType(t *testing.T) {
-	defer afterTest(t)
+func TestServeFileContentType(t *testing.T) { run(t, testServeFileContentType) }
+func testServeFileContentType(t *testing.T, mode testMode) {
 	const ctype = "icecream/chocolate"
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		switch r.FormValue("override") {
 		case "1":
 			w.Header().Set("Content-Type", ctype)
@@ -466,10 +522,9 @@
 			w.Header()["Content-Type"] = []string{}
 		}
 		ServeFile(w, r, "testdata/file")
-	}))
-	defer ts.Close()
+	})).ts
 	get := func(override string, want []string) {
-		resp, err := Get(ts.URL + "?override=" + override)
+		resp, err := ts.Client().Get(ts.URL + "?override=" + override)
 		if err != nil {
 			t.Fatal(err)
 		}
@@ -483,13 +538,12 @@
 	get("2", nil)
 }
 
-func TestServeFileMimeType(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestServeFileMimeType(t *testing.T) { run(t, testServeFileMimeType) }
+func testServeFileMimeType(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		ServeFile(w, r, "testdata/style.css")
-	}))
-	defer ts.Close()
-	resp, err := Get(ts.URL)
+	})).ts
+	resp, err := ts.Client().Get(ts.URL)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -500,13 +554,12 @@
 	}
 }
 
-func TestServeFileFromCWD(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestServeFileFromCWD(t *testing.T) { run(t, testServeFileFromCWD) }
+func testServeFileFromCWD(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		ServeFile(w, r, "fs_test.go")
-	}))
-	defer ts.Close()
-	r, err := Get(ts.URL)
+	})).ts
+	r, err := ts.Client().Get(ts.URL)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -517,14 +570,13 @@
 }
 
 // Issue 13996
-func TestServeDirWithoutTrailingSlash(t *testing.T) {
+func TestServeDirWithoutTrailingSlash(t *testing.T) { run(t, testServeDirWithoutTrailingSlash) }
+func testServeDirWithoutTrailingSlash(t *testing.T, mode testMode) {
 	e := "/testdata/"
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		ServeFile(w, r, ".")
-	}))
-	defer ts.Close()
-	r, err := Get(ts.URL + "/testdata")
+	})).ts
+	r, err := ts.Client().Get(ts.URL + "/testdata")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -536,11 +588,9 @@
 
 // Tests that ServeFile doesn't add a Content-Length if a Content-Encoding is
 // specified.
-func TestServeFileWithContentEncoding_h1(t *testing.T) { testServeFileWithContentEncoding(t, h1Mode) }
-func TestServeFileWithContentEncoding_h2(t *testing.T) { testServeFileWithContentEncoding(t, h2Mode) }
-func testServeFileWithContentEncoding(t *testing.T, h2 bool) {
-	defer afterTest(t)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestServeFileWithContentEncoding(t *testing.T) { run(t, testServeFileWithContentEncoding) }
+func testServeFileWithContentEncoding(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		w.Header().Set("Content-Encoding", "foo")
 		ServeFile(w, r, "testdata/file")
 
@@ -553,7 +603,6 @@
 		// Content-Length and test ServeFile only, flush here.
 		w.(Flusher).Flush()
 	}))
-	defer cst.close()
 	resp, err := cst.c.Get(cst.ts.URL)
 	if err != nil {
 		t.Fatal(err)
@@ -566,11 +615,9 @@
 
 // Tests that ServeFile does not generate representation metadata when
 // file has not been modified, as per RFC 7232 section 4.1.
-func TestServeFileNotModified_h1(t *testing.T) { testServeFileNotModified(t, h1Mode) }
-func TestServeFileNotModified_h2(t *testing.T) { testServeFileNotModified(t, h2Mode) }
-func testServeFileNotModified(t *testing.T, h2 bool) {
-	defer afterTest(t)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestServeFileNotModified(t *testing.T) { run(t, testServeFileNotModified) }
+func testServeFileNotModified(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		w.Header().Set("Content-Type", "application/json")
 		w.Header().Set("Content-Encoding", "foo")
 		w.Header().Set("Etag", `"123"`)
@@ -585,7 +632,6 @@
 		// Content-Length and test ServeFile only, flush here.
 		w.(Flusher).Flush()
 	}))
-	defer cst.close()
 	req, err := NewRequest("GET", cst.ts.URL, nil)
 	if err != nil {
 		t.Fatal(err)
@@ -618,9 +664,8 @@
 	}
 }
 
-func TestServeIndexHtml(t *testing.T) {
-	defer afterTest(t)
-
+func TestServeIndexHtml(t *testing.T) { run(t, testServeIndexHtml) }
+func testServeIndexHtml(t *testing.T, mode testMode) {
 	for i := 0; i < 2; i++ {
 		var h Handler
 		var name string
@@ -634,11 +679,10 @@
 		}
 		t.Run(name, func(t *testing.T) {
 			const want = "index.html says hello\n"
-			ts := httptest.NewServer(h)
-			defer ts.Close()
+			ts := newClientServerTest(t, mode, h).ts
 
 			for _, path := range []string{"/testdata/", "/testdata/index.html"} {
-				res, err := Get(ts.URL + path)
+				res, err := ts.Client().Get(ts.URL + path)
 				if err != nil {
 					t.Fatal(err)
 				}
@@ -655,14 +699,14 @@
 	}
 }
 
-func TestServeIndexHtmlFS(t *testing.T) {
-	defer afterTest(t)
+func TestServeIndexHtmlFS(t *testing.T) { run(t, testServeIndexHtmlFS) }
+func testServeIndexHtmlFS(t *testing.T, mode testMode) {
 	const want = "index.html says hello\n"
-	ts := httptest.NewServer(FileServer(Dir(".")))
+	ts := newClientServerTest(t, mode, FileServer(Dir("."))).ts
 	defer ts.Close()
 
 	for _, path := range []string{"/testdata/", "/testdata/index.html"} {
-		res, err := Get(ts.URL + path)
+		res, err := ts.Client().Get(ts.URL + path)
 		if err != nil {
 			t.Fatal(err)
 		}
@@ -677,10 +721,9 @@
 	}
 }
 
-func TestFileServerZeroByte(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(FileServer(Dir(".")))
-	defer ts.Close()
+func TestFileServerZeroByte(t *testing.T) { run(t, testFileServerZeroByte) }
+func testFileServerZeroByte(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, FileServer(Dir("."))).ts
 
 	c, err := net.Dial("tcp", ts.Listener.Addr().String())
 	if err != nil {
@@ -702,6 +745,25 @@
 	}
 }
 
+func TestFileServerNamesEscape(t *testing.T) { run(t, testFileServerNamesEscape) }
+func testFileServerNamesEscape(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, FileServer(Dir("testdata"))).ts
+	for _, path := range []string{
+		"/../testdata/file",
+		"/NUL", // don't read from device files on Windows
+	} {
+		res, err := ts.Client().Get(ts.URL + path)
+		if err != nil {
+			t.Fatal(err)
+		}
+		res.Body.Close()
+		if res.StatusCode < 400 || res.StatusCode > 599 {
+			t.Errorf("Get(%q): got status %v, want 4xx or 5xx", path, res.StatusCode)
+		}
+
+	}
+}
+
 type fakeFileInfo struct {
 	dir      bool
 	basename string
@@ -767,8 +829,8 @@
 	return &fakeFile{ReadSeeker: strings.NewReader(f.contents), fi: f, path: name}, nil
 }
 
-func TestDirectoryIfNotModified(t *testing.T) {
-	defer afterTest(t)
+func TestDirectoryIfNotModified(t *testing.T) { run(t, testDirectoryIfNotModified) }
+func testDirectoryIfNotModified(t *testing.T, mode testMode) {
 	const indexContents = "I am a fake index.html file"
 	fileMod := time.Unix(1000000000, 0).UTC()
 	fileModStr := fileMod.Format(TimeFormat)
@@ -787,10 +849,9 @@
 		"/index.html": indexFile,
 	}
 
-	ts := httptest.NewServer(FileServer(fs))
-	defer ts.Close()
+	ts := newClientServerTest(t, mode, FileServer(fs)).ts
 
-	res, err := Get(ts.URL)
+	res, err := ts.Client().Get(ts.URL)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -842,8 +903,8 @@
 	return fi
 }
 
-func TestServeContent(t *testing.T) {
-	defer afterTest(t)
+func TestServeContent(t *testing.T) { run(t, testServeContent) }
+func testServeContent(t *testing.T, mode testMode) {
 	type serveParam struct {
 		name        string
 		modtime     time.Time
@@ -852,7 +913,7 @@
 		etag        string
 	}
 	servec := make(chan serveParam, 1)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		p := <-servec
 		if p.etag != "" {
 			w.Header().Set("ETag", p.etag)
@@ -861,8 +922,7 @@
 			w.Header().Set("Content-Type", p.contentType)
 		}
 		ServeContent(w, r, p.name, p.modtime, p.content)
-	}))
-	defer ts.Close()
+	})).ts
 
 	type testCase struct {
 		// One of file or content must be set:
@@ -1171,8 +1231,8 @@
 func (issue12991File) Stat() (fs.FileInfo, error) { return nil, fs.ErrPermission }
 func (issue12991File) Close() error               { return nil }
 
-func TestServeContentErrorMessages(t *testing.T) {
-	defer afterTest(t)
+func TestServeContentErrorMessages(t *testing.T) { run(t, testServeContentErrorMessages) }
+func testServeContentErrorMessages(t *testing.T, mode testMode) {
 	fs := fakeFS{
 		"/500": &fakeFileInfo{
 			err: errors.New("random error"),
@@ -1181,8 +1241,7 @@
 			err: &fs.PathError{Err: fs.ErrPermission},
 		},
 	}
-	ts := httptest.NewServer(FileServer(fs))
-	defer ts.Close()
+	ts := newClientServerTest(t, mode, FileServer(fs)).ts
 	c := ts.Client()
 	for _, code := range []int{403, 404, 500} {
 		res, err := c.Get(fmt.Sprintf("%s/%d", ts.URL, code))
@@ -1231,7 +1290,7 @@
 	}
 	defer os.Remove(filepath)
 
-	var buf bytes.Buffer
+	var buf strings.Builder
 	child := exec.Command("strace", "-f", "-q", os.Args[0], "-test.run=TestLinuxSendfileChild")
 	child.ExtraFiles = append(child.ExtraFiles, lnf)
 	child.Env = append([]string{"GO_WANT_HELPER_PROCESS=1"}, os.Environ()...)
@@ -1300,20 +1359,20 @@
 
 // Issues 18984, 49552: tests that requests for paths beyond files return not-found errors
 func TestFileServerNotDirError(t *testing.T) {
-	defer afterTest(t)
-	t.Run("Dir", func(t *testing.T) {
-		testFileServerNotDirError(t, func(path string) FileSystem { return Dir(path) })
-	})
-	t.Run("FS", func(t *testing.T) {
-		testFileServerNotDirError(t, func(path string) FileSystem { return FS(os.DirFS(path)) })
+	run(t, func(t *testing.T, mode testMode) {
+		t.Run("Dir", func(t *testing.T) {
+			testFileServerNotDirError(t, mode, func(path string) FileSystem { return Dir(path) })
+		})
+		t.Run("FS", func(t *testing.T) {
+			testFileServerNotDirError(t, mode, func(path string) FileSystem { return FS(os.DirFS(path)) })
+		})
 	})
 }
 
-func testFileServerNotDirError(t *testing.T, newfs func(string) FileSystem) {
-	ts := httptest.NewServer(FileServer(newfs("testdata")))
-	defer ts.Close()
+func testFileServerNotDirError(t *testing.T, mode testMode, newfs func(string) FileSystem) {
+	ts := newClientServerTest(t, mode, FileServer(newfs("testdata"))).ts
 
-	res, err := Get(ts.URL + "/index.html/not-a-file")
+	res, err := ts.Client().Get(ts.URL + "/index.html/not-a-file")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -1417,19 +1476,11 @@
 
 // Issue 40940: Ensure that we only accept non-negative suffix-lengths
 // in "Range": "bytes=-N", and should reject "bytes=--2".
-func TestServeFileRejectsInvalidSuffixLengths_h1(t *testing.T) {
-	testServeFileRejectsInvalidSuffixLengths(t, h1Mode)
+func TestServeFileRejectsInvalidSuffixLengths(t *testing.T) {
+	run(t, testServeFileRejectsInvalidSuffixLengths, []testMode{http1Mode, https1Mode, http2Mode})
 }
-func TestServeFileRejectsInvalidSuffixLengths_h2(t *testing.T) {
-	testServeFileRejectsInvalidSuffixLengths(t, h2Mode)
-}
-
-func testServeFileRejectsInvalidSuffixLengths(t *testing.T, h2 bool) {
-	defer afterTest(t)
-	cst := httptest.NewUnstartedServer(FileServer(Dir("testdata")))
-	cst.EnableHTTP2 = h2
-	cst.StartTLS()
-	defer cst.Close()
+func testServeFileRejectsInvalidSuffixLengths(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, FileServer(Dir("testdata"))).ts
 
 	tests := []struct {
 		r        string
diff --git a/src/net/http/h2_bundle.go b/src/net/http/h2_bundle.go
index 53fbe93..1e0b83d 100644
--- a/src/net/http/h2_bundle.go
+++ b/src/net/http/h2_bundle.go
@@ -30,6 +30,7 @@
 	"errors"
 	"fmt"
 	"io"
+	"io/fs"
 	"log"
 	"math"
 	mathrand "math/rand"
@@ -859,7 +860,6 @@
 func (c *http2dialCall) dial(ctx context.Context, addr string) {
 	const singleUse = false // shared conn
 	c.res, c.err = c.p.t.dialClientConn(ctx, addr, singleUse)
-	close(c.done)
 
 	c.p.mu.Lock()
 	delete(c.p.dialing, addr)
@@ -867,6 +867,8 @@
 		c.p.addConnLocked(addr, c.res)
 	}
 	c.p.mu.Unlock()
+
+	close(c.done)
 }
 
 // addConnIfNeeded makes a NewClientConn out of c if a connection for key doesn't
@@ -1351,7 +1353,7 @@
 var http2padZeros = make([]byte, 255) // zeros for padding
 
 // A FrameType is a registered frame type as defined in
-// http://http2.github.io/http2-spec/#rfc.section.11.2
+// https://httpwg.org/specs/rfc7540.html#rfc.section.11.2
 type http2FrameType uint8
 
 const (
@@ -1474,7 +1476,7 @@
 
 // A FrameHeader is the 9 byte header of all HTTP/2 frames.
 //
-// See http://http2.github.io/http2-spec/#FrameHeader
+// See https://httpwg.org/specs/rfc7540.html#FrameHeader
 type http2FrameHeader struct {
 	valid bool // caller can access []byte fields in the Frame
 
@@ -1906,7 +1908,7 @@
 
 // A DataFrame conveys arbitrary, variable-length sequences of octets
 // associated with a stream.
-// See http://http2.github.io/http2-spec/#rfc.section.6.1
+// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.1
 type http2DataFrame struct {
 	http2FrameHeader
 	data []byte
@@ -2029,7 +2031,7 @@
 // endpoints communicate, such as preferences and constraints on peer
 // behavior.
 //
-// See http://http2.github.io/http2-spec/#SETTINGS
+// See https://httpwg.org/specs/rfc7540.html#SETTINGS
 type http2SettingsFrame struct {
 	http2FrameHeader
 	p []byte
@@ -2168,7 +2170,7 @@
 // A PingFrame is a mechanism for measuring a minimal round trip time
 // from the sender, as well as determining whether an idle connection
 // is still functional.
-// See http://http2.github.io/http2-spec/#rfc.section.6.7
+// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.7
 type http2PingFrame struct {
 	http2FrameHeader
 	Data [8]byte
@@ -2201,7 +2203,7 @@
 }
 
 // A GoAwayFrame informs the remote peer to stop creating streams on this connection.
-// See http://http2.github.io/http2-spec/#rfc.section.6.8
+// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.8
 type http2GoAwayFrame struct {
 	http2FrameHeader
 	LastStreamID uint32
@@ -2265,7 +2267,7 @@
 }
 
 // A WindowUpdateFrame is used to implement flow control.
-// See http://http2.github.io/http2-spec/#rfc.section.6.9
+// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.9
 type http2WindowUpdateFrame struct {
 	http2FrameHeader
 	Increment uint32 // never read with high bit set
@@ -2454,7 +2456,7 @@
 }
 
 // A PriorityFrame specifies the sender-advised priority of a stream.
-// See http://http2.github.io/http2-spec/#rfc.section.6.3
+// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.3
 type http2PriorityFrame struct {
 	http2FrameHeader
 	http2PriorityParam
@@ -2524,7 +2526,7 @@
 }
 
 // A RSTStreamFrame allows for abnormal termination of a stream.
-// See http://http2.github.io/http2-spec/#rfc.section.6.4
+// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.4
 type http2RSTStreamFrame struct {
 	http2FrameHeader
 	ErrCode http2ErrCode
@@ -2556,7 +2558,7 @@
 }
 
 // A ContinuationFrame is used to continue a sequence of header block fragments.
-// See http://http2.github.io/http2-spec/#rfc.section.6.10
+// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.10
 type http2ContinuationFrame struct {
 	http2FrameHeader
 	headerFragBuf []byte
@@ -2597,7 +2599,7 @@
 }
 
 // A PushPromiseFrame is used to initiate a server stream.
-// See http://http2.github.io/http2-spec/#rfc.section.6.6
+// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.6
 type http2PushPromiseFrame struct {
 	http2FrameHeader
 	PromiseID     uint32
@@ -3184,7 +3186,14 @@
 		"accept-language",
 		"accept-ranges",
 		"age",
+		"access-control-allow-credentials",
+		"access-control-allow-headers",
+		"access-control-allow-methods",
 		"access-control-allow-origin",
+		"access-control-expose-headers",
+		"access-control-max-age",
+		"access-control-request-headers",
+		"access-control-request-method",
 		"allow",
 		"authorization",
 		"cache-control",
@@ -3210,6 +3219,7 @@
 		"link",
 		"location",
 		"max-forwards",
+		"origin",
 		"proxy-authenticate",
 		"proxy-authorization",
 		"range",
@@ -3225,6 +3235,8 @@
 		"vary",
 		"via",
 		"www-authenticate",
+		"x-forwarded-for",
+		"x-forwarded-proto",
 	}
 	http2commonLowerHeader = make(map[string]string, len(common))
 	http2commonCanonHeader = make(map[string]string, len(common))
@@ -3243,6 +3255,14 @@
 	return http2asciiToLower(v)
 }
 
+func http2canonicalHeader(v string) string {
+	http2buildCommonHeaderMapsOnce()
+	if s, ok := http2commonCanonHeader[v]; ok {
+		return s
+	}
+	return CanonicalHeaderKey(v)
+}
+
 var (
 	http2VerboseLogs    bool
 	http2logFrameWrites bool
@@ -3268,14 +3288,14 @@
 	http2ClientPreface = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
 
 	// SETTINGS_MAX_FRAME_SIZE default
-	// http://http2.github.io/http2-spec/#rfc.section.6.5.2
+	// https://httpwg.org/specs/rfc7540.html#rfc.section.6.5.2
 	http2initialMaxFrameSize = 16384
 
 	// NextProtoTLS is the NPN/ALPN protocol negotiated during
 	// HTTP/2's TLS setup.
 	http2NextProtoTLS = "h2"
 
-	// http://http2.github.io/http2-spec/#SettingValues
+	// https://httpwg.org/specs/rfc7540.html#SettingValues
 	http2initialHeaderTableSize = 4096
 
 	http2initialWindowSize = 65535 // 6.9.2 Initial Flow Control Window Size
@@ -3324,7 +3344,7 @@
 // Setting is a setting parameter: which setting it is, and its value.
 type http2Setting struct {
 	// ID is which setting is being set.
-	// See http://http2.github.io/http2-spec/#SettingValues
+	// See https://httpwg.org/specs/rfc7540.html#SettingFormat
 	ID http2SettingID
 
 	// Val is the value.
@@ -3356,7 +3376,7 @@
 }
 
 // A SettingID is an HTTP/2 setting as defined in
-// http://http2.github.io/http2-spec/#iana-settings
+// https://httpwg.org/specs/rfc7540.html#iana-settings
 type http2SettingID uint16
 
 const (
@@ -3817,6 +3837,19 @@
 	// the HTTP/2 spec's recommendations.
 	MaxConcurrentStreams uint32
 
+	// MaxDecoderHeaderTableSize optionally specifies the http2
+	// SETTINGS_HEADER_TABLE_SIZE to send in the initial settings frame. It
+	// informs the remote endpoint of the maximum size of the header compression
+	// table used to decode header blocks, in octets. If zero, the default value
+	// of 4096 is used.
+	MaxDecoderHeaderTableSize uint32
+
+	// MaxEncoderHeaderTableSize optionally specifies an upper limit for the
+	// header compression table used for encoding request headers. Received
+	// SETTINGS_HEADER_TABLE_SIZE settings are capped at this limit. If zero,
+	// the default value of 4096 is used.
+	MaxEncoderHeaderTableSize uint32
+
 	// MaxReadFrameSize optionally specifies the largest frame
 	// this server is willing to read. A valid value is between
 	// 16k and 16M, inclusive. If zero or otherwise invalid, a
@@ -3862,7 +3895,7 @@
 }
 
 func (s *http2Server) initialConnRecvWindowSize() int32 {
-	if s.MaxUploadBufferPerConnection > http2initialWindowSize {
+	if s.MaxUploadBufferPerConnection >= http2initialWindowSize {
 		return s.MaxUploadBufferPerConnection
 	}
 	return 1 << 20
@@ -3889,6 +3922,20 @@
 	return http2defaultMaxStreams
 }
 
+func (s *http2Server) maxDecoderHeaderTableSize() uint32 {
+	if v := s.MaxDecoderHeaderTableSize; v > 0 {
+		return v
+	}
+	return http2initialHeaderTableSize
+}
+
+func (s *http2Server) maxEncoderHeaderTableSize() uint32 {
+	if v := s.MaxEncoderHeaderTableSize; v > 0 {
+		return v
+	}
+	return http2initialHeaderTableSize
+}
+
 // maxQueuedControlFrames is the maximum number of control frames like
 // SETTINGS, PING and RST_STREAM that will be queued for writing before
 // the connection is closed to prevent memory exhaustion attacks.
@@ -4034,6 +4081,20 @@
 	// requests. If nil, BaseConfig.Handler is used. If BaseConfig
 	// or BaseConfig.Handler is nil, http.DefaultServeMux is used.
 	Handler Handler
+
+	// UpgradeRequest is an initial request received on a connection
+	// undergoing an h2c upgrade. The request body must have been
+	// completely read from the connection before calling ServeConn,
+	// and the 101 Switching Protocols response written.
+	UpgradeRequest *Request
+
+	// Settings is the decoded contents of the HTTP2-Settings header
+	// in an h2c upgrade request.
+	Settings []byte
+
+	// SawClientPreface is set if the HTTP/2 connection preface
+	// has already been read from the connection.
+	SawClientPreface bool
 }
 
 func (o *http2ServeConnOpts) context() context.Context {
@@ -4099,9 +4160,9 @@
 		advMaxStreams:               s.maxConcurrentStreams(),
 		initialStreamSendWindowSize: http2initialWindowSize,
 		maxFrameSize:                http2initialMaxFrameSize,
-		headerTableSize:             http2initialHeaderTableSize,
 		serveG:                      http2newGoroutineLock(),
 		pushEnabled:                 true,
+		sawClientPreface:            opts.SawClientPreface,
 	}
 
 	s.state.registerConn(sc)
@@ -4128,12 +4189,13 @@
 	sc.flow.add(http2initialWindowSize)
 	sc.inflow.add(http2initialWindowSize)
 	sc.hpackEncoder = hpack.NewEncoder(&sc.headerWriteBuf)
+	sc.hpackEncoder.SetMaxDynamicTableSizeLimit(s.maxEncoderHeaderTableSize())
 
 	fr := http2NewFramer(sc.bw, c)
 	if s.CountError != nil {
 		fr.countError = s.CountError
 	}
-	fr.ReadMetaHeaders = hpack.NewDecoder(http2initialHeaderTableSize, nil)
+	fr.ReadMetaHeaders = hpack.NewDecoder(s.maxDecoderHeaderTableSize(), nil)
 	fr.MaxHeaderListSize = sc.maxHeaderListSize()
 	fr.SetMaxReadFrameSize(s.maxReadFrameSize())
 	sc.framer = fr
@@ -4184,9 +4246,27 @@
 		}
 	}
 
+	if opts.Settings != nil {
+		fr := &http2SettingsFrame{
+			http2FrameHeader: http2FrameHeader{valid: true},
+			p:                opts.Settings,
+		}
+		if err := fr.ForeachSetting(sc.processSetting); err != nil {
+			sc.rejectConn(http2ErrCodeProtocol, "invalid settings")
+			return
+		}
+		opts.Settings = nil
+	}
+
 	if hook := http2testHookGetServerConn; hook != nil {
 		hook(sc)
 	}
+
+	if opts.UpgradeRequest != nil {
+		sc.upgradeRequest(opts.UpgradeRequest)
+		opts.UpgradeRequest = nil
+	}
+
 	sc.serve()
 }
 
@@ -4231,6 +4311,7 @@
 	// Everything following is owned by the serve loop; use serveG.check():
 	serveG                      http2goroutineLock // used to verify funcs are on serve()
 	pushEnabled                 bool
+	sawClientPreface            bool // preface has already been read, used in h2c upgrade
 	sawFirstSettings            bool // got the initial SETTINGS frame after the preface
 	needToSendSettingsAck       bool
 	unackedSettings             int    // how many SETTINGS have we sent without ACKs?
@@ -4244,9 +4325,9 @@
 	streams                     map[uint32]*http2stream
 	initialStreamSendWindowSize int32
 	maxFrameSize                int32
-	headerTableSize             uint32
 	peerMaxHeaderListSize       uint32            // zero means unknown (default)
 	canonHeader                 map[string]string // http2-lower-case -> Go-Canonical-Case
+	canonHeaderKeysSize         int               // canonHeader keys size in bytes
 	writingFrame                bool              // started writing a frame (on serve goroutine or separate)
 	writingFrameAsync           bool              // started a frame on its own goroutine but haven't heard back on wroteFrameCh
 	needsFrameFlush             bool              // last frame write wasn't a flush
@@ -4307,7 +4388,9 @@
 	resetQueued      bool        // RST_STREAM queued for write; set by sc.resetStream
 	gotTrailerHeader bool        // HEADER frame for trailers was seen
 	wroteHeaders     bool        // whether we wrote headers (not status 100)
+	readDeadline     *time.Timer // nil if unused
 	writeDeadline    *time.Timer // nil if unused
+	closeErr         error       // set before cw is closed
 
 	trailer    Header // accumulated trailers
 	reqTrailer Header // handler's Request.Trailer
@@ -4426,6 +4509,13 @@
 	}
 }
 
+// maxCachedCanonicalHeadersKeysSize is an arbitrarily-chosen limit on the size
+// of the entries in the canonHeader cache.
+// This should be larger than the size of unique, uncommon header keys likely to
+// be sent by the peer, while not so high as to permit unreasonable memory usage
+// if the peer sends an unbounded number of unique header keys.
+const http2maxCachedCanonicalHeadersKeysSize = 2048
+
 func (sc *http2serverConn) canonicalHeader(v string) string {
 	sc.serveG.check()
 	http2buildCommonHeaderMapsOnce()
@@ -4441,14 +4531,10 @@
 		sc.canonHeader = make(map[string]string)
 	}
 	cv = CanonicalHeaderKey(v)
-	// maxCachedCanonicalHeaders is an arbitrarily-chosen limit on the number of
-	// entries in the canonHeader cache. This should be larger than the number
-	// of unique, uncommon header keys likely to be sent by the peer, while not
-	// so high as to permit unreasonable memory usage if the peer sends an unbounded
-	// number of unique header keys.
-	const maxCachedCanonicalHeaders = 32
-	if len(sc.canonHeader) < maxCachedCanonicalHeaders {
+	size := 100 + len(v)*2 // 100 bytes of map overhead + key + value
+	if sc.canonHeaderKeysSize+size <= http2maxCachedCanonicalHeadersKeysSize {
 		sc.canonHeader[v] = cv
+		sc.canonHeaderKeysSize += size
 	}
 	return cv
 }
@@ -4550,6 +4636,7 @@
 			{http2SettingMaxFrameSize, sc.srv.maxReadFrameSize()},
 			{http2SettingMaxConcurrentStreams, sc.advMaxStreams},
 			{http2SettingMaxHeaderListSize, sc.maxHeaderListSize()},
+			{http2SettingHeaderTableSize, sc.srv.maxDecoderHeaderTableSize()},
 			{http2SettingInitialWindowSize, uint32(sc.srv.initialStreamRecvWindowSize())},
 		},
 	})
@@ -4636,6 +4723,8 @@
 				}
 			case *http2startPushRequest:
 				sc.startPush(v)
+			case func(*http2serverConn):
+				v(sc)
 			default:
 				panic(fmt.Sprintf("unexpected type %T", v))
 			}
@@ -4698,6 +4787,9 @@
 // returns errPrefaceTimeout on timeout, or an error if the greeting
 // is invalid.
 func (sc *http2serverConn) readPreface() error {
+	if sc.sawClientPreface {
+		return nil
+	}
 	errc := make(chan error, 1)
 	go func() {
 		// Read the client preface
@@ -5058,6 +5150,9 @@
 func (sc *http2serverConn) goAway(code http2ErrCode) {
 	sc.serveG.check()
 	if sc.inGoAway {
+		if sc.goAwayCode == http2ErrCodeNo {
+			sc.goAwayCode = code
+		}
 		return
 	}
 	sc.inGoAway = true
@@ -5145,6 +5240,21 @@
 		sc.sawFirstSettings = true
 	}
 
+	// Discard frames for streams initiated after the identified last
+	// stream sent in a GOAWAY, or all frames after sending an error.
+	// We still need to return connection-level flow control for DATA frames.
+	// RFC 9113 Section 6.8.
+	if sc.inGoAway && (sc.goAwayCode != http2ErrCodeNo || f.Header().StreamID > sc.maxClientStreamID) {
+
+		if f, ok := f.(*http2DataFrame); ok {
+			if sc.inflow.available() < int32(f.Length) {
+				return sc.countError("data_flow", http2streamError(f.Header().StreamID, http2ErrCodeFlowControl))
+			}
+			sc.sendWindowUpdate(nil, int(f.Length)) // conn-level
+		}
+		return nil
+	}
+
 	switch f := f.(type) {
 	case *http2SettingsFrame:
 		return sc.processSettings(f)
@@ -5187,9 +5297,6 @@
 		// PROTOCOL_ERROR."
 		return sc.countError("ping_on_stream", http2ConnectionError(http2ErrCodeProtocol))
 	}
-	if sc.inGoAway && sc.goAwayCode != http2ErrCodeNo {
-		return nil
-	}
 	sc.writeFrame(http2FrameWriteRequest{write: http2writePingAck{f}})
 	return nil
 }
@@ -5251,6 +5358,9 @@
 		panic(fmt.Sprintf("invariant; can't close stream in state %v", st.state))
 	}
 	st.state = http2stateClosed
+	if st.readDeadline != nil {
+		st.readDeadline.Stop()
+	}
 	if st.writeDeadline != nil {
 		st.writeDeadline.Stop()
 	}
@@ -5276,6 +5386,14 @@
 
 		p.CloseWithError(err)
 	}
+	if e, ok := err.(http2StreamError); ok {
+		if e.Cause != nil {
+			err = e.Cause
+		} else {
+			err = http2errStreamClosed
+		}
+	}
+	st.closeErr = err
 	st.cw.Close() // signals Handler's CloseNotifier, unblocks writes, etc
 	sc.writeSched.CloseStream(st.id)
 }
@@ -5318,7 +5436,6 @@
 	}
 	switch s.ID {
 	case http2SettingHeaderTableSize:
-		sc.headerTableSize = s.Val
 		sc.hpackEncoder.SetMaxDynamicTableSize(s.Val)
 	case http2SettingEnablePush:
 		sc.pushEnabled = s.Val != 0
@@ -5372,16 +5489,6 @@
 func (sc *http2serverConn) processData(f *http2DataFrame) error {
 	sc.serveG.check()
 	id := f.Header().StreamID
-	if sc.inGoAway && (sc.goAwayCode != http2ErrCodeNo || id > sc.maxClientStreamID) {
-		// Discard all DATA frames if the GOAWAY is due to an
-		// error, or:
-		//
-		// Section 6.8: After sending a GOAWAY frame, the sender
-		// can discard frames for streams initiated by the
-		// receiver with identifiers higher than the identified
-		// last stream.
-		return nil
-	}
 
 	data := f.Data()
 	state, st := sc.state(id)
@@ -5434,6 +5541,12 @@
 
 	// Sender sending more than they'd declared?
 	if st.declBodyBytes != -1 && st.bodyBytes+int64(len(data)) > st.declBodyBytes {
+		if sc.inflow.available() < int32(f.Length) {
+			return sc.countError("data_flow", http2streamError(id, http2ErrCodeFlowControl))
+		}
+		sc.inflow.take(int32(f.Length))
+		sc.sendWindowUpdate(nil, int(f.Length)) // conn-level
+
 		st.body.CloseWithError(fmt.Errorf("sender tried to send more than declared Content-Length of %d bytes", st.declBodyBytes))
 		// RFC 7540, sec 8.1.2.6: A request or response is also malformed if the
 		// value of a content-length header field does not equal the sum of the
@@ -5518,19 +5631,27 @@
 	}
 }
 
+// onReadTimeout is run on its own goroutine (from time.AfterFunc)
+// when the stream's ReadTimeout has fired.
+func (st *http2stream) onReadTimeout() {
+	// Wrap the ErrDeadlineExceeded to avoid callers depending on us
+	// returning the bare error.
+	st.body.CloseWithError(fmt.Errorf("%w", os.ErrDeadlineExceeded))
+}
+
 // onWriteTimeout is run on its own goroutine (from time.AfterFunc)
 // when the stream's WriteTimeout has fired.
 func (st *http2stream) onWriteTimeout() {
-	st.sc.writeFrameFromHandler(http2FrameWriteRequest{write: http2streamError(st.id, http2ErrCodeInternal)})
+	st.sc.writeFrameFromHandler(http2FrameWriteRequest{write: http2StreamError{
+		StreamID: st.id,
+		Code:     http2ErrCodeInternal,
+		Cause:    os.ErrDeadlineExceeded,
+	}})
 }
 
 func (sc *http2serverConn) processHeaders(f *http2MetaHeadersFrame) error {
 	sc.serveG.check()
 	id := f.StreamID
-	if sc.inGoAway {
-		// Ignore.
-		return nil
-	}
 	// http://tools.ietf.org/html/rfc7540#section-5.1.1
 	// Streams initiated by a client MUST use odd-numbered stream
 	// identifiers. [...] An endpoint that receives an unexpected
@@ -5633,12 +5754,35 @@
 	// (in Go 1.8), though. That's a more sane option anyway.
 	if sc.hs.ReadTimeout != 0 {
 		sc.conn.SetReadDeadline(time.Time{})
+		if st.body != nil {
+			st.readDeadline = time.AfterFunc(sc.hs.ReadTimeout, st.onReadTimeout)
+		}
 	}
 
 	go sc.runHandler(rw, req, handler)
 	return nil
 }
 
+func (sc *http2serverConn) upgradeRequest(req *Request) {
+	sc.serveG.check()
+	id := uint32(1)
+	sc.maxClientStreamID = id
+	st := sc.newStream(id, 0, http2stateHalfClosedRemote)
+	st.reqTrailer = req.Trailer
+	if st.reqTrailer != nil {
+		st.trailer = make(Header)
+	}
+	rw := sc.newResponseWriter(st, req)
+
+	// Disable any read deadline set by the net/http package
+	// prior to the upgrade.
+	if sc.hs.ReadTimeout != 0 {
+		sc.conn.SetReadDeadline(time.Time{})
+	}
+
+	go sc.runHandler(rw, req, sc.handler.ServeHTTP)
+}
+
 func (st *http2stream) processTrailerHeaders(f *http2MetaHeadersFrame) error {
 	sc := st.sc
 	sc.serveG.check()
@@ -5681,9 +5825,6 @@
 }
 
 func (sc *http2serverConn) processPriority(f *http2PriorityFrame) error {
-	if sc.inGoAway {
-		return nil
-	}
 	if err := sc.checkPriority(f.StreamID, f.http2PriorityParam); err != nil {
 		return err
 	}
@@ -5757,12 +5898,6 @@
 		return nil, nil, sc.countError("bad_path_method", http2streamError(f.StreamID, http2ErrCodeProtocol))
 	}
 
-	bodyOpen := !f.StreamEnded()
-	if rp.method == "HEAD" && bodyOpen {
-		// HEAD requests can't have bodies
-		return nil, nil, sc.countError("head_body", http2streamError(f.StreamID, http2ErrCodeProtocol))
-	}
-
 	rp.header = make(Header)
 	for _, hf := range f.RegularFields() {
 		rp.header.Add(sc.canonicalHeader(hf.Name), hf.Value)
@@ -5775,6 +5910,7 @@
 	if err != nil {
 		return nil, nil, err
 	}
+	bodyOpen := !f.StreamEnded()
 	if bodyOpen {
 		if vv, ok := rp.header["Content-Length"]; ok {
 			if cl, err := strconv.ParseUint(vv[0], 10, 63); err == nil {
@@ -5869,6 +6005,11 @@
 	}
 	req = req.WithContext(st.ctx)
 
+	rw := sc.newResponseWriter(st, req)
+	return rw, req, nil
+}
+
+func (sc *http2serverConn) newResponseWriter(st *http2stream, req *Request) *http2responseWriter {
 	rws := http2responseWriterStatePool.Get().(*http2responseWriterState)
 	bwSave := rws.bw
 	*rws = http2responseWriterState{} // zero all the fields
@@ -5877,10 +6018,7 @@
 	rws.bw.Reset(http2chunkWriter{rws})
 	rws.stream = st
 	rws.req = req
-	rws.body = body
-
-	rw := &http2responseWriter{rws: rws}
-	return rw, req, nil
+	return &http2responseWriter{rws: rws}
 }
 
 // Run on its own goroutine.
@@ -5888,6 +6026,9 @@
 	didPanic := true
 	defer func() {
 		rw.rws.stream.cancelCtx()
+		if req.MultipartForm != nil {
+			req.MultipartForm.RemoveAll()
+		}
 		if didPanic {
 			e := recover()
 			sc.writeFrameFromHandler(http2FrameWriteRequest{
@@ -5999,7 +6140,7 @@
 	// a larger Read than this. Very unlikely, but we handle it here
 	// rather than elsewhere for now.
 	const maxUint31 = 1<<31 - 1
-	for n >= maxUint31 {
+	for n > maxUint31 {
 		sc.sendWindowUpdate32(st, maxUint31)
 		n -= maxUint31
 	}
@@ -6095,7 +6236,6 @@
 	// immutable within a request:
 	stream *http2stream
 	req    *Request
-	body   *http2requestBody // to close at end of request, if DATA frames didn't
 	conn   *http2serverConn
 
 	// TODO: adjust buffer writing sizes based on server config, frame size updates from peer, etc
@@ -6120,7 +6260,15 @@
 
 type http2chunkWriter struct{ rws *http2responseWriterState }
 
-func (cw http2chunkWriter) Write(p []byte) (n int, err error) { return cw.rws.writeChunk(p) }
+func (cw http2chunkWriter) Write(p []byte) (n int, err error) {
+	n, err = cw.rws.writeChunk(p)
+	if err == http2errStreamClosed {
+		// If writing failed because the stream has been closed,
+		// return the reason it was closed.
+		err = cw.rws.stream.closeErr
+	}
+	return n, err
+}
 
 func (rws *http2responseWriterState) hasTrailers() bool { return len(rws.trailers) > 0 }
 
@@ -6159,6 +6307,10 @@
 		rws.writeHeader(200)
 	}
 
+	if rws.handlerDone {
+		rws.promoteUndeclaredTrailers()
+	}
+
 	isHeadResp := rws.req.Method == "HEAD"
 	if !rws.sentHeader {
 		rws.sentHeader = true
@@ -6230,10 +6382,6 @@
 		return 0, nil
 	}
 
-	if rws.handlerDone {
-		rws.promoteUndeclaredTrailers()
-	}
-
 	// only send trailers if they have actually been defined by the
 	// server handler.
 	hasNonemptyTrailers := rws.hasNonemptyTrailers()
@@ -6314,23 +6462,85 @@
 	}
 }
 
+func (w *http2responseWriter) SetReadDeadline(deadline time.Time) error {
+	st := w.rws.stream
+	if !deadline.IsZero() && deadline.Before(time.Now()) {
+		// If we're setting a deadline in the past, reset the stream immediately
+		// so writes after SetWriteDeadline returns will fail.
+		st.onReadTimeout()
+		return nil
+	}
+	w.rws.conn.sendServeMsg(func(sc *http2serverConn) {
+		if st.readDeadline != nil {
+			if !st.readDeadline.Stop() {
+				// Deadline already exceeded, or stream has been closed.
+				return
+			}
+		}
+		if deadline.IsZero() {
+			st.readDeadline = nil
+		} else if st.readDeadline == nil {
+			st.readDeadline = time.AfterFunc(deadline.Sub(time.Now()), st.onReadTimeout)
+		} else {
+			st.readDeadline.Reset(deadline.Sub(time.Now()))
+		}
+	})
+	return nil
+}
+
+func (w *http2responseWriter) SetWriteDeadline(deadline time.Time) error {
+	st := w.rws.stream
+	if !deadline.IsZero() && deadline.Before(time.Now()) {
+		// If we're setting a deadline in the past, reset the stream immediately
+		// so writes after SetWriteDeadline returns will fail.
+		st.onWriteTimeout()
+		return nil
+	}
+	w.rws.conn.sendServeMsg(func(sc *http2serverConn) {
+		if st.writeDeadline != nil {
+			if !st.writeDeadline.Stop() {
+				// Deadline already exceeded, or stream has been closed.
+				return
+			}
+		}
+		if deadline.IsZero() {
+			st.writeDeadline = nil
+		} else if st.writeDeadline == nil {
+			st.writeDeadline = time.AfterFunc(deadline.Sub(time.Now()), st.onWriteTimeout)
+		} else {
+			st.writeDeadline.Reset(deadline.Sub(time.Now()))
+		}
+	})
+	return nil
+}
+
 func (w *http2responseWriter) Flush() {
+	w.FlushError()
+}
+
+func (w *http2responseWriter) FlushError() error {
 	rws := w.rws
 	if rws == nil {
 		panic("Header called after Handler finished")
 	}
+	var err error
 	if rws.bw.Buffered() > 0 {
-		if err := rws.bw.Flush(); err != nil {
-			// Ignore the error. The frame writer already knows.
-			return
-		}
+		err = rws.bw.Flush()
 	} else {
 		// The bufio.Writer won't call chunkWriter.Write
 		// (writeChunk with zero bytes, so we have to do it
 		// ourselves to force the HTTP response header and/or
 		// final DATA frame (with END_STREAM) to be sent.
-		rws.writeChunk(nil)
+		_, err = http2chunkWriter{rws}.Write(nil)
+		if err == nil {
+			select {
+			case <-rws.stream.cw:
+				err = rws.stream.closeErr
+			default:
+			}
+		}
 	}
+	return err
 }
 
 func (w *http2responseWriter) CloseNotify() <-chan bool {
@@ -6815,13 +7025,23 @@
 // A Transport internally caches connections to servers. It is safe
 // for concurrent use by multiple goroutines.
 type http2Transport struct {
-	// DialTLS specifies an optional dial function for creating
-	// TLS connections for requests.
+	// DialTLSContext specifies an optional dial function with context for
+	// creating TLS connections for requests.
 	//
-	// If DialTLS is nil, tls.Dial is used.
+	// If DialTLSContext and DialTLS is nil, tls.Dial is used.
 	//
 	// If the returned net.Conn has a ConnectionState method like tls.Conn,
 	// it will be used to set http.Response.TLS.
+	DialTLSContext func(ctx context.Context, network, addr string, cfg *tls.Config) (net.Conn, error)
+
+	// DialTLS specifies an optional dial function for creating
+	// TLS connections for requests.
+	//
+	// If DialTLSContext and DialTLS is nil, tls.Dial is used.
+	//
+	// Deprecated: Use DialTLSContext instead, which allows the transport
+	// to cancel dials as soon as they are no longer needed.
+	// If both are set, DialTLSContext takes priority.
 	DialTLS func(network, addr string, cfg *tls.Config) (net.Conn, error)
 
 	// TLSClientConfig specifies the TLS configuration to use with
@@ -6855,6 +7075,28 @@
 	// to mean no limit.
 	MaxHeaderListSize uint32
 
+	// MaxReadFrameSize is the http2 SETTINGS_MAX_FRAME_SIZE to send in the
+	// initial settings frame. It is the size in bytes of the largest frame
+	// payload that the sender is willing to receive. If 0, no setting is
+	// sent, and the value is provided by the peer, which should be 16384
+	// according to the spec:
+	// https://datatracker.ietf.org/doc/html/rfc7540#section-6.5.2.
+	// Values are bounded in the range 16k to 16M.
+	MaxReadFrameSize uint32
+
+	// MaxDecoderHeaderTableSize optionally specifies the http2
+	// SETTINGS_HEADER_TABLE_SIZE to send in the initial settings frame. It
+	// informs the remote endpoint of the maximum size of the header compression
+	// table used to decode header blocks, in octets. If zero, the default value
+	// of 4096 is used.
+	MaxDecoderHeaderTableSize uint32
+
+	// MaxEncoderHeaderTableSize optionally specifies an upper limit for the
+	// header compression table used for encoding request headers. Received
+	// SETTINGS_HEADER_TABLE_SIZE settings are capped at this limit. If zero,
+	// the default value of 4096 is used.
+	MaxEncoderHeaderTableSize uint32
+
 	// StrictMaxConcurrentStreams controls whether the server's
 	// SETTINGS_MAX_CONCURRENT_STREAMS should be respected
 	// globally. If false, new TCP connections are created to the
@@ -6908,6 +7150,19 @@
 	return t.MaxHeaderListSize
 }
 
+func (t *http2Transport) maxFrameReadSize() uint32 {
+	if t.MaxReadFrameSize == 0 {
+		return 0 // use the default provided by the peer
+	}
+	if t.MaxReadFrameSize < http2minMaxFrameSize {
+		return http2minMaxFrameSize
+	}
+	if t.MaxReadFrameSize > http2maxFrameSize {
+		return http2maxFrameSize
+	}
+	return t.MaxReadFrameSize
+}
+
 func (t *http2Transport) disableCompression() bool {
 	return t.DisableCompression || (t.t1 != nil && t.t1.DisableCompression)
 }
@@ -6996,7 +7251,8 @@
 // HTTP/2 server.
 type http2ClientConn struct {
 	t             *http2Transport
-	tconn         net.Conn             // usually *tls.Conn, except specialized impls
+	tconn         net.Conn // usually *tls.Conn, except specialized impls
+	tconnClosed   bool
 	tlsState      *tls.ConnectionState // nil only for specialized impls
 	reused        uint32               // whether conn is being reused; atomic
 	singleUse     bool                 // whether being used for a single http.Request
@@ -7029,10 +7285,11 @@
 	lastActive      time.Time
 	lastIdle        time.Time // time last idle
 	// Settings from peer: (also guarded by wmu)
-	maxFrameSize          uint32
-	maxConcurrentStreams  uint32
-	peerMaxHeaderListSize uint64
-	initialWindowSize     uint32
+	maxFrameSize           uint32
+	maxConcurrentStreams   uint32
+	peerMaxHeaderListSize  uint64
+	peerMaxHeaderTableSize uint32
+	initialWindowSize      uint32
 
 	// reqHeaderMu is a 1-element semaphore channel controlling access to sending new requests.
 	// Write to reqHeaderMu to lock it, read from it to unlock.
@@ -7082,8 +7339,8 @@
 	readErr     error     // sticky read error; owned by transportResponseBody.Read
 
 	reqBody              io.ReadCloser
-	reqBodyContentLength int64 // -1 means unknown
-	reqBodyClosed        bool  // body has been closed; guarded by cc.mu
+	reqBodyContentLength int64         // -1 means unknown
+	reqBodyClosed        chan struct{} // guarded by cc.mu; non-nil on Close, closed when done
 
 	// owned by writeRequest:
 	sentEndStream bool // sent an END_STREAM flag to the peer
@@ -7123,9 +7380,8 @@
 		cs.abortErr = err
 		close(cs.abort)
 	})
-	if cs.reqBody != nil && !cs.reqBodyClosed {
-		cs.reqBody.Close()
-		cs.reqBodyClosed = true
+	if cs.reqBody != nil {
+		cs.closeReqBodyLocked()
 	}
 	// TODO(dneil): Clean up tests where cs.cc.cond is nil.
 	if cs.cc.cond != nil {
@@ -7138,13 +7394,24 @@
 	cc := cs.cc
 	cc.mu.Lock()
 	defer cc.mu.Unlock()
-	if cs.reqBody != nil && !cs.reqBodyClosed {
-		cs.reqBody.Close()
-		cs.reqBodyClosed = true
+	if cs.reqBody != nil && cs.reqBodyClosed == nil {
+		cs.closeReqBodyLocked()
 		cc.cond.Broadcast()
 	}
 }
 
+func (cs *http2clientStream) closeReqBodyLocked() {
+	if cs.reqBodyClosed != nil {
+		return
+	}
+	cs.reqBodyClosed = make(chan struct{})
+	reqBodyClosed := cs.reqBodyClosed
+	go func() {
+		cs.reqBody.Close()
+		close(reqBodyClosed)
+	}()
+}
+
 type http2stickyErrWriter struct {
 	conn    net.Conn
 	timeout time.Duration
@@ -7229,6 +7496,15 @@
 	return net.JoinHostPort(host, port)
 }
 
+var http2retryBackoffHook func(time.Duration) *time.Timer
+
+func http2backoffNewTimer(d time.Duration) *time.Timer {
+	if http2retryBackoffHook != nil {
+		return http2retryBackoffHook(d)
+	}
+	return time.NewTimer(d)
+}
+
 // RoundTripOpt is like RoundTrip, but takes options.
 func (t *http2Transport) RoundTripOpt(req *Request, opt http2RoundTripOpt) (*Response, error) {
 	if !(req.URL.Scheme == "https" || (req.URL.Scheme == "http" && t.AllowHTTP)) {
@@ -7254,11 +7530,14 @@
 				}
 				backoff := float64(uint(1) << (uint(retry) - 1))
 				backoff += backoff * (0.1 * mathrand.Float64())
+				d := time.Second * time.Duration(backoff)
+				timer := http2backoffNewTimer(d)
 				select {
-				case <-time.After(time.Second * time.Duration(backoff)):
+				case <-timer.C:
 					t.vlogf("RoundTrip retrying after failure: %v", err)
 					continue
 				case <-req.Context().Done():
+					timer.Stop()
 					err = req.Context().Err()
 				}
 			}
@@ -7341,7 +7620,7 @@
 	if err != nil {
 		return nil, err
 	}
-	tconn, err := t.dialTLS(ctx)("tcp", addr, t.newTLSConfig(host))
+	tconn, err := t.dialTLS(ctx, "tcp", addr, t.newTLSConfig(host))
 	if err != nil {
 		return nil, err
 	}
@@ -7362,24 +7641,25 @@
 	return cfg
 }
 
-func (t *http2Transport) dialTLS(ctx context.Context) func(string, string, *tls.Config) (net.Conn, error) {
-	if t.DialTLS != nil {
-		return t.DialTLS
+func (t *http2Transport) dialTLS(ctx context.Context, network, addr string, tlsCfg *tls.Config) (net.Conn, error) {
+	if t.DialTLSContext != nil {
+		return t.DialTLSContext(ctx, network, addr, tlsCfg)
+	} else if t.DialTLS != nil {
+		return t.DialTLS(network, addr, tlsCfg)
 	}
-	return func(network, addr string, cfg *tls.Config) (net.Conn, error) {
-		tlsCn, err := t.dialTLSWithContext(ctx, network, addr, cfg)
-		if err != nil {
-			return nil, err
-		}
-		state := tlsCn.ConnectionState()
-		if p := state.NegotiatedProtocol; p != http2NextProtoTLS {
-			return nil, fmt.Errorf("http2: unexpected ALPN protocol %q; want %q", p, http2NextProtoTLS)
-		}
-		if !state.NegotiatedProtocolIsMutual {
-			return nil, errors.New("http2: could not negotiate protocol mutually")
-		}
-		return tlsCn, nil
+
+	tlsCn, err := t.dialTLSWithContext(ctx, network, addr, tlsCfg)
+	if err != nil {
+		return nil, err
 	}
+	state := tlsCn.ConnectionState()
+	if p := state.NegotiatedProtocol; p != http2NextProtoTLS {
+		return nil, fmt.Errorf("http2: unexpected ALPN protocol %q; want %q", p, http2NextProtoTLS)
+	}
+	if !state.NegotiatedProtocolIsMutual {
+		return nil, errors.New("http2: could not negotiate protocol mutually")
+	}
+	return tlsCn, nil
 }
 
 // disableKeepAlives reports whether connections should be closed as
@@ -7395,6 +7675,20 @@
 	return t.t1.ExpectContinueTimeout
 }
 
+func (t *http2Transport) maxDecoderHeaderTableSize() uint32 {
+	if v := t.MaxDecoderHeaderTableSize; v > 0 {
+		return v
+	}
+	return http2initialHeaderTableSize
+}
+
+func (t *http2Transport) maxEncoderHeaderTableSize() uint32 {
+	if v := t.MaxEncoderHeaderTableSize; v > 0 {
+		return v
+	}
+	return http2initialHeaderTableSize
+}
+
 func (t *http2Transport) NewClientConn(c net.Conn) (*http2ClientConn, error) {
 	return t.newClientConn(c, t.disableKeepAlives())
 }
@@ -7435,15 +7729,19 @@
 	})
 	cc.br = bufio.NewReader(c)
 	cc.fr = http2NewFramer(cc.bw, cc.br)
+	if t.maxFrameReadSize() != 0 {
+		cc.fr.SetMaxReadFrameSize(t.maxFrameReadSize())
+	}
 	if t.CountError != nil {
 		cc.fr.countError = t.CountError
 	}
-	cc.fr.ReadMetaHeaders = hpack.NewDecoder(http2initialHeaderTableSize, nil)
+	maxHeaderTableSize := t.maxDecoderHeaderTableSize()
+	cc.fr.ReadMetaHeaders = hpack.NewDecoder(maxHeaderTableSize, nil)
 	cc.fr.MaxHeaderListSize = t.maxHeaderListSize()
 
-	// TODO: SetMaxDynamicTableSize, SetMaxDynamicTableSizeLimit on
-	// henc in response to SETTINGS frames?
 	cc.henc = hpack.NewEncoder(&cc.hbuf)
+	cc.henc.SetMaxDynamicTableSizeLimit(t.maxEncoderHeaderTableSize())
+	cc.peerMaxHeaderTableSize = http2initialHeaderTableSize
 
 	if t.AllowHTTP {
 		cc.nextStreamID = 3
@@ -7458,9 +7756,15 @@
 		{ID: http2SettingEnablePush, Val: 0},
 		{ID: http2SettingInitialWindowSize, Val: http2transportDefaultStreamFlow},
 	}
+	if max := t.maxFrameReadSize(); max != 0 {
+		initialSettings = append(initialSettings, http2Setting{ID: http2SettingMaxFrameSize, Val: max})
+	}
 	if max := t.maxHeaderListSize(); max != 0 {
 		initialSettings = append(initialSettings, http2Setting{ID: http2SettingMaxHeaderListSize, Val: max})
 	}
+	if maxHeaderTableSize != http2initialHeaderTableSize {
+		initialSettings = append(initialSettings, http2Setting{ID: http2SettingHeaderTableSize, Val: maxHeaderTableSize})
+	}
 
 	cc.bw.Write(http2clientPreface)
 	cc.fr.WriteSettings(initialSettings...)
@@ -7659,10 +7963,10 @@
 	cc.closeIfIdle()
 }
 
-func (cc *http2ClientConn) closeConn() error {
+func (cc *http2ClientConn) closeConn() {
 	t := time.AfterFunc(250*time.Millisecond, cc.forceCloseConn)
 	defer t.Stop()
-	return cc.tconn.Close()
+	cc.tconn.Close()
 }
 
 // A tls.Conn.Close can hang for a long time if the peer is unresponsive.
@@ -7728,7 +8032,8 @@
 	http2shutdownEnterWaitStateHook()
 	select {
 	case <-done:
-		return cc.closeConn()
+		cc.closeConn()
+		return nil
 	case <-ctx.Done():
 		cc.mu.Lock()
 		// Free the goroutine above
@@ -7765,7 +8070,7 @@
 
 // closes the client connection immediately. In-flight requests are interrupted.
 // err is sent to streams.
-func (cc *http2ClientConn) closeForError(err error) error {
+func (cc *http2ClientConn) closeForError(err error) {
 	cc.mu.Lock()
 	cc.closed = true
 	for _, cs := range cc.streams {
@@ -7773,7 +8078,7 @@
 	}
 	cc.cond.Broadcast()
 	cc.mu.Unlock()
-	return cc.closeConn()
+	cc.closeConn()
 }
 
 // Close closes the client connection immediately.
@@ -7781,16 +8086,17 @@
 // In-flight requests are interrupted. For a graceful shutdown, use Shutdown instead.
 func (cc *http2ClientConn) Close() error {
 	err := errors.New("http2: client connection force closed via ClientConn.Close")
-	return cc.closeForError(err)
+	cc.closeForError(err)
+	return nil
 }
 
 // closes the client connection immediately. In-flight requests are interrupted.
-func (cc *http2ClientConn) closeForLostPing() error {
+func (cc *http2ClientConn) closeForLostPing() {
 	err := errors.New("http2: client connection lost")
 	if f := cc.t.CountError; f != nil {
 		f("conn_close_lost_ping")
 	}
-	return cc.closeForError(err)
+	cc.closeForError(err)
 }
 
 // errRequestCanceled is a copy of net/http's errRequestCanceled because it's not
@@ -7800,7 +8106,7 @@
 func http2commaSeparatedTrailers(req *Request) (string, error) {
 	keys := make([]string, 0, len(req.Trailer))
 	for k := range req.Trailer {
-		k = CanonicalHeaderKey(k)
+		k = http2canonicalHeader(k)
 		switch k {
 		case "Transfer-Encoding", "Trailer", "Content-Length":
 			return "", fmt.Errorf("invalid Trailer key %q", k)
@@ -8168,11 +8474,19 @@
 	// and in multiple cases: server replies <=299 and >299
 	// while still writing request body
 	cc.mu.Lock()
+	mustCloseBody := false
+	if cs.reqBody != nil && cs.reqBodyClosed == nil {
+		mustCloseBody = true
+		cs.reqBodyClosed = make(chan struct{})
+	}
 	bodyClosed := cs.reqBodyClosed
-	cs.reqBodyClosed = true
 	cc.mu.Unlock()
-	if !bodyClosed && cs.reqBody != nil {
+	if mustCloseBody {
 		cs.reqBody.Close()
+		close(bodyClosed)
+	}
+	if bodyClosed != nil {
+		<-bodyClosed
 	}
 
 	if err != nil && cs.sentEndStream {
@@ -8329,7 +8643,7 @@
 
 	var sawEOF bool
 	for !sawEOF {
-		n, err := body.Read(buf[:len(buf)])
+		n, err := body.Read(buf)
 		if hasContentLen {
 			remainLen -= int64(n)
 			if remainLen == 0 && err == nil {
@@ -8352,7 +8666,7 @@
 		}
 		if err != nil {
 			cc.mu.Lock()
-			bodyClosed := cs.reqBodyClosed
+			bodyClosed := cs.reqBodyClosed != nil
 			cc.mu.Unlock()
 			switch {
 			case bodyClosed:
@@ -8447,7 +8761,7 @@
 		if cc.closed {
 			return 0, http2errClientConnClosed
 		}
-		if cs.reqBodyClosed {
+		if cs.reqBodyClosed != nil {
 			return 0, http2errStopReqBodyWrite
 		}
 		select {
@@ -8632,7 +8946,7 @@
 
 	// Header list size is ok. Write the headers.
 	enumerateHeaders(func(name, value string) {
-		name, ascii := http2asciiToLower(name)
+		name, ascii := http2lowerHeader(name)
 		if !ascii {
 			// Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header
 			// field names have to be ASCII characters (just as in HTTP/1.x).
@@ -8685,7 +8999,7 @@
 	}
 
 	for k, vv := range trailer {
-		lowKey, ascii := http2asciiToLower(k)
+		lowKey, ascii := http2lowerHeader(k)
 		if !ascii {
 			// Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header
 			// field names have to be ASCII characters (just as in HTTP/1.x).
@@ -8743,7 +9057,7 @@
 	// wake up RoundTrip if there is a pending request.
 	cc.cond.Broadcast()
 
-	closeOnIdle := cc.singleUse || cc.doNotReuse || cc.t.disableKeepAlives()
+	closeOnIdle := cc.singleUse || cc.doNotReuse || cc.t.disableKeepAlives() || cc.goAway != nil
 	if closeOnIdle && cc.streamsReserved == 0 && len(cc.streams) == 0 {
 		if http2VerboseLogs {
 			cc.vlogf("http2: Transport closing idle conn %p (forSingleUse=%v, maxStream=%v)", cc, cc.singleUse, cc.nextStreamID-2)
@@ -8819,6 +9133,7 @@
 		err = io.ErrUnexpectedEOF
 	}
 	cc.closed = true
+
 	for _, cs := range cc.streams {
 		select {
 		case <-cs.peerClosed:
@@ -9017,7 +9332,7 @@
 		Status:     status + " " + StatusText(statusCode),
 	}
 	for _, hf := range regularFields {
-		key := CanonicalHeaderKey(hf.Name)
+		key := http2canonicalHeader(hf.Name)
 		if key == "Trailer" {
 			t := res.Trailer
 			if t == nil {
@@ -9025,7 +9340,7 @@
 				res.Trailer = t
 			}
 			http2foreachHeaderElement(hf.Value, func(v string) {
-				t[CanonicalHeaderKey(v)] = nil
+				t[http2canonicalHeader(v)] = nil
 			})
 		} else {
 			vv := header[key]
@@ -9130,7 +9445,7 @@
 
 	trailer := make(Header)
 	for _, hf := range f.RegularFields() {
-		key := CanonicalHeaderKey(hf.Name)
+		key := http2canonicalHeader(hf.Name)
 		trailer[key] = append(trailer[key], hf.Value)
 	}
 	cs.trailer = trailer
@@ -9412,7 +9727,6 @@
 		if fn := cc.t.CountError; fn != nil {
 			fn("recv_goaway_" + f.ErrCode.stringToken())
 		}
-
 	}
 	cc.setGoAway(f)
 	return nil
@@ -9477,8 +9791,10 @@
 			cc.cond.Broadcast()
 
 			cc.initialWindowSize = s.Val
+		case http2SettingHeaderTableSize:
+			cc.henc.SetMaxDynamicTableSize(s.Val)
+			cc.peerMaxHeaderTableSize = s.Val
 		default:
-			// TODO(bradfitz): handle more settings? SETTINGS_HEADER_TABLE_SIZE probably.
 			cc.vlogf("Unhandled Setting: %v", s)
 		}
 		return nil
@@ -9705,7 +10021,11 @@
 }
 
 func (gz *http2gzipReader) Close() error {
-	return gz.body.Close()
+	if err := gz.body.Close(); err != nil {
+		return err
+	}
+	gz.zerr = fs.ErrClosed
+	return nil
 }
 
 type http2errorReader struct{ err error }
@@ -9769,7 +10089,7 @@
 	cc.mu.Lock()
 	ci.WasIdle = len(cc.streams) == 0 && reused
 	if ci.WasIdle && !cc.lastActive.IsZero() {
-		ci.IdleTime = time.Now().Sub(cc.lastActive)
+		ci.IdleTime = time.Since(cc.lastActive)
 	}
 	cc.mu.Unlock()
 
@@ -10782,16 +11102,15 @@
 
 func (ws *http2priorityWriteScheduler) Push(wr http2FrameWriteRequest) {
 	var n *http2priorityNode
-	if id := wr.StreamID(); id == 0 {
+	if wr.isControl() {
 		n = &ws.root
 	} else {
+		id := wr.StreamID()
 		n = ws.nodes[id]
 		if n == nil {
 			// id is an idle or closed stream. wr should not be a HEADERS or
-			// DATA frame. However, wr can be a RST_STREAM. In this case, we
-			// push wr onto the root, rather than creating a new priorityNode,
-			// since RST_STREAM is tiny and the stream's priority is unknown
-			// anyway. See issue #17919.
+			// DATA frame. In other case, we push wr onto the root, rather
+			// than creating a new priorityNode.
 			if wr.DataSize() > 0 {
 				panic("add DATA on non-open stream")
 			}
diff --git a/src/net/http/h2_error.go b/src/net/http/h2_error.go
new file mode 100644
index 0000000..0391d31
--- /dev/null
+++ b/src/net/http/h2_error.go
@@ -0,0 +1,38 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !nethttpomithttp2
+// +build !nethttpomithttp2
+
+package http
+
+import (
+	"reflect"
+)
+
+func (e http2StreamError) As(target any) bool {
+	dst := reflect.ValueOf(target).Elem()
+	dstType := dst.Type()
+	if dstType.Kind() != reflect.Struct {
+		return false
+	}
+	src := reflect.ValueOf(e)
+	srcType := src.Type()
+	numField := srcType.NumField()
+	if dstType.NumField() != numField {
+		return false
+	}
+	for i := 0; i < numField; i++ {
+		sf := srcType.Field(i)
+		df := dstType.Field(i)
+		if sf.Name != df.Name || !sf.Type.ConvertibleTo(df.Type) {
+			return false
+		}
+	}
+	for i := 0; i < numField; i++ {
+		df := dst.Field(i)
+		df.Set(src.Field(i).Convert(df.Type()))
+	}
+	return true
+}
diff --git a/src/net/http/h2_error_test.go b/src/net/http/h2_error_test.go
new file mode 100644
index 0000000..0d85e2f
--- /dev/null
+++ b/src/net/http/h2_error_test.go
@@ -0,0 +1,44 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !nethttpomithttp2
+// +build !nethttpomithttp2
+
+package http
+
+import (
+	"errors"
+	"fmt"
+	"testing"
+)
+
+type externalStreamErrorCode uint32
+
+type externalStreamError struct {
+	StreamID uint32
+	Code     externalStreamErrorCode
+	Cause    error
+}
+
+func (e externalStreamError) Error() string {
+	return fmt.Sprintf("ID %v, code %v", e.StreamID, e.Code)
+}
+
+func TestStreamError(t *testing.T) {
+	var target externalStreamError
+	streamErr := http2streamError(42, http2ErrCodeProtocol)
+	ok := errors.As(streamErr, &target)
+	if !ok {
+		t.Fatalf("errors.As failed")
+	}
+	if target.StreamID != streamErr.StreamID {
+		t.Errorf("got StreamID %v, expected %v", target.StreamID, streamErr.StreamID)
+	}
+	if target.Cause != streamErr.Cause {
+		t.Errorf("got Cause %v, expected %v", target.Cause, streamErr.Cause)
+	}
+	if uint32(target.Code) != uint32(streamErr.Code) {
+		t.Errorf("got Code %v, expected %v", target.Code, streamErr.Code)
+	}
+}
diff --git a/src/net/http/header_test.go b/src/net/http/header_test.go
index 0b13d31..e98cc5c 100644
--- a/src/net/http/header_test.go
+++ b/src/net/http/header_test.go
@@ -9,6 +9,7 @@
 	"internal/race"
 	"reflect"
 	"runtime"
+	"strings"
 	"testing"
 	"time"
 )
@@ -105,7 +106,7 @@
 }
 
 func TestHeaderWrite(t *testing.T) {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	for i, test := range headerWriteTests {
 		test.h.WriteSubset(&buf, test.exclude)
 		if buf.String() != test.expected {
diff --git a/src/net/http/httptrace/trace_test.go b/src/net/http/httptrace/trace_test.go
index bb57ada..6efa1f7 100644
--- a/src/net/http/httptrace/trace_test.go
+++ b/src/net/http/httptrace/trace_test.go
@@ -5,13 +5,13 @@
 package httptrace
 
 import (
-	"bytes"
 	"context"
+	"strings"
 	"testing"
 )
 
 func TestWithClientTrace(t *testing.T) {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	connectStart := func(b byte) func(network, addr string) {
 		return func(network, addr string) {
 			buf.WriteByte(b)
@@ -37,7 +37,7 @@
 }
 
 func TestCompose(t *testing.T) {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	var testNum int
 
 	connectStart := func(b byte) func(network, addr string) {
diff --git a/src/net/http/httputil/dump.go b/src/net/http/httputil/dump.go
index d7baecd..7affe5e 100644
--- a/src/net/http/httputil/dump.go
+++ b/src/net/http/httputil/dump.go
@@ -59,7 +59,7 @@
 	return len(p), nil
 }
 
-// outGoingLength is a copy of the unexported
+// outgoingLength is a copy of the unexported
 // (*http.Request).outgoingLength method.
 func outgoingLength(req *http.Request) int64 {
 	if req.Body == nil || req.Body == http.NoBody {
@@ -258,9 +258,6 @@
 	if len(req.TransferEncoding) > 0 {
 		fmt.Fprintf(&b, "Transfer-Encoding: %s\r\n", strings.Join(req.TransferEncoding, ","))
 	}
-	if req.Close {
-		fmt.Fprintf(&b, "Connection: close\r\n")
-	}
 
 	err = req.Header.WriteSubset(&b, reqWriteExcludeHeaderDump)
 	if err != nil {
diff --git a/src/net/http/httputil/dump_test.go b/src/net/http/httputil/dump_test.go
index 5df2ee8..c20c054 100644
--- a/src/net/http/httputil/dump_test.go
+++ b/src/net/http/httputil/dump_test.go
@@ -236,6 +236,19 @@
 			"Transfer-Encoding: chunked\r\n" +
 			"Accept-Encoding: gzip\r\n\r\n",
 	},
+
+	// Issue 54616: request with Connection header doesn't result in duplicate header.
+	{
+		GetReq: func() *http.Request {
+			return mustReadRequest("GET / HTTP/1.1\r\n" +
+				"Host: example.com\r\n" +
+				"Connection: close\r\n\r\n")
+		},
+		NoBody: true,
+		WantDump: "GET / HTTP/1.1\r\n" +
+			"Host: example.com\r\n" +
+			"Connection: close\r\n\r\n",
+	},
 }
 
 func TestDumpRequest(t *testing.T) {
@@ -510,7 +523,7 @@
 		select {
 		case <-out:
 		case <-time.After(timeout):
-			b := &bytes.Buffer{}
+			b := &strings.Builder{}
 			fmt.Fprintf(b, "deadlock detected on iteration %d after %s with delay: %v\n", i, timeout, delay)
 			pprof.Lookup("goroutine").WriteTo(b, 1)
 			t.Fatal(b.String())
diff --git a/src/net/http/httputil/example_test.go b/src/net/http/httputil/example_test.go
index b77a243..6c107f8 100644
--- a/src/net/http/httputil/example_test.go
+++ b/src/net/http/httputil/example_test.go
@@ -103,7 +103,12 @@
 	if err != nil {
 		log.Fatal(err)
 	}
-	frontendProxy := httptest.NewServer(httputil.NewSingleHostReverseProxy(rpURL))
+	frontendProxy := httptest.NewServer(&httputil.ReverseProxy{
+		Rewrite: func(r *httputil.ProxyRequest) {
+			r.SetXForwarded()
+			r.SetURL(rpURL)
+		},
+	})
 	defer frontendProxy.Close()
 
 	resp, err := http.Get(frontendProxy.URL)
diff --git a/src/net/http/httputil/reverseproxy.go b/src/net/http/httputil/reverseproxy.go
index b5d3ce7..58064a5 100644
--- a/src/net/http/httputil/reverseproxy.go
+++ b/src/net/http/httputil/reverseproxy.go
@@ -8,12 +8,14 @@
 
 import (
 	"context"
+	"errors"
 	"fmt"
 	"io"
 	"log"
 	"mime"
 	"net"
 	"net/http"
+	"net/http/httptrace"
 	"net/http/internal/ascii"
 	"net/textproto"
 	"net/url"
@@ -24,29 +26,132 @@
 	"golang.org/x/net/http/httpguts"
 )
 
+// A ProxyRequest contains a request to be rewritten by a ReverseProxy.
+type ProxyRequest struct {
+	// In is the request received by the proxy.
+	// The Rewrite function must not modify In.
+	In *http.Request
+
+	// Out is the request which will be sent by the proxy.
+	// The Rewrite function may modify or replace this request.
+	// Hop-by-hop headers are removed from this request
+	// before Rewrite is called.
+	Out *http.Request
+}
+
+// SetURL routes the outbound request to the scheme, host, and base path
+// provided in target. If the target's path is "/base" and the incoming
+// request was for "/dir", the target request will be for "/base/dir".
+//
+// SetURL rewrites the outbound Host header to match the target's host.
+// To preserve the inbound request's Host header (the default behavior
+// of NewSingleHostReverseProxy):
+//
+//	rewriteFunc := func(r *httputil.ProxyRequest) {
+//		r.SetURL(url)
+//		r.Out.Host = r.In.Host
+//	}
+func (r *ProxyRequest) SetURL(target *url.URL) {
+	rewriteRequestURL(r.Out, target)
+	r.Out.Host = ""
+}
+
+// SetXForwarded sets the X-Forwarded-For, X-Forwarded-Host, and
+// X-Forwarded-Proto headers of the outbound request.
+//
+//   - The X-Forwarded-For header is set to the client IP address.
+//   - The X-Forwarded-Host header is set to the host name requested
+//     by the client.
+//   - The X-Forwarded-Proto header is set to "http" or "https", depending
+//     on whether the inbound request was made on a TLS-enabled connection.
+//
+// If the outbound request contains an existing X-Forwarded-For header,
+// SetXForwarded appends the client IP address to it. To append to the
+// inbound request's X-Forwarded-For header (the default behavior of
+// ReverseProxy when using a Director function), copy the header
+// from the inbound request before calling SetXForwarded:
+//
+//	rewriteFunc := func(r *httputil.ProxyRequest) {
+//		r.Out.Header["X-Forwarded-For"] = r.In.Header["X-Forwarded-For"]
+//		r.SetXForwarded()
+//	}
+func (r *ProxyRequest) SetXForwarded() {
+	clientIP, _, err := net.SplitHostPort(r.In.RemoteAddr)
+	if err == nil {
+		prior := r.Out.Header["X-Forwarded-For"]
+		if len(prior) > 0 {
+			clientIP = strings.Join(prior, ", ") + ", " + clientIP
+		}
+		r.Out.Header.Set("X-Forwarded-For", clientIP)
+	} else {
+		r.Out.Header.Del("X-Forwarded-For")
+	}
+	r.Out.Header.Set("X-Forwarded-Host", r.In.Host)
+	if r.In.TLS == nil {
+		r.Out.Header.Set("X-Forwarded-Proto", "http")
+	} else {
+		r.Out.Header.Set("X-Forwarded-Proto", "https")
+	}
+}
+
 // ReverseProxy is an HTTP Handler that takes an incoming request and
 // sends it to another server, proxying the response back to the
 // client.
 //
-// ReverseProxy by default sets the client IP as the value of the
-// X-Forwarded-For header.
-//
-// If an X-Forwarded-For header already exists, the client IP is
-// appended to the existing values. As a special case, if the header
-// exists in the Request.Header map but has a nil value (such as when
-// set by the Director func), the X-Forwarded-For header is
-// not modified.
-//
-// To prevent IP spoofing, be sure to delete any pre-existing
-// X-Forwarded-For header coming from the client or
-// an untrusted proxy.
+// 1xx responses are forwarded to the client if the underlying
+// transport supports ClientTrace.Got1xxResponse.
 type ReverseProxy struct {
-	// Director must be a function which modifies
+	// Rewrite must be a function which modifies
+	// the request into a new request to be sent
+	// using Transport. Its response is then copied
+	// back to the original client unmodified.
+	// Rewrite must not access the provided ProxyRequest
+	// or its contents after returning.
+	//
+	// The Forwarded, X-Forwarded, X-Forwarded-Host,
+	// and X-Forwarded-Proto headers are removed from the
+	// outbound request before Rewrite is called. See also
+	// the ProxyRequest.SetXForwarded method.
+	//
+	// Unparsable query parameters are removed from the
+	// outbound request before Rewrite is called.
+	// The Rewrite function may copy the inbound URL's
+	// RawQuery to the outbound URL to preserve the original
+	// parameter string. Note that this can lead to security
+	// issues if the proxy's interpretation of query parameters
+	// does not match that of the downstream server.
+	//
+	// At most one of Rewrite or Director may be set.
+	Rewrite func(*ProxyRequest)
+
+	// Director is a function which modifies
 	// the request into a new request to be sent
 	// using Transport. Its response is then copied
 	// back to the original client unmodified.
 	// Director must not access the provided Request
 	// after returning.
+	//
+	// By default, the X-Forwarded-For header is set to the
+	// value of the client IP address. If an X-Forwarded-For
+	// header already exists, the client IP is appended to the
+	// existing values. As a special case, if the header
+	// exists in the Request.Header map but has a nil value
+	// (such as when set by the Director func), the X-Forwarded-For
+	// header is not modified.
+	//
+	// To prevent IP spoofing, be sure to delete any pre-existing
+	// X-Forwarded-For header coming from the client or
+	// an untrusted proxy.
+	//
+	// Hop-by-hop headers are removed from the request after
+	// Director returns, which can remove headers added by
+	// Director. Use a Rewrite function instead to ensure
+	// modifications to the request are preserved.
+	//
+	// Unparsable query parameters are removed from the outbound
+	// request if Request.Form is set after Director returns.
+	//
+	// At most one of Rewrite or Director may be set.
 	Director func(*http.Request)
 
 	// The transport used to perform proxy requests.
@@ -138,28 +243,41 @@
 // URLs to the scheme, host, and base path provided in target. If the
 // target's path is "/base" and the incoming request was for "/dir",
 // the target request will be for /base/dir.
+//
 // NewSingleHostReverseProxy does not rewrite the Host header.
-// To rewrite Host headers, use ReverseProxy directly with a custom
-// Director policy.
+//
+// To customize the ReverseProxy behavior beyond what
+// NewSingleHostReverseProxy provides, use ReverseProxy directly
+// with a Rewrite function. The ProxyRequest SetURL method
+// may be used to route the outbound request. (Note that SetURL,
+// unlike NewSingleHostReverseProxy, rewrites the Host header
+// of the outbound request by default.)
+//
+//	proxy := &ReverseProxy{
+//		Rewrite: func(r *ProxyRequest) {
+//			r.SetURL(target)
+//			r.Out.Host = r.In.Host // if desired
+//		}
+//	}
 func NewSingleHostReverseProxy(target *url.URL) *ReverseProxy {
-	targetQuery := target.RawQuery
 	director := func(req *http.Request) {
-		req.URL.Scheme = target.Scheme
-		req.URL.Host = target.Host
-		req.URL.Path, req.URL.RawPath = joinURLPath(target, req.URL)
-		if targetQuery == "" || req.URL.RawQuery == "" {
-			req.URL.RawQuery = targetQuery + req.URL.RawQuery
-		} else {
-			req.URL.RawQuery = targetQuery + "&" + req.URL.RawQuery
-		}
-		if _, ok := req.Header["User-Agent"]; !ok {
-			// explicitly disable User-Agent so it's not set to default value
-			req.Header.Set("User-Agent", "")
-		}
+		rewriteRequestURL(req, target)
 	}
 	return &ReverseProxy{Director: director}
 }
 
+func rewriteRequestURL(req *http.Request, target *url.URL) {
+	targetQuery := target.RawQuery
+	req.URL.Scheme = target.Scheme
+	req.URL.Host = target.Host
+	req.URL.Path, req.URL.RawPath = joinURLPath(target, req.URL)
+	if targetQuery == "" || req.URL.RawQuery == "" {
+		req.URL.RawQuery = targetQuery + req.URL.RawQuery
+	} else {
+		req.URL.RawQuery = targetQuery + "&" + req.URL.RawQuery
+	}
+}
+
 func copyHeader(dst, src http.Header) {
 	for k, vv := range src {
 		for _, v := range vv {
@@ -260,7 +378,17 @@
 		outreq.Header = make(http.Header) // Issue 33142: historical behavior was to always allocate
 	}
 
-	p.Director(outreq)
+	if (p.Director != nil) == (p.Rewrite != nil) {
+		p.getErrorHandler()(rw, req, errors.New("ReverseProxy must have exactly one of Director or Rewrite set"))
+		return
+	}
+
+	if p.Director != nil {
+		p.Director(outreq)
+		if outreq.Form != nil {
+			outreq.URL.RawQuery = cleanQueryParams(outreq.URL.RawQuery)
+		}
+	}
 	outreq.Close = false
 
 	reqUpType := upgradeType(outreq.Header)
@@ -268,20 +396,13 @@
 		p.getErrorHandler()(rw, req, fmt.Errorf("client tried to switch to invalid protocol %q", reqUpType))
 		return
 	}
-	removeConnectionHeaders(outreq.Header)
-
-	// Remove hop-by-hop headers to the backend. Especially
-	// important is "Connection" because we want a persistent
-	// connection, regardless of what the client sent to us.
-	for _, h := range hopHeaders {
-		outreq.Header.Del(h)
-	}
+	removeHopByHopHeaders(outreq.Header)
 
 	// Issue 21096: tell backend applications that care about trailer support
 	// that we support trailers. (We do, but we don't go out of our way to
 	// advertise that unless the incoming client request thought it was worth
 	// mentioning.) Note that we look at req.Header, not outreq.Header, since
-	// the latter has passed through removeConnectionHeaders.
+	// the latter has passed through removeHopByHopHeaders.
 	if httpguts.HeaderValuesContainsToken(req.Header["Te"], "trailers") {
 		outreq.Header.Set("Te", "trailers")
 	}
@@ -293,20 +414,62 @@
 		outreq.Header.Set("Upgrade", reqUpType)
 	}
 
-	if clientIP, _, err := net.SplitHostPort(req.RemoteAddr); err == nil {
-		// If we aren't the first proxy retain prior
-		// X-Forwarded-For information as a comma+space
-		// separated list and fold multiple headers into one.
-		prior, ok := outreq.Header["X-Forwarded-For"]
-		omit := ok && prior == nil // Issue 38079: nil now means don't populate the header
-		if len(prior) > 0 {
-			clientIP = strings.Join(prior, ", ") + ", " + clientIP
+	if p.Rewrite != nil {
+		// Strip client-provided forwarding headers.
+		// The Rewrite func may use SetXForwarded to set new values
+		// for these or copy the previous values from the inbound request.
+		outreq.Header.Del("Forwarded")
+		outreq.Header.Del("X-Forwarded-For")
+		outreq.Header.Del("X-Forwarded-Host")
+		outreq.Header.Del("X-Forwarded-Proto")
+
+		// Remove unparsable query parameters from the outbound request.
+		outreq.URL.RawQuery = cleanQueryParams(outreq.URL.RawQuery)
+
+		pr := &ProxyRequest{
+			In:  req,
+			Out: outreq,
 		}
-		if !omit {
-			outreq.Header.Set("X-Forwarded-For", clientIP)
+		p.Rewrite(pr)
+		outreq = pr.Out
+	} else {
+		if clientIP, _, err := net.SplitHostPort(req.RemoteAddr); err == nil {
+			// If we aren't the first proxy retain prior
+			// X-Forwarded-For information as a comma+space
+			// separated list and fold multiple headers into one.
+			prior, ok := outreq.Header["X-Forwarded-For"]
+			omit := ok && prior == nil // Issue 38079: nil now means don't populate the header
+			if len(prior) > 0 {
+				clientIP = strings.Join(prior, ", ") + ", " + clientIP
+			}
+			if !omit {
+				outreq.Header.Set("X-Forwarded-For", clientIP)
+			}
 		}
 	}
 
+	if _, ok := outreq.Header["User-Agent"]; !ok {
+		// If the outbound request doesn't have a User-Agent header set,
+		// don't send the default Go HTTP client User-Agent.
+		outreq.Header.Set("User-Agent", "")
+	}
+
+	trace := &httptrace.ClientTrace{
+		Got1xxResponse: func(code int, header textproto.MIMEHeader) error {
+			h := rw.Header()
+			copyHeader(h, http.Header(header))
+			rw.WriteHeader(code)
+
+			// Clear headers, it's not automatically done by ResponseWriter.WriteHeader() for 1xx responses
+			for k := range h {
+				delete(h, k)
+			}
+
+			return nil
+		},
+	}
+	outreq = outreq.WithContext(httptrace.WithClientTrace(outreq.Context(), trace))
+
 	res, err := transport.RoundTrip(outreq)
 	if err != nil {
 		p.getErrorHandler()(rw, outreq, err)
@@ -322,11 +485,7 @@
 		return
 	}
 
-	removeConnectionHeaders(res.Header)
-
-	for _, h := range hopHeaders {
-		res.Header.Del(h)
-	}
+	removeHopByHopHeaders(res.Header)
 
 	if !p.modifyResponse(rw, res, outreq) {
 		return
@@ -405,9 +564,9 @@
 	return false
 }
 
-// removeConnectionHeaders removes hop-by-hop headers listed in the "Connection" header of h.
-// See RFC 7230, section 6.1
-func removeConnectionHeaders(h http.Header) {
+// removeHopByHopHeaders removes hop-by-hop headers.
+func removeHopByHopHeaders(h http.Header) {
+	// RFC 7230, section 6.1: Remove headers listed in the "Connection" header.
 	for _, f := range h["Connection"] {
 		for _, sf := range strings.Split(f, ",") {
 			if sf = textproto.TrimString(sf); sf != "" {
@@ -415,6 +574,12 @@
 			}
 		}
 	}
+	// RFC 2616, section 13.5.1: Remove a set of known hop-by-hop headers.
+	// This behavior is superseded by the RFC 7230 Connection header, but
+	// preserve it for backwards compatibility.
+	for _, f := range hopHeaders {
+		h.Del(f)
+	}
 }
 
 // flushInterval returns the p.FlushInterval value, conditionally
@@ -639,3 +804,36 @@
 	_, err := io.Copy(c.backend, c.user)
 	errc <- err
 }
+
+func cleanQueryParams(s string) string {
+	reencode := func(s string) string {
+		v, _ := url.ParseQuery(s)
+		return v.Encode()
+	}
+	for i := 0; i < len(s); {
+		switch s[i] {
+		case ';':
+			return reencode(s)
+		case '%':
+			if i+2 >= len(s) || !ishex(s[i+1]) || !ishex(s[i+2]) {
+				return reencode(s)
+			}
+			i += 3
+		default:
+			i++
+		}
+	}
+	return s
+}
+
+func ishex(c byte) bool {
+	switch {
+	case '0' <= c && c <= '9':
+		return true
+	case 'a' <= c && c <= 'f':
+		return true
+	case 'A' <= c && c <= 'F':
+		return true
+	}
+	return false
+}
diff --git a/src/net/http/httputil/reverseproxy_test.go b/src/net/http/httputil/reverseproxy_test.go
index 90e8903..d5b0fb4 100644
--- a/src/net/http/httputil/reverseproxy_test.go
+++ b/src/net/http/httputil/reverseproxy_test.go
@@ -16,7 +16,9 @@
 	"log"
 	"net/http"
 	"net/http/httptest"
+	"net/http/httptrace"
 	"net/http/internal/ascii"
+	"net/textproto"
 	"net/url"
 	"os"
 	"reflect"
@@ -319,7 +321,6 @@
 	defer frontend.Close()
 
 	getReq, _ := http.NewRequest("GET", frontend.URL, nil)
-	getReq.Host = "some-name"
 	getReq.Header.Set("Connection", "close")
 	getReq.Header.Set("X-Forwarded-For", prevForwardedFor)
 	getReq.Close = true
@@ -369,6 +370,46 @@
 	res.Body.Close()
 }
 
+func TestReverseProxyRewriteStripsForwarded(t *testing.T) {
+	headers := []string{
+		"Forwarded",
+		"X-Forwarded-For",
+		"X-Forwarded-Host",
+		"X-Forwarded-Proto",
+	}
+	backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		for _, h := range headers {
+			if v := r.Header.Get(h); v != "" {
+				t.Errorf("got %v header: %q", h, v)
+			}
+		}
+	}))
+	defer backend.Close()
+	backendURL, err := url.Parse(backend.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+	proxyHandler := &ReverseProxy{
+		Rewrite: func(r *ProxyRequest) {
+			r.SetURL(backendURL)
+		},
+	}
+	frontend := httptest.NewServer(proxyHandler)
+	defer frontend.Close()
+
+	getReq, _ := http.NewRequest("GET", frontend.URL, nil)
+	getReq.Host = "some-name"
+	getReq.Close = true
+	for _, h := range headers {
+		getReq.Header.Set(h, "x")
+	}
+	res, err := frontend.Client().Do(getReq)
+	if err != nil {
+		t.Fatalf("Get: %v", err)
+	}
+	res.Body.Close()
+}
+
 var proxyQueryTests = []struct {
 	baseSuffix string // suffix to add to backend URL
 	reqSuffix  string // suffix to add to frontend's request URL
@@ -574,46 +615,38 @@
 
 // Issue 15524
 func TestUserAgentHeader(t *testing.T) {
-	const explicitUA = "explicit UA"
+	var gotUA string
 	backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		if r.URL.Path == "/noua" {
-			if c := r.Header.Get("User-Agent"); c != "" {
-				t.Errorf("handler got non-empty User-Agent header %q", c)
-			}
-			return
-		}
-		if c := r.Header.Get("User-Agent"); c != explicitUA {
-			t.Errorf("handler got unexpected User-Agent header %q", c)
-		}
+		gotUA = r.Header.Get("User-Agent")
 	}))
 	defer backend.Close()
 	backendURL, err := url.Parse(backend.URL)
 	if err != nil {
 		t.Fatal(err)
 	}
-	proxyHandler := NewSingleHostReverseProxy(backendURL)
+
+	proxyHandler := new(ReverseProxy)
 	proxyHandler.ErrorLog = log.New(io.Discard, "", 0) // quiet for tests
+	proxyHandler.Director = func(req *http.Request) {
+		req.URL = backendURL
+	}
 	frontend := httptest.NewServer(proxyHandler)
 	defer frontend.Close()
 	frontendClient := frontend.Client()
 
-	getReq, _ := http.NewRequest("GET", frontend.URL, nil)
-	getReq.Header.Set("User-Agent", explicitUA)
-	getReq.Close = true
-	res, err := frontendClient.Do(getReq)
-	if err != nil {
-		t.Fatalf("Get: %v", err)
+	for _, sentUA := range []string{"explicit UA", ""} {
+		getReq, _ := http.NewRequest("GET", frontend.URL, nil)
+		getReq.Header.Set("User-Agent", sentUA)
+		getReq.Close = true
+		res, err := frontendClient.Do(getReq)
+		if err != nil {
+			t.Fatalf("Get: %v", err)
+		}
+		res.Body.Close()
+		if got, want := gotUA, sentUA; got != want {
+			t.Errorf("got forwarded User-Agent %q, want %q", got, want)
+		}
 	}
-	res.Body.Close()
-
-	getReq, _ = http.NewRequest("GET", frontend.URL+"/noua", nil)
-	getReq.Header.Set("User-Agent", "")
-	getReq.Close = true
-	res, err = frontendClient.Do(getReq)
-	if err != nil {
-		t.Fatalf("Get: %v", err)
-	}
-	res.Body.Close()
 }
 
 type bufferPool struct {
@@ -1029,13 +1062,14 @@
 	}
 	rp.ServeHTTP(httptest.NewRecorder(), req)
 
-	if req.Header.Get("From-Director") == "1" {
-		t.Error("Director header mutation modified caller's request")
+	for _, h := range []string{
+		"From-Director",
+		"X-Forwarded-For",
+	} {
+		if req.Header.Get(h) != "" {
+			t.Errorf("%v header mutation modified caller's request", h)
+		}
 	}
-	if req.Header.Get("X-Forwarded-For") != "" {
-		t.Error("X-Forward-For header mutation modified caller's request")
-	}
-
 }
 
 type roundTripperFunc func(req *http.Request) (*http.Response, error)
@@ -1048,7 +1082,7 @@
 	req, _ := http.NewRequest("GET", "http://foo.tld/", nil)
 	req.RemoteAddr = "1.2.3.4:56789"
 	closeCheck := new(checkCloser)
-	logBuf := new(bytes.Buffer)
+	logBuf := new(strings.Builder)
 	outErr := errors.New("ModifyResponse error")
 	rp := &ReverseProxy{
 		Director: func(req *http.Request) {},
@@ -1488,6 +1522,40 @@
 
 }
 
+func TestSetURL(t *testing.T) {
+	backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		w.Write([]byte(r.Host))
+	}))
+	defer backend.Close()
+	backendURL, err := url.Parse(backend.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+	proxyHandler := &ReverseProxy{
+		Rewrite: func(r *ProxyRequest) {
+			r.SetURL(backendURL)
+		},
+	}
+	frontend := httptest.NewServer(proxyHandler)
+	defer frontend.Close()
+	frontendClient := frontend.Client()
+
+	res, err := frontendClient.Get(frontend.URL)
+	if err != nil {
+		t.Fatalf("Get: %v", err)
+	}
+	defer res.Body.Close()
+
+	body, err := io.ReadAll(res.Body)
+	if err != nil {
+		t.Fatalf("Reading body: %v", err)
+	}
+
+	if got, want := string(body), backendURL.Host; got != want {
+		t.Errorf("backend got Host %q, want %q", got, want)
+	}
+}
+
 func TestSingleJoinSlash(t *testing.T) {
 	tests := []struct {
 		slasha   string
@@ -1537,3 +1605,203 @@
 		}
 	}
 }
+
+func TestReverseProxyRewriteReplacesOut(t *testing.T) {
+	const content = "response_content"
+	backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		w.Write([]byte(content))
+	}))
+	defer backend.Close()
+	proxyHandler := &ReverseProxy{
+		Rewrite: func(r *ProxyRequest) {
+			r.Out, _ = http.NewRequest("GET", backend.URL, nil)
+		},
+	}
+	frontend := httptest.NewServer(proxyHandler)
+	defer frontend.Close()
+
+	res, err := frontend.Client().Get(frontend.URL)
+	if err != nil {
+		t.Fatalf("Get: %v", err)
+	}
+	defer res.Body.Close()
+	body, _ := io.ReadAll(res.Body)
+	if got, want := string(body), content; got != want {
+		t.Errorf("got response %q, want %q", got, want)
+	}
+}
+
+func Test1xxResponses(t *testing.T) {
+	backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		h := w.Header()
+		h.Add("Link", "</style.css>; rel=preload; as=style")
+		h.Add("Link", "</script.js>; rel=preload; as=script")
+		w.WriteHeader(http.StatusEarlyHints)
+
+		h.Add("Link", "</foo.js>; rel=preload; as=script")
+		w.WriteHeader(http.StatusProcessing)
+
+		w.Write([]byte("Hello"))
+	}))
+	defer backend.Close()
+	backendURL, err := url.Parse(backend.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+	proxyHandler := NewSingleHostReverseProxy(backendURL)
+	proxyHandler.ErrorLog = log.New(io.Discard, "", 0) // quiet for tests
+	frontend := httptest.NewServer(proxyHandler)
+	defer frontend.Close()
+	frontendClient := frontend.Client()
+
+	checkLinkHeaders := func(t *testing.T, expected, got []string) {
+		t.Helper()
+
+		if len(expected) != len(got) {
+			t.Errorf("Expected %d link headers; got %d", len(expected), len(got))
+		}
+
+		for i := range expected {
+			if i >= len(got) {
+				t.Errorf("Expected %q link header; got nothing", expected[i])
+
+				continue
+			}
+
+			if expected[i] != got[i] {
+				t.Errorf("Expected %q link header; got %q", expected[i], got[i])
+			}
+		}
+	}
+
+	var respCounter uint8
+	trace := &httptrace.ClientTrace{
+		Got1xxResponse: func(code int, header textproto.MIMEHeader) error {
+			switch code {
+			case http.StatusEarlyHints:
+				checkLinkHeaders(t, []string{"</style.css>; rel=preload; as=style", "</script.js>; rel=preload; as=script"}, header["Link"])
+			case http.StatusProcessing:
+				checkLinkHeaders(t, []string{"</style.css>; rel=preload; as=style", "</script.js>; rel=preload; as=script", "</foo.js>; rel=preload; as=script"}, header["Link"])
+			default:
+				t.Error("Unexpected 1xx response")
+			}
+
+			respCounter++
+
+			return nil
+		},
+	}
+	req, _ := http.NewRequestWithContext(httptrace.WithClientTrace(context.Background(), trace), "GET", frontend.URL, nil)
+
+	res, err := frontendClient.Do(req)
+	if err != nil {
+		t.Fatalf("Get: %v", err)
+	}
+
+	defer res.Body.Close()
+
+	if respCounter != 2 {
+		t.Errorf("Expected 2 1xx responses; got %d", respCounter)
+	}
+	checkLinkHeaders(t, []string{"</style.css>; rel=preload; as=style", "</script.js>; rel=preload; as=script", "</foo.js>; rel=preload; as=script"}, res.Header["Link"])
+
+	body, _ := io.ReadAll(res.Body)
+	if string(body) != "Hello" {
+		t.Errorf("Read body %q; want Hello", body)
+	}
+}
+
+const (
+	testWantsCleanQuery = true
+	testWantsRawQuery   = false
+)
+
+func TestReverseProxyQueryParameterSmugglingDirectorDoesNotParseForm(t *testing.T) {
+	testReverseProxyQueryParameterSmuggling(t, testWantsRawQuery, func(u *url.URL) *ReverseProxy {
+		proxyHandler := NewSingleHostReverseProxy(u)
+		oldDirector := proxyHandler.Director
+		proxyHandler.Director = func(r *http.Request) {
+			oldDirector(r)
+		}
+		return proxyHandler
+	})
+}
+
+func TestReverseProxyQueryParameterSmugglingDirectorParsesForm(t *testing.T) {
+	testReverseProxyQueryParameterSmuggling(t, testWantsCleanQuery, func(u *url.URL) *ReverseProxy {
+		proxyHandler := NewSingleHostReverseProxy(u)
+		oldDirector := proxyHandler.Director
+		proxyHandler.Director = func(r *http.Request) {
+			// Parsing the form causes ReverseProxy to remove unparsable
+			// query parameters before forwarding.
+			r.FormValue("a")
+			oldDirector(r)
+		}
+		return proxyHandler
+	})
+}
+
+func TestReverseProxyQueryParameterSmugglingRewrite(t *testing.T) {
+	testReverseProxyQueryParameterSmuggling(t, testWantsCleanQuery, func(u *url.URL) *ReverseProxy {
+		return &ReverseProxy{
+			Rewrite: func(r *ProxyRequest) {
+				r.SetURL(u)
+			},
+		}
+	})
+}
+
+func TestReverseProxyQueryParameterSmugglingRewritePreservesRawQuery(t *testing.T) {
+	testReverseProxyQueryParameterSmuggling(t, testWantsRawQuery, func(u *url.URL) *ReverseProxy {
+		return &ReverseProxy{
+			Rewrite: func(r *ProxyRequest) {
+				r.SetURL(u)
+				r.Out.URL.RawQuery = r.In.URL.RawQuery
+			},
+		}
+	})
+}
+
+func testReverseProxyQueryParameterSmuggling(t *testing.T, wantCleanQuery bool, newProxy func(*url.URL) *ReverseProxy) {
+	const content = "response_content"
+	backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		w.Write([]byte(r.URL.RawQuery))
+	}))
+	defer backend.Close()
+	backendURL, err := url.Parse(backend.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+	proxyHandler := newProxy(backendURL)
+	frontend := httptest.NewServer(proxyHandler)
+	defer frontend.Close()
+
+	// Don't spam output with logs of queries containing semicolons.
+	backend.Config.ErrorLog = log.New(io.Discard, "", 0)
+	frontend.Config.ErrorLog = log.New(io.Discard, "", 0)
+
+	for _, test := range []struct {
+		rawQuery   string
+		cleanQuery string
+	}{{
+		rawQuery:   "a=1&a=2;b=3",
+		cleanQuery: "a=1",
+	}, {
+		rawQuery:   "a=1&a=%zz&b=3",
+		cleanQuery: "a=1&b=3",
+	}} {
+		res, err := frontend.Client().Get(frontend.URL + "?" + test.rawQuery)
+		if err != nil {
+			t.Fatalf("Get: %v", err)
+		}
+		defer res.Body.Close()
+		body, _ := io.ReadAll(res.Body)
+		wantQuery := test.rawQuery
+		if wantCleanQuery {
+			wantQuery = test.cleanQuery
+		}
+		if got, want := string(body), wantQuery; got != want {
+			t.Errorf("proxy forwarded raw query %q as %q, want %q", test.rawQuery, got, want)
+		}
+	}
+}
diff --git a/src/net/http/pprof/pprof.go b/src/net/http/pprof/pprof.go
index de5a4b9..db03af1 100644
--- a/src/net/http/pprof/pprof.go
+++ b/src/net/http/pprof/pprof.go
@@ -21,10 +21,15 @@
 //		log.Println(http.ListenAndServe("localhost:6060", nil))
 //	}()
 //
+// By default, all the profiles listed in [runtime/pprof.Profile] are
+// available (via [Handler]), in addition to the [Cmdline], [Profile], [Symbol],
+// and [Trace] profiles defined in this package.
 // If you are not using DefaultServeMux, you will have to register handlers
 // with the mux you are using.
 //
-// Then use the pprof tool to look at the heap profile:
+// # Usage examples
+//
+// Use the pprof tool to look at the heap profile:
 //
 //	go tool pprof http://localhost:6060/debug/pprof/heap
 //
@@ -222,6 +227,7 @@
 }
 
 // Handler returns an HTTP handler that serves the named profile.
+// Available profiles can be found in [runtime/pprof.Profile].
 func Handler(name string) http.Handler {
 	return handler(name)
 }
@@ -345,7 +351,7 @@
 	"allocs":       "A sampling of all past memory allocations",
 	"block":        "Stack traces that led to blocking on synchronization primitives",
 	"cmdline":      "The command line invocation of the current program",
-	"goroutine":    "Stack traces of all current goroutines",
+	"goroutine":    "Stack traces of all current goroutines. Use debug=2 as a query parameter to export in the same format as an unrecovered panic.",
 	"heap":         "A sampling of memory allocations of live objects. You can specify the gc GET parameter to run GC before taking the heap sample.",
 	"mutex":        "Stack traces of holders of contended mutexes",
 	"profile":      "CPU profile. You can specify the duration in the seconds GET parameter. After you get the profile file, use the go tool pprof command to investigate the profile.",
@@ -365,8 +371,7 @@
 // Index responds to a request for "/debug/pprof/" with an HTML page
 // listing the available profiles.
 func Index(w http.ResponseWriter, r *http.Request) {
-	if strings.HasPrefix(r.URL.Path, "/debug/pprof/") {
-		name := strings.TrimPrefix(r.URL.Path, "/debug/pprof/")
+	if name, found := strings.CutPrefix(r.URL.Path, "/debug/pprof/"); found {
 		if name != "" {
 			handler(name).ServeHTTP(w, r)
 			return
@@ -417,7 +422,9 @@
 </style>
 </head>
 <body>
-/debug/pprof/<br>
+/debug/pprof/
+<br>
+<p>Set debug=1 as a query parameter to export in legacy text format</p>
 <br>
 Types of profiles available:
 <table>
diff --git a/src/net/http/readrequest_test.go b/src/net/http/readrequest_test.go
index 1950f49..5aaf3b9 100644
--- a/src/net/http/readrequest_test.go
+++ b/src/net/http/readrequest_test.go
@@ -416,7 +416,7 @@
 		req.Body = nil
 		testName := fmt.Sprintf("Test %d (%q)", i, tt.Raw)
 		diff(t, testName, req, tt.Req)
-		var bout bytes.Buffer
+		var bout strings.Builder
 		if rbody != nil {
 			_, err := io.Copy(&bout, rbody)
 			if err != nil {
@@ -450,17 +450,18 @@
 Content-Length: 4
 
 abc`)},
-	{"smuggle_content_len_head", reqBytes(`HEAD / HTTP/1.1
+	{"smuggle_two_content_len_head", reqBytes(`HEAD / HTTP/1.1
 Host: foo
-Content-Length: 5`)},
+Content-Length: 4
+Content-Length: 5
+
+1234`)},
 
 	// golang.org/issue/22464
-	{"leading_space_in_header", reqBytes(`HEAD / HTTP/1.1
- Host: foo
-Content-Length: 5`)},
-	{"leading_tab_in_header", reqBytes(`HEAD / HTTP/1.1
-\tHost: foo
-Content-Length: 5`)},
+	{"leading_space_in_header", reqBytes(`GET / HTTP/1.1
+ Host: foo`)},
+	{"leading_tab_in_header", reqBytes(`GET / HTTP/1.1
+` + "\t" + `Host: foo`)},
 }
 
 func TestReadRequest_Bad(t *testing.T) {
diff --git a/src/net/http/request.go b/src/net/http/request.go
index cead91d..a45c9e3 100644
--- a/src/net/http/request.go
+++ b/src/net/http/request.go
@@ -49,9 +49,12 @@
 func (pe *ProtocolError) Error() string { return pe.ErrorString }
 
 var (
-	// ErrNotSupported is returned by the Push method of Pusher
-	// implementations to indicate that HTTP/2 Push support is not
-	// available.
+	// ErrNotSupported indicates that a feature is not supported.
+	//
+	// It is returned by ResponseController methods to indicate that
+	// the handler does not support the method, and by the Push method
+	// of Pusher implementations to indicate that HTTP/2 Push support
+	// is not available.
 	ErrNotSupported = &ProtocolError{"feature not supported"}
 
 	// Deprecated: ErrUnexpectedTrailer is no longer returned by
@@ -317,14 +320,14 @@
 	Response *Response
 
 	// ctx is either the client or server context. It should only
-	// be modified via copying the whole Request using WithContext.
+	// be modified via copying the whole Request using Clone or WithContext.
 	// It is unexported to prevent people from using Context wrong
 	// and mutating the contexts held by callers of the same request.
 	ctx context.Context
 }
 
 // Context returns the request's context. To change the context, use
-// WithContext.
+// Clone or WithContext.
 //
 // The returned context is always non-nil; it defaults to the
 // background context.
@@ -349,9 +352,7 @@
 // sending the request, and reading the response headers and body.
 //
 // To create a new request with a context, use NewRequestWithContext.
-// To change the context of a request, such as an incoming request you
-// want to modify before sending back out, use Request.Clone. Between
-// those two uses, it's rare to need WithContext.
+// To make a deep copy of a request with a new context, use Request.Clone.
 func (r *Request) WithContext(ctx context.Context) *Request {
 	if ctx == nil {
 		panic("nil context")
@@ -418,6 +419,9 @@
 // If multiple cookies match the given name, only one cookie will
 // be returned.
 func (r *Request) Cookie(name string) (*Cookie, error) {
+	if name == "" {
+		return nil, ErrNoCookie
+	}
 	for _, c := range readCookies(r.Header, name) {
 		return c, nil
 	}
@@ -1029,6 +1033,8 @@
 
 func readRequest(b *bufio.Reader) (req *Request, err error) {
 	tp := newTextprotoReader(b)
+	defer putTextprotoReader(tp)
+
 	req = new(Request)
 
 	// First line: GET /index.html HTTP/1.0
@@ -1037,7 +1043,6 @@
 		return nil, err
 	}
 	defer func() {
-		putTextprotoReader(tp)
 		if err == io.EOF {
 			err = io.ErrUnexpectedEOF
 		}
@@ -1168,7 +1173,8 @@
 	// If they asked for a 32KB byte read but only 5 bytes are
 	// remaining, no need to read 32KB. 6 bytes will answer the
 	// question of the whether we hit the limit or go past it.
-	if int64(len(p)) > l.n+1 {
+	// 0 < len(p) < 2^63
+	if int64(len(p))-1 > l.n {
 		p = p[:l.n+1]
 	}
 	n, err = l.r.Read(p)
diff --git a/src/net/http/request_test.go b/src/net/http/request_test.go
index d285840..23e49d6 100644
--- a/src/net/http/request_test.go
+++ b/src/net/http/request_test.go
@@ -15,7 +15,6 @@
 	"math"
 	"mime/multipart"
 	. "net/http"
-	"net/http/httptest"
 	"net/url"
 	"os"
 	"reflect"
@@ -289,10 +288,11 @@
 // the payload size and the internal leeway buffer size of 10MiB overflows, that we
 // correctly return an error.
 func TestMaxInt64ForMultipartFormMaxMemoryOverflow(t *testing.T) {
-	defer afterTest(t)
-
+	run(t, testMaxInt64ForMultipartFormMaxMemoryOverflow)
+}
+func testMaxInt64ForMultipartFormMaxMemoryOverflow(t *testing.T, mode testMode) {
 	payloadSize := 1 << 10
-	cst := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(rw ResponseWriter, req *Request) {
 		// The combination of:
 		//      MaxInt64 + payloadSize + (internal spare of 10MiB)
 		// triggers the overflow. See issue https://golang.org/issue/40430/
@@ -300,8 +300,7 @@
 			Error(rw, err.Error(), StatusBadRequest)
 			return
 		}
-	}))
-	defer cst.Close()
+	})).ts
 	fBuf := new(bytes.Buffer)
 	mw := multipart.NewWriter(fBuf)
 	mf, err := mw.CreateFormFile("file", "myfile.txt")
@@ -329,11 +328,9 @@
 	}
 }
 
-func TestRedirect_h1(t *testing.T) { testRedirect(t, h1Mode) }
-func TestRedirect_h2(t *testing.T) { testRedirect(t, h2Mode) }
-func testRedirect(t *testing.T, h2 bool) {
-	defer afterTest(t)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestRequestRedirect(t *testing.T) { run(t, testRequestRedirect) }
+func testRequestRedirect(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		switch r.URL.Path {
 		case "/":
 			w.Header().Set("Location", "/foo/")
@@ -344,7 +341,6 @@
 			w.WriteHeader(StatusBadRequest)
 		}
 	}))
-	defer cst.close()
 
 	var end = regexp.MustCompile("/foo/$")
 	r, err := cst.c.Get(cst.ts.URL)
@@ -485,10 +481,6 @@
 	1: {"GET / HTTP/1.1\r\nheader:foo\r\n", io.ErrUnexpectedEOF.Error(), nil},
 	2: {"", io.EOF.Error(), nil},
 	3: {
-		in:  "HEAD / HTTP/1.1\r\nContent-Length:4\r\n\r\n",
-		err: "http: method cannot contain a Content-Length",
-	},
-	4: {
 		in:     "HEAD / HTTP/1.1\r\n\r\n",
 		header: Header{},
 	},
@@ -496,32 +488,32 @@
 	// Multiple Content-Length values should either be
 	// deduplicated if same or reject otherwise
 	// See Issue 16490.
-	5: {
+	4: {
 		in:  "POST / HTTP/1.1\r\nContent-Length: 10\r\nContent-Length: 0\r\n\r\nGopher hey\r\n",
 		err: "cannot contain multiple Content-Length headers",
 	},
-	6: {
+	5: {
 		in:  "POST / HTTP/1.1\r\nContent-Length: 10\r\nContent-Length: 6\r\n\r\nGopher\r\n",
 		err: "cannot contain multiple Content-Length headers",
 	},
-	7: {
+	6: {
 		in:     "PUT / HTTP/1.1\r\nContent-Length: 6 \r\nContent-Length: 6\r\nContent-Length:6\r\n\r\nGopher\r\n",
 		err:    "",
 		header: Header{"Content-Length": {"6"}},
 	},
-	8: {
+	7: {
 		in:  "PUT / HTTP/1.1\r\nContent-Length: 1\r\nContent-Length: 6 \r\n\r\n",
 		err: "cannot contain multiple Content-Length headers",
 	},
-	9: {
+	8: {
 		in:  "POST / HTTP/1.1\r\nContent-Length:\r\nContent-Length: 3\r\n\r\n",
 		err: "cannot contain multiple Content-Length headers",
 	},
-	10: {
+	9: {
 		in:     "HEAD / HTTP/1.1\r\nContent-Length:0\r\nContent-Length: 0\r\n\r\n",
 		header: Header{"Content-Length": {"0"}},
 	},
-	11: {
+	10: {
 		in:  "HEAD / HTTP/1.1\r\nHost: foo\r\nHost: bar\r\n\r\n\r\n\r\n",
 		err: "too many Host headers",
 	},
@@ -815,7 +807,7 @@
 	clientReq := *req
 	clientReq.Body = nil
 
-	var out bytes.Buffer
+	var out strings.Builder
 	if err := clientReq.Write(&out); err != nil {
 		t.Fatal(err)
 	}
@@ -823,7 +815,7 @@
 	if strings.Contains(out.String(), "chunked") {
 		t.Error("wrote chunked request; want no body")
 	}
-	back, err := ReadRequest(bufio.NewReader(bytes.NewReader(out.Bytes())))
+	back, err := ReadRequest(bufio.NewReader(strings.NewReader(out.String())))
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -835,7 +827,7 @@
 		t.Errorf("Original request doesn't match Request read back.")
 		t.Logf("Original: %#v", req)
 		t.Logf("Original.URL: %#v", req.URL)
-		t.Logf("Wrote: %s", out.Bytes())
+		t.Logf("Wrote: %s", out.String())
 		t.Logf("Read back (doesn't match Original): %#v", back)
 	}
 }
@@ -982,6 +974,12 @@
 			wantN:   len(testStr),
 			wantErr: false,
 		},
+		10: { /* Issue 54408 */
+			limit:   int64(1<<63 - 1),
+			lenP:    len(testStr),
+			wantN:   len(testStr),
+			wantErr: false,
+		},
 	}
 	for i, tt := range tests {
 		rc := MaxBytesReader(nil, io.NopCloser(strings.NewReader(testStr)), tt.limit)
@@ -1033,19 +1031,10 @@
 	}
 }
 
-func TestNoPanicOnRoundTripWithBasicAuth_h1(t *testing.T) {
-	testNoPanicWithBasicAuth(t, h1Mode)
-}
-
-func TestNoPanicOnRoundTripWithBasicAuth_h2(t *testing.T) {
-	testNoPanicWithBasicAuth(t, h2Mode)
-}
-
 // Issue 34878: verify we don't panic when including basic auth (Go 1.13 regression)
-func testNoPanicWithBasicAuth(t *testing.T, h2 bool) {
-	defer afterTest(t)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {}))
-	defer cst.close()
+func TestNoPanicOnRoundTripWithBasicAuth(t *testing.T) { run(t, testNoPanicWithBasicAuth) }
+func testNoPanicWithBasicAuth(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {}))
 
 	u, err := url.Parse(cst.ts.URL)
 	if err != nil {
@@ -1108,7 +1097,7 @@
 		t.Errorf("FormFile file = %v, want nil", f)
 	}
 	if fh != nil {
-		t.Errorf("FormFile file header = %q, want nil", fh)
+		t.Errorf("FormFile file header = %v, want nil", fh)
 	}
 	if err != ErrMissingFile {
 		t.Errorf("FormFile err = %q, want ErrMissingFile", err)
@@ -1166,7 +1155,7 @@
 	if fh.Filename != expectFilename {
 		t.Errorf("filename = %q, want %q", fh.Filename, expectFilename)
 	}
-	var b bytes.Buffer
+	var b strings.Builder
 	_, err = io.Copy(&b, f)
 	if err != nil {
 		t.Fatal("copying contents:", err)
@@ -1177,6 +1166,47 @@
 	return f
 }
 
+// Issue 53181: verify Request.Cookie return the correct Cookie.
+// Return ErrNoCookie instead of the first cookie when name is "".
+func TestRequestCookie(t *testing.T) {
+	for _, tt := range []struct {
+		name        string
+		value       string
+		expectedErr error
+	}{
+		{
+			name:        "foo",
+			value:       "bar",
+			expectedErr: nil,
+		},
+		{
+			name:        "",
+			expectedErr: ErrNoCookie,
+		},
+	} {
+		req, err := NewRequest("GET", "http://example.com/", nil)
+		if err != nil {
+			t.Fatal(err)
+		}
+		req.AddCookie(&Cookie{Name: tt.name, Value: tt.value})
+		c, err := req.Cookie(tt.name)
+		if err != tt.expectedErr {
+			t.Errorf("got %v, want %v", err, tt.expectedErr)
+		}
+
+		// skip if error occurred.
+		if err != nil {
+			continue
+		}
+		if c.Value != tt.value {
+			t.Errorf("got %v, want %v", c.Value, tt.value)
+		}
+		if c.Name != tt.name {
+			t.Errorf("got %s, want %v", tt.name, c.Name)
+		}
+	}
+}
+
 const (
 	fileaContents = "This is a test file."
 	filebContents = "Another test file."
@@ -1285,11 +1315,6 @@
 `)
 }
 
-const (
-	withTLS = true
-	noTLS   = false
-)
-
 func BenchmarkFileAndServer_1KB(b *testing.B) {
 	benchmarkFileAndServer(b, 1<<10)
 }
@@ -1317,16 +1342,12 @@
 		b.Fatalf("Failed to copy %d bytes: %v", n, err)
 	}
 
-	b.Run("NoTLS", func(b *testing.B) {
-		runFileAndServerBenchmarks(b, noTLS, f, n)
-	})
-
-	b.Run("TLS", func(b *testing.B) {
-		runFileAndServerBenchmarks(b, withTLS, f, n)
-	})
+	run(b, func(b *testing.B, mode testMode) {
+		runFileAndServerBenchmarks(b, mode, f, n)
+	}, []testMode{http1Mode, https1Mode, http2Mode})
 }
 
-func runFileAndServerBenchmarks(b *testing.B, tlsOption bool, f *os.File, n int64) {
+func runFileAndServerBenchmarks(b *testing.B, mode testMode, f *os.File, n int64) {
 	handler := HandlerFunc(func(rw ResponseWriter, req *Request) {
 		defer req.Body.Close()
 		nc, err := io.Copy(io.Discard, req.Body)
@@ -1339,14 +1360,8 @@
 		}
 	})
 
-	var cst *httptest.Server
-	if tlsOption == withTLS {
-		cst = httptest.NewTLSServer(handler)
-	} else {
-		cst = httptest.NewServer(handler)
-	}
+	cst := newClientServerTest(b, mode, handler).ts
 
-	defer cst.Close()
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		// Perform some setup.
diff --git a/src/net/http/requestwrite_test.go b/src/net/http/requestwrite_test.go
index bdc1e3c..380ae9d 100644
--- a/src/net/http/requestwrite_test.go
+++ b/src/net/http/requestwrite_test.go
@@ -629,7 +629,7 @@
 			tt.Req.Header = make(Header)
 		}
 
-		var braw bytes.Buffer
+		var braw strings.Builder
 		err := tt.Req.Write(&braw)
 		if g, e := fmt.Sprintf("%v", err), fmt.Sprintf("%v", tt.WantError); g != e {
 			t.Errorf("writing #%d, err = %q, want %q", i, g, e)
@@ -649,7 +649,7 @@
 
 		if tt.WantProxy != "" {
 			setBody()
-			var praw bytes.Buffer
+			var praw strings.Builder
 			err = tt.Req.WriteProxy(&praw)
 			if err != nil {
 				t.Errorf("WriteProxy #%d: %s", i, err)
@@ -815,7 +815,7 @@
 	if err != nil {
 		t.Fatal(err)
 	}
-	buf := new(bytes.Buffer)
+	buf := new(strings.Builder)
 	if err := req.Write(buf); err != nil {
 		t.Error(err)
 	}
diff --git a/src/net/http/response_test.go b/src/net/http/response_test.go
index 5a735b0..19fb48f 100644
--- a/src/net/http/response_test.go
+++ b/src/net/http/response_test.go
@@ -596,7 +596,7 @@
 		rbody := resp.Body
 		resp.Body = nil
 		diff(t, fmt.Sprintf("#%d Response", i), resp, &tt.Resp)
-		var bout bytes.Buffer
+		var bout strings.Builder
 		if rbody != nil {
 			_, err = io.Copy(&bout, rbody)
 			if err != nil {
@@ -809,7 +809,7 @@
 		ProtoMajor: 1,
 		ProtoMinor: 3,
 	}
-	var buf bytes.Buffer
+	var buf strings.Builder
 	r.Write(&buf)
 	if strings.Contains(buf.String(), "123 123") {
 		t.Errorf("stutter in status: %s", buf.String())
@@ -829,7 +829,7 @@
 	if res.ContentLength != 123 {
 		t.Fatalf("Content-Length = %d; want 123", res.ContentLength)
 	}
-	var buf bytes.Buffer
+	var buf strings.Builder
 	n, err := io.Copy(&buf, res.Body)
 	if n != int64(len(shortBody)) {
 		t.Errorf("Copied %d bytes; want %d, len(%q)", n, len(shortBody), shortBody)
@@ -972,19 +972,6 @@
 	return fmt.Errorf("%v; want %v", err, wantErr)
 }
 
-func TestNeedsSniff(t *testing.T) {
-	// needsSniff returns true with an empty response.
-	r := &response{}
-	if got, want := r.needsSniff(), true; got != want {
-		t.Errorf("needsSniff = %t; want %t", got, want)
-	}
-	// needsSniff returns false when Content-Type = nil.
-	r.handlerHeader = Header{"Content-Type": nil}
-	if got, want := r.needsSniff(), false; got != want {
-		t.Errorf("needsSniff empty Content-Type = %t; want %t", got, want)
-	}
-}
-
 // A response should only write out single Connection: close header. Tests #19499.
 func TestResponseWritesOnlySingleConnectionClose(t *testing.T) {
 	const connectionCloseHeader = "Connection: close"
@@ -1002,7 +989,7 @@
 		t.Fatalf("ReadResponse failed %v", err)
 	}
 
-	var buf2 bytes.Buffer
+	var buf2 strings.Builder
 	if err = res.Write(&buf2); err != nil {
 		t.Fatalf("Write failed %v", err)
 	}
diff --git a/src/net/http/responsecontroller.go b/src/net/http/responsecontroller.go
new file mode 100644
index 0000000..018bdc0
--- /dev/null
+++ b/src/net/http/responsecontroller.go
@@ -0,0 +1,122 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package http
+
+import (
+	"bufio"
+	"fmt"
+	"net"
+	"time"
+)
+
+// A ResponseController is used by an HTTP handler to control the response.
+//
+// A ResponseController may not be used after the Handler.ServeHTTP method has returned.
+type ResponseController struct {
+	rw ResponseWriter
+}
+
+// NewResponseController creates a ResponseController for a request.
+//
+// The ResponseWriter should be the original value passed to the Handler.ServeHTTP method,
+// or have an Unwrap method returning the original ResponseWriter.
+//
+// If the ResponseWriter implements any of the following methods, the ResponseController
+// will call them as appropriate:
+//
+//	Flush()
+//	FlushError() error // alternative Flush returning an error
+//	Hijack() (net.Conn, *bufio.ReadWriter, error)
+//	SetReadDeadline(deadline time.Time) error
+//	SetWriteDeadline(deadline time.Time) error
+//
+// If the ResponseWriter does not support a method, ResponseController returns
+// an error matching ErrNotSupported.
+func NewResponseController(rw ResponseWriter) *ResponseController {
+	return &ResponseController{rw}
+}
+
+type rwUnwrapper interface {
+	Unwrap() ResponseWriter
+}
+
+// Flush flushes buffered data to the client.
+func (c *ResponseController) Flush() error {
+	rw := c.rw
+	for {
+		switch t := rw.(type) {
+		case interface{ FlushError() error }:
+			return t.FlushError()
+		case Flusher:
+			t.Flush()
+			return nil
+		case rwUnwrapper:
+			rw = t.Unwrap()
+		default:
+			return errNotSupported()
+		}
+	}
+}
+
+// Hijack lets the caller take over the connection.
+// See the Hijacker interface for details.
+func (c *ResponseController) Hijack() (net.Conn, *bufio.ReadWriter, error) {
+	rw := c.rw
+	for {
+		switch t := rw.(type) {
+		case Hijacker:
+			return t.Hijack()
+		case rwUnwrapper:
+			rw = t.Unwrap()
+		default:
+			return nil, nil, errNotSupported()
+		}
+	}
+}
+
+// SetReadDeadline sets the deadline for reading the entire request, including the body.
+// Reads from the request body after the deadline has been exceeded will return an error.
+// A zero value means no deadline.
+//
+// Setting the read deadline after it has been exceeded will not extend it.
+func (c *ResponseController) SetReadDeadline(deadline time.Time) error {
+	rw := c.rw
+	for {
+		switch t := rw.(type) {
+		case interface{ SetReadDeadline(time.Time) error }:
+			return t.SetReadDeadline(deadline)
+		case rwUnwrapper:
+			rw = t.Unwrap()
+		default:
+			return errNotSupported()
+		}
+	}
+}
+
+// SetWriteDeadline sets the deadline for writing the response.
+// Writes to the response body after the deadline has been exceeded will not block,
+// but may succeed if the data has been buffered.
+// A zero value means no deadline.
+//
+// Setting the write deadline after it has been exceeded will not extend it.
+func (c *ResponseController) SetWriteDeadline(deadline time.Time) error {
+	rw := c.rw
+	for {
+		switch t := rw.(type) {
+		case interface{ SetWriteDeadline(time.Time) error }:
+			return t.SetWriteDeadline(deadline)
+		case rwUnwrapper:
+			rw = t.Unwrap()
+		default:
+			return errNotSupported()
+		}
+	}
+}
+
+// errNotSupported returns an error that Is ErrNotSupported,
+// but is not == to it.
+func errNotSupported() error {
+	return fmt.Errorf("%w", ErrNotSupported)
+}
diff --git a/src/net/http/responsecontroller_test.go b/src/net/http/responsecontroller_test.go
new file mode 100644
index 0000000..0dca733
--- /dev/null
+++ b/src/net/http/responsecontroller_test.go
@@ -0,0 +1,265 @@
+package http_test
+
+import (
+	"errors"
+	"fmt"
+	"io"
+	. "net/http"
+	"os"
+	"sync"
+	"testing"
+	"time"
+)
+
+func TestResponseControllerFlush(t *testing.T) { run(t, testResponseControllerFlush) }
+func testResponseControllerFlush(t *testing.T, mode testMode) {
+	continuec := make(chan struct{})
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
+		ctl := NewResponseController(w)
+		w.Write([]byte("one"))
+		if err := ctl.Flush(); err != nil {
+			t.Errorf("ctl.Flush() = %v, want nil", err)
+			return
+		}
+		<-continuec
+		w.Write([]byte("two"))
+	}))
+
+	res, err := cst.c.Get(cst.ts.URL)
+	if err != nil {
+		t.Fatalf("unexpected connection error: %v", err)
+	}
+	defer res.Body.Close()
+
+	buf := make([]byte, 16)
+	n, err := res.Body.Read(buf)
+	close(continuec)
+	if err != nil || string(buf[:n]) != "one" {
+		t.Fatalf("Body.Read = %q, %v, want %q, nil", string(buf[:n]), err, "one")
+	}
+
+	got, err := io.ReadAll(res.Body)
+	if err != nil || string(got) != "two" {
+		t.Fatalf("Body.Read = %q, %v, want %q, nil", string(got), err, "two")
+	}
+}
+
+func TestResponseControllerHijack(t *testing.T) { run(t, testResponseControllerHijack) }
+func testResponseControllerHijack(t *testing.T, mode testMode) {
+	const header = "X-Header"
+	const value = "set"
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
+		ctl := NewResponseController(w)
+		c, _, err := ctl.Hijack()
+		if mode == http2Mode {
+			if err == nil {
+				t.Errorf("ctl.Hijack = nil, want error")
+			}
+			w.Header().Set(header, value)
+			return
+		}
+		if err != nil {
+			t.Errorf("ctl.Hijack = _, _, %v, want _, _, nil", err)
+			return
+		}
+		fmt.Fprintf(c, "HTTP/1.0 200 OK\r\n%v: %v\r\nContent-Length: 0\r\n\r\n", header, value)
+	}))
+	res, err := cst.c.Get(cst.ts.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if got, want := res.Header.Get(header), value; got != want {
+		t.Errorf("response header %q = %q, want %q", header, got, want)
+	}
+}
+
+func TestResponseControllerSetPastWriteDeadline(t *testing.T) {
+	run(t, testResponseControllerSetPastWriteDeadline)
+}
+func testResponseControllerSetPastWriteDeadline(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
+		ctl := NewResponseController(w)
+		w.Write([]byte("one"))
+		if err := ctl.Flush(); err != nil {
+			t.Errorf("before setting deadline: ctl.Flush() = %v, want nil", err)
+		}
+		if err := ctl.SetWriteDeadline(time.Now().Add(-10 * time.Second)); err != nil {
+			t.Errorf("ctl.SetWriteDeadline() = %v, want nil", err)
+		}
+
+		w.Write([]byte("two"))
+		if err := ctl.Flush(); err == nil {
+			t.Errorf("after setting deadline: ctl.Flush() = nil, want non-nil")
+		}
+		// Connection errors are sticky, so resetting the deadline does not permit
+		// making more progress. We might want to change this in the future, but verify
+		// the current behavior for now. If we do change this, we'll want to make sure
+		// to do so only for writing the response body, not headers.
+		if err := ctl.SetWriteDeadline(time.Now().Add(1 * time.Hour)); err != nil {
+			t.Errorf("ctl.SetWriteDeadline() = %v, want nil", err)
+		}
+		w.Write([]byte("three"))
+		if err := ctl.Flush(); err == nil {
+			t.Errorf("after resetting deadline: ctl.Flush() = nil, want non-nil")
+		}
+	}))
+
+	res, err := cst.c.Get(cst.ts.URL)
+	if err != nil {
+		t.Fatalf("unexpected connection error: %v", err)
+	}
+	defer res.Body.Close()
+	b, _ := io.ReadAll(res.Body)
+	if string(b) != "one" {
+		t.Errorf("unexpected body: %q", string(b))
+	}
+}
+
+func TestResponseControllerSetFutureWriteDeadline(t *testing.T) {
+	run(t, testResponseControllerSetFutureWriteDeadline)
+}
+func testResponseControllerSetFutureWriteDeadline(t *testing.T, mode testMode) {
+	errc := make(chan error, 1)
+	startwritec := make(chan struct{})
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
+		ctl := NewResponseController(w)
+		w.WriteHeader(200)
+		if err := ctl.Flush(); err != nil {
+			t.Errorf("ctl.Flush() = %v, want nil", err)
+		}
+		<-startwritec // don't set the deadline until the client reads response headers
+		if err := ctl.SetWriteDeadline(time.Now().Add(1 * time.Millisecond)); err != nil {
+			t.Errorf("ctl.SetWriteDeadline() = %v, want nil", err)
+		}
+		_, err := io.Copy(w, neverEnding('a'))
+		errc <- err
+	}))
+
+	res, err := cst.c.Get(cst.ts.URL)
+	close(startwritec)
+	if err != nil {
+		t.Fatalf("unexpected connection error: %v", err)
+	}
+	defer res.Body.Close()
+	_, err = io.Copy(io.Discard, res.Body)
+	if err == nil {
+		t.Errorf("client reading from truncated request body: got nil error, want non-nil")
+	}
+	err = <-errc // io.Copy error
+	if !errors.Is(err, os.ErrDeadlineExceeded) {
+		t.Errorf("server timed out writing request body: got err %v; want os.ErrDeadlineExceeded", err)
+	}
+}
+
+func TestResponseControllerSetPastReadDeadline(t *testing.T) {
+	run(t, testResponseControllerSetPastReadDeadline)
+}
+func testResponseControllerSetPastReadDeadline(t *testing.T, mode testMode) {
+	readc := make(chan struct{})
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
+		ctl := NewResponseController(w)
+		b := make([]byte, 3)
+		n, err := io.ReadFull(r.Body, b)
+		b = b[:n]
+		if err != nil || string(b) != "one" {
+			t.Errorf("before setting read deadline: Read = %v, %q, want nil, %q", err, string(b), "one")
+			return
+		}
+		if err := ctl.SetReadDeadline(time.Now()); err != nil {
+			t.Errorf("ctl.SetReadDeadline() = %v, want nil", err)
+			return
+		}
+		b, err = io.ReadAll(r.Body)
+		if err == nil || string(b) != "" {
+			t.Errorf("after setting read deadline: Read = %q, nil, want error", string(b))
+		}
+		close(readc)
+		// Connection errors are sticky, so resetting the deadline does not permit
+		// making more progress. We might want to change this in the future, but verify
+		// the current behavior for now.
+		if err := ctl.SetReadDeadline(time.Time{}); err != nil {
+			t.Errorf("ctl.SetReadDeadline() = %v, want nil", err)
+			return
+		}
+		b, err = io.ReadAll(r.Body)
+		if err == nil {
+			t.Errorf("after resetting read deadline: Read = %q, nil, want error", string(b))
+		}
+	}))
+
+	pr, pw := io.Pipe()
+	var wg sync.WaitGroup
+	wg.Add(1)
+	go func() {
+		defer wg.Done()
+		pw.Write([]byte("one"))
+		<-readc
+		pw.Write([]byte("two"))
+		pw.Close()
+	}()
+	defer wg.Wait()
+	res, err := cst.c.Post(cst.ts.URL, "text/foo", pr)
+	if err == nil {
+		defer res.Body.Close()
+	}
+}
+
+func TestResponseControllerSetFutureReadDeadline(t *testing.T) {
+	run(t, testResponseControllerSetFutureReadDeadline)
+}
+func testResponseControllerSetFutureReadDeadline(t *testing.T, mode testMode) {
+	respBody := "response body"
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, req *Request) {
+		ctl := NewResponseController(w)
+		if err := ctl.SetReadDeadline(time.Now().Add(1 * time.Millisecond)); err != nil {
+			t.Errorf("ctl.SetReadDeadline() = %v, want nil", err)
+		}
+		_, err := io.Copy(io.Discard, req.Body)
+		if !errors.Is(err, os.ErrDeadlineExceeded) {
+			t.Errorf("server timed out reading request body: got err %v; want os.ErrDeadlineExceeded", err)
+		}
+		w.Write([]byte(respBody))
+	}))
+	pr, pw := io.Pipe()
+	res, err := cst.c.Post(cst.ts.URL, "text/apocryphal", pr)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer res.Body.Close()
+	got, err := io.ReadAll(res.Body)
+	if string(got) != respBody || err != nil {
+		t.Errorf("client read response body: %q, %v; want %q, nil", string(got), err, respBody)
+	}
+	pw.Close()
+}
+
+type wrapWriter struct {
+	ResponseWriter
+}
+
+func (w wrapWriter) Unwrap() ResponseWriter {
+	return w.ResponseWriter
+}
+
+func TestWrappedResponseController(t *testing.T) { run(t, testWrappedResponseController) }
+func testWrappedResponseController(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
+		w = wrapWriter{w}
+		ctl := NewResponseController(w)
+		if err := ctl.Flush(); err != nil {
+			t.Errorf("ctl.Flush() = %v, want nil", err)
+		}
+		if err := ctl.SetReadDeadline(time.Time{}); err != nil {
+			t.Errorf("ctl.SetReadDeadline() = %v, want nil", err)
+		}
+		if err := ctl.SetWriteDeadline(time.Time{}); err != nil {
+			t.Errorf("ctl.SetWriteDeadline() = %v, want nil", err)
+		}
+	}))
+	res, err := cst.c.Get(cst.ts.URL)
+	if err != nil {
+		t.Fatalf("unexpected connection error: %v", err)
+	}
+	io.Copy(io.Discard, res.Body)
+	defer res.Body.Close()
+}
diff --git a/src/net/http/responsewrite_test.go b/src/net/http/responsewrite_test.go
index 1cc87b9..226ad72 100644
--- a/src/net/http/responsewrite_test.go
+++ b/src/net/http/responsewrite_test.go
@@ -5,7 +5,6 @@
 package http
 
 import (
-	"bytes"
 	"io"
 	"strings"
 	"testing"
@@ -276,7 +275,7 @@
 
 	for i := range respWriteTests {
 		tt := &respWriteTests[i]
-		var braw bytes.Buffer
+		var braw strings.Builder
 		err := tt.Resp.Write(&braw)
 		if err != nil {
 			t.Errorf("error writing #%d: %s", i, err)
diff --git a/src/net/http/serve_test.go b/src/net/http/serve_test.go
index cb6312d..eac527b 100644
--- a/src/net/http/serve_test.go
+++ b/src/net/http/serve_test.go
@@ -20,6 +20,7 @@
 	"io"
 	"log"
 	"math/rand"
+	"mime/multipart"
 	"net"
 	. "net/http"
 	"net/http/httptest"
@@ -147,7 +148,7 @@
 
 func (ht *handlerTest) rawResponse(req string) string {
 	reqb := reqBytes(req)
-	var output bytes.Buffer
+	var output strings.Builder
 	conn := &rwTestConn{
 		Reader: bytes.NewReader(reqb),
 		Writer: &output,
@@ -245,15 +246,13 @@
 	{"http://someHost.com/someDir", "/someDir/"},
 }
 
-func TestHostHandlers(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
+func TestHostHandlers(t *testing.T) { run(t, testHostHandlers, []testMode{http1Mode}) }
+func testHostHandlers(t *testing.T, mode testMode) {
 	mux := NewServeMux()
 	for _, h := range handlers {
 		mux.Handle(h.pattern, stringHandler(h.msg))
 	}
-	ts := httptest.NewServer(mux)
-	defer ts.Close()
+	ts := newClientServerTest(t, mode, mux).ts
 
 	conn, err := net.Dial("tcp", ts.Listener.Addr().String())
 	if err != nil {
@@ -486,9 +485,9 @@
 // properly sets the query string in the redirect URL.
 // See Issue 17841.
 func TestServeWithSlashRedirectKeepsQueryString(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
-
+	run(t, testServeWithSlashRedirectKeepsQueryString, []testMode{http1Mode})
+}
+func testServeWithSlashRedirectKeepsQueryString(t *testing.T, mode testMode) {
 	writeBackQuery := func(w ResponseWriter, r *Request) {
 		fmt.Fprintf(w, "%s", r.URL.RawQuery)
 	}
@@ -501,8 +500,7 @@
 		fmt.Fprintf(w, "%s:bar", r.URL.RawQuery)
 	})
 
-	ts := httptest.NewServer(mux)
-	defer ts.Close()
+	ts := newClientServerTest(t, mode, mux).ts
 
 	tests := [...]struct {
 		path     string
@@ -545,7 +543,6 @@
 
 func TestServeWithSlashRedirectForHostPatterns(t *testing.T) {
 	setParallel(t)
-	defer afterTest(t)
 
 	mux := NewServeMux()
 	mux.Handle("example.com/pkg/foo/", stringHandler("example.com/pkg/foo/"))
@@ -577,9 +574,6 @@
 		{"CONNECT", "http://example.com:3000/pkg/connect", 301, "/pkg/connect/", ""},
 	}
 
-	ts := httptest.NewServer(mux)
-	defer ts.Close()
-
 	for i, tt := range tests {
 		req, _ := NewRequest(tt.method, tt.url, nil)
 		w := httptest.NewRecorder()
@@ -601,13 +595,10 @@
 	}
 }
 
-func TestShouldRedirectConcurrency(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
-
+func TestShouldRedirectConcurrency(t *testing.T) { run(t, testShouldRedirectConcurrency) }
+func testShouldRedirectConcurrency(t *testing.T, mode testMode) {
 	mux := NewServeMux()
-	ts := httptest.NewServer(mux)
-	defer ts.Close()
+	newClientServerTest(t, mode, mux)
 	mux.HandleFunc("/", func(w ResponseWriter, r *Request) {})
 }
 
@@ -655,13 +646,12 @@
 	}
 }
 
-func TestServerTimeouts(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
+func TestServerTimeouts(t *testing.T) { run(t, testServerTimeouts, []testMode{http1Mode}) }
+func testServerTimeouts(t *testing.T, mode testMode) {
 	// Try three times, with increasing timeouts.
 	tries := []time.Duration{250 * time.Millisecond, 500 * time.Millisecond, 1 * time.Second}
 	for i, timeout := range tries {
-		err := testServerTimeouts(timeout)
+		err := testServerTimeoutsWithTimeout(t, timeout, mode)
 		if err == nil {
 			return
 		}
@@ -673,16 +663,15 @@
 	t.Fatal("all attempts failed")
 }
 
-func testServerTimeouts(timeout time.Duration) error {
+func testServerTimeoutsWithTimeout(t *testing.T, timeout time.Duration, mode testMode) error {
 	reqNum := 0
-	ts := httptest.NewUnstartedServer(HandlerFunc(func(res ResponseWriter, req *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(res ResponseWriter, req *Request) {
 		reqNum++
 		fmt.Fprintf(res, "req=%d", reqNum)
-	}))
-	ts.Config.ReadTimeout = timeout
-	ts.Config.WriteTimeout = timeout
-	ts.Start()
-	defer ts.Close()
+	}), func(ts *httptest.Server) {
+		ts.Config.ReadTimeout = timeout
+		ts.Config.WriteTimeout = timeout
+	}).ts
 
 	// Hit the HTTP server successfully.
 	c := ts.Client()
@@ -747,23 +736,90 @@
 	return nil
 }
 
+func TestServerReadTimeout(t *testing.T) { run(t, testServerReadTimeout) }
+func testServerReadTimeout(t *testing.T, mode testMode) {
+	respBody := "response body"
+	for timeout := 5 * time.Millisecond; ; timeout *= 2 {
+		cst := newClientServerTest(t, mode, HandlerFunc(func(res ResponseWriter, req *Request) {
+			_, err := io.Copy(io.Discard, req.Body)
+			if !errors.Is(err, os.ErrDeadlineExceeded) {
+				t.Errorf("server timed out reading request body: got err %v; want os.ErrDeadlineExceeded", err)
+			}
+			res.Write([]byte(respBody))
+		}), func(ts *httptest.Server) {
+			ts.Config.ReadHeaderTimeout = -1 // don't time out while reading headers
+			ts.Config.ReadTimeout = timeout
+		})
+		pr, pw := io.Pipe()
+		res, err := cst.c.Post(cst.ts.URL, "text/apocryphal", pr)
+		if err != nil {
+			t.Logf("Get error, retrying: %v", err)
+			cst.close()
+			continue
+		}
+		defer res.Body.Close()
+		got, err := io.ReadAll(res.Body)
+		if string(got) != respBody || err != nil {
+			t.Errorf("client read response body: %q, %v; want %q, nil", string(got), err, respBody)
+		}
+		pw.Close()
+		break
+	}
+}
+
+func TestServerWriteTimeout(t *testing.T) { run(t, testServerWriteTimeout) }
+func testServerWriteTimeout(t *testing.T, mode testMode) {
+	for timeout := 5 * time.Millisecond; ; timeout *= 2 {
+		errc := make(chan error, 2)
+		cst := newClientServerTest(t, mode, HandlerFunc(func(res ResponseWriter, req *Request) {
+			errc <- nil
+			_, err := io.Copy(res, neverEnding('a'))
+			errc <- err
+		}), func(ts *httptest.Server) {
+			ts.Config.WriteTimeout = timeout
+		})
+		res, err := cst.c.Get(cst.ts.URL)
+		if err != nil {
+			// Probably caused by the write timeout expiring before the handler runs.
+			t.Logf("Get error, retrying: %v", err)
+			cst.close()
+			continue
+		}
+		defer res.Body.Close()
+		_, err = io.Copy(io.Discard, res.Body)
+		if err == nil {
+			t.Errorf("client reading from truncated request body: got nil error, want non-nil")
+		}
+		select {
+		case <-errc:
+			err = <-errc // io.Copy error
+			if !errors.Is(err, os.ErrDeadlineExceeded) {
+				t.Errorf("server timed out writing request body: got err %v; want os.ErrDeadlineExceeded", err)
+			}
+			return
+		default:
+			// The write timeout expired before the handler started.
+			t.Logf("handler didn't run, retrying")
+			cst.close()
+		}
+	}
+}
+
 // Test that the HTTP/2 server handles Server.WriteTimeout (Issue 18437)
-func TestHTTP2WriteDeadlineExtendedOnNewRequest(t *testing.T) {
+func TestWriteDeadlineExtendedOnNewRequest(t *testing.T) {
+	run(t, testWriteDeadlineExtendedOnNewRequest)
+}
+func testWriteDeadlineExtendedOnNewRequest(t *testing.T, mode testMode) {
 	if testing.Short() {
 		t.Skip("skipping in short mode")
 	}
-	setParallel(t)
-	defer afterTest(t)
-	ts := httptest.NewUnstartedServer(HandlerFunc(func(res ResponseWriter, req *Request) {}))
-	ts.Config.WriteTimeout = 250 * time.Millisecond
-	ts.TLS = &tls.Config{NextProtos: []string{"h2"}}
-	ts.StartTLS()
-	defer ts.Close()
+	ts := newClientServerTest(t, mode, HandlerFunc(func(res ResponseWriter, req *Request) {}),
+		func(ts *httptest.Server) {
+			ts.Config.WriteTimeout = 250 * time.Millisecond
+		},
+	).ts
 
 	c := ts.Client()
-	if err := ExportHttp2ConfigureTransport(c.Transport.(*Transport)); err != nil {
-		t.Fatal(err)
-	}
 
 	for i := 1; i <= 3; i++ {
 		req, err := NewRequest("GET", ts.URL, nil)
@@ -784,9 +840,6 @@
 			t.Fatalf("http2 Get #%d: %v", i, err)
 		}
 		r.Body.Close()
-		if r.ProtoMajor != 2 {
-			t.Fatalf("http2 Get expected HTTP/2.0, got %q", r.Proto)
-		}
 		time.Sleep(ts.Config.WriteTimeout / 2)
 	}
 }
@@ -809,33 +862,31 @@
 }
 
 // Test that the HTTP/2 server RSTs stream on slow write.
-func TestHTTP2WriteDeadlineEnforcedPerStream(t *testing.T) {
+func TestWriteDeadlineEnforcedPerStream(t *testing.T) {
 	if testing.Short() {
 		t.Skip("skipping in short mode")
 	}
 	setParallel(t)
-	defer afterTest(t)
-	tryTimeouts(t, testHTTP2WriteDeadlineEnforcedPerStream)
+	run(t, func(t *testing.T, mode testMode) {
+		tryTimeouts(t, func(timeout time.Duration) error {
+			return testWriteDeadlineEnforcedPerStream(t, mode, timeout)
+		})
+	})
 }
 
-func testHTTP2WriteDeadlineEnforcedPerStream(timeout time.Duration) error {
+func testWriteDeadlineEnforcedPerStream(t *testing.T, mode testMode, timeout time.Duration) error {
 	reqNum := 0
-	ts := httptest.NewUnstartedServer(HandlerFunc(func(res ResponseWriter, req *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(res ResponseWriter, req *Request) {
 		reqNum++
 		if reqNum == 1 {
 			return // first request succeeds
 		}
 		time.Sleep(timeout) // second request times out
-	}))
-	ts.Config.WriteTimeout = timeout / 2
-	ts.TLS = &tls.Config{NextProtos: []string{"h2"}}
-	ts.StartTLS()
-	defer ts.Close()
+	}), func(ts *httptest.Server) {
+		ts.Config.WriteTimeout = timeout / 2
+	}).ts
 
 	c := ts.Client()
-	if err := ExportHttp2ConfigureTransport(c.Transport.(*Transport)); err != nil {
-		return fmt.Errorf("ExportHttp2ConfigureTransport: %v", err)
-	}
 
 	req, err := NewRequest("GET", ts.URL, nil)
 	if err != nil {
@@ -843,12 +894,9 @@
 	}
 	r, err := c.Do(req)
 	if err != nil {
-		return fmt.Errorf("http2 Get #1: %v", err)
+		return fmt.Errorf("Get #1: %v", err)
 	}
 	r.Body.Close()
-	if r.ProtoMajor != 2 {
-		return fmt.Errorf("http2 Get expected HTTP/2.0, got %q", r.Proto)
-	}
 
 	req, err = NewRequest("GET", ts.URL, nil)
 	if err != nil {
@@ -857,45 +905,42 @@
 	r, err = c.Do(req)
 	if err == nil {
 		r.Body.Close()
-		if r.ProtoMajor != 2 {
-			return fmt.Errorf("http2 Get expected HTTP/2.0, got %q", r.Proto)
-		}
-		return fmt.Errorf("http2 Get #2 expected error, got nil")
+		return fmt.Errorf("Get #2 expected error, got nil")
 	}
-	expected := "stream ID 3; INTERNAL_ERROR" // client IDs are odd, second stream should be 3
-	if !strings.Contains(err.Error(), expected) {
-		return fmt.Errorf("http2 Get #2: expected error to contain %q, got %q", expected, err)
+	if mode == http2Mode {
+		expected := "stream ID 3; INTERNAL_ERROR" // client IDs are odd, second stream should be 3
+		if !strings.Contains(err.Error(), expected) {
+			return fmt.Errorf("http2 Get #2: expected error to contain %q, got %q", expected, err)
+		}
 	}
 	return nil
 }
 
 // Test that the HTTP/2 server does not send RST when WriteDeadline not set.
-func TestHTTP2NoWriteDeadline(t *testing.T) {
+func TestNoWriteDeadline(t *testing.T) {
 	if testing.Short() {
 		t.Skip("skipping in short mode")
 	}
 	setParallel(t)
 	defer afterTest(t)
-	tryTimeouts(t, testHTTP2NoWriteDeadline)
+	run(t, func(t *testing.T, mode testMode) {
+		tryTimeouts(t, func(timeout time.Duration) error {
+			return testNoWriteDeadline(t, mode, timeout)
+		})
+	})
 }
 
-func testHTTP2NoWriteDeadline(timeout time.Duration) error {
+func testNoWriteDeadline(t *testing.T, mode testMode, timeout time.Duration) error {
 	reqNum := 0
-	ts := httptest.NewUnstartedServer(HandlerFunc(func(res ResponseWriter, req *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(res ResponseWriter, req *Request) {
 		reqNum++
 		if reqNum == 1 {
 			return // first request succeeds
 		}
 		time.Sleep(timeout) // second request timesout
-	}))
-	ts.TLS = &tls.Config{NextProtos: []string{"h2"}}
-	ts.StartTLS()
-	defer ts.Close()
+	})).ts
 
 	c := ts.Client()
-	if err := ExportHttp2ConfigureTransport(c.Transport.(*Transport)); err != nil {
-		return fmt.Errorf("ExportHttp2ConfigureTransport: %v", err)
-	}
 
 	for i := 0; i < 2; i++ {
 		req, err := NewRequest("GET", ts.URL, nil)
@@ -904,12 +949,9 @@
 		}
 		r, err := c.Do(req)
 		if err != nil {
-			return fmt.Errorf("http2 Get #%d: %v", i, err)
+			return fmt.Errorf("Get #%d: %v", i, err)
 		}
 		r.Body.Close()
-		if r.ProtoMajor != 2 {
-			return fmt.Errorf("http2 Get expected HTTP/2.0, got %q", r.Proto)
-		}
 	}
 	return nil
 }
@@ -917,15 +959,14 @@
 // golang.org/issue/4741 -- setting only a write timeout that triggers
 // shouldn't cause a handler to block forever on reads (next HTTP
 // request) that will never happen.
-func TestOnlyWriteTimeout(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
+func TestOnlyWriteTimeout(t *testing.T) { run(t, testOnlyWriteTimeout, []testMode{http1Mode}) }
+func testOnlyWriteTimeout(t *testing.T, mode testMode) {
 	var (
 		mu   sync.RWMutex
 		conn net.Conn
 	)
 	var afterTimeoutErrc = make(chan error, 1)
-	ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, req *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, req *Request) {
 		buf := make([]byte, 512<<10)
 		_, err := w.Write(buf)
 		if err != nil {
@@ -941,10 +982,9 @@
 		conn.SetWriteDeadline(time.Now().Add(-30 * time.Second))
 		_, err = w.Write(buf)
 		afterTimeoutErrc <- err
-	}))
-	ts.Listener = trackLastConnListener{ts.Listener, &mu, &conn}
-	ts.Start()
-	defer ts.Close()
+	}), func(ts *httptest.Server) {
+		ts.Listener = trackLastConnListener{ts.Listener, &mu, &conn}
+	}).ts
 
 	c := ts.Client()
 
@@ -991,9 +1031,12 @@
 }
 
 // TestIdentityResponse verifies that a handler can unset
-func TestIdentityResponse(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
+func TestIdentityResponse(t *testing.T) { run(t, testIdentityResponse) }
+func testIdentityResponse(t *testing.T, mode testMode) {
+	if mode == http2Mode {
+		t.Skip("https://go.dev/issue/56019")
+	}
+
 	handler := HandlerFunc(func(rw ResponseWriter, req *Request) {
 		rw.Header().Set("Content-Length", "3")
 		rw.Header().Set("Transfer-Encoding", req.FormValue("te"))
@@ -1011,9 +1054,7 @@
 		}
 	})
 
-	ts := httptest.NewServer(handler)
-	defer ts.Close()
-
+	ts := newClientServerTest(t, mode, handler).ts
 	c := ts.Client()
 
 	// Note: this relies on the assumption (which is true) that
@@ -1047,6 +1088,10 @@
 	}
 	res.Body.Close()
 
+	if mode != http1Mode {
+		return
+	}
+
 	// Verify that the connection is closed when the declared Content-Length
 	// is larger than what the handler wrote.
 	conn, err := net.Dial("tcp", ts.Listener.Addr().String())
@@ -1069,9 +1114,7 @@
 
 func testTCPConnectionCloses(t *testing.T, req string, h Handler) {
 	setParallel(t)
-	defer afterTest(t)
-	s := httptest.NewServer(h)
-	defer s.Close()
+	s := newClientServerTest(t, http1Mode, h).ts
 
 	conn, err := net.Dial("tcp", s.Listener.Addr().String())
 	if err != nil {
@@ -1113,9 +1156,7 @@
 
 func testTCPConnectionStaysOpen(t *testing.T, req string, handler Handler) {
 	setParallel(t)
-	defer afterTest(t)
-	ts := httptest.NewServer(handler)
-	defer ts.Close()
+	ts := newClientServerTest(t, http1Mode, handler).ts
 	conn, err := net.Dial("tcp", ts.Listener.Addr().String())
 	if err != nil {
 		t.Fatal(err)
@@ -1191,14 +1232,12 @@
 }
 
 // Issue 15703
-func TestKeepAliveFinalChunkWithEOF(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
-	cst := newClientServerTest(t, false /* h1 */, HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestKeepAliveFinalChunkWithEOF(t *testing.T) { run(t, testKeepAliveFinalChunkWithEOF) }
+func testKeepAliveFinalChunkWithEOF(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		w.(Flusher).Flush() // force chunked encoding
 		w.Write([]byte("{\"Addr\": \"" + r.RemoteAddr + "\"}"))
 	}))
-	defer cst.close()
 	type data struct {
 		Addr string
 	}
@@ -1221,16 +1260,11 @@
 	}
 }
 
-func TestSetsRemoteAddr_h1(t *testing.T) { testSetsRemoteAddr(t, h1Mode) }
-func TestSetsRemoteAddr_h2(t *testing.T) { testSetsRemoteAddr(t, h2Mode) }
-
-func testSetsRemoteAddr(t *testing.T, h2 bool) {
-	setParallel(t)
-	defer afterTest(t)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestSetsRemoteAddr(t *testing.T) { run(t, testSetsRemoteAddr) }
+func testSetsRemoteAddr(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		fmt.Fprintf(w, "%s", r.RemoteAddr)
 	}))
-	defer cst.close()
 
 	res, err := cst.c.Get(cst.ts.URL)
 	if err != nil {
@@ -1275,17 +1309,18 @@
 
 // Issue 12943
 func TestServerAllowsBlockingRemoteAddr(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		fmt.Fprintf(w, "RA:%s", r.RemoteAddr)
-	}))
+	run(t, testServerAllowsBlockingRemoteAddr, []testMode{http1Mode})
+}
+func testServerAllowsBlockingRemoteAddr(t *testing.T, mode testMode) {
 	conns := make(chan net.Conn)
-	ts.Listener = &blockingRemoteAddrListener{
-		Listener: ts.Listener,
-		conns:    conns,
-	}
-	ts.Start()
-	defer ts.Close()
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
+		fmt.Fprintf(w, "RA:%s", r.RemoteAddr)
+	}), func(ts *httptest.Server) {
+		ts.Listener = &blockingRemoteAddrListener{
+			Listener: ts.Listener,
+			conns:    conns,
+		}
+	}).ts
 
 	c := ts.Client()
 	c.Timeout = time.Second
@@ -1350,13 +1385,9 @@
 
 // TestHeadResponses verifies that all MIME type sniffing and Content-Length
 // counting of GET requests also happens on HEAD requests.
-func TestHeadResponses_h1(t *testing.T) { testHeadResponses(t, h1Mode) }
-func TestHeadResponses_h2(t *testing.T) { testHeadResponses(t, h2Mode) }
-
-func testHeadResponses(t *testing.T, h2 bool) {
-	setParallel(t)
-	defer afterTest(t)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestHeadResponses(t *testing.T) { run(t, testHeadResponses) }
+func testHeadResponses(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		_, err := w.Write([]byte("<html>"))
 		if err != nil {
 			t.Errorf("ResponseWriter.Write: %v", err)
@@ -1368,7 +1399,6 @@
 			t.Errorf("Copy(ResponseWriter, ...): %v", err)
 		}
 	}))
-	defer cst.close()
 	res, err := cst.c.Head(cst.ts.URL)
 	if err != nil {
 		t.Error(err)
@@ -1392,14 +1422,16 @@
 }
 
 func TestTLSHandshakeTimeout(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
-	ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
+	run(t, testTLSHandshakeTimeout, []testMode{https1Mode, http2Mode})
+}
+func testTLSHandshakeTimeout(t *testing.T, mode testMode) {
 	errc := make(chanWriter, 10) // but only expecting 1
-	ts.Config.ReadTimeout = 250 * time.Millisecond
-	ts.Config.ErrorLog = log.New(errc, "", 0)
-	ts.StartTLS()
-	defer ts.Close()
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {}),
+		func(ts *httptest.Server) {
+			ts.Config.ReadTimeout = 250 * time.Millisecond
+			ts.Config.ErrorLog = log.New(errc, "", 0)
+		},
+	).ts
 	conn, err := net.Dial("tcp", ts.Listener.Addr().String())
 	if err != nil {
 		t.Fatalf("Dial: %v", err)
@@ -1422,19 +1454,18 @@
 	}
 }
 
-func TestTLSServer(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
-	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestTLSServer(t *testing.T) { run(t, testTLSServer, []testMode{https1Mode, http2Mode}) }
+func testTLSServer(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		if r.TLS != nil {
 			w.Header().Set("X-TLS-Set", "true")
 			if r.TLS.HandshakeComplete {
 				w.Header().Set("X-TLS-HandshakeComplete", "true")
 			}
 		}
-	}))
-	ts.Config.ErrorLog = log.New(io.Discard, "", 0)
-	defer ts.Close()
+	}), func(ts *httptest.Server) {
+		ts.Config.ErrorLog = log.New(io.Discard, "", 0)
+	}).ts
 
 	// Connect an idle TCP connection to this server before we run
 	// our real tests. This idle connection used to block forever
@@ -1527,14 +1558,15 @@
 
 // Test that the HTTPS server nicely rejects plaintext HTTP/1.x requests.
 func TestTLSServerRejectHTTPRequests(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
-	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	run(t, testTLSServerRejectHTTPRequests, []testMode{https1Mode, http2Mode})
+}
+func testTLSServerRejectHTTPRequests(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		t.Error("unexpected HTTPS request")
-	}))
-	var errBuf bytes.Buffer
-	ts.Config.ErrorLog = log.New(&errBuf, "", 0)
-	defer ts.Close()
+	}), func(ts *httptest.Server) {
+		var errBuf bytes.Buffer
+		ts.Config.ErrorLog = log.New(&errBuf, "", 0)
+	}).ts
 	conn, err := net.Dial("tcp", ts.Listener.Addr().String())
 	if err != nil {
 		t.Fatal(err)
@@ -1726,11 +1758,9 @@
 
 // Tests that the server responds to the "Expect" request header
 // correctly.
-// http2 test: TestServer_Response_Automatic100Continue
-func TestServerExpect(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestServerExpect(t *testing.T) { run(t, testServerExpect, []testMode{http1Mode}) }
+func testServerExpect(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		// Note using r.FormValue("readbody") because for POST
 		// requests that would read from r.Body, which we only
 		// conditionally want to do.
@@ -1740,8 +1770,7 @@
 		} else {
 			w.WriteHeader(StatusUnauthorized)
 		}
-	}))
-	defer ts.Close()
+	})).ts
 
 	runTest := func(test serverExpectTest) {
 		conn, err := net.Dial("tcp", ts.Listener.Addr().String())
@@ -2286,11 +2315,8 @@
 	return nil
 }
 
-func TestTimeoutHandler_h1(t *testing.T) { testTimeoutHandler(t, h1Mode) }
-func TestTimeoutHandler_h2(t *testing.T) { testTimeoutHandler(t, h2Mode) }
-func testTimeoutHandler(t *testing.T, h2 bool) {
-	setParallel(t)
-	defer afterTest(t)
+func TestTimeoutHandler(t *testing.T) { run(t, testTimeoutHandler) }
+func testTimeoutHandler(t *testing.T, mode testMode) {
 	sendHi := make(chan bool, 1)
 	writeErrors := make(chan error, 1)
 	sayHi := HandlerFunc(func(w ResponseWriter, r *Request) {
@@ -2300,8 +2326,7 @@
 	})
 	ctx, cancel := context.WithCancel(context.Background())
 	h := NewTestTimeoutHandler(sayHi, cancelableTimeoutContext{ctx})
-	cst := newClientServerTest(t, h2, h)
-	defer cst.close()
+	cst := newClientServerTest(t, mode, h)
 
 	// Succeed without timing out:
 	sendHi <- true
@@ -2347,10 +2372,8 @@
 }
 
 // See issues 8209 and 8414.
-func TestTimeoutHandlerRace(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
-
+func TestTimeoutHandlerRace(t *testing.T) { run(t, testTimeoutHandlerRace) }
+func testTimeoutHandlerRace(t *testing.T, mode testMode) {
 	delayHi := HandlerFunc(func(w ResponseWriter, r *Request) {
 		ms, _ := strconv.Atoi(r.URL.Path[1:])
 		if ms == 0 {
@@ -2362,8 +2385,7 @@
 		}
 	})
 
-	ts := httptest.NewServer(TimeoutHandler(delayHi, 20*time.Millisecond, ""))
-	defer ts.Close()
+	ts := newClientServerTest(t, mode, TimeoutHandler(delayHi, 20*time.Millisecond, "")).ts
 
 	c := ts.Client()
 
@@ -2392,16 +2414,13 @@
 
 // See issues 8209 and 8414.
 // Both issues involved panics in the implementation of TimeoutHandler.
-func TestTimeoutHandlerRaceHeader(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
-
+func TestTimeoutHandlerRaceHeader(t *testing.T) { run(t, testTimeoutHandlerRaceHeader) }
+func testTimeoutHandlerRaceHeader(t *testing.T, mode testMode) {
 	delay204 := HandlerFunc(func(w ResponseWriter, r *Request) {
 		w.WriteHeader(204)
 	})
 
-	ts := httptest.NewServer(TimeoutHandler(delay204, time.Nanosecond, ""))
-	defer ts.Close()
+	ts := newClientServerTest(t, mode, TimeoutHandler(delay204, time.Nanosecond, "")).ts
 
 	var wg sync.WaitGroup
 	gate := make(chan bool, 50)
@@ -2432,9 +2451,8 @@
 }
 
 // Issue 9162
-func TestTimeoutHandlerRaceHeaderTimeout(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
+func TestTimeoutHandlerRaceHeaderTimeout(t *testing.T) { run(t, testTimeoutHandlerRaceHeaderTimeout) }
+func testTimeoutHandlerRaceHeaderTimeout(t *testing.T, mode testMode) {
 	sendHi := make(chan bool, 1)
 	writeErrors := make(chan error, 1)
 	sayHi := HandlerFunc(func(w ResponseWriter, r *Request) {
@@ -2445,8 +2463,7 @@
 	})
 	ctx, cancel := context.WithCancel(context.Background())
 	h := NewTestTimeoutHandler(sayHi, cancelableTimeoutContext{ctx})
-	cst := newClientServerTest(t, h1Mode, h)
-	defer cst.close()
+	cst := newClientServerTest(t, mode, h)
 
 	// Succeed without timing out:
 	sendHi <- true
@@ -2490,15 +2507,17 @@
 
 // Issue 14568.
 func TestTimeoutHandlerStartTimerWhenServing(t *testing.T) {
+	run(t, testTimeoutHandlerStartTimerWhenServing)
+}
+func testTimeoutHandlerStartTimerWhenServing(t *testing.T, mode testMode) {
 	if testing.Short() {
 		t.Skip("skipping sleeping test in -short mode")
 	}
-	defer afterTest(t)
 	var handler HandlerFunc = func(w ResponseWriter, _ *Request) {
 		w.WriteHeader(StatusNoContent)
 	}
 	timeout := 300 * time.Millisecond
-	ts := httptest.NewServer(TimeoutHandler(handler, timeout, ""))
+	ts := newClientServerTest(t, mode, TimeoutHandler(handler, timeout, "")).ts
 	defer ts.Close()
 
 	c := ts.Client()
@@ -2517,9 +2536,8 @@
 	}
 }
 
-func TestTimeoutHandlerContextCanceled(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
+func TestTimeoutHandlerContextCanceled(t *testing.T) { run(t, testTimeoutHandlerContextCanceled) }
+func testTimeoutHandlerContextCanceled(t *testing.T, mode testMode) {
 	writeErrors := make(chan error, 1)
 	sayHi := HandlerFunc(func(w ResponseWriter, r *Request) {
 		w.Header().Set("Content-Type", "text/plain")
@@ -2539,7 +2557,7 @@
 	ctx, cancel := context.WithCancel(context.Background())
 	cancel()
 	h := NewTestTimeoutHandler(sayHi, ctx)
-	cst := newClientServerTest(t, h1Mode, h)
+	cst := newClientServerTest(t, mode, h)
 	defer cst.close()
 
 	res, err := cst.c.Get(cst.ts.URL)
@@ -2559,15 +2577,13 @@
 }
 
 // https://golang.org/issue/15948
-func TestTimeoutHandlerEmptyResponse(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
+func TestTimeoutHandlerEmptyResponse(t *testing.T) { run(t, testTimeoutHandlerEmptyResponse) }
+func testTimeoutHandlerEmptyResponse(t *testing.T, mode testMode) {
 	var handler HandlerFunc = func(w ResponseWriter, _ *Request) {
 		// No response.
 	}
 	timeout := 300 * time.Millisecond
-	ts := httptest.NewServer(TimeoutHandler(handler, timeout, ""))
-	defer ts.Close()
+	ts := newClientServerTest(t, mode, TimeoutHandler(handler, timeout, "")).ts
 
 	c := ts.Client()
 
@@ -2586,7 +2602,9 @@
 	wrapper := func(h Handler) Handler {
 		return TimeoutHandler(h, time.Second, "")
 	}
-	testHandlerPanic(t, false, false, wrapper, "intentional death for testing")
+	run(t, func(t *testing.T, mode testMode) {
+		testHandlerPanic(t, false, mode, wrapper, "intentional death for testing")
+	}, testNotParallel)
 }
 
 func TestRedirectBadPath(t *testing.T) {
@@ -2704,17 +2722,10 @@
 // connection immediately. But when it re-uses the connection, it typically closes
 // the previous request's body, which is not optimal for zero-lengthed bodies,
 // as the client would then see http.ErrBodyReadAfterClose and not 0, io.EOF.
-func TestZeroLengthPostAndResponse_h1(t *testing.T) {
-	testZeroLengthPostAndResponse(t, h1Mode)
-}
-func TestZeroLengthPostAndResponse_h2(t *testing.T) {
-	testZeroLengthPostAndResponse(t, h2Mode)
-}
+func TestZeroLengthPostAndResponse(t *testing.T) { run(t, testZeroLengthPostAndResponse) }
 
-func testZeroLengthPostAndResponse(t *testing.T, h2 bool) {
-	setParallel(t)
-	defer afterTest(t)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(rw ResponseWriter, r *Request) {
+func testZeroLengthPostAndResponse(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(rw ResponseWriter, r *Request) {
 		all, err := io.ReadAll(r.Body)
 		if err != nil {
 			t.Fatalf("handler ReadAll: %v", err)
@@ -2724,7 +2735,6 @@
 		}
 		rw.Header().Set("Content-Length", "0")
 	}))
-	defer cst.close()
 
 	req, err := NewRequest("POST", cst.ts.URL, strings.NewReader(""))
 	if err != nil {
@@ -2751,42 +2761,35 @@
 	}
 }
 
-func TestHandlerPanicNil_h1(t *testing.T) { testHandlerPanic(t, false, h1Mode, nil, nil) }
-func TestHandlerPanicNil_h2(t *testing.T) { testHandlerPanic(t, false, h2Mode, nil, nil) }
-
-func TestHandlerPanic_h1(t *testing.T) {
-	testHandlerPanic(t, false, h1Mode, nil, "intentional death for testing")
+func TestHandlerPanicNil(t *testing.T) {
+	run(t, func(t *testing.T, mode testMode) {
+		testHandlerPanic(t, false, mode, nil, nil)
+	}, testNotParallel)
 }
-func TestHandlerPanic_h2(t *testing.T) {
-	testHandlerPanic(t, false, h2Mode, nil, "intentional death for testing")
+
+func TestHandlerPanic(t *testing.T) {
+	run(t, func(t *testing.T, mode testMode) {
+		testHandlerPanic(t, false, mode, nil, "intentional death for testing")
+	}, testNotParallel)
 }
 
 func TestHandlerPanicWithHijack(t *testing.T) {
 	// Only testing HTTP/1, and our http2 server doesn't support hijacking.
-	testHandlerPanic(t, true, h1Mode, nil, "intentional death for testing")
+	run(t, func(t *testing.T, mode testMode) {
+		testHandlerPanic(t, true, mode, nil, "intentional death for testing")
+	}, []testMode{http1Mode})
 }
 
-func testHandlerPanic(t *testing.T, withHijack, h2 bool, wrapper func(Handler) Handler, panicValue any) {
-	defer afterTest(t)
-	// Unlike the other tests that set the log output to io.Discard
-	// to quiet the output, this test uses a pipe. The pipe serves three
-	// purposes:
+func testHandlerPanic(t *testing.T, withHijack bool, mode testMode, wrapper func(Handler) Handler, panicValue any) {
+	// Direct log output to a pipe.
 	//
-	//   1) The log.Print from the http server (generated by the caught
-	//      panic) will go to the pipe instead of stderr, making the
-	//      output quiet.
+	// We read from the pipe to verify that the handler actually caught the panic
+	// and logged something.
 	//
-	//   2) We read from the pipe to verify that the handler
-	//      actually caught the panic and logged something.
-	//
-	//   3) The blocking Read call prevents this TestHandlerPanic
-	//      function from exiting before the HTTP server handler
-	//      finishes crashing. If this text function exited too
-	//      early (and its defer log.SetOutput(os.Stderr) ran),
-	//      then the crash output could spill into the next test.
+	// We use a pipe rather than a buffer, because when testing connection hijacking
+	// server shutdown doesn't wait for the hijacking handler to return, so the
+	// log may occur after the server has shut down.
 	pr, pw := io.Pipe()
-	log.SetOutput(pw)
-	defer log.SetOutput(os.Stderr)
 	defer pw.Close()
 
 	var handler Handler = HandlerFunc(func(w ResponseWriter, r *Request) {
@@ -2802,12 +2805,11 @@
 	if wrapper != nil {
 		handler = wrapper(handler)
 	}
-	cst := newClientServerTest(t, h2, handler)
-	defer cst.close()
+	cst := newClientServerTest(t, mode, handler, func(ts *httptest.Server) {
+		ts.Config.ErrorLog = log.New(pw, "", 0)
+	})
 
-	// Do a blocking read on the log output pipe so its logging
-	// doesn't bleed into the next test. But wait only 5 seconds
-	// for it.
+	// Do a blocking read on the log output pipe.
 	done := make(chan bool, 1)
 	go func() {
 		buf := make([]byte, 4<<10)
@@ -2828,10 +2830,16 @@
 		return
 	}
 
+	var delay time.Duration
+	if deadline, ok := t.Deadline(); ok {
+		delay = time.Until(deadline)
+	} else {
+		delay = 5 * time.Second
+	}
 	select {
 	case <-done:
 		return
-	case <-time.After(5 * time.Second):
+	case <-time.After(delay):
 		t.Fatal("expected server handler to log an error")
 	}
 }
@@ -2846,9 +2854,11 @@
 // Issue 16456: allow writing 0 bytes on hijacked conn to test hijack
 // without any log spam.
 func TestServerWriteHijackZeroBytes(t *testing.T) {
-	defer afterTest(t)
+	run(t, testServerWriteHijackZeroBytes, []testMode{http1Mode})
+}
+func testServerWriteHijackZeroBytes(t *testing.T, mode testMode) {
 	done := make(chan struct{})
-	ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		defer close(done)
 		w.(Flusher).Flush()
 		conn, _, err := w.(Hijacker).Hijack()
@@ -2861,10 +2871,9 @@
 		if err != ErrHijacked {
 			t.Errorf("Write error = %v; want ErrHijacked", err)
 		}
-	}))
-	ts.Config.ErrorLog = log.New(terrorWriter{t}, "Unexpected write: ", 0)
-	ts.Start()
-	defer ts.Close()
+	}), func(ts *httptest.Server) {
+		ts.Config.ErrorLog = log.New(terrorWriter{t}, "Unexpected write: ", 0)
+	}).ts
 
 	c := ts.Client()
 	res, err := c.Get(ts.URL)
@@ -2879,19 +2888,23 @@
 	}
 }
 
-func TestServerNoDate_h1(t *testing.T)        { testServerNoHeader(t, h1Mode, "Date") }
-func TestServerNoDate_h2(t *testing.T)        { testServerNoHeader(t, h2Mode, "Date") }
-func TestServerNoContentType_h1(t *testing.T) { testServerNoHeader(t, h1Mode, "Content-Type") }
-func TestServerNoContentType_h2(t *testing.T) { testServerNoHeader(t, h2Mode, "Content-Type") }
+func TestServerNoDate(t *testing.T) {
+	run(t, func(t *testing.T, mode testMode) {
+		testServerNoHeader(t, mode, "Date")
+	})
+}
 
-func testServerNoHeader(t *testing.T, h2 bool, header string) {
-	setParallel(t)
-	defer afterTest(t)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestServerContentType(t *testing.T) {
+	run(t, func(t *testing.T, mode testMode) {
+		testServerNoHeader(t, mode, "Content-Type")
+	})
+}
+
+func testServerNoHeader(t *testing.T, mode testMode, header string) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		w.Header()[header] = nil
 		io.WriteString(w, "<html>foo</html>") // non-empty
 	}))
-	defer cst.close()
 	res, err := cst.c.Get(cst.ts.URL)
 	if err != nil {
 		t.Fatal(err)
@@ -2902,15 +2915,13 @@
 	}
 }
 
-func TestStripPrefix(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
+func TestStripPrefix(t *testing.T) { run(t, testStripPrefix) }
+func testStripPrefix(t *testing.T, mode testMode) {
 	h := HandlerFunc(func(w ResponseWriter, r *Request) {
 		w.Header().Set("X-Path", r.URL.Path)
 		w.Header().Set("X-RawPath", r.URL.RawPath)
 	})
-	ts := httptest.NewServer(StripPrefix("/foo/bar", h))
-	defer ts.Close()
+	ts := newClientServerTest(t, mode, StripPrefix("/foo/bar", h)).ts
 
 	c := ts.Client()
 
@@ -2960,15 +2971,11 @@
 	}
 }
 
-func TestRequestLimit_h1(t *testing.T) { testRequestLimit(t, h1Mode) }
-func TestRequestLimit_h2(t *testing.T) { testRequestLimit(t, h2Mode) }
-func testRequestLimit(t *testing.T, h2 bool) {
-	setParallel(t)
-	defer afterTest(t)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestRequestLimit(t *testing.T) { run(t, testRequestLimit) }
+func testRequestLimit(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		t.Fatalf("didn't expect to get request in Handler")
 	}), optQuietLog)
-	defer cst.close()
 	req, _ := NewRequest("GET", cst.ts.URL, nil)
 	var bytesPerHeader = len("header12345: val12345\r\n")
 	for i := 0; i < ((DefaultMaxHeaderBytes+4096)/bytesPerHeader)+1; i++ {
@@ -2978,7 +2985,7 @@
 	if res != nil {
 		defer res.Body.Close()
 	}
-	if h2 {
+	if mode == http2Mode {
 		// In HTTP/2, the result depends on a race. If the client has received the
 		// server's SETTINGS before RoundTrip starts sending the request, then RoundTrip
 		// will fail with an error. Otherwise, the client should receive a 431 from the
@@ -3020,13 +3027,10 @@
 	return
 }
 
-func TestRequestBodyLimit_h1(t *testing.T) { testRequestBodyLimit(t, h1Mode) }
-func TestRequestBodyLimit_h2(t *testing.T) { testRequestBodyLimit(t, h2Mode) }
-func testRequestBodyLimit(t *testing.T, h2 bool) {
-	setParallel(t)
-	defer afterTest(t)
+func TestRequestBodyLimit(t *testing.T) { run(t, testRequestBodyLimit) }
+func testRequestBodyLimit(t *testing.T, mode testMode) {
 	const limit = 1 << 20
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		r.Body = MaxBytesReader(w, r.Body, limit)
 		n, err := io.Copy(io.Discard, r.Body)
 		if err == nil {
@@ -3043,7 +3047,6 @@
 			t.Errorf("MaxBytesError.Limit = %d, want %d", mbErr.Limit, limit)
 		}
 	}))
-	defer cst.close()
 
 	nWritten := new(int64)
 	req, _ := NewRequest("POST", cst.ts.URL, io.LimitReader(countReader{neverEnding('a'), nWritten}, limit*200))
@@ -3067,13 +3070,12 @@
 
 // TestClientWriteShutdown tests that if the client shuts down the write
 // side of their TCP connection, the server doesn't send a 400 Bad Request.
-func TestClientWriteShutdown(t *testing.T) {
+func TestClientWriteShutdown(t *testing.T) { run(t, testClientWriteShutdown) }
+func testClientWriteShutdown(t *testing.T, mode testMode) {
 	if runtime.GOOS == "plan9" {
 		t.Skip("skipping test; see https://golang.org/issue/17906")
 	}
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
-	defer ts.Close()
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {})).ts
 	conn, err := net.Dial("tcp", ts.Listener.Addr().String())
 	if err != nil {
 		t.Fatalf("Dial: %v", err)
@@ -3118,12 +3120,12 @@
 // closing the TCP connection, causing the client to get a RST.
 // See https://golang.org/issue/3595
 func TestServerGracefulClose(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	run(t, testServerGracefulClose, []testMode{http1Mode})
+}
+func testServerGracefulClose(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		Error(w, "bye", StatusUnauthorized)
-	}))
-	defer ts.Close()
+	})).ts
 
 	conn, err := net.Dial("tcp", ts.Listener.Addr().String())
 	if err != nil {
@@ -3161,11 +3163,9 @@
 	<-writeErr
 }
 
-func TestCaseSensitiveMethod_h1(t *testing.T) { testCaseSensitiveMethod(t, h1Mode) }
-func TestCaseSensitiveMethod_h2(t *testing.T) { testCaseSensitiveMethod(t, h2Mode) }
-func testCaseSensitiveMethod(t *testing.T, h2 bool) {
-	defer afterTest(t)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestCaseSensitiveMethod(t *testing.T) { run(t, testCaseSensitiveMethod) }
+func testCaseSensitiveMethod(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		if r.Method != "get" {
 			t.Errorf(`Got method %q; want "get"`, r.Method)
 		}
@@ -3186,8 +3186,10 @@
 // response, the net/http package adds a "Content-Length: 0" response
 // header.
 func TestContentLengthZero(t *testing.T) {
-	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {}))
-	defer ts.Close()
+	run(t, testContentLengthZero, []testMode{http1Mode})
+}
+func testContentLengthZero(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(rw ResponseWriter, req *Request) {})).ts
 
 	for _, version := range []string{"HTTP/1.0", "HTTP/1.1"} {
 		conn, err := net.Dial("tcp", ts.Listener.Addr().String())
@@ -3214,15 +3216,17 @@
 }
 
 func TestCloseNotifier(t *testing.T) {
-	defer afterTest(t)
+	run(t, testCloseNotifier, []testMode{http1Mode})
+}
+func testCloseNotifier(t *testing.T, mode testMode) {
 	gotReq := make(chan bool, 1)
 	sawClose := make(chan bool, 1)
-	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(rw ResponseWriter, req *Request) {
 		gotReq <- true
 		cc := rw.(CloseNotifier).CloseNotify()
 		<-cc
 		sawClose <- true
-	}))
+	})).ts
 	conn, err := net.Dial("tcp", ts.Listener.Addr().String())
 	if err != nil {
 		t.Fatalf("error dialing: %v", err)
@@ -3256,11 +3260,12 @@
 //
 // Issue 13165 (where it used to deadlock), but behavior changed in Issue 23921.
 func TestCloseNotifierPipelined(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
+	run(t, testCloseNotifierPipelined, []testMode{http1Mode})
+}
+func testCloseNotifierPipelined(t *testing.T, mode testMode) {
 	gotReq := make(chan bool, 2)
 	sawClose := make(chan bool, 2)
-	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(rw ResponseWriter, req *Request) {
 		gotReq <- true
 		cc := rw.(CloseNotifier).CloseNotify()
 		select {
@@ -3269,8 +3274,7 @@
 		case <-time.After(100 * time.Millisecond):
 		}
 		sawClose <- true
-	}))
-	defer ts.Close()
+	})).ts
 	conn, err := net.Dial("tcp", ts.Listener.Addr().String())
 	if err != nil {
 		t.Fatalf("error dialing: %v", err)
@@ -3340,12 +3344,14 @@
 // Issue 9763.
 // HTTP/1-only test. (http2 doesn't have Hijack)
 func TestHijackAfterCloseNotifier(t *testing.T) {
-	defer afterTest(t)
+	run(t, testHijackAfterCloseNotifier, []testMode{http1Mode})
+}
+func testHijackAfterCloseNotifier(t *testing.T, mode testMode) {
 	script := make(chan string, 2)
 	script <- "closenotify"
 	script <- "hijack"
 	close(script)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		plan := <-script
 		switch plan {
 		default:
@@ -3368,13 +3374,12 @@
 			c.Close()
 			return
 		}
-	}))
-	defer ts.Close()
-	res1, err := Get(ts.URL)
+	})).ts
+	res1, err := ts.Client().Get(ts.URL)
 	if err != nil {
 		log.Fatal(err)
 	}
-	res2, err := Get(ts.URL)
+	res2, err := ts.Client().Get(ts.URL)
 	if err != nil {
 		log.Fatal(err)
 	}
@@ -3386,12 +3391,13 @@
 }
 
 func TestHijackBeforeRequestBodyRead(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
+	run(t, testHijackBeforeRequestBodyRead, []testMode{http1Mode})
+}
+func testHijackBeforeRequestBodyRead(t *testing.T, mode testMode) {
 	var requestBody = bytes.Repeat([]byte("a"), 1<<20)
 	bodyOkay := make(chan bool, 1)
 	gotCloseNotify := make(chan bool, 1)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		defer close(bodyOkay) // caller will read false if nothing else
 
 		reqBody := r.Body
@@ -3418,8 +3424,7 @@
 		case <-time.After(5 * time.Second):
 			gotCloseNotify <- false
 		}
-	}))
-	defer ts.Close()
+	})).ts
 
 	conn, err := net.Dial("tcp", ts.Listener.Addr().String())
 	if err != nil {
@@ -3439,14 +3444,14 @@
 	}
 }
 
-func TestOptions(t *testing.T) {
+func TestOptions(t *testing.T) { run(t, testOptions, []testMode{http1Mode}) }
+func testOptions(t *testing.T, mode testMode) {
 	uric := make(chan string, 2) // only expect 1, but leave space for 2
 	mux := NewServeMux()
 	mux.HandleFunc("/", func(w ResponseWriter, r *Request) {
 		uric <- r.RequestURI
 	})
-	ts := httptest.NewServer(mux)
-	defer ts.Close()
+	ts := newClientServerTest(t, mode, mux).ts
 
 	conn, err := net.Dial("tcp", ts.Listener.Addr().String())
 	if err != nil {
@@ -3491,6 +3496,37 @@
 	}
 }
 
+func TestOptionsHandler(t *testing.T) { run(t, testOptionsHandler, []testMode{http1Mode}) }
+func testOptionsHandler(t *testing.T, mode testMode) {
+	rc := make(chan *Request, 1)
+
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
+		rc <- r
+	}), func(ts *httptest.Server) {
+		ts.Config.DisableGeneralOptionsHandler = true
+	}).ts
+
+	conn, err := net.Dial("tcp", ts.Listener.Addr().String())
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer conn.Close()
+
+	_, err = conn.Write([]byte("OPTIONS * HTTP/1.1\r\nHost: foo.com\r\n\r\n"))
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	select {
+	case got := <-rc:
+		if got.Method != "OPTIONS" || got.RequestURI != "*" {
+			t.Errorf("Expected OPTIONS * request, got %v", got)
+		}
+	case <-time.After(5 * time.Second):
+		t.Error("timeout")
+	}
+}
+
 // Tests regarding the ordering of Write, WriteHeader, Header, and
 // Flush calls. In Go 1.0, rw.WriteHeader immediately flushed the
 // (*response).header to the wire. In Go 1.1, the actual wire flush is
@@ -3710,7 +3746,7 @@
 
 func TestWriteAfterHijack(t *testing.T) {
 	req := reqBytes("GET / HTTP/1.1\nHost: golang.org")
-	var buf bytes.Buffer
+	var buf strings.Builder
 	wrotec := make(chan bool, 1)
 	conn := &rwTestConn{
 		Reader: bytes.NewReader(req),
@@ -3772,12 +3808,12 @@
 // optimization and is pointless if dealing with a
 // badly behaved client.
 func TestHTTP10ConnectionHeader(t *testing.T) {
-	defer afterTest(t)
-
+	run(t, testHTTP10ConnectionHeader, []testMode{http1Mode})
+}
+func testHTTP10ConnectionHeader(t *testing.T, mode testMode) {
 	mux := NewServeMux()
 	mux.Handle("/", HandlerFunc(func(ResponseWriter, *Request) {}))
-	ts := httptest.NewServer(mux)
-	defer ts.Close()
+	ts := newClientServerTest(t, mode, mux).ts
 
 	// net/http uses HTTP/1.1 for requests, so write requests manually
 	tests := []struct {
@@ -3824,14 +3860,11 @@
 }
 
 // See golang.org/issue/5660
-func TestServerReaderFromOrder_h1(t *testing.T) { testServerReaderFromOrder(t, h1Mode) }
-func TestServerReaderFromOrder_h2(t *testing.T) { testServerReaderFromOrder(t, h2Mode) }
-func testServerReaderFromOrder(t *testing.T, h2 bool) {
-	setParallel(t)
-	defer afterTest(t)
+func TestServerReaderFromOrder(t *testing.T) { run(t, testServerReaderFromOrder) }
+func testServerReaderFromOrder(t *testing.T, mode testMode) {
 	pr, pw := io.Pipe()
 	const size = 3 << 20
-	cst := newClientServerTest(t, h2, HandlerFunc(func(rw ResponseWriter, req *Request) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(rw ResponseWriter, req *Request) {
 		rw.Header().Set("Content-Type", "text/plain") // prevent sniffing path
 		done := make(chan bool)
 		go func() {
@@ -3851,7 +3884,6 @@
 		pw.Close()
 		<-done
 	}))
-	defer cst.close()
 
 	req, err := NewRequest("POST", cst.ts.URL, io.LimitReader(neverEnding('a'), size))
 	if err != nil {
@@ -3925,16 +3957,10 @@
 // proxy).  So then two people own that Request.Body (both the server
 // and the http client), and both think they can close it on failure.
 // Therefore, all incoming server requests Bodies need to be thread-safe.
-func TestTransportAndServerSharedBodyRace_h1(t *testing.T) {
-	testTransportAndServerSharedBodyRace(t, h1Mode)
+func TestTransportAndServerSharedBodyRace(t *testing.T) {
+	run(t, testTransportAndServerSharedBodyRace)
 }
-func TestTransportAndServerSharedBodyRace_h2(t *testing.T) {
-	testTransportAndServerSharedBodyRace(t, h2Mode)
-}
-func testTransportAndServerSharedBodyRace(t *testing.T, h2 bool) {
-	setParallel(t)
-	defer afterTest(t)
-
+func testTransportAndServerSharedBodyRace(t *testing.T, mode testMode) {
 	const bodySize = 1 << 20
 
 	// errorf is like t.Errorf, but also writes to println. When
@@ -3948,7 +3974,7 @@
 	}
 
 	unblockBackend := make(chan bool)
-	backend := newClientServerTest(t, h2, HandlerFunc(func(rw ResponseWriter, req *Request) {
+	backend := newClientServerTest(t, mode, HandlerFunc(func(rw ResponseWriter, req *Request) {
 		gone := rw.(CloseNotifier).CloseNotify()
 		didCopy := make(chan any)
 		go func() {
@@ -3975,7 +4001,7 @@
 
 	backendRespc := make(chan *Response, 1)
 	var proxy *clientServerTest
-	proxy = newClientServerTest(t, h2, HandlerFunc(func(rw ResponseWriter, req *Request) {
+	proxy = newClientServerTest(t, mode, HandlerFunc(func(rw ResponseWriter, req *Request) {
 		req2, _ := NewRequest("POST", backend.ts.URL, req.Body)
 		req2.ContentLength = bodySize
 		cancel := make(chan struct{})
@@ -3995,7 +4021,7 @@
 
 		// Try to cause a race: Both the Transport and the proxy handler's Server
 		// will try to read/close req.Body (aka req2.Body)
-		if h2 {
+		if mode == http2Mode {
 			close(cancel)
 		} else {
 			proxy.c.Transport.(*Transport).CancelRequest(req2)
@@ -4039,22 +4065,23 @@
 // cause the Handler goroutine's Request.Body.Close to block.
 // See issue 7121.
 func TestRequestBodyCloseDoesntBlock(t *testing.T) {
+	run(t, testRequestBodyCloseDoesntBlock, []testMode{http1Mode})
+}
+func testRequestBodyCloseDoesntBlock(t *testing.T, mode testMode) {
 	if testing.Short() {
 		t.Skip("skipping in -short mode")
 	}
-	defer afterTest(t)
 
 	readErrCh := make(chan error, 1)
 	errCh := make(chan error, 2)
 
-	server := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
+	server := newClientServerTest(t, mode, HandlerFunc(func(rw ResponseWriter, req *Request) {
 		go func(body io.Reader) {
 			_, err := body.Read(make([]byte, 100))
 			readErrCh <- err
 		}(req.Body)
 		time.Sleep(500 * time.Millisecond)
-	}))
-	defer server.Close()
+	})).ts
 
 	closeConn := make(chan bool)
 	defer close(closeConn)
@@ -4117,9 +4144,8 @@
 	}
 }
 
-func TestServerConnState(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
+func TestServerConnState(t *testing.T) { run(t, testServerConnState, []testMode{http1Mode}) }
+func testServerConnState(t *testing.T, mode testMode) {
 	handler := map[string]func(w ResponseWriter, r *Request){
 		"/": func(w ResponseWriter, r *Request) {
 			fmt.Fprintf(w, "Hello.")
@@ -4185,37 +4211,36 @@
 		// next call to wantLog.
 	}
 
-	ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		handler[r.URL.Path](w, r)
-	}))
+	}), func(ts *httptest.Server) {
+		ts.Config.ErrorLog = log.New(io.Discard, "", 0)
+		ts.Config.ConnState = func(c net.Conn, state ConnState) {
+			if c == nil {
+				t.Errorf("nil conn seen in state %s", state)
+				return
+			}
+			sl := <-activeLog
+			if sl.active == nil && state == StateNew {
+				sl.active = c
+			} else if sl.active != c {
+				t.Errorf("unexpected conn in state %s", state)
+				activeLog <- sl
+				return
+			}
+			sl.got = append(sl.got, state)
+			if sl.complete != nil && (len(sl.got) >= len(sl.want) || !reflect.DeepEqual(sl.got, sl.want[:len(sl.got)])) {
+				close(sl.complete)
+				sl.complete = nil
+			}
+			activeLog <- sl
+		}
+	}).ts
 	defer func() {
 		activeLog <- &stateLog{} // If the test failed, allow any remaining ConnState callbacks to complete.
 		ts.Close()
 	}()
 
-	ts.Config.ErrorLog = log.New(io.Discard, "", 0)
-	ts.Config.ConnState = func(c net.Conn, state ConnState) {
-		if c == nil {
-			t.Errorf("nil conn seen in state %s", state)
-			return
-		}
-		sl := <-activeLog
-		if sl.active == nil && state == StateNew {
-			sl.active = c
-		} else if sl.active != c {
-			t.Errorf("unexpected conn in state %s", state)
-			activeLog <- sl
-			return
-		}
-		sl.got = append(sl.got, state)
-		if sl.complete != nil && (len(sl.got) >= len(sl.want) || !reflect.DeepEqual(sl.got, sl.want[:len(sl.got)])) {
-			close(sl.complete)
-			sl.complete = nil
-		}
-		activeLog <- sl
-	}
-
-	ts.Start()
 	c := ts.Client()
 
 	mustGet := func(url string, headers ...string) {
@@ -4297,13 +4322,15 @@
 	}, StateNew, StateActive, StateIdle, StateClosed)
 }
 
-func TestServerKeepAlivesEnabled(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
-	ts.Config.SetKeepAlivesEnabled(false)
-	ts.Start()
-	defer ts.Close()
-	res, err := Get(ts.URL)
+func TestServerKeepAlivesEnabledResultClose(t *testing.T) {
+	run(t, testServerKeepAlivesEnabledResultClose, []testMode{http1Mode})
+}
+func testServerKeepAlivesEnabledResultClose(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
+	}), func(ts *httptest.Server) {
+		ts.Config.SetKeepAlivesEnabled(false)
+	}).ts
+	res, err := ts.Client().Get(ts.URL)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -4314,16 +4341,12 @@
 }
 
 // golang.org/issue/7856
-func TestServerEmptyBodyRace_h1(t *testing.T) { testServerEmptyBodyRace(t, h1Mode) }
-func TestServerEmptyBodyRace_h2(t *testing.T) { testServerEmptyBodyRace(t, h2Mode) }
-func testServerEmptyBodyRace(t *testing.T, h2 bool) {
-	setParallel(t)
-	defer afterTest(t)
+func TestServerEmptyBodyRace(t *testing.T) { run(t, testServerEmptyBodyRace) }
+func testServerEmptyBodyRace(t *testing.T, mode testMode) {
 	var n int32
-	cst := newClientServerTest(t, h2, HandlerFunc(func(rw ResponseWriter, req *Request) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(rw ResponseWriter, req *Request) {
 		atomic.AddInt32(&n, 1)
 	}), optQuietLog)
-	defer cst.close()
 	var wg sync.WaitGroup
 	const reqs = 20
 	for i := 0; i < reqs; i++ {
@@ -4404,9 +4427,9 @@
 // fixed.
 //
 // So add an explicit test for this.
-func TestServerFlushAndHijack(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestServerFlushAndHijack(t *testing.T) { run(t, testServerFlushAndHijack, []testMode{http1Mode}) }
+func testServerFlushAndHijack(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		io.WriteString(w, "Hello, ")
 		w.(Flusher).Flush()
 		conn, buf, _ := w.(Hijacker).Hijack()
@@ -4417,8 +4440,7 @@
 		if err := conn.Close(); err != nil {
 			t.Error(err)
 		}
-	}))
-	defer ts.Close()
+	})).ts
 	res, err := Get(ts.URL)
 	if err != nil {
 		t.Fatal(err)
@@ -4440,20 +4462,21 @@
 // To test, verify we don't timeout or see fewer unique client
 // addresses (== unique connections) than requests.
 func TestServerKeepAliveAfterWriteError(t *testing.T) {
+	run(t, testServerKeepAliveAfterWriteError, []testMode{http1Mode})
+}
+func testServerKeepAliveAfterWriteError(t *testing.T, mode testMode) {
 	if testing.Short() {
 		t.Skip("skipping in -short mode")
 	}
-	defer afterTest(t)
 	const numReq = 3
 	addrc := make(chan string, numReq)
-	ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		addrc <- r.RemoteAddr
 		time.Sleep(500 * time.Millisecond)
 		w.(Flusher).Flush()
-	}))
-	ts.Config.WriteTimeout = 250 * time.Millisecond
-	ts.Start()
-	defer ts.Close()
+	}), func(ts *httptest.Server) {
+		ts.Config.WriteTimeout = 250 * time.Millisecond
+	}).ts
 
 	errc := make(chan error, numReq)
 	go func() {
@@ -4497,12 +4520,13 @@
 // Issue 9987: shouldn't add automatic Content-Length (or
 // Content-Type) if a Transfer-Encoding was set by the handler.
 func TestNoContentLengthIfTransferEncoding(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	run(t, testNoContentLengthIfTransferEncoding, []testMode{http1Mode})
+}
+func testNoContentLengthIfTransferEncoding(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		w.Header().Set("Transfer-Encoding", "foo")
 		io.WriteString(w, "<html>")
-	}))
-	defer ts.Close()
+	})).ts
 	c, err := net.Dial("tcp", ts.Listener.Addr().String())
 	if err != nil {
 		t.Fatalf("Dial: %v", err)
@@ -4512,7 +4536,7 @@
 		t.Fatal(err)
 	}
 	bs := bufio.NewScanner(c)
-	var got bytes.Buffer
+	var got strings.Builder
 	for bs.Scan() {
 		if strings.TrimSpace(bs.Text()) == "" {
 			break
@@ -4601,7 +4625,7 @@
 Host: foo
 
 `)
-	var buf bytes.Buffer
+	var buf strings.Builder
 	conn := &rwTestConn{
 		Reader: bytes.NewReader(req),
 		Writer: &buf,
@@ -4650,15 +4674,12 @@
 	}
 }
 
-func TestHandlerSetsBodyNil_h1(t *testing.T) { testHandlerSetsBodyNil(t, h1Mode) }
-func TestHandlerSetsBodyNil_h2(t *testing.T) { testHandlerSetsBodyNil(t, h2Mode) }
-func testHandlerSetsBodyNil(t *testing.T, h2 bool) {
-	defer afterTest(t)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestHandlerSetsBodyNil(t *testing.T) { run(t, testHandlerSetsBodyNil) }
+func testHandlerSetsBodyNil(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		r.Body = nil
 		fmt.Fprintf(w, "%v", r.RemoteAddr)
 	}))
-	defer cst.close()
 	get := func() string {
 		res, err := cst.c.Get(cst.ts.URL)
 		if err != nil {
@@ -4748,9 +4769,11 @@
 }
 
 func TestServerHandlersCanHandleH2PRI(t *testing.T) {
+	run(t, testServerHandlersCanHandleH2PRI, []testMode{http1Mode})
+}
+func testServerHandlersCanHandleH2PRI(t *testing.T, mode testMode) {
 	const upgradeResponse = "upgrade here"
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		conn, br, err := w.(Hijacker).Hijack()
 		if err != nil {
 			t.Error(err)
@@ -4772,8 +4795,7 @@
 			return
 		}
 		io.WriteString(conn, upgradeResponse)
-	}))
-	defer ts.Close()
+	})).ts
 
 	c, err := net.Dial("tcp", ts.Listener.Addr().String())
 	if err != nil {
@@ -4840,17 +4862,12 @@
 	}
 }
 
-func TestServerRequestContextCancel_ServeHTTPDone_h1(t *testing.T) {
-	testServerRequestContextCancel_ServeHTTPDone(t, h1Mode)
+func TestServerRequestContextCancel_ServeHTTPDone(t *testing.T) {
+	run(t, testServerRequestContextCancel_ServeHTTPDone)
 }
-func TestServerRequestContextCancel_ServeHTTPDone_h2(t *testing.T) {
-	testServerRequestContextCancel_ServeHTTPDone(t, h2Mode)
-}
-func testServerRequestContextCancel_ServeHTTPDone(t *testing.T, h2 bool) {
-	setParallel(t)
-	defer afterTest(t)
+func testServerRequestContextCancel_ServeHTTPDone(t *testing.T, mode testMode) {
 	ctxc := make(chan context.Context, 1)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		ctx := r.Context()
 		select {
 		case <-ctx.Done():
@@ -4859,7 +4876,6 @@
 		}
 		ctxc <- ctx
 	}))
-	defer cst.close()
 	res, err := cst.c.Get(cst.ts.URL)
 	if err != nil {
 		t.Fatal(err)
@@ -4878,16 +4894,16 @@
 // is always blocked in a Read call so it notices the EOF from the client.
 // See issues 15927 and 15224.
 func TestServerRequestContextCancel_ConnClose(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
+	run(t, testServerRequestContextCancel_ConnClose, []testMode{http1Mode})
+}
+func testServerRequestContextCancel_ConnClose(t *testing.T, mode testMode) {
 	inHandler := make(chan struct{})
 	handlerDone := make(chan struct{})
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		close(inHandler)
 		<-r.Context().Done()
 		close(handlerDone)
-	}))
-	defer ts.Close()
+	})).ts
 	c, err := net.Dial("tcp", ts.Listener.Addr().String())
 	if err != nil {
 		t.Fatal(err)
@@ -4899,23 +4915,17 @@
 	<-handlerDone
 }
 
-func TestServerContext_ServerContextKey_h1(t *testing.T) {
-	testServerContext_ServerContextKey(t, h1Mode)
+func TestServerContext_ServerContextKey(t *testing.T) {
+	run(t, testServerContext_ServerContextKey)
 }
-func TestServerContext_ServerContextKey_h2(t *testing.T) {
-	testServerContext_ServerContextKey(t, h2Mode)
-}
-func testServerContext_ServerContextKey(t *testing.T, h2 bool) {
-	setParallel(t)
-	defer afterTest(t)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+func testServerContext_ServerContextKey(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		ctx := r.Context()
 		got := ctx.Value(ServerContextKey)
 		if _, ok := got.(*Server); !ok {
 			t.Errorf("context value = %T; want *http.Server", got)
 		}
 	}))
-	defer cst.close()
 	res, err := cst.c.Get(cst.ts.URL)
 	if err != nil {
 		t.Fatal(err)
@@ -4923,20 +4933,14 @@
 	res.Body.Close()
 }
 
-func TestServerContext_LocalAddrContextKey_h1(t *testing.T) {
-	testServerContext_LocalAddrContextKey(t, h1Mode)
+func TestServerContext_LocalAddrContextKey(t *testing.T) {
+	run(t, testServerContext_LocalAddrContextKey)
 }
-func TestServerContext_LocalAddrContextKey_h2(t *testing.T) {
-	testServerContext_LocalAddrContextKey(t, h2Mode)
-}
-func testServerContext_LocalAddrContextKey(t *testing.T, h2 bool) {
-	setParallel(t)
-	defer afterTest(t)
+func testServerContext_LocalAddrContextKey(t *testing.T, mode testMode) {
 	ch := make(chan any, 1)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		ch <- r.Context().Value(LocalAddrContextKey)
 	}))
-	defer cst.close()
 	if _, err := cst.c.Head(cst.ts.URL); err != nil {
 		t.Fatal(err)
 	}
@@ -4989,16 +4993,19 @@
 }
 
 func BenchmarkClientServer(b *testing.B) {
+	run(b, benchmarkClientServer, []testMode{http1Mode, https1Mode, http2Mode})
+}
+func benchmarkClientServer(b *testing.B, mode testMode) {
 	b.ReportAllocs()
 	b.StopTimer()
-	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, r *Request) {
+	ts := newClientServerTest(b, mode, HandlerFunc(func(rw ResponseWriter, r *Request) {
 		fmt.Fprintf(rw, "Hello world.\n")
-	}))
-	defer ts.Close()
+	})).ts
 	b.StartTimer()
 
+	c := ts.Client()
 	for i := 0; i < b.N; i++ {
-		res, err := Get(ts.URL)
+		res, err := c.Get(ts.URL)
 		if err != nil {
 			b.Fatal("Get:", err)
 		}
@@ -5016,33 +5023,21 @@
 	b.StopTimer()
 }
 
-func BenchmarkClientServerParallel4(b *testing.B) {
-	benchmarkClientServerParallel(b, 4, false)
-}
-
-func BenchmarkClientServerParallel64(b *testing.B) {
-	benchmarkClientServerParallel(b, 64, false)
-}
-
-func BenchmarkClientServerParallelTLS4(b *testing.B) {
-	benchmarkClientServerParallel(b, 4, true)
-}
-
-func BenchmarkClientServerParallelTLS64(b *testing.B) {
-	benchmarkClientServerParallel(b, 64, true)
-}
-
-func benchmarkClientServerParallel(b *testing.B, parallelism int, useTLS bool) {
-	b.ReportAllocs()
-	ts := httptest.NewUnstartedServer(HandlerFunc(func(rw ResponseWriter, r *Request) {
-		fmt.Fprintf(rw, "Hello world.\n")
-	}))
-	if useTLS {
-		ts.StartTLS()
-	} else {
-		ts.Start()
+func BenchmarkClientServerParallel(b *testing.B) {
+	for _, parallelism := range []int{4, 64} {
+		b.Run(fmt.Sprint(parallelism), func(b *testing.B) {
+			run(b, func(b *testing.B, mode testMode) {
+				benchmarkClientServerParallel(b, parallelism, mode)
+			}, []testMode{http1Mode, https1Mode, http2Mode})
+		})
 	}
-	defer ts.Close()
+}
+
+func benchmarkClientServerParallel(b *testing.B, parallelism int, mode testMode) {
+	b.ReportAllocs()
+	ts := newClientServerTest(b, mode, HandlerFunc(func(rw ResponseWriter, r *Request) {
+		fmt.Fprintf(rw, "Hello world.\n")
+	})).ts
 	b.ResetTimer()
 	b.SetParallelism(parallelism)
 	b.RunParallel(func(pb *testing.PB) {
@@ -5432,15 +5427,15 @@
 	}
 }
 
-func BenchmarkCloseNotifier(b *testing.B) {
+func BenchmarkCloseNotifier(b *testing.B) { run(b, benchmarkCloseNotifier, []testMode{http1Mode}) }
+func benchmarkCloseNotifier(b *testing.B, mode testMode) {
 	b.ReportAllocs()
 	b.StopTimer()
 	sawClose := make(chan bool)
-	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
+	ts := newClientServerTest(b, mode, HandlerFunc(func(rw ResponseWriter, req *Request) {
 		<-rw.(CloseNotifier).CloseNotify()
 		sawClose <- true
-	}))
-	defer ts.Close()
+	})).ts
 	tot := time.NewTimer(5 * time.Second)
 	defer tot.Stop()
 	b.StartTimer()
@@ -5476,20 +5471,18 @@
 	}
 }
 
-func TestServerIdleTimeout(t *testing.T) {
+func TestServerIdleTimeout(t *testing.T) { run(t, testServerIdleTimeout, []testMode{http1Mode}) }
+func testServerIdleTimeout(t *testing.T, mode testMode) {
 	if testing.Short() {
 		t.Skip("skipping in short mode")
 	}
-	setParallel(t)
-	defer afterTest(t)
-	ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		io.Copy(io.Discard, r.Body)
 		io.WriteString(w, r.RemoteAddr)
-	}))
-	ts.Config.ReadHeaderTimeout = 1 * time.Second
-	ts.Config.IdleTimeout = 2 * time.Second
-	ts.Start()
-	defer ts.Close()
+	}), func(ts *httptest.Server) {
+		ts.Config.ReadHeaderTimeout = 1 * time.Second
+		ts.Config.IdleTimeout = 2 * time.Second
+	}).ts
 	c := ts.Client()
 
 	get := func() string {
@@ -5544,12 +5537,12 @@
 // Tests that calls to Server.SetKeepAlivesEnabled(false) closes any
 // currently-open connections.
 func TestServerSetKeepAlivesEnabledClosesConns(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	run(t, testServerSetKeepAlivesEnabledClosesConns, []testMode{http1Mode})
+}
+func testServerSetKeepAlivesEnabledClosesConns(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		io.WriteString(w, r.RemoteAddr)
-	}))
-	defer ts.Close()
+	})).ts
 
 	c := ts.Client()
 	tr := c.Transport.(*Transport)
@@ -5588,16 +5581,8 @@
 	}
 }
 
-func TestServerShutdown_h1(t *testing.T) {
-	testServerShutdown(t, h1Mode)
-}
-func TestServerShutdown_h2(t *testing.T) {
-	testServerShutdown(t, h2Mode)
-}
-
-func testServerShutdown(t *testing.T, h2 bool) {
-	setParallel(t)
-	defer afterTest(t)
+func TestServerShutdown(t *testing.T) { run(t, testServerShutdown) }
+func testServerShutdown(t *testing.T, mode testMode) {
 	var doShutdown func() // set later
 	var doStateCount func()
 	var shutdownRes = make(chan error, 1)
@@ -5613,10 +5598,9 @@
 		time.Sleep(20 * time.Millisecond)
 		io.WriteString(w, r.RemoteAddr)
 	})
-	cst := newClientServerTest(t, h2, handler, func(srv *httptest.Server) {
+	cst := newClientServerTest(t, mode, handler, func(srv *httptest.Server) {
 		srv.Config.RegisterOnShutdown(func() { gotOnShutdown <- struct{}{} })
 	})
-	defer cst.close()
 
 	doShutdown = func() {
 		shutdownRes <- cst.ts.Config.Shutdown(context.Background())
@@ -5646,24 +5630,22 @@
 	}
 }
 
-func TestServerShutdownStateNew(t *testing.T) {
+func TestServerShutdownStateNew(t *testing.T) { run(t, testServerShutdownStateNew) }
+func testServerShutdownStateNew(t *testing.T, mode testMode) {
 	if testing.Short() {
 		t.Skip("test takes 5-6 seconds; skipping in short mode")
 	}
-	setParallel(t)
-	defer afterTest(t)
 
-	ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		// nothing.
-	}))
 	var connAccepted sync.WaitGroup
-	ts.Config.ConnState = func(conn net.Conn, state ConnState) {
-		if state == StateNew {
-			connAccepted.Done()
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
+		// nothing.
+	}), func(ts *httptest.Server) {
+		ts.Config.ConnState = func(conn net.Conn, state ConnState) {
+			if state == StateNew {
+				connAccepted.Done()
+			}
 		}
-	}
-	ts.Start()
-	defer ts.Close()
+	}).ts
 
 	// Start a connection but never write to it.
 	connAccepted.Add(1)
@@ -5725,16 +5707,14 @@
 
 // Issue 17717: tests that Server.SetKeepAlivesEnabled is respected by
 // both HTTP/1 and HTTP/2.
-func TestServerKeepAlivesEnabled_h1(t *testing.T) { testServerKeepAlivesEnabled(t, h1Mode) }
-func TestServerKeepAlivesEnabled_h2(t *testing.T) { testServerKeepAlivesEnabled(t, h2Mode) }
-func testServerKeepAlivesEnabled(t *testing.T, h2 bool) {
-	if h2 {
+func TestServerKeepAlivesEnabled(t *testing.T) { run(t, testServerKeepAlivesEnabled, testNotParallel) }
+func testServerKeepAlivesEnabled(t *testing.T, mode testMode) {
+	if mode == http2Mode {
 		restore := ExportSetH2GoawayTimeout(10 * time.Millisecond)
 		defer restore()
 	}
 	// Not parallel: messes with global variable. (http2goAwayTimeout)
-	defer afterTest(t)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {}))
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {}))
 	defer cst.close()
 	srv := cst.ts.Config
 	srv.SetKeepAlivesEnabled(false)
@@ -5771,9 +5751,8 @@
 // Issue 18447: test that the Server's ReadTimeout is stopped while
 // the server's doing its 1-byte background read between requests,
 // waiting for the connection to maybe close.
-func TestServerCancelsReadTimeoutWhenIdle(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
+func TestServerCancelsReadTimeoutWhenIdle(t *testing.T) { run(t, testServerCancelsReadTimeoutWhenIdle) }
+func testServerCancelsReadTimeoutWhenIdle(t *testing.T, mode testMode) {
 	runTimeSensitiveTest(t, []time.Duration{
 		10 * time.Millisecond,
 		50 * time.Millisecond,
@@ -5781,17 +5760,16 @@
 		time.Second,
 		2 * time.Second,
 	}, func(t *testing.T, timeout time.Duration) error {
-		ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 			select {
 			case <-time.After(2 * timeout):
 				fmt.Fprint(w, "ok")
 			case <-r.Context().Done():
 				fmt.Fprint(w, r.Context().Err())
 			}
-		}))
-		ts.Config.ReadTimeout = timeout
-		ts.Start()
-		defer ts.Close()
+		}), func(ts *httptest.Server) {
+			ts.Config.ReadTimeout = timeout
+		}).ts
 
 		c := ts.Client()
 
@@ -5811,6 +5789,58 @@
 	})
 }
 
+// Issue 54784: test that the Server's ReadHeaderTimeout only starts once the
+// beginning of a request has been received, rather than including time the
+// connection spent idle.
+func TestServerCancelsReadHeaderTimeoutWhenIdle(t *testing.T) {
+	run(t, testServerCancelsReadHeaderTimeoutWhenIdle, []testMode{http1Mode})
+}
+func testServerCancelsReadHeaderTimeoutWhenIdle(t *testing.T, mode testMode) {
+	runTimeSensitiveTest(t, []time.Duration{
+		10 * time.Millisecond,
+		50 * time.Millisecond,
+		250 * time.Millisecond,
+		time.Second,
+		2 * time.Second,
+	}, func(t *testing.T, timeout time.Duration) error {
+		ts := newClientServerTest(t, mode, serve(200), func(ts *httptest.Server) {
+			ts.Config.ReadHeaderTimeout = timeout
+			ts.Config.IdleTimeout = 0 // disable idle timeout
+		}).ts
+
+		// rather than using an http.Client, create a single connection, so that
+		// we can ensure this connection is not closed.
+		conn, err := net.Dial("tcp", ts.Listener.Addr().String())
+		if err != nil {
+			t.Fatalf("dial failed: %v", err)
+		}
+		br := bufio.NewReader(conn)
+		defer conn.Close()
+
+		if _, err := conn.Write([]byte("GET / HTTP/1.1\r\nHost: e.com\r\n\r\n")); err != nil {
+			return fmt.Errorf("writing first request failed: %v", err)
+		}
+
+		if _, err := ReadResponse(br, nil); err != nil {
+			return fmt.Errorf("first response (before timeout) failed: %v", err)
+		}
+
+		// wait for longer than the server's ReadHeaderTimeout, and then send
+		// another request
+		time.Sleep(timeout * 3 / 2)
+
+		if _, err := conn.Write([]byte("GET / HTTP/1.1\r\nHost: e.com\r\n\r\n")); err != nil {
+			return fmt.Errorf("writing second request failed: %v", err)
+		}
+
+		if _, err := ReadResponse(br, nil); err != nil {
+			return fmt.Errorf("second response (after timeout) failed: %v", err)
+		}
+
+		return nil
+	})
+}
+
 // runTimeSensitiveTest runs test with the provided durations until one passes.
 // If they all fail, t.Fatal is called with the last one's duration and error value.
 func runTimeSensitiveTest(t *testing.T, durations []time.Duration, test func(t *testing.T, d time.Duration) error) {
@@ -5828,13 +5858,13 @@
 // Issue 18535: test that the Server doesn't try to do a background
 // read if it's already done one.
 func TestServerDuplicateBackgroundRead(t *testing.T) {
+	run(t, testServerDuplicateBackgroundRead, []testMode{http1Mode})
+}
+func testServerDuplicateBackgroundRead(t *testing.T, mode testMode) {
 	if runtime.GOOS == "netbsd" && runtime.GOARCH == "arm" {
 		testenv.SkipFlaky(t, 24826)
 	}
 
-	setParallel(t)
-	defer afterTest(t)
-
 	goroutines := 5
 	requests := 2000
 	if testing.Short() {
@@ -5842,8 +5872,7 @@
 		requests = 100
 	}
 
-	hts := httptest.NewServer(HandlerFunc(NotFound))
-	defer hts.Close()
+	hts := newClientServerTest(t, mode, HandlerFunc(NotFound)).ts
 
 	reqBytes := []byte("GET / HTTP/1.1\r\nHost: e.com\r\n\r\n")
 
@@ -5886,14 +5915,15 @@
 // bufio.Reader.Buffered(), without resorting to Reading it
 // (potentially blocking) to get at it.
 func TestServerHijackGetsBackgroundByte(t *testing.T) {
+	run(t, testServerHijackGetsBackgroundByte, []testMode{http1Mode})
+}
+func testServerHijackGetsBackgroundByte(t *testing.T, mode testMode) {
 	if runtime.GOOS == "plan9" {
 		t.Skip("skipping test; see https://golang.org/issue/18657")
 	}
-	setParallel(t)
-	defer afterTest(t)
 	done := make(chan struct{})
 	inHandler := make(chan bool, 1)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		defer close(done)
 
 		// Tell the client to send more data after the GET request.
@@ -5916,8 +5946,7 @@
 			t.Error("context unexpectedly canceled")
 		default:
 		}
-	}))
-	defer ts.Close()
+	})).ts
 
 	cn, err := net.Dial("tcp", ts.Listener.Addr().String())
 	if err != nil {
@@ -5946,14 +5975,15 @@
 // immediate 1MB of data to the server to fill up the server's 4KB
 // buffer.
 func TestServerHijackGetsBackgroundByte_big(t *testing.T) {
+	run(t, testServerHijackGetsBackgroundByte_big, []testMode{http1Mode})
+}
+func testServerHijackGetsBackgroundByte_big(t *testing.T, mode testMode) {
 	if runtime.GOOS == "plan9" {
 		t.Skip("skipping test; see https://golang.org/issue/18657")
 	}
-	setParallel(t)
-	defer afterTest(t)
 	done := make(chan struct{})
 	const size = 8 << 10
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		defer close(done)
 
 		conn, buf, err := w.(Hijacker).Hijack()
@@ -5977,8 +6007,7 @@
 		} else if !allX {
 			t.Errorf("read %q; want %d 'x'", slurp, size)
 		}
-	}))
-	defer ts.Close()
+	})).ts
 
 	cn, err := net.Dial("tcp", ts.Listener.Addr().String())
 	if err != nil {
@@ -6114,73 +6143,27 @@
 	}
 }
 
-func TestServerContexts(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
+func TestServerContexts(t *testing.T) { run(t, testServerContexts) }
+func testServerContexts(t *testing.T, mode testMode) {
 	type baseKey struct{}
 	type connKey struct{}
 	ch := make(chan context.Context, 1)
-	ts := httptest.NewUnstartedServer(HandlerFunc(func(rw ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(rw ResponseWriter, r *Request) {
 		ch <- r.Context()
-	}))
-	ts.Config.BaseContext = func(ln net.Listener) context.Context {
-		if strings.Contains(reflect.TypeOf(ln).String(), "onceClose") {
-			t.Errorf("unexpected onceClose listener type %T", ln)
+	}), func(ts *httptest.Server) {
+		ts.Config.BaseContext = func(ln net.Listener) context.Context {
+			if strings.Contains(reflect.TypeOf(ln).String(), "onceClose") {
+				t.Errorf("unexpected onceClose listener type %T", ln)
+			}
+			return context.WithValue(context.Background(), baseKey{}, "base")
 		}
-		return context.WithValue(context.Background(), baseKey{}, "base")
-	}
-	ts.Config.ConnContext = func(ctx context.Context, c net.Conn) context.Context {
-		if got, want := ctx.Value(baseKey{}), "base"; got != want {
-			t.Errorf("in ConnContext, base context key = %#v; want %q", got, want)
+		ts.Config.ConnContext = func(ctx context.Context, c net.Conn) context.Context {
+			if got, want := ctx.Value(baseKey{}), "base"; got != want {
+				t.Errorf("in ConnContext, base context key = %#v; want %q", got, want)
+			}
+			return context.WithValue(ctx, connKey{}, "conn")
 		}
-		return context.WithValue(ctx, connKey{}, "conn")
-	}
-	ts.Start()
-	defer ts.Close()
-	res, err := ts.Client().Get(ts.URL)
-	if err != nil {
-		t.Fatal(err)
-	}
-	res.Body.Close()
-	ctx := <-ch
-	if got, want := ctx.Value(baseKey{}), "base"; got != want {
-		t.Errorf("base context key = %#v; want %q", got, want)
-	}
-	if got, want := ctx.Value(connKey{}), "conn"; got != want {
-		t.Errorf("conn context key = %#v; want %q", got, want)
-	}
-}
-
-func TestServerContextsHTTP2(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
-	type baseKey struct{}
-	type connKey struct{}
-	ch := make(chan context.Context, 1)
-	ts := httptest.NewUnstartedServer(HandlerFunc(func(rw ResponseWriter, r *Request) {
-		if r.ProtoMajor != 2 {
-			t.Errorf("unexpected HTTP/1.x request")
-		}
-		ch <- r.Context()
-	}))
-	ts.Config.BaseContext = func(ln net.Listener) context.Context {
-		if strings.Contains(reflect.TypeOf(ln).String(), "onceClose") {
-			t.Errorf("unexpected onceClose listener type %T", ln)
-		}
-		return context.WithValue(context.Background(), baseKey{}, "base")
-	}
-	ts.Config.ConnContext = func(ctx context.Context, c net.Conn) context.Context {
-		if got, want := ctx.Value(baseKey{}), "base"; got != want {
-			t.Errorf("in ConnContext, base context key = %#v; want %q", got, want)
-		}
-		return context.WithValue(ctx, connKey{}, "conn")
-	}
-	ts.TLS = &tls.Config{
-		NextProtos: []string{"h2", "http/1.1"},
-	}
-	ts.StartTLS()
-	defer ts.Close()
-	ts.Client().Transport.(*Transport).ForceAttemptHTTP2 = true
+	}).ts
 	res, err := ts.Client().Get(ts.URL)
 	if err != nil {
 		t.Fatal(err)
@@ -6197,20 +6180,20 @@
 
 // Issue 35750: check ConnContext not modifying context for other connections
 func TestConnContextNotModifyingAllContexts(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
+	run(t, testConnContextNotModifyingAllContexts)
+}
+func testConnContextNotModifyingAllContexts(t *testing.T, mode testMode) {
 	type connKey struct{}
-	ts := httptest.NewUnstartedServer(HandlerFunc(func(rw ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(rw ResponseWriter, r *Request) {
 		rw.Header().Set("Connection", "close")
-	}))
-	ts.Config.ConnContext = func(ctx context.Context, c net.Conn) context.Context {
-		if got := ctx.Value(connKey{}); got != nil {
-			t.Errorf("in ConnContext, unexpected context key = %#v", got)
+	}), func(ts *httptest.Server) {
+		ts.Config.ConnContext = func(ctx context.Context, c net.Conn) context.Context {
+			if got := ctx.Value(connKey{}); got != nil {
+				t.Errorf("in ConnContext, unexpected context key = %#v", got)
+			}
+			return context.WithValue(ctx, connKey{}, "conn")
 		}
-		return context.WithValue(ctx, connKey{}, "conn")
-	}
-	ts.Start()
-	defer ts.Close()
+	}).ts
 
 	var res *Response
 	var err error
@@ -6231,10 +6214,12 @@
 // Issue 30710: ensure that as per the spec, a server responds
 // with 501 Not Implemented for unsupported transfer-encodings.
 func TestUnsupportedTransferEncodingsReturn501(t *testing.T) {
-	cst := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	run(t, testUnsupportedTransferEncodingsReturn501, []testMode{http1Mode})
+}
+func testUnsupportedTransferEncodingsReturn501(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		w.Write([]byte("Hello, World!"))
-	}))
-	defer cst.Close()
+	})).ts
 
 	serverURL, err := url.Parse(cst.URL)
 	if err != nil {
@@ -6245,7 +6230,7 @@
 		"fugazi",
 		"foo-bar",
 		"unknown",
-		"\rchunked",
+		`" chunked"`,
 	}
 
 	for _, badTE := range unsupportedTEs {
@@ -6269,19 +6254,9 @@
 	}
 }
 
-func TestContentEncodingNoSniffing_h1(t *testing.T) {
-	testContentEncodingNoSniffing(t, h1Mode)
-}
-
-func TestContentEncodingNoSniffing_h2(t *testing.T) {
-	testContentEncodingNoSniffing(t, h2Mode)
-}
-
 // Issue 31753: don't sniff when Content-Encoding is set
-func testContentEncodingNoSniffing(t *testing.T, h2 bool) {
-	setParallel(t)
-	defer afterTest(t)
-
+func TestContentEncodingNoSniffing(t *testing.T) { run(t, testContentEncodingNoSniffing) }
+func testContentEncodingNoSniffing(t *testing.T, mode testMode) {
 	type setting struct {
 		name string
 		body []byte
@@ -6344,13 +6319,12 @@
 
 	for _, tt := range settings {
 		t.Run(tt.name, func(t *testing.T) {
-			cst := newClientServerTest(t, h2, HandlerFunc(func(rw ResponseWriter, r *Request) {
+			cst := newClientServerTest(t, mode, HandlerFunc(func(rw ResponseWriter, r *Request) {
 				if tt.contentEncoding != nil {
 					rw.Header().Set("Content-Encoding", tt.contentEncoding.(string))
 				}
 				rw.Write(tt.body)
 			}))
-			defer cst.close()
 
 			res, err := cst.c.Get(cst.ts.URL)
 			if err != nil {
@@ -6376,13 +6350,13 @@
 // Issue 30803: ensure that TimeoutHandler logs spurious
 // WriteHeader calls, for consistency with other Handlers.
 func TestTimeoutHandlerSuperfluousLogs(t *testing.T) {
+	run(t, testTimeoutHandlerSuperfluousLogs, []testMode{http1Mode})
+}
+func testTimeoutHandlerSuperfluousLogs(t *testing.T, mode testMode) {
 	if testing.Short() {
 		t.Skip("skipping in short mode")
 	}
 
-	setParallel(t)
-	defer afterTest(t)
-
 	pc, curFile, _, _ := runtime.Caller(0)
 	curFileBaseName := filepath.Base(curFile)
 	testFuncName := runtime.FuncForPC(pc).Name()
@@ -6427,7 +6401,7 @@
 				exitHandler <- true
 			}
 
-			logBuf := new(bytes.Buffer)
+			logBuf := new(strings.Builder)
 			srvLog := log.New(logBuf, "", 0)
 			// When expecting to timeout, we'll keep the duration short.
 			dur := 20 * time.Millisecond
@@ -6436,7 +6410,7 @@
 				dur = 10 * time.Second
 			}
 			th := TimeoutHandler(sh, dur, timeoutMsg)
-			cst := newClientServerTest(t, h1Mode /* the test is protocol-agnostic */, th, optWithServerLog(srvLog))
+			cst := newClientServerTest(t, mode, th, optWithServerLog(srvLog))
 			defer cst.close()
 
 			res, err := cst.c.Get(cst.ts.URL)
@@ -6506,15 +6480,16 @@
 		}
 	})
 }
+
 func TestDisableKeepAliveUpgrade(t *testing.T) {
+	run(t, testDisableKeepAliveUpgrade, []testMode{http1Mode})
+}
+func testDisableKeepAliveUpgrade(t *testing.T, mode testMode) {
 	if testing.Short() {
 		t.Skip("skipping in short mode")
 	}
 
-	setParallel(t)
-	defer afterTest(t)
-
-	s := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	s := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		w.Header().Set("Connection", "Upgrade")
 		w.Header().Set("Upgrade", "someProto")
 		w.WriteHeader(StatusSwitchingProtocols)
@@ -6527,10 +6502,9 @@
 		// Copy from the *bufio.ReadWriter, which may contain buffered data.
 		// Copy to the net.Conn, to avoid buffering the output.
 		io.Copy(c, buf)
-	}))
-	s.Config.SetKeepAlivesEnabled(false)
-	s.Start()
-	defer s.Close()
+	}), func(ts *httptest.Server) {
+		ts.Config.SetKeepAlivesEnabled(false)
+	}).ts
 
 	cl := s.Client()
 	cl.Transport.(*Transport).DisableKeepAlives = true
@@ -6599,21 +6573,21 @@
 		{"?a=1;x=good;x=bad", "", "good", true},
 	}
 
-	for _, tt := range tests {
-		t.Run(tt.query+"/allow=false", func(t *testing.T) {
-			allowSemicolons := false
-			testQuerySemicolon(t, tt.query, tt.xNoSemicolons, allowSemicolons, tt.warning)
-		})
-		t.Run(tt.query+"/allow=true", func(t *testing.T) {
-			allowSemicolons, expectWarning := true, false
-			testQuerySemicolon(t, tt.query, tt.xWithSemicolons, allowSemicolons, expectWarning)
-		})
-	}
+	run(t, func(t *testing.T, mode testMode) {
+		for _, tt := range tests {
+			t.Run(tt.query+"/allow=false", func(t *testing.T) {
+				allowSemicolons := false
+				testQuerySemicolon(t, mode, tt.query, tt.xNoSemicolons, allowSemicolons, tt.warning)
+			})
+			t.Run(tt.query+"/allow=true", func(t *testing.T) {
+				allowSemicolons, expectWarning := true, false
+				testQuerySemicolon(t, mode, tt.query, tt.xWithSemicolons, allowSemicolons, expectWarning)
+			})
+		}
+	})
 }
 
-func testQuerySemicolon(t *testing.T, query string, wantX string, allowSemicolons, expectWarning bool) {
-	setParallel(t)
-
+func testQuerySemicolon(t *testing.T, mode testMode, query string, wantX string, allowSemicolons, expectWarning bool) {
 	writeBackX := func(w ResponseWriter, r *Request) {
 		x := r.URL.Query().Get("x")
 		if expectWarning {
@@ -6636,11 +6610,10 @@
 		h = AllowQuerySemicolons(h)
 	}
 
-	ts := httptest.NewUnstartedServer(h)
-	logBuf := &bytes.Buffer{}
-	ts.Config.ErrorLog = log.New(logBuf, "", 0)
-	ts.Start()
-	defer ts.Close()
+	logBuf := &strings.Builder{}
+	ts := newClientServerTest(t, mode, h, func(ts *httptest.Server) {
+		ts.Config.ErrorLog = log.New(logBuf, "", 0)
+	}).ts
 
 	req, _ := NewRequest("GET", ts.URL+query, nil)
 	res, err := ts.Client().Do(req)
@@ -6675,13 +6648,15 @@
 		for _, requestSize := range []int64{100, 1_000, 1_000_000} {
 			t.Run(fmt.Sprintf("max size %d request size %d", maxSize, requestSize),
 				func(t *testing.T) {
-					testMaxBytesHandler(t, maxSize, requestSize)
+					run(t, func(t *testing.T, mode testMode) {
+						testMaxBytesHandler(t, mode, maxSize, requestSize)
+					})
 				})
 		}
 	}
 }
 
-func testMaxBytesHandler(t *testing.T, maxSize, requestSize int64) {
+func testMaxBytesHandler(t *testing.T, mode testMode, maxSize, requestSize int64) {
 	var (
 		handlerN   int64
 		handlerErr error
@@ -6692,7 +6667,7 @@
 		io.Copy(w, &buf)
 	})
 
-	ts := httptest.NewServer(MaxBytesHandler(echo, maxSize))
+	ts := newClientServerTest(t, mode, MaxBytesHandler(echo, maxSize)).ts
 	defer ts.Close()
 
 	c := ts.Client()
@@ -6758,3 +6733,124 @@
 		t.Errorf("unexpected response; got %q; should start by %q", got, expected)
 	}
 }
+
+func TestParseFormCleanup(t *testing.T) { run(t, testParseFormCleanup) }
+func testParseFormCleanup(t *testing.T, mode testMode) {
+	if mode == http2Mode {
+		t.Skip("https://go.dev/issue/20253")
+	}
+
+	const maxMemory = 1024
+	const key = "file"
+
+	if runtime.GOOS == "windows" {
+		// Windows sometimes refuses to remove a file that was just closed.
+		t.Skip("https://go.dev/issue/25965")
+	}
+
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
+		r.ParseMultipartForm(maxMemory)
+		f, _, err := r.FormFile(key)
+		if err != nil {
+			t.Errorf("r.FormFile(%q) = %v", key, err)
+			return
+		}
+		of, ok := f.(*os.File)
+		if !ok {
+			t.Errorf("r.FormFile(%q) returned type %T, want *os.File", key, f)
+			return
+		}
+		w.Write([]byte(of.Name()))
+	}))
+
+	fBuf := new(bytes.Buffer)
+	mw := multipart.NewWriter(fBuf)
+	mf, err := mw.CreateFormFile(key, "myfile.txt")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if _, err := mf.Write(bytes.Repeat([]byte("A"), maxMemory*2)); err != nil {
+		t.Fatal(err)
+	}
+	if err := mw.Close(); err != nil {
+		t.Fatal(err)
+	}
+	req, err := NewRequest("POST", cst.ts.URL, fBuf)
+	if err != nil {
+		t.Fatal(err)
+	}
+	req.Header.Set("Content-Type", mw.FormDataContentType())
+	res, err := cst.c.Do(req)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer res.Body.Close()
+	fname, err := io.ReadAll(res.Body)
+	if err != nil {
+		t.Fatal(err)
+	}
+	cst.close()
+	if _, err := os.Stat(string(fname)); !errors.Is(err, os.ErrNotExist) {
+		t.Errorf("file %q exists after HTTP handler returned", string(fname))
+	}
+}
+
+func TestHeadBody(t *testing.T) {
+	const identityMode = false
+	const chunkedMode = true
+	run(t, func(t *testing.T, mode testMode) {
+		t.Run("identity", func(t *testing.T) { testHeadBody(t, mode, identityMode, "HEAD") })
+		t.Run("chunked", func(t *testing.T) { testHeadBody(t, mode, chunkedMode, "HEAD") })
+	})
+}
+
+func TestGetBody(t *testing.T) {
+	const identityMode = false
+	const chunkedMode = true
+	run(t, func(t *testing.T, mode testMode) {
+		t.Run("identity", func(t *testing.T) { testHeadBody(t, mode, identityMode, "GET") })
+		t.Run("chunked", func(t *testing.T) { testHeadBody(t, mode, chunkedMode, "GET") })
+	})
+}
+
+func testHeadBody(t *testing.T, mode testMode, chunked bool, method string) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
+		b, err := io.ReadAll(r.Body)
+		if err != nil {
+			t.Errorf("server reading body: %v", err)
+			return
+		}
+		w.Header().Set("X-Request-Body", string(b))
+		w.Header().Set("Content-Length", "0")
+	}))
+	defer cst.close()
+	for _, reqBody := range []string{
+		"",
+		"",
+		"request_body",
+		"",
+	} {
+		var bodyReader io.Reader
+		if reqBody != "" {
+			bodyReader = strings.NewReader(reqBody)
+			if chunked {
+				bodyReader = bufio.NewReader(bodyReader)
+			}
+		}
+		req, err := NewRequest(method, cst.ts.URL, bodyReader)
+		if err != nil {
+			t.Fatal(err)
+		}
+		res, err := cst.c.Do(req)
+		if err != nil {
+			t.Fatal(err)
+		}
+		res.Body.Close()
+		if got, want := res.StatusCode, 200; got != want {
+			t.Errorf("%v request with %d-byte body: StatusCode = %v, want %v", method, len(reqBody), got, want)
+		}
+		if got, want := res.Header.Get("X-Request-Body"), reqBody; got != want {
+			t.Errorf("%v request with %d-byte body: handler read body %q, want %q", method, len(reqBody), got, want)
+		}
+	}
+}
diff --git a/src/net/http/server.go b/src/net/http/server.go
index 87dd412..c3c3f91 100644
--- a/src/net/http/server.go
+++ b/src/net/http/server.go
@@ -293,9 +293,9 @@
 	// on this connection, if any.
 	lastMethod string
 
-	curReq atomic.Value // of *response (which has a Request in it)
+	curReq atomic.Pointer[response] // (which has a Request in it)
 
-	curState struct{ atomic uint64 } // packed (unixtime<<8|uint8(ConnState))
+	curState atomic.Uint64 // packed (unixtime<<8|uint8(ConnState))
 
 	// mu guards hijackedv
 	mu sync.Mutex
@@ -395,11 +395,11 @@
 	return
 }
 
-func (cw *chunkWriter) flush() {
+func (cw *chunkWriter) flush() error {
 	if !cw.wroteHeader {
 		cw.writeHeader(nil)
 	}
-	cw.res.conn.bufw.Flush()
+	return cw.res.conn.bufw.Flush()
 }
 
 func (cw *chunkWriter) close() {
@@ -430,14 +430,14 @@
 	wants10KeepAlive bool               // HTTP/1.0 w/ Connection "keep-alive"
 	wantsClose       bool               // HTTP request has Connection "close"
 
-	// canWriteContinue is a boolean value accessed as an atomic int32
-	// that says whether or not a 100 Continue header can be written
-	// to the connection.
+	// canWriteContinue is an atomic boolean that says whether or
+	// not a 100 Continue header can be written to the
+	// connection.
 	// writeContinueMu must be held while writing the header.
-	// These two fields together synchronize the body reader
-	// (the expectContinueReader, which wants to write 100 Continue)
+	// These two fields together synchronize the body reader (the
+	// expectContinueReader, which wants to write 100 Continue)
 	// against the main writer.
-	canWriteContinue atomicBool
+	canWriteContinue atomic.Bool
 	writeContinueMu  sync.Mutex
 
 	w  *bufio.Writer // buffers output in chunks to chunkWriter
@@ -475,7 +475,7 @@
 	// written.
 	trailers []string
 
-	handlerDone atomicBool // set true when the handler exits
+	handlerDone atomic.Bool // set true when the handler exits
 
 	// Buffers for Date, Content-Length, and status code
 	dateBuf   [len(TimeFormat)]byte
@@ -486,7 +486,15 @@
 	// TODO(bradfitz): this is currently (for Go 1.8) always
 	// non-nil. Make this lazily-created again as it used to be?
 	closeNotifyCh  chan bool
-	didCloseNotify int32 // atomic (only 0->1 winner should send)
+	didCloseNotify atomic.Bool // atomic (only false->true winner should send)
+}
+
+func (c *response) SetReadDeadline(deadline time.Time) error {
+	return c.conn.rwc.SetReadDeadline(deadline)
+}
+
+func (c *response) SetWriteDeadline(deadline time.Time) error {
+	return c.conn.rwc.SetWriteDeadline(deadline)
 }
 
 // TrailerPrefix is a magic prefix for ResponseWriter.Header map keys
@@ -509,11 +517,11 @@
 func (w *response) finalTrailers() Header {
 	var t Header
 	for k, vv := range w.handlerHeader {
-		if strings.HasPrefix(k, TrailerPrefix) {
+		if kk, found := strings.CutPrefix(k, TrailerPrefix); found {
 			if t == nil {
 				t = make(Header)
 			}
-			t[strings.TrimPrefix(k, TrailerPrefix)] = vv
+			t[kk] = vv
 		}
 	}
 	for _, k := range w.trailers {
@@ -527,12 +535,6 @@
 	return t
 }
 
-type atomicBool int32
-
-func (b *atomicBool) isSet() bool { return atomic.LoadInt32((*int32)(b)) != 0 }
-func (b *atomicBool) setTrue()    { atomic.StoreInt32((*int32)(b), 1) }
-func (b *atomicBool) setFalse()   { atomic.StoreInt32((*int32)(b), 0) }
-
 // declareTrailer is called for each Trailer header when the
 // response header is written. It notes that a header will need to be
 // written in the trailers at the end of the response.
@@ -555,12 +557,6 @@
 	}
 }
 
-// needsSniff reports whether a Content-Type still needs to be sniffed.
-func (w *response) needsSniff() bool {
-	_, haveType := w.handlerHeader["Content-Type"]
-	return !w.cw.wroteHeader && !haveType && w.written < sniffLen
-}
-
 // writerOnly hides an io.Writer value's optional ReadFrom method
 // from io.Copy.
 type writerOnly struct {
@@ -749,8 +745,8 @@
 
 // may be called from multiple goroutines.
 func (cr *connReader) closeNotify() {
-	res, _ := cr.conn.curReq.Load().(*response)
-	if res != nil && atomic.CompareAndSwapInt32(&res.didCloseNotify, 0, 1) {
+	res := cr.conn.curReq.Load()
+	if res != nil && !res.didCloseNotify.Swap(true) {
 		res.closeNotifyCh <- true
 	}
 }
@@ -898,34 +894,34 @@
 type expectContinueReader struct {
 	resp       *response
 	readCloser io.ReadCloser
-	closed     atomicBool
-	sawEOF     atomicBool
+	closed     atomic.Bool
+	sawEOF     atomic.Bool
 }
 
 func (ecr *expectContinueReader) Read(p []byte) (n int, err error) {
-	if ecr.closed.isSet() {
+	if ecr.closed.Load() {
 		return 0, ErrBodyReadAfterClose
 	}
 	w := ecr.resp
-	if !w.wroteContinue && w.canWriteContinue.isSet() && !w.conn.hijacked() {
+	if !w.wroteContinue && w.canWriteContinue.Load() && !w.conn.hijacked() {
 		w.wroteContinue = true
 		w.writeContinueMu.Lock()
-		if w.canWriteContinue.isSet() {
+		if w.canWriteContinue.Load() {
 			w.conn.bufw.WriteString("HTTP/1.1 100 Continue\r\n\r\n")
 			w.conn.bufw.Flush()
-			w.canWriteContinue.setFalse()
+			w.canWriteContinue.Store(false)
 		}
 		w.writeContinueMu.Unlock()
 	}
 	n, err = ecr.readCloser.Read(p)
 	if err == io.EOF {
-		ecr.sawEOF.setTrue()
+		ecr.sawEOF.Store(true)
 	}
 	return
 }
 
 func (ecr *expectContinueReader) Close() error {
-	ecr.closed.setTrue()
+	ecr.closed.Store(true)
 	return ecr.readCloser.Close()
 }
 
@@ -1152,9 +1148,9 @@
 	// Handle informational headers
 	if code >= 100 && code <= 199 {
 		// Prevent a potential race with an automatically-sent 100 Continue triggered by Request.Body.Read()
-		if code == 100 && w.canWriteContinue.isSet() {
+		if code == 100 && w.canWriteContinue.Load() {
 			w.writeContinueMu.Lock()
-			w.canWriteContinue.setFalse()
+			w.canWriteContinue.Store(false)
 			w.writeContinueMu.Unlock()
 		}
 
@@ -1312,7 +1308,7 @@
 	// send a Content-Length header.
 	// Further, we don't send an automatic Content-Length if they
 	// set a Transfer-Encoding, because they're generally incompatible.
-	if w.handlerDone.isSet() && !trailers && !hasTE && bodyAllowedForStatus(w.status) && header.get("Content-Length") == "" && (!isHEAD || len(p) > 0) {
+	if w.handlerDone.Load() && !trailers && !hasTE && bodyAllowedForStatus(w.status) && header.get("Content-Length") == "" && (!isHEAD || len(p) > 0) {
 		w.contentLength = int64(len(p))
 		setHeader.contentLength = strconv.AppendInt(cw.res.clenBuf[:0], int64(len(p)), 10)
 	}
@@ -1354,7 +1350,7 @@
 	// because we don't know if the next bytes on the wire will be
 	// the body-following-the-timer or the subsequent request.
 	// See Issue 11549.
-	if ecr, ok := w.req.Body.(*expectContinueReader); ok && !ecr.sawEOF.isSet() {
+	if ecr, ok := w.req.Body.(*expectContinueReader); ok && !ecr.sawEOF.Load() {
 		w.closeAfterReply = true
 	}
 
@@ -1612,13 +1608,13 @@
 		return 0, ErrHijacked
 	}
 
-	if w.canWriteContinue.isSet() {
+	if w.canWriteContinue.Load() {
 		// Body reader wants to write 100 Continue but hasn't yet.
 		// Tell it not to. The store must be done while holding the lock
 		// because the lock makes sure that there is not an active write
 		// this very moment.
 		w.writeContinueMu.Lock()
-		w.canWriteContinue.setFalse()
+		w.canWriteContinue.Store(false)
 		w.writeContinueMu.Unlock()
 	}
 
@@ -1644,7 +1640,7 @@
 }
 
 func (w *response) finishRequest() {
-	w.handlerDone.setTrue()
+	w.handlerDone.Store(true)
 
 	if !w.wroteHeader {
 		w.WriteHeader(StatusOK)
@@ -1700,11 +1696,19 @@
 }
 
 func (w *response) Flush() {
+	w.FlushError()
+}
+
+func (w *response) FlushError() error {
 	if !w.wroteHeader {
 		w.WriteHeader(StatusOK)
 	}
-	w.w.Flush()
-	w.cw.flush()
+	err := w.w.Flush()
+	e2 := w.cw.flush()
+	if err == nil {
+		err = e2
+	}
+	return err
 }
 
 func (c *conn) finalFlush() {
@@ -1787,7 +1791,7 @@
 		panic("internal error")
 	}
 	packedState := uint64(time.Now().Unix()<<8) | uint64(state)
-	atomic.StoreUint64(&c.curState.atomic, packedState)
+	c.curState.Store(packedState)
 	if !runHook {
 		return
 	}
@@ -1797,7 +1801,7 @@
 }
 
 func (c *conn) getState() (state ConnState, unixSec int64) {
-	packedState := atomic.LoadUint64(&c.curState.atomic)
+	packedState := c.curState.Load()
 	return ConnState(packedState & 0xff), int64(packedState >> 8)
 }
 
@@ -1965,7 +1969,7 @@
 			if req.ProtoAtLeast(1, 1) && req.ContentLength != 0 {
 				// Wrap the Body reader with one that replies on the connection
 				req.Body = &expectContinueReader{readCloser: req.Body, resp: w}
-				w.canWriteContinue.setTrue()
+				w.canWriteContinue.Store(true)
 			}
 		} else if req.Header.get("Expect") != "" {
 			w.sendExpectationFailed()
@@ -1995,6 +1999,7 @@
 			return
 		}
 		w.finishRequest()
+		c.rwc.SetWriteDeadline(time.Time{})
 		if !w.shouldReuseConnection() {
 			if w.requestBodyLimitHit || w.closedRequestBodyEarly() {
 				c.closeWriteAndWait()
@@ -2002,7 +2007,7 @@
 			return
 		}
 		c.setState(c.rwc, StateIdle, runHooks)
-		c.curReq.Store((*response)(nil))
+		c.curReq.Store(nil)
 
 		if !w.conn.server.doKeepAlives() {
 			// We're in shutdown mode. We might've replied
@@ -2014,10 +2019,18 @@
 
 		if d := c.server.idleTimeout(); d != 0 {
 			c.rwc.SetReadDeadline(time.Now().Add(d))
-			if _, err := c.bufr.Peek(4); err != nil {
-				return
-			}
+		} else {
+			c.rwc.SetReadDeadline(time.Time{})
 		}
+
+		// Wait for the connection to become readable again before trying to
+		// read the next request. This prevents a ReadHeaderTimeout or
+		// ReadTimeout from starting until the first bytes of the next request
+		// have been received.
+		if _, err := c.bufr.Peek(4); err != nil {
+			return
+		}
+
 		c.rwc.SetReadDeadline(time.Time{})
 	}
 }
@@ -2043,7 +2056,7 @@
 // Hijack implements the Hijacker.Hijack method. Our response is both a ResponseWriter
 // and a Hijacker.
 func (w *response) Hijack() (rwc net.Conn, buf *bufio.ReadWriter, err error) {
-	if w.handlerDone.isSet() {
+	if w.handlerDone.Load() {
 		panic("net/http: Hijack called after ServeHTTP finished")
 	}
 	if w.wroteHeader {
@@ -2065,7 +2078,7 @@
 }
 
 func (w *response) CloseNotify() <-chan bool {
-	if w.handlerDone.isSet() {
+	if w.handlerDone.Load() {
 		panic("net/http: CloseNotify called after ServeHTTP finished")
 	}
 	return w.closeNotifyCh
@@ -2596,6 +2609,10 @@
 
 	Handler Handler // handler to invoke, http.DefaultServeMux if nil
 
+	// DisableGeneralOptionsHandler, if true, passes "OPTIONS *" requests to the Handler,
+	// otherwise responds with 200 OK and Content-Length: 0.
+	DisableGeneralOptionsHandler bool
+
 	// TLSConfig optionally provides a TLS configuration for use
 	// by ServeTLS and ListenAndServeTLS. Note that this value is
 	// cloned by ServeTLS and ListenAndServeTLS, so it's not
@@ -2679,46 +2696,20 @@
 	// value.
 	ConnContext func(ctx context.Context, c net.Conn) context.Context
 
-	inShutdown atomicBool // true when server is in shutdown
+	inShutdown atomic.Bool // true when server is in shutdown
 
-	disableKeepAlives int32     // accessed atomically.
+	disableKeepAlives atomic.Bool
 	nextProtoOnce     sync.Once // guards setupHTTP2_* init
 	nextProtoErr      error     // result of http2.ConfigureServer if used
 
 	mu         sync.Mutex
 	listeners  map[*net.Listener]struct{}
 	activeConn map[*conn]struct{}
-	doneChan   chan struct{}
 	onShutdown []func()
 
 	listenerGroup sync.WaitGroup
 }
 
-func (s *Server) getDoneChan() <-chan struct{} {
-	s.mu.Lock()
-	defer s.mu.Unlock()
-	return s.getDoneChanLocked()
-}
-
-func (s *Server) getDoneChanLocked() chan struct{} {
-	if s.doneChan == nil {
-		s.doneChan = make(chan struct{})
-	}
-	return s.doneChan
-}
-
-func (s *Server) closeDoneChanLocked() {
-	ch := s.getDoneChanLocked()
-	select {
-	case <-ch:
-		// Already closed. Don't close again.
-	default:
-		// Safe to close here. We're the only closer, guarded
-		// by s.mu.
-		close(ch)
-	}
-}
-
 // Close immediately closes all active net.Listeners and any
 // connections in state StateNew, StateActive, or StateIdle. For a
 // graceful shutdown, use Shutdown.
@@ -2729,10 +2720,9 @@
 // Close returns any error returned from closing the Server's
 // underlying Listener(s).
 func (srv *Server) Close() error {
-	srv.inShutdown.setTrue()
+	srv.inShutdown.Store(true)
 	srv.mu.Lock()
 	defer srv.mu.Unlock()
-	srv.closeDoneChanLocked()
 	err := srv.closeListenersLocked()
 
 	// Unlock srv.mu while waiting for listenerGroup.
@@ -2780,11 +2770,10 @@
 // Once Shutdown has been called on a server, it may not be reused;
 // future calls to methods such as Serve will return ErrServerClosed.
 func (srv *Server) Shutdown(ctx context.Context) error {
-	srv.inShutdown.setTrue()
+	srv.inShutdown.Store(true)
 
 	srv.mu.Lock()
 	lnerr := srv.closeListenersLocked()
-	srv.closeDoneChanLocked()
 	for _, f := range srv.onShutdown {
 		go f()
 	}
@@ -2928,17 +2917,17 @@
 	if handler == nil {
 		handler = DefaultServeMux
 	}
-	if req.RequestURI == "*" && req.Method == "OPTIONS" {
+	if !sh.srv.DisableGeneralOptionsHandler && req.RequestURI == "*" && req.Method == "OPTIONS" {
 		handler = globalOptionsHandler{}
 	}
 
 	if req.URL != nil && strings.Contains(req.URL.RawQuery, ";") {
-		var allowQuerySemicolonsInUse int32
+		var allowQuerySemicolonsInUse atomic.Bool
 		req = req.WithContext(context.WithValue(req.Context(), silenceSemWarnContextKey, func() {
-			atomic.StoreInt32(&allowQuerySemicolonsInUse, 1)
+			allowQuerySemicolonsInUse.Store(true)
 		}))
 		defer func() {
-			if atomic.LoadInt32(&allowQuerySemicolonsInUse) == 0 {
+			if !allowQuerySemicolonsInUse.Load() {
 				sh.srv.logf("http: URL query contains semicolon, which is no longer a supported separator; parts of the query may be stripped when parsed; see golang.org/issue/25192")
 			}
 		}()
@@ -3069,10 +3058,8 @@
 	for {
 		rw, err := l.Accept()
 		if err != nil {
-			select {
-			case <-srv.getDoneChan():
+			if srv.shuttingDown() {
 				return ErrServerClosed
-			default:
 			}
 			if ne, ok := err.(net.Error); ok && ne.Temporary() {
 				if tempDelay == 0 {
@@ -3199,11 +3186,11 @@
 }
 
 func (s *Server) doKeepAlives() bool {
-	return atomic.LoadInt32(&s.disableKeepAlives) == 0 && !s.shuttingDown()
+	return !s.disableKeepAlives.Load() && !s.shuttingDown()
 }
 
 func (s *Server) shuttingDown() bool {
-	return s.inShutdown.isSet()
+	return s.inShutdown.Load()
 }
 
 // SetKeepAlivesEnabled controls whether HTTP keep-alives are enabled.
@@ -3212,10 +3199,10 @@
 // shutting down should disable them.
 func (srv *Server) SetKeepAlivesEnabled(v bool) {
 	if v {
-		atomic.StoreInt32(&srv.disableKeepAlives, 0)
+		srv.disableKeepAlives.Store(false)
 		return
 	}
-	atomic.StoreInt32(&srv.disableKeepAlives, 1)
+	srv.disableKeepAlives.Store(true)
 
 	// Close idle HTTP/1 conns:
 	srv.closeIdleConns()
@@ -3326,11 +3313,13 @@
 	}
 }
 
+var http2server = godebug.New("http2server")
+
 // onceSetNextProtoDefaults configures HTTP/2, if the user hasn't
 // configured otherwise. (by setting srv.TLSNextProto non-nil)
 // It must only be called via srv.nextProtoOnce (use srv.setupHTTP2_*).
 func (srv *Server) onceSetNextProtoDefaults() {
-	if omitBundledHTTP2 || godebug.Get("http2server") == "0" {
+	if omitBundledHTTP2 || http2server.Value() == "0" {
 		return
 	}
 	// Enable HTTP/2 by default if the user hasn't otherwise
diff --git a/src/net/http/sniff_test.go b/src/net/http/sniff_test.go
index e913357..d6ef409 100644
--- a/src/net/http/sniff_test.go
+++ b/src/net/http/sniff_test.go
@@ -88,13 +88,9 @@
 	}
 }
 
-func TestServerContentType_h1(t *testing.T) { testServerContentType(t, h1Mode) }
-func TestServerContentType_h2(t *testing.T) { testServerContentType(t, h2Mode) }
-
-func testServerContentType(t *testing.T, h2 bool) {
-	setParallel(t)
-	defer afterTest(t)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestServerContentTypeSniff(t *testing.T) { run(t, testServerContentTypeSniff) }
+func testServerContentTypeSniff(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		i, _ := strconv.Atoi(r.FormValue("i"))
 		tt := sniffTests[i]
 		n, err := w.Write(tt.data)
@@ -134,15 +130,12 @@
 
 // Issue 5953: shouldn't sniff if the handler set a Content-Type header,
 // even if it's the empty string.
-func TestServerIssue5953_h1(t *testing.T) { testServerIssue5953(t, h1Mode) }
-func TestServerIssue5953_h2(t *testing.T) { testServerIssue5953(t, h2Mode) }
-func testServerIssue5953(t *testing.T, h2 bool) {
-	defer afterTest(t)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestServerIssue5953(t *testing.T) { run(t, testServerIssue5953) }
+func testServerIssue5953(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		w.Header()["Content-Type"] = []string{""}
 		fmt.Fprintf(w, "<html><head></head><body>hi</body></html>")
 	}))
-	defer cst.close()
 
 	resp, err := cst.c.Get(cst.ts.URL)
 	if err != nil {
@@ -173,11 +166,8 @@
 	return 1, nil
 }
 
-func TestContentTypeWithVariousSources_h1(t *testing.T) { testContentTypeWithVariousSources(t, h1Mode) }
-func TestContentTypeWithVariousSources_h2(t *testing.T) { testContentTypeWithVariousSources(t, h2Mode) }
-func testContentTypeWithVariousSources(t *testing.T, h2 bool) {
-	defer afterTest(t)
-
+func TestContentTypeWithVariousSources(t *testing.T) { run(t, testContentTypeWithVariousSources) }
+func testContentTypeWithVariousSources(t *testing.T, mode testMode) {
 	const (
 		input    = "\n<html>\n\t<head>\n"
 		expected = "text/html; charset=utf-8"
@@ -239,8 +229,7 @@
 		},
 	}} {
 		t.Run(test.name, func(t *testing.T) {
-			cst := newClientServerTest(t, h2, HandlerFunc(test.handler))
-			defer cst.close()
+			cst := newClientServerTest(t, mode, HandlerFunc(test.handler))
 
 			resp, err := cst.c.Get(cst.ts.URL)
 			if err != nil {
@@ -265,12 +254,9 @@
 	}
 }
 
-func TestSniffWriteSize_h1(t *testing.T) { testSniffWriteSize(t, h1Mode) }
-func TestSniffWriteSize_h2(t *testing.T) { testSniffWriteSize(t, h2Mode) }
-func testSniffWriteSize(t *testing.T, h2 bool) {
-	setParallel(t)
-	defer afterTest(t)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestSniffWriteSize(t *testing.T) { run(t, testSniffWriteSize) }
+func testSniffWriteSize(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		size, _ := strconv.Atoi(r.FormValue("size"))
 		written, err := io.WriteString(w, strings.Repeat("a", size))
 		if err != nil {
@@ -281,7 +267,6 @@
 			t.Errorf("write of %d bytes wrote %d bytes", size, written)
 		}
 	}))
-	defer cst.close()
 	for _, size := range []int{0, 1, 200, 600, 999, 1000, 1023, 1024, 512 << 10, 1 << 20} {
 		res, err := cst.c.Get(fmt.Sprintf("%s/?size=%d", cst.ts.URL, size))
 		if err != nil {
diff --git a/src/net/http/transfer.go b/src/net/http/transfer.go
index 4583c6b..7c7afd7 100644
--- a/src/net/http/transfer.go
+++ b/src/net/http/transfer.go
@@ -557,7 +557,7 @@
 	// or close connection when finished, since multipart is not supported yet
 	switch {
 	case t.Chunked:
-		if noResponseBodyExpected(t.RequestMethod) || !bodyAllowedForStatus(t.StatusCode) {
+		if isResponse && (noResponseBodyExpected(t.RequestMethod) || !bodyAllowedForStatus(t.StatusCode)) {
 			t.Body = NoBody
 		} else {
 			t.Body = &body{src: internal.NewChunkedReader(r), hdr: msg, r: r, closing: t.Close}
@@ -600,7 +600,7 @@
 	return nil
 }
 
-// Checks whether chunked is part of the encodings stack
+// Checks whether chunked is part of the encodings stack.
 func chunked(te []string) bool { return len(te) > 0 && te[0] == "chunked" }
 
 // Checks whether the encoding is explicitly "identity".
@@ -691,14 +691,7 @@
 	}
 
 	// Logic based on response type or status
-	if noResponseBodyExpected(requestMethod) {
-		// For HTTP requests, as part of hardening against request
-		// smuggling (RFC 7230), don't allow a Content-Length header for
-		// methods which don't permit bodies. As an exception, allow
-		// exactly one Content-Length header if its value is "0".
-		if isRequest && len(contentLens) > 0 && !(len(contentLens) == 1 && contentLens[0] == "0") {
-			return 0, fmt.Errorf("http: method cannot contain a Content-Length; got %q", contentLens)
-		}
+	if isResponse && noResponseBodyExpected(requestMethod) {
 		return 0, nil
 	}
 	if status/100 == 1 {
@@ -745,7 +738,7 @@
 
 // Determine whether to hang up after sending a request and body, or
 // receiving a response and body
-// 'header' is the request headers
+// 'header' is the request headers.
 func shouldClose(major, minor int, header Header, removeCloseHeader bool) bool {
 	if major < 1 {
 		return true
@@ -764,7 +757,7 @@
 	return hasClose
 }
 
-// Parse the trailer header
+// Parse the trailer header.
 func fixTrailer(header Header, chunked bool) (Header, error) {
 	vv, ok := header["Trailer"]
 	if !ok {
@@ -1088,7 +1081,7 @@
 }{}))
 
 // unwrapNopCloser return the underlying reader and true if r is a NopCloser
-// else it return false
+// else it return false.
 func unwrapNopCloser(r io.Reader) (underlyingReader io.Reader, isNopCloser bool) {
 	switch reflect.TypeOf(r) {
 	case nopCloserType, nopCloserWriterToType:
diff --git a/src/net/http/transport.go b/src/net/http/transport.go
index e470a6c..ddcb648 100644
--- a/src/net/http/transport.go
+++ b/src/net/http/transport.go
@@ -38,8 +38,8 @@
 // DefaultTransport is the default implementation of Transport and is
 // used by DefaultClient. It establishes network connections as needed
 // and caches them for reuse by subsequent calls. It uses HTTP proxies
-// as directed by the $HTTP_PROXY and $NO_PROXY (or $http_proxy and
-// $no_proxy) environment variables.
+// as directed by the environment variables HTTP_PROXY, HTTPS_PROXY
+// and NO_PROXY (or the lowercase versions thereof).
 var DefaultTransport RoundTripper = &Transport{
 	Proxy: ProxyFromEnvironment,
 	DialContext: defaultTransportDialContext(&net.Dialer{
@@ -120,6 +120,11 @@
 	// If Proxy is nil or returns a nil *URL, no proxy is used.
 	Proxy func(*Request) (*url.URL, error)
 
+	// OnProxyConnectResponse is called when the Transport gets an HTTP response from
+	// a proxy for a CONNECT request. It's called before the check for a 200 OK response.
+	// If it returns an error, the request fails with that error.
+	OnProxyConnectResponse func(ctx context.Context, proxyURL *url.URL, connectReq *Request, connectRes *Response) error
+
 	// DialContext specifies the dial function for creating unencrypted TCP connections.
 	// If DialContext is nil (and the deprecated Dial below is also nil),
 	// then the transport dials using package net.
@@ -309,6 +314,7 @@
 	t.nextProtoOnce.Do(t.onceSetNextProtoDefaults)
 	t2 := &Transport{
 		Proxy:                  t.Proxy,
+		OnProxyConnectResponse: t.OnProxyConnectResponse,
 		DialContext:            t.DialContext,
 		Dial:                   t.Dial,
 		DialTLS:                t.DialTLS,
@@ -356,11 +362,13 @@
 	return t.DialTLS != nil || t.DialTLSContext != nil
 }
 
+var http2client = godebug.New("http2client")
+
 // onceSetNextProtoDefaults initializes TLSNextProto.
 // It must be called via t.nextProtoOnce.Do.
 func (t *Transport) onceSetNextProtoDefaults() {
 	t.tlsNextProtoWasNil = (t.TLSNextProto == nil)
-	if godebug.Get("http2client") == "0" {
+	if http2client.Value() == "0" {
 		return
 	}
 
@@ -422,8 +430,8 @@
 // ProxyFromEnvironment returns the URL of the proxy to use for a
 // given request, as indicated by the environment variables
 // HTTP_PROXY, HTTPS_PROXY and NO_PROXY (or the lowercase versions
-// thereof). HTTPS_PROXY takes precedence over HTTP_PROXY for https
-// requests.
+// thereof). Requests use the proxy from the environment variable
+// matching their scheme, unless excluded by NO_PROXY.
 //
 // The environment values may be either a complete URL or a
 // "host[:port]", in which case the "http" scheme is assumed.
@@ -810,14 +818,12 @@
 //
 
 var (
-	// proxyConfigOnce guards proxyConfig
 	envProxyOnce      sync.Once
 	envProxyFuncValue func(*url.URL) (*url.URL, error)
 )
 
-// defaultProxyConfig returns a ProxyConfig value looked up
-// from the environment. This mitigates expensive lookups
-// on some platforms (e.g. Windows).
+// envProxyFunc returns a function that reads the
+// environment variable to determine the proxy address.
 func envProxyFunc() func(*url.URL) (*url.URL, error) {
 	envProxyOnce.Do(func() {
 		envProxyFuncValue = httpproxy.FromEnvironment().ProxyFunc()
@@ -1718,6 +1724,14 @@
 			conn.Close()
 			return nil, err
 		}
+
+		if t.OnProxyConnectResponse != nil {
+			err = t.OnProxyConnectResponse(ctx, cm.proxyURL, connectReq, resp)
+			if err != nil {
+				return nil, err
+			}
+		}
+
 		if resp.StatusCode != 200 {
 			_, text, ok := strings.Cut(resp.Status, " ")
 			conn.Close()
@@ -2045,7 +2059,7 @@
 		if pc.nwrite == startBytesWritten {
 			return nothingWrittenError{err}
 		}
-		return fmt.Errorf("net/http: HTTP/1.x transport connection broken: %v", err)
+		return fmt.Errorf("net/http: HTTP/1.x transport connection broken: %w", err)
 	}
 	return err
 }
@@ -2252,7 +2266,7 @@
 		// common case.
 		pc.closeLocked(errServerClosedIdle)
 	} else {
-		pc.closeLocked(fmt.Errorf("readLoopPeekFailLocked: %v", peekErr))
+		pc.closeLocked(fmt.Errorf("readLoopPeekFailLocked: %w", peekErr))
 	}
 }
 
@@ -2386,6 +2400,10 @@
 	error
 }
 
+func (nwe nothingWrittenError) Unwrap() error {
+	return nwe.error
+}
+
 func (pc *persistConn) writeLoop() {
 	defer close(pc.writeLoopDone)
 	for {
@@ -2623,7 +2641,7 @@
 				req.logf("writeErrCh resv: %T/%#v", err, err)
 			}
 			if err != nil {
-				pc.close(fmt.Errorf("write error: %v", err))
+				pc.close(fmt.Errorf("write error: %w", err))
 				return nil, pc.mapRoundTripError(req, startBytesWritten, err)
 			}
 			if d := pc.t.ResponseHeaderTimeout; d > 0 {
@@ -2725,7 +2743,7 @@
 	"socks5": "1080",
 }
 
-// canonicalAddr returns url.Host but always with a ":port" suffix
+// canonicalAddr returns url.Host but always with a ":port" suffix.
 func canonicalAddr(url *url.URL) string {
 	addr := url.Hostname()
 	if v, err := idnaASCII(addr); err == nil {
diff --git a/src/net/http/transport_test.go b/src/net/http/transport_test.go
index cba35db..245f73b 100644
--- a/src/net/http/transport_test.go
+++ b/src/net/http/transport_test.go
@@ -135,12 +135,11 @@
 	}
 }
 
-func TestReuseRequest(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestReuseRequest(t *testing.T) { run(t, testReuseRequest) }
+func testReuseRequest(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		w.Write([]byte("{}"))
-	}))
-	defer ts.Close()
+	})).ts
 
 	c := ts.Client()
 	req, _ := NewRequest("GET", ts.URL, nil)
@@ -165,10 +164,9 @@
 
 // Two subsequent requests and verify their response is the same.
 // The response from the server is our own IP:port
-func TestTransportKeepAlives(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(hostPortHandler)
-	defer ts.Close()
+func TestTransportKeepAlives(t *testing.T) { run(t, testTransportKeepAlives, []testMode{http1Mode}) }
+func testTransportKeepAlives(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, hostPortHandler).ts
 
 	c := ts.Client()
 	for _, disableKeepAlive := range []bool{false, true} {
@@ -197,9 +195,10 @@
 }
 
 func TestTransportConnectionCloseOnResponse(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(hostPortHandler)
-	defer ts.Close()
+	run(t, testTransportConnectionCloseOnResponse)
+}
+func testTransportConnectionCloseOnResponse(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, hostPortHandler).ts
 
 	connSet, testDial := makeTestDial(t)
 
@@ -253,9 +252,10 @@
 // describes the source source connection it got (remote port number +
 // address of its net.Conn).
 func TestTransportConnectionCloseOnRequest(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(hostPortHandler)
-	defer ts.Close()
+	run(t, testTransportConnectionCloseOnRequest, []testMode{http1Mode})
+}
+func testTransportConnectionCloseOnRequest(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, hostPortHandler).ts
 
 	connSet, testDial := makeTestDial(t)
 
@@ -317,9 +317,10 @@
 // send Connection: close.
 // HTTP/1-only (Connection: close doesn't exist in h2)
 func TestTransportConnectionCloseOnRequestDisableKeepAlive(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(hostPortHandler)
-	defer ts.Close()
+	run(t, testTransportConnectionCloseOnRequestDisableKeepAlive, []testMode{http1Mode})
+}
+func testTransportConnectionCloseOnRequestDisableKeepAlive(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, hostPortHandler).ts
 
 	c := ts.Client()
 	c.Transport.(*Transport).DisableKeepAlives = true
@@ -337,6 +338,9 @@
 // Test that Transport only sends one "Connection: close", regardless of
 // how "close" was indicated.
 func TestTransportRespectRequestWantsClose(t *testing.T) {
+	run(t, testTransportRespectRequestWantsClose, []testMode{http1Mode})
+}
+func testTransportRespectRequestWantsClose(t *testing.T, mode testMode) {
 	tests := []struct {
 		disableKeepAlives bool
 		close             bool
@@ -350,9 +354,7 @@
 	for _, tc := range tests {
 		t.Run(fmt.Sprintf("DisableKeepAlive=%v,RequestClose=%v", tc.disableKeepAlives, tc.close),
 			func(t *testing.T) {
-				defer afterTest(t)
-				ts := httptest.NewServer(hostPortHandler)
-				defer ts.Close()
+				ts := newClientServerTest(t, mode, hostPortHandler).ts
 
 				c := ts.Client()
 				c.Transport.(*Transport).DisableKeepAlives = tc.disableKeepAlives
@@ -387,9 +389,10 @@
 }
 
 func TestTransportIdleCacheKeys(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(hostPortHandler)
-	defer ts.Close()
+	run(t, testTransportIdleCacheKeys, []testMode{http1Mode})
+}
+func testTransportIdleCacheKeys(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, hostPortHandler).ts
 	c := ts.Client()
 	tr := c.Transport.(*Transport)
 
@@ -420,12 +423,12 @@
 
 // Tests that the HTTP transport re-uses connections when a client
 // reads to the end of a response Body without closing it.
-func TestTransportReadToEndReusesConn(t *testing.T) {
-	defer afterTest(t)
+func TestTransportReadToEndReusesConn(t *testing.T) { run(t, testTransportReadToEndReusesConn) }
+func testTransportReadToEndReusesConn(t *testing.T, mode testMode) {
 	const msg = "foobar"
 
 	var addrSeen map[string]int
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		addrSeen[r.RemoteAddr]++
 		if r.URL.Path == "/chunked/" {
 			w.WriteHeader(200)
@@ -435,16 +438,13 @@
 			w.WriteHeader(200)
 		}
 		w.Write([]byte(msg))
-	}))
-	defer ts.Close()
-
-	buf := make([]byte, len(msg))
+	})).ts
 
 	for pi, path := range []string{"/content-length/", "/chunked/"} {
 		wantLen := []int{len(msg), -1}[pi]
 		addrSeen = make(map[string]int)
 		for i := 0; i < 3; i++ {
-			res, err := Get(ts.URL + path)
+			res, err := ts.Client().Get(ts.URL + path)
 			if err != nil {
 				t.Errorf("Get %s: %v", path, err)
 				continue
@@ -459,9 +459,9 @@
 			if res.ContentLength != int64(wantLen) {
 				t.Errorf("%s res.ContentLength = %d; want %d", path, res.ContentLength, wantLen)
 			}
-			n, err := res.Body.Read(buf)
-			if n != len(msg) || err != io.EOF {
-				t.Errorf("%s Read = %v, %v; want %d, EOF", path, n, err, len(msg))
+			got, err := io.ReadAll(res.Body)
+			if string(got) != msg || err != nil {
+				t.Errorf("%s ReadAll(Body) = %q, %v; want %q, nil", path, string(got), err, msg)
 			}
 		}
 		if len(addrSeen) != 1 {
@@ -471,13 +471,15 @@
 }
 
 func TestTransportMaxPerHostIdleConns(t *testing.T) {
-	defer afterTest(t)
+	run(t, testTransportMaxPerHostIdleConns, []testMode{http1Mode})
+}
+func testTransportMaxPerHostIdleConns(t *testing.T, mode testMode) {
 	stop := make(chan struct{}) // stop marks the exit of main Test goroutine
 	defer close(stop)
 
 	resch := make(chan string)
 	gotReq := make(chan bool)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		gotReq <- true
 		var msg string
 		select {
@@ -490,8 +492,7 @@
 			t.Errorf("Write: %v", err)
 			return
 		}
-	}))
-	defer ts.Close()
+	})).ts
 
 	c := ts.Client()
 	tr := c.Transport.(*Transport)
@@ -559,14 +560,15 @@
 }
 
 func TestTransportMaxConnsPerHostIncludeDialInProgress(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	run(t, testTransportMaxConnsPerHostIncludeDialInProgress)
+}
+func testTransportMaxConnsPerHostIncludeDialInProgress(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		_, err := w.Write([]byte("foo"))
 		if err != nil {
 			t.Fatalf("Write: %v", err)
 		}
-	}))
-	defer ts.Close()
+	})).ts
 	c := ts.Client()
 	tr := c.Transport.(*Transport)
 	dialStarted := make(chan struct{})
@@ -626,7 +628,9 @@
 }
 
 func TestTransportMaxConnsPerHost(t *testing.T) {
-	defer afterTest(t)
+	run(t, testTransportMaxConnsPerHost, []testMode{http1Mode, https1Mode, http2Mode})
+}
+func testTransportMaxConnsPerHost(t *testing.T, mode testMode) {
 	CondSkipHTTP2(t)
 
 	h := HandlerFunc(func(w ResponseWriter, r *Request) {
@@ -636,115 +640,101 @@
 		}
 	})
 
-	testMaxConns := func(scheme string, ts *httptest.Server) {
-		defer ts.Close()
+	ts := newClientServerTest(t, mode, h).ts
+	c := ts.Client()
+	tr := c.Transport.(*Transport)
+	tr.MaxConnsPerHost = 1
 
-		c := ts.Client()
-		tr := c.Transport.(*Transport)
-		tr.MaxConnsPerHost = 1
-		if err := ExportHttp2ConfigureTransport(tr); err != nil {
-			t.Fatalf("ExportHttp2ConfigureTransport: %v", err)
-		}
-
-		mu := sync.Mutex{}
-		var conns []net.Conn
-		var dialCnt, gotConnCnt, tlsHandshakeCnt int32
-		tr.Dial = func(network, addr string) (net.Conn, error) {
-			atomic.AddInt32(&dialCnt, 1)
-			c, err := net.Dial(network, addr)
-			mu.Lock()
-			defer mu.Unlock()
-			conns = append(conns, c)
-			return c, err
-		}
-
-		doReq := func() {
-			trace := &httptrace.ClientTrace{
-				GotConn: func(connInfo httptrace.GotConnInfo) {
-					if !connInfo.Reused {
-						atomic.AddInt32(&gotConnCnt, 1)
-					}
-				},
-				TLSHandshakeStart: func() {
-					atomic.AddInt32(&tlsHandshakeCnt, 1)
-				},
-			}
-			req, _ := NewRequest("GET", ts.URL, nil)
-			req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace))
-
-			resp, err := c.Do(req)
-			if err != nil {
-				t.Fatalf("request failed: %v", err)
-			}
-			defer resp.Body.Close()
-			_, err = io.ReadAll(resp.Body)
-			if err != nil {
-				t.Fatalf("read body failed: %v", err)
-			}
-		}
-
-		wg := sync.WaitGroup{}
-		for i := 0; i < 10; i++ {
-			wg.Add(1)
-			go func() {
-				defer wg.Done()
-				doReq()
-			}()
-		}
-		wg.Wait()
-
-		expected := int32(tr.MaxConnsPerHost)
-		if dialCnt != expected {
-			t.Errorf("round 1: too many dials (%s): %d != %d", scheme, dialCnt, expected)
-		}
-		if gotConnCnt != expected {
-			t.Errorf("round 1: too many get connections (%s): %d != %d", scheme, gotConnCnt, expected)
-		}
-		if ts.TLS != nil && tlsHandshakeCnt != expected {
-			t.Errorf("round 1: too many tls handshakes (%s): %d != %d", scheme, tlsHandshakeCnt, expected)
-		}
-
-		if t.Failed() {
-			t.FailNow()
-		}
-
+	mu := sync.Mutex{}
+	var conns []net.Conn
+	var dialCnt, gotConnCnt, tlsHandshakeCnt int32
+	tr.Dial = func(network, addr string) (net.Conn, error) {
+		atomic.AddInt32(&dialCnt, 1)
+		c, err := net.Dial(network, addr)
 		mu.Lock()
-		for _, c := range conns {
-			c.Close()
-		}
-		conns = nil
-		mu.Unlock()
-		tr.CloseIdleConnections()
+		defer mu.Unlock()
+		conns = append(conns, c)
+		return c, err
+	}
 
-		doReq()
-		expected++
-		if dialCnt != expected {
-			t.Errorf("round 2: too many dials (%s): %d", scheme, dialCnt)
+	doReq := func() {
+		trace := &httptrace.ClientTrace{
+			GotConn: func(connInfo httptrace.GotConnInfo) {
+				if !connInfo.Reused {
+					atomic.AddInt32(&gotConnCnt, 1)
+				}
+			},
+			TLSHandshakeStart: func() {
+				atomic.AddInt32(&tlsHandshakeCnt, 1)
+			},
 		}
-		if gotConnCnt != expected {
-			t.Errorf("round 2: too many get connections (%s): %d != %d", scheme, gotConnCnt, expected)
+		req, _ := NewRequest("GET", ts.URL, nil)
+		req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace))
+
+		resp, err := c.Do(req)
+		if err != nil {
+			t.Fatalf("request failed: %v", err)
 		}
-		if ts.TLS != nil && tlsHandshakeCnt != expected {
-			t.Errorf("round 2: too many tls handshakes (%s): %d != %d", scheme, tlsHandshakeCnt, expected)
+		defer resp.Body.Close()
+		_, err = io.ReadAll(resp.Body)
+		if err != nil {
+			t.Fatalf("read body failed: %v", err)
 		}
 	}
 
-	testMaxConns("http", httptest.NewServer(h))
-	testMaxConns("https", httptest.NewTLSServer(h))
+	wg := sync.WaitGroup{}
+	for i := 0; i < 10; i++ {
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+			doReq()
+		}()
+	}
+	wg.Wait()
 
-	ts := httptest.NewUnstartedServer(h)
-	ts.TLS = &tls.Config{NextProtos: []string{"h2"}}
-	ts.StartTLS()
-	testMaxConns("http2", ts)
+	expected := int32(tr.MaxConnsPerHost)
+	if dialCnt != expected {
+		t.Errorf("round 1: too many dials: %d != %d", dialCnt, expected)
+	}
+	if gotConnCnt != expected {
+		t.Errorf("round 1: too many get connections: %d != %d", gotConnCnt, expected)
+	}
+	if ts.TLS != nil && tlsHandshakeCnt != expected {
+		t.Errorf("round 1: too many tls handshakes: %d != %d", tlsHandshakeCnt, expected)
+	}
+
+	if t.Failed() {
+		t.FailNow()
+	}
+
+	mu.Lock()
+	for _, c := range conns {
+		c.Close()
+	}
+	conns = nil
+	mu.Unlock()
+	tr.CloseIdleConnections()
+
+	doReq()
+	expected++
+	if dialCnt != expected {
+		t.Errorf("round 2: too many dials: %d", dialCnt)
+	}
+	if gotConnCnt != expected {
+		t.Errorf("round 2: too many get connections: %d != %d", gotConnCnt, expected)
+	}
+	if ts.TLS != nil && tlsHandshakeCnt != expected {
+		t.Errorf("round 2: too many tls handshakes: %d != %d", tlsHandshakeCnt, expected)
+	}
 }
 
 func TestTransportRemovesDeadIdleConnections(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	run(t, testTransportRemovesDeadIdleConnections, []testMode{http1Mode})
+}
+func testTransportRemovesDeadIdleConnections(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		io.WriteString(w, r.RemoteAddr)
-	}))
-	defer ts.Close()
+	})).ts
 
 	c := ts.Client()
 	tr := c.Transport.(*Transport)
@@ -789,10 +779,10 @@
 // Test that the Transport notices when a server hangs up on its
 // unexpectedly (a keep-alive connection is closed).
 func TestTransportServerClosingUnexpectedly(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
-	ts := httptest.NewServer(hostPortHandler)
-	defer ts.Close()
+	run(t, testTransportServerClosingUnexpectedly, []testMode{http1Mode})
+}
+func testTransportServerClosingUnexpectedly(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, hostPortHandler).ts
 	c := ts.Client()
 
 	fetch := func(n, retries int) string {
@@ -846,11 +836,13 @@
 // Test for https://golang.org/issue/2616 (appropriate issue number)
 // This fails pretty reliably with GOMAXPROCS=100 or something high.
 func TestStressSurpriseServerCloses(t *testing.T) {
-	defer afterTest(t)
+	run(t, testStressSurpriseServerCloses, []testMode{http1Mode})
+}
+func testStressSurpriseServerCloses(t *testing.T, mode testMode) {
 	if testing.Short() {
 		t.Skip("skipping test in short mode")
 	}
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		w.Header().Set("Content-Length", "5")
 		w.Header().Set("Content-Type", "text/plain")
 		w.Write([]byte("Hello"))
@@ -858,8 +850,7 @@
 		conn, buf, _ := w.(Hijacker).Hijack()
 		buf.Flush()
 		conn.Close()
-	}))
-	defer ts.Close()
+	})).ts
 	c := ts.Client()
 
 	// Do a bunch of traffic from different goroutines. Send to activityc
@@ -906,16 +897,15 @@
 
 // TestTransportHeadResponses verifies that we deal with Content-Lengths
 // with no bodies properly
-func TestTransportHeadResponses(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestTransportHeadResponses(t *testing.T) { run(t, testTransportHeadResponses) }
+func testTransportHeadResponses(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		if r.Method != "HEAD" {
 			panic("expected HEAD; got " + r.Method)
 		}
 		w.Header().Set("Content-Length", "123")
 		w.WriteHeader(200)
-	}))
-	defer ts.Close()
+	})).ts
 	c := ts.Client()
 
 	for i := 0; i < 2; i++ {
@@ -941,16 +931,17 @@
 // TestTransportHeadChunkedResponse verifies that we ignore chunked transfer-encoding
 // on responses to HEAD requests.
 func TestTransportHeadChunkedResponse(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	run(t, testTransportHeadChunkedResponse, []testMode{http1Mode}, testNotParallel)
+}
+func testTransportHeadChunkedResponse(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		if r.Method != "HEAD" {
 			panic("expected HEAD; got " + r.Method)
 		}
 		w.Header().Set("Transfer-Encoding", "chunked") // client should ignore
 		w.Header().Set("x-client-ipport", r.RemoteAddr)
 		w.WriteHeader(200)
-	}))
-	defer ts.Close()
+	})).ts
 	c := ts.Client()
 
 	// Ensure that we wait for the readLoop to complete before
@@ -991,11 +982,10 @@
 }
 
 // Test that the modification made to the Request by the RoundTripper is cleaned up
-func TestRoundTripGzip(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
+func TestRoundTripGzip(t *testing.T) { run(t, testRoundTripGzip) }
+func testRoundTripGzip(t *testing.T, mode testMode) {
 	const responseBody = "test response body"
-	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(rw ResponseWriter, req *Request) {
 		accept := req.Header.Get("Accept-Encoding")
 		if expect := req.FormValue("expect_accept"); accept != expect {
 			t.Errorf("in handler, test %v: Accept-Encoding = %q, want %q",
@@ -1010,8 +1000,7 @@
 			rw.Header().Set("Content-Encoding", accept)
 			rw.Write([]byte(responseBody))
 		}
-	}))
-	defer ts.Close()
+	})).ts
 	tr := ts.Client().Transport.(*Transport)
 
 	for i, test := range roundTripTests {
@@ -1055,12 +1044,14 @@
 
 }
 
-func TestTransportGzip(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
+func TestTransportGzip(t *testing.T) { run(t, testTransportGzip) }
+func testTransportGzip(t *testing.T, mode testMode) {
+	if mode == http2Mode {
+		t.Skip("https://go.dev/issue/56020")
+	}
 	const testString = "The test string aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
 	const nRandBytes = 1024 * 1024
-	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(rw ResponseWriter, req *Request) {
 		if req.Method == "HEAD" {
 			if g := req.Header.Get("Accept-Encoding"); g != "" {
 				t.Errorf("HEAD request sent with Accept-Encoding of %q; want none", g)
@@ -1087,8 +1078,7 @@
 			io.CopyN(gz, rand.Reader, nRandBytes)
 		}
 		gz.Close()
-	}))
-	defer ts.Close()
+	})).ts
 	c := ts.Client()
 
 	for _, chunked := range []string{"1", "0"} {
@@ -1153,10 +1143,10 @@
 // If a request has Expect:100-continue header, the request blocks sending body until the first response.
 // Premature consumption of the request body should not be occurred.
 func TestTransportExpect100Continue(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
-
-	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
+	run(t, testTransportExpect100Continue, []testMode{http1Mode})
+}
+func testTransportExpect100Continue(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(rw ResponseWriter, req *Request) {
 		switch req.URL.Path {
 		case "/100":
 			// This endpoint implicitly responds 100 Continue and reads body.
@@ -1194,8 +1184,7 @@
 			conn.Close()
 		}
 
-	}))
-	defer ts.Close()
+	})).ts
 
 	tests := []struct {
 		path   string
@@ -1242,7 +1231,9 @@
 }
 
 func TestSOCKS5Proxy(t *testing.T) {
-	defer afterTest(t)
+	run(t, testSOCKS5Proxy, []testMode{http1Mode, https1Mode, http2Mode})
+}
+func testSOCKS5Proxy(t *testing.T, mode testMode) {
 	ch := make(chan string, 1)
 	l := newLocalListener(t)
 	defer l.Close()
@@ -1322,12 +1313,7 @@
 	})
 	for _, useTLS := range []bool{false, true} {
 		t.Run(fmt.Sprintf("useTLS=%v", useTLS), func(t *testing.T) {
-			var ts *httptest.Server
-			if useTLS {
-				ts = httptest.NewTLSServer(h)
-			} else {
-				ts = httptest.NewServer(h)
-			}
+			ts := newClientServerTest(t, mode, h).ts
 			go proxy(t)
 			c := ts.Client()
 			c.Transport.(*Transport).Proxy = ProxyURL(pu)
@@ -1359,16 +1345,16 @@
 
 func TestTransportProxy(t *testing.T) {
 	defer afterTest(t)
-	testCases := []struct{ httpsSite, httpsProxy bool }{
-		{false, false},
-		{false, true},
-		{true, false},
-		{true, true},
+	testCases := []struct{ siteMode, proxyMode testMode }{
+		{http1Mode, http1Mode},
+		{http1Mode, https1Mode},
+		{https1Mode, http1Mode},
+		{https1Mode, https1Mode},
 	}
 	for _, testCase := range testCases {
-		httpsSite := testCase.httpsSite
-		httpsProxy := testCase.httpsProxy
-		t.Run(fmt.Sprintf("httpsSite=%v, httpsProxy=%v", httpsSite, httpsProxy), func(t *testing.T) {
+		siteMode := testCase.siteMode
+		proxyMode := testCase.proxyMode
+		t.Run(fmt.Sprintf("site=%v/proxy=%v", siteMode, proxyMode), func(t *testing.T) {
 			siteCh := make(chan *Request, 1)
 			h1 := HandlerFunc(func(w ResponseWriter, r *Request) {
 				siteCh <- r
@@ -1414,18 +1400,8 @@
 					}()
 				}
 			})
-			var ts *httptest.Server
-			if httpsSite {
-				ts = httptest.NewTLSServer(h1)
-			} else {
-				ts = httptest.NewServer(h1)
-			}
-			var proxy *httptest.Server
-			if httpsProxy {
-				proxy = httptest.NewTLSServer(h2)
-			} else {
-				proxy = httptest.NewServer(h2)
-			}
+			ts := newClientServerTest(t, siteMode, h1).ts
+			proxy := newClientServerTest(t, proxyMode, h2).ts
 
 			pu, err := url.Parse(proxy.URL)
 			if err != nil {
@@ -1436,7 +1412,7 @@
 			// If only one server is HTTPS, c must be derived from that server in order
 			// to ensure that it is configured to use the fake root CA from testcert.go.
 			c := proxy.Client()
-			if httpsSite {
+			if siteMode == https1Mode {
 				c = ts.Client()
 			}
 
@@ -1453,7 +1429,7 @@
 			c.Transport.(*Transport).CloseIdleConnections()
 			ts.Close()
 			proxy.Close()
-			if httpsSite {
+			if siteMode == https1Mode {
 				// First message should be a CONNECT, asking for a socket to the real server,
 				if got.Method != "CONNECT" {
 					t.Errorf("Wrong method for secure proxying: %q", got.Method)
@@ -1489,6 +1465,98 @@
 	}
 }
 
+func TestOnProxyConnectResponse(t *testing.T) {
+
+	var tcases = []struct {
+		proxyStatusCode int
+		err             error
+	}{
+		{
+			StatusOK,
+			nil,
+		},
+		{
+			StatusForbidden,
+			errors.New("403"),
+		},
+	}
+	for _, tcase := range tcases {
+		h1 := HandlerFunc(func(w ResponseWriter, r *Request) {
+
+		})
+
+		h2 := HandlerFunc(func(w ResponseWriter, r *Request) {
+			// Implement an entire CONNECT proxy
+			if r.Method == "CONNECT" {
+				if tcase.proxyStatusCode != StatusOK {
+					w.WriteHeader(tcase.proxyStatusCode)
+					return
+				}
+				hijacker, ok := w.(Hijacker)
+				if !ok {
+					t.Errorf("hijack not allowed")
+					return
+				}
+				clientConn, _, err := hijacker.Hijack()
+				if err != nil {
+					t.Errorf("hijacking failed")
+					return
+				}
+				res := &Response{
+					StatusCode: StatusOK,
+					Proto:      "HTTP/1.1",
+					ProtoMajor: 1,
+					ProtoMinor: 1,
+					Header:     make(Header),
+				}
+
+				targetConn, err := net.Dial("tcp", r.URL.Host)
+				if err != nil {
+					t.Errorf("net.Dial(%q) failed: %v", r.URL.Host, err)
+					return
+				}
+
+				if err := res.Write(clientConn); err != nil {
+					t.Errorf("Writing 200 OK failed: %v", err)
+					return
+				}
+
+				go io.Copy(targetConn, clientConn)
+				go func() {
+					io.Copy(clientConn, targetConn)
+					targetConn.Close()
+				}()
+			}
+		})
+		ts := newClientServerTest(t, https1Mode, h1).ts
+		proxy := newClientServerTest(t, https1Mode, h2).ts
+
+		pu, err := url.Parse(proxy.URL)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		c := proxy.Client()
+
+		c.Transport.(*Transport).Proxy = ProxyURL(pu)
+		c.Transport.(*Transport).OnProxyConnectResponse = func(ctx context.Context, proxyURL *url.URL, connectReq *Request, connectRes *Response) error {
+			if proxyURL.String() != pu.String() {
+				t.Errorf("proxy url got %s, want %s", proxyURL, pu)
+			}
+
+			if "https://"+connectReq.URL.String() != ts.URL {
+				t.Errorf("connect url got %s, want %s", connectReq.URL, ts.URL)
+			}
+			return tcase.err
+		}
+		if _, err := c.Head(ts.URL); err != nil {
+			if tcase.err != nil && !strings.Contains(err.Error(), tcase.err.Error()) {
+				t.Errorf("got %v, want %v", err, tcase.err)
+			}
+		}
+	}
+}
+
 // Issue 28012: verify that the Transport closes its TCP connection to http proxies
 // when they're slow to reply to HTTPS CONNECT responses.
 func TestTransportProxyHTTPSConnectLeak(t *testing.T) {
@@ -1602,10 +1670,10 @@
 // (A bug caused dialConn to instead write the per-request Proxy-Authorization
 // header through to the shared Header instance, introducing a data race.)
 func TestTransportProxyDialDoesNotMutateProxyConnectHeader(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
-
-	proxy := httptest.NewTLSServer(NotFoundHandler())
+	run(t, testTransportProxyDialDoesNotMutateProxyConnectHeader)
+}
+func testTransportProxyDialDoesNotMutateProxyConnectHeader(t *testing.T, mode testMode) {
+	proxy := newClientServerTest(t, mode, NotFoundHandler()).ts
 	defer proxy.Close()
 	c := proxy.Client()
 
@@ -1639,13 +1707,12 @@
 // client gets the same value back. This is more cute than anything,
 // but checks that we don't recurse forever, and checks that
 // Content-Encoding is removed.
-func TestTransportGzipRecursive(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestTransportGzipRecursive(t *testing.T) { run(t, testTransportGzipRecursive) }
+func testTransportGzipRecursive(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		w.Header().Set("Content-Encoding", "gzip")
 		w.Write(rgz)
-	}))
-	defer ts.Close()
+	})).ts
 
 	c := ts.Client()
 	res, err := c.Get(ts.URL)
@@ -1667,13 +1734,12 @@
 
 // golang.org/issue/7750: request fails when server replies with
 // a short gzip body
-func TestTransportGzipShort(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestTransportGzipShort(t *testing.T) { run(t, testTransportGzipShort) }
+func testTransportGzipShort(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		w.Header().Set("Content-Encoding", "gzip")
 		w.Write([]byte{0x1f, 0x8b})
-	}))
-	defer ts.Close()
+	})).ts
 
 	c := ts.Client()
 	res, err := c.Get(ts.URL)
@@ -1703,19 +1769,23 @@
 
 // tests that persistent goroutine connections shut down when no longer desired.
 func TestTransportPersistConnLeak(t *testing.T) {
+	run(t, testTransportPersistConnLeak, testNotParallel)
+}
+func testTransportPersistConnLeak(t *testing.T, mode testMode) {
+	if mode == http2Mode {
+		t.Skip("flaky in HTTP/2")
+	}
 	// Not parallel: counts goroutines
-	defer afterTest(t)
 
 	const numReq = 25
 	gotReqCh := make(chan bool, numReq)
 	unblockCh := make(chan bool, numReq)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		gotReqCh <- true
 		<-unblockCh
 		w.Header().Set("Content-Length", "0")
 		w.WriteHeader(204)
-	}))
-	defer ts.Close()
+	})).ts
 	c := ts.Client()
 	tr := c.Transport.(*Transport)
 
@@ -1773,11 +1843,16 @@
 // golang.org/issue/4531: Transport leaks goroutines when
 // request.ContentLength is explicitly short
 func TestTransportPersistConnLeakShortBody(t *testing.T) {
+	run(t, testTransportPersistConnLeakShortBody, testNotParallel)
+}
+func testTransportPersistConnLeakShortBody(t *testing.T, mode testMode) {
+	if mode == http2Mode {
+		t.Skip("flaky in HTTP/2")
+	}
+
 	// Not parallel: measures goroutines.
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-	}))
-	defer ts.Close()
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
+	})).ts
 	c := ts.Client()
 	tr := c.Transport.(*Transport)
 
@@ -1851,9 +1926,10 @@
 }
 
 func TestTransportPersistConnLeakNeverIdle(t *testing.T) {
-	defer afterTest(t)
-
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	run(t, testTransportPersistConnLeakNeverIdle, []testMode{http1Mode})
+}
+func testTransportPersistConnLeakNeverIdle(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		// Close every connection so that it cannot be kept alive.
 		conn, _, err := w.(Hijacker).Hijack()
 		if err != nil {
@@ -1861,8 +1937,7 @@
 			return
 		}
 		conn.Close()
-	}))
-	defer ts.Close()
+	})).ts
 
 	var d countingDialer
 	c := ts.Client()
@@ -1923,13 +1998,17 @@
 }
 
 func TestTransportPersistConnContextLeakMaxConnsPerHost(t *testing.T) {
-	defer afterTest(t)
+	run(t, testTransportPersistConnContextLeakMaxConnsPerHost)
+}
+func testTransportPersistConnContextLeakMaxConnsPerHost(t *testing.T, mode testMode) {
+	if mode == http2Mode {
+		t.Skip("https://go.dev/issue/56021")
+	}
 
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		runtime.Gosched()
 		w.WriteHeader(StatusOK)
-	}))
-	defer ts.Close()
+	})).ts
 
 	c := ts.Client()
 	c.Transport.(*Transport).MaxConnsPerHost = 1
@@ -1979,16 +2058,15 @@
 }
 
 // This used to crash; https://golang.org/issue/3266
-func TestTransportIdleConnCrash(t *testing.T) {
-	defer afterTest(t)
+func TestTransportIdleConnCrash(t *testing.T) { run(t, testTransportIdleConnCrash) }
+func testTransportIdleConnCrash(t *testing.T, mode testMode) {
 	var tr *Transport
 
 	unblockCh := make(chan bool, 1)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		<-unblockCh
 		tr.CloseIdleConnections()
-	}))
-	defer ts.Close()
+	})).ts
 	c := ts.Client()
 	tr = c.Transport.(*Transport)
 
@@ -2010,16 +2088,15 @@
 // before the response body has been read. This was a regression
 // which sadly lacked a triggering test. The large response body made
 // the old race easier to trigger.
-func TestIssue3644(t *testing.T) {
-	defer afterTest(t)
+func TestIssue3644(t *testing.T) { run(t, testIssue3644) }
+func testIssue3644(t *testing.T, mode testMode) {
 	const numFoos = 5000
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		w.Header().Set("Connection", "close")
 		for i := 0; i < numFoos; i++ {
 			w.Write([]byte("foo "))
 		}
-	}))
-	defer ts.Close()
+	})).ts
 	c := ts.Client()
 	res, err := c.Get(ts.URL)
 	if err != nil {
@@ -2037,14 +2114,12 @@
 
 // Test that a client receives a server's reply, even if the server doesn't read
 // the entire request body.
-func TestIssue3595(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
+func TestIssue3595(t *testing.T) { run(t, testIssue3595) }
+func testIssue3595(t *testing.T, mode testMode) {
 	const deniedMsg = "sorry, denied."
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		Error(w, deniedMsg, StatusUnauthorized)
-	}))
-	defer ts.Close()
+	})).ts
 	c := ts.Client()
 	res, err := c.Post(ts.URL, "application/octet-stream", neverEnding('a'))
 	if err != nil {
@@ -2062,12 +2137,11 @@
 
 // From https://golang.org/issue/4454 ,
 // "client fails to handle requests with no body and chunked encoding"
-func TestChunkedNoContent(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestChunkedNoContent(t *testing.T) { run(t, testChunkedNoContent) }
+func testChunkedNoContent(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		w.WriteHeader(StatusNoContent)
-	}))
-	defer ts.Close()
+	})).ts
 
 	c := ts.Client()
 	for _, closeBody := range []bool{true, false} {
@@ -2086,17 +2160,18 @@
 }
 
 func TestTransportConcurrency(t *testing.T) {
+	run(t, testTransportConcurrency, testNotParallel, []testMode{http1Mode})
+}
+func testTransportConcurrency(t *testing.T, mode testMode) {
 	// Not parallel: uses global test hooks.
-	defer afterTest(t)
 	maxProcs, numReqs := 16, 500
 	if testing.Short() {
 		maxProcs, numReqs = 4, 50
 	}
 	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs))
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		fmt.Fprintf(w, "%v", r.FormValue("echo"))
-	}))
-	defer ts.Close()
+	})).ts
 
 	var wg sync.WaitGroup
 	wg.Add(numReqs)
@@ -2147,67 +2222,46 @@
 	wg.Wait()
 }
 
-func TestIssue4191_InfiniteGetTimeout(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
-	const debug = false
+func TestIssue4191_InfiniteGetTimeout(t *testing.T) { run(t, testIssue4191_InfiniteGetTimeout) }
+func testIssue4191_InfiniteGetTimeout(t *testing.T, mode testMode) {
 	mux := NewServeMux()
 	mux.HandleFunc("/get", func(w ResponseWriter, r *Request) {
 		io.Copy(w, neverEnding('a'))
 	})
-	ts := httptest.NewServer(mux)
-	defer ts.Close()
-	timeout := 100 * time.Millisecond
+	ts := newClientServerTest(t, mode, mux).ts
 
+	connc := make(chan net.Conn, 1)
 	c := ts.Client()
 	c.Transport.(*Transport).Dial = func(n, addr string) (net.Conn, error) {
 		conn, err := net.Dial(n, addr)
 		if err != nil {
 			return nil, err
 		}
-		conn.SetDeadline(time.Now().Add(timeout))
-		if debug {
-			conn = NewLoggingConn("client", conn)
+		select {
+		case connc <- conn:
+		default:
 		}
 		return conn, nil
 	}
 
-	getFailed := false
-	nRuns := 5
-	if testing.Short() {
-		nRuns = 1
+	res, err := c.Get(ts.URL + "/get")
+	if err != nil {
+		t.Fatalf("Error issuing GET: %v", err)
 	}
-	for i := 0; i < nRuns; i++ {
-		if debug {
-			println("run", i+1, "of", nRuns)
-		}
-		sres, err := c.Get(ts.URL + "/get")
-		if err != nil {
-			if !getFailed {
-				// Make the timeout longer, once.
-				getFailed = true
-				t.Logf("increasing timeout")
-				i--
-				timeout *= 10
-				continue
-			}
-			t.Errorf("Error issuing GET: %v", err)
-			break
-		}
-		_, err = io.Copy(io.Discard, sres.Body)
-		if err == nil {
-			t.Errorf("Unexpected successful copy")
-			break
-		}
-	}
-	if debug {
-		println("tests complete; waiting for handlers to finish")
+	defer res.Body.Close()
+
+	conn := <-connc
+	conn.SetDeadline(time.Now().Add(1 * time.Millisecond))
+	_, err = io.Copy(io.Discard, res.Body)
+	if err == nil {
+		t.Errorf("Unexpected successful copy")
 	}
 }
 
 func TestIssue4191_InfiniteGetToPutTimeout(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
+	run(t, testIssue4191_InfiniteGetToPutTimeout, []testMode{http1Mode})
+}
+func testIssue4191_InfiniteGetToPutTimeout(t *testing.T, mode testMode) {
 	const debug = false
 	mux := NewServeMux()
 	mux.HandleFunc("/get", func(w ResponseWriter, r *Request) {
@@ -2217,7 +2271,7 @@
 		defer r.Body.Close()
 		io.Copy(io.Discard, r.Body)
 	})
-	ts := httptest.NewServer(mux)
+	ts := newClientServerTest(t, mode, mux).ts
 	timeout := 100 * time.Millisecond
 
 	c := ts.Client()
@@ -2270,9 +2324,8 @@
 	ts.Close()
 }
 
-func TestTransportResponseHeaderTimeout(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
+func TestTransportResponseHeaderTimeout(t *testing.T) { run(t, testTransportResponseHeaderTimeout) }
+func testTransportResponseHeaderTimeout(t *testing.T, mode testMode) {
 	if testing.Short() {
 		t.Skip("skipping timeout test in -short mode")
 	}
@@ -2285,8 +2338,7 @@
 		inHandler <- true
 		time.Sleep(2 * time.Second)
 	})
-	ts := httptest.NewServer(mux)
-	defer ts.Close()
+	ts := newClientServerTest(t, mode, mux).ts
 
 	c := ts.Client()
 	c.Transport.(*Transport).ResponseHeaderTimeout = 500 * time.Millisecond
@@ -2342,18 +2394,18 @@
 }
 
 func TestTransportCancelRequest(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
+	run(t, testTransportCancelRequest, []testMode{http1Mode})
+}
+func testTransportCancelRequest(t *testing.T, mode testMode) {
 	if testing.Short() {
 		t.Skip("skipping test in -short mode")
 	}
 	unblockc := make(chan bool)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		fmt.Fprintf(w, "Hello")
 		w.(Flusher).Flush() // send headers and some body
 		<-unblockc
-	}))
-	defer ts.Close()
+	})).ts
 	defer close(unblockc)
 
 	c := ts.Client()
@@ -2395,17 +2447,14 @@
 	}
 }
 
-func testTransportCancelRequestInDo(t *testing.T, body io.Reader) {
-	setParallel(t)
-	defer afterTest(t)
+func testTransportCancelRequestInDo(t *testing.T, mode testMode, body io.Reader) {
 	if testing.Short() {
 		t.Skip("skipping test in -short mode")
 	}
 	unblockc := make(chan bool)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		<-unblockc
-	}))
-	defer ts.Close()
+	})).ts
 	defer close(unblockc)
 
 	c := ts.Client()
@@ -2432,11 +2481,15 @@
 }
 
 func TestTransportCancelRequestInDo(t *testing.T) {
-	testTransportCancelRequestInDo(t, nil)
+	run(t, func(t *testing.T, mode testMode) {
+		testTransportCancelRequestInDo(t, mode, nil)
+	}, []testMode{http1Mode})
 }
 
 func TestTransportCancelRequestWithBodyInDo(t *testing.T) {
-	testTransportCancelRequestInDo(t, bytes.NewBuffer([]byte{0}))
+	run(t, func(t *testing.T, mode testMode) {
+		testTransportCancelRequestInDo(t, mode, bytes.NewBuffer([]byte{0}))
+	}, []testMode{http1Mode})
 }
 
 func TestTransportCancelRequestInDial(t *testing.T) {
@@ -2444,7 +2497,7 @@
 	if testing.Short() {
 		t.Skip("skipping test in -short mode")
 	}
-	var logbuf bytes.Buffer
+	var logbuf strings.Builder
 	eventLog := log.New(&logbuf, "", 0)
 
 	unblockDial := make(chan bool)
@@ -2497,19 +2550,17 @@
 	}
 }
 
-func TestCancelRequestWithChannel(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
+func TestCancelRequestWithChannel(t *testing.T) { run(t, testCancelRequestWithChannel) }
+func testCancelRequestWithChannel(t *testing.T, mode testMode) {
 	if testing.Short() {
 		t.Skip("skipping test in -short mode")
 	}
 	unblockc := make(chan bool)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		fmt.Fprintf(w, "Hello")
 		w.(Flusher).Flush() // send headers and some body
 		<-unblockc
-	}))
-	defer ts.Close()
+	})).ts
 	defer close(unblockc)
 
 	c := ts.Client()
@@ -2555,19 +2606,20 @@
 }
 
 func TestCancelRequestWithChannelBeforeDo_Cancel(t *testing.T) {
-	testCancelRequestWithChannelBeforeDo(t, false)
+	run(t, func(t *testing.T, mode testMode) {
+		testCancelRequestWithChannelBeforeDo(t, mode, false)
+	})
 }
 func TestCancelRequestWithChannelBeforeDo_Context(t *testing.T) {
-	testCancelRequestWithChannelBeforeDo(t, true)
+	run(t, func(t *testing.T, mode testMode) {
+		testCancelRequestWithChannelBeforeDo(t, mode, true)
+	})
 }
-func testCancelRequestWithChannelBeforeDo(t *testing.T, withCtx bool) {
-	setParallel(t)
-	defer afterTest(t)
+func testCancelRequestWithChannelBeforeDo(t *testing.T, mode testMode, withCtx bool) {
 	unblockc := make(chan bool)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		<-unblockc
-	}))
-	defer ts.Close()
+	})).ts
 	defer close(unblockc)
 
 	c := ts.Client()
@@ -2642,11 +2694,11 @@
 // golang.org/issue/3672 -- Client can't close HTTP stream
 // Calling Close on a Response.Body used to just read until EOF.
 // Now it actually closes the TCP connection.
-func TestTransportCloseResponseBody(t *testing.T) {
-	defer afterTest(t)
+func TestTransportCloseResponseBody(t *testing.T) { run(t, testTransportCloseResponseBody) }
+func testTransportCloseResponseBody(t *testing.T, mode testMode) {
 	writeErr := make(chan error, 1)
 	msg := []byte("young\n")
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		for {
 			_, err := w.Write(msg)
 			if err != nil {
@@ -2655,8 +2707,7 @@
 			}
 			w.(Flusher).Flush()
 		}
-	}))
-	defer ts.Close()
+	})).ts
 
 	c := ts.Client()
 	tr := c.Transport.(*Transport)
@@ -2761,10 +2812,8 @@
 	}
 }
 
-func TestTransportSocketLateBinding(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
-
+func TestTransportSocketLateBinding(t *testing.T) { run(t, testTransportSocketLateBinding) }
+func testTransportSocketLateBinding(t *testing.T, mode testMode) {
 	mux := NewServeMux()
 	fooGate := make(chan bool, 1)
 	mux.HandleFunc("/foo", func(w ResponseWriter, r *Request) {
@@ -2775,8 +2824,7 @@
 	mux.HandleFunc("/bar", func(w ResponseWriter, r *Request) {
 		w.Header().Set("bar-ipport", r.RemoteAddr)
 	})
-	ts := httptest.NewServer(mux)
-	defer ts.Close()
+	ts := newClientServerTest(t, mode, mux).ts
 
 	dialGate := make(chan bool, 1)
 	c := ts.Client()
@@ -2920,18 +2968,18 @@
 // Issue 17739: the HTTP client must ignore any unknown 1xx
 // informational responses before the actual response.
 func TestTransportIgnore1xxResponses(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
-	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
+	run(t, testTransportIgnore1xxResponses, []testMode{http1Mode})
+}
+func testTransportIgnore1xxResponses(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		conn, buf, _ := w.(Hijacker).Hijack()
 		buf.Write([]byte("HTTP/1.1 123 OneTwoThree\r\nFoo: bar\r\n\r\nHTTP/1.1 200 OK\r\nBar: baz\r\nContent-Length: 5\r\n\r\nHello"))
 		buf.Flush()
 		conn.Close()
 	}))
-	defer cst.close()
 	cst.tr.DisableKeepAlives = true // prevent log spam; our test server is hanging up anyway
 
-	var got bytes.Buffer
+	var got strings.Builder
 
 	req, _ := NewRequest("GET", cst.ts.URL, nil)
 	req = req.WithContext(httptrace.WithClientTrace(context.Background(), &httptrace.ClientTrace{
@@ -2949,14 +2997,15 @@
 	res.Write(&got)
 	want := "1xx: code=123, header=map[Foo:[bar]]\nHTTP/1.1 200 OK\r\nContent-Length: 5\r\nBar: baz\r\n\r\nHello"
 	if got.String() != want {
-		t.Errorf(" got: %q\nwant: %q\n", got.Bytes(), want)
+		t.Errorf(" got: %q\nwant: %q\n", got.String(), want)
 	}
 }
 
 func TestTransportLimits1xxResponses(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
-	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
+	run(t, testTransportLimits1xxResponses, []testMode{http1Mode})
+}
+func testTransportLimits1xxResponses(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		conn, buf, _ := w.(Hijacker).Hijack()
 		for i := 0; i < 10; i++ {
 			buf.Write([]byte("HTTP/1.1 123 OneTwoThree\r\n\r\n"))
@@ -2965,7 +3014,6 @@
 		buf.Flush()
 		conn.Close()
 	}))
-	defer cst.close()
 	cst.tr.DisableKeepAlives = true // prevent log spam; our test server is hanging up anyway
 
 	res, err := cst.c.Get(cst.ts.URL)
@@ -2982,16 +3030,16 @@
 // Issue 26161: the HTTP client must treat 101 responses
 // as the final response.
 func TestTransportTreat101Terminal(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
-	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
+	run(t, testTransportTreat101Terminal, []testMode{http1Mode})
+}
+func testTransportTreat101Terminal(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		conn, buf, _ := w.(Hijacker).Hijack()
 		buf.Write([]byte("HTTP/1.1 101 Switching Protocols\r\n\r\n"))
 		buf.Write([]byte("HTTP/1.1 204 No Content\r\n\r\n"))
 		buf.Flush()
 		conn.Close()
 	}))
-	defer cst.close()
 	res, err := cst.c.Get(cst.ts.URL)
 	if err != nil {
 		t.Fatal(err)
@@ -3015,7 +3063,7 @@
 }
 
 func (t proxyFromEnvTest) String() string {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	space := func() {
 		if buf.Len() > 0 {
 			buf.WriteByte(' ')
@@ -3123,16 +3171,18 @@
 }
 
 func TestIdleConnChannelLeak(t *testing.T) {
+	run(t, testIdleConnChannelLeak, []testMode{http1Mode}, testNotParallel)
+}
+func testIdleConnChannelLeak(t *testing.T, mode testMode) {
 	// Not parallel: uses global test hooks.
 	var mu sync.Mutex
 	var n int
 
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		mu.Lock()
 		n++
 		mu.Unlock()
-	}))
-	defer ts.Close()
+	})).ts
 
 	const nReqs = 5
 	didRead := make(chan bool, nReqs)
@@ -3180,11 +3230,12 @@
 // body into a ReadCloser if it's a Closer, and that the Transport
 // then closes it.
 func TestTransportClosesRequestBody(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	run(t, testTransportClosesRequestBody, []testMode{http1Mode})
+}
+func testTransportClosesRequestBody(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		io.Copy(io.Discard, r.Body)
-	}))
-	defer ts.Close()
+	})).ts
 
 	c := ts.Client()
 
@@ -3261,10 +3312,11 @@
 
 // Trying to repro golang.org/issue/3514
 func TestTLSServerClosesConnection(t *testing.T) {
-	defer afterTest(t)
-
+	run(t, testTLSServerClosesConnection, []testMode{https1Mode})
+}
+func testTLSServerClosesConnection(t *testing.T, mode testMode) {
 	closedc := make(chan bool, 1)
-	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		if strings.Contains(r.URL.Path, "/keep-alive-then-die") {
 			conn, _, _ := w.(Hijacker).Hijack()
 			conn.Write([]byte("HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nfoo"))
@@ -3273,8 +3325,7 @@
 			return
 		}
 		fmt.Fprintf(w, "hello")
-	}))
-	defer ts.Close()
+	})).ts
 
 	c := ts.Client()
 	tr := c.Transport.(*Transport)
@@ -3345,8 +3396,9 @@
 // questionable state.
 // golang.org/issue/7569
 func TestTransportNoReuseAfterEarlyResponse(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
+	run(t, testTransportNoReuseAfterEarlyResponse, []testMode{http1Mode})
+}
+func testTransportNoReuseAfterEarlyResponse(t *testing.T, mode testMode) {
 	var sconn struct {
 		sync.Mutex
 		c net.Conn
@@ -3365,7 +3417,7 @@
 	}
 	defer closeConn()
 
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		if r.Method == "GET" {
 			io.WriteString(w, "bar")
 			return
@@ -3376,8 +3428,7 @@
 		sconn.Unlock()
 		conn.Write([]byte("HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nfoo")) // keep-alive
 		go io.Copy(io.Discard, conn)
-	}))
-	defer ts.Close()
+	})).ts
 	c := ts.Client()
 
 	const bodySize = 256 << 10
@@ -3410,9 +3461,9 @@
 
 // Tests that we don't leak Transport persistConn.readLoop goroutines
 // when a server hangs up immediately after saying it would keep-alive.
-func TestTransportIssue10457(t *testing.T) {
-	defer afterTest(t) // used to fail in goroutine leak check
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestTransportIssue10457(t *testing.T) { run(t, testTransportIssue10457, []testMode{http1Mode}) }
+func testTransportIssue10457(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		// Send a response with no body, keep-alive
 		// (implicit), and then lie and immediately close the
 		// connection. This forces the Transport's readLoop to
@@ -3421,8 +3472,7 @@
 		conn, _, _ := w.(Hijacker).Hijack()
 		conn.Write([]byte("HTTP/1.1 200 OK\r\nFoo: Bar\r\nContent-Length: 0\r\n\r\n")) // keep-alive
 		conn.Close()
-	}))
-	defer ts.Close()
+	})).ts
 	c := ts.Client()
 
 	res, err := c.Get(ts.URL)
@@ -3463,6 +3513,9 @@
 // This automatically prevents an infinite resend loop because we'll run out of
 // the cached keep-alive connections eventually.
 func TestRetryRequestsOnError(t *testing.T) {
+	run(t, testRetryRequestsOnError, testNotParallel, []testMode{http1Mode})
+}
+func testRetryRequestsOnError(t *testing.T, mode testMode) {
 	newRequest := func(method, urlStr string, body io.Reader) *Request {
 		req, err := NewRequest(method, urlStr, body)
 		if err != nil {
@@ -3533,11 +3586,9 @@
 
 	for _, tc := range testCases {
 		t.Run(tc.name, func(t *testing.T) {
-			defer afterTest(t)
-
 			var (
 				mu     sync.Mutex
-				logbuf bytes.Buffer
+				logbuf strings.Builder
 			)
 			logf := func(format string, args ...any) {
 				mu.Lock()
@@ -3546,11 +3597,10 @@
 				logbuf.WriteByte('\n')
 			}
 
-			ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+			ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 				logf("Handler")
 				w.Header().Set("X-Status", "ok")
-			}))
-			defer ts.Close()
+			})).ts
 
 			var writeNumAtomic int32
 			c := ts.Client()
@@ -3620,15 +3670,13 @@
 }
 
 // Issue 6981
-func TestTransportClosesBodyOnError(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
+func TestTransportClosesBodyOnError(t *testing.T) { run(t, testTransportClosesBodyOnError) }
+func testTransportClosesBodyOnError(t *testing.T, mode testMode) {
 	readBody := make(chan error, 1)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		_, err := io.ReadAll(r.Body)
 		readBody <- err
-	}))
-	defer ts.Close()
+	})).ts
 	c := ts.Client()
 	fakeErr := errors.New("fake error")
 	didClose := make(chan bool, 1)
@@ -3668,17 +3716,17 @@
 }
 
 func TestTransportDialTLS(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
+	run(t, testTransportDialTLS, []testMode{https1Mode, http2Mode})
+}
+func testTransportDialTLS(t *testing.T, mode testMode) {
 	var mu sync.Mutex // guards following
 	var gotReq, didDial bool
 
-	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		mu.Lock()
 		gotReq = true
 		mu.Unlock()
-	}))
-	defer ts.Close()
+	})).ts
 	c := ts.Client()
 	c.Transport.(*Transport).DialTLS = func(netw, addr string) (net.Conn, error) {
 		mu.Lock()
@@ -3705,19 +3753,17 @@
 	}
 }
 
-func TestTransportDialContext(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
+func TestTransportDialContext(t *testing.T) { run(t, testTransportDialContext) }
+func testTransportDialContext(t *testing.T, mode testMode) {
 	var mu sync.Mutex // guards following
 	var gotReq bool
 	var receivedContext context.Context
 
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		mu.Lock()
 		gotReq = true
 		mu.Unlock()
-	}))
-	defer ts.Close()
+	})).ts
 	c := ts.Client()
 	c.Transport.(*Transport).DialContext = func(ctx context.Context, netw, addr string) (net.Conn, error) {
 		mu.Lock()
@@ -3746,18 +3792,18 @@
 }
 
 func TestTransportDialTLSContext(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
+	run(t, testTransportDialTLSContext, []testMode{https1Mode, http2Mode})
+}
+func testTransportDialTLSContext(t *testing.T, mode testMode) {
 	var mu sync.Mutex // guards following
 	var gotReq bool
 	var receivedContext context.Context
 
-	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		mu.Lock()
 		gotReq = true
 		mu.Unlock()
-	}))
-	defer ts.Close()
+	})).ts
 	c := ts.Client()
 	c.Transport.(*Transport).DialTLSContext = func(ctx context.Context, netw, addr string) (net.Conn, error) {
 		mu.Lock()
@@ -3879,6 +3925,9 @@
 }
 
 func TestTransportRemovesH2ConnsAfterIdle(t *testing.T) {
+	run(t, testTransportRemovesH2ConnsAfterIdle, []testMode{http2Mode})
+}
+func testTransportRemovesH2ConnsAfterIdle(t *testing.T, mode testMode) {
 	if testing.Short() {
 		t.Skip("skipping in short mode")
 	}
@@ -3888,8 +3937,7 @@
 		tr.MaxIdleConnsPerHost = 1
 		tr.IdleConnTimeout = 10 * time.Millisecond
 	}
-	cst := newClientServerTest(t, h2Mode, HandlerFunc(func(w ResponseWriter, r *Request) {}), trFunc)
-	defer cst.close()
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {}), trFunc)
 
 	if _, err := cst.c.Get(cst.ts.URL); err != nil {
 		t.Fatalf("got error: %s", err)
@@ -3920,13 +3968,12 @@
 // implicitly ask for gzip support. If they want that, they need to do it
 // on their own.
 // golang.org/issue/8923
-func TestTransportRangeAndGzip(t *testing.T) {
-	defer afterTest(t)
+func TestTransportRangeAndGzip(t *testing.T) { run(t, testTransportRangeAndGzip) }
+func testTransportRangeAndGzip(t *testing.T, mode testMode) {
 	reqc := make(chan *Request, 1)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		reqc <- r
-	}))
-	defer ts.Close()
+	})).ts
 	c := ts.Client()
 
 	req, _ := NewRequest("GET", ts.URL, nil)
@@ -3951,15 +3998,13 @@
 }
 
 // Test for issue 10474
-func TestTransportResponseCancelRace(t *testing.T) {
-	defer afterTest(t)
-
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestTransportResponseCancelRace(t *testing.T) { run(t, testTransportResponseCancelRace) }
+func testTransportResponseCancelRace(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		// important that this response has a body.
 		var b [1024]byte
 		w.Write(b[:])
-	}))
-	defer ts.Close()
+	})).ts
 	tr := ts.Client().Transport.(*Transport)
 
 	req, err := NewRequest("GET", ts.URL, nil)
@@ -3991,19 +4036,19 @@
 
 // Test for issue 19248: Content-Encoding's value is case insensitive.
 func TestTransportContentEncodingCaseInsensitive(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
+	run(t, testTransportContentEncodingCaseInsensitive)
+}
+func testTransportContentEncodingCaseInsensitive(t *testing.T, mode testMode) {
 	for _, ce := range []string{"gzip", "GZIP"} {
 		ce := ce
 		t.Run(ce, func(t *testing.T) {
 			const encodedString = "Hello Gopher"
-			ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+			ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 				w.Header().Set("Content-Encoding", ce)
 				gz := gzip.NewWriter(w)
 				gz.Write([]byte(encodedString))
 				gz.Close()
-			}))
-			defer ts.Close()
+			})).ts
 
 			res, err := ts.Client().Get(ts.URL)
 			if err != nil {
@@ -4024,10 +4069,10 @@
 }
 
 func TestTransportDialCancelRace(t *testing.T) {
-	defer afterTest(t)
-
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
-	defer ts.Close()
+	run(t, testTransportDialCancelRace, testNotParallel, []testMode{http1Mode})
+}
+func testTransportDialCancelRace(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {})).ts
 	tr := ts.Client().Transport.(*Transport)
 
 	req, err := NewRequest("GET", ts.URL, nil)
@@ -4140,13 +4185,12 @@
 }
 
 // Issue 22088: flush Transport request headers if we're not sure the body won't block on read.
-func TestTransportFlushesRequestHeader(t *testing.T) {
-	defer afterTest(t)
+func TestTransportFlushesRequestHeader(t *testing.T) { run(t, testTransportFlushesRequestHeader) }
+func testTransportFlushesRequestHeader(t *testing.T, mode testMode) {
 	gotReq := make(chan struct{})
-	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		close(gotReq)
 	}))
-	defer cst.close()
 
 	pr, pw := io.Pipe()
 	req, err := NewRequest("POST", cst.ts.URL, pr)
@@ -4175,20 +4219,21 @@
 
 // Issue 11745.
 func TestTransportPrefersResponseOverWriteError(t *testing.T) {
+	run(t, testTransportPrefersResponseOverWriteError)
+}
+func testTransportPrefersResponseOverWriteError(t *testing.T, mode testMode) {
 	if testing.Short() {
 		t.Skip("skipping in short mode")
 	}
-	defer afterTest(t)
 	const contentLengthLimit = 1024 * 1024 // 1MB
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		if r.ContentLength >= contentLengthLimit {
 			w.WriteHeader(StatusBadRequest)
 			r.Body.Close()
 			return
 		}
 		w.WriteHeader(StatusOK)
-	}))
-	defer ts.Close()
+	})).ts
 	c := ts.Client()
 
 	fail := 0
@@ -4296,12 +4341,13 @@
 // Plus it's nice to be consistent and not have timing-dependent
 // behavior.
 func TestTransportReuseConnEmptyResponseBody(t *testing.T) {
-	defer afterTest(t)
-	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
+	run(t, testTransportReuseConnEmptyResponseBody)
+}
+func testTransportReuseConnEmptyResponseBody(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		w.Header().Set("X-Addr", r.RemoteAddr)
 		// Empty response body.
 	}))
-	defer cst.close()
 	n := 100
 	if testing.Short() {
 		n = 10
@@ -4406,31 +4452,43 @@
 }
 
 func TestTransportReuseConnection_Gzip_Chunked(t *testing.T) {
-	testTransportReuseConnection_Gzip(t, true)
+	run(t, func(t *testing.T, mode testMode) {
+		testTransportReuseConnection_Gzip(t, mode, true)
+	})
 }
 
 func TestTransportReuseConnection_Gzip_ContentLength(t *testing.T) {
-	testTransportReuseConnection_Gzip(t, false)
+	run(t, func(t *testing.T, mode testMode) {
+		testTransportReuseConnection_Gzip(t, mode, false)
+	})
 }
 
 // Make sure we re-use underlying TCP connection for gzipped responses too.
-func testTransportReuseConnection_Gzip(t *testing.T, chunked bool) {
-	setParallel(t)
-	defer afterTest(t)
+func testTransportReuseConnection_Gzip(t *testing.T, mode testMode, chunked bool) {
 	addr := make(chan string, 2)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		addr <- r.RemoteAddr
 		w.Header().Set("Content-Encoding", "gzip")
 		if chunked {
 			w.(Flusher).Flush()
 		}
 		w.Write(rgz) // arbitrary gzip response
-	}))
-	defer ts.Close()
+	})).ts
 	c := ts.Client()
 
+	trace := &httptrace.ClientTrace{
+		GetConn:      func(hostPort string) { t.Logf("GetConn(%q)", hostPort) },
+		GotConn:      func(ci httptrace.GotConnInfo) { t.Logf("GotConn(%+v)", ci) },
+		PutIdleConn:  func(err error) { t.Logf("PutIdleConn(%v)", err) },
+		ConnectStart: func(network, addr string) { t.Logf("ConnectStart(%q, %q)", network, addr) },
+		ConnectDone:  func(network, addr string, err error) { t.Logf("ConnectDone(%q, %q, %v)", network, addr, err) },
+	}
+	ctx := httptrace.WithClientTrace(context.Background(), trace)
+
 	for i := 0; i < 2; i++ {
-		res, err := c.Get(ts.URL)
+		req, _ := NewRequest("GET", ts.URL, nil)
+		req = req.WithContext(ctx)
+		res, err := c.Do(req)
 		if err != nil {
 			t.Fatal(err)
 		}
@@ -4448,15 +4506,16 @@
 	}
 }
 
-func TestTransportResponseHeaderLength(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestTransportResponseHeaderLength(t *testing.T) { run(t, testTransportResponseHeaderLength) }
+func testTransportResponseHeaderLength(t *testing.T, mode testMode) {
+	if mode == http2Mode {
+		t.Skip("HTTP/2 Transport doesn't support MaxResponseHeaderBytes")
+	}
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		if r.URL.Path == "/long" {
 			w.Header().Set("Long", strings.Repeat("a", 1<<20))
 		}
-	}))
-	defer ts.Close()
+	})).ts
 	c := ts.Client()
 	c.Transport.(*Transport).MaxResponseHeaderBytes = 512 << 10
 
@@ -4482,18 +4541,23 @@
 	}
 }
 
-func TestTransportEventTrace(t *testing.T)    { testTransportEventTrace(t, h1Mode, false) }
-func TestTransportEventTrace_h2(t *testing.T) { testTransportEventTrace(t, h2Mode, false) }
+func TestTransportEventTrace(t *testing.T) {
+	run(t, func(t *testing.T, mode testMode) {
+		testTransportEventTrace(t, mode, false)
+	}, testNotParallel)
+}
 
 // test a non-nil httptrace.ClientTrace but with all hooks set to zero.
-func TestTransportEventTrace_NoHooks(t *testing.T)    { testTransportEventTrace(t, h1Mode, true) }
-func TestTransportEventTrace_NoHooks_h2(t *testing.T) { testTransportEventTrace(t, h2Mode, true) }
+func TestTransportEventTrace_NoHooks(t *testing.T) {
+	run(t, func(t *testing.T, mode testMode) {
+		testTransportEventTrace(t, mode, true)
+	}, testNotParallel)
+}
 
-func testTransportEventTrace(t *testing.T, h2 bool, noHooks bool) {
-	defer afterTest(t)
+func testTransportEventTrace(t *testing.T, mode testMode, noHooks bool) {
 	const resBody = "some body"
 	gotWroteReqEvent := make(chan struct{}, 500)
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		if r.Method == "GET" {
 			// Do nothing for the second request.
 			return
@@ -4509,13 +4573,17 @@
 			}
 		}
 		io.WriteString(w, resBody)
-	}))
+	}), func(tr *Transport) {
+		if tr.TLSClientConfig != nil {
+			tr.TLSClientConfig.InsecureSkipVerify = true
+		}
+	})
 	defer cst.close()
 
 	cst.tr.ExpectContinueTimeout = 1 * time.Second
 
 	var mu sync.Mutex // guards buf
-	var buf bytes.Buffer
+	var buf strings.Builder
 	logf := func(format string, args ...any) {
 		mu.Lock()
 		defer mu.Unlock()
@@ -4568,7 +4636,7 @@
 			gotWroteReqEvent <- struct{}{}
 		},
 	}
-	if h2 {
+	if mode == http2Mode {
 		trace.TLSHandshakeStart = func() { logf("tls handshake start") }
 		trace.TLSHandshakeDone = func(s tls.ConnectionState, err error) {
 			logf("tls handshake done. ConnectionState = %v \n err = %v", s, err)
@@ -4625,7 +4693,7 @@
 	wantOnceOrMore("connected to tcp " + addrStr + " = <nil>")
 	wantOnce("Reused:false WasIdle:false IdleTime:0s")
 	wantOnce("first response byte")
-	if h2 {
+	if mode == http2Mode {
 		wantOnce("tls handshake start")
 		wantOnce("tls handshake done")
 	} else {
@@ -4673,8 +4741,11 @@
 }
 
 func TestTransportEventTraceTLSVerify(t *testing.T) {
+	run(t, testTransportEventTraceTLSVerify, []testMode{https1Mode, http2Mode})
+}
+func testTransportEventTraceTLSVerify(t *testing.T, mode testMode) {
 	var mu sync.Mutex
-	var buf bytes.Buffer
+	var buf strings.Builder
 	logf := func(format string, args ...any) {
 		mu.Lock()
 		defer mu.Unlock()
@@ -4682,14 +4753,14 @@
 		buf.WriteByte('\n')
 	}
 
-	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		t.Error("Unexpected request")
-	}))
-	defer ts.Close()
-	ts.Config.ErrorLog = log.New(funcWriter(func(p []byte) (int, error) {
-		logf("%s", p)
-		return len(p), nil
-	}), "", 0)
+	}), func(ts *httptest.Server) {
+		ts.Config.ErrorLog = log.New(funcWriter(func(p []byte) (int, error) {
+			logf("%s", p)
+			return len(p), nil
+		}), "", 0)
+	}).ts
 
 	certpool := x509.NewCertPool()
 	certpool.AddCert(ts.Certificate())
@@ -4727,7 +4798,7 @@
 
 	wantOnce("TLSHandshakeStart")
 	wantOnce("TLSHandshakeDone")
-	wantOnce("err = x509: certificate is valid for example.com")
+	wantOnce("err = tls: failed to verify certificate: x509: certificate is valid for example.com")
 
 	if t.Failed() {
 		t.Errorf("Output:\n%s", got)
@@ -4760,7 +4831,7 @@
 	c := &Client{Transport: tr}
 
 	var mu sync.Mutex // guards buf
-	var buf bytes.Buffer
+	var buf strings.Builder
 	logf := func(format string, args ...any) {
 		mu.Lock()
 		defer mu.Unlock()
@@ -4823,9 +4894,10 @@
 // Test the httptrace.TLSHandshake{Start,Done} hooks with a https http1
 // connections. The http2 test is done in TestTransportEventTrace_h2
 func TestTLSHandshakeTrace(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
-	defer ts.Close()
+	run(t, testTLSHandshakeTrace, []testMode{https1Mode, http2Mode})
+}
+func testTLSHandshakeTrace(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {})).ts
 
 	var mu sync.Mutex
 	var start, done bool
@@ -4868,11 +4940,12 @@
 }
 
 func TestTransportMaxIdleConns(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	run(t, testTransportMaxIdleConns, []testMode{http1Mode})
+}
+func testTransportMaxIdleConns(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		// No body for convenience.
-	}))
-	defer ts.Close()
+	})).ts
 	c := ts.Client()
 	tr := c.Transport.(*Transport)
 	tr.MaxIdleConns = 4
@@ -4920,27 +4993,24 @@
 	}
 }
 
-func TestTransportIdleConnTimeout_h1(t *testing.T) { testTransportIdleConnTimeout(t, h1Mode) }
-func TestTransportIdleConnTimeout_h2(t *testing.T) { testTransportIdleConnTimeout(t, h2Mode) }
-func testTransportIdleConnTimeout(t *testing.T, h2 bool) {
+func TestTransportIdleConnTimeout(t *testing.T) { run(t, testTransportIdleConnTimeout) }
+func testTransportIdleConnTimeout(t *testing.T, mode testMode) {
 	if testing.Short() {
 		t.Skip("skipping in short mode")
 	}
-	defer afterTest(t)
 
 	const timeout = 1 * time.Second
 
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		// No body for convenience.
 	}))
-	defer cst.close()
 	tr := cst.tr
 	tr.IdleConnTimeout = timeout
 	defer tr.CloseIdleConnections()
 	c := &Client{Transport: tr}
 
 	idleConns := func() []string {
-		if h2 {
+		if mode == http2Mode {
 			return tr.IdleConnStrsForTesting_h2()
 		} else {
 			return tr.IdleConnStrsForTesting()
@@ -4994,12 +5064,11 @@
 // real connection until after the RoundTrip saw the error.  Then we
 // know the successful tls.Dial from DialTLS will need to go into the
 // idle pool. Then we give it a of time to explode.
-func TestIdleConnH2Crash(t *testing.T) {
-	setParallel(t)
-	cst := newClientServerTest(t, h2Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestIdleConnH2Crash(t *testing.T) { run(t, testIdleConnH2Crash, []testMode{http2Mode}) }
+func testIdleConnH2Crash(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		// nothing
 	}))
-	defer cst.close()
 
 	ctx, cancel := context.WithCancel(context.Background())
 	defer cancel()
@@ -5090,21 +5159,18 @@
 }
 
 // Issue 13835: international domain names should work
-func TestTransportIDNA_h1(t *testing.T) { testTransportIDNA(t, h1Mode) }
-func TestTransportIDNA_h2(t *testing.T) { testTransportIDNA(t, h2Mode) }
-func testTransportIDNA(t *testing.T, h2 bool) {
-	defer afterTest(t)
-
+func TestTransportIDNA(t *testing.T) { run(t, testTransportIDNA) }
+func testTransportIDNA(t *testing.T, mode testMode) {
 	const uniDomain = "гофер.го"
 	const punyDomain = "xn--c1ae0ajs.xn--c1aw"
 
 	var port string
-	cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		want := punyDomain + ":" + port
 		if r.Host != want {
 			t.Errorf("Host header = %q; want %q", r.Host, want)
 		}
-		if h2 {
+		if mode == http2Mode {
 			if r.TLS == nil {
 				t.Errorf("r.TLS == nil")
 			} else if r.TLS.ServerName != punyDomain {
@@ -5112,8 +5178,11 @@
 			}
 		}
 		w.Header().Set("Hit-Handler", "1")
-	}))
-	defer cst.close()
+	}), func(tr *Transport) {
+		if tr.TLSClientConfig != nil {
+			tr.TLSClientConfig.InsecureSkipVerify = true
+		}
+	})
 
 	ip, port, err := net.SplitHostPort(cst.ts.Listener.Addr().String())
 	if err != nil {
@@ -5161,9 +5230,11 @@
 
 // Issue 13290: send User-Agent in proxy CONNECT
 func TestTransportProxyConnectHeader(t *testing.T) {
-	defer afterTest(t)
+	run(t, testTransportProxyConnectHeader, []testMode{http1Mode})
+}
+func testTransportProxyConnectHeader(t *testing.T, mode testMode) {
 	reqc := make(chan *Request, 1)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		if r.Method != "CONNECT" {
 			t.Errorf("method = %q; want CONNECT", r.Method)
 		}
@@ -5174,8 +5245,7 @@
 			return
 		}
 		c.Close()
-	}))
-	defer ts.Close()
+	})).ts
 
 	c := ts.Client()
 	c.Transport.(*Transport).Proxy = func(r *Request) (*url.URL, error) {
@@ -5205,9 +5275,11 @@
 }
 
 func TestTransportProxyGetConnectHeader(t *testing.T) {
-	defer afterTest(t)
+	run(t, testTransportProxyGetConnectHeader, []testMode{http1Mode})
+}
+func testTransportProxyGetConnectHeader(t *testing.T, mode testMode) {
 	reqc := make(chan *Request, 1)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		if r.Method != "CONNECT" {
 			t.Errorf("method = %q; want CONNECT", r.Method)
 		}
@@ -5218,8 +5290,7 @@
 			return
 		}
 		c.Close()
-	}))
-	defer ts.Close()
+	})).ts
 
 	c := ts.Client()
 	c.Transport.(*Transport).Proxy = func(r *Request) (*url.URL, error) {
@@ -5406,14 +5477,15 @@
 // Issue 22330: do not allow the response body to be read when the status code
 // forbids a response body.
 func TestNoBodyOnChunked304Response(t *testing.T) {
-	defer afterTest(t)
-	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
+	run(t, testNoBodyOnChunked304Response, []testMode{http1Mode})
+}
+func testNoBodyOnChunked304Response(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		conn, buf, _ := w.(Hijacker).Hijack()
 		buf.Write([]byte("HTTP/1.1 304 NOT MODIFIED\r\nTransfer-Encoding: chunked\r\n\r\n0\r\n\r\n"))
 		buf.Flush()
 		conn.Close()
 	}))
-	defer cst.close()
 
 	// Our test server above is sending back bogus data after the
 	// response (the "0\r\n\r\n" part), which causes the Transport
@@ -5466,11 +5538,12 @@
 // This is the test variant that times out before the server replies with
 // any response headers.
 func TestClientTimeoutKillsConn_BeforeHeaders(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
+	run(t, testClientTimeoutKillsConn_BeforeHeaders, []testMode{http1Mode})
+}
+func testClientTimeoutKillsConn_BeforeHeaders(t *testing.T, mode testMode) {
 	inHandler := make(chan net.Conn, 1)
 	handlerReadReturned := make(chan bool, 1)
-	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		conn, _, err := w.(Hijacker).Hijack()
 		if err != nil {
 			t.Error(err)
@@ -5483,7 +5556,6 @@
 		}
 		handlerReadReturned <- true
 	}))
-	defer cst.close()
 
 	const timeout = 50 * time.Millisecond
 	cst.c.Timeout = timeout
@@ -5518,11 +5590,12 @@
 // This is the test variant that has the server send response headers
 // first, and time out during the write of the response body.
 func TestClientTimeoutKillsConn_AfterHeaders(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
+	run(t, testClientTimeoutKillsConn_AfterHeaders, []testMode{http1Mode})
+}
+func testClientTimeoutKillsConn_AfterHeaders(t *testing.T, mode testMode) {
 	inHandler := make(chan net.Conn, 1)
 	handlerResult := make(chan error, 1)
-	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		w.Header().Set("Content-Length", "100")
 		w.(Flusher).Flush()
 		conn, _, err := w.(Hijacker).Hijack()
@@ -5544,7 +5617,6 @@
 		}
 		handlerResult <- nil
 	}))
-	defer cst.close()
 
 	// Set Timeout to something very long but non-zero to exercise
 	// the codepaths that check for it. But rather than wait for it to fire
@@ -5590,11 +5662,12 @@
 }
 
 func TestTransportResponseBodyWritableOnProtocolSwitch(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
+	run(t, testTransportResponseBodyWritableOnProtocolSwitch, []testMode{http1Mode})
+}
+func testTransportResponseBodyWritableOnProtocolSwitch(t *testing.T, mode testMode) {
 	done := make(chan struct{})
 	defer close(done)
-	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		conn, _, err := w.(Hijacker).Hijack()
 		if err != nil {
 			t.Error(err)
@@ -5607,7 +5680,6 @@
 		fmt.Fprintf(conn, "%s\n", strings.ToUpper(bs.Text()))
 		<-done
 	}))
-	defer cst.close()
 
 	req, _ := NewRequest("GET", cst.ts.URL, nil)
 	req.Header.Set("Upgrade", "foo")
@@ -5640,10 +5712,10 @@
 	}
 }
 
-func TestTransportCONNECTBidi(t *testing.T) {
-	defer afterTest(t)
+func TestTransportCONNECTBidi(t *testing.T) { run(t, testTransportCONNECTBidi, []testMode{http1Mode}) }
+func testTransportCONNECTBidi(t *testing.T, mode testMode) {
 	const target = "backend:443"
-	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		if r.Method != "CONNECT" {
 			t.Errorf("unexpected method %q", r.Method)
 			w.WriteHeader(500)
@@ -5674,7 +5746,6 @@
 			brw.Flush()
 		}
 	}))
-	defer cst.close()
 	pr, pw := io.Pipe()
 	defer pw.Close()
 	req, err := NewRequest("CONNECT", cst.ts.URL, pr)
@@ -5771,7 +5842,8 @@
 	return c.TCPConn.ReadFrom(r)
 }
 
-func TestTransportRequestWriteRoundTrip(t *testing.T) {
+func TestTransportRequestWriteRoundTrip(t *testing.T) { run(t, testTransportRequestWriteRoundTrip) }
+func testTransportRequestWriteRoundTrip(t *testing.T, mode testMode) {
 	nBytes := int64(1 << 10)
 	newFileFunc := func() (r io.Reader, done func(), err error) {
 		f, err := os.CreateTemp("", "net-http-newfilefunc")
@@ -5865,7 +5937,7 @@
 
 			cst := newClientServerTest(
 				t,
-				h1Mode,
+				mode,
 				HandlerFunc(func(w ResponseWriter, r *Request) {
 					io.Copy(io.Discard, r.Body)
 					r.Body.Close()
@@ -5873,7 +5945,6 @@
 				}),
 				trFunc,
 			)
-			defer cst.close()
 
 			req, err := NewRequest("PUT", cst.ts.URL, r)
 			if err != nil {
@@ -5890,11 +5961,15 @@
 				t.Fatalf("status code = %d; want 200", resp.StatusCode)
 			}
 
-			if !tConn.ReadFromCalled && tc.expectedReadFrom {
+			expectedReadFrom := tc.expectedReadFrom
+			if mode != http1Mode {
+				expectedReadFrom = false
+			}
+			if !tConn.ReadFromCalled && expectedReadFrom {
 				t.Fatalf("did not call ReadFrom")
 			}
 
-			if tConn.ReadFromCalled && !tc.expectedReadFrom {
+			if tConn.ReadFromCalled && !expectedReadFrom {
 				t.Fatalf("ReadFrom was unexpectedly invoked")
 			}
 		})
@@ -5903,7 +5978,10 @@
 
 func TestTransportClone(t *testing.T) {
 	tr := &Transport{
-		Proxy:                  func(*Request) (*url.URL, error) { panic("") },
+		Proxy: func(*Request) (*url.URL, error) { panic("") },
+		OnProxyConnectResponse: func(ctx context.Context, proxyURL *url.URL, connectReq *Request, connectRes *Response) error {
+			return nil
+		},
 		DialContext:            func(ctx context.Context, network, addr string) (net.Conn, error) { panic("") },
 		Dial:                   func(network, addr string) (net.Conn, error) { panic("") },
 		DialTLS:                func(network, addr string) (net.Conn, error) { panic("") },
@@ -5975,16 +6053,18 @@
 }
 
 func TestTransportIgnores408(t *testing.T) {
+	run(t, testTransportIgnores408, []testMode{http1Mode}, testNotParallel)
+}
+func testTransportIgnores408(t *testing.T, mode testMode) {
 	// Not parallel. Relies on mutating the log package's global Output.
 	defer log.SetOutput(log.Writer())
 
-	var logout bytes.Buffer
+	var logout strings.Builder
 	log.SetOutput(&logout)
 
-	defer afterTest(t)
 	const target = "backend:443"
 
-	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		nc, _, err := w.(Hijacker).Hijack()
 		if err != nil {
 			t.Error(err)
@@ -5994,7 +6074,6 @@
 		nc.Write([]byte("HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nok"))
 		nc.Write([]byte("HTTP/1.1 408 bye\r\n")) // changing 408 to 409 makes test fail
 	}))
-	defer cst.close()
 	req, err := NewRequest("GET", cst.ts.URL, nil)
 	if err != nil {
 		t.Fatal(err)
@@ -6028,9 +6107,10 @@
 }
 
 func TestInvalidHeaderResponse(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
-	cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) {
+	run(t, testInvalidHeaderResponse, []testMode{http1Mode})
+}
+func testInvalidHeaderResponse(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		conn, buf, _ := w.(Hijacker).Hijack()
 		buf.Write([]byte("HTTP/1.1 200 OK\r\n" +
 			"Date: Wed, 30 Aug 2017 19:09:27 GMT\r\n" +
@@ -6040,7 +6120,6 @@
 		buf.Flush()
 		conn.Close()
 	}))
-	defer cst.close()
 	res, err := cst.c.Get(cst.ts.URL)
 	if err != nil {
 		t.Fatal(err)
@@ -6067,10 +6146,12 @@
 // Issue 35015: ensure that Transport closes the body on any error
 // with an invalid request, as promised by Client.Do docs.
 func TestTransportClosesBodyOnInvalidRequests(t *testing.T) {
-	cst := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	run(t, testTransportClosesBodyOnInvalidRequests)
+}
+func testTransportClosesBodyOnInvalidRequests(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		t.Errorf("Should not have been invoked")
-	}))
-	defer cst.Close()
+	})).ts
 
 	u, _ := url.Parse(cst.URL)
 
@@ -6135,7 +6216,7 @@
 			var bc bodyCloser
 			req := tt.req
 			req.Body = &bc
-			_, err := DefaultClient.Do(tt.req)
+			_, err := cst.Client().Do(tt.req)
 			if err == nil {
 				t.Fatal("Expected an error")
 			}
@@ -6172,8 +6253,10 @@
 
 // Issue 34978: don't cache a broken HTTP/2 connection
 func TestDontCacheBrokenHTTP2Conn(t *testing.T) {
-	cst := newClientServerTest(t, h2Mode, HandlerFunc(func(w ResponseWriter, r *Request) {}), optQuietLog)
-	defer cst.close()
+	run(t, testDontCacheBrokenHTTP2Conn, []testMode{http2Mode})
+}
+func testDontCacheBrokenHTTP2Conn(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {}), optQuietLog)
 
 	var brokenState brokenState
 
@@ -6235,7 +6318,9 @@
 // http.http2noCachedConnError is reported on multiple requests. There should
 // only be one decrement regardless of the number of failures.
 func TestTransportDecrementConnWhenIdleConnRemoved(t *testing.T) {
-	defer afterTest(t)
+	run(t, testTransportDecrementConnWhenIdleConnRemoved, []testMode{http2Mode})
+}
+func testTransportDecrementConnWhenIdleConnRemoved(t *testing.T, mode testMode) {
 	CondSkipHTTP2(t)
 
 	h := HandlerFunc(func(w ResponseWriter, r *Request) {
@@ -6245,17 +6330,11 @@
 		}
 	})
 
-	ts := httptest.NewUnstartedServer(h)
-	ts.EnableHTTP2 = true
-	ts.StartTLS()
-	defer ts.Close()
+	ts := newClientServerTest(t, mode, h).ts
 
 	c := ts.Client()
 	tr := c.Transport.(*Transport)
 	tr.MaxConnsPerHost = 1
-	if err := ExportHttp2ConfigureTransport(tr); err != nil {
-		t.Fatalf("ExportHttp2ConfigureTransport: %v", err)
-	}
 
 	errCh := make(chan error, 300)
 	doReq := func() {
@@ -6324,14 +6403,13 @@
 func (f roundTripFunc) RoundTrip(r *Request) (*Response, error) { return f(r) }
 
 // Issue 32441: body is not reset after ErrSkipAltProtocol
-func TestIssue32441(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+func TestIssue32441(t *testing.T) { run(t, testIssue32441, []testMode{http1Mode}) }
+func testIssue32441(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		if n, _ := io.Copy(io.Discard, r.Body); n == 0 {
 			t.Error("body length is zero")
 		}
-	}))
-	defer ts.Close()
+	})).ts
 	c := ts.Client()
 	c.Transport.(*Transport).RegisterProtocol("http", roundTripFunc(func(r *Request) (*Response, error) {
 		// Draining body to trigger failure condition on actual request to server.
@@ -6348,11 +6426,13 @@
 // Issue 39017. Ensure that HTTP/1 transports reject Content-Length headers
 // that contain a sign (eg. "+3"), per RFC 2616, Section 14.13.
 func TestTransportRejectsSignInContentLength(t *testing.T) {
-	cst := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	run(t, testTransportRejectsSignInContentLength, []testMode{http1Mode})
+}
+func testTransportRejectsSignInContentLength(t *testing.T, mode testMode) {
+	cst := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, r *Request) {
 		w.Header().Set("Content-Length", "+3")
 		w.Write([]byte("abc"))
-	}))
-	defer cst.Close()
+	})).ts
 
 	c := cst.Client()
 	res, err := c.Get(cst.URL)
@@ -6466,14 +6546,16 @@
 // Test that a new request which uses the connection of an active request
 // cannot cause it to be canceled as well.
 func TestCancelRequestWhenSharingConnection(t *testing.T) {
+	run(t, testCancelRequestWhenSharingConnection, []testMode{http1Mode})
+}
+func testCancelRequestWhenSharingConnection(t *testing.T, mode testMode) {
 	reqc := make(chan chan struct{}, 2)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, req *Request) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(w ResponseWriter, req *Request) {
 		ch := make(chan struct{}, 1)
 		reqc <- ch
 		<-ch
 		w.Header().Add("Content-Length", "0")
-	}))
-	defer ts.Close()
+	})).ts
 
 	client := ts.Client()
 	transport := client.Transport.(*Transport)
@@ -6483,7 +6565,8 @@
 	var wg sync.WaitGroup
 
 	wg.Add(1)
-	putidlec := make(chan chan struct{})
+	putidlec := make(chan chan struct{}, 1)
+	reqerrc := make(chan error, 1)
 	go func() {
 		defer wg.Done()
 		ctx := httptrace.WithClientTrace(context.Background(), &httptrace.ClientTrace{
@@ -6492,24 +6575,31 @@
 				// and wait for the order to proceed.
 				ch := make(chan struct{})
 				putidlec <- ch
+				close(putidlec) // panic if PutIdleConn runs twice for some reason
 				<-ch
 			},
 		})
 		req, _ := NewRequestWithContext(ctx, "GET", ts.URL, nil)
 		res, err := client.Do(req)
+		reqerrc <- err
 		if err == nil {
 			res.Body.Close()
 		}
-		if err != nil {
-			t.Errorf("request 1: got err %v, want nil", err)
-		}
 	}()
 
 	// Wait for the first request to receive a response and return the
 	// connection to the idle pool.
 	r1c := <-reqc
 	close(r1c)
-	idlec := <-putidlec
+	var idlec chan struct{}
+	select {
+	case err := <-reqerrc:
+		if err != nil {
+			t.Fatalf("request 1: got err %v, want nil", err)
+		}
+		idlec = <-putidlec
+	case idlec = <-putidlec:
+	}
 
 	wg.Add(1)
 	cancelctx, cancel := context.WithCancel(context.Background())
@@ -6523,6 +6613,9 @@
 		if !errors.Is(err, context.Canceled) {
 			t.Errorf("request 2: got err %v, want Canceled", err)
 		}
+
+		// Unblock the first request.
+		close(idlec)
 	}()
 
 	// Wait for the second request to arrive at the server, and then cancel
@@ -6530,23 +6623,18 @@
 	r2c := <-reqc
 	cancel()
 
-	// Give the cancellation a moment to take effect, and then unblock the first request.
-	time.Sleep(1 * time.Millisecond)
-	close(idlec)
+	<-idlec
 
 	close(r2c)
 	wg.Wait()
 }
 
-func TestHandlerAbortRacesBodyRead(t *testing.T) {
-	setParallel(t)
-	defer afterTest(t)
-
-	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
+func TestHandlerAbortRacesBodyRead(t *testing.T) { run(t, testHandlerAbortRacesBodyRead) }
+func testHandlerAbortRacesBodyRead(t *testing.T, mode testMode) {
+	ts := newClientServerTest(t, mode, HandlerFunc(func(rw ResponseWriter, req *Request) {
 		go io.Copy(io.Discard, req.Body)
 		panic(ErrAbortHandler)
-	}))
-	defer ts.Close()
+	})).ts
 
 	var wg sync.WaitGroup
 	for i := 0; i < 2; i++ {
diff --git a/src/net/http/triv.go b/src/net/http/triv.go
index 11b19ab..32edbbb 100644
--- a/src/net/http/triv.go
+++ b/src/net/http/triv.go
@@ -7,7 +7,6 @@
 package main
 
 import (
-	"bytes"
 	"expvar"
 	"flag"
 	"fmt"
@@ -17,6 +16,7 @@
 	"os"
 	"os/exec"
 	"strconv"
+	"strings"
 	"sync"
 )
 
@@ -49,8 +49,8 @@
 	case "GET":
 		ctr.n++
 	case "POST":
-		buf := new(bytes.Buffer)
-		io.Copy(buf, req.Body)
+		var buf strings.Builder
+		io.Copy(&buf, req.Body)
 		body := buf.String()
 		if n, err := strconv.Atoi(body); err != nil {
 			fmt.Fprintf(w, "bad POST: %v\nbody: [%v]\n", err, body)
@@ -101,7 +101,7 @@
 	io.WriteString(w, fmt.Sprintf("channel send #%d\n", <-ch))
 }
 
-// exec a program, redirecting output
+// exec a program, redirecting output.
 func DateServer(rw http.ResponseWriter, req *http.Request) {
 	rw.Header().Set("Content-Type", "text/plain; charset=utf-8")
 
@@ -118,7 +118,7 @@
 	http.Error(w, "oops", http.StatusNotFound)
 }
 
-var webroot = flag.String("root", os.Getenv("HOME"), "web root directory")
+var webroot = flag.String("root", "", "web root directory")
 
 func main() {
 	flag.Parse()
@@ -128,11 +128,13 @@
 	expvar.Publish("counter", ctr)
 	http.Handle("/counter", ctr)
 	http.Handle("/", http.HandlerFunc(Logger))
-	http.Handle("/go/", http.StripPrefix("/go/", http.FileServer(http.Dir(*webroot))))
+	if *webroot != "" {
+		http.Handle("/go/", http.StripPrefix("/go/", http.FileServer(http.Dir(*webroot))))
+	}
 	http.Handle("/chan", ChanCreate())
 	http.HandleFunc("/flags", FlagServer)
 	http.HandleFunc("/args", ArgServer)
 	http.HandleFunc("/go/hello", HelloServer)
 	http.HandleFunc("/date", DateServer)
-	log.Fatal(http.ListenAndServe(":12345", nil))
+	log.Fatal(http.ListenAndServe("localhost:12345", nil))
 }
diff --git a/src/net/interface.go b/src/net/interface.go
index 0e5d320..e1c9a2e 100644
--- a/src/net/interface.go
+++ b/src/net/interface.go
@@ -39,11 +39,12 @@
 type Flags uint
 
 const (
-	FlagUp           Flags = 1 << iota // interface is up
+	FlagUp           Flags = 1 << iota // interface is administratively up
 	FlagBroadcast                      // interface supports broadcast access capability
 	FlagLoopback                       // interface is a loopback interface
 	FlagPointToPoint                   // interface belongs to a point-to-point link
 	FlagMulticast                      // interface supports multicast access capability
+	FlagRunning                        // interface is in running state
 )
 
 var flagNames = []string{
@@ -52,6 +53,7 @@
 	"loopback",
 	"pointtopoint",
 	"multicast",
+	"running",
 }
 
 func (f Flags) String() string {
diff --git a/src/net/interface_aix.go b/src/net/interface_aix.go
index 7ad45d1..f2e967b 100644
--- a/src/net/interface_aix.go
+++ b/src/net/interface_aix.go
@@ -101,6 +101,9 @@
 	if rawFlags&syscall.IFF_UP != 0 {
 		f |= FlagUp
 	}
+	if rawFlags&syscall.IFF_RUNNING != 0 {
+		f |= FlagRunning
+	}
 	if rawFlags&syscall.IFF_BROADCAST != 0 {
 		f |= FlagBroadcast
 	}
diff --git a/src/net/interface_bsd.go b/src/net/interface_bsd.go
index db7bc75..9b2b42a 100644
--- a/src/net/interface_bsd.go
+++ b/src/net/interface_bsd.go
@@ -59,6 +59,9 @@
 	if rawFlags&syscall.IFF_UP != 0 {
 		f |= FlagUp
 	}
+	if rawFlags&syscall.IFF_RUNNING != 0 {
+		f |= FlagRunning
+	}
 	if rawFlags&syscall.IFF_BROADCAST != 0 {
 		f |= FlagBroadcast
 	}
diff --git a/src/net/interface_linux.go b/src/net/interface_linux.go
index 441ab2f..9112ecc 100644
--- a/src/net/interface_linux.go
+++ b/src/net/interface_linux.go
@@ -99,6 +99,9 @@
 	if rawFlags&syscall.IFF_UP != 0 {
 		f |= FlagUp
 	}
+	if rawFlags&syscall.IFF_RUNNING != 0 {
+		f |= FlagRunning
+	}
 	if rawFlags&syscall.IFF_BROADCAST != 0 {
 		f |= FlagBroadcast
 	}
diff --git a/src/net/interface_plan9.go b/src/net/interface_plan9.go
index 957975c..92b2eed 100644
--- a/src/net/interface_plan9.go
+++ b/src/net/interface_plan9.go
@@ -95,9 +95,9 @@
 			}
 		}
 
-		ifc.Flags = FlagUp | FlagBroadcast | FlagMulticast
+		ifc.Flags = FlagUp | FlagRunning | FlagBroadcast | FlagMulticast
 	} else {
-		ifc.Flags = FlagUp | FlagMulticast | FlagLoopback
+		ifc.Flags = FlagUp | FlagRunning | FlagMulticast | FlagLoopback
 	}
 
 	return ifc, nil
diff --git a/src/net/interface_solaris.go b/src/net/interface_solaris.go
index f8d1571..32f503f 100644
--- a/src/net/interface_solaris.go
+++ b/src/net/interface_solaris.go
@@ -37,6 +37,9 @@
 	if rawFlags&syscall.IFF_UP != 0 {
 		f |= FlagUp
 	}
+	if rawFlags&syscall.IFF_RUNNING != 0 {
+		f |= FlagRunning
+	}
 	if rawFlags&syscall.IFF_BROADCAST != 0 {
 		f |= FlagBroadcast
 	}
diff --git a/src/net/interface_windows.go b/src/net/interface_windows.go
index 30e90b8..22a1312 100644
--- a/src/net/interface_windows.go
+++ b/src/net/interface_windows.go
@@ -62,6 +62,7 @@
 			}
 			if aa.OperStatus == windows.IfOperStatusUp {
 				ifi.Flags |= FlagUp
+				ifi.Flags |= FlagRunning
 			}
 			// For now we need to infer link-layer service
 			// capabilities from media types.
diff --git a/src/net/ip.go b/src/net/ip.go
index 54c5288..d9f3da7 100644
--- a/src/net/ip.go
+++ b/src/net/ip.go
@@ -757,3 +757,9 @@
 	m := CIDRMask(n, 8*iplen)
 	return ip, &IPNet{IP: ip.Mask(m), Mask: m}, nil
 }
+
+func copyIP(x IP) IP {
+	y := make(IP, len(x))
+	copy(y, x)
+	return y
+}
diff --git a/src/net/iprawsock_posix.go b/src/net/iprawsock_posix.go
index 64112b0..7b4d239 100644
--- a/src/net/iprawsock_posix.go
+++ b/src/net/iprawsock_posix.go
@@ -122,7 +122,13 @@
 	default:
 		return nil, UnknownNetworkError(sd.network)
 	}
-	fd, err := internetSocket(ctx, network, laddr, raddr, syscall.SOCK_RAW, proto, "dial", sd.Dialer.Control)
+	ctrlCtxFn := sd.Dialer.ControlContext
+	if ctrlCtxFn == nil && sd.Dialer.Control != nil {
+		ctrlCtxFn = func(cxt context.Context, network, address string, c syscall.RawConn) error {
+			return sd.Dialer.Control(network, address, c)
+		}
+	}
+	fd, err := internetSocket(ctx, network, laddr, raddr, syscall.SOCK_RAW, proto, "dial", ctrlCtxFn)
 	if err != nil {
 		return nil, err
 	}
@@ -139,7 +145,13 @@
 	default:
 		return nil, UnknownNetworkError(sl.network)
 	}
-	fd, err := internetSocket(ctx, network, laddr, nil, syscall.SOCK_RAW, proto, "listen", sl.ListenConfig.Control)
+	var ctrlCtxFn func(cxt context.Context, network, address string, c syscall.RawConn) error
+	if sl.ListenConfig.Control != nil {
+		ctrlCtxFn = func(cxt context.Context, network, address string, c syscall.RawConn) error {
+			return sl.ListenConfig.Control(network, address, c)
+		}
+	}
+	fd, err := internetSocket(ctx, network, laddr, nil, syscall.SOCK_RAW, proto, "listen", ctrlCtxFn)
 	if err != nil {
 		return nil, err
 	}
diff --git a/src/net/ipsock_posix.go b/src/net/ipsock_posix.go
index 7bb66f2..7fd676b 100644
--- a/src/net/ipsock_posix.go
+++ b/src/net/ipsock_posix.go
@@ -134,12 +134,12 @@
 	return syscall.AF_INET6, false
 }
 
-func internetSocket(ctx context.Context, net string, laddr, raddr sockaddr, sotype, proto int, mode string, ctrlFn func(string, string, syscall.RawConn) error) (fd *netFD, err error) {
+func internetSocket(ctx context.Context, net string, laddr, raddr sockaddr, sotype, proto int, mode string, ctrlCtxFn func(context.Context, string, string, syscall.RawConn) error) (fd *netFD, err error) {
 	if (runtime.GOOS == "aix" || runtime.GOOS == "windows" || runtime.GOOS == "openbsd") && mode == "dial" && raddr.isWildcard() {
 		raddr = raddr.toLocal(net)
 	}
 	family, ipv6only := favoriteAddrFamily(net, laddr, raddr, mode)
-	return socket(ctx, net, family, sotype, proto, ipv6only, laddr, raddr, ctrlFn)
+	return socket(ctx, net, family, sotype, proto, ipv6only, laddr, raddr, ctrlCtxFn)
 }
 
 func ipToSockaddrInet4(ip IP, port int) (syscall.SockaddrInet4, error) {
diff --git a/src/net/lookup.go b/src/net/lookup.go
index 7f3d201..0fd5d2b 100644
--- a/src/net/lookup.go
+++ b/src/net/lookup.go
@@ -6,6 +6,7 @@
 
 import (
 	"context"
+	"errors"
 	"internal/nettrace"
 	"internal/singleflight"
 	"net/netip"
@@ -224,10 +225,15 @@
 	default:
 		return nil, UnknownNetworkError(network)
 	}
+
+	if host == "" {
+		return nil, &DNSError{Err: errNoSuchHost.Error(), Name: host, IsNotFound: true}
+	}
 	addrs, err := r.internetAddrList(ctx, afnet, host)
 	if err != nil {
 		return nil, err
 	}
+
 	ips := make([]IP, 0, len(addrs))
 	for _, addr := range addrs {
 		ips = append(ips, addr.(*IPAddr).IP)
@@ -316,14 +322,15 @@
 
 	lookupKey := network + "\000" + host
 	dnsWaitGroup.Add(1)
-	ch, called := r.getLookupGroup().DoChan(lookupKey, func() (any, error) {
-		defer dnsWaitGroup.Done()
+	ch := r.getLookupGroup().DoChan(lookupKey, func() (any, error) {
 		return testHookLookupIP(lookupGroupCtx, resolverFunc, network, host)
 	})
-	if !called {
-		dnsWaitGroup.Done()
-	}
 
+	dnsWaitGroupDone := func(ch <-chan singleflight.Result, cancelFn context.CancelFunc) {
+		<-ch
+		dnsWaitGroup.Done()
+		cancelFn()
+	}
 	select {
 	case <-ctx.Done():
 		// Our context was canceled. If we are the only
@@ -335,11 +342,9 @@
 		// See issues 8602, 20703, 22724.
 		if r.getLookupGroup().ForgetUnshared(lookupKey) {
 			lookupGroupCancel()
+			go dnsWaitGroupDone(ch, func() {})
 		} else {
-			go func() {
-				<-ch
-				lookupGroupCancel()
-			}()
+			go dnsWaitGroupDone(ch, lookupGroupCancel)
 		}
 		ctxErr := ctx.Err()
 		err := &DNSError{
@@ -352,6 +357,7 @@
 		}
 		return nil, err
 	case r := <-ch:
+		dnsWaitGroup.Done()
 		lookupGroupCancel()
 		err := r.Err
 		if err != nil {
@@ -706,7 +712,7 @@
 	} else {
 		target = "_" + service + "._" + proto + "." + name
 	}
-	p, server, err := r.lookup(ctx, target, dnsmessage.TypeSRV)
+	p, server, err := r.lookup(ctx, target, dnsmessage.TypeSRV, nil)
 	if err != nil {
 		return "", nil, err
 	}
@@ -752,7 +758,7 @@
 
 // goLookupMX returns the MX records for name.
 func (r *Resolver) goLookupMX(ctx context.Context, name string) ([]*MX, error) {
-	p, server, err := r.lookup(ctx, name, dnsmessage.TypeMX)
+	p, server, err := r.lookup(ctx, name, dnsmessage.TypeMX, nil)
 	if err != nil {
 		return nil, err
 	}
@@ -796,7 +802,7 @@
 
 // goLookupNS returns the NS records for name.
 func (r *Resolver) goLookupNS(ctx context.Context, name string) ([]*NS, error) {
-	p, server, err := r.lookup(ctx, name, dnsmessage.TypeNS)
+	p, server, err := r.lookup(ctx, name, dnsmessage.TypeNS, nil)
 	if err != nil {
 		return nil, err
 	}
@@ -838,7 +844,7 @@
 
 // goLookupTXT returns the TXT records from name.
 func (r *Resolver) goLookupTXT(ctx context.Context, name string) ([]string, error) {
-	p, server, err := r.lookup(ctx, name, dnsmessage.TypeTXT)
+	p, server, err := r.lookup(ctx, name, dnsmessage.TypeTXT, nil)
 	if err != nil {
 		return nil, err
 	}
@@ -891,3 +897,14 @@
 	}
 	return txts, nil
 }
+
+func parseCNAMEFromResources(resources []dnsmessage.Resource) (string, error) {
+	if len(resources) == 0 {
+		return "", errors.New("no CNAME record received")
+	}
+	c, ok := resources[0].Body.(*dnsmessage.CNAMEResource)
+	if !ok {
+		return "", errors.New("could not parse CNAME record")
+	}
+	return c.CNAME.String(), nil
+}
diff --git a/src/net/lookup_plan9.go b/src/net/lookup_plan9.go
index 445b129..1995742 100644
--- a/src/net/lookup_plan9.go
+++ b/src/net/lookup_plan9.go
@@ -183,8 +183,12 @@
 // "PreferGo" implementation rather than asking plan9 services
 // for the answers.
 func (r *Resolver) preferGoOverPlan9() bool {
-	conf := systemConf()
-	order := conf.hostLookupOrder(r, "") // name is unused
+	_, _, res := r.preferGoOverPlan9WithOrderAndConf()
+	return res
+}
+
+func (r *Resolver) preferGoOverPlan9WithOrderAndConf() (hostLookupOrder, *dnsConfig, bool) {
+	order, conf := systemConf().hostLookupOrder(r, "") // name is unused
 
 	// TODO(bradfitz): for now we only permit use of the PreferGo
 	// implementation when there's a non-nil Resolver with a
@@ -193,7 +197,7 @@
 	// DNS cache) and they don't want to actually hit the network.
 	// Once we add support for looking the default DNS servers
 	// from plan9, though, then we can relax this.
-	return order != hostLookupCgo && r != nil && r.Dial != nil
+	return order, conf, order != hostLookupCgo && r != nil && r.Dial != nil
 }
 
 func (r *Resolver) lookupIP(ctx context.Context, network, host string) (addrs []IPAddr, err error) {
@@ -244,9 +248,10 @@
 }
 
 func (r *Resolver) lookupCNAME(ctx context.Context, name string) (cname string, err error) {
-	if r.preferGoOverPlan9() {
-		return r.goLookupCNAME(ctx, name)
+	if order, conf, preferGo := r.preferGoOverPlan9WithOrderAndConf(); preferGo {
+		return r.goLookupCNAME(ctx, name, order, conf)
 	}
+
 	lines, err := queryDNS(ctx, name, "cname")
 	if err != nil {
 		if stringsHasSuffix(err.Error(), "dns failure") || stringsHasSuffix(err.Error(), "resource does not exist; negrcode 0") {
@@ -351,8 +356,8 @@
 }
 
 func (r *Resolver) lookupAddr(ctx context.Context, addr string) (name []string, err error) {
-	if r.preferGoOverPlan9() {
-		return r.goLookupPTR(ctx, addr)
+	if _, conf, preferGo := r.preferGoOverPlan9WithOrderAndConf(); preferGo {
+		return r.goLookupPTR(ctx, addr, conf)
 	}
 	arpa, err := reverseaddr(addr)
 	if err != nil {
diff --git a/src/net/lookup_test.go b/src/net/lookup_test.go
index 3a31f56..fa1a706 100644
--- a/src/net/lookup_test.go
+++ b/src/net/lookup_test.go
@@ -7,10 +7,10 @@
 package net
 
 import (
-	"bytes"
 	"context"
 	"fmt"
 	"internal/testenv"
+	"net/netip"
 	"reflect"
 	"runtime"
 	"sort"
@@ -49,21 +49,21 @@
 	cname, target        string
 }{
 	{
-		"xmpp-server", "tcp", "google.com",
+		"ldap", "tcp", "google.com",
 		"google.com.", "google.com.",
 	},
 	{
-		"xmpp-server", "tcp", "google.com.",
+		"ldap", "tcp", "google.com.",
 		"google.com.", "google.com.",
 	},
 
 	// non-standard back door
 	{
-		"", "", "_xmpp-server._tcp.google.com",
+		"", "", "_ldap._tcp.google.com",
 		"google.com.", "google.com.",
 	},
 	{
-		"", "", "_xmpp-server._tcp.google.com.",
+		"", "", "_ldap._tcp.google.com.",
 		"google.com.", "google.com.",
 	},
 }
@@ -348,6 +348,8 @@
 	{"www.iana.org", "icann.org."},
 	{"www.iana.org.", "icann.org."},
 	{"www.google.com", "google.com."},
+	{"google.com", "google.com."},
+	{"cname-to-txt.go4.org", "test-txt-record.go4.org."},
 }
 
 func TestLookupCNAME(t *testing.T) {
@@ -701,16 +703,16 @@
 		}
 	}
 
-	cname, srvs, err := LookupSRV("xmpp-server", "tcp", "google.com")
+	cname, srvs, err := LookupSRV("ldap", "tcp", "google.com")
 	if err != nil {
-		t.Errorf("LookupSRV(xmpp-server, tcp, google.com): %v (mode=%v)", err, mode)
+		t.Errorf("LookupSRV(ldap, tcp, google.com): %v (mode=%v)", err, mode)
 	} else {
 		if !hasSuffixFold(cname, ".google.com.") {
-			t.Errorf("LookupSRV(xmpp-server, tcp, google.com) returned cname=%v, want name ending in .google.com. with trailing dot (mode=%v)", cname, mode)
+			t.Errorf("LookupSRV(ldap, tcp, google.com) returned cname=%v, want name ending in .google.com. with trailing dot (mode=%v)", cname, mode)
 		}
 		for _, srv := range srvs {
 			if !hasSuffixFold(srv.Target, ".google.com.") {
-				t.Errorf("LookupSRV(xmpp-server, tcp, google.com) returned addrs=%v, want names ending in .google.com. with trailing dot (mode=%v)", srvString(srvs), mode)
+				t.Errorf("LookupSRV(ldap, tcp, google.com) returned addrs=%v, want names ending in .google.com. with trailing dot (mode=%v)", srvString(srvs), mode)
 				break
 			}
 		}
@@ -718,7 +720,7 @@
 }
 
 func mxString(mxs []*MX) string {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	sep := ""
 	fmt.Fprintf(&buf, "[")
 	for _, mx := range mxs {
@@ -730,7 +732,7 @@
 }
 
 func nsString(nss []*NS) string {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	sep := ""
 	fmt.Fprintf(&buf, "[")
 	for _, ns := range nss {
@@ -742,7 +744,7 @@
 }
 
 func srvString(srvs []*SRV) string {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	sep := ""
 	fmt.Fprintf(&buf, "[")
 	for _, srv := range srvs {
@@ -1208,6 +1210,17 @@
 	wg.Wait()
 }
 
+// Issue 53995: Resolver.LookupIP should return error for empty host name.
+func TestResolverLookupIPWithEmptyHost(t *testing.T) {
+	_, err := DefaultResolver.LookupIP(context.Background(), "ip", "")
+	if err == nil {
+		t.Fatal("DefaultResolver.LookupIP for empty host success, want no host error")
+	}
+	if !strings.HasSuffix(err.Error(), errNoSuchHost.Error()) {
+		t.Fatalf("lookup error = %v, want %v", err, errNoSuchHost)
+	}
+}
+
 func TestWithUnexpiredValuesPreserved(t *testing.T) {
 	ctx, cancel := context.WithCancel(context.Background())
 
@@ -1279,18 +1292,16 @@
 						t.Fatalf("DefaultResolver.LookupIP(%q, %q): failed with unexpected error: %v", network, host, err)
 					}
 
-					var v4Addrs []IP
-					var v6Addrs []IP
+					var v4Addrs []netip.Addr
+					var v6Addrs []netip.Addr
 					for _, ip := range ips {
-						switch {
-						case ip.To4() != nil:
-							// We need to skip the test below because To16 will
-							// convent an IPv4 address to an IPv4-mapped IPv6
-							// address.
-							v4Addrs = append(v4Addrs, ip)
-						case ip.To16() != nil:
-							v6Addrs = append(v6Addrs, ip)
-						default:
+						if addr, ok := netip.AddrFromSlice(ip); ok {
+							if addr.Is4() {
+								v4Addrs = append(v4Addrs, addr)
+							} else {
+								v6Addrs = append(v6Addrs, addr)
+							}
+						} else {
 							t.Fatalf("IP=%q is neither IPv4 nor IPv6", ip)
 						}
 					}
@@ -1312,7 +1323,7 @@
 						t.Errorf("DefaultResolver.LookupIP(%q, %q): unexpected IPv4 addresses: %v", network, host, v4Addrs)
 					}
 					if network == "ip4" && len(v6Addrs) > 0 {
-						t.Errorf("DefaultResolver.LookupIP(%q, %q): unexpected IPv6 addresses: %v", network, host, v6Addrs)
+						t.Errorf("DefaultResolver.LookupIP(%q, %q): unexpected IPv6 or IPv4-mapped IPv6 addresses: %v", network, host, v6Addrs)
 					}
 				})
 			}
diff --git a/src/net/lookup_unix.go b/src/net/lookup_unix.go
index 4b885e9..600e694 100644
--- a/src/net/lookup_unix.go
+++ b/src/net/lookup_unix.go
@@ -54,7 +54,7 @@
 }
 
 func (r *Resolver) lookupHost(ctx context.Context, host string) (addrs []string, err error) {
-	order := systemConf().hostLookupOrder(r, host)
+	order, conf := systemConf().hostLookupOrder(r, host)
 	if !r.preferGo() && order == hostLookupCgo {
 		if addrs, err, ok := cgoLookupHost(ctx, host); ok {
 			return addrs, err
@@ -62,14 +62,14 @@
 		// cgo not available (or netgo); fall back to Go's DNS resolver
 		order = hostLookupFilesDNS
 	}
-	return r.goLookupHostOrder(ctx, host, order)
+	return r.goLookupHostOrder(ctx, host, order, conf)
 }
 
 func (r *Resolver) lookupIP(ctx context.Context, network, host string) (addrs []IPAddr, err error) {
 	if r.preferGo() {
 		return r.goLookupIP(ctx, network, host)
 	}
-	order := systemConf().hostLookupOrder(r, host)
+	order, conf := systemConf().hostLookupOrder(r, host)
 	if order == hostLookupCgo {
 		if addrs, err, ok := cgoLookupIP(ctx, network, host); ok {
 			return addrs, err
@@ -77,7 +77,7 @@
 		// cgo not available (or netgo); fall back to Go's DNS resolver
 		order = hostLookupFilesDNS
 	}
-	ips, _, err := r.goLookupIPCNAMEOrder(ctx, network, host, order)
+	ips, _, err := r.goLookupIPCNAMEOrder(ctx, network, host, order, conf)
 	return ips, err
 }
 
@@ -98,12 +98,13 @@
 }
 
 func (r *Resolver) lookupCNAME(ctx context.Context, name string) (string, error) {
-	if !r.preferGo() && systemConf().canUseCgo() {
+	order, conf := systemConf().hostLookupOrder(r, name)
+	if !r.preferGo() && order == hostLookupCgo {
 		if cname, err, ok := cgoLookupCNAME(ctx, name); ok {
 			return cname, err
 		}
 	}
-	return r.goLookupCNAME(ctx, name)
+	return r.goLookupCNAME(ctx, name, order, conf)
 }
 
 func (r *Resolver) lookupSRV(ctx context.Context, service, proto, name string) (string, []*SRV, error) {
@@ -123,12 +124,13 @@
 }
 
 func (r *Resolver) lookupAddr(ctx context.Context, addr string) ([]string, error) {
-	if !r.preferGo() && systemConf().canUseCgo() {
+	order, conf := systemConf().hostLookupOrder(r, "")
+	if !r.preferGo() && order == hostLookupCgo {
 		if ptrs, err, ok := cgoLookupPTR(ctx, addr); ok {
 			return ptrs, err
 		}
 	}
-	return r.goLookupPTR(ctx, addr)
+	return r.goLookupPTR(ctx, addr, conf)
 }
 
 // concurrentThreadsLimit returns the number of threads we permit to
diff --git a/src/net/lookup_windows.go b/src/net/lookup_windows.go
index 9ff39c7..4ee7281 100644
--- a/src/net/lookup_windows.go
+++ b/src/net/lookup_windows.go
@@ -87,7 +87,7 @@
 // kernel for its answer.
 func (r *Resolver) preferGoOverWindows() bool {
 	conf := systemConf()
-	order := conf.hostLookupOrder(r, "") // name is unused
+	order, _ := conf.hostLookupOrder(r, "") // name is unused
 	return order != hostLookupCgo
 }
 
@@ -134,11 +134,11 @@
 			switch result.Family {
 			case syscall.AF_INET:
 				a := (*syscall.RawSockaddrInet4)(addr).Addr
-				addrs = append(addrs, IPAddr{IP: IPv4(a[0], a[1], a[2], a[3])})
+				addrs = append(addrs, IPAddr{IP: copyIP(a[:])})
 			case syscall.AF_INET6:
 				a := (*syscall.RawSockaddrInet6)(addr).Addr
 				zone := zoneCache.name(int((*syscall.RawSockaddrInet6)(addr).Scope_id))
-				addrs = append(addrs, IPAddr{IP: IP{a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]}, Zone: zone})
+				addrs = append(addrs, IPAddr{IP: copyIP(a[:]), Zone: zone})
 			default:
 				return nil, &DNSError{Err: syscall.EWINDOWS.Error(), Name: name}
 			}
@@ -230,9 +230,10 @@
 }
 
 func (r *Resolver) lookupCNAME(ctx context.Context, name string) (string, error) {
-	if r.preferGoOverWindows() {
-		return r.goLookupCNAME(ctx, name)
+	if order, conf := systemConf().hostLookupOrder(r, ""); order != hostLookupCgo {
+		return r.goLookupCNAME(ctx, name, order, conf)
 	}
+
 	// TODO(bradfitz): finish ctx plumbing. Nothing currently depends on this.
 	acquireThread()
 	defer releaseThread()
@@ -355,7 +356,7 @@
 
 func (r *Resolver) lookupAddr(ctx context.Context, addr string) ([]string, error) {
 	if r.preferGoOverWindows() {
-		return r.goLookupPTR(ctx, addr)
+		return r.goLookupPTR(ctx, addr, nil)
 	}
 
 	// TODO(bradfitz): finish ctx plumbing. Nothing currently depends on this.
@@ -382,7 +383,7 @@
 
 const dnsSectionMask = 0x0003
 
-// returns only results applicable to name and resolves CNAME entries
+// returns only results applicable to name and resolves CNAME entries.
 func validRecs(r *syscall.DNSRecord, dnstype uint16, name string) []*syscall.DNSRecord {
 	cname := syscall.StringToUTF16Ptr(name)
 	if dnstype != syscall.DNS_TYPE_CNAME {
@@ -405,7 +406,7 @@
 	return rec
 }
 
-// returns the last CNAME in chain
+// returns the last CNAME in chain.
 func resolveCNAME(name *uint16, r *syscall.DNSRecord) *uint16 {
 	// limit cname resolving to 10 in case of an infinite CNAME loop
 Cname:
diff --git a/src/net/lookup_windows_test.go b/src/net/lookup_windows_test.go
index b7a60e1..c618a05 100644
--- a/src/net/lookup_windows_test.go
+++ b/src/net/lookup_windows_test.go
@@ -5,7 +5,6 @@
 package net
 
 import (
-	"bytes"
 	"context"
 	"encoding/json"
 	"errors"
@@ -16,6 +15,7 @@
 	"regexp"
 	"sort"
 	"strings"
+	"syscall"
 	"testing"
 )
 
@@ -171,6 +171,14 @@
 	for _, addr := range lookupTestIPs {
 		names, err := LookupAddr(addr)
 		if err != nil {
+			// The DNSError type stores the error as a string, so it cannot wrap the
+			// original error code and we cannot check for it here. However, we can at
+			// least use its error string to identify the correct localized text for
+			// the error to skip.
+			var DNS_ERROR_RCODE_SERVER_FAILURE syscall.Errno = 9002
+			if strings.HasSuffix(err.Error(), DNS_ERROR_RCODE_SERVER_FAILURE.Error()) {
+				testenv.SkipFlaky(t, 38111)
+			}
 			t.Errorf("failed %s: %s", addr, err)
 		}
 		if len(names) == 0 {
@@ -207,8 +215,8 @@
 func (s byHost) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
 
 func nslookup(qtype, name string) (string, error) {
-	var out bytes.Buffer
-	var err bytes.Buffer
+	var out strings.Builder
+	var err strings.Builder
 	cmd := exec.Command("nslookup", "-querytype="+qtype, name)
 	cmd.Stdout = &out
 	cmd.Stderr = &err
diff --git a/src/net/mail/message.go b/src/net/mail/message.go
index c91aa3a..6268c08 100644
--- a/src/net/mail/message.go
+++ b/src/net/mail/message.go
@@ -829,18 +829,18 @@
 
 // quoteString renders a string as an RFC 5322 quoted-string.
 func quoteString(s string) string {
-	var buf strings.Builder
-	buf.WriteByte('"')
+	var b strings.Builder
+	b.WriteByte('"')
 	for _, r := range s {
 		if isQtext(r) || isWSP(r) {
-			buf.WriteRune(r)
+			b.WriteRune(r)
 		} else if isVchar(r) {
-			buf.WriteByte('\\')
-			buf.WriteRune(r)
+			b.WriteByte('\\')
+			b.WriteRune(r)
 		}
 	}
-	buf.WriteByte('"')
-	return buf.String()
+	b.WriteByte('"')
+	return b.String()
 }
 
 // isVchar reports whether r is an RFC 5322 VCHAR character.
@@ -850,7 +850,7 @@
 }
 
 // isMultibyte reports whether r is a multi-byte UTF-8 character
-// as supported by RFC 6532
+// as supported by RFC 6532.
 func isMultibyte(r rune) bool {
 	return r >= utf8.RuneSelf
 }
diff --git a/src/net/net.go b/src/net/net.go
index ff56c31..0a4f747 100644
--- a/src/net/net.go
+++ b/src/net/net.go
@@ -498,7 +498,7 @@
 	// immediate cancellation of dials.
 	aLongTimeAgo = time.Unix(1, 0)
 
-	// nonDeadline and noCancel are just zero values for
+	// noDeadline and noCancel are just zero values for
 	// readability with functions taking too many parameters.
 	noDeadline = time.Time{}
 	noCancel   = (chan struct{})(nil)
diff --git a/src/net/net_fake.go b/src/net/net_fake.go
index 6d07d62..2ecc1fa 100644
--- a/src/net/net_fake.go
+++ b/src/net/net_fake.go
@@ -57,7 +57,7 @@
 
 // socket returns a network file descriptor that is ready for
 // asynchronous I/O using the network poller.
-func socket(ctx context.Context, net string, family, sotype, proto int, ipv6only bool, laddr, raddr sockaddr, ctrlFn func(string, string, syscall.RawConn) error) (*netFD, error) {
+func socket(ctx context.Context, net string, family, sotype, proto int, ipv6only bool, laddr, raddr sockaddr, ctrlCtxFn func(context.Context, string, string, syscall.RawConn) error) (*netFD, error) {
 	fd := &netFD{family: family, sotype: sotype, net: net}
 
 	if laddr != nil && raddr == nil { // listener
@@ -194,7 +194,7 @@
 		if !p.rDeadline.IsZero() {
 			d := time.Until(p.rDeadline)
 			if d <= 0 {
-				return 0, syscall.EAGAIN
+				return 0, os.ErrDeadlineExceeded
 			}
 			time.AfterFunc(d, p.rCond.Broadcast)
 		}
@@ -221,7 +221,7 @@
 		if !p.wDeadline.IsZero() {
 			d := time.Until(p.wDeadline)
 			if d <= 0 {
-				return 0, syscall.EAGAIN
+				return 0, os.ErrDeadlineExceeded
 			}
 			time.AfterFunc(d, p.wCond.Broadcast)
 		}
@@ -317,6 +317,6 @@
 	return nil, syscall.ENOSYS
 }
 
-func (r *Resolver) lookup(ctx context.Context, name string, qtype dnsmessage.Type) (dnsmessage.Parser, string, error) {
+func (r *Resolver) lookup(ctx context.Context, name string, qtype dnsmessage.Type, conf *dnsConfig) (dnsmessage.Parser, string, error) {
 	panic("unreachable")
 }
diff --git a/src/net/net_test.go b/src/net/net_test.go
index c297c51..05c058a 100644
--- a/src/net/net_test.go
+++ b/src/net/net_test.go
@@ -430,6 +430,7 @@
 // runs peer1 and peer2 concurrently. withTCPConnPair returns when
 // both have completed.
 func withTCPConnPair(t *testing.T, peer1, peer2 func(c *TCPConn) error) {
+	t.Helper()
 	ln := newLocalListener(t, "tcp")
 	defer ln.Close()
 	errc := make(chan error, 2)
diff --git a/src/net/netgo.go b/src/net/netgo.go
index 75baa88..e478c88 100644
--- a/src/net/netgo.go
+++ b/src/net/netgo.go
@@ -4,9 +4,9 @@
 
 // Default netGo to true if the netgo build tag is being used, or the
 // C library DNS routines are not available. Note that the C library
-// routines are always available on Windows.
+// routines are always available on Darwin and Windows.
 
-//go:build netgo || (!cgo && !windows)
+//go:build netgo || (!cgo && !darwin && !windows)
 
 package net
 
diff --git a/src/net/netgo_unix_test.go b/src/net/netgo_unix_test.go
index 019772a..5ddebab 100644
--- a/src/net/netgo_unix_test.go
+++ b/src/net/netgo_unix_test.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build (!cgo || netgo) && (darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris)
+//go:build (!cgo || netgo) && (dragonfly || freebsd || linux || netbsd || openbsd || solaris)
 
 package net
 
diff --git a/src/net/netip/inlining_test.go b/src/net/netip/inlining_test.go
index 52991be..b521eee 100644
--- a/src/net/netip/inlining_test.go
+++ b/src/net/netip/inlining_test.go
@@ -42,7 +42,6 @@
 		"Addr.IsValid",
 		"Addr.IsUnspecified",
 		"Addr.Less",
-		"Addr.lessOrEq",
 		"Addr.Unmap",
 		"Addr.Zone",
 		"Addr.v4",
@@ -81,8 +80,6 @@
 	case "amd64", "arm64":
 		// These don't inline on 32-bit.
 		wantInlinable = append(wantInlinable,
-			"u64CommonPrefixLen",
-			"uint128.commonPrefixLen",
 			"Addr.Next",
 			"Addr.Prev",
 		)
diff --git a/src/net/netip/netip.go b/src/net/netip/netip.go
index bb83371..ec9266d 100644
--- a/src/net/netip/netip.go
+++ b/src/net/netip/netip.go
@@ -75,6 +75,13 @@
 // address ff02::1.
 func IPv6LinkLocalAllNodes() Addr { return AddrFrom16([16]byte{0: 0xff, 1: 0x02, 15: 0x01}) }
 
+// IPv6LinkLocalAllRouters returns the IPv6 link-local all routers multicast
+// address ff02::2.
+func IPv6LinkLocalAllRouters() Addr { return AddrFrom16([16]byte{0: 0xff, 1: 0x02, 15: 0x02}) }
+
+// IPv6Loopback returns the IPv6 loopback address ::1.
+func IPv6Loopback() Addr { return AddrFrom16([16]byte{15: 0x01}) }
+
 // IPv6Unspecified returns the IPv6 unspecified address "::".
 func IPv6Unspecified() Addr { return Addr{z: z6noz} }
 
@@ -102,18 +109,6 @@
 	}
 }
 
-// ipv6Slice is like IPv6Raw, but operates on a 16-byte slice. Assumes
-// slice is 16 bytes, caller must enforce this.
-func ipv6Slice(addr []byte) Addr {
-	return Addr{
-		addr: uint128{
-			beUint64(addr[:8]),
-			beUint64(addr[8:]),
-		},
-		z: z6noz,
-	}
-}
-
 // ParseAddr parses s as an IP address, returning the result. The string
 // s can be in dotted decimal ("192.0.2.1"), IPv6 ("2001:db8::68"),
 // or IPv6 with a scoped addressing zone ("fe80::1cc0:3e8c:119f:c2e1%ens18").
@@ -345,9 +340,9 @@
 func AddrFromSlice(slice []byte) (ip Addr, ok bool) {
 	switch len(slice) {
 	case 4:
-		return AddrFrom4(*(*[4]byte)(slice)), true
+		return AddrFrom4([4]byte(slice)), true
 	case 16:
-		return ipv6Slice(slice), true
+		return AddrFrom16([16]byte(slice)), true
 	}
 	return Addr{}, false
 }
@@ -452,8 +447,6 @@
 // IPv6 addresses with zones sort just after the same address without a zone.
 func (ip Addr) Less(ip2 Addr) bool { return ip.Compare(ip2) == -1 }
 
-func (ip Addr) lessOrEq(ip2 Addr) bool { return ip.Compare(ip2) <= 0 }
-
 // Is4 reports whether ip is an IPv4 address.
 //
 // It returns false for IPv4-mapped IPv6 addresses. See Addr.Unmap.
@@ -1017,13 +1010,13 @@
 		*ip = Addr{}
 		return nil
 	case n == 4:
-		*ip = AddrFrom4(*(*[4]byte)(b))
+		*ip = AddrFrom4([4]byte(b))
 		return nil
 	case n == 16:
-		*ip = ipv6Slice(b)
+		*ip = AddrFrom16([16]byte(b))
 		return nil
 	case n > 16:
-		*ip = ipv6Slice(b[:16]).WithZone(string(b[16:]))
+		*ip = AddrFrom16([16]byte(b[:16])).WithZone(string(b[16:]))
 		return nil
 	}
 	return errors.New("unexpected slice size")
@@ -1111,10 +1104,7 @@
 	return ip
 }
 
-// isZero reports whether p is the zero AddrPort.
-func (p AddrPort) isZero() bool { return p == AddrPort{} }
-
-// IsValid reports whether p.IP() is valid.
+// IsValid reports whether p.Addr() is valid.
 // All ports are valid, including zero.
 func (p AddrPort) IsValid() bool { return p.ip.IsValid() }
 
@@ -1276,7 +1266,7 @@
 // It reports -1 if invalid.
 func (p Prefix) Bits() int { return int(p.bits) }
 
-// IsValid reports whether p.Bits() has a valid range for p.IP().
+// IsValid reports whether p.Bits() has a valid range for p.Addr().
 // If p.Addr() is the zero Addr, IsValid returns false.
 // Note that if p is the zero Prefix, then p.IsValid() == false.
 func (p Prefix) IsValid() bool { return !p.ip.isZero() && p.bits >= 0 && int(p.bits) <= p.ip.BitLen() }
diff --git a/src/net/netip/netip_test.go b/src/net/netip/netip_test.go
index 74dcc97..b915b24 100644
--- a/src/net/netip/netip_test.go
+++ b/src/net/netip/netip_test.go
@@ -301,6 +301,41 @@
 	}
 }
 
+func TestAddrFromSlice(t *testing.T) {
+	tests := []struct {
+		ip       []byte
+		wantAddr Addr
+		wantOK   bool
+	}{
+		{
+			ip:       []byte{10, 0, 0, 1},
+			wantAddr: mustIP("10.0.0.1"),
+			wantOK:   true,
+		},
+		{
+			ip:       []byte{0xfe, 0x80, 15: 0x01},
+			wantAddr: mustIP("fe80::01"),
+			wantOK:   true,
+		},
+		{
+			ip:       []byte{0, 1, 2},
+			wantAddr: Addr{},
+			wantOK:   false,
+		},
+		{
+			ip:       nil,
+			wantAddr: Addr{},
+			wantOK:   false,
+		},
+	}
+	for _, tt := range tests {
+		addr, ok := AddrFromSlice(tt.ip)
+		if ok != tt.wantOK || addr != tt.wantAddr {
+			t.Errorf("AddrFromSlice(%#v) = %#v, %v, want %#v, %v", tt.ip, addr, ok, tt.wantAddr, tt.wantOK)
+		}
+	}
+}
+
 func TestIPv4Constructors(t *testing.T) {
 	if AddrFrom4([4]byte{1, 2, 3, 4}) != MustParseAddr("1.2.3.4") {
 		t.Errorf("don't match")
@@ -559,9 +594,6 @@
 		private4b = mustIP("172.16.0.1")
 		private4c = mustIP("192.168.1.1")
 		private6  = mustIP("fd00::1")
-
-		unspecified4 = AddrFrom4([4]byte{})
-		unspecified6 = IPv6Unspecified()
 	)
 
 	tests := []struct {
@@ -686,12 +718,12 @@
 		},
 		{
 			name:        "unspecified v4Addr",
-			ip:          unspecified4,
+			ip:          IPv4Unspecified(),
 			unspecified: true,
 		},
 		{
 			name:        "unspecified v6Addr",
-			ip:          unspecified6,
+			ip:          IPv6Unspecified(),
 			unspecified: true,
 		},
 	}
@@ -753,6 +785,16 @@
 			std:  net.IPv6linklocalallnodes,
 		},
 		{
+			name: "IPv6 link-local all routers",
+			ip:   IPv6LinkLocalAllRouters(),
+			std:  net.IPv6linklocalallrouters,
+		},
+		{
+			name: "IPv6 loopback",
+			ip:   IPv6Loopback(),
+			std:  net.IPv6loopback,
+		},
+		{
 			name: "IPv6 unspecified",
 			ip:   IPv6Unspecified(),
 			std:  net.IPv6unspecified,
@@ -1835,6 +1877,8 @@
 	test("ParseAddr/6", func() { sinkIP = panicIP(ParseAddr("::1")) })
 	test("MustParseAddr", func() { sinkIP = MustParseAddr("1.2.3.4") })
 	test("IPv6LinkLocalAllNodes", func() { sinkIP = IPv6LinkLocalAllNodes() })
+	test("IPv6LinkLocalAllRouters", func() { sinkIP = IPv6LinkLocalAllRouters() })
+	test("IPv6Loopback", func() { sinkIP = IPv6Loopback() })
 	test("IPv6Unspecified", func() { sinkIP = IPv6Unspecified() })
 
 	// IP methods
@@ -1908,10 +1952,10 @@
 		{"ipv4-in-ipv6", MustParseAddr("::ffff:192.168.1.1"), 1},
 		{"ipv4-in-ipv6+zone", MustParseAddr("::ffff:192.168.1.1%eth0"), 1},
 	}
-	isNooptBuilder := strings.HasSuffix(testenv.Builder(), "-noopt")
+	optimizationOff := testenv.OptimizationOff()
 	for _, tc := range tests {
 		t.Run(tc.name, func(t *testing.T) {
-			if isNooptBuilder && strings.HasPrefix(tc.name, "ipv4-in-ipv6") {
+			if optimizationOff && strings.HasPrefix(tc.name, "ipv4-in-ipv6") {
 				// Optimizations are required to remove some allocs.
 				t.Skipf("skipping on %v", testenv.Builder())
 			}
diff --git a/src/net/netip/uint128.go b/src/net/netip/uint128.go
index 738939d..b1605af 100644
--- a/src/net/netip/uint128.go
+++ b/src/net/netip/uint128.go
@@ -60,17 +60,6 @@
 	return uint128{u.hi + carry, lo}
 }
 
-func u64CommonPrefixLen(a, b uint64) uint8 {
-	return uint8(bits.LeadingZeros64(a ^ b))
-}
-
-func (u uint128) commonPrefixLen(v uint128) (n uint8) {
-	if n = u64CommonPrefixLen(u.hi, v.hi); n == 64 {
-		n += u64CommonPrefixLen(u.lo, v.lo)
-	}
-	return
-}
-
 // halves returns the two uint64 halves of the uint128.
 //
 // Logically, think of it as returning two uint64s.
diff --git a/src/net/nss.go b/src/net/nss.go
index c4c608f..092b515 100644
--- a/src/net/nss.go
+++ b/src/net/nss.go
@@ -7,12 +7,94 @@
 import (
 	"errors"
 	"internal/bytealg"
-	"io"
 	"os"
+	"sync"
+	"time"
 )
 
+const (
+	nssConfigPath = "/etc/nsswitch.conf"
+)
+
+var nssConfig nsswitchConfig
+
+type nsswitchConfig struct {
+	initOnce sync.Once // guards init of nsswitchConfig
+
+	// ch is used as a semaphore that only allows one lookup at a
+	// time to recheck nsswitch.conf
+	ch          chan struct{} // guards lastChecked and modTime
+	lastChecked time.Time     // last time nsswitch.conf was checked
+
+	mu      sync.Mutex // protects nssConf
+	nssConf *nssConf
+}
+
+func getSystemNSS() *nssConf {
+	nssConfig.tryUpdate()
+	nssConfig.mu.Lock()
+	conf := nssConfig.nssConf
+	nssConfig.mu.Unlock()
+	return conf
+}
+
+// init initializes conf and is only called via conf.initOnce.
+func (conf *nsswitchConfig) init() {
+	conf.nssConf = parseNSSConfFile("/etc/nsswitch.conf")
+	conf.lastChecked = time.Now()
+	conf.ch = make(chan struct{}, 1)
+}
+
+// tryUpdate tries to update conf.
+func (conf *nsswitchConfig) tryUpdate() {
+	conf.initOnce.Do(conf.init)
+
+	// Ensure only one update at a time checks nsswitch.conf
+	if !conf.tryAcquireSema() {
+		return
+	}
+	defer conf.releaseSema()
+
+	now := time.Now()
+	if conf.lastChecked.After(now.Add(-5 * time.Second)) {
+		return
+	}
+	conf.lastChecked = now
+
+	var mtime time.Time
+	if fi, err := os.Stat(nssConfigPath); err == nil {
+		mtime = fi.ModTime()
+	}
+	if mtime.Equal(conf.nssConf.mtime) {
+		return
+	}
+
+	nssConf := parseNSSConfFile(nssConfigPath)
+	conf.mu.Lock()
+	conf.nssConf = nssConf
+	conf.mu.Unlock()
+}
+
+func (conf *nsswitchConfig) acquireSema() {
+	conf.ch <- struct{}{}
+}
+
+func (conf *nsswitchConfig) tryAcquireSema() bool {
+	select {
+	case conf.ch <- struct{}{}:
+		return true
+	default:
+		return false
+	}
+}
+
+func (conf *nsswitchConfig) releaseSema() {
+	<-conf.ch
+}
+
 // nssConf represents the state of the machine's /etc/nsswitch.conf file.
 type nssConf struct {
+	mtime   time.Time              // time of nsswitch.conf modification
 	err     error                  // any error encountered opening or parsing the file
 	sources map[string][]nssSource // keyed by database (e.g. "hosts")
 }
@@ -65,56 +147,62 @@
 }
 
 func parseNSSConfFile(file string) *nssConf {
-	f, err := os.Open(file)
+	f, err := open(file)
 	if err != nil {
 		return &nssConf{err: err}
 	}
-	defer f.Close()
-	return parseNSSConf(f)
+	defer f.close()
+	mtime, _, err := f.stat()
+	if err != nil {
+		return &nssConf{err: err}
+	}
+
+	conf := parseNSSConf(f)
+	conf.mtime = mtime
+	return conf
 }
 
-func parseNSSConf(r io.Reader) *nssConf {
-	slurp, err := readFull(r)
-	if err != nil {
-		return &nssConf{err: err}
-	}
+func parseNSSConf(f *file) *nssConf {
 	conf := new(nssConf)
-	conf.err = foreachLine(slurp, func(line []byte) error {
+	for line, ok := f.readLine(); ok; line, ok = f.readLine() {
 		line = trimSpace(removeComment(line))
 		if len(line) == 0 {
-			return nil
+			continue
 		}
-		colon := bytealg.IndexByte(line, ':')
+		colon := bytealg.IndexByteString(line, ':')
 		if colon == -1 {
-			return errors.New("no colon on line")
+			conf.err = errors.New("no colon on line")
+			return conf
 		}
-		db := string(trimSpace(line[:colon]))
+		db := trimSpace(line[:colon])
 		srcs := line[colon+1:]
 		for {
 			srcs = trimSpace(srcs)
 			if len(srcs) == 0 {
 				break
 			}
-			sp := bytealg.IndexByte(srcs, ' ')
+			sp := bytealg.IndexByteString(srcs, ' ')
 			var src string
 			if sp == -1 {
-				src = string(srcs)
-				srcs = nil // done
+				src = srcs
+				srcs = "" // done
 			} else {
-				src = string(srcs[:sp])
+				src = srcs[:sp]
 				srcs = trimSpace(srcs[sp+1:])
 			}
 			var criteria []nssCriterion
 			// See if there's a criteria block in brackets.
 			if len(srcs) > 0 && srcs[0] == '[' {
-				bclose := bytealg.IndexByte(srcs, ']')
+				bclose := bytealg.IndexByteString(srcs, ']')
 				if bclose == -1 {
-					return errors.New("unclosed criterion bracket")
+					conf.err = errors.New("unclosed criterion bracket")
+					return conf
 				}
 				var err error
 				criteria, err = parseCriteria(srcs[1:bclose])
 				if err != nil {
-					return errors.New("invalid criteria: " + string(srcs[1:bclose]))
+					conf.err = errors.New("invalid criteria: " + srcs[1:bclose])
+					return conf
 				}
 				srcs = srcs[bclose+1:]
 			}
@@ -126,14 +214,13 @@
 				criteria: criteria,
 			})
 		}
-		return nil
-	})
+	}
 	return conf
 }
 
 // parses "foo=bar !foo=bar"
-func parseCriteria(x []byte) (c []nssCriterion, err error) {
-	err = foreachField(x, func(f []byte) error {
+func parseCriteria(x string) (c []nssCriterion, err error) {
+	err = foreachField(x, func(f string) error {
 		not := false
 		if len(f) > 0 && f[0] == '!' {
 			not = true
@@ -142,15 +229,19 @@
 		if len(f) < 3 {
 			return errors.New("criterion too short")
 		}
-		eq := bytealg.IndexByte(f, '=')
+		eq := bytealg.IndexByteString(f, '=')
 		if eq == -1 {
 			return errors.New("criterion lacks equal sign")
 		}
-		lowerASCIIBytes(f)
+		if hasUpperCase(f) {
+			lower := []byte(f)
+			lowerASCIIBytes(lower)
+			f = string(lower)
+		}
 		c = append(c, nssCriterion{
 			negate: not,
-			status: string(f[:eq]),
-			action: string(f[eq+1:]),
+			status: f[:eq],
+			action: f[eq+1:],
 		})
 		return nil
 	})
diff --git a/src/net/nss_test.go b/src/net/nss_test.go
index c9ccc60..94e6b5f 100644
--- a/src/net/nss_test.go
+++ b/src/net/nss_test.go
@@ -8,8 +8,8 @@
 
 import (
 	"reflect"
-	"strings"
 	"testing"
+	"time"
 )
 
 const ubuntuTrustyAvahi = `# /etc/nsswitch.conf
@@ -34,6 +34,8 @@
 `
 
 func TestParseNSSConf(t *testing.T) {
+	t.Parallel()
+
 	tests := []struct {
 		name string
 		in   string
@@ -161,7 +163,8 @@
 	}
 
 	for _, tt := range tests {
-		gotConf := parseNSSConf(strings.NewReader(tt.in))
+		gotConf := nssStr(t, tt.in)
+		gotConf.mtime = time.Time{} // ignore mtime in comparison
 		if !reflect.DeepEqual(gotConf, tt.want) {
 			t.Errorf("%s: mismatch\n got %#v\nwant %#v", tt.name, gotConf, tt.want)
 		}
diff --git a/src/net/parse.go b/src/net/parse.go
index ee2890f..fbc5014 100644
--- a/src/net/parse.go
+++ b/src/net/parse.go
@@ -64,6 +64,14 @@
 	return
 }
 
+func (f *file) stat() (mtime time.Time, size int64, err error) {
+	st, err := f.file.Stat()
+	if err != nil {
+		return time.Time{}, 0, err
+	}
+	return st.ModTime(), st.Size(), nil
+}
+
 func open(name string) (*file, error) {
 	fd, err := os.Open(name)
 	if err != nil {
@@ -236,7 +244,7 @@
 }
 
 // trimSpace returns x without any leading or trailing ASCII whitespace.
-func trimSpace(x []byte) []byte {
+func trimSpace(x string) string {
 	for len(x) > 0 && isSpace(x[0]) {
 		x = x[1:]
 	}
@@ -253,37 +261,19 @@
 
 // removeComment returns line, removing any '#' byte and any following
 // bytes.
-func removeComment(line []byte) []byte {
-	if i := bytealg.IndexByte(line, '#'); i != -1 {
+func removeComment(line string) string {
+	if i := bytealg.IndexByteString(line, '#'); i != -1 {
 		return line[:i]
 	}
 	return line
 }
 
-// foreachLine runs fn on each line of x.
-// Each line (except for possibly the last) ends in '\n'.
-// It returns the first non-nil error returned by fn.
-func foreachLine(x []byte, fn func(line []byte) error) error {
-	for len(x) > 0 {
-		nl := bytealg.IndexByte(x, '\n')
-		if nl == -1 {
-			return fn(x)
-		}
-		line := x[:nl+1]
-		x = x[nl+1:]
-		if err := fn(line); err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
 // foreachField runs fn on each non-empty run of non-space bytes in x.
 // It returns the first non-nil error returned by fn.
-func foreachField(x []byte, fn func(field []byte) error) error {
+func foreachField(x string, fn func(field string) error) error {
 	x = trimSpace(x)
 	for len(x) > 0 {
-		sp := bytealg.IndexByte(x, ' ')
+		sp := bytealg.IndexByteString(x, ' ')
 		if sp == -1 {
 			return fn(x)
 		}
@@ -327,17 +317,3 @@
 	}
 	return true
 }
-
-func readFull(r io.Reader) (all []byte, err error) {
-	buf := make([]byte, 1024)
-	for {
-		n, err := r.Read(buf)
-		all = append(all, buf[:n]...)
-		if err == io.EOF {
-			return all, nil
-		}
-		if err != nil {
-			return nil, err
-		}
-	}
-}
diff --git a/src/net/resolverdialfunc_test.go b/src/net/resolverdialfunc_test.go
index 034c636..1fb02b1 100644
--- a/src/net/resolverdialfunc_test.go
+++ b/src/net/resolverdialfunc_test.go
@@ -213,7 +213,6 @@
 
 type resolverFuncConn struct {
 	h       *resolverDialHandler
-	ctx     context.Context
 	network string
 	address string
 	builder *dnsmessage.Builder
diff --git a/src/net/rpc/jsonrpc/all_test.go b/src/net/rpc/jsonrpc/all_test.go
index f4e1278..e2ccdfc 100644
--- a/src/net/rpc/jsonrpc/all_test.go
+++ b/src/net/rpc/jsonrpc/all_test.go
@@ -5,7 +5,6 @@
 package jsonrpc
 
 import (
-	"bytes"
 	"encoding/json"
 	"errors"
 	"fmt"
@@ -262,7 +261,7 @@
 }
 
 func TestServerErrorHasNullResult(t *testing.T) {
-	var out bytes.Buffer
+	var out strings.Builder
 	sc := NewServerCodec(struct {
 		io.Reader
 		io.Writer
diff --git a/src/net/sendfile_linux.go b/src/net/sendfile_linux.go
index e5150aa..0299fdc 100644
--- a/src/net/sendfile_linux.go
+++ b/src/net/sendfile_linux.go
@@ -13,8 +13,8 @@
 // sendFile copies the contents of r to c using the sendfile
 // system call to minimize copies.
 //
-// if handled == true, sendFile returns the number of bytes copied and any
-// non-EOF error.
+// if handled == true, sendFile returns the number (potentially zero) of bytes
+// copied and any non-EOF error.
 //
 // if handled == false, sendFile performed no work.
 func sendFile(c *netFD, r io.Reader) (written int64, err error, handled bool) {
@@ -39,7 +39,7 @@
 
 	var werr error
 	err = sc.Read(func(fd uintptr) bool {
-		written, werr = poll.SendFile(&c.pfd, int(fd), remain)
+		written, werr, handled = poll.SendFile(&c.pfd, int(fd), remain)
 		return true
 	})
 	if err == nil {
@@ -49,5 +49,5 @@
 	if lr != nil {
 		lr.N = remain - written
 	}
-	return written, wrapSyscallError("sendfile", err), written > 0
+	return written, wrapSyscallError("sendfile", err), handled
 }
diff --git a/src/net/sendfile_linux_test.go b/src/net/sendfile_linux_test.go
new file mode 100644
index 0000000..8cd6acc
--- /dev/null
+++ b/src/net/sendfile_linux_test.go
@@ -0,0 +1,77 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build linux
+// +build linux
+
+package net
+
+import (
+	"io"
+	"os"
+	"strconv"
+	"testing"
+)
+
+func BenchmarkSendFile(b *testing.B) {
+	for i := 0; i <= 10; i++ {
+		size := 1 << (i + 10)
+		bench := sendFileBench{chunkSize: size}
+		b.Run(strconv.Itoa(size), bench.benchSendFile)
+	}
+}
+
+type sendFileBench struct {
+	chunkSize int
+}
+
+func (bench sendFileBench) benchSendFile(b *testing.B) {
+	fileSize := b.N * bench.chunkSize
+	f := createTempFile(b, fileSize)
+	fileName := f.Name()
+	defer os.Remove(fileName)
+	defer f.Close()
+
+	client, server := spliceTestSocketPair(b, "tcp")
+	defer server.Close()
+
+	cleanUp, err := startSpliceClient(client, "r", bench.chunkSize, fileSize)
+	if err != nil {
+		b.Fatal(err)
+	}
+	defer cleanUp()
+
+	b.ReportAllocs()
+	b.SetBytes(int64(bench.chunkSize))
+	b.ResetTimer()
+
+	// Data go from file to socket via sendfile(2).
+	sent, err := io.Copy(server, f)
+	if err != nil {
+		b.Fatalf("failed to copy data with sendfile, error: %v", err)
+	}
+	if sent != int64(fileSize) {
+		b.Fatalf("bytes sent mismatch\n\texpect: %d\n\tgot: %d", fileSize, sent)
+	}
+}
+
+func createTempFile(b *testing.B, size int) *os.File {
+	f, err := os.CreateTemp("", "linux-sendfile-test")
+	if err != nil {
+		b.Fatalf("failed to create temporary file: %v", err)
+	}
+
+	data := make([]byte, size)
+	if _, err := f.Write(data); err != nil {
+		b.Fatalf("failed to create and feed the file: %v", err)
+	}
+	if err := f.Sync(); err != nil {
+		b.Fatalf("failed to save the file: %v", err)
+	}
+	if _, err := f.Seek(0, io.SeekStart); err != nil {
+		b.Fatalf("failed to rewind the file: %v", err)
+	}
+
+	return f
+}
diff --git a/src/net/sendfile_test.go b/src/net/sendfile_test.go
index 6edfb67..969c022 100644
--- a/src/net/sendfile_test.go
+++ b/src/net/sendfile_test.go
@@ -175,7 +175,7 @@
 				return
 			}
 			defer f.Close()
-			if _, err := f.Seek(seekTo, os.SEEK_SET); err != nil {
+			if _, err := f.Seek(seekTo, io.SeekStart); err != nil {
 				errc <- err
 				return
 			}
diff --git a/src/net/sendfile_unix_alt.go b/src/net/sendfile_unix_alt.go
index f99af92..b867717 100644
--- a/src/net/sendfile_unix_alt.go
+++ b/src/net/sendfile_unix_alt.go
@@ -20,7 +20,7 @@
 //
 // if handled == false, sendFile performed no work.
 func sendFile(c *netFD, r io.Reader) (written int64, err error, handled bool) {
-	// FreeBSD, DragonFly and Solaris use 0 as the "until EOF" value.
+	// Darwin, FreeBSD, DragonFly and Solaris use 0 as the "until EOF" value.
 	// If you pass in more bytes than the file contains, it will
 	// loop back to the beginning ad nauseam until it's sent
 	// exactly the number of bytes told to. As such, we need to
@@ -48,7 +48,7 @@
 		remain = fi.Size()
 	}
 
-	// The other quirk with FreeBSD/DragonFly/Solaris's sendfile
+	// The other quirk with Darwin/FreeBSD/DragonFly/Solaris's sendfile
 	// implementation is that it doesn't use the current position
 	// of the file -- if you pass it offset 0, it starts from
 	// offset 0. There's no way to tell it "start from current
diff --git a/src/net/smtp/auth.go b/src/net/smtp/auth.go
index 7a32ef6..72eb166 100644
--- a/src/net/smtp/auth.go
+++ b/src/net/smtp/auth.go
@@ -103,7 +103,7 @@
 		d := hmac.New(md5.New, []byte(a.secret))
 		d.Write(fromServer)
 		s := make([]byte, 0, d.Size())
-		return []byte(fmt.Sprintf("%s %x", a.username, d.Sum(s))), nil
+		return fmt.Appendf(nil, "%s %x", a.username, d.Sum(s)), nil
 	}
 	return nil, nil
 }
diff --git a/src/net/smtp/smtp.go b/src/net/smtp/smtp.go
index 3bd2061..b5a025e 100644
--- a/src/net/smtp/smtp.go
+++ b/src/net/smtp/smtp.go
@@ -423,7 +423,7 @@
 	return c.Text.Close()
 }
 
-// validateLine checks to see if a line has CR or LF as per RFC 5321
+// validateLine checks to see if a line has CR or LF as per RFC 5321.
 func validateLine(line string) error {
 	if strings.ContainsAny(line, "\n\r") {
 		return errors.New("smtp: A line must not contain CR or LF")
diff --git a/src/net/smtp/smtp_test.go b/src/net/smtp/smtp_test.go
index f23fd79..dba0744 100644
--- a/src/net/smtp/smtp_test.go
+++ b/src/net/smtp/smtp_test.go
@@ -113,7 +113,7 @@
 func TestClientAuthTrimSpace(t *testing.T) {
 	server := "220 hello world\r\n" +
 		"200 some more"
-	var wrote bytes.Buffer
+	var wrote strings.Builder
 	var fake faker
 	fake.ReadWriter = struct {
 		io.Reader
@@ -164,7 +164,7 @@
 	server := strings.Join(strings.Split(basicServer, "\n"), "\r\n")
 	client := strings.Join(strings.Split(basicClient, "\n"), "\r\n")
 
-	var cmdbuf bytes.Buffer
+	var cmdbuf strings.Builder
 	bcmdbuf := bufio.NewWriter(&cmdbuf)
 	var fake faker
 	fake.ReadWriter = bufio.NewReadWriter(bufio.NewReader(strings.NewReader(server)), bcmdbuf)
@@ -505,7 +505,7 @@
 	server := strings.Join(strings.Split(newClientServer, "\n"), "\r\n")
 	client := strings.Join(strings.Split(newClientClient, "\n"), "\r\n")
 
-	var cmdbuf bytes.Buffer
+	var cmdbuf strings.Builder
 	bcmdbuf := bufio.NewWriter(&cmdbuf)
 	out := func() string {
 		bcmdbuf.Flush()
@@ -550,7 +550,7 @@
 	server := strings.Join(strings.Split(newClient2Server, "\n"), "\r\n")
 	client := strings.Join(strings.Split(newClient2Client, "\n"), "\r\n")
 
-	var cmdbuf bytes.Buffer
+	var cmdbuf strings.Builder
 	bcmdbuf := bufio.NewWriter(&cmdbuf)
 	var fake faker
 	fake.ReadWriter = bufio.NewReadWriter(bufio.NewReader(strings.NewReader(server)), bcmdbuf)
@@ -643,7 +643,7 @@
 	for i := 0; i < len(helloServer); i++ {
 		server := strings.Join(strings.Split(baseHelloServer+helloServer[i], "\n"), "\r\n")
 		client := strings.Join(strings.Split(baseHelloClient+helloClient[i], "\n"), "\r\n")
-		var cmdbuf bytes.Buffer
+		var cmdbuf strings.Builder
 		bcmdbuf := bufio.NewWriter(&cmdbuf)
 		var fake faker
 		fake.ReadWriter = bufio.NewReadWriter(bufio.NewReader(strings.NewReader(server)), bcmdbuf)
@@ -749,7 +749,7 @@
 func TestSendMail(t *testing.T) {
 	server := strings.Join(strings.Split(sendMailServer, "\n"), "\r\n")
 	client := strings.Join(strings.Split(sendMailClient, "\n"), "\r\n")
-	var cmdbuf bytes.Buffer
+	var cmdbuf strings.Builder
 	bcmdbuf := bufio.NewWriter(&cmdbuf)
 	l, err := net.Listen("tcp", "127.0.0.1:0")
 	if err != nil {
@@ -906,7 +906,7 @@
 func TestAuthFailed(t *testing.T) {
 	server := strings.Join(strings.Split(authFailedServer, "\n"), "\r\n")
 	client := strings.Join(strings.Split(authFailedClient, "\n"), "\r\n")
-	var cmdbuf bytes.Buffer
+	var cmdbuf strings.Builder
 	bcmdbuf := bufio.NewWriter(&cmdbuf)
 	var fake faker
 	fake.ReadWriter = bufio.NewReadWriter(bufio.NewReader(strings.NewReader(server)), bcmdbuf)
diff --git a/src/net/sock_linux.go b/src/net/sock_linux.go
index 2513f9b..cffe9a2 100644
--- a/src/net/sock_linux.go
+++ b/src/net/sock_linux.go
@@ -4,42 +4,10 @@
 
 package net
 
-import "syscall"
-
-func kernelVersion() (major int, minor int) {
-	var uname syscall.Utsname
-	if err := syscall.Uname(&uname); err != nil {
-		return
-	}
-
-	rl := uname.Release
-	var values [2]int
-	vi := 0
-	value := 0
-	for _, c := range rl {
-		if c >= '0' && c <= '9' {
-			value = (value * 10) + int(c-'0')
-		} else {
-			// Note that we're assuming N.N.N here.  If we see anything else we are likely to
-			// mis-parse it.
-			values[vi] = value
-			vi++
-			if vi >= len(values) {
-				break
-			}
-			value = 0
-		}
-	}
-	switch vi {
-	case 0:
-		return 0, 0
-	case 1:
-		return values[0], 0
-	case 2:
-		return values[0], values[1]
-	}
-	return
-}
+import (
+	"internal/syscall/unix"
+	"syscall"
+)
 
 // Linux stores the backlog as:
 //
@@ -50,7 +18,7 @@
 //
 // See issue 5030 and 41470.
 func maxAckBacklog(n int) int {
-	major, minor := kernelVersion()
+	major, minor := unix.KernelVersion()
 	size := 16
 	if major > 4 || (major == 4 && minor >= 1) {
 		size = 32
diff --git a/src/net/sock_linux_test.go b/src/net/sock_linux_test.go
index 5df0293..11303cf 100644
--- a/src/net/sock_linux_test.go
+++ b/src/net/sock_linux_test.go
@@ -5,12 +5,13 @@
 package net
 
 import (
+	"internal/syscall/unix"
 	"testing"
 )
 
 func TestMaxAckBacklog(t *testing.T) {
 	n := 196602
-	major, minor := kernelVersion()
+	major, minor := unix.KernelVersion()
 	backlog := maxAckBacklog(n)
 	expected := 1<<16 - 1
 	if major > 4 || (major == 4 && minor >= 1) {
diff --git a/src/net/sock_posix.go b/src/net/sock_posix.go
index 4431c3a..b3e1806 100644
--- a/src/net/sock_posix.go
+++ b/src/net/sock_posix.go
@@ -15,7 +15,7 @@
 
 // socket returns a network file descriptor that is ready for
 // asynchronous I/O using the network poller.
-func socket(ctx context.Context, net string, family, sotype, proto int, ipv6only bool, laddr, raddr sockaddr, ctrlFn func(string, string, syscall.RawConn) error) (fd *netFD, err error) {
+func socket(ctx context.Context, net string, family, sotype, proto int, ipv6only bool, laddr, raddr sockaddr, ctrlCtxFn func(context.Context, string, string, syscall.RawConn) error) (fd *netFD, err error) {
 	s, err := sysSocket(family, sotype, proto)
 	if err != nil {
 		return nil, err
@@ -54,20 +54,20 @@
 	if laddr != nil && raddr == nil {
 		switch sotype {
 		case syscall.SOCK_STREAM, syscall.SOCK_SEQPACKET:
-			if err := fd.listenStream(laddr, listenerBacklog(), ctrlFn); err != nil {
+			if err := fd.listenStream(ctx, laddr, listenerBacklog(), ctrlCtxFn); err != nil {
 				fd.Close()
 				return nil, err
 			}
 			return fd, nil
 		case syscall.SOCK_DGRAM:
-			if err := fd.listenDatagram(laddr, ctrlFn); err != nil {
+			if err := fd.listenDatagram(ctx, laddr, ctrlCtxFn); err != nil {
 				fd.Close()
 				return nil, err
 			}
 			return fd, nil
 		}
 	}
-	if err := fd.dial(ctx, laddr, raddr, ctrlFn); err != nil {
+	if err := fd.dial(ctx, laddr, raddr, ctrlCtxFn); err != nil {
 		fd.Close()
 		return nil, err
 	}
@@ -113,9 +113,11 @@
 	return func(syscall.Sockaddr) Addr { return nil }
 }
 
-func (fd *netFD) dial(ctx context.Context, laddr, raddr sockaddr, ctrlFn func(string, string, syscall.RawConn) error) error {
-	if ctrlFn != nil {
-		c, err := newRawConn(fd)
+func (fd *netFD) dial(ctx context.Context, laddr, raddr sockaddr, ctrlCtxFn func(context.Context, string, string, syscall.RawConn) error) error {
+	var c *rawConn
+	var err error
+	if ctrlCtxFn != nil {
+		c, err = newRawConn(fd)
 		if err != nil {
 			return err
 		}
@@ -125,11 +127,11 @@
 		} else if laddr != nil {
 			ctrlAddr = laddr.String()
 		}
-		if err := ctrlFn(fd.ctrlNetwork(), ctrlAddr, c); err != nil {
+		if err := ctrlCtxFn(ctx, fd.ctrlNetwork(), ctrlAddr, c); err != nil {
 			return err
 		}
 	}
-	var err error
+
 	var lsa syscall.Sockaddr
 	if laddr != nil {
 		if lsa, err = laddr.sockaddr(fd.family); err != nil {
@@ -172,7 +174,7 @@
 	return nil
 }
 
-func (fd *netFD) listenStream(laddr sockaddr, backlog int, ctrlFn func(string, string, syscall.RawConn) error) error {
+func (fd *netFD) listenStream(ctx context.Context, laddr sockaddr, backlog int, ctrlCtxFn func(context.Context, string, string, syscall.RawConn) error) error {
 	var err error
 	if err = setDefaultListenerSockopts(fd.pfd.Sysfd); err != nil {
 		return err
@@ -181,15 +183,17 @@
 	if lsa, err = laddr.sockaddr(fd.family); err != nil {
 		return err
 	}
-	if ctrlFn != nil {
+
+	if ctrlCtxFn != nil {
 		c, err := newRawConn(fd)
 		if err != nil {
 			return err
 		}
-		if err := ctrlFn(fd.ctrlNetwork(), laddr.String(), c); err != nil {
+		if err := ctrlCtxFn(ctx, fd.ctrlNetwork(), laddr.String(), c); err != nil {
 			return err
 		}
 	}
+
 	if err = syscall.Bind(fd.pfd.Sysfd, lsa); err != nil {
 		return os.NewSyscallError("bind", err)
 	}
@@ -204,7 +208,7 @@
 	return nil
 }
 
-func (fd *netFD) listenDatagram(laddr sockaddr, ctrlFn func(string, string, syscall.RawConn) error) error {
+func (fd *netFD) listenDatagram(ctx context.Context, laddr sockaddr, ctrlCtxFn func(context.Context, string, string, syscall.RawConn) error) error {
 	switch addr := laddr.(type) {
 	case *UDPAddr:
 		// We provide a socket that listens to a wildcard
@@ -233,12 +237,13 @@
 	if lsa, err = laddr.sockaddr(fd.family); err != nil {
 		return err
 	}
-	if ctrlFn != nil {
+
+	if ctrlCtxFn != nil {
 		c, err := newRawConn(fd)
 		if err != nil {
 			return err
 		}
-		if err := ctrlFn(fd.ctrlNetwork(), laddr.String(), c); err != nil {
+		if err := ctrlCtxFn(ctx, fd.ctrlNetwork(), laddr.String(), c); err != nil {
 			return err
 		}
 	}
diff --git a/src/net/tcpsock.go b/src/net/tcpsock.go
index 6bad0e8..672170e 100644
--- a/src/net/tcpsock.go
+++ b/src/net/tcpsock.go
@@ -217,10 +217,19 @@
 	return nil
 }
 
-func newTCPConn(fd *netFD) *TCPConn {
-	c := &TCPConn{conn{fd}}
-	setNoDelay(c.fd, true)
-	return c
+func newTCPConn(fd *netFD, keepAlive time.Duration, keepAliveHook func(time.Duration)) *TCPConn {
+	setNoDelay(fd, true)
+	if keepAlive == 0 {
+		keepAlive = defaultTCPKeepAlive
+	}
+	if keepAlive > 0 {
+		setKeepAlive(fd, true)
+		setKeepAlivePeriod(fd, keepAlive)
+		if keepAliveHook != nil {
+			keepAliveHook(keepAlive)
+		}
+	}
+	return &TCPConn{conn{fd}}
 }
 
 // DialTCP acts like Dial for TCP networks.
diff --git a/src/net/tcpsock_plan9.go b/src/net/tcpsock_plan9.go
index 435335e..d55948f 100644
--- a/src/net/tcpsock_plan9.go
+++ b/src/net/tcpsock_plan9.go
@@ -42,7 +42,7 @@
 	if err != nil {
 		return nil, err
 	}
-	return newTCPConn(fd), nil
+	return newTCPConn(fd, sd.Dialer.KeepAlive, testHookSetKeepAlive), nil
 }
 
 func (ln *TCPListener) ok() bool { return ln != nil && ln.fd != nil && ln.fd.ctl != nil }
@@ -52,16 +52,7 @@
 	if err != nil {
 		return nil, err
 	}
-	tc := newTCPConn(fd)
-	if ln.lc.KeepAlive >= 0 {
-		setKeepAlive(fd, true)
-		ka := ln.lc.KeepAlive
-		if ln.lc.KeepAlive == 0 {
-			ka = defaultTCPKeepAlive
-		}
-		setKeepAlivePeriod(fd, ka)
-	}
-	return tc, nil
+	return newTCPConn(fd, ln.lc.KeepAlive, nil), nil
 }
 
 func (ln *TCPListener) close() error {
diff --git a/src/net/tcpsock_posix.go b/src/net/tcpsock_posix.go
index 1c91170..0b3fa1a 100644
--- a/src/net/tcpsock_posix.go
+++ b/src/net/tcpsock_posix.go
@@ -65,7 +65,13 @@
 }
 
 func (sd *sysDialer) doDialTCP(ctx context.Context, laddr, raddr *TCPAddr) (*TCPConn, error) {
-	fd, err := internetSocket(ctx, sd.network, laddr, raddr, syscall.SOCK_STREAM, 0, "dial", sd.Dialer.Control)
+	ctrlCtxFn := sd.Dialer.ControlContext
+	if ctrlCtxFn == nil && sd.Dialer.Control != nil {
+		ctrlCtxFn = func(cxt context.Context, network, address string, c syscall.RawConn) error {
+			return sd.Dialer.Control(network, address, c)
+		}
+	}
+	fd, err := internetSocket(ctx, sd.network, laddr, raddr, syscall.SOCK_STREAM, 0, "dial", ctrlCtxFn)
 
 	// TCP has a rarely used mechanism called a 'simultaneous connection' in
 	// which Dial("tcp", addr1, addr2) run on the machine at addr1 can
@@ -95,13 +101,13 @@
 		if err == nil {
 			fd.Close()
 		}
-		fd, err = internetSocket(ctx, sd.network, laddr, raddr, syscall.SOCK_STREAM, 0, "dial", sd.Dialer.Control)
+		fd, err = internetSocket(ctx, sd.network, laddr, raddr, syscall.SOCK_STREAM, 0, "dial", ctrlCtxFn)
 	}
 
 	if err != nil {
 		return nil, err
 	}
-	return newTCPConn(fd), nil
+	return newTCPConn(fd, sd.Dialer.KeepAlive, testHookSetKeepAlive), nil
 }
 
 func selfConnect(fd *netFD, err error) bool {
@@ -143,16 +149,7 @@
 	if err != nil {
 		return nil, err
 	}
-	tc := newTCPConn(fd)
-	if ln.lc.KeepAlive >= 0 {
-		setKeepAlive(fd, true)
-		ka := ln.lc.KeepAlive
-		if ln.lc.KeepAlive == 0 {
-			ka = defaultTCPKeepAlive
-		}
-		setKeepAlivePeriod(fd, ka)
-	}
-	return tc, nil
+	return newTCPConn(fd, ln.lc.KeepAlive, nil), nil
 }
 
 func (ln *TCPListener) close() error {
@@ -168,7 +165,13 @@
 }
 
 func (sl *sysListener) listenTCP(ctx context.Context, laddr *TCPAddr) (*TCPListener, error) {
-	fd, err := internetSocket(ctx, sl.network, laddr, nil, syscall.SOCK_STREAM, 0, "listen", sl.ListenConfig.Control)
+	var ctrlCtxFn func(cxt context.Context, network, address string, c syscall.RawConn) error
+	if sl.ListenConfig.Control != nil {
+		ctrlCtxFn = func(cxt context.Context, network, address string, c syscall.RawConn) error {
+			return sl.ListenConfig.Control(network, address, c)
+		}
+	}
+	fd, err := internetSocket(ctx, sl.network, laddr, nil, syscall.SOCK_STREAM, 0, "listen", ctrlCtxFn)
 	if err != nil {
 		return nil, err
 	}
diff --git a/src/net/tcpsock_test.go b/src/net/tcpsock_test.go
index ae65788..35a93d1 100644
--- a/src/net/tcpsock_test.go
+++ b/src/net/tcpsock_test.go
@@ -617,50 +617,6 @@
 	<-done
 }
 
-func TestTCPSelfConnect(t *testing.T) {
-	if runtime.GOOS == "windows" {
-		// TODO(brainman): do not know why it hangs.
-		t.Skip("known-broken test on windows")
-	}
-
-	ln := newLocalListener(t, "tcp")
-	var d Dialer
-	c, err := d.Dial(ln.Addr().Network(), ln.Addr().String())
-	if err != nil {
-		ln.Close()
-		t.Fatal(err)
-	}
-	network := c.LocalAddr().Network()
-	laddr := *c.LocalAddr().(*TCPAddr)
-	c.Close()
-	ln.Close()
-
-	// Try to connect to that address repeatedly.
-	n := 100000
-	if testing.Short() {
-		n = 1000
-	}
-	switch runtime.GOOS {
-	case "darwin", "ios", "dragonfly", "freebsd", "netbsd", "openbsd", "plan9", "illumos", "solaris", "windows":
-		// Non-Linux systems take a long time to figure
-		// out that there is nothing listening on localhost.
-		n = 100
-	}
-	for i := 0; i < n; i++ {
-		d.Timeout = time.Millisecond
-		c, err := d.Dial(network, laddr.String())
-		if err == nil {
-			addr := c.LocalAddr().(*TCPAddr)
-			if addr.Port == laddr.Port || addr.IP.Equal(laddr.IP) {
-				t.Errorf("Dial %v should fail", addr)
-			} else {
-				t.Logf("Dial %v succeeded - possibly racing with other listener", addr)
-			}
-			c.Close()
-		}
-	}
-}
-
 // Test that >32-bit reads work on 64-bit systems.
 // On 32-bit systems this tests that maxint reads work.
 func TestTCPBig(t *testing.T) {
@@ -808,3 +764,22 @@
 		deadline = deadline.Add(1)
 	}
 }
+
+func TestDialTCPDefaultKeepAlive(t *testing.T) {
+	ln := newLocalListener(t, "tcp")
+	defer ln.Close()
+
+	got := time.Duration(-1)
+	testHookSetKeepAlive = func(d time.Duration) { got = d }
+	defer func() { testHookSetKeepAlive = func(time.Duration) {} }()
+
+	c, err := DialTCP("tcp", nil, ln.Addr().(*TCPAddr))
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer c.Close()
+
+	if got != defaultTCPKeepAlive {
+		t.Errorf("got keepalive %v; want %v", got, defaultTCPKeepAlive)
+	}
+}
diff --git a/src/net/testdata/aliases b/src/net/testdata/aliases
new file mode 100644
index 0000000..9330ba0
--- /dev/null
+++ b/src/net/testdata/aliases
@@ -0,0 +1,8 @@
+127.0.0.1 test
+127.0.0.2 test2.example.com 2.test
+127.0.0.3 3.test test3.example.com
+127.0.0.4 example.com
+127.0.0.5 test4.example.com 4.test 5.test test5.example.com
+
+# must be a non resolvable domain on the internet
+127.0.1.1 invalid.test invalid.invalid
diff --git a/src/net/testdata/search-single-dot-resolv.conf b/src/net/testdata/search-single-dot-resolv.conf
new file mode 100644
index 0000000..934cd3e
--- /dev/null
+++ b/src/net/testdata/search-single-dot-resolv.conf
@@ -0,0 +1,5 @@
+# /etc/resolv.conf
+
+domain localdomain
+search .
+nameserver 8.8.8.8
diff --git a/src/net/textproto/reader.go b/src/net/textproto/reader.go
index 1f7afc5..8e80008 100644
--- a/src/net/textproto/reader.go
+++ b/src/net/textproto/reader.go
@@ -7,8 +7,10 @@
 import (
 	"bufio"
 	"bytes"
+	"errors"
 	"fmt"
 	"io"
+	"math"
 	"strconv"
 	"strings"
 	"sync"
@@ -42,9 +44,7 @@
 func (r *Reader) ReadLineBytes() ([]byte, error) {
 	line, err := r.readLineSlice()
 	if line != nil {
-		buf := make([]byte, len(line))
-		copy(buf, line)
-		line = buf
+		line = bytes.Clone(line)
 	}
 	return line, err
 }
@@ -111,9 +111,7 @@
 func (r *Reader) ReadContinuedLineBytes() ([]byte, error) {
 	line, err := r.readContinuedLineSlice(noValidation)
 	if line != nil {
-		buf := make([]byte, len(line))
-		copy(buf, line)
-		line = buf
+		line = bytes.Clone(line)
 	}
 	return line, err
 }
@@ -481,6 +479,12 @@
 //		"Long-Key": {"Even Longer Value"},
 //	}
 func (r *Reader) ReadMIMEHeader() (MIMEHeader, error) {
+	return readMIMEHeader(r, math.MaxInt64)
+}
+
+// readMIMEHeader is a version of ReadMIMEHeader which takes a limit on the header size.
+// It is called by the mime/multipart package.
+func readMIMEHeader(r *Reader, lim int64) (MIMEHeader, error) {
 	// Avoid lots of small slice allocations later by allocating one
 	// large one ahead of time which we'll cut up into smaller
 	// slices. If this isn't big enough later, we allocate small ones.
@@ -512,7 +516,15 @@
 		if !ok {
 			return m, ProtocolError("malformed MIME header line: " + string(kv))
 		}
-		key := canonicalMIMEHeaderKey(k)
+		key, ok := canonicalMIMEHeaderKey(k)
+		if !ok {
+			return m, ProtocolError("malformed MIME header line: " + string(kv))
+		}
+		for _, c := range v {
+			if !validHeaderValueByte(c) {
+				return m, ProtocolError("malformed MIME header line: " + string(kv))
+			}
+		}
 
 		// As per RFC 7230 field-name is a token, tokens consist of one or more chars.
 		// We could return a ProtocolError here, but better to be liberal in what we
@@ -522,9 +534,19 @@
 		}
 
 		// Skip initial spaces in value.
-		value := strings.TrimLeft(string(v), " \t")
+		value := string(bytes.TrimLeft(v, " \t"))
 
 		vv := m[key]
+		if vv == nil {
+			lim -= int64(len(key))
+			lim -= 100 // map entry overhead
+		}
+		lim -= int64(len(value))
+		if lim < 0 {
+			// TODO: This should be a distinguishable error (ErrMessageTooLarge)
+			// to allow mime/multipart to detect it.
+			return m, errors.New("message too large")
+		}
 		if vv == nil && len(strs) > 0 {
 			// More than likely this will be a single-element key.
 			// Most headers aren't multi-valued.
@@ -589,10 +611,12 @@
 			return s
 		}
 		if upper && 'a' <= c && c <= 'z' {
-			return canonicalMIMEHeaderKey([]byte(s))
+			s, _ = canonicalMIMEHeaderKey([]byte(s))
+			return s
 		}
 		if !upper && 'A' <= c && c <= 'Z' {
-			return canonicalMIMEHeaderKey([]byte(s))
+			s, _ = canonicalMIMEHeaderKey([]byte(s))
+			return s
 		}
 		upper = c == '-'
 	}
@@ -601,7 +625,7 @@
 
 const toLower = 'a' - 'A'
 
-// validHeaderFieldByte reports whether b is a valid byte in a header
+// validHeaderFieldByte reports whether c is a valid byte in a header
 // field name. RFC 7230 says:
 //
 //	header-field   = field-name ":" OWS field-value OWS
@@ -609,8 +633,58 @@
 //	tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." /
 //	        "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA
 //	token = 1*tchar
-func validHeaderFieldByte(b byte) bool {
-	return int(b) < len(isTokenTable) && isTokenTable[b]
+func validHeaderFieldByte(c byte) bool {
+	// mask is a 128-bit bitmap with 1s for allowed bytes,
+	// so that the byte c can be tested with a shift and an and.
+	// If c >= 128, then 1<<c and 1<<(c-64) will both be zero,
+	// and this function will return false.
+	const mask = 0 |
+		(1<<(10)-1)<<'0' |
+		(1<<(26)-1)<<'a' |
+		(1<<(26)-1)<<'A' |
+		1<<'!' |
+		1<<'#' |
+		1<<'$' |
+		1<<'%' |
+		1<<'&' |
+		1<<'\'' |
+		1<<'*' |
+		1<<'+' |
+		1<<'-' |
+		1<<'.' |
+		1<<'^' |
+		1<<'_' |
+		1<<'`' |
+		1<<'|' |
+		1<<'~'
+	return ((uint64(1)<<c)&(mask&(1<<64-1)) |
+		(uint64(1)<<(c-64))&(mask>>64)) != 0
+}
+
+// validHeaderValueByte reports whether c is a valid byte in a header
+// field value. RFC 7230 says:
+//
+//	field-content  = field-vchar [ 1*( SP / HTAB ) field-vchar ]
+//	field-vchar    = VCHAR / obs-text
+//	obs-text       = %x80-FF
+//
+// RFC 5234 says:
+//
+//	HTAB           =  %x09
+//	SP             =  %x20
+//	VCHAR          =  %x21-7E
+func validHeaderValueByte(c byte) bool {
+	// mask is a 128-bit bitmap with 1s for allowed bytes,
+	// so that the byte c can be tested with a shift and an and.
+	// If c >= 128, then 1<<c and 1<<(c-64) will both be zero.
+	// Since this is the obs-text range, we invert the mask to
+	// create a bitmap with 1s for disallowed bytes.
+	const mask = 0 |
+		(1<<(0x7f-0x21)-1)<<0x21 | // VCHAR: %x21-7E
+		1<<0x20 | // SP: %x20
+		1<<0x09 // HTAB: %x09
+	return ((uint64(1)<<c)&^(mask&(1<<64-1)) |
+		(uint64(1)<<(c-64))&^(mask>>64)) == 0
 }
 
 // canonicalMIMEHeaderKey is like CanonicalMIMEHeaderKey but is
@@ -619,14 +693,29 @@
 //
 // For invalid inputs (if a contains spaces or non-token bytes), a
 // is unchanged and a string copy is returned.
-func canonicalMIMEHeaderKey(a []byte) string {
+//
+// ok is true if the header key contains only valid characters and spaces.
+// ReadMIMEHeader accepts header keys containing spaces, but does not
+// canonicalize them.
+func canonicalMIMEHeaderKey(a []byte) (_ string, ok bool) {
 	// See if a looks like a header key. If not, return it unchanged.
+	noCanon := false
 	for _, c := range a {
 		if validHeaderFieldByte(c) {
 			continue
 		}
 		// Don't canonicalize.
-		return string(a)
+		if c == ' ' {
+			// We accept invalid headers with a space before the
+			// colon, but must not canonicalize them.
+			// See https://go.dev/issue/34540.
+			noCanon = true
+			continue
+		}
+		return string(a), false
+	}
+	if noCanon {
+		return string(a), true
 	}
 
 	upper := true
@@ -648,9 +737,9 @@
 	// case, so a copy of a's bytes into a new string does not
 	// happen in this map lookup:
 	if v := commonHeader[string(a)]; v != "" {
-		return v
+		return v, true
 	}
-	return string(a)
+	return string(a), true
 }
 
 // commonHeader interns common header strings.
@@ -704,85 +793,3 @@
 		commonHeader[v] = v
 	}
 }
-
-// isTokenTable is a copy of net/http/lex.go's isTokenTable.
-// See https://httpwg.github.io/specs/rfc7230.html#rule.token.separators
-var isTokenTable = [127]bool{
-	'!':  true,
-	'#':  true,
-	'$':  true,
-	'%':  true,
-	'&':  true,
-	'\'': true,
-	'*':  true,
-	'+':  true,
-	'-':  true,
-	'.':  true,
-	'0':  true,
-	'1':  true,
-	'2':  true,
-	'3':  true,
-	'4':  true,
-	'5':  true,
-	'6':  true,
-	'7':  true,
-	'8':  true,
-	'9':  true,
-	'A':  true,
-	'B':  true,
-	'C':  true,
-	'D':  true,
-	'E':  true,
-	'F':  true,
-	'G':  true,
-	'H':  true,
-	'I':  true,
-	'J':  true,
-	'K':  true,
-	'L':  true,
-	'M':  true,
-	'N':  true,
-	'O':  true,
-	'P':  true,
-	'Q':  true,
-	'R':  true,
-	'S':  true,
-	'T':  true,
-	'U':  true,
-	'W':  true,
-	'V':  true,
-	'X':  true,
-	'Y':  true,
-	'Z':  true,
-	'^':  true,
-	'_':  true,
-	'`':  true,
-	'a':  true,
-	'b':  true,
-	'c':  true,
-	'd':  true,
-	'e':  true,
-	'f':  true,
-	'g':  true,
-	'h':  true,
-	'i':  true,
-	'j':  true,
-	'k':  true,
-	'l':  true,
-	'm':  true,
-	'n':  true,
-	'o':  true,
-	'p':  true,
-	'q':  true,
-	'r':  true,
-	's':  true,
-	't':  true,
-	'u':  true,
-	'v':  true,
-	'w':  true,
-	'x':  true,
-	'y':  true,
-	'z':  true,
-	'|':  true,
-	'~':  true,
-}
diff --git a/src/net/textproto/reader_test.go b/src/net/textproto/reader_test.go
index d11d40f..9618b87 100644
--- a/src/net/textproto/reader_test.go
+++ b/src/net/textproto/reader_test.go
@@ -189,16 +189,62 @@
 		"Foo-\r\n\tBar: foo\r\n\r\n",
 		"Foo\r\n\t: foo\r\n\r\n",
 		"Foo-\n\tBar",
+		"Foo \tBar: foo\r\n\r\n",
 	}
-
 	for _, input := range inputs {
 		r := reader(input)
-		if m, err := r.ReadMIMEHeader(); err == nil {
+		if m, err := r.ReadMIMEHeader(); err == nil || err == io.EOF {
 			t.Errorf("ReadMIMEHeader(%q) = %v, %v; want nil, err", input, m, err)
 		}
 	}
 }
 
+func TestReadMIMEHeaderBytes(t *testing.T) {
+	for i := 0; i <= 0xff; i++ {
+		s := "Foo" + string(rune(i)) + "Bar: foo\r\n\r\n"
+		r := reader(s)
+		wantErr := true
+		switch {
+		case i >= '0' && i <= '9':
+			wantErr = false
+		case i >= 'a' && i <= 'z':
+			wantErr = false
+		case i >= 'A' && i <= 'Z':
+			wantErr = false
+		case i == '!' || i == '#' || i == '$' || i == '%' || i == '&' || i == '\'' || i == '*' || i == '+' || i == '-' || i == '.' || i == '^' || i == '_' || i == '`' || i == '|' || i == '~':
+			wantErr = false
+		case i == ':':
+			// Special case: "Foo:Bar: foo" is the header "Foo".
+			wantErr = false
+		case i == ' ':
+			wantErr = false
+		}
+		m, err := r.ReadMIMEHeader()
+		if err != nil != wantErr {
+			t.Errorf("ReadMIMEHeader(%q) = %v, %v; want error=%v", s, m, err, wantErr)
+		}
+	}
+	for i := 0; i <= 0xff; i++ {
+		s := "Foo: foo" + string(rune(i)) + "bar\r\n\r\n"
+		r := reader(s)
+		wantErr := true
+		switch {
+		case i >= 0x21 && i <= 0x7e:
+			wantErr = false
+		case i == ' ':
+			wantErr = false
+		case i == '\t':
+			wantErr = false
+		case i >= 0x80 && i <= 0xff:
+			wantErr = false
+		}
+		m, err := r.ReadMIMEHeader()
+		if (err != nil) != wantErr {
+			t.Errorf("ReadMIMEHeader(%q) = %v, %v; want error=%v", s, m, err, wantErr)
+		}
+	}
+}
+
 // Test that continued lines are properly trimmed. Issue 11204.
 func TestReadMIMEHeaderTrimContinued(t *testing.T) {
 	// In this header, \n and \r\n terminated lines are mixed on purpose.
@@ -317,7 +363,7 @@
 	b := []byte("content-Length")
 	want := "Content-Length"
 	n := testing.AllocsPerRun(200, func() {
-		if x := canonicalMIMEHeaderKey(b); x != want {
+		if x, _ := canonicalMIMEHeaderKey(b); x != want {
 			t.Fatalf("canonicalMIMEHeaderKey(%q) = %q; want %q", b, x, want)
 		}
 	})
diff --git a/src/net/textproto/writer_test.go b/src/net/textproto/writer_test.go
index 2afef11..8f11b10 100644
--- a/src/net/textproto/writer_test.go
+++ b/src/net/textproto/writer_test.go
@@ -6,12 +6,12 @@
 
 import (
 	"bufio"
-	"bytes"
+	"strings"
 	"testing"
 )
 
 func TestPrintfLine(t *testing.T) {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	w := NewWriter(bufio.NewWriter(&buf))
 	err := w.PrintfLine("foo %d", 123)
 	if s := buf.String(); s != "foo 123\r\n" || err != nil {
@@ -20,7 +20,7 @@
 }
 
 func TestDotWriter(t *testing.T) {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	w := NewWriter(bufio.NewWriter(&buf))
 	d := w.DotWriter()
 	n, err := d.Write([]byte("abc\n.def\n..ghi\n.jkl\n."))
@@ -35,7 +35,7 @@
 }
 
 func TestDotWriterCloseEmptyWrite(t *testing.T) {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	w := NewWriter(bufio.NewWriter(&buf))
 	d := w.DotWriter()
 	n, err := d.Write([]byte{})
@@ -50,7 +50,7 @@
 }
 
 func TestDotWriterCloseNoWrite(t *testing.T) {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	w := NewWriter(bufio.NewWriter(&buf))
 	d := w.DotWriter()
 	d.Close()
diff --git a/src/net/timeout_test.go b/src/net/timeout_test.go
index 52ddf8c..832f40f 100644
--- a/src/net/timeout_test.go
+++ b/src/net/timeout_test.go
@@ -908,24 +908,10 @@
 	testVariousDeadlines(t)
 }
 
-type neverEnding byte
-
-func (b neverEnding) Read(p []byte) (int, error) {
-	for i := range p {
-		p[i] = byte(b)
-	}
-	return len(p), nil
-}
-
 func testVariousDeadlines(t *testing.T) {
 	if runtime.GOOS == "plan9" {
 		t.Skip("skipping test on plan9; see golang.org/issue/26945")
 	}
-	type result struct {
-		n   int64
-		err error
-		d   time.Duration
-	}
 
 	handler := func(ls *localServer, ln Listener) {
 		for {
diff --git a/src/net/udpsock_posix.go b/src/net/udpsock_posix.go
index 5b021d2..ffeec81 100644
--- a/src/net/udpsock_posix.go
+++ b/src/net/udpsock_posix.go
@@ -203,7 +203,13 @@
 }
 
 func (sd *sysDialer) dialUDP(ctx context.Context, laddr, raddr *UDPAddr) (*UDPConn, error) {
-	fd, err := internetSocket(ctx, sd.network, laddr, raddr, syscall.SOCK_DGRAM, 0, "dial", sd.Dialer.Control)
+	ctrlCtxFn := sd.Dialer.ControlContext
+	if ctrlCtxFn == nil && sd.Dialer.Control != nil {
+		ctrlCtxFn = func(cxt context.Context, network, address string, c syscall.RawConn) error {
+			return sd.Dialer.Control(network, address, c)
+		}
+	}
+	fd, err := internetSocket(ctx, sd.network, laddr, raddr, syscall.SOCK_DGRAM, 0, "dial", ctrlCtxFn)
 	if err != nil {
 		return nil, err
 	}
@@ -211,7 +217,13 @@
 }
 
 func (sl *sysListener) listenUDP(ctx context.Context, laddr *UDPAddr) (*UDPConn, error) {
-	fd, err := internetSocket(ctx, sl.network, laddr, nil, syscall.SOCK_DGRAM, 0, "listen", sl.ListenConfig.Control)
+	var ctrlCtxFn func(cxt context.Context, network, address string, c syscall.RawConn) error
+	if sl.ListenConfig.Control != nil {
+		ctrlCtxFn = func(cxt context.Context, network, address string, c syscall.RawConn) error {
+			return sl.ListenConfig.Control(network, address, c)
+		}
+	}
+	fd, err := internetSocket(ctx, sl.network, laddr, nil, syscall.SOCK_DGRAM, 0, "listen", ctrlCtxFn)
 	if err != nil {
 		return nil, err
 	}
@@ -219,7 +231,13 @@
 }
 
 func (sl *sysListener) listenMulticastUDP(ctx context.Context, ifi *Interface, gaddr *UDPAddr) (*UDPConn, error) {
-	fd, err := internetSocket(ctx, sl.network, gaddr, nil, syscall.SOCK_DGRAM, 0, "listen", sl.ListenConfig.Control)
+	var ctrlCtxFn func(cxt context.Context, network, address string, c syscall.RawConn) error
+	if sl.ListenConfig.Control != nil {
+		ctrlCtxFn = func(cxt context.Context, network, address string, c syscall.RawConn) error {
+			return sl.ListenConfig.Control(network, address, c)
+		}
+	}
+	fd, err := internetSocket(ctx, sl.network, gaddr, nil, syscall.SOCK_DGRAM, 0, "listen", ctrlCtxFn)
 	if err != nil {
 		return nil, err
 	}
diff --git a/src/net/udpsock_test.go b/src/net/udpsock_test.go
index 4fa7475..0ed2ff9 100644
--- a/src/net/udpsock_test.go
+++ b/src/net/udpsock_test.go
@@ -464,12 +464,9 @@
 		// Plan9 wasn't optimized.
 		t.Skipf("skipping on %v", runtime.GOOS)
 	}
-	builder := os.Getenv("GO_BUILDER_NAME")
-	switch builder {
-	case "linux-amd64-noopt":
-		// Optimizations are required to remove the allocs.
-		t.Skipf("skipping on %v", builder)
-	}
+	// Optimizations are required to remove the allocs.
+	testenv.SkipIfOptimizationOff(t)
+
 	conn, err := ListenUDP("udp4", &UDPAddr{IP: IPv4(127, 0, 0, 1)})
 	if err != nil {
 		t.Fatal(err)
@@ -633,7 +630,9 @@
 	}
 
 	switch runtime.GOOS {
-	case "openbsd":
+	case "dragonfly", "openbsd":
+		// DragonflyBSD's IPv6 sockets are always IPv6-only, according to the man page:
+		// https://www.dragonflybsd.org/cgi/web-man?command=ip6 (search for IPV6_V6ONLY).
 		// OpenBSD's IPv6 sockets are always IPv6-only, according to the man page:
 		// https://man.openbsd.org/ip6#IPV6_V6ONLY
 		t.Skipf("skipping on %v", runtime.GOOS)
diff --git a/src/net/unixsock_posix.go b/src/net/unixsock_posix.go
index b244dbd..c16b483 100644
--- a/src/net/unixsock_posix.go
+++ b/src/net/unixsock_posix.go
@@ -13,7 +13,7 @@
 	"syscall"
 )
 
-func unixSocket(ctx context.Context, net string, laddr, raddr sockaddr, mode string, ctrlFn func(string, string, syscall.RawConn) error) (*netFD, error) {
+func unixSocket(ctx context.Context, net string, laddr, raddr sockaddr, mode string, ctxCtrlFn func(context.Context, string, string, syscall.RawConn) error) (*netFD, error) {
 	var sotype int
 	switch net {
 	case "unix":
@@ -42,7 +42,7 @@
 		return nil, errors.New("unknown mode: " + mode)
 	}
 
-	fd, err := socket(ctx, net, syscall.AF_UNIX, sotype, 0, false, laddr, raddr, ctrlFn)
+	fd, err := socket(ctx, net, syscall.AF_UNIX, sotype, 0, false, laddr, raddr, ctxCtrlFn)
 	if err != nil {
 		return nil, err
 	}
@@ -155,7 +155,13 @@
 }
 
 func (sd *sysDialer) dialUnix(ctx context.Context, laddr, raddr *UnixAddr) (*UnixConn, error) {
-	fd, err := unixSocket(ctx, sd.network, laddr, raddr, "dial", sd.Dialer.Control)
+	ctrlCtxFn := sd.Dialer.ControlContext
+	if ctrlCtxFn == nil && sd.Dialer.Control != nil {
+		ctrlCtxFn = func(cxt context.Context, network, address string, c syscall.RawConn) error {
+			return sd.Dialer.Control(network, address, c)
+		}
+	}
+	fd, err := unixSocket(ctx, sd.network, laddr, raddr, "dial", ctrlCtxFn)
 	if err != nil {
 		return nil, err
 	}
@@ -211,7 +217,13 @@
 }
 
 func (sl *sysListener) listenUnix(ctx context.Context, laddr *UnixAddr) (*UnixListener, error) {
-	fd, err := unixSocket(ctx, sl.network, laddr, nil, "listen", sl.ListenConfig.Control)
+	var ctrlCtxFn func(cxt context.Context, network, address string, c syscall.RawConn) error
+	if sl.ListenConfig.Control != nil {
+		ctrlCtxFn = func(cxt context.Context, network, address string, c syscall.RawConn) error {
+			return sl.ListenConfig.Control(network, address, c)
+		}
+	}
+	fd, err := unixSocket(ctx, sl.network, laddr, nil, "listen", ctrlCtxFn)
 	if err != nil {
 		return nil, err
 	}
@@ -219,7 +231,13 @@
 }
 
 func (sl *sysListener) listenUnixgram(ctx context.Context, laddr *UnixAddr) (*UnixConn, error) {
-	fd, err := unixSocket(ctx, sl.network, laddr, nil, "listen", sl.ListenConfig.Control)
+	var ctrlCtxFn func(cxt context.Context, network, address string, c syscall.RawConn) error
+	if sl.ListenConfig.Control != nil {
+		ctrlCtxFn = func(cxt context.Context, network, address string, c syscall.RawConn) error {
+			return sl.ListenConfig.Control(network, address, c)
+		}
+	}
+	fd, err := unixSocket(ctx, sl.network, laddr, nil, "listen", ctrlCtxFn)
 	if err != nil {
 		return nil, err
 	}
diff --git a/src/net/url/url.go b/src/net/url/url.go
index e82ae6a..d530a50 100644
--- a/src/net/url/url.go
+++ b/src/net/url/url.go
@@ -351,11 +351,14 @@
 // Note that the Path field is stored in decoded form: /%47%6f%2f becomes /Go/.
 // A consequence is that it is impossible to tell which slashes in the Path were
 // slashes in the raw URL and which were %2f. This distinction is rarely important,
-// but when it is, the code should use RawPath, an optional field which only gets
-// set if the default encoding is different from Path.
+// but when it is, the code should use the EscapedPath method, which preserves
+// the original encoding of Path.
 //
-// URL's String method uses the EscapedPath method to obtain the path. See the
-// EscapedPath method for more details.
+// The RawPath field is an optional field which is only set when the default
+// encoding of Path is different from the escaped path. See the EscapedPath method
+// for more details.
+//
+// URL's String method uses the EscapedPath method to obtain the path.
 type URL struct {
 	Scheme      string
 	Opaque      string    // encoded opaque data
@@ -1191,17 +1194,23 @@
 // any existing path and the resulting path cleaned of any ./ or ../ elements.
 // Any sequences of multiple / characters will be reduced to a single /.
 func (u *URL) JoinPath(elem ...string) *URL {
-	url := *u
-	if len(elem) > 0 {
-		elem = append([]string{u.EscapedPath()}, elem...)
-		p := path.Join(elem...)
-		// path.Join will remove any trailing slashes.
-		// Preserve at least one.
-		if strings.HasSuffix(elem[len(elem)-1], "/") && !strings.HasSuffix(p, "/") {
-			p += "/"
-		}
-		url.setPath(p)
+	elem = append([]string{u.EscapedPath()}, elem...)
+	var p string
+	if !strings.HasPrefix(elem[0], "/") {
+		// Return a relative path if u is relative,
+		// but ensure that it contains no ../ elements.
+		elem[0] = "/" + elem[0]
+		p = path.Join(elem...)[1:]
+	} else {
+		p = path.Join(elem...)
 	}
+	// path.Join will remove any trailing slashes.
+	// Preserve at least one.
+	if strings.HasSuffix(elem[len(elem)-1], "/") && !strings.HasSuffix(p, "/") {
+		p += "/"
+	}
+	url := *u
+	url.setPath(p)
 	return &url
 }
 
diff --git a/src/net/url/url_test.go b/src/net/url/url_test.go
index 263eddf..577cf63 100644
--- a/src/net/url/url_test.go
+++ b/src/net/url/url_test.go
@@ -2082,6 +2082,26 @@
 		},
 		{
 			base: "https://go.googlesource.com/",
+			elem: []string{"../go"},
+			out:  "https://go.googlesource.com/go",
+		},
+		{
+			base: "https://go.googlesource.com",
+			elem: []string{"../go"},
+			out:  "https://go.googlesource.com/go",
+		},
+		{
+			base: "https://go.googlesource.com",
+			elem: []string{"../go", "../../go", "../../../go"},
+			out:  "https://go.googlesource.com/go",
+		},
+		{
+			base: "https://go.googlesource.com/../go",
+			elem: nil,
+			out:  "https://go.googlesource.com/go",
+		},
+		{
+			base: "https://go.googlesource.com/",
 			elem: []string{"./go"},
 			out:  "https://go.googlesource.com/go",
 		},
@@ -2112,7 +2132,7 @@
 		{
 			base: "https://go.googlesource.com",
 			elem: nil,
-			out:  "https://go.googlesource.com",
+			out:  "https://go.googlesource.com/",
 		},
 		{
 			base: "https://go.googlesource.com/",
@@ -2130,10 +2150,45 @@
 			out:  "https://go.googlesource.com/a%2fb/c%2fd",
 		},
 		{
+			base: "https://go.googlesource.com/a/b",
+			elem: []string{"/go"},
+			out:  "https://go.googlesource.com/a/b/go",
+		},
+		{
 			base: "/",
 			elem: nil,
 			out:  "/",
 		},
+		{
+			base: "a",
+			elem: nil,
+			out:  "a",
+		},
+		{
+			base: "a",
+			elem: []string{"b"},
+			out:  "a/b",
+		},
+		{
+			base: "a",
+			elem: []string{"../b"},
+			out:  "b",
+		},
+		{
+			base: "a",
+			elem: []string{"../../b"},
+			out:  "b",
+		},
+		{
+			base: "",
+			elem: []string{"a"},
+			out:  "a",
+		},
+		{
+			base: "",
+			elem: []string{"../a"},
+			out:  "a",
+		},
 	}
 	for _, tt := range tests {
 		wantErr := "nil"
diff --git a/src/net/writev_test.go b/src/net/writev_test.go
index 18795a4..c4efe9d 100644
--- a/src/net/writev_test.go
+++ b/src/net/writev_test.go
@@ -153,7 +153,7 @@
 
 		var wantSum int
 		switch runtime.GOOS {
-		case "android", "darwin", "ios", "dragonfly", "freebsd", "illumos", "linux", "netbsd", "openbsd":
+		case "aix", "android", "darwin", "ios", "dragonfly", "freebsd", "illumos", "linux", "netbsd", "openbsd", "solaris":
 			var wantMinCalls int
 			wantSum = want.Len()
 			v := chunks
diff --git a/src/net/writev_unix.go b/src/net/writev_unix.go
index 51ab29d..3b0325b 100644
--- a/src/net/writev_unix.go
+++ b/src/net/writev_unix.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build darwin || dragonfly || freebsd || illumos || linux || netbsd || openbsd
+//go:build unix
 
 package net
 
diff --git a/src/os/dir_windows.go b/src/os/dir_windows.go
index 253adad..445e4f7 100644
--- a/src/os/dir_windows.go
+++ b/src/os/dir_windows.go
@@ -11,8 +11,15 @@
 )
 
 func (file *File) readdir(n int, mode readdirMode) (names []string, dirents []DirEntry, infos []FileInfo, err error) {
-	if !file.isdir() {
-		return nil, nil, nil, &PathError{Op: "readdir", Path: file.name, Err: syscall.ENOTDIR}
+	// If this file has no dirinfo, create one.
+	needdata := true
+	if file.dirinfo == nil {
+		needdata = false
+		file.dirinfo, err = openDir(file.name)
+		if err != nil {
+			err = &PathError{Op: "readdir", Path: file.name, Err: err}
+			return
+		}
 	}
 	wantAll := n <= 0
 	if wantAll {
@@ -20,8 +27,8 @@
 	}
 	d := &file.dirinfo.data
 	for n != 0 && !file.dirinfo.isempty {
-		if file.dirinfo.needdata {
-			e := file.pfd.FindNextFile(d)
+		if needdata {
+			e := syscall.FindNextFile(file.dirinfo.h, d)
 			runtime.KeepAlive(file)
 			if e != nil {
 				if e == syscall.ERROR_NO_MORE_FILES {
@@ -32,7 +39,7 @@
 				}
 			}
 		}
-		file.dirinfo.needdata = true
+		needdata = true
 		name := syscall.UTF16ToString(d.FileName[0:])
 		if name == "." || name == ".." { // Useless names
 			continue
diff --git a/src/os/env.go b/src/os/env.go
index 330297b..63ad5ab 100644
--- a/src/os/env.go
+++ b/src/os/env.go
@@ -61,7 +61,7 @@
 	return false
 }
 
-// isAlphaNum reports whether the byte is an ASCII letter, number, or underscore
+// isAlphaNum reports whether the byte is an ASCII letter, number, or underscore.
 func isAlphaNum(c uint8) bool {
 	return c == '_' || '0' <= c && c <= '9' || 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z'
 }
diff --git a/src/os/error.go b/src/os/error.go
index fe8f2a8..9827446 100644
--- a/src/os/error.go
+++ b/src/os/error.go
@@ -5,7 +5,6 @@
 package os
 
 import (
-	"internal/oserror"
 	"internal/poll"
 	"io/fs"
 )
@@ -28,7 +27,6 @@
 	ErrDeadlineExceeded = errDeadlineExceeded() // "i/o timeout"
 )
 
-func errClosed() error     { return oserror.ErrClosed }
 func errNoDeadline() error { return poll.ErrNoDeadline }
 
 // errDeadlineExceeded returns the value for os.ErrDeadlineExceeded.
diff --git a/src/os/exec.go b/src/os/exec.go
index 9eb3166..d01ca59 100644
--- a/src/os/exec.go
+++ b/src/os/exec.go
@@ -21,7 +21,7 @@
 type Process struct {
 	Pid    int
 	handle uintptr      // handle is accessed atomically on Windows
-	isdone uint32       // process has been successfully waited on, non zero if true
+	isdone atomic.Bool  // process has been successfully waited on
 	sigMu  sync.RWMutex // avoid race between wait and signal
 }
 
@@ -32,11 +32,11 @@
 }
 
 func (p *Process) setDone() {
-	atomic.StoreUint32(&p.isdone, 1)
+	p.isdone.Store(true)
 }
 
 func (p *Process) done() bool {
-	return atomic.LoadUint32(&p.isdone) > 0
+	return p.isdone.Load()
 }
 
 // ProcAttr holds the attributes that will be applied to a new process
diff --git a/src/os/exec/dot_test.go b/src/os/exec/dot_test.go
index 306f98c..66c92f7 100644
--- a/src/os/exec/dot_test.go
+++ b/src/os/exec/dot_test.go
@@ -24,6 +24,7 @@
 
 func TestLookPath(t *testing.T) {
 	testenv.MustHaveExec(t)
+	// Not parallel: uses os.Chdir and t.Setenv.
 
 	tmpDir := filepath.Join(t.TempDir(), "testdir")
 	if err := os.Mkdir(tmpDir, 0777); err != nil {
@@ -58,7 +59,7 @@
 	// And try to trick it with "../testdir" too.
 	for _, errdot := range []string{"1", "0"} {
 		t.Run("GODEBUG=execerrdot="+errdot, func(t *testing.T) {
-			t.Setenv("GODEBUG", "execerrdot="+errdot)
+			t.Setenv("GODEBUG", "execerrdot="+errdot+",execwait=2")
 			for _, dir := range []string{".", "../testdir"} {
 				t.Run(pathVar+"="+dir, func(t *testing.T) {
 					t.Setenv(pathVar, dir+string(filepath.ListSeparator)+origPath)
diff --git a/src/os/exec/env_test.go b/src/os/exec/env_test.go
index 112f1e6..ea06af3 100644
--- a/src/os/exec/env_test.go
+++ b/src/os/exec/env_test.go
@@ -10,10 +10,14 @@
 )
 
 func TestDedupEnv(t *testing.T) {
+	t.Parallel()
+
 	tests := []struct {
-		noCase bool
-		in     []string
-		want   []string
+		noCase  bool
+		nulOK   bool
+		in      []string
+		want    []string
+		wantErr bool
 	}{
 		{
 			noCase: true,
@@ -41,11 +45,23 @@
 			in:   []string{"dodgy", "entries"},
 			want: []string{"dodgy", "entries"},
 		},
+		{
+			// Filter out entries containing NULs.
+			in:      []string{"A=a\x00b", "B=b", "C\x00C=c"},
+			want:    []string{"B=b"},
+			wantErr: true,
+		},
+		{
+			// Plan 9 needs to preserve environment variables with NUL (#56544).
+			nulOK: true,
+			in:    []string{"path=one\x00two"},
+			want:  []string{"path=one\x00two"},
+		},
 	}
 	for _, tt := range tests {
-		got := dedupEnvCase(tt.noCase, tt.in)
-		if !reflect.DeepEqual(got, tt.want) {
-			t.Errorf("Dedup(%v, %q) = %q; want %q", tt.noCase, tt.in, got, tt.want)
+		got, err := dedupEnvCase(tt.noCase, tt.nulOK, tt.in)
+		if !reflect.DeepEqual(got, tt.want) || (err != nil) != tt.wantErr {
+			t.Errorf("Dedup(%v, %q) = %q, %v; want %q, error:%v", tt.noCase, tt.in, got, err, tt.want, tt.wantErr)
 		}
 	}
 }
diff --git a/src/os/exec/example_test.go b/src/os/exec/example_test.go
index bb166ce..150f5cf 100644
--- a/src/os/exec/example_test.go
+++ b/src/os/exec/example_test.go
@@ -5,7 +5,6 @@
 package exec_test
 
 import (
-	"bytes"
 	"context"
 	"encoding/json"
 	"fmt"
@@ -28,7 +27,7 @@
 func ExampleCommand() {
 	cmd := exec.Command("tr", "a-z", "A-Z")
 	cmd.Stdin = strings.NewReader("some input")
-	var out bytes.Buffer
+	var out strings.Builder
 	cmd.Stdout = &out
 	err := cmd.Run()
 	if err != nil {
diff --git a/src/os/exec/exec.go b/src/os/exec/exec.go
index 737aaab..2f4bdff 100644
--- a/src/os/exec/exec.go
+++ b/src/os/exec/exec.go
@@ -94,6 +94,7 @@
 	"bytes"
 	"context"
 	"errors"
+	"internal/godebug"
 	"internal/syscall/execenv"
 	"io"
 	"os"
@@ -101,8 +102,8 @@
 	"runtime"
 	"strconv"
 	"strings"
-	"sync"
 	"syscall"
+	"time"
 )
 
 // Error is returned by LookPath when it fails to classify a file as an
@@ -120,6 +121,11 @@
 
 func (e *Error) Unwrap() error { return e.Err }
 
+// ErrWaitDelay is returned by (*Cmd).Wait if the process exits with a
+// successful status code but its output pipes are not closed before the
+// command's WaitDelay expires.
+var ErrWaitDelay = errors.New("exec: WaitDelay expired before I/O complete")
+
 // wrappedError wraps an error without relying on fmt.Errorf.
 type wrappedError struct {
 	prefix string
@@ -178,7 +184,8 @@
 	// goroutine reads from Stdin and delivers that data to the command
 	// over a pipe. In this case, Wait does not complete until the goroutine
 	// stops copying, either because it has reached the end of Stdin
-	// (EOF or a read error) or because writing to the pipe returned an error.
+	// (EOF or a read error), or because writing to the pipe returned an error,
+	// or because a nonzero WaitDelay was set and expired.
 	Stdin io.Reader
 
 	// Stdout and Stderr specify the process's standard output and error.
@@ -192,7 +199,8 @@
 	// Otherwise, during the execution of the command a separate goroutine
 	// reads from the process over a pipe and delivers that data to the
 	// corresponding Writer. In this case, Wait does not complete until the
-	// goroutine reaches EOF or encounters an error.
+	// goroutine reaches EOF or encounters an error or a nonzero WaitDelay
+	// expires.
 	//
 	// If Stdout and Stderr are the same writer, and have a type that can
 	// be compared with ==, at most one goroutine at a time will call Write.
@@ -213,18 +221,98 @@
 	// Process is the underlying process, once started.
 	Process *os.Process
 
-	// ProcessState contains information about an exited process,
-	// available after a call to Wait or Run.
+	// ProcessState contains information about an exited process.
+	// If the process was started successfully, Wait or Run will
+	// populate its ProcessState when the command completes.
 	ProcessState *os.ProcessState
 
-	ctx             context.Context // nil means none
-	Err             error           // LookPath error, if any.
-	childFiles      []*os.File
-	closeAfterStart []io.Closer
-	closeAfterWait  []io.Closer
-	goroutine       []func() error
-	goroutineErrs   <-chan error // one receive per goroutine
-	ctxErr          <-chan error // if non nil, receives the error from watchCtx exactly once
+	// ctx is the context passed to CommandContext, if any.
+	ctx context.Context
+
+	Err error // LookPath error, if any.
+
+	// If Cancel is non-nil, the command must have been created with
+	// CommandContext and Cancel will be called when the command's
+	// Context is done. By default, CommandContext sets Cancel to
+	// call the Kill method on the command's Process.
+	//
+	// Typically a custom Cancel will send a signal to the command's
+	// Process, but it may instead take other actions to initiate cancellation,
+	// such as closing a stdin or stdout pipe or sending a shutdown request on a
+	// network socket.
+	//
+	// If the command exits with a success status after Cancel is
+	// called, and Cancel does not return an error equivalent to
+	// os.ErrProcessDone, then Wait and similar methods will return a non-nil
+	// error: either an error wrapping the one returned by Cancel,
+	// or the error from the Context.
+	// (If the command exits with a non-success status, or Cancel
+	// returns an error that wraps os.ErrProcessDone, Wait and similar methods
+	// continue to return the command's usual exit status.)
+	//
+	// If Cancel is set to nil, nothing will happen immediately when the command's
+	// Context is done, but a nonzero WaitDelay will still take effect. That may
+	// be useful, for example, to work around deadlocks in commands that do not
+	// support shutdown signals but are expected to always finish quickly.
+	//
+	// Cancel will not be called if Start returns a non-nil error.
+	Cancel func() error
+
+	// If WaitDelay is non-zero, it bounds the time spent waiting on two sources
+	// of unexpected delay in Wait: a child process that fails to exit after the
+	// associated Context is canceled, and a child process that exits but leaves
+	// its I/O pipes unclosed.
+	//
+	// The WaitDelay timer starts when either the associated Context is done or a
+	// call to Wait observes that the child process has exited, whichever occurs
+	// first. When the delay has elapsed, the command shuts down the child process
+	// and/or its I/O pipes.
+	//
+	// If the child process has failed to exit — perhaps because it ignored or
+	// failed to receive a shutdown signal from a Cancel function, or because no
+	// Cancel function was set — then it will be terminated using os.Process.Kill.
+	//
+	// Then, if the I/O pipes communicating with the child process are still open,
+	// those pipes are closed in order to unblock any goroutines currently blocked
+	// on Read or Write calls.
+	//
+	// If pipes are closed due to WaitDelay, no Cancel call has occurred,
+	// and the command has otherwise exited with a successful status, Wait and
+	// similar methods will return ErrWaitDelay instead of nil.
+	//
+	// If WaitDelay is zero (the default), I/O pipes will be read until EOF,
+	// which might not occur until orphaned subprocesses of the command have
+	// also closed their descriptors for the pipes.
+	WaitDelay time.Duration
+
+	// childIOFiles holds closers for any of the child process's
+	// stdin, stdout, and/or stderr files that were opened by the Cmd itself
+	// (not supplied by the caller). These should be closed as soon as they
+	// are inherited by the child process.
+	childIOFiles []io.Closer
+
+	// parentIOPipes holds closers for the parent's end of any pipes
+	// connected to the child's stdin, stdout, and/or stderr streams
+	// that were opened by the Cmd itself (not supplied by the caller).
+	// These should be closed after Wait sees the command and copying
+	// goroutines exit, or after WaitDelay has expired.
+	parentIOPipes []io.Closer
+
+	// goroutine holds a set of closures to execute to copy data
+	// to and/or from the command's I/O pipes.
+	goroutine []func() error
+
+	// If goroutineErr is non-nil, it receives the first error from a copying
+	// goroutine once all such goroutines have completed.
+	// goroutineErr is set to nil once its error has been received.
+	goroutineErr <-chan error
+
+	// If ctxResult is non-nil, it receives the result of watchCtx exactly once.
+	ctxResult <-chan ctxResult
+
+	// The stack saved when the Command was created, if GODEBUG contains
+	// execwait=2. Used for debugging leaks.
+	createdByStack []byte
 
 	// For a security release long ago, we created x/sys/execabs,
 	// which manipulated the unexported lookPathErr error field
@@ -246,6 +334,23 @@
 	lookPathErr error
 }
 
+// A ctxResult reports the result of watching the Context associated with a
+// running command (and sending corresponding signals if needed).
+type ctxResult struct {
+	err error
+
+	// If timer is non-nil, it expires after WaitDelay has elapsed after
+	// the Context is done.
+	//
+	// (If timer is nil, that means that the Context was not done before the
+	// command completed, or no WaitDelay was set, or the WaitDelay already
+	// expired and its effect was already applied.)
+	timer *time.Timer
+}
+
+var execwait = godebug.New("execwait")
+var execerrdot = godebug.New("execerrdot")
+
 // Command returns the Cmd struct to execute the named program with
 // the given arguments.
 //
@@ -273,6 +378,43 @@
 		Path: name,
 		Args: append([]string{name}, arg...),
 	}
+
+	if v := execwait.Value(); v != "" {
+		if v == "2" {
+			// Obtain the caller stack. (This is equivalent to runtime/debug.Stack,
+			// copied to avoid importing the whole package.)
+			stack := make([]byte, 1024)
+			for {
+				n := runtime.Stack(stack, false)
+				if n < len(stack) {
+					stack = stack[:n]
+					break
+				}
+				stack = make([]byte, 2*len(stack))
+			}
+
+			if i := bytes.Index(stack, []byte("\nos/exec.Command(")); i >= 0 {
+				stack = stack[i+1:]
+			}
+			cmd.createdByStack = stack
+		}
+
+		runtime.SetFinalizer(cmd, func(c *Cmd) {
+			if c.Process != nil && c.ProcessState == nil {
+				debugHint := ""
+				if c.createdByStack == nil {
+					debugHint = " (set GODEBUG=execwait=2 to capture stacks for debugging)"
+				} else {
+					os.Stderr.WriteString("GODEBUG=execwait=2 detected a leaked exec.Cmd created by:\n")
+					os.Stderr.Write(c.createdByStack)
+					os.Stderr.WriteString("\n")
+					debugHint = ""
+				}
+				panic("exec: Cmd started a Process but leaked without a call to Wait" + debugHint)
+			}
+		})
+	}
+
 	if filepath.Base(name) == name {
 		lp, err := LookPath(name)
 		if lp != "" {
@@ -290,15 +432,22 @@
 
 // CommandContext is like Command but includes a context.
 //
-// The provided context is used to kill the process (by calling
-// os.Process.Kill) if the context becomes done before the command
-// completes on its own.
+// The provided context is used to interrupt the process
+// (by calling cmd.Cancel or os.Process.Kill)
+// if the context becomes done before the command completes on its own.
+//
+// CommandContext sets the command's Cancel function to invoke the Kill method
+// on its Process, and leaves its WaitDelay unset. The caller may change the
+// cancellation behavior by modifying those fields before starting the command.
 func CommandContext(ctx context.Context, name string, arg ...string) *Cmd {
 	if ctx == nil {
 		panic("nil Context")
 	}
 	cmd := Command(name, arg...)
 	cmd.ctx = ctx
+	cmd.Cancel = func() error {
+		return cmd.Process.Kill()
+	}
 	return cmd
 }
 
@@ -337,14 +486,14 @@
 	return []string{c.Path}
 }
 
-func (c *Cmd) stdin() (f *os.File, err error) {
+func (c *Cmd) childStdin() (*os.File, error) {
 	if c.Stdin == nil {
-		f, err = os.Open(os.DevNull)
+		f, err := os.Open(os.DevNull)
 		if err != nil {
-			return
+			return nil, err
 		}
-		c.closeAfterStart = append(c.closeAfterStart, f)
-		return
+		c.childIOFiles = append(c.childIOFiles, f)
+		return f, nil
 	}
 
 	if f, ok := c.Stdin.(*os.File); ok {
@@ -353,11 +502,11 @@
 
 	pr, pw, err := os.Pipe()
 	if err != nil {
-		return
+		return nil, err
 	}
 
-	c.closeAfterStart = append(c.closeAfterStart, pr)
-	c.closeAfterWait = append(c.closeAfterWait, pw)
+	c.childIOFiles = append(c.childIOFiles, pr)
+	c.parentIOPipes = append(c.parentIOPipes, pw)
 	c.goroutine = append(c.goroutine, func() error {
 		_, err := io.Copy(pw, c.Stdin)
 		if skipStdinCopyError(err) {
@@ -371,25 +520,29 @@
 	return pr, nil
 }
 
-func (c *Cmd) stdout() (f *os.File, err error) {
+func (c *Cmd) childStdout() (*os.File, error) {
 	return c.writerDescriptor(c.Stdout)
 }
 
-func (c *Cmd) stderr() (f *os.File, err error) {
+func (c *Cmd) childStderr(childStdout *os.File) (*os.File, error) {
 	if c.Stderr != nil && interfaceEqual(c.Stderr, c.Stdout) {
-		return c.childFiles[1], nil
+		return childStdout, nil
 	}
 	return c.writerDescriptor(c.Stderr)
 }
 
-func (c *Cmd) writerDescriptor(w io.Writer) (f *os.File, err error) {
+// writerDescriptor returns an os.File to which the child process
+// can write to send data to w.
+//
+// If w is nil, writerDescriptor returns a File that writes to os.DevNull.
+func (c *Cmd) writerDescriptor(w io.Writer) (*os.File, error) {
 	if w == nil {
-		f, err = os.OpenFile(os.DevNull, os.O_WRONLY, 0)
+		f, err := os.OpenFile(os.DevNull, os.O_WRONLY, 0)
 		if err != nil {
-			return
+			return nil, err
 		}
-		c.closeAfterStart = append(c.closeAfterStart, f)
-		return
+		c.childIOFiles = append(c.childIOFiles, f)
+		return f, nil
 	}
 
 	if f, ok := w.(*os.File); ok {
@@ -398,11 +551,11 @@
 
 	pr, pw, err := os.Pipe()
 	if err != nil {
-		return
+		return nil, err
 	}
 
-	c.closeAfterStart = append(c.closeAfterStart, pw)
-	c.closeAfterWait = append(c.closeAfterWait, pr)
+	c.childIOFiles = append(c.childIOFiles, pw)
+	c.parentIOPipes = append(c.parentIOPipes, pr)
 	c.goroutine = append(c.goroutine, func() error {
 		_, err := io.Copy(w, pr)
 		pr.Close() // in case io.Copy stopped due to write error
@@ -411,7 +564,7 @@
 	return pw, nil
 }
 
-func (c *Cmd) closeDescriptors(closers []io.Closer) {
+func closeDescriptors(closers []io.Closer) {
 	for _, fd := range closers {
 		fd.Close()
 	}
@@ -470,12 +623,27 @@
 // After a successful call to Start the Wait method must be called in
 // order to release associated system resources.
 func (c *Cmd) Start() error {
+	// Check for doubled Start calls before we defer failure cleanup. If the prior
+	// call to Start succeeded, we don't want to spuriously close its pipes.
+	if c.Process != nil {
+		return errors.New("exec: already started")
+	}
+
+	started := false
+	defer func() {
+		closeDescriptors(c.childIOFiles)
+		c.childIOFiles = nil
+
+		if !started {
+			closeDescriptors(c.parentIOPipes)
+			c.parentIOPipes = nil
+		}
+	}()
+
 	if c.Path == "" && c.Err == nil && c.lookPathErr == nil {
 		c.Err = errors.New("exec: no command")
 	}
 	if c.Err != nil || c.lookPathErr != nil {
-		c.closeDescriptors(c.closeAfterStart)
-		c.closeDescriptors(c.closeAfterWait)
 		if c.lookPathErr != nil {
 			return c.lookPathErr
 		}
@@ -484,37 +652,38 @@
 	if runtime.GOOS == "windows" {
 		lp, err := lookExtensions(c.Path, c.Dir)
 		if err != nil {
-			c.closeDescriptors(c.closeAfterStart)
-			c.closeDescriptors(c.closeAfterWait)
 			return err
 		}
 		c.Path = lp
 	}
-	if c.Process != nil {
-		return errors.New("exec: already started")
+	if c.Cancel != nil && c.ctx == nil {
+		return errors.New("exec: command with a non-nil Cancel was not created with CommandContext")
 	}
 	if c.ctx != nil {
 		select {
 		case <-c.ctx.Done():
-			c.closeDescriptors(c.closeAfterStart)
-			c.closeDescriptors(c.closeAfterWait)
 			return c.ctx.Err()
 		default:
 		}
 	}
 
-	c.childFiles = make([]*os.File, 0, 3+len(c.ExtraFiles))
-	type F func(*Cmd) (*os.File, error)
-	for _, setupFd := range []F{(*Cmd).stdin, (*Cmd).stdout, (*Cmd).stderr} {
-		fd, err := setupFd(c)
-		if err != nil {
-			c.closeDescriptors(c.closeAfterStart)
-			c.closeDescriptors(c.closeAfterWait)
-			return err
-		}
-		c.childFiles = append(c.childFiles, fd)
+	childFiles := make([]*os.File, 0, 3+len(c.ExtraFiles))
+	stdin, err := c.childStdin()
+	if err != nil {
+		return err
 	}
-	c.childFiles = append(c.childFiles, c.ExtraFiles...)
+	childFiles = append(childFiles, stdin)
+	stdout, err := c.childStdout()
+	if err != nil {
+		return err
+	}
+	childFiles = append(childFiles, stdout)
+	stderr, err := c.childStderr(stdout)
+	if err != nil {
+		return err
+	}
+	childFiles = append(childFiles, stderr)
+	childFiles = append(childFiles, c.ExtraFiles...)
 
 	env, err := c.environ()
 	if err != nil {
@@ -523,32 +692,153 @@
 
 	c.Process, err = os.StartProcess(c.Path, c.argv(), &os.ProcAttr{
 		Dir:   c.Dir,
-		Files: c.childFiles,
+		Files: childFiles,
 		Env:   env,
 		Sys:   c.SysProcAttr,
 	})
 	if err != nil {
-		c.closeDescriptors(c.closeAfterStart)
-		c.closeDescriptors(c.closeAfterWait)
 		return err
 	}
+	started = true
 
-	c.closeDescriptors(c.closeAfterStart)
-
-	// Don't allocate the goroutineErrs channel unless there are goroutines to fire.
+	// Don't allocate the goroutineErr channel unless there are goroutines to start.
 	if len(c.goroutine) > 0 {
-		errc := make(chan error, len(c.goroutine))
-		c.goroutineErrs = errc
+		goroutineErr := make(chan error, 1)
+		c.goroutineErr = goroutineErr
+
+		type goroutineStatus struct {
+			running  int
+			firstErr error
+		}
+		statusc := make(chan goroutineStatus, 1)
+		statusc <- goroutineStatus{running: len(c.goroutine)}
 		for _, fn := range c.goroutine {
 			go func(fn func() error) {
-				errc <- fn()
+				err := fn()
+
+				status := <-statusc
+				if status.firstErr == nil {
+					status.firstErr = err
+				}
+				status.running--
+				if status.running == 0 {
+					goroutineErr <- status.firstErr
+				} else {
+					statusc <- status
+				}
 			}(fn)
 		}
+		c.goroutine = nil // Allow the goroutines' closures to be GC'd when they complete.
+	}
+
+	// If we have anything to do when the command's Context expires,
+	// start a goroutine to watch for cancellation.
+	//
+	// (Even if the command was created by CommandContext, a helper library may
+	// have explicitly set its Cancel field back to nil, indicating that it should
+	// be allowed to continue running after cancellation after all.)
+	if (c.Cancel != nil || c.WaitDelay != 0) && c.ctx != nil && c.ctx.Done() != nil {
+		resultc := make(chan ctxResult)
+		c.ctxResult = resultc
+		go c.watchCtx(resultc)
+	}
+
+	return nil
+}
+
+// watchCtx watches c.ctx until it is able to send a result to resultc.
+//
+// If c.ctx is done before a result can be sent, watchCtx calls c.Cancel,
+// and/or kills cmd.Process it after c.WaitDelay has elapsed.
+//
+// watchCtx manipulates c.goroutineErr, so its result must be received before
+// c.awaitGoroutines is called.
+func (c *Cmd) watchCtx(resultc chan<- ctxResult) {
+	select {
+	case resultc <- ctxResult{}:
+		return
+	case <-c.ctx.Done():
+	}
+
+	var err error
+	if c.Cancel != nil {
+		if interruptErr := c.Cancel(); interruptErr == nil {
+			// We appear to have successfully interrupted the command, so any
+			// program behavior from this point may be due to ctx even if the
+			// command exits with code 0.
+			err = c.ctx.Err()
+		} else if errors.Is(interruptErr, os.ErrProcessDone) {
+			// The process already finished: we just didn't notice it yet.
+			// (Perhaps c.Wait hadn't been called, or perhaps it happened to race with
+			// c.ctx being cancelled.) Don't inject a needless error.
+		} else {
+			err = wrappedError{
+				prefix: "exec: canceling Cmd",
+				err:    interruptErr,
+			}
+		}
+	}
+	if c.WaitDelay == 0 {
+		resultc <- ctxResult{err: err}
+		return
+	}
+
+	timer := time.NewTimer(c.WaitDelay)
+	select {
+	case resultc <- ctxResult{err: err, timer: timer}:
+		// c.Process.Wait returned and we've handed the timer off to c.Wait.
+		// It will take care of goroutine shutdown from here.
+		return
+	case <-timer.C:
+	}
+
+	killed := false
+	if killErr := c.Process.Kill(); killErr == nil {
+		// We appear to have killed the process. c.Process.Wait should return a
+		// non-nil error to c.Wait unless the Kill signal races with a successful
+		// exit, and if that does happen we shouldn't report a spurious error,
+		// so don't set err to anything here.
+		killed = true
+	} else if !errors.Is(killErr, os.ErrProcessDone) {
+		err = wrappedError{
+			prefix: "exec: killing Cmd",
+			err:    killErr,
+		}
 	}
 
-	c.ctxErr = c.watchCtx()
+	if c.goroutineErr != nil {
+		select {
+		case goroutineErr := <-c.goroutineErr:
+			// Forward goroutineErr only if we don't have reason to believe it was
+			// caused by a call to Cancel or Kill above.
+			if err == nil && !killed {
+				err = goroutineErr
+			}
+		default:
+			// Close the child process's I/O pipes, in case it abandoned some
+			// subprocess that inherited them and is still holding them open
+			// (see https://go.dev/issue/23019).
+			//
+			// We close the goroutine pipes only after we have sent any signals we're
+			// going to send to the process (via Signal or Kill above): if we send
+			// SIGKILL to the process, we would prefer for it to die of SIGKILL, not
+			// SIGPIPE. (However, this may still cause any orphaned subprocesses to
+			// terminate with SIGPIPE.)
+			closeDescriptors(c.parentIOPipes)
+			// Wait for the copying goroutines to finish, but report ErrWaitDelay for
+			// the error: any other error here could result from closing the pipes.
+			_ = <-c.goroutineErr
+			if err == nil {
+				err = ErrWaitDelay
+			}
+		}
 
-	return nil
+		// Since we have already received the only result from c.goroutineErr,
+		// set it to nil to prevent awaitGoroutines from blocking on it.
+		c.goroutineErr = nil
+	}
+
+	resultc <- ctxResult{err: err}
 }
 
 // An ExitError reports an unsuccessful exit by a command.
@@ -596,76 +886,84 @@
 	if c.ProcessState != nil {
 		return errors.New("exec: Wait was already called")
 	}
+
 	state, err := c.Process.Wait()
 	if err == nil && !state.Success() {
 		err = &ExitError{ProcessState: state}
 	}
 	c.ProcessState = state
 
-	// Wait for the pipe-copying goroutines to complete.
-	var copyError error
-	for range c.goroutine {
-		if err := <-c.goroutineErrs; err != nil && copyError == nil {
-			copyError = err
-		}
-	}
-	c.goroutine = nil // Allow the goroutines' closures to be GC'd.
-
-	if c.ctxErr != nil {
-		interruptErr := <-c.ctxErr
+	var timer *time.Timer
+	if c.ctxResult != nil {
+		watch := <-c.ctxResult
+		timer = watch.timer
 		// If c.Process.Wait returned an error, prefer that.
-		// Otherwise, report any error from the interrupt goroutine.
-		if interruptErr != nil && err == nil {
-			err = interruptErr
+		// Otherwise, report any error from the watchCtx goroutine,
+		// such as a Context cancellation or a WaitDelay overrun.
+		if err == nil && watch.err != nil {
+			err = watch.err
 		}
 	}
-	// Report errors from the copying goroutines only if the program otherwise
-	// exited normally on its own. Otherwise, the copying error may be due to the
-	// abnormal termination.
-	if err == nil {
-		err = copyError
-	}
 
-	c.closeDescriptors(c.closeAfterWait)
-	c.closeAfterWait = nil
+	if goroutineErr := c.awaitGoroutines(timer); err == nil {
+		// Report an error from the copying goroutines only if the program otherwise
+		// exited normally on its own. Otherwise, the copying error may be due to the
+		// abnormal termination.
+		err = goroutineErr
+	}
+	closeDescriptors(c.parentIOPipes)
+	c.parentIOPipes = nil
 
 	return err
 }
 
-// watchCtx conditionally starts a goroutine that waits until either c.ctx is
-// done or c.Process.Wait has completed (called from Wait).
-// If c.ctx is done first, the goroutine terminates c.Process.
+// awaitGoroutines waits for the results of the goroutines copying data to or
+// from the command's I/O pipes.
 //
-// If a goroutine was started, watchCtx returns a channel on which its result
-// must be received.
-func (c *Cmd) watchCtx() <-chan error {
-	if c.ctx == nil {
-		return nil
-	}
-
-	errc := make(chan error)
-	go func() {
-		select {
-		case errc <- nil:
-			return
-		case <-c.ctx.Done():
+// If c.WaitDelay elapses before the goroutines complete, awaitGoroutines
+// forcibly closes their pipes and returns ErrWaitDelay.
+//
+// If timer is non-nil, it must send to timer.C at the end of c.WaitDelay.
+func (c *Cmd) awaitGoroutines(timer *time.Timer) error {
+	defer func() {
+		if timer != nil {
+			timer.Stop()
 		}
-
-		var err error
-		if killErr := c.Process.Kill(); killErr == nil {
-			// We appear to have successfully delivered a kill signal, so any
-			// program behavior from this point may be due to ctx.
-			err = c.ctx.Err()
-		} else if !errors.Is(killErr, os.ErrProcessDone) {
-			err = wrappedError{
-				prefix: "exec: error sending signal to Cmd",
-				err:    killErr,
-			}
-		}
-		errc <- err
+		c.goroutineErr = nil
 	}()
 
-	return errc
+	if c.goroutineErr == nil {
+		return nil // No running goroutines to await.
+	}
+
+	if timer == nil {
+		if c.WaitDelay == 0 {
+			return <-c.goroutineErr
+		}
+
+		select {
+		case err := <-c.goroutineErr:
+			// Avoid the overhead of starting a timer.
+			return err
+		default:
+		}
+
+		// No existing timer was started: either there is no Context associated with
+		// the command, or c.Process.Wait completed before the Context was done.
+		timer = time.NewTimer(c.WaitDelay)
+	}
+
+	select {
+	case <-timer.C:
+		closeDescriptors(c.parentIOPipes)
+		// Wait for the copying goroutines to finish, but ignore any error
+		// (since it was probably caused by closing the pipes).
+		_ = <-c.goroutineErr
+		return ErrWaitDelay
+
+	case err := <-c.goroutineErr:
+		return err
+	}
 }
 
 // Output runs the command and returns its standard output.
@@ -726,26 +1024,9 @@
 		return nil, err
 	}
 	c.Stdin = pr
-	c.closeAfterStart = append(c.closeAfterStart, pr)
-	wc := &closeOnce{File: pw}
-	c.closeAfterWait = append(c.closeAfterWait, wc)
-	return wc, nil
-}
-
-type closeOnce struct {
-	*os.File
-
-	once sync.Once
-	err  error
-}
-
-func (c *closeOnce) Close() error {
-	c.once.Do(c.close)
-	return c.err
-}
-
-func (c *closeOnce) close() {
-	c.err = c.File.Close()
+	c.childIOFiles = append(c.childIOFiles, pr)
+	c.parentIOPipes = append(c.parentIOPipes, pw)
+	return pw, nil
 }
 
 // StdoutPipe returns a pipe that will be connected to the command's
@@ -768,8 +1049,8 @@
 		return nil, err
 	}
 	c.Stdout = pw
-	c.closeAfterStart = append(c.closeAfterStart, pw)
-	c.closeAfterWait = append(c.closeAfterWait, pr)
+	c.childIOFiles = append(c.childIOFiles, pw)
+	c.parentIOPipes = append(c.parentIOPipes, pr)
 	return pr, nil
 }
 
@@ -793,8 +1074,8 @@
 		return nil, err
 	}
 	c.Stderr = pw
-	c.closeAfterStart = append(c.closeAfterStart, pw)
-	c.closeAfterWait = append(c.closeAfterWait, pr)
+	c.childIOFiles = append(c.childIOFiles, pw)
+	c.parentIOPipes = append(c.parentIOPipes, pr)
 	return pr, nil
 }
 
@@ -912,7 +1193,11 @@
 		}
 	}
 
-	return addCriticalEnv(dedupEnv(env)), err
+	env, dedupErr := dedupEnv(env)
+	if err == nil {
+		err = dedupErr
+	}
+	return addCriticalEnv(env), err
 }
 
 // Environ returns a copy of the environment in which the command would be run
@@ -926,20 +1211,31 @@
 // dedupEnv returns a copy of env with any duplicates removed, in favor of
 // later values.
 // Items not of the normal environment "key=value" form are preserved unchanged.
-func dedupEnv(env []string) []string {
-	return dedupEnvCase(runtime.GOOS == "windows", env)
+// Except on Plan 9, items containing NUL characters are removed, and
+// an error is returned along with the remaining values.
+func dedupEnv(env []string) ([]string, error) {
+	return dedupEnvCase(runtime.GOOS == "windows", runtime.GOOS == "plan9", env)
 }
 
 // dedupEnvCase is dedupEnv with a case option for testing.
 // If caseInsensitive is true, the case of keys is ignored.
-func dedupEnvCase(caseInsensitive bool, env []string) []string {
+// If nulOK is false, items containing NUL characters are allowed.
+func dedupEnvCase(caseInsensitive, nulOK bool, env []string) ([]string, error) {
 	// Construct the output in reverse order, to preserve the
 	// last occurrence of each key.
+	var err error
 	out := make([]string, 0, len(env))
 	saw := make(map[string]bool, len(env))
 	for n := len(env); n > 0; n-- {
 		kv := env[n-1]
 
+		// Reject NUL in environment variables to prevent security issues (#56284);
+		// except on Plan 9, which uses NUL as os.PathListSeparator (#56544).
+		if !nulOK && strings.IndexByte(kv, 0) != -1 {
+			err = errors.New("exec: environment variable contains NUL")
+			continue
+		}
+
 		i := strings.Index(kv, "=")
 		if i == 0 {
 			// We observe in practice keys with a single leading "=" on Windows.
@@ -974,7 +1270,7 @@
 		out[i], out[j] = out[j], out[i]
 	}
 
-	return out
+	return out, err
 }
 
 // addCriticalEnv adds any critical environment variables that are required
diff --git a/src/os/exec/exec_other_test.go b/src/os/exec/exec_other_test.go
new file mode 100644
index 0000000..64c819c
--- /dev/null
+++ b/src/os/exec/exec_other_test.go
@@ -0,0 +1,14 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !unix && !windows
+
+package exec_test
+
+import "os"
+
+var (
+	quitSignal os.Signal = nil
+	pipeSignal os.Signal = nil
+)
diff --git a/src/os/exec/exec_posix_test.go b/src/os/exec/exec_posix_test.go
index f040137..5d828b3 100644
--- a/src/os/exec/exec_posix_test.go
+++ b/src/os/exec/exec_posix_test.go
@@ -9,6 +9,7 @@
 import (
 	"fmt"
 	"internal/testenv"
+	"io"
 	"os"
 	"os/user"
 	"path/filepath"
@@ -23,7 +24,6 @@
 
 func init() {
 	registerHelperCommand("pwd", cmdPwd)
-	registerHelperCommand("sleep", cmdSleep)
 }
 
 func cmdPwd(...string) {
@@ -35,20 +35,12 @@
 	fmt.Println(pwd)
 }
 
-func cmdSleep(args ...string) {
-	n, err := strconv.Atoi(args[0])
-	if err != nil {
-		fmt.Println(err)
-		os.Exit(1)
-	}
-	time.Sleep(time.Duration(n) * time.Second)
-}
-
 func TestCredentialNoSetGroups(t *testing.T) {
 	if runtime.GOOS == "android" {
 		maySkipHelperCommand("echo")
 		t.Skip("unsupported on Android")
 	}
+	t.Parallel()
 
 	u, err := user.Current()
 	if err != nil {
@@ -85,15 +77,29 @@
 func TestWaitid(t *testing.T) {
 	t.Parallel()
 
-	cmd := helperCommand(t, "sleep", "3")
+	cmd := helperCommand(t, "pipetest")
+	stdin, err := cmd.StdinPipe()
+	if err != nil {
+		t.Fatal(err)
+	}
+	stdout, err := cmd.StdoutPipe()
+	if err != nil {
+		t.Fatal(err)
+	}
 	if err := cmd.Start(); err != nil {
 		t.Fatal(err)
 	}
 
-	// The sleeps here are unnecessary in the sense that the test
-	// should still pass, but they are useful to make it more
-	// likely that we are testing the expected state of the child.
-	time.Sleep(100 * time.Millisecond)
+	// Wait for the child process to come up and register any signal handlers.
+	const msg = "O:ping\n"
+	if _, err := io.WriteString(stdin, msg); err != nil {
+		t.Fatal(err)
+	}
+	buf := make([]byte, len(msg))
+	if _, err := io.ReadFull(stdout, buf); err != nil {
+		t.Fatal(err)
+	}
+	// Now leave the pipes open so that the process will hang until we close stdin.
 
 	if err := cmd.Process.Signal(syscall.SIGSTOP); err != nil {
 		cmd.Process.Kill()
@@ -105,16 +111,30 @@
 		ch <- cmd.Wait()
 	}()
 
-	time.Sleep(100 * time.Millisecond)
+	// Give a little time for Wait to block on waiting for the process.
+	// (This is just to give some time to trigger the bug; it should not be
+	// necessary for the test to pass.)
+	if testing.Short() {
+		time.Sleep(1 * time.Millisecond)
+	} else {
+		time.Sleep(10 * time.Millisecond)
+	}
 
+	// This call to Signal should succeed because the process still exists.
+	// (Prior to the fix for #19314, this would fail with os.ErrProcessDone
+	// or an equivalent error.)
 	if err := cmd.Process.Signal(syscall.SIGCONT); err != nil {
 		t.Error(err)
 		syscall.Kill(cmd.Process.Pid, syscall.SIGCONT)
 	}
 
-	cmd.Process.Kill()
-
-	<-ch
+	// The SIGCONT should allow the process to wake up, notice that stdin
+	// is closed, and exit successfully.
+	stdin.Close()
+	err = <-ch
+	if err != nil {
+		t.Fatal(err)
+	}
 }
 
 // https://go.dev/issue/50599: if Env is not set explicitly, setting Dir should
@@ -186,6 +206,8 @@
 // (This checks that the implementation for https://go.dev/issue/50599 doesn't
 // break existing users who may have explicitly mismatched the PWD variable.)
 func TestExplicitPWD(t *testing.T) {
+	t.Parallel()
+
 	maySkipHelperCommand("pwd")
 	testenv.MustHaveSymlink(t)
 
diff --git a/src/os/exec/exec_test.go b/src/os/exec/exec_test.go
index 8f79b19..67e2d25 100644
--- a/src/os/exec/exec_test.go
+++ b/src/os/exec/exec_test.go
@@ -11,6 +11,7 @@
 	"bufio"
 	"bytes"
 	"context"
+	"errors"
 	"flag"
 	"fmt"
 	"internal/poll"
@@ -23,12 +24,14 @@
 	"os"
 	"os/exec"
 	"os/exec/internal/fdtest"
+	"os/signal"
 	"path/filepath"
-	"reflect"
 	"runtime"
+	"runtime/debug"
 	"strconv"
 	"strings"
 	"sync"
+	"sync/atomic"
 	"testing"
 	"time"
 )
@@ -38,6 +41,13 @@
 var haveUnexpectedFDs bool
 
 func init() {
+	godebug := os.Getenv("GODEBUG")
+	if godebug != "" {
+		godebug += ","
+	}
+	godebug += "execwait=2"
+	os.Setenv("GODEBUG", godebug)
+
 	if os.Getenv("GO_EXEC_TEST_PID") != "" {
 		return
 	}
@@ -76,6 +86,14 @@
 				}
 			}
 		}
+
+		if !testing.Short() {
+			// Run a couple of GC cycles to increase the odds of detecting
+			// process leaks using the finalizers installed by GODEBUG=execwait=2.
+			runtime.GC()
+			runtime.GC()
+		}
+
 		os.Exit(code)
 	}
 
@@ -165,16 +183,16 @@
 var helperCommandUsed sync.Map
 
 var helperCommands = map[string]func(...string){
-	"echo":               cmdEcho,
-	"echoenv":            cmdEchoEnv,
-	"cat":                cmdCat,
-	"pipetest":           cmdPipeTest,
-	"stdinClose":         cmdStdinClose,
-	"exit":               cmdExit,
-	"describefiles":      cmdDescribeFiles,
-	"extraFilesAndPipes": cmdExtraFilesAndPipes,
-	"stderrfail":         cmdStderrFail,
-	"yes":                cmdYes,
+	"echo":          cmdEcho,
+	"echoenv":       cmdEchoEnv,
+	"cat":           cmdCat,
+	"pipetest":      cmdPipeTest,
+	"stdinClose":    cmdStdinClose,
+	"exit":          cmdExit,
+	"describefiles": cmdDescribeFiles,
+	"stderrfail":    cmdStderrFail,
+	"yes":           cmdYes,
+	"hang":          cmdHang,
 }
 
 func cmdEcho(args ...string) {
@@ -257,25 +275,6 @@
 	}
 }
 
-func cmdExtraFilesAndPipes(args ...string) {
-	n, _ := strconv.Atoi(args[0])
-	pipes := make([]*os.File, n)
-	for i := 0; i < n; i++ {
-		pipes[i] = os.NewFile(uintptr(3+i), strconv.Itoa(i))
-	}
-	response := ""
-	for i, r := range pipes {
-		buf := make([]byte, 10)
-		n, err := r.Read(buf)
-		if err != nil {
-			fmt.Fprintf(os.Stderr, "Child: read error: %v on pipe %d\n", err, i)
-			os.Exit(1)
-		}
-		response = response + string(buf[:n])
-	}
-	fmt.Fprintf(os.Stderr, "child: %s", response)
-}
-
 func cmdStderrFail(...string) {
 	fmt.Fprintf(os.Stderr, "some stderr text\n")
 	os.Exit(1)
@@ -295,6 +294,8 @@
 }
 
 func TestEcho(t *testing.T) {
+	t.Parallel()
+
 	bs, err := helperCommand(t, "echo", "foo bar", "baz").Output()
 	if err != nil {
 		t.Errorf("echo: %v", err)
@@ -305,6 +306,8 @@
 }
 
 func TestCommandRelativeName(t *testing.T) {
+	t.Parallel()
+
 	cmd := helperCommand(t, "echo", "foo")
 
 	// Run our own binary as a relative path
@@ -333,6 +336,8 @@
 }
 
 func TestCatStdin(t *testing.T) {
+	t.Parallel()
+
 	// Cat, testing stdin and stdout.
 	input := "Input string\nLine 2"
 	p := helperCommand(t, "cat")
@@ -348,6 +353,8 @@
 }
 
 func TestEchoFileRace(t *testing.T) {
+	t.Parallel()
+
 	cmd := helperCommand(t, "echo")
 	stdin, err := cmd.StdinPipe()
 	if err != nil {
@@ -368,6 +375,8 @@
 }
 
 func TestCatGoodAndBadFile(t *testing.T) {
+	t.Parallel()
+
 	// Testing combined output and error values.
 	bs, err := helperCommand(t, "cat", "/bogus/file.foo", "exec_test.go").CombinedOutput()
 	if _, ok := err.(*exec.ExitError); !ok {
@@ -386,6 +395,8 @@
 }
 
 func TestNoExistExecutable(t *testing.T) {
+	t.Parallel()
+
 	// Can't run a non-existent executable
 	err := exec.Command("/no-exist-executable").Run()
 	if err == nil {
@@ -394,6 +405,8 @@
 }
 
 func TestExitStatus(t *testing.T) {
+	t.Parallel()
+
 	// Test that exit values are returned correctly
 	cmd := helperCommand(t, "exit", "42")
 	err := cmd.Run()
@@ -412,6 +425,8 @@
 }
 
 func TestExitCode(t *testing.T) {
+	t.Parallel()
+
 	// Test that exit code are returned correctly
 	cmd := helperCommand(t, "exit", "42")
 	cmd.Run()
@@ -464,6 +479,8 @@
 }
 
 func TestPipes(t *testing.T) {
+	t.Parallel()
+
 	check := func(what string, err error) {
 		if err != nil {
 			t.Fatalf("%s: %v", what, err)
@@ -518,6 +535,8 @@
 
 // Issue 6270.
 func TestStdinClose(t *testing.T) {
+	t.Parallel()
+
 	check := func(what string, err error) {
 		if err != nil {
 			t.Fatalf("%s: %v", what, err)
@@ -533,12 +552,22 @@
 		t.Error("can't access methods of underlying *os.File")
 	}
 	check("Start", cmd.Start())
+
+	var wg sync.WaitGroup
+	wg.Add(1)
+	defer wg.Wait()
 	go func() {
+		defer wg.Done()
+
 		_, err := io.Copy(stdin, strings.NewReader(stdinCloseTestString))
 		check("Copy", err)
+
 		// Before the fix, this next line would race with cmd.Wait.
-		check("Close", stdin.Close())
+		if err := stdin.Close(); err != nil && !errors.Is(err, os.ErrClosed) {
+			t.Errorf("Close: %v", err)
+		}
 	}()
+
 	check("Wait", cmd.Wait())
 }
 
@@ -549,6 +578,8 @@
 // This test is run by cmd/dist under the race detector to verify that
 // the race detector no longer reports any problems.
 func TestStdinCloseRace(t *testing.T) {
+	t.Parallel()
+
 	cmd := helperCommand(t, "stdinClose")
 	stdin, err := cmd.StdinPipe()
 	if err != nil {
@@ -556,8 +587,15 @@
 	}
 	if err := cmd.Start(); err != nil {
 		t.Fatalf("Start: %v", err)
+
 	}
+
+	var wg sync.WaitGroup
+	wg.Add(2)
+	defer wg.Wait()
+
 	go func() {
+		defer wg.Done()
 		// We don't check the error return of Kill. It is
 		// possible that the process has already exited, in
 		// which case Kill will return an error "process
@@ -566,17 +604,20 @@
 		// doesn't matter whether this Kill succeeds or not.
 		cmd.Process.Kill()
 	}()
+
 	go func() {
+		defer wg.Done()
 		// Send the wrong string, so that the child fails even
 		// if the other goroutine doesn't manage to kill it first.
 		// This test is to check that the race detector does not
 		// falsely report an error, so it doesn't matter how the
 		// child process fails.
 		io.Copy(stdin, strings.NewReader("unexpected string"))
-		if err := stdin.Close(); err != nil {
+		if err := stdin.Close(); err != nil && !errors.Is(err, os.ErrClosed) {
 			t.Errorf("stdin.Close: %v", err)
 		}
 	}()
+
 	if err := cmd.Wait(); err == nil {
 		t.Fatalf("Wait: succeeded unexpectedly")
 	}
@@ -587,6 +628,7 @@
 	if runtime.GOOS == "windows" {
 		t.Skip("we don't currently suppore counting open handles on windows")
 	}
+	// Not parallel: checks for leaked file descriptors
 
 	openFDs := func() []uintptr {
 		var fds []uintptr
@@ -598,7 +640,11 @@
 		return fds
 	}
 
-	want := openFDs()
+	old := map[uintptr]bool{}
+	for _, fd := range openFDs() {
+		old[fd] = true
+	}
+
 	for i := 0; i < 6; i++ {
 		cmd := exec.Command("something-that-does-not-exist-executable")
 		cmd.StdoutPipe()
@@ -608,100 +654,24 @@
 			t.Fatal("unexpected success")
 		}
 	}
-	got := openFDs()
-	if !reflect.DeepEqual(got, want) {
-		t.Errorf("set of open file descriptors changed: got %v, want %v", got, want)
-	}
-}
 
-func TestExtraFilesFDShuffle(t *testing.T) {
-	maySkipHelperCommand("extraFilesAndPipes")
-	testenv.SkipFlaky(t, 5780)
-	switch runtime.GOOS {
-	case "windows":
-		t.Skip("no operating system support; skipping")
-	}
-
-	// syscall.StartProcess maps all the FDs passed to it in
-	// ProcAttr.Files (the concatenation of stdin,stdout,stderr and
-	// ExtraFiles) into consecutive FDs in the child, that is:
-	// Files{11, 12, 6, 7, 9, 3} should result in the file
-	// represented by FD 11 in the parent being made available as 0
-	// in the child, 12 as 1, etc.
-	//
-	// We want to test that FDs in the child do not get overwritten
-	// by one another as this shuffle occurs. The original implementation
-	// was buggy in that in some data dependent cases it would overwrite
-	// stderr in the child with one of the ExtraFile members.
-	// Testing for this case is difficult because it relies on using
-	// the same FD values as that case. In particular, an FD of 3
-	// must be at an index of 4 or higher in ProcAttr.Files and
-	// the FD of the write end of the Stderr pipe (as obtained by
-	// StderrPipe()) must be the same as the size of ProcAttr.Files;
-	// therefore we test that the read end of this pipe (which is what
-	// is returned to the parent by StderrPipe() being one less than
-	// the size of ProcAttr.Files, i.e. 3+len(cmd.ExtraFiles).
-	//
-	// Moving this test case around within the overall tests may
-	// affect the FDs obtained and hence the checks to catch these cases.
-	npipes := 2
-	c := helperCommand(t, "extraFilesAndPipes", strconv.Itoa(npipes+1))
-	rd, wr, _ := os.Pipe()
-	defer rd.Close()
-	if rd.Fd() != 3 {
-		t.Errorf("bad test value for test pipe: fd %d", rd.Fd())
-	}
-	stderr, _ := c.StderrPipe()
-	wr.WriteString("_LAST")
-	wr.Close()
-
-	pipes := make([]struct {
-		r, w *os.File
-	}, npipes)
-	data := []string{"a", "b"}
-
-	for i := 0; i < npipes; i++ {
-		r, w, err := os.Pipe()
-		if err != nil {
-			t.Fatalf("unexpected error creating pipe: %s", err)
-		}
-		pipes[i].r = r
-		pipes[i].w = w
-		w.WriteString(data[i])
-		c.ExtraFiles = append(c.ExtraFiles, pipes[i].r)
-		defer func() {
-			r.Close()
-			w.Close()
-		}()
-	}
-	// Put fd 3 at the end.
-	c.ExtraFiles = append(c.ExtraFiles, rd)
-
-	stderrFd := int(stderr.(*os.File).Fd())
-	if stderrFd != ((len(c.ExtraFiles) + 3) - 1) {
-		t.Errorf("bad test value for stderr pipe")
-	}
-
-	expected := "child: " + strings.Join(data, "") + "_LAST"
-
-	err := c.Start()
-	if err != nil {
-		t.Fatalf("Run: %v", err)
-	}
-
-	buf := make([]byte, 512)
-	n, err := stderr.Read(buf)
-	if err != nil {
-		t.Errorf("Read: %s", err)
-	} else {
-		if m := string(buf[:n]); m != expected {
-			t.Errorf("Read: '%s' not '%s'", m, expected)
+	// Since this test is not running in parallel, we don't expect any new file
+	// descriptors to be opened while it runs. However, if there are additional
+	// FDs present at the start of the test (for example, opened by libc), those
+	// may be closed due to a timeout of some sort. Allow those to go away, but
+	// check that no new FDs are added.
+	for _, fd := range openFDs() {
+		if !old[fd] {
+			t.Errorf("leaked file descriptor %v", fd)
 		}
 	}
-	c.Wait()
 }
 
 func TestExtraFiles(t *testing.T) {
+	if testing.Short() {
+		t.Skipf("skipping test in short mode that would build a helper binary")
+	}
+
 	if haveUnexpectedFDs {
 		// The point of this test is to make sure that any
 		// descriptors we open are marked close-on-exec.
@@ -804,7 +774,7 @@
 	}
 
 	c = exec.CommandContext(ctx, exe)
-	var stdout, stderr bytes.Buffer
+	var stdout, stderr strings.Builder
 	c.Stdout = &stdout
 	c.Stderr = &stderr
 	c.ExtraFiles = []*os.File{tf}
@@ -822,7 +792,7 @@
 	}
 	err = c.Run()
 	if err != nil {
-		t.Fatalf("Run: %v\n--- stdout:\n%s--- stderr:\n%s", err, stdout.Bytes(), stderr.Bytes())
+		t.Fatalf("Run: %v\n--- stdout:\n%s--- stderr:\n%s", err, stdout.String(), stderr.String())
 	}
 	if stdout.String() != text {
 		t.Errorf("got stdout %q, stderr %q; want %q on stdout", stdout.String(), stderr.String(), text)
@@ -834,6 +804,8 @@
 		maySkipHelperCommand("describefiles")
 		t.Skip("no operating system support; skipping")
 	}
+	t.Parallel()
+
 	listen := func() net.Listener {
 		ln, err := net.Listen("tcp", "127.0.0.1:0")
 		if err != nil {
@@ -885,7 +857,6 @@
 		for _, f := range cb.ExtraFiles {
 			f.Close()
 		}
-
 	}
 }
 
@@ -901,10 +872,14 @@
 
 // Issue 9173: ignore stdin pipe writes if the program completes successfully.
 func TestIgnorePipeErrorOnSuccess(t *testing.T) {
+	t.Parallel()
+
 	testWith := func(r io.Reader) func(*testing.T) {
 		return func(t *testing.T) {
+			t.Parallel()
+
 			cmd := helperCommand(t, "echo", "foo")
-			var out bytes.Buffer
+			var out strings.Builder
 			cmd.Stdin = r
 			cmd.Stdout = &out
 			if err := cmd.Run(); err != nil {
@@ -926,6 +901,8 @@
 }
 
 func TestClosePipeOnCopyError(t *testing.T) {
+	t.Parallel()
+
 	cmd := helperCommand(t, "yes")
 	cmd.Stdout = new(badWriter)
 	err := cmd.Run()
@@ -935,6 +912,8 @@
 }
 
 func TestOutputStderrCapture(t *testing.T) {
+	t.Parallel()
+
 	cmd := helperCommand(t, "stderrfail")
 	_, err := cmd.Output()
 	ee, ok := err.(*exec.ExitError)
@@ -949,6 +928,8 @@
 }
 
 func TestContext(t *testing.T) {
+	t.Parallel()
+
 	ctx, cancel := context.WithCancel(context.Background())
 	c := helperCommandContext(t, ctx, "pipetest")
 	stdin, err := c.StdinPipe()
@@ -1021,6 +1002,7 @@
 		if time.Since(start) > time.Minute {
 			// Panic instead of calling t.Fatal so that we get a goroutine dump.
 			// We want to know exactly what the os/exec goroutines got stuck on.
+			debug.SetTraceback("system")
 			panic("canceling context did not stop program")
 		}
 
@@ -1042,6 +1024,8 @@
 
 // test that environment variables are de-duped.
 func TestDedupEnvEcho(t *testing.T) {
+	t.Parallel()
+
 	cmd := helperCommand(t, "echoenv", "FOO")
 	cmd.Env = append(cmd.Environ(), "FOO=bad", "FOO=good")
 	out, err := cmd.CombinedOutput()
@@ -1053,7 +1037,21 @@
 	}
 }
 
+func TestEnvNULCharacter(t *testing.T) {
+	if runtime.GOOS == "plan9" {
+		t.Skip("plan9 explicitly allows NUL in the enviroment")
+	}
+	cmd := helperCommand(t, "echoenv", "FOO", "BAR")
+	cmd.Env = append(cmd.Environ(), "FOO=foo\x00BAR=bar")
+	out, err := cmd.CombinedOutput()
+	if err == nil {
+		t.Errorf("output = %q; want error", string(out))
+	}
+}
+
 func TestString(t *testing.T) {
+	t.Parallel()
+
 	echoPath, err := exec.LookPath("echo")
 	if err != nil {
 		t.Skip(err)
@@ -1076,10 +1074,13 @@
 }
 
 func TestStringPathNotResolved(t *testing.T) {
+	t.Parallel()
+
 	_, err := exec.LookPath("makemeasandwich")
 	if err == nil {
 		t.Skip("wow, thanks")
 	}
+
 	cmd := exec.Command("makemeasandwich", "-lettuce")
 	want := "makemeasandwich -lettuce"
 	if got := cmd.String(); got != want {
@@ -1094,3 +1095,616 @@
 		t.Errorf("new(Cmd).Start() = %v, want %q", err, want)
 	}
 }
+
+// TestDoubleStartLeavesPipesOpen checks for a regression in which calling
+// Start twice, which returns an error on the second call, would spuriously
+// close the pipes established in the first call.
+func TestDoubleStartLeavesPipesOpen(t *testing.T) {
+	t.Parallel()
+
+	cmd := helperCommand(t, "pipetest")
+	in, err := cmd.StdinPipe()
+	if err != nil {
+		t.Fatal(err)
+	}
+	out, err := cmd.StdoutPipe()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if err := cmd.Start(); err != nil {
+		t.Fatal(err)
+	}
+	t.Cleanup(func() {
+		if err := cmd.Wait(); err != nil {
+			t.Error(err)
+		}
+	})
+
+	if err := cmd.Start(); err == nil || !strings.HasSuffix(err.Error(), "already started") {
+		t.Fatalf("second call to Start returned a nil; want an 'already started' error")
+	}
+
+	outc := make(chan []byte, 1)
+	go func() {
+		b, err := io.ReadAll(out)
+		if err != nil {
+			t.Error(err)
+		}
+		outc <- b
+	}()
+
+	const msg = "O:Hello, pipe!\n"
+
+	_, err = io.WriteString(in, msg)
+	if err != nil {
+		t.Fatal(err)
+	}
+	in.Close()
+
+	b := <-outc
+	if !bytes.Equal(b, []byte(msg)) {
+		t.Fatalf("read %q from stdout pipe; want %q", b, msg)
+	}
+}
+
+func cmdHang(args ...string) {
+	sleep, err := time.ParseDuration(args[0])
+	if err != nil {
+		panic(err)
+	}
+
+	fs := flag.NewFlagSet("hang", flag.ExitOnError)
+	exitOnInterrupt := fs.Bool("interrupt", false, "if true, commands should exit 0 on os.Interrupt")
+	subsleep := fs.Duration("subsleep", 0, "amount of time for the 'hang' helper to leave an orphaned subprocess sleeping with stderr open")
+	probe := fs.Duration("probe", 0, "if nonzero, the 'hang' helper should write to stderr at this interval, and exit nonzero if a write fails")
+	read := fs.Bool("read", false, "if true, the 'hang' helper should read stdin to completion before sleeping")
+	fs.Parse(args[1:])
+
+	pid := os.Getpid()
+
+	if *subsleep != 0 {
+		cmd := exec.Command(exePath(nil), "hang", subsleep.String(), "-read=true", "-probe="+probe.String())
+		cmd.Stdin = os.Stdin
+		cmd.Stderr = os.Stderr
+		out, err := cmd.StdoutPipe()
+		if err != nil {
+			fmt.Fprintln(os.Stderr, err)
+			os.Exit(1)
+		}
+		cmd.Start()
+
+		buf := new(strings.Builder)
+		if _, err := io.Copy(buf, out); err != nil {
+			fmt.Fprintln(os.Stderr, err)
+			cmd.Process.Kill()
+			cmd.Wait()
+			os.Exit(1)
+		}
+		fmt.Fprintf(os.Stderr, "%d: started %d: %v\n", pid, cmd.Process.Pid, cmd)
+		go cmd.Wait() // Release resources if cmd happens not to outlive this process.
+	}
+
+	if *exitOnInterrupt {
+		c := make(chan os.Signal, 1)
+		signal.Notify(c, os.Interrupt)
+		go func() {
+			sig := <-c
+			fmt.Fprintf(os.Stderr, "%d: received %v\n", pid, sig)
+			os.Exit(0)
+		}()
+	} else {
+		signal.Ignore(os.Interrupt)
+	}
+
+	// Signal that the process is set up by closing stdout.
+	os.Stdout.Close()
+
+	if *read {
+		if pipeSignal != nil {
+			signal.Ignore(pipeSignal)
+		}
+		r := bufio.NewReader(os.Stdin)
+		for {
+			line, err := r.ReadBytes('\n')
+			if len(line) > 0 {
+				// Ignore write errors: we want to keep reading even if stderr is closed.
+				fmt.Fprintf(os.Stderr, "%d: read %s", pid, line)
+			}
+			if err != nil {
+				fmt.Fprintf(os.Stderr, "%d: finished read: %v", pid, err)
+				break
+			}
+		}
+	}
+
+	if *probe != 0 {
+		ticker := time.NewTicker(*probe)
+		go func() {
+			for range ticker.C {
+				if _, err := fmt.Fprintf(os.Stderr, "%d: ok\n", pid); err != nil {
+					os.Exit(1)
+				}
+			}
+		}()
+	}
+
+	if sleep != 0 {
+		time.Sleep(sleep)
+		fmt.Fprintf(os.Stderr, "%d: slept %v\n", pid, sleep)
+	}
+}
+
+// A tickReader reads an unbounded sequence of timestamps at no more than a
+// fixed interval.
+type tickReader struct {
+	interval time.Duration
+	lastTick time.Time
+	s        string
+}
+
+func newTickReader(interval time.Duration) *tickReader {
+	return &tickReader{interval: interval}
+}
+
+func (r *tickReader) Read(p []byte) (n int, err error) {
+	if len(r.s) == 0 {
+		if d := r.interval - time.Since(r.lastTick); d > 0 {
+			time.Sleep(d)
+		}
+		r.lastTick = time.Now()
+		r.s = r.lastTick.Format(time.RFC3339Nano + "\n")
+	}
+
+	n = copy(p, r.s)
+	r.s = r.s[n:]
+	return n, nil
+}
+
+func startHang(t *testing.T, ctx context.Context, hangTime time.Duration, interrupt os.Signal, waitDelay time.Duration, flags ...string) *exec.Cmd {
+	t.Helper()
+
+	args := append([]string{hangTime.String()}, flags...)
+	cmd := helperCommandContext(t, ctx, "hang", args...)
+	cmd.Stdin = newTickReader(1 * time.Millisecond)
+	cmd.Stderr = new(strings.Builder)
+	if interrupt == nil {
+		cmd.Cancel = nil
+	} else {
+		cmd.Cancel = func() error {
+			return cmd.Process.Signal(interrupt)
+		}
+	}
+	cmd.WaitDelay = waitDelay
+	out, err := cmd.StdoutPipe()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	t.Log(cmd)
+	if err := cmd.Start(); err != nil {
+		t.Fatal(err)
+	}
+
+	// Wait for cmd to close stdout to signal that its handlers are installed.
+	buf := new(strings.Builder)
+	if _, err := io.Copy(buf, out); err != nil {
+		t.Error(err)
+		cmd.Process.Kill()
+		cmd.Wait()
+		t.FailNow()
+	}
+	if buf.Len() > 0 {
+		t.Logf("stdout %v:\n%s", cmd.Args, buf)
+	}
+
+	return cmd
+}
+
+func TestWaitInterrupt(t *testing.T) {
+	t.Parallel()
+
+	// tooLong is an arbitrary duration that is expected to be much longer than
+	// the test runs, but short enough that leaked processes will eventually exit
+	// on their own.
+	const tooLong = 10 * time.Minute
+
+	// Control case: with no cancellation and no WaitDelay, we should wait for the
+	// process to exit.
+	t.Run("Wait", func(t *testing.T) {
+		t.Parallel()
+		cmd := startHang(t, context.Background(), 1*time.Millisecond, os.Kill, 0)
+		err := cmd.Wait()
+		t.Logf("stderr:\n%s", cmd.Stderr)
+		t.Logf("[%d] %v", cmd.Process.Pid, err)
+
+		if err != nil {
+			t.Errorf("Wait: %v; want <nil>", err)
+		}
+		if ps := cmd.ProcessState; !ps.Exited() {
+			t.Errorf("cmd did not exit: %v", ps)
+		} else if code := ps.ExitCode(); code != 0 {
+			t.Errorf("cmd.ProcessState.ExitCode() = %v; want 0", code)
+		}
+	})
+
+	// With a very long WaitDelay and no Cancel function, we should wait for the
+	// process to exit even if the command's Context is cancelled.
+	t.Run("WaitDelay", func(t *testing.T) {
+		if runtime.GOOS == "windows" {
+			t.Skipf("skipping: os.Interrupt is not implemented on Windows")
+		}
+		t.Parallel()
+
+		ctx, cancel := context.WithCancel(context.Background())
+		cmd := startHang(t, ctx, tooLong, nil, tooLong, "-interrupt=true")
+		cancel()
+
+		time.Sleep(1 * time.Millisecond)
+		// At this point cmd should still be running (because we passed nil to
+		// startHang for the cancel signal). Sending it an explicit Interrupt signal
+		// should succeed.
+		if err := cmd.Process.Signal(os.Interrupt); err != nil {
+			t.Error(err)
+		}
+
+		err := cmd.Wait()
+		t.Logf("stderr:\n%s", cmd.Stderr)
+		t.Logf("[%d] %v", cmd.Process.Pid, err)
+
+		// This program exits with status 0,
+		// but pretty much always does so during the wait delay.
+		// Since the Cmd itself didn't do anything to stop the process when the
+		// context expired, a successful exit is valid (even if late) and does
+		// not merit a non-nil error.
+		if err != nil {
+			t.Errorf("Wait: %v; want nil", err)
+		}
+		if ps := cmd.ProcessState; !ps.Exited() {
+			t.Errorf("cmd did not exit: %v", ps)
+		} else if code := ps.ExitCode(); code != 0 {
+			t.Errorf("cmd.ProcessState.ExitCode() = %v; want 0", code)
+		}
+	})
+
+	// If the context is cancelled and the Cancel function sends os.Kill,
+	// the process should be terminated immediately, and its output
+	// pipes should be closed (causing Wait to return) after WaitDelay
+	// even if a child process is still writing to them.
+	t.Run("SIGKILL-hang", func(t *testing.T) {
+		t.Parallel()
+
+		ctx, cancel := context.WithCancel(context.Background())
+		cmd := startHang(t, ctx, tooLong, os.Kill, 10*time.Millisecond, "-subsleep=10m", "-probe=1ms")
+		cancel()
+		err := cmd.Wait()
+		t.Logf("stderr:\n%s", cmd.Stderr)
+		t.Logf("[%d] %v", cmd.Process.Pid, err)
+
+		// This test should kill the child process after 10ms,
+		// leaving a grandchild process writing probes in a loop.
+		// The child process should be reported as failed,
+		// and the grandchild will exit (or die by SIGPIPE) once the
+		// stderr pipe is closed.
+		if ee := new(*exec.ExitError); !errors.As(err, ee) {
+			t.Errorf("Wait error = %v; want %T", err, *ee)
+		}
+	})
+
+	// If the process exits with status 0 but leaves a child behind writing
+	// to its output pipes, Wait should only wait for WaitDelay before
+	// closing the pipes and returning.  Wait should return ErrWaitDelay
+	// to indicate that the piped output may be incomplete even though the
+	// command returned a “success” code.
+	t.Run("Exit-hang", func(t *testing.T) {
+		t.Parallel()
+
+		cmd := startHang(t, context.Background(), 1*time.Millisecond, nil, 10*time.Millisecond, "-subsleep=10m", "-probe=1ms")
+		err := cmd.Wait()
+		t.Logf("stderr:\n%s", cmd.Stderr)
+		t.Logf("[%d] %v", cmd.Process.Pid, err)
+
+		// This child process should exit immediately,
+		// leaving a grandchild process writing probes in a loop.
+		// Since the child has no ExitError to report but we did not
+		// read all of its output, Wait should return ErrWaitDelay.
+		if !errors.Is(err, exec.ErrWaitDelay) {
+			t.Errorf("Wait error = %v; want %T", err, exec.ErrWaitDelay)
+		}
+	})
+
+	// If the Cancel function sends a signal that the process can handle, and it
+	// handles that signal without actually exiting, then it should be terminated
+	// after the WaitDelay.
+	t.Run("SIGINT-ignored", func(t *testing.T) {
+		if runtime.GOOS == "windows" {
+			t.Skipf("skipping: os.Interrupt is not implemented on Windows")
+		}
+		t.Parallel()
+
+		ctx, cancel := context.WithCancel(context.Background())
+		cmd := startHang(t, ctx, tooLong, os.Interrupt, 10*time.Millisecond, "-interrupt=false")
+		cancel()
+		err := cmd.Wait()
+		t.Logf("stderr:\n%s", cmd.Stderr)
+		t.Logf("[%d] %v", cmd.Process.Pid, err)
+
+		// This command ignores SIGINT, sleeping until it is killed.
+		// Wait should return the usual error for a killed process.
+		if ee := new(*exec.ExitError); !errors.As(err, ee) {
+			t.Errorf("Wait error = %v; want %T", err, *ee)
+		}
+	})
+
+	// If the process handles the cancellation signal and exits with status 0,
+	// Wait should report a non-nil error (because the process had to be
+	// interrupted), and it should be a context error (because there is no error
+	// to report from the child process itself).
+	t.Run("SIGINT-handled", func(t *testing.T) {
+		if runtime.GOOS == "windows" {
+			t.Skipf("skipping: os.Interrupt is not implemented on Windows")
+		}
+		t.Parallel()
+
+		ctx, cancel := context.WithCancel(context.Background())
+		cmd := startHang(t, ctx, tooLong, os.Interrupt, 0, "-interrupt=true")
+		cancel()
+		err := cmd.Wait()
+		t.Logf("stderr:\n%s", cmd.Stderr)
+		t.Logf("[%d] %v", cmd.Process.Pid, err)
+
+		if !errors.Is(err, ctx.Err()) {
+			t.Errorf("Wait error = %v; want %v", err, ctx.Err())
+		}
+		if ps := cmd.ProcessState; !ps.Exited() {
+			t.Errorf("cmd did not exit: %v", ps)
+		} else if code := ps.ExitCode(); code != 0 {
+			t.Errorf("cmd.ProcessState.ExitCode() = %v; want 0", code)
+		}
+	})
+
+	// If the Cancel function sends SIGQUIT, it should be handled in the usual
+	// way: a Go program should dump its goroutines and exit with non-success
+	// status. (We expect SIGQUIT to be a common pattern in real-world use.)
+	t.Run("SIGQUIT", func(t *testing.T) {
+		if quitSignal == nil {
+			t.Skipf("skipping: SIGQUIT is not supported on %v", runtime.GOOS)
+		}
+		t.Parallel()
+
+		ctx, cancel := context.WithCancel(context.Background())
+		cmd := startHang(t, ctx, tooLong, quitSignal, 0)
+		cancel()
+		err := cmd.Wait()
+		t.Logf("stderr:\n%s", cmd.Stderr)
+		t.Logf("[%d] %v", cmd.Process.Pid, err)
+
+		if ee := new(*exec.ExitError); !errors.As(err, ee) {
+			t.Errorf("Wait error = %v; want %v", err, ctx.Err())
+		}
+
+		if ps := cmd.ProcessState; !ps.Exited() {
+			t.Errorf("cmd did not exit: %v", ps)
+		} else if code := ps.ExitCode(); code != 2 {
+			// The default os/signal handler exits with code 2.
+			t.Errorf("cmd.ProcessState.ExitCode() = %v; want 2", code)
+		}
+
+		if !strings.Contains(fmt.Sprint(cmd.Stderr), "\n\ngoroutine ") {
+			t.Errorf("cmd.Stderr does not contain a goroutine dump")
+		}
+	})
+}
+
+func TestCancelErrors(t *testing.T) {
+	t.Parallel()
+
+	// If Cancel returns a non-ErrProcessDone error and the process
+	// exits successfully, Wait should wrap the error from Cancel.
+	t.Run("success after error", func(t *testing.T) {
+		t.Parallel()
+
+		ctx, cancel := context.WithCancel(context.Background())
+		defer cancel()
+
+		cmd := helperCommandContext(t, ctx, "pipetest")
+		stdin, err := cmd.StdinPipe()
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		errArbitrary := errors.New("arbitrary error")
+		cmd.Cancel = func() error {
+			stdin.Close()
+			t.Logf("Cancel returning %v", errArbitrary)
+			return errArbitrary
+		}
+		if err := cmd.Start(); err != nil {
+			t.Fatal(err)
+		}
+		cancel()
+
+		err = cmd.Wait()
+		t.Logf("[%d] %v", cmd.Process.Pid, err)
+		if !errors.Is(err, errArbitrary) || err == errArbitrary {
+			t.Errorf("Wait error = %v; want an error wrapping %v", err, errArbitrary)
+		}
+	})
+
+	// If Cancel returns an error equivalent to ErrProcessDone,
+	// Wait should ignore that error. (ErrProcessDone indicates that the
+	// process was already done before we tried to interrupt it — maybe we
+	// just didn't notice because Wait hadn't been called yet.)
+	t.Run("success after ErrProcessDone", func(t *testing.T) {
+		t.Parallel()
+
+		ctx, cancel := context.WithCancel(context.Background())
+		defer cancel()
+
+		cmd := helperCommandContext(t, ctx, "pipetest")
+		stdin, err := cmd.StdinPipe()
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		stdout, err := cmd.StdoutPipe()
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		// We intentionally race Cancel against the process exiting,
+		// but ensure that the process wins the race (and return ErrProcessDone
+		// from Cancel to report that).
+		interruptCalled := make(chan struct{})
+		done := make(chan struct{})
+		cmd.Cancel = func() error {
+			close(interruptCalled)
+			<-done
+			t.Logf("Cancel returning an error wrapping ErrProcessDone")
+			return fmt.Errorf("%w: stdout closed", os.ErrProcessDone)
+		}
+
+		if err := cmd.Start(); err != nil {
+			t.Fatal(err)
+		}
+
+		cancel()
+		<-interruptCalled
+		stdin.Close()
+		io.Copy(io.Discard, stdout) // reaches EOF when the process exits
+		close(done)
+
+		err = cmd.Wait()
+		t.Logf("[%d] %v", cmd.Process.Pid, err)
+		if err != nil {
+			t.Errorf("Wait error = %v; want nil", err)
+		}
+	})
+
+	// If Cancel returns an error and the process is killed after
+	// WaitDelay, Wait should report the usual SIGKILL ExitError, not the
+	// error from Cancel.
+	t.Run("killed after error", func(t *testing.T) {
+		t.Parallel()
+
+		ctx, cancel := context.WithCancel(context.Background())
+		defer cancel()
+
+		cmd := helperCommandContext(t, ctx, "pipetest")
+		stdin, err := cmd.StdinPipe()
+		if err != nil {
+			t.Fatal(err)
+		}
+		defer stdin.Close()
+
+		errArbitrary := errors.New("arbitrary error")
+		var interruptCalled atomic.Bool
+		cmd.Cancel = func() error {
+			t.Logf("Cancel called")
+			interruptCalled.Store(true)
+			return errArbitrary
+		}
+		cmd.WaitDelay = 1 * time.Millisecond
+		if err := cmd.Start(); err != nil {
+			t.Fatal(err)
+		}
+		cancel()
+
+		err = cmd.Wait()
+		t.Logf("[%d] %v", cmd.Process.Pid, err)
+
+		// Ensure that Cancel actually had the opportunity to
+		// return the error.
+		if !interruptCalled.Load() {
+			t.Errorf("Cancel was not called when the context was canceled")
+		}
+
+		// This test should kill the child process after 1ms,
+		// To maximize compatibility with existing uses of exec.CommandContext, the
+		// resulting error should be an exec.ExitError without additional wrapping.
+		if ee, ok := err.(*exec.ExitError); !ok {
+			t.Errorf("Wait error = %v; want %T", err, *ee)
+		}
+	})
+
+	// If Cancel returns ErrProcessDone but the process is not actually done
+	// (and has to be killed), Wait should report the usual SIGKILL ExitError,
+	// not the error from Cancel.
+	t.Run("killed after spurious ErrProcessDone", func(t *testing.T) {
+		t.Parallel()
+
+		ctx, cancel := context.WithCancel(context.Background())
+		defer cancel()
+
+		cmd := helperCommandContext(t, ctx, "pipetest")
+		stdin, err := cmd.StdinPipe()
+		if err != nil {
+			t.Fatal(err)
+		}
+		defer stdin.Close()
+
+		var interruptCalled atomic.Bool
+		cmd.Cancel = func() error {
+			t.Logf("Cancel returning an error wrapping ErrProcessDone")
+			interruptCalled.Store(true)
+			return fmt.Errorf("%w: stdout closed", os.ErrProcessDone)
+		}
+		cmd.WaitDelay = 1 * time.Millisecond
+		if err := cmd.Start(); err != nil {
+			t.Fatal(err)
+		}
+		cancel()
+
+		err = cmd.Wait()
+		t.Logf("[%d] %v", cmd.Process.Pid, err)
+
+		// Ensure that Cancel actually had the opportunity to
+		// return the error.
+		if !interruptCalled.Load() {
+			t.Errorf("Cancel was not called when the context was canceled")
+		}
+
+		// This test should kill the child process after 1ms,
+		// To maximize compatibility with existing uses of exec.CommandContext, the
+		// resulting error should be an exec.ExitError without additional wrapping.
+		if ee, ok := err.(*exec.ExitError); !ok {
+			t.Errorf("Wait error of type %T; want %T", err, ee)
+		}
+	})
+
+	// If Cancel returns an error and the process exits with an
+	// unsuccessful exit code, the process error should take precedence over the
+	// Cancel error.
+	t.Run("nonzero exit after error", func(t *testing.T) {
+		t.Parallel()
+
+		ctx, cancel := context.WithCancel(context.Background())
+		defer cancel()
+
+		cmd := helperCommandContext(t, ctx, "stderrfail")
+		stderr, err := cmd.StderrPipe()
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		errArbitrary := errors.New("arbitrary error")
+		interrupted := make(chan struct{})
+		cmd.Cancel = func() error {
+			close(interrupted)
+			return errArbitrary
+		}
+		if err := cmd.Start(); err != nil {
+			t.Fatal(err)
+		}
+		cancel()
+		<-interrupted
+		io.Copy(io.Discard, stderr)
+
+		err = cmd.Wait()
+		t.Logf("[%d] %v", cmd.Process.Pid, err)
+
+		if ee, ok := err.(*exec.ExitError); !ok || ee.ProcessState.ExitCode() != 1 {
+			t.Errorf("Wait error = %v; want exit status 1", err)
+		}
+	})
+}
diff --git a/src/os/exec/exec_unix_test.go b/src/os/exec/exec_unix_test.go
new file mode 100644
index 0000000..d26c93a
--- /dev/null
+++ b/src/os/exec/exec_unix_test.go
@@ -0,0 +1,17 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build unix
+
+package exec_test
+
+import (
+	"os"
+	"syscall"
+)
+
+var (
+	quitSignal os.Signal = syscall.SIGQUIT
+	pipeSignal os.Signal = syscall.SIGPIPE
+)
diff --git a/src/os/exec/exec_windows_test.go b/src/os/exec/exec_windows_test.go
index 35ae0b0..b39790d 100644
--- a/src/os/exec/exec_windows_test.go
+++ b/src/os/exec/exec_windows_test.go
@@ -17,6 +17,11 @@
 	"testing"
 )
 
+var (
+	quitSignal os.Signal = nil
+	pipeSignal os.Signal = syscall.SIGPIPE
+)
+
 func init() {
 	registerHelperCommand("pipehandle", cmdPipeHandle)
 }
@@ -33,6 +38,8 @@
 }
 
 func TestPipePassing(t *testing.T) {
+	t.Parallel()
+
 	r, w, err := os.Pipe()
 	if err != nil {
 		t.Error(err)
@@ -60,6 +67,8 @@
 }
 
 func TestNoInheritHandles(t *testing.T) {
+	t.Parallel()
+
 	cmd := exec.Command("cmd", "/c exit 88")
 	cmd.SysProcAttr = &syscall.SysProcAttr{NoInheritHandles: true}
 	err := cmd.Run()
@@ -76,6 +85,7 @@
 // with a copy of the parent's SYSTEMROOT.
 // (See issue 25210.)
 func TestChildCriticalEnv(t *testing.T) {
+	t.Parallel()
 	cmd := helperCommand(t, "echoenv", "SYSTEMROOT")
 
 	// Explicitly remove SYSTEMROOT from the command's environment.
diff --git a/src/os/exec/lp_linux_test.go b/src/os/exec/lp_linux_test.go
new file mode 100644
index 0000000..845573f
--- /dev/null
+++ b/src/os/exec/lp_linux_test.go
@@ -0,0 +1,82 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package exec
+
+import (
+	"errors"
+	"internal/syscall/unix"
+	"os"
+	"path/filepath"
+	"syscall"
+	"testing"
+)
+
+func TestFindExecutableVsNoexec(t *testing.T) {
+	t.Parallel()
+
+	// This test case relies on faccessat2(2) syscall, which appeared in Linux v5.8.
+	if major, minor := unix.KernelVersion(); major < 5 || (major == 5 && minor < 8) {
+		t.Skip("requires Linux kernel v5.8 with faccessat2(2) syscall")
+	}
+
+	tmp := t.TempDir()
+
+	// Create a tmpfs mount.
+	err := syscall.Mount("tmpfs", tmp, "tmpfs", 0, "")
+	if err != nil {
+		// Usually this means lack of CAP_SYS_ADMIN, but there might be
+		// other reasons, especially in restricted test environments.
+		t.Skipf("requires ability to mount tmpfs (%v)", err)
+	}
+	t.Cleanup(func() {
+		if err := syscall.Unmount(tmp, 0); err != nil {
+			t.Error(err)
+		}
+	})
+
+	// Create an executable.
+	path := filepath.Join(tmp, "program")
+	err = os.WriteFile(path, []byte("#!/bin/sh\necho 123\n"), 0o755)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// Check that it works as expected.
+	err = findExecutable(path)
+	if err != nil {
+		t.Fatalf("findExecutable: got %v, want nil", err)
+	}
+
+	for {
+		err = Command(path).Run()
+		if err == nil {
+			break
+		}
+		if errors.Is(err, syscall.ETXTBSY) {
+			// A fork+exec in another process may be holding open the FD that we used
+			// to write the executable (see https://go.dev/issue/22315).
+			// Since the descriptor should have CLOEXEC set, the problem should resolve
+			// as soon as the forked child reaches its exec call.
+			// Keep retrying until that happens.
+		} else {
+			t.Fatalf("exec: got %v, want nil", err)
+		}
+	}
+
+	// Remount with noexec flag.
+	err = syscall.Mount("", tmp, "", syscall.MS_REMOUNT|syscall.MS_NOEXEC, "")
+	if err != nil {
+		t.Fatalf("remount %s with noexec failed: %v", tmp, err)
+	}
+
+	if err := Command(path).Run(); err == nil {
+		t.Fatal("exec on noexec filesystem: got nil, want error")
+	}
+
+	err = findExecutable(path)
+	if err == nil {
+		t.Fatalf("findExecutable: got nil, want error")
+	}
+}
diff --git a/src/os/exec/lp_plan9.go b/src/os/exec/lp_plan9.go
index 092684f..59538d9 100644
--- a/src/os/exec/lp_plan9.go
+++ b/src/os/exec/lp_plan9.go
@@ -6,7 +6,6 @@
 
 import (
 	"errors"
-	"internal/godebug"
 	"io/fs"
 	"os"
 	"path/filepath"
@@ -54,7 +53,7 @@
 	for _, dir := range filepath.SplitList(path) {
 		path := filepath.Join(dir, file)
 		if err := findExecutable(path); err == nil {
-			if !filepath.IsAbs(path) && godebug.Get("execerrdot") != "0" {
+			if !filepath.IsAbs(path) && execerrdot.Value() != "0" {
 				return path, &Error{file, ErrDot}
 			}
 			return path, nil
diff --git a/src/os/exec/lp_unix.go b/src/os/exec/lp_unix.go
index b2b412c..2af9b01 100644
--- a/src/os/exec/lp_unix.go
+++ b/src/os/exec/lp_unix.go
@@ -8,11 +8,12 @@
 
 import (
 	"errors"
-	"internal/godebug"
+	"internal/syscall/unix"
 	"io/fs"
 	"os"
 	"path/filepath"
 	"strings"
+	"syscall"
 )
 
 // ErrNotFound is the error resulting if a path search failed to find an executable file.
@@ -23,7 +24,18 @@
 	if err != nil {
 		return err
 	}
-	if m := d.Mode(); !m.IsDir() && m&0111 != 0 {
+	m := d.Mode()
+	if m.IsDir() {
+		return syscall.EISDIR
+	}
+	err = unix.Eaccess(file, unix.X_OK)
+	// ENOSYS means Eaccess is not available or not implemented.
+	// EPERM can be returned by Linux containers employing seccomp.
+	// In both cases, fall back to checking the permission bits.
+	if err == nil || (err != syscall.ENOSYS && err != syscall.EPERM) {
+		return err
+	}
+	if m&0111 != 0 {
 		return nil
 	}
 	return fs.ErrPermission
@@ -57,7 +69,7 @@
 		}
 		path := filepath.Join(dir, file)
 		if err := findExecutable(path); err == nil {
-			if !filepath.IsAbs(path) && godebug.Get("execerrdot") != "0" {
+			if !filepath.IsAbs(path) && execerrdot.Value() != "0" {
 				return path, &Error{file, ErrDot}
 			}
 			return path, nil
diff --git a/src/os/exec/lp_unix_test.go b/src/os/exec/lp_unix_test.go
index ebeb5bb..181b1f0 100644
--- a/src/os/exec/lp_unix_test.go
+++ b/src/os/exec/lp_unix_test.go
@@ -12,6 +12,8 @@
 )
 
 func TestLookPathUnixEmptyPath(t *testing.T) {
+	// Not parallel: uses os.Chdir.
+
 	tmp, err := os.MkdirTemp("", "TestLookPathUnixEmptyPath")
 	if err != nil {
 		t.Fatal("TempDir failed: ", err)
diff --git a/src/os/exec/lp_windows.go b/src/os/exec/lp_windows.go
index ec45db7..97bfa58 100644
--- a/src/os/exec/lp_windows.go
+++ b/src/os/exec/lp_windows.go
@@ -6,7 +6,6 @@
 
 import (
 	"errors"
-	"internal/godebug"
 	"io/fs"
 	"os"
 	"path/filepath"
@@ -103,7 +102,7 @@
 	)
 	if _, found := syscall.Getenv("NoDefaultCurrentDirectoryInExePath"); !found {
 		if f, err := findExecutable(filepath.Join(".", file), exts); err == nil {
-			if godebug.Get("execerrdot") == "0" {
+			if execerrdot.Value() == "0" {
 				return f, nil
 			}
 			dotf, dotErr = f, &Error{file, ErrDot}
@@ -128,7 +127,7 @@
 				}
 			}
 
-			if !filepath.IsAbs(f) && godebug.Get("execerrdot") != "0" {
+			if !filepath.IsAbs(f) && execerrdot.Value() != "0" {
 				return f, &Error{file, ErrDot}
 			}
 			return f, nil
diff --git a/src/os/exec/lp_windows_test.go b/src/os/exec/lp_windows_test.go
index 1f609ff..d797b6c 100644
--- a/src/os/exec/lp_windows_test.go
+++ b/src/os/exec/lp_windows_test.go
@@ -334,12 +334,21 @@
 }
 
 func TestLookPathWindows(t *testing.T) {
+	if testing.Short() {
+		maySkipHelperCommand("lookpath")
+		t.Skipf("skipping test in short mode that would build a helper binary")
+	}
+	t.Parallel()
+
 	tmp := t.TempDir()
 	printpathExe := buildPrintPathExe(t, tmp)
 
 	// Run all tests.
 	for i, test := range lookPathTests {
+		i, test := i, test
 		t.Run(fmt.Sprint(i), func(t *testing.T) {
+			t.Parallel()
+
 			dir := filepath.Join(tmp, "d"+strconv.Itoa(i))
 			err := os.Mkdir(dir, 0700)
 			if err != nil {
@@ -524,17 +533,28 @@
 }
 
 func TestCommand(t *testing.T) {
+	if testing.Short() {
+		maySkipHelperCommand("exec")
+		t.Skipf("skipping test in short mode that would build a helper binary")
+	}
+	t.Parallel()
+
 	tmp := t.TempDir()
 	printpathExe := buildPrintPathExe(t, tmp)
 
 	// Run all tests.
 	for i, test := range commandTests {
-		dir := filepath.Join(tmp, "d"+strconv.Itoa(i))
-		err := os.Mkdir(dir, 0700)
-		if err != nil {
-			t.Fatal("Mkdir failed: ", err)
-		}
-		test.run(t, dir, printpathExe)
+		i, test := i, test
+		t.Run(fmt.Sprint(i), func(t *testing.T) {
+			t.Parallel()
+
+			dir := filepath.Join(tmp, "d"+strconv.Itoa(i))
+			err := os.Mkdir(dir, 0700)
+			if err != nil {
+				t.Fatal("Mkdir failed: ", err)
+			}
+			test.run(t, dir, printpathExe)
+		})
 	}
 }
 
diff --git a/src/os/executable_test.go b/src/os/executable_test.go
index 719d6a6..b69fe41 100644
--- a/src/os/executable_test.go
+++ b/src/os/executable_test.go
@@ -106,13 +106,13 @@
 		t.Fatal(err)
 	}
 
-	out, err := osexec.Command(testenv.GoToolPath(t), "build", "-o", exe, src).CombinedOutput()
+	out, err := testenv.Command(t, testenv.GoToolPath(t), "build", "-o", exe, src).CombinedOutput()
 	t.Logf("build output:\n%s", out)
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	out, err = osexec.Command(exe).CombinedOutput()
+	out, err = testenv.Command(t, exe).CombinedOutput()
 	t.Logf("exec output:\n%s", out)
 	if err != nil {
 		t.Fatal(err)
diff --git a/src/os/file.go b/src/os/file.go
index 9f38892..3d71ac0 100644
--- a/src/os/file.go
+++ b/src/os/file.go
@@ -42,8 +42,8 @@
 import (
 	"errors"
 	"internal/poll"
+	"internal/safefilepath"
 	"internal/testlog"
-	"internal/unsafeheader"
 	"io"
 	"io/fs"
 	"runtime"
@@ -226,10 +226,6 @@
 // relative to the current offset, and 2 means relative to the end.
 // It returns the new offset and an error, if any.
 // The behavior of Seek on a file opened with O_APPEND is not specified.
-//
-// If f is a directory, the behavior of Seek varies by operating
-// system; you can seek to the beginning of the directory on Unix-like
-// operating systems, but not on Windows.
 func (f *File) Seek(offset int64, whence int) (ret int64, err error) {
 	if err := f.checkValid("seek"); err != nil {
 		return 0, err
@@ -247,11 +243,7 @@
 // WriteString is like Write, but writes the contents of string s rather than
 // a slice of bytes.
 func (f *File) WriteString(s string) (n int, err error) {
-	var b []byte
-	hdr := (*unsafeheader.Slice)(unsafe.Pointer(&b))
-	hdr.Data = (*unsafeheader.String)(unsafe.Pointer(&s)).Data
-	hdr.Cap = len(s)
-	hdr.Len = len(s)
+	b := unsafe.Slice(unsafe.StringData(s), len(s))
 	return f.Write(b)
 }
 
@@ -259,9 +251,6 @@
 // bits (before umask).
 // If there is an error, it will be of type *PathError.
 func Mkdir(name string, perm FileMode) error {
-	if runtime.GOOS == "windows" && isWindowsNulName(name) {
-		return &PathError{Op: "mkdir", Path: name, Err: syscall.ENOTDIR}
-	}
 	longName := fixLongPath(name)
 	e := ignoringEINTR(func() error {
 		return syscall.Mkdir(longName, syscallMode(perm))
@@ -349,6 +338,7 @@
 // Rename renames (moves) oldpath to newpath.
 // If newpath already exists and is not a directory, Rename replaces it.
 // OS-specific restrictions may apply when oldpath and newpath are in different directories.
+// Even within the same directory, on non-Unix platforms Rename is not an atomic operation.
 // If there is an error, it will be of type *LinkError.
 func Rename(oldpath, newpath string) error {
 	return rename(oldpath, newpath)
@@ -596,24 +586,6 @@
 	return newRawConn(f)
 }
 
-// isWindowsNulName reports whether name is os.DevNull ('NUL') on Windows.
-// True is returned if name is 'NUL' whatever the case.
-func isWindowsNulName(name string) bool {
-	if len(name) != 3 {
-		return false
-	}
-	if name[0] != 'n' && name[0] != 'N' {
-		return false
-	}
-	if name[1] != 'u' && name[1] != 'U' {
-		return false
-	}
-	if name[2] != 'l' && name[2] != 'L' {
-		return false
-	}
-	return true
-}
-
 // DirFS returns a file system (an fs.FS) for the tree of files rooted at the directory dir.
 //
 // Note that DirFS("/prefix") only guarantees that the Open calls it makes to the
@@ -625,11 +597,14 @@
 // a general substitute for a chroot-style security mechanism when the directory tree
 // contains arbitrary content.
 //
+// The directory dir must not be "".
+//
 // The result implements fs.StatFS.
 func DirFS(dir string) fs.FS {
 	return dirFS(dir)
 }
 
+// containsAny reports whether any bytes in chars are within s.
 func containsAny(s, chars string) bool {
 	for i := 0; i < len(s); i++ {
 		for j := 0; j < len(chars); j++ {
@@ -644,27 +619,54 @@
 type dirFS string
 
 func (dir dirFS) Open(name string) (fs.File, error) {
-	if !fs.ValidPath(name) || runtime.GOOS == "windows" && containsAny(name, `\:`) {
-		return nil, &PathError{Op: "open", Path: name, Err: ErrInvalid}
-	}
-	f, err := Open(string(dir) + "/" + name)
+	fullname, err := dir.join(name)
 	if err != nil {
-		return nil, err // nil fs.File
+		return nil, &PathError{Op: "stat", Path: name, Err: err}
+	}
+	f, err := Open(fullname)
+	if err != nil {
+		// DirFS takes a string appropriate for GOOS,
+		// while the name argument here is always slash separated.
+		// dir.join will have mixed the two; undo that for
+		// error reporting.
+		err.(*PathError).Path = name
+		return nil, err
 	}
 	return f, nil
 }
 
 func (dir dirFS) Stat(name string) (fs.FileInfo, error) {
-	if !fs.ValidPath(name) || runtime.GOOS == "windows" && containsAny(name, `\:`) {
-		return nil, &PathError{Op: "stat", Path: name, Err: ErrInvalid}
-	}
-	f, err := Stat(string(dir) + "/" + name)
+	fullname, err := dir.join(name)
 	if err != nil {
+		return nil, &PathError{Op: "stat", Path: name, Err: err}
+	}
+	f, err := Stat(fullname)
+	if err != nil {
+		// See comment in dirFS.Open.
+		err.(*PathError).Path = name
 		return nil, err
 	}
 	return f, nil
 }
 
+// join returns the path for name in dir.
+func (dir dirFS) join(name string) (string, error) {
+	if dir == "" {
+		return "", errors.New("os: DirFS with empty root")
+	}
+	if !fs.ValidPath(name) {
+		return "", ErrInvalid
+	}
+	name, err := safefilepath.FromFS(name)
+	if err != nil {
+		return "", ErrInvalid
+	}
+	if IsPathSeparator(dir[len(dir)-1]) {
+		return string(dir) + name, nil
+	}
+	return string(dir) + string(PathSeparator) + name, nil
+}
+
 // ReadFile reads the named file and returns the contents.
 // A successful call returns err == nil, not err == EOF.
 // Because ReadFile reads the whole file, it does not treat an EOF from Read
@@ -713,6 +715,8 @@
 // WriteFile writes data to the named file, creating it if necessary.
 // If the file does not exist, WriteFile creates it with permissions perm (before umask);
 // otherwise WriteFile truncates it before writing, without changing permissions.
+// Since Writefile requires multiple system calls to complete, a failure mid-operation
+// can leave the file in a partially written state.
 func WriteFile(name string, data []byte, perm FileMode) error {
 	f, err := OpenFile(name, O_WRONLY|O_CREATE|O_TRUNC, perm)
 	if err != nil {
diff --git a/src/os/file_mutex_plan9.go b/src/os/file_mutex_plan9.go
new file mode 100644
index 0000000..26bf5a7
--- /dev/null
+++ b/src/os/file_mutex_plan9.go
@@ -0,0 +1,70 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package os
+
+// File locking support for Plan 9. This uses fdMutex from the
+// internal/poll package.
+
+// incref adds a reference to the file. It returns an error if the file
+// is already closed. This method is on File so that we can incorporate
+// a nil test.
+func (f *File) incref(op string) (err error) {
+	if f == nil {
+		return ErrInvalid
+	}
+	if !f.fdmu.Incref() {
+		err = ErrClosed
+		if op != "" {
+			err = &PathError{Op: op, Path: f.name, Err: err}
+		}
+	}
+	return err
+}
+
+// decref removes a reference to the file. If this is the last
+// remaining reference, and the file has been marked to be closed,
+// then actually close it.
+func (file *file) decref() error {
+	if file.fdmu.Decref() {
+		return file.destroy()
+	}
+	return nil
+}
+
+// readLock adds a reference to the file and locks it for reading.
+// It returns an error if the file is already closed.
+func (file *file) readLock() error {
+	if !file.fdmu.ReadLock() {
+		return ErrClosed
+	}
+	return nil
+}
+
+// readUnlock removes a reference from the file and unlocks it for reading.
+// It also closes the file if it marked as closed and there is no remaining
+// reference.
+func (file *file) readUnlock() {
+	if file.fdmu.ReadUnlock() {
+		file.destroy()
+	}
+}
+
+// writeLock adds a reference to the file and locks it for writing.
+// It returns an error if the file is already closed.
+func (file *file) writeLock() error {
+	if !file.fdmu.WriteLock() {
+		return ErrClosed
+	}
+	return nil
+}
+
+// writeUnlock removes a reference from the file and unlocks it for writing.
+// It also closes the file if it is marked as closed and there is no remaining
+// reference.
+func (file *file) writeUnlock() {
+	if file.fdmu.WriteUnlock() {
+		file.destroy()
+	}
+}
diff --git a/src/os/file_plan9.go b/src/os/file_plan9.go
index 93eb233..6e05df1 100644
--- a/src/os/file_plan9.go
+++ b/src/os/file_plan9.go
@@ -22,6 +22,7 @@
 // can overwrite this data, which could cause the finalizer
 // to close the wrong file descriptor.
 type file struct {
+	fdmu       poll.FDMutex
 	fd         int
 	name       string
 	dirinfo    *dirInfo // nil unless directory being read
@@ -142,24 +143,35 @@
 // be canceled and return immediately with an ErrClosed error.
 // Close will return an error if it has already been called.
 func (f *File) Close() error {
-	if err := f.checkValid("close"); err != nil {
-		return err
+	if f == nil {
+		return ErrInvalid
 	}
 	return f.file.close()
 }
 
 func (file *file) close() error {
-	if file == nil || file.fd == badFd {
-		return ErrInvalid
+	if !file.fdmu.IncrefAndClose() {
+		return &PathError{Op: "close", Path: file.name, Err: ErrClosed}
 	}
+
+	// At this point we should cancel any pending I/O.
+	// How do we do that on Plan 9?
+
+	err := file.decref()
+
+	// no need for a finalizer anymore
+	runtime.SetFinalizer(file, nil)
+	return err
+}
+
+// destroy actually closes the descriptor. This is called when
+// there are no remaining references, by the decref, readUnlock,
+// and writeUnlock methods.
+func (file *file) destroy() error {
 	var err error
 	if e := syscall.Close(file.fd); e != nil {
 		err = &PathError{Op: "close", Path: file.name, Err: e}
 	}
-	file.fd = badFd // so it can't be closed again
-
-	// no need for a finalizer anymore
-	runtime.SetFinalizer(file, nil)
 	return err
 }
 
@@ -193,6 +205,12 @@
 	if err != nil {
 		return &PathError{Op: "truncate", Path: f.name, Err: err}
 	}
+
+	if err := f.incref("truncate"); err != nil {
+		return err
+	}
+	defer f.decref()
+
 	if err = syscall.Fwstat(f.fd, buf[:n]); err != nil {
 		return &PathError{Op: "truncate", Path: f.name, Err: err}
 	}
@@ -219,6 +237,12 @@
 	if err != nil {
 		return &PathError{Op: "chmod", Path: f.name, Err: err}
 	}
+
+	if err := f.incref("chmod"); err != nil {
+		return err
+	}
+	defer f.decref()
+
 	if err = syscall.Fwstat(f.fd, buf[:n]); err != nil {
 		return &PathError{Op: "chmod", Path: f.name, Err: err}
 	}
@@ -240,6 +264,12 @@
 	if err != nil {
 		return &PathError{Op: "sync", Path: f.name, Err: err}
 	}
+
+	if err := f.incref("sync"); err != nil {
+		return err
+	}
+	defer f.decref()
+
 	if err = syscall.Fwstat(f.fd, buf[:n]); err != nil {
 		return &PathError{Op: "sync", Path: f.name, Err: err}
 	}
@@ -249,6 +279,10 @@
 // read reads up to len(b) bytes from the File.
 // It returns the number of bytes read and an error, if any.
 func (f *File) read(b []byte) (n int, err error) {
+	if err := f.readLock(); err != nil {
+		return 0, err
+	}
+	defer f.readUnlock()
 	n, e := fixCount(syscall.Read(f.fd, b))
 	if n == 0 && len(b) > 0 && e == nil {
 		return 0, io.EOF
@@ -260,6 +294,10 @@
 // It returns the number of bytes read and the error, if any.
 // EOF is signaled by a zero count with err set to nil.
 func (f *File) pread(b []byte, off int64) (n int, err error) {
+	if err := f.readLock(); err != nil {
+		return 0, err
+	}
+	defer f.readUnlock()
 	n, e := fixCount(syscall.Pread(f.fd, b, off))
 	if n == 0 && len(b) > 0 && e == nil {
 		return 0, io.EOF
@@ -272,6 +310,10 @@
 // Since Plan 9 preserves message boundaries, never allow
 // a zero-byte write.
 func (f *File) write(b []byte) (n int, err error) {
+	if err := f.writeLock(); err != nil {
+		return 0, err
+	}
+	defer f.writeUnlock()
 	if len(b) == 0 {
 		return 0, nil
 	}
@@ -283,6 +325,10 @@
 // Since Plan 9 preserves message boundaries, never allow
 // a zero-byte write.
 func (f *File) pwrite(b []byte, off int64) (n int, err error) {
+	if err := f.writeLock(); err != nil {
+		return 0, err
+	}
+	defer f.writeUnlock()
 	if len(b) == 0 {
 		return 0, nil
 	}
@@ -294,6 +340,10 @@
 // relative to the current offset, and 2 means relative to the end.
 // It returns the new offset and an error, if any.
 func (f *File) seek(offset int64, whence int) (ret int64, err error) {
+	if err := f.incref(""); err != nil {
+		return 0, err
+	}
+	defer f.decref()
 	if f.dirinfo != nil {
 		// Free cached dirinfo, so we allocate a new one if we
 		// access this file as a directory again. See #35767 and #37161.
@@ -331,7 +381,7 @@
 	return nil
 }
 
-// HasPrefix from the strings package.
+// hasPrefix from the strings package.
 func hasPrefix(s, prefix string) bool {
 	return len(s) >= len(prefix) && s[0:len(prefix)] == prefix
 }
@@ -493,9 +543,10 @@
 // which must be a directory.
 // If there is an error, it will be of type *PathError.
 func (f *File) Chdir() error {
-	if err := f.checkValid("chdir"); err != nil {
+	if err := f.incref("chdir"); err != nil {
 		return err
 	}
+	defer f.decref()
 	if e := syscall.Fchdir(f.fd); e != nil {
 		return &PathError{Op: "chdir", Path: f.name, Err: e}
 	}
@@ -526,16 +577,17 @@
 	return poll.ErrNoDeadline
 }
 
-// checkValid checks whether f is valid for use.
-// If not, it returns an appropriate error, perhaps incorporating the operation name op.
+// checkValid checks whether f is valid for use, but does not prepare
+// to actually use it. If f is not ready checkValid returns an appropriate
+// error, perhaps incorporating the operation name op.
 func (f *File) checkValid(op string) error {
 	if f == nil {
 		return ErrInvalid
 	}
-	if f.fd == badFd {
-		return &PathError{Op: op, Path: f.name, Err: ErrClosed}
+	if err := f.incref(op); err != nil {
+		return err
 	}
-	return nil
+	return f.decref()
 }
 
 type rawConn struct{}
diff --git a/src/os/file_unix.go b/src/os/file_unix.go
index c30a689..1833c26 100644
--- a/src/os/file_unix.go
+++ b/src/os/file_unix.go
@@ -168,18 +168,28 @@
 		}
 	}
 
-	if err := f.pfd.Init("file", pollable); err != nil {
-		// An error here indicates a failure to register
-		// with the netpoll system. That can happen for
-		// a file descriptor that is not supported by
-		// epoll/kqueue; for example, disk files on
-		// Linux systems. We assume that any real error
-		// will show up in later I/O.
-	} else if pollable {
-		// We successfully registered with netpoll, so put
-		// the file into nonblocking mode.
-		if err := syscall.SetNonblock(fdi, true); err == nil {
+	clearNonBlock := false
+	if pollable {
+		if kind == kindNonBlock {
 			f.nonblock = true
+		} else if err := syscall.SetNonblock(fdi, true); err == nil {
+			f.nonblock = true
+			clearNonBlock = true
+		} else {
+			pollable = false
+		}
+	}
+
+	// An error here indicates a failure to register
+	// with the netpoll system. That can happen for
+	// a file descriptor that is not supported by
+	// epoll/kqueue; for example, disk files on
+	// Linux systems. We assume that any real error
+	// will show up in later I/O.
+	// We do restore the blocking behavior if it was set by us.
+	if pollErr := f.pfd.Init("file", pollable); pollErr != nil && clearNonBlock {
+		if err := syscall.SetNonblock(fdi, false); err == nil {
+			f.nonblock = false
 		}
 	}
 
diff --git a/src/os/file_windows.go b/src/os/file_windows.go
index db5c27d..d94b78f 100644
--- a/src/os/file_windows.go
+++ b/src/os/file_windows.go
@@ -86,10 +86,14 @@
 
 // Auxiliary information if the File describes a directory
 type dirInfo struct {
-	data     syscall.Win32finddata
-	needdata bool
-	path     string
-	isempty  bool // set if FindFirstFile returns ERROR_FILE_NOT_FOUND
+	h       syscall.Handle // search handle created with FindFirstFile
+	data    syscall.Win32finddata
+	path    string
+	isempty bool // set if FindFirstFile returns ERROR_FILE_NOT_FOUND
+}
+
+func (d *dirInfo) close() error {
+	return syscall.FindClose(d.h)
 }
 
 func epipecheck(file *File, e error) {
@@ -99,17 +103,7 @@
 // On Unix-like systems, it is "/dev/null"; on Windows, "NUL".
 const DevNull = "NUL"
 
-func (f *file) isdir() bool { return f != nil && f.dirinfo != nil }
-
-func openFile(name string, flag int, perm FileMode) (file *File, err error) {
-	r, e := syscall.Open(fixLongPath(name), flag|syscall.O_CLOEXEC, syscallMode(perm))
-	if e != nil {
-		return nil, e
-	}
-	return newFile(r, name, "file"), nil
-}
-
-func openDir(name string) (file *File, err error) {
+func openDir(name string) (d *dirInfo, e error) {
 	var mask string
 
 	path := fixLongPath(name)
@@ -130,25 +124,27 @@
 	if e != nil {
 		return nil, e
 	}
-	d := new(dirInfo)
-	r, e := syscall.FindFirstFile(maskp, &d.data)
+	d = new(dirInfo)
+	d.h, e = syscall.FindFirstFile(maskp, &d.data)
 	if e != nil {
 		// FindFirstFile returns ERROR_FILE_NOT_FOUND when
 		// no matching files can be found. Then, if directory
 		// exists, we should proceed.
-		if e != syscall.ERROR_FILE_NOT_FOUND {
-			return nil, e
-		}
+		// If FindFirstFile failed because name does not point
+		// to a directory, we should return ENOTDIR.
 		var fa syscall.Win32FileAttributeData
-		pathp, e := syscall.UTF16PtrFromString(path)
-		if e != nil {
+		pathp, e1 := syscall.UTF16PtrFromString(path)
+		if e1 != nil {
 			return nil, e
 		}
-		e = syscall.GetFileAttributesEx(pathp, syscall.GetFileExInfoStandard, (*byte)(unsafe.Pointer(&fa)))
-		if e != nil {
+		e1 = syscall.GetFileAttributesEx(pathp, syscall.GetFileExInfoStandard, (*byte)(unsafe.Pointer(&fa)))
+		if e1 != nil {
 			return nil, e
 		}
 		if fa.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY == 0 {
+			return nil, syscall.ENOTDIR
+		}
+		if e != syscall.ERROR_FILE_NOT_FOUND {
 			return nil, e
 		}
 		d.isempty = true
@@ -157,12 +153,11 @@
 	if !isAbs(d.path) {
 		d.path, e = syscall.FullPath(d.path)
 		if e != nil {
+			d.close()
 			return nil, e
 		}
 	}
-	f := newFile(r, name, "dir")
-	f.dirinfo = d
-	return f, nil
+	return d, nil
 }
 
 // openFileNolog is the Windows implementation of OpenFile.
@@ -170,28 +165,36 @@
 	if name == "" {
 		return nil, &PathError{Op: "open", Path: name, Err: syscall.ENOENT}
 	}
-	r, errf := openFile(name, flag, perm)
-	if errf == nil {
-		return r, nil
-	}
-	r, errd := openDir(name)
-	if errd == nil {
-		if flag&O_WRONLY != 0 || flag&O_RDWR != 0 {
-			r.Close()
-			return nil, &PathError{Op: "open", Path: name, Err: syscall.EISDIR}
+	path := fixLongPath(name)
+	r, e := syscall.Open(path, flag|syscall.O_CLOEXEC, syscallMode(perm))
+	if e != nil {
+		// We should return EISDIR when we are trying to open a directory with write access.
+		if e == syscall.ERROR_ACCESS_DENIED && (flag&O_WRONLY != 0 || flag&O_RDWR != 0) {
+			pathp, e1 := syscall.UTF16PtrFromString(path)
+			if e1 == nil {
+				var fa syscall.Win32FileAttributeData
+				e1 = syscall.GetFileAttributesEx(pathp, syscall.GetFileExInfoStandard, (*byte)(unsafe.Pointer(&fa)))
+				if e1 == nil && fa.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 {
+					e = syscall.EISDIR
+				}
+			}
 		}
-		return r, nil
+		return nil, &PathError{Op: "open", Path: name, Err: e}
 	}
-	return nil, &PathError{Op: "open", Path: name, Err: errf}
+	f, e := newFile(r, name, "file"), nil
+	if e != nil {
+		return nil, &PathError{Op: "open", Path: name, Err: e}
+	}
+	return f, nil
 }
 
 func (file *file) close() error {
 	if file == nil {
 		return syscall.EINVAL
 	}
-	if file.isdir() && file.dirinfo.isempty {
-		// "special" empty directories
-		return nil
+	if file.dirinfo != nil {
+		file.dirinfo.close()
+		file.dirinfo = nil
 	}
 	var err error
 	if e := file.pfd.Close(); e != nil {
@@ -211,6 +214,12 @@
 // relative to the current offset, and 2 means relative to the end.
 // It returns the new offset and an error, if any.
 func (f *File) seek(offset int64, whence int) (ret int64, err error) {
+	if f.dirinfo != nil {
+		// Free cached dirinfo, so we allocate a new one if we
+		// access this file as a directory again. See #35767 and #37161.
+		f.dirinfo.close()
+		f.dirinfo = nil
+	}
 	ret, err = f.pfd.Seek(offset, whence)
 	runtime.KeepAlive(f)
 	return ret, err
diff --git a/src/os/os_test.go b/src/os/os_test.go
index ea935d3..277b245 100644
--- a/src/os/os_test.go
+++ b/src/os/os_test.go
@@ -5,7 +5,6 @@
 package os_test
 
 import (
-	"bytes"
 	"errors"
 	"flag"
 	"fmt"
@@ -275,9 +274,11 @@
 	if !equal(sfname, dir.Name()) {
 		t.Error("name should be ", sfname, "; is", dir.Name())
 	}
-	filesize := size(path, t)
-	if dir.Size() != filesize {
-		t.Error("size should be", filesize, "; is", dir.Size())
+	if dir.Mode()&ModeSymlink == 0 {
+		filesize := size(path, t)
+		if dir.Size() != filesize {
+			t.Error("size should be", filesize, "; is", dir.Size())
+		}
 	}
 }
 
@@ -315,12 +316,8 @@
 	_, err = file.Read(b)
 
 	e, ok := err.(*PathError)
-	if !ok {
-		t.Fatalf("Read: %T(%v), want PathError", e, e)
-	}
-
-	if e.Err != ErrClosed {
-		t.Errorf("Read: %v, want PathError(ErrClosed)", e)
+	if !ok || e.Err != ErrClosed {
+		t.Fatalf("Read: got %T(%v), want %T(%v)", err, err, e, ErrClosed)
 	}
 }
 
@@ -1167,7 +1164,7 @@
 	}
 	w.Close()
 
-	var b bytes.Buffer
+	var b strings.Builder
 	io.Copy(&b, r)
 	output := b.String()
 
@@ -1718,7 +1715,7 @@
 	}
 	w.Close()
 
-	var b bytes.Buffer
+	var b strings.Builder
 	io.Copy(&b, r)
 	_, err = p.Wait()
 	if err != nil {
@@ -1740,7 +1737,7 @@
 }
 
 func testWindowsHostname(t *testing.T, hostname string) {
-	cmd := osexec.Command("hostname")
+	cmd := testenv.Command(t, "hostname")
 	out, err := cmd.Output()
 	if err != nil {
 		t.Fatalf("Failed to execute hostname command: %v %s", err, out)
@@ -2017,18 +2014,8 @@
 	}
 }
 
-func testDevNullFileInfo(t *testing.T, statname, devNullName string, fi FileInfo, ignoreCase bool) {
+func testDevNullFileInfo(t *testing.T, statname, devNullName string, fi FileInfo) {
 	pre := fmt.Sprintf("%s(%q): ", statname, devNullName)
-	name := filepath.Base(devNullName)
-	if ignoreCase {
-		if strings.ToUpper(fi.Name()) != strings.ToUpper(name) {
-			t.Errorf(pre+"wrong file name have %v want %v", fi.Name(), name)
-		}
-	} else {
-		if fi.Name() != name {
-			t.Errorf(pre+"wrong file name have %v want %v", fi.Name(), name)
-		}
-	}
 	if fi.Size() != 0 {
 		t.Errorf(pre+"wrong file size have %d want 0", fi.Size())
 	}
@@ -2043,7 +2030,7 @@
 	}
 }
 
-func testDevNullFile(t *testing.T, devNullName string, ignoreCase bool) {
+func testDevNullFile(t *testing.T, devNullName string) {
 	f, err := Open(devNullName)
 	if err != nil {
 		t.Fatalf("Open(%s): %v", devNullName, err)
@@ -2054,17 +2041,21 @@
 	if err != nil {
 		t.Fatalf("Stat(%s): %v", devNullName, err)
 	}
-	testDevNullFileInfo(t, "f.Stat", devNullName, fi, ignoreCase)
+	testDevNullFileInfo(t, "f.Stat", devNullName, fi)
 
 	fi, err = Stat(devNullName)
 	if err != nil {
 		t.Fatalf("Stat(%s): %v", devNullName, err)
 	}
-	testDevNullFileInfo(t, "Stat", devNullName, fi, ignoreCase)
+	testDevNullFileInfo(t, "Stat", devNullName, fi)
 }
 
 func TestDevNullFile(t *testing.T) {
-	testDevNullFile(t, DevNull, false)
+	testDevNullFile(t, DevNull)
+	if runtime.GOOS == "windows" {
+		testDevNullFile(t, "./nul")
+		testDevNullFile(t, "//./nul")
+	}
 }
 
 var testLargeWrite = flag.Bool("large_write", false, "run TestLargeWriteToConsole test that floods console with output")
@@ -2141,9 +2132,9 @@
 
 	var cmd *osexec.Cmd
 	if runtime.GOOS == "windows" {
-		cmd = osexec.Command("cmd", "/c", "echo output | "+Args[0]+" -test.run=TestStatStdin")
+		cmd = testenv.Command(t, "cmd", "/c", "echo output | "+Args[0]+" -test.run=TestStatStdin")
 	} else {
-		cmd = osexec.Command("/bin/sh", "-c", "echo output | "+Args[0]+" -test.run=TestStatStdin")
+		cmd = testenv.Command(t, "/bin/sh", "-c", "echo output | "+Args[0]+" -test.run=TestStatStdin")
 	}
 	cmd.Env = append(Environ(), "GO_WANT_HELPER_PROCESS=1")
 
@@ -2298,7 +2289,7 @@
 	t.Parallel()
 
 	// Re-exec the test binary to start a process that hangs until stdin is closed.
-	cmd := osexec.Command(Args[0])
+	cmd := testenv.Command(t, Args[0])
 	cmd.Env = append(os.Environ(), "GO_OS_TEST_DRAIN_STDIN=1")
 	stdout, err := cmd.StdoutPipe()
 	if err != nil {
@@ -2349,7 +2340,7 @@
 		Exit(0)
 	}
 
-	cmd := osexec.Command(Args[0], "-test.run=TestGetppid")
+	cmd := testenv.Command(t, Args[0], "-test.run=TestGetppid")
 	cmd.Env = append(Environ(), "GO_WANT_HELPER_PROCESS=1")
 
 	// verify that Getppid() from the forked process reports our process id
@@ -2544,9 +2535,9 @@
 	if err := file.Close(); err == nil {
 		t.Error("second Close did not fail")
 	} else if pe, ok := err.(*PathError); !ok {
-		t.Errorf("second Close returned unexpected error type %T; expected fs.PathError", pe)
+		t.Errorf("second Close: got %T, want %T", err, pe)
 	} else if pe.Err != ErrClosed {
-		t.Errorf("second Close returned %q, wanted %q", err, ErrClosed)
+		t.Errorf("second Close: got %q, want %q", pe.Err, ErrClosed)
 	} else {
 		t.Logf("second close returned expected error %q", err)
 	}
@@ -2575,9 +2566,6 @@
 }
 
 func TestDirSeek(t *testing.T) {
-	if runtime.GOOS == "windows" {
-		testenv.SkipFlaky(t, 36019)
-	}
 	wd, err := Getwd()
 	if err != nil {
 		t.Fatal(err)
@@ -2620,9 +2608,6 @@
 	// See issue 37161. Read only one entry from a directory,
 	// seek to the beginning, and read again. We should not see
 	// duplicate entries.
-	if runtime.GOOS == "windows" {
-		testenv.SkipFlaky(t, 36019)
-	}
 	wd, err := Getwd()
 	if err != nil {
 		t.Fatal(err)
@@ -2717,16 +2702,70 @@
 			t.Fatal(err)
 		}
 	}
-	if err := fstest.TestFS(DirFS("./testdata/dirfs"), "a", "b", "dir/x"); err != nil {
+	fs := DirFS("./testdata/dirfs")
+	if err := fstest.TestFS(fs, "a", "b", "dir/x"); err != nil {
 		t.Fatal(err)
 	}
 
+	// Test that the error message does not contain a backslash,
+	// and does not contain the DirFS argument.
+	const nonesuch = "dir/nonesuch"
+	_, err := fs.Open(nonesuch)
+	if err == nil {
+		t.Error("fs.Open of nonexistent file succeeded")
+	} else {
+		if !strings.Contains(err.Error(), nonesuch) {
+			t.Errorf("error %q does not contain %q", err, nonesuch)
+		}
+		if strings.Contains(err.(*PathError).Path, "testdata") {
+			t.Errorf("error %q contains %q", err, "testdata")
+		}
+	}
+
 	// Test that Open does not accept backslash as separator.
 	d := DirFS(".")
-	_, err := d.Open(`testdata\dirfs`)
+	_, err = d.Open(`testdata\dirfs`)
 	if err == nil {
 		t.Fatalf(`Open testdata\dirfs succeeded`)
 	}
+
+	// Test that Open does not open Windows device files.
+	_, err = d.Open(`NUL`)
+	if err == nil {
+		t.Errorf(`Open NUL succeeded`)
+	}
+}
+
+func TestDirFSRootDir(t *testing.T) {
+	cwd, err := os.Getwd()
+	if err != nil {
+		t.Fatal(err)
+	}
+	cwd = cwd[len(filepath.VolumeName(cwd)):] // trim volume prefix (C:) on Windows
+	cwd = filepath.ToSlash(cwd)               // convert \ to /
+	cwd = strings.TrimPrefix(cwd, "/")        // trim leading /
+
+	// Test that Open can open a path starting at /.
+	d := DirFS("/")
+	f, err := d.Open(cwd + "/testdata/dirfs/a")
+	if err != nil {
+		t.Fatal(err)
+	}
+	f.Close()
+}
+
+func TestDirFSEmptyDir(t *testing.T) {
+	d := DirFS("")
+	cwd, _ := os.Getwd()
+	for _, path := range []string{
+		"testdata/dirfs/a",                          // not DirFS(".")
+		filepath.ToSlash(cwd) + "/testdata/dirfs/a", // not DirFS("/")
+	} {
+		_, err := d.Open(path)
+		if err == nil {
+			t.Fatalf(`DirFS("").Open(%q) succeeded`, path)
+		}
+	}
 }
 
 func TestDirFSPathsValid(t *testing.T) {
@@ -2792,3 +2831,115 @@
 		t.Errorf("expected 0 allocs for File.WriteString, got %v", allocs)
 	}
 }
+
+// Test that it's OK to have parallel I/O and Close on a pipe.
+func TestPipeIOCloseRace(t *testing.T) {
+	// Skip on wasm, which doesn't have pipes.
+	if runtime.GOOS == "js" {
+		t.Skip("skipping on js: no pipes")
+	}
+
+	r, w, err := Pipe()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	var wg sync.WaitGroup
+	wg.Add(3)
+
+	go func() {
+		defer wg.Done()
+		for {
+			n, err := w.Write([]byte("hi"))
+			if err != nil {
+				// We look at error strings as the
+				// expected errors are OS-specific.
+				switch {
+				case errors.Is(err, ErrClosed),
+					strings.Contains(err.Error(), "broken pipe"),
+					strings.Contains(err.Error(), "pipe is being closed"),
+					strings.Contains(err.Error(), "hungup channel"):
+					// Ignore an expected error.
+				default:
+					// Unexpected error.
+					t.Error(err)
+				}
+				return
+			}
+			if n != 2 {
+				t.Errorf("wrote %d bytes, expected 2", n)
+				return
+			}
+		}
+	}()
+
+	go func() {
+		defer wg.Done()
+		for {
+			var buf [2]byte
+			n, err := r.Read(buf[:])
+			if err != nil {
+				if err != io.EOF && !errors.Is(err, ErrClosed) {
+					t.Error(err)
+				}
+				return
+			}
+			if n != 2 {
+				t.Errorf("read %d bytes, want 2", n)
+			}
+		}
+	}()
+
+	go func() {
+		defer wg.Done()
+
+		// Let the other goroutines start. This is just to get
+		// a better test, the test will still pass if they
+		// don't start.
+		time.Sleep(time.Millisecond)
+
+		if err := r.Close(); err != nil {
+			t.Error(err)
+		}
+		if err := w.Close(); err != nil {
+			t.Error(err)
+		}
+	}()
+
+	wg.Wait()
+}
+
+// Test that it's OK to call Close concurrently on a pipe.
+func TestPipeCloseRace(t *testing.T) {
+	// Skip on wasm, which doesn't have pipes.
+	if runtime.GOOS == "js" {
+		t.Skip("skipping on js: no pipes")
+	}
+
+	r, w, err := Pipe()
+	if err != nil {
+		t.Fatal(err)
+	}
+	var wg sync.WaitGroup
+	c := make(chan error, 4)
+	f := func() {
+		defer wg.Done()
+		c <- r.Close()
+		c <- w.Close()
+	}
+	wg.Add(2)
+	go f()
+	go f()
+	nils, errs := 0, 0
+	for i := 0; i < 4; i++ {
+		err := <-c
+		if err == nil {
+			nils++
+		} else {
+			errs++
+		}
+	}
+	if nils != 2 || errs != 2 {
+		t.Errorf("got nils %d errs %d, want 2 2", nils, errs)
+	}
+}
diff --git a/src/os/os_windows_test.go b/src/os/os_windows_test.go
index 41a066d..b9fad71 100644
--- a/src/os/os_windows_test.go
+++ b/src/os/os_windows_test.go
@@ -891,10 +891,6 @@
 }
 
 func TestWindowsDevNullFile(t *testing.T) {
-	testDevNullFile(t, "NUL", true)
-	testDevNullFile(t, "nul", true)
-	testDevNullFile(t, "Nul", true)
-
 	f1, err := os.Open("NUL")
 	if err != nil {
 		t.Fatal(err)
@@ -922,6 +918,30 @@
 	}
 }
 
+func TestFileStatNUL(t *testing.T) {
+	f, err := os.Open("NUL")
+	if err != nil {
+		t.Fatal(err)
+	}
+	fi, err := f.Stat()
+	if err != nil {
+		t.Fatal(err)
+	}
+	if got, want := fi.Mode(), os.ModeDevice|os.ModeCharDevice|0666; got != want {
+		t.Errorf("Open(%q).Stat().Mode() = %v, want %v", "NUL", got, want)
+	}
+}
+
+func TestStatNUL(t *testing.T) {
+	fi, err := os.Stat("NUL")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if got, want := fi.Mode(), os.ModeDevice|os.ModeCharDevice|0666; got != want {
+		t.Errorf("Stat(%q).Mode() = %v, want %v", "NUL", got, want)
+	}
+}
+
 // TestSymlinkCreation verifies that creating a symbolic link
 // works on Windows when developer mode is active.
 // This is supported starting Windows 10 (1703, v10.0.14972).
@@ -1233,18 +1253,27 @@
 	testReadlink(t, "relfilelink", "file")
 }
 
-// os.Mkdir(os.DevNull) fails.
-func TestMkdirDevNull(t *testing.T) {
-	err := os.Mkdir(os.DevNull, 777)
-	oserr, ok := err.(*fs.PathError)
-	if !ok {
-		t.Fatalf("error (%T) is not *fs.PathError", err)
+func TestOpenDirTOCTOU(t *testing.T) {
+	// Check opened directories can't be renamed until the handle is closed.
+	// See issue 52747.
+	tmpdir := t.TempDir()
+	dir := filepath.Join(tmpdir, "dir")
+	if err := os.Mkdir(dir, 0777); err != nil {
+		t.Fatal(err)
 	}
-	errno, ok := oserr.Err.(syscall.Errno)
-	if !ok {
-		t.Fatalf("error (%T) is not syscall.Errno", oserr)
+	f, err := os.Open(dir)
+	if err != nil {
+		t.Fatal(err)
 	}
-	if errno != syscall.ENOTDIR {
-		t.Fatalf("error %d is not syscall.ENOTDIR", errno)
+	newpath := filepath.Join(tmpdir, "dir1")
+	err = os.Rename(dir, newpath)
+	if err == nil || !errors.Is(err, windows.ERROR_SHARING_VIOLATION) {
+		f.Close()
+		t.Fatalf("Rename(%q, %q) = %v; want windows.ERROR_SHARING_VIOLATION", dir, newpath, err)
+	}
+	f.Close()
+	err = os.Rename(dir, newpath)
+	if err != nil {
+		t.Error(err)
 	}
 }
diff --git a/src/os/proc.go b/src/os/proc.go
index cbd5a6a..3aae568 100644
--- a/src/os/proc.go
+++ b/src/os/proc.go
@@ -60,19 +60,21 @@
 //
 // For portability, the status code should be in the range [0, 125].
 func Exit(code int) {
-	if code == 0 {
-		if testlog.PanicOnExit0() {
-			// We were told to panic on calls to os.Exit(0).
-			// This is used to fail tests that make an early
-			// unexpected call to os.Exit(0).
-			panic("unexpected call to os.Exit(0) during test")
-		}
-
-		// Give race detector a chance to fail the program.
-		// Racy programs do not have the right to finish successfully.
-		runtime_beforeExit()
+	if code == 0 && testlog.PanicOnExit0() {
+		// We were told to panic on calls to os.Exit(0).
+		// This is used to fail tests that make an early
+		// unexpected call to os.Exit(0).
+		panic("unexpected call to os.Exit(0) during test")
 	}
+
+	// Inform the runtime that os.Exit is being called. If -race is
+	// enabled, this will give race detector a chance to fail the
+	// program (racy programs do not have the right to finish
+	// successfully). If coverage is enabled, then this call will
+	// enable us to write out a coverage data file.
+	runtime_beforeExit(code)
+
 	syscall.Exit(code)
 }
 
-func runtime_beforeExit() // implemented in runtime
+func runtime_beforeExit(exitCode int) // implemented in runtime
diff --git a/src/os/readfrom_linux_test.go b/src/os/readfrom_linux_test.go
index cb6a59a..982a2b6 100644
--- a/src/os/readfrom_linux_test.go
+++ b/src/os/readfrom_linux_test.go
@@ -13,6 +13,7 @@
 	. "os"
 	"path/filepath"
 	"strconv"
+	"strings"
 	"syscall"
 	"testing"
 	"time"
@@ -74,6 +75,56 @@
 		mustSeekStart(t, dst2)
 		mustContainData(t, dst2, data) // through traditional means
 	})
+	t.Run("CopyFileItself", func(t *testing.T) {
+		hook := hookCopyFileRange(t)
+
+		f, err := os.CreateTemp("", "file-readfrom-itself-test")
+		if err != nil {
+			t.Fatalf("failed to create tmp file: %v", err)
+		}
+		t.Cleanup(func() {
+			f.Close()
+			os.Remove(f.Name())
+		})
+
+		data := []byte("hello world!")
+		if _, err := f.Write(data); err != nil {
+			t.Fatalf("failed to create and feed the file: %v", err)
+		}
+
+		if err := f.Sync(); err != nil {
+			t.Fatalf("failed to save the file: %v", err)
+		}
+
+		// Rewind it.
+		if _, err := f.Seek(0, io.SeekStart); err != nil {
+			t.Fatalf("failed to rewind the file: %v", err)
+		}
+
+		// Read data from the file itself.
+		if _, err := io.Copy(f, f); err != nil {
+			t.Fatalf("failed to read from the file: %v", err)
+		}
+
+		if !hook.called || hook.written != 0 || hook.handled || hook.err != nil {
+			t.Fatalf("poll.CopyFileRange should be called and return the EINVAL error, but got hook.called=%t, hook.err=%v", hook.called, hook.err)
+		}
+
+		// Rewind it.
+		if _, err := f.Seek(0, io.SeekStart); err != nil {
+			t.Fatalf("failed to rewind the file: %v", err)
+		}
+
+		data2, err := io.ReadAll(f)
+		if err != nil {
+			t.Fatalf("failed to read from the file: %v", err)
+		}
+
+		// It should wind up a double of the original data.
+		if strings.Repeat(string(data), 2) != string(data2) {
+			t.Fatalf("data mismatch: %s != %s", string(data), string(data2))
+		}
+	})
 	t.Run("NotRegular", func(t *testing.T) {
 		t.Run("BothPipes", func(t *testing.T) {
 			hook := hookCopyFileRange(t)
@@ -344,6 +395,10 @@
 	srcfd  int
 	remain int64
 
+	written int64
+	handled bool
+	err     error
+
 	original func(dst, src *poll.FD, remain int64) (int64, bool, error)
 }
 
@@ -354,7 +409,8 @@
 		h.dstfd = dst.Sysfd
 		h.srcfd = src.Sysfd
 		h.remain = remain
-		return h.original(dst, src, remain)
+		h.written, h.handled, h.err = h.original(dst, src, remain)
+		return h.written, h.handled, h.err
 	}
 }
 
diff --git a/src/os/rlimit.go b/src/os/rlimit.go
index a89414d..e0d0ef9 100644
--- a/src/os/rlimit.go
+++ b/src/os/rlimit.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
+//go:build unix
 
 package os
 
diff --git a/src/os/signal/doc.go b/src/os/signal/doc.go
index ab262ed..1b9f40d 100644
--- a/src/os/signal/doc.go
+++ b/src/os/signal/doc.go
@@ -164,6 +164,12 @@
 system handler. If the program does not exit, the Go handler then
 reinstalls itself and continues execution of the program.
 
+If a SIGPIPE signal is received, the Go program will invoke the
+special handling described above if the SIGPIPE is received on a Go
+thread.  If the SIGPIPE is received on a non-Go thread the signal will
+be forwarded to the non-Go handler, if any; if there is none the
+default system handler will cause the program to terminate.
+
 # Non-Go programs that call Go code
 
 When Go code is built with options like -buildmode=c-shared, it will
diff --git a/src/os/signal/internal/pty/pty.go b/src/os/signal/internal/pty/pty.go
deleted file mode 100644
index 537febb..0000000
--- a/src/os/signal/internal/pty/pty.go
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build (aix || darwin || dragonfly || freebsd || (linux && !android) || netbsd || openbsd) && cgo
-
-// Package pty is a simple pseudo-terminal package for Unix systems,
-// implemented by calling C functions via cgo.
-// This is only used for testing the os/signal package.
-package pty
-
-/*
-#define _XOPEN_SOURCE 600
-#include <fcntl.h>
-#include <stdlib.h>
-#include <unistd.h>
-*/
-import "C"
-
-import (
-	"fmt"
-	"os"
-	"syscall"
-)
-
-type PtyError struct {
-	FuncName    string
-	ErrorString string
-	Errno       syscall.Errno
-}
-
-func ptyError(name string, err error) *PtyError {
-	return &PtyError{name, err.Error(), err.(syscall.Errno)}
-}
-
-func (e *PtyError) Error() string {
-	return fmt.Sprintf("%s: %s", e.FuncName, e.ErrorString)
-}
-
-func (e *PtyError) Unwrap() error { return e.Errno }
-
-// Open returns a control pty and the name of the linked process tty.
-func Open() (pty *os.File, processTTY string, err error) {
-	m, err := C.posix_openpt(C.O_RDWR)
-	if err != nil {
-		return nil, "", ptyError("posix_openpt", err)
-	}
-	if _, err := C.grantpt(m); err != nil {
-		C.close(m)
-		return nil, "", ptyError("grantpt", err)
-	}
-	if _, err := C.unlockpt(m); err != nil {
-		C.close(m)
-		return nil, "", ptyError("unlockpt", err)
-	}
-	processTTY = C.GoString(C.ptsname(m))
-	return os.NewFile(uintptr(m), "pty"), processTTY, nil
-}
diff --git a/src/os/signal/signal_cgo_test.go b/src/os/signal/signal_cgo_test.go
index 67bad66..ac59215 100644
--- a/src/os/signal/signal_cgo_test.go
+++ b/src/os/signal/signal_cgo_test.go
@@ -11,52 +11,72 @@
 package signal_test
 
 import (
-	"bufio"
-	"bytes"
 	"context"
+	"encoding/binary"
 	"fmt"
-	"io"
-	"io/fs"
+	"internal/testpty"
 	"os"
 	"os/exec"
-	ptypkg "os/signal/internal/pty"
+	"os/signal"
+	"runtime"
 	"strconv"
-	"strings"
-	"sync"
 	"syscall"
 	"testing"
 	"time"
+	"unsafe"
 )
 
+const (
+	ptyFD     = 3 // child end of pty.
+	controlFD = 4 // child end of control pipe.
+)
+
+// TestTerminalSignal tests that read from a pseudo-terminal does not return an
+// error if the process is SIGSTOP'd and put in the background during the read.
+//
+// This test simulates stopping a Go process running in a shell with ^Z and
+// then resuming with `fg`.
+//
+// This is a regression test for https://go.dev/issue/22838. On Darwin, PTY
+// reads return EINTR when this occurs, and Go should automatically retry.
 func TestTerminalSignal(t *testing.T) {
-	const enteringRead = "test program entering read"
-	if os.Getenv("GO_TEST_TERMINAL_SIGNALS") != "" {
-		var b [1]byte
-		fmt.Println(enteringRead)
-		n, err := os.Stdin.Read(b[:])
-		if n == 1 {
-			if b[0] == '\n' {
-				// This is what we expect
-				fmt.Println("read newline")
-			} else {
-				fmt.Printf("read 1 byte: %q\n", b)
-			}
-		} else {
-			fmt.Printf("read %d bytes\n", n)
-		}
-		if err != nil {
-			fmt.Println(err)
-			os.Exit(1)
-		}
-		os.Exit(0)
-	}
+	// This test simulates stopping a Go process running in a shell with ^Z
+	// and then resuming with `fg`. This sounds simple, but is actually
+	// quite complicated.
+	//
+	// In principle, what we are doing is:
+	// 1. Creating a new PTY parent/child FD pair.
+	// 2. Create a child that is in the foreground process group of the PTY, and read() from that process.
+	// 3. Stop the child with ^Z.
+	// 4. Take over as foreground process group of the PTY from the parent.
+	// 5. Make the child foreground process group again.
+	// 6. Continue the child.
+	//
+	// On Darwin, step 4 results in the read() returning EINTR once the
+	// process continues. internal/poll should automatically retry the
+	// read.
+	//
+	// These steps are complicated by the rules around foreground process
+	// groups. A process group cannot be foreground if it is "orphaned",
+	// unless it masks SIGTTOU.  i.e., to be foreground the process group
+	// must have a parent process group in the same session or mask SIGTTOU
+	// (which we do). An orphaned process group cannot receive
+	// terminal-generated SIGTSTP at all.
+	//
+	// Achieving this requires three processes total:
+	// - Top-level process: this is the main test process and creates the
+	// pseudo-terminal.
+	// - GO_TEST_TERMINAL_SIGNALS=1: This process creates a new process
+	// group and session. The PTY is the controlling terminal for this
+	// session. This process masks SIGTTOU, making it eligible to be a
+	// foreground process group. This process will take over as foreground
+	// from subprocess 2 (step 4 above).
+	// - GO_TEST_TERMINAL_SIGNALS=2: This process create a child process
+	// group of subprocess 1, and is the original foreground process group
+	// for the PTY. This subprocess is the one that is SIGSTOP'd.
 
-	t.Parallel()
-
-	// The test requires a shell that uses job control.
-	bash, err := exec.LookPath("bash")
-	if err != nil {
-		t.Skipf("could not find bash: %v", err)
+	if runtime.GOOS == "dragonfly" {
+		t.Skip("skipping: wait hangs on dragonfly; see https://go.dev/issue/56132")
 	}
 
 	scale := 1
@@ -66,14 +86,28 @@
 		}
 	}
 	pause := time.Duration(scale) * 10 * time.Millisecond
-	wait := time.Duration(scale) * 5 * time.Second
 
-	// The test only fails when using a "slow device," in this
-	// case a pseudo-terminal.
+	lvl := os.Getenv("GO_TEST_TERMINAL_SIGNALS")
+	switch lvl {
+	case "":
+		// Main test process, run code below.
+		break
+	case "1":
+		runSessionLeader(pause)
+		panic("unreachable")
+	case "2":
+		runStoppingChild()
+		panic("unreachable")
+	default:
+		fmt.Fprintf(os.Stderr, "unknown subprocess level %s\n", lvl)
+		os.Exit(1)
+	}
 
-	pty, procTTYName, err := ptypkg.Open()
+	t.Parallel()
+
+	pty, procTTYName, err := testpty.Open()
 	if err != nil {
-		ptyErr := err.(*ptypkg.PtyError)
+		ptyErr := err.(*testpty.PtyError)
 		if ptyErr.FuncName == "posix_openpt" && ptyErr.Errno == syscall.EACCES {
 			t.Skip("posix_openpt failed with EACCES, assuming chroot and skipping")
 		}
@@ -86,19 +120,26 @@
 	}
 	defer procTTY.Close()
 
-	// Start an interactive shell.
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+	// Control pipe. GO_TEST_TERMINAL_SIGNALS=2 send the PID of
+	// GO_TEST_TERMINAL_SIGNALS=3 here. After SIGSTOP, it also writes a
+	// byte to indicate that the foreground cycling is complete.
+	controlR, controlW, err := os.Pipe()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second)
 	defer cancel()
-	cmd := exec.CommandContext(ctx, bash, "--norc", "--noprofile", "-i")
-	// Clear HISTFILE so that we don't read or clobber the user's bash history.
-	cmd.Env = append(os.Environ(), "HISTFILE=")
-	cmd.Stdin = procTTY
-	cmd.Stdout = procTTY
-	cmd.Stderr = procTTY
+	cmd := exec.CommandContext(ctx, os.Args[0], "-test.run=TestTerminalSignal")
+	cmd.Env = append(os.Environ(), "GO_TEST_TERMINAL_SIGNALS=1")
+	cmd.Stdin = os.Stdin
+	cmd.Stdout = os.Stdout // for logging
+	cmd.Stderr = os.Stderr
+	cmd.ExtraFiles = []*os.File{procTTY, controlW}
 	cmd.SysProcAttr = &syscall.SysProcAttr{
 		Setsid:  true,
 		Setctty: true,
-		Ctty:    0,
+		Ctty:    ptyFD,
 	}
 
 	if err := cmd.Start(); err != nil {
@@ -109,78 +150,31 @@
 		t.Errorf("closing procTTY: %v", err)
 	}
 
-	progReady := make(chan bool)
-	sawPrompt := make(chan bool, 10)
-	const prompt = "prompt> "
-
-	// Read data from pty in the background.
-	var wg sync.WaitGroup
-	wg.Add(1)
-	defer wg.Wait()
-	go func() {
-		defer wg.Done()
-		input := bufio.NewReader(pty)
-		var line, handled []byte
-		for {
-			b, err := input.ReadByte()
-			if err != nil {
-				if len(line) > 0 || len(handled) > 0 {
-					t.Logf("%q", append(handled, line...))
-				}
-				if perr, ok := err.(*fs.PathError); ok {
-					err = perr.Err
-				}
-				// EOF means pty is closed.
-				// EIO means child process is done.
-				// "file already closed" means deferred close of pty has happened.
-				if err != io.EOF && err != syscall.EIO && !strings.Contains(err.Error(), "file already closed") {
-					t.Logf("error reading from pty: %v", err)
-				}
-				return
-			}
-
-			line = append(line, b)
-
-			if b == '\n' {
-				t.Logf("%q", append(handled, line...))
-				line = nil
-				handled = nil
-				continue
-			}
-
-			if bytes.Contains(line, []byte(enteringRead)) {
-				close(progReady)
-				handled = append(handled, line...)
-				line = nil
-			} else if bytes.Contains(line, []byte(prompt)) && !bytes.Contains(line, []byte("PS1=")) {
-				sawPrompt <- true
-				handled = append(handled, line...)
-				line = nil
-			}
-		}
-	}()
-
-	// Set the bash prompt so that we can see it.
-	if _, err := pty.Write([]byte("PS1='" + prompt + "'\n")); err != nil {
-		t.Fatalf("setting prompt: %v", err)
-	}
-	select {
-	case <-sawPrompt:
-	case <-time.After(wait):
-		t.Fatal("timed out waiting for shell prompt")
+	if err := controlW.Close(); err != nil {
+		t.Errorf("closing controlW: %v", err)
 	}
 
-	// Start a small program that reads from stdin
-	// (namely the code at the top of this function).
-	if _, err := pty.Write([]byte("GO_TEST_TERMINAL_SIGNALS=1 " + os.Args[0] + " -test.run=TestTerminalSignal\n")); err != nil {
-		t.Fatal(err)
+	// Wait for first child to send the second child's PID.
+	b := make([]byte, 8)
+	n, err := controlR.Read(b)
+	if err != nil {
+		t.Fatalf("error reading child pid: %v\n", err)
+	}
+	if n != 8 {
+		t.Fatalf("unexpected short read n = %d\n", n)
+	}
+	pid := binary.LittleEndian.Uint64(b[:])
+	process, err := os.FindProcess(int(pid))
+	if err != nil {
+		t.Fatalf("unable to find child process: %v", err)
 	}
 
-	// Wait for the program to print that it is starting.
-	select {
-	case <-progReady:
-	case <-time.After(wait):
-		t.Fatal("timed out waiting for program to start")
+	// Wait for the third child to write a byte indicating that it is
+	// entering the read.
+	b = make([]byte, 1)
+	_, err = pty.Read(b)
+	if err != nil {
+		t.Fatalf("error reading from child: %v", err)
 	}
 
 	// Give the program time to enter the read call.
@@ -189,51 +183,168 @@
 	// will pass.
 	time.Sleep(pause)
 
+	t.Logf("Sending ^Z...")
+
 	// Send a ^Z to stop the program.
 	if _, err := pty.Write([]byte{26}); err != nil {
 		t.Fatalf("writing ^Z to pty: %v", err)
 	}
 
-	// Wait for the program to stop and return to the shell.
-	select {
-	case <-sawPrompt:
-	case <-time.After(wait):
-		t.Fatal("timed out waiting for shell prompt")
+	// Wait for subprocess 1 to cycle the foreground process group.
+	if _, err := controlR.Read(b); err != nil {
+		t.Fatalf("error reading readiness: %v", err)
 	}
 
+	t.Logf("Sending SIGCONT...")
+
 	// Restart the stopped program.
-	if _, err := pty.Write([]byte("fg\n")); err != nil {
-		t.Fatalf("writing %q to pty: %v", "fg", err)
+	if err := process.Signal(syscall.SIGCONT); err != nil {
+		t.Fatalf("Signal(SIGCONT) got err %v want nil", err)
 	}
 
-	// Give the process time to restart.
-	// This is potentially racy: if the process does not restart
-	// quickly enough then the byte we send will go to bash rather
-	// than the program. Unfortunately there isn't anything we can
-	// look for to know that the program is running again.
-	// bash will print the program name, but that happens before it
-	// restarts the program.
-	time.Sleep(10 * pause)
-
-	// Write some data for the program to read,
-	// which should cause it to exit.
+	// Write some data for the program to read, which should cause it to
+	// exit.
 	if _, err := pty.Write([]byte{'\n'}); err != nil {
 		t.Fatalf("writing %q to pty: %v", "\n", err)
 	}
 
-	// Wait for the program to exit.
-	select {
-	case <-sawPrompt:
-	case <-time.After(wait):
-		t.Fatal("timed out waiting for shell prompt")
-	}
-
-	// Exit the shell with the program's exit status.
-	if _, err := pty.Write([]byte("exit $?\n")); err != nil {
-		t.Fatalf("writing %q to pty: %v", "exit", err)
-	}
+	t.Logf("Waiting for exit...")
 
 	if err = cmd.Wait(); err != nil {
 		t.Errorf("subprogram failed: %v", err)
 	}
 }
+
+// GO_TEST_TERMINAL_SIGNALS=1 subprocess above.
+func runSessionLeader(pause time.Duration) {
+	// "Attempts to use tcsetpgrp() from a process which is a
+	// member of a background process group on a fildes associated
+	// with its controlling terminal shall cause the process group
+	// to be sent a SIGTTOU signal. If the calling thread is
+	// blocking SIGTTOU signals or the process is ignoring SIGTTOU
+	// signals, the process shall be allowed to perform the
+	// operation, and no signal is sent."
+	//  -https://pubs.opengroup.org/onlinepubs/9699919799/functions/tcsetpgrp.html
+	//
+	// We are changing the terminal to put us in the foreground, so
+	// we must ignore SIGTTOU. We are also an orphaned process
+	// group (see above), so we must mask SIGTTOU to be eligible to
+	// become foreground at all.
+	signal.Ignore(syscall.SIGTTOU)
+
+	pty := os.NewFile(ptyFD, "pty")
+	controlW := os.NewFile(controlFD, "control-pipe")
+
+	// Slightly shorter timeout than in the parent.
+	ctx, cancel := context.WithTimeout(context.Background(), 90*time.Second)
+	defer cancel()
+	cmd := exec.CommandContext(ctx, os.Args[0], "-test.run=TestTerminalSignal")
+	cmd.Env = append(os.Environ(), "GO_TEST_TERMINAL_SIGNALS=2")
+	cmd.Stdin = os.Stdin
+	cmd.Stdout = os.Stdout
+	cmd.Stderr = os.Stderr
+	cmd.ExtraFiles = []*os.File{pty}
+	cmd.SysProcAttr = &syscall.SysProcAttr{
+		Foreground: true,
+		Ctty:       ptyFD,
+	}
+	if err := cmd.Start(); err != nil {
+		fmt.Fprintf(os.Stderr, "error starting second subprocess: %v\n", err)
+		os.Exit(1)
+	}
+
+	fn := func() error {
+		var b [8]byte
+		binary.LittleEndian.PutUint64(b[:], uint64(cmd.Process.Pid))
+		_, err := controlW.Write(b[:])
+		if err != nil {
+			return fmt.Errorf("error writing child pid: %w", err)
+		}
+
+		// Wait for stop.
+		var status syscall.WaitStatus
+		var errno syscall.Errno
+		for {
+			_, _, errno = syscall.Syscall6(syscall.SYS_WAIT4, uintptr(cmd.Process.Pid), uintptr(unsafe.Pointer(&status)), syscall.WUNTRACED, 0, 0, 0)
+			if errno != syscall.EINTR {
+				break
+			}
+		}
+		if errno != 0 {
+			return fmt.Errorf("error waiting for stop: %w", errno)
+		}
+
+		if !status.Stopped() {
+			return fmt.Errorf("unexpected wait status: %v", status)
+		}
+
+		// Take TTY.
+		pgrp := int32(syscall.Getpgrp()) // assume that pid_t is int32
+		_, _, errno = syscall.Syscall(syscall.SYS_IOCTL, ptyFD, syscall.TIOCSPGRP, uintptr(unsafe.Pointer(&pgrp)))
+		if errno != 0 {
+			return fmt.Errorf("error setting tty process group: %w", errno)
+		}
+
+		// Give the kernel time to potentially wake readers and have
+		// them return EINTR (darwin does this).
+		time.Sleep(pause)
+
+		// Give TTY back.
+		pid := int32(cmd.Process.Pid) // assume that pid_t is int32
+		_, _, errno = syscall.Syscall(syscall.SYS_IOCTL, ptyFD, syscall.TIOCSPGRP, uintptr(unsafe.Pointer(&pid)))
+		if errno != 0 {
+			return fmt.Errorf("error setting tty process group back: %w", errno)
+		}
+
+		// Report that we are done and SIGCONT can be sent. Note that
+		// the actual byte we send doesn't matter.
+		if _, err := controlW.Write(b[:1]); err != nil {
+			return fmt.Errorf("error writing readiness: %w", err)
+		}
+
+		return nil
+	}
+
+	err := fn()
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "session leader error: %v\n", err)
+		cmd.Process.Kill()
+		// Wait for exit below.
+	}
+
+	werr := cmd.Wait()
+	if werr != nil {
+		fmt.Fprintf(os.Stderr, "error running second subprocess: %v\n", err)
+	}
+
+	if err != nil || werr != nil {
+		os.Exit(1)
+	}
+
+	os.Exit(0)
+}
+
+// GO_TEST_TERMINAL_SIGNALS=2 subprocess above.
+func runStoppingChild() {
+	pty := os.NewFile(ptyFD, "pty")
+
+	var b [1]byte
+	if _, err := pty.Write(b[:]); err != nil {
+		fmt.Fprintf(os.Stderr, "error writing byte to PTY: %v\n", err)
+		os.Exit(1)
+	}
+
+	_, err := pty.Read(b[:])
+	if err != nil {
+		fmt.Fprintln(os.Stderr, err)
+		os.Exit(1)
+	}
+	if b[0] == '\n' {
+		// This is what we expect
+		fmt.Println("read newline")
+	} else {
+		fmt.Fprintf(os.Stderr, "read 1 unexpected byte: %q\n", b)
+		os.Exit(1)
+	}
+	os.Exit(0)
+}
diff --git a/src/os/signal/signal_windows_test.go b/src/os/signal/signal_windows_test.go
index 9b14551..02803e5 100644
--- a/src/os/signal/signal_windows_test.go
+++ b/src/os/signal/signal_windows_test.go
@@ -5,11 +5,11 @@
 package signal
 
 import (
-	"bytes"
 	"internal/testenv"
 	"os"
 	"os/exec"
 	"path/filepath"
+	"strings"
 	"syscall"
 	"testing"
 	"time"
@@ -78,9 +78,9 @@
 
 	// run it
 	cmd := exec.Command(exe)
-	var b bytes.Buffer
-	cmd.Stdout = &b
-	cmd.Stderr = &b
+	var buf strings.Builder
+	cmd.Stdout = &buf
+	cmd.Stderr = &buf
 	cmd.SysProcAttr = &syscall.SysProcAttr{
 		CreationFlags: syscall.CREATE_NEW_PROCESS_GROUP,
 	}
@@ -94,6 +94,6 @@
 	}()
 	err = cmd.Wait()
 	if err != nil {
-		t.Fatalf("Program exited with error: %v\n%v", err, string(b.Bytes()))
+		t.Fatalf("Program exited with error: %v\n%v", err, buf.String())
 	}
 }
diff --git a/src/os/stat_plan9.go b/src/os/stat_plan9.go
index e20accf..a5e9901 100644
--- a/src/os/stat_plan9.go
+++ b/src/os/stat_plan9.go
@@ -56,7 +56,11 @@
 		switch a := arg.(type) {
 		case *File:
 			name = a.name
+			if err := a.incref("fstat"); err != nil {
+				return nil, err
+			}
 			n, err = syscall.Fstat(a.fd, buf)
+			a.decref()
 		case string:
 			name = a
 			n, err = syscall.Stat(a, buf)
diff --git a/src/os/stat_windows.go b/src/os/stat_windows.go
index da4c490..8747c19 100644
--- a/src/os/stat_windows.go
+++ b/src/os/stat_windows.go
@@ -16,30 +16,7 @@
 	if file == nil {
 		return nil, ErrInvalid
 	}
-
-	if file.isdir() {
-		// I don't know any better way to do that for directory
-		return Stat(file.dirinfo.path)
-	}
-	if isWindowsNulName(file.name) {
-		return &devNullStat, nil
-	}
-
-	ft, err := file.pfd.GetFileType()
-	if err != nil {
-		return nil, &PathError{Op: "GetFileType", Path: file.name, Err: err}
-	}
-	switch ft {
-	case syscall.FILE_TYPE_PIPE, syscall.FILE_TYPE_CHAR:
-		return &fileStat{name: basename(file.name), filetype: ft}, nil
-	}
-
-	fs, err := newFileStatFromGetFileInformationByHandle(file.name, file.pfd.Sysfd)
-	if err != nil {
-		return nil, err
-	}
-	fs.filetype = ft
-	return fs, err
+	return statHandle(file.name, file.pfd.Sysfd)
 }
 
 // stat implements both Stat and Lstat of a file.
@@ -47,9 +24,6 @@
 	if len(name) == 0 {
 		return nil, &PathError{Op: funcname, Path: name, Err: syscall.Errno(syscall.ERROR_PATH_NOT_FOUND)}
 	}
-	if isWindowsNulName(name) {
-		return &devNullStat, nil
-	}
 	namep, err := syscall.UTF16PtrFromString(fixLongPath(name))
 	if err != nil {
 		return nil, &PathError{Op: funcname, Path: name, Err: err}
@@ -97,8 +71,24 @@
 		return nil, &PathError{Op: "CreateFile", Path: name, Err: err}
 	}
 	defer syscall.CloseHandle(h)
+	return statHandle(name, h)
+}
 
-	return newFileStatFromGetFileInformationByHandle(name, h)
+func statHandle(name string, h syscall.Handle) (FileInfo, error) {
+	ft, err := syscall.GetFileType(h)
+	if err != nil {
+		return nil, &PathError{Op: "GetFileType", Path: name, Err: err}
+	}
+	switch ft {
+	case syscall.FILE_TYPE_PIPE, syscall.FILE_TYPE_CHAR:
+		return &fileStat{name: basename(name), filetype: ft}, nil
+	}
+	fs, err := newFileStatFromGetFileInformationByHandle(name, h)
+	if err != nil {
+		return nil, err
+	}
+	fs.filetype = ft
+	return fs, err
 }
 
 // statNolog implements Stat for Windows.
diff --git a/src/os/str.go b/src/os/str.go
index 35643e0..242c945 100644
--- a/src/os/str.go
+++ b/src/os/str.go
@@ -6,7 +6,7 @@
 
 package os
 
-// itox converts val (an int) to a hexdecimal string.
+// itox converts val (an int) to a hexadecimal string.
 func itox(val int) string {
 	if val < 0 {
 		return "-" + uitox(uint(-val))
@@ -16,7 +16,7 @@
 
 const hex = "0123456789abcdef"
 
-// uitox converts val (a uint) to a hexdecimal string.
+// uitox converts val (a uint) to a hexadecimal string.
 func uitox(val uint) string {
 	if val == 0 { // avoid string allocation
 		return "0x0"
diff --git a/src/os/types_plan9.go b/src/os/types_plan9.go
index ccf4fd9..adb4013 100644
--- a/src/os/types_plan9.go
+++ b/src/os/types_plan9.go
@@ -28,5 +28,3 @@
 	b := fs2.sys.(*syscall.Dir)
 	return a.Qid.Path == b.Qid.Path && a.Type == b.Type && a.Dev == b.Dev
 }
-
-const badFd = -1
diff --git a/src/os/types_windows.go b/src/os/types_windows.go
index 5443dfe..d444e8b 100644
--- a/src/os/types_windows.go
+++ b/src/os/types_windows.go
@@ -110,9 +110,6 @@
 }
 
 func (fs *fileStat) Mode() (m FileMode) {
-	if fs == &devNullStat {
-		return ModeDevice | ModeCharDevice | 0666
-	}
 	if fs.FileAttributes&syscall.FILE_ATTRIBUTE_READONLY != 0 {
 		m |= 0444
 	} else {
@@ -204,15 +201,6 @@
 	return nil
 }
 
-// devNullStat is fileStat structure describing DevNull file ("NUL").
-var devNullStat = fileStat{
-	name: DevNull,
-	// hopefully this will work for SameFile
-	vol:   0,
-	idxhi: 0,
-	idxlo: 0,
-}
-
 func sameFile(fs1, fs2 *fileStat) bool {
 	e := fs1.loadFileId()
 	if e != nil {
diff --git a/src/os/user/cgo_listgroups_unix.go b/src/os/user/cgo_listgroups_unix.go
index 0d937da..5963695 100644
--- a/src/os/user/cgo_listgroups_unix.go
+++ b/src/os/user/cgo_listgroups_unix.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build (dragonfly || darwin || freebsd || (!android && linux) || netbsd || openbsd || (solaris && !illumos)) && cgo && !osusergo
+//go:build (cgo || darwin) && !osusergo && (darwin || dragonfly || freebsd || (linux && !android) || netbsd || openbsd || (solaris && !illumos))
 
 package user
 
@@ -12,12 +12,6 @@
 	"unsafe"
 )
 
-/*
-#include <unistd.h>
-#include <sys/types.h>
-*/
-import "C"
-
 const maxGroups = 2048
 
 func listGroups(u *User) ([]string, error) {
@@ -25,13 +19,13 @@
 	if err != nil {
 		return nil, fmt.Errorf("user: list groups for %s: invalid gid %q", u.Username, u.Gid)
 	}
-	userGID := C.gid_t(ug)
+	userGID := _C_gid_t(ug)
 	nameC := make([]byte, len(u.Username)+1)
 	copy(nameC, u.Username)
 
-	n := C.int(256)
-	gidsC := make([]C.gid_t, n)
-	rv := getGroupList((*C.char)(unsafe.Pointer(&nameC[0])), userGID, &gidsC[0], &n)
+	n := _C_int(256)
+	gidsC := make([]_C_gid_t, n)
+	rv := getGroupList((*_C_char)(unsafe.Pointer(&nameC[0])), userGID, &gidsC[0], &n)
 	if rv == -1 {
 		// Mac is the only Unix that does not set n properly when rv == -1, so
 		// we need to use different logic for Mac vs. the other OS's.
@@ -46,3 +40,18 @@
 	}
 	return gids, nil
 }
+
+// groupRetry retries getGroupList with much larger size for n. The result is
+// stored in gids.
+func groupRetry(username string, name []byte, userGID _C_gid_t, gids *[]_C_gid_t, n *_C_int) error {
+	// More than initial buffer, but now n contains the correct size.
+	if *n > maxGroups {
+		return fmt.Errorf("user: %q is a member of more than %d groups", username, maxGroups)
+	}
+	*gids = make([]_C_gid_t, *n)
+	rv := getGroupList((*_C_char)(unsafe.Pointer(&name[0])), userGID, &(*gids)[0], n)
+	if rv == -1 {
+		return fmt.Errorf("user: list groups for %s failed", username)
+	}
+	return nil
+}
diff --git a/src/os/user/cgo_lookup_cgo.go b/src/os/user/cgo_lookup_cgo.go
new file mode 100644
index 0000000..4f78dca
--- /dev/null
+++ b/src/os/user/cgo_lookup_cgo.go
@@ -0,0 +1,112 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build cgo && !osusergo && unix && !android && !darwin
+
+package user
+
+import (
+	"syscall"
+)
+
+/*
+#cgo solaris CFLAGS: -D_POSIX_PTHREAD_SEMANTICS
+#cgo CFLAGS: -fno-stack-protector
+#include <unistd.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <grp.h>
+#include <stdlib.h>
+#include <string.h>
+
+static struct passwd mygetpwuid_r(int uid, char *buf, size_t buflen, int *found, int *perr) {
+	struct passwd pwd;
+	struct passwd *result;
+	memset (&pwd, 0, sizeof(pwd));
+	*perr = getpwuid_r(uid, &pwd, buf, buflen, &result);
+	*found = result != NULL;
+	return pwd;
+}
+
+static struct passwd mygetpwnam_r(const char *name, char *buf, size_t buflen, int *found, int *perr) {
+	struct passwd pwd;
+	struct passwd *result;
+	memset(&pwd, 0, sizeof(pwd));
+	*perr = getpwnam_r(name, &pwd, buf, buflen, &result);
+	*found = result != NULL;
+	return pwd;
+}
+
+static struct group mygetgrgid_r(int gid, char *buf, size_t buflen, int *found, int *perr) {
+	struct group grp;
+	struct group *result;
+	memset(&grp, 0, sizeof(grp));
+	*perr = getgrgid_r(gid, &grp, buf, buflen, &result);
+	*found = result != NULL;
+	return grp;
+}
+
+static struct group mygetgrnam_r(const char *name, char *buf, size_t buflen, int *found, int *perr) {
+	struct group grp;
+	struct group *result;
+	memset(&grp, 0, sizeof(grp));
+	*perr = getgrnam_r(name, &grp, buf, buflen, &result);
+	*found = result != NULL;
+	return grp;
+}
+*/
+import "C"
+
+type _C_char = C.char
+type _C_int = C.int
+type _C_gid_t = C.gid_t
+type _C_uid_t = C.uid_t
+type _C_size_t = C.size_t
+type _C_struct_group = C.struct_group
+type _C_struct_passwd = C.struct_passwd
+type _C_long = C.long
+
+func _C_pw_uid(p *_C_struct_passwd) _C_uid_t   { return p.pw_uid }
+func _C_pw_uidp(p *_C_struct_passwd) *_C_uid_t { return &p.pw_uid }
+func _C_pw_gid(p *_C_struct_passwd) _C_gid_t   { return p.pw_gid }
+func _C_pw_gidp(p *_C_struct_passwd) *_C_gid_t { return &p.pw_gid }
+func _C_pw_name(p *_C_struct_passwd) *_C_char  { return p.pw_name }
+func _C_pw_gecos(p *_C_struct_passwd) *_C_char { return p.pw_gecos }
+func _C_pw_dir(p *_C_struct_passwd) *_C_char   { return p.pw_dir }
+
+func _C_gr_gid(g *_C_struct_group) _C_gid_t  { return g.gr_gid }
+func _C_gr_name(g *_C_struct_group) *_C_char { return g.gr_name }
+
+func _C_GoString(p *_C_char) string { return C.GoString(p) }
+
+func _C_getpwnam_r(name *_C_char, buf *_C_char, size _C_size_t) (pwd _C_struct_passwd, found bool, errno syscall.Errno) {
+	var f, e _C_int
+	pwd = C.mygetpwnam_r(name, buf, size, &f, &e)
+	return pwd, f != 0, syscall.Errno(e)
+}
+
+func _C_getpwuid_r(uid _C_uid_t, buf *_C_char, size _C_size_t) (pwd _C_struct_passwd, found bool, errno syscall.Errno) {
+	var f, e _C_int
+	pwd = C.mygetpwuid_r(_C_int(uid), buf, size, &f, &e)
+	return pwd, f != 0, syscall.Errno(e)
+}
+
+func _C_getgrnam_r(name *_C_char, buf *_C_char, size _C_size_t) (grp _C_struct_group, found bool, errno syscall.Errno) {
+	var f, e _C_int
+	grp = C.mygetgrnam_r(name, buf, size, &f, &e)
+	return grp, f != 0, syscall.Errno(e)
+}
+
+func _C_getgrgid_r(gid _C_gid_t, buf *_C_char, size _C_size_t) (grp _C_struct_group, found bool, errno syscall.Errno) {
+	var f, e _C_int
+	grp = C.mygetgrgid_r(_C_int(gid), buf, size, &f, &e)
+	return grp, f != 0, syscall.Errno(e)
+}
+
+const (
+	_C__SC_GETPW_R_SIZE_MAX = C._SC_GETPW_R_SIZE_MAX
+	_C__SC_GETGR_R_SIZE_MAX = C._SC_GETGR_R_SIZE_MAX
+)
+
+func _C_sysconf(key _C_int) _C_long { return C.sysconf(key) }
diff --git a/src/os/user/cgo_lookup_syscall.go b/src/os/user/cgo_lookup_syscall.go
new file mode 100644
index 0000000..321df65
--- /dev/null
+++ b/src/os/user/cgo_lookup_syscall.go
@@ -0,0 +1,65 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !osusergo && darwin
+
+package user
+
+import (
+	"internal/syscall/unix"
+	"syscall"
+)
+
+type _C_char = byte
+type _C_int = int32
+type _C_gid_t = uint32
+type _C_uid_t = uint32
+type _C_size_t = uintptr
+type _C_struct_group = unix.Group
+type _C_struct_passwd = unix.Passwd
+type _C_long = int64
+
+func _C_pw_uid(p *_C_struct_passwd) _C_uid_t   { return p.Uid }
+func _C_pw_uidp(p *_C_struct_passwd) *_C_uid_t { return &p.Uid }
+func _C_pw_gid(p *_C_struct_passwd) _C_gid_t   { return p.Gid }
+func _C_pw_gidp(p *_C_struct_passwd) *_C_gid_t { return &p.Gid }
+func _C_pw_name(p *_C_struct_passwd) *_C_char  { return p.Name }
+func _C_pw_gecos(p *_C_struct_passwd) *_C_char { return p.Gecos }
+func _C_pw_dir(p *_C_struct_passwd) *_C_char   { return p.Dir }
+
+func _C_gr_gid(g *_C_struct_group) _C_gid_t  { return g.Gid }
+func _C_gr_name(g *_C_struct_group) *_C_char { return g.Name }
+
+func _C_GoString(p *_C_char) string { return unix.GoString(p) }
+
+func _C_getpwnam_r(name *_C_char, buf *_C_char, size _C_size_t) (pwd _C_struct_passwd, found bool, errno syscall.Errno) {
+	var result *_C_struct_passwd
+	errno = unix.Getpwnam(name, &pwd, buf, size, &result)
+	return pwd, result != nil, errno
+}
+
+func _C_getpwuid_r(uid _C_uid_t, buf *_C_char, size _C_size_t) (pwd _C_struct_passwd, found bool, errno syscall.Errno) {
+	var result *_C_struct_passwd
+	errno = unix.Getpwuid(uid, &pwd, buf, size, &result)
+	return pwd, result != nil, errno
+}
+
+func _C_getgrnam_r(name *_C_char, buf *_C_char, size _C_size_t) (grp _C_struct_group, found bool, errno syscall.Errno) {
+	var result *_C_struct_group
+	errno = unix.Getgrnam(name, &grp, buf, size, &result)
+	return grp, result != nil, errno
+}
+
+func _C_getgrgid_r(gid _C_gid_t, buf *_C_char, size _C_size_t) (grp _C_struct_group, found bool, errno syscall.Errno) {
+	var result *_C_struct_group
+	errno = unix.Getgrgid(gid, &grp, buf, size, &result)
+	return grp, result != nil, errno
+}
+
+const (
+	_C__SC_GETPW_R_SIZE_MAX = unix.SC_GETPW_R_SIZE_MAX
+	_C__SC_GETGR_R_SIZE_MAX = unix.SC_GETGR_R_SIZE_MAX
+)
+
+func _C_sysconf(key _C_int) _C_long { return unix.Sysconf(key) }
diff --git a/src/os/user/cgo_lookup_unix.go b/src/os/user/cgo_lookup_unix.go
index 4f8577b..3735971 100644
--- a/src/os/user/cgo_lookup_unix.go
+++ b/src/os/user/cgo_lookup_unix.go
@@ -2,76 +2,39 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build unix && !android && cgo && !osusergo
+//go:build (cgo || darwin) && !osusergo && unix && !android
 
 package user
 
 import (
 	"fmt"
+	"runtime"
 	"strconv"
 	"strings"
 	"syscall"
 	"unsafe"
 )
 
-/*
-#cgo solaris CFLAGS: -D_POSIX_PTHREAD_SEMANTICS
-#include <unistd.h>
-#include <sys/types.h>
-#include <pwd.h>
-#include <grp.h>
-#include <stdlib.h>
-
-static int mygetpwuid_r(int uid, struct passwd *pwd,
-	char *buf, size_t buflen, struct passwd **result) {
-	return getpwuid_r(uid, pwd, buf, buflen, result);
-}
-
-static int mygetpwnam_r(const char *name, struct passwd *pwd,
-	char *buf, size_t buflen, struct passwd **result) {
-	return getpwnam_r(name, pwd, buf, buflen, result);
-}
-
-static int mygetgrgid_r(int gid, struct group *grp,
-	char *buf, size_t buflen, struct group **result) {
- return getgrgid_r(gid, grp, buf, buflen, result);
-}
-
-static int mygetgrnam_r(const char *name, struct group *grp,
-	char *buf, size_t buflen, struct group **result) {
- return getgrnam_r(name, grp, buf, buflen, result);
-}
-*/
-import "C"
-
 func current() (*User, error) {
 	return lookupUnixUid(syscall.Getuid())
 }
 
 func lookupUser(username string) (*User, error) {
-	var pwd C.struct_passwd
-	var result *C.struct_passwd
+	var pwd _C_struct_passwd
+	var found bool
 	nameC := make([]byte, len(username)+1)
 	copy(nameC, username)
 
-	buf := alloc(userBuffer)
-	defer buf.free()
-
-	err := retryWithBuffer(buf, func() syscall.Errno {
-		// mygetpwnam_r is a wrapper around getpwnam_r to avoid
-		// passing a size_t to getpwnam_r, because for unknown
-		// reasons passing a size_t to getpwnam_r doesn't work on
-		// Solaris.
-		return syscall.Errno(C.mygetpwnam_r((*C.char)(unsafe.Pointer(&nameC[0])),
-			&pwd,
-			(*C.char)(buf.ptr),
-			C.size_t(buf.size),
-			&result))
+	err := retryWithBuffer(userBuffer, func(buf []byte) syscall.Errno {
+		var errno syscall.Errno
+		pwd, found, errno = _C_getpwnam_r((*_C_char)(unsafe.Pointer(&nameC[0])),
+			(*_C_char)(unsafe.Pointer(&buf[0])), _C_size_t(len(buf)))
+		return errno
 	})
 	if err != nil {
 		return nil, fmt.Errorf("user: lookup username %s: %v", username, err)
 	}
-	if result == nil {
+	if !found {
 		return nil, UnknownUserError(username)
 	}
 	return buildUser(&pwd), err
@@ -86,37 +49,31 @@
 }
 
 func lookupUnixUid(uid int) (*User, error) {
-	var pwd C.struct_passwd
-	var result *C.struct_passwd
+	var pwd _C_struct_passwd
+	var found bool
 
-	buf := alloc(userBuffer)
-	defer buf.free()
-
-	err := retryWithBuffer(buf, func() syscall.Errno {
-		// mygetpwuid_r is a wrapper around getpwuid_r to avoid using uid_t
-		// because C.uid_t(uid) for unknown reasons doesn't work on linux.
-		return syscall.Errno(C.mygetpwuid_r(C.int(uid),
-			&pwd,
-			(*C.char)(buf.ptr),
-			C.size_t(buf.size),
-			&result))
+	err := retryWithBuffer(userBuffer, func(buf []byte) syscall.Errno {
+		var errno syscall.Errno
+		pwd, found, errno = _C_getpwuid_r(_C_uid_t(uid),
+			(*_C_char)(unsafe.Pointer(&buf[0])), _C_size_t(len(buf)))
+		return errno
 	})
 	if err != nil {
 		return nil, fmt.Errorf("user: lookup userid %d: %v", uid, err)
 	}
-	if result == nil {
+	if !found {
 		return nil, UnknownUserIdError(uid)
 	}
 	return buildUser(&pwd), nil
 }
 
-func buildUser(pwd *C.struct_passwd) *User {
+func buildUser(pwd *_C_struct_passwd) *User {
 	u := &User{
-		Uid:      strconv.FormatUint(uint64(pwd.pw_uid), 10),
-		Gid:      strconv.FormatUint(uint64(pwd.pw_gid), 10),
-		Username: C.GoString(pwd.pw_name),
-		Name:     C.GoString(pwd.pw_gecos),
-		HomeDir:  C.GoString(pwd.pw_dir),
+		Uid:      strconv.FormatUint(uint64(_C_pw_uid(pwd)), 10),
+		Gid:      strconv.FormatUint(uint64(_C_pw_gid(pwd)), 10),
+		Username: _C_GoString(_C_pw_name(pwd)),
+		Name:     _C_GoString(_C_pw_gecos(pwd)),
+		HomeDir:  _C_GoString(_C_pw_dir(pwd)),
 	}
 	// The pw_gecos field isn't quite standardized. Some docs
 	// say: "It is expected to be a comma separated list of
@@ -127,25 +84,22 @@
 }
 
 func lookupGroup(groupname string) (*Group, error) {
-	var grp C.struct_group
-	var result *C.struct_group
+	var grp _C_struct_group
+	var found bool
 
-	buf := alloc(groupBuffer)
-	defer buf.free()
 	cname := make([]byte, len(groupname)+1)
 	copy(cname, groupname)
 
-	err := retryWithBuffer(buf, func() syscall.Errno {
-		return syscall.Errno(C.mygetgrnam_r((*C.char)(unsafe.Pointer(&cname[0])),
-			&grp,
-			(*C.char)(buf.ptr),
-			C.size_t(buf.size),
-			&result))
+	err := retryWithBuffer(groupBuffer, func(buf []byte) syscall.Errno {
+		var errno syscall.Errno
+		grp, found, errno = _C_getgrnam_r((*_C_char)(unsafe.Pointer(&cname[0])),
+			(*_C_char)(unsafe.Pointer(&buf[0])), _C_size_t(len(buf)))
+		return errno
 	})
 	if err != nil {
 		return nil, fmt.Errorf("user: lookup groupname %s: %v", groupname, err)
 	}
-	if result == nil {
+	if !found {
 		return nil, UnknownGroupError(groupname)
 	}
 	return buildGroup(&grp), nil
@@ -160,47 +114,41 @@
 }
 
 func lookupUnixGid(gid int) (*Group, error) {
-	var grp C.struct_group
-	var result *C.struct_group
+	var grp _C_struct_group
+	var found bool
 
-	buf := alloc(groupBuffer)
-	defer buf.free()
-
-	err := retryWithBuffer(buf, func() syscall.Errno {
-		// mygetgrgid_r is a wrapper around getgrgid_r to avoid using gid_t
-		// because C.gid_t(gid) for unknown reasons doesn't work on linux.
-		return syscall.Errno(C.mygetgrgid_r(C.int(gid),
-			&grp,
-			(*C.char)(buf.ptr),
-			C.size_t(buf.size),
-			&result))
+	err := retryWithBuffer(groupBuffer, func(buf []byte) syscall.Errno {
+		var errno syscall.Errno
+		grp, found, errno = _C_getgrgid_r(_C_gid_t(gid),
+			(*_C_char)(unsafe.Pointer(&buf[0])), _C_size_t(len(buf)))
+		return syscall.Errno(errno)
 	})
 	if err != nil {
 		return nil, fmt.Errorf("user: lookup groupid %d: %v", gid, err)
 	}
-	if result == nil {
+	if !found {
 		return nil, UnknownGroupIdError(strconv.Itoa(gid))
 	}
 	return buildGroup(&grp), nil
 }
 
-func buildGroup(grp *C.struct_group) *Group {
+func buildGroup(grp *_C_struct_group) *Group {
 	g := &Group{
-		Gid:  strconv.Itoa(int(grp.gr_gid)),
-		Name: C.GoString(grp.gr_name),
+		Gid:  strconv.Itoa(int(_C_gr_gid(grp))),
+		Name: _C_GoString(_C_gr_name(grp)),
 	}
 	return g
 }
 
-type bufferKind C.int
+type bufferKind _C_int
 
-const (
-	userBuffer  = bufferKind(C._SC_GETPW_R_SIZE_MAX)
-	groupBuffer = bufferKind(C._SC_GETGR_R_SIZE_MAX)
+var (
+	userBuffer  = bufferKind(_C__SC_GETPW_R_SIZE_MAX)
+	groupBuffer = bufferKind(_C__SC_GETGR_R_SIZE_MAX)
 )
 
-func (k bufferKind) initialSize() C.size_t {
-	sz := C.sysconf(C.int(k))
+func (k bufferKind) initialSize() _C_size_t {
+	sz := _C_sysconf(_C_int(k))
 	if sz == -1 {
 		// DragonFly and FreeBSD do not have _SC_GETPW_R_SIZE_MAX.
 		// Additionally, not all Linux systems have it, either. For
@@ -211,47 +159,29 @@
 		// Truncate.  If this truly isn't enough, retryWithBuffer will error on the first run.
 		return maxBufferSize
 	}
-	return C.size_t(sz)
-}
-
-type memBuffer struct {
-	ptr  unsafe.Pointer
-	size C.size_t
-}
-
-func alloc(kind bufferKind) *memBuffer {
-	sz := kind.initialSize()
-	return &memBuffer{
-		ptr:  C.malloc(sz),
-		size: sz,
-	}
-}
-
-func (mb *memBuffer) resize(newSize C.size_t) {
-	mb.ptr = C.realloc(mb.ptr, newSize)
-	mb.size = newSize
-}
-
-func (mb *memBuffer) free() {
-	C.free(mb.ptr)
+	return _C_size_t(sz)
 }
 
 // retryWithBuffer repeatedly calls f(), increasing the size of the
 // buffer each time, until f succeeds, fails with a non-ERANGE error,
 // or the buffer exceeds a reasonable limit.
-func retryWithBuffer(buf *memBuffer, f func() syscall.Errno) error {
+func retryWithBuffer(startSize bufferKind, f func([]byte) syscall.Errno) error {
+	buf := make([]byte, startSize)
 	for {
-		errno := f()
+		errno := f(buf)
 		if errno == 0 {
 			return nil
+		} else if runtime.GOOS == "aix" && errno+1 == 0 {
+			// On AIX getpwuid_r appears to return -1,
+			// not ERANGE, on buffer overflow.
 		} else if errno != syscall.ERANGE {
 			return errno
 		}
-		newSize := buf.size * 2
+		newSize := len(buf) * 2
 		if !isSizeReasonable(int64(newSize)) {
 			return fmt.Errorf("internal buffer exceeds %d bytes", maxBufferSize)
 		}
-		buf.resize(newSize)
+		buf = make([]byte, newSize)
 	}
 }
 
@@ -262,9 +192,9 @@
 }
 
 // Because we can't use cgo in tests:
-func structPasswdForNegativeTest() C.struct_passwd {
-	sp := C.struct_passwd{}
-	sp.pw_uid = 1<<32 - 2
-	sp.pw_gid = 1<<32 - 3
+func structPasswdForNegativeTest() _C_struct_passwd {
+	sp := _C_struct_passwd{}
+	*_C_pw_uidp(&sp) = 1<<32 - 2
+	*_C_pw_gidp(&sp) = 1<<32 - 3
 	return sp
 }
diff --git a/src/os/user/getgrouplist_darwin.go b/src/os/user/getgrouplist_darwin.go
deleted file mode 100644
index db6fb87..0000000
--- a/src/os/user/getgrouplist_darwin.go
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2016 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build cgo && !osusergo
-
-package user
-
-/*
-#include <unistd.h>
-#include <sys/types.h>
-#include <stdlib.h>
-
-static int mygetgrouplist(const char* user, gid_t group, gid_t* groups, int* ngroups) {
-	int* buf = malloc(*ngroups * sizeof(int));
-	int rv = getgrouplist(user, (int) group, buf, ngroups);
-	int i;
-	if (rv == 0) {
-		for (i = 0; i < *ngroups; i++) {
-			groups[i] = (gid_t) buf[i];
-		}
-	}
-	free(buf);
-	return rv;
-}
-*/
-import "C"
-import (
-	"fmt"
-	"unsafe"
-)
-
-func getGroupList(name *C.char, userGID C.gid_t, gids *C.gid_t, n *C.int) C.int {
-	return C.mygetgrouplist(name, userGID, gids, n)
-}
-
-// groupRetry retries getGroupList with an increasingly large size for n. The
-// result is stored in gids.
-func groupRetry(username string, name []byte, userGID C.gid_t, gids *[]C.gid_t, n *C.int) error {
-	*n = C.int(256 * 2)
-	for {
-		*gids = make([]C.gid_t, *n)
-		rv := getGroupList((*C.char)(unsafe.Pointer(&name[0])), userGID, &(*gids)[0], n)
-		if rv >= 0 {
-			// n is set correctly
-			break
-		}
-		if *n > maxGroups {
-			return fmt.Errorf("user: %q is a member of more than %d groups", username, maxGroups)
-		}
-		*n = *n * C.int(2)
-	}
-	return nil
-}
diff --git a/src/os/user/getgrouplist_syscall.go b/src/os/user/getgrouplist_syscall.go
new file mode 100644
index 0000000..41b64fc
--- /dev/null
+++ b/src/os/user/getgrouplist_syscall.go
@@ -0,0 +1,19 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !osusergo && darwin
+
+package user
+
+import (
+	"internal/syscall/unix"
+)
+
+func getGroupList(name *_C_char, userGID _C_gid_t, gids *_C_gid_t, n *_C_int) _C_int {
+	err := unix.Getgrouplist(name, userGID, gids, n)
+	if err != nil {
+		return -1
+	}
+	return 0
+}
diff --git a/src/os/user/getgrouplist_unix.go b/src/os/user/getgrouplist_unix.go
index 104c224..fb482d3 100644
--- a/src/os/user/getgrouplist_unix.go
+++ b/src/os/user/getgrouplist_unix.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build (dragonfly || freebsd || (!android && linux) || netbsd || openbsd || (solaris && !illumos)) && cgo && !osusergo
+//go:build cgo && !osusergo && (dragonfly || freebsd || (!android && linux) || netbsd || openbsd || (solaris && !illumos))
 
 package user
 
@@ -16,26 +16,7 @@
 }
 */
 import "C"
-import (
-	"fmt"
-	"unsafe"
-)
 
-func getGroupList(name *C.char, userGID C.gid_t, gids *C.gid_t, n *C.int) C.int {
+func getGroupList(name *_C_char, userGID _C_gid_t, gids *_C_gid_t, n *_C_int) _C_int {
 	return C.mygetgrouplist(name, userGID, gids, n)
 }
-
-// groupRetry retries getGroupList with much larger size for n. The result is
-// stored in gids.
-func groupRetry(username string, name []byte, userGID C.gid_t, gids *[]C.gid_t, n *C.int) error {
-	// More than initial buffer, but now n contains the correct size.
-	if *n > maxGroups {
-		return fmt.Errorf("user: %q is a member of more than %d groups", username, maxGroups)
-	}
-	*gids = make([]C.gid_t, *n)
-	rv := getGroupList((*C.char)(unsafe.Pointer(&name[0])), userGID, &(*gids)[0], n)
-	if rv == -1 {
-		return fmt.Errorf("user: list groups for %s failed", username)
-	}
-	return nil
-}
diff --git a/src/os/user/listgroups_unix.go b/src/os/user/listgroups_unix.go
index fa2df49..ef366fa 100644
--- a/src/os/user/listgroups_unix.go
+++ b/src/os/user/listgroups_unix.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build ((darwin || dragonfly || freebsd || (js && wasm) || (!android && linux) || netbsd || openbsd || solaris) && (!cgo || osusergo)) || aix || illumos
+//go:build ((darwin || dragonfly || freebsd || (js && wasm) || (!android && linux) || netbsd || openbsd || solaris) && ((!cgo && !darwin) || osusergo)) || aix || illumos
 
 package user
 
@@ -16,10 +16,6 @@
 	"strconv"
 )
 
-const groupFile = "/etc/group"
-
-var colon = []byte{':'}
-
 func listGroupsFromReader(u *User, r io.Reader) ([]string, error) {
 	if u.Username == "" {
 		return nil, errors.New("user: list groups: empty username")
diff --git a/src/os/user/listgroups_unix_test.go b/src/os/user/listgroups_unix_test.go
index a9f79ec..4fa8b1f 100644
--- a/src/os/user/listgroups_unix_test.go
+++ b/src/os/user/listgroups_unix_test.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build ((darwin || dragonfly || freebsd || (js && wasm) || (!android && linux) || netbsd || openbsd || solaris) && (!cgo || osusergo)) || aix || illumos
+//go:build ((darwin || dragonfly || freebsd || (js && wasm) || (!android && linux) || netbsd || openbsd || solaris) && ((!cgo && !darwin) || osusergo)) || aix || illumos
 
 package user
 
@@ -25,7 +25,7 @@
 -minussign:*:21:root
 # Next line is invalid (empty group name)
 :*:22:root
-      
+
 daemon:*:1:root
     indented:*:7:root
 # comment:*:4:found
diff --git a/src/os/user/lookup.go b/src/os/user/lookup.go
index b36b7c0..ed33d0c 100644
--- a/src/os/user/lookup.go
+++ b/src/os/user/lookup.go
@@ -6,6 +6,13 @@
 
 import "sync"
 
+const (
+	userFile  = "/etc/passwd"
+	groupFile = "/etc/group"
+)
+
+var colon = []byte{':'}
+
 // Current returns the current user.
 //
 // The first call will cache the current user information.
diff --git a/src/os/user/lookup_plan9.go b/src/os/user/lookup_plan9.go
index 0793936..c2aabd5 100644
--- a/src/os/user/lookup_plan9.go
+++ b/src/os/user/lookup_plan9.go
@@ -13,9 +13,6 @@
 // Partial os/user support on Plan 9.
 // Supports Current(), but not Lookup()/LookupId().
 // The latter two would require parsing /adm/users.
-const (
-	userFile = "/dev/user"
-)
 
 func init() {
 	userImplemented = false
@@ -23,8 +20,15 @@
 	groupListImplemented = false
 }
 
+var (
+	// unused variables (in this implementation)
+	// modified during test to exercise code paths in the cgo implementation.
+	userBuffer  = 0
+	groupBuffer = 0
+)
+
 func current() (*User, error) {
-	ubytes, err := os.ReadFile(userFile)
+	ubytes, err := os.ReadFile("/dev/user")
 	if err != nil {
 		return nil, fmt.Errorf("user: %s", err)
 	}
diff --git a/src/os/user/lookup_stubs.go b/src/os/user/lookup_stubs.go
index ce1617d..89dfe45 100644
--- a/src/os/user/lookup_stubs.go
+++ b/src/os/user/lookup_stubs.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build (!cgo && !windows && !plan9) || android || (osusergo && !windows && !plan9)
+//go:build (!cgo && !darwin && !windows && !plan9) || android || (osusergo && !windows && !plan9)
 
 package user
 
@@ -13,6 +13,13 @@
 	"strconv"
 )
 
+var (
+	// unused variables (in this implementation)
+	// modified during test to exercise code paths in the cgo implementation.
+	userBuffer  = 0
+	groupBuffer = 0
+)
+
 func current() (*User, error) {
 	uid := currentUID()
 	// $USER and /etc/passwd may disagree; prefer the latter if we can get it.
diff --git a/src/os/user/lookup_unix.go b/src/os/user/lookup_unix.go
index ed06e73..608d9b2 100644
--- a/src/os/user/lookup_unix.go
+++ b/src/os/user/lookup_unix.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build ((unix && !android) || (js && wasm)) && (!cgo || osusergo)
+//go:build ((unix && !android) || (js && wasm)) && ((!cgo && !darwin) || osusergo)
 
 package user
 
@@ -16,8 +16,6 @@
 	"strings"
 )
 
-const userFile = "/etc/passwd"
-
 // lineFunc returns a value, an error, or (nil, nil) to skip the row.
 type lineFunc func(line []byte) (v any, err error)
 
diff --git a/src/os/user/lookup_unix_test.go b/src/os/user/lookup_unix_test.go
index 399a03f..78b3392 100644
--- a/src/os/user/lookup_unix_test.go
+++ b/src/os/user/lookup_unix_test.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build unix && !android && !cgo
+//go:build unix && !android && !cgo && !darwin
 
 package user
 
diff --git a/src/os/user/lookup_windows.go b/src/os/user/lookup_windows.go
index f65773c..e64b8ae 100644
--- a/src/os/user/lookup_windows.go
+++ b/src/os/user/lookup_windows.go
@@ -192,6 +192,13 @@
 	return u, nil
 }
 
+var (
+	// unused variables (in this implementation)
+	// modified during test to exercise code paths in the cgo implementation.
+	userBuffer  = 0
+	groupBuffer = 0
+)
+
 func current() (*User, error) {
 	t, e := syscall.OpenCurrentProcessToken()
 	if e != nil {
diff --git a/src/os/user/user_test.go b/src/os/user/user_test.go
index 8025174..0fa963d 100644
--- a/src/os/user/user_test.go
+++ b/src/os/user/user_test.go
@@ -16,6 +16,11 @@
 }
 
 func TestCurrent(t *testing.T) {
+	old := userBuffer
+	defer func() {
+		userBuffer = old
+	}()
+	userBuffer = 1 // force use of retry code
 	u, err := Current()
 	if err != nil {
 		t.Fatalf("Current: %v (got %#v)", err, u)
@@ -91,6 +96,11 @@
 }
 
 func TestLookupGroup(t *testing.T) {
+	old := groupBuffer
+	defer func() {
+		groupBuffer = old
+	}()
+	groupBuffer = 1 // force use of retry code
 	checkGroup(t)
 	user, err := Current()
 	if err != nil {
diff --git a/src/os/wait6_dragonfly.go b/src/os/wait6_dragonfly.go
new file mode 100644
index 0000000..cc3af39
--- /dev/null
+++ b/src/os/wait6_dragonfly.go
@@ -0,0 +1,18 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package os
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+const _P_PID = 0
+
+func wait6(idtype, id, options int) (status int, errno syscall.Errno) {
+	var status32 int32 // C.int
+	_, _, errno = syscall.Syscall6(syscall.SYS_WAIT6, uintptr(idtype), uintptr(id), uintptr(unsafe.Pointer(&status32)), uintptr(options), 0, 0)
+	return int(status32), errno
+}
diff --git a/src/os/wait6_freebsd64.go b/src/os/wait6_freebsd64.go
new file mode 100644
index 0000000..b2677c5
--- /dev/null
+++ b/src/os/wait6_freebsd64.go
@@ -0,0 +1,20 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build freebsd && (amd64 || arm64 || riscv64)
+
+package os
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+const _P_PID = 0
+
+func wait6(idtype, id, options int) (status int, errno syscall.Errno) {
+	var status32 int32 // C.int
+	_, _, errno = syscall.Syscall6(syscall.SYS_WAIT6, uintptr(idtype), uintptr(id), uintptr(unsafe.Pointer(&status32)), uintptr(options), 0, 0)
+	return int(status32), errno
+}
diff --git a/src/os/wait6_freebsd_386.go b/src/os/wait6_freebsd_386.go
new file mode 100644
index 0000000..30b01c5
--- /dev/null
+++ b/src/os/wait6_freebsd_386.go
@@ -0,0 +1,18 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package os
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+const _P_PID = 0
+
+func wait6(idtype, id, options int) (status int, errno syscall.Errno) {
+	// freebsd32_wait6_args{ idtype, id1, id2, status, options, wrusage, info }
+	_, _, errno = syscall.Syscall9(syscall.SYS_WAIT6, uintptr(idtype), uintptr(id), 0, uintptr(unsafe.Pointer(&status)), uintptr(options), 0, 0, 0, 0)
+	return status, errno
+}
diff --git a/src/os/wait6_freebsd_arm.go b/src/os/wait6_freebsd_arm.go
new file mode 100644
index 0000000..0fd8af0
--- /dev/null
+++ b/src/os/wait6_freebsd_arm.go
@@ -0,0 +1,18 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package os
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+const _P_PID = 0
+
+func wait6(idtype, id, options int) (status int, errno syscall.Errno) {
+	// freebsd32_wait6_args{ idtype, pad, id1, id2, status, options, wrusage, info }
+	_, _, errno = syscall.Syscall9(syscall.SYS_WAIT6, uintptr(idtype), 0, uintptr(id), 0, uintptr(unsafe.Pointer(&status)), uintptr(options), 0, 0, 0)
+	return status, errno
+}
diff --git a/src/os/wait6_netbsd.go b/src/os/wait6_netbsd.go
new file mode 100644
index 0000000..0bbb73d
--- /dev/null
+++ b/src/os/wait6_netbsd.go
@@ -0,0 +1,18 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package os
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+const _P_PID = 1 // not 0 as on FreeBSD and Dragonfly!
+
+func wait6(idtype, id, options int) (status int, errno syscall.Errno) {
+	var status32 int32 // C.int
+	_, _, errno = syscall.Syscall6(syscall.SYS_WAIT6, uintptr(idtype), uintptr(id), uintptr(unsafe.Pointer(&status32)), uintptr(options), 0, 0)
+	return int(status32), errno
+}
diff --git a/src/os/wait_unimp.go b/src/os/wait_unimp.go
index 721b9f9..bc93e44 100644
--- a/src/os/wait_unimp.go
+++ b/src/os/wait_unimp.go
@@ -6,7 +6,7 @@
 // waitid/wait6. netbsd implements wait6, but that is causing test
 // failures, see issue #48789.
 
-//go:build aix || darwin || (js && wasm) || netbsd || openbsd || solaris
+//go:build aix || darwin || (js && wasm) || openbsd || solaris
 
 package os
 
diff --git a/src/os/wait_wait6.go b/src/os/wait_wait6.go
index d395dac..1031428 100644
--- a/src/os/wait_wait6.go
+++ b/src/os/wait_wait6.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build dragonfly || freebsd
+//go:build dragonfly || freebsd || netbsd
 
 package os
 
@@ -11,24 +11,13 @@
 	"syscall"
 )
 
-const _P_PID = 0
-
 // blockUntilWaitable attempts to block until a call to p.Wait will
 // succeed immediately, and reports whether it has done so.
 // It does not actually call p.Wait.
 func (p *Process) blockUntilWaitable() (bool, error) {
 	var errno syscall.Errno
 	for {
-		// The arguments on 32-bit FreeBSD look like the following:
-		// - freebsd32_wait6_args{ idtype, id1, id2, status, options, wrusage, info } or
-		// - freebsd32_wait6_args{ idtype, pad, id1, id2, status, options, wrusage, info } when PAD64_REQUIRED=1 on ARM, MIPS or PowerPC
-		if runtime.GOOS == "freebsd" && runtime.GOARCH == "386" {
-			_, _, errno = syscall.Syscall9(syscall.SYS_WAIT6, _P_PID, uintptr(p.Pid), 0, 0, syscall.WEXITED|syscall.WNOWAIT, 0, 0, 0, 0)
-		} else if runtime.GOOS == "freebsd" && runtime.GOARCH == "arm" {
-			_, _, errno = syscall.Syscall9(syscall.SYS_WAIT6, _P_PID, 0, uintptr(p.Pid), 0, 0, syscall.WEXITED|syscall.WNOWAIT, 0, 0, 0)
-		} else {
-			_, _, errno = syscall.Syscall6(syscall.SYS_WAIT6, _P_PID, uintptr(p.Pid), 0, syscall.WEXITED|syscall.WNOWAIT, 0, 0)
-		}
+		_, errno = wait6(_P_PID, p.Pid, syscall.WEXITED|syscall.WNOWAIT)
 		if errno != syscall.EINTR {
 			break
 		}
diff --git a/src/path/filepath/path.go b/src/path/filepath/path.go
index de7a2c7..32dd887 100644
--- a/src/path/filepath/path.go
+++ b/src/path/filepath/path.go
@@ -15,6 +15,7 @@
 	"errors"
 	"io/fs"
 	"os"
+	"runtime"
 	"sort"
 	"strings"
 )
@@ -91,7 +92,7 @@
 	volLen := volumeNameLen(path)
 	path = path[volLen:]
 	if path == "" {
-		if volLen > 1 && originalPath[1] != ':' {
+		if volLen > 1 && os.IsPathSeparator(originalPath[0]) && os.IsPathSeparator(originalPath[1]) {
 			// should be UNC
 			return FromSlash(originalPath)
 		}
@@ -117,21 +118,9 @@
 		case os.IsPathSeparator(path[r]):
 			// empty path element
 			r++
-		case path[r] == '.' && r+1 == n:
+		case path[r] == '.' && (r+1 == n || os.IsPathSeparator(path[r+1])):
 			// . element
 			r++
-		case path[r] == '.' && os.IsPathSeparator(path[r+1]):
-			// ./ element
-			r++
-
-			for r < len(path) && os.IsPathSeparator(path[r]) {
-				r++
-			}
-			if out.w == 0 && volumeNameLen(path[r:]) > 0 {
-				// When joining prefix "." and an absolute path on Windows,
-				// the prefix should not be removed.
-				out.append('.')
-			}
 		case path[r] == '.' && path[r+1] == '.' && (r+2 == n || os.IsPathSeparator(path[r+2])):
 			// .. element: remove to last separator
 			r += 2
@@ -157,6 +146,18 @@
 			if rooted && out.w != 1 || !rooted && out.w != 0 {
 				out.append(Separator)
 			}
+			// If a ':' appears in the path element at the start of a Windows path,
+			// insert a .\ at the beginning to avoid converting relative paths
+			// like a/../c: into c:.
+			if runtime.GOOS == "windows" && out.w == 0 && out.volLen == 0 && r != 0 {
+				for i := r; i < n && !os.IsPathSeparator(path[i]); i++ {
+					if path[i] == ':' {
+						out.append('.')
+						out.append(Separator)
+						break
+					}
+				}
+			}
 			// copy element
 			for ; r < n && !os.IsPathSeparator(path[r]); r++ {
 				out.append(path[r])
@@ -172,6 +173,46 @@
 	return FromSlash(out.string())
 }
 
+// IsLocal reports whether path, using lexical analysis only, has all of these properties:
+//
+//   - is within the subtree rooted at the directory in which path is evaluated
+//   - is not an absolute path
+//   - is not empty
+//   - on Windows, is not a reserved name such as "NUL"
+//
+// If IsLocal(path) returns true, then
+// Join(base, path) will always produce a path contained within base and
+// Clean(path) will always produce an unrooted path with no ".." path elements.
+//
+// IsLocal is a purely lexical operation.
+// In particular, it does not account for the effect of any symbolic links
+// that may exist in the filesystem.
+func IsLocal(path string) bool {
+	return isLocal(path)
+}
+
+func unixIsLocal(path string) bool {
+	if IsAbs(path) || path == "" {
+		return false
+	}
+	hasDots := false
+	for p := path; p != ""; {
+		var part string
+		part, p, _ = strings.Cut(p, "/")
+		if part == "." || part == ".." {
+			hasDots = true
+			break
+		}
+	}
+	if hasDots {
+		path = Clean(path)
+	}
+	if path == ".." || strings.HasPrefix(path, "../") {
+		return false
+	}
+	return true
+}
+
 // ToSlash returns the result of replacing each separator character
 // in path with a slash ('/') character. Multiple separators are
 // replaced by multiple slashes.
@@ -352,6 +393,11 @@
 // as an error by any function.
 var SkipDir error = fs.SkipDir
 
+// SkipAll is used as a return value from WalkFuncs to indicate that
+// all remaining files and directories are to be skipped. It is not returned
+// as an error by any function.
+var SkipAll error = fs.SkipAll
+
 // WalkFunc is the type of the function called by Walk to visit each
 // file or directory.
 //
@@ -370,8 +416,9 @@
 // The error result returned by the function controls how Walk continues.
 // If the function returns the special value SkipDir, Walk skips the
 // current directory (path if info.IsDir() is true, otherwise path's
-// parent directory). Otherwise, if the function returns a non-nil error,
-// Walk stops entirely and returns that error.
+// parent directory). If the function returns the special value SkipAll,
+// Walk skips all remaining files and directories. Otherwise, if the function
+// returns a non-nil error, Walk stops entirely and returns that error.
 //
 // The err argument reports an error related to path, signaling that Walk
 // will not walk into that directory. The function can decide how to
@@ -441,7 +488,7 @@
 	if err != nil || err1 != nil {
 		// The caller's behavior is controlled by the return value, which is decided
 		// by walkFn. walkFn may ignore err and return nil.
-		// If walkFn returns SkipDir, it will be handled by the caller.
+		// If walkFn returns SkipDir or SkipAll, it will be handled by the caller.
 		// So walk should return whatever walkFn returns.
 		return err1
 	}
@@ -476,6 +523,10 @@
 // to walk that directory.
 //
 // WalkDir does not follow symbolic links.
+//
+// WalkDir calls fn with paths that use the separator character appropriate
+// for the operating system. This is unlike [io/fs.WalkDir], which always
+// uses slash separated paths.
 func WalkDir(root string, fn fs.WalkDirFunc) error {
 	info, err := os.Lstat(root)
 	if err != nil {
@@ -483,7 +534,7 @@
 	} else {
 		err = walkDir(root, &statDirEntry{info}, fn)
 	}
-	if err == SkipDir {
+	if err == SkipDir || err == SkipAll {
 		return nil
 	}
 	return err
@@ -519,7 +570,7 @@
 	} else {
 		err = walk(root, info, fn)
 	}
-	if err == SkipDir {
+	if err == SkipDir || err == SkipAll {
 		return nil
 	}
 	return err
@@ -611,5 +662,5 @@
 // Given "\\host\share\foo" it returns "\\host\share".
 // On other platforms it returns "".
 func VolumeName(path string) string {
-	return path[:volumeNameLen(path)]
+	return FromSlash(path[:volumeNameLen(path)])
 }
diff --git a/src/path/filepath/path_plan9.go b/src/path/filepath/path_plan9.go
index ec792fc..453206a 100644
--- a/src/path/filepath/path_plan9.go
+++ b/src/path/filepath/path_plan9.go
@@ -6,6 +6,10 @@
 
 import "strings"
 
+func isLocal(path string) bool {
+	return unixIsLocal(path)
+}
+
 // IsAbs reports whether the path is absolute.
 func IsAbs(path string) bool {
 	return strings.HasPrefix(path, "/") || strings.HasPrefix(path, "#")
diff --git a/src/path/filepath/path_test.go b/src/path/filepath/path_test.go
index a783d6b..697bcc6 100644
--- a/src/path/filepath/path_test.go
+++ b/src/path/filepath/path_test.go
@@ -49,9 +49,6 @@
 
 	// Remove doubled slash
 	{"abc//def//ghi", "abc/def/ghi"},
-	{"//abc", "/abc"},
-	{"///abc", "/abc"},
-	{"//abc//", "/abc"},
 	{"abc//", "abc"},
 
 	// Remove . elements
@@ -76,6 +73,13 @@
 	{"abc/../../././../def", "../../def"},
 }
 
+var nonwincleantests = []PathTest{
+	// Remove leading doubled slash
+	{"//abc", "/abc"},
+	{"///abc", "/abc"},
+	{"//abc//", "/abc"},
+}
+
 var wincleantests = []PathTest{
 	{`c:`, `c:.`},
 	{`c:\`, `c:\`},
@@ -86,16 +90,29 @@
 	{`c:..\abc`, `c:..\abc`},
 	{`\`, `\`},
 	{`/`, `\`},
-	{`\\i\..\c$`, `\c$`},
-	{`\\i\..\i\c$`, `\i\c$`},
-	{`\\i\..\I\c$`, `\I\c$`},
+	{`\\i\..\c$`, `\\i\..\c$`},
+	{`\\i\..\i\c$`, `\\i\..\i\c$`},
+	{`\\i\..\I\c$`, `\\i\..\I\c$`},
 	{`\\host\share\foo\..\bar`, `\\host\share\bar`},
 	{`//host/share/foo/../baz`, `\\host\share\baz`},
+	{`\\host\share\foo\..\..\..\..\bar`, `\\host\share\bar`},
+	{`\\.\C:\a\..\..\..\..\bar`, `\\.\C:\bar`},
+	{`\\.\C:\\\\a`, `\\.\C:\a`},
 	{`\\a\b\..\c`, `\\a\b\c`},
 	{`\\a\b`, `\\a\b`},
 	{`.\c:`, `.\c:`},
 	{`.\c:\foo`, `.\c:\foo`},
 	{`.\c:foo`, `.\c:foo`},
+	{`//abc`, `\\abc`},
+	{`///abc`, `\\\abc`},
+	{`//abc//`, `\\abc\\`},
+
+	// Don't allow cleaning to move an element with a colon to the start of the path.
+	{`a/../c:`, `.\c:`},
+	{`a\..\c:`, `.\c:`},
+	{`a/../c:/a`, `.\c:\a`},
+	{`a/../../c:`, `..\c:`},
+	{`foo:bar`, `foo:bar`},
 }
 
 func TestClean(t *testing.T) {
@@ -105,6 +122,8 @@
 			tests[i].result = filepath.FromSlash(tests[i].result)
 		}
 		tests = append(tests, wincleantests...)
+	} else {
+		tests = append(tests, nonwincleantests...)
 	}
 	for _, test := range tests {
 		if s := filepath.Clean(test.path); s != test.result {
@@ -131,6 +150,64 @@
 	}
 }
 
+type IsLocalTest struct {
+	path    string
+	isLocal bool
+}
+
+var islocaltests = []IsLocalTest{
+	{"", false},
+	{".", true},
+	{"..", false},
+	{"../a", false},
+	{"/", false},
+	{"/a", false},
+	{"/a/../..", false},
+	{"a", true},
+	{"a/../a", true},
+	{"a/", true},
+	{"a/.", true},
+	{"a/./b/./c", true},
+}
+
+var winislocaltests = []IsLocalTest{
+	{"NUL", false},
+	{"nul", false},
+	{"nul.", false},
+	{"com1", false},
+	{"./nul", false},
+	{`\`, false},
+	{`\a`, false},
+	{`C:`, false},
+	{`C:\a`, false},
+	{`..\a`, false},
+	{`a/../c:`, false},
+	{`CONIN$`, false},
+	{`conin$`, false},
+	{`CONOUT$`, false},
+	{`conout$`, false},
+	{`dollar$`, true}, // not a special file name
+}
+
+var plan9islocaltests = []IsLocalTest{
+	{"#a", false},
+}
+
+func TestIsLocal(t *testing.T) {
+	tests := islocaltests
+	if runtime.GOOS == "windows" {
+		tests = append(tests, winislocaltests...)
+	}
+	if runtime.GOOS == "plan9" {
+		tests = append(tests, plan9islocaltests...)
+	}
+	for _, test := range tests {
+		if got := filepath.IsLocal(test.path); got != test.isLocal {
+			t.Errorf("IsLocal(%q) = %v, want %v", test.path, got, test.isLocal)
+		}
+	}
+}
+
 const sep = filepath.Separator
 
 var slashtests = []PathTest{
@@ -257,8 +334,9 @@
 	{[]string{"/", "a"}, "/a"},
 	{[]string{"/", "a/b"}, "/a/b"},
 	{[]string{"/", ""}, "/"},
-	{[]string{"//", "a"}, "/a"},
 	{[]string{"/a", "b"}, "/a/b"},
+	{[]string{"a", "/b"}, "a/b"},
+	{[]string{"/a", "/b"}, "/a/b"},
 	{[]string{"a/", "b"}, "a/b"},
 	{[]string{"a/", ""}, "a"},
 	{[]string{"", ""}, ""},
@@ -267,6 +345,10 @@
 	{[]string{"/", "a", "b"}, "/a/b"},
 }
 
+var nonwinjointests = []JoinTest{
+	{[]string{"//", "a"}, "/a"},
+}
+
 var winjointests = []JoinTest{
 	{[]string{`directory`, `file`}, `directory\file`},
 	{[]string{`C:\Windows\`, `System32`}, `C:\Windows\System32`},
@@ -279,6 +361,8 @@
 	{[]string{`C:`, ``, ``, `b`}, `C:b`},
 	{[]string{`C:`, ``}, `C:.`},
 	{[]string{`C:`, ``, ``}, `C:.`},
+	{[]string{`C:`, `\a`}, `C:\a`},
+	{[]string{`C:`, ``, `\a`}, `C:\a`},
 	{[]string{`C:.`, `a`}, `C:a`},
 	{[]string{`C:a`, `b`}, `C:a\b`},
 	{[]string{`C:a`, `b`, `d`}, `C:a\b\d`},
@@ -288,17 +372,20 @@
 	{[]string{`\`}, `\`},
 	{[]string{`\`, ``}, `\`},
 	{[]string{`\`, `a`}, `\a`},
-	{[]string{`\\`, `a`}, `\a`},
+	{[]string{`\\`, `a`}, `\\a`},
 	{[]string{`\`, `a`, `b`}, `\a\b`},
-	{[]string{`\\`, `a`, `b`}, `\a\b`},
+	{[]string{`\\`, `a`, `b`}, `\\a\b`},
 	{[]string{`\`, `\\a\b`, `c`}, `\a\b\c`},
-	{[]string{`\\a`, `b`, `c`}, `\a\b\c`},
-	{[]string{`\\a\`, `b`, `c`}, `\a\b\c`},
+	{[]string{`\\a`, `b`, `c`}, `\\a\b\c`},
+	{[]string{`\\a\`, `b`, `c`}, `\\a\b\c`},
+	{[]string{`//`, `a`}, `\\a`},
 }
 
 func TestJoin(t *testing.T) {
 	if runtime.GOOS == "windows" {
 		jointests = append(jointests, winjointests...)
+	} else {
+		jointests = append(jointests, nonwinjointests...)
 	}
 	for _, test := range jointests {
 		expected := filepath.FromSlash(test.path)
@@ -638,6 +725,64 @@
 	})
 }
 
+func TestWalkSkipAllOnFile(t *testing.T) {
+	td := t.TempDir()
+
+	if err := os.MkdirAll(filepath.Join(td, "dir", "subdir"), 0755); err != nil {
+		t.Fatal(err)
+	}
+	if err := os.MkdirAll(filepath.Join(td, "dir2"), 0755); err != nil {
+		t.Fatal(err)
+	}
+
+	touch(t, filepath.Join(td, "dir", "foo1"))
+	touch(t, filepath.Join(td, "dir", "foo2"))
+	touch(t, filepath.Join(td, "dir", "subdir", "foo3"))
+	touch(t, filepath.Join(td, "dir", "foo4"))
+	touch(t, filepath.Join(td, "dir2", "bar"))
+	touch(t, filepath.Join(td, "last"))
+
+	remainingWereSkipped := true
+	walker := func(path string) error {
+		if strings.HasSuffix(path, "foo2") {
+			return filepath.SkipAll
+		}
+
+		if strings.HasSuffix(path, "foo3") ||
+			strings.HasSuffix(path, "foo4") ||
+			strings.HasSuffix(path, "bar") ||
+			strings.HasSuffix(path, "last") {
+			remainingWereSkipped = false
+		}
+		return nil
+	}
+
+	walkFn := func(path string, _ fs.FileInfo, _ error) error { return walker(path) }
+	walkDirFn := func(path string, _ fs.DirEntry, _ error) error { return walker(path) }
+
+	check := func(t *testing.T, walk func(root string) error, root string) {
+		t.Helper()
+		remainingWereSkipped = true
+		if err := walk(root); err != nil {
+			t.Fatal(err)
+		}
+		if !remainingWereSkipped {
+			t.Errorf("SkipAll on file foo2 did not block processing of remaining files and directories")
+		}
+	}
+
+	t.Run("Walk", func(t *testing.T) {
+		Walk := func(_ string) error { return filepath.Walk(td, walkFn) }
+		check(t, Walk, td)
+		check(t, Walk, filepath.Join(td, "dir"))
+	})
+	t.Run("WalkDir", func(t *testing.T) {
+		WalkDir := func(_ string) error { return filepath.WalkDir(td, walkDirFn) }
+		check(t, WalkDir, td)
+		check(t, WalkDir, filepath.Join(td, "dir"))
+	})
+}
+
 func TestWalkFileError(t *testing.T) {
 	td := t.TempDir()
 
@@ -728,7 +873,6 @@
 	{".", "."},
 	{"/.", "/"},
 	{"/", "/"},
-	{"////", "/"},
 	{"/foo", "/"},
 	{"x/", "x"},
 	{"abc", "."},
@@ -738,6 +882,10 @@
 	{"a/b/c.x", "a/b"},
 }
 
+var nonwindirtests = []PathTest{
+	{"////", "/"},
+}
+
 var windirtests = []PathTest{
 	{`c:\`, `c:\`},
 	{`c:.`, `c:.`},
@@ -748,6 +896,7 @@
 	{`\\host\share\`, `\\host\share\`},
 	{`\\host\share\a`, `\\host\share\`},
 	{`\\host\share\a\b`, `\\host\share\a`},
+	{`\\\\`, `\\\\`},
 }
 
 func TestDir(t *testing.T) {
@@ -759,6 +908,8 @@
 		}
 		// add windows specific tests
 		tests = append(tests, windirtests...)
+	} else {
+		tests = append(tests, nonwindirtests...)
 	}
 	for _, test := range tests {
 		if s := filepath.Dir(test.path); s != test.result {
@@ -812,11 +963,6 @@
 		for _, test := range isabstests {
 			tests = append(tests, IsAbsTest{"c:" + test.path, test.isAbs})
 		}
-		// Test reserved names.
-		tests = append(tests, IsAbsTest{os.DevNull, true})
-		tests = append(tests, IsAbsTest{"NUL", true})
-		tests = append(tests, IsAbsTest{"nul", true})
-		tests = append(tests, IsAbsTest{"CON", true})
 	} else {
 		tests = isabstests
 	}
@@ -1274,24 +1420,30 @@
 	{`c:`, `c:`},
 	{`2:`, ``},
 	{``, ``},
-	{`\\\host`, ``},
-	{`\\\host\`, ``},
-	{`\\\host\share`, ``},
-	{`\\\host\\share`, ``},
-	{`\\host`, ``},
-	{`//host`, ``},
-	{`\\host\`, ``},
-	{`//host/`, ``},
+	{`\\\host`, `\\\host`},
+	{`\\\host\`, `\\\host`},
+	{`\\\host\share`, `\\\host`},
+	{`\\\host\\share`, `\\\host`},
+	{`\\host`, `\\host`},
+	{`//host`, `\\host`},
+	{`\\host\`, `\\host\`},
+	{`//host/`, `\\host\`},
 	{`\\host\share`, `\\host\share`},
-	{`//host/share`, `//host/share`},
+	{`//host/share`, `\\host\share`},
 	{`\\host\share\`, `\\host\share`},
-	{`//host/share/`, `//host/share`},
+	{`//host/share/`, `\\host\share`},
 	{`\\host\share\foo`, `\\host\share`},
-	{`//host/share/foo`, `//host/share`},
+	{`//host/share/foo`, `\\host\share`},
 	{`\\host\share\\foo\\\bar\\\\baz`, `\\host\share`},
-	{`//host/share//foo///bar////baz`, `//host/share`},
+	{`//host/share//foo///bar////baz`, `\\host\share`},
 	{`\\host\share\foo\..\bar`, `\\host\share`},
-	{`//host/share/foo/../bar`, `//host/share`},
+	{`//host/share/foo/../bar`, `\\host\share`},
+	{`//./NUL`, `\\.\NUL`},
+	{`//?/NUL`, `\\?\NUL`},
+	{`//./C:`, `\\.\C:`},
+	{`//./C:/a/b/c`, `\\.\C:`},
+	{`//./UNC/host/share/a/b/c`, `\\.\UNC\host\share`},
+	{`//./UNC/host`, `\\.\UNC\host`},
 }
 
 func TestVolumeName(t *testing.T) {
diff --git a/src/path/filepath/path_unix.go b/src/path/filepath/path_unix.go
index 93fdfdd..ab1d08d 100644
--- a/src/path/filepath/path_unix.go
+++ b/src/path/filepath/path_unix.go
@@ -8,6 +8,10 @@
 
 import "strings"
 
+func isLocal(path string) bool {
+	return unixIsLocal(path)
+}
+
 // IsAbs reports whether the path is absolute.
 func IsAbs(path string) bool {
 	return strings.HasPrefix(path, "/")
diff --git a/src/path/filepath/path_windows.go b/src/path/filepath/path_windows.go
index b4d8ac3..4dca9e0 100644
--- a/src/path/filepath/path_windows.go
+++ b/src/path/filepath/path_windows.go
@@ -13,39 +13,98 @@
 	return c == '\\' || c == '/'
 }
 
-// reservedNames lists reserved Windows names. Search for PRN in
-// https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file
-// for details.
-var reservedNames = []string{
-	"CON", "PRN", "AUX", "NUL",
-	"COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9",
-	"LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9",
+func toUpper(c byte) byte {
+	if 'a' <= c && c <= 'z' {
+		return c - ('a' - 'A')
+	}
+	return c
 }
 
-// isReservedName returns true, if path is Windows reserved name.
-// See reservedNames for the full list.
-func isReservedName(path string) bool {
-	if len(path) == 0 {
-		return false
-	}
-	for _, reserved := range reservedNames {
-		if strings.EqualFold(path, reserved) {
-			return true
+// isReservedName reports if name is a Windows reserved device name or a console handle.
+// It does not detect names with an extension, which are also reserved on some Windows versions.
+//
+// For details, search for PRN in
+// https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file.
+func isReservedName(name string) bool {
+	if 3 <= len(name) && len(name) <= 4 {
+		switch string([]byte{toUpper(name[0]), toUpper(name[1]), toUpper(name[2])}) {
+		case "CON", "PRN", "AUX", "NUL":
+			return len(name) == 3
+		case "COM", "LPT":
+			return len(name) == 4 && '1' <= name[3] && name[3] <= '9'
 		}
 	}
+	// Passing CONIN$ or CONOUT$ to CreateFile opens a console handle.
+	// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea#consoles
+	//
+	// While CONIN$ and CONOUT$ aren't documented as being files,
+	// they behave the same as CON. For example, ./CONIN$ also opens the console input.
+	if len(name) == 6 && name[5] == '$' && strings.EqualFold(name, "CONIN$") {
+		return true
+	}
+	if len(name) == 7 && name[6] == '$' && strings.EqualFold(name, "CONOUT$") {
+		return true
+	}
 	return false
 }
 
+func isLocal(path string) bool {
+	if path == "" {
+		return false
+	}
+	if isSlash(path[0]) {
+		// Path rooted in the current drive.
+		return false
+	}
+	if strings.IndexByte(path, ':') >= 0 {
+		// Colons are only valid when marking a drive letter ("C:foo").
+		// Rejecting any path with a colon is conservative but safe.
+		return false
+	}
+	hasDots := false // contains . or .. path elements
+	for p := path; p != ""; {
+		var part string
+		part, p, _ = cutPath(p)
+		if part == "." || part == ".." {
+			hasDots = true
+		}
+		// Trim the extension and look for a reserved name.
+		base, _, hasExt := strings.Cut(part, ".")
+		if isReservedName(base) {
+			if !hasExt {
+				return false
+			}
+			// The path element is a reserved name with an extension. Some Windows
+			// versions consider this a reserved name, while others do not. Use
+			// FullPath to see if the name is reserved.
+			//
+			// FullPath will convert references to reserved device names to their
+			// canonical form: \\.\${DEVICE_NAME}
+			//
+			// FullPath does not perform this conversion for paths which contain
+			// a reserved device name anywhere other than in the last element,
+			// so check the part rather than the full path.
+			if p, _ := syscall.FullPath(part); len(p) >= 4 && p[:4] == `\\.\` {
+				return false
+			}
+		}
+	}
+	if hasDots {
+		path = Clean(path)
+	}
+	if path == ".." || strings.HasPrefix(path, `..\`) {
+		return false
+	}
+	return true
+}
+
 // IsAbs reports whether the path is absolute.
 func IsAbs(path string) (b bool) {
-	if isReservedName(path) {
-		return true
-	}
 	l := volumeNameLen(path)
 	if l == 0 {
 		return false
 	}
-	// If the volume name starts with a double slash, this is a UNC path.
+	// If the volume name starts with a double slash, this is an absolute path.
 	if isSlash(path[0]) && isSlash(path[1]) {
 		return true
 	}
@@ -58,6 +117,8 @@
 
 // volumeNameLen returns length of the leading volume name on Windows.
 // It returns 0 elsewhere.
+//
+// See: https://learn.microsoft.com/en-us/dotnet/standard/io/file-path-formats
 func volumeNameLen(path string) int {
 	if len(path) < 2 {
 		return 0
@@ -67,31 +128,40 @@
 	if path[1] == ':' && ('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z') {
 		return 2
 	}
-	// is it UNC? https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
-	if l := len(path); l >= 5 && isSlash(path[0]) && isSlash(path[1]) &&
-		!isSlash(path[2]) && path[2] != '.' {
-		// first, leading `\\` and next shouldn't be `\`. its server name.
-		for n := 3; n < l-1; n++ {
-			// second, next '\' shouldn't be repeated.
-			if isSlash(path[n]) {
-				n++
-				// third, following something characters. its share name.
-				if !isSlash(path[n]) {
-					if path[n] == '.' {
-						break
-					}
-					for ; n < l; n++ {
-						if isSlash(path[n]) {
-							break
-						}
-					}
-					return n
-				}
-				break
-			}
+	// UNC and DOS device paths start with two slashes.
+	if !isSlash(path[0]) || !isSlash(path[1]) {
+		return 0
+	}
+	rest := path[2:]
+	p1, rest, _ := cutPath(rest)
+	p2, rest, ok := cutPath(rest)
+	if !ok {
+		return len(path)
+	}
+	if p1 != "." && p1 != "?" {
+		// This is a UNC path: \\${HOST}\${SHARE}\
+		return len(path) - len(rest) - 1
+	}
+	// This is a DOS device path.
+	if len(p2) == 3 && toUpper(p2[0]) == 'U' && toUpper(p2[1]) == 'N' && toUpper(p2[2]) == 'C' {
+		// This is a DOS device path that links to a UNC: \\.\UNC\${HOST}\${SHARE}\
+		_, rest, _ = cutPath(rest)  // host
+		_, rest, ok = cutPath(rest) // share
+		if !ok {
+			return len(path)
 		}
 	}
-	return 0
+	return len(path) - len(rest) - 1
+}
+
+// cutPath slices path around the first path separator.
+func cutPath(path string) (before, after string, found bool) {
+	for i := range path {
+		if isSlash(path[i]) {
+			return path[:i], path[i+1:], true
+		}
+	}
+	return path, "", false
 }
 
 // HasPrefix exists for historical compatibility and should not be used.
@@ -151,12 +221,44 @@
 }
 
 func join(elem []string) string {
-	for i, e := range elem {
-		if e != "" {
-			return joinNonEmpty(elem[i:])
+	var b strings.Builder
+	var lastChar byte
+	for _, e := range elem {
+		switch {
+		case b.Len() == 0:
+			// Add the first non-empty path element unchanged.
+		case isSlash(lastChar):
+			// If the path ends in a slash, strip any leading slashes from the next
+			// path element to avoid creating a UNC path (any path starting with "\\")
+			// from non-UNC elements.
+			//
+			// The correct behavior for Join when the first element is an incomplete UNC
+			// path (for example, "\\") is underspecified. We currently join subsequent
+			// elements so Join("\\", "host", "share") produces "\\host\share".
+			for len(e) > 0 && isSlash(e[0]) {
+				e = e[1:]
+			}
+		case lastChar == ':':
+			// If the path ends in a colon, keep the path relative to the current directory
+			// on a drive and don't add a separator. Preserve leading slashes in the next
+			// path element, which may make the path absolute.
+			//
+			// 	Join(`C:`, `f`) = `C:f`
+			//	Join(`C:`, `\f`) = `C:\f`
+		default:
+			// In all other cases, add a separator between elements.
+			b.WriteByte('\\')
+			lastChar = '\\'
+		}
+		if len(e) > 0 {
+			b.WriteString(e)
+			lastChar = e[len(e)-1]
 		}
 	}
-	return ""
+	if b.Len() == 0 {
+		return ""
+	}
+	return Clean(b.String())
 }
 
 // joinNonEmpty is like join, but it assumes that the first element is non-empty.
@@ -196,7 +298,7 @@
 
 // isUNC reports whether path is a UNC path.
 func isUNC(path string) bool {
-	return volumeNameLen(path) > 2
+	return len(path) > 1 && isSlash(path[0]) && isSlash(path[1])
 }
 
 func sameWord(a, b string) bool {
diff --git a/src/path/filepath/path_windows_test.go b/src/path/filepath/path_windows_test.go
index 9e6c0ec..c8c7eef 100644
--- a/src/path/filepath/path_windows_test.go
+++ b/src/path/filepath/path_windows_test.go
@@ -542,7 +542,7 @@
 	}{
 		{`..\.`, `C:`, `..\C:`},
 		{`..`, `C:`, `..\C:`},
-		{`.`, `:`, `:`},
+		{`.`, `:`, `.\:`},
 		{`.`, `C:`, `.\C:`},
 		{`.`, `C:/a/b/../c`, `.\C:\a\c`},
 		{`.`, `\C:`, `.\C:`},
@@ -560,3 +560,23 @@
 		}
 	}
 }
+
+func TestAbsWindows(t *testing.T) {
+	for _, test := range []struct {
+		path string
+		want string
+	}{
+		{`C:\foo`, `C:\foo`},
+		{`\\host\share\foo`, `\\host\share\foo`},
+		{`\\host`, `\\host`},
+		{`\\.\NUL`, `\\.\NUL`},
+		{`NUL`, `\\.\NUL`},
+		{`COM1`, `\\.\COM1`},
+		{`a/NUL`, `\\.\NUL`},
+	} {
+		got, err := filepath.Abs(test.path)
+		if err != nil || got != test.want {
+			t.Errorf("Abs(%q) = %q, %v; want %q, nil", test.path, got, err, test.want)
+		}
+	}
+}
diff --git a/src/path/filepath/symlink_unix.go b/src/path/filepath/symlink_unix.go
index f8980d5..4cac063 100644
--- a/src/path/filepath/symlink_unix.go
+++ b/src/path/filepath/symlink_unix.go
@@ -1,3 +1,7 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
 //go:build !windows && !plan9
 
 package filepath
diff --git a/src/plugin/plugin.go b/src/plugin/plugin.go
index b2a0fbe..a5489e6 100644
--- a/src/plugin/plugin.go
+++ b/src/plugin/plugin.go
@@ -13,8 +13,56 @@
 // already part of the program are called. The main function is not run.
 // A plugin is only initialized once, and cannot be closed.
 //
-// Currently plugins are only supported on Linux, FreeBSD, and macOS.
-// Please report any issues.
+// # Warnings
+//
+// The ability to dynamically load parts of an application during
+// execution, perhaps based on user-defined configuration, may be a
+// useful building block in some designs. In particular, because
+// applications and dynamically loaded functions can share data
+// structures directly, plugins may enable very high-performance
+// integration of separate parts.
+//
+// However, the plugin mechanism has many significant drawbacks that
+// should be considered carefully during the design. For example:
+//
+//   - Plugins are currently supported only on Linux, FreeBSD, and
+//     macOS, making them unsuitable for applications intended to be
+//     portable.
+//
+//   - Applications that use plugins may require careful configuration
+//     to ensure that the various parts of the program be made available
+//     in the correct location in the file system (or container image).
+//     By contrast, deploying an application consisting of a single static
+//     executable is straightforward.
+//
+//   - Reasoning about program initialization is more difficult when
+//     some packages may not be initialized until long after the
+//     application has started running.
+//
+//   - Bugs in applications that load plugins could be exploited by an
+//     an attacker to load dangerous or untrusted libraries.
+//
+//   - Runtime crashes are likely to occur unless all parts of the
+//     program (the application and all its plugins) are compiled
+//     using exactly the same version of the toolchain, the same build
+//     tags, and the same values of certain flags and environment
+//     variables.
+//
+//   - Similar crashing problems are likely to arise unless all common
+//     dependencies of the application and its plugins are built from
+//     exactly the same source code.
+//
+//   - Together, these restrictions mean that, in practice, the
+//     application and its plugins must all be built together by a
+//     single person or component of a system. In that case, it may
+//     be simpler for that person or component to generate Go source
+//     files that blank-import the desired set of plugins and then
+//     compile a static executable in the usual way.
+//
+// For these reasons, many users decide that traditional interprocess
+// communication (IPC) mechanisms such as sockets, pipes, remote
+// procedure call (RPC), shared memory mappings, or file system
+// operations may be more suitable despite the performance overheads.
 package plugin
 
 // Plugin is a loaded Go plugin.
diff --git a/src/plugin/plugin_dlopen.go b/src/plugin/plugin_dlopen.go
index 6ba0f78..b4c4e40 100644
--- a/src/plugin/plugin_dlopen.go
+++ b/src/plugin/plugin_dlopen.go
@@ -146,10 +146,10 @@
 	plugins   map[string]*Plugin
 )
 
-// lastmoduleinit is defined in package runtime
+// lastmoduleinit is defined in package runtime.
 func lastmoduleinit() (pluginpath string, syms map[string]any, errstr string)
 
-// doInit is defined in package runtime
+// doInit is defined in package runtime.
 //
 //go:linkname doInit runtime.doInit
 func doInit(t unsafe.Pointer) // t should be a *runtime.initTask
diff --git a/src/plugin/plugin_test.go b/src/plugin/plugin_test.go
index 8185095..557987c 100644
--- a/src/plugin/plugin_test.go
+++ b/src/plugin/plugin_test.go
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build !linux || (linux && !arm64)
-
 package plugin_test
 
 import (
diff --git a/src/reflect/all_test.go b/src/reflect/all_test.go
index 56d9110..28a7640 100644
--- a/src/reflect/all_test.go
+++ b/src/reflect/all_test.go
@@ -15,6 +15,7 @@
 	"io"
 	"math"
 	"math/rand"
+	"net"
 	"os"
 	. "reflect"
 	"reflect/internal/example1"
@@ -47,6 +48,8 @@
 	d *int
 }
 
+var _ = T{} == T{} // tests depend on T being comparable
+
 type pair struct {
 	i any
 	s string
@@ -364,7 +367,7 @@
 		}
 	}
 
-	if strings.HasSuffix(testenv.Builder(), "-noopt") {
+	if testenv.OptimizationOff() {
 		return // no inlining with the noopt builder
 	}
 
@@ -736,25 +739,88 @@
 	assert(t, v.Type().String(), "func()")
 }
 
+func TestGrow(t *testing.T) {
+	v := ValueOf([]int(nil))
+	shouldPanic("reflect.Value.Grow using unaddressable value", func() { v.Grow(0) })
+	v = ValueOf(new([]int)).Elem()
+	v.Grow(0)
+	if !v.IsNil() {
+		t.Errorf("v.Grow(0) should still be nil")
+	}
+	v.Grow(1)
+	if v.Cap() == 0 {
+		t.Errorf("v.Cap = %v, want non-zero", v.Cap())
+	}
+	want := v.UnsafePointer()
+	v.Grow(1)
+	got := v.UnsafePointer()
+	if got != want {
+		t.Errorf("noop v.Grow should not change pointers")
+	}
+
+	t.Run("Append", func(t *testing.T) {
+		var got, want []T
+		v := ValueOf(&got).Elem()
+		appendValue := func(vt T) {
+			v.Grow(1)
+			v.SetLen(v.Len() + 1)
+			v.Index(v.Len() - 1).Set(ValueOf(vt))
+		}
+		for i := 0; i < 10; i++ {
+			vt := T{i, float64(i), strconv.Itoa(i), &i}
+			appendValue(vt)
+			want = append(want, vt)
+		}
+		if !DeepEqual(got, want) {
+			t.Errorf("value mismatch:\ngot  %v\nwant %v", got, want)
+		}
+	})
+
+	t.Run("Rate", func(t *testing.T) {
+		var b []byte
+		v := ValueOf(new([]byte)).Elem()
+		for i := 0; i < 10; i++ {
+			b = append(b[:cap(b)], make([]byte, 1)...)
+			v.SetLen(v.Cap())
+			v.Grow(1)
+			if v.Cap() != cap(b) {
+				t.Errorf("v.Cap = %v, want %v", v.Cap(), cap(b))
+			}
+		}
+	})
+
+	t.Run("ZeroCapacity", func(t *testing.T) {
+		for i := 0; i < 10; i++ {
+			v := ValueOf(new([]byte)).Elem()
+			v.Grow(61)
+			b := v.Bytes()
+			b = b[:cap(b)]
+			for i, c := range b {
+				if c != 0 {
+					t.Fatalf("Value.Bytes[%d] = 0x%02x, want 0x00", i, c)
+				}
+				b[i] = 0xff
+			}
+			runtime.GC()
+		}
+	})
+}
+
 var appendTests = []struct {
 	orig, extra []int
 }{
+	{nil, nil},
+	{[]int{}, nil},
+	{nil, []int{}},
+	{[]int{}, []int{}},
+	{nil, []int{22}},
+	{[]int{}, []int{22}},
+	{make([]int, 2, 4), nil},
+	{make([]int, 2, 4), []int{}},
 	{make([]int, 2, 4), []int{22}},
 	{make([]int, 2, 4), []int{22, 33, 44}},
 }
 
-func sameInts(x, y []int) bool {
-	if len(x) != len(y) {
-		return false
-	}
-	for i, xx := range x {
-		if xx != y[i] {
-			return false
-		}
-	}
-	return true
-}
-
 func TestAppend(t *testing.T) {
 	for i, test := range appendTests {
 		origLen, extraLen := len(test.orig), len(test.extra)
@@ -766,32 +832,51 @@
 		}
 		// Convert extra from []int to *SliceValue.
 		e1 := ValueOf(test.extra)
+
 		// Test Append.
-		a0 := ValueOf(test.orig)
-		have0 := Append(a0, e0...).Interface().([]int)
-		if !sameInts(have0, want) {
-			t.Errorf("Append #%d: have %v, want %v (%p %p)", i, have0, want, test.orig, have0)
+		a0 := ValueOf(&test.orig).Elem()
+		have0 := Append(a0, e0...)
+		if have0.CanAddr() {
+			t.Errorf("Append #%d: have slice should not be addressable", i)
+		}
+		if !DeepEqual(have0.Interface(), want) {
+			t.Errorf("Append #%d: have %v, want %v (%p %p)", i, have0, want, test.orig, have0.Interface())
 		}
 		// Check that the orig and extra slices were not modified.
+		if a0.Len() != len(test.orig) {
+			t.Errorf("Append #%d: a0.Len: have %d, want %d", i, a0.Len(), origLen)
+		}
 		if len(test.orig) != origLen {
 			t.Errorf("Append #%d origLen: have %v, want %v", i, len(test.orig), origLen)
 		}
 		if len(test.extra) != extraLen {
 			t.Errorf("Append #%d extraLen: have %v, want %v", i, len(test.extra), extraLen)
 		}
+
 		// Test AppendSlice.
-		a1 := ValueOf(test.orig)
-		have1 := AppendSlice(a1, e1).Interface().([]int)
-		if !sameInts(have1, want) {
+		a1 := ValueOf(&test.orig).Elem()
+		have1 := AppendSlice(a1, e1)
+		if have1.CanAddr() {
+			t.Errorf("AppendSlice #%d: have slice should not be addressable", i)
+		}
+		if !DeepEqual(have1.Interface(), want) {
 			t.Errorf("AppendSlice #%d: have %v, want %v", i, have1, want)
 		}
 		// Check that the orig and extra slices were not modified.
+		if a1.Len() != len(test.orig) {
+			t.Errorf("AppendSlice #%d: a1.Len: have %d, want %d", i, a0.Len(), origLen)
+		}
 		if len(test.orig) != origLen {
 			t.Errorf("AppendSlice #%d origLen: have %v, want %v", i, len(test.orig), origLen)
 		}
 		if len(test.extra) != extraLen {
 			t.Errorf("AppendSlice #%d extraLen: have %v, want %v", i, len(test.extra), extraLen)
 		}
+
+		// Test Append and AppendSlice with unexported value.
+		ax := ValueOf(struct{ x []int }{test.orig}).Field(0)
+		shouldPanic("using unexported field", func() { Append(ax, e0...) })
+		shouldPanic("using unexported field", func() { AppendSlice(ax, e1) })
 	}
 }
 
@@ -1199,17 +1284,6 @@
 	}
 }
 
-func BenchmarkDeepEqual(b *testing.B) {
-	for _, bb := range deepEqualPerfTests {
-		b.Run(ValueOf(bb.x).Type().String(), func(b *testing.B) {
-			b.ReportAllocs()
-			for i := 0; i < b.N; i++ {
-				sink = DeepEqual(bb.x, bb.y)
-			}
-		})
-	}
-}
-
 func check2ndField(x any, offs uintptr, t *testing.T) {
 	s := ValueOf(x)
 	f := s.Type().Field(1)
@@ -1364,9 +1438,16 @@
 		{uintptr(128), false},
 		// Array
 		{Zero(TypeOf([5]string{})).Interface(), true},
-		{[5]string{"", "", "", "", ""}, true},
-		{[5]string{}, true},
-		{[5]string{"", "", "", "a", ""}, false},
+		{[5]string{}, true},                     // comparable array
+		{[5]string{"", "", "", "a", ""}, false}, // comparable array
+		{[1]*int{}, true},                       // direct pointer array
+		{[1]*int{new(int)}, false},              // direct pointer array
+		{[3][]int{}, true},                      // incomparable array
+		{[3][]int{{1}}, false},                  // incomparable array
+		{[1 << 12]byte{}, true},
+		{[1 << 12]byte{1}, false},
+		{[3]Value{}, true},
+		{[3]Value{{}, ValueOf(0), {}}, false},
 		// Chan
 		{(chan string)(nil), true},
 		{make(chan string), false},
@@ -1393,8 +1474,14 @@
 		{"", true},
 		{"not-zero", false},
 		// Structs
-		{T{}, true},
-		{T{123, 456.75, "hello", &_i}, false},
+		{T{}, true},                           // comparable struct
+		{T{123, 456.75, "hello", &_i}, false}, // comparable struct
+		{struct{ p *int }{}, true},            // direct pointer struct
+		{struct{ p *int }{new(int)}, false},   // direct pointer struct
+		{struct{ s []int }{}, true},           // incomparable struct
+		{struct{ s []int }{[]int{1}}, false},  // incomparable struct
+		{struct{ Value }{}, true},
+		{struct{ Value }{ValueOf(0)}, false},
 		// UnsafePointer
 		{(unsafe.Pointer)(nil), true},
 		{(unsafe.Pointer)(new(int)), false},
@@ -1414,6 +1501,13 @@
 		if !Zero(TypeOf(tt.x)).IsZero() {
 			t.Errorf("%d: IsZero(Zero(TypeOf((%s)(%+v)))) is false", i, x.Kind(), tt.x)
 		}
+
+		p := New(x.Type()).Elem()
+		p.Set(x)
+		p.SetZero()
+		if !p.IsZero() {
+			t.Errorf("%d: IsZero((%s)(%+v)) is true after SetZero", i, p.Kind(), tt.x)
+		}
 	}
 
 	func() {
@@ -1876,11 +1970,9 @@
 				recvStr = fmt.Sprintf(", received %v, %v", recv.Interface(), recvOK)
 			}
 			t.Fatalf("%s\nselected #%d incorrectly%s", fmtSelect(info), i, recvStr)
-			continue
 		}
 		if cas.panic {
 			t.Fatalf("%s\nselected #%d incorrectly (case should panic)", fmtSelect(info), i)
-			continue
 		}
 
 		if cases[i].Dir == SelectRecv {
@@ -1941,26 +2033,6 @@
 	}
 }
 
-func BenchmarkSelect(b *testing.B) {
-	channel := make(chan int)
-	close(channel)
-	var cases []SelectCase
-	for i := 0; i < 8; i++ {
-		cases = append(cases, SelectCase{
-			Dir:  SelectRecv,
-			Chan: ValueOf(channel),
-		})
-	}
-	for _, numCases := range []int{1, 4, 8} {
-		b.Run(strconv.Itoa(numCases), func(b *testing.B) {
-			b.ReportAllocs()
-			for i := 0; i < b.N; i++ {
-				_, _, _ = Select(cases[:numCases])
-			}
-		})
-	}
-}
-
 // selectWatch and the selectWatcher are a watchdog mechanism for running Select.
 // If the selectWatcher notices that the select has been blocked for >1 second, it prints
 // an error describing the select and panics the entire test binary.
@@ -2006,7 +2078,7 @@
 
 // fmtSelect formats the information about a single select test.
 func fmtSelect(info []caseInfo) string {
-	var buf bytes.Buffer
+	var buf strings.Builder
 	fmt.Fprintf(&buf, "\nselect {\n")
 	for i, cas := range info {
 		fmt.Fprintf(&buf, "%d: %s", i, cas.desc)
@@ -2139,63 +2211,6 @@
 	runtime.KeepAlive(v)
 }
 
-func BenchmarkCall(b *testing.B) {
-	fv := ValueOf(func(a, b string) {})
-	b.ReportAllocs()
-	b.RunParallel(func(pb *testing.PB) {
-		args := []Value{ValueOf("a"), ValueOf("b")}
-		for pb.Next() {
-			fv.Call(args)
-		}
-	})
-}
-
-type myint int64
-
-func (i *myint) inc() {
-	*i = *i + 1
-}
-
-func BenchmarkCallMethod(b *testing.B) {
-	b.ReportAllocs()
-	z := new(myint)
-
-	v := ValueOf(z.inc)
-	for i := 0; i < b.N; i++ {
-		v.Call(nil)
-	}
-}
-
-func BenchmarkCallArgCopy(b *testing.B) {
-	byteArray := func(n int) Value {
-		return Zero(ArrayOf(n, TypeOf(byte(0))))
-	}
-	sizes := [...]struct {
-		fv  Value
-		arg Value
-	}{
-		{ValueOf(func(a [128]byte) {}), byteArray(128)},
-		{ValueOf(func(a [256]byte) {}), byteArray(256)},
-		{ValueOf(func(a [1024]byte) {}), byteArray(1024)},
-		{ValueOf(func(a [4096]byte) {}), byteArray(4096)},
-		{ValueOf(func(a [65536]byte) {}), byteArray(65536)},
-	}
-	for _, size := range sizes {
-		bench := func(b *testing.B) {
-			args := []Value{size.arg}
-			b.SetBytes(int64(size.arg.Len()))
-			b.ResetTimer()
-			b.RunParallel(func(pb *testing.PB) {
-				for pb.Next() {
-					size.fv.Call(args)
-				}
-			})
-		}
-		name := fmt.Sprintf("size=%v", size.arg.Len())
-		b.Run(name, bench)
-	}
-}
-
 func TestMakeFunc(t *testing.T) {
 	f := dummy
 	fv := MakeFunc(TypeOf(f), func(in []Value) []Value { return in })
@@ -2452,6 +2467,16 @@
 		t.Errorf("NoArgs returned %d values; want 0", n)
 	}
 
+	_, ok = TypeOf(&p).MethodByName("AA")
+	if ok {
+		t.Errorf(`MethodByName("AA") should have failed`)
+	}
+
+	_, ok = TypeOf(&p).MethodByName("ZZ")
+	if ok {
+		t.Errorf(`MethodByName("ZZ") should have failed`)
+	}
+
 	// Curried method of value.
 	tfunc := TypeOf((func(int) int)(nil))
 	v := ValueOf(p).Method(1)
@@ -3359,28 +3384,6 @@
 	}
 }
 
-func BenchmarkPtrTo(b *testing.B) {
-	// Construct a type with a zero ptrToThis.
-	type T struct{ int }
-	t := SliceOf(TypeOf(T{}))
-	ptrToThis := ValueOf(t).Elem().FieldByName("ptrToThis")
-	if !ptrToThis.IsValid() {
-		b.Fatalf("%v has no ptrToThis field; was it removed from rtype?", t)
-	}
-	if ptrToThis.Int() != 0 {
-		b.Fatalf("%v.ptrToThis unexpectedly nonzero", t)
-	}
-	b.ResetTimer()
-
-	// Now benchmark calling PointerTo on it: we'll have to hit the ptrMap cache on
-	// every call.
-	b.RunParallel(func(pb *testing.PB) {
-		for pb.Next() {
-			PointerTo(t)
-		}
-	})
-}
-
 func TestAddr(t *testing.T) {
 	var p struct {
 		X, Y int
@@ -3626,7 +3629,7 @@
 }
 
 func TestVariadic(t *testing.T) {
-	var b bytes.Buffer
+	var b strings.Builder
 	V := ValueOf
 
 	b.Reset()
@@ -4413,6 +4416,25 @@
 	{V(MyString("runes♝")), V(MyRunes("runes♝"))},
 	{V(MyRunes("runes♕")), V(MyString("runes♕"))},
 
+	// slice to array
+	{V([]byte(nil)), V([0]byte{})},
+	{V([]byte{}), V([0]byte{})},
+	{V([]byte{1}), V([1]byte{1})},
+	{V([]byte{1, 2}), V([2]byte{1, 2})},
+	{V([]byte{1, 2, 3}), V([3]byte{1, 2, 3})},
+	{V(MyBytes([]byte(nil))), V([0]byte{})},
+	{V(MyBytes{}), V([0]byte{})},
+	{V(MyBytes{1}), V([1]byte{1})},
+	{V(MyBytes{1, 2}), V([2]byte{1, 2})},
+	{V(MyBytes{1, 2, 3}), V([3]byte{1, 2, 3})},
+	{V([]byte(nil)), V(MyBytesArray0{})},
+	{V([]byte{}), V(MyBytesArray0([0]byte{}))},
+	{V([]byte{1, 2, 3, 4}), V(MyBytesArray([4]byte{1, 2, 3, 4}))},
+	{V(MyBytes{}), V(MyBytesArray0([0]byte{}))},
+	{V(MyBytes{5, 6, 7, 8}), V(MyBytesArray([4]byte{5, 6, 7, 8}))},
+	{V([]MyByte{}), V([0]MyByte{})},
+	{V([]MyByte{1, 2}), V([2]MyByte{1, 2})},
+
 	// slice to array pointer
 	{V([]byte(nil)), V((*[0]byte)(nil))},
 	{V([]byte{}), V(new([0]byte))},
@@ -4489,6 +4511,8 @@
 	// cannot convert mismatched array sizes
 	{V([2]byte{}), V([2]byte{})},
 	{V([3]byte{}), V([3]byte{})},
+	{V(MyBytesArray0{}), V([0]byte{})},
+	{V([0]byte{}), V(MyBytesArray0{})},
 
 	// cannot convert other instances
 	{V((**byte)(nil)), V((**byte)(nil))},
@@ -4664,6 +4688,34 @@
 	shouldPanic("reflect: cannot convert slice with length 4 to pointer to array with length 8", func() {
 		_ = v.Convert(pt)
 	})
+
+	if v.CanConvert(pt.Elem()) {
+		t.Errorf("slice with length 4 should not be convertible to [8]byte")
+	}
+	shouldPanic("reflect: cannot convert slice with length 4 to array with length 8", func() {
+		_ = v.Convert(pt.Elem())
+	})
+}
+
+func TestConvertSlice2Array(t *testing.T) {
+	s := make([]int, 4)
+	p := [4]int{}
+	pt := TypeOf(p)
+	ov := ValueOf(s)
+	v := ov.Convert(pt)
+	// Converting a slice to non-empty array needs to return
+	// a non-addressable copy of the original memory.
+	if v.CanAddr() {
+		t.Fatalf("convert slice to non-empty array returns a addressable copy array")
+	}
+	for i := range s {
+		ov.Index(i).Set(ValueOf(i + 1))
+	}
+	for i := range s {
+		if v.Index(i).Int() != 0 {
+			t.Fatalf("slice (%v) mutation visible in converted result (%v)", ov, v)
+		}
+	}
 }
 
 var gFloat32 float32
@@ -6230,30 +6282,13 @@
 	FuncOf([]Type{TypeOf(1), TypeOf(""), SliceOf(TypeOf(false))}, nil, true)
 	shouldPanic("must be slice", func() { FuncOf([]Type{TypeOf(0), TypeOf(""), TypeOf(false)}, nil, true) })
 	shouldPanic("must be slice", func() { FuncOf(nil, nil, true) })
-}
 
-type B1 struct {
-	X int
-	Y int
-	Z int
-}
-
-func BenchmarkFieldByName1(b *testing.B) {
-	t := TypeOf(B1{})
-	b.RunParallel(func(pb *testing.PB) {
-		for pb.Next() {
-			t.FieldByName("Z")
-		}
-	})
-}
-
-func BenchmarkFieldByName2(b *testing.B) {
-	t := TypeOf(S3{})
-	b.RunParallel(func(pb *testing.PB) {
-		for pb.Next() {
-			t.FieldByName("B")
-		}
-	})
+	//testcase for  #54669
+	var in []Type
+	for i := 0; i < 51; i++ {
+		in = append(in, TypeOf(1))
+	}
+	FuncOf(in, nil, false)
 }
 
 type R0 struct {
@@ -6334,30 +6369,6 @@
 	}
 }
 
-func BenchmarkFieldByName3(b *testing.B) {
-	t := TypeOf(R0{})
-	b.RunParallel(func(pb *testing.PB) {
-		for pb.Next() {
-			t.FieldByName("X")
-		}
-	})
-}
-
-type S struct {
-	i1 int64
-	i2 int64
-}
-
-func BenchmarkInterfaceBig(b *testing.B) {
-	v := ValueOf(S{})
-	b.RunParallel(func(pb *testing.PB) {
-		for pb.Next() {
-			v.Interface()
-		}
-	})
-	b.StopTimer()
-}
-
 func TestAllocsInterfaceBig(t *testing.T) {
 	if testing.Short() {
 		t.Skip("skipping malloc count in short mode")
@@ -6368,15 +6379,6 @@
 	}
 }
 
-func BenchmarkInterfaceSmall(b *testing.B) {
-	v := ValueOf(int64(0))
-	b.RunParallel(func(pb *testing.PB) {
-		for pb.Next() {
-			v.Interface()
-		}
-	})
-}
-
 func TestAllocsInterfaceSmall(t *testing.T) {
 	if testing.Short() {
 		t.Skip("skipping malloc count in short mode")
@@ -6989,8 +6991,21 @@
 	}
 }
 
+// trimBitmap removes trailing 0 elements from b and returns the result.
+func trimBitmap(b []byte) []byte {
+	for len(b) > 0 && b[len(b)-1] == 0 {
+		b = b[:len(b)-1]
+	}
+	return b
+}
+
 func verifyGCBits(t *testing.T, typ Type, bits []byte) {
 	heapBits := GCBits(New(typ).Interface())
+
+	// Trim scalars at the end, as bits might end in zero,
+	// e.g. with rep(2, lit(1, 0)).
+	bits = trimBitmap(bits)
+
 	if !bytes.Equal(heapBits, bits) {
 		_, _, line, _ := runtime.Caller(1)
 		t.Errorf("line %d: heapBits incorrect for %v\nhave %v\nwant %v", line, typ, heapBits, bits)
@@ -7007,12 +7022,10 @@
 	heapBits := GCBits(data.Interface())
 	// Repeat the bitmap for the slice size, trimming scalars in
 	// the last element.
-	bits = rep(cap, bits)
-	for len(bits) > 0 && bits[len(bits)-1] == 0 {
-		bits = bits[:len(bits)-1]
-	}
+	bits = trimBitmap(rep(cap, bits))
 	if !bytes.Equal(heapBits, bits) {
-		t.Errorf("heapBits incorrect for make(%v, 0, %v)\nhave %v\nwant %v", typ, cap, heapBits, bits)
+		_, _, line, _ := runtime.Caller(1)
+		t.Errorf("line %d: heapBits incorrect for make(%v, 0, %v)\nhave %v\nwant %v", line, typ, cap, heapBits, bits)
 	}
 }
 
@@ -7384,70 +7397,6 @@
 	wg.Wait()
 }
 
-func BenchmarkNew(b *testing.B) {
-	v := TypeOf(XM{})
-	b.RunParallel(func(pb *testing.PB) {
-		for pb.Next() {
-			New(v)
-		}
-	})
-}
-
-func BenchmarkMap(b *testing.B) {
-	type V *int
-	type S string
-	value := ValueOf((V)(nil))
-	stringKeys := []string{}
-	mapOfStrings := map[string]V{}
-	uint64Keys := []uint64{}
-	mapOfUint64s := map[uint64]V{}
-	userStringKeys := []S{}
-	mapOfUserStrings := map[S]V{}
-	for i := 0; i < 100; i++ {
-		stringKey := fmt.Sprintf("key%d", i)
-		stringKeys = append(stringKeys, stringKey)
-		mapOfStrings[stringKey] = nil
-
-		uint64Key := uint64(i)
-		uint64Keys = append(uint64Keys, uint64Key)
-		mapOfUint64s[uint64Key] = nil
-
-		userStringKey := S(fmt.Sprintf("key%d", i))
-		userStringKeys = append(userStringKeys, userStringKey)
-		mapOfUserStrings[userStringKey] = nil
-	}
-
-	tests := []struct {
-		label          string
-		m, keys, value Value
-	}{
-		{"StringKeys", ValueOf(mapOfStrings), ValueOf(stringKeys), value},
-		{"Uint64Keys", ValueOf(mapOfUint64s), ValueOf(uint64Keys), value},
-		{"UserStringKeys", ValueOf(mapOfUserStrings), ValueOf(userStringKeys), value},
-	}
-
-	for _, tt := range tests {
-		b.Run(tt.label, func(b *testing.B) {
-			b.Run("MapIndex", func(b *testing.B) {
-				b.ReportAllocs()
-				for i := 0; i < b.N; i++ {
-					for j := tt.keys.Len() - 1; j >= 0; j-- {
-						tt.m.MapIndex(tt.keys.Index(j))
-					}
-				}
-			})
-			b.Run("SetMapIndex", func(b *testing.B) {
-				b.ReportAllocs()
-				for i := 0; i < b.N; i++ {
-					for j := tt.keys.Len() - 1; j >= 0; j-- {
-						tt.m.SetMapIndex(tt.keys.Index(j), tt.value)
-					}
-				}
-			})
-		})
-	}
-}
-
 func TestSwapper(t *testing.T) {
 	type I int
 	var a, b, c I
@@ -7761,16 +7710,6 @@
 	}
 }
 
-func BenchmarkMapIterNext(b *testing.B) {
-	m := ValueOf(map[string]int{"a": 0, "b": 1, "c": 2, "d": 3})
-	it := m.MapRange()
-	for i := 0; i < b.N; i++ {
-		for it.Next() {
-		}
-		it.Reset(m)
-	}
-}
-
 func TestMapIterDelete0(t *testing.T) {
 	// Delete all elements before first iteration.
 	m := map[string]int{"one": 1, "two": 2, "three": 3}
@@ -7904,28 +7843,17 @@
 	if got := *y.Interface().(*int); got != b {
 		t.Errorf("pointer incorrect: got %d want %d", got, b)
 	}
-}
 
-//go:notinheap
-type nih struct{ x int }
-
-var global_nih = nih{x: 7}
-
-func TestNotInHeapDeref(t *testing.T) {
-	// See issue 48399.
-	v := ValueOf((*nih)(nil))
-	v.Elem()
-	shouldPanic("reflect: call of reflect.Value.Field on zero Value", func() { v.Elem().Field(0) })
-
-	v = ValueOf(&global_nih)
-	if got := v.Elem().Field(0).Int(); got != 7 {
-		t.Fatalf("got %d, want 7", got)
+	// Make sure we panic assigning from an unexported field.
+	m = ValueOf(struct{ m map[string]int }{data}).Field(0)
+	for iter := m.MapRange(); iter.Next(); {
+		shouldPanic("using value obtained using unexported field", func() {
+			k.SetIterKey(iter)
+		})
+		shouldPanic("using value obtained using unexported field", func() {
+			v.SetIterValue(iter)
+		})
 	}
-
-	v = ValueOf((*nih)(unsafe.Pointer(new(int))))
-	shouldPanic("reflect: reflect.Value.Elem on an invalid notinheap pointer", func() { v.Elem() })
-	shouldPanic("reflect: reflect.Value.Pointer on an invalid notinheap pointer", func() { v.Pointer() })
-	shouldPanic("reflect: reflect.Value.UnsafePointer on an invalid notinheap pointer", func() { v.UnsafePointer() })
 }
 
 func TestMethodCallValueCodePtr(t *testing.T) {
@@ -7967,91 +7895,6 @@
 	namedBytes []byte
 )
 
-var sourceAll = struct {
-	Bool         Value
-	String       Value
-	Bytes        Value
-	NamedBytes   Value
-	BytesArray   Value
-	SliceAny     Value
-	MapStringAny Value
-}{
-	Bool:         ValueOf(new(bool)).Elem(),
-	String:       ValueOf(new(string)).Elem(),
-	Bytes:        ValueOf(new([]byte)).Elem(),
-	NamedBytes:   ValueOf(new(namedBytes)).Elem(),
-	BytesArray:   ValueOf(new([32]byte)).Elem(),
-	SliceAny:     ValueOf(new([]any)).Elem(),
-	MapStringAny: ValueOf(new(map[string]any)).Elem(),
-}
-
-var sinkAll struct {
-	RawBool   bool
-	RawString string
-	RawBytes  []byte
-	RawInt    int
-}
-
-func BenchmarkBool(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		sinkAll.RawBool = sourceAll.Bool.Bool()
-	}
-}
-
-func BenchmarkString(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		sinkAll.RawString = sourceAll.String.String()
-	}
-}
-
-func BenchmarkBytes(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		sinkAll.RawBytes = sourceAll.Bytes.Bytes()
-	}
-}
-
-func BenchmarkNamedBytes(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		sinkAll.RawBytes = sourceAll.NamedBytes.Bytes()
-	}
-}
-
-func BenchmarkBytesArray(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		sinkAll.RawBytes = sourceAll.BytesArray.Bytes()
-	}
-}
-
-func BenchmarkSliceLen(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		sinkAll.RawInt = sourceAll.SliceAny.Len()
-	}
-}
-
-func BenchmarkMapLen(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		sinkAll.RawInt = sourceAll.MapStringAny.Len()
-	}
-}
-
-func BenchmarkStringLen(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		sinkAll.RawInt = sourceAll.String.Len()
-	}
-}
-
-func BenchmarkArrayLen(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		sinkAll.RawInt = sourceAll.BytesArray.Len()
-	}
-}
-
-func BenchmarkSliceCap(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		sinkAll.RawInt = sourceAll.SliceAny.Cap()
-	}
-}
-
 func TestValue_Cap(t *testing.T) {
 	a := &[3]int{1, 2, 3}
 	v := ValueOf(a)
@@ -8117,3 +7960,403 @@
 		t.Errorf("error is %q, want %q", e, wantStr)
 	}
 }
+
+func TestValue_Comparable(t *testing.T) {
+	var a int
+	var s []int
+	var i interface{} = a
+	var iSlice interface{} = s
+	var iArrayFalse interface{} = [2]interface{}{1, map[int]int{}}
+	var iArrayTrue interface{} = [2]interface{}{1, struct{ I interface{} }{1}}
+	var testcases = []struct {
+		value      Value
+		comparable bool
+		deref      bool
+	}{
+		{
+			ValueOf(32),
+			true,
+			false,
+		},
+		{
+			ValueOf(int8(1)),
+			true,
+			false,
+		},
+		{
+			ValueOf(int16(1)),
+			true,
+			false,
+		},
+		{
+			ValueOf(int32(1)),
+			true,
+			false,
+		},
+		{
+			ValueOf(int64(1)),
+			true,
+			false,
+		},
+		{
+			ValueOf(uint8(1)),
+			true,
+			false,
+		},
+		{
+			ValueOf(uint16(1)),
+			true,
+			false,
+		},
+		{
+			ValueOf(uint32(1)),
+			true,
+			false,
+		},
+		{
+			ValueOf(uint64(1)),
+			true,
+			false,
+		},
+		{
+			ValueOf(float32(1)),
+			true,
+			false,
+		},
+		{
+			ValueOf(float64(1)),
+			true,
+			false,
+		},
+		{
+			ValueOf(complex(float32(1), float32(1))),
+			true,
+			false,
+		},
+		{
+			ValueOf(complex(float64(1), float64(1))),
+			true,
+			false,
+		},
+		{
+			ValueOf("abc"),
+			true,
+			false,
+		},
+		{
+			ValueOf(true),
+			true,
+			false,
+		},
+		{
+			ValueOf(map[int]int{}),
+			false,
+			false,
+		},
+		{
+			ValueOf([]int{}),
+			false,
+			false,
+		},
+		{
+			Value{},
+			false,
+			false,
+		},
+		{
+			ValueOf(&a),
+			true,
+			false,
+		},
+		{
+			ValueOf(&s),
+			true,
+			false,
+		},
+		{
+			ValueOf(&i),
+			true,
+			true,
+		},
+		{
+			ValueOf(&iSlice),
+			false,
+			true,
+		},
+		{
+			ValueOf([2]int{}),
+			true,
+			false,
+		},
+		{
+			ValueOf([2]map[int]int{}),
+			false,
+			false,
+		},
+		{
+			ValueOf([0]func(){}),
+			false,
+			false,
+		},
+		{
+			ValueOf([2]struct{ I interface{} }{{1}, {1}}),
+			true,
+			false,
+		},
+		{
+			ValueOf([2]struct{ I interface{} }{{[]int{}}, {1}}),
+			false,
+			false,
+		},
+		{
+			ValueOf([2]interface{}{1, struct{ I int }{1}}),
+			true,
+			false,
+		},
+		{
+			ValueOf([2]interface{}{[1]interface{}{map[int]int{}}, struct{ I int }{1}}),
+			false,
+			false,
+		},
+		{
+			ValueOf(&iArrayFalse),
+			false,
+			true,
+		},
+		{
+			ValueOf(&iArrayTrue),
+			true,
+			true,
+		},
+	}
+
+	for _, cas := range testcases {
+		v := cas.value
+		if cas.deref {
+			v = v.Elem()
+		}
+		got := v.Comparable()
+		if got != cas.comparable {
+			t.Errorf("%T.Comparable = %t, want %t", v, got, cas.comparable)
+		}
+	}
+}
+
+type ValueEqualTest struct {
+	v, u           any
+	eq             bool
+	vDeref, uDeref bool
+}
+
+var equalI interface{} = 1
+var equalSlice interface{} = []int{1}
+var nilInterface interface{}
+var mapInterface interface{} = map[int]int{}
+
+var valueEqualTests = []ValueEqualTest{
+	{
+		Value{}, Value{},
+		true,
+		false, false,
+	},
+	{
+		true, true,
+		true,
+		false, false,
+	},
+	{
+		1, 1,
+		true,
+		false, false,
+	},
+	{
+		int8(1), int8(1),
+		true,
+		false, false,
+	},
+	{
+		int16(1), int16(1),
+		true,
+		false, false,
+	},
+	{
+		int32(1), int32(1),
+		true,
+		false, false,
+	},
+	{
+		int64(1), int64(1),
+		true,
+		false, false,
+	},
+	{
+		uint(1), uint(1),
+		true,
+		false, false,
+	},
+	{
+		uint8(1), uint8(1),
+		true,
+		false, false,
+	},
+	{
+		uint16(1), uint16(1),
+		true,
+		false, false,
+	},
+	{
+		uint32(1), uint32(1),
+		true,
+		false, false,
+	},
+	{
+		uint64(1), uint64(1),
+		true,
+		false, false,
+	},
+	{
+		float32(1), float32(1),
+		true,
+		false, false,
+	},
+	{
+		float64(1), float64(1),
+		true,
+		false, false,
+	},
+	{
+		complex(1, 1), complex(1, 1),
+		true,
+		false, false,
+	},
+	{
+		complex128(1 + 1i), complex128(1 + 1i),
+		true,
+		false, false,
+	},
+	{
+		func() {}, nil,
+		false,
+		false, false,
+	},
+	{
+		&equalI, 1,
+		true,
+		true, false,
+	},
+	{
+		(chan int)(nil), nil,
+		false,
+		false, false,
+	},
+	{
+		(chan int)(nil), (chan int)(nil),
+		true,
+		false, false,
+	},
+	{
+		&equalI, &equalI,
+		true,
+		false, false,
+	},
+	{
+		struct{ i int }{1}, struct{ i int }{1},
+		true,
+		false, false,
+	},
+	{
+		struct{ i int }{1}, struct{ i int }{2},
+		false,
+		false, false,
+	},
+	{
+		&nilInterface, &nilInterface,
+		true,
+		true, true,
+	},
+	{
+		1, ValueOf(struct{ i int }{1}).Field(0),
+		true,
+		false, false,
+	},
+}
+
+func TestValue_Equal(t *testing.T) {
+	for _, test := range valueEqualTests {
+		var v, u Value
+		if vv, ok := test.v.(Value); ok {
+			v = vv
+		} else {
+			v = ValueOf(test.v)
+		}
+
+		if uu, ok := test.u.(Value); ok {
+			u = uu
+		} else {
+			u = ValueOf(test.u)
+		}
+		if test.vDeref {
+			v = v.Elem()
+		}
+
+		if test.uDeref {
+			u = u.Elem()
+		}
+
+		if r := v.Equal(u); r != test.eq {
+			t.Errorf("%s == %s got %t, want %t", v.Type(), u.Type(), r, test.eq)
+		}
+	}
+}
+
+func TestValue_EqualNonComparable(t *testing.T) {
+	var invalid = Value{} // ValueOf(nil)
+	var values = []Value{
+		// Value of slice is non-comparable.
+		ValueOf([]int(nil)),
+		ValueOf(([]int{})),
+
+		// Value of map is non-comparable.
+		ValueOf(map[int]int(nil)),
+		ValueOf((map[int]int{})),
+
+		// Value of func is non-comparable.
+		ValueOf(((func())(nil))),
+		ValueOf(func() {}),
+
+		// Value of struct is non-comparable because of non-comparable elements.
+		ValueOf((NonComparableStruct{})),
+
+		// Value of array is non-comparable because of non-comparable elements.
+		ValueOf([0]map[int]int{}),
+		ValueOf([0]func(){}),
+		ValueOf(([1]struct{ I interface{} }{{[]int{}}})),
+		ValueOf(([1]interface{}{[1]interface{}{map[int]int{}}})),
+	}
+	for _, value := range values {
+		// Panic when reflect.Value.Equal using two valid non-comparable values.
+		shouldPanic("are not comparable", func() { value.Equal(value) })
+
+		// If one is non-comparable and the other is invalid, the expected result is always false.
+		if r := value.Equal(invalid); r != false {
+			t.Errorf("%s == invalid got %t, want false", value.Type(), r)
+		}
+	}
+}
+
+func TestInitFuncTypes(t *testing.T) {
+	n := 100
+	var wg sync.WaitGroup
+
+	wg.Add(n)
+	for i := 0; i < n; i++ {
+		go func() {
+			defer wg.Done()
+			ipT := TypeOf(net.IP{})
+			for i := 0; i < ipT.NumMethod(); i++ {
+				_ = ipT.Method(i)
+			}
+		}()
+	}
+	wg.Wait()
+}
diff --git a/src/reflect/arena.go b/src/reflect/arena.go
new file mode 100644
index 0000000..694a3a1
--- /dev/null
+++ b/src/reflect/arena.go
@@ -0,0 +1,18 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build goexperiment.arenas
+
+package reflect
+
+import "arena"
+
+// ArenaNew returns a Value representing a pointer to a new zero value for the
+// specified type, allocating storage for it in the provided arena. That is,
+// the returned Value's Type is PointerTo(typ).
+func ArenaNew(a *arena.Arena, typ Type) Value {
+	return ValueOf(arena_New(a, typ))
+}
+
+func arena_New(a *arena.Arena, typ any) any
diff --git a/src/reflect/benchmark_test.go b/src/reflect/benchmark_test.go
new file mode 100644
index 0000000..51634ab
--- /dev/null
+++ b/src/reflect/benchmark_test.go
@@ -0,0 +1,397 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package reflect_test
+
+import (
+	"fmt"
+	. "reflect"
+	"strconv"
+	"testing"
+)
+
+var sourceAll = struct {
+	Bool         Value
+	String       Value
+	Bytes        Value
+	NamedBytes   Value
+	BytesArray   Value
+	SliceAny     Value
+	MapStringAny Value
+}{
+	Bool:         ValueOf(new(bool)).Elem(),
+	String:       ValueOf(new(string)).Elem(),
+	Bytes:        ValueOf(new([]byte)).Elem(),
+	NamedBytes:   ValueOf(new(namedBytes)).Elem(),
+	BytesArray:   ValueOf(new([32]byte)).Elem(),
+	SliceAny:     ValueOf(new([]any)).Elem(),
+	MapStringAny: ValueOf(new(map[string]any)).Elem(),
+}
+
+var sinkAll struct {
+	RawBool   bool
+	RawString string
+	RawBytes  []byte
+	RawInt    int
+}
+
+func BenchmarkBool(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		sinkAll.RawBool = sourceAll.Bool.Bool()
+	}
+}
+
+func BenchmarkString(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		sinkAll.RawString = sourceAll.String.String()
+	}
+}
+
+func BenchmarkBytes(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		sinkAll.RawBytes = sourceAll.Bytes.Bytes()
+	}
+}
+
+func BenchmarkNamedBytes(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		sinkAll.RawBytes = sourceAll.NamedBytes.Bytes()
+	}
+}
+
+func BenchmarkBytesArray(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		sinkAll.RawBytes = sourceAll.BytesArray.Bytes()
+	}
+}
+
+func BenchmarkSliceLen(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		sinkAll.RawInt = sourceAll.SliceAny.Len()
+	}
+}
+
+func BenchmarkMapLen(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		sinkAll.RawInt = sourceAll.MapStringAny.Len()
+	}
+}
+
+func BenchmarkStringLen(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		sinkAll.RawInt = sourceAll.String.Len()
+	}
+}
+
+func BenchmarkArrayLen(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		sinkAll.RawInt = sourceAll.BytesArray.Len()
+	}
+}
+
+func BenchmarkSliceCap(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		sinkAll.RawInt = sourceAll.SliceAny.Cap()
+	}
+}
+
+func BenchmarkDeepEqual(b *testing.B) {
+	for _, bb := range deepEqualPerfTests {
+		b.Run(ValueOf(bb.x).Type().String(), func(b *testing.B) {
+			b.ReportAllocs()
+			for i := 0; i < b.N; i++ {
+				sink = DeepEqual(bb.x, bb.y)
+			}
+		})
+	}
+}
+
+func BenchmarkIsZero(b *testing.B) {
+	source := ValueOf(struct {
+		ArrayComparable    [4]T
+		ArrayIncomparable  [4]_Complex
+		StructComparable   T
+		StructIncomparable _Complex
+	}{})
+
+	for i := 0; i < source.NumField(); i++ {
+		name := source.Type().Field(i).Name
+		value := source.Field(i)
+		b.Run(name, func(b *testing.B) {
+			for i := 0; i < b.N; i++ {
+				sink = value.IsZero()
+			}
+		})
+	}
+}
+
+func BenchmarkSetZero(b *testing.B) {
+	source := ValueOf(new(struct {
+		Bool      bool
+		Int       int64
+		Uint      uint64
+		Float     float64
+		Complex   complex128
+		Array     [4]Value
+		Chan      chan Value
+		Func      func() Value
+		Interface interface{ String() string }
+		Map       map[string]Value
+		Pointer   *Value
+		Slice     []Value
+		String    string
+		Struct    Value
+	})).Elem()
+
+	for i := 0; i < source.NumField(); i++ {
+		name := source.Type().Field(i).Name
+		value := source.Field(i)
+		zero := Zero(value.Type())
+		b.Run(name+"/Direct", func(b *testing.B) {
+			for i := 0; i < b.N; i++ {
+				value.SetZero()
+			}
+		})
+		b.Run(name+"/CachedZero", func(b *testing.B) {
+			for i := 0; i < b.N; i++ {
+				value.Set(zero)
+			}
+		})
+		b.Run(name+"/NewZero", func(b *testing.B) {
+			for i := 0; i < b.N; i++ {
+				value.Set(Zero(value.Type()))
+			}
+		})
+	}
+}
+
+func BenchmarkSelect(b *testing.B) {
+	channel := make(chan int)
+	close(channel)
+	var cases []SelectCase
+	for i := 0; i < 8; i++ {
+		cases = append(cases, SelectCase{
+			Dir:  SelectRecv,
+			Chan: ValueOf(channel),
+		})
+	}
+	for _, numCases := range []int{1, 4, 8} {
+		b.Run(strconv.Itoa(numCases), func(b *testing.B) {
+			b.ReportAllocs()
+			for i := 0; i < b.N; i++ {
+				_, _, _ = Select(cases[:numCases])
+			}
+		})
+	}
+}
+
+func BenchmarkCall(b *testing.B) {
+	fv := ValueOf(func(a, b string) {})
+	b.ReportAllocs()
+	b.RunParallel(func(pb *testing.PB) {
+		args := []Value{ValueOf("a"), ValueOf("b")}
+		for pb.Next() {
+			fv.Call(args)
+		}
+	})
+}
+
+type myint int64
+
+func (i *myint) inc() {
+	*i = *i + 1
+}
+
+func BenchmarkCallMethod(b *testing.B) {
+	b.ReportAllocs()
+	z := new(myint)
+
+	v := ValueOf(z.inc)
+	for i := 0; i < b.N; i++ {
+		v.Call(nil)
+	}
+}
+
+func BenchmarkCallArgCopy(b *testing.B) {
+	byteArray := func(n int) Value {
+		return Zero(ArrayOf(n, TypeOf(byte(0))))
+	}
+	sizes := [...]struct {
+		fv  Value
+		arg Value
+	}{
+		{ValueOf(func(a [128]byte) {}), byteArray(128)},
+		{ValueOf(func(a [256]byte) {}), byteArray(256)},
+		{ValueOf(func(a [1024]byte) {}), byteArray(1024)},
+		{ValueOf(func(a [4096]byte) {}), byteArray(4096)},
+		{ValueOf(func(a [65536]byte) {}), byteArray(65536)},
+	}
+	for _, size := range sizes {
+		bench := func(b *testing.B) {
+			args := []Value{size.arg}
+			b.SetBytes(int64(size.arg.Len()))
+			b.ResetTimer()
+			b.RunParallel(func(pb *testing.PB) {
+				for pb.Next() {
+					size.fv.Call(args)
+				}
+			})
+		}
+		name := fmt.Sprintf("size=%v", size.arg.Len())
+		b.Run(name, bench)
+	}
+}
+
+func BenchmarkPtrTo(b *testing.B) {
+	// Construct a type with a zero ptrToThis.
+	type T struct{ int }
+	t := SliceOf(TypeOf(T{}))
+	ptrToThis := ValueOf(t).Elem().FieldByName("ptrToThis")
+	if !ptrToThis.IsValid() {
+		b.Fatalf("%v has no ptrToThis field; was it removed from rtype?", t)
+	}
+	if ptrToThis.Int() != 0 {
+		b.Fatalf("%v.ptrToThis unexpectedly nonzero", t)
+	}
+	b.ResetTimer()
+
+	// Now benchmark calling PointerTo on it: we'll have to hit the ptrMap cache on
+	// every call.
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			PointerTo(t)
+		}
+	})
+}
+
+type B1 struct {
+	X int
+	Y int
+	Z int
+}
+
+func BenchmarkFieldByName1(b *testing.B) {
+	t := TypeOf(B1{})
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			t.FieldByName("Z")
+		}
+	})
+}
+
+func BenchmarkFieldByName2(b *testing.B) {
+	t := TypeOf(S3{})
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			t.FieldByName("B")
+		}
+	})
+}
+
+func BenchmarkFieldByName3(b *testing.B) {
+	t := TypeOf(R0{})
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			t.FieldByName("X")
+		}
+	})
+}
+
+type S struct {
+	i1 int64
+	i2 int64
+}
+
+func BenchmarkInterfaceBig(b *testing.B) {
+	v := ValueOf(S{})
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			v.Interface()
+		}
+	})
+	b.StopTimer()
+}
+
+func BenchmarkInterfaceSmall(b *testing.B) {
+	v := ValueOf(int64(0))
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			v.Interface()
+		}
+	})
+}
+
+func BenchmarkNew(b *testing.B) {
+	v := TypeOf(XM{})
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			New(v)
+		}
+	})
+}
+
+func BenchmarkMap(b *testing.B) {
+	type V *int
+	type S string
+	value := ValueOf((V)(nil))
+	stringKeys := []string{}
+	mapOfStrings := map[string]V{}
+	uint64Keys := []uint64{}
+	mapOfUint64s := map[uint64]V{}
+	userStringKeys := []S{}
+	mapOfUserStrings := map[S]V{}
+	for i := 0; i < 100; i++ {
+		stringKey := fmt.Sprintf("key%d", i)
+		stringKeys = append(stringKeys, stringKey)
+		mapOfStrings[stringKey] = nil
+
+		uint64Key := uint64(i)
+		uint64Keys = append(uint64Keys, uint64Key)
+		mapOfUint64s[uint64Key] = nil
+
+		userStringKey := S(fmt.Sprintf("key%d", i))
+		userStringKeys = append(userStringKeys, userStringKey)
+		mapOfUserStrings[userStringKey] = nil
+	}
+
+	tests := []struct {
+		label          string
+		m, keys, value Value
+	}{
+		{"StringKeys", ValueOf(mapOfStrings), ValueOf(stringKeys), value},
+		{"Uint64Keys", ValueOf(mapOfUint64s), ValueOf(uint64Keys), value},
+		{"UserStringKeys", ValueOf(mapOfUserStrings), ValueOf(userStringKeys), value},
+	}
+
+	for _, tt := range tests {
+		b.Run(tt.label, func(b *testing.B) {
+			b.Run("MapIndex", func(b *testing.B) {
+				b.ReportAllocs()
+				for i := 0; i < b.N; i++ {
+					for j := tt.keys.Len() - 1; j >= 0; j-- {
+						tt.m.MapIndex(tt.keys.Index(j))
+					}
+				}
+			})
+			b.Run("SetMapIndex", func(b *testing.B) {
+				b.ReportAllocs()
+				for i := 0; i < b.N; i++ {
+					for j := tt.keys.Len() - 1; j >= 0; j-- {
+						tt.m.SetMapIndex(tt.keys.Index(j), tt.value)
+					}
+				}
+			})
+		})
+	}
+}
+
+func BenchmarkMapIterNext(b *testing.B) {
+	m := ValueOf(map[string]int{"a": 0, "b": 1, "c": 2, "d": 3})
+	it := m.MapRange()
+	for i := 0; i < b.N; i++ {
+		for it.Next() {
+		}
+		it.Reset(m)
+	}
+}
diff --git a/src/reflect/deepequal.go b/src/reflect/deepequal.go
index 50b436e..c898bc8 100644
--- a/src/reflect/deepequal.go
+++ b/src/reflect/deepequal.go
@@ -40,9 +40,9 @@
 		switch v1.Kind() {
 		case Pointer:
 			if v1.typ.ptrdata == 0 {
-				// go:notinheap pointers can't be cyclic.
-				// At least, all of our current uses of go:notinheap have
-				// that property. The runtime ones aren't cyclic (and we don't use
+				// not-in-heap pointers can't be cyclic.
+				// At least, all of our current uses of runtime/internal/sys.NotInHeap
+				// have that property. The runtime ones aren't cyclic (and we don't use
 				// DeepEqual on them anyway), and the cgo-generated ones are
 				// all empty structs.
 				return false
diff --git a/src/reflect/internal/example1/example.go b/src/reflect/internal/example1/example.go
index 0f829a8..181dd99 100644
--- a/src/reflect/internal/example1/example.go
+++ b/src/reflect/internal/example1/example.go
@@ -1,3 +1,7 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
 package example1
 
 type MyStruct struct {
diff --git a/src/reflect/internal/example2/example.go b/src/reflect/internal/example2/example.go
index df64ba1..8a55826 100644
--- a/src/reflect/internal/example2/example.go
+++ b/src/reflect/internal/example2/example.go
@@ -1,3 +1,7 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
 package example2
 
 type MyStruct struct {
diff --git a/src/reflect/nih_test.go b/src/reflect/nih_test.go
new file mode 100644
index 0000000..f503939
--- /dev/null
+++ b/src/reflect/nih_test.go
@@ -0,0 +1,38 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build cgo
+
+package reflect_test
+
+import (
+	. "reflect"
+	"runtime/cgo"
+	"testing"
+	"unsafe"
+)
+
+type nih struct {
+	_ cgo.Incomplete
+	x int
+}
+
+var global_nih = nih{x: 7}
+
+func TestNotInHeapDeref(t *testing.T) {
+	// See issue 48399.
+	v := ValueOf((*nih)(nil))
+	v.Elem()
+	shouldPanic("reflect: call of reflect.Value.Field on zero Value", func() { v.Elem().Field(0) })
+
+	v = ValueOf(&global_nih)
+	if got := v.Elem().Field(1).Int(); got != 7 {
+		t.Fatalf("got %d, want 7", got)
+	}
+
+	v = ValueOf((*nih)(unsafe.Pointer(new(int))))
+	shouldPanic("reflect: reflect.Value.Elem on an invalid notinheap pointer", func() { v.Elem() })
+	shouldPanic("reflect: reflect.Value.Pointer on an invalid notinheap pointer", func() { v.Pointer() })
+	shouldPanic("reflect: reflect.Value.UnsafePointer on an invalid notinheap pointer", func() { v.UnsafePointer() })
+}
diff --git a/src/reflect/set_test.go b/src/reflect/set_test.go
index 9ce0e09..028c051 100644
--- a/src/reflect/set_test.go
+++ b/src/reflect/set_test.go
@@ -10,6 +10,7 @@
 	"go/token"
 	"io"
 	. "reflect"
+	"strings"
 	"testing"
 	"unsafe"
 )
@@ -141,7 +142,7 @@
 func TestImplicitCallConversion(t *testing.T) {
 	// Arguments must be assignable to parameter types.
 	fv := ValueOf(io.WriteString)
-	b := new(bytes.Buffer)
+	b := new(strings.Builder)
 	fv.Call([]Value{ValueOf(b), ValueOf("hello world")})
 	if b.String() != "hello world" {
 		t.Errorf("After call: string=%q want %q", b.String(), "hello world")
diff --git a/src/reflect/type.go b/src/reflect/type.go
index a52d312..01d1456 100644
--- a/src/reflect/type.go
+++ b/src/reflect/type.go
@@ -17,7 +17,6 @@
 
 import (
 	"internal/goarch"
-	"internal/unsafeheader"
 	"strconv"
 	"sync"
 	"unicode"
@@ -525,27 +524,21 @@
 	}
 }
 
-func (n name) name() (s string) {
+func (n name) name() string {
 	if n.bytes == nil {
-		return
+		return ""
 	}
 	i, l := n.readVarint(1)
-	hdr := (*unsafeheader.String)(unsafe.Pointer(&s))
-	hdr.Data = unsafe.Pointer(n.data(1+i, "non-empty string"))
-	hdr.Len = l
-	return
+	return unsafe.String(n.data(1+i, "non-empty string"), l)
 }
 
-func (n name) tag() (s string) {
+func (n name) tag() string {
 	if !n.hasTag() {
 		return ""
 	}
 	i, l := n.readVarint(1)
 	i2, l2 := n.readVarint(1 + i + l)
-	hdr := (*unsafeheader.String)(unsafe.Pointer(&s))
-	hdr.Data = unsafe.Pointer(n.data(1+i+l+i2, "non-empty string"))
-	hdr.Len = l2
-	return
+	return unsafe.String(n.data(1+i+l+i2, "non-empty string"), l2)
 }
 
 func (n name) pkgPath() string {
@@ -892,12 +885,26 @@
 	if ut == nil {
 		return Method{}, false
 	}
-	// TODO(mdempsky): Binary search.
-	for i, p := range ut.exportedMethods() {
-		if t.nameOff(p.name).name() == name {
-			return t.Method(i), true
+
+	methods := ut.exportedMethods()
+
+	// We are looking for the first index i where the string becomes >= s.
+	// This is a copy of sort.Search, with f(h) replaced by (t.nameOff(methods[h].name).name() >= name).
+	i, j := 0, len(methods)
+	for i < j {
+		h := int(uint(i+j) >> 1) // avoid overflow when computing h
+		// i ≤ h < j
+		if !(t.nameOff(methods[h].name).name() >= name) {
+			i = h + 1 // preserves f(i-1) == false
+		} else {
+			j = h // preserves f(j) == true
 		}
 	}
+	// i == j, f(i-1) == false, and f(j) (= f(i)) == true  =>  answer is i.
+	if i < len(methods) && name == t.nameOff(methods[i].name).name() {
+		return t.Method(i), true
+	}
+
 	return Method{}, false
 }
 
@@ -1433,6 +1440,12 @@
 	return toType(eface.typ)
 }
 
+// rtypeOf directly extracts the *rtype of the provided value.
+func rtypeOf(i any) *rtype {
+	eface := *(*emptyInterface)(unsafe.Pointer(&i))
+	return eface.typ
+}
+
 // ptrMap is the cache for PointerTo.
 var ptrMap sync.Map // map[*rtype]*ptrType
 
@@ -1979,31 +1992,32 @@
 	return ti.(Type)
 }
 
-// TODO(crawshaw): as these funcTypeFixedN structs have no methods,
-// they could be defined at runtime using the StructOf function.
-type funcTypeFixed4 struct {
-	funcType
-	args [4]*rtype
-}
-type funcTypeFixed8 struct {
-	funcType
-	args [8]*rtype
-}
-type funcTypeFixed16 struct {
-	funcType
-	args [16]*rtype
-}
-type funcTypeFixed32 struct {
-	funcType
-	args [32]*rtype
-}
-type funcTypeFixed64 struct {
-	funcType
-	args [64]*rtype
-}
-type funcTypeFixed128 struct {
-	funcType
-	args [128]*rtype
+var funcTypes []Type
+var funcTypesMutex sync.Mutex
+
+func initFuncTypes(n int) Type {
+	funcTypesMutex.Lock()
+	defer funcTypesMutex.Unlock()
+	if n >= len(funcTypes) {
+		newFuncTypes := make([]Type, n+1)
+		copy(newFuncTypes, funcTypes)
+		funcTypes = newFuncTypes
+	}
+	if funcTypes[n] != nil {
+		return funcTypes[n]
+	}
+
+	funcTypes[n] = StructOf([]StructField{
+		{
+			Name: "FuncType",
+			Type: TypeOf(funcType{}),
+		},
+		{
+			Name: "Args",
+			Type: ArrayOf(n, TypeOf(&rtype{})),
+		},
+	})
+	return funcTypes[n]
 }
 
 // FuncOf returns the function type with the given argument and result types.
@@ -2023,36 +2037,13 @@
 	prototype := *(**funcType)(unsafe.Pointer(&ifunc))
 	n := len(in) + len(out)
 
-	var ft *funcType
-	var args []*rtype
-	switch {
-	case n <= 4:
-		fixed := new(funcTypeFixed4)
-		args = fixed.args[:0:len(fixed.args)]
-		ft = &fixed.funcType
-	case n <= 8:
-		fixed := new(funcTypeFixed8)
-		args = fixed.args[:0:len(fixed.args)]
-		ft = &fixed.funcType
-	case n <= 16:
-		fixed := new(funcTypeFixed16)
-		args = fixed.args[:0:len(fixed.args)]
-		ft = &fixed.funcType
-	case n <= 32:
-		fixed := new(funcTypeFixed32)
-		args = fixed.args[:0:len(fixed.args)]
-		ft = &fixed.funcType
-	case n <= 64:
-		fixed := new(funcTypeFixed64)
-		args = fixed.args[:0:len(fixed.args)]
-		ft = &fixed.funcType
-	case n <= 128:
-		fixed := new(funcTypeFixed128)
-		args = fixed.args[:0:len(fixed.args)]
-		ft = &fixed.funcType
-	default:
+	if n > 128 {
 		panic("reflect.FuncOf: too many arguments")
 	}
+
+	o := New(initFuncTypes(n)).Elem()
+	ft := (*funcType)(unsafe.Pointer(o.Field(0).Addr().Pointer()))
+	args := unsafe.Slice((**rtype)(unsafe.Pointer(o.Field(1).Addr().Pointer())), n)[0:0:n]
 	*ft = *prototype
 
 	// Build a hash and minimally populate ft.
@@ -2071,9 +2062,7 @@
 		args = append(args, t)
 		hash = fnv1(hash, byte(t.hash>>24), byte(t.hash>>16), byte(t.hash>>8), byte(t.hash))
 	}
-	if len(args) > 50 {
-		panic("reflect.FuncOf does not support more than 50 arguments")
-	}
+
 	ft.tflag = 0
 	ft.hash = hash
 	ft.inCount = uint16(len(in))
@@ -2265,7 +2254,10 @@
 
 	if ktyp.ptrdata != 0 || etyp.ptrdata != 0 {
 		nptr := (bucketSize*(1+ktyp.size+etyp.size) + goarch.PtrSize) / goarch.PtrSize
-		mask := make([]byte, (nptr+7)/8)
+		n := (nptr + 7) / 8
+		// Runtime needs pointer masks to be a multiple of uintptr in size.
+		n = (n + goarch.PtrSize - 1) &^ (goarch.PtrSize - 1)
+		mask := make([]byte, n)
 		base := bucketSize / goarch.PtrSize
 
 		if ktyp.ptrdata != 0 {
@@ -2971,7 +2963,10 @@
 		// Element is small with pointer mask; array is still small.
 		// Create direct pointer mask by turning each 1 bit in elem
 		// into length 1 bits in larger mask.
-		mask := make([]byte, (array.ptrdata/goarch.PtrSize+7)/8)
+		n := (array.ptrdata/goarch.PtrSize + 7) / 8
+		// Runtime needs pointer masks to be a multiple of uintptr in size.
+		n = (n + goarch.PtrSize - 1) &^ (goarch.PtrSize - 1)
+		mask := make([]byte, n)
 		emitGCMask(mask, 0, typ, array.len)
 		array.gcdata = &mask[0]
 
@@ -3140,8 +3135,13 @@
 
 // append a bit to the bitmap.
 func (bv *bitVector) append(bit uint8) {
-	if bv.n%8 == 0 {
-		bv.data = append(bv.data, 0)
+	if bv.n%(8*goarch.PtrSize) == 0 {
+		// Runtime needs pointer masks to be a multiple of uintptr in size.
+		// Since reflect passes bv.data directly to the runtime as a pointer mask,
+		// we append a full uintptr of zeros at a time.
+		for i := 0; i < goarch.PtrSize; i++ {
+			bv.data = append(bv.data, 0)
+		}
 	}
 	bv.data[bv.n/8] |= bit << (bv.n % 8)
 	bv.n++
diff --git a/src/reflect/value.go b/src/reflect/value.go
index 74554a3..42bb5ea 100644
--- a/src/reflect/value.go
+++ b/src/reflect/value.go
@@ -45,17 +45,19 @@
 	ptr unsafe.Pointer
 
 	// flag holds metadata about the value.
-	// The lowest bits are flag bits:
+	//
+	// The lowest five bits give the Kind of the value, mirroring typ.Kind().
+	//
+	// The next set of bits are flag bits:
 	//	- flagStickyRO: obtained via unexported not embedded field, so read-only
 	//	- flagEmbedRO: obtained via unexported embedded field, so read-only
 	//	- flagIndir: val holds a pointer to the data
-	//	- flagAddr: v.CanAddr is true (implies flagIndir)
+	//	- flagAddr: v.CanAddr is true (implies flagIndir and ptr is non-nil)
 	//	- flagMethod: v is a method value.
-	// The next five bits give the Kind of the value.
-	// This repeats typ.Kind() except for method values.
-	// The remaining 23+ bits give a method number for method values.
-	// If flag.kind() != Func, code can assume that flagMethod is unset.
 	// If ifaceIndir(typ), code can assume that flagIndir is set.
+	//
+	// The remaining 22+ bits give a method number for method values.
+	// If flag.kind() != Func, code can assume that flagMethod is unset.
 	flag
 
 	// A method value represents a curried method invocation
@@ -92,7 +94,7 @@
 
 // pointer returns the underlying pointer represented by v.
 // v.Kind() must be Pointer, Map, Chan, Func, or UnsafePointer
-// if v.Kind() == Pointer, the base type must not be go:notinheap.
+// if v.Kind() == Pointer, the base type must not be not-in-heap.
 func (v Value) pointer() unsafe.Pointer {
 	if v.typ.size != goarch.PtrSize || !v.typ.pointers() {
 		panic("can't call pointer on a non-pointer Value")
@@ -290,7 +292,7 @@
 	v.mustBe(Bool)
 }
 
-var bytesType = TypeOf(([]byte)(nil)).(*rtype)
+var bytesType = rtypeOf(([]byte)(nil))
 
 // Bytes returns v's underlying value.
 // It panics if v's underlying value is not a slice of bytes or
@@ -1381,7 +1383,7 @@
 	panic(&ValueError{"reflect.Value.Float", v.kind()})
 }
 
-var uint8Type = TypeOf(uint8(0)).(*rtype)
+var uint8Type = rtypeOf(uint8(0))
 
 // Index returns v's i'th element.
 // It panics if v's Kind is not Array, Slice, or String or i is out of range.
@@ -1579,7 +1581,16 @@
 		c := v.Complex()
 		return math.Float64bits(real(c)) == 0 && math.Float64bits(imag(c)) == 0
 	case Array:
-		for i := 0; i < v.Len(); i++ {
+		// If the type is comparable, then compare directly with zero.
+		if v.typ.equal != nil && v.typ.size <= maxZero {
+			if v.flag&flagIndir == 0 {
+				return v.ptr == nil
+			}
+			return v.typ.equal(v.ptr, unsafe.Pointer(&zeroVal[0]))
+		}
+
+		n := v.Len()
+		for i := 0; i < n; i++ {
 			if !v.Index(i).IsZero() {
 				return false
 			}
@@ -1590,19 +1601,82 @@
 	case String:
 		return v.Len() == 0
 	case Struct:
-		for i := 0; i < v.NumField(); i++ {
+		// If the type is comparable, then compare directly with zero.
+		if v.typ.equal != nil && v.typ.size <= maxZero {
+			if v.flag&flagIndir == 0 {
+				return v.ptr == nil
+			}
+			return v.typ.equal(v.ptr, unsafe.Pointer(&zeroVal[0]))
+		}
+
+		n := v.NumField()
+		for i := 0; i < n; i++ {
 			if !v.Field(i).IsZero() {
 				return false
 			}
 		}
 		return true
 	default:
-		// This should never happens, but will act as a safeguard for
-		// later, as a default value doesn't makes sense here.
+		// This should never happen, but will act as a safeguard for later,
+		// as a default value doesn't makes sense here.
 		panic(&ValueError{"reflect.Value.IsZero", v.Kind()})
 	}
 }
 
+// SetZero sets v to be the zero value of v's type.
+// It panics if CanSet returns false.
+func (v Value) SetZero() {
+	v.mustBeAssignable()
+	switch v.kind() {
+	case Bool:
+		*(*bool)(v.ptr) = false
+	case Int:
+		*(*int)(v.ptr) = 0
+	case Int8:
+		*(*int8)(v.ptr) = 0
+	case Int16:
+		*(*int16)(v.ptr) = 0
+	case Int32:
+		*(*int32)(v.ptr) = 0
+	case Int64:
+		*(*int64)(v.ptr) = 0
+	case Uint:
+		*(*uint)(v.ptr) = 0
+	case Uint8:
+		*(*uint8)(v.ptr) = 0
+	case Uint16:
+		*(*uint16)(v.ptr) = 0
+	case Uint32:
+		*(*uint32)(v.ptr) = 0
+	case Uint64:
+		*(*uint64)(v.ptr) = 0
+	case Uintptr:
+		*(*uintptr)(v.ptr) = 0
+	case Float32:
+		*(*float32)(v.ptr) = 0
+	case Float64:
+		*(*float64)(v.ptr) = 0
+	case Complex64:
+		*(*complex64)(v.ptr) = 0
+	case Complex128:
+		*(*complex128)(v.ptr) = 0
+	case String:
+		*(*string)(v.ptr) = ""
+	case Slice:
+		*(*unsafeheader.Slice)(v.ptr) = unsafeheader.Slice{}
+	case Interface:
+		*(*[2]unsafe.Pointer)(v.ptr) = [2]unsafe.Pointer{}
+	case Chan, Func, Map, Pointer, UnsafePointer:
+		*(*unsafe.Pointer)(v.ptr) = nil
+	case Array, Struct:
+		typedmemclr(v.typ, v.ptr)
+	default:
+		// This should never happen, but will act as a safeguard for later,
+		// as a default value doesn't makes sense here.
+		panic(&ValueError{"reflect.Value.SetZero", v.Kind()})
+	}
+}
+
 // Kind returns v's Kind.
 // If v is the zero Value (IsValid returns false), Kind returns Invalid.
 func (v Value) Kind() Kind {
@@ -1640,7 +1714,7 @@
 	panic(&ValueError{"reflect.Value.Len", v.kind()})
 }
 
-var stringType = TypeOf("").(*rtype)
+var stringType = rtypeOf("")
 
 // MapIndex returns the value associated with key in the map v.
 // It panics if v's Kind is not Map.
@@ -1765,7 +1839,8 @@
 
 // SetIterKey assigns to v the key of iter's current map entry.
 // It is equivalent to v.Set(iter.Key()), but it avoids allocating a new Value.
-// As in Go, the key must be assignable to v's type.
+// As in Go, the key must be assignable to v's type and
+// must not be derived from an unexported field.
 func (v Value) SetIterKey(iter *MapIter) {
 	if !iter.hiter.initialized() {
 		panic("reflect: Value.SetIterKey called before Next")
@@ -1784,6 +1859,7 @@
 	t := (*mapType)(unsafe.Pointer(iter.m.typ))
 	ktype := t.key
 
+	iter.m.mustBeExported() // do not let unexported m leak
 	key := Value{ktype, iterkey, iter.m.flag | flag(ktype.Kind()) | flagIndir}
 	key = key.assignTo("reflect.MapIter.SetKey", v.typ, target)
 	typedmemmove(v.typ, v.ptr, key.ptr)
@@ -1806,7 +1882,8 @@
 
 // SetIterValue assigns to v the value of iter's current map entry.
 // It is equivalent to v.Set(iter.Value()), but it avoids allocating a new Value.
-// As in Go, the value must be assignable to v's type.
+// As in Go, the value must be assignable to v's type and
+// must not be derived from an unexported field.
 func (v Value) SetIterValue(iter *MapIter) {
 	if !iter.hiter.initialized() {
 		panic("reflect: Value.SetIterValue called before Next")
@@ -1825,6 +1902,7 @@
 	t := (*mapType)(unsafe.Pointer(iter.m.typ))
 	vtype := t.elem
 
+	iter.m.mustBeExported() // do not let unexported m leak
 	elem := Value{vtype, iterelem, iter.m.flag | flag(vtype.Kind()) | flagIndir}
 	elem = elem.assignTo("reflect.MapIter.SetValue", v.typ, target)
 	typedmemmove(v.typ, v.ptr, elem.ptr)
@@ -2030,9 +2108,6 @@
 // and make an exception.
 
 // Pointer returns v's value as a uintptr.
-// It returns uintptr instead of unsafe.Pointer so that
-// code using reflect cannot obtain unsafe.Pointers
-// without importing the unsafe package explicitly.
 // It panics if v's Kind is not Chan, Func, Map, Pointer, Slice, or UnsafePointer.
 //
 // If v's Kind is Func, the returned pointer is an underlying
@@ -2080,7 +2155,7 @@
 		return uintptr(p)
 
 	case Slice:
-		return (*SliceHeader)(v.ptr).Data
+		return uintptr((*unsafeheader.Slice)(v.ptr).Data)
 	}
 	panic(&ValueError{"reflect.Value.Pointer", v.kind()})
 }
@@ -2149,7 +2224,8 @@
 
 // Set assigns x to the value v.
 // It panics if CanSet returns false.
-// As in Go, x's value must be assignable to v's type.
+// As in Go, x's value must be assignable to v's type and
+// must not be derived from an unexported field.
 func (v Value) Set(x Value) {
 	v.mustBeAssignable()
 	x.mustBeExported() // do not let unexported x leak
@@ -2347,7 +2423,7 @@
 	}
 }
 
-// SetPointer sets the unsafe.Pointer value v to x.
+// SetPointer sets the [unsafe.Pointer] value v to x.
 // It panics if v's Kind is not UnsafePointer.
 func (v Value) SetPointer(x unsafe.Pointer) {
 	v.mustBeAssignable()
@@ -2596,7 +2672,6 @@
 // and make an exception.
 
 // UnsafeAddr returns a pointer to v's data, as a uintptr.
-// It is for advanced clients that also import the "unsafe" package.
 // It panics if v is not addressable.
 //
 // It's preferred to use uintptr(Value.Addr().UnsafePointer()) to get the equivalent result.
@@ -2610,7 +2685,7 @@
 	return uintptr(v.ptr)
 }
 
-// UnsafePointer returns v's value as a unsafe.Pointer.
+// UnsafePointer returns v's value as a [unsafe.Pointer].
 // It panics if v's Kind is not Chan, Func, Map, Pointer, Slice, or UnsafePointer.
 //
 // If v's Kind is Func, the returned pointer is an underlying
@@ -2667,6 +2742,8 @@
 // Moreover, the Data field is not sufficient to guarantee the data
 // it references will not be garbage collected, so programs must keep
 // a separate, correctly typed pointer to the underlying data.
+//
+// In new code, use unsafe.String or unsafe.StringData instead.
 type StringHeader struct {
 	Data uintptr
 	Len  int
@@ -2678,6 +2755,8 @@
 // Moreover, the Data field is not sufficient to guarantee the data
 // it references will not be garbage collected, so programs must keep
 // a separate, correctly typed pointer to the underlying data.
+//
+// In new code, use unsafe.Slice or unsafe.SliceData instead.
 type SliceHeader struct {
 	Data uintptr
 	Len  int
@@ -2701,42 +2780,61 @@
 	return add(p, uintptr(i)*eltSize, "i < len")
 }
 
-// grow grows the slice s so that it can hold extra more values, allocating
-// more capacity if needed. It also returns the old and new slice lengths.
-func grow(s Value, extra int) (Value, int, int) {
-	i0 := s.Len()
-	i1 := i0 + extra
-	if i1 < i0 {
-		panic("reflect.Append: slice overflow")
+// Grow increases the slice's capacity, if necessary, to guarantee space for
+// another n elements. After Grow(n), at least n elements can be appended
+// to the slice without another allocation.
+//
+// It panics if v's Kind is not a Slice or if n is negative or too large to
+// allocate the memory.
+func (v Value) Grow(n int) {
+	v.mustBeAssignable()
+	v.mustBe(Slice)
+	v.grow(n)
+}
+
+// grow is identical to Grow but does not check for assignability.
+func (v Value) grow(n int) {
+	p := (*unsafeheader.Slice)(v.ptr)
+	switch {
+	case n < 0:
+		panic("reflect.Value.Grow: negative len")
+	case p.Len+n < 0:
+		panic("reflect.Value.Grow: slice overflow")
+	case p.Len+n > p.Cap:
+		t := v.typ.Elem().(*rtype)
+		*p = growslice(t, *p, n)
 	}
-	m := s.Cap()
-	if i1 <= m {
-		return s.Slice(0, i1), i0, i1
-	}
-	if m == 0 {
-		m = extra
-	} else {
-		const threshold = 256
-		for m < i1 {
-			if i0 < threshold {
-				m += m
-			} else {
-				m += (m + 3*threshold) / 4
-			}
-		}
-	}
-	t := MakeSlice(s.Type(), i1, m)
-	Copy(t, s)
-	return t, i0, i1
+}
+
+// extendSlice extends a slice by n elements.
+//
+// Unlike Value.grow, which modifies the slice in place and
+// does not change the length of the slice in place,
+// extendSlice returns a new slice value with the length
+// incremented by the number of specified elements.
+func (v Value) extendSlice(n int) Value {
+	v.mustBeExported()
+	v.mustBe(Slice)
+
+	// Shallow copy the slice header to avoid mutating the source slice.
+	sh := *(*unsafeheader.Slice)(v.ptr)
+	s := &sh
+	v.ptr = unsafe.Pointer(s)
+	v.flag = flagIndir | flag(Slice) // equivalent flag to MakeSlice
+
+	v.grow(n) // fine to treat as assignable since we allocate a new slice header
+	s.Len += n
+	return v
 }
 
 // Append appends the values x to a slice s and returns the resulting slice.
 // As in Go, each x's value must be assignable to the slice's element type.
 func Append(s Value, x ...Value) Value {
 	s.mustBe(Slice)
-	s, i0, i1 := grow(s, len(x))
-	for i, j := i0, 0; i < i1; i, j = i+1, j+1 {
-		s.Index(i).Set(x[j])
+	n := s.Len()
+	s = s.extendSlice(len(x))
+	for i, v := range x {
+		s.Index(n + i).Set(v)
 	}
 	return s
 }
@@ -2747,8 +2845,10 @@
 	s.mustBe(Slice)
 	t.mustBe(Slice)
 	typesMustMatch("reflect.AppendSlice", s.Type().Elem(), t.Type().Elem())
-	s, i0, i1 := grow(s, t.Len())
-	Copy(s.Slice(i0, i1), t)
+	ns := s.Len()
+	nt := t.Len()
+	s = s.extendSlice(nt)
+	Copy(s.Slice(ns, ns+nt), t)
 	return s
 }
 
@@ -3088,7 +3188,7 @@
 	t := typ.(*rtype)
 	pt := t.ptrTo()
 	if ifaceIndir(pt) {
-		// This is a pointer to a go:notinheap type.
+		// This is a pointer to a not-in-heap type.
 		panic("reflect: New of type that may not be allocated in heap (possibly undefined cgo C type)")
 	}
 	ptr := unsafe_New(t)
@@ -3166,10 +3266,14 @@
 	if !vt.ConvertibleTo(t) {
 		return false
 	}
-	// Currently the only conversion that is OK in terms of type
-	// but that can panic depending on the value is converting
-	// from slice to pointer-to-array.
-	if vt.Kind() == Slice && t.Kind() == Pointer && t.Elem().Kind() == Array {
+	// Converting from slice to array or to pointer-to-array can panic
+	// depending on the value.
+	switch {
+	case vt.Kind() == Slice && t.Kind() == Array:
+		if t.Len() > v.Len() {
+			return false
+		}
+	case vt.Kind() == Slice && t.Kind() == Pointer && t.Elem().Kind() == Array:
 		n := t.Elem().Len()
 		if n > v.Len() {
 			return false
@@ -3178,6 +3282,118 @@
 	return true
 }
 
+// Comparable reports whether the value v is comparable.
+// If the type of v is an interface, this checks the dynamic type.
+// If this reports true then v.Interface() == x will not panic for any x,
+// nor will v.Equal(u) for any Value u.
+func (v Value) Comparable() bool {
+	k := v.Kind()
+	switch k {
+	case Invalid:
+		return false
+
+	case Array:
+		switch v.Type().Elem().Kind() {
+		case Interface, Array, Struct:
+			for i := 0; i < v.Type().Len(); i++ {
+				if !v.Index(i).Comparable() {
+					return false
+				}
+			}
+			return true
+		}
+		return v.Type().Comparable()
+
+	case Interface:
+		return v.Elem().Comparable()
+
+	case Struct:
+		for i := 0; i < v.NumField(); i++ {
+			if !v.Field(i).Comparable() {
+				return false
+			}
+		}
+		return true
+
+	default:
+		return v.Type().Comparable()
+	}
+}
+
+// Equal reports true if v is equal to u.
+// For two invalid values, Equal will report true.
+// For an interface value, Equal will compare the value within the interface.
+// Otherwise, If the values have different types, Equal will report false.
+// Otherwise, for arrays and structs Equal will compare each element in order,
+// and report false if it finds non-equal elements.
+// During all comparisons, if values of the same type are compared,
+// and the type is not comparable, Equal will panic.
+func (v Value) Equal(u Value) bool {
+	if v.Kind() == Interface {
+		v = v.Elem()
+	}
+	if u.Kind() == Interface {
+		u = u.Elem()
+	}
+
+	if !v.IsValid() || !u.IsValid() {
+		return v.IsValid() == u.IsValid()
+	}
+
+	if v.Kind() != u.Kind() || v.Type() != u.Type() {
+		return false
+	}
+
+	// Handle each Kind directly rather than calling valueInterface
+	// to avoid allocating.
+	switch v.Kind() {
+	default:
+		panic("reflect.Value.Equal: invalid Kind")
+	case Bool:
+		return v.Bool() == u.Bool()
+	case Int, Int8, Int16, Int32, Int64:
+		return v.Int() == u.Int()
+	case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
+		return v.Uint() == u.Uint()
+	case Float32, Float64:
+		return v.Float() == u.Float()
+	case Complex64, Complex128:
+		return v.Complex() == u.Complex()
+	case String:
+		return v.String() == u.String()
+	case Chan, Pointer, UnsafePointer:
+		return v.Pointer() == u.Pointer()
+	case Array:
+		// u and v have the same type so they have the same length
+		vl := v.Len()
+		if vl == 0 {
+			// panic on [0]func()
+			if !v.Type().Elem().Comparable() {
+				break
+			}
+			return true
+		}
+		for i := 0; i < vl; i++ {
+			if !v.Index(i).Equal(u.Index(i)) {
+				return false
+			}
+		}
+		return true
+	case Struct:
+		// u and v have the same type so they have the same fields
+		nf := v.NumField()
+		for i := 0; i < nf; i++ {
+			if !v.Field(i).Equal(u.Field(i)) {
+				return false
+			}
+		}
+		return true
+	case Func, Map, Slice:
+		break
+	}
+	panic("reflect.Value.Equal: values of type " + v.Type().String() + " are not comparable")
+}
+
 // convertOp returns the function to convert a value of type src
 // to a value of type dst. If the conversion is illegal, convertOp returns nil.
 func convertOp(dst, src *rtype) func(Value, Type) Value {
@@ -3242,6 +3458,11 @@
 		if dst.Kind() == Pointer && dst.Elem().Kind() == Array && src.Elem() == dst.Elem().Elem() {
 			return cvtSliceArrayPtr
 		}
+		// "x is a slice, T is a array type,
+		// and the slice and array types have identical element types."
+		if dst.Kind() == Array && src.Elem() == dst.Elem() {
+			return cvtSliceArray
+		}
 
 	case Chan:
 		if dst.Kind() == Chan && specialChannelAssignability(dst, src) {
@@ -3303,7 +3524,7 @@
 	return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
 }
 
-// makeFloat returns a Value of type t equal to v, where t is a float32 type.
+// makeFloat32 returns a Value of type t equal to v, where t is a float32 type.
 func makeFloat32(f flag, v float32, t Type) Value {
 	typ := t.common()
 	ptr := unsafe_New(typ)
@@ -3445,6 +3666,22 @@
 	return Value{t.common(), h.Data, v.flag&^(flagIndir|flagAddr|flagKindMask) | flag(Pointer)}
 }
 
+// convertOp: []T -> [N]T
+func cvtSliceArray(v Value, t Type) Value {
+	n := t.Len()
+	if n > v.Len() {
+		panic("reflect: cannot convert slice with length " + itoa.Itoa(v.Len()) + " to array with length " + itoa.Itoa(n))
+	}
+	h := (*unsafeheader.Slice)(v.ptr)
+	typ := t.common()
+	ptr := h.Data
+	c := unsafe_New(typ)
+	typedmemmove(typ, c, ptr)
+	ptr = c
+
+	return Value{typ, ptr, v.flag&^(flagAddr|flagKindMask) | flag(Array)}
+}
+
 // convertOp: direct copy
 func cvtDirect(v Value, typ Type) Value {
 	f := v.flag
@@ -3605,6 +3842,9 @@
 
 func verifyNotInHeapPtr(p uintptr) bool
 
+//go:noescape
+func growslice(t *rtype, old unsafeheader.Slice, num int) unsafeheader.Slice
+
 // Dummy annotation marking that the value x escapes,
 // for use in cases where the reflect code is so clever that
 // the compiler cannot follow.
diff --git a/src/regexp/all_test.go b/src/regexp/all_test.go
index c233cfa..52de3fe 100644
--- a/src/regexp/all_test.go
+++ b/src/regexp/all_test.go
@@ -49,6 +49,7 @@
 	{`a**`, "invalid nested repetition operator: `**`"},
 	{`a*+`, "invalid nested repetition operator: `*+`"},
 	{`\x`, "invalid escape sequence: `\\x`"},
+	{strings.Repeat(`\pL`, 27000), "expression too large"},
 }
 
 func compileTest(t *testing.T, expr string, error string) *Regexp {
diff --git a/src/regexp/onepass.go b/src/regexp/onepass.go
index bc47f4c..b3066e8 100644
--- a/src/regexp/onepass.go
+++ b/src/regexp/onepass.go
@@ -33,11 +33,11 @@
 	Next []uint32
 }
 
-// OnePassPrefix returns a literal string that all matches for the
+// onePassPrefix returns a literal string that all matches for the
 // regexp must start with. Complete is true if the prefix
 // is the entire match. Pc is the index of the last rune instruction
-// in the string. The OnePassPrefix skips over the mandatory
-// EmptyBeginText
+// in the string. The onePassPrefix skips over the mandatory
+// EmptyBeginText.
 func onePassPrefix(p *syntax.Prog) (prefix string, complete bool, pc uint32) {
 	i := &p.Inst[p.Start]
 	if i.Op != syntax.InstEmptyWidth || (syntax.EmptyOp(i.Arg))&syntax.EmptyBeginText == 0 {
@@ -68,7 +68,7 @@
 	return buf.String(), complete, pc
 }
 
-// OnePassNext selects the next actionable state of the prog, based on the input character.
+// onePassNext selects the next actionable state of the prog, based on the input character.
 // It should only be called when i.Op == InstAlt or InstAltMatch, and from the one-pass machine.
 // One of the alternates may ultimately lead without input to end of line. If the instruction
 // is InstAltMatch the path to the InstMatch is in i.Out, the normal node in i.Next.
@@ -218,7 +218,7 @@
 	}
 }
 
-// onePassCopy creates a copy of the original Prog, as we'll be modifying it
+// onePassCopy creates a copy of the original Prog, as we'll be modifying it.
 func onePassCopy(prog *syntax.Prog) *onePassProg {
 	p := &onePassProg{
 		Start:  prog.Start,
diff --git a/src/regexp/regexp.go b/src/regexp/regexp.go
index 7958a39..990c06e 100644
--- a/src/regexp/regexp.go
+++ b/src/regexp/regexp.go
@@ -270,7 +270,7 @@
 	matchPool[re.mpool].Put(m)
 }
 
-// minInputLen walks the regexp to find the minimum length of any matchable input
+// minInputLen walks the regexp to find the minimum length of any matchable input.
 func minInputLen(re *syntax.Regexp) int {
 	switch re.Op {
 	default:
diff --git a/src/regexp/syntax/parse.go b/src/regexp/syntax/parse.go
index 350f297..accee9a 100644
--- a/src/regexp/syntax/parse.go
+++ b/src/regexp/syntax/parse.go
@@ -44,6 +44,7 @@
 	ErrTrailingBackslash     ErrorCode = "trailing backslash at end of expression"
 	ErrUnexpectedParen       ErrorCode = "unexpected )"
 	ErrNestingDepth          ErrorCode = "expression nests too deeply"
+	ErrLarge                 ErrorCode = "expression too large"
 )
 
 func (e ErrorCode) String() string {
@@ -91,15 +92,49 @@
 // until we've allocated at least maxHeight Regexp structures.
 const maxHeight = 1000
 
+// maxSize is the maximum size of a compiled regexp in Insts.
+// It too is somewhat arbitrarily chosen, but the idea is to be large enough
+// to allow significant regexps while at the same time small enough that
+// the compiled form will not take up too much memory.
+// 128 MB is enough for a 3.3 million Inst structures, which roughly
+// corresponds to a 3.3 MB regexp.
+const (
+	maxSize  = 128 << 20 / instSize
+	instSize = 5 * 8 // byte, 2 uint32, slice is 5 64-bit words
+)
+
+// maxRunes is the maximum number of runes allowed in a regexp tree
+// counting the runes in all the nodes.
+// Ignoring character classes p.numRunes is always less than the length of the regexp.
+// Character classes can make it much larger: each \pL adds 1292 runes.
+// 128 MB is enough for 32M runes, which is over 26k \pL instances.
+// Note that repetitions do not make copies of the rune slices,
+// so \pL{1000} is only one rune slice, not 1000.
+// We could keep a cache of character classes we've seen,
+// so that all the \pL we see use the same rune list,
+// but that doesn't remove the problem entirely:
+// consider something like [\pL01234][\pL01235][\pL01236]...[\pL^&*()].
+// And because the Rune slice is exposed directly in the Regexp,
+// there is not an opportunity to change the representation to allow
+// partial sharing between different character classes.
+// So the limit is the best we can do.
+const (
+	maxRunes = 128 << 20 / runeSize
+	runeSize = 4 // rune is int32
+)
+
 type parser struct {
 	flags       Flags     // parse mode flags
 	stack       []*Regexp // stack of parsed expressions
 	free        *Regexp
 	numCap      int // number of capturing groups seen
 	wholeRegexp string
-	tmpClass    []rune          // temporary char class work space
-	numRegexp   int             // number of regexps allocated
-	height      map[*Regexp]int // regexp height for height limit check
+	tmpClass    []rune            // temporary char class work space
+	numRegexp   int               // number of regexps allocated
+	numRunes    int               // number of runes in char classes
+	repeats     int64             // product of all repetitions seen
+	height      map[*Regexp]int   // regexp height, for height limit check
+	size        map[*Regexp]int64 // regexp compiled size, for size limit check
 }
 
 func (p *parser) newRegexp(op Op) *Regexp {
@@ -123,6 +158,104 @@
 	p.free = re
 }
 
+func (p *parser) checkLimits(re *Regexp) {
+	if p.numRunes > maxRunes {
+		panic(ErrLarge)
+	}
+	p.checkSize(re)
+	p.checkHeight(re)
+}
+
+func (p *parser) checkSize(re *Regexp) {
+	if p.size == nil {
+		// We haven't started tracking size yet.
+		// Do a relatively cheap check to see if we need to start.
+		// Maintain the product of all the repeats we've seen
+		// and don't track if the total number of regexp nodes
+		// we've seen times the repeat product is in budget.
+		if p.repeats == 0 {
+			p.repeats = 1
+		}
+		if re.Op == OpRepeat {
+			n := re.Max
+			if n == -1 {
+				n = re.Min
+			}
+			if n <= 0 {
+				n = 1
+			}
+			if int64(n) > maxSize/p.repeats {
+				p.repeats = maxSize
+			} else {
+				p.repeats *= int64(n)
+			}
+		}
+		if int64(p.numRegexp) < maxSize/p.repeats {
+			return
+		}
+
+		// We need to start tracking size.
+		// Make the map and belatedly populate it
+		// with info about everything we've constructed so far.
+		p.size = make(map[*Regexp]int64)
+		for _, re := range p.stack {
+			p.checkSize(re)
+		}
+	}
+
+	if p.calcSize(re, true) > maxSize {
+		panic(ErrLarge)
+	}
+}
+
+func (p *parser) calcSize(re *Regexp, force bool) int64 {
+	if !force {
+		if size, ok := p.size[re]; ok {
+			return size
+		}
+	}
+
+	var size int64
+	switch re.Op {
+	case OpLiteral:
+		size = int64(len(re.Rune))
+	case OpCapture, OpStar:
+		// star can be 1+ or 2+; assume 2 pessimistically
+		size = 2 + p.calcSize(re.Sub[0], false)
+	case OpPlus, OpQuest:
+		size = 1 + p.calcSize(re.Sub[0], false)
+	case OpConcat:
+		for _, sub := range re.Sub {
+			size += p.calcSize(sub, false)
+		}
+	case OpAlternate:
+		for _, sub := range re.Sub {
+			size += p.calcSize(sub, false)
+		}
+		if len(re.Sub) > 1 {
+			size += int64(len(re.Sub)) - 1
+		}
+	case OpRepeat:
+		sub := p.calcSize(re.Sub[0], false)
+		if re.Max == -1 {
+			if re.Min == 0 {
+				size = 2 + sub // x*
+			} else {
+				size = 1 + int64(re.Min)*sub // xxx+
+			}
+			break
+		}
+		// x{2,5} = xx(x(x(x)?)?)?
+		size = int64(re.Max)*sub + int64(re.Max-re.Min)
+	}
+
+	if size < 1 {
+		size = 1
+	}
+	p.size[re] = size
+	return size
+}
+
 func (p *parser) checkHeight(re *Regexp) {
 	if p.numRegexp < maxHeight {
 		return
@@ -159,6 +292,7 @@
 
 // push pushes the regexp re onto the parse stack and returns the regexp.
 func (p *parser) push(re *Regexp) *Regexp {
+	p.numRunes += len(re.Rune)
 	if re.Op == OpCharClass && len(re.Rune) == 2 && re.Rune[0] == re.Rune[1] {
 		// Single rune.
 		if p.maybeConcat(re.Rune[0], p.flags&^FoldCase) {
@@ -190,7 +324,7 @@
 	}
 
 	p.stack = append(p.stack, re)
-	p.checkHeight(re)
+	p.checkLimits(re)
 	return re
 }
 
@@ -300,7 +434,7 @@
 	re.Sub = re.Sub0[:1]
 	re.Sub[0] = sub
 	p.stack[n-1] = re
-	p.checkHeight(re)
+	p.checkLimits(re)
 
 	if op == OpRepeat && (min >= 2 || max >= 2) && !repeatIsValid(re, 1000) {
 		return "", &Error{ErrInvalidRepeatSize, before[:len(before)-len(after)]}
@@ -508,6 +642,7 @@
 
 			for j := start; j < i; j++ {
 				sub[j] = p.removeLeadingString(sub[j], len(str))
+				p.checkLimits(sub[j])
 			}
 			suffix := p.collapse(sub[start:i], OpAlternate) // recurse
 
@@ -565,6 +700,7 @@
 			for j := start; j < i; j++ {
 				reuse := j != start // prefix came from sub[start]
 				sub[j] = p.removeLeadingRegexp(sub[j], reuse)
+				p.checkLimits(sub[j])
 			}
 			suffix := p.collapse(sub[start:i], OpAlternate) // recurse
 
@@ -762,6 +898,8 @@
 			panic(r)
 		case nil:
 			// ok
+		case ErrLarge: // too big
+			err = &Error{Code: ErrLarge, Expr: s}
 		case ErrNestingDepth:
 			err = &Error{Code: ErrNestingDepth, Expr: s}
 		}
@@ -1800,7 +1938,7 @@
 	return r
 }
 
-// appendFolded returns the result of appending the case folding of the class x to the class r.
+// appendFoldedClass returns the result of appending the case folding of the class x to the class r.
 func appendFoldedClass(r []rune, x []rune) []rune {
 	for i := 0; i < len(x); i += 2 {
 		r = appendFoldedRange(r, x[i], x[i+1])
diff --git a/src/regexp/syntax/parse_test.go b/src/regexp/syntax/parse_test.go
index 1ef6d8a..67e3c56 100644
--- a/src/regexp/syntax/parse_test.go
+++ b/src/regexp/syntax/parse_test.go
@@ -484,12 +484,15 @@
 	`(?P<>a)`,
 	`[a-Z]`,
 	`(?i)[a-Z]`,
-	`a{100000}`,
-	`a{100000,}`,
-	"((((((((((x{2}){2}){2}){2}){2}){2}){2}){2}){2}){2})",
-	strings.Repeat("(", 1000) + strings.Repeat(")", 1000),
-	strings.Repeat("(?:", 1000) + strings.Repeat(")*", 1000),
 	`\Q\E*`,
+	`a{100000}`,  // too much repetition
+	`a{100000,}`, // too much repetition
+	"((((((((((x{2}){2}){2}){2}){2}){2}){2}){2}){2}){2})",    // too much repetition
+	strings.Repeat("(", 1000) + strings.Repeat(")", 1000),    // too deep
+	strings.Repeat("(?:", 1000) + strings.Repeat(")*", 1000), // too deep
+	"(" + strings.Repeat("(xx?)", 1000) + "){1000}",          // too long
+	strings.Repeat("(xx?){1000}", 1000),                      // too long
+	strings.Repeat(`\pL`, 27000),                             // too many runes
 }
 
 var onlyPerl = []string{
diff --git a/src/run.bash b/src/run.bash
index 99b09fc..35fa8f6 100755
--- a/src/run.bash
+++ b/src/run.bash
@@ -13,6 +13,15 @@
 # GO_BUILDER_NAME: the name of the Go builder that's running the tests.
 # Some tests are conditionally enabled or disabled based on the builder
 # name or the builder name being non-empty.
+#
+# GO_TEST_SHORT: if set to a non-empty, false-ish string, run tests in "-short=false" mode.
+# This environment variable is an internal implementation detail between the
+# Go build system (x/build) and cmd/dist for the purpose of longtest builders,
+# and will be removed if it stops being needed. See go.dev/issue/12508.
+#
+# GO_TEST_TIMEOUT_SCALE: a non-negative integer factor to scale test timeout by.
+# Defaults to 1, or as a special case for the purpose of the Go build system (x/build),
+# defaults to 2 when GOARCH is arm, and to 4 when GOARCH is mips, mipsle, mips64, or mips64le.
 
 set -e
 
@@ -21,6 +30,7 @@
 	exit 1
 fi
 
+export GOENV=off
 eval $(../bin/go tool dist env)
 export GOROOT   # The api test requires GOROOT to be set, so set it to match ../bin/go.
 
diff --git a/src/run.bat b/src/run.bat
index 74bf8a4..35c8ead 100644
--- a/src/run.bat
+++ b/src/run.bat
@@ -18,6 +18,7 @@
 

 set GOBUILDFAIL=0

 

+set GOENV=off

 ..\bin\go tool dist env > env.bat

 if errorlevel 1 goto fail

 call .\env.bat

diff --git a/src/run.rc b/src/run.rc
index 2a0bb7f..704290c 100755
--- a/src/run.rc
+++ b/src/run.rc
@@ -10,6 +10,7 @@
 	exit wrongdir
 }
 
+GOENV=off
 eval `{../bin/go tool dist env}
 
 GOPATH=/nonexist-gopath
diff --git a/src/runtime/HACKING.md b/src/runtime/HACKING.md
index 61b5a51..ce0b42a 100644
--- a/src/runtime/HACKING.md
+++ b/src/runtime/HACKING.md
@@ -235,7 +235,7 @@
   objects of the same type.
 
 In general, types that are allocated using any of these should be
-marked `//go:notinheap` (see below).
+marked as not in heap by embedding `runtime/internal/sys.NotInHeap`.
 
 Objects that are allocated in unmanaged memory **must not** contain
 heap pointers unless the following rules are also obeyed:
@@ -330,37 +330,3 @@
 The conversion from pointer to uintptr must appear in the argument list of any
 call to this function. This directive is used for some low-level system call
 implementations.
-
-go:notinheap
-------------
-
-`go:notinheap` applies to type declarations. It indicates that a type
-must never be allocated from the GC'd heap or on the stack.
-Specifically, pointers to this type must always fail the
-`runtime.inheap` check. The type may be used for global variables, or
-for objects in unmanaged memory (e.g., allocated with `sysAlloc`,
-`persistentalloc`, `fixalloc`, or from a manually-managed span).
-Specifically:
-
-1. `new(T)`, `make([]T)`, `append([]T, ...)` and implicit heap
-   allocation of T are disallowed. (Though implicit allocations are
-   disallowed in the runtime anyway.)
-
-2. A pointer to a regular type (other than `unsafe.Pointer`) cannot be
-   converted to a pointer to a `go:notinheap` type, even if they have
-   the same underlying type.
-
-3. Any type that contains a `go:notinheap` type is itself
-   `go:notinheap`. Structs and arrays are `go:notinheap` if their
-   elements are. Maps and channels of `go:notinheap` types are
-   disallowed. To keep things explicit, any type declaration where the
-   type is implicitly `go:notinheap` must be explicitly marked
-   `go:notinheap` as well.
-
-4. Write barriers on pointers to `go:notinheap` types can be omitted.
-
-The last point is the real benefit of `go:notinheap`. The runtime uses
-it for low-level internal structures to avoid memory barriers in the
-scheduler and the memory allocator where they are illegal or simply
-inefficient. This mechanism is reasonably safe and does not compromise
-the readability of the runtime.
diff --git a/src/runtime/align_runtime_test.go b/src/runtime/align_runtime_test.go
index ec7956d..d78b0b2 100644
--- a/src/runtime/align_runtime_test.go
+++ b/src/runtime/align_runtime_test.go
@@ -14,24 +14,7 @@
 // operations (all the *64 operations in runtime/internal/atomic).
 var AtomicFields = []uintptr{
 	unsafe.Offsetof(m{}.procid),
-	unsafe.Offsetof(p{}.timer0When),
-	unsafe.Offsetof(p{}.timerModifiedEarliest),
 	unsafe.Offsetof(p{}.gcFractionalMarkTime),
-	unsafe.Offsetof(schedt{}.goidgen),
-	unsafe.Offsetof(schedt{}.lastpoll),
-	unsafe.Offsetof(schedt{}.pollUntil),
-	unsafe.Offsetof(schedt{}.timeToRun),
-	unsafe.Offsetof(gcControllerState{}.bgScanCredit),
-	unsafe.Offsetof(gcControllerState{}.maxStackScan),
-	unsafe.Offsetof(gcControllerState{}.heapLive),
-	unsafe.Offsetof(gcControllerState{}.heapScan),
-	unsafe.Offsetof(gcControllerState{}.dedicatedMarkTime),
-	unsafe.Offsetof(gcControllerState{}.dedicatedMarkWorkersNeeded),
-	unsafe.Offsetof(gcControllerState{}.fractionalMarkTime),
-	unsafe.Offsetof(gcControllerState{}.idleMarkTime),
-	unsafe.Offsetof(gcControllerState{}.globalsScan),
-	unsafe.Offsetof(gcControllerState{}.lastStackScan),
-	unsafe.Offsetof(timeHistogram{}.underflow),
 	unsafe.Offsetof(profBuf{}.overflow),
 	unsafe.Offsetof(profBuf{}.overflowTime),
 	unsafe.Offsetof(heapStatsDelta{}.tinyAllocCount),
@@ -50,10 +33,7 @@
 	unsafe.Offsetof(lfnode{}.next),
 	unsafe.Offsetof(mstats{}.last_gc_nanotime),
 	unsafe.Offsetof(mstats{}.last_gc_unix),
-	unsafe.Offsetof(mstats{}.gcPauseDist),
-	unsafe.Offsetof(ticksType{}.val),
 	unsafe.Offsetof(workType{}.bytesMarked),
-	unsafe.Offsetof(timeHistogram{}.counts),
 }
 
 // AtomicVariables is the set of global variables on which we perform
diff --git a/src/runtime/align_test.go b/src/runtime/align_test.go
index 55cf783..5f225d6 100644
--- a/src/runtime/align_test.go
+++ b/src/runtime/align_test.go
@@ -5,7 +5,6 @@
 package runtime_test
 
 import (
-	"bytes"
 	"go/ast"
 	"go/build"
 	"go/importer"
@@ -13,6 +12,7 @@
 	"go/printer"
 	"go/token"
 	"go/types"
+	"internal/testenv"
 	"os"
 	"regexp"
 	"runtime"
@@ -23,6 +23,8 @@
 // Check that 64-bit fields on which we apply atomic operations
 // are aligned to 8 bytes. This can be a problem on 32-bit systems.
 func TestAtomicAlignment(t *testing.T) {
+	testenv.MustHaveGoBuild(t) // go command needed to resolve std .a files for importer.Default().
+
 	// Read the code making the tables above, to see which fields and
 	// variables we are currently checking.
 	checked := map[string]bool{}
@@ -180,7 +182,7 @@
 }
 
 func (v *Visitor) print(n ast.Node) string {
-	var b bytes.Buffer
+	var b strings.Builder
 	printer.Fprint(&b, v.fset, n)
 	return b.String()
 }
diff --git a/src/runtime/arena.go b/src/runtime/arena.go
new file mode 100644
index 0000000..c338d30
--- /dev/null
+++ b/src/runtime/arena.go
@@ -0,0 +1,1003 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Implementation of (safe) user arenas.
+//
+// This file contains the implementation of user arenas wherein Go values can
+// be manually allocated and freed in bulk. The act of manually freeing memory,
+// potentially before a GC cycle, means that a garbage collection cycle can be
+// delayed, improving efficiency by reducing GC cycle frequency. There are other
+// potential efficiency benefits, such as improved locality and access to a more
+// efficient allocation strategy.
+//
+// What makes the arenas here safe is that once they are freed, accessing the
+// arena's memory will cause an explicit program fault, and the arena's address
+// space will not be reused until no more pointers into it are found. There's one
+// exception to this: if an arena allocated memory that isn't exhausted, it's placed
+// back into a pool for reuse. This means that a crash is not always guaranteed.
+//
+// While this may seem unsafe, it still prevents memory corruption, and is in fact
+// necessary in order to make new(T) a valid implementation of arenas. Such a property
+// is desirable to allow for a trivial implementation. (It also avoids complexities
+// that arise from synchronization with the GC when trying to set the arena chunks to
+// fault while the GC is active.)
+//
+// The implementation works in layers. At the bottom, arenas are managed in chunks.
+// Each chunk must be a multiple of the heap arena size, or the heap arena size must
+// be divisible by the arena chunks. The address space for each chunk, and each
+// corresponding heapArena for that addres space, are eternelly reserved for use as
+// arena chunks. That is, they can never be used for the general heap. Each chunk
+// is also represented by a single mspan, and is modeled as a single large heap
+// allocation. It must be, because each chunk contains ordinary Go values that may
+// point into the heap, so it must be scanned just like any other object. Any
+// pointer into a chunk will therefore always cause the whole chunk to be scanned
+// while its corresponding arena is still live.
+//
+// Chunks may be allocated either from new memory mapped by the OS on our behalf,
+// or by reusing old freed chunks. When chunks are freed, their underlying memory
+// is returned to the OS, set to fault on access, and may not be reused until the
+// program doesn't point into the chunk anymore (the code refers to this state as
+// "quarantined"), a property checked by the GC.
+//
+// The sweeper handles moving chunks out of this quarantine state to be ready for
+// reuse. When the chunk is placed into the quarantine state, its corresponding
+// span is marked as noscan so that the GC doesn't try to scan memory that would
+// cause a fault.
+//
+// At the next layer are the user arenas themselves. They consist of a single
+// active chunk which new Go values are bump-allocated into and a list of chunks
+// that were exhausted when allocating into the arena. Once the arena is freed,
+// it frees all full chunks it references, and places the active one onto a reuse
+// list for a future arena to use. Each arena keeps its list of referenced chunks
+// explicitly live until it is freed. Each user arena also maps to an object which
+// has a finalizer attached that ensures the arena's chunks are all freed even if
+// the arena itself is never explicitly freed.
+//
+// Pointer-ful memory is bump-allocated from low addresses to high addresses in each
+// chunk, while pointer-free memory is bump-allocated from high address to low
+// addresses. The reason for this is to take advantage of a GC optimization wherein
+// the GC will stop scanning an object when there are no more pointers in it, which
+// also allows us to elide clearing the heap bitmap for pointer-free Go values
+// allocated into arenas.
+//
+// Note that arenas are not safe to use concurrently.
+//
+// In summary, there are 2 resources: arenas, and arena chunks. They exist in the
+// following lifecycle:
+//
+// (1) A new arena is created via newArena.
+// (2) Chunks are allocated to hold memory allocated into the arena with new or slice.
+//    (a) Chunks are first allocated from the reuse list of partially-used chunks.
+//    (b) If there are no such chunks, then chunks on the ready list are taken.
+//    (c) Failing all the above, memory for a new chunk is mapped.
+// (3) The arena is freed, or all references to it are dropped, triggering its finalizer.
+//    (a) If the GC is not active, exhausted chunks are set to fault and placed on a
+//        quarantine list.
+//    (b) If the GC is active, exhausted chunks are placed on a fault list and will
+//        go through step (a) at a later point in time.
+//    (c) Any remaining partially-used chunk is placed on a reuse list.
+// (4) Once no more pointers are found into quarantined arena chunks, the sweeper
+//     takes these chunks out of quarantine and places them on the ready list.
+
+package runtime
+
+import (
+	"internal/goarch"
+	"runtime/internal/atomic"
+	"runtime/internal/math"
+	"unsafe"
+)
+
+// Functions starting with arena_ are meant to be exported to downstream users
+// of arenas. They should wrap these functions in a higher-lever API.
+//
+// The underlying arena and its resources are managed through an opaque unsafe.Pointer.
+
+// arena_newArena is a wrapper around newUserArena.
+//
+//go:linkname arena_newArena arena.runtime_arena_newArena
+func arena_newArena() unsafe.Pointer {
+	return unsafe.Pointer(newUserArena())
+}
+
+// arena_arena_New is a wrapper around (*userArena).new, except that typ
+// is an any (must be a *_type, still) and typ must be a type descriptor
+// for a pointer to the type to actually be allocated, i.e. pass a *T
+// to allocate a T. This is necessary because this function returns a *T.
+//
+//go:linkname arena_arena_New arena.runtime_arena_arena_New
+func arena_arena_New(arena unsafe.Pointer, typ any) any {
+	t := (*_type)(efaceOf(&typ).data)
+	if t.kind&kindMask != kindPtr {
+		throw("arena_New: non-pointer type")
+	}
+	te := (*ptrtype)(unsafe.Pointer(t)).elem
+	x := ((*userArena)(arena)).new(te)
+	var result any
+	e := efaceOf(&result)
+	e._type = t
+	e.data = x
+	return result
+}
+
+// arena_arena_Slice is a wrapper around (*userArena).slice.
+//
+//go:linkname arena_arena_Slice arena.runtime_arena_arena_Slice
+func arena_arena_Slice(arena unsafe.Pointer, slice any, cap int) {
+	((*userArena)(arena)).slice(slice, cap)
+}
+
+// arena_arena_Free is a wrapper around (*userArena).free.
+//
+//go:linkname arena_arena_Free arena.runtime_arena_arena_Free
+func arena_arena_Free(arena unsafe.Pointer) {
+	((*userArena)(arena)).free()
+}
+
+// arena_heapify takes a value that lives in an arena and makes a copy
+// of it on the heap. Values that don't live in an arena are returned unmodified.
+//
+//go:linkname arena_heapify arena.runtime_arena_heapify
+func arena_heapify(s any) any {
+	var v unsafe.Pointer
+	e := efaceOf(&s)
+	t := e._type
+	switch t.kind & kindMask {
+	case kindString:
+		v = stringStructOf((*string)(e.data)).str
+	case kindSlice:
+		v = (*slice)(e.data).array
+	case kindPtr:
+		v = e.data
+	default:
+		panic("arena: Clone only supports pointers, slices, and strings")
+	}
+	span := spanOf(uintptr(v))
+	if span == nil || !span.isUserArenaChunk {
+		// Not stored in a user arena chunk.
+		return s
+	}
+	// Heap-allocate storage for a copy.
+	var x any
+	switch t.kind & kindMask {
+	case kindString:
+		s1 := s.(string)
+		s2, b := rawstring(len(s1))
+		copy(b, s1)
+		x = s2
+	case kindSlice:
+		len := (*slice)(e.data).len
+		et := (*slicetype)(unsafe.Pointer(t)).elem
+		sl := new(slice)
+		*sl = slice{makeslicecopy(et, len, len, (*slice)(e.data).array), len, len}
+		xe := efaceOf(&x)
+		xe._type = t
+		xe.data = unsafe.Pointer(sl)
+	case kindPtr:
+		et := (*ptrtype)(unsafe.Pointer(t)).elem
+		e2 := newobject(et)
+		typedmemmove(et, e2, e.data)
+		xe := efaceOf(&x)
+		xe._type = t
+		xe.data = e2
+	}
+	return x
+}
+
+const (
+	// userArenaChunkBytes is the size of a user arena chunk.
+	userArenaChunkBytesMax = 8 << 20
+	userArenaChunkBytes    = uintptr(int64(userArenaChunkBytesMax-heapArenaBytes)&(int64(userArenaChunkBytesMax-heapArenaBytes)>>63) + heapArenaBytes) // min(userArenaChunkBytesMax, heapArenaBytes)
+
+	// userArenaChunkPages is the number of pages a user arena chunk uses.
+	userArenaChunkPages = userArenaChunkBytes / pageSize
+
+	// userArenaChunkMaxAllocBytes is the maximum size of an object that can
+	// be allocated from an arena. This number is chosen to cap worst-case
+	// fragmentation of user arenas to 25%. Larger allocations are redirected
+	// to the heap.
+	userArenaChunkMaxAllocBytes = userArenaChunkBytes / 4
+)
+
+func init() {
+	if userArenaChunkPages*pageSize != userArenaChunkBytes {
+		throw("user arena chunk size is not a mutliple of the page size")
+	}
+	if userArenaChunkBytes%physPageSize != 0 {
+		throw("user arena chunk size is not a mutliple of the physical page size")
+	}
+	if userArenaChunkBytes < heapArenaBytes {
+		if heapArenaBytes%userArenaChunkBytes != 0 {
+			throw("user arena chunk size is smaller than a heap arena, but doesn't divide it")
+		}
+	} else {
+		if userArenaChunkBytes%heapArenaBytes != 0 {
+			throw("user arena chunks size is larger than a heap arena, but not a multiple")
+		}
+	}
+	lockInit(&userArenaState.lock, lockRankUserArenaState)
+}
+
+type userArena struct {
+	// full is a list of full chunks that have not enough free memory left, and
+	// that we'll free once this user arena is freed.
+	//
+	// Can't use mSpanList here because it's not-in-heap.
+	fullList *mspan
+
+	// active is the user arena chunk we're currently allocating into.
+	active *mspan
+
+	// refs is a set of references to the arena chunks so that they're kept alive.
+	//
+	// The last reference in the list always refers to active, while the rest of
+	// them correspond to fullList. Specifically, the head of fullList is the
+	// second-to-last one, fullList.next is the third-to-last, and so on.
+	//
+	// In other words, every time a new chunk becomes active, its appended to this
+	// list.
+	refs []unsafe.Pointer
+
+	// defunct is true if free has been called on this arena.
+	//
+	// This is just a best-effort way to discover a concurrent allocation
+	// and free. Also used to detect a double-free.
+	defunct atomic.Bool
+}
+
+// newUserArena creates a new userArena ready to be used.
+func newUserArena() *userArena {
+	a := new(userArena)
+	SetFinalizer(a, func(a *userArena) {
+		// If arena handle is dropped without being freed, then call
+		// free on the arena, so the arena chunks are never reclaimed
+		// by the garbage collector.
+		a.free()
+	})
+	a.refill()
+	return a
+}
+
+// new allocates a new object of the provided type into the arena, and returns
+// its pointer.
+//
+// This operation is not safe to call concurrently with other operations on the
+// same arena.
+func (a *userArena) new(typ *_type) unsafe.Pointer {
+	return a.alloc(typ, -1)
+}
+
+// slice allocates a new slice backing store. slice must be a pointer to a slice
+// (i.e. *[]T), because userArenaSlice will update the slice directly.
+//
+// cap determines the capacity of the slice backing store and must be non-negative.
+//
+// This operation is not safe to call concurrently with other operations on the
+// same arena.
+func (a *userArena) slice(sl any, cap int) {
+	if cap < 0 {
+		panic("userArena.slice: negative cap")
+	}
+	i := efaceOf(&sl)
+	typ := i._type
+	if typ.kind&kindMask != kindPtr {
+		panic("slice result of non-ptr type")
+	}
+	typ = (*ptrtype)(unsafe.Pointer(typ)).elem
+	if typ.kind&kindMask != kindSlice {
+		panic("slice of non-ptr-to-slice type")
+	}
+	typ = (*slicetype)(unsafe.Pointer(typ)).elem
+	// t is now the element type of the slice we want to allocate.
+
+	*((*slice)(i.data)) = slice{a.alloc(typ, cap), cap, cap}
+}
+
+// free returns the userArena's chunks back to mheap and marks it as defunct.
+//
+// Must be called at most once for any given arena.
+//
+// This operation is not safe to call concurrently with other operations on the
+// same arena.
+func (a *userArena) free() {
+	// Check for a double-free.
+	if a.defunct.Load() {
+		panic("arena double free")
+	}
+
+	// Mark ourselves as defunct.
+	a.defunct.Store(true)
+	SetFinalizer(a, nil)
+
+	// Free all the full arenas.
+	//
+	// The refs on this list are in reverse order from the second-to-last.
+	s := a.fullList
+	i := len(a.refs) - 2
+	for s != nil {
+		a.fullList = s.next
+		s.next = nil
+		freeUserArenaChunk(s, a.refs[i])
+		s = a.fullList
+		i--
+	}
+	if a.fullList != nil || i >= 0 {
+		// There's still something left on the full list, or we
+		// failed to actually iterate over the entire refs list.
+		throw("full list doesn't match refs list in length")
+	}
+
+	// Put the active chunk onto the reuse list.
+	//
+	// Note that active's reference is always the last reference in refs.
+	s = a.active
+	if s != nil {
+		if raceenabled || msanenabled || asanenabled {
+			// Don't reuse arenas with sanitizers enabled. We want to catch
+			// any use-after-free errors aggressively.
+			freeUserArenaChunk(s, a.refs[len(a.refs)-1])
+		} else {
+			lock(&userArenaState.lock)
+			userArenaState.reuse = append(userArenaState.reuse, liveUserArenaChunk{s, a.refs[len(a.refs)-1]})
+			unlock(&userArenaState.lock)
+		}
+	}
+	// nil out a.active so that a race with freeing will more likely cause a crash.
+	a.active = nil
+	a.refs = nil
+}
+
+// alloc reserves space in the current chunk or calls refill and reserves space
+// in a new chunk. If cap is negative, the type will be taken literally, otherwise
+// it will be considered as an element type for a slice backing store with capacity
+// cap.
+func (a *userArena) alloc(typ *_type, cap int) unsafe.Pointer {
+	s := a.active
+	var x unsafe.Pointer
+	for {
+		x = s.userArenaNextFree(typ, cap)
+		if x != nil {
+			break
+		}
+		s = a.refill()
+	}
+	return x
+}
+
+// refill inserts the current arena chunk onto the full list and obtains a new
+// one, either from the partial list or allocating a new one, both from mheap.
+func (a *userArena) refill() *mspan {
+	// If there's an active chunk, assume it's full.
+	s := a.active
+	if s != nil {
+		if s.userArenaChunkFree.size() > userArenaChunkMaxAllocBytes {
+			// It's difficult to tell when we're actually out of memory
+			// in a chunk because the allocation that failed may still leave
+			// some free space available. However, that amount of free space
+			// should never exceed the maximum allocation size.
+			throw("wasted too much memory in an arena chunk")
+		}
+		s.next = a.fullList
+		a.fullList = s
+		a.active = nil
+		s = nil
+	}
+	var x unsafe.Pointer
+
+	// Check the partially-used list.
+	lock(&userArenaState.lock)
+	if len(userArenaState.reuse) > 0 {
+		// Pick off the last arena chunk from the list.
+		n := len(userArenaState.reuse) - 1
+		x = userArenaState.reuse[n].x
+		s = userArenaState.reuse[n].mspan
+		userArenaState.reuse[n].x = nil
+		userArenaState.reuse[n].mspan = nil
+		userArenaState.reuse = userArenaState.reuse[:n]
+	}
+	unlock(&userArenaState.lock)
+	if s == nil {
+		// Allocate a new one.
+		x, s = newUserArenaChunk()
+		if s == nil {
+			throw("out of memory")
+		}
+	}
+	a.refs = append(a.refs, x)
+	a.active = s
+	return s
+}
+
+type liveUserArenaChunk struct {
+	*mspan // Must represent a user arena chunk.
+
+	// Reference to mspan.base() to keep the chunk alive.
+	x unsafe.Pointer
+}
+
+var userArenaState struct {
+	lock mutex
+
+	// reuse contains a list of partially-used and already-live
+	// user arena chunks that can be quickly reused for another
+	// arena.
+	//
+	// Protected by lock.
+	reuse []liveUserArenaChunk
+
+	// fault contains full user arena chunks that need to be faulted.
+	//
+	// Protected by lock.
+	fault []liveUserArenaChunk
+}
+
+// userArenaNextFree reserves space in the user arena for an item of the specified
+// type. If cap is not -1, this is for an array of cap elements of type t.
+func (s *mspan) userArenaNextFree(typ *_type, cap int) unsafe.Pointer {
+	size := typ.size
+	if cap > 0 {
+		if size > ^uintptr(0)/uintptr(cap) {
+			// Overflow.
+			throw("out of memory")
+		}
+		size *= uintptr(cap)
+	}
+	if size == 0 || cap == 0 {
+		return unsafe.Pointer(&zerobase)
+	}
+	if size > userArenaChunkMaxAllocBytes {
+		// Redirect allocations that don't fit into a chunk well directly
+		// from the heap.
+		if cap >= 0 {
+			return newarray(typ, cap)
+		}
+		return newobject(typ)
+	}
+
+	// Prevent preemption as we set up the space for a new object.
+	//
+	// Act like we're allocating.
+	mp := acquirem()
+	if mp.mallocing != 0 {
+		throw("malloc deadlock")
+	}
+	if mp.gsignal == getg() {
+		throw("malloc during signal")
+	}
+	mp.mallocing = 1
+
+	var ptr unsafe.Pointer
+	if typ.ptrdata == 0 {
+		// Allocate pointer-less objects from the tail end of the chunk.
+		v, ok := s.userArenaChunkFree.takeFromBack(size, typ.align)
+		if ok {
+			ptr = unsafe.Pointer(v)
+		}
+	} else {
+		v, ok := s.userArenaChunkFree.takeFromFront(size, typ.align)
+		if ok {
+			ptr = unsafe.Pointer(v)
+		}
+	}
+	if ptr == nil {
+		// Failed to allocate.
+		mp.mallocing = 0
+		releasem(mp)
+		return nil
+	}
+	if s.needzero != 0 {
+		throw("arena chunk needs zeroing, but should already be zeroed")
+	}
+	// Set up heap bitmap and do extra accounting.
+	if typ.ptrdata != 0 {
+		if cap >= 0 {
+			userArenaHeapBitsSetSliceType(typ, cap, ptr, s.base())
+		} else {
+			userArenaHeapBitsSetType(typ, ptr, s.base())
+		}
+		c := getMCache(mp)
+		if c == nil {
+			throw("mallocgc called without a P or outside bootstrapping")
+		}
+		if cap > 0 {
+			c.scanAlloc += size - (typ.size - typ.ptrdata)
+		} else {
+			c.scanAlloc += typ.ptrdata
+		}
+	}
+
+	// Ensure that the stores above that initialize x to
+	// type-safe memory and set the heap bits occur before
+	// the caller can make ptr observable to the garbage
+	// collector. Otherwise, on weakly ordered machines,
+	// the garbage collector could follow a pointer to x,
+	// but see uninitialized memory or stale heap bits.
+	publicationBarrier()
+
+	mp.mallocing = 0
+	releasem(mp)
+
+	return ptr
+}
+
+// userArenaHeapBitsSetType is the equivalent of heapBitsSetType but for
+// non-slice-backing-store Go values allocated in a user arena chunk. It
+// sets up the heap bitmap for the value with type typ allocated at address ptr.
+// base is the base address of the arena chunk.
+func userArenaHeapBitsSetType(typ *_type, ptr unsafe.Pointer, base uintptr) {
+	h := writeHeapBitsForAddr(uintptr(ptr))
+
+	// Our last allocation might have ended right at a noMorePtrs mark,
+	// which we would not have erased. We need to erase that mark here,
+	// because we're going to start adding new heap bitmap bits.
+	// We only need to clear one mark, because below we make sure to
+	// pad out the bits with zeroes and only write one noMorePtrs bit
+	// for each new object.
+	// (This is only necessary at noMorePtrs boundaries, as noMorePtrs
+	// marks within an object allocated with newAt will be erased by
+	// the normal writeHeapBitsForAddr mechanism.)
+	//
+	// Note that we skip this if this is the first allocation in the
+	// arena because there's definitely no previous noMorePtrs mark
+	// (in fact, we *must* do this, because we're going to try to back
+	// up a pointer to fix this up).
+	if uintptr(ptr)%(8*goarch.PtrSize*goarch.PtrSize) == 0 && uintptr(ptr) != base {
+		// Back up one pointer and rewrite that pointer. That will
+		// cause the writeHeapBits implementation to clear the
+		// noMorePtrs bit we need to clear.
+		r := heapBitsForAddr(uintptr(ptr)-goarch.PtrSize, goarch.PtrSize)
+		_, p := r.next()
+		b := uintptr(0)
+		if p == uintptr(ptr)-goarch.PtrSize {
+			b = 1
+		}
+		h = writeHeapBitsForAddr(uintptr(ptr) - goarch.PtrSize)
+		h = h.write(b, 1)
+	}
+
+	p := typ.gcdata // start of 1-bit pointer mask (or GC program)
+	var gcProgBits uintptr
+	if typ.kind&kindGCProg != 0 {
+		// Expand gc program, using the object itself for storage.
+		gcProgBits = runGCProg(addb(p, 4), (*byte)(ptr))
+		p = (*byte)(ptr)
+	}
+	nb := typ.ptrdata / goarch.PtrSize
+
+	for i := uintptr(0); i < nb; i += ptrBits {
+		k := nb - i
+		if k > ptrBits {
+			k = ptrBits
+		}
+		h = h.write(readUintptr(addb(p, i/8)), k)
+	}
+	// Note: we call pad here to ensure we emit explicit 0 bits
+	// for the pointerless tail of the object. This ensures that
+	// there's only a single noMorePtrs mark for the next object
+	// to clear. We don't need to do this to clear stale noMorePtrs
+	// markers from previous uses because arena chunk pointer bitmaps
+	// are always fully cleared when reused.
+	h = h.pad(typ.size - typ.ptrdata)
+	h.flush(uintptr(ptr), typ.size)
+
+	if typ.kind&kindGCProg != 0 {
+		// Zero out temporary ptrmask buffer inside object.
+		memclrNoHeapPointers(ptr, (gcProgBits+7)/8)
+	}
+
+	// Double-check that the bitmap was written out correctly.
+	//
+	// Derived from heapBitsSetType.
+	const doubleCheck = false
+	if doubleCheck {
+		size := typ.size
+		x := uintptr(ptr)
+		h := heapBitsForAddr(x, size)
+		for i := uintptr(0); i < size; i += goarch.PtrSize {
+			// Compute the pointer bit we want at offset i.
+			want := false
+			off := i % typ.size
+			if off < typ.ptrdata {
+				j := off / goarch.PtrSize
+				want = *addb(typ.gcdata, j/8)>>(j%8)&1 != 0
+			}
+			if want {
+				var addr uintptr
+				h, addr = h.next()
+				if addr != x+i {
+					throw("userArenaHeapBitsSetType: pointer entry not correct")
+				}
+			}
+		}
+		if _, addr := h.next(); addr != 0 {
+			throw("userArenaHeapBitsSetType: extra pointer")
+		}
+	}
+}
+
+// userArenaHeapBitsSetSliceType is the equivalent of heapBitsSetType but for
+// Go slice backing store values allocated in a user arena chunk. It sets up the
+// heap bitmap for n consecutive values with type typ allocated at address ptr.
+func userArenaHeapBitsSetSliceType(typ *_type, n int, ptr unsafe.Pointer, base uintptr) {
+	mem, overflow := math.MulUintptr(typ.size, uintptr(n))
+	if overflow || n < 0 || mem > maxAlloc {
+		panic(plainError("runtime: allocation size out of range"))
+	}
+	for i := 0; i < n; i++ {
+		userArenaHeapBitsSetType(typ, add(ptr, uintptr(i)*typ.size), base)
+	}
+}
+
+// newUserArenaChunk allocates a user arena chunk, which maps to a single
+// heap arena and single span. Returns a pointer to the base of the chunk
+// (this is really important: we need to keep the chunk alive) and the span.
+func newUserArenaChunk() (unsafe.Pointer, *mspan) {
+	if gcphase == _GCmarktermination {
+		throw("newUserArenaChunk called with gcphase == _GCmarktermination")
+	}
+
+	// Deduct assist credit. Because user arena chunks are modeled as one
+	// giant heap object which counts toward heapLive, we're obligated to
+	// assist the GC proportionally (and it's worth noting that the arena
+	// does represent additional work for the GC, but we also have no idea
+	// what that looks like until we actually allocate things into the
+	// arena).
+	deductAssistCredit(userArenaChunkBytes)
+
+	// Set mp.mallocing to keep from being preempted by GC.
+	mp := acquirem()
+	if mp.mallocing != 0 {
+		throw("malloc deadlock")
+	}
+	if mp.gsignal == getg() {
+		throw("malloc during signal")
+	}
+	mp.mallocing = 1
+
+	// Allocate a new user arena.
+	var span *mspan
+	systemstack(func() {
+		span = mheap_.allocUserArenaChunk()
+	})
+	if span == nil {
+		throw("out of memory")
+	}
+	x := unsafe.Pointer(span.base())
+
+	// Allocate black during GC.
+	// All slots hold nil so no scanning is needed.
+	// This may be racing with GC so do it atomically if there can be
+	// a race marking the bit.
+	if gcphase != _GCoff {
+		gcmarknewobject(span, span.base(), span.elemsize)
+	}
+
+	if raceenabled {
+		// TODO(mknyszek): Track individual objects.
+		racemalloc(unsafe.Pointer(span.base()), span.elemsize)
+	}
+
+	if msanenabled {
+		// TODO(mknyszek): Track individual objects.
+		msanmalloc(unsafe.Pointer(span.base()), span.elemsize)
+	}
+
+	if asanenabled {
+		// TODO(mknyszek): Track individual objects.
+		rzSize := computeRZlog(span.elemsize)
+		span.elemsize -= rzSize
+		span.limit -= rzSize
+		span.userArenaChunkFree = makeAddrRange(span.base(), span.limit)
+		asanpoison(unsafe.Pointer(span.limit), span.npages*pageSize-span.elemsize)
+		asanunpoison(unsafe.Pointer(span.base()), span.elemsize)
+	}
+
+	if rate := MemProfileRate; rate > 0 {
+		c := getMCache(mp)
+		if c == nil {
+			throw("newUserArenaChunk called without a P or outside bootstrapping")
+		}
+		// Note cache c only valid while m acquired; see #47302
+		if rate != 1 && userArenaChunkBytes < c.nextSample {
+			c.nextSample -= userArenaChunkBytes
+		} else {
+			profilealloc(mp, unsafe.Pointer(span.base()), userArenaChunkBytes)
+		}
+	}
+	mp.mallocing = 0
+	releasem(mp)
+
+	// Again, because this chunk counts toward heapLive, potentially trigger a GC.
+	if t := (gcTrigger{kind: gcTriggerHeap}); t.test() {
+		gcStart(t)
+	}
+
+	if debug.malloc {
+		if debug.allocfreetrace != 0 {
+			tracealloc(unsafe.Pointer(span.base()), userArenaChunkBytes, nil)
+		}
+
+		if inittrace.active && inittrace.id == getg().goid {
+			// Init functions are executed sequentially in a single goroutine.
+			inittrace.bytes += uint64(userArenaChunkBytes)
+		}
+	}
+
+	// Double-check it's aligned to the physical page size. Based on the current
+	// implementation this is trivially true, but it need not be in the future.
+	// However, if it's not aligned to the physical page size then we can't properly
+	// set it to fault later.
+	if uintptr(x)%physPageSize != 0 {
+		throw("user arena chunk is not aligned to the physical page size")
+	}
+
+	return x, span
+}
+
+// isUnusedUserArenaChunk indicates that the arena chunk has been set to fault
+// and doesn't contain any scannable memory anymore. However, it might still be
+// mSpanInUse as it sits on the quarantine list, since it needs to be swept.
+//
+// This is not safe to execute unless the caller has ownership of the mspan or
+// the world is stopped (preemption is prevented while the relevant state changes).
+//
+// This is really only meant to be used by accounting tests in the runtime to
+// distinguish when a span shouldn't be counted (since mSpanInUse might not be
+// enough).
+func (s *mspan) isUnusedUserArenaChunk() bool {
+	return s.isUserArenaChunk && s.spanclass == makeSpanClass(0, true)
+}
+
+// setUserArenaChunkToFault sets the address space for the user arena chunk to fault
+// and releases any underlying memory resources.
+//
+// Must be in a non-preemptible state to ensure the consistency of statistics
+// exported to MemStats.
+func (s *mspan) setUserArenaChunkToFault() {
+	if !s.isUserArenaChunk {
+		throw("invalid span in heapArena for user arena")
+	}
+	if s.npages*pageSize != userArenaChunkBytes {
+		throw("span on userArena.faultList has invalid size")
+	}
+
+	// Update the span class to be noscan. What we want to happen is that
+	// any pointer into the span keeps it from getting recycled, so we want
+	// the mark bit to get set, but we're about to set the address space to fault,
+	// so we have to prevent the GC from scanning this memory.
+	//
+	// It's OK to set it here because (1) a GC isn't in progress, so the scanning code
+	// won't make a bad decision, (2) we're currently non-preemptible and in the runtime,
+	// so a GC is blocked from starting. We might race with sweeping, which could
+	// put it on the "wrong" sweep list, but really don't care because the chunk is
+	// treated as a large object span and there's no meaningful difference between scan
+	// and noscan large objects in the sweeper. The STW at the start of the GC acts as a
+	// barrier for this update.
+	s.spanclass = makeSpanClass(0, true)
+
+	// Actually set the arena chunk to fault, so we'll get dangling pointer errors.
+	// sysFault currently uses a method on each OS that forces it to evacuate all
+	// memory backing the chunk.
+	sysFault(unsafe.Pointer(s.base()), s.npages*pageSize)
+
+	// Everything on the list is counted as in-use, however sysFault transitions to
+	// Reserved, not Prepared, so we skip updating heapFree or heapReleased and just
+	// remove the memory from the total altogether; it's just address space now.
+	gcController.heapInUse.add(-int64(s.npages * pageSize))
+
+	// Count this as a free of an object right now as opposed to when
+	// the span gets off the quarantine list. The main reason is so that the
+	// amount of bytes allocated doesn't exceed how much is counted as
+	// "mapped ready," which could cause a deadlock in the pacer.
+	gcController.totalFree.Add(int64(s.npages * pageSize))
+
+	// Update consistent stats to match.
+	//
+	// We're non-preemptible, so it's safe to update consistent stats (our P
+	// won't change out from under us).
+	stats := memstats.heapStats.acquire()
+	atomic.Xaddint64(&stats.committed, -int64(s.npages*pageSize))
+	atomic.Xaddint64(&stats.inHeap, -int64(s.npages*pageSize))
+	atomic.Xadd64(&stats.largeFreeCount, 1)
+	atomic.Xadd64(&stats.largeFree, int64(s.npages*pageSize))
+	memstats.heapStats.release()
+
+	// This counts as a free, so update heapLive.
+	gcController.update(-int64(s.npages*pageSize), 0)
+
+	// Mark it as free for the race detector.
+	if raceenabled {
+		racefree(unsafe.Pointer(s.base()), s.elemsize)
+	}
+
+	systemstack(func() {
+		// Add the user arena to the quarantine list.
+		lock(&mheap_.lock)
+		mheap_.userArena.quarantineList.insert(s)
+		unlock(&mheap_.lock)
+	})
+}
+
+// inUserArenaChunk returns true if p points to a user arena chunk.
+func inUserArenaChunk(p uintptr) bool {
+	s := spanOf(p)
+	if s == nil {
+		return false
+	}
+	return s.isUserArenaChunk
+}
+
+// freeUserArenaChunk releases the user arena represented by s back to the runtime.
+//
+// x must be a live pointer within s.
+//
+// The runtime will set the user arena to fault once it's safe (the GC is no longer running)
+// and then once the user arena is no longer referenced by the application, will allow it to
+// be reused.
+func freeUserArenaChunk(s *mspan, x unsafe.Pointer) {
+	if !s.isUserArenaChunk {
+		throw("span is not for a user arena")
+	}
+	if s.npages*pageSize != userArenaChunkBytes {
+		throw("invalid user arena span size")
+	}
+
+	// Mark the region as free to various santizers immediately instead
+	// of handling them at sweep time.
+	if raceenabled {
+		racefree(unsafe.Pointer(s.base()), s.elemsize)
+	}
+	if msanenabled {
+		msanfree(unsafe.Pointer(s.base()), s.elemsize)
+	}
+	if asanenabled {
+		asanpoison(unsafe.Pointer(s.base()), s.elemsize)
+	}
+
+	// Make ourselves non-preemptible as we manipulate state and statistics.
+	//
+	// Also required by setUserArenaChunksToFault.
+	mp := acquirem()
+
+	// We can only set user arenas to fault if we're in the _GCoff phase.
+	if gcphase == _GCoff {
+		lock(&userArenaState.lock)
+		faultList := userArenaState.fault
+		userArenaState.fault = nil
+		unlock(&userArenaState.lock)
+
+		s.setUserArenaChunkToFault()
+		for _, lc := range faultList {
+			lc.mspan.setUserArenaChunkToFault()
+		}
+
+		// Until the chunks are set to fault, keep them alive via the fault list.
+		KeepAlive(x)
+		KeepAlive(faultList)
+	} else {
+		// Put the user arena on the fault list.
+		lock(&userArenaState.lock)
+		userArenaState.fault = append(userArenaState.fault, liveUserArenaChunk{s, x})
+		unlock(&userArenaState.lock)
+	}
+	releasem(mp)
+}
+
+// allocUserArenaChunk attempts to reuse a free user arena chunk represented
+// as a span.
+//
+// Must be in a non-preemptible state to ensure the consistency of statistics
+// exported to MemStats.
+//
+// Acquires the heap lock. Must run on the system stack for that reason.
+//
+//go:systemstack
+func (h *mheap) allocUserArenaChunk() *mspan {
+	var s *mspan
+	var base uintptr
+
+	// First check the free list.
+	lock(&h.lock)
+	if !h.userArena.readyList.isEmpty() {
+		s = h.userArena.readyList.first
+		h.userArena.readyList.remove(s)
+		base = s.base()
+	} else {
+		// Free list was empty, so allocate a new arena.
+		hintList := &h.userArena.arenaHints
+		if raceenabled {
+			// In race mode just use the regular heap hints. We might fragment
+			// the address space, but the race detector requires that the heap
+			// is mapped contiguously.
+			hintList = &h.arenaHints
+		}
+		v, size := h.sysAlloc(userArenaChunkBytes, hintList, false)
+		if size%userArenaChunkBytes != 0 {
+			throw("sysAlloc size is not divisible by userArenaChunkBytes")
+		}
+		if size > userArenaChunkBytes {
+			// We got more than we asked for. This can happen if
+			// heapArenaSize > userArenaChunkSize, or if sysAlloc just returns
+			// some extra as a result of trying to find an aligned region.
+			//
+			// Divide it up and put it on the ready list.
+			for i := uintptr(userArenaChunkBytes); i < size; i += userArenaChunkBytes {
+				s := h.allocMSpanLocked()
+				s.init(uintptr(v)+i, userArenaChunkPages)
+				h.userArena.readyList.insertBack(s)
+			}
+			size = userArenaChunkBytes
+		}
+		base = uintptr(v)
+		if base == 0 {
+			// Out of memory.
+			unlock(&h.lock)
+			return nil
+		}
+		s = h.allocMSpanLocked()
+	}
+	unlock(&h.lock)
+
+	// sysAlloc returns Reserved address space, and any span we're
+	// reusing is set to fault (so, also Reserved), so transition
+	// it to Prepared and then Ready.
+	//
+	// Unlike (*mheap).grow, just map in everything that we
+	// asked for. We're likely going to use it all.
+	sysMap(unsafe.Pointer(base), userArenaChunkBytes, &gcController.heapReleased)
+	sysUsed(unsafe.Pointer(base), userArenaChunkBytes, userArenaChunkBytes)
+
+	// Model the user arena as a heap span for a large object.
+	spc := makeSpanClass(0, false)
+	h.initSpan(s, spanAllocHeap, spc, base, userArenaChunkPages)
+	s.isUserArenaChunk = true
+
+	// Account for this new arena chunk memory.
+	gcController.heapInUse.add(int64(userArenaChunkBytes))
+	gcController.heapReleased.add(-int64(userArenaChunkBytes))
+
+	stats := memstats.heapStats.acquire()
+	atomic.Xaddint64(&stats.inHeap, int64(userArenaChunkBytes))
+	atomic.Xaddint64(&stats.committed, int64(userArenaChunkBytes))
+
+	// Model the arena as a single large malloc.
+	atomic.Xadd64(&stats.largeAlloc, int64(userArenaChunkBytes))
+	atomic.Xadd64(&stats.largeAllocCount, 1)
+	memstats.heapStats.release()
+
+	// Count the alloc in inconsistent, internal stats.
+	gcController.totalAlloc.Add(int64(userArenaChunkBytes))
+
+	// Update heapLive.
+	gcController.update(int64(userArenaChunkBytes), 0)
+
+	// Put the large span in the mcentral swept list so that it's
+	// visible to the background sweeper.
+	h.central[spc].mcentral.fullSwept(h.sweepgen).push(s)
+	s.limit = s.base() + userArenaChunkBytes
+	s.freeindex = 1
+	s.allocCount = 1
+
+	// This must clear the entire heap bitmap so that it's safe
+	// to allocate noscan data without writing anything out.
+	s.initHeapBits(true)
+
+	// Clear the span preemptively. It's an arena chunk, so let's assume
+	// everything is going to be used.
+	//
+	// This also seems to make a massive difference as to whether or
+	// not Linux decides to back this memory with transparent huge
+	// pages. There's latency involved in this zeroing, but the hugepage
+	// gains are almost always worth it. Note: it's important that we
+	// clear even if it's freshly mapped and we know there's no point
+	// to zeroing as *that* is the critical signal to use huge pages.
+	memclrNoHeapPointers(unsafe.Pointer(s.base()), s.elemsize)
+	s.needzero = 0
+
+	s.freeIndexForScan = 1
+
+	// Set up the range for allocation.
+	s.userArenaChunkFree = makeAddrRange(base, s.limit)
+	return s
+}
diff --git a/src/runtime/arena_test.go b/src/runtime/arena_test.go
new file mode 100644
index 0000000..7e121ad
--- /dev/null
+++ b/src/runtime/arena_test.go
@@ -0,0 +1,529 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime_test
+
+import (
+	"internal/goarch"
+	"reflect"
+	. "runtime"
+	"runtime/debug"
+	"runtime/internal/atomic"
+	"testing"
+	"time"
+	"unsafe"
+)
+
+type smallScalar struct {
+	X uintptr
+}
+type smallPointer struct {
+	X *smallPointer
+}
+type smallPointerMix struct {
+	A *smallPointer
+	B byte
+	C *smallPointer
+	D [11]byte
+}
+type mediumScalarEven [8192]byte
+type mediumScalarOdd [3321]byte
+type mediumPointerEven [1024]*smallPointer
+type mediumPointerOdd [1023]*smallPointer
+
+type largeScalar [UserArenaChunkBytes + 1]byte
+type largePointer [UserArenaChunkBytes/unsafe.Sizeof(&smallPointer{}) + 1]*smallPointer
+
+func TestUserArena(t *testing.T) {
+	// Set GOMAXPROCS to 2 so we don't run too many of these
+	// tests in parallel.
+	defer GOMAXPROCS(GOMAXPROCS(2))
+
+	// Start a subtest so that we can clean up after any parallel tests within.
+	t.Run("Alloc", func(t *testing.T) {
+		ss := &smallScalar{5}
+		runSubTestUserArenaNew(t, ss, true)
+
+		sp := &smallPointer{new(smallPointer)}
+		runSubTestUserArenaNew(t, sp, true)
+
+		spm := &smallPointerMix{sp, 5, nil, [11]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}}
+		runSubTestUserArenaNew(t, spm, true)
+
+		mse := new(mediumScalarEven)
+		for i := range mse {
+			mse[i] = 121
+		}
+		runSubTestUserArenaNew(t, mse, true)
+
+		mso := new(mediumScalarOdd)
+		for i := range mso {
+			mso[i] = 122
+		}
+		runSubTestUserArenaNew(t, mso, true)
+
+		mpe := new(mediumPointerEven)
+		for i := range mpe {
+			mpe[i] = sp
+		}
+		runSubTestUserArenaNew(t, mpe, true)
+
+		mpo := new(mediumPointerOdd)
+		for i := range mpo {
+			mpo[i] = sp
+		}
+		runSubTestUserArenaNew(t, mpo, true)
+
+		ls := new(largeScalar)
+		for i := range ls {
+			ls[i] = 123
+		}
+		// Not in parallel because we don't want to hold this large allocation live.
+		runSubTestUserArenaNew(t, ls, false)
+
+		lp := new(largePointer)
+		for i := range lp {
+			lp[i] = sp
+		}
+		// Not in parallel because we don't want to hold this large allocation live.
+		runSubTestUserArenaNew(t, lp, false)
+
+		sss := make([]smallScalar, 25)
+		for i := range sss {
+			sss[i] = smallScalar{12}
+		}
+		runSubTestUserArenaSlice(t, sss, true)
+
+		mpos := make([]mediumPointerOdd, 5)
+		for i := range mpos {
+			mpos[i] = *mpo
+		}
+		runSubTestUserArenaSlice(t, mpos, true)
+
+		sps := make([]smallPointer, UserArenaChunkBytes/unsafe.Sizeof(smallPointer{})+1)
+		for i := range sps {
+			sps[i] = *sp
+		}
+		// Not in parallel because we don't want to hold this large allocation live.
+		runSubTestUserArenaSlice(t, sps, false)
+
+		// Test zero-sized types.
+		t.Run("struct{}", func(t *testing.T) {
+			arena := NewUserArena()
+			var x any
+			x = (*struct{})(nil)
+			arena.New(&x)
+			if v := unsafe.Pointer(x.(*struct{})); v != ZeroBase {
+				t.Errorf("expected zero-sized type to be allocated as zerobase: got %x, want %x", v, ZeroBase)
+			}
+			arena.Free()
+		})
+		t.Run("[]struct{}", func(t *testing.T) {
+			arena := NewUserArena()
+			var sl []struct{}
+			arena.Slice(&sl, 10)
+			if v := unsafe.Pointer(&sl[0]); v != ZeroBase {
+				t.Errorf("expected zero-sized type to be allocated as zerobase: got %x, want %x", v, ZeroBase)
+			}
+			arena.Free()
+		})
+		t.Run("[]int (cap 0)", func(t *testing.T) {
+			arena := NewUserArena()
+			var sl []int
+			arena.Slice(&sl, 0)
+			if len(sl) != 0 {
+				t.Errorf("expected requested zero-sized slice to still have zero length: got %x, want 0", len(sl))
+			}
+			arena.Free()
+		})
+	})
+
+	// Run a GC cycle to get any arenas off the quarantine list.
+	GC()
+
+	if n := GlobalWaitingArenaChunks(); n != 0 {
+		t.Errorf("expected zero waiting arena chunks, found %d", n)
+	}
+}
+
+func runSubTestUserArenaNew[S comparable](t *testing.T, value *S, parallel bool) {
+	t.Run(reflect.TypeOf(value).Elem().Name(), func(t *testing.T) {
+		if parallel {
+			t.Parallel()
+		}
+
+		// Allocate and write data, enough to exhaust the arena.
+		//
+		// This is an underestimate, likely leaving some space in the arena. That's a good thing,
+		// because it gives us coverage of boundary cases.
+		n := int(UserArenaChunkBytes / unsafe.Sizeof(*value))
+		if n == 0 {
+			n = 1
+		}
+
+		// Create a new arena and do a bunch of operations on it.
+		arena := NewUserArena()
+
+		arenaValues := make([]*S, 0, n)
+		for j := 0; j < n; j++ {
+			var x any
+			x = (*S)(nil)
+			arena.New(&x)
+			s := x.(*S)
+			*s = *value
+			arenaValues = append(arenaValues, s)
+		}
+		// Check integrity of allocated data.
+		for _, s := range arenaValues {
+			if *s != *value {
+				t.Errorf("failed integrity check: got %#v, want %#v", *s, *value)
+			}
+		}
+
+		// Release the arena.
+		arena.Free()
+	})
+}
+
+func runSubTestUserArenaSlice[S comparable](t *testing.T, value []S, parallel bool) {
+	t.Run("[]"+reflect.TypeOf(value).Elem().Name(), func(t *testing.T) {
+		if parallel {
+			t.Parallel()
+		}
+
+		// Allocate and write data, enough to exhaust the arena.
+		//
+		// This is an underestimate, likely leaving some space in the arena. That's a good thing,
+		// because it gives us coverage of boundary cases.
+		n := int(UserArenaChunkBytes / (unsafe.Sizeof(*new(S)) * uintptr(cap(value))))
+		if n == 0 {
+			n = 1
+		}
+
+		// Create a new arena and do a bunch of operations on it.
+		arena := NewUserArena()
+
+		arenaValues := make([][]S, 0, n)
+		for j := 0; j < n; j++ {
+			var sl []S
+			arena.Slice(&sl, cap(value))
+			copy(sl, value)
+			arenaValues = append(arenaValues, sl)
+		}
+		// Check integrity of allocated data.
+		for _, sl := range arenaValues {
+			for i := range sl {
+				got := sl[i]
+				want := value[i]
+				if got != want {
+					t.Errorf("failed integrity check: got %#v, want %#v at index %d", got, want, i)
+				}
+			}
+		}
+
+		// Release the arena.
+		arena.Free()
+	})
+}
+
+func TestUserArenaLiveness(t *testing.T) {
+	t.Run("Free", func(t *testing.T) {
+		testUserArenaLiveness(t, false)
+	})
+	t.Run("Finalizer", func(t *testing.T) {
+		testUserArenaLiveness(t, true)
+	})
+}
+
+func testUserArenaLiveness(t *testing.T, useArenaFinalizer bool) {
+	// Disable the GC so that there's zero chance we try doing anything arena related *during*
+	// a mark phase, since otherwise a bunch of arenas could end up on the fault list.
+	defer debug.SetGCPercent(debug.SetGCPercent(-1))
+
+	// Defensively ensure that any full arena chunks leftover from previous tests have been cleared.
+	GC()
+	GC()
+
+	arena := NewUserArena()
+
+	// Allocate a few pointer-ful but un-initialized objects so that later we can
+	// place a reference to heap object at a more interesting location.
+	for i := 0; i < 3; i++ {
+		var x any
+		x = (*mediumPointerOdd)(nil)
+		arena.New(&x)
+	}
+
+	var x any
+	x = (*smallPointerMix)(nil)
+	arena.New(&x)
+	v := x.(*smallPointerMix)
+
+	var safeToFinalize atomic.Bool
+	var finalized atomic.Bool
+	v.C = new(smallPointer)
+	SetFinalizer(v.C, func(_ *smallPointer) {
+		if !safeToFinalize.Load() {
+			t.Error("finalized arena-referenced object unexpectedly")
+		}
+		finalized.Store(true)
+	})
+
+	// Make sure it stays alive.
+	GC()
+	GC()
+
+	// In order to ensure the object can be freed, we now need to make sure to use
+	// the entire arena. Exhaust the rest of the arena.
+
+	for i := 0; i < int(UserArenaChunkBytes/unsafe.Sizeof(mediumScalarEven{})); i++ {
+		var x any
+		x = (*mediumScalarEven)(nil)
+		arena.New(&x)
+	}
+
+	// Make sure it stays alive again.
+	GC()
+	GC()
+
+	v = nil
+
+	safeToFinalize.Store(true)
+	if useArenaFinalizer {
+		arena = nil
+
+		// Try to queue the arena finalizer.
+		GC()
+		GC()
+
+		// In order for the finalizer we actually want to run to execute,
+		// we need to make sure this one runs first.
+		if !BlockUntilEmptyFinalizerQueue(int64(2 * time.Second)) {
+			t.Fatal("finalizer queue was never emptied")
+		}
+	} else {
+		// Free the arena explicitly.
+		arena.Free()
+	}
+
+	// Try to queue the object's finalizer that we set earlier.
+	GC()
+	GC()
+
+	if !BlockUntilEmptyFinalizerQueue(int64(2 * time.Second)) {
+		t.Fatal("finalizer queue was never emptied")
+	}
+	if !finalized.Load() {
+		t.Error("expected arena-referenced object to be finalized")
+	}
+}
+
+func TestUserArenaClearsPointerBits(t *testing.T) {
+	// This is a regression test for a serious issue wherein if pointer bits
+	// aren't properly cleared, it's possible to allocate scalar data down
+	// into a previously pointer-ful area, causing misinterpretation by the GC.
+
+	// Create a large object, grab a pointer into it, and free it.
+	x := new([8 << 20]byte)
+	xp := uintptr(unsafe.Pointer(&x[124]))
+	var finalized atomic.Bool
+	SetFinalizer(x, func(_ *[8 << 20]byte) {
+		finalized.Store(true)
+	})
+
+	// Write three chunks worth of pointer data. Three gives us a
+	// high likelihood that when we write 2 later, we'll get the behavior
+	// we want.
+	a := NewUserArena()
+	for i := 0; i < int(UserArenaChunkBytes/goarch.PtrSize*3); i++ {
+		var x any
+		x = (*smallPointer)(nil)
+		a.New(&x)
+	}
+	a.Free()
+
+	// Recycle the arena chunks.
+	GC()
+	GC()
+
+	a = NewUserArena()
+	for i := 0; i < int(UserArenaChunkBytes/goarch.PtrSize*2); i++ {
+		var x any
+		x = (*smallScalar)(nil)
+		a.New(&x)
+		v := x.(*smallScalar)
+		// Write a pointer that should not keep x alive.
+		*v = smallScalar{xp}
+	}
+	KeepAlive(x)
+	x = nil
+
+	// Try to free x.
+	GC()
+	GC()
+
+	if !BlockUntilEmptyFinalizerQueue(int64(2 * time.Second)) {
+		t.Fatal("finalizer queue was never emptied")
+	}
+	if !finalized.Load() {
+		t.Fatal("heap allocation kept alive through non-pointer reference")
+	}
+
+	// Clean up the arena.
+	a.Free()
+	GC()
+	GC()
+}
+
+func TestUserArenaCloneString(t *testing.T) {
+	a := NewUserArena()
+
+	// A static string (not on heap or arena)
+	var s = "abcdefghij"
+
+	// Create a byte slice in the arena, initialize it with s
+	var b []byte
+	a.Slice(&b, len(s))
+	copy(b, s)
+
+	// Create a string as using the same memory as the byte slice, hence in
+	// the arena. This could be an arena API, but hasn't really been needed
+	// yet.
+	var as string
+	asHeader := (*reflect.StringHeader)(unsafe.Pointer(&as))
+	asHeader.Data = (*reflect.SliceHeader)(unsafe.Pointer(&b)).Data
+	asHeader.Len = len(b)
+
+	// Clone should make a copy of as, since it is in the arena.
+	asCopy := UserArenaClone(as)
+	if (*reflect.StringHeader)(unsafe.Pointer(&as)).Data == (*reflect.StringHeader)(unsafe.Pointer(&asCopy)).Data {
+		t.Error("Clone did not make a copy")
+	}
+
+	// Clone should make a copy of subAs, since subAs is just part of as and so is in the arena.
+	subAs := as[1:3]
+	subAsCopy := UserArenaClone(subAs)
+	if (*reflect.StringHeader)(unsafe.Pointer(&subAs)).Data == (*reflect.StringHeader)(unsafe.Pointer(&subAsCopy)).Data {
+		t.Error("Clone did not make a copy")
+	}
+	if len(subAs) != len(subAsCopy) {
+		t.Errorf("Clone made an incorrect copy (bad length): %d -> %d", len(subAs), len(subAsCopy))
+	} else {
+		for i := range subAs {
+			if subAs[i] != subAsCopy[i] {
+				t.Errorf("Clone made an incorrect copy (data at index %d): %d -> %d", i, subAs[i], subAs[i])
+			}
+		}
+	}
+
+	// Clone should not make a copy of doubleAs, since doubleAs will be on the heap.
+	doubleAs := as + as
+	doubleAsCopy := UserArenaClone(doubleAs)
+	if (*reflect.StringHeader)(unsafe.Pointer(&doubleAs)).Data != (*reflect.StringHeader)(unsafe.Pointer(&doubleAsCopy)).Data {
+		t.Error("Clone should not have made a copy")
+	}
+
+	// Clone should not make a copy of s, since s is a static string.
+	sCopy := UserArenaClone(s)
+	if (*reflect.StringHeader)(unsafe.Pointer(&s)).Data != (*reflect.StringHeader)(unsafe.Pointer(&sCopy)).Data {
+		t.Error("Clone should not have made a copy")
+	}
+
+	a.Free()
+}
+
+func TestUserArenaClonePointer(t *testing.T) {
+	a := NewUserArena()
+
+	// Clone should not make a copy of a heap-allocated smallScalar.
+	x := Escape(new(smallScalar))
+	xCopy := UserArenaClone(x)
+	if unsafe.Pointer(x) != unsafe.Pointer(xCopy) {
+		t.Errorf("Clone should not have made a copy: %#v -> %#v", x, xCopy)
+	}
+
+	// Clone should make a copy of an arena-allocated smallScalar.
+	var i any
+	i = (*smallScalar)(nil)
+	a.New(&i)
+	xArena := i.(*smallScalar)
+	xArenaCopy := UserArenaClone(xArena)
+	if unsafe.Pointer(xArena) == unsafe.Pointer(xArenaCopy) {
+		t.Errorf("Clone should have made a copy: %#v -> %#v", xArena, xArenaCopy)
+	}
+	if *xArena != *xArenaCopy {
+		t.Errorf("Clone made an incorrect copy copy: %#v -> %#v", *xArena, *xArenaCopy)
+	}
+
+	a.Free()
+}
+
+func TestUserArenaCloneSlice(t *testing.T) {
+	a := NewUserArena()
+
+	// A static string (not on heap or arena)
+	var s = "klmnopqrstuv"
+
+	// Create a byte slice in the arena, initialize it with s
+	var b []byte
+	a.Slice(&b, len(s))
+	copy(b, s)
+
+	// Clone should make a copy of b, since it is in the arena.
+	bCopy := UserArenaClone(b)
+	if unsafe.Pointer(&b[0]) == unsafe.Pointer(&bCopy[0]) {
+		t.Errorf("Clone did not make a copy: %#v -> %#v", b, bCopy)
+	}
+	if len(b) != len(bCopy) {
+		t.Errorf("Clone made an incorrect copy (bad length): %d -> %d", len(b), len(bCopy))
+	} else {
+		for i := range b {
+			if b[i] != bCopy[i] {
+				t.Errorf("Clone made an incorrect copy (data at index %d): %d -> %d", i, b[i], bCopy[i])
+			}
+		}
+	}
+
+	// Clone should make a copy of bSub, since bSub is just part of b and so is in the arena.
+	bSub := b[1:3]
+	bSubCopy := UserArenaClone(bSub)
+	if unsafe.Pointer(&bSub[0]) == unsafe.Pointer(&bSubCopy[0]) {
+		t.Errorf("Clone did not make a copy: %#v -> %#v", bSub, bSubCopy)
+	}
+	if len(bSub) != len(bSubCopy) {
+		t.Errorf("Clone made an incorrect copy (bad length): %d -> %d", len(bSub), len(bSubCopy))
+	} else {
+		for i := range bSub {
+			if bSub[i] != bSubCopy[i] {
+				t.Errorf("Clone made an incorrect copy (data at index %d): %d -> %d", i, bSub[i], bSubCopy[i])
+			}
+		}
+	}
+
+	// Clone should not make a copy of bNotArena, since it will not be in an arena.
+	bNotArena := make([]byte, len(s))
+	copy(bNotArena, s)
+	bNotArenaCopy := UserArenaClone(bNotArena)
+	if unsafe.Pointer(&bNotArena[0]) != unsafe.Pointer(&bNotArenaCopy[0]) {
+		t.Error("Clone should not have made a copy")
+	}
+
+	a.Free()
+}
+
+func TestUserArenaClonePanic(t *testing.T) {
+	var s string
+	func() {
+		x := smallScalar{2}
+		defer func() {
+			if v := recover(); v != nil {
+				s = v.(string)
+			}
+		}()
+		UserArenaClone(x)
+	}()
+	if s == "" {
+		t.Errorf("expected panic from Clone")
+	}
+}
diff --git a/src/runtime/asan/asan.go b/src/runtime/asan/asan.go
index 4359f41..25f15ae 100644
--- a/src/runtime/asan/asan.go
+++ b/src/runtime/asan/asan.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build asan && linux && (arm64 || amd64 || riscv64)
+//go:build asan && linux && (arm64 || amd64 || riscv64 || ppc64le)
 
 package asan
 
@@ -34,7 +34,7 @@
 	__asan_poison_memory_region(addr, sz);
 }
 
-// Keep in sync with the defination in compiler-rt
+// Keep in sync with the definition in compiler-rt
 // https://github.com/llvm/llvm-project/blob/main/compiler-rt/lib/asan/asan_interface_internal.h#L41
 // This structure is used to describe the source location of
 // a place where global was defined.
@@ -44,7 +44,7 @@
 	int column_no;
 };
 
-// Keep in sync with the defination in compiler-rt
+// Keep in sync with the definition in compiler-rt
 // https://github.com/llvm/llvm-project/blob/main/compiler-rt/lib/asan/asan_interface_internal.h#L48
 // So far, the current implementation is only compatible with the ASan library from version v7 to v9.
 // https://github.com/llvm/llvm-project/blob/main/compiler-rt/lib/asan/asan_init_version.h
diff --git a/src/runtime/asan_ppc64le.s b/src/runtime/asan_ppc64le.s
new file mode 100644
index 0000000..d13301a
--- /dev/null
+++ b/src/runtime/asan_ppc64le.s
@@ -0,0 +1,87 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build asan
+
+#include "go_asm.h"
+#include "textflag.h"
+
+#define RARG0 R3
+#define RARG1 R4
+#define RARG2 R5
+#define RARG3 R6
+#define FARG R12
+
+// Called from instrumented code.
+// func runtime·doasanread(addr unsafe.Pointer, sz, sp, pc uintptr)
+TEXT	runtime·doasanread(SB),NOSPLIT|NOFRAME,$0-32
+	MOVD	addr+0(FP), RARG0
+	MOVD	sz+8(FP), RARG1
+	MOVD	sp+16(FP), RARG2
+	MOVD	pc+24(FP), RARG3
+	// void __asan_read_go(void *addr, uintptr_t sz, void *sp, void *pc);
+	MOVD	$__asan_read_go(SB), FARG
+	BR	asancall<>(SB)
+
+// func runtime·doasanwrite(addr unsafe.Pointer, sz, sp, pc uintptr)
+TEXT	runtime·doasanwrite(SB),NOSPLIT|NOFRAME,$0-32
+	MOVD	addr+0(FP), RARG0
+	MOVD	sz+8(FP), RARG1
+	MOVD	sp+16(FP), RARG2
+	MOVD	pc+24(FP), RARG3
+	// void __asan_write_go(void *addr, uintptr_t sz, void *sp, void *pc);
+	MOVD	$__asan_write_go(SB), FARG
+	BR	asancall<>(SB)
+
+// func runtime·asanunpoison(addr unsafe.Pointer, sz uintptr)
+TEXT	runtime·asanunpoison(SB),NOSPLIT|NOFRAME,$0-16
+	MOVD	addr+0(FP), RARG0
+	MOVD	sz+8(FP), RARG1
+	// void __asan_unpoison_go(void *addr, uintptr_t sz);
+	MOVD	$__asan_unpoison_go(SB), FARG
+	BR	asancall<>(SB)
+
+// func runtime·asanpoison(addr unsafe.Pointer, sz uintptr)
+TEXT	runtime·asanpoison(SB),NOSPLIT|NOFRAME,$0-16
+	MOVD	addr+0(FP), RARG0
+	MOVD	sz+8(FP), RARG1
+	// void __asan_poison_go(void *addr, uintptr_t sz);
+	MOVD	$__asan_poison_go(SB), FARG
+	BR	asancall<>(SB)
+
+// func runtime·asanregisterglobals(addr unsafe.Pointer, n uintptr)
+TEXT	runtime·asanregisterglobals(SB),NOSPLIT|NOFRAME,$0-16
+	MOVD	addr+0(FP), RARG0
+	MOVD	n+8(FP), RARG1
+	// void __asan_register_globals_go(void *addr, uintptr_t n);
+	MOVD	$__asan_register_globals_go(SB), FARG
+	BR	asancall<>(SB)
+
+// Switches SP to g0 stack and calls (FARG). Arguments already set.
+TEXT	asancall<>(SB), NOSPLIT, $0-0
+	// LR saved in generated prologue
+	// Get info from the current goroutine
+	MOVD	runtime·tls_g(SB), R10  // g offset in TLS
+	MOVD	0(R10), g
+	MOVD	g_m(g), R7		// m for g
+	MOVD	R1, R16			// callee-saved, preserved across C call
+	MOVD	m_g0(R7), R10		// g0 for m
+	CMP	R10, g			// same g0?
+	BEQ	call			// already on g0
+	MOVD	(g_sched+gobuf_sp)(R10), R1 // switch R1
+call:
+	// prepare frame for C ABI
+	SUB	$32, R1			// create frame for callee saving LR, CR, R2 etc.
+	RLDCR	$0, R1, $~15, R1	// align SP to 16 bytes
+	MOVD	FARG, CTR		// address of function to be called
+	MOVD	R0, 0(R1)		// clear back chain pointer
+	BL	(CTR)
+	MOVD	$0, R0			// C code can clobber R0 set it back to 0
+	MOVD	R16, R1			// restore R1;
+	MOVD	runtime·tls_g(SB), R10	// find correct g
+	MOVD	0(R10), g
+	RET
+
+// tls_g, g value for each thread in TLS
+GLOBL runtime·tls_g+0(SB), TLSBSS+DUPOK, $8
diff --git a/src/runtime/asm_amd64.h b/src/runtime/asm_amd64.h
index 49e0ee2..f7a8896 100644
--- a/src/runtime/asm_amd64.h
+++ b/src/runtime/asm_amd64.h
@@ -5,10 +5,21 @@
 // Define features that are guaranteed to be supported by setting the AMD64 variable.
 // If a feature is supported, there's no need to check it at runtime every time.
 
+#ifdef GOAMD64_v2
+#define hasPOPCNT
+#define hasSSE42
+#endif
+
 #ifdef GOAMD64_v3
+#define hasAVX
 #define hasAVX2
+#define hasPOPCNT
+#define hasSSE42
 #endif
 
 #ifdef GOAMD64_v4
+#define hasAVX
 #define hasAVX2
+#define hasPOPCNT
+#define hasSSE42
 #endif
diff --git a/src/runtime/asm_amd64.s b/src/runtime/asm_amd64.s
index d2f7984..13c8de4 100644
--- a/src/runtime/asm_amd64.s
+++ b/src/runtime/asm_amd64.s
@@ -201,16 +201,16 @@
 	JZ	needtls
 	// arg 1: g0, already in DI
 	MOVQ	$setg_gcc<>(SB), SI // arg 2: setg_gcc
+	MOVQ	$0, DX	// arg 3, 4: not used when using platform's TLS
+	MOVQ	$0, CX
 #ifdef GOOS_android
 	MOVQ	$runtime·tls_g(SB), DX 	// arg 3: &tls_g
 	// arg 4: TLS base, stored in slot 0 (Android's TLS_SLOT_SELF).
 	// Compensate for tls_g (+16).
 	MOVQ	-16(TLS), CX
-#else
-	MOVQ	$0, DX	// arg 3, 4: not used when using platform's TLS
-	MOVQ	$0, CX
 #endif
 #ifdef GOOS_windows
+	MOVQ	$runtime·tls_g(SB), DX 	// arg 3: &tls_g
 	// Adjust for the Win64 calling convention.
 	MOVQ	CX, R9 // arg 4
 	MOVQ	DX, R8 // arg 3
@@ -251,6 +251,10 @@
 	JMP ok
 #endif
 
+#ifdef GOOS_windows
+	CALL	runtime·wintls(SB)
+#endif
+
 	LEAQ	runtime·m0+m_tls(SB), DI
 	CALL	runtime·settls(SB)
 
@@ -2026,6 +2030,9 @@
 DATA runtime·tls_g+0(SB)/8, $16
 GLOBL runtime·tls_g+0(SB), NOPTR, $8
 #endif
+#ifdef GOOS_windows
+GLOBL runtime·tls_g+0(SB), NOPTR, $8
+#endif
 
 // The compiler and assembler's -spectre=ret mode rewrites
 // all indirect CALL AX / JMP AX instructions to be
diff --git a/src/runtime/asm_arm.s b/src/runtime/asm_arm.s
index b47184e..591ef2a 100644
--- a/src/runtime/asm_arm.s
+++ b/src/runtime/asm_arm.s
@@ -387,6 +387,13 @@
 	RET
 
 TEXT runtime·morestack_noctxt(SB),NOSPLIT|NOFRAME,$0-0
+	// Force SPWRITE. This function doesn't actually write SP,
+	// but it is called with a special calling convention where
+	// the caller doesn't save LR on stack but passes it as a
+	// register (R3), and the unwinder currently doesn't understand.
+	// Make it SPWRITE to stop unwinding. (See issue 54332)
+	MOVW	R13, R13
+
 	MOVW	$0, R7
 	B runtime·morestack(SB)
 
diff --git a/src/runtime/asm_arm64.s b/src/runtime/asm_arm64.s
index 7836ba1..7eb5bcf 100644
--- a/src/runtime/asm_arm64.s
+++ b/src/runtime/asm_arm64.s
@@ -320,6 +320,13 @@
 	UNDEF
 
 TEXT runtime·morestack_noctxt(SB),NOSPLIT|NOFRAME,$0-0
+	// Force SPWRITE. This function doesn't actually write SP,
+	// but it is called with a special calling convention where
+	// the caller doesn't save LR on stack but passes it as a
+	// register (R3), and the unwinder currently doesn't understand.
+	// Make it SPWRITE to stop unwinding. (See issue 54332)
+	MOVD	RSP, RSP
+
 	MOVW	$0, R26
 	B runtime·morestack(SB)
 
diff --git a/src/runtime/asm_mips64x.s b/src/runtime/asm_mips64x.s
index 3597ebe..1abadb9 100644
--- a/src/runtime/asm_mips64x.s
+++ b/src/runtime/asm_mips64x.s
@@ -258,6 +258,13 @@
 	UNDEF
 
 TEXT runtime·morestack_noctxt(SB),NOSPLIT|NOFRAME,$0-0
+	// Force SPWRITE. This function doesn't actually write SP,
+	// but it is called with a special calling convention where
+	// the caller doesn't save LR on stack but passes it as a
+	// register (R3), and the unwinder currently doesn't understand.
+	// Make it SPWRITE to stop unwinding. (See issue 54332)
+	MOVV	R29, R29
+
 	MOVV	R0, REGCTXT
 	JMP	runtime·morestack(SB)
 
diff --git a/src/runtime/asm_mipsx.s b/src/runtime/asm_mipsx.s
index 4a086b8..877c1bb 100644
--- a/src/runtime/asm_mipsx.s
+++ b/src/runtime/asm_mipsx.s
@@ -257,6 +257,13 @@
 	UNDEF
 
 TEXT runtime·morestack_noctxt(SB),NOSPLIT,$0-0
+	// Force SPWRITE. This function doesn't actually write SP,
+	// but it is called with a special calling convention where
+	// the caller doesn't save LR on stack but passes it as a
+	// register (R3), and the unwinder currently doesn't understand.
+	// Make it SPWRITE to stop unwinding. (See issue 54332)
+	MOVW	R29, R29
+
 	MOVW	R0, REGCTXT
 	JMP	runtime·morestack(SB)
 
diff --git a/src/runtime/asm_ppc64x.s b/src/runtime/asm_ppc64x.s
index c6bcf82..61ff17a 100644
--- a/src/runtime/asm_ppc64x.s
+++ b/src/runtime/asm_ppc64x.s
@@ -334,6 +334,16 @@
 	UNDEF
 
 TEXT runtime·morestack_noctxt(SB),NOSPLIT|NOFRAME,$0-0
+	// Force SPWRITE. This function doesn't actually write SP,
+	// but it is called with a special calling convention where
+	// the caller doesn't save LR on stack but passes it as a
+	// register (R5), and the unwinder currently doesn't understand.
+	// Make it SPWRITE to stop unwinding. (See issue 54332)
+	// Use OR R0, R1 instead of MOVD R1, R1 as the MOVD instruction
+	// has a special affect on Power8,9,10 by lowering the thread 
+	// priority and causing a slowdown in execution time
+
+	OR	R0, R1
 	MOVD	R0, R11
 	BR	runtime·morestack(SB)
 
diff --git a/src/runtime/asm_riscv64.s b/src/runtime/asm_riscv64.s
index 00caa9f..31b81ae 100644
--- a/src/runtime/asm_riscv64.s
+++ b/src/runtime/asm_riscv64.s
@@ -158,8 +158,8 @@
  */
 
 // Called during function prolog when more stack is needed.
-// Caller has already loaded:
-// R1: framesize, R2: argsize, R3: LR
+// Called with return address (i.e. caller's PC) in X5 (aka T0),
+// and the LR register contains the caller's LR.
 //
 // The traceback routines see morestack on a g0 as being
 // the top of a stack (for example, morestack calling newstack
@@ -209,6 +209,13 @@
 
 // func morestack_noctxt()
 TEXT runtime·morestack_noctxt(SB),NOSPLIT|NOFRAME,$0-0
+	// Force SPWRITE. This function doesn't actually write SP,
+	// but it is called with a special calling convention where
+	// the caller doesn't save LR on stack but passes it as a
+	// register, and the unwinder currently doesn't understand.
+	// Make it SPWRITE to stop unwinding. (See issue 54332)
+	MOV	X2, X2
+
 	MOV	ZERO, CTXT
 	JMP	runtime·morestack(SB)
 
@@ -261,11 +268,7 @@
 
 // func mcall(fn func(*g))
 TEXT runtime·mcall<ABIInternal>(SB), NOSPLIT|NOFRAME, $0-8
-#ifdef GOEXPERIMENT_regabiargs
 	MOV	X10, CTXT
-#else
-	MOV	fn+0(FP), CTXT
-#endif
 
 	// Save caller state in g->sched
 	MOV	X2, (g_sched+gobuf_sp)(g)
@@ -637,7 +640,6 @@
 	MOV	T0, ret+0(FP)
 	RET
 
-#ifdef GOEXPERIMENT_regabiargs
 // spillArgs stores return values from registers to a *internal/abi.RegArgs in X25.
 TEXT ·spillArgs(SB),NOSPLIT,$0-0
 	MOV	X10, (0*8)(X25)
@@ -709,13 +711,6 @@
 	MOVD	(30*8)(X25), F22
 	MOVD	(31*8)(X25), F23
 	RET
-#else
-TEXT ·spillArgs(SB),NOSPLIT,$0-0
-	RET
-
-TEXT ·unspillArgs(SB),NOSPLIT,$0-0
-	RET
-#endif
 
 // gcWriteBarrier performs a heap pointer write and informs the GC.
 //
@@ -825,157 +820,72 @@
 // corresponding runtime handler.
 // The tail call makes these stubs disappear in backtraces.
 TEXT runtime·panicIndex<ABIInternal>(SB),NOSPLIT,$0-16
-#ifdef GOEXPERIMENT_regabiargs
 	MOV	T0, X10
 	MOV	T1, X11
-#else
-	MOV	T0, x+0(FP)
-	MOV	T1, y+8(FP)
-#endif
 	JMP	runtime·goPanicIndex<ABIInternal>(SB)
 TEXT runtime·panicIndexU<ABIInternal>(SB),NOSPLIT,$0-16
-#ifdef GOEXPERIMENT_regabiargs
 	MOV	T0, X10
 	MOV	T1, X11
-#else
-	MOV	T0, x+0(FP)
-	MOV	T1, y+8(FP)
-#endif
 	JMP	runtime·goPanicIndexU<ABIInternal>(SB)
 TEXT runtime·panicSliceAlen<ABIInternal>(SB),NOSPLIT,$0-16
-#ifdef GOEXPERIMENT_regabiargs
 	MOV	T1, X10
 	MOV	T2, X11
-#else
-	MOV	T1, x+0(FP)
-	MOV	T2, y+8(FP)
-#endif
 	JMP	runtime·goPanicSliceAlen<ABIInternal>(SB)
 TEXT runtime·panicSliceAlenU<ABIInternal>(SB),NOSPLIT,$0-16
-#ifdef GOEXPERIMENT_regabiargs
 	MOV	T1, X10
 	MOV	T2, X11
-#else
-	MOV	T1, x+0(FP)
-	MOV	T2, y+8(FP)
-#endif
 	JMP	runtime·goPanicSliceAlenU<ABIInternal>(SB)
 TEXT runtime·panicSliceAcap<ABIInternal>(SB),NOSPLIT,$0-16
-#ifdef GOEXPERIMENT_regabiargs
 	MOV	T1, X10
 	MOV	T2, X11
-#else
-	MOV	T1, x+0(FP)
-	MOV	T2, y+8(FP)
-#endif
 	JMP	runtime·goPanicSliceAcap<ABIInternal>(SB)
 TEXT runtime·panicSliceAcapU<ABIInternal>(SB),NOSPLIT,$0-16
-#ifdef GOEXPERIMENT_regabiargs
 	MOV	T1, X10
 	MOV	T2, X11
-#else
-	MOV	T1, x+0(FP)
-	MOV	T2, y+8(FP)
-#endif
 	JMP	runtime·goPanicSliceAcapU<ABIInternal>(SB)
 TEXT runtime·panicSliceB<ABIInternal>(SB),NOSPLIT,$0-16
-#ifdef GOEXPERIMENT_regabiargs
 	MOV	T0, X10
 	MOV	T1, X11
-#else
-	MOV	T0, x+0(FP)
-	MOV	T1, y+8(FP)
-#endif
 	JMP	runtime·goPanicSliceB<ABIInternal>(SB)
 TEXT runtime·panicSliceBU<ABIInternal>(SB),NOSPLIT,$0-16
-#ifdef GOEXPERIMENT_regabiargs
 	MOV	T0, X10
 	MOV	T1, X11
-#else
-	MOV	T0, x+0(FP)
-	MOV	T1, y+8(FP)
-#endif
 	JMP	runtime·goPanicSliceBU<ABIInternal>(SB)
 TEXT runtime·panicSlice3Alen<ABIInternal>(SB),NOSPLIT,$0-16
-#ifdef GOEXPERIMENT_regabiargs
 	MOV	T2, X10
 	MOV	T3, X11
-#else
-	MOV	T2, x+0(FP)
-	MOV	T3, y+8(FP)
-#endif
 	JMP	runtime·goPanicSlice3Alen<ABIInternal>(SB)
 TEXT runtime·panicSlice3AlenU<ABIInternal>(SB),NOSPLIT,$0-16
-#ifdef GOEXPERIMENT_regabiargs
 	MOV	T2, X10
 	MOV	T3, X11
-#else
-	MOV	T2, x+0(FP)
-	MOV	T3, y+8(FP)
-#endif
 	JMP	runtime·goPanicSlice3AlenU<ABIInternal>(SB)
 TEXT runtime·panicSlice3Acap<ABIInternal>(SB),NOSPLIT,$0-16
-#ifdef GOEXPERIMENT_regabiargs
 	MOV	T2, X10
 	MOV	T3, X11
-#else
-	MOV	T2, x+0(FP)
-	MOV	T3, y+8(FP)
-#endif
 	JMP	runtime·goPanicSlice3Acap<ABIInternal>(SB)
 TEXT runtime·panicSlice3AcapU<ABIInternal>(SB),NOSPLIT,$0-16
-#ifdef GOEXPERIMENT_regabiargs
 	MOV	T2, X10
 	MOV	T3, X11
-#else
-	MOV	T2, x+0(FP)
-	MOV	T3, y+8(FP)
-#endif
 	JMP	runtime·goPanicSlice3AcapU<ABIInternal>(SB)
 TEXT runtime·panicSlice3B<ABIInternal>(SB),NOSPLIT,$0-16
-#ifdef GOEXPERIMENT_regabiargs
 	MOV	T1, X10
 	MOV	T2, X11
-#else
-	MOV	T1, x+0(FP)
-	MOV	T2, y+8(FP)
-#endif
 	JMP	runtime·goPanicSlice3B<ABIInternal>(SB)
 TEXT runtime·panicSlice3BU<ABIInternal>(SB),NOSPLIT,$0-16
-#ifdef GOEXPERIMENT_regabiargs
 	MOV	T1, X10
 	MOV	T2, X11
-#else
-	MOV	T1, x+0(FP)
-	MOV	T2, y+8(FP)
-#endif
 	JMP	runtime·goPanicSlice3BU<ABIInternal>(SB)
 TEXT runtime·panicSlice3C<ABIInternal>(SB),NOSPLIT,$0-16
-#ifdef GOEXPERIMENT_regabiargs
 	MOV	T0, X10
 	MOV	T1, X11
-#else
-	MOV	T0, x+0(FP)
-	MOV	T1, y+8(FP)
-#endif
 	JMP	runtime·goPanicSlice3C<ABIInternal>(SB)
 TEXT runtime·panicSlice3CU<ABIInternal>(SB),NOSPLIT,$0-16
-#ifdef GOEXPERIMENT_regabiargs
 	MOV	T0, X10
 	MOV	T1, X11
-#else
-	MOV	T0, x+0(FP)
-	MOV	T1, y+8(FP)
-#endif
 	JMP	runtime·goPanicSlice3CU<ABIInternal>(SB)
 TEXT runtime·panicSliceConvert<ABIInternal>(SB),NOSPLIT,$0-16
-#ifdef GOEXPERIMENT_regabiargs
 	MOV	T2, X10
 	MOV	T3, X11
-#else
-	MOV	T2, x+0(FP)
-	MOV	T3, y+8(FP)
-#endif
 	JMP	runtime·goPanicSliceConvert<ABIInternal>(SB)
 
 DATA	runtime·mainPC+0(SB)/8,$runtime·main<ABIInternal>(SB)
diff --git a/src/runtime/asm_s390x.s b/src/runtime/asm_s390x.s
index 9159a67..334e1aa 100644
--- a/src/runtime/asm_s390x.s
+++ b/src/runtime/asm_s390x.s
@@ -346,6 +346,13 @@
 	UNDEF
 
 TEXT runtime·morestack_noctxt(SB),NOSPLIT|NOFRAME,$0-0
+	// Force SPWRITE. This function doesn't actually write SP,
+	// but it is called with a special calling convention where
+	// the caller doesn't save LR on stack but passes it as a
+	// register (R5), and the unwinder currently doesn't understand.
+	// Make it SPWRITE to stop unwinding. (See issue 54332)
+	MOVD	R15, R15
+
 	MOVD	$0, R12
 	BR	runtime·morestack(SB)
 
diff --git a/src/runtime/asm_wasm.s b/src/runtime/asm_wasm.s
index d885da6..e075c72 100644
--- a/src/runtime/asm_wasm.s
+++ b/src/runtime/asm_wasm.s
@@ -320,10 +320,8 @@
 		I64Load stackArgs+16(FP); \
 		I32WrapI64; \
 		I64Load stackArgsSize+24(FP); \
-		I64Const $3; \
-		I64ShrU; \
 		I32WrapI64; \
-		Call runtime·wasmMove(SB); \
+		MemoryCopy; \
 	End; \
 	\
 	MOVD f+8(FP), CTXT; \
diff --git a/src/runtime/atomic_pointer.go b/src/runtime/atomic_pointer.go
index b8f0c22..25e0e65 100644
--- a/src/runtime/atomic_pointer.go
+++ b/src/runtime/atomic_pointer.go
@@ -35,6 +35,27 @@
 	atomic.StorepNoWB(noescape(ptr), new)
 }
 
+// atomic_storePointer is the implementation of runtime/internal/UnsafePointer.Store
+// (like StoreNoWB but with the write barrier).
+//
+//go:nosplit
+//go:linkname atomic_storePointer runtime/internal/atomic.storePointer
+func atomic_storePointer(ptr *unsafe.Pointer, new unsafe.Pointer) {
+	atomicstorep(unsafe.Pointer(ptr), new)
+}
+
+// atomic_casPointer is the implementation of runtime/internal/UnsafePointer.CompareAndSwap
+// (like CompareAndSwapNoWB but with the write barrier).
+//
+//go:nosplit
+//go:linkname atomic_casPointer runtime/internal/atomic.casPointer
+func atomic_casPointer(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool {
+	if writeBarrier.enabled {
+		atomicwb(ptr, new)
+	}
+	return atomic.Casp1(ptr, old, new)
+}
+
 // Like above, but implement in terms of sync/atomic's uintptr operations.
 // We cannot just call the runtime routines, because the race detector expects
 // to be able to intercept the sync/atomic forms but not the runtime forms.
diff --git a/src/runtime/cgo/cgo.go b/src/runtime/cgo/cgo.go
index 298aa63..b8473e5 100644
--- a/src/runtime/cgo/cgo.go
+++ b/src/runtime/cgo/cgo.go
@@ -23,9 +23,18 @@
 #cgo solaris LDFLAGS: -lxnet
 #cgo solaris LDFLAGS: -lsocket
 
-#cgo CFLAGS: -Wall -Werror
+// We use -fno-stack-protector because internal linking won't find
+// the support functions. See issues #52919 and #54313.
+#cgo CFLAGS: -Wall -Werror -fno-stack-protector
 
 #cgo solaris CPPFLAGS: -D_POSIX_PTHREAD_SEMANTICS
 
 */
 import "C"
+
+import "runtime/internal/sys"
+
+// Incomplete is used specifically for the semantics of incomplete C types.
+type Incomplete struct {
+	_ sys.NotInHeap
+}
diff --git a/src/runtime/cgo/gcc_386.S b/src/runtime/cgo/gcc_386.S
index ff55b2c..5e6d715 100644
--- a/src/runtime/cgo/gcc_386.S
+++ b/src/runtime/cgo/gcc_386.S
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+.file "gcc_386.S"
+
 /*
  * Apple still insists on underscore prefixes for C function names.
  */
diff --git a/src/runtime/cgo/gcc_aix_ppc64.S b/src/runtime/cgo/gcc_aix_ppc64.S
index a00fae2..a77363e 100644
--- a/src/runtime/cgo/gcc_aix_ppc64.S
+++ b/src/runtime/cgo/gcc_aix_ppc64.S
@@ -5,6 +5,8 @@
 // +build ppc64
 // +build aix
 
+.file "gcc_aix_ppc64.S"
+
 /*
  * void crosscall_ppc64(void (*fn)(void), void *g)
  *
diff --git a/src/runtime/cgo/gcc_amd64.S b/src/runtime/cgo/gcc_amd64.S
index 46699d1..5a1629e 100644
--- a/src/runtime/cgo/gcc_amd64.S
+++ b/src/runtime/cgo/gcc_amd64.S
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+.file "gcc_amd64.S"
+
 /*
  * Apple still insists on underscore prefixes for C function names.
  */
diff --git a/src/runtime/cgo/gcc_arm.S b/src/runtime/cgo/gcc_arm.S
index fe1c48b..6e8c14a 100644
--- a/src/runtime/cgo/gcc_arm.S
+++ b/src/runtime/cgo/gcc_arm.S
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+.file "gcc_arm.S"
+
 /*
  * Apple still insists on underscore prefixes for C function names.
  */
diff --git a/src/runtime/cgo/gcc_arm64.S b/src/runtime/cgo/gcc_arm64.S
index 9154d2a..865f67c 100644
--- a/src/runtime/cgo/gcc_arm64.S
+++ b/src/runtime/cgo/gcc_arm64.S
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+.file "gcc_arm64.S"
+
 /*
  * Apple still insists on underscore prefixes for C function names.
  */
diff --git a/src/runtime/cgo/gcc_darwin_amd64.c b/src/runtime/cgo/gcc_darwin_amd64.c
index d5b7fd8..955b81d 100644
--- a/src/runtime/cgo/gcc_darwin_amd64.c
+++ b/src/runtime/cgo/gcc_darwin_amd64.c
@@ -14,15 +14,12 @@
 void
 x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
 {
-	pthread_attr_t attr;
 	size_t size;
 
 	setg_gcc = setg;
 
-	pthread_attr_init(&attr);
-	pthread_attr_getstacksize(&attr, &size);
-	g->stacklo = (uintptr)&attr - size + 4096;
-	pthread_attr_destroy(&attr);
+	size = pthread_get_stacksize_np(pthread_self());
+	g->stacklo = (uintptr)&size - size + 4096;
 }
 
 
@@ -38,8 +35,9 @@
 	sigfillset(&ign);
 	pthread_sigmask(SIG_SETMASK, &ign, &oset);
 
+	size = pthread_get_stacksize_np(pthread_self());
 	pthread_attr_init(&attr);
-	pthread_attr_getstacksize(&attr, &size);
+	pthread_attr_setstacksize(&attr, size);
 	// Leave stacklo=0 and set stackhi=size; mstart will do the rest.
 	ts->g->stackhi = size;
 	err = _cgo_try_pthread_create(&p, &attr, threadentry, ts);
diff --git a/src/runtime/cgo/gcc_darwin_arm64.c b/src/runtime/cgo/gcc_darwin_arm64.c
index 24be675..5b77a42 100644
--- a/src/runtime/cgo/gcc_darwin_arm64.c
+++ b/src/runtime/cgo/gcc_darwin_arm64.c
@@ -36,8 +36,9 @@
 	sigfillset(&ign);
 	pthread_sigmask(SIG_SETMASK, &ign, &oset);
 
+	size = pthread_get_stacksize_np(pthread_self());
 	pthread_attr_init(&attr);
-	pthread_attr_getstacksize(&attr, &size);
+	pthread_attr_setstacksize(&attr, size);
 	// Leave stacklo=0 and set stackhi=size; mstart will do the rest.
 	ts->g->stackhi = size;
 	err = _cgo_try_pthread_create(&p, &attr, threadentry, ts);
@@ -126,15 +127,12 @@
 void
 x_cgo_init(G *g, void (*setg)(void*))
 {
-	pthread_attr_t attr;
 	size_t size;
 
 	//fprintf(stderr, "x_cgo_init = %p\n", &x_cgo_init); // aid debugging in presence of ASLR
 	setg_gcc = setg;
-	pthread_attr_init(&attr);
-	pthread_attr_getstacksize(&attr, &size);
-	g->stacklo = (uintptr)&attr - size + 4096;
-	pthread_attr_destroy(&attr);
+	size = pthread_get_stacksize_np(pthread_self());
+	g->stacklo = (uintptr)&size - size + 4096;
 
 #if TARGET_OS_IPHONE
 	darwin_arm_init_mach_exception_handler();
diff --git a/src/runtime/cgo/gcc_freebsd_riscv64.c b/src/runtime/cgo/gcc_freebsd_riscv64.c
new file mode 100644
index 0000000..6ce5e65
--- /dev/null
+++ b/src/runtime/cgo/gcc_freebsd_riscv64.c
@@ -0,0 +1,67 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include <sys/types.h>
+#include <errno.h>
+#include <sys/signalvar.h>
+#include <pthread.h>
+#include <signal.h>
+#include <string.h>
+#include "libcgo.h"
+#include "libcgo_unix.h"
+
+static void* threadentry(void*);
+static void (*setg_gcc)(void*);
+
+void
+x_cgo_init(G *g, void (*setg)(void*))
+{
+	pthread_attr_t attr;
+	size_t size;
+
+	setg_gcc = setg;
+	pthread_attr_init(&attr);
+	pthread_attr_getstacksize(&attr, &size);
+	g->stacklo = (uintptr)&attr - size + 4096;
+	pthread_attr_destroy(&attr);
+}
+
+void
+_cgo_sys_thread_start(ThreadStart *ts)
+{
+	pthread_attr_t attr;
+	sigset_t ign, oset;
+	pthread_t p;
+	size_t size;
+	int err;
+
+	SIGFILLSET(ign);
+	pthread_sigmask(SIG_SETMASK, &ign, &oset);
+
+	pthread_attr_init(&attr);
+	pthread_attr_getstacksize(&attr, &size);
+	// Leave stacklo=0 and set stackhi=size; mstart will do the rest.
+	ts->g->stackhi = size;
+	err = _cgo_try_pthread_create(&p, &attr, threadentry, ts);
+
+	pthread_sigmask(SIG_SETMASK, &oset, nil);
+
+	if (err != 0) {
+		fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
+		abort();
+	}
+}
+
+extern void crosscall1(void (*fn)(void), void (*setg_gcc)(void*), void *g);
+static void*
+threadentry(void *v)
+{
+	ThreadStart ts;
+
+	ts = *(ThreadStart*)v;
+	free(v);
+
+	crosscall1(ts.fn, setg_gcc, (void*)ts.g);
+	return nil;
+}
diff --git a/src/runtime/cgo/gcc_linux_ppc64x.S b/src/runtime/cgo/gcc_linux_ppc64x.S
index 595eb38..957ef3a 100644
--- a/src/runtime/cgo/gcc_linux_ppc64x.S
+++ b/src/runtime/cgo/gcc_linux_ppc64x.S
@@ -5,6 +5,8 @@
 // +build ppc64 ppc64le
 // +build linux
 
+.file "gcc_linux_ppc64x.S"
+
 /*
  * Apple still insists on underscore prefixes for C function names.
  */
diff --git a/src/runtime/cgo/gcc_loong64.S b/src/runtime/cgo/gcc_loong64.S
index 100aa33..6b7668f 100644
--- a/src/runtime/cgo/gcc_loong64.S
+++ b/src/runtime/cgo/gcc_loong64.S
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+.file "gcc_loong64.S"
+
 /*
  * void crosscall1(void (*fn)(void), void (*setg_gcc)(void *g), void *g)
  *
diff --git a/src/runtime/cgo/gcc_mips64x.S b/src/runtime/cgo/gcc_mips64x.S
index 908dd21..ec24d71 100644
--- a/src/runtime/cgo/gcc_mips64x.S
+++ b/src/runtime/cgo/gcc_mips64x.S
@@ -4,6 +4,8 @@
 
 // +build mips64 mips64le
 
+.file "gcc_mips64x.S"
+
 /*
  * void crosscall1(void (*fn)(void), void (*setg_gcc)(void *g), void *g)
  *
diff --git a/src/runtime/cgo/gcc_mipsx.S b/src/runtime/cgo/gcc_mipsx.S
index 54f4b82..2867f6a 100644
--- a/src/runtime/cgo/gcc_mipsx.S
+++ b/src/runtime/cgo/gcc_mipsx.S
@@ -4,6 +4,8 @@
 
 // +build mips mipsle
 
+.file "gcc_mipsx.S"
+
 /*
  * void crosscall1(void (*fn)(void), void (*setg_gcc)(void *g), void *g)
  *
diff --git a/src/runtime/cgo/gcc_mmap.c b/src/runtime/cgo/gcc_mmap.c
index 698a7e3..83d857f 100644
--- a/src/runtime/cgo/gcc_mmap.c
+++ b/src/runtime/cgo/gcc_mmap.c
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build linux,amd64 linux,arm64 linux,ppc64le
+// +build linux,amd64 linux,arm64 linux,ppc64le freebsd,amd64
 
 #include <errno.h>
 #include <stdint.h>
diff --git a/src/runtime/cgo/gcc_riscv64.S b/src/runtime/cgo/gcc_riscv64.S
index f429dc6..8f07649 100644
--- a/src/runtime/cgo/gcc_riscv64.S
+++ b/src/runtime/cgo/gcc_riscv64.S
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+.file "gcc_riscv64.S"
+
 /*
  * void crosscall1(void (*fn)(void), void (*setg_gcc)(void *g), void *g)
  *
diff --git a/src/runtime/cgo/gcc_s390x.S b/src/runtime/cgo/gcc_s390x.S
index 614de4b..8bd30fe 100644
--- a/src/runtime/cgo/gcc_s390x.S
+++ b/src/runtime/cgo/gcc_s390x.S
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+.file "gcc_s390x.S"
+
 /*
  * void crosscall_s390x(void (*fn)(void), void *g)
  *
diff --git a/src/runtime/cgo/gcc_windows_amd64.c b/src/runtime/cgo/gcc_windows_amd64.c
index 996947e..3ff3c64 100644
--- a/src/runtime/cgo/gcc_windows_amd64.c
+++ b/src/runtime/cgo/gcc_windows_amd64.c
@@ -13,11 +13,13 @@
 
 static void threadentry(void*);
 static void (*setg_gcc)(void*);
+static DWORD *tls_g;
 
 void
 x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
 {
 	setg_gcc = setg;
+	tls_g = (DWORD *)tlsg;
 }
 
 
@@ -41,8 +43,8 @@
 	 * Set specific keys in thread local storage.
 	 */
 	asm volatile (
-	  "movq %0, %%gs:0x28\n"	// MOVL tls0, 0x28(GS)
-	  :: "r"(ts.tls)
+	  "movq %0, %%gs:0(%1)\n"	// MOVL tls0, 0(tls_g)(GS)
+	  :: "r"(ts.tls), "r"(*tls_g)
 	);
 
 	crosscall_amd64(ts.fn, setg_gcc, (void*)ts.g);
diff --git a/src/runtime/cgo/mmap.go b/src/runtime/cgo/mmap.go
index eae0a9e..2f7e83b 100644
--- a/src/runtime/cgo/mmap.go
+++ b/src/runtime/cgo/mmap.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build (linux && amd64) || (linux && arm64)
+//go:build (linux && amd64) || (linux && arm64) || (freebsd && amd64)
 
 package cgo
 
diff --git a/src/runtime/cgo_mmap.go b/src/runtime/cgo_mmap.go
index 4cb3e65..30660f7 100644
--- a/src/runtime/cgo_mmap.go
+++ b/src/runtime/cgo_mmap.go
@@ -4,7 +4,7 @@
 
 // Support for memory sanitizer. See runtime/cgo/mmap.go.
 
-//go:build (linux && amd64) || (linux && arm64)
+//go:build (linux && amd64) || (linux && arm64) || (freebsd && amd64)
 
 package runtime
 
diff --git a/src/runtime/cgocall.go b/src/runtime/cgocall.go
index 892654e..9c75280 100644
--- a/src/runtime/cgocall.go
+++ b/src/runtime/cgocall.go
@@ -86,7 +86,6 @@
 
 import (
 	"internal/goarch"
-	"runtime/internal/atomic"
 	"runtime/internal/sys"
 	"unsafe"
 )
@@ -259,7 +258,7 @@
 	// We must still stay on the same m.
 	defer unlockOSThread()
 
-	if gp.m.needextram || atomic.Load(&extraMWaiters) > 0 {
+	if gp.m.needextram || extraMWaiters.Load() > 0 {
 		gp.m.needextram = false
 		systemstack(newextram)
 	}
@@ -347,12 +346,12 @@
 	}
 }
 
-// called from assembly
+// called from assembly.
 func badcgocallback() {
 	throw("misaligned stack in cgocallback")
 }
 
-// called from (incomplete) assembly
+// called from (incomplete) assembly.
 func cgounimpl() {
 	throw("cgo not implemented")
 }
@@ -568,17 +567,16 @@
 		if base == 0 {
 			return
 		}
-		hbits := heapBitsForAddr(base)
 		n := span.elemsize
-		for i = uintptr(0); i < n; i += goarch.PtrSize {
-			if !hbits.morePointers() {
-				// No more possible pointers.
+		hbits := heapBitsForAddr(base, n)
+		for {
+			var addr uintptr
+			if hbits, addr = hbits.next(); addr == 0 {
 				break
 			}
-			if hbits.isPointer() && cgoIsGoPointer(*(*unsafe.Pointer)(unsafe.Pointer(base + i))) {
+			if cgoIsGoPointer(*(*unsafe.Pointer)(unsafe.Pointer(addr))) {
 				panic(errorString(msg))
 			}
-			hbits = hbits.next()
 		}
 
 		return
diff --git a/src/runtime/cgocheck.go b/src/runtime/cgocheck.go
index 74a2ec0..84e7516 100644
--- a/src/runtime/cgocheck.go
+++ b/src/runtime/cgocheck.go
@@ -32,14 +32,14 @@
 
 	// If we are running on the system stack then dst might be an
 	// address on the stack, which is OK.
-	g := getg()
-	if g == g.m.g0 || g == g.m.gsignal {
+	gp := getg()
+	if gp == gp.m.g0 || gp == gp.m.gsignal {
 		return
 	}
 
 	// Allocating memory can write to various mfixalloc structs
 	// that look like they are non-Go memory.
-	if g.m.mallocing != 0 {
+	if gp.m.mallocing != 0 {
 		return
 	}
 
@@ -153,16 +153,16 @@
 
 	// src must be in the regular heap.
 
-	hbits := heapBitsForAddr(uintptr(src))
-	for i := uintptr(0); i < off+size; i += goarch.PtrSize {
-		bits := hbits.bits()
-		if i >= off && bits&bitPointer != 0 {
-			v := *(*unsafe.Pointer)(add(src, i))
-			if cgoIsGoPointer(v) {
-				throw(cgoWriteBarrierFail)
-			}
+	hbits := heapBitsForAddr(uintptr(src), size)
+	for {
+		var addr uintptr
+		if hbits, addr = hbits.next(); addr == 0 {
+			break
 		}
-		hbits = hbits.next()
+		v := *(*unsafe.Pointer)(unsafe.Pointer(addr))
+		if cgoIsGoPointer(v) {
+			throw(cgoWriteBarrierFail)
+		}
 	}
 }
 
diff --git a/src/runtime/chan.go b/src/runtime/chan.go
index ca516ad..6a0ad35 100644
--- a/src/runtime/chan.go
+++ b/src/runtime/chan.go
@@ -138,7 +138,7 @@
 	return c.qcount == c.dataqsiz
 }
 
-// entry point for c <- x from compiled code
+// entry point for c <- x from compiled code.
 //
 //go:nosplit
 func chansend1(c *hchan, elem unsafe.Pointer) {
@@ -255,7 +255,7 @@
 	// to park on a channel. The window between when this G's status
 	// changes and when we set gp.activeStackChans is not safe for
 	// stack shrinking.
-	atomic.Store8(&gp.parkingOnChan, 1)
+	gp.parkingOnChan.Store(true)
 	gopark(chanparkcommit, unsafe.Pointer(&c.lock), waitReasonChanSend, traceEvGoBlockSend, 2)
 	// Ensure the value being sent is kept alive until the
 	// receiver copies it out. The sudog has a pointer to the
@@ -435,7 +435,7 @@
 	return atomic.Loaduint(&c.qcount) == 0
 }
 
-// entry points for <- c from compiled code
+// entry points for <- c from compiled code.
 //
 //go:nosplit
 func chanrecv1(c *hchan, elem unsafe.Pointer) {
@@ -579,7 +579,7 @@
 	// to park on a channel. The window between when this G's status
 	// changes and when we set gp.activeStackChans is not safe for
 	// stack shrinking.
-	atomic.Store8(&gp.parkingOnChan, 1)
+	gp.parkingOnChan.Store(true)
 	gopark(chanparkcommit, unsafe.Pointer(&c.lock), waitReasonChanReceive, traceEvGoBlockRecv, 2)
 
 	// someone woke us up
@@ -664,7 +664,7 @@
 	// Mark that it's safe for stack shrinking to occur now,
 	// because any thread acquiring this G's stack for shrinking
 	// is guaranteed to observe activeStackChans after this store.
-	atomic.Store8(&gp.parkingOnChan, 0)
+	gp.parkingOnChan.Store(false)
 	// Make sure we unlock after setting activeStackChans and
 	// unsetting parkingOnChan. The moment we unlock chanLock
 	// we risk gp getting readied by a channel operation and
@@ -791,7 +791,7 @@
 		// We use a flag in the G struct to tell us when someone
 		// else has won the race to signal this goroutine but the goroutine
 		// hasn't removed itself from the queue yet.
-		if sgp.isSelect && !atomic.Cas(&sgp.g.selectDone, 0, 1) {
+		if sgp.isSelect && !sgp.g.selectDone.CompareAndSwap(0, 1) {
 			continue
 		}
 
diff --git a/src/runtime/checkptr_test.go b/src/runtime/checkptr_test.go
index 15011ec..811c0f0 100644
--- a/src/runtime/checkptr_test.go
+++ b/src/runtime/checkptr_test.go
@@ -39,6 +39,8 @@
 		{"CheckPtrSmall", "fatal error: checkptr: pointer arithmetic computed bad pointer value\n"},
 		{"CheckPtrSliceOK", ""},
 		{"CheckPtrSliceFail", "fatal error: checkptr: unsafe.Slice result straddles multiple allocations\n"},
+		{"CheckPtrStringOK", ""},
+		{"CheckPtrStringFail", "fatal error: checkptr: unsafe.String result straddles multiple allocations\n"},
 	}
 
 	for _, tc := range testCases {
diff --git a/src/runtime/coverage/apis.go b/src/runtime/coverage/apis.go
new file mode 100644
index 0000000..7d851f9
--- /dev/null
+++ b/src/runtime/coverage/apis.go
@@ -0,0 +1,178 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package coverage
+
+import (
+	"fmt"
+	"internal/coverage"
+	"io"
+	"reflect"
+	"sync/atomic"
+	"unsafe"
+)
+
+// WriteMetaDir writes a coverage meta-data file for the currently
+// running program to the directory specified in 'dir'. An error will
+// be returned if the operation can't be completed successfully (for
+// example, if the currently running program was not built with
+// "-cover", or if the directory does not exist).
+func WriteMetaDir(dir string) error {
+	if !finalHashComputed {
+		return fmt.Errorf("error: no meta-data available (binary not built with -cover?)")
+	}
+	return emitMetaDataToDirectory(dir, getCovMetaList())
+}
+
+// WriteMeta writes the meta-data content (the payload that would
+// normally be emitted to a meta-data file) for the currently running
+// program to the the writer 'w'. An error will be returned if the
+// operation can't be completed successfully (for example, if the
+// currently running program was not built with "-cover", or if a
+// write fails).
+func WriteMeta(w io.Writer) error {
+	if w == nil {
+		return fmt.Errorf("error: nil writer in WriteMeta")
+	}
+	if !finalHashComputed {
+		return fmt.Errorf("error: no meta-data available (binary not built with -cover?)")
+	}
+	ml := getCovMetaList()
+	return writeMetaData(w, ml, cmode, cgran, finalHash)
+}
+
+// WriteCountersDir writes a coverage counter-data file for the
+// currently running program to the directory specified in 'dir'. An
+// error will be returned if the operation can't be completed
+// successfully (for example, if the currently running program was not
+// built with "-cover", or if the directory does not exist). The
+// counter data written will be a snapshot taken at the point of the
+// call.
+func WriteCountersDir(dir string) error {
+	return emitCounterDataToDirectory(dir)
+}
+
+// WriteCounters writes coverage counter-data content for
+// the currently running program to the writer 'w'. An error will be
+// returned if the operation can't be completed successfully (for
+// example, if the currently running program was not built with
+// "-cover", or if a write fails). The counter data written will be a
+// snapshot taken at the point of the invocation.
+func WriteCounters(w io.Writer) error {
+	if w == nil {
+		return fmt.Errorf("error: nil writer in WriteCounters")
+	}
+	// Ask the runtime for the list of coverage counter symbols.
+	cl := getCovCounterList()
+	if len(cl) == 0 {
+		return fmt.Errorf("program not built with -cover")
+	}
+	if !finalHashComputed {
+		return fmt.Errorf("meta-data not written yet, unable to write counter data")
+	}
+
+	pm := getCovPkgMap()
+	s := &emitState{
+		counterlist: cl,
+		pkgmap:      pm,
+	}
+	return s.emitCounterDataToWriter(w)
+}
+
+// ClearCounters clears/resets all coverage counter variables in the
+// currently running program. It returns an error if the program in
+// question was not built with the "-cover" flag. Clearing of coverage
+// counters is also not supported for programs not using atomic
+// counter mode (see more detailed comments below for the rationale
+// here).
+func ClearCounters() error {
+	cl := getCovCounterList()
+	if len(cl) == 0 {
+		return fmt.Errorf("program not built with -cover")
+	}
+	if cmode != coverage.CtrModeAtomic {
+		return fmt.Errorf("ClearCounters invoked for program build with -covermode=%s (please use -covermode=atomic)", cmode.String())
+	}
+
+	// Implementation note: this function would be faster and simpler
+	// if we could just zero out the entire counter array, but for the
+	// moment we go through and zero out just the slots in the array
+	// corresponding to the counter values. We do this to avoid the
+	// following bad scenario: suppose that a user builds their Go
+	// program with "-cover", and that program has a function (call it
+	// main.XYZ) that invokes ClearCounters:
+	//
+	//     func XYZ() {
+	//       ... do some stuff ...
+	//       coverage.ClearCounters()
+	//       if someCondition {   <<--- HERE
+	//         ...
+	//       }
+	//     }
+	//
+	// At the point where ClearCounters executes, main.XYZ has not yet
+	// finished running, thus as soon as the call returns the line
+	// marked "HERE" above will trigger the writing of a non-zero
+	// value into main.XYZ's counter slab. However since we've just
+	// finished clearing the entire counter segment, we will have lost
+	// the values in the prolog portion of main.XYZ's counter slab
+	// (nctrs, pkgid, funcid). This means that later on at the end of
+	// program execution as we walk through the entire counter array
+	// for the program looking for executed functions, we'll zoom past
+	// main.XYZ's prolog (which was zero'd) and hit the non-zero
+	// counter value corresponding to the "HERE" block, which will
+	// then be interpreted as the start of another live function.
+	// Things will go downhill from there.
+	//
+	// This same scenario is also a potential risk if the program is
+	// running on an architecture that permits reordering of
+	// writes/stores, since the inconsistency described above could
+	// arise here. Example scenario:
+	//
+	//     func ABC() {
+	//       ...                    // prolog
+	//       if alwaysTrue() {
+	//         XYZ()                // counter update here
+	//       }
+	//     }
+	//
+	// In the instrumented version of ABC, the prolog of the function
+	// will contain a series of stores to the initial portion of the
+	// counter array to write number-of-counters, pkgid, funcid. Later
+	// in the function there is also a store to increment a counter
+	// for the block containing the call to XYZ(). If the CPU is
+	// allowed to reorder stores and decides to issue the XYZ store
+	// before the prolog stores, this could be observable as an
+	// inconsistency similar to the one above. Hence the requirement
+	// for atomic counter mode: according to package atomic docs,
+	// "...operations that happen in a specific order on one thread,
+	// will always be observed to happen in exactly that order by
+	// another thread". Thus we can be sure that there will be no
+	// inconsistency when reading the counter array from the thread
+	// running ClearCounters.
+
+	var sd []atomic.Uint32
+
+	bufHdr := (*reflect.SliceHeader)(unsafe.Pointer(&sd))
+	for _, c := range cl {
+		bufHdr.Data = uintptr(unsafe.Pointer(c.Counters))
+		bufHdr.Len = int(c.Len)
+		bufHdr.Cap = int(c.Len)
+		for i := 0; i < len(sd); i++ {
+			// Skip ahead until the next non-zero value.
+			sdi := sd[i].Load()
+			if sdi == 0 {
+				continue
+			}
+			// We found a function that was executed; clear its counters.
+			nCtrs := sdi
+			for j := 0; j < int(nCtrs); j++ {
+				sd[i+coverage.FirstCtrOffset+j].Store(0)
+			}
+			// Move to next function.
+			i += coverage.FirstCtrOffset + int(nCtrs) - 1
+		}
+	}
+	return nil
+}
diff --git a/src/runtime/coverage/dummy.s b/src/runtime/coverage/dummy.s
new file mode 100644
index 0000000..7592859
--- /dev/null
+++ b/src/runtime/coverage/dummy.s
@@ -0,0 +1,8 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// The runtime package uses //go:linkname to push a few functions into this
+// package but we still need a .s file so the Go tool does not pass -complete
+// to 'go tool compile' so the latter does not complain about Go functions
+// with no bodies.
diff --git a/src/runtime/coverage/emit.go b/src/runtime/coverage/emit.go
new file mode 100644
index 0000000..2aed99c
--- /dev/null
+++ b/src/runtime/coverage/emit.go
@@ -0,0 +1,667 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package coverage
+
+import (
+	"crypto/md5"
+	"fmt"
+	"internal/coverage"
+	"internal/coverage/encodecounter"
+	"internal/coverage/encodemeta"
+	"internal/coverage/rtcov"
+	"io"
+	"os"
+	"path/filepath"
+	"reflect"
+	"runtime"
+	"sync/atomic"
+	"time"
+	"unsafe"
+)
+
+// This file contains functions that support the writing of data files
+// emitted at the end of code coverage testing runs, from instrumented
+// executables.
+
+// getCovMetaList returns a list of meta-data blobs registered
+// for the currently executing instrumented program. It is defined in the
+// runtime.
+func getCovMetaList() []rtcov.CovMetaBlob
+
+// getCovCounterList returns a list of counter-data blobs registered
+// for the currently executing instrumented program. It is defined in the
+// runtime.
+func getCovCounterList() []rtcov.CovCounterBlob
+
+// getCovPkgMap returns a map storing the remapped package IDs for
+// hard-coded runtime packages (see internal/coverage/pkgid.go for
+// more on why hard-coded package IDs are needed). This function
+// is defined in the runtime.
+func getCovPkgMap() map[int]int
+
+// emitState holds useful state information during the emit process.
+//
+// When an instrumented program finishes execution and starts the
+// process of writing out coverage data, it's possible that an
+// existing meta-data file already exists in the output directory. In
+// this case openOutputFiles() below will leave the 'mf' field below
+// as nil. If a new meta-data file is needed, field 'mfname' will be
+// the final desired path of the meta file, 'mftmp' will be a
+// temporary file, and 'mf' will be an open os.File pointer for
+// 'mftmp'. The meta-data file payload will be written to 'mf', the
+// temp file will be then closed and renamed (from 'mftmp' to
+// 'mfname'), so as to insure that the meta-data file is created
+// atomically; we want this so that things work smoothly in cases
+// where there are several instances of a given instrumented program
+// all terminating at the same time and trying to create meta-data
+// files simultaneously.
+//
+// For counter data files there is less chance of a collision, hence
+// the openOutputFiles() stores the counter data file in 'cfname' and
+// then places the *io.File into 'cf'.
+type emitState struct {
+	mfname string   // path of final meta-data output file
+	mftmp  string   // path to meta-data temp file (if needed)
+	mf     *os.File // open os.File for meta-data temp file
+	cfname string   // path of final counter data file
+	cftmp  string   // path to counter data temp file
+	cf     *os.File // open os.File for counter data file
+	outdir string   // output directory
+
+	// List of meta-data symbols obtained from the runtime
+	metalist []rtcov.CovMetaBlob
+
+	// List of counter-data symbols obtained from the runtime
+	counterlist []rtcov.CovCounterBlob
+
+	// Table to use for remapping hard-coded pkg ids.
+	pkgmap map[int]int
+
+	// emit debug trace output
+	debug bool
+}
+
+var (
+	// finalHash is computed at init time from the list of meta-data
+	// symbols registered during init. It is used both for writing the
+	// meta-data file and counter-data files.
+	finalHash [16]byte
+	// Set to true when we've computed finalHash + finalMetaLen.
+	finalHashComputed bool
+	// Total meta-data length.
+	finalMetaLen uint64
+	// Records whether we've already attempted to write meta-data.
+	metaDataEmitAttempted bool
+	// Counter mode for this instrumented program run.
+	cmode coverage.CounterMode
+	// Counter granularity for this instrumented program run.
+	cgran coverage.CounterGranularity
+	// Cached value of GOCOVERDIR environment variable.
+	goCoverDir string
+	// Copy of os.Args made at init time, converted into map format.
+	capturedOsArgs map[string]string
+	// Flag used in tests to signal that coverage data already written.
+	covProfileAlreadyEmitted bool
+)
+
+// fileType is used to select between counter-data files and
+// meta-data files.
+type fileType int
+
+const (
+	noFile = 1 << iota
+	metaDataFile
+	counterDataFile
+)
+
+// emitMetaData emits the meta-data output file for this coverage run.
+// This entry point is intended to be invoked by the compiler from
+// an instrumented program's main package init func.
+func emitMetaData() {
+	if covProfileAlreadyEmitted {
+		return
+	}
+	ml, err := prepareForMetaEmit()
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "error: coverage meta-data prep failed: %v\n", err)
+		if os.Getenv("GOCOVERDEBUG") != "" {
+			panic("meta-data write failure")
+		}
+	}
+	if len(ml) == 0 {
+		fmt.Fprintf(os.Stderr, "program not built with -cover\n")
+		return
+	}
+
+	goCoverDir = os.Getenv("GOCOVERDIR")
+	if goCoverDir == "" {
+		fmt.Fprintf(os.Stderr, "warning: GOCOVERDIR not set, no coverage data emitted\n")
+		return
+	}
+
+	if err := emitMetaDataToDirectory(goCoverDir, ml); err != nil {
+		fmt.Fprintf(os.Stderr, "error: coverage meta-data emit failed: %v\n", err)
+		if os.Getenv("GOCOVERDEBUG") != "" {
+			panic("meta-data write failure")
+		}
+	}
+}
+
+func modeClash(m coverage.CounterMode) bool {
+	if m == coverage.CtrModeRegOnly || m == coverage.CtrModeTestMain {
+		return false
+	}
+	if cmode == coverage.CtrModeInvalid {
+		cmode = m
+		return false
+	}
+	return cmode != m
+}
+
+func granClash(g coverage.CounterGranularity) bool {
+	if cgran == coverage.CtrGranularityInvalid {
+		cgran = g
+		return false
+	}
+	return cgran != g
+}
+
+// prepareForMetaEmit performs preparatory steps needed prior to
+// emitting a meta-data file, notably computing a final hash of
+// all meta-data blobs and capturing os args.
+func prepareForMetaEmit() ([]rtcov.CovMetaBlob, error) {
+	// Ask the runtime for the list of coverage meta-data symbols.
+	ml := getCovMetaList()
+
+	// In the normal case (go build -o prog.exe ... ; ./prog.exe)
+	// len(ml) will always be non-zero, but we check here since at
+	// some point this function will be reachable via user-callable
+	// APIs (for example, to write out coverage data from a server
+	// program that doesn't ever call os.Exit).
+	if len(ml) == 0 {
+		return nil, nil
+	}
+
+	s := &emitState{
+		metalist: ml,
+		debug:    os.Getenv("GOCOVERDEBUG") != "",
+	}
+
+	// Capture os.Args() now so as to avoid issues if args
+	// are rewritten during program execution.
+	capturedOsArgs = captureOsArgs()
+
+	if s.debug {
+		fmt.Fprintf(os.Stderr, "=+= GOCOVERDIR is %s\n", os.Getenv("GOCOVERDIR"))
+		fmt.Fprintf(os.Stderr, "=+= contents of covmetalist:\n")
+		for k, b := range ml {
+			fmt.Fprintf(os.Stderr, "=+= slot: %d path: %s ", k, b.PkgPath)
+			if b.PkgID != -1 {
+				fmt.Fprintf(os.Stderr, " hcid: %d", b.PkgID)
+			}
+			fmt.Fprintf(os.Stderr, "\n")
+		}
+		pm := getCovPkgMap()
+		fmt.Fprintf(os.Stderr, "=+= remap table:\n")
+		for from, to := range pm {
+			fmt.Fprintf(os.Stderr, "=+= from %d to %d\n",
+				uint32(from), uint32(to))
+		}
+	}
+
+	h := md5.New()
+	tlen := uint64(unsafe.Sizeof(coverage.MetaFileHeader{}))
+	for _, entry := range ml {
+		if _, err := h.Write(entry.Hash[:]); err != nil {
+			return nil, err
+		}
+		tlen += uint64(entry.Len)
+		ecm := coverage.CounterMode(entry.CounterMode)
+		if modeClash(ecm) {
+			return nil, fmt.Errorf("coverage counter mode clash: package %s uses mode=%d, but package %s uses mode=%s\n", ml[0].PkgPath, cmode, entry.PkgPath, ecm)
+		}
+		ecg := coverage.CounterGranularity(entry.CounterGranularity)
+		if granClash(ecg) {
+			return nil, fmt.Errorf("coverage counter granularity clash: package %s uses gran=%d, but package %s uses gran=%s\n", ml[0].PkgPath, cgran, entry.PkgPath, ecg)
+		}
+	}
+
+	// Hash mode and granularity as well.
+	h.Write([]byte(cmode.String()))
+	h.Write([]byte(cgran.String()))
+
+	// Compute final digest.
+	fh := h.Sum(nil)
+	copy(finalHash[:], fh)
+	finalHashComputed = true
+	finalMetaLen = tlen
+
+	return ml, nil
+}
+
+// emitMetaData emits the meta-data output file to the specified
+// directory, returning an error if something went wrong.
+func emitMetaDataToDirectory(outdir string, ml []rtcov.CovMetaBlob) error {
+	ml, err := prepareForMetaEmit()
+	if err != nil {
+		return err
+	}
+	if len(ml) == 0 {
+		return nil
+	}
+
+	metaDataEmitAttempted = true
+
+	s := &emitState{
+		metalist: ml,
+		debug:    os.Getenv("GOCOVERDEBUG") != "",
+		outdir:   outdir,
+	}
+
+	// Open output files.
+	if err := s.openOutputFiles(finalHash, finalMetaLen, metaDataFile); err != nil {
+		return err
+	}
+
+	// Emit meta-data file only if needed (may already be present).
+	if s.needMetaDataFile() {
+		if err := s.emitMetaDataFile(finalHash, finalMetaLen); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// emitCounterData emits the counter data output file for this coverage run.
+// This entry point is intended to be invoked by the runtime when an
+// instrumented program is terminating or calling os.Exit().
+func emitCounterData() {
+	if goCoverDir == "" || !finalHashComputed || covProfileAlreadyEmitted {
+		return
+	}
+	if err := emitCounterDataToDirectory(goCoverDir); err != nil {
+		fmt.Fprintf(os.Stderr, "error: coverage counter data emit failed: %v\n", err)
+		if os.Getenv("GOCOVERDEBUG") != "" {
+			panic("counter-data write failure")
+		}
+	}
+}
+
+// emitMetaData emits the counter-data output file for this coverage run.
+func emitCounterDataToDirectory(outdir string) error {
+	// Ask the runtime for the list of coverage counter symbols.
+	cl := getCovCounterList()
+	if len(cl) == 0 {
+		// no work to do here.
+		return nil
+	}
+
+	if !finalHashComputed {
+		return fmt.Errorf("error: meta-data not available (binary not built with -cover?)")
+	}
+
+	// Ask the runtime for the list of coverage counter symbols.
+	pm := getCovPkgMap()
+	s := &emitState{
+		counterlist: cl,
+		pkgmap:      pm,
+		outdir:      outdir,
+		debug:       os.Getenv("GOCOVERDEBUG") != "",
+	}
+
+	// Open output file.
+	if err := s.openOutputFiles(finalHash, finalMetaLen, counterDataFile); err != nil {
+		return err
+	}
+	if s.cf == nil {
+		return fmt.Errorf("counter data output file open failed (no additional info")
+	}
+
+	// Emit counter data file.
+	if err := s.emitCounterDataFile(finalHash, s.cf); err != nil {
+		return err
+	}
+	if err := s.cf.Close(); err != nil {
+		return fmt.Errorf("closing counter data file: %v", err)
+	}
+
+	// Counter file has now been closed. Rename the temp to the
+	// final desired path.
+	if err := os.Rename(s.cftmp, s.cfname); err != nil {
+		return fmt.Errorf("writing %s: rename from %s failed: %v\n", s.cfname, s.cftmp, err)
+	}
+
+	return nil
+}
+
+// emitMetaData emits counter data for this coverage run to an io.Writer.
+func (s *emitState) emitCounterDataToWriter(w io.Writer) error {
+	if err := s.emitCounterDataFile(finalHash, w); err != nil {
+		return err
+	}
+	return nil
+}
+
+// openMetaFile determines whether we need to emit a meta-data output
+// file, or whether we can reuse the existing file in the coverage out
+// dir. It updates mfname/mftmp/mf fields in 's', returning an error
+// if something went wrong. See the comment on the emitState type
+// definition above for more on how file opening is managed.
+func (s *emitState) openMetaFile(metaHash [16]byte, metaLen uint64) error {
+
+	// Open meta-outfile for reading to see if it exists.
+	fn := fmt.Sprintf("%s.%x", coverage.MetaFilePref, metaHash)
+	s.mfname = filepath.Join(s.outdir, fn)
+	fi, err := os.Stat(s.mfname)
+	if err != nil || fi.Size() != int64(metaLen) {
+		// We need a new meta-file.
+		tname := "tmp." + fn + fmt.Sprintf("%d", time.Now().UnixNano())
+		s.mftmp = filepath.Join(s.outdir, tname)
+		s.mf, err = os.Create(s.mftmp)
+		if err != nil {
+			return fmt.Errorf("creating meta-data file %s: %v", s.mftmp, err)
+		}
+	}
+	return nil
+}
+
+// openCounterFile opens an output file for the counter data portion
+// of a test coverage run. If updates the 'cfname' and 'cf' fields in
+// 's', returning an error if something went wrong.
+func (s *emitState) openCounterFile(metaHash [16]byte) error {
+	processID := os.Getpid()
+	fn := fmt.Sprintf(coverage.CounterFileTempl, coverage.CounterFilePref, metaHash, processID, time.Now().UnixNano())
+	s.cfname = filepath.Join(s.outdir, fn)
+	s.cftmp = filepath.Join(s.outdir, "tmp."+fn)
+	var err error
+	s.cf, err = os.Create(s.cftmp)
+	if err != nil {
+		return fmt.Errorf("creating counter data file %s: %v", s.cftmp, err)
+	}
+	return nil
+}
+
+// openOutputFiles opens output files in preparation for emitting
+// coverage data. In the case of the meta-data file, openOutputFiles
+// may determine that we can reuse an existing meta-data file in the
+// outdir, in which case it will leave the 'mf' field in the state
+// struct as nil. If a new meta-file is needed, the field 'mfname'
+// will be the final desired path of the meta file, 'mftmp' will be a
+// temporary file, and 'mf' will be an open os.File pointer for
+// 'mftmp'. The idea is that the client/caller will write content into
+// 'mf', close it, and then rename 'mftmp' to 'mfname'. This function
+// also opens the counter data output file, setting 'cf' and 'cfname'
+// in the state struct.
+func (s *emitState) openOutputFiles(metaHash [16]byte, metaLen uint64, which fileType) error {
+	fi, err := os.Stat(s.outdir)
+	if err != nil {
+		return fmt.Errorf("output directory %q inaccessible (err: %v); no coverage data written", s.outdir, err)
+	}
+	if !fi.IsDir() {
+		return fmt.Errorf("output directory %q not a directory; no coverage data written", s.outdir)
+	}
+
+	if (which & metaDataFile) != 0 {
+		if err := s.openMetaFile(metaHash, metaLen); err != nil {
+			return err
+		}
+	}
+	if (which & counterDataFile) != 0 {
+		if err := s.openCounterFile(metaHash); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// emitMetaDataFile emits coverage meta-data to a previously opened
+// temporary file (s.mftmp), then renames the generated file to the
+// final path (s.mfname).
+func (s *emitState) emitMetaDataFile(finalHash [16]byte, tlen uint64) error {
+	if err := writeMetaData(s.mf, s.metalist, cmode, cgran, finalHash); err != nil {
+		return fmt.Errorf("writing %s: %v\n", s.mftmp, err)
+	}
+	if err := s.mf.Close(); err != nil {
+		return fmt.Errorf("closing meta data temp file: %v", err)
+	}
+
+	// Temp file has now been flushed and closed. Rename the temp to the
+	// final desired path.
+	if err := os.Rename(s.mftmp, s.mfname); err != nil {
+		return fmt.Errorf("writing %s: rename from %s failed: %v\n", s.mfname, s.mftmp, err)
+	}
+
+	return nil
+}
+
+// needMetaDataFile returns TRUE if we need to emit a meta-data file
+// for this program run. It should be used only after
+// openOutputFiles() has been invoked.
+func (s *emitState) needMetaDataFile() bool {
+	return s.mf != nil
+}
+
+func writeMetaData(w io.Writer, metalist []rtcov.CovMetaBlob, cmode coverage.CounterMode, gran coverage.CounterGranularity, finalHash [16]byte) error {
+	mfw := encodemeta.NewCoverageMetaFileWriter("<io.Writer>", w)
+
+	// Note: "sd" is re-initialized on each iteration of the loop
+	// below, and would normally be declared inside the loop, but
+	// placed here escape analysis since we capture it in bufHdr.
+	var sd []byte
+	bufHdr := (*reflect.SliceHeader)(unsafe.Pointer(&sd))
+
+	var blobs [][]byte
+	for _, e := range metalist {
+		bufHdr.Data = uintptr(unsafe.Pointer(e.P))
+		bufHdr.Len = int(e.Len)
+		bufHdr.Cap = int(e.Len)
+		blobs = append(blobs, sd)
+	}
+	return mfw.Write(finalHash, blobs, cmode, gran)
+}
+
+func (s *emitState) NumFuncs() (int, error) {
+	var sd []atomic.Uint32
+	bufHdr := (*reflect.SliceHeader)(unsafe.Pointer(&sd))
+
+	totalFuncs := 0
+	for _, c := range s.counterlist {
+		bufHdr.Data = uintptr(unsafe.Pointer(c.Counters))
+		bufHdr.Len = int(c.Len)
+		bufHdr.Cap = int(c.Len)
+		for i := 0; i < len(sd); i++ {
+			// Skip ahead until the next non-zero value.
+			sdi := sd[i].Load()
+			if sdi == 0 {
+				continue
+			}
+
+			// We found a function that was executed.
+			nCtrs := sdi
+
+			// Check to make sure that we have at least one live
+			// counter. See the implementation note in ClearCoverageCounters
+			// for a description of why this is needed.
+			isLive := false
+			st := i + coverage.FirstCtrOffset
+			counters := sd[st : st+int(nCtrs)]
+			for i := 0; i < len(counters); i++ {
+				if counters[i].Load() != 0 {
+					isLive = true
+					break
+				}
+			}
+			if !isLive {
+				// Skip this function.
+				i += coverage.FirstCtrOffset + int(nCtrs) - 1
+				continue
+			}
+
+			totalFuncs++
+
+			// Move to the next function.
+			i += coverage.FirstCtrOffset + int(nCtrs) - 1
+		}
+	}
+	return totalFuncs, nil
+}
+
+func (s *emitState) VisitFuncs(f encodecounter.CounterVisitorFn) error {
+	var sd []atomic.Uint32
+	var tcounters []uint32
+	bufHdr := (*reflect.SliceHeader)(unsafe.Pointer(&sd))
+
+	rdCounters := func(actrs []atomic.Uint32, ctrs []uint32) []uint32 {
+		ctrs = ctrs[:0]
+		for i := range actrs {
+			ctrs = append(ctrs, actrs[i].Load())
+		}
+		return ctrs
+	}
+
+	dpkg := uint32(0)
+	for _, c := range s.counterlist {
+		bufHdr.Data = uintptr(unsafe.Pointer(c.Counters))
+		bufHdr.Len = int(c.Len)
+		bufHdr.Cap = int(c.Len)
+		for i := 0; i < len(sd); i++ {
+			// Skip ahead until the next non-zero value.
+			sdi := sd[i].Load()
+			if sdi == 0 {
+				continue
+			}
+
+			// We found a function that was executed.
+			nCtrs := sd[i+coverage.NumCtrsOffset].Load()
+			pkgId := sd[i+coverage.PkgIdOffset].Load()
+			funcId := sd[i+coverage.FuncIdOffset].Load()
+			cst := i + coverage.FirstCtrOffset
+			counters := sd[cst : cst+int(nCtrs)]
+
+			// Check to make sure that we have at least one live
+			// counter. See the implementation note in ClearCoverageCounters
+			// for a description of why this is needed.
+			isLive := false
+			for i := 0; i < len(counters); i++ {
+				if counters[i].Load() != 0 {
+					isLive = true
+					break
+				}
+			}
+			if !isLive {
+				// Skip this function.
+				i += coverage.FirstCtrOffset + int(nCtrs) - 1
+				continue
+			}
+
+			if s.debug {
+				if pkgId != dpkg {
+					dpkg = pkgId
+					fmt.Fprintf(os.Stderr, "\n=+= %d: pk=%d visit live fcn",
+						i, pkgId)
+				}
+				fmt.Fprintf(os.Stderr, " {i=%d F%d NC%d}", i, funcId, nCtrs)
+			}
+
+			// Vet and/or fix up package ID. A package ID of zero
+			// indicates that there is some new package X that is a
+			// runtime dependency, and this package has code that
+			// executes before its corresponding init package runs.
+			// This is a fatal error that we should only see during
+			// Go development (e.g. tip).
+			ipk := int32(pkgId)
+			if ipk == 0 {
+				fmt.Fprintf(os.Stderr, "\n")
+				reportErrorInHardcodedList(int32(i), ipk, funcId, nCtrs)
+			} else if ipk < 0 {
+				if newId, ok := s.pkgmap[int(ipk)]; ok {
+					pkgId = uint32(newId)
+				} else {
+					fmt.Fprintf(os.Stderr, "\n")
+					reportErrorInHardcodedList(int32(i), ipk, funcId, nCtrs)
+				}
+			} else {
+				// The package ID value stored in the counter array
+				// has 1 added to it (so as to preclude the
+				// possibility of a zero value ; see
+				// runtime.addCovMeta), so subtract off 1 here to form
+				// the real package ID.
+				pkgId--
+			}
+
+			tcounters = rdCounters(counters, tcounters)
+			if err := f(pkgId, funcId, tcounters); err != nil {
+				return err
+			}
+
+			// Skip over this function.
+			i += coverage.FirstCtrOffset + int(nCtrs) - 1
+		}
+		if s.debug {
+			fmt.Fprintf(os.Stderr, "\n")
+		}
+	}
+	return nil
+}
+
+// captureOsArgs converts os.Args() into the format we use to store
+// this info in the counter data file (counter data file "args"
+// section is a generic key-value collection). See the 'args' section
+// in internal/coverage/defs.go for more info. The args map
+// is also used to capture GOOS + GOARCH values as well.
+func captureOsArgs() map[string]string {
+	m := make(map[string]string)
+	m["argc"] = fmt.Sprintf("%d", len(os.Args))
+	for k, a := range os.Args {
+		m[fmt.Sprintf("argv%d", k)] = a
+	}
+	m["GOOS"] = runtime.GOOS
+	m["GOARCH"] = runtime.GOARCH
+	return m
+}
+
+// emitCounterDataFile emits the counter data portion of a
+// coverage output file (to the file 's.cf').
+func (s *emitState) emitCounterDataFile(finalHash [16]byte, w io.Writer) error {
+	cfw := encodecounter.NewCoverageDataWriter(w, coverage.CtrULeb128)
+	if err := cfw.Write(finalHash, capturedOsArgs, s); err != nil {
+		return err
+	}
+	return nil
+}
+
+// markProfileEmitted signals the runtime/coverage machinery that
+// coverate data output files have already been written out, and there
+// is no need to take any additional action at exit time. This
+// function is called (via linknamed reference) from the
+// coverage-related boilerplate code in _testmain.go emitted for go
+// unit tests.
+func markProfileEmitted(val bool) {
+	covProfileAlreadyEmitted = val
+}
+
+func reportErrorInHardcodedList(slot, pkgID int32, fnID, nCtrs uint32) {
+	metaList := getCovMetaList()
+	pkgMap := getCovPkgMap()
+
+	println("internal error in coverage meta-data tracking:")
+	println("encountered bad pkgID:", pkgID, " at slot:", slot,
+		" fnID:", fnID, " numCtrs:", nCtrs)
+	println("list of hard-coded runtime package IDs needs revising.")
+	println("[see the comment on the 'rtPkgs' var in ")
+	println(" <goroot>/src/internal/coverage/pkid.go]")
+	println("registered list:")
+	for k, b := range metaList {
+		print("slot: ", k, " path='", b.PkgPath, "' ")
+		if b.PkgID != -1 {
+			print(" hard-coded id: ", b.PkgID)
+		}
+		println("")
+	}
+	println("remap table:")
+	for from, to := range pkgMap {
+		println("from ", from, " to ", to)
+	}
+}
diff --git a/src/runtime/coverage/emitdata_test.go b/src/runtime/coverage/emitdata_test.go
new file mode 100644
index 0000000..3839e44
--- /dev/null
+++ b/src/runtime/coverage/emitdata_test.go
@@ -0,0 +1,451 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package coverage
+
+import (
+	"fmt"
+	"internal/coverage"
+	"internal/goexperiment"
+	"internal/platform"
+	"internal/testenv"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"runtime"
+	"strings"
+	"testing"
+)
+
+// Set to true for debugging (linux only).
+const fixedTestDir = false
+
+func TestCoverageApis(t *testing.T) {
+	if testing.Short() {
+		t.Skipf("skipping test: too long for short mode")
+	}
+	if !goexperiment.CoverageRedesign {
+		t.Skipf("skipping new coverage tests (experiment not enabled)")
+	}
+	testenv.MustHaveGoBuild(t)
+	dir := t.TempDir()
+	if fixedTestDir {
+		dir = "/tmp/qqqzzz"
+		os.RemoveAll(dir)
+		mkdir(t, dir)
+	}
+
+	// Build harness.
+	bdir := mkdir(t, filepath.Join(dir, "build"))
+	hargs := []string{"-cover", "-coverpkg=all"}
+	if testing.CoverMode() != "" {
+		hargs = append(hargs, "-covermode="+testing.CoverMode())
+	}
+	harnessPath := buildHarness(t, bdir, hargs)
+
+	t.Logf("harness path is %s", harnessPath)
+
+	// Sub-tests for each API we want to inspect, plus
+	// extras for error testing.
+	t.Run("emitToDir", func(t *testing.T) {
+		t.Parallel()
+		testEmitToDir(t, harnessPath, dir)
+	})
+	t.Run("emitToWriter", func(t *testing.T) {
+		t.Parallel()
+		testEmitToWriter(t, harnessPath, dir)
+	})
+	t.Run("emitToNonexistentDir", func(t *testing.T) {
+		t.Parallel()
+		testEmitToNonexistentDir(t, harnessPath, dir)
+	})
+	t.Run("emitToNilWriter", func(t *testing.T) {
+		t.Parallel()
+		testEmitToNilWriter(t, harnessPath, dir)
+	})
+	t.Run("emitToFailingWriter", func(t *testing.T) {
+		t.Parallel()
+		testEmitToFailingWriter(t, harnessPath, dir)
+	})
+	t.Run("emitWithCounterClear", func(t *testing.T) {
+		t.Parallel()
+		testEmitWithCounterClear(t, harnessPath, dir)
+	})
+
+}
+
+// upmergeCoverData helps improve coverage data for this package
+// itself. If this test itself is being invoked with "-cover", then
+// what we'd like is for package coverage data (that is, coverage for
+// routines in "runtime/coverage") to be incorporated into the test
+// run from the "harness.exe" runs we've just done. We can accomplish
+// this by doing a merge from the harness gocoverdir's to the test
+// gocoverdir.
+func upmergeCoverData(t *testing.T, gocoverdir string) {
+	if testing.CoverMode() == "" {
+		return
+	}
+	testGoCoverDir := os.Getenv("GOCOVERDIR")
+	if testGoCoverDir == "" {
+		return
+	}
+	args := []string{"tool", "covdata", "merge", "-pkg=runtime/coverage",
+		"-o", testGoCoverDir, "-i", gocoverdir}
+	t.Logf("up-merge of covdata from %s to %s", gocoverdir, testGoCoverDir)
+	t.Logf("executing: go %+v", args)
+	cmd := exec.Command(testenv.GoToolPath(t), args...)
+	if b, err := cmd.CombinedOutput(); err != nil {
+		t.Fatalf("covdata merge failed (%v): %s", err, b)
+	}
+}
+
+// buildHarness builds the helper program "harness.exe".
+func buildHarness(t *testing.T, dir string, opts []string) string {
+	harnessPath := filepath.Join(dir, "harness.exe")
+	harnessSrc := filepath.Join("testdata", "harness.go")
+	args := []string{"build", "-o", harnessPath}
+	args = append(args, opts...)
+	args = append(args, harnessSrc)
+	//t.Logf("harness build: go %+v\n", args)
+	cmd := exec.Command(testenv.GoToolPath(t), args...)
+	if b, err := cmd.CombinedOutput(); err != nil {
+		t.Fatalf("build failed (%v): %s", err, b)
+	}
+	return harnessPath
+}
+
+func mkdir(t *testing.T, d string) string {
+	t.Helper()
+	if err := os.Mkdir(d, 0777); err != nil {
+		t.Fatalf("mkdir failed: %v", err)
+	}
+	return d
+}
+
+// updateGoCoverDir updates the specified environment 'env' to set
+// GOCOVERDIR to 'gcd' (if setGoCoverDir is TRUE) or removes
+// GOCOVERDIR from the environment (if setGoCoverDir is false).
+func updateGoCoverDir(env []string, gcd string, setGoCoverDir bool) []string {
+	rv := []string{}
+	found := false
+	for _, v := range env {
+		if strings.HasPrefix(v, "GOCOVERDIR=") {
+			if !setGoCoverDir {
+				continue
+			}
+			v = "GOCOVERDIR=" + gcd
+			found = true
+		}
+		rv = append(rv, v)
+	}
+	if !found && setGoCoverDir {
+		rv = append(rv, "GOCOVERDIR="+gcd)
+	}
+	return rv
+}
+
+func runHarness(t *testing.T, harnessPath string, tp string, setGoCoverDir bool, rdir, edir string) (string, error) {
+	t.Logf("running: %s -tp %s -o %s with rdir=%s and GOCOVERDIR=%v", harnessPath, tp, edir, rdir, setGoCoverDir)
+	cmd := exec.Command(harnessPath, "-tp", tp, "-o", edir)
+	cmd.Dir = rdir
+	cmd.Env = updateGoCoverDir(os.Environ(), rdir, setGoCoverDir)
+	b, err := cmd.CombinedOutput()
+	//t.Logf("harness run output: %s\n", string(b))
+	return string(b), err
+}
+
+func testForSpecificFunctions(t *testing.T, dir string, want []string, avoid []string) string {
+	args := []string{"tool", "covdata", "debugdump",
+		"-live", "-pkg=command-line-arguments", "-i=" + dir}
+	t.Logf("running: go %v\n", args)
+	cmd := exec.Command(testenv.GoToolPath(t), args...)
+	b, err := cmd.CombinedOutput()
+	if err != nil {
+		t.Fatalf("'go tool covdata failed (%v): %s", err, b)
+	}
+	output := string(b)
+	rval := ""
+	for _, f := range want {
+		wf := "Func: " + f + "\n"
+		if strings.Contains(output, wf) {
+			continue
+		}
+		rval += fmt.Sprintf("error: output should contain %q but does not\n", wf)
+	}
+	for _, f := range avoid {
+		wf := "Func: " + f + "\n"
+		if strings.Contains(output, wf) {
+			rval += fmt.Sprintf("error: output should not contain %q but does\n", wf)
+		}
+	}
+	if rval != "" {
+		t.Logf("=-= begin output:\n" + output + "\n=-= end output\n")
+	}
+	return rval
+}
+
+func withAndWithoutRunner(f func(setit bool, tag string)) {
+	// Run 'f' with and without GOCOVERDIR set.
+	for i := 0; i < 2; i++ {
+		tag := "x"
+		setGoCoverDir := true
+		if i == 0 {
+			setGoCoverDir = false
+			tag = "y"
+		}
+		f(setGoCoverDir, tag)
+	}
+}
+
+func mktestdirs(t *testing.T, tag, tp, dir string) (string, string) {
+	t.Helper()
+	rdir := mkdir(t, filepath.Join(dir, tp+"-rdir-"+tag))
+	edir := mkdir(t, filepath.Join(dir, tp+"-edir-"+tag))
+	return rdir, edir
+}
+
+func testEmitToDir(t *testing.T, harnessPath string, dir string) {
+	withAndWithoutRunner(func(setGoCoverDir bool, tag string) {
+		tp := "emitToDir"
+		rdir, edir := mktestdirs(t, tag, tp, dir)
+		output, err := runHarness(t, harnessPath, tp,
+			setGoCoverDir, rdir, edir)
+		if err != nil {
+			t.Logf("%s", output)
+			t.Fatalf("running 'harness -tp emitDir': %v", err)
+		}
+
+		// Just check to make sure meta-data file and counter data file were
+		// written. Another alternative would be to run "go tool covdata"
+		// or equivalent, but for now, this is what we've got.
+		dents, err := os.ReadDir(edir)
+		if err != nil {
+			t.Fatalf("os.ReadDir(%s) failed: %v", edir, err)
+		}
+		mfc := 0
+		cdc := 0
+		for _, e := range dents {
+			if e.IsDir() {
+				continue
+			}
+			if strings.HasPrefix(e.Name(), coverage.MetaFilePref) {
+				mfc++
+			} else if strings.HasPrefix(e.Name(), coverage.CounterFilePref) {
+				cdc++
+			}
+		}
+		wantmf := 1
+		wantcf := 1
+		if mfc != wantmf {
+			t.Errorf("EmitToDir: want %d meta-data files, got %d\n", wantmf, mfc)
+		}
+		if cdc != wantcf {
+			t.Errorf("EmitToDir: want %d counter-data files, got %d\n", wantcf, cdc)
+		}
+		upmergeCoverData(t, edir)
+		upmergeCoverData(t, rdir)
+	})
+}
+
+func testEmitToWriter(t *testing.T, harnessPath string, dir string) {
+	withAndWithoutRunner(func(setGoCoverDir bool, tag string) {
+		tp := "emitToWriter"
+		rdir, edir := mktestdirs(t, tag, tp, dir)
+		output, err := runHarness(t, harnessPath, tp, setGoCoverDir, rdir, edir)
+		if err != nil {
+			t.Logf("%s", output)
+			t.Fatalf("running 'harness -tp %s': %v", tp, err)
+		}
+		want := []string{"main", tp}
+		avoid := []string{"final"}
+		if msg := testForSpecificFunctions(t, edir, want, avoid); msg != "" {
+			t.Errorf("coverage data from %q output match failed: %s", tp, msg)
+		}
+		upmergeCoverData(t, edir)
+		upmergeCoverData(t, rdir)
+	})
+}
+
+func testEmitToNonexistentDir(t *testing.T, harnessPath string, dir string) {
+	withAndWithoutRunner(func(setGoCoverDir bool, tag string) {
+		tp := "emitToNonexistentDir"
+		rdir, edir := mktestdirs(t, tag, tp, dir)
+		output, err := runHarness(t, harnessPath, tp, setGoCoverDir, rdir, edir)
+		if err != nil {
+			t.Logf("%s", output)
+			t.Fatalf("running 'harness -tp %s': %v", tp, err)
+		}
+		upmergeCoverData(t, edir)
+		upmergeCoverData(t, rdir)
+	})
+}
+
+func testEmitToUnwritableDir(t *testing.T, harnessPath string, dir string) {
+	withAndWithoutRunner(func(setGoCoverDir bool, tag string) {
+
+		tp := "emitToUnwritableDir"
+		rdir, edir := mktestdirs(t, tag, tp, dir)
+
+		// Make edir unwritable.
+		if err := os.Chmod(edir, 0555); err != nil {
+			t.Fatalf("chmod failed: %v", err)
+		}
+		defer os.Chmod(edir, 0777)
+
+		output, err := runHarness(t, harnessPath, tp, setGoCoverDir, rdir, edir)
+		if err != nil {
+			t.Logf("%s", output)
+			t.Fatalf("running 'harness -tp %s': %v", tp, err)
+		}
+		upmergeCoverData(t, edir)
+		upmergeCoverData(t, rdir)
+	})
+}
+
+func testEmitToNilWriter(t *testing.T, harnessPath string, dir string) {
+	withAndWithoutRunner(func(setGoCoverDir bool, tag string) {
+		tp := "emitToNilWriter"
+		rdir, edir := mktestdirs(t, tag, tp, dir)
+		output, err := runHarness(t, harnessPath, tp, setGoCoverDir, rdir, edir)
+		if err != nil {
+			t.Logf("%s", output)
+			t.Fatalf("running 'harness -tp %s': %v", tp, err)
+		}
+		upmergeCoverData(t, edir)
+		upmergeCoverData(t, rdir)
+	})
+}
+
+func testEmitToFailingWriter(t *testing.T, harnessPath string, dir string) {
+	withAndWithoutRunner(func(setGoCoverDir bool, tag string) {
+		tp := "emitToFailingWriter"
+		rdir, edir := mktestdirs(t, tag, tp, dir)
+		output, err := runHarness(t, harnessPath, tp, setGoCoverDir, rdir, edir)
+		if err != nil {
+			t.Logf("%s", output)
+			t.Fatalf("running 'harness -tp %s': %v", tp, err)
+		}
+		upmergeCoverData(t, edir)
+		upmergeCoverData(t, rdir)
+	})
+}
+
+func testEmitWithCounterClear(t *testing.T, harnessPath string, dir string) {
+	// Ensure that we have two versions of the harness: one built with
+	// -covermode=atomic and one built with -covermode=set (we need
+	// both modes to test all of the functionality).
+	var nonatomicHarnessPath, atomicHarnessPath string
+	if testing.CoverMode() != "atomic" {
+		nonatomicHarnessPath = harnessPath
+		bdir2 := mkdir(t, filepath.Join(dir, "build2"))
+		hargs := []string{"-covermode=atomic", "-coverpkg=all"}
+		atomicHarnessPath = buildHarness(t, bdir2, hargs)
+	} else {
+		atomicHarnessPath = harnessPath
+		mode := "set"
+		if testing.CoverMode() != "" && testing.CoverMode() != "atomic" {
+			mode = testing.CoverMode()
+		}
+		// Build a special nonatomic covermode version of the harness
+		// (we need both modes to test all of the functionality).
+		bdir2 := mkdir(t, filepath.Join(dir, "build2"))
+		hargs := []string{"-covermode=" + mode, "-coverpkg=all"}
+		nonatomicHarnessPath = buildHarness(t, bdir2, hargs)
+	}
+
+	withAndWithoutRunner(func(setGoCoverDir bool, tag string) {
+		// First a run with the nonatomic harness path, which we
+		// expect to fail.
+		tp := "emitWithCounterClear"
+		rdir1, edir1 := mktestdirs(t, tag, tp+"1", dir)
+		output, err := runHarness(t, nonatomicHarnessPath, tp,
+			setGoCoverDir, rdir1, edir1)
+		if err == nil {
+			t.Logf("%s", output)
+			t.Fatalf("running '%s -tp %s': unexpected success",
+				nonatomicHarnessPath, tp)
+		}
+
+		// Next a run with the atomic harness path, which we
+		// expect to succeed.
+		rdir2, edir2 := mktestdirs(t, tag, tp+"2", dir)
+		output, err = runHarness(t, atomicHarnessPath, tp,
+			setGoCoverDir, rdir2, edir2)
+		if err != nil {
+			t.Logf("%s", output)
+			t.Fatalf("running 'harness -tp %s': %v", tp, err)
+		}
+		want := []string{tp, "postClear"}
+		avoid := []string{"preClear", "main", "final"}
+		if msg := testForSpecificFunctions(t, edir2, want, avoid); msg != "" {
+			t.Logf("%s", output)
+			t.Errorf("coverage data from %q output match failed: %s", tp, msg)
+		}
+
+		if testing.CoverMode() == "atomic" {
+			upmergeCoverData(t, edir2)
+			upmergeCoverData(t, rdir2)
+		} else {
+			upmergeCoverData(t, edir1)
+			upmergeCoverData(t, rdir1)
+		}
+	})
+}
+
+func TestApisOnNocoverBinary(t *testing.T) {
+	if testing.Short() {
+		t.Skipf("skipping test: too long for short mode")
+	}
+	testenv.MustHaveGoBuild(t)
+	dir := t.TempDir()
+
+	// Build harness with no -cover.
+	bdir := mkdir(t, filepath.Join(dir, "nocover"))
+	edir := mkdir(t, filepath.Join(dir, "emitDirNo"))
+	harnessPath := buildHarness(t, bdir, nil)
+	output, err := runHarness(t, harnessPath, "emitToDir", false, edir, edir)
+	if err == nil {
+		t.Fatalf("expected error on TestApisOnNocoverBinary harness run")
+	}
+	const want = "not built with -cover"
+	if !strings.Contains(output, want) {
+		t.Errorf("error output does not contain %q: %s", want, output)
+	}
+}
+
+func TestIssue56006EmitDataRaceCoverRunningGoroutine(t *testing.T) {
+	if testing.Short() {
+		t.Skipf("skipping test: too long for short mode")
+	}
+	if !goexperiment.CoverageRedesign {
+		t.Skipf("skipping new coverage tests (experiment not enabled)")
+	}
+
+	// This test requires "go test -race -cover", meaning that we need
+	// go build, go run, and "-race" support.
+	testenv.MustHaveGoRun(t)
+	if !platform.RaceDetectorSupported(runtime.GOOS, runtime.GOARCH) ||
+		!testenv.HasCGO() {
+		t.Skip("skipped due to lack of race detector support / CGO")
+	}
+
+	// This will run a program with -cover and -race where we have a
+	// goroutine still running (and updating counters) at the point where
+	// the test runtime is trying to write out counter data.
+	cmd := exec.Command(testenv.GoToolPath(t), "test", "-cover", "-race")
+	cmd.Dir = filepath.Join("testdata", "issue56006")
+	b, err := cmd.CombinedOutput()
+	if err != nil {
+		t.Fatalf("go test -cover -race failed: %v", err)
+	}
+
+	// Don't want to see any data races in output.
+	avoid := []string{"DATA RACE"}
+	for _, no := range avoid {
+		if strings.Contains(string(b), no) {
+			t.Logf("%s\n", string(b))
+			t.Fatalf("found %s in test output, not permitted", no)
+		}
+	}
+}
diff --git a/src/runtime/coverage/hooks.go b/src/runtime/coverage/hooks.go
new file mode 100644
index 0000000..a9fbf9d
--- /dev/null
+++ b/src/runtime/coverage/hooks.go
@@ -0,0 +1,42 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package coverage
+
+import _ "unsafe"
+
+// initHook is invoked from the main package "init" routine in
+// programs built with "-cover". This function is intended to be
+// called only by the compiler.
+//
+// If 'istest' is false, it indicates we're building a regular program
+// ("go build -cover ..."), in which case we immediately try to write
+// out the meta-data file, and register emitCounterData as an exit
+// hook.
+//
+// If 'istest' is true (indicating that the program in question is a
+// Go test binary), then we tentatively queue up both emitMetaData and
+// emitCounterData as exit hooks. In the normal case (e.g. regular "go
+// test -cover" run) the testmain.go boilerplate will run at the end
+// of the test, write out the coverage percentage, and then invoke
+// markProfileEmitted() to indicate that no more work needs to be
+// done. If however that call is never made, this is a sign that the
+// test binary is being used as a replacement binary for the tool
+// being tested, hence we do want to run exit hooks when the program
+// terminates.
+func initHook(istest bool) {
+	// Note: hooks are run in reverse registration order, so
+	// register the counter data hook before the meta-data hook
+	// (in the case where two hooks are needed).
+	runOnNonZeroExit := true
+	runtime_addExitHook(emitCounterData, runOnNonZeroExit)
+	if istest {
+		runtime_addExitHook(emitMetaData, runOnNonZeroExit)
+	} else {
+		emitMetaData()
+	}
+}
+
+//go:linkname runtime_addExitHook runtime.addExitHook
+func runtime_addExitHook(f func(), runOnNonZeroExit bool)
diff --git a/src/runtime/coverage/testdata/harness.go b/src/runtime/coverage/testdata/harness.go
new file mode 100644
index 0000000..5c87e4c
--- /dev/null
+++ b/src/runtime/coverage/testdata/harness.go
@@ -0,0 +1,259 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"flag"
+	"fmt"
+	"internal/coverage/slicewriter"
+	"io"
+	"io/ioutil"
+	"log"
+	"path/filepath"
+	"runtime/coverage"
+	"strings"
+)
+
+var verbflag = flag.Int("v", 0, "Verbose trace output level")
+var testpointflag = flag.String("tp", "", "Testpoint to run")
+var outdirflag = flag.String("o", "", "Output dir into which to emit")
+
+func emitToWriter() {
+	log.SetPrefix("emitToWriter: ")
+	var slwm slicewriter.WriteSeeker
+	if err := coverage.WriteMeta(&slwm); err != nil {
+		log.Fatalf("error: WriteMeta returns %v", err)
+	}
+	mf := filepath.Join(*outdirflag, "covmeta.0abcdef")
+	if err := ioutil.WriteFile(mf, slwm.BytesWritten(), 0666); err != nil {
+		log.Fatalf("error: writing %s: %v", mf, err)
+	}
+	var slwc slicewriter.WriteSeeker
+	if err := coverage.WriteCounters(&slwc); err != nil {
+		log.Fatalf("error: WriteCounters returns %v", err)
+	}
+	cf := filepath.Join(*outdirflag, "covcounters.0abcdef.99.77")
+	if err := ioutil.WriteFile(cf, slwc.BytesWritten(), 0666); err != nil {
+		log.Fatalf("error: writing %s: %v", cf, err)
+	}
+}
+
+func emitToDir() {
+	log.SetPrefix("emitToDir: ")
+	if err := coverage.WriteMetaDir(*outdirflag); err != nil {
+		log.Fatalf("error: WriteMetaDir returns %v", err)
+	}
+	if err := coverage.WriteCountersDir(*outdirflag); err != nil {
+		log.Fatalf("error: WriteCountersDir returns %v", err)
+	}
+}
+
+func emitToNonexistentDir() {
+	log.SetPrefix("emitToNonexistentDir: ")
+
+	want := []string{
+		"no such file or directory",             // linux-ish
+		"system cannot find the file specified", // windows
+		"does not exist",                        // plan9
+	}
+
+	checkWant := func(which string, got string) {
+		found := false
+		for _, w := range want {
+			if strings.Contains(got, w) {
+				found = true
+				break
+			}
+		}
+		if !found {
+			log.Fatalf("%s emit to bad dir: got error:\n  %v\nwanted error with one of:\n  %+v", which, got, want)
+		}
+	}
+
+	// Mangle the output directory to produce something nonexistent.
+	mangled := *outdirflag + "_MANGLED"
+	if err := coverage.WriteMetaDir(mangled); err == nil {
+		log.Fatal("expected error from WriteMetaDir to nonexistent dir")
+	} else {
+		got := fmt.Sprintf("%v", err)
+		checkWant("meta data", got)
+	}
+
+	// Now try to emit counter data file to a bad dir.
+	if err := coverage.WriteCountersDir(mangled); err == nil {
+		log.Fatal("expected error emitting counter data to bad dir")
+	} else {
+		got := fmt.Sprintf("%v", err)
+		checkWant("counter data", got)
+	}
+}
+
+func emitToUnwritableDir() {
+	log.SetPrefix("emitToUnwritableDir: ")
+
+	want := "permission denied"
+
+	if err := coverage.WriteMetaDir(*outdirflag); err == nil {
+		log.Fatal("expected error from WriteMetaDir to unwritable dir")
+	} else {
+		got := fmt.Sprintf("%v", err)
+		if !strings.Contains(got, want) {
+			log.Fatalf("meta-data emit to unwritable dir: wanted error containing %q got %q", want, got)
+		}
+	}
+
+	// Similarly with writing counter data.
+	if err := coverage.WriteCountersDir(*outdirflag); err == nil {
+		log.Fatal("expected error emitting counter data to unwritable dir")
+	} else {
+		got := fmt.Sprintf("%v", err)
+		if !strings.Contains(got, want) {
+			log.Fatalf("emitting counter data to unwritable dir: wanted error containing %q got %q", want, got)
+		}
+	}
+}
+
+func emitToNilWriter() {
+	log.SetPrefix("emitToWriter: ")
+	want := "nil writer"
+	var bad io.WriteSeeker
+	if err := coverage.WriteMeta(bad); err == nil {
+		log.Fatal("expected error passing nil writer for meta emit")
+	} else {
+		got := fmt.Sprintf("%v", err)
+		if !strings.Contains(got, want) {
+			log.Fatalf("emitting meta-data passing nil writer: wanted error containing %q got %q", want, got)
+		}
+	}
+
+	if err := coverage.WriteCounters(bad); err == nil {
+		log.Fatal("expected error passing nil writer for counter emit")
+	} else {
+		got := fmt.Sprintf("%v", err)
+		if !strings.Contains(got, want) {
+			log.Fatalf("emitting counter data passing nil writer: wanted error containing %q got %q", want, got)
+		}
+	}
+}
+
+type failingWriter struct {
+	writeCount int
+	writeLimit int
+	slws       slicewriter.WriteSeeker
+}
+
+func (f *failingWriter) Write(p []byte) (n int, err error) {
+	c := f.writeCount
+	f.writeCount++
+	if f.writeLimit < 0 || c < f.writeLimit {
+		return f.slws.Write(p)
+	}
+	return 0, fmt.Errorf("manufactured write error")
+}
+
+func (f *failingWriter) Seek(offset int64, whence int) (int64, error) {
+	return f.slws.Seek(offset, whence)
+}
+
+func (f *failingWriter) reset(lim int) {
+	f.writeCount = 0
+	f.writeLimit = lim
+	f.slws = slicewriter.WriteSeeker{}
+}
+
+func writeStressTest(tag string, testf func(testf *failingWriter) error) {
+	// Invoke the function initially without the write limit
+	// set, to capture the number of writes performed.
+	fw := &failingWriter{writeLimit: -1}
+	testf(fw)
+
+	// Now that we know how many writes are going to happen, run the
+	// function repeatedly, each time with a Write operation set to
+	// fail at a new spot. The goal here is to make sure that:
+	// A) an error is reported, and B) nothing crashes.
+	tot := fw.writeCount
+	for i := 0; i < tot; i++ {
+		fw.reset(i)
+		err := testf(fw)
+		if err == nil {
+			log.Fatalf("no error from write %d tag %s", i, tag)
+		}
+	}
+}
+
+func postClear() int {
+	return 42
+}
+
+func preClear() int {
+	return 42
+}
+
+// This test is designed to ensure that write errors are properly
+// handled by the code that writes out coverage data. It repeatedly
+// invokes the 'emit to writer' apis using a specially crafted writer
+// that captures the total number of expected writes, then replays the
+// execution N times with a manufactured write error at the
+// appropriate spot.
+func emitToFailingWriter() {
+	log.SetPrefix("emitToFailingWriter: ")
+
+	writeStressTest("emit-meta", func(f *failingWriter) error {
+		return coverage.WriteMeta(f)
+	})
+	writeStressTest("emit-counter", func(f *failingWriter) error {
+		return coverage.WriteCounters(f)
+	})
+}
+
+func emitWithCounterClear() {
+	log.SetPrefix("emitWitCounterClear: ")
+	preClear()
+	if err := coverage.ClearCounters(); err != nil {
+		log.Fatalf("clear failed: %v", err)
+	}
+	postClear()
+	if err := coverage.WriteMetaDir(*outdirflag); err != nil {
+		log.Fatalf("error: WriteMetaDir returns %v", err)
+	}
+	if err := coverage.WriteCountersDir(*outdirflag); err != nil {
+		log.Fatalf("error: WriteCountersDir returns %v", err)
+	}
+}
+
+func final() int {
+	println("I run last.")
+	return 43
+}
+
+func main() {
+	log.SetFlags(0)
+	flag.Parse()
+	if *testpointflag == "" {
+		log.Fatalf("error: no testpoint (use -tp flag)")
+	}
+	if *outdirflag == "" {
+		log.Fatalf("error: no output dir specified (use -o flag)")
+	}
+	switch *testpointflag {
+	case "emitToDir":
+		emitToDir()
+	case "emitToWriter":
+		emitToWriter()
+	case "emitToNonexistentDir":
+		emitToNonexistentDir()
+	case "emitToUnwritableDir":
+		emitToUnwritableDir()
+	case "emitToNilWriter":
+		emitToNilWriter()
+	case "emitToFailingWriter":
+		emitToFailingWriter()
+	case "emitWithCounterClear":
+		emitWithCounterClear()
+	default:
+		log.Fatalf("error: unknown testpoint %q", *testpointflag)
+	}
+	final()
+}
diff --git a/src/runtime/coverage/testdata/issue56006/repro.go b/src/runtime/coverage/testdata/issue56006/repro.go
new file mode 100644
index 0000000..60a4925
--- /dev/null
+++ b/src/runtime/coverage/testdata/issue56006/repro.go
@@ -0,0 +1,26 @@
+package main
+
+//go:noinline
+func blah(x int) int {
+	if x != 0 {
+		return x + 42
+	}
+	return x - 42
+}
+
+func main() {
+	go infloop()
+	println(blah(1) + blah(0))
+}
+
+var G int
+
+func infloop() {
+	for {
+		G += blah(1)
+		G += blah(0)
+		if G > 10000 {
+			G = 0
+		}
+	}
+}
diff --git a/src/runtime/coverage/testdata/issue56006/repro_test.go b/src/runtime/coverage/testdata/issue56006/repro_test.go
new file mode 100644
index 0000000..674d819
--- /dev/null
+++ b/src/runtime/coverage/testdata/issue56006/repro_test.go
@@ -0,0 +1,8 @@
+package main
+
+import "testing"
+
+func TestSomething(t *testing.T) {
+	go infloop()
+	println(blah(1) + blah(0))
+}
diff --git a/src/runtime/coverage/testsupport.go b/src/runtime/coverage/testsupport.go
new file mode 100644
index 0000000..a481bbb
--- /dev/null
+++ b/src/runtime/coverage/testsupport.go
@@ -0,0 +1,234 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package coverage
+
+import (
+	"fmt"
+	"internal/coverage"
+	"internal/coverage/calloc"
+	"internal/coverage/cformat"
+	"internal/coverage/cmerge"
+	"internal/coverage/decodecounter"
+	"internal/coverage/decodemeta"
+	"internal/coverage/pods"
+	"io"
+	"os"
+	"strings"
+)
+
+// processCoverTestDir is called (via a linknamed reference) from
+// testmain code when "go test -cover" is in effect. It is not
+// intended to be used other than internally by the Go command's
+// generated code.
+func processCoverTestDir(dir string, cfile string, cm string, cpkg string) error {
+	return processCoverTestDirInternal(dir, cfile, cm, cpkg, os.Stdout)
+}
+
+// processCoverTestDirInternal is an io.Writer version of processCoverTestDir,
+// exposed for unit testing.
+func processCoverTestDirInternal(dir string, cfile string, cm string, cpkg string, w io.Writer) error {
+	cmode := coverage.ParseCounterMode(cm)
+	if cmode == coverage.CtrModeInvalid {
+		return fmt.Errorf("invalid counter mode %q", cm)
+	}
+
+	// Emit meta-data and counter data.
+	ml := getCovMetaList()
+	if len(ml) == 0 {
+		// This corresponds to the case where we have a package that
+		// contains test code but no functions (which is fine). In this
+		// case there is no need to emit anything.
+	} else {
+		if err := emitMetaDataToDirectory(dir, ml); err != nil {
+			return err
+		}
+		if err := emitCounterDataToDirectory(dir); err != nil {
+			return err
+		}
+	}
+
+	// Collect pods from test run. For the majority of cases we would
+	// expect to see a single pod here, but allow for multiple pods in
+	// case the test harness is doing extra work to collect data files
+	// from builds that it kicks off as part of the testing.
+	podlist, err := pods.CollectPods([]string{dir}, false)
+	if err != nil {
+		return fmt.Errorf("reading from %s: %v", dir, err)
+	}
+
+	// Open text output file if appropriate.
+	var tf *os.File
+	var tfClosed bool
+	if cfile != "" {
+		var err error
+		tf, err = os.Create(cfile)
+		if err != nil {
+			return fmt.Errorf("internal error: opening coverage data output file %q: %v", cfile, err)
+		}
+		defer func() {
+			if !tfClosed {
+				tfClosed = true
+				tf.Close()
+			}
+		}()
+	}
+
+	// Read/process the pods.
+	ts := &tstate{
+		cm:    &cmerge.Merger{},
+		cf:    cformat.NewFormatter(cmode),
+		cmode: cmode,
+	}
+	// Generate the expected hash string based on the final meta-data
+	// hash for this test, then look only for pods that refer to that
+	// hash (just in case there are multiple instrumented executables
+	// in play). See issue #57924 for more on this.
+	hashstring := fmt.Sprintf("%x", finalHash)
+	for _, p := range podlist {
+		if !strings.Contains(p.MetaFile, hashstring) {
+			continue
+		}
+		if err := ts.processPod(p); err != nil {
+			return err
+		}
+	}
+
+	// Emit percent.
+	if err := ts.cf.EmitPercent(w, cpkg, true); err != nil {
+		return err
+	}
+
+	// Emit text output.
+	if tf != nil {
+		if err := ts.cf.EmitTextual(tf); err != nil {
+			return err
+		}
+		tfClosed = true
+		if err := tf.Close(); err != nil {
+			return fmt.Errorf("closing %s: %v", cfile, err)
+		}
+	}
+
+	return nil
+}
+
+type tstate struct {
+	calloc.BatchCounterAlloc
+	cm    *cmerge.Merger
+	cf    *cformat.Formatter
+	cmode coverage.CounterMode
+}
+
+// processPod reads coverage counter data for a specific pod.
+func (ts *tstate) processPod(p pods.Pod) error {
+	// Open meta-data file
+	f, err := os.Open(p.MetaFile)
+	if err != nil {
+		return fmt.Errorf("unable to open meta-data file %s: %v", p.MetaFile, err)
+	}
+	defer func() {
+		f.Close()
+	}()
+	var mfr *decodemeta.CoverageMetaFileReader
+	mfr, err = decodemeta.NewCoverageMetaFileReader(f, nil)
+	if err != nil {
+		return fmt.Errorf("error reading meta-data file %s: %v", p.MetaFile, err)
+	}
+	newmode := mfr.CounterMode()
+	if newmode != ts.cmode {
+		return fmt.Errorf("internal error: counter mode clash: %q from test harness, %q from data file %s", ts.cmode.String(), newmode.String(), p.MetaFile)
+	}
+	newgran := mfr.CounterGranularity()
+	if err := ts.cm.SetModeAndGranularity(p.MetaFile, cmode, newgran); err != nil {
+		return err
+	}
+
+	// A map to store counter data, indexed by pkgid/fnid tuple.
+	pmm := make(map[pkfunc][]uint32)
+
+	// Helper to read a single counter data file.
+	readcdf := func(cdf string) error {
+		cf, err := os.Open(cdf)
+		if err != nil {
+			return fmt.Errorf("opening counter data file %s: %s", cdf, err)
+		}
+		defer cf.Close()
+		var cdr *decodecounter.CounterDataReader
+		cdr, err = decodecounter.NewCounterDataReader(cdf, cf)
+		if err != nil {
+			return fmt.Errorf("reading counter data file %s: %s", cdf, err)
+		}
+		var data decodecounter.FuncPayload
+		for {
+			ok, err := cdr.NextFunc(&data)
+			if err != nil {
+				return fmt.Errorf("reading counter data file %s: %v", cdf, err)
+			}
+			if !ok {
+				break
+			}
+
+			// NB: sanity check on pkg and func IDs?
+			key := pkfunc{pk: data.PkgIdx, fcn: data.FuncIdx}
+			if prev, found := pmm[key]; found {
+				// Note: no overflow reporting here.
+				if err, _ := ts.cm.MergeCounters(data.Counters, prev); err != nil {
+					return fmt.Errorf("processing counter data file %s: %v", cdf, err)
+				}
+			}
+			c := ts.AllocateCounters(len(data.Counters))
+			copy(c, data.Counters)
+			pmm[key] = c
+		}
+		return nil
+	}
+
+	// Read counter data files.
+	for _, cdf := range p.CounterDataFiles {
+		if err := readcdf(cdf); err != nil {
+			return err
+		}
+	}
+
+	// Visit meta-data file.
+	np := uint32(mfr.NumPackages())
+	payload := []byte{}
+	for pkIdx := uint32(0); pkIdx < np; pkIdx++ {
+		var pd *decodemeta.CoverageMetaDataDecoder
+		pd, payload, err = mfr.GetPackageDecoder(pkIdx, payload)
+		if err != nil {
+			return fmt.Errorf("reading pkg %d from meta-file %s: %s", pkIdx, p.MetaFile, err)
+		}
+		ts.cf.SetPackage(pd.PackagePath())
+		var fd coverage.FuncDesc
+		nf := pd.NumFuncs()
+		for fnIdx := uint32(0); fnIdx < nf; fnIdx++ {
+			if err := pd.ReadFunc(fnIdx, &fd); err != nil {
+				return fmt.Errorf("reading meta-data file %s: %v",
+					p.MetaFile, err)
+			}
+			key := pkfunc{pk: pkIdx, fcn: fnIdx}
+			counters, haveCounters := pmm[key]
+			for i := 0; i < len(fd.Units); i++ {
+				u := fd.Units[i]
+				// Skip units with non-zero parent (no way to represent
+				// these in the existing format).
+				if u.Parent != 0 {
+					continue
+				}
+				count := uint32(0)
+				if haveCounters {
+					count = counters[i]
+				}
+				ts.cf.AddUnit(fd.Srcfile, fd.Funcname, fd.Lit, u, count)
+			}
+		}
+	}
+	return nil
+}
+
+type pkfunc struct {
+	pk, fcn uint32
+}
diff --git a/src/runtime/coverage/ts_test.go b/src/runtime/coverage/ts_test.go
new file mode 100644
index 0000000..b826058
--- /dev/null
+++ b/src/runtime/coverage/ts_test.go
@@ -0,0 +1,58 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package coverage
+
+import (
+	"internal/goexperiment"
+	"os"
+	"path/filepath"
+	"strings"
+	"testing"
+	_ "unsafe"
+)
+
+//go:linkname testing_testGoCoverDir testing.testGoCoverDir
+func testing_testGoCoverDir() string
+
+// TestTestSupport does a basic verification of the functionality in
+// runtime/coverage.processCoverTestDir (doing this here as opposed to
+// relying on other test paths will provide a better signal when
+// running "go test -cover" for this package).
+func TestTestSupport(t *testing.T) {
+	if !goexperiment.CoverageRedesign {
+		return
+	}
+	if testing.CoverMode() == "" {
+		return
+	}
+	t.Logf("testing.testGoCoverDir() returns %s mode=%s\n",
+		testing_testGoCoverDir(), testing.CoverMode())
+
+	textfile := filepath.Join(t.TempDir(), "file.txt")
+	var sb strings.Builder
+	err := processCoverTestDirInternal(testing_testGoCoverDir(), textfile,
+		testing.CoverMode(), "", &sb)
+	if err != nil {
+		t.Fatalf("bad: %v", err)
+	}
+
+	// Check for existence of text file.
+	if inf, err := os.Open(textfile); err != nil {
+		t.Fatalf("problems opening text file %s: %v", textfile, err)
+	} else {
+		inf.Close()
+	}
+
+	// Check for percent output with expected tokens.
+	strout := sb.String()
+	want1 := "runtime/coverage"
+	want2 := "of statements"
+	if !strings.Contains(strout, want1) ||
+		!strings.Contains(strout, want2) {
+		t.Logf("output from run: %s\n", strout)
+		t.Fatalf("percent output missing key tokens: %q and %q",
+			want1, want2)
+	}
+}
diff --git a/src/runtime/covercounter.go b/src/runtime/covercounter.go
new file mode 100644
index 0000000..72842bd
--- /dev/null
+++ b/src/runtime/covercounter.go
@@ -0,0 +1,26 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+import (
+	"internal/coverage/rtcov"
+	"unsafe"
+)
+
+//go:linkname runtime_coverage_getCovCounterList runtime/coverage.getCovCounterList
+func runtime_coverage_getCovCounterList() []rtcov.CovCounterBlob {
+	res := []rtcov.CovCounterBlob{}
+	u32sz := unsafe.Sizeof(uint32(0))
+	for datap := &firstmoduledata; datap != nil; datap = datap.next {
+		if datap.covctrs == datap.ecovctrs {
+			continue
+		}
+		res = append(res, rtcov.CovCounterBlob{
+			Counters: (*uint32)(unsafe.Pointer(datap.covctrs)),
+			Len:      uint64((datap.ecovctrs - datap.covctrs) / u32sz),
+		})
+	}
+	return res
+}
diff --git a/src/runtime/covermeta.go b/src/runtime/covermeta.go
new file mode 100644
index 0000000..54ef42a
--- /dev/null
+++ b/src/runtime/covermeta.go
@@ -0,0 +1,72 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+import (
+	"internal/coverage/rtcov"
+	"unsafe"
+)
+
+// covMeta is the top-level container for bits of state related to
+// code coverage meta-data in the runtime.
+var covMeta struct {
+	// metaList contains the list of currently registered meta-data
+	// blobs for the running program.
+	metaList []rtcov.CovMetaBlob
+
+	// pkgMap records mappings from hard-coded package IDs to
+	// slots in the covMetaList above.
+	pkgMap map[int]int
+
+	// Set to true if we discover a package mapping glitch.
+	hardCodedListNeedsUpdating bool
+}
+
+// addCovMeta is invoked during package "init" functions by the
+// compiler when compiling for coverage instrumentation; here 'p' is a
+// meta-data blob of length 'dlen' for the package in question, 'hash'
+// is a compiler-computed md5.sum for the blob, 'pkpath' is the
+// package path, 'pkid' is the hard-coded ID that the compiler is
+// using for the package (or -1 if the compiler doesn't think a
+// hard-coded ID is needed), and 'cmode'/'cgran' are the coverage
+// counter mode and granularity requested by the user. Return value is
+// the ID for the package for use by the package code itself.
+func addCovMeta(p unsafe.Pointer, dlen uint32, hash [16]byte, pkpath string, pkid int, cmode uint8, cgran uint8) uint32 {
+	slot := len(covMeta.metaList)
+	covMeta.metaList = append(covMeta.metaList,
+		rtcov.CovMetaBlob{
+			P:                  (*byte)(p),
+			Len:                dlen,
+			Hash:               hash,
+			PkgPath:            pkpath,
+			PkgID:              pkid,
+			CounterMode:        cmode,
+			CounterGranularity: cgran,
+		})
+	if pkid != -1 {
+		if covMeta.pkgMap == nil {
+			covMeta.pkgMap = make(map[int]int)
+		}
+		if _, ok := covMeta.pkgMap[pkid]; ok {
+			throw("runtime.addCovMeta: coverage package map collision")
+		}
+		// Record the real slot (position on meta-list) for this
+		// package; we'll use the map to fix things up later on.
+		covMeta.pkgMap[pkid] = slot
+	}
+
+	// ID zero is reserved as invalid.
+	return uint32(slot + 1)
+}
+
+//go:linkname runtime_coverage_getCovMetaList runtime/coverage.getCovMetaList
+func runtime_coverage_getCovMetaList() []rtcov.CovMetaBlob {
+	return covMeta.metaList
+}
+
+//go:linkname runtime_coverage_getCovPkgMap runtime/coverage.getCovPkgMap
+func runtime_coverage_getCovPkgMap() map[int]int {
+	return covMeta.pkgMap
+}
diff --git a/src/runtime/cpuflags_arm64.go b/src/runtime/cpuflags_arm64.go
index 7576bef..a0f1d11 100644
--- a/src/runtime/cpuflags_arm64.go
+++ b/src/runtime/cpuflags_arm64.go
@@ -11,7 +11,7 @@
 var arm64UseAlignedLoads bool
 
 func init() {
-	if cpu.ARM64.IsNeoverseN1 || cpu.ARM64.IsZeus {
+	if cpu.ARM64.IsNeoverseN1 || cpu.ARM64.IsNeoverseV1 {
 		arm64UseAlignedLoads = true
 	}
 }
diff --git a/src/runtime/cpuprof.go b/src/runtime/cpuprof.go
index 2f7f6b4..6ef374e 100644
--- a/src/runtime/cpuprof.go
+++ b/src/runtime/cpuprof.go
@@ -14,7 +14,6 @@
 
 import (
 	"internal/abi"
-	"runtime/internal/atomic"
 	"runtime/internal/sys"
 	"unsafe"
 )
@@ -106,12 +105,12 @@
 //go:nowritebarrierrec
 func (p *cpuProfile) add(tagPtr *unsafe.Pointer, stk []uintptr) {
 	// Simple cas-lock to coordinate with setcpuprofilerate.
-	for !atomic.Cas(&prof.signalLock, 0, 1) {
+	for !prof.signalLock.CompareAndSwap(0, 1) {
 		// TODO: Is it safe to osyield here? https://go.dev/issue/52672
 		osyield()
 	}
 
-	if prof.hz != 0 { // implies cpuprof.log != nil
+	if prof.hz.Load() != 0 { // implies cpuprof.log != nil
 		if p.numExtra > 0 || p.lostExtra > 0 || p.lostAtomic > 0 {
 			p.addExtra()
 		}
@@ -123,7 +122,7 @@
 		cpuprof.log.write(tagPtr, nanotime(), hdr[:], stk)
 	}
 
-	atomic.Store(&prof.signalLock, 0)
+	prof.signalLock.Store(0)
 }
 
 // addNonGo adds the non-Go stack trace to the profile.
@@ -143,7 +142,7 @@
 	// process at a time. If not, this lock will serialize those too.
 	// The use of timer_create(2) on Linux to request process-targeted
 	// signals may have changed this.)
-	for !atomic.Cas(&prof.signalLock, 0, 1) {
+	for !prof.signalLock.CompareAndSwap(0, 1) {
 		// TODO: Is it safe to osyield here? https://go.dev/issue/52672
 		osyield()
 	}
@@ -157,7 +156,7 @@
 		cpuprof.lostExtra++
 	}
 
-	atomic.Store(&prof.signalLock, 0)
+	prof.signalLock.Store(0)
 }
 
 // addExtra adds the "extra" profiling events,
diff --git a/src/runtime/crash_cgo_test.go b/src/runtime/crash_cgo_test.go
index 5e58712..51d7bb5 100644
--- a/src/runtime/crash_cgo_test.go
+++ b/src/runtime/crash_cgo_test.go
@@ -8,6 +8,7 @@
 
 import (
 	"fmt"
+	"internal/goos"
 	"internal/testenv"
 	"os"
 	"os/exec"
@@ -217,7 +218,9 @@
 }
 
 func TestCgoPprofCallback(t *testing.T) {
-	t.Parallel()
+	if testing.Short() {
+		t.Skip("skipping in short mode") // takes a full second
+	}
 	switch runtime.GOOS {
 	case "windows", "plan9":
 		t.Skipf("skipping cgo pprof callback test on %s", runtime.GOOS)
@@ -603,8 +606,14 @@
 		t.Skipf("no signals on %s", runtime.GOOS)
 	}
 
-	for _, test := range []string{"Segv", "SegvInCgo"} {
+	for _, test := range []string{"Segv", "SegvInCgo", "TgkillSegv", "TgkillSegvInCgo"} {
 		test := test
+
+		// The tgkill variants only run on Linux.
+		if runtime.GOOS != "linux" && strings.HasPrefix(test, "Tgkill") {
+			continue
+		}
+
 		t.Run(test, func(t *testing.T) {
 			t.Parallel()
 			got := runTestProg(t, "testprogcgo", test)
@@ -633,9 +642,14 @@
 				testenv.SkipFlaky(t, 50979)
 			}
 
-			nowant := "runtime: "
-			if strings.Contains(got, nowant) {
-				t.Errorf("unexpectedly saw %q in output", nowant)
+			for _, nowant := range []string{"fatal error: ", "runtime: "} {
+				if strings.Contains(got, nowant) {
+					if runtime.GOOS == "darwin" && strings.Contains(got, "0xb01dfacedebac1e") {
+						// See the comment in signal_darwin_amd64.go.
+						t.Skip("skipping due to Darwin handling of malformed addresses")
+					}
+					t.Errorf("unexpectedly saw %q in output", nowant)
+				}
 			}
 		})
 	}
@@ -710,3 +724,47 @@
 		t.Fatalf("want %s, got %s\n", want, output)
 	}
 }
+
+func TestCgoTraceParser(t *testing.T) {
+	// Test issue 29707.
+	switch runtime.GOOS {
+	case "plan9", "windows":
+		t.Skipf("no pthreads on %s", runtime.GOOS)
+	}
+	output := runTestProg(t, "testprogcgo", "CgoTraceParser")
+	want := "OK\n"
+	ErrTimeOrder := "ErrTimeOrder\n"
+	if output == ErrTimeOrder {
+		t.Skipf("skipping due to golang.org/issue/16755: %v", output)
+	} else if output != want {
+		t.Fatalf("want %s, got %s\n", want, output)
+	}
+}
+
+func TestCgoTraceParserWithOneProc(t *testing.T) {
+	// Test issue 29707.
+	switch runtime.GOOS {
+	case "plan9", "windows":
+		t.Skipf("no pthreads on %s", runtime.GOOS)
+	}
+	output := runTestProg(t, "testprogcgo", "CgoTraceParser", "GOMAXPROCS=1")
+	want := "OK\n"
+	ErrTimeOrder := "ErrTimeOrder\n"
+	if output == ErrTimeOrder {
+		t.Skipf("skipping due to golang.org/issue/16755: %v", output)
+	} else if output != want {
+		t.Fatalf("GOMAXPROCS=1, want %s, got %s\n", want, output)
+	}
+}
+
+func TestCgoSigfwd(t *testing.T) {
+	t.Parallel()
+	if !goos.IsUnix {
+		t.Skipf("no signals on %s", runtime.GOOS)
+	}
+
+	got := runTestProg(t, "testprogcgo", "CgoSigfwd", "GO_TEST_CGOSIGFWD=1")
+	if want := "OK\n"; got != want {
+		t.Fatalf("expected %q, but got:\n%s", want, got)
+	}
+}
diff --git a/src/runtime/crash_test.go b/src/runtime/crash_test.go
index 01d7cbe..309777d 100644
--- a/src/runtime/crash_test.go
+++ b/src/runtime/crash_test.go
@@ -18,6 +18,7 @@
 	"strings"
 	"sync"
 	"testing"
+	"time"
 )
 
 var toRemove []string
@@ -58,18 +59,31 @@
 }
 
 func runBuiltTestProg(t *testing.T, exe, name string, env ...string) string {
+	t.Helper()
+
 	if *flagQuick {
 		t.Skip("-quick")
 	}
 
-	testenv.MustHaveGoBuild(t)
+	start := time.Now()
 
-	cmd := testenv.CleanCmdEnv(exec.Command(exe, name))
+	cmd := testenv.CleanCmdEnv(testenv.Command(t, exe, name))
 	cmd.Env = append(cmd.Env, env...)
 	if testing.Short() {
 		cmd.Env = append(cmd.Env, "RUNTIME_TEST_SHORT=1")
 	}
-	out, _ := testenv.RunWithTimeout(t, cmd)
+	out, err := cmd.CombinedOutput()
+	if err == nil {
+		t.Logf("%v (%v): ok", cmd, time.Since(start))
+	} else {
+		if _, ok := err.(*exec.ExitError); ok {
+			t.Logf("%v: %v", cmd, err)
+		} else if errors.Is(err, exec.ErrWaitDelay) {
+			t.Fatalf("%v: %v", cmd, err)
+		} else {
+			t.Fatalf("%v failed to start: %v", cmd, err)
+		}
+	}
 	return string(out)
 }
 
@@ -844,3 +858,11 @@
 		}
 	}
 }
+
+func TestPanicOnUnsafeSlice(t *testing.T) {
+	output := runTestProg(t, "testprog", "panicOnNilAndEleSizeIsZero")
+	want := "panic: runtime error: unsafe.Slice: ptr is nil and len is not zero"
+	if !strings.Contains(output, want) {
+		t.Errorf("output does not contain %q:\n%s", want, output)
+	}
+}
diff --git a/src/runtime/create_file_nounix.go b/src/runtime/create_file_nounix.go
new file mode 100644
index 0000000..60f7517
--- /dev/null
+++ b/src/runtime/create_file_nounix.go
@@ -0,0 +1,14 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !unix
+
+package runtime
+
+const canCreateFile = false
+
+func create(name *byte, perm int32) int32 {
+	throw("unimplemented")
+	return -1
+}
diff --git a/src/runtime/create_file_unix.go b/src/runtime/create_file_unix.go
new file mode 100644
index 0000000..7280810
--- /dev/null
+++ b/src/runtime/create_file_unix.go
@@ -0,0 +1,14 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build unix
+
+package runtime
+
+const canCreateFile = true
+
+// create returns an fd to a write-only file.
+func create(name *byte, perm int32) int32 {
+	return open(name, _O_CREAT|_O_WRONLY|_O_TRUNC, perm)
+}
diff --git a/src/runtime/debug.go b/src/runtime/debug.go
index 0ab23e0..669c36f 100644
--- a/src/runtime/debug.go
+++ b/src/runtime/debug.go
@@ -85,13 +85,13 @@
 //go:linkname mayMoreStackPreempt
 func mayMoreStackPreempt() {
 	// Don't do anything on the g0 or gsignal stack.
-	g := getg()
-	if g == g.m.g0 || g == g.m.gsignal {
+	gp := getg()
+	if gp == gp.m.g0 || gp == gp.m.gsignal {
 		return
 	}
 	// Force a preemption, unless the stack is already poisoned.
-	if g.stackguard0 < stackPoisonMin {
-		g.stackguard0 = stackPreempt
+	if gp.stackguard0 < stackPoisonMin {
+		gp.stackguard0 = stackPreempt
 	}
 }
 
@@ -104,12 +104,12 @@
 //go:linkname mayMoreStackMove
 func mayMoreStackMove() {
 	// Don't do anything on the g0 or gsignal stack.
-	g := getg()
-	if g == g.m.g0 || g == g.m.gsignal {
+	gp := getg()
+	if gp == gp.m.g0 || gp == gp.m.gsignal {
 		return
 	}
 	// Force stack movement, unless the stack is already poisoned.
-	if g.stackguard0 < stackPoisonMin {
-		g.stackguard0 = stackForceMove
+	if gp.stackguard0 < stackPoisonMin {
+		gp.stackguard0 = stackForceMove
 	}
 }
diff --git a/src/runtime/debug/mod.go b/src/runtime/debug/mod.go
index 688e258..8b7a423 100644
--- a/src/runtime/debug/mod.go
+++ b/src/runtime/debug/mod.go
@@ -11,7 +11,7 @@
 	"strings"
 )
 
-// exported from runtime
+// exported from runtime.
 func modinfo() string
 
 // ReadBuildInfo returns the build information embedded
@@ -39,14 +39,26 @@
 
 // BuildInfo represents the build information read from a Go binary.
 type BuildInfo struct {
-	GoVersion string         // Version of Go that produced this binary.
-	Path      string         // The main package path
-	Main      Module         // The module containing the main package
-	Deps      []*Module      // Module dependencies
-	Settings  []BuildSetting // Other information about the build.
+	// GoVersion is the version of the Go toolchain that built the binary
+	// (for example, "go1.19.2").
+	GoVersion string
+
+	// Path is the package path of the main package for the binary
+	// (for example, "golang.org/x/tools/cmd/stringer").
+	Path string
+
+	// Main describes the module that contains the main package for the binary.
+	Main Module
+
+	// Deps describes all the dependency modules, both direct and indirect,
+	// that contributed packages to the build of this binary.
+	Deps []*Module
+
+	// Settings describes the build settings used to build the binary.
+	Settings []BuildSetting
 }
 
-// Module represents a module.
+// A Module describes a single module included in a build.
 type Module struct {
 	Path    string  // module path
 	Version string  // module version
@@ -54,8 +66,24 @@
 	Replace *Module // replaced by this module
 }
 
-// BuildSetting describes a setting that may be used to understand how the
-// binary was built. For example, VCS commit and dirty status is stored here.
+// A BuildSetting is a key-value pair describing one setting that influenced a build.
+//
+// Defined keys include:
+//
+//   - -buildmode: the buildmode flag used (typically "exe")
+//   - -compiler: the compiler toolchain flag used (typically "gc")
+//   - CGO_ENABLED: the effective CGO_ENABLED environment variable
+//   - CGO_CFLAGS: the effective CGO_CFLAGS environment variable
+//   - CGO_CPPFLAGS: the effective CGO_CPPFLAGS environment variable
+//   - CGO_CXXFLAGS:  the effective CGO_CPPFLAGS environment variable
+//   - CGO_LDFLAGS: the effective CGO_CPPFLAGS environment variable
+//   - GOARCH: the architecture target
+//   - GOAMD64/GOARM64/GO386/etc: the architecture feature level for GOARCH
+//   - GOOS: the operating system target
+//   - vcs: the version control system for the source tree where the build ran
+//   - vcs.revision: the revision identifier for the current commit or checkout
+//   - vcs.time: the modification time associated with vcs.revision, in RFC3339 format
+//   - vcs.modified: true or false indicating whether the source tree had local modifications
 type BuildSetting struct {
 	// Key and Value describe the build setting.
 	// Key must not contain an equals sign, space, tab, or newline.
diff --git a/src/runtime/debugcall.go b/src/runtime/debugcall.go
index 2f164e7..a4393b1 100644
--- a/src/runtime/debugcall.go
+++ b/src/runtime/debugcall.go
@@ -158,11 +158,10 @@
 		gp.schedlink = 0
 
 		// Park the calling goroutine.
-		gp.waitreason = waitReasonDebugCall
 		if trace.enabled {
 			traceGoPark(traceEvGoBlock, 1)
 		}
-		casgstatus(gp, _Grunning, _Gwaiting)
+		casGToWaiting(gp, _Grunning, waitReasonDebugCall)
 		dropg()
 
 		// Directly execute the new goroutine. The debug
diff --git a/src/runtime/debuglog.go b/src/runtime/debuglog.go
index ca1a791..b18774e 100644
--- a/src/runtime/debuglog.go
+++ b/src/runtime/debuglog.go
@@ -17,6 +17,7 @@
 
 import (
 	"runtime/internal/atomic"
+	"runtime/internal/sys"
 	"unsafe"
 )
 
@@ -63,7 +64,7 @@
 		allp := (*uintptr)(unsafe.Pointer(&allDloggers))
 		all := (*dlogger)(unsafe.Pointer(atomic.Loaduintptr(allp)))
 		for l1 := all; l1 != nil; l1 = l1.allLink {
-			if atomic.Load(&l1.owned) == 0 && atomic.Cas(&l1.owned, 0, 1) {
+			if l1.owned.Load() == 0 && l1.owned.CompareAndSwap(0, 1) {
 				l = l1
 				break
 			}
@@ -79,7 +80,7 @@
 			throw("failed to allocate debug log")
 		}
 		l.w.r.data = &l.w.data
-		l.owned = 1
+		l.owned.Store(1)
 
 		// Prepend to allDloggers list.
 		headp := (*uintptr)(unsafe.Pointer(&allDloggers))
@@ -121,9 +122,8 @@
 //
 // To obtain a dlogger, call dlog(). When done with the dlogger, call
 // end().
-//
-//go:notinheap
 type dlogger struct {
+	_ sys.NotInHeap
 	w debugLogWriter
 
 	// allLink is the next dlogger in the allDloggers list.
@@ -131,7 +131,7 @@
 
 	// owned indicates that this dlogger is owned by an M. This is
 	// accessed atomically.
-	owned uint32
+	owned atomic.Uint32
 }
 
 // allDloggers is a list of all dloggers, linked through
@@ -160,7 +160,7 @@
 	}
 
 	// Return the logger to the global pool.
-	atomic.Store(&l.owned, 0)
+	l.owned.Store(0)
 }
 
 const (
@@ -292,21 +292,24 @@
 	if !dlogEnabled {
 		return l
 	}
-	str := stringStructOf(&x)
+
+	strData := unsafe.StringData(x)
 	datap := &firstmoduledata
-	if len(x) > 4 && datap.etext <= uintptr(str.str) && uintptr(str.str) < datap.end {
+	if len(x) > 4 && datap.etext <= uintptr(unsafe.Pointer(strData)) && uintptr(unsafe.Pointer(strData)) < datap.end {
 		// String constants are in the rodata section, which
 		// isn't recorded in moduledata. But it has to be
 		// somewhere between etext and end.
 		l.w.byte(debugLogConstString)
-		l.w.uvarint(uint64(str.len))
-		l.w.uvarint(uint64(uintptr(str.str) - datap.etext))
+		l.w.uvarint(uint64(len(x)))
+		l.w.uvarint(uint64(uintptr(unsafe.Pointer(strData)) - datap.etext))
 	} else {
 		l.w.byte(debugLogString)
+		// We can't use unsafe.Slice as it may panic, which isn't safe
+		// in this (potentially) nowritebarrier context.
 		var b []byte
 		bb := (*slice)(unsafe.Pointer(&b))
-		bb.array = str.str
-		bb.len, bb.cap = str.len, str.len
+		bb.array = unsafe.Pointer(strData)
+		bb.len, bb.cap = len(x), len(x)
 		if len(b) > debugLogStringLimit {
 			b = b[:debugLogStringLimit]
 		}
@@ -356,9 +359,8 @@
 // overwrite old records. Hence, it maintains a reader that consumes
 // the log as it gets overwritten. That reader state is where an
 // actual log reader would start.
-//
-//go:notinheap
 type debugLogWriter struct {
+	_     sys.NotInHeap
 	write uint64
 	data  debugLogBuf
 
@@ -376,8 +378,10 @@
 	buf [10]byte
 }
 
-//go:notinheap
-type debugLogBuf [debugLogBytes]byte
+type debugLogBuf struct {
+	_ sys.NotInHeap
+	b [debugLogBytes]byte
+}
 
 const (
 	// debugLogHeaderSize is the number of bytes in the framing
@@ -390,7 +394,7 @@
 
 //go:nosplit
 func (l *debugLogWriter) ensure(n uint64) {
-	for l.write+n >= l.r.begin+uint64(len(l.data)) {
+	for l.write+n >= l.r.begin+uint64(len(l.data.b)) {
 		// Consume record at begin.
 		if l.r.skip() == ^uint64(0) {
 			// Wrapped around within a record.
@@ -406,8 +410,8 @@
 
 //go:nosplit
 func (l *debugLogWriter) writeFrameAt(pos, size uint64) bool {
-	l.data[pos%uint64(len(l.data))] = uint8(size)
-	l.data[(pos+1)%uint64(len(l.data))] = uint8(size >> 8)
+	l.data.b[pos%uint64(len(l.data.b))] = uint8(size)
+	l.data.b[(pos+1)%uint64(len(l.data.b))] = uint8(size >> 8)
 	return size <= 0xFFFF
 }
 
@@ -441,7 +445,7 @@
 	l.ensure(1)
 	pos := l.write
 	l.write++
-	l.data[pos%uint64(len(l.data))] = x
+	l.data.b[pos%uint64(len(l.data.b))] = x
 }
 
 //go:nosplit
@@ -450,7 +454,7 @@
 	pos := l.write
 	l.write += uint64(len(x))
 	for len(x) > 0 {
-		n := copy(l.data[pos%uint64(len(l.data)):], x)
+		n := copy(l.data.b[pos%uint64(len(l.data.b)):], x)
 		pos += uint64(n)
 		x = x[n:]
 	}
@@ -513,15 +517,15 @@
 
 //go:nosplit
 func (r *debugLogReader) readUint16LEAt(pos uint64) uint16 {
-	return uint16(r.data[pos%uint64(len(r.data))]) |
-		uint16(r.data[(pos+1)%uint64(len(r.data))])<<8
+	return uint16(r.data.b[pos%uint64(len(r.data.b))]) |
+		uint16(r.data.b[(pos+1)%uint64(len(r.data.b))])<<8
 }
 
 //go:nosplit
 func (r *debugLogReader) readUint64LEAt(pos uint64) uint64 {
 	var b [8]byte
 	for i := range b {
-		b[i] = r.data[pos%uint64(len(r.data))]
+		b[i] = r.data.b[pos%uint64(len(r.data.b))]
 		pos++
 	}
 	return uint64(b[0]) | uint64(b[1])<<8 |
@@ -557,7 +561,7 @@
 	pos := r.begin + debugLogHeaderSize
 	var u uint64
 	for i := uint(0); ; i += 7 {
-		b := r.data[pos%uint64(len(r.data))]
+		b := r.data.b[pos%uint64(len(r.data.b))]
 		pos++
 		u |= uint64(b&^0x80) << i
 		if b&0x80 == 0 {
@@ -588,7 +592,7 @@
 func (r *debugLogReader) uvarint() uint64 {
 	var u uint64
 	for i := uint(0); ; i += 7 {
-		b := r.data[r.begin%uint64(len(r.data))]
+		b := r.data.b[r.begin%uint64(len(r.data.b))]
 		r.begin++
 		u |= uint64(b&^0x80) << i
 		if b&0x80 == 0 {
@@ -610,7 +614,7 @@
 }
 
 func (r *debugLogReader) printVal() bool {
-	typ := r.data[r.begin%uint64(len(r.data))]
+	typ := r.data.b[r.begin%uint64(len(r.data.b))]
 	r.begin++
 
 	switch typ {
@@ -644,7 +648,7 @@
 			break
 		}
 		for sl > 0 {
-			b := r.data[r.begin%uint64(len(r.data)):]
+			b := r.data.b[r.begin%uint64(len(r.data.b)):]
 			if uint64(len(b)) > sl {
 				b = b[:sl]
 			}
@@ -656,6 +660,8 @@
 	case debugLogConstString:
 		len, ptr := int(r.uvarint()), uintptr(r.uvarint())
 		ptr += firstmoduledata.etext
+		// We can't use unsafe.String as it may panic, which isn't safe
+		// in this (potentially) nowritebarrier context.
 		str := stringStruct{
 			str: unsafe.Pointer(ptr),
 			len: len,
diff --git a/src/runtime/debuglog_test.go b/src/runtime/debuglog_test.go
index 2570e35..18c54a8 100644
--- a/src/runtime/debuglog_test.go
+++ b/src/runtime/debuglog_test.go
@@ -23,8 +23,8 @@
 package runtime_test
 
 import (
-	"bytes"
 	"fmt"
+	"internal/testenv"
 	"regexp"
 	"runtime"
 	"strings"
@@ -94,7 +94,7 @@
 		}
 		wg.Done()
 	}()
-	var want bytes.Buffer
+	var want strings.Builder
 	for i := 0; i < 1000; i++ {
 		runtime.Dlog().I(i).End()
 		fmt.Fprintf(&want, "[] %d\n", i)
@@ -122,7 +122,7 @@
 
 	runtime.ResetDebugLog()
 	var longString = strings.Repeat("a", 128)
-	var want bytes.Buffer
+	var want strings.Builder
 	for i, j := 0, 0; j < 2*runtime.DebugLogBytes; i, j = i+1, j+len(longString) {
 		runtime.Dlog().I(i).S(longString).End()
 		fmt.Fprintf(&want, "[] %d %s\n", i, longString)
@@ -156,3 +156,14 @@
 		t.Fatalf("want %q, got %q", want, got)
 	}
 }
+
+// TestDebugLogBuild verifies that the runtime builds with -tags=debuglog.
+func TestDebugLogBuild(t *testing.T) {
+	testenv.MustHaveGoBuild(t)
+
+	// It doesn't matter which program we build, anything will rebuild the
+	// runtime.
+	if _, err := buildTestProg(t, "testprog", "-tags=debuglog"); err != nil {
+		t.Fatal(err)
+	}
+}
diff --git a/src/runtime/defs1_netbsd_386.go b/src/runtime/defs1_netbsd_386.go
index b6e47a0..f7fe45b 100644
--- a/src/runtime/defs1_netbsd_386.go
+++ b/src/runtime/defs1_netbsd_386.go
@@ -8,7 +8,10 @@
 	_EFAULT = 0xe
 	_EAGAIN = 0x23
 
+	_O_WRONLY   = 0x1
 	_O_NONBLOCK = 0x4
+	_O_CREAT    = 0x200
+	_O_TRUNC    = 0x400
 	_O_CLOEXEC  = 0x400000
 
 	_PROT_NONE  = 0x0
@@ -20,7 +23,8 @@
 	_MAP_PRIVATE = 0x2
 	_MAP_FIXED   = 0x10
 
-	_MADV_FREE = 0x6
+	_MADV_DONTNEED = 0x4
+	_MADV_FREE     = 0x6
 
 	_SA_SIGINFO = 0x40
 	_SA_RESTART = 0x2
diff --git a/src/runtime/defs1_netbsd_amd64.go b/src/runtime/defs1_netbsd_amd64.go
index b8292fa..80908cd 100644
--- a/src/runtime/defs1_netbsd_amd64.go
+++ b/src/runtime/defs1_netbsd_amd64.go
@@ -8,7 +8,10 @@
 	_EFAULT = 0xe
 	_EAGAIN = 0x23
 
+	_O_WRONLY   = 0x1
 	_O_NONBLOCK = 0x4
+	_O_CREAT    = 0x200
+	_O_TRUNC    = 0x400
 	_O_CLOEXEC  = 0x400000
 
 	_PROT_NONE  = 0x0
@@ -20,7 +23,8 @@
 	_MAP_PRIVATE = 0x2
 	_MAP_FIXED   = 0x10
 
-	_MADV_FREE = 0x6
+	_MADV_DONTNEED = 0x4
+	_MADV_FREE     = 0x6
 
 	_SA_SIGINFO = 0x40
 	_SA_RESTART = 0x2
diff --git a/src/runtime/defs1_netbsd_arm.go b/src/runtime/defs1_netbsd_arm.go
index d2cb486..c63e592 100644
--- a/src/runtime/defs1_netbsd_arm.go
+++ b/src/runtime/defs1_netbsd_arm.go
@@ -8,7 +8,10 @@
 	_EFAULT = 0xe
 	_EAGAIN = 0x23
 
+	_O_WRONLY   = 0x1
 	_O_NONBLOCK = 0x4
+	_O_CREAT    = 0x200
+	_O_TRUNC    = 0x400
 	_O_CLOEXEC  = 0x400000
 
 	_PROT_NONE  = 0x0
@@ -20,7 +23,8 @@
 	_MAP_PRIVATE = 0x2
 	_MAP_FIXED   = 0x10
 
-	_MADV_FREE = 0x6
+	_MADV_DONTNEED = 0x4
+	_MADV_FREE     = 0x6
 
 	_SA_SIGINFO = 0x40
 	_SA_RESTART = 0x2
diff --git a/src/runtime/defs1_netbsd_arm64.go b/src/runtime/defs1_netbsd_arm64.go
index 7776fe1..804b5b0 100644
--- a/src/runtime/defs1_netbsd_arm64.go
+++ b/src/runtime/defs1_netbsd_arm64.go
@@ -8,7 +8,10 @@
 	_EFAULT = 0xe
 	_EAGAIN = 0x23
 
+	_O_WRONLY   = 0x1
 	_O_NONBLOCK = 0x4
+	_O_CREAT    = 0x200
+	_O_TRUNC    = 0x400
 	_O_CLOEXEC  = 0x400000
 
 	_PROT_NONE  = 0x0
@@ -20,7 +23,8 @@
 	_MAP_PRIVATE = 0x2
 	_MAP_FIXED   = 0x10
 
-	_MADV_FREE = 0x6
+	_MADV_DONTNEED = 0x4
+	_MADV_FREE     = 0x6
 
 	_SA_SIGINFO = 0x40
 	_SA_RESTART = 0x2
diff --git a/src/runtime/defs1_solaris_amd64.go b/src/runtime/defs1_solaris_amd64.go
index 3c13f33..bb53c22 100644
--- a/src/runtime/defs1_solaris_amd64.go
+++ b/src/runtime/defs1_solaris_amd64.go
@@ -23,7 +23,8 @@
 	_MAP_PRIVATE = 0x2
 	_MAP_FIXED   = 0x10
 
-	_MADV_FREE = 0x5
+	_MADV_DONTNEED = 0x4
+	_MADV_FREE     = 0x5
 
 	_SA_SIGINFO = 0x8
 	_SA_RESTART = 0x4
@@ -90,7 +91,10 @@
 
 	_MAXHOSTNAMELEN = 0x100
 
+	_O_WRONLY   = 0x1
 	_O_NONBLOCK = 0x80
+	_O_TRUNC    = 0x200
+	_O_CREAT    = 0x100
 	_O_CLOEXEC  = 0x800000
 	_FD_CLOEXEC = 0x1
 	_F_GETFL    = 0x3
diff --git a/src/runtime/defs2_linux.go b/src/runtime/defs2_linux.go
index 41ad735..5d6730a 100644
--- a/src/runtime/defs2_linux.go
+++ b/src/runtime/defs2_linux.go
@@ -121,17 +121,6 @@
 
 	O_RDONLY  = C.O_RDONLY
 	O_CLOEXEC = C.O_CLOEXEC
-
-	EPOLLIN       = C.POLLIN
-	EPOLLOUT      = C.POLLOUT
-	EPOLLERR      = C.POLLERR
-	EPOLLHUP      = C.POLLHUP
-	EPOLLRDHUP    = C.POLLRDHUP
-	EPOLLET       = C.EPOLLET
-	EPOLL_CLOEXEC = C.EPOLL_CLOEXEC
-	EPOLL_CTL_ADD = C.EPOLL_CTL_ADD
-	EPOLL_CTL_DEL = C.EPOLL_CTL_DEL
-	EPOLL_CTL_MOD = C.EPOLL_CTL_MOD
 )
 
 type Fpreg C.struct__fpreg
diff --git a/src/runtime/defs_aix.go b/src/runtime/defs_aix.go
index b794cd5..3895989 100644
--- a/src/runtime/defs_aix.go
+++ b/src/runtime/defs_aix.go
@@ -124,7 +124,10 @@
 	_ITIMER_PROF    = C.ITIMER_PROF
 
 	_O_RDONLY   = C.O_RDONLY
+	_O_WRONLY   = C.O_WRONLY
 	_O_NONBLOCK = C.O_NONBLOCK
+	_O_CREAT    = C.O_CREAT
+	_O_TRUNC    = C.O_TRUNC
 
 	_SS_DISABLE  = C.SS_DISABLE
 	_SI_USER     = C.SI_USER
diff --git a/src/runtime/defs_aix_ppc64.go b/src/runtime/defs_aix_ppc64.go
index 4e20c85..2d25b7c 100644
--- a/src/runtime/defs_aix_ppc64.go
+++ b/src/runtime/defs_aix_ppc64.go
@@ -81,7 +81,10 @@
 	_ITIMER_PROF    = 0x2
 
 	_O_RDONLY   = 0x0
+	_O_WRONLY   = 0x1
 	_O_NONBLOCK = 0x4
+	_O_CREAT    = 0x100
+	_O_TRUNC    = 0x200
 
 	_SS_DISABLE  = 0x2
 	_SI_USER     = 0x0
diff --git a/src/runtime/defs_darwin.go b/src/runtime/defs_darwin.go
index 59b81cf..89e4253 100644
--- a/src/runtime/defs_darwin.go
+++ b/src/runtime/defs_darwin.go
@@ -120,7 +120,10 @@
 	F_SETFL    = C.F_SETFL
 	FD_CLOEXEC = C.FD_CLOEXEC
 
+	O_WRONLY   = C.O_WRONLY
 	O_NONBLOCK = C.O_NONBLOCK
+	O_CREAT    = C.O_CREAT
+	O_TRUNC    = C.O_TRUNC
 )
 
 type StackT C.struct_sigaltstack
diff --git a/src/runtime/defs_darwin_amd64.go b/src/runtime/defs_darwin_amd64.go
index cbc26bf..84e6f37 100644
--- a/src/runtime/defs_darwin_amd64.go
+++ b/src/runtime/defs_darwin_amd64.go
@@ -99,7 +99,10 @@
 	_F_SETFL    = 0x4
 	_FD_CLOEXEC = 0x1
 
-	_O_NONBLOCK = 4
+	_O_WRONLY   = 0x1
+	_O_NONBLOCK = 0x4
+	_O_CREAT    = 0x200
+	_O_TRUNC    = 0x400
 )
 
 type stackt struct {
diff --git a/src/runtime/defs_darwin_arm64.go b/src/runtime/defs_darwin_arm64.go
index 9076e8b..30d7443 100644
--- a/src/runtime/defs_darwin_arm64.go
+++ b/src/runtime/defs_darwin_arm64.go
@@ -101,7 +101,10 @@
 	_F_SETFL    = 0x4
 	_FD_CLOEXEC = 0x1
 
-	_O_NONBLOCK = 4
+	_O_WRONLY   = 0x1
+	_O_NONBLOCK = 0x4
+	_O_CREAT    = 0x200
+	_O_TRUNC    = 0x400
 )
 
 type stackt struct {
diff --git a/src/runtime/defs_dragonfly.go b/src/runtime/defs_dragonfly.go
index 952163b..9dcfdf0 100644
--- a/src/runtime/defs_dragonfly.go
+++ b/src/runtime/defs_dragonfly.go
@@ -32,7 +32,10 @@
 	EBUSY  = C.EBUSY
 	EAGAIN = C.EAGAIN
 
+	O_WRONLY   = C.O_WRONLY
 	O_NONBLOCK = C.O_NONBLOCK
+	O_CREAT    = C.O_CREAT
+	O_TRUNC    = C.O_TRUNC
 	O_CLOEXEC  = C.O_CLOEXEC
 
 	PROT_NONE  = C.PROT_NONE
@@ -44,7 +47,8 @@
 	MAP_PRIVATE = C.MAP_PRIVATE
 	MAP_FIXED   = C.MAP_FIXED
 
-	MADV_FREE = C.MADV_FREE
+	MADV_DONTNEED = C.MADV_DONTNEED
+	MADV_FREE     = C.MADV_FREE
 
 	SA_SIGINFO = C.SA_SIGINFO
 	SA_RESTART = C.SA_RESTART
diff --git a/src/runtime/defs_dragonfly_amd64.go b/src/runtime/defs_dragonfly_amd64.go
index 4358c1e..f1a2302 100644
--- a/src/runtime/defs_dragonfly_amd64.go
+++ b/src/runtime/defs_dragonfly_amd64.go
@@ -11,7 +11,10 @@
 	_EBUSY  = 0x10
 	_EAGAIN = 0x23
 
+	_O_WRONLY   = 0x1
 	_O_NONBLOCK = 0x4
+	_O_CREAT    = 0x200
+	_O_TRUNC    = 0x400
 	_O_CLOEXEC  = 0x20000
 
 	_PROT_NONE  = 0x0
@@ -23,7 +26,8 @@
 	_MAP_PRIVATE = 0x2
 	_MAP_FIXED   = 0x10
 
-	_MADV_FREE = 0x5
+	_MADV_DONTNEED = 0x4
+	_MADV_FREE     = 0x5
 
 	_SA_SIGINFO = 0x40
 	_SA_RESTART = 0x2
diff --git a/src/runtime/defs_freebsd.go b/src/runtime/defs_freebsd.go
index 3fbd580..d86ae91 100644
--- a/src/runtime/defs_freebsd.go
+++ b/src/runtime/defs_freebsd.go
@@ -16,10 +16,11 @@
 
 /*
 #include <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
 #include <sys/time.h>
 #include <signal.h>
 #include <errno.h>
-#define _WANT_FREEBSD11_KEVENT 1
 #include <sys/event.h>
 #include <sys/mman.h>
 #include <sys/ucontext.h>
@@ -45,11 +46,15 @@
 )
 
 const (
-	EINTR  = C.EINTR
-	EFAULT = C.EFAULT
-	EAGAIN = C.EAGAIN
+	EINTR     = C.EINTR
+	EFAULT    = C.EFAULT
+	EAGAIN    = C.EAGAIN
+	ETIMEDOUT = C.ETIMEDOUT
 
+	O_WRONLY   = C.O_WRONLY
 	O_NONBLOCK = C.O_NONBLOCK
+	O_CREAT    = C.O_CREAT
+	O_TRUNC    = C.O_TRUNC
 	O_CLOEXEC  = C.O_CLOEXEC
 
 	PROT_NONE  = C.PROT_NONE
@@ -62,7 +67,8 @@
 	MAP_PRIVATE = C.MAP_PRIVATE
 	MAP_FIXED   = C.MAP_FIXED
 
-	MADV_FREE = C.MADV_FREE
+	MADV_DONTNEED = C.MADV_DONTNEED
+	MADV_FREE     = C.MADV_FREE
 
 	SA_SIGINFO = C.SA_SIGINFO
 	SA_RESTART = C.SA_RESTART
@@ -154,7 +160,7 @@
 
 type Umtx_time C.struct__umtx_time
 
-type Kevent C.struct_kevent_freebsd11
+type KeventT C.struct_kevent
 
 type bintime C.struct_bintime
 type vdsoTimehands C.struct_vdso_timehands
diff --git a/src/runtime/defs_freebsd_386.go b/src/runtime/defs_freebsd_386.go
index ff4dcfa..ee82741 100644
--- a/src/runtime/defs_freebsd_386.go
+++ b/src/runtime/defs_freebsd_386.go
@@ -1,5 +1,6 @@
-// created by cgo -cdefs and then converted to Go
-// cgo -cdefs defs_freebsd.go
+// Code generated by cgo, then manually converted into appropriate naming and code
+// for the Go runtime.
+// go tool cgo -godefs defs_freebsd.go
 
 package runtime
 
@@ -18,7 +19,10 @@
 	_EAGAIN    = 0x23
 	_ETIMEDOUT = 0x3c
 
+	_O_WRONLY   = 0x1
 	_O_NONBLOCK = 0x4
+	_O_CREAT    = 0x200
+	_O_TRUNC    = 0x400
 	_O_CLOEXEC  = 0x100000
 
 	_PROT_NONE  = 0x0
@@ -31,7 +35,8 @@
 	_MAP_PRIVATE = 0x2
 	_MAP_FIXED   = 0x10
 
-	_MADV_FREE = 0x5
+	_MADV_DONTNEED = 0x4
+	_MADV_FREE     = 0x5
 
 	_SA_SIGINFO = 0x40
 	_SA_RESTART = 0x2
@@ -228,8 +233,9 @@
 	filter int16
 	flags  uint16
 	fflags uint32
-	data   int32
+	data   int64
 	udata  *byte
+	ext    [4]uint64
 }
 
 type bintime struct {
diff --git a/src/runtime/defs_freebsd_amd64.go b/src/runtime/defs_freebsd_amd64.go
index f537c89..9003f92 100644
--- a/src/runtime/defs_freebsd_amd64.go
+++ b/src/runtime/defs_freebsd_amd64.go
@@ -1,5 +1,6 @@
-// created by cgo -cdefs and then converted to Go
-// cgo -cdefs defs_freebsd.go
+// Code generated by cgo, then manually converted into appropriate naming and code
+// for the Go runtime.
+// go tool cgo -godefs defs_freebsd.go
 
 package runtime
 
@@ -18,7 +19,10 @@
 	_EAGAIN    = 0x23
 	_ETIMEDOUT = 0x3c
 
+	_O_WRONLY   = 0x1
 	_O_NONBLOCK = 0x4
+	_O_CREAT    = 0x200
+	_O_TRUNC    = 0x400
 	_O_CLOEXEC  = 0x100000
 
 	_PROT_NONE  = 0x0
@@ -31,7 +35,8 @@
 	_MAP_PRIVATE = 0x2
 	_MAP_FIXED   = 0x10
 
-	_MADV_FREE = 0x5
+	_MADV_DONTNEED = 0x4
+	_MADV_FREE     = 0x5
 
 	_SA_SIGINFO = 0x40
 	_SA_RESTART = 0x2
@@ -241,6 +246,7 @@
 	fflags uint32
 	data   int64
 	udata  *byte
+	ext    [4]uint64
 }
 
 type bintime struct {
diff --git a/src/runtime/defs_freebsd_arm.go b/src/runtime/defs_freebsd_arm.go
index 2e20ae7..68cc1b9 100644
--- a/src/runtime/defs_freebsd_arm.go
+++ b/src/runtime/defs_freebsd_arm.go
@@ -1,5 +1,6 @@
-// created by cgo -cdefs and then converted to Go
-// cgo -cdefs defs_freebsd.go
+// Code generated by cgo, then manually converted into appropriate naming and code
+// for the Go runtime.
+// go tool cgo -godefs defs_freebsd.go
 
 package runtime
 
@@ -18,7 +19,10 @@
 	_EAGAIN    = 0x23
 	_ETIMEDOUT = 0x3c
 
+	_O_WRONLY   = 0x1
 	_O_NONBLOCK = 0x4
+	_O_CREAT    = 0x200
+	_O_TRUNC    = 0x400
 	_O_CLOEXEC  = 0x100000
 
 	_PROT_NONE  = 0x0
@@ -31,7 +35,8 @@
 	_MAP_PRIVATE = 0x2
 	_MAP_FIXED   = 0x10
 
-	_MADV_FREE = 0x5
+	_MADV_DONTNEED = 0x4
+	_MADV_FREE     = 0x5
 
 	_SA_SIGINFO = 0x40
 	_SA_RESTART = 0x2
@@ -197,12 +202,15 @@
 }
 
 type keventt struct {
-	ident  uint32
-	filter int16
-	flags  uint16
-	fflags uint32
-	data   int32
-	udata  *byte
+	ident     uint32
+	filter    int16
+	flags     uint16
+	fflags    uint32
+	pad_cgo_0 [4]byte
+	data      int64
+	udata     *byte
+	pad_cgo_1 [4]byte
+	ext       [4]uint64
 }
 
 type bintime struct {
diff --git a/src/runtime/defs_freebsd_arm64.go b/src/runtime/defs_freebsd_arm64.go
index 1838108..1d67236 100644
--- a/src/runtime/defs_freebsd_arm64.go
+++ b/src/runtime/defs_freebsd_arm64.go
@@ -1,5 +1,6 @@
-// created by cgo -cdefs and then converted to Go
-// cgo -cdefs defs_freebsd.go
+// Code generated by cgo, then manually converted into appropriate naming and code
+// for the Go runtime.
+// go tool cgo -godefs defs_freebsd.go
 
 package runtime
 
@@ -18,7 +19,10 @@
 	_EAGAIN    = 0x23
 	_ETIMEDOUT = 0x3c
 
+	_O_WRONLY   = 0x1
 	_O_NONBLOCK = 0x4
+	_O_CREAT    = 0x200
+	_O_TRUNC    = 0x400
 	_O_CLOEXEC  = 0x100000
 
 	_PROT_NONE  = 0x0
@@ -31,7 +35,8 @@
 	_MAP_PRIVATE = 0x2
 	_MAP_FIXED   = 0x10
 
-	_MADV_FREE = 0x5
+	_MADV_DONTNEED = 0x4
+	_MADV_FREE     = 0x5
 
 	_SA_SIGINFO = 0x40
 	_SA_RESTART = 0x2
@@ -225,6 +230,7 @@
 	fflags uint32
 	data   int64
 	udata  *byte
+	ext    [4]uint64
 }
 
 type bintime struct {
diff --git a/src/runtime/defs_freebsd_riscv64.go b/src/runtime/defs_freebsd_riscv64.go
new file mode 100644
index 0000000..b977bde
--- /dev/null
+++ b/src/runtime/defs_freebsd_riscv64.go
@@ -0,0 +1,266 @@
+// created by cgo -cdefs and then converted to Go
+// cgo -cdefs defs_freebsd.go
+
+package runtime
+
+import "unsafe"
+
+const (
+	_NBBY            = 0x8
+	_CTL_MAXNAME     = 0x18
+	_CPU_LEVEL_WHICH = 0x3
+	_CPU_WHICH_PID   = 0x2
+)
+
+const (
+	_EINTR     = 0x4
+	_EFAULT    = 0xe
+	_EAGAIN    = 0x23
+	_ETIMEDOUT = 0x3c
+
+	_O_WRONLY   = 0x1
+	_O_NONBLOCK = 0x4
+	_O_CREAT    = 0x200
+	_O_TRUNC    = 0x400
+	_O_CLOEXEC  = 0x100000
+
+	_PROT_NONE  = 0x0
+	_PROT_READ  = 0x1
+	_PROT_WRITE = 0x2
+	_PROT_EXEC  = 0x4
+
+	_MAP_ANON    = 0x1000
+	_MAP_SHARED  = 0x1
+	_MAP_PRIVATE = 0x2
+	_MAP_FIXED   = 0x10
+
+	_MADV_DONTNEED = 0x4
+	_MADV_FREE     = 0x5
+
+	_SA_SIGINFO = 0x40
+	_SA_RESTART = 0x2
+	_SA_ONSTACK = 0x1
+
+	_CLOCK_MONOTONIC = 0x4
+	_CLOCK_REALTIME  = 0x0
+
+	_UMTX_OP_WAIT_UINT         = 0xb
+	_UMTX_OP_WAIT_UINT_PRIVATE = 0xf
+	_UMTX_OP_WAKE              = 0x3
+	_UMTX_OP_WAKE_PRIVATE      = 0x10
+
+	_SIGHUP    = 0x1
+	_SIGINT    = 0x2
+	_SIGQUIT   = 0x3
+	_SIGILL    = 0x4
+	_SIGTRAP   = 0x5
+	_SIGABRT   = 0x6
+	_SIGEMT    = 0x7
+	_SIGFPE    = 0x8
+	_SIGKILL   = 0x9
+	_SIGBUS    = 0xa
+	_SIGSEGV   = 0xb
+	_SIGSYS    = 0xc
+	_SIGPIPE   = 0xd
+	_SIGALRM   = 0xe
+	_SIGTERM   = 0xf
+	_SIGURG    = 0x10
+	_SIGSTOP   = 0x11
+	_SIGTSTP   = 0x12
+	_SIGCONT   = 0x13
+	_SIGCHLD   = 0x14
+	_SIGTTIN   = 0x15
+	_SIGTTOU   = 0x16
+	_SIGIO     = 0x17
+	_SIGXCPU   = 0x18
+	_SIGXFSZ   = 0x19
+	_SIGVTALRM = 0x1a
+	_SIGPROF   = 0x1b
+	_SIGWINCH  = 0x1c
+	_SIGINFO   = 0x1d
+	_SIGUSR1   = 0x1e
+	_SIGUSR2   = 0x1f
+
+	_FPE_INTDIV = 0x2
+	_FPE_INTOVF = 0x1
+	_FPE_FLTDIV = 0x3
+	_FPE_FLTOVF = 0x4
+	_FPE_FLTUND = 0x5
+	_FPE_FLTRES = 0x6
+	_FPE_FLTINV = 0x7
+	_FPE_FLTSUB = 0x8
+
+	_BUS_ADRALN = 0x1
+	_BUS_ADRERR = 0x2
+	_BUS_OBJERR = 0x3
+
+	_SEGV_MAPERR = 0x1
+	_SEGV_ACCERR = 0x2
+
+	_ITIMER_REAL    = 0x0
+	_ITIMER_VIRTUAL = 0x1
+	_ITIMER_PROF    = 0x2
+
+	_EV_ADD       = 0x1
+	_EV_DELETE    = 0x2
+	_EV_CLEAR     = 0x20
+	_EV_RECEIPT   = 0x40
+	_EV_ERROR     = 0x4000
+	_EV_EOF       = 0x8000
+	_EVFILT_READ  = -0x1
+	_EVFILT_WRITE = -0x2
+)
+
+type rtprio struct {
+	_type uint16
+	prio  uint16
+}
+
+type thrparam struct {
+	start_func uintptr
+	arg        unsafe.Pointer
+	stack_base uintptr
+	stack_size uintptr
+	tls_base   unsafe.Pointer
+	tls_size   uintptr
+	child_tid  unsafe.Pointer // *int64
+	parent_tid *int64
+	flags      int32
+	pad_cgo_0  [4]byte
+	rtp        *rtprio
+	spare      [3]uintptr
+}
+
+type thread int64 // long
+
+type sigset struct {
+	__bits [4]uint32
+}
+
+type stackt struct {
+	ss_sp     uintptr
+	ss_size   uintptr
+	ss_flags  int32
+	pad_cgo_0 [4]byte
+}
+
+type siginfo struct {
+	si_signo  int32
+	si_errno  int32
+	si_code   int32
+	si_pid    int32
+	si_uid    uint32
+	si_status int32
+	si_addr   uint64
+	si_value  [8]byte
+	_reason   [40]byte
+}
+
+type gpregs struct {
+	gp_ra      uint64
+	gp_sp      uint64
+	gp_gp      uint64
+	gp_tp      uint64
+	gp_t       [7]uint64
+	gp_s       [12]uint64
+	gp_a       [8]uint64
+	gp_sepc    uint64
+	gp_sstatus uint64
+}
+
+type fpregs struct {
+	fp_x     [64]uint64 // actually __uint64_t fp_x[32][2]
+	fp_fcsr  uint64
+	fp_flags int32
+	pad      int32
+}
+
+type mcontext struct {
+	mc_gpregs gpregs
+	mc_fpregs fpregs
+	mc_flags  int32
+	mc_pad    int32
+	mc_spare  [8]uint64
+}
+
+type ucontext struct {
+	uc_sigmask  sigset
+	uc_mcontext mcontext
+	uc_link     *ucontext
+	uc_stack    stackt
+	uc_flags    int32
+	__spare__   [4]int32
+	pad_cgo_0   [12]byte
+}
+
+type timespec struct {
+	tv_sec  int64
+	tv_nsec int64
+}
+
+//go:nosplit
+func (ts *timespec) setNsec(ns int64) {
+	ts.tv_sec = ns / 1e9
+	ts.tv_nsec = ns % 1e9
+}
+
+type timeval struct {
+	tv_sec  int64
+	tv_usec int64
+}
+
+func (tv *timeval) set_usec(x int32) {
+	tv.tv_usec = int64(x)
+}
+
+type itimerval struct {
+	it_interval timeval
+	it_value    timeval
+}
+
+type umtx_time struct {
+	_timeout timespec
+	_flags   uint32
+	_clockid uint32
+}
+
+type keventt struct {
+	ident  uint64
+	filter int16
+	flags  uint16
+	fflags uint32
+	data   int64
+	udata  *byte
+	ext    [4]uint64
+}
+
+type bintime struct {
+	sec  int64
+	frac uint64
+}
+
+type vdsoTimehands struct {
+	algo         uint32
+	gen          uint32
+	scale        uint64
+	offset_count uint32
+	counter_mask uint32
+	offset       bintime
+	boottime     bintime
+	physical     uint32
+	res          [7]uint32
+}
+
+type vdsoTimekeep struct {
+	ver       uint32
+	enabled   uint32
+	current   uint32
+	pad_cgo_0 [4]byte
+}
+
+const (
+	_VDSO_TK_VER_CURR = 0x1
+
+	vdsoTimehandsSize = 0x58
+	vdsoTimekeepSize  = 0x10
+)
diff --git a/src/runtime/defs_linux.go b/src/runtime/defs_linux.go
index e55bb6b..296fcb4 100644
--- a/src/runtime/defs_linux.go
+++ b/src/runtime/defs_linux.go
@@ -115,17 +115,6 @@
 	CLOCK_THREAD_CPUTIME_ID = C.CLOCK_THREAD_CPUTIME_ID
 
 	SIGEV_THREAD_ID = C.SIGEV_THREAD_ID
-
-	EPOLLIN       = C.POLLIN
-	EPOLLOUT      = C.POLLOUT
-	EPOLLERR      = C.POLLERR
-	EPOLLHUP      = C.POLLHUP
-	EPOLLRDHUP    = C.POLLRDHUP
-	EPOLLET       = C.EPOLLET
-	EPOLL_CLOEXEC = C.EPOLL_CLOEXEC
-	EPOLL_CTL_ADD = C.EPOLL_CTL_ADD
-	EPOLL_CTL_DEL = C.EPOLL_CTL_DEL
-	EPOLL_CTL_MOD = C.EPOLL_CTL_MOD
 )
 
 type Sigset C.sigset_t
@@ -136,4 +125,3 @@
 type Itimerspec C.struct_itimerspec
 type Itimerval C.struct_itimerval
 type Sigevent C.struct_sigevent
-type EpollEvent C.struct_epoll_event
diff --git a/src/runtime/defs_linux_386.go b/src/runtime/defs_linux_386.go
index 5376bde..72339f4 100644
--- a/src/runtime/defs_linux_386.go
+++ b/src/runtime/defs_linux_386.go
@@ -90,20 +90,12 @@
 	_SIGEV_THREAD_ID = 0x4
 
 	_O_RDONLY   = 0x0
+	_O_WRONLY   = 0x1
+	_O_CREAT    = 0x40
+	_O_TRUNC    = 0x200
 	_O_NONBLOCK = 0x800
 	_O_CLOEXEC  = 0x80000
 
-	_EPOLLIN       = 0x1
-	_EPOLLOUT      = 0x4
-	_EPOLLERR      = 0x8
-	_EPOLLHUP      = 0x10
-	_EPOLLRDHUP    = 0x2000
-	_EPOLLET       = 0x80000000
-	_EPOLL_CLOEXEC = 0x80000
-	_EPOLL_CTL_ADD = 0x1
-	_EPOLL_CTL_DEL = 0x2
-	_EPOLL_CTL_MOD = 0x3
-
 	_AF_UNIX    = 0x1
 	_SOCK_DGRAM = 0x2
 )
@@ -254,11 +246,6 @@
 	_ [_sigev_max_size - unsafe.Sizeof(sigeventFields{})]byte
 }
 
-type epollevent struct {
-	events uint32
-	data   [8]byte // to match amd64
-}
-
 type sockaddr_un struct {
 	family uint16
 	path   [108]byte
diff --git a/src/runtime/defs_linux_amd64.go b/src/runtime/defs_linux_amd64.go
index da4d357..298f3eb 100644
--- a/src/runtime/defs_linux_amd64.go
+++ b/src/runtime/defs_linux_amd64.go
@@ -89,17 +89,6 @@
 
 	_SIGEV_THREAD_ID = 0x4
 
-	_EPOLLIN       = 0x1
-	_EPOLLOUT      = 0x4
-	_EPOLLERR      = 0x8
-	_EPOLLHUP      = 0x10
-	_EPOLLRDHUP    = 0x2000
-	_EPOLLET       = 0x80000000
-	_EPOLL_CLOEXEC = 0x80000
-	_EPOLL_CTL_ADD = 0x1
-	_EPOLL_CTL_DEL = 0x2
-	_EPOLL_CTL_MOD = 0x3
-
 	_AF_UNIX    = 0x1
 	_SOCK_DGRAM = 0x2
 )
@@ -171,16 +160,14 @@
 	_ [_sigev_max_size - unsafe.Sizeof(sigeventFields{})]byte
 }
 
-type epollevent struct {
-	events uint32
-	data   [8]byte // unaligned uintptr
-}
-
 // created by cgo -cdefs and then converted to Go
 // cgo -cdefs defs_linux.go defs1_linux.go
 
 const (
 	_O_RDONLY   = 0x0
+	_O_WRONLY   = 0x1
+	_O_CREAT    = 0x40
+	_O_TRUNC    = 0x200
 	_O_NONBLOCK = 0x800
 	_O_CLOEXEC  = 0x80000
 )
diff --git a/src/runtime/defs_linux_arm.go b/src/runtime/defs_linux_arm.go
index 18aa093..6fee57d 100644
--- a/src/runtime/defs_linux_arm.go
+++ b/src/runtime/defs_linux_arm.go
@@ -80,6 +80,9 @@
 	_ITIMER_PROF    = 0x2
 	_ITIMER_VIRTUAL = 0x1
 	_O_RDONLY       = 0
+	_O_WRONLY       = 0x1
+	_O_CREAT        = 0x40
+	_O_TRUNC        = 0x200
 	_O_NONBLOCK     = 0x800
 	_O_CLOEXEC      = 0x80000
 
@@ -87,17 +90,6 @@
 
 	_SIGEV_THREAD_ID = 0x4
 
-	_EPOLLIN       = 0x1
-	_EPOLLOUT      = 0x4
-	_EPOLLERR      = 0x8
-	_EPOLLHUP      = 0x10
-	_EPOLLRDHUP    = 0x2000
-	_EPOLLET       = 0x80000000
-	_EPOLL_CLOEXEC = 0x80000
-	_EPOLL_CTL_ADD = 0x1
-	_EPOLL_CTL_DEL = 0x2
-	_EPOLL_CTL_MOD = 0x3
-
 	_AF_UNIX    = 0x1
 	_SOCK_DGRAM = 0x2
 )
@@ -208,12 +200,6 @@
 	sa_mask     uint64
 }
 
-type epollevent struct {
-	events uint32
-	_pad   uint32
-	data   [8]byte // to match amd64
-}
-
 type sockaddr_un struct {
 	family uint16
 	path   [108]byte
diff --git a/src/runtime/defs_linux_arm64.go b/src/runtime/defs_linux_arm64.go
index c5d7d7e..0216096 100644
--- a/src/runtime/defs_linux_arm64.go
+++ b/src/runtime/defs_linux_arm64.go
@@ -89,17 +89,6 @@
 
 	_SIGEV_THREAD_ID = 0x4
 
-	_EPOLLIN       = 0x1
-	_EPOLLOUT      = 0x4
-	_EPOLLERR      = 0x8
-	_EPOLLHUP      = 0x10
-	_EPOLLRDHUP    = 0x2000
-	_EPOLLET       = 0x80000000
-	_EPOLL_CLOEXEC = 0x80000
-	_EPOLL_CTL_ADD = 0x1
-	_EPOLL_CTL_DEL = 0x2
-	_EPOLL_CTL_MOD = 0x3
-
 	_AF_UNIX    = 0x1
 	_SOCK_DGRAM = 0x2
 )
@@ -171,17 +160,14 @@
 	_ [_sigev_max_size - unsafe.Sizeof(sigeventFields{})]byte
 }
 
-type epollevent struct {
-	events uint32
-	_pad   uint32
-	data   [8]byte // to match amd64
-}
-
 // Created by cgo -cdefs and then converted to Go by hand
 // ../cmd/cgo/cgo -cdefs defs_linux.go defs1_linux.go defs2_linux.go
 
 const (
 	_O_RDONLY   = 0x0
+	_O_WRONLY   = 0x1
+	_O_CREAT    = 0x40
+	_O_TRUNC    = 0x200
 	_O_NONBLOCK = 0x800
 	_O_CLOEXEC  = 0x80000
 )
diff --git a/src/runtime/defs_linux_loong64.go b/src/runtime/defs_linux_loong64.go
index dda4009..6eca18b 100644
--- a/src/runtime/defs_linux_loong64.go
+++ b/src/runtime/defs_linux_loong64.go
@@ -89,17 +89,6 @@
 	_CLOCK_THREAD_CPUTIME_ID = 0x3
 
 	_SIGEV_THREAD_ID = 0x4
-
-	_EPOLLIN       = 0x1
-	_EPOLLOUT      = 0x4
-	_EPOLLERR      = 0x8
-	_EPOLLHUP      = 0x10
-	_EPOLLRDHUP    = 0x2000
-	_EPOLLET       = 0x80000000
-	_EPOLL_CLOEXEC = 0x80000
-	_EPOLL_CTL_ADD = 0x1
-	_EPOLL_CTL_DEL = 0x2
-	_EPOLL_CTL_MOD = 0x3
 )
 
 type timespec struct {
@@ -146,14 +135,11 @@
 	_ [_sigev_max_size - unsafe.Sizeof(sigeventFields{})]byte
 }
 
-type epollevent struct {
-	events    uint32
-	pad_cgo_0 [4]byte
-	data      [8]byte // unaligned uintptr
-}
-
 const (
 	_O_RDONLY   = 0x0
+	_O_WRONLY   = 0x1
+	_O_CREAT    = 0x40
+	_O_TRUNC    = 0x200
 	_O_NONBLOCK = 0x800
 	_O_CLOEXEC  = 0x80000
 )
diff --git a/src/runtime/defs_linux_mips64x.go b/src/runtime/defs_linux_mips64x.go
index e645248..2e8c405 100644
--- a/src/runtime/defs_linux_mips64x.go
+++ b/src/runtime/defs_linux_mips64x.go
@@ -90,17 +90,6 @@
 	_CLOCK_THREAD_CPUTIME_ID = 0x3
 
 	_SIGEV_THREAD_ID = 0x4
-
-	_EPOLLIN       = 0x1
-	_EPOLLOUT      = 0x4
-	_EPOLLERR      = 0x8
-	_EPOLLHUP      = 0x10
-	_EPOLLRDHUP    = 0x2000
-	_EPOLLET       = 0x80000000
-	_EPOLL_CLOEXEC = 0x80000
-	_EPOLL_CTL_ADD = 0x1
-	_EPOLL_CTL_DEL = 0x2
-	_EPOLL_CTL_MOD = 0x3
 )
 
 //struct Sigset {
@@ -178,14 +167,11 @@
 	_ [_sigev_max_size - unsafe.Sizeof(sigeventFields{})]byte
 }
 
-type epollevent struct {
-	events    uint32
-	pad_cgo_0 [4]byte
-	data      [8]byte // unaligned uintptr
-}
-
 const (
 	_O_RDONLY    = 0x0
+	_O_WRONLY    = 0x1
+	_O_CREAT     = 0x100
+	_O_TRUNC     = 0x200
 	_O_NONBLOCK  = 0x80
 	_O_CLOEXEC   = 0x80000
 	_SA_RESTORER = 0
diff --git a/src/runtime/defs_linux_mipsx.go b/src/runtime/defs_linux_mipsx.go
index 5afb6f4..7593600 100644
--- a/src/runtime/defs_linux_mipsx.go
+++ b/src/runtime/defs_linux_mipsx.go
@@ -90,17 +90,6 @@
 	_CLOCK_THREAD_CPUTIME_ID = 0x3
 
 	_SIGEV_THREAD_ID = 0x4
-
-	_EPOLLIN       = 0x1
-	_EPOLLOUT      = 0x4
-	_EPOLLERR      = 0x8
-	_EPOLLHUP      = 0x10
-	_EPOLLRDHUP    = 0x2000
-	_EPOLLET       = 0x80000000
-	_EPOLL_CLOEXEC = 0x80000
-	_EPOLL_CTL_ADD = 0x1
-	_EPOLL_CTL_DEL = 0x2
-	_EPOLL_CTL_MOD = 0x3
 )
 
 type timespec struct {
@@ -172,15 +161,12 @@
 	_ [_sigev_max_size - unsafe.Sizeof(sigeventFields{})]byte
 }
 
-type epollevent struct {
-	events    uint32
-	pad_cgo_0 [4]byte
-	data      uint64
-}
-
 const (
 	_O_RDONLY    = 0x0
+	_O_WRONLY    = 0x1
 	_O_NONBLOCK  = 0x80
+	_O_CREAT     = 0x100
+	_O_TRUNC     = 0x200
 	_O_CLOEXEC   = 0x80000
 	_SA_RESTORER = 0
 )
diff --git a/src/runtime/defs_linux_ppc64.go b/src/runtime/defs_linux_ppc64.go
index f3e305e..bb3ac01 100644
--- a/src/runtime/defs_linux_ppc64.go
+++ b/src/runtime/defs_linux_ppc64.go
@@ -87,17 +87,6 @@
 	_CLOCK_THREAD_CPUTIME_ID = 0x3
 
 	_SIGEV_THREAD_ID = 0x4
-
-	_EPOLLIN       = 0x1
-	_EPOLLOUT      = 0x4
-	_EPOLLERR      = 0x8
-	_EPOLLHUP      = 0x10
-	_EPOLLRDHUP    = 0x2000
-	_EPOLLET       = 0x80000000
-	_EPOLL_CLOEXEC = 0x80000
-	_EPOLL_CTL_ADD = 0x1
-	_EPOLL_CTL_DEL = 0x2
-	_EPOLL_CTL_MOD = 0x3
 )
 
 //struct Sigset {
@@ -172,17 +161,14 @@
 	_ [_sigev_max_size - unsafe.Sizeof(sigeventFields{})]byte
 }
 
-type epollevent struct {
-	events    uint32
-	pad_cgo_0 [4]byte
-	data      [8]byte // unaligned uintptr
-}
-
 // created by cgo -cdefs and then converted to Go
 // cgo -cdefs defs_linux.go defs3_linux.go
 
 const (
 	_O_RDONLY    = 0x0
+	_O_WRONLY    = 0x1
+	_O_CREAT     = 0x40
+	_O_TRUNC     = 0x200
 	_O_NONBLOCK  = 0x800
 	_O_CLOEXEC   = 0x80000
 	_SA_RESTORER = 0
diff --git a/src/runtime/defs_linux_ppc64le.go b/src/runtime/defs_linux_ppc64le.go
index f3e305e..bb3ac01 100644
--- a/src/runtime/defs_linux_ppc64le.go
+++ b/src/runtime/defs_linux_ppc64le.go
@@ -87,17 +87,6 @@
 	_CLOCK_THREAD_CPUTIME_ID = 0x3
 
 	_SIGEV_THREAD_ID = 0x4
-
-	_EPOLLIN       = 0x1
-	_EPOLLOUT      = 0x4
-	_EPOLLERR      = 0x8
-	_EPOLLHUP      = 0x10
-	_EPOLLRDHUP    = 0x2000
-	_EPOLLET       = 0x80000000
-	_EPOLL_CLOEXEC = 0x80000
-	_EPOLL_CTL_ADD = 0x1
-	_EPOLL_CTL_DEL = 0x2
-	_EPOLL_CTL_MOD = 0x3
 )
 
 //struct Sigset {
@@ -172,17 +161,14 @@
 	_ [_sigev_max_size - unsafe.Sizeof(sigeventFields{})]byte
 }
 
-type epollevent struct {
-	events    uint32
-	pad_cgo_0 [4]byte
-	data      [8]byte // unaligned uintptr
-}
-
 // created by cgo -cdefs and then converted to Go
 // cgo -cdefs defs_linux.go defs3_linux.go
 
 const (
 	_O_RDONLY    = 0x0
+	_O_WRONLY    = 0x1
+	_O_CREAT     = 0x40
+	_O_TRUNC     = 0x200
 	_O_NONBLOCK  = 0x800
 	_O_CLOEXEC   = 0x80000
 	_SA_RESTORER = 0
diff --git a/src/runtime/defs_linux_riscv64.go b/src/runtime/defs_linux_riscv64.go
index 29496ac..ce4a7f3 100644
--- a/src/runtime/defs_linux_riscv64.go
+++ b/src/runtime/defs_linux_riscv64.go
@@ -89,17 +89,6 @@
 	_CLOCK_THREAD_CPUTIME_ID = 0x3
 
 	_SIGEV_THREAD_ID = 0x4
-
-	_EPOLLIN       = 0x1
-	_EPOLLOUT      = 0x4
-	_EPOLLERR      = 0x8
-	_EPOLLHUP      = 0x10
-	_EPOLLRDHUP    = 0x2000
-	_EPOLLET       = 0x80000000
-	_EPOLL_CLOEXEC = 0x80000
-	_EPOLL_CTL_ADD = 0x1
-	_EPOLL_CTL_DEL = 0x2
-	_EPOLL_CTL_MOD = 0x3
 )
 
 type timespec struct {
@@ -171,14 +160,11 @@
 	_ [_sigev_max_size - unsafe.Sizeof(sigeventFields{})]byte
 }
 
-type epollevent struct {
-	events    uint32
-	pad_cgo_0 [4]byte
-	data      [8]byte // unaligned uintptr
-}
-
 const (
 	_O_RDONLY   = 0x0
+	_O_WRONLY   = 0x1
+	_O_CREAT    = 0x40
+	_O_TRUNC    = 0x200
 	_O_NONBLOCK = 0x800
 	_O_CLOEXEC  = 0x80000
 )
diff --git a/src/runtime/defs_linux_s390x.go b/src/runtime/defs_linux_s390x.go
index 817a29e..36497dd 100644
--- a/src/runtime/defs_linux_s390x.go
+++ b/src/runtime/defs_linux_s390x.go
@@ -88,17 +88,6 @@
 	_CLOCK_THREAD_CPUTIME_ID = 0x3
 
 	_SIGEV_THREAD_ID = 0x4
-
-	_EPOLLIN       = 0x1
-	_EPOLLOUT      = 0x4
-	_EPOLLERR      = 0x8
-	_EPOLLHUP      = 0x10
-	_EPOLLRDHUP    = 0x2000
-	_EPOLLET       = 0x80000000
-	_EPOLL_CLOEXEC = 0x80000
-	_EPOLL_CTL_ADD = 0x1
-	_EPOLL_CTL_DEL = 0x2
-	_EPOLL_CTL_MOD = 0x3
 )
 
 type timespec struct {
@@ -168,14 +157,11 @@
 	_ [_sigev_max_size - unsafe.Sizeof(sigeventFields{})]byte
 }
 
-type epollevent struct {
-	events    uint32
-	pad_cgo_0 [4]byte
-	data      [8]byte // unaligned uintptr
-}
-
 const (
 	_O_RDONLY    = 0x0
+	_O_WRONLY    = 0x1
+	_O_CREAT     = 0x40
+	_O_TRUNC     = 0x200
 	_O_NONBLOCK  = 0x800
 	_O_CLOEXEC   = 0x80000
 	_SA_RESTORER = 0
diff --git a/src/runtime/defs_netbsd.go b/src/runtime/defs_netbsd.go
index 6b084c0..43923e3 100644
--- a/src/runtime/defs_netbsd.go
+++ b/src/runtime/defs_netbsd.go
@@ -34,7 +34,10 @@
 	EFAULT = C.EFAULT
 	EAGAIN = C.EAGAIN
 
+	O_WRONLY   = C.O_WRONLY
 	O_NONBLOCK = C.O_NONBLOCK
+	O_CREAT    = C.O_CREAT
+	O_TRUNC    = C.O_TRUNC
 	O_CLOEXEC  = C.O_CLOEXEC
 
 	PROT_NONE  = C.PROT_NONE
@@ -46,7 +49,8 @@
 	MAP_PRIVATE = C.MAP_PRIVATE
 	MAP_FIXED   = C.MAP_FIXED
 
-	MADV_FREE = C.MADV_FREE
+	MADV_DONTNEED = C.MADV_DONTNEED
+	MADV_FREE     = C.MADV_FREE
 
 	SA_SIGINFO = C.SA_SIGINFO
 	SA_RESTART = C.SA_RESTART
diff --git a/src/runtime/defs_openbsd.go b/src/runtime/defs_openbsd.go
index cbf53eb..4161e21 100644
--- a/src/runtime/defs_openbsd.go
+++ b/src/runtime/defs_openbsd.go
@@ -48,7 +48,8 @@
 	MAP_FIXED   = C.MAP_FIXED
 	MAP_STACK   = C.MAP_STACK
 
-	MADV_FREE = C.MADV_FREE
+	MADV_DONTNEED = C.MADV_DONTNEED
+	MADV_FREE     = C.MADV_FREE
 
 	SA_SIGINFO = C.SA_SIGINFO
 	SA_RESTART = C.SA_RESTART
diff --git a/src/runtime/defs_openbsd_386.go b/src/runtime/defs_openbsd_386.go
index 35c559b..25524c5 100644
--- a/src/runtime/defs_openbsd_386.go
+++ b/src/runtime/defs_openbsd_386.go
@@ -10,7 +10,10 @@
 	_EFAULT = 0xe
 	_EAGAIN = 0x23
 
+	_O_WRONLY   = 0x1
 	_O_NONBLOCK = 0x4
+	_O_CREAT    = 0x200
+	_O_TRUNC    = 0x400
 	_O_CLOEXEC  = 0x10000
 
 	_PROT_NONE  = 0x0
@@ -23,7 +26,8 @@
 	_MAP_FIXED   = 0x10
 	_MAP_STACK   = 0x4000
 
-	_MADV_FREE = 0x6
+	_MADV_DONTNEED = 0x4
+	_MADV_FREE     = 0x6
 
 	_SA_SIGINFO = 0x40
 	_SA_RESTART = 0x2
diff --git a/src/runtime/defs_openbsd_amd64.go b/src/runtime/defs_openbsd_amd64.go
index d7432da..a31d03b 100644
--- a/src/runtime/defs_openbsd_amd64.go
+++ b/src/runtime/defs_openbsd_amd64.go
@@ -10,7 +10,10 @@
 	_EFAULT = 0xe
 	_EAGAIN = 0x23
 
+	_O_WRONLY   = 0x1
 	_O_NONBLOCK = 0x4
+	_O_CREAT    = 0x200
+	_O_TRUNC    = 0x400
 	_O_CLOEXEC  = 0x10000
 
 	_PROT_NONE  = 0x0
@@ -23,7 +26,8 @@
 	_MAP_FIXED   = 0x10
 	_MAP_STACK   = 0x4000
 
-	_MADV_FREE = 0x6
+	_MADV_DONTNEED = 0x4
+	_MADV_FREE     = 0x6
 
 	_SA_SIGINFO = 0x40
 	_SA_RESTART = 0x2
diff --git a/src/runtime/defs_openbsd_arm.go b/src/runtime/defs_openbsd_arm.go
index 471b306..1d1767b 100644
--- a/src/runtime/defs_openbsd_arm.go
+++ b/src/runtime/defs_openbsd_arm.go
@@ -10,7 +10,10 @@
 	_EFAULT = 0xe
 	_EAGAIN = 0x23
 
+	_O_WRONLY   = 0x1
 	_O_NONBLOCK = 0x4
+	_O_CREAT    = 0x200
+	_O_TRUNC    = 0x400
 	_O_CLOEXEC  = 0x10000
 
 	_PROT_NONE  = 0x0
@@ -23,7 +26,8 @@
 	_MAP_FIXED   = 0x10
 	_MAP_STACK   = 0x4000
 
-	_MADV_FREE = 0x6
+	_MADV_DONTNEED = 0x4
+	_MADV_FREE     = 0x6
 
 	_SA_SIGINFO = 0x40
 	_SA_RESTART = 0x2
diff --git a/src/runtime/defs_openbsd_arm64.go b/src/runtime/defs_openbsd_arm64.go
index 5300ab0..745d0d3 100644
--- a/src/runtime/defs_openbsd_arm64.go
+++ b/src/runtime/defs_openbsd_arm64.go
@@ -11,7 +11,10 @@
 	_EFAULT = 0xe
 	_EAGAIN = 0x23
 
+	_O_WRONLY   = 0x1
 	_O_NONBLOCK = 0x4
+	_O_CREAT    = 0x200
+	_O_TRUNC    = 0x400
 	_O_CLOEXEC  = 0x10000
 
 	_PROT_NONE  = 0x0
@@ -24,7 +27,8 @@
 	_MAP_FIXED   = 0x10
 	_MAP_STACK   = 0x4000
 
-	_MADV_FREE = 0x6
+	_MADV_DONTNEED = 0x4
+	_MADV_FREE     = 0x6
 
 	_SA_SIGINFO = 0x40
 	_SA_RESTART = 0x2
diff --git a/src/runtime/defs_openbsd_mips64.go b/src/runtime/defs_openbsd_mips64.go
index a8789ef..1e469e4 100644
--- a/src/runtime/defs_openbsd_mips64.go
+++ b/src/runtime/defs_openbsd_mips64.go
@@ -17,7 +17,10 @@
 	_EFAULT = 0xe
 	_EAGAIN = 0x23
 
+	_O_WRONLY   = 0x1
 	_O_NONBLOCK = 0x4
+	_O_CREAT    = 0x200
+	_O_TRUNC    = 0x400
 	_O_CLOEXEC  = 0x10000
 
 	_PROT_NONE  = 0x0
@@ -30,7 +33,8 @@
 	_MAP_FIXED   = 0x10
 	_MAP_STACK   = 0x4000
 
-	_MADV_FREE = 0x6
+	_MADV_DONTNEED = 0x4
+	_MADV_FREE     = 0x6
 
 	_SA_SIGINFO = 0x40
 	_SA_RESTART = 0x2
diff --git a/src/runtime/defs_solaris.go b/src/runtime/defs_solaris.go
index f626498..406304d 100644
--- a/src/runtime/defs_solaris.go
+++ b/src/runtime/defs_solaris.go
@@ -53,7 +53,8 @@
 	MAP_PRIVATE = C.MAP_PRIVATE
 	MAP_FIXED   = C.MAP_FIXED
 
-	MADV_FREE = C.MADV_FREE
+	MADV_DONTNEED = C.MADV_DONTNEED
+	MADV_FREE     = C.MADV_FREE
 
 	SA_SIGINFO = C.SA_SIGINFO
 	SA_RESTART = C.SA_RESTART
@@ -119,7 +120,10 @@
 
 	MAXHOSTNAMELEN = C.MAXHOSTNAMELEN
 
+	O_WRONLY   = C.O_WRONLY
 	O_NONBLOCK = C.O_NONBLOCK
+	O_CREAT    = C.O_CREAT
+	O_TRUNC    = C.O_TRUNC
 	O_CLOEXEC  = C.O_CLOEXEC
 	FD_CLOEXEC = C.FD_CLOEXEC
 	F_GETFL    = C.F_GETFL
diff --git a/src/runtime/ehooks_test.go b/src/runtime/ehooks_test.go
new file mode 100644
index 0000000..ee286ec
--- /dev/null
+++ b/src/runtime/ehooks_test.go
@@ -0,0 +1,91 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime_test
+
+import (
+	"internal/platform"
+	"internal/testenv"
+	"os/exec"
+	"runtime"
+	"strings"
+	"testing"
+)
+
+func TestExitHooks(t *testing.T) {
+	bmodes := []string{""}
+	if testing.Short() {
+		t.Skip("skipping due to -short")
+	}
+	// Note the HasCGO() test below; this is to prevent the test
+	// running if CGO_ENABLED=0 is in effect.
+	haverace := platform.RaceDetectorSupported(runtime.GOOS, runtime.GOARCH)
+	if haverace && testenv.HasCGO() {
+		bmodes = append(bmodes, "-race")
+	}
+	for _, bmode := range bmodes {
+		scenarios := []struct {
+			mode     string
+			expected string
+			musthave string
+		}{
+			{
+				mode:     "simple",
+				expected: "bar foo",
+				musthave: "",
+			},
+			{
+				mode:     "goodexit",
+				expected: "orange apple",
+				musthave: "",
+			},
+			{
+				mode:     "badexit",
+				expected: "blub blix",
+				musthave: "",
+			},
+			{
+				mode:     "panics",
+				expected: "",
+				musthave: "fatal error: internal error: exit hook invoked panic",
+			},
+			{
+				mode:     "callsexit",
+				expected: "",
+				musthave: "fatal error: internal error: exit hook invoked exit",
+			},
+		}
+
+		exe, err := buildTestProg(t, "testexithooks", bmode)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		bt := ""
+		if bmode != "" {
+			bt = " bmode: " + bmode
+		}
+		for _, s := range scenarios {
+			cmd := exec.Command(exe, []string{"-mode", s.mode}...)
+			out, _ := cmd.CombinedOutput()
+			outs := strings.ReplaceAll(string(out), "\n", " ")
+			outs = strings.TrimSpace(outs)
+			if s.expected != "" {
+				if s.expected != outs {
+					t.Logf("raw output: %q", outs)
+					t.Errorf("failed%s mode %s: wanted %q got %q", bt,
+						s.mode, s.expected, outs)
+				}
+			} else if s.musthave != "" {
+				if !strings.Contains(outs, s.musthave) {
+					t.Logf("raw output: %q", outs)
+					t.Errorf("failed mode %s: output does not contain %q",
+						s.mode, s.musthave)
+				}
+			} else {
+				panic("badly written scenario")
+			}
+		}
+	}
+}
diff --git a/src/runtime/env_plan9.go b/src/runtime/env_plan9.go
index 65480c8..d206c5d 100644
--- a/src/runtime/env_plan9.go
+++ b/src/runtime/env_plan9.go
@@ -17,7 +17,7 @@
 	nameOffset = 39
 )
 
-// Goenvs caches the Plan 9 environment variables at start of execution into
+// goenvs caches the Plan 9 environment variables at start of execution into
 // string array envs, to supply the initial contents for os.Environ.
 // Subsequent calls to os.Setenv will change this cache, without writing back
 // to the (possibly shared) Plan 9 environment, so that Setenv and Getenv
@@ -70,7 +70,7 @@
 	})
 }
 
-// Dofiles reads the directory opened with file descriptor fd, applying function f
+// dofiles reads the directory opened with file descriptor fd, applying function f
 // to each filename in it.
 //
 //go:nosplit
@@ -95,7 +95,7 @@
 	}
 }
 
-// Gdirname returns the first filename from a buffer of directory entries,
+// gdirname returns the first filename from a buffer of directory entries,
 // and a slice containing the remaining directory entries.
 // If the buffer doesn't start with a valid directory entry, the returned name is nil.
 //
@@ -117,7 +117,7 @@
 	return
 }
 
-// Gbit16 reads a 16-bit little-endian binary number from b and returns it
+// gbit16 reads a 16-bit little-endian binary number from b and returns it
 // with the remaining slice of b.
 //
 //go:nosplit
diff --git a/src/runtime/env_posix.go b/src/runtime/env_posix.go
index 94a19d8..0eb4f0d 100644
--- a/src/runtime/env_posix.go
+++ b/src/runtime/env_posix.go
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build unix || (js && wasm) || windows || plan9
-
 package runtime
 
 import "unsafe"
@@ -48,10 +46,7 @@
 var _cgo_unsetenv unsafe.Pointer // pointer to C function
 
 // Update the C environment if cgo is loaded.
-// Called from syscall.Setenv.
-//
-//go:linkname syscall_setenv_c syscall.setenv_c
-func syscall_setenv_c(k string, v string) {
+func setenv_c(k string, v string) {
 	if _cgo_setenv == nil {
 		return
 	}
@@ -60,10 +55,7 @@
 }
 
 // Update the C environment if cgo is loaded.
-// Called from syscall.unsetenv.
-//
-//go:linkname syscall_unsetenv_c syscall.unsetenv_c
-func syscall_unsetenv_c(k string) {
+func unsetenv_c(k string) {
 	if _cgo_unsetenv == nil {
 		return
 	}
diff --git a/src/runtime/error.go b/src/runtime/error.go
index b11473c..a211fbf 100644
--- a/src/runtime/error.go
+++ b/src/runtime/error.go
@@ -151,7 +151,7 @@
 	boundsSlice3Acap: "slice bounds out of range [::%x] with capacity %y",
 	boundsSlice3B:    "slice bounds out of range [:%x:%y]",
 	boundsSlice3C:    "slice bounds out of range [%x:%y:]",
-	boundsConvert:    "cannot convert slice with length %y to pointer to array with length %x",
+	boundsConvert:    "cannot convert slice with length %y to array or pointer to array with length %x",
 }
 
 // boundsNegErrorFmts are overriding formats if x is negative. In this case there's no need to report y.
diff --git a/src/runtime/exithook.go b/src/runtime/exithook.go
new file mode 100644
index 0000000..bb29a94
--- /dev/null
+++ b/src/runtime/exithook.go
@@ -0,0 +1,69 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+// addExitHook registers the specified function 'f' to be run at
+// program termination (e.g. when someone invokes os.Exit(), or when
+// main.main returns). Hooks are run in reverse order of registration:
+// first hook added is the last one run.
+//
+// CAREFUL: the expectation is that addExitHook should only be called
+// from a safe context (e.g. not an error/panic path or signal
+// handler, preemption enabled, allocation allowed, write barriers
+// allowed, etc), and that the exit function 'f' will be invoked under
+// similar circumstances. That is the say, we are expecting that 'f'
+// uses normal / high-level Go code as opposed to one of the more
+// restricted dialects used for the trickier parts of the runtime.
+func addExitHook(f func(), runOnNonZeroExit bool) {
+	exitHooks.hooks = append(exitHooks.hooks, exitHook{f: f, runOnNonZeroExit: runOnNonZeroExit})
+}
+
+// exitHook stores a function to be run on program exit, registered
+// by the utility runtime.addExitHook.
+type exitHook struct {
+	f                func() // func to run
+	runOnNonZeroExit bool   // whether to run on non-zero exit code
+}
+
+// exitHooks stores state related to hook functions registered to
+// run when program execution terminates.
+var exitHooks struct {
+	hooks            []exitHook
+	runningExitHooks bool
+}
+
+// runExitHooks runs any registered exit hook functions (funcs
+// previously registered using runtime.addExitHook). Here 'exitCode'
+// is the status code being passed to os.Exit, or zero if the program
+// is terminating normally without calling os.Exit).
+func runExitHooks(exitCode int) {
+	if exitHooks.runningExitHooks {
+		throw("internal error: exit hook invoked exit")
+	}
+	exitHooks.runningExitHooks = true
+
+	runExitHook := func(f func()) (caughtPanic bool) {
+		defer func() {
+			if x := recover(); x != nil {
+				caughtPanic = true
+			}
+		}()
+		f()
+		return
+	}
+
+	finishPageTrace()
+	for i := range exitHooks.hooks {
+		h := exitHooks.hooks[len(exitHooks.hooks)-i-1]
+		if exitCode != 0 && !h.runOnNonZeroExit {
+			continue
+		}
+		if caughtPanic := runExitHook(h.f); caughtPanic {
+			throw("internal error: exit hook invoked panic")
+		}
+	}
+	exitHooks.hooks = nil
+	exitHooks.runningExitHooks = false
+}
diff --git a/src/runtime/export_debug_test.go b/src/runtime/export_debug_test.go
index 09e9779..2d8a133 100644
--- a/src/runtime/export_debug_test.go
+++ b/src/runtime/export_debug_test.go
@@ -109,7 +109,7 @@
 	// a signal handler. Add the go:nowritebarrierrec annotation and restructure
 	// this to avoid write barriers.
 
-	switch h.gp.atomicstatus {
+	switch h.gp.atomicstatus.Load() {
 	case _Grunning:
 		if getg().m != h.mp {
 			println("trap on wrong M", getg().m, h.mp)
diff --git a/src/runtime/export_debuglog_test.go b/src/runtime/export_debuglog_test.go
index 1a9074e..c9dfdcb 100644
--- a/src/runtime/export_debuglog_test.go
+++ b/src/runtime/export_debuglog_test.go
@@ -25,11 +25,11 @@
 func (l *dlogger) PC(x uintptr) *dlogger { return l.pc(x) }
 
 func DumpDebugLog() string {
-	g := getg()
-	g.writebuf = make([]byte, 0, 1<<20)
+	gp := getg()
+	gp.writebuf = make([]byte, 0, 1<<20)
 	printDebugLog()
-	buf := g.writebuf
-	g.writebuf = nil
+	buf := gp.writebuf
+	gp.writebuf = nil
 
 	return string(buf)
 }
diff --git a/src/runtime/export_linux_test.go b/src/runtime/export_linux_test.go
index dea94a9..a441c0e 100644
--- a/src/runtime/export_linux_test.go
+++ b/src/runtime/export_linux_test.go
@@ -6,19 +6,17 @@
 
 package runtime
 
-import "unsafe"
+import (
+	"runtime/internal/syscall"
+)
 
 const SiginfoMaxSize = _si_max_size
 const SigeventMaxSize = _sigev_max_size
 
+var Closeonexec = syscall.CloseOnExec
 var NewOSProc0 = newosproc0
 var Mincore = mincore
 var Add = add
 
-type EpollEvent epollevent
 type Siginfo siginfo
 type Sigevent sigevent
-
-func Epollctl(epfd, op, fd int32, ev unsafe.Pointer) int32 {
-	return epollctl(epfd, op, fd, (*epollevent)(ev))
-}
diff --git a/src/runtime/export_openbsd_test.go b/src/runtime/export_openbsd_test.go
new file mode 100644
index 0000000..ef680dc
--- /dev/null
+++ b/src/runtime/export_openbsd_test.go
@@ -0,0 +1,15 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build openbsd && !mips64
+
+package runtime
+
+func Fcntl(fd, cmd, arg uintptr) (uintptr, uintptr) {
+	r := fcntl(int32(fd), int32(cmd), int32(arg))
+	if r < 0 {
+		return ^uintptr(0), uintptr(-r)
+	}
+	return uintptr(r), 0
+}
diff --git a/src/runtime/export_test.go b/src/runtime/export_test.go
index 9639946..e7476e6 100644
--- a/src/runtime/export_test.go
+++ b/src/runtime/export_test.go
@@ -69,6 +69,9 @@
 func LFStackPop(head *uint64) *LFNode {
 	return (*LFNode)(unsafe.Pointer((*lfstack)(head).pop()))
 }
+func LFNodeValidate(node *LFNode) {
+	lfnodeValidate((*lfnode)(unsafe.Pointer(node)))
+}
 
 func Netpoll(delta int64) {
 	systemstack(func() {
@@ -84,23 +87,23 @@
 }
 
 func RunSchedLocalQueueTest() {
-	_p_ := new(p)
-	gs := make([]g, len(_p_.runq))
+	pp := new(p)
+	gs := make([]g, len(pp.runq))
 	Escape(gs) // Ensure gs doesn't move, since we use guintptrs
-	for i := 0; i < len(_p_.runq); i++ {
-		if g, _ := runqget(_p_); g != nil {
+	for i := 0; i < len(pp.runq); i++ {
+		if g, _ := runqget(pp); g != nil {
 			throw("runq is not empty initially")
 		}
 		for j := 0; j < i; j++ {
-			runqput(_p_, &gs[i], false)
+			runqput(pp, &gs[i], false)
 		}
 		for j := 0; j < i; j++ {
-			if g, _ := runqget(_p_); g != &gs[i] {
+			if g, _ := runqget(pp); g != &gs[i] {
 				print("bad element at iter ", i, "/", j, "\n")
 				throw("bad element")
 			}
 		}
-		if g, _ := runqget(_p_); g != nil {
+		if g, _ := runqget(pp); g != nil {
 			throw("runq is not empty afterwards")
 		}
 	}
@@ -362,6 +365,9 @@
 			if s.state.get() != mSpanInUse {
 				continue
 			}
+			if s.isUnusedUserArenaChunk() {
+				continue
+			}
 			if sizeclass := s.spanclass.sizeclass(); sizeclass == 0 {
 				slow.Mallocs++
 				slow.Alloc += uint64(s.elemsize)
@@ -460,17 +466,17 @@
 }
 
 func LockOSCounts() (external, internal uint32) {
-	g := getg()
-	if g.m.lockedExt+g.m.lockedInt == 0 {
-		if g.lockedm != 0 {
+	gp := getg()
+	if gp.m.lockedExt+gp.m.lockedInt == 0 {
+		if gp.lockedm != 0 {
 			panic("lockedm on non-locked goroutine")
 		}
 	} else {
-		if g.lockedm == 0 {
+		if gp.lockedm == 0 {
 			panic("nil lockedm on locked goroutine")
 		}
 	}
-	return g.m.lockedExt, g.m.lockedInt
+	return gp.m.lockedExt, gp.m.lockedInt
 }
 
 //go:noinline
@@ -500,7 +506,10 @@
 // MapNextArenaHint reserves a page at the next arena growth hint,
 // preventing the arena from growing there, and returns the range of
 // addresses that are no longer viable.
-func MapNextArenaHint() (start, end uintptr) {
+//
+// This may fail to reserve memory. If it fails, it still returns the
+// address range it attempted to reserve.
+func MapNextArenaHint() (start, end uintptr, ok bool) {
 	hint := mheap_.arenaHints
 	addr := hint.addr
 	if hint.down {
@@ -509,7 +518,13 @@
 	} else {
 		start, end = addr, addr+heapArenaBytes
 	}
-	sysReserve(unsafe.Pointer(addr), physPageSize)
+	got := sysReserve(unsafe.Pointer(addr), physPageSize)
+	ok = (addr == uintptr(got))
+	if !ok {
+		// We were unable to get the requested reservation.
+		// Release what we did get and fail.
+		sysFreeOS(got, physPageSize)
+	}
 	return
 }
 
@@ -525,6 +540,12 @@
 	return getg()
 }
 
+func GIsWaitingOnMutex(gp *G) bool {
+	return readgstatus(gp) == _Gwaiting && gp.waitreason.isMutexWait()
+}
+
+var CasGStatusAlwaysTrack = &casgstatusAlwaysTrack
+
 //go:noinline
 func PanicForTesting(b []byte, i int) byte {
 	return unexportedPanicForTesting(b, i)
@@ -1164,7 +1185,7 @@
 
 func SemNwait(addr *uint32) uint32 {
 	root := semtable.rootFor(addr)
-	return atomic.Load(&root.nwait)
+	return root.nwait.Load()
 }
 
 const SemTableSize = semTabSize
@@ -1196,8 +1217,6 @@
 }
 
 // mspan wrapper for testing.
-//
-//go:notinheap
 type MSpan mspan
 
 // Allocate an mspan for testing.
@@ -1230,23 +1249,29 @@
 }
 
 const (
-	TimeHistSubBucketBits   = timeHistSubBucketBits
-	TimeHistNumSubBuckets   = timeHistNumSubBuckets
-	TimeHistNumSuperBuckets = timeHistNumSuperBuckets
+	TimeHistSubBucketBits = timeHistSubBucketBits
+	TimeHistNumSubBuckets = timeHistNumSubBuckets
+	TimeHistNumBuckets    = timeHistNumBuckets
+	TimeHistMinBucketBits = timeHistMinBucketBits
+	TimeHistMaxBucketBits = timeHistMaxBucketBits
 )
 
 type TimeHistogram timeHistogram
 
 // Counts returns the counts for the given bucket, subBucket indices.
 // Returns true if the bucket was valid, otherwise returns the counts
-// for the underflow bucket and false.
-func (th *TimeHistogram) Count(bucket, subBucket uint) (uint64, bool) {
+// for the overflow bucket if bucket > 0 or the underflow bucket if
+// bucket < 0, and false.
+func (th *TimeHistogram) Count(bucket, subBucket int) (uint64, bool) {
 	t := (*timeHistogram)(th)
-	i := bucket*TimeHistNumSubBuckets + subBucket
-	if i >= uint(len(t.counts)) {
-		return t.underflow, false
+	if bucket < 0 {
+		return t.underflow.Load(), false
 	}
-	return t.counts[i], true
+	i := bucket*TimeHistNumSubBuckets + subBucket
+	if i >= len(t.counts) {
+		return t.overflow.Load(), false
+	}
+	return t.counts[i].Load(), true
 }
 
 func (th *TimeHistogram) Record(duration int64) {
@@ -1266,10 +1291,7 @@
 }
 
 func FinalizerGAsleep() bool {
-	lock(&finlock)
-	result := fingwait
-	unlock(&finlock)
-	return result
+	return fingStatus.Load()&fingWait != 0
 }
 
 // For GCTestMoveStackOnNextCall, it's important not to introduce an
@@ -1322,10 +1344,10 @@
 	if c.heapMarked > trigger {
 		trigger = c.heapMarked
 	}
-	c.maxStackScan = stackSize
-	c.globalsScan = globalsSize
-	c.heapLive = trigger
-	c.heapScan += uint64(float64(trigger-c.heapMarked) * scannableFrac)
+	c.maxStackScan.Store(stackSize)
+	c.globalsScan.Store(globalsSize)
+	c.heapLive.Store(trigger)
+	c.heapScan.Add(int64(float64(trigger-c.heapMarked) * scannableFrac))
 	c.startCycle(0, gomaxprocs, gcTrigger{kind: gcTriggerHeap})
 }
 
@@ -1338,7 +1360,7 @@
 }
 
 func (c *GCController) HeapLive() uint64 {
-	return c.heapLive
+	return c.heapLive.Load()
 }
 
 func (c *GCController) HeapMarked() uint64 {
@@ -1358,8 +1380,8 @@
 }
 
 func (c *GCController) Revise(d GCControllerReviseDelta) {
-	c.heapLive += uint64(d.HeapLive)
-	c.heapScan += uint64(d.HeapScan)
+	c.heapLive.Add(d.HeapLive)
+	c.heapScan.Add(d.HeapScan)
 	c.heapScanWork.Add(d.HeapScanWork)
 	c.stackScanWork.Add(d.StackScanWork)
 	c.globalsScanWork.Add(d.GlobalsScanWork)
@@ -1616,3 +1638,83 @@
 func (s *ScavengeIndex) Clear(ci ChunkIdx) {
 	s.i.clear(chunkIdx(ci))
 }
+
+const GTrackingPeriod = gTrackingPeriod
+
+var ZeroBase = unsafe.Pointer(&zerobase)
+
+const UserArenaChunkBytes = userArenaChunkBytes
+
+type UserArena struct {
+	arena *userArena
+}
+
+func NewUserArena() *UserArena {
+	return &UserArena{newUserArena()}
+}
+
+func (a *UserArena) New(out *any) {
+	i := efaceOf(out)
+	typ := i._type
+	if typ.kind&kindMask != kindPtr {
+		panic("new result of non-ptr type")
+	}
+	typ = (*ptrtype)(unsafe.Pointer(typ)).elem
+	i.data = a.arena.new(typ)
+}
+
+func (a *UserArena) Slice(sl any, cap int) {
+	a.arena.slice(sl, cap)
+}
+
+func (a *UserArena) Free() {
+	a.arena.free()
+}
+
+func GlobalWaitingArenaChunks() int {
+	n := 0
+	systemstack(func() {
+		lock(&mheap_.lock)
+		for s := mheap_.userArena.quarantineList.first; s != nil; s = s.next {
+			n++
+		}
+		unlock(&mheap_.lock)
+	})
+	return n
+}
+
+func UserArenaClone[T any](s T) T {
+	return arena_heapify(s).(T)
+}
+
+var AlignUp = alignUp
+
+// BlockUntilEmptyFinalizerQueue blocks until either the finalizer
+// queue is emptied (and the finalizers have executed) or the timeout
+// is reached. Returns true if the finalizer queue was emptied.
+func BlockUntilEmptyFinalizerQueue(timeout int64) bool {
+	start := nanotime()
+	for nanotime()-start < timeout {
+		lock(&finlock)
+		// We know the queue has been drained when both finq is nil
+		// and the finalizer g has stopped executing.
+		empty := finq == nil
+		empty = empty && readgstatus(fing) == _Gwaiting && fing.waitreason == waitReasonFinalizerWait
+		unlock(&finlock)
+		if empty {
+			return true
+		}
+		Gosched()
+	}
+	return false
+}
+
+func FrameStartLine(f *Frame) int {
+	return f.startLine
+}
+
+// PersistentAlloc allocates some memory that lives outside the Go heap.
+// This memory will never be freed; use sparingly.
+func PersistentAlloc(n uintptr) unsafe.Pointer {
+	return persistentalloc(n, 0, &memstats.other_sys)
+}
diff --git a/src/runtime/export_unix2_test.go b/src/runtime/export_unix2_test.go
new file mode 100644
index 0000000..360565f
--- /dev/null
+++ b/src/runtime/export_unix2_test.go
@@ -0,0 +1,10 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build unix && !linux
+
+package runtime
+
+// for linux close-on-exec implemented in runtime/internal/syscall
+var Closeonexec = closeonexec
diff --git a/src/runtime/export_unix_test.go b/src/runtime/export_unix_test.go
index a548cf7..71a55d8 100644
--- a/src/runtime/export_unix_test.go
+++ b/src/runtime/export_unix_test.go
@@ -9,7 +9,6 @@
 import "unsafe"
 
 var NonblockingPipe = nonblockingPipe
-var Closeonexec = closeonexec
 
 func sigismember(mask *sigset, i int) bool {
 	clear := *mask
@@ -90,3 +89,9 @@
 func SendSigusr1(mp *M) {
 	signalM(mp, _SIGUSR1)
 }
+
+const (
+	O_WRONLY = _O_WRONLY
+	O_CREAT  = _O_CREAT
+	O_TRUNC  = _O_TRUNC
+)
diff --git a/src/runtime/extern.go b/src/runtime/extern.go
index 15c519d..6c41c62 100644
--- a/src/runtime/extern.go
+++ b/src/runtime/extern.go
@@ -42,6 +42,12 @@
 	clobber the memory content of an object with bad content when it frees
 	the object.
 
+	cpu.*: cpu.all=off disables the use of all optional instruction set extensions.
+	cpu.extension=off disables use of instructions from the specified instruction set extension.
+	extension is the lower case name for the instruction set extension such as sse41 or avx
+	as listed in internal/cpu package. As an example cpu.avx=off disables runtime detection
+	and thereby use of AVX instructions.
+
 	cgocheck: setting cgocheck=0 disables all checks for packages
 	using cgo to incorrectly pass Go pointers to non-Go code.
 	Setting cgocheck=1 (the default) enables relatively cheap
@@ -73,7 +79,7 @@
 	error at each collection, summarizing the amount of memory collected and the
 	length of the pause. The format of this line is subject to change.
 	Currently, it is:
-		gc # @#s #%: #+#+# ms clock, #+#/#/#+# ms cpu, #->#-># MB, # MB goal, # P
+		gc # @#s #%: #+#+# ms clock, #+#/#/#+# ms cpu, #->#-># MB, # MB goal, # MB stacks, #MB globals, # P
 	where the fields are as follows:
 		gc #         the GC number, incremented at each GC
 		@#s          time in seconds since program start
@@ -112,12 +118,22 @@
 	madvdontneed: setting madvdontneed=0 will use MADV_FREE
 	instead of MADV_DONTNEED on Linux when returning memory to the
 	kernel. This is more efficient, but means RSS numbers will
-	drop only when the OS is under memory pressure.
+	drop only when the OS is under memory pressure. On the BSDs and
+	Illumos/Solaris, setting madvdontneed=1 will use MADV_DONTNEED instead
+	of MADV_FREE. This is less efficient, but causes RSS numbers to drop
+	more quickly.
 
 	memprofilerate: setting memprofilerate=X will update the value of runtime.MemProfileRate.
 	When set to 0 memory profiling is disabled.  Refer to the description of
 	MemProfileRate for the default value.
 
+	pagetrace: setting pagetrace=/path/to/file will write out a trace of page events
+	that can be viewed, analyzed, and visualized using the x/debug/cmd/pagetrace tool.
+	Build your program with GOEXPERIMENT=pagetrace to enable this functionality. Do not
+	enable this functionality if your program is a setuid binary as it introduces a security
+	risk in that scenario. Currently not supported on Windows, plan9 or js/wasm. Setting this
+	option for some applications can produce large traces, so use with care.
+
 	invalidptr: invalidptr=1 (the default) causes the garbage collector and stack
 	copier to crash the program if an invalid pointer value (for example, 1)
 	is found in a pointer-typed location. Setting invalidptr=0 disables this check.
diff --git a/src/runtime/float.go b/src/runtime/float.go
index c80c8b7..9f281c4 100644
--- a/src/runtime/float.go
+++ b/src/runtime/float.go
@@ -24,12 +24,12 @@
 	return !isNaN(f) && !isFinite(f)
 }
 
-// Abs returns the absolute value of x.
+// abs returns the absolute value of x.
 //
 // Special cases are:
 //
-//	Abs(±Inf) = +Inf
-//	Abs(NaN) = NaN
+//	abs(±Inf) = +Inf
+//	abs(NaN) = NaN
 func abs(x float64) float64 {
 	const sign = 1 << 63
 	return float64frombits(float64bits(x) &^ sign)
@@ -42,12 +42,12 @@
 	return float64frombits(float64bits(x)&^sign | float64bits(y)&sign)
 }
 
-// Float64bits returns the IEEE 754 binary representation of f.
+// float64bits returns the IEEE 754 binary representation of f.
 func float64bits(f float64) uint64 {
 	return *(*uint64)(unsafe.Pointer(&f))
 }
 
-// Float64frombits returns the floating point number corresponding
+// float64frombits returns the floating point number corresponding
 // the IEEE 754 binary representation b.
 func float64frombits(b uint64) float64 {
 	return *(*float64)(unsafe.Pointer(&b))
diff --git a/src/runtime/gc_test.go b/src/runtime/gc_test.go
index 122818f..0b2c972 100644
--- a/src/runtime/gc_test.go
+++ b/src/runtime/gc_test.go
@@ -689,7 +689,7 @@
 		time.Sleep(100 * time.Millisecond)
 		start := time.Now()
 		runtime.ReadMemStats(&ms)
-		latencies = append(latencies, time.Now().Sub(start))
+		latencies = append(latencies, time.Since(start))
 	}
 	// Make sure to stop the timer before we wait! The load created above
 	// is very heavy-weight and not easy to stop, so we could end up
diff --git a/src/runtime/hash_test.go b/src/runtime/hash_test.go
index e726006..d4a2b3f 100644
--- a/src/runtime/hash_test.go
+++ b/src/runtime/hash_test.go
@@ -6,6 +6,7 @@
 
 import (
 	"fmt"
+	"internal/race"
 	"math"
 	"math/rand"
 	. "runtime"
@@ -125,6 +126,9 @@
 
 // All 0-3 byte strings have distinct hashes.
 func TestSmhasherSmallKeys(t *testing.T) {
+	if race.Enabled {
+		t.Skip("Too long for race mode")
+	}
 	h := newHashSet()
 	var b [3]byte
 	for i := 0; i < 256; i++ {
@@ -166,6 +170,9 @@
 	if testing.Short() {
 		t.Skip("Skipping in short mode")
 	}
+	if race.Enabled {
+		t.Skip("Too long for race mode")
+	}
 	h := newHashSet()
 	for n := 2; n <= 16; n++ {
 		twoNonZero(h, n)
@@ -208,6 +215,9 @@
 	if testing.Short() {
 		t.Skip("Skipping in short mode")
 	}
+	if race.Enabled {
+		t.Skip("Too long for race mode")
+	}
 	r := rand.New(rand.NewSource(1234))
 	const REPEAT = 8
 	const N = 1000000
@@ -275,6 +285,9 @@
 	if testing.Short() {
 		t.Skip("Skipping in short mode")
 	}
+	if race.Enabled {
+		t.Skip("Too long for race mode")
+	}
 	permutation(t, []uint32{0, 1, 2, 3, 4, 5, 6, 7}, 8)
 	permutation(t, []uint32{0, 1 << 29, 2 << 29, 3 << 29, 4 << 29, 5 << 29, 6 << 29, 7 << 29}, 8)
 	permutation(t, []uint32{0, 1}, 20)
@@ -447,6 +460,9 @@
 	if testing.Short() {
 		t.Skip("Skipping in short mode")
 	}
+	if race.Enabled {
+		t.Skip("Too long for race mode")
+	}
 	avalancheTest1(t, &BytesKey{make([]byte, 2)})
 	avalancheTest1(t, &BytesKey{make([]byte, 4)})
 	avalancheTest1(t, &BytesKey{make([]byte, 8)})
@@ -514,6 +530,9 @@
 
 // All bit rotations of a set of distinct keys
 func TestSmhasherWindowed(t *testing.T) {
+	if race.Enabled {
+		t.Skip("Too long for race mode")
+	}
 	t.Logf("32 bit keys")
 	windowed(t, &Int32Key{})
 	t.Logf("64 bit keys")
diff --git a/src/runtime/heapdump.go b/src/runtime/heapdump.go
index c7f2b7a..f57a1a1 100644
--- a/src/runtime/heapdump.go
+++ b/src/runtime/heapdump.go
@@ -120,7 +120,7 @@
 
 var typecache [typeCacheBuckets]typeCacheBucket
 
-// dump a uint64 in a varint format parseable by encoding/binary
+// dump a uint64 in a varint format parseable by encoding/binary.
 func dumpint(v uint64) {
 	var buf [10]byte
 	var n int
@@ -142,7 +142,7 @@
 	}
 }
 
-// dump varint uint64 length followed by memory contents
+// dump varint uint64 length followed by memory contents.
 func dumpmemrange(data unsafe.Pointer, len uintptr) {
 	dumpint(uint64(len))
 	dwrite(data, len)
@@ -156,11 +156,10 @@
 }
 
 func dumpstr(s string) {
-	sp := stringStructOf(&s)
-	dumpmemrange(sp.str, uintptr(sp.len))
+	dumpmemrange(unsafe.Pointer(unsafe.StringData(s)), uintptr(len(s)))
 }
 
-// dump information for a type
+// dump information for a type.
 func dumptype(t *_type) {
 	if t == nil {
 		return
@@ -197,19 +196,17 @@
 	if x := t.uncommon(); x == nil || t.nameOff(x.pkgpath).name() == "" {
 		dumpstr(t.string())
 	} else {
-		pkgpathstr := t.nameOff(x.pkgpath).name()
-		pkgpath := stringStructOf(&pkgpathstr)
-		namestr := t.name()
-		name := stringStructOf(&namestr)
-		dumpint(uint64(uintptr(pkgpath.len) + 1 + uintptr(name.len)))
-		dwrite(pkgpath.str, uintptr(pkgpath.len))
+		pkgpath := t.nameOff(x.pkgpath).name()
+		name := t.name()
+		dumpint(uint64(uintptr(len(pkgpath)) + 1 + uintptr(len(name))))
+		dwrite(unsafe.Pointer(unsafe.StringData(pkgpath)), uintptr(len(pkgpath)))
 		dwritebyte('.')
-		dwrite(name.str, uintptr(name.len))
+		dwrite(unsafe.Pointer(unsafe.StringData(name)), uintptr(len(name)))
 	}
 	dumpbool(t.kind&kindDirectIface == 0 || t.ptrdata != 0)
 }
 
-// dump an object
+// dump an object.
 func dumpobj(obj unsafe.Pointer, size uintptr, bv bitvector) {
 	dumpint(tagObject)
 	dumpint(uint64(uintptr(obj)))
@@ -242,7 +239,7 @@
 	depth  uintptr   // depth in call stack (0 == most recent)
 }
 
-// dump kinds & offsets of interesting fields in bv
+// dump kinds & offsets of interesting fields in bv.
 func dumpbv(cbv *bitvector, offset uintptr) {
 	for i := uintptr(0); i < uintptr(cbv.n); i++ {
 		if cbv.ptrbit(i) == 1 {
@@ -327,7 +324,7 @@
 
 	// Record arg info for parent.
 	child.argoff = s.argp - s.fp
-	child.arglen = s.arglen
+	child.arglen = s.argBytes()
 	child.sp = (*uint8)(unsafe.Pointer(s.sp))
 	child.depth++
 	stkmap = (*stackmap)(funcdata(f, _FUNCDATA_ArgsPointerMaps))
@@ -354,7 +351,7 @@
 	dumpint(tagGoroutine)
 	dumpint(uint64(uintptr(unsafe.Pointer(gp))))
 	dumpint(uint64(sp))
-	dumpint(uint64(gp.goid))
+	dumpint(gp.goid)
 	dumpint(uint64(gp.gopc))
 	dumpint(uint64(readgstatus(gp)))
 	dumpbool(isSystemGoroutine(gp, false))
@@ -693,9 +690,8 @@
 func writeheapdump_m(fd uintptr, m *MemStats) {
 	assertWorldStopped()
 
-	_g_ := getg()
-	casgstatus(_g_.m.curg, _Grunning, _Gwaiting)
-	_g_.waitreason = waitReasonDumpingHeap
+	gp := getg()
+	casGToWaiting(gp.m.curg, _Grunning, waitReasonDumpingHeap)
 
 	// Set dump file.
 	dumpfd = fd
@@ -710,7 +706,7 @@
 		tmpbuf = nil
 	}
 
-	casgstatus(_g_.m.curg, _Gwaiting, _Grunning)
+	casgstatus(gp.m.curg, _Gwaiting, _Grunning)
 }
 
 // dumpint() the kind & offset of each field in an object.
@@ -737,16 +733,16 @@
 	for i := uintptr(0); i < nptr/8+1; i++ {
 		tmpbuf[i] = 0
 	}
-	i := uintptr(0)
-	hbits := heapBitsForAddr(p)
-	for ; i < nptr; i++ {
-		if !hbits.morePointers() {
-			break // end of object
+
+	hbits := heapBitsForAddr(p, size)
+	for {
+		var addr uintptr
+		hbits, addr = hbits.next()
+		if addr == 0 {
+			break
 		}
-		if hbits.isPointer() {
-			tmpbuf[i/8] |= 1 << (i % 8)
-		}
-		hbits = hbits.next()
+		i := (addr - p) / goarch.PtrSize
+		tmpbuf[i/8] |= 1 << (i % 8)
 	}
-	return bitvector{int32(i), &tmpbuf[0]}
+	return bitvector{int32(nptr), &tmpbuf[0]}
 }
diff --git a/src/runtime/histogram.go b/src/runtime/histogram.go
index eddfbab..43dfe61 100644
--- a/src/runtime/histogram.go
+++ b/src/runtime/histogram.go
@@ -12,72 +12,88 @@
 
 const (
 	// For the time histogram type, we use an HDR histogram.
-	// Values are placed in super-buckets based solely on the most
-	// significant set bit. Thus, super-buckets are power-of-2 sized.
+	// Values are placed in buckets based solely on the most
+	// significant set bit. Thus, buckets are power-of-2 sized.
 	// Values are then placed into sub-buckets based on the value of
 	// the next timeHistSubBucketBits most significant bits. Thus,
-	// sub-buckets are linear within a super-bucket.
+	// sub-buckets are linear within a bucket.
 	//
 	// Therefore, the number of sub-buckets (timeHistNumSubBuckets)
 	// defines the error. This error may be computed as
 	// 1/timeHistNumSubBuckets*100%. For example, for 16 sub-buckets
-	// per super-bucket the error is approximately 6%.
+	// per bucket the error is approximately 6%.
 	//
-	// The number of super-buckets (timeHistNumSuperBuckets), on the
-	// other hand, defines the range. To reserve room for sub-buckets,
-	// bit timeHistSubBucketBits is the first bit considered for
-	// super-buckets, so super-bucket indices are adjusted accordingly.
+	// The number of buckets (timeHistNumBuckets), on the
+	// other hand, defines the range. To avoid producing a large number
+	// of buckets that are close together, especially for small numbers
+	// (e.g. 1, 2, 3, 4, 5 ns) that aren't very useful, timeHistNumBuckets
+	// is defined in terms of the least significant bit (timeHistMinBucketBits)
+	// that needs to be set before we start bucketing and the most
+	// significant bit (timeHistMaxBucketBits) that we bucket before we just
+	// dump it into a catch-all bucket.
 	//
-	// As an example, consider 45 super-buckets with 16 sub-buckets.
+	// As an example, consider the configuration:
 	//
-	//    00110
-	//    ^----
-	//    │  ^
-	//    │  └---- Lowest 4 bits -> sub-bucket 6
-	//    └------- Bit 4 unset -> super-bucket 0
+	//    timeHistMinBucketBits = 9
+	//    timeHistMaxBucketBits = 48
+	//    timeHistSubBucketBits = 2
 	//
-	//    10110
-	//    ^----
-	//    │  ^
-	//    │  └---- Next 4 bits -> sub-bucket 6
-	//    └------- Bit 4 set -> super-bucket 1
-	//    100010
-	//    ^----^
-	//    │  ^ └-- Lower bits ignored
-	//    │  └---- Next 4 bits -> sub-bucket 1
-	//    └------- Bit 5 set -> super-bucket 2
+	// Then:
 	//
-	// Following this pattern, super-bucket 44 will have the bit 47 set. We don't
-	// have any buckets for higher values, so the highest sub-bucket will
-	// contain values of 2^48-1 nanoseconds or approx. 3 days. This range is
-	// more than enough to handle durations produced by the runtime.
-	timeHistSubBucketBits   = 4
-	timeHistNumSubBuckets   = 1 << timeHistSubBucketBits
-	timeHistNumSuperBuckets = 45
-	timeHistTotalBuckets    = timeHistNumSuperBuckets*timeHistNumSubBuckets + 1
+	//    011000001
+	//    ^--
+	//    │ ^
+	//    │ └---- Next 2 bits -> sub-bucket 3
+	//    └------- Bit 9 unset -> bucket 0
+	//
+	//    110000001
+	//    ^--
+	//    │ ^
+	//    │ └---- Next 2 bits -> sub-bucket 2
+	//    └------- Bit 9 set -> bucket 1
+	//
+	//    1000000010
+	//    ^-- ^
+	//    │ ^ └-- Lower bits ignored
+	//    │ └---- Next 2 bits -> sub-bucket 0
+	//    └------- Bit 10 set -> bucket 2
+	//
+	// Following this pattern, bucket 38 will have the bit 46 set. We don't
+	// have any buckets for higher values, so we spill the rest into an overflow
+	// bucket containing values of 2^47-1 nanoseconds or approx. 1 day or more.
+	// This range is more than enough to handle durations produced by the runtime.
+	timeHistMinBucketBits = 9
+	timeHistMaxBucketBits = 48 // Note that this is exclusive; 1 higher than the actual range.
+	timeHistSubBucketBits = 2
+	timeHistNumSubBuckets = 1 << timeHistSubBucketBits
+	timeHistNumBuckets    = timeHistMaxBucketBits - timeHistMinBucketBits + 1
+	// Two extra buckets, one for underflow, one for overflow.
+	timeHistTotalBuckets = timeHistNumBuckets*timeHistNumSubBuckets + 2
 )
 
 // timeHistogram represents a distribution of durations in
 // nanoseconds.
 //
 // The accuracy and range of the histogram is defined by the
-// timeHistSubBucketBits and timeHistNumSuperBuckets constants.
+// timeHistSubBucketBits and timeHistNumBuckets constants.
 //
 // It is an HDR histogram with exponentially-distributed
 // buckets and linearly distributed sub-buckets.
 //
-// Counts in the histogram are updated atomically, so it is safe
-// for concurrent use. It is also safe to read all the values
-// atomically.
+// The histogram is safe for concurrent reads and writes.
 type timeHistogram struct {
-	counts [timeHistNumSuperBuckets * timeHistNumSubBuckets]uint64
+	counts [timeHistNumBuckets * timeHistNumSubBuckets]atomic.Uint64
 
 	// underflow counts all the times we got a negative duration
 	// sample. Because of how time works on some platforms, it's
 	// possible to measure negative durations. We could ignore them,
 	// but we record them anyway because it's better to have some
 	// signal that it's happening than just missing samples.
-	underflow uint64
+	underflow atomic.Uint64
+
+	// overflow counts all the times we got a duration that exceeded
+	// the range counts represents.
+	overflow atomic.Uint64
 }
 
 // record adds the given duration to the distribution.
@@ -87,36 +103,35 @@
 //
 //go:nosplit
 func (h *timeHistogram) record(duration int64) {
+	// If the duration is negative, capture that in underflow.
 	if duration < 0 {
-		atomic.Xadd64(&h.underflow, 1)
+		h.underflow.Add(1)
 		return
 	}
-	// The index of the exponential bucket is just the index
-	// of the highest set bit adjusted for how many bits we
-	// use for the subbucket. Note that it's timeHistSubBucketsBits-1
-	// because we use the 0th bucket to hold values < timeHistNumSubBuckets.
-	var superBucket, subBucket uint
-	if duration >= timeHistNumSubBuckets {
-		// At this point, we know the duration value will always be
-		// at least timeHistSubBucketsBits long.
-		superBucket = uint(sys.Len64(uint64(duration))) - timeHistSubBucketBits
-		if superBucket*timeHistNumSubBuckets >= uint(len(h.counts)) {
-			// The bucket index we got is larger than what we support, so
-			// include this count in the highest bucket, which extends to
-			// infinity.
-			superBucket = timeHistNumSuperBuckets - 1
-			subBucket = timeHistNumSubBuckets - 1
-		} else {
-			// The linear subbucket index is just the timeHistSubBucketsBits
-			// bits after the top bit. To extract that value, shift down
-			// the duration such that we leave the top bit and the next bits
-			// intact, then extract the index.
-			subBucket = uint((duration >> (superBucket - 1)) % timeHistNumSubBuckets)
-		}
+	// bucketBit is the target bit for the bucket which is usually the
+	// highest 1 bit, but if we're less than the minimum, is the highest
+	// 1 bit of the minimum (which will be zero in the duration).
+	//
+	// bucket is the bucket index, which is the bucketBit minus the
+	// highest bit of the minimum, plus one to leave room for the catch-all
+	// bucket for samples lower than the minimum.
+	var bucketBit, bucket uint
+	if l := sys.Len64(uint64(duration)); l < timeHistMinBucketBits {
+		bucketBit = timeHistMinBucketBits
+		bucket = 0 // bucketBit - timeHistMinBucketBits
 	} else {
-		subBucket = uint(duration)
+		bucketBit = uint(l)
+		bucket = bucketBit - timeHistMinBucketBits + 1
 	}
-	atomic.Xadd64(&h.counts[superBucket*timeHistNumSubBuckets+subBucket], 1)
+	// If the bucket we computed is greater than the number of buckets,
+	// count that in overflow.
+	if bucket >= timeHistNumBuckets {
+		h.overflow.Add(1)
+		return
+	}
+	// The sub-bucket index is just next timeHistSubBucketBits after the bucketBit.
+	subBucket := uint(duration>>(bucketBit-1-timeHistSubBucketBits)) % timeHistNumSubBuckets
+	h.counts[bucket*timeHistNumSubBuckets+subBucket].Add(1)
 }
 
 const (
@@ -139,33 +154,37 @@
 // not nanoseconds like the timeHistogram represents durations.
 func timeHistogramMetricsBuckets() []float64 {
 	b := make([]float64, timeHistTotalBuckets+1)
+	// Underflow bucket.
 	b[0] = float64NegInf()
-	// Super-bucket 0 has no bits above timeHistSubBucketBits
-	// set, so just iterate over each bucket and assign the
-	// incrementing bucket.
-	for i := 0; i < timeHistNumSubBuckets; i++ {
-		bucketNanos := uint64(i)
-		b[i+1] = float64(bucketNanos) / 1e9
+
+	for j := 0; j < timeHistNumSubBuckets; j++ {
+		// No bucket bit for the first few buckets. Just sub-bucket bits after the
+		// min bucket bit.
+		bucketNanos := uint64(j) << (timeHistMinBucketBits - 1 - timeHistSubBucketBits)
+		// Convert nanoseconds to seconds via a division.
+		// These values will all be exactly representable by a float64.
+		b[j+1] = float64(bucketNanos) / 1e9
 	}
-	// Generate the rest of the super-buckets. It's easier to reason
-	// about if we cut out the 0'th bucket, so subtract one since
-	// we just handled that bucket.
-	for i := 0; i < timeHistNumSuperBuckets-1; i++ {
+	// Generate the rest of the buckets. It's easier to reason
+	// about if we cut out the 0'th bucket.
+	for i := timeHistMinBucketBits; i < timeHistMaxBucketBits; i++ {
 		for j := 0; j < timeHistNumSubBuckets; j++ {
-			// Set the super-bucket bit.
-			bucketNanos := uint64(1) << (i + timeHistSubBucketBits)
+			// Set the bucket bit.
+			bucketNanos := uint64(1) << (i - 1)
 			// Set the sub-bucket bits.
-			bucketNanos |= uint64(j) << i
-			// The index for this bucket is going to be the (i+1)'th super bucket
-			// (note that we're starting from zero, but handled the first super-bucket
+			bucketNanos |= uint64(j) << (i - 1 - timeHistSubBucketBits)
+			// The index for this bucket is going to be the (i+1)'th bucket
+			// (note that we're starting from zero, but handled the first bucket
 			// earlier, so we need to compensate), and the j'th sub bucket.
 			// Add 1 because we left space for -Inf.
-			bucketIndex := (i+1)*timeHistNumSubBuckets + j + 1
+			bucketIndex := (i-timeHistMinBucketBits+1)*timeHistNumSubBuckets + j + 1
 			// Convert nanoseconds to seconds via a division.
 			// These values will all be exactly representable by a float64.
 			b[bucketIndex] = float64(bucketNanos) / 1e9
 		}
 	}
+	// Overflow bucket.
+	b[len(b)-2] = float64(uint64(1)<<(timeHistMaxBucketBits-1)) / 1e9
 	b[len(b)-1] = float64Inf()
 	return b
 }
diff --git a/src/runtime/histogram_test.go b/src/runtime/histogram_test.go
index b12b65a..5246e86 100644
--- a/src/runtime/histogram_test.go
+++ b/src/runtime/histogram_test.go
@@ -20,50 +20,54 @@
 	h := &dummyTimeHistogram
 
 	// Record exactly one sample in each bucket.
-	for i := 0; i < TimeHistNumSuperBuckets; i++ {
-		var base int64
-		if i > 0 {
-			base = int64(1) << (i + TimeHistSubBucketBits - 1)
-		}
-		for j := 0; j < TimeHistNumSubBuckets; j++ {
-			v := int64(j)
-			if i > 0 {
-				v <<= i - 1
-			}
-			h.Record(base + v)
+	for j := 0; j < TimeHistNumSubBuckets; j++ {
+		v := int64(j) << (TimeHistMinBucketBits - 1 - TimeHistSubBucketBits)
+		for k := 0; k < j; k++ {
+			// Record a number of times equal to the bucket index.
+			h.Record(v)
 		}
 	}
-	// Hit the underflow bucket.
+	for i := TimeHistMinBucketBits; i < TimeHistMaxBucketBits; i++ {
+		base := int64(1) << (i - 1)
+		for j := 0; j < TimeHistNumSubBuckets; j++ {
+			v := int64(j) << (i - 1 - TimeHistSubBucketBits)
+			for k := 0; k < (i+1-TimeHistMinBucketBits)*TimeHistNumSubBuckets+j; k++ {
+				// Record a number of times equal to the bucket index.
+				h.Record(base + v)
+			}
+		}
+	}
+	// Hit the underflow and overflow buckets.
 	h.Record(int64(-1))
+	h.Record(math.MaxInt64)
+	h.Record(math.MaxInt64)
 
 	// Check to make sure there's exactly one count in each
 	// bucket.
-	for i := uint(0); i < TimeHistNumSuperBuckets; i++ {
-		for j := uint(0); j < TimeHistNumSubBuckets; j++ {
+	for i := 0; i < TimeHistNumBuckets; i++ {
+		for j := 0; j < TimeHistNumSubBuckets; j++ {
 			c, ok := h.Count(i, j)
 			if !ok {
-				t.Errorf("hit underflow bucket unexpectedly: (%d, %d)", i, j)
-			} else if c != 1 {
-				t.Errorf("bucket (%d, %d) has count that is not 1: %d", i, j, c)
+				t.Errorf("unexpected invalid bucket: (%d, %d)", i, j)
+			} else if idx := uint64(i*TimeHistNumSubBuckets + j); c != idx {
+				t.Errorf("bucket (%d, %d) has count that is not %d: %d", i, j, idx, c)
 			}
 		}
 	}
-	c, ok := h.Count(TimeHistNumSuperBuckets, 0)
+	c, ok := h.Count(-1, 0)
 	if ok {
-		t.Errorf("expected to hit underflow bucket: (%d, %d)", TimeHistNumSuperBuckets, 0)
+		t.Errorf("expected to hit underflow bucket: (%d, %d)", -1, 0)
 	}
 	if c != 1 {
-		t.Errorf("underflow bucket has count that is not 1: %d", c)
+		t.Errorf("overflow bucket has count that is not 1: %d", c)
 	}
 
-	// Check overflow behavior.
-	// By hitting a high value, we should just be adding into the highest bucket.
-	h.Record(math.MaxInt64)
-	c, ok = h.Count(TimeHistNumSuperBuckets-1, TimeHistNumSubBuckets-1)
-	if !ok {
-		t.Error("hit underflow bucket in highest bucket unexpectedly")
-	} else if c != 2 {
-		t.Errorf("highest has count that is not 2: %d", c)
+	c, ok = h.Count(TimeHistNumBuckets+1, 0)
+	if ok {
+		t.Errorf("expected to hit overflow bucket: (%d, %d)", TimeHistNumBuckets+1, 0)
+	}
+	if c != 2 {
+		t.Errorf("overflow bucket has count that is not 2: %d", c)
 	}
 
 	dummyTimeHistogram = TimeHistogram{}
@@ -72,34 +76,32 @@
 func TestTimeHistogramMetricsBuckets(t *testing.T) {
 	buckets := TimeHistogramMetricsBuckets()
 
-	nonInfBucketsLen := TimeHistNumSubBuckets * TimeHistNumSuperBuckets
-	expBucketsLen := nonInfBucketsLen + 2 // Count -Inf and +Inf.
+	nonInfBucketsLen := TimeHistNumSubBuckets * TimeHistNumBuckets
+	expBucketsLen := nonInfBucketsLen + 3 // Count -Inf, the edge for the overflow bucket, and +Inf.
 	if len(buckets) != expBucketsLen {
 		t.Fatalf("unexpected length of buckets: got %d, want %d", len(buckets), expBucketsLen)
 	}
-	// Check the first non-Inf 2*TimeHistNumSubBuckets buckets in order, skipping the
-	// first bucket which should be -Inf (checked later).
-	//
-	// Because of the way this scheme works, the bottom TimeHistNumSubBuckets
-	// buckets are fully populated, and then the next TimeHistNumSubBuckets
-	// have the TimeHistSubBucketBits'th bit set, while the bottom are once
-	// again fully populated.
-	for i := 1; i <= 2*TimeHistNumSubBuckets+1; i++ {
-		if got, want := buckets[i], float64(i-1)/1e9; got != want {
-			t.Errorf("expected bucket %d to have value %e, got %e", i, want, got)
-		}
-	}
 	// Check some values.
 	idxToBucket := map[int]float64{
 		0:                 math.Inf(-1),
-		33:                float64(0x10<<1) / 1e9,
-		34:                float64(0x11<<1) / 1e9,
-		49:                float64(0x10<<2) / 1e9,
-		58:                float64(0x19<<2) / 1e9,
-		65:                float64(0x10<<3) / 1e9,
-		513:               float64(0x10<<31) / 1e9,
-		519:               float64(0x16<<31) / 1e9,
-		expBucketsLen - 2: float64(0x1f<<43) / 1e9,
+		1:                 0.0,
+		2:                 float64(0x040) / 1e9,
+		3:                 float64(0x080) / 1e9,
+		4:                 float64(0x0c0) / 1e9,
+		5:                 float64(0x100) / 1e9,
+		6:                 float64(0x140) / 1e9,
+		7:                 float64(0x180) / 1e9,
+		8:                 float64(0x1c0) / 1e9,
+		9:                 float64(0x200) / 1e9,
+		10:                float64(0x280) / 1e9,
+		11:                float64(0x300) / 1e9,
+		12:                float64(0x380) / 1e9,
+		13:                float64(0x400) / 1e9,
+		15:                float64(0x600) / 1e9,
+		81:                float64(0x8000000) / 1e9,
+		82:                float64(0xa000000) / 1e9,
+		108:               float64(0x380000000) / 1e9,
+		expBucketsLen - 2: float64(0x1<<47) / 1e9,
 		expBucketsLen - 1: math.Inf(1),
 	}
 	for idx, bucket := range idxToBucket {
diff --git a/src/runtime/internal/atomic/atomic_loong64.go b/src/runtime/internal/atomic/atomic_loong64.go
index 908a7d6..d82a5b8 100644
--- a/src/runtime/internal/atomic/atomic_loong64.go
+++ b/src/runtime/internal/atomic/atomic_loong64.go
@@ -42,6 +42,9 @@
 func LoadAcq(ptr *uint32) uint32
 
 //go:noescape
+func LoadAcq64(ptr *uint64) uint64
+
+//go:noescape
 func LoadAcquintptr(ptr *uintptr) uintptr
 
 //go:noescape
@@ -80,4 +83,7 @@
 func StoreRel(ptr *uint32, val uint32)
 
 //go:noescape
+func StoreRel64(ptr *uint64, val uint64)
+
+//go:noescape
 func StoreReluintptr(ptr *uintptr, val uintptr)
diff --git a/src/runtime/internal/atomic/atomic_loong64.s b/src/runtime/internal/atomic/atomic_loong64.s
index bfb6c7e..3d802be 100644
--- a/src/runtime/internal/atomic/atomic_loong64.s
+++ b/src/runtime/internal/atomic/atomic_loong64.s
@@ -156,6 +156,9 @@
 TEXT ·StoreRel(SB), NOSPLIT, $0-12
 	JMP	·Store(SB)
 
+TEXT ·StoreRel64(SB), NOSPLIT, $0-16
+	JMP	·Store64(SB)
+
 TEXT ·StoreReluintptr(SB), NOSPLIT, $0-16
 	JMP     ·Store64(SB)
 
@@ -293,6 +296,10 @@
 TEXT ·LoadAcq(SB),NOSPLIT|NOFRAME,$0-12
 	JMP	atomic·Load(SB)
 
+// uint64 ·LoadAcq64(uint64 volatile* ptr)
+TEXT ·LoadAcq64(SB),NOSPLIT|NOFRAME,$0-16
+	JMP	atomic·Load64(SB)
+
 // uintptr ·LoadAcquintptr(uintptr volatile* ptr)
 TEXT ·LoadAcquintptr(SB),NOSPLIT|NOFRAME,$0-16
 	JMP     atomic·Load64(SB)
diff --git a/src/runtime/internal/atomic/atomic_test.go b/src/runtime/internal/atomic/atomic_test.go
index 2ae60b8..2427bfd 100644
--- a/src/runtime/internal/atomic/atomic_test.go
+++ b/src/runtime/internal/atomic/atomic_test.go
@@ -345,6 +345,36 @@
 	}
 }
 
+func TestCasRel(t *testing.T) {
+	const _magic = 0x5a5aa5a5
+	var x struct {
+		before uint32
+		i      uint32
+		after  uint32
+		o      uint32
+		n      uint32
+	}
+
+	x.before = _magic
+	x.after = _magic
+	for j := 0; j < 32; j += 1 {
+		x.i = (1 << j) + 0
+		x.o = (1 << j) + 0
+		x.n = (1 << j) + 1
+		if !atomic.CasRel(&x.i, x.o, x.n) {
+			t.Fatalf("should have swapped %#x %#x", x.o, x.n)
+		}
+
+		if x.i != x.n {
+			t.Fatalf("wrong x.i after swap: x.i=%#x x.n=%#x", x.i, x.n)
+		}
+
+		if x.before != _magic || x.after != _magic {
+			t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, _magic, _magic)
+		}
+	}
+}
+
 func TestStorepNoWB(t *testing.T) {
 	var p [2]*int
 	for i := range p {
diff --git a/src/runtime/internal/atomic/sys_linux_arm.s b/src/runtime/internal/atomic/sys_linux_arm.s
index 0cc7fa7..9225df8 100644
--- a/src/runtime/internal/atomic/sys_linux_arm.s
+++ b/src/runtime/internal/atomic/sys_linux_arm.s
@@ -15,9 +15,6 @@
 //	LR = return address
 // The function returns with CS true if the swap happened.
 // http://lxr.linux.no/linux+v2.6.37.2/arch/arm/kernel/entry-armv.S#L850
-// On older kernels (before 2.6.24) the function can incorrectly
-// report a conflict, so we have to double-check the compare ourselves
-// and retry if necessary.
 //
 // https://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=b49c0f24cf6744a3f4fd09289fe7cade349dead5
 //
@@ -37,20 +34,13 @@
 	// because we don't know how to traceback through __kuser_cmpxchg
 	MOVW    (R2), R0
 	MOVW	old+4(FP), R0
-loop:
 	MOVW	new+8(FP), R1
 	BL	cas<>(SB)
-	BCC	check
+	BCC	ret0
 	MOVW	$1, R0
 	MOVB	R0, ret+12(FP)
 	RET
-check:
-	// Kernel lies; double-check.
-	MOVW	ptr+0(FP), R2
-	MOVW	old+4(FP), R0
-	MOVW	0(R2), R3
-	CMP	R0, R3
-	BEQ	loop
+ret0:
 	MOVW	$0, R0
 	MOVB	R0, ret+12(FP)
 	RET
diff --git a/src/runtime/internal/atomic/types.go b/src/runtime/internal/atomic/types.go
index d346a76..0d75226 100644
--- a/src/runtime/internal/atomic/types.go
+++ b/src/runtime/internal/atomic/types.go
@@ -15,25 +15,32 @@
 }
 
 // Load accesses and returns the value atomically.
+//
+//go:nosplit
 func (i *Int32) Load() int32 {
 	return Loadint32(&i.value)
 }
 
 // Store updates the value atomically.
+//
+//go:nosplit
 func (i *Int32) Store(value int32) {
 	Storeint32(&i.value, value)
 }
 
 // CompareAndSwap atomically compares i's value with old,
 // and if they're equal, swaps i's value with new.
+// It reports whether the swap ran.
 //
-// Returns true if the operation succeeded.
+//go:nosplit
 func (i *Int32) CompareAndSwap(old, new int32) bool {
 	return Casint32(&i.value, old, new)
 }
 
 // Swap replaces i's value with new, returning
 // i's value before the replacement.
+//
+//go:nosplit
 func (i *Int32) Swap(new int32) int32 {
 	return Xchgint32(&i.value, new)
 }
@@ -43,6 +50,8 @@
 //
 // This operation wraps around in the usual
 // two's-complement way.
+//
+//go:nosplit
 func (i *Int32) Add(delta int32) int32 {
 	return Xaddint32(&i.value, delta)
 }
@@ -59,25 +68,32 @@
 }
 
 // Load accesses and returns the value atomically.
+//
+//go:nosplit
 func (i *Int64) Load() int64 {
 	return Loadint64(&i.value)
 }
 
 // Store updates the value atomically.
+//
+//go:nosplit
 func (i *Int64) Store(value int64) {
 	Storeint64(&i.value, value)
 }
 
 // CompareAndSwap atomically compares i's value with old,
 // and if they're equal, swaps i's value with new.
+// It reports whether the swap ran.
 //
-// Returns true if the operation succeeded.
+//go:nosplit
 func (i *Int64) CompareAndSwap(old, new int64) bool {
 	return Casint64(&i.value, old, new)
 }
 
 // Swap replaces i's value with new, returning
 // i's value before the replacement.
+//
+//go:nosplit
 func (i *Int64) Swap(new int64) int64 {
 	return Xchgint64(&i.value, new)
 }
@@ -87,6 +103,8 @@
 //
 // This operation wraps around in the usual
 // two's-complement way.
+//
+//go:nosplit
 func (i *Int64) Add(delta int64) int64 {
 	return Xaddint64(&i.value, delta)
 }
@@ -100,11 +118,15 @@
 }
 
 // Load accesses and returns the value atomically.
+//
+//go:nosplit
 func (u *Uint8) Load() uint8 {
 	return Load8(&u.value)
 }
 
 // Store updates the value atomically.
+//
+//go:nosplit
 func (u *Uint8) Store(value uint8) {
 	Store8(&u.value, value)
 }
@@ -114,6 +136,8 @@
 // the result into u.
 //
 // The full process is performed atomically.
+//
+//go:nosplit
 func (u *Uint8) And(value uint8) {
 	And8(&u.value, value)
 }
@@ -123,6 +147,8 @@
 // the result into u.
 //
 // The full process is performed atomically.
+//
+//go:nosplit
 func (u *Uint8) Or(value uint8) {
 	Or8(&u.value, value)
 }
@@ -136,11 +162,15 @@
 }
 
 // Load accesses and returns the value atomically.
+//
+//go:nosplit
 func (b *Bool) Load() bool {
 	return b.u.Load() != 0
 }
 
 // Store updates the value atomically.
+//
+//go:nosplit
 func (b *Bool) Store(value bool) {
 	s := uint8(0)
 	if value {
@@ -158,6 +188,8 @@
 }
 
 // Load accesses and returns the value atomically.
+//
+//go:nosplit
 func (u *Uint32) Load() uint32 {
 	return Load(&u.value)
 }
@@ -169,11 +201,15 @@
 // on this thread can be observed to occur before it.
 //
 // WARNING: Use sparingly and with great care.
+//
+//go:nosplit
 func (u *Uint32) LoadAcquire() uint32 {
 	return LoadAcq(&u.value)
 }
 
 // Store updates the value atomically.
+//
+//go:nosplit
 func (u *Uint32) Store(value uint32) {
 	Store(&u.value, value)
 }
@@ -185,14 +221,17 @@
 // on this thread can be observed to occur after it.
 //
 // WARNING: Use sparingly and with great care.
+//
+//go:nosplit
 func (u *Uint32) StoreRelease(value uint32) {
 	StoreRel(&u.value, value)
 }
 
 // CompareAndSwap atomically compares u's value with old,
 // and if they're equal, swaps u's value with new.
+// It reports whether the swap ran.
 //
-// Returns true if the operation succeeded.
+//go:nosplit
 func (u *Uint32) CompareAndSwap(old, new uint32) bool {
 	return Cas(&u.value, old, new)
 }
@@ -202,16 +241,19 @@
 // may observe operations that occur after this operation to
 // precede it, but no operation that precedes it
 // on this thread can be observed to occur after it.
-//
-// Returns true if the operation succeeded.
+// It reports whether the swap ran.
 //
 // WARNING: Use sparingly and with great care.
+//
+//go:nosplit
 func (u *Uint32) CompareAndSwapRelease(old, new uint32) bool {
 	return CasRel(&u.value, old, new)
 }
 
 // Swap replaces u's value with new, returning
 // u's value before the replacement.
+//
+//go:nosplit
 func (u *Uint32) Swap(value uint32) uint32 {
 	return Xchg(&u.value, value)
 }
@@ -221,6 +263,8 @@
 // the result into u.
 //
 // The full process is performed atomically.
+//
+//go:nosplit
 func (u *Uint32) And(value uint32) {
 	And(&u.value, value)
 }
@@ -230,6 +274,8 @@
 // the result into u.
 //
 // The full process is performed atomically.
+//
+//go:nosplit
 func (u *Uint32) Or(value uint32) {
 	Or(&u.value, value)
 }
@@ -239,6 +285,8 @@
 //
 // This operation wraps around in the usual
 // two's-complement way.
+//
+//go:nosplit
 func (u *Uint32) Add(delta int32) uint32 {
 	return Xadd(&u.value, delta)
 }
@@ -255,25 +303,32 @@
 }
 
 // Load accesses and returns the value atomically.
+//
+//go:nosplit
 func (u *Uint64) Load() uint64 {
 	return Load64(&u.value)
 }
 
 // Store updates the value atomically.
+//
+//go:nosplit
 func (u *Uint64) Store(value uint64) {
 	Store64(&u.value, value)
 }
 
 // CompareAndSwap atomically compares u's value with old,
 // and if they're equal, swaps u's value with new.
+// It reports whether the swap ran.
 //
-// Returns true if the operation succeeded.
+//go:nosplit
 func (u *Uint64) CompareAndSwap(old, new uint64) bool {
 	return Cas64(&u.value, old, new)
 }
 
 // Swap replaces u's value with new, returning
 // u's value before the replacement.
+//
+//go:nosplit
 func (u *Uint64) Swap(value uint64) uint64 {
 	return Xchg64(&u.value, value)
 }
@@ -283,6 +338,8 @@
 //
 // This operation wraps around in the usual
 // two's-complement way.
+//
+//go:nosplit
 func (u *Uint64) Add(delta int64) uint64 {
 	return Xadd64(&u.value, delta)
 }
@@ -296,6 +353,8 @@
 }
 
 // Load accesses and returns the value atomically.
+//
+//go:nosplit
 func (u *Uintptr) Load() uintptr {
 	return Loaduintptr(&u.value)
 }
@@ -307,11 +366,15 @@
 // on this thread can be observed to occur before it.
 //
 // WARNING: Use sparingly and with great care.
+//
+//go:nosplit
 func (u *Uintptr) LoadAcquire() uintptr {
 	return LoadAcquintptr(&u.value)
 }
 
 // Store updates the value atomically.
+//
+//go:nosplit
 func (u *Uintptr) Store(value uintptr) {
 	Storeuintptr(&u.value, value)
 }
@@ -323,20 +386,25 @@
 // on this thread can be observed to occur after it.
 //
 // WARNING: Use sparingly and with great care.
+//
+//go:nosplit
 func (u *Uintptr) StoreRelease(value uintptr) {
 	StoreReluintptr(&u.value, value)
 }
 
 // CompareAndSwap atomically compares u's value with old,
 // and if they're equal, swaps u's value with new.
+// It reports whether the swap ran.
 //
-// Returns true if the operation succeeded.
+//go:nosplit
 func (u *Uintptr) CompareAndSwap(old, new uintptr) bool {
 	return Casuintptr(&u.value, old, new)
 }
 
 // Swap replaces u's value with new, returning
 // u's value before the replacement.
+//
+//go:nosplit
 func (u *Uintptr) Swap(value uintptr) uintptr {
 	return Xchguintptr(&u.value, value)
 }
@@ -346,6 +414,8 @@
 //
 // This operation wraps around in the usual
 // two's-complement way.
+//
+//go:nosplit
 func (u *Uintptr) Add(delta uintptr) uintptr {
 	return Xadduintptr(&u.value, delta)
 }
@@ -361,12 +431,16 @@
 }
 
 // Load accesses and returns the value atomically.
+//
+//go:nosplit
 func (f *Float64) Load() float64 {
 	r := f.u.Load()
 	return *(*float64)(unsafe.Pointer(&r))
 }
 
 // Store updates the value atomically.
+//
+//go:nosplit
 func (f *Float64) Store(value float64) {
 	f.u.Store(*(*uint64)(unsafe.Pointer(&value)))
 }
@@ -386,6 +460,8 @@
 }
 
 // Load accesses and returns the value atomically.
+//
+//go:nosplit
 func (u *UnsafePointer) Load() unsafe.Pointer {
 	return Loadp(unsafe.Pointer(&u.value))
 }
@@ -396,24 +472,102 @@
 // perform a write barrier on value, and so this operation may
 // hide pointers from the GC. Use with care and sparingly.
 // It is safe to use with values not found in the Go heap.
+// Prefer Store instead.
+//
+//go:nosplit
 func (u *UnsafePointer) StoreNoWB(value unsafe.Pointer) {
 	StorepNoWB(unsafe.Pointer(&u.value), value)
 }
 
+// Store updates the value atomically.
+func (u *UnsafePointer) Store(value unsafe.Pointer) {
+	storePointer(&u.value, value)
+}
+
+// provided by runtime
+//go:linkname storePointer
+func storePointer(ptr *unsafe.Pointer, new unsafe.Pointer)
+
 // CompareAndSwapNoWB atomically (with respect to other methods)
 // compares u's value with old, and if they're equal,
 // swaps u's value with new.
-//
-// Returns true if the operation succeeded.
+// It reports whether the swap ran.
 //
 // WARNING: As the name implies this operation does *not*
 // perform a write barrier on value, and so this operation may
 // hide pointers from the GC. Use with care and sparingly.
 // It is safe to use with values not found in the Go heap.
+// Prefer CompareAndSwap instead.
+//
+//go:nosplit
 func (u *UnsafePointer) CompareAndSwapNoWB(old, new unsafe.Pointer) bool {
 	return Casp1(&u.value, old, new)
 }
 
+// CompareAndSwap atomically compares u's value with old,
+// and if they're equal, swaps u's value with new.
+// It reports whether the swap ran.
+func (u *UnsafePointer) CompareAndSwap(old, new unsafe.Pointer) bool {
+	return casPointer(&u.value, old, new)
+}
+
+func casPointer(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool
+
+// Pointer is an atomic pointer of type *T.
+type Pointer[T any] struct {
+	u UnsafePointer
+}
+
+// Load accesses and returns the value atomically.
+//
+//go:nosplit
+func (p *Pointer[T]) Load() *T {
+	return (*T)(p.u.Load())
+}
+
+// StoreNoWB updates the value atomically.
+//
+// WARNING: As the name implies this operation does *not*
+// perform a write barrier on value, and so this operation may
+// hide pointers from the GC. Use with care and sparingly.
+// It is safe to use with values not found in the Go heap.
+// Prefer Store instead.
+//
+//go:nosplit
+func (p *Pointer[T]) StoreNoWB(value *T) {
+	p.u.StoreNoWB(unsafe.Pointer(value))
+}
+
+// Store updates the value atomically.
+//go:nosplit
+func (p *Pointer[T]) Store(value *T) {
+	p.u.Store(unsafe.Pointer(value))
+}
+
+// CompareAndSwapNoWB atomically (with respect to other methods)
+// compares u's value with old, and if they're equal,
+// swaps u's value with new.
+// It reports whether the swap ran.
+//
+// WARNING: As the name implies this operation does *not*
+// perform a write barrier on value, and so this operation may
+// hide pointers from the GC. Use with care and sparingly.
+// It is safe to use with values not found in the Go heap.
+// Prefer CompareAndSwap instead.
+//
+//go:nosplit
+func (p *Pointer[T]) CompareAndSwapNoWB(old, new *T) bool {
+	return p.u.CompareAndSwapNoWB(unsafe.Pointer(old), unsafe.Pointer(new))
+}
+
+// CompareAndSwap atomically (with respect to other methods)
+// compares u's value with old, and if they're equal,
+// swaps u's value with new.
+// It reports whether the swap ran.
+func (p *Pointer[T]) CompareAndSwap(old, new *T) bool {
+	return p.u.CompareAndSwap(unsafe.Pointer(old), unsafe.Pointer(new))
+}
+
 // noCopy may be embedded into structs which must not be copied
 // after the first use.
 //
diff --git a/src/runtime/internal/atomic/types_64bit.go b/src/runtime/internal/atomic/types_64bit.go
index 43c1ba2..006e83b 100644
--- a/src/runtime/internal/atomic/types_64bit.go
+++ b/src/runtime/internal/atomic/types_64bit.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build amd64 || arm64 || mips64 || mips64le || ppc64 || ppc64le || riscv64 || s390x || wasm
+//go:build amd64 || arm64 || loong64 || mips64 || mips64le || ppc64 || ppc64le || riscv64 || s390x || wasm
 
 package atomic
 
@@ -13,6 +13,8 @@
 // on this thread can be observed to occur before it.
 //
 // WARNING: Use sparingly and with great care.
+//
+//go:nosplit
 func (u *Uint64) LoadAcquire() uint64 {
 	return LoadAcq64(&u.value)
 }
@@ -24,6 +26,8 @@
 // on this thread can be observed to occur after it.
 //
 // WARNING: Use sparingly and with great care.
+//
+//go:nosplit
 func (u *Uint64) StoreRelease(value uint64) {
 	StoreRel64(&u.value, value)
 }
diff --git a/src/runtime/internal/startlinetest/func_amd64.go b/src/runtime/internal/startlinetest/func_amd64.go
new file mode 100644
index 0000000..ab7063d
--- /dev/null
+++ b/src/runtime/internal/startlinetest/func_amd64.go
@@ -0,0 +1,13 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package startlinetest contains helpers for runtime_test.TestStartLineAsm.
+package startlinetest
+
+// Defined in func_amd64.s, this is a trivial assembly function that calls
+// runtime_test.callerStartLine.
+func AsmFunc() int
+
+// Provided by runtime_test.
+var CallerStartLine func(bool) int
diff --git a/src/runtime/internal/startlinetest/func_amd64.s b/src/runtime/internal/startlinetest/func_amd64.s
new file mode 100644
index 0000000..96982be
--- /dev/null
+++ b/src/runtime/internal/startlinetest/func_amd64.s
@@ -0,0 +1,28 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "funcdata.h"
+#include "textflag.h"
+
+// Assembly function for runtime_test.TestStartLineAsm.
+//
+// Note that this file can't be built directly as part of runtime_test, as assembly
+// files can't declare an alternative package. Building it into runtime is
+// possible, but linkshared complicates things:
+//
+//  1. linkshared mode leaves the function around in the final output of
+//     non-test builds.
+//  2. Due of (1), the linker can't resolve the callerStartLine relocation
+//     (as runtime_test isn't built for non-test builds).
+//
+// Thus it is simpler to just put this in its own package, imported only by
+// runtime_test. We use ABIInternal as no ABI wrapper is generated for
+// callerStartLine since it is in a different package.
+
+TEXT	·AsmFunc<ABIInternal>(SB),NOSPLIT,$8-0
+	NO_LOCAL_POINTERS
+	MOVQ	$0, AX // wantInlined
+	MOVQ	·CallerStartLine(SB), DX
+	CALL	(DX)
+	RET
diff --git a/src/runtime/internal/sys/consts.go b/src/runtime/internal/sys/consts.go
index fffcf81..98c0f09 100644
--- a/src/runtime/internal/sys/consts.go
+++ b/src/runtime/internal/sys/consts.go
@@ -10,7 +10,9 @@
 )
 
 // AIX requires a larger stack for syscalls.
-const StackGuardMultiplier = StackGuardMultiplierDefault*(1-goos.IsAix) + 2*goos.IsAix
+// The race build also needs more stack. See issue 54291.
+// This arithmetic must match that in cmd/internal/objabi/stack.go:stackGuardMultiplier.
+const StackGuardMultiplier = 1 + goos.IsAix + isRace
 
 // DefaultPhysPageSize is the default physical page size.
 const DefaultPhysPageSize = goarch.DefaultPhysPageSize
diff --git a/src/runtime/internal/sys/consts_norace.go b/src/runtime/internal/sys/consts_norace.go
new file mode 100644
index 0000000..a9613b8
--- /dev/null
+++ b/src/runtime/internal/sys/consts_norace.go
@@ -0,0 +1,9 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !race
+
+package sys
+
+const isRace = 0
diff --git a/src/runtime/internal/sys/consts_race.go b/src/runtime/internal/sys/consts_race.go
new file mode 100644
index 0000000..f824fb3
--- /dev/null
+++ b/src/runtime/internal/sys/consts_race.go
@@ -0,0 +1,9 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build race
+
+package sys
+
+const isRace = 1
diff --git a/src/runtime/internal/sys/intrinsics.go b/src/runtime/internal/sys/intrinsics.go
index 5af4901..902d893 100644
--- a/src/runtime/internal/sys/intrinsics.go
+++ b/src/runtime/internal/sys/intrinsics.go
@@ -5,56 +5,75 @@
 //go:build !386
 
 // TODO finish intrinsifying 386, deadcode the assembly, remove build tags, merge w/ intrinsics_common
-// TODO replace all uses of CtzXX with TrailingZerosXX; they are the same.
 
 package sys
 
-// Using techniques from http://supertech.csail.mit.edu/papers/debruijn.pdf
+// Copied from math/bits to avoid dependence.
 
-const deBruijn64ctz = 0x0218a392cd3d5dbf
-
-var deBruijnIdx64ctz = [64]byte{
-	0, 1, 2, 7, 3, 13, 8, 19,
-	4, 25, 14, 28, 9, 34, 20, 40,
-	5, 17, 26, 38, 15, 46, 29, 48,
-	10, 31, 35, 54, 21, 50, 41, 57,
-	63, 6, 12, 18, 24, 27, 33, 39,
-	16, 37, 45, 47, 30, 53, 49, 56,
-	62, 11, 23, 32, 36, 44, 52, 55,
-	61, 22, 43, 51, 60, 42, 59, 58,
+var deBruijn32tab = [32]byte{
+	0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
+	31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9,
 }
 
-const deBruijn32ctz = 0x04653adf
+const deBruijn32 = 0x077CB531
 
-var deBruijnIdx32ctz = [32]byte{
-	0, 1, 2, 6, 3, 11, 7, 16,
-	4, 14, 12, 21, 8, 23, 17, 26,
-	31, 5, 10, 15, 13, 20, 22, 25,
-	30, 9, 19, 24, 29, 18, 28, 27,
+var deBruijn64tab = [64]byte{
+	0, 1, 56, 2, 57, 49, 28, 3, 61, 58, 42, 50, 38, 29, 17, 4,
+	62, 47, 59, 36, 45, 43, 51, 22, 53, 39, 33, 30, 24, 18, 12, 5,
+	63, 55, 48, 27, 60, 41, 37, 16, 46, 35, 44, 21, 52, 32, 23, 11,
+	54, 26, 40, 15, 34, 20, 31, 10, 25, 14, 19, 9, 13, 8, 7, 6,
 }
 
-// Ctz64 counts trailing (low-order) zeroes,
-// and if all are zero, then 64.
-func Ctz64(x uint64) int {
-	x &= -x                       // isolate low-order bit
-	y := x * deBruijn64ctz >> 58  // extract part of deBruijn sequence
-	i := int(deBruijnIdx64ctz[y]) // convert to bit index
-	z := int((x - 1) >> 57 & 64)  // adjustment if zero
-	return i + z
+const deBruijn64 = 0x03f79d71b4ca8b09
+
+const ntz8tab = "" +
+	"\x08\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+	"\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+	"\x05\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+	"\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+	"\x06\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+	"\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+	"\x05\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+	"\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+	"\x07\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+	"\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+	"\x05\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+	"\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+	"\x06\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+	"\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+	"\x05\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+	"\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00"
+
+// TrailingZeros32 returns the number of trailing zero bits in x; the result is 32 for x == 0.
+func TrailingZeros32(x uint32) int {
+	if x == 0 {
+		return 32
+	}
+	// see comment in TrailingZeros64
+	return int(deBruijn32tab[(x&-x)*deBruijn32>>(32-5)])
 }
 
-// Ctz32 counts trailing (low-order) zeroes,
-// and if all are zero, then 32.
-func Ctz32(x uint32) int {
-	x &= -x                       // isolate low-order bit
-	y := x * deBruijn32ctz >> 27  // extract part of deBruijn sequence
-	i := int(deBruijnIdx32ctz[y]) // convert to bit index
-	z := int((x - 1) >> 26 & 32)  // adjustment if zero
-	return i + z
+// TrailingZeros64 returns the number of trailing zero bits in x; the result is 64 for x == 0.
+func TrailingZeros64(x uint64) int {
+	if x == 0 {
+		return 64
+	}
+	// If popcount is fast, replace code below with return popcount(^x & (x - 1)).
+	//
+	// x & -x leaves only the right-most bit set in the word. Let k be the
+	// index of that bit. Since only a single bit is set, the value is two
+	// to the power of k. Multiplying by a power of two is equivalent to
+	// left shifting, in this case by k bits. The de Bruijn (64 bit) constant
+	// is such that all six bit, consecutive substrings are distinct.
+	// Therefore, if we have a left shifted version of this constant we can
+	// find by how many bits it was shifted by looking at which six bit
+	// substring ended up at the top of the word.
+	// (Knuth, volume 4, section 7.3.1)
+	return int(deBruijn64tab[(x&-x)*deBruijn64>>(64-6)])
 }
 
-// Ctz8 returns the number of trailing zero bits in x; the result is 8 for x == 0.
-func Ctz8(x uint8) int {
+// TrailingZeros8 returns the number of trailing zero bits in x; the result is 8 for x == 0.
+func TrailingZeros8(x uint8) int {
 	return int(ntz8tab[x])
 }
 
diff --git a/src/runtime/internal/sys/intrinsics_386.s b/src/runtime/internal/sys/intrinsics_386.s
index 784b246..f33ade0 100644
--- a/src/runtime/internal/sys/intrinsics_386.s
+++ b/src/runtime/internal/sys/intrinsics_386.s
@@ -4,7 +4,7 @@
 
 #include "textflag.h"
 
-TEXT runtime∕internal∕sys·Ctz64(SB), NOSPLIT, $0-12
+TEXT runtime∕internal∕sys·TrailingZeros64(SB), NOSPLIT, $0-12
 	// Try low 32 bits.
 	MOVL	x_lo+0(FP), AX
 	BSFL	AX, AX
@@ -26,7 +26,7 @@
 	MOVL	$64, ret+8(FP)
 	RET
 
-TEXT runtime∕internal∕sys·Ctz32(SB), NOSPLIT, $0-8
+TEXT runtime∕internal∕sys·TrailingZeros32(SB), NOSPLIT, $0-8
 	MOVL	x+0(FP), AX
 	BSFL	AX, AX
 	JNZ	2(PC)
@@ -34,7 +34,7 @@
 	MOVL	AX, ret+4(FP)
 	RET
 
-TEXT runtime∕internal∕sys·Ctz8(SB), NOSPLIT, $0-8
+TEXT runtime∕internal∕sys·TrailingZeros8(SB), NOSPLIT, $0-8
 	MOVBLZX	x+0(FP), AX
 	BSFL	AX, AX
 	JNZ	2(PC)
diff --git a/src/runtime/internal/sys/intrinsics_common.go b/src/runtime/internal/sys/intrinsics_common.go
index 48d9759..1461551 100644
--- a/src/runtime/internal/sys/intrinsics_common.go
+++ b/src/runtime/internal/sys/intrinsics_common.go
@@ -6,45 +6,29 @@
 
 // Copied from math/bits to avoid dependence.
 
-var len8tab = [256]uint8{
-	0x00, 0x01, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-	0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-	0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-	0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
-	0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-	0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-	0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-	0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-	0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-	0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-	0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-	0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-	0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-	0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-	0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-	0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-}
+const len8tab = "" +
+	"\x00\x01\x02\x02\x03\x03\x03\x03\x04\x04\x04\x04\x04\x04\x04\x04" +
+	"\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05" +
+	"\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06" +
+	"\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06" +
+	"\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07" +
+	"\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07" +
+	"\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07" +
+	"\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07" +
+	"\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" +
+	"\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" +
+	"\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" +
+	"\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" +
+	"\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" +
+	"\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" +
+	"\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" +
+	"\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08"
 
-var ntz8tab = [256]uint8{
-	0x08, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
-	0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
-	0x05, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
-	0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
-	0x06, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
-	0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
-	0x05, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
-	0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
-	0x07, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
-	0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
-	0x05, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
-	0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
-	0x06, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
-	0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
-	0x05, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
-	0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
-}
-
-// len64 returns the minimum number of bits required to represent x; the result is 0 for x == 0.
+// Len64 returns the minimum number of bits required to represent x; the result is 0 for x == 0.
+//
+// nosplit because this is used in src/runtime/histogram.go, which make run in sensitive contexts.
+//
+//go:nosplit
 func Len64(x uint64) (n int) {
 	if x >= 1<<32 {
 		x >>= 32
@@ -98,45 +82,12 @@
 	return int(x) & (1<<7 - 1)
 }
 
-var deBruijn64tab = [64]byte{
-	0, 1, 56, 2, 57, 49, 28, 3, 61, 58, 42, 50, 38, 29, 17, 4,
-	62, 47, 59, 36, 45, 43, 51, 22, 53, 39, 33, 30, 24, 18, 12, 5,
-	63, 55, 48, 27, 60, 41, 37, 16, 46, 35, 44, 21, 52, 32, 23, 11,
-	54, 26, 40, 15, 34, 20, 31, 10, 25, 14, 19, 9, 13, 8, 7, 6,
-}
-
-const deBruijn64 = 0x03f79d71b4ca8b09
-
-// TrailingZeros64 returns the number of trailing zero bits in x; the result is 64 for x == 0.
-func TrailingZeros64(x uint64) int {
-	if x == 0 {
-		return 64
-	}
-	// If popcount is fast, replace code below with return popcount(^x & (x - 1)).
-	//
-	// x & -x leaves only the right-most bit set in the word. Let k be the
-	// index of that bit. Since only a single bit is set, the value is two
-	// to the power of k. Multiplying by a power of two is equivalent to
-	// left shifting, in this case by k bits. The de Bruijn (64 bit) constant
-	// is such that all six bit, consecutive substrings are distinct.
-	// Therefore, if we have a left shifted version of this constant we can
-	// find by how many bits it was shifted by looking at which six bit
-	// substring ended up at the top of the word.
-	// (Knuth, volume 4, section 7.3.1)
-	return int(deBruijn64tab[(x&-x)*deBruijn64>>(64-6)])
-}
-
 // LeadingZeros64 returns the number of leading zero bits in x; the result is 64 for x == 0.
 func LeadingZeros64(x uint64) int { return 64 - Len64(x) }
 
 // LeadingZeros8 returns the number of leading zero bits in x; the result is 8 for x == 0.
 func LeadingZeros8(x uint8) int { return 8 - Len8(x) }
 
-// TrailingZeros8 returns the number of trailing zero bits in x; the result is 8 for x == 0.
-func TrailingZeros8(x uint8) int {
-	return int(ntz8tab[x])
-}
-
 // Len8 returns the minimum number of bits required to represent x; the result is 0 for x == 0.
 func Len8(x uint8) int {
 	return int(len8tab[x])
diff --git a/src/runtime/internal/sys/intrinsics_stubs.go b/src/runtime/internal/sys/intrinsics_stubs.go
index a020652..66cfcde 100644
--- a/src/runtime/internal/sys/intrinsics_stubs.go
+++ b/src/runtime/internal/sys/intrinsics_stubs.go
@@ -6,8 +6,8 @@
 
 package sys
 
-func Ctz64(x uint64) int
-func Ctz32(x uint32) int
-func Ctz8(x uint8) int
+func TrailingZeros64(x uint64) int
+func TrailingZeros32(x uint32) int
+func TrailingZeros8(x uint8) int
 func Bswap64(x uint64) uint64
 func Bswap32(x uint32) uint32
diff --git a/src/runtime/internal/sys/intrinsics_test.go b/src/runtime/internal/sys/intrinsics_test.go
index 0444183..bf75f19 100644
--- a/src/runtime/internal/sys/intrinsics_test.go
+++ b/src/runtime/internal/sys/intrinsics_test.go
@@ -5,19 +5,19 @@
 	"testing"
 )
 
-func TestCtz64(t *testing.T) {
+func TestTrailingZeros64(t *testing.T) {
 	for i := 0; i <= 64; i++ {
 		x := uint64(5) << uint(i)
-		if got := sys.Ctz64(x); got != i {
-			t.Errorf("Ctz64(%d)=%d, want %d", x, got, i)
+		if got := sys.TrailingZeros64(x); got != i {
+			t.Errorf("TrailingZeros64(%d)=%d, want %d", x, got, i)
 		}
 	}
 }
-func TestCtz32(t *testing.T) {
+func TestTrailingZeros32(t *testing.T) {
 	for i := 0; i <= 32; i++ {
 		x := uint32(5) << uint(i)
-		if got := sys.Ctz32(x); got != i {
-			t.Errorf("Ctz32(%d)=%d, want %d", x, got, i)
+		if got := sys.TrailingZeros32(x); got != i {
+			t.Errorf("TrailingZeros32(%d)=%d, want %d", x, got, i)
 		}
 	}
 }
diff --git a/src/runtime/internal/sys/nih.go b/src/runtime/internal/sys/nih.go
new file mode 100644
index 0000000..17eab67
--- /dev/null
+++ b/src/runtime/internal/sys/nih.go
@@ -0,0 +1,41 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sys
+
+// NOTE: keep in sync with cmd/compile/internal/types.CalcSize
+// to make the compiler recognize this as an intrinsic type.
+type nih struct{}
+
+// NotInHeap is a type must never be allocated from the GC'd heap or on the stack,
+// and is called not-in-heap.
+//
+// Other types can embed NotInHeap to make it not-in-heap. Specifically, pointers
+// to these types must always fail the `runtime.inheap` check. The type may be used
+// for global variables, or for objects in unmanaged memory (e.g., allocated with
+// `sysAlloc`, `persistentalloc`, r`fixalloc`, or from a manually-managed span).
+//
+// Specifically:
+//
+// 1. `new(T)`, `make([]T)`, `append([]T, ...)` and implicit heap
+// allocation of T are disallowed. (Though implicit allocations are
+// disallowed in the runtime anyway.)
+//
+// 2. A pointer to a regular type (other than `unsafe.Pointer`) cannot be
+// converted to a pointer to a not-in-heap type, even if they have the
+// same underlying type.
+//
+// 3. Any type that containing a not-in-heap type is itself considered as not-in-heap.
+//
+// - Structs and arrays are not-in-heap if their elements are not-in-heap.
+// - Maps and channels contains no-in-heap types are disallowed.
+//
+// 4. Write barriers on pointers to not-in-heap types can be omitted.
+//
+// The last point is the real benefit of NotInHeap. The runtime uses
+// it for low-level internal structures to avoid memory barriers in the
+// scheduler and the memory allocator where they are illegal or simply
+// inefficient. This mechanism is reasonably safe and does not compromise
+// the readability of the runtime.
+type NotInHeap struct{ _ nih }
diff --git a/src/runtime/internal/sys/zversion.go b/src/runtime/internal/sys/zversion.go
index b058a3d..184c263 100644
--- a/src/runtime/internal/sys/zversion.go
+++ b/src/runtime/internal/sys/zversion.go
@@ -1,5 +1,3 @@
 // Code generated by go tool dist; DO NOT EDIT.
 
 package sys
-
-const StackGuardMultiplierDefault = 1
diff --git a/src/runtime/internal/syscall/asm_linux_mips64x.s b/src/runtime/internal/syscall/asm_linux_mips64x.s
index 0e88a2d..6b7c524 100644
--- a/src/runtime/internal/syscall/asm_linux_mips64x.s
+++ b/src/runtime/internal/syscall/asm_linux_mips64x.s
@@ -15,6 +15,7 @@
 	MOVV	a4+32(FP), R7
 	MOVV	a5+40(FP), R8
 	MOVV	a6+48(FP), R9
+	MOVV	R0, R3	// reset R3 to 0 as 1-ret SYSCALL keeps it
 	SYSCALL
 	BEQ	R7, ok
 	MOVV	$-1, R1
diff --git a/src/runtime/internal/syscall/asm_linux_mipsx.s b/src/runtime/internal/syscall/asm_linux_mipsx.s
index 050029e..561310f 100644
--- a/src/runtime/internal/syscall/asm_linux_mipsx.s
+++ b/src/runtime/internal/syscall/asm_linux_mipsx.s
@@ -20,6 +20,7 @@
 	MOVW	a6+24(FP), R9
 	MOVW	R8, 16(R29)
 	MOVW	R9, 20(R29)
+	MOVW	R0, R3	// reset R3 to 0 as 1-ret SYSCALL keeps it
 	SYSCALL
 	BEQ	R7, ok
 	MOVW	$-1, R1
diff --git a/src/runtime/internal/syscall/asm_linux_ppc64x.s b/src/runtime/internal/syscall/asm_linux_ppc64x.s
index 8cf8737..3e985ed 100644
--- a/src/runtime/internal/syscall/asm_linux_ppc64x.s
+++ b/src/runtime/internal/syscall/asm_linux_ppc64x.s
@@ -7,22 +7,17 @@
 #include "textflag.h"
 
 // func Syscall6(num, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, errno uintptr)
-TEXT ·Syscall6(SB),NOSPLIT,$0-80
-	MOVD	num+0(FP), R9	// syscall entry
-	MOVD	a1+8(FP), R3
-	MOVD	a2+16(FP), R4
-	MOVD	a3+24(FP), R5
-	MOVD	a4+32(FP), R6
-	MOVD	a5+40(FP), R7
-	MOVD	a6+48(FP), R8
-	SYSCALL	R9
-	MOVD	R0, r2+64(FP) // r2 is not used. Always set to 0.
-	BVC	ok
-	MOVD	$-1, R4
-	MOVD	R4, r1+56(FP)
-	MOVD	R3, errno+72(FP)
-	RET
-ok:
-	MOVD	R3, r1+56(FP)
-	MOVD	R0, errno+72(FP)
+TEXT ·Syscall6<ABIInternal>(SB),NOSPLIT,$0-80
+	MOVD	R3, R10	// Move syscall number to R10. SYSCALL will move it R0, and restore R0.
+	MOVD	R4, R3
+	MOVD	R5, R4
+	MOVD	R6, R5
+	MOVD	R7, R6
+	MOVD	R8, R7
+	MOVD	R9, R8
+	SYSCALL	R10
+	MOVD	$-1, R6
+	ISEL	CR0SO, R3, R0, R5 // errno = (error) ? R3 : 0
+	ISEL	CR0SO, R6, R3, R3 // r1 = (error) ? -1 : 0
+	MOVD	$0, R4            // r2 is not used on linux/ppc64
 	RET
diff --git a/src/runtime/internal/syscall/asm_linux_riscv64.s b/src/runtime/internal/syscall/asm_linux_riscv64.s
index a8652fd..15e50ec 100644
--- a/src/runtime/internal/syscall/asm_linux_riscv64.s
+++ b/src/runtime/internal/syscall/asm_linux_riscv64.s
@@ -5,25 +5,39 @@
 #include "textflag.h"
 
 // func Syscall6(num, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, errno uintptr)
-TEXT ·Syscall6(SB),NOSPLIT,$0-80
-	MOV	num+0(FP), A7	// syscall entry
-	MOV	a1+8(FP), A0
-	MOV	a2+16(FP), A1
-	MOV	a3+24(FP), A2
-	MOV	a4+32(FP), A3
-	MOV	a5+40(FP), A4
-	MOV	a6+48(FP), A5
+//
+// We need to convert to the syscall ABI.
+//
+// arg | ABIInternal | Syscall
+// ---------------------------
+// num | A0          | A7
+// a1  | A1          | A0
+// a2  | A2          | A1
+// a3  | A3          | A2
+// a4  | A4          | A3
+// a5  | A5          | A4
+// a6  | A6          | A5
+//
+// r1  | A0          | A0
+// r2  | A1          | A1
+// err | A2          | part of A0
+TEXT ·Syscall6<ABIInternal>(SB),NOSPLIT,$0-80
+	MOV	A0, A7
+	MOV	A1, A0
+	MOV	A2, A1
+	MOV	A3, A2
+	MOV	A4, A3
+	MOV	A5, A4
+	MOV	A6, A5
 	ECALL
 	MOV	$-4096, T0
 	BLTU	T0, A0, err
-	MOV	A0, r1+56(FP)
-	MOV	A1, r2+64(FP)
-	MOV	ZERO, errno+72(FP)
+	// r1 already in A0
+	// r2 already in A1
+	MOV	ZERO, A2 // errno
 	RET
 err:
-	MOV	$-1, T0
-	MOV	T0, r1+56(FP)
-	MOV	ZERO, r2+64(FP)
-	SUB	A0, ZERO, A0
-	MOV	A0, errno+72(FP)
+	SUB	A0, ZERO, A2 // errno
+	MOV	$-1, A0	     // r1
+	MOV	ZERO, A1     // r2
 	RET
diff --git a/src/runtime/internal/syscall/defs_linux.go b/src/runtime/internal/syscall/defs_linux.go
new file mode 100644
index 0000000..71f1fa1
--- /dev/null
+++ b/src/runtime/internal/syscall/defs_linux.go
@@ -0,0 +1,10 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package syscall
+
+const (
+	F_SETFD    = 2
+	FD_CLOEXEC = 1
+)
diff --git a/src/runtime/internal/syscall/defs_linux_386.go b/src/runtime/internal/syscall/defs_linux_386.go
new file mode 100644
index 0000000..dc723a6
--- /dev/null
+++ b/src/runtime/internal/syscall/defs_linux_386.go
@@ -0,0 +1,29 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package syscall
+
+const (
+	SYS_FCNTL         = 55
+	SYS_EPOLL_CTL     = 255
+	SYS_EPOLL_PWAIT   = 319
+	SYS_EPOLL_CREATE1 = 329
+	SYS_EPOLL_PWAIT2  = 441
+
+	EPOLLIN       = 0x1
+	EPOLLOUT      = 0x4
+	EPOLLERR      = 0x8
+	EPOLLHUP      = 0x10
+	EPOLLRDHUP    = 0x2000
+	EPOLLET       = 0x80000000
+	EPOLL_CLOEXEC = 0x80000
+	EPOLL_CTL_ADD = 0x1
+	EPOLL_CTL_DEL = 0x2
+	EPOLL_CTL_MOD = 0x3
+)
+
+type EpollEvent struct {
+	Events uint32
+	Data   [8]byte // to match amd64
+}
diff --git a/src/runtime/internal/syscall/defs_linux_amd64.go b/src/runtime/internal/syscall/defs_linux_amd64.go
new file mode 100644
index 0000000..886eb5b
--- /dev/null
+++ b/src/runtime/internal/syscall/defs_linux_amd64.go
@@ -0,0 +1,29 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package syscall
+
+const (
+	SYS_FCNTL         = 72
+	SYS_EPOLL_CTL     = 233
+	SYS_EPOLL_PWAIT   = 281
+	SYS_EPOLL_CREATE1 = 291
+	SYS_EPOLL_PWAIT2  = 441
+
+	EPOLLIN       = 0x1
+	EPOLLOUT      = 0x4
+	EPOLLERR      = 0x8
+	EPOLLHUP      = 0x10
+	EPOLLRDHUP    = 0x2000
+	EPOLLET       = 0x80000000
+	EPOLL_CLOEXEC = 0x80000
+	EPOLL_CTL_ADD = 0x1
+	EPOLL_CTL_DEL = 0x2
+	EPOLL_CTL_MOD = 0x3
+)
+
+type EpollEvent struct {
+	Events uint32
+	Data   [8]byte // unaligned uintptr
+}
diff --git a/src/runtime/internal/syscall/defs_linux_arm.go b/src/runtime/internal/syscall/defs_linux_arm.go
new file mode 100644
index 0000000..8f812a2
--- /dev/null
+++ b/src/runtime/internal/syscall/defs_linux_arm.go
@@ -0,0 +1,30 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package syscall
+
+const (
+	SYS_FCNTL         = 55
+	SYS_EPOLL_CTL     = 251
+	SYS_EPOLL_PWAIT   = 346
+	SYS_EPOLL_CREATE1 = 357
+	SYS_EPOLL_PWAIT2  = 441
+
+	EPOLLIN       = 0x1
+	EPOLLOUT      = 0x4
+	EPOLLERR      = 0x8
+	EPOLLHUP      = 0x10
+	EPOLLRDHUP    = 0x2000
+	EPOLLET       = 0x80000000
+	EPOLL_CLOEXEC = 0x80000
+	EPOLL_CTL_ADD = 0x1
+	EPOLL_CTL_DEL = 0x2
+	EPOLL_CTL_MOD = 0x3
+)
+
+type EpollEvent struct {
+	Events uint32
+	_pad   uint32
+	Data   [8]byte // to match amd64
+}
diff --git a/src/runtime/internal/syscall/defs_linux_arm64.go b/src/runtime/internal/syscall/defs_linux_arm64.go
new file mode 100644
index 0000000..48e11b0
--- /dev/null
+++ b/src/runtime/internal/syscall/defs_linux_arm64.go
@@ -0,0 +1,30 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package syscall
+
+const (
+	SYS_EPOLL_CREATE1 = 20
+	SYS_EPOLL_CTL     = 21
+	SYS_EPOLL_PWAIT   = 22
+	SYS_FCNTL         = 25
+	SYS_EPOLL_PWAIT2  = 441
+
+	EPOLLIN       = 0x1
+	EPOLLOUT      = 0x4
+	EPOLLERR      = 0x8
+	EPOLLHUP      = 0x10
+	EPOLLRDHUP    = 0x2000
+	EPOLLET       = 0x80000000
+	EPOLL_CLOEXEC = 0x80000
+	EPOLL_CTL_ADD = 0x1
+	EPOLL_CTL_DEL = 0x2
+	EPOLL_CTL_MOD = 0x3
+)
+
+type EpollEvent struct {
+	Events uint32
+	_pad   uint32
+	Data   [8]byte // to match amd64
+}
diff --git a/src/runtime/internal/syscall/defs_linux_loong64.go b/src/runtime/internal/syscall/defs_linux_loong64.go
new file mode 100644
index 0000000..b78ef81
--- /dev/null
+++ b/src/runtime/internal/syscall/defs_linux_loong64.go
@@ -0,0 +1,30 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package syscall
+
+const (
+	SYS_EPOLL_CREATE1 = 20
+	SYS_EPOLL_CTL     = 21
+	SYS_EPOLL_PWAIT   = 22
+	SYS_FCNTL         = 25
+	SYS_EPOLL_PWAIT2  = 441
+
+	EPOLLIN       = 0x1
+	EPOLLOUT      = 0x4
+	EPOLLERR      = 0x8
+	EPOLLHUP      = 0x10
+	EPOLLRDHUP    = 0x2000
+	EPOLLET       = 0x80000000
+	EPOLL_CLOEXEC = 0x80000
+	EPOLL_CTL_ADD = 0x1
+	EPOLL_CTL_DEL = 0x2
+	EPOLL_CTL_MOD = 0x3
+)
+
+type EpollEvent struct {
+	Events    uint32
+	pad_cgo_0 [4]byte
+	Data      [8]byte // unaligned uintptr
+}
diff --git a/src/runtime/internal/syscall/defs_linux_mips64x.go b/src/runtime/internal/syscall/defs_linux_mips64x.go
new file mode 100644
index 0000000..92b49ca
--- /dev/null
+++ b/src/runtime/internal/syscall/defs_linux_mips64x.go
@@ -0,0 +1,32 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build linux && (mips64 || mips64le)
+
+package syscall
+
+const (
+	SYS_FCNTL         = 5070
+	SYS_EPOLL_CTL     = 5208
+	SYS_EPOLL_PWAIT   = 5272
+	SYS_EPOLL_CREATE1 = 5285
+	SYS_EPOLL_PWAIT2  = 5441
+
+	EPOLLIN       = 0x1
+	EPOLLOUT      = 0x4
+	EPOLLERR      = 0x8
+	EPOLLHUP      = 0x10
+	EPOLLRDHUP    = 0x2000
+	EPOLLET       = 0x80000000
+	EPOLL_CLOEXEC = 0x80000
+	EPOLL_CTL_ADD = 0x1
+	EPOLL_CTL_DEL = 0x2
+	EPOLL_CTL_MOD = 0x3
+)
+
+type EpollEvent struct {
+	Events    uint32
+	pad_cgo_0 [4]byte
+	Data      [8]byte // unaligned uintptr
+}
diff --git a/src/runtime/internal/syscall/defs_linux_mipsx.go b/src/runtime/internal/syscall/defs_linux_mipsx.go
new file mode 100644
index 0000000..e28d09c
--- /dev/null
+++ b/src/runtime/internal/syscall/defs_linux_mipsx.go
@@ -0,0 +1,32 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build linux && (mips || mipsle)
+
+package syscall
+
+const (
+	SYS_FCNTL         = 4055
+	SYS_EPOLL_CTL     = 4249
+	SYS_EPOLL_PWAIT   = 4313
+	SYS_EPOLL_CREATE1 = 4326
+	SYS_EPOLL_PWAIT2  = 4441
+
+	EPOLLIN       = 0x1
+	EPOLLOUT      = 0x4
+	EPOLLERR      = 0x8
+	EPOLLHUP      = 0x10
+	EPOLLRDHUP    = 0x2000
+	EPOLLET       = 0x80000000
+	EPOLL_CLOEXEC = 0x80000
+	EPOLL_CTL_ADD = 0x1
+	EPOLL_CTL_DEL = 0x2
+	EPOLL_CTL_MOD = 0x3
+)
+
+type EpollEvent struct {
+	Events    uint32
+	pad_cgo_0 [4]byte
+	Data      uint64
+}
diff --git a/src/runtime/internal/syscall/defs_linux_ppc64x.go b/src/runtime/internal/syscall/defs_linux_ppc64x.go
new file mode 100644
index 0000000..a74483e
--- /dev/null
+++ b/src/runtime/internal/syscall/defs_linux_ppc64x.go
@@ -0,0 +1,32 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build linux && (ppc64 || ppc64le)
+
+package syscall
+
+const (
+	SYS_FCNTL         = 55
+	SYS_EPOLL_CTL     = 237
+	SYS_EPOLL_PWAIT   = 303
+	SYS_EPOLL_CREATE1 = 315
+	SYS_EPOLL_PWAIT2  = 441
+
+	EPOLLIN       = 0x1
+	EPOLLOUT      = 0x4
+	EPOLLERR      = 0x8
+	EPOLLHUP      = 0x10
+	EPOLLRDHUP    = 0x2000
+	EPOLLET       = 0x80000000
+	EPOLL_CLOEXEC = 0x80000
+	EPOLL_CTL_ADD = 0x1
+	EPOLL_CTL_DEL = 0x2
+	EPOLL_CTL_MOD = 0x3
+)
+
+type EpollEvent struct {
+	Events    uint32
+	pad_cgo_0 [4]byte
+	Data      [8]byte // unaligned uintptr
+}
diff --git a/src/runtime/internal/syscall/defs_linux_riscv64.go b/src/runtime/internal/syscall/defs_linux_riscv64.go
new file mode 100644
index 0000000..b78ef81
--- /dev/null
+++ b/src/runtime/internal/syscall/defs_linux_riscv64.go
@@ -0,0 +1,30 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package syscall
+
+const (
+	SYS_EPOLL_CREATE1 = 20
+	SYS_EPOLL_CTL     = 21
+	SYS_EPOLL_PWAIT   = 22
+	SYS_FCNTL         = 25
+	SYS_EPOLL_PWAIT2  = 441
+
+	EPOLLIN       = 0x1
+	EPOLLOUT      = 0x4
+	EPOLLERR      = 0x8
+	EPOLLHUP      = 0x10
+	EPOLLRDHUP    = 0x2000
+	EPOLLET       = 0x80000000
+	EPOLL_CLOEXEC = 0x80000
+	EPOLL_CTL_ADD = 0x1
+	EPOLL_CTL_DEL = 0x2
+	EPOLL_CTL_MOD = 0x3
+)
+
+type EpollEvent struct {
+	Events    uint32
+	pad_cgo_0 [4]byte
+	Data      [8]byte // unaligned uintptr
+}
diff --git a/src/runtime/internal/syscall/defs_linux_s390x.go b/src/runtime/internal/syscall/defs_linux_s390x.go
new file mode 100644
index 0000000..a7bb1ba
--- /dev/null
+++ b/src/runtime/internal/syscall/defs_linux_s390x.go
@@ -0,0 +1,30 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package syscall
+
+const (
+	SYS_FCNTL         = 55
+	SYS_EPOLL_CTL     = 250
+	SYS_EPOLL_PWAIT   = 312
+	SYS_EPOLL_CREATE1 = 327
+	SYS_EPOLL_PWAIT2  = 441
+
+	EPOLLIN       = 0x1
+	EPOLLOUT      = 0x4
+	EPOLLERR      = 0x8
+	EPOLLHUP      = 0x10
+	EPOLLRDHUP    = 0x2000
+	EPOLLET       = 0x80000000
+	EPOLL_CLOEXEC = 0x80000
+	EPOLL_CTL_ADD = 0x1
+	EPOLL_CTL_DEL = 0x2
+	EPOLL_CTL_MOD = 0x3
+)
+
+type EpollEvent struct {
+	Events    uint32
+	pad_cgo_0 [4]byte
+	Data      [8]byte // unaligned uintptr
+}
diff --git a/src/runtime/internal/syscall/syscall_linux.go b/src/runtime/internal/syscall/syscall_linux.go
index 7f268e8..a103d31 100644
--- a/src/runtime/internal/syscall/syscall_linux.go
+++ b/src/runtime/internal/syscall/syscall_linux.go
@@ -6,7 +6,7 @@
 package syscall
 
 import (
-	_ "unsafe" // for go:linkname
+	"unsafe"
 )
 
 // TODO(https://go.dev/issue/51087): This package is incomplete and currently
@@ -37,3 +37,30 @@
 func syscall_RawSyscall6(num, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, errno uintptr) {
 	return Syscall6(num, a1, a2, a3, a4, a5, a6)
 }
+
+func EpollCreate1(flags int32) (fd int32, errno uintptr) {
+	r1, _, e := Syscall6(SYS_EPOLL_CREATE1, uintptr(flags), 0, 0, 0, 0, 0)
+	return int32(r1), e
+}
+
+var _zero uintptr
+
+func EpollWait(epfd int32, events []EpollEvent, maxev, waitms int32) (n int32, errno uintptr) {
+	var ev unsafe.Pointer
+	if len(events) > 0 {
+		ev = unsafe.Pointer(&events[0])
+	} else {
+		ev = unsafe.Pointer(&_zero)
+	}
+	r1, _, e := Syscall6(SYS_EPOLL_PWAIT, uintptr(epfd), uintptr(ev), uintptr(maxev), uintptr(waitms), 0, 0)
+	return int32(r1), e
+}
+
+func EpollCtl(epfd, op, fd int32, event *EpollEvent) (errno uintptr) {
+	_, _, e := Syscall6(SYS_EPOLL_CTL, uintptr(epfd), uintptr(op), uintptr(fd), uintptr(unsafe.Pointer(event)), 0, 0)
+	return e
+}
+
+func CloseOnExec(fd int32) {
+	Syscall6(SYS_FCNTL, uintptr(fd), F_SETFD, FD_CLOEXEC, 0, 0, 0)
+}
diff --git a/src/runtime/internal/syscall/syscall_linux_test.go b/src/runtime/internal/syscall/syscall_linux_test.go
new file mode 100644
index 0000000..1976da5
--- /dev/null
+++ b/src/runtime/internal/syscall/syscall_linux_test.go
@@ -0,0 +1,19 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package syscall_test
+
+import (
+	"runtime/internal/syscall"
+	"testing"
+)
+
+func TestEpollctlErrorSign(t *testing.T) {
+	v := syscall.EpollCtl(-1, 1, -1, &syscall.EpollEvent{})
+
+	const EBADF = 0x09
+	if v != EBADF {
+		t.Errorf("epollctl = %v, want %v", v, EBADF)
+	}
+}
diff --git a/src/runtime/lfstack.go b/src/runtime/lfstack.go
index 406561a..306a8e8 100644
--- a/src/runtime/lfstack.go
+++ b/src/runtime/lfstack.go
@@ -18,8 +18,7 @@
 // This stack is intrusive. Nodes must embed lfnode as the first field.
 //
 // The stack does not keep GC-visible pointers to nodes, so the caller
-// is responsible for ensuring the nodes are not garbage collected
-// (typically by allocating them from manually-managed memory).
+// must ensure the nodes are allocated outside the Go heap.
 type lfstack uint64
 
 func (head *lfstack) push(node *lfnode) {
@@ -59,6 +58,9 @@
 // lfnodeValidate panics if node is not a valid address for use with
 // lfstack.push. This only needs to be called when node is allocated.
 func lfnodeValidate(node *lfnode) {
+	if base, _, _ := findObject(uintptr(unsafe.Pointer(node)), 0, 0); base != 0 {
+		throw("lfstack node allocated from the heap")
+	}
 	if lfstackUnpack(lfstackPack(node, ^uintptr(0))) != node {
 		printlock()
 		println("runtime: bad lfnode address", hex(uintptr(unsafe.Pointer(node))))
diff --git a/src/runtime/lfstack_64bit.go b/src/runtime/lfstack_64bit.go
index 154130c..88cbd3b 100644
--- a/src/runtime/lfstack_64bit.go
+++ b/src/runtime/lfstack_64bit.go
@@ -36,12 +36,21 @@
 	// We use one bit to distinguish between the two ranges.
 	aixAddrBits = 57
 	aixCntBits  = 64 - aixAddrBits + 3
+
+	// riscv64 SV57 mode gives 56 bits of userspace VA.
+	// lfstack code supports it, but broader support for SV57 mode is incomplete,
+	// and there may be other issues (see #54104).
+	riscv64AddrBits = 56
+	riscv64CntBits  = 64 - riscv64AddrBits + 3
 )
 
 func lfstackPack(node *lfnode, cnt uintptr) uint64 {
 	if GOARCH == "ppc64" && GOOS == "aix" {
 		return uint64(uintptr(unsafe.Pointer(node)))<<(64-aixAddrBits) | uint64(cnt&(1<<aixCntBits-1))
 	}
+	if GOARCH == "riscv64" {
+		return uint64(uintptr(unsafe.Pointer(node)))<<(64-riscv64AddrBits) | uint64(cnt&(1<<riscv64CntBits-1))
+	}
 	return uint64(uintptr(unsafe.Pointer(node)))<<(64-addrBits) | uint64(cnt&(1<<cntBits-1))
 }
 
@@ -54,5 +63,8 @@
 	if GOARCH == "ppc64" && GOOS == "aix" {
 		return (*lfnode)(unsafe.Pointer(uintptr((val >> aixCntBits << 3) | 0xa<<56)))
 	}
+	if GOARCH == "riscv64" {
+		return (*lfnode)(unsafe.Pointer(uintptr(val >> riscv64CntBits << 3)))
+	}
 	return (*lfnode)(unsafe.Pointer(uintptr(val >> cntBits << 3)))
 }
diff --git a/src/runtime/lfstack_test.go b/src/runtime/lfstack_test.go
index d0a1b6b..e36297e 100644
--- a/src/runtime/lfstack_test.go
+++ b/src/runtime/lfstack_test.go
@@ -16,6 +16,17 @@
 	data int
 }
 
+// allocMyNode allocates nodes that are stored in an lfstack
+// outside the Go heap.
+// We require lfstack objects to live outside the heap so that
+// checkptr passes on the unsafe shenanigans used.
+func allocMyNode(data int) *MyNode {
+	n := (*MyNode)(PersistentAlloc(unsafe.Sizeof(MyNode{})))
+	LFNodeValidate(&n.LFNode)
+	n.data = data
+	return n
+}
+
 func fromMyNode(node *MyNode) *LFNode {
 	return (*LFNode)(unsafe.Pointer(node))
 }
@@ -30,22 +41,17 @@
 	stack := new(uint64)
 	global = stack // force heap allocation
 
-	// Need to keep additional references to nodes, the stack is not all that type-safe.
-	var nodes []*MyNode
-
 	// Check the stack is initially empty.
 	if LFStackPop(stack) != nil {
 		t.Fatalf("stack is not empty")
 	}
 
 	// Push one element.
-	node := &MyNode{data: 42}
-	nodes = append(nodes, node)
+	node := allocMyNode(42)
 	LFStackPush(stack, fromMyNode(node))
 
 	// Push another.
-	node = &MyNode{data: 43}
-	nodes = append(nodes, node)
+	node = allocMyNode(43)
 	LFStackPush(stack, fromMyNode(node))
 
 	// Pop one element.
@@ -75,8 +81,6 @@
 	}
 }
 
-var stress []*MyNode
-
 func TestLFStackStress(t *testing.T) {
 	const K = 100
 	P := 4 * GOMAXPROCS(-1)
@@ -86,15 +90,11 @@
 	}
 	// Create 2 stacks.
 	stacks := [2]*uint64{new(uint64), new(uint64)}
-	// Need to keep additional references to nodes,
-	// the lock-free stack is not type-safe.
-	stress = nil
 	// Push K elements randomly onto the stacks.
 	sum := 0
 	for i := 0; i < K; i++ {
 		sum += i
-		node := &MyNode{data: i}
-		stress = append(stress, node)
+		node := allocMyNode(i)
 		LFStackPush(stacks[i%2], fromMyNode(node))
 	}
 	c := make(chan bool, P)
@@ -134,7 +134,4 @@
 	if sum2 != sum {
 		t.Fatalf("Wrong sum %d/%d", sum2, sum)
 	}
-
-	// Let nodes be collected now.
-	stress = nil
 }
diff --git a/src/runtime/libfuzzer.go b/src/runtime/libfuzzer.go
index 6bfaef8..0ece035 100644
--- a/src/runtime/libfuzzer.go
+++ b/src/runtime/libfuzzer.go
@@ -20,49 +20,49 @@
 // This may result in these functions having callers that are nosplit. That is why they must be nosplit.
 //
 //go:nosplit
-func libfuzzerTraceCmp1(arg0, arg1 uint8, fakePC int) {
+func libfuzzerTraceCmp1(arg0, arg1 uint8, fakePC uint) {
 	fakePC = fakePC % retSledSize
 	libfuzzerCallTraceIntCmp(&__sanitizer_cov_trace_cmp1, uintptr(arg0), uintptr(arg1), uintptr(fakePC))
 }
 
 //go:nosplit
-func libfuzzerTraceCmp2(arg0, arg1 uint16, fakePC int) {
+func libfuzzerTraceCmp2(arg0, arg1 uint16, fakePC uint) {
 	fakePC = fakePC % retSledSize
 	libfuzzerCallTraceIntCmp(&__sanitizer_cov_trace_cmp2, uintptr(arg0), uintptr(arg1), uintptr(fakePC))
 }
 
 //go:nosplit
-func libfuzzerTraceCmp4(arg0, arg1 uint32, fakePC int) {
+func libfuzzerTraceCmp4(arg0, arg1 uint32, fakePC uint) {
 	fakePC = fakePC % retSledSize
 	libfuzzerCallTraceIntCmp(&__sanitizer_cov_trace_cmp4, uintptr(arg0), uintptr(arg1), uintptr(fakePC))
 }
 
 //go:nosplit
-func libfuzzerTraceCmp8(arg0, arg1 uint64, fakePC int) {
+func libfuzzerTraceCmp8(arg0, arg1 uint64, fakePC uint) {
 	fakePC = fakePC % retSledSize
 	libfuzzerCallTraceIntCmp(&__sanitizer_cov_trace_cmp8, uintptr(arg0), uintptr(arg1), uintptr(fakePC))
 }
 
 //go:nosplit
-func libfuzzerTraceConstCmp1(arg0, arg1 uint8, fakePC int) {
+func libfuzzerTraceConstCmp1(arg0, arg1 uint8, fakePC uint) {
 	fakePC = fakePC % retSledSize
 	libfuzzerCallTraceIntCmp(&__sanitizer_cov_trace_const_cmp1, uintptr(arg0), uintptr(arg1), uintptr(fakePC))
 }
 
 //go:nosplit
-func libfuzzerTraceConstCmp2(arg0, arg1 uint16, fakePC int) {
+func libfuzzerTraceConstCmp2(arg0, arg1 uint16, fakePC uint) {
 	fakePC = fakePC % retSledSize
 	libfuzzerCallTraceIntCmp(&__sanitizer_cov_trace_const_cmp2, uintptr(arg0), uintptr(arg1), uintptr(fakePC))
 }
 
 //go:nosplit
-func libfuzzerTraceConstCmp4(arg0, arg1 uint32, fakePC int) {
+func libfuzzerTraceConstCmp4(arg0, arg1 uint32, fakePC uint) {
 	fakePC = fakePC % retSledSize
 	libfuzzerCallTraceIntCmp(&__sanitizer_cov_trace_const_cmp4, uintptr(arg0), uintptr(arg1), uintptr(fakePC))
 }
 
 //go:nosplit
-func libfuzzerTraceConstCmp8(arg0, arg1 uint64, fakePC int) {
+func libfuzzerTraceConstCmp8(arg0, arg1 uint64, fakePC uint) {
 	fakePC = fakePC % retSledSize
 	libfuzzerCallTraceIntCmp(&__sanitizer_cov_trace_const_cmp8, uintptr(arg0), uintptr(arg1), uintptr(fakePC))
 }
@@ -148,13 +148,8 @@
 //go:cgo_import_static __sanitizer_cov_8bit_counters_init
 var __sanitizer_cov_8bit_counters_init byte
 
-//go:linkname __start___sancov_cntrs __start___sancov_cntrs
-//go:cgo_import_static __start___sancov_cntrs
-var __start___sancov_cntrs byte
-
-//go:linkname __stop___sancov_cntrs __stop___sancov_cntrs
-//go:cgo_import_static __stop___sancov_cntrs
-var __stop___sancov_cntrs byte
+// start, stop markers of counters, set by the linker
+var __start___sancov_cntrs, __stop___sancov_cntrs byte
 
 //go:linkname __sanitizer_cov_pcs_init __sanitizer_cov_pcs_init
 //go:cgo_import_static __sanitizer_cov_pcs_init
diff --git a/src/runtime/libfuzzer_amd64.s b/src/runtime/libfuzzer_amd64.s
index 65ac7a3..4355369 100644
--- a/src/runtime/libfuzzer_amd64.s
+++ b/src/runtime/libfuzzer_amd64.s
@@ -52,7 +52,7 @@
 // manipulating the return address so that libfuzzer's integer compare hooks
 // work
 // libFuzzer's compare hooks obtain the caller's address from the compiler
-// builtin __builtin_return_adress. Since we invoke the hooks always
+// builtin __builtin_return_address. Since we invoke the hooks always
 // from the same native function, this builtin would always return the same
 // value. Internally, the libFuzzer hooks call through to the always inlined
 // HandleCmp and thus can't be mimicked without patching libFuzzer.
diff --git a/src/runtime/lock_futex.go b/src/runtime/lock_futex.go
index 1578984..cc7d465 100644
--- a/src/runtime/lock_futex.go
+++ b/src/runtime/lock_futex.go
@@ -226,7 +226,7 @@
 }
 
 // same as runtime·notetsleep, but called on user g (not g0)
-// calls only nosplit functions between entersyscallblock/exitsyscall
+// calls only nosplit functions between entersyscallblock/exitsyscall.
 func notetsleepg(n *note, ns int64) bool {
 	gp := getg()
 	if gp == gp.m.g0 {
diff --git a/src/runtime/lock_sema.go b/src/runtime/lock_sema.go
index c5e8cfe..e15bbf7 100644
--- a/src/runtime/lock_sema.go
+++ b/src/runtime/lock_sema.go
@@ -284,7 +284,7 @@
 }
 
 // same as runtime·notetsleep, but called on user g (not g0)
-// calls only nosplit functions between entersyscallblock/exitsyscall
+// calls only nosplit functions between entersyscallblock/exitsyscall.
 func notetsleepg(n *note, ns int64) bool {
 	gp := getg()
 	if gp == gp.m.g0 {
diff --git a/src/runtime/lockrank.go b/src/runtime/lockrank.go
index bb0b189..284a61e 100644
--- a/src/runtime/lockrank.go
+++ b/src/runtime/lockrank.go
@@ -1,183 +1,120 @@
-// Copyright 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file records the static ranks of the locks in the runtime. If a lock
-// is not given a rank, then it is assumed to be a leaf lock, which means no other
-// lock can be acquired while it is held. Therefore, leaf locks do not need to be
-// given an explicit rank. We list all of the architecture-independent leaf locks
-// for documentation purposes, but don't list any of the architecture-dependent
-// locks (which are all leaf locks). debugLock is ignored for ranking, since it is used
-// when printing out lock ranking errors.
-//
-// lockInit(l *mutex, rank int) is used to set the rank of lock before it is used.
-// If there is no clear place to initialize a lock, then the rank of a lock can be
-// specified during the lock call itself via lockWithrank(l *mutex, rank int).
-//
-// Besides the static lock ranking (which is a total ordering of the locks), we
-// also represent and enforce the actual partial order among the locks in the
-// arcs[] array below. That is, if it is possible that lock B can be acquired when
-// lock A is the previous acquired lock that is still held, then there should be
-// an entry for A in arcs[B][]. We will currently fail not only if the total order
-// (the lock ranking) is violated, but also if there is a missing entry in the
-// partial order.
+// Code generated by mklockrank.go; DO NOT EDIT.
 
 package runtime
 
 type lockRank int
 
-// Constants representing the lock rank of the architecture-independent locks in
-// the runtime. Locks with lower rank must be taken before locks with higher
-// rank.
+// Constants representing the ranks of all non-leaf runtime locks, in rank order.
+// Locks with lower rank must be taken before locks with higher rank,
+// in addition to satisfying the partial order in lockPartialOrder.
+// A few ranks allow self-cycles, which are specified in lockPartialOrder.
 const (
-	lockRankDummy lockRank = iota
+	lockRankUnknown lockRank = iota
 
-	// Locks held above sched
 	lockRankSysmon
 	lockRankScavenge
 	lockRankForcegc
+	lockRankDefer
 	lockRankSweepWaiters
 	lockRankAssistQueue
-	lockRankCpuprof
 	lockRankSweep
-
 	lockRankPollDesc
+	lockRankCpuprof
 	lockRankSched
-	lockRankDeadlock
 	lockRankAllg
 	lockRankAllp
-
-	lockRankTimers // Multiple timers locked simultaneously in destroy()
+	lockRankTimers
+	lockRankNetpollInit
+	lockRankHchan
+	lockRankNotifyList
+	lockRankSudog
+	lockRankRwmutexW
+	lockRankRwmutexR
+	lockRankRoot
 	lockRankItab
 	lockRankReflectOffs
-	lockRankHchan // Multiple hchans acquired in lock order in syncadjustsudogs()
+	lockRankUserArenaState
+	// TRACEGLOBAL
 	lockRankTraceBuf
-	lockRankFin
-	lockRankNotifyList
 	lockRankTraceStrings
+	// MALLOC
+	lockRankFin
+	lockRankGcBitsArenas
+	lockRankMheapSpecial
 	lockRankMspanSpecial
+	lockRankSpanSetSpine
+	// MPROF
 	lockRankProfInsert
 	lockRankProfBlock
 	lockRankProfMemActive
 	lockRankProfMemFuture
-	lockRankGcBitsArenas
-	lockRankRoot
-	lockRankTrace
-	lockRankTraceStackTab
-	lockRankNetpollInit
-
-	lockRankRwmutexW
-	lockRankRwmutexR
-
-	lockRankSpanSetSpine
+	// STACKGROW
 	lockRankGscan
 	lockRankStackpool
 	lockRankStackLarge
-	lockRankDefer
-	lockRankSudog
-
-	// Memory-related non-leaf locks
+	lockRankHchanLeaf
+	// WB
 	lockRankWbufSpans
 	lockRankMheap
-	lockRankMheapSpecial
-
-	// Memory-related leaf locks
 	lockRankGlobalAlloc
-	lockRankPageAllocScav
-
-	// Other leaf locks
-	lockRankGFree
-	// Generally, hchan must be acquired before gscan. But in one specific
-	// case (in syncadjustsudogs from markroot after the g has been suspended
-	// by suspendG), we allow gscan to be acquired, and then an hchan lock. To
-	// allow this case, we get this lockRankHchanLeaf rank in
-	// syncadjustsudogs(), rather than lockRankHchan. By using this special
-	// rank, we don't allow any further locks to be acquired other than more
-	// hchan locks.
-	lockRankHchanLeaf
+	// TRACE
+	lockRankTrace
+	lockRankTraceStackTab
 	lockRankPanic
-
-	// Leaf locks with no dependencies, so these constants are not actually used anywhere.
-	// There are other architecture-dependent leaf locks as well.
-	lockRankNewmHandoff
-	lockRankDebugPtrmask
-	lockRankFaketimeState
-	lockRankTicks
-	lockRankRaceFini
-	lockRankPollCache
-	lockRankDebug
+	lockRankDeadlock
 )
 
-// lockRankLeafRank is the rank of lock that does not have a declared rank, and hence is
-// a leaf lock.
+// lockRankLeafRank is the rank of lock that does not have a declared rank,
+// and hence is a leaf lock.
 const lockRankLeafRank lockRank = 1000
 
-// lockNames gives the names associated with each of the above ranks
+// lockNames gives the names associated with each of the above ranks.
 var lockNames = []string{
-	lockRankDummy: "",
-
-	lockRankSysmon:       "sysmon",
-	lockRankScavenge:     "scavenge",
-	lockRankForcegc:      "forcegc",
-	lockRankSweepWaiters: "sweepWaiters",
-	lockRankAssistQueue:  "assistQueue",
-	lockRankCpuprof:      "cpuprof",
-	lockRankSweep:        "sweep",
-
-	lockRankPollDesc: "pollDesc",
-	lockRankSched:    "sched",
-	lockRankDeadlock: "deadlock",
-	lockRankAllg:     "allg",
-	lockRankAllp:     "allp",
-
-	lockRankTimers:      "timers",
-	lockRankItab:        "itab",
-	lockRankReflectOffs: "reflectOffs",
-
-	lockRankHchan:         "hchan",
-	lockRankTraceBuf:      "traceBuf",
-	lockRankFin:           "fin",
-	lockRankNotifyList:    "notifyList",
-	lockRankTraceStrings:  "traceStrings",
-	lockRankMspanSpecial:  "mspanSpecial",
-	lockRankProfInsert:    "profInsert",
-	lockRankProfBlock:     "profBlock",
-	lockRankProfMemActive: "profMemActive",
-	lockRankProfMemFuture: "profMemFuture",
-	lockRankGcBitsArenas:  "gcBitsArenas",
-	lockRankRoot:          "root",
-	lockRankTrace:         "trace",
-	lockRankTraceStackTab: "traceStackTab",
-	lockRankNetpollInit:   "netpollInit",
-
-	lockRankRwmutexW: "rwmutexW",
-	lockRankRwmutexR: "rwmutexR",
-
-	lockRankSpanSetSpine: "spanSetSpine",
-	lockRankGscan:        "gscan",
-	lockRankStackpool:    "stackpool",
-	lockRankStackLarge:   "stackLarge",
-	lockRankDefer:        "defer",
-	lockRankSudog:        "sudog",
-
-	lockRankWbufSpans:    "wbufSpans",
-	lockRankMheap:        "mheap",
-	lockRankMheapSpecial: "mheapSpecial",
-
-	lockRankGlobalAlloc:   "globalAlloc.mutex",
-	lockRankPageAllocScav: "pageAlloc.scav.lock",
-
-	lockRankGFree:     "gFree",
-	lockRankHchanLeaf: "hchanLeaf",
-	lockRankPanic:     "panic",
-
-	lockRankNewmHandoff:   "newmHandoff.lock",
-	lockRankDebugPtrmask:  "debugPtrmask.lock",
-	lockRankFaketimeState: "faketimeState.lock",
-	lockRankTicks:         "ticks.lock",
-	lockRankRaceFini:      "raceFiniLock",
-	lockRankPollCache:     "pollCache.lock",
-	lockRankDebug:         "debugLock",
+	lockRankSysmon:         "sysmon",
+	lockRankScavenge:       "scavenge",
+	lockRankForcegc:        "forcegc",
+	lockRankDefer:          "defer",
+	lockRankSweepWaiters:   "sweepWaiters",
+	lockRankAssistQueue:    "assistQueue",
+	lockRankSweep:          "sweep",
+	lockRankPollDesc:       "pollDesc",
+	lockRankCpuprof:        "cpuprof",
+	lockRankSched:          "sched",
+	lockRankAllg:           "allg",
+	lockRankAllp:           "allp",
+	lockRankTimers:         "timers",
+	lockRankNetpollInit:    "netpollInit",
+	lockRankHchan:          "hchan",
+	lockRankNotifyList:     "notifyList",
+	lockRankSudog:          "sudog",
+	lockRankRwmutexW:       "rwmutexW",
+	lockRankRwmutexR:       "rwmutexR",
+	lockRankRoot:           "root",
+	lockRankItab:           "itab",
+	lockRankReflectOffs:    "reflectOffs",
+	lockRankUserArenaState: "userArenaState",
+	lockRankTraceBuf:       "traceBuf",
+	lockRankTraceStrings:   "traceStrings",
+	lockRankFin:            "fin",
+	lockRankGcBitsArenas:   "gcBitsArenas",
+	lockRankMheapSpecial:   "mheapSpecial",
+	lockRankMspanSpecial:   "mspanSpecial",
+	lockRankSpanSetSpine:   "spanSetSpine",
+	lockRankProfInsert:     "profInsert",
+	lockRankProfBlock:      "profBlock",
+	lockRankProfMemActive:  "profMemActive",
+	lockRankProfMemFuture:  "profMemFuture",
+	lockRankGscan:          "gscan",
+	lockRankStackpool:      "stackpool",
+	lockRankStackLarge:     "stackLarge",
+	lockRankHchanLeaf:      "hchanLeaf",
+	lockRankWbufSpans:      "wbufSpans",
+	lockRankMheap:          "mheap",
+	lockRankGlobalAlloc:    "globalAlloc",
+	lockRankTrace:          "trace",
+	lockRankTraceStackTab:  "traceStackTab",
+	lockRankPanic:          "panic",
+	lockRankDeadlock:       "deadlock",
 }
 
 func (rank lockRank) String() string {
@@ -187,74 +124,61 @@
 	if rank == lockRankLeafRank {
 		return "LEAF"
 	}
+	if rank < 0 || int(rank) >= len(lockNames) {
+		return "BAD RANK"
+	}
 	return lockNames[rank]
 }
 
-// lockPartialOrder is a partial order among the various lock types, listing the
-// immediate ordering that has actually been observed in the runtime. Each entry
-// (which corresponds to a particular lock rank) specifies the list of locks
-// that can already be held immediately "above" it.
+// lockPartialOrder is the transitive closure of the lock rank graph.
+// An entry for rank X lists all of the ranks that can already be held
+// when rank X is acquired.
 //
-// So, for example, the lockRankSched entry shows that all the locks preceding
-// it in rank can actually be held. The allp lock shows that only the sysmon or
-// sched lock can be held immediately above it when it is acquired.
+// Lock ranks that allow self-cycles list themselves.
 var lockPartialOrder [][]lockRank = [][]lockRank{
-	lockRankDummy:         {},
-	lockRankSysmon:        {},
-	lockRankScavenge:      {lockRankSysmon},
-	lockRankForcegc:       {lockRankSysmon},
-	lockRankSweepWaiters:  {},
-	lockRankAssistQueue:   {},
-	lockRankCpuprof:       {},
-	lockRankSweep:         {},
-	lockRankPollDesc:      {},
-	lockRankSched:         {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankPollDesc},
-	lockRankDeadlock:      {lockRankDeadlock},
-	lockRankAllg:          {lockRankSysmon, lockRankSched},
-	lockRankAllp:          {lockRankSysmon, lockRankSched},
-	lockRankTimers:        {lockRankSysmon, lockRankScavenge, lockRankPollDesc, lockRankSched, lockRankAllp, lockRankTimers},
-	lockRankItab:          {},
-	lockRankReflectOffs:   {lockRankItab},
-	lockRankHchan:         {lockRankScavenge, lockRankSweep, lockRankHchan},
-	lockRankTraceBuf:      {lockRankSysmon, lockRankScavenge},
-	lockRankFin:           {lockRankSysmon, lockRankScavenge, lockRankSched, lockRankAllg, lockRankTimers, lockRankReflectOffs, lockRankHchan, lockRankTraceBuf},
-	lockRankNotifyList:    {},
-	lockRankTraceStrings:  {lockRankTraceBuf},
-	lockRankMspanSpecial:  {lockRankSysmon, lockRankScavenge, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankTraceBuf, lockRankNotifyList, lockRankTraceStrings},
-	lockRankProfInsert:    {lockRankSysmon, lockRankScavenge, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankTraceBuf, lockRankNotifyList, lockRankTraceStrings},
-	lockRankProfBlock:     {lockRankSysmon, lockRankScavenge, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankTraceBuf, lockRankNotifyList, lockRankTraceStrings},
-	lockRankProfMemActive: {lockRankSysmon, lockRankScavenge, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankTraceBuf, lockRankNotifyList, lockRankTraceStrings},
-	lockRankProfMemFuture: {lockRankSysmon, lockRankScavenge, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankTraceBuf, lockRankNotifyList, lockRankTraceStrings, lockRankProfMemActive},
-	lockRankGcBitsArenas:  {lockRankSysmon, lockRankScavenge, lockRankAssistQueue, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankTraceBuf, lockRankNotifyList, lockRankTraceStrings},
-	lockRankRoot:          {},
-	lockRankTrace:         {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankAssistQueue, lockRankSweep, lockRankSched, lockRankHchan, lockRankTraceBuf, lockRankTraceStrings, lockRankRoot},
-	lockRankTraceStackTab: {lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankSched, lockRankAllg, lockRankTimers, lockRankHchan, lockRankTraceBuf, lockRankFin, lockRankNotifyList, lockRankTraceStrings, lockRankRoot, lockRankTrace},
-	lockRankNetpollInit:   {lockRankTimers},
-
-	lockRankRwmutexW: {},
-	lockRankRwmutexR: {lockRankSysmon, lockRankRwmutexW},
-
-	lockRankSpanSetSpine:  {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankPollDesc, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankTraceBuf, lockRankNotifyList, lockRankTraceStrings},
-	lockRankGscan:         {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankPollDesc, lockRankSched, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankTraceBuf, lockRankFin, lockRankNotifyList, lockRankTraceStrings, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankGcBitsArenas, lockRankRoot, lockRankTrace, lockRankTraceStackTab, lockRankNetpollInit, lockRankSpanSetSpine},
-	lockRankStackpool:     {lockRankSysmon, lockRankScavenge, lockRankSweepWaiters, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankPollDesc, lockRankSched, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankTraceBuf, lockRankFin, lockRankNotifyList, lockRankTraceStrings, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankGcBitsArenas, lockRankRoot, lockRankTrace, lockRankTraceStackTab, lockRankNetpollInit, lockRankRwmutexR, lockRankSpanSetSpine, lockRankGscan},
-	lockRankStackLarge:    {lockRankSysmon, lockRankAssistQueue, lockRankSched, lockRankItab, lockRankHchan, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankGcBitsArenas, lockRankRoot, lockRankSpanSetSpine, lockRankGscan},
-	lockRankDefer:         {},
-	lockRankSudog:         {lockRankHchan, lockRankNotifyList},
-	lockRankWbufSpans:     {lockRankSysmon, lockRankScavenge, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankSched, lockRankAllg, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankFin, lockRankNotifyList, lockRankTraceStrings, lockRankMspanSpecial, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankRoot, lockRankTrace, lockRankGscan, lockRankDefer, lockRankSudog},
-	lockRankMheap:         {lockRankSysmon, lockRankScavenge, lockRankSweepWaiters, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankPollDesc, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankTraceBuf, lockRankFin, lockRankNotifyList, lockRankTraceStrings, lockRankMspanSpecial, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankGcBitsArenas, lockRankRoot, lockRankTrace, lockRankSpanSetSpine, lockRankGscan, lockRankStackpool, lockRankStackLarge, lockRankDefer, lockRankSudog, lockRankWbufSpans},
-	lockRankMheapSpecial:  {lockRankSysmon, lockRankScavenge, lockRankAssistQueue, lockRankCpuprof, lockRankSweep, lockRankPollDesc, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankItab, lockRankReflectOffs, lockRankHchan, lockRankTraceBuf, lockRankNotifyList, lockRankTraceStrings},
-	lockRankGlobalAlloc:   {lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankSpanSetSpine, lockRankMheap, lockRankMheapSpecial},
-	lockRankPageAllocScav: {lockRankMheap},
-
-	lockRankGFree:     {lockRankSched},
-	lockRankHchanLeaf: {lockRankGscan, lockRankHchanLeaf},
-	lockRankPanic:     {lockRankDeadlock}, // plus any other lock held on throw.
-
-	lockRankNewmHandoff:   {},
-	lockRankDebugPtrmask:  {},
-	lockRankFaketimeState: {},
-	lockRankTicks:         {},
-	lockRankRaceFini:      {},
-	lockRankPollCache:     {},
-	lockRankDebug:         {},
+	lockRankSysmon:         {},
+	lockRankScavenge:       {lockRankSysmon},
+	lockRankForcegc:        {lockRankSysmon},
+	lockRankDefer:          {},
+	lockRankSweepWaiters:   {},
+	lockRankAssistQueue:    {},
+	lockRankSweep:          {},
+	lockRankPollDesc:       {},
+	lockRankCpuprof:        {},
+	lockRankSched:          {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof},
+	lockRankAllg:           {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched},
+	lockRankAllp:           {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched},
+	lockRankTimers:         {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllp, lockRankTimers},
+	lockRankNetpollInit:    {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllp, lockRankTimers},
+	lockRankHchan:          {lockRankSysmon, lockRankScavenge, lockRankSweep, lockRankHchan},
+	lockRankNotifyList:     {},
+	lockRankSudog:          {lockRankSysmon, lockRankScavenge, lockRankSweep, lockRankHchan, lockRankNotifyList},
+	lockRankRwmutexW:       {},
+	lockRankRwmutexR:       {lockRankSysmon, lockRankRwmutexW},
+	lockRankRoot:           {},
+	lockRankItab:           {},
+	lockRankReflectOffs:    {lockRankItab},
+	lockRankUserArenaState: {},
+	lockRankTraceBuf:       {lockRankSysmon, lockRankScavenge},
+	lockRankTraceStrings:   {lockRankSysmon, lockRankScavenge, lockRankTraceBuf},
+	lockRankFin:            {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankHchan, lockRankNotifyList, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings},
+	lockRankGcBitsArenas:   {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankHchan, lockRankNotifyList, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings},
+	lockRankMheapSpecial:   {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankHchan, lockRankNotifyList, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings},
+	lockRankMspanSpecial:   {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankHchan, lockRankNotifyList, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings},
+	lockRankSpanSetSpine:   {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankHchan, lockRankNotifyList, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings},
+	lockRankProfInsert:     {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankHchan, lockRankNotifyList, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings},
+	lockRankProfBlock:      {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankHchan, lockRankNotifyList, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings},
+	lockRankProfMemActive:  {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankHchan, lockRankNotifyList, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings},
+	lockRankProfMemFuture:  {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankHchan, lockRankNotifyList, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankProfMemActive},
+	lockRankGscan:          {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankNetpollInit, lockRankHchan, lockRankNotifyList, lockRankRoot, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankFin, lockRankGcBitsArenas, lockRankSpanSetSpine, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture},
+	lockRankStackpool:      {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankNetpollInit, lockRankHchan, lockRankNotifyList, lockRankRwmutexW, lockRankRwmutexR, lockRankRoot, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankFin, lockRankGcBitsArenas, lockRankSpanSetSpine, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankGscan},
+	lockRankStackLarge:     {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankNetpollInit, lockRankHchan, lockRankNotifyList, lockRankRoot, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankFin, lockRankGcBitsArenas, lockRankSpanSetSpine, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankGscan},
+	lockRankHchanLeaf:      {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankNetpollInit, lockRankHchan, lockRankNotifyList, lockRankRoot, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankFin, lockRankGcBitsArenas, lockRankSpanSetSpine, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankGscan, lockRankHchanLeaf},
+	lockRankWbufSpans:      {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankDefer, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankNetpollInit, lockRankHchan, lockRankNotifyList, lockRankSudog, lockRankRoot, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankFin, lockRankGcBitsArenas, lockRankMspanSpecial, lockRankSpanSetSpine, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankGscan},
+	lockRankMheap:          {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankDefer, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankNetpollInit, lockRankHchan, lockRankNotifyList, lockRankSudog, lockRankRwmutexW, lockRankRwmutexR, lockRankRoot, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankFin, lockRankGcBitsArenas, lockRankMspanSpecial, lockRankSpanSetSpine, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankGscan, lockRankStackpool, lockRankStackLarge, lockRankWbufSpans},
+	lockRankGlobalAlloc:    {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankDefer, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankNetpollInit, lockRankHchan, lockRankNotifyList, lockRankSudog, lockRankRwmutexW, lockRankRwmutexR, lockRankRoot, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankFin, lockRankGcBitsArenas, lockRankMheapSpecial, lockRankMspanSpecial, lockRankSpanSetSpine, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankGscan, lockRankStackpool, lockRankStackLarge, lockRankWbufSpans, lockRankMheap},
+	lockRankTrace:          {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankDefer, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankNetpollInit, lockRankHchan, lockRankNotifyList, lockRankSudog, lockRankRwmutexW, lockRankRwmutexR, lockRankRoot, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankFin, lockRankGcBitsArenas, lockRankMspanSpecial, lockRankSpanSetSpine, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankGscan, lockRankStackpool, lockRankStackLarge, lockRankWbufSpans, lockRankMheap},
+	lockRankTraceStackTab:  {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankDefer, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankNetpollInit, lockRankHchan, lockRankNotifyList, lockRankSudog, lockRankRwmutexW, lockRankRwmutexR, lockRankRoot, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankFin, lockRankGcBitsArenas, lockRankMspanSpecial, lockRankSpanSetSpine, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankGscan, lockRankStackpool, lockRankStackLarge, lockRankWbufSpans, lockRankMheap, lockRankTrace},
+	lockRankPanic:          {},
+	lockRankDeadlock:       {lockRankPanic, lockRankDeadlock},
 }
diff --git a/src/runtime/lockrank_on.go b/src/runtime/lockrank_on.go
index a170569..5dcc79b 100644
--- a/src/runtime/lockrank_on.go
+++ b/src/runtime/lockrank_on.go
@@ -13,7 +13,7 @@
 
 // worldIsStopped is accessed atomically to track world-stops. 1 == world
 // stopped.
-var worldIsStopped uint32
+var worldIsStopped atomic.Uint32
 
 // lockRankStruct is embedded in mutex
 type lockRankStruct struct {
@@ -24,6 +24,9 @@
 	pad int
 }
 
+// lockInit(l *mutex, rank int) sets the rank of lock before it is used.
+// If there is no clear place to initialize a lock, then the rank of a lock can be
+// specified during the lock call itself via lockWithRank(l *mutex, rank int).
 func lockInit(l *mutex, rank lockRank) {
 	l.rank = rank
 }
@@ -298,7 +301,7 @@
 //
 //go:nosplit
 func worldStopped() {
-	if stopped := atomic.Xadd(&worldIsStopped, 1); stopped != 1 {
+	if stopped := worldIsStopped.Add(1); stopped != 1 {
 		systemstack(func() {
 			print("world stop count=", stopped, "\n")
 			throw("recursive world stop")
@@ -314,7 +317,7 @@
 //
 //go:nosplit
 func worldStarted() {
-	if stopped := atomic.Xadd(&worldIsStopped, -1); stopped != 0 {
+	if stopped := worldIsStopped.Add(-1); stopped != 0 {
 		systemstack(func() {
 			print("world stop count=", stopped, "\n")
 			throw("released non-stopped world stop")
@@ -326,7 +329,7 @@
 //
 //go:nosplit
 func checkWorldStopped() bool {
-	stopped := atomic.Load(&worldIsStopped)
+	stopped := worldIsStopped.Load()
 	if stopped > 1 {
 		systemstack(func() {
 			print("inconsistent world stop count=", stopped, "\n")
diff --git a/src/runtime/lockrank_test.go b/src/runtime/lockrank_test.go
index 4b2fc0e..a7b1b8d 100644
--- a/src/runtime/lockrank_test.go
+++ b/src/runtime/lockrank_test.go
@@ -1,41 +1,29 @@
-// Copyright 2021 The Go Authors. All rights reserved.
+// Copyright 2022 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
 package runtime_test
 
 import (
-	. "runtime"
+	"bytes"
+	"internal/testenv"
+	"os"
+	"os/exec"
 	"testing"
 )
 
-// Check that the partial order in lockPartialOrder fits within the total order
-// determined by the order of the lockRank constants.
-func TestLockRankPartialOrder(t *testing.T) {
-	for r, list := range LockPartialOrder {
-		rank := LockRank(r)
-		for _, e := range list {
-			entry := LockRank(e)
-			if entry > rank {
-				t.Errorf("lockPartialOrder row %v entry %v is inconsistent with total lock ranking order", rank, entry)
-			}
-		}
+// Test that the generated code for the lock rank graph is up-to-date.
+func TestLockRankGenerated(t *testing.T) {
+	testenv.MustHaveGoRun(t)
+	want, err := testenv.CleanCmdEnv(exec.Command(testenv.GoToolPath(t), "run", "mklockrank.go")).CombinedOutput()
+	if err != nil {
+		t.Fatal(err)
 	}
-}
-
-// Verify that partial order lists are kept sorted. This is a purely cosemetic
-// check to make manual reviews simpler. It does not affect correctness, unlike
-// the above test.
-func TestLockRankPartialOrderSortedEntries(t *testing.T) {
-	for r, list := range LockPartialOrder {
-		rank := LockRank(r)
-		var prev LockRank
-		for _, e := range list {
-			entry := LockRank(e)
-			if entry <= prev {
-				t.Errorf("Partial order for rank %v out of order: %v <= %v in %v", rank, entry, prev, list)
-			}
-			prev = entry
-		}
+	got, err := os.ReadFile("lockrank.go")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !bytes.Equal(want, got) {
+		t.Fatalf("lockrank.go is out of date. Please run go generate.")
 	}
 }
diff --git a/src/runtime/malloc.go b/src/runtime/malloc.go
index eb24fdb..7ff2190 100644
--- a/src/runtime/malloc.go
+++ b/src/runtime/malloc.go
@@ -247,13 +247,15 @@
 	// memory.
 	heapArenaBytes = 1 << logHeapArenaBytes
 
+	heapArenaWords = heapArenaBytes / goarch.PtrSize
+
 	// logHeapArenaBytes is log_2 of heapArenaBytes. For clarity,
 	// prefer using heapArenaBytes where possible (we need the
 	// constant to compute some other constants).
 	logHeapArenaBytes = (6+20)*(_64bit*(1-goos.IsWindows)*(1-goarch.IsWasm)*(1-goos.IsIos*goarch.IsArm64)) + (2+20)*(_64bit*goos.IsWindows) + (2+20)*(1-_64bit) + (2+20)*goarch.IsWasm + (2+20)*goos.IsIos*goarch.IsArm64
 
-	// heapArenaBitmapBytes is the size of each heap arena's bitmap.
-	heapArenaBitmapBytes = heapArenaBytes / (goarch.PtrSize * 8 / 2)
+	// heapArenaBitmapWords is the size of each heap arena's bitmap in uintptrs.
+	heapArenaBitmapWords = heapArenaWords / (8 * goarch.PtrSize)
 
 	pagesPerArena = heapArenaBytes / pageSize
 
@@ -353,10 +355,10 @@
 		throw("bad TinySizeClass")
 	}
 
-	if heapArenaBitmapBytes&(heapArenaBitmapBytes-1) != 0 {
+	if heapArenaBitmapWords&(heapArenaBitmapWords-1) != 0 {
 		// heapBits expects modular arithmetic on bitmap
 		// addresses to work.
-		throw("heapArenaBitmapBytes not a power of 2")
+		throw("heapArenaBitmapWords not a power of 2")
 	}
 
 	// Check physPageSize.
@@ -450,6 +452,14 @@
 		//
 		// On AIX, mmaps starts at 0x0A00000000000000 for 64-bit.
 		// processes.
+		//
+		// Space mapped for user arenas comes immediately after the range
+		// originally reserved for the regular heap when race mode is not
+		// enabled because user arena chunks can never be used for regular heap
+		// allocations and we want to avoid fragmenting the address space.
+		//
+		// In race mode we have no choice but to just use the same hints because
+		// the race detector requires that the heap be mapped contiguously.
 		for i := 0x7f; i >= 0; i-- {
 			var p uintptr
 			switch {
@@ -475,9 +485,16 @@
 			default:
 				p = uintptr(i)<<40 | uintptrMask&(0x00c0<<32)
 			}
+			// Switch to generating hints for user arenas if we've gone
+			// through about half the hints. In race mode, take only about
+			// a quarter; we don't have very much space to work with.
+			hintList := &mheap_.arenaHints
+			if (!raceenabled && i > 0x3f) || (raceenabled && i > 0x5f) {
+				hintList = &mheap_.userArena.arenaHints
+			}
 			hint := (*arenaHint)(mheap_.arenaHintAlloc.alloc())
 			hint.addr = p
-			hint.next, mheap_.arenaHints = mheap_.arenaHints, hint
+			hint.next, *hintList = *hintList, hint
 		}
 	} else {
 		// On a 32-bit machine, we're much more concerned
@@ -545,6 +562,14 @@
 		hint := (*arenaHint)(mheap_.arenaHintAlloc.alloc())
 		hint.addr = p
 		hint.next, mheap_.arenaHints = mheap_.arenaHints, hint
+
+		// Place the hint for user arenas just after the large reservation.
+		//
+		// While this potentially competes with the hint above, in practice we probably
+		// aren't going to be getting this far anyway on 32-bit platforms.
+		userArenaHint := (*arenaHint)(mheap_.arenaHintAlloc.alloc())
+		userArenaHint.addr = p
+		userArenaHint.next, mheap_.userArena.arenaHints = mheap_.userArena.arenaHints, userArenaHint
 	}
 }
 
@@ -554,26 +579,37 @@
 // heapArenaBytes. sysAlloc returns nil on failure.
 // There is no corresponding free function.
 //
+// hintList is a list of hint addresses for where to allocate new
+// heap arenas. It must be non-nil.
+//
+// register indicates whether the heap arena should be registered
+// in allArenas.
+//
 // sysAlloc returns a memory region in the Reserved state. This region must
 // be transitioned to Prepared and then Ready before use.
 //
 // h must be locked.
-func (h *mheap) sysAlloc(n uintptr) (v unsafe.Pointer, size uintptr) {
+func (h *mheap) sysAlloc(n uintptr, hintList **arenaHint, register bool) (v unsafe.Pointer, size uintptr) {
 	assertLockHeld(&h.lock)
 
 	n = alignUp(n, heapArenaBytes)
 
-	// First, try the arena pre-reservation.
-	// Newly-used mappings are considered released.
-	v = h.arena.alloc(n, heapArenaBytes, &gcController.heapReleased)
-	if v != nil {
-		size = n
-		goto mapped
+	if hintList == &h.arenaHints {
+		// First, try the arena pre-reservation.
+		// Newly-used mappings are considered released.
+		//
+		// Only do this if we're using the regular heap arena hints.
+		// This behavior is only for the heap.
+		v = h.arena.alloc(n, heapArenaBytes, &gcController.heapReleased)
+		if v != nil {
+			size = n
+			goto mapped
+		}
 	}
 
 	// Try to grow the heap at a hint address.
-	for h.arenaHints != nil {
-		hint := h.arenaHints
+	for *hintList != nil {
+		hint := *hintList
 		p := hint.addr
 		if hint.down {
 			p -= n
@@ -605,7 +641,7 @@
 		if v != nil {
 			sysFreeOS(v, n)
 		}
-		h.arenaHints = hint.next
+		*hintList = hint.next
 		h.arenaHintAlloc.free(unsafe.Pointer(hint))
 	}
 
@@ -690,26 +726,28 @@
 			}
 		}
 
-		// Add the arena to the arenas list.
-		if len(h.allArenas) == cap(h.allArenas) {
-			size := 2 * uintptr(cap(h.allArenas)) * goarch.PtrSize
-			if size == 0 {
-				size = physPageSize
+		// Register the arena in allArenas if requested.
+		if register {
+			if len(h.allArenas) == cap(h.allArenas) {
+				size := 2 * uintptr(cap(h.allArenas)) * goarch.PtrSize
+				if size == 0 {
+					size = physPageSize
+				}
+				newArray := (*notInHeap)(persistentalloc(size, goarch.PtrSize, &memstats.gcMiscSys))
+				if newArray == nil {
+					throw("out of memory allocating allArenas")
+				}
+				oldSlice := h.allArenas
+				*(*notInHeapSlice)(unsafe.Pointer(&h.allArenas)) = notInHeapSlice{newArray, len(h.allArenas), int(size / goarch.PtrSize)}
+				copy(h.allArenas, oldSlice)
+				// Do not free the old backing array because
+				// there may be concurrent readers. Since we
+				// double the array each time, this can lead
+				// to at most 2x waste.
 			}
-			newArray := (*notInHeap)(persistentalloc(size, goarch.PtrSize, &memstats.gcMiscSys))
-			if newArray == nil {
-				throw("out of memory allocating allArenas")
-			}
-			oldSlice := h.allArenas
-			*(*notInHeapSlice)(unsafe.Pointer(&h.allArenas)) = notInHeapSlice{newArray, len(h.allArenas), int(size / goarch.PtrSize)}
-			copy(h.allArenas, oldSlice)
-			// Do not free the old backing array because
-			// there may be concurrent readers. Since we
-			// double the array each time, this can lead
-			// to at most 2x waste.
+			h.allArenas = h.allArenas[:len(h.allArenas)+1]
+			h.allArenas[len(h.allArenas)-1] = ri
 		}
-		h.allArenas = h.allArenas[:len(h.allArenas)+1]
-		h.allArenas[len(h.allArenas)-1] = ri
 
 		// Store atomically just in case an object from the
 		// new heap arena becomes visible before the heap lock
@@ -740,8 +778,6 @@
 	case p == 0:
 		return nil, 0
 	case p&(align-1) == 0:
-		// We got lucky and got an aligned region, so we can
-		// use the whole thing.
 		return unsafe.Pointer(p), size + align
 	case GOOS == "windows":
 		// On Windows we can't release pieces of a
@@ -780,7 +816,7 @@
 // nextFreeFast returns the next free object if one is quickly available.
 // Otherwise it returns 0.
 func nextFreeFast(s *mspan) gclinkptr {
-	theBit := sys.Ctz64(s.allocCache) // Is there a free object in the allocCache?
+	theBit := sys.TrailingZeros64(s.allocCache) // Is there a free object in the allocCache?
 	if theBit < 64 {
 		result := s.freeindex + uintptr(theBit)
 		if result < s.nelems {
@@ -847,6 +883,11 @@
 	if size == 0 {
 		return unsafe.Pointer(&zerobase)
 	}
+
+	// It's possible for any malloc to trigger sweeping, which may in
+	// turn queue finalizers. Record this dynamic lock edge.
+	lockRankMayQueueFinalizer()
+
 	userSize := size
 	if asanenabled {
 		// Refer to ASAN runtime library, the malloc() function allocates extra memory,
@@ -888,24 +929,7 @@
 
 	// assistG is the G to charge for this allocation, or nil if
 	// GC is not currently active.
-	var assistG *g
-	if gcBlackenEnabled != 0 {
-		// Charge the current user G for this allocation.
-		assistG = getg()
-		if assistG.m.curg != nil {
-			assistG = assistG.m.curg
-		}
-		// Charge the allocation against the G. We'll account
-		// for internal fragmentation at the end of mallocgc.
-		assistG.gcAssistBytes -= int64(size)
-
-		if assistG.gcAssistBytes < 0 {
-			// This G is in debt. Assist the GC to correct
-			// this before allocating. This must happen
-			// before disabling preemption.
-			gcAssistAlloc(assistG)
-		}
-	}
+	assistG := deductAssistCredit(size)
 
 	// Set mp.mallocing to keep from being preempted by GC.
 	mp := acquirem()
@@ -1019,7 +1043,7 @@
 			}
 			x = unsafe.Pointer(v)
 			if needzero && span.needzero != 0 {
-				memclrNoHeapPointers(unsafe.Pointer(v), size)
+				memclrNoHeapPointers(x, size)
 			}
 		}
 	} else {
@@ -1045,8 +1069,8 @@
 		}
 	}
 
-	var scanSize uintptr
 	if !noscan {
+		var scanSize uintptr
 		heapBitsSetType(uintptr(x), size, dataSize, typ)
 		if dataSize > typ.size {
 			// Array allocation. If there are any
@@ -1068,13 +1092,23 @@
 	// the garbage collector could follow a pointer to x,
 	// but see uninitialized memory or stale heap bits.
 	publicationBarrier()
+	// As x and the heap bits are initialized, update
+	// freeIndexForScan now so x is seen by the GC
+	// (including convervative scan) as an allocated object.
+	// While this pointer can't escape into user code as a
+	// _live_ pointer until we return, conservative scanning
+	// may find a dead pointer that happens to point into this
+	// object. Delaying this update until now ensures that
+	// conservative scanning considers this pointer dead until
+	// this point.
+	span.freeIndexForScan = span.freeindex
 
 	// Allocate black during GC.
 	// All slots hold nil so no scanning is needed.
 	// This may be racing with GC so do it atomically if there can be
 	// a race marking the bit.
 	if gcphase != _GCoff {
-		gcmarknewobject(span, uintptr(x), size, scanSize)
+		gcmarknewobject(span, uintptr(x), size)
 	}
 
 	if raceenabled {
@@ -1158,6 +1192,34 @@
 	return x
 }
 
+// deductAssistCredit reduces the current G's assist credit
+// by size bytes, and assists the GC if necessary.
+//
+// Caller must be preemptible.
+//
+// Returns the G for which the assist credit was accounted.
+func deductAssistCredit(size uintptr) *g {
+	var assistG *g
+	if gcBlackenEnabled != 0 {
+		// Charge the current user G for this allocation.
+		assistG = getg()
+		if assistG.m.curg != nil {
+			assistG = assistG.m.curg
+		}
+		// Charge the allocation against the G. We'll account
+		// for internal fragmentation at the end of mallocgc.
+		assistG.gcAssistBytes -= int64(size)
+
+		if assistG.gcAssistBytes < 0 {
+			// This G is in debt. Assist the GC to correct
+			// this before allocating. This must happen
+			// before disabling preemption.
+			gcAssistAlloc(assistG)
+		}
+	}
+	return assistG
+}
+
 // memclrNoHeapPointersChunked repeatedly calls memclrNoHeapPointers
 // on chunks of the buffer to be zeroed, with opportunities for preemption
 // along the way.  memclrNoHeapPointers contains no safepoints and also
@@ -1187,7 +1249,7 @@
 
 // implementation of new builtin
 // compiler (both frontend and SSA backend) knows the signature
-// of this function
+// of this function.
 func newobject(typ *_type) unsafe.Pointer {
 	return mallocgc(typ.size, typ, true)
 }
@@ -1245,7 +1307,7 @@
 	}
 	if GOOS == "plan9" {
 		// Plan 9 doesn't support floating point in note handler.
-		if g := getg(); g == g.m.gsignal {
+		if gp := getg(); gp == gp.m.gsignal {
 			return nextSampleNoFP()
 		}
 	}
@@ -1323,7 +1385,8 @@
 // The returned memory will be zeroed.
 // sysStat must be non-nil.
 //
-// Consider marking persistentalloc'd types go:notinheap.
+// Consider marking persistentalloc'd types not in heap by embedding
+// runtime/internal/sys.NotInHeap.
 func persistentalloc(size, align uintptr, sysStat *sysMemStat) unsafe.Pointer {
 	var p *notInHeap
 	systemstack(func() {
@@ -1464,14 +1527,12 @@
 // notInHeap is off-heap memory allocated by a lower-level allocator
 // like sysAlloc or persistentAlloc.
 //
-// In general, it's better to use real types marked as go:notinheap,
-// but this serves as a generic type for situations where that isn't
-// possible (like in the allocators).
+// In general, it's better to use real types which embed
+// runtime/internal/sys.NotInHeap, but this serves as a generic type
+// for situations where that isn't possible (like in the allocators).
 //
 // TODO: Use this as the return type of sysAlloc, persistentAlloc, etc?
-//
-//go:notinheap
-type notInHeap struct{}
+type notInHeap struct{ _ sys.NotInHeap }
 
 func (p *notInHeap) add(bytes uintptr) *notInHeap {
 	return (*notInHeap)(unsafe.Pointer(uintptr(unsafe.Pointer(p)) + bytes))
diff --git a/src/runtime/malloc_test.go b/src/runtime/malloc_test.go
index cc20076..5b9ce98 100644
--- a/src/runtime/malloc_test.go
+++ b/src/runtime/malloc_test.go
@@ -294,7 +294,11 @@
 	for i := 0; i < 5; i++ {
 		// Reserve memory at the next hint so it can't be used
 		// for the heap.
-		start, end := MapNextArenaHint()
+		start, end, ok := MapNextArenaHint()
+		if !ok {
+			t.Skipf("failed to reserve memory at next arena hint [%#x, %#x)", start, end)
+		}
+		t.Logf("reserved [%#x, %#x)", start, end)
 		disallowed = append(disallowed, [2]uintptr{start, end})
 		// Allocate until the runtime tries to use the hint we
 		// just mapped over.
@@ -314,46 +318,36 @@
 	}
 }
 
-var mallocSink uintptr
-
 func BenchmarkMalloc8(b *testing.B) {
-	var x uintptr
 	for i := 0; i < b.N; i++ {
 		p := new(int64)
-		x ^= uintptr(unsafe.Pointer(p))
+		Escape(p)
 	}
-	mallocSink = x
 }
 
 func BenchmarkMalloc16(b *testing.B) {
-	var x uintptr
 	for i := 0; i < b.N; i++ {
 		p := new([2]int64)
-		x ^= uintptr(unsafe.Pointer(p))
+		Escape(p)
 	}
-	mallocSink = x
 }
 
 func BenchmarkMallocTypeInfo8(b *testing.B) {
-	var x uintptr
 	for i := 0; i < b.N; i++ {
 		p := new(struct {
 			p [8 / unsafe.Sizeof(uintptr(0))]*int
 		})
-		x ^= uintptr(unsafe.Pointer(p))
+		Escape(p)
 	}
-	mallocSink = x
 }
 
 func BenchmarkMallocTypeInfo16(b *testing.B) {
-	var x uintptr
 	for i := 0; i < b.N; i++ {
 		p := new(struct {
 			p [16 / unsafe.Sizeof(uintptr(0))]*int
 		})
-		x ^= uintptr(unsafe.Pointer(p))
+		Escape(p)
 	}
-	mallocSink = x
 }
 
 type LargeStruct struct {
@@ -361,12 +355,10 @@
 }
 
 func BenchmarkMallocLargeStruct(b *testing.B) {
-	var x uintptr
 	for i := 0; i < b.N; i++ {
 		p := make([]LargeStruct, 2)
-		x ^= uintptr(unsafe.Pointer(&p[0]))
+		Escape(p)
 	}
-	mallocSink = x
 }
 
 var n = flag.Int("n", 1000, "number of goroutines")
diff --git a/src/runtime/map.go b/src/runtime/map.go
index 65be472..f546ce8 100644
--- a/src/runtime/map.go
+++ b/src/runtime/map.go
@@ -514,7 +514,7 @@
 	return unsafe.Pointer(&zeroVal[0]), false
 }
 
-// returns both key and elem. Used by map iterator
+// returns both key and elem. Used by map iterator.
 func mapaccessK(t *maptype, h *hmap, key unsafe.Pointer) (unsafe.Pointer, unsafe.Pointer) {
 	if h == nil || h.count == 0 {
 		return nil, nil
diff --git a/src/runtime/mbarrier.go b/src/runtime/mbarrier.go
index c3b4541..46ef42f 100644
--- a/src/runtime/mbarrier.go
+++ b/src/runtime/mbarrier.go
@@ -196,7 +196,7 @@
 	reflect_typedmemmove(typ, dst, src)
 }
 
-// typedmemmovepartial is like typedmemmove but assumes that
+// reflect_typedmemmovepartial is like typedmemmove but assumes that
 // dst and src point off bytes into the value and only copies size bytes.
 // off must be a multiple of goarch.PtrSize.
 //
@@ -311,6 +311,8 @@
 // If the caller knows that typ has pointers, it can alternatively
 // call memclrHasPointers.
 //
+// TODO: A "go:nosplitrec" annotation would be perfect for this.
+//
 //go:nosplit
 func typedmemclr(typ *_type, ptr unsafe.Pointer) {
 	if writeBarrier.needed && typ.ptrdata != 0 {
diff --git a/src/runtime/mbitmap.go b/src/runtime/mbitmap.go
index a3a6590..088b566 100644
--- a/src/runtime/mbitmap.go
+++ b/src/runtime/mbitmap.go
@@ -14,34 +14,28 @@
 //
 // Heap bitmap
 //
-// The heap bitmap comprises 2 bits for each pointer-sized word in the heap,
-// stored in the heapArena metadata backing each heap arena.
-// That is, if ha is the heapArena for the arena starting a start,
-// then ha.bitmap[0] holds the 2-bit entries for the four words start
-// through start+3*ptrSize, ha.bitmap[1] holds the entries for
-// start+4*ptrSize through start+7*ptrSize, and so on.
+// The heap bitmap comprises 1 bit for each pointer-sized word in the heap,
+// recording whether a pointer is stored in that word or not. This bitmap
+// is stored in the heapArena metadata backing each heap arena.
+// That is, if ha is the heapArena for the arena starting at "start",
+// then ha.bitmap[0] holds the 64 bits for the 64 words "start"
+// through start+63*ptrSize, ha.bitmap[1] holds the entries for
+// start+64*ptrSize through start+127*ptrSize, and so on.
+// Bits correspond to words in little-endian order. ha.bitmap[0]&1 represents
+// the word at "start", ha.bitmap[0]>>1&1 represents the word at start+8, etc.
+// (For 32-bit platforms, s/64/32/.)
 //
-// In each 2-bit entry, the lower bit is a pointer/scalar bit, just
-// like in the stack/data bitmaps described above. The upper bit
-// indicates scan/dead: a "1" value ("scan") indicates that there may
-// be pointers in later words of the allocation, and a "0" value
-// ("dead") indicates there are no more pointers in the allocation. If
-// the upper bit is 0, the lower bit must also be 0, and this
-// indicates scanning can ignore the rest of the allocation.
+// We also keep a noMorePtrs bitmap which allows us to stop scanning
+// the heap bitmap early in certain situations. If ha.noMorePtrs[i]>>j&1
+// is 1, then the object containing the last word described by ha.bitmap[8*i+j]
+// has no more pointers beyond those described by ha.bitmap[8*i+j].
+// If ha.noMorePtrs[i]>>j&1 is set, the entries in ha.bitmap[8*i+j+1] and
+// beyond must all be zero until the start of the next object.
 //
-// The 2-bit entries are split when written into the byte, so that the top half
-// of the byte contains 4 high (scan) bits and the bottom half contains 4 low
-// (pointer) bits. This form allows a copy from the 1-bit to the 4-bit form to
-// keep the pointer bits contiguous, instead of having to space them out.
+// The bitmap for noscan spans is set to all zero at span allocation time.
 //
-// The code makes use of the fact that the zero value for a heap
-// bitmap means scalar/dead. This property must be preserved when
-// modifying the encoding.
-//
-// The bitmap for noscan spans is not maintained. Code must ensure
-// that an object is scannable before consulting its bitmap by
-// checking either the noscan bit in the span or by consulting its
-// type's information.
+// The bitmap for unallocated objects in scannable spans is not maintained
+// (can be junk).
 
 package runtime
 
@@ -52,18 +46,6 @@
 	"unsafe"
 )
 
-const (
-	bitPointer = 1 << 0
-	bitScan    = 1 << 4
-
-	heapBitsShift      = 1     // shift offset between successive bitPointer or bitScan entries
-	wordsPerBitmapByte = 8 / 2 // heap words described by one bitmap byte
-
-	// all scan/pointer bits in a byte
-	bitScanAll    = bitScan | bitScan<<heapBitsShift | bitScan<<(2*heapBitsShift) | bitScan<<(3*heapBitsShift)
-	bitPointerAll = bitPointer | bitPointer<<heapBitsShift | bitPointer<<(2*heapBitsShift) | bitPointer<<(3*heapBitsShift)
-)
-
 // addb returns the byte pointer p+n.
 //
 //go:nowritebarrier
@@ -110,21 +92,6 @@
 	return (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(p)) - 1))
 }
 
-// heapBits provides access to the bitmap bits for a single heap word.
-// The methods on heapBits take value receivers so that the compiler
-// can more easily inline calls to those methods and registerize the
-// struct fields independently.
-type heapBits struct {
-	bitp  *uint8
-	shift uint32
-	arena uint32 // Index of heap arena containing bitp
-	last  *uint8 // Last byte arena's bitmap
-}
-
-// Make the compiler check that heapBits.arena is large enough to hold
-// the maximum arena frame number.
-var _ = heapBits{arena: (1<<heapAddrBits)/heapArenaBytes - 1}
-
 // markBits provides access to the mark bit for an object in the heap.
 // bytep points to the byte holding the mark bit.
 // mask is a byte with a single bit set that can be &ed with *bytep
@@ -180,7 +147,7 @@
 
 	aCache := s.allocCache
 
-	bitIndex := sys.Ctz64(aCache)
+	bitIndex := sys.TrailingZeros64(aCache)
 	for bitIndex == 64 {
 		// Move index to start of next cached bits.
 		sfreeindex = (sfreeindex + 64) &^ (64 - 1)
@@ -192,7 +159,7 @@
 		// Refill s.allocCache with the next 64 alloc bits.
 		s.refillAllocCache(whichByte)
 		aCache = s.allocCache
-		bitIndex = sys.Ctz64(aCache)
+		bitIndex = sys.TrailingZeros64(aCache)
 		// nothing available in cached bits
 		// grab the next 8 bytes and try again.
 	}
@@ -224,7 +191,7 @@
 // been no preemption points since ensuring this (which could allow a
 // GC transition, which would allow the state to change).
 func (s *mspan) isFree(index uintptr) bool {
-	if index < s.freeindex {
+	if index < s.freeIndexForScan {
 		return false
 	}
 	bytep, mask := s.allocBits.bitp(index)
@@ -264,7 +231,7 @@
 }
 
 func (s *mspan) markBitsForBase() markBits {
-	return markBits{(*uint8)(s.gcmarkBits), uint8(1), 0}
+	return markBits{&s.gcmarkBits.x, uint8(1), 0}
 }
 
 // isMarked reports whether mark bit m is set.
@@ -313,32 +280,6 @@
 	m.index++
 }
 
-// heapBitsForAddr returns the heapBits for the address addr.
-// The caller must ensure addr is in an allocated span.
-// In particular, be careful not to point past the end of an object.
-//
-// nosplit because it is used during write barriers and must not be preempted.
-//
-//go:nosplit
-func heapBitsForAddr(addr uintptr) (h heapBits) {
-	// 2 bits per word, 4 pairs per byte, and a mask is hard coded.
-	arena := arenaIndex(addr)
-	ha := mheap_.arenas[arena.l1()][arena.l2()]
-	// The compiler uses a load for nil checking ha, but in this
-	// case we'll almost never hit that cache line again, so it
-	// makes more sense to do a value check.
-	if ha == nil {
-		// addr is not in the heap. Return nil heapBits, which
-		// we expect to crash in the caller.
-		return
-	}
-	h.bitp = &ha.bitmap[(addr/(goarch.PtrSize*4))%heapArenaBitmapBytes]
-	h.shift = uint32((addr / goarch.PtrSize) & 3)
-	h.arena = uint32(arena)
-	h.last = &ha.bitmap[len(ha.bitmap)-1]
-	return
-}
-
 // clobberdeadPtr is a special value that is used by the compiler to
 // clobber dead stack slots, when -clobberdead flag is set.
 const clobberdeadPtr = uintptr(0xdeaddead | 0xdeaddead<<((^uintptr(0)>>63)*32))
@@ -423,7 +364,7 @@
 	return
 }
 
-// verifyNotInHeapPtr reports whether converting the not-in-heap pointer into a unsafe.Pointer is ok.
+// reflect_verifyNotInHeapPtr reports whether converting the not-in-heap pointer into a unsafe.Pointer is ok.
 //
 //go:linkname reflect_verifyNotInHeapPtr reflect.verifyNotInHeapPtr
 func reflect_verifyNotInHeapPtr(p uintptr) bool {
@@ -433,121 +374,134 @@
 	return spanOf(p) == nil && p != clobberdeadPtr
 }
 
-// next returns the heapBits describing the next pointer-sized word in memory.
-// That is, if h describes address p, h.next() describes p+ptrSize.
+const ptrBits = 8 * goarch.PtrSize
+
+// heapBits provides access to the bitmap bits for a single heap word.
+// The methods on heapBits take value receivers so that the compiler
+// can more easily inline calls to those methods and registerize the
+// struct fields independently.
+type heapBits struct {
+	// heapBits will report on pointers in the range [addr,addr+size).
+	// The low bit of mask contains the pointerness of the word at addr
+	// (assuming valid>0).
+	addr, size uintptr
+
+	// The next few pointer bits representing words starting at addr.
+	// Those bits already returned by next() are zeroed.
+	mask uintptr
+	// Number of bits in mask that are valid. mask is always less than 1<<valid.
+	valid uintptr
+}
+
+// heapBitsForAddr returns the heapBits for the address addr.
+// The caller must ensure [addr,addr+size) is in an allocated span.
+// In particular, be careful not to point past the end of an object.
+//
+// nosplit because it is used during write barriers and must not be preempted.
+//
+//go:nosplit
+func heapBitsForAddr(addr, size uintptr) heapBits {
+	// Find arena
+	ai := arenaIndex(addr)
+	ha := mheap_.arenas[ai.l1()][ai.l2()]
+
+	// Word index in arena.
+	word := addr / goarch.PtrSize % heapArenaWords
+
+	// Word index and bit offset in bitmap array.
+	idx := word / ptrBits
+	off := word % ptrBits
+
+	// Grab relevant bits of bitmap.
+	mask := ha.bitmap[idx] >> off
+	valid := ptrBits - off
+
+	// Process depending on where the object ends.
+	nptr := size / goarch.PtrSize
+	if nptr < valid {
+		// Bits for this object end before the end of this bitmap word.
+		// Squash bits for the following objects.
+		mask &= 1<<(nptr&(ptrBits-1)) - 1
+		valid = nptr
+	} else if nptr == valid {
+		// Bits for this object end at exactly the end of this bitmap word.
+		// All good.
+	} else {
+		// Bits for this object extend into the next bitmap word. See if there
+		// may be any pointers recorded there.
+		if uintptr(ha.noMorePtrs[idx/8])>>(idx%8)&1 != 0 {
+			// No more pointers in this object after this bitmap word.
+			// Update size so we know not to look there.
+			size = valid * goarch.PtrSize
+		}
+	}
+
+	return heapBits{addr: addr, size: size, mask: mask, valid: valid}
+}
+
+// Returns the (absolute) address of the next known pointer and
+// a heapBits iterator representing any remaining pointers.
+// If there are no more pointers, returns address 0.
 // Note that next does not modify h. The caller must record the result.
 //
 // nosplit because it is used during write barriers and must not be preempted.
 //
 //go:nosplit
-func (h heapBits) next() heapBits {
-	if h.shift < 3*heapBitsShift {
-		h.shift += heapBitsShift
-	} else if h.bitp != h.last {
-		h.bitp, h.shift = add1(h.bitp), 0
+func (h heapBits) next() (heapBits, uintptr) {
+	for {
+		if h.mask != 0 {
+			var i int
+			if goarch.PtrSize == 8 {
+				i = sys.TrailingZeros64(uint64(h.mask))
+			} else {
+				i = sys.TrailingZeros32(uint32(h.mask))
+			}
+			h.mask ^= uintptr(1) << (i & (ptrBits - 1))
+			return h, h.addr + uintptr(i)*goarch.PtrSize
+		}
+
+		// Skip words that we've already processed.
+		h.addr += h.valid * goarch.PtrSize
+		h.size -= h.valid * goarch.PtrSize
+		if h.size == 0 {
+			return h, 0 // no more pointers
+		}
+
+		// Grab more bits and try again.
+		h = heapBitsForAddr(h.addr, h.size)
+	}
+}
+
+// nextFast is like next, but can return 0 even when there are more pointers
+// to be found. Callers should call next if nextFast returns 0 as its second
+// return value.
+//
+//	if addr, h = h.nextFast(); addr == 0 {
+//	    if addr, h = h.next(); addr == 0 {
+//	        ... no more pointers ...
+//	    }
+//	}
+//	... process pointer at addr ...
+//
+// nextFast is designed to be inlineable.
+//
+//go:nosplit
+func (h heapBits) nextFast() (heapBits, uintptr) {
+	// TESTQ/JEQ
+	if h.mask == 0 {
+		return h, 0
+	}
+	// BSFQ
+	var i int
+	if goarch.PtrSize == 8 {
+		i = sys.TrailingZeros64(uint64(h.mask))
 	} else {
-		// Move to the next arena.
-		return h.nextArena()
+		i = sys.TrailingZeros32(uint32(h.mask))
 	}
-	return h
-}
-
-// nextArena advances h to the beginning of the next heap arena.
-//
-// This is a slow-path helper to next. gc's inliner knows that
-// heapBits.next can be inlined even though it calls this. This is
-// marked noinline so it doesn't get inlined into next and cause next
-// to be too big to inline.
-//
-//go:nosplit
-//go:noinline
-func (h heapBits) nextArena() heapBits {
-	h.arena++
-	ai := arenaIdx(h.arena)
-	l2 := mheap_.arenas[ai.l1()]
-	if l2 == nil {
-		// We just passed the end of the object, which
-		// was also the end of the heap. Poison h. It
-		// should never be dereferenced at this point.
-		return heapBits{}
-	}
-	ha := l2[ai.l2()]
-	if ha == nil {
-		return heapBits{}
-	}
-	h.bitp, h.shift = &ha.bitmap[0], 0
-	h.last = &ha.bitmap[len(ha.bitmap)-1]
-	return h
-}
-
-// forward returns the heapBits describing n pointer-sized words ahead of h in memory.
-// That is, if h describes address p, h.forward(n) describes p+n*ptrSize.
-// h.forward(1) is equivalent to h.next(), just slower.
-// Note that forward does not modify h. The caller must record the result.
-// bits returns the heap bits for the current word.
-//
-//go:nosplit
-func (h heapBits) forward(n uintptr) heapBits {
-	n += uintptr(h.shift) / heapBitsShift
-	nbitp := uintptr(unsafe.Pointer(h.bitp)) + n/4
-	h.shift = uint32(n%4) * heapBitsShift
-	if nbitp <= uintptr(unsafe.Pointer(h.last)) {
-		h.bitp = (*uint8)(unsafe.Pointer(nbitp))
-		return h
-	}
-
-	// We're in a new heap arena.
-	past := nbitp - (uintptr(unsafe.Pointer(h.last)) + 1)
-	h.arena += 1 + uint32(past/heapArenaBitmapBytes)
-	ai := arenaIdx(h.arena)
-	if l2 := mheap_.arenas[ai.l1()]; l2 != nil && l2[ai.l2()] != nil {
-		a := l2[ai.l2()]
-		h.bitp = &a.bitmap[past%heapArenaBitmapBytes]
-		h.last = &a.bitmap[len(a.bitmap)-1]
-	} else {
-		h.bitp, h.last = nil, nil
-	}
-	return h
-}
-
-// forwardOrBoundary is like forward, but stops at boundaries between
-// contiguous sections of the bitmap. It returns the number of words
-// advanced over, which will be <= n.
-func (h heapBits) forwardOrBoundary(n uintptr) (heapBits, uintptr) {
-	maxn := 4 * ((uintptr(unsafe.Pointer(h.last)) + 1) - uintptr(unsafe.Pointer(h.bitp)))
-	if n > maxn {
-		n = maxn
-	}
-	return h.forward(n), n
-}
-
-// The caller can test morePointers and isPointer by &-ing with bitScan and bitPointer.
-// The result includes in its higher bits the bits for subsequent words
-// described by the same bitmap byte.
-//
-// nosplit because it is used during write barriers and must not be preempted.
-//
-//go:nosplit
-func (h heapBits) bits() uint32 {
-	// The (shift & 31) eliminates a test and conditional branch
-	// from the generated code.
-	return uint32(*h.bitp) >> (h.shift & 31)
-}
-
-// morePointers reports whether this word and all remaining words in this object
-// are scalars.
-// h must not describe the second word of the object.
-func (h heapBits) morePointers() bool {
-	return h.bits()&bitScan != 0
-}
-
-// isPointer reports whether the heap bits describe a pointer word.
-//
-// nosplit because it is used during write barriers and must not be preempted.
-//
-//go:nosplit
-func (h heapBits) isPointer() bool {
-	return h.bits()&bitPointer != 0
+	// BTCQ
+	h.mask ^= uintptr(1) << (i & (ptrBits - 1))
+	// LEAQ (XX)(XX*8)
+	return h, h.addr + uintptr(i)*goarch.PtrSize
 }
 
 // bulkBarrierPreWrite executes a write barrier
@@ -611,27 +565,29 @@
 	}
 
 	buf := &getg().m.p.ptr().wbBuf
-	h := heapBitsForAddr(dst)
+	h := heapBitsForAddr(dst, size)
 	if src == 0 {
-		for i := uintptr(0); i < size; i += goarch.PtrSize {
-			if h.isPointer() {
-				dstx := (*uintptr)(unsafe.Pointer(dst + i))
-				if !buf.putFast(*dstx, 0) {
-					wbBufFlush(nil, 0)
-				}
+		for {
+			var addr uintptr
+			if h, addr = h.next(); addr == 0 {
+				break
 			}
-			h = h.next()
+			dstx := (*uintptr)(unsafe.Pointer(addr))
+			if !buf.putFast(*dstx, 0) {
+				wbBufFlush(nil, 0)
+			}
 		}
 	} else {
-		for i := uintptr(0); i < size; i += goarch.PtrSize {
-			if h.isPointer() {
-				dstx := (*uintptr)(unsafe.Pointer(dst + i))
-				srcx := (*uintptr)(unsafe.Pointer(src + i))
-				if !buf.putFast(*dstx, *srcx) {
-					wbBufFlush(nil, 0)
-				}
+		for {
+			var addr uintptr
+			if h, addr = h.next(); addr == 0 {
+				break
 			}
-			h = h.next()
+			dstx := (*uintptr)(unsafe.Pointer(addr))
+			srcx := (*uintptr)(unsafe.Pointer(src + (addr - dst)))
+			if !buf.putFast(*dstx, *srcx) {
+				wbBufFlush(nil, 0)
+			}
 		}
 	}
 }
@@ -654,15 +610,16 @@
 		return
 	}
 	buf := &getg().m.p.ptr().wbBuf
-	h := heapBitsForAddr(dst)
-	for i := uintptr(0); i < size; i += goarch.PtrSize {
-		if h.isPointer() {
-			srcx := (*uintptr)(unsafe.Pointer(src + i))
-			if !buf.putFast(0, *srcx) {
-				wbBufFlush(nil, 0)
-			}
+	h := heapBitsForAddr(dst, size)
+	for {
+		var addr uintptr
+		if h, addr = h.next(); addr == 0 {
+			break
 		}
-		h = h.next()
+		srcx := (*uintptr)(unsafe.Pointer(addr - dst + src))
+		if !buf.putFast(0, *srcx) {
+			wbBufFlush(nil, 0)
+		}
 	}
 }
 
@@ -759,43 +716,31 @@
 	}
 }
 
-// The methods operating on spans all require that h has been returned
-// by heapBitsForSpan and that size, n, total are the span layout description
-// returned by the mspan's layout method.
-// If total > size*n, it means that there is extra leftover memory in the span,
-// usually due to rounding.
-//
-// TODO(rsc): Perhaps introduce a different heapBitsSpan type.
-
-// initSpan initializes the heap bitmap for a span.
-// If this is a span of pointer-sized objects, it initializes all
-// words to pointer/scan.
-// Otherwise, it initializes all words to scalar/dead.
-func (h heapBits) initSpan(s *mspan) {
-	// Clear bits corresponding to objects.
-	nw := (s.npages << _PageShift) / goarch.PtrSize
-	if nw%wordsPerBitmapByte != 0 {
-		throw("initSpan: unaligned length")
-	}
-	if h.shift != 0 {
-		throw("initSpan: unaligned base")
+// initHeapBits initializes the heap bitmap for a span.
+// If this is a span of single pointer allocations, it initializes all
+// words to pointer. If force is true, clears all bits.
+func (s *mspan) initHeapBits(forceClear bool) {
+	if forceClear || s.spanclass.noscan() {
+		// Set all the pointer bits to zero. We do this once
+		// when the span is allocated so we don't have to do it
+		// for each object allocation.
+		base := s.base()
+		size := s.npages * pageSize
+		h := writeHeapBitsForAddr(base)
+		h.flush(base, size)
+		return
 	}
 	isPtrs := goarch.PtrSize == 8 && s.elemsize == goarch.PtrSize
-	for nw > 0 {
-		hNext, anw := h.forwardOrBoundary(nw)
-		nbyte := anw / wordsPerBitmapByte
-		if isPtrs {
-			bitp := h.bitp
-			for i := uintptr(0); i < nbyte; i++ {
-				*bitp = bitPointerAll | bitScanAll
-				bitp = add1(bitp)
-			}
-		} else {
-			memclrNoHeapPointers(unsafe.Pointer(h.bitp), nbyte)
-		}
-		h = hNext
-		nw -= anw
+	if !isPtrs {
+		return // nothing to do
 	}
+	h := writeHeapBitsForAddr(s.base())
+	size := s.npages * pageSize
+	nptrs := size / goarch.PtrSize
+	for i := uintptr(0); i < nptrs; i += ptrBits {
+		h = h.write(^uintptr(0), ptrBits)
+	}
+	h.flush(s.base(), size)
 }
 
 // countAlloc returns the number of objects allocated in span s by
@@ -818,6 +763,159 @@
 	return count
 }
 
+type writeHeapBits struct {
+	addr  uintptr // address that the low bit of mask represents the pointer state of.
+	mask  uintptr // some pointer bits starting at the address addr.
+	valid uintptr // number of bits in buf that are valid (including low)
+	low   uintptr // number of low-order bits to not overwrite
+}
+
+func writeHeapBitsForAddr(addr uintptr) (h writeHeapBits) {
+	// We start writing bits maybe in the middle of a heap bitmap word.
+	// Remember how many bits into the word we started, so we can be sure
+	// not to overwrite the previous bits.
+	h.low = addr / goarch.PtrSize % ptrBits
+
+	// round down to heap word that starts the bitmap word.
+	h.addr = addr - h.low*goarch.PtrSize
+
+	// We don't have any bits yet.
+	h.mask = 0
+	h.valid = h.low
+
+	return
+}
+
+// write appends the pointerness of the next valid pointer slots
+// using the low valid bits of bits. 1=pointer, 0=scalar.
+func (h writeHeapBits) write(bits, valid uintptr) writeHeapBits {
+	if h.valid+valid <= ptrBits {
+		// Fast path - just accumulate the bits.
+		h.mask |= bits << h.valid
+		h.valid += valid
+		return h
+	}
+	// Too many bits to fit in this word. Write the current word
+	// out and move on to the next word.
+
+	data := h.mask | bits<<h.valid       // mask for this word
+	h.mask = bits >> (ptrBits - h.valid) // leftover for next word
+	h.valid += valid - ptrBits           // have h.valid+valid bits, writing ptrBits of them
+
+	// Flush mask to the memory bitmap.
+	// TODO: figure out how to cache arena lookup.
+	ai := arenaIndex(h.addr)
+	ha := mheap_.arenas[ai.l1()][ai.l2()]
+	idx := h.addr / (ptrBits * goarch.PtrSize) % heapArenaBitmapWords
+	m := uintptr(1)<<h.low - 1
+	ha.bitmap[idx] = ha.bitmap[idx]&m | data
+	// Note: no synchronization required for this write because
+	// the allocator has exclusive access to the page, and the bitmap
+	// entries are all for a single page. Also, visibility of these
+	// writes is guaranteed by the publication barrier in mallocgc.
+
+	// Clear noMorePtrs bit, since we're going to be writing bits
+	// into the following word.
+	ha.noMorePtrs[idx/8] &^= uint8(1) << (idx % 8)
+	// Note: same as above
+
+	// Move to next word of bitmap.
+	h.addr += ptrBits * goarch.PtrSize
+	h.low = 0
+	return h
+}
+
+// Add padding of size bytes.
+func (h writeHeapBits) pad(size uintptr) writeHeapBits {
+	if size == 0 {
+		return h
+	}
+	words := size / goarch.PtrSize
+	for words > ptrBits {
+		h = h.write(0, ptrBits)
+		words -= ptrBits
+	}
+	return h.write(0, words)
+}
+
+// Flush the bits that have been written, and add zeros as needed
+// to cover the full object [addr, addr+size).
+func (h writeHeapBits) flush(addr, size uintptr) {
+	// zeros counts the number of bits needed to represent the object minus the
+	// number of bits we've already written. This is the number of 0 bits
+	// that need to be added.
+	zeros := (addr+size-h.addr)/goarch.PtrSize - h.valid
+
+	// Add zero bits up to the bitmap word boundary
+	if zeros > 0 {
+		z := ptrBits - h.valid
+		if z > zeros {
+			z = zeros
+		}
+		h.valid += z
+		zeros -= z
+	}
+
+	// Find word in bitmap that we're going to write.
+	ai := arenaIndex(h.addr)
+	ha := mheap_.arenas[ai.l1()][ai.l2()]
+	idx := h.addr / (ptrBits * goarch.PtrSize) % heapArenaBitmapWords
+
+	// Write remaining bits.
+	if h.valid != h.low {
+		m := uintptr(1)<<h.low - 1      // don't clear existing bits below "low"
+		m |= ^(uintptr(1)<<h.valid - 1) // don't clear existing bits above "valid"
+		ha.bitmap[idx] = ha.bitmap[idx]&m | h.mask
+	}
+	if zeros == 0 {
+		return
+	}
+
+	// Record in the noMorePtrs map that there won't be any more 1 bits,
+	// so readers can stop early.
+	ha.noMorePtrs[idx/8] |= uint8(1) << (idx % 8)
+
+	// Advance to next bitmap word.
+	h.addr += ptrBits * goarch.PtrSize
+
+	// Continue on writing zeros for the rest of the object.
+	// For standard use of the ptr bits this is not required, as
+	// the bits are read from the beginning of the object. Some uses,
+	// like noscan spans, oblets, bulk write barriers, and cgocheck, might
+	// start mid-object, so these writes are still required.
+	for {
+		// Write zero bits.
+		ai := arenaIndex(h.addr)
+		ha := mheap_.arenas[ai.l1()][ai.l2()]
+		idx := h.addr / (ptrBits * goarch.PtrSize) % heapArenaBitmapWords
+		if zeros < ptrBits {
+			ha.bitmap[idx] &^= uintptr(1)<<zeros - 1
+			break
+		} else if zeros == ptrBits {
+			ha.bitmap[idx] = 0
+			break
+		} else {
+			ha.bitmap[idx] = 0
+			zeros -= ptrBits
+		}
+		ha.noMorePtrs[idx/8] |= uint8(1) << (idx % 8)
+		h.addr += ptrBits * goarch.PtrSize
+	}
+}
+
+// Read the bytes starting at the aligned pointer p into a uintptr.
+// Read is little-endian.
+func readUintptr(p *byte) uintptr {
+	x := *(*uintptr)(unsafe.Pointer(p))
+	if goarch.BigEndian {
+		if goarch.PtrSize == 8 {
+			return uintptr(sys.Bswap64(uint64(x)))
+		}
+		return uintptr(sys.Bswap32(uint32(x)))
+	}
+	return x
+}
+
 // heapBitsSetType records that the new allocation [x, x+size)
 // holds in [x, x+dataSize) one or more values of type typ.
 // (The number of values is given by dataSize / typ.size.)
@@ -829,7 +927,7 @@
 // heapBitsSweepSpan.
 //
 // There can only be one allocation from a given span active at a time,
-// and the bitmap for a span always falls on byte boundaries,
+// and the bitmap for a span always falls on word boundaries,
 // so there are no write-write races for access to the heap bitmap.
 // Hence, heapBitsSetType can access the bitmap without atomics.
 //
@@ -844,209 +942,61 @@
 func heapBitsSetType(x, size, dataSize uintptr, typ *_type) {
 	const doubleCheck = false // slow but helpful; enable to test modifications to this code
 
-	const (
-		mask1 = bitPointer | bitScan                        // 00010001
-		mask2 = bitPointer | bitScan | mask1<<heapBitsShift // 00110011
-		mask3 = bitPointer | bitScan | mask2<<heapBitsShift // 01110111
-	)
-
-	// dataSize is always size rounded up to the next malloc size class,
-	// except in the case of allocating a defer block, in which case
-	// size is sizeof(_defer{}) (at least 6 words) and dataSize may be
-	// arbitrarily larger.
-	//
-	// The checks for size == goarch.PtrSize and size == 2*goarch.PtrSize can therefore
-	// assume that dataSize == size without checking it explicitly.
+	if doubleCheck && dataSize%typ.size != 0 {
+		throw("heapBitsSetType: dataSize not a multiple of typ.size")
+	}
 
 	if goarch.PtrSize == 8 && size == goarch.PtrSize {
 		// It's one word and it has pointers, it must be a pointer.
 		// Since all allocated one-word objects are pointers
 		// (non-pointers are aggregated into tinySize allocations),
-		// initSpan sets the pointer bits for us. Nothing to do here.
+		// (*mspan).initHeapBits sets the pointer bits for us.
+		// Nothing to do here.
 		if doubleCheck {
-			h := heapBitsForAddr(x)
-			if !h.isPointer() {
+			h, addr := heapBitsForAddr(x, size).next()
+			if addr != x {
 				throw("heapBitsSetType: pointer bit missing")
 			}
-			if !h.morePointers() {
-				throw("heapBitsSetType: scan bit missing")
+			_, addr = h.next()
+			if addr != 0 {
+				throw("heapBitsSetType: second pointer bit found")
 			}
 		}
 		return
 	}
 
-	h := heapBitsForAddr(x)
-	ptrmask := typ.gcdata // start of 1-bit pointer mask (or GC program, handled below)
+	h := writeHeapBitsForAddr(x)
 
-	// 2-word objects only have 4 bitmap bits and 3-word objects only have 6 bitmap bits.
-	// Therefore, these objects share a heap bitmap byte with the objects next to them.
-	// These are called out as a special case primarily so the code below can assume all
-	// objects are at least 4 words long and that their bitmaps start either at the beginning
-	// of a bitmap byte, or half-way in (h.shift of 0 and 2 respectively).
-
-	if size == 2*goarch.PtrSize {
-		if typ.size == goarch.PtrSize {
-			// We're allocating a block big enough to hold two pointers.
-			// On 64-bit, that means the actual object must be two pointers,
-			// or else we'd have used the one-pointer-sized block.
-			// On 32-bit, however, this is the 8-byte block, the smallest one.
-			// So it could be that we're allocating one pointer and this was
-			// just the smallest block available. Distinguish by checking dataSize.
-			// (In general the number of instances of typ being allocated is
-			// dataSize/typ.size.)
-			if goarch.PtrSize == 4 && dataSize == goarch.PtrSize {
-				// 1 pointer object. On 32-bit machines clear the bit for the
-				// unused second word.
-				*h.bitp &^= (bitPointer | bitScan | (bitPointer|bitScan)<<heapBitsShift) << h.shift
-				*h.bitp |= (bitPointer | bitScan) << h.shift
-			} else {
-				// 2-element array of pointer.
-				*h.bitp |= (bitPointer | bitScan | (bitPointer|bitScan)<<heapBitsShift) << h.shift
-			}
-			return
-		}
-		// Otherwise typ.size must be 2*goarch.PtrSize,
-		// and typ.kind&kindGCProg == 0.
-		if doubleCheck {
-			if typ.size != 2*goarch.PtrSize || typ.kind&kindGCProg != 0 {
-				print("runtime: heapBitsSetType size=", size, " but typ.size=", typ.size, " gcprog=", typ.kind&kindGCProg != 0, "\n")
-				throw("heapBitsSetType")
-			}
-		}
-		b := uint32(*ptrmask)
-		hb := b & 3
-		hb |= bitScanAll & ((bitScan << (typ.ptrdata / goarch.PtrSize)) - 1)
-		// Clear the bits for this object so we can set the
-		// appropriate ones.
-		*h.bitp &^= (bitPointer | bitScan | ((bitPointer | bitScan) << heapBitsShift)) << h.shift
-		*h.bitp |= uint8(hb << h.shift)
-		return
-	} else if size == 3*goarch.PtrSize {
-		b := uint8(*ptrmask)
-		if doubleCheck {
-			if b == 0 {
-				println("runtime: invalid type ", typ.string())
-				throw("heapBitsSetType: called with non-pointer type")
-			}
-			if goarch.PtrSize != 8 {
-				throw("heapBitsSetType: unexpected 3 pointer wide size class on 32 bit")
-			}
-			if typ.kind&kindGCProg != 0 {
-				throw("heapBitsSetType: unexpected GC prog for 3 pointer wide size class")
-			}
-			if typ.size == 2*goarch.PtrSize {
-				print("runtime: heapBitsSetType size=", size, " but typ.size=", typ.size, "\n")
-				throw("heapBitsSetType: inconsistent object sizes")
-			}
-		}
-		if typ.size == goarch.PtrSize {
-			// The type contains a pointer otherwise heapBitsSetType wouldn't have been called.
-			// Since the type is only 1 pointer wide and contains a pointer, its gcdata must be exactly 1.
-			if doubleCheck && *typ.gcdata != 1 {
-				print("runtime: heapBitsSetType size=", size, " typ.size=", typ.size, "but *typ.gcdata", *typ.gcdata, "\n")
-				throw("heapBitsSetType: unexpected gcdata for 1 pointer wide type size in 3 pointer wide size class")
-			}
-			// 3 element array of pointers. Unrolling ptrmask 3 times into p yields 00000111.
-			b = 7
-		}
-
-		hb := b & 7
-		// Set bitScan bits for all pointers.
-		hb |= hb << wordsPerBitmapByte
-		// First bitScan bit is always set since the type contains pointers.
-		hb |= bitScan
-		// Second bitScan bit needs to also be set if the third bitScan bit is set.
-		hb |= hb & (bitScan << (2 * heapBitsShift)) >> 1
-
-		// For h.shift > 1 heap bits cross a byte boundary and need to be written part
-		// to h.bitp and part to the next h.bitp.
-		switch h.shift {
-		case 0:
-			*h.bitp &^= mask3 << 0
-			*h.bitp |= hb << 0
-		case 1:
-			*h.bitp &^= mask3 << 1
-			*h.bitp |= hb << 1
-		case 2:
-			*h.bitp &^= mask2 << 2
-			*h.bitp |= (hb & mask2) << 2
-			// Two words written to the first byte.
-			// Advance two words to get to the next byte.
-			h = h.next().next()
-			*h.bitp &^= mask1
-			*h.bitp |= (hb >> 2) & mask1
-		case 3:
-			*h.bitp &^= mask1 << 3
-			*h.bitp |= (hb & mask1) << 3
-			// One word written to the first byte.
-			// Advance one word to get to the next byte.
-			h = h.next()
-			*h.bitp &^= mask2
-			*h.bitp |= (hb >> 1) & mask2
-		}
-		return
-	}
-
-	// Copy from 1-bit ptrmask into 2-bit bitmap.
-	// The basic approach is to use a single uintptr as a bit buffer,
-	// alternating between reloading the buffer and writing bitmap bytes.
-	// In general, one load can supply two bitmap byte writes.
-	// This is a lot of lines of code, but it compiles into relatively few
-	// machine instructions.
-
-	outOfPlace := false
-	if arenaIndex(x+size-1) != arenaIdx(h.arena) || (doubleCheck && fastrandn(2) == 0) {
-		// This object spans heap arenas, so the bitmap may be
-		// discontiguous. Unroll it into the object instead
-		// and then copy it out.
-		//
-		// In doubleCheck mode, we randomly do this anyway to
-		// stress test the bitmap copying path.
-		outOfPlace = true
-		h.bitp = (*uint8)(unsafe.Pointer(x))
-		h.last = nil
-	}
-
-	var (
-		// Ptrmask input.
-		p     *byte   // last ptrmask byte read
-		b     uintptr // ptrmask bits already loaded
-		nb    uintptr // number of bits in b at next read
-		endp  *byte   // final ptrmask byte to read (then repeat)
-		endnb uintptr // number of valid bits in *endp
-		pbits uintptr // alternate source of bits
-
-		// Heap bitmap output.
-		w     uintptr // words processed
-		nw    uintptr // number of words to process
-		hbitp *byte   // next heap bitmap byte to write
-		hb    uintptr // bits being prepared for *hbitp
-	)
-
-	hbitp = h.bitp
-
-	// Handle GC program. Delayed until this part of the code
-	// so that we can use the same double-checking mechanism
-	// as the 1-bit case. Nothing above could have encountered
-	// GC programs: the cases were all too small.
+	// Handle GC program.
 	if typ.kind&kindGCProg != 0 {
-		heapBitsSetTypeGCProg(h, typ.ptrdata, typ.size, dataSize, size, addb(typ.gcdata, 4))
-		if doubleCheck {
-			// Double-check the heap bits written by GC program
-			// by running the GC program to create a 1-bit pointer mask
-			// and then jumping to the double-check code below.
-			// This doesn't catch bugs shared between the 1-bit and 4-bit
-			// GC program execution, but it does catch mistakes specific
-			// to just one of those and bugs in heapBitsSetTypeGCProg's
-			// implementation of arrays.
-			lock(&debugPtrmask.lock)
-			if debugPtrmask.data == nil {
-				debugPtrmask.data = (*byte)(persistentalloc(1<<20, 1, &memstats.other_sys))
+		// Expand the gc program into the storage we're going to use for the actual object.
+		obj := (*uint8)(unsafe.Pointer(x))
+		n := runGCProg(addb(typ.gcdata, 4), obj)
+		// Use the expanded program to set the heap bits.
+		for i := uintptr(0); true; i += typ.size {
+			// Copy expanded program to heap bitmap.
+			p := obj
+			j := n
+			for j > 8 {
+				h = h.write(uintptr(*p), 8)
+				p = add1(p)
+				j -= 8
 			}
-			ptrmask = debugPtrmask.data
-			runGCProg(addb(typ.gcdata, 4), nil, ptrmask, 1)
+			h = h.write(uintptr(*p), j)
+
+			if i+typ.size == dataSize {
+				break // no padding after last element
+			}
+
+			// Pad with zeros to the start of the next element.
+			h = h.pad(typ.size - n*goarch.PtrSize)
 		}
-		goto Phase4
+
+		h.flush(x, size)
+
+		// Erase the expanded GC program.
+		memclrNoHeapPointers(unsafe.Pointer(obj), (n+7)/8)
+		return
 	}
 
 	// Note about sizes:
@@ -1061,424 +1011,98 @@
 	// to scan the buffer's heap bitmap at all.
 	// The 1-bit ptrmasks are sized to contain only bits for
 	// the typ.ptrdata prefix, zero padded out to a full byte
-	// of bitmap. This code sets nw (below) so that heap bitmap
-	// bits are only written for the typ.ptrdata prefix; if there is
-	// more room in the allocated object, the next heap bitmap
-	// entry is a 00, indicating that there are no more pointers
-	// to scan. So only the ptrmask for the ptrdata bytes is needed.
+	// of bitmap. If there is more room in the allocated object,
+	// that space is pointerless. The noMorePtrs bitmap will prevent
+	// scanning large pointerless tails of an object.
 	//
 	// Replicated copies are not as nice: if there is an array of
 	// objects with scalar tails, all but the last tail does have to
 	// be initialized, because there is no way to say "skip forward".
-	// However, because of the possibility of a repeated type with
-	// size not a multiple of 4 pointers (one heap bitmap byte),
-	// the code already must handle the last ptrmask byte specially
-	// by treating it as containing only the bits for endnb pointers,
-	// where endnb <= 4. We represent large scalar tails that must
-	// be expanded in the replication by setting endnb larger than 4.
-	// This will have the effect of reading many bits out of b,
-	// but once the real bits are shifted out, b will supply as many
-	// zero bits as we try to read, which is exactly what we need.
 
-	p = ptrmask
-	if typ.size < dataSize {
-		// Filling in bits for an array of typ.
-		// Set up for repetition of ptrmask during main loop.
-		// Note that ptrmask describes only a prefix of
-		const maxBits = goarch.PtrSize*8 - 7
-		if typ.ptrdata/goarch.PtrSize <= maxBits {
-			// Entire ptrmask fits in uintptr with room for a byte fragment.
-			// Load into pbits and never read from ptrmask again.
-			// This is especially important when the ptrmask has
-			// fewer than 8 bits in it; otherwise the reload in the middle
-			// of the Phase 2 loop would itself need to loop to gather
-			// at least 8 bits.
-
-			// Accumulate ptrmask into b.
-			// ptrmask is sized to describe only typ.ptrdata, but we record
-			// it as describing typ.size bytes, since all the high bits are zero.
-			nb = typ.ptrdata / goarch.PtrSize
-			for i := uintptr(0); i < nb; i += 8 {
-				b |= uintptr(*p) << i
-				p = add1(p)
-			}
-			nb = typ.size / goarch.PtrSize
-
-			// Replicate ptrmask to fill entire pbits uintptr.
-			// Doubling and truncating is fewer steps than
-			// iterating by nb each time. (nb could be 1.)
-			// Since we loaded typ.ptrdata/goarch.PtrSize bits
-			// but are pretending to have typ.size/goarch.PtrSize,
-			// there might be no replication necessary/possible.
-			pbits = b
-			endnb = nb
-			if nb+nb <= maxBits {
-				for endnb <= goarch.PtrSize*8 {
-					pbits |= pbits << endnb
-					endnb += endnb
+	ptrs := typ.ptrdata / goarch.PtrSize
+	if typ.size == dataSize { // Single element
+		if ptrs <= ptrBits { // Single small element
+			m := readUintptr(typ.gcdata)
+			h = h.write(m, ptrs)
+		} else { // Single large element
+			p := typ.gcdata
+			for {
+				h = h.write(readUintptr(p), ptrBits)
+				p = addb(p, ptrBits/8)
+				ptrs -= ptrBits
+				if ptrs <= ptrBits {
+					break
 				}
-				// Truncate to a multiple of original ptrmask.
-				// Because nb+nb <= maxBits, nb fits in a byte.
-				// Byte division is cheaper than uintptr division.
-				endnb = uintptr(maxBits/byte(nb)) * nb
-				pbits &= 1<<endnb - 1
-				b = pbits
-				nb = endnb
 			}
-
-			// Clear p and endp as sentinel for using pbits.
-			// Checked during Phase 2 loop.
-			p = nil
-			endp = nil
-		} else {
-			// Ptrmask is larger. Read it multiple times.
-			n := (typ.ptrdata/goarch.PtrSize+7)/8 - 1
-			endp = addb(ptrmask, n)
-			endnb = typ.size/goarch.PtrSize - n*8
+			m := readUintptr(p)
+			h = h.write(m, ptrs)
 		}
-	}
-	if p != nil {
-		b = uintptr(*p)
-		p = add1(p)
-		nb = 8
-	}
-
-	if typ.size == dataSize {
-		// Single entry: can stop once we reach the non-pointer data.
-		nw = typ.ptrdata / goarch.PtrSize
-	} else {
-		// Repeated instances of typ in an array.
-		// Have to process first N-1 entries in full, but can stop
-		// once we reach the non-pointer data in the final entry.
-		nw = ((dataSize/typ.size-1)*typ.size + typ.ptrdata) / goarch.PtrSize
-	}
-	if nw == 0 {
-		// No pointers! Caller was supposed to check.
-		println("runtime: invalid type ", typ.string())
-		throw("heapBitsSetType: called with non-pointer type")
-		return
-	}
-
-	// Phase 1: Special case for leading byte (shift==0) or half-byte (shift==2).
-	// The leading byte is special because it contains the bits for word 1,
-	// which does not have the scan bit set.
-	// The leading half-byte is special because it's a half a byte,
-	// so we have to be careful with the bits already there.
-	switch {
-	default:
-		throw("heapBitsSetType: unexpected shift")
-
-	case h.shift == 0:
-		// Ptrmask and heap bitmap are aligned.
-		//
-		// This is a fast path for small objects.
-		//
-		// The first byte we write out covers the first four
-		// words of the object. The scan/dead bit on the first
-		// word must be set to scan since there are pointers
-		// somewhere in the object.
-		// In all following words, we set the scan/dead
-		// appropriately to indicate that the object continues
-		// to the next 2-bit entry in the bitmap.
-		//
-		// We set four bits at a time here, but if the object
-		// is fewer than four words, phase 3 will clear
-		// unnecessary bits.
-		hb = b & bitPointerAll
-		hb |= bitScanAll
-		if w += 4; w >= nw {
-			goto Phase3
-		}
-		*hbitp = uint8(hb)
-		hbitp = add1(hbitp)
-		b >>= 4
-		nb -= 4
-
-	case h.shift == 2:
-		// Ptrmask and heap bitmap are misaligned.
-		//
-		// On 32 bit architectures only the 6-word object that corresponds
-		// to a 24 bytes size class can start with h.shift of 2 here since
-		// all other non 16 byte aligned size classes have been handled by
-		// special code paths at the beginning of heapBitsSetType on 32 bit.
-		//
-		// Many size classes are only 16 byte aligned. On 64 bit architectures
-		// this results in a heap bitmap position starting with a h.shift of 2.
-		//
-		// The bits for the first two words are in a byte shared
-		// with another object, so we must be careful with the bits
-		// already there.
-		//
-		// We took care of 1-word, 2-word, and 3-word objects above,
-		// so this is at least a 6-word object.
-		hb = (b & (bitPointer | bitPointer<<heapBitsShift)) << (2 * heapBitsShift)
-		hb |= bitScan << (2 * heapBitsShift)
-		if nw > 1 {
-			hb |= bitScan << (3 * heapBitsShift)
-		}
-		b >>= 2
-		nb -= 2
-		*hbitp &^= uint8((bitPointer | bitScan | ((bitPointer | bitScan) << heapBitsShift)) << (2 * heapBitsShift))
-		*hbitp |= uint8(hb)
-		hbitp = add1(hbitp)
-		if w += 2; w >= nw {
-			// We know that there is more data, because we handled 2-word and 3-word objects above.
-			// This must be at least a 6-word object. If we're out of pointer words,
-			// mark no scan in next bitmap byte and finish.
-			hb = 0
-			w += 4
-			goto Phase3
-		}
-	}
-
-	// Phase 2: Full bytes in bitmap, up to but not including write to last byte (full or partial) in bitmap.
-	// The loop computes the bits for that last write but does not execute the write;
-	// it leaves the bits in hb for processing by phase 3.
-	// To avoid repeated adjustment of nb, we subtract out the 4 bits we're going to
-	// use in the first half of the loop right now, and then we only adjust nb explicitly
-	// if the 8 bits used by each iteration isn't balanced by 8 bits loaded mid-loop.
-	nb -= 4
-	for {
-		// Emit bitmap byte.
-		// b has at least nb+4 bits, with one exception:
-		// if w+4 >= nw, then b has only nw-w bits,
-		// but we'll stop at the break and then truncate
-		// appropriately in Phase 3.
-		hb = b & bitPointerAll
-		hb |= bitScanAll
-		if w += 4; w >= nw {
-			break
-		}
-		*hbitp = uint8(hb)
-		hbitp = add1(hbitp)
-		b >>= 4
-
-		// Load more bits. b has nb right now.
-		if p != endp {
-			// Fast path: keep reading from ptrmask.
-			// nb unmodified: we just loaded 8 bits,
-			// and the next iteration will consume 8 bits,
-			// leaving us with the same nb the next time we're here.
-			if nb < 8 {
-				b |= uintptr(*p) << nb
-				p = add1(p)
-			} else {
-				// Reduce the number of bits in b.
-				// This is important if we skipped
-				// over a scalar tail, since nb could
-				// be larger than the bit width of b.
-				nb -= 8
+	} else { // Repeated element
+		words := typ.size / goarch.PtrSize // total words, including scalar tail
+		if words <= ptrBits {              // Repeated small element
+			n := dataSize / typ.size
+			m := readUintptr(typ.gcdata)
+			// Make larger unit to repeat
+			for words <= ptrBits/2 {
+				if n&1 != 0 {
+					h = h.write(m, words)
+				}
+				n /= 2
+				m |= m << words
+				ptrs += words
+				words *= 2
+				if n == 1 {
+					break
+				}
 			}
-		} else if p == nil {
-			// Almost as fast path: track bit count and refill from pbits.
-			// For short repetitions.
-			if nb < 8 {
-				b |= pbits << nb
-				nb += endnb
+			for n > 1 {
+				h = h.write(m, words)
+				n--
 			}
-			nb -= 8 // for next iteration
-		} else {
-			// Slow path: reached end of ptrmask.
-			// Process final partial byte and rewind to start.
-			b |= uintptr(*p) << nb
-			nb += endnb
-			if nb < 8 {
-				b |= uintptr(*ptrmask) << nb
-				p = add1(ptrmask)
-			} else {
-				nb -= 8
-				p = ptrmask
+			h = h.write(m, ptrs)
+		} else { // Repeated large element
+			for i := uintptr(0); true; i += typ.size {
+				p := typ.gcdata
+				j := ptrs
+				for j > ptrBits {
+					h = h.write(readUintptr(p), ptrBits)
+					p = addb(p, ptrBits/8)
+					j -= ptrBits
+				}
+				m := readUintptr(p)
+				h = h.write(m, j)
+				if i+typ.size == dataSize {
+					break // don't need the trailing nonptr bits on the last element.
+				}
+				// Pad with zeros to the start of the next element.
+				h = h.pad(typ.size - typ.ptrdata)
 			}
 		}
-
-		// Emit bitmap byte.
-		hb = b & bitPointerAll
-		hb |= bitScanAll
-		if w += 4; w >= nw {
-			break
-		}
-		*hbitp = uint8(hb)
-		hbitp = add1(hbitp)
-		b >>= 4
 	}
+	h.flush(x, size)
 
-Phase3:
-	// Phase 3: Write last byte or partial byte and zero the rest of the bitmap entries.
-	if w > nw {
-		// Counting the 4 entries in hb not yet written to memory,
-		// there are more entries than possible pointer slots.
-		// Discard the excess entries (can't be more than 3).
-		mask := uintptr(1)<<(4-(w-nw)) - 1
-		hb &= mask | mask<<4 // apply mask to both pointer bits and scan bits
-	}
-
-	// Change nw from counting possibly-pointer words to total words in allocation.
-	nw = size / goarch.PtrSize
-
-	// Write whole bitmap bytes.
-	// The first is hb, the rest are zero.
-	if w <= nw {
-		*hbitp = uint8(hb)
-		hbitp = add1(hbitp)
-		hb = 0 // for possible final half-byte below
-		for w += 4; w <= nw; w += 4 {
-			*hbitp = 0
-			hbitp = add1(hbitp)
-		}
-	}
-
-	// Write final partial bitmap byte if any.
-	// We know w > nw, or else we'd still be in the loop above.
-	// It can be bigger only due to the 4 entries in hb that it counts.
-	// If w == nw+4 then there's nothing left to do: we wrote all nw entries
-	// and can discard the 4 sitting in hb.
-	// But if w == nw+2, we need to write first two in hb.
-	// The byte is shared with the next object, so be careful with
-	// existing bits.
-	if w == nw+2 {
-		*hbitp = *hbitp&^(bitPointer|bitScan|(bitPointer|bitScan)<<heapBitsShift) | uint8(hb)
-	}
-
-Phase4:
-	// Phase 4: Copy unrolled bitmap to per-arena bitmaps, if necessary.
-	if outOfPlace {
-		// TODO: We could probably make this faster by
-		// handling [x+dataSize, x+size) specially.
-		h := heapBitsForAddr(x)
-		// cnw is the number of heap words, or bit pairs
-		// remaining (like nw above).
-		cnw := size / goarch.PtrSize
-		src := (*uint8)(unsafe.Pointer(x))
-		// We know the first and last byte of the bitmap are
-		// not the same, but it's still possible for small
-		// objects span arenas, so it may share bitmap bytes
-		// with neighboring objects.
-		//
-		// Handle the first byte specially if it's shared. See
-		// Phase 1 for why this is the only special case we need.
-		if doubleCheck {
-			if !(h.shift == 0 || h.shift == 2) {
-				print("x=", x, " size=", size, " cnw=", h.shift, "\n")
-				throw("bad start shift")
-			}
-		}
-		if h.shift == 2 {
-			*h.bitp = *h.bitp&^((bitPointer|bitScan|(bitPointer|bitScan)<<heapBitsShift)<<(2*heapBitsShift)) | *src
-			h = h.next().next()
-			cnw -= 2
-			src = addb(src, 1)
-		}
-		// We're now byte aligned. Copy out to per-arena
-		// bitmaps until the last byte (which may again be
-		// partial).
-		for cnw >= 4 {
-			// This loop processes four words at a time,
-			// so round cnw down accordingly.
-			hNext, words := h.forwardOrBoundary(cnw / 4 * 4)
-
-			// n is the number of bitmap bytes to copy.
-			n := words / 4
-			memmove(unsafe.Pointer(h.bitp), unsafe.Pointer(src), n)
-			cnw -= words
-			h = hNext
-			src = addb(src, n)
-		}
-		if doubleCheck && h.shift != 0 {
-			print("cnw=", cnw, " h.shift=", h.shift, "\n")
-			throw("bad shift after block copy")
-		}
-		// Handle the last byte if it's shared.
-		if cnw == 2 {
-			*h.bitp = *h.bitp&^(bitPointer|bitScan|(bitPointer|bitScan)<<heapBitsShift) | *src
-			src = addb(src, 1)
-			h = h.next().next()
-		}
-		if doubleCheck {
-			if uintptr(unsafe.Pointer(src)) > x+size {
-				throw("copy exceeded object size")
-			}
-			if !(cnw == 0 || cnw == 2) {
-				print("x=", x, " size=", size, " cnw=", cnw, "\n")
-				throw("bad number of remaining words")
-			}
-			// Set up hbitp so doubleCheck code below can check it.
-			hbitp = h.bitp
-		}
-		// Zero the object where we wrote the bitmap.
-		memclrNoHeapPointers(unsafe.Pointer(x), uintptr(unsafe.Pointer(src))-x)
-	}
-
-	// Double check the whole bitmap.
 	if doubleCheck {
-		// x+size may not point to the heap, so back up one
-		// word and then advance it the way we do above.
-		end := heapBitsForAddr(x + size - goarch.PtrSize)
-		if outOfPlace {
-			// In out-of-place copying, we just advance
-			// using next.
-			end = end.next()
-		} else {
-			// Don't use next because that may advance to
-			// the next arena and the in-place logic
-			// doesn't do that.
-			end.shift += heapBitsShift
-			if end.shift == 4*heapBitsShift {
-				end.bitp, end.shift = add1(end.bitp), 0
+		h := heapBitsForAddr(x, size)
+		for i := uintptr(0); i < size; i += goarch.PtrSize {
+			// Compute the pointer bit we want at offset i.
+			want := false
+			if i < dataSize {
+				off := i % typ.size
+				if off < typ.ptrdata {
+					j := off / goarch.PtrSize
+					want = *addb(typ.gcdata, j/8)>>(j%8)&1 != 0
+				}
+			}
+			if want {
+				var addr uintptr
+				h, addr = h.next()
+				if addr != x+i {
+					throw("heapBitsSetType: pointer entry not correct")
+				}
 			}
 		}
-		if typ.kind&kindGCProg == 0 && (hbitp != end.bitp || (w == nw+2) != (end.shift == 2)) {
-			println("ended at wrong bitmap byte for", typ.string(), "x", dataSize/typ.size)
-			print("typ.size=", typ.size, " typ.ptrdata=", typ.ptrdata, " dataSize=", dataSize, " size=", size, "\n")
-			print("w=", w, " nw=", nw, " b=", hex(b), " nb=", nb, " hb=", hex(hb), "\n")
-			h0 := heapBitsForAddr(x)
-			print("initial bits h0.bitp=", h0.bitp, " h0.shift=", h0.shift, "\n")
-			print("ended at hbitp=", hbitp, " but next starts at bitp=", end.bitp, " shift=", end.shift, "\n")
-			throw("bad heapBitsSetType")
-		}
-
-		// Double-check that bits to be written were written correctly.
-		// Does not check that other bits were not written, unfortunately.
-		h := heapBitsForAddr(x)
-		nptr := typ.ptrdata / goarch.PtrSize
-		ndata := typ.size / goarch.PtrSize
-		count := dataSize / typ.size
-		totalptr := ((count-1)*typ.size + typ.ptrdata) / goarch.PtrSize
-		for i := uintptr(0); i < size/goarch.PtrSize; i++ {
-			j := i % ndata
-			var have, want uint8
-			have = (*h.bitp >> h.shift) & (bitPointer | bitScan)
-			if i >= totalptr {
-				if typ.kind&kindGCProg != 0 && i < (totalptr+3)/4*4 {
-					// heapBitsSetTypeGCProg always fills
-					// in full nibbles of bitScan.
-					want = bitScan
-				}
-			} else {
-				if j < nptr && (*addb(ptrmask, j/8)>>(j%8))&1 != 0 {
-					want |= bitPointer
-				}
-				want |= bitScan
-			}
-			if have != want {
-				println("mismatch writing bits for", typ.string(), "x", dataSize/typ.size)
-				print("typ.size=", typ.size, " typ.ptrdata=", typ.ptrdata, " dataSize=", dataSize, " size=", size, "\n")
-				print("kindGCProg=", typ.kind&kindGCProg != 0, " outOfPlace=", outOfPlace, "\n")
-				print("w=", w, " nw=", nw, " b=", hex(b), " nb=", nb, " hb=", hex(hb), "\n")
-				h0 := heapBitsForAddr(x)
-				print("initial bits h0.bitp=", h0.bitp, " h0.shift=", h0.shift, "\n")
-				print("current bits h.bitp=", h.bitp, " h.shift=", h.shift, " *h.bitp=", hex(*h.bitp), "\n")
-				print("ptrmask=", ptrmask, " p=", p, " endp=", endp, " endnb=", endnb, " pbits=", hex(pbits), " b=", hex(b), " nb=", nb, "\n")
-				println("at word", i, "offset", i*goarch.PtrSize, "have", hex(have), "want", hex(want))
-				if typ.kind&kindGCProg != 0 {
-					println("GC program:")
-					dumpGCProg(addb(typ.gcdata, 4))
-				}
-				throw("bad heapBitsSetType")
-			}
-			h = h.next()
-		}
-		if ptrmask == debugPtrmask.data {
-			unlock(&debugPtrmask.lock)
+		if _, addr := h.next(); addr != 0 {
+			throw("heapBitsSetType: extra pointer")
 		}
 	}
 }
@@ -1488,92 +1112,6 @@
 	data *byte
 }
 
-// heapBitsSetTypeGCProg implements heapBitsSetType using a GC program.
-// progSize is the size of the memory described by the program.
-// elemSize is the size of the element that the GC program describes (a prefix of).
-// dataSize is the total size of the intended data, a multiple of elemSize.
-// allocSize is the total size of the allocated memory.
-//
-// GC programs are only used for large allocations.
-// heapBitsSetType requires that allocSize is a multiple of 4 words,
-// so that the relevant bitmap bytes are not shared with surrounding
-// objects.
-func heapBitsSetTypeGCProg(h heapBits, progSize, elemSize, dataSize, allocSize uintptr, prog *byte) {
-	if goarch.PtrSize == 8 && allocSize%(4*goarch.PtrSize) != 0 {
-		// Alignment will be wrong.
-		throw("heapBitsSetTypeGCProg: small allocation")
-	}
-	var totalBits uintptr
-	if elemSize == dataSize {
-		totalBits = runGCProg(prog, nil, h.bitp, 2)
-		if totalBits*goarch.PtrSize != progSize {
-			println("runtime: heapBitsSetTypeGCProg: total bits", totalBits, "but progSize", progSize)
-			throw("heapBitsSetTypeGCProg: unexpected bit count")
-		}
-	} else {
-		count := dataSize / elemSize
-
-		// Piece together program trailer to run after prog that does:
-		//	literal(0)
-		//	repeat(1, elemSize-progSize-1) // zeros to fill element size
-		//	repeat(elemSize, count-1) // repeat that element for count
-		// This zero-pads the data remaining in the first element and then
-		// repeats that first element to fill the array.
-		var trailer [40]byte // 3 varints (max 10 each) + some bytes
-		i := 0
-		if n := elemSize/goarch.PtrSize - progSize/goarch.PtrSize; n > 0 {
-			// literal(0)
-			trailer[i] = 0x01
-			i++
-			trailer[i] = 0
-			i++
-			if n > 1 {
-				// repeat(1, n-1)
-				trailer[i] = 0x81
-				i++
-				n--
-				for ; n >= 0x80; n >>= 7 {
-					trailer[i] = byte(n | 0x80)
-					i++
-				}
-				trailer[i] = byte(n)
-				i++
-			}
-		}
-		// repeat(elemSize/ptrSize, count-1)
-		trailer[i] = 0x80
-		i++
-		n := elemSize / goarch.PtrSize
-		for ; n >= 0x80; n >>= 7 {
-			trailer[i] = byte(n | 0x80)
-			i++
-		}
-		trailer[i] = byte(n)
-		i++
-		n = count - 1
-		for ; n >= 0x80; n >>= 7 {
-			trailer[i] = byte(n | 0x80)
-			i++
-		}
-		trailer[i] = byte(n)
-		i++
-		trailer[i] = 0
-		i++
-
-		runGCProg(prog, &trailer[0], h.bitp, 2)
-
-		// Even though we filled in the full array just now,
-		// record that we only filled in up to the ptrdata of the
-		// last element. This will cause the code below to
-		// memclr the dead section of the final array element,
-		// so that scanobject can stop early in the final element.
-		totalBits = (elemSize*(count-1) + progSize) / goarch.PtrSize
-	}
-	endProg := unsafe.Pointer(addb(h.bitp, (totalBits+3)/4))
-	endAlloc := unsafe.Pointer(addb(h.bitp, allocSize/goarch.PtrSize/wordsPerBitmapByte))
-	memclrNoHeapPointers(endProg, uintptr(endAlloc)-uintptr(endProg))
-}
-
 // progToPointerMask returns the 1-bit pointer mask output by the GC program prog.
 // size the size of the region described by prog, in bytes.
 // The resulting bitvector will have no more than size/goarch.PtrSize bits.
@@ -1581,7 +1119,7 @@
 	n := (size/goarch.PtrSize + 7) / 8
 	x := (*[1 << 30]byte)(persistentalloc(n+1, 1, &memstats.buckhash_sys))[:n+1]
 	x[len(x)-1] = 0xa1 // overflow check sentinel
-	n = runGCProg(prog, nil, &x[0], 1)
+	n = runGCProg(prog, &x[0])
 	if x[len(x)-1] != 0xa1 {
 		throw("progToPointerMask: overflow")
 	}
@@ -1602,15 +1140,8 @@
 //	10000000 n c: repeat the previous n bits c times; n, c are varints
 //	1nnnnnnn c: repeat the previous n bits c times; c is a varint
 
-// runGCProg executes the GC program prog, and then trailer if non-nil,
-// writing to dst with entries of the given size.
-// If size == 1, dst is a 1-bit pointer mask laid out moving forward from dst.
-// If size == 2, dst is the 2-bit heap bitmap, and writes move backward
-// starting at dst (because the heap bitmap does). In this case, the caller guarantees
-// that only whole bytes in dst need to be written.
-//
-// runGCProg returns the number of 1- or 2-bit entries written to memory.
-func runGCProg(prog, trailer, dst *byte, size int) uintptr {
+// runGCProg returns the number of 1-bit entries written to memory.
+func runGCProg(prog, dst *byte) uintptr {
 	dstStart := dst
 
 	// Bits waiting to be written to memory.
@@ -1623,20 +1154,9 @@
 		// Flush accumulated full bytes.
 		// The rest of the loop assumes that nbits <= 7.
 		for ; nbits >= 8; nbits -= 8 {
-			if size == 1 {
-				*dst = uint8(bits)
-				dst = add1(dst)
-				bits >>= 8
-			} else {
-				v := bits&bitPointerAll | bitScanAll
-				*dst = uint8(v)
-				dst = add1(dst)
-				bits >>= 4
-				v = bits&bitPointerAll | bitScanAll
-				*dst = uint8(v)
-				dst = add1(dst)
-				bits >>= 4
-			}
+			*dst = uint8(bits)
+			dst = add1(dst)
+			bits >>= 8
 		}
 
 		// Process one instruction.
@@ -1646,32 +1166,16 @@
 		if inst&0x80 == 0 {
 			// Literal bits; n == 0 means end of program.
 			if n == 0 {
-				// Program is over; continue in trailer if present.
-				if trailer != nil {
-					p = trailer
-					trailer = nil
-					continue
-				}
+				// Program is over.
 				break Run
 			}
 			nbyte := n / 8
 			for i := uintptr(0); i < nbyte; i++ {
 				bits |= uintptr(*p) << nbits
 				p = add1(p)
-				if size == 1 {
-					*dst = uint8(bits)
-					dst = add1(dst)
-					bits >>= 8
-				} else {
-					v := bits&0xf | bitScanAll
-					*dst = uint8(v)
-					dst = add1(dst)
-					bits >>= 4
-					v = bits&0xf | bitScanAll
-					*dst = uint8(v)
-					dst = add1(dst)
-					bits >>= 4
-				}
+				*dst = uint8(bits)
+				dst = add1(dst)
+				bits >>= 8
 			}
 			if n %= 8; n > 0 {
 				bits |= uintptr(*p) << nbits
@@ -1720,22 +1224,12 @@
 			npattern := nbits
 
 			// If we need more bits, fetch them from memory.
-			if size == 1 {
+			src = subtract1(src)
+			for npattern < n {
+				pattern <<= 8
+				pattern |= uintptr(*src)
 				src = subtract1(src)
-				for npattern < n {
-					pattern <<= 8
-					pattern |= uintptr(*src)
-					src = subtract1(src)
-					npattern += 8
-				}
-			} else {
-				src = subtract1(src)
-				for npattern < n {
-					pattern <<= 4
-					pattern |= uintptr(*src) & 0xf
-					src = subtract1(src)
-					npattern += 4
-				}
+				npattern += 8
 			}
 
 			// We started with the whole bit output buffer,
@@ -1785,20 +1279,11 @@
 			for ; c >= npattern; c -= npattern {
 				bits |= pattern << nbits
 				nbits += npattern
-				if size == 1 {
-					for nbits >= 8 {
-						*dst = uint8(bits)
-						dst = add1(dst)
-						bits >>= 8
-						nbits -= 8
-					}
-				} else {
-					for nbits >= 4 {
-						*dst = uint8(bits&0xf | bitScanAll)
-						dst = add1(dst)
-						bits >>= 4
-						nbits -= 4
-					}
+				for nbits >= 8 {
+					*dst = uint8(bits)
+					dst = add1(dst)
+					bits >>= 8
+					nbits -= 8
 				}
 			}
 
@@ -1815,75 +1300,38 @@
 		// Since nbits <= 7, we know the first few bytes of repeated data
 		// are already written to memory.
 		off := n - nbits // n > nbits because n > maxBits and nbits <= 7
-		if size == 1 {
-			// Leading src fragment.
-			src = subtractb(src, (off+7)/8)
-			if frag := off & 7; frag != 0 {
-				bits |= uintptr(*src) >> (8 - frag) << nbits
-				src = add1(src)
-				nbits += frag
-				c -= frag
-			}
-			// Main loop: load one byte, write another.
-			// The bits are rotating through the bit buffer.
-			for i := c / 8; i > 0; i-- {
-				bits |= uintptr(*src) << nbits
-				src = add1(src)
-				*dst = uint8(bits)
-				dst = add1(dst)
-				bits >>= 8
-			}
-			// Final src fragment.
-			if c %= 8; c > 0 {
-				bits |= (uintptr(*src) & (1<<c - 1)) << nbits
-				nbits += c
-			}
-		} else {
-			// Leading src fragment.
-			src = subtractb(src, (off+3)/4)
-			if frag := off & 3; frag != 0 {
-				bits |= (uintptr(*src) & 0xf) >> (4 - frag) << nbits
-				src = add1(src)
-				nbits += frag
-				c -= frag
-			}
-			// Main loop: load one byte, write another.
-			// The bits are rotating through the bit buffer.
-			for i := c / 4; i > 0; i-- {
-				bits |= (uintptr(*src) & 0xf) << nbits
-				src = add1(src)
-				*dst = uint8(bits&0xf | bitScanAll)
-				dst = add1(dst)
-				bits >>= 4
-			}
-			// Final src fragment.
-			if c %= 4; c > 0 {
-				bits |= (uintptr(*src) & (1<<c - 1)) << nbits
-				nbits += c
-			}
+		// Leading src fragment.
+		src = subtractb(src, (off+7)/8)
+		if frag := off & 7; frag != 0 {
+			bits |= uintptr(*src) >> (8 - frag) << nbits
+			src = add1(src)
+			nbits += frag
+			c -= frag
 		}
-	}
-
-	// Write any final bits out, using full-byte writes, even for the final byte.
-	var totalBits uintptr
-	if size == 1 {
-		totalBits = (uintptr(unsafe.Pointer(dst))-uintptr(unsafe.Pointer(dstStart)))*8 + nbits
-		nbits += -nbits & 7
-		for ; nbits > 0; nbits -= 8 {
+		// Main loop: load one byte, write another.
+		// The bits are rotating through the bit buffer.
+		for i := c / 8; i > 0; i-- {
+			bits |= uintptr(*src) << nbits
+			src = add1(src)
 			*dst = uint8(bits)
 			dst = add1(dst)
 			bits >>= 8
 		}
-	} else {
-		totalBits = (uintptr(unsafe.Pointer(dst))-uintptr(unsafe.Pointer(dstStart)))*4 + nbits
-		nbits += -nbits & 3
-		for ; nbits > 0; nbits -= 4 {
-			v := bits&0xf | bitScanAll
-			*dst = uint8(v)
-			dst = add1(dst)
-			bits >>= 4
+		// Final src fragment.
+		if c %= 8; c > 0 {
+			bits |= (uintptr(*src) & (1<<c - 1)) << nbits
+			nbits += c
 		}
 	}
+
+	// Write any final bits out, using full-byte writes, even for the final byte.
+	totalBits := (uintptr(unsafe.Pointer(dst))-uintptr(unsafe.Pointer(dstStart)))*8 + nbits
+	nbits += -nbits & 7
+	for ; nbits > 0; nbits -= 8 {
+		*dst = uint8(bits)
+		dst = add1(dst)
+		bits >>= 8
+	}
 	return totalBits
 }
 
@@ -1898,7 +1346,7 @@
 	// Compute the number of pages needed for bitmapBytes.
 	pages := divRoundUp(bitmapBytes, pageSize)
 	s := mheap_.allocManual(pages, spanAllocPtrScalarBits)
-	runGCProg(addb(prog, 4), nil, (*byte)(unsafe.Pointer(s.startAddr)), 1)
+	runGCProg(addb(prog, 4), (*byte)(unsafe.Pointer(s.startAddr)))
 	return s
 }
 func dematerializeGCProg(s *mspan) {
@@ -1961,18 +1409,12 @@
 	return true
 }
 
-// gcbits returns the GC type info for x, for testing.
+// reflect_gcbits returns the GC type info for x, for testing.
 // The result is the bitmap entries (0 or 1), one entry per byte.
 //
 //go:linkname reflect_gcbits reflect.gcbits
 func reflect_gcbits(x any) []byte {
-	ret := getgcmask(x)
-	typ := (*ptrtype)(unsafe.Pointer(efaceOf(&x)._type)).elem
-	nptr := typ.ptrdata / goarch.PtrSize
-	for uintptr(len(ret)) > nptr && ret[len(ret)-1] == 0 {
-		ret = ret[:len(ret)-1]
-	}
-	return ret
+	return getgcmask(x)
 }
 
 // Returns GC type info for the pointer stored in ep for testing.
@@ -2011,30 +1453,33 @@
 
 	// heap
 	if base, s, _ := findObject(uintptr(p), 0, 0); base != 0 {
-		hbits := heapBitsForAddr(base)
+		if s.spanclass.noscan() {
+			return nil
+		}
 		n := s.elemsize
+		hbits := heapBitsForAddr(base, n)
 		mask = make([]byte, n/goarch.PtrSize)
-		for i := uintptr(0); i < n; i += goarch.PtrSize {
-			if hbits.isPointer() {
-				mask[i/goarch.PtrSize] = 1
-			}
-			if !hbits.morePointers() {
-				mask = mask[:i/goarch.PtrSize]
+		for {
+			var addr uintptr
+			if hbits, addr = hbits.next(); addr == 0 {
 				break
 			}
-			hbits = hbits.next()
+			mask[(addr-base)/goarch.PtrSize] = 1
+		}
+		// Callers expect this mask to end at the last pointer.
+		for len(mask) > 0 && mask[len(mask)-1] == 0 {
+			mask = mask[:len(mask)-1]
 		}
 		return
 	}
 
 	// stack
-	if _g_ := getg(); _g_.m.curg.stack.lo <= uintptr(p) && uintptr(p) < _g_.m.curg.stack.hi {
+	if gp := getg(); gp.m.curg.stack.lo <= uintptr(p) && uintptr(p) < gp.m.curg.stack.hi {
 		var frame stkframe
 		frame.sp = uintptr(p)
-		_g_ := getg()
-		gentraceback(_g_.m.curg.sched.pc, _g_.m.curg.sched.sp, 0, _g_.m.curg, 0, nil, 1000, getgcmaskcb, noescape(unsafe.Pointer(&frame)), 0)
+		gentraceback(gp.m.curg.sched.pc, gp.m.curg.sched.sp, 0, gp.m.curg, 0, nil, 1000, getgcmaskcb, noescape(unsafe.Pointer(&frame)), 0)
 		if frame.fn.valid() {
-			locals, _, _ := getStackMap(&frame, nil, false)
+			locals, _, _ := frame.getStackMap(nil, false)
 			if locals.n == 0 {
 				return
 			}
diff --git a/src/runtime/mcache.go b/src/runtime/mcache.go
index 1f484fb..acfd99b 100644
--- a/src/runtime/mcache.go
+++ b/src/runtime/mcache.go
@@ -6,6 +6,7 @@
 
 import (
 	"runtime/internal/atomic"
+	"runtime/internal/sys"
 	"unsafe"
 )
 
@@ -15,9 +16,9 @@
 //
 // mcaches are allocated from non-GC'd memory, so any heap pointers
 // must be specially handled.
-//
-//go:notinheap
 type mcache struct {
+	_ sys.NotInHeap
+
 	// The following members are accessed on every malloc,
 	// so they are grouped here for better caching.
 	nextSample uintptr // trigger heap sample after allocating this many bytes
@@ -49,7 +50,7 @@
 	// was last flushed. If flushGen != mheap_.sweepgen, the spans
 	// in this mcache are stale and need to the flushed so they
 	// can be swept. This is done in acquirep.
-	flushGen uint32
+	flushGen atomic.Uint32
 }
 
 // A gclink is a node in a linked list of blocks, like mlink,
@@ -86,7 +87,7 @@
 	systemstack(func() {
 		lock(&mheap_.lock)
 		c = (*mcache)(mheap_.cachealloc.alloc())
-		c.flushGen = mheap_.sweepgen
+		c.flushGen.Store(mheap_.sweepgen)
 		unlock(&mheap_.lock)
 	})
 	for i := range c.alloc {
@@ -251,7 +252,7 @@
 	// visible to the background sweeper.
 	mheap_.central[spc].mcentral.fullSwept(mheap_.sweepgen).push(s)
 	s.limit = s.base() + size
-	heapBitsForAddr(s.base()).initSpan(s)
+	s.initHeapBits(false)
 	return s
 }
 
@@ -317,13 +318,14 @@
 	// allocate-black. However, with this approach it's difficult
 	// to avoid spilling mark bits into the *next* GC cycle.
 	sg := mheap_.sweepgen
-	if c.flushGen == sg {
+	flushGen := c.flushGen.Load()
+	if flushGen == sg {
 		return
-	} else if c.flushGen != sg-2 {
-		println("bad flushGen", c.flushGen, "in prepareForSweep; sweepgen", sg)
+	} else if flushGen != sg-2 {
+		println("bad flushGen", flushGen, "in prepareForSweep; sweepgen", sg)
 		throw("bad flushGen")
 	}
 	c.releaseAll()
 	stackcache_clear(c)
-	atomic.Store(&c.flushGen, mheap_.sweepgen) // Synchronizes with gcStart
+	c.flushGen.Store(mheap_.sweepgen) // Synchronizes with gcStart
 }
diff --git a/src/runtime/mcentral.go b/src/runtime/mcentral.go
index e4bdf35..3382c54 100644
--- a/src/runtime/mcentral.go
+++ b/src/runtime/mcentral.go
@@ -12,12 +12,14 @@
 
 package runtime
 
-import "runtime/internal/atomic"
+import (
+	"runtime/internal/atomic"
+	"runtime/internal/sys"
+)
 
 // Central list of free objects of a given size.
-//
-//go:notinheap
 type mcentral struct {
+	_         sys.NotInHeap
 	spanclass spanClass
 
 	// partial and full contain two mspan sets: one of swept in-use
@@ -250,6 +252,6 @@
 	// n := (npages << _PageShift) / size
 	n := s.divideByElemSize(npages << _PageShift)
 	s.limit = s.base() + size*n
-	heapBitsForAddr(s.base()).initSpan(s)
+	s.initHeapBits(false)
 	return s
 }
diff --git a/src/runtime/mcheckmark.go b/src/runtime/mcheckmark.go
index 1dd2858..73c1a10 100644
--- a/src/runtime/mcheckmark.go
+++ b/src/runtime/mcheckmark.go
@@ -15,6 +15,7 @@
 import (
 	"internal/goarch"
 	"runtime/internal/atomic"
+	"runtime/internal/sys"
 	"unsafe"
 )
 
@@ -22,9 +23,10 @@
 // per-arena bitmap with a bit for every word in the arena. The mark
 // is stored on the bit corresponding to the first word of the marked
 // allocation.
-//
-//go:notinheap
-type checkmarksMap [heapArenaBytes / goarch.PtrSize / 8]uint8
+type checkmarksMap struct {
+	_ sys.NotInHeap
+	b [heapArenaBytes / goarch.PtrSize / 8]uint8
+}
 
 // If useCheckmark is true, marking of an object uses the checkmark
 // bits instead of the standard mark bits.
@@ -50,8 +52,8 @@
 			arena.checkmarks = bitmap
 		} else {
 			// Otherwise clear the existing bitmap.
-			for i := range bitmap {
-				bitmap[i] = 0
+			for i := range bitmap.b {
+				bitmap.b[i] = 0
 			}
 		}
 	}
@@ -88,9 +90,9 @@
 
 	ai := arenaIndex(obj)
 	arena := mheap_.arenas[ai.l1()][ai.l2()]
-	arenaWord := (obj / heapArenaBytes / 8) % uintptr(len(arena.checkmarks))
+	arenaWord := (obj / heapArenaBytes / 8) % uintptr(len(arena.checkmarks.b))
 	mask := byte(1 << ((obj / heapArenaBytes) % 8))
-	bytep := &arena.checkmarks[arenaWord]
+	bytep := &arena.checkmarks.b[arenaWord]
 
 	if atomic.Load8(bytep)&mask != 0 {
 		// Already checkmarked.
diff --git a/src/runtime/mem_bsd.go b/src/runtime/mem_bsd.go
index 782465a..6c5edb1 100644
--- a/src/runtime/mem_bsd.go
+++ b/src/runtime/mem_bsd.go
@@ -23,7 +23,11 @@
 }
 
 func sysUnusedOS(v unsafe.Pointer, n uintptr) {
-	madvise(v, n, _MADV_FREE)
+	if debug.madvdontneed != 0 {
+		madvise(v, n, _MADV_DONTNEED)
+	} else {
+		madvise(v, n, _MADV_FREE)
+	}
 }
 
 func sysUsedOS(v unsafe.Pointer, n uintptr) {
diff --git a/src/runtime/mem_plan9.go b/src/runtime/mem_plan9.go
index 0e8bf74..88e7d92 100644
--- a/src/runtime/mem_plan9.go
+++ b/src/runtime/mem_plan9.go
@@ -92,7 +92,7 @@
 }
 
 func memCheck() {
-	if memDebug == false {
+	if !memDebug {
 		return
 	}
 	for p := memFreelist.ptr(); p != nil && p.next != 0; p = p.next.ptr() {
diff --git a/src/runtime/memclr_riscv64.s b/src/runtime/memclr_riscv64.s
index f0e517a..d12b545 100644
--- a/src/runtime/memclr_riscv64.s
+++ b/src/runtime/memclr_riscv64.s
@@ -8,41 +8,96 @@
 
 // void runtime·memclrNoHeapPointers(void*, uintptr)
 TEXT runtime·memclrNoHeapPointers<ABIInternal>(SB),NOSPLIT,$0-16
-#ifndef GOEXPERIMENT_regabiargs
-	MOV	ptr+0(FP), A0
-	MOV	n+8(FP), A1
-#endif
-	ADD	A0, A1, T4
+	// X10 = ptr
+	// X11 = n
 
-	// If less than eight bytes, do one byte at a time.
-	SLTU	$8, A1, T3
-	BNE	T3, ZERO, outcheck
+	// If less than 8 bytes, do single byte zeroing.
+	MOV	$8, X9
+	BLT	X11, X9, check4
 
-	// Do one byte at a time until eight-aligned.
-	JMP	aligncheck
+	// Check alignment
+	AND	$3, X10, X5
+	BEQZ	X5, aligned
+
+	// Zero one byte at a time until we reach 8 byte alignment.
+	SUB	X5, X11, X11
 align:
-	MOVB	ZERO, (A0)
-	ADD	$1, A0
-aligncheck:
-	AND	$7, A0, T3
-	BNE	T3, ZERO, align
+	ADD	$-1, X5
+	MOVB	ZERO, 0(X10)
+	ADD	$1, X10
+	BNEZ	X5, align
 
-	// Do eight bytes at a time as long as there is room.
-	ADD	$-7, T4, T5
-	JMP	wordscheck
-words:
-	MOV	ZERO, (A0)
-	ADD	$8, A0
-wordscheck:
-	SLTU	T5, A0, T3
-	BNE	T3, ZERO, words
+aligned:
+	MOV	$8, X9
+	BLT	X11, X9, check4
+	MOV	$16, X9
+	BLT	X11, X9, zero8
+	MOV	$32, X9
+	BLT	X11, X9, zero16
+	MOV	$64, X9
+	BLT	X11, X9, zero32
+loop64:
+	MOV	ZERO, 0(X10)
+	MOV	ZERO, 8(X10)
+	MOV	ZERO, 16(X10)
+	MOV	ZERO, 24(X10)
+	MOV	ZERO, 32(X10)
+	MOV	ZERO, 40(X10)
+	MOV	ZERO, 48(X10)
+	MOV	ZERO, 56(X10)
+	ADD	$64, X10
+	ADD	$-64, X11
+	BGE	X11, X9, loop64
+	BEQZ	X11, done
 
-	JMP	outcheck
-out:
-	MOVB	ZERO, (A0)
-	ADD	$1, A0
-outcheck:
-	BNE	A0, T4, out
+check32:
+	MOV	$32, X9
+	BLT	X11, X9, check16
+zero32:
+	MOV	ZERO, 0(X10)
+	MOV	ZERO, 8(X10)
+	MOV	ZERO, 16(X10)
+	MOV	ZERO, 24(X10)
+	ADD	$32, X10
+	ADD	$-32, X11
+	BEQZ	X11, done
+
+check16:
+	MOV	$16, X9
+	BLT	X11, X9, check8
+zero16:
+	MOV	ZERO, 0(X10)
+	MOV	ZERO, 8(X10)
+	ADD	$16, X10
+	ADD	$-16, X11
+	BEQZ	X11, done
+
+check8:
+	MOV	$8, X9
+	BLT	X11, X9, check4
+zero8:
+	MOV	ZERO, 0(X10)
+	ADD	$8, X10
+	ADD	$-8, X11
+	BEQZ	X11, done
+
+check4:
+	MOV	$4, X9
+	BLT	X11, X9, loop1
+zero4:
+	MOVB	ZERO, 0(X10)
+	MOVB	ZERO, 1(X10)
+	MOVB	ZERO, 2(X10)
+	MOVB	ZERO, 3(X10)
+	ADD	$4, X10
+	ADD	$-4, X11
+
+loop1:
+	BEQZ	X11, done
+	MOVB	ZERO, 0(X10)
+	ADD	$1, X10
+	ADD	$-1, X11
+	JMP	loop1
 
 done:
 	RET
diff --git a/src/runtime/memclr_wasm.s b/src/runtime/memclr_wasm.s
index 5a05304..19d08ff 100644
--- a/src/runtime/memclr_wasm.s
+++ b/src/runtime/memclr_wasm.s
@@ -11,29 +11,10 @@
 	MOVD ptr+0(FP), R0
 	MOVD n+8(FP), R1
 
-loop:
-	Loop
-		Get R1
-		I64Eqz
-		If
-			RET
-		End
-
-		Get R0
-		I32WrapI64
-		I64Const $0
-		I64Store8 $0
-
-		Get R0
-		I64Const $1
-		I64Add
-		Set R0
-
-		Get R1
-		I64Const $1
-		I64Sub
-		Set R1
-
-		Br loop
-	End
-	UNDEF
+	Get R0
+	I32WrapI64
+	I32Const $0
+	Get R1
+	I32WrapI64
+	MemoryFill
+	RET
diff --git a/src/runtime/memmove_linux_amd64_test.go b/src/runtime/memmove_linux_amd64_test.go
index b3ccd90..5f90062 100644
--- a/src/runtime/memmove_linux_amd64_test.go
+++ b/src/runtime/memmove_linux_amd64_test.go
@@ -6,7 +6,6 @@
 
 import (
 	"os"
-	"reflect"
 	"syscall"
 	"testing"
 	"unsafe"
@@ -45,11 +44,7 @@
 		defer syscall.Syscall(syscall.SYS_MUNMAP, base+off, 65536, 0)
 	}
 
-	var s []byte
-	sp := (*reflect.SliceHeader)(unsafe.Pointer(&s))
-	sp.Data = base
-	sp.Len, sp.Cap = 3<<30, 3<<30
-
+	s := unsafe.Slice((*byte)(unsafe.Pointer(base)), 3<<30)
 	n := copy(s[1:], s)
 	if n != 3<<30-1 {
 		t.Fatalf("copied %d bytes, expected %d", n, 3<<30-1)
diff --git a/src/runtime/memmove_riscv64.s b/src/runtime/memmove_riscv64.s
index 538aee3..ea622ed 100644
--- a/src/runtime/memmove_riscv64.s
+++ b/src/runtime/memmove_riscv64.s
@@ -8,93 +8,311 @@
 
 // void runtime·memmove(void*, void*, uintptr)
 TEXT runtime·memmove<ABIInternal>(SB),NOSPLIT,$-0-24
-#ifndef GOEXPERIMENT_regabiargs
-	MOV	to+0(FP), A0
-	MOV	from+8(FP), A1
-	MOV	n+16(FP), A2
-#endif
-	ADD	A1, A2, T5
+	// X10 = to
+	// X11 = from
+	// X12 = n
+	BEQ	X10, X11, done
+	BEQZ	X12, done
 
 	// If the destination is ahead of the source, start at the end of the
 	// buffer and go backward.
-	BLTU	A1, A0, b
+	BGTU	X10, X11, backward
 
-	// If less than eight bytes, do one byte at a time.
-	SLTU	$8, A2, T3
-	BNE	T3, ZERO, f_outcheck
+	// If less than 8 bytes, do single byte copies.
+	MOV	$8, X9
+	BLT	X12, X9, f_loop4_check
 
-	// Do one byte at a time until from is eight-aligned.
-	JMP	f_aligncheck
+	// Check alignment - if alignment differs we have to do one byte at a time.
+	AND	$3, X10, X5
+	AND	$3, X11, X6
+	BNE	X5, X6, f_loop8_unaligned_check
+	BEQZ	X5, f_loop_check
+
+	// Move one byte at a time until we reach 8 byte alignment.
+	SUB	X5, X12, X12
 f_align:
-	MOVB	(A1), T3
-	MOVB	T3, (A0)
-	ADD	$1, A0
-	ADD	$1, A1
-f_aligncheck:
-	AND	$7, A1, T3
-	BNE	T3, ZERO, f_align
+	ADD	$-1, X5
+	MOVB	0(X11), X14
+	MOVB	X14, 0(X10)
+	ADD	$1, X10
+	ADD	$1, X11
+	BNEZ	X5, f_align
 
-	// Do eight bytes at a time as long as there is room.
-	ADD	$-7, T5, T6
-	JMP	f_wordscheck
-f_words:
-	MOV	(A1), T3
-	MOV	T3, (A0)
-	ADD	$8, A0
-	ADD	$8, A1
-f_wordscheck:
-	SLTU	T6, A1, T3
-	BNE	T3, ZERO, f_words
+f_loop_check:
+	MOV	$16, X9
+	BLT	X12, X9, f_loop8_check
+	MOV	$32, X9
+	BLT	X12, X9, f_loop16_check
+	MOV	$64, X9
+	BLT	X12, X9, f_loop32_check
+f_loop64:
+	MOV	0(X11), X14
+	MOV	8(X11), X15
+	MOV	16(X11), X16
+	MOV	24(X11), X17
+	MOV	32(X11), X18
+	MOV	40(X11), X19
+	MOV	48(X11), X20
+	MOV	56(X11), X21
+	MOV	X14, 0(X10)
+	MOV	X15, 8(X10)
+	MOV	X16, 16(X10)
+	MOV	X17, 24(X10)
+	MOV	X18, 32(X10)
+	MOV	X19, 40(X10)
+	MOV	X20, 48(X10)
+	MOV	X21, 56(X10)
+	ADD	$64, X10
+	ADD	$64, X11
+	ADD	$-64, X12
+	BGE	X12, X9, f_loop64
+	BEQZ	X12, done
 
-	// Finish off the remaining partial word.
-	JMP 	f_outcheck
-f_out:
-	MOVB	(A1), T3
-	MOVB	T3, (A0)
-	ADD	$1, A0
-	ADD	$1, A1
-f_outcheck:
-	BNE	A1, T5, f_out
+f_loop32_check:
+	MOV	$32, X9
+	BLT	X12, X9, f_loop16_check
+f_loop32:
+	MOV	0(X11), X14
+	MOV	8(X11), X15
+	MOV	16(X11), X16
+	MOV	24(X11), X17
+	MOV	X14, 0(X10)
+	MOV	X15, 8(X10)
+	MOV	X16, 16(X10)
+	MOV	X17, 24(X10)
+	ADD	$32, X10
+	ADD	$32, X11
+	ADD	$-32, X12
+	BGE	X12, X9, f_loop32
+	BEQZ	X12, done
 
-	RET
+f_loop16_check:
+	MOV	$16, X9
+	BLT	X12, X9, f_loop8_check
+f_loop16:
+	MOV	0(X11), X14
+	MOV	8(X11), X15
+	MOV	X14, 0(X10)
+	MOV	X15, 8(X10)
+	ADD	$16, X10
+	ADD	$16, X11
+	ADD	$-16, X12
+	BGE	X12, X9, f_loop16
+	BEQZ	X12, done
 
-b:
-	ADD	A0, A2, T4
-	// If less than eight bytes, do one byte at a time.
-	SLTU	$8, A2, T3
-	BNE	T3, ZERO, b_outcheck
+f_loop8_check:
+	MOV	$8, X9
+	BLT	X12, X9, f_loop4_check
+f_loop8:
+	MOV	0(X11), X14
+	MOV	X14, 0(X10)
+	ADD	$8, X10
+	ADD	$8, X11
+	ADD	$-8, X12
+	BGE	X12, X9, f_loop8
+	BEQZ	X12, done
+	JMP	f_loop4_check
 
-	// Do one byte at a time until from+n is eight-aligned.
-	JMP	b_aligncheck
+f_loop8_unaligned_check:
+	MOV	$8, X9
+	BLT	X12, X9, f_loop4_check
+f_loop8_unaligned:
+	MOVB	0(X11), X14
+	MOVB	1(X11), X15
+	MOVB	2(X11), X16
+	MOVB	3(X11), X17
+	MOVB	4(X11), X18
+	MOVB	5(X11), X19
+	MOVB	6(X11), X20
+	MOVB	7(X11), X21
+	MOVB	X14, 0(X10)
+	MOVB	X15, 1(X10)
+	MOVB	X16, 2(X10)
+	MOVB	X17, 3(X10)
+	MOVB	X18, 4(X10)
+	MOVB	X19, 5(X10)
+	MOVB	X20, 6(X10)
+	MOVB	X21, 7(X10)
+	ADD	$8, X10
+	ADD	$8, X11
+	ADD	$-8, X12
+	BGE	X12, X9, f_loop8_unaligned
+
+f_loop4_check:
+	MOV	$4, X9
+	BLT	X12, X9, f_loop1
+f_loop4:
+	MOVB	0(X11), X14
+	MOVB	1(X11), X15
+	MOVB	2(X11), X16
+	MOVB	3(X11), X17
+	MOVB	X14, 0(X10)
+	MOVB	X15, 1(X10)
+	MOVB	X16, 2(X10)
+	MOVB	X17, 3(X10)
+	ADD	$4, X10
+	ADD	$4, X11
+	ADD	$-4, X12
+	BGE	X12, X9, f_loop4
+
+f_loop1:
+	BEQZ	X12, done
+	MOVB	0(X11), X14
+	MOVB	X14, 0(X10)
+	ADD	$1, X10
+	ADD	$1, X11
+	ADD	$-1, X12
+	JMP	f_loop1
+
+backward:
+	ADD	X10, X12, X10
+	ADD	X11, X12, X11
+
+	// If less than 8 bytes, do single byte copies.
+	MOV	$8, X9
+	BLT	X12, X9, b_loop4_check
+
+	// Check alignment - if alignment differs we have to do one byte at a time.
+	AND	$3, X10, X5
+	AND	$3, X11, X6
+	BNE	X5, X6, b_loop8_unaligned_check
+	BEQZ	X5, b_loop_check
+
+	// Move one byte at a time until we reach 8 byte alignment.
+	SUB	X5, X12, X12
 b_align:
-	ADD	$-1, T4
-	ADD	$-1, T5
-	MOVB	(T5), T3
-	MOVB	T3, (T4)
-b_aligncheck:
-	AND	$7, T5, T3
-	BNE	T3, ZERO, b_align
+	ADD	$-1, X5
+	ADD	$-1, X10
+	ADD	$-1, X11
+	MOVB	0(X11), X14
+	MOVB	X14, 0(X10)
+	BNEZ	X5, b_align
 
-	// Do eight bytes at a time as long as there is room.
-	ADD	$7, A1, T6
-	JMP	b_wordscheck
-b_words:
-	ADD	$-8, T4
-	ADD	$-8, T5
-	MOV	(T5), T3
-	MOV	T3, (T4)
-b_wordscheck:
-	SLTU	T5, T6, T3
-	BNE	T3, ZERO, b_words
+b_loop_check:
+	MOV	$16, X9
+	BLT	X12, X9, b_loop8_check
+	MOV	$32, X9
+	BLT	X12, X9, b_loop16_check
+	MOV	$64, X9
+	BLT	X12, X9, b_loop32_check
+b_loop64:
+	ADD	$-64, X10
+	ADD	$-64, X11
+	MOV	0(X11), X14
+	MOV	8(X11), X15
+	MOV	16(X11), X16
+	MOV	24(X11), X17
+	MOV	32(X11), X18
+	MOV	40(X11), X19
+	MOV	48(X11), X20
+	MOV	56(X11), X21
+	MOV	X14, 0(X10)
+	MOV	X15, 8(X10)
+	MOV	X16, 16(X10)
+	MOV	X17, 24(X10)
+	MOV	X18, 32(X10)
+	MOV	X19, 40(X10)
+	MOV	X20, 48(X10)
+	MOV	X21, 56(X10)
+	ADD	$-64, X12
+	BGE	X12, X9, b_loop64
+	BEQZ	X12, done
 
-	// Finish off the remaining partial word.
-	JMP	b_outcheck
-b_out:
-	ADD	$-1, T4
-	ADD	$-1, T5
-	MOVB	(T5), T3
-	MOVB	T3, (T4)
-b_outcheck:
-	BNE	T5, A1, b_out
+b_loop32_check:
+	MOV	$32, X9
+	BLT	X12, X9, b_loop16_check
+b_loop32:
+	ADD	$-32, X10
+	ADD	$-32, X11
+	MOV	0(X11), X14
+	MOV	8(X11), X15
+	MOV	16(X11), X16
+	MOV	24(X11), X17
+	MOV	X14, 0(X10)
+	MOV	X15, 8(X10)
+	MOV	X16, 16(X10)
+	MOV	X17, 24(X10)
+	ADD	$-32, X12
+	BGE	X12, X9, b_loop32
+	BEQZ	X12, done
 
+b_loop16_check:
+	MOV	$16, X9
+	BLT	X12, X9, b_loop8_check
+b_loop16:
+	ADD	$-16, X10
+	ADD	$-16, X11
+	MOV	0(X11), X14
+	MOV	8(X11), X15
+	MOV	X14, 0(X10)
+	MOV	X15, 8(X10)
+	ADD	$-16, X12
+	BGE	X12, X9, b_loop16
+	BEQZ	X12, done
+
+b_loop8_check:
+	MOV	$8, X9
+	BLT	X12, X9, b_loop4_check
+b_loop8:
+	ADD	$-8, X10
+	ADD	$-8, X11
+	MOV	0(X11), X14
+	MOV	X14, 0(X10)
+	ADD	$-8, X12
+	BGE	X12, X9, b_loop8
+	BEQZ	X12, done
+	JMP	b_loop4_check
+
+b_loop8_unaligned_check:
+	MOV	$8, X9
+	BLT	X12, X9, b_loop4_check
+b_loop8_unaligned:
+	ADD	$-8, X10
+	ADD	$-8, X11
+	MOVB	0(X11), X14
+	MOVB	1(X11), X15
+	MOVB	2(X11), X16
+	MOVB	3(X11), X17
+	MOVB	4(X11), X18
+	MOVB	5(X11), X19
+	MOVB	6(X11), X20
+	MOVB	7(X11), X21
+	MOVB	X14, 0(X10)
+	MOVB	X15, 1(X10)
+	MOVB	X16, 2(X10)
+	MOVB	X17, 3(X10)
+	MOVB	X18, 4(X10)
+	MOVB	X19, 5(X10)
+	MOVB	X20, 6(X10)
+	MOVB	X21, 7(X10)
+	ADD	$-8, X12
+	BGE	X12, X9, b_loop8_unaligned
+
+b_loop4_check:
+	MOV	$4, X9
+	BLT	X12, X9, b_loop1
+b_loop4:
+	ADD	$-4, X10
+	ADD	$-4, X11
+	MOVB	0(X11), X14
+	MOVB	1(X11), X15
+	MOVB	2(X11), X16
+	MOVB	3(X11), X17
+	MOVB	X14, 0(X10)
+	MOVB	X15, 1(X10)
+	MOVB	X16, 2(X10)
+	MOVB	X17, 3(X10)
+	ADD	$-4, X12
+	BGE	X12, X9, b_loop4
+
+b_loop1:
+	BEQZ	X12, done
+	ADD	$-1, X10
+	ADD	$-1, X11
+	MOVB	0(X11), X14
+	MOVB	X14, 0(X10)
+	ADD	$-1, X12
+	JMP	b_loop1
+
+done:
 	RET
diff --git a/src/runtime/memmove_test.go b/src/runtime/memmove_test.go
index 8887320..f1247f6 100644
--- a/src/runtime/memmove_test.go
+++ b/src/runtime/memmove_test.go
@@ -244,23 +244,23 @@
 					dst[i] = nil
 				}
 
-				var ready uint32
+				var ready atomic.Uint32
 				go func() {
 					sp := unsafe.Pointer(&src[0])
 					dp := unsafe.Pointer(&dst[0])
-					atomic.StoreUint32(&ready, 1)
+					ready.Store(1)
 					for i := 0; i < 10000; i++ {
 						Memmove(dp, sp, sz)
 						MemclrNoHeapPointers(dp, sz)
 					}
-					atomic.StoreUint32(&ready, 2)
+					ready.Store(2)
 				}()
 
-				for atomic.LoadUint32(&ready) == 0 {
+				for ready.Load() == 0 {
 					Gosched()
 				}
 
-				for atomic.LoadUint32(&ready) != 2 {
+				for ready.Load() != 2 {
 					for i := range dst {
 						p := dst[i]
 						if p != nil && p != &x {
@@ -417,20 +417,20 @@
 	}
 
 	benchSizes := []RunData{
-		RunData{[]int{1043, 1078, 1894, 1582, 1044, 1165, 1467, 1100, 1919, 1562, 1932, 1645,
+		{[]int{1043, 1078, 1894, 1582, 1044, 1165, 1467, 1100, 1919, 1562, 1932, 1645,
 			1412, 1038, 1576, 1200, 1029, 1336, 1095, 1494, 1350, 1025, 1502, 1548, 1316, 1296,
 			1868, 1639, 1546, 1626, 1642, 1308, 1726, 1665, 1678, 1187, 1515, 1598, 1353, 1237,
 			1977, 1452, 2012, 1914, 1514, 1136, 1975, 1618, 1536, 1695, 1600, 1733, 1392, 1099,
 			1358, 1996, 1224, 1783, 1197, 1838, 1460, 1556, 1554, 2020}}, // 1kb-2kb
-		RunData{[]int{3964, 5139, 6573, 7775, 6553, 2413, 3466, 5394, 2469, 7336, 7091, 6745,
+		{[]int{3964, 5139, 6573, 7775, 6553, 2413, 3466, 5394, 2469, 7336, 7091, 6745,
 			4028, 5643, 6164, 3475, 4138, 6908, 7559, 3335, 5660, 4122, 3945, 2082, 7564, 6584,
 			5111, 2288, 6789, 2797, 4928, 7986, 5163, 5447, 2999, 4968, 3174, 3202, 7908, 8137,
 			4735, 6161, 4646, 7592, 3083, 5329, 3687, 2754, 3599, 7231, 6455, 2549, 8063, 2189,
 			7121, 5048, 4277, 6626, 6306, 2815, 7473, 3963, 7549, 7255}}, // 2kb-8kb
-		RunData{[]int{16304, 15936, 15760, 4736, 9136, 11184, 10160, 5952, 14560, 15744,
+		{[]int{16304, 15936, 15760, 4736, 9136, 11184, 10160, 5952, 14560, 15744,
 			6624, 5872, 13088, 14656, 14192, 10304, 4112, 10384, 9344, 4496, 11392, 7024,
 			5200, 10064, 14784, 5808, 13504, 10480, 8512, 4896, 13264, 5600}}, // 4kb-16kb
-		RunData{[]int{164576, 233136, 220224, 183280, 214112, 217248, 228560, 201728}}, // 128kb-256kb
+		{[]int{164576, 233136, 220224, 183280, 214112, 217248, 228560, 201728}}, // 128kb-256kb
 	}
 
 	for _, t := range benchSizes {
@@ -468,160 +468,382 @@
 	}
 }
 
+func BenchmarkClearFat7(b *testing.B) {
+	p := new([7]byte)
+	Escape(p)
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		*p = [7]byte{}
+	}
+}
+
 func BenchmarkClearFat8(b *testing.B) {
+	p := new([8 / 4]uint32)
+	Escape(p)
+	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		var x [8 / 4]uint32
-		_ = x
+		*p = [8 / 4]uint32{}
 	}
 }
+
+func BenchmarkClearFat11(b *testing.B) {
+	p := new([11]byte)
+	Escape(p)
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		*p = [11]byte{}
+	}
+}
+
 func BenchmarkClearFat12(b *testing.B) {
+	p := new([12 / 4]uint32)
+	Escape(p)
+	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		var x [12 / 4]uint32
-		_ = x
+		*p = [12 / 4]uint32{}
 	}
 }
+
+func BenchmarkClearFat13(b *testing.B) {
+	p := new([13]byte)
+	Escape(p)
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		*p = [13]byte{}
+	}
+}
+
+func BenchmarkClearFat14(b *testing.B) {
+	p := new([14]byte)
+	Escape(p)
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		*p = [14]byte{}
+	}
+}
+
+func BenchmarkClearFat15(b *testing.B) {
+	p := new([15]byte)
+	Escape(p)
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		*p = [15]byte{}
+	}
+}
+
 func BenchmarkClearFat16(b *testing.B) {
+	p := new([16 / 4]uint32)
+	Escape(p)
+	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		var x [16 / 4]uint32
-		_ = x
+		*p = [16 / 4]uint32{}
 	}
 }
+
 func BenchmarkClearFat24(b *testing.B) {
+	p := new([24 / 4]uint32)
+	Escape(p)
+	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		var x [24 / 4]uint32
-		_ = x
+		*p = [24 / 4]uint32{}
 	}
 }
+
 func BenchmarkClearFat32(b *testing.B) {
+	p := new([32 / 4]uint32)
+	Escape(p)
+	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		var x [32 / 4]uint32
-		_ = x
+		*p = [32 / 4]uint32{}
 	}
 }
+
 func BenchmarkClearFat40(b *testing.B) {
+	p := new([40 / 4]uint32)
+	Escape(p)
+	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		var x [40 / 4]uint32
-		_ = x
+		*p = [40 / 4]uint32{}
 	}
 }
+
 func BenchmarkClearFat48(b *testing.B) {
+	p := new([48 / 4]uint32)
+	Escape(p)
+	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		var x [48 / 4]uint32
-		_ = x
+		*p = [48 / 4]uint32{}
 	}
 }
+
 func BenchmarkClearFat56(b *testing.B) {
+	p := new([56 / 4]uint32)
+	Escape(p)
+	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		var x [56 / 4]uint32
-		_ = x
+		*p = [56 / 4]uint32{}
 	}
 }
+
 func BenchmarkClearFat64(b *testing.B) {
+	p := new([64 / 4]uint32)
+	Escape(p)
+	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		var x [64 / 4]uint32
-		_ = x
+		*p = [64 / 4]uint32{}
 	}
 }
+
+func BenchmarkClearFat72(b *testing.B) {
+	p := new([72 / 4]uint32)
+	Escape(p)
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		*p = [72 / 4]uint32{}
+	}
+}
+
 func BenchmarkClearFat128(b *testing.B) {
+	p := new([128 / 4]uint32)
+	Escape(p)
+	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		var x [128 / 4]uint32
-		_ = x
+		*p = [128 / 4]uint32{}
 	}
 }
+
 func BenchmarkClearFat256(b *testing.B) {
+	p := new([256 / 4]uint32)
+	Escape(p)
+	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		var x [256 / 4]uint32
-		_ = x
+		*p = [256 / 4]uint32{}
 	}
 }
+
 func BenchmarkClearFat512(b *testing.B) {
+	p := new([512 / 4]uint32)
+	Escape(p)
+	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		var x [512 / 4]uint32
-		_ = x
+		*p = [512 / 4]uint32{}
 	}
 }
+
 func BenchmarkClearFat1024(b *testing.B) {
+	p := new([1024 / 4]uint32)
+	Escape(p)
+	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		var x [1024 / 4]uint32
-		_ = x
+		*p = [1024 / 4]uint32{}
+	}
+}
+
+func BenchmarkClearFat1032(b *testing.B) {
+	p := new([1032 / 4]uint32)
+	Escape(p)
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		*p = [1032 / 4]uint32{}
+	}
+}
+
+func BenchmarkClearFat1040(b *testing.B) {
+	p := new([1040 / 4]uint32)
+	Escape(p)
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		*p = [1040 / 4]uint32{}
+	}
+}
+
+func BenchmarkCopyFat7(b *testing.B) {
+	var x [7]byte
+	p := new([7]byte)
+	Escape(p)
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		*p = x
 	}
 }
 
 func BenchmarkCopyFat8(b *testing.B) {
 	var x [8 / 4]uint32
+	p := new([8 / 4]uint32)
+	Escape(p)
+	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		y := x
-		_ = y
+		*p = x
 	}
 }
+
+func BenchmarkCopyFat11(b *testing.B) {
+	var x [11]byte
+	p := new([11]byte)
+	Escape(p)
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		*p = x
+	}
+}
+
 func BenchmarkCopyFat12(b *testing.B) {
 	var x [12 / 4]uint32
+	p := new([12 / 4]uint32)
+	Escape(p)
+	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		y := x
-		_ = y
+		*p = x
 	}
 }
+
+func BenchmarkCopyFat13(b *testing.B) {
+	var x [13]byte
+	p := new([13]byte)
+	Escape(p)
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		*p = x
+	}
+}
+
+func BenchmarkCopyFat14(b *testing.B) {
+	var x [14]byte
+	p := new([14]byte)
+	Escape(p)
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		*p = x
+	}
+}
+
+func BenchmarkCopyFat15(b *testing.B) {
+	var x [15]byte
+	p := new([15]byte)
+	Escape(p)
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		*p = x
+	}
+}
+
 func BenchmarkCopyFat16(b *testing.B) {
 	var x [16 / 4]uint32
+	p := new([16 / 4]uint32)
+	Escape(p)
+	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		y := x
-		_ = y
+		*p = x
 	}
 }
+
 func BenchmarkCopyFat24(b *testing.B) {
 	var x [24 / 4]uint32
+	p := new([24 / 4]uint32)
+	Escape(p)
+	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		y := x
-		_ = y
+		*p = x
 	}
 }
+
 func BenchmarkCopyFat32(b *testing.B) {
 	var x [32 / 4]uint32
+	p := new([32 / 4]uint32)
+	Escape(p)
+	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		y := x
-		_ = y
+		*p = x
 	}
 }
+
 func BenchmarkCopyFat64(b *testing.B) {
 	var x [64 / 4]uint32
+	p := new([64 / 4]uint32)
+	Escape(p)
+	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		y := x
-		_ = y
+		*p = x
 	}
 }
+
+func BenchmarkCopyFat72(b *testing.B) {
+	var x [72 / 4]uint32
+	p := new([72 / 4]uint32)
+	Escape(p)
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		*p = x
+	}
+}
+
 func BenchmarkCopyFat128(b *testing.B) {
 	var x [128 / 4]uint32
+	p := new([128 / 4]uint32)
+	Escape(p)
+	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		y := x
-		_ = y
+		*p = x
 	}
 }
+
 func BenchmarkCopyFat256(b *testing.B) {
 	var x [256 / 4]uint32
+	p := new([256 / 4]uint32)
+	Escape(p)
+	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		y := x
-		_ = y
+		*p = x
 	}
 }
+
 func BenchmarkCopyFat512(b *testing.B) {
 	var x [512 / 4]uint32
+	p := new([512 / 4]uint32)
+	Escape(p)
+	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		y := x
-		_ = y
+		*p = x
 	}
 }
+
 func BenchmarkCopyFat520(b *testing.B) {
 	var x [520 / 4]uint32
+	p := new([520 / 4]uint32)
+	Escape(p)
+	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		y := x
-		_ = y
+		*p = x
 	}
 }
+
 func BenchmarkCopyFat1024(b *testing.B) {
 	var x [1024 / 4]uint32
+	p := new([1024 / 4]uint32)
+	Escape(p)
+	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
-		y := x
-		_ = y
+		*p = x
+	}
+}
+
+func BenchmarkCopyFat1032(b *testing.B) {
+	var x [1032 / 4]uint32
+	p := new([1032 / 4]uint32)
+	Escape(p)
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		*p = x
+	}
+}
+
+func BenchmarkCopyFat1040(b *testing.B) {
+	var x [1040 / 4]uint32
+	p := new([1040 / 4]uint32)
+	Escape(p)
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		*p = x
 	}
 }
 
diff --git a/src/runtime/memmove_wasm.s b/src/runtime/memmove_wasm.s
index 8525fea..1be8487 100644
--- a/src/runtime/memmove_wasm.s
+++ b/src/runtime/memmove_wasm.s
@@ -13,142 +13,10 @@
 	MOVD n+16(FP), R2
 
 	Get R0
+	I32WrapI64
 	Get R1
-	I64LtU
-	If // forward
-exit_forward_64:
-		Block
-loop_forward_64:
-			Loop
-				Get R2
-				I64Const $8
-				I64LtU
-				BrIf exit_forward_64
-
-				MOVD 0(R1), 0(R0)
-
-				Get R0
-				I64Const $8
-				I64Add
-				Set R0
-
-				Get R1
-				I64Const $8
-				I64Add
-				Set R1
-
-				Get R2
-				I64Const $8
-				I64Sub
-				Set R2
-
-				Br loop_forward_64
-			End
-		End
-
-loop_forward_8:
-		Loop
-			Get R2
-			I64Eqz
-			If
-				RET
-			End
-
-			Get R0
-			I32WrapI64
-			I64Load8U (R1)
-			I64Store8 $0
-
-			Get R0
-			I64Const $1
-			I64Add
-			Set R0
-
-			Get R1
-			I64Const $1
-			I64Add
-			Set R1
-
-			Get R2
-			I64Const $1
-			I64Sub
-			Set R2
-
-			Br loop_forward_8
-		End
-
-	Else
-		// backward
-		Get R0
-		Get R2
-		I64Add
-		Set R0
-
-		Get R1
-		Get R2
-		I64Add
-		Set R1
-
-exit_backward_64:
-		Block
-loop_backward_64:
-			Loop
-				Get R2
-				I64Const $8
-				I64LtU
-				BrIf exit_backward_64
-
-				Get R0
-				I64Const $8
-				I64Sub
-				Set R0
-
-				Get R1
-				I64Const $8
-				I64Sub
-				Set R1
-
-				Get R2
-				I64Const $8
-				I64Sub
-				Set R2
-
-				MOVD 0(R1), 0(R0)
-
-				Br loop_backward_64
-			End
-		End
-
-loop_backward_8:
-		Loop
-			Get R2
-			I64Eqz
-			If
-				RET
-			End
-
-			Get R0
-			I64Const $1
-			I64Sub
-			Set R0
-
-			Get R1
-			I64Const $1
-			I64Sub
-			Set R1
-
-			Get R2
-			I64Const $1
-			I64Sub
-			Set R2
-
-			Get R0
-			I32WrapI64
-			I64Load8U (R1)
-			I64Store8 $0
-
-			Br loop_backward_8
-		End
-	End
-
-	UNDEF
+	I32WrapI64
+	Get R2
+	I32WrapI64
+	MemoryCopy
+	RET
diff --git a/src/runtime/metrics.go b/src/runtime/metrics.go
index 986121b..2061dc0 100644
--- a/src/runtime/metrics.go
+++ b/src/runtime/metrics.go
@@ -7,7 +7,6 @@
 // Metrics implementation exported to runtime/metrics.
 
 import (
-	"runtime/internal/atomic"
 	"unsafe"
 )
 
@@ -41,7 +40,7 @@
 	// Acquire the metricsSema but with handoff. Operations are typically
 	// expensive enough that queueing up goroutines and handing off between
 	// them will be noticeably better-behaved.
-	semacquire1(&metricsSema, true, 0, 0)
+	semacquire1(&metricsSema, true, 0, 0, waitReasonSemacquire)
 	if raceenabled {
 		raceacquire(unsafe.Pointer(&metricsSema))
 	}
@@ -91,6 +90,83 @@
 				out.scalar = uint64(NumCgoCall())
 			},
 		},
+		"/cpu/classes/gc/mark/assist:cpu-seconds": {
+			deps: makeStatDepSet(cpuStatsDep),
+			compute: func(in *statAggregate, out *metricValue) {
+				out.kind = metricKindFloat64
+				out.scalar = float64bits(nsToSec(in.cpuStats.gcAssistTime))
+			},
+		},
+		"/cpu/classes/gc/mark/dedicated:cpu-seconds": {
+			deps: makeStatDepSet(cpuStatsDep),
+			compute: func(in *statAggregate, out *metricValue) {
+				out.kind = metricKindFloat64
+				out.scalar = float64bits(nsToSec(in.cpuStats.gcDedicatedTime))
+			},
+		},
+		"/cpu/classes/gc/mark/idle:cpu-seconds": {
+			deps: makeStatDepSet(cpuStatsDep),
+			compute: func(in *statAggregate, out *metricValue) {
+				out.kind = metricKindFloat64
+				out.scalar = float64bits(nsToSec(in.cpuStats.gcIdleTime))
+			},
+		},
+		"/cpu/classes/gc/pause:cpu-seconds": {
+			deps: makeStatDepSet(cpuStatsDep),
+			compute: func(in *statAggregate, out *metricValue) {
+				out.kind = metricKindFloat64
+				out.scalar = float64bits(nsToSec(in.cpuStats.gcPauseTime))
+			},
+		},
+		"/cpu/classes/gc/total:cpu-seconds": {
+			deps: makeStatDepSet(cpuStatsDep),
+			compute: func(in *statAggregate, out *metricValue) {
+				out.kind = metricKindFloat64
+				out.scalar = float64bits(nsToSec(in.cpuStats.gcTotalTime))
+			},
+		},
+		"/cpu/classes/idle:cpu-seconds": {
+			deps: makeStatDepSet(cpuStatsDep),
+			compute: func(in *statAggregate, out *metricValue) {
+				out.kind = metricKindFloat64
+				out.scalar = float64bits(nsToSec(in.cpuStats.idleTime))
+			},
+		},
+		"/cpu/classes/scavenge/assist:cpu-seconds": {
+			deps: makeStatDepSet(cpuStatsDep),
+			compute: func(in *statAggregate, out *metricValue) {
+				out.kind = metricKindFloat64
+				out.scalar = float64bits(nsToSec(in.cpuStats.scavengeAssistTime))
+			},
+		},
+		"/cpu/classes/scavenge/background:cpu-seconds": {
+			deps: makeStatDepSet(cpuStatsDep),
+			compute: func(in *statAggregate, out *metricValue) {
+				out.kind = metricKindFloat64
+				out.scalar = float64bits(nsToSec(in.cpuStats.scavengeBgTime))
+			},
+		},
+		"/cpu/classes/scavenge/total:cpu-seconds": {
+			deps: makeStatDepSet(cpuStatsDep),
+			compute: func(in *statAggregate, out *metricValue) {
+				out.kind = metricKindFloat64
+				out.scalar = float64bits(nsToSec(in.cpuStats.scavengeTotalTime))
+			},
+		},
+		"/cpu/classes/total:cpu-seconds": {
+			deps: makeStatDepSet(cpuStatsDep),
+			compute: func(in *statAggregate, out *metricValue) {
+				out.kind = metricKindFloat64
+				out.scalar = float64bits(nsToSec(in.cpuStats.totalTime))
+			},
+		},
+		"/cpu/classes/user:cpu-seconds": {
+			deps: makeStatDepSet(cpuStatsDep),
+			compute: func(in *statAggregate, out *metricValue) {
+				out.kind = metricKindFloat64
+				out.scalar = float64bits(nsToSec(in.cpuStats.userTime))
+			},
+		},
 		"/gc/cycles/automatic:gc-cycles": {
 			deps: makeStatDepSet(sysStatsDep),
 			compute: func(in *statAggregate, out *metricValue) {
@@ -197,10 +273,11 @@
 				// The bottom-most bucket, containing negative values, is tracked
 				// as a separately as underflow, so fill that in manually and then
 				// iterate over the rest.
-				hist.counts[0] = atomic.Load64(&memstats.gcPauseDist.underflow)
+				hist.counts[0] = memstats.gcPauseDist.underflow.Load()
 				for i := range memstats.gcPauseDist.counts {
-					hist.counts[i+1] = atomic.Load64(&memstats.gcPauseDist.counts[i])
+					hist.counts[i+1] = memstats.gcPauseDist.counts[i].Load()
 				}
+				hist.counts[len(hist.counts)-1] = memstats.gcPauseDist.overflow.Load()
 			},
 		},
 		"/gc/stack/starting-size:bytes": {
@@ -327,10 +404,17 @@
 		"/sched/latencies:seconds": {
 			compute: func(_ *statAggregate, out *metricValue) {
 				hist := out.float64HistOrInit(timeHistBuckets)
-				hist.counts[0] = atomic.Load64(&sched.timeToRun.underflow)
+				hist.counts[0] = sched.timeToRun.underflow.Load()
 				for i := range sched.timeToRun.counts {
-					hist.counts[i+1] = atomic.Load64(&sched.timeToRun.counts[i])
+					hist.counts[i+1] = sched.timeToRun.counts[i].Load()
 				}
+				hist.counts[len(hist.counts)-1] = sched.timeToRun.overflow.Load()
+			},
+		},
+		"/sync/mutex/wait/total:seconds": {
+			compute: func(_ *statAggregate, out *metricValue) {
+				out.kind = metricKindFloat64
+				out.scalar = float64bits(nsToSec(sched.totalMutexWaitTime.Load()))
 			},
 		},
 	}
@@ -344,6 +428,7 @@
 const (
 	heapStatsDep statDep = iota // corresponds to heapStatsAggregate
 	sysStatsDep                 // corresponds to sysStatsAggregate
+	cpuStatsDep                 // corresponds to cpuStatsAggregate
 	numStatsDeps
 )
 
@@ -489,6 +574,23 @@
 	})
 }
 
+// cpuStatsAggregate represents CPU stats obtained from the runtime
+// acquired together to avoid skew and inconsistencies.
+type cpuStatsAggregate struct {
+	cpuStats
+}
+
+// compute populates the cpuStatsAggregate with values from the runtime.
+func (a *cpuStatsAggregate) compute() {
+	a.cpuStats = work.cpuStats
+}
+
+// nsToSec takes a duration in nanoseconds and converts it to seconds as
+// a float64.
+func nsToSec(ns int64) float64 {
+	return float64(ns) / 1e9
+}
+
 // statAggregate is the main driver of the metrics implementation.
 //
 // It contains multiple aggregates of runtime statistics, as well
@@ -498,6 +600,7 @@
 	ensured   statDepSet
 	heapStats heapStatsAggregate
 	sysStats  sysStatsAggregate
+	cpuStats  cpuStatsAggregate
 }
 
 // ensure populates statistics aggregates determined by deps if they
@@ -516,12 +619,14 @@
 			a.heapStats.compute()
 		case sysStatsDep:
 			a.sysStats.compute()
+		case cpuStatsDep:
+			a.cpuStats.compute()
 		}
 	}
 	a.ensured = a.ensured.union(missing)
 }
 
-// metricValidKind is a runtime copy of runtime/metrics.ValueKind and
+// metricKind is a runtime copy of runtime/metrics.ValueKind and
 // must be kept structurally identical to that type.
 type metricKind int
 
diff --git a/src/runtime/metrics/description.go b/src/runtime/metrics/description.go
index ee99d39..dcfe01e 100644
--- a/src/runtime/metrics/description.go
+++ b/src/runtime/metrics/description.go
@@ -58,6 +58,122 @@
 		Cumulative:  true,
 	},
 	{
+		Name: "/cpu/classes/gc/mark/assist:cpu-seconds",
+		Description: "Estimated total CPU time goroutines spent performing GC tasks " +
+			"to assist the GC and prevent it from falling behind the application. " +
+			"This metric is an overestimate, and not directly comparable to " +
+			"system CPU time measurements. Compare only with other /cpu/classes " +
+			"metrics.",
+		Kind:       KindFloat64,
+		Cumulative: true,
+	},
+	{
+		Name: "/cpu/classes/gc/mark/dedicated:cpu-seconds",
+		Description: "Estimated total CPU time spent performing GC tasks on " +
+			"processors (as defined by GOMAXPROCS) dedicated to those tasks. " +
+			"This includes time spent with the world stopped due to the GC. " +
+			"This metric is an overestimate, and not directly comparable to " +
+			"system CPU time measurements. Compare only with other /cpu/classes " +
+			"metrics.",
+		Kind:       KindFloat64,
+		Cumulative: true,
+	},
+	{
+		Name: "/cpu/classes/gc/mark/idle:cpu-seconds",
+		Description: "Estimated total CPU time spent performing GC tasks on " +
+			"spare CPU resources that the Go scheduler could not otherwise find " +
+			"a use for. This should be subtracted from the total GC CPU time to " +
+			"obtain a measure of compulsory GC CPU time. " +
+			"This metric is an overestimate, and not directly comparable to " +
+			"system CPU time measurements. Compare only with other /cpu/classes " +
+			"metrics.",
+		Kind:       KindFloat64,
+		Cumulative: true,
+	},
+	{
+		Name: "/cpu/classes/gc/pause:cpu-seconds",
+		Description: "Estimated total CPU time spent with the application paused by " +
+			"the GC. Even if only one thread is running during the pause, this is " +
+			"computed as GOMAXPROCS times the pause latency because nothing else " +
+			"can be executing. This is the exact sum of samples in /gc/pause:seconds " +
+			"if each sample is multiplied by GOMAXPROCS at the time it is taken. " +
+			"This metric is an overestimate, and not directly comparable to " +
+			"system CPU time measurements. Compare only with other /cpu/classes " +
+			"metrics.",
+		Kind:       KindFloat64,
+		Cumulative: true,
+	},
+	{
+		Name: "/cpu/classes/gc/total:cpu-seconds",
+		Description: "Estimated total CPU time spent performing GC tasks. " +
+			"This metric is an overestimate, and not directly comparable to " +
+			"system CPU time measurements. Compare only with other /cpu/classes " +
+			"metrics. Sum of all metrics in /cpu/classes/gc.",
+		Kind:       KindFloat64,
+		Cumulative: true,
+	},
+	{
+		Name: "/cpu/classes/idle:cpu-seconds",
+		Description: "Estimated total available CPU time not spent executing any Go or Go runtime code. " +
+			"In other words, the part of /cpu/classes/total:cpu-seconds that was unused. " +
+			"This metric is an overestimate, and not directly comparable to " +
+			"system CPU time measurements. Compare only with other /cpu/classes " +
+			"metrics.",
+		Kind:       KindFloat64,
+		Cumulative: true,
+	},
+	{
+		Name: "/cpu/classes/scavenge/assist:cpu-seconds",
+		Description: "Estimated total CPU time spent returning unused memory to the " +
+			"underlying platform in response eagerly in response to memory pressure. " +
+			"This metric is an overestimate, and not directly comparable to " +
+			"system CPU time measurements. Compare only with other /cpu/classes " +
+			"metrics.",
+		Kind:       KindFloat64,
+		Cumulative: true,
+	},
+	{
+		Name: "/cpu/classes/scavenge/background:cpu-seconds",
+		Description: "Estimated total CPU time spent performing background tasks " +
+			"to return unused memory to the underlying platform. " +
+			"This metric is an overestimate, and not directly comparable to " +
+			"system CPU time measurements. Compare only with other /cpu/classes " +
+			"metrics.",
+		Kind:       KindFloat64,
+		Cumulative: true,
+	},
+	{
+		Name: "/cpu/classes/scavenge/total:cpu-seconds",
+		Description: "Estimated total CPU time spent performing tasks that return " +
+			"unused memory to the underlying platform. " +
+			"This metric is an overestimate, and not directly comparable to " +
+			"system CPU time measurements. Compare only with other /cpu/classes " +
+			"metrics. Sum of all metrics in /cpu/classes/scavenge.",
+		Kind:       KindFloat64,
+		Cumulative: true,
+	},
+	{
+		Name: "/cpu/classes/total:cpu-seconds",
+		Description: "Estimated total available CPU time for user Go code " +
+			"or the Go runtime, as defined by GOMAXPROCS. In other words, GOMAXPROCS " +
+			"integrated over the wall-clock duration this process has been executing for. " +
+			"This metric is an overestimate, and not directly comparable to " +
+			"system CPU time measurements. Compare only with other /cpu/classes " +
+			"metrics. Sum of all metrics in /cpu/classes.",
+		Kind:       KindFloat64,
+		Cumulative: true,
+	},
+	{
+		Name: "/cpu/classes/user:cpu-seconds",
+		Description: "Estimated total CPU time spent running user Go code. This may " +
+			"also include some small amount of time spent in the Go runtime. " +
+			"This metric is an overestimate, and not directly comparable to " +
+			"system CPU time measurements. Compare only with other /cpu/classes " +
+			"metrics.",
+		Kind:       KindFloat64,
+		Cumulative: true,
+	},
+	{
 		Name:        "/gc/cycles/automatic:gc-cycles",
 		Description: "Count of completed GC cycles generated by the Go runtime.",
 		Kind:        KindUint64,
@@ -250,6 +366,12 @@
 		Description: "Distribution of the time goroutines have spent in the scheduler in a runnable state before actually running.",
 		Kind:        KindFloat64Histogram,
 	},
+	{
+		Name:        "/sync/mutex/wait/total:seconds",
+		Description: "Approximate cumulative time goroutines have spent blocked on a sync.Mutex or sync.RWMutex. This metric is useful for identifying global changes in lock contention. Collect a mutex or block profile using the runtime/pprof package for more detailed contention data.",
+		Kind:        KindFloat64,
+		Cumulative:  true,
+	},
 }
 
 // All returns a slice of containing metric descriptions for all supported metrics.
diff --git a/src/runtime/metrics/doc.go b/src/runtime/metrics/doc.go
index 28c9f6a..b593d8d 100644
--- a/src/runtime/metrics/doc.go
+++ b/src/runtime/metrics/doc.go
@@ -54,6 +54,90 @@
 	/cgo/go-to-c-calls:calls
 		Count of calls made from Go to C by the current process.
 
+	/cpu/classes/gc/mark/assist:cpu-seconds
+		Estimated total CPU time goroutines spent performing GC tasks
+		to assist the GC and prevent it from falling behind the application.
+		This metric is an overestimate, and not directly comparable to
+		system CPU time measurements. Compare only with other /cpu/classes
+		metrics.
+
+	/cpu/classes/gc/mark/dedicated:cpu-seconds
+		Estimated total CPU time spent performing GC tasks on
+		processors (as defined by GOMAXPROCS) dedicated to those tasks.
+		This includes time spent with the world stopped due to the GC.
+		This metric is an overestimate, and not directly comparable to
+		system CPU time measurements. Compare only with other /cpu/classes
+		metrics.
+
+	/cpu/classes/gc/mark/idle:cpu-seconds
+		Estimated total CPU time spent performing GC tasks on
+		spare CPU resources that the Go scheduler could not otherwise find
+		a use for. This should be subtracted from the total GC CPU time to
+		obtain a measure of compulsory GC CPU time.
+		This metric is an overestimate, and not directly comparable to
+		system CPU time measurements. Compare only with other /cpu/classes
+		metrics.
+
+	/cpu/classes/gc/pause:cpu-seconds
+		Estimated total CPU time spent with the application paused by
+		the GC. Even if only one thread is running during the pause, this is
+		computed as GOMAXPROCS times the pause latency because nothing else
+		can be executing. This is the exact sum of samples in /gc/pause:seconds
+		if each sample is multiplied by GOMAXPROCS at the time it is taken.
+		This metric is an overestimate, and not directly comparable to
+		system CPU time measurements. Compare only with other /cpu/classes
+		metrics.
+
+	/cpu/classes/gc/total:cpu-seconds
+		Estimated total CPU time spent performing GC tasks.
+		This metric is an overestimate, and not directly comparable to
+		system CPU time measurements. Compare only with other /cpu/classes
+		metrics. Sum of all metrics in /cpu/classes/gc.
+
+	/cpu/classes/idle:cpu-seconds
+		Estimated total available CPU time not spent executing any Go or Go
+		runtime code. In other words, the part of /cpu/classes/total:cpu-seconds
+		that was unused.
+		This metric is an overestimate, and not directly comparable to
+		system CPU time measurements. Compare only with other /cpu/classes
+		metrics.
+
+	/cpu/classes/scavenge/assist:cpu-seconds
+		Estimated total CPU time spent returning unused memory to the
+		underlying platform in response eagerly in response to memory pressure.
+		This metric is an overestimate, and not directly comparable to
+		system CPU time measurements. Compare only with other /cpu/classes
+		metrics.
+
+	/cpu/classes/scavenge/background:cpu-seconds
+		Estimated total CPU time spent performing background tasks
+		to return unused memory to the underlying platform.
+		This metric is an overestimate, and not directly comparable to
+		system CPU time measurements. Compare only with other /cpu/classes
+		metrics.
+
+	/cpu/classes/scavenge/total:cpu-seconds
+		Estimated total CPU time spent performing tasks that return
+		unused memory to the underlying platform.
+		This metric is an overestimate, and not directly comparable to
+		system CPU time measurements. Compare only with other /cpu/classes
+		metrics. Sum of all metrics in /cpu/classes/scavenge.
+
+	/cpu/classes/total:cpu-seconds
+		Estimated total available CPU time for user Go code or the Go runtime, as
+		defined by GOMAXPROCS. In other words, GOMAXPROCS integrated over the
+		wall-clock duration this process has been executing for.
+		This metric is an overestimate, and not directly comparable to
+		system CPU time measurements. Compare only with other /cpu/classes
+		metrics. Sum of all metrics in /cpu/classes.
+
+	/cpu/classes/user:cpu-seconds
+		Estimated total CPU time spent running user Go code. This may
+		also include some small amount of time spent in the Go runtime.
+		This metric is an overestimate, and not directly comparable to
+		system CPU time measurements. Compare only with other /cpu/classes
+		metrics.
+
 	/gc/cycles/automatic:gc-cycles
 		Count of completed GC cycles generated by the Go runtime.
 
@@ -188,5 +272,12 @@
 	/sched/latencies:seconds
 		Distribution of the time goroutines have spent in the scheduler
 		in a runnable state before actually running.
+
+	/sync/mutex/wait/total:seconds
+		Approximate cumulative time goroutines have spent blocked on a
+		sync.Mutex or sync.RWMutex. This metric is useful for identifying
+		global changes in lock contention. Collect a mutex or block
+		profile using the runtime/pprof package for more detailed
+		contention data.
 */
 package metrics
diff --git a/src/runtime/metrics_test.go b/src/runtime/metrics_test.go
index 8baf020..d981c8e 100644
--- a/src/runtime/metrics_test.go
+++ b/src/runtime/metrics_test.go
@@ -5,6 +5,7 @@
 package runtime_test
 
 import (
+	"reflect"
 	"runtime"
 	"runtime/metrics"
 	"sort"
@@ -156,13 +157,19 @@
 	// Tests whether readMetrics produces consistent, sensible values.
 	// The values are read concurrently with the runtime doing other
 	// things (e.g. allocating) so what we read can't reasonably compared
-	// to runtime values.
+	// to other runtime values (e.g. MemStats).
 
 	// Run a few GC cycles to get some of the stats to be non-zero.
 	runtime.GC()
 	runtime.GC()
 	runtime.GC()
 
+	// Set GOMAXPROCS high then sleep briefly to ensure we generate
+	// some idle time.
+	oldmaxprocs := runtime.GOMAXPROCS(10)
+	time.Sleep(time.Millisecond)
+	runtime.GOMAXPROCS(oldmaxprocs)
+
 	// Read all the supported metrics through the metrics package.
 	descs, samples := prepareAllMetricsSamples()
 	metrics.Read(samples)
@@ -181,6 +188,22 @@
 		numGC  uint64
 		pauses uint64
 	}
+	var cpu struct {
+		gcAssist    float64
+		gcDedicated float64
+		gcIdle      float64
+		gcPause     float64
+		gcTotal     float64
+
+		idle float64
+		user float64
+
+		scavengeAssist float64
+		scavengeBg     float64
+		scavengeTotal  float64
+
+		total float64
+	}
 	for i := range samples {
 		kind := samples[i].Value.Kind()
 		if want := descs[samples[i].Name].Kind; kind != want {
@@ -199,6 +222,28 @@
 			}
 		}
 		switch samples[i].Name {
+		case "/cpu/classes/gc/mark/assist:cpu-seconds":
+			cpu.gcAssist = samples[i].Value.Float64()
+		case "/cpu/classes/gc/mark/dedicated:cpu-seconds":
+			cpu.gcDedicated = samples[i].Value.Float64()
+		case "/cpu/classes/gc/mark/idle:cpu-seconds":
+			cpu.gcIdle = samples[i].Value.Float64()
+		case "/cpu/classes/gc/pause:cpu-seconds":
+			cpu.gcPause = samples[i].Value.Float64()
+		case "/cpu/classes/gc/total:cpu-seconds":
+			cpu.gcTotal = samples[i].Value.Float64()
+		case "/cpu/classes/idle:cpu-seconds":
+			cpu.idle = samples[i].Value.Float64()
+		case "/cpu/classes/scavenge/assist:cpu-seconds":
+			cpu.scavengeAssist = samples[i].Value.Float64()
+		case "/cpu/classes/scavenge/background:cpu-seconds":
+			cpu.scavengeBg = samples[i].Value.Float64()
+		case "/cpu/classes/scavenge/total:cpu-seconds":
+			cpu.scavengeTotal = samples[i].Value.Float64()
+		case "/cpu/classes/total:cpu-seconds":
+			cpu.total = samples[i].Value.Float64()
+		case "/cpu/classes/user:cpu-seconds":
+			cpu.user = samples[i].Value.Float64()
 		case "/memory/classes/total:bytes":
 			totalVirtual.got = samples[i].Value.Uint64()
 		case "/memory/classes/heap/objects:bytes":
@@ -235,6 +280,33 @@
 			}
 		}
 	}
+	// Only check this on Linux where we can be reasonably sure we have a high-resolution timer.
+	if runtime.GOOS == "linux" {
+		if cpu.gcDedicated <= 0 && cpu.gcAssist <= 0 && cpu.gcIdle <= 0 {
+			t.Errorf("found no time spent on GC work: %#v", cpu)
+		}
+		if cpu.gcPause <= 0 {
+			t.Errorf("found no GC pauses: %f", cpu.gcPause)
+		}
+		if cpu.idle <= 0 {
+			t.Errorf("found no idle time: %f", cpu.idle)
+		}
+		if total := cpu.gcDedicated + cpu.gcAssist + cpu.gcIdle + cpu.gcPause; !withinEpsilon(cpu.gcTotal, total, 0.01) {
+			t.Errorf("calculated total GC CPU not within 1%% of sampled total: %f vs. %f", total, cpu.gcTotal)
+		}
+		if total := cpu.scavengeAssist + cpu.scavengeBg; !withinEpsilon(cpu.scavengeTotal, total, 0.01) {
+			t.Errorf("calculated total scavenge CPU not within 1%% of sampled total: %f vs. %f", total, cpu.scavengeTotal)
+		}
+		if cpu.total <= 0 {
+			t.Errorf("found no total CPU time passed")
+		}
+		if cpu.user <= 0 {
+			t.Errorf("found no user time passed")
+		}
+		if total := cpu.gcTotal + cpu.scavengeTotal + cpu.user + cpu.idle; !withinEpsilon(cpu.total, total, 0.02) {
+			t.Errorf("calculated total CPU not within 2%% of sampled total: %f vs. %f", total, cpu.total)
+		}
+	}
 	if totalVirtual.got != totalVirtual.want {
 		t.Errorf(`"/memory/classes/total:bytes" does not match sum of /memory/classes/**: got %d, want %d`, totalVirtual.got, totalVirtual.want)
 	}
@@ -303,7 +375,7 @@
 	for i := 0; i < b.N; i++ {
 		start := time.Now()
 		metrics.Read(samples)
-		latencies = append(latencies, time.Now().Sub(start))
+		latencies = append(latencies, time.Since(start))
 	}
 	// Make sure to stop the timer before we wait! The load created above
 	// is very heavy-weight and not easy to stop, so we could end up
@@ -411,3 +483,131 @@
 
 	wg.Wait()
 }
+
+func withinEpsilon(v1, v2, e float64) bool {
+	return v2-v2*e <= v1 && v1 <= v2+v2*e
+}
+
+func TestMutexWaitTimeMetric(t *testing.T) {
+	var sample [1]metrics.Sample
+	sample[0].Name = "/sync/mutex/wait/total:seconds"
+
+	locks := []locker2{
+		new(mutex),
+		new(rwmutexWrite),
+		new(rwmutexReadWrite),
+		new(rwmutexWriteRead),
+	}
+	for _, lock := range locks {
+		t.Run(reflect.TypeOf(lock).Elem().Name(), func(t *testing.T) {
+			metrics.Read(sample[:])
+			before := time.Duration(sample[0].Value.Float64() * 1e9)
+
+			minMutexWaitTime := generateMutexWaitTime(lock)
+
+			metrics.Read(sample[:])
+			after := time.Duration(sample[0].Value.Float64() * 1e9)
+
+			if wt := after - before; wt < minMutexWaitTime {
+				t.Errorf("too little mutex wait time: got %s, want %s", wt, minMutexWaitTime)
+			}
+		})
+	}
+}
+
+// locker2 represents an API surface of two concurrent goroutines
+// locking the same resource, but through different APIs. It's intended
+// to abstract over the relationship of two Lock calls or an RLock
+// and a Lock call.
+type locker2 interface {
+	Lock1()
+	Unlock1()
+	Lock2()
+	Unlock2()
+}
+
+type mutex struct {
+	mu sync.Mutex
+}
+
+func (m *mutex) Lock1()   { m.mu.Lock() }
+func (m *mutex) Unlock1() { m.mu.Unlock() }
+func (m *mutex) Lock2()   { m.mu.Lock() }
+func (m *mutex) Unlock2() { m.mu.Unlock() }
+
+type rwmutexWrite struct {
+	mu sync.RWMutex
+}
+
+func (m *rwmutexWrite) Lock1()   { m.mu.Lock() }
+func (m *rwmutexWrite) Unlock1() { m.mu.Unlock() }
+func (m *rwmutexWrite) Lock2()   { m.mu.Lock() }
+func (m *rwmutexWrite) Unlock2() { m.mu.Unlock() }
+
+type rwmutexReadWrite struct {
+	mu sync.RWMutex
+}
+
+func (m *rwmutexReadWrite) Lock1()   { m.mu.RLock() }
+func (m *rwmutexReadWrite) Unlock1() { m.mu.RUnlock() }
+func (m *rwmutexReadWrite) Lock2()   { m.mu.Lock() }
+func (m *rwmutexReadWrite) Unlock2() { m.mu.Unlock() }
+
+type rwmutexWriteRead struct {
+	mu sync.RWMutex
+}
+
+func (m *rwmutexWriteRead) Lock1()   { m.mu.Lock() }
+func (m *rwmutexWriteRead) Unlock1() { m.mu.Unlock() }
+func (m *rwmutexWriteRead) Lock2()   { m.mu.RLock() }
+func (m *rwmutexWriteRead) Unlock2() { m.mu.RUnlock() }
+
+// generateMutexWaitTime causes a couple of goroutines
+// to block a whole bunch of times on a sync.Mutex, returning
+// the minimum amount of time that should be visible in the
+// /sync/mutex-wait:seconds metric.
+func generateMutexWaitTime(mu locker2) time.Duration {
+	// Set up the runtime to always track casgstatus transitions for metrics.
+	*runtime.CasGStatusAlwaysTrack = true
+
+	mu.Lock1()
+
+	// Start up a goroutine to wait on the lock.
+	gc := make(chan *runtime.G)
+	done := make(chan bool)
+	go func() {
+		gc <- runtime.Getg()
+
+		for {
+			mu.Lock2()
+			mu.Unlock2()
+			if <-done {
+				return
+			}
+		}
+	}()
+	gp := <-gc
+
+	// Set the block time high enough so that it will always show up, even
+	// on systems with coarse timer granularity.
+	const blockTime = 100 * time.Millisecond
+
+	// Make sure the goroutine spawned above actually blocks on the lock.
+	for {
+		if runtime.GIsWaitingOnMutex(gp) {
+			break
+		}
+		runtime.Gosched()
+	}
+
+	// Let some amount of time pass.
+	time.Sleep(blockTime)
+
+	// Let the other goroutine acquire the lock.
+	mu.Unlock1()
+	done <- true
+
+	// Reset flag.
+	*runtime.CasGStatusAlwaysTrack = false
+	return blockTime
+}
diff --git a/src/runtime/mfinal.go b/src/runtime/mfinal.go
index f3f3a79..d4d4f1f 100644
--- a/src/runtime/mfinal.go
+++ b/src/runtime/mfinal.go
@@ -10,6 +10,7 @@
 	"internal/abi"
 	"internal/goarch"
 	"runtime/internal/atomic"
+	"runtime/internal/sys"
 	"unsafe"
 )
 
@@ -19,9 +20,8 @@
 // finblock is allocated from non-GC'd memory, so any heap pointers
 // must be specially handled. GC currently assumes that the finalizer
 // queue does not grow during marking (but it can shrink).
-//
-//go:notinheap
 type finblock struct {
+	_       sys.NotInHeap
 	alllink *finblock
 	next    *finblock
 	cnt     uint32
@@ -29,13 +29,23 @@
 	fin     [(_FinBlockSize - 2*goarch.PtrSize - 2*4) / unsafe.Sizeof(finalizer{})]finalizer
 }
 
+var fingStatus atomic.Uint32
+
+// finalizer goroutine status.
+const (
+	fingUninitialized uint32 = iota
+	fingCreated       uint32 = 1 << (iota - 1)
+	fingRunningFinalizer
+	fingWait
+	fingWake
+)
+
 var finlock mutex  // protects the following variables
 var fing *g        // goroutine that runs finalizers
 var finq *finblock // list of finalizers that are to be executed
 var finc *finblock // cache of free blocks
 var finptrmask [_FinBlockSize / goarch.PtrSize / 8]byte
-var fingwait bool
-var fingwake bool
+
 var allfin *finblock // list of all blocks
 
 // NOTE: Layout known to queuefinalizer.
@@ -75,6 +85,12 @@
 	0<<0 | 1<<1 | 1<<2 | 1<<3 | 1<<4 | 0<<5 | 1<<6 | 1<<7,
 }
 
+// lockRankMayQueueFinalizer records the lock ranking effects of a
+// function that may call queuefinalizer.
+func lockRankMayQueueFinalizer() {
+	lockWithRankMayAcquire(&finlock, getLockRank(&finlock))
+}
+
 func queuefinalizer(p unsafe.Pointer, fn *funcval, nret uintptr, fint *_type, ot *ptrtype) {
 	if gcphase != _GCoff {
 		// Currently we assume that the finalizer queue won't
@@ -120,8 +136,8 @@
 	f.fint = fint
 	f.ot = ot
 	f.arg = p
-	fingwake = true
 	unlock(&finlock)
+	fingStatus.Or(fingWake)
 }
 
 //go:nowritebarrier
@@ -135,30 +151,28 @@
 }
 
 func wakefing() *g {
-	var res *g
-	lock(&finlock)
-	if fingwait && fingwake {
-		fingwait = false
-		fingwake = false
-		res = fing
+	if ok := fingStatus.CompareAndSwap(fingCreated|fingWait|fingWake, fingCreated); ok {
+		return fing
 	}
-	unlock(&finlock)
-	return res
+	return nil
 }
 
-var (
-	fingCreate  uint32
-	fingRunning bool
-)
-
 func createfing() {
 	// start the finalizer goroutine exactly once
-	if fingCreate == 0 && atomic.Cas(&fingCreate, 0, 1) {
+	if fingStatus.Load() == fingUninitialized && fingStatus.CompareAndSwap(fingUninitialized, fingCreated) {
 		go runfinq()
 	}
 }
 
-// This is the goroutine that runs all of the finalizers
+func finalizercommit(gp *g, lock unsafe.Pointer) bool {
+	unlock((*mutex)(lock))
+	// fingStatus should be modified after fing is put into a waiting state
+	// to avoid waking fing in running state, even if it is about to be parked.
+	fingStatus.Or(fingWait)
+	return true
+}
+
+// This is the goroutine that runs all of the finalizers.
 func runfinq() {
 	var (
 		frame    unsafe.Pointer
@@ -176,8 +190,7 @@
 		fb := finq
 		finq = nil
 		if fb == nil {
-			fingwait = true
-			goparkunlock(&finlock, waitReasonFinalizerWait, traceEvGoBlock, 1)
+			gopark(finalizercommit, unsafe.Pointer(&finlock), waitReasonFinalizerWait, traceEvGoBlock, 1)
 			continue
 		}
 		argRegs = intArgRegs
@@ -238,9 +251,9 @@
 				default:
 					throw("bad kind in runfinq")
 				}
-				fingRunning = true
+				fingStatus.Or(fingRunningFinalizer)
 				reflectcall(nil, unsafe.Pointer(f.fn), frame, uint32(framesz), uint32(framesz), uint32(framesz), &regs)
-				fingRunning = false
+				fingStatus.And(^fingRunningFinalizer)
 
 				// Drop finalizer queue heap references
 				// before hiding them from markroot.
@@ -299,12 +312,21 @@
 // bufio.Writer, because the buffer would not be flushed at program exit.
 //
 // It is not guaranteed that a finalizer will run if the size of *obj is
-// zero bytes.
+// zero bytes, because it may share same address with other zero-size
+// objects in memory. See https://go.dev/ref/spec#Size_and_alignment_guarantees.
 //
 // It is not guaranteed that a finalizer will run for objects allocated
 // in initializers for package-level variables. Such objects may be
 // linker-allocated, not heap-allocated.
 //
+// Note that because finalizers may execute arbitrarily far into the future
+// after an object is no longer referenced, the runtime is allowed to perform
+// a space-saving optimization that batches objects together in a single
+// allocation slot. The finalizer for an unreferenced object in such an
+// allocation may never run if it always exists in the same batch as a
+// referenced object. Typically, this batching only happens for tiny
+// (on the order of 16 bytes or less) and pointer-free objects.
+//
 // A finalizer may run as soon as an object becomes unreachable.
 // In order to use finalizers correctly, the program must ensure that
 // the object is reachable until it is no longer required.
@@ -357,6 +379,11 @@
 		throw("nil elem type!")
 	}
 
+	if inUserArenaChunk(uintptr(e.data)) {
+		// Arena-allocated objects are not eligible for finalizers.
+		throw("runtime.SetFinalizer: first argument was allocated into an arena")
+	}
+
 	// find the containing object
 	base, _, _ := findObject(uintptr(e.data), 0, 0)
 
diff --git a/src/runtime/mfinal_test.go b/src/runtime/mfinal_test.go
index 902ccc5..61d625a 100644
--- a/src/runtime/mfinal_test.go
+++ b/src/runtime/mfinal_test.go
@@ -53,7 +53,7 @@
 		}},
 	}
 
-	for i, tt := range finalizerTests {
+	for _, tt := range finalizerTests {
 		done := make(chan bool, 1)
 		go func() {
 			// allocate struct with pointer to avoid hitting tinyalloc.
@@ -71,11 +71,7 @@
 		}()
 		<-done
 		runtime.GC()
-		select {
-		case <-ch:
-		case <-time.After(time.Second * 4):
-			t.Errorf("#%d: finalizer for type %T didn't run", i, tt.finalizer)
-		}
+		<-ch
 	}
 }
 
@@ -109,11 +105,7 @@
 	}()
 	<-done
 	runtime.GC()
-	select {
-	case <-ch:
-	case <-time.After(4 * time.Second):
-		t.Errorf("finalizer for type *bigValue didn't run")
-	}
+	<-ch
 }
 
 func fin(v *int) {
@@ -188,11 +180,7 @@
 	fin := make(chan bool, 1)
 	runtime.SetFinalizer(y, func(z *objtype) { fin <- true })
 	runtime.GC()
-	select {
-	case <-fin:
-	case <-time.After(4 * time.Second):
-		t.Errorf("finalizer of next object in memory didn't run")
-	}
+	<-fin
 	xsglobal = xs // keep empty slice alive until here
 }
 
@@ -220,11 +208,7 @@
 	// set finalizer on string contents of y
 	runtime.SetFinalizer(y, func(z *objtype) { fin <- true })
 	runtime.GC()
-	select {
-	case <-fin:
-	case <-time.After(4 * time.Second):
-		t.Errorf("finalizer of next string in memory didn't run")
-	}
+	<-fin
 	ssglobal = ss // keep 0-length string live until here
 }
 
diff --git a/src/runtime/mfixalloc.go b/src/runtime/mfixalloc.go
index b701a09..8788d95 100644
--- a/src/runtime/mfixalloc.go
+++ b/src/runtime/mfixalloc.go
@@ -8,7 +8,10 @@
 
 package runtime
 
-import "unsafe"
+import (
+	"runtime/internal/sys"
+	"unsafe"
+)
 
 // FixAlloc is a simple free-list allocator for fixed size objects.
 // Malloc uses a FixAlloc wrapped around sysAlloc to manage its
@@ -23,7 +26,8 @@
 // Callers can keep state in the object but the first word is
 // smashed by freeing and reallocating.
 //
-// Consider marking fixalloc'd types go:notinheap.
+// Consider marking fixalloc'd types not in heap by embedding
+// runtime/internal/sys.NotInHeap.
 type fixalloc struct {
 	size   uintptr
 	first  func(arg, p unsafe.Pointer) // called first time p is returned
@@ -42,9 +46,8 @@
 // this cannot be used by some of the internal GC structures. For example when
 // the sweeper is placing an unmarked object on the free list it does not want the
 // write barrier to be called since that could result in the object being reachable.
-//
-//go:notinheap
 type mlink struct {
+	_    sys.NotInHeap
 	next *mlink
 }
 
diff --git a/src/runtime/mgc.go b/src/runtime/mgc.go
index 63e0463..1b05707 100644
--- a/src/runtime/mgc.go
+++ b/src/runtime/mgc.go
@@ -366,10 +366,6 @@
 	// explicit user call.
 	userForced bool
 
-	// totaltime is the CPU nanoseconds spent in GC since the
-	// program started if debug.gctrace > 0.
-	totaltime int64
-
 	// initialHeapLive is the value of gcController.heapLive at the
 	// beginning of this GC cycle.
 	initialHeapLive uint64
@@ -393,7 +389,7 @@
 	// cycle is sweep termination, mark, mark termination, and
 	// sweep. This differs from memstats.numgc, which is
 	// incremented at mark termination.
-	cycles uint32
+	cycles atomic.Uint32
 
 	// Timing/utilization stats for this cycle.
 	stwprocs, maxprocs                 int32
@@ -404,6 +400,9 @@
 
 	// debug.gctrace heap sizes for this cycle.
 	heap0, heap1, heap2 uint64
+
+	// Cumulative estimated CPU usage.
+	cpuStats
 }
 
 // GC runs a garbage collection and blocks the caller until the
@@ -436,7 +435,7 @@
 
 	// Wait until the current sweep termination, mark, and mark
 	// termination complete.
-	n := atomic.Load(&work.cycles)
+	n := work.cycles.Load()
 	gcWaitOnMark(n)
 
 	// We're now in sweep N or later. Trigger GC cycle N+1, which
@@ -451,7 +450,7 @@
 	// complete the cycle and because runtime.GC() is often used
 	// as part of tests and benchmarks to get the system into a
 	// relatively stable and isolated state.
-	for atomic.Load(&work.cycles) == n+1 && sweepone() != ^uintptr(0) {
+	for work.cycles.Load() == n+1 && sweepone() != ^uintptr(0) {
 		sweep.nbgsweep++
 		Gosched()
 	}
@@ -467,7 +466,7 @@
 	// First, wait for sweeping to finish. (We know there are no
 	// more spans on the sweep queue, but we may be concurrently
 	// sweeping spans, so we have to wait.)
-	for atomic.Load(&work.cycles) == n+1 && !isSweepDone() {
+	for work.cycles.Load() == n+1 && !isSweepDone() {
 		Gosched()
 	}
 
@@ -475,7 +474,7 @@
 	// stable heap profile. Only do this if we haven't already hit
 	// another mark termination.
 	mp := acquirem()
-	cycle := atomic.Load(&work.cycles)
+	cycle := work.cycles.Load()
 	if cycle == n+1 || (gcphase == _GCmark && cycle == n+2) {
 		mProf_PostSweep()
 	}
@@ -488,7 +487,7 @@
 	for {
 		// Disable phase transitions.
 		lock(&work.sweepWaiters.lock)
-		nMarks := atomic.Load(&work.cycles)
+		nMarks := work.cycles.Load()
 		if gcphase != _GCmark {
 			// We've already completed this cycle's mark.
 			nMarks++
@@ -546,7 +545,7 @@
 // that the exit condition for the _GCoff phase has been met. The exit
 // condition should be tested when allocating.
 func (t gcTrigger) test() bool {
-	if !memstats.enablegc || panicking != 0 || gcphase != _GCoff {
+	if !memstats.enablegc || panicking.Load() != 0 || gcphase != _GCoff {
 		return false
 	}
 	switch t.kind {
@@ -556,7 +555,7 @@
 		// atomically wrote gcController.heapLive anyway and we'll see our
 		// own write.
 		trigger, _ := gcController.trigger()
-		return atomic.Load64(&gcController.heapLive) >= trigger
+		return gcController.heapLive.Load() >= trigger
 	case gcTriggerTime:
 		if gcController.gcPercent.Load() < 0 {
 			return false
@@ -565,7 +564,7 @@
 		return lastgc != 0 && t.now-lastgc > forcegcperiod
 	case gcTriggerCycle:
 		// t.n > work.cycles, but accounting for wraparound.
-		return int32(t.n-work.cycles) > 0
+		return int32(t.n-work.cycles.Load()) > 0
 	}
 	return true
 }
@@ -612,9 +611,6 @@
 		return
 	}
 
-	// For stats, check if this GC was forced by the user.
-	work.userForced = trigger.kind == gcTriggerCycle
-
 	// In gcstoptheworld debug mode, upgrade the mode accordingly.
 	// We do this after re-checking the transition condition so
 	// that multiple goroutines that detect the heap trigger don't
@@ -630,13 +626,17 @@
 	semacquire(&gcsema)
 	semacquire(&worldsema)
 
+	// For stats, check if this GC was forced by the user.
+	// Update it under gcsema to avoid gctrace getting wrong values.
+	work.userForced = trigger.kind == gcTriggerCycle
+
 	if trace.enabled {
 		traceGCStart()
 	}
 
 	// Check that all Ps have finished deferred mcache flushes.
 	for _, p := range allp {
-		if fg := atomic.Load(&p.mcache.flushGen); fg != mheap_.sweepgen {
+		if fg := p.mcache.flushGen.Load(); fg != mheap_.sweepgen {
 			println("runtime: p", p.id, "flushGen", fg, "!= sweepgen", mheap_.sweepgen)
 			throw("p mcache not flushed")
 		}
@@ -652,7 +652,7 @@
 		// so it can't be more than ncpu, even if GOMAXPROCS is.
 		work.stwprocs = ncpu
 	}
-	work.heap0 = atomic.Load64(&gcController.heapLive)
+	work.heap0 = gcController.heapLive.Load()
 	work.pauseNS = 0
 	work.mode = mode
 
@@ -672,7 +672,7 @@
 	// reclaimed until the next GC cycle.
 	clearpools()
 
-	work.cycles++
+	work.cycles.Add(1)
 
 	// Assists and workers can start the moment we start
 	// the world.
@@ -810,22 +810,22 @@
 		// Otherwise, our attempt to force all P's to a safepoint could
 		// result in a deadlock as we attempt to preempt a worker that's
 		// trying to preempt us (e.g. for a stack scan).
-		casgstatus(gp, _Grunning, _Gwaiting)
-		forEachP(func(_p_ *p) {
+		casGToWaiting(gp, _Grunning, waitReasonGCMarkTermination)
+		forEachP(func(pp *p) {
 			// Flush the write barrier buffer, since this may add
 			// work to the gcWork.
-			wbBufFlush1(_p_)
+			wbBufFlush1(pp)
 
 			// Flush the gcWork, since this may create global work
 			// and set the flushedWork flag.
 			//
 			// TODO(austin): Break up these workbufs to
 			// better distribute work.
-			_p_.gcw.dispose()
+			pp.gcw.dispose()
 			// Collect the flushedWork flag.
-			if _p_.gcw.flushedWork {
+			if pp.gcw.flushedWork {
 				atomic.Xadd(&gcMarkDoneFlushed, 1)
-				_p_.gcw.flushedWork = false
+				pp.gcw.flushedWork = false
 			}
 		})
 		casgstatus(gp, _Gwaiting, _Grunning)
@@ -879,7 +879,7 @@
 	if restart {
 		getg().m.preemptoff = ""
 		systemstack(func() {
-			now := startTheWorldWithSema(true)
+			now := startTheWorldWithSema(trace.enabled)
 			work.pauseNS += now - work.pauseStart
 			memstats.gcPauseDist.record(now - work.pauseStart)
 		})
@@ -924,16 +924,14 @@
 	// Start marktermination (write barrier remains enabled for now).
 	setGCPhase(_GCmarktermination)
 
-	work.heap1 = gcController.heapLive
+	work.heap1 = gcController.heapLive.Load()
 	startTime := nanotime()
 
 	mp := acquirem()
 	mp.preemptoff = "gcing"
-	_g_ := getg()
-	_g_.m.traceback = 2
-	gp := _g_.m.curg
-	casgstatus(gp, _Grunning, _Gwaiting)
-	gp.waitreason = waitReasonGarbageCollection
+	mp.traceback = 2
+	curgp := mp.curg
+	casGToWaiting(curgp, _Grunning, waitReasonGarbageCollection)
 
 	// Run gc on the g0 stack. We do this so that the g stack
 	// we're currently running on will no longer change. Cuts
@@ -972,8 +970,8 @@
 		gcSweep(work.mode)
 	})
 
-	_g_.m.traceback = 0
-	casgstatus(gp, _Gwaiting, _Grunning)
+	mp.traceback = 0
+	casgstatus(curgp, _Gwaiting, _Grunning)
 
 	if trace.enabled {
 		traceGCDone()
@@ -1006,24 +1004,57 @@
 	memstats.pause_end[memstats.numgc%uint32(len(memstats.pause_end))] = uint64(unixNow)
 	memstats.pause_total_ns += uint64(work.pauseNS)
 
-	// Update work.totaltime.
 	sweepTermCpu := int64(work.stwprocs) * (work.tMark - work.tSweepTerm)
 	// We report idle marking time below, but omit it from the
 	// overall utilization here since it's "free".
-	markCpu := gcController.assistTime.Load() + gcController.dedicatedMarkTime + gcController.fractionalMarkTime
+	markAssistCpu := gcController.assistTime.Load()
+	markDedicatedCpu := gcController.dedicatedMarkTime.Load()
+	markFractionalCpu := gcController.fractionalMarkTime.Load()
+	markIdleCpu := gcController.idleMarkTime.Load()
 	markTermCpu := int64(work.stwprocs) * (work.tEnd - work.tMarkTerm)
-	cycleCpu := sweepTermCpu + markCpu + markTermCpu
-	work.totaltime += cycleCpu
+	scavAssistCpu := scavenge.assistTime.Load()
+	scavBgCpu := scavenge.backgroundTime.Load()
+
+	// Update cumulative GC CPU stats.
+	work.cpuStats.gcAssistTime += markAssistCpu
+	work.cpuStats.gcDedicatedTime += markDedicatedCpu + markFractionalCpu
+	work.cpuStats.gcIdleTime += markIdleCpu
+	work.cpuStats.gcPauseTime += sweepTermCpu + markTermCpu
+	work.cpuStats.gcTotalTime += sweepTermCpu + markAssistCpu + markDedicatedCpu + markFractionalCpu + markIdleCpu + markTermCpu
+
+	// Update cumulative scavenge CPU stats.
+	work.cpuStats.scavengeAssistTime += scavAssistCpu
+	work.cpuStats.scavengeBgTime += scavBgCpu
+	work.cpuStats.scavengeTotalTime += scavAssistCpu + scavBgCpu
+
+	// Update total CPU.
+	work.cpuStats.totalTime = sched.totaltime + (now-sched.procresizetime)*int64(gomaxprocs)
+	work.cpuStats.idleTime += sched.idleTime.Load()
+
+	// Compute userTime. We compute this indirectly as everything that's not the above.
+	//
+	// Since time spent in _Pgcstop is covered by gcPauseTime, and time spent in _Pidle
+	// is covered by idleTime, what we're left with is time spent in _Prunning and _Psyscall,
+	// the latter of which is fine because the P will either go idle or get used for something
+	// else via sysmon. Meanwhile if we subtract GC time from whatever's left, we get non-GC
+	// _Prunning time. Note that this still leaves time spent in sweeping and in the scheduler,
+	// but that's fine. The overwhelming majority of this time will be actual user time.
+	work.cpuStats.userTime = work.cpuStats.totalTime - (work.cpuStats.gcTotalTime +
+		work.cpuStats.scavengeTotalTime + work.cpuStats.idleTime)
 
 	// Compute overall GC CPU utilization.
-	totalCpu := sched.totaltime + (now-sched.procresizetime)*int64(gomaxprocs)
-	memstats.gc_cpu_fraction = float64(work.totaltime) / float64(totalCpu)
+	// Omit idle marking time from the overall utilization here since it's "free".
+	memstats.gc_cpu_fraction = float64(work.cpuStats.gcTotalTime-work.cpuStats.gcIdleTime) / float64(work.cpuStats.totalTime)
 
-	// Reset assist time stat.
+	// Reset assist time and background time stats.
 	//
 	// Do this now, instead of at the start of the next GC cycle, because
 	// these two may keep accumulating even if the GC is not active.
-	mheap_.pages.scav.assistTime.Store(0)
+	scavenge.assistTime.Store(0)
+	scavenge.backgroundTime.Store(0)
+
+	// Reset idle time stat.
+	sched.idleTime.Store(0)
 
 	// Reset sweep state.
 	sweep.nbgsweep = 0
@@ -1056,7 +1087,7 @@
 		throw("failed to set sweep barrier")
 	}
 
-	systemstack(func() { startTheWorldWithSema(true) })
+	systemstack(func() { startTheWorldWithSema(trace.enabled) })
 
 	// Flush the heap profile so we can start a new cycle next GC.
 	// This is relatively expensive, so we don't do it with the
@@ -1075,8 +1106,8 @@
 	// is necessary to sweep all spans, we need to ensure all
 	// mcaches are flushed before we start the next GC cycle.
 	systemstack(func() {
-		forEachP(func(_p_ *p) {
-			_p_.mcache.prepareForSweep()
+		forEachP(func(pp *p) {
+			pp.mcache.prepareForSweep()
 		})
 	})
 	// Now that we've swept stale spans in mcaches, they don't
@@ -1106,8 +1137,8 @@
 		for i, ns := range []int64{
 			sweepTermCpu,
 			gcController.assistTime.Load(),
-			gcController.dedicatedMarkTime + gcController.fractionalMarkTime,
-			gcController.idleMarkTime,
+			gcController.dedicatedMarkTime.Load() + gcController.fractionalMarkTime.Load(),
+			gcController.idleMarkTime.Load(),
 			markTermCpu,
 		} {
 			if i == 2 || i == 3 {
@@ -1121,8 +1152,8 @@
 		print(" ms cpu, ",
 			work.heap0>>20, "->", work.heap1>>20, "->", work.heap2>>20, " MB, ",
 			gcController.lastHeapGoal>>20, " MB goal, ",
-			atomic.Load64(&gcController.maxStackScan)>>20, " MB stacks, ",
-			gcController.globalsScan>>20, " MB globals, ",
+			gcController.lastStackScan.Load()>>20, " MB stacks, ",
+			gcController.globalsScan.Load()>>20, " MB globals, ",
 			work.maxprocs, " P")
 		if work.userForced {
 			print(" (forced)")
@@ -1131,6 +1162,15 @@
 		printunlock()
 	}
 
+	// Set any arena chunks that were deferred to fault.
+	lock(&userArenaState.lock)
+	faultList := userArenaState.fault
+	userArenaState.fault = nil
+	unlock(&userArenaState.lock)
+	for _, lc := range faultList {
+		lc.mspan.setUserArenaChunkToFault()
+	}
+
 	semrelease(&worldsema)
 	semrelease(&gcsema)
 	// Careful: another GC cycle may start now.
@@ -1183,7 +1223,7 @@
 	work.nwait = ^uint32(0)
 }
 
-// gcBgMarkWorker is an entry in the gcBgMarkWorkerPool. It points to a single
+// gcBgMarkWorkerNode is an entry in the gcBgMarkWorkerPool. It points to a single
 // gcBgMarkWorker goroutine.
 type gcBgMarkWorkerNode struct {
 	// Unused workers are managed in a lock-free stack. This field must be first.
@@ -1300,7 +1340,7 @@
 			// the G stack. However, stack shrinking is
 			// disabled for mark workers, so it is safe to
 			// read from the G stack.
-			casgstatus(gp, _Grunning, _Gwaiting)
+			casGToWaiting(gp, _Grunning, waitReasonGCWorkerActive)
 			switch pp.gcMarkWorkerMode {
 			default:
 				throw("gcBgMarkWorker: unexpected gcMarkWorkerMode")
@@ -1566,7 +1606,7 @@
 	}
 
 	work.bytesMarked = 0
-	work.initialHeapLive = atomic.Load64(&gcController.heapLive)
+	work.initialHeapLive = gcController.heapLive.Load()
 }
 
 // Hooks for other packages
diff --git a/src/runtime/mgclimit.go b/src/runtime/mgclimit.go
index d94e471..bcbe7f8 100644
--- a/src/runtime/mgclimit.go
+++ b/src/runtime/mgclimit.go
@@ -55,8 +55,6 @@
 	// the mark and sweep phases.
 	transitioning bool
 
-	_ uint32 // Align assistTimePool and lastUpdate on 32-bit platforms.
-
 	// assistTimePool is the accumulated assist time since the last update.
 	assistTimePool atomic.Int64
 
@@ -339,7 +337,7 @@
 	l.unlock()
 }
 
-// limiterEventType indicates the type of an event occuring on some P.
+// limiterEventType indicates the type of an event occurring on some P.
 //
 // These events represent the full set of events that the GC CPU limiter tracks
 // to execute its function.
@@ -471,9 +469,10 @@
 	// Account for the event.
 	switch typ {
 	case limiterEventIdleMarkWork:
-		fallthrough
+		gcCPULimiter.addIdleTime(duration)
 	case limiterEventIdle:
 		gcCPULimiter.addIdleTime(duration)
+		sched.idleTime.Add(duration)
 	case limiterEventMarkAssist:
 		fallthrough
 	case limiterEventScavengeAssist:
diff --git a/src/runtime/mgcmark.go b/src/runtime/mgcmark.go
index 7463707..cfda706 100644
--- a/src/runtime/mgcmark.go
+++ b/src/runtime/mgcmark.go
@@ -218,8 +218,7 @@
 			userG := getg().m.curg
 			selfScan := gp == userG && readgstatus(userG) == _Grunning
 			if selfScan {
-				casgstatus(userG, _Grunning, _Gwaiting)
-				userG.waitreason = waitReasonGarbageCollectionScan
+				casGToWaiting(userG, _Grunning, waitReasonGarbageCollectionScan)
 			}
 
 			// TODO: suspendG blocks (and spins) until gp
@@ -387,7 +386,9 @@
 				// Mark everything that can be reached from
 				// the object (but *not* the object itself or
 				// we'll never collect it).
-				scanobject(p, gcw)
+				if !s.spanclass.noscan() {
+					scanobject(p, gcw)
+				}
 
 				// The special itself is a root.
 				scanblock(uintptr(unsafe.Pointer(&spf.fn)), goarch.PtrSize, &oneptrmask[0], gcw, nil)
@@ -440,7 +441,7 @@
 	// will just cause steals to fail until credit is accumulated
 	// again, so in the long run it doesn't really matter, but we
 	// do have to handle the negative credit case.
-	bgScanCredit := atomic.Loadint64(&gcController.bgScanCredit)
+	bgScanCredit := gcController.bgScanCredit.Load()
 	stolen := int64(0)
 	if bgScanCredit > 0 {
 		if bgScanCredit < scanWork {
@@ -450,7 +451,7 @@
 			stolen = scanWork
 			gp.gcAssistBytes += debtBytes
 		}
-		atomic.Xaddint64(&gcController.bgScanCredit, -stolen)
+		gcController.bgScanCredit.Add(-stolen)
 
 		scanWork -= stolen
 
@@ -558,8 +559,7 @@
 	}
 
 	// gcDrainN requires the caller to be preemptible.
-	casgstatus(gp, _Grunning, _Gwaiting)
-	gp.waitreason = waitReasonGCAssistMarking
+	casGToWaiting(gp, _Grunning, waitReasonGCAssistMarking)
 
 	// drain own cached work first in the hopes that it
 	// will be more cache friendly.
@@ -595,15 +595,15 @@
 	}
 	now := nanotime()
 	duration := now - startTime
-	_p_ := gp.m.p.ptr()
-	_p_.gcAssistTime += duration
+	pp := gp.m.p.ptr()
+	pp.gcAssistTime += duration
 	if trackLimiterEvent {
-		_p_.limiterEvent.stop(limiterEventMarkAssist, now)
+		pp.limiterEvent.stop(limiterEventMarkAssist, now)
 	}
-	if _p_.gcAssistTime > gcAssistTimeSlack {
-		gcController.assistTime.Add(_p_.gcAssistTime)
+	if pp.gcAssistTime > gcAssistTimeSlack {
+		gcController.assistTime.Add(pp.gcAssistTime)
 		gcCPULimiter.update(now)
-		_p_.gcAssistTime = 0
+		pp.gcAssistTime = 0
 	}
 }
 
@@ -639,7 +639,7 @@
 	// the queue, but can still back out. This avoids a
 	// race in case background marking has flushed more
 	// credit since we checked above.
-	if atomic.Loadint64(&gcController.bgScanCredit) > 0 {
+	if gcController.bgScanCredit.Load() > 0 {
 		work.assistQueue.q = oldList
 		if oldList.tail != 0 {
 			oldList.tail.ptr().schedlink.set(nil)
@@ -668,7 +668,7 @@
 		// small window here where an assist may add itself to
 		// the blocked queue and park. If that happens, we'll
 		// just get it on the next flush.
-		atomic.Xaddint64(&gcController.bgScanCredit, scanWork)
+		gcController.bgScanCredit.Add(scanWork)
 		return
 	}
 
@@ -708,7 +708,7 @@
 		// Convert from scan bytes back to work.
 		assistWorkPerByte := gcController.assistWorkPerByte.Load()
 		scanWork = int64(float64(scanBytes) * assistWorkPerByte)
-		atomic.Xaddint64(&gcController.bgScanCredit, scanWork)
+		gcController.bgScanCredit.Add(scanWork)
 	}
 	unlock(&work.assistQueue.lock)
 }
@@ -943,10 +943,10 @@
 		}
 
 		// Scan arguments to this frame.
-		if frame.arglen != 0 {
+		if n := frame.argBytes(); n != 0 {
 			// TODO: We could pass the entry argument map
 			// to narrow this down further.
-			scanConservative(frame.argp, frame.arglen, nil, gcw, state)
+			scanConservative(frame.argp, n, nil, gcw, state)
 		}
 
 		if isAsyncPreempt || isDebugCall {
@@ -964,7 +964,7 @@
 		return
 	}
 
-	locals, args, objs := getStackMap(frame, &state.cache, false)
+	locals, args, objs := frame.getStackMap(&state.cache, false)
 
 	// Scan local variables if stack frame has been allocated.
 	if locals.n > 0 {
@@ -1061,7 +1061,7 @@
 	// Drain root marking jobs.
 	if work.markrootNext < work.markrootJobs {
 		// Stop if we're preemptible or if someone wants to STW.
-		for !(gp.preempt && (preemptible || atomic.Load(&sched.gcwaiting) != 0)) {
+		for !(gp.preempt && (preemptible || sched.gcwaiting.Load())) {
 			job := atomic.Xadd(&work.markrootNext, +1) - 1
 			if job >= work.markrootJobs {
 				break
@@ -1075,7 +1075,7 @@
 
 	// Drain heap marking jobs.
 	// Stop if we're preemptible or if someone wants to STW.
-	for !(gp.preempt && (preemptible || atomic.Load(&sched.gcwaiting) != 0)) {
+	for !(gp.preempt && (preemptible || sched.gcwaiting.Load())) {
 		// Try to keep work available on the global queue. We used to
 		// check if there were waiting workers, but it's better to
 		// just keep work available than to make workers wait. In the
@@ -1265,28 +1265,21 @@
 	// b is either the beginning of an object, in which case this
 	// is the size of the object to scan, or it points to an
 	// oblet, in which case we compute the size to scan below.
-	hbits := heapBitsForAddr(b)
 	s := spanOfUnchecked(b)
 	n := s.elemsize
 	if n == 0 {
 		throw("scanobject n == 0")
 	}
+	if s.spanclass.noscan() {
+		// Correctness-wise this is ok, but it's inefficient
+		// if noscan objects reach here.
+		throw("scanobject of a noscan object")
+	}
 
 	if n > maxObletBytes {
 		// Large object. Break into oblets for better
 		// parallelism and lower latency.
 		if b == s.base() {
-			// It's possible this is a noscan object (not
-			// from greyobject, but from other code
-			// paths), in which case we must *not* enqueue
-			// oblets since their bitmaps will be
-			// uninitialized.
-			if s.spanclass.noscan() {
-				// Bypass the whole scan.
-				gcw.bytesMarked += uint64(n)
-				return
-			}
-
 			// Enqueue the other oblets to scan later.
 			// Some oblets may be in b's scalar tail, but
 			// these will be marked as "no more pointers",
@@ -1308,20 +1301,24 @@
 		}
 	}
 
-	var i uintptr
-	for i = 0; i < n; i, hbits = i+goarch.PtrSize, hbits.next() {
-		// Load bits once. See CL 22712 and issue 16973 for discussion.
-		bits := hbits.bits()
-		if bits&bitScan == 0 {
-			break // no more pointers in this object
+	hbits := heapBitsForAddr(b, n)
+	var scanSize uintptr
+	for {
+		var addr uintptr
+		if hbits, addr = hbits.nextFast(); addr == 0 {
+			if hbits, addr = hbits.next(); addr == 0 {
+				break
+			}
 		}
-		if bits&bitPointer == 0 {
-			continue // not a pointer
-		}
+
+		// Keep track of farthest pointer we found, so we can
+		// update heapScanWork. TODO: is there a better metric,
+		// now that we can skip scalar portions pretty efficiently?
+		scanSize = addr - b + goarch.PtrSize
 
 		// Work here is duplicated in scanblock and above.
 		// If you make changes here, make changes there too.
-		obj := *(*uintptr)(unsafe.Pointer(b + i))
+		obj := *(*uintptr)(unsafe.Pointer(addr))
 
 		// At this point we have extracted the next potential pointer.
 		// Quickly filter out nil and pointers back to the current object.
@@ -1335,13 +1332,13 @@
 			// heap. In this case, we know the object was
 			// just allocated and hence will be marked by
 			// allocation itself.
-			if obj, span, objIndex := findObject(obj, b, i); obj != 0 {
-				greyobject(obj, b, i, span, gcw, objIndex)
+			if obj, span, objIndex := findObject(obj, b, addr-b); obj != 0 {
+				greyobject(obj, b, addr-b, span, gcw, objIndex)
 			}
 		}
 	}
 	gcw.bytesMarked += uint64(n)
-	gcw.heapScanWork += int64(i)
+	gcw.heapScanWork += int64(scanSize)
 }
 
 // scanConservative scans block [b, b+n) conservatively, treating any
@@ -1564,7 +1561,7 @@
 //
 //go:nowritebarrier
 //go:nosplit
-func gcmarknewobject(span *mspan, obj, size, scanSize uintptr) {
+func gcmarknewobject(span *mspan, obj, size uintptr) {
 	if useCheckmark { // The world should be stopped so this should not happen.
 		throw("gcmarknewobject called while doing checkmark")
 	}
diff --git a/src/runtime/mgcpacer.go b/src/runtime/mgcpacer.go
index 2d9fd27..9d9840e 100644
--- a/src/runtime/mgcpacer.go
+++ b/src/runtime/mgcpacer.go
@@ -8,7 +8,7 @@
 	"internal/cpu"
 	"internal/goexperiment"
 	"runtime/internal/atomic"
-	"unsafe"
+	_ "unsafe" // for go:linkname
 )
 
 // go119MemoryLimitSupport is a feature flag for a number of changes
@@ -74,13 +74,6 @@
 	memoryLimitHeapGoalHeadroom = 1 << 20
 )
 
-func init() {
-	if offset := unsafe.Offsetof(gcController.heapLive); offset%8 != 0 {
-		println(offset)
-		throw("gcController.heapLive not aligned to 8 bytes")
-	}
-}
-
 // gcController implements the GC pacing controller that determines
 // when to trigger concurrent garbage collection and how much marking
 // work to do in mutator assists and background marking.
@@ -99,8 +92,6 @@
 	// Initialized from GOGC. GOGC=off means no GC.
 	gcPercent atomic.Int32
 
-	_ uint32 // padding so following 64-bit values are 8-byte aligned
-
 	// memoryLimit is the soft memory limit in bytes.
 	//
 	// Initialized from GOMEMLIMIT. GOMEMLIMIT=off is equivalent to MaxInt64
@@ -145,14 +136,10 @@
 	// Updated at the end of each GC cycle, in endCycle.
 	consMark float64
 
-	// consMarkController holds the state for the mark-cons ratio
-	// estimation over time.
-	//
-	// Its purpose is to smooth out noisiness in the computation of
-	// consMark; see consMark for details.
-	consMarkController piController
-
-	_ uint32 // Padding for atomics on 32-bit platforms.
+	// lastConsMark is the computed cons/mark value for the previous GC
+	// cycle. Note that this is *not* the last value of cons/mark, but the
+	// actual computed value. See endCycle for details.
+	lastConsMark float64
 
 	// gcPercentHeapGoal is the goal heapLive for when next GC ends derived
 	// from gcPercent.
@@ -193,32 +180,27 @@
 	// hence goes up as we allocate and down as we sweep) while heapLive
 	// excludes these objects (and hence only goes up between GCs).
 	//
-	// This is updated atomically without locking. To reduce
-	// contention, this is updated only when obtaining a span from
-	// an mcentral and at this point it counts all of the
-	// unallocated slots in that span (which will be allocated
-	// before that mcache obtains another span from that
-	// mcentral). Hence, it slightly overestimates the "true" live
-	// heap size. It's better to overestimate than to
-	// underestimate because 1) this triggers the GC earlier than
-	// necessary rather than potentially too late and 2) this
-	// leads to a conservative GC rate rather than a GC rate that
-	// is potentially too low.
-	//
-	// Reads should likewise be atomic (or during STW).
+	// To reduce contention, this is updated only when obtaining a span
+	// from an mcentral and at this point it counts all of the unallocated
+	// slots in that span (which will be allocated before that mcache
+	// obtains another span from that mcentral). Hence, it slightly
+	// overestimates the "true" live heap size. It's better to overestimate
+	// than to underestimate because 1) this triggers the GC earlier than
+	// necessary rather than potentially too late and 2) this leads to a
+	// conservative GC rate rather than a GC rate that is potentially too
+	// low.
 	//
 	// Whenever this is updated, call traceHeapAlloc() and
 	// this gcControllerState's revise() method.
-	heapLive uint64
+	heapLive atomic.Uint64
 
-	// heapScan is the number of bytes of "scannable" heap. This
-	// is the live heap (as counted by heapLive), but omitting
-	// no-scan objects and no-scan tails of objects.
+	// heapScan is the number of bytes of "scannable" heap. This is the
+	// live heap (as counted by heapLive), but omitting no-scan objects and
+	// no-scan tails of objects.
 	//
-	// This value is fixed at the start of a GC cycle, so during a
-	// GC cycle it is safe to read without atomics, and it represents
-	// the maximum scannable heap.
-	heapScan uint64
+	// This value is fixed at the start of a GC cycle. It represents the
+	// maximum scannable heap.
+	heapScan atomic.Uint64
 
 	// lastHeapScan is the number of bytes of heap that were scanned
 	// last GC cycle. It is the same as heapMarked, but only
@@ -229,7 +211,7 @@
 
 	// lastStackScan is the number of bytes of stack that were scanned
 	// last GC cycle.
-	lastStackScan uint64
+	lastStackScan atomic.Uint64
 
 	// maxStackScan is the amount of allocated goroutine stack space in
 	// use by goroutines.
@@ -239,15 +221,11 @@
 	// goroutine stack space is much harder to measure cheaply. By using
 	// allocated space, we make an overestimate; this is OK, it's better
 	// to conservatively overcount than undercount.
-	//
-	// Read and updated atomically.
-	maxStackScan uint64
+	maxStackScan atomic.Uint64
 
 	// globalsScan is the total amount of global variable space
 	// that is scannable.
-	//
-	// Read and updated atomically.
-	globalsScan uint64
+	globalsScan atomic.Uint64
 
 	// heapMarked is the number of bytes marked by the previous
 	// GC. After mark termination, heapLive == heapMarked, but
@@ -273,12 +251,11 @@
 	stackScanWork   atomic.Int64
 	globalsScanWork atomic.Int64
 
-	// bgScanCredit is the scan work credit accumulated by the
-	// concurrent background scan. This credit is accumulated by
-	// the background scan and stolen by mutator assists. This is
-	// updated atomically. Updates occur in bounded batches, since
-	// it is both written and read throughout the cycle.
-	bgScanCredit int64
+	// bgScanCredit is the scan work credit accumulated by the concurrent
+	// background scan. This credit is accumulated by the background scan
+	// and stolen by mutator assists.  Updates occur in bounded batches,
+	// since it is both written and read throughout the cycle.
+	bgScanCredit atomic.Int64
 
 	// assistTime is the nanoseconds spent in mutator assists
 	// during this cycle. This is updated atomically, and must also
@@ -287,31 +264,29 @@
 	// written and read throughout the cycle.
 	assistTime atomic.Int64
 
-	// dedicatedMarkTime is the nanoseconds spent in dedicated
-	// mark workers during this cycle. This is updated atomically
-	// at the end of the concurrent mark phase.
-	dedicatedMarkTime int64
+	// dedicatedMarkTime is the nanoseconds spent in dedicated mark workers
+	// during this cycle. This is updated at the end of the concurrent mark
+	// phase.
+	dedicatedMarkTime atomic.Int64
 
-	// fractionalMarkTime is the nanoseconds spent in the
-	// fractional mark worker during this cycle. This is updated
-	// atomically throughout the cycle and will be up-to-date if
-	// the fractional mark worker is not currently running.
-	fractionalMarkTime int64
+	// fractionalMarkTime is the nanoseconds spent in the fractional mark
+	// worker during this cycle. This is updated throughout the cycle and
+	// will be up-to-date if the fractional mark worker is not currently
+	// running.
+	fractionalMarkTime atomic.Int64
 
-	// idleMarkTime is the nanoseconds spent in idle marking
-	// during this cycle. This is updated atomically throughout
-	// the cycle.
-	idleMarkTime int64
+	// idleMarkTime is the nanoseconds spent in idle marking during this
+	// cycle. This is updated throughout the cycle.
+	idleMarkTime atomic.Int64
 
 	// markStartTime is the absolute start time in nanoseconds
 	// that assists and background mark workers started.
 	markStartTime int64
 
-	// dedicatedMarkWorkersNeeded is the number of dedicated mark
-	// workers that need to be started. This is computed at the
-	// beginning of each cycle and decremented atomically as
-	// dedicated mark workers get started.
-	dedicatedMarkWorkersNeeded int64
+	// dedicatedMarkWorkersNeeded is the number of dedicated mark workers
+	// that need to be started. This is computed at the beginning of each
+	// cycle and decremented as dedicated mark workers get started.
+	dedicatedMarkWorkersNeeded atomic.Int64
 
 	// idleMarkWorkers is two packed int32 values in a single uint64.
 	// These two values are always updated simultaneously.
@@ -395,28 +370,6 @@
 func (c *gcControllerState) init(gcPercent int32, memoryLimit int64) {
 	c.heapMinimum = defaultHeapMinimum
 	c.triggered = ^uint64(0)
-
-	c.consMarkController = piController{
-		// Tuned first via the Ziegler-Nichols process in simulation,
-		// then the integral time was manually tuned against real-world
-		// applications to deal with noisiness in the measured cons/mark
-		// ratio.
-		kp: 0.9,
-		ti: 4.0,
-
-		// Set a high reset time in GC cycles.
-		// This is inversely proportional to the rate at which we
-		// accumulate error from clipping. By making this very high
-		// we make the accumulation slow. In general, clipping is
-		// OK in our situation, hence the choice.
-		//
-		// Tune this if we get unintended effects from clipping for
-		// a long time.
-		tt:  1000,
-		min: -1000,
-		max: 1000,
-	}
-
 	c.setGCPercent(gcPercent)
 	c.setMemoryLimit(memoryLimit)
 	c.commit(true) // No sweep phase in the first GC cycle.
@@ -433,32 +386,13 @@
 	c.heapScanWork.Store(0)
 	c.stackScanWork.Store(0)
 	c.globalsScanWork.Store(0)
-	c.bgScanCredit = 0
+	c.bgScanCredit.Store(0)
 	c.assistTime.Store(0)
-	c.dedicatedMarkTime = 0
-	c.fractionalMarkTime = 0
-	c.idleMarkTime = 0
+	c.dedicatedMarkTime.Store(0)
+	c.fractionalMarkTime.Store(0)
+	c.idleMarkTime.Store(0)
 	c.markStartTime = markStartTime
-
-	// TODO(mknyszek): This is supposed to be the actual trigger point for the heap, but
-	// causes regressions in memory use. The cause is that the PI controller used to smooth
-	// the cons/mark ratio measurements tends to flail when using the less accurate precomputed
-	// trigger for the cons/mark calculation, and this results in the controller being more
-	// conservative about steady-states it tries to find in the future.
-	//
-	// This conservatism is transient, but these transient states tend to matter for short-lived
-	// programs, especially because the PI controller is overdamped, partially because it is
-	// configured with a relatively large time constant.
-	//
-	// Ultimately, I think this is just two mistakes piled on one another: the choice of a swingy
-	// smoothing function that recalls a fairly long history (due to its overdamped time constant)
-	// coupled with an inaccurate cons/mark calculation. It just so happens this works better
-	// today, and it makes it harder to change things in the future.
-	//
-	// This is described in #53738. Fix this for #53892 by changing back to the actual trigger
-	// point and simplifying the smoothing function.
-	heapTrigger, heapGoal := c.trigger()
-	c.triggered = heapTrigger
+	c.triggered = c.heapLive.Load()
 
 	// Compute the background mark utilization goal. In general,
 	// this may not come out exactly. We round the number of
@@ -466,26 +400,26 @@
 	// 25%. For small GOMAXPROCS, this would introduce too much
 	// error, so we add fractional workers in that case.
 	totalUtilizationGoal := float64(procs) * gcBackgroundUtilization
-	c.dedicatedMarkWorkersNeeded = int64(totalUtilizationGoal + 0.5)
-	utilError := float64(c.dedicatedMarkWorkersNeeded)/totalUtilizationGoal - 1
+	dedicatedMarkWorkersNeeded := int64(totalUtilizationGoal + 0.5)
+	utilError := float64(dedicatedMarkWorkersNeeded)/totalUtilizationGoal - 1
 	const maxUtilError = 0.3
 	if utilError < -maxUtilError || utilError > maxUtilError {
 		// Rounding put us more than 30% off our goal. With
 		// gcBackgroundUtilization of 25%, this happens for
 		// GOMAXPROCS<=3 or GOMAXPROCS=6. Enable fractional
 		// workers to compensate.
-		if float64(c.dedicatedMarkWorkersNeeded) > totalUtilizationGoal {
+		if float64(dedicatedMarkWorkersNeeded) > totalUtilizationGoal {
 			// Too many dedicated workers.
-			c.dedicatedMarkWorkersNeeded--
+			dedicatedMarkWorkersNeeded--
 		}
-		c.fractionalUtilizationGoal = (totalUtilizationGoal - float64(c.dedicatedMarkWorkersNeeded)) / float64(procs)
+		c.fractionalUtilizationGoal = (totalUtilizationGoal - float64(dedicatedMarkWorkersNeeded)) / float64(procs)
 	} else {
 		c.fractionalUtilizationGoal = 0
 	}
 
 	// In STW mode, we just want dedicated workers.
 	if debug.gcstoptheworld > 0 {
-		c.dedicatedMarkWorkersNeeded = int64(procs)
+		dedicatedMarkWorkersNeeded = int64(procs)
 		c.fractionalUtilizationGoal = 0
 	}
 
@@ -500,7 +434,7 @@
 		// required. However, we need at least one dedicated mark worker or
 		// idle GC worker to ensure GC progress in some scenarios (see comment
 		// on maxIdleMarkWorkers).
-		if c.dedicatedMarkWorkersNeeded > 0 {
+		if dedicatedMarkWorkersNeeded > 0 {
 			c.setMaxIdleMarkWorkers(0)
 		} else {
 			// TODO(mknyszek): The fundamental reason why we need this is because
@@ -510,22 +444,24 @@
 			c.setMaxIdleMarkWorkers(1)
 		}
 	} else {
-		// N.B. gomaxprocs and dedicatedMarkWorkersNeeded is guaranteed not to
+		// N.B. gomaxprocs and dedicatedMarkWorkersNeeded are guaranteed not to
 		// change during a GC cycle.
-		c.setMaxIdleMarkWorkers(int32(procs) - int32(c.dedicatedMarkWorkersNeeded))
+		c.setMaxIdleMarkWorkers(int32(procs) - int32(dedicatedMarkWorkersNeeded))
 	}
 
 	// Compute initial values for controls that are updated
 	// throughout the cycle.
+	c.dedicatedMarkWorkersNeeded.Store(dedicatedMarkWorkersNeeded)
 	c.revise()
 
 	if debug.gcpacertrace > 0 {
+		heapGoal := c.heapGoal()
 		assistRatio := c.assistWorkPerByte.Load()
 		print("pacer: assist ratio=", assistRatio,
-			" (scan ", gcController.heapScan>>20, " MB in ",
+			" (scan ", gcController.heapScan.Load()>>20, " MB in ",
 			work.initialHeapLive>>20, "->",
 			heapGoal>>20, " MB)",
-			" workers=", c.dedicatedMarkWorkersNeeded,
+			" workers=", dedicatedMarkWorkersNeeded,
 			"+", c.fractionalUtilizationGoal, "\n")
 	}
 }
@@ -559,8 +495,8 @@
 		// act like GOGC is huge for the below calculations.
 		gcPercent = 100000
 	}
-	live := atomic.Load64(&c.heapLive)
-	scan := atomic.Load64(&c.heapScan)
+	live := c.heapLive.Load()
+	scan := c.heapScan.Load()
 	work := c.heapScanWork.Load() + c.stackScanWork.Load() + c.globalsScanWork.Load()
 
 	// Assume we're under the soft goal. Pace GC to complete at
@@ -569,14 +505,14 @@
 
 	// The expected scan work is computed as the amount of bytes scanned last
 	// GC cycle (both heap and stack), plus our estimate of globals work for this cycle.
-	scanWorkExpected := int64(c.lastHeapScan + c.lastStackScan + c.globalsScan)
+	scanWorkExpected := int64(c.lastHeapScan + c.lastStackScan.Load() + c.globalsScan.Load())
 
 	// maxScanWork is a worst-case estimate of the amount of scan work that
 	// needs to be performed in this GC cycle. Specifically, it represents
 	// the case where *all* scannable memory turns out to be live, and
 	// *all* allocated stack space is scannable.
-	maxStackScan := atomic.Load64(&c.maxStackScan)
-	maxScanWork := int64(scan + maxStackScan + c.globalsScan)
+	maxStackScan := c.maxStackScan.Load()
+	maxScanWork := int64(scan + maxStackScan + c.globalsScan.Load())
 	if work > scanWorkExpected {
 		// We've already done more scan work than expected. Because our expectation
 		// is based on a steady-state scannable heap size, we assume this means our
@@ -675,7 +611,7 @@
 		utilization += float64(c.assistTime.Load()) / float64(assistDuration*int64(procs))
 	}
 
-	if c.heapLive <= c.triggered {
+	if c.heapLive.Load() <= c.triggered {
 		// Shouldn't happen, but let's be very safe about this in case the
 		// GC is somehow extremely short.
 		//
@@ -688,7 +624,7 @@
 	}
 	idleUtilization := 0.0
 	if assistDuration > 0 {
-		idleUtilization = float64(c.idleMarkTime) / float64(assistDuration*int64(procs))
+		idleUtilization = float64(c.idleMarkTime.Load()) / float64(assistDuration*int64(procs))
 	}
 	// Determine the cons/mark ratio.
 	//
@@ -706,7 +642,7 @@
 	//
 	//    assistDuration * procs * (utilization + idleUtilization)
 	//
-	// In this case, we *include* idle utilization, because that is additional CPU time that the
+	// In this case, we *include* idle utilization, because that is additional CPU time that
 	// the GC had available to it.
 	//
 	// In effect, idle GC time is sort of double-counted here, but it's very weird compared
@@ -719,44 +655,23 @@
 	//
 	// Note that because we only care about the ratio, assistDuration and procs cancel out.
 	scanWork := c.heapScanWork.Load() + c.stackScanWork.Load() + c.globalsScanWork.Load()
-	currentConsMark := (float64(c.heapLive-c.triggered) * (utilization + idleUtilization)) /
+	currentConsMark := (float64(c.heapLive.Load()-c.triggered) * (utilization + idleUtilization)) /
 		(float64(scanWork) * (1 - utilization))
 
-	// Update cons/mark controller. The time period for this is 1 GC cycle.
-	//
-	// This use of a PI controller might seem strange. So, here's an explanation:
-	//
-	// currentConsMark represents the consMark we *should've* had to be perfectly
-	// on-target for this cycle. Given that we assume the next GC will be like this
-	// one in the steady-state, it stands to reason that we should just pick that
-	// as our next consMark. In practice, however, currentConsMark is too noisy:
-	// we're going to be wildly off-target in each GC cycle if we do that.
-	//
-	// What we do instead is make a long-term assumption: there is some steady-state
-	// consMark value, but it's obscured by noise. By constantly shooting for this
-	// noisy-but-perfect consMark value, the controller will bounce around a bit,
-	// but its average behavior, in aggregate, should be less noisy and closer to
-	// the true long-term consMark value, provided its tuned to be slightly overdamped.
-	var ok bool
+	// Update our cons/mark estimate. This is the raw value above, but averaged over 2 GC cycles
+	// because it tends to be jittery, even in the steady-state. The smoothing helps the GC to
+	// maintain much more stable cycle-by-cycle behavior.
 	oldConsMark := c.consMark
-	c.consMark, ok = c.consMarkController.next(c.consMark, currentConsMark, 1.0)
-	if !ok {
-		// The error spiraled out of control. This is incredibly unlikely seeing
-		// as this controller is essentially just a smoothing function, but it might
-		// mean that something went very wrong with how currentConsMark was calculated.
-		// Just reset consMark and keep going.
-		c.consMark = 0
-	}
+	c.consMark = (currentConsMark + c.lastConsMark) / 2
+	c.lastConsMark = currentConsMark
 
 	if debug.gcpacertrace > 0 {
 		printlock()
 		goal := gcGoalUtilization * 100
 		print("pacer: ", int(utilization*100), "% CPU (", int(goal), " exp.) for ")
-		print(c.heapScanWork.Load(), "+", c.stackScanWork.Load(), "+", c.globalsScanWork.Load(), " B work (", c.lastHeapScan+c.lastStackScan+c.globalsScan, " B exp.) ")
-		print("in ", c.triggered, " B -> ", c.heapLive, " B (∆goal ", int64(c.heapLive)-int64(c.lastHeapGoal), ", cons/mark ", oldConsMark, ")")
-		if !ok {
-			print("[controller reset]")
-		}
+		print(c.heapScanWork.Load(), "+", c.stackScanWork.Load(), "+", c.globalsScanWork.Load(), " B work (", c.lastHeapScan+c.lastStackScan.Load()+c.globalsScan.Load(), " B exp.) ")
+		live := c.heapLive.Load()
+		print("in ", c.triggered, " B -> ", live, " B (∆goal ", int64(live)-int64(c.lastHeapGoal), ", cons/mark ", oldConsMark, ")")
 		println()
 		printunlock()
 	}
@@ -771,14 +686,14 @@
 	// If there are idle Ps, wake one so it will run an idle worker.
 	// NOTE: This is suspected of causing deadlocks. See golang.org/issue/19112.
 	//
-	//	if atomic.Load(&sched.npidle) != 0 && atomic.Load(&sched.nmspinning) == 0 {
+	//	if sched.npidle.Load() != 0 && sched.nmspinning.Load() == 0 {
 	//		wakep()
 	//		return
 	//	}
 
 	// There are no idle Ps. If we need more dedicated workers,
 	// try to preempt a running P so it will switch to a worker.
-	if c.dedicatedMarkWorkersNeeded <= 0 {
+	if c.dedicatedMarkWorkersNeeded.Load() <= 0 {
 		return
 	}
 	// Pick a random other P to preempt.
@@ -805,9 +720,9 @@
 	}
 }
 
-// findRunnableGCWorker returns a background mark worker for _p_ if it
+// findRunnableGCWorker returns a background mark worker for pp if it
 // should be run. This must only be called when gcBlackenEnabled != 0.
-func (c *gcControllerState) findRunnableGCWorker(_p_ *p, now int64) (*g, int64) {
+func (c *gcControllerState) findRunnableGCWorker(pp *p, now int64) (*g, int64) {
 	if gcBlackenEnabled == 0 {
 		throw("gcControllerState.findRunnable: blackening not enabled")
 	}
@@ -823,7 +738,7 @@
 		gcCPULimiter.update(now)
 	}
 
-	if !gcMarkWorkAvailable(_p_) {
+	if !gcMarkWorkAvailable(pp) {
 		// No work to be done right now. This can happen at
 		// the end of the mark phase when there are still
 		// assists tapering off. Don't bother running a worker
@@ -848,14 +763,14 @@
 		return nil, now
 	}
 
-	decIfPositive := func(ptr *int64) bool {
+	decIfPositive := func(val *atomic.Int64) bool {
 		for {
-			v := atomic.Loadint64(ptr)
+			v := val.Load()
 			if v <= 0 {
 				return false
 			}
 
-			if atomic.Casint64(ptr, v, v-1) {
+			if val.CompareAndSwap(v, v-1) {
 				return true
 			}
 		}
@@ -864,7 +779,7 @@
 	if decIfPositive(&c.dedicatedMarkWorkersNeeded) {
 		// This P is now dedicated to marking until the end of
 		// the concurrent mark phase.
-		_p_.gcMarkWorkerMode = gcMarkWorkerDedicatedMode
+		pp.gcMarkWorkerMode = gcMarkWorkerDedicatedMode
 	} else if c.fractionalUtilizationGoal == 0 {
 		// No need for fractional workers.
 		gcBgMarkWorkerPool.push(&node.node)
@@ -875,13 +790,13 @@
 		//
 		// This should be kept in sync with pollFractionalWorkerExit.
 		delta := now - c.markStartTime
-		if delta > 0 && float64(_p_.gcFractionalMarkTime)/float64(delta) > c.fractionalUtilizationGoal {
+		if delta > 0 && float64(pp.gcFractionalMarkTime)/float64(delta) > c.fractionalUtilizationGoal {
 			// Nope. No need to run a fractional worker.
 			gcBgMarkWorkerPool.push(&node.node)
 			return nil, now
 		}
 		// Run a fractional worker.
-		_p_.gcMarkWorkerMode = gcMarkWorkerFractionalMode
+		pp.gcMarkWorkerMode = gcMarkWorkerFractionalMode
 	}
 
 	// Run the background mark worker.
@@ -900,15 +815,15 @@
 // The world must be stopped.
 func (c *gcControllerState) resetLive(bytesMarked uint64) {
 	c.heapMarked = bytesMarked
-	c.heapLive = bytesMarked
-	c.heapScan = uint64(c.heapScanWork.Load())
+	c.heapLive.Store(bytesMarked)
+	c.heapScan.Store(uint64(c.heapScanWork.Load()))
 	c.lastHeapScan = uint64(c.heapScanWork.Load())
-	c.lastStackScan = uint64(c.stackScanWork.Load())
+	c.lastStackScan.Store(uint64(c.stackScanWork.Load()))
 	c.triggered = ^uint64(0) // Reset triggered.
 
 	// heapLive was updated, so emit a trace event.
 	if trace.enabled {
-		traceHeapAlloc()
+		traceHeapAlloc(bytesMarked)
 	}
 }
 
@@ -921,12 +836,12 @@
 func (c *gcControllerState) markWorkerStop(mode gcMarkWorkerMode, duration int64) {
 	switch mode {
 	case gcMarkWorkerDedicatedMode:
-		atomic.Xaddint64(&c.dedicatedMarkTime, duration)
-		atomic.Xaddint64(&c.dedicatedMarkWorkersNeeded, 1)
+		c.dedicatedMarkTime.Add(duration)
+		c.dedicatedMarkWorkersNeeded.Add(1)
 	case gcMarkWorkerFractionalMode:
-		atomic.Xaddint64(&c.fractionalMarkTime, duration)
+		c.fractionalMarkTime.Add(duration)
 	case gcMarkWorkerIdleMode:
-		atomic.Xaddint64(&c.idleMarkTime, duration)
+		c.idleMarkTime.Add(duration)
 		c.removeIdleMarkWorker()
 	default:
 		throw("markWorkerStop: unknown mark worker mode")
@@ -935,17 +850,17 @@
 
 func (c *gcControllerState) update(dHeapLive, dHeapScan int64) {
 	if dHeapLive != 0 {
-		atomic.Xadd64(&gcController.heapLive, dHeapLive)
+		live := gcController.heapLive.Add(dHeapLive)
 		if trace.enabled {
 			// gcController.heapLive changed.
-			traceHeapAlloc()
+			traceHeapAlloc(live)
 		}
 	}
 	if gcBlackenEnabled == 0 {
 		// Update heapScan when we're not in a current GC. It is fixed
 		// at the beginning of a cycle.
 		if dHeapScan != 0 {
-			atomic.Xadd64(&gcController.heapScan, dHeapScan)
+			gcController.heapScan.Add(dHeapScan)
 		}
 	} else {
 		// gcController.heapLive changed.
@@ -955,18 +870,18 @@
 
 func (c *gcControllerState) addScannableStack(pp *p, amount int64) {
 	if pp == nil {
-		atomic.Xadd64(&c.maxStackScan, amount)
+		c.maxStackScan.Add(amount)
 		return
 	}
 	pp.maxStackScanDelta += amount
 	if pp.maxStackScanDelta >= maxStackScanSlack || pp.maxStackScanDelta <= -maxStackScanSlack {
-		atomic.Xadd64(&c.maxStackScan, pp.maxStackScanDelta)
+		c.maxStackScan.Add(pp.maxStackScanDelta)
 		pp.maxStackScanDelta = 0
 	}
 }
 
 func (c *gcControllerState) addGlobals(amount int64) {
-	atomic.Xadd64(&c.globalsScan, amount)
+	c.globalsScan.Add(amount)
 }
 
 // heapGoal returns the current heap goal.
@@ -1260,7 +1175,7 @@
 		// Concurrent sweep happens in the heap growth
 		// from gcController.heapLive to trigger. Make sure we
 		// give the sweeper some runway if it doesn't have enough.
-		c.sweepDistMinTrigger.Store(atomic.Load64(&c.heapLive) + sweepMinHeapDistance)
+		c.sweepDistMinTrigger.Store(c.heapLive.Load() + sweepMinHeapDistance)
 	}
 
 	// Compute the next GC goal, which is when the allocated heap
@@ -1268,7 +1183,7 @@
 	// plus additional runway for non-heap sources of GC work.
 	gcPercentHeapGoal := ^uint64(0)
 	if gcPercent := c.gcPercent.Load(); gcPercent >= 0 {
-		gcPercentHeapGoal = c.heapMarked + (c.heapMarked+atomic.Load64(&c.lastStackScan)+atomic.Load64(&c.globalsScan))*uint64(gcPercent)/100
+		gcPercentHeapGoal = c.heapMarked + (c.heapMarked+c.lastStackScan.Load()+c.globalsScan.Load())*uint64(gcPercent)/100
 	}
 	// Apply the minimum heap size here. It's defined in terms of gcPercent
 	// and is only updated by functions that call commit.
@@ -1300,7 +1215,7 @@
 	// Furthermore, by setting the runway so that CPU resources are divided
 	// this way, assuming that the cons/mark ratio is correct, we make that
 	// division a reality.
-	c.runway.Store(uint64((c.consMark * (1 - gcGoalUtilization) / (gcGoalUtilization)) * float64(c.lastHeapScan+c.lastStackScan+c.globalsScan)))
+	c.runway.Store(uint64((c.consMark * (1 - gcGoalUtilization) / (gcGoalUtilization)) * float64(c.lastHeapScan+c.lastStackScan.Load()+c.globalsScan.Load())))
 }
 
 // setGCPercent updates gcPercent. commit must be called after.
@@ -1335,7 +1250,7 @@
 	// If we just disabled GC, wait for any concurrent GC mark to
 	// finish so we always return with no GC running.
 	if in < 0 {
-		gcWaitOnMark(atomic.Load(&work.cycles))
+		gcWaitOnMark(work.cycles.Load())
 	}
 
 	return out
@@ -1400,74 +1315,6 @@
 	return n
 }
 
-type piController struct {
-	kp float64 // Proportional constant.
-	ti float64 // Integral time constant.
-	tt float64 // Reset time.
-
-	min, max float64 // Output boundaries.
-
-	// PI controller state.
-
-	errIntegral float64 // Integral of the error from t=0 to now.
-
-	// Error flags.
-	errOverflow   bool // Set if errIntegral ever overflowed.
-	inputOverflow bool // Set if an operation with the input overflowed.
-}
-
-// next provides a new sample to the controller.
-//
-// input is the sample, setpoint is the desired point, and period is how much
-// time (in whatever unit makes the most sense) has passed since the last sample.
-//
-// Returns a new value for the variable it's controlling, and whether the operation
-// completed successfully. One reason this might fail is if error has been growing
-// in an unbounded manner, to the point of overflow.
-//
-// In the specific case of an error overflow occurs, the errOverflow field will be
-// set and the rest of the controller's internal state will be fully reset.
-func (c *piController) next(input, setpoint, period float64) (float64, bool) {
-	// Compute the raw output value.
-	prop := c.kp * (setpoint - input)
-	rawOutput := prop + c.errIntegral
-
-	// Clamp rawOutput into output.
-	output := rawOutput
-	if isInf(output) || isNaN(output) {
-		// The input had a large enough magnitude that either it was already
-		// overflowed, or some operation with it overflowed.
-		// Set a flag and reset. That's the safest thing to do.
-		c.reset()
-		c.inputOverflow = true
-		return c.min, false
-	}
-	if output < c.min {
-		output = c.min
-	} else if output > c.max {
-		output = c.max
-	}
-
-	// Update the controller's state.
-	if c.ti != 0 && c.tt != 0 {
-		c.errIntegral += (c.kp*period/c.ti)*(setpoint-input) + (period/c.tt)*(output-rawOutput)
-		if isInf(c.errIntegral) || isNaN(c.errIntegral) {
-			// So much error has accumulated that we managed to overflow.
-			// The assumptions around the controller have likely broken down.
-			// Set a flag and reset. That's the safest thing to do.
-			c.reset()
-			c.errOverflow = true
-			return c.min, false
-		}
-	}
-	return output, true
-}
-
-// reset resets the controller state, except for controller error flags.
-func (c *piController) reset() {
-	c.errIntegral = 0
-}
-
 // addIdleMarkWorker attempts to add a new idle mark worker.
 //
 // If this returns true, the caller must become an idle mark worker unless
diff --git a/src/runtime/mgcpacer_test.go b/src/runtime/mgcpacer_test.go
index 12d885d..e373e32 100644
--- a/src/runtime/mgcpacer_test.go
+++ b/src/runtime/mgcpacer_test.go
@@ -1019,51 +1019,6 @@
 	}
 }
 
-func FuzzPIController(f *testing.F) {
-	isNormal := func(x float64) bool {
-		return !math.IsInf(x, 0) && !math.IsNaN(x)
-	}
-	isPositive := func(x float64) bool {
-		return isNormal(x) && x > 0
-	}
-	// Seed with constants from controllers in the runtime.
-	// It's not critical that we keep these in sync, they're just
-	// reasonable seed inputs.
-	f.Add(0.3375, 3.2e6, 1e9, 0.001, 1000.0, 0.01)
-	f.Add(0.9, 4.0, 1000.0, -1000.0, 1000.0, 0.84)
-	f.Fuzz(func(t *testing.T, kp, ti, tt, min, max, setPoint float64) {
-		// Ignore uninteresting invalid parameters. These parameters
-		// are constant, so in practice surprising values will be documented
-		// or will be other otherwise immediately visible.
-		//
-		// We just want to make sure that given a non-Inf, non-NaN input,
-		// we always get a non-Inf, non-NaN output.
-		if !isPositive(kp) || !isPositive(ti) || !isPositive(tt) {
-			return
-		}
-		if !isNormal(min) || !isNormal(max) || min > max {
-			return
-		}
-		// Use a random source, but make it deterministic.
-		rs := rand.New(rand.NewSource(800))
-		randFloat64 := func() float64 {
-			return math.Float64frombits(rs.Uint64())
-		}
-		p := NewPIController(kp, ti, tt, min, max)
-		state := float64(0)
-		for i := 0; i < 100; i++ {
-			input := randFloat64()
-			// Ignore the "ok" parameter. We're just trying to break it.
-			// state is intentionally completely uncorrelated with the input.
-			var ok bool
-			state, ok = p.Next(input, setPoint, 1.0)
-			if !isNormal(state) {
-				t.Fatalf("got NaN or Inf result from controller: %f %v", state, ok)
-			}
-		}
-	})
-}
-
 func TestIdleMarkWorkerCount(t *testing.T) {
 	const workers = 10
 	c := NewGCController(100, math.MaxInt64)
diff --git a/src/runtime/mgcscavenge.go b/src/runtime/mgcscavenge.go
index bf38f87..e59340e 100644
--- a/src/runtime/mgcscavenge.go
+++ b/src/runtime/mgcscavenge.go
@@ -221,6 +221,16 @@
 	// gcController.memoryLimit by choosing to target the memory limit or
 	// some lower target to keep the scavenger working.
 	memoryLimitGoal atomic.Uint64
+
+	// assistTime is the time spent by the allocator scavenging in the last GC cycle.
+	//
+	// This is reset once a GC cycle ends.
+	assistTime atomic.Int64
+
+	// backgroundTime is the time spent by the background scavenger in the last GC cycle.
+	//
+	// This is reset once a GC cycle ends.
+	backgroundTime atomic.Int64
 }
 
 const (
@@ -361,6 +371,7 @@
 			if start >= end {
 				return r, 0
 			}
+			scavenge.backgroundTime.Add(end - start)
 			return r, end - start
 		}
 	}
@@ -718,7 +729,7 @@
 	if p.summary[len(p.summary)-1][ci].max() >= uint(minPages) {
 		// We only bother looking for a candidate if there at least
 		// minPages free pages at all.
-		base, npages := p.chunkOf(ci).findScavengeCandidate(pallocChunkPages-1, minPages, maxPages)
+		base, npages := p.chunkOf(ci).findScavengeCandidate(searchIdx, minPages, maxPages)
 
 		// If we found something, scavenge it and return!
 		if npages != 0 {
@@ -736,6 +747,8 @@
 			unlock(p.mheapLock)
 
 			if !p.test {
+				pageTraceScav(getg().m.p.ptr(), 0, addr, uintptr(npages))
+
 				// Only perform the actual scavenging if we're not in a test.
 				// It's dangerous to do so otherwise.
 				sysUnused(unsafe.Pointer(addr), uintptr(npages)*pageSize)
@@ -1103,3 +1116,71 @@
 func (s *scavengeIndex) clear(ci chunkIdx) {
 	s.chunks[ci/8].And(^uint8(1 << (ci % 8)))
 }
+
+type piController struct {
+	kp float64 // Proportional constant.
+	ti float64 // Integral time constant.
+	tt float64 // Reset time.
+
+	min, max float64 // Output boundaries.
+
+	// PI controller state.
+
+	errIntegral float64 // Integral of the error from t=0 to now.
+
+	// Error flags.
+	errOverflow   bool // Set if errIntegral ever overflowed.
+	inputOverflow bool // Set if an operation with the input overflowed.
+}
+
+// next provides a new sample to the controller.
+//
+// input is the sample, setpoint is the desired point, and period is how much
+// time (in whatever unit makes the most sense) has passed since the last sample.
+//
+// Returns a new value for the variable it's controlling, and whether the operation
+// completed successfully. One reason this might fail is if error has been growing
+// in an unbounded manner, to the point of overflow.
+//
+// In the specific case of an error overflow occurs, the errOverflow field will be
+// set and the rest of the controller's internal state will be fully reset.
+func (c *piController) next(input, setpoint, period float64) (float64, bool) {
+	// Compute the raw output value.
+	prop := c.kp * (setpoint - input)
+	rawOutput := prop + c.errIntegral
+
+	// Clamp rawOutput into output.
+	output := rawOutput
+	if isInf(output) || isNaN(output) {
+		// The input had a large enough magnitude that either it was already
+		// overflowed, or some operation with it overflowed.
+		// Set a flag and reset. That's the safest thing to do.
+		c.reset()
+		c.inputOverflow = true
+		return c.min, false
+	}
+	if output < c.min {
+		output = c.min
+	} else if output > c.max {
+		output = c.max
+	}
+
+	// Update the controller's state.
+	if c.ti != 0 && c.tt != 0 {
+		c.errIntegral += (c.kp*period/c.ti)*(setpoint-input) + (period/c.tt)*(output-rawOutput)
+		if isInf(c.errIntegral) || isNaN(c.errIntegral) {
+			// So much error has accumulated that we managed to overflow.
+			// The assumptions around the controller have likely broken down.
+			// Set a flag and reset. That's the safest thing to do.
+			c.reset()
+			c.errOverflow = true
+			return c.min, false
+		}
+	}
+	return output, true
+}
+
+// reset resets the controller state, except for controller error flags.
+func (c *piController) reset() {
+	c.errIntegral = 0
+}
diff --git a/src/runtime/mgcscavenge_test.go b/src/runtime/mgcscavenge_test.go
index 620392f..c436ff0 100644
--- a/src/runtime/mgcscavenge_test.go
+++ b/src/runtime/mgcscavenge_test.go
@@ -7,6 +7,7 @@
 import (
 	"fmt"
 	"internal/goos"
+	"math"
 	"math/rand"
 	. "runtime"
 	"runtime/internal/atomic"
@@ -707,3 +708,48 @@
 		find(0, 0)
 	})
 }
+
+func FuzzPIController(f *testing.F) {
+	isNormal := func(x float64) bool {
+		return !math.IsInf(x, 0) && !math.IsNaN(x)
+	}
+	isPositive := func(x float64) bool {
+		return isNormal(x) && x > 0
+	}
+	// Seed with constants from controllers in the runtime.
+	// It's not critical that we keep these in sync, they're just
+	// reasonable seed inputs.
+	f.Add(0.3375, 3.2e6, 1e9, 0.001, 1000.0, 0.01)
+	f.Add(0.9, 4.0, 1000.0, -1000.0, 1000.0, 0.84)
+	f.Fuzz(func(t *testing.T, kp, ti, tt, min, max, setPoint float64) {
+		// Ignore uninteresting invalid parameters. These parameters
+		// are constant, so in practice surprising values will be documented
+		// or will be other otherwise immediately visible.
+		//
+		// We just want to make sure that given a non-Inf, non-NaN input,
+		// we always get a non-Inf, non-NaN output.
+		if !isPositive(kp) || !isPositive(ti) || !isPositive(tt) {
+			return
+		}
+		if !isNormal(min) || !isNormal(max) || min > max {
+			return
+		}
+		// Use a random source, but make it deterministic.
+		rs := rand.New(rand.NewSource(800))
+		randFloat64 := func() float64 {
+			return math.Float64frombits(rs.Uint64())
+		}
+		p := NewPIController(kp, ti, tt, min, max)
+		state := float64(0)
+		for i := 0; i < 100; i++ {
+			input := randFloat64()
+			// Ignore the "ok" parameter. We're just trying to break it.
+			// state is intentionally completely uncorrelated with the input.
+			var ok bool
+			state, ok = p.Next(input, setPoint, 1.0)
+			if !isNormal(state) {
+				t.Fatalf("got NaN or Inf result from controller: %f %v", state, ok)
+			}
+		}
+	})
+}
diff --git a/src/runtime/mgcstack.go b/src/runtime/mgcstack.go
index 472c61a..6b55220 100644
--- a/src/runtime/mgcstack.go
+++ b/src/runtime/mgcstack.go
@@ -96,6 +96,7 @@
 
 import (
 	"internal/goarch"
+	"runtime/internal/sys"
 	"unsafe"
 )
 
@@ -103,17 +104,15 @@
 
 // Buffer for pointers found during stack tracing.
 // Must be smaller than or equal to workbuf.
-//
-//go:notinheap
 type stackWorkBuf struct {
+	_ sys.NotInHeap
 	stackWorkBufHdr
 	obj [(_WorkbufSize - unsafe.Sizeof(stackWorkBufHdr{})) / goarch.PtrSize]uintptr
 }
 
 // Header declaration must come after the buf declaration above, because of issue #14620.
-//
-//go:notinheap
 type stackWorkBufHdr struct {
+	_ sys.NotInHeap
 	workbufhdr
 	next *stackWorkBuf // linked list of workbufs
 	// Note: we could theoretically repurpose lfnode.next as this next pointer.
@@ -123,15 +122,14 @@
 
 // Buffer for stack objects found on a goroutine stack.
 // Must be smaller than or equal to workbuf.
-//
-//go:notinheap
 type stackObjectBuf struct {
+	_ sys.NotInHeap
 	stackObjectBufHdr
 	obj [(_WorkbufSize - unsafe.Sizeof(stackObjectBufHdr{})) / unsafe.Sizeof(stackObject{})]stackObject
 }
 
-//go:notinheap
 type stackObjectBufHdr struct {
+	_ sys.NotInHeap
 	workbufhdr
 	next *stackObjectBuf
 }
@@ -147,9 +145,8 @@
 
 // A stackObject represents a variable on the stack that has had
 // its address taken.
-//
-//go:notinheap
 type stackObject struct {
+	_     sys.NotInHeap
 	off   uint32             // offset above stack.lo
 	size  uint32             // size of object
 	r     *stackObjectRecord // info of the object (for ptr/nonptr bits). nil if object has been scanned.
diff --git a/src/runtime/mgcsweep.go b/src/runtime/mgcsweep.go
index de57f18..6ccf090 100644
--- a/src/runtime/mgcsweep.go
+++ b/src/runtime/mgcsweep.go
@@ -33,10 +33,9 @@
 
 // State of background sweep.
 type sweepdata struct {
-	lock    mutex
-	g       *g
-	parked  bool
-	started bool
+	lock   mutex
+	g      *g
+	parked bool
 
 	nbgsweep    uint32
 	npausesweep uint32
@@ -177,7 +176,8 @@
 				return
 			}
 			if debug.gcpacertrace > 0 {
-				print("pacer: sweep done at heap size ", gcController.heapLive>>20, "MB; allocated ", (gcController.heapLive-mheap_.sweepHeapLiveBasis)>>20, "MB during sweep; swept ", mheap_.pagesSwept.Load(), " pages at ", mheap_.sweepPagesPerByte, " pages/byte\n")
+				live := gcController.heapLive.Load()
+				print("pacer: sweep done at heap size ", live>>20, "MB; allocated ", (live-mheap_.sweepHeapLiveBasis)>>20, "MB during sweep; swept ", mheap_.pagesSwept.Load(), " pages at ", mheap_.sweepPagesPerByte, " pages/byte\n")
 			}
 			return
 		}
@@ -278,12 +278,34 @@
 	goparkunlock(&sweep.lock, waitReasonGCSweepWait, traceEvGoBlock, 1)
 
 	for {
+		// bgsweep attempts to be a "low priority" goroutine by intentionally
+		// yielding time. It's OK if it doesn't run, because goroutines allocating
+		// memory will sweep and ensure that all spans are swept before the next
+		// GC cycle. We really only want to run when we're idle.
+		//
+		// However, calling Gosched after each span swept produces a tremendous
+		// amount of tracing events, sometimes up to 50% of events in a trace. It's
+		// also inefficient to call into the scheduler so much because sweeping a
+		// single span is in general a very fast operation, taking as little as 30 ns
+		// on modern hardware. (See #54767.)
+		//
+		// As a result, bgsweep sweeps in batches, and only calls into the scheduler
+		// at the end of every batch. Furthermore, it only yields its time if there
+		// isn't spare idle time available on other cores. If there's available idle
+		// time, helping to sweep can reduce allocation latencies by getting ahead of
+		// the proportional sweeper and having spans ready to go for allocation.
+		const sweepBatchSize = 10
+		nSwept := 0
 		for sweepone() != ^uintptr(0) {
 			sweep.nbgsweep++
-			Gosched()
+			nSwept++
+			if nSwept%sweepBatchSize == 0 {
+				goschedIfBusy()
+			}
 		}
 		for freeSomeWbufs(true) {
-			Gosched()
+			// N.B. freeSomeWbufs is already batched internally.
+			goschedIfBusy()
 		}
 		lock(&sweep.lock)
 		if !isSweepDone() {
@@ -431,8 +453,8 @@
 	// Caller must disable preemption.
 	// Otherwise when this function returns the span can become unswept again
 	// (if GC is triggered on another goroutine).
-	_g_ := getg()
-	if _g_.m.locks == 0 && _g_.m.mallocing == 0 && _g_ != _g_.m.g0 {
+	gp := getg()
+	if gp.m.locks == 0 && gp.m.mallocing == 0 && gp != gp.m.g0 {
 		throw("mspan.ensureSwept: m is not locked")
 	}
 
@@ -470,8 +492,8 @@
 func (sl *sweepLocked) sweep(preserve bool) bool {
 	// It's critical that we enter this function with preemption disabled,
 	// GC must not start while we are in the middle of this function.
-	_g_ := getg()
-	if _g_.m.locks == 0 && _g_.m.mallocing == 0 && _g_ != _g_.m.g0 {
+	gp := getg()
+	if gp.m.locks == 0 && gp.m.mallocing == 0 && gp != gp.m.g0 {
 		throw("mspan.sweep: m is not locked")
 	}
 
@@ -579,13 +601,14 @@
 				if debug.clobberfree != 0 {
 					clobberfree(unsafe.Pointer(x), size)
 				}
-				if raceenabled {
+				// User arenas are handled on explicit free.
+				if raceenabled && !s.isUserArenaChunk {
 					racefree(unsafe.Pointer(x), size)
 				}
-				if msanenabled {
+				if msanenabled && !s.isUserArenaChunk {
 					msanfree(unsafe.Pointer(x), size)
 				}
-				if asanenabled {
+				if asanenabled && !s.isUserArenaChunk {
 					asanpoison(unsafe.Pointer(x), size)
 				}
 			}
@@ -625,6 +648,7 @@
 
 	s.allocCount = nalloc
 	s.freeindex = 0 // reset allocation index to start of span.
+	s.freeIndexForScan = 0
 	if trace.enabled {
 		getg().m.p.ptr().traceReclaimed += uintptr(nfreed) * s.elemsize
 	}
@@ -659,6 +683,41 @@
 	// to go so release the span.
 	atomic.Store(&s.sweepgen, sweepgen)
 
+	if s.isUserArenaChunk {
+		if preserve {
+			// This is a case that should never be handled by a sweeper that
+			// preserves the span for reuse.
+			throw("sweep: tried to preserve a user arena span")
+		}
+		if nalloc > 0 {
+			// There still exist pointers into the span or the span hasn't been
+			// freed yet. It's not ready to be reused. Put it back on the
+			// full swept list for the next cycle.
+			mheap_.central[spc].mcentral.fullSwept(sweepgen).push(s)
+			return false
+		}
+
+		// It's only at this point that the sweeper doesn't actually need to look
+		// at this arena anymore, so subtract from pagesInUse now.
+		mheap_.pagesInUse.Add(-s.npages)
+		s.state.set(mSpanDead)
+
+		// The arena is ready to be recycled. Remove it from the quarantine list
+		// and place it on the ready list. Don't add it back to any sweep lists.
+		systemstack(func() {
+			// It's the arena code's responsibility to get the chunk on the quarantine
+			// list by the time all references to the chunk are gone.
+			if s.list != &mheap_.userArena.quarantineList {
+				throw("user arena span is on the wrong list")
+			}
+			lock(&mheap_.lock)
+			mheap_.userArena.quarantineList.remove(s)
+			mheap_.userArena.readyList.insert(s)
+			unlock(&mheap_.lock)
+		})
+		return false
+	}
+
 	if spc.sizeclass() != 0 {
 		// Handle spans for small objects.
 		if nfreed > 0 {
@@ -814,11 +873,30 @@
 		traceGCSweepStart()
 	}
 
+	// Fix debt if necessary.
 retry:
 	sweptBasis := mheap_.pagesSweptBasis.Load()
-
-	// Fix debt if necessary.
-	newHeapLive := uintptr(atomic.Load64(&gcController.heapLive)-mheap_.sweepHeapLiveBasis) + spanBytes
+	live := gcController.heapLive.Load()
+	liveBasis := mheap_.sweepHeapLiveBasis
+	newHeapLive := spanBytes
+	if liveBasis < live {
+		// Only do this subtraction when we don't overflow. Otherwise, pagesTarget
+		// might be computed as something really huge, causing us to get stuck
+		// sweeping here until the next mark phase.
+		//
+		// Overflow can happen here if gcPaceSweeper is called concurrently with
+		// sweeping (i.e. not during a STW, like it usually is) because this code
+		// is intentionally racy. A concurrent call to gcPaceSweeper can happen
+		// if a GC tuning parameter is modified and we read an older value of
+		// heapLive than what was used to set the basis.
+		//
+		// This state should be transient, so it's fine to just let newHeapLive
+		// be a relatively small number. We'll probably just skip this attempt to
+		// sweep.
+		//
+		// See issue #57523.
+		newHeapLive += uintptr(live - liveBasis)
+	}
 	pagesTarget := int64(mheap_.sweepPagesPerByte*float64(newHeapLive)) - int64(callerSweepPages)
 	for pagesTarget > int64(mheap_.pagesSwept.Load()-sweptBasis) {
 		if sweepone() == ^uintptr(0) {
@@ -862,7 +940,7 @@
 		// trigger. Compute the ratio of in-use pages to sweep
 		// per byte allocated, accounting for the fact that
 		// some might already be swept.
-		heapLiveBasis := atomic.Load64(&gcController.heapLive)
+		heapLiveBasis := gcController.heapLive.Load()
 		heapDistance := int64(trigger) - int64(heapLiveBasis)
 		// Add a little margin so rounding errors and
 		// concurrent sweep are less likely to leave pages
diff --git a/src/runtime/mgcwork.go b/src/runtime/mgcwork.go
index 424de2f..7ab8975 100644
--- a/src/runtime/mgcwork.go
+++ b/src/runtime/mgcwork.go
@@ -7,6 +7,7 @@
 import (
 	"internal/goarch"
 	"runtime/internal/atomic"
+	"runtime/internal/sys"
 	"unsafe"
 )
 
@@ -320,8 +321,8 @@
 	nobj int
 }
 
-//go:notinheap
 type workbuf struct {
+	_ sys.NotInHeap
 	workbufhdr
 	// account for the above fields
 	obj [(_WorkbufSize - unsafe.Sizeof(workbufhdr{})) / goarch.PtrSize]uintptr
@@ -420,7 +421,7 @@
 }
 
 // trygetfull tries to get a full or partially empty workbuffer.
-// If one is not immediately available return nil
+// If one is not immediately available return nil.
 //
 //go:nowritebarrier
 func trygetfull() *workbuf {
diff --git a/src/runtime/mheap.go b/src/runtime/mheap.go
index b19a2ff..1401e92 100644
--- a/src/runtime/mheap.go
+++ b/src/runtime/mheap.go
@@ -12,6 +12,7 @@
 	"internal/cpu"
 	"internal/goarch"
 	"runtime/internal/atomic"
+	"runtime/internal/sys"
 	"unsafe"
 )
 
@@ -57,15 +58,13 @@
 //
 // mheap must not be heap-allocated because it contains mSpanLists,
 // which must not be heap-allocated.
-//
-//go:notinheap
 type mheap struct {
+	_ sys.NotInHeap
+
 	// lock must only be acquired on the system stack, otherwise a g
 	// could self-deadlock if its stack grows with the lock held.
 	lock mutex
 
-	_ uint32 // 8-byte align pages so its alignment is consistent with tests.
-
 	pages pageAlloc // page allocation data structure
 
 	sweepgen uint32 // sweep generation, see comment in mspan; written during STW
@@ -83,8 +82,6 @@
 	// access (since that may free the backing store).
 	allspans []*mspan // all spans out there
 
-	// _ uint32 // align uint64 fields on 32-bit for atomics
-
 	// Proportional sweep
 	//
 	// These parameters represent a linear function from gcController.heapLive
@@ -103,13 +100,11 @@
 	// accounting for current progress. If we could only adjust
 	// the slope, it would create a discontinuity in debt if any
 	// progress has already been made.
-	pagesInUse         atomic.Uint64 // pages of spans in stats mSpanInUse
-	pagesSwept         atomic.Uint64 // pages swept this cycle
-	pagesSweptBasis    atomic.Uint64 // pagesSwept to use as the origin of the sweep ratio
-	sweepHeapLiveBasis uint64        // value of gcController.heapLive to use as the origin of sweep ratio; written with lock, read without
-	sweepPagesPerByte  float64       // proportional sweep ratio; written with lock, read without
-	// TODO(austin): pagesInUse should be a uintptr, but the 386
-	// compiler can't 8-byte align fields.
+	pagesInUse         atomic.Uintptr // pages of spans in stats mSpanInUse
+	pagesSwept         atomic.Uint64  // pages swept this cycle
+	pagesSweptBasis    atomic.Uint64  // pagesSwept to use as the origin of the sweep ratio
+	sweepHeapLiveBasis uint64         // value of gcController.heapLive to use as the origin of sweep ratio; written with lock, read without
+	sweepPagesPerByte  float64        // proportional sweep ratio; written with lock, read without
 
 	// Page reclaimer state
 
@@ -190,8 +185,6 @@
 		base, end uintptr
 	}
 
-	_ uint32 // ensure 64-bit alignment of central
-
 	// central free lists for small size classes.
 	// the padding makes sure that the mcentrals are
 	// spaced CacheLinePadSize bytes apart, so that each mcentral.lock
@@ -199,7 +192,7 @@
 	// central is indexed by spanClass.
 	central [numSpanClasses]struct {
 		mcentral mcentral
-		pad      [cpu.CacheLinePadSize - unsafe.Sizeof(mcentral{})%cpu.CacheLinePadSize]byte
+		pad      [(cpu.CacheLinePadSize - unsafe.Sizeof(mcentral{})%cpu.CacheLinePadSize) % cpu.CacheLinePadSize]byte
 	}
 
 	spanalloc             fixalloc // allocator for span*
@@ -210,6 +203,25 @@
 	speciallock           mutex    // lock for special record allocators.
 	arenaHintAlloc        fixalloc // allocator for arenaHints
 
+	// User arena state.
+	//
+	// Protected by mheap_.lock.
+	userArena struct {
+		// arenaHints is a list of addresses at which to attempt to
+		// add more heap arenas for user arena chunks. This is initially
+		// populated with a set of general hint addresses, and grown with
+		// the bounds of actual heap arena ranges.
+		arenaHints *arenaHint
+
+		// quarantineList is a list of user arena spans that have been set to fault, but
+		// are waiting for all pointers into them to go away. Sweeping handles
+		// identifying when this is true, and moves the span to the ready list.
+		quarantineList mSpanList
+
+		// readyList is a list of empty user arena spans that are ready for reuse.
+		readyList mSpanList
+	}
+
 	unused *specialfinalizer // never set, just here to force the specialfinalizer type into DWARF
 }
 
@@ -217,13 +229,26 @@
 
 // A heapArena stores metadata for a heap arena. heapArenas are stored
 // outside of the Go heap and accessed via the mheap_.arenas index.
-//
-//go:notinheap
 type heapArena struct {
+	_ sys.NotInHeap
+
 	// bitmap stores the pointer/scalar bitmap for the words in
-	// this arena. See mbitmap.go for a description. Use the
-	// heapBits type to access this.
-	bitmap [heapArenaBitmapBytes]byte
+	// this arena. See mbitmap.go for a description.
+	// This array uses 1 bit per word of heap, or 1.6% of the heap size (for 64-bit).
+	bitmap [heapArenaBitmapWords]uintptr
+
+	// If the ith bit of noMorePtrs is true, then there are no more
+	// pointers for the object containing the word described by the
+	// high bit of bitmap[i].
+	// In that case, bitmap[i+1], ... must be zero until the start
+	// of the next object.
+	// We never operate on these entries using bit-parallel techniques,
+	// so it is ok if they are small. Also, they can't be bigger than
+	// uint16 because at that size a single noMorePtrs entry
+	// represents 8K of memory, the minimum size of a span. Any larger
+	// and we'd have to worry about concurrent updates.
+	// This array uses 1 bit per word of bitmap, or .024% of the heap size (for 64-bit).
+	noMorePtrs [heapArenaBitmapWords / 8]uint8
 
 	// spans maps from virtual address page ID within this arena to *mspan.
 	// For allocated spans, their pages map to the span itself.
@@ -290,9 +315,8 @@
 
 // arenaHint is a hint for where to grow the heap arenas. See
 // mheap_.arenaHints.
-//
-//go:notinheap
 type arenaHint struct {
+	_    sys.NotInHeap
 	addr uintptr
 	down bool
 	next *arenaHint
@@ -347,34 +371,39 @@
 	"mSpanDead",
 	"mSpanInUse",
 	"mSpanManual",
-	"mSpanFree",
 }
 
-// mSpanStateBox holds an mSpanState and provides atomic operations on
-// it. This is a separate type to disallow accidental comparison or
-// assignment with mSpanState.
+// mSpanStateBox holds an atomic.Uint8 to provide atomic operations on
+// an mSpanState. This is a separate type to disallow accidental comparison
+// or assignment with mSpanState.
 type mSpanStateBox struct {
-	s mSpanState
+	s atomic.Uint8
 }
 
+// It is nosplit to match get, below.
+
+//go:nosplit
 func (b *mSpanStateBox) set(s mSpanState) {
-	atomic.Store8((*uint8)(&b.s), uint8(s))
+	b.s.Store(uint8(s))
 }
 
+// It is nosplit because it's called indirectly by typedmemclr,
+// which must not be preempted.
+
+//go:nosplit
 func (b *mSpanStateBox) get() mSpanState {
-	return mSpanState(atomic.Load8((*uint8)(&b.s)))
+	return mSpanState(b.s.Load())
 }
 
 // mSpanList heads a linked list of spans.
-//
-//go:notinheap
 type mSpanList struct {
+	_     sys.NotInHeap
 	first *mspan // first span in list, or nil if none
 	last  *mspan // last span in list, or nil if none
 }
 
-//go:notinheap
 type mspan struct {
+	_    sys.NotInHeap
 	next *mspan     // next span in list, or nil if none
 	prev *mspan     // previous span in list, or nil if none
 	list *mSpanList // For debugging. TODO: Remove.
@@ -451,11 +480,21 @@
 	spanclass             spanClass     // size class and noscan (uint8)
 	state                 mSpanStateBox // mSpanInUse etc; accessed atomically (get/set methods)
 	needzero              uint8         // needs to be zeroed before allocation
+	isUserArenaChunk      bool          // whether or not this span represents a user arena
 	allocCountBeforeCache uint16        // a copy of allocCount that is stored just before this span is cached
 	elemsize              uintptr       // computed from sizeclass or from npages
 	limit                 uintptr       // end of data in span
 	speciallock           mutex         // guards specials list
 	specials              *special      // linked list of special records sorted by offset.
+	userArenaChunkFree    addrRange     // interval for managing chunk allocation
+
+	// freeIndexForScan is like freeindex, except that freeindex is
+	// used by the allocator whereas freeIndexForScan is used by the
+	// GC scanner. They are two fields so that the GC sees the object
+	// is allocated only when the object and the heap bits are
+	// initialized (see also the assignment of freeIndexForScan in
+	// mallocgc, and issue 54596).
+	freeIndexForScan uintptr
 }
 
 func (s *mspan) base() uintptr {
@@ -565,6 +604,12 @@
 
 type arenaIdx uint
 
+// l1 returns the "l1" portion of an arenaIdx.
+//
+// Marked nosplit because it's called by spanOf and other nosplit
+// functions.
+//
+//go:nosplit
 func (i arenaIdx) l1() uint {
 	if arenaL1Bits == 0 {
 		// Let the compiler optimize this away if there's no
@@ -575,6 +620,12 @@
 	}
 }
 
+// l2 returns the "l2" portion of an arenaIdx.
+//
+// Marked nosplit because it's called by spanOf and other nosplit funcs.
+// functions.
+//
+//go:nosplit
 func (i arenaIdx) l2() uint {
 	if arenaL1Bits == 0 {
 		return uint(i)
@@ -1183,6 +1234,7 @@
 		base = alignUp(base, physPageSize)
 		scav = h.pages.allocRange(base, npages)
 	}
+
 	if base == 0 {
 		// Try to acquire a base address.
 		base, scav = h.pages.alloc(npages)
@@ -1207,56 +1259,6 @@
 	unlock(&h.lock)
 
 HaveSpan:
-	// At this point, both s != nil and base != 0, and the heap
-	// lock is no longer held. Initialize the span.
-	s.init(base, npages)
-	if h.allocNeedsZero(base, npages) {
-		s.needzero = 1
-	}
-	nbytes := npages * pageSize
-	if typ.manual() {
-		s.manualFreeList = 0
-		s.nelems = 0
-		s.limit = s.base() + s.npages*pageSize
-		s.state.set(mSpanManual)
-	} else {
-		// We must set span properties before the span is published anywhere
-		// since we're not holding the heap lock.
-		s.spanclass = spanclass
-		if sizeclass := spanclass.sizeclass(); sizeclass == 0 {
-			s.elemsize = nbytes
-			s.nelems = 1
-			s.divMul = 0
-		} else {
-			s.elemsize = uintptr(class_to_size[sizeclass])
-			s.nelems = nbytes / s.elemsize
-			s.divMul = class_to_divmagic[sizeclass]
-		}
-
-		// Initialize mark and allocation structures.
-		s.freeindex = 0
-		s.allocCache = ^uint64(0) // all 1s indicating all free.
-		s.gcmarkBits = newMarkBits(s.nelems)
-		s.allocBits = newAllocBits(s.nelems)
-
-		// It's safe to access h.sweepgen without the heap lock because it's
-		// only ever updated with the world stopped and we run on the
-		// systemstack which blocks a STW transition.
-		atomic.Store(&s.sweepgen, h.sweepgen)
-
-		// Now that the span is filled in, set its state. This
-		// is a publication barrier for the other fields in
-		// the span. While valid pointers into this span
-		// should never be visible until the span is returned,
-		// if the garbage collector finds an invalid pointer,
-		// access to the span may race with initialization of
-		// the span. We resolve this race by atomically
-		// setting the state after the span is fully
-		// initialized, and atomically checking the state in
-		// any situation where a pointer is suspect.
-		s.state.set(mSpanInUse)
-	}
-
 	// Decide if we need to scavenge in response to what we just allocated.
 	// Specifically, we track the maximum amount of memory to scavenge of all
 	// the alternatives below, assuming that the maximum satisfies *all*
@@ -1304,6 +1306,7 @@
 	// There are a few very limited cirumstances where we won't have a P here.
 	// It's OK to simply skip scavenging in these cases. Something else will notice
 	// and pick up the tab.
+	var now int64
 	if pp != nil && bytesToScavenge > 0 {
 		// Measure how long we spent scavenging and add that measurement to the assist
 		// time so we can track it for the GC CPU limiter.
@@ -1319,14 +1322,18 @@
 		})
 
 		// Finish up accounting.
-		now := nanotime()
+		now = nanotime()
 		if track {
 			pp.limiterEvent.stop(limiterEventScavengeAssist, now)
 		}
-		h.pages.scav.assistTime.Add(now - start)
+		scavenge.assistTime.Add(now - start)
 	}
 
+	// Initialize the span.
+	h.initSpan(s, typ, spanclass, base, npages)
+
 	// Commit and account for any scavenged memory that the span now owns.
+	nbytes := npages * pageSize
 	if scav != 0 {
 		// sysUsed all the pages that are actually available
 		// in the span since some of them might be scavenged.
@@ -1354,6 +1361,64 @@
 	}
 	memstats.heapStats.release()
 
+	pageTraceAlloc(pp, now, base, npages)
+	return s
+}
+
+// initSpan initializes a blank span s which will represent the range
+// [base, base+npages*pageSize). typ is the type of span being allocated.
+func (h *mheap) initSpan(s *mspan, typ spanAllocType, spanclass spanClass, base, npages uintptr) {
+	// At this point, both s != nil and base != 0, and the heap
+	// lock is no longer held. Initialize the span.
+	s.init(base, npages)
+	if h.allocNeedsZero(base, npages) {
+		s.needzero = 1
+	}
+	nbytes := npages * pageSize
+	if typ.manual() {
+		s.manualFreeList = 0
+		s.nelems = 0
+		s.limit = s.base() + s.npages*pageSize
+		s.state.set(mSpanManual)
+	} else {
+		// We must set span properties before the span is published anywhere
+		// since we're not holding the heap lock.
+		s.spanclass = spanclass
+		if sizeclass := spanclass.sizeclass(); sizeclass == 0 {
+			s.elemsize = nbytes
+			s.nelems = 1
+			s.divMul = 0
+		} else {
+			s.elemsize = uintptr(class_to_size[sizeclass])
+			s.nelems = nbytes / s.elemsize
+			s.divMul = class_to_divmagic[sizeclass]
+		}
+
+		// Initialize mark and allocation structures.
+		s.freeindex = 0
+		s.freeIndexForScan = 0
+		s.allocCache = ^uint64(0) // all 1s indicating all free.
+		s.gcmarkBits = newMarkBits(s.nelems)
+		s.allocBits = newAllocBits(s.nelems)
+
+		// It's safe to access h.sweepgen without the heap lock because it's
+		// only ever updated with the world stopped and we run on the
+		// systemstack which blocks a STW transition.
+		atomic.Store(&s.sweepgen, h.sweepgen)
+
+		// Now that the span is filled in, set its state. This
+		// is a publication barrier for the other fields in
+		// the span. While valid pointers into this span
+		// should never be visible until the span is returned,
+		// if the garbage collector finds an invalid pointer,
+		// access to the span may race with initialization of
+		// the span. We resolve this race by atomically
+		// setting the state after the span is fully
+		// initialized, and atomically checking the state in
+		// any situation where a pointer is suspect.
+		s.state.set(mSpanInUse)
+	}
+
 	// Publish the span in various locations.
 
 	// This is safe to call without the lock held because the slots
@@ -1373,14 +1438,12 @@
 		atomic.Or8(&arena.pageInUse[pageIdx], pageMask)
 
 		// Update related page sweeper stats.
-		h.pagesInUse.Add(int64(npages))
+		h.pagesInUse.Add(npages)
 	}
 
 	// Make sure the newly allocated span will be observed
 	// by the GC before pointers into the span are published.
 	publicationBarrier()
-
-	return s
 }
 
 // Try to add at least npage pages of memory to the heap,
@@ -1406,7 +1469,7 @@
 		// Not enough room in the current arena. Allocate more
 		// arena space. This may not be contiguous with the
 		// current arena, so we have to request the full ask.
-		av, asize := h.sysAlloc(ask)
+		av, asize := h.sysAlloc(ask, &h.arenaHints, true)
 		if av == nil {
 			inUse := gcController.heapFree.load() + gcController.heapReleased.load() + gcController.heapInUse.load()
 			print("runtime: out of memory: cannot allocate ", ask, "-byte block (", inUse, " in use)\n")
@@ -1474,6 +1537,8 @@
 // Free the span back into the heap.
 func (h *mheap) freeSpan(s *mspan) {
 	systemstack(func() {
+		pageTraceFree(getg().m.p.ptr(), 0, s.base(), s.npages)
+
 		lock(&h.lock)
 		if msanenabled {
 			// Tell msan that this entire span is no longer in use.
@@ -1504,6 +1569,8 @@
 //
 //go:systemstack
 func (h *mheap) freeManual(s *mspan, typ spanAllocType) {
+	pageTraceFree(getg().m.p.ptr(), 0, s.base(), s.npages)
+
 	s.needzero = 1
 	lock(&h.lock)
 	h.freeSpanLocked(s, typ)
@@ -1519,11 +1586,14 @@
 			throw("mheap.freeSpanLocked - invalid stack free")
 		}
 	case mSpanInUse:
+		if s.isUserArenaChunk {
+			throw("mheap.freeSpanLocked - invalid free of user arena chunk")
+		}
 		if s.allocCount != 0 || s.sweepgen != h.sweepgen {
 			print("mheap.freeSpanLocked - span ", s, " ptr ", hex(s.base()), " allocCount ", s.allocCount, " sweepgen ", s.sweepgen, "/", h.sweepgen, "\n")
 			throw("mheap.freeSpanLocked - invalid free")
 		}
-		h.pagesInUse.Add(-int64(s.npages))
+		h.pagesInUse.Add(-s.npages)
 
 		// Clear in-use bit in arena page bitmap.
 		arena, pageIdx, pageMask := pageIndexOf(s.base())
@@ -1602,6 +1672,7 @@
 	span.specials = nil
 	span.needzero = 0
 	span.freeindex = 0
+	span.freeIndexForScan = 0
 	span.allocBits = nil
 	span.gcmarkBits = nil
 	span.state.set(mSpanDead)
@@ -1715,8 +1786,8 @@
 	// if that happens.
 )
 
-//go:notinheap
 type special struct {
+	_      sys.NotInHeap
 	next   *special // linked list in span
 	offset uint16   // span offset of object
 	kind   byte     // kind of special
@@ -1836,9 +1907,8 @@
 //
 // specialfinalizer is allocated from non-GC'd memory, so any heap
 // pointers must be specially handled.
-//
-//go:notinheap
 type specialfinalizer struct {
+	_       sys.NotInHeap
 	special special
 	fn      *funcval // May be a heap pointer.
 	nret    uintptr
@@ -1862,12 +1932,14 @@
 		// situation where it's possible that markrootSpans
 		// has already run but mark termination hasn't yet.
 		if gcphase != _GCoff {
-			base, _, _ := findObject(uintptr(p), 0, 0)
+			base, span, _ := findObject(uintptr(p), 0, 0)
 			mp := acquirem()
 			gcw := &mp.p.ptr().gcw
 			// Mark everything reachable from the object
 			// so it's retained for the finalizer.
-			scanobject(base, gcw)
+			if !span.spanclass.noscan() {
+				scanobject(base, gcw)
+			}
 			// Mark the finalizer itself, since the
 			// special isn't part of the GC'd heap.
 			scanblock(uintptr(unsafe.Pointer(&s.fn)), goarch.PtrSize, &oneptrmask[0], gcw, nil)
@@ -1895,9 +1967,8 @@
 }
 
 // The described object is being heap profiled.
-//
-//go:notinheap
 type specialprofile struct {
+	_       sys.NotInHeap
 	special special
 	b       *bucket
 }
@@ -1976,14 +2047,15 @@
 	}
 }
 
-// gcBits is an alloc/mark bitmap. This is always used as *gcBits.
-//
-//go:notinheap
-type gcBits uint8
+// gcBits is an alloc/mark bitmap. This is always used as gcBits.x.
+type gcBits struct {
+	_ sys.NotInHeap
+	x uint8
+}
 
 // bytep returns a pointer to the n'th byte of b.
 func (b *gcBits) bytep(n uintptr) *uint8 {
-	return addb((*uint8)(b), n)
+	return addb(&b.x, n)
 }
 
 // bitp returns a pointer to the byte containing bit n and a mask for
@@ -2000,8 +2072,8 @@
 	next uintptr // *gcBits triggers recursive type bug. (issue 14620)
 }
 
-//go:notinheap
 type gcBitsArena struct {
+	_ sys.NotInHeap
 	// gcBitsHeader // side step recursive type bug (issue 14620) by including fields by hand.
 	free uintptr // free is the index into bits of the next free byte; read/write atomically
 	next *gcBitsArena
diff --git a/src/runtime/mklockrank.go b/src/runtime/mklockrank.go
new file mode 100644
index 0000000..bc15e57
--- /dev/null
+++ b/src/runtime/mklockrank.go
@@ -0,0 +1,366 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build ignore
+
+// mklockrank records the static rank graph of the locks in the
+// runtime and generates the rank checking structures in lockrank.go.
+package main
+
+import (
+	"bytes"
+	"flag"
+	"fmt"
+	"go/format"
+	"internal/dag"
+	"io"
+	"log"
+	"os"
+	"strings"
+)
+
+// ranks describes the lock rank graph. See "go doc internal/dag" for
+// the syntax.
+//
+// "a < b" means a must be acquired before b if both are held
+// (or, if b is held, a cannot be acquired).
+//
+// "NONE < a" means no locks may be held when a is acquired.
+//
+// If a lock is not given a rank, then it is assumed to be a leaf
+// lock, which means no other lock can be acquired while it is held.
+// Therefore, leaf locks do not need to be given an explicit rank.
+//
+// Ranks in all caps are pseudo-nodes that help define order, but do
+// not actually define a rank.
+//
+// TODO: It's often hard to correlate rank names to locks. Change
+// these to be more consistent with the locks they label.
+const ranks = `
+# Sysmon
+NONE
+< sysmon
+< scavenge, forcegc;
+
+# Defer
+NONE < defer;
+
+# GC
+NONE <
+  sweepWaiters,
+  assistQueue,
+  sweep;
+
+# Scheduler, timers, netpoll
+NONE < pollDesc, cpuprof;
+assistQueue,
+  cpuprof,
+  forcegc,
+  pollDesc, # pollDesc can interact with timers, which can lock sched.
+  scavenge,
+  sweep,
+  sweepWaiters
+< sched;
+sched < allg, allp;
+allp < timers;
+timers < netpollInit;
+
+# Channels
+scavenge, sweep < hchan;
+NONE < notifyList;
+hchan, notifyList < sudog;
+
+# RWMutex
+NONE < rwmutexW;
+rwmutexW, sysmon < rwmutexR;
+
+# Semaphores
+NONE < root;
+
+# Itabs
+NONE
+< itab
+< reflectOffs;
+
+# User arena state
+NONE < userArenaState;
+
+# Tracing without a P uses a global trace buffer.
+scavenge
+# Above TRACEGLOBAL can emit a trace event without a P.
+< TRACEGLOBAL
+# Below TRACEGLOBAL manages the global tracing buffer.
+# Note that traceBuf eventually chains to MALLOC, but we never get that far
+# in the situation where there's no P.
+< traceBuf;
+# Starting/stopping tracing traces strings.
+traceBuf < traceStrings;
+
+# Malloc
+allg,
+  hchan,
+  notifyList,
+  reflectOffs,
+  timers,
+  traceStrings,
+  userArenaState
+# Above MALLOC are things that can allocate memory.
+< MALLOC
+# Below MALLOC is the malloc implementation.
+< fin,
+  gcBitsArenas,
+  mheapSpecial,
+  mspanSpecial,
+  spanSetSpine,
+  MPROF;
+
+# Memory profiling
+MPROF < profInsert, profBlock, profMemActive;
+profMemActive < profMemFuture;
+
+# Stack allocation and copying
+gcBitsArenas,
+  netpollInit,
+  profBlock,
+  profInsert,
+  profMemFuture,
+  spanSetSpine,
+  fin,
+  root
+# Anything that can grow the stack can acquire STACKGROW.
+# (Most higher layers imply STACKGROW, like MALLOC.)
+< STACKGROW
+# Below STACKGROW is the stack allocator/copying implementation.
+< gscan;
+gscan, rwmutexR < stackpool;
+gscan < stackLarge;
+# Generally, hchan must be acquired before gscan. But in one case,
+# where we suspend a G and then shrink its stack, syncadjustsudogs
+# can acquire hchan locks while holding gscan. To allow this case,
+# we use hchanLeaf instead of hchan.
+gscan < hchanLeaf;
+
+# Write barrier
+defer,
+  gscan,
+  mspanSpecial,
+  sudog
+# Anything that can have write barriers can acquire WB.
+# Above WB, we can have write barriers.
+< WB
+# Below WB is the write barrier implementation.
+< wbufSpans;
+
+# Span allocator
+stackLarge,
+  stackpool,
+  wbufSpans
+# Above mheap is anything that can call the span allocator.
+< mheap;
+# Below mheap is the span allocator implementation.
+mheap, mheapSpecial < globalAlloc;
+
+# Execution tracer events (with a P)
+hchan,
+  mheap,
+  root,
+  sched,
+  traceStrings,
+  notifyList,
+  fin
+# Above TRACE is anything that can create a trace event
+< TRACE
+< trace
+< traceStackTab;
+
+# panic is handled specially. It is implicitly below all other locks.
+NONE < panic;
+# deadlock is not acquired while holding panic, but it also needs to be
+# below all other locks.
+panic < deadlock;
+`
+
+// cyclicRanks lists lock ranks that allow multiple locks of the same
+// rank to be acquired simultaneously. The runtime enforces ordering
+// within these ranks using a separate mechanism.
+var cyclicRanks = map[string]bool{
+	// Multiple timers are locked simultaneously in destroy().
+	"timers": true,
+	// Multiple hchans are acquired in hchan.sortkey() order in
+	// select.
+	"hchan": true,
+	// Multiple hchanLeafs are acquired in hchan.sortkey() order in
+	// syncadjustsudogs().
+	"hchanLeaf": true,
+	// The point of the deadlock lock is to deadlock.
+	"deadlock": true,
+}
+
+func main() {
+	flagO := flag.String("o", "", "write to `file` instead of stdout")
+	flagDot := flag.Bool("dot", false, "emit graphviz output instead of Go")
+	flag.Parse()
+	if flag.NArg() != 0 {
+		fmt.Fprintf(os.Stderr, "too many arguments")
+		os.Exit(2)
+	}
+
+	g, err := dag.Parse(ranks)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	var out []byte
+	if *flagDot {
+		var b bytes.Buffer
+		g.TransitiveReduction()
+		// Add cyclic edges for visualization.
+		for k := range cyclicRanks {
+			g.AddEdge(k, k)
+		}
+		// Reverse the graph. It's much easier to read this as
+		// a "<" partial order than a ">" partial order. This
+		// ways, locks are acquired from the top going down
+		// and time moves forward over the edges instead of
+		// backward.
+		g.Transpose()
+		generateDot(&b, g)
+		out = b.Bytes()
+	} else {
+		var b bytes.Buffer
+		generateGo(&b, g)
+		out, err = format.Source(b.Bytes())
+		if err != nil {
+			log.Fatal(err)
+		}
+	}
+
+	if *flagO != "" {
+		err = os.WriteFile(*flagO, out, 0666)
+	} else {
+		_, err = os.Stdout.Write(out)
+	}
+	if err != nil {
+		log.Fatal(err)
+	}
+}
+
+func generateGo(w io.Writer, g *dag.Graph) {
+	fmt.Fprintf(w, `// Code generated by mklockrank.go; DO NOT EDIT.
+
+package runtime
+
+type lockRank int
+
+`)
+
+	// Create numeric ranks.
+	topo := g.Topo()
+	for i, j := 0, len(topo)-1; i < j; i, j = i+1, j-1 {
+		topo[i], topo[j] = topo[j], topo[i]
+	}
+	fmt.Fprintf(w, `
+// Constants representing the ranks of all non-leaf runtime locks, in rank order.
+// Locks with lower rank must be taken before locks with higher rank,
+// in addition to satisfying the partial order in lockPartialOrder.
+// A few ranks allow self-cycles, which are specified in lockPartialOrder.
+const (
+	lockRankUnknown lockRank = iota
+
+`)
+	for _, rank := range topo {
+		if isPseudo(rank) {
+			fmt.Fprintf(w, "\t// %s\n", rank)
+		} else {
+			fmt.Fprintf(w, "\t%s\n", cname(rank))
+		}
+	}
+	fmt.Fprintf(w, `)
+
+// lockRankLeafRank is the rank of lock that does not have a declared rank,
+// and hence is a leaf lock.
+const lockRankLeafRank lockRank = 1000
+`)
+
+	// Create string table.
+	fmt.Fprintf(w, `
+// lockNames gives the names associated with each of the above ranks.
+var lockNames = []string{
+`)
+	for _, rank := range topo {
+		if !isPseudo(rank) {
+			fmt.Fprintf(w, "\t%s: %q,\n", cname(rank), rank)
+		}
+	}
+	fmt.Fprintf(w, `}
+
+func (rank lockRank) String() string {
+	if rank == 0 {
+		return "UNKNOWN"
+	}
+	if rank == lockRankLeafRank {
+		return "LEAF"
+	}
+	if rank < 0 || int(rank) >= len(lockNames) {
+		return "BAD RANK"
+	}
+	return lockNames[rank]
+}
+`)
+
+	// Create partial order structure.
+	fmt.Fprintf(w, `
+// lockPartialOrder is the transitive closure of the lock rank graph.
+// An entry for rank X lists all of the ranks that can already be held
+// when rank X is acquired.
+//
+// Lock ranks that allow self-cycles list themselves.
+var lockPartialOrder [][]lockRank = [][]lockRank{
+`)
+	for _, rank := range topo {
+		if isPseudo(rank) {
+			continue
+		}
+		list := []string{}
+		for _, before := range g.Edges(rank) {
+			if !isPseudo(before) {
+				list = append(list, cname(before))
+			}
+		}
+		if cyclicRanks[rank] {
+			list = append(list, cname(rank))
+		}
+
+		fmt.Fprintf(w, "\t%s: {%s},\n", cname(rank), strings.Join(list, ", "))
+	}
+	fmt.Fprintf(w, "}\n")
+}
+
+// cname returns the Go const name for the given lock rank label.
+func cname(label string) string {
+	return "lockRank" + strings.ToUpper(label[:1]) + label[1:]
+}
+
+func isPseudo(label string) bool {
+	return strings.ToUpper(label) == label
+}
+
+// generateDot emits a Graphviz dot representation of g to w.
+func generateDot(w io.Writer, g *dag.Graph) {
+	fmt.Fprintf(w, "digraph g {\n")
+
+	// Define all nodes.
+	for _, node := range g.Nodes {
+		fmt.Fprintf(w, "%q;\n", node)
+	}
+
+	// Create edges.
+	for _, node := range g.Nodes {
+		for _, to := range g.Edges(node) {
+			fmt.Fprintf(w, "%q -> %q;\n", node, to)
+		}
+	}
+
+	fmt.Fprintf(w, "}\n")
+}
diff --git a/src/runtime/mkpreempt.go b/src/runtime/mkpreempt.go
index 28befcb..61d2d02 100644
--- a/src/runtime/mkpreempt.go
+++ b/src/runtime/mkpreempt.go
@@ -126,6 +126,9 @@
 		fmt.Fprintf(out, "//go:build %s || %sle\n\n", base, base)
 	}
 	fmt.Fprintf(out, "#include \"go_asm.h\"\n")
+	if arch == "amd64" {
+		fmt.Fprintf(out, "#include \"asm_amd64.h\"\n")
+	}
 	fmt.Fprintf(out, "#include \"textflag.h\"\n\n")
 	fmt.Fprintf(out, "TEXT ·asyncPreempt(SB),NOSPLIT|NOFRAME,$0-0\n")
 }
@@ -267,8 +270,10 @@
 	// Clear the upper bits to get to a clean state. See issue #37174.
 	// It is safe here as Go code don't use the upper bits of Y registers.
 	p("#ifdef GOOS_darwin")
+	p("#ifndef hasAVX")
 	p("CMPB internal∕cpu·X86+const_offsetX86HasAVX(SB), $0")
 	p("JE 2(PC)")
+	p("#endif")
 	p("VZEROUPPER")
 	p("#endif")
 
diff --git a/src/runtime/mmap.go b/src/runtime/mmap.go
index 3280a62..f0183f6 100644
--- a/src/runtime/mmap.go
+++ b/src/runtime/mmap.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build !aix && !darwin && !js && (!linux || !amd64) && (!linux || !arm64) && !openbsd && !plan9 && !solaris && !windows
+//go:build !aix && !darwin && !js && (!linux || !amd64) && (!linux || !arm64) && (!freebsd || !amd64) && !openbsd && !plan9 && !solaris && !windows
 
 package runtime
 
diff --git a/src/runtime/mpagealloc.go b/src/runtime/mpagealloc.go
index 5de25cf..35b2a01 100644
--- a/src/runtime/mpagealloc.go
+++ b/src/runtime/mpagealloc.go
@@ -48,7 +48,6 @@
 package runtime
 
 import (
-	"runtime/internal/atomic"
 	"unsafe"
 )
 
@@ -107,7 +106,7 @@
 	return chunkIdx((p - arenaBaseOffset) / pallocChunkBytes)
 }
 
-// chunkIndex returns the base address of the palloc chunk at index ci.
+// chunkBase returns the base address of the palloc chunk at index ci.
 func chunkBase(ci chunkIdx) uintptr {
 	return uintptr(ci)*pallocChunkBytes + arenaBaseOffset
 }
@@ -267,25 +266,16 @@
 	// All access is protected by the mheapLock.
 	inUse addrRanges
 
-	_ uint32 // Align scav so it's easier to reason about alignment within scav.
-
 	// scav stores the scavenger state.
 	scav struct {
 		// index is an efficient index of chunks that have pages available to
 		// scavenge.
 		index scavengeIndex
 
-		// released is the amount of memory released this generation.
+		// released is the amount of memory released this scavenge cycle.
 		//
 		// Updated atomically.
 		released uintptr
-
-		_ uint32 // Align assistTime for atomics on 32-bit platforms.
-
-		// scavengeAssistTime is the time spent scavenging in the last GC cycle.
-		//
-		// This is reset once a GC cycle ends.
-		assistTime atomic.Int64
 	}
 
 	// mheap_.lock. This level of indirection makes it possible
@@ -395,14 +385,13 @@
 	for c := chunkIndex(base); c < chunkIndex(limit); c++ {
 		if p.chunks[c.l1()] == nil {
 			// Create the necessary l2 entry.
-			//
-			// Store it atomically to avoid races with readers which
-			// don't acquire the heap lock.
 			r := sysAlloc(unsafe.Sizeof(*p.chunks[0]), p.sysStat)
 			if r == nil {
 				throw("pageAlloc: out of memory")
 			}
-			atomic.StorepNoWB(unsafe.Pointer(&p.chunks[c.l1()]), r)
+			// Store the new chunk block but avoid a write barrier.
+			// grow is used in call chains that disallow write barriers.
+			*(*uintptr)(unsafe.Pointer(&p.chunks[c.l1()])) = uintptr(r)
 		}
 		p.chunkOf(c).scavenged.setRange(0, pallocChunkPages)
 	}
@@ -678,7 +667,7 @@
 
 		// Determine j0, the first index we should start iterating from.
 		// The searchAddr may help us eliminate iterations if we followed the
-		// searchAddr on the previous level or we're on the root leve, in which
+		// searchAddr on the previous level or we're on the root level, in which
 		// case the searchAddr should be the same as i after levelShift.
 		j0 := 0
 		if searchIdx := offAddrToLevelIndex(l, p.searchAddr); searchIdx&^(entriesPerBlock-1) == i {
diff --git a/src/runtime/mpagecache.go b/src/runtime/mpagecache.go
index 5bad4f7..5bc9c84 100644
--- a/src/runtime/mpagecache.go
+++ b/src/runtime/mpagecache.go
@@ -21,8 +21,7 @@
 	scav  uint64  // 64-bit bitmap representing scavenged pages (1 means scavenged)
 }
 
-// empty returns true if the pageCache has any free pages, and false
-// otherwise.
+// empty reports whether the page cache has no free pages.
 func (c *pageCache) empty() bool {
 	return c.cache == 0
 }
diff --git a/src/runtime/mprof.go b/src/runtime/mprof.go
index 99a67b9..24f8889 100644
--- a/src/runtime/mprof.go
+++ b/src/runtime/mprof.go
@@ -10,6 +10,7 @@
 import (
 	"internal/abi"
 	"runtime/internal/atomic"
+	"runtime/internal/sys"
 	"unsafe"
 )
 
@@ -57,9 +58,8 @@
 // creation, including its next and allnext links.
 //
 // No heap pointers.
-//
-//go:notinheap
 type bucket struct {
+	_       sys.NotInHeap
 	next    *bucket
 	allnext *bucket
 	typ     bucketType // memBucket or blockBucket (includes mutexProfile)
@@ -510,10 +510,18 @@
 	bp := b.bp()
 
 	lock(&profBlockLock)
+	// We want to up-scale the count and cycles according to the
+	// probability that the event was sampled. For block profile events,
+	// the sample probability is 1 if cycles >= rate, and cycles / rate
+	// otherwise. For mutex profile events, the sample probability is 1 / rate.
+	// We scale the events by 1 / (probability the event was sampled).
 	if which == blockProfile && cycles < rate {
 		// Remove sampling bias, see discussion on http://golang.org/cl/299991.
 		bp.count += float64(rate) / float64(cycles)
 		bp.cycles += rate
+	} else if which == mutexProfile {
+		bp.count += float64(rate)
+		bp.cycles += rate * cycles
 	} else {
 		bp.count++
 		bp.cycles += cycles
@@ -584,17 +592,7 @@
 // memory profiling rate should do so just once, as early as
 // possible in the execution of the program (for example,
 // at the beginning of main).
-var MemProfileRate int = defaultMemProfileRate(512 * 1024)
-
-// defaultMemProfileRate returns 0 if disableMemoryProfiling is set.
-// It exists primarily for the godoc rendering of MemProfileRate
-// above.
-func defaultMemProfileRate(v int) int {
-	if disableMemoryProfiling {
-		return 0
-	}
-	return v
-}
+var MemProfileRate int = 512 * 1024
 
 // disableMemoryProfiling is set by the linker if runtime.MemProfile
 // is not used and the link type guarantees nobody else could use it
@@ -917,7 +915,7 @@
 	// doesn't change during the collection. So, check the finalizer goroutine
 	// in particular.
 	n = int(gcount())
-	if fingRunning {
+	if fingStatus.Load()&fingRunningFinalizer != 0 {
 		n++
 	}
 
diff --git a/src/runtime/mranges.go b/src/runtime/mranges.go
index 9cf83cc..4388d26 100644
--- a/src/runtime/mranges.go
+++ b/src/runtime/mranges.go
@@ -70,6 +70,30 @@
 	return a
 }
 
+// takeFromFront takes len bytes from the front of the address range, aligning
+// the base to align first. On success, returns the aligned start of the region
+// taken and true.
+func (a *addrRange) takeFromFront(len uintptr, align uint8) (uintptr, bool) {
+	base := alignUp(a.base.addr(), uintptr(align)) + len
+	if base > a.limit.addr() {
+		return 0, false
+	}
+	a.base = offAddr{base}
+	return base - len, true
+}
+
+// takeFromBack takes len bytes from the end of the address range, aligning
+// the limit to align after subtracting len. On success, returns the aligned
+// start of the region taken and true.
+func (a *addrRange) takeFromBack(len uintptr, align uint8) (uintptr, bool) {
+	limit := alignDown(a.limit.addr()-len, uintptr(align))
+	if a.base.addr() > limit {
+		return 0, false
+	}
+	a.limit = offAddr{limit}
+	return limit, true
+}
+
 // removeGreaterEqual removes all addresses in a greater than or equal
 // to addr and returns the new range.
 func (a addrRange) removeGreaterEqual(addr uintptr) addrRange {
diff --git a/src/runtime/msan.go b/src/runtime/msan.go
index c485216..5e2aae1 100644
--- a/src/runtime/msan.go
+++ b/src/runtime/msan.go
@@ -31,8 +31,8 @@
 //
 //go:nosplit
 func msanread(addr unsafe.Pointer, sz uintptr) {
-	g := getg()
-	if g == nil || g.m == nil || g == g.m.g0 || g == g.m.gsignal {
+	gp := getg()
+	if gp == nil || gp.m == nil || gp == gp.m.g0 || gp == gp.m.gsignal {
 		return
 	}
 	domsanread(addr, sz)
diff --git a/src/runtime/msan/msan.go b/src/runtime/msan/msan.go
index f1bf4e1..4e41f85 100644
--- a/src/runtime/msan/msan.go
+++ b/src/runtime/msan/msan.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build msan && linux && (amd64 || arm64)
+//go:build msan && ((linux && (amd64 || arm64)) || (freebsd && amd64))
 
 package msan
 
diff --git a/src/runtime/mspanset.go b/src/runtime/mspanset.go
index 4158495..abbd450 100644
--- a/src/runtime/mspanset.go
+++ b/src/runtime/mspanset.go
@@ -33,9 +33,9 @@
 	// anyway. (In principle, we could do this during STW.)
 
 	spineLock mutex
-	spine     unsafe.Pointer // *[N]*spanSetBlock, accessed atomically
-	spineLen  uintptr        // Spine array length, accessed atomically
-	spineCap  uintptr        // Spine array cap, accessed under lock
+	spine     atomicSpanSetSpinePointer // *[N]atomic.Pointer[spanSetBlock]
+	spineLen  atomic.Uintptr            // Spine array length
+	spineCap  uintptr                   // Spine array cap, accessed under spineLock
 
 	// index is the head and tail of the spanSet in a single field.
 	// The head and the tail both represent an index into the logical
@@ -48,7 +48,7 @@
 	// span in the heap were stored in this set, and each span were
 	// the minimum size (1 runtime page, 8 KiB), then roughly the
 	// smallest heap which would be unrepresentable is 32 TiB in size.
-	index headTailIndex
+	index atomicHeadTailIndex
 }
 
 const (
@@ -63,10 +63,10 @@
 	// popped is the number of pop operations that have occurred on
 	// this block. This number is used to help determine when a block
 	// may be safely recycled.
-	popped uint32
+	popped atomic.Uint32
 
 	// spans is the set of spans in this block.
-	spans [spanSetBlockEntries]*mspan
+	spans [spanSetBlockEntries]atomicMSpanPointer
 }
 
 // push adds span s to buffer b. push is safe to call concurrently
@@ -77,25 +77,24 @@
 	top, bottom := cursor/spanSetBlockEntries, cursor%spanSetBlockEntries
 
 	// Do we need to add a block?
-	spineLen := atomic.Loaduintptr(&b.spineLen)
+	spineLen := b.spineLen.Load()
 	var block *spanSetBlock
 retry:
 	if top < spineLen {
-		spine := atomic.Loadp(unsafe.Pointer(&b.spine))
-		blockp := add(spine, goarch.PtrSize*top)
-		block = (*spanSetBlock)(atomic.Loadp(blockp))
+		block = b.spine.Load().lookup(top).Load()
 	} else {
 		// Add a new block to the spine, potentially growing
 		// the spine.
 		lock(&b.spineLock)
 		// spineLen cannot change until we release the lock,
 		// but may have changed while we were waiting.
-		spineLen = atomic.Loaduintptr(&b.spineLen)
+		spineLen = b.spineLen.Load()
 		if top < spineLen {
 			unlock(&b.spineLock)
 			goto retry
 		}
 
+		spine := b.spine.Load()
 		if spineLen == b.spineCap {
 			// Grow the spine.
 			newCap := b.spineCap * 2
@@ -106,10 +105,12 @@
 			if b.spineCap != 0 {
 				// Blocks are allocated off-heap, so
 				// no write barriers.
-				memmove(newSpine, b.spine, b.spineCap*goarch.PtrSize)
+				memmove(newSpine, spine.p, b.spineCap*goarch.PtrSize)
 			}
+			spine = spanSetSpinePointer{newSpine}
+
 			// Spine is allocated off-heap, so no write barrier.
-			atomic.StorepNoWB(unsafe.Pointer(&b.spine), newSpine)
+			b.spine.StoreNoWB(spine)
 			b.spineCap = newCap
 			// We can't immediately free the old spine
 			// since a concurrent push with a lower index
@@ -124,16 +125,15 @@
 		block = spanSetBlockPool.alloc()
 
 		// Add it to the spine.
-		blockp := add(b.spine, goarch.PtrSize*top)
 		// Blocks are allocated off-heap, so no write barrier.
-		atomic.StorepNoWB(blockp, unsafe.Pointer(block))
-		atomic.Storeuintptr(&b.spineLen, spineLen+1)
+		spine.lookup(top).StoreNoWB(block)
+		b.spineLen.Store(spineLen + 1)
 		unlock(&b.spineLock)
 	}
 
 	// We have a block. Insert the span atomically, since there may be
 	// concurrent readers via the block API.
-	atomic.StorepNoWB(unsafe.Pointer(&block.spans[bottom]), unsafe.Pointer(s))
+	block.spans[bottom].StoreNoWB(s)
 }
 
 // pop removes and returns a span from buffer b, or nil if b is empty.
@@ -150,7 +150,7 @@
 		}
 		// Check if the head position we want to claim is actually
 		// backed by a block.
-		spineLen := atomic.Loaduintptr(&b.spineLen)
+		spineLen := b.spineLen.Load()
 		if spineLen <= uintptr(head)/spanSetBlockEntries {
 			// We're racing with a spine growth and the allocation of
 			// a new block (and maybe a new spine!), and trying to grab
@@ -180,24 +180,23 @@
 	// We may be reading a stale spine pointer, but because the length
 	// grows monotonically and we've already verified it, we'll definitely
 	// be reading from a valid block.
-	spine := atomic.Loadp(unsafe.Pointer(&b.spine))
-	blockp := add(spine, goarch.PtrSize*uintptr(top))
+	blockp := b.spine.Load().lookup(uintptr(top))
 
 	// Given that the spine length is correct, we know we will never
 	// see a nil block here, since the length is always updated after
 	// the block is set.
-	block := (*spanSetBlock)(atomic.Loadp(blockp))
-	s := (*mspan)(atomic.Loadp(unsafe.Pointer(&block.spans[bottom])))
+	block := blockp.Load()
+	s := block.spans[bottom].Load()
 	for s == nil {
 		// We raced with the span actually being set, but given that we
 		// know a block for this span exists, the race window here is
 		// extremely small. Try again.
-		s = (*mspan)(atomic.Loadp(unsafe.Pointer(&block.spans[bottom])))
+		s = block.spans[bottom].Load()
 	}
 	// Clear the pointer. This isn't strictly necessary, but defensively
 	// avoids accidentally re-using blocks which could lead to memory
 	// corruption. This way, we'll get a nil pointer access instead.
-	atomic.StorepNoWB(unsafe.Pointer(&block.spans[bottom]), nil)
+	block.spans[bottom].StoreNoWB(nil)
 
 	// Increase the popped count. If we are the last possible popper
 	// in the block (note that bottom need not equal spanSetBlockEntries-1
@@ -211,9 +210,9 @@
 	// pushers (there can't be any). Note that we may not be the popper
 	// which claimed the last slot in the block, we're just the last one
 	// to finish popping.
-	if atomic.Xadd(&block.popped, 1) == spanSetBlockEntries {
+	if block.popped.Add(1) == spanSetBlockEntries {
 		// Clear the block's pointer.
-		atomic.StorepNoWB(blockp, nil)
+		blockp.StoreNoWB(nil)
 
 		// Return the block to the block pool.
 		spanSetBlockPool.free(block)
@@ -235,23 +234,23 @@
 		throw("attempt to clear non-empty span set")
 	}
 	top := head / spanSetBlockEntries
-	if uintptr(top) < b.spineLen {
+	if uintptr(top) < b.spineLen.Load() {
 		// If the head catches up to the tail and the set is empty,
 		// we may not clean up the block containing the head and tail
 		// since it may be pushed into again. In order to avoid leaking
 		// memory since we're going to reset the head and tail, clean
 		// up such a block now, if it exists.
-		blockp := (**spanSetBlock)(add(b.spine, goarch.PtrSize*uintptr(top)))
-		block := *blockp
+		blockp := b.spine.Load().lookup(uintptr(top))
+		block := blockp.Load()
 		if block != nil {
-			// Sanity check the popped value.
-			if block.popped == 0 {
+			// Check the popped value.
+			if block.popped.Load() == 0 {
 				// popped should never be zero because that means we have
 				// pushed at least one value but not yet popped if this
 				// block pointer is not nil.
 				throw("span set block with unpopped elements found in reset")
 			}
-			if block.popped == spanSetBlockEntries {
+			if block.popped.Load() == spanSetBlockEntries {
 				// popped should also never be equal to spanSetBlockEntries
 				// because the last popper should have made the block pointer
 				// in this slot nil.
@@ -259,14 +258,45 @@
 			}
 
 			// Clear the pointer to the block.
-			atomic.StorepNoWB(unsafe.Pointer(blockp), nil)
+			blockp.StoreNoWB(nil)
 
 			// Return the block to the block pool.
 			spanSetBlockPool.free(block)
 		}
 	}
 	b.index.reset()
-	atomic.Storeuintptr(&b.spineLen, 0)
+	b.spineLen.Store(0)
+}
+
+// atomicSpanSetSpinePointer is an atomically-accessed spanSetSpinePointer.
+//
+// It has the same semantics as atomic.UnsafePointer.
+type atomicSpanSetSpinePointer struct {
+	a atomic.UnsafePointer
+}
+
+// Loads the spanSetSpinePointer and returns it.
+//
+// It has the same semantics as atomic.UnsafePointer.
+func (s *atomicSpanSetSpinePointer) Load() spanSetSpinePointer {
+	return spanSetSpinePointer{s.a.Load()}
+}
+
+// Stores the spanSetSpinePointer.
+//
+// It has the same semantics as atomic.UnsafePointer.
+func (s *atomicSpanSetSpinePointer) StoreNoWB(p spanSetSpinePointer) {
+	s.a.StoreNoWB(p.p)
+}
+
+// spanSetSpinePointer represents a pointer to a contiguous block of atomic.Pointer[spanSetBlock].
+type spanSetSpinePointer struct {
+	p unsafe.Pointer
+}
+
+// lookup returns &s[idx].
+func (s spanSetSpinePointer) lookup(idx uintptr) *atomic.Pointer[spanSetBlock] {
+	return (*atomic.Pointer[spanSetBlock])(add(unsafe.Pointer(s.p), goarch.PtrSize*idx))
 }
 
 // spanSetBlockPool is a global pool of spanSetBlocks.
@@ -288,7 +318,7 @@
 
 // free returns a spanSetBlock back to the pool.
 func (p *spanSetBlockAlloc) free(block *spanSetBlock) {
-	atomic.Store(&block.popped, 0)
+	block.popped.Store(0)
 	p.stack.push(&block.lfnode)
 }
 
@@ -317,29 +347,34 @@
 	return h.head(), h.tail()
 }
 
+// atomicHeadTailIndex is an atomically-accessed headTailIndex.
+type atomicHeadTailIndex struct {
+	u atomic.Uint64
+}
+
 // load atomically reads a headTailIndex value.
-func (h *headTailIndex) load() headTailIndex {
-	return headTailIndex(atomic.Load64((*uint64)(h)))
+func (h *atomicHeadTailIndex) load() headTailIndex {
+	return headTailIndex(h.u.Load())
 }
 
 // cas atomically compares-and-swaps a headTailIndex value.
-func (h *headTailIndex) cas(old, new headTailIndex) bool {
-	return atomic.Cas64((*uint64)(h), uint64(old), uint64(new))
+func (h *atomicHeadTailIndex) cas(old, new headTailIndex) bool {
+	return h.u.CompareAndSwap(uint64(old), uint64(new))
 }
 
 // incHead atomically increments the head of a headTailIndex.
-func (h *headTailIndex) incHead() headTailIndex {
-	return headTailIndex(atomic.Xadd64((*uint64)(h), (1 << 32)))
+func (h *atomicHeadTailIndex) incHead() headTailIndex {
+	return headTailIndex(h.u.Add(1 << 32))
 }
 
 // decHead atomically decrements the head of a headTailIndex.
-func (h *headTailIndex) decHead() headTailIndex {
-	return headTailIndex(atomic.Xadd64((*uint64)(h), -(1 << 32)))
+func (h *atomicHeadTailIndex) decHead() headTailIndex {
+	return headTailIndex(h.u.Add(-(1 << 32)))
 }
 
 // incTail atomically increments the tail of a headTailIndex.
-func (h *headTailIndex) incTail() headTailIndex {
-	ht := headTailIndex(atomic.Xadd64((*uint64)(h), +1))
+func (h *atomicHeadTailIndex) incTail() headTailIndex {
+	ht := headTailIndex(h.u.Add(1))
 	// Check for overflow.
 	if ht.tail() == 0 {
 		print("runtime: head = ", ht.head(), ", tail = ", ht.tail(), "\n")
@@ -349,6 +384,21 @@
 }
 
 // reset clears the headTailIndex to (0, 0).
-func (h *headTailIndex) reset() {
-	atomic.Store64((*uint64)(h), 0)
+func (h *atomicHeadTailIndex) reset() {
+	h.u.Store(0)
+}
+
+// atomicMSpanPointer is an atomic.Pointer[mspan]. Can't use generics because it's NotInHeap.
+type atomicMSpanPointer struct {
+	p atomic.UnsafePointer
+}
+
+// Load returns the *mspan.
+func (p *atomicMSpanPointer) Load() *mspan {
+	return (*mspan)(p.p.Load())
+}
+
+// Store stores an *mspan.
+func (p *atomicMSpanPointer) StoreNoWB(s *mspan) {
+	p.p.StoreNoWB(unsafe.Pointer(s))
 }
diff --git a/src/runtime/mstats.go b/src/runtime/mstats.go
index 0029ea9..3a5273f 100644
--- a/src/runtime/mstats.go
+++ b/src/runtime/mstats.go
@@ -45,8 +45,6 @@
 
 	enablegc bool
 
-	_ uint32 // ensure gcPauseDist is aligned.
-
 	// gcPauseDist represents the distribution of all GC-related
 	// application pauses in the runtime.
 	//
@@ -334,10 +332,6 @@
 		println(offset)
 		throw("memstats.heapStats not aligned to 8 bytes")
 	}
-	if offset := unsafe.Offsetof(memstats.gcPauseDist); offset%8 != 0 {
-		println(offset)
-		throw("memstats.gcPauseDist not aligned to 8 bytes")
-	}
 	// Ensure the size of heapStatsDelta causes adjacent fields/slots (e.g.
 	// [3]heapStatsDelta) to be 8-byte aligned.
 	if size := unsafe.Sizeof(heapStatsDelta{}); size%8 != 0 {
@@ -733,8 +727,7 @@
 
 	// gen represents the current index into which writers
 	// are writing, and can take on the value of 0, 1, or 2.
-	// This value is updated atomically.
-	gen uint32
+	gen atomic.Uint32
 
 	// noPLock is intended to provide mutual exclusion for updating
 	// stats when no P is available. It does not block other writers
@@ -763,7 +756,7 @@
 //go:nosplit
 func (m *consistentHeapStats) acquire() *heapStatsDelta {
 	if pp := getg().m.p.ptr(); pp != nil {
-		seq := atomic.Xadd(&pp.statsSeq, 1)
+		seq := pp.statsSeq.Add(1)
 		if seq%2 == 0 {
 			// Should have been incremented to odd.
 			print("runtime: seq=", seq, "\n")
@@ -772,7 +765,7 @@
 	} else {
 		lock(&m.noPLock)
 	}
-	gen := atomic.Load(&m.gen) % 3
+	gen := m.gen.Load() % 3
 	return &m.stats[gen]
 }
 
@@ -792,7 +785,7 @@
 //go:nosplit
 func (m *consistentHeapStats) release() {
 	if pp := getg().m.p.ptr(); pp != nil {
-		seq := atomic.Xadd(&pp.statsSeq, 1)
+		seq := pp.statsSeq.Add(1)
 		if seq%2 != 0 {
 			// Should have been incremented to even.
 			print("runtime: seq=", seq, "\n")
@@ -843,7 +836,7 @@
 	// Get the current generation. We can be confident that this
 	// will not change since read is serialized and is the only
 	// one that modifies currGen.
-	currGen := atomic.Load(&m.gen)
+	currGen := m.gen.Load()
 	prevGen := currGen - 1
 	if currGen == 0 {
 		prevGen = 2
@@ -858,7 +851,7 @@
 	//
 	// This exchange is safe to do because we won't race
 	// with anyone else trying to update this value.
-	atomic.Xchg(&m.gen, (currGen+1)%3)
+	m.gen.Swap((currGen + 1) % 3)
 
 	// Allow P-less writers to continue. They'll be writing to the
 	// next generation now.
@@ -866,7 +859,7 @@
 
 	for _, p := range allp {
 		// Spin until there are no more writers.
-		for atomic.Load(&p.statsSeq)%2 != 0 {
+		for p.statsSeq.Load()%2 != 0 {
 		}
 	}
 
@@ -886,3 +879,25 @@
 
 	releasem(mp)
 }
+
+type cpuStats struct {
+	// All fields are CPU time in nanoseconds computed by comparing
+	// calls of nanotime. This means they're all overestimates, because
+	// they don't accurately compute on-CPU time (so some of the time
+	// could be spent scheduled away by the OS).
+
+	gcAssistTime    int64 // GC assists
+	gcDedicatedTime int64 // GC dedicated mark workers + pauses
+	gcIdleTime      int64 // GC idle mark workers
+	gcPauseTime     int64 // GC pauses (all GOMAXPROCS, even if just 1 is running)
+	gcTotalTime     int64
+
+	scavengeAssistTime int64 // background scavenger
+	scavengeBgTime     int64 // scavenge assists
+	scavengeTotalTime  int64
+
+	idleTime int64 // Time Ps spent in _Pidle.
+	userTime int64 // Time Ps spent in _Prunning or _Psyscall that's not any of the above.
+
+	totalTime int64 // GOMAXPROCS * (monotonic wall clock time elapsed)
+}
diff --git a/src/runtime/mwbbuf.go b/src/runtime/mwbbuf.go
index 39ce0b4..3b7cbf8 100644
--- a/src/runtime/mwbbuf.go
+++ b/src/runtime/mwbbuf.go
@@ -212,22 +212,22 @@
 //
 //go:nowritebarrierrec
 //go:systemstack
-func wbBufFlush1(_p_ *p) {
+func wbBufFlush1(pp *p) {
 	// Get the buffered pointers.
-	start := uintptr(unsafe.Pointer(&_p_.wbBuf.buf[0]))
-	n := (_p_.wbBuf.next - start) / unsafe.Sizeof(_p_.wbBuf.buf[0])
-	ptrs := _p_.wbBuf.buf[:n]
+	start := uintptr(unsafe.Pointer(&pp.wbBuf.buf[0]))
+	n := (pp.wbBuf.next - start) / unsafe.Sizeof(pp.wbBuf.buf[0])
+	ptrs := pp.wbBuf.buf[:n]
 
 	// Poison the buffer to make extra sure nothing is enqueued
 	// while we're processing the buffer.
-	_p_.wbBuf.next = 0
+	pp.wbBuf.next = 0
 
 	if useCheckmark {
 		// Slow path for checkmark mode.
 		for _, ptr := range ptrs {
 			shade(ptr)
 		}
-		_p_.wbBuf.reset()
+		pp.wbBuf.reset()
 		return
 	}
 
@@ -245,7 +245,7 @@
 	// could track whether any un-shaded goroutine has used the
 	// buffer, or just track globally whether there are any
 	// un-shaded stacks and flush after each stack scan.
-	gcw := &_p_.gcw
+	gcw := &pp.gcw
 	pos := 0
 	for _, ptr := range ptrs {
 		if ptr < minLegalPointer {
@@ -286,5 +286,5 @@
 	// Enqueue the greyed objects.
 	gcw.putBatch(ptrs[:pos])
 
-	_p_.wbBuf.reset()
+	pp.wbBuf.reset()
 }
diff --git a/src/runtime/nbpipe_fcntl_libc_test.go b/src/runtime/nbpipe_fcntl_libc_test.go
index a9c8987..170245d 100644
--- a/src/runtime/nbpipe_fcntl_libc_test.go
+++ b/src/runtime/nbpipe_fcntl_libc_test.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build aix || darwin || solaris
+//go:build aix || darwin || (openbsd && !mips64) || solaris
 
 package runtime_test
 
diff --git a/src/runtime/nbpipe_fcntl_unix_test.go b/src/runtime/nbpipe_fcntl_unix_test.go
index 97607fa..b7252ea 100644
--- a/src/runtime/nbpipe_fcntl_unix_test.go
+++ b/src/runtime/nbpipe_fcntl_unix_test.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build dragonfly || freebsd || linux || netbsd || openbsd
+//go:build dragonfly || freebsd || linux || netbsd || (openbsd && mips64)
 
 package runtime_test
 
diff --git a/src/runtime/netpoll.go b/src/runtime/netpoll.go
index ac6bc89..5ac1f37 100644
--- a/src/runtime/netpoll.go
+++ b/src/runtime/netpoll.go
@@ -8,6 +8,7 @@
 
 import (
 	"runtime/internal/atomic"
+	"runtime/internal/sys"
 	"unsafe"
 )
 
@@ -49,16 +50,17 @@
 // goroutines respectively. The semaphore can be in the following states:
 //
 //	pdReady - io readiness notification is pending;
-//	          a goroutine consumes the notification by changing the state to nil.
+//	          a goroutine consumes the notification by changing the state to pdNil.
 //	pdWait - a goroutine prepares to park on the semaphore, but not yet parked;
 //	         the goroutine commits to park by changing the state to G pointer,
 //	         or, alternatively, concurrent io notification changes the state to pdReady,
-//	         or, alternatively, concurrent timeout/close changes the state to nil.
+//	         or, alternatively, concurrent timeout/close changes the state to pdNil.
 //	G pointer - the goroutine is blocked on the semaphore;
-//	            io notification or timeout/close changes the state to pdReady or nil respectively
+//	            io notification or timeout/close changes the state to pdReady or pdNil respectively
 //	            and unparks the goroutine.
-//	nil - none of the above.
+//	pdNil - none of the above.
 const (
+	pdNil   uintptr = 0
 	pdReady uintptr = 1
 	pdWait  uintptr = 2
 )
@@ -68,9 +70,8 @@
 // Network poller descriptor.
 //
 // No heap pointers.
-//
-//go:notinheap
 type pollDesc struct {
+	_    sys.NotInHeap
 	link *pollDesc // in pollcache, protected by pollcache.lock
 	fd   uintptr   // constant for pollDesc usage lifetime
 
@@ -93,8 +94,8 @@
 
 	// rg, wg are accessed atomically and hold g pointers.
 	// (Using atomic.Uintptr here is similar to using guintptr elsewhere.)
-	rg atomic.Uintptr // pdReady, pdWait, G waiting for read or nil
-	wg atomic.Uintptr // pdReady, pdWait, G waiting for write or nil
+	rg atomic.Uintptr // pdReady, pdWait, G waiting for read or pdNil
+	wg atomic.Uintptr // pdReady, pdWait, G waiting for write or pdNil
 
 	lock    mutex // protects the following fields
 	closing bool
@@ -177,10 +178,10 @@
 
 var (
 	netpollInitLock mutex
-	netpollInited   uint32
+	netpollInited   atomic.Uint32
 
 	pollcache      pollCache
-	netpollWaiters uint32
+	netpollWaiters atomic.Uint32
 )
 
 //go:linkname poll_runtime_pollServerInit internal/poll.runtime_pollServerInit
@@ -189,19 +190,19 @@
 }
 
 func netpollGenericInit() {
-	if atomic.Load(&netpollInited) == 0 {
+	if netpollInited.Load() == 0 {
 		lockInit(&netpollInitLock, lockRankNetpollInit)
 		lock(&netpollInitLock)
-		if netpollInited == 0 {
+		if netpollInited.Load() == 0 {
 			netpollinit()
-			atomic.Store(&netpollInited, 1)
+			netpollInited.Store(1)
 		}
 		unlock(&netpollInitLock)
 	}
 }
 
 func netpollinited() bool {
-	return atomic.Load(&netpollInited) != 0
+	return netpollInited.Load() != 0
 }
 
 //go:linkname poll_runtime_isPollServerDescriptor internal/poll.runtime_isPollServerDescriptor
@@ -217,21 +218,21 @@
 	pd := pollcache.alloc()
 	lock(&pd.lock)
 	wg := pd.wg.Load()
-	if wg != 0 && wg != pdReady {
+	if wg != pdNil && wg != pdReady {
 		throw("runtime: blocked write on free polldesc")
 	}
 	rg := pd.rg.Load()
-	if rg != 0 && rg != pdReady {
+	if rg != pdNil && rg != pdReady {
 		throw("runtime: blocked read on free polldesc")
 	}
 	pd.fd = fd
 	pd.closing = false
 	pd.setEventErr(false)
 	pd.rseq++
-	pd.rg.Store(0)
+	pd.rg.Store(pdNil)
 	pd.rd = 0
 	pd.wseq++
-	pd.wg.Store(0)
+	pd.wg.Store(pdNil)
 	pd.wd = 0
 	pd.self = pd
 	pd.publishInfo()
@@ -251,11 +252,11 @@
 		throw("runtime: close polldesc w/o unblock")
 	}
 	wg := pd.wg.Load()
-	if wg != 0 && wg != pdReady {
+	if wg != pdNil && wg != pdReady {
 		throw("runtime: blocked write on closing polldesc")
 	}
 	rg := pd.rg.Load()
-	if rg != 0 && rg != pdReady {
+	if rg != pdNil && rg != pdReady {
 		throw("runtime: blocked read on closing polldesc")
 	}
 	netpollclose(pd.fd)
@@ -280,9 +281,9 @@
 		return errcode
 	}
 	if mode == 'r' {
-		pd.rg.Store(0)
+		pd.rg.Store(pdNil)
 	} else if mode == 'w' {
-		pd.wg.Store(0)
+		pd.wg.Store(pdNil)
 	}
 	return pollNoError
 }
@@ -482,17 +483,17 @@
 		// Bump the count of goroutines waiting for the poller.
 		// The scheduler uses this to decide whether to block
 		// waiting for the poller if there is nothing else to do.
-		atomic.Xadd(&netpollWaiters, 1)
+		netpollWaiters.Add(1)
 	}
 	return r
 }
 
 func netpollgoready(gp *g, traceskip int) {
-	atomic.Xadd(&netpollWaiters, -1)
+	netpollWaiters.Add(-1)
 	goready(gp, traceskip+1)
 }
 
-// returns true if IO is ready, or false if timedout or closed
+// returns true if IO is ready, or false if timed out or closed
 // waitio - wait only for completed IO, ignore errors
 // Concurrent calls to netpollblock in the same mode are forbidden, as pollDesc
 // can hold only a single waiting goroutine for each mode.
@@ -505,16 +506,16 @@
 	// set the gpp semaphore to pdWait
 	for {
 		// Consume notification if already ready.
-		if gpp.CompareAndSwap(pdReady, 0) {
+		if gpp.CompareAndSwap(pdReady, pdNil) {
 			return true
 		}
-		if gpp.CompareAndSwap(0, pdWait) {
+		if gpp.CompareAndSwap(pdNil, pdWait) {
 			break
 		}
 
 		// Double check that this isn't corrupt; otherwise we'd loop
 		// forever.
-		if v := gpp.Load(); v != pdReady && v != 0 {
+		if v := gpp.Load(); v != pdReady && v != pdNil {
 			throw("runtime: double wait")
 		}
 	}
@@ -526,7 +527,7 @@
 		gopark(netpollblockcommit, unsafe.Pointer(gpp), waitReasonIOWait, traceEvGoBlockNet, 5)
 	}
 	// be careful to not lose concurrent pdReady notification
-	old := gpp.Swap(0)
+	old := gpp.Swap(pdNil)
 	if old > pdWait {
 		throw("runtime: corrupted polldesc")
 	}
@@ -544,7 +545,7 @@
 		if old == pdReady {
 			return nil
 		}
-		if old == 0 && !ioready {
+		if old == pdNil && !ioready {
 			// Only set pdReady for ioready. runtime_pollWait
 			// will check for timeout/cancel before waiting.
 			return nil
@@ -555,7 +556,7 @@
 		}
 		if gpp.CompareAndSwap(old, new) {
 			if old == pdWait {
-				old = 0
+				old = pdNil
 			}
 			return (*g)(unsafe.Pointer(old))
 		}
@@ -641,8 +642,8 @@
 // makeArg converts pd to an interface{}.
 // makeArg does not do any allocation. Normally, such
 // a conversion requires an allocation because pointers to
-// go:notinheap types (which pollDesc is) must be stored
-// in interfaces indirectly. See issue 42076.
+// types which embed runtime/internal/sys.NotInHeap (which pollDesc is)
+// must be stored in interfaces indirectly. See issue 42076.
 func (pd *pollDesc) makeArg() (i any) {
 	x := (*eface)(unsafe.Pointer(&i))
 	x._type = pdType
diff --git a/src/runtime/netpoll_aix.go b/src/runtime/netpoll_aix.go
index 22cc513..5184aad 100644
--- a/src/runtime/netpoll_aix.go
+++ b/src/runtime/netpoll_aix.go
@@ -45,7 +45,7 @@
 	wrwake         int32
 	pendingUpdates int32
 
-	netpollWakeSig uint32 // used to avoid duplicate calls of netpollBreak
+	netpollWakeSig atomic.Uint32 // used to avoid duplicate calls of netpollBreak
 )
 
 func netpollinit() {
@@ -135,10 +135,13 @@
 
 // netpollBreak interrupts a poll.
 func netpollBreak() {
-	if atomic.Cas(&netpollWakeSig, 0, 1) {
-		b := [1]byte{0}
-		write(uintptr(wrwake), unsafe.Pointer(&b[0]), 1)
+	// Failing to cas indicates there is an in-flight wakeup, so we're done here.
+	if !netpollWakeSig.CompareAndSwap(0, 1) {
+		return
 	}
+
+	b := [1]byte{0}
+	write(uintptr(wrwake), unsafe.Pointer(&b[0]), 1)
 }
 
 // netpoll checks for ready network connections.
@@ -193,7 +196,7 @@
 			var b [1]byte
 			for read(rdwake, unsafe.Pointer(&b[0]), 1) == 1 {
 			}
-			atomic.Store(&netpollWakeSig, 0)
+			netpollWakeSig.Store(0)
 		}
 		// Still look at the other fds even if the mode may have
 		// changed, as netpollBreak might have been called.
diff --git a/src/runtime/netpoll_epoll.go b/src/runtime/netpoll_epoll.go
index b7d6199..7164a59 100644
--- a/src/runtime/netpoll_epoll.go
+++ b/src/runtime/netpoll_epoll.go
@@ -8,49 +8,37 @@
 
 import (
 	"runtime/internal/atomic"
+	"runtime/internal/syscall"
 	"unsafe"
 )
 
-func epollcreate(size int32) int32
-func epollcreate1(flags int32) int32
-
-//go:noescape
-func epollctl(epfd, op, fd int32, ev *epollevent) int32
-
-//go:noescape
-func epollwait(epfd int32, ev *epollevent, nev, timeout int32) int32
-func closeonexec(fd int32)
-
 var (
 	epfd int32 = -1 // epoll descriptor
 
 	netpollBreakRd, netpollBreakWr uintptr // for netpollBreak
 
-	netpollWakeSig uint32 // used to avoid duplicate calls of netpollBreak
+	netpollWakeSig atomic.Uint32 // used to avoid duplicate calls of netpollBreak
 )
 
 func netpollinit() {
-	epfd = epollcreate1(_EPOLL_CLOEXEC)
-	if epfd < 0 {
-		epfd = epollcreate(1024)
-		if epfd < 0 {
-			println("runtime: epollcreate failed with", -epfd)
-			throw("runtime: netpollinit failed")
-		}
-		closeonexec(epfd)
-	}
-	r, w, errno := nonblockingPipe()
+	var errno uintptr
+	epfd, errno = syscall.EpollCreate1(syscall.EPOLL_CLOEXEC)
 	if errno != 0 {
-		println("runtime: pipe failed with", -errno)
+		println("runtime: epollcreate failed with", errno)
+		throw("runtime: netpollinit failed")
+	}
+	r, w, errpipe := nonblockingPipe()
+	if errpipe != 0 {
+		println("runtime: pipe failed with", -errpipe)
 		throw("runtime: pipe failed")
 	}
-	ev := epollevent{
-		events: _EPOLLIN,
+	ev := syscall.EpollEvent{
+		Events: syscall.EPOLLIN,
 	}
-	*(**uintptr)(unsafe.Pointer(&ev.data)) = &netpollBreakRd
-	errno = epollctl(epfd, _EPOLL_CTL_ADD, r, &ev)
+	*(**uintptr)(unsafe.Pointer(&ev.Data)) = &netpollBreakRd
+	errno = syscall.EpollCtl(epfd, syscall.EPOLL_CTL_ADD, r, &ev)
 	if errno != 0 {
-		println("runtime: epollctl failed with", -errno)
+		println("runtime: epollctl failed with", errno)
 		throw("runtime: epollctl failed")
 	}
 	netpollBreakRd = uintptr(r)
@@ -61,16 +49,16 @@
 	return fd == uintptr(epfd) || fd == netpollBreakRd || fd == netpollBreakWr
 }
 
-func netpollopen(fd uintptr, pd *pollDesc) int32 {
-	var ev epollevent
-	ev.events = _EPOLLIN | _EPOLLOUT | _EPOLLRDHUP | _EPOLLET
-	*(**pollDesc)(unsafe.Pointer(&ev.data)) = pd
-	return -epollctl(epfd, _EPOLL_CTL_ADD, int32(fd), &ev)
+func netpollopen(fd uintptr, pd *pollDesc) uintptr {
+	var ev syscall.EpollEvent
+	ev.Events = syscall.EPOLLIN | syscall.EPOLLOUT | syscall.EPOLLRDHUP | syscall.EPOLLET
+	*(**pollDesc)(unsafe.Pointer(&ev.Data)) = pd
+	return syscall.EpollCtl(epfd, syscall.EPOLL_CTL_ADD, int32(fd), &ev)
 }
 
-func netpollclose(fd uintptr) int32 {
-	var ev epollevent
-	return -epollctl(epfd, _EPOLL_CTL_DEL, int32(fd), &ev)
+func netpollclose(fd uintptr) uintptr {
+	var ev syscall.EpollEvent
+	return syscall.EpollCtl(epfd, syscall.EPOLL_CTL_DEL, int32(fd), &ev)
 }
 
 func netpollarm(pd *pollDesc, mode int) {
@@ -79,22 +67,25 @@
 
 // netpollBreak interrupts an epollwait.
 func netpollBreak() {
-	if atomic.Cas(&netpollWakeSig, 0, 1) {
-		for {
-			var b byte
-			n := write(netpollBreakWr, unsafe.Pointer(&b), 1)
-			if n == 1 {
-				break
-			}
-			if n == -_EINTR {
-				continue
-			}
-			if n == -_EAGAIN {
-				return
-			}
-			println("runtime: netpollBreak write failed with", -n)
-			throw("runtime: netpollBreak write failed")
+	// Failing to cas indicates there is an in-flight wakeup, so we're done here.
+	if !netpollWakeSig.CompareAndSwap(0, 1) {
+		return
+	}
+
+	for {
+		var b byte
+		n := write(netpollBreakWr, unsafe.Pointer(&b), 1)
+		if n == 1 {
+			break
 		}
+		if n == -_EINTR {
+			continue
+		}
+		if n == -_EAGAIN {
+			return
+		}
+		println("runtime: netpollBreak write failed with", -n)
+		throw("runtime: netpollBreak write failed")
 	}
 }
 
@@ -121,12 +112,12 @@
 		// 1e9 ms == ~11.5 days.
 		waitms = 1e9
 	}
-	var events [128]epollevent
+	var events [128]syscall.EpollEvent
 retry:
-	n := epollwait(epfd, &events[0], int32(len(events)), waitms)
-	if n < 0 {
-		if n != -_EINTR {
-			println("runtime: epollwait on fd", epfd, "failed with", -n)
+	n, errno := syscall.EpollWait(epfd, events[:], int32(len(events)), waitms)
+	if errno != 0 {
+		if errno != _EINTR {
+			println("runtime: epollwait on fd", epfd, "failed with", errno)
 			throw("runtime: netpoll failed")
 		}
 		// If a timed sleep was interrupted, just return to
@@ -138,14 +129,14 @@
 	}
 	var toRun gList
 	for i := int32(0); i < n; i++ {
-		ev := &events[i]
-		if ev.events == 0 {
+		ev := events[i]
+		if ev.Events == 0 {
 			continue
 		}
 
-		if *(**uintptr)(unsafe.Pointer(&ev.data)) == &netpollBreakRd {
-			if ev.events != _EPOLLIN {
-				println("runtime: netpoll: break fd ready for", ev.events)
+		if *(**uintptr)(unsafe.Pointer(&ev.Data)) == &netpollBreakRd {
+			if ev.Events != syscall.EPOLLIN {
+				println("runtime: netpoll: break fd ready for", ev.Events)
 				throw("runtime: netpoll: break fd ready for something unexpected")
 			}
 			if delay != 0 {
@@ -154,21 +145,21 @@
 				// if blocking.
 				var tmp [16]byte
 				read(int32(netpollBreakRd), noescape(unsafe.Pointer(&tmp[0])), int32(len(tmp)))
-				atomic.Store(&netpollWakeSig, 0)
+				netpollWakeSig.Store(0)
 			}
 			continue
 		}
 
 		var mode int32
-		if ev.events&(_EPOLLIN|_EPOLLRDHUP|_EPOLLHUP|_EPOLLERR) != 0 {
+		if ev.Events&(syscall.EPOLLIN|syscall.EPOLLRDHUP|syscall.EPOLLHUP|syscall.EPOLLERR) != 0 {
 			mode += 'r'
 		}
-		if ev.events&(_EPOLLOUT|_EPOLLHUP|_EPOLLERR) != 0 {
+		if ev.Events&(syscall.EPOLLOUT|syscall.EPOLLHUP|syscall.EPOLLERR) != 0 {
 			mode += 'w'
 		}
 		if mode != 0 {
-			pd := *(**pollDesc)(unsafe.Pointer(&ev.data))
-			pd.setEventErr(ev.events == _EPOLLERR)
+			pd := *(**pollDesc)(unsafe.Pointer(&ev.Data))
+			pd.setEventErr(ev.Events == syscall.EPOLLERR)
 			netpollready(&toRun, pd, mode)
 		}
 	}
diff --git a/src/runtime/netpoll_kqueue.go b/src/runtime/netpoll_kqueue.go
index 1694753..5ae77b5 100644
--- a/src/runtime/netpoll_kqueue.go
+++ b/src/runtime/netpoll_kqueue.go
@@ -18,7 +18,7 @@
 
 	netpollBreakRd, netpollBreakWr uintptr // for netpollBreak
 
-	netpollWakeSig uint32 // used to avoid duplicate calls of netpollBreak
+	netpollWakeSig atomic.Uint32 // used to avoid duplicate calls of netpollBreak
 )
 
 func netpollinit() {
@@ -83,19 +83,22 @@
 
 // netpollBreak interrupts a kevent.
 func netpollBreak() {
-	if atomic.Cas(&netpollWakeSig, 0, 1) {
-		for {
-			var b byte
-			n := write(netpollBreakWr, unsafe.Pointer(&b), 1)
-			if n == 1 || n == -_EAGAIN {
-				break
-			}
-			if n == -_EINTR {
-				continue
-			}
-			println("runtime: netpollBreak write failed with", -n)
-			throw("runtime: netpollBreak write failed")
+	// Failing to cas indicates there is an in-flight wakeup, so we're done here.
+	if !netpollWakeSig.CompareAndSwap(0, 1) {
+		return
+	}
+
+	for {
+		var b byte
+		n := write(netpollBreakWr, unsafe.Pointer(&b), 1)
+		if n == 1 || n == -_EAGAIN {
+			break
 		}
+		if n == -_EINTR {
+			continue
+		}
+		println("runtime: netpollBreak write failed with", -n)
+		throw("runtime: netpollBreak write failed")
 	}
 }
 
@@ -152,7 +155,7 @@
 				// if blocking.
 				var tmp [16]byte
 				read(int32(netpollBreakRd), noescape(unsafe.Pointer(&tmp[0])), int32(len(tmp)))
-				atomic.Store(&netpollWakeSig, 0)
+				netpollWakeSig.Store(0)
 			}
 			continue
 		}
diff --git a/src/runtime/netpoll_solaris.go b/src/runtime/netpoll_solaris.go
index 6e545b3..d835cd9 100644
--- a/src/runtime/netpoll_solaris.go
+++ b/src/runtime/netpoll_solaris.go
@@ -88,7 +88,7 @@
 	libc_port_dissociate,
 	libc_port_getn,
 	libc_port_alert libcFunc
-	netpollWakeSig uint32 // used to avoid duplicate calls of netpollBreak
+	netpollWakeSig atomic.Uint32 // used to avoid duplicate calls of netpollBreak
 )
 
 func errno() int32 {
@@ -191,17 +191,20 @@
 
 // netpollBreak interrupts a port_getn wait.
 func netpollBreak() {
-	if atomic.Cas(&netpollWakeSig, 0, 1) {
-		// Use port_alert to put portfd into alert mode.
-		// This will wake up all threads sleeping in port_getn on portfd,
-		// and cause their calls to port_getn to return immediately.
-		// Further, until portfd is taken out of alert mode,
-		// all calls to port_getn will return immediately.
-		if port_alert(portfd, _PORT_ALERT_UPDATE, _POLLHUP, uintptr(unsafe.Pointer(&portfd))) < 0 {
-			if e := errno(); e != _EBUSY {
-				println("runtime: port_alert failed with", e)
-				throw("runtime: netpoll: port_alert failed")
-			}
+	// Failing to cas indicates there is an in-flight wakeup, so we're done here.
+	if !netpollWakeSig.CompareAndSwap(0, 1) {
+		return
+	}
+
+	// Use port_alert to put portfd into alert mode.
+	// This will wake up all threads sleeping in port_getn on portfd,
+	// and cause their calls to port_getn to return immediately.
+	// Further, until portfd is taken out of alert mode,
+	// all calls to port_getn will return immediately.
+	if port_alert(portfd, _PORT_ALERT_UPDATE, _POLLHUP, uintptr(unsafe.Pointer(&portfd))) < 0 {
+		if e := errno(); e != _EBUSY {
+			println("runtime: port_alert failed with", e)
+			throw("runtime: netpoll: port_alert failed")
 		}
 	}
 }
@@ -274,7 +277,7 @@
 					println("runtime: port_alert failed with", e)
 					throw("runtime: netpoll: port_alert failed")
 				}
-				atomic.Store(&netpollWakeSig, 0)
+				netpollWakeSig.Store(0)
 			}
 			continue
 		}
diff --git a/src/runtime/netpoll_stub.go b/src/runtime/netpoll_stub.go
index d0a63bc..14cf0c3 100644
--- a/src/runtime/netpoll_stub.go
+++ b/src/runtime/netpoll_stub.go
@@ -8,8 +8,8 @@
 
 import "runtime/internal/atomic"
 
-var netpollInited uint32
-var netpollWaiters uint32
+var netpollInited atomic.Uint32
+var netpollWaiters atomic.Uint32
 
 var netpollStubLock mutex
 var netpollNote note
@@ -19,7 +19,7 @@
 var netpollBroken bool
 
 func netpollGenericInit() {
-	atomic.Store(&netpollInited, 1)
+	netpollInited.Store(1)
 }
 
 func netpollBreak() {
@@ -57,5 +57,5 @@
 }
 
 func netpollinited() bool {
-	return atomic.Load(&netpollInited) != 0
+	return netpollInited.Load() != 0
 }
diff --git a/src/runtime/netpoll_windows.go b/src/runtime/netpoll_windows.go
index 4c1cd26..796bf1d 100644
--- a/src/runtime/netpoll_windows.go
+++ b/src/runtime/netpoll_windows.go
@@ -35,7 +35,7 @@
 var (
 	iocphandle uintptr = _INVALID_HANDLE_VALUE // completion port io handle
 
-	netpollWakeSig uint32 // used to avoid duplicate calls of netpollBreak
+	netpollWakeSig atomic.Uint32 // used to avoid duplicate calls of netpollBreak
 )
 
 func netpollinit() {
@@ -67,11 +67,14 @@
 }
 
 func netpollBreak() {
-	if atomic.Cas(&netpollWakeSig, 0, 1) {
-		if stdcall4(_PostQueuedCompletionStatus, iocphandle, 0, 0, 0) == 0 {
-			println("runtime: netpoll: PostQueuedCompletionStatus failed (errno=", getlasterror(), ")")
-			throw("runtime: netpoll: PostQueuedCompletionStatus failed")
-		}
+	// Failing to cas indicates there is an in-flight wakeup, so we're done here.
+	if !netpollWakeSig.CompareAndSwap(0, 1) {
+		return
+	}
+
+	if stdcall4(_PostQueuedCompletionStatus, iocphandle, 0, 0, 0) == 0 {
+		println("runtime: netpoll: PostQueuedCompletionStatus failed (errno=", getlasterror(), ")")
+		throw("runtime: netpoll: PostQueuedCompletionStatus failed")
 	}
 }
 
@@ -133,7 +136,7 @@
 			}
 			handlecompletion(&toRun, op, errno, qty)
 		} else {
-			atomic.Store(&netpollWakeSig, 0)
+			netpollWakeSig.Store(0)
 			if delay == 0 {
 				// Forward the notification to the
 				// blocked poller.
diff --git a/src/runtime/os2_aix.go b/src/runtime/os2_aix.go
index 9ad1caa..2efc565 100644
--- a/src/runtime/os2_aix.go
+++ b/src/runtime/os2_aix.go
@@ -388,11 +388,11 @@
 
 //go:nosplit
 func exit(code int32) {
-	_g_ := getg()
+	gp := getg()
 
 	// Check the validity of g because without a g during
 	// newosproc0.
-	if _g_ != nil {
+	if gp != nil {
 		syscall1(&libc_exit, uintptr(code))
 		return
 	}
@@ -403,11 +403,11 @@
 
 //go:nosplit
 func write1(fd uintptr, p unsafe.Pointer, n int32) int32 {
-	_g_ := getg()
+	gp := getg()
 
 	// Check the validity of g because without a g during
 	// newosproc0.
-	if _g_ != nil {
+	if gp != nil {
 		r, errno := syscall3(&libc_write, uintptr(fd), uintptr(p), uintptr(n))
 		if int32(r) < 0 {
 			return -int32(errno)
@@ -493,11 +493,11 @@
 
 //go:nosplit
 func sigaction(sig uintptr, new, old *sigactiont) {
-	_g_ := getg()
+	gp := getg()
 
 	// Check the validity of g because without a g during
 	// runtime.libpreinit.
-	if _g_ != nil {
+	if gp != nil {
 		r, err := syscall3(&libc_sigaction, sig, uintptr(unsafe.Pointer(new)), uintptr(unsafe.Pointer(old)))
 		if int32(r) == -1 {
 			println("Sigaction failed for sig: ", sig, " with error:", hex(err))
@@ -645,11 +645,11 @@
 
 //go:nosplit
 func pthread_attr_init(attr *pthread_attr) int32 {
-	_g_ := getg()
+	gp := getg()
 
 	// Check the validity of g because without a g during
 	// newosproc0.
-	if _g_ != nil {
+	if gp != nil {
 		r, _ := syscall1(&libpthread_attr_init, uintptr(unsafe.Pointer(attr)))
 		return int32(r)
 	}
@@ -661,11 +661,11 @@
 
 //go:nosplit
 func pthread_attr_setdetachstate(attr *pthread_attr, state int32) int32 {
-	_g_ := getg()
+	gp := getg()
 
 	// Check the validity of g because without a g during
 	// newosproc0.
-	if _g_ != nil {
+	if gp != nil {
 		r, _ := syscall2(&libpthread_attr_setdetachstate, uintptr(unsafe.Pointer(attr)), uintptr(state))
 		return int32(r)
 	}
@@ -689,11 +689,11 @@
 
 //go:nosplit
 func pthread_attr_setstacksize(attr *pthread_attr, size uint64) int32 {
-	_g_ := getg()
+	gp := getg()
 
 	// Check the validity of g because without a g during
 	// newosproc0.
-	if _g_ != nil {
+	if gp != nil {
 		r, _ := syscall2(&libpthread_attr_setstacksize, uintptr(unsafe.Pointer(attr)), uintptr(size))
 		return int32(r)
 	}
@@ -705,11 +705,11 @@
 
 //go:nosplit
 func pthread_create(tid *pthread, attr *pthread_attr, fn *funcDescriptor, arg unsafe.Pointer) int32 {
-	_g_ := getg()
+	gp := getg()
 
 	// Check the validity of g because without a g during
 	// newosproc0.
-	if _g_ != nil {
+	if gp != nil {
 		r, _ := syscall4(&libpthread_create, uintptr(unsafe.Pointer(tid)), uintptr(unsafe.Pointer(attr)), uintptr(unsafe.Pointer(fn)), uintptr(arg))
 		return int32(r)
 	}
@@ -723,11 +723,11 @@
 
 //go:nosplit
 func sigprocmask(how int32, new, old *sigset) {
-	_g_ := getg()
+	gp := getg()
 
 	// Check the validity of m because it might be called during a cgo
 	// callback early enough where m isn't available yet.
-	if _g_ != nil && _g_.m != nil {
+	if gp != nil && gp.m != nil {
 		r, err := syscall3(&libpthread_sigthreadmask, uintptr(how), uintptr(unsafe.Pointer(new)), uintptr(unsafe.Pointer(old)))
 		if int32(r) != 0 {
 			println("syscall sigthreadmask failed: ", hex(err))
diff --git a/src/runtime/os3_plan9.go b/src/runtime/os3_plan9.go
index e901b3e..8c9cbe2 100644
--- a/src/runtime/os3_plan9.go
+++ b/src/runtime/os3_plan9.go
@@ -14,7 +14,9 @@
 //
 //go:nowritebarrierrec
 func sighandler(_ureg *ureg, note *byte, gp *g) int {
-	_g_ := getg()
+	gsignal := getg()
+	mp := gsignal.m
+
 	var t sigTabT
 	var docrash bool
 	var sig int
@@ -61,7 +63,7 @@
 	if flags&_SigPanic != 0 {
 		// Copy the error string from sigtramp's stack into m->notesig so
 		// we can reliably access it from the panic routines.
-		memmove(unsafe.Pointer(_g_.m.notesig), unsafe.Pointer(note), uintptr(len(notestr)+1))
+		memmove(unsafe.Pointer(mp.notesig), unsafe.Pointer(note), uintptr(len(notestr)+1))
 		gp.sig = uint32(sig)
 		gp.sigpc = c.pc()
 
@@ -120,8 +122,8 @@
 		return _NCONT
 	}
 Throw:
-	_g_.m.throwing = throwTypeRuntime
-	_g_.m.caughtsig.set(gp)
+	mp.throwing = throwTypeRuntime
+	mp.caughtsig.set(gp)
 	startpanic_m()
 	print(notestr, "\n")
 	print("PC=", hex(c.pc()), "\n")
diff --git a/src/runtime/os3_solaris.go b/src/runtime/os3_solaris.go
index 8c85b71..ffac4b6 100644
--- a/src/runtime/os3_solaris.go
+++ b/src/runtime/os3_solaris.go
@@ -7,6 +7,7 @@
 import (
 	"internal/abi"
 	"internal/goarch"
+	"runtime/internal/atomic"
 	"unsafe"
 )
 
@@ -171,18 +172,20 @@
 	// Disable signals during create, so that the new thread starts
 	// with signals disabled. It will enable them in minit.
 	sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
-	ret = pthread_create(&tid, &attr, abi.FuncPCABI0(tstart_sysvicall), unsafe.Pointer(mp))
+	ret = retryOnEAGAIN(func() int32 {
+		return pthread_create(&tid, &attr, abi.FuncPCABI0(tstart_sysvicall), unsafe.Pointer(mp))
+	})
 	sigprocmask(_SIG_SETMASK, &oset, nil)
 	if ret != 0 {
 		print("runtime: failed to create new OS thread (have ", mcount(), " already; errno=", ret, ")\n")
-		if ret == -_EAGAIN {
+		if ret == _EAGAIN {
 			println("runtime: may need to increase max user processes (ulimit -u)")
 		}
 		throw("newosproc")
 	}
 }
 
-func exitThread(wait *uint32) {
+func exitThread(wait *atomic.Uint32) {
 	// We should never reach exitThread on Solaris because we let
 	// libc clean up threads.
 	throw("exitThread")
@@ -267,7 +270,7 @@
 	return *((*uintptr)(unsafe.Pointer(&sa._funcptr)))
 }
 
-// setSignaltstackSP sets the ss_sp field of a stackt.
+// setSignalstackSP sets the ss_sp field of a stackt.
 //
 //go:nosplit
 func setSignalstackSP(s *stackt, sp uintptr) {
@@ -308,18 +311,17 @@
 	}
 
 	var sem *semt
-	_g_ := getg()
 
 	// Call libc's malloc rather than malloc. This will
 	// allocate space on the C heap. We can't call malloc
 	// here because it could cause a deadlock.
-	_g_.m.libcall.fn = uintptr(unsafe.Pointer(&libc_malloc))
-	_g_.m.libcall.n = 1
-	_g_.m.scratch = mscratch{}
-	_g_.m.scratch.v[0] = unsafe.Sizeof(*sem)
-	_g_.m.libcall.args = uintptr(unsafe.Pointer(&_g_.m.scratch))
-	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&_g_.m.libcall))
-	sem = (*semt)(unsafe.Pointer(_g_.m.libcall.r1))
+	mp.libcall.fn = uintptr(unsafe.Pointer(&libc_malloc))
+	mp.libcall.n = 1
+	mp.scratch = mscratch{}
+	mp.scratch.v[0] = unsafe.Sizeof(*sem)
+	mp.libcall.args = uintptr(unsafe.Pointer(&mp.scratch))
+	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&mp.libcall))
+	sem = (*semt)(unsafe.Pointer(mp.libcall.r1))
 	if sem_init(sem, 0, 0) != 0 {
 		throw("sem_init")
 	}
diff --git a/src/runtime/os_aix.go b/src/runtime/os_aix.go
index 15e4929..e07c7f1 100644
--- a/src/runtime/os_aix.go
+++ b/src/runtime/os_aix.go
@@ -8,6 +8,7 @@
 
 import (
 	"internal/abi"
+	"runtime/internal/atomic"
 	"unsafe"
 )
 
@@ -110,17 +111,17 @@
 	)
 
 	if pthread_attr_init(&attr) != 0 {
-		write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
+		writeErrStr(failthreadcreate)
 		exit(1)
 	}
 
 	if pthread_attr_setstacksize(&attr, threadStackSize) != 0 {
-		write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
+		writeErrStr(failthreadcreate)
 		exit(1)
 	}
 
 	if pthread_attr_setdetachstate(&attr, _PTHREAD_CREATE_DETACHED) != 0 {
-		write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
+		writeErrStr(failthreadcreate)
 		exit(1)
 	}
 
@@ -139,14 +140,12 @@
 	}
 	sigprocmask(_SIG_SETMASK, &oset, nil)
 	if ret != 0 {
-		write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
+		writeErrStr(failthreadcreate)
 		exit(1)
 	}
 
 }
 
-var failthreadcreate = []byte("runtime: failed to create new OS thread\n")
-
 // Called to do synchronous initialization of Go code built with
 // -buildmode=c-archive or -buildmode=c-shared.
 // None of the Go runtime is initialized.
@@ -164,7 +163,7 @@
 }
 
 // errno address must be retrieved by calling _Errno libc function.
-// This will return a pointer to errno
+// This will return a pointer to errno.
 func miniterrno() {
 	mp := getg().m
 	r, _ := syscall0(&libc__Errno)
@@ -212,16 +211,9 @@
 	// Disable signals during create, so that the new thread starts
 	// with signals disabled. It will enable them in minit.
 	sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
-	var ret int32
-	for tries := 0; tries < 20; tries++ {
-		// pthread_create can fail with EAGAIN for no reasons
-		// but it will be ok if it retries.
-		ret = pthread_create(&tid, &attr, &tstart, unsafe.Pointer(mp))
-		if ret != _EAGAIN {
-			break
-		}
-		usleep(uint32(tries+1) * 1000) // Milliseconds.
-	}
+	ret := retryOnEAGAIN(func() int32 {
+		return pthread_create(&tid, &attr, &tstart, unsafe.Pointer(mp))
+	})
 	sigprocmask(_SIG_SETMASK, &oset, nil)
 	if ret != 0 {
 		print("runtime: failed to create new OS thread (have ", mcount(), " already; errno=", ret, ")\n")
@@ -233,7 +225,7 @@
 
 }
 
-func exitThread(wait *uint32) {
+func exitThread(wait *atomic.Uint32) {
 	// We should never reach exitThread on AIX because we let
 	// libc clean up threads.
 	throw("exitThread")
@@ -296,7 +288,7 @@
 	return sa.sa_handler
 }
 
-// setSignaltstackSP sets the ss_sp field of a stackt.
+// setSignalstackSP sets the ss_sp field of a stackt.
 //
 //go:nosplit
 func setSignalstackSP(s *stackt, sp uintptr) {
diff --git a/src/runtime/os_darwin.go b/src/runtime/os_darwin.go
index 8562d7d..c4f3bb6 100644
--- a/src/runtime/os_darwin.go
+++ b/src/runtime/os_darwin.go
@@ -136,6 +136,8 @@
 
 	ncpu = getncpu()
 	physPageSize = getPageSize()
+
+	osinit_hack()
 }
 
 func sysctlbynameInt32(name []byte) (int32, int32) {
@@ -208,21 +210,21 @@
 	var err int32
 	err = pthread_attr_init(&attr)
 	if err != 0 {
-		write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
+		writeErrStr(failthreadcreate)
 		exit(1)
 	}
 
 	// Find out OS stack size for our own stack guard.
 	var stacksize uintptr
 	if pthread_attr_getstacksize(&attr, &stacksize) != 0 {
-		write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
+		writeErrStr(failthreadcreate)
 		exit(1)
 	}
 	mp.g0.stack.hi = stacksize // for mstart
 
 	// Tell the pthread library we won't join with this thread.
 	if pthread_attr_setdetachstate(&attr, _PTHREAD_CREATE_DETACHED) != 0 {
-		write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
+		writeErrStr(failthreadcreate)
 		exit(1)
 	}
 
@@ -230,10 +232,12 @@
 	// setup and then calls mstart.
 	var oset sigset
 	sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
-	err = pthread_create(&attr, abi.FuncPCABI0(mstart_stub), unsafe.Pointer(mp))
+	err = retryOnEAGAIN(func() int32 {
+		return pthread_create(&attr, abi.FuncPCABI0(mstart_stub), unsafe.Pointer(mp))
+	})
 	sigprocmask(_SIG_SETMASK, &oset, nil)
 	if err != 0 {
-		write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
+		writeErrStr(failthreadcreate)
 		exit(1)
 	}
 }
@@ -253,7 +257,7 @@
 	var err int32
 	err = pthread_attr_init(&attr)
 	if err != 0 {
-		write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
+		writeErrStr(failthreadcreate)
 		exit(1)
 	}
 
@@ -263,7 +267,7 @@
 	// we use the OS default stack size instead of the suggestion.
 	// Find out that stack size for our own stack guard.
 	if pthread_attr_getstacksize(&attr, &stacksize) != 0 {
-		write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
+		writeErrStr(failthreadcreate)
 		exit(1)
 	}
 	g0.stack.hi = stacksize // for mstart
@@ -271,7 +275,7 @@
 
 	// Tell the pthread library we won't join with this thread.
 	if pthread_attr_setdetachstate(&attr, _PTHREAD_CREATE_DETACHED) != 0 {
-		write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
+		writeErrStr(failthreadcreate)
 		exit(1)
 	}
 
@@ -282,14 +286,11 @@
 	err = pthread_create(&attr, fn, nil)
 	sigprocmask(_SIG_SETMASK, &oset, nil)
 	if err != 0 {
-		write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
+		writeErrStr(failthreadcreate)
 		exit(1)
 	}
 }
 
-var failallocatestack = []byte("runtime: failed to allocate stack for the new OS thread\n")
-var failthreadcreate = []byte("runtime: failed to create new OS thread\n")
-
 // Called to do synchronous initialization of Go code built with
 // -buildmode=c-archive or -buildmode=c-shared.
 // None of the Go runtime is initialized.
@@ -412,7 +413,7 @@
 	return *(*uintptr)(unsafe.Pointer(&sa.__sigaction_u))
 }
 
-// setSignaltstackSP sets the ss_sp field of a stackt.
+// setSignalstackSP sets the ss_sp field of a stackt.
 //
 //go:nosplit
 func setSignalstackSP(s *stackt, sp uintptr) {
diff --git a/src/runtime/os_dragonfly.go b/src/runtime/os_dragonfly.go
index 8347814..e467578 100644
--- a/src/runtime/os_dragonfly.go
+++ b/src/runtime/os_dragonfly.go
@@ -162,7 +162,10 @@
 	}
 
 	// TODO: Check for error.
-	lwp_create(&params)
+	retryOnEAGAIN(func() int32 {
+		lwp_create(&params)
+		return 0
+	})
 	sigprocmask(_SIG_SETMASK, &oset, nil)
 }
 
@@ -248,7 +251,7 @@
 	return sa.sa_sigaction
 }
 
-// setSignaltstackSP sets the ss_sp field of a stackt.
+// setSignalstackSP sets the ss_sp field of a stackt.
 //
 //go:nosplit
 func setSignalstackSP(s *stackt, sp uintptr) {
diff --git a/src/runtime/os_freebsd.go b/src/runtime/os_freebsd.go
index 23efd1a..f53cb11 100644
--- a/src/runtime/os_freebsd.go
+++ b/src/runtime/os_freebsd.go
@@ -213,10 +213,14 @@
 
 	var oset sigset
 	sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
-	ret := thr_new(&param, int32(unsafe.Sizeof(param)))
+	ret := retryOnEAGAIN(func() int32 {
+		errno := thr_new(&param, int32(unsafe.Sizeof(param)))
+		// thr_new returns negative errno
+		return -errno
+	})
 	sigprocmask(_SIG_SETMASK, &oset, nil)
-	if ret < 0 {
-		print("runtime: failed to create new OS thread (have ", mcount(), " already; errno=", -ret, ")\n")
+	if ret != 0 {
+		print("runtime: failed to create new OS thread (have ", mcount(), " already; errno=", ret, ")\n")
 		throw("newosproc")
 	}
 }
@@ -227,7 +231,7 @@
 func newosproc0(stacksize uintptr, fn unsafe.Pointer) {
 	stack := sysAlloc(stacksize, &memstats.stacks_sys)
 	if stack == nil {
-		write(2, unsafe.Pointer(&failallocatestack[0]), int32(len(failallocatestack)))
+		writeErrStr(failallocatestack)
 		exit(1)
 	}
 	// This code "knows" it's being called once from the library
@@ -252,14 +256,11 @@
 	ret := thr_new(&param, int32(unsafe.Sizeof(param)))
 	sigprocmask(_SIG_SETMASK, &oset, nil)
 	if ret < 0 {
-		write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
+		writeErrStr(failthreadcreate)
 		exit(1)
 	}
 }
 
-var failallocatestack = []byte("runtime: failed to allocate stack for the new OS thread\n")
-var failthreadcreate = []byte("runtime: failed to create new OS thread\n")
-
 // Called to do synchronous initialization of Go code built with
 // -buildmode=c-archive or -buildmode=c-shared.
 // None of the Go runtime is initialized.
@@ -362,7 +363,7 @@
 	return sa.sa_handler
 }
 
-// setSignaltstackSP sets the ss_sp field of a stackt.
+// setSignalstackSP sets the ss_sp field of a stackt.
 //
 //go:nosplit
 func setSignalstackSP(s *stackt, sp uintptr) {
diff --git a/src/runtime/os_freebsd_riscv64.go b/src/runtime/os_freebsd_riscv64.go
new file mode 100644
index 0000000..0f2ed50
--- /dev/null
+++ b/src/runtime/os_freebsd_riscv64.go
@@ -0,0 +1,7 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+func osArchInit() {}
diff --git a/src/runtime/os_js.go b/src/runtime/os_js.go
index 34cc027..7481fb9 100644
--- a/src/runtime/os_js.go
+++ b/src/runtime/os_js.go
@@ -7,6 +7,7 @@
 package runtime
 
 import (
+	"runtime/internal/atomic"
 	"unsafe"
 )
 
@@ -35,7 +36,7 @@
 	usleep(usec)
 }
 
-func exitThread(wait *uint32)
+func exitThread(wait *atomic.Uint32)
 
 type mOS struct{}
 
@@ -49,13 +50,13 @@
 const _SIGSEGV = 0xb
 
 func sigpanic() {
-	g := getg()
-	if !canpanic(g) {
+	gp := getg()
+	if !canpanic() {
 		throw("unexpected signal during runtime execution")
 	}
 
 	// js only invokes the exception handler for memory faults.
-	g.sig = _SIGSEGV
+	gp.sig = _SIGSEGV
 	panicmem()
 }
 
diff --git a/src/runtime/os_linux.go b/src/runtime/os_linux.go
index 25aea65..3ad1e3b 100644
--- a/src/runtime/os_linux.go
+++ b/src/runtime/os_linux.go
@@ -21,12 +21,12 @@
 	// profileTimer holds the ID of the POSIX interval timer for profiling CPU
 	// usage on this thread.
 	//
-	// It is valid when the profileTimerValid field is non-zero. A thread
+	// It is valid when the profileTimerValid field is true. A thread
 	// creates and manages its own timer, and these fields are read and written
 	// only by this thread. But because some of the reads on profileTimerValid
-	// are in signal handling code, access to that field uses atomic operations.
+	// are in signal handling code, this field should be atomic type.
 	profileTimer      int32
-	profileTimerValid uint32
+	profileTimerValid atomic.Bool
 
 	// needPerThreadSyscall indicates that a per-thread syscall is required
 	// for doAllThreadsSyscall.
@@ -176,12 +176,20 @@
 	// with signals disabled. It will enable them in minit.
 	var oset sigset
 	sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
-	ret := clone(cloneFlags, stk, unsafe.Pointer(mp), unsafe.Pointer(mp.g0), unsafe.Pointer(abi.FuncPCABI0(mstart)))
+	ret := retryOnEAGAIN(func() int32 {
+		r := clone(cloneFlags, stk, unsafe.Pointer(mp), unsafe.Pointer(mp.g0), unsafe.Pointer(abi.FuncPCABI0(mstart)))
+		// clone returns positive TID, negative errno.
+		// We don't care about the TID.
+		if r >= 0 {
+			return 0
+		}
+		return -r
+	})
 	sigprocmask(_SIG_SETMASK, &oset, nil)
 
-	if ret < 0 {
-		print("runtime: failed to create new OS thread (have ", mcount(), " already; errno=", -ret, ")\n")
-		if ret == -_EAGAIN {
+	if ret != 0 {
+		print("runtime: failed to create new OS thread (have ", mcount(), " already; errno=", ret, ")\n")
+		if ret == _EAGAIN {
 			println("runtime: may need to increase max user processes (ulimit -u)")
 		}
 		throw("newosproc")
@@ -194,19 +202,16 @@
 func newosproc0(stacksize uintptr, fn unsafe.Pointer) {
 	stack := sysAlloc(stacksize, &memstats.stacks_sys)
 	if stack == nil {
-		write(2, unsafe.Pointer(&failallocatestack[0]), int32(len(failallocatestack)))
+		writeErrStr(failallocatestack)
 		exit(1)
 	}
 	ret := clone(cloneFlags, unsafe.Pointer(uintptr(stack)+stacksize), nil, nil, fn)
 	if ret < 0 {
-		write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
+		writeErrStr(failthreadcreate)
 		exit(1)
 	}
 }
 
-var failallocatestack = []byte("runtime: failed to allocate stack for the new OS thread\n")
-var failthreadcreate = []byte("runtime: failed to create new OS thread\n")
-
 const (
 	_AT_NULL   = 0  // End of vector
 	_AT_PAGESZ = 6  // System physical page size
@@ -504,7 +509,7 @@
 	return sa.sa_handler
 }
 
-// setSignaltstackSP sets the ss_sp field of a stackt.
+// setSignalstackSP sets the ss_sp field of a stackt.
 //
 //go:nosplit
 func setSignalstackSP(s *stackt, sp uintptr) {
@@ -593,7 +598,7 @@
 
 	// Having an M means the thread interacts with the Go scheduler, and we can
 	// check whether there's an active per-thread timer for this thread.
-	if atomic.Load(&mp.profileTimerValid) != 0 {
+	if mp.profileTimerValid.Load() {
 		// If this M has its own per-thread CPU profiling interval timer, we
 		// should track the SIGPROF signals that come from that timer (for
 		// accurate reporting of its CPU usage; see issue 35057) and ignore any
@@ -619,9 +624,9 @@
 	}
 
 	// destroy any active timer
-	if atomic.Load(&mp.profileTimerValid) != 0 {
+	if mp.profileTimerValid.Load() {
 		timerid := mp.profileTimer
-		atomic.Store(&mp.profileTimerValid, 0)
+		mp.profileTimerValid.Store(false)
 		mp.profileTimer = 0
 
 		ret := timer_delete(timerid)
@@ -681,7 +686,7 @@
 	}
 
 	mp.profileTimer = timerid
-	atomic.Store(&mp.profileTimerValid, 1)
+	mp.profileTimerValid.Store(true)
 }
 
 // perThreadSyscallArgs contains the system call number, arguments, and
@@ -880,9 +885,23 @@
 	}
 	if errno != 0 || r1 != args.r1 || r2 != args.r2 {
 		print("trap:", args.trap, ", a123456=[", args.a1, ",", args.a2, ",", args.a3, ",", args.a4, ",", args.a5, ",", args.a6, "]\n")
-		print("results: got {r1=", r1, ",r2=", r2, ",errno=", errno, "}, want {r1=", args.r1, ",r2=", args.r2, ",errno=0\n")
+		print("results: got {r1=", r1, ",r2=", r2, ",errno=", errno, "}, want {r1=", args.r1, ",r2=", args.r2, ",errno=0}\n")
 		fatal("AllThreadsSyscall6 results differ between threads; runtime corrupted")
 	}
 
 	gp.m.needPerThreadSyscall.Store(0)
 }
+
+const (
+	_SI_USER  = 0
+	_SI_TKILL = -6
+)
+
+// sigFromUser reports whether the signal was sent because of a call
+// to kill or tgkill.
+//
+//go:nosplit
+func (c *sigctxt) sigFromUser() bool {
+	code := int32(c.sigcode())
+	return code == _SI_USER || code == _SI_TKILL
+}
diff --git a/src/runtime/os_linux_arm.go b/src/runtime/os_linux_arm.go
index b590da7..bd3ab44 100644
--- a/src/runtime/os_linux_arm.go
+++ b/src/runtime/os_linux_arm.go
@@ -11,6 +11,8 @@
 	_HWCAP_VFPv3 = 1 << 13 // introduced in 2.6.30
 )
 
+func vdsoCall()
+
 func checkgoarm() {
 	// On Android, /proc/self/auxv might be unreadable and hwcap won't
 	// reflect the CPU capabilities. Assume that every Android arm device
diff --git a/src/runtime/os_linux_be64.go b/src/runtime/os_linux_be64.go
index 537515f..d8d4ac2 100644
--- a/src/runtime/os_linux_be64.go
+++ b/src/runtime/os_linux_be64.go
@@ -11,7 +11,6 @@
 const (
 	_SS_DISABLE  = 2
 	_NSIG        = 65
-	_SI_USER     = 0
 	_SIG_BLOCK   = 0
 	_SIG_UNBLOCK = 1
 	_SIG_SETMASK = 2
diff --git a/src/runtime/os_linux_generic.go b/src/runtime/os_linux_generic.go
index bed9e66..15fafc1 100644
--- a/src/runtime/os_linux_generic.go
+++ b/src/runtime/os_linux_generic.go
@@ -9,7 +9,6 @@
 const (
 	_SS_DISABLE  = 2
 	_NSIG        = 65
-	_SI_USER     = 0
 	_SIG_BLOCK   = 0
 	_SIG_UNBLOCK = 1
 	_SIG_SETMASK = 2
diff --git a/src/runtime/os_linux_mips64x.go b/src/runtime/os_linux_mips64x.go
index 188db01..11d35bc 100644
--- a/src/runtime/os_linux_mips64x.go
+++ b/src/runtime/os_linux_mips64x.go
@@ -27,7 +27,6 @@
 const (
 	_SS_DISABLE  = 2
 	_NSIG        = 129
-	_SI_USER     = 0
 	_SIG_BLOCK   = 1
 	_SIG_UNBLOCK = 2
 	_SIG_SETMASK = 3
diff --git a/src/runtime/os_linux_mipsx.go b/src/runtime/os_linux_mipsx.go
index 73016f8..cdf83ff 100644
--- a/src/runtime/os_linux_mipsx.go
+++ b/src/runtime/os_linux_mipsx.go
@@ -21,7 +21,6 @@
 const (
 	_SS_DISABLE  = 2
 	_NSIG        = 128 + 1
-	_SI_USER     = 0
 	_SIG_BLOCK   = 1
 	_SIG_UNBLOCK = 2
 	_SIG_SETMASK = 3
diff --git a/src/runtime/os_netbsd.go b/src/runtime/os_netbsd.go
index 3cbace3..ce59618 100644
--- a/src/runtime/os_netbsd.go
+++ b/src/runtime/os_netbsd.go
@@ -152,16 +152,16 @@
 
 //go:nosplit
 func semasleep(ns int64) int32 {
-	_g_ := getg()
+	gp := getg()
 	var deadline int64
 	if ns >= 0 {
 		deadline = nanotime() + ns
 	}
 
 	for {
-		v := atomic.Load(&_g_.m.waitsemacount)
+		v := atomic.Load(&gp.m.waitsemacount)
 		if v > 0 {
-			if atomic.Cas(&_g_.m.waitsemacount, v, v-1) {
+			if atomic.Cas(&gp.m.waitsemacount, v, v-1) {
 				return 0 // semaphore acquired
 			}
 			continue
@@ -178,7 +178,7 @@
 			ts.setNsec(wait)
 			tsp = &ts
 		}
-		ret := lwp_park(_CLOCK_MONOTONIC, _TIMER_RELTIME, tsp, 0, unsafe.Pointer(&_g_.m.waitsemacount), nil)
+		ret := lwp_park(_CLOCK_MONOTONIC, _TIMER_RELTIME, tsp, 0, unsafe.Pointer(&gp.m.waitsemacount), nil)
 		if ret == _ETIMEDOUT {
 			return -1
 		}
@@ -227,11 +227,15 @@
 
 	lwp_mcontext_init(&uc.uc_mcontext, stk, mp, mp.g0, abi.FuncPCABI0(netbsdMstart))
 
-	ret := lwp_create(unsafe.Pointer(&uc), _LWP_DETACHED, unsafe.Pointer(&mp.procid))
+	ret := retryOnEAGAIN(func() int32 {
+		errno := lwp_create(unsafe.Pointer(&uc), _LWP_DETACHED, unsafe.Pointer(&mp.procid))
+		// lwp_create returns negative errno
+		return -errno
+	})
 	sigprocmask(_SIG_SETMASK, &oset, nil)
-	if ret < 0 {
-		print("runtime: failed to create new OS thread (have ", mcount()-1, " already; errno=", -ret, ")\n")
-		if ret == -_EAGAIN {
+	if ret != 0 {
+		print("runtime: failed to create new OS thread (have ", mcount()-1, " already; errno=", ret, ")\n")
+		if ret == _EAGAIN {
 			println("runtime: may need to increase max user processes (ulimit -p)")
 		}
 		throw("runtime.newosproc")
@@ -289,8 +293,8 @@
 // Called to initialize a new m (including the bootstrap m).
 // Called on the new thread, cannot allocate memory.
 func minit() {
-	_g_ := getg()
-	_g_.m.procid = uint64(lwp_self())
+	gp := getg()
+	gp.m.procid = uint64(lwp_self())
 
 	// On NetBSD a thread created by pthread_create inherits the
 	// signal stack of the creating thread. We always create a
@@ -299,8 +303,8 @@
 	// created in C that calls sigaltstack and then calls a Go
 	// function, because we will lose track of the C code's
 	// sigaltstack, but it's the best we can do.
-	signalstack(&_g_.m.gsignal.stack)
-	_g_.m.newSigstack = true
+	signalstack(&gp.m.gsignal.stack)
+	gp.m.newSigstack = true
 
 	minitSignalMask()
 }
@@ -352,7 +356,7 @@
 	return sa.sa_sigaction
 }
 
-// setSignaltstackSP sets the ss_sp field of a stackt.
+// setSignalstackSP sets the ss_sp field of a stackt.
 //
 //go:nosplit
 func setSignalstackSP(s *stackt, sp uintptr) {
diff --git a/src/runtime/os_openbsd.go b/src/runtime/os_openbsd.go
index 2383dc8..500286a 100644
--- a/src/runtime/os_openbsd.go
+++ b/src/runtime/os_openbsd.go
@@ -51,6 +51,21 @@
 	return out, true
 }
 
+func sysctlUint64(mib []uint32) (uint64, bool) {
+	var out uint64
+	nout := unsafe.Sizeof(out)
+	ret := sysctl(&mib[0], uint32(len(mib)), (*byte)(unsafe.Pointer(&out)), &nout, nil, 0)
+	if ret < 0 {
+		return 0, false
+	}
+	return out, true
+}
+
+//go:linkname internal_cpu_sysctlUint64 internal/cpu.sysctlUint64
+func internal_cpu_sysctlUint64(mib []uint32) (uint64, bool) {
+	return sysctlUint64(mib)
+}
+
 func getncpu() int32 {
 	// Try hw.ncpuonline first because hw.ncpu would report a number twice as
 	// high as the actual CPUs running on OpenBSD 6.4 with hyperthreading
@@ -84,7 +99,7 @@
 
 //go:nosplit
 func semasleep(ns int64) int32 {
-	_g_ := getg()
+	gp := getg()
 
 	// Compute sleep deadline.
 	var tsp *timespec
@@ -95,9 +110,9 @@
 	}
 
 	for {
-		v := atomic.Load(&_g_.m.waitsemacount)
+		v := atomic.Load(&gp.m.waitsemacount)
 		if v > 0 {
-			if atomic.Cas(&_g_.m.waitsemacount, v, v-1) {
+			if atomic.Cas(&gp.m.waitsemacount, v, v-1) {
 				return 0 // semaphore acquired
 			}
 			continue
@@ -110,7 +125,7 @@
 		// be examined [...] immediately before blocking. If that int
 		// is non-zero then __thrsleep() will immediately return EINTR
 		// without blocking."
-		ret := thrsleep(uintptr(unsafe.Pointer(&_g_.m.waitsemacount)), _CLOCK_MONOTONIC, tsp, 0, &_g_.m.waitsemacount)
+		ret := thrsleep(uintptr(unsafe.Pointer(&gp.m.waitsemacount)), _CLOCK_MONOTONIC, tsp, 0, &gp.m.waitsemacount)
 		if ret == _EWOULDBLOCK {
 			return -1
 		}
@@ -214,7 +229,7 @@
 	return sa.sa_sigaction
 }
 
-// setSignaltstackSP sets the ss_sp field of a stackt.
+// setSignalstackSP sets the ss_sp field of a stackt.
 //
 //go:nosplit
 func setSignalstackSP(s *stackt, sp uintptr) {
diff --git a/src/runtime/os_openbsd_libc.go b/src/runtime/os_openbsd_libc.go
index 4ad2a06..201f162 100644
--- a/src/runtime/os_openbsd_libc.go
+++ b/src/runtime/os_openbsd_libc.go
@@ -11,8 +11,6 @@
 	"unsafe"
 )
 
-var failThreadCreate = []byte("runtime: failed to create new OS thread\n")
-
 // mstart_stub provides glue code to call mstart from pthread_create.
 func mstart_stub()
 
@@ -27,21 +25,21 @@
 	// Initialize an attribute object.
 	var attr pthreadattr
 	if err := pthread_attr_init(&attr); err != 0 {
-		write(2, unsafe.Pointer(&failThreadCreate[0]), int32(len(failThreadCreate)))
+		writeErrStr(failthreadcreate)
 		exit(1)
 	}
 
 	// Find out OS stack size for our own stack guard.
 	var stacksize uintptr
 	if pthread_attr_getstacksize(&attr, &stacksize) != 0 {
-		write(2, unsafe.Pointer(&failThreadCreate[0]), int32(len(failThreadCreate)))
+		writeErrStr(failthreadcreate)
 		exit(1)
 	}
 	mp.g0.stack.hi = stacksize // for mstart
 
 	// Tell the pthread library we won't join with this thread.
 	if pthread_attr_setdetachstate(&attr, _PTHREAD_CREATE_DETACHED) != 0 {
-		write(2, unsafe.Pointer(&failThreadCreate[0]), int32(len(failThreadCreate)))
+		writeErrStr(failthreadcreate)
 		exit(1)
 	}
 
@@ -49,10 +47,12 @@
 	// setup and then calls mstart.
 	var oset sigset
 	sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
-	err := pthread_create(&attr, abi.FuncPCABI0(mstart_stub), unsafe.Pointer(mp))
+	err := retryOnEAGAIN(func() int32 {
+		return pthread_create(&attr, abi.FuncPCABI0(mstart_stub), unsafe.Pointer(mp))
+	})
 	sigprocmask(_SIG_SETMASK, &oset, nil)
 	if err != 0 {
-		write(2, unsafe.Pointer(&failThreadCreate[0]), int32(len(failThreadCreate)))
+		writeErrStr(failthreadcreate)
 		exit(1)
 	}
 
diff --git a/src/runtime/os_openbsd_syscall.go b/src/runtime/os_openbsd_syscall.go
index 9d67a7e..d784f76 100644
--- a/src/runtime/os_openbsd_syscall.go
+++ b/src/runtime/os_openbsd_syscall.go
@@ -34,12 +34,16 @@
 
 	var oset sigset
 	sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
-	ret := tfork(&param, unsafe.Sizeof(param), mp, mp.g0, abi.FuncPCABI0(mstart))
+	ret := retryOnEAGAIN(func() int32 {
+		errno := tfork(&param, unsafe.Sizeof(param), mp, mp.g0, abi.FuncPCABI0(mstart))
+		// tfork returns negative errno
+		return -errno
+	})
 	sigprocmask(_SIG_SETMASK, &oset, nil)
 
-	if ret < 0 {
-		print("runtime: failed to create new OS thread (have ", mcount()-1, " already; errno=", -ret, ")\n")
-		if ret == -_EAGAIN {
+	if ret != 0 {
+		print("runtime: failed to create new OS thread (have ", mcount()-1, " already; errno=", ret, ")\n")
+		if ret == _EAGAIN {
 			println("runtime: may need to increase max user processes (ulimit -p)")
 		}
 		throw("runtime.newosproc")
diff --git a/src/runtime/os_openbsd_syscall2.go b/src/runtime/os_openbsd_syscall2.go
index e4c9d2f..ebf478b 100644
--- a/src/runtime/os_openbsd_syscall2.go
+++ b/src/runtime/os_openbsd_syscall2.go
@@ -7,6 +7,7 @@
 package runtime
 
 import (
+	"runtime/internal/atomic"
 	"unsafe"
 )
 
@@ -37,7 +38,7 @@
 	usleep(usec)
 }
 
-// write calls the write system call.
+// write1 calls the write system call.
 // It returns a non-negative number of bytes written or a negative errno value.
 //
 //go:noescape
@@ -46,14 +47,14 @@
 //go:noescape
 func open(name *byte, mode, perm int32) int32
 
-// return value is only set on linux to be used in osinit()
+// return value is only set on linux to be used in osinit().
 func madvise(addr unsafe.Pointer, n uintptr, flags int32) int32
 
-// exitThread terminates the current thread, writing *wait = 0 when
+// exitThread terminates the current thread, writing *wait = freeMStack when
 // the stack is safe to reclaim.
 //
 //go:noescape
-func exitThread(wait *uint32)
+func exitThread(wait *atomic.Uint32)
 
 //go:noescape
 func obsdsigprocmask(how int32, new sigset) sigset
diff --git a/src/runtime/os_plan9.go b/src/runtime/os_plan9.go
index f0e7c6a..5e5a63d 100644
--- a/src/runtime/os_plan9.go
+++ b/src/runtime/os_plan9.go
@@ -75,13 +75,13 @@
 }
 
 func sigpanic() {
-	g := getg()
-	if !canpanic(g) {
+	gp := getg()
+	if !canpanic() {
 		throw("unexpected signal during runtime execution")
 	}
 
-	note := gostringnocopy((*byte)(unsafe.Pointer(g.m.notesig)))
-	switch g.sig {
+	note := gostringnocopy((*byte)(unsafe.Pointer(gp.m.notesig)))
+	switch gp.sig {
 	case _SIGRFAULT, _SIGWFAULT:
 		i := indexNoFloat(note, "addr=")
 		if i >= 0 {
@@ -92,17 +92,24 @@
 			panicmem()
 		}
 		addr := note[i:]
-		g.sigcode1 = uintptr(atolwhex(addr))
-		if g.sigcode1 < 0x1000 {
+		gp.sigcode1 = uintptr(atolwhex(addr))
+		if gp.sigcode1 < 0x1000 {
 			panicmem()
 		}
-		if g.paniconfault {
-			panicmemAddr(g.sigcode1)
+		if gp.paniconfault {
+			panicmemAddr(gp.sigcode1)
 		}
-		print("unexpected fault address ", hex(g.sigcode1), "\n")
+		if inUserArenaChunk(gp.sigcode1) {
+			// We could check that the arena chunk is explicitly set to fault,
+			// but the fact that we faulted on accessing it is enough to prove
+			// that it is.
+			print("accessed data from freed user arena ", hex(gp.sigcode1), "\n")
+		} else {
+			print("unexpected fault address ", hex(gp.sigcode1), "\n")
+		}
 		throw("fault")
 	case _SIGTRAP:
-		if g.paniconfault {
+		if gp.paniconfault {
 			panicmem()
 		}
 		throw(note)
@@ -461,7 +468,7 @@
 	}
 }
 
-func exitThread(wait *uint32) {
+func exitThread(wait *atomic.Uint32) {
 	// We should never reach exitThread on Plan 9 because we let
 	// the OS clean up threads.
 	throw("exitThread")
@@ -473,19 +480,19 @@
 
 //go:nosplit
 func semasleep(ns int64) int {
-	_g_ := getg()
+	gp := getg()
 	if ns >= 0 {
 		ms := timediv(ns, 1000000, nil)
 		if ms == 0 {
 			ms = 1
 		}
-		ret := plan9_tsemacquire(&_g_.m.waitsemacount, ms)
+		ret := plan9_tsemacquire(&gp.m.waitsemacount, ms)
 		if ret == 1 {
 			return 0 // success
 		}
 		return -1 // timeout or interrupted
 	}
-	for plan9_semacquire(&_g_.m.waitsemacount, 1) < 0 {
+	for plan9_semacquire(&gp.m.waitsemacount, 1) < 0 {
 		// interrupted; try again (c.f. lock_sema.go)
 	}
 	return 0 // success
diff --git a/src/runtime/os_unix_nonlinux.go b/src/runtime/os_unix_nonlinux.go
new file mode 100644
index 0000000..b98753b
--- /dev/null
+++ b/src/runtime/os_unix_nonlinux.go
@@ -0,0 +1,15 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build unix && !linux
+
+package runtime
+
+// sigFromUser reports whether the signal was sent because of a call
+// to kill.
+//
+//go:nosplit
+func (c *sigctxt) sigFromUser() bool {
+	return c.sigcode() == _SI_USER
+}
diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go
index 2f6ec75..44718f1 100644
--- a/src/runtime/os_windows.go
+++ b/src/runtime/os_windows.go
@@ -941,7 +941,7 @@
 	throw("bad newosproc0")
 }
 
-func exitThread(wait *uint32) {
+func exitThread(wait *atomic.Uint32) {
 	// We should never reach exitThread on Windows because we let
 	// the OS clean up threads.
 	throw("exitThread")
@@ -1326,7 +1326,7 @@
 	if !atomic.Cas(&mp.preemptExtLock, 0, 1) {
 		// External code is running. Fail the preemption
 		// attempt.
-		atomic.Xadd(&mp.preemptGen, 1)
+		mp.preemptGen.Add(1)
 		return
 	}
 
@@ -1336,7 +1336,7 @@
 		// The M hasn't been minit'd yet (or was just unminit'd).
 		unlock(&mp.threadLock)
 		atomic.Store(&mp.preemptExtLock, 0)
-		atomic.Xadd(&mp.preemptGen, 1)
+		mp.preemptGen.Add(1)
 		return
 	}
 	var thread uintptr
@@ -1366,7 +1366,7 @@
 		atomic.Store(&mp.preemptExtLock, 0)
 		// The thread no longer exists. This shouldn't be
 		// possible, but just acknowledge the request.
-		atomic.Xadd(&mp.preemptGen, 1)
+		mp.preemptGen.Add(1)
 		return
 	}
 
@@ -1431,7 +1431,7 @@
 	atomic.Store(&mp.preemptExtLock, 0)
 
 	// Acknowledge the preemption.
-	atomic.Xadd(&mp.preemptGen, 1)
+	mp.preemptGen.Add(1)
 
 	stdcall1(_ResumeThread, thread)
 	stdcall1(_CloseHandle, thread)
diff --git a/src/runtime/pagetrace_off.go b/src/runtime/pagetrace_off.go
new file mode 100644
index 0000000..10b44d4
--- /dev/null
+++ b/src/runtime/pagetrace_off.go
@@ -0,0 +1,28 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !goexperiment.pagetrace
+
+package runtime
+
+//go:systemstack
+func pageTraceAlloc(pp *p, now int64, base, npages uintptr) {
+}
+
+//go:systemstack
+func pageTraceFree(pp *p, now int64, base, npages uintptr) {
+}
+
+//go:systemstack
+func pageTraceScav(pp *p, now int64, base, npages uintptr) {
+}
+
+type pageTraceBuf struct {
+}
+
+func initPageTrace(env string) {
+}
+
+func finishPageTrace() {
+}
diff --git a/src/runtime/pagetrace_on.go b/src/runtime/pagetrace_on.go
new file mode 100644
index 0000000..0e621cb
--- /dev/null
+++ b/src/runtime/pagetrace_on.go
@@ -0,0 +1,358 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build goexperiment.pagetrace
+
+// Page tracer.
+//
+// This file contains an implementation of page trace instrumentation for tracking
+// the way the Go runtime manages pages of memory. The trace may be enabled at program
+// startup with the GODEBUG option pagetrace.
+//
+// Each page trace event is either 8 or 16 bytes wide. The first
+// 8 bytes follow this format for non-sync events:
+//
+//     [16 timestamp delta][35 base address][10 npages][1 isLarge][2 pageTraceEventType]
+//
+// If the "large" bit is set then the event is 16 bytes wide with the second 8 byte word
+// containing the full npages value (the npages bitfield is 0).
+//
+// The base address's bottom pageShift bits are always zero hence why we can pack other
+// data in there. We ignore the top 16 bits, assuming a 48 bit address space for the
+// heap.
+//
+// The timestamp delta is computed from the difference between the current nanotime
+// timestamp and the last sync event's timestamp. The bottom pageTraceTimeLostBits of
+// this delta is removed and only the next pageTraceTimeDeltaBits are kept.
+//
+// A sync event is emitted at the beginning of each trace buffer and whenever the
+// timestamp delta would not fit in an event.
+//
+// Sync events have the following structure:
+//
+//    [61 timestamp or P ID][1 isPID][2 pageTraceSyncEvent]
+//
+// In essence, the "large" bit repurposed to indicate whether it's a timestamp or a P ID
+// (these are typically uint32). Note that we only have 61 bits for the 64-bit timestamp,
+// but like for the delta we drop the bottom pageTraceTimeLostBits here as well.
+
+package runtime
+
+import (
+	"runtime/internal/sys"
+	"unsafe"
+)
+
+// pageTraceAlloc records a page trace allocation event.
+// pp may be nil. Call only if debug.pagetracefd != 0.
+//
+// Must run on the system stack as a crude way to prevent preemption.
+//
+//go:systemstack
+func pageTraceAlloc(pp *p, now int64, base, npages uintptr) {
+	if pageTrace.enabled {
+		if now == 0 {
+			now = nanotime()
+		}
+		pageTraceEmit(pp, now, base, npages, pageTraceAllocEvent)
+	}
+}
+
+// pageTraceFree records a page trace free event.
+// pp may be nil. Call only if debug.pagetracefd != 0.
+//
+// Must run on the system stack as a crude way to prevent preemption.
+//
+//go:systemstack
+func pageTraceFree(pp *p, now int64, base, npages uintptr) {
+	if pageTrace.enabled {
+		if now == 0 {
+			now = nanotime()
+		}
+		pageTraceEmit(pp, now, base, npages, pageTraceFreeEvent)
+	}
+}
+
+// pageTraceScav records a page trace scavenge event.
+// pp may be nil. Call only if debug.pagetracefd != 0.
+//
+// Must run on the system stack as a crude way to prevent preemption.
+//
+//go:systemstack
+func pageTraceScav(pp *p, now int64, base, npages uintptr) {
+	if pageTrace.enabled {
+		if now == 0 {
+			now = nanotime()
+		}
+		pageTraceEmit(pp, now, base, npages, pageTraceScavEvent)
+	}
+}
+
+// pageTraceEventType is a page trace event type.
+type pageTraceEventType uint8
+
+const (
+	pageTraceSyncEvent  pageTraceEventType = iota // Timestamp emission.
+	pageTraceAllocEvent                           // Allocation of pages.
+	pageTraceFreeEvent                            // Freeing pages.
+	pageTraceScavEvent                            // Scavenging pages.
+)
+
+// pageTraceEmit emits a page trace event.
+//
+// Must run on the system stack as a crude way to prevent preemption.
+//
+//go:systemstack
+func pageTraceEmit(pp *p, now int64, base, npages uintptr, typ pageTraceEventType) {
+	// Get a buffer.
+	var tbp *pageTraceBuf
+	pid := int32(-1)
+	if pp == nil {
+		// We have no P, so take the global buffer.
+		lock(&pageTrace.lock)
+		tbp = &pageTrace.buf
+	} else {
+		tbp = &pp.pageTraceBuf
+		pid = pp.id
+	}
+
+	// Initialize the buffer if necessary.
+	tb := *tbp
+	if tb.buf == nil {
+		tb.buf = (*pageTraceEvents)(sysAlloc(pageTraceBufSize, &memstats.other_sys))
+		tb = tb.writePid(pid)
+	}
+
+	// Handle timestamp and emit a sync event if necessary.
+	if now < tb.timeBase {
+		now = tb.timeBase
+	}
+	if now-tb.timeBase >= pageTraceTimeMaxDelta {
+		tb.timeBase = now
+		tb = tb.writeSync(pid)
+	}
+
+	// Emit the event.
+	tb = tb.writeEvent(pid, now, base, npages, typ)
+
+	// Write back the buffer.
+	*tbp = tb
+	if pp == nil {
+		unlock(&pageTrace.lock)
+	}
+}
+
+const (
+	pageTraceBufSize = 32 << 10
+
+	// These constants describe the per-event timestamp delta encoding.
+	pageTraceTimeLostBits  = 7  // How many bits of precision we lose in the delta.
+	pageTraceTimeDeltaBits = 16 // Size of the delta in bits.
+	pageTraceTimeMaxDelta  = 1 << (pageTraceTimeLostBits + pageTraceTimeDeltaBits)
+)
+
+// pageTraceEvents is the low-level buffer containing the trace data.
+type pageTraceEvents struct {
+	_      sys.NotInHeap
+	events [pageTraceBufSize / 8]uint64
+}
+
+// pageTraceBuf is a wrapper around pageTraceEvents that knows how to write events
+// to the buffer. It tracks state necessary to do so.
+type pageTraceBuf struct {
+	buf      *pageTraceEvents
+	len      int   // How many events have been written so far.
+	timeBase int64 // The current timestamp base from which deltas are produced.
+	finished bool  // Whether this trace buf should no longer flush anything out.
+}
+
+// writePid writes a P ID event indicating which P we're running on.
+//
+// Assumes there's always space in the buffer since this is only called at the
+// beginning of a new buffer.
+//
+// Must run on the system stack as a crude way to prevent preemption.
+//
+//go:systemstack
+func (tb pageTraceBuf) writePid(pid int32) pageTraceBuf {
+	e := uint64(int64(pid))<<3 | 0b100 | uint64(pageTraceSyncEvent)
+	tb.buf.events[tb.len] = e
+	tb.len++
+	return tb
+}
+
+// writeSync writes a sync event, which is just a timestamp. Handles flushing.
+//
+// Must run on the system stack as a crude way to prevent preemption.
+//
+//go:systemstack
+func (tb pageTraceBuf) writeSync(pid int32) pageTraceBuf {
+	if tb.len+1 > len(tb.buf.events) {
+		// N.B. flush will writeSync again.
+		return tb.flush(pid, tb.timeBase)
+	}
+	e := ((uint64(tb.timeBase) >> pageTraceTimeLostBits) << 3) | uint64(pageTraceSyncEvent)
+	tb.buf.events[tb.len] = e
+	tb.len++
+	return tb
+}
+
+// writeEvent handles writing all non-sync and non-pid events. Handles flushing if necessary.
+//
+// pid indicates the P we're currently running on. Necessary in case we need to flush.
+// now is the current nanotime timestamp.
+// base is the base address of whatever group of pages this event is happening to.
+// npages is the length of the group of pages this event is happening to.
+// typ is the event that's happening to these pages.
+//
+// Must run on the system stack as a crude way to prevent preemption.
+//
+//go:systemstack
+func (tb pageTraceBuf) writeEvent(pid int32, now int64, base, npages uintptr, typ pageTraceEventType) pageTraceBuf {
+	large := 0
+	np := npages
+	if npages >= 1024 {
+		large = 1
+		np = 0
+	}
+	if tb.len+1+large > len(tb.buf.events) {
+		tb = tb.flush(pid, now)
+	}
+	if base%pageSize != 0 {
+		throw("base address not page aligned")
+	}
+	e := uint64(base)
+	// The pageShift low-order bits are zero.
+	e |= uint64(typ)        // 2 bits
+	e |= uint64(large) << 2 // 1 bit
+	e |= uint64(np) << 3    // 10 bits
+	// Write the timestamp delta in the upper pageTraceTimeDeltaBits.
+	e |= uint64((now-tb.timeBase)>>pageTraceTimeLostBits) << (64 - pageTraceTimeDeltaBits)
+	tb.buf.events[tb.len] = e
+	if large != 0 {
+		// npages doesn't fit in 10 bits, so write an additional word with that data.
+		tb.buf.events[tb.len+1] = uint64(npages)
+	}
+	tb.len += 1 + large
+	return tb
+}
+
+// flush writes out the contents of the buffer to pageTrace.fd and resets the buffer.
+// It then writes out a P ID event and the first sync event for the new buffer.
+//
+// Must run on the system stack as a crude way to prevent preemption.
+//
+//go:systemstack
+func (tb pageTraceBuf) flush(pid int32, now int64) pageTraceBuf {
+	if !tb.finished {
+		lock(&pageTrace.fdLock)
+		writeFull(uintptr(pageTrace.fd), (*byte)(unsafe.Pointer(&tb.buf.events[0])), tb.len*8)
+		unlock(&pageTrace.fdLock)
+	}
+	tb.len = 0
+	tb.timeBase = now
+	return tb.writePid(pid).writeSync(pid)
+}
+
+var pageTrace struct {
+	// enabled indicates whether tracing is enabled. If true, fd >= 0.
+	//
+	// Safe to read without synchronization because it's only set once
+	// at program initialization.
+	enabled bool
+
+	// buf is the page trace buffer used if there is no P.
+	//
+	// lock protects buf.
+	lock mutex
+	buf  pageTraceBuf
+
+	// fdLock protects writing to fd.
+	//
+	// fd is the file to write the page trace to.
+	fdLock mutex
+	fd     int32
+}
+
+// initPageTrace initializes the page tracing infrastructure from GODEBUG.
+//
+// env must be the value of the GODEBUG environment variable.
+func initPageTrace(env string) {
+	var value string
+	for env != "" {
+		elt, rest := env, ""
+		for i := 0; i < len(env); i++ {
+			if env[i] == ',' {
+				elt, rest = env[:i], env[i+1:]
+				break
+			}
+		}
+		env = rest
+		if hasPrefix(elt, "pagetrace=") {
+			value = elt[len("pagetrace="):]
+			break
+		}
+	}
+	pageTrace.fd = -1
+	if canCreateFile && value != "" {
+		var tmp [4096]byte
+		if len(value) != 0 && len(value) < 4096 {
+			copy(tmp[:], value)
+			pageTrace.fd = create(&tmp[0], 0o664)
+		}
+	}
+	pageTrace.enabled = pageTrace.fd >= 0
+}
+
+// finishPageTrace flushes all P's trace buffers and disables page tracing.
+func finishPageTrace() {
+	if !pageTrace.enabled {
+		return
+	}
+	// Grab worldsema as we're about to execute a ragged barrier.
+	semacquire(&worldsema)
+	systemstack(func() {
+		// Disable tracing. This isn't strictly necessary and it's best-effort.
+		pageTrace.enabled = false
+
+		// Execute a ragged barrier, flushing each trace buffer.
+		forEachP(func(pp *p) {
+			if pp.pageTraceBuf.buf != nil {
+				pp.pageTraceBuf = pp.pageTraceBuf.flush(pp.id, nanotime())
+			}
+			pp.pageTraceBuf.finished = true
+		})
+
+		// Write the global have-no-P buffer.
+		lock(&pageTrace.lock)
+		if pageTrace.buf.buf != nil {
+			pageTrace.buf = pageTrace.buf.flush(-1, nanotime())
+		}
+		pageTrace.buf.finished = true
+		unlock(&pageTrace.lock)
+
+		// Safely close the file as nothing else should be allowed to write to the fd.
+		lock(&pageTrace.fdLock)
+		closefd(pageTrace.fd)
+		pageTrace.fd = -1
+		unlock(&pageTrace.fdLock)
+	})
+	semrelease(&worldsema)
+}
+
+// writeFull ensures that a complete write of bn bytes from b is made to fd.
+func writeFull(fd uintptr, b *byte, bn int) {
+	for bn > 0 {
+		n := write(fd, unsafe.Pointer(b), int32(bn))
+		if n == -_EINTR || n == -_EAGAIN {
+			continue
+		}
+		if n < 0 {
+			print("errno=", -n, "\n")
+			throw("writeBytes: bad write")
+		}
+		bn -= int(n)
+		b = addb(b, uintptr(n))
+	}
+}
diff --git a/src/runtime/panic.go b/src/runtime/panic.go
index 121f202..26618db 100644
--- a/src/runtime/panic.go
+++ b/src/runtime/panic.go
@@ -197,9 +197,9 @@
 	panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSlice3C})
 }
 
-// failures in the conversion (*[x]T)s, 0 <= x <= y, x == cap(s)
+// failures in the conversion ([x]T)(s) or (*[x]T)(s), 0 <= x <= y, y == len(s)
 func goPanicSliceConvert(x int, y int) {
-	panicCheck1(getcallerpc(), "slice length too short to convert to pointer to array")
+	panicCheck1(getcallerpc(), "slice length too short to convert to array or pointer to array")
 	panic(boundsError{x: int64(x), signed: true, y: y, code: boundsConvert})
 }
 
@@ -457,7 +457,7 @@
 			return
 		}
 		if d.openDefer {
-			done := runOpenDeferFrame(gp, d)
+			done := runOpenDeferFrame(d)
 			if !done {
 				throw("unfinished open-coded defers in deferreturn")
 			}
@@ -519,7 +519,7 @@
 		d.started = true
 		d._panic = (*_panic)(noescape(unsafe.Pointer(&p)))
 		if d.openDefer {
-			done := runOpenDeferFrame(gp, d)
+			done := runOpenDeferFrame(d)
 			if !done {
 				// We should always run all defers in the frame,
 				// since there is no panic associated with this
@@ -744,7 +744,7 @@
 // d. It normally processes all active defers in the frame, but stops immediately
 // if a defer does a successful recover. It returns true if there are no
 // remaining defers to run in the frame.
-func runOpenDeferFrame(gp *g, d *_defer) bool {
+func runOpenDeferFrame(d *_defer) bool {
 	done := true
 	fd := d.fd
 
@@ -837,7 +837,7 @@
 	p.link = gp._panic
 	gp._panic = (*_panic)(noescape(unsafe.Pointer(&p)))
 
-	atomic.Xadd(&runningPanicDefers, 1)
+	runningPanicDefers.Add(1)
 
 	// By calculating getcallerpc/getcallersp here, we avoid scanning the
 	// gopanic frame (stack scanning is slow...)
@@ -881,7 +881,7 @@
 
 		done := true
 		if d.openDefer {
-			done = runOpenDeferFrame(gp, d)
+			done = runOpenDeferFrame(d)
 			if done && !d._panic.recovered {
 				addOneOpenDeferFrame(gp, 0, nil)
 			}
@@ -917,7 +917,7 @@
 				mcall(recovery)
 				throw("bypassed recovery failed") // mcall should not return
 			}
-			atomic.Xadd(&runningPanicDefers, -1)
+			runningPanicDefers.Add(-1)
 
 			// After a recover, remove any remaining non-started,
 			// open-coded defer entries, since the corresponding defers
@@ -1067,13 +1067,11 @@
 }
 
 // runningPanicDefers is non-zero while running deferred functions for panic.
-// runningPanicDefers is incremented and decremented atomically.
 // This is used to try hard to get a panic stack trace out when exiting.
-var runningPanicDefers uint32
+var runningPanicDefers atomic.Uint32
 
 // panicking is non-zero when crashing the program for an unrecovered panic.
-// panicking is incremented and decremented atomically.
-var panicking uint32
+var panicking atomic.Uint32
 
 // paniclk is held while printing the panic information and stack trace,
 // so that two concurrent panics don't overlap their output.
@@ -1155,7 +1153,7 @@
 			// startpanic_m set panicking, which will
 			// block main from exiting, so now OK to
 			// decrement runningPanicDefers.
-			atomic.Xadd(&runningPanicDefers, -1)
+			runningPanicDefers.Add(-1)
 
 			printpanics(msgs)
 		}
@@ -1190,7 +1188,7 @@
 //
 //go:nowritebarrierrec
 func startpanic_m() bool {
-	_g_ := getg()
+	gp := getg()
 	if mheap_.cachealloc.size == 0 { // very early
 		print("runtime: panic before malloc heap initialized\n")
 	}
@@ -1198,19 +1196,19 @@
 	// could happen in a signal handler, or in a throw, or inside
 	// malloc itself. We want to catch if an allocation ever does
 	// happen (even if we're not in one of these situations).
-	_g_.m.mallocing++
+	gp.m.mallocing++
 
 	// If we're dying because of a bad lock count, set it to a
 	// good lock count so we don't recursively panic below.
-	if _g_.m.locks < 0 {
-		_g_.m.locks = 1
+	if gp.m.locks < 0 {
+		gp.m.locks = 1
 	}
 
-	switch _g_.m.dying {
+	switch gp.m.dying {
 	case 0:
 		// Setting dying >0 has the side-effect of disabling this G's writebuf.
-		_g_.m.dying = 1
-		atomic.Xadd(&panicking, 1)
+		gp.m.dying = 1
+		panicking.Add(1)
 		lock(&paniclk)
 		if debug.schedtrace > 0 || debug.scheddetail > 0 {
 			schedtrace(true)
@@ -1220,13 +1218,13 @@
 	case 1:
 		// Something failed while panicking.
 		// Just print a stack trace and exit.
-		_g_.m.dying = 2
+		gp.m.dying = 2
 		print("panic during panic\n")
 		return false
 	case 2:
 		// This is a genuine bug in the runtime, we couldn't even
 		// print the stack trace successfully.
-		_g_.m.dying = 3
+		gp.m.dying = 3
 		print("stack trace unavailable\n")
 		exit(4)
 		fallthrough
@@ -1240,6 +1238,8 @@
 var didothers bool
 var deadlock mutex
 
+// gp is the crashing g running on this M, but may be a user G, while getg() is
+// always g0.
 func dopanic_m(gp *g, pc, sp uintptr) bool {
 	if gp.sig != 0 {
 		signame := signame(gp.sig)
@@ -1252,7 +1252,6 @@
 	}
 
 	level, all, docrash := gotraceback()
-	_g_ := getg()
 	if level > 0 {
 		if gp != gp.m.curg {
 			all = true
@@ -1261,7 +1260,7 @@
 			print("\n")
 			goroutineheader(gp)
 			traceback(pc, sp, 0, gp)
-		} else if level >= 2 || _g_.m.throwing >= throwTypeRuntime {
+		} else if level >= 2 || gp.m.throwing >= throwTypeRuntime {
 			print("\nruntime stack:\n")
 			traceback(pc, sp, 0, gp)
 		}
@@ -1272,7 +1271,7 @@
 	}
 	unlock(&paniclk)
 
-	if atomic.Xadd(&panicking, -1) != 0 {
+	if panicking.Add(-1) != 0 {
 		// Some other m is panicking too.
 		// Let it print what it needs to print.
 		// Wait forever without chewing up cpu.
@@ -1290,29 +1289,32 @@
 // panicking.
 //
 //go:nosplit
-func canpanic(gp *g) bool {
-	// Note that g is m->gsignal, different from gp.
-	// Note also that g->m can change at preemption, so m can go stale
-	// if this function ever makes a function call.
-	_g_ := getg()
-	mp := _g_.m
+func canpanic() bool {
+	gp := getg()
+	mp := acquirem()
 
 	// Is it okay for gp to panic instead of crashing the program?
 	// Yes, as long as it is running Go code, not runtime code,
 	// and not stuck in a system call.
-	if gp == nil || gp != mp.curg {
+	if gp != mp.curg {
+		releasem(mp)
 		return false
 	}
-	if mp.locks != 0 || mp.mallocing != 0 || mp.throwing != throwTypeNone || mp.preemptoff != "" || mp.dying != 0 {
+	// N.B. mp.locks != 1 instead of 0 to account for acquirem.
+	if mp.locks != 1 || mp.mallocing != 0 || mp.throwing != throwTypeNone || mp.preemptoff != "" || mp.dying != 0 {
+		releasem(mp)
 		return false
 	}
 	status := readgstatus(gp)
 	if status&^_Gscan != _Grunning || gp.syscallsp != 0 {
+		releasem(mp)
 		return false
 	}
 	if GOOS == "windows" && mp.libcallsp != 0 {
+		releasem(mp)
 		return false
 	}
+	releasem(mp)
 	return true
 }
 
diff --git a/src/runtime/pprof/label.go b/src/runtime/pprof/label.go
index 0c58a7a..d39e0ad 100644
--- a/src/runtime/pprof/label.go
+++ b/src/runtime/pprof/label.go
@@ -57,8 +57,8 @@
 // WithLabels returns a new context.Context with the given labels added.
 // A label overwrites a prior label with the same key.
 func WithLabels(ctx context.Context, labels LabelSet) context.Context {
-	childLabels := make(labelMap)
 	parentLabels := labelValue(ctx)
+	childLabels := make(labelMap, len(parentLabels))
 	// TODO(matloob): replace the map implementation with something
 	// more efficient so creating a child context WithLabels doesn't need
 	// to clone the map.
diff --git a/src/runtime/pprof/pe.go b/src/runtime/pprof/pe.go
new file mode 100644
index 0000000..4105458
--- /dev/null
+++ b/src/runtime/pprof/pe.go
@@ -0,0 +1,19 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pprof
+
+import "os"
+
+// peBuildID returns a best effort unique ID for the named executable.
+//
+// It would be wasteful to calculate the hash of the whole file,
+// instead use the binary name and the last modified time for the buildid.
+func peBuildID(file string) string {
+	s, err := os.Stat(file)
+	if err != nil {
+		return file
+	}
+	return file + s.ModTime().String()
+}
diff --git a/src/runtime/pprof/pprof.go b/src/runtime/pprof/pprof.go
index f0b25c1..17a490e 100644
--- a/src/runtime/pprof/pprof.go
+++ b/src/runtime/pprof/pprof.go
@@ -74,7 +74,6 @@
 
 import (
 	"bufio"
-	"bytes"
 	"fmt"
 	"internal/abi"
 	"io"
@@ -372,8 +371,7 @@
 // as the pprof-proto format output. Translations from cycle count to time duration
 // are done because The proto expects count and time (nanoseconds) instead of count
 // and the number of cycles for block, contention profiles.
-// Possible 'scaler' functions are scaleBlockProfile and scaleMutexProfile.
-func printCountCycleProfile(w io.Writer, countName, cycleName string, scaler func(int64, float64) (int64, float64), records []runtime.BlockProfileRecord) error {
+func printCountCycleProfile(w io.Writer, countName, cycleName string, records []runtime.BlockProfileRecord) error {
 	// Output profile in protobuf form.
 	b := newProfileBuilder(w)
 	b.pbValueType(tagProfile_PeriodType, countName, "count")
@@ -386,9 +384,8 @@
 	values := []int64{0, 0}
 	var locs []uint64
 	for _, r := range records {
-		count, nanosec := scaler(r.Count, float64(r.Cycles)/cpuGHz)
-		values[0] = count
-		values[1] = int64(nanosec)
+		values[0] = r.Count
+		values[1] = int64(float64(r.Cycles) / cpuGHz)
 		// For count profiles, all stack addresses are
 		// return PCs, which is what appendLocsForStack expects.
 		locs = b.appendLocsForStack(locs[:0], r.Stack())
@@ -402,7 +399,7 @@
 // The profile will be in compressed proto format unless debug is nonzero.
 func printCountProfile(w io.Writer, debug int, name string, p countProfile) error {
 	// Build count of each stack.
-	var buf bytes.Buffer
+	var buf strings.Builder
 	key := func(stk []uintptr, lbls *labelMap) string {
 		buf.Reset()
 		fmt.Fprintf(&buf, "@")
@@ -593,10 +590,24 @@
 	// Technically the rate is MemProfileRate not 2*MemProfileRate,
 	// but early versions of the C++ heap profiler reported 2*MemProfileRate,
 	// so that's what pprof has come to expect.
+	rate := 2 * runtime.MemProfileRate
+
+	// pprof reads a profile with alloc == inuse as being a "2-column" profile
+	// (objects and bytes, not distinguishing alloc from inuse),
+	// but then such a profile can't be merged using pprof *.prof with
+	// other 4-column profiles where alloc != inuse.
+	// The easiest way to avoid this bug is to adjust allocBytes so it's never == inuseBytes.
+	// pprof doesn't use these header values anymore except for checking equality.
+	inUseBytes := total.InUseBytes()
+	allocBytes := total.AllocBytes
+	if inUseBytes == allocBytes {
+		allocBytes++
+	}
+
 	fmt.Fprintf(w, "heap profile: %d: %d [%d: %d] @ heap/%d\n",
-		total.InUseObjects(), total.InUseBytes(),
-		total.AllocObjects, total.AllocBytes,
-		2*runtime.MemProfileRate)
+		total.InUseObjects(), inUseBytes,
+		total.AllocObjects, allocBytes,
+		rate)
 
 	for i := range p {
 		r := &p[i]
@@ -842,24 +853,16 @@
 
 // writeBlock writes the current blocking profile to w.
 func writeBlock(w io.Writer, debug int) error {
-	return writeProfileInternal(w, debug, "contention", runtime.BlockProfile, scaleBlockProfile)
-}
-
-func scaleBlockProfile(cnt int64, ns float64) (int64, float64) {
-	// Do nothing.
-	// The current way of block profile sampling makes it
-	// hard to compute the unsampled number. The legacy block
-	// profile parse doesn't attempt to scale or unsample.
-	return cnt, ns
+	return writeProfileInternal(w, debug, "contention", runtime.BlockProfile)
 }
 
 // writeMutex writes the current mutex profile to w.
 func writeMutex(w io.Writer, debug int) error {
-	return writeProfileInternal(w, debug, "mutex", runtime.MutexProfile, scaleMutexProfile)
+	return writeProfileInternal(w, debug, "mutex", runtime.MutexProfile)
 }
 
-// writeProfileInternal writes the current blocking or mutex profile depending on the passed parameters
-func writeProfileInternal(w io.Writer, debug int, name string, runtimeProfile func([]runtime.BlockProfileRecord) (int, bool), scaleProfile func(int64, float64) (int64, float64)) error {
+// writeProfileInternal writes the current blocking or mutex profile depending on the passed parameters.
+func writeProfileInternal(w io.Writer, debug int, name string, runtimeProfile func([]runtime.BlockProfileRecord) (int, bool)) error {
 	var p []runtime.BlockProfileRecord
 	n, ok := runtimeProfile(nil)
 	for {
@@ -874,7 +877,7 @@
 	sort.Slice(p, func(i, j int) bool { return p[i].Cycles > p[j].Cycles })
 
 	if debug <= 0 {
-		return printCountCycleProfile(w, "contentions", "delay", scaleProfile, p)
+		return printCountCycleProfile(w, "contentions", "delay", p)
 	}
 
 	b := bufio.NewWriter(w)
@@ -904,9 +907,4 @@
 	return b.Flush()
 }
 
-func scaleMutexProfile(cnt int64, ns float64) (int64, float64) {
-	period := runtime.SetMutexProfileFraction(-1)
-	return cnt * int64(period), ns * float64(period)
-}
-
 func runtime_cyclesPerSecond() int64
diff --git a/src/runtime/pprof/pprof_norusage.go b/src/runtime/pprof/pprof_norusage.go
index 3d60525..8de3808 100644
--- a/src/runtime/pprof/pprof_norusage.go
+++ b/src/runtime/pprof/pprof_norusage.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris
+//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows
 
 package pprof
 
diff --git a/src/runtime/pprof/pprof_rusage.go b/src/runtime/pprof/pprof_rusage.go
index 984a32e..aa429fb 100644
--- a/src/runtime/pprof/pprof_rusage.go
+++ b/src/runtime/pprof/pprof_rusage.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
+//go:build unix
 
 package pprof
 
@@ -28,6 +28,8 @@
 	}
 
 	var rusage syscall.Rusage
-	syscall.Getrusage(syscall.RUSAGE_SELF, &rusage)
-	fmt.Fprintf(w, "# MaxRSS = %d\n", uintptr(rusage.Maxrss)*rssToBytes)
+	err := syscall.Getrusage(syscall.RUSAGE_SELF, &rusage)
+	if err == nil {
+		fmt.Fprintf(w, "# MaxRSS = %d\n", uintptr(rusage.Maxrss)*rssToBytes)
+	}
 }
diff --git a/src/runtime/pprof/pprof_test.go b/src/runtime/pprof/pprof_test.go
index aabc180..53688ad 100644
--- a/src/runtime/pprof/pprof_test.go
+++ b/src/runtime/pprof/pprof_test.go
@@ -12,6 +12,7 @@
 	"fmt"
 	"internal/abi"
 	"internal/profile"
+	"internal/syscall/unix"
 	"internal/testenv"
 	"io"
 	"math"
@@ -116,11 +117,8 @@
 
 	// Linux [5.9,5.16) has a kernel bug that can break CPU timers on newly
 	// created threads, breaking our CPU accounting.
-	major, minor, patch, err := linuxKernelVersion()
-	if err != nil {
-		t.Errorf("Error determining kernel version: %v", err)
-	}
-	t.Logf("Running on Linux %d.%d.%d", major, minor, patch)
+	major, minor := unix.KernelVersion()
+	t.Logf("Running on Linux %d.%d", major, minor)
 	defer func() {
 		if t.Failed() {
 			t.Logf("Failure of this test may indicate that your system suffers from a known Linux kernel bug fixed on newer kernels. See https://golang.org/issue/49065.")
@@ -530,7 +528,7 @@
 	ok = true
 
 	var samples uintptr
-	var buf bytes.Buffer
+	var buf strings.Builder
 	p := parseProfile(t, prof.Bytes(), func(count uintptr, stk []*profile.Location, labels map[string][]string) {
 		fmt.Fprintf(&buf, "%d:", count)
 		fprintStack(&buf, stk)
@@ -609,7 +607,7 @@
 		var total uintptr
 		for i, name := range need {
 			total += have[i]
-			t.Logf("%s: %d\n", name, have[i])
+			t.Logf("found %d samples in expected function %s\n", have[i], name)
 		}
 		if total == 0 {
 			t.Logf("no samples in expected functions")
@@ -720,7 +718,7 @@
 			// The place we'd see it would be the inner most frame.
 			name := stk[0].Line[0].Function.Name
 			if name == "gogo" {
-				var buf bytes.Buffer
+				var buf strings.Builder
 				fprintStack(&buf, stk)
 				t.Fatalf("found profile entry for gogo:\n%s", buf.String())
 			}
@@ -729,6 +727,9 @@
 }
 
 func fprintStack(w io.Writer, stk []*profile.Location) {
+	if len(stk) == 0 {
+		fmt.Fprintf(w, " (stack empty)")
+	}
 	for _, loc := range stk {
 		fmt.Fprintf(w, " %#x", loc.Address)
 		fmt.Fprintf(w, " (")
@@ -924,7 +925,7 @@
 	}
 
 	t.Run("debug=1", func(t *testing.T) {
-		var w bytes.Buffer
+		var w strings.Builder
 		Lookup("block").WriteTo(&w, 1)
 		prof := w.String()
 
@@ -1091,7 +1092,7 @@
 	var mu sync.Mutex
 	mu.Lock()
 	go func() {
-		awaitBlockedGoroutine(t, "semacquire", "blockMutex")
+		awaitBlockedGoroutine(t, "sync.Mutex.Lock", "blockMutex")
 		mu.Unlock()
 	}()
 	// Note: Unlock releases mu before recording the mutex event,
@@ -1196,7 +1197,7 @@
 	blockMutex(t)
 
 	t.Run("debug=1", func(t *testing.T) {
-		var w bytes.Buffer
+		var w strings.Builder
 		Lookup("mutex").WriteTo(&w, 1)
 		prof := w.String()
 		t.Logf("received profile: %v", prof)
@@ -1248,6 +1249,50 @@
 	})
 }
 
+func TestMutexProfileRateAdjust(t *testing.T) {
+	old := runtime.SetMutexProfileFraction(1)
+	defer runtime.SetMutexProfileFraction(old)
+	if old != 0 {
+		t.Fatalf("need MutexProfileRate 0, got %d", old)
+	}
+
+	readProfile := func() (contentions int64, delay int64) {
+		var w bytes.Buffer
+		Lookup("mutex").WriteTo(&w, 0)
+		p, err := profile.Parse(&w)
+		if err != nil {
+			t.Fatalf("failed to parse profile: %v", err)
+		}
+		t.Logf("parsed proto: %s", p)
+		if err := p.CheckValid(); err != nil {
+			t.Fatalf("invalid profile: %v", err)
+		}
+
+		for _, s := range p.Sample {
+			for _, l := range s.Location {
+				for _, line := range l.Line {
+					if line.Function.Name == "runtime/pprof.blockMutex.func1" {
+						contentions += s.Value[0]
+						delay += s.Value[1]
+					}
+				}
+			}
+		}
+		return
+	}
+
+	blockMutex(t)
+	contentions, delay := readProfile()
+	if contentions == 0 || delay == 0 {
+		t.Fatal("did not see expected function in profile")
+	}
+	runtime.SetMutexProfileFraction(0)
+	newContentions, newDelay := readProfile()
+	if newContentions != contentions || newDelay != delay {
+		t.Fatalf("sample value changed: got [%d, %d], want [%d, %d]", newContentions, newDelay, contentions, delay)
+	}
+}
+
 func func1(c chan int) { <-c }
 func func2(c chan int) { <-c }
 func func3(c chan int) { <-c }
@@ -1319,13 +1364,13 @@
 		t.Errorf("protobuf profile is invalid: %v", err)
 	}
 	expectedLabels := map[int64]map[string]string{
-		50: map[string]string{},
-		44: map[string]string{"label": "value"},
-		40: map[string]string{},
-		36: map[string]string{"label": "value"},
-		10: map[string]string{},
-		9:  map[string]string{"label": "value"},
-		1:  map[string]string{},
+		50: {},
+		44: {"label": "value"},
+		40: {},
+		36: {"label": "value"},
+		10: {},
+		9:  {"label": "value"},
+		1:  {},
 	}
 	if !containsCountsLabels(p, expectedLabels) {
 		t.Errorf("expected count profile to contain goroutines with counts and labels %v, got %v",
@@ -1419,7 +1464,7 @@
 				go func() {
 					defer wg.Done()
 					for ctx.Err() == nil {
-						var w bytes.Buffer
+						var w strings.Builder
 						goroutineProf.WriteTo(&w, 1)
 						prof := w.String()
 						count := profilerCalls(prof)
@@ -1437,7 +1482,7 @@
 	// The finalizer goroutine should not show up in most profiles, since it's
 	// marked as a system goroutine when idle.
 	t.Run("finalizer not present", func(t *testing.T) {
-		var w bytes.Buffer
+		var w strings.Builder
 		goroutineProf.WriteTo(&w, 1)
 		prof := w.String()
 		if includesFinalizer(prof) {
@@ -1465,7 +1510,7 @@
 				runtime.GC()
 			}
 		}
-		var w bytes.Buffer
+		var w strings.Builder
 		goroutineProf.WriteTo(&w, 1)
 		prof := w.String()
 		if !includesFinalizer(prof) {
@@ -1679,7 +1724,7 @@
 	emptyCallStackTestRun++
 
 	t.Parallel()
-	var buf bytes.Buffer
+	var buf strings.Builder
 	p := NewProfile(name)
 
 	p.Add("foo", 47674)
@@ -1759,7 +1804,7 @@
 		go func() {
 			goroutineProf := Lookup("goroutine")
 			for ctx.Err() == nil {
-				var w bytes.Buffer
+				var w strings.Builder
 				goroutineProf.WriteTo(&w, 1)
 				prof := w.String()
 				if strings.Contains(prof, "loop-i") {
@@ -1825,14 +1870,14 @@
 		isLabeled := s.Label != nil && contains(s.Label["key"], "value")
 		var (
 			mayBeLabeled     bool
-			mustBeLabeled    bool
-			mustNotBeLabeled bool
+			mustBeLabeled    string
+			mustNotBeLabeled string
 		)
 		for _, loc := range s.Location {
 			for _, l := range loc.Line {
 				switch l.Function.Name {
 				case "runtime/pprof.labelHog", "runtime/pprof.parallelLabelHog", "runtime/pprof.parallelLabelHog.func1":
-					mustBeLabeled = true
+					mustBeLabeled = l.Function.Name
 				case "runtime/pprof.Do":
 					// Do sets the labels, so samples may
 					// or may not be labeled depending on
@@ -1844,7 +1889,7 @@
 					// (such as those identified by
 					// runtime.isSystemGoroutine). These
 					// should never be labeled.
-					mustNotBeLabeled = true
+					mustNotBeLabeled = l.Function.Name
 				case "gogo", "gosave_systemstack_switch", "racecall":
 					// These are context switch/race
 					// critical that we can't do a full
@@ -1866,25 +1911,28 @@
 				}
 			}
 		}
-		if mustNotBeLabeled {
-			// If this must not be labeled, then mayBeLabeled hints
-			// are not relevant.
+		errorStack := func(f string, args ...any) {
+			var buf strings.Builder
+			fprintStack(&buf, s.Location)
+			t.Errorf("%s: %s", fmt.Sprintf(f, args...), buf.String())
+		}
+		if mustBeLabeled != "" && mustNotBeLabeled != "" {
+			errorStack("sample contains both %s, which must be labeled, and %s, which must not be labeled", mustBeLabeled, mustNotBeLabeled)
+			continue
+		}
+		if mustBeLabeled != "" || mustNotBeLabeled != "" {
+			// We found a definitive frame, so mayBeLabeled hints are not relevant.
 			mayBeLabeled = false
 		}
-		if mustBeLabeled && !isLabeled {
-			var buf bytes.Buffer
-			fprintStack(&buf, s.Location)
-			t.Errorf("Sample labeled got false want true: %s", buf.String())
+		if mayBeLabeled {
+			// This sample may or may not be labeled, so there's nothing we can check.
+			continue
 		}
-		if mustNotBeLabeled && isLabeled {
-			var buf bytes.Buffer
-			fprintStack(&buf, s.Location)
-			t.Errorf("Sample labeled got true want false: %s", buf.String())
+		if mustBeLabeled != "" && !isLabeled {
+			errorStack("sample must be labeled because of %s, but is not", mustBeLabeled)
 		}
-		if isLabeled && !(mayBeLabeled || mustBeLabeled) {
-			var buf bytes.Buffer
-			fprintStack(&buf, s.Location)
-			t.Errorf("Sample labeled got true want false: %s", buf.String())
+		if mustNotBeLabeled != "" && isLabeled {
+			errorStack("sample must not be labeled because of %s, but is", mustNotBeLabeled)
 		}
 	}
 }
diff --git a/src/runtime/pprof/pprof_windows.go b/src/runtime/pprof/pprof_windows.go
new file mode 100644
index 0000000..23ef2f8
--- /dev/null
+++ b/src/runtime/pprof/pprof_windows.go
@@ -0,0 +1,22 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pprof
+
+import (
+	"fmt"
+	"internal/syscall/windows"
+	"io"
+	"syscall"
+	"unsafe"
+)
+
+func addMaxRSS(w io.Writer) {
+	var m windows.PROCESS_MEMORY_COUNTERS
+	p, _ := syscall.GetCurrentProcess()
+	err := windows.GetProcessMemoryInfo(p, &m, uint32(unsafe.Sizeof(m)))
+	if err == nil {
+		fmt.Fprintf(w, "# MaxRSS = %d\n", m.PeakWorkingSetSize)
+	}
+}
diff --git a/src/runtime/pprof/proto.go b/src/runtime/pprof/proto.go
index 085027c..b68f30d 100644
--- a/src/runtime/pprof/proto.go
+++ b/src/runtime/pprof/proto.go
@@ -10,7 +10,6 @@
 	"fmt"
 	"internal/abi"
 	"io"
-	"os"
 	"runtime"
 	"strconv"
 	"strings"
@@ -46,10 +45,11 @@
 
 type memMap struct {
 	// initialized as reading mapping
-	start         uintptr
-	end           uintptr
-	offset        uint64
-	file, buildID string
+	start   uintptr // Address at which the binary (or DLL) is loaded into memory.
+	end     uintptr // The limit of the address range occupied by this mapping.
+	offset  uint64  // Offset in the binary that corresponds to the first mapped address.
+	file    string  // The object this entry is loaded from.
+	buildID string  // A string that uniquely identifies a particular program version with high probability.
 
 	funcs symbolizeFlag
 	fake  bool // map entry was faked; /proc/self/maps wasn't available
@@ -230,7 +230,7 @@
 		frame.PC = addr - 1
 	}
 	ret := []runtime.Frame{frame}
-	for frame.Function != "runtime.goexit" && more == true {
+	for frame.Function != "runtime.goexit" && more {
 		frame, more = frames.Next()
 		ret = append(ret, frame)
 	}
@@ -395,6 +395,10 @@
 // location ID slice, locs. The addresses in the stack are return PCs or 1 + the PC of
 // an inline marker as the runtime traceback function returns.
 //
+// It may return an empty slice even if locs is non-empty, for example if locs consists
+// solely of runtime.goexit. We still count these empty stacks in profiles in order to
+// get the right cumulative sample count.
+//
 // It may emit to b.pb, so there must be no message encoding in progress.
 func (b *profileBuilder) appendLocsForStack(locs []uint64, stk []uintptr) (newLocs []uint64) {
 	b.deck.reset()
@@ -590,6 +594,7 @@
 	type newFunc struct {
 		id         uint64
 		name, file string
+		startLine  int64
 	}
 	newFuncs := make([]newFunc, 0, 8)
 
@@ -610,7 +615,12 @@
 		if funcID == 0 {
 			funcID = uint64(len(b.funcs)) + 1
 			b.funcs[frame.Function] = int(funcID)
-			newFuncs = append(newFuncs, newFunc{funcID, frame.Function, frame.File})
+			newFuncs = append(newFuncs, newFunc{
+				id:        funcID,
+				name:      frame.Function,
+				file:      frame.File,
+				startLine: int64(runtime_FrameStartLine(&frame)),
+			})
 		}
 		b.pbLine(tagLocation_Line, funcID, int64(frame.Line))
 	}
@@ -633,6 +643,7 @@
 		b.pb.int64Opt(tagFunction_Name, b.stringIndex(fn.name))
 		b.pb.int64Opt(tagFunction_SystemName, b.stringIndex(fn.name))
 		b.pb.int64Opt(tagFunction_Filename, b.stringIndex(fn.file))
+		b.pb.int64Opt(tagFunction_StartLine, fn.startLine)
 		b.pb.endMessage(tagProfile_Function, start)
 	}
 
@@ -640,20 +651,6 @@
 	return id
 }
 
-// readMapping reads /proc/self/maps and writes mappings to b.pb.
-// It saves the address ranges of the mappings in b.mem for use
-// when emitting locations.
-func (b *profileBuilder) readMapping() {
-	data, _ := os.ReadFile("/proc/self/maps")
-	parseProcSelfMaps(data, b.addMapping)
-	if len(b.mem) == 0 { // pprof expects a map entry, so fake one.
-		b.addMappingEntry(0, 0, 0, "", "", true)
-		// TODO(hyangah): make addMapping return *memMap or
-		// take a memMap struct, and get rid of addMappingEntry
-		// that takes a bunch of positional arguments.
-	}
-}
-
 var space = []byte(" ")
 var newline = []byte("\n")
 
@@ -735,13 +732,12 @@
 			continue
 		}
 
-		// TODO: pprof's remapMappingIDs makes two adjustments:
+		// TODO: pprof's remapMappingIDs makes one adjustment:
 		// 1. If there is an /anon_hugepage mapping first and it is
 		// consecutive to a next mapping, drop the /anon_hugepage.
-		// 2. If start-offset = 0x400000, change start to 0x400000 and offset to 0.
-		// There's no indication why either of these is needed.
-		// Let's try not doing these and see what breaks.
-		// If we do need them, they would go here, before we
+		// There's no indication why this is needed.
+		// Let's try not doing this and see what breaks.
+		// If we do need it, it would go here, before we
 		// enter the mappings into b.mem in the first place.
 
 		buildID, _ := elfBuildID(file)
diff --git a/src/runtime/pprof/proto_other.go b/src/runtime/pprof/proto_other.go
new file mode 100644
index 0000000..4a7fe79
--- /dev/null
+++ b/src/runtime/pprof/proto_other.go
@@ -0,0 +1,30 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !windows
+
+package pprof
+
+import (
+	"errors"
+	"os"
+)
+
+// readMapping reads /proc/self/maps and writes mappings to b.pb.
+// It saves the address ranges of the mappings in b.mem for use
+// when emitting locations.
+func (b *profileBuilder) readMapping() {
+	data, _ := os.ReadFile("/proc/self/maps")
+	parseProcSelfMaps(data, b.addMapping)
+	if len(b.mem) == 0 { // pprof expects a map entry, so fake one.
+		b.addMappingEntry(0, 0, 0, "", "", true)
+		// TODO(hyangah): make addMapping return *memMap or
+		// take a memMap struct, and get rid of addMappingEntry
+		// that takes a bunch of positional arguments.
+	}
+}
+
+func readMainModuleMapping() (start, end uint64, err error) {
+	return 0, 0, errors.New("not implemented")
+}
diff --git a/src/runtime/pprof/proto_test.go b/src/runtime/pprof/proto_test.go
index 84a051a..780b481 100644
--- a/src/runtime/pprof/proto_test.go
+++ b/src/runtime/pprof/proto_test.go
@@ -101,6 +101,36 @@
 		addr2 = mprof.Mapping[1].Start
 		map2 = mprof.Mapping[1]
 		map2.BuildID, _ = elfBuildID(map2.File)
+	case "windows":
+		addr1 = uint64(abi.FuncPCABIInternal(f1))
+		addr2 = uint64(abi.FuncPCABIInternal(f2))
+
+		exe, err := os.Executable()
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		start, end, err := readMainModuleMapping()
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		map1 = &profile.Mapping{
+			ID:           1,
+			Start:        start,
+			Limit:        end,
+			File:         exe,
+			BuildID:      peBuildID(exe),
+			HasFunctions: true,
+		}
+		map2 = &profile.Mapping{
+			ID:           1,
+			Start:        start,
+			Limit:        end,
+			File:         exe,
+			BuildID:      peBuildID(exe),
+			HasFunctions: true,
+		}
 	case "js":
 		addr1 = uint64(abi.FuncPCABIInternal(f1))
 		addr2 = uint64(abi.FuncPCABIInternal(f2))
@@ -285,7 +315,7 @@
 			if len(out) > 0 && out[len(out)-1] != '\n' {
 				out += "\n"
 			}
-			var buf bytes.Buffer
+			var buf strings.Builder
 			parseProcSelfMaps([]byte(in), func(lo, hi, offset uint64, file, buildID string) {
 				fmt.Fprintf(&buf, "%08x %08x %08x %s\n", lo, hi, offset, file)
 			})
diff --git a/src/runtime/pprof/proto_windows.go b/src/runtime/pprof/proto_windows.go
new file mode 100644
index 0000000..d5ae4a5
--- /dev/null
+++ b/src/runtime/pprof/proto_windows.go
@@ -0,0 +1,73 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pprof
+
+import (
+	"errors"
+	"internal/syscall/windows"
+	"syscall"
+)
+
+// readMapping adds memory mapping information to the profile.
+func (b *profileBuilder) readMapping() {
+	snap, err := createModuleSnapshot()
+	if err != nil {
+		// pprof expects a map entry, so fake one, when we haven't added anything yet.
+		b.addMappingEntry(0, 0, 0, "", "", true)
+		return
+	}
+	defer func() { _ = syscall.CloseHandle(snap) }()
+
+	var module windows.ModuleEntry32
+	module.Size = uint32(windows.SizeofModuleEntry32)
+	err = windows.Module32First(snap, &module)
+	if err != nil {
+		// pprof expects a map entry, so fake one, when we haven't added anything yet.
+		b.addMappingEntry(0, 0, 0, "", "", true)
+		return
+	}
+	for err == nil {
+		exe := syscall.UTF16ToString(module.ExePath[:])
+		b.addMappingEntry(
+			uint64(module.ModBaseAddr),
+			uint64(module.ModBaseAddr)+uint64(module.ModBaseSize),
+			0,
+			exe,
+			peBuildID(exe),
+			false,
+		)
+		err = windows.Module32Next(snap, &module)
+	}
+}
+
+func readMainModuleMapping() (start, end uint64, err error) {
+	snap, err := createModuleSnapshot()
+	if err != nil {
+		return 0, 0, err
+	}
+	defer func() { _ = syscall.CloseHandle(snap) }()
+
+	var module windows.ModuleEntry32
+	module.Size = uint32(windows.SizeofModuleEntry32)
+	err = windows.Module32First(snap, &module)
+	if err != nil {
+		return 0, 0, err
+	}
+
+	return uint64(module.ModBaseAddr), uint64(module.ModBaseAddr) + uint64(module.ModBaseSize), nil
+}
+
+func createModuleSnapshot() (syscall.Handle, error) {
+	for {
+		snap, err := syscall.CreateToolhelp32Snapshot(windows.TH32CS_SNAPMODULE|windows.TH32CS_SNAPMODULE32, uint32(syscall.Getpid()))
+		var errno syscall.Errno
+		if err != nil && errors.As(err, &errno) && errno == windows.ERROR_BAD_LENGTH {
+			// When CreateToolhelp32Snapshot(SNAPMODULE|SNAPMODULE32, ...) fails
+			// with ERROR_BAD_LENGTH then it should be retried until it succeeds.
+			continue
+		}
+		return snap, err
+	}
+}
diff --git a/src/runtime/pprof/protobuf.go b/src/runtime/pprof/protobuf.go
index 7b99095..f7ec1ac 100644
--- a/src/runtime/pprof/protobuf.go
+++ b/src/runtime/pprof/protobuf.go
@@ -116,7 +116,7 @@
 }
 
 func (b *protobuf) boolOpt(tag int, x bool) {
-	if x == false {
+	if !x {
 		return
 	}
 	b.bool(tag, x)
diff --git a/src/runtime/pprof/runtime.go b/src/runtime/pprof/runtime.go
index dd2545b..57e9ca4 100644
--- a/src/runtime/pprof/runtime.go
+++ b/src/runtime/pprof/runtime.go
@@ -6,9 +6,13 @@
 
 import (
 	"context"
+	"runtime"
 	"unsafe"
 )
 
+// runtime_FrameStartLine is defined in runtime/symtab.go.
+func runtime_FrameStartLine(f *runtime.Frame) int
+
 // runtime_expandFinalInlineFrame is defined in runtime/symtab.go.
 func runtime_expandFinalInlineFrame(stk []uintptr) []uintptr
 
diff --git a/src/runtime/pprof/rusage_test.go b/src/runtime/pprof/rusage_test.go
index b82b1af..8039510 100644
--- a/src/runtime/pprof/rusage_test.go
+++ b/src/runtime/pprof/rusage_test.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
+//go:build unix
 
 package pprof
 
diff --git a/src/runtime/pprof/uname_linux_test.go b/src/runtime/pprof/uname_linux_test.go
deleted file mode 100644
index 8374c83..0000000
--- a/src/runtime/pprof/uname_linux_test.go
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build linux
-
-package pprof
-
-import (
-	"fmt"
-	"regexp"
-	"strconv"
-	"syscall"
-)
-
-var versionRe = regexp.MustCompile(`^(\d+)(?:\.(\d+)(?:\.(\d+))).*$`)
-
-func linuxKernelVersion() (major, minor, patch int, err error) {
-	var uname syscall.Utsname
-	if err := syscall.Uname(&uname); err != nil {
-		return 0, 0, 0, err
-	}
-
-	buf := make([]byte, 0, len(uname.Release))
-	for _, b := range uname.Release {
-		if b == 0 {
-			break
-		}
-		buf = append(buf, byte(b))
-	}
-	rl := string(buf)
-
-	m := versionRe.FindStringSubmatch(rl)
-	if m == nil {
-		return 0, 0, 0, fmt.Errorf("error matching version number in %q", rl)
-	}
-
-	v, err := strconv.ParseInt(m[1], 10, 64)
-	if err != nil {
-		return 0, 0, 0, fmt.Errorf("error parsing major version %q in %s: %w", m[1], rl, err)
-	}
-	major = int(v)
-
-	if len(m) >= 3 {
-		v, err := strconv.ParseInt(m[2], 10, 64)
-		if err != nil {
-			return 0, 0, 0, fmt.Errorf("error parsing minor version %q in %s: %w", m[2], rl, err)
-		}
-		minor = int(v)
-	}
-
-	if len(m) >= 4 {
-		v, err := strconv.ParseInt(m[3], 10, 64)
-		if err != nil {
-			return 0, 0, 0, fmt.Errorf("error parsing patch version %q in %s: %w", m[3], rl, err)
-		}
-		patch = int(v)
-	}
-
-	return
-}
diff --git a/src/runtime/pprof/uname_other_test.go b/src/runtime/pprof/uname_other_test.go
deleted file mode 100644
index 3276407..0000000
--- a/src/runtime/pprof/uname_other_test.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build !linux
-
-package pprof
-
-import (
-	"errors"
-)
-
-func linuxKernelVersion() (major, minor, patch int, err error) {
-	return 0, 0, 0, errors.New("not running on linux")
-}
diff --git a/src/runtime/preempt.go b/src/runtime/preempt.go
index da24f50..4f62fc6 100644
--- a/src/runtime/preempt.go
+++ b/src/runtime/preempt.go
@@ -55,7 +55,6 @@
 import (
 	"internal/abi"
 	"internal/goarch"
-	"runtime/internal/atomic"
 )
 
 type suspendGState struct {
@@ -192,7 +191,7 @@
 		case _Grunning:
 			// Optimization: if there is already a pending preemption request
 			// (from the previous loop iteration), don't bother with the atomics.
-			if gp.preemptStop && gp.preempt && gp.stackguard0 == stackPreempt && asyncM == gp.m && atomic.Load(&asyncM.preemptGen) == asyncGen {
+			if gp.preemptStop && gp.preempt && gp.stackguard0 == stackPreempt && asyncM == gp.m && asyncM.preemptGen.Load() == asyncGen {
 				break
 			}
 
@@ -208,7 +207,7 @@
 
 			// Prepare for asynchronous preemption.
 			asyncM2 := gp.m
-			asyncGen2 := atomic.Load(&asyncM2.preemptGen)
+			asyncGen2 := asyncM2.preemptGen.Load()
 			needAsync := asyncM != asyncM2 || asyncGen != asyncGen2
 			asyncM = asyncM2
 			asyncGen = asyncGen2
@@ -419,7 +418,7 @@
 		inltree := (*[1 << 20]inlinedCall)(inldata)
 		ix := pcdatavalue(f, _PCDATA_InlTreeIndex, pc, nil)
 		if ix >= 0 {
-			name = funcnameFromNameoff(f, inltree[ix].func_)
+			name = funcnameFromNameOff(f, inltree[ix].nameOff)
 		}
 	}
 	if hasPrefix(name, "runtime.") ||
diff --git a/src/runtime/preempt_amd64.s b/src/runtime/preempt_amd64.s
index 31f7c8b..94a84fb 100644
--- a/src/runtime/preempt_amd64.s
+++ b/src/runtime/preempt_amd64.s
@@ -1,6 +1,7 @@
 // Code generated by mkpreempt.go; DO NOT EDIT.
 
 #include "go_asm.h"
+#include "asm_amd64.h"
 #include "textflag.h"
 
 TEXT ·asyncPreempt(SB),NOSPLIT|NOFRAME,$0-0
@@ -27,8 +28,10 @@
 	MOVQ R14, 96(SP)
 	MOVQ R15, 104(SP)
 	#ifdef GOOS_darwin
+	#ifndef hasAVX
 	CMPB internal∕cpu·X86+const_offsetX86HasAVX(SB), $0
 	JE 2(PC)
+	#endif
 	VZEROUPPER
 	#endif
 	MOVUPS X0, 112(SP)
diff --git a/src/runtime/print.go b/src/runtime/print.go
index b2a642b..a1e0b8e 100644
--- a/src/runtime/print.go
+++ b/src/runtime/print.go
@@ -6,7 +6,6 @@
 
 import (
 	"internal/goarch"
-	"runtime/internal/atomic"
 	"unsafe"
 )
 
@@ -40,7 +39,7 @@
 func recordForPanic(b []byte) {
 	printlock()
 
-	if atomic.Load(&panicking) == 0 {
+	if panicking.Load() == 0 {
 		// Not actively crashing: maintain circular buffer of print output.
 		for i := 0; i < len(b); {
 			n := copy(printBacklog[printBacklogIndex:], b[i:])
diff --git a/src/runtime/proc.go b/src/runtime/proc.go
index 3991a48..554a60d 100644
--- a/src/runtime/proc.go
+++ b/src/runtime/proc.go
@@ -73,7 +73,7 @@
 // If there is at least one spinning thread (sched.nmspinning>1), we don't
 // unpark new threads when submitting work. To compensate for that, if the last
 // spinning thread finds work and stops spinning, it must unpark a new spinning
-// thread.  This approach smooths out unjustified spikes of thread unparking,
+// thread. This approach smooths out unjustified spikes of thread unparking,
 // but at the same time guarantees eventual maximal CPU parallelism
 // utilization.
 //
@@ -143,11 +143,11 @@
 
 // The main goroutine.
 func main() {
-	g := getg()
+	mp := getg().m
 
 	// Racectx of m0->g0 is used only as the parent of the main goroutine.
 	// It must not be used for anything else.
-	g.m.g0.racectx = 0
+	mp.g0.racectx = 0
 
 	// Max stack size is 1 GB on 64-bit, 250 MB on 32-bit.
 	// Using decimal instead of binary GB and MB because
@@ -180,7 +180,7 @@
 	// to preserve the lock.
 	lockOSThread()
 
-	if g.m != &m0 {
+	if mp != &m0 {
 		throw("runtime.main not on m0")
 	}
 
@@ -249,6 +249,7 @@
 	fn := main_main // make an indirect call, as the linker doesn't know the address of the main package when laying down the runtime
 	fn()
 	if raceenabled {
+		runExitHooks(0) // run hooks now, since racefini does not return
 		racefini()
 	}
 
@@ -256,18 +257,19 @@
 	// another goroutine at the same time as main returns,
 	// let the other goroutine finish printing the panic trace.
 	// Once it does, it will exit. See issues 3934 and 20018.
-	if atomic.Load(&runningPanicDefers) != 0 {
+	if runningPanicDefers.Load() != 0 {
 		// Running deferred functions should not take long.
 		for c := 0; c < 1000; c++ {
-			if atomic.Load(&runningPanicDefers) == 0 {
+			if runningPanicDefers.Load() == 0 {
 				break
 			}
 			Gosched()
 		}
 	}
-	if atomic.Load(&panicking) != 0 {
+	if panicking.Load() != 0 {
 		gopark(nil, nil, waitReasonPanicWait, traceEvGoStop, 1)
 	}
+	runExitHooks(0)
 
 	exit(0)
 	for {
@@ -279,8 +281,9 @@
 // os_beforeExit is called from os.Exit(0).
 //
 //go:linkname os_beforeExit os.runtime_beforeExit
-func os_beforeExit() {
-	if raceenabled {
+func os_beforeExit(exitCode int) {
+	runExitHooks(exitCode)
+	if exitCode == 0 && raceenabled {
 		racefini()
 	}
 }
@@ -295,10 +298,10 @@
 	lockInit(&forcegc.lock, lockRankForcegc)
 	for {
 		lock(&forcegc.lock)
-		if forcegc.idle != 0 {
+		if forcegc.idle.Load() {
 			throw("forcegc: phase error")
 		}
-		atomic.Store(&forcegc.idle, 1)
+		forcegc.idle.Store(true)
 		goparkunlock(&forcegc.lock, waitReasonForceGCIdle, traceEvGoBlock, 1)
 		// this goroutine is explicitly resumed by sysmon
 		if debug.gctrace > 0 {
@@ -326,6 +329,21 @@
 	mcall(goschedguarded_m)
 }
 
+// goschedIfBusy yields the processor like gosched, but only does so if
+// there are no idle Ps or if we're on the only P and there's nothing in
+// the run queue. In both cases, there is freely available idle time.
+//
+//go:nosplit
+func goschedIfBusy() {
+	gp := getg()
+	// Call gosched if gp.preempt is set; we may be in a tight loop that
+	// doesn't otherwise yield.
+	if !gp.preempt && sched.npidle.Load() > 0 {
+		return
+	}
+	mcall(gosched_m)
+}
+
 // Puts the current goroutine into a waiting state and calls unlockf on the
 // system stack.
 //
@@ -463,7 +481,7 @@
 	releasem(mp)
 }
 
-// called from assembly
+// called from assembly.
 func badmcall(fn func(*g)) {
 	throw("runtime: mcall called on m->g0 stack")
 }
@@ -476,22 +494,16 @@
 	panic(plainError("arg size to reflect.call more than 1GB"))
 }
 
-var badmorestackg0Msg = "fatal: morestack on g0\n"
-
 //go:nosplit
 //go:nowritebarrierrec
 func badmorestackg0() {
-	sp := stringStructOf(&badmorestackg0Msg)
-	write(2, sp.str, int32(sp.len))
+	writeErrStr("fatal: morestack on g0\n")
 }
 
-var badmorestackgsignalMsg = "fatal: morestack on gsignal\n"
-
 //go:nosplit
 //go:nowritebarrierrec
 func badmorestackgsignal() {
-	sp := stringStructOf(&badmorestackgsignalMsg)
-	write(2, sp.str, int32(sp.len))
+	writeErrStr("fatal: morestack on gsignal\n")
 }
 
 //go:nosplit
@@ -600,35 +612,13 @@
 	_GoidCacheBatch = 16
 )
 
-// cpuinit extracts the environment variable GODEBUG from the environment on
-// Unix-like operating systems and calls internal/cpu.Initialize.
-func cpuinit() {
-	const prefix = "GODEBUG="
-	var env string
-
+// cpuinit sets up CPU feature flags and calls internal/cpu.Initialize. env should be the complete
+// value of the GODEBUG environment variable.
+func cpuinit(env string) {
 	switch GOOS {
 	case "aix", "darwin", "ios", "dragonfly", "freebsd", "netbsd", "openbsd", "illumos", "solaris", "linux":
 		cpu.DebugOptions = true
-
-		// Similar to goenv_unix but extracts the environment value for
-		// GODEBUG directly.
-		// TODO(moehrmann): remove when general goenvs() can be called before cpuinit()
-		n := int32(0)
-		for argv_index(argv, argc+1+n) != nil {
-			n++
-		}
-
-		for i := int32(0); i < n; i++ {
-			p := argv_index(argv, argc+1+i)
-			s := *(*string)(unsafe.Pointer(&stringStruct{unsafe.Pointer(p), findnull(p)}))
-
-			if hasPrefix(s, prefix) {
-				env = gostring(p)[len(prefix):]
-				break
-			}
-		}
 	}
-
 	cpu.Initialize(env)
 
 	// Support cpu feature variables are used in code generated by the compiler
@@ -647,6 +637,35 @@
 	}
 }
 
+// getGodebugEarly extracts the environment variable GODEBUG from the environment on
+// Unix-like operating systems and returns it. This function exists to extract GODEBUG
+// early before much of the runtime is initialized.
+func getGodebugEarly() string {
+	const prefix = "GODEBUG="
+	var env string
+	switch GOOS {
+	case "aix", "darwin", "ios", "dragonfly", "freebsd", "netbsd", "openbsd", "illumos", "solaris", "linux":
+		// Similar to goenv_unix but extracts the environment value for
+		// GODEBUG directly.
+		// TODO(moehrmann): remove when general goenvs() can be called before cpuinit()
+		n := int32(0)
+		for argv_index(argv, argc+1+n) != nil {
+			n++
+		}
+
+		for i := int32(0); i < n; i++ {
+			p := argv_index(argv, argc+1+i)
+			s := unsafe.String(p, findnull(p))
+
+			if hasPrefix(s, prefix) {
+				env = gostring(p)[len(prefix):]
+				break
+			}
+		}
+	}
+	return env
+}
+
 // The bootstrap sequence is:
 //
 //	call osinit
@@ -678,9 +697,9 @@
 
 	// raceinit must be the first call to race detector.
 	// In particular, it must be done before mallocinit below calls racemapshadow.
-	_g_ := getg()
+	gp := getg()
 	if raceenabled {
-		_g_.racectx, raceprocctx0 = raceinit()
+		gp.racectx, raceprocctx0 = raceinit()
 	}
 
 	sched.maxmcount = 10000
@@ -691,30 +710,35 @@
 	moduledataverify()
 	stackinit()
 	mallocinit()
-	cpuinit()      // must run before alginit
-	alginit()      // maps, hash, fastrand must not be used before this call
-	fastrandinit() // must run before mcommoninit
-	mcommoninit(_g_.m, -1)
+	godebug := getGodebugEarly()
+	initPageTrace(godebug) // must run after mallocinit but before anything allocates
+	cpuinit(godebug)       // must run before alginit
+	alginit()              // maps, hash, fastrand must not be used before this call
+	fastrandinit()         // must run before mcommoninit
+	mcommoninit(gp.m, -1)
 	modulesinit()   // provides activeModules
 	typelinksinit() // uses maps, activeModules
 	itabsinit()     // uses activeModules
 	stkobjinit()    // must run before GC starts
 
-	sigsave(&_g_.m.sigmask)
-	initSigmask = _g_.m.sigmask
-
-	if offset := unsafe.Offsetof(sched.timeToRun); offset%8 != 0 {
-		println(offset)
-		throw("sched.timeToRun not aligned to 8 bytes")
-	}
+	sigsave(&gp.m.sigmask)
+	initSigmask = gp.m.sigmask
 
 	goargs()
 	goenvs()
 	parsedebugvars()
 	gcinit()
 
+	// if disableMemoryProfiling is set, update MemProfileRate to 0 to turn off memprofile.
+	// Note: parsedebugvars may update MemProfileRate, but when disableMemoryProfiling is
+	// set to true by the linker, it means that nothing is consuming the profile, it is
+	// safe to set MemProfileRate to 0.
+	if disableMemoryProfiling {
+		MemProfileRate = 0
+	}
+
 	lock(&sched.lock)
-	sched.lastpoll = uint64(nanotime())
+	sched.lastpoll.Store(nanotime())
 	procs := ncpu
 	if n, ok := atoi32(gogetenv("GOMAXPROCS")); ok && n > 0 {
 		procs = n
@@ -733,8 +757,8 @@
 	if debug.cgocheck > 1 {
 		writeBarrier.cgo = true
 		writeBarrier.enabled = true
-		for _, p := range allp {
-			p.wbBuf.reset()
+		for _, pp := range allp {
+			pp.wbBuf.reset()
 		}
 	}
 
@@ -751,9 +775,9 @@
 }
 
 func dumpgstatus(gp *g) {
-	_g_ := getg()
-	print("runtime: gp: gp=", gp, ", goid=", gp.goid, ", gp->atomicstatus=", readgstatus(gp), "\n")
-	print("runtime:  g:  g=", _g_, ", goid=", _g_.goid, ",  g->atomicstatus=", readgstatus(_g_), "\n")
+	thisg := getg()
+	print("runtime:   gp: gp=", gp, ", goid=", gp.goid, ", gp->atomicstatus=", readgstatus(gp), "\n")
+	print("runtime: getg:  g=", thisg, ", goid=", thisg.goid, ",  g->atomicstatus=", readgstatus(thisg), "\n")
 }
 
 // sched.lock must be held.
@@ -784,10 +808,10 @@
 
 // Pre-allocated ID may be passed as 'id', or omitted by passing -1.
 func mcommoninit(mp *m, id int64) {
-	_g_ := getg()
+	gp := getg()
 
 	// g0 stack won't make sense for user (and is not necessary unwindable).
-	if _g_ != _g_.m.g0 {
+	if gp != gp.m.g0 {
 		callers(1, mp.createstack[:])
 	}
 
@@ -832,6 +856,12 @@
 	}
 }
 
+func (mp *m) becomeSpinning() {
+	mp.spinning = true
+	sched.nmspinning.Add(1)
+	sched.needspinning.Store(0)
+}
+
 var fastrandseed uintptr
 
 func fastrandinit() {
@@ -848,7 +878,6 @@
 	status := readgstatus(gp)
 
 	// Mark runnable.
-	_g_ := getg()
 	mp := acquirem() // disable preemption because it can be holding p in a local var
 	if status&^_Gscan != _Gwaiting {
 		dumpgstatus(gp)
@@ -857,7 +886,7 @@
 
 	// status is Gwaiting or Gscanwaiting, make Grunnable and put on runq
 	casgstatus(gp, _Gwaiting, _Grunnable)
-	runqput(_g_.m.p.ptr(), gp, next)
+	runqput(mp.p.ptr(), gp, next)
 	wakep()
 	releasem(mp)
 }
@@ -868,20 +897,20 @@
 
 // freezing is set to non-zero if the runtime is trying to freeze the
 // world.
-var freezing uint32
+var freezing atomic.Bool
 
 // Similar to stopTheWorld but best-effort and can be called several times.
 // There is no reverse operation, used during crashing.
 // This function must not lock any mutexes.
 func freezetheworld() {
-	atomic.Store(&freezing, 1)
+	freezing.Store(true)
 	// stopwait and preemption requests can be lost
 	// due to races with concurrently executing threads,
 	// so try several times
 	for i := 0; i < 5; i++ {
 		// this should tell the scheduler to not start any new goroutines
 		sched.stopwait = freezeStopWait
-		atomic.Store(&sched.gcwaiting, 1)
+		sched.gcwaiting.Store(true)
 		// this should stop running goroutines
 		if !preemptall() {
 			break // no running goroutines
@@ -899,7 +928,7 @@
 //
 //go:nosplit
 func readgstatus(gp *g) uint32 {
-	return atomic.Load(&gp.atomicstatus)
+	return gp.atomicstatus.Load()
 }
 
 // The Gscanstatuses are acting like locks and this releases them.
@@ -921,7 +950,7 @@
 		_Gscansyscall,
 		_Gscanpreempted:
 		if newval == oldval&^_Gscan {
-			success = atomic.Cas(&gp.atomicstatus, oldval, newval)
+			success = gp.atomicstatus.CompareAndSwap(oldval, newval)
 		}
 	}
 	if !success {
@@ -941,7 +970,7 @@
 		_Gwaiting,
 		_Gsyscall:
 		if newval == oldval|_Gscan {
-			r := atomic.Cas(&gp.atomicstatus, oldval, newval)
+			r := gp.atomicstatus.CompareAndSwap(oldval, newval)
 			if r {
 				acquireLockRank(lockRankGscan)
 			}
@@ -954,6 +983,10 @@
 	panic("not reached")
 }
 
+// casgstatusAlwaysTrack is a debug flag that causes casgstatus to always track
+// various latencies on every transition instead of sampling them.
+var casgstatusAlwaysTrack = false
+
 // If asked to move to or from a Gscanstatus this will throw. Use the castogscanstatus
 // and casfrom_Gscanstatus instead.
 // casgstatus will loop if the g->atomicstatus is in a Gscan status until the routine that
@@ -977,15 +1010,15 @@
 
 	// loop if gp->atomicstatus is in a scan state giving
 	// GC time to finish and change the state to oldval.
-	for i := 0; !atomic.Cas(&gp.atomicstatus, oldval, newval); i++ {
-		if oldval == _Gwaiting && gp.atomicstatus == _Grunnable {
+	for i := 0; !gp.atomicstatus.CompareAndSwap(oldval, newval); i++ {
+		if oldval == _Gwaiting && gp.atomicstatus.Load() == _Grunnable {
 			throw("casgstatus: waiting for Gwaiting but is Grunnable")
 		}
 		if i == 0 {
 			nextYield = nanotime() + yieldDelay
 		}
 		if nanotime() < nextYield {
-			for x := 0; x < 10 && gp.atomicstatus != oldval; x++ {
+			for x := 0; x < 10 && gp.atomicstatus.Load() != oldval; x++ {
 				procyield(1)
 			}
 		} else {
@@ -994,37 +1027,75 @@
 		}
 	}
 
-	// Handle tracking for scheduling latencies.
 	if oldval == _Grunning {
-		// Track every 8th time a goroutine transitions out of running.
-		if gp.trackingSeq%gTrackingPeriod == 0 {
+		// Track every gTrackingPeriod time a goroutine transitions out of running.
+		if casgstatusAlwaysTrack || gp.trackingSeq%gTrackingPeriod == 0 {
 			gp.tracking = true
 		}
 		gp.trackingSeq++
 	}
-	if gp.tracking {
-		if oldval == _Grunnable {
-			// We transitioned out of runnable, so measure how much
-			// time we spent in this state and add it to
-			// runnableTime.
-			now := nanotime()
-			gp.runnableTime += now - gp.runnableStamp
-			gp.runnableStamp = 0
-		}
-		if newval == _Grunnable {
-			// We just transitioned into runnable, so record what
-			// time that happened.
-			now := nanotime()
-			gp.runnableStamp = now
-		} else if newval == _Grunning {
-			// We're transitioning into running, so turn off
-			// tracking and record how much time we spent in
-			// runnable.
-			gp.tracking = false
-			sched.timeToRun.record(gp.runnableTime)
-			gp.runnableTime = 0
-		}
+	if !gp.tracking {
+		return
 	}
+
+	// Handle various kinds of tracking.
+	//
+	// Currently:
+	// - Time spent in runnable.
+	// - Time spent blocked on a sync.Mutex or sync.RWMutex.
+	switch oldval {
+	case _Grunnable:
+		// We transitioned out of runnable, so measure how much
+		// time we spent in this state and add it to
+		// runnableTime.
+		now := nanotime()
+		gp.runnableTime += now - gp.trackingStamp
+		gp.trackingStamp = 0
+	case _Gwaiting:
+		if !gp.waitreason.isMutexWait() {
+			// Not blocking on a lock.
+			break
+		}
+		// Blocking on a lock, measure it. Note that because we're
+		// sampling, we have to multiply by our sampling period to get
+		// a more representative estimate of the absolute value.
+		// gTrackingPeriod also represents an accurate sampling period
+		// because we can only enter this state from _Grunning.
+		now := nanotime()
+		sched.totalMutexWaitTime.Add((now - gp.trackingStamp) * gTrackingPeriod)
+		gp.trackingStamp = 0
+	}
+	switch newval {
+	case _Gwaiting:
+		if !gp.waitreason.isMutexWait() {
+			// Not blocking on a lock.
+			break
+		}
+		// Blocking on a lock. Write down the timestamp.
+		now := nanotime()
+		gp.trackingStamp = now
+	case _Grunnable:
+		// We just transitioned into runnable, so record what
+		// time that happened.
+		now := nanotime()
+		gp.trackingStamp = now
+	case _Grunning:
+		// We're transitioning into running, so turn off
+		// tracking and record how much time we spent in
+		// runnable.
+		gp.tracking = false
+		sched.timeToRun.record(gp.runnableTime)
+		gp.runnableTime = 0
+	}
+}
+
+// casGToWaiting transitions gp from old to _Gwaiting, and sets the wait reason.
+//
+// Use this over casgstatus when possible to ensure that a waitreason is set.
+func casGToWaiting(gp *g, old uint32, reason waitReason) {
+	// Set the wait reason before calling casgstatus, because casgstatus will use it.
+	gp.waitreason = reason
+	casgstatus(gp, old, _Gwaiting)
 }
 
 // casgstatus(gp, oldstatus, Gcopystack), assuming oldstatus is Gwaiting or Grunnable.
@@ -1040,7 +1111,7 @@
 		if oldstatus != _Gwaiting && oldstatus != _Grunnable {
 			throw("copystack: bad status, not Gwaiting or Grunnable")
 		}
-		if atomic.Cas(&gp.atomicstatus, oldstatus, _Gcopystack) {
+		if gp.atomicstatus.CompareAndSwap(oldstatus, _Gcopystack) {
 			return oldstatus
 		}
 	}
@@ -1055,7 +1126,7 @@
 		throw("bad g transition")
 	}
 	acquireLockRank(lockRankGscan)
-	for !atomic.Cas(&gp.atomicstatus, _Grunning, _Gscan|_Gpreempted) {
+	for !gp.atomicstatus.CompareAndSwap(_Grunning, _Gscan|_Gpreempted) {
 	}
 }
 
@@ -1066,7 +1137,8 @@
 	if old != _Gpreempted || new != _Gwaiting {
 		throw("bad g transition")
 	}
-	return atomic.Cas(&gp.atomicstatus, _Gpreempted, _Gwaiting)
+	gp.waitreason = waitReasonPreempted
+	return gp.atomicstatus.CompareAndSwap(_Gpreempted, _Gwaiting)
 }
 
 // stopTheWorld stops all P's from executing goroutines, interrupting
@@ -1098,7 +1170,8 @@
 		// must have preempted all goroutines, including any attempting
 		// to scan our stack, in which case, any stack shrinking will
 		// have already completed by the time we exit.
-		casgstatus(gp, _Grunning, _Gwaiting)
+		// Don't provide a wait reason because we're still executing.
+		casGToWaiting(gp, _Grunning, waitReasonStoppingTheWorld)
 		stopTheWorldWithSema()
 		casgstatus(gp, _Gwaiting, _Grunning)
 	})
@@ -1177,41 +1250,41 @@
 // Holding worldsema causes any other goroutines invoking
 // stopTheWorld to block.
 func stopTheWorldWithSema() {
-	_g_ := getg()
+	gp := getg()
 
 	// If we hold a lock, then we won't be able to stop another M
 	// that is blocked trying to acquire the lock.
-	if _g_.m.locks > 0 {
+	if gp.m.locks > 0 {
 		throw("stopTheWorld: holding locks")
 	}
 
 	lock(&sched.lock)
 	sched.stopwait = gomaxprocs
-	atomic.Store(&sched.gcwaiting, 1)
+	sched.gcwaiting.Store(true)
 	preemptall()
 	// stop current P
-	_g_.m.p.ptr().status = _Pgcstop // Pgcstop is only diagnostic.
+	gp.m.p.ptr().status = _Pgcstop // Pgcstop is only diagnostic.
 	sched.stopwait--
 	// try to retake all P's in Psyscall status
-	for _, p := range allp {
-		s := p.status
-		if s == _Psyscall && atomic.Cas(&p.status, s, _Pgcstop) {
+	for _, pp := range allp {
+		s := pp.status
+		if s == _Psyscall && atomic.Cas(&pp.status, s, _Pgcstop) {
 			if trace.enabled {
-				traceGoSysBlock(p)
-				traceProcStop(p)
+				traceGoSysBlock(pp)
+				traceProcStop(pp)
 			}
-			p.syscalltick++
+			pp.syscalltick++
 			sched.stopwait--
 		}
 	}
 	// stop idle P's
 	now := nanotime()
 	for {
-		p, _ := pidleget(now)
-		if p == nil {
+		pp, _ := pidleget(now)
+		if pp == nil {
 			break
 		}
-		p.status = _Pgcstop
+		pp.status = _Pgcstop
 		sched.stopwait--
 	}
 	wait := sched.stopwait > 0
@@ -1234,13 +1307,13 @@
 	if sched.stopwait != 0 {
 		bad = "stopTheWorld: not stopped (stopwait != 0)"
 	} else {
-		for _, p := range allp {
-			if p.status != _Pgcstop {
+		for _, pp := range allp {
+			if pp.status != _Pgcstop {
 				bad = "stopTheWorld: not stopped (status != _Pgcstop)"
 			}
 		}
 	}
-	if atomic.Load(&freezing) != 0 {
+	if freezing.Load() {
 		// Some other thread is panicking. This can cause the
 		// sanity checks above to fail if the panic happens in
 		// the signal handler on a stopped thread. Either way,
@@ -1271,9 +1344,9 @@
 		newprocs = 0
 	}
 	p1 := procresize(procs)
-	sched.gcwaiting = 0
-	if sched.sysmonwait != 0 {
-		sched.sysmonwait = 0
+	sched.gcwaiting.Store(false)
+	if sched.sysmonwait.Load() {
+		sched.sysmonwait.Store(false)
 		notewakeup(&sched.sysmonnote)
 	}
 	unlock(&sched.lock)
@@ -1354,9 +1427,9 @@
 //go:nosplit
 //go:nowritebarrierrec
 func mstart0() {
-	_g_ := getg()
+	gp := getg()
 
-	osStack := _g_.stack.lo == 0
+	osStack := gp.stack.lo == 0
 	if osStack {
 		// Initialize stack bounds from system stack.
 		// Cgo may have left stack size in stack.hi.
@@ -1366,25 +1439,25 @@
 		// We set hi to &size, but there are things above
 		// it. The 1024 is supposed to compensate this,
 		// but is somewhat arbitrary.
-		size := _g_.stack.hi
+		size := gp.stack.hi
 		if size == 0 {
 			size = 8192 * sys.StackGuardMultiplier
 		}
-		_g_.stack.hi = uintptr(noescape(unsafe.Pointer(&size)))
-		_g_.stack.lo = _g_.stack.hi - size + 1024
+		gp.stack.hi = uintptr(noescape(unsafe.Pointer(&size)))
+		gp.stack.lo = gp.stack.hi - size + 1024
 	}
 	// Initialize stack guard so that we can start calling regular
 	// Go code.
-	_g_.stackguard0 = _g_.stack.lo + _StackGuard
+	gp.stackguard0 = gp.stack.lo + _StackGuard
 	// This is the g0, so we can also call go:systemstack
 	// functions, which check stackguard1.
-	_g_.stackguard1 = _g_.stackguard0
+	gp.stackguard1 = gp.stackguard0
 	mstart1()
 
 	// Exit this thread.
 	if mStackIsSystemAllocated() {
 		// Windows, Solaris, illumos, Darwin, AIX and Plan 9 always system-allocate
-		// the stack, but put it in _g_.stack before mstart,
+		// the stack, but put it in gp.stack before mstart,
 		// so the logic above hasn't set osStack yet.
 		osStack = true
 	}
@@ -1396,9 +1469,9 @@
 //
 //go:noinline
 func mstart1() {
-	_g_ := getg()
+	gp := getg()
 
-	if _g_ != _g_.m.g0 {
+	if gp != gp.m.g0 {
 		throw("bad runtime·mstart")
 	}
 
@@ -1408,26 +1481,26 @@
 	// so other calls can reuse the current frame.
 	// And goexit0 does a gogo that needs to return from mstart1
 	// and let mstart0 exit the thread.
-	_g_.sched.g = guintptr(unsafe.Pointer(_g_))
-	_g_.sched.pc = getcallerpc()
-	_g_.sched.sp = getcallersp()
+	gp.sched.g = guintptr(unsafe.Pointer(gp))
+	gp.sched.pc = getcallerpc()
+	gp.sched.sp = getcallersp()
 
 	asminit()
 	minit()
 
 	// Install signal handlers; after minit so that minit can
 	// prepare the thread to be able to handle the signals.
-	if _g_.m == &m0 {
+	if gp.m == &m0 {
 		mstartm0()
 	}
 
-	if fn := _g_.m.mstartfn; fn != nil {
+	if fn := gp.m.mstartfn; fn != nil {
 		fn()
 	}
 
-	if _g_.m != &m0 {
-		acquirep(_g_.m.nextp.ptr())
-		_g_.m.nextp = 0
+	if gp.m != &m0 {
+		acquirep(gp.m.nextp.ptr())
+		gp.m.nextp = 0
 	}
 	schedule()
 }
@@ -1461,7 +1534,7 @@
 // mexit tears down and exits the current thread.
 //
 // Don't call this directly to exit the thread, since it must run at
-// the top of the thread stack. Instead, use gogo(&_g_.m.g0.sched) to
+// the top of the thread stack. Instead, use gogo(&gp.m.g0.sched) to
 // unwind the stack to the point that exits the thread.
 //
 // It is entered with m.p != nil, so write barriers are allowed. It
@@ -1469,10 +1542,9 @@
 //
 //go:yeswritebarrierrec
 func mexit(osStack bool) {
-	g := getg()
-	m := g.m
+	mp := getg().m
 
-	if m == &m0 {
+	if mp == &m0 {
 		// This is the main thread. Just wedge it.
 		//
 		// On Linux, exiting the main thread puts the process
@@ -1497,41 +1569,40 @@
 	unminit()
 
 	// Free the gsignal stack.
-	if m.gsignal != nil {
-		stackfree(m.gsignal.stack)
+	if mp.gsignal != nil {
+		stackfree(mp.gsignal.stack)
 		// On some platforms, when calling into VDSO (e.g. nanotime)
 		// we store our g on the gsignal stack, if there is one.
 		// Now the stack is freed, unlink it from the m, so we
 		// won't write to it when calling VDSO code.
-		m.gsignal = nil
+		mp.gsignal = nil
 	}
 
 	// Remove m from allm.
 	lock(&sched.lock)
 	for pprev := &allm; *pprev != nil; pprev = &(*pprev).alllink {
-		if *pprev == m {
-			*pprev = m.alllink
+		if *pprev == mp {
+			*pprev = mp.alllink
 			goto found
 		}
 	}
 	throw("m not found in allm")
 found:
-	if !osStack {
-		// Delay reaping m until it's done with the stack.
-		//
-		// If this is using an OS stack, the OS will free it
-		// so there's no need for reaping.
-		atomic.Store(&m.freeWait, 1)
-		// Put m on the free list, though it will not be reaped until
-		// freeWait is 0. Note that the free list must not be linked
-		// through alllink because some functions walk allm without
-		// locking, so may be using alllink.
-		m.freelink = sched.freem
-		sched.freem = m
-	}
+	// Delay reaping m until it's done with the stack.
+	//
+	// Put mp on the free list, though it will not be reaped while freeWait
+	// is freeMWait. mp is no longer reachable via allm, so even if it is
+	// on an OS stack, we must keep a reference to mp alive so that the GC
+	// doesn't free mp while we are still using it.
+	//
+	// Note that the free list must not be linked through alllink because
+	// some functions walk allm without locking, so may be using alllink.
+	mp.freeWait.Store(freeMWait)
+	mp.freelink = sched.freem
+	sched.freem = mp
 	unlock(&sched.lock)
 
-	atomic.Xadd64(&ncgocall, int64(m.ncgocall))
+	atomic.Xadd64(&ncgocall, int64(mp.ncgocall))
 
 	// Release the P.
 	handoffp(releasep())
@@ -1548,16 +1619,19 @@
 	if GOOS == "darwin" || GOOS == "ios" {
 		// Make sure pendingPreemptSignals is correct when an M exits.
 		// For #41702.
-		if atomic.Load(&m.signalPending) != 0 {
-			atomic.Xadd(&pendingPreemptSignals, -1)
+		if mp.signalPending.Load() != 0 {
+			pendingPreemptSignals.Add(-1)
 		}
 	}
 
 	// Destroy all allocated resources. After this is called, we may no
 	// longer take any locks.
-	mdestroy(m)
+	mdestroy(mp)
 
 	if osStack {
+		// No more uses of mp, so it is safe to drop the reference.
+		mp.freeWait.Store(freeMRef)
+
 		// Return from mstart and let the system thread
 		// library free the g0 stack and terminate the thread.
 		return
@@ -1567,7 +1641,7 @@
 	// return to. Exit the thread directly. exitThread will clear
 	// m.freeWait when it's done with the stack and the m can be
 	// reaped.
-	exitThread(&m.freeWait)
+	exitThread(&mp.freeWait)
 }
 
 // forEachP calls fn(p) for every P p when p reaches a GC safe point.
@@ -1583,7 +1657,7 @@
 //go:systemstack
 func forEachP(fn func(*p)) {
 	mp := acquirem()
-	_p_ := getg().m.p.ptr()
+	pp := getg().m.p.ptr()
 
 	lock(&sched.lock)
 	if sched.safePointWait != 0 {
@@ -1593,9 +1667,9 @@
 	sched.safePointFn = fn
 
 	// Ask all Ps to run the safe point function.
-	for _, p := range allp {
-		if p != _p_ {
-			atomic.Store(&p.runSafePointFn, 1)
+	for _, p2 := range allp {
+		if p2 != pp {
+			atomic.Store(&p2.runSafePointFn, 1)
 		}
 	}
 	preemptall()
@@ -1617,19 +1691,19 @@
 	unlock(&sched.lock)
 
 	// Run fn for the current P.
-	fn(_p_)
+	fn(pp)
 
 	// Force Ps currently in _Psyscall into _Pidle and hand them
 	// off to induce safe point function execution.
-	for _, p := range allp {
-		s := p.status
-		if s == _Psyscall && p.runSafePointFn == 1 && atomic.Cas(&p.status, s, _Pidle) {
+	for _, p2 := range allp {
+		s := p2.status
+		if s == _Psyscall && p2.runSafePointFn == 1 && atomic.Cas(&p2.status, s, _Pidle) {
 			if trace.enabled {
-				traceGoSysBlock(p)
-				traceProcStop(p)
+				traceGoSysBlock(p2)
+				traceProcStop(p2)
 			}
-			p.syscalltick++
-			handoffp(p)
+			p2.syscalltick++
+			handoffp(p2)
 		}
 	}
 
@@ -1650,8 +1724,8 @@
 	if sched.safePointWait != 0 {
 		throw("forEachP: not done")
 	}
-	for _, p := range allp {
-		if p.runSafePointFn != 0 {
+	for _, p2 := range allp {
+		if p2.runSafePointFn != 0 {
 			throw("forEachP: P did not run fn")
 		}
 	}
@@ -1707,20 +1781,20 @@
 // id is optional pre-allocated m ID. Omit by passing -1.
 //
 // This function is allowed to have write barriers even if the caller
-// isn't because it borrows _p_.
+// isn't because it borrows pp.
 //
 //go:yeswritebarrierrec
-func allocm(_p_ *p, fn func(), id int64) *m {
+func allocm(pp *p, fn func(), id int64) *m {
 	allocmLock.rlock()
 
-	// The caller owns _p_, but we may borrow (i.e., acquirep) it. We must
+	// The caller owns pp, but we may borrow (i.e., acquirep) it. We must
 	// disable preemption to ensure it is not stolen, which would make the
 	// caller lose ownership.
 	acquirem()
 
-	_g_ := getg()
-	if _g_.m.p == 0 {
-		acquirep(_p_) // temporarily borrow p for mallocs in this function
+	gp := getg()
+	if gp.m.p == 0 {
+		acquirep(pp) // temporarily borrow p for mallocs in this function
 	}
 
 	// Release the free M list. We need to do this somewhere and
@@ -1729,19 +1803,25 @@
 		lock(&sched.lock)
 		var newList *m
 		for freem := sched.freem; freem != nil; {
-			if freem.freeWait != 0 {
+			wait := freem.freeWait.Load()
+			if wait == freeMWait {
 				next := freem.freelink
 				freem.freelink = newList
 				newList = freem
 				freem = next
 				continue
 			}
-			// stackfree must be on the system stack, but allocm is
-			// reachable off the system stack transitively from
-			// startm.
-			systemstack(func() {
-				stackfree(freem.g0.stack)
-			})
+			// Free the stack if needed. For freeMRef, there is
+			// nothing to do except drop freem from the sched.freem
+			// list.
+			if wait == freeMStack {
+				// stackfree must be on the system stack, but allocm is
+				// reachable off the system stack transitively from
+				// startm.
+				systemstack(func() {
+					stackfree(freem.g0.stack)
+				})
+			}
 			freem = freem.freelink
 		}
 		sched.freem = newList
@@ -1761,11 +1841,11 @@
 	}
 	mp.g0.m = mp
 
-	if _p_ == _g_.m.p.ptr() {
+	if pp == gp.m.p.ptr() {
 		releasep()
 	}
 
-	releasem(_g_.m)
+	releasem(gp.m)
 	allocmLock.runlock()
 	return mp
 }
@@ -1813,7 +1893,7 @@
 		// for details.
 		//
 		// Can not throw, because scheduler is not initialized yet.
-		write(2, unsafe.Pointer(&earlycgocallback[0]), int32(len(earlycgocallback)))
+		writeErrStr("fatal error: cgo callback before cgo call\n")
 		exit(1)
 	}
 
@@ -1859,10 +1939,10 @@
 	// scheduling stack is, but we assume there's at least 32 kB,
 	// which is more than enough for us.
 	setg(mp.g0)
-	_g_ := getg()
-	_g_.stack.hi = getcallersp() + 1024
-	_g_.stack.lo = getcallersp() - 32*1024
-	_g_.stackguard0 = _g_.stack.lo + _StackGuard
+	gp := getg()
+	gp.stack.hi = getcallersp() + 1024
+	gp.stack.lo = getcallersp() - 32*1024
+	gp.stackguard0 = gp.stack.lo + _StackGuard
 
 	// Initialize this thread to use the m.
 	asminit()
@@ -1870,16 +1950,14 @@
 
 	// mp.curg is now a real goroutine.
 	casgstatus(mp.curg, _Gdead, _Gsyscall)
-	atomic.Xadd(&sched.ngsys, -1)
+	sched.ngsys.Add(-1)
 }
 
-var earlycgocallback = []byte("fatal error: cgo callback before cgo call\n")
-
 // newextram allocates m's and puts them on the extra list.
 // It is called with a working local m, so that it can do things
 // like call schedlock and allocate.
 func newextram() {
-	c := atomic.Xchg(&extraMWaiters, 0)
+	c := extraMWaiters.Swap(0)
 	if c > 0 {
 		for i := uint32(0); i < c; i++ {
 			oneNewExtraM()
@@ -1918,13 +1996,23 @@
 	casgstatus(gp, _Gidle, _Gdead)
 	gp.m = mp
 	mp.curg = gp
+	mp.isextra = true
 	mp.lockedInt++
 	mp.lockedg.set(gp)
 	gp.lockedm.set(mp)
-	gp.goid = int64(atomic.Xadd64(&sched.goidgen, 1))
+	gp.goid = sched.goidgen.Add(1)
+	gp.sysblocktraced = true
 	if raceenabled {
 		gp.racectx = racegostart(abi.FuncPCABIInternal(newextram) + sys.PCQuantum)
 	}
+	if trace.enabled {
+		// Trigger two trace events for the locked g in the extra m,
+		// since the next event of the g will be traceEvGoSysExit in exitsyscall,
+		// while calling from C thread to Go.
+		traceGoCreate(gp, 0) // no start pc
+		gp.traceseq++
+		traceEvent(traceEvGoInSyscall, -1, gp.goid)
+	}
 	// put on allg for garbage collector
 	allgadd(gp)
 
@@ -1932,7 +2020,7 @@
 	// counted by gcount. It would be more "proper" to increment
 	// sched.ngfree, but that requires locking. Incrementing ngsys
 	// has the same effect.
-	atomic.Xadd(&sched.ngsys, +1)
+	sched.ngsys.Add(1)
 
 	// Add m to the extra list.
 	mnext := lockextra(true)
@@ -1973,7 +2061,7 @@
 	// Return mp.curg to dead state.
 	casgstatus(mp.curg, _Gsyscall, _Gdead)
 	mp.curg.preemptStop = false
-	atomic.Xadd(&sched.ngsys, +1)
+	sched.ngsys.Add(1)
 
 	// Block signals before unminit.
 	// Unminit unregisters the signal handling stack (but needs g on some systems).
@@ -2000,9 +2088,9 @@
 	return uintptr(unsafe.Pointer(getg().m))
 }
 
-var extram uintptr
+var extram atomic.Uintptr
 var extraMCount uint32 // Protected by lockextra
-var extraMWaiters uint32
+var extraMWaiters atomic.Uint32
 
 // lockextra locks the extra list and returns the list head.
 // The caller must unlock the list by storing a new list head
@@ -2016,7 +2104,7 @@
 
 	incr := false
 	for {
-		old := atomic.Loaduintptr(&extram)
+		old := extram.Load()
 		if old == locked {
 			osyield_no_g()
 			continue
@@ -2026,13 +2114,13 @@
 				// Add 1 to the number of threads
 				// waiting for an M.
 				// This is cleared by newextram.
-				atomic.Xadd(&extraMWaiters, 1)
+				extraMWaiters.Add(1)
 				incr = true
 			}
 			usleep_no_g(1)
 			continue
 		}
-		if atomic.Casuintptr(&extram, old, locked) {
+		if extram.CompareAndSwap(old, locked) {
 			return (*m)(unsafe.Pointer(old))
 		}
 		osyield_no_g()
@@ -2042,7 +2130,7 @@
 
 //go:nosplit
 func unlockextra(mp *m) {
-	atomic.Storeuintptr(&extram, uintptr(unsafe.Pointer(mp)))
+	extram.Store(uintptr(unsafe.Pointer(mp)))
 }
 
 var (
@@ -2057,6 +2145,13 @@
 	execLock rwmutex
 )
 
+// These errors are reported (via writeErrStr) by some OS-specific
+// versions of newosproc and newosproc0.
+const (
+	failthreadcreate  = "runtime: failed to create new OS thread\n"
+	failallocatestack = "runtime: failed to allocate stack for the new OS thread\n"
+)
+
 // newmHandoff contains a list of m structures that need new OS threads.
 // This is used by newm in situations where newm itself can't safely
 // start an OS thread.
@@ -2085,7 +2180,7 @@
 // id is optional pre-allocated m ID. Omit by passing -1.
 //
 //go:nowritebarrierrec
-func newm(fn func(), _p_ *p, id int64) {
+func newm(fn func(), pp *p, id int64) {
 	// allocm adds a new M to allm, but they do not start until created by
 	// the OS in newm1 or the template thread.
 	//
@@ -2098,8 +2193,8 @@
 	// start.
 	acquirem()
 
-	mp := allocm(_p_, fn, id)
-	mp.nextp.set(_p_)
+	mp := allocm(pp, fn, id)
+	mp.nextp.set(pp)
 	mp.sigmask = initSigmask
 	if gp := getg(); gp != nil && gp.m != nil && (gp.m.lockedExt != 0 || gp.m.incgo) && GOOS != "plan9" {
 		// We're on a locked M or a thread that may have been
@@ -2221,24 +2316,24 @@
 // Stops execution of the current m until new work is available.
 // Returns with acquired P.
 func stopm() {
-	_g_ := getg()
+	gp := getg()
 
-	if _g_.m.locks != 0 {
+	if gp.m.locks != 0 {
 		throw("stopm holding locks")
 	}
-	if _g_.m.p != 0 {
+	if gp.m.p != 0 {
 		throw("stopm holding p")
 	}
-	if _g_.m.spinning {
+	if gp.m.spinning {
 		throw("stopm spinning")
 	}
 
 	lock(&sched.lock)
-	mput(_g_.m)
+	mput(gp.m)
 	unlock(&sched.lock)
 	mPark()
-	acquirep(_g_.m.nextp.ptr())
-	_g_.m.nextp = 0
+	acquirep(gp.m.nextp.ptr())
+	gp.m.nextp = 0
 }
 
 func mspinning() {
@@ -2249,8 +2344,8 @@
 // Schedules some M to run the p (creates an M if necessary).
 // If p==nil, tries to get an idle P, if no idle P's does nothing.
 // May run with m.p==nil, so write barriers are not allowed.
-// If spinning is set, the caller has incremented nmspinning and startm will
-// either decrement nmspinning or set m.spinning in the newly started M.
+// If spinning is set, the caller has incremented nmspinning and must provide a
+// P. startm will set m.spinning in the newly started M.
 //
 // Callers passing a non-nil P must call from a non-preemptible context. See
 // comment on acquirem below.
@@ -2258,7 +2353,7 @@
 // Must not have write barriers because this may be called without a P.
 //
 //go:nowritebarrierrec
-func startm(_p_ *p, spinning bool) {
+func startm(pp *p, spinning bool) {
 	// Disable preemption.
 	//
 	// Every owned P must have an owner that will eventually stop it in the
@@ -2277,17 +2372,16 @@
 	// disable preemption before acquiring a P from pidleget below.
 	mp := acquirem()
 	lock(&sched.lock)
-	if _p_ == nil {
-		_p_, _ = pidleget(0)
-		if _p_ == nil {
+	if pp == nil {
+		if spinning {
+			// TODO(prattmic): All remaining calls to this function
+			// with _p_ == nil could be cleaned up to find a P
+			// before calling startm.
+			throw("startm: P required for spinning=true")
+		}
+		pp, _ = pidleget(0)
+		if pp == nil {
 			unlock(&sched.lock)
-			if spinning {
-				// The caller incremented nmspinning, but there are no idle Ps,
-				// so it's okay to just undo the increment and give up.
-				if int32(atomic.Xadd(&sched.nmspinning, -1)) < 0 {
-					throw("startm: negative nmspinning")
-				}
-			}
 			releasem(mp)
 			return
 		}
@@ -2314,8 +2408,8 @@
 			// The caller incremented nmspinning, so set m.spinning in the new M.
 			fn = mspinning
 		}
-		newm(fn, _p_, id)
-		// Ownership transfer of _p_ committed by start in newm.
+		newm(fn, pp, id)
+		// Ownership transfer of pp committed by start in newm.
 		// Preemption is now safe.
 		releasem(mp)
 		return
@@ -2327,14 +2421,14 @@
 	if nmp.nextp != 0 {
 		throw("startm: m has p")
 	}
-	if spinning && !runqempty(_p_) {
+	if spinning && !runqempty(pp) {
 		throw("startm: p has runnable gs")
 	}
 	// The caller incremented nmspinning, so set m.spinning in the new M.
 	nmp.spinning = spinning
-	nmp.nextp.set(_p_)
+	nmp.nextp.set(pp)
 	notewakeup(&nmp.park)
-	// Ownership transfer of _p_ committed by wakeup. Preemption is now
+	// Ownership transfer of pp committed by wakeup. Preemption is now
 	// safe.
 	releasem(mp)
 }
@@ -2343,34 +2437,35 @@
 // Always runs without a P, so write barriers are not allowed.
 //
 //go:nowritebarrierrec
-func handoffp(_p_ *p) {
+func handoffp(pp *p) {
 	// handoffp must start an M in any situation where
-	// findrunnable would return a G to run on _p_.
+	// findrunnable would return a G to run on pp.
 
 	// if it has local work, start it straight away
-	if !runqempty(_p_) || sched.runqsize != 0 {
-		startm(_p_, false)
+	if !runqempty(pp) || sched.runqsize != 0 {
+		startm(pp, false)
 		return
 	}
 	// if there's trace work to do, start it straight away
-	if (trace.enabled || trace.shutdown) && traceReaderAvailable() {
-		startm(_p_, false)
+	if (trace.enabled || trace.shutdown) && traceReaderAvailable() != nil {
+		startm(pp, false)
 		return
 	}
 	// if it has GC work, start it straight away
-	if gcBlackenEnabled != 0 && gcMarkWorkAvailable(_p_) {
-		startm(_p_, false)
+	if gcBlackenEnabled != 0 && gcMarkWorkAvailable(pp) {
+		startm(pp, false)
 		return
 	}
 	// no local work, check that there are no spinning/idle M's,
 	// otherwise our help is not required
-	if atomic.Load(&sched.nmspinning)+atomic.Load(&sched.npidle) == 0 && atomic.Cas(&sched.nmspinning, 0, 1) { // TODO: fast atomic
-		startm(_p_, true)
+	if sched.nmspinning.Load()+sched.npidle.Load() == 0 && sched.nmspinning.CompareAndSwap(0, 1) { // TODO: fast atomic
+		sched.needspinning.Store(0)
+		startm(pp, true)
 		return
 	}
 	lock(&sched.lock)
-	if sched.gcwaiting != 0 {
-		_p_.status = _Pgcstop
+	if sched.gcwaiting.Load() {
+		pp.status = _Pgcstop
 		sched.stopwait--
 		if sched.stopwait == 0 {
 			notewakeup(&sched.stopnote)
@@ -2378,8 +2473,8 @@
 		unlock(&sched.lock)
 		return
 	}
-	if _p_.runSafePointFn != 0 && atomic.Cas(&_p_.runSafePointFn, 1, 0) {
-		sched.safePointFn(_p_)
+	if pp.runSafePointFn != 0 && atomic.Cas(&pp.runSafePointFn, 1, 0) {
+		sched.safePointFn(pp)
 		sched.safePointWait--
 		if sched.safePointWait == 0 {
 			notewakeup(&sched.safePointNote)
@@ -2387,21 +2482,21 @@
 	}
 	if sched.runqsize != 0 {
 		unlock(&sched.lock)
-		startm(_p_, false)
+		startm(pp, false)
 		return
 	}
 	// If this is the last running P and nobody is polling network,
 	// need to wakeup another M to poll network.
-	if sched.npidle == uint32(gomaxprocs-1) && atomic.Load64(&sched.lastpoll) != 0 {
+	if sched.npidle.Load() == gomaxprocs-1 && sched.lastpoll.Load() != 0 {
 		unlock(&sched.lock)
-		startm(_p_, false)
+		startm(pp, false)
 		return
 	}
 
 	// The scheduler lock cannot be held when calling wakeNetPoller below
 	// because wakeNetPoller may call wakep which may call startm.
-	when := nobarrierWakeTime(_p_)
-	pidleput(_p_, 0)
+	when := nobarrierWakeTime(pp)
+	pidleput(pp, 0)
 	unlock(&sched.lock)
 
 	if when != 0 {
@@ -2411,41 +2506,67 @@
 
 // Tries to add one more P to execute G's.
 // Called when a G is made runnable (newproc, ready).
+// Must be called with a P.
 func wakep() {
-	if atomic.Load(&sched.npidle) == 0 {
+	// Be conservative about spinning threads, only start one if none exist
+	// already.
+	if sched.nmspinning.Load() != 0 || !sched.nmspinning.CompareAndSwap(0, 1) {
 		return
 	}
-	// be conservative about spinning threads
-	if atomic.Load(&sched.nmspinning) != 0 || !atomic.Cas(&sched.nmspinning, 0, 1) {
+
+	// Disable preemption until ownership of pp transfers to the next M in
+	// startm. Otherwise preemption here would leave pp stuck waiting to
+	// enter _Pgcstop.
+	//
+	// See preemption comment on acquirem in startm for more details.
+	mp := acquirem()
+
+	var pp *p
+	lock(&sched.lock)
+	pp, _ = pidlegetSpinning(0)
+	if pp == nil {
+		if sched.nmspinning.Add(-1) < 0 {
+			throw("wakep: negative nmspinning")
+		}
+		unlock(&sched.lock)
+		releasem(mp)
 		return
 	}
-	startm(nil, true)
+	// Since we always have a P, the race in the "No M is available"
+	// comment in startm doesn't apply during the small window between the
+	// unlock here and lock in startm. A checkdead in between will always
+	// see at least one running M (ours).
+	unlock(&sched.lock)
+
+	startm(pp, true)
+
+	releasem(mp)
 }
 
 // Stops execution of the current m that is locked to a g until the g is runnable again.
 // Returns with acquired P.
 func stoplockedm() {
-	_g_ := getg()
+	gp := getg()
 
-	if _g_.m.lockedg == 0 || _g_.m.lockedg.ptr().lockedm.ptr() != _g_.m {
+	if gp.m.lockedg == 0 || gp.m.lockedg.ptr().lockedm.ptr() != gp.m {
 		throw("stoplockedm: inconsistent locking")
 	}
-	if _g_.m.p != 0 {
+	if gp.m.p != 0 {
 		// Schedule another M to run this p.
-		_p_ := releasep()
-		handoffp(_p_)
+		pp := releasep()
+		handoffp(pp)
 	}
 	incidlelocked(1)
 	// Wait until another thread schedules lockedg again.
 	mPark()
-	status := readgstatus(_g_.m.lockedg.ptr())
+	status := readgstatus(gp.m.lockedg.ptr())
 	if status&^_Gscan != _Grunnable {
 		print("runtime:stoplockedm: lockedg (atomicstatus=", status, ") is not Grunnable or Gscanrunnable\n")
-		dumpgstatus(_g_.m.lockedg.ptr())
+		dumpgstatus(gp.m.lockedg.ptr())
 		throw("stoplockedm: not runnable")
 	}
-	acquirep(_g_.m.nextp.ptr())
-	_g_.m.nextp = 0
+	acquirep(gp.m.nextp.ptr())
+	gp.m.nextp = 0
 }
 
 // Schedules the locked m to run the locked gp.
@@ -2453,10 +2574,8 @@
 //
 //go:nowritebarrierrec
 func startlockedm(gp *g) {
-	_g_ := getg()
-
 	mp := gp.lockedm.ptr()
-	if mp == _g_.m {
+	if mp == getg().m {
 		throw("startlockedm: locked to me")
 	}
 	if mp.nextp != 0 {
@@ -2464,8 +2583,8 @@
 	}
 	// directly handoff current P to the locked m
 	incidlelocked(-1)
-	_p_ := releasep()
-	mp.nextp.set(_p_)
+	pp := releasep()
+	mp.nextp.set(pp)
 	notewakeup(&mp.park)
 	stopm()
 }
@@ -2473,22 +2592,22 @@
 // Stops the current m for stopTheWorld.
 // Returns when the world is restarted.
 func gcstopm() {
-	_g_ := getg()
+	gp := getg()
 
-	if sched.gcwaiting == 0 {
+	if !sched.gcwaiting.Load() {
 		throw("gcstopm: not waiting for gc")
 	}
-	if _g_.m.spinning {
-		_g_.m.spinning = false
+	if gp.m.spinning {
+		gp.m.spinning = false
 		// OK to just drop nmspinning here,
 		// startTheWorld will unpark threads as necessary.
-		if int32(atomic.Xadd(&sched.nmspinning, -1)) < 0 {
+		if sched.nmspinning.Add(-1) < 0 {
 			throw("gcstopm: negative nmspinning")
 		}
 	}
-	_p_ := releasep()
+	pp := releasep()
 	lock(&sched.lock)
-	_p_.status = _Pgcstop
+	pp.status = _Pgcstop
 	sched.stopwait--
 	if sched.stopwait == 0 {
 		notewakeup(&sched.stopnote)
@@ -2507,7 +2626,7 @@
 //
 //go:yeswritebarrierrec
 func execute(gp *g, inheritTime bool) {
-	_g_ := getg()
+	mp := getg().m
 
 	if goroutineProfile.active {
 		// Make sure that gp has had its stack written out to the goroutine
@@ -2518,19 +2637,19 @@
 
 	// Assign gp.m before entering _Grunning so running Gs have an
 	// M.
-	_g_.m.curg = gp
-	gp.m = _g_.m
+	mp.curg = gp
+	gp.m = mp
 	casgstatus(gp, _Grunnable, _Grunning)
 	gp.waitsince = 0
 	gp.preempt = false
 	gp.stackguard0 = gp.stack.lo + _StackGuard
 	if !inheritTime {
-		_g_.m.p.ptr().schedtick++
+		mp.p.ptr().schedtick++
 	}
 
 	// Check whether the profiler needs to be turned on or off.
 	hz := sched.profilehz
-	if _g_.m.profilehz != hz {
+	if mp.profilehz != hz {
 		setThreadCPUProfiler(hz)
 	}
 
@@ -2551,19 +2670,19 @@
 // tryWakeP indicates that the returned goroutine is not normal (GC worker, trace
 // reader) so the caller should try to wake a P.
 func findRunnable() (gp *g, inheritTime, tryWakeP bool) {
-	_g_ := getg()
+	mp := getg().m
 
 	// The conditions here and in handoffp must agree: if
 	// findrunnable would return a G to run, handoffp must start
 	// an M.
 
 top:
-	_p_ := _g_.m.p.ptr()
-	if sched.gcwaiting != 0 {
+	pp := mp.p.ptr()
+	if sched.gcwaiting.Load() {
 		gcstopm()
 		goto top
 	}
-	if _p_.runSafePointFn != 0 {
+	if pp.runSafePointFn != 0 {
 		runSafePointFn()
 	}
 
@@ -2571,11 +2690,11 @@
 	// which may steal timers. It's important that between now
 	// and then, nothing blocks, so these numbers remain mostly
 	// relevant.
-	now, pollUntil, _ := checkTimers(_p_, 0)
+	now, pollUntil, _ := checkTimers(pp, 0)
 
 	// Try to schedule the trace reader.
 	if trace.enabled || trace.shutdown {
-		gp = traceReader()
+		gp := traceReader()
 		if gp != nil {
 			casgstatus(gp, _Gwaiting, _Grunnable)
 			traceGoUnpark(gp, 0)
@@ -2585,18 +2704,19 @@
 
 	// Try to schedule a GC worker.
 	if gcBlackenEnabled != 0 {
-		gp, now = gcController.findRunnableGCWorker(_p_, now)
+		gp, tnow := gcController.findRunnableGCWorker(pp, now)
 		if gp != nil {
 			return gp, false, true
 		}
+		now = tnow
 	}
 
 	// Check the global runnable queue once in a while to ensure fairness.
 	// Otherwise two goroutines can completely occupy the local runqueue
 	// by constantly respawning each other.
-	if _p_.schedtick%61 == 0 && sched.runqsize > 0 {
+	if pp.schedtick%61 == 0 && sched.runqsize > 0 {
 		lock(&sched.lock)
-		gp = globrunqget(_p_, 1)
+		gp := globrunqget(pp, 1)
 		unlock(&sched.lock)
 		if gp != nil {
 			return gp, false, false
@@ -2604,7 +2724,7 @@
 	}
 
 	// Wake up the finalizer G.
-	if fingwait && fingwake {
+	if fingStatus.Load()&(fingWait|fingWake) == fingWait|fingWake {
 		if gp := wakefing(); gp != nil {
 			ready(gp, 0, true)
 		}
@@ -2614,14 +2734,14 @@
 	}
 
 	// local runq
-	if gp, inheritTime := runqget(_p_); gp != nil {
+	if gp, inheritTime := runqget(pp); gp != nil {
 		return gp, inheritTime, false
 	}
 
 	// global runq
 	if sched.runqsize != 0 {
 		lock(&sched.lock)
-		gp := globrunqget(_p_, 0)
+		gp := globrunqget(pp, 0)
 		unlock(&sched.lock)
 		if gp != nil {
 			return gp, false, false
@@ -2635,7 +2755,7 @@
 	// blocked thread (e.g. it has already returned from netpoll, but does
 	// not set lastpoll yet), this thread will do blocking netpoll below
 	// anyway.
-	if netpollinited() && atomic.Load(&netpollWaiters) > 0 && atomic.Load64(&sched.lastpoll) != 0 {
+	if netpollinited() && netpollWaiters.Load() > 0 && sched.lastpoll.Load() != 0 {
 		if list := netpoll(0); !list.empty() { // non-blocking
 			gp := list.pop()
 			injectglist(&list)
@@ -2652,15 +2772,12 @@
 	// Limit the number of spinning Ms to half the number of busy Ps.
 	// This is necessary to prevent excessive CPU consumption when
 	// GOMAXPROCS>>1 but the program parallelism is low.
-	procs := uint32(gomaxprocs)
-	if _g_.m.spinning || 2*atomic.Load(&sched.nmspinning) < procs-atomic.Load(&sched.npidle) {
-		if !_g_.m.spinning {
-			_g_.m.spinning = true
-			atomic.Xadd(&sched.nmspinning, 1)
+	if mp.spinning || 2*sched.nmspinning.Load() < gomaxprocs-sched.npidle.Load() {
+		if !mp.spinning {
+			mp.becomeSpinning()
 		}
 
 		gp, inheritTime, tnow, w, newWork := stealWork(now)
-		now = tnow
 		if gp != nil {
 			// Successfully stole.
 			return gp, inheritTime, false
@@ -2670,6 +2787,8 @@
 			// discover.
 			goto top
 		}
+
+		now = tnow
 		if w != 0 && (pollUntil == 0 || w < pollUntil) {
 			// Earlier timer to wait for.
 			pollUntil = w
@@ -2680,10 +2799,10 @@
 	//
 	// If we're in the GC mark phase, can safely scan and blacken objects,
 	// and have work to do, run idle-time marking rather than give up the P.
-	if gcBlackenEnabled != 0 && gcMarkWorkAvailable(_p_) && gcController.addIdleMarkWorker() {
+	if gcBlackenEnabled != 0 && gcMarkWorkAvailable(pp) && gcController.addIdleMarkWorker() {
 		node := (*gcBgMarkWorkerNode)(gcBgMarkWorkerPool.pop())
 		if node != nil {
-			_p_.gcMarkWorkerMode = gcMarkWorkerIdleMode
+			pp.gcMarkWorkerMode = gcMarkWorkerIdleMode
 			gp := node.gp.ptr()
 			casgstatus(gp, _Gwaiting, _Grunnable)
 			if trace.enabled {
@@ -2722,19 +2841,25 @@
 
 	// return P and block
 	lock(&sched.lock)
-	if sched.gcwaiting != 0 || _p_.runSafePointFn != 0 {
+	if sched.gcwaiting.Load() || pp.runSafePointFn != 0 {
 		unlock(&sched.lock)
 		goto top
 	}
 	if sched.runqsize != 0 {
-		gp := globrunqget(_p_, 0)
+		gp := globrunqget(pp, 0)
 		unlock(&sched.lock)
 		return gp, false, false
 	}
-	if releasep() != _p_ {
+	if !mp.spinning && sched.needspinning.Load() == 1 {
+		// See "Delicate dance" comment below.
+		mp.becomeSpinning()
+		unlock(&sched.lock)
+		goto top
+	}
+	if releasep() != pp {
 		throw("findrunnable: wrong p")
 	}
-	now = pidleput(_p_, now)
+	now = pidleput(pp, now)
 	unlock(&sched.lock)
 
 	// Delicate dance: thread transitions from spinning to non-spinning
@@ -2751,43 +2876,60 @@
 	// * New/modified-earlier timers on a per-P timer heap.
 	// * Idle-priority GC work (barring golang.org/issue/19112).
 	//
-	// If we discover new work below, we need to restore m.spinning as a signal
-	// for resetspinning to unpark a new worker thread (because there can be more
-	// than one starving goroutine). However, if after discovering new work
-	// we also observe no idle Ps it is OK to skip unparking a new worker
-	// thread: the system is fully loaded so no spinning threads are required.
-	// Also see "Worker thread parking/unparking" comment at the top of the file.
-	wasSpinning := _g_.m.spinning
-	if _g_.m.spinning {
-		_g_.m.spinning = false
-		if int32(atomic.Xadd(&sched.nmspinning, -1)) < 0 {
+	// If we discover new work below, we need to restore m.spinning as a
+	// signal for resetspinning to unpark a new worker thread (because
+	// there can be more than one starving goroutine).
+	//
+	// However, if after discovering new work we also observe no idle Ps
+	// (either here or in resetspinning), we have a problem. We may be
+	// racing with a non-spinning M in the block above, having found no
+	// work and preparing to release its P and park. Allowing that P to go
+	// idle will result in loss of work conservation (idle P while there is
+	// runnable work). This could result in complete deadlock in the
+	// unlikely event that we discover new work (from netpoll) right as we
+	// are racing with _all_ other Ps going idle.
+	//
+	// We use sched.needspinning to synchronize with non-spinning Ms going
+	// idle. If needspinning is set when they are about to drop their P,
+	// they abort the drop and instead become a new spinning M on our
+	// behalf. If we are not racing and the system is truly fully loaded
+	// then no spinning threads are required, and the next thread to
+	// naturally become spinning will clear the flag.
+	//
+	// Also see "Worker thread parking/unparking" comment at the top of the
+	// file.
+	wasSpinning := mp.spinning
+	if mp.spinning {
+		mp.spinning = false
+		if sched.nmspinning.Add(-1) < 0 {
 			throw("findrunnable: negative nmspinning")
 		}
 
 		// Note the for correctness, only the last M transitioning from
 		// spinning to non-spinning must perform these rechecks to
-		// ensure no missed work. We are performing it on every M that
-		// transitions as a conservative change to monitor effects on
-		// latency. See golang.org/issue/43997.
+		// ensure no missed work. However, the runtime has some cases
+		// of transient increments of nmspinning that are decremented
+		// without going through this path, so we must be conservative
+		// and perform the check on all spinning Ms.
+		//
+		// See https://go.dev/issue/43997.
 
 		// Check all runqueues once again.
-		_p_ = checkRunqsNoP(allpSnapshot, idlepMaskSnapshot)
-		if _p_ != nil {
-			acquirep(_p_)
-			_g_.m.spinning = true
-			atomic.Xadd(&sched.nmspinning, 1)
+		pp := checkRunqsNoP(allpSnapshot, idlepMaskSnapshot)
+		if pp != nil {
+			acquirep(pp)
+			mp.becomeSpinning()
 			goto top
 		}
 
 		// Check for idle-priority GC work again.
-		_p_, gp = checkIdleGCNoP()
-		if _p_ != nil {
-			acquirep(_p_)
-			_g_.m.spinning = true
-			atomic.Xadd(&sched.nmspinning, 1)
+		pp, gp := checkIdleGCNoP()
+		if pp != nil {
+			acquirep(pp)
+			mp.becomeSpinning()
 
 			// Run the idle worker.
-			_p_.gcMarkWorkerMode = gcMarkWorkerIdleMode
+			pp.gcMarkWorkerMode = gcMarkWorkerIdleMode
 			casgstatus(gp, _Gwaiting, _Grunnable)
 			if trace.enabled {
 				traceGoUnpark(gp, 0)
@@ -2805,12 +2947,12 @@
 	}
 
 	// Poll network until next timer.
-	if netpollinited() && (atomic.Load(&netpollWaiters) > 0 || pollUntil != 0) && atomic.Xchg64(&sched.lastpoll, 0) != 0 {
-		atomic.Store64(&sched.pollUntil, uint64(pollUntil))
-		if _g_.m.p != 0 {
+	if netpollinited() && (netpollWaiters.Load() > 0 || pollUntil != 0) && sched.lastpoll.Swap(0) != 0 {
+		sched.pollUntil.Store(pollUntil)
+		if mp.p != 0 {
 			throw("findrunnable: netpoll with p")
 		}
-		if _g_.m.spinning {
+		if mp.spinning {
 			throw("findrunnable: netpoll with spinning")
 		}
 		// Refresh now.
@@ -2827,8 +2969,8 @@
 			delay = 0
 		}
 		list := netpoll(delay) // block until new work is available
-		atomic.Store64(&sched.pollUntil, 0)
-		atomic.Store64(&sched.lastpoll, uint64(now))
+		sched.pollUntil.Store(0)
+		sched.lastpoll.Store(now)
 		if faketime != 0 && list.empty() {
 			// Using fake time and nothing is ready; stop M.
 			// When all M's stop, checkdead will call timejump.
@@ -2836,12 +2978,12 @@
 			goto top
 		}
 		lock(&sched.lock)
-		_p_, _ = pidleget(now)
+		pp, _ := pidleget(now)
 		unlock(&sched.lock)
-		if _p_ == nil {
+		if pp == nil {
 			injectglist(&list)
 		} else {
-			acquirep(_p_)
+			acquirep(pp)
 			if !list.empty() {
 				gp := list.pop()
 				injectglist(&list)
@@ -2852,13 +2994,12 @@
 				return gp, false, false
 			}
 			if wasSpinning {
-				_g_.m.spinning = true
-				atomic.Xadd(&sched.nmspinning, 1)
+				mp.becomeSpinning()
 			}
 			goto top
 		}
 	} else if pollUntil != 0 && netpollinited() {
-		pollerPollUntil := int64(atomic.Load64(&sched.pollUntil))
+		pollerPollUntil := sched.pollUntil.Load()
 		if pollerPollUntil == 0 || pollerPollUntil > pollUntil {
 			netpollBreak()
 		}
@@ -2879,7 +3020,7 @@
 	if !runqempty(p) {
 		return true
 	}
-	if netpollinited() && atomic.Load(&netpollWaiters) > 0 && sched.lastpoll != 0 {
+	if netpollinited() && netpollWaiters.Load() > 0 && sched.lastpoll.Load() != 0 {
 		if list := netpoll(0); !list.empty() {
 			injectglist(&list)
 			return true
@@ -2904,7 +3045,7 @@
 		stealTimersOrRunNextG := i == stealTries-1
 
 		for enum := stealOrder.start(fastrand()); !enum.done(); enum.next() {
-			if sched.gcwaiting != 0 {
+			if sched.gcwaiting.Load() {
 				// GC work may be available.
 				return nil, false, now, pollUntil, true
 			}
@@ -2972,17 +3113,18 @@
 	for id, p2 := range allpSnapshot {
 		if !idlepMaskSnapshot.read(uint32(id)) && !runqempty(p2) {
 			lock(&sched.lock)
-			pp, _ := pidleget(0)
-			unlock(&sched.lock)
-			if pp != nil {
-				return pp
+			pp, _ := pidlegetSpinning(0)
+			if pp == nil {
+				// Can't get a P, don't bother checking remaining Ps.
+				unlock(&sched.lock)
+				return nil
 			}
-
-			// Can't get a P, don't bother checking remaining Ps.
-			break
+			unlock(&sched.lock)
+			return pp
 		}
 	}
 
+	// No work available.
 	return nil
 }
 
@@ -3038,7 +3180,7 @@
 	// the assumption in gcControllerState.findRunnableGCWorker that an
 	// empty gcBgMarkWorkerPool is only possible if gcMarkDone is running.
 	lock(&sched.lock)
-	pp, now := pidleget(0)
+	pp, now := pidlegetSpinning(0)
 	if pp == nil {
 		unlock(&sched.lock)
 		return nil, nil
@@ -3068,12 +3210,12 @@
 // going to wake up before the when argument; or it wakes an idle P to service
 // timers and the network poller if there isn't one already.
 func wakeNetPoller(when int64) {
-	if atomic.Load64(&sched.lastpoll) == 0 {
+	if sched.lastpoll.Load() == 0 {
 		// In findrunnable we ensure that when polling the pollUntil
 		// field is either zero or the time to which the current
 		// poll is expected to run. This can have a spurious wakeup
 		// but should never miss a wakeup.
-		pollerPollUntil := int64(atomic.Load64(&sched.pollUntil))
+		pollerPollUntil := sched.pollUntil.Load()
 		if pollerPollUntil == 0 || pollerPollUntil > when {
 			netpollBreak()
 		}
@@ -3087,13 +3229,13 @@
 }
 
 func resetspinning() {
-	_g_ := getg()
-	if !_g_.m.spinning {
+	gp := getg()
+	if !gp.m.spinning {
 		throw("resetspinning: not a spinning m")
 	}
-	_g_.m.spinning = false
-	nmspinning := atomic.Xadd(&sched.nmspinning, -1)
-	if int32(nmspinning) < 0 {
+	gp.m.spinning = false
+	nmspinning := sched.nmspinning.Add(-1)
+	if nmspinning < 0 {
 		throw("findrunnable: negative nmspinning")
 	}
 	// M wakeup policy is deliberately somewhat conservative, so check if we
@@ -3138,8 +3280,20 @@
 	*glist = gList{}
 
 	startIdle := func(n int) {
-		for ; n != 0 && sched.npidle != 0; n-- {
-			startm(nil, false)
+		for i := 0; i < n; i++ {
+			mp := acquirem() // See comment in startm.
+			lock(&sched.lock)
+
+			pp, _ := pidlegetSpinning(0)
+			if pp == nil {
+				unlock(&sched.lock)
+				releasem(mp)
+				break
+			}
+
+			unlock(&sched.lock)
+			startm(pp, false)
+			releasem(mp)
 		}
 	}
 
@@ -3152,7 +3306,7 @@
 		return
 	}
 
-	npidle := int(atomic.Load(&sched.npidle))
+	npidle := int(sched.npidle.Load())
 	var globq gQueue
 	var n int
 	for n = 0; n < npidle && !q.empty(); n++ {
@@ -3175,31 +3329,31 @@
 // One round of scheduler: find a runnable goroutine and execute it.
 // Never returns.
 func schedule() {
-	_g_ := getg()
+	mp := getg().m
 
-	if _g_.m.locks != 0 {
+	if mp.locks != 0 {
 		throw("schedule: holding locks")
 	}
 
-	if _g_.m.lockedg != 0 {
+	if mp.lockedg != 0 {
 		stoplockedm()
-		execute(_g_.m.lockedg.ptr(), false) // Never returns.
+		execute(mp.lockedg.ptr(), false) // Never returns.
 	}
 
 	// We should not schedule away from a g that is executing a cgo call,
 	// since the cgo call is using the m's g0 stack.
-	if _g_.m.incgo {
+	if mp.incgo {
 		throw("schedule: in cgo")
 	}
 
 top:
-	pp := _g_.m.p.ptr()
+	pp := mp.p.ptr()
 	pp.preempt = false
 
 	// Safety check: if we are spinning, the run queue should be empty.
 	// Check this before calling checkTimers, as that might call
 	// goready to put a ready goroutine on the local run queue.
-	if _g_.m.spinning && (pp.runnext != 0 || pp.runqhead != pp.runqtail) {
+	if mp.spinning && (pp.runnext != 0 || pp.runqhead != pp.runqtail) {
 		throw("schedule: spinning with local work")
 	}
 
@@ -3208,7 +3362,7 @@
 	// This thread is going to run a goroutine and is not spinning anymore,
 	// so if it was marked as spinning we need to reset it now and potentially
 	// start a new spinning M.
-	if _g_.m.spinning {
+	if mp.spinning {
 		resetspinning()
 	}
 
@@ -3252,10 +3406,10 @@
 // readied later, the caller can do other work but eventually should
 // call schedule to restart the scheduling of goroutines on this m.
 func dropg() {
-	_g_ := getg()
+	gp := getg()
 
-	setMNoWB(&_g_.m.curg.m, nil)
-	setGNoWB(&_g_.m.curg, nil)
+	setMNoWB(&gp.m.curg.m, nil)
+	setGNoWB(&gp.m.curg, nil)
 }
 
 // checkTimers runs any timers for the P that are ready.
@@ -3271,8 +3425,8 @@
 func checkTimers(pp *p, now int64) (rnow, pollUntil int64, ran bool) {
 	// If it's not yet time for the first timer, or the first adjusted
 	// timer, then there is nothing to do.
-	next := int64(atomic.Load64(&pp.timer0When))
-	nextAdj := int64(atomic.Load64(&pp.timerModifiedEarliest))
+	next := pp.timer0When.Load()
+	nextAdj := pp.timerModifiedEarliest.Load()
 	if next == 0 || (nextAdj != 0 && nextAdj < next) {
 		next = nextAdj
 	}
@@ -3290,7 +3444,7 @@
 		// if we would clear deleted timers.
 		// This corresponds to the condition below where
 		// we decide whether to call clearDeletedTimers.
-		if pp != getg().m.p.ptr() || int(atomic.Load(&pp.deletedTimers)) <= int(atomic.Load(&pp.numTimers)/4) {
+		if pp != getg().m.p.ptr() || int(pp.deletedTimers.Load()) <= int(pp.numTimers.Load()/4) {
 			return now, next, false
 		}
 	}
@@ -3315,7 +3469,7 @@
 	// If this is the local P, and there are a lot of deleted timers,
 	// clear them out. We only do this for the local P to reduce
 	// lock contention on timersLock.
-	if pp == getg().m.p.ptr() && int(atomic.Load(&pp.deletedTimers)) > len(pp.timers)/4 {
+	if pp == getg().m.p.ptr() && int(pp.deletedTimers.Load()) > len(pp.timers)/4 {
 		clearDeletedTimers(pp)
 	}
 
@@ -3331,19 +3485,21 @@
 
 // park continuation on g0.
 func park_m(gp *g) {
-	_g_ := getg()
+	mp := getg().m
 
 	if trace.enabled {
-		traceGoPark(_g_.m.waittraceev, _g_.m.waittraceskip)
+		traceGoPark(mp.waittraceev, mp.waittraceskip)
 	}
 
+	// N.B. Not using casGToWaiting here because the waitreason is
+	// set by park_m's caller.
 	casgstatus(gp, _Grunning, _Gwaiting)
 	dropg()
 
-	if fn := _g_.m.waitunlockf; fn != nil {
-		ok := fn(gp, _g_.m.waitlock)
-		_g_.m.waitunlockf = nil
-		_g_.m.waitlock = nil
+	if fn := mp.waitunlockf; fn != nil {
+		ok := fn(gp, mp.waitlock)
+		mp.waitunlockf = nil
+		mp.waitlock = nil
 		if !ok {
 			if trace.enabled {
 				traceGoUnpark(gp, 2)
@@ -3378,7 +3534,7 @@
 	goschedImpl(gp)
 }
 
-// goschedguarded is a forbidden-states-avoided version of gosched_m
+// goschedguarded is a forbidden-states-avoided version of gosched_m.
 func goschedguarded_m(gp *g) {
 
 	if !canPreemptM(gp.m) {
@@ -3410,7 +3566,6 @@
 		dumpgstatus(gp)
 		throw("bad g status")
 	}
-	gp.waitreason = waitReasonPreempted
 
 	if gp.asyncSafePoint {
 		// Double-check that async preemption does not
@@ -3470,24 +3625,24 @@
 
 // goexit continuation on g0.
 func goexit0(gp *g) {
-	_g_ := getg()
-	_p_ := _g_.m.p.ptr()
+	mp := getg().m
+	pp := mp.p.ptr()
 
 	casgstatus(gp, _Grunning, _Gdead)
-	gcController.addScannableStack(_p_, -int64(gp.stack.hi-gp.stack.lo))
+	gcController.addScannableStack(pp, -int64(gp.stack.hi-gp.stack.lo))
 	if isSystemGoroutine(gp, false) {
-		atomic.Xadd(&sched.ngsys, -1)
+		sched.ngsys.Add(-1)
 	}
 	gp.m = nil
 	locked := gp.lockedm != 0
 	gp.lockedm = 0
-	_g_.m.lockedg = 0
+	mp.lockedg = 0
 	gp.preemptStop = false
 	gp.paniconfault = false
 	gp._defer = nil // should be true already but just in case.
 	gp._panic = nil // non-nil for Goexit during panic. points at stack-allocated data.
 	gp.writebuf = nil
-	gp.waitreason = 0
+	gp.waitreason = waitReasonZero
 	gp.param = nil
 	gp.labels = nil
 	gp.timer = nil
@@ -3498,22 +3653,22 @@
 		// rapidly creating an exiting goroutines.
 		assistWorkPerByte := gcController.assistWorkPerByte.Load()
 		scanCredit := int64(assistWorkPerByte * float64(gp.gcAssistBytes))
-		atomic.Xaddint64(&gcController.bgScanCredit, scanCredit)
+		gcController.bgScanCredit.Add(scanCredit)
 		gp.gcAssistBytes = 0
 	}
 
 	dropg()
 
 	if GOARCH == "wasm" { // no threads yet on wasm
-		gfput(_p_, gp)
+		gfput(pp, gp)
 		schedule() // never returns
 	}
 
-	if _g_.m.lockedInt != 0 {
-		print("invalid m->lockedInt = ", _g_.m.lockedInt, "\n")
+	if mp.lockedInt != 0 {
+		print("invalid m->lockedInt = ", mp.lockedInt, "\n")
 		throw("internal lockOSThread error")
 	}
-	gfput(_p_, gp)
+	gfput(pp, gp)
 	if locked {
 		// The goroutine may have locked this thread because
 		// it put it in an unusual kernel state. Kill it
@@ -3522,11 +3677,11 @@
 		// Return to mstart, which will release the P and exit
 		// the thread.
 		if GOOS != "plan9" { // See golang.org/issue/22227.
-			gogo(&_g_.m.g0.sched)
+			gogo(&mp.g0.sched)
 		} else {
 			// Clear lockedExt on plan9 since we may end up re-using
 			// this thread.
-			_g_.m.lockedExt = 0
+			mp.lockedExt = 0
 		}
 	}
 	schedule()
@@ -3541,9 +3696,9 @@
 //go:nosplit
 //go:nowritebarrierrec
 func save(pc, sp uintptr) {
-	_g_ := getg()
+	gp := getg()
 
-	if _g_ == _g_.m.g0 || _g_ == _g_.m.gsignal {
+	if gp == gp.m.g0 || gp == gp.m.gsignal {
 		// m.g0.sched is special and must describe the context
 		// for exiting the thread. mstart1 writes to it directly.
 		// m.gsignal.sched should not be used at all.
@@ -3552,14 +3707,14 @@
 		throw("save on system g not allowed")
 	}
 
-	_g_.sched.pc = pc
-	_g_.sched.sp = sp
-	_g_.sched.lr = 0
-	_g_.sched.ret = 0
+	gp.sched.pc = pc
+	gp.sched.sp = sp
+	gp.sched.lr = 0
+	gp.sched.ret = 0
 	// We need to ensure ctxt is zero, but can't have a write
 	// barrier here. However, it should always already be zero.
 	// Assert that.
-	if _g_.sched.ctxt != nil {
+	if gp.sched.ctxt != nil {
 		badctxt()
 	}
 }
@@ -3594,7 +3749,7 @@
 // when syscall returns we emit traceGoSysExit and when the goroutine starts running
 // (potentially instantly, if exitsyscallfast returns true) we emit traceGoStart.
 // To ensure that traceGoSysExit is emitted strictly after traceGoSysBlock,
-// we remember current value of syscalltick in m (_g_.m.syscalltick = _g_.m.p.ptr().syscalltick),
+// we remember current value of syscalltick in m (gp.m.syscalltick = gp.m.p.ptr().syscalltick),
 // whoever emits traceGoSysBlock increments p.syscalltick afterwards;
 // and we wait for the increment before emitting traceGoSysExit.
 // Note that the increment is done even if tracing is not enabled,
@@ -3602,27 +3757,27 @@
 //
 //go:nosplit
 func reentersyscall(pc, sp uintptr) {
-	_g_ := getg()
+	gp := getg()
 
 	// Disable preemption because during this function g is in Gsyscall status,
 	// but can have inconsistent g->sched, do not let GC observe it.
-	_g_.m.locks++
+	gp.m.locks++
 
 	// Entersyscall must not call any function that might split/grow the stack.
 	// (See details in comment above.)
 	// Catch calls that might, by replacing the stack guard with something that
 	// will trip any stack check and leaving a flag to tell newstack to die.
-	_g_.stackguard0 = stackPreempt
-	_g_.throwsplit = true
+	gp.stackguard0 = stackPreempt
+	gp.throwsplit = true
 
 	// Leave SP around for GC and traceback.
 	save(pc, sp)
-	_g_.syscallsp = sp
-	_g_.syscallpc = pc
-	casgstatus(_g_, _Grunning, _Gsyscall)
-	if _g_.syscallsp < _g_.stack.lo || _g_.stack.hi < _g_.syscallsp {
+	gp.syscallsp = sp
+	gp.syscallpc = pc
+	casgstatus(gp, _Grunning, _Gsyscall)
+	if gp.syscallsp < gp.stack.lo || gp.stack.hi < gp.syscallsp {
 		systemstack(func() {
-			print("entersyscall inconsistent ", hex(_g_.syscallsp), " [", hex(_g_.stack.lo), ",", hex(_g_.stack.hi), "]\n")
+			print("entersyscall inconsistent ", hex(gp.syscallsp), " [", hex(gp.stack.lo), ",", hex(gp.stack.hi), "]\n")
 			throw("entersyscall")
 		})
 	}
@@ -3635,30 +3790,30 @@
 		save(pc, sp)
 	}
 
-	if atomic.Load(&sched.sysmonwait) != 0 {
+	if sched.sysmonwait.Load() {
 		systemstack(entersyscall_sysmon)
 		save(pc, sp)
 	}
 
-	if _g_.m.p.ptr().runSafePointFn != 0 {
+	if gp.m.p.ptr().runSafePointFn != 0 {
 		// runSafePointFn may stack split if run on this stack
 		systemstack(runSafePointFn)
 		save(pc, sp)
 	}
 
-	_g_.m.syscalltick = _g_.m.p.ptr().syscalltick
-	_g_.sysblocktraced = true
-	pp := _g_.m.p.ptr()
+	gp.m.syscalltick = gp.m.p.ptr().syscalltick
+	gp.sysblocktraced = true
+	pp := gp.m.p.ptr()
 	pp.m = 0
-	_g_.m.oldp.set(pp)
-	_g_.m.p = 0
+	gp.m.oldp.set(pp)
+	gp.m.p = 0
 	atomic.Store(&pp.status, _Psyscall)
-	if sched.gcwaiting != 0 {
+	if sched.gcwaiting.Load() {
 		systemstack(entersyscall_gcwait)
 		save(pc, sp)
 	}
 
-	_g_.m.locks--
+	gp.m.locks--
 }
 
 // Standard syscall entry used by the go syscall library and normal cgo calls.
@@ -3673,24 +3828,24 @@
 
 func entersyscall_sysmon() {
 	lock(&sched.lock)
-	if atomic.Load(&sched.sysmonwait) != 0 {
-		atomic.Store(&sched.sysmonwait, 0)
+	if sched.sysmonwait.Load() {
+		sched.sysmonwait.Store(false)
 		notewakeup(&sched.sysmonnote)
 	}
 	unlock(&sched.lock)
 }
 
 func entersyscall_gcwait() {
-	_g_ := getg()
-	_p_ := _g_.m.oldp.ptr()
+	gp := getg()
+	pp := gp.m.oldp.ptr()
 
 	lock(&sched.lock)
-	if sched.stopwait > 0 && atomic.Cas(&_p_.status, _Psyscall, _Pgcstop) {
+	if sched.stopwait > 0 && atomic.Cas(&pp.status, _Psyscall, _Pgcstop) {
 		if trace.enabled {
-			traceGoSysBlock(_p_)
-			traceProcStop(_p_)
+			traceGoSysBlock(pp)
+			traceProcStop(pp)
 		}
-		_p_.syscalltick++
+		pp.syscalltick++
 		if sched.stopwait--; sched.stopwait == 0 {
 			notewakeup(&sched.stopnote)
 		}
@@ -3702,34 +3857,34 @@
 //
 //go:nosplit
 func entersyscallblock() {
-	_g_ := getg()
+	gp := getg()
 
-	_g_.m.locks++ // see comment in entersyscall
-	_g_.throwsplit = true
-	_g_.stackguard0 = stackPreempt // see comment in entersyscall
-	_g_.m.syscalltick = _g_.m.p.ptr().syscalltick
-	_g_.sysblocktraced = true
-	_g_.m.p.ptr().syscalltick++
+	gp.m.locks++ // see comment in entersyscall
+	gp.throwsplit = true
+	gp.stackguard0 = stackPreempt // see comment in entersyscall
+	gp.m.syscalltick = gp.m.p.ptr().syscalltick
+	gp.sysblocktraced = true
+	gp.m.p.ptr().syscalltick++
 
 	// Leave SP around for GC and traceback.
 	pc := getcallerpc()
 	sp := getcallersp()
 	save(pc, sp)
-	_g_.syscallsp = _g_.sched.sp
-	_g_.syscallpc = _g_.sched.pc
-	if _g_.syscallsp < _g_.stack.lo || _g_.stack.hi < _g_.syscallsp {
+	gp.syscallsp = gp.sched.sp
+	gp.syscallpc = gp.sched.pc
+	if gp.syscallsp < gp.stack.lo || gp.stack.hi < gp.syscallsp {
 		sp1 := sp
-		sp2 := _g_.sched.sp
-		sp3 := _g_.syscallsp
+		sp2 := gp.sched.sp
+		sp3 := gp.syscallsp
 		systemstack(func() {
-			print("entersyscallblock inconsistent ", hex(sp1), " ", hex(sp2), " ", hex(sp3), " [", hex(_g_.stack.lo), ",", hex(_g_.stack.hi), "]\n")
+			print("entersyscallblock inconsistent ", hex(sp1), " ", hex(sp2), " ", hex(sp3), " [", hex(gp.stack.lo), ",", hex(gp.stack.hi), "]\n")
 			throw("entersyscallblock")
 		})
 	}
-	casgstatus(_g_, _Grunning, _Gsyscall)
-	if _g_.syscallsp < _g_.stack.lo || _g_.stack.hi < _g_.syscallsp {
+	casgstatus(gp, _Grunning, _Gsyscall)
+	if gp.syscallsp < gp.stack.lo || gp.stack.hi < gp.syscallsp {
 		systemstack(func() {
-			print("entersyscallblock inconsistent ", hex(sp), " ", hex(_g_.sched.sp), " ", hex(_g_.syscallsp), " [", hex(_g_.stack.lo), ",", hex(_g_.stack.hi), "]\n")
+			print("entersyscallblock inconsistent ", hex(sp), " ", hex(gp.sched.sp), " ", hex(gp.syscallsp), " [", hex(gp.stack.lo), ",", hex(gp.stack.hi), "]\n")
 			throw("entersyscallblock")
 		})
 	}
@@ -3739,7 +3894,7 @@
 	// Resave for traceback during blocked call.
 	save(getcallerpc(), getcallersp())
 
-	_g_.m.locks--
+	gp.m.locks--
 }
 
 func entersyscallblock_handoff() {
@@ -3763,16 +3918,16 @@
 //go:nowritebarrierrec
 //go:linkname exitsyscall
 func exitsyscall() {
-	_g_ := getg()
+	gp := getg()
 
-	_g_.m.locks++ // see comment in entersyscall
-	if getcallersp() > _g_.syscallsp {
+	gp.m.locks++ // see comment in entersyscall
+	if getcallersp() > gp.syscallsp {
 		throw("exitsyscall: syscall frame is no longer valid")
 	}
 
-	_g_.waitsince = 0
-	oldp := _g_.m.oldp.ptr()
-	_g_.m.oldp = 0
+	gp.waitsince = 0
+	oldp := gp.m.oldp.ptr()
+	gp.m.oldp = 0
 	if exitsyscallfast(oldp) {
 		// When exitsyscallfast returns success, we have a P so can now use
 		// write barriers
@@ -3781,33 +3936,33 @@
 			// profile, exactly as it was when the goroutine profiler first
 			// stopped the world.
 			systemstack(func() {
-				tryRecordGoroutineProfileWB(_g_)
+				tryRecordGoroutineProfileWB(gp)
 			})
 		}
 		if trace.enabled {
-			if oldp != _g_.m.p.ptr() || _g_.m.syscalltick != _g_.m.p.ptr().syscalltick {
+			if oldp != gp.m.p.ptr() || gp.m.syscalltick != gp.m.p.ptr().syscalltick {
 				systemstack(traceGoStart)
 			}
 		}
 		// There's a cpu for us, so we can run.
-		_g_.m.p.ptr().syscalltick++
+		gp.m.p.ptr().syscalltick++
 		// We need to cas the status and scan before resuming...
-		casgstatus(_g_, _Gsyscall, _Grunning)
+		casgstatus(gp, _Gsyscall, _Grunning)
 
 		// Garbage collector isn't running (since we are),
 		// so okay to clear syscallsp.
-		_g_.syscallsp = 0
-		_g_.m.locks--
-		if _g_.preempt {
+		gp.syscallsp = 0
+		gp.m.locks--
+		if gp.preempt {
 			// restore the preemption request in case we've cleared it in newstack
-			_g_.stackguard0 = stackPreempt
+			gp.stackguard0 = stackPreempt
 		} else {
 			// otherwise restore the real _StackGuard, we've spoiled it in entersyscall/entersyscallblock
-			_g_.stackguard0 = _g_.stack.lo + _StackGuard
+			gp.stackguard0 = gp.stack.lo + _StackGuard
 		}
-		_g_.throwsplit = false
+		gp.throwsplit = false
 
-		if sched.disable.user && !schedEnabled(_g_) {
+		if sched.disable.user && !schedEnabled(gp) {
 			// Scheduling of this goroutine is disabled.
 			Gosched()
 		}
@@ -3815,21 +3970,21 @@
 		return
 	}
 
-	_g_.sysexitticks = 0
+	gp.sysexitticks = 0
 	if trace.enabled {
 		// Wait till traceGoSysBlock event is emitted.
 		// This ensures consistency of the trace (the goroutine is started after it is blocked).
-		for oldp != nil && oldp.syscalltick == _g_.m.syscalltick {
+		for oldp != nil && oldp.syscalltick == gp.m.syscalltick {
 			osyield()
 		}
 		// We can't trace syscall exit right now because we don't have a P.
 		// Tracing code can invoke write barriers that cannot run without a P.
 		// So instead we remember the syscall exit time and emit the event
 		// in execute when we have a P.
-		_g_.sysexitticks = cputicks()
+		gp.sysexitticks = cputicks()
 	}
 
-	_g_.m.locks--
+	gp.m.locks--
 
 	// Call the scheduler.
 	mcall(exitsyscall0)
@@ -3840,14 +3995,14 @@
 	// Must wait until now because until gosched returns
 	// we don't know for sure that the garbage collector
 	// is not running.
-	_g_.syscallsp = 0
-	_g_.m.p.ptr().syscalltick++
-	_g_.throwsplit = false
+	gp.syscallsp = 0
+	gp.m.p.ptr().syscalltick++
+	gp.throwsplit = false
 }
 
 //go:nosplit
 func exitsyscallfast(oldp *p) bool {
-	_g_ := getg()
+	gp := getg()
 
 	// Freezetheworld sets stopwait but does not retake P's.
 	if sched.stopwait == freezeStopWait {
@@ -3871,7 +4026,7 @@
 				if oldp != nil {
 					// Wait till traceGoSysBlock event is emitted.
 					// This ensures consistency of the trace (the goroutine is started after it is blocked).
-					for oldp.syscalltick == _g_.m.syscalltick {
+					for oldp.syscalltick == gp.m.syscalltick {
 						osyield()
 					}
 				}
@@ -3891,33 +4046,33 @@
 //
 //go:nosplit
 func exitsyscallfast_reacquired() {
-	_g_ := getg()
-	if _g_.m.syscalltick != _g_.m.p.ptr().syscalltick {
+	gp := getg()
+	if gp.m.syscalltick != gp.m.p.ptr().syscalltick {
 		if trace.enabled {
-			// The p was retaken and then enter into syscall again (since _g_.m.syscalltick has changed).
+			// The p was retaken and then enter into syscall again (since gp.m.syscalltick has changed).
 			// traceGoSysBlock for this syscall was already emitted,
 			// but here we effectively retake the p from the new syscall running on the same p.
 			systemstack(func() {
 				// Denote blocking of the new syscall.
-				traceGoSysBlock(_g_.m.p.ptr())
+				traceGoSysBlock(gp.m.p.ptr())
 				// Denote completion of the current syscall.
 				traceGoSysExit(0)
 			})
 		}
-		_g_.m.p.ptr().syscalltick++
+		gp.m.p.ptr().syscalltick++
 	}
 }
 
 func exitsyscallfast_pidle() bool {
 	lock(&sched.lock)
-	_p_, _ := pidleget(0)
-	if _p_ != nil && atomic.Load(&sched.sysmonwait) != 0 {
-		atomic.Store(&sched.sysmonwait, 0)
+	pp, _ := pidleget(0)
+	if pp != nil && sched.sysmonwait.Load() {
+		sched.sysmonwait.Store(false)
 		notewakeup(&sched.sysmonnote)
 	}
 	unlock(&sched.lock)
-	if _p_ != nil {
-		acquirep(_p_)
+	if pp != nil {
+		acquirep(pp)
 		return true
 	}
 	return false
@@ -3933,12 +4088,12 @@
 	casgstatus(gp, _Gsyscall, _Grunnable)
 	dropg()
 	lock(&sched.lock)
-	var _p_ *p
+	var pp *p
 	if schedEnabled(gp) {
-		_p_, _ = pidleget(0)
+		pp, _ = pidleget(0)
 	}
 	var locked bool
-	if _p_ == nil {
+	if pp == nil {
 		globrunqput(gp)
 
 		// Below, we stoplockedm if gp is locked. globrunqput releases
@@ -3947,13 +4102,13 @@
 		// could race with another M transitioning gp from unlocked to
 		// locked.
 		locked = gp.lockedm != 0
-	} else if atomic.Load(&sched.sysmonwait) != 0 {
-		atomic.Store(&sched.sysmonwait, 0)
+	} else if sched.sysmonwait.Load() {
+		sched.sysmonwait.Store(false)
 		notewakeup(&sched.sysmonnote)
 	}
 	unlock(&sched.lock)
-	if _p_ != nil {
-		acquirep(_p_)
+	if pp != nil {
+		acquirep(pp)
 		execute(gp, false) // Never returns.
 	}
 	if locked {
@@ -4038,7 +4193,7 @@
 // pendingPreemptSignals is the number of preemption signals
 // that have been sent but not received. This is only used on Darwin.
 // For #41702.
-var pendingPreemptSignals uint32
+var pendingPreemptSignals atomic.Int32
 
 // Called from syscall package before Exec.
 //
@@ -4050,7 +4205,7 @@
 	// On Darwin, wait for all pending preemption signals to
 	// be received. See issue #41702.
 	if GOOS == "darwin" || GOOS == "ios" {
-		for int32(atomic.Load(&pendingPreemptSignals)) > 0 {
+		for pendingPreemptSignals.Load() > 0 {
 			osyield()
 		}
 	}
@@ -4089,8 +4244,8 @@
 	systemstack(func() {
 		newg := newproc1(fn, gp, pc)
 
-		_p_ := getg().m.p.ptr()
-		runqput(_p_, newg, true)
+		pp := getg().m.p.ptr()
+		runqput(pp, newg, true)
 
 		if mainStarted {
 			wakep()
@@ -4102,15 +4257,13 @@
 // address of the go statement that created this. The caller is responsible
 // for adding the new g to the scheduler.
 func newproc1(fn *funcval, callergp *g, callerpc uintptr) *g {
-	_g_ := getg()
-
 	if fn == nil {
 		fatal("go of nil func value")
 	}
-	acquirem() // disable preemption because it can be holding p in a local var
 
-	_p_ := _g_.m.p.ptr()
-	newg := gfget(_p_)
+	mp := acquirem() // disable preemption because we hold M and P in local vars.
+	pp := mp.p.ptr()
+	newg := gfget(pp)
 	if newg == nil {
 		newg = malg(_StackMin)
 		casgstatus(newg, _Gidle, _Gdead)
@@ -4145,11 +4298,11 @@
 	newg.ancestors = saveAncestors(callergp)
 	newg.startpc = fn.fn
 	if isSystemGoroutine(newg, false) {
-		atomic.Xadd(&sched.ngsys, +1)
+		sched.ngsys.Add(1)
 	} else {
 		// Only user goroutines inherit pprof labels.
-		if _g_.m.curg != nil {
-			newg.labels = _g_.m.curg.labels
+		if mp.curg != nil {
+			newg.labels = mp.curg.labels
 		}
 		if goroutineProfile.active {
 			// A concurrent goroutine profile is running. It should include
@@ -4166,18 +4319,18 @@
 		newg.tracking = true
 	}
 	casgstatus(newg, _Gdead, _Grunnable)
-	gcController.addScannableStack(_p_, int64(newg.stack.hi-newg.stack.lo))
+	gcController.addScannableStack(pp, int64(newg.stack.hi-newg.stack.lo))
 
-	if _p_.goidcache == _p_.goidcacheend {
+	if pp.goidcache == pp.goidcacheend {
 		// Sched.goidgen is the last allocated id,
 		// this batch must be [sched.goidgen+1, sched.goidgen+GoidCacheBatch].
 		// At startup sched.goidgen=0, so main goroutine receives goid=1.
-		_p_.goidcache = atomic.Xadd64(&sched.goidgen, _GoidCacheBatch)
-		_p_.goidcache -= _GoidCacheBatch - 1
-		_p_.goidcacheend = _p_.goidcache + _GoidCacheBatch
+		pp.goidcache = sched.goidgen.Add(_GoidCacheBatch)
+		pp.goidcache -= _GoidCacheBatch - 1
+		pp.goidcacheend = pp.goidcache + _GoidCacheBatch
 	}
-	newg.goid = int64(_p_.goidcache)
-	_p_.goidcache++
+	newg.goid = pp.goidcache
+	pp.goidcache++
 	if raceenabled {
 		newg.racectx = racegostart(callerpc)
 		if newg.labels != nil {
@@ -4189,7 +4342,7 @@
 	if trace.enabled {
 		traceGoCreate(newg, newg.startpc)
 	}
-	releasem(_g_.m)
+	releasem(mp)
 
 	return newg
 }
@@ -4230,7 +4383,7 @@
 
 // Put on gfree list.
 // If local list is too long, transfer a batch to the global list.
-func gfput(_p_ *p, gp *g) {
+func gfput(pp *p, gp *g) {
 	if readgstatus(gp) != _Gdead {
 		throw("gfput: bad status (not Gdead)")
 	}
@@ -4245,17 +4398,17 @@
 		gp.stackguard0 = 0
 	}
 
-	_p_.gFree.push(gp)
-	_p_.gFree.n++
-	if _p_.gFree.n >= 64 {
+	pp.gFree.push(gp)
+	pp.gFree.n++
+	if pp.gFree.n >= 64 {
 		var (
 			inc      int32
 			stackQ   gQueue
 			noStackQ gQueue
 		)
-		for _p_.gFree.n >= 32 {
-			gp = _p_.gFree.pop()
-			_p_.gFree.n--
+		for pp.gFree.n >= 32 {
+			gp := pp.gFree.pop()
+			pp.gFree.n--
 			if gp.stack.lo == 0 {
 				noStackQ.push(gp)
 			} else {
@@ -4273,12 +4426,12 @@
 
 // Get from gfree list.
 // If local list is empty, grab a batch from global list.
-func gfget(_p_ *p) *g {
+func gfget(pp *p) *g {
 retry:
-	if _p_.gFree.empty() && (!sched.gFree.stack.empty() || !sched.gFree.noStack.empty()) {
+	if pp.gFree.empty() && (!sched.gFree.stack.empty() || !sched.gFree.noStack.empty()) {
 		lock(&sched.gFree.lock)
 		// Move a batch of free Gs to the P.
-		for _p_.gFree.n < 32 {
+		for pp.gFree.n < 32 {
 			// Prefer Gs with stacks.
 			gp := sched.gFree.stack.pop()
 			if gp == nil {
@@ -4288,17 +4441,17 @@
 				}
 			}
 			sched.gFree.n--
-			_p_.gFree.push(gp)
-			_p_.gFree.n++
+			pp.gFree.push(gp)
+			pp.gFree.n++
 		}
 		unlock(&sched.gFree.lock)
 		goto retry
 	}
-	gp := _p_.gFree.pop()
+	gp := pp.gFree.pop()
 	if gp == nil {
 		return nil
 	}
-	_p_.gFree.n--
+	pp.gFree.n--
 	if gp.stack.lo != 0 && gp.stack.hi-gp.stack.lo != uintptr(startingStackSize) {
 		// Deallocate old stack. We kept it in gfput because it was the
 		// right size when the goroutine was put on the free list, but
@@ -4331,15 +4484,15 @@
 }
 
 // Purge all cached G's from gfree list to the global list.
-func gfpurge(_p_ *p) {
+func gfpurge(pp *p) {
 	var (
 		inc      int32
 		stackQ   gQueue
 		noStackQ gQueue
 	)
-	for !_p_.gFree.empty() {
-		gp := _p_.gFree.pop()
-		_p_.gFree.n--
+	for !pp.gFree.empty() {
+		gp := pp.gFree.pop()
+		pp.gFree.n--
 		if gp.stack.lo == 0 {
 			noStackQ.push(gp)
 		} else {
@@ -4368,9 +4521,9 @@
 	if GOARCH == "wasm" {
 		return // no threads on wasm yet
 	}
-	_g_ := getg()
-	_g_.m.lockedg.set(_g_)
-	_g_.lockedm.set(_g_.m)
+	gp := getg()
+	gp.m.lockedg.set(gp)
+	gp.lockedm.set(gp.m)
 }
 
 //go:nosplit
@@ -4396,10 +4549,10 @@
 		// while we're in a known-good state.
 		startTemplateThread()
 	}
-	_g_ := getg()
-	_g_.m.lockedExt++
-	if _g_.m.lockedExt == 0 {
-		_g_.m.lockedExt--
+	gp := getg()
+	gp.m.lockedExt++
+	if gp.m.lockedExt == 0 {
+		gp.m.lockedExt--
 		panic("LockOSThread nesting overflow")
 	}
 	dolockOSThread()
@@ -4420,12 +4573,12 @@
 	if GOARCH == "wasm" {
 		return // no threads on wasm yet
 	}
-	_g_ := getg()
-	if _g_.m.lockedInt != 0 || _g_.m.lockedExt != 0 {
+	gp := getg()
+	if gp.m.lockedInt != 0 || gp.m.lockedExt != 0 {
 		return
 	}
-	_g_.m.lockedg = 0
-	_g_.lockedm = 0
+	gp.m.lockedg = 0
+	gp.lockedm = 0
 }
 
 //go:nosplit
@@ -4443,21 +4596,21 @@
 // the goroutine locked to the OS thread until the goroutine (and
 // hence the thread) exits.
 func UnlockOSThread() {
-	_g_ := getg()
-	if _g_.m.lockedExt == 0 {
+	gp := getg()
+	if gp.m.lockedExt == 0 {
 		return
 	}
-	_g_.m.lockedExt--
+	gp.m.lockedExt--
 	dounlockOSThread()
 }
 
 //go:nosplit
 func unlockOSThread() {
-	_g_ := getg()
-	if _g_.m.lockedInt == 0 {
+	gp := getg()
+	if gp.m.lockedInt == 0 {
 		systemstack(badunlockosthread)
 	}
-	_g_.m.lockedInt--
+	gp.m.lockedInt--
 	dounlockOSThread()
 }
 
@@ -4466,9 +4619,9 @@
 }
 
 func gcount() int32 {
-	n := int32(atomic.Loaduintptr(&allglen)) - sched.gFree.n - int32(atomic.Load(&sched.ngsys))
-	for _, _p_ := range allp {
-		n -= _p_.gFree.n
+	n := int32(atomic.Loaduintptr(&allglen)) - sched.gFree.n - sched.ngsys.Load()
+	for _, pp := range allp {
+		n -= pp.gFree.n
 	}
 
 	// All these variables can be changed concurrently, so the result can be inconsistent.
@@ -4484,8 +4637,11 @@
 }
 
 var prof struct {
-	signalLock uint32
-	hz         int32
+	signalLock atomic.Uint32
+
+	// Must hold signalLock to write. Reads may be lock-free, but
+	// signalLock should be taken to synchronize with changes.
+	hz atomic.Int32
 }
 
 func _System()                    { _System() }
@@ -4500,7 +4656,7 @@
 //
 //go:nowritebarrierrec
 func sigprof(pc, sp, lr uintptr, gp *g, mp *m) {
-	if prof.hz == 0 {
+	if prof.hz.Load() == 0 {
 		return
 	}
 
@@ -4550,7 +4706,7 @@
 		// cgoCallers.  We are running in a signal handler
 		// with all signals blocked, so we don't have to worry
 		// about any other code interrupting us.
-		if atomic.Load(&mp.cgoCallersUse) == 0 && mp.cgoCallers != nil && mp.cgoCallers[0] != 0 {
+		if mp.cgoCallersUse.Load() == 0 && mp.cgoCallers != nil && mp.cgoCallers[0] != 0 {
 			for cgoOff < len(mp.cgoCallers) && mp.cgoCallers[cgoOff] != 0 {
 				cgoOff++
 			}
@@ -4563,41 +4719,37 @@
 		if n > 0 {
 			n += cgoOff
 		}
+	} else if usesLibcall() && mp.libcallg != 0 && mp.libcallpc != 0 && mp.libcallsp != 0 {
+		// Libcall, i.e. runtime syscall on windows.
+		// Collect Go stack that leads to the call.
+		n = gentraceback(mp.libcallpc, mp.libcallsp, 0, mp.libcallg.ptr(), 0, &stk[n], len(stk[n:]), nil, nil, 0)
+	} else if mp != nil && mp.vdsoSP != 0 {
+		// VDSO call, e.g. nanotime1 on Linux.
+		// Collect Go stack that leads to the call.
+		n = gentraceback(mp.vdsoPC, mp.vdsoSP, 0, gp, 0, &stk[n], len(stk[n:]), nil, nil, _TraceJumpStack)
 	} else {
 		n = gentraceback(pc, sp, lr, gp, 0, &stk[0], len(stk), nil, nil, _TraceTrap|_TraceJumpStack)
 	}
 
 	if n <= 0 {
 		// Normal traceback is impossible or has failed.
-		// See if it falls into several common cases.
-		n = 0
-		if usesLibcall() && mp.libcallg != 0 && mp.libcallpc != 0 && mp.libcallsp != 0 {
-			// Libcall, i.e. runtime syscall on windows.
-			// Collect Go stack that leads to the call.
-			n = gentraceback(mp.libcallpc, mp.libcallsp, 0, mp.libcallg.ptr(), 0, &stk[0], len(stk), nil, nil, 0)
+		// Account it against abstract "System" or "GC".
+		n = 2
+		if inVDSOPage(pc) {
+			pc = abi.FuncPCABIInternal(_VDSO) + sys.PCQuantum
+		} else if pc > firstmoduledata.etext {
+			// "ExternalCode" is better than "etext".
+			pc = abi.FuncPCABIInternal(_ExternalCode) + sys.PCQuantum
 		}
-		if n == 0 && mp != nil && mp.vdsoSP != 0 {
-			n = gentraceback(mp.vdsoPC, mp.vdsoSP, 0, gp, 0, &stk[0], len(stk), nil, nil, _TraceTrap|_TraceJumpStack)
-		}
-		if n == 0 {
-			// If all of the above has failed, account it against abstract "System" or "GC".
-			n = 2
-			if inVDSOPage(pc) {
-				pc = abi.FuncPCABIInternal(_VDSO) + sys.PCQuantum
-			} else if pc > firstmoduledata.etext {
-				// "ExternalCode" is better than "etext".
-				pc = abi.FuncPCABIInternal(_ExternalCode) + sys.PCQuantum
-			}
-			stk[0] = pc
-			if mp.preemptoff != "" {
-				stk[1] = abi.FuncPCABIInternal(_GC) + sys.PCQuantum
-			} else {
-				stk[1] = abi.FuncPCABIInternal(_System) + sys.PCQuantum
-			}
+		stk[0] = pc
+		if mp.preemptoff != "" {
+			stk[1] = abi.FuncPCABIInternal(_GC) + sys.PCQuantum
+		} else {
+			stk[1] = abi.FuncPCABIInternal(_System) + sys.PCQuantum
 		}
 	}
 
-	if prof.hz != 0 {
+	if prof.hz.Load() != 0 {
 		// Note: it can happen on Windows that we interrupted a system thread
 		// with no g, so gp could nil. The other nil checks are done out of
 		// caution, but not expected to be nil in practice.
@@ -4630,22 +4782,22 @@
 
 	// Disable preemption, otherwise we can be rescheduled to another thread
 	// that has profiling enabled.
-	_g_ := getg()
-	_g_.m.locks++
+	gp := getg()
+	gp.m.locks++
 
 	// Stop profiler on this thread so that it is safe to lock prof.
 	// if a profiling signal came in while we had prof locked,
 	// it would deadlock.
 	setThreadCPUProfiler(0)
 
-	for !atomic.Cas(&prof.signalLock, 0, 1) {
+	for !prof.signalLock.CompareAndSwap(0, 1) {
 		osyield()
 	}
-	if prof.hz != hz {
+	if prof.hz.Load() != hz {
 		setProcessCPUProfiler(hz)
-		prof.hz = hz
+		prof.hz.Store(hz)
 	}
-	atomic.Store(&prof.signalLock, 0)
+	prof.signalLock.Store(0)
 
 	lock(&sched.lock)
 	sched.profilehz = hz
@@ -4655,7 +4807,7 @@
 		setThreadCPUProfiler(hz)
 	}
 
-	_g_.m.locks--
+	gp.m.locks--
 }
 
 // init initializes pp, which may be a freshly allocated p or a
@@ -4726,9 +4878,9 @@
 		lock(&pp.timersLock)
 		moveTimers(plocal, pp.timers)
 		pp.timers = nil
-		pp.numTimers = 0
-		pp.deletedTimers = 0
-		atomic.Store64(&pp.timer0When, 0)
+		pp.numTimers.Store(0)
+		pp.deletedTimers.Store(0)
+		pp.timer0When.Store(0)
 		unlock(&pp.timersLock)
 		unlock(&plocal.timersLock)
 	}
@@ -4852,32 +5004,32 @@
 		atomicstorep(unsafe.Pointer(&allp[i]), unsafe.Pointer(pp))
 	}
 
-	_g_ := getg()
-	if _g_.m.p != 0 && _g_.m.p.ptr().id < nprocs {
+	gp := getg()
+	if gp.m.p != 0 && gp.m.p.ptr().id < nprocs {
 		// continue to use the current P
-		_g_.m.p.ptr().status = _Prunning
-		_g_.m.p.ptr().mcache.prepareForSweep()
+		gp.m.p.ptr().status = _Prunning
+		gp.m.p.ptr().mcache.prepareForSweep()
 	} else {
 		// release the current P and acquire allp[0].
 		//
 		// We must do this before destroying our current P
 		// because p.destroy itself has write barriers, so we
 		// need to do that from a valid P.
-		if _g_.m.p != 0 {
+		if gp.m.p != 0 {
 			if trace.enabled {
 				// Pretend that we were descheduled
 				// and then scheduled again to keep
 				// the trace sane.
 				traceGoSched()
-				traceProcStop(_g_.m.p.ptr())
+				traceProcStop(gp.m.p.ptr())
 			}
-			_g_.m.p.ptr().m = 0
+			gp.m.p.ptr().m = 0
 		}
-		_g_.m.p = 0
-		p := allp[0]
-		p.m = 0
-		p.status = _Pidle
-		acquirep(p)
+		gp.m.p = 0
+		pp := allp[0]
+		pp.m = 0
+		pp.status = _Pidle
+		acquirep(pp)
 		if trace.enabled {
 			traceGoStart()
 		}
@@ -4888,8 +5040,8 @@
 
 	// release resources from unused P's
 	for i := nprocs; i < old; i++ {
-		p := allp[i]
-		p.destroy()
+		pp := allp[i]
+		pp.destroy()
 		// can't free P itself because it can be referenced by an M in syscall
 	}
 
@@ -4904,17 +5056,17 @@
 
 	var runnablePs *p
 	for i := nprocs - 1; i >= 0; i-- {
-		p := allp[i]
-		if _g_.m.p.ptr() == p {
+		pp := allp[i]
+		if gp.m.p.ptr() == pp {
 			continue
 		}
-		p.status = _Pidle
-		if runqempty(p) {
-			pidleput(p, now)
+		pp.status = _Pidle
+		if runqempty(pp) {
+			pidleput(pp, now)
 		} else {
-			p.m.set(mget())
-			p.link.set(runnablePs)
-			runnablePs = p
+			pp.m.set(mget())
+			pp.link.set(runnablePs)
+			runnablePs = pp
 		}
 	}
 	stealOrder.reset(uint32(nprocs))
@@ -4930,18 +5082,18 @@
 // Associate p and the current m.
 //
 // This function is allowed to have write barriers even if the caller
-// isn't because it immediately acquires _p_.
+// isn't because it immediately acquires pp.
 //
 //go:yeswritebarrierrec
-func acquirep(_p_ *p) {
+func acquirep(pp *p) {
 	// Do the part that isn't allowed to have write barriers.
-	wirep(_p_)
+	wirep(pp)
 
 	// Have p; write barriers now allowed.
 
 	// Perform deferred mcache flush before this P can allocate
 	// from a potentially stale mcache.
-	_p_.mcache.prepareForSweep()
+	pp.mcache.prepareForSweep()
 
 	if trace.enabled {
 		traceProcStart()
@@ -4949,49 +5101,49 @@
 }
 
 // wirep is the first step of acquirep, which actually associates the
-// current M to _p_. This is broken out so we can disallow write
+// current M to pp. This is broken out so we can disallow write
 // barriers for this part, since we don't yet have a P.
 //
 //go:nowritebarrierrec
 //go:nosplit
-func wirep(_p_ *p) {
-	_g_ := getg()
+func wirep(pp *p) {
+	gp := getg()
 
-	if _g_.m.p != 0 {
+	if gp.m.p != 0 {
 		throw("wirep: already in go")
 	}
-	if _p_.m != 0 || _p_.status != _Pidle {
+	if pp.m != 0 || pp.status != _Pidle {
 		id := int64(0)
-		if _p_.m != 0 {
-			id = _p_.m.ptr().id
+		if pp.m != 0 {
+			id = pp.m.ptr().id
 		}
-		print("wirep: p->m=", _p_.m, "(", id, ") p->status=", _p_.status, "\n")
+		print("wirep: p->m=", pp.m, "(", id, ") p->status=", pp.status, "\n")
 		throw("wirep: invalid p state")
 	}
-	_g_.m.p.set(_p_)
-	_p_.m.set(_g_.m)
-	_p_.status = _Prunning
+	gp.m.p.set(pp)
+	pp.m.set(gp.m)
+	pp.status = _Prunning
 }
 
 // Disassociate p and the current m.
 func releasep() *p {
-	_g_ := getg()
+	gp := getg()
 
-	if _g_.m.p == 0 {
+	if gp.m.p == 0 {
 		throw("releasep: invalid arg")
 	}
-	_p_ := _g_.m.p.ptr()
-	if _p_.m.ptr() != _g_.m || _p_.status != _Prunning {
-		print("releasep: m=", _g_.m, " m->p=", _g_.m.p.ptr(), " p->m=", hex(_p_.m), " p->status=", _p_.status, "\n")
+	pp := gp.m.p.ptr()
+	if pp.m.ptr() != gp.m || pp.status != _Prunning {
+		print("releasep: m=", gp.m, " m->p=", gp.m.p.ptr(), " p->m=", hex(pp.m), " p->status=", pp.status, "\n")
 		throw("releasep: invalid p state")
 	}
 	if trace.enabled {
-		traceProcStop(_g_.m.p.ptr())
+		traceProcStop(gp.m.p.ptr())
 	}
-	_g_.m.p = 0
-	_p_.m = 0
-	_p_.status = _Pidle
-	return _p_
+	gp.m.p = 0
+	pp.m = 0
+	pp.status = _Pidle
+	return pp
 }
 
 func incidlelocked(v int32) {
@@ -5020,7 +5172,7 @@
 	// freezetheworld will cause all running threads to block.
 	// And runtime will essentially enter into deadlock state,
 	// except that there is a thread that will call exit soon.
-	if panicking > 0 {
+	if panicking.Load() > 0 {
 		return
 	}
 
@@ -5090,7 +5242,7 @@
 			// M must be spinning to steal. We set this to be
 			// explicit, but since this is the only M it would
 			// become spinning on its own anyways.
-			atomic.Xadd(&sched.nmspinning, 1)
+			sched.nmspinning.Add(1)
 			mp.spinning = true
 			mp.nextp.set(pp)
 			notewakeup(&mp.park)
@@ -5099,8 +5251,8 @@
 	}
 
 	// There are no goroutines running, so we can look at the P's.
-	for _, _p_ := range allp {
-		if len(_p_.timers) > 0 {
+	for _, pp := range allp {
+		if len(pp.timers) > 0 {
 			return
 		}
 	}
@@ -5160,13 +5312,13 @@
 		// from a timer to avoid adding system load to applications that spend
 		// most of their time sleeping.
 		now := nanotime()
-		if debug.schedtrace <= 0 && (sched.gcwaiting != 0 || atomic.Load(&sched.npidle) == uint32(gomaxprocs)) {
+		if debug.schedtrace <= 0 && (sched.gcwaiting.Load() || sched.npidle.Load() == gomaxprocs) {
 			lock(&sched.lock)
-			if atomic.Load(&sched.gcwaiting) != 0 || atomic.Load(&sched.npidle) == uint32(gomaxprocs) {
+			if sched.gcwaiting.Load() || sched.npidle.Load() == gomaxprocs {
 				syscallWake := false
 				next := timeSleepUntil()
 				if next > now {
-					atomic.Store(&sched.sysmonwait, 1)
+					sched.sysmonwait.Store(true)
 					unlock(&sched.lock)
 					// Make wake-up period small enough
 					// for the sampling to be correct.
@@ -5183,7 +5335,7 @@
 						osRelax(false)
 					}
 					lock(&sched.lock)
-					atomic.Store(&sched.sysmonwait, 0)
+					sched.sysmonwait.Store(false)
 					noteclear(&sched.sysmonnote)
 				}
 				if syscallWake {
@@ -5204,9 +5356,9 @@
 			asmcgocall(*cgo_yield, nil)
 		}
 		// poll network if not polled for more than 10ms
-		lastpoll := int64(atomic.Load64(&sched.lastpoll))
+		lastpoll := sched.lastpoll.Load()
 		if netpollinited() && lastpoll != 0 && lastpoll+10*1000*1000 < now {
-			atomic.Cas64(&sched.lastpoll, uint64(lastpoll), uint64(now))
+			sched.lastpoll.CompareAndSwap(lastpoll, now)
 			list := netpoll(0) // non-blocking - returns list of goroutines
 			if !list.empty() {
 				// Need to decrement number of idle locked M's
@@ -5253,9 +5405,9 @@
 			idle++
 		}
 		// check if we need to force a GC
-		if t := (gcTrigger{kind: gcTriggerTime, now: now}); t.test() && atomic.Load(&forcegc.idle) != 0 {
+		if t := (gcTrigger{kind: gcTriggerTime, now: now}); t.test() && forcegc.idle.Load() {
 			lock(&forcegc.lock)
-			forcegc.idle = 0
+			forcegc.idle.Store(false)
 			var list gList
 			list.push(forcegc.g)
 			injectglist(&list)
@@ -5289,23 +5441,23 @@
 	// temporarily drop the allpLock. Hence, we need to re-fetch
 	// allp each time around the loop.
 	for i := 0; i < len(allp); i++ {
-		_p_ := allp[i]
-		if _p_ == nil {
+		pp := allp[i]
+		if pp == nil {
 			// This can happen if procresize has grown
 			// allp but not yet created new Ps.
 			continue
 		}
-		pd := &_p_.sysmontick
-		s := _p_.status
+		pd := &pp.sysmontick
+		s := pp.status
 		sysretake := false
 		if s == _Prunning || s == _Psyscall {
 			// Preempt G if it's running for too long.
-			t := int64(_p_.schedtick)
+			t := int64(pp.schedtick)
 			if int64(pd.schedtick) != t {
 				pd.schedtick = uint32(t)
 				pd.schedwhen = now
 			} else if pd.schedwhen+forcePreemptNS <= now {
-				preemptone(_p_)
+				preemptone(pp)
 				// In case of syscall, preemptone() doesn't
 				// work, because there is no M wired to P.
 				sysretake = true
@@ -5313,7 +5465,7 @@
 		}
 		if s == _Psyscall {
 			// Retake P from syscall if it's there for more than 1 sysmon tick (at least 20us).
-			t := int64(_p_.syscalltick)
+			t := int64(pp.syscalltick)
 			if !sysretake && int64(pd.syscalltick) != t {
 				pd.syscalltick = uint32(t)
 				pd.syscallwhen = now
@@ -5322,7 +5474,7 @@
 			// On the one hand we don't want to retake Ps if there is no other work to do,
 			// but on the other hand we want to retake them eventually
 			// because they can prevent the sysmon thread from deep sleep.
-			if runqempty(_p_) && atomic.Load(&sched.nmspinning)+atomic.Load(&sched.npidle) > 0 && pd.syscallwhen+10*1000*1000 > now {
+			if runqempty(pp) && sched.nmspinning.Load()+sched.npidle.Load() > 0 && pd.syscallwhen+10*1000*1000 > now {
 				continue
 			}
 			// Drop allpLock so we can take sched.lock.
@@ -5332,14 +5484,14 @@
 			// Otherwise the M from which we retake can exit the syscall,
 			// increment nmidle and report deadlock.
 			incidlelocked(-1)
-			if atomic.Cas(&_p_.status, s, _Pidle) {
+			if atomic.Cas(&pp.status, s, _Pidle) {
 				if trace.enabled {
-					traceGoSysBlock(_p_)
-					traceProcStop(_p_)
+					traceGoSysBlock(pp)
+					traceProcStop(pp)
 				}
 				n++
-				_p_.syscalltick++
-				handoffp(_p_)
+				pp.syscalltick++
+				handoffp(pp)
 			}
 			incidlelocked(1)
 			lock(&allpLock)
@@ -5356,11 +5508,11 @@
 // Returns true if preemption request was issued to at least one goroutine.
 func preemptall() bool {
 	res := false
-	for _, _p_ := range allp {
-		if _p_.status != _Prunning {
+	for _, pp := range allp {
+		if pp.status != _Prunning {
 			continue
 		}
-		if preemptone(_p_) {
+		if preemptone(pp) {
 			res = true
 		}
 	}
@@ -5377,8 +5529,8 @@
 // The actual preemption will happen at some point in the future
 // and will be indicated by the gp->status no longer being
 // Grunning
-func preemptone(_p_ *p) bool {
-	mp := _p_.m.ptr()
+func preemptone(pp *p) bool {
+	mp := pp.m.ptr()
 	if mp == nil || mp == getg().m {
 		return false
 	}
@@ -5397,7 +5549,7 @@
 
 	// Request an async preemption of this P.
 	if preemptMSupported && debug.asyncpreemptoff == 0 {
-		_p_.preempt = true
+		pp.preempt = true
 		preemptM(mp)
 	}
 
@@ -5413,23 +5565,25 @@
 	}
 
 	lock(&sched.lock)
-	print("SCHED ", (now-starttime)/1e6, "ms: gomaxprocs=", gomaxprocs, " idleprocs=", sched.npidle, " threads=", mcount(), " spinningthreads=", sched.nmspinning, " idlethreads=", sched.nmidle, " runqueue=", sched.runqsize)
+	print("SCHED ", (now-starttime)/1e6, "ms: gomaxprocs=", gomaxprocs, " idleprocs=", sched.npidle.Load(), " threads=", mcount(), " spinningthreads=", sched.nmspinning.Load(), " needspinning=", sched.needspinning.Load(), " idlethreads=", sched.nmidle, " runqueue=", sched.runqsize)
 	if detailed {
-		print(" gcwaiting=", sched.gcwaiting, " nmidlelocked=", sched.nmidlelocked, " stopwait=", sched.stopwait, " sysmonwait=", sched.sysmonwait, "\n")
+		print(" gcwaiting=", sched.gcwaiting.Load(), " nmidlelocked=", sched.nmidlelocked, " stopwait=", sched.stopwait, " sysmonwait=", sched.sysmonwait.Load(), "\n")
 	}
 	// We must be careful while reading data from P's, M's and G's.
 	// Even if we hold schedlock, most data can be changed concurrently.
 	// E.g. (p->m ? p->m->id : -1) can crash if p->m changes from non-nil to nil.
-	for i, _p_ := range allp {
-		mp := _p_.m.ptr()
-		h := atomic.Load(&_p_.runqhead)
-		t := atomic.Load(&_p_.runqtail)
+	for i, pp := range allp {
+		mp := pp.m.ptr()
+		h := atomic.Load(&pp.runqhead)
+		t := atomic.Load(&pp.runqtail)
 		if detailed {
-			id := int64(-1)
+			print("  P", i, ": status=", pp.status, " schedtick=", pp.schedtick, " syscalltick=", pp.syscalltick, " m=")
 			if mp != nil {
-				id = mp.id
+				print(mp.id)
+			} else {
+				print("nil")
 			}
-			print("  P", i, ": status=", _p_.status, " schedtick=", _p_.schedtick, " syscalltick=", _p_.syscalltick, " m=", id, " runqsize=", t-h, " gfreecnt=", _p_.gFree.n, " timerslen=", len(_p_.timers), "\n")
+			print(" runqsize=", t-h, " gfreecnt=", pp.gFree.n, " timerslen=", len(pp.timers), "\n")
 		} else {
 			// In non-detailed mode format lengths of per-P run queues as:
 			// [len1 len2 len3 len4]
@@ -5450,36 +5604,42 @@
 	}
 
 	for mp := allm; mp != nil; mp = mp.alllink {
-		_p_ := mp.p.ptr()
-		gp := mp.curg
-		lockedg := mp.lockedg.ptr()
-		id1 := int32(-1)
-		if _p_ != nil {
-			id1 = _p_.id
+		pp := mp.p.ptr()
+		print("  M", mp.id, ": p=")
+		if pp != nil {
+			print(pp.id)
+		} else {
+			print("nil")
 		}
-		id2 := int64(-1)
-		if gp != nil {
-			id2 = gp.goid
+		print(" curg=")
+		if mp.curg != nil {
+			print(mp.curg.goid)
+		} else {
+			print("nil")
 		}
-		id3 := int64(-1)
-		if lockedg != nil {
-			id3 = lockedg.goid
+		print(" mallocing=", mp.mallocing, " throwing=", mp.throwing, " preemptoff=", mp.preemptoff, " locks=", mp.locks, " dying=", mp.dying, " spinning=", mp.spinning, " blocked=", mp.blocked, " lockedg=")
+		if lockedg := mp.lockedg.ptr(); lockedg != nil {
+			print(lockedg.goid)
+		} else {
+			print("nil")
 		}
-		print("  M", mp.id, ": p=", id1, " curg=", id2, " mallocing=", mp.mallocing, " throwing=", mp.throwing, " preemptoff=", mp.preemptoff, ""+" locks=", mp.locks, " dying=", mp.dying, " spinning=", mp.spinning, " blocked=", mp.blocked, " lockedg=", id3, "\n")
+		print("\n")
 	}
 
 	forEachG(func(gp *g) {
-		mp := gp.m
-		lockedm := gp.lockedm.ptr()
-		id1 := int64(-1)
-		if mp != nil {
-			id1 = mp.id
+		print("  G", gp.goid, ": status=", readgstatus(gp), "(", gp.waitreason.String(), ") m=")
+		if gp.m != nil {
+			print(gp.m.id)
+		} else {
+			print("nil")
 		}
-		id2 := int64(-1)
-		if lockedm != nil {
-			id2 = lockedm.id
+		print(" lockedm=")
+		if lockedm := gp.lockedm.ptr(); lockedm != nil {
+			print(lockedm.id)
+		} else {
+			print("nil")
 		}
-		print("  G", gp.goid, ": status=", readgstatus(gp), "(", gp.waitreason.String(), ") m=", id1, " lockedm=", id2, "\n")
+		print("\n")
 	})
 	unlock(&sched.lock)
 }
@@ -5501,7 +5661,7 @@
 		sched.disable.n = 0
 		globrunqputbatch(&sched.disable.runnable, n)
 		unlock(&sched.lock)
-		for ; n != 0 && sched.npidle != 0; n-- {
+		for ; n != 0 && sched.npidle.Load() != 0; n-- {
 			startm(nil, false)
 		}
 	} else {
@@ -5592,7 +5752,7 @@
 
 // Try get a batch of G's from the global runnable queue.
 // sched.lock must be held.
-func globrunqget(_p_ *p, max int32) *g {
+func globrunqget(pp *p, max int32) *g {
 	assertLockHeld(&sched.lock)
 
 	if sched.runqsize == 0 {
@@ -5606,8 +5766,8 @@
 	if max > 0 && n > max {
 		n = max
 	}
-	if n > int32(len(_p_.runq))/2 {
-		n = int32(len(_p_.runq)) / 2
+	if n > int32(len(pp.runq))/2 {
+		n = int32(len(pp.runq)) / 2
 	}
 
 	sched.runqsize -= n
@@ -5616,7 +5776,7 @@
 	n--
 	for ; n > 0; n-- {
 		gp1 := sched.runq.pop()
-		runqput(_p_, gp1, false)
+		runqput(pp, gp1, false)
 	}
 	return gp
 }
@@ -5671,7 +5831,7 @@
 // TODO(prattmic): Additional targeted updates may improve the above cases.
 // e.g., updating the mask when stealing a timer.
 func updateTimerPMask(pp *p) {
-	if atomic.Load(&pp.numTimers) > 0 {
+	if pp.numTimers.Load() > 0 {
 		return
 	}
 
@@ -5679,7 +5839,7 @@
 	// decrement numTimers when handling a timerModified timer in
 	// checkTimers. We must take timersLock to serialize with these changes.
 	lock(&pp.timersLock)
-	if atomic.Load(&pp.numTimers) == 0 {
+	if pp.numTimers.Load() == 0 {
 		timerpMask.clear(pp.id)
 	}
 	unlock(&pp.timersLock)
@@ -5696,21 +5856,21 @@
 // May run during STW, so write barriers are not allowed.
 //
 //go:nowritebarrierrec
-func pidleput(_p_ *p, now int64) int64 {
+func pidleput(pp *p, now int64) int64 {
 	assertLockHeld(&sched.lock)
 
-	if !runqempty(_p_) {
+	if !runqempty(pp) {
 		throw("pidleput: P has non-empty run queue")
 	}
 	if now == 0 {
 		now = nanotime()
 	}
-	updateTimerPMask(_p_) // clear if there are no timers.
-	idlepMask.set(_p_.id)
-	_p_.link = sched.pidle
-	sched.pidle.set(_p_)
-	atomic.Xadd(&sched.npidle, 1)
-	if !_p_.limiterEvent.start(limiterEventIdle, now) {
+	updateTimerPMask(pp) // clear if there are no timers.
+	idlepMask.set(pp.id)
+	pp.link = sched.pidle
+	sched.pidle.set(pp)
+	sched.npidle.Add(1)
+	if !pp.limiterEvent.start(limiterEventIdle, now) {
 		throw("must be able to track idle limiter event")
 	}
 	return now
@@ -5726,33 +5886,58 @@
 func pidleget(now int64) (*p, int64) {
 	assertLockHeld(&sched.lock)
 
-	_p_ := sched.pidle.ptr()
-	if _p_ != nil {
+	pp := sched.pidle.ptr()
+	if pp != nil {
 		// Timer may get added at any time now.
 		if now == 0 {
 			now = nanotime()
 		}
-		timerpMask.set(_p_.id)
-		idlepMask.clear(_p_.id)
-		sched.pidle = _p_.link
-		atomic.Xadd(&sched.npidle, -1)
-		_p_.limiterEvent.stop(limiterEventIdle, now)
+		timerpMask.set(pp.id)
+		idlepMask.clear(pp.id)
+		sched.pidle = pp.link
+		sched.npidle.Add(-1)
+		pp.limiterEvent.stop(limiterEventIdle, now)
 	}
-	return _p_, now
+	return pp, now
 }
 
-// runqempty reports whether _p_ has no Gs on its local run queue.
+// pidlegetSpinning tries to get a p from the _Pidle list, acquiring ownership.
+// This is called by spinning Ms (or callers than need a spinning M) that have
+// found work. If no P is available, this must synchronized with non-spinning
+// Ms that may be preparing to drop their P without discovering this work.
+//
+// sched.lock must be held.
+//
+// May run during STW, so write barriers are not allowed.
+//
+//go:nowritebarrierrec
+func pidlegetSpinning(now int64) (*p, int64) {
+	assertLockHeld(&sched.lock)
+
+	pp, now := pidleget(now)
+	if pp == nil {
+		// See "Delicate dance" comment in findrunnable. We found work
+		// that we cannot take, we must synchronize with non-spinning
+		// Ms that may be preparing to drop their P.
+		sched.needspinning.Store(1)
+		return nil, now
+	}
+
+	return pp, now
+}
+
+// runqempty reports whether pp has no Gs on its local run queue.
 // It never returns true spuriously.
-func runqempty(_p_ *p) bool {
-	// Defend against a race where 1) _p_ has G1 in runqnext but runqhead == runqtail,
-	// 2) runqput on _p_ kicks G1 to the runq, 3) runqget on _p_ empties runqnext.
+func runqempty(pp *p) bool {
+	// Defend against a race where 1) pp has G1 in runqnext but runqhead == runqtail,
+	// 2) runqput on pp kicks G1 to the runq, 3) runqget on pp empties runqnext.
 	// Simply observing that runqhead == runqtail and then observing that runqnext == nil
 	// does not mean the queue is empty.
 	for {
-		head := atomic.Load(&_p_.runqhead)
-		tail := atomic.Load(&_p_.runqtail)
-		runnext := atomic.Loaduintptr((*uintptr)(unsafe.Pointer(&_p_.runnext)))
-		if tail == atomic.Load(&_p_.runqtail) {
+		head := atomic.Load(&pp.runqhead)
+		tail := atomic.Load(&pp.runqtail)
+		runnext := atomic.Loaduintptr((*uintptr)(unsafe.Pointer(&pp.runnext)))
+		if tail == atomic.Load(&pp.runqtail) {
 			return head == tail && runnext == 0
 		}
 	}
@@ -5771,18 +5956,18 @@
 
 // runqput tries to put g on the local runnable queue.
 // If next is false, runqput adds g to the tail of the runnable queue.
-// If next is true, runqput puts g in the _p_.runnext slot.
+// If next is true, runqput puts g in the pp.runnext slot.
 // If the run queue is full, runnext puts g on the global queue.
 // Executed only by the owner P.
-func runqput(_p_ *p, gp *g, next bool) {
+func runqput(pp *p, gp *g, next bool) {
 	if randomizeScheduler && next && fastrandn(2) == 0 {
 		next = false
 	}
 
 	if next {
 	retryNext:
-		oldnext := _p_.runnext
-		if !_p_.runnext.cas(oldnext, guintptr(unsafe.Pointer(gp))) {
+		oldnext := pp.runnext
+		if !pp.runnext.cas(oldnext, guintptr(unsafe.Pointer(gp))) {
 			goto retryNext
 		}
 		if oldnext == 0 {
@@ -5793,14 +5978,14 @@
 	}
 
 retry:
-	h := atomic.LoadAcq(&_p_.runqhead) // load-acquire, synchronize with consumers
-	t := _p_.runqtail
-	if t-h < uint32(len(_p_.runq)) {
-		_p_.runq[t%uint32(len(_p_.runq))].set(gp)
-		atomic.StoreRel(&_p_.runqtail, t+1) // store-release, makes the item available for consumption
+	h := atomic.LoadAcq(&pp.runqhead) // load-acquire, synchronize with consumers
+	t := pp.runqtail
+	if t-h < uint32(len(pp.runq)) {
+		pp.runq[t%uint32(len(pp.runq))].set(gp)
+		atomic.StoreRel(&pp.runqtail, t+1) // store-release, makes the item available for consumption
 		return
 	}
-	if runqputslow(_p_, gp, h, t) {
+	if runqputslow(pp, gp, h, t) {
 		return
 	}
 	// the queue is not full, now the put above must succeed
@@ -5809,19 +5994,19 @@
 
 // Put g and a batch of work from local runnable queue on global queue.
 // Executed only by the owner P.
-func runqputslow(_p_ *p, gp *g, h, t uint32) bool {
-	var batch [len(_p_.runq)/2 + 1]*g
+func runqputslow(pp *p, gp *g, h, t uint32) bool {
+	var batch [len(pp.runq)/2 + 1]*g
 
 	// First, grab a batch from local queue.
 	n := t - h
 	n = n / 2
-	if n != uint32(len(_p_.runq)/2) {
+	if n != uint32(len(pp.runq)/2) {
 		throw("runqputslow: queue is not full")
 	}
 	for i := uint32(0); i < n; i++ {
-		batch[i] = _p_.runq[(h+i)%uint32(len(_p_.runq))].ptr()
+		batch[i] = pp.runq[(h+i)%uint32(len(pp.runq))].ptr()
 	}
-	if !atomic.CasRel(&_p_.runqhead, h, h+n) { // cas-release, commits consume
+	if !atomic.CasRel(&pp.runqhead, h, h+n) { // cas-release, commits consume
 		return false
 	}
 	batch[n] = gp
@@ -5886,50 +6071,50 @@
 // If inheritTime is true, gp should inherit the remaining time in the
 // current time slice. Otherwise, it should start a new time slice.
 // Executed only by the owner P.
-func runqget(_p_ *p) (gp *g, inheritTime bool) {
+func runqget(pp *p) (gp *g, inheritTime bool) {
 	// If there's a runnext, it's the next G to run.
-	next := _p_.runnext
+	next := pp.runnext
 	// If the runnext is non-0 and the CAS fails, it could only have been stolen by another P,
 	// because other Ps can race to set runnext to 0, but only the current P can set it to non-0.
-	// Hence, there's no need to retry this CAS if it falls.
-	if next != 0 && _p_.runnext.cas(next, 0) {
+	// Hence, there's no need to retry this CAS if it fails.
+	if next != 0 && pp.runnext.cas(next, 0) {
 		return next.ptr(), true
 	}
 
 	for {
-		h := atomic.LoadAcq(&_p_.runqhead) // load-acquire, synchronize with other consumers
-		t := _p_.runqtail
+		h := atomic.LoadAcq(&pp.runqhead) // load-acquire, synchronize with other consumers
+		t := pp.runqtail
 		if t == h {
 			return nil, false
 		}
-		gp := _p_.runq[h%uint32(len(_p_.runq))].ptr()
-		if atomic.CasRel(&_p_.runqhead, h, h+1) { // cas-release, commits consume
+		gp := pp.runq[h%uint32(len(pp.runq))].ptr()
+		if atomic.CasRel(&pp.runqhead, h, h+1) { // cas-release, commits consume
 			return gp, false
 		}
 	}
 }
 
-// runqdrain drains the local runnable queue of _p_ and returns all goroutines in it.
+// runqdrain drains the local runnable queue of pp and returns all goroutines in it.
 // Executed only by the owner P.
-func runqdrain(_p_ *p) (drainQ gQueue, n uint32) {
-	oldNext := _p_.runnext
-	if oldNext != 0 && _p_.runnext.cas(oldNext, 0) {
+func runqdrain(pp *p) (drainQ gQueue, n uint32) {
+	oldNext := pp.runnext
+	if oldNext != 0 && pp.runnext.cas(oldNext, 0) {
 		drainQ.pushBack(oldNext.ptr())
 		n++
 	}
 
 retry:
-	h := atomic.LoadAcq(&_p_.runqhead) // load-acquire, synchronize with other consumers
-	t := _p_.runqtail
+	h := atomic.LoadAcq(&pp.runqhead) // load-acquire, synchronize with other consumers
+	t := pp.runqtail
 	qn := t - h
 	if qn == 0 {
 		return
 	}
-	if qn > uint32(len(_p_.runq)) { // read inconsistent h and t
+	if qn > uint32(len(pp.runq)) { // read inconsistent h and t
 		goto retry
 	}
 
-	if !atomic.CasRel(&_p_.runqhead, h, h+qn) { // cas-release, commits consume
+	if !atomic.CasRel(&pp.runqhead, h, h+qn) { // cas-release, commits consume
 		goto retry
 	}
 
@@ -5941,34 +6126,34 @@
 	// meanwhile, other P's can't access to all G's in local P's runnable queue and steal them.
 	// See https://groups.google.com/g/golang-dev/c/0pTKxEKhHSc/m/6Q85QjdVBQAJ for more details.
 	for i := uint32(0); i < qn; i++ {
-		gp := _p_.runq[(h+i)%uint32(len(_p_.runq))].ptr()
+		gp := pp.runq[(h+i)%uint32(len(pp.runq))].ptr()
 		drainQ.pushBack(gp)
 		n++
 	}
 	return
 }
 
-// Grabs a batch of goroutines from _p_'s runnable queue into batch.
+// Grabs a batch of goroutines from pp's runnable queue into batch.
 // Batch is a ring buffer starting at batchHead.
 // Returns number of grabbed goroutines.
 // Can be executed by any P.
-func runqgrab(_p_ *p, batch *[256]guintptr, batchHead uint32, stealRunNextG bool) uint32 {
+func runqgrab(pp *p, batch *[256]guintptr, batchHead uint32, stealRunNextG bool) uint32 {
 	for {
-		h := atomic.LoadAcq(&_p_.runqhead) // load-acquire, synchronize with other consumers
-		t := atomic.LoadAcq(&_p_.runqtail) // load-acquire, synchronize with the producer
+		h := atomic.LoadAcq(&pp.runqhead) // load-acquire, synchronize with other consumers
+		t := atomic.LoadAcq(&pp.runqtail) // load-acquire, synchronize with the producer
 		n := t - h
 		n = n - n/2
 		if n == 0 {
 			if stealRunNextG {
-				// Try to steal from _p_.runnext.
-				if next := _p_.runnext; next != 0 {
-					if _p_.status == _Prunning {
-						// Sleep to ensure that _p_ isn't about to run the g
+				// Try to steal from pp.runnext.
+				if next := pp.runnext; next != 0 {
+					if pp.status == _Prunning {
+						// Sleep to ensure that pp isn't about to run the g
 						// we are about to steal.
 						// The important use case here is when the g running
-						// on _p_ ready()s another g and then almost
+						// on pp ready()s another g and then almost
 						// immediately blocks. Instead of stealing runnext
-						// in this window, back off to give _p_ a chance to
+						// in this window, back off to give pp a chance to
 						// schedule runnext. This will avoid thrashing gs
 						// between different Ps.
 						// A sync chan send/recv takes ~50ns as of time of
@@ -5982,7 +6167,7 @@
 							osyield()
 						}
 					}
-					if !_p_.runnext.cas(next, 0) {
+					if !pp.runnext.cas(next, 0) {
 						continue
 					}
 					batch[batchHead%uint32(len(batch))] = next
@@ -5991,14 +6176,14 @@
 			}
 			return 0
 		}
-		if n > uint32(len(_p_.runq)/2) { // read inconsistent h and t
+		if n > uint32(len(pp.runq)/2) { // read inconsistent h and t
 			continue
 		}
 		for i := uint32(0); i < n; i++ {
-			g := _p_.runq[(h+i)%uint32(len(_p_.runq))]
+			g := pp.runq[(h+i)%uint32(len(pp.runq))]
 			batch[(batchHead+i)%uint32(len(batch))] = g
 		}
-		if atomic.CasRel(&_p_.runqhead, h, h+n) { // cas-release, commits consume
+		if atomic.CasRel(&pp.runqhead, h, h+n) { // cas-release, commits consume
 			return n
 		}
 	}
@@ -6007,22 +6192,22 @@
 // Steal half of elements from local runnable queue of p2
 // and put onto local runnable queue of p.
 // Returns one of the stolen elements (or nil if failed).
-func runqsteal(_p_, p2 *p, stealRunNextG bool) *g {
-	t := _p_.runqtail
-	n := runqgrab(p2, &_p_.runq, t, stealRunNextG)
+func runqsteal(pp, p2 *p, stealRunNextG bool) *g {
+	t := pp.runqtail
+	n := runqgrab(p2, &pp.runq, t, stealRunNextG)
 	if n == 0 {
 		return nil
 	}
 	n--
-	gp := _p_.runq[(t+n)%uint32(len(_p_.runq))].ptr()
+	gp := pp.runq[(t+n)%uint32(len(pp.runq))].ptr()
 	if n == 0 {
 		return gp
 	}
-	h := atomic.LoadAcq(&_p_.runqhead) // load-acquire, synchronize with consumers
-	if t-h+n >= uint32(len(_p_.runq)) {
+	h := atomic.LoadAcq(&pp.runqhead) // load-acquire, synchronize with consumers
+	if t-h+n >= uint32(len(pp.runq)) {
 		throw("runqsteal: runq overflow")
 	}
-	atomic.StoreRel(&_p_.runqtail, t+n) // store-release, makes the item available for consumption
+	atomic.StoreRel(&pp.runqtail, t+n) // store-release, makes the item available for consumption
 	return gp
 }
 
@@ -6143,8 +6328,8 @@
 
 //go:nosplit
 func procPin() int {
-	_g_ := getg()
-	mp := _g_.m
+	gp := getg()
+	mp := gp.m
 
 	mp.locks++
 	return int(mp.p.ptr().id)
@@ -6152,8 +6337,8 @@
 
 //go:nosplit
 func procUnpin() {
-	_g_ := getg()
-	_g_.m.locks--
+	gp := getg()
+	gp.m.locks--
 }
 
 //go:linkname sync_runtime_procPin sync.runtime_procPin
@@ -6190,7 +6375,7 @@
 	// GOMAXPROCS>1 and there is at least one other running P and local runq is empty.
 	// As opposed to runtime mutex we don't do passive spinning here,
 	// because there can be work on global runq or on other Ps.
-	if i >= active_spin || ncpu <= 1 || gomaxprocs <= int32(sched.npidle+sched.nmspinning)+1 {
+	if i >= active_spin || ncpu <= 1 || gomaxprocs <= sched.npidle.Load()+sched.nmspinning.Load()+1 {
 		return false
 	}
 	if p := getg().m.p.ptr(); !runqempty(p) {
@@ -6278,7 +6463,7 @@
 
 type tracestat struct {
 	active bool   // init tracing activation status
-	id     int64  // init goroutine id
+	id     uint64 // init goroutine id
 	allocs uint64 // heap allocations
 	bytes  uint64 // heap allocated bytes
 }
diff --git a/src/runtime/profbuf.go b/src/runtime/profbuf.go
index 3d907d5..c579f21 100644
--- a/src/runtime/profbuf.go
+++ b/src/runtime/profbuf.go
@@ -87,9 +87,9 @@
 type profBuf struct {
 	// accessed atomically
 	r, w         profAtomic
-	overflow     uint64
-	overflowTime uint64
-	eof          uint32
+	overflow     atomic.Uint64
+	overflowTime atomic.Uint64
+	eof          atomic.Uint32
 
 	// immutable (excluding slice content)
 	hdrsize uintptr
@@ -150,15 +150,15 @@
 
 // hasOverflow reports whether b has any overflow records pending.
 func (b *profBuf) hasOverflow() bool {
-	return uint32(atomic.Load64(&b.overflow)) > 0
+	return uint32(b.overflow.Load()) > 0
 }
 
 // takeOverflow consumes the pending overflow records, returning the overflow count
 // and the time of the first overflow.
 // When called by the reader, it is racing against incrementOverflow.
 func (b *profBuf) takeOverflow() (count uint32, time uint64) {
-	overflow := atomic.Load64(&b.overflow)
-	time = atomic.Load64(&b.overflowTime)
+	overflow := b.overflow.Load()
+	time = b.overflowTime.Load()
 	for {
 		count = uint32(overflow)
 		if count == 0 {
@@ -166,11 +166,11 @@
 			break
 		}
 		// Increment generation, clear overflow count in low bits.
-		if atomic.Cas64(&b.overflow, overflow, ((overflow>>32)+1)<<32) {
+		if b.overflow.CompareAndSwap(overflow, ((overflow>>32)+1)<<32) {
 			break
 		}
-		overflow = atomic.Load64(&b.overflow)
-		time = atomic.Load64(&b.overflowTime)
+		overflow = b.overflow.Load()
+		time = b.overflowTime.Load()
 	}
 	return uint32(overflow), time
 }
@@ -179,14 +179,14 @@
 // It is racing against a possible takeOverflow in the reader.
 func (b *profBuf) incrementOverflow(now int64) {
 	for {
-		overflow := atomic.Load64(&b.overflow)
+		overflow := b.overflow.Load()
 
 		// Once we see b.overflow reach 0, it's stable: no one else is changing it underfoot.
 		// We need to set overflowTime if we're incrementing b.overflow from 0.
 		if uint32(overflow) == 0 {
 			// Store overflowTime first so it's always available when overflow != 0.
-			atomic.Store64(&b.overflowTime, uint64(now))
-			atomic.Store64(&b.overflow, (((overflow>>32)+1)<<32)+1)
+			b.overflowTime.Store(uint64(now))
+			b.overflow.Store((((overflow >> 32) + 1) << 32) + 1)
 			break
 		}
 		// Otherwise we're racing to increment against reader
@@ -196,7 +196,7 @@
 		if int32(overflow) == -1 {
 			break
 		}
-		if atomic.Cas64(&b.overflow, overflow, overflow+1) {
+		if b.overflow.CompareAndSwap(overflow, overflow+1) {
 			break
 		}
 	}
@@ -394,10 +394,10 @@
 // close signals that there will be no more writes on the buffer.
 // Once all the data has been read from the buffer, reads will return eof=true.
 func (b *profBuf) close() {
-	if atomic.Load(&b.eof) > 0 {
+	if b.eof.Load() > 0 {
 		throw("runtime: profBuf already closed")
 	}
-	atomic.Store(&b.eof, 1)
+	b.eof.Store(1)
 	b.wakeupExtra()
 }
 
@@ -475,7 +475,7 @@
 			dst[2+b.hdrsize] = uint64(count)
 			return dst[:2+b.hdrsize+1], overflowTag[:1], false
 		}
-		if atomic.Load(&b.eof) > 0 {
+		if b.eof.Load() > 0 {
 			// No data, no overflow, EOF set: done.
 			return nil, nil, true
 		}
diff --git a/src/runtime/race.go b/src/runtime/race.go
index 4694288..f83a04d 100644
--- a/src/runtime/race.go
+++ b/src/runtime/race.go
@@ -67,21 +67,21 @@
 // Non-synchronization events (memory accesses, function entry/exit) still affect
 // the race detector.
 func RaceDisable() {
-	_g_ := getg()
-	if _g_.raceignore == 0 {
-		racecall(&__tsan_go_ignore_sync_begin, _g_.racectx, 0, 0, 0)
+	gp := getg()
+	if gp.raceignore == 0 {
+		racecall(&__tsan_go_ignore_sync_begin, gp.racectx, 0, 0, 0)
 	}
-	_g_.raceignore++
+	gp.raceignore++
 }
 
 //go:nosplit
 
 // RaceEnable re-enables handling of race events in the current goroutine.
 func RaceEnable() {
-	_g_ := getg()
-	_g_.raceignore--
-	if _g_.raceignore == 0 {
-		racecall(&__tsan_go_ignore_sync_end, _g_.racectx, 0, 0, 0)
+	gp := getg()
+	gp.raceignore--
+	if gp.raceignore == 0 {
+		racecall(&__tsan_go_ignore_sync_end, gp.racectx, 0, 0, 0)
 	}
 }
 
@@ -187,7 +187,7 @@
 							continue
 						}
 						ctx.pc = f.Entry() + uintptr(inltree[ix].parentPc) // "caller" pc
-						ctx.fn = cfuncnameFromNameoff(fi, inltree[ix].func_)
+						ctx.fn = cfuncnameFromNameOff(fi, inltree[ix].nameOff)
 						ctx.line = uintptr(line)
 						ctx.file = &bytes(file)[0] // assume NUL-terminated
 						ctx.off = pc - f.Entry()
@@ -350,7 +350,7 @@
 // with up to 4 uintptr arguments.
 func racecall(fn *byte, arg0, arg1, arg2, arg3 uintptr)
 
-// checks if the address has shadow (i.e. heap or data/bss)
+// checks if the address has shadow (i.e. heap or data/bss).
 //
 //go:nosplit
 func isvalidaddr(addr unsafe.Pointer) bool {
@@ -360,8 +360,8 @@
 
 //go:nosplit
 func raceinit() (gctx, pctx uintptr) {
-	// cgo is required to initialize libc, which is used by race runtime
-	if !iscgo {
+	// On most machines, cgo is required to initialize libc, which is used by race runtime.
+	if !iscgo && GOOS != "darwin" {
 		throw("raceinit: race build must use cgo")
 	}
 
@@ -453,12 +453,12 @@
 
 //go:nosplit
 func racegostart(pc uintptr) uintptr {
-	_g_ := getg()
+	gp := getg()
 	var spawng *g
-	if _g_.m.curg != nil {
-		spawng = _g_.m.curg
+	if gp.m.curg != nil {
+		spawng = gp.m.curg
 	} else {
-		spawng = _g_
+		spawng = gp
 	}
 
 	var racectx uintptr
@@ -478,8 +478,8 @@
 
 //go:nosplit
 func racewriterangepc(addr unsafe.Pointer, sz, callpc, pc uintptr) {
-	_g_ := getg()
-	if _g_ != _g_.m.curg {
+	gp := getg()
+	if gp != gp.m.curg {
 		// The call is coming from manual instrumentation of Go code running on g0/gsignal.
 		// Not interesting.
 		return
@@ -495,8 +495,8 @@
 
 //go:nosplit
 func racereadrangepc(addr unsafe.Pointer, sz, callpc, pc uintptr) {
-	_g_ := getg()
-	if _g_ != _g_.m.curg {
+	gp := getg()
+	if gp != gp.m.curg {
 		// The call is coming from manual instrumentation of Go code running on g0/gsignal.
 		// Not interesting.
 		return
diff --git a/src/runtime/race/README b/src/runtime/race/README
index ad8f55f..596700a 100644
--- a/src/runtime/race/README
+++ b/src/runtime/race/README
@@ -6,7 +6,6 @@
 
 race_darwin_amd64.syso built with LLVM 127e59048cd3d8dbb80c14b3036918c114089529 and Go 59ab6f351a370a27458755dc69f4a837e55a05a6.
 race_freebsd_amd64.syso built with LLVM 127e59048cd3d8dbb80c14b3036918c114089529 and Go 59ab6f351a370a27458755dc69f4a837e55a05a6.
-race_linux_amd64.syso built with LLVM 127e59048cd3d8dbb80c14b3036918c114089529 and Go 59ab6f351a370a27458755dc69f4a837e55a05a6.
 race_linux_ppc64le.syso built with LLVM 41cb504b7c4b18ac15830107431a0c1eec73a6b2 and Go 851ecea4cc99ab276109493477b2c7e30c253ea8.
 race_netbsd_amd64.syso built with LLVM 41cb504b7c4b18ac15830107431a0c1eec73a6b2 and Go 851ecea4cc99ab276109493477b2c7e30c253ea8.
 race_windows_amd64.syso built with LLVM 89f7ccea6f6488c443655880229c54db1f180153 and Go f62d3202bf9dbb3a00ad2a2c63ff4fa4188c5d3b.
@@ -14,3 +13,5 @@
 race_darwin_arm64.syso built with LLVM 41cb504b7c4b18ac15830107431a0c1eec73a6b2 and Go 851ecea4cc99ab276109493477b2c7e30c253ea8.
 race_openbsd_amd64.syso built with LLVM fcf6ae2f070eba73074b6ec8d8281e54d29dbeeb and Go 8f2db14cd35bbd674cb2988a508306de6655e425.
 race_linux_s390x.syso built with LLVM 41cb504b7c4b18ac15830107431a0c1eec73a6b2 and Go 851ecea4cc99ab276109493477b2c7e30c253ea8.
+internal/amd64v3/race_linux.syso built with LLVM 74c2d4f6024c8f160871a2baa928d0b42415f183 and Go c0f27eb3d580c8b9efd73802678eba4c6c9461be.
+internal/amd64v1/race_linux.syso built with LLVM 74c2d4f6024c8f160871a2baa928d0b42415f183 and Go c0f27eb3d580c8b9efd73802678eba4c6c9461be.
diff --git a/src/runtime/race/doc.go b/src/runtime/race/doc.go
index 9e93f66..60a20df 100644
--- a/src/runtime/race/doc.go
+++ b/src/runtime/race/doc.go
@@ -7,3 +7,5 @@
 // For details about the race detector see
 // https://golang.org/doc/articles/race_detector.html
 package race
+
+//go:generate ./mkcgo.sh
diff --git a/src/runtime/race/internal/amd64v1/doc.go b/src/runtime/race/internal/amd64v1/doc.go
new file mode 100644
index 0000000..ccb088c
--- /dev/null
+++ b/src/runtime/race/internal/amd64v1/doc.go
@@ -0,0 +1,10 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This package holds the race detector .syso for
+// amd64 architectures with GOAMD64<v3.
+
+//go:build amd64 && ((linux && !amd64.v3) || darwin || freebsd || netbsd || openbsd || windows)
+
+package amd64v1
diff --git a/src/runtime/race/race_darwin_amd64.syso b/src/runtime/race/internal/amd64v1/race_darwin.syso
similarity index 100%
rename from src/runtime/race/race_darwin_amd64.syso
rename to src/runtime/race/internal/amd64v1/race_darwin.syso
Binary files differ
diff --git a/src/runtime/race/race_freebsd_amd64.syso b/src/runtime/race/internal/amd64v1/race_freebsd.syso
similarity index 100%
rename from src/runtime/race/race_freebsd_amd64.syso
rename to src/runtime/race/internal/amd64v1/race_freebsd.syso
Binary files differ
diff --git a/src/runtime/race/internal/amd64v1/race_linux.syso b/src/runtime/race/internal/amd64v1/race_linux.syso
new file mode 100644
index 0000000..68f1508
--- /dev/null
+++ b/src/runtime/race/internal/amd64v1/race_linux.syso
Binary files differ
diff --git a/src/runtime/race/race_netbsd_amd64.syso b/src/runtime/race/internal/amd64v1/race_netbsd.syso
similarity index 100%
rename from src/runtime/race/race_netbsd_amd64.syso
rename to src/runtime/race/internal/amd64v1/race_netbsd.syso
Binary files differ
diff --git a/src/runtime/race/race_openbsd_amd64.syso b/src/runtime/race/internal/amd64v1/race_openbsd.syso
similarity index 100%
rename from src/runtime/race/race_openbsd_amd64.syso
rename to src/runtime/race/internal/amd64v1/race_openbsd.syso
Binary files differ
diff --git a/src/runtime/race/race_windows_amd64.syso b/src/runtime/race/internal/amd64v1/race_windows.syso
similarity index 100%
rename from src/runtime/race/race_windows_amd64.syso
rename to src/runtime/race/internal/amd64v1/race_windows.syso
Binary files differ
diff --git a/src/runtime/race/internal/amd64v3/doc.go b/src/runtime/race/internal/amd64v3/doc.go
new file mode 100644
index 0000000..215998a
--- /dev/null
+++ b/src/runtime/race/internal/amd64v3/doc.go
@@ -0,0 +1,10 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This package holds the race detector .syso for
+// amd64 architectures with GOAMD64>=v3.
+
+//go:build amd64 && linux && amd64.v3
+
+package amd64v3
diff --git a/src/runtime/race/internal/amd64v3/race_linux.syso b/src/runtime/race/internal/amd64v3/race_linux.syso
new file mode 100644
index 0000000..33c3e76
--- /dev/null
+++ b/src/runtime/race/internal/amd64v3/race_linux.syso
Binary files differ
diff --git a/src/runtime/race/mkcgo.sh b/src/runtime/race/mkcgo.sh
new file mode 100755
index 0000000..6ebe5a4
--- /dev/null
+++ b/src/runtime/race/mkcgo.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+hdr='
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Code generated by mkcgo.sh. DO NOT EDIT.
+
+//go:build race
+
+'
+
+convert() {
+	(echo "$hdr"; go tool cgo -dynpackage race -dynimport $1) | gofmt
+}
+
+convert race_darwin_arm64.syso >race_darwin_arm64.go
+convert internal/amd64v1/race_darwin.syso >race_darwin_amd64.go
+
diff --git a/src/runtime/race/race.go b/src/runtime/race/race.go
index 8692066..9c508eb 100644
--- a/src/runtime/race/race.go
+++ b/src/runtime/race/race.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build (race && linux && amd64) || (race && freebsd && amd64) || (race && netbsd && amd64) || (race && darwin && amd64) || (race && windows && amd64) || (race && linux && ppc64le) || (race && linux && arm64) || (race && darwin && arm64) || (race && openbsd && amd64) || (race && linux && s390x)
+//go:build race && ((linux && (amd64 || arm64 || ppc64le || s390x)) || ((freebsd || netbsd || openbsd || windows) && amd64))
 
 package race
 
@@ -11,5 +11,10 @@
 // The prebuilt race runtime lives in race_GOOS_GOARCH.syso.
 // Calls to the runtime are done directly from src/runtime/race.go.
 
+// On darwin we always use system DLLs to create threads,
+// so we use race_darwin_$GOARCH.go to provide the syso-derived
+// symbol information without needing to invoke cgo.
+// This allows -race to be used on Mac systems without a C toolchain.
+
 // void __race_unused_func(void);
 import "C"
diff --git a/src/runtime/race/race_darwin_amd64.go b/src/runtime/race/race_darwin_amd64.go
new file mode 100644
index 0000000..fbb838a
--- /dev/null
+++ b/src/runtime/race/race_darwin_amd64.go
@@ -0,0 +1,101 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Code generated by mkcgo.sh. DO NOT EDIT.
+
+//go:build race
+
+package race
+
+//go:cgo_import_dynamic _Block_object_assign _Block_object_assign ""
+//go:cgo_import_dynamic _Block_object_dispose _Block_object_dispose ""
+//go:cgo_import_dynamic _NSConcreteStackBlock _NSConcreteStackBlock ""
+//go:cgo_import_dynamic _NSGetArgv _NSGetArgv ""
+//go:cgo_import_dynamic _NSGetEnviron _NSGetEnviron ""
+//go:cgo_import_dynamic _NSGetExecutablePath _NSGetExecutablePath ""
+//go:cgo_import_dynamic __bzero __bzero ""
+//go:cgo_import_dynamic __error __error ""
+//go:cgo_import_dynamic __fork __fork ""
+//go:cgo_import_dynamic __mmap __mmap ""
+//go:cgo_import_dynamic __munmap __munmap ""
+//go:cgo_import_dynamic __stack_chk_fail __stack_chk_fail ""
+//go:cgo_import_dynamic __stack_chk_guard __stack_chk_guard ""
+//go:cgo_import_dynamic _dyld_get_image_header _dyld_get_image_header ""
+//go:cgo_import_dynamic _dyld_get_image_name _dyld_get_image_name ""
+//go:cgo_import_dynamic _dyld_get_image_vmaddr_slide _dyld_get_image_vmaddr_slide ""
+//go:cgo_import_dynamic _dyld_get_shared_cache_range _dyld_get_shared_cache_range ""
+//go:cgo_import_dynamic _dyld_get_shared_cache_uuid _dyld_get_shared_cache_uuid ""
+//go:cgo_import_dynamic _dyld_image_count _dyld_image_count ""
+//go:cgo_import_dynamic _exit _exit ""
+//go:cgo_import_dynamic abort abort ""
+//go:cgo_import_dynamic arc4random_buf arc4random_buf ""
+//go:cgo_import_dynamic close close ""
+//go:cgo_import_dynamic dlsym dlsym ""
+//go:cgo_import_dynamic dup dup ""
+//go:cgo_import_dynamic dup2 dup2 ""
+//go:cgo_import_dynamic dyld_shared_cache_iterate_text dyld_shared_cache_iterate_text ""
+//go:cgo_import_dynamic execve execve ""
+//go:cgo_import_dynamic exit exit ""
+//go:cgo_import_dynamic fstat$INODE64 fstat$INODE64 ""
+//go:cgo_import_dynamic ftruncate ftruncate ""
+//go:cgo_import_dynamic getpid getpid ""
+//go:cgo_import_dynamic getrlimit getrlimit ""
+//go:cgo_import_dynamic gettimeofday gettimeofday ""
+//go:cgo_import_dynamic getuid getuid ""
+//go:cgo_import_dynamic grantpt grantpt ""
+//go:cgo_import_dynamic ioctl ioctl ""
+//go:cgo_import_dynamic isatty isatty ""
+//go:cgo_import_dynamic lstat$INODE64 lstat$INODE64 ""
+//go:cgo_import_dynamic mach_absolute_time mach_absolute_time ""
+//go:cgo_import_dynamic mach_task_self_ mach_task_self_ ""
+//go:cgo_import_dynamic mach_timebase_info mach_timebase_info ""
+//go:cgo_import_dynamic mach_vm_region_recurse mach_vm_region_recurse ""
+//go:cgo_import_dynamic madvise madvise ""
+//go:cgo_import_dynamic malloc_num_zones malloc_num_zones ""
+//go:cgo_import_dynamic malloc_zones malloc_zones ""
+//go:cgo_import_dynamic memcpy memcpy ""
+//go:cgo_import_dynamic memset_pattern16 memset_pattern16 ""
+//go:cgo_import_dynamic mkdir mkdir ""
+//go:cgo_import_dynamic mprotect mprotect ""
+//go:cgo_import_dynamic open open ""
+//go:cgo_import_dynamic pipe pipe ""
+//go:cgo_import_dynamic posix_openpt posix_openpt ""
+//go:cgo_import_dynamic posix_spawn posix_spawn ""
+//go:cgo_import_dynamic posix_spawn_file_actions_addclose posix_spawn_file_actions_addclose ""
+//go:cgo_import_dynamic posix_spawn_file_actions_adddup2 posix_spawn_file_actions_adddup2 ""
+//go:cgo_import_dynamic posix_spawn_file_actions_destroy posix_spawn_file_actions_destroy ""
+//go:cgo_import_dynamic posix_spawn_file_actions_init posix_spawn_file_actions_init ""
+//go:cgo_import_dynamic posix_spawnattr_destroy posix_spawnattr_destroy ""
+//go:cgo_import_dynamic posix_spawnattr_init posix_spawnattr_init ""
+//go:cgo_import_dynamic posix_spawnattr_setflags posix_spawnattr_setflags ""
+//go:cgo_import_dynamic pthread_attr_getstack pthread_attr_getstack ""
+//go:cgo_import_dynamic pthread_create pthread_create ""
+//go:cgo_import_dynamic pthread_get_stackaddr_np pthread_get_stackaddr_np ""
+//go:cgo_import_dynamic pthread_get_stacksize_np pthread_get_stacksize_np ""
+//go:cgo_import_dynamic pthread_getspecific pthread_getspecific ""
+//go:cgo_import_dynamic pthread_join pthread_join ""
+//go:cgo_import_dynamic pthread_self pthread_self ""
+//go:cgo_import_dynamic pthread_sigmask pthread_sigmask ""
+//go:cgo_import_dynamic pthread_threadid_np pthread_threadid_np ""
+//go:cgo_import_dynamic read read ""
+//go:cgo_import_dynamic readlink readlink ""
+//go:cgo_import_dynamic realpath$DARWIN_EXTSN realpath$DARWIN_EXTSN ""
+//go:cgo_import_dynamic rename rename ""
+//go:cgo_import_dynamic sched_yield sched_yield ""
+//go:cgo_import_dynamic setrlimit setrlimit ""
+//go:cgo_import_dynamic sigaction sigaction ""
+//go:cgo_import_dynamic stat$INODE64 stat$INODE64 ""
+//go:cgo_import_dynamic sysconf sysconf ""
+//go:cgo_import_dynamic sysctl sysctl ""
+//go:cgo_import_dynamic sysctlbyname sysctlbyname ""
+//go:cgo_import_dynamic task_info task_info ""
+//go:cgo_import_dynamic tcgetattr tcgetattr ""
+//go:cgo_import_dynamic tcsetattr tcsetattr ""
+//go:cgo_import_dynamic unlink unlink ""
+//go:cgo_import_dynamic unlockpt unlockpt ""
+//go:cgo_import_dynamic usleep usleep ""
+//go:cgo_import_dynamic vm_region_64 vm_region_64 ""
+//go:cgo_import_dynamic vm_region_recurse_64 vm_region_recurse_64 ""
+//go:cgo_import_dynamic waitpid waitpid ""
+//go:cgo_import_dynamic write write ""
diff --git a/src/runtime/race/race_darwin_arm64.go b/src/runtime/race/race_darwin_arm64.go
new file mode 100644
index 0000000..fe8584c
--- /dev/null
+++ b/src/runtime/race/race_darwin_arm64.go
@@ -0,0 +1,95 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Code generated by mkcgo.sh. DO NOT EDIT.
+
+//go:build race
+
+package race
+
+//go:cgo_import_dynamic _NSGetArgv _NSGetArgv ""
+//go:cgo_import_dynamic _NSGetEnviron _NSGetEnviron ""
+//go:cgo_import_dynamic _NSGetExecutablePath _NSGetExecutablePath ""
+//go:cgo_import_dynamic __error __error ""
+//go:cgo_import_dynamic __fork __fork ""
+//go:cgo_import_dynamic __mmap __mmap ""
+//go:cgo_import_dynamic __munmap __munmap ""
+//go:cgo_import_dynamic __stack_chk_fail __stack_chk_fail ""
+//go:cgo_import_dynamic __stack_chk_guard __stack_chk_guard ""
+//go:cgo_import_dynamic _dyld_get_image_header _dyld_get_image_header ""
+//go:cgo_import_dynamic _dyld_get_image_name _dyld_get_image_name ""
+//go:cgo_import_dynamic _dyld_get_image_vmaddr_slide _dyld_get_image_vmaddr_slide ""
+//go:cgo_import_dynamic _dyld_image_count _dyld_image_count ""
+//go:cgo_import_dynamic _exit _exit ""
+//go:cgo_import_dynamic abort abort ""
+//go:cgo_import_dynamic arc4random_buf arc4random_buf ""
+//go:cgo_import_dynamic bzero bzero ""
+//go:cgo_import_dynamic close close ""
+//go:cgo_import_dynamic dlsym dlsym ""
+//go:cgo_import_dynamic dup dup ""
+//go:cgo_import_dynamic dup2 dup2 ""
+//go:cgo_import_dynamic execve execve ""
+//go:cgo_import_dynamic exit exit ""
+//go:cgo_import_dynamic fstat fstat ""
+//go:cgo_import_dynamic ftruncate ftruncate ""
+//go:cgo_import_dynamic getpid getpid ""
+//go:cgo_import_dynamic getrlimit getrlimit ""
+//go:cgo_import_dynamic gettimeofday gettimeofday ""
+//go:cgo_import_dynamic getuid getuid ""
+//go:cgo_import_dynamic grantpt grantpt ""
+//go:cgo_import_dynamic ioctl ioctl ""
+//go:cgo_import_dynamic isatty isatty ""
+//go:cgo_import_dynamic lstat lstat ""
+//go:cgo_import_dynamic mach_absolute_time mach_absolute_time ""
+//go:cgo_import_dynamic mach_task_self_ mach_task_self_ ""
+//go:cgo_import_dynamic mach_timebase_info mach_timebase_info ""
+//go:cgo_import_dynamic mach_vm_region_recurse mach_vm_region_recurse ""
+//go:cgo_import_dynamic madvise madvise ""
+//go:cgo_import_dynamic malloc_num_zones malloc_num_zones ""
+//go:cgo_import_dynamic malloc_zones malloc_zones ""
+//go:cgo_import_dynamic memcpy memcpy ""
+//go:cgo_import_dynamic memset_pattern16 memset_pattern16 ""
+//go:cgo_import_dynamic mkdir mkdir ""
+//go:cgo_import_dynamic mprotect mprotect ""
+//go:cgo_import_dynamic open open ""
+//go:cgo_import_dynamic pipe pipe ""
+//go:cgo_import_dynamic posix_openpt posix_openpt ""
+//go:cgo_import_dynamic posix_spawn posix_spawn ""
+//go:cgo_import_dynamic posix_spawn_file_actions_addclose posix_spawn_file_actions_addclose ""
+//go:cgo_import_dynamic posix_spawn_file_actions_adddup2 posix_spawn_file_actions_adddup2 ""
+//go:cgo_import_dynamic posix_spawn_file_actions_destroy posix_spawn_file_actions_destroy ""
+//go:cgo_import_dynamic posix_spawn_file_actions_init posix_spawn_file_actions_init ""
+//go:cgo_import_dynamic posix_spawnattr_destroy posix_spawnattr_destroy ""
+//go:cgo_import_dynamic posix_spawnattr_init posix_spawnattr_init ""
+//go:cgo_import_dynamic posix_spawnattr_setflags posix_spawnattr_setflags ""
+//go:cgo_import_dynamic pthread_attr_getstack pthread_attr_getstack ""
+//go:cgo_import_dynamic pthread_create pthread_create ""
+//go:cgo_import_dynamic pthread_get_stackaddr_np pthread_get_stackaddr_np ""
+//go:cgo_import_dynamic pthread_get_stacksize_np pthread_get_stacksize_np ""
+//go:cgo_import_dynamic pthread_getspecific pthread_getspecific ""
+//go:cgo_import_dynamic pthread_join pthread_join ""
+//go:cgo_import_dynamic pthread_self pthread_self ""
+//go:cgo_import_dynamic pthread_sigmask pthread_sigmask ""
+//go:cgo_import_dynamic pthread_threadid_np pthread_threadid_np ""
+//go:cgo_import_dynamic read read ""
+//go:cgo_import_dynamic readlink readlink ""
+//go:cgo_import_dynamic realpath$DARWIN_EXTSN realpath$DARWIN_EXTSN ""
+//go:cgo_import_dynamic rename rename ""
+//go:cgo_import_dynamic sched_yield sched_yield ""
+//go:cgo_import_dynamic setrlimit setrlimit ""
+//go:cgo_import_dynamic sigaction sigaction ""
+//go:cgo_import_dynamic stat stat ""
+//go:cgo_import_dynamic sysconf sysconf ""
+//go:cgo_import_dynamic sysctl sysctl ""
+//go:cgo_import_dynamic sysctlbyname sysctlbyname ""
+//go:cgo_import_dynamic task_info task_info ""
+//go:cgo_import_dynamic tcgetattr tcgetattr ""
+//go:cgo_import_dynamic tcsetattr tcsetattr ""
+//go:cgo_import_dynamic unlink unlink ""
+//go:cgo_import_dynamic unlockpt unlockpt ""
+//go:cgo_import_dynamic usleep usleep ""
+//go:cgo_import_dynamic vm_region_64 vm_region_64 ""
+//go:cgo_import_dynamic vm_region_recurse_64 vm_region_recurse_64 ""
+//go:cgo_import_dynamic waitpid waitpid ""
+//go:cgo_import_dynamic write write ""
diff --git a/src/runtime/race/race_linux_amd64.syso b/src/runtime/race/race_linux_amd64.syso
deleted file mode 100644
index 6885610..0000000
--- a/src/runtime/race/race_linux_amd64.syso
+++ /dev/null
Binary files differ
diff --git a/src/runtime/race/race_unix_test.go b/src/runtime/race/race_unix_test.go
index 6cc0730..3cf53b0 100644
--- a/src/runtime/race/race_unix_test.go
+++ b/src/runtime/race/race_unix_test.go
@@ -19,11 +19,11 @@
 	if err != nil {
 		t.Fatalf("failed to mmap memory: %v", err)
 	}
+	defer syscall.Munmap(data)
 	p := (*uint32)(unsafe.Pointer(&data[0]))
 	atomic.AddUint32(p, 1)
 	(*p)++
 	if *p != 2 {
 		t.Fatalf("data[0] = %v, expect 2", *p)
 	}
-	syscall.Munmap(data)
 }
diff --git a/src/runtime/race/race_v1_amd64.go b/src/runtime/race/race_v1_amd64.go
new file mode 100644
index 0000000..7c40db1
--- /dev/null
+++ b/src/runtime/race/race_v1_amd64.go
@@ -0,0 +1,9 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build (linux && !amd64.v3) || darwin || freebsd || netbsd || openbsd || windows
+
+package race
+
+import _ "runtime/race/internal/amd64v1"
diff --git a/src/runtime/race/race_v3_amd64.go b/src/runtime/race/race_v3_amd64.go
new file mode 100644
index 0000000..80728d8
--- /dev/null
+++ b/src/runtime/race/race_v3_amd64.go
@@ -0,0 +1,9 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build linux && amd64.v3
+
+package race
+
+import _ "runtime/race/internal/amd64v3"
diff --git a/src/runtime/race/sched_test.go b/src/runtime/race/sched_test.go
index 9fe83ea..a66860c 100644
--- a/src/runtime/race/sched_test.go
+++ b/src/runtime/race/sched_test.go
@@ -7,10 +7,10 @@
 package race_test
 
 import (
-	"bytes"
 	"fmt"
 	"reflect"
 	"runtime"
+	"strings"
 	"testing"
 )
 
@@ -40,7 +40,7 @@
 		}
 	}
 
-	var buf bytes.Buffer
+	var buf strings.Builder
 	for i := 0; i < N; i++ {
 		fmt.Fprintf(&buf, "%v\n", out[i])
 	}
diff --git a/src/runtime/rdebug.go b/src/runtime/rdebug.go
index 1b213f1..7ecb2a5 100644
--- a/src/runtime/rdebug.go
+++ b/src/runtime/rdebug.go
@@ -15,8 +15,8 @@
 
 //go:linkname setPanicOnFault runtime/debug.setPanicOnFault
 func setPanicOnFault(new bool) (old bool) {
-	_g_ := getg()
-	old = _g_.paniconfault
-	_g_.paniconfault = new
+	gp := getg()
+	old = gp.paniconfault
+	gp.paniconfault = new
 	return old
 }
diff --git a/src/runtime/retry.go b/src/runtime/retry.go
new file mode 100644
index 0000000..2e2f813
--- /dev/null
+++ b/src/runtime/retry.go
@@ -0,0 +1,23 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build unix
+
+package runtime
+
+// retryOnEAGAIN retries a function until it does not return EAGAIN.
+// It will use an increasing delay between calls, and retry up to 20 times.
+// The function argument is expected to return an errno value,
+// and retryOnEAGAIN will return any errno value other than EAGAIN.
+// If all retries return EAGAIN, then retryOnEAGAIN will return EAGAIN.
+func retryOnEAGAIN(fn func() int32) int32 {
+	for tries := 0; tries < 20; tries++ {
+		errno := fn()
+		if errno != _EAGAIN {
+			return errno
+		}
+		usleep_no_g(uint32(tries+1) * 1000) // milliseconds
+	}
+	return _EAGAIN
+}
diff --git a/src/runtime/rt0_freebsd_riscv64.s b/src/runtime/rt0_freebsd_riscv64.s
new file mode 100644
index 0000000..dc46b70
--- /dev/null
+++ b/src/runtime/rt0_freebsd_riscv64.s
@@ -0,0 +1,112 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+// On FreeBSD argc/argv are passed in R0, not X2
+TEXT _rt0_riscv64_freebsd(SB),NOSPLIT|NOFRAME,$0
+	ADD	$8, A0, A1	// argv
+	MOV	0(A0), A0	// argc
+	JMP	main(SB)
+
+// When building with -buildmode=c-shared, this symbol is called when the shared
+// library is loaded.
+TEXT _rt0_riscv64_freebsd_lib(SB),NOSPLIT,$224
+	// Preserve callee-save registers, along with X1 (LR).
+	MOV	X1, (8*3)(X2)
+	MOV	X8, (8*4)(X2)
+	MOV	X9, (8*5)(X2)
+	MOV	X18, (8*6)(X2)
+	MOV	X19, (8*7)(X2)
+	MOV	X20, (8*8)(X2)
+	MOV	X21, (8*9)(X2)
+	MOV	X22, (8*10)(X2)
+	MOV	X23, (8*11)(X2)
+	MOV	X24, (8*12)(X2)
+	MOV	X25, (8*13)(X2)
+	MOV	X26, (8*14)(X2)
+	MOV	g, (8*15)(X2)
+	MOVD	F8, (8*16)(X2)
+	MOVD	F9, (8*17)(X2)
+	MOVD	F18, (8*18)(X2)
+	MOVD	F19, (8*19)(X2)
+	MOVD	F20, (8*20)(X2)
+	MOVD	F21, (8*21)(X2)
+	MOVD	F22, (8*22)(X2)
+	MOVD	F23, (8*23)(X2)
+	MOVD	F24, (8*24)(X2)
+	MOVD	F25, (8*25)(X2)
+	MOVD	F26, (8*26)(X2)
+	MOVD	F27, (8*27)(X2)
+
+	// Initialize g as nil in case of using g later e.g. sigaction in cgo_sigaction.go
+	MOV	X0, g
+
+	MOV	A0, _rt0_riscv64_freebsd_lib_argc<>(SB)
+	MOV	A1, _rt0_riscv64_freebsd_lib_argv<>(SB)
+
+	// Synchronous initialization.
+	MOV	$runtime·libpreinit(SB), T0
+	JALR	RA, T0
+
+	// Create a new thread to do the runtime initialization and return.
+	MOV	_cgo_sys_thread_create(SB), T0
+	BEQZ	T0, nocgo
+	MOV	$_rt0_riscv64_freebsd_lib_go(SB), A0
+	MOV	$0, A1
+	JALR	RA, T0
+	JMP	restore
+
+nocgo:
+	MOV	$0x800000, A0                     // stacksize = 8192KB
+	MOV	$_rt0_riscv64_freebsd_lib_go(SB), A1
+	MOV	A0, 8(X2)
+	MOV	A1, 16(X2)
+	MOV	$runtime·newosproc0(SB), T0
+	JALR	RA, T0
+
+restore:
+	// Restore callee-save registers, along with X1 (LR).
+	MOV	(8*3)(X2), X1
+	MOV	(8*4)(X2), X8
+	MOV	(8*5)(X2), X9
+	MOV	(8*6)(X2), X18
+	MOV	(8*7)(X2), X19
+	MOV	(8*8)(X2), X20
+	MOV	(8*9)(X2), X21
+	MOV	(8*10)(X2), X22
+	MOV	(8*11)(X2), X23
+	MOV	(8*12)(X2), X24
+	MOV	(8*13)(X2), X25
+	MOV	(8*14)(X2), X26
+	MOV	(8*15)(X2), g
+	MOVD	(8*16)(X2), F8
+	MOVD	(8*17)(X2), F9
+	MOVD	(8*18)(X2), F18
+	MOVD	(8*19)(X2), F19
+	MOVD	(8*20)(X2), F20
+	MOVD	(8*21)(X2), F21
+	MOVD	(8*22)(X2), F22
+	MOVD	(8*23)(X2), F23
+	MOVD	(8*24)(X2), F24
+	MOVD	(8*25)(X2), F25
+	MOVD	(8*26)(X2), F26
+	MOVD	(8*27)(X2), F27
+
+	RET
+
+TEXT _rt0_riscv64_freebsd_lib_go(SB),NOSPLIT,$0
+	MOV	_rt0_riscv64_freebsd_lib_argc<>(SB), A0
+	MOV	_rt0_riscv64_freebsd_lib_argv<>(SB), A1
+	MOV	$runtime·rt0_go(SB), T0
+	JALR	ZERO, T0
+
+DATA _rt0_riscv64_freebsd_lib_argc<>(SB)/8, $0
+GLOBL _rt0_riscv64_freebsd_lib_argc<>(SB),NOPTR, $8
+DATA _rt0_riscv64_freebsd_lib_argv<>(SB)/8, $0
+GLOBL _rt0_riscv64_freebsd_lib_argv<>(SB),NOPTR, $8
+
+TEXT main(SB),NOSPLIT|NOFRAME,$0
+	MOV	$runtime·rt0_go(SB), T0
+	JALR	ZERO, T0
diff --git a/src/runtime/rt0_linux_ppc64.s b/src/runtime/rt0_linux_ppc64.s
index 897d610..c9300a9 100644
--- a/src/runtime/rt0_linux_ppc64.s
+++ b/src/runtime/rt0_linux_ppc64.s
@@ -22,6 +22,7 @@
 	// There is no TLS base pointer.
 	//
 	// TODO(austin): Support ABI v1 dynamic linking entry point
+	XOR	R0, R0 // Note, newer kernels may not always set R0 to 0.
 	MOVD	$runtime·rt0_go(SB), R12
 	MOVD	R12, CTR
 	MOVBZ	runtime·iscgo(SB), R5
diff --git a/src/runtime/runtime-gdb.py b/src/runtime/runtime-gdb.py
index 5bb605c..c4462de 100644
--- a/src/runtime/runtime-gdb.py
+++ b/src/runtime/runtime-gdb.py
@@ -447,7 +447,7 @@
 		# args = gdb.string_to_argv(arg)
 		vp = gdb.lookup_type('void').pointer()
 		for ptr in SliceValue(gdb.parse_and_eval("'runtime.allgs'")):
-			if ptr['atomicstatus'] == G_DEAD:
+			if ptr['atomicstatus']['value'] == G_DEAD:
 				continue
 			s = ' '
 			if ptr['m']:
@@ -455,7 +455,7 @@
 			pc = ptr['sched']['pc'].cast(vp)
 			pc = pc_to_int(pc)
 			blk = gdb.block_for_pc(pc)
-			status = int(ptr['atomicstatus'])
+			status = int(ptr['atomicstatus']['value'])
 			st = sts.get(status, "unknown(%d)" % status)
 			print(s, ptr['goid'], "{0:8s}".format(st), blk.function)
 
@@ -472,7 +472,7 @@
 	"""
 	vp = gdb.lookup_type('void').pointer()
 	for ptr in SliceValue(gdb.parse_and_eval("'runtime.allgs'")):
-		if ptr['atomicstatus'] == G_DEAD:
+		if ptr['atomicstatus']['value'] == G_DEAD:
 			continue
 		if ptr['goid'] == goid:
 			break
@@ -480,7 +480,7 @@
 		return None, None
 	# Get the goroutine's saved state.
 	pc, sp = ptr['sched']['pc'], ptr['sched']['sp']
-	status = ptr['atomicstatus']&~G_SCAN
+	status = ptr['atomicstatus']['value']&~G_SCAN
 	# Goroutine is not running nor in syscall, so use the info in goroutine
 	if status != G_RUNNING and status != G_SYSCALL:
 		return pc.cast(vp), sp.cast(vp)
diff --git a/src/runtime/runtime-gdb_test.go b/src/runtime/runtime-gdb_test.go
index d97c2a2..4e7c227 100644
--- a/src/runtime/runtime-gdb_test.go
+++ b/src/runtime/runtime-gdb_test.go
@@ -6,6 +6,7 @@
 
 import (
 	"bytes"
+	"flag"
 	"fmt"
 	"internal/testenv"
 	"os"
@@ -16,6 +17,7 @@
 	"strconv"
 	"strings"
 	"testing"
+	"time"
 )
 
 // NOTE: In some configurations, GDB will segfault when sent a SIGWINCH signal.
@@ -40,6 +42,10 @@
 		if runtime.GOARCH == "mips" {
 			t.Skip("skipping gdb tests on linux/mips; see https://golang.org/issue/25939")
 		}
+		// Disable GDB tests on alpine until issue #54352 resolved.
+		if strings.HasSuffix(testenv.Builder(), "-alpine") {
+			t.Skip("skipping gdb tests on alpine; see https://golang.org/issue/54352")
+		}
 	case "freebsd":
 		t.Skip("skipping gdb tests on FreeBSD; see https://golang.org/issue/29508")
 	case "aix":
@@ -394,6 +400,15 @@
 	if runtime.GOOS == "netbsd" {
 		testenv.SkipFlaky(t, 15603)
 	}
+	if flag.Lookup("test.parallel").Value.(flag.Getter).Get().(int) < 2 {
+		// It is possible that this test will hang for a long time due to an
+		// apparent GDB bug reported in https://go.dev/issue/37405.
+		// If test parallelism is high enough, that might be ok: the other parallel
+		// tests will finish, and then this test will finish right before it would
+		// time out. However, if test are running sequentially, a hang in this test
+		// would likely cause the remaining tests to run out of time.
+		testenv.SkipFlaky(t, 37405)
+	}
 
 	checkGdbEnvironment(t)
 	t.Parallel()
@@ -415,6 +430,7 @@
 	}
 
 	// Execute gdb commands.
+	start := time.Now()
 	args := []string{"-nx", "-batch",
 		"-iex", "add-auto-load-safe-path " + filepath.Join(testenv.GOROOT(t), "src", "runtime"),
 		"-ex", "set startup-with-shell off",
@@ -424,7 +440,32 @@
 		"-ex", "continue",
 		filepath.Join(dir, "a.exe"),
 	}
-	got, err := testenv.RunWithTimeout(t, exec.Command("gdb", args...))
+	cmd = testenv.Command(t, "gdb", args...)
+
+	// Work around the GDB hang reported in https://go.dev/issue/37405.
+	// Sometimes (rarely), the GDB process hangs completely when the Go program
+	// exits, and we suspect that the bug is on the GDB side.
+	//
+	// The default Cancel function added by testenv.Command will mark the test as
+	// failed if it is in danger of timing out, but we want to instead mark it as
+	// skipped. Change the Cancel function to kill the process and merely log
+	// instead of failing the test.
+	//
+	// (This approach does not scale: if the test parallelism is less than or
+	// equal to the number of tests that run right up to the deadline, then the
+	// remaining parallel tests are likely to time out. But as long as it's just
+	// this one flaky test, it's probably fine..?)
+	//
+	// If there is no deadline set on the test at all, relying on the timeout set
+	// by testenv.Command will cause the test to hang indefinitely, but that's
+	// what “no deadline” means, after all — and it's probably the right behavior
+	// anyway if someone is trying to investigate and fix the GDB bug.
+	cmd.Cancel = func() error {
+		t.Logf("GDB command timed out after %v: %v", time.Since(start), cmd)
+		return cmd.Process.Kill()
+	}
+
+	got, err := cmd.CombinedOutput()
 	t.Logf("gdb output:\n%s", got)
 	if err != nil {
 		if bytes.Contains(got, []byte("internal-error: wait returned unexpected status 0x0")) {
diff --git a/src/runtime/runtime.go b/src/runtime/runtime.go
index 2cf93ab..9f68738 100644
--- a/src/runtime/runtime.go
+++ b/src/runtime/runtime.go
@@ -6,29 +6,29 @@
 
 import (
 	"runtime/internal/atomic"
-	_ "unsafe" // for go:linkname
+	"unsafe"
 )
 
 //go:generate go run wincallback.go
 //go:generate go run mkduff.go
 //go:generate go run mkfastlog2table.go
+//go:generate go run mklockrank.go -o lockrank.go
 
 var ticks ticksType
 
 type ticksType struct {
 	lock mutex
-	pad  uint32 // ensure 8-byte alignment of val on 386
-	val  uint64
+	val  atomic.Int64
 }
 
 // Note: Called by runtime/pprof in addition to runtime code.
 func tickspersecond() int64 {
-	r := int64(atomic.Load64(&ticks.val))
+	r := ticks.val.Load()
 	if r != 0 {
 		return r
 	}
 	lock(&ticks.lock)
-	r = int64(ticks.val)
+	r = ticks.val.Load()
 	if r == 0 {
 		t0 := nanotime()
 		c0 := cputicks()
@@ -42,7 +42,7 @@
 		if r == 0 {
 			r++
 		}
-		atomic.Store64(&ticks.val, uint64(r))
+		ticks.val.Store(r)
 	}
 	unlock(&ticks.lock)
 	return r
@@ -65,3 +65,52 @@
 func syscall_Exit(code int) {
 	exit(int32(code))
 }
+
+var godebugDefault string
+var godebugUpdate atomic.Pointer[func(string, string)]
+var godebugEnv atomic.Pointer[string] // set by parsedebugvars
+
+//go:linkname godebug_setUpdate internal/godebug.setUpdate
+func godebug_setUpdate(update func(string, string)) {
+	p := new(func(string, string))
+	*p = update
+	godebugUpdate.Store(p)
+	godebugNotify()
+}
+
+func godebugNotify() {
+	if update := godebugUpdate.Load(); update != nil {
+		var env string
+		if p := godebugEnv.Load(); p != nil {
+			env = *p
+		}
+		(*update)(godebugDefault, env)
+	}
+}
+
+//go:linkname syscall_runtimeSetenv syscall.runtimeSetenv
+func syscall_runtimeSetenv(key, value string) {
+	setenv_c(key, value)
+	if key == "GODEBUG" {
+		p := new(string)
+		*p = value
+		godebugEnv.Store(p)
+		godebugNotify()
+	}
+}
+
+//go:linkname syscall_runtimeUnsetenv syscall.runtimeUnsetenv
+func syscall_runtimeUnsetenv(key string) {
+	unsetenv_c(key)
+	if key == "GODEBUG" {
+		godebugEnv.Store(nil)
+		godebugNotify()
+	}
+}
+
+// writeErrStr writes a string to descriptor 2.
+//
+//go:nosplit
+func writeErrStr(s string) {
+	write(2, unsafe.Pointer(unsafe.StringData(s)), int32(len(s)))
+}
diff --git a/src/runtime/runtime1.go b/src/runtime/runtime1.go
index e307901..277f18a 100644
--- a/src/runtime/runtime1.go
+++ b/src/runtime/runtime1.go
@@ -35,13 +35,13 @@
 //
 //go:nosplit
 func gotraceback() (level int32, all, crash bool) {
-	_g_ := getg()
+	gp := getg()
 	t := atomic.Load(&traceback_cache)
 	crash = t&tracebackCrash != 0
-	all = _g_.m.throwing >= throwTypeUser || t&tracebackAll != 0
-	if _g_.m.traceback != 0 {
-		level = int32(_g_.m.traceback)
-	} else if _g_.m.throwing >= throwTypeRuntime {
+	all = gp.m.throwing >= throwTypeUser || t&tracebackAll != 0
+	if gp.m.traceback != 0 {
+		level = int32(gp.m.traceback)
+	} else if gp.m.throwing >= throwTypeRuntime {
 		// Always include runtime frames in runtime throws unless
 		// otherwise overridden by m.traceback.
 		level = 2
@@ -56,7 +56,7 @@
 	argv **byte
 )
 
-// nosplit for use in linux startup sysargs
+// nosplit for use in linux startup sysargs.
 //
 //go:nosplit
 func argv_index(argv **byte, i int32) *byte {
@@ -355,6 +355,8 @@
 	{"adaptivestackstart", &debug.adaptivestackstart},
 }
 
+var globalGODEBUG string
+
 func parsedebugvars() {
 	// defaults
 	debug.cgocheck = 1
@@ -372,7 +374,9 @@
 		debug.madvdontneed = 1
 	}
 
-	for p := gogetenv("GODEBUG"); p != ""; {
+	globalGODEBUG = gogetenv("GODEBUG")
+	godebugEnv.StoreNoWB(&globalGODEBUG)
+	for p := globalGODEBUG; p != ""; {
 		field := ""
 		i := bytealg.IndexByteString(p, ',')
 		if i < 0 {
@@ -474,18 +478,18 @@
 
 //go:nosplit
 func acquirem() *m {
-	_g_ := getg()
-	_g_.m.locks++
-	return _g_.m
+	gp := getg()
+	gp.m.locks++
+	return gp.m
 }
 
 //go:nosplit
 func releasem(mp *m) {
-	_g_ := getg()
+	gp := getg()
 	mp.locks--
-	if mp.locks == 0 && _g_.preempt {
+	if mp.locks == 0 && gp.preempt {
 		// restore the preemption request in case we've cleared it in newstack
-		_g_.stackguard0 = stackPreempt
+		gp.stackguard0 = stackPreempt
 	}
 }
 
diff --git a/src/runtime/runtime2.go b/src/runtime/runtime2.go
index e178822..9381d1e 100644
--- a/src/runtime/runtime2.go
+++ b/src/runtime/runtime2.go
@@ -435,9 +435,9 @@
 	// 3. By debugCallWrap to pass parameters to a new goroutine because allocating a
 	//    closure in the runtime is forbidden.
 	param        unsafe.Pointer
-	atomicstatus uint32
+	atomicstatus atomic.Uint32
 	stackLock    uint32 // sigprof/scang lock; TODO: fold in to atomicstatus
-	goid         int64
+	goid         uint64
 	schedlink    guintptr
 	waitsince    int64      // approx time when the g become blocked
 	waitreason   waitReason // if status==Gwaiting
@@ -461,14 +461,14 @@
 	activeStackChans bool
 	// parkingOnChan indicates that the goroutine is about to
 	// park on a chansend or chanrecv. Used to signal an unsafe point
-	// for stack shrinking. It's a boolean value, but is updated atomically.
-	parkingOnChan uint8
+	// for stack shrinking.
+	parkingOnChan atomic.Bool
 
 	raceignore     int8     // ignore race detection events
 	sysblocktraced bool     // StartTrace has emitted EvGoInSyscall about this goroutine
 	tracking       bool     // whether we're tracking this G for sched latency statistics
 	trackingSeq    uint8    // used to decide whether to track this G
-	runnableStamp  int64    // timestamp of when the G last became runnable, only used when tracking
+	trackingStamp  int64    // timestamp of when the G last started being tracked
 	runnableTime   int64    // the amount of time spent runnable, cleared when running, only used when tracking
 	sysexitticks   int64    // cputicks when syscall has returned (for tracing)
 	traceseq       uint64   // trace event sequencer
@@ -487,7 +487,7 @@
 	cgoCtxt        []uintptr      // cgo traceback context
 	labels         unsafe.Pointer // profiler labels
 	timer          *timer         // cached timer for time.Sleep
-	selectDone     uint32         // are we participating in a select and did someone win the race?
+	selectDone     atomic.Uint32  // are we participating in a select and did someone win the race?
 
 	// goroutineProfiled indicates the status of this goroutine's stack for the
 	// current in-progress goroutine profile
@@ -516,6 +516,13 @@
 	tlsSize  = tlsSlots * goarch.PtrSize
 )
 
+// Values for m.freeWait.
+const (
+	freeMStack = 0 // M done, free stack and reference.
+	freeMRef   = 1 // M done, free reference.
+	freeMWait  = 2 // M still in use.
+)
+
 type m struct {
 	g0      *g     // goroutine with scheduling stack
 	morebuf gobuf  // gobuf arg to morestack
@@ -545,15 +552,16 @@
 	blocked       bool // m is blocked on a note
 	newSigstack   bool // minit on C thread called sigaltstack
 	printlock     int8
-	incgo         bool   // m is executing a cgo call
-	freeWait      uint32 // if == 0, safe to free g0 and delete m (atomic)
+	incgo         bool          // m is executing a cgo call
+	isextra       bool          // m is an extra m
+	freeWait      atomic.Uint32 // Whether it is safe to free g0 and delete m (one of freeMRef, freeMStack, freeMWait)
 	fastrand      uint64
 	needextram    bool
 	traceback     uint8
-	ncgocall      uint64      // number of cgo calls in total
-	ncgo          int32       // number of cgo calls currently in progress
-	cgoCallersUse uint32      // if non-zero, cgoCallers in use temporarily
-	cgoCallers    *cgoCallers // cgo traceback if crashing in cgo call
+	ncgocall      uint64        // number of cgo calls in total
+	ncgo          int32         // number of cgo calls currently in progress
+	cgoCallersUse atomic.Uint32 // if non-zero, cgoCallers in use temporarily
+	cgoCallers    *cgoCallers   // cgo traceback if crashing in cgo call
 	park          note
 	alllink       *m // on allm
 	schedlink     muintptr
@@ -583,12 +591,11 @@
 
 	// preemptGen counts the number of completed preemption
 	// signals. This is used to detect when a preemption is
-	// requested, but fails. Accessed atomically.
-	preemptGen uint32
+	// requested, but fails.
+	preemptGen atomic.Uint32
 
 	// Whether this is a pending preemption signal on this M.
-	// Accessed atomically.
-	signalPending uint32
+	signalPending atomic.Uint32
 
 	dlogPerM
 
@@ -668,19 +675,15 @@
 
 	palloc persistentAlloc // per-P to avoid mutex
 
-	_ uint32 // Alignment for atomic fields below
-
 	// The when field of the first entry on the timer heap.
-	// This is updated using atomic functions.
 	// This is 0 if the timer heap is empty.
-	timer0When uint64
+	timer0When atomic.Int64
 
 	// The earliest known nextwhen field of a timer with
 	// timerModifiedEarlier status. Because the timer may have been
 	// modified again, there need not be any timer with this value.
-	// This is updated using atomic functions.
 	// This is 0 if there are no timerModifiedEarlier timers.
-	timerModifiedEarliest uint64
+	timerModifiedEarliest atomic.Int64
 
 	// Per-P GC state
 	gcAssistTime         int64 // Nanoseconds in assistAlloc
@@ -713,7 +716,7 @@
 
 	// statsSeq is a counter indicating whether this P is currently
 	// writing any stats. Its value is even when not, odd when it is.
-	statsSeq uint32
+	statsSeq atomic.Uint32
 
 	// Lock for timers. We normally access the timers while running
 	// on this P, but the scheduler can also do it from a different P.
@@ -725,12 +728,10 @@
 	timers []*timer
 
 	// Number of timers in P's heap.
-	// Modified using atomic instructions.
-	numTimers uint32
+	numTimers atomic.Uint32
 
 	// Number of timerDeleted timers in P's heap.
-	// Modified using atomic instructions.
-	deletedTimers uint32
+	deletedTimers atomic.Uint32
 
 	// Race context used while executing timer functions.
 	timerRaceCtx uintptr
@@ -753,15 +754,19 @@
 	// scheduler ASAP (regardless of what G is running on it).
 	preempt bool
 
+	// pageTraceBuf is a buffer for writing out page allocation/free/scavenge traces.
+	//
+	// Used only if GOEXPERIMENT=pagetrace.
+	pageTraceBuf pageTraceBuf
+
 	// Padding is no longer needed. False sharing is now not a worry because p is large enough
 	// that its size class is an integer multiple of the cache line size (for any of our architectures).
 }
 
 type schedt struct {
-	// accessed atomically. keep at top to ensure alignment on 32-bit systems.
-	goidgen   uint64
-	lastpoll  uint64 // time of last network poll, 0 if currently polling
-	pollUntil uint64 // time to which current poll is sleeping
+	goidgen   atomic.Uint64
+	lastpoll  atomic.Int64 // time of last network poll, 0 if currently polling
+	pollUntil atomic.Int64 // time to which current poll is sleeping
 
 	lock mutex
 
@@ -776,11 +781,12 @@
 	nmsys        int32    // number of system m's not counted for deadlock
 	nmfreed      int64    // cumulative number of freed m's
 
-	ngsys uint32 // number of system goroutines; updated atomically
+	ngsys atomic.Int32 // number of system goroutines
 
-	pidle      puintptr // idle p's
-	npidle     uint32
-	nmspinning uint32 // See "Worker thread parking/unparking" comment in proc.go.
+	pidle        puintptr // idle p's
+	npidle       atomic.Int32
+	nmspinning   atomic.Int32  // See "Worker thread parking/unparking" comment in proc.go.
+	needspinning atomic.Uint32 // See "Delicate dance" comment in proc.go. Boolean. Must hold sched.lock to set to 1.
 
 	// Global runnable queue.
 	runq     gQueue
@@ -818,10 +824,10 @@
 	// m.exited is set. Linked through m.freelink.
 	freem *m
 
-	gcwaiting  uint32 // gc is waiting to run
+	gcwaiting  atomic.Bool // gc is waiting to run
 	stopwait   int32
 	stopnote   note
-	sysmonwait uint32
+	sysmonwait atomic.Bool
 	sysmonnote note
 
 	// safepointFn should be called on each P at the next GC
@@ -844,9 +850,16 @@
 	// timeToRun is a distribution of scheduling latencies, defined
 	// as the sum of time a G spends in the _Grunnable state before
 	// it transitions to _Grunning.
-	//
-	// timeToRun is protected by sched.lock.
 	timeToRun timeHistogram
+
+	// idleTime is the total CPU time Ps have "spent" idle.
+	//
+	// Reset on each GC cycle.
+	idleTime atomic.Int64
+
+	// totalMutexWaitTime is the sum of time goroutines have spent in _Gwaiting
+	// with a waitreason of the form waitReasonSync{RW,}Mutex{R,}Lock.
+	totalMutexWaitTime atomic.Int64
 }
 
 // Values for the flags field of a sigTabT.
@@ -867,8 +880,8 @@
 // Keep in sync with linker (../cmd/link/internal/ld/pcln.go:/pclntab)
 // and with package debug/gosym and with symtab.go in package runtime.
 type _func struct {
-	entryoff uint32 // start pc, as offset from moduledata.text/pcHeader.textStart
-	nameoff  int32  // function name
+	entryOff uint32 // start pc, as offset from moduledata.text/pcHeader.textStart
+	nameOff  int32  // function name, as index into moduledata.funcnametab.
 
 	args        int32  // in/out args size
 	deferreturn uint32 // offset of start of a deferreturn call instruction from entry, if any.
@@ -878,21 +891,45 @@
 	pcln      uint32
 	npcdata   uint32
 	cuOffset  uint32 // runtime.cutab offset of this function's CU
+	startLine int32  // line number of start of function (func keyword/TEXT directive)
 	funcID    funcID // set for certain special runtime functions
 	flag      funcFlag
 	_         [1]byte // pad
 	nfuncdata uint8   // must be last, must end on a uint32-aligned boundary
+
+	// The end of the struct is followed immediately by two variable-length
+	// arrays that reference the pcdata and funcdata locations for this
+	// function.
+
+	// pcdata contains the offset into moduledata.pctab for the start of
+	// that index's table. e.g.,
+	// &moduledata.pctab[_func.pcdata[_PCDATA_UnsafePoint]] is the start of
+	// the unsafe point table.
+	//
+	// An offset of 0 indicates that there is no table.
+	//
+	// pcdata [npcdata]uint32
+
+	// funcdata contains the offset past moduledata.gofunc which contains a
+	// pointer to that index's funcdata. e.g.,
+	// *(moduledata.gofunc +  _func.funcdata[_FUNCDATA_ArgsPointerMaps]) is
+	// the argument pointer map.
+	//
+	// An offset of ^uint32(0) indicates that there is no entry.
+	//
+	// funcdata [nfuncdata]uint32
 }
 
 // Pseudo-Func that is returned for PCs that occur in inlined code.
 // A *Func can be either a *_func or a *funcinl, and they are distinguished
 // by the first uintptr.
 type funcinl struct {
-	ones  uint32  // set to ^0 to distinguish from _func
-	entry uintptr // entry of the real (the "outermost") frame
-	name  string
-	file  string
-	line  int
+	ones      uint32  // set to ^0 to distinguish from _func
+	entry     uintptr // entry of the real (the "outermost") frame
+	name      string
+	file      string
+	line      int32
+	startLine int32
 }
 
 // layout of Itab known to compilers
@@ -917,7 +954,7 @@
 type forcegcstate struct {
 	lock mutex
 	g    *g
-	idle uint32
+	idle atomic.Bool
 }
 
 // extendRandom extends the random numbers in r[:n] to the whole slice r.
@@ -994,24 +1031,10 @@
 	goexit    bool
 }
 
-// stack traces
-type stkframe struct {
-	fn       funcInfo   // function being run
-	pc       uintptr    // program counter within fn
-	continpc uintptr    // program counter where execution can continue, or 0 if not
-	lr       uintptr    // program counter at caller aka link register
-	sp       uintptr    // stack pointer at pc
-	fp       uintptr    // stack pointer at caller aka frame pointer
-	varp     uintptr    // top of local variables
-	argp     uintptr    // pointer to function arguments
-	arglen   uintptr    // number of bytes at argp
-	argmap   *bitvector // force use of this argmap
-}
-
 // ancestorInfo records details of where a goroutine was started.
 type ancestorInfo struct {
 	pcs  []uintptr // pcs from the stack of this goroutine
-	goid int64     // goroutine id of this goroutine; original goroutine possibly dead
+	goid uint64    // goroutine id of this goroutine; original goroutine possibly dead
 	gopc uintptr   // pc of go statement that created this goroutine
 }
 
@@ -1050,12 +1073,17 @@
 	waitReasonSemacquire                              // "semacquire"
 	waitReasonSleep                                   // "sleep"
 	waitReasonSyncCondWait                            // "sync.Cond.Wait"
-	waitReasonTimerGoroutineIdle                      // "timer goroutine (idle)"
+	waitReasonSyncMutexLock                           // "sync.Mutex.Lock"
+	waitReasonSyncRWMutexRLock                        // "sync.RWMutex.RLock"
+	waitReasonSyncRWMutexLock                         // "sync.RWMutex.Lock"
 	waitReasonTraceReaderBlocked                      // "trace reader (blocked)"
 	waitReasonWaitForGCCycle                          // "wait for GC cycle"
 	waitReasonGCWorkerIdle                            // "GC worker (idle)"
+	waitReasonGCWorkerActive                          // "GC worker (active)"
 	waitReasonPreempted                               // "preempted"
 	waitReasonDebugCall                               // "debug call"
+	waitReasonGCMarkTermination                       // "GC mark termination"
+	waitReasonStoppingTheWorld                        // "stopping the world"
 )
 
 var waitReasonStrings = [...]string{
@@ -1080,12 +1108,17 @@
 	waitReasonSemacquire:            "semacquire",
 	waitReasonSleep:                 "sleep",
 	waitReasonSyncCondWait:          "sync.Cond.Wait",
-	waitReasonTimerGoroutineIdle:    "timer goroutine (idle)",
+	waitReasonSyncMutexLock:         "sync.Mutex.Lock",
+	waitReasonSyncRWMutexRLock:      "sync.RWMutex.RLock",
+	waitReasonSyncRWMutexLock:       "sync.RWMutex.Lock",
 	waitReasonTraceReaderBlocked:    "trace reader (blocked)",
 	waitReasonWaitForGCCycle:        "wait for GC cycle",
 	waitReasonGCWorkerIdle:          "GC worker (idle)",
+	waitReasonGCWorkerActive:        "GC worker (active)",
 	waitReasonPreempted:             "preempted",
 	waitReasonDebugCall:             "debug call",
+	waitReasonGCMarkTermination:     "GC mark termination",
+	waitReasonStoppingTheWorld:      "stopping the world",
 }
 
 func (w waitReason) String() string {
@@ -1095,6 +1128,12 @@
 	return waitReasonStrings[w]
 }
 
+func (w waitReason) isMutexWait() bool {
+	return w == waitReasonSyncMutexLock ||
+		w == waitReasonSyncRWMutexRLock ||
+		w == waitReasonSyncRWMutexLock
+}
+
 var (
 	allm       *m
 	gomaxprocs int32
diff --git a/src/runtime/runtime_linux_test.go b/src/runtime/runtime_linux_test.go
index a753aee..6af5561 100644
--- a/src/runtime/runtime_linux_test.go
+++ b/src/runtime/runtime_linux_test.go
@@ -53,15 +53,6 @@
 	}
 }
 
-func TestEpollctlErrorSign(t *testing.T) {
-	v := Epollctl(-1, 1, -1, unsafe.Pointer(&EpollEvent{}))
-
-	const EBADF = 0x09
-	if v != -EBADF {
-		t.Errorf("epollctl = %v, want %v", v, -EBADF)
-	}
-}
-
 func TestKernelStructSize(t *testing.T) {
 	// Check that the Go definitions of structures exchanged with the kernel are
 	// the same size as what the kernel defines.
diff --git a/src/runtime/runtime_test.go b/src/runtime/runtime_test.go
index 018a8db..2faf06e 100644
--- a/src/runtime/runtime_test.go
+++ b/src/runtime/runtime_test.go
@@ -377,7 +377,7 @@
 				if !ok {
 					b.Fatal("goroutine profile failed")
 				}
-				latencies = append(latencies, time.Now().Sub(start))
+				latencies = append(latencies, time.Since(start))
 			}
 			b.StopTimer()
 
diff --git a/src/runtime/rwmutex.go b/src/runtime/rwmutex.go
index 7713c3f..ede3d13 100644
--- a/src/runtime/rwmutex.go
+++ b/src/runtime/rwmutex.go
@@ -23,8 +23,8 @@
 	wLock  mutex    // serializes writers
 	writer muintptr // pending writer waiting for completing readers
 
-	readerCount uint32 // number of pending readers
-	readerWait  uint32 // number of departing readers
+	readerCount atomic.Int32 // number of pending readers
+	readerWait  atomic.Int32 // number of departing readers
 }
 
 const rwmutexMaxReaders = 1 << 30
@@ -36,7 +36,7 @@
 	// deadlock (issue #20903). Alternatively, we could drop the P
 	// while sleeping.
 	acquirem()
-	if int32(atomic.Xadd(&rw.readerCount, 1)) < 0 {
+	if rw.readerCount.Add(1) < 0 {
 		// A writer is pending. Park on the reader queue.
 		systemstack(func() {
 			lockWithRank(&rw.rLock, lockRankRwmutexR)
@@ -60,12 +60,12 @@
 
 // runlock undoes a single rlock call on rw.
 func (rw *rwmutex) runlock() {
-	if r := int32(atomic.Xadd(&rw.readerCount, -1)); r < 0 {
+	if r := rw.readerCount.Add(-1); r < 0 {
 		if r+1 == 0 || r+1 == -rwmutexMaxReaders {
 			throw("runlock of unlocked rwmutex")
 		}
 		// A writer is pending.
-		if atomic.Xadd(&rw.readerWait, -1) == 0 {
+		if rw.readerWait.Add(-1) == 0 {
 			// The last reader unblocks the writer.
 			lockWithRank(&rw.rLock, lockRankRwmutexR)
 			w := rw.writer.ptr()
@@ -84,10 +84,10 @@
 	lockWithRank(&rw.wLock, lockRankRwmutexW)
 	m := getg().m
 	// Announce that there is a pending writer.
-	r := int32(atomic.Xadd(&rw.readerCount, -rwmutexMaxReaders)) + rwmutexMaxReaders
+	r := rw.readerCount.Add(-rwmutexMaxReaders) + rwmutexMaxReaders
 	// Wait for any active readers to complete.
 	lockWithRank(&rw.rLock, lockRankRwmutexR)
-	if r != 0 && atomic.Xadd(&rw.readerWait, r) != 0 {
+	if r != 0 && rw.readerWait.Add(r) != 0 {
 		// Wait for reader to wake us up.
 		systemstack(func() {
 			rw.writer.set(m)
@@ -103,7 +103,7 @@
 // unlock unlocks rw for writing.
 func (rw *rwmutex) unlock() {
 	// Announce to readers that there is no active writer.
-	r := int32(atomic.Xadd(&rw.readerCount, rwmutexMaxReaders))
+	r := rw.readerCount.Add(rwmutexMaxReaders)
 	if r >= rwmutexMaxReaders {
 		throw("unlock of unlocked rwmutex")
 	}
diff --git a/src/runtime/rwmutex_test.go b/src/runtime/rwmutex_test.go
index f15d367..ddb16ae 100644
--- a/src/runtime/rwmutex_test.go
+++ b/src/runtime/rwmutex_test.go
@@ -17,10 +17,10 @@
 	"testing"
 )
 
-func parallelReader(m *RWMutex, clocked chan bool, cunlock *uint32, cdone chan bool) {
+func parallelReader(m *RWMutex, clocked chan bool, cunlock *atomic.Bool, cdone chan bool) {
 	m.RLock()
 	clocked <- true
-	for atomic.LoadUint32(cunlock) == 0 {
+	for !cunlock.Load() {
 	}
 	m.RUnlock()
 	cdone <- true
@@ -30,7 +30,7 @@
 	GOMAXPROCS(numReaders + 1)
 	var m RWMutex
 	clocked := make(chan bool, numReaders)
-	var cunlock uint32
+	var cunlock atomic.Bool
 	cdone := make(chan bool)
 	for i := 0; i < numReaders; i++ {
 		go parallelReader(&m, clocked, &cunlock, cdone)
@@ -39,7 +39,7 @@
 	for i := 0; i < numReaders; i++ {
 		<-clocked
 	}
-	atomic.StoreUint32(&cunlock, 1)
+	cunlock.Store(true)
 	// Wait for the goroutines to finish.
 	for i := 0; i < numReaders; i++ {
 		<-cdone
diff --git a/src/runtime/select.go b/src/runtime/select.go
index e18b2f1..1072465 100644
--- a/src/runtime/select.go
+++ b/src/runtime/select.go
@@ -8,7 +8,6 @@
 
 import (
 	"internal/abi"
-	"runtime/internal/atomic"
 	"unsafe"
 )
 
@@ -70,7 +69,7 @@
 	// Mark that it's safe for stack shrinking to occur now,
 	// because any thread acquiring this G's stack for shrinking
 	// is guaranteed to observe activeStackChans after this store.
-	atomic.Store8(&gp.parkingOnChan, 0)
+	gp.parkingOnChan.Store(false)
 	// Make sure we unlock after setting activeStackChans and
 	// unsetting parkingOnChan. The moment we unlock any of the
 	// channel locks we risk gp getting readied by a channel operation
@@ -324,13 +323,13 @@
 	// to park on a channel. The window between when this G's status
 	// changes and when we set gp.activeStackChans is not safe for
 	// stack shrinking.
-	atomic.Store8(&gp.parkingOnChan, 1)
+	gp.parkingOnChan.Store(true)
 	gopark(selparkcommit, nil, waitReasonSelect, traceEvGoBlockSelect, 1)
 	gp.activeStackChans = false
 
 	sellock(scases, lockorder)
 
-	gp.selectDone = 0
+	gp.selectDone.Store(0)
 	sg = (*sudog)(gp.param)
 	gp.param = nil
 
diff --git a/src/runtime/sema.go b/src/runtime/sema.go
index 39935f7..bc23a85 100644
--- a/src/runtime/sema.go
+++ b/src/runtime/sema.go
@@ -39,8 +39,8 @@
 // BenchmarkSemTable/OneAddrCollision/* for a benchmark that exercises this.
 type semaRoot struct {
 	lock  mutex
-	treap *sudog // root of balanced tree of unique waiters.
-	nwait uint32 // Number of waiters. Read w/o the lock.
+	treap *sudog        // root of balanced tree of unique waiters.
+	nwait atomic.Uint32 // Number of waiters. Read w/o the lock.
 }
 
 var semtable semTable
@@ -59,12 +59,12 @@
 
 //go:linkname sync_runtime_Semacquire sync.runtime_Semacquire
 func sync_runtime_Semacquire(addr *uint32) {
-	semacquire1(addr, false, semaBlockProfile, 0)
+	semacquire1(addr, false, semaBlockProfile, 0, waitReasonSemacquire)
 }
 
 //go:linkname poll_runtime_Semacquire internal/poll.runtime_Semacquire
 func poll_runtime_Semacquire(addr *uint32) {
-	semacquire1(addr, false, semaBlockProfile, 0)
+	semacquire1(addr, false, semaBlockProfile, 0, waitReasonSemacquire)
 }
 
 //go:linkname sync_runtime_Semrelease sync.runtime_Semrelease
@@ -74,7 +74,17 @@
 
 //go:linkname sync_runtime_SemacquireMutex sync.runtime_SemacquireMutex
 func sync_runtime_SemacquireMutex(addr *uint32, lifo bool, skipframes int) {
-	semacquire1(addr, lifo, semaBlockProfile|semaMutexProfile, skipframes)
+	semacquire1(addr, lifo, semaBlockProfile|semaMutexProfile, skipframes, waitReasonSyncMutexLock)
+}
+
+//go:linkname sync_runtime_SemacquireRWMutexR sync.runtime_SemacquireRWMutexR
+func sync_runtime_SemacquireRWMutexR(addr *uint32, lifo bool, skipframes int) {
+	semacquire1(addr, lifo, semaBlockProfile|semaMutexProfile, skipframes, waitReasonSyncRWMutexRLock)
+}
+
+//go:linkname sync_runtime_SemacquireRWMutex sync.runtime_SemacquireRWMutex
+func sync_runtime_SemacquireRWMutex(addr *uint32, lifo bool, skipframes int) {
+	semacquire1(addr, lifo, semaBlockProfile|semaMutexProfile, skipframes, waitReasonSyncRWMutexLock)
 }
 
 //go:linkname poll_runtime_Semrelease internal/poll.runtime_Semrelease
@@ -98,10 +108,10 @@
 
 // Called from runtime.
 func semacquire(addr *uint32) {
-	semacquire1(addr, false, 0, 0)
+	semacquire1(addr, false, 0, 0, waitReasonSemacquire)
 }
 
-func semacquire1(addr *uint32, lifo bool, profile semaProfileFlags, skipframes int) {
+func semacquire1(addr *uint32, lifo bool, profile semaProfileFlags, skipframes int, reason waitReason) {
 	gp := getg()
 	if gp != gp.m.curg {
 		throw("semacquire not on the G stack")
@@ -137,17 +147,17 @@
 	for {
 		lockWithRank(&root.lock, lockRankRoot)
 		// Add ourselves to nwait to disable "easy case" in semrelease.
-		atomic.Xadd(&root.nwait, 1)
+		root.nwait.Add(1)
 		// Check cansemacquire to avoid missed wakeup.
 		if cansemacquire(addr) {
-			atomic.Xadd(&root.nwait, -1)
+			root.nwait.Add(-1)
 			unlock(&root.lock)
 			break
 		}
 		// Any semrelease after the cansemacquire knows we're waiting
 		// (we set nwait above), so go to sleep.
 		root.queue(addr, s, lifo)
-		goparkunlock(&root.lock, waitReasonSemacquire, traceEvGoBlockSync, 4+skipframes)
+		goparkunlock(&root.lock, reason, traceEvGoBlockSync, 4+skipframes)
 		if s.ticket != 0 || cansemacquire(addr) {
 			break
 		}
@@ -169,13 +179,13 @@
 	// Easy case: no waiters?
 	// This check must happen after the xadd, to avoid a missed wakeup
 	// (see loop in semacquire).
-	if atomic.Load(&root.nwait) == 0 {
+	if root.nwait.Load() == 0 {
 		return
 	}
 
 	// Harder case: search for a waiter and wake it.
 	lockWithRank(&root.lock, lockRankRoot)
-	if atomic.Load(&root.nwait) == 0 {
+	if root.nwait.Load() == 0 {
 		// The count is already consumed by another goroutine,
 		// so no need to wake up another goroutine.
 		unlock(&root.lock)
@@ -183,7 +193,7 @@
 	}
 	s, t0 := root.dequeue(addr)
 	if s != nil {
-		atomic.Xadd(&root.nwait, -1)
+		root.nwait.Add(-1)
 	}
 	unlock(&root.lock)
 	if s != nil { // May be slow or even yield, so unlock first
@@ -451,7 +461,7 @@
 type notifyList struct {
 	// wait is the ticket number of the next waiter. It is atomically
 	// incremented outside the lock.
-	wait uint32
+	wait atomic.Uint32
 
 	// notify is the ticket number of the next waiter to be notified. It can
 	// be read outside the lock, but is only written to with lock held.
@@ -482,7 +492,7 @@
 func notifyListAdd(l *notifyList) uint32 {
 	// This may be called concurrently, for example, when called from
 	// sync.Cond.Wait while holding a RWMutex in read mode.
-	return atomic.Xadd(&l.wait, 1) - 1
+	return l.wait.Add(1) - 1
 }
 
 // notifyListWait waits for a notification. If one has been sent since
@@ -527,7 +537,7 @@
 func notifyListNotifyAll(l *notifyList) {
 	// Fast-path: if there are no new waiters since the last notification
 	// we don't need to acquire the lock.
-	if atomic.Load(&l.wait) == atomic.Load(&l.notify) {
+	if l.wait.Load() == atomic.Load(&l.notify) {
 		return
 	}
 
@@ -542,7 +552,7 @@
 	// value of wait because any previous waiters are already in the list
 	// or will notice that they have already been notified when trying to
 	// add themselves to the list.
-	atomic.Store(&l.notify, atomic.Load(&l.wait))
+	atomic.Store(&l.notify, l.wait.Load())
 	unlock(&l.lock)
 
 	// Go through the local list and ready all waiters.
@@ -560,7 +570,7 @@
 func notifyListNotifyOne(l *notifyList) {
 	// Fast-path: if there are no new waiters since the last notification
 	// we don't need to acquire the lock at all.
-	if atomic.Load(&l.wait) == atomic.Load(&l.notify) {
+	if l.wait.Load() == atomic.Load(&l.notify) {
 		return
 	}
 
@@ -568,7 +578,7 @@
 
 	// Re-check under the lock if we need to do anything.
 	t := l.notify
-	if t == atomic.Load(&l.wait) {
+	if t == l.wait.Load() {
 		unlock(&l.lock)
 		return
 	}
diff --git a/src/runtime/semasleep_test.go b/src/runtime/semasleep_test.go
index d56733c..7262853 100644
--- a/src/runtime/semasleep_test.go
+++ b/src/runtime/semasleep_test.go
@@ -37,14 +37,16 @@
 	if err := cmd.Start(); err != nil {
 		t.Fatalf("Failed to start command: %v", err)
 	}
+
+	waiting := false
 	doneCh := make(chan error, 1)
-	go func() {
-		doneCh <- cmd.Wait()
-		close(doneCh)
-	}()
 	t.Cleanup(func() {
 		cmd.Process.Kill()
-		<-doneCh
+		if waiting {
+			<-doneCh
+		} else {
+			cmd.Wait()
+		}
 	})
 
 	// Wait for After1 to close its stdout so that we know the runtime's SIGIO
@@ -57,6 +59,19 @@
 		t.Fatalf("error reading from testprog: %v", err)
 	}
 
+	// Wait for child exit.
+	//
+	// Note that we must do this after waiting for the write/child end of
+	// stdout to close. Wait closes the read/parent end of stdout, so
+	// starting this goroutine prior to io.ReadAll introduces a race
+	// condition where ReadAll may get fs.ErrClosed if the child exits too
+	// quickly.
+	waiting = true
+	go func() {
+		doneCh <- cmd.Wait()
+		close(doneCh)
+	}()
+
 	// Wait for an arbitrary timeout longer than one second. The subprocess itself
 	// attempts to sleep for one second, but if the machine running the test is
 	// heavily loaded that subprocess may not schedule very quickly even if the
diff --git a/src/runtime/signal_darwin_amd64.go b/src/runtime/signal_darwin_amd64.go
index abc212a..20544d8 100644
--- a/src/runtime/signal_darwin_amd64.go
+++ b/src/runtime/signal_darwin_amd64.go
@@ -84,6 +84,10 @@
 		// in real life, people will probably search for it and find this code.
 		// There are no Google hits for b01dfacedebac1e or 0xb01dfacedebac1e
 		// as I type this comment.
+		//
+		// Note: if this code is removed, please consider
+		// enabling TestSignalForwardingGo for darwin-amd64 in
+		// misc/cgo/testcarchive/carchive_test.go.
 		if c.sigcode() == _SI_USER {
 			c.set_sigcode(_SI_USER + 1)
 			c.set_sigaddr(0xb01dfacedebac1e)
diff --git a/src/runtime/signal_freebsd_riscv64.go b/src/runtime/signal_freebsd_riscv64.go
new file mode 100644
index 0000000..fbf6c63
--- /dev/null
+++ b/src/runtime/signal_freebsd_riscv64.go
@@ -0,0 +1,63 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+import "unsafe"
+
+type sigctxt struct {
+	info *siginfo
+	ctxt unsafe.Pointer
+}
+
+//go:nosplit
+//go:nowritebarrierrec
+func (c *sigctxt) regs() *mcontext { return &(*ucontext)(c.ctxt).uc_mcontext }
+
+func (c *sigctxt) ra() uint64  { return c.regs().mc_gpregs.gp_ra }
+func (c *sigctxt) sp() uint64  { return c.regs().mc_gpregs.gp_sp }
+func (c *sigctxt) gp() uint64  { return c.regs().mc_gpregs.gp_gp }
+func (c *sigctxt) tp() uint64  { return c.regs().mc_gpregs.gp_tp }
+func (c *sigctxt) t0() uint64  { return c.regs().mc_gpregs.gp_t[0] }
+func (c *sigctxt) t1() uint64  { return c.regs().mc_gpregs.gp_t[1] }
+func (c *sigctxt) t2() uint64  { return c.regs().mc_gpregs.gp_t[2] }
+func (c *sigctxt) s0() uint64  { return c.regs().mc_gpregs.gp_s[0] }
+func (c *sigctxt) s1() uint64  { return c.regs().mc_gpregs.gp_s[1] }
+func (c *sigctxt) a0() uint64  { return c.regs().mc_gpregs.gp_a[0] }
+func (c *sigctxt) a1() uint64  { return c.regs().mc_gpregs.gp_a[1] }
+func (c *sigctxt) a2() uint64  { return c.regs().mc_gpregs.gp_a[2] }
+func (c *sigctxt) a3() uint64  { return c.regs().mc_gpregs.gp_a[3] }
+func (c *sigctxt) a4() uint64  { return c.regs().mc_gpregs.gp_a[4] }
+func (c *sigctxt) a5() uint64  { return c.regs().mc_gpregs.gp_a[5] }
+func (c *sigctxt) a6() uint64  { return c.regs().mc_gpregs.gp_a[6] }
+func (c *sigctxt) a7() uint64  { return c.regs().mc_gpregs.gp_a[7] }
+func (c *sigctxt) s2() uint64  { return c.regs().mc_gpregs.gp_s[2] }
+func (c *sigctxt) s3() uint64  { return c.regs().mc_gpregs.gp_s[3] }
+func (c *sigctxt) s4() uint64  { return c.regs().mc_gpregs.gp_s[4] }
+func (c *sigctxt) s5() uint64  { return c.regs().mc_gpregs.gp_s[5] }
+func (c *sigctxt) s6() uint64  { return c.regs().mc_gpregs.gp_s[6] }
+func (c *sigctxt) s7() uint64  { return c.regs().mc_gpregs.gp_s[7] }
+func (c *sigctxt) s8() uint64  { return c.regs().mc_gpregs.gp_s[8] }
+func (c *sigctxt) s9() uint64  { return c.regs().mc_gpregs.gp_s[9] }
+func (c *sigctxt) s10() uint64 { return c.regs().mc_gpregs.gp_s[10] }
+func (c *sigctxt) s11() uint64 { return c.regs().mc_gpregs.gp_s[11] }
+func (c *sigctxt) t3() uint64  { return c.regs().mc_gpregs.gp_t[3] }
+func (c *sigctxt) t4() uint64  { return c.regs().mc_gpregs.gp_t[4] }
+func (c *sigctxt) t5() uint64  { return c.regs().mc_gpregs.gp_t[5] }
+func (c *sigctxt) t6() uint64  { return c.regs().mc_gpregs.gp_t[6] }
+
+//go:nosplit
+//go:nowritebarrierrec
+func (c *sigctxt) pc() uint64 { return c.regs().mc_gpregs.gp_sepc }
+
+func (c *sigctxt) sigcode() uint64 { return uint64(c.info.si_code) }
+func (c *sigctxt) sigaddr() uint64 { return c.info.si_addr }
+
+func (c *sigctxt) set_pc(x uint64) { c.regs().mc_gpregs.gp_sepc = x }
+func (c *sigctxt) set_ra(x uint64) { c.regs().mc_gpregs.gp_ra = x }
+func (c *sigctxt) set_sp(x uint64) { c.regs().mc_gpregs.gp_sp = x }
+func (c *sigctxt) set_gp(x uint64) { c.regs().mc_gpregs.gp_gp = x }
+
+func (c *sigctxt) set_sigcode(x uint64) { c.info.si_code = int32(x) }
+func (c *sigctxt) set_sigaddr(x uint64) { c.info.si_addr = x }
diff --git a/src/runtime/signal_riscv64.go b/src/runtime/signal_riscv64.go
index 5eeb227..b8d7b97 100644
--- a/src/runtime/signal_riscv64.go
+++ b/src/runtime/signal_riscv64.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build linux && riscv64
+//go:build (linux || freebsd) && riscv64
 
 package runtime
 
diff --git a/src/runtime/signal_unix.go b/src/runtime/signal_unix.go
index 0be499b..c401fc1 100644
--- a/src/runtime/signal_unix.go
+++ b/src/runtime/signal_unix.go
@@ -349,11 +349,11 @@
 	}
 
 	// Acknowledge the preemption.
-	atomic.Xadd(&gp.m.preemptGen, 1)
-	atomic.Store(&gp.m.signalPending, 0)
+	gp.m.preemptGen.Add(1)
+	gp.m.signalPending.Store(0)
 
 	if GOOS == "darwin" || GOOS == "ios" {
-		atomic.Xadd(&pendingPreemptSignals, -1)
+		pendingPreemptSignals.Add(-1)
 	}
 }
 
@@ -372,9 +372,9 @@
 		execLock.rlock()
 	}
 
-	if atomic.Cas(&mp.signalPending, 0, 1) {
+	if mp.signalPending.CompareAndSwap(0, 1) {
 		if GOOS == "darwin" || GOOS == "ios" {
-			atomic.Xadd(&pendingPreemptSignals, 1)
+			pendingPreemptSignals.Add(1)
 		}
 
 		// If multiple threads are preempting the same M, it may send many
@@ -433,9 +433,9 @@
 		return
 	}
 	c := &sigctxt{info, ctx}
-	g := sigFetchG(c)
-	setg(g)
-	if g == nil {
+	gp := sigFetchG(c)
+	setg(gp)
+	if gp == nil {
 		if sig == _SIGPROF {
 			// Some platforms (Linux) have per-thread timers, which we use in
 			// combination with the process-wide timer. Avoid double-counting.
@@ -453,7 +453,7 @@
 			// The default behavior for sigPreempt is to ignore
 			// the signal, so badsignal will be a no-op anyway.
 			if GOOS == "darwin" || GOOS == "ios" {
-				atomic.Xadd(&pendingPreemptSignals, -1)
+				pendingPreemptSignals.Add(-1)
 			}
 			return
 		}
@@ -462,22 +462,22 @@
 		return
 	}
 
-	setg(g.m.gsignal)
+	setg(gp.m.gsignal)
 
 	// If some non-Go code called sigaltstack, adjust.
 	var gsignalStack gsignalStack
-	setStack := adjustSignalStack(sig, g.m, &gsignalStack)
+	setStack := adjustSignalStack(sig, gp.m, &gsignalStack)
 	if setStack {
-		g.m.gsignal.stktopsp = getcallersp()
+		gp.m.gsignal.stktopsp = getcallersp()
 	}
 
-	if g.stackguard0 == stackFork {
+	if gp.stackguard0 == stackFork {
 		signalDuringFork(sig)
 	}
 
 	c.fixsigcode(sig)
-	sighandler(sig, info, ctx, g)
-	setg(g)
+	sighandler(sig, info, ctx, gp)
+	setg(gp)
 	if setStack {
 		restoreGsignalStack(&gsignalStack)
 	}
@@ -502,7 +502,7 @@
 //go:nosplit
 //go:nowritebarrierrec
 func sigprofNonGo(sig uint32, info *siginfo, ctx unsafe.Pointer) {
-	if prof.hz != 0 {
+	if prof.hz.Load() != 0 {
 		c := &sigctxt{info, ctx}
 		// Some platforms (Linux) have per-thread timers, which we use in
 		// combination with the process-wide timer. Avoid double-counting.
@@ -525,7 +525,7 @@
 //go:nosplit
 //go:nowritebarrierrec
 func sigprofNonGoPC(pc uintptr) {
-	if prof.hz != 0 {
+	if prof.hz.Load() != 0 {
 		stk := []uintptr{
 			pc,
 			abi.FuncPCABIInternal(_ExternalCode) + sys.PCQuantum,
@@ -596,7 +596,7 @@
 
 // sighandler is invoked when a signal occurs. The global g will be
 // set to a gsignal goroutine and we will be running on the alternate
-// signal stack. The parameter g will be the value of the global g
+// signal stack. The parameter gp will be the value of the global g
 // when the signal occurred. The sig, info, and ctxt parameters are
 // from the system signal handler: they are the parameters passed when
 // the SA is passed to the sigaction system call.
@@ -606,9 +606,11 @@
 //
 //go:nowritebarrierrec
 func sighandler(sig uint32, info *siginfo, ctxt unsafe.Pointer, gp *g) {
-	_g_ := getg()
+	// The g executing the signal handler. This is almost always
+	// mp.gsignal. See delayedSignal for an exception.
+	gsignal := getg()
+	mp := gsignal.m
 	c := &sigctxt{info, ctxt}
-	mp := _g_.m
 
 	// Cgo TSAN (not the Go race detector) intercepts signals and calls the
 	// signal handler at a later time. When the signal handler is called, the
@@ -620,7 +622,7 @@
 	// signal delivery. We use that as an indicator of delayed signals.
 	// For delayed signals, the handler is called on the g0 stack (see
 	// adjustSignalStack).
-	delayedSignal := *cgo_yield != nil && mp != nil && _g_.stack == mp.g0.stack
+	delayedSignal := *cgo_yield != nil && mp != nil && gsignal.stack == mp.g0.stack
 
 	if sig == _SIGPROF {
 		// Some platforms (Linux) have per-thread timers, which we use in
@@ -660,7 +662,7 @@
 	if sig < uint32(len(sigtable)) {
 		flags = sigtable[sig].flags
 	}
-	if c.sigcode() != _SI_USER && flags&_SigPanic != 0 && gp.throwsplit {
+	if !c.sigFromUser() && flags&_SigPanic != 0 && gp.throwsplit {
 		// We can't safely sigpanic because it may grow the
 		// stack. Abort in the signal handler instead.
 		flags = _SigThrow
@@ -670,7 +672,7 @@
 		// causes a memory fault. Don't turn that into a panic.
 		flags = _SigThrow
 	}
-	if c.sigcode() != _SI_USER && flags&_SigPanic != 0 {
+	if !c.sigFromUser() && flags&_SigPanic != 0 {
 		// The signal is going to cause a panic.
 		// Arrange the stack so that it looks like the point
 		// where the signal occurred made a call to the
@@ -688,13 +690,13 @@
 		return
 	}
 
-	if c.sigcode() == _SI_USER || flags&_SigNotify != 0 {
+	if c.sigFromUser() || flags&_SigNotify != 0 {
 		if sigsend(sig) {
 			return
 		}
 	}
 
-	if c.sigcode() == _SI_USER && signal_ignored(sig) {
+	if c.sigFromUser() && signal_ignored(sig) {
 		return
 	}
 
@@ -704,14 +706,14 @@
 
 	// _SigThrow means that we should exit now.
 	// If we get here with _SigPanic, it means that the signal
-	// was sent to us by a program (c.sigcode() == _SI_USER);
+	// was sent to us by a program (c.sigFromUser() is true);
 	// in that case, if we didn't handle it in sigsend, we exit now.
 	if flags&(_SigThrow|_SigPanic) == 0 {
 		return
 	}
 
-	_g_.m.throwing = throwTypeRuntime
-	_g_.m.caughtsig.set(gp)
+	mp.throwing = throwTypeRuntime
+	mp.caughtsig.set(gp)
 
 	if crashing == 0 {
 		startpanic_m()
@@ -723,12 +725,12 @@
 		print("Signal ", sig, "\n")
 	}
 
-	print("PC=", hex(c.sigpc()), " m=", _g_.m.id, " sigcode=", c.sigcode(), "\n")
-	if _g_.m.incgo && gp == _g_.m.g0 && _g_.m.curg != nil {
+	print("PC=", hex(c.sigpc()), " m=", mp.id, " sigcode=", c.sigcode(), "\n")
+	if mp.incgo && gp == mp.g0 && mp.curg != nil {
 		print("signal arrived during cgo execution\n")
 		// Switch to curg so that we get a traceback of the Go code
 		// leading up to the cgocall, which switched from curg to g0.
-		gp = _g_.m.curg
+		gp = mp.curg
 	}
 	if sig == _SIGILL || sig == _SIGFPE {
 		// It would be nice to know how long the instruction is.
@@ -760,10 +762,10 @@
 	if level > 0 {
 		goroutineheader(gp)
 		tracebacktrap(c.sigpc(), c.sigsp(), c.siglr(), gp)
-		if crashing > 0 && gp != _g_.m.curg && _g_.m.curg != nil && readgstatus(_g_.m.curg)&^_Gscan == _Grunning {
+		if crashing > 0 && gp != mp.curg && mp.curg != nil && readgstatus(mp.curg)&^_Gscan == _Grunning {
 			// tracebackothers on original m skipped this one; trace it now.
-			goroutineheader(_g_.m.curg)
-			traceback(^uintptr(0), ^uintptr(0), 0, _g_.m.curg)
+			goroutineheader(mp.curg)
+			traceback(^uintptr(0), ^uintptr(0), 0, mp.curg)
 		} else if crashing == 0 {
 			tracebackothers(gp)
 			print("\n")
@@ -814,34 +816,41 @@
 //
 //go:linkname sigpanic
 func sigpanic() {
-	g := getg()
-	if !canpanic(g) {
+	gp := getg()
+	if !canpanic() {
 		throw("unexpected signal during runtime execution")
 	}
 
-	switch g.sig {
+	switch gp.sig {
 	case _SIGBUS:
-		if g.sigcode0 == _BUS_ADRERR && g.sigcode1 < 0x1000 {
+		if gp.sigcode0 == _BUS_ADRERR && gp.sigcode1 < 0x1000 {
 			panicmem()
 		}
 		// Support runtime/debug.SetPanicOnFault.
-		if g.paniconfault {
-			panicmemAddr(g.sigcode1)
+		if gp.paniconfault {
+			panicmemAddr(gp.sigcode1)
 		}
-		print("unexpected fault address ", hex(g.sigcode1), "\n")
+		print("unexpected fault address ", hex(gp.sigcode1), "\n")
 		throw("fault")
 	case _SIGSEGV:
-		if (g.sigcode0 == 0 || g.sigcode0 == _SEGV_MAPERR || g.sigcode0 == _SEGV_ACCERR) && g.sigcode1 < 0x1000 {
+		if (gp.sigcode0 == 0 || gp.sigcode0 == _SEGV_MAPERR || gp.sigcode0 == _SEGV_ACCERR) && gp.sigcode1 < 0x1000 {
 			panicmem()
 		}
 		// Support runtime/debug.SetPanicOnFault.
-		if g.paniconfault {
-			panicmemAddr(g.sigcode1)
+		if gp.paniconfault {
+			panicmemAddr(gp.sigcode1)
 		}
-		print("unexpected fault address ", hex(g.sigcode1), "\n")
+		if inUserArenaChunk(gp.sigcode1) {
+			// We could check that the arena chunk is explicitly set to fault,
+			// but the fact that we faulted on accessing it is enough to prove
+			// that it is.
+			print("accessed data from freed user arena ", hex(gp.sigcode1), "\n")
+		} else {
+			print("unexpected fault address ", hex(gp.sigcode1), "\n")
+		}
 		throw("fault")
 	case _SIGFPE:
-		switch g.sigcode0 {
+		switch gp.sigcode0 {
 		case _FPE_INTDIV:
 			panicdivide()
 		case _FPE_INTOVF:
@@ -850,11 +859,11 @@
 		panicfloat()
 	}
 
-	if g.sig >= uint32(len(sigtable)) {
-		// can't happen: we looked up g.sig in sigtable to decide to call sigpanic
+	if gp.sig >= uint32(len(sigtable)) {
+		// can't happen: we looked up gp.sig in sigtable to decide to call sigpanic
 		throw("unexpected signal value")
 	}
-	panic(errorString(sigtable[g.sig].name))
+	panic(errorString(sigtable[gp.sig].name))
 }
 
 // dieFromSignal kills the program with a signal.
@@ -927,7 +936,7 @@
 	//
 	// On FreeBSD, the libthr sigaction code prevents
 	// this from working so we fall through to raise.
-	if GOOS != "freebsd" && (isarchive || islibrary) && handler == _SIG_DFL && c.sigcode() != _SI_USER {
+	if GOOS != "freebsd" && (isarchive || islibrary) && handler == _SIG_DFL && !c.sigFromUser() {
 		return
 	}
 
@@ -1030,8 +1039,6 @@
 	throw("signal received during fork")
 }
 
-var badginsignalMsg = "fatal: bad g in signal handler\n"
-
 // This runs on a foreign stack, without an m or a g. No stack split.
 //
 //go:nosplit
@@ -1042,8 +1049,7 @@
 		// There is no extra M. needm will not be able to grab
 		// an M. Instead of hanging, just crash.
 		// Cannot call split-stack function as there is no G.
-		s := stringStructOf(&badginsignalMsg)
-		write(2, s.str, int32(s.len))
+		writeErrStr("fatal: bad g in signal handler\n")
 		exit(2)
 		*(*uintptr)(unsafe.Pointer(uintptr(123))) = 2
 	}
@@ -1108,15 +1114,15 @@
 	// Unfortunately, user generated SIGPIPEs will also be forwarded, because si_code
 	// is set to _SI_USER even for a SIGPIPE raised from a write to a closed socket
 	// or pipe.
-	if (c.sigcode() == _SI_USER || flags&_SigPanic == 0) && sig != _SIGPIPE {
+	if (c.sigFromUser() || flags&_SigPanic == 0) && sig != _SIGPIPE {
 		return false
 	}
 	// Determine if the signal occurred inside Go code. We test that:
 	//   (1) we weren't in VDSO page,
 	//   (2) we were in a goroutine (i.e., m.curg != nil), and
 	//   (3) we weren't in CGO.
-	g := sigFetchG(c)
-	if g != nil && g.m != nil && g.m.curg != nil && !g.m.incgo {
+	gp := sigFetchG(c)
+	if gp != nil && gp.m != nil && gp.m.curg != nil && !gp.m.incgo {
 		return false
 	}
 
@@ -1207,15 +1213,15 @@
 // of whether it is already set). Record which choice was made in
 // newSigstack, so that it can be undone in unminit.
 func minitSignalStack() {
-	_g_ := getg()
+	mp := getg().m
 	var st stackt
 	sigaltstack(nil, &st)
 	if st.ss_flags&_SS_DISABLE != 0 || !iscgo {
-		signalstack(&_g_.m.gsignal.stack)
-		_g_.m.newSigstack = true
+		signalstack(&mp.gsignal.stack)
+		mp.newSigstack = true
 	} else {
-		setGsignalStack(&st, &_g_.m.goSigStack)
-		_g_.m.newSigstack = false
+		setGsignalStack(&st, &mp.goSigStack)
+		mp.newSigstack = false
 	}
 }
 
@@ -1297,18 +1303,18 @@
 //go:nosplit
 //go:nowritebarrierrec
 func setGsignalStack(st *stackt, old *gsignalStack) {
-	g := getg()
+	gp := getg()
 	if old != nil {
-		old.stack = g.m.gsignal.stack
-		old.stackguard0 = g.m.gsignal.stackguard0
-		old.stackguard1 = g.m.gsignal.stackguard1
-		old.stktopsp = g.m.gsignal.stktopsp
+		old.stack = gp.m.gsignal.stack
+		old.stackguard0 = gp.m.gsignal.stackguard0
+		old.stackguard1 = gp.m.gsignal.stackguard1
+		old.stktopsp = gp.m.gsignal.stktopsp
 	}
 	stsp := uintptr(unsafe.Pointer(st.ss_sp))
-	g.m.gsignal.stack.lo = stsp
-	g.m.gsignal.stack.hi = stsp + st.ss_size
-	g.m.gsignal.stackguard0 = stsp + _StackGuard
-	g.m.gsignal.stackguard1 = stsp + _StackGuard
+	gp.m.gsignal.stack.lo = stsp
+	gp.m.gsignal.stack.hi = stsp + st.ss_size
+	gp.m.gsignal.stackguard0 = stsp + _StackGuard
+	gp.m.gsignal.stackguard1 = stsp + _StackGuard
 }
 
 // restoreGsignalStack restores the gsignal stack to the value it had
@@ -1340,9 +1346,9 @@
 //go:nosplit
 //go:linkname setsigsegv
 func setsigsegv(pc uintptr) {
-	g := getg()
-	g.sig = _SIGSEGV
-	g.sigpc = pc
-	g.sigcode0 = _SEGV_MAPERR
-	g.sigcode1 = 0 // TODO: emulate si_addr
+	gp := getg()
+	gp.sig = _SIGSEGV
+	gp.sigpc = pc
+	gp.sigcode0 = _SEGV_MAPERR
+	gp.sigcode1 = 0 // TODO: emulate si_addr
 }
diff --git a/src/runtime/signal_windows.go b/src/runtime/signal_windows.go
index c5cf38c..37986cd 100644
--- a/src/runtime/signal_windows.go
+++ b/src/runtime/signal_windows.go
@@ -199,35 +199,37 @@
 	return 0 // not reached
 }
 
+// Always called on g0. gp is the G where the exception occurred.
+//
 //go:nosplit
 func winthrow(info *exceptionrecord, r *context, gp *g) {
-	_g_ := getg()
+	g0 := getg()
 
-	if panicking != 0 { // traceback already printed
+	if panicking.Load() != 0 { // traceback already printed
 		exit(2)
 	}
-	panicking = 1
+	panicking.Store(1)
 
 	// In case we're handling a g0 stack overflow, blow away the
 	// g0 stack bounds so we have room to print the traceback. If
 	// this somehow overflows the stack, the OS will trap it.
-	_g_.stack.lo = 0
-	_g_.stackguard0 = _g_.stack.lo + _StackGuard
-	_g_.stackguard1 = _g_.stackguard0
+	g0.stack.lo = 0
+	g0.stackguard0 = g0.stack.lo + _StackGuard
+	g0.stackguard1 = g0.stackguard0
 
 	print("Exception ", hex(info.exceptioncode), " ", hex(info.exceptioninformation[0]), " ", hex(info.exceptioninformation[1]), " ", hex(r.ip()), "\n")
 
 	print("PC=", hex(r.ip()), "\n")
-	if _g_.m.incgo && gp == _g_.m.g0 && _g_.m.curg != nil {
+	if g0.m.incgo && gp == g0.m.g0 && g0.m.curg != nil {
 		if iscgo {
 			print("signal arrived during external code execution\n")
 		}
-		gp = _g_.m.curg
+		gp = g0.m.curg
 	}
 	print("\n")
 
-	_g_.m.throwing = throwTypeRuntime
-	_g_.m.caughtsig.set(gp)
+	g0.m.throwing = throwTypeRuntime
+	g0.m.caughtsig.set(gp)
 
 	level, _, docrash := gotraceback()
 	if level > 0 {
@@ -244,20 +246,27 @@
 }
 
 func sigpanic() {
-	g := getg()
-	if !canpanic(g) {
+	gp := getg()
+	if !canpanic() {
 		throw("unexpected signal during runtime execution")
 	}
 
-	switch g.sig {
+	switch gp.sig {
 	case _EXCEPTION_ACCESS_VIOLATION:
-		if g.sigcode1 < 0x1000 {
+		if gp.sigcode1 < 0x1000 {
 			panicmem()
 		}
-		if g.paniconfault {
-			panicmemAddr(g.sigcode1)
+		if gp.paniconfault {
+			panicmemAddr(gp.sigcode1)
 		}
-		print("unexpected fault address ", hex(g.sigcode1), "\n")
+		if inUserArenaChunk(gp.sigcode1) {
+			// We could check that the arena chunk is explicitly set to fault,
+			// but the fact that we faulted on accessing it is enough to prove
+			// that it is.
+			print("accessed data from freed user arena ", hex(gp.sigcode1), "\n")
+		} else {
+			print("unexpected fault address ", hex(gp.sigcode1), "\n")
+		}
 		throw("fault")
 	case _EXCEPTION_INT_DIVIDE_BY_ZERO:
 		panicdivide()
diff --git a/src/runtime/signal_windows_test.go b/src/runtime/signal_windows_test.go
index add23cd..c9b8e90 100644
--- a/src/runtime/signal_windows_test.go
+++ b/src/runtime/signal_windows_test.go
@@ -1,4 +1,6 @@
-//go:build windows
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
 
 package runtime_test
 
@@ -15,6 +17,64 @@
 	"testing"
 )
 
+func TestVectoredHandlerExceptionInNonGoThread(t *testing.T) {
+	if *flagQuick {
+		t.Skip("-quick")
+	}
+	if strings.HasPrefix(testenv.Builder(), "windows-amd64-2012") {
+		testenv.SkipFlaky(t, 49681)
+	}
+	testenv.MustHaveGoBuild(t)
+	testenv.MustHaveCGO(t)
+	testenv.MustHaveExecPath(t, "gcc")
+	testprog.Lock()
+	defer testprog.Unlock()
+	dir := t.TempDir()
+
+	// build c program
+	dll := filepath.Join(dir, "veh.dll")
+	cmd := exec.Command("gcc", "-shared", "-o", dll, "testdata/testwinlibthrow/veh.c")
+	out, err := testenv.CleanCmdEnv(cmd).CombinedOutput()
+	if err != nil {
+		t.Fatalf("failed to build c exe: %s\n%s", err, out)
+	}
+
+	// build go exe
+	exe := filepath.Join(dir, "test.exe")
+	cmd = exec.Command(testenv.GoToolPath(t), "build", "-o", exe, "testdata/testwinlibthrow/main.go")
+	out, err = testenv.CleanCmdEnv(cmd).CombinedOutput()
+	if err != nil {
+		t.Fatalf("failed to build go library: %s\n%s", err, out)
+	}
+
+	// run test program in same thread
+	cmd = exec.Command(exe)
+	out, err = testenv.CleanCmdEnv(cmd).CombinedOutput()
+	if err == nil {
+		t.Fatal("error expected")
+	}
+	if _, ok := err.(*exec.ExitError); ok && len(out) > 0 {
+		if !bytes.Contains(out, []byte("Exception 0x2a")) {
+			t.Fatalf("unexpected failure while running executable: %s\n%s", err, out)
+		}
+	} else {
+		t.Fatalf("unexpected error while running executable: %s\n%s", err, out)
+	}
+	// run test program in a new thread
+	cmd = exec.Command(exe, "thread")
+	out, err = testenv.CleanCmdEnv(cmd).CombinedOutput()
+	if err == nil {
+		t.Fatal("error expected")
+	}
+	if err, ok := err.(*exec.ExitError); ok {
+		if err.ExitCode() != 42 {
+			t.Fatalf("unexpected failure while running executable: %s\n%s", err, out)
+		}
+	} else {
+		t.Fatalf("unexpected error while running executable: %s\n%s", err, out)
+	}
+}
+
 func TestVectoredHandlerDontCrashOnLibrary(t *testing.T) {
 	if *flagQuick {
 		t.Skip("-quick")
@@ -91,8 +151,8 @@
 
 	// run test program
 	cmd = exec.Command(exe)
-	var stdout bytes.Buffer
-	var stderr bytes.Buffer
+	var stdout strings.Builder
+	var stderr strings.Builder
 	cmd.Stdout = &stdout
 	cmd.Stderr = &stderr
 	inPipe, err := cmd.StdinPipe()
diff --git a/src/runtime/sigqueue.go b/src/runtime/sigqueue.go
index 49502cb..51e424d 100644
--- a/src/runtime/sigqueue.go
+++ b/src/runtime/sigqueue.go
@@ -54,8 +54,8 @@
 	wanted     [(_NSIG + 31) / 32]uint32
 	ignored    [(_NSIG + 31) / 32]uint32
 	recv       [(_NSIG + 31) / 32]uint32
-	state      uint32
-	delivering uint32
+	state      atomic.Uint32
+	delivering atomic.Uint32
 	inuse      bool
 }
 
@@ -74,11 +74,11 @@
 		return false
 	}
 
-	atomic.Xadd(&sig.delivering, 1)
+	sig.delivering.Add(1)
 	// We are running in the signal handler; defer is not available.
 
 	if w := atomic.Load(&sig.wanted[s/32]); w&bit == 0 {
-		atomic.Xadd(&sig.delivering, -1)
+		sig.delivering.Add(-1)
 		return false
 	}
 
@@ -86,7 +86,7 @@
 	for {
 		mask := sig.mask[s/32]
 		if mask&bit != 0 {
-			atomic.Xadd(&sig.delivering, -1)
+			sig.delivering.Add(-1)
 			return true // signal already in queue
 		}
 		if atomic.Cas(&sig.mask[s/32], mask, mask|bit) {
@@ -97,18 +97,18 @@
 	// Notify receiver that queue has new bit.
 Send:
 	for {
-		switch atomic.Load(&sig.state) {
+		switch sig.state.Load() {
 		default:
 			throw("sigsend: inconsistent state")
 		case sigIdle:
-			if atomic.Cas(&sig.state, sigIdle, sigSending) {
+			if sig.state.CompareAndSwap(sigIdle, sigSending) {
 				break Send
 			}
 		case sigSending:
 			// notification already pending
 			break Send
 		case sigReceiving:
-			if atomic.Cas(&sig.state, sigReceiving, sigIdle) {
+			if sig.state.CompareAndSwap(sigReceiving, sigIdle) {
 				if GOOS == "darwin" || GOOS == "ios" {
 					sigNoteWakeup(&sig.note)
 					break Send
@@ -119,7 +119,7 @@
 		}
 	}
 
-	atomic.Xadd(&sig.delivering, -1)
+	sig.delivering.Add(-1)
 	return true
 }
 
@@ -140,11 +140,11 @@
 		// Wait for updates to be available from signal sender.
 	Receive:
 		for {
-			switch atomic.Load(&sig.state) {
+			switch sig.state.Load() {
 			default:
 				throw("signal_recv: inconsistent state")
 			case sigIdle:
-				if atomic.Cas(&sig.state, sigIdle, sigReceiving) {
+				if sig.state.CompareAndSwap(sigIdle, sigReceiving) {
 					if GOOS == "darwin" || GOOS == "ios" {
 						sigNoteSleep(&sig.note)
 						break Receive
@@ -154,7 +154,7 @@
 					break Receive
 				}
 			case sigSending:
-				if atomic.Cas(&sig.state, sigSending, sigIdle) {
+				if sig.state.CompareAndSwap(sigSending, sigIdle) {
 					break Receive
 				}
 			}
@@ -182,14 +182,14 @@
 	// a signal, has read from sig.wanted, is now updating sig.mask,
 	// and has not yet woken up the processor thread. We need to wait
 	// until all current signal deliveries have completed.
-	for atomic.Load(&sig.delivering) != 0 {
+	for sig.delivering.Load() != 0 {
 		Gosched()
 	}
 
 	// Although WaitUntilIdle seems like the right name for this
 	// function, the state we are looking for is sigReceiving, not
 	// sigIdle.  The sigIdle state is really more like sigProcessing.
-	for atomic.Load(&sig.state) != sigReceiving {
+	for sig.state.Load() != sigReceiving {
 		Gosched()
 	}
 }
diff --git a/src/runtime/slice.go b/src/runtime/slice.go
index 2413a46..459dc88 100644
--- a/src/runtime/slice.go
+++ b/src/runtime/slice.go
@@ -18,7 +18,7 @@
 	cap   int
 }
 
-// A notInHeapSlice is a slice backed by go:notinheap memory.
+// A notInHeapSlice is a slice backed by runtime/internal/sys.NotInHeap memory.
 type notInHeapSlice struct {
 	array *notInHeap
 	len   int
@@ -123,92 +123,72 @@
 	return math.MulUintptr(a, b)
 }
 
-// Keep this code in sync with cmd/compile/internal/walk/builtin.go:walkUnsafeSlice
-func unsafeslice(et *_type, ptr unsafe.Pointer, len int) {
-	if len < 0 {
-		panicunsafeslicelen()
-	}
-
-	mem, overflow := math.MulUintptr(et.size, uintptr(len))
-	if overflow || mem > -uintptr(ptr) {
-		if ptr == nil {
-			panicunsafeslicenilptr()
-		}
-		panicunsafeslicelen()
-	}
-}
-
-// Keep this code in sync with cmd/compile/internal/walk/builtin.go:walkUnsafeSlice
-func unsafeslice64(et *_type, ptr unsafe.Pointer, len64 int64) {
-	len := int(len64)
-	if int64(len) != len64 {
-		panicunsafeslicelen()
-	}
-	unsafeslice(et, ptr, len)
-}
-
-func unsafeslicecheckptr(et *_type, ptr unsafe.Pointer, len64 int64) {
-	unsafeslice64(et, ptr, len64)
-
-	// Check that underlying array doesn't straddle multiple heap objects.
-	// unsafeslice64 has already checked for overflow.
-	if checkptrStraddles(ptr, uintptr(len64)*et.size) {
-		throw("checkptr: unsafe.Slice result straddles multiple allocations")
-	}
-}
-
-func panicunsafeslicelen() {
-	panic(errorString("unsafe.Slice: len out of range"))
-}
-
-func panicunsafeslicenilptr() {
-	panic(errorString("unsafe.Slice: ptr is nil and len is not zero"))
-}
-
-// growslice handles slice growth during append.
-// It is passed the slice element type, the old slice, and the desired new minimum capacity,
-// and it returns a new slice with at least that capacity, with the old data
-// copied into it.
-// The new slice's length is set to the old slice's length,
-// NOT to the new requested capacity.
-// This is for codegen convenience. The old slice's length is used immediately
-// to calculate where to write new values during an append.
-// TODO: When the old backend is gone, reconsider this decision.
-// The SSA backend might prefer the new length or to return only ptr/cap and save stack space.
-func growslice(et *_type, old slice, cap int) slice {
+// growslice allocates new backing store for a slice.
+//
+// arguments:
+//
+//	oldPtr = pointer to the slice's backing array
+//	newLen = new length (= oldLen + num)
+//	oldCap = original slice's capacity.
+//	   num = number of elements being added
+//	    et = element type
+//
+// return values:
+//
+//	newPtr = pointer to the new backing store
+//	newLen = same value as the argument
+//	newCap = capacity of the new backing store
+//
+// Requires that uint(newLen) > uint(oldCap).
+// Assumes the original slice length is newLen - num
+//
+// A new backing store is allocated with space for at least newLen elements.
+// Existing entries [0, oldLen) are copied over to the new backing store.
+// Added entries [oldLen, newLen) are not initialized by growslice
+// (although for pointer-containing element types, they are zeroed). They
+// must be initialized by the caller.
+// Trailing entries [newLen, newCap) are zeroed.
+//
+// growslice's odd calling convention makes the generated code that calls
+// this function simpler. In particular, it accepts and returns the
+// new length so that the old length is not live (does not need to be
+// spilled/restored) and the new length is returned (also does not need
+// to be spilled/restored).
+func growslice(oldPtr unsafe.Pointer, newLen, oldCap, num int, et *_type) slice {
+	oldLen := newLen - num
 	if raceenabled {
 		callerpc := getcallerpc()
-		racereadrangepc(old.array, uintptr(old.len*int(et.size)), callerpc, abi.FuncPCABIInternal(growslice))
+		racereadrangepc(oldPtr, uintptr(oldLen*int(et.size)), callerpc, abi.FuncPCABIInternal(growslice))
 	}
 	if msanenabled {
-		msanread(old.array, uintptr(old.len*int(et.size)))
+		msanread(oldPtr, uintptr(oldLen*int(et.size)))
 	}
 	if asanenabled {
-		asanread(old.array, uintptr(old.len*int(et.size)))
+		asanread(oldPtr, uintptr(oldLen*int(et.size)))
 	}
 
-	if cap < old.cap {
-		panic(errorString("growslice: cap out of range"))
+	if newLen < 0 {
+		panic(errorString("growslice: len out of range"))
 	}
 
 	if et.size == 0 {
 		// append should not create a slice with nil pointer but non-zero len.
-		// We assume that append doesn't need to preserve old.array in this case.
-		return slice{unsafe.Pointer(&zerobase), old.len, cap}
+		// We assume that append doesn't need to preserve oldPtr in this case.
+		return slice{unsafe.Pointer(&zerobase), newLen, newLen}
 	}
 
-	newcap := old.cap
+	newcap := oldCap
 	doublecap := newcap + newcap
-	if cap > doublecap {
-		newcap = cap
+	if newLen > doublecap {
+		newcap = newLen
 	} else {
 		const threshold = 256
-		if old.cap < threshold {
+		if oldCap < threshold {
 			newcap = doublecap
 		} else {
 			// Check 0 < newcap to detect overflow
 			// and prevent an infinite loop.
-			for 0 < newcap && newcap < cap {
+			for 0 < newcap && newcap < newLen {
 				// Transition from growing 2x for small slices
 				// to growing 1.25x for large slices. This formula
 				// gives a smooth-ish transition between the two.
@@ -217,7 +197,7 @@
 			// Set newcap to the requested cap when
 			// the newcap calculation overflowed.
 			if newcap <= 0 {
-				newcap = cap
+				newcap = newLen
 			}
 		}
 	}
@@ -230,14 +210,14 @@
 	// For powers of 2, use a variable shift.
 	switch {
 	case et.size == 1:
-		lenmem = uintptr(old.len)
-		newlenmem = uintptr(cap)
+		lenmem = uintptr(oldLen)
+		newlenmem = uintptr(newLen)
 		capmem = roundupsize(uintptr(newcap))
 		overflow = uintptr(newcap) > maxAlloc
 		newcap = int(capmem)
 	case et.size == goarch.PtrSize:
-		lenmem = uintptr(old.len) * goarch.PtrSize
-		newlenmem = uintptr(cap) * goarch.PtrSize
+		lenmem = uintptr(oldLen) * goarch.PtrSize
+		newlenmem = uintptr(newLen) * goarch.PtrSize
 		capmem = roundupsize(uintptr(newcap) * goarch.PtrSize)
 		overflow = uintptr(newcap) > maxAlloc/goarch.PtrSize
 		newcap = int(capmem / goarch.PtrSize)
@@ -245,21 +225,23 @@
 		var shift uintptr
 		if goarch.PtrSize == 8 {
 			// Mask shift for better code generation.
-			shift = uintptr(sys.Ctz64(uint64(et.size))) & 63
+			shift = uintptr(sys.TrailingZeros64(uint64(et.size))) & 63
 		} else {
-			shift = uintptr(sys.Ctz32(uint32(et.size))) & 31
+			shift = uintptr(sys.TrailingZeros32(uint32(et.size))) & 31
 		}
-		lenmem = uintptr(old.len) << shift
-		newlenmem = uintptr(cap) << shift
+		lenmem = uintptr(oldLen) << shift
+		newlenmem = uintptr(newLen) << shift
 		capmem = roundupsize(uintptr(newcap) << shift)
 		overflow = uintptr(newcap) > (maxAlloc >> shift)
 		newcap = int(capmem >> shift)
+		capmem = uintptr(newcap) << shift
 	default:
-		lenmem = uintptr(old.len) * et.size
-		newlenmem = uintptr(cap) * et.size
+		lenmem = uintptr(oldLen) * et.size
+		newlenmem = uintptr(newLen) * et.size
 		capmem, overflow = math.MulUintptr(et.size, uintptr(newcap))
 		capmem = roundupsize(capmem)
 		newcap = int(capmem / et.size)
+		capmem = uintptr(newcap) * et.size
 	}
 
 	// The check of overflow in addition to capmem > maxAlloc is needed
@@ -276,27 +258,48 @@
 	//   print(len(s), "\n")
 	// }
 	if overflow || capmem > maxAlloc {
-		panic(errorString("growslice: cap out of range"))
+		panic(errorString("growslice: len out of range"))
 	}
 
 	var p unsafe.Pointer
 	if et.ptrdata == 0 {
 		p = mallocgc(capmem, nil, false)
-		// The append() that calls growslice is going to overwrite from old.len to cap (which will be the new length).
+		// The append() that calls growslice is going to overwrite from oldLen to newLen.
 		// Only clear the part that will not be overwritten.
+		// The reflect_growslice() that calls growslice will manually clear
+		// the region not cleared here.
 		memclrNoHeapPointers(add(p, newlenmem), capmem-newlenmem)
 	} else {
 		// Note: can't use rawmem (which avoids zeroing of memory), because then GC can scan uninitialized memory.
 		p = mallocgc(capmem, et, true)
 		if lenmem > 0 && writeBarrier.enabled {
-			// Only shade the pointers in old.array since we know the destination slice p
+			// Only shade the pointers in oldPtr since we know the destination slice p
 			// only contains nil pointers because it has been cleared during alloc.
-			bulkBarrierPreWriteSrcOnly(uintptr(p), uintptr(old.array), lenmem-et.size+et.ptrdata)
+			bulkBarrierPreWriteSrcOnly(uintptr(p), uintptr(oldPtr), lenmem-et.size+et.ptrdata)
 		}
 	}
-	memmove(p, old.array, lenmem)
+	memmove(p, oldPtr, lenmem)
 
-	return slice{p, old.len, newcap}
+	return slice{p, newLen, newcap}
+}
+
+//go:linkname reflect_growslice reflect.growslice
+func reflect_growslice(et *_type, old slice, num int) slice {
+	// Semantically equivalent to slices.Grow, except that the caller
+	// is responsible for ensuring that old.len+num > old.cap.
+	num -= old.cap - old.len // preserve memory of old[old.len:old.cap]
+	new := growslice(old.array, old.cap+num, old.cap, num, et)
+	// growslice does not zero out new[old.cap:new.len] since it assumes that
+	// the memory will be overwritten by an append() that called growslice.
+	// Since the caller of reflect_growslice is not append(),
+	// zero out this region before returning the slice to the reflect package.
+	if et.ptrdata == 0 {
+		oldcapmem := uintptr(old.cap) * et.size
+		newlenmem := uintptr(new.len) * et.size
+		memclrNoHeapPointers(add(new.array, oldcapmem), newlenmem-oldcapmem)
+	}
+	new.len = old.len // preserve the old length
+	return new
 }
 
 func isPowerOfTwo(x uintptr) bool {
diff --git a/src/runtime/stack.go b/src/runtime/stack.go
index 2a7f0bd..d5e587a 100644
--- a/src/runtime/stack.go
+++ b/src/runtime/stack.go
@@ -98,6 +98,7 @@
 	// The guard leaves enough room for one _StackSmall frame plus
 	// a _StackLimit chain of NOSPLIT calls plus _StackSystem
 	// bytes for the OS.
+	// This arithmetic must match that in cmd/internal/objabi/stack.go:StackLimit.
 	_StackGuard = 928*sys.StackGuardMultiplier + _StackSystem
 
 	// After a stack split check the SP is allowed to be this
@@ -107,6 +108,7 @@
 
 	// The maximum number of bytes that a chain of NOSPLIT
 	// functions can use.
+	// This arithmetic must match that in cmd/internal/objabi/stack.go:StackLimit.
 	_StackLimit = _StackGuard - _StackSystem - _StackSmall
 )
 
@@ -157,11 +159,11 @@
 // There is a free list for each order.
 var stackpool [_NumStackOrders]struct {
 	item stackpoolItem
-	_    [cpu.CacheLinePadSize - unsafe.Sizeof(stackpoolItem{})%cpu.CacheLinePadSize]byte
+	_    [(cpu.CacheLinePadSize - unsafe.Sizeof(stackpoolItem{})%cpu.CacheLinePadSize) % cpu.CacheLinePadSize]byte
 }
 
-//go:notinheap
 type stackpoolItem struct {
+	_    sys.NotInHeap
 	mu   mutex
 	span mSpanList
 }
@@ -564,7 +566,7 @@
 	sghi uintptr
 }
 
-// Adjustpointer checks whether *vpp is in the old stack described by adjinfo.
+// adjustpointer checks whether *vpp is in the old stack described by adjinfo.
 // If so, it rewrites *vpp to point into the new stack.
 func adjustpointer(adjinfo *adjustinfo, vpp unsafe.Pointer) {
 	pp := (*uintptr)(vpp)
@@ -617,7 +619,7 @@
 		}
 		b := *(addb(bv.bytedata, i/8))
 		for b != 0 {
-			j := uintptr(sys.Ctz8(b))
+			j := uintptr(sys.TrailingZeros8(b))
 			b &= b - 1
 			pp := (*uintptr)(add(scanp, (i+j)*goarch.PtrSize))
 		retry:
@@ -664,7 +666,7 @@
 		return true
 	}
 
-	locals, args, objs := getStackMap(frame, &adjinfo.cache, true)
+	locals, args, objs := frame.getStackMap(&adjinfo.cache, true)
 
 	// Adjust local variables if stack frame has been allocated.
 	if locals.n > 0 {
@@ -886,7 +888,7 @@
 	// Adjust sudogs, synchronizing with channel ops if necessary.
 	ncopy := used
 	if !gp.activeStackChans {
-		if newsize < old.hi-old.lo && atomic.Load8(&gp.parkingOnChan) != 0 {
+		if newsize < old.hi-old.lo && gp.parkingOnChan.Load() {
 			// It's not safe for someone to shrink this stack while we're actively
 			// parking on a channel, but it is safe to grow since we do that
 			// ourselves and explicitly don't want to synchronize with channels
@@ -1150,7 +1152,7 @@
 	// We also can't *shrink* the stack in the window between the
 	// goroutine calling gopark to park on a channel and
 	// gp.activeStackChans being set.
-	return gp.syscallsp == 0 && !gp.asyncSafePoint && atomic.Load8(&gp.parkingOnChan) == 0
+	return gp.syscallsp == 0 && !gp.asyncSafePoint && !gp.parkingOnChan.Load()
 }
 
 // Maybe shrink the stack being used by gp.
@@ -1247,147 +1249,6 @@
 	unlock(&stackLarge.lock)
 }
 
-// getStackMap returns the locals and arguments live pointer maps, and
-// stack object list for frame.
-func getStackMap(frame *stkframe, cache *pcvalueCache, debug bool) (locals, args bitvector, objs []stackObjectRecord) {
-	targetpc := frame.continpc
-	if targetpc == 0 {
-		// Frame is dead. Return empty bitvectors.
-		return
-	}
-
-	f := frame.fn
-	pcdata := int32(-1)
-	if targetpc != f.entry() {
-		// Back up to the CALL. If we're at the function entry
-		// point, we want to use the entry map (-1), even if
-		// the first instruction of the function changes the
-		// stack map.
-		targetpc--
-		pcdata = pcdatavalue(f, _PCDATA_StackMapIndex, targetpc, cache)
-	}
-	if pcdata == -1 {
-		// We do not have a valid pcdata value but there might be a
-		// stackmap for this function. It is likely that we are looking
-		// at the function prologue, assume so and hope for the best.
-		pcdata = 0
-	}
-
-	// Local variables.
-	size := frame.varp - frame.sp
-	var minsize uintptr
-	switch goarch.ArchFamily {
-	case goarch.ARM64:
-		minsize = sys.StackAlign
-	default:
-		minsize = sys.MinFrameSize
-	}
-	if size > minsize {
-		stackid := pcdata
-		stkmap := (*stackmap)(funcdata(f, _FUNCDATA_LocalsPointerMaps))
-		if stkmap == nil || stkmap.n <= 0 {
-			print("runtime: frame ", funcname(f), " untyped locals ", hex(frame.varp-size), "+", hex(size), "\n")
-			throw("missing stackmap")
-		}
-		// If nbit == 0, there's no work to do.
-		if stkmap.nbit > 0 {
-			if stackid < 0 || stackid >= stkmap.n {
-				// don't know where we are
-				print("runtime: pcdata is ", stackid, " and ", stkmap.n, " locals stack map entries for ", funcname(f), " (targetpc=", hex(targetpc), ")\n")
-				throw("bad symbol table")
-			}
-			locals = stackmapdata(stkmap, stackid)
-			if stackDebug >= 3 && debug {
-				print("      locals ", stackid, "/", stkmap.n, " ", locals.n, " words ", locals.bytedata, "\n")
-			}
-		} else if stackDebug >= 3 && debug {
-			print("      no locals to adjust\n")
-		}
-	}
-
-	// Arguments.
-	if frame.arglen > 0 {
-		if frame.argmap != nil {
-			// argmap is set when the function is reflect.makeFuncStub or reflect.methodValueCall.
-			// In this case, arglen specifies how much of the args section is actually live.
-			// (It could be either all the args + results, or just the args.)
-			args = *frame.argmap
-			n := int32(frame.arglen / goarch.PtrSize)
-			if n < args.n {
-				args.n = n // Don't use more of the arguments than arglen.
-			}
-		} else {
-			stackmap := (*stackmap)(funcdata(f, _FUNCDATA_ArgsPointerMaps))
-			if stackmap == nil || stackmap.n <= 0 {
-				print("runtime: frame ", funcname(f), " untyped args ", hex(frame.argp), "+", hex(frame.arglen), "\n")
-				throw("missing stackmap")
-			}
-			if pcdata < 0 || pcdata >= stackmap.n {
-				// don't know where we are
-				print("runtime: pcdata is ", pcdata, " and ", stackmap.n, " args stack map entries for ", funcname(f), " (targetpc=", hex(targetpc), ")\n")
-				throw("bad symbol table")
-			}
-			if stackmap.nbit > 0 {
-				args = stackmapdata(stackmap, pcdata)
-			}
-		}
-	}
-
-	// stack objects.
-	if (GOARCH == "amd64" || GOARCH == "arm64" || GOARCH == "ppc64" || GOARCH == "ppc64le" || GOARCH == "riscv64") &&
-		unsafe.Sizeof(abi.RegArgs{}) > 0 && frame.argmap != nil {
-		// argmap is set when the function is reflect.makeFuncStub or reflect.methodValueCall.
-		// We don't actually use argmap in this case, but we need to fake the stack object
-		// record for these frames which contain an internal/abi.RegArgs at a hard-coded offset.
-		// This offset matches the assembly code on amd64 and arm64.
-		objs = methodValueCallFrameObjs[:]
-	} else {
-		p := funcdata(f, _FUNCDATA_StackObjects)
-		if p != nil {
-			n := *(*uintptr)(p)
-			p = add(p, goarch.PtrSize)
-			r0 := (*stackObjectRecord)(noescape(p))
-			objs = unsafe.Slice(r0, int(n))
-			// Note: the noescape above is needed to keep
-			// getStackMap from "leaking param content:
-			// frame".  That leak propagates up to getgcmask, then
-			// GCMask, then verifyGCInfo, which converts the stack
-			// gcinfo tests into heap gcinfo tests :(
-		}
-	}
-
-	return
-}
-
-var methodValueCallFrameObjs [1]stackObjectRecord // initialized in stackobjectinit
-
-func stkobjinit() {
-	var abiRegArgsEface any = abi.RegArgs{}
-	abiRegArgsType := efaceOf(&abiRegArgsEface)._type
-	if abiRegArgsType.kind&kindGCProg != 0 {
-		throw("abiRegArgsType needs GC Prog, update methodValueCallFrameObjs")
-	}
-	// Set methodValueCallFrameObjs[0].gcdataoff so that
-	// stackObjectRecord.gcdata() will work correctly with it.
-	ptr := uintptr(unsafe.Pointer(&methodValueCallFrameObjs[0]))
-	var mod *moduledata
-	for datap := &firstmoduledata; datap != nil; datap = datap.next {
-		if datap.gofunc <= ptr && ptr < datap.end {
-			mod = datap
-			break
-		}
-	}
-	if mod == nil {
-		throw("methodValueCallFrameObjs is not in a module")
-	}
-	methodValueCallFrameObjs[0] = stackObjectRecord{
-		off:       -int32(alignUp(abiRegArgsType.size, 8)), // It's always the highest address local.
-		size:      int32(abiRegArgsType.size),
-		_ptrdata:  int32(abiRegArgsType.ptrdata),
-		gcdataoff: uint32(uintptr(unsafe.Pointer(abiRegArgsType.gcdata)) - mod.rodata),
-	}
-}
-
 // A stackObjectRecord is generated by the compiler for each stack object in a stack frame.
 // This record must match the generator code in cmd/compile/internal/liveness/plive.go:emitStackObjects.
 type stackObjectRecord struct {
diff --git a/src/runtime/stack_test.go b/src/runtime/stack_test.go
index dfb29a9..92d5880 100644
--- a/src/runtime/stack_test.go
+++ b/src/runtime/stack_test.go
@@ -5,7 +5,6 @@
 package runtime_test
 
 import (
-	"bytes"
 	"fmt"
 	"reflect"
 	"regexp"
@@ -109,13 +108,14 @@
 
 	// in finalizer
 	var finalizerStart time.Time
-	var started, progress uint32
+	var started atomic.Bool
+	var progress atomic.Uint32
 	wg.Add(1)
 	s := new(string) // Must be of a type that avoids the tiny allocator, or else the finalizer might not run.
 	SetFinalizer(s, func(ss *string) {
 		defer wg.Done()
 		finalizerStart = time.Now()
-		atomic.StoreUint32(&started, 1)
+		started.Store(true)
 		growStack(&progress)
 	})
 	setFinalizerTime := time.Now()
@@ -128,10 +128,10 @@
 			// Panic — instead of calling t.Error and returning from the test — so
 			// that we get a useful goroutine dump if the test times out, especially
 			// if GOTRACEBACK=system or GOTRACEBACK=crash is set.
-			if atomic.LoadUint32(&started) == 0 {
+			if !started.Load() {
 				panic("finalizer did not start")
 			} else {
-				panic(fmt.Sprintf("finalizer started %s ago (%s after registration) and ran %d iterations, but did not return", time.Since(finalizerStart), finalizerStart.Sub(setFinalizerTime), atomic.LoadUint32(&progress)))
+				panic(fmt.Sprintf("finalizer started %s ago (%s after registration) and ran %d iterations, but did not return", time.Since(finalizerStart), finalizerStart.Sub(setFinalizerTime), progress.Load()))
 			}
 		})
 		defer timer.Stop()
@@ -139,7 +139,7 @@
 
 	GC()
 	wg.Wait()
-	t.Logf("finalizer started after %s and ran %d iterations in %v", finalizerStart.Sub(setFinalizerTime), atomic.LoadUint32(&progress), time.Since(finalizerStart))
+	t.Logf("finalizer started after %s and ran %d iterations in %v", finalizerStart.Sub(setFinalizerTime), progress.Load(), time.Since(finalizerStart))
 }
 
 // ... and in init
@@ -147,7 +147,7 @@
 //	growStack()
 //}
 
-func growStack(progress *uint32) {
+func growStack(progress *atomic.Uint32) {
 	n := 1 << 10
 	if testing.Short() {
 		n = 1 << 8
@@ -159,7 +159,7 @@
 			panic("stack is corrupted")
 		}
 		if progress != nil {
-			atomic.StoreUint32(progress, uint32(i))
+			progress.Store(uint32(i))
 		}
 	}
 	GC()
@@ -777,7 +777,7 @@
 	// and that we see TestTracebackSystemstack.
 	countIn, countOut := 0, 0
 	frames := CallersFrames(pcs)
-	var tb bytes.Buffer
+	var tb strings.Builder
 	for {
 		frame, more := frames.Next()
 		fmt.Fprintf(&tb, "\n%s+0x%x %s:%d", frame.Function, frame.PC-frame.Entry, frame.File, frame.Line)
diff --git a/src/runtime/start_line_amd64_test.go b/src/runtime/start_line_amd64_test.go
new file mode 100644
index 0000000..305ed0b
--- /dev/null
+++ b/src/runtime/start_line_amd64_test.go
@@ -0,0 +1,23 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime_test
+
+import (
+	"runtime/internal/startlinetest"
+	"testing"
+)
+
+// TestStartLineAsm tests the start line metadata of an assembly function. This
+// is only tested on amd64 to avoid the need for a proliferation of per-arch
+// copies of this function.
+func TestStartLineAsm(t *testing.T) {
+	startlinetest.CallerStartLine = callerStartLine
+
+	const wantLine = 23
+	got := startlinetest.AsmFunc()
+	if got != wantLine {
+		t.Errorf("start line got %d want %d", got, wantLine)
+	}
+}
diff --git a/src/runtime/start_line_test.go b/src/runtime/start_line_test.go
new file mode 100644
index 0000000..6c4faa8
--- /dev/null
+++ b/src/runtime/start_line_test.go
@@ -0,0 +1,138 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime_test
+
+import (
+	"fmt"
+	"internal/testenv"
+	"runtime"
+	"testing"
+)
+
+// The tests in this file test the function start line metadata included in
+// _func and inlinedCall. TestStartLine hard-codes the start lines of functions
+// in this file. If code moves, the test will need to be updated.
+//
+// The "start line" of a function should be the line containing the func
+// keyword.
+
+func normalFunc() int {
+	return callerStartLine(false)
+}
+
+func multilineDeclarationFunc() int {
+	return multilineDeclarationFunc1(0, 0, 0)
+}
+
+//go:noinline
+func multilineDeclarationFunc1(
+	a, b, c int) int {
+	return callerStartLine(false)
+}
+
+func blankLinesFunc() int {
+
+	// Some
+	// lines
+	// without
+	// code
+
+	return callerStartLine(false)
+}
+
+func inlineFunc() int {
+	return inlineFunc1()
+}
+
+func inlineFunc1() int {
+	return callerStartLine(true)
+}
+
+var closureFn func() int
+
+func normalClosure() int {
+	// Assign to global to ensure this isn't inlined.
+	closureFn = func() int {
+		return callerStartLine(false)
+	}
+	return closureFn()
+}
+
+func inlineClosure() int {
+	return func() int {
+		return callerStartLine(true)
+	}()
+}
+
+func TestStartLine(t *testing.T) {
+	// We test inlined vs non-inlined variants. We can't do that if
+	// optimizations are disabled.
+	testenv.SkipIfOptimizationOff(t)
+
+	testCases := []struct{
+		name string
+		fn   func() int
+		want int
+	}{
+		{
+			name: "normal",
+			fn:   normalFunc,
+			want: 21,
+		},
+		{
+			name: "multiline-declaration",
+			fn:   multilineDeclarationFunc,
+			want: 30,
+		},
+		{
+			name: "blank-lines",
+			fn:   blankLinesFunc,
+			want: 35,
+		},
+		{
+			name: "inline",
+			fn:   inlineFunc,
+			want: 49,
+		},
+		{
+			name: "normal-closure",
+			fn:   normalClosure,
+			want: 57,
+		},
+		{
+			name: "inline-closure",
+			fn:   inlineClosure,
+			want: 64,
+		},
+	}
+
+	for _, tc := range testCases {
+		t.Run(tc.name, func(t *testing.T) {
+			got := tc.fn()
+			if got != tc.want {
+				t.Errorf("start line got %d want %d", got, tc.want)
+			}
+		})
+	}
+}
+
+//go:noinline
+func callerStartLine(wantInlined bool) int {
+	var pcs [1]uintptr
+	n := runtime.Callers(2, pcs[:])
+	if n != 1 {
+		panic(fmt.Sprintf("no caller of callerStartLine? n = %d", n))
+	}
+
+	frames := runtime.CallersFrames(pcs[:])
+	frame, _ := frames.Next()
+
+	inlined := frame.Func == nil // Func always set to nil for inlined frames
+	if wantInlined != inlined {
+		panic(fmt.Sprintf("caller %s inlined got %v want %v", frame.Function, inlined, wantInlined))
+	}
+
+	return runtime.FrameStartLine(&frame)
+}
diff --git a/src/runtime/stkframe.go b/src/runtime/stkframe.go
new file mode 100644
index 0000000..3ecf3a8
--- /dev/null
+++ b/src/runtime/stkframe.go
@@ -0,0 +1,289 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+import (
+	"internal/abi"
+	"internal/goarch"
+	"runtime/internal/sys"
+	"unsafe"
+)
+
+// A stkframe holds information about a single physical stack frame.
+type stkframe struct {
+	// fn is the function being run in this frame. If there is
+	// inlining, this is the outermost function.
+	fn funcInfo
+
+	// pc is the program counter within fn.
+	//
+	// The meaning of this is subtle:
+	//
+	// - Typically, this frame performed a regular function call
+	//   and this is the return PC (just after the CALL
+	//   instruction). In this case, pc-1 reflects the CALL
+	//   instruction itself and is the correct source of symbolic
+	//   information.
+	//
+	// - If this frame "called" sigpanic, then pc is the
+	//   instruction that panicked, and pc is the correct address
+	//   to use for symbolic information.
+	//
+	// - If this is the innermost frame, then PC is where
+	//   execution will continue, but it may not be the
+	//   instruction following a CALL. This may be from
+	//   cooperative preemption, in which case this is the
+	//   instruction after the call to morestack. Or this may be
+	//   from a signal or an un-started goroutine, in which case
+	//   PC could be any instruction, including the first
+	//   instruction in a function. Conventionally, we use pc-1
+	//   for symbolic information, unless pc == fn.entry(), in
+	//   which case we use pc.
+	pc uintptr
+
+	// continpc is the PC where execution will continue in fn, or
+	// 0 if execution will not continue in this frame.
+	//
+	// This is usually the same as pc, unless this frame "called"
+	// sigpanic, in which case it's either the address of
+	// deferreturn or 0 if this frame will never execute again.
+	//
+	// This is the PC to use to look up GC liveness for this frame.
+	continpc uintptr
+
+	lr   uintptr // program counter at caller aka link register
+	sp   uintptr // stack pointer at pc
+	fp   uintptr // stack pointer at caller aka frame pointer
+	varp uintptr // top of local variables
+	argp uintptr // pointer to function arguments
+}
+
+// reflectMethodValue is a partial duplicate of reflect.makeFuncImpl
+// and reflect.methodValue.
+type reflectMethodValue struct {
+	fn     uintptr
+	stack  *bitvector // ptrmap for both args and results
+	argLen uintptr    // just args
+}
+
+// argBytes returns the argument frame size for a call to frame.fn.
+func (frame *stkframe) argBytes() uintptr {
+	if frame.fn.args != _ArgsSizeUnknown {
+		return uintptr(frame.fn.args)
+	}
+	// This is an uncommon and complicated case. Fall back to fully
+	// fetching the argument map to compute its size.
+	argMap, _ := frame.argMapInternal()
+	return uintptr(argMap.n) * goarch.PtrSize
+}
+
+// argMapInternal is used internally by stkframe to fetch special
+// argument maps.
+//
+// argMap.n is always populated with the size of the argument map.
+//
+// argMap.bytedata is only populated for dynamic argument maps (used
+// by reflect). If the caller requires the argument map, it should use
+// this if non-nil, and otherwise fetch the argument map using the
+// current PC.
+//
+// hasReflectStackObj indicates that this frame also has a reflect
+// function stack object, which the caller must synthesize.
+func (frame *stkframe) argMapInternal() (argMap bitvector, hasReflectStackObj bool) {
+	f := frame.fn
+	if f.args != _ArgsSizeUnknown {
+		argMap.n = f.args / goarch.PtrSize
+		return
+	}
+	// Extract argument bitmaps for reflect stubs from the calls they made to reflect.
+	switch funcname(f) {
+	case "reflect.makeFuncStub", "reflect.methodValueCall":
+		// These take a *reflect.methodValue as their
+		// context register and immediately save it to 0(SP).
+		// Get the methodValue from 0(SP).
+		arg0 := frame.sp + sys.MinFrameSize
+
+		minSP := frame.fp
+		if !usesLR {
+			// The CALL itself pushes a word.
+			// Undo that adjustment.
+			minSP -= goarch.PtrSize
+		}
+		if arg0 >= minSP {
+			// The function hasn't started yet.
+			// This only happens if f was the
+			// start function of a new goroutine
+			// that hasn't run yet *and* f takes
+			// no arguments and has no results
+			// (otherwise it will get wrapped in a
+			// closure). In this case, we can't
+			// reach into its locals because it
+			// doesn't have locals yet, but we
+			// also know its argument map is
+			// empty.
+			if frame.pc != f.entry() {
+				print("runtime: confused by ", funcname(f), ": no frame (sp=", hex(frame.sp), " fp=", hex(frame.fp), ") at entry+", hex(frame.pc-f.entry()), "\n")
+				throw("reflect mismatch")
+			}
+			return bitvector{}, false // No locals, so also no stack objects
+		}
+		hasReflectStackObj = true
+		mv := *(**reflectMethodValue)(unsafe.Pointer(arg0))
+		// Figure out whether the return values are valid.
+		// Reflect will update this value after it copies
+		// in the return values.
+		retValid := *(*bool)(unsafe.Pointer(arg0 + 4*goarch.PtrSize))
+		if mv.fn != f.entry() {
+			print("runtime: confused by ", funcname(f), "\n")
+			throw("reflect mismatch")
+		}
+		argMap = *mv.stack
+		if !retValid {
+			// argMap.n includes the results, but
+			// those aren't valid, so drop them.
+			n := int32((uintptr(mv.argLen) &^ (goarch.PtrSize - 1)) / goarch.PtrSize)
+			if n < argMap.n {
+				argMap.n = n
+			}
+		}
+	}
+	return
+}
+
+// getStackMap returns the locals and arguments live pointer maps, and
+// stack object list for frame.
+func (frame *stkframe) getStackMap(cache *pcvalueCache, debug bool) (locals, args bitvector, objs []stackObjectRecord) {
+	targetpc := frame.continpc
+	if targetpc == 0 {
+		// Frame is dead. Return empty bitvectors.
+		return
+	}
+
+	f := frame.fn
+	pcdata := int32(-1)
+	if targetpc != f.entry() {
+		// Back up to the CALL. If we're at the function entry
+		// point, we want to use the entry map (-1), even if
+		// the first instruction of the function changes the
+		// stack map.
+		targetpc--
+		pcdata = pcdatavalue(f, _PCDATA_StackMapIndex, targetpc, cache)
+	}
+	if pcdata == -1 {
+		// We do not have a valid pcdata value but there might be a
+		// stackmap for this function. It is likely that we are looking
+		// at the function prologue, assume so and hope for the best.
+		pcdata = 0
+	}
+
+	// Local variables.
+	size := frame.varp - frame.sp
+	var minsize uintptr
+	switch goarch.ArchFamily {
+	case goarch.ARM64:
+		minsize = sys.StackAlign
+	default:
+		minsize = sys.MinFrameSize
+	}
+	if size > minsize {
+		stackid := pcdata
+		stkmap := (*stackmap)(funcdata(f, _FUNCDATA_LocalsPointerMaps))
+		if stkmap == nil || stkmap.n <= 0 {
+			print("runtime: frame ", funcname(f), " untyped locals ", hex(frame.varp-size), "+", hex(size), "\n")
+			throw("missing stackmap")
+		}
+		// If nbit == 0, there's no work to do.
+		if stkmap.nbit > 0 {
+			if stackid < 0 || stackid >= stkmap.n {
+				// don't know where we are
+				print("runtime: pcdata is ", stackid, " and ", stkmap.n, " locals stack map entries for ", funcname(f), " (targetpc=", hex(targetpc), ")\n")
+				throw("bad symbol table")
+			}
+			locals = stackmapdata(stkmap, stackid)
+			if stackDebug >= 3 && debug {
+				print("      locals ", stackid, "/", stkmap.n, " ", locals.n, " words ", locals.bytedata, "\n")
+			}
+		} else if stackDebug >= 3 && debug {
+			print("      no locals to adjust\n")
+		}
+	}
+
+	// Arguments. First fetch frame size and special-case argument maps.
+	var isReflect bool
+	args, isReflect = frame.argMapInternal()
+	if args.n > 0 && args.bytedata == nil {
+		// Non-empty argument frame, but not a special map.
+		// Fetch the argument map at pcdata.
+		stackmap := (*stackmap)(funcdata(f, _FUNCDATA_ArgsPointerMaps))
+		if stackmap == nil || stackmap.n <= 0 {
+			print("runtime: frame ", funcname(f), " untyped args ", hex(frame.argp), "+", hex(args.n*goarch.PtrSize), "\n")
+			throw("missing stackmap")
+		}
+		if pcdata < 0 || pcdata >= stackmap.n {
+			// don't know where we are
+			print("runtime: pcdata is ", pcdata, " and ", stackmap.n, " args stack map entries for ", funcname(f), " (targetpc=", hex(targetpc), ")\n")
+			throw("bad symbol table")
+		}
+		if stackmap.nbit == 0 {
+			args.n = 0
+		} else {
+			args = stackmapdata(stackmap, pcdata)
+		}
+	}
+
+	// stack objects.
+	if (GOARCH == "amd64" || GOARCH == "arm64" || GOARCH == "ppc64" || GOARCH == "ppc64le" || GOARCH == "riscv64") &&
+		unsafe.Sizeof(abi.RegArgs{}) > 0 && isReflect {
+		// For reflect.makeFuncStub and reflect.methodValueCall,
+		// we need to fake the stack object record.
+		// These frames contain an internal/abi.RegArgs at a hard-coded offset.
+		// This offset matches the assembly code on amd64 and arm64.
+		objs = methodValueCallFrameObjs[:]
+	} else {
+		p := funcdata(f, _FUNCDATA_StackObjects)
+		if p != nil {
+			n := *(*uintptr)(p)
+			p = add(p, goarch.PtrSize)
+			r0 := (*stackObjectRecord)(noescape(p))
+			objs = unsafe.Slice(r0, int(n))
+			// Note: the noescape above is needed to keep
+			// getStackMap from "leaking param content:
+			// frame".  That leak propagates up to getgcmask, then
+			// GCMask, then verifyGCInfo, which converts the stack
+			// gcinfo tests into heap gcinfo tests :(
+		}
+	}
+
+	return
+}
+
+var methodValueCallFrameObjs [1]stackObjectRecord // initialized in stackobjectinit
+
+func stkobjinit() {
+	var abiRegArgsEface any = abi.RegArgs{}
+	abiRegArgsType := efaceOf(&abiRegArgsEface)._type
+	if abiRegArgsType.kind&kindGCProg != 0 {
+		throw("abiRegArgsType needs GC Prog, update methodValueCallFrameObjs")
+	}
+	// Set methodValueCallFrameObjs[0].gcdataoff so that
+	// stackObjectRecord.gcdata() will work correctly with it.
+	ptr := uintptr(unsafe.Pointer(&methodValueCallFrameObjs[0]))
+	var mod *moduledata
+	for datap := &firstmoduledata; datap != nil; datap = datap.next {
+		if datap.gofunc <= ptr && ptr < datap.end {
+			mod = datap
+			break
+		}
+	}
+	if mod == nil {
+		throw("methodValueCallFrameObjs is not in a module")
+	}
+	methodValueCallFrameObjs[0] = stackObjectRecord{
+		off:       -int32(alignUp(abiRegArgsType.size, 8)), // It's always the highest address local.
+		size:      int32(abiRegArgsType.size),
+		_ptrdata:  int32(abiRegArgsType.ptrdata),
+		gcdataoff: uint32(uintptr(unsafe.Pointer(abiRegArgsType.gcdata)) - mod.rodata),
+	}
+}
diff --git a/src/runtime/string.go b/src/runtime/string.go
index 359a565..a00976b 100644
--- a/src/runtime/string.go
+++ b/src/runtime/string.go
@@ -78,7 +78,7 @@
 // n is the length of the slice.
 // Buf is a fixed-size buffer for the result,
 // it is not nil if the result does not escape.
-func slicebytetostring(buf *tmpBuf, ptr *byte, n int) (str string) {
+func slicebytetostring(buf *tmpBuf, ptr *byte, n int) string {
 	if n == 0 {
 		// Turns out to be a relatively common case.
 		// Consider that you want to parse out data between parens in "foo()bar",
@@ -102,9 +102,7 @@
 		if goarch.BigEndian {
 			p = add(p, 7)
 		}
-		stringStructOf(&str).str = p
-		stringStructOf(&str).len = 1
-		return
+		return unsafe.String((*byte)(p), 1)
 	}
 
 	var p unsafe.Pointer
@@ -113,16 +111,14 @@
 	} else {
 		p = mallocgc(uintptr(n), nil, false)
 	}
-	stringStructOf(&str).str = p
-	stringStructOf(&str).len = n
 	memmove(p, unsafe.Pointer(ptr), uintptr(n))
-	return
+	return unsafe.String((*byte)(p), n)
 }
 
 // stringDataOnStack reports whether the string's data is
 // stored on the current goroutine's stack.
 func stringDataOnStack(s string) bool {
-	ptr := uintptr(stringStructOf(&s).str)
+	ptr := uintptr(unsafe.Pointer(unsafe.StringData(s)))
 	stk := getg().stack
 	return stk.lo <= ptr && ptr < stk.hi
 }
@@ -151,7 +147,7 @@
 //     where k is []byte, T1 to Tn is a nesting of struct and array literals.
 //   - Used for "<"+string(b)+">" concatenation where b is []byte.
 //   - Used for string(b)=="foo" comparison where b is []byte.
-func slicebytetostringtmp(ptr *byte, n int) (str string) {
+func slicebytetostringtmp(ptr *byte, n int) string {
 	if raceenabled && n > 0 {
 		racereadrangepc(unsafe.Pointer(ptr),
 			uintptr(n),
@@ -164,9 +160,7 @@
 	if asanenabled && n > 0 {
 		asanread(unsafe.Pointer(ptr), uintptr(n))
 	}
-	stringStructOf(&str).str = unsafe.Pointer(ptr)
-	stringStructOf(&str).len = n
-	return
+	return unsafe.String(ptr, n)
 }
 
 func stringtoslicebyte(buf *tmpBuf, s string) []byte {
@@ -271,13 +265,7 @@
 // b to set the string contents and then drop b.
 func rawstring(size int) (s string, b []byte) {
 	p := mallocgc(uintptr(size), nil, false)
-
-	stringStructOf(&s).str = p
-	stringStructOf(&s).len = size
-
-	*(*slice)(unsafe.Pointer(&b)) = slice{p, size, size}
-
-	return
+	return unsafe.String((*byte)(p), size), unsafe.Slice((*byte)(p), size)
 }
 
 // rawbyteslice allocates a new byte slice. The byte slice is not zeroed.
@@ -337,6 +325,13 @@
 	return s
 }
 
+// internal_syscall_gostring is a version of gostring for internal/syscall/unix.
+//
+//go:linkname internal_syscall_gostring internal/syscall/unix.gostring
+func internal_syscall_gostring(p *byte) string {
+	return gostring(p)
+}
+
 func gostringn(p *byte, l int) string {
 	if l == 0 {
 		return ""
diff --git a/src/runtime/string_test.go b/src/runtime/string_test.go
index 1ea7f5e..cfc0ad7 100644
--- a/src/runtime/string_test.go
+++ b/src/runtime/string_test.go
@@ -223,6 +223,19 @@
 	}
 }
 
+func TestConcatTempString(t *testing.T) {
+	s := "bytes"
+	b := []byte(s)
+	n := testing.AllocsPerRun(1000, func() {
+		if "prefix "+string(b)+" suffix" != "prefix bytes suffix" {
+			t.Fatalf("strings are not equal: '%v' and '%v'", "prefix "+string(b)+" suffix", "prefix bytes suffix")
+		}
+	})
+	if n != 0 {
+		t.Fatalf("want 0 allocs, got %v", n)
+	}
+}
+
 func TestCompareTempString(t *testing.T) {
 	s := strings.Repeat("x", sizeNoStack)
 	b := []byte(s)
@@ -230,10 +243,24 @@
 		if string(b) != s {
 			t.Fatalf("strings are not equal: '%v' and '%v'", string(b), s)
 		}
+		if string(b) < s {
+			t.Fatalf("strings are not equal: '%v' and '%v'", string(b), s)
+		}
+		if string(b) > s {
+			t.Fatalf("strings are not equal: '%v' and '%v'", string(b), s)
+		}
 		if string(b) == s {
 		} else {
 			t.Fatalf("strings are not equal: '%v' and '%v'", string(b), s)
 		}
+		if string(b) <= s {
+		} else {
+			t.Fatalf("strings are not equal: '%v' and '%v'", string(b), s)
+		}
+		if string(b) >= s {
+		} else {
+			t.Fatalf("strings are not equal: '%v' and '%v'", string(b), s)
+		}
 	})
 	if n != 0 {
 		t.Fatalf("want 0 allocs, got %v", n)
diff --git a/src/runtime/stubs.go b/src/runtime/stubs.go
index 929f8fa..42c2612 100644
--- a/src/runtime/stubs.go
+++ b/src/runtime/stubs.go
@@ -59,13 +59,10 @@
 //go:noescape
 func systemstack(fn func())
 
-var badsystemstackMsg = "fatal: systemstack called from unexpected goroutine"
-
 //go:nosplit
 //go:nowritebarrierrec
 func badsystemstack() {
-	sp := stringStructOf(&badsystemstackMsg)
-	write(2, sp.str, int32(sp.len))
+	writeErrStr("fatal: systemstack called from unexpected goroutine")
 }
 
 // memclrNoHeapPointers clears n bytes starting at ptr.
@@ -131,7 +128,7 @@
 	// by the compiler should be in this list.
 	if goarch.IsAmd64|goarch.IsArm64|goarch.IsPpc64|
 		goarch.IsPpc64le|goarch.IsMips64|goarch.IsMips64le|
-		goarch.IsS390x|goarch.IsRiscv64 == 1 {
+		goarch.IsS390x|goarch.IsRiscv64|goarch.IsLoong64 == 1 {
 		mp.fastrand += 0xa0761d6478bd642f
 		hi, lo := math.Mul64(mp.fastrand, mp.fastrand^0xe7037ed1a0b428db)
 		return uint32(hi ^ lo)
@@ -196,6 +193,9 @@
 	return uint(fastrand64())
 }
 
+//go:linkname rand_fastrand64 math/rand.fastrand64
+func rand_fastrand64() uint64 { return fastrand64() }
+
 //go:linkname sync_fastrandn sync.fastrandn
 func sync_fastrandn(n uint32) uint32 { return fastrandn(n) }
 
diff --git a/src/runtime/stubs2.go b/src/runtime/stubs2.go
index 94a888d..0d83deb 100644
--- a/src/runtime/stubs2.go
+++ b/src/runtime/stubs2.go
@@ -6,7 +6,10 @@
 
 package runtime
 
-import "unsafe"
+import (
+	"runtime/internal/atomic"
+	"unsafe"
+)
 
 // read calls the read system call.
 // It returns a non-negative number of bytes written or a negative errno value.
@@ -22,7 +25,7 @@
 	usleep(usec)
 }
 
-// write calls the write system call.
+// write1 calls the write system call.
 // It returns a non-negative number of bytes written or a negative errno value.
 //
 //go:noescape
@@ -31,11 +34,11 @@
 //go:noescape
 func open(name *byte, mode, perm int32) int32
 
-// return value is only set on linux to be used in osinit()
+// return value is only set on linux to be used in osinit().
 func madvise(addr unsafe.Pointer, n uintptr, flags int32) int32
 
-// exitThread terminates the current thread, writing *wait = 0 when
+// exitThread terminates the current thread, writing *wait = freeMStack when
 // the stack is safe to reclaim.
 //
 //go:noescape
-func exitThread(wait *uint32)
+func exitThread(wait *atomic.Uint32)
diff --git a/src/runtime/stubs_ppc64.go b/src/runtime/stubs_ppc64.go
index 6919b74..e23e338 100644
--- a/src/runtime/stubs_ppc64.go
+++ b/src/runtime/stubs_ppc64.go
@@ -6,7 +6,7 @@
 
 package runtime
 
-// This is needed for vet
+// This is needed for vet.
 //
 //go:noescape
 func callCgoSigaction(sig uintptr, new, old *sigactiont) int32
diff --git a/src/runtime/symtab.go b/src/runtime/symtab.go
index ad34b68..dead27e 100644
--- a/src/runtime/symtab.go
+++ b/src/runtime/symtab.go
@@ -49,6 +49,15 @@
 	File string
 	Line int
 
+	// startLine is the line number of the beginning of the function in
+	// this frame. Specifically, it is the line number of the func keyword
+	// for Go functions. Note that //line directives can change the
+	// filename and/or line number arbitrarily within a function, meaning
+	// that the Line - startLine offset is not always meaningful.
+	//
+	// This may be zero if not known.
+	startLine int
+
 	// Entry point program counter for the function; may be zero
 	// if not known. If Func is not nil then Entry ==
 	// Func.Entry().
@@ -108,6 +117,7 @@
 			pc--
 		}
 		name := funcname(funcInfo)
+		startLine := f.startLine()
 		if inldata := funcdata(funcInfo, _FUNCDATA_InlTree); inldata != nil {
 			inltree := (*[1 << 20]inlinedCall)(inldata)
 			// Non-strict as cgoTraceback may have added bogus PCs
@@ -116,17 +126,19 @@
 			if ix >= 0 {
 				// Note: entry is not modified. It always refers to a real frame, not an inlined one.
 				f = nil
-				name = funcnameFromNameoff(funcInfo, inltree[ix].func_)
-				// File/line is already correct.
-				// TODO: remove file/line from InlinedCall?
+				ic := inltree[ix]
+				name = funcnameFromNameOff(funcInfo, ic.nameOff)
+				startLine = ic.startLine
+				// File/line from funcline1 below are already correct.
 			}
 		}
 		ci.frames = append(ci.frames, Frame{
-			PC:       pc,
-			Func:     f,
-			Function: name,
-			Entry:    entry,
-			funcInfo: funcInfo,
+			PC:        pc,
+			Func:      f,
+			Function:  name,
+			Entry:     entry,
+			startLine: int(startLine),
+			funcInfo:  funcInfo,
 			// Note: File,Line set below
 		})
 	}
@@ -158,6 +170,13 @@
 	return
 }
 
+// runtime_FrameStartLine returns the start line of the function in a Frame.
+//
+//go:linkname runtime_FrameStartLine runtime/pprof.runtime_FrameStartLine
+func runtime_FrameStartLine(f *Frame) int {
+	return f.startLine
+}
+
 // runtime_expandFinalInlineFrame expands the final pc in stk to include all
 // "callers" if pc is inline.
 //
@@ -393,7 +412,7 @@
 
 // pcHeader holds data used by the pclntab lookups.
 type pcHeader struct {
-	magic          uint32  // 0xFFFFFFF0
+	magic          uint32  // 0xFFFFFFF1
 	pad1, pad2     uint8   // 0,0
 	minLC          uint8   // min instruction size
 	ptrSize        uint8   // size of a ptr in bytes
@@ -428,6 +447,7 @@
 	data, edata           uintptr
 	bss, ebss             uintptr
 	noptrbss, enoptrbss   uintptr
+	covctrs, ecovctrs     uintptr
 	end, gcdata, gcbss    uintptr
 	types, etypes         uintptr
 	rodata                uintptr
@@ -575,7 +595,7 @@
 const minfunc = 16                 // minimum function size
 const pcbucketsize = 256 * minfunc // size of bucket in the pc->func lookup table
 
-// findfunctab is an array of these structures.
+// findfuncbucket is an array of these structures.
 // Each bucket represents 4096 bytes of the text segment.
 // Each subbucket represents 256 bytes of the text segment.
 // To find a function given a pc, locate the bucket and subbucket for
@@ -599,7 +619,7 @@
 func moduledataverify1(datap *moduledata) {
 	// Check that the pclntab's format is valid.
 	hdr := datap.pcHeader
-	if hdr.magic != 0xfffffff0 || hdr.pad1 != 0 || hdr.pad2 != 0 ||
+	if hdr.magic != 0xfffffff1 || hdr.pad1 != 0 || hdr.pad2 != 0 ||
 		hdr.minLC != sys.PCQuantum || hdr.ptrSize != goarch.PtrSize || hdr.textStart != datap.text {
 		println("runtime: pcHeader: magic=", hex(hdr.magic), "pad1=", hdr.pad1, "pad2=", hdr.pad2,
 			"minLC=", hdr.minLC, "ptrSize=", hdr.ptrSize, "pcHeader.textStart=", hex(hdr.textStart),
@@ -727,14 +747,16 @@
 		// The runtime currently doesn't have function end info, alas.
 		if ix := pcdatavalue1(f, _PCDATA_InlTreeIndex, pc, nil, false); ix >= 0 {
 			inltree := (*[1 << 20]inlinedCall)(inldata)
-			name := funcnameFromNameoff(f, inltree[ix].func_)
+			ic := inltree[ix]
+			name := funcnameFromNameOff(f, ic.nameOff)
 			file, line := funcline(f, pc)
 			fi := &funcinl{
-				ones:  ^uint32(0),
-				entry: f.entry(), // entry of the real (the outermost) function.
-				name:  name,
-				file:  file,
-				line:  int(line),
+				ones:      ^uint32(0),
+				entry:     f.entry(), // entry of the real (the outermost) function.
+				name:      name,
+				file:      file,
+				line:      line,
+				startLine: ic.startLine,
 			}
 			return (*Func)(unsafe.Pointer(fi))
 		}
@@ -773,7 +795,7 @@
 	fn := f.raw()
 	if fn.isInlined() { // inlined version
 		fi := (*funcinl)(unsafe.Pointer(fn))
-		return fi.file, fi.line
+		return fi.file, int(fi.line)
 	}
 	// Pass strict=false here, because anyone can call this function,
 	// and they might just be wrong about targetpc belonging to f.
@@ -781,6 +803,17 @@
 	return file, int(line32)
 }
 
+// startLine returns the starting line number of the function. i.e., the line
+// number of the func keyword.
+func (f *Func) startLine() int32 {
+	fn := f.raw()
+	if fn.isInlined() { // inlined version
+		fi := (*funcinl)(unsafe.Pointer(fn))
+		return fi.startLine
+	}
+	return fn.funcInfo().startLine
+}
+
 // findmoduledatap looks up the moduledata for a PC.
 //
 // It is nosplit because it's part of the isgoexception
@@ -811,12 +844,12 @@
 
 // isInlined reports whether f should be re-interpreted as a *funcinl.
 func (f *_func) isInlined() bool {
-	return f.entryoff == ^uint32(0) // see comment for funcinl.ones
+	return f.entryOff == ^uint32(0) // see comment for funcinl.ones
 }
 
 // entry returns the entry PC for f.
 func (f funcInfo) entry() uintptr {
-	return f.datap.textAddr(f.entryoff)
+	return f.datap.textAddr(f.entryOff)
 }
 
 // findfunc looks up function metadata for a PC.
@@ -902,7 +935,7 @@
 	}
 
 	if !f.valid() {
-		if strict && panicking == 0 {
+		if strict && panicking.Load() == 0 {
 			println("runtime: no module data for", hex(f.entry()))
 			throw("no module data")
 		}
@@ -945,7 +978,7 @@
 
 	// If there was a table, it should have covered all program counters.
 	// If not, something is wrong.
-	if panicking != 0 || !strict {
+	if panicking.Load() != 0 || !strict {
 		return -1, 0
 	}
 
@@ -968,10 +1001,10 @@
 }
 
 func cfuncname(f funcInfo) *byte {
-	if !f.valid() || f.nameoff == 0 {
+	if !f.valid() || f.nameOff == 0 {
 		return nil
 	}
-	return &f.datap.funcnametab[f.nameoff]
+	return &f.datap.funcnametab[f.nameOff]
 }
 
 func funcname(f funcInfo) string {
@@ -994,15 +1027,15 @@
 	return name[:i]
 }
 
-func cfuncnameFromNameoff(f funcInfo, nameoff int32) *byte {
+func cfuncnameFromNameOff(f funcInfo, nameOff int32) *byte {
 	if !f.valid() {
 		return nil
 	}
-	return &f.datap.funcnametab[nameoff]
+	return &f.datap.funcnametab[nameOff]
 }
 
-func funcnameFromNameoff(f funcInfo, nameoff int32) string {
-	return gostringnocopy(cfuncnameFromNameoff(f, nameoff))
+func funcnameFromNameOff(f funcInfo, nameOff int32) string {
+	return gostringnocopy(cfuncnameFromNameOff(f, nameOff))
 }
 
 func funcfile(f funcInfo, fileno int32) string {
@@ -1173,11 +1206,9 @@
 
 // inlinedCall is the encoding of entries in the FUNCDATA_InlTree table.
 type inlinedCall struct {
-	parent   int16  // index of parent in the inltree, or < 0
-	funcID   funcID // type of the called function
-	_        byte
-	file     int32 // perCU file index for inlined call. See cmd/link:pcln.go
-	line     int32 // line number of the call site
-	func_    int32 // offset into pclntab for name of called function
-	parentPc int32 // position of an instruction whose source position is the call site (offset from entry)
+	funcID    funcID // type of the called function
+	_         [3]byte
+	nameOff   int32 // offset into pclntab for name of called function
+	parentPc  int32 // position of an instruction whose source position is the call site (offset from entry)
+	startLine int32 // line number of start of function (func keyword/TEXT directive)
 }
diff --git a/src/runtime/sys_darwin.go b/src/runtime/sys_darwin.go
index 1547fdc..5ba697e 100644
--- a/src/runtime/sys_darwin.go
+++ b/src/runtime/sys_darwin.go
@@ -6,6 +6,7 @@
 
 import (
 	"internal/abi"
+	"runtime/internal/atomic"
 	"unsafe"
 )
 
@@ -48,6 +49,17 @@
 }
 func syscall6()
 
+//go:linkname syscall_syscall9 syscall.syscall9
+//go:nosplit
+//go:cgo_unsafe_args
+func syscall_syscall9(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2, err uintptr) {
+	entersyscall()
+	libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall9)), unsafe.Pointer(&fn))
+	exitsyscall()
+	return
+}
+func syscall9()
+
 //go:linkname syscall_syscall6X syscall.syscall6X
 //go:nosplit
 func syscall_syscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
@@ -86,7 +98,7 @@
 	return args.r1, args.r2, args.err
 }
 
-// syscallNoErr is used in crypto/x509 to call into Security.framework and CF.
+// crypto_x509_syscall is used in crypto/x509/internal/macos to call into Security.framework and CF.
 
 //go:linkname crypto_x509_syscall crypto/x509/internal/macos.syscall
 //go:nosplit
@@ -167,6 +179,47 @@
 }
 func pthread_kill_trampoline()
 
+// osinit_hack is a clumsy hack to work around Apple libc bugs
+// causing fork+exec to hang in the child process intermittently.
+// See go.dev/issue/33565 and go.dev/issue/56784 for a few reports.
+//
+// The stacks obtained from the hung child processes are in
+// libSystem_atfork_child, which is supposed to reinitialize various
+// parts of the C library in the new process.
+//
+// One common stack dies in _notify_fork_child calling _notify_globals
+// (inlined) calling _os_alloc_once, because _os_alloc_once detects that
+// the once lock is held by the parent process and then calls
+// _os_once_gate_corruption_abort. The allocation is setting up the
+// globals for the notification subsystem. See the source code at [1].
+// To work around this, we can allocate the globals earlier in the Go
+// program's lifetime, before any execs are involved, by calling any
+// notify routine that is exported, calls _notify_globals, and doesn't do
+// anything too expensive otherwise. notify_is_valid_token(0) fits the bill.
+//
+// The other common stack dies in xpc_atfork_child calling
+// _objc_msgSend_uncached which ends up in
+// WAITING_FOR_ANOTHER_THREAD_TO_FINISH_CALLING_+initialize. Of course,
+// whatever thread the child is waiting for is in the parent process and
+// is not going to finish anything in the child process. There is no
+// public source code for these routines, so it is unclear exactly what
+// the problem is. An Apple engineer suggests using xpc_date_create_from_current,
+// which empirically does fix the problem.
+//
+// So osinit_hack_trampoline (in sys_darwin_$GOARCH.s) calls
+// notify_is_valid_token(0) and xpc_date_create_from_current(), which makes the
+// fork+exec hangs stop happening. If Apple fixes the libc bug in
+// some future version of macOS, then we can remove this awful code.
+//
+//go:nosplit
+func osinit_hack() {
+	if GOOS == "darwin" { // not ios
+		libcCall(unsafe.Pointer(abi.FuncPCABI0(osinit_hack_trampoline)), nil)
+	}
+	return
+}
+func osinit_hack_trampoline()
+
 // mmap is used to do low-level memory allocation via mmap. Don't allow stack
 // splits, since this function (used by sysAlloc) is called in a lot of low-level
 // parts of the runtime and callers often assume it won't acquire any locks.
@@ -474,7 +527,8 @@
 func pthread_cond_signal_trampoline()
 
 // Not used on Darwin, but must be defined.
-func exitThread(wait *uint32) {
+func exitThread(wait *atomic.Uint32) {
+	throw("exitThread")
 }
 
 //go:nosplit
@@ -535,3 +589,6 @@
 //go:cgo_import_dynamic libc_pthread_cond_wait pthread_cond_wait "/usr/lib/libSystem.B.dylib"
 //go:cgo_import_dynamic libc_pthread_cond_timedwait_relative_np pthread_cond_timedwait_relative_np "/usr/lib/libSystem.B.dylib"
 //go:cgo_import_dynamic libc_pthread_cond_signal pthread_cond_signal "/usr/lib/libSystem.B.dylib"
+
+//go:cgo_import_dynamic libc_notify_is_valid_token notify_is_valid_token "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_xpc_date_create_from_current xpc_date_create_from_current "/usr/lib/libSystem.B.dylib"
diff --git a/src/runtime/sys_darwin_amd64.s b/src/runtime/sys_darwin_amd64.s
index ba81fcc..6eaeeb9 100644
--- a/src/runtime/sys_darwin_amd64.s
+++ b/src/runtime/sys_darwin_amd64.s
@@ -597,6 +597,15 @@
 	POPQ	BP
 	RET
 
+TEXT runtime·osinit_hack_trampoline(SB),NOSPLIT,$0
+	PUSHQ	BP
+	MOVQ	SP, BP
+	MOVQ	$0, DI	// arg 1 val
+	CALL	libc_notify_is_valid_token(SB)
+	CALL	libc_xpc_date_create_from_current(SB)
+	POPQ	BP
+	RET
+
 // syscall calls a function in libc on behalf of the syscall package.
 // syscall takes a pointer to a struct like:
 // struct {
@@ -839,6 +848,65 @@
 	POPQ	BP
 	RET
 
+// syscall9 calls a function in libc on behalf of the syscall package.
+// syscall9 takes a pointer to a struct like:
+// struct {
+//	fn    uintptr
+//	a1    uintptr
+//	a2    uintptr
+//	a3    uintptr
+//	a4    uintptr
+//	a5    uintptr
+//	a6    uintptr
+//	a7    uintptr
+//	a8    uintptr
+//	a9    uintptr
+//	r1    uintptr
+//	r2    uintptr
+//	err   uintptr
+// }
+// syscall9 must be called on the g0 stack with the
+// C calling convention (use libcCall).
+//
+// syscall9 expects a 32-bit result and tests for 32-bit -1
+// to decide there was an error.
+TEXT runtime·syscall9(SB),NOSPLIT,$0
+	PUSHQ	BP
+	MOVQ	SP, BP
+	SUBQ	$16, SP
+	MOVQ	(0*8)(DI), R13// fn
+	MOVQ	(2*8)(DI), SI // a2
+	MOVQ	(3*8)(DI), DX // a3
+	MOVQ	(4*8)(DI), CX // a4
+	MOVQ	(5*8)(DI), R8 // a5
+	MOVQ	(6*8)(DI), R9 // a6
+	MOVQ	(7*8)(DI), R10 // a7
+	MOVQ	(8*8)(DI), R11 // a8
+	MOVQ	(9*8)(DI), R12 // a9
+	MOVQ	DI, (SP)
+	MOVQ	(1*8)(DI), DI // a1
+	XORL	AX, AX	      // vararg: say "no float args"
+
+	CALL	R13
+
+	MOVQ	(SP), DI
+	MOVQ	AX, (10*8)(DI) // r1
+	MOVQ	DX, (11*8)(DI) // r2
+
+	CMPL	AX, $-1
+	JNE	ok
+
+	CALL	libc_error(SB)
+	MOVLQSX	(AX), AX
+	MOVQ	(SP), DI
+	MOVQ	AX, (12*8)(DI) // err
+
+ok:
+	XORL	AX, AX        // no error (it's ignored anyway)
+	MOVQ	BP, SP
+	POPQ	BP
+	RET
+
 // syscall_x509 is for crypto/x509. It is like syscall6 but does not check for errors,
 // takes 5 uintptrs and 1 float64, and only returns one value,
 // for use with standard C ABI functions.
diff --git a/src/runtime/sys_darwin_arm64.s b/src/runtime/sys_darwin_arm64.s
index bf0dc9d..4a51fb3 100644
--- a/src/runtime/sys_darwin_arm64.s
+++ b/src/runtime/sys_darwin_arm64.s
@@ -458,6 +458,12 @@
 	BL	libc_pthread_setspecific(SB)
 	RET
 
+TEXT runtime·osinit_hack_trampoline(SB),NOSPLIT,$0
+	MOVD	$0, R0	// arg 1 val
+	BL	libc_notify_is_valid_token(SB)
+	BL	libc_xpc_date_create_from_current(SB)
+	RET
+
 // syscall calls a function in libc on behalf of the syscall package.
 // syscall takes a pointer to a struct like:
 // struct {
@@ -669,6 +675,63 @@
 ok:
 	RET
 
+// syscall9 calls a function in libc on behalf of the syscall package.
+// syscall9 takes a pointer to a struct like:
+// struct {
+//	fn    uintptr
+//	a1    uintptr
+//	a2    uintptr
+//	a3    uintptr
+//	a4    uintptr
+//	a5    uintptr
+//	a6    uintptr
+//	a7    uintptr
+//	a8    uintptr
+//	a9    uintptr
+//	r1    uintptr
+//	r2    uintptr
+//	err   uintptr
+// }
+// syscall9 must be called on the g0 stack with the
+// C calling convention (use libcCall).
+TEXT runtime·syscall9(SB),NOSPLIT,$0
+	SUB	$16, RSP	// push structure pointer
+	MOVD	R0, 8(RSP)
+
+	MOVD	0(R0), R12	// fn
+	MOVD	16(R0), R1	// a2
+	MOVD	24(R0), R2	// a3
+	MOVD	32(R0), R3	// a4
+	MOVD	40(R0), R4	// a5
+	MOVD	48(R0), R5	// a6
+	MOVD	56(R0), R6	// a7
+	MOVD	64(R0), R7	// a8
+	MOVD	72(R0), R8	// a9
+	MOVD	8(R0), R0	// a1
+
+	// If fn is declared as vararg, we have to pass the vararg arguments on the stack.
+	// See syscall above. The only function this applies to is openat, for which the 4th
+	// arg must be on the stack.
+	MOVD	R3, (RSP)
+
+	BL	(R12)
+
+	MOVD	8(RSP), R2	// pop structure pointer
+	ADD	$16, RSP
+	MOVD	R0, 80(R2)	// save r1
+	MOVD	R1, 88(R2)	// save r2
+	CMPW	$-1, R0
+	BNE	ok
+	SUB	$16, RSP	// push structure pointer
+	MOVD	R2, 8(RSP)
+	BL	libc_error(SB)
+	MOVW	(R0), R0
+	MOVD	8(RSP), R2	// pop structure pointer
+	ADD	$16, RSP
+	MOVD	R0, 96(R2)	// save err
+ok:
+	RET
+
 // syscall_x509 is for crypto/x509. It is like syscall6 but does not check for errors,
 // takes 5 uintptrs and 1 float64, and only returns one value,
 // for use with standard C ABI functions.
diff --git a/src/runtime/sys_dragonfly_amd64.s b/src/runtime/sys_dragonfly_amd64.s
index 602d5e9..0cf9821 100644
--- a/src/runtime/sys_dragonfly_amd64.s
+++ b/src/runtime/sys_dragonfly_amd64.s
@@ -65,7 +65,7 @@
 	MOVL	$0xf1, 0xf1  // crash
 	RET
 
-// func exitThread(wait *uint32)
+// func exitThread(wait *atomic.Uint32)
 TEXT runtime·exitThread(SB),NOSPLIT,$0-8
 	MOVQ	wait+0(FP), AX
 	// We're done using the stack.
diff --git a/src/runtime/sys_freebsd_386.s b/src/runtime/sys_freebsd_386.s
index 9e5210b..4e0bc9b 100644
--- a/src/runtime/sys_freebsd_386.s
+++ b/src/runtime/sys_freebsd_386.s
@@ -10,8 +10,44 @@
 #include "go_tls.h"
 #include "textflag.h"
 
+#define CLOCK_REALTIME		0
+#define CLOCK_MONOTONIC		4
+#define FD_CLOEXEC		1
+#define F_SETFD			2
+
+#define SYS_exit		1
+#define SYS_read		3
+#define SYS_write		4
+#define SYS_open		5
+#define SYS_close		6
+#define SYS_getpid		20
+#define SYS_kill		37
+#define SYS_sigaltstack		53
+#define SYS_munmap		73
+#define SYS_madvise		75
+#define SYS_setitimer		83
+#define SYS_fcntl		92
+#define SYS_sysarch		165
+#define SYS___sysctl		202
+#define SYS_clock_gettime	232
+#define SYS_nanosleep		240
+#define SYS_sched_yield		331
+#define SYS_sigprocmask		340
+#define SYS_kqueue		362
+#define SYS_sigaction		416
+#define SYS_sigreturn		417
+#define SYS_thr_exit		431
+#define SYS_thr_self		432
+#define SYS_thr_kill		433
+#define SYS__umtx_op		454
+#define SYS_thr_new		455
+#define SYS_mmap		477
+#define SYS_cpuset_getaffinity	487
+#define SYS_pipe2 		542
+#define SYS_kevent		560
+
 TEXT runtime·sys_umtx_op(SB),NOSPLIT,$-4
-	MOVL	$454, AX
+	MOVL	$SYS__umtx_op, AX
 	INT	$0x80
 	JAE	2(PC)
 	NEGL	AX
@@ -19,7 +55,7 @@
 	RET
 
 TEXT runtime·thr_new(SB),NOSPLIT,$-4
-	MOVL	$455, AX
+	MOVL	$SYS_thr_new, AX
 	INT	$0x80
 	JAE	2(PC)
 	NEGL	AX
@@ -54,7 +90,7 @@
 
 // Exit the entire program (like C exit)
 TEXT runtime·exit(SB),NOSPLIT,$-4
-	MOVL	$1, AX
+	MOVL	$SYS_exit, AX
 	INT	$0x80
 	MOVL	$0xf1, 0xf1  // crash
 	RET
@@ -63,7 +99,7 @@
 DATA exitStack<>+0x00(SB)/4, $0
 DATA exitStack<>+0x04(SB)/4, $0
 
-// func exitThread(wait *uint32)
+// func exitThread(wait *atomic.Uint32)
 TEXT runtime·exitThread(SB),NOSPLIT,$0-4
 	MOVL	wait+0(FP), AX
 	// We're done using the stack.
@@ -72,13 +108,13 @@
 	// on the stack. We want to pass 0, so switch over to a fake
 	// stack of 0s. It won't write to the stack.
 	MOVL	$exitStack<>(SB), SP
-	MOVL	$431, AX	// thr_exit
+	MOVL	$SYS_thr_exit, AX
 	INT	$0x80
 	MOVL	$0xf1, 0xf1  // crash
 	JMP	0(PC)
 
 TEXT runtime·open(SB),NOSPLIT,$-4
-	MOVL	$5, AX
+	MOVL	$SYS_open, AX
 	INT	$0x80
 	JAE	2(PC)
 	MOVL	$-1, AX
@@ -86,7 +122,7 @@
 	RET
 
 TEXT runtime·closefd(SB),NOSPLIT,$-4
-	MOVL	$6, AX
+	MOVL	$SYS_close, AX
 	INT	$0x80
 	JAE	2(PC)
 	MOVL	$-1, AX
@@ -94,7 +130,7 @@
 	RET
 
 TEXT runtime·read(SB),NOSPLIT,$-4
-	MOVL	$3, AX
+	MOVL	$SYS_read, AX
 	INT	$0x80
 	JAE	2(PC)
 	NEGL	AX			// caller expects negative errno
@@ -103,7 +139,7 @@
 
 // func pipe2(flags int32) (r, w int32, errno int32)
 TEXT runtime·pipe2(SB),NOSPLIT,$12-16
-	MOVL	$542, AX
+	MOVL	$SYS_pipe2, AX
 	LEAL	r+4(FP), BX
 	MOVL	BX, 4(SP)
 	MOVL	flags+0(FP), BX
@@ -115,7 +151,7 @@
 	RET
 
 TEXT runtime·write1(SB),NOSPLIT,$-4
-	MOVL	$4, AX
+	MOVL	$SYS_write, AX
 	INT	$0x80
 	JAE	2(PC)
 	NEGL	AX			// caller expects negative errno
@@ -126,25 +162,25 @@
 	// thr_self(&0(FP))
 	LEAL	ret+0(FP), AX
 	MOVL	AX, 4(SP)
-	MOVL	$432, AX
+	MOVL	$SYS_thr_self, AX
 	INT	$0x80
 	RET
 
 TEXT runtime·thr_kill(SB),NOSPLIT,$-4
 	// thr_kill(tid, sig)
-	MOVL	$433, AX
+	MOVL	$SYS_thr_kill, AX
 	INT	$0x80
 	RET
 
 TEXT runtime·raiseproc(SB),NOSPLIT,$16
 	// getpid
-	MOVL	$20, AX
+	MOVL	$SYS_getpid, AX
 	INT	$0x80
 	// kill(self, sig)
 	MOVL	AX, 4(SP)
 	MOVL	sig+0(FP), AX
 	MOVL	AX, 8(SP)
-	MOVL	$37, AX
+	MOVL	$SYS_kill, AX
 	INT	$0x80
 	RET
 
@@ -160,7 +196,7 @@
 	MOVSL
 	MOVL	$0, AX	// top 32 bits of file offset
 	STOSL
-	MOVL	$477, AX
+	MOVL	$SYS_mmap, AX
 	INT	$0x80
 	JAE	ok
 	MOVL	$0, p+24(FP)
@@ -172,14 +208,14 @@
 	RET
 
 TEXT runtime·munmap(SB),NOSPLIT,$-4
-	MOVL	$73, AX
+	MOVL	$SYS_munmap, AX
 	INT	$0x80
 	JAE	2(PC)
 	MOVL	$0xf1, 0xf1  // crash
 	RET
 
 TEXT runtime·madvise(SB),NOSPLIT,$-4
-	MOVL	$75, AX	// madvise
+	MOVL	$SYS_madvise, AX
 	INT	$0x80
 	JAE	2(PC)
 	MOVL	$-1, AX
@@ -187,15 +223,15 @@
 	RET
 
 TEXT runtime·setitimer(SB), NOSPLIT, $-4
-	MOVL	$83, AX
+	MOVL	$SYS_setitimer, AX
 	INT	$0x80
 	RET
 
 // func fallback_walltime() (sec int64, nsec int32)
 TEXT runtime·fallback_walltime(SB), NOSPLIT, $32-12
-	MOVL	$232, AX // clock_gettime
+	MOVL	$SYS_clock_gettime, AX
 	LEAL	12(SP), BX
-	MOVL	$0, 4(SP)	// CLOCK_REALTIME
+	MOVL	$CLOCK_REALTIME, 4(SP)
 	MOVL	BX, 8(SP)
 	INT	$0x80
 	MOVL	12(SP), AX	// sec
@@ -209,9 +245,9 @@
 
 // func fallback_nanotime() int64
 TEXT runtime·fallback_nanotime(SB), NOSPLIT, $32-8
-	MOVL	$232, AX
+	MOVL	$SYS_clock_gettime, AX
 	LEAL	12(SP), BX
-	MOVL	$4, 4(SP)	// CLOCK_MONOTONIC
+	MOVL	$CLOCK_MONOTONIC, 4(SP)
 	MOVL	BX, 8(SP)
 	INT	$0x80
 	MOVL	12(SP), AX	// sec
@@ -230,7 +266,7 @@
 
 
 TEXT runtime·asmSigaction(SB),NOSPLIT,$-4
-	MOVL	$416, AX
+	MOVL	$SYS_sigaction, AX
 	INT	$0x80
 	MOVL	AX, ret+12(FP)
 	RET
@@ -267,13 +303,13 @@
 	MOVL	24(SP), AX	// context
 	MOVL	$0, 0(SP)	// syscall gap
 	MOVL	AX, 4(SP)
-	MOVL	$417, AX	// sigreturn(ucontext)
+	MOVL	$SYS_sigreturn, AX
 	INT	$0x80
 	MOVL	$0xf1, 0xf1  // crash
 	RET
 
 TEXT runtime·sigaltstack(SB),NOSPLIT,$0
-	MOVL	$53, AX
+	MOVL	$SYS_sigaltstack, AX
 	INT	$0x80
 	JAE	2(PC)
 	MOVL	$0xf1, 0xf1  // crash
@@ -293,7 +329,7 @@
 	LEAL	12(SP), AX
 	MOVL	AX, 4(SP)		// arg 1 - rqtp
 	MOVL	$0, 8(SP)		// arg 2 - rmtp
-	MOVL	$240, AX		// sys_nanosleep
+	MOVL	$SYS_nanosleep, AX
 	INT	$0x80
 	RET
 
@@ -352,7 +388,7 @@
 	MOVL	$0, 0(SP)	// syscall gap
 	MOVL	$1, 4(SP)
 	MOVL	AX, 8(SP)
-	MOVL	$165, AX
+	MOVL	$SYS_sysarch, AX
 	INT	$0x80
 	JAE	2(PC)
 	INT	$3
@@ -368,7 +404,7 @@
 	MOVSL				// arg 4 - oldlenp
 	MOVSL				// arg 5 - newp
 	MOVSL				// arg 6 - newlen
-	MOVL	$202, AX		// sys___sysctl
+	MOVL	$SYS___sysctl, AX
 	INT	$0x80
 	JAE	4(PC)
 	NEGL	AX
@@ -379,7 +415,7 @@
 	RET
 
 TEXT runtime·osyield(SB),NOSPLIT,$-4
-	MOVL	$331, AX		// sys_sched_yield
+	MOVL	$SYS_sched_yield, AX
 	INT	$0x80
 	RET
 
@@ -391,7 +427,7 @@
 	MOVL	AX, 8(SP)		// arg 2 - set
 	MOVL	old+8(FP), AX
 	MOVL	AX, 12(SP)		// arg 3 - oset
-	MOVL	$340, AX		// sys_sigprocmask
+	MOVL	$SYS_sigprocmask, AX
 	INT	$0x80
 	JAE	2(PC)
 	MOVL	$0xf1, 0xf1  // crash
@@ -399,7 +435,7 @@
 
 // int32 runtime·kqueue(void);
 TEXT runtime·kqueue(SB),NOSPLIT,$0
-	MOVL	$362, AX
+	MOVL	$SYS_kqueue, AX
 	INT	$0x80
 	JAE	2(PC)
 	NEGL	AX
@@ -408,7 +444,7 @@
 
 // int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout);
 TEXT runtime·kevent(SB),NOSPLIT,$0
-	MOVL	$363, AX
+	MOVL	$SYS_kevent, AX
 	INT	$0x80
 	JAE	2(PC)
 	NEGL	AX
@@ -417,12 +453,12 @@
 
 // int32 runtime·closeonexec(int32 fd);
 TEXT runtime·closeonexec(SB),NOSPLIT,$32
-	MOVL	$92, AX		// fcntl
+	MOVL	$SYS_fcntl, AX
 	// 0(SP) is where the caller PC would be; kernel skips it
 	MOVL	fd+0(FP), BX
 	MOVL	BX, 4(SP)	// fd
-	MOVL	$2, 8(SP)	// F_SETFD
-	MOVL	$1, 12(SP)	// FD_CLOEXEC
+	MOVL	$F_SETFD, 8(SP)
+	MOVL	$FD_CLOEXEC, 12(SP)
 	INT	$0x80
 	JAE	2(PC)
 	NEGL	AX
@@ -430,7 +466,7 @@
 
 // func cpuset_getaffinity(level int, which int, id int64, size int, mask *byte) int32
 TEXT runtime·cpuset_getaffinity(SB), NOSPLIT, $0-28
-	MOVL	$487, AX
+	MOVL	$SYS_cpuset_getaffinity, AX
 	INT	$0x80
 	JAE	2(PC)
 	NEGL	AX
diff --git a/src/runtime/sys_freebsd_amd64.s b/src/runtime/sys_freebsd_amd64.s
index 94341f6..374e0ab 100644
--- a/src/runtime/sys_freebsd_amd64.s
+++ b/src/runtime/sys_freebsd_amd64.s
@@ -11,13 +11,49 @@
 #include "textflag.h"
 #include "cgo/abi_amd64.h"
 
+#define CLOCK_REALTIME		0
+#define CLOCK_MONOTONIC		4
+#define FD_CLOEXEC		1
+#define F_SETFD			2
+#define AMD64_SET_FSBASE	129
+
+#define SYS_exit		1
+#define SYS_read		3
+#define SYS_write		4
+#define SYS_open		5
+#define SYS_close		6
+#define SYS_getpid		20
+#define SYS_kill		37
+#define SYS_sigaltstack		53
+#define SYS_munmap		73
+#define SYS_madvise		75
+#define SYS_setitimer		83
+#define SYS_fcntl		92
+#define SYS_sysarch		165
+#define SYS___sysctl		202
+#define SYS_clock_gettime	232
+#define SYS_nanosleep		240
+#define SYS_sched_yield		331
+#define SYS_sigprocmask		340
+#define SYS_kqueue		362
+#define SYS_sigaction		416
+#define SYS_thr_exit		431
+#define SYS_thr_self		432
+#define SYS_thr_kill		433
+#define SYS__umtx_op		454
+#define SYS_thr_new		455
+#define SYS_mmap		477
+#define SYS_cpuset_getaffinity	487
+#define SYS_pipe2 		542
+#define SYS_kevent		560
+
 TEXT runtime·sys_umtx_op(SB),NOSPLIT,$0
 	MOVQ addr+0(FP), DI
 	MOVL mode+8(FP), SI
 	MOVL val+12(FP), DX
 	MOVQ uaddr1+16(FP), R10
 	MOVQ ut+24(FP), R8
-	MOVL $454, AX
+	MOVL $SYS__umtx_op, AX
 	SYSCALL
 	JCC	2(PC)
 	NEGQ	AX
@@ -27,7 +63,7 @@
 TEXT runtime·thr_new(SB),NOSPLIT,$0
 	MOVQ param+0(FP), DI
 	MOVL size+8(FP), SI
-	MOVL $455, AX
+	MOVL $SYS_thr_new, AX
 	SYSCALL
 	JCC	2(PC)
 	NEGQ	AX
@@ -55,18 +91,18 @@
 // Exit the entire program (like C exit)
 TEXT runtime·exit(SB),NOSPLIT,$-8
 	MOVL	code+0(FP), DI		// arg 1 exit status
-	MOVL	$1, AX
+	MOVL	$SYS_exit, AX
 	SYSCALL
 	MOVL	$0xf1, 0xf1  // crash
 	RET
 
-// func exitThread(wait *uint32)
+// func exitThread(wait *atomic.uint32)
 TEXT runtime·exitThread(SB),NOSPLIT,$0-8
 	MOVQ	wait+0(FP), AX
 	// We're done using the stack.
 	MOVL	$0, (AX)
 	MOVL	$0, DI		// arg 1 long *state
-	MOVL	$431, AX	// thr_exit
+	MOVL	$SYS_thr_exit, AX
 	SYSCALL
 	MOVL	$0xf1, 0xf1  // crash
 	JMP	0(PC)
@@ -75,7 +111,7 @@
 	MOVQ	name+0(FP), DI		// arg 1 pathname
 	MOVL	mode+8(FP), SI		// arg 2 flags
 	MOVL	perm+12(FP), DX		// arg 3 mode
-	MOVL	$5, AX
+	MOVL	$SYS_open, AX
 	SYSCALL
 	JCC	2(PC)
 	MOVL	$-1, AX
@@ -84,7 +120,7 @@
 
 TEXT runtime·closefd(SB),NOSPLIT,$-8
 	MOVL	fd+0(FP), DI		// arg 1 fd
-	MOVL	$6, AX
+	MOVL	$SYS_close, AX
 	SYSCALL
 	JCC	2(PC)
 	MOVL	$-1, AX
@@ -95,7 +131,7 @@
 	MOVL	fd+0(FP), DI		// arg 1 fd
 	MOVQ	p+8(FP), SI		// arg 2 buf
 	MOVL	n+16(FP), DX		// arg 3 count
-	MOVL	$3, AX
+	MOVL	$SYS_read, AX
 	SYSCALL
 	JCC	2(PC)
 	NEGQ	AX			// caller expects negative errno
@@ -106,7 +142,7 @@
 TEXT runtime·pipe2(SB),NOSPLIT,$0-20
 	LEAQ	r+8(FP), DI
 	MOVL	flags+0(FP), SI
-	MOVL	$542, AX
+	MOVL	$SYS_pipe2, AX
 	SYSCALL
 	JCC	2(PC)
 	NEGQ	AX
@@ -117,7 +153,7 @@
 	MOVQ	fd+0(FP), DI		// arg 1 fd
 	MOVQ	p+8(FP), SI		// arg 2 buf
 	MOVL	n+16(FP), DX		// arg 3 count
-	MOVL	$4, AX
+	MOVL	$SYS_write, AX
 	SYSCALL
 	JCC	2(PC)
 	NEGQ	AX			// caller expects negative errno
@@ -127,7 +163,7 @@
 TEXT runtime·thr_self(SB),NOSPLIT,$0-8
 	// thr_self(&0(FP))
 	LEAQ	ret+0(FP), DI	// arg 1
-	MOVL	$432, AX
+	MOVL	$SYS_thr_self, AX
 	SYSCALL
 	RET
 
@@ -135,18 +171,18 @@
 	// thr_kill(tid, sig)
 	MOVQ	tid+0(FP), DI	// arg 1 id
 	MOVQ	sig+8(FP), SI	// arg 2 sig
-	MOVL	$433, AX
+	MOVL	$SYS_thr_kill, AX
 	SYSCALL
 	RET
 
 TEXT runtime·raiseproc(SB),NOSPLIT,$0
 	// getpid
-	MOVL	$20, AX
+	MOVL	$SYS_getpid, AX
 	SYSCALL
 	// kill(self, sig)
 	MOVQ	AX, DI		// arg 1 pid
 	MOVL	sig+0(FP), SI	// arg 2 sig
-	MOVL	$37, AX
+	MOVL	$SYS_kill, AX
 	SYSCALL
 	RET
 
@@ -154,14 +190,14 @@
 	MOVL	mode+0(FP), DI
 	MOVQ	new+8(FP), SI
 	MOVQ	old+16(FP), DX
-	MOVL	$83, AX
+	MOVL	$SYS_setitimer, AX
 	SYSCALL
 	RET
 
 // func fallback_walltime() (sec int64, nsec int32)
 TEXT runtime·fallback_walltime(SB), NOSPLIT, $32-12
-	MOVL	$232, AX	// clock_gettime
-	MOVQ	$0, DI		// CLOCK_REALTIME
+	MOVL	$SYS_clock_gettime, AX
+	MOVQ	$CLOCK_REALTIME, DI
 	LEAQ	8(SP), SI
 	SYSCALL
 	MOVQ	8(SP), AX	// sec
@@ -173,8 +209,8 @@
 	RET
 
 TEXT runtime·fallback_nanotime(SB), NOSPLIT, $32-8
-	MOVL	$232, AX
-	MOVQ	$4, DI		// CLOCK_MONOTONIC
+	MOVL	$SYS_clock_gettime, AX
+	MOVQ	$CLOCK_MONOTONIC, DI
 	LEAQ	8(SP), SI
 	SYSCALL
 	MOVQ	8(SP), AX	// sec
@@ -191,7 +227,7 @@
 	MOVQ	sig+0(FP), DI		// arg 1 sig
 	MOVQ	new+8(FP), SI		// arg 2 act
 	MOVQ	old+16(FP), DX		// arg 3 oact
-	MOVL	$416, AX
+	MOVL	$SYS_sigaction, AX
 	SYSCALL
 	JCC	2(PC)
 	MOVL	$-1, AX
@@ -349,14 +385,14 @@
 	MOVQ	_cgo_callers(SB), AX
 	JMP	AX
 
-TEXT runtime·mmap(SB),NOSPLIT,$0
+TEXT runtime·sysMmap(SB),NOSPLIT,$0
 	MOVQ	addr+0(FP), DI		// arg 1 addr
 	MOVQ	n+8(FP), SI		// arg 2 len
 	MOVL	prot+16(FP), DX		// arg 3 prot
 	MOVL	flags+20(FP), R10		// arg 4 flags
 	MOVL	fd+24(FP), R8		// arg 5 fid
 	MOVL	off+28(FP), R9		// arg 6 offset
-	MOVL	$477, AX
+	MOVL	$SYS_mmap, AX
 	SYSCALL
 	JCC	ok
 	MOVQ	$0, p+32(FP)
@@ -367,20 +403,51 @@
 	MOVQ	$0, err+40(FP)
 	RET
 
-TEXT runtime·munmap(SB),NOSPLIT,$0
+// Call the function stored in _cgo_mmap using the GCC calling convention.
+// This must be called on the system stack.
+TEXT runtime·callCgoMmap(SB),NOSPLIT,$16
+	MOVQ	addr+0(FP), DI
+	MOVQ	n+8(FP), SI
+	MOVL	prot+16(FP), DX
+	MOVL	flags+20(FP), CX
+	MOVL	fd+24(FP), R8
+	MOVL	off+28(FP), R9
+	MOVQ	_cgo_mmap(SB), AX
+	MOVQ	SP, BX
+	ANDQ	$~15, SP	// alignment as per amd64 psABI
+	MOVQ	BX, 0(SP)
+	CALL	AX
+	MOVQ	0(SP), SP
+	MOVQ	AX, ret+32(FP)
+	RET
+
+TEXT runtime·sysMunmap(SB),NOSPLIT,$0
 	MOVQ	addr+0(FP), DI		// arg 1 addr
 	MOVQ	n+8(FP), SI		// arg 2 len
-	MOVL	$73, AX
+	MOVL	$SYS_munmap, AX
 	SYSCALL
 	JCC	2(PC)
 	MOVL	$0xf1, 0xf1  // crash
 	RET
 
+// Call the function stored in _cgo_munmap using the GCC calling convention.
+// This must be called on the system stack.
+TEXT runtime·callCgoMunmap(SB),NOSPLIT,$16-16
+	MOVQ	addr+0(FP), DI
+	MOVQ	n+8(FP), SI
+	MOVQ	_cgo_munmap(SB), AX
+	MOVQ	SP, BX
+	ANDQ	$~15, SP	// alignment as per amd64 psABI
+	MOVQ	BX, 0(SP)
+	CALL	AX
+	MOVQ	0(SP), SP
+	RET
+
 TEXT runtime·madvise(SB),NOSPLIT,$0
 	MOVQ	addr+0(FP), DI
 	MOVQ	n+8(FP), SI
 	MOVL	flags+16(FP), DX
-	MOVQ	$75, AX	// madvise
+	MOVQ	$SYS_madvise, AX
 	SYSCALL
 	JCC	2(PC)
 	MOVL	$-1, AX
@@ -390,7 +457,7 @@
 TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
 	MOVQ	new+0(FP), DI
 	MOVQ	old+8(FP), SI
-	MOVQ	$53, AX
+	MOVQ	$SYS_sigaltstack, AX
 	SYSCALL
 	JCC	2(PC)
 	MOVL	$0xf1, 0xf1  // crash
@@ -408,7 +475,7 @@
 
 	MOVQ	SP, DI			// arg 1 - rqtp
 	MOVQ	$0, SI			// arg 2 - rmtp
-	MOVL	$240, AX		// sys_nanosleep
+	MOVL	$SYS_nanosleep, AX
 	SYSCALL
 	RET
 
@@ -417,8 +484,8 @@
 	ADDQ	$8, DI	// adjust for ELF: wants to use -8(FS) for g and m
 	MOVQ	DI, 0(SP)
 	MOVQ	SP, SI
-	MOVQ	$129, DI	// AMD64_SET_FSBASE
-	MOVQ	$165, AX	// sysarch
+	MOVQ	$AMD64_SET_FSBASE, DI
+	MOVQ	$SYS_sysarch, AX
 	SYSCALL
 	JCC	2(PC)
 	MOVL	$0xf1, 0xf1  // crash
@@ -431,7 +498,7 @@
 	MOVQ	size+24(FP), R10		// arg 4 - oldlenp
 	MOVQ	dst+32(FP), R8		// arg 5 - newp
 	MOVQ	ndst+40(FP), R9		// arg 6 - newlen
-	MOVQ	$202, AX		// sys___sysctl
+	MOVQ	$SYS___sysctl, AX
 	SYSCALL
 	JCC 4(PC)
 	NEGQ	AX
@@ -442,7 +509,7 @@
 	RET
 
 TEXT runtime·osyield(SB),NOSPLIT,$-4
-	MOVL	$331, AX		// sys_sched_yield
+	MOVL	$SYS_sched_yield, AX
 	SYSCALL
 	RET
 
@@ -450,7 +517,7 @@
 	MOVL	how+0(FP), DI		// arg 1 - how
 	MOVQ	new+8(FP), SI		// arg 2 - set
 	MOVQ	old+16(FP), DX		// arg 3 - oset
-	MOVL	$340, AX		// sys_sigprocmask
+	MOVL	$SYS_sigprocmask, AX
 	SYSCALL
 	JAE	2(PC)
 	MOVL	$0xf1, 0xf1  // crash
@@ -461,7 +528,7 @@
 	MOVQ	$0, DI
 	MOVQ	$0, SI
 	MOVQ	$0, DX
-	MOVL	$362, AX
+	MOVL	$SYS_kqueue, AX
 	SYSCALL
 	JCC	2(PC)
 	NEGQ	AX
@@ -476,7 +543,7 @@
 	MOVQ	ev+24(FP), R10
 	MOVL	nev+32(FP), R8
 	MOVQ	ts+40(FP), R9
-	MOVL	$363, AX
+	MOVL	$SYS_kevent, AX
 	SYSCALL
 	JCC	2(PC)
 	NEGQ	AX
@@ -486,9 +553,9 @@
 // void runtime·closeonexec(int32 fd);
 TEXT runtime·closeonexec(SB),NOSPLIT,$0
 	MOVL	fd+0(FP), DI	// fd
-	MOVQ	$2, SI		// F_SETFD
-	MOVQ	$1, DX		// FD_CLOEXEC
-	MOVL	$92, AX		// fcntl
+	MOVQ	$F_SETFD, SI
+	MOVQ	$FD_CLOEXEC, DX
+	MOVL	$SYS_fcntl, AX
 	SYSCALL
 	RET
 
@@ -499,7 +566,7 @@
 	MOVQ	id+16(FP), DX
 	MOVQ	size+24(FP), R10
 	MOVQ	mask+32(FP), R8
-	MOVL	$487, AX
+	MOVL	$SYS_cpuset_getaffinity, AX
 	SYSCALL
 	JCC	2(PC)
 	NEGQ	AX
diff --git a/src/runtime/sys_freebsd_arm.s b/src/runtime/sys_freebsd_arm.s
index cbee34d..a3fee14 100644
--- a/src/runtime/sys_freebsd_arm.s
+++ b/src/runtime/sys_freebsd_arm.s
@@ -31,7 +31,6 @@
 #define SYS_sched_yield (SYS_BASE + 331)
 #define SYS_sigprocmask (SYS_BASE + 340)
 #define SYS_kqueue (SYS_BASE + 362)
-#define SYS_kevent (SYS_BASE + 363)
 #define SYS_sigaction (SYS_BASE + 416)
 #define SYS_thr_exit (SYS_BASE + 431)
 #define SYS_thr_self (SYS_BASE + 432)
@@ -41,6 +40,7 @@
 #define SYS_mmap (SYS_BASE + 477)
 #define SYS_cpuset_getaffinity (SYS_BASE + 487)
 #define SYS_pipe2 (SYS_BASE + 542)
+#define SYS_kevent (SYS_BASE + 560)
 
 TEXT runtime·sys_umtx_op(SB),NOSPLIT,$0
 	MOVW addr+0(FP), R0
@@ -85,7 +85,7 @@
 	MOVW.CS R8, (R8)
 	RET
 
-// func exitThread(wait *uint32)
+// func exitThread(wait *atomic.Uint32)
 TEXT runtime·exitThread(SB),NOSPLIT,$0-4
 	MOVW	wait+0(FP), R0
 	// We're done using the stack.
diff --git a/src/runtime/sys_freebsd_arm64.s b/src/runtime/sys_freebsd_arm64.s
index 5dcdf37..29866cb 100644
--- a/src/runtime/sys_freebsd_arm64.s
+++ b/src/runtime/sys_freebsd_arm64.s
@@ -38,7 +38,6 @@
 #define SYS_sched_yield		331
 #define SYS_sigprocmask		340
 #define SYS_kqueue		362
-#define SYS_kevent		363
 #define SYS_sigaction		416
 #define SYS_thr_exit		431
 #define SYS_thr_self		432
@@ -48,6 +47,7 @@
 #define SYS_mmap		477
 #define SYS_cpuset_getaffinity	487
 #define SYS_pipe2 		542
+#define SYS_kevent		560
 
 TEXT emptyfunc<>(SB),0,$0-0
 	RET
@@ -99,7 +99,7 @@
 	MOVD	$0, R0
 	MOVD	R0, (R0)
 
-// func exitThread(wait *uint32)
+// func exitThread(wait *atomic.Uint32)
 TEXT runtime·exitThread(SB),NOSPLIT|NOFRAME,$0-8
 	MOVD	wait+0(FP), R0
 	// We're done using the stack.
@@ -460,7 +460,7 @@
 	BEQ	3(PC)
 
 	// get CNTPCT (Physical Count Register) into R0
-	MRS	CNTPCT_EL0, R0 // SIGILL
+	MRS	CNTPCT_EL0, R0
 	B	2(PC)
 
 	// get CNTVCT (Virtual Count Register) into R0
diff --git a/src/runtime/sys_freebsd_riscv64.s b/src/runtime/sys_freebsd_riscv64.s
new file mode 100644
index 0000000..30deed2
--- /dev/null
+++ b/src/runtime/sys_freebsd_riscv64.s
@@ -0,0 +1,436 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//
+// System calls and other sys.stuff for riscv64, FreeBSD
+// /usr/src/sys/kern/syscalls.master for syscall numbers.
+//
+
+#include "go_asm.h"
+#include "go_tls.h"
+#include "textflag.h"
+
+#define CLOCK_REALTIME		0
+#define CLOCK_MONOTONIC		4
+#define FD_CLOEXEC		1
+#define F_SETFD			2
+#define F_GETFL			3
+#define F_SETFL			4
+#define O_NONBLOCK		4
+
+#define SYS_exit		1
+#define SYS_read		3
+#define SYS_write		4
+#define SYS_open		5
+#define SYS_close		6
+#define SYS_getpid		20
+#define SYS_kill		37
+#define SYS_sigaltstack		53
+#define SYS_munmap		73
+#define SYS_madvise		75
+#define SYS_setitimer		83
+#define SYS_fcntl		92
+#define SYS___sysctl		202
+#define SYS_nanosleep		240
+#define SYS_clock_gettime	232
+#define SYS_sched_yield		331
+#define SYS_sigprocmask		340
+#define SYS_kqueue		362
+#define SYS_sigaction		416
+#define SYS_thr_exit		431
+#define SYS_thr_self		432
+#define SYS_thr_kill		433
+#define SYS__umtx_op		454
+#define SYS_thr_new		455
+#define SYS_mmap		477
+#define SYS_cpuset_getaffinity	487
+#define SYS_pipe2 		542
+#define SYS_kevent		560
+
+TEXT emptyfunc<>(SB),0,$0-0
+	RET
+
+// func sys_umtx_op(addr *uint32, mode int32, val uint32, uaddr1 uintptr, ut *umtx_time) int32
+TEXT runtime·sys_umtx_op(SB),NOSPLIT,$0
+	MOV	addr+0(FP), A0
+	MOVW	mode+8(FP), A1
+	MOVW	val+12(FP), A2
+	MOV	uaddr1+16(FP), A3
+	MOV	ut+24(FP), A4
+	MOV	$SYS__umtx_op, T0
+	ECALL
+	BEQ	T0, ZERO, ok
+	NEG	A0, A0
+ok:
+	MOVW	A0, ret+32(FP)
+	RET
+
+// func thr_new(param *thrparam, size int32) int32
+TEXT runtime·thr_new(SB),NOSPLIT,$0
+	MOV	param+0(FP), A0
+	MOVW	size+8(FP), A1
+	MOV	$SYS_thr_new, T0
+	ECALL
+	BEQ	T0, ZERO, ok
+	NEG	A0, A0
+ok:
+	MOVW	A0, ret+16(FP)
+	RET
+
+// func thr_start()
+TEXT runtime·thr_start(SB),NOSPLIT,$0
+	// set up g
+	MOV	m_g0(A0), g
+	MOV	A0, g_m(g)
+	CALL	emptyfunc<>(SB)	 // fault if stack check is wrong
+	CALL	runtime·mstart(SB)
+
+	WORD	$0	// crash
+	RET
+
+// func exit(code int32)
+TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0-4
+	MOVW	code+0(FP), A0
+	MOV	$SYS_exit, T0
+	ECALL
+	WORD	$0	// crash
+
+// func exitThread(wait *atomic.Uint32)
+TEXT runtime·exitThread(SB),NOSPLIT|NOFRAME,$0-8
+	MOV	wait+0(FP), A0
+	// We're done using the stack.
+	FENCE
+	MOVW	ZERO, (A0)
+	FENCE
+	MOV	$0, A0	// exit code
+	MOV	$SYS_thr_exit, T0
+	ECALL
+	JMP	0(PC)
+
+// func open(name *byte, mode, perm int32) int32
+TEXT runtime·open(SB),NOSPLIT|NOFRAME,$0-20
+	MOV	name+0(FP), A0
+	MOVW	mode+8(FP), A1
+	MOVW	perm+12(FP), A2
+	MOV	$SYS_open, T0
+	ECALL
+	BEQ	T0, ZERO, ok
+	MOV	$-1, A0
+ok:
+	MOVW	A0, ret+16(FP)
+	RET
+
+// func closefd(fd int32) int32
+TEXT runtime·closefd(SB),NOSPLIT|NOFRAME,$0-12
+	MOVW	fd+0(FP), A0
+	MOV	$SYS_close, T0
+	ECALL
+	BEQ	T0, ZERO, ok
+	MOV	$-1, A0
+ok:
+	MOVW	A0, ret+8(FP)
+	RET
+
+// func pipe2(flags int32) (r, w int32, errno int32)
+TEXT runtime·pipe2(SB),NOSPLIT|NOFRAME,$0-20
+	MOV	$r+8(FP), A0
+	MOVW	flags+0(FP), A1
+	MOV	$SYS_pipe2, T0
+	ECALL
+	BEQ	T0, ZERO, ok
+	NEG	A0, A0
+ok:
+	MOVW	A0, errno+16(FP)
+	RET
+
+// func write1(fd uintptr, p unsafe.Pointer, n int32) int32
+TEXT runtime·write1(SB),NOSPLIT|NOFRAME,$0-28
+	MOV	fd+0(FP), A0
+	MOV	p+8(FP), A1
+	MOVW	n+16(FP), A2
+	MOV	$SYS_write, T0
+	ECALL
+	BEQ	T0, ZERO, ok
+	NEG	A0, A0
+ok:
+	MOVW	A0, ret+24(FP)
+	RET
+
+// func read(fd int32, p unsafe.Pointer, n int32) int32
+TEXT runtime·read(SB),NOSPLIT|NOFRAME,$0-28
+	MOVW	fd+0(FP), A0
+	MOV	p+8(FP), A1
+	MOVW	n+16(FP), A2
+	MOV	$SYS_read, T0
+	ECALL
+	BEQ	T0, ZERO, ok
+	NEG	A0, A0
+ok:
+	MOVW	A0, ret+24(FP)
+	RET
+
+// func usleep(usec uint32)
+TEXT runtime·usleep(SB),NOSPLIT,$24-4
+	MOVWU	usec+0(FP), A0
+	MOV	$1000, A1
+	MUL	A1, A0, A0
+	MOV	$1000000000, A1
+	DIV	A1, A0, A2
+	MOV	A2, 8(X2)
+	REM	A1, A0, A3
+	MOV	A3, 16(X2)
+	ADD	$8, X2, A0
+	MOV	ZERO, A1
+	MOV	$SYS_nanosleep, T0
+	ECALL
+	RET
+
+// func thr_self() thread
+TEXT runtime·thr_self(SB),NOSPLIT,$8-8
+	MOV	$ptr-8(SP), A0	// arg 1 &8(SP)
+	MOV	$SYS_thr_self, T0
+	ECALL
+	MOV	ptr-8(SP), A0
+	MOV	A0, ret+0(FP)
+	RET
+
+// func thr_kill(t thread, sig int)
+TEXT runtime·thr_kill(SB),NOSPLIT,$0-16
+	MOV	tid+0(FP), A0	// arg 1 pid
+	MOV	sig+8(FP), A1	// arg 2 sig
+	MOV	$SYS_thr_kill, T0
+	ECALL
+	RET
+
+// func raiseproc(sig uint32)
+TEXT runtime·raiseproc(SB),NOSPLIT|NOFRAME,$0
+	MOV	$SYS_getpid, T0
+	ECALL
+	// arg 1 pid - already in A0
+	MOVW	sig+0(FP), A1	// arg 2
+	MOV	$SYS_kill, T0
+	ECALL
+	RET
+
+// func setitimer(mode int32, new, old *itimerval)
+TEXT runtime·setitimer(SB),NOSPLIT|NOFRAME,$0-24
+	MOVW	mode+0(FP), A0
+	MOV	new+8(FP), A1
+	MOV	old+16(FP), A2
+	MOV	$SYS_setitimer, T0
+	ECALL
+	RET
+
+// func fallback_walltime() (sec int64, nsec int32)
+TEXT runtime·fallback_walltime(SB),NOSPLIT,$24-12
+	MOV	$CLOCK_REALTIME, A0
+	MOV	$8(X2), A1
+	MOV	$SYS_clock_gettime, T0
+	ECALL
+	MOV	8(X2), T0	// sec
+	MOVW	16(X2), T1	// nsec
+	MOV	T0, sec+0(FP)
+	MOVW	T1, nsec+8(FP)
+	RET
+
+// func fallback_nanotime() int64
+TEXT runtime·fallback_nanotime(SB),NOSPLIT,$24-8
+	MOV	$CLOCK_MONOTONIC, A0
+	MOV	$8(X2), A1
+	MOV	$SYS_clock_gettime, T0
+	ECALL
+	MOV	8(X2), T0	// sec
+	MOV	16(X2), T1	// nsec
+
+	// sec is in T0, nsec in T1
+	// return nsec in T0
+	MOV	$1000000000, T2
+	MUL	T2, T0
+	ADD	T1, T0
+
+	MOV	T0, ret+0(FP)
+	RET
+
+// func asmSigaction(sig uintptr, new, old *sigactiont) int32
+TEXT runtime·asmSigaction(SB),NOSPLIT|NOFRAME,$0
+	MOV	sig+0(FP), A0		// arg 1 sig
+	MOV	new+8(FP), A1		// arg 2 act
+	MOV	old+16(FP), A2		// arg 3 oact
+	MOV	$SYS_sigaction, T0
+	ECALL
+	BEQ	T0, ZERO, ok
+	MOV	$-1, A0
+ok:
+	MOVW	A0, ret+24(FP)
+	RET
+
+// func sigfwd(fn uintptr, sig uint32, info *siginfo, ctx unsafe.Pointer)
+TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
+	MOVW	sig+8(FP), A0
+	MOV	info+16(FP), A1
+	MOV	ctx+24(FP), A2
+	MOV	fn+0(FP), T1
+	JALR	RA, T1
+	RET
+
+// func sigtramp(signo, ureg, ctxt unsafe.Pointer)
+TEXT runtime·sigtramp(SB),NOSPLIT,$64
+	MOVW	A0, 8(X2)
+	MOV	A1, 16(X2)
+	MOV	A2, 24(X2)
+
+	// this might be called in external code context,
+	// where g is not set.
+	MOVBU	runtime·iscgo(SB), A0
+	BEQ	A0, ZERO, ok
+	CALL	runtime·load_g(SB)
+ok:
+	MOV	$runtime·sigtrampgo(SB), A0
+	JALR	RA, A0
+	RET
+
+// func mmap(addr uintptr, n uintptr, prot int, flags int, fd int, off int64) (ret uintptr, err error)
+TEXT runtime·mmap(SB),NOSPLIT|NOFRAME,$0
+	MOV	addr+0(FP), A0
+	MOV	n+8(FP), A1
+	MOVW	prot+16(FP), A2
+	MOVW	flags+20(FP), A3
+	MOVW	fd+24(FP), A4
+	MOVW	off+28(FP), A5
+	MOV	$SYS_mmap, T0
+	ECALL
+	BNE	T0, ZERO, fail
+	MOV	A0, p+32(FP)
+	MOV	ZERO, err+40(FP)
+	RET
+fail:
+	MOV	ZERO, p+32(FP)
+	MOV	A0, err+40(FP)
+	RET
+
+// func munmap(addr uintptr, n uintptr) (err error)
+TEXT runtime·munmap(SB),NOSPLIT|NOFRAME,$0
+	MOV	addr+0(FP), A0
+	MOV	n+8(FP), A1
+	MOV	$SYS_munmap, T0
+	ECALL
+	BNE	T0, ZERO, fail
+	RET
+fail:
+	WORD	$0	// crash
+
+// func madvise(addr unsafe.Pointer, n uintptr, flags int32) int32
+TEXT runtime·madvise(SB),NOSPLIT|NOFRAME,$0
+	MOV	addr+0(FP), A0
+	MOV	n+8(FP), A1
+	MOVW	flags+16(FP), A2
+	MOV	$SYS_madvise, T0
+	ECALL
+	BEQ	T0, ZERO, ok
+	MOV	$-1, A0
+ok:
+	MOVW	A0, ret+24(FP)
+	RET
+
+// func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32
+TEXT runtime·sysctl(SB),NOSPLIT,$0
+	MOV	mib+0(FP), A0
+	MOV	miblen+8(FP), A1
+	MOV	out+16(FP), A2
+	MOV	size+24(FP), A3
+	MOV	dst+32(FP), A4
+	MOV	ndst+40(FP), A5
+	MOV	$SYS___sysctl, T0
+	ECALL
+	BEQ	T0, ZERO, ok
+	NEG	A0, A0
+ok:
+	MOVW	A0, ret+48(FP)
+	RET
+
+// func sigaltstack(new, old *stackt)
+TEXT runtime·sigaltstack(SB),NOSPLIT|NOFRAME,$0
+	MOV	new+0(FP), A0
+	MOV	old+8(FP), A1
+	MOV	$SYS_sigaltstack, T0
+	ECALL
+	BNE	T0, ZERO, fail
+	RET
+fail:
+	WORD	$0	// crash
+
+// func osyield()
+TEXT runtime·osyield(SB),NOSPLIT|NOFRAME,$0
+	MOV	$SYS_sched_yield, T0
+	ECALL
+	RET
+
+// func sigprocmask(how int32, new, old *sigset)
+TEXT runtime·sigprocmask(SB),NOSPLIT|NOFRAME,$0-24
+	MOVW	how+0(FP), A0
+	MOV	new+8(FP), A1
+	MOV	old+16(FP), A2
+	MOV	$SYS_sigprocmask, T0
+	ECALL
+	BNE	T0, ZERO, fail
+	RET
+fail:
+	WORD	$0	// crash
+
+
+// func cpuset_getaffinity(level int, which int, id int64, size int, mask *byte) int32
+TEXT runtime·cpuset_getaffinity(SB),NOSPLIT|NOFRAME,$0-44
+	MOV	level+0(FP), A0
+	MOV	which+8(FP), A1
+	MOV	id+16(FP), A2
+	MOV	size+24(FP), A3
+	MOV	mask+32(FP), A4
+	MOV	$SYS_cpuset_getaffinity, T0
+	ECALL
+	BEQ	T0, ZERO, ok
+	MOV	$-1, A0
+ok:
+	MOVW	A0, ret+40(FP)
+	RET
+
+// func kqueue() int32
+TEXT runtime·kqueue(SB),NOSPLIT|NOFRAME,$0
+	MOV $SYS_kqueue, T0
+	ECALL
+	BEQ	T0, ZERO, ok
+	MOV	$-1, A0
+ok:
+	MOVW	A0, ret+0(FP)
+	RET
+
+// func kevent(kq int, ch unsafe.Pointer, nch int, ev unsafe.Pointer, nev int, ts *Timespec) (n int, err error)
+TEXT runtime·kevent(SB),NOSPLIT,$0
+	MOVW	kq+0(FP), A0
+	MOV	ch+8(FP), A1
+	MOVW	nch+16(FP), A2
+	MOV	ev+24(FP), A3
+	MOVW	nev+32(FP), A4
+	MOV	ts+40(FP), A5
+	MOV	$SYS_kevent, T0
+	ECALL
+	BEQ	T0, ZERO, ok
+	NEG	A0, A0
+ok:
+	MOVW	A0, ret+48(FP)
+	RET
+
+// func closeonexec(fd int32)
+TEXT runtime·closeonexec(SB),NOSPLIT|NOFRAME,$0
+	MOVW	fd+0(FP), A0
+	MOV	$F_SETFD, A1
+	MOV	$FD_CLOEXEC, A2
+	MOV	$SYS_fcntl, T0
+	ECALL
+	RET
+
+// func getCntxct() uint32
+TEXT runtime·getCntxct(SB),NOSPLIT|NOFRAME,$0
+	RDTIME	A0
+	MOVW	A0, ret+0(FP)
+	RET
diff --git a/src/runtime/sys_linux_386.s b/src/runtime/sys_linux_386.s
index 4942f21..12a2941 100644
--- a/src/runtime/sys_linux_386.s
+++ b/src/runtime/sys_linux_386.s
@@ -33,7 +33,6 @@
 #define SYS_access		33
 #define SYS_kill		37
 #define SYS_brk 		45
-#define SYS_fcntl		55
 #define SYS_munmap		91
 #define SYS_socketcall		102
 #define SYS_setittimer		104
@@ -52,15 +51,11 @@
 #define SYS_sched_getaffinity	242
 #define SYS_set_thread_area	243
 #define SYS_exit_group		252
-#define SYS_epoll_create	254
-#define SYS_epoll_ctl		255
-#define SYS_epoll_wait		256
 #define SYS_timer_create	259
 #define SYS_timer_settime	260
 #define SYS_timer_delete	263
 #define SYS_clock_gettime	265
 #define SYS_tgkill		270
-#define SYS_epoll_create1	329
 #define SYS_pipe2		331
 
 TEXT runtime·exit(SB),NOSPLIT,$0
@@ -77,7 +72,7 @@
 	INT $3	// not reached
 	RET
 
-// func exitThread(wait *uint32)
+// func exitThread(wait *atomic.Uint32)
 TEXT runtime·exitThread(SB),NOSPLIT,$0-4
 	MOVL	wait+0(FP), AX
 	// We're done using the stack.
@@ -726,53 +721,6 @@
 	MOVL	AX, ret+12(FP)
 	RET
 
-// int32 runtime·epollcreate(int32 size);
-TEXT runtime·epollcreate(SB),NOSPLIT,$0
-	MOVL    $SYS_epoll_create, AX
-	MOVL	size+0(FP), BX
-	INVOKE_SYSCALL
-	MOVL	AX, ret+4(FP)
-	RET
-
-// int32 runtime·epollcreate1(int32 flags);
-TEXT runtime·epollcreate1(SB),NOSPLIT,$0
-	MOVL    $SYS_epoll_create1, AX
-	MOVL	flags+0(FP), BX
-	INVOKE_SYSCALL
-	MOVL	AX, ret+4(FP)
-	RET
-
-// func epollctl(epfd, op, fd int32, ev *epollEvent) int
-TEXT runtime·epollctl(SB),NOSPLIT,$0
-	MOVL	$SYS_epoll_ctl, AX
-	MOVL	epfd+0(FP), BX
-	MOVL	op+4(FP), CX
-	MOVL	fd+8(FP), DX
-	MOVL	ev+12(FP), SI
-	INVOKE_SYSCALL
-	MOVL	AX, ret+16(FP)
-	RET
-
-// int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout);
-TEXT runtime·epollwait(SB),NOSPLIT,$0
-	MOVL	$SYS_epoll_wait, AX
-	MOVL	epfd+0(FP), BX
-	MOVL	ev+4(FP), CX
-	MOVL	nev+8(FP), DX
-	MOVL	timeout+12(FP), SI
-	INVOKE_SYSCALL
-	MOVL	AX, ret+16(FP)
-	RET
-
-// void runtime·closeonexec(int32 fd);
-TEXT runtime·closeonexec(SB),NOSPLIT,$0
-	MOVL	$SYS_fcntl, AX
-	MOVL	fd+0(FP), BX  // fd
-	MOVL	$2, CX  // F_SETFD
-	MOVL	$1, DX  // FD_CLOEXEC
-	INVOKE_SYSCALL
-	RET
-
 // int access(const char *name, int mode)
 TEXT runtime·access(SB),NOSPLIT,$0
 	MOVL	$SYS_access, AX
diff --git a/src/runtime/sys_linux_amd64.s b/src/runtime/sys_linux_amd64.s
index ca6ecb1..c7a89ba 100644
--- a/src/runtime/sys_linux_amd64.s
+++ b/src/runtime/sys_linux_amd64.s
@@ -33,24 +33,19 @@
 #define SYS_clone		56
 #define SYS_exit		60
 #define SYS_kill		62
-#define SYS_fcntl		72
 #define SYS_sigaltstack 	131
 #define SYS_arch_prctl		158
 #define SYS_gettid		186
 #define SYS_futex		202
 #define SYS_sched_getaffinity	204
-#define SYS_epoll_create	213
 #define SYS_timer_create	222
 #define SYS_timer_settime	223
 #define SYS_timer_delete	226
 #define SYS_clock_gettime	228
 #define SYS_exit_group		231
-#define SYS_epoll_ctl		233
 #define SYS_tgkill		234
 #define SYS_openat		257
 #define SYS_faccessat		269
-#define SYS_epoll_pwait		281
-#define SYS_epoll_create1	291
 #define SYS_pipe2		293
 
 TEXT runtime·exit(SB),NOSPLIT,$0-4
@@ -59,7 +54,7 @@
 	SYSCALL
 	RET
 
-// func exitThread(wait *uint32)
+// func exitThread(wait *atomic.Uint32)
 TEXT runtime·exitThread(SB),NOSPLIT,$0-8
 	MOVQ	wait+0(FP), AX
 	// We're done using the stack.
@@ -666,55 +661,6 @@
 	MOVL	AX, ret+24(FP)
 	RET
 
-// int32 runtime·epollcreate(int32 size);
-TEXT runtime·epollcreate(SB),NOSPLIT,$0
-	MOVL    size+0(FP), DI
-	MOVL    $SYS_epoll_create, AX
-	SYSCALL
-	MOVL	AX, ret+8(FP)
-	RET
-
-// int32 runtime·epollcreate1(int32 flags);
-TEXT runtime·epollcreate1(SB),NOSPLIT,$0
-	MOVL	flags+0(FP), DI
-	MOVL	$SYS_epoll_create1, AX
-	SYSCALL
-	MOVL	AX, ret+8(FP)
-	RET
-
-// func epollctl(epfd, op, fd int32, ev *epollEvent) int
-TEXT runtime·epollctl(SB),NOSPLIT,$0
-	MOVL	epfd+0(FP), DI
-	MOVL	op+4(FP), SI
-	MOVL	fd+8(FP), DX
-	MOVQ	ev+16(FP), R10
-	MOVL	$SYS_epoll_ctl, AX
-	SYSCALL
-	MOVL	AX, ret+24(FP)
-	RET
-
-// int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout);
-TEXT runtime·epollwait(SB),NOSPLIT,$0
-	// This uses pwait instead of wait, because Android O blocks wait.
-	MOVL	epfd+0(FP), DI
-	MOVQ	ev+8(FP), SI
-	MOVL	nev+16(FP), DX
-	MOVL	timeout+20(FP), R10
-	MOVQ	$0, R8
-	MOVL	$SYS_epoll_pwait, AX
-	SYSCALL
-	MOVL	AX, ret+24(FP)
-	RET
-
-// void runtime·closeonexec(int32 fd);
-TEXT runtime·closeonexec(SB),NOSPLIT,$0
-	MOVL    fd+0(FP), DI  // fd
-	MOVQ    $2, SI  // F_SETFD
-	MOVQ    $1, DX  // FD_CLOEXEC
-	MOVL	$SYS_fcntl, AX
-	SYSCALL
-	RET
-
 // int access(const char *name, int mode)
 TEXT runtime·access(SB),NOSPLIT,$0
 	// This uses faccessat instead of access, because Android O blocks access.
diff --git a/src/runtime/sys_linux_arm.s b/src/runtime/sys_linux_arm.s
index 66bf403..7b8c4f0 100644
--- a/src/runtime/sys_linux_arm.s
+++ b/src/runtime/sys_linux_arm.s
@@ -41,15 +41,10 @@
 #define SYS_nanosleep (SYS_BASE + 162)
 #define SYS_sched_getaffinity (SYS_BASE + 242)
 #define SYS_clock_gettime (SYS_BASE + 263)
-#define SYS_epoll_create (SYS_BASE + 250)
-#define SYS_epoll_ctl (SYS_BASE + 251)
-#define SYS_epoll_wait (SYS_BASE + 252)
 #define SYS_timer_create (SYS_BASE + 257)
 #define SYS_timer_settime (SYS_BASE + 258)
 #define SYS_timer_delete (SYS_BASE + 261)
-#define SYS_epoll_create1 (SYS_BASE + 357)
 #define SYS_pipe2 (SYS_BASE + 359)
-#define SYS_fcntl (SYS_BASE + 55)
 #define SYS_access (SYS_BASE + 33)
 #define SYS_connect (SYS_BASE + 283)
 #define SYS_socket (SYS_BASE + 281)
@@ -122,7 +117,7 @@
 	MOVW	$1003, R1
 	MOVW	R0, (R1)	// fail hard
 
-// func exitThread(wait *uint32)
+// func exitThread(wait *atomic.Uint32)
 TEXT runtime·exitThread(SB),NOSPLIT|NOFRAME,$0-4
 	MOVW	wait+0(FP), R0
 	// We're done using the stack.
@@ -262,73 +257,105 @@
 	MOVW	R0, ret+12(FP)
 	RET
 
-TEXT runtime·walltime(SB),NOSPLIT,$8-12
+// Call a VDSO function.
+//
+// R0-R3: arguments to VDSO function (C calling convention)
+// R4: uintptr function to call
+//
+// There is no return value.
+TEXT runtime·vdsoCall(SB),NOSPLIT,$8-0
+	// R0-R3 may be arguments to fn, do not touch.
+	// R4 is function to call.
+	// R5-R9 are available as locals. They are unchanged by the C call
+	// (callee-save).
+
 	// We don't know how much stack space the VDSO code will need,
 	// so switch to g0.
 
 	// Save old SP. Use R13 instead of SP to avoid linker rewriting the offsets.
-	MOVW	R13, R4	// R4 is unchanged by C code.
+	MOVW	R13, R5
 
-	MOVW	g_m(g), R5 // R5 is unchanged by C code.
+	MOVW	g_m(g), R6
 
 	// Set vdsoPC and vdsoSP for SIGPROF traceback.
 	// Save the old values on stack and restore them on exit,
 	// so this function is reentrant.
-	MOVW	m_vdsoPC(R5), R1
-	MOVW	m_vdsoSP(R5), R2
-	MOVW	R1, 4(R13)
-	MOVW	R2, 8(R13)
+	MOVW	m_vdsoPC(R6), R7
+	MOVW	m_vdsoSP(R6), R8
+	MOVW	R7, 4(R13)
+	MOVW	R8, 8(R13)
 
-	MOVW	$ret-4(FP), R2 // caller's SP
-	MOVW	LR, m_vdsoPC(R5)
-	MOVW	R2, m_vdsoSP(R5)
+	MOVW	$sp-4(FP), R7 // caller's SP
+	MOVW	LR, m_vdsoPC(R6)
+	MOVW	R7, m_vdsoSP(R6)
 
-	MOVW	m_curg(R5), R0
+	MOVW	m_curg(R6), R7
 
-	CMP	g, R0		// Only switch if on curg.
+	CMP	g, R7		// Only switch if on curg.
 	B.NE	noswitch
 
-	MOVW	m_g0(R5), R0
-	MOVW	(g_sched+gobuf_sp)(R0), R13	 // Set SP to g0 stack
+	MOVW	m_g0(R6), R7
+	MOVW	(g_sched+gobuf_sp)(R7), R13	 // Set SP to g0 stack
 
 noswitch:
-	SUB	$24, R13	// Space for results
 	BIC	$0x7, R13	// Align for C code
 
-	MOVW	$CLOCK_REALTIME, R0
-	MOVW	$8(R13), R1	// timespec
-	MOVW	runtime·vdsoClockgettimeSym(SB), R2
-	CMP	$0, R2
-	B.EQ	fallback
-
 	// Store g on gsignal's stack, so if we receive a signal
 	// during VDSO code we can find the g.
-	// If we don't have a signal stack, we won't receive signal,
-	// so don't bother saving g.
-	// When using cgo, we already saved g on TLS, also don't save
-	// g here.
-	// Also don't save g if we are already on the signal stack.
-	// We won't get a nested signal.
-	MOVB	runtime·iscgo(SB), R6
-	CMP	$0, R6
+
+	// When using cgo, we already saved g on TLS, also don't save g here.
+	MOVB	runtime·iscgo(SB), R7
+	CMP	$0, R7
 	BNE	nosaveg
-	MOVW	m_gsignal(R5), R6          // g.m.gsignal
-	CMP	$0, R6
+	// If we don't have a signal stack, we won't receive signal, so don't
+	// bother saving g.
+	MOVW	m_gsignal(R6), R7          // g.m.gsignal
+	CMP	$0, R7
 	BEQ	nosaveg
-	CMP	g, R6
+	// Don't save g if we are already on the signal stack, as we won't get
+	// a nested signal.
+	CMP	g, R7
 	BEQ	nosaveg
-	MOVW	(g_stack+stack_lo)(R6), R6 // g.m.gsignal.stack.lo
-	MOVW	g, (R6)
+	// If we don't have a signal stack, we won't receive signal, so don't
+	// bother saving g.
+	MOVW	(g_stack+stack_lo)(R7), R7 // g.m.gsignal.stack.lo
+	CMP	$0, R7
+	BEQ	nosaveg
+	MOVW	g, (R7)
 
-	BL	(R2)
+	BL	(R4)
 
-	MOVW	$0, R1
-	MOVW	R1, (R6) // clear g slot, R6 is unchanged by C code
+	MOVW	$0, R8
+	MOVW	R8, (R7) // clear g slot
 
 	JMP	finish
 
 nosaveg:
-	BL	(R2)
+	BL	(R4)
+
+finish:
+	MOVW	R5, R13		// Restore real SP
+	// Restore vdsoPC, vdsoSP
+	// We don't worry about being signaled between the two stores.
+	// If we are not in a signal handler, we'll restore vdsoSP to 0,
+	// and no one will care about vdsoPC. If we are in a signal handler,
+	// we cannot receive another signal.
+	MOVW	8(R13), R7
+	MOVW	R7, m_vdsoSP(R6)
+	MOVW	4(R13), R7
+	MOVW	R7, m_vdsoPC(R6)
+	RET
+
+TEXT runtime·walltime(SB),NOSPLIT,$12-12
+	MOVW	$CLOCK_REALTIME, R0
+	MOVW	$spec-12(SP), R1	// timespec
+
+	MOVW	runtime·vdsoClockgettimeSym(SB), R4
+	CMP	$0, R4
+	B.EQ	fallback
+
+	BL	runtime·vdsoCall(SB)
+
 	JMP	finish
 
 fallback:
@@ -336,19 +363,8 @@
 	SWI	$0
 
 finish:
-	MOVW	8(R13), R0  // sec
-	MOVW	12(R13), R2  // nsec
-
-	MOVW	R4, R13		// Restore real SP
-	// Restore vdsoPC, vdsoSP
-	// We don't worry about being signaled between the two stores.
-	// If we are not in a signal handler, we'll restore vdsoSP to 0,
-	// and no one will care about vdsoPC. If we are in a signal handler,
-	// we cannot receive another signal.
-	MOVW	8(R13), R1
-	MOVW	R1, m_vdsoSP(R5)
-	MOVW	4(R13), R1
-	MOVW	R1, m_vdsoPC(R5)
+	MOVW	sec-12(SP), R0  // sec
+	MOVW	nsec-8(SP), R2  // nsec
 
 	MOVW	R0, sec_lo+0(FP)
 	MOVW	$0, R1
@@ -356,73 +372,17 @@
 	MOVW	R2, nsec+8(FP)
 	RET
 
-// int64 nanotime1(void)
-TEXT runtime·nanotime1(SB),NOSPLIT,$8-8
-	// Switch to g0 stack. See comment above in runtime·walltime.
-
-	// Save old SP. Use R13 instead of SP to avoid linker rewriting the offsets.
-	MOVW	R13, R4	// R4 is unchanged by C code.
-
-	MOVW	g_m(g), R5 // R5 is unchanged by C code.
-
-	// Set vdsoPC and vdsoSP for SIGPROF traceback.
-	// Save the old values on stack and restore them on exit,
-	// so this function is reentrant.
-	MOVW	m_vdsoPC(R5), R1
-	MOVW	m_vdsoSP(R5), R2
-	MOVW	R1, 4(R13)
-	MOVW	R2, 8(R13)
-
-	MOVW	$ret-4(FP), R2 // caller's SP
-	MOVW	LR, m_vdsoPC(R5)
-	MOVW	R2, m_vdsoSP(R5)
-
-	MOVW	m_curg(R5), R0
-
-	CMP	g, R0		// Only switch if on curg.
-	B.NE	noswitch
-
-	MOVW	m_g0(R5), R0
-	MOVW	(g_sched+gobuf_sp)(R0), R13	// Set SP to g0 stack
-
-noswitch:
-	SUB	$24, R13	// Space for results
-	BIC	$0x7, R13	// Align for C code
-
+// func nanotime1() int64
+TEXT runtime·nanotime1(SB),NOSPLIT,$12-8
 	MOVW	$CLOCK_MONOTONIC, R0
-	MOVW	$8(R13), R1	// timespec
-	MOVW	runtime·vdsoClockgettimeSym(SB), R2
-	CMP	$0, R2
+	MOVW	$spec-12(SP), R1	// timespec
+
+	MOVW	runtime·vdsoClockgettimeSym(SB), R4
+	CMP	$0, R4
 	B.EQ	fallback
 
-	// Store g on gsignal's stack, so if we receive a signal
-	// during VDSO code we can find the g.
-	// If we don't have a signal stack, we won't receive signal,
-	// so don't bother saving g.
-	// When using cgo, we already saved g on TLS, also don't save
-	// g here.
-	// Also don't save g if we are already on the signal stack.
-	// We won't get a nested signal.
-	MOVB	runtime·iscgo(SB), R6
-	CMP	$0, R6
-	BNE	nosaveg
-	MOVW	m_gsignal(R5), R6          // g.m.gsignal
-	CMP	$0, R6
-	BEQ	nosaveg
-	CMP	g, R6
-	BEQ	nosaveg
-	MOVW	(g_stack+stack_lo)(R6), R6 // g.m.gsignal.stack.lo
-	MOVW	g, (R6)
+	BL	runtime·vdsoCall(SB)
 
-	BL	(R2)
-
-	MOVW	$0, R1
-	MOVW	R1, (R6) // clear g slot, R6 is unchanged by C code
-
-	JMP	finish
-
-nosaveg:
-	BL	(R2)
 	JMP	finish
 
 fallback:
@@ -430,19 +390,8 @@
 	SWI	$0
 
 finish:
-	MOVW	8(R13), R0	// sec
-	MOVW	12(R13), R2	// nsec
-
-	MOVW	R4, R13		// Restore real SP
-	// Restore vdsoPC, vdsoSP
-	// We don't worry about being signaled between the two stores.
-	// If we are not in a signal handler, we'll restore vdsoSP to 0,
-	// and no one will care about vdsoPC. If we are in a signal handler,
-	// we cannot receive another signal.
-	MOVW	8(R13), R4
-	MOVW	R4, m_vdsoSP(R5)
-	MOVW	4(R13), R4
-	MOVW	R4, m_vdsoPC(R5)
+	MOVW	sec-12(SP), R0  // sec
+	MOVW	nsec-8(SP), R2  // nsec
 
 	MOVW	$1000000000, R3
 	MULLU	R0, R3, (R1, R0)
@@ -451,6 +400,7 @@
 
 	MOVW	R0, ret_lo+0(FP)
 	MOVW	R1, ret_hi+4(FP)
+
 	RET
 
 // int32 futex(int32 *uaddr, int32 op, int32 val,
@@ -661,53 +611,6 @@
 	MOVW	R0, ret+12(FP)
 	RET
 
-// int32 runtime·epollcreate(int32 size)
-TEXT runtime·epollcreate(SB),NOSPLIT,$0
-	MOVW	size+0(FP), R0
-	MOVW	$SYS_epoll_create, R7
-	SWI	$0
-	MOVW	R0, ret+4(FP)
-	RET
-
-// int32 runtime·epollcreate1(int32 flags)
-TEXT runtime·epollcreate1(SB),NOSPLIT,$0
-	MOVW	flags+0(FP), R0
-	MOVW	$SYS_epoll_create1, R7
-	SWI	$0
-	MOVW	R0, ret+4(FP)
-	RET
-
-// func epollctl(epfd, op, fd int32, ev *epollEvent) int
-TEXT runtime·epollctl(SB),NOSPLIT,$0
-	MOVW	epfd+0(FP), R0
-	MOVW	op+4(FP), R1
-	MOVW	fd+8(FP), R2
-	MOVW	ev+12(FP), R3
-	MOVW	$SYS_epoll_ctl, R7
-	SWI	$0
-	MOVW	R0, ret+16(FP)
-	RET
-
-// int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout)
-TEXT runtime·epollwait(SB),NOSPLIT,$0
-	MOVW	epfd+0(FP), R0
-	MOVW	ev+4(FP), R1
-	MOVW	nev+8(FP), R2
-	MOVW	timeout+12(FP), R3
-	MOVW	$SYS_epoll_wait, R7
-	SWI	$0
-	MOVW	R0, ret+16(FP)
-	RET
-
-// void runtime·closeonexec(int32 fd)
-TEXT runtime·closeonexec(SB),NOSPLIT,$0
-	MOVW	fd+0(FP), R0	// fd
-	MOVW	$2, R1	// F_SETFD
-	MOVW	$1, R2	// FD_CLOEXEC
-	MOVW	$SYS_fcntl, R7
-	SWI	$0
-	RET
-
 // b __kuser_get_tls @ 0xffff0fe0
 TEXT runtime·read_tls_fallback(SB),NOSPLIT|NOFRAME,$0
 	MOVW	$0xffff0fe0, R0
diff --git a/src/runtime/sys_linux_arm64.s b/src/runtime/sys_linux_arm64.s
index b47b6fd..38ff6ac 100644
--- a/src/runtime/sys_linux_arm64.s
+++ b/src/runtime/sys_linux_arm64.s
@@ -22,7 +22,6 @@
 #define SYS_openat		56
 #define SYS_close		57
 #define SYS_pipe2		59
-#define SYS_fcntl		25
 #define SYS_nanosleep		101
 #define SYS_mmap		222
 #define SYS_munmap		215
@@ -42,9 +41,6 @@
 #define SYS_futex		98
 #define SYS_sched_getaffinity	123
 #define SYS_exit_group		94
-#define SYS_epoll_create1	20
-#define SYS_epoll_ctl		21
-#define SYS_epoll_pwait		22
 #define SYS_clock_gettime	113
 #define SYS_faccessat		48
 #define SYS_socket		198
@@ -60,7 +56,7 @@
 	SVC
 	RET
 
-// func exitThread(wait *uint32)
+// func exitThread(wait *atomic.Uint32)
 TEXT runtime·exitThread(SB),NOSPLIT|NOFRAME,$0-8
 	MOVD	wait+0(FP), R0
 	// We're done using the stack.
@@ -762,54 +758,6 @@
 	MOVW	R0, ret+24(FP)
 	RET
 
-// int32 runtime·epollcreate(int32 size);
-TEXT runtime·epollcreate(SB),NOSPLIT|NOFRAME,$0
-	MOVW	$0, R0
-	MOVD	$SYS_epoll_create1, R8
-	SVC
-	MOVW	R0, ret+8(FP)
-	RET
-
-// int32 runtime·epollcreate1(int32 flags);
-TEXT runtime·epollcreate1(SB),NOSPLIT|NOFRAME,$0
-	MOVW	flags+0(FP), R0
-	MOVD	$SYS_epoll_create1, R8
-	SVC
-	MOVW	R0, ret+8(FP)
-	RET
-
-// func epollctl(epfd, op, fd int32, ev *epollEvent) int
-TEXT runtime·epollctl(SB),NOSPLIT|NOFRAME,$0
-	MOVW	epfd+0(FP), R0
-	MOVW	op+4(FP), R1
-	MOVW	fd+8(FP), R2
-	MOVD	ev+16(FP), R3
-	MOVD	$SYS_epoll_ctl, R8
-	SVC
-	MOVW	R0, ret+24(FP)
-	RET
-
-// int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout);
-TEXT runtime·epollwait(SB),NOSPLIT|NOFRAME,$0
-	MOVW	epfd+0(FP), R0
-	MOVD	ev+8(FP), R1
-	MOVW	nev+16(FP), R2
-	MOVW	timeout+20(FP), R3
-	MOVD	$0, R4
-	MOVD	$SYS_epoll_pwait, R8
-	SVC
-	MOVW	R0, ret+24(FP)
-	RET
-
-// void runtime·closeonexec(int32 fd);
-TEXT runtime·closeonexec(SB),NOSPLIT|NOFRAME,$0
-	MOVW	fd+0(FP), R0  // fd
-	MOVD	$2, R1	// F_SETFD
-	MOVD	$1, R2	// FD_CLOEXEC
-	MOVD	$SYS_fcntl, R8
-	SVC
-	RET
-
 // int access(const char *name, int mode)
 TEXT runtime·access(SB),NOSPLIT,$0-20
 	MOVD	$AT_FDCWD, R0
diff --git a/src/runtime/sys_linux_loong64.s b/src/runtime/sys_linux_loong64.s
index 36a92df..9ce5e72 100644
--- a/src/runtime/sys_linux_loong64.s
+++ b/src/runtime/sys_linux_loong64.s
@@ -18,7 +18,6 @@
 #define SYS_close		57
 #define SYS_getpid		172
 #define SYS_kill		129
-#define SYS_fcntl		25
 #define SYS_mmap		222
 #define SYS_munmap		215
 #define SYS_setitimer		103
@@ -35,12 +34,9 @@
 #define SYS_futex		98
 #define SYS_sched_getaffinity	123
 #define SYS_exit_group		94
-#define SYS_epoll_ctl		21
 #define SYS_tgkill		131
 #define SYS_openat		56
-#define SYS_epoll_pwait		22
 #define SYS_clock_gettime	113
-#define SYS_epoll_create1	20
 #define SYS_brk			214
 #define SYS_pipe2		59
 #define SYS_timer_create	107
@@ -53,7 +49,7 @@
 	SYSCALL
 	RET
 
-// func exitThread(wait *uint32)
+// func exitThread(wait *atomic.Uint32)
 TEXT runtime·exitThread(SB),NOSPLIT|NOFRAME,$0-8
 	MOVV	wait+0(FP), R19
 	// We're done using the stack.
@@ -534,54 +530,6 @@
 	MOVW	R4, ret+24(FP)
 	RET
 
-// int32 runtime·epollcreate(int32 size);
-TEXT runtime·epollcreate(SB),NOSPLIT|NOFRAME,$0
-	MOVW	size+0(FP), R4
-	MOVV	$SYS_epoll_create1, R11
-	SYSCALL
-	MOVW	R4, ret+8(FP)
-	RET
-
-// int32 runtime·epollcreate1(int32 flags);
-TEXT runtime·epollcreate1(SB),NOSPLIT|NOFRAME,$0
-	MOVW	flags+0(FP), R4
-	MOVV	$SYS_epoll_create1, R11
-	SYSCALL
-	MOVW	R4, ret+8(FP)
-	RET
-
-// func epollctl(epfd, op, fd int32, ev *epollEvent) int
-TEXT runtime·epollctl(SB),NOSPLIT|NOFRAME,$0
-	MOVW	epfd+0(FP), R4
-	MOVW	op+4(FP), R5
-	MOVW	fd+8(FP), R6
-	MOVV	ev+16(FP), R7
-	MOVV	$SYS_epoll_ctl, R11
-	SYSCALL
-	MOVW	R4, ret+24(FP)
-	RET
-
-// int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout);
-TEXT runtime·epollwait(SB),NOSPLIT|NOFRAME,$0
-	MOVW	epfd+0(FP), R4
-	MOVV	ev+8(FP), R5
-	MOVW	nev+16(FP), R6
-	MOVW	timeout+20(FP), R7
-	MOVV	$0, R8
-	MOVV	$SYS_epoll_pwait, R11
-	SYSCALL
-	MOVW	R4, ret+24(FP)
-	RET
-
-// void runtime·closeonexec(int32 fd);
-TEXT runtime·closeonexec(SB),NOSPLIT|NOFRAME,$0
-	MOVW	fd+0(FP), R4  // fd
-	MOVV	$2, R5	// F_SETFD
-	MOVV	$1, R6	// FD_CLOEXEC
-	MOVV	$SYS_fcntl, R11
-	SYSCALL
-	RET
-
 // func sbrk0() uintptr
 TEXT runtime·sbrk0(SB),NOSPLIT|NOFRAME,$0-8
 	// Implemented as brk(NULL).
diff --git a/src/runtime/sys_linux_mips64x.s b/src/runtime/sys_linux_mips64x.s
index 06d54df..47f2da5 100644
--- a/src/runtime/sys_linux_mips64x.s
+++ b/src/runtime/sys_linux_mips64x.s
@@ -20,7 +20,6 @@
 #define SYS_close		5003
 #define SYS_getpid		5038
 #define SYS_kill		5060
-#define SYS_fcntl		5070
 #define SYS_mmap		5009
 #define SYS_munmap		5011
 #define SYS_setitimer		5036
@@ -37,16 +36,12 @@
 #define SYS_futex		5194
 #define SYS_sched_getaffinity	5196
 #define SYS_exit_group		5205
-#define SYS_epoll_create	5207
-#define SYS_epoll_ctl		5208
 #define SYS_timer_create	5216
 #define SYS_timer_settime	5217
 #define SYS_timer_delete	5220
 #define SYS_tgkill		5225
 #define SYS_openat		5247
-#define SYS_epoll_pwait		5272
 #define SYS_clock_gettime	5222
-#define SYS_epoll_create1	5285
 #define SYS_brk			5012
 #define SYS_pipe2		5287
 
@@ -56,7 +51,7 @@
 	SYSCALL
 	RET
 
-// func exitThread(wait *uint32)
+// func exitThread(wait *atomic.Uint32)
 TEXT runtime·exitThread(SB),NOSPLIT|NOFRAME,$0-8
 	MOVV	wait+0(FP), R1
 	// We're done using the stack.
@@ -568,62 +563,6 @@
 	MOVW	R2, ret+24(FP)
 	RET
 
-// int32 runtime·epollcreate(int32 size);
-TEXT runtime·epollcreate(SB),NOSPLIT|NOFRAME,$0
-	MOVW    size+0(FP), R4
-	MOVV	$SYS_epoll_create, R2
-	SYSCALL
-	BEQ	R7, 2(PC)
-	SUBVU	R2, R0, R2	// caller expects negative errno
-	MOVW	R2, ret+8(FP)
-	RET
-
-// int32 runtime·epollcreate1(int32 flags);
-TEXT runtime·epollcreate1(SB),NOSPLIT|NOFRAME,$0
-	MOVW	flags+0(FP), R4
-	MOVV	$SYS_epoll_create1, R2
-	SYSCALL
-	BEQ	R7, 2(PC)
-	SUBVU	R2, R0, R2	// caller expects negative errno
-	MOVW	R2, ret+8(FP)
-	RET
-
-// func epollctl(epfd, op, fd int32, ev *epollEvent) int
-TEXT runtime·epollctl(SB),NOSPLIT|NOFRAME,$0
-	MOVW	epfd+0(FP), R4
-	MOVW	op+4(FP), R5
-	MOVW	fd+8(FP), R6
-	MOVV	ev+16(FP), R7
-	MOVV	$SYS_epoll_ctl, R2
-	SYSCALL
-	SUBVU	R2, R0, R2	// caller expects negative errno
-	MOVW	R2, ret+24(FP)
-	RET
-
-// int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout);
-TEXT runtime·epollwait(SB),NOSPLIT|NOFRAME,$0
-	// This uses pwait instead of wait, because Android O blocks wait.
-	MOVW	epfd+0(FP), R4
-	MOVV	ev+8(FP), R5
-	MOVW	nev+16(FP), R6
-	MOVW	timeout+20(FP), R7
-	MOVV	$0, R8
-	MOVV	$SYS_epoll_pwait, R2
-	SYSCALL
-	BEQ	R7, 2(PC)
-	SUBVU	R2, R0, R2	// caller expects negative errno
-	MOVW	R2, ret+24(FP)
-	RET
-
-// void runtime·closeonexec(int32 fd);
-TEXT runtime·closeonexec(SB),NOSPLIT|NOFRAME,$0
-	MOVW    fd+0(FP), R4  // fd
-	MOVV    $2, R5  // F_SETFD
-	MOVV    $1, R6  // FD_CLOEXEC
-	MOVV	$SYS_fcntl, R2
-	SYSCALL
-	RET
-
 // func sbrk0() uintptr
 TEXT runtime·sbrk0(SB),NOSPLIT|NOFRAME,$0-8
 	// Implemented as brk(NULL).
diff --git a/src/runtime/sys_linux_mipsx.s b/src/runtime/sys_linux_mipsx.s
index e70edcc..5e6b6c1 100644
--- a/src/runtime/sys_linux_mipsx.s
+++ b/src/runtime/sys_linux_mipsx.s
@@ -20,7 +20,6 @@
 #define SYS_getpid		4020
 #define SYS_kill		4037
 #define SYS_brk			4045
-#define SYS_fcntl		4055
 #define SYS_mmap		4090
 #define SYS_munmap		4091
 #define SYS_setitimer		4104
@@ -37,15 +36,11 @@
 #define SYS_futex		4238
 #define SYS_sched_getaffinity	4240
 #define SYS_exit_group		4246
-#define SYS_epoll_create	4248
-#define SYS_epoll_ctl		4249
-#define SYS_epoll_wait		4250
 #define SYS_timer_create	4257
 #define SYS_timer_settime	4258
 #define SYS_timer_delete	4261
 #define SYS_clock_gettime	4263
 #define SYS_tgkill		4266
-#define SYS_epoll_create1	4326
 #define SYS_pipe2		4328
 
 TEXT runtime·exit(SB),NOSPLIT,$0-4
@@ -55,7 +50,7 @@
 	UNDEF
 	RET
 
-// func exitThread(wait *uint32)
+// func exitThread(wait *atomic.Uint32)
 TEXT runtime·exitThread(SB),NOSPLIT,$0-4
 	MOVW	wait+0(FP), R1
 	// We're done using the stack.
@@ -487,60 +482,6 @@
 	MOVW	R2, ret+12(FP)
 	RET
 
-// int32 runtime·epollcreate(int32 size);
-TEXT runtime·epollcreate(SB),NOSPLIT,$0-8
-	MOVW	size+0(FP), R4
-	MOVW	$SYS_epoll_create, R2
-	SYSCALL
-	BEQ	R7, 2(PC)
-	SUBU	R2, R0, R2	// caller expects negative errno
-	MOVW	R2, ret+4(FP)
-	RET
-
-// int32 runtime·epollcreate1(int32 flags);
-TEXT runtime·epollcreate1(SB),NOSPLIT,$0-8
-	MOVW	flags+0(FP), R4
-	MOVW	$SYS_epoll_create1, R2
-	SYSCALL
-	BEQ	R7, 2(PC)
-	SUBU	R2, R0, R2	// caller expects negative errno
-	MOVW	R2, ret+4(FP)
-	RET
-
-// func epollctl(epfd, op, fd int32, ev *epollEvent) int
-TEXT runtime·epollctl(SB),NOSPLIT,$0-20
-	MOVW	epfd+0(FP), R4
-	MOVW	op+4(FP), R5
-	MOVW	fd+8(FP), R6
-	MOVW	ev+12(FP), R7
-	MOVW	$SYS_epoll_ctl, R2
-	SYSCALL
-	SUBU	R2, R0, R2	// caller expects negative errno
-	MOVW	R2, ret+16(FP)
-	RET
-
-// int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout);
-TEXT runtime·epollwait(SB),NOSPLIT,$0-20
-	MOVW	epfd+0(FP), R4
-	MOVW	ev+4(FP), R5
-	MOVW	nev+8(FP), R6
-	MOVW	timeout+12(FP), R7
-	MOVW	$SYS_epoll_wait, R2
-	SYSCALL
-	BEQ	R7, 2(PC)
-	SUBU	R2, R0, R2	// caller expects negative errno
-	MOVW	R2, ret+16(FP)
-	RET
-
-// void runtime·closeonexec(int32 fd);
-TEXT runtime·closeonexec(SB),NOSPLIT,$0-4
-	MOVW	fd+0(FP), R4	// fd
-	MOVW	$2, R5	// F_SETFD
-	MOVW	$1, R6	// FD_CLOEXEC
-	MOVW	$SYS_fcntl, R2
-	SYSCALL
-	RET
-
 // func sbrk0() uintptr
 TEXT runtime·sbrk0(SB),NOSPLIT,$0-4
 	// Implemented as brk(NULL).
diff --git a/src/runtime/sys_linux_ppc64x.s b/src/runtime/sys_linux_ppc64x.s
index 2913a05..d0427a4 100644
--- a/src/runtime/sys_linux_ppc64x.s
+++ b/src/runtime/sys_linux_ppc64x.s
@@ -21,7 +21,6 @@
 #define SYS_getpid		 20
 #define SYS_kill		 37
 #define SYS_brk			 45
-#define SYS_fcntl		 55
 #define SYS_mmap		 90
 #define SYS_munmap		 91
 #define SYS_setitimer		104
@@ -38,15 +37,11 @@
 #define SYS_futex		221
 #define SYS_sched_getaffinity	223
 #define SYS_exit_group		234
-#define SYS_epoll_create	236
-#define SYS_epoll_ctl		237
-#define SYS_epoll_wait		238
 #define SYS_timer_create	240
 #define SYS_timer_settime	241
 #define SYS_timer_delete	244
 #define SYS_clock_gettime	246
 #define SYS_tgkill		250
-#define SYS_epoll_create1	315
 #define SYS_pipe2		317
 
 TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0-4
@@ -54,7 +49,7 @@
 	SYSCALL	$SYS_exit_group
 	RET
 
-// func exitThread(wait *uint32)
+// func exitThread(wait *atomic.Uint32)
 TEXT runtime·exitThread(SB),NOSPLIT|NOFRAME,$0-8
 	MOVD	wait+0(FP), R1
 	// We're done using the stack.
@@ -111,16 +106,22 @@
 	MOVW	R3, errno+16(FP)
 	RET
 
+// func usleep(usec uint32)
 TEXT runtime·usleep(SB),NOSPLIT,$16-4
 	MOVW	usec+0(FP), R3
-	MOVD	R3, R5
-	MOVW	$1000000, R4
-	DIVD	R4, R3
-	MOVD	R3, 8(R1)
-	MOVW	$1000, R4
-	MULLD	R3, R4
-	SUB	R4, R5
-	MOVD	R5, 16(R1)
+
+	// Use magic constant 0x8637bd06 and shift right 51
+	// to perform usec/1000000.
+	MOVD	$0x8637bd06, R4
+	MULLD	R3, R4, R4	// Convert usec to S.
+	SRD	$51, R4, R4
+	MOVD	R4, 8(R1)	// Store to tv_sec
+
+	MOVD	$1000000, R5
+	MULLW	R4, R5, R5	// Convert tv_sec back into uS
+	SUB	R5, R3, R5	// Compute remainder uS.
+	MULLD	$1000, R5, R5	// Convert to nsec
+	MOVD	R5, 16(R1)	// Store to tv_nsec
 
 	// nanosleep(&ts, 0)
 	ADD	$8, R1, R3
@@ -876,55 +877,6 @@
 	MOVW	R3, ret+24(FP)
 	RET
 
-// int32 runtime·epollcreate(int32 size);
-TEXT runtime·epollcreate(SB),NOSPLIT|NOFRAME,$0
-	MOVW    size+0(FP), R3
-	SYSCALL	$SYS_epoll_create
-	BVC	2(PC)
-	NEG	R3	// caller expects negative errno
-	MOVW	R3, ret+8(FP)
-	RET
-
-// int32 runtime·epollcreate1(int32 flags);
-TEXT runtime·epollcreate1(SB),NOSPLIT|NOFRAME,$0
-	MOVW	flags+0(FP), R3
-	SYSCALL	$SYS_epoll_create1
-	BVC	2(PC)
-	NEG	R3	// caller expects negative errno
-	MOVW	R3, ret+8(FP)
-	RET
-
-// func epollctl(epfd, op, fd int32, ev *epollEvent) int
-TEXT runtime·epollctl(SB),NOSPLIT|NOFRAME,$0
-	MOVW	epfd+0(FP), R3
-	MOVW	op+4(FP), R4
-	MOVW	fd+8(FP), R5
-	MOVD	ev+16(FP), R6
-	SYSCALL	$SYS_epoll_ctl
-	NEG	R3	// caller expects negative errno
-	MOVW	R3, ret+24(FP)
-	RET
-
-// int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout);
-TEXT runtime·epollwait(SB),NOSPLIT|NOFRAME,$0
-	MOVW	epfd+0(FP), R3
-	MOVD	ev+8(FP), R4
-	MOVW	nev+16(FP), R5
-	MOVW	timeout+20(FP), R6
-	SYSCALL	$SYS_epoll_wait
-	BVC	2(PC)
-	NEG	R3	// caller expects negative errno
-	MOVW	R3, ret+24(FP)
-	RET
-
-// void runtime·closeonexec(int32 fd);
-TEXT runtime·closeonexec(SB),NOSPLIT|NOFRAME,$0
-	MOVW    fd+0(FP), R3  // fd
-	MOVD    $2, R4  // F_SETFD
-	MOVD    $1, R5  // FD_CLOEXEC
-	SYSCALL	$SYS_fcntl
-	RET
-
 // func sbrk0() uintptr
 TEXT runtime·sbrk0(SB),NOSPLIT|NOFRAME,$0
 	// Implemented as brk(NULL).
diff --git a/src/runtime/sys_linux_riscv64.s b/src/runtime/sys_linux_riscv64.s
index afb2d11..d1558fd 100644
--- a/src/runtime/sys_linux_riscv64.s
+++ b/src/runtime/sys_linux_riscv64.s
@@ -18,13 +18,9 @@
 #define SYS_clone		220
 #define SYS_close		57
 #define SYS_connect		203
-#define SYS_epoll_create1	20
-#define SYS_epoll_ctl		21
-#define SYS_epoll_pwait		22
 #define SYS_exit		93
 #define SYS_exit_group		94
 #define SYS_faccessat		48
-#define SYS_fcntl		25
 #define SYS_futex		98
 #define SYS_getpid		172
 #define SYS_gettid		178
@@ -61,7 +57,7 @@
 	ECALL
 	RET
 
-// func exitThread(wait *uint32)
+// func exitThread(wait *atomic.Uint32)
 TEXT runtime·exitThread(SB),NOSPLIT|NOFRAME,$0-8
 	MOV	wait+0(FP), A0
 	// We're done using the stack.
@@ -578,54 +574,6 @@
 	MOV	A0, ret+24(FP)
 	RET
 
-// func epollcreate(size int32) int32
-TEXT runtime·epollcreate(SB),NOSPLIT|NOFRAME,$0
-	MOV	$0, A0
-	MOV	$SYS_epoll_create1, A7
-	ECALL
-	MOVW	A0, ret+8(FP)
-	RET
-
-// func epollcreate1(flags int32) int32
-TEXT runtime·epollcreate1(SB),NOSPLIT|NOFRAME,$0
-	MOVW	flags+0(FP), A0
-	MOV	$SYS_epoll_create1, A7
-	ECALL
-	MOVW	A0, ret+8(FP)
-	RET
-
-// func epollctl(epfd, op, fd int32, ev *epollevent) int32
-TEXT runtime·epollctl(SB),NOSPLIT|NOFRAME,$0
-	MOVW	epfd+0(FP), A0
-	MOVW	op+4(FP), A1
-	MOVW	fd+8(FP), A2
-	MOV	ev+16(FP), A3
-	MOV	$SYS_epoll_ctl, A7
-	ECALL
-	MOVW	A0, ret+24(FP)
-	RET
-
-// func epollwait(epfd int32, ev *epollevent, nev, timeout int32) int32
-TEXT runtime·epollwait(SB),NOSPLIT|NOFRAME,$0
-	MOVW	epfd+0(FP), A0
-	MOV	ev+8(FP), A1
-	MOVW	nev+16(FP), A2
-	MOVW	timeout+20(FP), A3
-	MOV	$0, A4
-	MOV	$SYS_epoll_pwait, A7
-	ECALL
-	MOVW	A0, ret+24(FP)
-	RET
-
-// func closeonexec(int32)
-TEXT runtime·closeonexec(SB),NOSPLIT|NOFRAME,$0
-	MOVW	fd+0(FP), A0  // fd
-	MOV	$2, A1	// F_SETFD
-	MOV	$1, A2	// FD_CLOEXEC
-	MOV	$SYS_fcntl, A7
-	ECALL
-	RET
-
 // func sbrk0() uintptr
 TEXT runtime·sbrk0(SB),NOSPLIT,$0-8
 	// Implemented as brk(NULL).
diff --git a/src/runtime/sys_linux_s390x.s b/src/runtime/sys_linux_s390x.s
index c82cb9b..1448670 100644
--- a/src/runtime/sys_linux_s390x.s
+++ b/src/runtime/sys_linux_s390x.s
@@ -17,7 +17,6 @@
 #define SYS_getpid               20
 #define SYS_kill                 37
 #define SYS_brk			 45
-#define SYS_fcntl                55
 #define SYS_mmap                 90
 #define SYS_munmap               91
 #define SYS_setitimer           104
@@ -35,15 +34,11 @@
 #define SYS_sched_getaffinity   240
 #define SYS_tgkill              241
 #define SYS_exit_group          248
-#define SYS_epoll_create        249
-#define SYS_epoll_ctl           250
-#define SYS_epoll_wait          251
 #define SYS_timer_create        254
 #define SYS_timer_settime       255
 #define SYS_timer_delete        258
 #define SYS_clock_gettime       260
 #define SYS_pipe2		325
-#define SYS_epoll_create1       327
 
 TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0-4
 	MOVW	code+0(FP), R2
@@ -51,7 +46,7 @@
 	SYSCALL
 	RET
 
-// func exitThread(wait *uint32)
+// func exitThread(wait *atomic.Uint32)
 TEXT runtime·exitThread(SB),NOSPLIT|NOFRAME,$0-8
 	MOVD	wait+0(FP), R1
 	// We're done using the stack.
@@ -589,53 +584,6 @@
 	MOVW	R2, ret+24(FP)
 	RET
 
-// int32 runtime·epollcreate(int32 size);
-TEXT runtime·epollcreate(SB),NOSPLIT|NOFRAME,$0
-	MOVW    size+0(FP), R2
-	MOVW	$SYS_epoll_create, R1
-	SYSCALL
-	MOVW	R2, ret+8(FP)
-	RET
-
-// int32 runtime·epollcreate1(int32 flags);
-TEXT runtime·epollcreate1(SB),NOSPLIT|NOFRAME,$0
-	MOVW	flags+0(FP), R2
-	MOVW	$SYS_epoll_create1, R1
-	SYSCALL
-	MOVW	R2, ret+8(FP)
-	RET
-
-// func epollctl(epfd, op, fd int32, ev *epollEvent) int
-TEXT runtime·epollctl(SB),NOSPLIT|NOFRAME,$0
-	MOVW	epfd+0(FP), R2
-	MOVW	op+4(FP), R3
-	MOVW	fd+8(FP), R4
-	MOVD	ev+16(FP), R5
-	MOVW	$SYS_epoll_ctl, R1
-	SYSCALL
-	MOVW	R2, ret+24(FP)
-	RET
-
-// int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout);
-TEXT runtime·epollwait(SB),NOSPLIT|NOFRAME,$0
-	MOVW	epfd+0(FP), R2
-	MOVD	ev+8(FP), R3
-	MOVW	nev+16(FP), R4
-	MOVW	timeout+20(FP), R5
-	MOVW	$SYS_epoll_wait, R1
-	SYSCALL
-	MOVW	R2, ret+24(FP)
-	RET
-
-// void runtime·closeonexec(int32 fd);
-TEXT runtime·closeonexec(SB),NOSPLIT|NOFRAME,$0
-	MOVW    fd+0(FP), R2  // fd
-	MOVD    $2, R3  // F_SETFD
-	MOVD    $1, R4  // FD_CLOEXEC
-	MOVW	$SYS_fcntl, R1
-	SYSCALL
-	RET
-
 // func sbrk0() uintptr
 TEXT runtime·sbrk0(SB),NOSPLIT|NOFRAME,$0-8
 	// Implemented as brk(NULL).
diff --git a/src/runtime/sys_netbsd_386.s b/src/runtime/sys_netbsd_386.s
index 581b4fc..7be18c6 100644
--- a/src/runtime/sys_netbsd_386.s
+++ b/src/runtime/sys_netbsd_386.s
@@ -53,7 +53,7 @@
 	MOVL	$0xf1, 0xf1		// crash
 	RET
 
-// func exitThread(wait *uint32)
+// func exitThread(wait *atomic.Uint32)
 TEXT runtime·exitThread(SB),NOSPLIT,$0-4
 	MOVL	wait+0(FP), AX
 	// We're done using the stack.
diff --git a/src/runtime/sys_netbsd_amd64.s b/src/runtime/sys_netbsd_amd64.s
index ab11f6f..30f3f38 100644
--- a/src/runtime/sys_netbsd_amd64.s
+++ b/src/runtime/sys_netbsd_amd64.s
@@ -122,7 +122,7 @@
 	MOVL	$0xf1, 0xf1		// crash
 	RET
 
-// func exitThread(wait *uint32)
+// func exitThread(wait *atomic.Uint32)
 TEXT runtime·exitThread(SB),NOSPLIT,$0-8
 	MOVQ	wait+0(FP), AX
 	// We're done using the stack.
diff --git a/src/runtime/sys_netbsd_arm.s b/src/runtime/sys_netbsd_arm.s
index dbe3dbc..62fa852 100644
--- a/src/runtime/sys_netbsd_arm.s
+++ b/src/runtime/sys_netbsd_arm.s
@@ -56,7 +56,7 @@
 	MOVW.CS R8, (R8)
 	RET
 
-// func exitThread(wait *uint32)
+// func exitThread(wait *atomic.Uint32)
 TEXT runtime·exitThread(SB),NOSPLIT,$0-4
 	MOVW wait+0(FP), R0
 	// We're done using the stack.
diff --git a/src/runtime/sys_netbsd_arm64.s b/src/runtime/sys_netbsd_arm64.s
index fc126ca..d57959f 100644
--- a/src/runtime/sys_netbsd_arm64.s
+++ b/src/runtime/sys_netbsd_arm64.s
@@ -115,7 +115,7 @@
 	MOVD	$0, R0			// If we're still running,
 	MOVD	R0, (R0)		// crash
 
-// func exitThread(wait *uint32)
+// func exitThread(wait *atomic.Uint32)
 TEXT runtime·exitThread(SB),NOSPLIT,$0-8
 	MOVD	wait+0(FP), R0
 	// We're done using the stack.
diff --git a/src/runtime/sys_openbsd2.go b/src/runtime/sys_openbsd2.go
index f936e0c..49bad8e 100644
--- a/src/runtime/sys_openbsd2.go
+++ b/src/runtime/sys_openbsd2.go
@@ -8,6 +8,7 @@
 
 import (
 	"internal/abi"
+	"runtime/internal/atomic"
 	"unsafe"
 )
 
@@ -248,7 +249,8 @@
 func sigaltstack_trampoline()
 
 // Not used on OpenBSD, but must be defined.
-func exitThread(wait *uint32) {
+func exitThread(wait *atomic.Uint32) {
+	throw("exitThread")
 }
 
 //go:nosplit
diff --git a/src/runtime/sys_openbsd_mips64.s b/src/runtime/sys_openbsd_mips64.s
index c2b2092..affd586 100644
--- a/src/runtime/sys_openbsd_mips64.s
+++ b/src/runtime/sys_openbsd_mips64.s
@@ -24,7 +24,7 @@
 	MOVV	R2, (R2)
 	RET
 
-// func exitThread(wait *uint32)
+// func exitThread(wait *atomic.Uint32)
 TEXT runtime·exitThread(SB),NOSPLIT,$0
 	MOVV	wait+0(FP), R4		// arg 1 - notdead
 	MOVV	$302, R2		// sys___threxit
@@ -277,7 +277,7 @@
 
 	// In parent, return.
 	BEQ	R2, 3(PC)
-	MOVW	R2, ret+40(FP)
+	MOVW	$0, ret+40(FP)
 	RET
 
 	// Initialise m, g.
diff --git a/src/runtime/sys_wasm.go b/src/runtime/sys_wasm.go
index e6e7f47..bf57569 100644
--- a/src/runtime/sys_wasm.go
+++ b/src/runtime/sys_wasm.go
@@ -16,10 +16,6 @@
 
 var wasmStack m0Stack
 
-func wasmMove()
-
-func wasmZero()
-
 func wasmDiv()
 
 func wasmTruncS()
diff --git a/src/runtime/sys_wasm.s b/src/runtime/sys_wasm.s
index 164dd16..f706e00 100644
--- a/src/runtime/sys_wasm.s
+++ b/src/runtime/sys_wasm.s
@@ -4,73 +4,6 @@
 
 #include "textflag.h"
 
-TEXT runtime·wasmMove(SB), NOSPLIT, $0-0
-loop:
-	Loop
-		// *dst = *src
-		Get R0
-		Get R1
-		I64Load $0
-		I64Store $0
-
-		// n--
-		Get R2
-		I32Const $1
-		I32Sub
-		Tee R2
-
-		// n == 0
-		I32Eqz
-		If
-			Return
-		End
-
-		// dst += 8
-		Get R0
-		I32Const $8
-		I32Add
-		Set R0
-
-		// src += 8
-		Get R1
-		I32Const $8
-		I32Add
-		Set R1
-
-		Br loop
-	End
-	UNDEF
-
-TEXT runtime·wasmZero(SB), NOSPLIT, $0-0
-loop:
-	Loop
-		// *dst = 0
-		Get R0
-		I64Const $0
-		I64Store $0
-
-		// n--
-		Get R1
-		I32Const $1
-		I32Sub
-		Tee R1
-
-		// n == 0
-		I32Eqz
-		If
-			Return
-		End
-
-		// dst += 8
-		Get R0
-		I32Const $8
-		I32Add
-		Set R0
-
-		Br loop
-	End
-	UNDEF
-
 TEXT runtime·wasmDiv(SB), NOSPLIT, $0-0
 	Get R0
 	I64Const $-0x8000000000000000
diff --git a/src/runtime/sys_windows_amd64.s b/src/runtime/sys_windows_amd64.s
index 1467b4d..777726f 100644
--- a/src/runtime/sys_windows_amd64.s
+++ b/src/runtime/sys_windows_amd64.s
@@ -8,6 +8,9 @@
 #include "time_windows.h"
 #include "cgo/abi_amd64.h"
 
+// Offsets into Thread Environment Block (pointer in GS)
+#define TEB_TlsSlots 0x1480
+
 // void runtime·asmstdcall(void *c);
 TEXT runtime·asmstdcall(SB),NOSPLIT|NOFRAME,$0
 	// asmcgocall will put first argument into CX.
@@ -116,6 +119,7 @@
 	// Make stack space for the rest of the function.
 	ADJSP	$48
 
+	MOVQ	CX, R13	// save exception address
 	MOVQ	AX, R15	// save handler address
 
 	// find g
@@ -153,8 +157,8 @@
 	MOVQ	DI, SP
 
 g0:
-	MOVQ	0(CX), BX // ExceptionRecord*
-	MOVQ	8(CX), CX // Context*
+	MOVQ	0(R13), BX // ExceptionRecord*
+	MOVQ	8(R13), CX // Context*
 	MOVQ	BX, 0(SP)
 	MOVQ	CX, 8(SP)
 	MOVQ	DX, 16(SP)
@@ -162,6 +166,8 @@
 	// AX is set to report result back to Windows
 	MOVL	24(SP), AX
 
+	MOVQ	SP, DI // save g0 SP
+
 	// switch back to original stack and g
 	// no-op if we never left.
 	MOVQ	40(SP), SP
@@ -169,12 +175,54 @@
 	get_tls(BP)
 	MOVQ	DX, g(BP)
 
+	// if return value is CONTINUE_SEARCH, do not set up control
+	// flow guard workaround.
+	CMPQ	AX, $0
+	JEQ	done
+
+	// Check if we need to set up the control flow guard workaround.
+	// On Windows, the stack pointer in the context must lie within
+	// system stack limits when we resume from exception.
+	// Store the resume SP and PC in alternate registers
+	// and return to sigresume on the g0 stack.
+	// sigresume makes no use of the stack at all,
+	// loading SP from R8 and jumping to R9.
+	// Note that smashing R8 and R9 is only safe because we know sigpanic
+	// will not actually return to the original frame, so the registers
+	// are effectively dead. But this does mean we can't use the
+	// same mechanism for async preemption.
+	MOVQ	8(R13), CX
+	MOVQ	$sigresume<>(SB), BX
+	CMPQ	BX, context_rip(CX)
+	JEQ	done			// do not clobber saved SP/PC
+
+	// Save resume SP and PC into R8, R9.
+	MOVQ	context_rsp(CX), BX
+	MOVQ	BX, context_r8(CX)
+	MOVQ	context_rip(CX), BX
+	MOVQ	BX, context_r9(CX)
+
+	// Set up context record to return to sigresume on g0 stack
+	MOVD	DI, BX
+	MOVD	BX, context_rsp(CX)
+	MOVD	$sigresume<>(SB), BX
+	MOVD	BX, context_rip(CX)
+
 done:
 	ADJSP	$-48
 	POP_REGS_HOST_TO_ABI0()
 
 	RET
 
+// Trampoline to resume execution from exception handler.
+// This is part of the control flow guard workaround.
+// It switches stacks and jumps to the continuation address.
+// R8 and R9 are set above at the end of sigtramp<>
+// in the context that starts executing at sigresume<>.
+TEXT sigresume<>(SB),NOSPLIT|NOFRAME,$0
+	MOVQ	R8, SP
+	JMP	R9
+
 TEXT runtime·exceptiontramp(SB),NOSPLIT|NOFRAME,$0
 	MOVQ	$runtime·exceptionhandler(SB), AX
 	JMP	sigtramp<>(SB)
@@ -258,10 +306,10 @@
 	MOVQ	AX, g_stackguard1(DX)
 
 	// Set up tls.
-	LEAQ	m_tls(CX), SI
-	MOVQ	SI, 0x28(GS)
+	LEAQ	m_tls(CX), DI
 	MOVQ	CX, g_m(DX)
-	MOVQ	DX, g(SI)
+	MOVQ	DX, g(DI)
+	CALL	runtime·settls(SB) // clobbers CX
 
 	CALL	runtime·stackcheck(SB)	// clobbers AX,CX
 	CALL	runtime·mstart(SB)
@@ -273,7 +321,8 @@
 
 // set tls base to DI
 TEXT runtime·settls(SB),NOSPLIT,$0
-	MOVQ	DI, 0x28(GS)
+	MOVQ	runtime·tls_g(SB), CX
+	MOVQ	DI, 0(CX)(GS)
 	RET
 
 // Runs on OS stack.
@@ -359,3 +408,32 @@
 	LEAQ	m_tls(AX), DI
 	CALL	runtime·settls(SB)
 	RET
+
+// This is called from rt0_go, which runs on the system stack
+// using the initial stack allocated by the OS.
+TEXT runtime·wintls(SB),NOSPLIT|NOFRAME,$0
+	// Allocate a TLS slot to hold g across calls to external code
+	MOVQ	SP, AX
+	ANDQ	$~15, SP	// alignment as per Windows requirement
+	SUBQ	$48, SP	// room for SP and 4 args as per Windows requirement
+			// plus one extra word to keep stack 16 bytes aligned
+	MOVQ	AX, 32(SP)
+	MOVQ	runtime·_TlsAlloc(SB), AX
+	CALL	AX
+	MOVQ	32(SP), SP
+
+	MOVQ	AX, CX	// TLS index
+
+	// Assert that slot is less than 64 so we can use _TEB->TlsSlots
+	CMPQ	CX, $64
+	JB	ok
+	CALL	runtime·abort(SB)
+ok:
+	// Convert the TLS index at CX into
+	// an offset from TEB_TlsSlots.
+	SHLQ	$3, CX
+
+	// Save offset from TLS into tls_g.
+	ADDQ	$TEB_TlsSlots, CX
+	MOVQ	CX, runtime·tls_g(SB)
+	RET
diff --git a/src/runtime/sys_windows_arm.s b/src/runtime/sys_windows_arm.s
index 5dc576a..db6d8f1 100644
--- a/src/runtime/sys_windows_arm.s
+++ b/src/runtime/sys_windows_arm.s
@@ -123,8 +123,14 @@
 	MOVW	R1, R7			// Save param1
 
 	BL      runtime·load_g(SB)
-	CMP	$0, g			// is there a current g?
-	BL.EQ	runtime·badsignal2(SB)
+	CMP	$0,	g		// is there a current g?
+	BNE	g_ok
+	ADD	$(8+20), R13	// free locals
+	MOVM.IA.W (R13), [R3, R4-R11, R14]	// pop {r3, r4-r11, lr}
+	MOVW	$0, R0		// continue 
+	BEQ	return
+
+g_ok:
 
 	// save g and SP in case of stack switch
 	MOVW	R13, 24(R13)
diff --git a/src/runtime/sys_windows_arm64.s b/src/runtime/sys_windows_arm64.s
index 024625f..4702a4d 100644
--- a/src/runtime/sys_windows_arm64.s
+++ b/src/runtime/sys_windows_arm64.s
@@ -113,7 +113,8 @@
 	MOVD	$runtime·badsignalmsg(SB), R1	// lpBuffer
 	MOVD	$runtime·badsignallen(SB), R2	// lpNumberOfBytesToWrite
 	MOVD	(R2), R2
-	MOVD	R13, R3		// lpNumberOfBytesWritten
+	// point R3 to stack local that will receive number of bytes written
+	ADD	$16, RSP, R3		// lpNumberOfBytesWritten
 	MOVD	$0, R4			// lpOverlapped
 	MOVD	runtime·_WriteFile(SB), R12
 	SUB	$16, RSP	// skip over saved frame pointer below RSP
@@ -146,10 +147,15 @@
 	MOVD	g, R17 			// saved R28 (callee-save from Windows, not really g)
 
 	BL      runtime·load_g(SB)	// smashes R0, R27, R28 (g)
-	CMP	$0, g			// is there a current g?
-	BNE	2(PC)
-	BL	runtime·badsignal2(SB)
+	CMP	$0,	g		// is there a current g?
+	BNE	g_ok
+	MOVD	R7, LR
+	MOVD	R16, R27	// restore R27
+	MOVD	R17, g		// restore R28
+	MOVD	$0, R0		// continue 
+	RET
 
+g_ok:
 	// Do we need to switch to the g0 stack?
 	MOVD	g, R3			// R3 = oldg (for sigtramp_g0)
 	MOVD	g_m(g), R2		// R2 = m
diff --git a/src/runtime/syscall_aix.go b/src/runtime/syscall_aix.go
index f294922..cc9e912 100644
--- a/src/runtime/syscall_aix.go
+++ b/src/runtime/syscall_aix.go
@@ -127,9 +127,9 @@
 
 // like close, but must not split stack, for fork.
 //
-//go:linkname syscall_close syscall.close
+//go:linkname syscall_closeFD syscall.closeFD
 //go:nosplit
-func syscall_close(fd int32) int32 {
+func syscall_closeFD(fd int32) int32 {
 	_, err := syscall1(&libc_close, uintptr(fd))
 	return int32(err)
 }
diff --git a/src/runtime/syscall_unix_test.go b/src/runtime/syscall_unix_test.go
new file mode 100644
index 0000000..2a69c40
--- /dev/null
+++ b/src/runtime/syscall_unix_test.go
@@ -0,0 +1,25 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build unix
+
+package runtime_test
+
+import (
+	"runtime"
+	"syscall"
+	"testing"
+)
+
+func TestSyscallFlagAlignment(t *testing.T) {
+	// TODO(mknyszek): Check other flags.
+	check := func(name string, got, want int) {
+		if got != want {
+			t.Errorf("flag %s does not line up: got %d, want %d", name, got, want)
+		}
+	}
+	check("O_WRONLY", runtime.O_WRONLY, syscall.O_WRONLY)
+	check("O_CREAT", runtime.O_CREAT, syscall.O_CREAT)
+	check("O_TRUNC", runtime.O_TRUNC, syscall.O_TRUNC)
+}
diff --git a/src/runtime/syscall_windows_test.go b/src/runtime/syscall_windows_test.go
index 37f8f40..abc2838 100644
--- a/src/runtime/syscall_windows_test.go
+++ b/src/runtime/syscall_windows_test.go
@@ -5,7 +5,6 @@
 package runtime_test
 
 import (
-	"bytes"
 	"fmt"
 	"internal/abi"
 	"internal/syscall/windows/sysdll"
@@ -629,7 +628,7 @@
 }
 
 func TestRaiseException(t *testing.T) {
-	if testenv.Builder() == "windows-amd64-2012" {
+	if strings.HasPrefix(testenv.Builder(), "windows-amd64-2012") {
 		testenv.SkipFlaky(t, 49681)
 	}
 	o := runTestProg(t, "testprog", "RaiseException")
@@ -1044,7 +1043,7 @@
 
 	cmd := exec.Command(os.Args[0], "-test.run=TestNumCPU")
 	cmd.Env = append(os.Environ(), "GO_WANT_HELPER_PROCESS=1")
-	var buf bytes.Buffer
+	var buf strings.Builder
 	cmd.Stdout = &buf
 	cmd.Stderr = &buf
 	cmd.SysProcAttr = &syscall.SysProcAttr{CreationFlags: _CREATE_SUSPENDED}
@@ -1054,7 +1053,7 @@
 	}
 	defer func() {
 		err = cmd.Wait()
-		childOutput := string(buf.Bytes())
+		childOutput := buf.String()
 		if err != nil {
 			t.Fatalf("child failed: %v: %v", err, childOutput)
 		}
@@ -1216,7 +1215,7 @@
 
 // wantLoadLibraryEx reports whether we expect LoadLibraryEx to work for tests.
 func wantLoadLibraryEx() bool {
-	return testenv.Builder() == "windows-amd64-gce" || testenv.Builder() == "windows-386-gce"
+	return testenv.Builder() != "" && (runtime.GOARCH == "amd64" || runtime.GOARCH == "386")
 }
 
 func TestLoadLibraryEx(t *testing.T) {
diff --git a/src/runtime/testdata/testexithooks/testexithooks.go b/src/runtime/testdata/testexithooks/testexithooks.go
new file mode 100644
index 0000000..ceb3326
--- /dev/null
+++ b/src/runtime/testdata/testexithooks/testexithooks.go
@@ -0,0 +1,85 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"flag"
+	"os"
+	_ "unsafe"
+)
+
+var modeflag = flag.String("mode", "", "mode to run in")
+
+func main() {
+	flag.Parse()
+	switch *modeflag {
+	case "simple":
+		testSimple()
+	case "goodexit":
+		testGoodExit()
+	case "badexit":
+		testBadExit()
+	case "panics":
+		testPanics()
+	case "callsexit":
+		testHookCallsExit()
+	default:
+		panic("unknown mode")
+	}
+}
+
+//go:linkname runtime_addExitHook runtime.addExitHook
+func runtime_addExitHook(f func(), runOnNonZeroExit bool)
+
+func testSimple() {
+	f1 := func() { println("foo") }
+	f2 := func() { println("bar") }
+	runtime_addExitHook(f1, false)
+	runtime_addExitHook(f2, false)
+	// no explicit call to os.Exit
+}
+
+func testGoodExit() {
+	f1 := func() { println("apple") }
+	f2 := func() { println("orange") }
+	runtime_addExitHook(f1, false)
+	runtime_addExitHook(f2, false)
+	// explicit call to os.Exit
+	os.Exit(0)
+}
+
+func testBadExit() {
+	f1 := func() { println("blog") }
+	f2 := func() { println("blix") }
+	f3 := func() { println("blek") }
+	f4 := func() { println("blub") }
+	f5 := func() { println("blat") }
+	runtime_addExitHook(f1, false)
+	runtime_addExitHook(f2, true)
+	runtime_addExitHook(f3, false)
+	runtime_addExitHook(f4, true)
+	runtime_addExitHook(f5, false)
+	os.Exit(1)
+}
+
+func testPanics() {
+	f1 := func() { println("ok") }
+	f2 := func() { panic("BADBADBAD") }
+	f3 := func() { println("good") }
+	runtime_addExitHook(f1, true)
+	runtime_addExitHook(f2, true)
+	runtime_addExitHook(f3, true)
+	os.Exit(0)
+}
+
+func testHookCallsExit() {
+	f1 := func() { println("ok") }
+	f2 := func() { os.Exit(1) }
+	f3 := func() { println("good") }
+	runtime_addExitHook(f1, true)
+	runtime_addExitHook(f2, true)
+	runtime_addExitHook(f3, true)
+	os.Exit(1)
+}
diff --git a/src/runtime/testdata/testprog/checkptr.go b/src/runtime/testdata/testprog/checkptr.go
index b27e5f7..60e71e6 100644
--- a/src/runtime/testdata/testprog/checkptr.go
+++ b/src/runtime/testdata/testprog/checkptr.go
@@ -20,6 +20,8 @@
 	register("CheckPtrSmall", CheckPtrSmall)
 	register("CheckPtrSliceOK", CheckPtrSliceOK)
 	register("CheckPtrSliceFail", CheckPtrSliceFail)
+	register("CheckPtrStringOK", CheckPtrStringOK)
+	register("CheckPtrStringFail", CheckPtrStringFail)
 	register("CheckPtrAlignmentNested", CheckPtrAlignmentNested)
 }
 
@@ -98,6 +100,17 @@
 	sink2 = unsafe.Slice(p, 100)
 }
 
+func CheckPtrStringOK() {
+	p := new([4]byte)
+	sink2 = unsafe.String(&p[1], 3)
+}
+
+func CheckPtrStringFail() {
+	p := new(byte)
+	sink2 = p
+	sink2 = unsafe.String(p, 100)
+}
+
 func CheckPtrAlignmentNested() {
 	s := make([]int8, 100)
 	p := unsafe.Pointer(&s[0])
diff --git a/src/runtime/testdata/testprog/gc.go b/src/runtime/testdata/testprog/gc.go
index 0f44575..5dc85fb 100644
--- a/src/runtime/testdata/testprog/gc.go
+++ b/src/runtime/testdata/testprog/gc.go
@@ -396,7 +396,7 @@
 		// should do considerably better than this bound.
 		bound := int64(myLimit + 16<<20)
 		start := time.Now()
-		for time.Now().Sub(start) < 200*time.Millisecond {
+		for time.Since(start) < 200*time.Millisecond {
 			metrics.Read(m[:])
 			retained := int64(m[0].Value.Uint64() - m[1].Value.Uint64())
 			if retained > bound {
diff --git a/src/runtime/testdata/testprog/numcpu_freebsd.go b/src/runtime/testdata/testprog/numcpu_freebsd.go
index 7209f67..310c212 100644
--- a/src/runtime/testdata/testprog/numcpu_freebsd.go
+++ b/src/runtime/testdata/testprog/numcpu_freebsd.go
@@ -48,7 +48,7 @@
 		fmt.Printf("fail to launch '%s', error: %s, output: %s\n", strings.Join(cmd.Args, " "), err, output)
 		return
 	}
-	if bytes.Equal(output, []byte("1\n")) == false {
+	if !bytes.Equal(output, []byte("1\n")) {
 		// SMP mode deactivated in kernel.
 		fmt.Println("OK")
 		return
diff --git a/src/runtime/testdata/testprog/traceback_ancestors.go b/src/runtime/testdata/testprog/traceback_ancestors.go
index 1d0d00b..8fc1aa7 100644
--- a/src/runtime/testdata/testprog/traceback_ancestors.go
+++ b/src/runtime/testdata/testprog/traceback_ancestors.go
@@ -87,9 +87,10 @@
 	buf := make([]byte, 128)
 	runtime.Stack(buf, false)
 	prefix := []byte("goroutine ")
-	if !bytes.HasPrefix(buf, prefix) {
+	var found bool
+	if buf, found = bytes.CutPrefix(buf, prefix); !found {
 		panic(fmt.Sprintf("expected %q at beginning of traceback:\n%s", prefix, buf))
 	}
-	id, _, _ := bytes.Cut(bytes.TrimPrefix(buf, prefix), []byte(" "))
+	id, _, _ := bytes.Cut(buf, []byte(" "))
 	return string(id)
 }
diff --git a/src/runtime/testdata/testprog/unsafe.go b/src/runtime/testdata/testprog/unsafe.go
new file mode 100644
index 0000000..021b08f
--- /dev/null
+++ b/src/runtime/testdata/testprog/unsafe.go
@@ -0,0 +1,12 @@
+package main
+
+import "unsafe"
+
+func init() {
+	register("panicOnNilAndEleSizeIsZero", panicOnNilAndEleSizeIsZero)
+}
+
+func panicOnNilAndEleSizeIsZero() {
+	var p *struct{}
+	_ = unsafe.Slice(p, 5)
+}
diff --git a/src/runtime/testdata/testprogcgo/issue29707.go b/src/runtime/testdata/testprogcgo/issue29707.go
new file mode 100644
index 0000000..7d9299f
--- /dev/null
+++ b/src/runtime/testdata/testprogcgo/issue29707.go
@@ -0,0 +1,60 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !plan9 && !windows
+// +build !plan9,!windows
+
+// This is for issue #29707
+
+package main
+
+/*
+#include <pthread.h>
+
+extern void* callbackTraceParser(void*);
+typedef void* (*cbTraceParser)(void*);
+
+static void testCallbackTraceParser(cbTraceParser cb) {
+	pthread_t thread_id;
+	pthread_create(&thread_id, NULL, cb, NULL);
+	pthread_join(thread_id, NULL);
+}
+*/
+import "C"
+
+import (
+	"bytes"
+	"fmt"
+	traceparser "internal/trace"
+	"runtime/trace"
+	"time"
+	"unsafe"
+)
+
+func init() {
+	register("CgoTraceParser", CgoTraceParser)
+}
+
+//export callbackTraceParser
+func callbackTraceParser(unsafe.Pointer) unsafe.Pointer {
+	time.Sleep(time.Millisecond)
+	return nil
+}
+
+func CgoTraceParser() {
+	buf := new(bytes.Buffer)
+
+	trace.Start(buf)
+	C.testCallbackTraceParser(C.cbTraceParser(C.callbackTraceParser))
+	trace.Stop()
+
+	_, err := traceparser.Parse(buf, "")
+	if err == traceparser.ErrTimeOrder {
+		fmt.Println("ErrTimeOrder")
+	} else if err != nil {
+		fmt.Println("Parse error: ", err)
+	} else {
+		fmt.Println("OK")
+	}
+}
diff --git a/src/runtime/testdata/testprogcgo/segv.go b/src/runtime/testdata/testprogcgo/segv.go
index 0632475..bf5aa31 100644
--- a/src/runtime/testdata/testprogcgo/segv.go
+++ b/src/runtime/testdata/testprogcgo/segv.go
@@ -2,18 +2,16 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build !plan9 && !windows
-// +build !plan9,!windows
+//go:build unix
+// +build unix
 
 package main
 
+// #include <unistd.h>
 // static void nop() {}
 import "C"
 
-import (
-	"syscall"
-	"time"
-)
+import "syscall"
 
 func init() {
 	register("Segv", Segv)
@@ -35,8 +33,8 @@
 
 	syscall.Kill(syscall.Getpid(), syscall.SIGSEGV)
 
-	// Give the OS time to deliver the signal.
-	time.Sleep(time.Second)
+	// Wait for the OS to deliver the signal.
+	C.pause()
 }
 
 func SegvInCgo() {
@@ -52,6 +50,6 @@
 
 	syscall.Kill(syscall.Getpid(), syscall.SIGSEGV)
 
-	// Give the OS time to deliver the signal.
-	time.Sleep(time.Second)
+	// Wait for the OS to deliver the signal.
+	C.pause()
 }
diff --git a/src/runtime/testdata/testprogcgo/segv_linux.go b/src/runtime/testdata/testprogcgo/segv_linux.go
new file mode 100644
index 0000000..fe93778
--- /dev/null
+++ b/src/runtime/testdata/testprogcgo/segv_linux.go
@@ -0,0 +1,51 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+// #include <unistd.h>
+// static void nop() {}
+import "C"
+
+import "syscall"
+
+func init() {
+	register("TgkillSegv", TgkillSegv)
+	register("TgkillSegvInCgo", TgkillSegvInCgo)
+}
+
+func TgkillSegv() {
+	c := make(chan bool)
+	go func() {
+		close(c)
+		for i := 0; ; i++ {
+			// Sum defined in segv.go.
+			Sum += i
+		}
+	}()
+
+	<-c
+
+	syscall.Tgkill(syscall.Getpid(), syscall.Gettid(), syscall.SIGSEGV)
+
+	// Wait for the OS to deliver the signal.
+	C.pause()
+}
+
+func TgkillSegvInCgo() {
+	c := make(chan bool)
+	go func() {
+		close(c)
+		for {
+			C.nop()
+		}
+	}()
+
+	<-c
+
+	syscall.Tgkill(syscall.Getpid(), syscall.Gettid(), syscall.SIGSEGV)
+
+	// Wait for the OS to deliver the signal.
+	C.pause()
+}
diff --git a/src/runtime/testdata/testprogcgo/sigfwd.go b/src/runtime/testdata/testprogcgo/sigfwd.go
new file mode 100644
index 0000000..f6a0c03
--- /dev/null
+++ b/src/runtime/testdata/testprogcgo/sigfwd.go
@@ -0,0 +1,87 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build unix
+
+package main
+
+import (
+	"fmt"
+	"os"
+)
+
+/*
+#include <signal.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+sig_atomic_t expectCSigsegv;
+int *sigfwdP;
+
+static void sigsegv() {
+	expectCSigsegv = 1;
+	*sigfwdP = 1;
+	fprintf(stderr, "ERROR: C SIGSEGV not thrown on caught?.\n");
+	exit(2);
+}
+
+static void segvhandler(int signum) {
+	if (signum == SIGSEGV) {
+		if (expectCSigsegv == 0) {
+			fprintf(stderr, "SIGSEGV caught in C unexpectedly\n");
+			exit(1);
+		}
+		fprintf(stdout, "OK\n");
+		exit(0);  // success
+	}
+}
+
+static void __attribute__ ((constructor)) sigsetup(void) {
+	if (getenv("GO_TEST_CGOSIGFWD") == NULL) {
+		return;
+	}
+
+	struct sigaction act;
+
+	memset(&act, 0, sizeof act);
+	act.sa_handler = segvhandler;
+	sigaction(SIGSEGV, &act, NULL);
+}
+*/
+import "C"
+
+func init() {
+	register("CgoSigfwd", CgoSigfwd)
+}
+
+var nilPtr *byte
+
+func f() (ret bool) {
+	defer func() {
+		if recover() == nil {
+			fmt.Fprintf(os.Stderr, "ERROR: couldn't raise SIGSEGV in Go\n")
+			C.exit(2)
+		}
+		ret = true
+	}()
+	*nilPtr = 1
+	return false
+}
+
+func CgoSigfwd() {
+	if os.Getenv("GO_TEST_CGOSIGFWD") == "" {
+		fmt.Fprintf(os.Stderr, "test must be run with GO_TEST_CGOSIGFWD set\n")
+		os.Exit(1)
+	}
+
+	// Test that the signal originating in Go is handled (and recovered) by Go.
+	if !f() {
+		fmt.Fprintf(os.Stderr, "couldn't recover from SIGSEGV in Go.\n")
+		C.exit(2)
+	}
+
+	// Test that the signal originating in C is handled by C.
+	C.sigsegv()
+}
diff --git a/src/runtime/testdata/testwinlibthrow/main.go b/src/runtime/testdata/testwinlibthrow/main.go
new file mode 100644
index 0000000..ce0c92f
--- /dev/null
+++ b/src/runtime/testdata/testwinlibthrow/main.go
@@ -0,0 +1,19 @@
+package main

+

+import (

+	"os"

+	"syscall"

+)

+

+func main() {

+	dll := syscall.MustLoadDLL("veh.dll")

+	RaiseNoExcept := dll.MustFindProc("RaiseNoExcept")

+	ThreadRaiseNoExcept := dll.MustFindProc("ThreadRaiseNoExcept")

+

+	thread := len(os.Args) > 1 && os.Args[1] == "thread"

+	if !thread {

+		RaiseNoExcept.Call()

+	} else {

+		ThreadRaiseNoExcept.Call()

+	}

+}

diff --git a/src/runtime/testdata/testwinlibthrow/veh.c b/src/runtime/testdata/testwinlibthrow/veh.c
new file mode 100644
index 0000000..08c1f9e
--- /dev/null
+++ b/src/runtime/testdata/testwinlibthrow/veh.c
@@ -0,0 +1,26 @@
+//go:build ignore

+

+#include <windows.h>

+

+__declspec(dllexport)

+void RaiseNoExcept(void)

+{

+    RaiseException(42, 0, 0, 0);

+}

+

+static DWORD WINAPI ThreadRaiser(void* Context)

+{

+    RaiseNoExcept();

+    return 0;

+}

+

+__declspec(dllexport)

+void ThreadRaiseNoExcept(void)

+{

+    HANDLE thread = CreateThread(0, 0, ThreadRaiser,  0, 0, 0);

+    if (0 != thread)

+    {

+        WaitForSingleObject(thread, INFINITE);

+        CloseHandle(thread);

+    }

+}

diff --git a/src/runtime/time.go b/src/runtime/time.go
index 80b0bfb..6cd70b7 100644
--- a/src/runtime/time.go
+++ b/src/runtime/time.go
@@ -36,7 +36,7 @@
 	nextwhen int64
 
 	// The status field holds one of the values below.
-	status uint32
+	status atomic.Uint32
 }
 
 // Code outside this file has to be careful in using a timer value.
@@ -249,6 +249,7 @@
 	goready(arg.(*g), 0)
 }
 
+// Note: this changes some unsynchronized operations to synchronized operations
 // addtimer adds a timer to the current P.
 // This should only be called with a newly created timer.
 // That avoids the risk of changing the when field of a timer in some P's heap,
@@ -263,10 +264,10 @@
 	if t.period < 0 {
 		throw("timer period must be non-negative")
 	}
-	if t.status != timerNoStatus {
+	if t.status.Load() != timerNoStatus {
 		throw("addtimer called with initialized timer")
 	}
-	t.status = timerWaiting
+	t.status.Store(timerWaiting)
 
 	when := t.when
 
@@ -289,7 +290,7 @@
 func doaddtimer(pp *p, t *timer) {
 	// Timers rely on the network poller, so make sure the poller
 	// has started.
-	if netpollInited == 0 {
+	if netpollInited.Load() == 0 {
 		netpollGenericInit()
 	}
 
@@ -301,9 +302,9 @@
 	pp.timers = append(pp.timers, t)
 	siftupTimer(pp.timers, i)
 	if t == pp.timers[0] {
-		atomic.Store64(&pp.timer0When, uint64(t.when))
+		pp.timer0When.Store(t.when)
 	}
-	atomic.Xadd(&pp.numTimers, 1)
+	pp.numTimers.Add(1)
 }
 
 // deltimer deletes the timer t. It may be on some other P, so we can't
@@ -312,21 +313,21 @@
 // Reports whether the timer was removed before it was run.
 func deltimer(t *timer) bool {
 	for {
-		switch s := atomic.Load(&t.status); s {
+		switch s := t.status.Load(); s {
 		case timerWaiting, timerModifiedLater:
 			// Prevent preemption while the timer is in timerModifying.
 			// This could lead to a self-deadlock. See #38070.
 			mp := acquirem()
-			if atomic.Cas(&t.status, s, timerModifying) {
+			if t.status.CompareAndSwap(s, timerModifying) {
 				// Must fetch t.pp before changing status,
 				// as cleantimers in another goroutine
 				// can clear t.pp of a timerDeleted timer.
 				tpp := t.pp.ptr()
-				if !atomic.Cas(&t.status, timerModifying, timerDeleted) {
+				if !t.status.CompareAndSwap(timerModifying, timerDeleted) {
 					badTimer()
 				}
 				releasem(mp)
-				atomic.Xadd(&tpp.deletedTimers, 1)
+				tpp.deletedTimers.Add(1)
 				// Timer was not yet run.
 				return true
 			} else {
@@ -336,15 +337,15 @@
 			// Prevent preemption while the timer is in timerModifying.
 			// This could lead to a self-deadlock. See #38070.
 			mp := acquirem()
-			if atomic.Cas(&t.status, s, timerModifying) {
+			if t.status.CompareAndSwap(s, timerModifying) {
 				// Must fetch t.pp before setting status
 				// to timerDeleted.
 				tpp := t.pp.ptr()
-				if !atomic.Cas(&t.status, timerModifying, timerDeleted) {
+				if !t.status.CompareAndSwap(timerModifying, timerDeleted) {
 					badTimer()
 				}
 				releasem(mp)
-				atomic.Xadd(&tpp.deletedTimers, 1)
+				tpp.deletedTimers.Add(1)
 				// Timer was not yet run.
 				return true
 			} else {
@@ -397,10 +398,10 @@
 	if i == 0 {
 		updateTimer0When(pp)
 	}
-	n := atomic.Xadd(&pp.numTimers, -1)
+	n := pp.numTimers.Add(-1)
 	if n == 0 {
 		// If there are no timers, then clearly none are modified.
-		atomic.Store64(&pp.timerModifiedEarliest, 0)
+		pp.timerModifiedEarliest.Store(0)
 	}
 	return smallestChanged
 }
@@ -425,10 +426,10 @@
 		siftdownTimer(pp.timers, 0)
 	}
 	updateTimer0When(pp)
-	n := atomic.Xadd(&pp.numTimers, -1)
+	n := pp.numTimers.Add(-1)
 	if n == 0 {
 		// If there are no timers, then clearly none are modified.
-		atomic.Store64(&pp.timerModifiedEarliest, 0)
+		pp.timerModifiedEarliest.Store(0)
 	}
 }
 
@@ -449,12 +450,12 @@
 	var mp *m
 loop:
 	for {
-		switch status = atomic.Load(&t.status); status {
+		switch status = t.status.Load(); status {
 		case timerWaiting, timerModifiedEarlier, timerModifiedLater:
 			// Prevent preemption while the timer is in timerModifying.
 			// This could lead to a self-deadlock. See #38070.
 			mp = acquirem()
-			if atomic.Cas(&t.status, status, timerModifying) {
+			if t.status.CompareAndSwap(status, timerModifying) {
 				pending = true // timer not yet run
 				break loop
 			}
@@ -466,7 +467,7 @@
 
 			// Timer was already run and t is no longer in a heap.
 			// Act like addtimer.
-			if atomic.Cas(&t.status, status, timerModifying) {
+			if t.status.CompareAndSwap(status, timerModifying) {
 				wasRemoved = true
 				pending = false // timer already run or stopped
 				break loop
@@ -476,8 +477,8 @@
 			// Prevent preemption while the timer is in timerModifying.
 			// This could lead to a self-deadlock. See #38070.
 			mp = acquirem()
-			if atomic.Cas(&t.status, status, timerModifying) {
-				atomic.Xadd(&t.pp.ptr().deletedTimers, -1)
+			if t.status.CompareAndSwap(status, timerModifying) {
+				t.pp.ptr().deletedTimers.Add(-1)
 				pending = false // timer already stopped
 				break loop
 			}
@@ -506,7 +507,7 @@
 		lock(&pp.timersLock)
 		doaddtimer(pp, t)
 		unlock(&pp.timersLock)
-		if !atomic.Cas(&t.status, timerModifying, timerWaiting) {
+		if !t.status.CompareAndSwap(timerModifying, timerWaiting) {
 			badTimer()
 		}
 		releasem(mp)
@@ -531,7 +532,7 @@
 		}
 
 		// Set the new status of the timer.
-		if !atomic.Cas(&t.status, timerModifying, newStatus) {
+		if !t.status.CompareAndSwap(timerModifying, newStatus) {
 			badTimer()
 		}
 		releasem(mp)
@@ -577,18 +578,18 @@
 		if t.pp.ptr() != pp {
 			throw("cleantimers: bad p")
 		}
-		switch s := atomic.Load(&t.status); s {
+		switch s := t.status.Load(); s {
 		case timerDeleted:
-			if !atomic.Cas(&t.status, s, timerRemoving) {
+			if !t.status.CompareAndSwap(s, timerRemoving) {
 				continue
 			}
 			dodeltimer0(pp)
-			if !atomic.Cas(&t.status, timerRemoving, timerRemoved) {
+			if !t.status.CompareAndSwap(timerRemoving, timerRemoved) {
 				badTimer()
 			}
-			atomic.Xadd(&pp.deletedTimers, -1)
+			pp.deletedTimers.Add(-1)
 		case timerModifiedEarlier, timerModifiedLater:
-			if !atomic.Cas(&t.status, s, timerMoving) {
+			if !t.status.CompareAndSwap(s, timerMoving) {
 				continue
 			}
 			// Now we can change the when field.
@@ -596,7 +597,7 @@
 			// Move t to the right position.
 			dodeltimer0(pp)
 			doaddtimer(pp, t)
-			if !atomic.Cas(&t.status, timerMoving, timerWaiting) {
+			if !t.status.CompareAndSwap(timerMoving, timerWaiting) {
 				badTimer()
 			}
 		default:
@@ -614,30 +615,30 @@
 	for _, t := range timers {
 	loop:
 		for {
-			switch s := atomic.Load(&t.status); s {
+			switch s := t.status.Load(); s {
 			case timerWaiting:
-				if !atomic.Cas(&t.status, s, timerMoving) {
+				if !t.status.CompareAndSwap(s, timerMoving) {
 					continue
 				}
 				t.pp = 0
 				doaddtimer(pp, t)
-				if !atomic.Cas(&t.status, timerMoving, timerWaiting) {
+				if !t.status.CompareAndSwap(timerMoving, timerWaiting) {
 					badTimer()
 				}
 				break loop
 			case timerModifiedEarlier, timerModifiedLater:
-				if !atomic.Cas(&t.status, s, timerMoving) {
+				if !t.status.CompareAndSwap(s, timerMoving) {
 					continue
 				}
 				t.when = t.nextwhen
 				t.pp = 0
 				doaddtimer(pp, t)
-				if !atomic.Cas(&t.status, timerMoving, timerWaiting) {
+				if !t.status.CompareAndSwap(timerMoving, timerWaiting) {
 					badTimer()
 				}
 				break loop
 			case timerDeleted:
-				if !atomic.Cas(&t.status, s, timerRemoved) {
+				if !t.status.CompareAndSwap(s, timerRemoved) {
 					continue
 				}
 				t.pp = 0
@@ -671,8 +672,8 @@
 	// a lot of timers back and forth if the timers rarely expire.
 	// We'll postpone looking through all the adjusted timers until
 	// one would actually expire.
-	first := atomic.Load64(&pp.timerModifiedEarliest)
-	if first == 0 || int64(first) > now {
+	first := pp.timerModifiedEarliest.Load()
+	if first == 0 || first > now {
 		if verifyTimers {
 			verifyTimerHeap(pp)
 		}
@@ -680,7 +681,7 @@
 	}
 
 	// We are going to clear all timerModifiedEarlier timers.
-	atomic.Store64(&pp.timerModifiedEarliest, 0)
+	pp.timerModifiedEarliest.Store(0)
 
 	var moved []*timer
 	for i := 0; i < len(pp.timers); i++ {
@@ -688,20 +689,20 @@
 		if t.pp.ptr() != pp {
 			throw("adjusttimers: bad p")
 		}
-		switch s := atomic.Load(&t.status); s {
+		switch s := t.status.Load(); s {
 		case timerDeleted:
-			if atomic.Cas(&t.status, s, timerRemoving) {
+			if t.status.CompareAndSwap(s, timerRemoving) {
 				changed := dodeltimer(pp, i)
-				if !atomic.Cas(&t.status, timerRemoving, timerRemoved) {
+				if !t.status.CompareAndSwap(timerRemoving, timerRemoved) {
 					badTimer()
 				}
-				atomic.Xadd(&pp.deletedTimers, -1)
+				pp.deletedTimers.Add(-1)
 				// Go back to the earliest changed heap entry.
 				// "- 1" because the loop will add 1.
 				i = changed - 1
 			}
 		case timerModifiedEarlier, timerModifiedLater:
-			if atomic.Cas(&t.status, s, timerMoving) {
+			if t.status.CompareAndSwap(s, timerMoving) {
 				// Now we can change the when field.
 				t.when = t.nextwhen
 				// Take t off the heap, and hold onto it.
@@ -741,7 +742,7 @@
 func addAdjustedTimers(pp *p, moved []*timer) {
 	for _, t := range moved {
 		doaddtimer(pp, t)
-		if !atomic.Cas(&t.status, timerMoving, timerWaiting) {
+		if !t.status.CompareAndSwap(timerMoving, timerWaiting) {
 			badTimer()
 		}
 	}
@@ -754,8 +755,8 @@
 //
 //go:nowritebarrierrec
 func nobarrierWakeTime(pp *p) int64 {
-	next := int64(atomic.Load64(&pp.timer0When))
-	nextAdj := int64(atomic.Load64(&pp.timerModifiedEarliest))
+	next := pp.timer0When.Load()
+	nextAdj := pp.timerModifiedEarliest.Load()
 	if next == 0 || (nextAdj != 0 && nextAdj < next) {
 		next = nextAdj
 	}
@@ -776,14 +777,14 @@
 		if t.pp.ptr() != pp {
 			throw("runtimer: bad p")
 		}
-		switch s := atomic.Load(&t.status); s {
+		switch s := t.status.Load(); s {
 		case timerWaiting:
 			if t.when > now {
 				// Not ready to run.
 				return t.when
 			}
 
-			if !atomic.Cas(&t.status, s, timerRunning) {
+			if !t.status.CompareAndSwap(s, timerRunning) {
 				continue
 			}
 			// Note that runOneTimer may temporarily unlock
@@ -792,26 +793,26 @@
 			return 0
 
 		case timerDeleted:
-			if !atomic.Cas(&t.status, s, timerRemoving) {
+			if !t.status.CompareAndSwap(s, timerRemoving) {
 				continue
 			}
 			dodeltimer0(pp)
-			if !atomic.Cas(&t.status, timerRemoving, timerRemoved) {
+			if !t.status.CompareAndSwap(timerRemoving, timerRemoved) {
 				badTimer()
 			}
-			atomic.Xadd(&pp.deletedTimers, -1)
+			pp.deletedTimers.Add(-1)
 			if len(pp.timers) == 0 {
 				return -1
 			}
 
 		case timerModifiedEarlier, timerModifiedLater:
-			if !atomic.Cas(&t.status, s, timerMoving) {
+			if !t.status.CompareAndSwap(s, timerMoving) {
 				continue
 			}
 			t.when = t.nextwhen
 			dodeltimer0(pp)
 			doaddtimer(pp, t)
-			if !atomic.Cas(&t.status, timerMoving, timerWaiting) {
+			if !t.status.CompareAndSwap(timerMoving, timerWaiting) {
 				badTimer()
 			}
 
@@ -858,14 +859,14 @@
 			t.when = maxWhen
 		}
 		siftdownTimer(pp.timers, 0)
-		if !atomic.Cas(&t.status, timerRunning, timerWaiting) {
+		if !t.status.CompareAndSwap(timerRunning, timerWaiting) {
 			badTimer()
 		}
 		updateTimer0When(pp)
 	} else {
 		// Remove from heap.
 		dodeltimer0(pp)
-		if !atomic.Cas(&t.status, timerRunning, timerNoStatus) {
+		if !t.status.CompareAndSwap(timerRunning, timerNoStatus) {
 			badTimer()
 		}
 	}
@@ -903,7 +904,7 @@
 func clearDeletedTimers(pp *p) {
 	// We are going to clear all timerModifiedEarlier timers.
 	// Do this now in case new ones show up while we are looping.
-	atomic.Store64(&pp.timerModifiedEarliest, 0)
+	pp.timerModifiedEarliest.Store(0)
 
 	cdel := int32(0)
 	to := 0
@@ -912,7 +913,7 @@
 nextTimer:
 	for _, t := range timers {
 		for {
-			switch s := atomic.Load(&t.status); s {
+			switch s := t.status.Load(); s {
 			case timerWaiting:
 				if changedHeap {
 					timers[to] = t
@@ -921,22 +922,22 @@
 				to++
 				continue nextTimer
 			case timerModifiedEarlier, timerModifiedLater:
-				if atomic.Cas(&t.status, s, timerMoving) {
+				if t.status.CompareAndSwap(s, timerMoving) {
 					t.when = t.nextwhen
 					timers[to] = t
 					siftupTimer(timers, to)
 					to++
 					changedHeap = true
-					if !atomic.Cas(&t.status, timerMoving, timerWaiting) {
+					if !t.status.CompareAndSwap(timerMoving, timerWaiting) {
 						badTimer()
 					}
 					continue nextTimer
 				}
 			case timerDeleted:
-				if atomic.Cas(&t.status, s, timerRemoving) {
+				if t.status.CompareAndSwap(s, timerRemoving) {
 					t.pp = 0
 					cdel++
-					if !atomic.Cas(&t.status, timerRemoving, timerRemoved) {
+					if !t.status.CompareAndSwap(timerRemoving, timerRemoved) {
 						badTimer()
 					}
 					changedHeap = true
@@ -964,8 +965,8 @@
 		timers[i] = nil
 	}
 
-	atomic.Xadd(&pp.deletedTimers, -cdel)
-	atomic.Xadd(&pp.numTimers, -cdel)
+	pp.deletedTimers.Add(-cdel)
+	pp.numTimers.Add(-cdel)
 
 	timers = timers[:to]
 	pp.timers = timers
@@ -993,7 +994,7 @@
 			throw("bad timer heap")
 		}
 	}
-	if numTimers := int(atomic.Load(&pp.numTimers)); len(pp.timers) != numTimers {
+	if numTimers := int(pp.numTimers.Load()); len(pp.timers) != numTimers {
 		println("timer heap len", len(pp.timers), "!= numTimers", numTimers)
 		throw("bad timer heap len")
 	}
@@ -1003,9 +1004,9 @@
 // The caller must have locked the timers for pp.
 func updateTimer0When(pp *p) {
 	if len(pp.timers) == 0 {
-		atomic.Store64(&pp.timer0When, 0)
+		pp.timer0When.Store(0)
 	} else {
-		atomic.Store64(&pp.timer0When, uint64(pp.timers[0].when))
+		pp.timer0When.Store(pp.timers[0].when)
 	}
 }
 
@@ -1014,11 +1015,12 @@
 // The timers for pp will not be locked.
 func updateTimerModifiedEarliest(pp *p, nextwhen int64) {
 	for {
-		old := atomic.Load64(&pp.timerModifiedEarliest)
+		old := pp.timerModifiedEarliest.Load()
 		if old != 0 && int64(old) < nextwhen {
 			return
 		}
-		if atomic.Cas64(&pp.timerModifiedEarliest, old, uint64(nextwhen)) {
+
+		if pp.timerModifiedEarliest.CompareAndSwap(old, nextwhen) {
 			return
 		}
 	}
@@ -1039,12 +1041,12 @@
 			continue
 		}
 
-		w := int64(atomic.Load64(&pp.timer0When))
+		w := pp.timer0When.Load()
 		if w != 0 && w < next {
 			next = w
 		}
 
-		w = int64(atomic.Load64(&pp.timerModifiedEarliest))
+		w = pp.timerModifiedEarliest.Load()
 		if w != 0 && w < next {
 			next = w
 		}
diff --git a/src/runtime/trace.go b/src/runtime/trace.go
index 10436d8..e7dfab1 100644
--- a/src/runtime/trace.go
+++ b/src/runtime/trace.go
@@ -109,6 +109,8 @@
 
 // trace is global tracing context.
 var trace struct {
+	// trace.lock must only be acquired on the system stack where
+	// stack splits cannot happen while it is held.
 	lock          mutex       // protects the following members
 	lockOwner     *g          // to avoid deadlocks during recursive lock locks
 	enabled       bool        // when set runtime traces events
@@ -126,7 +128,6 @@
 	empty         traceBufPtr // stack of empty buffers
 	fullHead      traceBufPtr // queue of full buffers
 	fullTail      traceBufPtr
-	reader        guintptr        // goroutine that called ReadTrace, or nil
 	stackTab      traceStackTable // maps stack traces to unique ids
 	// cpuLogRead accepts CPU profile samples from the signal handler where
 	// they're generated. It uses a two-word header to hold the IDs of the P and
@@ -144,6 +145,8 @@
 	// specific P.
 	cpuLogBuf traceBufPtr
 
+	reader atomic.Pointer[g] // goroutine that called ReadTrace, or nil
+
 	signalLock  atomic.Uint32 // protects use of the following member, only usable in signal handlers
 	cpuLogWrite *profBuf      // copy of cpuLogRead for use in signal handlers, set without signalLock
 
@@ -173,9 +176,8 @@
 }
 
 // traceBuf is per-P tracing buffer.
-//
-//go:notinheap
 type traceBuf struct {
+	_ sys.NotInHeap
 	traceBufHeader
 	arr [64<<10 - unsafe.Sizeof(traceBufHeader{})]byte // underlying buffer for traceBufHeader.buf
 }
@@ -186,7 +188,7 @@
 // manipulated in contexts where write barriers are not allowed, so
 // this is necessary.
 //
-// TODO: Since traceBuf is now go:notinheap, this isn't necessary.
+// TODO: Since traceBuf is now embedded runtime/internal/sys.NotInHeap, this isn't necessary.
 type traceBufPtr uintptr
 
 func (tp traceBufPtr) ptr() *traceBuf   { return (*traceBuf)(unsafe.Pointer(tp)) }
@@ -232,14 +234,12 @@
 	// - or GoSysExit appears for a goroutine for which we don't emit EvGoInSyscall below.
 	// To instruct traceEvent that it must not ignore events below, we set startingtrace.
 	// trace.enabled is set afterwards once we have emitted all preliminary events.
-	_g_ := getg()
-	_g_.m.startingtrace = true
+	mp := getg().m
+	mp.startingtrace = true
 
 	// Obtain current stack ID to use in all traceEvGoCreate events below.
-	mp := acquirem()
 	stkBuf := make([]uintptr, traceStackSize)
 	stackID := traceStackID(mp, stkBuf, 2)
-	releasem(mp)
 
 	profBuf := newProfBuf(2, profBufWordCount, profBufTagCount) // after the timestamp, header is [pp.id, gp.goid]
 	trace.cpuLogRead = profBuf
@@ -261,16 +261,27 @@
 			gp.tracelastp = getg().m.p
 			// +PCQuantum because traceFrameForPC expects return PCs and subtracts PCQuantum.
 			id := trace.stackTab.put([]uintptr{startPCforTrace(gp.startpc) + sys.PCQuantum})
-			traceEvent(traceEvGoCreate, -1, uint64(gp.goid), uint64(id), stackID)
+			traceEvent(traceEvGoCreate, -1, gp.goid, uint64(id), stackID)
 		}
 		if status == _Gwaiting {
 			// traceEvGoWaiting is implied to have seq=1.
 			gp.traceseq++
-			traceEvent(traceEvGoWaiting, -1, uint64(gp.goid))
+			traceEvent(traceEvGoWaiting, -1, gp.goid)
 		}
 		if status == _Gsyscall {
 			gp.traceseq++
-			traceEvent(traceEvGoInSyscall, -1, uint64(gp.goid))
+			traceEvent(traceEvGoInSyscall, -1, gp.goid)
+		} else if status == _Gdead && gp.m != nil && gp.m.isextra {
+			// Trigger two trace events for the dead g in the extra m,
+			// since the next event of the g will be traceEvGoSysExit in exitsyscall,
+			// while calling from C thread to Go.
+			gp.traceseq = 0
+			gp.tracelastp = getg().m.p
+			// +PCQuantum because traceFrameForPC expects return PCs and subtracts PCQuantum.
+			id := trace.stackTab.put([]uintptr{startPCforTrace(0) + sys.PCQuantum}) // no start pc
+			traceEvent(traceEvGoCreate, -1, gp.goid, uint64(id), stackID)
+			gp.traceseq++
+			traceEvent(traceEvGoInSyscall, -1, gp.goid)
 		} else {
 			gp.sysblocktraced = false
 		}
@@ -293,7 +304,7 @@
 	trace.strings = make(map[string]uint64)
 
 	trace.seqGC = 0
-	_g_.m.startingtrace = false
+	mp.startingtrace = false
 	trace.enabled = true
 
 	// Register runtime goroutine labels.
@@ -386,31 +397,33 @@
 		raceacquire(unsafe.Pointer(&trace.shutdownSema))
 	}
 
-	// The lock protects us from races with StartTrace/StopTrace because they do stop-the-world.
-	lock(&trace.lock)
-	for _, p := range allp[:cap(allp)] {
-		if p.tracebuf != 0 {
-			throw("trace: non-empty trace buffer in proc")
+	systemstack(func() {
+		// The lock protects us from races with StartTrace/StopTrace because they do stop-the-world.
+		lock(&trace.lock)
+		for _, p := range allp[:cap(allp)] {
+			if p.tracebuf != 0 {
+				throw("trace: non-empty trace buffer in proc")
+			}
 		}
-	}
-	if trace.buf != 0 {
-		throw("trace: non-empty global trace buffer")
-	}
-	if trace.fullHead != 0 || trace.fullTail != 0 {
-		throw("trace: non-empty full trace buffer")
-	}
-	if trace.reading != 0 || trace.reader != 0 {
-		throw("trace: reading after shutdown")
-	}
-	for trace.empty != 0 {
-		buf := trace.empty
-		trace.empty = buf.ptr().link
-		sysFree(unsafe.Pointer(buf), unsafe.Sizeof(*buf.ptr()), &memstats.other_sys)
-	}
-	trace.strings = nil
-	trace.shutdown = false
-	trace.cpuLogRead = nil
-	unlock(&trace.lock)
+		if trace.buf != 0 {
+			throw("trace: non-empty global trace buffer")
+		}
+		if trace.fullHead != 0 || trace.fullTail != 0 {
+			throw("trace: non-empty full trace buffer")
+		}
+		if trace.reading != 0 || trace.reader.Load() != nil {
+			throw("trace: reading after shutdown")
+		}
+		for trace.empty != 0 {
+			buf := trace.empty
+			trace.empty = buf.ptr().link
+			sysFree(unsafe.Pointer(buf), unsafe.Sizeof(*buf.ptr()), &memstats.other_sys)
+		}
+		trace.strings = nil
+		trace.shutdown = false
+		trace.cpuLogRead = nil
+		unlock(&trace.lock)
+	})
 }
 
 // ReadTrace returns the next chunk of binary tracing data, blocking until data
@@ -419,6 +432,55 @@
 // returned data before calling ReadTrace again.
 // ReadTrace must be called from one goroutine at a time.
 func ReadTrace() []byte {
+top:
+	var buf []byte
+	var park bool
+	systemstack(func() {
+		buf, park = readTrace0()
+	})
+	if park {
+		gopark(func(gp *g, _ unsafe.Pointer) bool {
+			if !trace.reader.CompareAndSwapNoWB(nil, gp) {
+				// We're racing with another reader.
+				// Wake up and handle this case.
+				return false
+			}
+
+			if g2 := traceReader(); gp == g2 {
+				// New data arrived between unlocking
+				// and the CAS and we won the wake-up
+				// race, so wake up directly.
+				return false
+			} else if g2 != nil {
+				printlock()
+				println("runtime: got trace reader", g2, g2.goid)
+				throw("unexpected trace reader")
+			}
+
+			return true
+		}, nil, waitReasonTraceReaderBlocked, traceEvGoBlock, 2)
+		goto top
+	}
+
+	return buf
+}
+
+// readTrace0 is ReadTrace's continuation on g0. This must run on the
+// system stack because it acquires trace.lock.
+//
+//go:systemstack
+func readTrace0() (buf []byte, park bool) {
+	if raceenabled {
+		// g0 doesn't have a race context. Borrow the user G's.
+		if getg().racectx != 0 {
+			throw("expected racectx == 0")
+		}
+		getg().racectx = getg().m.curg.racectx
+		// (This defer should get open-coded, which is safe on
+		// the system stack.)
+		defer func() { getg().racectx = 0 }()
+	}
+
 	// This function may need to lock trace.lock recursively
 	// (goparkunlock -> traceGoPark -> traceEvent -> traceFlush).
 	// To allow this we use trace.lockOwner.
@@ -426,16 +488,16 @@
 	// allocation can call heap allocate, which will try to emit a trace
 	// event while holding heap lock.
 	lock(&trace.lock)
-	trace.lockOwner = getg()
+	trace.lockOwner = getg().m.curg
 
-	if trace.reader != 0 {
+	if trace.reader.Load() != nil {
 		// More than one goroutine reads trace. This is bad.
 		// But we rather do not crash the program because of tracing,
 		// because tracing can be enabled at runtime on prod servers.
 		trace.lockOwner = nil
 		unlock(&trace.lock)
 		println("runtime: ReadTrace called from multiple goroutines simultaneously")
-		return nil
+		return nil, false
 	}
 	// Recycle the old buffer.
 	if buf := trace.reading; buf != 0 {
@@ -448,7 +510,7 @@
 		trace.headerWritten = true
 		trace.lockOwner = nil
 		unlock(&trace.lock)
-		return []byte("go 1.19 trace\x00\x00\x00")
+		return []byte("go 1.19 trace\x00\x00\x00"), false
 	}
 	// Optimistically look for CPU profile samples. This may write new stack
 	// records, and may write new tracing buffers.
@@ -457,17 +519,22 @@
 	}
 	// Wait for new data.
 	if trace.fullHead == 0 && !trace.shutdown {
-		trace.reader.set(getg())
-		goparkunlock(&trace.lock, waitReasonTraceReaderBlocked, traceEvGoBlock, 2)
-		lock(&trace.lock)
+		// We don't simply use a note because the scheduler
+		// executes this goroutine directly when it wakes up
+		// (also a note would consume an M).
+		trace.lockOwner = nil
+		unlock(&trace.lock)
+		return nil, true
 	}
+newFull:
+	assertLockHeld(&trace.lock)
 	// Write a buffer.
 	if trace.fullHead != 0 {
 		buf := traceFullDequeue()
 		trace.reading = buf
 		trace.lockOwner = nil
 		unlock(&trace.lock)
-		return buf.ptr().arr[:buf.ptr().pos]
+		return buf.ptr().arr[:buf.ptr().pos], false
 	}
 
 	// Write footer with timer frequency.
@@ -480,13 +547,22 @@
 		}
 		trace.lockOwner = nil
 		unlock(&trace.lock)
-		var data []byte
-		data = append(data, traceEvFrequency|0<<traceArgCountShift)
-		data = traceAppend(data, uint64(freq))
+
+		// Write frequency event.
+		bufp := traceFlush(0, 0)
+		buf := bufp.ptr()
+		buf.byte(traceEvFrequency | 0<<traceArgCountShift)
+		buf.varint(uint64(freq))
+
+		// Dump stack table.
 		// This will emit a bunch of full buffers, we will pick them up
 		// on the next iteration.
-		trace.stackTab.dump()
-		return data
+		bufp = trace.stackTab.dump(bufp)
+
+		// Flush final buffer.
+		lock(&trace.lock)
+		traceFullQueue(bufp)
+		goto newFull // trace.lock should be held at newFull
 	}
 	// Done.
 	if trace.shutdown {
@@ -500,40 +576,51 @@
 		}
 		// trace.enabled is already reset, so can call traceable functions.
 		semrelease(&trace.shutdownSema)
-		return nil
+		return nil, false
 	}
 	// Also bad, but see the comment above.
 	trace.lockOwner = nil
 	unlock(&trace.lock)
 	println("runtime: spurious wakeup of trace reader")
-	return nil
+	return nil, false
 }
 
 // traceReader returns the trace reader that should be woken up, if any.
 // Callers should first check that trace.enabled or trace.shutdown is set.
+//
+// This must run on the system stack because it acquires trace.lock.
+//
+//go:systemstack
 func traceReader() *g {
-	if !traceReaderAvailable() {
+	// Optimistic check first
+	if traceReaderAvailable() == nil {
 		return nil
 	}
 	lock(&trace.lock)
-	if !traceReaderAvailable() {
+	gp := traceReaderAvailable()
+	if gp == nil || !trace.reader.CompareAndSwapNoWB(gp, nil) {
 		unlock(&trace.lock)
 		return nil
 	}
-	gp := trace.reader.ptr()
-	trace.reader.set(nil)
 	unlock(&trace.lock)
 	return gp
 }
 
-// traceReaderAvailable returns true if the trace reader is not currently
+// traceReaderAvailable returns the trace reader if it is not currently
 // scheduled and should be. Callers should first check that trace.enabled
 // or trace.shutdown is set.
-func traceReaderAvailable() bool {
-	return trace.reader != 0 && (trace.fullHead != 0 || trace.shutdown)
+func traceReaderAvailable() *g {
+	if trace.fullHead != 0 || trace.shutdown {
+		return trace.reader.Load()
+	}
+	return nil
 }
 
 // traceProcFree frees trace buffer associated with pp.
+//
+// This must run on the system stack because it acquires trace.lock.
+//
+//go:systemstack
 func traceProcFree(pp *p) {
 	buf := pp.tracebuf
 	pp.tracebuf = 0
@@ -624,7 +711,9 @@
 	// TODO: test on non-zero extraBytes param.
 	maxSize := 2 + 5*traceBytesPerNumber + extraBytes // event type, length, sequence, timestamp, stack id and two add params
 	if buf == nil || len(buf.arr)-buf.pos < maxSize {
-		buf = traceFlush(traceBufPtrOf(buf), pid).ptr()
+		systemstack(func() {
+			buf = traceFlush(traceBufPtrOf(buf), pid).ptr()
+		})
 		bufp.set(buf)
 	}
 
@@ -701,7 +790,7 @@
 		hdr[0] = 0b10
 	}
 	if gp != nil {
-		hdr[1] = uint64(gp.goid)
+		hdr[1] = gp.goid
 	}
 
 	// Allow only one writer at a time
@@ -765,7 +854,9 @@
 
 			buf := bufp.ptr()
 			if buf == nil {
-				*bufp = traceFlush(*bufp, 0)
+				systemstack(func() {
+					*bufp = traceFlush(*bufp, 0)
+				})
 				buf = bufp.ptr()
 			}
 			for i := range stk {
@@ -782,19 +873,18 @@
 }
 
 func traceStackID(mp *m, buf []uintptr, skip int) uint64 {
-	_g_ := getg()
-	gp := mp.curg
+	gp := getg()
+	curgp := mp.curg
 	var nstk int
-	if gp == _g_ {
+	if curgp == gp {
 		nstk = callers(skip+1, buf)
-	} else if gp != nil {
-		gp = mp.curg
-		nstk = gcallers(gp, skip, buf)
+	} else if curgp != nil {
+		nstk = gcallers(curgp, skip, buf)
 	}
 	if nstk > 0 {
 		nstk-- // skip runtime.goexit
 	}
-	if nstk > 0 && gp.goid == 1 {
+	if nstk > 0 && curgp.goid == 1 {
 		nstk-- // skip runtime.main
 	}
 	id := trace.stackTab.put(buf[:nstk])
@@ -803,6 +893,11 @@
 
 // traceAcquireBuffer returns trace buffer to use and, if necessary, locks it.
 func traceAcquireBuffer() (mp *m, pid int32, bufp *traceBufPtr) {
+	// Any time we acquire a buffer, we may end up flushing it,
+	// but flushes are rare. Record the lock edge even if it
+	// doesn't happen this time.
+	lockRankMayTraceFlush()
+
 	mp = acquirem()
 	if p := mp.p.ptr(); p != nil {
 		return mp, p.id, &p.tracebuf
@@ -819,7 +914,21 @@
 	releasem(getg().m)
 }
 
+// lockRankMayTraceFlush records the lock ranking effects of a
+// potential call to traceFlush.
+func lockRankMayTraceFlush() {
+	owner := trace.lockOwner
+	dolock := owner == nil || owner != getg().m.curg
+	if dolock {
+		lockWithRankMayAcquire(&trace.lock, getLockRank(&trace.lock))
+	}
+}
+
 // traceFlush puts buf onto stack of full buffers and returns an empty buffer.
+//
+// This must run on the system stack because it acquires trace.lock.
+//
+//go:systemstack
 func traceFlush(buf traceBufPtr, pid int32) traceBufPtr {
 	owner := trace.lockOwner
 	dolock := owner == nil || owner != getg().m.curg
@@ -897,8 +1006,10 @@
 	buf := bufp.ptr()
 	size := 1 + 2*traceBytesPerNumber + len(s)
 	if buf == nil || len(buf.arr)-buf.pos < size {
-		buf = traceFlush(traceBufPtrOf(buf), pid).ptr()
-		bufp.set(buf)
+		systemstack(func() {
+			buf = traceFlush(traceBufPtrOf(buf), pid).ptr()
+			bufp.set(buf)
+		})
 	}
 	buf.byte(traceEvString)
 	buf.varint(id)
@@ -917,15 +1028,6 @@
 	return id, bufp
 }
 
-// traceAppend appends v to buf in little-endian-base-128 encoding.
-func traceAppend(buf []byte, v uint64) []byte {
-	for ; v >= 0x80; v >>= 7 {
-		buf = append(buf, 0x80|byte(v))
-	}
-	buf = append(buf, byte(v))
-	return buf
-}
-
 // varint appends v to buf in little-endian-base-128 encoding.
 func (buf *traceBuf) varint(v uint64) {
 	pos := buf.pos
@@ -938,6 +1040,22 @@
 	buf.pos = pos
 }
 
+// varintAt writes varint v at byte position pos in buf. This always
+// consumes traceBytesPerNumber bytes. This is intended for when the
+// caller needs to reserve space for a varint but can't populate it
+// until later.
+func (buf *traceBuf) varintAt(pos int, v uint64) {
+	for i := 0; i < traceBytesPerNumber; i++ {
+		if i < traceBytesPerNumber-1 {
+			buf.arr[pos] = 0x80 | byte(v)
+		} else {
+			buf.arr[pos] = byte(v)
+		}
+		v >>= 7
+		pos++
+	}
+}
+
 // byte appends v to buf.
 func (buf *traceBuf) byte(v byte) {
 	buf.arr[buf.pos] = v
@@ -947,7 +1065,7 @@
 // traceStackTable maps stack traces (arrays of PC's) to unique uint32 ids.
 // It is lock-free for reading.
 type traceStackTable struct {
-	lock mutex
+	lock mutex // Must be acquired on the system stack
 	seq  uint32
 	mem  traceAlloc
 	tab  [1 << 13]traceStackPtr
@@ -983,26 +1101,31 @@
 		return id
 	}
 	// Now, double check under the mutex.
-	lock(&tab.lock)
-	if id := tab.find(pcs, hash); id != 0 {
+	// Switch to the system stack so we can acquire tab.lock
+	var id uint32
+	systemstack(func() {
+		lock(&tab.lock)
+		if id = tab.find(pcs, hash); id != 0 {
+			unlock(&tab.lock)
+			return
+		}
+		// Create new record.
+		tab.seq++
+		stk := tab.newStack(len(pcs))
+		stk.hash = hash
+		stk.id = tab.seq
+		id = stk.id
+		stk.n = len(pcs)
+		stkpc := stk.stack()
+		for i, pc := range pcs {
+			stkpc[i] = pc
+		}
+		part := int(hash % uintptr(len(tab.tab)))
+		stk.link = tab.tab[part]
+		atomicstorep(unsafe.Pointer(&tab.tab[part]), unsafe.Pointer(stk))
 		unlock(&tab.lock)
-		return id
-	}
-	// Create new record.
-	tab.seq++
-	stk := tab.newStack(len(pcs))
-	stk.hash = hash
-	stk.id = tab.seq
-	stk.n = len(pcs)
-	stkpc := stk.stack()
-	for i, pc := range pcs {
-		stkpc[i] = pc
-	}
-	part := int(hash % uintptr(len(tab.tab)))
-	stk.link = tab.tab[part]
-	atomicstorep(unsafe.Pointer(&tab.tab[part]), unsafe.Pointer(stk))
-	unlock(&tab.lock)
-	return stk.id
+	})
+	return id
 }
 
 // find checks if the stack trace pcs is already present in the table.
@@ -1027,61 +1150,75 @@
 	return (*traceStack)(tab.mem.alloc(unsafe.Sizeof(traceStack{}) + uintptr(n)*goarch.PtrSize))
 }
 
-// allFrames returns all of the Frames corresponding to pcs.
-func allFrames(pcs []uintptr) []Frame {
-	frames := make([]Frame, 0, len(pcs))
+// traceFrames returns the frames corresponding to pcs. It may
+// allocate and may emit trace events.
+func traceFrames(bufp traceBufPtr, pcs []uintptr) ([]traceFrame, traceBufPtr) {
+	frames := make([]traceFrame, 0, len(pcs))
 	ci := CallersFrames(pcs)
 	for {
+		var frame traceFrame
 		f, more := ci.Next()
-		frames = append(frames, f)
+		frame, bufp = traceFrameForPC(bufp, 0, f)
+		frames = append(frames, frame)
 		if !more {
-			return frames
+			return frames, bufp
 		}
 	}
 }
 
 // dump writes all previously cached stacks to trace buffers,
 // releases all memory and resets state.
-func (tab *traceStackTable) dump() {
-	var tmp [(2 + 4*traceStackSize) * traceBytesPerNumber]byte
-	bufp := traceFlush(0, 0)
-	for _, stk := range tab.tab {
-		stk := stk.ptr()
+//
+// This must run on the system stack because it calls traceFlush.
+//
+//go:systemstack
+func (tab *traceStackTable) dump(bufp traceBufPtr) traceBufPtr {
+	for i := range tab.tab {
+		stk := tab.tab[i].ptr()
 		for ; stk != nil; stk = stk.link.ptr() {
-			tmpbuf := tmp[:0]
-			tmpbuf = traceAppend(tmpbuf, uint64(stk.id))
-			frames := allFrames(stk.stack())
-			tmpbuf = traceAppend(tmpbuf, uint64(len(frames)))
-			for _, f := range frames {
-				var frame traceFrame
-				frame, bufp = traceFrameForPC(bufp, 0, f)
-				tmpbuf = traceAppend(tmpbuf, uint64(f.PC))
-				tmpbuf = traceAppend(tmpbuf, uint64(frame.funcID))
-				tmpbuf = traceAppend(tmpbuf, uint64(frame.fileID))
-				tmpbuf = traceAppend(tmpbuf, uint64(frame.line))
-			}
-			// Now copy to the buffer.
-			size := 1 + traceBytesPerNumber + len(tmpbuf)
-			if buf := bufp.ptr(); len(buf.arr)-buf.pos < size {
+			var frames []traceFrame
+			frames, bufp = traceFrames(bufp, stk.stack())
+
+			// Estimate the size of this record. This
+			// bound is pretty loose, but avoids counting
+			// lots of varint sizes.
+			maxSize := 1 + traceBytesPerNumber + (2+4*len(frames))*traceBytesPerNumber
+			// Make sure we have enough buffer space.
+			if buf := bufp.ptr(); len(buf.arr)-buf.pos < maxSize {
 				bufp = traceFlush(bufp, 0)
 			}
+
+			// Emit header, with space reserved for length.
 			buf := bufp.ptr()
 			buf.byte(traceEvStack | 3<<traceArgCountShift)
-			buf.varint(uint64(len(tmpbuf)))
-			buf.pos += copy(buf.arr[buf.pos:], tmpbuf)
+			lenPos := buf.pos
+			buf.pos += traceBytesPerNumber
+
+			// Emit body.
+			recPos := buf.pos
+			buf.varint(uint64(stk.id))
+			buf.varint(uint64(len(frames)))
+			for _, frame := range frames {
+				buf.varint(uint64(frame.PC))
+				buf.varint(frame.funcID)
+				buf.varint(frame.fileID)
+				buf.varint(frame.line)
+			}
+
+			// Fill in size header.
+			buf.varintAt(lenPos, uint64(buf.pos-recPos))
 		}
 	}
 
-	lock(&trace.lock)
-	traceFullQueue(bufp)
-	unlock(&trace.lock)
-
 	tab.mem.drop()
 	*tab = traceStackTable{}
 	lockInit(&((*tab).lock), lockRankTraceStackTab)
+
+	return bufp
 }
 
 type traceFrame struct {
+	PC     uintptr
 	funcID uint64
 	fileID uint64
 	line   uint64
@@ -1092,6 +1229,7 @@
 func traceFrameForPC(buf traceBufPtr, pid int32, f Frame) (traceFrame, traceBufPtr) {
 	bufp := &buf
 	var frame traceFrame
+	frame.PC = f.PC
 
 	fn := f.Function
 	const maxLen = 1 << 10
@@ -1120,14 +1258,13 @@
 // traceAllocBlock is allocated from non-GC'd memory, so it must not
 // contain heap pointers. Writes to pointers to traceAllocBlocks do
 // not need write barriers.
-//
-//go:notinheap
 type traceAllocBlock struct {
+	_    sys.NotInHeap
 	next traceAllocBlockPtr
 	data [64<<10 - goarch.PtrSize]byte
 }
 
-// TODO: Since traceAllocBlock is now go:notinheap, this isn't necessary.
+// TODO: Since traceAllocBlock is now embedded runtime/internal/sys.NotInHeap, this isn't necessary.
 type traceAllocBlockPtr uintptr
 
 func (p traceAllocBlockPtr) ptr() *traceAllocBlock   { return (*traceAllocBlock)(unsafe.Pointer(p)) }
@@ -1208,11 +1345,11 @@
 func traceGCSweepStart() {
 	// Delay the actual GCSweepStart event until the first span
 	// sweep. If we don't sweep anything, don't emit any events.
-	_p_ := getg().m.p.ptr()
-	if _p_.traceSweep {
+	pp := getg().m.p.ptr()
+	if pp.traceSweep {
 		throw("double traceGCSweepStart")
 	}
-	_p_.traceSweep, _p_.traceSwept, _p_.traceReclaimed = true, 0, 0
+	pp.traceSweep, pp.traceSwept, pp.traceReclaimed = true, 0, 0
 }
 
 // traceGCSweepSpan traces the sweep of a single page.
@@ -1220,24 +1357,24 @@
 // This may be called outside a traceGCSweepStart/traceGCSweepDone
 // pair; however, it will not emit any trace events in this case.
 func traceGCSweepSpan(bytesSwept uintptr) {
-	_p_ := getg().m.p.ptr()
-	if _p_.traceSweep {
-		if _p_.traceSwept == 0 {
+	pp := getg().m.p.ptr()
+	if pp.traceSweep {
+		if pp.traceSwept == 0 {
 			traceEvent(traceEvGCSweepStart, 1)
 		}
-		_p_.traceSwept += bytesSwept
+		pp.traceSwept += bytesSwept
 	}
 }
 
 func traceGCSweepDone() {
-	_p_ := getg().m.p.ptr()
-	if !_p_.traceSweep {
+	pp := getg().m.p.ptr()
+	if !pp.traceSweep {
 		throw("missing traceGCSweepStart")
 	}
-	if _p_.traceSwept != 0 {
-		traceEvent(traceEvGCSweepDone, -1, uint64(_p_.traceSwept), uint64(_p_.traceReclaimed))
+	if pp.traceSwept != 0 {
+		traceEvent(traceEvGCSweepDone, -1, uint64(pp.traceSwept), uint64(pp.traceReclaimed))
 	}
-	_p_.traceSweep = false
+	pp.traceSweep = false
 }
 
 func traceGCMarkAssistStart() {
@@ -1253,20 +1390,20 @@
 	newg.tracelastp = getg().m.p
 	// +PCQuantum because traceFrameForPC expects return PCs and subtracts PCQuantum.
 	id := trace.stackTab.put([]uintptr{startPCforTrace(pc) + sys.PCQuantum})
-	traceEvent(traceEvGoCreate, 2, uint64(newg.goid), uint64(id))
+	traceEvent(traceEvGoCreate, 2, newg.goid, uint64(id))
 }
 
 func traceGoStart() {
-	_g_ := getg().m.curg
-	_p_ := _g_.m.p
-	_g_.traceseq++
-	if _p_.ptr().gcMarkWorkerMode != gcMarkWorkerNotWorker {
-		traceEvent(traceEvGoStartLabel, -1, uint64(_g_.goid), _g_.traceseq, trace.markWorkerLabels[_p_.ptr().gcMarkWorkerMode])
-	} else if _g_.tracelastp == _p_ {
-		traceEvent(traceEvGoStartLocal, -1, uint64(_g_.goid))
+	gp := getg().m.curg
+	pp := gp.m.p
+	gp.traceseq++
+	if pp.ptr().gcMarkWorkerMode != gcMarkWorkerNotWorker {
+		traceEvent(traceEvGoStartLabel, -1, gp.goid, gp.traceseq, trace.markWorkerLabels[pp.ptr().gcMarkWorkerMode])
+	} else if gp.tracelastp == pp {
+		traceEvent(traceEvGoStartLocal, -1, gp.goid)
 	} else {
-		_g_.tracelastp = _p_
-		traceEvent(traceEvGoStart, -1, uint64(_g_.goid), _g_.traceseq)
+		gp.tracelastp = pp
+		traceEvent(traceEvGoStart, -1, gp.goid, gp.traceseq)
 	}
 }
 
@@ -1275,14 +1412,14 @@
 }
 
 func traceGoSched() {
-	_g_ := getg()
-	_g_.tracelastp = _g_.m.p
+	gp := getg()
+	gp.tracelastp = gp.m.p
 	traceEvent(traceEvGoSched, 1)
 }
 
 func traceGoPreempt() {
-	_g_ := getg()
-	_g_.tracelastp = _g_.m.p
+	gp := getg()
+	gp.tracelastp = gp.m.p
 	traceEvent(traceEvGoPreempt, 1)
 }
 
@@ -1294,13 +1431,13 @@
 }
 
 func traceGoUnpark(gp *g, skip int) {
-	_p_ := getg().m.p
+	pp := getg().m.p
 	gp.traceseq++
-	if gp.tracelastp == _p_ {
-		traceEvent(traceEvGoUnblockLocal, skip, uint64(gp.goid))
+	if gp.tracelastp == pp {
+		traceEvent(traceEvGoUnblockLocal, skip, gp.goid)
 	} else {
-		gp.tracelastp = _p_
-		traceEvent(traceEvGoUnblock, skip, uint64(gp.goid), gp.traceseq)
+		gp.tracelastp = pp
+		traceEvent(traceEvGoUnblock, skip, gp.goid, gp.traceseq)
 	}
 }
 
@@ -1321,10 +1458,10 @@
 		// aka right now), and assign a fresh time stamp to keep the log consistent.
 		ts = 0
 	}
-	_g_ := getg().m.curg
-	_g_.traceseq++
-	_g_.tracelastp = _g_.m.p
-	traceEvent(traceEvGoSysExit, -1, uint64(_g_.goid), _g_.traceseq, uint64(ts)/traceTickDiv)
+	gp := getg().m.curg
+	gp.traceseq++
+	gp.tracelastp = gp.m.p
+	traceEvent(traceEvGoSysExit, -1, gp.goid, gp.traceseq, uint64(ts)/traceTickDiv)
 }
 
 func traceGoSysBlock(pp *p) {
@@ -1338,8 +1475,8 @@
 	releasem(mp)
 }
 
-func traceHeapAlloc() {
-	traceEvent(traceEvHeapAlloc, -1, gcController.heapLive)
+func traceHeapAlloc(live uint64) {
+	traceEvent(traceEvHeapAlloc, -1, live)
 }
 
 func traceHeapGoal() {
@@ -1432,7 +1569,7 @@
 func startPCforTrace(pc uintptr) uintptr {
 	f := findfunc(pc)
 	if !f.valid() {
-		return pc // should not happen, but don't care
+		return pc // may happen for locked g in extra M since its pc is 0.
 	}
 	w := funcdata(f, _FUNCDATA_WrapInfo)
 	if w == nil {
diff --git a/src/runtime/trace/annotation.go b/src/runtime/trace/annotation.go
index 9171633..d47cb85 100644
--- a/src/runtime/trace/annotation.go
+++ b/src/runtime/trace/annotation.go
@@ -178,8 +178,7 @@
 // The information is advisory only. The tracing status
 // may have changed by the time this function returns.
 func IsEnabled() bool {
-	enabled := atomic.LoadInt32(&tracing.enabled)
-	return enabled == 1
+	return tracing.enabled.Load()
 }
 
 //
diff --git a/src/runtime/trace/annotation_test.go b/src/runtime/trace/annotation_test.go
index 31fccef..69ea8f2 100644
--- a/src/runtime/trace/annotation_test.go
+++ b/src/runtime/trace/annotation_test.go
@@ -147,7 +147,7 @@
 		pretty := func(data []testData) string {
 			var s strings.Builder
 			for _, d := range data {
-				s.WriteString(fmt.Sprintf("\t%+v\n", d))
+				fmt.Fprintf(&s, "\t%+v\n", d)
 			}
 			return s.String()
 		}
diff --git a/src/runtime/trace/trace.go b/src/runtime/trace/trace.go
index cf2b644..86c97e2 100644
--- a/src/runtime/trace/trace.go
+++ b/src/runtime/trace/trace.go
@@ -134,7 +134,7 @@
 			w.Write(data)
 		}
 	}()
-	atomic.StoreInt32(&tracing.enabled, 1)
+	tracing.enabled.Store(true)
 	return nil
 }
 
@@ -143,12 +143,12 @@
 func Stop() {
 	tracing.Lock()
 	defer tracing.Unlock()
-	atomic.StoreInt32(&tracing.enabled, 0)
+	tracing.enabled.Store(false)
 
 	runtime.StopTrace()
 }
 
 var tracing struct {
-	sync.Mutex       // gate mutators (Start, Stop)
-	enabled    int32 // accessed via atomic
+	sync.Mutex // gate mutators (Start, Stop)
+	enabled    atomic.Bool
 }
diff --git a/src/runtime/traceback.go b/src/runtime/traceback.go
index 49147ff..37f35d5 100644
--- a/src/runtime/traceback.go
+++ b/src/runtime/traceback.go
@@ -7,7 +7,6 @@
 import (
 	"internal/bytealg"
 	"internal/goarch"
-	"runtime/internal/atomic"
 	"runtime/internal/sys"
 	"unsafe"
 )
@@ -54,8 +53,6 @@
 	}
 	level, _, _ := gotraceback()
 
-	var ctxt *funcval // Context pointer for unstarted goroutines. See issue #25897.
-
 	if pc0 == ^uintptr(0) && sp0 == ^uintptr(0) { // Signal to fetch saved values from gp.
 		if gp.syscallsp != 0 {
 			pc0 = gp.syscallpc
@@ -69,7 +66,6 @@
 			if usesLR {
 				lr0 = gp.sched.lr
 			}
-			ctxt = (*funcval)(gp.sched.ctxt)
 		}
 	}
 
@@ -163,7 +159,10 @@
 		if frame.fp == 0 {
 			// Jump over system stack transitions. If we're on g0 and there's a user
 			// goroutine, try to jump. Otherwise this is a regular call.
-			if flags&_TraceJumpStack != 0 && gp == gp.m.g0 && gp.m.curg != nil {
+			// We also defensively check that this won't switch M's on us,
+			// which could happen at critical points in the scheduler.
+			// This ensures gp.m doesn't change from a stack jump.
+			if flags&_TraceJumpStack != 0 && gp == gp.m.g0 && gp.m.curg != nil && gp.m.curg.m == gp.m {
 				switch f.funcID {
 				case funcID_morestack:
 					// morestack does not return normally -- newstack()
@@ -171,20 +170,33 @@
 					// This keeps morestack() from showing up in the backtrace,
 					// but that makes some sense since it'll never be returned
 					// to.
-					frame.pc = gp.m.curg.sched.pc
+					gp = gp.m.curg
+					frame.pc = gp.sched.pc
 					frame.fn = findfunc(frame.pc)
 					f = frame.fn
 					flag = f.flag
-					frame.lr = gp.m.curg.sched.lr
-					frame.sp = gp.m.curg.sched.sp
-					stack = gp.m.curg.stack
-					cgoCtxt = gp.m.curg.cgoCtxt
+					frame.lr = gp.sched.lr
+					frame.sp = gp.sched.sp
+					stack = gp.stack
+					cgoCtxt = gp.cgoCtxt
 				case funcID_systemstack:
 					// systemstack returns normally, so just follow the
 					// stack transition.
-					frame.sp = gp.m.curg.sched.sp
-					stack = gp.m.curg.stack
-					cgoCtxt = gp.m.curg.cgoCtxt
+					if usesLR && funcspdelta(f, frame.pc, &cache) == 0 {
+						// We're at the function prologue and the stack
+						// switch hasn't happened, or epilogue where we're
+						// about to return. Just unwind normally.
+						// Do this only on LR machines because on x86
+						// systemstack doesn't have an SP delta (the CALL
+						// instruction opens the frame), therefore no way
+						// to check.
+						flag &^= funcFlag_SPWRITE
+						break
+					}
+					gp = gp.m.curg
+					frame.sp = gp.sched.sp
+					stack = gp.stack
+					cgoCtxt = gp.cgoCtxt
 					flag &^= funcFlag_SPWRITE
 				}
 			}
@@ -287,21 +299,7 @@
 			frame.varp -= goarch.PtrSize
 		}
 
-		// Derive size of arguments.
-		// Most functions have a fixed-size argument block,
-		// so we can use metadata about the function f.
-		// Not all, though: there are some variadic functions
-		// in package runtime and reflect, and for those we use call-specific
-		// metadata recorded by f's caller.
-		if callback != nil || printing {
-			frame.argp = frame.fp + sys.MinFrameSize
-			var ok bool
-			frame.arglen, frame.argmap, ok = getArgInfoFast(f, callback != nil)
-			if !ok {
-				frame.arglen, frame.argmap = getArgInfo(&frame, f, callback != nil, ctxt)
-			}
-		}
-		ctxt = nil // ctxt is only needed to get arg maps for the topmost frame
+		frame.argp = frame.fp + sys.MinFrameSize
 
 		// Determine frame's 'continuation PC', where it can continue.
 		// Normally this is the return address on the stack, but if sigpanic
@@ -418,8 +416,9 @@
 
 					// Create a fake _func for the
 					// inlined function.
-					inlFunc.nameoff = inltree[ix].func_
+					inlFunc.nameOff = inltree[ix].nameOff
 					inlFunc.funcID = inltree[ix].funcID
+					inlFunc.startLine = inltree[ix].startLine
 
 					if (flags&_TraceRuntimeFrames) != 0 || showframe(inlFuncInfo, gp, nprint == 0, inlFuncInfo.funcID, lastFuncID) {
 						name := funcname(inlFuncInfo)
@@ -494,7 +493,6 @@
 		frame.lr = 0
 		frame.sp = frame.fp
 		frame.fp = 0
-		frame.argmap = nil
 
 		// On link register architectures, sighandler saves the LR on stack
 		// before faking a call.
@@ -665,74 +663,6 @@
 	}
 }
 
-// reflectMethodValue is a partial duplicate of reflect.makeFuncImpl
-// and reflect.methodValue.
-type reflectMethodValue struct {
-	fn     uintptr
-	stack  *bitvector // ptrmap for both args and results
-	argLen uintptr    // just args
-}
-
-// getArgInfoFast returns the argument frame information for a call to f.
-// It is short and inlineable. However, it does not handle all functions.
-// If ok reports false, you must call getArgInfo instead.
-// TODO(josharian): once we do mid-stack inlining,
-// call getArgInfo directly from getArgInfoFast and stop returning an ok bool.
-func getArgInfoFast(f funcInfo, needArgMap bool) (arglen uintptr, argmap *bitvector, ok bool) {
-	return uintptr(f.args), nil, !(needArgMap && f.args == _ArgsSizeUnknown)
-}
-
-// getArgInfo returns the argument frame information for a call to f
-// with call frame frame.
-//
-// This is used for both actual calls with active stack frames and for
-// deferred calls or goroutines that are not yet executing. If this is an actual
-// call, ctxt must be nil (getArgInfo will retrieve what it needs from
-// the active stack frame). If this is a deferred call or unstarted goroutine,
-// ctxt must be the function object that was deferred or go'd.
-func getArgInfo(frame *stkframe, f funcInfo, needArgMap bool, ctxt *funcval) (arglen uintptr, argmap *bitvector) {
-	arglen = uintptr(f.args)
-	if needArgMap && f.args == _ArgsSizeUnknown {
-		// Extract argument bitmaps for reflect stubs from the calls they made to reflect.
-		switch funcname(f) {
-		case "reflect.makeFuncStub", "reflect.methodValueCall":
-			// These take a *reflect.methodValue as their
-			// context register.
-			var mv *reflectMethodValue
-			var retValid bool
-			if ctxt != nil {
-				// This is not an actual call, but a
-				// deferred call or an unstarted goroutine.
-				// The function value is itself the *reflect.methodValue.
-				mv = (*reflectMethodValue)(unsafe.Pointer(ctxt))
-			} else {
-				// This is a real call that took the
-				// *reflect.methodValue as its context
-				// register and immediately saved it
-				// to 0(SP). Get the methodValue from
-				// 0(SP).
-				arg0 := frame.sp + sys.MinFrameSize
-				mv = *(**reflectMethodValue)(unsafe.Pointer(arg0))
-				// Figure out whether the return values are valid.
-				// Reflect will update this value after it copies
-				// in the return values.
-				retValid = *(*bool)(unsafe.Pointer(arg0 + 4*goarch.PtrSize))
-			}
-			if mv.fn != f.entry() {
-				print("runtime: confused by ", funcname(f), "\n")
-				throw("reflect mismatch")
-			}
-			bv := mv.stack
-			arglen = uintptr(bv.n * goarch.PtrSize)
-			if !retValid {
-				arglen = uintptr(mv.argLen) &^ (goarch.PtrSize - 1)
-			}
-			argmap = bv
-		}
-	}
-	return
-}
-
 // tracebackCgoContext handles tracing back a cgo context value, from
 // the context argument to setCgoTraceback, for the gentraceback
 // function. It returns the new value of n.
@@ -819,10 +749,10 @@
 		// concurrently with a signal handler.
 		// We just have to stop a signal handler from interrupting
 		// in the middle of our copy.
-		atomic.Store(&gp.m.cgoCallersUse, 1)
+		gp.m.cgoCallersUse.Store(1)
 		cgoCallers := *gp.m.cgoCallers
 		gp.m.cgoCallers[0] = 0
-		atomic.Store(&gp.m.cgoCallersUse, 0)
+		gp.m.cgoCallersUse.Store(0)
 
 		printCgoTraceback(&cgoCallers)
 	}
@@ -880,7 +810,7 @@
 	}
 }
 
-// printAncestorTraceback prints the given function info at a given pc
+// printAncestorTracebackFuncInfo prints the given function info at a given pc
 // within an ancestor traceback. The precision of this info is reduced
 // due to only have access to the pcs at the time of the caller
 // goroutine being created.
@@ -890,7 +820,7 @@
 		inltree := (*[1 << 20]inlinedCall)(inldata)
 		ix := pcdatavalue(f, _PCDATA_InlTreeIndex, pc, nil)
 		if ix >= 0 {
-			name = funcnameFromNameoff(f, inltree[ix].func_)
+			name = funcnameFromNameOff(f, inltree[ix].nameOff)
 		}
 	}
 	file, line := funcline(f, pc)
@@ -923,8 +853,8 @@
 // showframe reports whether the frame with the given characteristics should
 // be printed during a traceback.
 func showframe(f funcInfo, gp *g, firstFrame bool, funcID, childID funcID) bool {
-	g := getg()
-	if g.m.throwing >= throwTypeRuntime && gp != nil && (gp == g.m.curg || gp == g.m.caughtsig.ptr()) {
+	mp := getg().m
+	if mp.throwing >= throwTypeRuntime && gp != nil && (gp == mp.curg || gp == mp.caughtsig.ptr()) {
 		return true
 	}
 	return showfuncinfo(f, firstFrame, funcID, childID)
@@ -934,7 +864,7 @@
 // be printed during a traceback.
 func showfuncinfo(f funcInfo, firstFrame bool, funcID, childID funcID) bool {
 	// Note that f may be a synthesized funcInfo for an inlined
-	// function, in which case only nameoff and funcID are set.
+	// function, in which case only nameOff and funcID are set.
 
 	level, _, _ := gotraceback()
 	if level > 1 {
@@ -1051,10 +981,10 @@
 		}
 		print("\n")
 		goroutineheader(gp)
-		// Note: gp.m == g.m occurs when tracebackothers is
-		// called from a signal handler initiated during a
-		// systemstack call. The original G is still in the
-		// running state, and we want to print its stack.
+		// Note: gp.m == getg().m occurs when tracebackothers is called
+		// from a signal handler initiated during a systemstack call.
+		// The original G is still in the running state, and we want to
+		// print its stack.
 		if gp.m != getg().m && readgstatus(gp)&^_Gscan == _Grunning {
 			print("\tgoroutine running on other thread; stack unavailable\n")
 			printcreatedby(gp)
@@ -1136,7 +1066,7 @@
 			// always consider it a user goroutine.
 			return false
 		}
-		return !fingRunning
+		return fingStatus.Load()&fingRunningFinalizer == 0
 	}
 	return hasPrefix(funcname(f), "runtime.")
 }
@@ -1352,7 +1282,7 @@
 	data     uintptr
 }
 
-// cgoTraceback prints a traceback of callers.
+// printCgoTraceback prints a traceback of callers.
 func printCgoTraceback(callers *cgoCallers) {
 	if cgoSymbolizer == nil {
 		for _, c := range callers {
@@ -1407,7 +1337,7 @@
 // callCgoSymbolizer calls the cgoSymbolizer function.
 func callCgoSymbolizer(arg *cgoSymbolizerArg) {
 	call := cgocall
-	if panicking > 0 || getg().m.curg != getg() {
+	if panicking.Load() > 0 || getg().m.curg != getg() {
 		// We do not want to call into the scheduler when panicking
 		// or when on the system stack.
 		call = asmcgocall
@@ -1427,7 +1357,7 @@
 		return
 	}
 	call := cgocall
-	if panicking > 0 || getg().m.curg != getg() {
+	if panicking.Load() > 0 || getg().m.curg != getg() {
 		// We do not want to call into the scheduler when panicking
 		// or when on the system stack.
 		call = asmcgocall
diff --git a/src/runtime/traceback_test.go b/src/runtime/traceback_test.go
index e50bd95..97eb921 100644
--- a/src/runtime/traceback_test.go
+++ b/src/runtime/traceback_test.go
@@ -9,7 +9,6 @@
 	"internal/abi"
 	"internal/testenv"
 	"runtime"
-	"strings"
 	"testing"
 )
 
@@ -19,7 +18,7 @@
 	if *flagQuick {
 		t.Skip("-quick")
 	}
-	optimized := !strings.HasSuffix(testenv.Builder(), "-noopt")
+	optimized := !testenv.OptimizationOff()
 	abiSel := func(x, y string) string {
 		// select expected output based on ABI
 		// In noopt build we always spill arguments so the output is the same as stack ABI.
diff --git a/src/runtime/type.go b/src/runtime/type.go
index e8e7819..1c6103e 100644
--- a/src/runtime/type.go
+++ b/src/runtime/type.go
@@ -454,7 +454,7 @@
 	}
 }
 
-func (n name) name() (s string) {
+func (n name) name() string {
 	if n.bytes == nil {
 		return ""
 	}
@@ -462,22 +462,16 @@
 	if l == 0 {
 		return ""
 	}
-	hdr := (*stringStruct)(unsafe.Pointer(&s))
-	hdr.str = unsafe.Pointer(n.data(1 + i))
-	hdr.len = l
-	return
+	return unsafe.String(n.data(1+i), l)
 }
 
-func (n name) tag() (s string) {
+func (n name) tag() string {
 	if *n.data(0)&(1<<1) == 0 {
 		return ""
 	}
 	i, l := n.readvarint(1)
 	i2, l2 := n.readvarint(1 + i + l)
-	hdr := (*stringStruct)(unsafe.Pointer(&s))
-	hdr.str = unsafe.Pointer(n.data(1 + i + l + i2))
-	hdr.len = l2
-	return
+	return unsafe.String(n.data(1+i+l+i2), l2)
 }
 
 func (n name) pkgPath() string {
diff --git a/src/runtime/unsafe.go b/src/runtime/unsafe.go
new file mode 100644
index 0000000..54649e8
--- /dev/null
+++ b/src/runtime/unsafe.go
@@ -0,0 +1,98 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+import (
+	"runtime/internal/math"
+	"unsafe"
+)
+
+func unsafestring(ptr unsafe.Pointer, len int) {
+	if len < 0 {
+		panicunsafestringlen()
+	}
+
+	if uintptr(len) > -uintptr(ptr) {
+		if ptr == nil {
+			panicunsafestringnilptr()
+		}
+		panicunsafestringlen()
+	}
+}
+
+// Keep this code in sync with cmd/compile/internal/walk/builtin.go:walkUnsafeString
+func unsafestring64(ptr unsafe.Pointer, len64 int64) {
+	len := int(len64)
+	if int64(len) != len64 {
+		panicunsafestringlen()
+	}
+	unsafestring(ptr, len)
+}
+
+func unsafestringcheckptr(ptr unsafe.Pointer, len64 int64) {
+	unsafestring64(ptr, len64)
+
+	// Check that underlying array doesn't straddle multiple heap objects.
+	// unsafestring64 has already checked for overflow.
+	if checkptrStraddles(ptr, uintptr(len64)) {
+		throw("checkptr: unsafe.String result straddles multiple allocations")
+	}
+}
+
+func panicunsafestringlen() {
+	panic(errorString("unsafe.String: len out of range"))
+}
+
+func panicunsafestringnilptr() {
+	panic(errorString("unsafe.String: ptr is nil and len is not zero"))
+}
+
+// Keep this code in sync with cmd/compile/internal/walk/builtin.go:walkUnsafeSlice
+func unsafeslice(et *_type, ptr unsafe.Pointer, len int) {
+	if len < 0 {
+		panicunsafeslicelen()
+	}
+
+	if et.size == 0 {
+		if ptr == nil && len > 0 {
+			panicunsafeslicenilptr()
+		}
+	}
+
+	mem, overflow := math.MulUintptr(et.size, uintptr(len))
+	if overflow || mem > -uintptr(ptr) {
+		if ptr == nil {
+			panicunsafeslicenilptr()
+		}
+		panicunsafeslicelen()
+	}
+}
+
+// Keep this code in sync with cmd/compile/internal/walk/builtin.go:walkUnsafeSlice
+func unsafeslice64(et *_type, ptr unsafe.Pointer, len64 int64) {
+	len := int(len64)
+	if int64(len) != len64 {
+		panicunsafeslicelen()
+	}
+	unsafeslice(et, ptr, len)
+}
+
+func unsafeslicecheckptr(et *_type, ptr unsafe.Pointer, len64 int64) {
+	unsafeslice64(et, ptr, len64)
+
+	// Check that underlying array doesn't straddle multiple heap objects.
+	// unsafeslice64 has already checked for overflow.
+	if checkptrStraddles(ptr, uintptr(len64)*et.size) {
+		throw("checkptr: unsafe.Slice result straddles multiple allocations")
+	}
+}
+
+func panicunsafeslicelen() {
+	panic(errorString("unsafe.Slice: len out of range"))
+}
+
+func panicunsafeslicenilptr() {
+	panic(errorString("unsafe.Slice: ptr is nil and len is not zero"))
+}
diff --git a/src/runtime/vdso_freebsd_arm64.go b/src/runtime/vdso_freebsd_arm64.go
index 7d9f62d..37b26d7 100644
--- a/src/runtime/vdso_freebsd_arm64.go
+++ b/src/runtime/vdso_freebsd_arm64.go
@@ -14,7 +14,7 @@
 func (th *vdsoTimehands) getTimecounter() (uint32, bool) {
 	switch th.algo {
 	case _VDSO_TH_ALGO_ARM_GENTIM:
-		return getCntxct(false), true
+		return getCntxct(th.physical != 0), true
 	default:
 		return 0, false
 	}
diff --git a/src/runtime/vdso_freebsd_riscv64.go b/src/runtime/vdso_freebsd_riscv64.go
new file mode 100644
index 0000000..a4fff4b
--- /dev/null
+++ b/src/runtime/vdso_freebsd_riscv64.go
@@ -0,0 +1,21 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+const (
+	_VDSO_TH_ALGO_RISCV_RDTIME = 1
+)
+
+func getCntxct() uint32
+
+//go:nosplit
+func (th *vdsoTimehands) getTimecounter() (uint32, bool) {
+	switch th.algo {
+	case _VDSO_TH_ALGO_RISCV_RDTIME:
+		return getCntxct(), true
+	default:
+		return 0, false
+	}
+}
diff --git a/src/runtime/vdso_freebsd_x86.go b/src/runtime/vdso_freebsd_x86.go
index 5324a3d..66d1c65 100644
--- a/src/runtime/vdso_freebsd_x86.go
+++ b/src/runtime/vdso_freebsd_x86.go
@@ -34,10 +34,8 @@
 	return uint32(tsc)
 }
 
-//go:systemstack
+//go:nosplit
 func (th *vdsoTimehands) getHPETTimecounter() (uint32, bool) {
-	const digits = "0123456789"
-
 	idx := int(th.x86_hpet_idx)
 	if idx >= len(hpetDevMap) {
 		return 0, false
@@ -45,25 +43,7 @@
 
 	p := atomic.Loaduintptr(&hpetDevMap[idx])
 	if p == 0 {
-		var devPath [len(hpetDevPath)]byte
-		copy(devPath[:], hpetDevPath)
-		devPath[9] = digits[idx]
-
-		fd := open(&devPath[0], 0 /* O_RDONLY */, 0)
-		if fd < 0 {
-			atomic.Casuintptr(&hpetDevMap[idx], 0, ^uintptr(0))
-			return 0, false
-		}
-
-		addr, mmapErr := mmap(nil, physPageSize, _PROT_READ, _MAP_SHARED, fd, 0)
-		closefd(fd)
-		newP := uintptr(addr)
-		if mmapErr != 0 {
-			newP = ^uintptr(0)
-		}
-		if !atomic.Casuintptr(&hpetDevMap[idx], 0, newP) && mmapErr == 0 {
-			munmap(addr, physPageSize)
-		}
+		systemstack(func() { initHPETTimecounter(idx) })
 		p = atomic.Loaduintptr(&hpetDevMap[idx])
 	}
 	if p == ^uintptr(0) {
@@ -72,20 +52,38 @@
 	return *(*uint32)(unsafe.Pointer(p + _HPET_MAIN_COUNTER)), true
 }
 
+//go:systemstack
+func initHPETTimecounter(idx int) {
+	const digits = "0123456789"
+
+	var devPath [len(hpetDevPath)]byte
+	copy(devPath[:], hpetDevPath)
+	devPath[9] = digits[idx]
+
+	fd := open(&devPath[0], 0 /* O_RDONLY */ |_O_CLOEXEC, 0)
+	if fd < 0 {
+		atomic.Casuintptr(&hpetDevMap[idx], 0, ^uintptr(0))
+		return
+	}
+
+	addr, mmapErr := mmap(nil, physPageSize, _PROT_READ, _MAP_SHARED, fd, 0)
+	closefd(fd)
+	newP := uintptr(addr)
+	if mmapErr != 0 {
+		newP = ^uintptr(0)
+	}
+	if !atomic.Casuintptr(&hpetDevMap[idx], 0, newP) && mmapErr == 0 {
+		munmap(addr, physPageSize)
+	}
+}
+
 //go:nosplit
 func (th *vdsoTimehands) getTimecounter() (uint32, bool) {
 	switch th.algo {
 	case _VDSO_TH_ALGO_X86_TSC:
 		return th.getTSCTimecounter(), true
 	case _VDSO_TH_ALGO_X86_HPET:
-		var (
-			tc uint32
-			ok bool
-		)
-		systemstack(func() {
-			tc, ok = th.getHPETTimecounter()
-		})
-		return tc, ok
+		return th.getHPETTimecounter()
 	default:
 		return 0, false
 	}
diff --git a/src/runtime/wincallback.go b/src/runtime/wincallback.go
index 442a984..9ec2027 100644
--- a/src/runtime/wincallback.go
+++ b/src/runtime/wincallback.go
@@ -62,7 +62,7 @@
 TEXT runtime·callbackasm(SB),NOSPLIT|NOFRAME,$0
 `)
 	for i := 0; i < maxCallback; i++ {
-		buf.WriteString(fmt.Sprintf("\tMOVW\t$%d, R12\n", i))
+		fmt.Fprintf(&buf, "\tMOVW\t$%d, R12\n", i)
 		buf.WriteString("\tB\truntime·callbackasm1(SB)\n")
 	}
 
@@ -90,7 +90,7 @@
 TEXT runtime·callbackasm(SB),NOSPLIT|NOFRAME,$0
 `)
 	for i := 0; i < maxCallback; i++ {
-		buf.WriteString(fmt.Sprintf("\tMOVD\t$%d, R12\n", i))
+		fmt.Fprintf(&buf, "\tMOVD\t$%d, R12\n", i)
 		buf.WriteString("\tB\truntime·callbackasm1(SB)\n")
 	}
 
@@ -104,12 +104,12 @@
 func gengo() {
 	var buf bytes.Buffer
 
-	buf.WriteString(fmt.Sprintf(`// Code generated by wincallback.go using 'go generate'. DO NOT EDIT.
+	fmt.Fprintf(&buf, `// Code generated by wincallback.go using 'go generate'. DO NOT EDIT.
 
 package runtime
 
 const cb_max = %d // maximum number of windows callbacks allowed
-`, maxCallback))
+`, maxCallback)
 	err := os.WriteFile("zcallback_windows.go", buf.Bytes(), 0666)
 	if err != nil {
 		fmt.Fprintf(os.Stderr, "wincallback: %s\n", err)
diff --git a/src/sort/slice.go b/src/sort/slice.go
index 443182b..d0b2102 100644
--- a/src/sort/slice.go
+++ b/src/sort/slice.go
@@ -4,7 +4,10 @@
 
 package sort
 
-import "math/bits"
+import (
+	"internal/reflectlite"
+	"math/bits"
+)
 
 // Slice sorts the slice x given the provided less function.
 // It panics if x is not a slice.
@@ -16,8 +19,8 @@
 // The less function must satisfy the same requirements as
 // the Interface type's Less method.
 func Slice(x any, less func(i, j int) bool) {
-	rv := reflectValueOf(x)
-	swap := reflectSwapper(x)
+	rv := reflectlite.ValueOf(x)
+	swap := reflectlite.Swapper(x)
 	length := rv.Len()
 	limit := bits.Len(uint(length))
 	pdqsort_func(lessSwap{less, swap}, 0, length, limit)
@@ -30,15 +33,15 @@
 // The less function must satisfy the same requirements as
 // the Interface type's Less method.
 func SliceStable(x any, less func(i, j int) bool) {
-	rv := reflectValueOf(x)
-	swap := reflectSwapper(x)
+	rv := reflectlite.ValueOf(x)
+	swap := reflectlite.Swapper(x)
 	stable_func(lessSwap{less, swap}, rv.Len())
 }
 
 // SliceIsSorted reports whether the slice x is sorted according to the provided less function.
 // It panics if x is not a slice.
 func SliceIsSorted(x any, less func(i, j int) bool) bool {
-	rv := reflectValueOf(x)
+	rv := reflectlite.ValueOf(x)
 	n := rv.Len()
 	for i := n - 1; i > 0; i-- {
 		if less(i, i-1) {
diff --git a/src/sort/slice_go113.go b/src/sort/slice_go113.go
deleted file mode 100644
index 53542db..0000000
--- a/src/sort/slice_go113.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build go1.13
-// +build go1.13
-
-package sort
-
-import "internal/reflectlite"
-
-var reflectValueOf = reflectlite.ValueOf
-var reflectSwapper = reflectlite.Swapper
diff --git a/src/sort/slice_go14.go b/src/sort/slice_go14.go
deleted file mode 100644
index e477367..0000000
--- a/src/sort/slice_go14.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build !go1.8
-// +build !go1.8
-
-package sort
-
-import "reflect"
-
-var reflectValueOf = reflect.ValueOf
-
-func reflectSwapper(x any) func(int, int) {
-	v := reflectValueOf(x)
-	tmp := reflect.New(v.Type().Elem()).Elem()
-	return func(i, j int) {
-		a, b := v.Index(i), v.Index(j)
-		tmp.Set(a)
-		a.Set(b)
-		b.Set(tmp)
-	}
-}
diff --git a/src/sort/slice_go18.go b/src/sort/slice_go18.go
deleted file mode 100644
index 1538477..0000000
--- a/src/sort/slice_go18.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build go1.8 && !go1.13
-// +build go1.8,!go1.13
-
-package sort
-
-import "reflect"
-
-var reflectValueOf = reflect.ValueOf
-var reflectSwapper = reflect.Swapper
diff --git a/src/strconv/atoc.go b/src/strconv/atoc.go
index 85c7baf..f6fdd14 100644
--- a/src/strconv/atoc.go
+++ b/src/strconv/atoc.go
@@ -11,7 +11,7 @@
 func convErr(err error, s string) (syntax, range_ error) {
 	if x, ok := err.(*NumError); ok {
 		x.Func = fnParseComplex
-		x.Num = s
+		x.Num = cloneString(s)
 		if x.Err == ErrRange {
 			return nil, x
 		}
diff --git a/src/strconv/atof_test.go b/src/strconv/atof_test.go
index aa587a4..7b287b4 100644
--- a/src/strconv/atof_test.go
+++ b/src/strconv/atof_test.go
@@ -12,7 +12,6 @@
 	"strings"
 	"sync"
 	"testing"
-	"time"
 )
 
 type atofTest struct {
@@ -463,7 +462,6 @@
 	}
 
 	// Generate random inputs for tests and benchmarks
-	rand.Seed(time.Now().UnixNano())
 	if testing.Short() {
 		atofRandomTests = make([]atofSimpleTest, 100)
 	} else {
diff --git a/src/strconv/atoi.go b/src/strconv/atoi.go
index be08f93..520d826 100644
--- a/src/strconv/atoi.go
+++ b/src/strconv/atoi.go
@@ -33,20 +33,36 @@
 
 func (e *NumError) Unwrap() error { return e.Err }
 
+// cloneString returns a string copy of x.
+//
+// All ParseXXX functions allow the input string to escape to the error value.
+// This hurts strconv.ParseXXX(string(b)) calls where b is []byte since
+// the conversion from []byte must allocate a string on the heap.
+// If we assume errors are infrequent, then we can avoid escaping the input
+// back to the output by copying it first. This allows the compiler to call
+// strconv.ParseXXX without a heap allocation for most []byte to string
+// conversions, since it can now prove that the string cannot escape Parse.
+//
+// TODO: Use strings.Clone instead? However, we cannot depend on "strings"
+// since it incurs a transitive dependency on "unicode".
+// Either move strings.Clone to an internal/bytealg or make the
+// "strings" to "unicode" dependency lighter (see https://go.dev/issue/54098).
+func cloneString(x string) string { return string([]byte(x)) }
+
 func syntaxError(fn, str string) *NumError {
-	return &NumError{fn, str, ErrSyntax}
+	return &NumError{fn, cloneString(str), ErrSyntax}
 }
 
 func rangeError(fn, str string) *NumError {
-	return &NumError{fn, str, ErrRange}
+	return &NumError{fn, cloneString(str), ErrRange}
 }
 
 func baseError(fn, str string, base int) *NumError {
-	return &NumError{fn, str, errors.New("invalid base " + Itoa(base))}
+	return &NumError{fn, cloneString(str), errors.New("invalid base " + Itoa(base))}
 }
 
 func bitSizeError(fn, str string, bitSize int) *NumError {
-	return &NumError{fn, str, errors.New("invalid bit size " + Itoa(bitSize))}
+	return &NumError{fn, cloneString(str), errors.New("invalid bit size " + Itoa(bitSize))}
 }
 
 const intSize = 32 << (^uint(0) >> 63)
@@ -205,7 +221,7 @@
 	un, err = ParseUint(s, base, bitSize)
 	if err != nil && err.(*NumError).Err != ErrRange {
 		err.(*NumError).Func = fnParseInt
-		err.(*NumError).Num = s0
+		err.(*NumError).Num = cloneString(s0)
 		return 0, err
 	}
 
@@ -239,7 +255,7 @@
 		if s[0] == '-' || s[0] == '+' {
 			s = s[1:]
 			if len(s) < 1 {
-				return 0, &NumError{fnAtoi, s0, ErrSyntax}
+				return 0, syntaxError(fnAtoi, s0)
 			}
 		}
 
@@ -247,7 +263,7 @@
 		for _, ch := range []byte(s) {
 			ch -= '0'
 			if ch > 9 {
-				return 0, &NumError{fnAtoi, s0, ErrSyntax}
+				return 0, syntaxError(fnAtoi, s0)
 			}
 			n = n*10 + int(ch)
 		}
diff --git a/src/strconv/ftoa.go b/src/strconv/ftoa.go
index f602d0f..fcbf4df 100644
--- a/src/strconv/ftoa.go
+++ b/src/strconv/ftoa.go
@@ -373,7 +373,6 @@
 type decimalSlice struct {
 	d      []byte
 	nd, dp int
-	neg    bool
 }
 
 // %e: -d.ddddde±dd
diff --git a/src/strconv/ftoaryu.go b/src/strconv/ftoaryu.go
index b975cdc..2e7bf71 100644
--- a/src/strconv/ftoaryu.go
+++ b/src/strconv/ftoaryu.go
@@ -33,7 +33,7 @@
 	e2 := exp
 	if b := bits.Len32(mant); b < 25 {
 		mant <<= uint(25 - b)
-		e2 += int(b) - 25
+		e2 += b - 25
 	}
 	// Choose an exponent such that rounded mant*(2^e2)*(10^q) has
 	// at least prec decimal digits, i.e
@@ -100,7 +100,7 @@
 	e2 := exp
 	if b := bits.Len64(mant); b < 55 {
 		mant = mant << uint(55-b)
-		e2 += int(b) - 55
+		e2 += b - 55
 	}
 	// Choose an exponent such that rounded mant*(2^e2)*(10^q) has
 	// at least prec decimal digits, i.e
@@ -194,7 +194,7 @@
 	}
 	// render digits (similar to formatBits)
 	n := uint(prec)
-	d.nd = int(prec)
+	d.nd = prec
 	v := m
 	for v >= 100 {
 		var v1, v2 uint64
diff --git a/src/strconv/itoa_test.go b/src/strconv/itoa_test.go
index b5ee3aa..b8bc524 100644
--- a/src/strconv/itoa_test.go
+++ b/src/strconv/itoa_test.go
@@ -93,6 +93,14 @@
 			}
 		}
 	}
+
+	// Override when base is illegal
+	defer func() {
+		if r := recover(); r == nil {
+			t.Fatalf("expected panic due to illegal base")
+		}
+	}()
+	FormatUint(12345678, 1)
 }
 
 type uitob64Test struct {
diff --git a/src/strconv/strconv_test.go b/src/strconv/strconv_test.go
index d3c1e95..41b8fa7 100644
--- a/src/strconv/strconv_test.go
+++ b/src/strconv/strconv_test.go
@@ -66,6 +66,68 @@
 	}
 }
 
+// Sink makes sure the compiler cannot optimize away the benchmarks.
+var Sink struct {
+	Bool       bool
+	Int        int
+	Int64      int64
+	Uint64     uint64
+	Float64    float64
+	Complex128 complex128
+	Error      error
+	Bytes      []byte
+}
+
+func TestAllocationsFromBytes(t *testing.T) {
+	const runsPerTest = 100
+	bytes := struct{ Bool, Number, String, Buffer []byte }{
+		Bool:   []byte("false"),
+		Number: []byte("123456789"),
+		String: []byte("hello, world!"),
+		Buffer: make([]byte, 1024),
+	}
+
+	checkNoAllocs := func(f func()) func(t *testing.T) {
+		return func(t *testing.T) {
+			t.Helper()
+			if allocs := testing.AllocsPerRun(runsPerTest, f); allocs != 0 {
+				t.Errorf("got %v allocs, want 0 allocs", allocs)
+			}
+		}
+	}
+
+	t.Run("Atoi", checkNoAllocs(func() {
+		Sink.Int, Sink.Error = Atoi(string(bytes.Number))
+	}))
+	t.Run("ParseBool", checkNoAllocs(func() {
+		Sink.Bool, Sink.Error = ParseBool(string(bytes.Bool))
+	}))
+	t.Run("ParseInt", checkNoAllocs(func() {
+		Sink.Int64, Sink.Error = ParseInt(string(bytes.Number), 10, 64)
+	}))
+	t.Run("ParseUint", checkNoAllocs(func() {
+		Sink.Uint64, Sink.Error = ParseUint(string(bytes.Number), 10, 64)
+	}))
+	t.Run("ParseFloat", checkNoAllocs(func() {
+		Sink.Float64, Sink.Error = ParseFloat(string(bytes.Number), 64)
+	}))
+	t.Run("ParseComplex", checkNoAllocs(func() {
+		Sink.Complex128, Sink.Error = ParseComplex(string(bytes.Number), 128)
+	}))
+	t.Run("CanBackquote", checkNoAllocs(func() {
+		Sink.Bool = CanBackquote(string(bytes.String))
+	}))
+	t.Run("AppendQuote", checkNoAllocs(func() {
+		Sink.Bytes = AppendQuote(bytes.Buffer[:0], string(bytes.String))
+	}))
+	t.Run("AppendQuoteToASCII", checkNoAllocs(func() {
+		Sink.Bytes = AppendQuoteToASCII(bytes.Buffer[:0], string(bytes.String))
+	}))
+	t.Run("AppendQuoteToGraphic", checkNoAllocs(func() {
+		Sink.Bytes = AppendQuoteToGraphic(bytes.Buffer[:0], string(bytes.String))
+	}))
+}
+
 func TestErrorPrefixes(t *testing.T) {
 	_, errInt := Atoi("INVALID")
 	_, errBool := ParseBool("INVALID")
diff --git a/src/strings/builder.go b/src/strings/builder.go
index 3caddab..7710464 100644
--- a/src/strings/builder.go
+++ b/src/strings/builder.go
@@ -45,7 +45,7 @@
 
 // String returns the accumulated string.
 func (b *Builder) String() string {
-	return *(*string)(unsafe.Pointer(&b.buf))
+	return unsafe.String(unsafe.SliceData(b.buf), len(b.buf))
 }
 
 // Len returns the number of accumulated bytes; b.Len() == len(b.String()).
@@ -103,18 +103,9 @@
 // It returns the length of r and a nil error.
 func (b *Builder) WriteRune(r rune) (int, error) {
 	b.copyCheck()
-	// Compare as uint32 to correctly handle negative runes.
-	if uint32(r) < utf8.RuneSelf {
-		b.buf = append(b.buf, byte(r))
-		return 1, nil
-	}
-	l := len(b.buf)
-	if cap(b.buf)-l < utf8.UTFMax {
-		b.grow(utf8.UTFMax)
-	}
-	n := utf8.EncodeRune(b.buf[l:l+utf8.UTFMax], r)
-	b.buf = b.buf[:l+n]
-	return n, nil
+	n := len(b.buf)
+	b.buf = utf8.AppendRune(b.buf, r)
+	return len(b.buf) - n, nil
 }
 
 // WriteString appends the contents of s to b's buffer.
diff --git a/src/strings/builder_test.go b/src/strings/builder_test.go
index e3d2392..dbc2c19 100644
--- a/src/strings/builder_test.go
+++ b/src/strings/builder_test.go
@@ -109,6 +109,15 @@
 			t.Errorf("growLen=%d: got %d allocs during Write; want %v", growLen, g, w)
 		}
 	}
+	// when growLen < 0, should panic
+	var a Builder
+	n := -1
+	defer func() {
+		if r := recover(); r == nil {
+			t.Errorf("a.Grow(%d) should panic()", n)
+		}
+	}()
+	a.Grow(n)
 }
 
 func TestBuilderWrite2(t *testing.T) {
diff --git a/src/strings/clone.go b/src/strings/clone.go
index edd1497..d14df11 100644
--- a/src/strings/clone.go
+++ b/src/strings/clone.go
@@ -24,5 +24,5 @@
 	}
 	b := make([]byte, len(s))
 	copy(b, s)
-	return *(*string)(unsafe.Pointer(&b))
+	return unsafe.String(&b[0], len(b))
 }
diff --git a/src/strings/clone_test.go b/src/strings/clone_test.go
index a9ba8ad..64f2760 100644
--- a/src/strings/clone_test.go
+++ b/src/strings/clone_test.go
@@ -1,11 +1,10 @@
 // Copyright 2021 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.ß
+// license that can be found in the LICENSE file.
 
 package strings_test
 
 import (
-	"reflect"
 	"strings"
 	"testing"
 	"unsafe"
@@ -27,15 +26,12 @@
 			t.Errorf("Clone(%q) = %q; want %q", input, clone, input)
 		}
 
-		inputHeader := (*reflect.StringHeader)(unsafe.Pointer(&input))
-		cloneHeader := (*reflect.StringHeader)(unsafe.Pointer(&clone))
-		if len(input) != 0 && cloneHeader.Data == inputHeader.Data {
+		if len(input) != 0 && unsafe.StringData(clone) == unsafe.StringData(input) {
 			t.Errorf("Clone(%q) return value should not reference inputs backing memory.", input)
 		}
 
-		emptyHeader := (*reflect.StringHeader)(unsafe.Pointer(&emptyString))
-		if len(input) == 0 && cloneHeader.Data != emptyHeader.Data {
-			t.Errorf("Clone(%#v) return value should be equal to empty string.", inputHeader)
+		if len(input) == 0 && unsafe.StringData(clone) != unsafe.StringData(emptyString) {
+			t.Errorf("Clone(%#v) return value should be equal to empty string.", unsafe.StringData(input))
 		}
 	}
 }
diff --git a/src/strings/compare_test.go b/src/strings/compare_test.go
index 94554e0..a435784 100644
--- a/src/strings/compare_test.go
+++ b/src/strings/compare_test.go
@@ -57,7 +57,7 @@
 	// unsafeString converts a []byte to a string with no allocation.
 	// The caller must not modify b while the result string is in use.
 	unsafeString := func(b []byte) string {
-		return *(*string)(unsafe.Pointer(&b))
+		return unsafe.String(unsafe.SliceData(b), len(b))
 	}
 
 	lengths := make([]int, 0) // lengths to test in ascending order
diff --git a/src/strings/replace.go b/src/strings/replace.go
index 73bc78a..f504fb4 100644
--- a/src/strings/replace.go
+++ b/src/strings/replace.go
@@ -455,21 +455,30 @@
 }
 
 func (r *byteReplacer) WriteString(w io.Writer, s string) (n int, err error) {
-	// TODO(bradfitz): use io.WriteString with slices of s, avoiding allocation.
-	bufsize := 32 << 10
-	if len(s) < bufsize {
-		bufsize = len(s)
-	}
-	buf := make([]byte, bufsize)
-
-	for len(s) > 0 {
-		ncopy := copy(buf, s)
-		s = s[ncopy:]
-		for i, b := range buf[:ncopy] {
-			buf[i] = r[b]
+	sw := getStringWriter(w)
+	last := 0
+	for i := 0; i < len(s); i++ {
+		b := s[i]
+		if r[b] == b {
+			continue
 		}
-		wn, err := w.Write(buf[:ncopy])
-		n += wn
+		if last != i {
+			wn, err := sw.WriteString(s[last:i])
+			n += wn
+			if err != nil {
+				return n, err
+			}
+		}
+		last = i + 1
+		nw, err := w.Write(r[b : int(b)+1])
+		n += nw
+		if err != nil {
+			return n, err
+		}
+	}
+	if last != len(s) {
+		nw, err := sw.WriteString(s[last:])
+		n += nw
 		if err != nil {
 			return n, err
 		}
diff --git a/src/strings/strings.go b/src/strings/strings.go
index 1dc4238..646161f 100644
--- a/src/strings/strings.go
+++ b/src/strings/strings.go
@@ -15,7 +15,7 @@
 
 // explode splits s into a slice of UTF-8 strings,
 // one string per Unicode character up to a maximum of n (n < 0 means no limit).
-// Invalid UTF-8 sequences become correct encodings of U+FFFD.
+// Invalid UTF-8 bytes are sliced individually.
 func explode(s string, n int) []string {
 	l := utf8.RuneCountInString(s)
 	if n < 0 || n > l {
@@ -23,12 +23,9 @@
 	}
 	a := make([]string, n)
 	for i := 0; i < n-1; i++ {
-		ch, size := utf8.DecodeRuneInString(s)
+		_, size := utf8.DecodeRuneInString(s)
 		a[i] = s[:size]
 		s = s[size:]
-		if ch == utf8.RuneError {
-			a[i] = string(utf8.RuneError)
-		}
 	}
 	if n > 0 {
 		a[n-1] = s
@@ -523,34 +520,63 @@
 
 // Repeat returns a new string consisting of count copies of the string s.
 //
-// It panics if count is negative or if
-// the result of (len(s) * count) overflows.
+// It panics if count is negative or if the result of (len(s) * count)
+// overflows.
 func Repeat(s string, count int) string {
-	if count == 0 {
+	switch count {
+	case 0:
 		return ""
+	case 1:
+		return s
 	}
 
 	// Since we cannot return an error on overflow,
 	// we should panic if the repeat will generate
 	// an overflow.
-	// See Issue golang.org/issue/16237
+	// See golang.org/issue/16237.
 	if count < 0 {
 		panic("strings: negative Repeat count")
 	} else if len(s)*count/count != len(s) {
 		panic("strings: Repeat count causes overflow")
 	}
 
+	if len(s) == 0 {
+		return ""
+	}
+
 	n := len(s) * count
+
+	// Past a certain chunk size it is counterproductive to use
+	// larger chunks as the source of the write, as when the source
+	// is too large we are basically just thrashing the CPU D-cache.
+	// So if the result length is larger than an empirically-found
+	// limit (8KB), we stop growing the source string once the limit
+	// is reached and keep reusing the same source string - that
+	// should therefore be always resident in the L1 cache - until we
+	// have completed the construction of the result.
+	// This yields significant speedups (up to +100%) in cases where
+	// the result length is large (roughly, over L2 cache size).
+	const chunkLimit = 8 * 1024
+	chunkMax := n
+	if n > chunkLimit {
+		chunkMax = chunkLimit / len(s) * len(s)
+		if chunkMax == 0 {
+			chunkMax = len(s)
+		}
+	}
+
 	var b Builder
 	b.Grow(n)
 	b.WriteString(s)
 	for b.Len() < n {
-		if b.Len() <= n/2 {
-			b.WriteString(b.String())
-		} else {
-			b.WriteString(b.String()[:n-b.Len()])
-			break
+		chunk := n - b.Len()
+		if chunk > b.Len() {
+			chunk = b.Len()
 		}
+		if chunk > chunkMax {
+			chunk = chunkMax
+		}
+		b.WriteString(b.String()[:chunk])
 	}
 	return b.String()
 }
@@ -571,14 +597,24 @@
 		if !hasLower {
 			return s
 		}
-		var b Builder
+		var (
+			b   Builder
+			pos int
+		)
 		b.Grow(len(s))
 		for i := 0; i < len(s); i++ {
 			c := s[i]
 			if 'a' <= c && c <= 'z' {
 				c -= 'a' - 'A'
+				if pos < i {
+					b.WriteString(s[pos:i])
+				}
+				b.WriteByte(c)
+				pos = i + 1
 			}
-			b.WriteByte(c)
+		}
+		if pos < len(s) {
+			b.WriteString(s[pos:])
 		}
 		return b.String()
 	}
@@ -601,14 +637,24 @@
 		if !hasUpper {
 			return s
 		}
-		var b Builder
+		var (
+			b   Builder
+			pos int
+		)
 		b.Grow(len(s))
 		for i := 0; i < len(s); i++ {
 			c := s[i]
 			if 'A' <= c && c <= 'Z' {
 				c += 'a' - 'A'
+				if pos < i {
+					b.WriteString(s[pos:i])
+				}
+				b.WriteByte(c)
+				pos = i + 1
 			}
-			b.WriteByte(c)
+		}
+		if pos < len(s) {
+			b.WriteString(s[pos:])
 		}
 		return b.String()
 	}
@@ -1047,15 +1093,44 @@
 // are equal under simple Unicode case-folding, which is a more general
 // form of case-insensitivity.
 func EqualFold(s, t string) bool {
-	for s != "" && t != "" {
-		// Extract first rune from each string.
-		var sr, tr rune
-		if s[0] < utf8.RuneSelf {
-			sr, s = rune(s[0]), s[1:]
-		} else {
-			r, size := utf8.DecodeRuneInString(s)
-			sr, s = r, s[size:]
+	// ASCII fast path
+	i := 0
+	for ; i < len(s) && i < len(t); i++ {
+		sr := s[i]
+		tr := t[i]
+		if sr|tr >= utf8.RuneSelf {
+			goto hasUnicode
 		}
+
+		// Easy case.
+		if tr == sr {
+			continue
+		}
+
+		// Make sr < tr to simplify what follows.
+		if tr < sr {
+			tr, sr = sr, tr
+		}
+		// ASCII only, sr/tr must be upper/lower case
+		if 'A' <= sr && sr <= 'Z' && tr == sr+'a'-'A' {
+			continue
+		}
+		return false
+	}
+	// Check if we've exhausted both strings.
+	return len(s) == len(t)
+
+hasUnicode:
+	s = s[i:]
+	t = t[i:]
+	for _, sr := range s {
+		// If t is exhausted the strings are not equal.
+		if len(t) == 0 {
+			return false
+		}
+
+		// Extract first rune from second string.
+		var tr rune
 		if t[0] < utf8.RuneSelf {
 			tr, t = rune(t[0]), t[1:]
 		} else {
@@ -1095,8 +1170,8 @@
 		return false
 	}
 
-	// One string is empty. Are both?
-	return s == t
+	// First string is empty, so check if the second one is also empty.
+	return len(t) == 0
 }
 
 // Index returns the index of the first instance of substr in s, or -1 if substr is not present in s.
@@ -1190,3 +1265,25 @@
 	}
 	return s, "", false
 }
+
+// CutPrefix returns s without the provided leading prefix string
+// and reports whether it found the prefix.
+// If s doesn't start with prefix, CutPrefix returns s, false.
+// If prefix is the empty string, CutPrefix returns s, true.
+func CutPrefix(s, prefix string) (after string, found bool) {
+	if !HasPrefix(s, prefix) {
+		return s, false
+	}
+	return s[len(prefix):], true
+}
+
+// CutSuffix returns s without the provided ending suffix string
+// and reports whether it found the suffix.
+// If s doesn't end with suffix, CutSuffix returns s, false.
+// If suffix is the empty string, CutSuffix returns s, true.
+func CutSuffix(s, suffix string) (before string, found bool) {
+	if !HasSuffix(s, suffix) {
+		return s, false
+	}
+	return s[:len(s)-len(suffix)], true
+}
diff --git a/src/strings/strings_test.go b/src/strings/strings_test.go
index 9e7fb85..3991d12 100644
--- a/src/strings/strings_test.go
+++ b/src/strings/strings_test.go
@@ -54,6 +54,11 @@
 	{"foo", "", 0},
 	{"foo", "o", 1},
 	{"abcABCabc", "A", 3},
+	{"jrzm6jjhorimglljrea4w3rlgosts0w2gia17hno2td4qd1jz", "jz", 47},
+	{"ekkuk5oft4eq0ocpacknhwouic1uua46unx12l37nioq9wbpnocqks6", "ks6", 52},
+	{"999f2xmimunbuyew5vrkla9cpwhmxan8o98ec", "98ec", 33},
+	{"9lpt9r98i04k8bz6c6dsrthb96bhi", "96bhi", 24},
+	{"55u558eqfaod2r2gu42xxsu631xf0zobs5840vl", "5840vl", 33},
 	// cases with one byte strings - test special case in Index()
 	{"", "a", -1},
 	{"x", "a", -1},
@@ -406,6 +411,8 @@
 	{"1 2 3 4", " ", 3, []string{"1", "2", "3 4"}},
 	{"1 2", " ", 3, []string{"1", "2"}},
 	{"", "T", math.MaxInt / 4, []string{""}},
+	{"\xff-\xff", "", -1, []string{"\xff", "-", "\xff"}},
+	{"\xff-\xff", "-", -1, []string{"\xff", "\xff"}},
 }
 
 func TestSplit(t *testing.T) {
@@ -547,6 +554,7 @@
 	{"AbC123", "ABC123"},
 	{"azAZ09_", "AZAZ09_"},
 	{"longStrinGwitHmixofsmaLLandcAps", "LONGSTRINGWITHMIXOFSMALLANDCAPS"},
+	{"RENAN BASTOS 93 AOSDAJDJAIDJAIDAJIaidsjjaidijadsjiadjiOOKKO", "RENAN BASTOS 93 AOSDAJDJAIDJAIDAJIAIDSJJAIDIJADSJIADJIOOKKO"},
 	{"long\u0250string\u0250with\u0250nonascii\u2C6Fchars", "LONG\u2C6FSTRING\u2C6FWITH\u2C6FNONASCII\u2C6FCHARS"},
 	{"\u0250\u0250\u0250\u0250\u0250", "\u2C6F\u2C6F\u2C6F\u2C6F\u2C6F"}, // grows one byte per char
 	{"a\u0080\U0010FFFF", "A\u0080\U0010FFFF"},                           // test utf8.RuneSelf and utf8.MaxRune
@@ -558,6 +566,7 @@
 	{"AbC123", "abc123"},
 	{"azAZ09_", "azaz09_"},
 	{"longStrinGwitHmixofsmaLLandcAps", "longstringwithmixofsmallandcaps"},
+	{"renan bastos 93 AOSDAJDJAIDJAIDAJIaidsjjaidijadsjiadjiOOKKO", "renan bastos 93 aosdajdjaidjaidajiaidsjjaidijadsjiadjiookko"},
 	{"LONG\u2C6FSTRING\u2C6FWITH\u2C6FNONASCII\u2C6FCHARS", "long\u0250string\u0250with\u0250nonascii\u0250chars"},
 	{"\u2C6D\u2C6D\u2C6D\u2C6D\u2C6D", "\u0251\u0251\u0251\u0251\u0251"}, // shrinks one byte per char
 	{"A\u0080\U0010FFFF", "a\u0080\U0010FFFF"},                           // test utf8.RuneSelf and utf8.MaxRune
@@ -656,8 +665,7 @@
 	}
 	orig := "Input string that we expect not to be copied."
 	m = Map(identity, orig)
-	if (*reflect.StringHeader)(unsafe.Pointer(&orig)).Data !=
-		(*reflect.StringHeader)(unsafe.Pointer(&m)).Data {
+	if unsafe.StringData(orig) != unsafe.StringData(m) {
 		t.Error("unexpected copy during identity map")
 	}
 
@@ -1102,6 +1110,8 @@
 	*/
 }
 
+var longString = "a" + string(make([]byte, 1<<16)) + "z"
+
 var RepeatTests = []struct {
 	in, out string
 	count   int
@@ -1113,6 +1123,9 @@
 	{"-", "-", 1},
 	{"-", "----------", 10},
 	{"abc ", "abc abc abc ", 3},
+	// Tests for results over the chunkLimit
+	{string(rune(0)), string(make([]byte, 1<<16)), 1 << 16},
+	{longString, longString + longString, 2},
 }
 
 func TestRepeat(t *testing.T) {
@@ -1553,13 +1566,36 @@
 }
 
 func BenchmarkEqualFold(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		for _, tt := range EqualFoldTests {
-			if out := EqualFold(tt.s, tt.t); out != tt.out {
-				b.Fatal("wrong result")
+	b.Run("Tests", func(b *testing.B) {
+		for i := 0; i < b.N; i++ {
+			for _, tt := range EqualFoldTests {
+				if out := EqualFold(tt.s, tt.t); out != tt.out {
+					b.Fatal("wrong result")
+				}
 			}
 		}
-	}
+	})
+
+	const s1 = "abcdefghijKz"
+	const s2 = "abcDefGhijKz"
+
+	b.Run("ASCII", func(b *testing.B) {
+		for i := 0; i < b.N; i++ {
+			EqualFold(s1, s2)
+		}
+	})
+
+	b.Run("UnicodePrefix", func(b *testing.B) {
+		for i := 0; i < b.N; i++ {
+			EqualFold("αβδ"+s1, "ΑΒΔ"+s2)
+		}
+	})
+
+	b.Run("UnicodeSuffix", func(b *testing.B) {
+		for i := 0; i < b.N; i++ {
+			EqualFold(s1+"αβδ", s2+"ΑΒΔ")
+		}
+	})
 }
 
 var CountTests = []struct {
@@ -1609,6 +1645,48 @@
 	}
 }
 
+var cutPrefixTests = []struct {
+	s, sep string
+	after  string
+	found  bool
+}{
+	{"abc", "a", "bc", true},
+	{"abc", "abc", "", true},
+	{"abc", "", "abc", true},
+	{"abc", "d", "abc", false},
+	{"", "d", "", false},
+	{"", "", "", true},
+}
+
+func TestCutPrefix(t *testing.T) {
+	for _, tt := range cutPrefixTests {
+		if after, found := CutPrefix(tt.s, tt.sep); after != tt.after || found != tt.found {
+			t.Errorf("CutPrefix(%q, %q) = %q, %v, want %q, %v", tt.s, tt.sep, after, found, tt.after, tt.found)
+		}
+	}
+}
+
+var cutSuffixTests = []struct {
+	s, sep string
+	after  string
+	found  bool
+}{
+	{"abc", "bc", "a", true},
+	{"abc", "abc", "", true},
+	{"abc", "", "abc", true},
+	{"abc", "d", "abc", false},
+	{"", "d", "", false},
+	{"", "", "", true},
+}
+
+func TestCutSuffix(t *testing.T) {
+	for _, tt := range cutSuffixTests {
+		if after, found := CutSuffix(tt.s, tt.sep); after != tt.after || found != tt.found {
+			t.Errorf("CutSuffix(%q, %q) = %q, %v, want %q, %v", tt.s, tt.sep, after, found, tt.after, tt.found)
+		}
+	}
+}
+
 func makeBenchInputHard() string {
 	tokens := [...]string{
 		"<a>", "<p>", "<b>", "<strong>",
@@ -1807,7 +1885,7 @@
 func BenchmarkRepeat(b *testing.B) {
 	s := "0123456789"
 	for _, n := range []int{5, 10} {
-		for _, c := range []int{1, 2, 6} {
+		for _, c := range []int{0, 1, 2, 6} {
 			b.Run(fmt.Sprintf("%dx%d", n, c), func(b *testing.B) {
 				for i := 0; i < b.N; i++ {
 					Repeat(s[:n], c)
@@ -1817,6 +1895,25 @@
 	}
 }
 
+func BenchmarkRepeatLarge(b *testing.B) {
+	s := Repeat("@", 8*1024)
+	for j := 8; j <= 30; j++ {
+		for _, k := range []int{1, 16, 4097} {
+			s := s[:k]
+			n := (1 << j) / k
+			if n == 0 {
+				continue
+			}
+			b.Run(fmt.Sprintf("%d/%d", 1<<j, k), func(b *testing.B) {
+				for i := 0; i < b.N; i++ {
+					Repeat(s, n)
+				}
+				b.SetBytes(int64(n * len(s)))
+			})
+		}
+	}
+}
+
 func BenchmarkIndexAnyASCII(b *testing.B) {
 	x := Repeat("#", 2048) // Never matches set
 	cs := "0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz"
diff --git a/src/sync/atomic/atomic_test.go b/src/sync/atomic/atomic_test.go
index 02d55fb..c3604ef 100644
--- a/src/sync/atomic/atomic_test.go
+++ b/src/sync/atomic/atomic_test.go
@@ -32,16 +32,6 @@
 	magic64 = 0xdeddeadbeefbeef
 )
 
-// Do the 64-bit functions panic? If so, don't bother testing.
-var test64err = func() (err any) {
-	defer func() {
-		err = recover()
-	}()
-	var x int64
-	AddInt64(&x, 1)
-	return nil
-}()
-
 func TestSwapInt32(t *testing.T) {
 	var x struct {
 		before int32
@@ -127,9 +117,6 @@
 }
 
 func TestSwapInt64(t *testing.T) {
-	if test64err != nil {
-		t.Skipf("Skipping 64-bit tests: %v", test64err)
-	}
 	var x struct {
 		before int64
 		i      int64
@@ -152,9 +139,6 @@
 }
 
 func TestSwapInt64Method(t *testing.T) {
-	if test64err != nil {
-		t.Skipf("Skipping 64-bit tests: %v", test64err)
-	}
 	var x struct {
 		before int64
 		i      Int64
@@ -177,9 +161,6 @@
 }
 
 func TestSwapUint64(t *testing.T) {
-	if test64err != nil {
-		t.Skipf("Skipping 64-bit tests: %v", test64err)
-	}
 	var x struct {
 		before uint64
 		i      uint64
@@ -202,9 +183,6 @@
 }
 
 func TestSwapUint64Method(t *testing.T) {
-	if test64err != nil {
-		t.Skipf("Skipping 64-bit tests: %v", test64err)
-	}
 	var x struct {
 		before uint64
 		i      Uint64
@@ -420,9 +398,6 @@
 }
 
 func TestAddInt64(t *testing.T) {
-	if test64err != nil {
-		t.Skipf("Skipping 64-bit tests: %v", test64err)
-	}
 	var x struct {
 		before int64
 		i      int64
@@ -445,9 +420,6 @@
 }
 
 func TestAddInt64Method(t *testing.T) {
-	if test64err != nil {
-		t.Skipf("Skipping 64-bit tests: %v", test64err)
-	}
 	var x struct {
 		before int64
 		i      Int64
@@ -470,9 +442,6 @@
 }
 
 func TestAddUint64(t *testing.T) {
-	if test64err != nil {
-		t.Skipf("Skipping 64-bit tests: %v", test64err)
-	}
 	var x struct {
 		before uint64
 		i      uint64
@@ -495,9 +464,6 @@
 }
 
 func TestAddUint64Method(t *testing.T) {
-	if test64err != nil {
-		t.Skipf("Skipping 64-bit tests: %v", test64err)
-	}
 	var x struct {
 		before uint64
 		i      Uint64
@@ -682,9 +648,6 @@
 }
 
 func TestCompareAndSwapInt64(t *testing.T) {
-	if test64err != nil {
-		t.Skipf("Skipping 64-bit tests: %v", test64err)
-	}
 	var x struct {
 		before int64
 		i      int64
@@ -715,9 +678,6 @@
 }
 
 func TestCompareAndSwapInt64Method(t *testing.T) {
-	if test64err != nil {
-		t.Skipf("Skipping 64-bit tests: %v", test64err)
-	}
 	var x struct {
 		before int64
 		i      Int64
@@ -748,9 +708,6 @@
 }
 
 func testCompareAndSwapUint64(t *testing.T, cas func(*uint64, uint64, uint64) bool) {
-	if test64err != nil {
-		t.Skipf("Skipping 64-bit tests: %v", test64err)
-	}
 	var x struct {
 		before uint64
 		i      uint64
@@ -785,9 +742,6 @@
 }
 
 func TestCompareAndSwapUint64Method(t *testing.T) {
-	if test64err != nil {
-		t.Skipf("Skipping 64-bit tests: %v", test64err)
-	}
 	var x struct {
 		before uint64
 		i      Uint64
@@ -1027,9 +981,6 @@
 }
 
 func TestLoadInt64(t *testing.T) {
-	if test64err != nil {
-		t.Skipf("Skipping 64-bit tests: %v", test64err)
-	}
 	var x struct {
 		before int64
 		i      int64
@@ -1051,9 +1002,6 @@
 }
 
 func TestLoadInt64Method(t *testing.T) {
-	if test64err != nil {
-		t.Skipf("Skipping 64-bit tests: %v", test64err)
-	}
 	var x struct {
 		before int64
 		i      Int64
@@ -1077,9 +1025,6 @@
 }
 
 func TestLoadUint64(t *testing.T) {
-	if test64err != nil {
-		t.Skipf("Skipping 64-bit tests: %v", test64err)
-	}
 	var x struct {
 		before uint64
 		i      uint64
@@ -1101,9 +1046,6 @@
 }
 
 func TestLoadUint64Method(t *testing.T) {
-	if test64err != nil {
-		t.Skipf("Skipping 64-bit tests: %v", test64err)
-	}
 	var x struct {
 		before uint64
 		i      Uint64
@@ -1302,9 +1244,6 @@
 }
 
 func TestStoreInt64(t *testing.T) {
-	if test64err != nil {
-		t.Skipf("Skipping 64-bit tests: %v", test64err)
-	}
 	var x struct {
 		before int64
 		i      int64
@@ -1349,9 +1288,6 @@
 }
 
 func TestStoreUint64(t *testing.T) {
-	if test64err != nil {
-		t.Skipf("Skipping 64-bit tests: %v", test64err)
-	}
 	var x struct {
 		before uint64
 		i      uint64
@@ -1374,9 +1310,6 @@
 }
 
 func TestStoreUint64Method(t *testing.T) {
-	if test64err != nil {
-		t.Skipf("Skipping 64-bit tests: %v", test64err)
-	}
 	var x struct {
 		before uint64
 		i      Uint64
@@ -1997,9 +1930,6 @@
 }
 
 func TestHammer64(t *testing.T) {
-	if test64err != nil {
-		t.Skipf("Skipping 64-bit tests: %v", test64err)
-	}
 	const p = 4
 	n := 100000
 	if testing.Short() {
@@ -2252,16 +2182,13 @@
 }
 
 func TestHammerStoreLoad(t *testing.T) {
-	var tests []func(*testing.T, unsafe.Pointer)
-	tests = append(tests, hammerStoreLoadInt32, hammerStoreLoadUint32,
+	tests := []func(*testing.T, unsafe.Pointer){
+		hammerStoreLoadInt32, hammerStoreLoadUint32,
 		hammerStoreLoadUintptr, hammerStoreLoadPointer,
 		hammerStoreLoadInt32Method, hammerStoreLoadUint32Method,
 		hammerStoreLoadUintptrMethod, hammerStoreLoadPointerMethod,
-	)
-	if test64err == nil {
-		tests = append(tests, hammerStoreLoadInt64, hammerStoreLoadUint64,
-			hammerStoreLoadInt64Method, hammerStoreLoadUint64Method,
-		)
+		hammerStoreLoadInt64, hammerStoreLoadUint64,
+		hammerStoreLoadInt64Method, hammerStoreLoadUint64Method,
 	}
 	n := int(1e6)
 	if testing.Short() {
@@ -2337,9 +2264,6 @@
 	if runtime.NumCPU() == 1 {
 		t.Skipf("Skipping test on %v processor machine", runtime.NumCPU())
 	}
-	if test64err != nil {
-		t.Skipf("Skipping 64-bit tests: %v", test64err)
-	}
 	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
 	N := int64(1e3)
 	if testing.Short() {
@@ -2428,9 +2352,6 @@
 	if runtime.NumCPU() == 1 {
 		t.Skipf("Skipping test on %v processor machine", runtime.NumCPU())
 	}
-	if test64err != nil {
-		t.Skipf("Skipping 64-bit tests: %v", test64err)
-	}
 	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
 	N := int64(1e3)
 	if testing.Short() {
@@ -2605,3 +2526,9 @@
 		}()
 	}
 }
+
+// Test that this compiles.
+// When atomic.Pointer used _ [0]T, it did not.
+type List struct {
+	Next Pointer[List]
+}
diff --git a/src/sync/atomic/doc.go b/src/sync/atomic/doc.go
index 7977d13..472ab9d 100644
--- a/src/sync/atomic/doc.go
+++ b/src/sync/atomic/doc.go
@@ -56,98 +56,137 @@
 //
 // On ARM, 386, and 32-bit MIPS, it is the caller's responsibility to arrange
 // for 64-bit alignment of 64-bit words accessed atomically via the primitive
-// atomic functions (types Int64 and Uint64 are automatically aligned).
+// atomic functions (types [Int64] and [Uint64] are automatically aligned).
 // The first word in an allocated struct, array, or slice; in a global
 // variable; or in a local variable (because the subject of all atomic operations
 // will escape to the heap) can be relied upon to be 64-bit aligned.
 
 // SwapInt32 atomically stores new into *addr and returns the previous *addr value.
+// Consider using the more ergonomic and less error-prone [Int32.Swap] instead.
 func SwapInt32(addr *int32, new int32) (old int32)
 
 // SwapInt64 atomically stores new into *addr and returns the previous *addr value.
+// Consider using the more ergonomic and less error-prone [Int64.Swap] instead
+// (particularly if you target 32-bit platforms; see the bugs section).
 func SwapInt64(addr *int64, new int64) (old int64)
 
 // SwapUint32 atomically stores new into *addr and returns the previous *addr value.
+// Consider using the more ergonomic and less error-prone [Uint32.Swap] instead.
 func SwapUint32(addr *uint32, new uint32) (old uint32)
 
 // SwapUint64 atomically stores new into *addr and returns the previous *addr value.
+// Consider using the more ergonomic and less error-prone [Uint64.Swap] instead
+// (particularly if you target 32-bit platforms; see the bugs section).
 func SwapUint64(addr *uint64, new uint64) (old uint64)
 
 // SwapUintptr atomically stores new into *addr and returns the previous *addr value.
+// Consider using the more ergonomic and less error-prone [Uintptr.Swap] instead.
 func SwapUintptr(addr *uintptr, new uintptr) (old uintptr)
 
 // SwapPointer atomically stores new into *addr and returns the previous *addr value.
+// Consider using the more ergonomic and less error-prone [Pointer.Swap] instead.
 func SwapPointer(addr *unsafe.Pointer, new unsafe.Pointer) (old unsafe.Pointer)
 
 // CompareAndSwapInt32 executes the compare-and-swap operation for an int32 value.
+// Consider using the more ergonomic and less error-prone [Int32.CompareAndSwap] instead.
 func CompareAndSwapInt32(addr *int32, old, new int32) (swapped bool)
 
 // CompareAndSwapInt64 executes the compare-and-swap operation for an int64 value.
+// Consider using the more ergonomic and less error-prone [Int64.CompareAndSwap] instead
+// (particularly if you target 32-bit platforms; see the bugs section).
 func CompareAndSwapInt64(addr *int64, old, new int64) (swapped bool)
 
 // CompareAndSwapUint32 executes the compare-and-swap operation for a uint32 value.
+// Consider using the more ergonomic and less error-prone [Uint32.CompareAndSwap] instead.
 func CompareAndSwapUint32(addr *uint32, old, new uint32) (swapped bool)
 
 // CompareAndSwapUint64 executes the compare-and-swap operation for a uint64 value.
+// Consider using the more ergonomic and less error-prone [Uint64.CompareAndSwap] instead
+// (particularly if you target 32-bit platforms; see the bugs section).
 func CompareAndSwapUint64(addr *uint64, old, new uint64) (swapped bool)
 
 // CompareAndSwapUintptr executes the compare-and-swap operation for a uintptr value.
+// Consider using the more ergonomic and less error-prone [Uintptr.CompareAndSwap] instead.
 func CompareAndSwapUintptr(addr *uintptr, old, new uintptr) (swapped bool)
 
 // CompareAndSwapPointer executes the compare-and-swap operation for a unsafe.Pointer value.
+// Consider using the more ergonomic and less error-prone [Pointer.CompareAndSwap] instead.
 func CompareAndSwapPointer(addr *unsafe.Pointer, old, new unsafe.Pointer) (swapped bool)
 
 // AddInt32 atomically adds delta to *addr and returns the new value.
+// Consider using the more ergonomic and less error-prone [Int32.Add] instead.
 func AddInt32(addr *int32, delta int32) (new int32)
 
 // AddUint32 atomically adds delta to *addr and returns the new value.
 // To subtract a signed positive constant value c from x, do AddUint32(&x, ^uint32(c-1)).
 // In particular, to decrement x, do AddUint32(&x, ^uint32(0)).
+// Consider using the more ergonomic and less error-prone [Uint32.Add] instead.
 func AddUint32(addr *uint32, delta uint32) (new uint32)
 
 // AddInt64 atomically adds delta to *addr and returns the new value.
+// Consider using the more ergonomic and less error-prone [Int64.Add] instead
+// (particularly if you target 32-bit platforms; see the bugs section).
 func AddInt64(addr *int64, delta int64) (new int64)
 
 // AddUint64 atomically adds delta to *addr and returns the new value.
 // To subtract a signed positive constant value c from x, do AddUint64(&x, ^uint64(c-1)).
 // In particular, to decrement x, do AddUint64(&x, ^uint64(0)).
+// Consider using the more ergonomic and less error-prone [Uint64.Add] instead
+// (particularly if you target 32-bit platforms; see the bugs section).
 func AddUint64(addr *uint64, delta uint64) (new uint64)
 
 // AddUintptr atomically adds delta to *addr and returns the new value.
+// Consider using the more ergonomic and less error-prone [Uintptr.Add] instead.
 func AddUintptr(addr *uintptr, delta uintptr) (new uintptr)
 
 // LoadInt32 atomically loads *addr.
+// Consider using the more ergonomic and less error-prone [Int32.Load] instead.
 func LoadInt32(addr *int32) (val int32)
 
 // LoadInt64 atomically loads *addr.
+// Consider using the more ergonomic and less error-prone [Int64.Load] instead
+// (particularly if you target 32-bit platforms; see the bugs section).
 func LoadInt64(addr *int64) (val int64)
 
 // LoadUint32 atomically loads *addr.
+// Consider using the more ergonomic and less error-prone [Uint32.Load] instead.
 func LoadUint32(addr *uint32) (val uint32)
 
 // LoadUint64 atomically loads *addr.
+// Consider using the more ergonomic and less error-prone [Uint64.Load] instead
+// (particularly if you target 32-bit platforms; see the bugs section).
 func LoadUint64(addr *uint64) (val uint64)
 
 // LoadUintptr atomically loads *addr.
+// Consider using the more ergonomic and less error-prone [Uintptr.Load] instead.
 func LoadUintptr(addr *uintptr) (val uintptr)
 
 // LoadPointer atomically loads *addr.
+// Consider using the more ergonomic and less error-prone [Pointer.Load] instead.
 func LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer)
 
 // StoreInt32 atomically stores val into *addr.
+// Consider using the more ergonomic and less error-prone [Int32.Store] instead.
 func StoreInt32(addr *int32, val int32)
 
 // StoreInt64 atomically stores val into *addr.
+// Consider using the more ergonomic and less error-prone [Int64.Store] instead
+// (particularly if you target 32-bit platforms; see the bugs section).
 func StoreInt64(addr *int64, val int64)
 
 // StoreUint32 atomically stores val into *addr.
+// Consider using the more ergonomic and less error-prone [Uint32.Store] instead.
 func StoreUint32(addr *uint32, val uint32)
 
 // StoreUint64 atomically stores val into *addr.
+// Consider using the more ergonomic and less error-prone [Uint64.Store] instead
+// (particularly if you target 32-bit platforms; see the bugs section).
 func StoreUint64(addr *uint64, val uint64)
 
 // StoreUintptr atomically stores val into *addr.
+// Consider using the more ergonomic and less error-prone [Uintptr.Store] instead.
 func StoreUintptr(addr *uintptr, val uintptr)
 
 // StorePointer atomically stores val into *addr.
+// Consider using the more ergonomic and less error-prone [Pointer.Store] instead.
 func StorePointer(addr *unsafe.Pointer, val unsafe.Pointer)
diff --git a/src/sync/atomic/type.go b/src/sync/atomic/type.go
index f7b8f5a..cc01683 100644
--- a/src/sync/atomic/type.go
+++ b/src/sync/atomic/type.go
@@ -35,8 +35,17 @@
 	return 0
 }
 
+// For testing *Pointer[T]'s methods can be inlined.
+// Keep in sync with cmd/compile/internal/test/inl_test.go:TestIntendedInlining.
+var _ = &Pointer[int]{}
+
 // A Pointer is an atomic pointer of type *T. The zero value is a nil *T.
 type Pointer[T any] struct {
+	// Mention *T in a field to disallow conversion between Pointer types.
+	// See go.dev/issue/56603 for more details.
+	// Use *T, not T, to avoid spurious recursive type definition errors.
+	_ [0]*T
+
 	_ noCopy
 	v unsafe.Pointer
 }
diff --git a/src/sync/atomic/value.go b/src/sync/atomic/value.go
index 88315f2..a57b08a 100644
--- a/src/sync/atomic/value.go
+++ b/src/sync/atomic/value.go
@@ -17,8 +17,8 @@
 	v any
 }
 
-// ifaceWords is interface{} internal representation.
-type ifaceWords struct {
+// efaceWords is interface{} internal representation.
+type efaceWords struct {
 	typ  unsafe.Pointer
 	data unsafe.Pointer
 }
@@ -26,14 +26,14 @@
 // Load returns the value set by the most recent Store.
 // It returns nil if there has been no call to Store for this Value.
 func (v *Value) Load() (val any) {
-	vp := (*ifaceWords)(unsafe.Pointer(v))
+	vp := (*efaceWords)(unsafe.Pointer(v))
 	typ := LoadPointer(&vp.typ)
 	if typ == nil || typ == unsafe.Pointer(&firstStoreInProgress) {
 		// First store not yet completed.
 		return nil
 	}
 	data := LoadPointer(&vp.data)
-	vlp := (*ifaceWords)(unsafe.Pointer(&val))
+	vlp := (*efaceWords)(unsafe.Pointer(&val))
 	vlp.typ = typ
 	vlp.data = data
 	return
@@ -41,15 +41,15 @@
 
 var firstStoreInProgress byte
 
-// Store sets the value of the Value to x.
+// Store sets the value of the Value v to val.
 // All calls to Store for a given Value must use values of the same concrete type.
 // Store of an inconsistent type panics, as does Store(nil).
 func (v *Value) Store(val any) {
 	if val == nil {
 		panic("sync/atomic: store of nil value into Value")
 	}
-	vp := (*ifaceWords)(unsafe.Pointer(v))
-	vlp := (*ifaceWords)(unsafe.Pointer(&val))
+	vp := (*efaceWords)(unsafe.Pointer(v))
+	vlp := (*efaceWords)(unsafe.Pointer(&val))
 	for {
 		typ := LoadPointer(&vp.typ)
 		if typ == nil {
@@ -91,8 +91,8 @@
 	if new == nil {
 		panic("sync/atomic: swap of nil value into Value")
 	}
-	vp := (*ifaceWords)(unsafe.Pointer(v))
-	np := (*ifaceWords)(unsafe.Pointer(&new))
+	vp := (*efaceWords)(unsafe.Pointer(v))
+	np := (*efaceWords)(unsafe.Pointer(&new))
 	for {
 		typ := LoadPointer(&vp.typ)
 		if typ == nil {
@@ -121,7 +121,7 @@
 		if typ != np.typ {
 			panic("sync/atomic: swap of inconsistently typed value into Value")
 		}
-		op := (*ifaceWords)(unsafe.Pointer(&old))
+		op := (*efaceWords)(unsafe.Pointer(&old))
 		op.typ, op.data = np.typ, SwapPointer(&vp.data, np.data)
 		return old
 	}
@@ -136,9 +136,9 @@
 	if new == nil {
 		panic("sync/atomic: compare and swap of nil value into Value")
 	}
-	vp := (*ifaceWords)(unsafe.Pointer(v))
-	np := (*ifaceWords)(unsafe.Pointer(&new))
-	op := (*ifaceWords)(unsafe.Pointer(&old))
+	vp := (*efaceWords)(unsafe.Pointer(v))
+	np := (*efaceWords)(unsafe.Pointer(&new))
+	op := (*efaceWords)(unsafe.Pointer(&old))
 	if op.typ != nil && np.typ != op.typ {
 		panic("sync/atomic: compare and swap of inconsistently typed values")
 	}
@@ -180,8 +180,8 @@
 		// has not changed since LoadPointer.
 		data := LoadPointer(&vp.data)
 		var i any
-		(*ifaceWords)(unsafe.Pointer(&i)).typ = typ
-		(*ifaceWords)(unsafe.Pointer(&i)).data = data
+		(*efaceWords)(unsafe.Pointer(&i)).typ = typ
+		(*efaceWords)(unsafe.Pointer(&i)).data = data
 		if i != old {
 			return false
 		}
@@ -190,5 +190,5 @@
 }
 
 // Disable/enable preemption, implemented in runtime.
-func runtime_procPin()
+func runtime_procPin() int
 func runtime_procUnpin()
diff --git a/src/sync/cond.go b/src/sync/cond.go
index cbf5ba6..cc927ad 100644
--- a/src/sync/cond.go
+++ b/src/sync/cond.go
@@ -53,7 +53,7 @@
 // Wait locks c.L before returning. Unlike in other systems,
 // Wait cannot return unless awoken by Broadcast or Signal.
 //
-// Because c.L is not locked when Wait first resumes, the caller
+// Because c.L is not locked while Wait is waiting, the caller
 // typically cannot assume that the condition is true when
 // Wait returns. Instead, the caller should Wait in a loop:
 //
diff --git a/src/sync/map.go b/src/sync/map.go
index ec529e0..e8ccf58 100644
--- a/src/sync/map.go
+++ b/src/sync/map.go
@@ -6,7 +6,6 @@
 
 import (
 	"sync/atomic"
-	"unsafe"
 )
 
 // Map is like a Go map[interface{}]interface{} but is safe for concurrent use
@@ -28,9 +27,11 @@
 // In the terminology of the Go memory model, Map arranges that a write operation
 // “synchronizes before” any read operation that observes the effect of the write, where
 // read and write operations are defined as follows.
-// Load, LoadAndDelete, LoadOrStore are read operations;
-// Delete, LoadAndDelete, and Store are write operations;
-// and LoadOrStore is a write operation when it returns loaded set to false.
+// Load, LoadAndDelete, LoadOrStore, Swap, CompareAndSwap, and CompareAndDelete
+// are read operations; Delete, LoadAndDelete, Store, and Swap are write operations;
+// LoadOrStore is a write operation when it returns loaded set to false;
+// CompareAndSwap is a write operation when it returns swapped set to true;
+// and CompareAndDelete is a write operation when it returns deleted set to true.
 type Map struct {
 	mu Mutex
 
@@ -43,7 +44,7 @@
 	// Entries stored in read may be updated concurrently without mu, but updating
 	// a previously-expunged entry requires that the entry be copied to the dirty
 	// map and unexpunged with mu held.
-	read atomic.Value // readOnly
+	read atomic.Pointer[readOnly]
 
 	// dirty contains the portion of the map's contents that require mu to be
 	// held. To ensure that the dirty map can be promoted to the read map quickly,
@@ -74,7 +75,7 @@
 
 // expunged is an arbitrary pointer that marks entries which have been deleted
 // from the dirty map.
-var expunged = unsafe.Pointer(new(any))
+var expunged = new(any)
 
 // An entry is a slot in the map corresponding to a particular key.
 type entry struct {
@@ -97,25 +98,34 @@
 	// p != expunged. If p == expunged, an entry's associated value can be updated
 	// only after first setting m.dirty[key] = e so that lookups using the dirty
 	// map find the entry.
-	p unsafe.Pointer // *interface{}
+	p atomic.Pointer[any]
 }
 
 func newEntry(i any) *entry {
-	return &entry{p: unsafe.Pointer(&i)}
+	e := &entry{}
+	e.p.Store(&i)
+	return e
+}
+
+func (m *Map) loadReadOnly() readOnly {
+	if p := m.read.Load(); p != nil {
+		return *p
+	}
+	return readOnly{}
 }
 
 // Load returns the value stored in the map for a key, or nil if no
 // value is present.
 // The ok result indicates whether value was found in the map.
 func (m *Map) Load(key any) (value any, ok bool) {
-	read, _ := m.read.Load().(readOnly)
+	read := m.loadReadOnly()
 	e, ok := read.m[key]
 	if !ok && read.amended {
 		m.mu.Lock()
 		// Avoid reporting a spurious miss if m.dirty got promoted while we were
 		// blocked on m.mu. (If further loads of the same key will not miss, it's
 		// not worth copying the dirty map for this key.)
-		read, _ = m.read.Load().(readOnly)
+		read = m.loadReadOnly()
 		e, ok = read.m[key]
 		if !ok && read.amended {
 			e, ok = m.dirty[key]
@@ -133,56 +143,42 @@
 }
 
 func (e *entry) load() (value any, ok bool) {
-	p := atomic.LoadPointer(&e.p)
+	p := e.p.Load()
 	if p == nil || p == expunged {
 		return nil, false
 	}
-	return *(*any)(p), true
+	return *p, true
 }
 
 // Store sets the value for a key.
 func (m *Map) Store(key, value any) {
-	read, _ := m.read.Load().(readOnly)
-	if e, ok := read.m[key]; ok && e.tryStore(&value) {
-		return
-	}
-
-	m.mu.Lock()
-	read, _ = m.read.Load().(readOnly)
-	if e, ok := read.m[key]; ok {
-		if e.unexpungeLocked() {
-			// The entry was previously expunged, which implies that there is a
-			// non-nil dirty map and this entry is not in it.
-			m.dirty[key] = e
-		}
-		e.storeLocked(&value)
-	} else if e, ok := m.dirty[key]; ok {
-		e.storeLocked(&value)
-	} else {
-		if !read.amended {
-			// We're adding the first new key to the dirty map.
-			// Make sure it is allocated and mark the read-only map as incomplete.
-			m.dirtyLocked()
-			m.read.Store(readOnly{m: read.m, amended: true})
-		}
-		m.dirty[key] = newEntry(value)
-	}
-	m.mu.Unlock()
+	_, _ = m.Swap(key, value)
 }
 
-// tryStore stores a value if the entry has not been expunged.
+// tryCompareAndSwap compare the entry with the given old value and swaps
+// it with a new value if the entry is equal to the old value, and the entry
+// has not been expunged.
 //
-// If the entry is expunged, tryStore returns false and leaves the entry
-// unchanged.
-func (e *entry) tryStore(i *any) bool {
+// If the entry is expunged, tryCompareAndSwap returns false and leaves
+// the entry unchanged.
+func (e *entry) tryCompareAndSwap(old, new any) bool {
+	p := e.p.Load()
+	if p == nil || p == expunged || *p != old {
+		return false
+	}
+
+	// Copy the interface after the first load to make this method more amenable
+	// to escape analysis: if the comparison fails from the start, we shouldn't
+	// bother heap-allocating an interface value to store.
+	nc := new
 	for {
-		p := atomic.LoadPointer(&e.p)
-		if p == expunged {
-			return false
-		}
-		if atomic.CompareAndSwapPointer(&e.p, p, unsafe.Pointer(i)) {
+		if e.p.CompareAndSwap(p, &nc) {
 			return true
 		}
+		p = e.p.Load()
+		if p == nil || p == expunged || *p != old {
+			return false
+		}
 	}
 }
 
@@ -191,14 +187,14 @@
 // If the entry was previously expunged, it must be added to the dirty map
 // before m.mu is unlocked.
 func (e *entry) unexpungeLocked() (wasExpunged bool) {
-	return atomic.CompareAndSwapPointer(&e.p, expunged, nil)
+	return e.p.CompareAndSwap(expunged, nil)
 }
 
-// storeLocked unconditionally stores a value to the entry.
+// swapLocked unconditionally swaps a value into the entry.
 //
 // The entry must be known not to be expunged.
-func (e *entry) storeLocked(i *any) {
-	atomic.StorePointer(&e.p, unsafe.Pointer(i))
+func (e *entry) swapLocked(i *any) *any {
+	return e.p.Swap(i)
 }
 
 // LoadOrStore returns the existing value for the key if present.
@@ -206,7 +202,7 @@
 // The loaded result is true if the value was loaded, false if stored.
 func (m *Map) LoadOrStore(key, value any) (actual any, loaded bool) {
 	// Avoid locking if it's a clean hit.
-	read, _ := m.read.Load().(readOnly)
+	read := m.loadReadOnly()
 	if e, ok := read.m[key]; ok {
 		actual, loaded, ok := e.tryLoadOrStore(value)
 		if ok {
@@ -215,7 +211,7 @@
 	}
 
 	m.mu.Lock()
-	read, _ = m.read.Load().(readOnly)
+	read = m.loadReadOnly()
 	if e, ok := read.m[key]; ok {
 		if e.unexpungeLocked() {
 			m.dirty[key] = e
@@ -229,7 +225,7 @@
 			// We're adding the first new key to the dirty map.
 			// Make sure it is allocated and mark the read-only map as incomplete.
 			m.dirtyLocked()
-			m.read.Store(readOnly{m: read.m, amended: true})
+			m.read.Store(&readOnly{m: read.m, amended: true})
 		}
 		m.dirty[key] = newEntry(value)
 		actual, loaded = value, false
@@ -245,12 +241,12 @@
 // If the entry is expunged, tryLoadOrStore leaves the entry unchanged and
 // returns with ok==false.
 func (e *entry) tryLoadOrStore(i any) (actual any, loaded, ok bool) {
-	p := atomic.LoadPointer(&e.p)
+	p := e.p.Load()
 	if p == expunged {
 		return nil, false, false
 	}
 	if p != nil {
-		return *(*any)(p), true, true
+		return *p, true, true
 	}
 
 	// Copy the interface after the first load to make this method more amenable
@@ -258,15 +254,15 @@
 	// shouldn't bother heap-allocating.
 	ic := i
 	for {
-		if atomic.CompareAndSwapPointer(&e.p, nil, unsafe.Pointer(&ic)) {
+		if e.p.CompareAndSwap(nil, &ic) {
 			return i, false, true
 		}
-		p = atomic.LoadPointer(&e.p)
+		p = e.p.Load()
 		if p == expunged {
 			return nil, false, false
 		}
 		if p != nil {
-			return *(*any)(p), true, true
+			return *p, true, true
 		}
 	}
 }
@@ -274,11 +270,11 @@
 // LoadAndDelete deletes the value for a key, returning the previous value if any.
 // The loaded result reports whether the key was present.
 func (m *Map) LoadAndDelete(key any) (value any, loaded bool) {
-	read, _ := m.read.Load().(readOnly)
+	read := m.loadReadOnly()
 	e, ok := read.m[key]
 	if !ok && read.amended {
 		m.mu.Lock()
-		read, _ = m.read.Load().(readOnly)
+		read = m.loadReadOnly()
 		e, ok = read.m[key]
 		if !ok && read.amended {
 			e, ok = m.dirty[key]
@@ -303,16 +299,142 @@
 
 func (e *entry) delete() (value any, ok bool) {
 	for {
-		p := atomic.LoadPointer(&e.p)
+		p := e.p.Load()
 		if p == nil || p == expunged {
 			return nil, false
 		}
-		if atomic.CompareAndSwapPointer(&e.p, p, nil) {
-			return *(*any)(p), true
+		if e.p.CompareAndSwap(p, nil) {
+			return *p, true
 		}
 	}
 }
 
+// trySwap swaps a value if the entry has not been expunged.
+//
+// If the entry is expunged, trySwap returns false and leaves the entry
+// unchanged.
+func (e *entry) trySwap(i *any) (*any, bool) {
+	for {
+		p := e.p.Load()
+		if p == expunged {
+			return nil, false
+		}
+		if e.p.CompareAndSwap(p, i) {
+			return p, true
+		}
+	}
+}
+
+// Swap swaps the value for a key and returns the previous value if any.
+// The loaded result reports whether the key was present.
+func (m *Map) Swap(key, value any) (previous any, loaded bool) {
+	read := m.loadReadOnly()
+	if e, ok := read.m[key]; ok {
+		if v, ok := e.trySwap(&value); ok {
+			if v == nil {
+				return nil, false
+			}
+			return *v, true
+		}
+	}
+
+	m.mu.Lock()
+	read = m.loadReadOnly()
+	if e, ok := read.m[key]; ok {
+		if e.unexpungeLocked() {
+			// The entry was previously expunged, which implies that there is a
+			// non-nil dirty map and this entry is not in it.
+			m.dirty[key] = e
+		}
+		if v := e.swapLocked(&value); v != nil {
+			loaded = true
+			previous = *v
+		}
+	} else if e, ok := m.dirty[key]; ok {
+		if v := e.swapLocked(&value); v != nil {
+			loaded = true
+			previous = *v
+		}
+	} else {
+		if !read.amended {
+			// We're adding the first new key to the dirty map.
+			// Make sure it is allocated and mark the read-only map as incomplete.
+			m.dirtyLocked()
+			m.read.Store(&readOnly{m: read.m, amended: true})
+		}
+		m.dirty[key] = newEntry(value)
+	}
+	m.mu.Unlock()
+	return previous, loaded
+}
+
+// CompareAndSwap swaps the old and new values for key
+// if the value stored in the map is equal to old.
+// The old value must be of a comparable type.
+func (m *Map) CompareAndSwap(key, old, new any) bool {
+	read := m.loadReadOnly()
+	if e, ok := read.m[key]; ok {
+		return e.tryCompareAndSwap(old, new)
+	} else if !read.amended {
+		return false // No existing value for key.
+	}
+
+	m.mu.Lock()
+	defer m.mu.Unlock()
+	read = m.loadReadOnly()
+	swapped := false
+	if e, ok := read.m[key]; ok {
+		swapped = e.tryCompareAndSwap(old, new)
+	} else if e, ok := m.dirty[key]; ok {
+		swapped = e.tryCompareAndSwap(old, new)
+		// We needed to lock mu in order to load the entry for key,
+		// and the operation didn't change the set of keys in the map
+		// (so it would be made more efficient by promoting the dirty
+		// map to read-only).
+		// Count it as a miss so that we will eventually switch to the
+		// more efficient steady state.
+		m.missLocked()
+	}
+	return swapped
+}
+
+// CompareAndDelete deletes the entry for key if its value is equal to old.
+// The old value must be of a comparable type.
+//
+// If there is no current value for key in the map, CompareAndDelete
+// returns false (even if the old value is the nil interface value).
+func (m *Map) CompareAndDelete(key, old any) (deleted bool) {
+	read := m.loadReadOnly()
+	e, ok := read.m[key]
+	if !ok && read.amended {
+		m.mu.Lock()
+		read = m.loadReadOnly()
+		e, ok = read.m[key]
+		if !ok && read.amended {
+			e, ok = m.dirty[key]
+			// Don't delete key from m.dirty: we still need to do the “compare” part
+			// of the operation. The entry will eventually be expunged when the
+			// dirty map is promoted to the read map.
+			//
+			// Regardless of whether the entry was present, record a miss: this key
+			// will take the slow path until the dirty map is promoted to the read
+			// map.
+			m.missLocked()
+		}
+		m.mu.Unlock()
+	}
+	for ok {
+		p := e.p.Load()
+		if p == nil || p == expunged || *p != old {
+			return false
+		}
+		if e.p.CompareAndSwap(p, nil) {
+			return true
+		}
+	}
+	return false
+}
+
 // Range calls f sequentially for each key and value present in the map.
 // If f returns false, range stops the iteration.
 //
@@ -329,17 +451,17 @@
 	// present at the start of the call to Range.
 	// If read.amended is false, then read.m satisfies that property without
 	// requiring us to hold m.mu for a long time.
-	read, _ := m.read.Load().(readOnly)
+	read := m.loadReadOnly()
 	if read.amended {
 		// m.dirty contains keys not in read.m. Fortunately, Range is already O(N)
 		// (assuming the caller does not break out early), so a call to Range
 		// amortizes an entire copy of the map: we can promote the dirty copy
 		// immediately!
 		m.mu.Lock()
-		read, _ = m.read.Load().(readOnly)
+		read = m.loadReadOnly()
 		if read.amended {
 			read = readOnly{m: m.dirty}
-			m.read.Store(read)
+			m.read.Store(&read)
 			m.dirty = nil
 			m.misses = 0
 		}
@@ -362,7 +484,7 @@
 	if m.misses < len(m.dirty) {
 		return
 	}
-	m.read.Store(readOnly{m: m.dirty})
+	m.read.Store(&readOnly{m: m.dirty})
 	m.dirty = nil
 	m.misses = 0
 }
@@ -372,7 +494,7 @@
 		return
 	}
 
-	read, _ := m.read.Load().(readOnly)
+	read := m.loadReadOnly()
 	m.dirty = make(map[any]*entry, len(read.m))
 	for k, e := range read.m {
 		if !e.tryExpungeLocked() {
@@ -382,12 +504,12 @@
 }
 
 func (e *entry) tryExpungeLocked() (isExpunged bool) {
-	p := atomic.LoadPointer(&e.p)
+	p := e.p.Load()
 	for p == nil {
-		if atomic.CompareAndSwapPointer(&e.p, nil, expunged) {
+		if e.p.CompareAndSwap(nil, expunged) {
 			return true
 		}
-		p = atomic.LoadPointer(&e.p)
+		p = e.p.Load()
 	}
 	return p == expunged
 }
diff --git a/src/sync/map_bench_test.go b/src/sync/map_bench_test.go
index e7b0e60..eebec3b 100644
--- a/src/sync/map_bench_test.go
+++ b/src/sync/map_bench_test.go
@@ -198,7 +198,9 @@
 
 		perG: func(b *testing.B, pb *testing.PB, i int, m mapInterface) {
 			for ; pb.Next(); i++ {
-				m.LoadAndDelete(0)
+				if _, loaded := m.LoadAndDelete(0); loaded {
+					m.Store(0, 0)
+				}
 			}
 		},
 	})
@@ -287,3 +289,247 @@
 		},
 	})
 }
+
+func BenchmarkSwapCollision(b *testing.B) {
+	benchMap(b, bench{
+		setup: func(_ *testing.B, m mapInterface) {
+			m.LoadOrStore(0, 0)
+		},
+
+		perG: func(b *testing.B, pb *testing.PB, i int, m mapInterface) {
+			for ; pb.Next(); i++ {
+				m.Swap(0, 0)
+			}
+		},
+	})
+}
+
+func BenchmarkSwapMostlyHits(b *testing.B) {
+	const hits, misses = 1023, 1
+
+	benchMap(b, bench{
+		setup: func(_ *testing.B, m mapInterface) {
+			for i := 0; i < hits; i++ {
+				m.LoadOrStore(i, i)
+			}
+			// Prime the map to get it into a steady state.
+			for i := 0; i < hits*2; i++ {
+				m.Load(i % hits)
+			}
+		},
+
+		perG: func(b *testing.B, pb *testing.PB, i int, m mapInterface) {
+			for ; pb.Next(); i++ {
+				if i%(hits+misses) < hits {
+					v := i % (hits + misses)
+					m.Swap(v, v)
+				} else {
+					m.Swap(i, i)
+					m.Delete(i)
+				}
+			}
+		},
+	})
+}
+
+func BenchmarkSwapMostlyMisses(b *testing.B) {
+	const hits, misses = 1, 1023
+
+	benchMap(b, bench{
+		setup: func(_ *testing.B, m mapInterface) {
+			for i := 0; i < hits; i++ {
+				m.LoadOrStore(i, i)
+			}
+			// Prime the map to get it into a steady state.
+			for i := 0; i < hits*2; i++ {
+				m.Load(i % hits)
+			}
+		},
+
+		perG: func(b *testing.B, pb *testing.PB, i int, m mapInterface) {
+			for ; pb.Next(); i++ {
+				if i%(hits+misses) < hits {
+					v := i % (hits + misses)
+					m.Swap(v, v)
+				} else {
+					m.Swap(i, i)
+					m.Delete(i)
+				}
+			}
+		},
+	})
+}
+
+func BenchmarkCompareAndSwapCollision(b *testing.B) {
+	benchMap(b, bench{
+		setup: func(_ *testing.B, m mapInterface) {
+			m.LoadOrStore(0, 0)
+		},
+
+		perG: func(b *testing.B, pb *testing.PB, i int, m mapInterface) {
+			for pb.Next() {
+				if m.CompareAndSwap(0, 0, 42) {
+					m.CompareAndSwap(0, 42, 0)
+				}
+			}
+		},
+	})
+}
+
+func BenchmarkCompareAndSwapNoExistingKey(b *testing.B) {
+	benchMap(b, bench{
+		perG: func(b *testing.B, pb *testing.PB, i int, m mapInterface) {
+			for ; pb.Next(); i++ {
+				if m.CompareAndSwap(i, 0, 0) {
+					m.Delete(i)
+				}
+			}
+		},
+	})
+}
+
+func BenchmarkCompareAndSwapValueNotEqual(b *testing.B) {
+	benchMap(b, bench{
+		setup: func(_ *testing.B, m mapInterface) {
+			m.Store(0, 0)
+		},
+
+		perG: func(b *testing.B, pb *testing.PB, i int, m mapInterface) {
+			for ; pb.Next(); i++ {
+				m.CompareAndSwap(0, 1, 2)
+			}
+		},
+	})
+}
+
+func BenchmarkCompareAndSwapMostlyHits(b *testing.B) {
+	const hits, misses = 1023, 1
+
+	benchMap(b, bench{
+		setup: func(b *testing.B, m mapInterface) {
+			if _, ok := m.(*DeepCopyMap); ok {
+				b.Skip("DeepCopyMap has quadratic running time.")
+			}
+
+			for i := 0; i < hits; i++ {
+				m.LoadOrStore(i, i)
+			}
+			// Prime the map to get it into a steady state.
+			for i := 0; i < hits*2; i++ {
+				m.Load(i % hits)
+			}
+		},
+
+		perG: func(b *testing.B, pb *testing.PB, i int, m mapInterface) {
+			for ; pb.Next(); i++ {
+				v := i
+				if i%(hits+misses) < hits {
+					v = i % (hits + misses)
+				}
+				m.CompareAndSwap(v, v, v)
+			}
+		},
+	})
+}
+
+func BenchmarkCompareAndSwapMostlyMisses(b *testing.B) {
+	const hits, misses = 1, 1023
+
+	benchMap(b, bench{
+		setup: func(_ *testing.B, m mapInterface) {
+			for i := 0; i < hits; i++ {
+				m.LoadOrStore(i, i)
+			}
+			// Prime the map to get it into a steady state.
+			for i := 0; i < hits*2; i++ {
+				m.Load(i % hits)
+			}
+		},
+
+		perG: func(b *testing.B, pb *testing.PB, i int, m mapInterface) {
+			for ; pb.Next(); i++ {
+				v := i
+				if i%(hits+misses) < hits {
+					v = i % (hits + misses)
+				}
+				m.CompareAndSwap(v, v, v)
+			}
+		},
+	})
+}
+
+func BenchmarkCompareAndDeleteCollision(b *testing.B) {
+	benchMap(b, bench{
+		setup: func(_ *testing.B, m mapInterface) {
+			m.LoadOrStore(0, 0)
+		},
+
+		perG: func(b *testing.B, pb *testing.PB, i int, m mapInterface) {
+			for ; pb.Next(); i++ {
+				if m.CompareAndDelete(0, 0) {
+					m.Store(0, 0)
+				}
+			}
+		},
+	})
+}
+
+func BenchmarkCompareAndDeleteMostlyHits(b *testing.B) {
+	const hits, misses = 1023, 1
+
+	benchMap(b, bench{
+		setup: func(b *testing.B, m mapInterface) {
+			if _, ok := m.(*DeepCopyMap); ok {
+				b.Skip("DeepCopyMap has quadratic running time.")
+			}
+
+			for i := 0; i < hits; i++ {
+				m.LoadOrStore(i, i)
+			}
+			// Prime the map to get it into a steady state.
+			for i := 0; i < hits*2; i++ {
+				m.Load(i % hits)
+			}
+		},
+
+		perG: func(b *testing.B, pb *testing.PB, i int, m mapInterface) {
+			for ; pb.Next(); i++ {
+				v := i
+				if i%(hits+misses) < hits {
+					v = i % (hits + misses)
+				}
+				if m.CompareAndDelete(v, v) {
+					m.Store(v, v)
+				}
+			}
+		},
+	})
+}
+
+func BenchmarkCompareAndDeleteMostlyMisses(b *testing.B) {
+	const hits, misses = 1, 1023
+
+	benchMap(b, bench{
+		setup: func(_ *testing.B, m mapInterface) {
+			for i := 0; i < hits; i++ {
+				m.LoadOrStore(i, i)
+			}
+			// Prime the map to get it into a steady state.
+			for i := 0; i < hits*2; i++ {
+				m.Load(i % hits)
+			}
+		},
+
+		perG: func(b *testing.B, pb *testing.PB, i int, m mapInterface) {
+			for ; pb.Next(); i++ {
+				v := i
+				if i%(hits+misses) < hits {
+					v = i % (hits + misses)
+				}
+				if m.CompareAndDelete(v, v) {
+					m.Store(v, v)
+				}
+			}
+		},
+	})
+}
diff --git a/src/sync/map_reference_test.go b/src/sync/map_reference_test.go
index 1122b40..aa5ebf3 100644
--- a/src/sync/map_reference_test.go
+++ b/src/sync/map_reference_test.go
@@ -18,9 +18,17 @@
 	LoadOrStore(key, value any) (actual any, loaded bool)
 	LoadAndDelete(key any) (value any, loaded bool)
 	Delete(any)
+	Swap(key, value any) (previous any, loaded bool)
+	CompareAndSwap(key, old, new any) (swapped bool)
+	CompareAndDelete(key, old any) (deleted bool)
 	Range(func(key, value any) (shouldContinue bool))
 }
 
+var (
+	_ mapInterface = &RWMutexMap{}
+	_ mapInterface = &DeepCopyMap{}
+)
+
 // RWMutexMap is an implementation of mapInterface using a sync.RWMutex.
 type RWMutexMap struct {
 	mu    sync.RWMutex
@@ -57,6 +65,18 @@
 	return actual, loaded
 }
 
+func (m *RWMutexMap) Swap(key, value any) (previous any, loaded bool) {
+	m.mu.Lock()
+	if m.dirty == nil {
+		m.dirty = make(map[any]any)
+	}
+
+	previous, loaded = m.dirty[key]
+	m.dirty[key] = value
+	m.mu.Unlock()
+	return
+}
+
 func (m *RWMutexMap) LoadAndDelete(key any) (value any, loaded bool) {
 	m.mu.Lock()
 	value, loaded = m.dirty[key]
@@ -75,6 +95,36 @@
 	m.mu.Unlock()
 }
 
+func (m *RWMutexMap) CompareAndSwap(key, old, new any) (swapped bool) {
+	m.mu.Lock()
+	defer m.mu.Unlock()
+	if m.dirty == nil {
+		return false
+	}
+
+	value, loaded := m.dirty[key]
+	if loaded && value == old {
+		m.dirty[key] = new
+		return true
+	}
+	return false
+}
+
+func (m *RWMutexMap) CompareAndDelete(key, old any) (deleted bool) {
+	m.mu.Lock()
+	defer m.mu.Unlock()
+	if m.dirty == nil {
+		return false
+	}
+
+	value, loaded := m.dirty[key]
+	if loaded && value == old {
+		delete(m.dirty, key)
+		return true
+	}
+	return false
+}
+
 func (m *RWMutexMap) Range(f func(key, value any) (shouldContinue bool)) {
 	m.mu.RLock()
 	keys := make([]any, 0, len(m.dirty))
@@ -137,6 +187,16 @@
 	return actual, loaded
 }
 
+func (m *DeepCopyMap) Swap(key, value any) (previous any, loaded bool) {
+	m.mu.Lock()
+	dirty := m.dirty()
+	previous, loaded = dirty[key]
+	dirty[key] = value
+	m.clean.Store(dirty)
+	m.mu.Unlock()
+	return
+}
+
 func (m *DeepCopyMap) LoadAndDelete(key any) (value any, loaded bool) {
 	m.mu.Lock()
 	dirty := m.dirty()
@@ -155,6 +215,43 @@
 	m.mu.Unlock()
 }
 
+func (m *DeepCopyMap) CompareAndSwap(key, old, new any) (swapped bool) {
+	clean, _ := m.clean.Load().(map[any]any)
+	if previous, ok := clean[key]; !ok || previous != old {
+		return false
+	}
+
+	m.mu.Lock()
+	defer m.mu.Unlock()
+	dirty := m.dirty()
+	value, loaded := dirty[key]
+	if loaded && value == old {
+		dirty[key] = new
+		m.clean.Store(dirty)
+		return true
+	}
+	return false
+}
+
+func (m *DeepCopyMap) CompareAndDelete(key, old any) (deleted bool) {
+	clean, _ := m.clean.Load().(map[any]any)
+	if previous, ok := clean[key]; !ok || previous != old {
+		return false
+	}
+
+	m.mu.Lock()
+	defer m.mu.Unlock()
+
+	dirty := m.dirty()
+	value, loaded := dirty[key]
+	if loaded && value == old {
+		delete(dirty, key)
+		m.clean.Store(dirty)
+		return true
+	}
+	return false
+}
+
 func (m *DeepCopyMap) Range(f func(key, value any) (shouldContinue bool)) {
 	clean, _ := m.clean.Load().(map[any]any)
 	for k, v := range clean {
diff --git a/src/sync/map_test.go b/src/sync/map_test.go
index 8352471..1eb3fc6 100644
--- a/src/sync/map_test.go
+++ b/src/sync/map_test.go
@@ -17,14 +17,26 @@
 type mapOp string
 
 const (
-	opLoad          = mapOp("Load")
-	opStore         = mapOp("Store")
-	opLoadOrStore   = mapOp("LoadOrStore")
-	opLoadAndDelete = mapOp("LoadAndDelete")
-	opDelete        = mapOp("Delete")
+	opLoad             = mapOp("Load")
+	opStore            = mapOp("Store")
+	opLoadOrStore      = mapOp("LoadOrStore")
+	opLoadAndDelete    = mapOp("LoadAndDelete")
+	opDelete           = mapOp("Delete")
+	opSwap             = mapOp("Swap")
+	opCompareAndSwap   = mapOp("CompareAndSwap")
+	opCompareAndDelete = mapOp("CompareAndDelete")
 )
 
-var mapOps = [...]mapOp{opLoad, opStore, opLoadOrStore, opLoadAndDelete, opDelete}
+var mapOps = [...]mapOp{
+	opLoad,
+	opStore,
+	opLoadOrStore,
+	opLoadAndDelete,
+	opDelete,
+	opSwap,
+	opCompareAndSwap,
+	opCompareAndDelete,
+}
 
 // mapCall is a quick.Generator for calls on mapInterface.
 type mapCall struct {
@@ -46,6 +58,21 @@
 	case opDelete:
 		m.Delete(c.k)
 		return nil, false
+	case opSwap:
+		return m.Swap(c.k, c.v)
+	case opCompareAndSwap:
+		if m.CompareAndSwap(c.k, c.v, rand.Int()) {
+			m.Delete(c.k)
+			return c.v, true
+		}
+		return nil, false
+	case opCompareAndDelete:
+		if m.CompareAndDelete(c.k, c.v) {
+			if _, ok := m.Load(c.k); !ok {
+				return nil, true
+			}
+		}
+		return nil, false
 	default:
 		panic("invalid mapOp")
 	}
@@ -245,3 +272,11 @@
 		t.Fatalf("Unexpected sync.Map size, got %v want %v", length, 0)
 	}
 }
+
+func TestCompareAndSwap_NonExistingKey(t *testing.T) {
+	m := &sync.Map{}
+	if m.CompareAndSwap(m, nil, 42) {
+		// See https://go.dev/issue/51972#issuecomment-1126408637.
+		t.Fatalf("CompareAndSwap on an non-existing key succeeded")
+	}
+}
diff --git a/src/sync/runtime.go b/src/sync/runtime.go
index de2b0a3..5a90813 100644
--- a/src/sync/runtime.go
+++ b/src/sync/runtime.go
@@ -13,11 +13,17 @@
 // library and should not be used directly.
 func runtime_Semacquire(s *uint32)
 
-// SemacquireMutex is like Semacquire, but for profiling contended Mutexes.
+// Semacquire(RW)Mutex(R) is like Semacquire, but for profiling contended
+// Mutexes and RWMutexes.
 // If lifo is true, queue waiter at the head of wait queue.
 // skipframes is the number of frames to omit during tracing, counting from
 // runtime_SemacquireMutex's caller.
+// The different forms of this function just tell the runtime how to present
+// the reason for waiting in a backtrace, and is used to compute some metrics.
+// Otherwise they're functionally identical.
 func runtime_SemacquireMutex(s *uint32, lifo bool, skipframes int)
+func runtime_SemacquireRWMutexR(s *uint32, lifo bool, skipframes int)
+func runtime_SemacquireRWMutex(s *uint32, lifo bool, skipframes int)
 
 // Semrelease atomically increments *s and notifies a waiting goroutine
 // if one is blocked in Semacquire.
diff --git a/src/sync/rwmutex.go b/src/sync/rwmutex.go
index e914f3e..ad52951 100644
--- a/src/sync/rwmutex.go
+++ b/src/sync/rwmutex.go
@@ -34,11 +34,11 @@
 // and the corresponding call to RUnlock “synchronizes before”
 // the n+1'th call to Lock.
 type RWMutex struct {
-	w           Mutex  // held if there are pending writers
-	writerSem   uint32 // semaphore for writers to wait for completing readers
-	readerSem   uint32 // semaphore for readers to wait for completing writers
-	readerCount int32  // number of pending readers
-	readerWait  int32  // number of departing readers
+	w           Mutex        // held if there are pending writers
+	writerSem   uint32       // semaphore for writers to wait for completing readers
+	readerSem   uint32       // semaphore for readers to wait for completing writers
+	readerCount atomic.Int32 // number of pending readers
+	readerWait  atomic.Int32 // number of departing readers
 }
 
 const rwmutexMaxReaders = 1 << 30
@@ -66,9 +66,9 @@
 		_ = rw.w.state
 		race.Disable()
 	}
-	if atomic.AddInt32(&rw.readerCount, 1) < 0 {
+	if rw.readerCount.Add(1) < 0 {
 		// A writer is pending, wait for it.
-		runtime_SemacquireMutex(&rw.readerSem, false, 0)
+		runtime_SemacquireRWMutexR(&rw.readerSem, false, 0)
 	}
 	if race.Enabled {
 		race.Enable()
@@ -87,14 +87,14 @@
 		race.Disable()
 	}
 	for {
-		c := atomic.LoadInt32(&rw.readerCount)
+		c := rw.readerCount.Load()
 		if c < 0 {
 			if race.Enabled {
 				race.Enable()
 			}
 			return false
 		}
-		if atomic.CompareAndSwapInt32(&rw.readerCount, c, c+1) {
+		if rw.readerCount.CompareAndSwap(c, c+1) {
 			if race.Enabled {
 				race.Enable()
 				race.Acquire(unsafe.Pointer(&rw.readerSem))
@@ -114,7 +114,7 @@
 		race.ReleaseMerge(unsafe.Pointer(&rw.writerSem))
 		race.Disable()
 	}
-	if r := atomic.AddInt32(&rw.readerCount, -1); r < 0 {
+	if r := rw.readerCount.Add(-1); r < 0 {
 		// Outlined slow-path to allow the fast-path to be inlined
 		rw.rUnlockSlow(r)
 	}
@@ -129,7 +129,7 @@
 		fatal("sync: RUnlock of unlocked RWMutex")
 	}
 	// A writer is pending.
-	if atomic.AddInt32(&rw.readerWait, -1) == 0 {
+	if rw.readerWait.Add(-1) == 0 {
 		// The last reader unblocks the writer.
 		runtime_Semrelease(&rw.writerSem, false, 1)
 	}
@@ -146,10 +146,10 @@
 	// First, resolve competition with other writers.
 	rw.w.Lock()
 	// Announce to readers there is a pending writer.
-	r := atomic.AddInt32(&rw.readerCount, -rwmutexMaxReaders) + rwmutexMaxReaders
+	r := rw.readerCount.Add(-rwmutexMaxReaders) + rwmutexMaxReaders
 	// Wait for active readers.
-	if r != 0 && atomic.AddInt32(&rw.readerWait, r) != 0 {
-		runtime_SemacquireMutex(&rw.writerSem, false, 0)
+	if r != 0 && rw.readerWait.Add(r) != 0 {
+		runtime_SemacquireRWMutex(&rw.writerSem, false, 0)
 	}
 	if race.Enabled {
 		race.Enable()
@@ -174,7 +174,7 @@
 		}
 		return false
 	}
-	if !atomic.CompareAndSwapInt32(&rw.readerCount, 0, -rwmutexMaxReaders) {
+	if !rw.readerCount.CompareAndSwap(0, -rwmutexMaxReaders) {
 		rw.w.Unlock()
 		if race.Enabled {
 			race.Enable()
@@ -203,7 +203,7 @@
 	}
 
 	// Announce to readers there is no active writer.
-	r := atomic.AddInt32(&rw.readerCount, rwmutexMaxReaders)
+	r := rw.readerCount.Add(rwmutexMaxReaders)
 	if r >= rwmutexMaxReaders {
 		race.Enable()
 		fatal("sync: Unlock of unlocked RWMutex")
diff --git a/src/sync/waitgroup.go b/src/sync/waitgroup.go
index 9f26ae1..be21417 100644
--- a/src/sync/waitgroup.go
+++ b/src/sync/waitgroup.go
@@ -23,27 +23,8 @@
 type WaitGroup struct {
 	noCopy noCopy
 
-	// 64-bit value: high 32 bits are counter, low 32 bits are waiter count.
-	// 64-bit atomic operations require 64-bit alignment, but 32-bit
-	// compilers only guarantee that 64-bit fields are 32-bit aligned.
-	// For this reason on 32 bit architectures we need to check in state()
-	// if state1 is aligned or not, and dynamically "swap" the field order if
-	// needed.
-	state1 uint64
-	state2 uint32
-}
-
-// state returns pointers to the state and sema fields stored within wg.state*.
-func (wg *WaitGroup) state() (statep *uint64, semap *uint32) {
-	if unsafe.Alignof(wg.state1) == 8 || uintptr(unsafe.Pointer(&wg.state1))%8 == 0 {
-		// state1 is 64-bit aligned: nothing to do.
-		return &wg.state1, &wg.state2
-	} else {
-		// state1 is 32-bit aligned but not 64-bit aligned: this means that
-		// (&state1)+4 is 64-bit aligned.
-		state := (*[3]uint32)(unsafe.Pointer(&wg.state1))
-		return (*uint64)(unsafe.Pointer(&state[1])), &state[0]
-	}
+	state atomic.Uint64 // high 32 bits are counter, low 32 bits are waiter count.
+	sema  uint32
 }
 
 // Add adds delta, which may be negative, to the WaitGroup counter.
@@ -60,9 +41,7 @@
 // new Add calls must happen after all previous Wait calls have returned.
 // See the WaitGroup example.
 func (wg *WaitGroup) Add(delta int) {
-	statep, semap := wg.state()
 	if race.Enabled {
-		_ = *statep // trigger nil deref early
 		if delta < 0 {
 			// Synchronize decrements with Wait.
 			race.ReleaseMerge(unsafe.Pointer(wg))
@@ -70,14 +49,14 @@
 		race.Disable()
 		defer race.Enable()
 	}
-	state := atomic.AddUint64(statep, uint64(delta)<<32)
+	state := wg.state.Add(uint64(delta) << 32)
 	v := int32(state >> 32)
 	w := uint32(state)
 	if race.Enabled && delta > 0 && v == int32(delta) {
 		// The first increment must be synchronized with Wait.
 		// Need to model this as a read, because there can be
 		// several concurrent wg.counter transitions from 0.
-		race.Read(unsafe.Pointer(semap))
+		race.Read(unsafe.Pointer(&wg.sema))
 	}
 	if v < 0 {
 		panic("sync: negative WaitGroup counter")
@@ -93,13 +72,13 @@
 	// - Adds must not happen concurrently with Wait,
 	// - Wait does not increment waiters if it sees counter == 0.
 	// Still do a cheap sanity check to detect WaitGroup misuse.
-	if *statep != state {
+	if wg.state.Load() != state {
 		panic("sync: WaitGroup misuse: Add called concurrently with Wait")
 	}
 	// Reset waiters count to 0.
-	*statep = 0
+	wg.state.Store(0)
 	for ; w != 0; w-- {
-		runtime_Semrelease(semap, false, 0)
+		runtime_Semrelease(&wg.sema, false, 0)
 	}
 }
 
@@ -110,13 +89,11 @@
 
 // Wait blocks until the WaitGroup counter is zero.
 func (wg *WaitGroup) Wait() {
-	statep, semap := wg.state()
 	if race.Enabled {
-		_ = *statep // trigger nil deref early
 		race.Disable()
 	}
 	for {
-		state := atomic.LoadUint64(statep)
+		state := wg.state.Load()
 		v := int32(state >> 32)
 		w := uint32(state)
 		if v == 0 {
@@ -128,16 +105,16 @@
 			return
 		}
 		// Increment waiters count.
-		if atomic.CompareAndSwapUint64(statep, state, state+1) {
+		if wg.state.CompareAndSwap(state, state+1) {
 			if race.Enabled && w == 0 {
 				// Wait must be synchronized with the first Add.
 				// Need to model this is as a write to race with the read in Add.
 				// As a consequence, can do the write only for the first waiter,
 				// otherwise concurrent Waits will race with each other.
-				race.Write(unsafe.Pointer(semap))
+				race.Write(unsafe.Pointer(&wg.sema))
 			}
-			runtime_Semacquire(semap)
-			if *statep != 0 {
+			runtime_Semacquire(&wg.sema)
+			if wg.state.Load() != 0 {
 				panic("sync: WaitGroup is reused before previous Wait has returned")
 			}
 			if race.Enabled {
diff --git a/src/syscall/asm_freebsd_riscv64.s b/src/syscall/asm_freebsd_riscv64.s
new file mode 100644
index 0000000..dc21f76
--- /dev/null
+++ b/src/syscall/asm_freebsd_riscv64.s
@@ -0,0 +1,125 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+//
+// System calls for riscv64, FreeBSD
+//
+
+// func Syscall(trap int64, a1, a2, a3 int64) (r1, r2, err int64)
+TEXT ·Syscall(SB),NOSPLIT,$0-56
+	CALL	runtime·entersyscall(SB)
+	MOV	a1+8(FP), A0
+	MOV	a2+16(FP), A1
+	MOV	a3+24(FP), A2
+	MOV	trap+0(FP), T0	// syscall entry
+	ECALL
+	BNE	T0, ZERO, err
+	MOV	A0, r1+32(FP)	// r1
+	MOV	A1, r2+40(FP)	// r2
+	MOV	ZERO, err+48(FP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+err:
+	MOV	$-1, T0
+	MOV	T0, r1+32(FP)	// r1
+	MOV	ZERO, r2+40(FP)	// r2
+	MOV	A0, err+48(FP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+
+// func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
+TEXT ·Syscall6(SB),NOSPLIT,$0-80
+	CALL	runtime·entersyscall(SB)
+	MOV	a1+8(FP), A0
+	MOV	a2+16(FP), A1
+	MOV	a3+24(FP), A2
+	MOV	a4+32(FP), A3
+	MOV	a5+40(FP), A4
+	MOV	a6+48(FP), A5
+	MOV	trap+0(FP), T0	// syscall entry
+	ECALL
+	BNE	T0, ZERO, err
+	MOV	A0, r1+56(FP)	// r1
+	MOV	A1, r2+64(FP)	// r2
+	MOV	ZERO, err+72(FP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+err:
+	MOV	$-1, T0
+	MOV	T0, r1+56(FP)	// r1
+	MOV	ZERO, r2+64(FP)	// r2
+	MOV	A0, err+72(FP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+// func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
+TEXT ·RawSyscall(SB),NOSPLIT,$0-56
+	MOV	a1+8(FP), A0
+	MOV	a2+16(FP), A1
+	MOV	a3+24(FP), A2
+	MOV	trap+0(FP), T0	// syscall entry
+	ECALL
+	BNE	T0, ZERO, err
+	MOV	A0, r1+32(FP)	// r1
+	MOV	A1, r2+40(FP)	// r2
+	MOV	ZERO, err+48(FP)	// errno
+	RET
+err:
+	MOV	$-1, T0
+	MOV	T0, r1+32(FP)	// r1
+	MOV	ZERO, r2+40(FP)	// r2
+	MOV	A0, err+48(FP)	// errno
+	RET
+
+// func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
+TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
+	MOV	a1+8(FP), A0
+	MOV	a2+16(FP), A1
+	MOV	a3+24(FP), A2
+	MOV	a4+32(FP), A3
+	MOV	a5+40(FP), A4
+	MOV	a6+48(FP), A5
+	MOV	trap+0(FP), T0	// syscall entry
+	ECALL
+	BNE	T0, ZERO, err
+	MOV	A0, r1+56(FP)	// r1
+	MOV	A1, r2+64(FP)	// r2
+	MOV	ZERO, err+72(FP)	// errno
+	RET
+err:
+	MOV	$-1, T0
+	MOV	T0, r1+56(FP)	// r1
+	MOV	ZERO, r2+64(FP)	// r2
+	MOV	A0, err+72(FP)	// errno
+	RET
+
+// Actually Syscall7
+// func Syscall9(num uintptr, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2, err uintptr)
+TEXT ·Syscall9(SB),NOSPLIT,$0-104
+	CALL	runtime·entersyscall(SB)
+	MOV	a1+8(FP), A0
+	MOV	a2+16(FP), A1
+	MOV	a3+24(FP), A2
+	MOV	a4+32(FP), A3
+	MOV	a5+40(FP), A4
+	MOV	a6+48(FP), A5
+	MOV	a7+56(FP), A6
+	MOV	num+0(FP), T0	// syscall entry
+	ECALL
+	BNE	T0, ZERO, err
+	MOV	A0, r1+80(FP)	// r1
+	MOV	A1, r2+88(FP)	// r2
+	MOV	ZERO, err+96(FP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+err:
+	MOV	$-1, T0
+	MOV	T0, r1+80(FP)	// r1
+	MOV	ZERO, r2+88(FP)	// r2
+	MOV	A0, err+96(FP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
diff --git a/src/syscall/asm_linux_386.s b/src/syscall/asm_linux_386.s
index e86a859..a8e63f7 100644
--- a/src/syscall/asm_linux_386.s
+++ b/src/syscall/asm_linux_386.s
@@ -13,24 +13,24 @@
 // instead of the glibc-specific "CALL 0x10(GS)".
 #define INVOKE_SYSCALL	INT	$0x80
 
-// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
-TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-16
+// func rawVforkSyscall(trap, a1, a2 uintptr) (r1, err uintptr)
+TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-20
 	MOVL	trap+0(FP), AX	// syscall entry
 	MOVL	a1+4(FP), BX
-	MOVL	$0, CX
+	MOVL	a2+8(FP), CX
 	MOVL	$0, DX
 	POPL	SI // preserve return address
 	INVOKE_SYSCALL
 	PUSHL	SI
 	CMPL	AX, $0xfffff001
 	JLS	ok
-	MOVL	$-1, r1+8(FP)
+	MOVL	$-1, r1+12(FP)
 	NEGL	AX
-	MOVL	AX, err+12(FP)
+	MOVL	AX, err+16(FP)
 	RET
 ok:
-	MOVL	AX, r1+8(FP)
-	MOVL	$0, err+12(FP)
+	MOVL	AX, r1+12(FP)
+	MOVL	$0, err+16(FP)
 	RET
 
 // func rawSyscallNoError(trap uintptr, a1, a2, a3 uintptr) (r1, r2 uintptr);
diff --git a/src/syscall/asm_linux_amd64.s b/src/syscall/asm_linux_amd64.s
index 3206a45..00d6fed 100644
--- a/src/syscall/asm_linux_amd64.s
+++ b/src/syscall/asm_linux_amd64.s
@@ -11,10 +11,10 @@
 
 #define SYS_gettimeofday 96
 
-// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
-TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-32
+// func rawVforkSyscall(trap, a1, a2 uintptr) (r1, err uintptr)
+TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-40
 	MOVQ	a1+8(FP), DI
-	MOVQ	$0, SI
+	MOVQ	a2+16(FP), SI
 	MOVQ	$0, DX
 	MOVQ	$0, R10
 	MOVQ	$0, R8
@@ -25,13 +25,13 @@
 	PUSHQ	R12
 	CMPQ	AX, $0xfffffffffffff001
 	JLS	ok2
-	MOVQ	$-1, r1+16(FP)
+	MOVQ	$-1, r1+24(FP)
 	NEGQ	AX
-	MOVQ	AX, err+24(FP)
+	MOVQ	AX, err+32(FP)
 	RET
 ok2:
-	MOVQ	AX, r1+16(FP)
-	MOVQ	$0, err+24(FP)
+	MOVQ	AX, r1+24(FP)
+	MOVQ	$0, err+32(FP)
 	RET
 
 // func rawSyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr)
diff --git a/src/syscall/asm_linux_arm.s b/src/syscall/asm_linux_arm.s
index 3252220..d399541 100644
--- a/src/syscall/asm_linux_arm.s
+++ b/src/syscall/asm_linux_arm.s
@@ -41,25 +41,25 @@
 	BL	runtime·exitsyscall(SB)
 	RET
 
-// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
-TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-16
+// func rawVforkSyscall(trap, a1, a2 uintptr) (r1, err uintptr)
+TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-20
 	MOVW	trap+0(FP), R7	// syscall entry
 	MOVW	a1+4(FP), R0
-	MOVW	$0, R1
+	MOVW	a2+8(FP), R1
 	MOVW	$0, R2
 	SWI	$0
 	MOVW	$0xfffff001, R1
 	CMP	R1, R0
 	BLS	ok
 	MOVW	$-1, R1
-	MOVW	R1, r1+8(FP)
+	MOVW	R1, r1+12(FP)
 	RSB	$0, R0, R0
-	MOVW	R0, err+12(FP)
+	MOVW	R0, err+16(FP)
 	RET
 ok:
-	MOVW	R0, r1+8(FP)
+	MOVW	R0, r1+12(FP)
 	MOVW	$0, R0
-	MOVW	R0, err+12(FP)
+	MOVW	R0, err+16(FP)
 	RET
 
 // func rawSyscallNoError(trap uintptr, a1, a2, a3 uintptr) (r1, r2 uintptr);
diff --git a/src/syscall/asm_linux_arm64.s b/src/syscall/asm_linux_arm64.s
index be78ac8..7fa789a 100644
--- a/src/syscall/asm_linux_arm64.s
+++ b/src/syscall/asm_linux_arm64.s
@@ -4,10 +4,10 @@
 
 #include "textflag.h"
 
-// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
-TEXT ·rawVforkSyscall(SB),NOSPLIT,$0-32
+// func rawVforkSyscall(trap, a1, a2 uintptr) (r1, err uintptr)
+TEXT ·rawVforkSyscall(SB),NOSPLIT,$0-40
 	MOVD	a1+8(FP), R0
-	MOVD	$0, R1
+	MOVD	a2+16(FP), R1
 	MOVD	$0, R2
 	MOVD	$0, R3
 	MOVD	$0, R4
@@ -17,13 +17,13 @@
 	CMN	$4095, R0
 	BCC	ok
 	MOVD	$-1, R4
-	MOVD	R4, r1+16(FP)	// r1
+	MOVD	R4, r1+24(FP)	// r1
 	NEG	R0, R0
-	MOVD	R0, err+24(FP)	// errno
+	MOVD	R0, err+32(FP)	// errno
 	RET
 ok:
-	MOVD	R0, r1+16(FP)	// r1
-	MOVD	ZR, err+24(FP)	// errno
+	MOVD	R0, r1+24(FP)	// r1
+	MOVD	ZR, err+32(FP)	// errno
 	RET
 
 // func rawSyscallNoError(trap uintptr, a1, a2, a3 uintptr) (r1, r2 uintptr);
diff --git a/src/syscall/asm_linux_loong64.s b/src/syscall/asm_linux_loong64.s
index 7dc69c6..1a7457c 100644
--- a/src/syscall/asm_linux_loong64.s
+++ b/src/syscall/asm_linux_loong64.s
@@ -8,10 +8,10 @@
 // System calls for loong64, Linux
 //
 
-// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
-TEXT ·rawVforkSyscall(SB),NOSPLIT,$0-32
+// func rawVforkSyscall(trap, a1, a2 uintptr) (r1, err uintptr)
+TEXT ·rawVforkSyscall(SB),NOSPLIT,$0-40
 	MOVV	a1+8(FP), R4
-	MOVV	$0, R5
+	MOVV	a2+16(FP), R5
 	MOVV	$0, R6
 	MOVV	$0, R7
 	MOVV	$0, R8
@@ -21,13 +21,13 @@
 	MOVW	$-4096, R12
 	BGEU	R12, R4, ok
 	MOVV	$-1, R12
-	MOVV	R12, r1+16(FP)		// r1
+	MOVV	R12, r1+24(FP)		// r1
 	SUBVU	R4, R0, R4
-	MOVV	R4, err+24(FP)		// errno
+	MOVV	R4, err+32(FP)		// errno
 	RET
 ok:
-	MOVV	R4, r1+16(FP)	// r1
-	MOVV	R0, err+24(FP)	// errno
+	MOVV	R4, r1+24(FP)	// r1
+	MOVV	R0, err+32(FP)	// errno
 	RET
 
 TEXT ·rawSyscallNoError(SB),NOSPLIT,$0-48
diff --git a/src/syscall/asm_linux_mips64x.s b/src/syscall/asm_linux_mips64x.s
index fadf193..6c7a6bc 100644
--- a/src/syscall/asm_linux_mips64x.s
+++ b/src/syscall/asm_linux_mips64x.s
@@ -10,10 +10,10 @@
 // System calls for mips64, Linux
 //
 
-// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
-TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-32
+// func rawVforkSyscall(trap, a1, a2 uintptr) (r1, err uintptr)
+TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-40
 	MOVV	a1+8(FP), R4
-	MOVV	R0, R5
+	MOVV	a2+16(FP), R5
 	MOVV	R0, R6
 	MOVV	R0, R7
 	MOVV	R0, R8
@@ -22,12 +22,12 @@
 	SYSCALL
 	BEQ	R7, ok
 	MOVV	$-1, R1
-	MOVV	R1, r1+16(FP)	// r1
-	MOVV	R2, err+24(FP)	// errno
+	MOVV	R1, r1+24(FP)	// r1
+	MOVV	R2, err+32(FP)	// errno
 	RET
 ok:
-	MOVV	R2, r1+16(FP)	// r1
-	MOVV	R0, err+24(FP)	// errno
+	MOVV	R2, r1+24(FP)	// r1
+	MOVV	R0, err+32(FP)	// errno
 	RET
 
 TEXT ·rawSyscallNoError(SB),NOSPLIT,$0-48
@@ -38,7 +38,8 @@
 	MOVV	R0, R8
 	MOVV	R0, R9
 	MOVV	trap+0(FP), R2	// syscall entry
+	MOVV	R0, R3	// reset R3 to zero as 1-ret SYSCALL keeps it
 	SYSCALL
-	MOVV	R2, r1+32(FP)
-	MOVV	R3, r2+40(FP)
+	MOVV	R2, r1+32(FP)	// r1
+	MOVV	R3, r2+40(FP)	// r2
 	RET
diff --git a/src/syscall/asm_linux_mipsx.s b/src/syscall/asm_linux_mipsx.s
index b8cae96..99f0154 100644
--- a/src/syscall/asm_linux_mipsx.s
+++ b/src/syscall/asm_linux_mipsx.s
@@ -29,6 +29,7 @@
 	MOVW	R10, 24(R29)
 	MOVW	R11, 28(R29)
 	MOVW	trap+0(FP), R2	// syscall entry
+	MOVW	R0, R3	// reset R3 to zero as 1-ret SYSCALL keeps it
 	SYSCALL
 	BEQ	R7, ok9
 	MOVW	$-1, R1
@@ -44,21 +45,21 @@
 	JAL	runtime·exitsyscall(SB)
 	RET
 
-// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
-TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-16
+// func rawVforkSyscall(trap, a1, a2 uintptr) (r1, err uintptr)
+TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-20
 	MOVW	a1+4(FP), R4
-	MOVW	R0, R5
+	MOVW	a2+8(FP), R5
 	MOVW	R0, R6
 	MOVW	trap+0(FP), R2	// syscall entry
 	SYSCALL
 	BEQ	R7, ok
 	MOVW	$-1, R1
-	MOVW	R1, r1+8(FP)	// r1
-	MOVW	R2, err+12(FP)	// errno
+	MOVW	R1, r1+12(FP)	// r1
+	MOVW	R2, err+16(FP)	// errno
 	RET
 ok:
-	MOVW	R2, r1+8(FP)	// r1
-	MOVW	R0, err+12(FP)	// errno
+	MOVW	R2, r1+12(FP)	// r1
+	MOVW	R0, err+16(FP)	// errno
 	RET
 
 TEXT ·rawSyscallNoError(SB),NOSPLIT,$20-24
@@ -66,6 +67,7 @@
 	MOVW	a2+8(FP), R5
 	MOVW	a3+12(FP), R6
 	MOVW	trap+0(FP), R2	// syscall entry
+	MOVW	R0, R3	// reset R3 to zero as 1-ret SYSCALL keeps it
 	SYSCALL
 	MOVW	R2, r1+16(FP)	// r1
 	MOVW	R3, r2+20(FP)	// r2
diff --git a/src/syscall/asm_linux_ppc64x.s b/src/syscall/asm_linux_ppc64x.s
index 89cc1c2..b9412fe 100644
--- a/src/syscall/asm_linux_ppc64x.s
+++ b/src/syscall/asm_linux_ppc64x.s
@@ -10,10 +10,10 @@
 // System calls for ppc64, Linux
 //
 
-// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
-TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-32
+// func rawVforkSyscall(trap, a1, a2 uintptr) (r1, err uintptr)
+TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-40
 	MOVD	a1+8(FP), R3
-	MOVD	R0, R4
+	MOVD	a2+16(FP), R4
 	MOVD	R0, R5
 	MOVD	R0, R6
 	MOVD	R0, R7
@@ -22,12 +22,12 @@
 	SYSCALL R9
 	BVC	ok
 	MOVD	$-1, R4
-	MOVD	R4, r1+16(FP)	// r1
-	MOVD	R3, err+24(FP)	// errno
+	MOVD	R4, r1+24(FP)	// r1
+	MOVD	R3, err+32(FP)	// errno
 	RET
 ok:
-	MOVD	R3, r1+16(FP)	// r1
-	MOVD	R0, err+24(FP)	// errno
+	MOVD	R3, r1+24(FP)	// r1
+	MOVD	R0, err+32(FP)	// errno
 	RET
 
 TEXT ·rawSyscallNoError(SB),NOSPLIT,$0-48
diff --git a/src/syscall/asm_linux_riscv64.s b/src/syscall/asm_linux_riscv64.s
index 0fc1f73..6fd09ec 100644
--- a/src/syscall/asm_linux_riscv64.s
+++ b/src/syscall/asm_linux_riscv64.s
@@ -8,10 +8,10 @@
 // System calls for riscv64, Linux
 //
 
-// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
-TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-32
+// func rawVforkSyscall(trap, a1, a2 uintptr) (r1, err uintptr)
+TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-40
 	MOV	a1+8(FP), A0
-	MOV	ZERO, A1
+	MOV	a2+16(FP), A1
 	MOV	ZERO, A2
 	MOV	ZERO, A3
 	MOV	ZERO, A4
@@ -20,14 +20,14 @@
 	ECALL
 	MOV	$-4096, T0
 	BLTU	T0, A0, err
-	MOV	A0, r1+16(FP)	// r1
-	MOV	ZERO, err+24(FP)	// errno
+	MOV	A0, r1+24(FP)	// r1
+	MOV	ZERO, err+32(FP)	// errno
 	RET
 err:
 	MOV	$-1, T0
-	MOV	T0, r1+16(FP)	// r1
+	MOV	T0, r1+24(FP)	// r1
 	SUB	A0, ZERO, A0
-	MOV	A0, err+24(FP)	// errno
+	MOV	A0, err+32(FP)	// errno
 	RET
 
 TEXT ·rawSyscallNoError(SB),NOSPLIT,$0-48
diff --git a/src/syscall/asm_linux_s390x.s b/src/syscall/asm_linux_s390x.s
index c3631c1..41c34b1 100644
--- a/src/syscall/asm_linux_s390x.s
+++ b/src/syscall/asm_linux_s390x.s
@@ -8,10 +8,10 @@
 // System calls for s390x, Linux
 //
 
-// func rawVforkSyscall(trap, a1 uintptr) (r1, err uintptr)
-TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-32
-	MOVD	$0, R2
-	MOVD	a1+8(FP), R3
+// func rawVforkSyscall(trap, a1, a2 uintptr) (r1, err uintptr)
+TEXT ·rawVforkSyscall(SB),NOSPLIT|NOFRAME,$0-40
+	MOVD	a1+8(FP), R2
+	MOVD	a2+16(FP), R3
 	MOVD	$0, R4
 	MOVD	$0, R5
 	MOVD	$0, R6
@@ -20,13 +20,13 @@
 	SYSCALL
 	MOVD	$0xfffffffffffff001, R8
 	CMPUBLT	R2, R8, ok2
-	MOVD	$-1, r1+16(FP)
+	MOVD	$-1, r1+24(FP)
 	NEG	R2, R2
-	MOVD	R2, err+24(FP)	// errno
+	MOVD	R2, err+32(FP)	// errno
 	RET
 ok2:
-	MOVD	R2, r1+16(FP)
-	MOVD	$0, err+24(FP)	// errno
+	MOVD	R2, r1+24(FP)
+	MOVD	$0, err+32(FP)	// errno
 	RET
 
 // func rawSyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr)
diff --git a/src/syscall/asm_solaris_amd64.s b/src/syscall/asm_solaris_amd64.s
index 3672d36..6891e9c 100644
--- a/src/syscall/asm_solaris_amd64.s
+++ b/src/syscall/asm_solaris_amd64.s
@@ -20,7 +20,7 @@
 TEXT ·chroot1(SB),NOSPLIT,$0
 	JMP	runtime·syscall_chroot(SB)
 
-TEXT ·close(SB),NOSPLIT,$0
+TEXT ·closeFD(SB),NOSPLIT,$0
 	JMP	runtime·syscall_close(SB)
 
 TEXT ·dup2child(SB),NOSPLIT,$0
diff --git a/src/syscall/const_plan9.go b/src/syscall/const_plan9.go
index 063d5df..64a4b50 100644
--- a/src/syscall/const_plan9.go
+++ b/src/syscall/const_plan9.go
@@ -1,3 +1,7 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
 package syscall
 
 // Plan 9 Constants
diff --git a/src/syscall/env_unix.go b/src/syscall/env_unix.go
index 67e6c5f..6d917da 100644
--- a/src/syscall/env_unix.go
+++ b/src/syscall/env_unix.go
@@ -31,11 +31,6 @@
 
 func runtime_envs() []string // in package runtime
 
-// setenv_c and unsetenv_c are provided by the runtime but are no-ops
-// if cgo isn't loaded.
-func setenv_c(k, v string)
-func unsetenv_c(k string)
-
 func copyenv() {
 	env = make(map[string]int)
 	for i, s := range envs {
@@ -67,7 +62,7 @@
 		envs[i] = ""
 		delete(env, key)
 	}
-	unsetenv_c(key)
+	runtimeUnsetenv(key)
 	return nil
 }
 
@@ -124,7 +119,7 @@
 		envs = append(envs, kv)
 	}
 	env[key] = i
-	setenv_c(key, value)
+	runtimeSetenv(key, value)
 	return nil
 }
 
@@ -135,7 +130,7 @@
 	defer envLock.Unlock()
 
 	for k := range env {
-		unsetenv_c(k)
+		runtimeUnsetenv(k)
 	}
 	env = make(map[string]int)
 	envs = []string{}
diff --git a/src/syscall/env_windows.go b/src/syscall/env_windows.go
index 74b154e..94364f9 100644
--- a/src/syscall/env_windows.go
+++ b/src/syscall/env_windows.go
@@ -42,6 +42,7 @@
 	if e != nil {
 		return e
 	}
+	runtimeSetenv(key, value)
 	return nil
 }
 
@@ -50,7 +51,12 @@
 	if err != nil {
 		return err
 	}
-	return SetEnvironmentVariable(keyp, nil)
+	e := SetEnvironmentVariable(keyp, nil)
+	if e != nil {
+		return e
+	}
+	runtimeUnsetenv(key)
+	return nil
 }
 
 func Clearenv() {
@@ -68,21 +74,24 @@
 }
 
 func Environ() []string {
-	s, e := GetEnvironmentStrings()
+	envp, e := GetEnvironmentStrings()
 	if e != nil {
 		return nil
 	}
-	defer FreeEnvironmentStrings(s)
+	defer FreeEnvironmentStrings(envp)
+
 	r := make([]string, 0, 50) // Empty with room to grow.
-	for from, i, p := 0, 0, (*[1 << 24]uint16)(unsafe.Pointer(s)); true; i++ {
-		if p[i] == 0 {
-			// empty string marks the end
-			if i <= from {
-				break
-			}
-			r = append(r, string(utf16.Decode(p[from:i])))
-			from = i + 1
+	const size = unsafe.Sizeof(*envp)
+	for *envp != 0 { // environment block ends with empty string
+		// find NUL terminator
+		end := unsafe.Pointer(envp)
+		for *(*uint16)(end) != 0 {
+			end = unsafe.Add(end, size)
 		}
+
+		entry := unsafe.Slice(envp, (uintptr(end)-uintptr(unsafe.Pointer(envp)))/size)
+		r = append(r, string(utf16.Decode(entry)))
+		envp = (*uint16)(unsafe.Add(end, size))
 	}
 	return r
 }
diff --git a/src/syscall/exec_bsd.go b/src/syscall/exec_bsd.go
index 4762ae7..32c3ebd 100644
--- a/src/syscall/exec_bsd.go
+++ b/src/syscall/exec_bsd.go
@@ -184,6 +184,8 @@
 	if pipe < nextfd {
 		if runtime.GOOS == "netbsd" || (runtime.GOOS == "openbsd" && runtime.GOARCH == "mips64") {
 			_, _, err1 = RawSyscall(_SYS_DUP3, uintptr(pipe), uintptr(nextfd), O_CLOEXEC)
+		} else if runtime.GOOS == "dragonfly" {
+			_, _, err1 = RawSyscall(SYS_FCNTL, uintptr(pipe), _F_DUP2FD_CLOEXEC, uintptr(nextfd))
 		} else {
 			_, _, err1 = RawSyscall(SYS_DUP2, uintptr(pipe), uintptr(nextfd), 0)
 			if err1 != 0 {
@@ -198,12 +200,14 @@
 		nextfd++
 	}
 	for i = 0; i < len(fd); i++ {
-		if fd[i] >= 0 && fd[i] < int(i) {
+		if fd[i] >= 0 && fd[i] < i {
 			if nextfd == pipe { // don't stomp on pipe
 				nextfd++
 			}
 			if runtime.GOOS == "netbsd" || (runtime.GOOS == "openbsd" && runtime.GOARCH == "mips64") {
 				_, _, err1 = RawSyscall(_SYS_DUP3, uintptr(fd[i]), uintptr(nextfd), O_CLOEXEC)
+			} else if runtime.GOOS == "dragonfly" {
+				_, _, err1 = RawSyscall(SYS_FCNTL, uintptr(fd[i]), _F_DUP2FD_CLOEXEC, uintptr(nextfd))
 			} else {
 				_, _, err1 = RawSyscall(SYS_DUP2, uintptr(fd[i]), uintptr(nextfd), 0)
 				if err1 != 0 {
@@ -225,7 +229,7 @@
 			RawSyscall(SYS_CLOSE, uintptr(i), 0, 0)
 			continue
 		}
-		if fd[i] == int(i) {
+		if fd[i] == i {
 			// dup2(i, i) won't clear close-on-exec flag on Linux,
 			// probably not elsewhere either.
 			_, _, err1 = RawSyscall(SYS_FCNTL, uintptr(fd[i]), F_SETFD, 0)
diff --git a/src/syscall/exec_freebsd.go b/src/syscall/exec_freebsd.go
index 851b8fb..af5a415 100644
--- a/src/syscall/exec_freebsd.go
+++ b/src/syscall/exec_freebsd.go
@@ -205,7 +205,7 @@
 		r1, _, _ = RawSyscall(SYS_GETPPID, 0, 0, 0)
 		if r1 != ppid {
 			pid, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
-			_, _, err1 := RawSyscall(SYS_KILL, pid, uintptr(sys.Pdeathsig), 0)
+			_, _, err1 = RawSyscall(SYS_KILL, pid, uintptr(sys.Pdeathsig), 0)
 			if err1 != 0 {
 				goto childerror
 			}
@@ -223,7 +223,7 @@
 		nextfd++
 	}
 	for i = 0; i < len(fd); i++ {
-		if fd[i] >= 0 && fd[i] < int(i) {
+		if fd[i] >= 0 && fd[i] < i {
 			if nextfd == pipe { // don't stomp on pipe
 				nextfd++
 			}
@@ -242,7 +242,7 @@
 			RawSyscall(SYS_CLOSE, uintptr(i), 0, 0)
 			continue
 		}
-		if fd[i] == int(i) {
+		if fd[i] == i {
 			// dup2(i, i) won't clear close-on-exec flag on Linux,
 			// probably not elsewhere either.
 			_, _, err1 = RawSyscall(SYS_FCNTL, uintptr(fd[i]), F_SETFD, 0)
diff --git a/src/syscall/exec_libc.go b/src/syscall/exec_libc.go
index aee1b8c..ef0c87e 100644
--- a/src/syscall/exec_libc.go
+++ b/src/syscall/exec_libc.go
@@ -43,7 +43,7 @@
 
 func chdir(path uintptr) (err Errno)
 func chroot1(path uintptr) (err Errno)
-func close(fd uintptr) (err Errno)
+func closeFD(fd uintptr) (err Errno)
 func dup2child(old uintptr, new uintptr) (val uintptr, err Errno)
 func execve(path uintptr, argv uintptr, envp uintptr) (err Errno)
 func exit(code uintptr)
@@ -199,7 +199,7 @@
 	// so that pass 2 won't stomp on an fd it needs later.
 	if pipe < nextfd {
 		switch runtime.GOOS {
-		case "illumos":
+		case "illumos", "solaris":
 			_, err1 = fcntl1(uintptr(pipe), _F_DUP2FD_CLOEXEC, uintptr(nextfd))
 		default:
 			_, err1 = dup2child(uintptr(pipe), uintptr(nextfd))
@@ -215,12 +215,12 @@
 		nextfd++
 	}
 	for i = 0; i < len(fd); i++ {
-		if fd[i] >= 0 && fd[i] < int(i) {
+		if fd[i] >= 0 && fd[i] < i {
 			if nextfd == pipe { // don't stomp on pipe
 				nextfd++
 			}
 			switch runtime.GOOS {
-			case "illumos":
+			case "illumos", "solaris":
 				_, err1 = fcntl1(uintptr(fd[i]), _F_DUP2FD_CLOEXEC, uintptr(nextfd))
 			default:
 				_, err1 = dup2child(uintptr(fd[i]), uintptr(nextfd))
@@ -240,10 +240,10 @@
 	// Pass 2: dup fd[i] down onto i.
 	for i = 0; i < len(fd); i++ {
 		if fd[i] == -1 {
-			close(uintptr(i))
+			closeFD(uintptr(i))
 			continue
 		}
-		if fd[i] == int(i) {
+		if fd[i] == i {
 			// dup2(i, i) won't clear close-on-exec flag on Linux,
 			// probably not elsewhere either.
 			_, err1 = fcntl1(uintptr(fd[i]), F_SETFD, 0)
@@ -265,7 +265,7 @@
 	// Programs that know they inherit fds >= 3 will need
 	// to set them close-on-exec.
 	for i = len(fd); i < 3; i++ {
-		close(uintptr(i))
+		closeFD(uintptr(i))
 	}
 
 	// Detach fd 0 from tty
diff --git a/src/syscall/exec_libc2.go b/src/syscall/exec_libc2.go
index 9eb61a5..41bc79a 100644
--- a/src/syscall/exec_libc2.go
+++ b/src/syscall/exec_libc2.go
@@ -198,7 +198,7 @@
 		nextfd++
 	}
 	for i = 0; i < len(fd); i++ {
-		if fd[i] >= 0 && fd[i] < int(i) {
+		if fd[i] >= 0 && fd[i] < i {
 			if nextfd == pipe { // don't stomp on pipe
 				nextfd++
 			}
@@ -225,7 +225,7 @@
 			rawSyscall(abi.FuncPCABI0(libc_close_trampoline), uintptr(i), 0, 0)
 			continue
 		}
-		if fd[i] == int(i) {
+		if fd[i] == i {
 			// dup2(i, i) won't clear close-on-exec flag on Linux,
 			// probably not elsewhere either.
 			_, _, err1 = rawSyscall(abi.FuncPCABI0(libc_fcntl_trampoline), uintptr(fd[i]), F_SETFD, 0)
diff --git a/src/syscall/exec_linux.go b/src/syscall/exec_linux.go
index 554aad4..7e0c3d2 100644
--- a/src/syscall/exec_linux.go
+++ b/src/syscall/exec_linux.go
@@ -12,6 +12,45 @@
 	"unsafe"
 )
 
+// Linux unshare/clone/clone2/clone3 flags, architecture-independent,
+// copied from linux/sched.h.
+const (
+	CLONE_VM             = 0x00000100 // set if VM shared between processes
+	CLONE_FS             = 0x00000200 // set if fs info shared between processes
+	CLONE_FILES          = 0x00000400 // set if open files shared between processes
+	CLONE_SIGHAND        = 0x00000800 // set if signal handlers and blocked signals shared
+	CLONE_PIDFD          = 0x00001000 // set if a pidfd should be placed in parent
+	CLONE_PTRACE         = 0x00002000 // set if we want to let tracing continue on the child too
+	CLONE_VFORK          = 0x00004000 // set if the parent wants the child to wake it up on mm_release
+	CLONE_PARENT         = 0x00008000 // set if we want to have the same parent as the cloner
+	CLONE_THREAD         = 0x00010000 // Same thread group?
+	CLONE_NEWNS          = 0x00020000 // New mount namespace group
+	CLONE_SYSVSEM        = 0x00040000 // share system V SEM_UNDO semantics
+	CLONE_SETTLS         = 0x00080000 // create a new TLS for the child
+	CLONE_PARENT_SETTID  = 0x00100000 // set the TID in the parent
+	CLONE_CHILD_CLEARTID = 0x00200000 // clear the TID in the child
+	CLONE_DETACHED       = 0x00400000 // Unused, ignored
+	CLONE_UNTRACED       = 0x00800000 // set if the tracing process can't force CLONE_PTRACE on this clone
+	CLONE_CHILD_SETTID   = 0x01000000 // set the TID in the child
+	CLONE_NEWCGROUP      = 0x02000000 // New cgroup namespace
+	CLONE_NEWUTS         = 0x04000000 // New utsname namespace
+	CLONE_NEWIPC         = 0x08000000 // New ipc namespace
+	CLONE_NEWUSER        = 0x10000000 // New user namespace
+	CLONE_NEWPID         = 0x20000000 // New pid namespace
+	CLONE_NEWNET         = 0x40000000 // New network namespace
+	CLONE_IO             = 0x80000000 // Clone io context
+
+	// Flags for the clone3() syscall.
+
+	CLONE_CLEAR_SIGHAND = 0x100000000 // Clear any signal handler and reset to SIG_DFL.
+	CLONE_INTO_CGROUP   = 0x200000000 // Clone into a specific cgroup given the right permissions.
+
+	// Cloning flags intersect with CSIGNAL so can be used with unshare and clone3
+	// syscalls only:
+
+	CLONE_NEWTIME = 0x00000080 // New time namespace
+)
+
 // SysProcIDMap holds Container ID to Host ID mappings used for User Namespaces in Linux.
 // See user_namespaces(7).
 type SysProcIDMap struct {
@@ -60,6 +99,8 @@
 	// users this should be set to false for mappings work.
 	GidMappingsEnableSetgroups bool
 	AmbientCaps                []uintptr // Ambient capabilities (Linux only)
+	UseCgroupFD                bool      // Whether to make use of the CgroupFD field.
+	CgroupFD                   int       // File descriptor of a cgroup to put the new process into.
 }
 
 var (
@@ -137,6 +178,21 @@
 // See CAP_TO_MASK in linux/capability.h:
 func capToMask(cap uintptr) uint32 { return 1 << uint(cap&31) }
 
+// cloneArgs holds arguments for clone3 Linux syscall.
+type cloneArgs struct {
+	flags      uint64 // Flags bit mask
+	pidFD      uint64 // Where to store PID file descriptor (int *)
+	childTID   uint64 // Where to store child TID, in child's memory (pid_t *)
+	parentTID  uint64 // Where to store child TID, in parent's memory (pid_t *)
+	exitSignal uint64 // Signal to deliver to parent on child termination
+	stack      uint64 // Pointer to lowest byte of stack
+	stackSize  uint64 // Size of stack
+	tls        uint64 // Location of new TLS
+	setTID     uint64 // Pointer to a pid_t array (since Linux 5.5)
+	setTIDSize uint64 // Number of elements in set_tid (since Linux 5.5)
+	cgroup     uint64 // File descriptor for target cgroup of child (since Linux 5.7)
+}
+
 // forkAndExecInChild1 implements the body of forkAndExecInChild up to
 // the parent's post-fork path. This is a separate function so we can
 // separate the child's and parent's stack frames if we're using
@@ -166,9 +222,10 @@
 		nextfd                    int
 		i                         int
 		caps                      caps
-		fd1                       uintptr
+		fd1, flags                uintptr
 		puid, psetgroups, pgid    []byte
 		uidmap, setgroups, gidmap []byte
+		clone3                    *cloneArgs
 	)
 
 	if sys.UidMappings != nil {
@@ -213,17 +270,33 @@
 		}
 	}
 
+	flags = sys.Cloneflags
+	if sys.Cloneflags&CLONE_NEWUSER == 0 && sys.Unshareflags&CLONE_NEWUSER == 0 {
+		flags |= CLONE_VFORK | CLONE_VM
+	}
+	// Whether to use clone3.
+	if sys.UseCgroupFD {
+		clone3 = &cloneArgs{
+			flags:      uint64(flags) | CLONE_INTO_CGROUP,
+			exitSignal: uint64(SIGCHLD),
+			cgroup:     uint64(sys.CgroupFD),
+		}
+	}
+
 	// About to call fork.
 	// No more allocation or calls of non-assembly functions.
 	runtime_BeforeFork()
 	locked = true
-	switch {
-	case sys.Cloneflags&CLONE_NEWUSER == 0 && sys.Unshareflags&CLONE_NEWUSER == 0:
-		r1, err1 = rawVforkSyscall(SYS_CLONE, uintptr(SIGCHLD|CLONE_VFORK|CLONE_VM)|sys.Cloneflags)
-	case runtime.GOARCH == "s390x":
-		r1, _, err1 = RawSyscall6(SYS_CLONE, 0, uintptr(SIGCHLD)|sys.Cloneflags, 0, 0, 0, 0)
-	default:
-		r1, _, err1 = RawSyscall6(SYS_CLONE, uintptr(SIGCHLD)|sys.Cloneflags, 0, 0, 0, 0, 0)
+	if clone3 != nil {
+		r1, err1 = rawVforkSyscall(_SYS_clone3, uintptr(unsafe.Pointer(clone3)), unsafe.Sizeof(*clone3))
+	} else {
+		flags |= uintptr(SIGCHLD)
+		if runtime.GOARCH == "s390x" {
+			// On Linux/s390, the first two arguments of clone(2) are swapped.
+			r1, err1 = rawVforkSyscall(SYS_CLONE, 0, flags)
+		} else {
+			r1, err1 = rawVforkSyscall(SYS_CLONE, flags, 0)
+		}
 	}
 	if err1 != 0 || r1 != 0 {
 		// If we're in the parent, we must return immediately
@@ -397,7 +470,7 @@
 		// so it is safe to always use _LINUX_CAPABILITY_VERSION_3.
 		caps.hdr.version = _LINUX_CAPABILITY_VERSION_3
 
-		if _, _, err1 := RawSyscall(SYS_CAPGET, uintptr(unsafe.Pointer(&caps.hdr)), uintptr(unsafe.Pointer(&caps.data[0])), 0); err1 != 0 {
+		if _, _, err1 = RawSyscall(SYS_CAPGET, uintptr(unsafe.Pointer(&caps.hdr)), uintptr(unsafe.Pointer(&caps.data[0])), 0); err1 != 0 {
 			goto childerror
 		}
 
@@ -408,7 +481,7 @@
 			caps.data[capToIndex(c)].inheritable |= capToMask(c)
 		}
 
-		if _, _, err1 := RawSyscall(SYS_CAPSET, uintptr(unsafe.Pointer(&caps.hdr)), uintptr(unsafe.Pointer(&caps.data[0])), 0); err1 != 0 {
+		if _, _, err1 = RawSyscall(SYS_CAPSET, uintptr(unsafe.Pointer(&caps.hdr)), uintptr(unsafe.Pointer(&caps.data[0])), 0); err1 != 0 {
 			goto childerror
 		}
 
@@ -441,7 +514,7 @@
 		r1, _ = rawSyscallNoError(SYS_GETPPID, 0, 0, 0)
 		if r1 != ppid {
 			pid, _ := rawSyscallNoError(SYS_GETPID, 0, 0, 0)
-			_, _, err1 := RawSyscall(SYS_KILL, pid, uintptr(sys.Pdeathsig), 0)
+			_, _, err1 = RawSyscall(SYS_KILL, pid, uintptr(sys.Pdeathsig), 0)
 			if err1 != 0 {
 				goto childerror
 			}
@@ -459,7 +532,7 @@
 		nextfd++
 	}
 	for i = 0; i < len(fd); i++ {
-		if fd[i] >= 0 && fd[i] < int(i) {
+		if fd[i] >= 0 && fd[i] < i {
 			if nextfd == pipe { // don't stomp on pipe
 				nextfd++
 			}
@@ -478,7 +551,7 @@
 			RawSyscall(SYS_CLOSE, uintptr(i), 0, 0)
 			continue
 		}
-		if fd[i] == int(i) {
+		if fd[i] == i {
 			// dup2(i, i) won't clear close-on-exec flag on Linux,
 			// probably not elsewhere either.
 			_, _, err1 = RawSyscall(fcntl64Syscall, uintptr(fd[i]), F_SETFD, 0)
@@ -551,7 +624,7 @@
 func formatIDMappings(idMap []SysProcIDMap) []byte {
 	var data []byte
 	for _, im := range idMap {
-		data = append(data, []byte(itoa.Itoa(im.ContainerID)+" "+itoa.Itoa(im.HostID)+" "+itoa.Itoa(im.Size)+"\n")...)
+		data = append(data, itoa.Itoa(im.ContainerID)+" "+itoa.Itoa(im.HostID)+" "+itoa.Itoa(im.Size)+"\n"...)
 	}
 	return data
 }
diff --git a/src/syscall/exec_linux_test.go b/src/syscall/exec_linux_test.go
index 0ec9c4d..a6900f9 100644
--- a/src/syscall/exec_linux_test.go
+++ b/src/syscall/exec_linux_test.go
@@ -7,6 +7,8 @@
 package syscall_test
 
 import (
+	"bytes"
+	"errors"
 	"flag"
 	"fmt"
 	"internal/testenv"
@@ -14,6 +16,7 @@
 	"os"
 	"os/exec"
 	"os/user"
+	"path"
 	"path/filepath"
 	"runtime"
 	"strconv"
@@ -65,6 +68,10 @@
 	// Skip the test if the sysctl that prevents unprivileged user
 	// from creating user namespaces is enabled.
 	data, errRead := os.ReadFile("/proc/sys/kernel/unprivileged_userns_clone")
+	if os.IsNotExist(errRead) {
+		// This file is only available in some Debian/Ubuntu kernels.
+		return
+	}
 	if errRead != nil || len(data) < 1 || data[0] == '0' {
 		t.Skip("kernel prohibits user namespace in unprivileged process")
 	}
@@ -457,6 +464,98 @@
 	}
 }
 
+func prepareCgroupFD(t *testing.T) (int, string) {
+	t.Helper()
+
+	const O_PATH = 0x200000 // Same for all architectures, but for some reason not defined in syscall for 386||amd64.
+
+	// Requires cgroup v2.
+	const prefix = "/sys/fs/cgroup"
+	selfCg, err := os.ReadFile("/proc/self/cgroup")
+	if err != nil {
+		if os.IsNotExist(err) || os.IsPermission(err) {
+			t.Skip(err)
+		}
+		t.Fatal(err)
+	}
+
+	// Expect a single line like this:
+	// 0::/user.slice/user-1000.slice/[email protected]/app.slice/vte-spawn-891992a2-efbb-4f28-aedb-b24f9e706770.scope
+	// Otherwise it's either cgroup v1 or a hybrid hierarchy.
+	if bytes.Count(selfCg, []byte("\n")) > 1 {
+		t.Skip("cgroup v2 not available")
+	}
+	cg := bytes.TrimPrefix(selfCg, []byte("0::"))
+	if len(cg) == len(selfCg) { // No prefix found.
+		t.Skipf("cgroup v2 not available (/proc/self/cgroup contents: %q)", selfCg)
+	}
+
+	// Need clone3 with CLONE_INTO_CGROUP support.
+	_, err = syscall.ForkExec("non-existent binary", nil, &syscall.ProcAttr{
+		Sys: &syscall.SysProcAttr{
+			UseCgroupFD: true,
+			CgroupFD:    -1,
+		},
+	})
+	// // EPERM can be returned if clone3 is not enabled by seccomp.
+	if err == syscall.ENOSYS || err == syscall.EPERM {
+		t.Skipf("clone3 with CLONE_INTO_CGROUP not available: %v", err)
+	}
+
+	// Need an ability to create a sub-cgroup.
+	subCgroup, err := os.MkdirTemp(prefix+string(bytes.TrimSpace(cg)), "subcg-")
+	if err != nil {
+		// ErrPermission or EROFS (#57262) when running in an unprivileged container.
+		// ErrNotExist when cgroupfs is not mounted in chroot/schroot.
+		if os.IsNotExist(err) || os.IsPermission(err) || errors.Is(err, syscall.EROFS) {
+			t.Skip(err)
+		}
+		t.Fatal(err)
+	}
+	t.Cleanup(func() { syscall.Rmdir(subCgroup) })
+
+	cgroupFD, err := syscall.Open(subCgroup, O_PATH, 0)
+	if err != nil {
+		t.Fatal(&os.PathError{Op: "open", Path: subCgroup, Err: err})
+	}
+	t.Cleanup(func() { syscall.Close(cgroupFD) })
+
+	return cgroupFD, "/" + path.Base(subCgroup)
+}
+
+func TestUseCgroupFD(t *testing.T) {
+	fd, suffix := prepareCgroupFD(t)
+
+	cmd := exec.Command(os.Args[0], "-test.run=TestUseCgroupFDHelper")
+	cmd.Env = append(os.Environ(), "GO_WANT_HELPER_PROCESS=1")
+	cmd.SysProcAttr = &syscall.SysProcAttr{
+		UseCgroupFD: true,
+		CgroupFD:    fd,
+	}
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		t.Fatalf("Cmd failed with err %v, output: %s", err, out)
+	}
+	// NB: this wouldn't work with cgroupns.
+	if !bytes.HasSuffix(bytes.TrimSpace(out), []byte(suffix)) {
+		t.Fatalf("got: %q, want: a line that ends with %q", out, suffix)
+	}
+}
+
+func TestUseCgroupFDHelper(*testing.T) {
+	if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
+		return
+	}
+	defer os.Exit(0)
+	// Read and print own cgroup path.
+	selfCg, err := os.ReadFile("/proc/self/cgroup")
+	if err != nil {
+		fmt.Fprintln(os.Stderr, err)
+		os.Exit(2)
+	}
+	fmt.Print(string(selfCg))
+}
+
 type capHeader struct {
 	version uint32
 	pid     int32
diff --git a/src/syscall/exec_plan9.go b/src/syscall/exec_plan9.go
index 6680e6f..8f28b5a 100644
--- a/src/syscall/exec_plan9.go
+++ b/src/syscall/exec_plan9.go
@@ -245,7 +245,7 @@
 		nextfd++
 	}
 	for i = 0; i < len(fd); i++ {
-		if fd[i] >= 0 && fd[i] < int(i) {
+		if fd[i] >= 0 && fd[i] < i {
 			if nextfd == pipe { // don't stomp on pipe
 				nextfd++
 			}
@@ -265,7 +265,7 @@
 			RawSyscall(SYS_CLOSE, uintptr(i), 0, 0)
 			continue
 		}
-		if fd[i] == int(i) {
+		if fd[i] == i {
 			continue
 		}
 		r1, _, _ = RawSyscall(SYS_DUP, uintptr(fd[i]), uintptr(i), 0)
@@ -276,7 +276,7 @@
 
 	// Pass 3: close fd[i] if it was moved in the previous pass.
 	for i = 0; i < len(fd); i++ {
-		if fd[i] >= 0 && fd[i] != int(i) {
+		if fd[i] >= len(fd) {
 			RawSyscall(SYS_CLOSE, uintptr(fd[i]), 0, 0)
 		}
 	}
diff --git a/src/syscall/exec_windows.go b/src/syscall/exec_windows.go
index 92464e0..45295de 100644
--- a/src/syscall/exec_windows.go
+++ b/src/syscall/exec_windows.go
@@ -7,6 +7,7 @@
 package syscall
 
 import (
+	"internal/bytealg"
 	"runtime"
 	"sync"
 	"unicode/utf16"
@@ -115,12 +116,16 @@
 // the representation required by CreateProcess: a sequence of NUL
 // terminated strings followed by a nil.
 // Last bytes are two UCS-2 NULs, or four NUL bytes.
-func createEnvBlock(envv []string) *uint16 {
+// If any string contains a NUL, it returns (nil, EINVAL).
+func createEnvBlock(envv []string) (*uint16, error) {
 	if len(envv) == 0 {
-		return &utf16.Encode([]rune("\x00\x00"))[0]
+		return &utf16.Encode([]rune("\x00\x00"))[0], nil
 	}
 	length := 0
 	for _, s := range envv {
+		if bytealg.IndexByteString(s, 0) != -1 {
+			return nil, EINVAL
+		}
 		length += len(s) + 1
 	}
 	length += 1
@@ -135,7 +140,7 @@
 	}
 	copy(b[i:i+1], []byte{0})
 
-	return &utf16.Encode([]rune(string(b)))[0]
+	return &utf16.Encode([]rune(string(b)))[0], nil
 }
 
 func CloseOnExec(fd Handle) {
@@ -400,12 +405,17 @@
 		}
 	}
 
+	envBlock, err := createEnvBlock(attr.Env)
+	if err != nil {
+		return 0, 0, err
+	}
+
 	pi := new(ProcessInformation)
 	flags := sys.CreationFlags | CREATE_UNICODE_ENVIRONMENT | _EXTENDED_STARTUPINFO_PRESENT
 	if sys.Token != 0 {
-		err = CreateProcessAsUser(sys.Token, argv0p, argvp, sys.ProcessAttributes, sys.ThreadAttributes, willInheritHandles, flags, createEnvBlock(attr.Env), dirp, &si.StartupInfo, pi)
+		err = CreateProcessAsUser(sys.Token, argv0p, argvp, sys.ProcessAttributes, sys.ThreadAttributes, willInheritHandles, flags, envBlock, dirp, &si.StartupInfo, pi)
 	} else {
-		err = CreateProcess(argv0p, argvp, sys.ProcessAttributes, sys.ThreadAttributes, willInheritHandles, flags, createEnvBlock(attr.Env), dirp, &si.StartupInfo, pi)
+		err = CreateProcess(argv0p, argvp, sys.ProcessAttributes, sys.ThreadAttributes, willInheritHandles, flags, envBlock, dirp, &si.StartupInfo, pi)
 	}
 	if err != nil {
 		return 0, 0, err
diff --git a/src/syscall/export_freebsd_test.go b/src/syscall/export_freebsd_test.go
deleted file mode 100644
index d47f090..0000000
--- a/src/syscall/export_freebsd_test.go
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package syscall
-
-type Dirent_freebsd11 = dirent_freebsd11
-
-var (
-	Roundup              = roundup
-	ConvertFromDirents11 = convertFromDirents11
-)
diff --git a/src/syscall/flock.go b/src/syscall/flock.go
index 8cb8f16..820f526 100644
--- a/src/syscall/flock.go
+++ b/src/syscall/flock.go
@@ -1,9 +1,9 @@
-//go:build linux || freebsd || openbsd || netbsd || dragonfly
-
 // Copyright 2014 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build linux || freebsd || openbsd || netbsd || dragonfly
+
 package syscall
 
 import "unsafe"
diff --git a/src/syscall/fs_js.go b/src/syscall/fs_js.go
index 3541446..ce0aa88 100644
--- a/src/syscall/fs_js.go
+++ b/src/syscall/fs_js.go
@@ -544,7 +544,7 @@
 	}
 }
 
-// mapJSError maps an error given by Node.js to the appropriate Go error
+// mapJSError maps an error given by Node.js to the appropriate Go error.
 func mapJSError(jsErr js.Value) error {
 	errno, ok := errnoByCode[jsErr.Get("code").String()]
 	if !ok {
diff --git a/src/syscall/lsf_linux.go b/src/syscall/lsf_linux.go
index 28e96d5..838acc5 100644
--- a/src/syscall/lsf_linux.go
+++ b/src/syscall/lsf_linux.go
@@ -48,7 +48,7 @@
 
 // Deprecated: Use golang.org/x/net/bpf instead.
 func SetLsfPromisc(name string, m bool) error {
-	s, e := cloexecSocket(AF_INET, SOCK_DGRAM, 0)
+	s, e := Socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC, 0)
 	if e != nil {
 		return e
 	}
diff --git a/src/syscall/mkall.sh b/src/syscall/mkall.sh
index dccb385..6b27253 100755
--- a/src/syscall/mkall.sh
+++ b/src/syscall/mkall.sh
@@ -88,11 +88,12 @@
 
 case "$1" in
 -syscalls)
-	for i in zsyscall*go
+	shift
+	for i in ${@:-zsyscall*go}
 	do
 		# Run the command line that appears in the first line
 		# of the generated file to regenerate it.
-		sed 1q $i | sed 's;^// ;;' | sh > _$i && gofmt < _$i > $i
+		sed 1q $i | sed 's;^// ;./;' | sh > _$i && gofmt < _$i > $i
 		rm _$i
 	done
 	exit 0
@@ -165,6 +166,13 @@
 	# API consistent between platforms.
 	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
 	;;
+freebsd_riscv64)
+	mkerrors="$mkerrors"
+	mksysnum="curl -s 'https://cgit.freebsd.org/src/plain/sys/kern/syscalls.master?h=stable/12' | ./mksysnum_freebsd.pl"
+	# Let the type of C char be signed to make the bare syscall
+	# API consistent between platforms.
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
+	;;
 linux_386)
 	mkerrors="$mkerrors -m32"
 	mksyscall="./mksyscall.pl -l32"
diff --git a/src/syscall/mkerrors.sh b/src/syscall/mkerrors.sh
index 92ab4c5..ddd5533 100755
--- a/src/syscall/mkerrors.sh
+++ b/src/syscall/mkerrors.sh
@@ -270,6 +270,7 @@
 		$2 ~ /^(SIGEV_|SIGSTKSZ|SIGRT(MIN|MAX))/ {next}
 		$2 ~ /^(SCM_SRCRT)$/ {next}
 		$2 ~ /^(MAP_FAILED)$/ {next}
+		$2 ~ /^CLONE_[A-Z_]+/ {next} # These are defined in exec_linux.go.
 		$2 ~ /^ELF_.*$/ {next}	# <asm/elf.h> contains ELF_ARCH, etc.
 
 		$2 !~ /^ETH_/ &&
@@ -317,7 +318,6 @@
 		$2 ~ /^RUSAGE_(SELF|CHILDREN|THREAD)/ ||
 		$2 ~ /^RLIMIT_(AS|CORE|CPU|DATA|FSIZE|NOFILE|STACK)|RLIM_INFINITY/ ||
 		$2 ~ /^PRIO_(PROCESS|PGRP|USER)/ ||
-		$2 ~ /^CLONE_[A-Z_]+/ ||
 		$2 !~ /^(BPF_TIMEVAL)$/ &&
 		$2 ~ /^(BPF|DLT)_/ ||
 		$2 !~ "WMESGLEN" &&
@@ -342,7 +342,7 @@
 signals=$(
 	echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
 	awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' |
-	egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT)' |
+	grep -v 'SIGSTKSIZE\|SIGSTKSZ\|SIGRT' |
 	sort
 )
 
@@ -352,7 +352,7 @@
 	sort >_error.grep
 echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags |
 	awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print "^\t" $2 "[ \t]*=" }' |
-	egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT)' |
+	grep -v 'SIGSTKSIZE\|SIGSTKSZ\|SIGRT' |
 	sort >_signal.grep
 
 echo '// mkerrors.sh' "$@"
diff --git a/src/syscall/mmap_unix_test.go b/src/syscall/mmap_unix_test.go
index 3e9c08d..911dfa6 100644
--- a/src/syscall/mmap_unix_test.go
+++ b/src/syscall/mmap_unix_test.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd
+//go:build unix
 
 package syscall_test
 
diff --git a/src/syscall/netlink_linux.go b/src/syscall/netlink_linux.go
index 2d81070..e976c70 100644
--- a/src/syscall/netlink_linux.go
+++ b/src/syscall/netlink_linux.go
@@ -50,7 +50,7 @@
 // NetlinkRIB returns routing information base, as known as RIB, which
 // consists of network facility information, states and parameters.
 func NetlinkRIB(proto, family int) ([]byte, error) {
-	s, err := cloexecSocket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)
+	s, err := Socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_ROUTE)
 	if err != nil {
 		return nil, err
 	}
diff --git a/src/syscall/route_freebsd_32bit.go b/src/syscall/route_freebsd_32bit.go
index c70f0bb..14373ab 100644
--- a/src/syscall/route_freebsd_32bit.go
+++ b/src/syscall/route_freebsd_32bit.go
@@ -22,12 +22,9 @@
 	// FreeBSD 10 and beyond have a restructured mbuf
 	// packet header view.
 	// See https://svnweb.freebsd.org/base?view=revision&revision=254804.
-	if supportsABI(1000000) {
-		m := (*ifMsghdr)(unsafe.Pointer(any))
-		p.Header.Data.Hwassist = uint32(m.Data.Hwassist)
-		p.Header.Data.Epoch = m.Data.Epoch
-		p.Header.Data.Lastchange = m.Data.Lastchange
-		return &InterfaceMessage{Header: p.Header, Data: b[int(unsafe.Offsetof(p.Header.Data))+int(p.Header.Data.Datalen) : any.Msglen]}
-	}
+	m := (*ifMsghdr)(unsafe.Pointer(any))
+	p.Header.Data.Hwassist = uint32(m.Data.Hwassist)
+	p.Header.Data.Epoch = m.Data.Epoch
+	p.Header.Data.Lastchange = m.Data.Lastchange
 	return &InterfaceMessage{Header: p.Header, Data: b[int(unsafe.Offsetof(p.Header.Data))+int(p.Header.Data.Datalen) : any.Msglen]}
 }
diff --git a/src/syscall/route_freebsd_64bit.go b/src/syscall/route_freebsd_64bit.go
index 9febdfa..01f3f21 100644
--- a/src/syscall/route_freebsd_64bit.go
+++ b/src/syscall/route_freebsd_64bit.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build (freebsd && amd64) || (freebsd && arm64)
+//go:build (freebsd && amd64) || (freebsd && arm64) || (freebsd && riscv64)
 
 package syscall
 
diff --git a/src/syscall/sock_cloexec_linux.go b/src/syscall/sock_cloexec_linux.go
deleted file mode 100644
index 600cf25..0000000
--- a/src/syscall/sock_cloexec_linux.go
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package syscall
-
-// This is a stripped down version of sysSocket from net/sock_cloexec.go.
-func cloexecSocket(family, sotype, proto int) (int, error) {
-	s, err := Socket(family, sotype|SOCK_CLOEXEC, proto)
-	switch err {
-	case nil:
-		return s, nil
-	default:
-		return -1, err
-	case EINVAL:
-	}
-
-	ForkLock.RLock()
-	s, err = Socket(family, sotype, proto)
-	if err == nil {
-		CloseOnExec(s)
-	}
-	ForkLock.RUnlock()
-	if err != nil {
-		Close(s)
-		return -1, err
-	}
-	return s, nil
-}
diff --git a/src/syscall/syscall.go b/src/syscall/syscall.go
index 62bfa44..446a299 100644
--- a/src/syscall/syscall.go
+++ b/src/syscall/syscall.go
@@ -100,3 +100,7 @@
 
 func Getpagesize() int
 func Exit(code int)
+
+// runtimeSetenv and runtimeUnsetenv are provided by the runtime.
+func runtimeSetenv(k, v string)
+func runtimeUnsetenv(k string)
diff --git a/src/syscall/syscall_aix.go b/src/syscall/syscall_aix.go
index dbcb7bb..807990f 100644
--- a/src/syscall/syscall_aix.go
+++ b/src/syscall/syscall_aix.go
@@ -343,7 +343,7 @@
 	msg.Namelen = uint32(SizeofSockaddrAny)
 	var iov Iovec
 	if len(p) > 0 {
-		iov.Base = (*byte)(unsafe.Pointer(&p[0]))
+		iov.Base = &p[0]
 		iov.SetLen(len(p))
 	}
 	var dummy byte
@@ -358,7 +358,7 @@
 			iov.Base = &dummy
 			iov.SetLen(1)
 		}
-		msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
+		msg.Control = &oob[0]
 		msg.SetControllen(len(oob))
 	}
 	msg.Iov = &iov
@@ -373,11 +373,11 @@
 
 func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
 	var msg Msghdr
-	msg.Name = (*byte)(unsafe.Pointer(ptr))
+	msg.Name = (*byte)(ptr)
 	msg.Namelen = uint32(salen)
 	var iov Iovec
 	if len(p) > 0 {
-		iov.Base = (*byte)(unsafe.Pointer(&p[0]))
+		iov.Base = &p[0]
 		iov.SetLen(len(p))
 	}
 	var dummy byte
@@ -392,7 +392,7 @@
 			iov.Base = &dummy
 			iov.SetLen(1)
 		}
-		msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
+		msg.Control = &oob[0]
 		msg.SetControllen(len(oob))
 	}
 	msg.Iov = &iov
@@ -642,6 +642,7 @@
 //sys	Unlink(path string) (err error)
 //sysnb	Uname(buf *Utsname) (err error)
 //sys	write(fd int, p []byte) (n int, err error)
+//sys	writev(fd int, iovecs []Iovec) (n uintptr, err error)
 
 //sys	gettimeofday(tv *Timeval, tzp *Timezone) (err error)
 
diff --git a/src/syscall/syscall_bsd.go b/src/syscall/syscall_bsd.go
index 5e636d5..c7a7d78 100644
--- a/src/syscall/syscall_bsd.go
+++ b/src/syscall/syscall_bsd.go
@@ -364,7 +364,7 @@
 	msg.Namelen = uint32(SizeofSockaddrAny)
 	var iov Iovec
 	if len(p) > 0 {
-		iov.Base = (*byte)(unsafe.Pointer(&p[0]))
+		iov.Base = &p[0]
 		iov.SetLen(len(p))
 	}
 	var dummy byte
@@ -374,7 +374,7 @@
 			iov.Base = &dummy
 			iov.SetLen(1)
 		}
-		msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
+		msg.Control = &oob[0]
 		msg.SetControllen(len(oob))
 	}
 	msg.Iov = &iov
@@ -391,11 +391,11 @@
 
 func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
 	var msg Msghdr
-	msg.Name = (*byte)(unsafe.Pointer(ptr))
+	msg.Name = (*byte)(ptr)
 	msg.Namelen = uint32(salen)
 	var iov Iovec
 	if len(p) > 0 {
-		iov.Base = (*byte)(unsafe.Pointer(&p[0]))
+		iov.Base = &p[0]
 		iov.SetLen(len(p))
 	}
 	var dummy byte
@@ -405,7 +405,7 @@
 			iov.Base = &dummy
 			iov.SetLen(1)
 		}
-		msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
+		msg.Control = &oob[0]
 		msg.SetControllen(len(oob))
 	}
 	msg.Iov = &iov
diff --git a/src/syscall/syscall_darwin.go b/src/syscall/syscall_darwin.go
index 663bd98..a39e99d 100644
--- a/src/syscall/syscall_darwin.go
+++ b/src/syscall/syscall_darwin.go
@@ -171,6 +171,7 @@
 //sys	Mlock(b []byte) (err error)
 //sys	Mlockall(flags int) (err error)
 //sys	Mprotect(b []byte, prot int) (err error)
+//sys	msync(b []byte, flags int) (err error)
 //sys	Munlock(b []byte) (err error)
 //sys	Munlockall() (err error)
 //sys	Open(path string, mode int, perm uint32) (fd int, err error)
@@ -226,7 +227,7 @@
 
 func fdopendir(fd int) (dir uintptr, err error) {
 	r0, _, e1 := syscallPtr(abi.FuncPCABI0(libc_fdopendir_trampoline), uintptr(fd), 0, 0)
-	dir = uintptr(r0)
+	dir = r0
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -310,12 +311,7 @@
 			break
 		}
 		// Copy entry into return buffer.
-		s := struct {
-			ptr unsafe.Pointer
-			siz int
-			cap int
-		}{ptr: unsafe.Pointer(&entry), siz: reclen, cap: reclen}
-		copy(buf, *(*[]byte)(unsafe.Pointer(&s)))
+		copy(buf, unsafe.Slice((*byte)(unsafe.Pointer(&entry)), reclen))
 		buf = buf[reclen:]
 		n += reclen
 		cnt++
diff --git a/src/syscall/syscall_dragonfly.go b/src/syscall/syscall_dragonfly.go
index 1a3cfe5..1a1f1f6 100644
--- a/src/syscall/syscall_dragonfly.go
+++ b/src/syscall/syscall_dragonfly.go
@@ -22,7 +22,10 @@
 func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
 func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
 
-const _SYS_DUP3 = 0
+const (
+	_SYS_DUP3         = 0
+	_F_DUP2FD_CLOEXEC = F_DUP2FD_CLOEXEC
+)
 
 // See version list in https://github.com/DragonFlyBSD/DragonFlyBSD/blob/master/sys/sys/param.h
 var (
diff --git a/src/syscall/syscall_freebsd.go b/src/syscall/syscall_freebsd.go
index 0637215..0f39126 100644
--- a/src/syscall/syscall_freebsd.go
+++ b/src/syscall/syscall_freebsd.go
@@ -12,40 +12,13 @@
 
 package syscall
 
-import (
-	"sync"
-	"unsafe"
-)
+import "unsafe"
 
 func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
 func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
 func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
 func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
 
-const (
-	_SYS_FSTAT_FREEBSD12         = 551 // { int fstat(int fd, _Out_ struct stat *sb); }
-	_SYS_FSTATAT_FREEBSD12       = 552 // { int fstatat(int fd, _In_z_ char *path, _Out_ struct stat *buf, int flag); }
-	_SYS_GETDIRENTRIES_FREEBSD12 = 554 // { ssize_t getdirentries(int fd, _Out_writes_bytes_(count) char *buf, size_t count, _Out_ off_t *basep); }
-	_SYS_STATFS_FREEBSD12        = 555 // { int statfs(_In_z_ char *path, _Out_ struct statfs *buf); }
-	_SYS_FSTATFS_FREEBSD12       = 556 // { int fstatfs(int fd, _Out_ struct statfs *buf); }
-	_SYS_GETFSSTAT_FREEBSD12     = 557 // { int getfsstat(_Out_writes_bytes_opt_(bufsize) struct statfs *buf, long bufsize, int mode); }
-	_SYS_MKNODAT_FREEBSD12       = 559 // { int mknodat(int fd, _In_z_ char *path, mode_t mode, dev_t dev); }
-)
-
-// See https://www.freebsd.org/doc/en_US.ISO8859-1/books/porters-handbook/versions.html.
-var (
-	osreldateOnce sync.Once
-	osreldate     uint32
-)
-
-// INO64_FIRST from /usr/src/lib/libc/sys/compat-ino64.h
-const _ino64First = 1200031
-
-func supportsABI(ver uint32) bool {
-	osreldateOnce.Do(func() { osreldate, _ = SysctlUint32("kern.osreldate") })
-	return osreldate >= ver
-}
-
 type SockaddrDatalink struct {
 	Len    uint8
 	Family uint8
@@ -148,273 +121,49 @@
 
 func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
 	var (
-		_p0          unsafe.Pointer
-		bufsize      uintptr
-		oldBuf       []statfs_freebsd11_t
-		needsConvert bool
+		_p0     unsafe.Pointer
+		bufsize uintptr
 	)
-
 	if len(buf) > 0 {
-		if supportsABI(_ino64First) {
-			_p0 = unsafe.Pointer(&buf[0])
-			bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))
-		} else {
-			n := len(buf)
-			oldBuf = make([]statfs_freebsd11_t, n)
-			_p0 = unsafe.Pointer(&oldBuf[0])
-			bufsize = unsafe.Sizeof(statfs_freebsd11_t{}) * uintptr(n)
-			needsConvert = true
-		}
+		_p0 = unsafe.Pointer(&buf[0])
+		bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))
 	}
-	var sysno uintptr = SYS_GETFSSTAT
-	if supportsABI(_ino64First) {
-		sysno = _SYS_GETFSSTAT_FREEBSD12
-	}
-	r0, _, e1 := Syscall(sysno, uintptr(_p0), bufsize, uintptr(flags))
+	r0, _, e1 := Syscall(SYS_GETFSSTAT, uintptr(_p0), bufsize, uintptr(flags))
 	n = int(r0)
 	if e1 != 0 {
 		err = e1
 	}
-	if e1 == 0 && needsConvert {
-		for i := range oldBuf {
-			buf[i].convertFrom(&oldBuf[i])
-		}
-	}
 	return
 }
 
 func Stat(path string, st *Stat_t) (err error) {
-	var oldStat stat_freebsd11_t
-	if supportsABI(_ino64First) {
-		return fstatat_freebsd12(_AT_FDCWD, path, st, 0)
-	}
-	err = stat(path, &oldStat)
-	if err != nil {
-		return err
-	}
-
-	st.convertFrom(&oldStat)
-	return nil
+	return Fstatat(_AT_FDCWD, path, st, 0)
 }
 
 func Lstat(path string, st *Stat_t) (err error) {
-	var oldStat stat_freebsd11_t
-	if supportsABI(_ino64First) {
-		return fstatat_freebsd12(_AT_FDCWD, path, st, _AT_SYMLINK_NOFOLLOW)
-	}
-	err = lstat(path, &oldStat)
-	if err != nil {
-		return err
-	}
-
-	st.convertFrom(&oldStat)
-	return nil
-}
-
-func Fstat(fd int, st *Stat_t) (err error) {
-	var oldStat stat_freebsd11_t
-	if supportsABI(_ino64First) {
-		return fstat_freebsd12(fd, st)
-	}
-	err = fstat(fd, &oldStat)
-	if err != nil {
-		return err
-	}
-
-	st.convertFrom(&oldStat)
-	return nil
-}
-
-func Fstatat(fd int, path string, st *Stat_t, flags int) (err error) {
-	var oldStat stat_freebsd11_t
-	if supportsABI(_ino64First) {
-		return fstatat_freebsd12(fd, path, st, flags)
-	}
-	err = fstatat(fd, path, &oldStat, flags)
-	if err != nil {
-		return err
-	}
-
-	st.convertFrom(&oldStat)
-	return nil
-}
-
-func Statfs(path string, st *Statfs_t) (err error) {
-	var oldStatfs statfs_freebsd11_t
-	if supportsABI(_ino64First) {
-		return statfs_freebsd12(path, st)
-	}
-	err = statfs(path, &oldStatfs)
-	if err != nil {
-		return err
-	}
-
-	st.convertFrom(&oldStatfs)
-	return nil
-}
-
-func Fstatfs(fd int, st *Statfs_t) (err error) {
-	var oldStatfs statfs_freebsd11_t
-	if supportsABI(_ino64First) {
-		return fstatfs_freebsd12(fd, st)
-	}
-	err = fstatfs(fd, &oldStatfs)
-	if err != nil {
-		return err
-	}
-
-	st.convertFrom(&oldStatfs)
-	return nil
+	return Fstatat(_AT_FDCWD, path, st, _AT_SYMLINK_NOFOLLOW)
 }
 
 func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
-	if supportsABI(_ino64First) {
-		if basep == nil || unsafe.Sizeof(*basep) == 8 {
-			return getdirentries_freebsd12(fd, buf, (*uint64)(unsafe.Pointer(basep)))
-		}
-		// The freebsd12 syscall needs a 64-bit base. On 32-bit machines
-		// we can't just use the basep passed in. See #32498.
-		var base uint64 = uint64(*basep)
-		n, err = getdirentries_freebsd12(fd, buf, &base)
-		*basep = uintptr(base)
-		if base>>32 != 0 {
-			// We can't stuff the base back into a uintptr, so any
-			// future calls would be suspect. Generate an error.
-			// EIO is allowed by getdirentries.
-			err = EIO
-		}
-		return
+	if basep == nil || unsafe.Sizeof(*basep) == 8 {
+		return getdirentries(fd, buf, (*uint64)(unsafe.Pointer(basep)))
 	}
-
-	// The old syscall entries are smaller than the new. Use 1/4 of the original
-	// buffer size rounded up to DIRBLKSIZ (see /usr/src/lib/libc/sys/getdirentries.c).
-	oldBufLen := roundup(len(buf)/4, _dirblksiz)
-	oldBuf := make([]byte, oldBufLen)
-	n, err = getdirentries(fd, oldBuf, basep)
-	if err == nil && n > 0 {
-		n = convertFromDirents11(buf, oldBuf[:n])
+	// The syscall needs a 64-bit base. On 32-bit machines
+	// we can't just use the basep passed in. See #32498.
+	var base uint64 = uint64(*basep)
+	n, err = getdirentries(fd, buf, &base)
+	*basep = uintptr(base)
+	if base>>32 != 0 {
+		// We can't stuff the base back into a uintptr, so any
+		// future calls would be suspect. Generate an error.
+		// EIO is allowed by getdirentries.
+		err = EIO
 	}
 	return
 }
 
 func Mknod(path string, mode uint32, dev uint64) (err error) {
-	var oldDev int
-	if supportsABI(_ino64First) {
-		return mknodat_freebsd12(_AT_FDCWD, path, mode, dev)
-	}
-	oldDev = int(dev)
-	return mknod(path, mode, oldDev)
-}
-
-// round x to the nearest multiple of y, larger or equal to x.
-//
-// from /usr/include/sys/param.h Macros for counting and rounding.
-// #define roundup(x, y)   ((((x)+((y)-1))/(y))*(y))
-func roundup(x, y int) int {
-	return ((x + y - 1) / y) * y
-}
-
-func (s *Stat_t) convertFrom(old *stat_freebsd11_t) {
-	*s = Stat_t{
-		Dev:           uint64(old.Dev),
-		Ino:           uint64(old.Ino),
-		Nlink:         uint64(old.Nlink),
-		Mode:          old.Mode,
-		Uid:           old.Uid,
-		Gid:           old.Gid,
-		Rdev:          uint64(old.Rdev),
-		Atimespec:     old.Atimespec,
-		Mtimespec:     old.Mtimespec,
-		Ctimespec:     old.Ctimespec,
-		Birthtimespec: old.Birthtimespec,
-		Size:          old.Size,
-		Blocks:        old.Blocks,
-		Blksize:       old.Blksize,
-		Flags:         old.Flags,
-		Gen:           uint64(old.Gen),
-	}
-}
-
-func (s *Statfs_t) convertFrom(old *statfs_freebsd11_t) {
-	*s = Statfs_t{
-		Version:     _statfsVersion,
-		Type:        old.Type,
-		Flags:       old.Flags,
-		Bsize:       old.Bsize,
-		Iosize:      old.Iosize,
-		Blocks:      old.Blocks,
-		Bfree:       old.Bfree,
-		Bavail:      old.Bavail,
-		Files:       old.Files,
-		Ffree:       old.Ffree,
-		Syncwrites:  old.Syncwrites,
-		Asyncwrites: old.Asyncwrites,
-		Syncreads:   old.Syncreads,
-		Asyncreads:  old.Asyncreads,
-		// Spare
-		Namemax: old.Namemax,
-		Owner:   old.Owner,
-		Fsid:    old.Fsid,
-		// Charspare
-		// Fstypename
-		// Mntfromname
-		// Mntonname
-	}
-
-	sl := old.Fstypename[:]
-	n := clen(*(*[]byte)(unsafe.Pointer(&sl)))
-	copy(s.Fstypename[:], old.Fstypename[:n])
-
-	sl = old.Mntfromname[:]
-	n = clen(*(*[]byte)(unsafe.Pointer(&sl)))
-	copy(s.Mntfromname[:], old.Mntfromname[:n])
-
-	sl = old.Mntonname[:]
-	n = clen(*(*[]byte)(unsafe.Pointer(&sl)))
-	copy(s.Mntonname[:], old.Mntonname[:n])
-}
-
-func convertFromDirents11(buf []byte, old []byte) int {
-	const (
-		fixedSize    = int(unsafe.Offsetof(Dirent{}.Name))
-		oldFixedSize = int(unsafe.Offsetof(dirent_freebsd11{}.Name))
-	)
-
-	dstPos := 0
-	srcPos := 0
-	for dstPos+fixedSize < len(buf) && srcPos+oldFixedSize < len(old) {
-		var dstDirent Dirent
-		var srcDirent dirent_freebsd11
-
-		// If multiple direntries are written, sometimes when we reach the final one,
-		// we may have cap of old less than size of dirent_freebsd11.
-		copy((*[unsafe.Sizeof(srcDirent)]byte)(unsafe.Pointer(&srcDirent))[:], old[srcPos:])
-
-		reclen := roundup(fixedSize+int(srcDirent.Namlen)+1, 8)
-		if dstPos+reclen > len(buf) {
-			break
-		}
-
-		dstDirent.Fileno = uint64(srcDirent.Fileno)
-		dstDirent.Off = 0
-		dstDirent.Reclen = uint16(reclen)
-		dstDirent.Type = srcDirent.Type
-		dstDirent.Pad0 = 0
-		dstDirent.Namlen = uint16(srcDirent.Namlen)
-		dstDirent.Pad1 = 0
-
-		copy(dstDirent.Name[:], srcDirent.Name[:srcDirent.Namlen])
-		copy(buf[dstPos:], (*[unsafe.Sizeof(dstDirent)]byte)(unsafe.Pointer(&dstDirent))[:])
-		padding := buf[dstPos+fixedSize+int(dstDirent.Namlen) : dstPos+reclen]
-		for i := range padding {
-			padding[i] = 0
-		}
-
-		dstPos += int(dstDirent.Reclen)
-		srcPos += int(srcDirent.Reclen)
-	}
-
-	return dstPos
+	return mknodat(_AT_FDCWD, path, mode, dev)
 }
 
 /*
@@ -436,16 +185,12 @@
 //sys	Fchown(fd int, uid int, gid int) (err error)
 //sys	Flock(fd int, how int) (err error)
 //sys	Fpathconf(fd int, name int) (val int, err error)
-//sys	fstat(fd int, stat *stat_freebsd11_t) (err error)
-//sys	fstat_freebsd12(fd int, stat *Stat_t) (err error) = _SYS_FSTAT_FREEBSD12
-//sys	fstatat(fd int, path string, stat *stat_freebsd11_t, flags int) (err error)
-//sys	fstatat_freebsd12(fd int, path string, stat *Stat_t, flags int) (err error) = _SYS_FSTATAT_FREEBSD12
-//sys	fstatfs(fd int, stat *statfs_freebsd11_t) (err error)
-//sys	fstatfs_freebsd12(fd int, stat *Statfs_t) (err error) = _SYS_FSTATFS_FREEBSD12
+//sys	Fstat(fd int, stat *Stat_t) (err error)
+//sys	Fstatat(fd int, path string, stat *Stat_t, flags int) (err error)
+//sys	Fstatfs(fd int, stat *Statfs_t) (err error)
 //sys	Fsync(fd int) (err error)
 //sys	Ftruncate(fd int, length int64) (err error)
-//sys	getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error)
-//sys	getdirentries_freebsd12(fd int, buf []byte, basep *uint64) (n int, err error) = _SYS_GETDIRENTRIES_FREEBSD12
+//sys	getdirentries(fd int, buf []byte, basep *uint64) (n int, err error)
 //sys	Getdtablesize() (size int)
 //sysnb	Getegid() (egid int)
 //sysnb	Geteuid() (uid int)
@@ -466,11 +211,9 @@
 //sys	Lchown(path string, uid int, gid int) (err error)
 //sys	Link(path string, link string) (err error)
 //sys	Listen(s int, backlog int) (err error)
-//sys	lstat(path string, stat *stat_freebsd11_t) (err error)
 //sys	Mkdir(path string, mode uint32) (err error)
 //sys	Mkfifo(path string, mode uint32) (err error)
-//sys	mknod(path string, mode uint32, dev int) (err error)
-//sys	mknodat_freebsd12(fd int, path string, mode uint32, dev uint64) (err error) = _SYS_MKNODAT_FREEBSD12
+//sys	mknodat(fd int, path string, mode uint32, dev uint64) (err error)
 //sys	Nanosleep(time *Timespec, leftover *Timespec) (err error)
 //sys	Open(path string, mode int, perm uint32) (fd int, err error)
 //sys	Pathconf(path string, name int) (val int, err error)
@@ -495,9 +238,7 @@
 //sysnb	Setsid() (pid int, err error)
 //sysnb	Settimeofday(tp *Timeval) (err error)
 //sysnb	Setuid(uid int) (err error)
-//sys	stat(path string, stat *stat_freebsd11_t) (err error)
-//sys	statfs(path string, stat *statfs_freebsd11_t) (err error)
-//sys	statfs_freebsd12(path string, stat *Statfs_t) (err error) = _SYS_STATFS_FREEBSD12
+//sys	Statfs(path string, stat *Statfs_t) (err error)
 //sys	Symlink(path string, link string) (err error)
 //sys	Sync() (err error)
 //sys	Truncate(path string, length int64) (err error)
diff --git a/src/syscall/syscall_freebsd_riscv64.go b/src/syscall/syscall_freebsd_riscv64.go
new file mode 100644
index 0000000..cc3a2c1
--- /dev/null
+++ b/src/syscall/syscall_freebsd_riscv64.go
@@ -0,0 +1,47 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package syscall
+
+import "unsafe"
+
+func setTimespec(sec, nsec int64) Timespec {
+	return Timespec{Sec: sec, Nsec: nsec}
+}
+
+func setTimeval(sec, usec int64) Timeval {
+	return Timeval{Sec: sec, Usec: usec}
+}
+
+func SetKevent(k *Kevent_t, fd, mode, flags int) {
+	k.Ident = uint64(fd)
+	k.Filter = int16(mode)
+	k.Flags = uint16(flags)
+}
+
+func (iov *Iovec) SetLen(length int) {
+	iov.Len = uint64(length)
+}
+
+func (msghdr *Msghdr) SetControllen(length int) {
+	msghdr.Controllen = uint32(length)
+}
+
+func (cmsg *Cmsghdr) SetLen(length int) {
+	cmsg.Len = uint32(length)
+}
+
+func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
+	var writtenOut uint64 = 0
+	_, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0, 0)
+
+	written = int(writtenOut)
+
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno)
diff --git a/src/syscall/syscall_freebsd_test.go b/src/syscall/syscall_freebsd_test.go
index f04b12b..15e3802 100644
--- a/src/syscall/syscall_freebsd_test.go
+++ b/src/syscall/syscall_freebsd_test.go
@@ -7,53 +7,10 @@
 package syscall_test
 
 import (
-	"fmt"
 	"os"
-	"syscall"
 	"testing"
-	"unsafe"
 )
 
-func TestConvertFromDirent11(t *testing.T) {
-	const (
-		filenameFmt  = "%04d"
-		numFiles     = 64
-		fixedHdrSize = int(unsafe.Offsetof(syscall.Dirent_freebsd11{}.Name))
-	)
-
-	namlen := len(fmt.Sprintf(filenameFmt, 0))
-	reclen := syscall.Roundup(fixedHdrSize+namlen+1, 4)
-	old := make([]byte, numFiles*reclen)
-	for i := 0; i < numFiles; i++ {
-		dent := syscall.Dirent_freebsd11{
-			Fileno: uint32(i + 1),
-			Reclen: uint16(reclen),
-			Type:   syscall.DT_REG,
-			Namlen: uint8(namlen),
-		}
-		rec := make([]byte, reclen)
-		copy(rec, (*[fixedHdrSize]byte)(unsafe.Pointer(&dent))[:])
-		copy(rec[fixedHdrSize:], fmt.Sprintf(filenameFmt, i+1))
-		copy(old[i*reclen:], rec)
-	}
-
-	buf := make([]byte, 2*len(old))
-	n := syscall.ConvertFromDirents11(buf, old)
-
-	names := make([]string, 0, numFiles)
-	_, _, names = syscall.ParseDirent(buf[:n], -1, names)
-
-	if len(names) != numFiles {
-		t.Errorf("expected %d files, have %d; names: %q", numFiles, len(names), names)
-	}
-
-	for i, name := range names {
-		if expected := fmt.Sprintf(filenameFmt, i+1); name != expected {
-			t.Errorf("expected names[%d] to be %q; got %q", i, expected, name)
-		}
-	}
-}
-
 func TestMain(m *testing.M) {
 	if os.Getenv("GO_DEATHSIG_PARENT") == "1" {
 		deathSignalParent()
diff --git a/src/syscall/syscall_illumos.go b/src/syscall/syscall_illumos.go
index 04f9e7e..d043636 100644
--- a/src/syscall/syscall_illumos.go
+++ b/src/syscall/syscall_illumos.go
@@ -4,12 +4,13 @@
 
 //go:build illumos
 
-// Illumos system calls not present on Solaris.
-
 package syscall
 
 import "unsafe"
 
+// F_DUP2FD_CLOEXEC has different values on Solaris and Illumos.
+const F_DUP2FD_CLOEXEC = 0x24
+
 //go:cgo_import_dynamic libc_flock flock "libc.so"
 
 //go:linkname procFlock libc_flock
diff --git a/src/syscall/syscall_linux.go b/src/syscall/syscall_linux.go
index e1837b9..f337388 100644
--- a/src/syscall/syscall_linux.go
+++ b/src/syscall/syscall_linux.go
@@ -13,6 +13,7 @@
 
 import (
 	"internal/itoa"
+	"runtime"
 	"unsafe"
 )
 
@@ -94,6 +95,7 @@
 }
 
 func rawSyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr)
+func rawVforkSyscall(trap, a1, a2 uintptr) (r1 uintptr, err Errno)
 
 /*
  * Wrapped
@@ -115,6 +117,13 @@
 	return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode)
 }
 
+func EpollCreate(size int) (fd int, err error) {
+	if size <= 0 {
+		return -1, EINVAL
+	}
+	return EpollCreate1(0)
+}
+
 func isGroupMember(gid int) bool {
 	groups, err := Getgroups()
 	if err != nil {
@@ -129,11 +138,35 @@
 	return false
 }
 
+func isCapDacOverrideSet() bool {
+	const _CAP_DAC_OVERRIDE = 1
+	var c caps
+	c.hdr.version = _LINUX_CAPABILITY_VERSION_3
+
+	_, _, err := RawSyscall(SYS_CAPGET, uintptr(unsafe.Pointer(&c.hdr)), uintptr(unsafe.Pointer(&c.data[0])), 0)
+
+	return err == 0 && c.data[0].effective&capToMask(_CAP_DAC_OVERRIDE) != 0
+}
+
 //sys	faccessat(dirfd int, path string, mode uint32) (err error)
+//sys	faccessat2(dirfd int, path string, mode uint32, flags int) (err error) = _SYS_faccessat2
 
 func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
-	if flags & ^(_AT_SYMLINK_NOFOLLOW|_AT_EACCESS) != 0 {
-		return EINVAL
+	if flags == 0 {
+		return faccessat(dirfd, path, mode)
+	}
+
+	// Attempt to use the newer faccessat2, which supports flags directly,
+	// falling back if it doesn't exist.
+	//
+	// Don't attempt on Android, which does not allow faccessat2 through
+	// its seccomp policy [1] on any version of Android as of 2022-12-20.
+	//
+	// [1] https://cs.android.com/android/platform/superproject/+/master:bionic/libc/SECCOMP_BLOCKLIST_APP.TXT;l=4;drc=dbb8670dfdcc677f7e3b9262e93800fa14c4e417
+	if runtime.GOOS != "android" {
+		if err := faccessat2(dirfd, path, mode, flags); err != ENOSYS && err != EPERM {
+			return err
+		}
 	}
 
 	// The Linux kernel faccessat system call does not take any flags.
@@ -142,8 +175,8 @@
 	// Because people naturally expect syscall.Faccessat to act
 	// like C faccessat, we do the same.
 
-	if flags == 0 {
-		return faccessat(dirfd, path, mode)
+	if flags & ^(_AT_SYMLINK_NOFOLLOW|_AT_EACCESS) != 0 {
+		return EINVAL
 	}
 
 	var st Stat_t
@@ -156,9 +189,16 @@
 		return nil
 	}
 
+	// Fallback to checking permission bits.
 	var uid int
 	if flags&_AT_EACCESS != 0 {
 		uid = Geteuid()
+		if uid != 0 && isCapDacOverrideSet() {
+			// If CAP_DAC_OVERRIDE is set, file access check is
+			// done by the kernel in the same way as for root
+			// (see generic_permission() in the Linux sources).
+			uid = 0
+		}
 	} else {
 		uid = Getuid()
 	}
@@ -630,21 +670,6 @@
 	return nil, EAFNOSUPPORT
 }
 
-func Accept(fd int) (nfd int, sa Sockaddr, err error) {
-	var rsa RawSockaddrAny
-	var len _Socklen = SizeofSockaddrAny
-	nfd, err = accept4(fd, &rsa, &len, 0)
-	if err != nil {
-		return
-	}
-	sa, err = anyToSockaddr(&rsa)
-	if err != nil {
-		Close(nfd)
-		nfd = 0
-	}
-	return
-}
-
 func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {
 	var rsa RawSockaddrAny
 	var len _Socklen = SizeofSockaddrAny
diff --git a/src/syscall/syscall_linux_386.go b/src/syscall/syscall_linux_386.go
index fc7df84..0c9c6aa 100644
--- a/src/syscall/syscall_linux_386.go
+++ b/src/syscall/syscall_linux_386.go
@@ -6,7 +6,11 @@
 
 import "unsafe"
 
-const _SYS_setgroups = SYS_SETGROUPS32
+const (
+	_SYS_setgroups  = SYS_SETGROUPS32
+	_SYS_clone3     = 435
+	_SYS_faccessat2 = 439
+)
 
 func setTimespec(sec, nsec int64) Timespec {
 	return Timespec{Sec: int32(sec), Nsec: int32(nsec)}
@@ -19,7 +23,6 @@
 // 64-bit file system and 32-bit uid calls
 // (386 default is 32-bit file system and 16-bit uid).
 //sys	Dup2(oldfd int, newfd int) (err error)
-//sysnb	EpollCreate(size int) (fd int, err error)
 //sys	Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32
 //sys	Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
 //sys	fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64
@@ -346,5 +349,3 @@
 func (cmsg *Cmsghdr) SetLen(length int) {
 	cmsg.Len = uint32(length)
 }
-
-func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno)
diff --git a/src/syscall/syscall_linux_accept.go b/src/syscall/syscall_linux_accept.go
new file mode 100644
index 0000000..66c0f84
--- /dev/null
+++ b/src/syscall/syscall_linux_accept.go
@@ -0,0 +1,34 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// We require Linux kernel version 2.6.32. The accept4 system call was
+// added in version 2.6.28, so in general we can use accept4.
+// Unfortunately, for ARM only, accept4 was added in version 2.6.36.
+// Handle that case here, by using a copy of the Accept function that
+// we used in Go 1.17.
+
+//go:build linux && arm
+
+package syscall
+
+//sys	accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
+
+func Accept(fd int) (nfd int, sa Sockaddr, err error) {
+	var rsa RawSockaddrAny
+	var len _Socklen = SizeofSockaddrAny
+	// Try accept4 first for Android and newer kernels.
+	nfd, err = accept4(fd, &rsa, &len, 0)
+	if err == ENOSYS {
+		nfd, err = accept(fd, &rsa, &len)
+	}
+	if err != nil {
+		return
+	}
+	sa, err = anyToSockaddr(&rsa)
+	if err != nil {
+		Close(nfd)
+		nfd = 0
+	}
+	return
+}
diff --git a/src/syscall/syscall_linux_accept4.go b/src/syscall/syscall_linux_accept4.go
new file mode 100644
index 0000000..7489867
--- /dev/null
+++ b/src/syscall/syscall_linux_accept4.go
@@ -0,0 +1,25 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file provides the Accept function used on all systems
+// other than arm. See syscall_linux_accept.go for why.
+
+//go:build linux && !arm
+
+package syscall
+
+func Accept(fd int) (nfd int, sa Sockaddr, err error) {
+	var rsa RawSockaddrAny
+	var len _Socklen = SizeofSockaddrAny
+	nfd, err = accept4(fd, &rsa, &len, 0)
+	if err != nil {
+		return
+	}
+	sa, err = anyToSockaddr(&rsa)
+	if err != nil {
+		Close(nfd)
+		nfd = 0
+	}
+	return
+}
diff --git a/src/syscall/syscall_linux_amd64.go b/src/syscall/syscall_linux_amd64.go
index 0bcc664..77e1393 100644
--- a/src/syscall/syscall_linux_amd64.go
+++ b/src/syscall/syscall_linux_amd64.go
@@ -4,10 +4,13 @@
 
 package syscall
 
-const _SYS_setgroups = SYS_SETGROUPS
+const (
+	_SYS_setgroups  = SYS_SETGROUPS
+	_SYS_clone3     = 435
+	_SYS_faccessat2 = 439
+)
 
 //sys	Dup2(oldfd int, newfd int) (err error)
-//sysnb	EpollCreate(size int) (fd int, err error)
 //sys	Fchown(fd int, uid int, gid int) (err error)
 //sys	Fstat(fd int, stat *Stat_t) (err error)
 //sys	Fstatfs(fd int, buf *Statfs_t) (err error)
@@ -118,5 +121,3 @@
 func (cmsg *Cmsghdr) SetLen(length int) {
 	cmsg.Len = uint64(length)
 }
-
-func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno)
diff --git a/src/syscall/syscall_linux_arm.go b/src/syscall/syscall_linux_arm.go
index 9db7027..f4740af 100644
--- a/src/syscall/syscall_linux_arm.go
+++ b/src/syscall/syscall_linux_arm.go
@@ -6,7 +6,11 @@
 
 import "unsafe"
 
-const _SYS_setgroups = SYS_SETGROUPS32
+const (
+	_SYS_setgroups  = SYS_SETGROUPS32
+	_SYS_clone3     = 435
+	_SYS_faccessat2 = 439
+)
 
 func setTimespec(sec, nsec int64) Timespec {
 	return Timespec{Sec: int32(sec), Nsec: int32(nsec)}
@@ -46,7 +50,6 @@
 // 64-bit file system and 32-bit uid calls
 // (16-bit uid calls are not always supported in newer kernels)
 //sys	Dup2(oldfd int, newfd int) (err error)
-//sysnb	EpollCreate(size int) (fd int, err error)
 //sys	Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32
 //sys	Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
 //sys	fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64
@@ -198,5 +201,3 @@
 func (cmsg *Cmsghdr) SetLen(length int) {
 	cmsg.Len = uint32(length)
 }
-
-func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno)
diff --git a/src/syscall/syscall_linux_arm64.go b/src/syscall/syscall_linux_arm64.go
index ef935f3..f426862 100644
--- a/src/syscall/syscall_linux_arm64.go
+++ b/src/syscall/syscall_linux_arm64.go
@@ -6,20 +6,21 @@
 
 import "unsafe"
 
-const _SYS_setgroups = SYS_SETGROUPS
-
-func EpollCreate(size int) (fd int, err error) {
-	if size <= 0 {
-		return -1, EINVAL
-	}
-	return EpollCreate1(0)
-}
+const (
+	_SYS_setgroups  = SYS_SETGROUPS
+	_SYS_clone3     = 435
+	_SYS_faccessat2 = 439
+)
 
 //sys	EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_PWAIT
 //sys	Fchown(fd int, uid int, gid int) (err error)
 //sys	Fstat(fd int, stat *Stat_t) (err error)
-//sys	Fstatat(fd int, path string, stat *Stat_t, flags int) (err error)
 //sys	fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error)
+
+func Fstatat(fd int, path string, stat *Stat_t, flags int) error {
+	return fstatat(fd, path, stat, flags)
+}
+
 //sys	Fstatfs(fd int, buf *Statfs_t) (err error)
 //sys	Ftruncate(fd int, length int64) (err error)
 //sysnb	Getegid() (egid int)
@@ -40,7 +41,7 @@
 //sys	Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
 
 func Stat(path string, stat *Stat_t) (err error) {
-	return Fstatat(_AT_FDCWD, path, stat, 0)
+	return fstatat(_AT_FDCWD, path, stat, 0)
 }
 
 func Lchown(path string, uid int, gid int) (err error) {
@@ -48,7 +49,7 @@
 }
 
 func Lstat(path string, stat *Stat_t) (err error) {
-	return Fstatat(_AT_FDCWD, path, stat, _AT_SYMLINK_NOFOLLOW)
+	return fstatat(_AT_FDCWD, path, stat, _AT_SYMLINK_NOFOLLOW)
 }
 
 //sys	Statfs(path string, buf *Statfs_t) (err error)
@@ -182,5 +183,3 @@
 	_, err := ppoll(nil, 0, nil, nil)
 	return err
 }
-
-func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno)
diff --git a/src/syscall/syscall_linux_loong64.go b/src/syscall/syscall_linux_loong64.go
index 99674b4..5a0fa08 100644
--- a/src/syscall/syscall_linux_loong64.go
+++ b/src/syscall/syscall_linux_loong64.go
@@ -6,14 +6,11 @@
 
 import "unsafe"
 
-const _SYS_setgroups = SYS_SETGROUPS
-
-func EpollCreate(size int) (fd int, err error) {
-	if size <= 0 {
-		return -1, EINVAL
-	}
-	return EpollCreate1(0)
-}
+const (
+	_SYS_setgroups  = SYS_SETGROUPS
+	_SYS_clone3     = 435
+	_SYS_faccessat2 = 439
+)
 
 //sys	EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_PWAIT
 //sys	Fchown(fd int, uid int, gid int) (err error)
@@ -221,5 +218,3 @@
 	_, err := ppoll(nil, 0, nil, nil)
 	return err
 }
-
-func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno)
diff --git a/src/syscall/syscall_linux_mips64x.go b/src/syscall/syscall_linux_mips64x.go
index 258eb97..8a0aa5c 100644
--- a/src/syscall/syscall_linux_mips64x.go
+++ b/src/syscall/syscall_linux_mips64x.go
@@ -6,10 +6,13 @@
 
 package syscall
 
-const _SYS_setgroups = SYS_SETGROUPS
+const (
+	_SYS_setgroups  = SYS_SETGROUPS
+	_SYS_clone3     = 5435
+	_SYS_faccessat2 = 5439
+)
 
 //sys	Dup2(oldfd int, newfd int) (err error)
-//sysnb	EpollCreate(size int) (fd int, err error)
 //sys	Fchown(fd int, uid int, gid int) (err error)
 //sys	Fstatfs(fd int, buf *Statfs_t) (err error)
 //sys	fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_NEWFSTATAT
@@ -180,5 +183,3 @@
 func (cmsg *Cmsghdr) SetLen(length int) {
 	cmsg.Len = uint64(length)
 }
-
-func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno)
diff --git a/src/syscall/syscall_linux_mipsx.go b/src/syscall/syscall_linux_mipsx.go
index 5390277..c8468fb 100644
--- a/src/syscall/syscall_linux_mipsx.go
+++ b/src/syscall/syscall_linux_mipsx.go
@@ -8,12 +8,15 @@
 
 import "unsafe"
 
-const _SYS_setgroups = SYS_SETGROUPS
+const (
+	_SYS_setgroups  = SYS_SETGROUPS
+	_SYS_clone3     = 4435
+	_SYS_faccessat2 = 4439
+)
 
 func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno)
 
 //sys	Dup2(oldfd int, newfd int) (err error)
-//sysnb	EpollCreate(size int) (fd int, err error)
 //sys	Fchown(fd int, uid int, gid int) (err error)
 //sys	fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64
 //sys	Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64
@@ -191,5 +194,3 @@
 func (cmsg *Cmsghdr) SetLen(length int) {
 	cmsg.Len = uint32(length)
 }
-
-func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno)
diff --git a/src/syscall/syscall_linux_ppc64x.go b/src/syscall/syscall_linux_ppc64x.go
index 88ad8e4..5c076d8 100644
--- a/src/syscall/syscall_linux_ppc64x.go
+++ b/src/syscall/syscall_linux_ppc64x.go
@@ -6,10 +6,13 @@
 
 package syscall
 
-const _SYS_setgroups = SYS_SETGROUPS
+const (
+	_SYS_setgroups  = SYS_SETGROUPS
+	_SYS_clone3     = 435
+	_SYS_faccessat2 = 439
+)
 
 //sys	Dup2(oldfd int, newfd int) (err error)
-//sysnb	EpollCreate(size int) (fd int, err error)
 //sys	EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
 //sys	Fchown(fd int, uid int, gid int) (err error)
 //sys	Fstat(fd int, stat *Stat_t) (err error)
@@ -89,8 +92,6 @@
 	cmsg.Len = uint64(length)
 }
 
-func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno)
-
 //sys	syncFileRange2(fd int, flags int, off int64, n int64) (err error) = SYS_SYNC_FILE_RANGE2
 
 func SyncFileRange(fd int, off int64, n int64, flags int) error {
diff --git a/src/syscall/syscall_linux_riscv64.go b/src/syscall/syscall_linux_riscv64.go
index 0ac4c54..3bb5460 100644
--- a/src/syscall/syscall_linux_riscv64.go
+++ b/src/syscall/syscall_linux_riscv64.go
@@ -6,20 +6,21 @@
 
 import "unsafe"
 
-const _SYS_setgroups = SYS_SETGROUPS
-
-func EpollCreate(size int) (fd int, err error) {
-	if size <= 0 {
-		return -1, EINVAL
-	}
-	return EpollCreate1(0)
-}
+const (
+	_SYS_setgroups  = SYS_SETGROUPS
+	_SYS_clone3     = 435
+	_SYS_faccessat2 = 439
+)
 
 //sys	EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) = SYS_EPOLL_PWAIT
 //sys	Fchown(fd int, uid int, gid int) (err error)
 //sys	Fstat(fd int, stat *Stat_t) (err error)
-//sys	Fstatat(fd int, path string, stat *Stat_t, flags int) (err error)
 //sys	fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error)
+
+func Fstatat(fd int, path string, stat *Stat_t, flags int) error {
+	return fstatat(fd, path, stat, flags)
+}
+
 //sys	Fstatfs(fd int, buf *Statfs_t) (err error)
 //sys	Ftruncate(fd int, length int64) (err error)
 //sysnb	Getegid() (egid int)
@@ -44,7 +45,7 @@
 }
 
 func Stat(path string, stat *Stat_t) (err error) {
-	return Fstatat(_AT_FDCWD, path, stat, 0)
+	return fstatat(_AT_FDCWD, path, stat, 0)
 }
 
 func Lchown(path string, uid int, gid int) (err error) {
@@ -52,7 +53,7 @@
 }
 
 func Lstat(path string, stat *Stat_t) (err error) {
-	return Fstatat(_AT_FDCWD, path, stat, _AT_SYMLINK_NOFOLLOW)
+	return fstatat(_AT_FDCWD, path, stat, _AT_SYMLINK_NOFOLLOW)
 }
 
 //sys	Statfs(path string, buf *Statfs_t) (err error)
@@ -168,5 +169,3 @@
 	_, err := ppoll(nil, 0, nil, nil)
 	return err
 }
-
-func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno)
diff --git a/src/syscall/syscall_linux_s390x.go b/src/syscall/syscall_linux_s390x.go
index 46b252d..cb83697 100644
--- a/src/syscall/syscall_linux_s390x.go
+++ b/src/syscall/syscall_linux_s390x.go
@@ -6,10 +6,13 @@
 
 import "unsafe"
 
-const _SYS_setgroups = SYS_SETGROUPS
+const (
+	_SYS_setgroups  = SYS_SETGROUPS
+	_SYS_clone3     = 435
+	_SYS_faccessat2 = 439
+)
 
 //sys	Dup2(oldfd int, newfd int) (err error)
-//sysnb	EpollCreate(size int) (fd int, err error)
 //sys	EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
 //sys	Fchown(fd int, uid int, gid int) (err error)
 //sys	Fstat(fd int, stat *Stat_t) (err error)
@@ -255,5 +258,3 @@
 func (cmsg *Cmsghdr) SetLen(length int) {
 	cmsg.Len = uint64(length)
 }
-
-func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno)
diff --git a/src/syscall/syscall_linux_test.go b/src/syscall/syscall_linux_test.go
index 0444b64..ff128b1 100644
--- a/src/syscall/syscall_linux_test.go
+++ b/src/syscall/syscall_linux_test.go
@@ -516,6 +516,9 @@
 	if syscall.Getuid() != 0 {
 		t.Skip("skipping root only test")
 	}
+	if _, err := os.Stat("/etc/alpine-release"); err == nil {
+		t.Skip("skipping glibc test on alpine - go.dev/issue/19938")
+	}
 	vs := []struct {
 		call           string
 		fn             func() error
diff --git a/src/syscall/syscall_netbsd.go b/src/syscall/syscall_netbsd.go
index d8efb41..7f7c5b1 100644
--- a/src/syscall/syscall_netbsd.go
+++ b/src/syscall/syscall_netbsd.go
@@ -20,7 +20,10 @@
 func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
 func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
 
-const _SYS_DUP3 = SYS_DUP3
+const (
+	_SYS_DUP3         = SYS_DUP3
+	_F_DUP2FD_CLOEXEC = 0
+)
 
 type SockaddrDatalink struct {
 	Len    uint8
diff --git a/src/syscall/syscall_openbsd.go b/src/syscall/syscall_openbsd.go
index 7521734..ba67ab1 100644
--- a/src/syscall/syscall_openbsd.go
+++ b/src/syscall/syscall_openbsd.go
@@ -209,6 +209,7 @@
 //sys	Unlink(path string) (err error)
 //sys	Unmount(path string, flags int) (err error)
 //sys	write(fd int, p []byte) (n int, err error)
+//sys	writev(fd int, iovecs []Iovec) (n uintptr, err error)
 //sys	mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
 //sys	munmap(addr uintptr, length uintptr) (err error)
 //sys	utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error)
diff --git a/src/syscall/syscall_openbsd_mips64.go b/src/syscall/syscall_openbsd_mips64.go
index 4508ad9..838c684 100644
--- a/src/syscall/syscall_openbsd_mips64.go
+++ b/src/syscall/syscall_openbsd_mips64.go
@@ -4,7 +4,10 @@
 
 package syscall
 
-const _SYS_DUP3 = SYS_DUP3
+const (
+	_SYS_DUP3         = SYS_DUP3
+	_F_DUP2FD_CLOEXEC = 0
+)
 
 func setTimespec(sec, nsec int64) Timespec {
 	return Timespec{Sec: sec, Nsec: nsec}
diff --git a/src/syscall/syscall_solaris.go b/src/syscall/syscall_solaris.go
index 0363597..2d042ac 100644
--- a/src/syscall/syscall_solaris.go
+++ b/src/syscall/syscall_solaris.go
@@ -14,13 +14,13 @@
 
 import "unsafe"
 
+const _F_DUP2FD_CLOEXEC = F_DUP2FD_CLOEXEC
+
 func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
 func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
 func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
 func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
 
-const _F_DUP2FD_CLOEXEC = F_DUP2FD_CLOEXEC
-
 // Implemented in asm_solaris_amd64.s.
 func rawSysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
 func sysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
@@ -495,6 +495,7 @@
 //sys	socket(domain int, typ int, proto int) (fd int, err error) = libsocket.__xnet_socket
 //sysnb	socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) = libsocket.__xnet_socketpair
 //sys	write(fd int, p []byte) (n int, err error)
+//sys	writev(fd int, iovecs []Iovec) (n uintptr, err error)
 //sys	getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) = libsocket.__xnet_getsockopt
 //sysnb	getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = libsocket.getpeername
 //sys	getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = libsocket.getsockname
@@ -536,6 +537,20 @@
 	return
 }
 
+var mapper = &mmapper{
+	active: make(map[*byte][]byte),
+	mmap:   mmap,
+	munmap: munmap,
+}
+
+func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
+	return mapper.Mmap(fd, offset, length, prot, flags)
+}
+
+func Munmap(b []byte) (err error) {
+	return mapper.Munmap(b)
+}
+
 func Utimes(path string, tv []Timeval) error {
 	if len(tv) != 2 {
 		return EINVAL
diff --git a/src/syscall/syscall_solarisonly.go b/src/syscall/syscall_solarisonly.go
new file mode 100644
index 0000000..0877bd7
--- /dev/null
+++ b/src/syscall/syscall_solarisonly.go
@@ -0,0 +1,10 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build solaris && !illumos
+
+package syscall
+
+// F_DUP2FD_CLOEXEC has different values on Solaris and Illumos.
+const F_DUP2FD_CLOEXEC = 0x30
diff --git a/src/syscall/syscall_unix.go b/src/syscall/syscall_unix.go
index cf0e238..c59d4fc 100644
--- a/src/syscall/syscall_unix.go
+++ b/src/syscall/syscall_unix.go
@@ -11,7 +11,6 @@
 	"internal/itoa"
 	"internal/oserror"
 	"internal/race"
-	"internal/unsafeheader"
 	"runtime"
 	"sync"
 	"unsafe"
@@ -57,11 +56,7 @@
 	}
 
 	// Use unsafe to turn addr into a []byte.
-	var b []byte
-	hdr := (*unsafeheader.Slice)(unsafe.Pointer(&b))
-	hdr.Data = unsafe.Pointer(addr)
-	hdr.Cap = length
-	hdr.Len = length
+	b := unsafe.Slice((*byte)(unsafe.Pointer(addr)), length)
 
 	// Register mapping in m and return it.
 	p := &b[cap(b)-1]
@@ -442,11 +437,17 @@
 }
 
 func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
-	ptr, n, err := to.sockaddr()
-	if err != nil {
-		return err
+	var (
+		ptr   unsafe.Pointer
+		salen _Socklen
+	)
+	if to != nil {
+		ptr, salen, err = to.sockaddr()
+		if err != nil {
+			return err
+		}
 	}
-	return sendto(fd, p, flags, ptr, n)
+	return sendto(fd, p, flags, ptr, salen)
 }
 
 func SetsockoptByte(fd, level, opt int, value byte) (err error) {
diff --git a/src/syscall/syscall_windows.go b/src/syscall/syscall_windows.go
index ebaf843..4fbcdcd 100644
--- a/src/syscall/syscall_windows.go
+++ b/src/syscall/syscall_windows.go
@@ -12,7 +12,6 @@
 	"internal/itoa"
 	"internal/oserror"
 	"internal/race"
-	"internal/unsafeheader"
 	"runtime"
 	"sync"
 	"unicode/utf16"
@@ -43,7 +42,13 @@
 	if bytealg.IndexByteString(s, 0) != -1 {
 		return nil, EINVAL
 	}
-	return utf16.Encode([]rune(s + "\x00")), nil
+	// In the worst case all characters require two uint16.
+	// Also account for the terminating NULL character.
+	buf := make([]uint16, 0, len(s)*2+1)
+	for _, r := range s {
+		buf = utf16.AppendRune(buf, r)
+	}
+	return utf16.AppendRune(buf, '\x00'), nil
 }
 
 // UTF16ToString returns the UTF-8 encoding of the UTF-16 sequence s,
@@ -72,11 +77,7 @@
 		n++
 	}
 	// Turn *uint16 into []uint16.
-	var s []uint16
-	hdr := (*unsafeheader.Slice)(unsafe.Pointer(&s))
-	hdr.Data = unsafe.Pointer(p)
-	hdr.Cap = n
-	hdr.Len = n
+	s := unsafe.Slice(p, n)
 	// Decode []uint16 into string.
 	return string(utf16.Decode(s))
 }
@@ -370,8 +371,11 @@
 			}
 		}
 	}
-	h, e := CreateFile(pathp, access, sharemode, sa, createmode, attrs, 0)
-	return h, e
+	if createmode == OPEN_EXISTING && access == GENERIC_READ {
+		// Necessary for opening directory handles.
+		attrs |= FILE_FLAG_BACKUP_SEMANTICS
+	}
+	return CreateFile(pathp, access, sharemode, sa, createmode, attrs, 0)
 }
 
 func Read(fd Handle, p []byte) (n int, err error) {
@@ -915,9 +919,13 @@
 }
 
 func WSASendto(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to Sockaddr, overlapped *Overlapped, croutine *byte) (err error) {
-	rsa, len, err := to.sockaddr()
-	if err != nil {
-		return err
+	var rsa unsafe.Pointer
+	var len int32
+	if to != nil {
+		rsa, len, err = to.sockaddr()
+		if err != nil {
+			return err
+		}
 	}
 	r1, _, e1 := Syscall9(procWSASendTo.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(rsa)), uintptr(len), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)))
 	if r1 == socket_error {
diff --git a/src/syscall/syscall_windows_test.go b/src/syscall/syscall_windows_test.go
index 87f6580..3b56721 100644
--- a/src/syscall/syscall_windows_test.go
+++ b/src/syscall/syscall_windows_test.go
@@ -15,6 +15,28 @@
 	"testing"
 )
 
+func TestOpen_Dir(t *testing.T) {
+	dir := t.TempDir()
+
+	h, err := syscall.Open(dir, syscall.O_RDONLY, 0)
+	if err != nil {
+		t.Fatalf("Open failed: %v", err)
+	}
+	syscall.CloseHandle(h)
+	h, err = syscall.Open(dir, syscall.O_RDONLY|syscall.O_TRUNC, 0)
+	if err == nil {
+		t.Error("Open should have failed")
+	} else {
+		syscall.CloseHandle(h)
+	}
+	h, err = syscall.Open(dir, syscall.O_RDONLY|syscall.O_CREAT, 0)
+	if err == nil {
+		t.Error("Open should have failed")
+	} else {
+		syscall.CloseHandle(h)
+	}
+}
+
 func TestWin32finddata(t *testing.T) {
 	dir := t.TempDir()
 
diff --git a/src/syscall/types_freebsd.go b/src/syscall/types_freebsd.go
index 83bc7dc..7031015 100644
--- a/src/syscall/types_freebsd.go
+++ b/src/syscall/types_freebsd.go
@@ -14,9 +14,6 @@
 package syscall
 
 /*
-#define	_WANT_FREEBSD11_STAT	1
-#define	_WANT_FREEBSD11_STATFS	1
-#define	_WANT_FREEBSD11_DIRENT	1
 #define	_WANT_FREEBSD11_KEVENT	1
 
 #include <dirent.h>
@@ -172,18 +169,12 @@
 
 type Stat_t C.struct_stat
 
-type stat_freebsd11_t C.struct_freebsd11_stat
-
 type Statfs_t C.struct_statfs
 
-type statfs_freebsd11_t C.struct_freebsd11_statfs
-
 type Flock_t C.struct_flock
 
 type Dirent C.struct_dirent
 
-type dirent_freebsd11 C.struct_freebsd11_dirent
-
 type Fsid C.struct_fsid
 
 // File system limits
diff --git a/src/syscall/zerrors_freebsd_riscv64.go b/src/syscall/zerrors_freebsd_riscv64.go
new file mode 100644
index 0000000..7aa9aa9
--- /dev/null
+++ b/src/syscall/zerrors_freebsd_riscv64.go
@@ -0,0 +1,1718 @@
+// mkerrors.sh -m64
+// Code generated by the command above; DO NOT EDIT.
+
+//go:build freebsd && riscv64
+
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs -- -m64 _const.go
+
+package syscall
+
+const (
+	AF_APPLETALK                      = 0x10
+	AF_ARP                            = 0x23
+	AF_ATM                            = 0x1e
+	AF_BLUETOOTH                      = 0x24
+	AF_CCITT                          = 0xa
+	AF_CHAOS                          = 0x5
+	AF_CNT                            = 0x15
+	AF_COIP                           = 0x14
+	AF_DATAKIT                        = 0x9
+	AF_DECnet                         = 0xc
+	AF_DLI                            = 0xd
+	AF_E164                           = 0x1a
+	AF_ECMA                           = 0x8
+	AF_HYLINK                         = 0xf
+	AF_IEEE80211                      = 0x25
+	AF_IMPLINK                        = 0x3
+	AF_INET                           = 0x2
+	AF_INET6                          = 0x1c
+	AF_INET6_SDP                      = 0x2a
+	AF_INET_SDP                       = 0x28
+	AF_IPX                            = 0x17
+	AF_ISDN                           = 0x1a
+	AF_ISO                            = 0x7
+	AF_LAT                            = 0xe
+	AF_LINK                           = 0x12
+	AF_LOCAL                          = 0x1
+	AF_MAX                            = 0x2a
+	AF_NATM                           = 0x1d
+	AF_NETBIOS                        = 0x6
+	AF_NETGRAPH                       = 0x20
+	AF_OSI                            = 0x7
+	AF_PUP                            = 0x4
+	AF_ROUTE                          = 0x11
+	AF_SCLUSTER                       = 0x22
+	AF_SIP                            = 0x18
+	AF_SLOW                           = 0x21
+	AF_SNA                            = 0xb
+	AF_UNIX                           = 0x1
+	AF_UNSPEC                         = 0x0
+	AF_VENDOR00                       = 0x27
+	AF_VENDOR01                       = 0x29
+	AF_VENDOR02                       = 0x2b
+	AF_VENDOR03                       = 0x2d
+	AF_VENDOR04                       = 0x2f
+	AF_VENDOR05                       = 0x31
+	AF_VENDOR06                       = 0x33
+	AF_VENDOR07                       = 0x35
+	AF_VENDOR08                       = 0x37
+	AF_VENDOR09                       = 0x39
+	AF_VENDOR10                       = 0x3b
+	AF_VENDOR11                       = 0x3d
+	AF_VENDOR12                       = 0x3f
+	AF_VENDOR13                       = 0x41
+	AF_VENDOR14                       = 0x43
+	AF_VENDOR15                       = 0x45
+	AF_VENDOR16                       = 0x47
+	AF_VENDOR17                       = 0x49
+	AF_VENDOR18                       = 0x4b
+	AF_VENDOR19                       = 0x4d
+	AF_VENDOR20                       = 0x4f
+	AF_VENDOR21                       = 0x51
+	AF_VENDOR22                       = 0x53
+	AF_VENDOR23                       = 0x55
+	AF_VENDOR24                       = 0x57
+	AF_VENDOR25                       = 0x59
+	AF_VENDOR26                       = 0x5b
+	AF_VENDOR27                       = 0x5d
+	AF_VENDOR28                       = 0x5f
+	AF_VENDOR29                       = 0x61
+	AF_VENDOR30                       = 0x63
+	AF_VENDOR31                       = 0x65
+	AF_VENDOR32                       = 0x67
+	AF_VENDOR33                       = 0x69
+	AF_VENDOR34                       = 0x6b
+	AF_VENDOR35                       = 0x6d
+	AF_VENDOR36                       = 0x6f
+	AF_VENDOR37                       = 0x71
+	AF_VENDOR38                       = 0x73
+	AF_VENDOR39                       = 0x75
+	AF_VENDOR40                       = 0x77
+	AF_VENDOR41                       = 0x79
+	AF_VENDOR42                       = 0x7b
+	AF_VENDOR43                       = 0x7d
+	AF_VENDOR44                       = 0x7f
+	AF_VENDOR45                       = 0x81
+	AF_VENDOR46                       = 0x83
+	AF_VENDOR47                       = 0x85
+	B0                                = 0x0
+	B110                              = 0x6e
+	B115200                           = 0x1c200
+	B1200                             = 0x4b0
+	B134                              = 0x86
+	B14400                            = 0x3840
+	B150                              = 0x96
+	B1800                             = 0x708
+	B19200                            = 0x4b00
+	B200                              = 0xc8
+	B230400                           = 0x38400
+	B2400                             = 0x960
+	B28800                            = 0x7080
+	B300                              = 0x12c
+	B38400                            = 0x9600
+	B460800                           = 0x70800
+	B4800                             = 0x12c0
+	B50                               = 0x32
+	B57600                            = 0xe100
+	B600                              = 0x258
+	B7200                             = 0x1c20
+	B75                               = 0x4b
+	B76800                            = 0x12c00
+	B921600                           = 0xe1000
+	B9600                             = 0x2580
+	BIOCFEEDBACK                      = 0x8004427c
+	BIOCFLUSH                         = 0x20004268
+	BIOCGBLEN                         = 0x40044266
+	BIOCGDIRECTION                    = 0x40044276
+	BIOCGDLT                          = 0x4004426a
+	BIOCGDLTLIST                      = 0xc0104279
+	BIOCGETBUFMODE                    = 0x4004427d
+	BIOCGETIF                         = 0x4020426b
+	BIOCGETZMAX                       = 0x4008427f
+	BIOCGHDRCMPLT                     = 0x40044274
+	BIOCGRSIG                         = 0x40044272
+	BIOCGRTIMEOUT                     = 0x4010426e
+	BIOCGSEESENT                      = 0x40044276
+	BIOCGSTATS                        = 0x4008426f
+	BIOCGTSTAMP                       = 0x40044283
+	BIOCIMMEDIATE                     = 0x80044270
+	BIOCLOCK                          = 0x2000427a
+	BIOCPROMISC                       = 0x20004269
+	BIOCROTZBUF                       = 0x40184280
+	BIOCSBLEN                         = 0xc0044266
+	BIOCSDIRECTION                    = 0x80044277
+	BIOCSDLT                          = 0x80044278
+	BIOCSETBUFMODE                    = 0x8004427e
+	BIOCSETF                          = 0x80104267
+	BIOCSETFNR                        = 0x80104282
+	BIOCSETIF                         = 0x8020426c
+	BIOCSETWF                         = 0x8010427b
+	BIOCSETZBUF                       = 0x80184281
+	BIOCSHDRCMPLT                     = 0x80044275
+	BIOCSRSIG                         = 0x80044273
+	BIOCSRTIMEOUT                     = 0x8010426d
+	BIOCSSEESENT                      = 0x80044277
+	BIOCSTSTAMP                       = 0x80044284
+	BIOCVERSION                       = 0x40044271
+	BPF_A                             = 0x10
+	BPF_ABS                           = 0x20
+	BPF_ADD                           = 0x0
+	BPF_ALIGNMENT                     = 0x8
+	BPF_ALU                           = 0x4
+	BPF_AND                           = 0x50
+	BPF_B                             = 0x10
+	BPF_BUFMODE_BUFFER                = 0x1
+	BPF_BUFMODE_ZBUF                  = 0x2
+	BPF_DIV                           = 0x30
+	BPF_H                             = 0x8
+	BPF_IMM                           = 0x0
+	BPF_IND                           = 0x40
+	BPF_JA                            = 0x0
+	BPF_JEQ                           = 0x10
+	BPF_JGE                           = 0x30
+	BPF_JGT                           = 0x20
+	BPF_JMP                           = 0x5
+	BPF_JSET                          = 0x40
+	BPF_K                             = 0x0
+	BPF_LD                            = 0x0
+	BPF_LDX                           = 0x1
+	BPF_LEN                           = 0x80
+	BPF_LSH                           = 0x60
+	BPF_MAJOR_VERSION                 = 0x1
+	BPF_MAXBUFSIZE                    = 0x80000
+	BPF_MAXINSNS                      = 0x200
+	BPF_MEM                           = 0x60
+	BPF_MEMWORDS                      = 0x10
+	BPF_MINBUFSIZE                    = 0x20
+	BPF_MINOR_VERSION                 = 0x1
+	BPF_MISC                          = 0x7
+	BPF_MSH                           = 0xa0
+	BPF_MUL                           = 0x20
+	BPF_NEG                           = 0x80
+	BPF_OR                            = 0x40
+	BPF_RELEASE                       = 0x30bb6
+	BPF_RET                           = 0x6
+	BPF_RSH                           = 0x70
+	BPF_ST                            = 0x2
+	BPF_STX                           = 0x3
+	BPF_SUB                           = 0x10
+	BPF_TAX                           = 0x0
+	BPF_TXA                           = 0x80
+	BPF_T_BINTIME                     = 0x2
+	BPF_T_BINTIME_FAST                = 0x102
+	BPF_T_BINTIME_MONOTONIC           = 0x202
+	BPF_T_BINTIME_MONOTONIC_FAST      = 0x302
+	BPF_T_FAST                        = 0x100
+	BPF_T_FLAG_MASK                   = 0x300
+	BPF_T_FORMAT_MASK                 = 0x3
+	BPF_T_MICROTIME                   = 0x0
+	BPF_T_MICROTIME_FAST              = 0x100
+	BPF_T_MICROTIME_MONOTONIC         = 0x200
+	BPF_T_MICROTIME_MONOTONIC_FAST    = 0x300
+	BPF_T_MONOTONIC                   = 0x200
+	BPF_T_MONOTONIC_FAST              = 0x300
+	BPF_T_NANOTIME                    = 0x1
+	BPF_T_NANOTIME_FAST               = 0x101
+	BPF_T_NANOTIME_MONOTONIC          = 0x201
+	BPF_T_NANOTIME_MONOTONIC_FAST     = 0x301
+	BPF_T_NONE                        = 0x3
+	BPF_T_NORMAL                      = 0x0
+	BPF_W                             = 0x0
+	BPF_X                             = 0x8
+	BRKINT                            = 0x2
+	CFLUSH                            = 0xf
+	CLOCAL                            = 0x8000
+	CREAD                             = 0x800
+	CS5                               = 0x0
+	CS6                               = 0x100
+	CS7                               = 0x200
+	CS8                               = 0x300
+	CSIZE                             = 0x300
+	CSTART                            = 0x11
+	CSTATUS                           = 0x14
+	CSTOP                             = 0x13
+	CSTOPB                            = 0x400
+	CSUSP                             = 0x1a
+	CTL_MAXNAME                       = 0x18
+	CTL_NET                           = 0x4
+	DLT_A429                          = 0xb8
+	DLT_A653_ICM                      = 0xb9
+	DLT_AIRONET_HEADER                = 0x78
+	DLT_AOS                           = 0xde
+	DLT_APPLE_IP_OVER_IEEE1394        = 0x8a
+	DLT_ARCNET                        = 0x7
+	DLT_ARCNET_LINUX                  = 0x81
+	DLT_ATM_CLIP                      = 0x13
+	DLT_ATM_RFC1483                   = 0xb
+	DLT_AURORA                        = 0x7e
+	DLT_AX25                          = 0x3
+	DLT_AX25_KISS                     = 0xca
+	DLT_BACNET_MS_TP                  = 0xa5
+	DLT_BLUETOOTH_HCI_H4              = 0xbb
+	DLT_BLUETOOTH_HCI_H4_WITH_PHDR    = 0xc9
+	DLT_CAN20B                        = 0xbe
+	DLT_CAN_SOCKETCAN                 = 0xe3
+	DLT_CHAOS                         = 0x5
+	DLT_CHDLC                         = 0x68
+	DLT_CISCO_IOS                     = 0x76
+	DLT_C_HDLC                        = 0x68
+	DLT_C_HDLC_WITH_DIR               = 0xcd
+	DLT_DBUS                          = 0xe7
+	DLT_DECT                          = 0xdd
+	DLT_DOCSIS                        = 0x8f
+	DLT_DVB_CI                        = 0xeb
+	DLT_ECONET                        = 0x73
+	DLT_EN10MB                        = 0x1
+	DLT_EN3MB                         = 0x2
+	DLT_ENC                           = 0x6d
+	DLT_ERF                           = 0xc5
+	DLT_ERF_ETH                       = 0xaf
+	DLT_ERF_POS                       = 0xb0
+	DLT_FC_2                          = 0xe0
+	DLT_FC_2_WITH_FRAME_DELIMS        = 0xe1
+	DLT_FDDI                          = 0xa
+	DLT_FLEXRAY                       = 0xd2
+	DLT_FRELAY                        = 0x6b
+	DLT_FRELAY_WITH_DIR               = 0xce
+	DLT_GCOM_SERIAL                   = 0xad
+	DLT_GCOM_T1E1                     = 0xac
+	DLT_GPF_F                         = 0xab
+	DLT_GPF_T                         = 0xaa
+	DLT_GPRS_LLC                      = 0xa9
+	DLT_GSMTAP_ABIS                   = 0xda
+	DLT_GSMTAP_UM                     = 0xd9
+	DLT_HHDLC                         = 0x79
+	DLT_IBM_SN                        = 0x92
+	DLT_IBM_SP                        = 0x91
+	DLT_IEEE802                       = 0x6
+	DLT_IEEE802_11                    = 0x69
+	DLT_IEEE802_11_RADIO              = 0x7f
+	DLT_IEEE802_11_RADIO_AVS          = 0xa3
+	DLT_IEEE802_15_4                  = 0xc3
+	DLT_IEEE802_15_4_LINUX            = 0xbf
+	DLT_IEEE802_15_4_NOFCS            = 0xe6
+	DLT_IEEE802_15_4_NONASK_PHY       = 0xd7
+	DLT_IEEE802_16_MAC_CPS            = 0xbc
+	DLT_IEEE802_16_MAC_CPS_RADIO      = 0xc1
+	DLT_IPFILTER                      = 0x74
+	DLT_IPMB                          = 0xc7
+	DLT_IPMB_LINUX                    = 0xd1
+	DLT_IPNET                         = 0xe2
+	DLT_IPOIB                         = 0xf2
+	DLT_IPV4                          = 0xe4
+	DLT_IPV6                          = 0xe5
+	DLT_IP_OVER_FC                    = 0x7a
+	DLT_JUNIPER_ATM1                  = 0x89
+	DLT_JUNIPER_ATM2                  = 0x87
+	DLT_JUNIPER_ATM_CEMIC             = 0xee
+	DLT_JUNIPER_CHDLC                 = 0xb5
+	DLT_JUNIPER_ES                    = 0x84
+	DLT_JUNIPER_ETHER                 = 0xb2
+	DLT_JUNIPER_FIBRECHANNEL          = 0xea
+	DLT_JUNIPER_FRELAY                = 0xb4
+	DLT_JUNIPER_GGSN                  = 0x85
+	DLT_JUNIPER_ISM                   = 0xc2
+	DLT_JUNIPER_MFR                   = 0x86
+	DLT_JUNIPER_MLFR                  = 0x83
+	DLT_JUNIPER_MLPPP                 = 0x82
+	DLT_JUNIPER_MONITOR               = 0xa4
+	DLT_JUNIPER_PIC_PEER              = 0xae
+	DLT_JUNIPER_PPP                   = 0xb3
+	DLT_JUNIPER_PPPOE                 = 0xa7
+	DLT_JUNIPER_PPPOE_ATM             = 0xa8
+	DLT_JUNIPER_SERVICES              = 0x88
+	DLT_JUNIPER_SRX_E2E               = 0xe9
+	DLT_JUNIPER_ST                    = 0xc8
+	DLT_JUNIPER_VP                    = 0xb7
+	DLT_JUNIPER_VS                    = 0xe8
+	DLT_LAPB_WITH_DIR                 = 0xcf
+	DLT_LAPD                          = 0xcb
+	DLT_LIN                           = 0xd4
+	DLT_LINUX_EVDEV                   = 0xd8
+	DLT_LINUX_IRDA                    = 0x90
+	DLT_LINUX_LAPD                    = 0xb1
+	DLT_LINUX_PPP_WITHDIRECTION       = 0xa6
+	DLT_LINUX_SLL                     = 0x71
+	DLT_LOOP                          = 0x6c
+	DLT_LTALK                         = 0x72
+	DLT_MATCHING_MAX                  = 0xf6
+	DLT_MATCHING_MIN                  = 0x68
+	DLT_MFR                           = 0xb6
+	DLT_MOST                          = 0xd3
+	DLT_MPEG_2_TS                     = 0xf3
+	DLT_MPLS                          = 0xdb
+	DLT_MTP2                          = 0x8c
+	DLT_MTP2_WITH_PHDR                = 0x8b
+	DLT_MTP3                          = 0x8d
+	DLT_MUX27010                      = 0xec
+	DLT_NETANALYZER                   = 0xf0
+	DLT_NETANALYZER_TRANSPARENT       = 0xf1
+	DLT_NFC_LLCP                      = 0xf5
+	DLT_NFLOG                         = 0xef
+	DLT_NG40                          = 0xf4
+	DLT_NULL                          = 0x0
+	DLT_PCI_EXP                       = 0x7d
+	DLT_PFLOG                         = 0x75
+	DLT_PFSYNC                        = 0x79
+	DLT_PPI                           = 0xc0
+	DLT_PPP                           = 0x9
+	DLT_PPP_BSDOS                     = 0x10
+	DLT_PPP_ETHER                     = 0x33
+	DLT_PPP_PPPD                      = 0xa6
+	DLT_PPP_SERIAL                    = 0x32
+	DLT_PPP_WITH_DIR                  = 0xcc
+	DLT_PPP_WITH_DIRECTION            = 0xa6
+	DLT_PRISM_HEADER                  = 0x77
+	DLT_PRONET                        = 0x4
+	DLT_RAIF1                         = 0xc6
+	DLT_RAW                           = 0xc
+	DLT_RIO                           = 0x7c
+	DLT_SCCP                          = 0x8e
+	DLT_SITA                          = 0xc4
+	DLT_SLIP                          = 0x8
+	DLT_SLIP_BSDOS                    = 0xf
+	DLT_STANAG_5066_D_PDU             = 0xed
+	DLT_SUNATM                        = 0x7b
+	DLT_SYMANTEC_FIREWALL             = 0x63
+	DLT_TZSP                          = 0x80
+	DLT_USB                           = 0xba
+	DLT_USB_LINUX                     = 0xbd
+	DLT_USB_LINUX_MMAPPED             = 0xdc
+	DLT_USER0                         = 0x93
+	DLT_USER1                         = 0x94
+	DLT_USER10                        = 0x9d
+	DLT_USER11                        = 0x9e
+	DLT_USER12                        = 0x9f
+	DLT_USER13                        = 0xa0
+	DLT_USER14                        = 0xa1
+	DLT_USER15                        = 0xa2
+	DLT_USER2                         = 0x95
+	DLT_USER3                         = 0x96
+	DLT_USER4                         = 0x97
+	DLT_USER5                         = 0x98
+	DLT_USER6                         = 0x99
+	DLT_USER7                         = 0x9a
+	DLT_USER8                         = 0x9b
+	DLT_USER9                         = 0x9c
+	DLT_WIHART                        = 0xdf
+	DLT_X2E_SERIAL                    = 0xd5
+	DLT_X2E_XORAYA                    = 0xd6
+	DT_BLK                            = 0x6
+	DT_CHR                            = 0x2
+	DT_DIR                            = 0x4
+	DT_FIFO                           = 0x1
+	DT_LNK                            = 0xa
+	DT_REG                            = 0x8
+	DT_SOCK                           = 0xc
+	DT_UNKNOWN                        = 0x0
+	DT_WHT                            = 0xe
+	ECHO                              = 0x8
+	ECHOCTL                           = 0x40
+	ECHOE                             = 0x2
+	ECHOK                             = 0x4
+	ECHOKE                            = 0x1
+	ECHONL                            = 0x10
+	ECHOPRT                           = 0x20
+	EVFILT_AIO                        = -0x3
+	EVFILT_FS                         = -0x9
+	EVFILT_LIO                        = -0xa
+	EVFILT_PROC                       = -0x5
+	EVFILT_READ                       = -0x1
+	EVFILT_SIGNAL                     = -0x6
+	EVFILT_SYSCOUNT                   = 0xb
+	EVFILT_TIMER                      = -0x7
+	EVFILT_USER                       = -0xb
+	EVFILT_VNODE                      = -0x4
+	EVFILT_WRITE                      = -0x2
+	EV_ADD                            = 0x1
+	EV_CLEAR                          = 0x20
+	EV_DELETE                         = 0x2
+	EV_DISABLE                        = 0x8
+	EV_DISPATCH                       = 0x80
+	EV_DROP                           = 0x1000
+	EV_ENABLE                         = 0x4
+	EV_EOF                            = 0x8000
+	EV_ERROR                          = 0x4000
+	EV_FLAG1                          = 0x2000
+	EV_ONESHOT                        = 0x10
+	EV_RECEIPT                        = 0x40
+	EV_SYSFLAGS                       = 0xf000
+	EXTA                              = 0x4b00
+	EXTB                              = 0x9600
+	EXTPROC                           = 0x800
+	FD_CLOEXEC                        = 0x1
+	FD_SETSIZE                        = 0x400
+	FLUSHO                            = 0x800000
+	F_CANCEL                          = 0x5
+	F_DUP2FD                          = 0xa
+	F_DUP2FD_CLOEXEC                  = 0x12
+	F_DUPFD                           = 0x0
+	F_DUPFD_CLOEXEC                   = 0x11
+	F_GETFD                           = 0x1
+	F_GETFL                           = 0x3
+	F_GETLK                           = 0xb
+	F_GETOWN                          = 0x5
+	F_OGETLK                          = 0x7
+	F_OK                              = 0x0
+	F_OSETLK                          = 0x8
+	F_OSETLKW                         = 0x9
+	F_RDAHEAD                         = 0x10
+	F_RDLCK                           = 0x1
+	F_READAHEAD                       = 0xf
+	F_SETFD                           = 0x2
+	F_SETFL                           = 0x4
+	F_SETLK                           = 0xc
+	F_SETLKW                          = 0xd
+	F_SETLK_REMOTE                    = 0xe
+	F_SETOWN                          = 0x6
+	F_UNLCK                           = 0x2
+	F_UNLCKSYS                        = 0x4
+	F_WRLCK                           = 0x3
+	HUPCL                             = 0x4000
+	ICANON                            = 0x100
+	ICMP6_FILTER                      = 0x12
+	ICRNL                             = 0x100
+	IEXTEN                            = 0x400
+	IFAN_ARRIVAL                      = 0x0
+	IFAN_DEPARTURE                    = 0x1
+	IFF_ALLMULTI                      = 0x200
+	IFF_ALTPHYS                       = 0x4000
+	IFF_BROADCAST                     = 0x2
+	IFF_CANTCHANGE                    = 0x218f72
+	IFF_CANTCONFIG                    = 0x10000
+	IFF_DEBUG                         = 0x4
+	IFF_DRV_OACTIVE                   = 0x400
+	IFF_DRV_RUNNING                   = 0x40
+	IFF_DYING                         = 0x200000
+	IFF_LINK0                         = 0x1000
+	IFF_LINK1                         = 0x2000
+	IFF_LINK2                         = 0x4000
+	IFF_LOOPBACK                      = 0x8
+	IFF_MONITOR                       = 0x40000
+	IFF_MULTICAST                     = 0x8000
+	IFF_NOARP                         = 0x80
+	IFF_OACTIVE                       = 0x400
+	IFF_POINTOPOINT                   = 0x10
+	IFF_PPROMISC                      = 0x20000
+	IFF_PROMISC                       = 0x100
+	IFF_RENAMING                      = 0x400000
+	IFF_RUNNING                       = 0x40
+	IFF_SIMPLEX                       = 0x800
+	IFF_SMART                         = 0x20
+	IFF_STATICARP                     = 0x80000
+	IFF_UP                            = 0x1
+	IFNAMSIZ                          = 0x10
+	IFT_1822                          = 0x2
+	IFT_A12MPPSWITCH                  = 0x82
+	IFT_AAL2                          = 0xbb
+	IFT_AAL5                          = 0x31
+	IFT_ADSL                          = 0x5e
+	IFT_AFLANE8023                    = 0x3b
+	IFT_AFLANE8025                    = 0x3c
+	IFT_ARAP                          = 0x58
+	IFT_ARCNET                        = 0x23
+	IFT_ARCNETPLUS                    = 0x24
+	IFT_ASYNC                         = 0x54
+	IFT_ATM                           = 0x25
+	IFT_ATMDXI                        = 0x69
+	IFT_ATMFUNI                       = 0x6a
+	IFT_ATMIMA                        = 0x6b
+	IFT_ATMLOGICAL                    = 0x50
+	IFT_ATMRADIO                      = 0xbd
+	IFT_ATMSUBINTERFACE               = 0x86
+	IFT_ATMVCIENDPT                   = 0xc2
+	IFT_ATMVIRTUAL                    = 0x95
+	IFT_BGPPOLICYACCOUNTING           = 0xa2
+	IFT_BRIDGE                        = 0xd1
+	IFT_BSC                           = 0x53
+	IFT_CARP                          = 0xf8
+	IFT_CCTEMUL                       = 0x3d
+	IFT_CEPT                          = 0x13
+	IFT_CES                           = 0x85
+	IFT_CHANNEL                       = 0x46
+	IFT_CNR                           = 0x55
+	IFT_COFFEE                        = 0x84
+	IFT_COMPOSITELINK                 = 0x9b
+	IFT_DCN                           = 0x8d
+	IFT_DIGITALPOWERLINE              = 0x8a
+	IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
+	IFT_DLSW                          = 0x4a
+	IFT_DOCSCABLEDOWNSTREAM           = 0x80
+	IFT_DOCSCABLEMACLAYER             = 0x7f
+	IFT_DOCSCABLEUPSTREAM             = 0x81
+	IFT_DS0                           = 0x51
+	IFT_DS0BUNDLE                     = 0x52
+	IFT_DS1FDL                        = 0xaa
+	IFT_DS3                           = 0x1e
+	IFT_DTM                           = 0x8c
+	IFT_DVBASILN                      = 0xac
+	IFT_DVBASIOUT                     = 0xad
+	IFT_DVBRCCDOWNSTREAM              = 0x93
+	IFT_DVBRCCMACLAYER                = 0x92
+	IFT_DVBRCCUPSTREAM                = 0x94
+	IFT_ENC                           = 0xf4
+	IFT_EON                           = 0x19
+	IFT_EPLRS                         = 0x57
+	IFT_ESCON                         = 0x49
+	IFT_ETHER                         = 0x6
+	IFT_FAITH                         = 0xf2
+	IFT_FAST                          = 0x7d
+	IFT_FASTETHER                     = 0x3e
+	IFT_FASTETHERFX                   = 0x45
+	IFT_FDDI                          = 0xf
+	IFT_FIBRECHANNEL                  = 0x38
+	IFT_FRAMERELAYINTERCONNECT        = 0x3a
+	IFT_FRAMERELAYMPI                 = 0x5c
+	IFT_FRDLCIENDPT                   = 0xc1
+	IFT_FRELAY                        = 0x20
+	IFT_FRELAYDCE                     = 0x2c
+	IFT_FRF16MFRBUNDLE                = 0xa3
+	IFT_FRFORWARD                     = 0x9e
+	IFT_G703AT2MB                     = 0x43
+	IFT_G703AT64K                     = 0x42
+	IFT_GIF                           = 0xf0
+	IFT_GIGABITETHERNET               = 0x75
+	IFT_GR303IDT                      = 0xb2
+	IFT_GR303RDT                      = 0xb1
+	IFT_H323GATEKEEPER                = 0xa4
+	IFT_H323PROXY                     = 0xa5
+	IFT_HDH1822                       = 0x3
+	IFT_HDLC                          = 0x76
+	IFT_HDSL2                         = 0xa8
+	IFT_HIPERLAN2                     = 0xb7
+	IFT_HIPPI                         = 0x2f
+	IFT_HIPPIINTERFACE                = 0x39
+	IFT_HOSTPAD                       = 0x5a
+	IFT_HSSI                          = 0x2e
+	IFT_HY                            = 0xe
+	IFT_IBM370PARCHAN                 = 0x48
+	IFT_IDSL                          = 0x9a
+	IFT_IEEE1394                      = 0x90
+	IFT_IEEE80211                     = 0x47
+	IFT_IEEE80212                     = 0x37
+	IFT_IEEE8023ADLAG                 = 0xa1
+	IFT_IFGSN                         = 0x91
+	IFT_IMT                           = 0xbe
+	IFT_INFINIBAND                    = 0xc7
+	IFT_INTERLEAVE                    = 0x7c
+	IFT_IP                            = 0x7e
+	IFT_IPFORWARD                     = 0x8e
+	IFT_IPOVERATM                     = 0x72
+	IFT_IPOVERCDLC                    = 0x6d
+	IFT_IPOVERCLAW                    = 0x6e
+	IFT_IPSWITCH                      = 0x4e
+	IFT_IPXIP                         = 0xf9
+	IFT_ISDN                          = 0x3f
+	IFT_ISDNBASIC                     = 0x14
+	IFT_ISDNPRIMARY                   = 0x15
+	IFT_ISDNS                         = 0x4b
+	IFT_ISDNU                         = 0x4c
+	IFT_ISO88022LLC                   = 0x29
+	IFT_ISO88023                      = 0x7
+	IFT_ISO88024                      = 0x8
+	IFT_ISO88025                      = 0x9
+	IFT_ISO88025CRFPINT               = 0x62
+	IFT_ISO88025DTR                   = 0x56
+	IFT_ISO88025FIBER                 = 0x73
+	IFT_ISO88026                      = 0xa
+	IFT_ISUP                          = 0xb3
+	IFT_L2VLAN                        = 0x87
+	IFT_L3IPVLAN                      = 0x88
+	IFT_L3IPXVLAN                     = 0x89
+	IFT_LAPB                          = 0x10
+	IFT_LAPD                          = 0x4d
+	IFT_LAPF                          = 0x77
+	IFT_LOCALTALK                     = 0x2a
+	IFT_LOOP                          = 0x18
+	IFT_MEDIAMAILOVERIP               = 0x8b
+	IFT_MFSIGLINK                     = 0xa7
+	IFT_MIOX25                        = 0x26
+	IFT_MODEM                         = 0x30
+	IFT_MPC                           = 0x71
+	IFT_MPLS                          = 0xa6
+	IFT_MPLSTUNNEL                    = 0x96
+	IFT_MSDSL                         = 0x8f
+	IFT_MVL                           = 0xbf
+	IFT_MYRINET                       = 0x63
+	IFT_NFAS                          = 0xaf
+	IFT_NSIP                          = 0x1b
+	IFT_OPTICALCHANNEL                = 0xc3
+	IFT_OPTICALTRANSPORT              = 0xc4
+	IFT_OTHER                         = 0x1
+	IFT_P10                           = 0xc
+	IFT_P80                           = 0xd
+	IFT_PARA                          = 0x22
+	IFT_PFLOG                         = 0xf6
+	IFT_PFSYNC                        = 0xf7
+	IFT_PLC                           = 0xae
+	IFT_POS                           = 0xab
+	IFT_PPP                           = 0x17
+	IFT_PPPMULTILINKBUNDLE            = 0x6c
+	IFT_PROPBWAP2MP                   = 0xb8
+	IFT_PROPCNLS                      = 0x59
+	IFT_PROPDOCSWIRELESSDOWNSTREAM    = 0xb5
+	IFT_PROPDOCSWIRELESSMACLAYER      = 0xb4
+	IFT_PROPDOCSWIRELESSUPSTREAM      = 0xb6
+	IFT_PROPMUX                       = 0x36
+	IFT_PROPVIRTUAL                   = 0x35
+	IFT_PROPWIRELESSP2P               = 0x9d
+	IFT_PTPSERIAL                     = 0x16
+	IFT_PVC                           = 0xf1
+	IFT_QLLC                          = 0x44
+	IFT_RADIOMAC                      = 0xbc
+	IFT_RADSL                         = 0x5f
+	IFT_REACHDSL                      = 0xc0
+	IFT_RFC1483                       = 0x9f
+	IFT_RS232                         = 0x21
+	IFT_RSRB                          = 0x4f
+	IFT_SDLC                          = 0x11
+	IFT_SDSL                          = 0x60
+	IFT_SHDSL                         = 0xa9
+	IFT_SIP                           = 0x1f
+	IFT_SLIP                          = 0x1c
+	IFT_SMDSDXI                       = 0x2b
+	IFT_SMDSICIP                      = 0x34
+	IFT_SONET                         = 0x27
+	IFT_SONETOVERHEADCHANNEL          = 0xb9
+	IFT_SONETPATH                     = 0x32
+	IFT_SONETVT                       = 0x33
+	IFT_SRP                           = 0x97
+	IFT_SS7SIGLINK                    = 0x9c
+	IFT_STACKTOSTACK                  = 0x6f
+	IFT_STARLAN                       = 0xb
+	IFT_STF                           = 0xd7
+	IFT_T1                            = 0x12
+	IFT_TDLC                          = 0x74
+	IFT_TERMPAD                       = 0x5b
+	IFT_TR008                         = 0xb0
+	IFT_TRANSPHDLC                    = 0x7b
+	IFT_TUNNEL                        = 0x83
+	IFT_ULTRA                         = 0x1d
+	IFT_USB                           = 0xa0
+	IFT_V11                           = 0x40
+	IFT_V35                           = 0x2d
+	IFT_V36                           = 0x41
+	IFT_V37                           = 0x78
+	IFT_VDSL                          = 0x61
+	IFT_VIRTUALIPADDRESS              = 0x70
+	IFT_VOICEEM                       = 0x64
+	IFT_VOICEENCAP                    = 0x67
+	IFT_VOICEFXO                      = 0x65
+	IFT_VOICEFXS                      = 0x66
+	IFT_VOICEOVERATM                  = 0x98
+	IFT_VOICEOVERFRAMERELAY           = 0x99
+	IFT_VOICEOVERIP                   = 0x68
+	IFT_X213                          = 0x5d
+	IFT_X25                           = 0x5
+	IFT_X25DDN                        = 0x4
+	IFT_X25HUNTGROUP                  = 0x7a
+	IFT_X25MLP                        = 0x79
+	IFT_X25PLE                        = 0x28
+	IFT_XETHER                        = 0x1a
+	IGNBRK                            = 0x1
+	IGNCR                             = 0x80
+	IGNPAR                            = 0x4
+	IMAXBEL                           = 0x2000
+	INLCR                             = 0x40
+	INPCK                             = 0x10
+	IN_CLASSA_HOST                    = 0xffffff
+	IN_CLASSA_MAX                     = 0x80
+	IN_CLASSA_NET                     = 0xff000000
+	IN_CLASSA_NSHIFT                  = 0x18
+	IN_CLASSB_HOST                    = 0xffff
+	IN_CLASSB_MAX                     = 0x10000
+	IN_CLASSB_NET                     = 0xffff0000
+	IN_CLASSB_NSHIFT                  = 0x10
+	IN_CLASSC_HOST                    = 0xff
+	IN_CLASSC_NET                     = 0xffffff00
+	IN_CLASSC_NSHIFT                  = 0x8
+	IN_CLASSD_HOST                    = 0xfffffff
+	IN_CLASSD_NET                     = 0xf0000000
+	IN_CLASSD_NSHIFT                  = 0x1c
+	IN_LOOPBACKNET                    = 0x7f
+	IN_RFC3021_MASK                   = 0xfffffffe
+	IPPROTO_3PC                       = 0x22
+	IPPROTO_ADFS                      = 0x44
+	IPPROTO_AH                        = 0x33
+	IPPROTO_AHIP                      = 0x3d
+	IPPROTO_APES                      = 0x63
+	IPPROTO_ARGUS                     = 0xd
+	IPPROTO_AX25                      = 0x5d
+	IPPROTO_BHA                       = 0x31
+	IPPROTO_BLT                       = 0x1e
+	IPPROTO_BRSATMON                  = 0x4c
+	IPPROTO_CARP                      = 0x70
+	IPPROTO_CFTP                      = 0x3e
+	IPPROTO_CHAOS                     = 0x10
+	IPPROTO_CMTP                      = 0x26
+	IPPROTO_CPHB                      = 0x49
+	IPPROTO_CPNX                      = 0x48
+	IPPROTO_DDP                       = 0x25
+	IPPROTO_DGP                       = 0x56
+	IPPROTO_DIVERT                    = 0x102
+	IPPROTO_DONE                      = 0x101
+	IPPROTO_DSTOPTS                   = 0x3c
+	IPPROTO_EGP                       = 0x8
+	IPPROTO_EMCON                     = 0xe
+	IPPROTO_ENCAP                     = 0x62
+	IPPROTO_EON                       = 0x50
+	IPPROTO_ESP                       = 0x32
+	IPPROTO_ETHERIP                   = 0x61
+	IPPROTO_FRAGMENT                  = 0x2c
+	IPPROTO_GGP                       = 0x3
+	IPPROTO_GMTP                      = 0x64
+	IPPROTO_GRE                       = 0x2f
+	IPPROTO_HELLO                     = 0x3f
+	IPPROTO_HMP                       = 0x14
+	IPPROTO_HOPOPTS                   = 0x0
+	IPPROTO_ICMP                      = 0x1
+	IPPROTO_ICMPV6                    = 0x3a
+	IPPROTO_IDP                       = 0x16
+	IPPROTO_IDPR                      = 0x23
+	IPPROTO_IDRP                      = 0x2d
+	IPPROTO_IGMP                      = 0x2
+	IPPROTO_IGP                       = 0x55
+	IPPROTO_IGRP                      = 0x58
+	IPPROTO_IL                        = 0x28
+	IPPROTO_INLSP                     = 0x34
+	IPPROTO_INP                       = 0x20
+	IPPROTO_IP                        = 0x0
+	IPPROTO_IPCOMP                    = 0x6c
+	IPPROTO_IPCV                      = 0x47
+	IPPROTO_IPEIP                     = 0x5e
+	IPPROTO_IPIP                      = 0x4
+	IPPROTO_IPPC                      = 0x43
+	IPPROTO_IPV4                      = 0x4
+	IPPROTO_IPV6                      = 0x29
+	IPPROTO_IRTP                      = 0x1c
+	IPPROTO_KRYPTOLAN                 = 0x41
+	IPPROTO_LARP                      = 0x5b
+	IPPROTO_LEAF1                     = 0x19
+	IPPROTO_LEAF2                     = 0x1a
+	IPPROTO_MAX                       = 0x100
+	IPPROTO_MAXID                     = 0x34
+	IPPROTO_MEAS                      = 0x13
+	IPPROTO_MH                        = 0x87
+	IPPROTO_MHRP                      = 0x30
+	IPPROTO_MICP                      = 0x5f
+	IPPROTO_MOBILE                    = 0x37
+	IPPROTO_MPLS                      = 0x89
+	IPPROTO_MTP                       = 0x5c
+	IPPROTO_MUX                       = 0x12
+	IPPROTO_ND                        = 0x4d
+	IPPROTO_NHRP                      = 0x36
+	IPPROTO_NONE                      = 0x3b
+	IPPROTO_NSP                       = 0x1f
+	IPPROTO_NVPII                     = 0xb
+	IPPROTO_OLD_DIVERT                = 0xfe
+	IPPROTO_OSPFIGP                   = 0x59
+	IPPROTO_PFSYNC                    = 0xf0
+	IPPROTO_PGM                       = 0x71
+	IPPROTO_PIGP                      = 0x9
+	IPPROTO_PIM                       = 0x67
+	IPPROTO_PRM                       = 0x15
+	IPPROTO_PUP                       = 0xc
+	IPPROTO_PVP                       = 0x4b
+	IPPROTO_RAW                       = 0xff
+	IPPROTO_RCCMON                    = 0xa
+	IPPROTO_RDP                       = 0x1b
+	IPPROTO_ROUTING                   = 0x2b
+	IPPROTO_RSVP                      = 0x2e
+	IPPROTO_RVD                       = 0x42
+	IPPROTO_SATEXPAK                  = 0x40
+	IPPROTO_SATMON                    = 0x45
+	IPPROTO_SCCSP                     = 0x60
+	IPPROTO_SCTP                      = 0x84
+	IPPROTO_SDRP                      = 0x2a
+	IPPROTO_SEND                      = 0x103
+	IPPROTO_SEP                       = 0x21
+	IPPROTO_SKIP                      = 0x39
+	IPPROTO_SPACER                    = 0x7fff
+	IPPROTO_SRPC                      = 0x5a
+	IPPROTO_ST                        = 0x7
+	IPPROTO_SVMTP                     = 0x52
+	IPPROTO_SWIPE                     = 0x35
+	IPPROTO_TCF                       = 0x57
+	IPPROTO_TCP                       = 0x6
+	IPPROTO_TLSP                      = 0x38
+	IPPROTO_TP                        = 0x1d
+	IPPROTO_TPXX                      = 0x27
+	IPPROTO_TRUNK1                    = 0x17
+	IPPROTO_TRUNK2                    = 0x18
+	IPPROTO_TTP                       = 0x54
+	IPPROTO_UDP                       = 0x11
+	IPPROTO_VINES                     = 0x53
+	IPPROTO_VISA                      = 0x46
+	IPPROTO_VMTP                      = 0x51
+	IPPROTO_WBEXPAK                   = 0x4f
+	IPPROTO_WBMON                     = 0x4e
+	IPPROTO_WSN                       = 0x4a
+	IPPROTO_XNET                      = 0xf
+	IPPROTO_XTP                       = 0x24
+	IPV6_AUTOFLOWLABEL                = 0x3b
+	IPV6_BINDANY                      = 0x40
+	IPV6_BINDV6ONLY                   = 0x1b
+	IPV6_CHECKSUM                     = 0x1a
+	IPV6_DEFAULT_MULTICAST_HOPS       = 0x1
+	IPV6_DEFAULT_MULTICAST_LOOP       = 0x1
+	IPV6_DEFHLIM                      = 0x40
+	IPV6_DONTFRAG                     = 0x3e
+	IPV6_DSTOPTS                      = 0x32
+	IPV6_FAITH                        = 0x1d
+	IPV6_FLOWINFO_MASK                = 0xffffff0f
+	IPV6_FLOWLABEL_MASK               = 0xffff0f00
+	IPV6_FRAGTTL                      = 0x78
+	IPV6_FW_ADD                       = 0x1e
+	IPV6_FW_DEL                       = 0x1f
+	IPV6_FW_FLUSH                     = 0x20
+	IPV6_FW_GET                       = 0x22
+	IPV6_FW_ZERO                      = 0x21
+	IPV6_HLIMDEC                      = 0x1
+	IPV6_HOPLIMIT                     = 0x2f
+	IPV6_HOPOPTS                      = 0x31
+	IPV6_IPSEC_POLICY                 = 0x1c
+	IPV6_JOIN_GROUP                   = 0xc
+	IPV6_LEAVE_GROUP                  = 0xd
+	IPV6_MAXHLIM                      = 0xff
+	IPV6_MAXOPTHDR                    = 0x800
+	IPV6_MAXPACKET                    = 0xffff
+	IPV6_MAX_GROUP_SRC_FILTER         = 0x200
+	IPV6_MAX_MEMBERSHIPS              = 0xfff
+	IPV6_MAX_SOCK_SRC_FILTER          = 0x80
+	IPV6_MIN_MEMBERSHIPS              = 0x1f
+	IPV6_MMTU                         = 0x500
+	IPV6_MSFILTER                     = 0x4a
+	IPV6_MULTICAST_HOPS               = 0xa
+	IPV6_MULTICAST_IF                 = 0x9
+	IPV6_MULTICAST_LOOP               = 0xb
+	IPV6_NEXTHOP                      = 0x30
+	IPV6_PATHMTU                      = 0x2c
+	IPV6_PKTINFO                      = 0x2e
+	IPV6_PORTRANGE                    = 0xe
+	IPV6_PORTRANGE_DEFAULT            = 0x0
+	IPV6_PORTRANGE_HIGH               = 0x1
+	IPV6_PORTRANGE_LOW                = 0x2
+	IPV6_PREFER_TEMPADDR              = 0x3f
+	IPV6_RECVDSTOPTS                  = 0x28
+	IPV6_RECVHOPLIMIT                 = 0x25
+	IPV6_RECVHOPOPTS                  = 0x27
+	IPV6_RECVPATHMTU                  = 0x2b
+	IPV6_RECVPKTINFO                  = 0x24
+	IPV6_RECVRTHDR                    = 0x26
+	IPV6_RECVTCLASS                   = 0x39
+	IPV6_RTHDR                        = 0x33
+	IPV6_RTHDRDSTOPTS                 = 0x23
+	IPV6_RTHDR_LOOSE                  = 0x0
+	IPV6_RTHDR_STRICT                 = 0x1
+	IPV6_RTHDR_TYPE_0                 = 0x0
+	IPV6_SOCKOPT_RESERVED1            = 0x3
+	IPV6_TCLASS                       = 0x3d
+	IPV6_UNICAST_HOPS                 = 0x4
+	IPV6_USE_MIN_MTU                  = 0x2a
+	IPV6_V6ONLY                       = 0x1b
+	IPV6_VERSION                      = 0x60
+	IPV6_VERSION_MASK                 = 0xf0
+	IP_ADD_MEMBERSHIP                 = 0xc
+	IP_ADD_SOURCE_MEMBERSHIP          = 0x46
+	IP_BINDANY                        = 0x18
+	IP_BLOCK_SOURCE                   = 0x48
+	IP_DEFAULT_MULTICAST_LOOP         = 0x1
+	IP_DEFAULT_MULTICAST_TTL          = 0x1
+	IP_DF                             = 0x4000
+	IP_DONTFRAG                       = 0x43
+	IP_DROP_MEMBERSHIP                = 0xd
+	IP_DROP_SOURCE_MEMBERSHIP         = 0x47
+	IP_DUMMYNET3                      = 0x31
+	IP_DUMMYNET_CONFIGURE             = 0x3c
+	IP_DUMMYNET_DEL                   = 0x3d
+	IP_DUMMYNET_FLUSH                 = 0x3e
+	IP_DUMMYNET_GET                   = 0x40
+	IP_FAITH                          = 0x16
+	IP_FW3                            = 0x30
+	IP_FW_ADD                         = 0x32
+	IP_FW_DEL                         = 0x33
+	IP_FW_FLUSH                       = 0x34
+	IP_FW_GET                         = 0x36
+	IP_FW_NAT_CFG                     = 0x38
+	IP_FW_NAT_DEL                     = 0x39
+	IP_FW_NAT_GET_CONFIG              = 0x3a
+	IP_FW_NAT_GET_LOG                 = 0x3b
+	IP_FW_RESETLOG                    = 0x37
+	IP_FW_TABLE_ADD                   = 0x28
+	IP_FW_TABLE_DEL                   = 0x29
+	IP_FW_TABLE_FLUSH                 = 0x2a
+	IP_FW_TABLE_GETSIZE               = 0x2b
+	IP_FW_TABLE_LIST                  = 0x2c
+	IP_FW_ZERO                        = 0x35
+	IP_HDRINCL                        = 0x2
+	IP_IPSEC_POLICY                   = 0x15
+	IP_MAXPACKET                      = 0xffff
+	IP_MAX_GROUP_SRC_FILTER           = 0x200
+	IP_MAX_MEMBERSHIPS                = 0xfff
+	IP_MAX_SOCK_MUTE_FILTER           = 0x80
+	IP_MAX_SOCK_SRC_FILTER            = 0x80
+	IP_MAX_SOURCE_FILTER              = 0x400
+	IP_MF                             = 0x2000
+	IP_MINTTL                         = 0x42
+	IP_MIN_MEMBERSHIPS                = 0x1f
+	IP_MSFILTER                       = 0x4a
+	IP_MSS                            = 0x240
+	IP_MULTICAST_IF                   = 0x9
+	IP_MULTICAST_LOOP                 = 0xb
+	IP_MULTICAST_TTL                  = 0xa
+	IP_MULTICAST_VIF                  = 0xe
+	IP_OFFMASK                        = 0x1fff
+	IP_ONESBCAST                      = 0x17
+	IP_OPTIONS                        = 0x1
+	IP_PORTRANGE                      = 0x13
+	IP_PORTRANGE_DEFAULT              = 0x0
+	IP_PORTRANGE_HIGH                 = 0x1
+	IP_PORTRANGE_LOW                  = 0x2
+	IP_RECVDSTADDR                    = 0x7
+	IP_RECVIF                         = 0x14
+	IP_RECVOPTS                       = 0x5
+	IP_RECVRETOPTS                    = 0x6
+	IP_RECVTOS                        = 0x44
+	IP_RECVTTL                        = 0x41
+	IP_RETOPTS                        = 0x8
+	IP_RF                             = 0x8000
+	IP_RSVP_OFF                       = 0x10
+	IP_RSVP_ON                        = 0xf
+	IP_RSVP_VIF_OFF                   = 0x12
+	IP_RSVP_VIF_ON                    = 0x11
+	IP_SENDSRCADDR                    = 0x7
+	IP_TOS                            = 0x3
+	IP_TTL                            = 0x4
+	IP_UNBLOCK_SOURCE                 = 0x49
+	ISIG                              = 0x80
+	ISTRIP                            = 0x20
+	IXANY                             = 0x800
+	IXOFF                             = 0x400
+	IXON                              = 0x200
+	LOCK_EX                           = 0x2
+	LOCK_NB                           = 0x4
+	LOCK_SH                           = 0x1
+	LOCK_UN                           = 0x8
+	MADV_AUTOSYNC                     = 0x7
+	MADV_CORE                         = 0x9
+	MADV_DONTNEED                     = 0x4
+	MADV_FREE                         = 0x5
+	MADV_NOCORE                       = 0x8
+	MADV_NORMAL                       = 0x0
+	MADV_NOSYNC                       = 0x6
+	MADV_PROTECT                      = 0xa
+	MADV_RANDOM                       = 0x1
+	MADV_SEQUENTIAL                   = 0x2
+	MADV_WILLNEED                     = 0x3
+	MAP_32BIT                         = 0x80000
+	MAP_ALIGNED_SUPER                 = 0x1000000
+	MAP_ALIGNMENT_MASK                = -0x1000000
+	MAP_ALIGNMENT_SHIFT               = 0x18
+	MAP_ANON                          = 0x1000
+	MAP_ANONYMOUS                     = 0x1000
+	MAP_COPY                          = 0x2
+	MAP_FILE                          = 0x0
+	MAP_FIXED                         = 0x10
+	MAP_HASSEMAPHORE                  = 0x200
+	MAP_NOCORE                        = 0x20000
+	MAP_NORESERVE                     = 0x40
+	MAP_NOSYNC                        = 0x800
+	MAP_PREFAULT_READ                 = 0x40000
+	MAP_PRIVATE                       = 0x2
+	MAP_RENAME                        = 0x20
+	MAP_RESERVED0080                  = 0x80
+	MAP_RESERVED0100                  = 0x100
+	MAP_SHARED                        = 0x1
+	MAP_STACK                         = 0x400
+	MCL_CURRENT                       = 0x1
+	MCL_FUTURE                        = 0x2
+	MSG_CMSG_CLOEXEC                  = 0x40000
+	MSG_COMPAT                        = 0x8000
+	MSG_CTRUNC                        = 0x20
+	MSG_DONTROUTE                     = 0x4
+	MSG_DONTWAIT                      = 0x80
+	MSG_EOF                           = 0x100
+	MSG_EOR                           = 0x8
+	MSG_NBIO                          = 0x4000
+	MSG_NOSIGNAL                      = 0x20000
+	MSG_NOTIFICATION                  = 0x2000
+	MSG_OOB                           = 0x1
+	MSG_PEEK                          = 0x2
+	MSG_TRUNC                         = 0x10
+	MSG_WAITALL                       = 0x40
+	MS_ASYNC                          = 0x1
+	MS_INVALIDATE                     = 0x2
+	MS_SYNC                           = 0x0
+	NAME_MAX                          = 0xff
+	NET_RT_DUMP                       = 0x1
+	NET_RT_FLAGS                      = 0x2
+	NET_RT_IFLIST                     = 0x3
+	NET_RT_IFLISTL                    = 0x5
+	NET_RT_IFMALIST                   = 0x4
+	NET_RT_MAXID                      = 0x6
+	NOFLSH                            = 0x80000000
+	NOTE_ATTRIB                       = 0x8
+	NOTE_CHILD                        = 0x4
+	NOTE_DELETE                       = 0x1
+	NOTE_EXEC                         = 0x20000000
+	NOTE_EXIT                         = 0x80000000
+	NOTE_EXTEND                       = 0x4
+	NOTE_FFAND                        = 0x40000000
+	NOTE_FFCOPY                       = 0xc0000000
+	NOTE_FFCTRLMASK                   = 0xc0000000
+	NOTE_FFLAGSMASK                   = 0xffffff
+	NOTE_FFNOP                        = 0x0
+	NOTE_FFOR                         = 0x80000000
+	NOTE_FORK                         = 0x40000000
+	NOTE_LINK                         = 0x10
+	NOTE_LOWAT                        = 0x1
+	NOTE_PCTRLMASK                    = 0xf0000000
+	NOTE_PDATAMASK                    = 0xfffff
+	NOTE_RENAME                       = 0x20
+	NOTE_REVOKE                       = 0x40
+	NOTE_TRACK                        = 0x1
+	NOTE_TRACKERR                     = 0x2
+	NOTE_TRIGGER                      = 0x1000000
+	NOTE_WRITE                        = 0x2
+	OCRNL                             = 0x10
+	ONLCR                             = 0x2
+	ONLRET                            = 0x40
+	ONOCR                             = 0x20
+	ONOEOT                            = 0x8
+	OPOST                             = 0x1
+	O_ACCMODE                         = 0x3
+	O_APPEND                          = 0x8
+	O_ASYNC                           = 0x40
+	O_CLOEXEC                         = 0x100000
+	O_CREAT                           = 0x200
+	O_DIRECT                          = 0x10000
+	O_DIRECTORY                       = 0x20000
+	O_EXCL                            = 0x800
+	O_EXEC                            = 0x40000
+	O_EXLOCK                          = 0x20
+	O_FSYNC                           = 0x80
+	O_NDELAY                          = 0x4
+	O_NOCTTY                          = 0x8000
+	O_NOFOLLOW                        = 0x100
+	O_NONBLOCK                        = 0x4
+	O_RDONLY                          = 0x0
+	O_RDWR                            = 0x2
+	O_SHLOCK                          = 0x10
+	O_SYNC                            = 0x80
+	O_TRUNC                           = 0x400
+	O_TTY_INIT                        = 0x80000
+	O_WRONLY                          = 0x1
+	PARENB                            = 0x1000
+	PARMRK                            = 0x8
+	PARODD                            = 0x2000
+	PENDIN                            = 0x20000000
+	PRIO_PGRP                         = 0x1
+	PRIO_PROCESS                      = 0x0
+	PRIO_USER                         = 0x2
+	PROT_EXEC                         = 0x4
+	PROT_NONE                         = 0x0
+	PROT_READ                         = 0x1
+	PROT_WRITE                        = 0x2
+	RLIMIT_AS                         = 0xa
+	RLIMIT_CORE                       = 0x4
+	RLIMIT_CPU                        = 0x0
+	RLIMIT_DATA                       = 0x2
+	RLIMIT_FSIZE                      = 0x1
+	RLIMIT_NOFILE                     = 0x8
+	RLIMIT_STACK                      = 0x3
+	RLIM_INFINITY                     = 0x7fffffffffffffff
+	RTAX_AUTHOR                       = 0x6
+	RTAX_BRD                          = 0x7
+	RTAX_DST                          = 0x0
+	RTAX_GATEWAY                      = 0x1
+	RTAX_GENMASK                      = 0x3
+	RTAX_IFA                          = 0x5
+	RTAX_IFP                          = 0x4
+	RTAX_MAX                          = 0x8
+	RTAX_NETMASK                      = 0x2
+	RTA_AUTHOR                        = 0x40
+	RTA_BRD                           = 0x80
+	RTA_DST                           = 0x1
+	RTA_GATEWAY                       = 0x2
+	RTA_GENMASK                       = 0x8
+	RTA_IFA                           = 0x20
+	RTA_IFP                           = 0x10
+	RTA_NETMASK                       = 0x4
+	RTF_BLACKHOLE                     = 0x1000
+	RTF_BROADCAST                     = 0x400000
+	RTF_DONE                          = 0x40
+	RTF_DYNAMIC                       = 0x10
+	RTF_FMASK                         = 0x1004d808
+	RTF_GATEWAY                       = 0x2
+	RTF_GWFLAG_COMPAT                 = 0x80000000
+	RTF_HOST                          = 0x4
+	RTF_LLDATA                        = 0x400
+	RTF_LLINFO                        = 0x400
+	RTF_LOCAL                         = 0x200000
+	RTF_MODIFIED                      = 0x20
+	RTF_MULTICAST                     = 0x800000
+	RTF_PINNED                        = 0x100000
+	RTF_PRCLONING                     = 0x10000
+	RTF_PROTO1                        = 0x8000
+	RTF_PROTO2                        = 0x4000
+	RTF_PROTO3                        = 0x40000
+	RTF_REJECT                        = 0x8
+	RTF_RNH_LOCKED                    = 0x40000000
+	RTF_STATIC                        = 0x800
+	RTF_STICKY                        = 0x10000000
+	RTF_UP                            = 0x1
+	RTF_XRESOLVE                      = 0x200
+	RTM_ADD                           = 0x1
+	RTM_CHANGE                        = 0x3
+	RTM_DELADDR                       = 0xd
+	RTM_DELETE                        = 0x2
+	RTM_DELMADDR                      = 0x10
+	RTM_GET                           = 0x4
+	RTM_IEEE80211                     = 0x12
+	RTM_IFANNOUNCE                    = 0x11
+	RTM_IFINFO                        = 0xe
+	RTM_LOCK                          = 0x8
+	RTM_LOSING                        = 0x5
+	RTM_MISS                          = 0x7
+	RTM_NEWADDR                       = 0xc
+	RTM_NEWMADDR                      = 0xf
+	RTM_OLDADD                        = 0x9
+	RTM_OLDDEL                        = 0xa
+	RTM_REDIRECT                      = 0x6
+	RTM_RESOLVE                       = 0xb
+	RTM_RTTUNIT                       = 0xf4240
+	RTM_VERSION                       = 0x5
+	RTV_EXPIRE                        = 0x4
+	RTV_HOPCOUNT                      = 0x2
+	RTV_MTU                           = 0x1
+	RTV_RPIPE                         = 0x8
+	RTV_RTT                           = 0x40
+	RTV_RTTVAR                        = 0x80
+	RTV_SPIPE                         = 0x10
+	RTV_SSTHRESH                      = 0x20
+	RTV_WEIGHT                        = 0x100
+	RT_CACHING_CONTEXT                = 0x1
+	RT_DEFAULT_FIB                    = 0x0
+	RT_NORTREF                        = 0x2
+	RUSAGE_CHILDREN                   = -0x1
+	RUSAGE_SELF                       = 0x0
+	RUSAGE_THREAD                     = 0x1
+	SCM_BINTIME                       = 0x4
+	SCM_CREDS                         = 0x3
+	SCM_RIGHTS                        = 0x1
+	SCM_TIMESTAMP                     = 0x2
+	SHUT_RD                           = 0x0
+	SHUT_RDWR                         = 0x2
+	SHUT_WR                           = 0x1
+	SIOCADDMULTI                      = 0x80206931
+	SIOCADDRT                         = 0x8040720a
+	SIOCAIFADDR                       = 0x8040691a
+	SIOCAIFGROUP                      = 0x80286987
+	SIOCALIFADDR                      = 0x8118691b
+	SIOCATMARK                        = 0x40047307
+	SIOCDELMULTI                      = 0x80206932
+	SIOCDELRT                         = 0x8040720b
+	SIOCDIFADDR                       = 0x80206919
+	SIOCDIFGROUP                      = 0x80286989
+	SIOCDIFPHYADDR                    = 0x80206949
+	SIOCDLIFADDR                      = 0x8118691d
+	SIOCGDRVSPEC                      = 0xc028697b
+	SIOCGETSGCNT                      = 0xc0207210
+	SIOCGETVIFCNT                     = 0xc028720f
+	SIOCGHIWAT                        = 0x40047301
+	SIOCGIFADDR                       = 0xc0206921
+	SIOCGIFBRDADDR                    = 0xc0206923
+	SIOCGIFCAP                        = 0xc020691f
+	SIOCGIFCONF                       = 0xc0106924
+	SIOCGIFDESCR                      = 0xc020692a
+	SIOCGIFDSTADDR                    = 0xc0206922
+	SIOCGIFFIB                        = 0xc020695c
+	SIOCGIFFLAGS                      = 0xc0206911
+	SIOCGIFGENERIC                    = 0xc020693a
+	SIOCGIFGMEMB                      = 0xc028698a
+	SIOCGIFGROUP                      = 0xc0286988
+	SIOCGIFINDEX                      = 0xc0206920
+	SIOCGIFMAC                        = 0xc0206926
+	SIOCGIFMEDIA                      = 0xc0306938
+	SIOCGIFMETRIC                     = 0xc0206917
+	SIOCGIFMTU                        = 0xc0206933
+	SIOCGIFNETMASK                    = 0xc0206925
+	SIOCGIFPDSTADDR                   = 0xc0206948
+	SIOCGIFPHYS                       = 0xc0206935
+	SIOCGIFPSRCADDR                   = 0xc0206947
+	SIOCGIFSTATUS                     = 0xc331693b
+	SIOCGLIFADDR                      = 0xc118691c
+	SIOCGLIFPHYADDR                   = 0xc118694b
+	SIOCGLOWAT                        = 0x40047303
+	SIOCGPGRP                         = 0x40047309
+	SIOCGPRIVATE_0                    = 0xc0206950
+	SIOCGPRIVATE_1                    = 0xc0206951
+	SIOCIFCREATE                      = 0xc020697a
+	SIOCIFCREATE2                     = 0xc020697c
+	SIOCIFDESTROY                     = 0x80206979
+	SIOCIFGCLONERS                    = 0xc0106978
+	SIOCSDRVSPEC                      = 0x8028697b
+	SIOCSHIWAT                        = 0x80047300
+	SIOCSIFADDR                       = 0x8020690c
+	SIOCSIFBRDADDR                    = 0x80206913
+	SIOCSIFCAP                        = 0x8020691e
+	SIOCSIFDESCR                      = 0x80206929
+	SIOCSIFDSTADDR                    = 0x8020690e
+	SIOCSIFFIB                        = 0x8020695d
+	SIOCSIFFLAGS                      = 0x80206910
+	SIOCSIFGENERIC                    = 0x80206939
+	SIOCSIFLLADDR                     = 0x8020693c
+	SIOCSIFMAC                        = 0x80206927
+	SIOCSIFMEDIA                      = 0xc0206937
+	SIOCSIFMETRIC                     = 0x80206918
+	SIOCSIFMTU                        = 0x80206934
+	SIOCSIFNAME                       = 0x80206928
+	SIOCSIFNETMASK                    = 0x80206916
+	SIOCSIFPHYADDR                    = 0x80406946
+	SIOCSIFPHYS                       = 0x80206936
+	SIOCSIFRVNET                      = 0xc020695b
+	SIOCSIFVNET                       = 0xc020695a
+	SIOCSLIFPHYADDR                   = 0x8118694a
+	SIOCSLOWAT                        = 0x80047302
+	SIOCSPGRP                         = 0x80047308
+	SOCK_CLOEXEC                      = 0x10000000
+	SOCK_DGRAM                        = 0x2
+	SOCK_MAXADDRLEN                   = 0xff
+	SOCK_NONBLOCK                     = 0x20000000
+	SOCK_RAW                          = 0x3
+	SOCK_RDM                          = 0x4
+	SOCK_SEQPACKET                    = 0x5
+	SOCK_STREAM                       = 0x1
+	SOL_SOCKET                        = 0xffff
+	SOMAXCONN                         = 0x80
+	SO_ACCEPTCONN                     = 0x2
+	SO_ACCEPTFILTER                   = 0x1000
+	SO_BINTIME                        = 0x2000
+	SO_BROADCAST                      = 0x20
+	SO_DEBUG                          = 0x1
+	SO_DONTROUTE                      = 0x10
+	SO_ERROR                          = 0x1007
+	SO_KEEPALIVE                      = 0x8
+	SO_LABEL                          = 0x1009
+	SO_LINGER                         = 0x80
+	SO_LISTENINCQLEN                  = 0x1013
+	SO_LISTENQLEN                     = 0x1012
+	SO_LISTENQLIMIT                   = 0x1011
+	SO_NOSIGPIPE                      = 0x800
+	SO_NO_DDP                         = 0x8000
+	SO_NO_OFFLOAD                     = 0x4000
+	SO_OOBINLINE                      = 0x100
+	SO_PEERLABEL                      = 0x1010
+	SO_PROTOCOL                       = 0x1016
+	SO_PROTOTYPE                      = 0x1016
+	SO_RCVBUF                         = 0x1002
+	SO_RCVLOWAT                       = 0x1004
+	SO_RCVTIMEO                       = 0x1006
+	SO_REUSEADDR                      = 0x4
+	SO_REUSEPORT                      = 0x200
+	SO_SETFIB                         = 0x1014
+	SO_SNDBUF                         = 0x1001
+	SO_SNDLOWAT                       = 0x1003
+	SO_SNDTIMEO                       = 0x1005
+	SO_TIMESTAMP                      = 0x400
+	SO_TYPE                           = 0x1008
+	SO_USELOOPBACK                    = 0x40
+	SO_USER_COOKIE                    = 0x1015
+	SO_VENDOR                         = 0x80000000
+	TCIFLUSH                          = 0x1
+	TCIOFLUSH                         = 0x3
+	TCOFLUSH                          = 0x2
+	TCP_CA_NAME_MAX                   = 0x10
+	TCP_CONGESTION                    = 0x40
+	TCP_INFO                          = 0x20
+	TCP_KEEPCNT                       = 0x400
+	TCP_KEEPIDLE                      = 0x100
+	TCP_KEEPINIT                      = 0x80
+	TCP_KEEPINTVL                     = 0x200
+	TCP_MAXBURST                      = 0x4
+	TCP_MAXHLEN                       = 0x3c
+	TCP_MAXOLEN                       = 0x28
+	TCP_MAXSEG                        = 0x2
+	TCP_MAXWIN                        = 0xffff
+	TCP_MAX_SACK                      = 0x4
+	TCP_MAX_WINSHIFT                  = 0xe
+	TCP_MD5SIG                        = 0x10
+	TCP_MINMSS                        = 0xd8
+	TCP_MSS                           = 0x218
+	TCP_NODELAY                       = 0x1
+	TCP_NOOPT                         = 0x8
+	TCP_NOPUSH                        = 0x4
+	TCP_VENDOR                        = 0x80000000
+	TCSAFLUSH                         = 0x2
+	TIOCCBRK                          = 0x2000747a
+	TIOCCDTR                          = 0x20007478
+	TIOCCONS                          = 0x80047462
+	TIOCDRAIN                         = 0x2000745e
+	TIOCEXCL                          = 0x2000740d
+	TIOCEXT                           = 0x80047460
+	TIOCFLUSH                         = 0x80047410
+	TIOCGDRAINWAIT                    = 0x40047456
+	TIOCGETA                          = 0x402c7413
+	TIOCGETD                          = 0x4004741a
+	TIOCGPGRP                         = 0x40047477
+	TIOCGPTN                          = 0x4004740f
+	TIOCGSID                          = 0x40047463
+	TIOCGWINSZ                        = 0x40087468
+	TIOCMBIC                          = 0x8004746b
+	TIOCMBIS                          = 0x8004746c
+	TIOCMGDTRWAIT                     = 0x4004745a
+	TIOCMGET                          = 0x4004746a
+	TIOCMSDTRWAIT                     = 0x8004745b
+	TIOCMSET                          = 0x8004746d
+	TIOCM_CAR                         = 0x40
+	TIOCM_CD                          = 0x40
+	TIOCM_CTS                         = 0x20
+	TIOCM_DCD                         = 0x40
+	TIOCM_DSR                         = 0x100
+	TIOCM_DTR                         = 0x2
+	TIOCM_LE                          = 0x1
+	TIOCM_RI                          = 0x80
+	TIOCM_RNG                         = 0x80
+	TIOCM_RTS                         = 0x4
+	TIOCM_SR                          = 0x10
+	TIOCM_ST                          = 0x8
+	TIOCNOTTY                         = 0x20007471
+	TIOCNXCL                          = 0x2000740e
+	TIOCOUTQ                          = 0x40047473
+	TIOCPKT                           = 0x80047470
+	TIOCPKT_DATA                      = 0x0
+	TIOCPKT_DOSTOP                    = 0x20
+	TIOCPKT_FLUSHREAD                 = 0x1
+	TIOCPKT_FLUSHWRITE                = 0x2
+	TIOCPKT_IOCTL                     = 0x40
+	TIOCPKT_NOSTOP                    = 0x10
+	TIOCPKT_START                     = 0x8
+	TIOCPKT_STOP                      = 0x4
+	TIOCPTMASTER                      = 0x2000741c
+	TIOCSBRK                          = 0x2000747b
+	TIOCSCTTY                         = 0x20007461
+	TIOCSDRAINWAIT                    = 0x80047457
+	TIOCSDTR                          = 0x20007479
+	TIOCSETA                          = 0x802c7414
+	TIOCSETAF                         = 0x802c7416
+	TIOCSETAW                         = 0x802c7415
+	TIOCSETD                          = 0x8004741b
+	TIOCSIG                           = 0x2004745f
+	TIOCSPGRP                         = 0x80047476
+	TIOCSTART                         = 0x2000746e
+	TIOCSTAT                          = 0x20007465
+	TIOCSTI                           = 0x80017472
+	TIOCSTOP                          = 0x2000746f
+	TIOCSWINSZ                        = 0x80087467
+	TIOCTIMESTAMP                     = 0x40107459
+	TIOCUCNTL                         = 0x80047466
+	TOSTOP                            = 0x400000
+	VDISCARD                          = 0xf
+	VDSUSP                            = 0xb
+	VEOF                              = 0x0
+	VEOL                              = 0x1
+	VEOL2                             = 0x2
+	VERASE                            = 0x3
+	VERASE2                           = 0x7
+	VINTR                             = 0x8
+	VKILL                             = 0x5
+	VLNEXT                            = 0xe
+	VMIN                              = 0x10
+	VQUIT                             = 0x9
+	VREPRINT                          = 0x6
+	VSTART                            = 0xc
+	VSTATUS                           = 0x12
+	VSTOP                             = 0xd
+	VSUSP                             = 0xa
+	VTIME                             = 0x11
+	VWERASE                           = 0x4
+	WCONTINUED                        = 0x4
+	WCOREFLAG                         = 0x80
+	WEXITED                           = 0x10
+	WLINUXCLONE                       = 0x80000000
+	WNOHANG                           = 0x1
+	WNOWAIT                           = 0x8
+	WSTOPPED                          = 0x2
+	WTRAPPED                          = 0x20
+	WUNTRACED                         = 0x2
+)
+
+// Errors
+const (
+	E2BIG           = Errno(0x7)
+	EACCES          = Errno(0xd)
+	EADDRINUSE      = Errno(0x30)
+	EADDRNOTAVAIL   = Errno(0x31)
+	EAFNOSUPPORT    = Errno(0x2f)
+	EAGAIN          = Errno(0x23)
+	EALREADY        = Errno(0x25)
+	EAUTH           = Errno(0x50)
+	EBADF           = Errno(0x9)
+	EBADMSG         = Errno(0x59)
+	EBADRPC         = Errno(0x48)
+	EBUSY           = Errno(0x10)
+	ECANCELED       = Errno(0x55)
+	ECAPMODE        = Errno(0x5e)
+	ECHILD          = Errno(0xa)
+	ECONNABORTED    = Errno(0x35)
+	ECONNREFUSED    = Errno(0x3d)
+	ECONNRESET      = Errno(0x36)
+	EDEADLK         = Errno(0xb)
+	EDESTADDRREQ    = Errno(0x27)
+	EDOM            = Errno(0x21)
+	EDOOFUS         = Errno(0x58)
+	EDQUOT          = Errno(0x45)
+	EEXIST          = Errno(0x11)
+	EFAULT          = Errno(0xe)
+	EFBIG           = Errno(0x1b)
+	EFTYPE          = Errno(0x4f)
+	EHOSTDOWN       = Errno(0x40)
+	EHOSTUNREACH    = Errno(0x41)
+	EIDRM           = Errno(0x52)
+	EILSEQ          = Errno(0x56)
+	EINPROGRESS     = Errno(0x24)
+	EINTR           = Errno(0x4)
+	EINVAL          = Errno(0x16)
+	EIO             = Errno(0x5)
+	EISCONN         = Errno(0x38)
+	EISDIR          = Errno(0x15)
+	ELAST           = Errno(0x60)
+	ELOOP           = Errno(0x3e)
+	EMFILE          = Errno(0x18)
+	EMLINK          = Errno(0x1f)
+	EMSGSIZE        = Errno(0x28)
+	EMULTIHOP       = Errno(0x5a)
+	ENAMETOOLONG    = Errno(0x3f)
+	ENEEDAUTH       = Errno(0x51)
+	ENETDOWN        = Errno(0x32)
+	ENETRESET       = Errno(0x34)
+	ENETUNREACH     = Errno(0x33)
+	ENFILE          = Errno(0x17)
+	ENOATTR         = Errno(0x57)
+	ENOBUFS         = Errno(0x37)
+	ENODEV          = Errno(0x13)
+	ENOENT          = Errno(0x2)
+	ENOEXEC         = Errno(0x8)
+	ENOLCK          = Errno(0x4d)
+	ENOLINK         = Errno(0x5b)
+	ENOMEM          = Errno(0xc)
+	ENOMSG          = Errno(0x53)
+	ENOPROTOOPT     = Errno(0x2a)
+	ENOSPC          = Errno(0x1c)
+	ENOSYS          = Errno(0x4e)
+	ENOTBLK         = Errno(0xf)
+	ENOTCAPABLE     = Errno(0x5d)
+	ENOTCONN        = Errno(0x39)
+	ENOTDIR         = Errno(0x14)
+	ENOTEMPTY       = Errno(0x42)
+	ENOTRECOVERABLE = Errno(0x5f)
+	ENOTSOCK        = Errno(0x26)
+	ENOTSUP         = Errno(0x2d)
+	ENOTTY          = Errno(0x19)
+	ENXIO           = Errno(0x6)
+	EOPNOTSUPP      = Errno(0x2d)
+	EOVERFLOW       = Errno(0x54)
+	EOWNERDEAD      = Errno(0x60)
+	EPERM           = Errno(0x1)
+	EPFNOSUPPORT    = Errno(0x2e)
+	EPIPE           = Errno(0x20)
+	EPROCLIM        = Errno(0x43)
+	EPROCUNAVAIL    = Errno(0x4c)
+	EPROGMISMATCH   = Errno(0x4b)
+	EPROGUNAVAIL    = Errno(0x4a)
+	EPROTO          = Errno(0x5c)
+	EPROTONOSUPPORT = Errno(0x2b)
+	EPROTOTYPE      = Errno(0x29)
+	ERANGE          = Errno(0x22)
+	EREMOTE         = Errno(0x47)
+	EROFS           = Errno(0x1e)
+	ERPCMISMATCH    = Errno(0x49)
+	ESHUTDOWN       = Errno(0x3a)
+	ESOCKTNOSUPPORT = Errno(0x2c)
+	ESPIPE          = Errno(0x1d)
+	ESRCH           = Errno(0x3)
+	ESTALE          = Errno(0x46)
+	ETIMEDOUT       = Errno(0x3c)
+	ETOOMANYREFS    = Errno(0x3b)
+	ETXTBSY         = Errno(0x1a)
+	EUSERS          = Errno(0x44)
+	EWOULDBLOCK     = Errno(0x23)
+	EXDEV           = Errno(0x12)
+)
+
+// Signals
+const (
+	SIGABRT   = Signal(0x6)
+	SIGALRM   = Signal(0xe)
+	SIGBUS    = Signal(0xa)
+	SIGCHLD   = Signal(0x14)
+	SIGCONT   = Signal(0x13)
+	SIGEMT    = Signal(0x7)
+	SIGFPE    = Signal(0x8)
+	SIGHUP    = Signal(0x1)
+	SIGILL    = Signal(0x4)
+	SIGINFO   = Signal(0x1d)
+	SIGINT    = Signal(0x2)
+	SIGIO     = Signal(0x17)
+	SIGIOT    = Signal(0x6)
+	SIGKILL   = Signal(0x9)
+	SIGLIBRT  = Signal(0x21)
+	SIGLWP    = Signal(0x20)
+	SIGPIPE   = Signal(0xd)
+	SIGPROF   = Signal(0x1b)
+	SIGQUIT   = Signal(0x3)
+	SIGSEGV   = Signal(0xb)
+	SIGSTOP   = Signal(0x11)
+	SIGSYS    = Signal(0xc)
+	SIGTERM   = Signal(0xf)
+	SIGTHR    = Signal(0x20)
+	SIGTRAP   = Signal(0x5)
+	SIGTSTP   = Signal(0x12)
+	SIGTTIN   = Signal(0x15)
+	SIGTTOU   = Signal(0x16)
+	SIGURG    = Signal(0x10)
+	SIGUSR1   = Signal(0x1e)
+	SIGUSR2   = Signal(0x1f)
+	SIGVTALRM = Signal(0x1a)
+	SIGWINCH  = Signal(0x1c)
+	SIGXCPU   = Signal(0x18)
+	SIGXFSZ   = Signal(0x19)
+)
+
+// Error table
+var errors = [...]string{
+	1:  "operation not permitted",
+	2:  "no such file or directory",
+	3:  "no such process",
+	4:  "interrupted system call",
+	5:  "input/output error",
+	6:  "device not configured",
+	7:  "argument list too long",
+	8:  "exec format error",
+	9:  "bad file descriptor",
+	10: "no child processes",
+	11: "resource deadlock avoided",
+	12: "cannot allocate memory",
+	13: "permission denied",
+	14: "bad address",
+	15: "block device required",
+	16: "device busy",
+	17: "file exists",
+	18: "cross-device link",
+	19: "operation not supported by device",
+	20: "not a directory",
+	21: "is a directory",
+	22: "invalid argument",
+	23: "too many open files in system",
+	24: "too many open files",
+	25: "inappropriate ioctl for device",
+	26: "text file busy",
+	27: "file too large",
+	28: "no space left on device",
+	29: "illegal seek",
+	30: "read-only file system",
+	31: "too many links",
+	32: "broken pipe",
+	33: "numerical argument out of domain",
+	34: "result too large",
+	35: "resource temporarily unavailable",
+	36: "operation now in progress",
+	37: "operation already in progress",
+	38: "socket operation on non-socket",
+	39: "destination address required",
+	40: "message too long",
+	41: "protocol wrong type for socket",
+	42: "protocol not available",
+	43: "protocol not supported",
+	44: "socket type not supported",
+	45: "operation not supported",
+	46: "protocol family not supported",
+	47: "address family not supported by protocol family",
+	48: "address already in use",
+	49: "can't assign requested address",
+	50: "network is down",
+	51: "network is unreachable",
+	52: "network dropped connection on reset",
+	53: "software caused connection abort",
+	54: "connection reset by peer",
+	55: "no buffer space available",
+	56: "socket is already connected",
+	57: "socket is not connected",
+	58: "can't send after socket shutdown",
+	59: "too many references: can't splice",
+	60: "operation timed out",
+	61: "connection refused",
+	62: "too many levels of symbolic links",
+	63: "file name too long",
+	64: "host is down",
+	65: "no route to host",
+	66: "directory not empty",
+	67: "too many processes",
+	68: "too many users",
+	69: "disc quota exceeded",
+	70: "stale NFS file handle",
+	71: "too many levels of remote in path",
+	72: "RPC struct is bad",
+	73: "RPC version wrong",
+	74: "RPC prog. not avail",
+	75: "program version wrong",
+	76: "bad procedure for program",
+	77: "no locks available",
+	78: "function not implemented",
+	79: "inappropriate file type or format",
+	80: "authentication error",
+	81: "need authenticator",
+	82: "identifier removed",
+	83: "no message of desired type",
+	84: "value too large to be stored in data type",
+	85: "operation canceled",
+	86: "illegal byte sequence",
+	87: "attribute not found",
+	88: "programming error",
+	89: "bad message",
+	90: "multihop attempted",
+	91: "link has been severed",
+	92: "protocol error",
+	93: "capabilities insufficient",
+	94: "not permitted in capability mode",
+	95: "state not recoverable",
+	96: "previous owner died",
+}
+
+// Signal table
+var signals = [...]string{
+	1:  "hangup",
+	2:  "interrupt",
+	3:  "quit",
+	4:  "illegal instruction",
+	5:  "trace/BPT trap",
+	6:  "abort trap",
+	7:  "EMT trap",
+	8:  "floating point exception",
+	9:  "killed",
+	10: "bus error",
+	11: "segmentation fault",
+	12: "bad system call",
+	13: "broken pipe",
+	14: "alarm clock",
+	15: "terminated",
+	16: "urgent I/O condition",
+	17: "suspended (signal)",
+	18: "suspended",
+	19: "continued",
+	20: "child exited",
+	21: "stopped (tty input)",
+	22: "stopped (tty output)",
+	23: "I/O possible",
+	24: "cputime limit exceeded",
+	25: "filesize limit exceeded",
+	26: "virtual timer expired",
+	27: "profiling timer expired",
+	28: "window size changes",
+	29: "information request",
+	30: "user defined signal 1",
+	31: "user defined signal 2",
+	32: "unknown signal",
+	33: "unknown signal",
+}
diff --git a/src/syscall/zerrors_linux_386.go b/src/syscall/zerrors_linux_386.go
index 5e4c867..045a416 100644
--- a/src/syscall/zerrors_linux_386.go
+++ b/src/syscall/zerrors_linux_386.go
@@ -148,28 +148,6 @@
 	BPF_TXA                          = 0x80
 	BPF_W                            = 0x0
 	BPF_X                            = 0x8
-	CLONE_CHILD_CLEARTID             = 0x200000
-	CLONE_CHILD_SETTID               = 0x1000000
-	CLONE_DETACHED                   = 0x400000
-	CLONE_FILES                      = 0x400
-	CLONE_FS                         = 0x200
-	CLONE_IO                         = 0x80000000
-	CLONE_NEWIPC                     = 0x8000000
-	CLONE_NEWNET                     = 0x40000000
-	CLONE_NEWNS                      = 0x20000
-	CLONE_NEWPID                     = 0x20000000
-	CLONE_NEWUSER                    = 0x10000000
-	CLONE_NEWUTS                     = 0x4000000
-	CLONE_PARENT                     = 0x8000
-	CLONE_PARENT_SETTID              = 0x100000
-	CLONE_PTRACE                     = 0x2000
-	CLONE_SETTLS                     = 0x80000
-	CLONE_SIGHAND                    = 0x800
-	CLONE_SYSVSEM                    = 0x40000
-	CLONE_THREAD                     = 0x10000
-	CLONE_UNTRACED                   = 0x800000
-	CLONE_VFORK                      = 0x4000
-	CLONE_VM                         = 0x100
 	DT_BLK                           = 0x6
 	DT_CHR                           = 0x2
 	DT_DIR                           = 0x4
diff --git a/src/syscall/zerrors_linux_amd64.go b/src/syscall/zerrors_linux_amd64.go
index 3ff6e49..4eb4474 100644
--- a/src/syscall/zerrors_linux_amd64.go
+++ b/src/syscall/zerrors_linux_amd64.go
@@ -148,28 +148,6 @@
 	BPF_TXA                          = 0x80
 	BPF_W                            = 0x0
 	BPF_X                            = 0x8
-	CLONE_CHILD_CLEARTID             = 0x200000
-	CLONE_CHILD_SETTID               = 0x1000000
-	CLONE_DETACHED                   = 0x400000
-	CLONE_FILES                      = 0x400
-	CLONE_FS                         = 0x200
-	CLONE_IO                         = 0x80000000
-	CLONE_NEWIPC                     = 0x8000000
-	CLONE_NEWNET                     = 0x40000000
-	CLONE_NEWNS                      = 0x20000
-	CLONE_NEWPID                     = 0x20000000
-	CLONE_NEWUSER                    = 0x10000000
-	CLONE_NEWUTS                     = 0x4000000
-	CLONE_PARENT                     = 0x8000
-	CLONE_PARENT_SETTID              = 0x100000
-	CLONE_PTRACE                     = 0x2000
-	CLONE_SETTLS                     = 0x80000
-	CLONE_SIGHAND                    = 0x800
-	CLONE_SYSVSEM                    = 0x40000
-	CLONE_THREAD                     = 0x10000
-	CLONE_UNTRACED                   = 0x800000
-	CLONE_VFORK                      = 0x4000
-	CLONE_VM                         = 0x100
 	DT_BLK                           = 0x6
 	DT_CHR                           = 0x2
 	DT_DIR                           = 0x4
diff --git a/src/syscall/zerrors_linux_arm.go b/src/syscall/zerrors_linux_arm.go
index 35825cc..a5f925e 100644
--- a/src/syscall/zerrors_linux_arm.go
+++ b/src/syscall/zerrors_linux_arm.go
@@ -148,28 +148,6 @@
 	BPF_TXA                          = 0x80
 	BPF_W                            = 0x0
 	BPF_X                            = 0x8
-	CLONE_CHILD_CLEARTID             = 0x200000
-	CLONE_CHILD_SETTID               = 0x1000000
-	CLONE_DETACHED                   = 0x400000
-	CLONE_FILES                      = 0x400
-	CLONE_FS                         = 0x200
-	CLONE_IO                         = 0x80000000
-	CLONE_NEWIPC                     = 0x8000000
-	CLONE_NEWNET                     = 0x40000000
-	CLONE_NEWNS                      = 0x20000
-	CLONE_NEWPID                     = 0x20000000
-	CLONE_NEWUSER                    = 0x10000000
-	CLONE_NEWUTS                     = 0x4000000
-	CLONE_PARENT                     = 0x8000
-	CLONE_PARENT_SETTID              = 0x100000
-	CLONE_PTRACE                     = 0x2000
-	CLONE_SETTLS                     = 0x80000
-	CLONE_SIGHAND                    = 0x800
-	CLONE_SYSVSEM                    = 0x40000
-	CLONE_THREAD                     = 0x10000
-	CLONE_UNTRACED                   = 0x800000
-	CLONE_VFORK                      = 0x4000
-	CLONE_VM                         = 0x100
 	DT_BLK                           = 0x6
 	DT_CHR                           = 0x2
 	DT_DIR                           = 0x4
diff --git a/src/syscall/zerrors_linux_arm64.go b/src/syscall/zerrors_linux_arm64.go
index 444b881..ec8ac07 100644
--- a/src/syscall/zerrors_linux_arm64.go
+++ b/src/syscall/zerrors_linux_arm64.go
@@ -192,28 +192,6 @@
 	BRKINT                           = 0x2
 	CFLUSH                           = 0xf
 	CLOCAL                           = 0x800
-	CLONE_CHILD_CLEARTID             = 0x200000
-	CLONE_CHILD_SETTID               = 0x1000000
-	CLONE_DETACHED                   = 0x400000
-	CLONE_FILES                      = 0x400
-	CLONE_FS                         = 0x200
-	CLONE_IO                         = 0x80000000
-	CLONE_NEWIPC                     = 0x8000000
-	CLONE_NEWNET                     = 0x40000000
-	CLONE_NEWNS                      = 0x20000
-	CLONE_NEWPID                     = 0x20000000
-	CLONE_NEWUSER                    = 0x10000000
-	CLONE_NEWUTS                     = 0x4000000
-	CLONE_PARENT                     = 0x8000
-	CLONE_PARENT_SETTID              = 0x100000
-	CLONE_PTRACE                     = 0x2000
-	CLONE_SETTLS                     = 0x80000
-	CLONE_SIGHAND                    = 0x800
-	CLONE_SYSVSEM                    = 0x40000
-	CLONE_THREAD                     = 0x10000
-	CLONE_UNTRACED                   = 0x800000
-	CLONE_VFORK                      = 0x4000
-	CLONE_VM                         = 0x100
 	CREAD                            = 0x80
 	CS5                              = 0x0
 	CS6                              = 0x10
diff --git a/src/syscall/zerrors_linux_loong64.go b/src/syscall/zerrors_linux_loong64.go
index 17b109d..a28439c 100644
--- a/src/syscall/zerrors_linux_loong64.go
+++ b/src/syscall/zerrors_linux_loong64.go
@@ -206,33 +206,6 @@
 	CLONE_ARGS_SIZE_VER0              = 0x40
 	CLONE_ARGS_SIZE_VER1              = 0x50
 	CLONE_ARGS_SIZE_VER2              = 0x58
-	CLONE_CHILD_CLEARTID              = 0x200000
-	CLONE_CHILD_SETTID                = 0x1000000
-	CLONE_CLEAR_SIGHAND               = 0x100000000
-	CLONE_DETACHED                    = 0x400000
-	CLONE_FILES                       = 0x400
-	CLONE_FS                          = 0x200
-	CLONE_INTO_CGROUP                 = 0x200000000
-	CLONE_IO                          = 0x80000000
-	CLONE_NEWCGROUP                   = 0x2000000
-	CLONE_NEWIPC                      = 0x8000000
-	CLONE_NEWNET                      = 0x40000000
-	CLONE_NEWNS                       = 0x20000
-	CLONE_NEWPID                      = 0x20000000
-	CLONE_NEWTIME                     = 0x80
-	CLONE_NEWUSER                     = 0x10000000
-	CLONE_NEWUTS                      = 0x4000000
-	CLONE_PARENT                      = 0x8000
-	CLONE_PARENT_SETTID               = 0x100000
-	CLONE_PIDFD                       = 0x1000
-	CLONE_PTRACE                      = 0x2000
-	CLONE_SETTLS                      = 0x80000
-	CLONE_SIGHAND                     = 0x800
-	CLONE_SYSVSEM                     = 0x40000
-	CLONE_THREAD                      = 0x10000
-	CLONE_UNTRACED                    = 0x800000
-	CLONE_VFORK                       = 0x4000
-	CLONE_VM                          = 0x100
 	CREAD                             = 0x80
 	CS5                               = 0x0
 	CS6                               = 0x10
diff --git a/src/syscall/zerrors_linux_mips.go b/src/syscall/zerrors_linux_mips.go
index d3dae6d..3fe5c00 100644
--- a/src/syscall/zerrors_linux_mips.go
+++ b/src/syscall/zerrors_linux_mips.go
@@ -191,28 +191,6 @@
 	BRKINT                           = 0x2
 	CFLUSH                           = 0xf
 	CLOCAL                           = 0x800
-	CLONE_CHILD_CLEARTID             = 0x200000
-	CLONE_CHILD_SETTID               = 0x1000000
-	CLONE_DETACHED                   = 0x400000
-	CLONE_FILES                      = 0x400
-	CLONE_FS                         = 0x200
-	CLONE_IO                         = 0x80000000
-	CLONE_NEWIPC                     = 0x8000000
-	CLONE_NEWNET                     = 0x40000000
-	CLONE_NEWNS                      = 0x20000
-	CLONE_NEWPID                     = 0x20000000
-	CLONE_NEWUSER                    = 0x10000000
-	CLONE_NEWUTS                     = 0x4000000
-	CLONE_PARENT                     = 0x8000
-	CLONE_PARENT_SETTID              = 0x100000
-	CLONE_PTRACE                     = 0x2000
-	CLONE_SETTLS                     = 0x80000
-	CLONE_SIGHAND                    = 0x800
-	CLONE_SYSVSEM                    = 0x40000
-	CLONE_THREAD                     = 0x10000
-	CLONE_UNTRACED                   = 0x800000
-	CLONE_VFORK                      = 0x4000
-	CLONE_VM                         = 0x100
 	CREAD                            = 0x80
 	CS5                              = 0x0
 	CS6                              = 0x10
diff --git a/src/syscall/zerrors_linux_mips64.go b/src/syscall/zerrors_linux_mips64.go
index 84c9e8f..74a1843 100644
--- a/src/syscall/zerrors_linux_mips64.go
+++ b/src/syscall/zerrors_linux_mips64.go
@@ -189,28 +189,6 @@
 	BRKINT                           = 0x2
 	CFLUSH                           = 0xf
 	CLOCAL                           = 0x800
-	CLONE_CHILD_CLEARTID             = 0x200000
-	CLONE_CHILD_SETTID               = 0x1000000
-	CLONE_DETACHED                   = 0x400000
-	CLONE_FILES                      = 0x400
-	CLONE_FS                         = 0x200
-	CLONE_IO                         = 0x80000000
-	CLONE_NEWIPC                     = 0x8000000
-	CLONE_NEWNET                     = 0x40000000
-	CLONE_NEWNS                      = 0x20000
-	CLONE_NEWPID                     = 0x20000000
-	CLONE_NEWUSER                    = 0x10000000
-	CLONE_NEWUTS                     = 0x4000000
-	CLONE_PARENT                     = 0x8000
-	CLONE_PARENT_SETTID              = 0x100000
-	CLONE_PTRACE                     = 0x2000
-	CLONE_SETTLS                     = 0x80000
-	CLONE_SIGHAND                    = 0x800
-	CLONE_SYSVSEM                    = 0x40000
-	CLONE_THREAD                     = 0x10000
-	CLONE_UNTRACED                   = 0x800000
-	CLONE_VFORK                      = 0x4000
-	CLONE_VM                         = 0x100
 	CREAD                            = 0x80
 	CS5                              = 0x0
 	CS6                              = 0x10
diff --git a/src/syscall/zerrors_linux_mips64le.go b/src/syscall/zerrors_linux_mips64le.go
index 84c9e8f..74a1843 100644
--- a/src/syscall/zerrors_linux_mips64le.go
+++ b/src/syscall/zerrors_linux_mips64le.go
@@ -189,28 +189,6 @@
 	BRKINT                           = 0x2
 	CFLUSH                           = 0xf
 	CLOCAL                           = 0x800
-	CLONE_CHILD_CLEARTID             = 0x200000
-	CLONE_CHILD_SETTID               = 0x1000000
-	CLONE_DETACHED                   = 0x400000
-	CLONE_FILES                      = 0x400
-	CLONE_FS                         = 0x200
-	CLONE_IO                         = 0x80000000
-	CLONE_NEWIPC                     = 0x8000000
-	CLONE_NEWNET                     = 0x40000000
-	CLONE_NEWNS                      = 0x20000
-	CLONE_NEWPID                     = 0x20000000
-	CLONE_NEWUSER                    = 0x10000000
-	CLONE_NEWUTS                     = 0x4000000
-	CLONE_PARENT                     = 0x8000
-	CLONE_PARENT_SETTID              = 0x100000
-	CLONE_PTRACE                     = 0x2000
-	CLONE_SETTLS                     = 0x80000
-	CLONE_SIGHAND                    = 0x800
-	CLONE_SYSVSEM                    = 0x40000
-	CLONE_THREAD                     = 0x10000
-	CLONE_UNTRACED                   = 0x800000
-	CLONE_VFORK                      = 0x4000
-	CLONE_VM                         = 0x100
 	CREAD                            = 0x80
 	CS5                              = 0x0
 	CS6                              = 0x10
diff --git a/src/syscall/zerrors_linux_mipsle.go b/src/syscall/zerrors_linux_mipsle.go
index d3dae6d..3fe5c00 100644
--- a/src/syscall/zerrors_linux_mipsle.go
+++ b/src/syscall/zerrors_linux_mipsle.go
@@ -191,28 +191,6 @@
 	BRKINT                           = 0x2
 	CFLUSH                           = 0xf
 	CLOCAL                           = 0x800
-	CLONE_CHILD_CLEARTID             = 0x200000
-	CLONE_CHILD_SETTID               = 0x1000000
-	CLONE_DETACHED                   = 0x400000
-	CLONE_FILES                      = 0x400
-	CLONE_FS                         = 0x200
-	CLONE_IO                         = 0x80000000
-	CLONE_NEWIPC                     = 0x8000000
-	CLONE_NEWNET                     = 0x40000000
-	CLONE_NEWNS                      = 0x20000
-	CLONE_NEWPID                     = 0x20000000
-	CLONE_NEWUSER                    = 0x10000000
-	CLONE_NEWUTS                     = 0x4000000
-	CLONE_PARENT                     = 0x8000
-	CLONE_PARENT_SETTID              = 0x100000
-	CLONE_PTRACE                     = 0x2000
-	CLONE_SETTLS                     = 0x80000
-	CLONE_SIGHAND                    = 0x800
-	CLONE_SYSVSEM                    = 0x40000
-	CLONE_THREAD                     = 0x10000
-	CLONE_UNTRACED                   = 0x800000
-	CLONE_VFORK                      = 0x4000
-	CLONE_VM                         = 0x100
 	CREAD                            = 0x80
 	CS5                              = 0x0
 	CS6                              = 0x10
diff --git a/src/syscall/zerrors_linux_ppc64.go b/src/syscall/zerrors_linux_ppc64.go
index dd439ac..b63daea 100644
--- a/src/syscall/zerrors_linux_ppc64.go
+++ b/src/syscall/zerrors_linux_ppc64.go
@@ -191,28 +191,6 @@
 	BRKINT                           = 0x2
 	CFLUSH                           = 0xf
 	CLOCAL                           = 0x8000
-	CLONE_CHILD_CLEARTID             = 0x200000
-	CLONE_CHILD_SETTID               = 0x1000000
-	CLONE_DETACHED                   = 0x400000
-	CLONE_FILES                      = 0x400
-	CLONE_FS                         = 0x200
-	CLONE_IO                         = 0x80000000
-	CLONE_NEWIPC                     = 0x8000000
-	CLONE_NEWNET                     = 0x40000000
-	CLONE_NEWNS                      = 0x20000
-	CLONE_NEWPID                     = 0x20000000
-	CLONE_NEWUSER                    = 0x10000000
-	CLONE_NEWUTS                     = 0x4000000
-	CLONE_PARENT                     = 0x8000
-	CLONE_PARENT_SETTID              = 0x100000
-	CLONE_PTRACE                     = 0x2000
-	CLONE_SETTLS                     = 0x80000
-	CLONE_SIGHAND                    = 0x800
-	CLONE_SYSVSEM                    = 0x40000
-	CLONE_THREAD                     = 0x10000
-	CLONE_UNTRACED                   = 0x800000
-	CLONE_VFORK                      = 0x4000
-	CLONE_VM                         = 0x100
 	CREAD                            = 0x800
 	CS5                              = 0x0
 	CS6                              = 0x100
diff --git a/src/syscall/zerrors_linux_ppc64le.go b/src/syscall/zerrors_linux_ppc64le.go
index b71cb0b..01f8adb 100644
--- a/src/syscall/zerrors_linux_ppc64le.go
+++ b/src/syscall/zerrors_linux_ppc64le.go
@@ -192,28 +192,6 @@
 	BRKINT                           = 0x2
 	CFLUSH                           = 0xf
 	CLOCAL                           = 0x8000
-	CLONE_CHILD_CLEARTID             = 0x200000
-	CLONE_CHILD_SETTID               = 0x1000000
-	CLONE_DETACHED                   = 0x400000
-	CLONE_FILES                      = 0x400
-	CLONE_FS                         = 0x200
-	CLONE_IO                         = 0x80000000
-	CLONE_NEWIPC                     = 0x8000000
-	CLONE_NEWNET                     = 0x40000000
-	CLONE_NEWNS                      = 0x20000
-	CLONE_NEWPID                     = 0x20000000
-	CLONE_NEWUSER                    = 0x10000000
-	CLONE_NEWUTS                     = 0x4000000
-	CLONE_PARENT                     = 0x8000
-	CLONE_PARENT_SETTID              = 0x100000
-	CLONE_PTRACE                     = 0x2000
-	CLONE_SETTLS                     = 0x80000
-	CLONE_SIGHAND                    = 0x800
-	CLONE_SYSVSEM                    = 0x40000
-	CLONE_THREAD                     = 0x10000
-	CLONE_UNTRACED                   = 0x800000
-	CLONE_VFORK                      = 0x4000
-	CLONE_VM                         = 0x100
 	CREAD                            = 0x800
 	CS5                              = 0x0
 	CS6                              = 0x100
diff --git a/src/syscall/zerrors_linux_riscv64.go b/src/syscall/zerrors_linux_riscv64.go
index 582537d..f4b1d9a 100644
--- a/src/syscall/zerrors_linux_riscv64.go
+++ b/src/syscall/zerrors_linux_riscv64.go
@@ -196,28 +196,6 @@
 	BRKINT                           = 0x2
 	CFLUSH                           = 0xf
 	CLOCAL                           = 0x800
-	CLONE_CHILD_CLEARTID             = 0x200000
-	CLONE_CHILD_SETTID               = 0x1000000
-	CLONE_DETACHED                   = 0x400000
-	CLONE_FILES                      = 0x400
-	CLONE_FS                         = 0x200
-	CLONE_IO                         = 0x80000000
-	CLONE_NEWIPC                     = 0x8000000
-	CLONE_NEWNET                     = 0x40000000
-	CLONE_NEWNS                      = 0x20000
-	CLONE_NEWPID                     = 0x20000000
-	CLONE_NEWUSER                    = 0x10000000
-	CLONE_NEWUTS                     = 0x4000000
-	CLONE_PARENT                     = 0x8000
-	CLONE_PARENT_SETTID              = 0x100000
-	CLONE_PTRACE                     = 0x2000
-	CLONE_SETTLS                     = 0x80000
-	CLONE_SIGHAND                    = 0x800
-	CLONE_SYSVSEM                    = 0x40000
-	CLONE_THREAD                     = 0x10000
-	CLONE_UNTRACED                   = 0x800000
-	CLONE_VFORK                      = 0x4000
-	CLONE_VM                         = 0x100
 	CREAD                            = 0x80
 	CS5                              = 0x0
 	CS6                              = 0x10
diff --git a/src/syscall/zerrors_linux_s390x.go b/src/syscall/zerrors_linux_s390x.go
index cd1aa16..8b99a60 100644
--- a/src/syscall/zerrors_linux_s390x.go
+++ b/src/syscall/zerrors_linux_s390x.go
@@ -193,29 +193,6 @@
 	BRKINT                           = 0x2
 	CFLUSH                           = 0xf
 	CLOCAL                           = 0x800
-	CLONE_CHILD_CLEARTID             = 0x200000
-	CLONE_CHILD_SETTID               = 0x1000000
-	CLONE_DETACHED                   = 0x400000
-	CLONE_FILES                      = 0x400
-	CLONE_FS                         = 0x200
-	CLONE_IO                         = 0x80000000
-	CLONE_NEWCGROUP                  = 0x2000000
-	CLONE_NEWIPC                     = 0x8000000
-	CLONE_NEWNET                     = 0x40000000
-	CLONE_NEWNS                      = 0x20000
-	CLONE_NEWPID                     = 0x20000000
-	CLONE_NEWUSER                    = 0x10000000
-	CLONE_NEWUTS                     = 0x4000000
-	CLONE_PARENT                     = 0x8000
-	CLONE_PARENT_SETTID              = 0x100000
-	CLONE_PTRACE                     = 0x2000
-	CLONE_SETTLS                     = 0x80000
-	CLONE_SIGHAND                    = 0x800
-	CLONE_SYSVSEM                    = 0x40000
-	CLONE_THREAD                     = 0x10000
-	CLONE_UNTRACED                   = 0x800000
-	CLONE_VFORK                      = 0x4000
-	CLONE_VM                         = 0x100
 	CREAD                            = 0x80
 	CS5                              = 0x0
 	CS6                              = 0x10
diff --git a/src/syscall/zerrors_solaris_amd64.go b/src/syscall/zerrors_solaris_amd64.go
index fb25dac..4a1d9c3 100644
--- a/src/syscall/zerrors_solaris_amd64.go
+++ b/src/syscall/zerrors_solaris_amd64.go
@@ -276,7 +276,6 @@
 	F_CHKFL                       = 0x8
 	F_COMPAT                      = 0x8
 	F_DUP2FD                      = 0x9
-	F_DUP2FD_CLOEXEC              = 0x24
 	F_DUPFD                       = 0x0
 	F_DUPFD_CLOEXEC               = 0x25
 	F_FREESP                      = 0xb
@@ -594,6 +593,7 @@
 	MAP_ALIGN                     = 0x200
 	MAP_ANON                      = 0x100
 	MAP_ANONYMOUS                 = 0x100
+	MAP_FILE                      = 0x0
 	MAP_FIXED                     = 0x10
 	MAP_INITDATA                  = 0x800
 	MAP_NORESERVE                 = 0x40
diff --git a/src/syscall/zsyscall_aix_ppc64.go b/src/syscall/zsyscall_aix_ppc64.go
index 39838a4..c9e2ede 100644
--- a/src/syscall/zsyscall_aix_ppc64.go
+++ b/src/syscall/zsyscall_aix_ppc64.go
@@ -96,6 +96,7 @@
 //go:cgo_import_dynamic libc_Unlink unlink "libc.a/shr_64.o"
 //go:cgo_import_dynamic libc_Uname uname "libc.a/shr_64.o"
 //go:cgo_import_dynamic libc_write write "libc.a/shr_64.o"
+//go:cgo_import_dynamic libc_writev writev "libc.a/shr_64.o"
 //go:cgo_import_dynamic libc_gettimeofday gettimeofday "libc.a/shr_64.o"
 //go:cgo_import_dynamic libc_mmap mmap "libc.a/shr_64.o"
 //go:cgo_import_dynamic libc_munmap munmap "libc.a/shr_64.o"
@@ -189,6 +190,7 @@
 //go:linkname libc_Unlink libc_Unlink
 //go:linkname libc_Uname libc_Uname
 //go:linkname libc_write libc_write
+//go:linkname libc_writev libc_writev
 //go:linkname libc_gettimeofday libc_gettimeofday
 //go:linkname libc_mmap libc_mmap
 //go:linkname libc_munmap libc_munmap
@@ -285,6 +287,7 @@
 	libc_Unlink,
 	libc_Uname,
 	libc_write,
+	libc_writev,
 	libc_gettimeofday,
 	libc_mmap,
 	libc_munmap libcFunc
@@ -1381,6 +1384,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func writev(fd int, iovecs []Iovec) (n uintptr, err error) {
+	var _p0 *Iovec
+	if len(iovecs) > 0 {
+		_p0 = &iovecs[0]
+	}
+	r0, _, e1 := syscall6(uintptr(unsafe.Pointer(&libc_writev)), 3, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(iovecs)), 0, 0, 0)
+	n = uintptr(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func gettimeofday(tv *Timeval, tzp *Timezone) (err error) {
 	_, _, e1 := syscall6(uintptr(unsafe.Pointer(&libc_gettimeofday)), 2, uintptr(unsafe.Pointer(tv)), uintptr(unsafe.Pointer(tzp)), 0, 0, 0, 0)
 	if e1 != 0 {
diff --git a/src/syscall/zsyscall_darwin_amd64.go b/src/syscall/zsyscall_darwin_amd64.go
index ee78a57..6b3fff3 100644
--- a/src/syscall/zsyscall_darwin_amd64.go
+++ b/src/syscall/zsyscall_darwin_amd64.go
@@ -1063,6 +1063,26 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func msync(b []byte, flags int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_msync_trampoline), uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func libc_msync_trampoline()
+
+//go:cgo_import_dynamic libc_msync msync "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Munlock(b []byte) (err error) {
 	var _p0 unsafe.Pointer
 	if len(b) > 0 {
diff --git a/src/syscall/zsyscall_darwin_amd64.s b/src/syscall/zsyscall_darwin_amd64.s
index 563083d..90e51fb 100644
--- a/src/syscall/zsyscall_darwin_amd64.s
+++ b/src/syscall/zsyscall_darwin_amd64.s
@@ -143,6 +143,8 @@
 	JMP	libc_mlockall(SB)
 TEXT ·libc_mprotect_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_mprotect(SB)
+TEXT ·libc_msync_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_msync(SB)
 TEXT ·libc_munlock_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_munlock(SB)
 TEXT ·libc_munlockall_trampoline(SB),NOSPLIT,$0-0
diff --git a/src/syscall/zsyscall_darwin_arm64.go b/src/syscall/zsyscall_darwin_arm64.go
index ac1eccf..6160144 100644
--- a/src/syscall/zsyscall_darwin_arm64.go
+++ b/src/syscall/zsyscall_darwin_arm64.go
@@ -1063,6 +1063,26 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func msync(b []byte, flags int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := syscall(abi.FuncPCABI0(libc_msync_trampoline), uintptr(_p0), uintptr(len(b)), uintptr(flags))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func libc_msync_trampoline()
+
+//go:cgo_import_dynamic libc_msync msync "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func Munlock(b []byte) (err error) {
 	var _p0 unsafe.Pointer
 	if len(b) > 0 {
diff --git a/src/syscall/zsyscall_darwin_arm64.s b/src/syscall/zsyscall_darwin_arm64.s
index 0567a42..f007479 100644
--- a/src/syscall/zsyscall_darwin_arm64.s
+++ b/src/syscall/zsyscall_darwin_arm64.s
@@ -143,6 +143,8 @@
 	JMP	libc_mlockall(SB)
 TEXT ·libc_mprotect_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_mprotect(SB)
+TEXT ·libc_msync_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_msync(SB)
 TEXT ·libc_munlock_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_munlock(SB)
 TEXT ·libc_munlockall_trampoline(SB),NOSPLIT,$0-0
diff --git a/src/syscall/zsyscall_freebsd_386.go b/src/syscall/zsyscall_freebsd_386.go
index 04bad4a..3839dd7 100644
--- a/src/syscall/zsyscall_freebsd_386.go
+++ b/src/syscall/zsyscall_freebsd_386.go
@@ -463,7 +463,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func fstat(fd int, stat *stat_freebsd11_t) (err error) {
+func Fstat(fd int, stat *Stat_t) (err error) {
 	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -473,17 +473,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func fstat_freebsd12(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := Syscall(_SYS_FSTAT_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fstatat(fd int, path string, stat *stat_freebsd11_t, flags int) (err error) {
+func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
@@ -498,22 +488,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func fstatat_freebsd12(fd int, path string, stat *Stat_t, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(_SYS_FSTATAT_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fstatfs(fd int, stat *statfs_freebsd11_t) (err error) {
+func Fstatfs(fd int, stat *Statfs_t) (err error) {
 	_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -523,16 +498,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func fstatfs_freebsd12(fd int, stat *Statfs_t) (err error) {
-	_, _, e1 := Syscall(_SYS_FSTATFS_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Fsync(fd int) (err error) {
 	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
 	if e1 != 0 {
@@ -553,7 +518,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
+func getdirentries(fd int, buf []byte, basep *uint64) (n int, err error) {
 	var _p0 unsafe.Pointer
 	if len(buf) > 0 {
 		_p0 = unsafe.Pointer(&buf[0])
@@ -570,23 +535,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func getdirentries_freebsd12(fd int, buf []byte, basep *uint64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(_SYS_GETDIRENTRIES_FREEBSD12, uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Getdtablesize() (size int) {
 	r0, _, _ := Syscall(SYS_GETDTABLESIZE, 0, 0, 0)
 	size = int(r0)
@@ -788,21 +736,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func lstat(path string, stat *stat_freebsd11_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Mkdir(path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -833,28 +766,13 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func mknod(path string, mode uint32, dev int) (err error) {
+func mknodat(fd int, path string, mode uint32, dev uint64) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func mknodat_freebsd12(fd int, path string, mode uint32, dev uint64) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(_SYS_MKNODAT_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
+	_, _, e1 := Syscall6(SYS_MKNODAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1175,22 +1093,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func stat(path string, stat *stat_freebsd11_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func statfs(path string, stat *statfs_freebsd11_t) (err error) {
+func Statfs(path string, stat *Statfs_t) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
@@ -1205,21 +1108,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func statfs_freebsd12(path string, stat *Statfs_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(_SYS_STATFS_FREEBSD12, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Symlink(path string, link string) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
diff --git a/src/syscall/zsyscall_freebsd_amd64.go b/src/syscall/zsyscall_freebsd_amd64.go
index eeb9c0c..1092302 100644
--- a/src/syscall/zsyscall_freebsd_amd64.go
+++ b/src/syscall/zsyscall_freebsd_amd64.go
@@ -463,7 +463,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func fstat(fd int, stat *stat_freebsd11_t) (err error) {
+func Fstat(fd int, stat *Stat_t) (err error) {
 	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -473,17 +473,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func fstat_freebsd12(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := Syscall(_SYS_FSTAT_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fstatat(fd int, path string, stat *stat_freebsd11_t, flags int) (err error) {
+func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
@@ -498,22 +488,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func fstatat_freebsd12(fd int, path string, stat *Stat_t, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(_SYS_FSTATAT_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fstatfs(fd int, stat *statfs_freebsd11_t) (err error) {
+func Fstatfs(fd int, stat *Statfs_t) (err error) {
 	_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -523,16 +498,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func fstatfs_freebsd12(fd int, stat *Statfs_t) (err error) {
-	_, _, e1 := Syscall(_SYS_FSTATFS_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Fsync(fd int) (err error) {
 	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
 	if e1 != 0 {
@@ -553,7 +518,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
+func getdirentries(fd int, buf []byte, basep *uint64) (n int, err error) {
 	var _p0 unsafe.Pointer
 	if len(buf) > 0 {
 		_p0 = unsafe.Pointer(&buf[0])
@@ -570,23 +535,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func getdirentries_freebsd12(fd int, buf []byte, basep *uint64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(_SYS_GETDIRENTRIES_FREEBSD12, uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Getdtablesize() (size int) {
 	r0, _, _ := Syscall(SYS_GETDTABLESIZE, 0, 0, 0)
 	size = int(r0)
@@ -788,21 +736,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func lstat(path string, stat *stat_freebsd11_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Mkdir(path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -833,28 +766,13 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func mknod(path string, mode uint32, dev int) (err error) {
+func mknodat(fd int, path string, mode uint32, dev uint64) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func mknodat_freebsd12(fd int, path string, mode uint32, dev uint64) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(_SYS_MKNODAT_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
+	_, _, e1 := Syscall6(SYS_MKNODAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1175,22 +1093,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func stat(path string, stat *stat_freebsd11_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func statfs(path string, stat *statfs_freebsd11_t) (err error) {
+func Statfs(path string, stat *Statfs_t) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
@@ -1205,21 +1108,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func statfs_freebsd12(path string, stat *Statfs_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(_SYS_STATFS_FREEBSD12, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Symlink(path string, link string) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
diff --git a/src/syscall/zsyscall_freebsd_arm.go b/src/syscall/zsyscall_freebsd_arm.go
index 8ea4282..53e48d5 100644
--- a/src/syscall/zsyscall_freebsd_arm.go
+++ b/src/syscall/zsyscall_freebsd_arm.go
@@ -463,7 +463,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func fstat(fd int, stat *stat_freebsd11_t) (err error) {
+func Fstat(fd int, stat *Stat_t) (err error) {
 	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -473,17 +473,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func fstat_freebsd12(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := Syscall(_SYS_FSTAT_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fstatat(fd int, path string, stat *stat_freebsd11_t, flags int) (err error) {
+func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
@@ -498,22 +488,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func fstatat_freebsd12(fd int, path string, stat *Stat_t, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(_SYS_FSTATAT_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fstatfs(fd int, stat *statfs_freebsd11_t) (err error) {
+func Fstatfs(fd int, stat *Statfs_t) (err error) {
 	_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -523,16 +498,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func fstatfs_freebsd12(fd int, stat *Statfs_t) (err error) {
-	_, _, e1 := Syscall(_SYS_FSTATFS_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Fsync(fd int) (err error) {
 	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
 	if e1 != 0 {
@@ -553,7 +518,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
+func getdirentries(fd int, buf []byte, basep *uint64) (n int, err error) {
 	var _p0 unsafe.Pointer
 	if len(buf) > 0 {
 		_p0 = unsafe.Pointer(&buf[0])
@@ -570,23 +535,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func getdirentries_freebsd12(fd int, buf []byte, basep *uint64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(_SYS_GETDIRENTRIES_FREEBSD12, uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Getdtablesize() (size int) {
 	r0, _, _ := Syscall(SYS_GETDTABLESIZE, 0, 0, 0)
 	size = int(r0)
@@ -788,21 +736,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func lstat(path string, stat *stat_freebsd11_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Mkdir(path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -833,28 +766,13 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func mknod(path string, mode uint32, dev int) (err error) {
+func mknodat(fd int, path string, mode uint32, dev uint64) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func mknodat_freebsd12(fd int, path string, mode uint32, dev uint64) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(_SYS_MKNODAT_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
+	_, _, e1 := Syscall6(SYS_MKNODAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1175,22 +1093,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func stat(path string, stat *stat_freebsd11_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func statfs(path string, stat *statfs_freebsd11_t) (err error) {
+func Statfs(path string, stat *Statfs_t) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
@@ -1205,21 +1108,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func statfs_freebsd12(path string, stat *Statfs_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(_SYS_STATFS_FREEBSD12, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Symlink(path string, link string) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
diff --git a/src/syscall/zsyscall_freebsd_arm64.go b/src/syscall/zsyscall_freebsd_arm64.go
index 73bf505..320ce1f 100644
--- a/src/syscall/zsyscall_freebsd_arm64.go
+++ b/src/syscall/zsyscall_freebsd_arm64.go
@@ -463,7 +463,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func fstat(fd int, stat *stat_freebsd11_t) (err error) {
+func Fstat(fd int, stat *Stat_t) (err error) {
 	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -473,17 +473,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func fstat_freebsd12(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := Syscall(_SYS_FSTAT_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fstatat(fd int, path string, stat *stat_freebsd11_t, flags int) (err error) {
+func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
@@ -498,22 +488,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func fstatat_freebsd12(fd int, path string, stat *Stat_t, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(_SYS_FSTATAT_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fstatfs(fd int, stat *statfs_freebsd11_t) (err error) {
+func Fstatfs(fd int, stat *Statfs_t) (err error) {
 	_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
@@ -523,16 +498,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func fstatfs_freebsd12(fd int, stat *Statfs_t) (err error) {
-	_, _, e1 := Syscall(_SYS_FSTATFS_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Fsync(fd int) (err error) {
 	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
 	if e1 != 0 {
@@ -553,7 +518,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
+func getdirentries(fd int, buf []byte, basep *uint64) (n int, err error) {
 	var _p0 unsafe.Pointer
 	if len(buf) > 0 {
 		_p0 = unsafe.Pointer(&buf[0])
@@ -570,23 +535,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func getdirentries_freebsd12(fd int, buf []byte, basep *uint64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(_SYS_GETDIRENTRIES_FREEBSD12, uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Getdtablesize() (size int) {
 	r0, _, _ := Syscall(SYS_GETDTABLESIZE, 0, 0, 0)
 	size = int(r0)
@@ -788,21 +736,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func lstat(path string, stat *stat_freebsd11_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Mkdir(path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -833,28 +766,13 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func mknod(path string, mode uint32, dev int) (err error) {
+func mknodat(fd int, path string, mode uint32, dev uint64) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
 		return
 	}
-	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func mknodat_freebsd12(fd int, path string, mode uint32, dev uint64) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(_SYS_MKNODAT_FREEBSD12, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
+	_, _, e1 := Syscall6(SYS_MKNODAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
 	if e1 != 0 {
 		err = errnoErr(e1)
 	}
@@ -1175,22 +1093,7 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func stat(path string, stat *stat_freebsd11_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func statfs(path string, stat *statfs_freebsd11_t) (err error) {
+func Statfs(path string, stat *Statfs_t) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
 	if err != nil {
@@ -1205,21 +1108,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func statfs_freebsd12(path string, stat *Statfs_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(_SYS_STATFS_FREEBSD12, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Symlink(path string, link string) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
diff --git a/src/syscall/zsyscall_freebsd_riscv64.go b/src/syscall/zsyscall_freebsd_riscv64.go
new file mode 100644
index 0000000..a63eafb
--- /dev/null
+++ b/src/syscall/zsyscall_freebsd_riscv64.go
@@ -0,0 +1,1308 @@
+// mksyscall.pl -tags freebsd,riscv64 syscall_bsd.go syscall_freebsd.go syscall_freebsd_riscv64.go
+// Code generated by the command above; DO NOT EDIT.
+
+//go:build freebsd && riscv64
+
+package syscall
+
+import "unsafe"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setgroups(ngid int, gid *_Gid_t) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
+	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+	wpid = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socket(domain int, typ int, proto int) (fd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
+	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
+	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Shutdown(s int, how int) (err error) {
+	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
+	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
+	r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
+	var _p0 unsafe.Pointer
+	if len(mib) > 0 {
+		_p0 = unsafe.Pointer(&mib[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimes(path string, timeval *[2]Timeval) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func futimes(fd int, timeval *[2]Timeval) (err error) {
+	_, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fcntl(fd int, cmd int, arg int) (val int, err error) {
+	r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
+	val = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe2(p *[2]_C_int, flags int) (err error) {
+	_, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Access(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
+	_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chflags(path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chmod(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chroot(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Close(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup(fd int) (nfd int, err error) {
+	r0, _, e1 := Syscall(SYS_DUP, uintptr(fd), 0, 0)
+	nfd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup2(from int, to int) (err error) {
+	_, _, e1 := Syscall(SYS_DUP2, uintptr(from), uintptr(to), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchdir(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchflags(fd int, flags int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchmod(fd int, mode uint32) (err error) {
+	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchown(fd int, uid int, gid int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Flock(fd int, how int) (err error) {
+	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fpathconf(fd int, name int) (val int, err error) {
+	r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0)
+	val = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstat(fd int, stat *Stat_t) (err error) {
+	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstatfs(fd int, stat *Statfs_t) (err error) {
+	_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fsync(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ftruncate(fd int, length int64) (err error) {
+	_, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getdirentries(fd int, buf []byte, basep *uint64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_GETDIRENTRIES, uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getdtablesize() (size int) {
+	r0, _, _ := Syscall(SYS_GETDTABLESIZE, 0, 0, 0)
+	size = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getegid() (egid int) {
+	r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
+	egid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Geteuid() (uid int) {
+	r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getgid() (gid int) {
+	r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
+	gid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgid(pid int) (pgid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
+	pgid = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgrp() (pgrp int) {
+	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
+	pgrp = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpid() (pid int) {
+	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
+	pid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getppid() (ppid int) {
+	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
+	ppid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpriority(which int, who int) (prio int, err error) {
+	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
+	prio = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrlimit(which int, lim *Rlimit) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrusage(who int, rusage *Rusage) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getsid(pid int) (sid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0)
+	sid = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Gettimeofday(tv *Timeval) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getuid() (uid int) {
+	r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Issetugid() (tainted bool) {
+	r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0)
+	tainted = bool(r0 != 0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kill(pid int, signum Signal) (err error) {
+	_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kqueue() (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lchown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Link(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Listen(s int, backlog int) (err error) {
+	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkdir(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkfifo(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mknodat(fd int, path string, mode uint32, dev uint64) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_MKNODAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
+	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Open(path string, mode int, perm uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pathconf(path string, name int) (val int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
+	val = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pread(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pwrite(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func read(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Readlink(path string, buf []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(buf) > 0 {
+		_p1 = unsafe.Pointer(&buf[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rename(from string, to string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(from)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(to)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Revoke(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rmdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
+	r0, _, e1 := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence))
+	newoffset = int64(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) {
+	_, _, e1 := Syscall6(SYS_SELECT, uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setegid(egid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETEGID, uintptr(egid), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seteuid(euid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setgid(gid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setlogin(name string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(name)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpgid(pid int, pgid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpriority(which int, who int, prio int) (err error) {
+	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setregid(rgid int, egid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setreuid(ruid int, euid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setrlimit(which int, lim *Rlimit) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setsid() (pid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
+	pid = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Settimeofday(tp *Timeval) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setuid(uid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Statfs(path string, stat *Statfs_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Symlink(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sync() (err error) {
+	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Truncate(path string, length int64) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), uintptr(length), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Umask(newmask int) (oldmask int) {
+	r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0)
+	oldmask = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Undelete(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNDELETE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unlink(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unmount(path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func write(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
+	r0, _, e1 := Syscall6(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos))
+	ret = uintptr(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func munmap(addr uintptr, length uintptr) (err error) {
+	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error) {
+	r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
+	nfd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flag), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getcwd(buf []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS___GETCWD, uintptr(_p0), uintptr(len(buf)), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
diff --git a/src/syscall/zsyscall_linux_386.go b/src/syscall/zsyscall_linux_386.go
index 36a3d7e..6a646fb 100644
--- a/src/syscall/zsyscall_linux_386.go
+++ b/src/syscall/zsyscall_linux_386.go
@@ -24,6 +24,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func faccessat2(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(_SYS_faccessat2, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func fchmodat(dirfd int, path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -1067,17 +1082,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func EpollCreate(size int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Fchown(fd int, uid int, gid int) (err error) {
 	_, _, e1 := Syscall(SYS_FCHOWN32, uintptr(fd), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
diff --git a/src/syscall/zsyscall_linux_amd64.go b/src/syscall/zsyscall_linux_amd64.go
index 07f328e..d5b0099 100644
--- a/src/syscall/zsyscall_linux_amd64.go
+++ b/src/syscall/zsyscall_linux_amd64.go
@@ -24,6 +24,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func faccessat2(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(_SYS_faccessat2, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func fchmodat(dirfd int, path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -1067,17 +1082,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func EpollCreate(size int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Fchown(fd int, uid int, gid int) (err error) {
 	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
diff --git a/src/syscall/zsyscall_linux_arm.go b/src/syscall/zsyscall_linux_arm.go
index df79dbd..69f811a 100644
--- a/src/syscall/zsyscall_linux_arm.go
+++ b/src/syscall/zsyscall_linux_arm.go
@@ -1,4 +1,4 @@
-// mksyscall.pl -l32 -arm -tags linux,arm syscall_linux.go syscall_linux_arm.go
+// mksyscall.pl -l32 -arm -tags linux,arm syscall_linux.go syscall_linux_arm.go syscall_linux_accept.go
 // Code generated by the command above; DO NOT EDIT.
 
 //go:build linux && arm
@@ -24,6 +24,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func faccessat2(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(_SYS_faccessat2, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func fchmodat(dirfd int, path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -1225,17 +1240,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func EpollCreate(size int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Fchown(fd int, uid int, gid int) (err error) {
 	_, _, e1 := Syscall(SYS_FCHOWN32, uintptr(fd), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
@@ -1597,3 +1601,14 @@
 	}
 	return
 }
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	fd = int(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
diff --git a/src/syscall/zsyscall_linux_arm64.go b/src/syscall/zsyscall_linux_arm64.go
index 73321bd..7655ccb 100644
--- a/src/syscall/zsyscall_linux_arm64.go
+++ b/src/syscall/zsyscall_linux_arm64.go
@@ -24,6 +24,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func faccessat2(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(_SYS_faccessat2, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func fchmodat(dirfd int, path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -1094,21 +1109,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
diff --git a/src/syscall/zsyscall_linux_loong64.go b/src/syscall/zsyscall_linux_loong64.go
index b3d703d..abbc19b 100644
--- a/src/syscall/zsyscall_linux_loong64.go
+++ b/src/syscall/zsyscall_linux_loong64.go
@@ -24,6 +24,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func faccessat2(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(_SYS_faccessat2, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func fchmodat(dirfd int, path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
diff --git a/src/syscall/zsyscall_linux_mips.go b/src/syscall/zsyscall_linux_mips.go
index 1ef8eeb..792668c 100644
--- a/src/syscall/zsyscall_linux_mips.go
+++ b/src/syscall/zsyscall_linux_mips.go
@@ -24,6 +24,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func faccessat2(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(_SYS_faccessat2, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func fchmodat(dirfd int, path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -1067,17 +1082,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func EpollCreate(size int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Fchown(fd int, uid int, gid int) (err error) {
 	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
diff --git a/src/syscall/zsyscall_linux_mips64.go b/src/syscall/zsyscall_linux_mips64.go
index 1ed877c..27dbcb8 100644
--- a/src/syscall/zsyscall_linux_mips64.go
+++ b/src/syscall/zsyscall_linux_mips64.go
@@ -24,6 +24,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func faccessat2(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(_SYS_faccessat2, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func fchmodat(dirfd int, path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -1067,17 +1082,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func EpollCreate(size int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Fchown(fd int, uid int, gid int) (err error) {
 	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
diff --git a/src/syscall/zsyscall_linux_mips64le.go b/src/syscall/zsyscall_linux_mips64le.go
index 3d7cc9e..0362303 100644
--- a/src/syscall/zsyscall_linux_mips64le.go
+++ b/src/syscall/zsyscall_linux_mips64le.go
@@ -24,6 +24,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func faccessat2(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(_SYS_faccessat2, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func fchmodat(dirfd int, path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -1067,17 +1082,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func EpollCreate(size int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Fchown(fd int, uid int, gid int) (err error) {
 	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
diff --git a/src/syscall/zsyscall_linux_mipsle.go b/src/syscall/zsyscall_linux_mipsle.go
index 59b49dd..5320dfa 100644
--- a/src/syscall/zsyscall_linux_mipsle.go
+++ b/src/syscall/zsyscall_linux_mipsle.go
@@ -24,6 +24,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func faccessat2(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(_SYS_faccessat2, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func fchmodat(dirfd int, path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -1067,17 +1082,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func EpollCreate(size int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func Fchown(fd int, uid int, gid int) (err error) {
 	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
 	if e1 != 0 {
diff --git a/src/syscall/zsyscall_linux_ppc64.go b/src/syscall/zsyscall_linux_ppc64.go
index 93632bd..61f3063 100644
--- a/src/syscall/zsyscall_linux_ppc64.go
+++ b/src/syscall/zsyscall_linux_ppc64.go
@@ -24,6 +24,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func faccessat2(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(_SYS_faccessat2, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func fchmodat(dirfd int, path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -1067,17 +1082,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func EpollCreate(size int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
 	var _p0 unsafe.Pointer
 	if len(events) > 0 {
diff --git a/src/syscall/zsyscall_linux_ppc64le.go b/src/syscall/zsyscall_linux_ppc64le.go
index fc8f6b7..3e14ab3 100644
--- a/src/syscall/zsyscall_linux_ppc64le.go
+++ b/src/syscall/zsyscall_linux_ppc64le.go
@@ -24,6 +24,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func faccessat2(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(_SYS_faccessat2, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func fchmodat(dirfd int, path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -1067,17 +1082,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func EpollCreate(size int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
 	var _p0 unsafe.Pointer
 	if len(events) > 0 {
diff --git a/src/syscall/zsyscall_linux_riscv64.go b/src/syscall/zsyscall_linux_riscv64.go
index 0efa707..4a3fa5d 100644
--- a/src/syscall/zsyscall_linux_riscv64.go
+++ b/src/syscall/zsyscall_linux_riscv64.go
@@ -24,6 +24,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func faccessat2(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(_SYS_faccessat2, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func fchmodat(dirfd int, path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -1094,21 +1109,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_FSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
diff --git a/src/syscall/zsyscall_linux_s390x.go b/src/syscall/zsyscall_linux_s390x.go
index 568bb43..1fca71e 100644
--- a/src/syscall/zsyscall_linux_s390x.go
+++ b/src/syscall/zsyscall_linux_s390x.go
@@ -24,6 +24,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func faccessat2(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(_SYS_faccessat2, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func fchmodat(dirfd int, path string, mode uint32) (err error) {
 	var _p0 *byte
 	_p0, err = BytePtrFromString(path)
@@ -1067,17 +1082,6 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
-func EpollCreate(size int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = errnoErr(e1)
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
 func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
 	var _p0 unsafe.Pointer
 	if len(events) > 0 {
diff --git a/src/syscall/zsyscall_openbsd_386.go b/src/syscall/zsyscall_openbsd_386.go
index f7986d5..b60af17 100644
--- a/src/syscall/zsyscall_openbsd_386.go
+++ b/src/syscall/zsyscall_openbsd_386.go
@@ -1610,6 +1610,27 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func writev(fd int, iovecs []Iovec) (n uintptr, err error) {
+	var _p0 unsafe.Pointer
+	if len(iovecs) > 0 {
+		_p0 = unsafe.Pointer(&iovecs[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_writev_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(iovecs)))
+	n = uintptr(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func libc_writev_trampoline()
+
+//go:cgo_import_dynamic libc_writev writev "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
 	r0, _, e1 := syscall9(abi.FuncPCABI0(libc_mmap_trampoline), uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos), uintptr(pos>>32), 0, 0)
 	ret = uintptr(r0)
diff --git a/src/syscall/zsyscall_openbsd_386.s b/src/syscall/zsyscall_openbsd_386.s
index e2c5862..a77d931 100644
--- a/src/syscall/zsyscall_openbsd_386.s
+++ b/src/syscall/zsyscall_openbsd_386.s
@@ -201,6 +201,8 @@
 	JMP	libc_unmount(SB)
 TEXT ·libc_write_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_write(SB)
+TEXT ·libc_writev_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_writev(SB)
 TEXT ·libc_mmap_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_mmap(SB)
 TEXT ·libc_munmap_trampoline(SB),NOSPLIT,$0-0
diff --git a/src/syscall/zsyscall_openbsd_amd64.go b/src/syscall/zsyscall_openbsd_amd64.go
index 605443d..8b3e81e 100644
--- a/src/syscall/zsyscall_openbsd_amd64.go
+++ b/src/syscall/zsyscall_openbsd_amd64.go
@@ -1610,6 +1610,27 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func writev(fd int, iovecs []Iovec) (n uintptr, err error) {
+	var _p0 unsafe.Pointer
+	if len(iovecs) > 0 {
+		_p0 = unsafe.Pointer(&iovecs[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := syscallX(abi.FuncPCABI0(libc_writev_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(iovecs)))
+	n = uintptr(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func libc_writev_trampoline()
+
+//go:cgo_import_dynamic libc_writev writev "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
 	r0, _, e1 := syscall6X(abi.FuncPCABI0(libc_mmap_trampoline), uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos))
 	ret = uintptr(r0)
diff --git a/src/syscall/zsyscall_openbsd_amd64.s b/src/syscall/zsyscall_openbsd_amd64.s
index 964c9ed..d13e9c0 100644
--- a/src/syscall/zsyscall_openbsd_amd64.s
+++ b/src/syscall/zsyscall_openbsd_amd64.s
@@ -201,6 +201,8 @@
 	JMP	libc_unmount(SB)
 TEXT ·libc_write_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_write(SB)
+TEXT ·libc_writev_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_writev(SB)
 TEXT ·libc_mmap_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_mmap(SB)
 TEXT ·libc_munmap_trampoline(SB),NOSPLIT,$0-0
diff --git a/src/syscall/zsyscall_openbsd_arm.go b/src/syscall/zsyscall_openbsd_arm.go
index 0f2312f..42d5781 100644
--- a/src/syscall/zsyscall_openbsd_arm.go
+++ b/src/syscall/zsyscall_openbsd_arm.go
@@ -1610,6 +1610,27 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func writev(fd int, iovecs []Iovec) (n uintptr, err error) {
+	var _p0 unsafe.Pointer
+	if len(iovecs) > 0 {
+		_p0 = unsafe.Pointer(&iovecs[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := syscall(abi.FuncPCABI0(libc_writev_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(iovecs)))
+	n = uintptr(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func libc_writev_trampoline()
+
+//go:cgo_import_dynamic libc_writev writev "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
 	r0, _, e1 := syscall9(abi.FuncPCABI0(libc_mmap_trampoline), uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), 0, uintptr(pos), uintptr(pos>>32), 0)
 	ret = uintptr(r0)
diff --git a/src/syscall/zsyscall_openbsd_arm.s b/src/syscall/zsyscall_openbsd_arm.s
index 5975780..34ae794 100644
--- a/src/syscall/zsyscall_openbsd_arm.s
+++ b/src/syscall/zsyscall_openbsd_arm.s
@@ -201,6 +201,8 @@
 	JMP	libc_unmount(SB)
 TEXT ·libc_write_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_write(SB)
+TEXT ·libc_writev_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_writev(SB)
 TEXT ·libc_mmap_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_mmap(SB)
 TEXT ·libc_munmap_trampoline(SB),NOSPLIT,$0-0
diff --git a/src/syscall/zsyscall_openbsd_arm64.go b/src/syscall/zsyscall_openbsd_arm64.go
index 1367e2a..7a5a2c0 100644
--- a/src/syscall/zsyscall_openbsd_arm64.go
+++ b/src/syscall/zsyscall_openbsd_arm64.go
@@ -1610,6 +1610,27 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func writev(fd int, iovecs []Iovec) (n uintptr, err error) {
+	var _p0 unsafe.Pointer
+	if len(iovecs) > 0 {
+		_p0 = unsafe.Pointer(&iovecs[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := syscallX(abi.FuncPCABI0(libc_writev_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(iovecs)))
+	n = uintptr(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+func libc_writev_trampoline()
+
+//go:cgo_import_dynamic libc_writev writev "libc.so"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
 	r0, _, e1 := syscall6X(abi.FuncPCABI0(libc_mmap_trampoline), uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos))
 	ret = uintptr(r0)
diff --git a/src/syscall/zsyscall_openbsd_arm64.s b/src/syscall/zsyscall_openbsd_arm64.s
index 2c4a0b0..20a79e4 100644
--- a/src/syscall/zsyscall_openbsd_arm64.s
+++ b/src/syscall/zsyscall_openbsd_arm64.s
@@ -201,6 +201,8 @@
 	JMP	libc_unmount(SB)
 TEXT ·libc_write_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_write(SB)
+TEXT ·libc_writev_trampoline(SB),NOSPLIT,$0-0
+	JMP	libc_writev(SB)
 TEXT ·libc_mmap_trampoline(SB),NOSPLIT,$0-0
 	JMP	libc_mmap(SB)
 TEXT ·libc_munmap_trampoline(SB),NOSPLIT,$0-0
diff --git a/src/syscall/zsyscall_solaris_amd64.go b/src/syscall/zsyscall_solaris_amd64.go
index a2bbeed..19e5ec1 100644
--- a/src/syscall/zsyscall_solaris_amd64.go
+++ b/src/syscall/zsyscall_solaris_amd64.go
@@ -85,6 +85,7 @@
 //go:cgo_import_dynamic libc___xnet_socket __xnet_socket "libsocket.so"
 //go:cgo_import_dynamic libc___xnet_socketpair __xnet_socketpair "libsocket.so"
 //go:cgo_import_dynamic libc_write write "libc.so"
+//go:cgo_import_dynamic libc_writev writev "libc.so"
 //go:cgo_import_dynamic libc___xnet_getsockopt __xnet_getsockopt "libsocket.so"
 //go:cgo_import_dynamic libc_getpeername getpeername "libsocket.so"
 //go:cgo_import_dynamic libc_getsockname getsockname "libsocket.so"
@@ -172,6 +173,7 @@
 //go:linkname libc___xnet_socket libc___xnet_socket
 //go:linkname libc___xnet_socketpair libc___xnet_socketpair
 //go:linkname libc_write libc_write
+//go:linkname libc_writev libc_writev
 //go:linkname libc___xnet_getsockopt libc___xnet_getsockopt
 //go:linkname libc_getpeername libc_getpeername
 //go:linkname libc_getsockname libc_getsockname
@@ -262,6 +264,7 @@
 	libc___xnet_socket,
 	libc___xnet_socketpair,
 	libc_write,
+	libc_writev,
 	libc___xnet_getsockopt,
 	libc_getpeername,
 	libc_getsockname,
@@ -1209,6 +1212,21 @@
 
 // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
 
+func writev(fd int, iovecs []Iovec) (n uintptr, err error) {
+	var _p0 *Iovec
+	if len(iovecs) > 0 {
+		_p0 = &iovecs[0]
+	}
+	r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc_writev)), 3, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(iovecs)), 0, 0, 0)
+	n = uintptr(r0)
+	if e1 != 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
 func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
 	_, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&libc___xnet_getsockopt)), 5, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
 	if e1 != 0 {
diff --git a/src/syscall/zsysnum_freebsd_386.go b/src/syscall/zsysnum_freebsd_386.go
index 355b2ec..ada885e 100644
--- a/src/syscall/zsysnum_freebsd_386.go
+++ b/src/syscall/zsysnum_freebsd_386.go
@@ -120,14 +120,10 @@
 	SYS_SETGID                   = 181 // { int setgid(gid_t gid); }
 	SYS_SETEGID                  = 182 // { int setegid(gid_t egid); }
 	SYS_SETEUID                  = 183 // { int seteuid(uid_t euid); }
-	SYS_STAT                     = 188 // { int stat(char *path, struct stat *ub); }
-	SYS_FSTAT                    = 189 // { int fstat(int fd, struct stat *sb); }
-	SYS_LSTAT                    = 190 // { int lstat(char *path, struct stat *ub); }
 	SYS_PATHCONF                 = 191 // { int pathconf(char *path, int name); }
 	SYS_FPATHCONF                = 192 // { int fpathconf(int fd, int name); }
 	SYS_GETRLIMIT                = 194 // { int getrlimit(u_int which, \
 	SYS_SETRLIMIT                = 195 // { int setrlimit(u_int which, \
-	SYS_GETDIRENTRIES            = 196 // { int getdirentries(int fd, char *buf, \
 	SYS_FREEBSD6_MMAP            = 197 // { caddr_t freebsd6_mmap(caddr_t addr, \
 	SYS_FREEBSD6_LSEEK           = 199 // { off_t freebsd6_lseek(int fd, int pad, \
 	SYS_FREEBSD6_TRUNCATE        = 200 // { int freebsd6_truncate(char *path, int pad, \
@@ -234,9 +230,6 @@
 	SYS_UUIDGEN                  = 392 // { int uuidgen(struct uuid *store, \
 	SYS_SENDFILE                 = 393 // { int sendfile(int fd, int s, off_t offset, \
 	SYS_MAC_SYSCALL              = 394 // { int mac_syscall(const char *policy, \
-	SYS_GETFSSTAT                = 395 // { int getfsstat(struct statfs *buf, \
-	SYS_STATFS                   = 396 // { int statfs(char *path, \
-	SYS_FSTATFS                  = 397 // { int fstatfs(int fd, struct statfs *buf); }
 	SYS_FHSTATFS                 = 398 // { int fhstatfs(const struct fhandle *u_fhp, \
 	SYS___MAC_GET_PID            = 409 // { int __mac_get_pid(pid_t pid, \
 	SYS___MAC_GET_LINK           = 410 // { int __mac_get_link(const char *path_p, \
@@ -306,12 +299,10 @@
 	SYS_FCHMODAT                 = 490 // { int fchmodat(int fd, char *path, mode_t mode, \
 	SYS_FCHOWNAT                 = 491 // { int fchownat(int fd, char *path, uid_t uid, \
 	SYS_FEXECVE                  = 492 // { int fexecve(int fd, char **argv, \
-	SYS_FSTATAT                  = 493 // { int fstatat(int fd, char *path, \
 	SYS_FUTIMESAT                = 494 // { int futimesat(int fd, char *path, \
 	SYS_LINKAT                   = 495 // { int linkat(int fd1, char *path1, int fd2, \
 	SYS_MKDIRAT                  = 496 // { int mkdirat(int fd, char *path, mode_t mode); }
 	SYS_MKFIFOAT                 = 497 // { int mkfifoat(int fd, char *path, mode_t mode); }
-	SYS_MKNODAT                  = 498 // { int mknodat(int fd, char *path, mode_t mode, \
 	SYS_OPENAT                   = 499 // { int openat(int fd, char *path, int flag, \
 	SYS_READLINKAT               = 500 // { int readlinkat(int fd, char *path, char *buf, \
 	SYS_RENAMEAT                 = 501 // { int renameat(int oldfd, char *old, int newfd, \
@@ -348,4 +339,11 @@
 	SYS_PIPE2                    = 542 // { int pipe2(int *fildes, int flags); }
 	SYS_PROCCTL                  = 544 // { int procctl(idtype_t idtype, id_t id, \
 	SYS_UTIMENSAT                = 547 // { int utimensat(int fd, \
+	SYS_FSTAT                    = 551 // { int fstat(int fd, _Out_ struct stat *sb); }
+	SYS_FSTATAT                  = 552 // { int fstatat(int fd, _In_z_ char *path, \
+	SYS_GETDIRENTRIES            = 554 // { ssize_t getdirentries(int fd, \
+	SYS_STATFS                   = 555 // { int statfs(_In_z_ char *path, \
+	SYS_FSTATFS                  = 556 // { int fstatfs(int fd, \
+	SYS_GETFSSTAT                = 557 // { int getfsstat( \
+	SYS_MKNODAT                  = 559 // { int mknodat(int fd, _In_z_ char *path, \
 )
diff --git a/src/syscall/zsysnum_freebsd_amd64.go b/src/syscall/zsysnum_freebsd_amd64.go
index 84c821c..85a50ad 100644
--- a/src/syscall/zsysnum_freebsd_amd64.go
+++ b/src/syscall/zsysnum_freebsd_amd64.go
@@ -120,14 +120,10 @@
 	SYS_SETGID                   = 181 // { int setgid(gid_t gid); }
 	SYS_SETEGID                  = 182 // { int setegid(gid_t egid); }
 	SYS_SETEUID                  = 183 // { int seteuid(uid_t euid); }
-	SYS_STAT                     = 188 // { int stat(char *path, struct stat *ub); }
-	SYS_FSTAT                    = 189 // { int fstat(int fd, struct stat *sb); }
-	SYS_LSTAT                    = 190 // { int lstat(char *path, struct stat *ub); }
 	SYS_PATHCONF                 = 191 // { int pathconf(char *path, int name); }
 	SYS_FPATHCONF                = 192 // { int fpathconf(int fd, int name); }
 	SYS_GETRLIMIT                = 194 // { int getrlimit(u_int which, \
 	SYS_SETRLIMIT                = 195 // { int setrlimit(u_int which, \
-	SYS_GETDIRENTRIES            = 196 // { int getdirentries(int fd, char *buf, \
 	SYS_FREEBSD6_MMAP            = 197 // { caddr_t freebsd6_mmap(caddr_t addr, \
 	SYS_FREEBSD6_LSEEK           = 199 // { off_t freebsd6_lseek(int fd, int pad, \
 	SYS_FREEBSD6_TRUNCATE        = 200 // { int freebsd6_truncate(char *path, int pad, \
@@ -234,9 +230,6 @@
 	SYS_UUIDGEN                  = 392 // { int uuidgen(struct uuid *store, \
 	SYS_SENDFILE                 = 393 // { int sendfile(int fd, int s, off_t offset, \
 	SYS_MAC_SYSCALL              = 394 // { int mac_syscall(const char *policy, \
-	SYS_GETFSSTAT                = 395 // { int getfsstat(struct statfs *buf, \
-	SYS_STATFS                   = 396 // { int statfs(char *path, \
-	SYS_FSTATFS                  = 397 // { int fstatfs(int fd, struct statfs *buf); }
 	SYS_FHSTATFS                 = 398 // { int fhstatfs(const struct fhandle *u_fhp, \
 	SYS___MAC_GET_PID            = 409 // { int __mac_get_pid(pid_t pid, \
 	SYS___MAC_GET_LINK           = 410 // { int __mac_get_link(const char *path_p, \
@@ -306,12 +299,10 @@
 	SYS_FCHMODAT                 = 490 // { int fchmodat(int fd, char *path, mode_t mode, \
 	SYS_FCHOWNAT                 = 491 // { int fchownat(int fd, char *path, uid_t uid, \
 	SYS_FEXECVE                  = 492 // { int fexecve(int fd, char **argv, \
-	SYS_FSTATAT                  = 493 // { int fstatat(int fd, char *path, \
 	SYS_FUTIMESAT                = 494 // { int futimesat(int fd, char *path, \
 	SYS_LINKAT                   = 495 // { int linkat(int fd1, char *path1, int fd2, \
 	SYS_MKDIRAT                  = 496 // { int mkdirat(int fd, char *path, mode_t mode); }
 	SYS_MKFIFOAT                 = 497 // { int mkfifoat(int fd, char *path, mode_t mode); }
-	SYS_MKNODAT                  = 498 // { int mknodat(int fd, char *path, mode_t mode, \
 	SYS_OPENAT                   = 499 // { int openat(int fd, char *path, int flag, \
 	SYS_READLINKAT               = 500 // { int readlinkat(int fd, char *path, char *buf, \
 	SYS_RENAMEAT                 = 501 // { int renameat(int oldfd, char *old, int newfd, \
@@ -348,4 +339,11 @@
 	SYS_PIPE2                    = 542 // { int pipe2(int *fildes, int flags); }
 	SYS_PROCCTL                  = 544 // { int procctl(idtype_t idtype, id_t id, \
 	SYS_UTIMENSAT                = 547 // { int utimensat(int fd, \
+	SYS_FSTAT                    = 551 // { int fstat(int fd, _Out_ struct stat *sb); }
+	SYS_FSTATAT                  = 552 // { int fstatat(int fd, _In_z_ char *path, \
+	SYS_GETDIRENTRIES            = 554 // { ssize_t getdirentries(int fd, \
+	SYS_STATFS                   = 555 // { int statfs(_In_z_ char *path, \
+	SYS_FSTATFS                  = 556 // { int fstatfs(int fd, \
+	SYS_GETFSSTAT                = 557 // { int getfsstat( \
+	SYS_MKNODAT                  = 559 // { int mknodat(int fd, _In_z_ char *path, \
 )
diff --git a/src/syscall/zsysnum_freebsd_arm.go b/src/syscall/zsysnum_freebsd_arm.go
index 785e787..7f6e3fc 100644
--- a/src/syscall/zsysnum_freebsd_arm.go
+++ b/src/syscall/zsysnum_freebsd_arm.go
@@ -120,14 +120,10 @@
 	SYS_SETGID                   = 181 // { int setgid(gid_t gid); }
 	SYS_SETEGID                  = 182 // { int setegid(gid_t egid); }
 	SYS_SETEUID                  = 183 // { int seteuid(uid_t euid); }
-	SYS_STAT                     = 188 // { int stat(char *path, struct stat *ub); }
-	SYS_FSTAT                    = 189 // { int fstat(int fd, struct stat *sb); }
-	SYS_LSTAT                    = 190 // { int lstat(char *path, struct stat *ub); }
 	SYS_PATHCONF                 = 191 // { int pathconf(char *path, int name); }
 	SYS_FPATHCONF                = 192 // { int fpathconf(int fd, int name); }
 	SYS_GETRLIMIT                = 194 // { int getrlimit(u_int which, \
 	SYS_SETRLIMIT                = 195 // { int setrlimit(u_int which, \
-	SYS_GETDIRENTRIES            = 196 // { int getdirentries(int fd, char *buf, \
 	SYS_FREEBSD6_MMAP            = 197 // { caddr_t freebsd6_mmap(caddr_t addr, \
 	SYS_FREEBSD6_LSEEK           = 199 // { off_t freebsd6_lseek(int fd, int pad, \
 	SYS_FREEBSD6_TRUNCATE        = 200 // { int freebsd6_truncate(char *path, int pad, \
@@ -234,9 +230,6 @@
 	SYS_UUIDGEN                  = 392 // { int uuidgen(struct uuid *store, \
 	SYS_SENDFILE                 = 393 // { int sendfile(int fd, int s, off_t offset, \
 	SYS_MAC_SYSCALL              = 394 // { int mac_syscall(const char *policy, \
-	SYS_GETFSSTAT                = 395 // { int getfsstat(struct statfs *buf, \
-	SYS_STATFS                   = 396 // { int statfs(char *path, \
-	SYS_FSTATFS                  = 397 // { int fstatfs(int fd, struct statfs *buf); }
 	SYS_FHSTATFS                 = 398 // { int fhstatfs(const struct fhandle *u_fhp, \
 	SYS___MAC_GET_PID            = 409 // { int __mac_get_pid(pid_t pid, \
 	SYS___MAC_GET_LINK           = 410 // { int __mac_get_link(const char *path_p, \
@@ -306,12 +299,10 @@
 	SYS_FCHMODAT                 = 490 // { int fchmodat(int fd, char *path, mode_t mode, \
 	SYS_FCHOWNAT                 = 491 // { int fchownat(int fd, char *path, uid_t uid, \
 	SYS_FEXECVE                  = 492 // { int fexecve(int fd, char **argv, \
-	SYS_FSTATAT                  = 493 // { int fstatat(int fd, char *path, \
 	SYS_FUTIMESAT                = 494 // { int futimesat(int fd, char *path, \
 	SYS_LINKAT                   = 495 // { int linkat(int fd1, char *path1, int fd2, \
 	SYS_MKDIRAT                  = 496 // { int mkdirat(int fd, char *path, mode_t mode); }
 	SYS_MKFIFOAT                 = 497 // { int mkfifoat(int fd, char *path, mode_t mode); }
-	SYS_MKNODAT                  = 498 // { int mknodat(int fd, char *path, mode_t mode, \
 	SYS_OPENAT                   = 499 // { int openat(int fd, char *path, int flag, \
 	SYS_READLINKAT               = 500 // { int readlinkat(int fd, char *path, char *buf, \
 	SYS_RENAMEAT                 = 501 // { int renameat(int oldfd, char *old, int newfd, \
@@ -348,4 +339,11 @@
 	SYS_PIPE2                    = 542 // { int pipe2(int *fildes, int flags); }
 	SYS_PROCCTL                  = 544 // { int procctl(idtype_t idtype, id_t id, \
 	SYS_UTIMENSAT                = 547 // { int utimensat(int fd, \
+	SYS_FSTAT                    = 551 // { int fstat(int fd, _Out_ struct stat *sb); }
+	SYS_FSTATAT                  = 552 // { int fstatat(int fd, _In_z_ char *path, \
+	SYS_GETDIRENTRIES            = 554 // { ssize_t getdirentries(int fd, \
+	SYS_STATFS                   = 555 // { int statfs(_In_z_ char *path, \
+	SYS_FSTATFS                  = 556 // { int fstatfs(int fd, \
+	SYS_GETFSSTAT                = 557 // { int getfsstat( \
+	SYS_MKNODAT                  = 559 // { int mknodat(int fd, _In_z_ char *path, \
 )
diff --git a/src/syscall/zsysnum_freebsd_arm64.go b/src/syscall/zsysnum_freebsd_arm64.go
index 7144a8a..bde0f3b 100644
--- a/src/syscall/zsysnum_freebsd_arm64.go
+++ b/src/syscall/zsysnum_freebsd_arm64.go
@@ -123,14 +123,10 @@
 	SYS_SETGID                   = 181 // { int setgid(gid_t gid); }
 	SYS_SETEGID                  = 182 // { int setegid(gid_t egid); }
 	SYS_SETEUID                  = 183 // { int seteuid(uid_t euid); }
-	SYS_STAT                     = 188 // { int stat(char *path, struct stat *ub); }
-	SYS_FSTAT                    = 189 // { int fstat(int fd, struct stat *sb); }
-	SYS_LSTAT                    = 190 // { int lstat(char *path, struct stat *ub); }
 	SYS_PATHCONF                 = 191 // { int pathconf(char *path, int name); }
 	SYS_FPATHCONF                = 192 // { int fpathconf(int fd, int name); }
 	SYS_GETRLIMIT                = 194 // { int getrlimit(u_int which, struct rlimit *rlp); } getrlimit __getrlimit_args int
 	SYS_SETRLIMIT                = 195 // { int setrlimit(u_int which, struct rlimit *rlp); } setrlimit __setrlimit_args int
-	SYS_GETDIRENTRIES            = 196 // { int getdirentries(int fd, char *buf, u_int count, long *basep); }
 	SYS___SYSCTL                 = 202 // { int __sysctl(int *name, u_int namelen, void *old, size_t *oldlenp, void *new, size_t newlen); } __sysctl sysctl_args int
 	SYS_MLOCK                    = 203 // { int mlock(const void *addr, size_t len); }
 	SYS_MUNLOCK                  = 204 // { int munlock(const void *addr, size_t len); }
@@ -250,9 +246,6 @@
 	SYS_UUIDGEN                  = 392 // { int uuidgen(struct uuid *store, int count); }
 	SYS_SENDFILE                 = 393 // { int sendfile(int fd, int s, off_t offset, size_t nbytes, struct sf_hdtr *hdtr, off_t *sbytes, int flags); }
 	SYS_MAC_SYSCALL              = 394 // { int mac_syscall(const char *policy, int call, void *arg); }
-	SYS_GETFSSTAT                = 395 // { int getfsstat(struct statfs *buf, long bufsize, int mode); }
-	SYS_STATFS                   = 396 // { int statfs(char *path, struct statfs *buf); }
-	SYS_FSTATFS                  = 397 // { int fstatfs(int fd, struct statfs *buf); }
 	SYS_FHSTATFS                 = 398 // { int fhstatfs(const struct fhandle *u_fhp, struct statfs *buf); }
 	SYS_KSEM_CLOSE               = 400 // { int ksem_close(semid_t id); }
 	SYS_KSEM_POST                = 401 // { int ksem_post(semid_t id); }
@@ -337,12 +330,10 @@
 	SYS_FCHMODAT                 = 490 // { int fchmodat(int fd, char *path, mode_t mode, int flag); }
 	SYS_FCHOWNAT                 = 491 // { int fchownat(int fd, char *path, uid_t uid, gid_t gid, int flag); }
 	SYS_FEXECVE                  = 492 // { int fexecve(int fd, char **argv, char **envv); }
-	SYS_FSTATAT                  = 493 // { int fstatat(int fd, char *path, struct stat *buf, int flag); }
 	SYS_FUTIMESAT                = 494 // { int futimesat(int fd, char *path, struct timeval *times); }
 	SYS_LINKAT                   = 495 // { int linkat(int fd1, char *path1, int fd2, char *path2, int flag); }
 	SYS_MKDIRAT                  = 496 // { int mkdirat(int fd, char *path, mode_t mode); }
 	SYS_MKFIFOAT                 = 497 // { int mkfifoat(int fd, char *path, mode_t mode); }
-	SYS_MKNODAT                  = 498 // { int mknodat(int fd, char *path, mode_t mode, dev_t dev); }
 	SYS_OPENAT                   = 499 // { int openat(int fd, char *path, int flag, mode_t mode); }
 	SYS_READLINKAT               = 500 // { int readlinkat(int fd, char *path, char *buf, size_t bufsize); }
 	SYS_RENAMEAT                 = 501 // { int renameat(int oldfd, char *old, int newfd, char *new); }
@@ -393,4 +384,11 @@
 	SYS_NUMA_GETAFFINITY         = 548 // { int numa_getaffinity(cpuwhich_t which, id_t id, struct vm_domain_policy_entry *policy); }
 	SYS_NUMA_SETAFFINITY         = 549 // { int numa_setaffinity(cpuwhich_t which, id_t id, const struct vm_domain_policy_entry *policy); }
 	SYS_FDATASYNC                = 550 // { int fdatasync(int fd); }
+	SYS_FSTAT                    = 551 // { int fstat(int fd, _Out_ struct stat *sb); }
+	SYS_FSTATAT                  = 552 // { int fstatat(int fd, _In_z_ char *path, \
+	SYS_GETDIRENTRIES            = 554 // { ssize_t getdirentries(int fd, \
+	SYS_STATFS                   = 555 // { int statfs(_In_z_ char *path, \
+	SYS_FSTATFS                  = 556 // { int fstatfs(int fd, \
+	SYS_GETFSSTAT                = 557 // { int getfsstat( \
+	SYS_MKNODAT                  = 559 // { int mknodat(int fd, _In_z_ char *path, \
 )
diff --git a/src/syscall/zsysnum_freebsd_riscv64.go b/src/syscall/zsysnum_freebsd_riscv64.go
new file mode 100644
index 0000000..48e7029
--- /dev/null
+++ b/src/syscall/zsysnum_freebsd_riscv64.go
@@ -0,0 +1,394 @@
+// mksysnum_freebsd.pl
+// Code generated by the command above; DO NOT EDIT.
+
+//go:build riscv64 && freebsd
+
+package syscall
+
+const (
+	// SYS_NOSYS = 0;  // { int nosys(void); } syscall nosys_args int
+	SYS_EXIT                     = 1   // { void sys_exit(int rval); } exit sys_exit_args void
+	SYS_FORK                     = 2   // { int fork(void); }
+	SYS_READ                     = 3   // { ssize_t read(int fd, void *buf, size_t nbyte); }
+	SYS_WRITE                    = 4   // { ssize_t write(int fd, const void *buf, size_t nbyte); }
+	SYS_OPEN                     = 5   // { int open(char *path, int flags, int mode); }
+	SYS_CLOSE                    = 6   // { int close(int fd); }
+	SYS_WAIT4                    = 7   // { int wait4(int pid, int *status, int options, struct rusage *rusage); }
+	SYS_LINK                     = 9   // { int link(char *path, char *link); }
+	SYS_UNLINK                   = 10  // { int unlink(char *path); }
+	SYS_CHDIR                    = 12  // { int chdir(char *path); }
+	SYS_FCHDIR                   = 13  // { int fchdir(int fd); }
+	SYS_MKNOD                    = 14  // { int mknod(char *path, int mode, int dev); }
+	SYS_CHMOD                    = 15  // { int chmod(char *path, int mode); }
+	SYS_CHOWN                    = 16  // { int chown(char *path, int uid, int gid); }
+	SYS_OBREAK                   = 17  // { int obreak(char *nsize); } break obreak_args int
+	SYS_GETPID                   = 20  // { pid_t getpid(void); }
+	SYS_MOUNT                    = 21  // { int mount(char *type, char *path, int flags, caddr_t data); }
+	SYS_UNMOUNT                  = 22  // { int unmount(char *path, int flags); }
+	SYS_SETUID                   = 23  // { int setuid(uid_t uid); }
+	SYS_GETUID                   = 24  // { uid_t getuid(void); }
+	SYS_GETEUID                  = 25  // { uid_t geteuid(void); }
+	SYS_PTRACE                   = 26  // { int ptrace(int req, pid_t pid, caddr_t addr, int data); }
+	SYS_RECVMSG                  = 27  // { int recvmsg(int s, struct msghdr *msg, int flags); }
+	SYS_SENDMSG                  = 28  // { int sendmsg(int s, struct msghdr *msg, int flags); }
+	SYS_RECVFROM                 = 29  // { int recvfrom(int s, caddr_t buf, size_t len, int flags, struct sockaddr * __restrict from, __socklen_t * __restrict fromlenaddr); }
+	SYS_ACCEPT                   = 30  // { int accept(int s, struct sockaddr * __restrict name, __socklen_t * __restrict anamelen); }
+	SYS_GETPEERNAME              = 31  // { int getpeername(int fdes, struct sockaddr * __restrict asa, __socklen_t * __restrict alen); }
+	SYS_GETSOCKNAME              = 32  // { int getsockname(int fdes, struct sockaddr * __restrict asa, __socklen_t * __restrict alen); }
+	SYS_ACCESS                   = 33  // { int access(char *path, int amode); }
+	SYS_CHFLAGS                  = 34  // { int chflags(const char *path, u_long flags); }
+	SYS_FCHFLAGS                 = 35  // { int fchflags(int fd, u_long flags); }
+	SYS_SYNC                     = 36  // { int sync(void); }
+	SYS_KILL                     = 37  // { int kill(int pid, int signum); }
+	SYS_GETPPID                  = 39  // { pid_t getppid(void); }
+	SYS_DUP                      = 41  // { int dup(u_int fd); }
+	SYS_PIPE                     = 42  // { int pipe(void); }
+	SYS_GETEGID                  = 43  // { gid_t getegid(void); }
+	SYS_PROFIL                   = 44  // { int profil(caddr_t samples, size_t size, size_t offset, u_int scale); }
+	SYS_KTRACE                   = 45  // { int ktrace(const char *fname, int ops, int facs, int pid); }
+	SYS_GETGID                   = 47  // { gid_t getgid(void); }
+	SYS_GETLOGIN                 = 49  // { int getlogin(char *namebuf, u_int namelen); }
+	SYS_SETLOGIN                 = 50  // { int setlogin(char *namebuf); }
+	SYS_ACCT                     = 51  // { int acct(char *path); }
+	SYS_SIGALTSTACK              = 53  // { int sigaltstack(stack_t *ss, stack_t *oss); }
+	SYS_IOCTL                    = 54  // { int ioctl(int fd, u_long com, caddr_t data); }
+	SYS_REBOOT                   = 55  // { int reboot(int opt); }
+	SYS_REVOKE                   = 56  // { int revoke(char *path); }
+	SYS_SYMLINK                  = 57  // { int symlink(char *path, char *link); }
+	SYS_READLINK                 = 58  // { ssize_t readlink(char *path, char *buf, size_t count); }
+	SYS_EXECVE                   = 59  // { int execve(char *fname, char **argv, char **envv); }
+	SYS_UMASK                    = 60  // { int umask(int newmask); } umask umask_args int
+	SYS_CHROOT                   = 61  // { int chroot(char *path); }
+	SYS_MSYNC                    = 65  // { int msync(void *addr, size_t len, int flags); }
+	SYS_VFORK                    = 66  // { int vfork(void); }
+	SYS_SBRK                     = 69  // { int sbrk(int incr); }
+	SYS_SSTK                     = 70  // { int sstk(int incr); }
+	SYS_OVADVISE                 = 72  // { int ovadvise(int anom); } vadvise ovadvise_args int
+	SYS_MUNMAP                   = 73  // { int munmap(void *addr, size_t len); }
+	SYS_MPROTECT                 = 74  // { int mprotect(const void *addr, size_t len, int prot); }
+	SYS_MADVISE                  = 75  // { int madvise(void *addr, size_t len, int behav); }
+	SYS_MINCORE                  = 78  // { int mincore(const void *addr, size_t len, char *vec); }
+	SYS_GETGROUPS                = 79  // { int getgroups(u_int gidsetsize, gid_t *gidset); }
+	SYS_SETGROUPS                = 80  // { int setgroups(u_int gidsetsize, gid_t *gidset); }
+	SYS_GETPGRP                  = 81  // { int getpgrp(void); }
+	SYS_SETPGID                  = 82  // { int setpgid(int pid, int pgid); }
+	SYS_SETITIMER                = 83  // { int setitimer(u_int which, struct itimerval *itv, struct itimerval *oitv); }
+	SYS_SWAPON                   = 85  // { int swapon(char *name); }
+	SYS_GETITIMER                = 86  // { int getitimer(u_int which, struct itimerval *itv); }
+	SYS_GETDTABLESIZE            = 89  // { int getdtablesize(void); }
+	SYS_DUP2                     = 90  // { int dup2(u_int from, u_int to); }
+	SYS_FCNTL                    = 92  // { int fcntl(int fd, int cmd, long arg); }
+	SYS_SELECT                   = 93  // { int select(int nd, fd_set *in, fd_set *ou, fd_set *ex, struct timeval *tv); }
+	SYS_FSYNC                    = 95  // { int fsync(int fd); }
+	SYS_SETPRIORITY              = 96  // { int setpriority(int which, int who, int prio); }
+	SYS_SOCKET                   = 97  // { int socket(int domain, int type, int protocol); }
+	SYS_CONNECT                  = 98  // { int connect(int s, caddr_t name, int namelen); }
+	SYS_GETPRIORITY              = 100 // { int getpriority(int which, int who); }
+	SYS_BIND                     = 104 // { int bind(int s, caddr_t name, int namelen); }
+	SYS_SETSOCKOPT               = 105 // { int setsockopt(int s, int level, int name, caddr_t val, int valsize); }
+	SYS_LISTEN                   = 106 // { int listen(int s, int backlog); }
+	SYS_GETTIMEOFDAY             = 116 // { int gettimeofday(struct timeval *tp, struct timezone *tzp); }
+	SYS_GETRUSAGE                = 117 // { int getrusage(int who, struct rusage *rusage); }
+	SYS_GETSOCKOPT               = 118 // { int getsockopt(int s, int level, int name, caddr_t val, int *avalsize); }
+	SYS_READV                    = 120 // { int readv(int fd, struct iovec *iovp, u_int iovcnt); }
+	SYS_WRITEV                   = 121 // { int writev(int fd, struct iovec *iovp, u_int iovcnt); }
+	SYS_SETTIMEOFDAY             = 122 // { int settimeofday(struct timeval *tv, struct timezone *tzp); }
+	SYS_FCHOWN                   = 123 // { int fchown(int fd, int uid, int gid); }
+	SYS_FCHMOD                   = 124 // { int fchmod(int fd, int mode); }
+	SYS_SETREUID                 = 126 // { int setreuid(int ruid, int euid); }
+	SYS_SETREGID                 = 127 // { int setregid(int rgid, int egid); }
+	SYS_RENAME                   = 128 // { int rename(char *from, char *to); }
+	SYS_FLOCK                    = 131 // { int flock(int fd, int how); }
+	SYS_MKFIFO                   = 132 // { int mkfifo(char *path, int mode); }
+	SYS_SENDTO                   = 133 // { int sendto(int s, caddr_t buf, size_t len, int flags, caddr_t to, int tolen); }
+	SYS_SHUTDOWN                 = 134 // { int shutdown(int s, int how); }
+	SYS_SOCKETPAIR               = 135 // { int socketpair(int domain, int type, int protocol, int *rsv); }
+	SYS_MKDIR                    = 136 // { int mkdir(char *path, int mode); }
+	SYS_RMDIR                    = 137 // { int rmdir(char *path); }
+	SYS_UTIMES                   = 138 // { int utimes(char *path, struct timeval *tptr); }
+	SYS_ADJTIME                  = 140 // { int adjtime(struct timeval *delta, struct timeval *olddelta); }
+	SYS_SETSID                   = 147 // { int setsid(void); }
+	SYS_QUOTACTL                 = 148 // { int quotactl(char *path, int cmd, int uid, caddr_t arg); }
+	SYS_NLM_SYSCALL              = 154 // { int nlm_syscall(int debug_level, int grace_period, int addr_count, char **addrs); }
+	SYS_NFSSVC                   = 155 // { int nfssvc(int flag, caddr_t argp); }
+	SYS_LGETFH                   = 160 // { int lgetfh(char *fname, struct fhandle *fhp); }
+	SYS_GETFH                    = 161 // { int getfh(char *fname, struct fhandle *fhp); }
+	SYS_SYSARCH                  = 165 // { int sysarch(int op, char *parms); }
+	SYS_RTPRIO                   = 166 // { int rtprio(int function, pid_t pid, struct rtprio *rtp); }
+	SYS_SEMSYS                   = 169 // { int semsys(int which, int a2, int a3, int a4, int a5); }
+	SYS_MSGSYS                   = 170 // { int msgsys(int which, int a2, int a3, int a4, int a5, int a6); }
+	SYS_SHMSYS                   = 171 // { int shmsys(int which, int a2, int a3, int a4); }
+	SYS_SETFIB                   = 175 // { int setfib(int fibnum); }
+	SYS_NTP_ADJTIME              = 176 // { int ntp_adjtime(struct timex *tp); }
+	SYS_SETGID                   = 181 // { int setgid(gid_t gid); }
+	SYS_SETEGID                  = 182 // { int setegid(gid_t egid); }
+	SYS_SETEUID                  = 183 // { int seteuid(uid_t euid); }
+	SYS_PATHCONF                 = 191 // { int pathconf(char *path, int name); }
+	SYS_FPATHCONF                = 192 // { int fpathconf(int fd, int name); }
+	SYS_GETRLIMIT                = 194 // { int getrlimit(u_int which, struct rlimit *rlp); } getrlimit __getrlimit_args int
+	SYS_SETRLIMIT                = 195 // { int setrlimit(u_int which, struct rlimit *rlp); } setrlimit __setrlimit_args int
+	SYS___SYSCTL                 = 202 // { int __sysctl(int *name, u_int namelen, void *old, size_t *oldlenp, void *new, size_t newlen); } __sysctl sysctl_args int
+	SYS_MLOCK                    = 203 // { int mlock(const void *addr, size_t len); }
+	SYS_MUNLOCK                  = 204 // { int munlock(const void *addr, size_t len); }
+	SYS_UNDELETE                 = 205 // { int undelete(char *path); }
+	SYS_FUTIMES                  = 206 // { int futimes(int fd, struct timeval *tptr); }
+	SYS_GETPGID                  = 207 // { int getpgid(pid_t pid); }
+	SYS_POLL                     = 209 // { int poll(struct pollfd *fds, u_int nfds, int timeout); }
+	SYS_SEMGET                   = 221 // { int semget(key_t key, int nsems, int semflg); }
+	SYS_SEMOP                    = 222 // { int semop(int semid, struct sembuf *sops, size_t nsops); }
+	SYS_MSGGET                   = 225 // { int msgget(key_t key, int msgflg); }
+	SYS_MSGSND                   = 226 // { int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); }
+	SYS_MSGRCV                   = 227 // { int msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg); }
+	SYS_SHMAT                    = 228 // { int shmat(int shmid, const void *shmaddr, int shmflg); }
+	SYS_SHMDT                    = 230 // { int shmdt(const void *shmaddr); }
+	SYS_SHMGET                   = 231 // { int shmget(key_t key, size_t size, int shmflg); }
+	SYS_CLOCK_GETTIME            = 232 // { int clock_gettime(clockid_t clock_id, struct timespec *tp); }
+	SYS_CLOCK_SETTIME            = 233 // { int clock_settime( clockid_t clock_id, const struct timespec *tp); }
+	SYS_CLOCK_GETRES             = 234 // { int clock_getres(clockid_t clock_id, struct timespec *tp); }
+	SYS_KTIMER_CREATE            = 235 // { int ktimer_create(clockid_t clock_id, struct sigevent *evp, int *timerid); }
+	SYS_KTIMER_DELETE            = 236 // { int ktimer_delete(int timerid); }
+	SYS_KTIMER_SETTIME           = 237 // { int ktimer_settime(int timerid, int flags, const struct itimerspec *value, struct itimerspec *ovalue); }
+	SYS_KTIMER_GETTIME           = 238 // { int ktimer_gettime(int timerid, struct itimerspec *value); }
+	SYS_KTIMER_GETOVERRUN        = 239 // { int ktimer_getoverrun(int timerid); }
+	SYS_NANOSLEEP                = 240 // { int nanosleep(const struct timespec *rqtp, struct timespec *rmtp); }
+	SYS_FFCLOCK_GETCOUNTER       = 241 // { int ffclock_getcounter(ffcounter *ffcount); }
+	SYS_FFCLOCK_SETESTIMATE      = 242 // { int ffclock_setestimate( struct ffclock_estimate *cest); }
+	SYS_FFCLOCK_GETESTIMATE      = 243 // { int ffclock_getestimate( struct ffclock_estimate *cest); }
+	SYS_CLOCK_NANOSLEEP          = 244 // { int clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *rqtp, struct timespec *rmtp); }
+	SYS_CLOCK_GETCPUCLOCKID2     = 247 // { int clock_getcpuclockid2(id_t id,int which, clockid_t *clock_id); }
+	SYS_NTP_GETTIME              = 248 // { int ntp_gettime(struct ntptimeval *ntvp); }
+	SYS_MINHERIT                 = 250 // { int minherit(void *addr, size_t len, int inherit); }
+	SYS_RFORK                    = 251 // { int rfork(int flags); }
+	SYS_OPENBSD_POLL             = 252 // { int openbsd_poll(struct pollfd *fds, u_int nfds, int timeout); }
+	SYS_ISSETUGID                = 253 // { int issetugid(void); }
+	SYS_LCHOWN                   = 254 // { int lchown(char *path, int uid, int gid); }
+	SYS_AIO_READ                 = 255 // { int aio_read(struct aiocb *aiocbp); }
+	SYS_AIO_WRITE                = 256 // { int aio_write(struct aiocb *aiocbp); }
+	SYS_LIO_LISTIO               = 257 // { int lio_listio(int mode, struct aiocb * const *acb_list, int nent, struct sigevent *sig); }
+	SYS_GETDENTS                 = 272 // { int getdents(int fd, char *buf, size_t count); }
+	SYS_LCHMOD                   = 274 // { int lchmod(char *path, mode_t mode); }
+	SYS_LUTIMES                  = 276 // { int lutimes(char *path, struct timeval *tptr); }
+	SYS_NSTAT                    = 278 // { int nstat(char *path, struct nstat *ub); }
+	SYS_NFSTAT                   = 279 // { int nfstat(int fd, struct nstat *sb); }
+	SYS_NLSTAT                   = 280 // { int nlstat(char *path, struct nstat *ub); }
+	SYS_PREADV                   = 289 // { ssize_t preadv(int fd, struct iovec *iovp, u_int iovcnt, off_t offset); }
+	SYS_PWRITEV                  = 290 // { ssize_t pwritev(int fd, struct iovec *iovp, u_int iovcnt, off_t offset); }
+	SYS_FHOPEN                   = 298 // { int fhopen(const struct fhandle *u_fhp, int flags); }
+	SYS_FHSTAT                   = 299 // { int fhstat(const struct fhandle *u_fhp, struct stat *sb); }
+	SYS_MODNEXT                  = 300 // { int modnext(int modid); }
+	SYS_MODSTAT                  = 301 // { int modstat(int modid, struct module_stat *stat); }
+	SYS_MODFNEXT                 = 302 // { int modfnext(int modid); }
+	SYS_MODFIND                  = 303 // { int modfind(const char *name); }
+	SYS_KLDLOAD                  = 304 // { int kldload(const char *file); }
+	SYS_KLDUNLOAD                = 305 // { int kldunload(int fileid); }
+	SYS_KLDFIND                  = 306 // { int kldfind(const char *file); }
+	SYS_KLDNEXT                  = 307 // { int kldnext(int fileid); }
+	SYS_KLDSTAT                  = 308 // { int kldstat(int fileid, struct kld_file_stat* stat); }
+	SYS_KLDFIRSTMOD              = 309 // { int kldfirstmod(int fileid); }
+	SYS_GETSID                   = 310 // { int getsid(pid_t pid); }
+	SYS_SETRESUID                = 311 // { int setresuid(uid_t ruid, uid_t euid, uid_t suid); }
+	SYS_SETRESGID                = 312 // { int setresgid(gid_t rgid, gid_t egid, gid_t sgid); }
+	SYS_AIO_RETURN               = 314 // { ssize_t aio_return(struct aiocb *aiocbp); }
+	SYS_AIO_SUSPEND              = 315 // { int aio_suspend( struct aiocb * const * aiocbp, int nent, const struct timespec *timeout); }
+	SYS_AIO_CANCEL               = 316 // { int aio_cancel(int fd, struct aiocb *aiocbp); }
+	SYS_AIO_ERROR                = 317 // { int aio_error(struct aiocb *aiocbp); }
+	SYS_YIELD                    = 321 // { int yield(void); }
+	SYS_MLOCKALL                 = 324 // { int mlockall(int how); }
+	SYS_MUNLOCKALL               = 325 // { int munlockall(void); }
+	SYS___GETCWD                 = 326 // { int __getcwd(char *buf, u_int buflen); }
+	SYS_SCHED_SETPARAM           = 327 // { int sched_setparam (pid_t pid, const struct sched_param *param); }
+	SYS_SCHED_GETPARAM           = 328 // { int sched_getparam (pid_t pid, struct sched_param *param); }
+	SYS_SCHED_SETSCHEDULER       = 329 // { int sched_setscheduler (pid_t pid, int policy, const struct sched_param *param); }
+	SYS_SCHED_GETSCHEDULER       = 330 // { int sched_getscheduler (pid_t pid); }
+	SYS_SCHED_YIELD              = 331 // { int sched_yield (void); }
+	SYS_SCHED_GET_PRIORITY_MAX   = 332 // { int sched_get_priority_max (int policy); }
+	SYS_SCHED_GET_PRIORITY_MIN   = 333 // { int sched_get_priority_min (int policy); }
+	SYS_SCHED_RR_GET_INTERVAL    = 334 // { int sched_rr_get_interval (pid_t pid, struct timespec *interval); }
+	SYS_UTRACE                   = 335 // { int utrace(const void *addr, size_t len); }
+	SYS_KLDSYM                   = 337 // { int kldsym(int fileid, int cmd, void *data); }
+	SYS_JAIL                     = 338 // { int jail(struct jail *jail); }
+	SYS_SIGPROCMASK              = 340 // { int sigprocmask(int how, const sigset_t *set, sigset_t *oset); }
+	SYS_SIGSUSPEND               = 341 // { int sigsuspend(const sigset_t *sigmask); }
+	SYS_SIGPENDING               = 343 // { int sigpending(sigset_t *set); }
+	SYS_SIGTIMEDWAIT             = 345 // { int sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec *timeout); }
+	SYS_SIGWAITINFO              = 346 // { int sigwaitinfo(const sigset_t *set, siginfo_t *info); }
+	SYS___ACL_GET_FILE           = 347 // { int __acl_get_file(const char *path, acl_type_t type, struct acl *aclp); }
+	SYS___ACL_SET_FILE           = 348 // { int __acl_set_file(const char *path, acl_type_t type, struct acl *aclp); }
+	SYS___ACL_GET_FD             = 349 // { int __acl_get_fd(int filedes, acl_type_t type, struct acl *aclp); }
+	SYS___ACL_SET_FD             = 350 // { int __acl_set_fd(int filedes, acl_type_t type, struct acl *aclp); }
+	SYS___ACL_DELETE_FILE        = 351 // { int __acl_delete_file(const char *path, acl_type_t type); }
+	SYS___ACL_DELETE_FD          = 352 // { int __acl_delete_fd(int filedes, acl_type_t type); }
+	SYS___ACL_ACLCHECK_FILE      = 353 // { int __acl_aclcheck_file(const char *path, acl_type_t type, struct acl *aclp); }
+	SYS___ACL_ACLCHECK_FD        = 354 // { int __acl_aclcheck_fd(int filedes, acl_type_t type, struct acl *aclp); }
+	SYS_EXTATTRCTL               = 355 // { int extattrctl(const char *path, int cmd, const char *filename, int attrnamespace, const char *attrname); }
+	SYS_EXTATTR_SET_FILE         = 356 // { ssize_t extattr_set_file( const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
+	SYS_EXTATTR_GET_FILE         = 357 // { ssize_t extattr_get_file( const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
+	SYS_EXTATTR_DELETE_FILE      = 358 // { int extattr_delete_file(const char *path, int attrnamespace, const char *attrname); }
+	SYS_AIO_WAITCOMPLETE         = 359 // { ssize_t aio_waitcomplete( struct aiocb **aiocbp, struct timespec *timeout); }
+	SYS_GETRESUID                = 360 // { int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); }
+	SYS_GETRESGID                = 361 // { int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); }
+	SYS_KQUEUE                   = 362 // { int kqueue(void); }
+	SYS_KEVENT                   = 363 // { int kevent(int fd, struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents, const struct timespec *timeout); }
+	SYS_EXTATTR_SET_FD           = 371 // { ssize_t extattr_set_fd(int fd, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
+	SYS_EXTATTR_GET_FD           = 372 // { ssize_t extattr_get_fd(int fd, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
+	SYS_EXTATTR_DELETE_FD        = 373 // { int extattr_delete_fd(int fd, int attrnamespace, const char *attrname); }
+	SYS___SETUGID                = 374 // { int __setugid(int flag); }
+	SYS_EACCESS                  = 376 // { int eaccess(char *path, int amode); }
+	SYS_NMOUNT                   = 378 // { int nmount(struct iovec *iovp, unsigned int iovcnt, int flags); }
+	SYS___MAC_GET_PROC           = 384 // { int __mac_get_proc(struct mac *mac_p); }
+	SYS___MAC_SET_PROC           = 385 // { int __mac_set_proc(struct mac *mac_p); }
+	SYS___MAC_GET_FD             = 386 // { int __mac_get_fd(int fd, struct mac *mac_p); }
+	SYS___MAC_GET_FILE           = 387 // { int __mac_get_file(const char *path_p, struct mac *mac_p); }
+	SYS___MAC_SET_FD             = 388 // { int __mac_set_fd(int fd, struct mac *mac_p); }
+	SYS___MAC_SET_FILE           = 389 // { int __mac_set_file(const char *path_p, struct mac *mac_p); }
+	SYS_KENV                     = 390 // { int kenv(int what, const char *name, char *value, int len); }
+	SYS_LCHFLAGS                 = 391 // { int lchflags(const char *path, u_long flags); }
+	SYS_UUIDGEN                  = 392 // { int uuidgen(struct uuid *store, int count); }
+	SYS_SENDFILE                 = 393 // { int sendfile(int fd, int s, off_t offset, size_t nbytes, struct sf_hdtr *hdtr, off_t *sbytes, int flags); }
+	SYS_MAC_SYSCALL              = 394 // { int mac_syscall(const char *policy, int call, void *arg); }
+	SYS_FHSTATFS                 = 398 // { int fhstatfs(const struct fhandle *u_fhp, struct statfs *buf); }
+	SYS_KSEM_CLOSE               = 400 // { int ksem_close(semid_t id); }
+	SYS_KSEM_POST                = 401 // { int ksem_post(semid_t id); }
+	SYS_KSEM_WAIT                = 402 // { int ksem_wait(semid_t id); }
+	SYS_KSEM_TRYWAIT             = 403 // { int ksem_trywait(semid_t id); }
+	SYS_KSEM_INIT                = 404 // { int ksem_init(semid_t *idp, unsigned int value); }
+	SYS_KSEM_OPEN                = 405 // { int ksem_open(semid_t *idp, const char *name, int oflag, mode_t mode, unsigned int value); }
+	SYS_KSEM_UNLINK              = 406 // { int ksem_unlink(const char *name); }
+	SYS_KSEM_GETVALUE            = 407 // { int ksem_getvalue(semid_t id, int *val); }
+	SYS_KSEM_DESTROY             = 408 // { int ksem_destroy(semid_t id); }
+	SYS___MAC_GET_PID            = 409 // { int __mac_get_pid(pid_t pid, struct mac *mac_p); }
+	SYS___MAC_GET_LINK           = 410 // { int __mac_get_link(const char *path_p, struct mac *mac_p); }
+	SYS___MAC_SET_LINK           = 411 // { int __mac_set_link(const char *path_p, struct mac *mac_p); }
+	SYS_EXTATTR_SET_LINK         = 412 // { ssize_t extattr_set_link( const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
+	SYS_EXTATTR_GET_LINK         = 413 // { ssize_t extattr_get_link( const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes); }
+	SYS_EXTATTR_DELETE_LINK      = 414 // { int extattr_delete_link( const char *path, int attrnamespace, const char *attrname); }
+	SYS___MAC_EXECVE             = 415 // { int __mac_execve(char *fname, char **argv, char **envv, struct mac *mac_p); }
+	SYS_SIGACTION                = 416 // { int sigaction(int sig, const struct sigaction *act, struct sigaction *oact); }
+	SYS_SIGRETURN                = 417 // { int sigreturn( const struct __ucontext *sigcntxp); }
+	SYS_GETCONTEXT               = 421 // { int getcontext(struct __ucontext *ucp); }
+	SYS_SETCONTEXT               = 422 // { int setcontext( const struct __ucontext *ucp); }
+	SYS_SWAPCONTEXT              = 423 // { int swapcontext(struct __ucontext *oucp, const struct __ucontext *ucp); }
+	SYS_SWAPOFF                  = 424 // { int swapoff(const char *name); }
+	SYS___ACL_GET_LINK           = 425 // { int __acl_get_link(const char *path, acl_type_t type, struct acl *aclp); }
+	SYS___ACL_SET_LINK           = 426 // { int __acl_set_link(const char *path, acl_type_t type, struct acl *aclp); }
+	SYS___ACL_DELETE_LINK        = 427 // { int __acl_delete_link(const char *path, acl_type_t type); }
+	SYS___ACL_ACLCHECK_LINK      = 428 // { int __acl_aclcheck_link(const char *path, acl_type_t type, struct acl *aclp); }
+	SYS_SIGWAIT                  = 429 // { int sigwait(const sigset_t *set, int *sig); }
+	SYS_THR_CREATE               = 430 // { int thr_create(ucontext_t *ctx, long *id, int flags); }
+	SYS_THR_EXIT                 = 431 // { void thr_exit(long *state); }
+	SYS_THR_SELF                 = 432 // { int thr_self(long *id); }
+	SYS_THR_KILL                 = 433 // { int thr_kill(long id, int sig); }
+	SYS_JAIL_ATTACH              = 436 // { int jail_attach(int jid); }
+	SYS_EXTATTR_LIST_FD          = 437 // { ssize_t extattr_list_fd(int fd, int attrnamespace, void *data, size_t nbytes); }
+	SYS_EXTATTR_LIST_FILE        = 438 // { ssize_t extattr_list_file( const char *path, int attrnamespace, void *data, size_t nbytes); }
+	SYS_EXTATTR_LIST_LINK        = 439 // { ssize_t extattr_list_link( const char *path, int attrnamespace, void *data, size_t nbytes); }
+	SYS_KSEM_TIMEDWAIT           = 441 // { int ksem_timedwait(semid_t id, const struct timespec *abstime); }
+	SYS_THR_SUSPEND              = 442 // { int thr_suspend( const struct timespec *timeout); }
+	SYS_THR_WAKE                 = 443 // { int thr_wake(long id); }
+	SYS_KLDUNLOADF               = 444 // { int kldunloadf(int fileid, int flags); }
+	SYS_AUDIT                    = 445 // { int audit(const void *record, u_int length); }
+	SYS_AUDITON                  = 446 // { int auditon(int cmd, void *data, u_int length); }
+	SYS_GETAUID                  = 447 // { int getauid(uid_t *auid); }
+	SYS_SETAUID                  = 448 // { int setauid(uid_t *auid); }
+	SYS_GETAUDIT                 = 449 // { int getaudit(struct auditinfo *auditinfo); }
+	SYS_SETAUDIT                 = 450 // { int setaudit(struct auditinfo *auditinfo); }
+	SYS_GETAUDIT_ADDR            = 451 // { int getaudit_addr( struct auditinfo_addr *auditinfo_addr, u_int length); }
+	SYS_SETAUDIT_ADDR            = 452 // { int setaudit_addr( struct auditinfo_addr *auditinfo_addr, u_int length); }
+	SYS_AUDITCTL                 = 453 // { int auditctl(char *path); }
+	SYS__UMTX_OP                 = 454 // { int _umtx_op(void *obj, int op, u_long val, void *uaddr1, void *uaddr2); }
+	SYS_THR_NEW                  = 455 // { int thr_new(struct thr_param *param, int param_size); }
+	SYS_SIGQUEUE                 = 456 // { int sigqueue(pid_t pid, int signum, void *value); }
+	SYS_KMQ_OPEN                 = 457 // { int kmq_open(const char *path, int flags, mode_t mode, const struct mq_attr *attr); }
+	SYS_KMQ_SETATTR              = 458 // { int kmq_setattr(int mqd,		const struct mq_attr *attr,		struct mq_attr *oattr); }
+	SYS_KMQ_TIMEDRECEIVE         = 459 // { int kmq_timedreceive(int mqd,	char *msg_ptr, size_t msg_len,	unsigned *msg_prio,			const struct timespec *abs_timeout); }
+	SYS_KMQ_TIMEDSEND            = 460 // { int kmq_timedsend(int mqd,		const char *msg_ptr, size_t msg_len,unsigned msg_prio,			const struct timespec *abs_timeout);}
+	SYS_KMQ_NOTIFY               = 461 // { int kmq_notify(int mqd,		const struct sigevent *sigev); }
+	SYS_KMQ_UNLINK               = 462 // { int kmq_unlink(const char *path); }
+	SYS_ABORT2                   = 463 // { int abort2(const char *why, int nargs, void **args); }
+	SYS_THR_SET_NAME             = 464 // { int thr_set_name(long id, const char *name); }
+	SYS_AIO_FSYNC                = 465 // { int aio_fsync(int op, struct aiocb *aiocbp); }
+	SYS_RTPRIO_THREAD            = 466 // { int rtprio_thread(int function, lwpid_t lwpid, struct rtprio *rtp); }
+	SYS_SCTP_PEELOFF             = 471 // { int sctp_peeloff(int sd, uint32_t name); }
+	SYS_SCTP_GENERIC_SENDMSG     = 472 // { int sctp_generic_sendmsg(int sd, caddr_t msg, int mlen, caddr_t to, __socklen_t tolen, struct sctp_sndrcvinfo *sinfo, int flags); }
+	SYS_SCTP_GENERIC_SENDMSG_IOV = 473 // { int sctp_generic_sendmsg_iov(int sd, struct iovec *iov, int iovlen, caddr_t to, __socklen_t tolen, struct sctp_sndrcvinfo *sinfo, int flags); }
+	SYS_SCTP_GENERIC_RECVMSG     = 474 // { int sctp_generic_recvmsg(int sd, struct iovec *iov, int iovlen, struct sockaddr * from, __socklen_t *fromlenaddr, struct sctp_sndrcvinfo *sinfo, int *msg_flags); }
+	SYS_PREAD                    = 475 // { ssize_t pread(int fd, void *buf, size_t nbyte, off_t offset); }
+	SYS_PWRITE                   = 476 // { ssize_t pwrite(int fd, const void *buf, size_t nbyte, off_t offset); }
+	SYS_MMAP                     = 477 // { caddr_t mmap(caddr_t addr, size_t len, int prot, int flags, int fd, off_t pos); }
+	SYS_LSEEK                    = 478 // { off_t lseek(int fd, off_t offset, int whence); }
+	SYS_TRUNCATE                 = 479 // { int truncate(char *path, off_t length); }
+	SYS_FTRUNCATE                = 480 // { int ftruncate(int fd, off_t length); }
+	SYS_THR_KILL2                = 481 // { int thr_kill2(pid_t pid, long id, int sig); }
+	SYS_SHM_OPEN                 = 482 // { int shm_open(const char *path, int flags, mode_t mode); }
+	SYS_SHM_UNLINK               = 483 // { int shm_unlink(const char *path); }
+	SYS_CPUSET                   = 484 // { int cpuset(cpusetid_t *setid); }
+	SYS_CPUSET_SETID             = 485 // { int cpuset_setid(cpuwhich_t which, id_t id, cpusetid_t setid); }
+	SYS_CPUSET_GETID             = 486 // { int cpuset_getid(cpulevel_t level, cpuwhich_t which, id_t id, cpusetid_t *setid); }
+	SYS_CPUSET_GETAFFINITY       = 487 // { int cpuset_getaffinity(cpulevel_t level, cpuwhich_t which, id_t id, size_t cpusetsize, cpuset_t *mask); }
+	SYS_CPUSET_SETAFFINITY       = 488 // { int cpuset_setaffinity(cpulevel_t level, cpuwhich_t which, id_t id, size_t cpusetsize, const cpuset_t *mask); }
+	SYS_FACCESSAT                = 489 // { int faccessat(int fd, char *path, int amode, int flag); }
+	SYS_FCHMODAT                 = 490 // { int fchmodat(int fd, char *path, mode_t mode, int flag); }
+	SYS_FCHOWNAT                 = 491 // { int fchownat(int fd, char *path, uid_t uid, gid_t gid, int flag); }
+	SYS_FEXECVE                  = 492 // { int fexecve(int fd, char **argv, char **envv); }
+	SYS_FUTIMESAT                = 494 // { int futimesat(int fd, char *path, struct timeval *times); }
+	SYS_LINKAT                   = 495 // { int linkat(int fd1, char *path1, int fd2, char *path2, int flag); }
+	SYS_MKDIRAT                  = 496 // { int mkdirat(int fd, char *path, mode_t mode); }
+	SYS_MKFIFOAT                 = 497 // { int mkfifoat(int fd, char *path, mode_t mode); }
+	SYS_OPENAT                   = 499 // { int openat(int fd, char *path, int flag, mode_t mode); }
+	SYS_READLINKAT               = 500 // { int readlinkat(int fd, char *path, char *buf, size_t bufsize); }
+	SYS_RENAMEAT                 = 501 // { int renameat(int oldfd, char *old, int newfd, char *new); }
+	SYS_SYMLINKAT                = 502 // { int symlinkat(char *path1, int fd, char *path2); }
+	SYS_UNLINKAT                 = 503 // { int unlinkat(int fd, char *path, int flag); }
+	SYS_POSIX_OPENPT             = 504 // { int posix_openpt(int flags); }
+	SYS_GSSD_SYSCALL             = 505 // { int gssd_syscall(char *path); }
+	SYS_JAIL_GET                 = 506 // { int jail_get(struct iovec *iovp, unsigned int iovcnt, int flags); }
+	SYS_JAIL_SET                 = 507 // { int jail_set(struct iovec *iovp, unsigned int iovcnt, int flags); }
+	SYS_JAIL_REMOVE              = 508 // { int jail_remove(int jid); }
+	SYS_CLOSEFROM                = 509 // { int closefrom(int lowfd); }
+	SYS___SEMCTL                 = 510 // { int __semctl(int semid, int semnum, int cmd, union semun *arg); }
+	SYS_MSGCTL                   = 511 // { int msgctl(int msqid, int cmd, struct msqid_ds *buf); }
+	SYS_SHMCTL                   = 512 // { int shmctl(int shmid, int cmd, struct shmid_ds *buf); }
+	SYS_LPATHCONF                = 513 // { int lpathconf(char *path, int name); }
+	SYS___CAP_RIGHTS_GET         = 515 // { int __cap_rights_get(int version, int fd, cap_rights_t *rightsp); }
+	SYS_CAP_ENTER                = 516 // { int cap_enter(void); }
+	SYS_CAP_GETMODE              = 517 // { int cap_getmode(u_int *modep); }
+	SYS_PDFORK                   = 518 // { int pdfork(int *fdp, int flags); }
+	SYS_PDKILL                   = 519 // { int pdkill(int fd, int signum); }
+	SYS_PDGETPID                 = 520 // { int pdgetpid(int fd, pid_t *pidp); }
+	SYS_PSELECT                  = 522 // { int pselect(int nd, fd_set *in, fd_set *ou, fd_set *ex, const struct timespec *ts, const sigset_t *sm); }
+	SYS_GETLOGINCLASS            = 523 // { int getloginclass(char *namebuf, size_t namelen); }
+	SYS_SETLOGINCLASS            = 524 // { int setloginclass(const char *namebuf); }
+	SYS_RCTL_GET_RACCT           = 525 // { int rctl_get_racct(const void *inbufp, size_t inbuflen, void *outbufp, size_t outbuflen); }
+	SYS_RCTL_GET_RULES           = 526 // { int rctl_get_rules(const void *inbufp, size_t inbuflen, void *outbufp, size_t outbuflen); }
+	SYS_RCTL_GET_LIMITS          = 527 // { int rctl_get_limits(const void *inbufp, size_t inbuflen, void *outbufp, size_t outbuflen); }
+	SYS_RCTL_ADD_RULE            = 528 // { int rctl_add_rule(const void *inbufp, size_t inbuflen, void *outbufp, size_t outbuflen); }
+	SYS_RCTL_REMOVE_RULE         = 529 // { int rctl_remove_rule(const void *inbufp, size_t inbuflen, void *outbufp, size_t outbuflen); }
+	SYS_POSIX_FALLOCATE          = 530 // { int posix_fallocate(int fd, off_t offset, off_t len); }
+	SYS_POSIX_FADVISE            = 531 // { int posix_fadvise(int fd, off_t offset, off_t len, int advice); }
+	SYS_WAIT6                    = 532 // { int wait6(idtype_t idtype, id_t id, int *status, int options, struct __wrusage *wrusage, siginfo_t *info); }
+	SYS_CAP_RIGHTS_LIMIT         = 533 // { int cap_rights_limit(int fd, cap_rights_t *rightsp); }
+	SYS_CAP_IOCTLS_LIMIT         = 534 // { int cap_ioctls_limit(int fd, const u_long *cmds, size_t ncmds); }
+	SYS_CAP_IOCTLS_GET           = 535 // { ssize_t cap_ioctls_get(int fd, u_long *cmds, size_t maxcmds); }
+	SYS_CAP_FCNTLS_LIMIT         = 536 // { int cap_fcntls_limit(int fd, uint32_t fcntlrights); }
+	SYS_CAP_FCNTLS_GET           = 537 // { int cap_fcntls_get(int fd, uint32_t *fcntlrightsp); }
+	SYS_BINDAT                   = 538 // { int bindat(int fd, int s, caddr_t name, int namelen); }
+	SYS_CONNECTAT                = 539 // { int connectat(int fd, int s, caddr_t name, int namelen); }
+	SYS_CHFLAGSAT                = 540 // { int chflagsat(int fd, const char *path, u_long flags, int atflag); }
+	SYS_ACCEPT4                  = 541 // { int accept4(int s, struct sockaddr * __restrict name, __socklen_t * __restrict anamelen, int flags); }
+	SYS_PIPE2                    = 542 // { int pipe2(int *fildes, int flags); }
+	SYS_AIO_MLOCK                = 543 // { int aio_mlock(struct aiocb *aiocbp); }
+	SYS_PROCCTL                  = 544 // { int procctl(idtype_t idtype, id_t id, int com, void *data); }
+	SYS_PPOLL                    = 545 // { int ppoll(struct pollfd *fds, u_int nfds, const struct timespec *ts, const sigset_t *set); }
+	SYS_FUTIMENS                 = 546 // { int futimens(int fd, struct timespec *times); }
+	SYS_UTIMENSAT                = 547 // { int utimensat(int fd, char *path, struct timespec *times, int flag); }
+	SYS_NUMA_GETAFFINITY         = 548 // { int numa_getaffinity(cpuwhich_t which, id_t id, struct vm_domain_policy_entry *policy); }
+	SYS_NUMA_SETAFFINITY         = 549 // { int numa_setaffinity(cpuwhich_t which, id_t id, const struct vm_domain_policy_entry *policy); }
+	SYS_FDATASYNC                = 550 // { int fdatasync(int fd); }
+	SYS_FSTAT                    = 551 // { int fstat(int fd, _Out_ struct stat *sb); }
+	SYS_FSTATAT                  = 552 // { int fstatat(int fd, _In_z_ char *path, \
+	SYS_GETDIRENTRIES            = 554 // { ssize_t getdirentries(int fd, \
+	SYS_STATFS                   = 555 // { int statfs(_In_z_ char *path, \
+	SYS_FSTATFS                  = 556 // { int fstatfs(int fd, \
+	SYS_GETFSSTAT                = 557 // { int getfsstat( \
+	SYS_MKNODAT                  = 559 // { int mknodat(int fd, _In_z_ char *path, \
+)
diff --git a/src/syscall/ztypes_freebsd_386.go b/src/syscall/ztypes_freebsd_386.go
index e1946de..70ae808 100644
--- a/src/syscall/ztypes_freebsd_386.go
+++ b/src/syscall/ztypes_freebsd_386.go
@@ -106,27 +106,6 @@
 	Spare         [10]uint64
 }
 
-type stat_freebsd11_t struct {
-	Dev           uint32
-	Ino           uint32
-	Mode          uint16
-	Nlink         uint16
-	Uid           uint32
-	Gid           uint32
-	Rdev          uint32
-	Atimespec     Timespec
-	Mtimespec     Timespec
-	Ctimespec     Timespec
-	Size          int64
-	Blocks        int64
-	Blksize       int32
-	Flags         uint32
-	Gen           uint32
-	Lspare        int32
-	Birthtimespec Timespec
-	Pad_cgo_0     [8]byte
-}
-
 type Statfs_t struct {
 	Version     uint32
 	Type        uint32
@@ -152,31 +131,6 @@
 	Mntonname   [1024]int8
 }
 
-type statfs_freebsd11_t struct {
-	Version     uint32
-	Type        uint32
-	Flags       uint64
-	Bsize       uint64
-	Iosize      uint64
-	Blocks      uint64
-	Bfree       uint64
-	Bavail      int64
-	Files       uint64
-	Ffree       int64
-	Syncwrites  uint64
-	Asyncwrites uint64
-	Syncreads   uint64
-	Asyncreads  uint64
-	Spare       [10]uint64
-	Namemax     uint32
-	Owner       uint32
-	Fsid        Fsid
-	Charspare   [80]int8
-	Fstypename  [16]int8
-	Mntfromname [88]int8
-	Mntonname   [88]int8
-}
-
 type Flock_t struct {
 	Start  int64
 	Len    int64
@@ -197,14 +151,6 @@
 	Name   [256]int8
 }
 
-type dirent_freebsd11 struct {
-	Fileno uint32
-	Reclen uint16
-	Type   uint8
-	Namlen uint8
-	Name   [256]int8
-}
-
 type Fsid struct {
 	Val [2]int32
 }
diff --git a/src/syscall/ztypes_freebsd_amd64.go b/src/syscall/ztypes_freebsd_amd64.go
index a718345..050432a 100644
--- a/src/syscall/ztypes_freebsd_amd64.go
+++ b/src/syscall/ztypes_freebsd_amd64.go
@@ -102,26 +102,6 @@
 	Spare         [10]uint64
 }
 
-type stat_freebsd11_t struct {
-	Dev           uint32
-	Ino           uint32
-	Mode          uint16
-	Nlink         uint16
-	Uid           uint32
-	Gid           uint32
-	Rdev          uint32
-	Atimespec     Timespec
-	Mtimespec     Timespec
-	Ctimespec     Timespec
-	Size          int64
-	Blocks        int64
-	Blksize       int32
-	Flags         uint32
-	Gen           uint32
-	Lspare        int32
-	Birthtimespec Timespec
-}
-
 type Statfs_t struct {
 	Version     uint32
 	Type        uint32
@@ -147,31 +127,6 @@
 	Mntonname   [1024]int8
 }
 
-type statfs_freebsd11_t struct {
-	Version     uint32
-	Type        uint32
-	Flags       uint64
-	Bsize       uint64
-	Iosize      uint64
-	Blocks      uint64
-	Bfree       uint64
-	Bavail      int64
-	Files       uint64
-	Ffree       int64
-	Syncwrites  uint64
-	Asyncwrites uint64
-	Syncreads   uint64
-	Asyncreads  uint64
-	Spare       [10]uint64
-	Namemax     uint32
-	Owner       uint32
-	Fsid        Fsid
-	Charspare   [80]int8
-	Fstypename  [16]int8
-	Mntfromname [88]int8
-	Mntonname   [88]int8
-}
-
 type Flock_t struct {
 	Start     int64
 	Len       int64
@@ -193,14 +148,6 @@
 	Name   [256]int8
 }
 
-type dirent_freebsd11 struct {
-	Fileno uint32
-	Reclen uint16
-	Type   uint8
-	Namlen uint8
-	Name   [256]int8
-}
-
 type Fsid struct {
 	Val [2]int32
 }
diff --git a/src/syscall/ztypes_freebsd_arm.go b/src/syscall/ztypes_freebsd_arm.go
index 9c5a066..ae5ed56 100644
--- a/src/syscall/ztypes_freebsd_arm.go
+++ b/src/syscall/ztypes_freebsd_arm.go
@@ -104,26 +104,6 @@
 	Spare         [10]uint64
 }
 
-type stat_freebsd11_t struct {
-	Dev           uint32
-	Ino           uint32
-	Mode          uint16
-	Nlink         uint16
-	Uid           uint32
-	Gid           uint32
-	Rdev          uint32
-	Atimespec     Timespec
-	Mtimespec     Timespec
-	Ctimespec     Timespec
-	Size          int64
-	Blocks        int64
-	Blksize       int32
-	Flags         uint32
-	Gen           uint32
-	Lspare        int32
-	Birthtimespec Timespec
-}
-
 type Statfs_t struct {
 	Version     uint32
 	Type        uint32
@@ -149,31 +129,6 @@
 	Mntonname   [1024]int8
 }
 
-type statfs_freebsd11_t struct {
-	Version     uint32
-	Type        uint32
-	Flags       uint64
-	Bsize       uint64
-	Iosize      uint64
-	Blocks      uint64
-	Bfree       uint64
-	Bavail      int64
-	Files       uint64
-	Ffree       int64
-	Syncwrites  uint64
-	Asyncwrites uint64
-	Syncreads   uint64
-	Asyncreads  uint64
-	Spare       [10]uint64
-	Namemax     uint32
-	Owner       uint32
-	Fsid        Fsid
-	Charspare   [80]int8
-	Fstypename  [16]int8
-	Mntfromname [88]int8
-	Mntonname   [88]int8
-}
-
 type Flock_t struct {
 	Start     int64
 	Len       int64
@@ -195,14 +150,6 @@
 	Name   [256]int8
 }
 
-type dirent_freebsd11 struct {
-	Fileno uint32
-	Reclen uint16
-	Type   uint8
-	Namlen uint8
-	Name   [256]int8
-}
-
 type Fsid struct {
 	Val [2]int32
 }
diff --git a/src/syscall/ztypes_freebsd_arm64.go b/src/syscall/ztypes_freebsd_arm64.go
index 3ccd9fc..b3ab991 100644
--- a/src/syscall/ztypes_freebsd_arm64.go
+++ b/src/syscall/ztypes_freebsd_arm64.go
@@ -102,26 +102,6 @@
 	Spare         [10]uint64
 }
 
-type stat_freebsd11_t struct {
-	Dev           uint32
-	Ino           uint32
-	Mode          uint16
-	Nlink         uint16
-	Uid           uint32
-	Gid           uint32
-	Rdev          uint32
-	Atimespec     Timespec
-	Mtimespec     Timespec
-	Ctimespec     Timespec
-	Size          int64
-	Blocks        int64
-	Blksize       int32
-	Flags         uint32
-	Gen           uint32
-	Lspare        int32
-	Birthtimespec Timespec
-}
-
 type Statfs_t struct {
 	Version     uint32
 	Type        uint32
@@ -147,31 +127,6 @@
 	Mntonname   [1024]int8
 }
 
-type statfs_freebsd11_t struct {
-	Version     uint32
-	Type        uint32
-	Flags       uint64
-	Bsize       uint64
-	Iosize      uint64
-	Blocks      uint64
-	Bfree       uint64
-	Bavail      int64
-	Files       uint64
-	Ffree       int64
-	Syncwrites  uint64
-	Asyncwrites uint64
-	Syncreads   uint64
-	Asyncreads  uint64
-	Spare       [10]uint64
-	Namemax     uint32
-	Owner       uint32
-	Fsid        Fsid
-	Charspare   [80]int8
-	Fstypename  [16]int8
-	Mntfromname [88]int8
-	Mntonname   [88]int8
-}
-
 type Flock_t struct {
 	Start     int64
 	Len       int64
@@ -193,14 +148,6 @@
 	Name   [256]int8
 }
 
-type dirent_freebsd11 struct {
-	Fileno uint32
-	Reclen uint16
-	Type   uint8
-	Namlen uint8
-	Name   [256]int8
-}
-
 type Fsid struct {
 	Val [2]int32
 }
diff --git a/src/syscall/ztypes_freebsd_riscv64.go b/src/syscall/ztypes_freebsd_riscv64.go
new file mode 100644
index 0000000..2889518
--- /dev/null
+++ b/src/syscall/ztypes_freebsd_riscv64.go
@@ -0,0 +1,519 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs types_freebsd.go | go run mkpost.go
+
+//go:build riscv64 && freebsd
+
+package syscall
+
+const (
+	sizeofPtr      = 0x8
+	sizeofShort    = 0x2
+	sizeofInt      = 0x4
+	sizeofLong     = 0x8
+	sizeofLongLong = 0x8
+)
+
+type (
+	_C_short     int16
+	_C_int       int32
+	_C_long      int64
+	_C_long_long int64
+)
+
+type Timespec struct {
+	Sec  int64
+	Nsec int64
+}
+
+type Timeval struct {
+	Sec  int64
+	Usec int64
+}
+
+type Rusage struct {
+	Utime    Timeval
+	Stime    Timeval
+	Maxrss   int64
+	Ixrss    int64
+	Idrss    int64
+	Isrss    int64
+	Minflt   int64
+	Majflt   int64
+	Nswap    int64
+	Inblock  int64
+	Oublock  int64
+	Msgsnd   int64
+	Msgrcv   int64
+	Nsignals int64
+	Nvcsw    int64
+	Nivcsw   int64
+}
+
+type Rlimit struct {
+	Cur int64
+	Max int64
+}
+
+type _Gid_t uint32
+
+const (
+	S_IFMT   = 0xf000
+	S_IFIFO  = 0x1000
+	S_IFCHR  = 0x2000
+	S_IFDIR  = 0x4000
+	S_IFBLK  = 0x6000
+	S_IFREG  = 0x8000
+	S_IFLNK  = 0xa000
+	S_IFSOCK = 0xc000
+	S_ISUID  = 0x800
+	S_ISGID  = 0x400
+	S_ISVTX  = 0x200
+	S_IRUSR  = 0x100
+	S_IWUSR  = 0x80
+	S_IXUSR  = 0x40
+	S_IRWXG  = 0x38
+	S_IRWXO  = 0x7
+)
+
+const (
+	_statfsVersion = 0x20140518
+	_dirblksiz     = 0x400
+)
+
+type Stat_t struct {
+	Dev           uint64
+	Ino           uint64
+	Nlink         uint64
+	Mode          uint16
+	Padding0      int16
+	Uid           uint32
+	Gid           uint32
+	Padding1      int32
+	Rdev          uint64
+	Atimespec     Timespec
+	Mtimespec     Timespec
+	Ctimespec     Timespec
+	Birthtimespec Timespec
+	Size          int64
+	Blocks        int64
+	Blksize       int32
+	Flags         uint32
+	Gen           uint64
+	Spare         [10]uint64
+}
+
+type Statfs_t struct {
+	Version     uint32
+	Type        uint32
+	Flags       uint64
+	Bsize       uint64
+	Iosize      uint64
+	Blocks      uint64
+	Bfree       uint64
+	Bavail      int64
+	Files       uint64
+	Ffree       int64
+	Syncwrites  uint64
+	Asyncwrites uint64
+	Syncreads   uint64
+	Asyncreads  uint64
+	Spare       [10]uint64
+	Namemax     uint32
+	Owner       uint32
+	Fsid        Fsid
+	Charspare   [80]int8
+	Fstypename  [16]int8
+	Mntfromname [1024]int8
+	Mntonname   [1024]int8
+}
+
+type Flock_t struct {
+	Start     int64
+	Len       int64
+	Pid       int32
+	Type      int16
+	Whence    int16
+	Sysid     int32
+	Pad_cgo_0 [4]byte
+}
+
+type Dirent struct {
+	Fileno uint64
+	Off    int64
+	Reclen uint16
+	Type   uint8
+	Pad0   uint8
+	Namlen uint16
+	Pad1   uint16
+	Name   [256]int8
+}
+
+type Fsid struct {
+	Val [2]int32
+}
+
+const (
+	pathMax = 0x400
+)
+
+type RawSockaddrInet4 struct {
+	Len    uint8
+	Family uint8
+	Port   uint16
+	Addr   [4]byte /* in_addr */
+	Zero   [8]int8
+}
+
+type RawSockaddrInet6 struct {
+	Len      uint8
+	Family   uint8
+	Port     uint16
+	Flowinfo uint32
+	Addr     [16]byte /* in6_addr */
+	Scope_id uint32
+}
+
+type RawSockaddrUnix struct {
+	Len    uint8
+	Family uint8
+	Path   [104]int8
+}
+
+type RawSockaddrDatalink struct {
+	Len    uint8
+	Family uint8
+	Index  uint16
+	Type   uint8
+	Nlen   uint8
+	Alen   uint8
+	Slen   uint8
+	Data   [46]int8
+}
+
+type RawSockaddr struct {
+	Len    uint8
+	Family uint8
+	Data   [14]int8
+}
+
+type RawSockaddrAny struct {
+	Addr RawSockaddr
+	Pad  [92]int8
+}
+
+type _Socklen uint32
+
+type Linger struct {
+	Onoff  int32
+	Linger int32
+}
+
+type Iovec struct {
+	Base *byte
+	Len  uint64
+}
+
+type IPMreq struct {
+	Multiaddr [4]byte /* in_addr */
+	Interface [4]byte /* in_addr */
+}
+
+type IPMreqn struct {
+	Multiaddr [4]byte /* in_addr */
+	Address   [4]byte /* in_addr */
+	Ifindex   int32
+}
+
+type IPv6Mreq struct {
+	Multiaddr [16]byte /* in6_addr */
+	Interface uint32
+}
+
+type Msghdr struct {
+	Name       *byte
+	Namelen    uint32
+	Pad_cgo_0  [4]byte
+	Iov        *Iovec
+	Iovlen     int32
+	Pad_cgo_1  [4]byte
+	Control    *byte
+	Controllen uint32
+	Flags      int32
+}
+
+type Cmsghdr struct {
+	Len   uint32
+	Level int32
+	Type  int32
+}
+
+type Inet6Pktinfo struct {
+	Addr    [16]byte /* in6_addr */
+	Ifindex uint32
+}
+
+type IPv6MTUInfo struct {
+	Addr RawSockaddrInet6
+	Mtu  uint32
+}
+
+type ICMPv6Filter struct {
+	Filt [8]uint32
+}
+
+const (
+	SizeofSockaddrInet4    = 0x10
+	SizeofSockaddrInet6    = 0x1c
+	SizeofSockaddrAny      = 0x6c
+	SizeofSockaddrUnix     = 0x6a
+	SizeofSockaddrDatalink = 0x36
+	SizeofLinger           = 0x8
+	SizeofIPMreq           = 0x8
+	SizeofIPMreqn          = 0xc
+	SizeofIPv6Mreq         = 0x14
+	SizeofMsghdr           = 0x30
+	SizeofCmsghdr          = 0xc
+	SizeofInet6Pktinfo     = 0x14
+	SizeofIPv6MTUInfo      = 0x20
+	SizeofICMPv6Filter     = 0x20
+)
+
+const (
+	PTRACE_TRACEME = 0x0
+	PTRACE_CONT    = 0x7
+	PTRACE_KILL    = 0x8
+)
+
+type Kevent_t struct {
+	Ident  uint64
+	Filter int16
+	Flags  uint16
+	Fflags uint32
+	Data   int64
+	Udata  *byte
+}
+
+type FdSet struct {
+	X__fds_bits [16]uint64
+}
+
+const (
+	sizeofIfMsghdr         = 0xa8
+	SizeofIfMsghdr         = 0xa8
+	sizeofIfData           = 0x98
+	SizeofIfData           = 0x98
+	SizeofIfaMsghdr        = 0x14
+	SizeofIfmaMsghdr       = 0x10
+	SizeofIfAnnounceMsghdr = 0x18
+	SizeofRtMsghdr         = 0x98
+	SizeofRtMetrics        = 0x70
+)
+
+type ifMsghdr struct {
+	Msglen    uint16
+	Version   uint8
+	Type      uint8
+	Addrs     int32
+	Flags     int32
+	Index     uint16
+	Pad_cgo_0 [2]byte
+	Data      ifData
+}
+
+type IfMsghdr struct {
+	Msglen    uint16
+	Version   uint8
+	Type      uint8
+	Addrs     int32
+	Flags     int32
+	Index     uint16
+	Pad_cgo_0 [2]byte
+	Data      IfData
+}
+
+type ifData struct {
+	Type        uint8
+	Physical    uint8
+	Addrlen     uint8
+	Hdrlen      uint8
+	Link_state  uint8
+	Vhid        uint8
+	Baudrate_pf uint8
+	Datalen     uint8
+	Mtu         uint64
+	Metric      uint64
+	Baudrate    uint64
+	Ipackets    uint64
+	Ierrors     uint64
+	Opackets    uint64
+	Oerrors     uint64
+	Collisions  uint64
+	Ibytes      uint64
+	Obytes      uint64
+	Imcasts     uint64
+	Omcasts     uint64
+	Iqdrops     uint64
+	Noproto     uint64
+	Hwassist    uint64
+	Epoch       int64
+	Lastchange  Timeval
+}
+
+type IfData struct {
+	Type        uint8
+	Physical    uint8
+	Addrlen     uint8
+	Hdrlen      uint8
+	Link_state  uint8
+	Spare_char1 uint8
+	Spare_char2 uint8
+	Datalen     uint8
+	Mtu         uint64
+	Metric      uint64
+	Baudrate    uint64
+	Ipackets    uint64
+	Ierrors     uint64
+	Opackets    uint64
+	Oerrors     uint64
+	Collisions  uint64
+	Ibytes      uint64
+	Obytes      uint64
+	Imcasts     uint64
+	Omcasts     uint64
+	Iqdrops     uint64
+	Noproto     uint64
+	Hwassist    uint64
+	Epoch       int64
+	Lastchange  Timeval
+}
+
+type IfaMsghdr struct {
+	Msglen    uint16
+	Version   uint8
+	Type      uint8
+	Addrs     int32
+	Flags     int32
+	Index     uint16
+	Pad_cgo_0 [2]byte
+	Metric    int32
+}
+
+type IfmaMsghdr struct {
+	Msglen    uint16
+	Version   uint8
+	Type      uint8
+	Addrs     int32
+	Flags     int32
+	Index     uint16
+	Pad_cgo_0 [2]byte
+}
+
+type IfAnnounceMsghdr struct {
+	Msglen  uint16
+	Version uint8
+	Type    uint8
+	Index   uint16
+	Name    [16]int8
+	What    uint16
+}
+
+type RtMsghdr struct {
+	Msglen    uint16
+	Version   uint8
+	Type      uint8
+	Index     uint16
+	Pad_cgo_0 [2]byte
+	Flags     int32
+	Addrs     int32
+	Pid       int32
+	Seq       int32
+	Errno     int32
+	Fmask     int32
+	Inits     uint64
+	Rmx       RtMetrics
+}
+
+type RtMetrics struct {
+	Locks    uint64
+	Mtu      uint64
+	Hopcount uint64
+	Expire   uint64
+	Recvpipe uint64
+	Sendpipe uint64
+	Ssthresh uint64
+	Rtt      uint64
+	Rttvar   uint64
+	Pksent   uint64
+	Weight   uint64
+	Filler   [3]uint64
+}
+
+const (
+	SizeofBpfVersion    = 0x4
+	SizeofBpfStat       = 0x8
+	SizeofBpfZbuf       = 0x18
+	SizeofBpfProgram    = 0x10
+	SizeofBpfInsn       = 0x8
+	SizeofBpfHdr        = 0x20
+	SizeofBpfZbufHeader = 0x20
+)
+
+type BpfVersion struct {
+	Major uint16
+	Minor uint16
+}
+
+type BpfStat struct {
+	Recv uint32
+	Drop uint32
+}
+
+type BpfZbuf struct {
+	Bufa   *byte
+	Bufb   *byte
+	Buflen uint64
+}
+
+type BpfProgram struct {
+	Len       uint32
+	Pad_cgo_0 [4]byte
+	Insns     *BpfInsn
+}
+
+type BpfInsn struct {
+	Code uint16
+	Jt   uint8
+	Jf   uint8
+	K    uint32
+}
+
+type BpfHdr struct {
+	Tstamp    Timeval
+	Caplen    uint32
+	Datalen   uint32
+	Hdrlen    uint16
+	Pad_cgo_0 [6]byte
+}
+
+type BpfZbufHeader struct {
+	Kernel_gen uint32
+	Kernel_len uint32
+	User_gen   uint32
+	X_bzh_pad  [5]uint32
+}
+
+const (
+	_AT_FDCWD            = -0x64
+	_AT_SYMLINK_FOLLOW   = 0x400
+	_AT_SYMLINK_NOFOLLOW = 0x200
+)
+
+type Termios struct {
+	Iflag  uint32
+	Oflag  uint32
+	Cflag  uint32
+	Lflag  uint32
+	Cc     [20]uint8
+	Ispeed uint32
+	Ospeed uint32
+}
diff --git a/src/testing/benchmark.go b/src/testing/benchmark.go
index d8ec217..be9b87f 100644
--- a/src/testing/benchmark.go
+++ b/src/testing/benchmark.go
@@ -234,7 +234,7 @@
 	}()
 	<-b.signal
 	if b.failed {
-		fmt.Fprintf(b.w, "--- FAIL: %s\n%s", b.name, b.output)
+		fmt.Fprintf(b.w, "%s--- FAIL: %s\n%s", b.chatty.prefix(), b.name, b.output)
 		return false
 	}
 	// Only print the output if we know we are not going to proceed.
@@ -242,14 +242,14 @@
 	b.mu.RLock()
 	finished := b.finished
 	b.mu.RUnlock()
-	if atomic.LoadInt32(&b.hasSub) != 0 || finished {
+	if b.hasSub.Load() || finished {
 		tag := "BENCH"
 		if b.skipped {
 			tag = "SKIP"
 		}
 		if b.chatty != nil && (len(b.output) > 0 || finished) {
 			b.trimOutput()
-			fmt.Fprintf(b.w, "--- %s: %s\n%s", tag, b.name, b.output)
+			fmt.Fprintf(b.w, "%s--- %s: %s\n%s", b.chatty.prefix(), tag, b.name, b.output)
 		}
 		return false
 	}
@@ -337,6 +337,17 @@
 	b.result = BenchmarkResult{b.N, b.duration, b.bytes, b.netAllocs, b.netBytes, b.extra}
 }
 
+// Elapsed returns the measured elapsed time of the benchmark.
+// The duration reported by Elapsed matches the one measured by
+// StartTimer, StopTimer, and ResetTimer.
+func (b *B) Elapsed() time.Duration {
+	d := b.duration
+	if b.timerOn {
+		d += time.Since(b.start)
+	}
+	return d
+}
+
 // ReportMetric adds "n unit" to the reported benchmark results.
 // If the metric is per-iteration, the caller should divide by b.N,
 // and by convention units should end in "/op".
@@ -525,7 +536,7 @@
 		}
 	}
 	ctx := &benchContext{
-		match:  newMatcher(matchString, *matchBenchmarks, "-test.bench"),
+		match:  newMatcher(matchString, *matchBenchmarks, "-test.bench", *skip),
 		extLen: len(benchmarkName("", maxprocs)),
 	}
 	var bs []InternalBenchmark
@@ -591,7 +602,7 @@
 				// The output could be very long here, but probably isn't.
 				// We print it all, regardless, because we don't want to trim the reason
 				// the benchmark failed.
-				fmt.Fprintf(b.w, "--- FAIL: %s\n%s", benchName, b.output)
+				fmt.Fprintf(b.w, "%s--- FAIL: %s\n%s", b.chatty.prefix(), benchName, b.output)
 				continue
 			}
 			results := r.String()
@@ -606,15 +617,23 @@
 			// benchmarks since the output generation time will skew the results.
 			if len(b.output) > 0 {
 				b.trimOutput()
-				fmt.Fprintf(b.w, "--- BENCH: %s\n%s", benchName, b.output)
+				fmt.Fprintf(b.w, "%s--- BENCH: %s\n%s", b.chatty.prefix(), benchName, b.output)
 			}
 			if p := runtime.GOMAXPROCS(-1); p != procs {
 				fmt.Fprintf(os.Stderr, "testing: %s left GOMAXPROCS set to %d\n", benchName, p)
 			}
+			if b.chatty != nil && b.chatty.json {
+				b.chatty.Updatef("", "=== NAME  %s\n", "")
+			}
 		}
 	}
 }
 
+// If hideStdoutForTesting is true, Run does not print the benchName.
+// This avoids a spurious print during 'go test' on package testing itself,
+// which invokes b.Run in its own tests (see sub_test.go).
+var hideStdoutForTesting = false
+
 // Run benchmarks f as a subbenchmark with the given name. It reports
 // whether there were any failures.
 //
@@ -623,7 +642,7 @@
 func (b *B) Run(name string, f func(b *B)) bool {
 	// Since b has subbenchmarks, we will no longer run it as a benchmark itself.
 	// Release the lock and acquire it on exit to ensure locks stay paired.
-	atomic.StoreInt32(&b.hasSub, 1)
+	b.hasSub.Store(true)
 	benchmarkLock.Unlock()
 	defer benchmarkLock.Lock()
 
@@ -655,7 +674,7 @@
 	if partial {
 		// Partial name match, like -bench=X/Y matching BenchmarkX.
 		// Only process sub-benchmarks, if any.
-		atomic.StoreInt32(&sub.hasSub, 1)
+		sub.hasSub.Store(true)
 	}
 
 	if b.chatty != nil {
@@ -670,7 +689,12 @@
 			}
 		})
 
-		fmt.Println(benchName)
+		if !hideStdoutForTesting {
+			if b.chatty.json {
+				b.chatty.Updatef(benchName, "=== RUN   %s\n", benchName)
+			}
+			fmt.Println(benchName)
+		}
 	}
 
 	if sub.run1() {
@@ -753,6 +777,9 @@
 // goroutine-local state and then iterate until pb.Next returns false.
 // It should not use the StartTimer, StopTimer, or ResetTimer functions,
 // because they have global effect. It should also not call Run.
+//
+// RunParallel reports ns/op values as wall time for the benchmark as a whole,
+// not the sum of wall time or CPU time over each parallel goroutine.
 func (b *B) RunParallel(body func(*PB)) {
 	if b.N == 0 {
 		return // Nothing to do when probing.
diff --git a/src/testing/benchmark_test.go b/src/testing/benchmark_test.go
index 3b1dc82..2987170 100644
--- a/src/testing/benchmark_test.go
+++ b/src/testing/benchmark_test.go
@@ -176,5 +176,38 @@
 		// This metric is per-operation, so divide by b.N and
 		// report it as a "/op" unit.
 		b.ReportMetric(float64(compares)/float64(b.N), "compares/op")
+		// This metric is per-time, so divide by b.Elapsed and
+		// report it as a "/ns" unit.
+		b.ReportMetric(float64(compares)/float64(b.Elapsed().Nanoseconds()), "compares/ns")
+	})
+}
+
+func ExampleB_ReportMetric_parallel() {
+	// This reports a custom benchmark metric relevant to a
+	// specific algorithm (in this case, sorting) in parallel.
+	testing.Benchmark(func(b *testing.B) {
+		var compares atomic.Int64
+		b.RunParallel(func(pb *testing.PB) {
+			for pb.Next() {
+				s := []int{5, 4, 3, 2, 1}
+				sort.Slice(s, func(i, j int) bool {
+					// Because RunParallel runs the function many
+					// times in parallel, we must increment the
+					// counter atomically to avoid racing writes.
+					compares.Add(1)
+					return s[i] < s[j]
+				})
+			}
+		})
+
+		// NOTE: Report each metric once, after all of the parallel
+		// calls have completed.
+
+		// This metric is per-operation, so divide by b.N and
+		// report it as a "/op" unit.
+		b.ReportMetric(float64(compares.Load())/float64(b.N), "compares/op")
+		// This metric is per-time, so divide by b.Elapsed and
+		// report it as a "/ns" unit.
+		b.ReportMetric(float64(compares.Load())/float64(b.Elapsed().Nanoseconds()), "compares/ns")
 	})
 }
diff --git a/src/testing/cover.go b/src/testing/cover.go
index 62ee5ac..b52e53a 100644
--- a/src/testing/cover.go
+++ b/src/testing/cover.go
@@ -8,6 +8,7 @@
 
 import (
 	"fmt"
+	"internal/goexperiment"
 	"os"
 	"sync/atomic"
 )
@@ -78,6 +79,10 @@
 
 // coverReport reports the coverage percentage and writes a coverage profile if requested.
 func coverReport() {
+	if goexperiment.CoverageRedesign {
+		coverReport2()
+		return
+	}
 	var f *os.File
 	var err error
 	if *coverProfile != "" {
diff --git a/src/testing/example.go b/src/testing/example.go
index f33e8d2..f618b06 100644
--- a/src/testing/example.go
+++ b/src/testing/example.go
@@ -80,10 +80,14 @@
 		}
 	}
 	if fail != "" || !finished || recovered != nil {
-		fmt.Printf("--- FAIL: %s (%s)\n%s", eg.Name, dstr, fail)
+		fmt.Printf("%s--- FAIL: %s (%s)\n%s", chatty.prefix(), eg.Name, dstr, fail)
 		passed = false
-	} else if *chatty {
-		fmt.Printf("--- PASS: %s (%s)\n", eg.Name, dstr)
+	} else if chatty.on {
+		fmt.Printf("%s--- PASS: %s (%s)\n", chatty.prefix(), eg.Name, dstr)
+	}
+
+	if chatty.on && chatty.json {
+		fmt.Printf("%s=== NAME   %s\n", chatty.prefix(), "")
 	}
 
 	if recovered != nil {
diff --git a/src/testing/flag_test.go b/src/testing/flag_test.go
new file mode 100644
index 0000000..483ae65
--- /dev/null
+++ b/src/testing/flag_test.go
@@ -0,0 +1,86 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package testing_test
+
+import (
+	"flag"
+	"internal/testenv"
+	"os"
+	"os/exec"
+	"testing"
+)
+
+var testFlagArg = flag.String("test_flag_arg", "", "TestFlag: passing -v option")
+
+const flagTestEnv = "GO_WANT_FLAG_HELPER_PROCESS"
+
+func TestFlag(t *testing.T) {
+	if os.Getenv(flagTestEnv) == "1" {
+		testFlagHelper(t)
+		return
+	}
+
+	testenv.MustHaveExec(t)
+
+	for _, flag := range []string{"", "-test.v", "-test.v=test2json"} {
+		flag := flag
+		t.Run(flag, func(t *testing.T) {
+			t.Parallel()
+			exe, err := os.Executable()
+			if err != nil {
+				exe = os.Args[0]
+			}
+			cmd := exec.Command(exe, "-test.run=TestFlag", "-test_flag_arg="+flag)
+			if flag != "" {
+				cmd.Args = append(cmd.Args, flag)
+			}
+			cmd.Env = append(cmd.Environ(), flagTestEnv+"=1")
+			b, err := cmd.CombinedOutput()
+			if len(b) > 0 {
+				t.Logf("%s", b)
+			}
+			if err != nil {
+				t.Error(err)
+			}
+		})
+	}
+}
+
+// testFlagHelper is called by the TestFlagHelper subprocess.
+func testFlagHelper(t *testing.T) {
+	f := flag.Lookup("test.v")
+	if f == nil {
+		t.Fatal(`flag.Lookup("test.v") failed`)
+	}
+
+	bf, ok := f.Value.(interface{ IsBoolFlag() bool })
+	if !ok {
+		t.Errorf("test.v flag (type %T) does not have IsBoolFlag method", f)
+	} else if !bf.IsBoolFlag() {
+		t.Error("test.v IsBoolFlag() returned false")
+	}
+
+	gf, ok := f.Value.(flag.Getter)
+	if !ok {
+		t.Fatalf("test.v flag (type %T) does not have Get method", f)
+	}
+	v := gf.Get()
+
+	var want any
+	switch *testFlagArg {
+	case "":
+		want = false
+	case "-test.v":
+		want = true
+	case "-test.v=test2json":
+		want = "test2json"
+	default:
+		t.Fatalf("unexpected test_flag_arg %q", *testFlagArg)
+	}
+
+	if v != want {
+		t.Errorf("test.v is %v want %v", v, want)
+	}
+}
diff --git a/src/testing/fuzz.go b/src/testing/fuzz.go
index b9f3a3d..d31a3f8 100644
--- a/src/testing/fuzz.go
+++ b/src/testing/fuzz.go
@@ -5,7 +5,6 @@
 package testing
 
 import (
-	"bytes"
 	"errors"
 	"flag"
 	"fmt"
@@ -14,7 +13,7 @@
 	"path/filepath"
 	"reflect"
 	"runtime"
-	"sync/atomic"
+	"strings"
 	"time"
 )
 
@@ -41,7 +40,7 @@
 
 // fuzzWorkerExitCode is used as an exit code by fuzz worker processes after an
 // internal error. This distinguishes internal errors from uncontrolled panics
-// and other failiures. Keep in sync with internal/fuzz.workerExitCode.
+// and other failures. Keep in sync with internal/fuzz.workerExitCode.
 const fuzzWorkerExitCode = 70
 
 // InternalFuzzTarget is an internal type but exported because it is
@@ -317,7 +316,6 @@
 		}
 		t.w = indenter{&t.common}
 		if t.chatty != nil {
-			// TODO(#48132): adjust this to work with test2json.
 			t.chatty.Updatef(t.name, "=== RUN   %s\n", t.name)
 		}
 		f.common.inFuzzFn, f.inFuzzFn = true, true
@@ -337,6 +335,9 @@
 			fn.Call(args)
 		})
 		<-t.signal
+		if t.chatty != nil && t.chatty.json {
+			t.chatty.Updatef(t.parent.name, "=== NAME  %s\n", t.parent.name)
+		}
 		f.common.inFuzzFn, f.inFuzzFn = false, false
 		return !t.Failed()
 	}
@@ -380,7 +381,7 @@
 			// fuzz worker. This would become very verbose, particularly during
 			// minimization. Return the error instead, and let the caller deal
 			// with the output.
-			var buf bytes.Buffer
+			var buf strings.Builder
 			if ok := run(&buf, e); !ok {
 				return errors.New(buf.String())
 			}
@@ -472,55 +473,74 @@
 	if len(fuzzTests) == 0 || *isFuzzWorker {
 		return ran, ok
 	}
-	m := newMatcher(deps.MatchString, *match, "-test.run")
-	tctx := newTestContext(*parallel, m)
-	tctx.deadline = deadline
+	m := newMatcher(deps.MatchString, *match, "-test.run", *skip)
 	var mFuzz *matcher
 	if *matchFuzz != "" {
-		mFuzz = newMatcher(deps.MatchString, *matchFuzz, "-test.fuzz")
+		mFuzz = newMatcher(deps.MatchString, *matchFuzz, "-test.fuzz", *skip)
 	}
-	fctx := &fuzzContext{deps: deps, mode: seedCorpusOnly}
-	root := common{w: os.Stdout} // gather output in one place
-	if Verbose() {
-		root.chatty = newChattyPrinter(root.w)
-	}
-	for _, ft := range fuzzTests {
-		if shouldFailFast() {
-			break
-		}
-		testName, matched, _ := tctx.match.fullName(nil, ft.Name)
-		if !matched {
-			continue
-		}
-		if mFuzz != nil {
-			if _, fuzzMatched, _ := mFuzz.fullName(nil, ft.Name); fuzzMatched {
-				// If this will be fuzzed, then don't run the seed corpus
-				// right now. That will happen later.
-				continue
+
+	for _, procs := range cpuList {
+		runtime.GOMAXPROCS(procs)
+		for i := uint(0); i < *count; i++ {
+			if shouldFailFast() {
+				break
+			}
+
+			tctx := newTestContext(*parallel, m)
+			tctx.deadline = deadline
+			fctx := &fuzzContext{deps: deps, mode: seedCorpusOnly}
+			root := common{w: os.Stdout} // gather output in one place
+			if Verbose() {
+				root.chatty = newChattyPrinter(root.w)
+			}
+			for _, ft := range fuzzTests {
+				if shouldFailFast() {
+					break
+				}
+				testName, matched, _ := tctx.match.fullName(nil, ft.Name)
+				if !matched {
+					continue
+				}
+				if mFuzz != nil {
+					if _, fuzzMatched, _ := mFuzz.fullName(nil, ft.Name); fuzzMatched {
+						// If this will be fuzzed, then don't run the seed corpus
+						// right now. That will happen later.
+						continue
+					}
+				}
+				f := &F{
+					common: common{
+						signal:  make(chan bool),
+						barrier: make(chan bool),
+						name:    testName,
+						parent:  &root,
+						level:   root.level + 1,
+						chatty:  root.chatty,
+					},
+					testContext: tctx,
+					fuzzContext: fctx,
+				}
+				f.w = indenter{&f.common}
+				if f.chatty != nil {
+					f.chatty.Updatef(f.name, "=== RUN   %s\n", f.name)
+				}
+				go fRunner(f, ft.Fn)
+				<-f.signal
+				if f.chatty != nil && f.chatty.json {
+					f.chatty.Updatef(f.parent.name, "=== NAME  %s\n", f.parent.name)
+				}
+				ok = ok && !f.Failed()
+				ran = ran || f.ran
+			}
+			if !ran {
+				// There were no tests to run on this iteration.
+				// This won't change, so no reason to keep trying.
+				break
 			}
 		}
-		f := &F{
-			common: common{
-				signal:  make(chan bool),
-				barrier: make(chan bool),
-				name:    testName,
-				parent:  &root,
-				level:   root.level + 1,
-				chatty:  root.chatty,
-			},
-			testContext: tctx,
-			fuzzContext: fctx,
-		}
-		f.w = indenter{&f.common}
-		if f.chatty != nil {
-			// TODO(#48132): adjust this to work with test2json.
-			f.chatty.Updatef(f.name, "=== RUN   %s\n", f.name)
-		}
-
-		go fRunner(f, ft.Fn)
-		<-f.signal
 	}
-	return root.ran, !root.Failed()
+
+	return ran, ok
 }
 
 // runFuzzing runs the fuzz test matching the pattern for -fuzz. Only one such
@@ -533,7 +553,7 @@
 	if len(fuzzTests) == 0 || *matchFuzz == "" {
 		return true
 	}
-	m := newMatcher(deps.MatchString, *matchFuzz, "-test.fuzz")
+	m := newMatcher(deps.MatchString, *matchFuzz, "-test.fuzz", *skip)
 	tctx := newTestContext(1, m)
 	tctx.isFuzzing = true
 	fctx := &fuzzContext{
@@ -584,11 +604,13 @@
 	}
 	f.w = indenter{&f.common}
 	if f.chatty != nil {
-		// TODO(#48132): adjust this to work with test2json.
-		f.chatty.Updatef(f.name, "=== FUZZ  %s\n", f.name)
+		f.chatty.Updatef(f.name, "=== RUN   %s\n", f.name)
 	}
 	go fRunner(f, fuzzTest.Fn)
 	<-f.signal
+	if f.chatty != nil {
+		f.chatty.Updatef(f.parent.name, "=== NAME  %s\n", f.parent.name)
+	}
 	return !f.failed
 }
 
@@ -615,7 +637,7 @@
 		// the original panic should still be
 		// clear.
 		if f.Failed() {
-			atomic.AddUint32(&numFailed, 1)
+			numFailed.Add(1)
 		}
 		err := recover()
 		if err == nil {
diff --git a/src/testing/helper_test.go b/src/testing/helper_test.go
index 357a079..6e8986a 100644
--- a/src/testing/helper_test.go
+++ b/src/testing/helper_test.go
@@ -5,14 +5,13 @@
 package testing
 
 import (
-	"bytes"
 	"regexp"
 	"strings"
 )
 
 func TestTBHelper(t *T) {
-	var buf bytes.Buffer
-	ctx := newTestContext(1, newMatcher(regexp.MatchString, "", ""))
+	var buf strings.Builder
+	ctx := newTestContext(1, allMatcher())
 	t1 := &T{
 		common: common{
 			signal: make(chan bool),
@@ -55,8 +54,8 @@
 }
 
 func TestTBHelperParallel(t *T) {
-	var buf bytes.Buffer
-	ctx := newTestContext(1, newMatcher(regexp.MatchString, "", ""))
+	var buf strings.Builder
+	ctx := newTestContext(1, newMatcher(regexp.MatchString, "", "", ""))
 	t1 := &T{
 		common: common{
 			signal: make(chan bool),
@@ -82,7 +81,7 @@
 
 func BenchmarkTBHelper(b *B) {
 	w := noopWriter(0)
-	ctx := newTestContext(1, newMatcher(regexp.MatchString, "", ""))
+	ctx := newTestContext(1, allMatcher())
 	t1 := &T{
 		common: common{
 			signal: make(chan bool),
diff --git a/src/testing/iotest/logger_test.go b/src/testing/iotest/logger_test.go
index fec4467..7a7d0aa 100644
--- a/src/testing/iotest/logger_test.go
+++ b/src/testing/iotest/logger_test.go
@@ -9,6 +9,7 @@
 	"errors"
 	"fmt"
 	"log"
+	"strings"
 	"testing"
 )
 
@@ -32,12 +33,12 @@
 		log.SetOutput(olw)
 	}()
 
-	lOut := new(bytes.Buffer)
+	lOut := new(strings.Builder)
 	log.SetPrefix("lw: ")
 	log.SetOutput(lOut)
 	log.SetFlags(0)
 
-	lw := new(bytes.Buffer)
+	lw := new(strings.Builder)
 	wl := NewWriteLogger("write:", lw)
 	if _, err := wl.Write([]byte("Hello, World!")); err != nil {
 		t.Fatalf("Unexpectedly failed to write: %v", err)
@@ -64,7 +65,7 @@
 		log.SetOutput(olw)
 	}()
 
-	lOut := new(bytes.Buffer)
+	lOut := new(strings.Builder)
 	log.SetPrefix("lw: ")
 	log.SetOutput(lOut)
 	log.SetFlags(0)
@@ -93,7 +94,7 @@
 		log.SetOutput(olw)
 	}()
 
-	lOut := new(bytes.Buffer)
+	lOut := new(strings.Builder)
 	log.SetPrefix("lr: ")
 	log.SetOutput(lOut)
 	log.SetFlags(0)
@@ -130,7 +131,7 @@
 		log.SetOutput(olw)
 	}()
 
-	lOut := new(bytes.Buffer)
+	lOut := new(strings.Builder)
 	log.SetPrefix("lr: ")
 	log.SetOutput(lOut)
 	log.SetFlags(0)
diff --git a/src/testing/iotest/reader_test.go b/src/testing/iotest/reader_test.go
index f149e74..1d22237 100644
--- a/src/testing/iotest/reader_test.go
+++ b/src/testing/iotest/reader_test.go
@@ -26,7 +26,7 @@
 
 	b = make([]byte, 3)
 	// Read from obr until EOF.
-	got := new(bytes.Buffer)
+	got := new(strings.Builder)
 	for i := 0; ; i++ {
 		n, err = obr.Read(b)
 		if err != nil {
@@ -77,7 +77,7 @@
 	}
 	// non empty read buffer
 	b = make([]byte, 2)
-	got := new(bytes.Buffer)
+	got := new(strings.Builder)
 	for i := 0; ; i++ {
 		n, err = hr.Read(b)
 		if err != nil {
@@ -190,7 +190,7 @@
 	der := DataErrReader(buf)
 
 	b := make([]byte, 3)
-	got := new(bytes.Buffer)
+	got := new(strings.Builder)
 	var n int
 	var err error
 	for {
diff --git a/src/testing/iotest/writer_test.go b/src/testing/iotest/writer_test.go
index 5aaa77c..2762513 100644
--- a/src/testing/iotest/writer_test.go
+++ b/src/testing/iotest/writer_test.go
@@ -5,7 +5,7 @@
 package iotest
 
 import (
-	"bytes"
+	"strings"
 	"testing"
 )
 
@@ -23,7 +23,7 @@
 
 func TestTruncateWriter(t *testing.T) {
 	for _, tt := range truncateWriterTests {
-		buf := new(bytes.Buffer)
+		buf := new(strings.Builder)
 		tw := TruncateWriter(buf, tt.trunc)
 		n, err := tw.Write([]byte(tt.in))
 		if err != nil {
diff --git a/src/testing/match.go b/src/testing/match.go
index d530f70..92b7dc6 100644
--- a/src/testing/match.go
+++ b/src/testing/match.go
@@ -15,6 +15,7 @@
 // matcher sanitizes, uniques, and filters names of subtests and subbenchmarks.
 type matcher struct {
 	filter    filterMatch
+	skip      filterMatch
 	matchFunc func(pat, str string) (bool, error)
 
 	mu sync.Mutex
@@ -47,17 +48,33 @@
 // eliminate this Mutex.
 var matchMutex sync.Mutex
 
-func newMatcher(matchString func(pat, str string) (bool, error), patterns, name string) *matcher {
-	var impl filterMatch
-	if patterns != "" {
-		impl = splitRegexp(patterns)
-		if err := impl.verify(name, matchString); err != nil {
+func allMatcher() *matcher {
+	return newMatcher(nil, "", "", "")
+}
+
+func newMatcher(matchString func(pat, str string) (bool, error), patterns, name, skips string) *matcher {
+	var filter, skip filterMatch
+	if patterns == "" {
+		filter = simpleMatch{} // always partial true
+	} else {
+		filter = splitRegexp(patterns)
+		if err := filter.verify(name, matchString); err != nil {
 			fmt.Fprintf(os.Stderr, "testing: invalid regexp for %s\n", err)
 			os.Exit(1)
 		}
 	}
+	if skips == "" {
+		skip = alternationMatch{} // always false
+	} else {
+		skip = splitRegexp(skips)
+		if err := skip.verify("-test.skip", matchString); err != nil {
+			fmt.Fprintf(os.Stderr, "testing: invalid regexp for %v\n", err)
+			os.Exit(1)
+		}
+	}
 	return &matcher{
-		filter:    impl,
+		filter:    filter,
+		skip:      skip,
 		matchFunc: matchString,
 		subNames:  map[string]int32{},
 	}
@@ -76,14 +93,23 @@
 	matchMutex.Lock()
 	defer matchMutex.Unlock()
 
-	if m.filter == nil {
-		return name, true, false
+	// We check the full array of paths each time to allow for the case that a pattern contains a '/'.
+	elem := strings.Split(name, "/")
+
+	// filter must match.
+	// accept partial match that may produce full match later.
+	ok, partial = m.filter.matches(elem, m.matchFunc)
+	if !ok {
+		return name, false, false
 	}
 
-	// We check the full array of paths each time to allow for the case that
-	// a pattern contains a '/'.
-	elem := strings.Split(name, "/")
-	ok, partial = m.filter.matches(elem, m.matchFunc)
+	// skip must not match.
+	// ignore partial match so we can get to more precise match later.
+	skip, partialSkip := m.skip.matches(elem, m.matchFunc)
+	if skip && !partialSkip {
+		return name, false, false
+	}
+
 	return name, ok, partial
 }
 
diff --git a/src/testing/match_test.go b/src/testing/match_test.go
index 206ac0b..d31efbc 100644
--- a/src/testing/match_test.go
+++ b/src/testing/match_test.go
@@ -12,6 +12,10 @@
 	"unicode"
 )
 
+func init() {
+	testingTesting = true
+}
+
 // Verify that our IsSpace agrees with unicode.IsSpace.
 func TestIsSpace(t *T) {
 	n := 0
@@ -89,54 +93,75 @@
 func TestMatcher(t *T) {
 	testCases := []struct {
 		pattern     string
+		skip        string
 		parent, sub string
 		ok          bool
 		partial     bool
 	}{
 		// Behavior without subtests.
-		{"", "", "TestFoo", true, false},
-		{"TestFoo", "", "TestFoo", true, false},
-		{"TestFoo/", "", "TestFoo", true, true},
-		{"TestFoo/bar/baz", "", "TestFoo", true, true},
-		{"TestFoo", "", "TestBar", false, false},
-		{"TestFoo/", "", "TestBar", false, false},
-		{"TestFoo/bar/baz", "", "TestBar/bar/baz", false, false},
+		{"", "", "", "TestFoo", true, false},
+		{"TestFoo", "", "", "TestFoo", true, false},
+		{"TestFoo/", "", "", "TestFoo", true, true},
+		{"TestFoo/bar/baz", "", "", "TestFoo", true, true},
+		{"TestFoo", "", "", "TestBar", false, false},
+		{"TestFoo/", "", "", "TestBar", false, false},
+		{"TestFoo/bar/baz", "", "", "TestBar/bar/baz", false, false},
+		{"", "TestBar", "", "TestFoo", true, false},
+		{"", "TestBar", "", "TestBar", false, false},
+
+		// Skipping a non-existent test doesn't change anything.
+		{"", "TestFoo/skipped", "", "TestFoo", true, false},
+		{"TestFoo", "TestFoo/skipped", "", "TestFoo", true, false},
+		{"TestFoo/", "TestFoo/skipped", "", "TestFoo", true, true},
+		{"TestFoo/bar/baz", "TestFoo/skipped", "", "TestFoo", true, true},
+		{"TestFoo", "TestFoo/skipped", "", "TestBar", false, false},
+		{"TestFoo/", "TestFoo/skipped", "", "TestBar", false, false},
+		{"TestFoo/bar/baz", "TestFoo/skipped", "", "TestBar/bar/baz", false, false},
 
 		// with subtests
-		{"", "TestFoo", "x", true, false},
-		{"TestFoo", "TestFoo", "x", true, false},
-		{"TestFoo/", "TestFoo", "x", true, false},
-		{"TestFoo/bar/baz", "TestFoo", "bar", true, true},
+		{"", "", "TestFoo", "x", true, false},
+		{"TestFoo", "", "TestFoo", "x", true, false},
+		{"TestFoo/", "", "TestFoo", "x", true, false},
+		{"TestFoo/bar/baz", "", "TestFoo", "bar", true, true},
+
+		{"", "TestFoo/skipped", "TestFoo", "x", true, false},
+		{"TestFoo", "TestFoo/skipped", "TestFoo", "x", true, false},
+		{"TestFoo", "TestFoo/skipped", "TestFoo", "skipped", false, false},
+		{"TestFoo/", "TestFoo/skipped", "TestFoo", "x", true, false},
+		{"TestFoo/bar/baz", "TestFoo/skipped", "TestFoo", "bar", true, true},
+
 		// Subtest with a '/' in its name still allows for copy and pasted names
 		// to match.
-		{"TestFoo/bar/baz", "TestFoo", "bar/baz", true, false},
-		{"TestFoo/bar/baz", "TestFoo/bar", "baz", true, false},
-		{"TestFoo/bar/baz", "TestFoo", "x", false, false},
-		{"TestFoo", "TestBar", "x", false, false},
-		{"TestFoo/", "TestBar", "x", false, false},
-		{"TestFoo/bar/baz", "TestBar", "x/bar/baz", false, false},
+		{"TestFoo/bar/baz", "", "TestFoo", "bar/baz", true, false},
+		{"TestFoo/bar/baz", "TestFoo/bar/baz", "TestFoo", "bar/baz", false, false},
+		{"TestFoo/bar/baz", "TestFoo/bar/baz/skip", "TestFoo", "bar/baz", true, false},
+		{"TestFoo/bar/baz", "", "TestFoo/bar", "baz", true, false},
+		{"TestFoo/bar/baz", "", "TestFoo", "x", false, false},
+		{"TestFoo", "", "TestBar", "x", false, false},
+		{"TestFoo/", "", "TestBar", "x", false, false},
+		{"TestFoo/bar/baz", "", "TestBar", "x/bar/baz", false, false},
 
-		{"A/B|C/D", "TestA", "B", true, false},
-		{"A/B|C/D", "TestC", "D", true, false},
-		{"A/B|C/D", "TestA", "C", false, false},
+		{"A/B|C/D", "", "TestA", "B", true, false},
+		{"A/B|C/D", "", "TestC", "D", true, false},
+		{"A/B|C/D", "", "TestA", "C", false, false},
 
 		// subtests only
-		{"", "TestFoo", "x", true, false},
-		{"/", "TestFoo", "x", true, false},
-		{"./", "TestFoo", "x", true, false},
-		{"./.", "TestFoo", "x", true, false},
-		{"/bar/baz", "TestFoo", "bar", true, true},
-		{"/bar/baz", "TestFoo", "bar/baz", true, false},
-		{"//baz", "TestFoo", "bar/baz", true, false},
-		{"//", "TestFoo", "bar/baz", true, false},
-		{"/bar/baz", "TestFoo/bar", "baz", true, false},
-		{"//foo", "TestFoo", "bar/baz", false, false},
-		{"/bar/baz", "TestFoo", "x", false, false},
-		{"/bar/baz", "TestBar", "x/bar/baz", false, false},
+		{"", "", "TestFoo", "x", true, false},
+		{"/", "", "TestFoo", "x", true, false},
+		{"./", "", "TestFoo", "x", true, false},
+		{"./.", "", "TestFoo", "x", true, false},
+		{"/bar/baz", "", "TestFoo", "bar", true, true},
+		{"/bar/baz", "", "TestFoo", "bar/baz", true, false},
+		{"//baz", "", "TestFoo", "bar/baz", true, false},
+		{"//", "", "TestFoo", "bar/baz", true, false},
+		{"/bar/baz", "", "TestFoo/bar", "baz", true, false},
+		{"//foo", "", "TestFoo", "bar/baz", false, false},
+		{"/bar/baz", "", "TestFoo", "x", false, false},
+		{"/bar/baz", "", "TestBar", "x/bar/baz", false, false},
 	}
 
 	for _, tc := range testCases {
-		m := newMatcher(regexp.MatchString, tc.pattern, "-test.run")
+		m := newMatcher(regexp.MatchString, tc.pattern, "-test.run", tc.skip)
 
 		parent := &common{name: tc.parent}
 		if tc.parent != "" {
@@ -184,7 +209,7 @@
 }
 
 func TestNaming(t *T) {
-	m := newMatcher(regexp.MatchString, "", "")
+	m := newMatcher(regexp.MatchString, "", "", "")
 	parent := &common{name: "x", level: 1} // top-level test.
 
 	for i, tc := range namingTestCases {
@@ -202,7 +227,7 @@
 	var m *matcher
 	var seen map[string]string
 	reset := func() {
-		m = newMatcher(regexp.MatchString, "", "")
+		m = allMatcher()
 		seen = make(map[string]string)
 	}
 	reset()
diff --git a/src/testing/newcover.go b/src/testing/newcover.go
new file mode 100644
index 0000000..1805f79
--- /dev/null
+++ b/src/testing/newcover.go
@@ -0,0 +1,48 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Support for test coverage with redesigned coverage implementation.
+
+package testing
+
+import (
+	"fmt"
+	"internal/goexperiment"
+	"os"
+)
+
+// cover2 variable stores the current coverage mode and a
+// tear-down function to be called at the end of the testing run.
+var cover2 struct {
+	mode     string
+	tearDown func(coverprofile string, gocoverdir string) (string, error)
+}
+
+// registerCover2 is invoked during "go test -cover" runs by the test harness
+// code in _testmain.go; it is used to record a 'tear down' function
+// (to be called when the test is complete) and the coverage mode.
+func registerCover2(mode string, tearDown func(coverprofile string, gocoverdir string) (string, error)) {
+	cover2.mode = mode
+	cover2.tearDown = tearDown
+}
+
+// coverReport2 invokes a callback in _testmain.go that will
+// emit coverage data at the point where test execution is complete,
+// for "go test -cover" runs.
+func coverReport2() {
+	if !goexperiment.CoverageRedesign {
+		panic("unexpected")
+	}
+	if errmsg, err := cover2.tearDown(*coverProfile, *gocoverdir); err != nil {
+		fmt.Fprintf(os.Stderr, "%s: %v\n", errmsg, err)
+		os.Exit(2)
+	}
+}
+
+// testGoCoverDir returns the value passed to the -test.gocoverdir
+// flag by the Go command, if goexperiment.CoverageRedesign is
+// in effect.
+func testGoCoverDir() string {
+	return *gocoverdir
+}
diff --git a/src/testing/panic_test.go b/src/testing/panic_test.go
index 6b8b953..8733bc3 100644
--- a/src/testing/panic_test.go
+++ b/src/testing/panic_test.go
@@ -11,6 +11,7 @@
 	"os"
 	"os/exec"
 	"regexp"
+	"runtime"
 	"strings"
 	"testing"
 )
@@ -208,3 +209,59 @@
 		})
 	}
 }
+
+func TestMorePanic(t *testing.T) {
+	testenv.MustHaveExec(t)
+
+	testCases := []struct {
+		desc  string
+		flags []string
+		want  string
+	}{
+		{
+			desc:  "Issue 48502: call runtime.Goexit in t.Cleanup after panic",
+			flags: []string{"-test.run=TestGoexitInCleanupAfterPanicHelper"},
+			want: `panic: die
+	panic: test executed panic(nil) or runtime.Goexit`,
+		},
+		{
+			desc:  "Issue 48515: call t.Run in t.Cleanup should trigger panic",
+			flags: []string{"-test.run=TestCallRunInCleanupHelper"},
+			want:  `panic: testing: t.Run called during t.Cleanup`,
+		},
+	}
+
+	for _, tc := range testCases {
+		cmd := exec.Command(os.Args[0], tc.flags...)
+		cmd.Env = append(os.Environ(), "GO_WANT_HELPER_PROCESS=1")
+		b, _ := cmd.CombinedOutput()
+		got := string(b)
+		want := tc.want
+		re := makeRegexp(want)
+		if ok, err := regexp.MatchString(re, got); !ok || err != nil {
+			t.Errorf("output:\ngot:\n%s\nwant:\n%s", got, want)
+		}
+	}
+}
+
+func TestCallRunInCleanupHelper(t *testing.T) {
+	if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
+		return
+	}
+
+	t.Cleanup(func() {
+		t.Run("in-cleanup", func(t *testing.T) {
+			t.Log("must not be executed")
+		})
+	})
+}
+
+func TestGoexitInCleanupAfterPanicHelper(t *testing.T) {
+	if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
+		return
+	}
+
+	t.Cleanup(func() { runtime.Goexit() })
+	t.Parallel()
+	panic("die")
+}
diff --git a/src/testing/run_example.go b/src/testing/run_example.go
index e7eab1e..776fbff 100644
--- a/src/testing/run_example.go
+++ b/src/testing/run_example.go
@@ -19,8 +19,8 @@
 )
 
 func runExample(eg InternalExample) (ok bool) {
-	if *chatty {
-		fmt.Printf("=== RUN   %s\n", eg.Name)
+	if chatty.on {
+		fmt.Printf("%s=== RUN   %s\n", chatty.prefix(), eg.Name)
 	}
 
 	// Capture stdout.
diff --git a/src/testing/run_example_js.go b/src/testing/run_example_js.go
index adef951..572c6b3 100644
--- a/src/testing/run_example_js.go
+++ b/src/testing/run_example_js.go
@@ -17,8 +17,8 @@
 // TODO(@musiol, @odeke-em): unify this code back into
 // example.go when js/wasm gets an os.Pipe implementation.
 func runExample(eg InternalExample) (ok bool) {
-	if *chatty {
-		fmt.Printf("=== RUN   %s\n", eg.Name)
+	if chatty.on {
+		fmt.Printf("%s=== RUN   %s\n", chatty.prefix(), eg.Name)
 	}
 
 	// Capture stdout to temporary file. We're not using
@@ -36,7 +36,7 @@
 		// Restore stdout, get output and remove temporary file.
 		os.Stdout = stdout
 		var buf strings.Builder
-		_, seekErr := f.Seek(0, os.SEEK_SET)
+		_, seekErr := f.Seek(0, io.SeekStart)
 		_, readErr := io.Copy(&buf, f)
 		out := buf.String()
 		f.Close()
diff --git a/src/testing/sub_test.go b/src/testing/sub_test.go
index 6324d46..55b14c3 100644
--- a/src/testing/sub_test.go
+++ b/src/testing/sub_test.go
@@ -124,6 +124,7 @@
 		ok     bool
 		maxPar int
 		chatty bool
+		json   bool
 		output string
 		f      func(*T)
 	}{{
@@ -204,6 +205,36 @@
 			})
 		},
 	}, {
+		desc:   "chatty with recursion and json",
+		ok:     false,
+		chatty: true,
+		json:   true,
+		output: `
+^V=== RUN   chatty with recursion and json
+^V=== RUN   chatty with recursion and json/#00
+^V=== RUN   chatty with recursion and json/#00/#00
+^V--- PASS: chatty with recursion and json/#00/#00 (N.NNs)
+^V=== NAME  chatty with recursion and json/#00
+^V=== RUN   chatty with recursion and json/#00/#01
+    sub_test.go:NNN: skip
+^V--- SKIP: chatty with recursion and json/#00/#01 (N.NNs)
+^V=== NAME  chatty with recursion and json/#00
+^V=== RUN   chatty with recursion and json/#00/#02
+    sub_test.go:NNN: fail
+^V--- FAIL: chatty with recursion and json/#00/#02 (N.NNs)
+^V=== NAME  chatty with recursion and json/#00
+^V--- FAIL: chatty with recursion and json/#00 (N.NNs)
+^V=== NAME  chatty with recursion and json
+^V--- FAIL: chatty with recursion and json (N.NNs)
+^V=== NAME  `,
+		f: func(t *T) {
+			t.Run("", func(t *T) {
+				t.Run("", func(t *T) {})
+				t.Run("", func(t *T) { t.Skip("skip") })
+				t.Run("", func(t *T) { t.Fatal("fail") })
+			})
+		},
+	}, {
 		desc: "skipping without message, not chatty",
 		ok:   true,
 		f:    func(t *T) { t.SkipNow() },
@@ -476,19 +507,20 @@
 	}}
 	for _, tc := range testCases {
 		t.Run(tc.desc, func(t *T) {
-			ctx := newTestContext(tc.maxPar, newMatcher(regexp.MatchString, "", ""))
-			buf := &bytes.Buffer{}
+			ctx := newTestContext(tc.maxPar, allMatcher())
+			buf := &strings.Builder{}
 			root := &T{
 				common: common{
 					signal:  make(chan bool),
 					barrier: make(chan bool),
-					name:    "Test",
+					name:    "",
 					w:       buf,
 				},
 				context: ctx,
 			}
 			if tc.chatty {
 				root.chatty = newChattyPrinter(root.w)
+				root.chatty.json = tc.json
 			}
 			ok := root.Run(tc.desc, tc.f)
 			ctx.release()
@@ -657,10 +689,14 @@
 			}
 		},
 	}}
+	hideStdoutForTesting = true
+	defer func() {
+		hideStdoutForTesting = false
+	}()
 	for _, tc := range testCases {
 		t.Run(tc.desc, func(t *T) {
 			var ok bool
-			buf := &bytes.Buffer{}
+			buf := &strings.Builder{}
 			// This is almost like the Benchmark function, except that we override
 			// the benchtime and catch the failure result of the subbenchmark.
 			root := &B{
@@ -698,6 +734,7 @@
 
 func makeRegexp(s string) string {
 	s = regexp.QuoteMeta(s)
+	s = strings.ReplaceAll(s, "^V", "\x16")
 	s = strings.ReplaceAll(s, ":NNN:", `:\d\d\d\d?:`)
 	s = strings.ReplaceAll(s, "N\\.NNs", `\d*\.\d*s`)
 	return s
@@ -768,13 +805,13 @@
 		return len(b), nil
 	}
 
-	var wg sync.WaitGroup
 	root := &T{
 		common:  common{w: &funcWriter{raceDetector}},
-		context: newTestContext(1, newMatcher(regexp.MatchString, "", "")),
+		context: newTestContext(1, allMatcher()),
 	}
 	root.chatty = newChattyPrinter(root.w)
 	root.Run("", func(t *T) {
+		var wg sync.WaitGroup
 		for i := 0; i < 100; i++ {
 			wg.Add(1)
 			go func(i int) {
@@ -784,8 +821,8 @@
 				})
 			}(i)
 		}
+		wg.Wait()
 	})
-	wg.Wait()
 
 	if races > 0 {
 		t.Errorf("detected %d racy Writes", races)
@@ -794,7 +831,7 @@
 
 // The late log message did not include the test name.  Issue 29388.
 func TestLogAfterComplete(t *T) {
-	ctx := newTestContext(1, newMatcher(regexp.MatchString, "", ""))
+	ctx := newTestContext(1, allMatcher())
 	var buf bytes.Buffer
 	t1 := &T{
 		common: common{
diff --git a/src/testing/testing.go b/src/testing/testing.go
index ec2d864..fc34cbf 100644
--- a/src/testing/testing.go
+++ b/src/testing/testing.go
@@ -13,13 +13,21 @@
 //
 // Within these functions, use the Error, Fail or related methods to signal failure.
 //
-// To write a new test suite, create a file whose name ends _test.go that
-// contains the TestXxx functions as described here. Put the file in the same
-// package as the one being tested. The file will be excluded from regular
+// To write a new test suite, create a file that
+// contains the TestXxx functions as described here,
+// and give that file a name ending in "_test.go".
+// The file will be excluded from regular
 // package builds but will be included when the "go test" command is run.
-// For more detail, run "go help test" and "go help testflag".
 //
-// A simple test function looks like this:
+// The test file can be in the same package as the one being tested,
+// or in a corresponding package with the suffix "_test".
+//
+// If the test file is in the same package, it may refer to unexported
+// identifiers within the package, as in this example:
+//
+//	package abs
+//
+//	import "testing"
 //
 //	func TestAbs(t *testing.T) {
 //	    got := Abs(-1)
@@ -28,6 +36,27 @@
 //	    }
 //	}
 //
+// If the file is in a separate "_test" package, the package being tested
+// must be imported explicitly and only its exported identifiers may be used.
+// This is known as "black box" testing.
+//
+//	package abs_test
+//
+//	import (
+//		"testing"
+//
+//		"path_to_pkg/abs"
+//	)
+//
+//	func TestAbs(t *testing.T) {
+//	    got := abs.Abs(-1)
+//	    if got != 1 {
+//	        t.Errorf("Abs(-1) = %d; want 1", got)
+//	    }
+//	}
+//
+// For more detail, run "go help test" and "go help testflag".
+//
 // # Benchmarks
 //
 // Functions of the form
@@ -235,7 +264,7 @@
 //	            t.Skip()
 //	        }
 //	        if _, err := json.Marshal(v); err != nil {
-//	            t.Error("Marshal: %v", err)
+//	            t.Errorf("Marshal: %v", err)
 //	        }
 //	    })
 //	}
@@ -344,6 +373,7 @@
 	"errors"
 	"flag"
 	"fmt"
+	"internal/goexperiment"
 	"internal/race"
 	"io"
 	"math/rand"
@@ -352,6 +382,7 @@
 	"runtime"
 	"runtime/debug"
 	"runtime/trace"
+	"sort"
 	"strconv"
 	"strings"
 	"sync"
@@ -389,11 +420,13 @@
 	// the "go test" command is run.
 	outputDir = flag.String("test.outputdir", "", "write profiles to `dir`")
 	// Report as tests are run; default is silent for success.
-	chatty = flag.Bool("test.v", false, "verbose: print additional output")
+	flag.Var(&chatty, "test.v", "verbose: print additional output")
 	count = flag.Uint("test.count", 1, "run tests and benchmarks `n` times")
 	coverProfile = flag.String("test.coverprofile", "", "write a coverage profile to `file`")
+	gocoverdir = flag.String("test.gocoverdir", "", "write coverage intermediate files to this directory")
 	matchList = flag.String("test.list", "", "list tests, examples, and benchmarks matching `regexp` then exit")
 	match = flag.String("test.run", "", "run only tests and examples matching `regexp`")
+	skip = flag.String("test.skip", "", "do not list or run tests matching `regexp`")
 	memProfile = flag.String("test.memprofile", "", "write an allocation profile to `file`")
 	memProfileRate = flag.Int("test.memprofilerate", 0, "set memory allocation profiling `rate` (see runtime.MemProfileRate)")
 	cpuProfile = flag.String("test.cpuprofile", "", "write a cpu profile to `file`")
@@ -418,11 +451,13 @@
 	short                *bool
 	failFast             *bool
 	outputDir            *string
-	chatty               *bool
+	chatty               chattyFlag
 	count                *uint
 	coverProfile         *string
+	gocoverdir           *string
 	matchList            *string
 	match                *string
+	skip                 *string
 	memProfile           *string
 	memProfileRate       *int
 	cpuProfile           *string
@@ -443,17 +478,78 @@
 	cpuList     []int
 	testlogFile *os.File
 
-	numFailed uint32 // number of test failures
+	numFailed atomic.Uint32 // number of test failures
+
+	running sync.Map // map[string]time.Time of running, unpaused tests
 )
 
+type chattyFlag struct {
+	on   bool // -v is set in some form
+	json bool // -v=test2json is set, to make output better for test2json
+}
+
+func (*chattyFlag) IsBoolFlag() bool { return true }
+
+func (f *chattyFlag) Set(arg string) error {
+	switch arg {
+	default:
+		return fmt.Errorf("invalid flag -test.v=%s", arg)
+	case "true", "test2json":
+		f.on = true
+		f.json = arg == "test2json"
+	case "false":
+		f.on = false
+		f.json = false
+	}
+	return nil
+}
+
+func (f *chattyFlag) String() string {
+	if f.json {
+		return "test2json"
+	}
+	if f.on {
+		return "true"
+	}
+	return "false"
+}
+
+func (f *chattyFlag) Get() any {
+	if f.json {
+		return "test2json"
+	}
+	return f.on
+}
+
+const marker = byte(0x16) // ^V for framing
+
+func (f *chattyFlag) prefix() string {
+	if f.json {
+		return string(marker)
+	}
+	return ""
+}
+
 type chattyPrinter struct {
 	w          io.Writer
 	lastNameMu sync.Mutex // guards lastName
 	lastName   string     // last printed test name in chatty mode
+	json       bool       // -v=json output mode
 }
 
 func newChattyPrinter(w io.Writer) *chattyPrinter {
-	return &chattyPrinter{w: w}
+	return &chattyPrinter{w: w, json: chatty.json}
+}
+
+// prefix is like chatty.prefix but using p.json instead of chatty.json.
+// Using p.json allows tests to check the json behavior without modifying
+// the global variable. For convenience, we allow p == nil and treat
+// that as not in json mode (because it's not chatty at all).
+func (p *chattyPrinter) prefix() string {
+	if p != nil && p.json {
+		return string(marker)
+	}
+	return ""
 }
 
 // Updatef prints a message about the status of the named test to w.
@@ -464,11 +560,11 @@
 	defer p.lastNameMu.Unlock()
 
 	// Since the message already implies an association with a specific new test,
-	// we don't need to check what the old test name was or log an extra CONT line
+	// we don't need to check what the old test name was or log an extra NAME line
 	// for it. (We're updating it anyway, and the current message already includes
 	// the test name.)
 	p.lastName = testName
-	fmt.Fprintf(p.w, format, args...)
+	fmt.Fprintf(p.w, p.prefix()+format, args...)
 }
 
 // Printf prints a message, generated by the named test, that does not
@@ -480,7 +576,7 @@
 	if p.lastName == "" {
 		p.lastName = testName
 	} else if p.lastName != testName {
-		fmt.Fprintf(p.w, "=== CONT  %s\n", testName)
+		fmt.Fprintf(p.w, "%s=== NAME  %s\n", p.prefix(), testName)
 		p.lastName = testName
 	}
 
@@ -509,11 +605,13 @@
 	finished    bool                 // Test function has completed.
 	inFuzzFn    bool                 // Whether the fuzz target, if this is one, is running.
 
-	chatty     *chattyPrinter // A copy of chattyPrinter, if the chatty flag is set.
-	bench      bool           // Whether the current test is a benchmark.
-	hasSub     int32          // Written atomically.
-	raceErrors int            // Number of races detected during test.
-	runner     string         // Function name of tRunner running the test.
+	chatty         *chattyPrinter // A copy of chattyPrinter, if the chatty flag is set.
+	bench          bool           // Whether the current test is a benchmark.
+	hasSub         atomic.Bool    // whether there are sub-benchmarks.
+	cleanupStarted atomic.Bool    // Registered cleanup callbacks have started to execute
+	raceErrors     int            // Number of races detected during test.
+	runner         string         // Function name of tRunner running the test.
+	isParallel     bool           // Whether the test is parallel.
 
 	parent   *common
 	level    int       // Nesting depth of test or benchmark.
@@ -548,19 +646,19 @@
 // values are "set", "count", or "atomic". The return value will be
 // empty if test coverage is not enabled.
 func CoverMode() string {
+	if goexperiment.CoverageRedesign {
+		return cover2.mode
+	}
 	return cover.Mode
 }
 
 // Verbose reports whether the -test.v flag is set.
 func Verbose() bool {
 	// Same as in Short.
-	if chatty == nil {
-		panic("testing: Verbose called before Init")
-	}
 	if !flag.Parsed() {
 		panic("testing: Verbose called before Parse")
 	}
-	return *chatty
+	return chatty.on
 }
 
 func (c *common) checkFuzzFn(name string) {
@@ -695,26 +793,33 @@
 	defer c.mu.Unlock()
 
 	if len(c.output) > 0 {
+		// Add the current c.output to the print,
+		// and then arrange for the print to replace c.output.
+		// (This displays the logged output after the --- FAIL line.)
 		format += "%s"
 		args = append(args[:len(args):len(args)], c.output)
-		c.output = c.output[:0] // but why?
+		c.output = c.output[:0]
 	}
 
-	if c.chatty != nil && p.w == c.chatty.w {
+	if c.chatty != nil && (p.w == c.chatty.w || c.chatty.json) {
 		// We're flushing to the actual output, so track that this output is
 		// associated with a specific test (and, specifically, that the next output
 		// is *not* associated with that test).
 		//
 		// Moreover, if c.output is non-empty it is important that this write be
 		// atomic with respect to the output of other tests, so that we don't end up
-		// with confusing '=== CONT' lines in the middle of our '--- PASS' block.
+		// with confusing '=== NAME' lines in the middle of our '--- PASS' block.
 		// Neither humans nor cmd/test2json can parse those easily.
-		// (See https://golang.org/issue/40771.)
+		// (See https://go.dev/issue/40771.)
+		//
+		// If test2json is used, we never flush to parent tests,
+		// so that the json stream shows subtests as they finish.
+		// (See https://go.dev/issue/29811.)
 		c.chatty.Updatef(testName, format, args...)
 	} else {
 		// We're flushing to the output buffer of the parent test, which will
 		// itself follow a test-name header when it is finally flushed to stdout.
-		fmt.Fprintf(p.w, format, args...)
+		fmt.Fprintf(p.w, c.chatty.prefix()+format, args...)
 	}
 }
 
@@ -733,9 +838,14 @@
 		}
 		// An indent of 4 spaces will neatly align the dashes with the status
 		// indicator of the parent.
+		line := b[:end]
+		if line[0] == marker {
+			w.c.output = append(w.c.output, marker)
+			line = line[1:]
+		}
 		const indent = "    "
 		w.c.output = append(w.c.output, indent...)
-		w.c.output = append(w.c.output, b[:end]...)
+		w.c.output = append(w.c.output, line...)
 		b = b[end:]
 	}
 	return
@@ -787,9 +897,8 @@
 // may be called simultaneously from multiple goroutines.
 type T struct {
 	common
-	isParallel bool
-	isEnvSet   bool
-	context    *testContext // For running tests and subtests.
+	isEnvSet bool
+	context  *testContext // For running tests and subtests.
 }
 
 func (c *common) private() {}
@@ -1099,12 +1208,17 @@
 			})
 		}
 	}
+
+	if c.tempDirErr == nil {
+		c.tempDirSeq++
+	}
+	seq := c.tempDirSeq
 	c.tempDirMu.Unlock()
 
 	if c.tempDirErr != nil {
 		c.Fatalf("TempDir: %v", c.tempDirErr)
 	}
-	seq := atomic.AddInt32(&c.tempDirSeq, 1)
+
 	dir := fmt.Sprintf("%s%c%03d", c.tempDir, os.PathSeparator, seq)
 	if err := os.Mkdir(dir, 0777); err != nil {
 		c.Fatalf("TempDir: %v", err)
@@ -1146,7 +1260,8 @@
 // restore the environment variable to its original value
 // after the test.
 //
-// This cannot be used in parallel tests.
+// Because Setenv affects the whole process, it cannot be used
+// in parallel tests or tests with parallel ancestors.
 func (c *common) Setenv(key, value string) {
 	c.checkFuzzFn("Setenv")
 	prevValue, ok := os.LookupEnv(key)
@@ -1178,6 +1293,9 @@
 // If catchPanic is true, this will catch panics, and return the recovered
 // value if any.
 func (c *common) runCleanup(ph panicHandling) (panicVal any) {
+	c.cleanupStarted.Store(true)
+	defer c.cleanupStarted.Store(false)
+
 	if ph == recoverAndReturnPanic {
 		defer func() {
 			panicVal = recover()
@@ -1258,14 +1376,9 @@
 	t.raceErrors += race.Errors()
 
 	if t.chatty != nil {
-		// Unfortunately, even though PAUSE indicates that the named test is *no
-		// longer* running, cmd/test2json interprets it as changing the active test
-		// for the purpose of log parsing. We could fix cmd/test2json, but that
-		// won't fix existing deployments of third-party tools that already shell
-		// out to older builds of cmd/test2json — so merely fixing cmd/test2json
-		// isn't enough for now.
 		t.chatty.Updatef(t.name, "=== PAUSE %s\n", t.name)
 	}
+	running.Delete(t.name)
 
 	t.signal <- true   // Release calling test.
 	<-t.parent.barrier // Wait for the parent test to complete.
@@ -1274,6 +1387,7 @@
 	if t.chatty != nil {
 		t.chatty.Updatef(t.name, "=== CONT  %s\n", t.name)
 	}
+	running.Store(t.name, time.Now())
 
 	t.start = time.Now()
 	t.raceErrors += -race.Errors()
@@ -1283,9 +1397,22 @@
 // restore the environment variable to its original value
 // after the test.
 //
-// This cannot be used in parallel tests.
+// Because Setenv affects the whole process, it cannot be used
+// in parallel tests or tests with parallel ancestors.
 func (t *T) Setenv(key, value string) {
-	if t.isParallel {
+	// Non-parallel subtests that have parallel ancestors may still
+	// run in parallel with other tests: they are only non-parallel
+	// with respect to the other subtests of the same parent.
+	// Since SetEnv affects the whole process, we need to disallow it
+	// if the current test or any parent is parallel.
+	isParallel := false
+	for c := &t.common; c != nil; c = c.parent {
+		if c.isParallel {
+			isParallel = true
+			break
+		}
+	}
+	if isParallel {
 		panic("testing: t.Setenv called after t.Parallel; cannot set environment variables in parallel tests")
 	}
 
@@ -1312,7 +1439,7 @@
 	// a signal saying that the test is done.
 	defer func() {
 		if t.Failed() {
-			atomic.AddUint32(&numFailed, 1)
+			numFailed.Add(1)
 		}
 
 		if t.raceErrors+race.Errors() > 0 {
@@ -1340,8 +1467,10 @@
 				finished = p.finished
 				p.mu.RUnlock()
 				if finished {
-					t.Errorf("%v: subtest may have called FailNow on a parent test", err)
-					err = nil
+					if !t.isParallel {
+						t.Errorf("%v: subtest may have called FailNow on a parent test", err)
+						err = nil
+					}
 					signal = false
 					break
 				}
@@ -1364,15 +1493,16 @@
 		// complete even if a cleanup function calls t.FailNow. See issue 41355.
 		didPanic := false
 		defer func() {
+			// Only report that the test is complete if it doesn't panic,
+			// as otherwise the test binary can exit before the panic is
+			// reported to the user. See issue 41479.
 			if didPanic {
 				return
 			}
 			if err != nil {
 				panic(err)
 			}
-			// Only report that the test is complete if it doesn't panic,
-			// as otherwise the test binary can exit before the panic is
-			// reported to the user. See issue 41479.
+			running.Delete(t.name)
 			t.signal <- signal
 		}()
 
@@ -1431,7 +1561,7 @@
 		// Do not lock t.done to allow race detector to detect race in case
 		// the user does not appropriately synchronize a goroutine.
 		t.done = true
-		if t.parent != nil && atomic.LoadInt32(&t.hasSub) == 0 {
+		if t.parent != nil && !t.hasSub.Load() {
 			t.setRan()
 		}
 	}()
@@ -1458,7 +1588,11 @@
 // Run may be called simultaneously from multiple goroutines, but all such calls
 // must return before the outer test function for t returns.
 func (t *T) Run(name string, f func(t *T)) bool {
-	atomic.StoreInt32(&t.hasSub, 1)
+	if t.cleanupStarted.Load() {
+		panic("testing: t.Run called during t.Cleanup")
+	}
+
+	t.hasSub.Store(true)
 	testName, ok, _ := t.context.match.fullName(&t.common, name)
 	if !ok || shouldFailFast() {
 		return true
@@ -1485,6 +1619,8 @@
 	if t.chatty != nil {
 		t.chatty.Updatef(t.name, "=== RUN   %s\n", t.name)
 	}
+	running.Store(t.name, time.Now())
+
 	// Instead of reducing the running count of this test before calling the
 	// tRunner and increasing it afterwards, we rely on tRunner keeping the
 	// count correct. This ensures that a sequence of sequential tests runs
@@ -1496,6 +1632,9 @@
 		// parent tests by one of the subtests. Continue aborting up the chain.
 		runtime.Goexit()
 	}
+	if t.chatty != nil && t.chatty.json {
+		t.chatty.Updatef(t.parent.name, "=== NAME  %s\n", t.parent.name)
+	}
 	return !t.failed
 }
 
@@ -1657,6 +1796,9 @@
 	}
 }
 
+var testingTesting bool
+var realStderr *os.File
+
 // Run runs the tests. It returns an exit code to pass to os.Exit.
 func (m *M) Run() (code int) {
 	defer func() {
@@ -1666,7 +1808,7 @@
 	// Count the number of calls to m.Run.
 	// We only ever expected 1, but we didn't enforce that,
 	// and now there are tests in the wild that call m.Run multiple times.
-	// Sigh. golang.org/issue/23129.
+	// Sigh. go.dev/issue/23129.
 	m.numRun++
 
 	// TestMain may have already called flag.Parse.
@@ -1674,6 +1816,44 @@
 		flag.Parse()
 	}
 
+	if chatty.json {
+		// With -v=json, stdout and stderr are pointing to the same pipe,
+		// which is leading into test2json. In general, operating systems
+		// do a good job of ensuring that writes to the same pipe through
+		// different file descriptors are delivered whole, so that writing
+		// AAA to stdout and BBB to stderr simultaneously produces
+		// AAABBB or BBBAAA on the pipe, not something like AABBBA.
+		// However, the exception to this is when the pipe fills: in that
+		// case, Go's use of non-blocking I/O means that writing AAA
+		// or BBB might be split across multiple system calls, making it
+		// entirely possible to get output like AABBBA. The same problem
+		// happens inside the operating system kernel if we switch to
+		// blocking I/O on the pipe. This interleaved output can do things
+		// like print unrelated messages in the middle of a TestFoo line,
+		// which confuses test2json. Setting os.Stderr = os.Stdout will make
+		// them share a single pfd, which will hold a lock for each program
+		// write, preventing any interleaving.
+		//
+		// It might be nice to set Stderr = Stdout always, or perhaps if
+		// we can tell they are the same file, but for now -v=json is
+		// a very clear signal. Making the two files the same may cause
+		// surprises if programs close os.Stdout but expect to be able
+		// to continue to write to os.Stderr, but it's hard to see why a
+		// test would think it could take over global state that way.
+		//
+		// This fix only helps programs where the output is coming directly
+		// from Go code. It does not help programs in which a subprocess is
+		// writing to stderr or stdout at the same time that a Go test is writing output.
+		// It also does not help when the output is coming from the runtime,
+		// such as when using the print/println functions, since that code writes
+		// directly to fd 2 without any locking.
+		// We keep realStderr around to prevent fd 2 from being closed.
+		//
+		// See go.dev/issue/33419.
+		realStderr = os.Stderr
+		os.Stderr = os.Stdout
+	}
+
 	if *parallel < 1 {
 		fmt.Fprintln(os.Stderr, "testing: -parallel can only be given a positive integer")
 		flag.Usage()
@@ -1687,7 +1867,7 @@
 		return
 	}
 
-	if len(*matchList) != 0 {
+	if *matchList != "" {
 		listTests(m.deps.MatchString, m.tests, m.benchmarks, m.fuzzTargets, m.examples)
 		m.exitCode = 0
 		return
@@ -1729,9 +1909,19 @@
 		m.stopAlarm()
 		if !testRan && !exampleRan && !fuzzTargetsRan && *matchBenchmarks == "" && *matchFuzz == "" {
 			fmt.Fprintln(os.Stderr, "testing: warning: no tests to run")
+			if testingTesting && *match != "^$" {
+				// If this happens during testing of package testing it could be that
+				// package testing's own logic for when to run a test is broken,
+				// in which case every test will run nothing and succeed,
+				// with no obvious way to detect this problem (since no tests are running).
+				// So make 'no tests to run' a hard failure when testing package testing itself.
+				// The compile-only builders use -run=^$ to run no tests, so allow that.
+				fmt.Print(chatty.prefix(), "FAIL: package testing must run tests\n")
+				testOk = false
+			}
 		}
 		if !testOk || !exampleOk || !fuzzTargetsOk || !runBenchmarks(m.deps.ImportPath(), m.deps.MatchString, m.benchmarks) || race.Errors() > 0 {
-			fmt.Println("FAIL")
+			fmt.Print(chatty.prefix(), "FAIL\n")
 			m.exitCode = 1
 			return
 		}
@@ -1739,7 +1929,7 @@
 
 	fuzzingOk := runFuzzing(m.deps, m.fuzzTargets)
 	if !fuzzingOk {
-		fmt.Println("FAIL")
+		fmt.Print(chatty.prefix(), "FAIL\n")
 		if *isFuzzWorker {
 			m.exitCode = fuzzWorkerExitCode
 		} else {
@@ -1750,7 +1940,7 @@
 
 	m.exitCode = 0
 	if !*isFuzzWorker {
-		fmt.Println("PASS")
+		fmt.Print(chatty.prefix(), "PASS\n")
 	}
 	return
 }
@@ -1828,7 +2018,7 @@
 				// to keep trying.
 				break
 			}
-			ctx := newTestContext(*parallel, newMatcher(matchString, *match, "-test.run"))
+			ctx := newTestContext(*parallel, newMatcher(matchString, *match, "-test.run", *skip))
 			ctx.deadline = deadline
 			t := &T{
 				common: common{
@@ -1895,10 +2085,14 @@
 	if *mutexProfile != "" && *mutexProfileFraction >= 0 {
 		runtime.SetMutexProfileFraction(*mutexProfileFraction)
 	}
-	if *coverProfile != "" && cover.Mode == "" {
+	if *coverProfile != "" && CoverMode() == "" {
 		fmt.Fprintf(os.Stderr, "testing: cannot use -test.coverprofile because test binary was not built with coverage enabled\n")
 		os.Exit(2)
 	}
+	if *gocoverdir != "" && CoverMode() == "" {
+		fmt.Fprintf(os.Stderr, "testing: cannot use -test.gocoverdir because test binary was not built with coverage enabled\n")
+		os.Exit(2)
+	}
 	if *testlog != "" {
 		// Note: Not using toOutputDir.
 		// This file is for use by cmd/go, not users.
@@ -1992,7 +2186,7 @@
 		}
 		f.Close()
 	}
-	if cover.Mode != "" {
+	if CoverMode() != "" {
 		coverReport()
 	}
 }
@@ -2033,11 +2227,33 @@
 	m.timer = time.AfterFunc(*timeout, func() {
 		m.after()
 		debug.SetTraceback("all")
-		panic(fmt.Sprintf("test timed out after %v", *timeout))
+		extra := ""
+
+		if list := runningList(); len(list) > 0 {
+			var b strings.Builder
+			b.WriteString("\nrunning tests:")
+			for _, name := range list {
+				b.WriteString("\n\t")
+				b.WriteString(name)
+			}
+			extra = b.String()
+		}
+		panic(fmt.Sprintf("test timed out after %v%s", *timeout, extra))
 	})
 	return deadline
 }
 
+// runningList returns the list of running tests.
+func runningList() []string {
+	var list []string
+	running.Range(func(k, v any) bool {
+		list = append(list, fmt.Sprintf("%s (%v)", k.(string), time.Since(v.(time.Time)).Round(time.Second)))
+		return true
+	})
+	sort.Strings(list)
+	return list
+}
+
 // stopAlarm turns off the alarm.
 func (m *M) stopAlarm() {
 	if *timeout > 0 {
@@ -2064,5 +2280,5 @@
 }
 
 func shouldFailFast() bool {
-	return *failFast && atomic.LoadUint32(&numFailed) > 0
+	return *failFast && numFailed.Load() > 0
 }
diff --git a/src/testing/testing_test.go b/src/testing/testing_test.go
index 08ae239..3616f04 100644
--- a/src/testing/testing_test.go
+++ b/src/testing/testing_test.go
@@ -200,3 +200,35 @@
 
 	t.Setenv("GO_TEST_KEY_1", "value")
 }
+
+func TestSetenvWithParallelParentBeforeSetenv(t *testing.T) {
+	t.Parallel()
+
+	t.Run("child", func(t *testing.T) {
+		defer func() {
+			want := "testing: t.Setenv called after t.Parallel; cannot set environment variables in parallel tests"
+			if got := recover(); got != want {
+				t.Fatalf("expected panic; got %#v want %q", got, want)
+			}
+		}()
+
+		t.Setenv("GO_TEST_KEY_1", "value")
+	})
+}
+
+func TestSetenvWithParallelGrandParentBeforeSetenv(t *testing.T) {
+	t.Parallel()
+
+	t.Run("child", func(t *testing.T) {
+		t.Run("grand-child", func(t *testing.T) {
+			defer func() {
+				want := "testing: t.Setenv called after t.Parallel; cannot set environment variables in parallel tests"
+				if got := recover(); got != want {
+					t.Fatalf("expected panic; got %#v want %q", got, want)
+				}
+			}()
+
+			t.Setenv("GO_TEST_KEY_1", "value")
+		})
+	})
+}
diff --git a/src/text/template/doc.go b/src/text/template/doc.go
index 58cc973..7817a17 100644
--- a/src/text/template/doc.go
+++ b/src/text/template/doc.go
@@ -424,10 +424,10 @@
 The define action names the template being created by providing a string
 constant. Here is a simple example:
 
-	`{{define "T1"}}ONE{{end}}
+	{{define "T1"}}ONE{{end}}
 	{{define "T2"}}TWO{{end}}
 	{{define "T3"}}{{template "T1"}} {{template "T2"}}{{end}}
-	{{template "T3"}}`
+	{{template "T3"}}
 
 This defines two templates, T1 and T2, and a third T3 that invokes the other two
 when it is executed. Finally it invokes T3. If executed this template will
diff --git a/src/text/template/exec.go b/src/text/template/exec.go
index 37984cf..fb60c17 100644
--- a/src/text/template/exec.go
+++ b/src/text/template/exec.go
@@ -94,6 +94,12 @@
 
 var missingVal = reflect.ValueOf(missingValType{})
 
+var missingValReflectType = reflect.TypeOf(missingValType{})
+
+func isMissing(v reflect.Value) bool {
+	return v.IsValid() && v.Type() == missingValReflectType
+}
+
 // at marks the state to be on node n, for error reporting.
 func (s *state) at(node parse.Node) {
 	s.node = node
@@ -357,11 +363,19 @@
 	oneIteration := func(index, elem reflect.Value) {
 		// Set top var (lexically the second if there are two) to the element.
 		if len(r.Pipe.Decl) > 0 {
-			s.setTopVar(1, elem)
+			if r.Pipe.IsAssign {
+				s.setVar(r.Pipe.Decl[0].Ident[0], elem)
+			} else {
+				s.setTopVar(1, elem)
+			}
 		}
 		// Set next var (lexically the first if there are two) to the index.
 		if len(r.Pipe.Decl) > 1 {
-			s.setTopVar(2, index)
+			if r.Pipe.IsAssign {
+				s.setVar(r.Pipe.Decl[1].Ident[0], index)
+			} else {
+				s.setTopVar(2, index)
+			}
 		}
 		defer s.pop(mark)
 		defer func() {
@@ -471,7 +485,7 @@
 }
 
 func (s *state) notAFunction(args []parse.Node, final reflect.Value) {
-	if len(args) > 1 || final != missingVal {
+	if len(args) > 1 || !isMissing(final) {
 		s.errorf("can't give argument to non-function %s", args[0])
 	}
 }
@@ -629,7 +643,7 @@
 	if method := ptr.MethodByName(fieldName); method.IsValid() {
 		return s.evalCall(dot, method, false, node, fieldName, args, final)
 	}
-	hasArgs := len(args) > 1 || final != missingVal
+	hasArgs := len(args) > 1 || !isMissing(final)
 	// It's not a method; must be a field of a struct or an element of a map.
 	switch receiver.Kind() {
 	case reflect.Struct:
@@ -700,7 +714,7 @@
 	}
 	typ := fun.Type()
 	numIn := len(args)
-	if final != missingVal {
+	if !isMissing(final) {
 		numIn++
 	}
 	numFixed := len(args)
@@ -763,7 +777,7 @@
 		}
 	}
 	// Add final value if necessary.
-	if final != missingVal {
+	if !isMissing(final) {
 		t := typ.In(typ.NumIn() - 1)
 		if typ.IsVariadic() {
 			if numIn-1 < numFixed {
diff --git a/src/text/template/exec_test.go b/src/text/template/exec_test.go
index 56566b9..6b163f0 100644
--- a/src/text/template/exec_test.go
+++ b/src/text/template/exec_test.go
@@ -692,6 +692,8 @@
 	{"bug18a", "{{eq . '.'}}", "true", '.', true},
 	{"bug18b", "{{eq . 'e'}}", "true", 'e', true},
 	{"bug18c", "{{eq . 'P'}}", "true", 'P', true},
+
+	{"issue56490", "{{$i := 0}}{{$x := 0}}{{range $i = .AI}}{{end}}{{$i}}", "5", tVal, true},
 }
 
 func zeroArgs() string {
@@ -772,7 +774,7 @@
 }
 
 func testExecute(execTests []execTest, template *Template, t *testing.T) {
-	b := new(bytes.Buffer)
+	b := new(strings.Builder)
 	funcs := FuncMap{
 		"add":         add,
 		"count":       count,
@@ -861,7 +863,7 @@
 		if err != nil {
 			t.Fatalf("delim %q text %q parse err %s", left, text, err)
 		}
-		var b = new(bytes.Buffer)
+		var b = new(strings.Builder)
 		err = tmpl.Execute(b, value)
 		if err != nil {
 			t.Fatalf("delim %q exec err %s", left, err)
@@ -1024,7 +1026,7 @@
 	if err != nil {
 		t.Fatal("parse error:", err)
 	}
-	var b bytes.Buffer
+	var b strings.Builder
 	const expect = "[1[2[3[4]][5[6]]][7[8[9]][10[11]]]]"
 	// First by looking up the template.
 	err = tmpl.Lookup("tree").Execute(&b, tree)
@@ -1236,7 +1238,7 @@
 }
 
 func TestComparison(t *testing.T) {
-	b := new(bytes.Buffer)
+	b := new(strings.Builder)
 	var cmpStruct = struct {
 		Uthree, Ufour    uint
 		NegOne, Three    int
@@ -1284,7 +1286,7 @@
 	if err != nil {
 		t.Fatal(err)
 	}
-	var b bytes.Buffer
+	var b strings.Builder
 	// By default, just get "<no value>"
 	err = tmpl.Execute(&b, data)
 	if err != nil {
@@ -1454,7 +1456,7 @@
 		t.Fatal(err)
 	}
 
-	var buf bytes.Buffer
+	var buf strings.Builder
 	if err := tmpl.Execute(&buf, "hello"); err != nil {
 		t.Fatal(err)
 	}
@@ -1560,7 +1562,7 @@
 	}
 	for _, text := range texts {
 		tmpl := Must(New("tmpl").Parse(text))
-		var buf bytes.Buffer
+		var buf strings.Builder
 		err := tmpl.Execute(&buf, reflect.ValueOf([]V{{1}}))
 		if err != nil {
 			t.Fatalf("%s: Execute: %v", text, err)
@@ -1616,7 +1618,7 @@
 
 	for _, tt := range tests {
 		tmpl := Must(New("tmpl").Parse(tt.text))
-		var buf bytes.Buffer
+		var buf strings.Builder
 		err := tmpl.Execute(&buf, map[string]any{
 			"PlusOne": func(n int) int {
 				return n + 1
@@ -1709,7 +1711,7 @@
 // Issue 31810. Check that a parenthesized first argument behaves properly.
 func TestIssue31810(t *testing.T) {
 	// A simple value with no arguments is fine.
-	var b bytes.Buffer
+	var b strings.Builder
 	const text = "{{ (.)  }}"
 	tmpl, err := New("").Parse(text)
 	if err != nil {
diff --git a/src/text/template/funcs.go b/src/text/template/funcs.go
index 390d47e..dbea6e7 100644
--- a/src/text/template/funcs.go
+++ b/src/text/template/funcs.go
@@ -5,7 +5,6 @@
 package template
 
 import (
-	"bytes"
 	"errors"
 	"fmt"
 	"io"
@@ -438,7 +437,7 @@
 
 // isNil returns true if v is the zero reflect.Value, or nil of its type.
 func isNil(v reflect.Value) bool {
-	if v == zero {
+	if !v.IsValid() {
 		return true
 	}
 	switch v.Kind() {
@@ -642,7 +641,7 @@
 	if !strings.ContainsAny(s, "'\"&<>\000") {
 		return s
 	}
-	var b bytes.Buffer
+	var b strings.Builder
 	HTMLEscape(&b, []byte(s))
 	return b.String()
 }
@@ -725,7 +724,7 @@
 	if strings.IndexFunc(s, jsIsSpecial) < 0 {
 		return s
 	}
-	var b bytes.Buffer
+	var b strings.Builder
 	JSEscape(&b, []byte(s))
 	return b.String()
 }
diff --git a/src/text/template/multi_test.go b/src/text/template/multi_test.go
index 6b81ffe..63cd3f7 100644
--- a/src/text/template/multi_test.go
+++ b/src/text/template/multi_test.go
@@ -7,9 +7,9 @@
 // Tests for multiple-template parsing and execution.
 
 import (
-	"bytes"
 	"fmt"
 	"os"
+	"strings"
 	"testing"
 	"text/template/parse"
 )
@@ -242,7 +242,7 @@
 		}
 	}
 	// Execute root.
-	var b bytes.Buffer
+	var b strings.Builder
 	err = root.ExecuteTemplate(&b, "a", 0)
 	if err != nil {
 		t.Fatal(err)
@@ -281,7 +281,7 @@
 		t.Fatal(err)
 	}
 	// Execute.
-	var b bytes.Buffer
+	var b strings.Builder
 	err = added.ExecuteTemplate(&b, "a", 0)
 	if err != nil {
 		t.Fatal(err)
@@ -410,7 +410,7 @@
 				t.Fatal(err)
 			}
 		}
-		buf := &bytes.Buffer{}
+		buf := &strings.Builder{}
 		if err := m.Execute(buf, c.in); err != nil {
 			t.Error(i, err)
 			continue
@@ -445,7 +445,7 @@
 				t.Fatal(err)
 			}
 		}
-		var buf bytes.Buffer
+		var buf strings.Builder
 		res.Execute(&buf, 0)
 		if buf.String() != "stylesheet" {
 			t.Fatalf("iteration %d: got %q; expected %q", i, buf.String(), "stylesheet")
diff --git a/src/text/template/parse/lex.go b/src/text/template/parse/lex.go
index 29403dd..70fc86b 100644
--- a/src/text/template/parse/lex.go
+++ b/src/text/template/parse/lex.go
@@ -111,20 +111,26 @@
 
 // lexer holds the state of the scanner.
 type lexer struct {
-	name        string    // the name of the input; used only for error reports
-	input       string    // the string being scanned
-	leftDelim   string    // start of action
-	rightDelim  string    // end of action
-	emitComment bool      // emit itemComment tokens.
-	pos         Pos       // current position in the input
-	start       Pos       // start position of this item
-	atEOF       bool      // we have hit the end of input and returned eof
-	items       chan item // channel of scanned items
-	parenDepth  int       // nesting depth of ( ) exprs
-	line        int       // 1+number of newlines seen
-	startLine   int       // start line of this item
-	breakOK     bool      // break keyword allowed
-	continueOK  bool      // continue keyword allowed
+	name         string // the name of the input; used only for error reports
+	input        string // the string being scanned
+	leftDelim    string // start of action marker
+	rightDelim   string // end of action marker
+	pos          Pos    // current position in the input
+	start        Pos    // start position of this item
+	atEOF        bool   // we have hit the end of input and returned eof
+	parenDepth   int    // nesting depth of ( ) exprs
+	line         int    // 1+number of newlines seen
+	startLine    int    // start line of this item
+	item         item   // item to return to parser
+	insideAction bool   // are we inside an action?
+	options      lexOptions
+}
+
+// lexOptions control behavior of the lexer. All default to false.
+type lexOptions struct {
+	emitComment bool // emit itemComment tokens.
+	breakOK     bool // break keyword allowed
+	continueOK  bool // continue keyword allowed
 }
 
 // next returns the next rune in the input.
@@ -160,14 +166,29 @@
 	}
 }
 
-// emit passes an item back to the client.
-func (l *lexer) emit(t itemType) {
-	l.items <- item{t, l.start, l.input[l.start:l.pos], l.startLine}
+// thisItem returns the item at the current input point with the specified type
+// and advances the input.
+func (l *lexer) thisItem(t itemType) item {
+	i := item{t, l.start, l.input[l.start:l.pos], l.startLine}
 	l.start = l.pos
 	l.startLine = l.line
+	return i
+}
+
+// emit passes the trailing text as an item back to the parser.
+func (l *lexer) emit(t itemType) stateFn {
+	return l.emitItem(l.thisItem(t))
+}
+
+// emitItem passes the specified item to the parser.
+func (l *lexer) emitItem(i item) stateFn {
+	l.item = i
+	return nil
 }
 
 // ignore skips over the pending input before this point.
+// It tracks newlines in the ignored text, so use it only
+// for text that is skipped without calling l.next.
 func (l *lexer) ignore() {
 	l.line += strings.Count(l.input[l.start:l.pos], "\n")
 	l.start = l.pos
@@ -193,25 +214,31 @@
 // errorf returns an error token and terminates the scan by passing
 // back a nil pointer that will be the next state, terminating l.nextItem.
 func (l *lexer) errorf(format string, args ...any) stateFn {
-	l.items <- item{itemError, l.start, fmt.Sprintf(format, args...), l.startLine}
+	l.item = item{itemError, l.start, fmt.Sprintf(format, args...), l.startLine}
+	l.start = 0
+	l.pos = 0
+	l.input = l.input[:0]
 	return nil
 }
 
 // nextItem returns the next item from the input.
 // Called by the parser, not in the lexing goroutine.
 func (l *lexer) nextItem() item {
-	return <-l.items
-}
-
-// drain drains the output so the lexing goroutine will exit.
-// Called by the parser, not in the lexing goroutine.
-func (l *lexer) drain() {
-	for range l.items {
+	l.item = item{itemEOF, l.pos, "EOF", l.startLine}
+	state := lexText
+	if l.insideAction {
+		state = lexInsideAction
+	}
+	for {
+		state = state(l)
+		if state == nil {
+			return l.item
+		}
 	}
 }
 
 // lex creates a new scanner for the input string.
-func lex(name, input, left, right string, emitComment, breakOK, continueOK bool) *lexer {
+func lex(name, input, left, right string) *lexer {
 	if left == "" {
 		left = leftDelim
 	}
@@ -219,29 +246,17 @@
 		right = rightDelim
 	}
 	l := &lexer{
-		name:        name,
-		input:       input,
-		leftDelim:   left,
-		rightDelim:  right,
-		emitComment: emitComment,
-		breakOK:     breakOK,
-		continueOK:  continueOK,
-		items:       make(chan item),
-		line:        1,
-		startLine:   1,
+		name:         name,
+		input:        input,
+		leftDelim:    left,
+		rightDelim:   right,
+		line:         1,
+		startLine:    1,
+		insideAction: false,
 	}
-	go l.run()
 	return l
 }
 
-// run runs the state machine for the lexer.
-func (l *lexer) run() {
-	for state := lexText; state != nil; {
-		state = state(l)
-	}
-	close(l.items)
-}
-
 // state functions
 
 const (
@@ -254,29 +269,32 @@
 // lexText scans until an opening action delimiter, "{{".
 func lexText(l *lexer) stateFn {
 	if x := strings.Index(l.input[l.pos:], l.leftDelim); x >= 0 {
-		ldn := Pos(len(l.leftDelim))
-		l.pos += Pos(x)
-		trimLength := Pos(0)
-		if hasLeftTrimMarker(l.input[l.pos+ldn:]) {
-			trimLength = rightTrimLength(l.input[l.start:l.pos])
-		}
-		l.pos -= trimLength
-		if l.pos > l.start {
+		if x > 0 {
+			l.pos += Pos(x)
+			// Do we trim any trailing space?
+			trimLength := Pos(0)
+			delimEnd := l.pos + Pos(len(l.leftDelim))
+			if hasLeftTrimMarker(l.input[delimEnd:]) {
+				trimLength = rightTrimLength(l.input[l.start:l.pos])
+			}
+			l.pos -= trimLength
 			l.line += strings.Count(l.input[l.start:l.pos], "\n")
-			l.emit(itemText)
+			i := l.thisItem(itemText)
+			l.pos += trimLength
+			l.ignore()
+			if len(i.val) > 0 {
+				return l.emitItem(i)
+			}
 		}
-		l.pos += trimLength
-		l.ignore()
 		return lexLeftDelim
 	}
 	l.pos = Pos(len(l.input))
 	// Correctly reached EOF.
 	if l.pos > l.start {
 		l.line += strings.Count(l.input[l.start:l.pos], "\n")
-		l.emit(itemText)
+		return l.emit(itemText)
 	}
-	l.emit(itemEOF)
-	return nil
+	return l.emit(itemEOF)
 }
 
 // rightTrimLength returns the length of the spaces at the end of the string.
@@ -301,6 +319,7 @@
 }
 
 // lexLeftDelim scans the left delimiter, which is known to be present, possibly with a trim marker.
+// (The text to be trimmed has already been emitted.)
 func lexLeftDelim(l *lexer) stateFn {
 	l.pos += Pos(len(l.leftDelim))
 	trimSpace := hasLeftTrimMarker(l.input[l.pos:])
@@ -313,28 +332,27 @@
 		l.ignore()
 		return lexComment
 	}
-	l.emit(itemLeftDelim)
+	i := l.thisItem(itemLeftDelim)
+	l.insideAction = true
 	l.pos += afterMarker
 	l.ignore()
 	l.parenDepth = 0
-	return lexInsideAction
+	return l.emitItem(i)
 }
 
 // lexComment scans a comment. The left comment marker is known to be present.
 func lexComment(l *lexer) stateFn {
 	l.pos += Pos(len(leftComment))
-	i := strings.Index(l.input[l.pos:], rightComment)
-	if i < 0 {
+	x := strings.Index(l.input[l.pos:], rightComment)
+	if x < 0 {
 		return l.errorf("unclosed comment")
 	}
-	l.pos += Pos(i + len(rightComment))
+	l.pos += Pos(x + len(rightComment))
 	delim, trimSpace := l.atRightDelim()
 	if !delim {
 		return l.errorf("comment ends before closing delimiter")
 	}
-	if l.emitComment {
-		l.emit(itemComment)
-	}
+	i := l.thisItem(itemComment)
 	if trimSpace {
 		l.pos += trimMarkerLen
 	}
@@ -343,23 +361,27 @@
 		l.pos += leftTrimLength(l.input[l.pos:])
 	}
 	l.ignore()
+	if l.options.emitComment {
+		return l.emitItem(i)
+	}
 	return lexText
 }
 
 // lexRightDelim scans the right delimiter, which is known to be present, possibly with a trim marker.
 func lexRightDelim(l *lexer) stateFn {
-	trimSpace := hasRightTrimMarker(l.input[l.pos:])
+	_, trimSpace := l.atRightDelim()
 	if trimSpace {
 		l.pos += trimMarkerLen
 		l.ignore()
 	}
 	l.pos += Pos(len(l.rightDelim))
-	l.emit(itemRightDelim)
+	i := l.thisItem(itemRightDelim)
 	if trimSpace {
 		l.pos += leftTrimLength(l.input[l.pos:])
 		l.ignore()
 	}
-	return lexText
+	l.insideAction = false
+	return l.emitItem(i)
 }
 
 // lexInsideAction scans the elements inside action delimiters.
@@ -381,14 +403,14 @@
 		l.backup() // Put space back in case we have " -}}".
 		return lexSpace
 	case r == '=':
-		l.emit(itemAssign)
+		return l.emit(itemAssign)
 	case r == ':':
 		if l.next() != '=' {
 			return l.errorf("expected :=")
 		}
-		l.emit(itemDeclare)
+		return l.emit(itemDeclare)
 	case r == '|':
-		l.emit(itemPipe)
+		return l.emit(itemPipe)
 	case r == '"':
 		return lexQuote
 	case r == '`':
@@ -413,20 +435,19 @@
 		l.backup()
 		return lexIdentifier
 	case r == '(':
-		l.emit(itemLeftParen)
 		l.parenDepth++
+		return l.emit(itemLeftParen)
 	case r == ')':
-		l.emit(itemRightParen)
 		l.parenDepth--
 		if l.parenDepth < 0 {
-			return l.errorf("unexpected right paren %#U", r)
+			return l.errorf("unexpected right paren")
 		}
+		return l.emit(itemRightParen)
 	case r <= unicode.MaxASCII && unicode.IsPrint(r):
-		l.emit(itemChar)
+		return l.emit(itemChar)
 	default:
 		return l.errorf("unrecognized character in action: %#U", r)
 	}
-	return lexInsideAction
 }
 
 // lexSpace scans a run of space characters.
@@ -451,13 +472,11 @@
 			return lexRightDelim // On the delim, so go right to that.
 		}
 	}
-	l.emit(itemSpace)
-	return lexInsideAction
+	return l.emit(itemSpace)
 }
 
 // lexIdentifier scans an alphanumeric.
 func lexIdentifier(l *lexer) stateFn {
-Loop:
 	for {
 		switch r := l.next(); {
 		case isAlphaNumeric(r):
@@ -471,22 +490,19 @@
 			switch {
 			case key[word] > itemKeyword:
 				item := key[word]
-				if item == itemBreak && !l.breakOK || item == itemContinue && !l.continueOK {
-					l.emit(itemIdentifier)
-				} else {
-					l.emit(item)
+				if item == itemBreak && !l.options.breakOK || item == itemContinue && !l.options.continueOK {
+					return l.emit(itemIdentifier)
 				}
+				return l.emit(item)
 			case word[0] == '.':
-				l.emit(itemField)
+				return l.emit(itemField)
 			case word == "true", word == "false":
-				l.emit(itemBool)
+				return l.emit(itemBool)
 			default:
-				l.emit(itemIdentifier)
+				return l.emit(itemIdentifier)
 			}
-			break Loop
 		}
 	}
-	return lexInsideAction
 }
 
 // lexField scans a field: .Alphanumeric.
@@ -499,22 +515,19 @@
 // The $ has been scanned.
 func lexVariable(l *lexer) stateFn {
 	if l.atTerminator() { // Nothing interesting follows -> "$".
-		l.emit(itemVariable)
-		return lexInsideAction
+		return l.emit(itemVariable)
 	}
 	return lexFieldOrVariable(l, itemVariable)
 }
 
-// lexVariable scans a field or variable: [.$]Alphanumeric.
+// lexFieldOrVariable scans a field or variable: [.$]Alphanumeric.
 // The . or $ has been scanned.
 func lexFieldOrVariable(l *lexer, typ itemType) stateFn {
 	if l.atTerminator() { // Nothing interesting follows -> "." or "$".
 		if typ == itemVariable {
-			l.emit(itemVariable)
-		} else {
-			l.emit(itemDot)
+			return l.emit(itemVariable)
 		}
-		return lexInsideAction
+		return l.emit(itemDot)
 	}
 	var r rune
 	for {
@@ -527,8 +540,7 @@
 	if !l.atTerminator() {
 		return l.errorf("bad character %#U", r)
 	}
-	l.emit(typ)
-	return lexInsideAction
+	return l.emit(typ)
 }
 
 // atTerminator reports whether the input is at valid termination character to
@@ -564,8 +576,7 @@
 			break Loop
 		}
 	}
-	l.emit(itemCharConstant)
-	return lexInsideAction
+	return l.emit(itemCharConstant)
 }
 
 // lexNumber scans a number: decimal, octal, hex, float, or imaginary. This
@@ -581,11 +592,9 @@
 		if !l.scanNumber() || l.input[l.pos-1] != 'i' {
 			return l.errorf("bad number syntax: %q", l.input[l.start:l.pos])
 		}
-		l.emit(itemComplex)
-	} else {
-		l.emit(itemNumber)
+		return l.emit(itemComplex)
 	}
-	return lexInsideAction
+	return l.emit(itemNumber)
 }
 
 func (l *lexer) scanNumber() bool {
@@ -641,8 +650,7 @@
 			break Loop
 		}
 	}
-	l.emit(itemString)
-	return lexInsideAction
+	return l.emit(itemString)
 }
 
 // lexRawQuote scans a raw quoted string.
@@ -656,8 +664,7 @@
 			break Loop
 		}
 	}
-	l.emit(itemRawString)
-	return lexInsideAction
+	return l.emit(itemRawString)
 }
 
 // isSpace reports whether r is a space character.
diff --git a/src/text/template/parse/lex_test.go b/src/text/template/parse/lex_test.go
index c5f4296..d47f10f 100644
--- a/src/text/template/parse/lex_test.go
+++ b/src/text/template/parse/lex_test.go
@@ -359,8 +359,7 @@
 	{"extra right paren", "{{3)}}", []item{
 		tLeft,
 		mkItem(itemNumber, "3"),
-		tRpar,
-		mkItem(itemError, `unexpected right paren U+0029 ')'`),
+		mkItem(itemError, "unexpected right paren"),
 	}},
 
 	// Fixed bugs
@@ -394,7 +393,12 @@
 
 // collect gathers the emitted items into a slice.
 func collect(t *lexTest, left, right string) (items []item) {
-	l := lex(t.name, t.input, left, right, true, true, true)
+	l := lex(t.name, t.input, left, right)
+	l.options = lexOptions{
+		emitComment: true,
+		breakOK:     true,
+		continueOK:  true,
+	}
 	for {
 		item := l.nextItem()
 		items = append(items, item)
@@ -431,7 +435,9 @@
 		items := collect(&test, "", "")
 		if !equal(items, test.items, false) {
 			t.Errorf("%s: got\n\t%+v\nexpected\n\t%v", test.name, items, test.items)
+			return // TODO
 		}
+		t.Log(test.name, "OK")
 	}
 }
 
@@ -485,6 +491,23 @@
 	}
 }
 
+func TestDelimsAndMarkers(t *testing.T) {
+	test := lexTest{"delims that look like markers", "{{- .x -}} {{- - .x - -}}", []item{
+		mkItem(itemLeftDelim, "{{- "),
+		mkItem(itemField, ".x"),
+		mkItem(itemRightDelim, " -}}"),
+		mkItem(itemLeftDelim, "{{- "),
+		mkItem(itemField, ".x"),
+		mkItem(itemRightDelim, " -}}"),
+		tEOF,
+	}}
+	items := collect(&test, "{{- ", " -}}")
+
+	if !equal(items, test.items, false) {
+		t.Errorf("%s: got\n\t%v\nexpected\n\t%v", test.name, items, test.items)
+	}
+}
+
 var lexPosTests = []lexTest{
 	{"empty", "", []item{{itemEOF, 0, "", 1}}},
 	{"punctuation", "{{,@%#}}", []item{
@@ -546,22 +569,6 @@
 	}
 }
 
-// Test that an error shuts down the lexing goroutine.
-func TestShutdown(t *testing.T) {
-	// We need to duplicate template.Parse here to hold on to the lexer.
-	const text = "erroneous{{define}}{{else}}1234"
-	lexer := lex("foo", text, "{{", "}}", false, true, true)
-	_, err := New("root").parseLexer(lexer)
-	if err == nil {
-		t.Fatalf("expected error")
-	}
-	// The error should have drained the input. Therefore, the lexer should be shut down.
-	token, ok := <-lexer.items
-	if ok {
-		t.Fatalf("input was not drained; got %v", token)
-	}
-}
-
 // parseLexer is a local version of parse that lets us pass in the lexer instead of building it.
 // We expect an error, so the tree set and funcs list are explicitly nil.
 func (t *Tree) parseLexer(lex *lexer) (tree *Tree, err error) {
diff --git a/src/text/template/parse/parse.go b/src/text/template/parse/parse.go
index 00c258a..d43d533 100644
--- a/src/text/template/parse/parse.go
+++ b/src/text/template/parse/parse.go
@@ -210,7 +210,6 @@
 			panic(e)
 		}
 		if t != nil {
-			t.lex.drain()
 			t.stopParse()
 		}
 		*errp = e.(error)
@@ -224,6 +223,11 @@
 	t.vars = []string{"$"}
 	t.funcs = funcs
 	t.treeSet = treeSet
+	lex.options = lexOptions{
+		emitComment: t.Mode&ParseComments != 0,
+		breakOK:     !t.hasFunction("break"),
+		continueOK:  !t.hasFunction("continue"),
+	}
 }
 
 // stopParse terminates parsing.
@@ -241,10 +245,7 @@
 func (t *Tree) Parse(text, leftDelim, rightDelim string, treeSet map[string]*Tree, funcs ...map[string]any) (tree *Tree, err error) {
 	defer t.recover(&err)
 	t.ParseName = t.Name
-	emitComment := t.Mode&ParseComments != 0
-	breakOK := !t.hasFunction("break")
-	continueOK := !t.hasFunction("continue")
-	lexer := lex(t.Name, text, leftDelim, rightDelim, emitComment, breakOK, continueOK)
+	lexer := lex(t.Name, text, leftDelim, rightDelim)
 	t.startParse(funcs, lexer, treeSet)
 	t.text = text
 	t.parse()
diff --git a/src/text/template/parse/parse_test.go b/src/text/template/parse/parse_test.go
index fdb25d7..59e0a17 100644
--- a/src/text/template/parse/parse_test.go
+++ b/src/text/template/parse/parse_test.go
@@ -391,6 +391,36 @@
 	}
 }
 
+func TestKeywordsAndFuncs(t *testing.T) {
+	// Check collisions between functions and new keywords like 'break'. When a
+	// break function is provided, the parser should treat 'break' as a function,
+	// not a keyword.
+	textFormat = "%q"
+	defer func() { textFormat = "%s" }()
+
+	inp := `{{range .X}}{{break 20}}{{end}}`
+	{
+		// 'break' is a defined function, don't treat it as a keyword: it should
+		// accept an argument successfully.
+		var funcsWithKeywordFunc = map[string]any{
+			"break": func(in any) any { return in },
+		}
+		tmpl, err := New("").Parse(inp, "", "", make(map[string]*Tree), funcsWithKeywordFunc)
+		if err != nil || tmpl == nil {
+			t.Errorf("with break func: unexpected error: %v", err)
+		}
+	}
+
+	{
+		// No function called 'break'; treat it as a keyword. Results in a parse
+		// error.
+		tmpl, err := New("").Parse(inp, "", "", make(map[string]*Tree), make(map[string]any))
+		if err == nil || tmpl != nil {
+			t.Errorf("without break func: expected error; got none")
+		}
+	}
+}
+
 func TestSkipFuncCheck(t *testing.T) {
 	oldTextFormat := textFormat
 	textFormat = "%q"
@@ -489,7 +519,7 @@
 		hasError, `unclosed left paren`},
 	{"rparen",
 		"{{.X 1 2 3 ) }}",
-		hasError, `unexpected ")" in command`},
+		hasError, "unexpected right paren"},
 	{"rparen2",
 		"{{(.X 1 2 3",
 		hasError, `unclosed action`},
@@ -597,7 +627,8 @@
 }
 
 func TestLineNum(t *testing.T) {
-	const count = 100
+	// const count = 100
+	const count = 3
 	text := strings.Repeat("{{printf 1234}}\n", count)
 	tree, err := New("bench").Parse(text, "", "", make(map[string]*Tree), builtins)
 	if err != nil {
@@ -611,11 +642,11 @@
 		// Action first.
 		action := nodes[i].(*ActionNode)
 		if action.Line != line {
-			t.Fatalf("line %d: action is line %d", line, action.Line)
+			t.Errorf("line %d: action is line %d", line, action.Line)
 		}
 		pipe := action.Pipe
 		if pipe.Line != line {
-			t.Fatalf("line %d: pipe is line %d", line, pipe.Line)
+			t.Errorf("line %d: pipe is line %d", line, pipe.Line)
 		}
 	}
 }
diff --git a/src/time/export_test.go b/src/time/export_test.go
index b450aec..a4940d1 100644
--- a/src/time/export_test.go
+++ b/src/time/export_test.go
@@ -132,3 +132,9 @@
 }
 
 var Quote = quote
+
+var AppendInt = appendInt
+var AppendFormatAny = Time.appendFormat
+var AppendFormatRFC3339 = Time.appendFormatRFC3339
+var ParseAny = parse
+var ParseRFC3339 = parseRFC3339[string]
diff --git a/src/time/format.go b/src/time/format.go
index 8431ff8..f94d68e 100644
--- a/src/time/format.go
+++ b/src/time/format.go
@@ -116,6 +116,9 @@
 	StampMilli = "Jan _2 15:04:05.000"
 	StampMicro = "Jan _2 15:04:05.000000"
 	StampNano  = "Jan _2 15:04:05.000000000"
+	DateTime   = "2006-01-02 15:04:05"
+	DateOnly   = "2006-01-02"
+	TimeOnly   = "15:04:05"
 )
 
 const (
@@ -400,39 +403,61 @@
 		u = uint(-x)
 	}
 
-	// Assemble decimal in reverse order.
-	var buf [20]byte
-	i := len(buf)
-	for u >= 10 {
-		i--
-		q := u / 10
-		buf[i] = byte('0' + u - q*10)
-		u = q
+	// 2-digit and 4-digit fields are the most common in time formats.
+	utod := func(u uint) byte { return '0' + byte(u) }
+	switch {
+	case width == 2 && u < 1e2:
+		return append(b, utod(u/1e1), utod(u%1e1))
+	case width == 4 && u < 1e4:
+		return append(b, utod(u/1e3), utod(u/1e2%1e1), utod(u/1e1%1e1), utod(u%1e1))
 	}
-	i--
-	buf[i] = byte('0' + u)
+
+	// Compute the number of decimal digits.
+	var n int
+	if u == 0 {
+		n = 1
+	}
+	for u2 := u; u2 > 0; u2 /= 10 {
+		n++
+	}
 
 	// Add 0-padding.
-	for w := len(buf) - i; w < width; w++ {
+	for pad := width - n; pad > 0; pad-- {
 		b = append(b, '0')
 	}
 
-	return append(b, buf[i:]...)
+	// Ensure capacity.
+	if len(b)+n <= cap(b) {
+		b = b[:len(b)+n]
+	} else {
+		b = append(b, make([]byte, n)...)
+	}
+
+	// Assemble decimal in reverse order.
+	i := len(b) - 1
+	for u >= 10 && i > 0 {
+		q := u / 10
+		b[i] = utod(u - q*10)
+		u = q
+		i--
+	}
+	b[i] = utod(u)
+	return b
 }
 
 // Never printed, just needs to be non-nil for return by atoi.
 var atoiError = errors.New("time: invalid number")
 
 // Duplicates functionality in strconv, but avoids dependency.
-func atoi(s string) (x int, err error) {
+func atoi[bytes []byte | string](s bytes) (x int, err error) {
 	neg := false
-	if s != "" && (s[0] == '-' || s[0] == '+') {
+	if len(s) > 0 && (s[0] == '-' || s[0] == '+') {
 		neg = s[0] == '-'
 		s = s[1:]
 	}
 	q, rem, err := leadingInt(s)
 	x = int(q)
-	if err != nil || rem != "" {
+	if err != nil || len(rem) > 0 {
 		return 0, atoiError
 	}
 	if neg {
@@ -441,7 +466,7 @@
 	return x, nil
 }
 
-// The "std" value passed to formatNano contains two packed fields: the number of
+// The "std" value passed to appendNano contains two packed fields: the number of
 // digits after the decimal and the separator character (period or comma).
 // These functions pack and unpack that variable.
 func stdFracSecond(code, n, c int) int {
@@ -463,35 +488,29 @@
 	return ','
 }
 
-// formatNano appends a fractional second, as nanoseconds, to b
-// and returns the result.
-func formatNano(b []byte, nanosec uint, std int) []byte {
-	var (
-		n         = digitsLen(std)
-		separator = separator(std)
-		trim      = std&stdMask == stdFracSecond9
-	)
-	u := nanosec
-	var buf [9]byte
-	for start := len(buf); start > 0; {
-		start--
-		buf[start] = byte(u%10 + '0')
-		u /= 10
+// appendNano appends a fractional second, as nanoseconds, to b
+// and returns the result. The nanosec must be within [0, 999999999].
+func appendNano(b []byte, nanosec int, std int) []byte {
+	trim := std&stdMask == stdFracSecond9
+	n := digitsLen(std)
+	if trim && (n == 0 || nanosec == 0) {
+		return b
 	}
-
-	if n > 9 {
-		n = 9
+	dot := separator(std)
+	b = append(b, dot)
+	b = appendInt(b, nanosec, 9)
+	if n < 9 {
+		b = b[:len(b)-9+n]
 	}
 	if trim {
-		for n > 0 && buf[n-1] == '0' {
-			n--
+		for len(b) > 0 && b[len(b)-1] == '0' {
+			b = b[:len(b)-1]
 		}
-		if n == 0 {
-			return b
+		if len(b) > 0 && b[len(b)-1] == dot {
+			b = b[:len(b)-1]
 		}
 	}
-	b = append(b, separator)
-	return append(b, buf[:n]...)
+	return b
 }
 
 // String returns the time formatted using the format string
@@ -537,26 +556,29 @@
 // GoString implements fmt.GoStringer and formats t to be printed in Go source
 // code.
 func (t Time) GoString() string {
-	buf := make([]byte, 0, 70)
+	abs := t.abs()
+	year, month, day, _ := absDate(abs, true)
+	hour, minute, second := absClock(abs)
+
+	buf := make([]byte, 0, len("time.Date(9999, time.September, 31, 23, 59, 59, 999999999, time.Local)"))
 	buf = append(buf, "time.Date("...)
-	buf = appendInt(buf, t.Year(), 0)
-	month := t.Month()
+	buf = appendInt(buf, year, 0)
 	if January <= month && month <= December {
 		buf = append(buf, ", time."...)
-		buf = append(buf, t.Month().String()...)
+		buf = append(buf, longMonthNames[month-1]...)
 	} else {
 		// It's difficult to construct a time.Time with a date outside the
 		// standard range but we might as well try to handle the case.
 		buf = appendInt(buf, int(month), 0)
 	}
 	buf = append(buf, ", "...)
-	buf = appendInt(buf, t.Day(), 0)
+	buf = appendInt(buf, day, 0)
 	buf = append(buf, ", "...)
-	buf = appendInt(buf, t.Hour(), 0)
+	buf = appendInt(buf, hour, 0)
 	buf = append(buf, ", "...)
-	buf = appendInt(buf, t.Minute(), 0)
+	buf = appendInt(buf, minute, 0)
 	buf = append(buf, ", "...)
-	buf = appendInt(buf, t.Second(), 0)
+	buf = appendInt(buf, second, 0)
 	buf = append(buf, ", "...)
 	buf = appendInt(buf, t.Nanosecond(), 0)
 	buf = append(buf, ", "...)
@@ -582,8 +604,8 @@
 		// Of these, Location(loc.name) is the least disruptive. This is an edge
 		// case we hope not to hit too often.
 		buf = append(buf, `time.Location(`...)
-		buf = append(buf, []byte(quote(loc.name))...)
-		buf = append(buf, `)`...)
+		buf = append(buf, quote(loc.name)...)
+		buf = append(buf, ')')
 	}
 	buf = append(buf, ')')
 	return string(buf)
@@ -612,6 +634,18 @@
 // AppendFormat is like Format but appends the textual
 // representation to b and returns the extended buffer.
 func (t Time) AppendFormat(b []byte, layout string) []byte {
+	// Optimize for RFC3339 as it accounts for over half of all representations.
+	switch layout {
+	case RFC3339:
+		return t.appendFormatRFC3339(b, false)
+	case RFC3339Nano:
+		return t.appendFormatRFC3339(b, true)
+	default:
+		return t.appendFormat(b, layout)
+	}
+}
+
+func (t Time) appendFormat(b []byte, layout string) []byte {
 	var (
 		name, offset, abs = t.locabs()
 
@@ -623,6 +657,7 @@
 		min   int
 		sec   int
 	)
+
 	// Each iteration generates one std value.
 	for layout != "" {
 		prefix, std, suffix := nextStdChunk(layout)
@@ -772,7 +807,7 @@
 			b = appendInt(b, zone/60, 2)
 			b = appendInt(b, zone%60, 2)
 		case stdFracSecond0, stdFracSecond9:
-			b = formatNano(b, uint(t.Nanosecond()), std)
+			b = appendNano(b, t.Nanosecond(), std)
 		}
 	}
 	return b
@@ -789,6 +824,20 @@
 	Message    string
 }
 
+// newParseError creates a new ParseError.
+// The provided value and valueElem are cloned to avoid escaping their values.
+func newParseError(layout, value, layoutElem, valueElem, message string) *ParseError {
+	valueCopy := cloneString(value)
+	valueElemCopy := cloneString(valueElem)
+	return &ParseError{layout, valueCopy, layoutElem, valueElemCopy, message}
+}
+
+// cloneString returns a string copy of s.
+// Do not use strings.Clone to avoid dependency on strings package.
+func cloneString(s string) string {
+	return string([]byte(s))
+}
+
 // These are borrowed from unicode/utf8 and strconv and replicate behavior in
 // that package, since we can't take a dependency on either.
 const (
@@ -847,7 +896,7 @@
 }
 
 // isDigit reports whether s[i] is in range and is a decimal digit.
-func isDigit(s string, i int) bool {
+func isDigit[bytes []byte | string](s bytes, i int) bool {
 	if len(s) <= i {
 		return false
 	}
@@ -956,6 +1005,12 @@
 // differ by the actual zone offset. To avoid such problems, prefer time layouts
 // that use a numeric zone offset, or use ParseInLocation.
 func Parse(layout, value string) (Time, error) {
+	// Optimize for RFC3339 as it accounts for over half of all representations.
+	if layout == RFC3339 || layout == RFC3339Nano {
+		if t, ok := parseRFC3339(value, Local); ok {
+			return t, nil
+		}
+	}
 	return parse(layout, value, UTC, Local)
 }
 
@@ -965,6 +1020,12 @@
 // Second, when given a zone offset or abbreviation, Parse tries to match it
 // against the Local location; ParseInLocation uses the given location.
 func ParseInLocation(layout, value string, loc *Location) (Time, error) {
+	// Optimize for RFC3339 as it accounts for over half of all representations.
+	if layout == RFC3339 || layout == RFC3339Nano {
+		if t, ok := parseRFC3339(value, loc); ok {
+			return t, nil
+		}
+	}
 	return parse(layout, value, loc, loc)
 }
 
@@ -996,28 +1057,29 @@
 		stdstr := layout[len(prefix) : len(layout)-len(suffix)]
 		value, err = skip(value, prefix)
 		if err != nil {
-			return Time{}, &ParseError{alayout, avalue, prefix, value, ""}
+			return Time{}, newParseError(alayout, avalue, prefix, value, "")
 		}
 		if std == 0 {
 			if len(value) != 0 {
-				return Time{}, &ParseError{alayout, avalue, "", value, ": extra text: " + quote(value)}
+				return Time{}, newParseError(alayout, avalue, "", value, ": extra text: "+quote(value))
 			}
 			break
 		}
 		layout = suffix
 		var p string
+		hold := value
 		switch std & stdMask {
 		case stdYear:
 			if len(value) < 2 {
 				err = errBad
 				break
 			}
-			hold := value
 			p, value = value[0:2], value[2:]
 			year, err = atoi(p)
 			if err != nil {
-				value = hold
-			} else if year >= 69 { // Unix time starts Dec 31 1969 in some time zones
+				break
+			}
+			if year >= 69 { // Unix time starts Dec 31 1969 in some time zones
 				year += 1900
 			} else {
 				year += 2000
@@ -1078,6 +1140,9 @@
 			}
 		case stdSecond, stdZeroSecond:
 			sec, value, err = getnum(value, std == stdZeroSecond)
+			if err != nil {
+				break
+			}
 			if sec < 0 || 60 <= sec {
 				rangeErrString = "second"
 				break
@@ -1173,12 +1238,12 @@
 				sign, hour, min, seconds, value = value[0:1], value[1:3], value[3:5], "00", value[5:]
 			}
 			var hr, mm, ss int
-			hr, err = atoi(hour)
+			hr, _, err = getnum(hour, true)
 			if err == nil {
-				mm, err = atoi(min)
+				mm, _, err = getnum(min, true)
 			}
 			if err == nil {
-				ss, err = atoi(seconds)
+				ss, _, err = getnum(seconds, true)
 			}
 			zoneOffset = (hr*60+mm)*60 + ss // offset is in seconds
 			switch sign[0] {
@@ -1221,17 +1286,17 @@
 			// Take any number of digits, even more than asked for,
 			// because it is what the stdSecond case would do.
 			i := 0
-			for i < 9 && i+1 < len(value) && '0' <= value[i+1] && value[i+1] <= '9' {
+			for i+1 < len(value) && '0' <= value[i+1] && value[i+1] <= '9' {
 				i++
 			}
 			nsec, rangeErrString, err = parseNanoseconds(value, 1+i)
 			value = value[1+i:]
 		}
 		if rangeErrString != "" {
-			return Time{}, &ParseError{alayout, avalue, stdstr, value, ": " + rangeErrString + " out of range"}
+			return Time{}, newParseError(alayout, avalue, stdstr, value, ": "+rangeErrString+" out of range")
 		}
 		if err != nil {
-			return Time{}, &ParseError{alayout, avalue, stdstr, value, ""}
+			return Time{}, newParseError(alayout, avalue, stdstr, hold, "")
 		}
 	}
 	if pmSet && hour < 12 {
@@ -1253,7 +1318,7 @@
 			}
 		}
 		if yday < 1 || yday > 365 {
-			return Time{}, &ParseError{alayout, avalue, "", value, ": day-of-year out of range"}
+			return Time{}, newParseError(alayout, avalue, "", value, ": day-of-year out of range")
 		}
 		if m == 0 {
 			m = (yday-1)/31 + 1
@@ -1265,11 +1330,11 @@
 		// If month, day already seen, yday's m, d must match.
 		// Otherwise, set them from m, d.
 		if month >= 0 && month != m {
-			return Time{}, &ParseError{alayout, avalue, "", value, ": day-of-year does not match month"}
+			return Time{}, newParseError(alayout, avalue, "", value, ": day-of-year does not match month")
 		}
 		month = m
 		if day >= 0 && day != d {
-			return Time{}, &ParseError{alayout, avalue, "", value, ": day-of-year does not match day"}
+			return Time{}, newParseError(alayout, avalue, "", value, ": day-of-year does not match day")
 		}
 		day = d
 	} else {
@@ -1283,7 +1348,7 @@
 
 	// Validate the day of the month.
 	if day < 1 || day > daysIn(Month(month), year) {
-		return Time{}, &ParseError{alayout, avalue, "", value, ": day out of range"}
+		return Time{}, newParseError(alayout, avalue, "", value, ": day out of range")
 	}
 
 	if z != nil {
@@ -1303,7 +1368,8 @@
 		}
 
 		// Otherwise create fake zone to record offset.
-		t.setLoc(FixedZone(zoneName, zoneOffset))
+		zoneNameCopy := cloneString(zoneName) // avoid leaking the input value
+		t.setLoc(FixedZone(zoneNameCopy, zoneOffset))
 		return t, nil
 	}
 
@@ -1323,7 +1389,8 @@
 			offset, _ = atoi(zoneName[3:]) // Guaranteed OK by parseGMT.
 			offset *= 3600
 		}
-		t.setLoc(FixedZone(zoneName, offset))
+		zoneNameCopy := cloneString(zoneName) // avoid leaking the input value
+		t.setLoc(FixedZone(zoneNameCopy, offset))
 		return t, nil
 	}
 
@@ -1402,7 +1469,7 @@
 
 // parseSignedOffset parses a signed timezone offset (e.g. "+03" or "-04").
 // The function checks for a signed number in the range -23 through +23 excluding zero.
-// Returns length of the found offset string or 0 otherwise
+// Returns length of the found offset string or 0 otherwise.
 func parseSignedOffset(value string) int {
 	sign := value[0]
 	if sign != '-' && sign != '+' {
@@ -1424,7 +1491,7 @@
 	return b == '.' || b == ','
 }
 
-func parseNanoseconds(value string, nbytes int) (ns int, rangeErrString string, err error) {
+func parseNanoseconds[bytes []byte | string](value bytes, nbytes int) (ns int, rangeErrString string, err error) {
 	if !commaOrPeriod(value[0]) {
 		err = errBad
 		return
@@ -1452,7 +1519,7 @@
 var errLeadingInt = errors.New("time: bad [0-9]*") // never printed
 
 // leadingInt consumes the leading [0-9]* from s.
-func leadingInt(s string) (x uint64, rem string, err error) {
+func leadingInt[bytes []byte | string](s bytes) (x uint64, rem bytes, err error) {
 	i := 0
 	for ; i < len(s); i++ {
 		c := s[i]
@@ -1461,12 +1528,12 @@
 		}
 		if x > 1<<63/10 {
 			// overflow
-			return 0, "", errLeadingInt
+			return 0, rem, errLeadingInt
 		}
 		x = x*10 + uint64(c) - '0'
 		if x > 1<<63 {
 			// overflow
-			return 0, "", errLeadingInt
+			return 0, rem, errLeadingInt
 		}
 	}
 	return x, s[i:], nil
diff --git a/src/time/format_rfc3339.go b/src/time/format_rfc3339.go
new file mode 100644
index 0000000..1151666
--- /dev/null
+++ b/src/time/format_rfc3339.go
@@ -0,0 +1,188 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package time
+
+import "errors"
+
+// RFC 3339 is the most commonly used format.
+//
+// It is implicitly used by the Time.(Marshal|Unmarshal)(Text|JSON) methods.
+// Also, according to analysis on https://go.dev/issue/52746,
+// RFC 3339 accounts for 57% of all explicitly specified time formats,
+// with the second most popular format only being used 8% of the time.
+// The overwhelming use of RFC 3339 compared to all other formats justifies
+// the addition of logic to optimize formatting and parsing.
+
+func (t Time) appendFormatRFC3339(b []byte, nanos bool) []byte {
+	_, offset, abs := t.locabs()
+
+	// Format date.
+	year, month, day, _ := absDate(abs, true)
+	b = appendInt(b, year, 4)
+	b = append(b, '-')
+	b = appendInt(b, int(month), 2)
+	b = append(b, '-')
+	b = appendInt(b, day, 2)
+
+	b = append(b, 'T')
+
+	// Format time.
+	hour, min, sec := absClock(abs)
+	b = appendInt(b, hour, 2)
+	b = append(b, ':')
+	b = appendInt(b, min, 2)
+	b = append(b, ':')
+	b = appendInt(b, sec, 2)
+
+	if nanos {
+		std := stdFracSecond(stdFracSecond9, 9, '.')
+		b = appendNano(b, t.Nanosecond(), std)
+	}
+
+	if offset == 0 {
+		return append(b, 'Z')
+	}
+
+	// Format zone.
+	zone := offset / 60 // convert to minutes
+	if zone < 0 {
+		b = append(b, '-')
+		zone = -zone
+	} else {
+		b = append(b, '+')
+	}
+	b = appendInt(b, zone/60, 2)
+	b = append(b, ':')
+	b = appendInt(b, zone%60, 2)
+	return b
+}
+
+func (t Time) appendStrictRFC3339(b []byte) ([]byte, error) {
+	n0 := len(b)
+	b = t.appendFormatRFC3339(b, true)
+
+	// Not all valid Go timestamps can be serialized as valid RFC 3339.
+	// Explicitly check for these edge cases.
+	// See https://go.dev/issue/4556 and https://go.dev/issue/54580.
+	num2 := func(b []byte) byte { return 10*(b[0]-'0') + (b[1] - '0') }
+	switch {
+	case b[n0+len("9999")] != '-': // year must be exactly 4 digits wide
+		return b, errors.New("year outside of range [0,9999]")
+	case b[len(b)-1] != 'Z':
+		c := b[len(b)-len("Z07:00")]
+		if ('0' <= c && c <= '9') || num2(b[len(b)-len("07:00"):]) >= 24 {
+			return b, errors.New("timezone hour outside of range [0,23]")
+		}
+	}
+	return b, nil
+}
+
+func parseRFC3339[bytes []byte | string](s bytes, local *Location) (Time, bool) {
+	// parseUint parses s as an unsigned decimal integer and
+	// verifies that it is within some range.
+	// If it is invalid or out-of-range,
+	// it sets ok to false and returns the min value.
+	ok := true
+	parseUint := func(s bytes, min, max int) (x int) {
+		for _, c := range []byte(s) {
+			if c < '0' || '9' < c {
+				ok = false
+				return min
+			}
+			x = x*10 + int(c) - '0'
+		}
+		if x < min || max < x {
+			ok = false
+			return min
+		}
+		return x
+	}
+
+	// Parse the date and time.
+	if len(s) < len("2006-01-02T15:04:05") {
+		return Time{}, false
+	}
+	year := parseUint(s[0:4], 0, 9999)                       // e.g., 2006
+	month := parseUint(s[5:7], 1, 12)                        // e.g., 01
+	day := parseUint(s[8:10], 1, daysIn(Month(month), year)) // e.g., 02
+	hour := parseUint(s[11:13], 0, 23)                       // e.g., 15
+	min := parseUint(s[14:16], 0, 59)                        // e.g., 04
+	sec := parseUint(s[17:19], 0, 59)                        // e.g., 05
+	if !ok || !(s[4] == '-' && s[7] == '-' && s[10] == 'T' && s[13] == ':' && s[16] == ':') {
+		return Time{}, false
+	}
+	s = s[19:]
+
+	// Parse the fractional second.
+	var nsec int
+	if len(s) >= 2 && s[0] == '.' && isDigit(s, 1) {
+		n := 2
+		for ; n < len(s) && isDigit(s, n); n++ {
+		}
+		nsec, _, _ = parseNanoseconds(s, n)
+		s = s[n:]
+	}
+
+	// Parse the time zone.
+	t := Date(year, Month(month), day, hour, min, sec, nsec, UTC)
+	if len(s) != 1 || s[0] != 'Z' {
+		if len(s) != len("-07:00") {
+			return Time{}, false
+		}
+		hr := parseUint(s[1:3], 0, 23) // e.g., 07
+		mm := parseUint(s[4:6], 0, 59) // e.g., 00
+		if !ok || !((s[0] == '-' || s[0] == '+') && s[3] == ':') {
+			return Time{}, false
+		}
+		zoneOffset := (hr*60 + mm) * 60
+		if s[0] == '-' {
+			zoneOffset *= -1
+		}
+		t.addSec(-int64(zoneOffset))
+
+		// Use local zone with the given offset if possible.
+		if _, offset, _, _, _ := local.lookup(t.unixSec()); offset == zoneOffset {
+			t.setLoc(local)
+		} else {
+			t.setLoc(FixedZone("", zoneOffset))
+		}
+	}
+	return t, true
+}
+
+func parseStrictRFC3339(b []byte) (Time, error) {
+	t, ok := parseRFC3339(b, Local)
+	if !ok {
+		t, err := Parse(RFC3339, string(b))
+		if err != nil {
+			return Time{}, err
+		}
+
+		// The parse template syntax cannot correctly validate RFC 3339.
+		// Explicitly check for cases that Parse is unable to validate for.
+		// See https://go.dev/issue/54580.
+		num2 := func(b []byte) byte { return 10*(b[0]-'0') + (b[1] - '0') }
+		switch {
+		// TODO(https://go.dev/issue/54580): Strict parsing is disabled for now.
+		// Enable this again with a GODEBUG opt-out.
+		case true:
+			return t, nil
+		case b[len("2006-01-02T")+1] == ':': // hour must be two digits
+			return Time{}, &ParseError{RFC3339, string(b), "15", string(b[len("2006-01-02T"):][:1]), ""}
+		case b[len("2006-01-02T15:04:05")] == ',': // sub-second separator must be a period
+			return Time{}, &ParseError{RFC3339, string(b), ".", ",", ""}
+		case b[len(b)-1] != 'Z':
+			switch {
+			case num2(b[len(b)-len("07:00"):]) >= 24: // timezone hour must be in range
+				return Time{}, &ParseError{RFC3339, string(b), "Z07:00", string(b[len(b)-len("Z07:00"):]), ": timezone hour out of range"}
+			case num2(b[len(b)-len("00"):]) >= 60: // timezone minute must be in range
+				return Time{}, &ParseError{RFC3339, string(b), "Z07:00", string(b[len(b)-len("Z07:00"):]), ": timezone minute out of range"}
+			}
+		default: // unknown error; should not occur
+			return Time{}, &ParseError{RFC3339, string(b), RFC3339, string(b), ""}
+		}
+	}
+	return t, nil
+}
diff --git a/src/time/format_test.go b/src/time/format_test.go
index 9ae2b80..8a26eaa 100644
--- a/src/time/format_test.go
+++ b/src/time/format_test.go
@@ -5,7 +5,9 @@
 package time_test
 
 import (
+	"bytes"
 	"fmt"
+	"math"
 	"strconv"
 	"strings"
 	"testing"
@@ -88,6 +90,51 @@
 	}
 }
 
+func TestAppendInt(t *testing.T) {
+	tests := []struct {
+		in    int
+		width int
+		want  string
+	}{
+		{0, 0, "0"},
+		{0, 1, "0"},
+		{0, 2, "00"},
+		{0, 3, "000"},
+		{1, 0, "1"},
+		{1, 1, "1"},
+		{1, 2, "01"},
+		{1, 3, "001"},
+		{-1, 0, "-1"},
+		{-1, 1, "-1"},
+		{-1, 2, "-01"},
+		{-1, 3, "-001"},
+		{99, 2, "99"},
+		{100, 2, "100"},
+		{1, 4, "0001"},
+		{12, 4, "0012"},
+		{123, 4, "0123"},
+		{1234, 4, "1234"},
+		{12345, 4, "12345"},
+		{1, 5, "00001"},
+		{12, 5, "00012"},
+		{123, 5, "00123"},
+		{1234, 5, "01234"},
+		{12345, 5, "12345"},
+		{123456, 5, "123456"},
+		{0, 9, "000000000"},
+		{123, 9, "000000123"},
+		{123456, 9, "000123456"},
+		{123456789, 9, "123456789"},
+	}
+	var got []byte
+	for _, tt := range tests {
+		got = AppendInt(got[:0], tt.in, tt.width)
+		if string(got) != tt.want {
+			t.Errorf("appendInt(%d, %d) = %s, want %s", tt.in, tt.width, got, tt.want)
+		}
+	}
+}
+
 type FormatTest struct {
 	name   string
 	format string
@@ -115,6 +162,9 @@
 	{"StampMilli", StampMilli, "Feb  4 21:00:57.012"},
 	{"StampMicro", StampMicro, "Feb  4 21:00:57.012345"},
 	{"StampNano", StampNano, "Feb  4 21:00:57.012345600"},
+	{"DateTime", DateTime, "2009-02-04 21:00:57"},
+	{"DateOnly", DateOnly, "2009-02-04"},
+	{"TimeOnly", TimeOnly, "21:00:57"},
 	{"YearDay", "Jan  2 002 __2 2", "Feb  4 035  35 4"},
 	{"Year", "2006 6 06 _6 __6 ___6", "2009 6 09 _6 __6 ___6"},
 	{"Month", "Jan January 1 01 _1", "Feb February 2 02 _2"},
@@ -570,13 +620,13 @@
 }
 
 var parseErrorTests = []ParseErrorTest{
-	{ANSIC, "Feb  4 21:00:60 2010", "cannot parse"}, // cannot parse Feb as Mon
-	{ANSIC, "Thu Feb  4 21:00:57 @2010", "cannot parse"},
+	{ANSIC, "Feb  4 21:00:60 2010", `cannot parse "Feb  4 21:00:60 2010" as "Mon"`},
+	{ANSIC, "Thu Feb  4 21:00:57 @2010", `cannot parse "@2010" as "2006"`},
 	{ANSIC, "Thu Feb  4 21:00:60 2010", "second out of range"},
 	{ANSIC, "Thu Feb  4 21:61:57 2010", "minute out of range"},
 	{ANSIC, "Thu Feb  4 24:00:60 2010", "hour out of range"},
-	{"Mon Jan _2 15:04:05.000 2006", "Thu Feb  4 23:00:59x01 2010", "cannot parse"},
-	{"Mon Jan _2 15:04:05.000 2006", "Thu Feb  4 23:00:59.xxx 2010", "cannot parse"},
+	{"Mon Jan _2 15:04:05.000 2006", "Thu Feb  4 23:00:59x01 2010", `cannot parse "x01 2010" as ".000"`},
+	{"Mon Jan _2 15:04:05.000 2006", "Thu Feb  4 23:00:59.xxx 2010", `cannot parse ".xxx 2010" as ".000"`},
 	{"Mon Jan _2 15:04:05.000 2006", "Thu Feb  4 23:00:59.-123 2010", "fractional second out of range"},
 	// issue 4502. StampNano requires exactly 9 digits of precision.
 	{StampNano, "Dec  7 11:22:01.000000", `cannot parse ".000000" as ".000000000"`},
@@ -588,9 +638,11 @@
 	{RFC3339, "2006-01-02T15:04:05Z_abc", `parsing time "2006-01-02T15:04:05Z_abc": extra text: "_abc"`},
 	// invalid second followed by optional fractional seconds
 	{RFC3339, "2010-02-04T21:00:67.012345678-08:00", "second out of range"},
+	// issue 54569
+	{RFC3339, "0000-01-01T00:00:.0+00:00", `parsing time "0000-01-01T00:00:.0+00:00" as "2006-01-02T15:04:05Z07:00": cannot parse ".0+00:00" as "05"`},
 	// issue 21113
-	{"_2 Jan 06 15:04 MST", "4 --- 00 00:00 GMT", "cannot parse"},
-	{"_2 January 06 15:04 MST", "4 --- 00 00:00 GMT", "cannot parse"},
+	{"_2 Jan 06 15:04 MST", "4 --- 00 00:00 GMT", `cannot parse "--- 00 00:00 GMT" as "Jan"`},
+	{"_2 January 06 15:04 MST", "4 --- 00 00:00 GMT", `cannot parse "--- 00 00:00 GMT" as "January"`},
 
 	// invalid or mismatched day-of-year
 	{"Jan _2 002 2006", "Feb  4 034 2006", "day-of-year does not match day"},
@@ -599,6 +651,16 @@
 	// issue 45391.
 	{`"2006-01-02T15:04:05Z07:00"`, "0", `parsing time "0" as "\"2006-01-02T15:04:05Z07:00\"": cannot parse "0" as "\""`},
 	{RFC3339, "\"", `parsing time "\"" as "2006-01-02T15:04:05Z07:00": cannot parse "\"" as "2006"`},
+
+	// issue 54570
+	{RFC3339, "0000-01-01T00:00:00+00:+0", `parsing time "0000-01-01T00:00:00+00:+0" as "2006-01-02T15:04:05Z07:00": cannot parse "+00:+0" as "Z07:00"`},
+	{RFC3339, "0000-01-01T00:00:00+-0:00", `parsing time "0000-01-01T00:00:00+-0:00" as "2006-01-02T15:04:05Z07:00": cannot parse "+-0:00" as "Z07:00"`},
+
+	// issue 56730
+	{"2006-01-02", "22-10-25", `parsing time "22-10-25" as "2006-01-02": cannot parse "22-10-25" as "2006"`},
+	{"06-01-02", "a2-10-25", `parsing time "a2-10-25" as "06-01-02": cannot parse "a2-10-25" as "06"`},
+	{"03:04PM", "12:03pM", `parsing time "12:03pM" as "03:04PM": cannot parse "pM" as "PM"`},
+	{"03:04pm", "12:03pM", `parsing time "12:03pM" as "03:04pm": cannot parse "pM" as "pm"`},
 }
 
 func TestParseErrors(t *testing.T) {
@@ -860,43 +922,145 @@
 	}
 }
 
-// Issue 48685
+var longFractionalDigitsTests = []struct {
+	value string
+	want  int
+}{
+	// 9 digits
+	{"2021-09-29T16:04:33.000000000Z", 0},
+	{"2021-09-29T16:04:33.000000001Z", 1},
+	{"2021-09-29T16:04:33.100000000Z", 100_000_000},
+	{"2021-09-29T16:04:33.100000001Z", 100_000_001},
+	{"2021-09-29T16:04:33.999999999Z", 999_999_999},
+	{"2021-09-29T16:04:33.012345678Z", 12_345_678},
+	// 10 digits, truncates
+	{"2021-09-29T16:04:33.0000000000Z", 0},
+	{"2021-09-29T16:04:33.0000000001Z", 0},
+	{"2021-09-29T16:04:33.1000000000Z", 100_000_000},
+	{"2021-09-29T16:04:33.1000000009Z", 100_000_000},
+	{"2021-09-29T16:04:33.9999999999Z", 999_999_999},
+	{"2021-09-29T16:04:33.0123456789Z", 12_345_678},
+	// 11 digits, truncates
+	{"2021-09-29T16:04:33.10000000000Z", 100_000_000},
+	{"2021-09-29T16:04:33.00123456789Z", 1_234_567},
+	// 12 digits, truncates
+	{"2021-09-29T16:04:33.000123456789Z", 123_456},
+	// 15 digits, truncates
+	{"2021-09-29T16:04:33.9999999999999999Z", 999_999_999},
+}
+
+// Issue 48685 and 54567.
 func TestParseFractionalSecondsLongerThanNineDigits(t *testing.T) {
-	tests := []struct {
-		s    string
-		want int
-	}{
-		// 9 digits
-		{"2021-09-29T16:04:33.000000000Z", 0},
-		{"2021-09-29T16:04:33.000000001Z", 1},
-		{"2021-09-29T16:04:33.100000000Z", 100_000_000},
-		{"2021-09-29T16:04:33.100000001Z", 100_000_001},
-		{"2021-09-29T16:04:33.999999999Z", 999_999_999},
-		{"2021-09-29T16:04:33.012345678Z", 12_345_678},
-		// 10 digits, truncates
-		{"2021-09-29T16:04:33.0000000000Z", 0},
-		{"2021-09-29T16:04:33.0000000001Z", 0},
-		{"2021-09-29T16:04:33.1000000000Z", 100_000_000},
-		{"2021-09-29T16:04:33.1000000009Z", 100_000_000},
-		{"2021-09-29T16:04:33.9999999999Z", 999_999_999},
-		{"2021-09-29T16:04:33.0123456789Z", 12_345_678},
-		// 11 digits, truncates
-		{"2021-09-29T16:04:33.10000000000Z", 100_000_000},
-		{"2021-09-29T16:04:33.00123456789Z", 1_234_567},
-		// 12 digits, truncates
-		{"2021-09-29T16:04:33.000123456789Z", 123_456},
-		// 15 digits, truncates
-		{"2021-09-29T16:04:33.9999999999999999Z", 999_999_999},
+	for _, tt := range longFractionalDigitsTests {
+		for _, format := range []string{RFC3339, RFC3339Nano} {
+			tm, err := Parse(format, tt.value)
+			if err != nil {
+				t.Errorf("Parse(%q, %q) error: %v", format, tt.value, err)
+				continue
+			}
+			if got := tm.Nanosecond(); got != tt.want {
+				t.Errorf("Parse(%q, %q) = got %d, want %d", format, tt.value, got, tt.want)
+			}
+		}
+	}
+}
+
+func FuzzFormatRFC3339(f *testing.F) {
+	for _, ts := range [][2]int64{
+		{math.MinInt64, math.MinInt64}, // 292277026304-08-26T15:42:51Z
+		{-62167219200, 0},              // 0000-01-01T00:00:00Z
+		{1661201140, 676836973},        // 2022-08-22T20:45:40.676836973Z
+		{253402300799, 999999999},      // 9999-12-31T23:59:59.999999999Z
+		{math.MaxInt64, math.MaxInt64}, // -292277022365-05-08T08:17:07Z
+	} {
+		f.Add(ts[0], ts[1], true, false, 0)
+		f.Add(ts[0], ts[1], false, true, 0)
+		for _, offset := range []int{0, 60, 60 * 60, 99*60*60 + 99*60, 123456789} {
+			f.Add(ts[0], ts[1], false, false, -offset)
+			f.Add(ts[0], ts[1], false, false, +offset)
+		}
 	}
 
-	for _, tt := range tests {
-		tm, err := Parse(RFC3339, tt.s)
-		if err != nil {
-			t.Errorf("Unexpected error: %v", err)
-			continue
+	f.Fuzz(func(t *testing.T, sec, nsec int64, useUTC, useLocal bool, tzOffset int) {
+		var loc *Location
+		switch {
+		case useUTC:
+			loc = UTC
+		case useLocal:
+			loc = Local
+		default:
+			loc = FixedZone("", tzOffset)
 		}
-		if got := tm.Nanosecond(); got != tt.want {
-			t.Errorf("Parse(%q) = got %d, want %d", tt.s, got, tt.want)
+		ts := Unix(sec, nsec).In(loc)
+
+		got := AppendFormatRFC3339(ts, nil, false)
+		want := AppendFormatAny(ts, nil, RFC3339)
+		if !bytes.Equal(got, want) {
+			t.Errorf("Format(%s, RFC3339) mismatch:\n\tgot:  %s\n\twant: %s", ts, got, want)
 		}
+
+		gotNanos := AppendFormatRFC3339(ts, nil, true)
+		wantNanos := AppendFormatAny(ts, nil, RFC3339Nano)
+		if !bytes.Equal(got, want) {
+			t.Errorf("Format(%s, RFC3339Nano) mismatch:\n\tgot:  %s\n\twant: %s", ts, gotNanos, wantNanos)
+		}
+	})
+}
+
+func FuzzParseRFC3339(f *testing.F) {
+	for _, tt := range formatTests {
+		f.Add(tt.result)
 	}
+	for _, tt := range parseTests {
+		f.Add(tt.value)
+	}
+	for _, tt := range parseErrorTests {
+		f.Add(tt.value)
+	}
+	for _, tt := range longFractionalDigitsTests {
+		f.Add(tt.value)
+	}
+
+	f.Fuzz(func(t *testing.T, s string) {
+		// equalTime is like time.Time.Equal, but also compares the time zone.
+		equalTime := func(t1, t2 Time) bool {
+			name1, offset1 := t1.Zone()
+			name2, offset2 := t2.Zone()
+			return t1.Equal(t2) && name1 == name2 && offset1 == offset2
+		}
+
+		for _, tz := range []*Location{UTC, Local} {
+			// Parsing as RFC3339 or RFC3339Nano should be identical.
+			t1, err1 := ParseAny(RFC3339, s, UTC, tz)
+			t2, err2 := ParseAny(RFC3339Nano, s, UTC, tz)
+			switch {
+			case (err1 == nil) != (err2 == nil):
+				t.Fatalf("ParseAny(%q) error mismatch:\n\tgot:  %v\n\twant: %v", s, err1, err2)
+			case !equalTime(t1, t2):
+				t.Fatalf("ParseAny(%q) value mismatch:\n\tgot:  %v\n\twant: %v", s, t1, t2)
+			}
+
+			// TODO(https://go.dev/issue/54580):
+			// Remove these checks after ParseAny rejects all invalid RFC 3339.
+			if err1 == nil {
+				num2 := func(s string) byte { return 10*(s[0]-'0') + (s[1] - '0') }
+				switch {
+				case len(s) > 12 && s[12] == ':':
+					t.Skipf("ParseAny(%q) incorrectly allows single-digit hour fields", s)
+				case len(s) > 19 && s[19] == ',':
+					t.Skipf("ParseAny(%q) incorrectly allows comma as sub-second separator", s)
+				case !strings.HasSuffix(s, "Z") && len(s) > 4 && (num2(s[len(s)-5:]) >= 24 || num2(s[len(s)-2:]) >= 60):
+					t.Skipf("ParseAny(%q) incorrectly allows out-of-range zone offset", s)
+				}
+			}
+
+			// Customized parser should be identical to general parser.
+			switch got, ok := ParseRFC3339(s, tz); {
+			case ok != (err1 == nil):
+				t.Fatalf("ParseRFC3339(%q) error mismatch:\n\tgot:  %v\n\twant: %v", s, ok, err1 == nil)
+			case !equalTime(got, t1):
+				t.Fatalf("ParseRFC3339(%q) value mismatch:\n\tgot:  %v\n\twant: %v", s, got, t2)
+			}
+		}
+	})
 }
diff --git a/src/time/mono_test.go b/src/time/mono_test.go
index 8778ab7..cdbb11e 100644
--- a/src/time/mono_test.go
+++ b/src/time/mono_test.go
@@ -106,6 +106,12 @@
 	if !now.Before(tn1) {
 		t.Errorf("Now().Before(Now().Add(1*Hour)) = false, want true")
 	}
+	if got, want := now.Compare(tn1), -1; got != want {
+		t.Errorf("Now().Compare(Now().Add(1*Hour)) = %d, want %d", got, want)
+	}
+	if got, want := tn1.Compare(now), 1; got != want {
+		t.Errorf("Now().Add(1*Hour).Compare(Now()) = %d, want %d", got, want)
+	}
 }
 
 func TestMonotonicSub(t *testing.T) {
@@ -155,7 +161,7 @@
 	sub("t3", "t3", t3, t3w, t3, t3w, 0, 0)
 
 	cmp := func(txs, tys string, tx, txw, ty, tyw Time, c, cw int) {
-		check := func(expr string, b, want bool) {
+		check := func(expr string, b, want any) {
 			if b != want {
 				t.Errorf("%s = %v, want %v", expr, b, want)
 			}
@@ -174,6 +180,11 @@
 		check(txs+"w.Equal("+tys+")", txw.Equal(ty), cw == 0)
 		check(txs+".Equal("+tys+"w)", tx.Equal(tyw), cw == 0)
 		check(txs+"w.Equal("+tys+"w)", txw.Equal(tyw), cw == 0)
+
+		check(txs+".Compare("+tys+")", tx.Compare(ty), c)
+		check(txs+"w.Compare("+tys+")", txw.Compare(ty), cw)
+		check(txs+".Compare("+tys+"w)", tx.Compare(tyw), cw)
+		check(txs+"w.Compare("+tys+"w)", txw.Compare(tyw), cw)
 	}
 
 	cmp("t1", "t1", t1, t1w, t1, t1w, 0, 0)
@@ -229,6 +240,12 @@
 	if !t2.Before(t1) {
 		t.Errorf("Now().Add(-5*Second).Before(Now().Add(1*Hour)) = false, want true\nt1=%v\nt2=%v", t1, t2)
 	}
+	if got, want := t1.Compare(t2), 1; got != want {
+		t.Errorf("Now().Add(1*Hour).Compare(Now().Add(-5*Second)) = %d, want %d\nt1=%v\nt2=%v", got, want, t1, t2)
+	}
+	if got, want := t2.Compare(t1), -1; got != want {
+		t.Errorf("Now().Add(-5*Second).Before(Now().Add(1*Hour)) = %d, want %d\nt1=%v\nt2=%v", got, want, t1, t2)
+	}
 }
 
 var monotonicStringTests = []struct {
diff --git a/src/time/sleep_test.go b/src/time/sleep_test.go
index 5a949b6..8aac3b6 100644
--- a/src/time/sleep_test.go
+++ b/src/time/sleep_test.go
@@ -65,9 +65,9 @@
 }
 
 func TestAfterStress(t *testing.T) {
-	stop := uint32(0)
+	var stop atomic.Bool
 	go func() {
-		for atomic.LoadUint32(&stop) == 0 {
+		for !stop.Load() {
 			runtime.GC()
 			// Yield so that the OS can wake up the timer thread,
 			// so that it can generate channel sends for the main goroutine,
@@ -80,7 +80,7 @@
 		<-ticker.C
 	}
 	ticker.Stop()
-	atomic.StoreUint32(&stop, 1)
+	stop.Store(true)
 }
 
 func benchmark(b *testing.B, bench func(n int)) {
diff --git a/src/time/time.go b/src/time/time.go
index 47b26e3..e8aac59 100644
--- a/src/time/time.go
+++ b/src/time/time.go
@@ -46,7 +46,7 @@
 // The canonical way to strip a monotonic clock reading is to use t = t.Round(0).
 //
 // If Times t and u both contain monotonic clock readings, the operations
-// t.After(u), t.Before(u), t.Equal(u), and t.Sub(u) are carried out
+// t.After(u), t.Before(u), t.Equal(u), t.Compare(u), and t.Sub(u) are carried out
 // using the monotonic clock readings alone, ignoring the wall clock
 // readings. If either t or u contains no monotonic clock reading, these
 // operations fall back to using the wall clock readings.
@@ -266,6 +266,27 @@
 	return ts < us || ts == us && t.nsec() < u.nsec()
 }
 
+// Compare compares the time instant t with u. If t is before u, it returns -1;
+// if t is after u, it returns +1; if they're the same, it returns 0.
+func (t Time) Compare(u Time) int {
+	var tc, uc int64
+	if t.wall&u.wall&hasMonotonic != 0 {
+		tc, uc = t.ext, u.ext
+	} else {
+		tc, uc = t.sec(), u.sec()
+		if tc == uc {
+			tc, uc = int64(t.nsec()), int64(u.nsec())
+		}
+	}
+	switch {
+	case tc < uc:
+		return -1
+	case tc > uc:
+		return +1
+	}
+	return 0
+}
+
 // Equal reports whether t and u represent the same time instant.
 // Two times can be equal even if they are in different locations.
 // For example, 6:00 +0200 and 4:00 UTC are Equal.
@@ -1091,6 +1112,9 @@
 	mono -= startNano
 	sec += unixToInternal - minWall
 	if uint64(sec)>>33 != 0 {
+		// Seconds field overflowed the 33 bits available when
+		// storing a monotonic time. This will be true after
+		// March 16, 2157.
 		return Time{uint64(nsec), sec + minWall, Local}
 	}
 	return Time{hasMonotonic | uint64(sec)<<nsecShift | uint64(nsec), mono, Local}
@@ -1313,51 +1337,54 @@
 }
 
 // MarshalJSON implements the json.Marshaler interface.
-// The time is a quoted string in RFC 3339 format, with sub-second precision added if present.
+// The time is a quoted string in the RFC 3339 format with sub-second precision.
+// If the timestamp cannot be represented as valid RFC 3339
+// (e.g., the year is out of range), then an error is reported.
 func (t Time) MarshalJSON() ([]byte, error) {
-	if y := t.Year(); y < 0 || y >= 10000 {
-		// RFC 3339 is clear that years are 4 digits exactly.
-		// See golang.org/issue/4556#c15 for more discussion.
-		return nil, errors.New("Time.MarshalJSON: year outside of range [0,9999]")
+	b := make([]byte, 0, len(RFC3339Nano)+len(`""`))
+	b = append(b, '"')
+	b, err := t.appendStrictRFC3339(b)
+	b = append(b, '"')
+	if err != nil {
+		return nil, errors.New("Time.MarshalJSON: " + err.Error())
 	}
-
-	b := make([]byte, 0, len(RFC3339Nano)+2)
-	b = append(b, '"')
-	b = t.AppendFormat(b, RFC3339Nano)
-	b = append(b, '"')
 	return b, nil
 }
 
 // UnmarshalJSON implements the json.Unmarshaler interface.
-// The time is expected to be a quoted string in RFC 3339 format.
+// The time must be a quoted string in the RFC 3339 format.
 func (t *Time) UnmarshalJSON(data []byte) error {
-	// Ignore null, like in the main JSON package.
 	if string(data) == "null" {
 		return nil
 	}
-	// Fractional seconds are handled implicitly by Parse.
+	// TODO(https://go.dev/issue/47353): Properly unescape a JSON string.
+	if len(data) < 2 || data[0] != '"' || data[len(data)-1] != '"' {
+		return errors.New("Time.UnmarshalJSON: input is not a JSON string")
+	}
+	data = data[len(`"`) : len(data)-len(`"`)]
 	var err error
-	*t, err = Parse(`"`+RFC3339+`"`, string(data))
+	*t, err = parseStrictRFC3339(data)
 	return err
 }
 
 // MarshalText implements the encoding.TextMarshaler interface.
-// The time is formatted in RFC 3339 format, with sub-second precision added if present.
+// The time is formatted in RFC 3339 format with sub-second precision.
+// If the timestamp cannot be represented as valid RFC 3339
+// (e.g., the year is out of range), then an error is reported.
 func (t Time) MarshalText() ([]byte, error) {
-	if y := t.Year(); y < 0 || y >= 10000 {
-		return nil, errors.New("Time.MarshalText: year outside of range [0,9999]")
-	}
-
 	b := make([]byte, 0, len(RFC3339Nano))
-	return t.AppendFormat(b, RFC3339Nano), nil
+	b, err := t.appendStrictRFC3339(b)
+	if err != nil {
+		return nil, errors.New("Time.MarshalText: " + err.Error())
+	}
+	return b, nil
 }
 
 // UnmarshalText implements the encoding.TextUnmarshaler interface.
-// The time is expected to be in RFC 3339 format.
+// The time must be in the RFC 3339 format.
 func (t *Time) UnmarshalText(data []byte) error {
-	// Fractional seconds are handled implicitly by Parse.
 	var err error
-	*t, err = Parse(RFC3339, string(data))
+	*t, err = parseStrictRFC3339(data)
 	return err
 }
 
diff --git a/src/time/time_test.go b/src/time/time_test.go
index 6fde5f6..4221efe 100644
--- a/src/time/time_test.go
+++ b/src/time/time_test.go
@@ -804,6 +804,7 @@
 	{Date(9999, 4, 12, 23, 20, 50, 520*1e6, UTC), `"9999-04-12T23:20:50.52Z"`},
 	{Date(1996, 12, 19, 16, 39, 57, 0, Local), `"1996-12-19T16:39:57-08:00"`},
 	{Date(0, 1, 1, 0, 0, 0, 1, FixedZone("", 1*60)), `"0000-01-01T00:00:00.000000001+00:01"`},
+	{Date(2020, 1, 1, 0, 0, 0, 0, FixedZone("", 23*60*60+59*60)), `"2020-01-01T00:00:00+23:59"`},
 }
 
 func TestTimeJSON(t *testing.T) {
@@ -822,28 +823,67 @@
 	}
 }
 
-func TestInvalidTimeJSON(t *testing.T) {
-	var tt Time
-	err := json.Unmarshal([]byte(`{"now is the time":"buddy"}`), &tt)
-	_, isParseErr := err.(*ParseError)
-	if !isParseErr {
-		t.Errorf("expected *time.ParseError unmarshaling JSON, got %v", err)
+func TestUnmarshalInvalidTimes(t *testing.T) {
+	tests := []struct {
+		in   string
+		want string
+	}{
+		{`{}`, "Time.UnmarshalJSON: input is not a JSON string"},
+		{`[]`, "Time.UnmarshalJSON: input is not a JSON string"},
+		{`"2000-01-01T1:12:34Z"`, `<nil>`},
+		{`"2000-01-01T00:00:00,000Z"`, `<nil>`},
+		{`"2000-01-01T00:00:00+24:00"`, `<nil>`},
+		{`"2000-01-01T00:00:00+00:60"`, `<nil>`},
+		{`"2000-01-01T00:00:00+123:45"`, `parsing time "2000-01-01T00:00:00+123:45" as "2006-01-02T15:04:05Z07:00": cannot parse "+123:45" as "Z07:00"`},
+	}
+
+	for _, tt := range tests {
+		var ts Time
+
+		want := tt.want
+		err := json.Unmarshal([]byte(tt.in), &ts)
+		if fmt.Sprint(err) != want {
+			t.Errorf("Time.UnmarshalJSON(%s) = %v, want %v", tt.in, err, want)
+		}
+
+		if strings.HasPrefix(tt.in, `"`) && strings.HasSuffix(tt.in, `"`) {
+			err = ts.UnmarshalText([]byte(strings.Trim(tt.in, `"`)))
+			if fmt.Sprint(err) != want {
+				t.Errorf("Time.UnmarshalText(%s) = %v, want %v", tt.in, err, want)
+			}
+		}
 	}
 }
 
-var notJSONEncodableTimes = []struct {
-	time Time
-	want string
-}{
-	{Date(10000, 1, 1, 0, 0, 0, 0, UTC), "Time.MarshalJSON: year outside of range [0,9999]"},
-	{Date(-1, 1, 1, 0, 0, 0, 0, UTC), "Time.MarshalJSON: year outside of range [0,9999]"},
-}
+func TestMarshalInvalidTimes(t *testing.T) {
+	tests := []struct {
+		time Time
+		want string
+	}{
+		{Date(10000, 1, 1, 0, 0, 0, 0, UTC), "Time.MarshalJSON: year outside of range [0,9999]"},
+		{Date(-998, 1, 1, 0, 0, 0, 0, UTC).Add(-Second), "Time.MarshalJSON: year outside of range [0,9999]"},
+		{Date(0, 1, 1, 0, 0, 0, 0, UTC).Add(-Nanosecond), "Time.MarshalJSON: year outside of range [0,9999]"},
+		{Date(2020, 1, 1, 0, 0, 0, 0, FixedZone("", 24*60*60)), "Time.MarshalJSON: timezone hour outside of range [0,23]"},
+		{Date(2020, 1, 1, 0, 0, 0, 0, FixedZone("", 123*60*60)), "Time.MarshalJSON: timezone hour outside of range [0,23]"},
+	}
 
-func TestNotJSONEncodableTime(t *testing.T) {
-	for _, tt := range notJSONEncodableTimes {
-		_, err := tt.time.MarshalJSON()
-		if err == nil || err.Error() != tt.want {
-			t.Errorf("%v MarshalJSON error = %v, want %v", tt.time, err, tt.want)
+	for _, tt := range tests {
+		want := tt.want
+		b, err := tt.time.MarshalJSON()
+		switch {
+		case b != nil:
+			t.Errorf("(%v).MarshalText() = %q, want nil", tt.time, b)
+		case err == nil || err.Error() != want:
+			t.Errorf("(%v).MarshalJSON() error = %v, want %v", tt.time, err, want)
+		}
+
+		want = strings.ReplaceAll(tt.want, "JSON", "Text")
+		b, err = tt.time.MarshalText()
+		switch {
+		case b != nil:
+			t.Errorf("(%v).MarshalText() = %q, want nil", tt.time, b)
+		case err == nil || err.Error() != want:
+			t.Errorf("(%v).MarshalText() error = %v, want %v", tt.time, err, want)
 		}
 	}
 }
@@ -1282,6 +1322,7 @@
 	{"After", func(t1, t2 Time) bool { return t1.After(t2) == t2.After(t1) }},
 	{"Before", func(t1, t2 Time) bool { return t1.Before(t2) == t2.Before(t1) }},
 	{"Equal", func(t1, t2 Time) bool { return t1.Equal(t2) == t2.Equal(t1) }},
+	{"Compare", func(t1, t2 Time) bool { return t1.Compare(t2) == t2.Compare(t1) }},
 
 	{"IsZero", func(t1, t2 Time) bool { return t1.IsZero() == t2.IsZero() }},
 	{"Date", func(t1, t2 Time) bool {
@@ -1402,6 +1443,20 @@
 	}
 }
 
+func BenchmarkFormatRFC3339(b *testing.B) {
+	t := Unix(1265346057, 0)
+	for i := 0; i < b.N; i++ {
+		t.Format("2006-01-02T15:04:05Z07:00")
+	}
+}
+
+func BenchmarkFormatRFC3339Nano(b *testing.B) {
+	t := Unix(1265346057, 0)
+	for i := 0; i < b.N; i++ {
+		t.Format("2006-01-02T15:04:05.999999999Z07:00")
+	}
+}
+
 func BenchmarkFormatNow(b *testing.B) {
 	// Like BenchmarkFormat, but easier, because the time zone
 	// lookup cache is optimized for the present.
@@ -1431,6 +1486,38 @@
 	}
 }
 
+const testdataRFC3339UTC = "2020-08-22T11:27:43.123456789Z"
+
+func BenchmarkParseRFC3339UTC(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Parse(RFC3339, testdataRFC3339UTC)
+	}
+}
+
+var testdataRFC3339UTCBytes = []byte(testdataRFC3339UTC)
+
+func BenchmarkParseRFC3339UTCBytes(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Parse(RFC3339, string(testdataRFC3339UTCBytes))
+	}
+}
+
+const testdataRFC3339TZ = "2020-08-22T11:27:43.123456789-02:00"
+
+func BenchmarkParseRFC3339TZ(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Parse(RFC3339, testdataRFC3339TZ)
+	}
+}
+
+var testdataRFC3339TZBytes = []byte(testdataRFC3339TZ)
+
+func BenchmarkParseRFC3339TZBytes(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Parse(RFC3339, string(testdataRFC3339TZBytes))
+	}
+}
+
 func BenchmarkParseDuration(b *testing.B) {
 	for i := 0; i < b.N; i++ {
 		ParseDuration("9007199254.740993ms")
@@ -1473,6 +1560,21 @@
 	}
 }
 
+func BenchmarkGoString(b *testing.B) {
+	t := Now()
+	for i := 0; i < b.N; i++ {
+		_ = t.GoString()
+	}
+}
+
+func BenchmarkUnmarshalText(b *testing.B) {
+	var t Time
+	in := []byte("2020-08-22T11:27:43.123456789-02:00")
+	for i := 0; i < b.N; i++ {
+		t.UnmarshalText(in)
+	}
+}
+
 func TestMarshalBinaryZeroTime(t *testing.T) {
 	t0 := Time{}
 	enc, err := t0.MarshalBinary()
@@ -1519,6 +1621,16 @@
 	}
 }
 
+func TestUnmarshalTextAllocations(t *testing.T) {
+	in := []byte(testdataRFC3339UTC) // short enough to be stack allocated
+	if allocs := testing.AllocsPerRun(100, func() {
+		var t Time
+		t.UnmarshalText(in)
+	}); allocs != 0 {
+		t.Errorf("got %v allocs, want 0 allocs", allocs)
+	}
+}
+
 // Issue 17720: Zero value of time.Month fails to print
 func TestZeroMonthString(t *testing.T) {
 	if got, want := Month(0).String(), "%!Month(0)"; got != want {
diff --git a/src/time/tzdata/zipdata.go b/src/time/tzdata/zipdata.go
index 162936a..d5785ad 100644
--- a/src/time/tzdata/zipdata.go
+++ b/src/time/tzdata/zipdata.go
@@ -16,428 +16,886 @@
 
 package tzdata
 
-const zipdata = "PK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x1c\x00Africa/UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00" +
-	"\x04S_\x01\x00PK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\xc1\n\x8a\x84\xad\x00\x00\x00\xad\x00\x00\x00\x0f\x00\x1c\x00Africa/Sao_TomeUT\t\x00\x03\xdc\xfc\x94b\xdc" +
-	"\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00" +
-	"\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xff^<\xfd" +
-	"0\xff\xff\xff\xff\x92掀\x00\x00\x00\x00ZI\x88\x10\x00\x00\x00\x00\\*\xbb\x90\x01\x02\x03\x02\x00\x00\x06P\x00\x00\xff\xff\xf7c\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x0e\x10\x00\bLMT\x00GMT" +
-	"\x00WAT\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0e\x00\x1c\x00Africa/ConakryUT\t\x00\x03" +
-	"\xdc\xfc\x94b\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff" +
-	"\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\f" +
-	"\x00\x1c\x00Africa/DakarUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00" +
-	"\x00\x00\x00\x8ej\xbeT\xaa\x81\t\x03\xa0\x00\x00\x00\xa0\x00\x00\x00\x0f\x00\x1c\x00Africa/NdjamenaUT\t\x00\x03\xdc\xfc\x94b\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b" +
-	"\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZi" +
-	"f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xff\x92\xe6\x80d\x00\x00\x00\x00\x12fqp\x00\x00\x00" +
-	"\x00\x13&\xde`\x01\x02\x01\x00\x00\x0e\x1c\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\bLMT\x00WAT\x00WAST\x00\nWAT-1\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT" +
-	"d\x01\x05\x89\x7f\a\x00\x00\x7f\a\x00\x00\x11\x00\x1c\x00Africa/CasablancaUT\t\x00\x03\xdc\xfc\x94b\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01" +
-	"\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc5\x00\x00\x00\x05\x00\x00\x00\f\xff\xff\xff\xff\x96Q\xf9\x9c\xff\xff\xff\xff\xc6\xff\x14\x80\xff\xff\xff\xff\xc7X\xacp" +
-	"\xff\xff\xff\xff\xc7\xd9\xed\x80\xff\xff\xff\xffҡ2\xf0\xff\xff\xff\xff\xdb5\xa4\x00\xff\xff\xff\xff\xdb\xee'\xf0\xff\xff\xff\xff\xfb%r@\xff\xff\xff\xff\xfb\xc2\xefp\x00\x00\x00\x00\bk\x84\x80\x00\x00\x00\x00" +
-	"\b\xc6m\xf0\x00\x00\x00\x00\v\xe8\f\x00\x00\x00\x00\x00\faG\xf0\x00\x00\x00\x00\r\xc9?\x80\x00\x00\x00\x00\x0e\x8e\xf2p\x00\x00\x00\x00\x0f\xd3Q\x80\x00\x00\x00\x00\x10'\xa3p\x00\x00\x00\x00\x1a\xb7\xa6\x00" +
-	"\x00\x00\x00\x00\x1e\x18o\xf0\x00\x00\x00\x00HA\xe6\x80\x00\x00\x00\x00H\xbb\"p\x00\x00\x00\x00J#\x1a\x00\x00\x00\x00\x00J\x8d\xd5p\x00\x00\x00\x00K\xdc\xc0\x80\x00\x00\x00\x00L]\xe5p\x00\x00\x00\x00" +
-	"M\x97\xb8\x80\x00\x00\x00\x00N4\x8c\xf0\x00\x00\x00\x00O\x9c\xa0\xa0\x00\x00\x00\x00P\b\xbb\xa0\x00\x00\x00\x00P1\x9a \x00\x00\x00\x00Pg\xa7\xa0\x00\x00\x00\x00Q|\x82\xa0\x00\x00\x00\x00Q\xd8ˠ" +
-	"\x00\x00\x00\x00R\x05\x9e\xa0\x00\x00\x00\x00Rls\xa0\x00\x00\x00\x00S7z\xa0\x00\x00\x00\x00S\xae!\xa0\x00\x00\x00\x00S\xdcF \x00\x00\x00\x00TLU\xa0\x00\x00\x00\x00U\x17\\\xa0\x00\x00\x00\x00" +
-	"U|\xe0 \x00\x00\x00\x00U\xab\x04\xa0\x00\x00\x00\x00V,7\xa0\x00\x00\x00\x00V\xf7>\xa0\x00\x00\x00\x00WS\x87\xa0\x00\x00\x00\x00W\x81\xac \x00\x00\x00\x00X\x15T \x00\x00\x00\x00X\xd7 \xa0" +
-	"\x00\x00\x00\x00Y \xf4\xa0\x00\x00\x00\x00YXS\xa0\x00\x00\x00\x00Y\xf56 \x00\x00\x00\x00Z\xb7\x02\xa0\x00\x00\x00\x00Z\xf7\x9c \x00\x00\x00\x00[%\xc0\xa0\x00\x00\x00\x00[\xd5\x18 \x00\x00\x00\x00" +
-	"\\\xceC\xa0\x00\x00\x00\x00\\\xfch \x00\x00\x00\x00^\x9b\xb0\xa0\x00\x00\x00\x00^\xd3\x0f\xa0\x00\x00\x00\x00`rX \x00\x00\x00\x00`\xa0|\xa0\x00\x00\x00\x00b?\xc5 \x00\x00\x00\x00bw$ " +
-	"\x00\x00\x00\x00d\x16l\xa0\x00\x00\x00\x00dMˠ\x00\x00\x00\x00e\xed\x14 \x00\x00\x00\x00f\x1b8\xa0\x00\x00\x00\x00g\xba\x81 \x00\x00\x00\x00g\xf1\xe0 \x00\x00\x00\x00i\x91(\xa0\x00\x00\x00\x00" +
-	"i\xbfM \x00\x00\x00\x00kg\xd0 \x00\x00\x00\x00k\x95\xf4\xa0\x00\x00\x00\x00m5= \x00\x00\x00\x00ml\x9c \x00\x00\x00\x00o\v\xe4\xa0\x00\x00\x00\x00o:\t \x00\x00\x00\x00p\xd9Q\xa0" +
-	"\x00\x00\x00\x00q\x10\xb0\xa0\x00\x00\x00\x00r\xaf\xf9 \x00\x00\x00\x00r\xe7X \x00\x00\x00\x00t\x86\xa0\xa0\x00\x00\x00\x00t\xb4\xc5 \x00\x00\x00\x00vT\r\xa0\x00\x00\x00\x00v\x8bl\xa0\x00\x00\x00\x00" +
-	"x*\xb5 \x00\x00\x00\x00xX٠\x00\x00\x00\x00y\xf8\" \x00\x00\x00\x00z/\x81 \x00\x00\x00\x00{\xceɠ\x00\x00\x00\x00|\x06(\xa0\x00\x00\x00\x00}\xa5q \x00\x00\x00\x00}ӕ\xa0" +
-	"\x00\x00\x00\x00\x7fr\xde \x00\x00\x00\x00\x7f\xaa= \x00\x00\x00\x00\x81I\x85\xa0\x00\x00\x00\x00\x81\x80\xe4\xa0\x00\x00\x00\x00\x83 - \x00\x00\x00\x00\x83NQ\xa0\x00\x00\x00\x00\x84\xed\x9a \x00\x00\x00\x00" +
-	"\x85$\xf9 \x00\x00\x00\x00\x86\xc4A\xa0\x00\x00\x00\x00\x86\xf2f \x00\x00\x00\x00\x88\x91\xae\xa0\x00\x00\x00\x00\x88\xc9\r\xa0\x00\x00\x00\x00\x8ahV \x00\x00\x00\x00\x8a\x9f\xb5 \x00\x00\x00\x00\x8c>\xfd\xa0" +
-	"\x00\x00\x00\x00\x8cm\" \x00\x00\x00\x00\x8e\fj\xa0\x00\x00\x00\x00\x8eCɠ\x00\x00\x00\x00\x8f\xe3\x12 \x00\x00\x00\x00\x90\x1aq \x00\x00\x00\x00\x91\xb9\xb9\xa0\x00\x00\x00\x00\x91\xe7\xde \x00\x00\x00\x00" +
-	"\x93\x87&\xa0\x00\x00\x00\x00\x93\xbe\x85\xa0\x00\x00\x00\x00\x95]\xce \x00\x00\x00\x00\x95\x8b\xf2\xa0\x00\x00\x00\x00\x97+; \x00\x00\x00\x00\x97b\x9a \x00\x00\x00\x00\x99\x01\xe2\xa0\x00\x00\x00\x00\x999A\xa0" +
-	"\x00\x00\x00\x00\x9a؊ \x00\x00\x00\x00\x9b\x06\xae\xa0\x00\x00\x00\x00\x9c\xa5\xf7 \x00\x00\x00\x00\x9c\xddV \x00\x00\x00\x00\x9e|\x9e\xa0\x00\x00\x00\x00\x9e\xb3\xfd\xa0\x00\x00\x00\x00\xa0SF \x00\x00\x00\x00" +
-	"\xa0\x81j\xa0\x00\x00\x00\x00\xa2 \xb3 \x00\x00\x00\x00\xa2X\x12 \x00\x00\x00\x00\xa3\xf7Z\xa0\x00\x00\x00\x00\xa4%\x7f \x00\x00\x00\x00\xa5\xc4Ǡ\x00\x00\x00\x00\xa5\xfc&\xa0\x00\x00\x00\x00\xa7\x9bo " +
-	"\x00\x00\x00\x00\xa7\xd2\xce \x00\x00\x00\x00\xa9r\x16\xa0\x00\x00\x00\x00\xa9\xa0; \x00\x00\x00\x00\xab?\x83\xa0\x00\x00\x00\x00\xabv\xe2\xa0\x00\x00\x00\x00\xad\x16+ \x00\x00\x00\x00\xadM\x8a \x00\x00\x00\x00" +
-	"\xae\xecҠ\x00\x00\x00\x00\xaf\x1a\xf7 \x00\x00\x00\x00\xb0\xba?\xa0\x00\x00\x00\x00\xb0\xf1\x9e\xa0\x00\x00\x00\x00\xb2\x90\xe7 \x00\x00\x00\x00\xb2\xbf\v\xa0\x00\x00\x00\x00\xb4^T \x00\x00\x00\x00\xb4\x95\xb3 " +
-	"\x00\x00\x00\x00\xb64\xfb\xa0\x00\x00\x00\x00\xb6lZ\xa0\x00\x00\x00\x00\xb8\v\xa3 \x00\x00\x00\x00\xb89Ǡ\x00\x00\x00\x00\xb9\xd9\x10 \x00\x00\x00\x00\xba\x10o \x00\x00\x00\x00\xbb\xaf\xb7\xa0\x00\x00\x00\x00" +
-	"\xbb\xe7\x16\xa0\x00\x00\x00\x00\xbd\x86_ \x00\x00\x00\x00\xbd\xb4\x83\xa0\x00\x00\x00\x00\xbfS\xcc \x00\x00\x00\x00\xbf\x8b+ \x00\x00\x00\x00\xc1*s\xa0\x00\x00\x00\x00\xc1X\x98 \x00\x00\x00\x00\xc2\xf7\xe0\xa0" +
-	"\x00\x00\x00\x00\xc3/?\xa0\x00\x00\x00\x00\xc4Έ \x00\x00\x00\x00\xc5\x05\xe7 \x00\x00\x00\x00ƥ/\xa0\x00\x00\x00\x00\xc6\xd3T \x00\x00\x00\x00\xc8r\x9c\xa0\x00\x00\x00\x00ȩ\xfb\xa0\x00\x00\x00\x00" +
-	"\xcaID \x00\x00\x00\x00ʀ\xa3 \x00\x00\x00\x00\xcc\x1f\xeb\xa0\x00\x00\x00\x00\xccN\x10 \x00\x00\x00\x00\xcd\xedX\xa0\x00\x00\x00\x00\xce$\xb7\xa0\x00\x00\x00\x00\xcf\xc4\x00 \x00\x00\x00\x00\xcf\xf2$\xa0" +
-	"\x00\x00\x00\x00ёm \x00\x00\x00\x00\xd1\xc8\xcc \x00\x00\x00\x00\xd3h\x14\xa0\x00\x00\x00\x00ӟs\xa0\x00\x00\x00\x00\xd5>\xbc \x00\x00\x00\x00\xd5l\xe0\xa0\x00\x00\x00\x00\xd7\f) \x00\x00\x00\x00" +
-	"\xd7C\x88 \x00\x00\x00\x00\xd8\xe2Р\x00\x00\x00\x00\xd9\x1a/\xa0\x00\x00\x00\x00ڹx \x00\x00\x00\x00\xda眠\x00\x00\x00\x00܆\xe5 \x00\x00\x00\x00ܾD \x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" +
-	"\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" +
-	"\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" +
-	"\x03\x04\x03\x04\x03\x04\x03\x04\x03\xff\xff\xf8\xe4\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x0e\x10\x00\x04\x00\x00\x00\x00\x01\bLMT\x00+01\x00+00\x00\n<+01>-1\n" +
-	"PK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\v\x00\x1c\x00Africa/LomeUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04" +
-	"\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" +
-	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00" +
-	"\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeTÊ\x0e\xc0\xd6\x01\x00\x00\xd6\x01\x00\x00\x0e\x00\x1c\x00Africa/Algi" +
-	"ersUT\t\x00\x03\xdc\xfc\x94b\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\"\x00\x00" +
-	"\x00\x06\x00\x00\x00\x1a\xff\xff\xff\xffkɛ$\xff\xff\xff\xff\x91`PO\xff\xff\xff\xff\x9bGx\xf0\xff\xff\xff\xff\x9b\xd7,p\xff\xff\xff\xff\x9c\xbc\x91p\xff\xff\xff\xff\x9d\xc0H\xf0\xff\xff\xff\xff\x9e\x89" +
-	"\xfep\xff\xff\xff\xff\x9f\xa0*\xf0\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1\x80\f\xf0\xff\xff\xff\xff\xa2.\x12\xf0\xff\xff\xff\xff\xa3zL\xf0\xff\xff\xff\xff\xa45\x81\xf0\xff\xff\xff\xff\xa4\xb8\x06p\xff\xff" +
-	"\xff\xff\xc6\xff\x06p\xff\xff\xff\xff\xc7X\xba\x80\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЊ\x00\x00\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2N$p\xff\xff\xff\xff\xd4K" +
-	"\ap\xff\xff\xff\xff\xe5\xce\xd3\x00\xff\xff\xff\xff\xf3\\\xb0\xf0\x00\x00\x00\x00\x02x\xc1\xf0\x00\x00\x00\x00\x03C\xc8\xf0\x00\x00\x00\x00\r\xcf\xd7\x00\x00\x00\x00\x00\x0e\xadD\xf0\x00\x00\x00\x00\x0fxZ\x00\x00\x00" +
-	"\x00\x00\x10hY\x10\x00\x00\x00\x00\x12vCp\x00\x00\x00\x00\x13fB\x80\x00\x00\x00\x00\x14_|\x10\x00\x00\x00\x00\x15O_\x00\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x04\x05\x04\x05\x03" +
-	"\x05\x03\x02\x03\x02\x05\x04\x05\x03\x02\x03\x05\x00\x00\x02\xdc\x00\x00\x00\x00\x021\x00\x04\x00\x00\x0e\x10\x01\b\x00\x00\x00\x00\x00\r\x00\x00\x1c \x01\x11\x00\x00\x0e\x10\x00\x16LMT\x00PMT\x00WEST" +
-	"\x00WET\x00CEST\x00CET\x00\nCET-1\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\x10\x00\x1c\x00Africa/Mo" +
-	"gadishuUT\t\x00\x03\xdc\xfc\x94b\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1\xed\xadX\xff\xff\xff\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\"\x84\x00" +
-	"\x00\x00\x00#(\x00\x04\x00\x00*0\x00\n\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00+0245\x00\nEAT-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT" +
-	"\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\f\x00\x1c\x00Africa/LagosUT\t\x00\x03\xdc\xfc\x94b\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif" +
+const zipdata = "PK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0e\x00\x00\x00Africa/AbidjanTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\f\x00\x00\x00Africa/AccraTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\x12\x00\x00\x00Africa/Addis_AbabaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1\xed\xadX\xff\xff\xff\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\"\x84\x00\x00" +
+	"\x00\x00#(\x00\x04\x00\x00*0\x00\n\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00+0245\x00\nEAT-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc3" +
+	"\x8a\x0e\xc0\xd6\x01\x00\x00\xd6\x01\x00\x00\x0e\x00\x00\x00Africa/AlgiersTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\"\x00\x00\x00\x06" +
+	"\x00\x00\x00\x1a\xff\xff\xff\xffkɛ$\xff\xff\xff\xff\x91`PO\xff\xff\xff\xff\x9bGx\xf0\xff\xff\xff\xff\x9b\xd7,p\xff\xff\xff\xff\x9c\xbc\x91p\xff\xff\xff\xff\x9d\xc0H\xf0\xff\xff\xff\xff\x9e\x89\xfep" +
+	"\xff\xff\xff\xff\x9f\xa0*\xf0\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1\x80\f\xf0\xff\xff\xff\xff\xa2.\x12\xf0\xff\xff\xff\xff\xa3zL\xf0\xff\xff\xff\xff\xa45\x81\xf0\xff\xff\xff\xff\xa4\xb8\x06p\xff\xff\xff\xff" +
+	"\xc6\xff\x06p\xff\xff\xff\xff\xc7X\xba\x80\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЊ\x00\x00\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2N$p\xff\xff\xff\xff\xd4K\ap" +
+	"\xff\xff\xff\xff\xe5\xce\xd3\x00\xff\xff\xff\xff\xf3\\\xb0\xf0\x00\x00\x00\x00\x02x\xc1\xf0\x00\x00\x00\x00\x03C\xc8\xf0\x00\x00\x00\x00\r\xcf\xd7\x00\x00\x00\x00\x00\x0e\xadD\xf0\x00\x00\x00\x00\x0fxZ\x00\x00\x00\x00\x00" +
+	"\x10hY\x10\x00\x00\x00\x00\x12vCp\x00\x00\x00\x00\x13fB\x80\x00\x00\x00\x00\x14_|\x10\x00\x00\x00\x00\x15O_\x00\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x04\x05\x04\x05\x03\x05\x03" +
+	"\x02\x03\x02\x05\x04\x05\x03\x02\x03\x05\x00\x00\x02\xdc\x00\x00\x00\x00\x021\x00\x04\x00\x00\x0e\x10\x01\b\x00\x00\x00\x00\x00\r\x00\x00\x1c \x01\x11\x00\x00\x0e\x10\x00\x16LMT\x00PMT\x00WEST\x00W" +
+	"ET\x00CEST\x00CET\x00\nCET-1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\r\x00\x00\x00Africa/Asma" +
+	"raTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0" +
+	"\xd0\xff\xff\xff\xff\xc1\xed\xadX\xff\xff\xff\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\"\x84\x00\x00\x00\x00#(\x00\x04\x00\x00*0\x00\n\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00" +
+	"+0245\x00\nEAT-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\r\x00\x00\x00Africa/AsmeraTZif" +
 	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x86\xabp\xd1\xff\xff\xff\xff\x8cP`\x00\xff\xff\xff\xff\x96\xaaC\xd1\xff\xff\xff\xff\xa1" +
-	"Q\xefx\x01\x00\x02\x03\x00\x00\x03/\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\a\b\x00\b\x00\x00\x0e\x10\x00\x0eLMT\x00GMT\x00+0030\x00WAT\x00\nWAT-1\nPK\x03\x04" +
-	"\n\x00\x00\x00\x00\x00\x8ej\xbeT\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x12\x00\x1c\x00Africa/BrazzavilleUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v" +
-	"\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00" +
-	"\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x86\xabp\xd1\xff\xff\xff\xff\x8c" +
-	"P`\x00\xff\xff\xff\xff\x96\xaaC\xd1\xff\xff\xff\xff\xa1Q\xefx\x01\x00\x02\x03\x00\x00\x03/\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\a\b\x00\b\x00\x00\x0e\x10\x00\x0eLMT\x00GMT\x00+0030" +
-	"\x00WAT\x00\nWAT-1\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0f\x00\x1c\x00Africa/TimbuktuUT\t" +
-	"\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b" +
-	"\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00" +
-	"\x00\x11\x00\x1c\x00Africa/NouakchottUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1" +
+	"\xed\xadX\xff\xff\xff\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\"\x84\x00\x00\x00\x00#(\x00\x04\x00\x00*0\x00\n\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00+0245\x00" +
+	"\nEAT-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\r\x00\x00\x00Africa/BamakoTZif2\x00\x00\x00\x00\x00" +
 	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
 	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\n" +
-	"PK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\xcc\fTξ\x00\x00\x00\xbe\x00\x00\x00\r\x00\x1c\x00Africa/MaseruUT\t\x00\x03\xdc\xfc\x94b\xdc\xfc\x94bux\v\x00" +
-	"\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00" +
-	"\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x04\x00\x00\x00\t\xff\xff\xff\xffm{A@\xff\xff\xff\xff\x82F" +
-	"\xcfh\xff\xff\xff\xff̮\x8c\x80\xff\xff\xff\xff͞op\xff\xff\xff\xffΎn\x80\xff\xff\xff\xff\xcf~Qp\x01\x03\x02\x03\x02\x03\x00\x00\x1a@\x00\x00\x00\x00\x15\x18\x00\x04\x00\x00*0\x01\x04\x00\x00" +
-	"\x1c \x00\x04LMT\x00SAST\x00\nSAST-2\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x11\x00\x1c\x00Africa/Li" +
-	"brevilleUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x86\xabp\xd1\xff\xff\xff\xff\x8cP`\x00\xff\xff\xff\xff\x96\xaaC\xd1\xff\xff\xff\xff\xa1Q\xefx\x01\x00\x02\x03\x00\x00\x03/\x00\x00\x00\x00\x00\x00\x00\x04\x00" +
-	"\x00\a\b\x00\b\x00\x00\x0e\x10\x00\x0eLMT\x00GMT\x00+0030\x00WAT\x00\nWAT-1\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT \x1b\xb0_\x83\x00\x00\x00\x83\x00" +
-	"\x00\x00\r\x00\x1c\x00Africa/HarareUT\t\x00\x03\xdc\xfc\x94b\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00\nCAT-2\nPK" +
-	"\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\r\x00\x1c\x00Africa/MalaboUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04" +
-	"\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" +
-	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x86\xabp\xd1\xff\xff\xff\xff\x8cP`\x00" +
-	"\xff\xff\xff\xff\x96\xaaC\xd1\xff\xff\xff\xff\xa1Q\xefx\x01\x00\x02\x03\x00\x00\x03/\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\a\b\x00\b\x00\x00\x0e\x10\x00\x0eLMT\x00GMT\x00+0030\x00WA" +
-	"T\x00\nWAT-1\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\r\x00\x1c\x00Africa/BanguiUT\t\x00\x03\xdc\xfc\x94" +
-	"b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" +
-	"\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x86" +
-	"\xabp\xd1\xff\xff\xff\xff\x8cP`\x00\xff\xff\xff\xff\x96\xaaC\xd1\xff\xff\xff\xff\xa1Q\xefx\x01\x00\x02\x03\x00\x00\x03/\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\a\b\x00\b\x00\x00\x0e\x10\x00\x0eLMT\x00G" +
-	"MT\x00+0030\x00WAT\x00\nWAT-1\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\x0e\x00\x1c\x00Africa/Nai" +
-	"robiUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00" +
-	"\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1\xed\xadX\xff\xff\xff\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\"\x84\x00\x00\x00\x00" +
-	"#(\x00\x04\x00\x00*0\x00\n\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00+0245\x00\nEAT-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\xa7\x1d\xb3" +
-	"c\xb4\x00\x00\x00\xb4\x00\x00\x00\x0f\x00\x1c\x00Africa/KinshasaUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif" +
-	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x86\xabp\xd1\xff\xff\xff\xff\x8cP`\x00\xff\xff\xff\xff\x96\xaaC\xd1\xff\xff\xff\xff\xa1" +
-	"Q\xefx\x01\x00\x02\x03\x00\x00\x03/\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\a\b\x00\b\x00\x00\x0e\x10\x00\x0eLMT\x00GMT\x00+0030\x00WAT\x00\nWAT-1\nPK\x03\x04" +
-	"\n\x00\x00\x00\x00\x00\x8ej\xbeT\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x11\x00\x1c\x00Africa/Porto-NovoUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00" +
-	"\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00" +
-	"\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x86\xabp\xd1\xff\xff\xff\xff\x8cP" +
-	"`\x00\xff\xff\xff\xff\x96\xaaC\xd1\xff\xff\xff\xff\xa1Q\xefx\x01\x00\x02\x03\x00\x00\x03/\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\a\b\x00\b\x00\x00\x0e\x10\x00\x0eLMT\x00GMT\x00+0030\x00" +
-	"WAT\x00\nWAT-1\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\x12tnj\xfc\x04\x00\x00\xfc\x04\x00\x00\f\x00\x1c\x00Africa/CairoUT\t\x00\x03\xdc\xfc" +
-	"\x94b\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xff" +
-	"}\xbdM\xab\xff\xff\xff\xffȓ\xb4\xe0\xff\xff\xff\xff\xc8\xfa{\xd0\xff\xff\xff\xff\xc9\xfc\xef\xe0\xff\xff\xff\xff\xca\xc7\xe8\xd0\xff\xff\xff\xff\xcbˮ`\xff\xff\xff\xff\xcc\xdf)\xd0\xff\xff\xff\xffͬ\xe1\xe0" +
-	"\xff\xff\xff\xff\xce\xc6\xf4\xd0\xff\xff\xff\xffϏf\xe0\xff\xff\xff\xffЩy\xd0\xff\xff\xff\xffф`\xe0\xff\xff\xff\xffҊ\xadP\xff\xff\xff\xff\xe86c`\xff\xff\xff\xff\xe8\xf4-P\xff\xff\xff\xff" +
-	"\xea\v\xb9`\xff\xff\xff\xff\xea\xd5`\xd0\xff\xff\xff\xff\xeb\xec\xfa\xf0\xff\xff\xff\xff\xec\xb5m\x00\xff\xff\xff\xff\xed\xcf\x7f\xf0\xff\xff\xff\xff\xee\x97\xf2\x00\xff\xff\xff\xffﰳp\xff\xff\xff\xff\xf0y%\x80" +
-	"\xff\xff\xff\xff\xf1\x91\xe6\xf0\xff\xff\xff\xff\xf2ZY\x00\xff\xff\xff\xff\xf3s\x1ap\xff\xff\xff\xff\xf4;\x8c\x80\xff\xff\xff\xff\xf5U\x9fp\xff\xff\xff\xff\xf6\x1e\x11\x80\xff\xff\xff\xff\xf76\xd2\xf0\xff\xff\xff\xff" +
-	"\xf7\xffE\x00\xff\xff\xff\xff\xf9\x18\x06p\xff\xff\xff\xff\xf9\xe1\xca\x00\xff\xff\xff\xff\xfa\xf99\xf0\xff\xff\xff\xff\xfb\xc2\xfd\x80\xff\xff\xff\xff\xfc۾\xf0\xff\xff\xff\xff\xfd\xa5\x82\x80\xff\xff\xff\xff\xfe\xbc\xf2p" +
-	"\xff\xff\xff\xff\xff\x86\xb6\x00\x00\x00\x00\x00\x00\x9e%\xf0\x00\x00\x00\x00\x01g\xe9\x80\x00\x00\x00\x00\x02\x7fYp\x00\x00\x00\x00\x03I\x1d\x00\x00\x00\x00\x00\x04a\xdep\x00\x00\x00\x00\x05+\xa2\x00\x00\x00\x00\x00" +
-	"\x06C\x11\xf0\x00\x00\x00\x00\a\fՀ\x00\x00\x00\x00\b$Ep\x00\x00\x00\x00\b\xee\t\x00\x00\x00\x00\x00\n\x05x\xf0\x00\x00\x00\x00\n\xcf<\x80\x00\x00\x00\x00\v\xe7\xfd\xf0\x00\x00\x00\x00\f\xb1\xc1\x80" +
-	"\x00\x00\x00\x00\r\xc91p\x00\x00\x00\x00\x0e\x92\xf5\x00\x00\x00\x00\x00\x0f\xaad\xf0\x00\x00\x00\x00\x10t(\x80\x00\x00\x00\x00\x11\x8b\x98p\x00\x00\x00\x00\x12U\\\x00\x00\x00\x00\x00\x13n\x1dp\x00\x00\x00\x00" +
-	"\x147\xe1\x00\x00\x00\x00\x00\x15OP\xf0\x00\x00\x00\x00\x16\x19\x14\x80\x00\x00\x00\x00\x17\xa0\x93\xf0\x00\x00\x00\x00\x17\xfaH\x00\x00\x00\x00\x00\x19p\xa3\xf0\x00\x00\x00\x00\x19\xdb{\x80\x00\x00\x00\x00\x1a\xf4<\xf0" +
-	"\x00\x00\x00\x00\x1b\xbe\x00\x80\x00\x00\x00\x00\x1c\xd5pp\x00\x00\x00\x00\x1d\x9f4\x00\x00\x00\x00\x00\x1e\xb6\xa3\xf0\x00\x00\x00\x00\x1f\x80g\x80\x00\x00\x00\x00 \x97\xd7p\x00\x00\x00\x00!a\x9b\x00\x00\x00\x00\x00" +
-	"\"z\\p\x00\x00\x00\x00#D \x00\x00\x00\x00\x00$b'p\x00\x00\x00\x00%%S\x80\x00\x00\x00\x00&<\xc3p\x00\x00\x00\x00'\x06\x87\x00\x00\x00\x00\x00(\x1d\xf6\xf0\x00\x00\x00\x00(纀" +
-	"\x00\x00\x00\x00*\x00{\xf0\x00\x00\x00\x00*\xca?\x80\x00\x00\x00\x00+\xe1\xafp\x00\x00\x00\x00,\xabs\x00\x00\x00\x00\x00-\xc2\xe2\xf0\x00\x00\x00\x00.\x8c\xa6\x80\x00\x00\x00\x00/\xa0\x13\xe0\x00\x00\x00\x00" +
-	"0k\f\xd0\x00\x00\x00\x001\x7f\xf5\xe0\x00\x00\x00\x002J\xee\xd0\x00\x00\x00\x003_\xd7\xe0\x00\x00\x00\x004*\xd0\xd0\x00\x00\x00\x005?\xb9\xe0\x00\x00\x00\x006\n\xb2\xd0\x00\x00\x00\x007(\xd6`" +
-	"\x00\x00\x00\x007\xf3\xcfP\x00\x00\x00\x009\b\xb8`\x00\x00\x00\x009ӱP\x00\x00\x00\x00:\xe8\x9a`\x00\x00\x00\x00;\xb3\x93P\x00\x00\x00\x00<\xc8|`\x00\x00\x00\x00=\x93uP\x00\x00\x00\x00" +
-	">\xa8^`\x00\x00\x00\x00?sWP\x00\x00\x00\x00@\x91z\xe0\x00\x00\x00\x00A\\s\xd0\x00\x00\x00\x00Bq\\\xe0\x00\x00\x00\x00C<U\xd0\x00\x00\x00\x00DQ>\xe0\x00\x00\x00\x00E\x12\xfdP" +
-	"\x00\x00\x00\x00F1 \xe0\x00\x00\x00\x00F\xe0jP\x00\x00\x00\x00H\x11\x02\xe0\x00\x00\x00\x00H\xb7\x11\xd0\x00\x00\x00\x00I\xf0\xe4\xe0\x00\x00\x00\x00J\x8d\xb9P\x00\x00\x00\x00K\xda\x01`\x00\x00\x00\x00" +
-	"La\xbd\xd0\x00\x00\x00\x00L\x89X\xe0\x00\x00\x00\x00L\xa4\xfaP\x00\x00\x00\x00Su8\xe0\x00\x00\x00\x00S\xac\x89\xd0\x00\x00\x00\x00Sڼ`\x00\x00\x00\x00T$\x82P\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"PK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\r\x00\x00\x00Africa/BanguiTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x86\xabp\xd1\xff\xff\xff\xff\x8cP`\x00\xff\xff\xff\xff\x96\xaaC\xd1\xff\xff\xff\xff\xa1Q\xefx\x01\x00\x02\x03\x00\x00\x03/\x00\x00" +
+	"\x00\x00\x00\x00\x00\x04\x00\x00\a\b\x00\b\x00\x00\x0e\x10\x00\x0eLMT\x00GMT\x00+0030\x00WAT\x00\nWAT-1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{" +
+	"\x87\x82\x00\x00\x00\x82\x00\x00\x00\r\x00\x00\x00Africa/BanjulTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00" +
+	"\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca>\xd5\xe0\x95\x00\x00\x00\x95\x00" +
+	"\x00\x00\r\x00\x00\x00Africa/BissauTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00" +
+	"\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x92\xe6" +
+	"\x9c\x90\x00\x00\x00\x00\tga\x10\x01\x02\xff\xff\xf1d\x00\x00\xff\xff\xf1\xf0\x00\x04\x00\x00\x00\x00\x00\bLMT\x00-01\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\x0f\x00\x00\x00Africa/BlantyreTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" +
+	"\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00\nCAT-2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d" +
+	"\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x12\x00\x00\x00Africa/BrazzavilleTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00" +
+	"\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x86\xabp\xd1\xff\xff\xff\xff\x8cP`\x00\xff\xff\xff\xff\x96\xaaC\xd1\xff\xff\xff\xff\xa1Q\xefx\x01\x00\x02\x03\x00\x00\x03/\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\a\b\x00" +
+	"\b\x00\x00\x0e\x10\x00\x0eLMT\x00GMT\x00+0030\x00WAT\x00\nWAT-1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\x10\x00" +
+	"\x00\x00Africa/BujumburaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00" +
+	"\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x82F\xc5" +
+	"\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00\nCAT-2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12tnj\xfc\x04\x00\x00\xfc\x04\x00\x00\f\x00\x00\x00A" +
+	"frica/CairoTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00" +
+	"\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xff}\xbdM\xab\xff\xff\xff\xffȓ" +
+	"\xb4\xe0\xff\xff\xff\xff\xc8\xfa{\xd0\xff\xff\xff\xff\xc9\xfc\xef\xe0\xff\xff\xff\xff\xca\xc7\xe8\xd0\xff\xff\xff\xff\xcbˮ`\xff\xff\xff\xff\xcc\xdf)\xd0\xff\xff\xff\xffͬ\xe1\xe0\xff\xff\xff\xff\xce\xc6\xf4\xd0\xff\xff" +
+	"\xff\xffϏf\xe0\xff\xff\xff\xffЩy\xd0\xff\xff\xff\xffф`\xe0\xff\xff\xff\xffҊ\xadP\xff\xff\xff\xff\xe86c`\xff\xff\xff\xff\xe8\xf4-P\xff\xff\xff\xff\xea\v\xb9`\xff\xff\xff\xff\xea\xd5" +
+	"`\xd0\xff\xff\xff\xff\xeb\xec\xfa\xf0\xff\xff\xff\xff\xec\xb5m\x00\xff\xff\xff\xff\xed\xcf\x7f\xf0\xff\xff\xff\xff\xee\x97\xf2\x00\xff\xff\xff\xffﰳp\xff\xff\xff\xff\xf0y%\x80\xff\xff\xff\xff\xf1\x91\xe6\xf0\xff\xff" +
+	"\xff\xff\xf2ZY\x00\xff\xff\xff\xff\xf3s\x1ap\xff\xff\xff\xff\xf4;\x8c\x80\xff\xff\xff\xff\xf5U\x9fp\xff\xff\xff\xff\xf6\x1e\x11\x80\xff\xff\xff\xff\xf76\xd2\xf0\xff\xff\xff\xff\xf7\xffE\x00\xff\xff\xff\xff\xf9\x18" +
+	"\x06p\xff\xff\xff\xff\xf9\xe1\xca\x00\xff\xff\xff\xff\xfa\xf99\xf0\xff\xff\xff\xff\xfb\xc2\xfd\x80\xff\xff\xff\xff\xfc۾\xf0\xff\xff\xff\xff\xfd\xa5\x82\x80\xff\xff\xff\xff\xfe\xbc\xf2p\xff\xff\xff\xff\xff\x86\xb6\x00\x00\x00" +
+	"\x00\x00\x00\x9e%\xf0\x00\x00\x00\x00\x01g\xe9\x80\x00\x00\x00\x00\x02\x7fYp\x00\x00\x00\x00\x03I\x1d\x00\x00\x00\x00\x00\x04a\xdep\x00\x00\x00\x00\x05+\xa2\x00\x00\x00\x00\x00\x06C\x11\xf0\x00\x00\x00\x00\a\f" +
+	"Հ\x00\x00\x00\x00\b$Ep\x00\x00\x00\x00\b\xee\t\x00\x00\x00\x00\x00\n\x05x\xf0\x00\x00\x00\x00\n\xcf<\x80\x00\x00\x00\x00\v\xe7\xfd\xf0\x00\x00\x00\x00\f\xb1\xc1\x80\x00\x00\x00\x00\r\xc91p\x00\x00" +
+	"\x00\x00\x0e\x92\xf5\x00\x00\x00\x00\x00\x0f\xaad\xf0\x00\x00\x00\x00\x10t(\x80\x00\x00\x00\x00\x11\x8b\x98p\x00\x00\x00\x00\x12U\\\x00\x00\x00\x00\x00\x13n\x1dp\x00\x00\x00\x00\x147\xe1\x00\x00\x00\x00\x00\x15O" +
+	"P\xf0\x00\x00\x00\x00\x16\x19\x14\x80\x00\x00\x00\x00\x17\xa0\x93\xf0\x00\x00\x00\x00\x17\xfaH\x00\x00\x00\x00\x00\x19p\xa3\xf0\x00\x00\x00\x00\x19\xdb{\x80\x00\x00\x00\x00\x1a\xf4<\xf0\x00\x00\x00\x00\x1b\xbe\x00\x80\x00\x00" +
+	"\x00\x00\x1c\xd5pp\x00\x00\x00\x00\x1d\x9f4\x00\x00\x00\x00\x00\x1e\xb6\xa3\xf0\x00\x00\x00\x00\x1f\x80g\x80\x00\x00\x00\x00 \x97\xd7p\x00\x00\x00\x00!a\x9b\x00\x00\x00\x00\x00\"z\\p\x00\x00\x00\x00#D" +
+	" \x00\x00\x00\x00\x00$b'p\x00\x00\x00\x00%%S\x80\x00\x00\x00\x00&<\xc3p\x00\x00\x00\x00'\x06\x87\x00\x00\x00\x00\x00(\x1d\xf6\xf0\x00\x00\x00\x00(纀\x00\x00\x00\x00*\x00{\xf0\x00\x00" +
+	"\x00\x00*\xca?\x80\x00\x00\x00\x00+\xe1\xafp\x00\x00\x00\x00,\xabs\x00\x00\x00\x00\x00-\xc2\xe2\xf0\x00\x00\x00\x00.\x8c\xa6\x80\x00\x00\x00\x00/\xa0\x13\xe0\x00\x00\x00\x000k\f\xd0\x00\x00\x00\x001\x7f" +
+	"\xf5\xe0\x00\x00\x00\x002J\xee\xd0\x00\x00\x00\x003_\xd7\xe0\x00\x00\x00\x004*\xd0\xd0\x00\x00\x00\x005?\xb9\xe0\x00\x00\x00\x006\n\xb2\xd0\x00\x00\x00\x007(\xd6`\x00\x00\x00\x007\xf3\xcfP\x00\x00" +
+	"\x00\x009\b\xb8`\x00\x00\x00\x009ӱP\x00\x00\x00\x00:\xe8\x9a`\x00\x00\x00\x00;\xb3\x93P\x00\x00\x00\x00<\xc8|`\x00\x00\x00\x00=\x93uP\x00\x00\x00\x00>\xa8^`\x00\x00\x00\x00?s" +
+	"WP\x00\x00\x00\x00@\x91z\xe0\x00\x00\x00\x00A\\s\xd0\x00\x00\x00\x00Bq\\\xe0\x00\x00\x00\x00C<U\xd0\x00\x00\x00\x00DQ>\xe0\x00\x00\x00\x00E\x12\xfdP\x00\x00\x00\x00F1 \xe0\x00\x00" +
+	"\x00\x00F\xe0jP\x00\x00\x00\x00H\x11\x02\xe0\x00\x00\x00\x00H\xb7\x11\xd0\x00\x00\x00\x00I\xf0\xe4\xe0\x00\x00\x00\x00J\x8d\xb9P\x00\x00\x00\x00K\xda\x01`\x00\x00\x00\x00La\xbd\xd0\x00\x00\x00\x00L\x89" +
+	"X\xe0\x00\x00\x00\x00L\xa4\xfaP\x00\x00\x00\x00Su8\xe0\x00\x00\x00\x00S\xac\x89\xd0\x00\x00\x00\x00Sڼ`\x00\x00\x00\x00T$\x82P\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
 	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00" +
-	"\x00\x1dU\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\tLMT\x00EEST\x00EET\x00\nEET-2\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4" +
-	"\x00\x00\x00\r\x00\x1c\x00Africa/DoualaUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x86\xabp\xd1\xff\xff\xff\xff\x8cP`\x00\xff\xff\xff\xff\x96\xaaC\xd1\xff\xff\xff\xff\xa1Q\xefx\x01\x00\x02\x03\x00" +
-	"\x00\x03/\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\a\b\x00\b\x00\x00\x0e\x10\x00\x0eLMT\x00GMT\x00+0030\x00WAT\x00\nWAT-1\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej" +
-	"\xbeT\x14\xcf\x10n\xca\x01\x00\x00\xca\x01\x00\x00\v\x00\x1c\x00Africa/JubaUT\t\x00\x03\xdc\xfc\x94b\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZi" +
-	"f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00#\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff\xb6\xa3\xda\xdc\x00\x00\x00\x00\x00\x9e\x17\xe0\x00\x00\x00\x00\x01z4P\x00\x00\x00\x00" +
-	"\x02}\xf9\xe0\x00\x00\x00\x00\x03[g\xd0\x00\x00\x00\x00\x04`~\xe0\x00\x00\x00\x00\x05=\xec\xd0\x00\x00\x00\x00\x06@`\xe0\x00\x00\x00\x00\a\x1f P\x00\x00\x00\x00\b B\xe0\x00\x00\x00\x00\t\x00S\xd0" +
-	"\x00\x00\x00\x00\n\x00$\xe0\x00\x00\x00\x00\n\xe1\x87P\x00\x00\x00\x00\v\xe0\x06\xe0\x00\x00\x00\x00\f\xc4\fP\x00\x00\x00\x00\r\xbf\xe8\xe0\x00\x00\x00\x00\x0e\xa5?\xd0\x00\x00\x00\x00\x0f\xa9\x05`\x00\x00\x00\x00" +
-	"\x10\x86sP\x00\x00\x00\x00\x11\x88\xe7`\x00\x00\x00\x00\x12g\xa6\xd0\x00\x00\x00\x00\x13h\xc9`\x00\x00\x00\x00\x14J+\xd0\x00\x00\x00\x00\x15H\xab`\x00\x00\x00\x00\x16+_P\x00\x00\x00\x00\x17(\x8d`" +
-	"\x00\x00\x00\x00\x18\f\x92\xd0\x00\x00\x00\x00\x19\bo`\x00\x00\x00\x00\x19\xed\xc6P\x00\x00\x00\x00\x1a\xf1\x8b\xe0\x00\x00\x00\x00\x1b\xd0KP\x00\x00\x00\x00\x1c\xd1m\xe0\x00\x00\x00\x00\x1d\xb1~\xd0\x00\x00\x00\x00" +
-	"8\x80E \x00\x00\x00\x00`\x17\x1aP\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x00\x00\x1d\xa4\x00\x00\x00\x00*0\x01\x04\x00" +
-	"\x00\x1c \x00\t\x00\x00*0\x00\rLMT\x00CAST\x00CAT\x00EAT\x00\nCAT-2\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00" +
-	"\x00\x0f\x00\x1c\x00Africa/GaboroneUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00\nCAT-2\nP" +
-	"K\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\x93\xf4\x94\v\xc1\x01\x00\x00\xc1\x01\x00\x00\f\x00\x1c\x00Africa/TunisUT\t\x00\x03\xdc\xfc\x94b\xdc\xfc\x94bux\v\x00\x01\x04" +
-	"\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" +
-	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\"\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xffYF\x13\xf4\xff\xff\xff\xff\x91`PO" +
-	"\xff\xff\xff\xff\xc6:\x88\xe0\xff\xff\xff\xff\xc7X\x9e`\xff\xff\xff\xff\xc7\xdb\"\xe0\xff\xff\xff\xff\xca\xe2T\xe0\xff\xff\xff\xff˭i\xf0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff" +
-	"\xcd\xc2\x16\x00\xff\xff\xff\xff\xcd̰\x10\xff\xff\xff\xff\u03a25\x00\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЉ\xe3\xe0\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2N\x16`\x00\x00\x00\x00\r\xc7\xdf\xf0" +
-	"\x00\x00\x00\x00\x0e\x89\xacp\x00\x00\x00\x00\x0f\xaad\xf0\x00\x00\x00\x00\x10t\x1ap\x00\x00\x00\x00\"\xa3:\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00" +
-	"&<\xc3p\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00Bt\r\xf0\x00\x00\x00\x00C<\x80\x00\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10" +
-	"\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00\t\x8c\x00\x00\x00\x00\x021" +
-	"\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\rLMT\x00PMT\x00CEST\x00CET\x00\nCET-1\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\xb4\x8d\x98ƿ\x00\x00\x00" +
-	"\xbf\x00\x00\x00\x0e\x00\x1c\x00Africa/KampalaUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1\xed\xadX\xff\xff\xff" +
-	"\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\"\x84\x00\x00\x00\x00#(\x00\x04\x00\x00*0\x00\n\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00+0245\x00\nEAT-3" +
-	"\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\xcc\fTξ\x00\x00\x00\xbe\x00\x00\x00\x0e\x00\x1c\x00Africa/MbabaneUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux" +
-	"\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00" +
-	"\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x04\x00\x00\x00\t\xff\xff\xff\xffm{A@\xff\xff\xff\xff" +
-	"\x82F\xcfh\xff\xff\xff\xff̮\x8c\x80\xff\xff\xff\xff͞op\xff\xff\xff\xffΎn\x80\xff\xff\xff\xff\xcf~Qp\x01\x03\x02\x03\x02\x03\x00\x00\x1a@\x00\x00\x00\x00\x15\x18\x00\x04\x00\x00*0\x01\x04" +
-	"\x00\x00\x1c \x00\x04LMT\x00SAST\x00\nSAST-2\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\x12\x00\x1c\x00Africa/" +
-	"Addis_AbabaUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1\xed\xadX\xff\xff\xff\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00" +
-	"\x00\"\x84\x00\x00\x00\x00#(\x00\x04\x00\x00*0\x00\n\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00+0245\x00\nEAT-3\nPK\x03\x04\n\x00\x00\x00\x00\x00" +
-	"\x8ej\xbeT \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\r\x00\x1c\x00Africa/MaputoUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01" +
-	"\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT" +
-	"\x00CAT\x00\nCAT-2\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\xca>\xd5\xe0\x95\x00\x00\x00\x95\x00\x00\x00\r\x00\x1c\x00Africa/BissauUT\t\x00\x03" +
-	"\xdc\xfc\x94b\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff" +
-	"\xff\xff\x92朐\x00\x00\x00\x00\tga\x10\x01\x02\xff\xff\xf1d\x00\x00\xff\xff\xf1\xf0\x00\x04\x00\x00\x00\x00\x00\bLMT\x00-01\x00GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00" +
-	"\x00\x00\x8ej\xbeT \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\x0f\x00\x1c\x00Africa/BlantyreUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00" +
-	"\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif" +
-	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00" +
-	"\x04LMT\x00CAT\x00\nCAT-2\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\r\x00\x1c\x00Africa/NiameyU" +
-	"T\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x1dU\x00\x00\x00\x00*0\x01" +
+	"\x04\x00\x00\x1c \x00\tLMT\x00EEST\x00EET\x00\nEET-2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01\x05\x89\x7f\a\x00\x00\x7f\a\x00\x00\x11\x00\x00\x00Afr" +
+	"ica/CasablancaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00" +
+	"\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc5\x00\x00\x00\x05\x00\x00\x00\f\xff\xff\xff\xff\x96Q\xf9\x9c\xff\xff\xff" +
+	"\xff\xc6\xff\x14\x80\xff\xff\xff\xff\xc7X\xacp\xff\xff\xff\xff\xc7\xd9\xed\x80\xff\xff\xff\xffҡ2\xf0\xff\xff\xff\xff\xdb5\xa4\x00\xff\xff\xff\xff\xdb\xee'\xf0\xff\xff\xff\xff\xfb%r@\xff\xff\xff\xff\xfb\xc2\xef" +
+	"p\x00\x00\x00\x00\bk\x84\x80\x00\x00\x00\x00\b\xc6m\xf0\x00\x00\x00\x00\v\xe8\f\x00\x00\x00\x00\x00\faG\xf0\x00\x00\x00\x00\r\xc9?\x80\x00\x00\x00\x00\x0e\x8e\xf2p\x00\x00\x00\x00\x0f\xd3Q\x80\x00\x00\x00" +
+	"\x00\x10'\xa3p\x00\x00\x00\x00\x1a\xb7\xa6\x00\x00\x00\x00\x00\x1e\x18o\xf0\x00\x00\x00\x00HA\xe6\x80\x00\x00\x00\x00H\xbb\"p\x00\x00\x00\x00J#\x1a\x00\x00\x00\x00\x00J\x8d\xd5p\x00\x00\x00\x00K\xdc\xc0" +
+	"\x80\x00\x00\x00\x00L]\xe5p\x00\x00\x00\x00M\x97\xb8\x80\x00\x00\x00\x00N4\x8c\xf0\x00\x00\x00\x00O\x9c\xa0\xa0\x00\x00\x00\x00P\b\xbb\xa0\x00\x00\x00\x00P1\x9a \x00\x00\x00\x00Pg\xa7\xa0\x00\x00\x00" +
+	"\x00Q|\x82\xa0\x00\x00\x00\x00Q\xd8ˠ\x00\x00\x00\x00R\x05\x9e\xa0\x00\x00\x00\x00Rls\xa0\x00\x00\x00\x00S7z\xa0\x00\x00\x00\x00S\xae!\xa0\x00\x00\x00\x00S\xdcF \x00\x00\x00\x00TLU" +
+	"\xa0\x00\x00\x00\x00U\x17\\\xa0\x00\x00\x00\x00U|\xe0 \x00\x00\x00\x00U\xab\x04\xa0\x00\x00\x00\x00V,7\xa0\x00\x00\x00\x00V\xf7>\xa0\x00\x00\x00\x00WS\x87\xa0\x00\x00\x00\x00W\x81\xac \x00\x00\x00" +
+	"\x00X\x15T \x00\x00\x00\x00X\xd7 \xa0\x00\x00\x00\x00Y \xf4\xa0\x00\x00\x00\x00YXS\xa0\x00\x00\x00\x00Y\xf56 \x00\x00\x00\x00Z\xb7\x02\xa0\x00\x00\x00\x00Z\xf7\x9c \x00\x00\x00\x00[%\xc0" +
+	"\xa0\x00\x00\x00\x00[\xd5\x18 \x00\x00\x00\x00\\\xceC\xa0\x00\x00\x00\x00\\\xfch \x00\x00\x00\x00^\x9b\xb0\xa0\x00\x00\x00\x00^\xd3\x0f\xa0\x00\x00\x00\x00`rX \x00\x00\x00\x00`\xa0|\xa0\x00\x00\x00" +
+	"\x00b?\xc5 \x00\x00\x00\x00bw$ \x00\x00\x00\x00d\x16l\xa0\x00\x00\x00\x00dMˠ\x00\x00\x00\x00e\xed\x14 \x00\x00\x00\x00f\x1b8\xa0\x00\x00\x00\x00g\xba\x81 \x00\x00\x00\x00g\xf1\xe0" +
+	" \x00\x00\x00\x00i\x91(\xa0\x00\x00\x00\x00i\xbfM \x00\x00\x00\x00kg\xd0 \x00\x00\x00\x00k\x95\xf4\xa0\x00\x00\x00\x00m5= \x00\x00\x00\x00ml\x9c \x00\x00\x00\x00o\v\xe4\xa0\x00\x00\x00" +
+	"\x00o:\t \x00\x00\x00\x00p\xd9Q\xa0\x00\x00\x00\x00q\x10\xb0\xa0\x00\x00\x00\x00r\xaf\xf9 \x00\x00\x00\x00r\xe7X \x00\x00\x00\x00t\x86\xa0\xa0\x00\x00\x00\x00t\xb4\xc5 \x00\x00\x00\x00vT\r" +
+	"\xa0\x00\x00\x00\x00v\x8bl\xa0\x00\x00\x00\x00x*\xb5 \x00\x00\x00\x00xX٠\x00\x00\x00\x00y\xf8\" \x00\x00\x00\x00z/\x81 \x00\x00\x00\x00{\xceɠ\x00\x00\x00\x00|\x06(\xa0\x00\x00\x00" +
+	"\x00}\xa5q \x00\x00\x00\x00}ӕ\xa0\x00\x00\x00\x00\x7fr\xde \x00\x00\x00\x00\x7f\xaa= \x00\x00\x00\x00\x81I\x85\xa0\x00\x00\x00\x00\x81\x80\xe4\xa0\x00\x00\x00\x00\x83 - \x00\x00\x00\x00\x83NQ" +
+	"\xa0\x00\x00\x00\x00\x84\xed\x9a \x00\x00\x00\x00\x85$\xf9 \x00\x00\x00\x00\x86\xc4A\xa0\x00\x00\x00\x00\x86\xf2f \x00\x00\x00\x00\x88\x91\xae\xa0\x00\x00\x00\x00\x88\xc9\r\xa0\x00\x00\x00\x00\x8ahV \x00\x00\x00" +
+	"\x00\x8a\x9f\xb5 \x00\x00\x00\x00\x8c>\xfd\xa0\x00\x00\x00\x00\x8cm\" \x00\x00\x00\x00\x8e\fj\xa0\x00\x00\x00\x00\x8eCɠ\x00\x00\x00\x00\x8f\xe3\x12 \x00\x00\x00\x00\x90\x1aq \x00\x00\x00\x00\x91\xb9\xb9" +
+	"\xa0\x00\x00\x00\x00\x91\xe7\xde \x00\x00\x00\x00\x93\x87&\xa0\x00\x00\x00\x00\x93\xbe\x85\xa0\x00\x00\x00\x00\x95]\xce \x00\x00\x00\x00\x95\x8b\xf2\xa0\x00\x00\x00\x00\x97+; \x00\x00\x00\x00\x97b\x9a \x00\x00\x00" +
+	"\x00\x99\x01\xe2\xa0\x00\x00\x00\x00\x999A\xa0\x00\x00\x00\x00\x9a؊ \x00\x00\x00\x00\x9b\x06\xae\xa0\x00\x00\x00\x00\x9c\xa5\xf7 \x00\x00\x00\x00\x9c\xddV \x00\x00\x00\x00\x9e|\x9e\xa0\x00\x00\x00\x00\x9e\xb3\xfd" +
+	"\xa0\x00\x00\x00\x00\xa0SF \x00\x00\x00\x00\xa0\x81j\xa0\x00\x00\x00\x00\xa2 \xb3 \x00\x00\x00\x00\xa2X\x12 \x00\x00\x00\x00\xa3\xf7Z\xa0\x00\x00\x00\x00\xa4%\x7f \x00\x00\x00\x00\xa5\xc4Ǡ\x00\x00\x00" +
+	"\x00\xa5\xfc&\xa0\x00\x00\x00\x00\xa7\x9bo \x00\x00\x00\x00\xa7\xd2\xce \x00\x00\x00\x00\xa9r\x16\xa0\x00\x00\x00\x00\xa9\xa0; \x00\x00\x00\x00\xab?\x83\xa0\x00\x00\x00\x00\xabv\xe2\xa0\x00\x00\x00\x00\xad\x16+" +
+	" \x00\x00\x00\x00\xadM\x8a \x00\x00\x00\x00\xae\xecҠ\x00\x00\x00\x00\xaf\x1a\xf7 \x00\x00\x00\x00\xb0\xba?\xa0\x00\x00\x00\x00\xb0\xf1\x9e\xa0\x00\x00\x00\x00\xb2\x90\xe7 \x00\x00\x00\x00\xb2\xbf\v\xa0\x00\x00\x00" +
+	"\x00\xb4^T \x00\x00\x00\x00\xb4\x95\xb3 \x00\x00\x00\x00\xb64\xfb\xa0\x00\x00\x00\x00\xb6lZ\xa0\x00\x00\x00\x00\xb8\v\xa3 \x00\x00\x00\x00\xb89Ǡ\x00\x00\x00\x00\xb9\xd9\x10 \x00\x00\x00\x00\xba\x10o" +
+	" \x00\x00\x00\x00\xbb\xaf\xb7\xa0\x00\x00\x00\x00\xbb\xe7\x16\xa0\x00\x00\x00\x00\xbd\x86_ \x00\x00\x00\x00\xbd\xb4\x83\xa0\x00\x00\x00\x00\xbfS\xcc \x00\x00\x00\x00\xbf\x8b+ \x00\x00\x00\x00\xc1*s\xa0\x00\x00\x00" +
+	"\x00\xc1X\x98 \x00\x00\x00\x00\xc2\xf7\xe0\xa0\x00\x00\x00\x00\xc3/?\xa0\x00\x00\x00\x00\xc4Έ \x00\x00\x00\x00\xc5\x05\xe7 \x00\x00\x00\x00ƥ/\xa0\x00\x00\x00\x00\xc6\xd3T \x00\x00\x00\x00\xc8r\x9c" +
+	"\xa0\x00\x00\x00\x00ȩ\xfb\xa0\x00\x00\x00\x00\xcaID \x00\x00\x00\x00ʀ\xa3 \x00\x00\x00\x00\xcc\x1f\xeb\xa0\x00\x00\x00\x00\xccN\x10 \x00\x00\x00\x00\xcd\xedX\xa0\x00\x00\x00\x00\xce$\xb7\xa0\x00\x00\x00" +
+	"\x00\xcf\xc4\x00 \x00\x00\x00\x00\xcf\xf2$\xa0\x00\x00\x00\x00ёm \x00\x00\x00\x00\xd1\xc8\xcc \x00\x00\x00\x00\xd3h\x14\xa0\x00\x00\x00\x00ӟs\xa0\x00\x00\x00\x00\xd5>\xbc \x00\x00\x00\x00\xd5l\xe0" +
+	"\xa0\x00\x00\x00\x00\xd7\f) \x00\x00\x00\x00\xd7C\x88 \x00\x00\x00\x00\xd8\xe2Р\x00\x00\x00\x00\xd9\x1a/\xa0\x00\x00\x00\x00ڹx \x00\x00\x00\x00\xda眠\x00\x00\x00\x00܆\xe5 \x00\x00\x00" +
+	"\x00ܾD \x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03" +
+	"\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" +
+	"\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" +
+	"\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\xff\xff\xf8\xe4\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x0e\x10\x00\x04\x00\x00\x00\x00\x01\bLMT\x00+01\x00" +
+	"+00\x00\n<+01>-1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f\x1b\xeb\xdd2\x02\x00\x002\x02\x00\x00\f\x00\x00\x00Africa/CeutaTZif2" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00\x05\x00\x00\x00\x16\xff\xff\xff\xff~6\xb5\x00\xff\xff\xff\xff\x9e\xd6up\xff\xff\xff\xff\x9f\xa1n`\xff\xff\xff\xff\xaa\x05" +
+	"\xefp\xff\xff\xff\xff\xaa\xe7n\x00\xff\xff\xff\xff\xadɧ\xf0\xff\xff\xff\xff\xae\xa72\x00\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x14\x00\xff\xff\xff\xff\xb1\x89z\x00\xff\xff\xff\xff\xb2p0\x80\xff\xff" +
+	"\xff\xff\xfb%r@\xff\xff\xff\xff\xfb\xc2\xefp\x00\x00\x00\x00\bk\x84\x80\x00\x00\x00\x00\b\xc6m\xf0\x00\x00\x00\x00\v\xe8\f\x00\x00\x00\x00\x00\faG\xf0\x00\x00\x00\x00\r\xc9?\x80\x00\x00\x00\x00\x0e\x8e" +
+	"\xf2p\x00\x00\x00\x00\x0f\xd3Q\x80\x00\x00\x00\x00\x10'\xa3p\x00\x00\x00\x00\x1a\xb7\xa6\x00\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00" +
+	"\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5" +
+	"%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00" +
+	"\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\xff\xff\xfb" +
+	"\x04\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x0e\x10\x01\b\x00\x00\x0e\x10\x00\r\x00\x00\x1c \x01\x11LMT\x00WET\x00WEST\x00CET\x00CEST\x00\nCET-1CEST," +
+	"M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0e\x00\x00\x00Africa/Conakr" +
+	"yTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT" +
+	"\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\f\x00\x00\x00Africa/DakarTZif2\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGM" +
+	"T0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\x14\x00\x00\x00Africa/Dar_es_SalaamTZif2\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1\xed\xadX" +
+	"\xff\xff\xff\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\"\x84\x00\x00\x00\x00#(\x00\x04\x00\x00*0\x00\n\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00+0245\x00\nEA" +
+	"T-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\x0f\x00\x00\x00Africa/DjiboutiTZif2\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1\xed\xadX\xff\xff\xff\xff" +
+	"\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\"\x84\x00\x00\x00\x00#(\x00\x04\x00\x00*0\x00\n\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00+0245\x00\nEAT-3\n" +
+	"PK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\r\x00\x00\x00Africa/DoualaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x86\xabp\xd1\xff\xff\xff\xff\x8cP`\x00\xff\xff\xff\xff\x96\xaaC\xd1\xff\xff\xff\xff\xa1Q\xefx\x01\x00\x02\x03\x00\x00\x03/\x00\x00" +
+	"\x00\x00\x00\x00\x00\x04\x00\x00\a\b\x00\b\x00\x00\x0e\x10\x00\x0eLMT\x00GMT\x00+0030\x00WAT\x00\nWAT-1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)\xae\x8e" +
+	"o&\a\x00\x00&\a\x00\x00\x0f\x00\x00\x00Africa/El_AaiunTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xba\x00\x00\x00\x06\x00" +
+	"\x00\x00\x10\xff\xff\xff\xff\xbcH\xf0\xe0\x00\x00\x00\x00\vѰ\x90\x00\x00\x00\x00\v\xe8\f\x00\x00\x00\x00\x00\faG\xf0\x00\x00\x00\x00\r\xc9?\x80\x00\x00\x00\x00\x0e\x8e\xf2p\x00\x00\x00\x00\x0f\xd3Q\x80\x00" +
+	"\x00\x00\x00\x10'\xa3p\x00\x00\x00\x00HA\xe6\x80\x00\x00\x00\x00H\xbb\"p\x00\x00\x00\x00J#\x1a\x00\x00\x00\x00\x00J\x8d\xd5p\x00\x00\x00\x00K\xdc\xc0\x80\x00\x00\x00\x00L]\xe5p\x00\x00\x00\x00M" +
+	"\x97\xb8\x80\x00\x00\x00\x00N4\x8c\xf0\x00\x00\x00\x00O\x9c\xa0\xa0\x00\x00\x00\x00P\b\xbb\xa0\x00\x00\x00\x00P1\x9a \x00\x00\x00\x00Pg\xa7\xa0\x00\x00\x00\x00Q|\x82\xa0\x00\x00\x00\x00Q\xd8ˠ\x00" +
+	"\x00\x00\x00R\x05\x9e\xa0\x00\x00\x00\x00Rls\xa0\x00\x00\x00\x00S7z\xa0\x00\x00\x00\x00S\xae!\xa0\x00\x00\x00\x00S\xdcF \x00\x00\x00\x00TLU\xa0\x00\x00\x00\x00U\x17\\\xa0\x00\x00\x00\x00U" +
+	"|\xe0 \x00\x00\x00\x00U\xab\x04\xa0\x00\x00\x00\x00V,7\xa0\x00\x00\x00\x00V\xf7>\xa0\x00\x00\x00\x00WS\x87\xa0\x00\x00\x00\x00W\x81\xac \x00\x00\x00\x00X\x15T \x00\x00\x00\x00X\xd7 \xa0\x00" +
+	"\x00\x00\x00Y \xf4\xa0\x00\x00\x00\x00YXS\xa0\x00\x00\x00\x00Y\xf56 \x00\x00\x00\x00Z\xb7\x02\xa0\x00\x00\x00\x00Z\xf7\x9c \x00\x00\x00\x00[%\xc0\xa0\x00\x00\x00\x00[\xd5\x18 \x00\x00\x00\x00\\" +
+	"\xceC\xa0\x00\x00\x00\x00\\\xfch \x00\x00\x00\x00^\x9b\xb0\xa0\x00\x00\x00\x00^\xd3\x0f\xa0\x00\x00\x00\x00`rX \x00\x00\x00\x00`\xa0|\xa0\x00\x00\x00\x00b?\xc5 \x00\x00\x00\x00bw$ \x00" +
+	"\x00\x00\x00d\x16l\xa0\x00\x00\x00\x00dMˠ\x00\x00\x00\x00e\xed\x14 \x00\x00\x00\x00f\x1b8\xa0\x00\x00\x00\x00g\xba\x81 \x00\x00\x00\x00g\xf1\xe0 \x00\x00\x00\x00i\x91(\xa0\x00\x00\x00\x00i" +
+	"\xbfM \x00\x00\x00\x00kg\xd0 \x00\x00\x00\x00k\x95\xf4\xa0\x00\x00\x00\x00m5= \x00\x00\x00\x00ml\x9c \x00\x00\x00\x00o\v\xe4\xa0\x00\x00\x00\x00o:\t \x00\x00\x00\x00p\xd9Q\xa0\x00" +
+	"\x00\x00\x00q\x10\xb0\xa0\x00\x00\x00\x00r\xaf\xf9 \x00\x00\x00\x00r\xe7X \x00\x00\x00\x00t\x86\xa0\xa0\x00\x00\x00\x00t\xb4\xc5 \x00\x00\x00\x00vT\r\xa0\x00\x00\x00\x00v\x8bl\xa0\x00\x00\x00\x00x" +
+	"*\xb5 \x00\x00\x00\x00xX٠\x00\x00\x00\x00y\xf8\" \x00\x00\x00\x00z/\x81 \x00\x00\x00\x00{\xceɠ\x00\x00\x00\x00|\x06(\xa0\x00\x00\x00\x00}\xa5q \x00\x00\x00\x00}ӕ\xa0\x00" +
+	"\x00\x00\x00\x7fr\xde \x00\x00\x00\x00\x7f\xaa= \x00\x00\x00\x00\x81I\x85\xa0\x00\x00\x00\x00\x81\x80\xe4\xa0\x00\x00\x00\x00\x83 - \x00\x00\x00\x00\x83NQ\xa0\x00\x00\x00\x00\x84\xed\x9a \x00\x00\x00\x00\x85" +
+	"$\xf9 \x00\x00\x00\x00\x86\xc4A\xa0\x00\x00\x00\x00\x86\xf2f \x00\x00\x00\x00\x88\x91\xae\xa0\x00\x00\x00\x00\x88\xc9\r\xa0\x00\x00\x00\x00\x8ahV \x00\x00\x00\x00\x8a\x9f\xb5 \x00\x00\x00\x00\x8c>\xfd\xa0\x00" +
+	"\x00\x00\x00\x8cm\" \x00\x00\x00\x00\x8e\fj\xa0\x00\x00\x00\x00\x8eCɠ\x00\x00\x00\x00\x8f\xe3\x12 \x00\x00\x00\x00\x90\x1aq \x00\x00\x00\x00\x91\xb9\xb9\xa0\x00\x00\x00\x00\x91\xe7\xde \x00\x00\x00\x00\x93" +
+	"\x87&\xa0\x00\x00\x00\x00\x93\xbe\x85\xa0\x00\x00\x00\x00\x95]\xce \x00\x00\x00\x00\x95\x8b\xf2\xa0\x00\x00\x00\x00\x97+; \x00\x00\x00\x00\x97b\x9a \x00\x00\x00\x00\x99\x01\xe2\xa0\x00\x00\x00\x00\x999A\xa0\x00" +
+	"\x00\x00\x00\x9a؊ \x00\x00\x00\x00\x9b\x06\xae\xa0\x00\x00\x00\x00\x9c\xa5\xf7 \x00\x00\x00\x00\x9c\xddV \x00\x00\x00\x00\x9e|\x9e\xa0\x00\x00\x00\x00\x9e\xb3\xfd\xa0\x00\x00\x00\x00\xa0SF \x00\x00\x00\x00\xa0" +
+	"\x81j\xa0\x00\x00\x00\x00\xa2 \xb3 \x00\x00\x00\x00\xa2X\x12 \x00\x00\x00\x00\xa3\xf7Z\xa0\x00\x00\x00\x00\xa4%\x7f \x00\x00\x00\x00\xa5\xc4Ǡ\x00\x00\x00\x00\xa5\xfc&\xa0\x00\x00\x00\x00\xa7\x9bo \x00" +
+	"\x00\x00\x00\xa7\xd2\xce \x00\x00\x00\x00\xa9r\x16\xa0\x00\x00\x00\x00\xa9\xa0; \x00\x00\x00\x00\xab?\x83\xa0\x00\x00\x00\x00\xabv\xe2\xa0\x00\x00\x00\x00\xad\x16+ \x00\x00\x00\x00\xadM\x8a \x00\x00\x00\x00\xae" +
+	"\xecҠ\x00\x00\x00\x00\xaf\x1a\xf7 \x00\x00\x00\x00\xb0\xba?\xa0\x00\x00\x00\x00\xb0\xf1\x9e\xa0\x00\x00\x00\x00\xb2\x90\xe7 \x00\x00\x00\x00\xb2\xbf\v\xa0\x00\x00\x00\x00\xb4^T \x00\x00\x00\x00\xb4\x95\xb3 \x00" +
+	"\x00\x00\x00\xb64\xfb\xa0\x00\x00\x00\x00\xb6lZ\xa0\x00\x00\x00\x00\xb8\v\xa3 \x00\x00\x00\x00\xb89Ǡ\x00\x00\x00\x00\xb9\xd9\x10 \x00\x00\x00\x00\xba\x10o \x00\x00\x00\x00\xbb\xaf\xb7\xa0\x00\x00\x00\x00\xbb" +
+	"\xe7\x16\xa0\x00\x00\x00\x00\xbd\x86_ \x00\x00\x00\x00\xbd\xb4\x83\xa0\x00\x00\x00\x00\xbfS\xcc \x00\x00\x00\x00\xbf\x8b+ \x00\x00\x00\x00\xc1*s\xa0\x00\x00\x00\x00\xc1X\x98 \x00\x00\x00\x00\xc2\xf7\xe0\xa0\x00" +
+	"\x00\x00\x00\xc3/?\xa0\x00\x00\x00\x00\xc4Έ \x00\x00\x00\x00\xc5\x05\xe7 \x00\x00\x00\x00ƥ/\xa0\x00\x00\x00\x00\xc6\xd3T \x00\x00\x00\x00\xc8r\x9c\xa0\x00\x00\x00\x00ȩ\xfb\xa0\x00\x00\x00\x00\xca" +
+	"ID \x00\x00\x00\x00ʀ\xa3 \x00\x00\x00\x00\xcc\x1f\xeb\xa0\x00\x00\x00\x00\xccN\x10 \x00\x00\x00\x00\xcd\xedX\xa0\x00\x00\x00\x00\xce$\xb7\xa0\x00\x00\x00\x00\xcf\xc4\x00 \x00\x00\x00\x00\xcf\xf2$\xa0\x00" +
+	"\x00\x00\x00ёm \x00\x00\x00\x00\xd1\xc8\xcc \x00\x00\x00\x00\xd3h\x14\xa0\x00\x00\x00\x00ӟs\xa0\x00\x00\x00\x00\xd5>\xbc \x00\x00\x00\x00\xd5l\xe0\xa0\x00\x00\x00\x00\xd7\f) \x00\x00\x00\x00\xd7" +
+	"C\x88 \x00\x00\x00\x00\xd8\xe2Р\x00\x00\x00\x00\xd9\x1a/\xa0\x00\x00\x00\x00ڹx \x00\x00\x00\x00\xda眠\x00\x00\x00\x00܆\xe5 \x00\x00\x00\x00ܾD \x01\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" +
+	"\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" +
+	"\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\xff\xff\xf3" +
+	"\xa0\x00\x00\xff\xff\xf1\xf0\x00\x04\x00\x00\x0e\x10\x01\b\x00\x00\x00\x00\x00\f\x00\x00\x00\x00\x01\f\x00\x00\x0e\x10\x00\bLMT\x00-01\x00+01\x00+00\x00\n<+01>-1\nPK" +
+	"\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0f\x00\x00\x00Africa/FreetownTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\x0f\x00\x00\x00Africa/GaboroneTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00\nCAT-2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\r\x00\x00\x00Africa/HarareTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00" +
+	"\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00\nCAT-2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcc\fT" +
+	"ξ\x00\x00\x00\xbe\x00\x00\x00\x13\x00\x00\x00Africa/JohannesburgTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00" +
+	"\x00\x00\x04\x00\x00\x00\t\xff\xff\xff\xffm{A@\xff\xff\xff\xff\x82F\xcfh\xff\xff\xff\xff̮\x8c\x80\xff\xff\xff\xff͞op\xff\xff\xff\xffΎn\x80\xff\xff\xff\xff\xcf~Qp\x01\x03\x02\x03\x02" +
+	"\x03\x00\x00\x1a@\x00\x00\x00\x00\x15\x18\x00\x04\x00\x00*0\x01\x04\x00\x00\x1c \x00\x04LMT\x00SAST\x00\nSAST-2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\xcf\x10n" +
+	"\xca\x01\x00\x00\xca\x01\x00\x00\v\x00\x00\x00Africa/JubaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00#\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff" +
+	"\xff\xff\xb6\xa3\xda\xdc\x00\x00\x00\x00\x00\x9e\x17\xe0\x00\x00\x00\x00\x01z4P\x00\x00\x00\x00\x02}\xf9\xe0\x00\x00\x00\x00\x03[g\xd0\x00\x00\x00\x00\x04`~\xe0\x00\x00\x00\x00\x05=\xec\xd0\x00\x00\x00\x00\x06@" +
+	"`\xe0\x00\x00\x00\x00\a\x1f P\x00\x00\x00\x00\b B\xe0\x00\x00\x00\x00\t\x00S\xd0\x00\x00\x00\x00\n\x00$\xe0\x00\x00\x00\x00\n\xe1\x87P\x00\x00\x00\x00\v\xe0\x06\xe0\x00\x00\x00\x00\f\xc4\fP\x00\x00" +
+	"\x00\x00\r\xbf\xe8\xe0\x00\x00\x00\x00\x0e\xa5?\xd0\x00\x00\x00\x00\x0f\xa9\x05`\x00\x00\x00\x00\x10\x86sP\x00\x00\x00\x00\x11\x88\xe7`\x00\x00\x00\x00\x12g\xa6\xd0\x00\x00\x00\x00\x13h\xc9`\x00\x00\x00\x00\x14J" +
+	"+\xd0\x00\x00\x00\x00\x15H\xab`\x00\x00\x00\x00\x16+_P\x00\x00\x00\x00\x17(\x8d`\x00\x00\x00\x00\x18\f\x92\xd0\x00\x00\x00\x00\x19\bo`\x00\x00\x00\x00\x19\xed\xc6P\x00\x00\x00\x00\x1a\xf1\x8b\xe0\x00\x00" +
+	"\x00\x00\x1b\xd0KP\x00\x00\x00\x00\x1c\xd1m\xe0\x00\x00\x00\x00\x1d\xb1~\xd0\x00\x00\x00\x008\x80E \x00\x00\x00\x00`\x17\x1aP\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x00\x00\x1d\xa4\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\t\x00\x00*0\x00\rLMT\x00CAST\x00CAT\x00EAT\x00\nCAT-2" +
+	"\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\x0e\x00\x00\x00Africa/KampalaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1\xed\xadX\xff\xff\xff\xff\xcclz\xd4" +
+	"\x01\x02\x01\x03\x02\x00\x00\"\x84\x00\x00\x00\x00#(\x00\x04\x00\x00*0\x00\n\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00+0245\x00\nEAT-3\nPK\x03\x04" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\xadD\xef\xca\x01\x00\x00\xca\x01\x00\x00\x0f\x00\x00\x00Africa/KhartoumTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00#\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff\xb6\xa3\xda\x00\x00\x00\x00\x00\x00\x9e\x17\xe0\x00\x00\x00\x00\x01z4P\x00\x00\x00\x00\x02}\xf9\xe0\x00\x00\x00\x00\x03[g\xd0\x00\x00\x00\x00" +
+	"\x04`~\xe0\x00\x00\x00\x00\x05=\xec\xd0\x00\x00\x00\x00\x06@`\xe0\x00\x00\x00\x00\a\x1f P\x00\x00\x00\x00\b B\xe0\x00\x00\x00\x00\t\x00S\xd0\x00\x00\x00\x00\n\x00$\xe0\x00\x00\x00\x00\n\xe1\x87P" +
+	"\x00\x00\x00\x00\v\xe0\x06\xe0\x00\x00\x00\x00\f\xc4\fP\x00\x00\x00\x00\r\xbf\xe8\xe0\x00\x00\x00\x00\x0e\xa5?\xd0\x00\x00\x00\x00\x0f\xa9\x05`\x00\x00\x00\x00\x10\x86sP\x00\x00\x00\x00\x11\x88\xe7`\x00\x00\x00\x00" +
+	"\x12g\xa6\xd0\x00\x00\x00\x00\x13h\xc9`\x00\x00\x00\x00\x14J+\xd0\x00\x00\x00\x00\x15H\xab`\x00\x00\x00\x00\x16+_P\x00\x00\x00\x00\x17(\x8d`\x00\x00\x00\x00\x18\f\x92\xd0\x00\x00\x00\x00\x19\bo`" +
+	"\x00\x00\x00\x00\x19\xed\xc6P\x00\x00\x00\x00\x1a\xf1\x8b\xe0\x00\x00\x00\x00\x1b\xd0KP\x00\x00\x00\x00\x1c\xd1m\xe0\x00\x00\x00\x00\x1d\xb1~\xd0\x00\x00\x00\x008\x80E \x00\x00\x00\x00Y\xf8\xe4P\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x00\x00\x1e\x80\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\t\x00\x00*0\x00\rLMT\x00C" +
+	"AST\x00CAT\x00EAT\x00\nCAT-2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\r\x00\x00\x00Africa/Kiga" +
+	"liTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LM" +
+	"T\x00CAT\x00\nCAT-2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x0f\x00\x00\x00Africa/KinshasaTZ" +
+	"if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x86\xabp\xd1\xff\xff\xff\xff\x8cP`\x00\xff\xff\xff\xff\x96\xaaC\xd1\xff\xff\xff" +
+	"\xff\xa1Q\xefx\x01\x00\x02\x03\x00\x00\x03/\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\a\b\x00\b\x00\x00\x0e\x10\x00\x0eLMT\x00GMT\x00+0030\x00WAT\x00\nWAT-1\nPK" +
+	"\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\f\x00\x00\x00Africa/LagosTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x86\xabp\xd1\xff\xff\xff\xff\x8cP`\x00\xff\xff\xff\xff\x96\xaaC\xd1\xff\xff\xff\xff\xa1Q\xefx\x01\x00\x02\x03\x00\x00\x03/\x00\x00\x00\x00\x00" +
+	"\x00\x00\x04\x00\x00\a\b\x00\b\x00\x00\x0e\x10\x00\x0eLMT\x00GMT\x00+0030\x00WAT\x00\nWAT-1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00" +
+	"\x00\x00\xb4\x00\x00\x00\x11\x00\x00\x00Africa/LibrevilleTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
 	"\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00" +
 	"\x00\x12\xff\xff\xff\xff\x86\xabp\xd1\xff\xff\xff\xff\x8cP`\x00\xff\xff\xff\xff\x96\xaaC\xd1\xff\xff\xff\xff\xa1Q\xefx\x01\x00\x02\x03\x00\x00\x03/\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\a\b\x00\b\x00\x00\x0e\x10" +
-	"\x00\x0eLMT\x00GMT\x00+0030\x00WAT\x00\nWAT-1\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\r\x00\x1c\x00Afr" +
-	"ica/BanjulUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej" +
-	"\xbeT\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0e\x00\x1c\x00Africa/AbidjanUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00" +
-	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00" +
-	"GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\r\x00\x1c\x00Africa/AsmaraUT\t\x00\x03\xdc\xfc" +
-	"\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff" +
-	"\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1\xed\xadX\xff\xff\xff\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\"\x84\x00\x00\x00\x00#(\x00\x04\x00\x00*0\x00\n\x00" +
-	"\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00+0245\x00\nEAT-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\r\x00" +
-	"\x1c\x00Africa/BamakoUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00" +
-	"\x00\x00\x00\x8ej\xbeT\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x12\x00\x1c\x00Africa/OuagadougouUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04" +
-	"\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" +
-	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00" +
-	"\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\r\x00\x1c\x00Africa/Lusa" +
-	"kaUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" +
-	"\x02\x00\x00\x00\b\xff\xff\xff\xff\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00\nCAT-2\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\xa7\x1d\xb3c\xb4" +
-	"\x00\x00\x00\xb4\x00\x00\x00\r\x00\x1c\x00Africa/LuandaUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x86\xabp\xd1\xff\xff\xff\xff\x8cP`\x00\xff\xff\xff\xff\x96\xaaC\xd1\xff\xff\xff\xff\xa1Q\xefx\x01" +
-	"\x00\x02\x03\x00\x00\x03/\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\a\b\x00\b\x00\x00\x0e\x10\x00\x0eLMT\x00GMT\x00+0030\x00WAT\x00\nWAT-1\nPK\x03\x04\n\x00\x00\x00" +
-	"\x00\x00\x8ej\xbeT\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\r\x00\x1c\x00Africa/AsmeraUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S" +
-	"_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00" +
+	"\x00\x0eLMT\x00GMT\x00+0030\x00WAT\x00\nWAT-1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\v\x00\x00\x00Afr" +
+	"ica/LomeTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00T" +
+	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00" +
+	"\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\r\x00\x00\x00Africa/Luand" +
+	"aTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x86\xabp\xd1\xff\xff\xff\xff\x8cP`\x00\xff\xff\xff\xff\x96\xaaC\xd1" +
+	"\xff\xff\xff\xff\xa1Q\xefx\x01\x00\x02\x03\x00\x00\x03/\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\a\b\x00\b\x00\x00\x0e\x10\x00\x0eLMT\x00GMT\x00+0030\x00WAT\x00\nWAT-1" +
+	"\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\x11\x00\x00\x00Africa/LubumbashiTZif2\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00\nCAT-2\nP" +
+	"K\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\r\x00\x00\x00Africa/LusakaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00\nCAT-2\nPK\x03\x04\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\r\x00\x00\x00Africa/MalaboTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x86\xabp\xd1\xff\xff\xff\xff\x8cP`\x00\xff\xff\xff\xff\x96\xaaC\xd1\xff\xff\xff\xff\xa1Q\xefx\x01\x00\x02\x03\x00\x00\x03/\x00\x00\x00\x00\x00\x00\x00\x04\x00" +
+	"\x00\a\b\x00\b\x00\x00\x0e\x10\x00\x0eLMT\x00GMT\x00+0030\x00WAT\x00\nWAT-1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00" +
+	"\x00\x00\r\x00\x00\x00Africa/MaputoTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00" +
+	"\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x82F" +
+	"\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00\nCAT-2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcc\fTξ\x00\x00\x00\xbe\x00\x00\x00\r\x00\x00\x00" +
+	"Africa/MaseruTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00" +
+	"\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x04\x00\x00\x00\t\xff\xff\xff\xffm{A@\xff\xff\xff\xff" +
+	"\x82F\xcfh\xff\xff\xff\xff̮\x8c\x80\xff\xff\xff\xff͞op\xff\xff\xff\xffΎn\x80\xff\xff\xff\xff\xcf~Qp\x01\x03\x02\x03\x02\x03\x00\x00\x1a@\x00\x00\x00\x00\x15\x18\x00\x04\x00\x00*0\x01\x04" +
+	"\x00\x00\x1c \x00\x04LMT\x00SAST\x00\nSAST-2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcc\fTξ\x00\x00\x00\xbe\x00\x00\x00\x0e\x00\x00\x00Africa/" +
+	"MbabaneTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZ" +
+	"if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x04\x00\x00\x00\t\xff\xff\xff\xffm{A@\xff\xff\xff\xff\x82F\xcfh\xff\xff" +
+	"\xff\xff̮\x8c\x80\xff\xff\xff\xff͞op\xff\xff\xff\xffΎn\x80\xff\xff\xff\xff\xcf~Qp\x01\x03\x02\x03\x02\x03\x00\x00\x1a@\x00\x00\x00\x00\x15\x18\x00\x04\x00\x00*0\x01\x04\x00\x00\x1c \x00\x04" +
+	"LMT\x00SAST\x00\nSAST-2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\x10\x00\x00\x00Africa/Mogadi" +
+	"shuTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00" +
 	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7" +
 	"\xe0\xd0\xff\xff\xff\xff\xc1\xed\xadX\xff\xff\xff\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\"\x84\x00\x00\x00\x00#(\x00\x04\x00\x00*0\x00\n\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT" +
-	"\x00+0245\x00\nEAT-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\x11\x00\x1c\x00Africa/Lubumbash" +
-	"iUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02" +
-	"\x00\x00\x00\b\xff\xff\xff\xff\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00\nCAT-2\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\xf1\b{\x87\x82\x00" +
-	"\x00\x00\x82\x00\x00\x00\f\x00\x1c\x00Africa/AccraUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\n" +
-	"PK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeTV\xadD\xef\xca\x01\x00\x00\xca\x01\x00\x00\x0f\x00\x1c\x00Africa/KhartoumUT\t\x00\x03\xdc\xfc\x94b\xdc\xfc\x94bux" +
-	"\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00" +
-	"\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00#\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff\xb6\xa3\xda\x00\x00\x00\x00\x00" +
-	"\x00\x9e\x17\xe0\x00\x00\x00\x00\x01z4P\x00\x00\x00\x00\x02}\xf9\xe0\x00\x00\x00\x00\x03[g\xd0\x00\x00\x00\x00\x04`~\xe0\x00\x00\x00\x00\x05=\xec\xd0\x00\x00\x00\x00\x06@`\xe0\x00\x00\x00\x00\a\x1f P" +
-	"\x00\x00\x00\x00\b B\xe0\x00\x00\x00\x00\t\x00S\xd0\x00\x00\x00\x00\n\x00$\xe0\x00\x00\x00\x00\n\xe1\x87P\x00\x00\x00\x00\v\xe0\x06\xe0\x00\x00\x00\x00\f\xc4\fP\x00\x00\x00\x00\r\xbf\xe8\xe0\x00\x00\x00\x00" +
-	"\x0e\xa5?\xd0\x00\x00\x00\x00\x0f\xa9\x05`\x00\x00\x00\x00\x10\x86sP\x00\x00\x00\x00\x11\x88\xe7`\x00\x00\x00\x00\x12g\xa6\xd0\x00\x00\x00\x00\x13h\xc9`\x00\x00\x00\x00\x14J+\xd0\x00\x00\x00\x00\x15H\xab`" +
-	"\x00\x00\x00\x00\x16+_P\x00\x00\x00\x00\x17(\x8d`\x00\x00\x00\x00\x18\f\x92\xd0\x00\x00\x00\x00\x19\bo`\x00\x00\x00\x00\x19\xed\xc6P\x00\x00\x00\x00\x1a\xf1\x8b\xe0\x00\x00\x00\x00\x1b\xd0KP\x00\x00\x00\x00" +
-	"\x1c\xd1m\xe0\x00\x00\x00\x00\x1d\xb1~\xd0\x00\x00\x00\x008\x80E \x00\x00\x00\x00Y\xf8\xe4P\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x03\x02\x00\x00\x1e\x80\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\t\x00\x00*0\x00\rLMT\x00CAST\x00CAT\x00EAT\x00\nCAT-2\nPK\x03\x04\n\x00\x00\x00\x00" +
-	"\x00\x8fj\xbeT\x9f\x1b\xeb\xdd2\x02\x00\x002\x02\x00\x00\f\x00\x1c\x00Africa/CeutaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01" +
-	"\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00\x05\x00\x00\x00\x16\xff\xff\xff\xff~6\xb5\x00\xff\xff\xff\xff\x9e\xd6up\xff\xff\xff\xff\x9f\xa1n`" +
-	"\xff\xff\xff\xff\xaa\x05\xefp\xff\xff\xff\xff\xaa\xe7n\x00\xff\xff\xff\xff\xadɧ\xf0\xff\xff\xff\xff\xae\xa72\x00\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x14\x00\xff\xff\xff\xff\xb1\x89z\x00\xff\xff\xff\xff" +
-	"\xb2p0\x80\xff\xff\xff\xff\xfb%r@\xff\xff\xff\xff\xfb\xc2\xefp\x00\x00\x00\x00\bk\x84\x80\x00\x00\x00\x00\b\xc6m\xf0\x00\x00\x00\x00\v\xe8\f\x00\x00\x00\x00\x00\faG\xf0\x00\x00\x00\x00\r\xc9?\x80" +
-	"\x00\x00\x00\x00\x0e\x8e\xf2p\x00\x00\x00\x00\x0f\xd3Q\x80\x00\x00\x00\x00\x10'\xa3p\x00\x00\x00\x00\x1a\xb7\xa6\x00\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00" +
-	"!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90" +
-	"\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00" +
-	"/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" +
-	"\x04\x03\x04\xff\xff\xfb\x04\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x0e\x10\x01\b\x00\x00\x0e\x10\x00\r\x00\x00\x1c \x01\x11LMT\x00WET\x00WEST\x00CET\x00CEST\x00\nCET-" +
-	"1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\x10\x00\x1c\x00Africa/" +
-	"BujumburaUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00\nCAT-2\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej" +
-	"\xbeTm)\xb8P~\x02\x00\x00~\x02\x00\x00\x0f\x00\x1c\x00Africa/WindhoekUT\t\x00\x03\xdc\xfc\x94b\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01" +
-	"\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005\x00\x00\x00\x06\x00\x00\x00\x17\xff\xff\xff\xffm{Kx\xff\xff\xff\xff\x82F\xcfh\xff\xff\xff\xff̮\x8c\x80" +
-	"\xff\xff\xff\xff͞op\x00\x00\x00\x00&\x06\xa7\xe0\x00\x00\x00\x00-\x8c\xc7`\x00\x00\x00\x00.i\x1c\x10\x00\x00\x00\x00/}\xe9\x00\x00\x00\x00\x000H\xfe\x10\x00\x00\x00\x001g\x05\x80\x00\x00\x00\x00" +
-	"2(\xe0\x10\x00\x00\x00\x003F\xe7\x80\x00\x00\x00\x004\x11\xfc\x90\x00\x00\x00\x005&ɀ\x00\x00\x00\x005\xf1ސ\x00\x00\x00\x007\x06\xab\x80\x00\x00\x00\x007\xd1\xc0\x90\x00\x00\x00\x008捀" +
-	"\x00\x00\x00\x009\xb1\xa2\x90\x00\x00\x00\x00:\xc6o\x80\x00\x00\x00\x00;\x91\x84\x90\x00\x00\x00\x00<\xaf\x8c\x00\x00\x00\x00\x00=qf\x90\x00\x00\x00\x00>\x8fn\x00\x00\x00\x00\x00?Z\x83\x10\x00\x00\x00\x00" +
-	"@oP\x00\x00\x00\x00\x00A:e\x10\x00\x00\x00\x00BO2\x00\x00\x00\x00\x00C\x1aG\x10\x00\x00\x00\x00D/\x14\x00\x00\x00\x00\x00D\xfa)\x10\x00\x00\x00\x00F\x0e\xf6\x00\x00\x00\x00\x00F\xda\v\x10" +
-	"\x00\x00\x00\x00G\xf8\x12\x80\x00\x00\x00\x00H\xc3'\x90\x00\x00\x00\x00I\xd7\xf4\x80\x00\x00\x00\x00J\xa3\t\x90\x00\x00\x00\x00K\xb7ր\x00\x00\x00\x00L\x82\xeb\x90\x00\x00\x00\x00M\x97\xb8\x80\x00\x00\x00\x00" +
-	"Nb͐\x00\x00\x00\x00Ow\x9a\x80\x00\x00\x00\x00PB\xaf\x90\x00\x00\x00\x00Q`\xb7\x00\x00\x00\x00\x00R\"\x91\x90\x00\x00\x00\x00S@\x99\x00\x00\x00\x00\x00T\v\xae\x10\x00\x00\x00\x00U {\x00" +
-	"\x00\x00\x00\x00U\xeb\x90\x10\x00\x00\x00\x00W\x00]\x00\x00\x00\x00\x00W\xcbr\x10\x00\x00\x00\x00X\xe0?\x00\x00\x00\x00\x00Y\xabT\x10\x01\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" +
-	"\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x00\x00\x10\b\x00\x00\x00\x00\x15\x18\x00\x04\x00\x00\x1c \x00\n\x00\x00*0\x01\n\x00\x00\x0e" +
-	"\x10\x01\x0f\x00\x00\x1c \x00\x13LMT\x00+0130\x00SAST\x00WAT\x00CAT\x00\nCAT-2\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT)\xae\x8eo&\a\x00" +
-	"\x00&\a\x00\x00\x0f\x00\x1c\x00Africa/El_AaiunUT\t\x00\x03\xdc\xfc\x94b\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00" +
+	"\x00+0245\x00\nEAT-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x006\x99rU\xa4\x00\x00\x00\xa4\x00\x00\x00\x0f\x00\x00\x00Africa/MonroviaT" +
+	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xffZz\xa6\x9c\xff\xff\xff\xff\xa0_l\x9c\x00\x00\x00\x00\x03\xcaZn\x01\x02" +
+	"\x03\xff\xff\xf5\xe4\x00\x00\xff\xff\xf5\xe4\x00\x04\xff\xff\xf5\x92\x00\x04\x00\x00\x00\x00\x00\bLMT\x00MMT\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98" +
+	"ƿ\x00\x00\x00\xbf\x00\x00\x00\x0e\x00\x00\x00Africa/NairobiTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00" +
+	"\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1\xed\xadX\xff\xff\xff\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\"\x84\x00\x00\x00\x00#(\x00\x04\x00" +
+	"\x00*0\x00\n\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00+0245\x00\nEAT-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa\x81\t\x03\xa0\x00\x00\x00" +
+	"\xa0\x00\x00\x00\x0f\x00\x00\x00Africa/NdjamenaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\r\xff\xff" +
+	"\xff\xff\x92\xe6\x80d\x00\x00\x00\x00\x12fqp\x00\x00\x00\x00\x13&\xde`\x01\x02\x01\x00\x00\x0e\x1c\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\bLMT\x00WAT\x00WAST\x00\nWAT" +
+	"-1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\r\x00\x00\x00Africa/NiameyTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x86\xabp\xd1\xff\xff\xff\xff\x8cP`\x00\xff\xff\xff\xff\x96\xaaC\xd1\xff\xff\xff\xff\xa1Q\xefx\x01\x00\x02\x03\x00\x00\x03" +
+	"/\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\a\b\x00\b\x00\x00\x0e\x10\x00\x0eLMT\x00GMT\x00+0030\x00WAT\x00\nWAT-1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x11\x00\x00\x00Africa/NouakchottTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" +
+	"\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{" +
+	"\x87\x82\x00\x00\x00\x82\x00\x00\x00\x12\x00\x00\x00Africa/OuagadougouTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00" +
+	"\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4" +
+	"\x00\x00\x00\xb4\x00\x00\x00\x11\x00\x00\x00Africa/Porto-NovoTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00" +
+	"\x00\x00\x12\xff\xff\xff\xff\x86\xabp\xd1\xff\xff\xff\xff\x8cP`\x00\xff\xff\xff\xff\x96\xaaC\xd1\xff\xff\xff\xff\xa1Q\xefx\x01\x00\x02\x03\x00\x00\x03/\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\a\b\x00\b\x00\x00\x0e" +
+	"\x10\x00\x0eLMT\x00GMT\x00+0030\x00WAT\x00\nWAT-1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc1\n\x8a\x84\xad\x00\x00\x00\xad\x00\x00\x00\x0f\x00\x00\x00Af" +
+	"rica/Sao_TomeTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00" +
+	"\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xff^<\xfd0\xff\xff\xff\xff" +
+	"\x92掀\x00\x00\x00\x00ZI\x88\x10\x00\x00\x00\x00\\*\xbb\x90\x01\x02\x03\x02\x00\x00\x06P\x00\x00\xff\xff\xf7c\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x0e\x10\x00\bLMT\x00GMT\x00WAT\x00" +
+	"\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0f\x00\x00\x00Africa/TimbuktuTZif2\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0" +
+	"\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00_\x7f2[\xaf\x01\x00\x00\xaf\x01\x00\x00\x0e\x00\x00\x00Africa/TripoliTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff\xa1\xf2\xc1$\xff\xff\xff\xffݻ\xb1\x10\xff\xff\xff\xff\xde#\xad`\xff\xff\xff\xff\xe1x\xd2\x10\xff\xff\xff\xff\xe1\xe7e\xe0" +
+	"\xff\xff\xff\xff\xe5/?p\xff\xff\xff\xff\xe5\xa9\xcc\xe0\xff\xff\xff\xff\xebN\xc6\xf0\x00\x00\x00\x00\x16\x92B`\x00\x00\x00\x00\x17\b\xf7p\x00\x00\x00\x00\x17\xfa+\xe0\x00\x00\x00\x00\x18\xea*\xf0\x00\x00\x00\x00" +
+	"\x19\xdb_`\x00\x00\x00\x00\x1a̯\xf0\x00\x00\x00\x00\x1b\xbd\xe4`\x00\x00\x00\x00\x1c\xb4z\xf0\x00\x00\x00\x00\x1d\x9f\x17\xe0\x00\x00\x00\x00\x1e\x93\vp\x00\x00\x00\x00\x1f\x82\xee`\x00\x00\x00\x00 pJp" +
+	"\x00\x00\x00\x00!a~\xe0\x00\x00\x00\x00\"R\xcfp\x00\x00\x00\x00#D\x03\xe0\x00\x00\x00\x00$4\x02\xf0\x00\x00\x00\x00%%7`\x00\x00\x00\x00&@\xb7\xf0\x00\x00\x00\x002N\xf1`\x00\x00\x00\x00" +
+	"3D6p\x00\x00\x00\x0045j\xe0\x00\x00\x00\x00P\x9d\x99\x00\x00\x00\x00\x00QTـ\x00\x00\x00\x00Ri\xb4\x80\x02\x01\x02\x01\x02\x01\x02\x03\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x03\x02\x01\x03\x02\x01\x03\x00\x00\f\\\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x1c \x00\rLMT\x00CEST\x00CET\x00EET\x00\nEET-2\nPK\x03\x04" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x93\xf4\x94\v\xc1\x01\x00\x00\xc1\x01\x00\x00\f\x00\x00\x00Africa/TunisTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\"\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xffYF\x13\xf4\xff\xff\xff\xff\x91`PO\xff\xff\xff\xff\xc6:\x88\xe0\xff\xff\xff\xff\xc7X\x9e`\xff\xff\xff\xff\xc7\xdb\"\xe0\xff\xff\xff\xff\xca\xe2T" +
+	"\xe0\xff\xff\xff\xff˭i\xf0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\xcd\xc2\x16\x00\xff\xff\xff\xff\xcd̰\x10\xff\xff\xff\xff\u03a25\x00\xff\xff\xff\xffϒ4\x10\xff\xff\xff" +
+	"\xffЉ\xe3\xe0\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2N\x16`\x00\x00\x00\x00\r\xc7\xdf\xf0\x00\x00\x00\x00\x0e\x89\xacp\x00\x00\x00\x00\x0f\xaad\xf0\x00\x00\x00\x00\x10t\x1ap\x00\x00\x00\x00\"\xa3:" +
+	"\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&<\xc3p\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00Bt\r\xf0\x00\x00\x00\x00C<\x80\x00\x00\x00\x00" +
+	"\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00\t\x8c\x00\x00\x00\x00\x021\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\rLMT\x00PMT\x00CEST\x00CET\x00" +
+	"\nCET-1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00m)\xb8P~\x02\x00\x00~\x02\x00\x00\x0f\x00\x00\x00Africa/WindhoekTZif2\x00\x00\x00" +
 	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xba\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xbcH\xf0\xe0\x00\x00\x00\x00\vѰ\x90\x00\x00\x00\x00\v\xe8\f\x00\x00\x00\x00\x00\faG\xf0\x00" +
-	"\x00\x00\x00\r\xc9?\x80\x00\x00\x00\x00\x0e\x8e\xf2p\x00\x00\x00\x00\x0f\xd3Q\x80\x00\x00\x00\x00\x10'\xa3p\x00\x00\x00\x00HA\xe6\x80\x00\x00\x00\x00H\xbb\"p\x00\x00\x00\x00J#\x1a\x00\x00\x00\x00\x00J" +
-	"\x8d\xd5p\x00\x00\x00\x00K\xdc\xc0\x80\x00\x00\x00\x00L]\xe5p\x00\x00\x00\x00M\x97\xb8\x80\x00\x00\x00\x00N4\x8c\xf0\x00\x00\x00\x00O\x9c\xa0\xa0\x00\x00\x00\x00P\b\xbb\xa0\x00\x00\x00\x00P1\x9a \x00" +
-	"\x00\x00\x00Pg\xa7\xa0\x00\x00\x00\x00Q|\x82\xa0\x00\x00\x00\x00Q\xd8ˠ\x00\x00\x00\x00R\x05\x9e\xa0\x00\x00\x00\x00Rls\xa0\x00\x00\x00\x00S7z\xa0\x00\x00\x00\x00S\xae!\xa0\x00\x00\x00\x00S" +
-	"\xdcF \x00\x00\x00\x00TLU\xa0\x00\x00\x00\x00U\x17\\\xa0\x00\x00\x00\x00U|\xe0 \x00\x00\x00\x00U\xab\x04\xa0\x00\x00\x00\x00V,7\xa0\x00\x00\x00\x00V\xf7>\xa0\x00\x00\x00\x00WS\x87\xa0\x00" +
-	"\x00\x00\x00W\x81\xac \x00\x00\x00\x00X\x15T \x00\x00\x00\x00X\xd7 \xa0\x00\x00\x00\x00Y \xf4\xa0\x00\x00\x00\x00YXS\xa0\x00\x00\x00\x00Y\xf56 \x00\x00\x00\x00Z\xb7\x02\xa0\x00\x00\x00\x00Z" +
-	"\xf7\x9c \x00\x00\x00\x00[%\xc0\xa0\x00\x00\x00\x00[\xd5\x18 \x00\x00\x00\x00\\\xceC\xa0\x00\x00\x00\x00\\\xfch \x00\x00\x00\x00^\x9b\xb0\xa0\x00\x00\x00\x00^\xd3\x0f\xa0\x00\x00\x00\x00`rX \x00" +
-	"\x00\x00\x00`\xa0|\xa0\x00\x00\x00\x00b?\xc5 \x00\x00\x00\x00bw$ \x00\x00\x00\x00d\x16l\xa0\x00\x00\x00\x00dMˠ\x00\x00\x00\x00e\xed\x14 \x00\x00\x00\x00f\x1b8\xa0\x00\x00\x00\x00g" +
-	"\xba\x81 \x00\x00\x00\x00g\xf1\xe0 \x00\x00\x00\x00i\x91(\xa0\x00\x00\x00\x00i\xbfM \x00\x00\x00\x00kg\xd0 \x00\x00\x00\x00k\x95\xf4\xa0\x00\x00\x00\x00m5= \x00\x00\x00\x00ml\x9c \x00" +
-	"\x00\x00\x00o\v\xe4\xa0\x00\x00\x00\x00o:\t \x00\x00\x00\x00p\xd9Q\xa0\x00\x00\x00\x00q\x10\xb0\xa0\x00\x00\x00\x00r\xaf\xf9 \x00\x00\x00\x00r\xe7X \x00\x00\x00\x00t\x86\xa0\xa0\x00\x00\x00\x00t" +
-	"\xb4\xc5 \x00\x00\x00\x00vT\r\xa0\x00\x00\x00\x00v\x8bl\xa0\x00\x00\x00\x00x*\xb5 \x00\x00\x00\x00xX٠\x00\x00\x00\x00y\xf8\" \x00\x00\x00\x00z/\x81 \x00\x00\x00\x00{\xceɠ\x00" +
-	"\x00\x00\x00|\x06(\xa0\x00\x00\x00\x00}\xa5q \x00\x00\x00\x00}ӕ\xa0\x00\x00\x00\x00\x7fr\xde \x00\x00\x00\x00\x7f\xaa= \x00\x00\x00\x00\x81I\x85\xa0\x00\x00\x00\x00\x81\x80\xe4\xa0\x00\x00\x00\x00\x83" +
-	" - \x00\x00\x00\x00\x83NQ\xa0\x00\x00\x00\x00\x84\xed\x9a \x00\x00\x00\x00\x85$\xf9 \x00\x00\x00\x00\x86\xc4A\xa0\x00\x00\x00\x00\x86\xf2f \x00\x00\x00\x00\x88\x91\xae\xa0\x00\x00\x00\x00\x88\xc9\r\xa0\x00" +
-	"\x00\x00\x00\x8ahV \x00\x00\x00\x00\x8a\x9f\xb5 \x00\x00\x00\x00\x8c>\xfd\xa0\x00\x00\x00\x00\x8cm\" \x00\x00\x00\x00\x8e\fj\xa0\x00\x00\x00\x00\x8eCɠ\x00\x00\x00\x00\x8f\xe3\x12 \x00\x00\x00\x00\x90" +
-	"\x1aq \x00\x00\x00\x00\x91\xb9\xb9\xa0\x00\x00\x00\x00\x91\xe7\xde \x00\x00\x00\x00\x93\x87&\xa0\x00\x00\x00\x00\x93\xbe\x85\xa0\x00\x00\x00\x00\x95]\xce \x00\x00\x00\x00\x95\x8b\xf2\xa0\x00\x00\x00\x00\x97+; \x00" +
-	"\x00\x00\x00\x97b\x9a \x00\x00\x00\x00\x99\x01\xe2\xa0\x00\x00\x00\x00\x999A\xa0\x00\x00\x00\x00\x9a؊ \x00\x00\x00\x00\x9b\x06\xae\xa0\x00\x00\x00\x00\x9c\xa5\xf7 \x00\x00\x00\x00\x9c\xddV \x00\x00\x00\x00\x9e" +
-	"|\x9e\xa0\x00\x00\x00\x00\x9e\xb3\xfd\xa0\x00\x00\x00\x00\xa0SF \x00\x00\x00\x00\xa0\x81j\xa0\x00\x00\x00\x00\xa2 \xb3 \x00\x00\x00\x00\xa2X\x12 \x00\x00\x00\x00\xa3\xf7Z\xa0\x00\x00\x00\x00\xa4%\x7f \x00" +
-	"\x00\x00\x00\xa5\xc4Ǡ\x00\x00\x00\x00\xa5\xfc&\xa0\x00\x00\x00\x00\xa7\x9bo \x00\x00\x00\x00\xa7\xd2\xce \x00\x00\x00\x00\xa9r\x16\xa0\x00\x00\x00\x00\xa9\xa0; \x00\x00\x00\x00\xab?\x83\xa0\x00\x00\x00\x00\xab" +
-	"v\xe2\xa0\x00\x00\x00\x00\xad\x16+ \x00\x00\x00\x00\xadM\x8a \x00\x00\x00\x00\xae\xecҠ\x00\x00\x00\x00\xaf\x1a\xf7 \x00\x00\x00\x00\xb0\xba?\xa0\x00\x00\x00\x00\xb0\xf1\x9e\xa0\x00\x00\x00\x00\xb2\x90\xe7 \x00" +
-	"\x00\x00\x00\xb2\xbf\v\xa0\x00\x00\x00\x00\xb4^T \x00\x00\x00\x00\xb4\x95\xb3 \x00\x00\x00\x00\xb64\xfb\xa0\x00\x00\x00\x00\xb6lZ\xa0\x00\x00\x00\x00\xb8\v\xa3 \x00\x00\x00\x00\xb89Ǡ\x00\x00\x00\x00\xb9" +
-	"\xd9\x10 \x00\x00\x00\x00\xba\x10o \x00\x00\x00\x00\xbb\xaf\xb7\xa0\x00\x00\x00\x00\xbb\xe7\x16\xa0\x00\x00\x00\x00\xbd\x86_ \x00\x00\x00\x00\xbd\xb4\x83\xa0\x00\x00\x00\x00\xbfS\xcc \x00\x00\x00\x00\xbf\x8b+ \x00" +
-	"\x00\x00\x00\xc1*s\xa0\x00\x00\x00\x00\xc1X\x98 \x00\x00\x00\x00\xc2\xf7\xe0\xa0\x00\x00\x00\x00\xc3/?\xa0\x00\x00\x00\x00\xc4Έ \x00\x00\x00\x00\xc5\x05\xe7 \x00\x00\x00\x00ƥ/\xa0\x00\x00\x00\x00\xc6" +
-	"\xd3T \x00\x00\x00\x00\xc8r\x9c\xa0\x00\x00\x00\x00ȩ\xfb\xa0\x00\x00\x00\x00\xcaID \x00\x00\x00\x00ʀ\xa3 \x00\x00\x00\x00\xcc\x1f\xeb\xa0\x00\x00\x00\x00\xccN\x10 \x00\x00\x00\x00\xcd\xedX\xa0\x00" +
-	"\x00\x00\x00\xce$\xb7\xa0\x00\x00\x00\x00\xcf\xc4\x00 \x00\x00\x00\x00\xcf\xf2$\xa0\x00\x00\x00\x00ёm \x00\x00\x00\x00\xd1\xc8\xcc \x00\x00\x00\x00\xd3h\x14\xa0\x00\x00\x00\x00ӟs\xa0\x00\x00\x00\x00\xd5" +
-	">\xbc \x00\x00\x00\x00\xd5l\xe0\xa0\x00\x00\x00\x00\xd7\f) \x00\x00\x00\x00\xd7C\x88 \x00\x00\x00\x00\xd8\xe2Р\x00\x00\x00\x00\xd9\x1a/\xa0\x00\x00\x00\x00ڹx \x00\x00\x00\x00\xda眠\x00" +
-	"\x00\x00\x00܆\xe5 \x00\x00\x00\x00ܾD \x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04" +
-	"\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" +
-	"\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" +
-	"\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\xff\xff\xf3\xa0\x00\x00\xff\xff\xf1\xf0\x00\x04\x00\x00\x0e\x10\x01\b\x00\x00\x00\x00\x00\f\x00\x00\x00\x00\x01\f\x00\x00\x0e\x10\x00\bLMT" +
-	"\x00-01\x00+01\x00+00\x00\n<+01>-1\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT_\x7f2[\xaf\x01\x00\x00\xaf\x01\x00\x00\x0e\x00\x1c\x00Africa/T" +
-	"ripoliUT\t\x00\x03\xdc\xfc\x94b\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005\x00\x00\x00\x06\x00\x00\x00\x17\xff\xff\xff\xffm{Kx\xff\xff\xff\xff\x82F\xcfh\xff\xff\xff\xff̮\x8c\x80\xff\xff\xff\xff͞op\x00" +
+	"\x00\x00\x00&\x06\xa7\xe0\x00\x00\x00\x00-\x8c\xc7`\x00\x00\x00\x00.i\x1c\x10\x00\x00\x00\x00/}\xe9\x00\x00\x00\x00\x000H\xfe\x10\x00\x00\x00\x001g\x05\x80\x00\x00\x00\x002(\xe0\x10\x00\x00\x00\x003" +
+	"F\xe7\x80\x00\x00\x00\x004\x11\xfc\x90\x00\x00\x00\x005&ɀ\x00\x00\x00\x005\xf1ސ\x00\x00\x00\x007\x06\xab\x80\x00\x00\x00\x007\xd1\xc0\x90\x00\x00\x00\x008捀\x00\x00\x00\x009\xb1\xa2\x90\x00" +
+	"\x00\x00\x00:\xc6o\x80\x00\x00\x00\x00;\x91\x84\x90\x00\x00\x00\x00<\xaf\x8c\x00\x00\x00\x00\x00=qf\x90\x00\x00\x00\x00>\x8fn\x00\x00\x00\x00\x00?Z\x83\x10\x00\x00\x00\x00@oP\x00\x00\x00\x00\x00A" +
+	":e\x10\x00\x00\x00\x00BO2\x00\x00\x00\x00\x00C\x1aG\x10\x00\x00\x00\x00D/\x14\x00\x00\x00\x00\x00D\xfa)\x10\x00\x00\x00\x00F\x0e\xf6\x00\x00\x00\x00\x00F\xda\v\x10\x00\x00\x00\x00G\xf8\x12\x80\x00" +
+	"\x00\x00\x00H\xc3'\x90\x00\x00\x00\x00I\xd7\xf4\x80\x00\x00\x00\x00J\xa3\t\x90\x00\x00\x00\x00K\xb7ր\x00\x00\x00\x00L\x82\xeb\x90\x00\x00\x00\x00M\x97\xb8\x80\x00\x00\x00\x00Nb͐\x00\x00\x00\x00O" +
+	"w\x9a\x80\x00\x00\x00\x00PB\xaf\x90\x00\x00\x00\x00Q`\xb7\x00\x00\x00\x00\x00R\"\x91\x90\x00\x00\x00\x00S@\x99\x00\x00\x00\x00\x00T\v\xae\x10\x00\x00\x00\x00U {\x00\x00\x00\x00\x00U\xeb\x90\x10\x00" +
+	"\x00\x00\x00W\x00]\x00\x00\x00\x00\x00W\xcbr\x10\x00\x00\x00\x00X\xe0?\x00\x00\x00\x00\x00Y\xabT\x10\x01\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" +
+	"\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x00\x00\x10\b\x00\x00\x00\x00\x15\x18\x00\x04\x00\x00\x1c \x00\n\x00\x00*0\x01\n\x00\x00\x0e\x10\x01\x0f\x00\x00\x1c \x00\x13" +
+	"LMT\x00+0130\x00SAST\x00WAT\x00CAT\x00\nCAT-2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xae,\xa44\xc9\x03\x00\x00\xc9\x03\x00\x00\f\x00\x00\x00" +
+	"America/AdakTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00" +
+	"\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00T\x00\x00\x00\n\x00\x00\x00!\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}" +
+	"\x87Z^\xff\xff\xff\xffˉD\xd0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2aP@\xff\xff\xff\xff\xfa\xd2U\xb0\xff\xff\xff\xff\xfe\xb8qP\xff\xff\xff\xff\xff\xa8T@\x00\x00\x00\x00\x00\x98SP\x00" +
+	"\x00\x00\x00\x01\x886@\x00\x00\x00\x00\x02x5P\x00\x00\x00\x00\x03qR\xc0\x00\x00\x00\x00\x04aQ\xd0\x00\x00\x00\x00\x05Q4\xc0\x00\x00\x00\x00\x06A3\xd0\x00\x00\x00\x00\a1\x16\xc0\x00\x00\x00\x00\a" +
+	"\x8dm\xd0\x00\x00\x00\x00\t\x10\xf8\xc0\x00\x00\x00\x00\t\xad\xe9P\x00\x00\x00\x00\n\xf0\xda\xc0\x00\x00\x00\x00\v\xe0\xd9\xd0\x00\x00\x00\x00\f\xd9\xf7@\x00\x00\x00\x00\r\xc0\xbb\xd0\x00\x00\x00\x00\x0e\xb9\xd9@\x00" +
+	"\x00\x00\x00\x0f\xa9\xd8P\x00\x00\x00\x00\x10\x99\xbb@\x00\x00\x00\x00\x11\x89\xbaP\x00\x00\x00\x00\x12y\x9d@\x00\x00\x00\x00\x13i\x9cP\x00\x00\x00\x00\x14Y\x7f@\x00\x00\x00\x00\x15I~P\x00\x00\x00\x00\x16" +
+	"9a@\x00\x00\x00\x00\x17)`P\x00\x00\x00\x00\x18\"}\xc0\x00\x00\x00\x00\x19\tBP\x00\x00\x00\x00\x1a\x02_\xc0\x00\x00\x00\x00\x1a+\" \x00\x00\x00\x00\x1a\xf2P\xc0\x00\x00\x00\x00\x1b\xe23\xb0\x00" +
+	"\x00\x00\x00\x1c\xd22\xc0\x00\x00\x00\x00\x1d\xc2\x15\xb0\x00\x00\x00\x00\x1e\xb2\x14\xc0\x00\x00\x00\x00\x1f\xa1\xf7\xb0\x00\x00\x00\x00 vG@\x00\x00\x00\x00!\x81ٰ\x00\x00\x00\x00\"V)@\x00\x00\x00\x00#" +
+	"j\xf60\x00\x00\x00\x00$6\v@\x00\x00\x00\x00%J\xd80\x00\x00\x00\x00&\x15\xed@\x00\x00\x00\x00'*\xba0\x00\x00\x00\x00'\xff\t\xc0\x00\x00\x00\x00)\n\x9c0\x00\x00\x00\x00)\xde\xeb\xc0\x00" +
+	"\x00\x00\x00*\xea~0\x00\x00\x00\x00+\xbe\xcd\xc0\x00\x00\x00\x00,Ӛ\xb0\x00\x00\x00\x00-\x9e\xaf\xc0\x00\x00\x00\x00.\xb3|\xb0\x00\x00\x00\x00/~\x91\xc0\x00\x00\x00\x000\x93^\xb0\x00\x00\x00\x001" +
+	"g\xae@\x00\x00\x00\x002s@\xb0\x00\x00\x00\x003G\x90@\x00\x00\x00\x004S\"\xb0\x00\x00\x00\x005'r@\x00\x00\x00\x0063\x04\xb0\x00\x00\x00\x007\aT@\x00\x00\x00\x008\x1c!0\x00" +
+	"\x00\x00\x008\xe76@\x00\x00\x00\x009\xfc\x030\x00\x00\x00\x00:\xc7\x18@\x00\x00\x00\x00;\xdb\xe50\x00\x00\x00\x00<\xb04\xc0\x00\x00\x00\x00=\xbb\xc70\x00\x00\x00\x00>\x90\x16\xc0\x00\x00\x00\x00?" +
+	"\x9b\xa90\x00\x00\x00\x00@o\xf8\xc0\x00\x00\x00\x00A\x84Ű\x00\x00\x00\x00BO\xda\xc0\x00\x00\x00\x00Cd\xa7\xb0\x00\x00\x00\x00D/\xbc\xc0\x00\x00\x00\x00ED\x89\xb0\x00\x00\x00\x00E\xf3\xef@\x01" +
+	"\x02\x03\x04\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\a\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t" +
+	"\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\x00\x00\xab\xe2\x00\x00\xff\xffZb\x00\x00\xff\xffeP\x00\x04\xff\xffs`\x01\b\xff\xffs`\x01\f\xff\xffeP\x00\x10\xff" +
+	"\xffs`\x01\x14\xff\xffs`\x00\x18\xff\xff\x81p\x01\x1d\xff\xffs`\x00\x19LMT\x00NST\x00NWT\x00NPT\x00BST\x00BDT\x00AHST\x00HDT\x00\nHST" +
+	"10HDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005\x11Q\x06\xd1\x03\x00\x00\xd1\x03\x00\x00\x11\x00\x00\x00America/A" +
+	"nchorageTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00T" +
+	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00T\x00\x00\x00\n\x00\x00\x00(\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}\x87AH\xff" +
+	"\xff\xff\xffˉ6\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2aB0\xff\xff\xff\xff\xfa\xd2G\xa0\xff\xff\xff\xff\xfe\xb8c@\xff\xff\xff\xff\xff\xa8F0\x00\x00\x00\x00\x00\x98E@\x00\x00\x00\x00\x01" +
+	"\x88(0\x00\x00\x00\x00\x02x'@\x00\x00\x00\x00\x03qD\xb0\x00\x00\x00\x00\x04aC\xc0\x00\x00\x00\x00\x05Q&\xb0\x00\x00\x00\x00\x06A%\xc0\x00\x00\x00\x00\a1\b\xb0\x00\x00\x00\x00\a\x8d_\xc0\x00" +
+	"\x00\x00\x00\t\x10\xea\xb0\x00\x00\x00\x00\t\xad\xdb@\x00\x00\x00\x00\n\xf0̰\x00\x00\x00\x00\v\xe0\xcb\xc0\x00\x00\x00\x00\f\xd9\xe90\x00\x00\x00\x00\r\xc0\xad\xc0\x00\x00\x00\x00\x0e\xb9\xcb0\x00\x00\x00\x00\x0f" +
+	"\xa9\xca@\x00\x00\x00\x00\x10\x99\xad0\x00\x00\x00\x00\x11\x89\xac@\x00\x00\x00\x00\x12y\x8f0\x00\x00\x00\x00\x13i\x8e@\x00\x00\x00\x00\x14Yq0\x00\x00\x00\x00\x15Ip@\x00\x00\x00\x00\x169S0\x00" +
+	"\x00\x00\x00\x17)R@\x00\x00\x00\x00\x18\"o\xb0\x00\x00\x00\x00\x19\t4@\x00\x00\x00\x00\x1a\x02Q\xb0\x00\x00\x00\x00\x1a+\x14\x10\x00\x00\x00\x00\x1a\xf2B\xb0\x00\x00\x00\x00\x1b\xe2%\xa0\x00\x00\x00\x00\x1c" +
+	"\xd2$\xb0\x00\x00\x00\x00\x1d\xc2\a\xa0\x00\x00\x00\x00\x1e\xb2\x06\xb0\x00\x00\x00\x00\x1f\xa1\xe9\xa0\x00\x00\x00\x00 v90\x00\x00\x00\x00!\x81ˠ\x00\x00\x00\x00\"V\x1b0\x00\x00\x00\x00#j\xe8 \x00" +
+	"\x00\x00\x00$5\xfd0\x00\x00\x00\x00%J\xca \x00\x00\x00\x00&\x15\xdf0\x00\x00\x00\x00'*\xac \x00\x00\x00\x00'\xfe\xfb\xb0\x00\x00\x00\x00)\n\x8e \x00\x00\x00\x00)\xdeݰ\x00\x00\x00\x00*" +
+	"\xeap \x00\x00\x00\x00+\xbe\xbf\xb0\x00\x00\x00\x00,ӌ\xa0\x00\x00\x00\x00-\x9e\xa1\xb0\x00\x00\x00\x00.\xb3n\xa0\x00\x00\x00\x00/~\x83\xb0\x00\x00\x00\x000\x93P\xa0\x00\x00\x00\x001g\xa00\x00" +
+	"\x00\x00\x002s2\xa0\x00\x00\x00\x003G\x820\x00\x00\x00\x004S\x14\xa0\x00\x00\x00\x005'd0\x00\x00\x00\x0062\xf6\xa0\x00\x00\x00\x007\aF0\x00\x00\x00\x008\x1c\x13 \x00\x00\x00\x008" +
+	"\xe7(0\x00\x00\x00\x009\xfb\xf5 \x00\x00\x00\x00:\xc7\n0\x00\x00\x00\x00;\xdb\xd7 \x00\x00\x00\x00<\xb0&\xb0\x00\x00\x00\x00=\xbb\xb9 \x00\x00\x00\x00>\x90\b\xb0\x00\x00\x00\x00?\x9b\x9b \x00" +
+	"\x00\x00\x00@o\xea\xb0\x00\x00\x00\x00A\x84\xb7\xa0\x00\x00\x00\x00BO̰\x00\x00\x00\x00Cd\x99\xa0\x00\x00\x00\x00D/\xae\xb0\x00\x00\x00\x00ED{\xa0\x00\x00\x00\x00E\xf3\xe10\x01\x02\x03\x04\x02" +
+	"\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\a\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t" +
+	"\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\x00\x00\xc4\xf8\x00\x00\xff\xffsx\x00\x00\xff\xffs`\x00\x04\xff\xff\x81p\x01\b\xff\xff\x81p\x01\f\xff\xffs`\x00\x10\xff\xff\x81p\x01" +
+	"\x15\xff\xff\x81p\x00\x1a\xff\xff\x8f\x80\x01\x1e\xff\xff\x81p\x00#LMT\x00AST\x00AWT\x00APT\x00AHST\x00AHDT\x00YST\x00AKDT\x00AKST\x00\n" +
+	"AKST9AKDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x00\x00Ameri" +
+	"ca/AnguillaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00" +
+	"\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf6" +
+	"2\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AW" +
+	"T\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0f\x00\x00\x00America/AntiguaTZif2\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0" +
+	"\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00<\x01V\rP\x02\x00\x00P\x02\x00\x00\x11\x00\x00\x00America/AraguainaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x003\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaat0\xff\xff\xff\xff\xb8\x0fI\xe0\xff\xff\xff\xff\xb8\xfd@\xa0\xff\xff\xff\xff\xb9\xf140\xff\xff\xff\xff\xba\xdet \xff\xff\xff\xff\xda8\xae0" +
+	"\xff\xff\xff\xff\xda\xeb\xfa0\xff\xff\xff\xff\xdc\x19\xe1\xb0\xff\xff\xff\xffܹY \xff\xff\xff\xff\xdd\xfb\x150\xff\xff\xff\xffޛ\xde \xff\xff\xff\xff\xdfݚ0\xff\xff\xff\xff\xe0T3 \xff\xff\xff\xff" +
+	"\xf4\x97\xff\xb0\xff\xff\xff\xff\xf5\x05^ \xff\xff\xff\xff\xf6\xc0d0\xff\xff\xff\xff\xf7\x0e\x1e\xa0\xff\xff\xff\xff\xf8Q,0\xff\xff\xff\xff\xf8\xc7\xc5 \xff\xff\xff\xff\xfa\nҰ\xff\xff\xff\xff\xfa\xa8\xf8\xa0" +
+	"\xff\xff\xff\xff\xfb\xec\x060\xff\xff\xff\xff\xfc\x8b}\xa0\x00\x00\x00\x00\x1dɎ0\x00\x00\x00\x00\x1exנ\x00\x00\x00\x00\x1f\xa05\xb0\x00\x00\x00\x00 3Ϡ\x00\x00\x00\x00!\x81i0\x00\x00\x00\x00" +
+	"\"\vȠ\x00\x00\x00\x00#X\x10\xb0\x00\x00\x00\x00#\xe2p \x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xd4\xc7 \x00\x00\x00\x000\x80y0\x00\x00\x00\x001\x1dM\xa0\x00\x00\x00\x002W \xb0" +
+	"\x00\x00\x00\x003\x06j \x00\x00\x00\x0048T0\x00\x00\x00\x004\xf8\xc1 \x00\x00\x00\x006 \x1f0\x00\x00\x00\x006\xcfh\xa0\x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xb8\x85 \x00\x00\x00\x00" +
+	"9\xdf\xe30\x00\x00\x00\x00:\x8f,\xa0\x00\x00\x00\x00;\xc8\xff\xb0\x00\x00\x00\x00<o\x0e\xa0\x00\x00\x00\x00=đ0\x00\x00\x00\x00>N\xf0\xa0\x00\x00\x00\x00P\x83e0\x00\x00\x00\x00Q 9\xa0" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xd2\xd0\x00\x00\xff\xff\xe3" +
+	"\xe0\x01\x04\xff\xff\xd5\xd0\x00\bLMT\x00-02\x00-03\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\xbf\xf5\xe5\xc4\x02\x00\x00\xc4\x02\x00\x00\x1e\x00\x00\x00A" +
+	"merica/Argentina/Buenos_AiresTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x06" +
+	"\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xa8L\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0" +
+	"\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff" +
+	"\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0" +
+	"\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff" +
+	"\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@" +
+	"\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00" +
+	"\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xf10" +
+	"\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x00\x00\x00\x00" +
+	"H\xfa\xa2\xb0\x00\x00\x00\x00I\xbca \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04" +
+	"\x05\x04\x05\x04\x05\x04\x05\x03\x05\x04\x05\x04\x05\xff\xff\xc94\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04" +
+	"\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00R\xc8\xd9\xf6\xc4\x02\x00\x00\xc4\x02\x00\x00\x1b\x00\x00\x00America/Argen" +
+	"tina/CatamarcaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00" +
+	"\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xaf,\xff\xff\xff" +
+	"\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1" +
+	"@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff" +
+	"\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1" +
+	"\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff" +
+	"\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35" +
+	"\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00" +
+	"\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd3" +
+	"0\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xbb\xf10\x00\x00\x00\x00@\xd5\v\xc0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\xff\xff" +
+	"\xc2T\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>" +
+	"3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00R\xc8\xd9\xf6\xc4\x02\x00\x00\xc4\x02\x00\x00 \x00\x00\x00America/Argentina/ComodRivad" +
+	"aviaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xaf,\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6" +
+	"{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff" +
+	"\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4" +
+	"\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff" +
+	"\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf6" +
+	"2\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff" +
+	"\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%" +
+	"7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00" +
+	"\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xbb\xf10\x00\x00\x00\x00@\xd5\v\xc0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\xff\xff\xc2T\x00\x00\xff\xff\xc3\xd0\x00\x04" +
+	"\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\xef\xf0R\x8a\xc4\x02\x00\x00\xc4\x02\x00\x00\x19\x00\x00\x00America/Argentina/CordobaTZif2\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xad\xb0\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e" +
+	"\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff" +
+	"\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe" +
+	"*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff" +
+	"\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13" +
+	"C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff" +
+	"\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!" +
+	"\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00" +
+	"\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x00\x00\x00\x00H\xfa\xa2\xb0\x00\x00\x00\x00I\xbca \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x04\x05\x04\x05\xff\xff\xc3\xd0\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01" +
+	"\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00utZ\x1a\xb2\x02\x00\x00\xb2\x02\x00" +
+	"\x00\x17\x00\x00\x00America/Argentina/JujuyTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00;\x00\x00\x00\x06\x00" +
+	"\x00\x00\x14\xff\xff\xff\xffr\x9c\xae\xb8\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff" +
+	"\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1" +
+	"\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff" +
+	"\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4" +
+	"=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff" +
+	"\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b" +
+	"$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'*W\xc0\x00\x00\x00\x00'\xe2۰\x00\x00\x00\x00(\xee\x8a@\x00" +
+	"\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x02\x03\x02\x04\x05\x04\x05\x03\x05\x04\x05\xff\xff\xc2\xc8\x00\x00" +
+	"\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK" +
+	"\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00m\aD\x0e\xcd\x02\x00\x00\xcd\x02\x00\x00\x1a\x00\x00\x00America/Argentina/La_RiojaTZif2\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xb0,\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1a\xc9" +
+	"\xb0\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff" +
+	"\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04" +
+	"@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff" +
+	"\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6\xe6\x9f" +
+	"\xb0\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff" +
+	"\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v" +
+	"\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'͵\xa0\x00\x00\x00\x00(&&@\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00" +
+	"\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xbb\xf10\x00\x00\x00\x00@\xd5\v\xc0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x05\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\xff\xff\xc1T\x00\x00\xff\xff\xc3\xd0\x00\x04\xff" +
+	"\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00ŒZ\x8c\xc4\x02\x00\x00\xc4\x02\x00\x00\x19\x00\x00\x00America/Argentina/MendozaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xb2\x04\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f" +
+	"@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff" +
+	"\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*" +
+	"0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff" +
+	"\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C" +
+	"\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff" +
+	"\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'\x194" +
+	"@\x00\x00\x00\x00'\xcdð\x00\x00\x00\x00(\xfag\xc0\x00\x00\x00\x00)\xb0H\xb0\x00\x00\x00\x00*\xe0\xe1@\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00" +
+	"\x00@\xb0\x13\xb0\x00\x00\x00\x00AV>\xc0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x02\x03\x02\x03\x02\x04\x05\x03\x05\x02\x05\x04\x05\xff\xff\xbf|\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10" +
+	"\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8ep\xb4c\xc4\x02\x00\x00\xc4\x02\x00\x00" +
+	"\x1e\x00\x00\x00America/Argentina/Rio_GallegosTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
 	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	" \x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff\xa1\xf2\xc1$\xff\xff\xff\xffݻ\xb1\x10\xff\xff\xff\xff\xde#\xad`\xff\xff\xff\xff\xe1x\xd2\x10\xff\xff\xff\xff\xe1\xe7e\xe0\xff\xff\xff\xff\xe5/?p\xff\xff\xff" +
-	"\xff\xe5\xa9\xcc\xe0\xff\xff\xff\xff\xebN\xc6\xf0\x00\x00\x00\x00\x16\x92B`\x00\x00\x00\x00\x17\b\xf7p\x00\x00\x00\x00\x17\xfa+\xe0\x00\x00\x00\x00\x18\xea*\xf0\x00\x00\x00\x00\x19\xdb_`\x00\x00\x00\x00\x1a̯" +
-	"\xf0\x00\x00\x00\x00\x1b\xbd\xe4`\x00\x00\x00\x00\x1c\xb4z\xf0\x00\x00\x00\x00\x1d\x9f\x17\xe0\x00\x00\x00\x00\x1e\x93\vp\x00\x00\x00\x00\x1f\x82\xee`\x00\x00\x00\x00 pJp\x00\x00\x00\x00!a~\xe0\x00\x00\x00" +
-	"\x00\"R\xcfp\x00\x00\x00\x00#D\x03\xe0\x00\x00\x00\x00$4\x02\xf0\x00\x00\x00\x00%%7`\x00\x00\x00\x00&@\xb7\xf0\x00\x00\x00\x002N\xf1`\x00\x00\x00\x003D6p\x00\x00\x00\x0045j" +
-	"\xe0\x00\x00\x00\x00P\x9d\x99\x00\x00\x00\x00\x00QTـ\x00\x00\x00\x00Ri\xb4\x80\x02\x01\x02\x01\x02\x01\x02\x03\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x01\x03\x02\x01\x03\x00\x00\f" +
-	"\\\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x1c \x00\rLMT\x00CEST\x00CET\x00EET\x00\nEET-2\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT6" +
-	"\x99rU\xa4\x00\x00\x00\xa4\x00\x00\x00\x0f\x00\x1c\x00Africa/MonroviaUT\t\x00\x03\xdc\xfc\x94b\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZ" +
+	"=\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xb2d\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff" +
+	"\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f" +
+	"\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff" +
+	"\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd" +
+	"\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff" +
+	"\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J" +
+	"\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00" +
+	"\x00)\x00\xf10\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xbb\xf10\x00\x00\x00\x00@\xd5\v" +
+	"\xc0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05" +
+	"\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\xff\xff\xbf\x1c\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CM" +
+	"T\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t*\x9b!\xb2\x02\x00\x00\xb2\x02\x00\x00\x17\x00\x00\x00America/" +
+	"Argentina/SaltaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00" +
+	"\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00;\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xae\xd4\xff\xff" +
+	"\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8" +
+	"\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff" +
+	"\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM" +
+	"\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff" +
+	"\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc3" +
+	"5\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00" +
+	"\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0" +
+	"\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x04\x05\xff\xff¬\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff" +
+	"\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfc" +
+	"z=\xe1\xcd\x02\x00\x00\xcd\x02\x00\x00\x1a\x00\x00\x00America/Argentina/San_JuanTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00>\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xb1\xbc\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff" +
+	"\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@" +
+	"\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff" +
+	"\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0" +
+	"\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff" +
+	"\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@" +
+	"\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00" +
+	"'͵\xa0\x00\x00\x00\x00(&&@\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0" +
+	"\x00\x00\x00\x00@\xba\x9f\xb0\x00\x00\x00\x00A\x030@\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x05\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\xff\xff\xbf\xc4\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff" +
+	"\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\x80\xb9\\\xcd\x02\x00\x00" +
+	"\xcd\x02\x00\x00\x1a\x00\x00\x00America/Argentina/San_LuisTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	">\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xaf\xb4\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff" +
+	"\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f" +
+	"\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff" +
+	"\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd" +
+	"\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff" +
+	"\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J" +
+	"\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xfd\xa5\xa0\x00\x00\x00\x00'\x194@\x00\x00\x00\x00'\xcdð\x00\x00\x00" +
+	"\x00(G\x1b\xc0\x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xba\x9f\xb0\x00\x00\x00\x00A\x030@\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\x93\xfc\xa0\x00\x00\x00\x00G\xd3R" +
+	"\xb0\x00\x00\x00\x00H\xf1v@\x00\x00\x00\x00I\xb34\xb0\x00\x00\x00\x00J\xd1X@\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x02\x03\x02\x05\x03\x05\x02\x05\x04\x03\x02\x03\x02\x05\xff\xff\xc1\xcc\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5" +
+	"\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y\xd8֭\xd6\x02\x00\x00\xd6\x02\x00\x00\x19\x00\x00" +
+	"\x00America/Argentina/TucumanTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\x00\x00\x00\x06\x00\x00\x00" +
+	"\x14\xff\xff\xff\xffr\x9c\xae\xa4\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff" +
+	"\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d" +
+	"@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff" +
+	"\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b" +
+	"0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff" +
+	"\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o" +
+	"\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00" +
+	"\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xbb\xf10\x00\x00\x00\x00@\xcb\xd1@\x00\x00\x00\x00Gw\t" +
+	"\xb0\x00\x00\x00\x00G\xdc\x7f \x00\x00\x00\x00H\xfa\xa2\xb0\x00\x00\x00\x00I\xbca \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\x04\x05\xff\xff\xc2\xdc\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff" +
+	"\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8b}\xb6\x1e\xc4\x02\x00\x00\xc4\x02\x00\x00\x19\x00" +
+	"\x00\x00America/Argentina/UshuaiaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x06\x00\x00" +
+	"\x00\x14\xff\xff\xff\xffr\x9c\xb1\x88\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff" +
+	"\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d" +
+	"\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff" +
+	"\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=" +
+	"\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff" +
+	"\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$" +
+	"o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xf10\x00\x00" +
+	"\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xb9N0\x00\x00\x00\x00@\xd5\v\xc0\x00\x00\x00\x00Gw" +
+	"\t\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04" +
+	"\x05\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\xff\xff\xbf\xf8\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-" +
+	"03\x00-02\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\r\x00\x00\x00America/ArubaTZ" +
 	"if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xffZz\xa6\x9c\xff\xff\xff\xff\xa0_l\x9c\x00\x00\x00\x00\x03\xcaZn\x01\x02\x03" +
-	"\xff\xff\xf5\xe4\x00\x00\xff\xff\xf5\xe4\x00\x04\xff\xff\xf5\x92\x00\x04\x00\x00\x00\x00\x00\bLMT\x00MMT\x00GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\xb4\x8d\x98\xc6" +
-	"\xbf\x00\x00\x00\xbf\x00\x00\x00\x14\x00\x1c\x00Africa/Dar_es_SalaamUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff" +
+	"\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00d\xa9y\x9at\x03\x00\x00t\x03\x00\x00\x10\x00\x00\x00America/AsuncionTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00O\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xffi\x87\x11\x90\xff\xff\xff\xff\xb8\x17\xf5\x90\x00\x00\x00\x00\x05+\xda@\x00\x00\x00\x00\a\xfc\xf0\xb0\x00\x00\x00\x00\n\xcft\xc0\x00\x00\x00\x00" +
+	"\v\x97ʰ\x00\x00\x00\x00\f\xb1\xf9\xc0\x00\x00\x00\x00\rx\xfe0\x00\x00\x00\x00\x0e\x93-@\x00\x00\x00\x00\x0fZ1\xb0\x00\x00\x00\x00\x10t`\xc0\x00\x00\x00\x00\x11dC\xb0\x00\x00\x00\x00\x12U\x94@" +
+	"\x00\x00\x00\x00\x13FȰ\x00\x00\x00\x00\x148\x19@\x00\x00\x00\x00\x15'\xfc0\x00\x00\x00\x00\x16\x19L\xc0\x00\x00\x00\x00\x17\t/\xb0\x00\x00\x00\x00\x17\xfa\x80@\x00\x00\x00\x00\x18\xeac0\x00\x00\x00\x00" +
+	"\x19۳\xc0\x00\x00\x00\x00\x1a\xcc\xe80\x00\x00\x00\x00\x1b\xbe8\xc0\x00\x00\x00\x00\x1c\xae\x1b\xb0\x00\x00\x00\x00\x1d\x9fl@\x00\x00\x00\x00\x1e\x8fO0\x00\x00\x00\x00\x1f\x80\x9f\xc0\x00\x00\x00\x00 p\x82\xb0" +
+	"\x00\x00\x00\x00!a\xd3@\x00\x00\x00\x00\"S\a\xb0\x00\x00\x00\x00#DX@\x00\x00\x00\x00$4;0\x00\x00\x00\x00%A;@\x00\x00\x00\x00&\x15n\xb0\x00\x00\x00\x00'\x06\xbf@\x00\x00\x00\x00" +
+	"'\xf6\xa20\x00\x00\x00\x00(\xee\x8a@\x00\x00\x00\x00)\xb0H\xb0\x00\x00\x00\x00*Ͻ\xc0\x00\x00\x00\x00+\xb9\t0\x00\x00\x00\x00,\xab\xab@\x00\x00\x00\x00-p\f\xb0\x00\x00\x00\x00.\x8c\xde\xc0" +
+	"\x00\x00\x00\x00/O\xee\xb0\x00\x00\x00\x000n\x12@\x00\x00\x00\x0016h0\x00\x00\x00\x002W.\xc0\x00\x00\x00\x003\x0f\xb2\xb0\x00\x00\x00\x0047\x10\xc0\x00\x00\x00\x004\xf8\xcf0\x00\x00\x00\x00" +
+	"6\x16\xf2\xc0\x00\x00\x00\x006\xe1\xeb\xb0\x00\x00\x00\x007\xf6\xd4\xc0\x00\x00\x00\x008\xc1Ͱ\x00\x00\x00\x009ֶ\xc0\x00\x00\x00\x00:\xa1\xaf\xb0\x00\x00\x00\x00;\xbf\xd3@\x00\x00\x00\x00<\xaf\xb60" +
+	"\x00\x00\x00\x00=q\x90\xc0\x00\x00\x00\x00>\x8f\x980\x00\x00\x00\x00?Z\xad@\x00\x00\x00\x00@oz0\x00\x00\x00\x00Aq\xee@\x00\x00\x00\x00B3\xac\xb0\x00\x00\x00\x00CQ\xd0@\x00\x00\x00\x00" +
+	"D\x13\x8e\xb0\x00\x00\x00\x00E1\xb2@\x00\x00\x00\x00E\xf3p\xb0\x00\x00\x00\x00G\x1a\xce\xc0\x00\x00\x00\x00G\xd3R\xb0\x00\x00\x00\x00H\xfa\xb0\xc0\x00\x00\x00\x00I\xb34\xb0\x00\x00\x00\x00Jڒ\xc0" +
+	"\x00\x00\x00\x00K\xc1;0\x00\x00\x00\x00L\xa7\xff\xc0\x00\x00\x00\x00M\xa1\x1d0\x00\x00\x00\x00N\x87\xe1\xc0\x00\x00\x00\x00O\x80\xff0\x00\x00\x00\x00Pp\xfe@\x01\x02\x03\x02\x04\x02\x04\x02\x04\x02\x04\x02" +
+	"\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02" +
+	"\x04\x02\x04\x02\x04\x02\x04\xff\xff\xc9\xf0\x00\x00\xff\xff\xc9\xf0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x00\f\xff\xff\xd5\xd0\x01\fLMT\x00AMT\x00-04\x00-03\x00\n<-04>4" +
+	"<-03>,M10.1.0/0,M3.4.0/0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Ծ\xe7#\x95\x00\x00\x00\x95\x00\x00\x00\x10\x00\x00\x00Ameri" +
+	"ca/AtikokanTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00" +
+	"\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xffi\x87&\x10\xff\xff\xff\xff\x8b\xf4" +
+	"a\xe8\x01\x02\xff\xff\xb5p\x00\x00\xff\xff\xb5\x18\x00\x04\xff\xff\xb9\xb0\x00\bLMT\x00CMT\x00EST\x00\nEST5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xae,\xa44\xc9\x03" +
+	"\x00\x00\xc9\x03\x00\x00\f\x00\x00\x00America/AtkaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00T\x00\x00\x00\n\x00\x00\x00!\xff\xff\xff" +
+	"\xff?\xc2\xfd\xd1\xff\xff\xff\xff}\x87Z^\xff\xff\xff\xffˉD\xd0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2aP@\xff\xff\xff\xff\xfa\xd2U\xb0\xff\xff\xff\xff\xfe\xb8qP\xff\xff\xff\xff\xff\xa8T" +
+	"@\x00\x00\x00\x00\x00\x98SP\x00\x00\x00\x00\x01\x886@\x00\x00\x00\x00\x02x5P\x00\x00\x00\x00\x03qR\xc0\x00\x00\x00\x00\x04aQ\xd0\x00\x00\x00\x00\x05Q4\xc0\x00\x00\x00\x00\x06A3\xd0\x00\x00\x00" +
+	"\x00\a1\x16\xc0\x00\x00\x00\x00\a\x8dm\xd0\x00\x00\x00\x00\t\x10\xf8\xc0\x00\x00\x00\x00\t\xad\xe9P\x00\x00\x00\x00\n\xf0\xda\xc0\x00\x00\x00\x00\v\xe0\xd9\xd0\x00\x00\x00\x00\f\xd9\xf7@\x00\x00\x00\x00\r\xc0\xbb" +
+	"\xd0\x00\x00\x00\x00\x0e\xb9\xd9@\x00\x00\x00\x00\x0f\xa9\xd8P\x00\x00\x00\x00\x10\x99\xbb@\x00\x00\x00\x00\x11\x89\xbaP\x00\x00\x00\x00\x12y\x9d@\x00\x00\x00\x00\x13i\x9cP\x00\x00\x00\x00\x14Y\x7f@\x00\x00\x00" +
+	"\x00\x15I~P\x00\x00\x00\x00\x169a@\x00\x00\x00\x00\x17)`P\x00\x00\x00\x00\x18\"}\xc0\x00\x00\x00\x00\x19\tBP\x00\x00\x00\x00\x1a\x02_\xc0\x00\x00\x00\x00\x1a+\" \x00\x00\x00\x00\x1a\xf2P" +
+	"\xc0\x00\x00\x00\x00\x1b\xe23\xb0\x00\x00\x00\x00\x1c\xd22\xc0\x00\x00\x00\x00\x1d\xc2\x15\xb0\x00\x00\x00\x00\x1e\xb2\x14\xc0\x00\x00\x00\x00\x1f\xa1\xf7\xb0\x00\x00\x00\x00 vG@\x00\x00\x00\x00!\x81ٰ\x00\x00\x00" +
+	"\x00\"V)@\x00\x00\x00\x00#j\xf60\x00\x00\x00\x00$6\v@\x00\x00\x00\x00%J\xd80\x00\x00\x00\x00&\x15\xed@\x00\x00\x00\x00'*\xba0\x00\x00\x00\x00'\xff\t\xc0\x00\x00\x00\x00)\n\x9c" +
+	"0\x00\x00\x00\x00)\xde\xeb\xc0\x00\x00\x00\x00*\xea~0\x00\x00\x00\x00+\xbe\xcd\xc0\x00\x00\x00\x00,Ӛ\xb0\x00\x00\x00\x00-\x9e\xaf\xc0\x00\x00\x00\x00.\xb3|\xb0\x00\x00\x00\x00/~\x91\xc0\x00\x00\x00" +
+	"\x000\x93^\xb0\x00\x00\x00\x001g\xae@\x00\x00\x00\x002s@\xb0\x00\x00\x00\x003G\x90@\x00\x00\x00\x004S\"\xb0\x00\x00\x00\x005'r@\x00\x00\x00\x0063\x04\xb0\x00\x00\x00\x007\aT" +
+	"@\x00\x00\x00\x008\x1c!0\x00\x00\x00\x008\xe76@\x00\x00\x00\x009\xfc\x030\x00\x00\x00\x00:\xc7\x18@\x00\x00\x00\x00;\xdb\xe50\x00\x00\x00\x00<\xb04\xc0\x00\x00\x00\x00=\xbb\xc70\x00\x00\x00" +
+	"\x00>\x90\x16\xc0\x00\x00\x00\x00?\x9b\xa90\x00\x00\x00\x00@o\xf8\xc0\x00\x00\x00\x00A\x84Ű\x00\x00\x00\x00BO\xda\xc0\x00\x00\x00\x00Cd\xa7\xb0\x00\x00\x00\x00D/\xbc\xc0\x00\x00\x00\x00ED\x89" +
+	"\xb0\x00\x00\x00\x00E\xf3\xef@\x01\x02\x03\x04\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\a\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t" +
+	"\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\x00\x00\xab\xe2\x00\x00\xff\xffZb\x00\x00\xff\xffeP\x00\x04\xff\xffs`\x01\b\xff\xffs" +
+	"`\x01\f\xff\xffeP\x00\x10\xff\xffs`\x01\x14\xff\xffs`\x00\x18\xff\xff\x81p\x01\x1d\xff\xffs`\x00\x19LMT\x00NST\x00NWT\x00NPT\x00BST\x00BDT\x00AHS" +
+	"T\x00HDT\x00\nHST10HDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00OKjǪ\x02\x00\x00\xaa\x02\x00\x00\r\x00\x00" +
+	"\x00America/BahiaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00" +
+	"\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaak\x1c\xff\xff\xff" +
+	"\xff\xb8\x0fI\xe0\xff\xff\xff\xff\xb8\xfd@\xa0\xff\xff\xff\xff\xb9\xf140\xff\xff\xff\xff\xba\xdet \xff\xff\xff\xff\xda8\xae0\xff\xff\xff\xff\xda\xeb\xfa0\xff\xff\xff\xff\xdc\x19\xe1\xb0\xff\xff\xff\xffܹY" +
+	" \xff\xff\xff\xff\xdd\xfb\x150\xff\xff\xff\xffޛ\xde \xff\xff\xff\xff\xdfݚ0\xff\xff\xff\xff\xe0T3 \xff\xff\xff\xff\xf4\x97\xff\xb0\xff\xff\xff\xff\xf5\x05^ \xff\xff\xff\xff\xf6\xc0d0\xff\xff\xff" +
+	"\xff\xf7\x0e\x1e\xa0\xff\xff\xff\xff\xf8Q,0\xff\xff\xff\xff\xf8\xc7\xc5 \xff\xff\xff\xff\xfa\nҰ\xff\xff\xff\xff\xfa\xa8\xf8\xa0\xff\xff\xff\xff\xfb\xec\x060\xff\xff\xff\xff\xfc\x8b}\xa0\x00\x00\x00\x00\x1dɎ" +
+	"0\x00\x00\x00\x00\x1exנ\x00\x00\x00\x00\x1f\xa05\xb0\x00\x00\x00\x00 3Ϡ\x00\x00\x00\x00!\x81i0\x00\x00\x00\x00\"\vȠ\x00\x00\x00\x00#X\x10\xb0\x00\x00\x00\x00#\xe2p \x00\x00\x00" +
+	"\x00%7\xf2\xb0\x00\x00\x00\x00%\xd4\xc7 \x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xbd\xe3\xa0\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\x94\x8b \x00\x00\x00\x00*\xea\r\xb0\x00\x00\x00\x00+k2" +
+	"\xa0\x00\x00\x00\x00,\xc0\xb50\x00\x00\x00\x00-f\xc4 \x00\x00\x00\x00.\xa0\x970\x00\x00\x00\x00/F\xa6 \x00\x00\x00\x000\x80y0\x00\x00\x00\x001\x1dM\xa0\x00\x00\x00\x002W \xb0\x00\x00\x00" +
+	"\x003\x06j \x00\x00\x00\x0048T0\x00\x00\x00\x004\xf8\xc1 \x00\x00\x00\x006 \x1f0\x00\x00\x00\x006\xcfh\xa0\x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xb8\x85 \x00\x00\x00\x009\xdf\xe3" +
+	"0\x00\x00\x00\x00:\x8f,\xa0\x00\x00\x00\x00;\xc8\xff\xb0\x00\x00\x00\x00<o\x0e\xa0\x00\x00\x00\x00=đ0\x00\x00\x00\x00>N\xf0\xa0\x00\x00\x00\x00N\x9aH\xb0\x00\x00\x00\x00OI\x92 \x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff" +
+	"\xdb\xe4\x00\x00\xff\xff\xe3\xe0\x01\x04\xff\xff\xd5\xd0\x00\bLMT\x00-02\x00-03\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00U\x0e\x01n\xd8\x02\x00\x00\xd8\x02" +
+	"\x00\x00\x16\x00\x00\x00America/Bahia_BanderasTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\x00\x00\x00\x06\x00" +
+	"\x00\x00\x18\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6fV`\xff\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff\xb8\f6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\xff\xff\xff\xff\xcb\xeaq`\xff" +
+	"\xff\xff\xffؑ\xb4\xf0\x00\x00\x00\x00\x00\x00p\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x006" +
+	"2ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xf5\x12\x90\x00\x00\x00\x00;\xb6\xd1\x00\x00\x00\x00\x00<\xb0\n\x90\x00" +
+	"\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D" +
+	"/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00F\x0ft\x90\x00\x00\x00\x00G$A\x80\x00\x00\x00\x00G\xf8\x91\x10\x00\x00\x00\x00I\x04#\x80\x00\x00\x00\x00I\xd8s\x10\x00\x00\x00\x00J\xe4\x05\x80\x00" +
+	"\x00\x00\x00K\xb8U\x10\x00\x00\x00\x00L\xcd\x13\xf0\x00\x00\x00\x00M\x98)\x00\x00\x00\x00\x00N\xac\xf5\xf0\x00\x00\x00\x00Ox\v\x00\x00\x00\x00\x00P\x8c\xd7\xf0\x00\x00\x00\x00Qa'\x80\x00\x00\x00\x00R" +
+	"l\xb9\xf0\x00\x00\x00\x00SA\t\x80\x00\x00\x00\x00TL\x9b\xf0\x00\x00\x00\x00U \xeb\x80\x00\x00\x00\x00V,}\xf0\x00\x00\x00\x00W\x00̀\x00\x00\x00\x00X\x15\x9ap\x00\x00\x00\x00Xீ\x00" +
+	"\x00\x00\x00Y\xf5|p\x00\x00\x00\x00Z\xc0\x91\x80\x00\x00\x00\x00[\xd5^p\x00\x00\x00\x00\\\xa9\xae\x00\x00\x00\x00\x00]\xb5@p\x00\x00\x00\x00^\x89\x90\x00\x00\x00\x00\x00_\x95\"p\x00\x00\x00\x00`" +
+	"ir\x00\x00\x00\x00\x00a~>\xf0\x00\x00\x00\x00bIT\x00\x00\x00\x00\x00c^ \xf0\x01\x02\x01\x03\x01\x02\x01\x04\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01" +
+	"\x03\x01\x03\x01\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\xff\xff\x9dT\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\x8f\x80\x00\x10" +
+	"\xff\xff\xb9\xb0\x01\x14LMT\x00MST\x00CST\x00MDT\x00PST\x00CDT\x00\nCST6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00l=\xad\xbe\x16\x01\x00\x00\x16\x01" +
+	"\x00\x00\x10\x00\x00\x00America/BarbadosTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff" +
+	"\xff\x92@\xa9e\xff\xff\xff\xff\xcb\xe3\xcb\xd0\xff\xff\xff\xff̔\x82\xe0\xff\xff\xff\xff\xcd\xd6\"\xd0\xff\xff\xff\xff\xce|M\xe0\xff\xff\xff\xffϛ\xa6\xd0\xff\xff\xff\xff\xd0ej`\x00\x00\x00\x00\x0e\x00\xf2" +
+	"\xe0\x00\x00\x00\x00\x0e\x94\x8c\xd0\x00\x00\x00\x00\x0f\x97\x00\xe0\x00\x00\x00\x00\x10tn\xd0\x00\x00\x00\x00\x11v\xe2\xe0\x00\x00\x00\x00\x12TP\xd0\x00\x00\x00\x00\x13_\xff`\x00\x00\x00\x00\x140>P\x02\x01\x02" +
+	"\x01\x02\x03\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xc8\x1b\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xce\xc8\x01\fLMT\x00ADT\x00AST\x00-0330\x00\nAST4\n" +
+	"PK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85-\xb9\xf8\x8a\x01\x00\x00\x8a\x01\x00\x00\r\x00\x00\x00America/BelemTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaatt\xff\xff\xff\xff\xb8\x0fI\xe0\xff\xff\xff\xff\xb8\xfd@\xa0\xff\xff\xff\xff\xb9\xf140\xff\xff\xff\xff\xba\xdet \xff\xff" +
+	"\xff\xff\xda8\xae0\xff\xff\xff\xff\xda\xeb\xfa0\xff\xff\xff\xff\xdc\x19\xe1\xb0\xff\xff\xff\xffܹY \xff\xff\xff\xff\xdd\xfb\x150\xff\xff\xff\xffޛ\xde \xff\xff\xff\xff\xdfݚ0\xff\xff\xff\xff\xe0T" +
+	"3 \xff\xff\xff\xff\xf4\x97\xff\xb0\xff\xff\xff\xff\xf5\x05^ \xff\xff\xff\xff\xf6\xc0d0\xff\xff\xff\xff\xf7\x0e\x1e\xa0\xff\xff\xff\xff\xf8Q,0\xff\xff\xff\xff\xf8\xc7\xc5 \xff\xff\xff\xff\xfa\nҰ\xff\xff" +
+	"\xff\xff\xfa\xa8\xf8\xa0\xff\xff\xff\xff\xfb\xec\x060\xff\xff\xff\xff\xfc\x8b}\xa0\x00\x00\x00\x00\x1dɎ0\x00\x00\x00\x00\x1exנ\x00\x00\x00\x00\x1f\xa05\xb0\x00\x00\x00\x00 3Ϡ\x00\x00\x00\x00!\x81" +
+	"i0\x00\x00\x00\x00\"\vȠ\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xffҌ\x00\x00\xff\xff\xe3\xe0\x01\x04\xff\xff\xd5\xd0\x00\bLMT" +
+	"\x00-02\x00-03\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x89غ\xee\x15\x04\x00\x00\x15\x04\x00\x00\x0e\x00\x00\x00America/Beliz" +
+	"eTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b\x00\x00\x00\x06\x00\x00\x00\x1a\xff\xff\xff\xff\x93^ٰ\xff\xff\xff\xff\x9f\x9f;\xe0\xff\xff\xff\xff\xa0EQ\xd8" +
+	"\xff\xff\xff\xff\xa1\x7f\x1d\xe0\xff\xff\xff\xff\xa2.nX\xff\xff\xff\xff\xa3^\xff\xe0\xff\xff\xff\xff\xa4\x0ePX\xff\xff\xff\xff\xa5>\xe1\xe0\xff\xff\xff\xff\xa5\xee2X\xff\xff\xff\xff\xa7'\xfe`\xff\xff\xff\xff" +
+	"\xa7\xce\x14X\xff\xff\xff\xff\xa9\a\xe0`\xff\xff\xff\xff\xa9\xad\xf6X\xff\xff\xff\xff\xaa\xe7\xc2`\xff\xff\xff\xff\xab\x97\x12\xd8\xff\xff\xff\xff\xacǤ`\xff\xff\xff\xff\xadv\xf4\xd8\xff\xff\xff\xff\xae\xa7\x86`" +
+	"\xff\xff\xff\xff\xafV\xd6\xd8\xff\xff\xff\xff\xb0\x87h`\xff\xff\xff\xff\xb16\xb8\xd8\xff\xff\xff\xff\xb2p\x84\xe0\xff\xff\xff\xff\xb3\x16\x9a\xd8\xff\xff\xff\xff\xb4Pf\xe0\xff\xff\xff\xff\xb4\xf6|\xd8\xff\xff\xff\xff" +
+	"\xb60H\xe0\xff\xff\xff\xff\xb6ߙX\xff\xff\xff\xff\xb8\x10*\xe0\xff\xff\xff\xff\xb8\xbf{X\xff\xff\xff\xff\xb9\xf0\f\xe0\xff\xff\xff\xff\xba\x9f]X\xff\xff\xff\xff\xbb\xd9)`\xff\xff\xff\xff\xbc\x7f?X" +
+	"\xff\xff\xff\xff\xbd\xb9\v`\xff\xff\xff\xff\xbe_!X\xff\xff\xff\xff\xbf\x98\xed`\xff\xff\xff\xff\xc0?\x03X\xff\xff\xff\xff\xc1x\xcf`\xff\xff\xff\xff\xc2(\x1f\xd8\xff\xff\xff\xff\xc3X\xb1`\xff\xff\xff\xff" +
+	"\xc4\b\x01\xd8\xff\xff\xff\xff\xc58\x93`\xff\xff\xff\xff\xc5\xe7\xe3\xd8\xff\xff\xff\xff\xc7!\xaf\xe0\xff\xff\xff\xff\xc7\xc7\xc5\xd8\xff\xff\xff\xff\xc9\x01\x91\xe0\xff\xff\xff\xffɧ\xa7\xd8\xff\xff\xff\xff\xca\xe1s\xe0" +
+	"\xff\xff\xff\xffː\xc4X\xff\xff\xff\xff\xcc@\"\xe0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2\xc6qP\xff\xff\xff\xff\xd6)\xfa`\xff\xff\xff\xff\xd6\xd9J\xd8\xff\xff\xff\xff\xd8\t\xdc`\xff\xff\xff\xff" +
+	"ع,\xd8\xff\xff\xff\xff\xd9\xe9\xbe`\xff\xff\xff\xffڙ\x0e\xd8\xff\xff\xff\xff\xdb\xd2\xda\xe0\xff\xff\xff\xff\xdcx\xf0\xd8\xff\xff\xff\xffݲ\xbc\xe0\xff\xff\xff\xff\xdeX\xd2\xd8\xff\xff\xff\xffߒ\x9e\xe0" +
+	"\xff\xff\xff\xff\xe0A\xefX\xff\xff\xff\xff\xe1r\x80\xe0\xff\xff\xff\xff\xe2!\xd1X\xff\xff\xff\xff\xe3Rb\xe0\xff\xff\xff\xff\xe4\x01\xb3X\xff\xff\xff\xff\xe52D\xe0\xff\xff\xff\xff\xe5\xe1\x95X\xff\xff\xff\xff" +
+	"\xe7\x1ba`\xff\xff\xff\xff\xe7\xc1wX\xff\xff\xff\xff\xe8\xfbC`\xff\xff\xff\xff\xe9\xa1YX\xff\xff\xff\xff\xea\xdb%`\xff\xff\xff\xff\xeb\x8au\xd8\xff\xff\xff\xff\xec\xbb\a`\xff\xff\xff\xff\xedjW\xd8" +
+	"\xff\xff\xff\xff\xee\x9a\xe9`\xff\xff\xff\xff\xefJ9\xd8\xff\xff\xff\xff\xf0\x84\x05\xe0\xff\xff\xff\xff\xf1*\x1b\xd8\xff\xff\xff\xff\xf2c\xe7\xe0\xff\xff\xff\xff\xf3\t\xfd\xd8\xff\xff\xff\xff\xf4C\xc9\xe0\xff\xff\xff\xff" +
+	"\xf4\xe9\xdf\xd8\xff\xff\xff\xff\xf6#\xab\xe0\xff\xff\xff\xff\xf6\xd2\xfcX\xff\xff\xff\xff\xf8\x03\x8d\xe0\xff\xff\xff\xff\xf8\xb2\xdeX\xff\xff\xff\xff\xf9\xe3o\xe0\xff\xff\xff\xff\xfa\x92\xc0X\xff\xff\xff\xff\xfb̌`" +
+	"\xff\xff\xff\xff\xfcr\xa2X\x00\x00\x00\x00\ab\xdb`\x00\x00\x00\x00\a\xb9\xd0P\x00\x00\x00\x00\x18aq`\x00\x00\x00\x00\x18\xab7P\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x02\x05\x02\xff\xff\xadP\x00\x00\xff\xff\xb2\xa8\x01\x04\xff\xff\xab\xa0\x00\n\xff\xff\xb9\xb0\x01\x0e\xff\xff\xb9\xb0\x01\x12\xff\xff\xb9\xb0\x01\x16LMT\x00-0" +
+	"530\x00CST\x00CWT\x00CPT\x00CDT\x00\nCST6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x14\x00\x00\x00Amer" +
+	"ica/Blanc-SablonTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01" +
+	"\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff" +
+	"\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00A" +
+	"PT\x00AWT\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8Dz\x97\xae\x01\x00\x00\xae\x01\x00\x00\x11\x00\x00\x00America/Boa_Vista" +
 	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff" +
-	"\xff\xff\xff\xc1\xed\xadX\xff\xff\xff\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\"\x84\x00\x00\x00\x00#(\x00\x04\x00\x00*0\x00\n\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00+0" +
-	"245\x00\nEAT-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\xcc\fTξ\x00\x00\x00\xbe\x00\x00\x00\x13\x00\x1c\x00Africa/Johannesburg" +
-	"UT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x04\x00" +
-	"\x00\x00\t\xff\xff\xff\xffm{A@\xff\xff\xff\xff\x82F\xcfh\xff\xff\xff\xff̮\x8c\x80\xff\xff\xff\xff͞op\xff\xff\xff\xffΎn\x80\xff\xff\xff\xff\xcf~Qp\x01\x03\x02\x03\x02\x03\x00\x00\x1a" +
-	"@\x00\x00\x00\x00\x15\x18\x00\x04\x00\x00*0\x01\x04\x00\x00\x1c \x00\x04LMT\x00SAST\x00\nSAST-2\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT \x1b\xb0_\x83\x00\x00\x00" +
-	"\x83\x00\x00\x00\r\x00\x1c\x00Africa/KigaliUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00!\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaa\x7f\xe0\xff\xff\xff\xff\xb8\x0fW\xf0\xff\xff\xff\xff\xb8\xfdN\xb0\xff" +
+	"\xff\xff\xff\xb9\xf1B@\xff\xff\xff\xff\xbaނ0\xff\xff\xff\xff\xda8\xbc@\xff\xff\xff\xff\xda\xec\b@\xff\xff\xff\xff\xdc\x19\xef\xc0\xff\xff\xff\xffܹg0\xff\xff\xff\xff\xdd\xfb#@\xff\xff\xff\xff\xde" +
+	"\x9b\xec0\xff\xff\xff\xff\xdfݨ@\xff\xff\xff\xff\xe0TA0\xff\xff\xff\xff\xf4\x98\r\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf6\xc0r@\xff\xff\xff\xff\xf7\x0e,\xb0\xff\xff\xff\xff\xf8Q:@\xff" +
+	"\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xfa\n\xe0\xc0\xff\xff\xff\xff\xfa\xa9\x06\xb0\xff\xff\xff\xff\xfb\xec\x14@\xff\xff\xff\xff\xfc\x8b\x8b\xb0\x00\x00\x00\x00\x1dɜ@\x00\x00\x00\x00\x1ex\xe5\xb0\x00\x00\x00\x00\x1f" +
+	"\xa0C\xc0\x00\x00\x00\x00 3ݰ\x00\x00\x00\x00!\x81w@\x00\x00\x00\x00\"\vְ\x00\x00\x00\x007\xf6\xd4\xc0\x00\x00\x00\x008\xb8\x930\x00\x00\x00\x009\xdf\xf1@\x00\x00\x00\x009\xe9\x1d\xb0\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xc7 \x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\bLMT\x00-03\x00-0" +
+	"4\x00\n<-04>4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,g\xec\xec\xb3\x00\x00\x00\xb3\x00\x00\x00\x0e\x00\x00\x00America/BogotaTZif2\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff^\x9c4\xf0\xff\xff\xff\xff\x98XUp\x00\x00\x00\x00*\x03sP\x00\x00\x00\x00+t\x89" +
+	"@\x01\x03\x02\x03\xff\xff\xba\x90\x00\x00\xff\xff\xba\x90\x00\x04\xff\xff\xc7\xc0\x01\b\xff\xff\xb9\xb0\x00\fLMT\x00BMT\x00-04\x00-05\x00\n<-05>5\nPK\x03\x04\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00.\xbe\x1a>\xe7\x03\x00\x00\xe7\x03\x00\x00\r\x00\x00\x00America/BoiseTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00Z\x00\x00\x00\a\x00\x00\x00\x1c\xff\xff\xff\xff^\x04\x1a\xc0\xff\xff\xff\xff\x9e\xa6H\xa0\xff\xff\xff\xff\x9f\xbb\x15\x90\xff\xff\xff\xff\xa0\x86*\xa0\xff\xff\xff\xff\xa1\x9a\xf7\x90\xff\xff\xff\xff\xa8FL \xff" +
+	"\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W\x10\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe" +
+	"\xb89\x10\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x1b\x10\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xfd\x10\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00" +
+	"\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\a\xb2\x1f\x90\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\t\xad\xb1\x10\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\vࡐ\x00\x00\x00\x00\f" +
+	"ٿ\x00\x00\x00\x00\x00\r\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00" +
+	"\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a" +
+	"\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00" +
+	"\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeߐ\x00\x00\x00\x00)" +
+	"\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00" +
+	"\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007" +
+	"\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00" +
+	"\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00E" +
+	"D_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x02\x01\x02\x01\x02\x05\x03\x04\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" +
+	"\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\x93\x0f\x00\x00\xff\xff\x9d\x90\x01\x04\xff\xff\x8f\x80\x00\b\xff" +
+	"\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10\xff\xff\x9d\x90\x00\x14\xff\xff\xab\xa0\x01\x18LMT\x00PDT\x00PST\x00MWT\x00MPT\x00MST\x00MDT\x00\nMST7MDT," +
+	"M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\xbf\xf5\xe5\xc4\x02\x00\x00\xc4\x02\x00\x00\x14\x00\x00\x00America/Buenos_" +
+	"AiresTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif" +
+	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xa8L\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff" +
+	"\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70" +
+	"\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff" +
+	"\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0" +
+	"\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff" +
+	"\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0" +
+	"\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00" +
+	"%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W " +
+	"\x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x00\x00\x00\x00H\xfa\xa2\xb0\x00\x00\x00\x00I\xbca \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x03\x05\x04\x05\x04\x05\xff\xff\xc94\x00\x00\xff\xff\xc3\xd0\x00" +
+	"\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x05\xba\xb2\x94s\x03\x00\x00s\x03\x00\x00\x15\x00\x00\x00America/Cambridge_BayTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00L\x00\x00\x00\b\x00\x00\x00 \xff\xff\xff\xff\xa1\xf2̀\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\x00\x00\x00\x00\x04a\x19\x90\x00" +
+	"\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\b ݐ\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\n\x00\xbf\x90\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\v" +
+	"ࡐ\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00" +
+	"\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00\x00\x1a" +
+	"\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x1d\x10\x00" +
+	"\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'" +
+	"\xfeߐ\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00" +
+	"\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x006" +
+	"2ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\x04\xe9P\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;ۻ\x00\x00" +
+	"\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00C" +
+	"d}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x03\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" +
+	"\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x06\x05\a\x06\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x00\x00\x00\x00\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\xab\xa0\x01" +
+	"\b\xff\xff\x9d\x90\x00\f\xff\xff\xab\xa0\x01\x10\xff\xff\xb9\xb0\x01\x14\xff\xff\xab\xa0\x00\x18\xff\xff\xb9\xb0\x00\x1c-00\x00MWT\x00MPT\x00MST\x00MDT\x00CDT\x00CST\x00E" +
+	"ST\x00\nMST7MDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1e\xfbn۸\x03\x00\x00\xb8\x03\x00\x00\x14\x00\x00\x00Ame" +
+	"rica/Campo_GrandeTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" +
+	"\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00[\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaaz4" +
+	"\xff\xff\xff\xff\xb8\x0fW\xf0\xff\xff\xff\xff\xb8\xfdN\xb0\xff\xff\xff\xff\xb9\xf1B@\xff\xff\xff\xff\xbaނ0\xff\xff\xff\xff\xda8\xbc@\xff\xff\xff\xff\xda\xec\b@\xff\xff\xff\xff\xdc\x19\xef\xc0\xff\xff\xff\xff" +
+	"ܹg0\xff\xff\xff\xff\xdd\xfb#@\xff\xff\xff\xffޛ\xec0\xff\xff\xff\xff\xdfݨ@\xff\xff\xff\xff\xe0TA0\xff\xff\xff\xff\xf4\x98\r\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf6\xc0r@" +
+	"\xff\xff\xff\xff\xf7\x0e,\xb0\xff\xff\xff\xff\xf8Q:@\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xfa\n\xe0\xc0\xff\xff\xff\xff\xfa\xa9\x06\xb0\xff\xff\xff\xff\xfb\xec\x14@\xff\xff\xff\xff\xfc\x8b\x8b\xb0\x00\x00\x00\x00" +
+	"\x1dɜ@\x00\x00\x00\x00\x1ex\xe5\xb0\x00\x00\x00\x00\x1f\xa0C\xc0\x00\x00\x00\x00 3ݰ\x00\x00\x00\x00!\x81w@\x00\x00\x00\x00\"\vְ\x00\x00\x00\x00#X\x1e\xc0\x00\x00\x00\x00#\xe2~0" +
+	"\x00\x00\x00\x00%8\x00\xc0\x00\x00\x00\x00%\xd4\xd50\x00\x00\x00\x00'!\x1d@\x00\x00\x00\x00'\xbd\xf1\xb0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\x94\x990\x00\x00\x00\x00*\xea\x1b\xc0\x00\x00\x00\x00" +
+	"+k@\xb0\x00\x00\x00\x00,\xc0\xc3@\x00\x00\x00\x00-f\xd20\x00\x00\x00\x00.\xa0\xa5@\x00\x00\x00\x00/F\xb40\x00\x00\x00\x000\x80\x87@\x00\x00\x00\x001\x1d[\xb0\x00\x00\x00\x002W.\xc0" +
+	"\x00\x00\x00\x003\x06x0\x00\x00\x00\x0048b@\x00\x00\x00\x004\xf8\xcf0\x00\x00\x00\x006 -@\x00\x00\x00\x006\xcfv\xb0\x00\x00\x00\x007\xf6\xd4\xc0\x00\x00\x00\x008\xb8\x930\x00\x00\x00\x00" +
+	"9\xdf\xf1@\x00\x00\x00\x00:\x8f:\xb0\x00\x00\x00\x00;\xc9\r\xc0\x00\x00\x00\x00<o\x1c\xb0\x00\x00\x00\x00=ğ@\x00\x00\x00\x00>N\xfe\xb0\x00\x00\x00\x00?\x92\f@\x00\x00\x00\x00@.\xe0\xb0" +
+	"\x00\x00\x00\x00A\x87\x06@\x00\x00\x00\x00B\x17\xfd0\x00\x00\x00\x00CQ\xd0@\x00\x00\x00\x00C\xf7\xdf0\x00\x00\x00\x00EMa\xc0\x00\x00\x00\x00E\xe0\xfb\xb0\x00\x00\x00\x00G\x11\x94@\x00\x00\x00\x00" +
+	"G\xb7\xa30\x00\x00\x00\x00H\xfa\xb0\xc0\x00\x00\x00\x00I\x97\x850\x00\x00\x00\x00Jڒ\xc0\x00\x00\x00\x00K\x80\xa1\xb0\x00\x00\x00\x00L\xbat\xc0\x00\x00\x00\x00M`\x83\xb0\x00\x00\x00\x00N\x9aV\xc0" +
+	"\x00\x00\x00\x00OI\xa00\x00\x00\x00\x00P\x83s@\x00\x00\x00\x00Q G\xb0\x00\x00\x00\x00RcU@\x00\x00\x00\x00S\x00)\xb0\x00\x00\x00\x00TC7@\x00\x00\x00\x00T\xe9F0\x00\x00\x00\x00" +
+	"V#\x19@\x00\x00\x00\x00V\xc9(0\x00\x00\x00\x00X\x02\xfb@\x00\x00\x00\x00X\xa9\n0\x00\x00\x00\x00Y\xe2\xdd@\x00\x00\x00\x00Z\x88\xec0\x00\x00\x00\x00[\xden\xc0\x00\x00\x00\x00\\h\xce0" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xcc\xcc\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\bLMT\x00-03\x00-04" +
+	"\x00\n<-04>4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf2\x04\xde\xdd\x11\x02\x00\x00\x11\x02\x00\x00\x0e\x00\x00\x00America/CancunTZif2\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\xa5\xb6\xda`\x00\x00\x00\x00\x16\x86\xd5`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`" +
+	"\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x005\xc4\x00`\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x00" +
+	"8\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xf5\x04\x80\x00\x00\x00\x00;\xb6\xc2\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0" +
+	"\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00F\x0ff\x80\x00\x00\x00\x00" +
+	"G$3p\x00\x00\x00\x00G\xf8\x83\x00\x00\x00\x00\x00I\x04\x15p\x00\x00\x00\x00I\xd8e\x00\x00\x00\x00\x00J\xe3\xf7p\x00\x00\x00\x00K\xb8G\x00\x00\x00\x00\x00L\xcd\x13\xf0\x00\x00\x00\x00M\x98)\x00" +
+	"\x00\x00\x00\x00N\xac\xf5\xf0\x00\x00\x00\x00Ox\v\x00\x00\x00\x00\x00P\x8c\xd7\xf0\x00\x00\x00\x00Qa'\x80\x00\x00\x00\x00Rl\xb9\xf0\x00\x00\x00\x00SA\t\x80\x00\x00\x00\x00TL\x9b\xf0\x00\x00\x00\x00" +
+	"T\xcd\xdd\x00\x01\x03\x02\x03\x02\x03\x02\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x03\xff\xff\xae\xa8\x00\x00\xff\xff\xab\xa0\x00\x04\xff\xff" +
+	"\xc7\xc0\x01\b\xff\xff\xb9\xb0\x00\f\xff\xff\xb9\xb0\x01\x10LMT\x00CST\x00EDT\x00EST\x00CDT\x00\nEST5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x8e\xee\x13" +
+	"\xbe\x00\x00\x00\xbe\x00\x00\x00\x0f\x00\x00\x00America/CaracasTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00" +
+	"\x00\x12\xff\xff\xff\xffi\x87\x1a@\xff\xff\xff\xff\x93\x1e,<\xff\xff\xff\xff\xf6\x98\xecH\x00\x00\x00\x00G[\x92p\x00\x00\x00\x00W%\xa9p\x01\x02\x03\x02\x03\xff\xff\xc1@\x00\x00\xff\xff\xc1D\x00\x04\xff" +
+	"\xff\xc0\xb8\x00\b\xff\xff\xc7\xc0\x00\x0eLMT\x00CMT\x00-0430\x00-04\x00\n<-04>4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00R\xc8\xd9\xf6\xc4\x02\x00\x00\xc4" +
+	"\x02\x00\x00\x11\x00\x00\x00America/CatamarcaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x06\x00\x00\x00\x14\xff" +
+	"\xff\xff\xffr\x9c\xaf,\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba" +
+	"\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff" +
+	"\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xff\xc8" +
+	"\x81\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff" +
+	"\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa" +
+	"\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00" +
+	"\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)" +
+	"\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xbb\xf10\x00\x00\x00\x00@\xd5\v\xc0\x00\x00\x00\x00Gw\t\xb0\x00" +
+	"\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04\x05" +
+	"\x04\x05\x03\x05\x02\x05\x04\x05\xff\xff\xc2T\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00" +
+	"-02\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1'\a\xbd\x97\x00\x00\x00\x97\x00\x00\x00\x0f\x00\x00\x00America/CayenneTZi" +
+	"f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x91\xf4+\x90\xff\xff\xff\xff\xfb\xc35\xc0\x01\x02\xff\xff\xce\xf0\x00\x00\xff\xff\xc7\xc0" +
+	"\x00\x04\xff\xff\xd5\xd0\x00\bLMT\x00-04\x00-03\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Ծ\xe7#\x95\x00\x00\x00\x95\x00\x00\x00\x0e\x00\x00\x00Am" +
+	"erica/CaymanTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00" +
+	"\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xffi\x87&\x10\xff\xff\xff\xff\x8b" +
+	"\xf4a\xe8\x01\x02\xff\xff\xb5p\x00\x00\xff\xff\xb5\x18\x00\x04\xff\xff\xb9\xb0\x00\bLMT\x00CMT\x00EST\x00\nEST5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9bܩ=\xda" +
+	"\x06\x00\x00\xda\x06\x00\x00\x0f\x00\x00\x00America/ChicagoTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaf\x00\x00\x00\x06\x00\x00\x00" +
+	"\x18\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xa2\xcbt\x00\xff\xff\xff\xff\xa3\x83\xf7\xf0\xff\xff\xff" +
+	"\xff\xa4EҀ\xff\xff\xff\xff\xa5c\xd9\xf0\xff\xff\xff\xff\xa6S\xd9\x00\xff\xff\xff\xff\xa7\x15\x97p\xff\xff\xff\xff\xa83\xbb\x00\xff\xff\xff\xff\xa8\xfe\xb3\xf0\xff\xff\xff\xff\xaa\x13\x9d\x00\xff\xff\xff\xff\xaaޕ" +
+	"\xf0\xff\xff\xff\xff\xab\xf3\x7f\x00\xff\xff\xff\xff\xac\xbew\xf0\xff\xff\xff\xff\xad\xd3a\x00\xff\xff\xff\xff\xae\x9eY\xf0\xff\xff\xff\xff\xaf\xb3C\x00\xff\xff\xff\xff\xb0~;\xf0\xff\xff\xff\xff\xb1\x9c_\x80\xff\xff\xff" +
+	"\xff\xb2gXp\xff\xff\xff\xff\xb3|A\x80\xff\xff\xff\xff\xb4G:p\xff\xff\xff\xff\xb5\\#\x80\xff\xff\xff\xff\xb6'\x1cp\xff\xff\xff\xff\xb7<\x05\x80\xff\xff\xff\xff\xb8\x06\xfep\xff\xff\xff\xff\xb9\x1b\xe7" +
+	"\x80\xff\xff\xff\xff\xb9\xe6\xe0p\xff\xff\xff\xff\xbb\x05\x04\x00\xff\xff\xff\xff\xbb\xc6\xc2p\xff\xff\xff\xff\xbc\xe4\xe6\x00\xff\xff\xff\xff\xbd\xaf\xde\xf0\xff\xff\xff\xff\xbe\xc4\xc8\x00\xff\xff\xff\xff\xbf\x8f\xc0\xf0\xff\xff\xff" +
+	"\xff\xc0Z\xd6\x00\xff\xff\xff\xff\xc1\xb0<p\xff\xff\xff\xff\u0084\x8c\x00\xff\xff\xff\xff\xc3O\x84\xf0\xff\xff\xff\xff\xc4dn\x00\xff\xff\xff\xff\xc5/f\xf0\xff\xff\xff\xff\xc6M\x8a\x80\xff\xff\xff\xff\xc7\x0fH" +
+	"\xf0\xff\xff\xff\xff\xc8-l\x80\xff\xff\xff\xff\xc8\xf8ep\xff\xff\xff\xff\xca\rN\x80\xff\xff\xff\xff\xca\xd8Gp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff" +
+	"\xff\xd3u\xf3\x00\xff\xff\xff\xff\xd4@\xeb\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91" +
+	"\xf0\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90p\xff\xff\xff\xff\u07bey\x80\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff" +
+	"\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5W<\xf0\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe77\x1e\xf0\xff\xff\xff\xff\xe8'\x1e" +
+	"\x00\xff\xff\xff\xff\xe9\x17\x00\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea\xf6\xe2\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xd6\xc4\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\xee\xbf\xe1p\xff\xff\xff" +
+	"\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xf0\x9f\xc3p\xff\xff\xff\xff\xf1\x8f\u0080\xff\xff\xff\xff\xf2\x7f\xa5p\xff\xff\xff\xff\xf3o\xa4\x80\xff\xff\xff\xff\xf4_\x87p\xff\xff\xff\xff\xf5O\x86\x80\xff\xff\xff\xff\xf6?i" +
+	"p\xff\xff\xff\xff\xf7/h\x80\xff\xff\xff\xff\xf8(\x85\xf0\xff\xff\xff\xff\xf9\x0fJ\x80\xff\xff\xff\xff\xfa\bg\xf0\xff\xff\xff\xff\xfa\xf8g\x00\xff\xff\xff\xff\xfb\xe8I\xf0\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff" +
+	"\xff\xfd\xc8+\xf0\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\r\xf0\x00\x00\x00\x00\x00\x98\r\x00\x00\x00\x00\x00\x01\x87\xef\xf0\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\fp\x00\x00\x00\x00\x04a\v" +
+	"\x80\x00\x00\x00\x00\x05P\xeep\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\a0\xd0p\x00\x00\x00\x00\a\x8d'\x80\x00\x00\x00\x00\t\x10\xb2p\x00\x00\x00\x00\t\xad\xa3\x00\x00\x00\x00\x00\n\xf0\x94p\x00\x00\x00" +
+	"\x00\v\xe0\x93\x80\x00\x00\x00\x00\fٰ\xf0\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99t\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV" +
+	"\xf0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\"7p\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00" +
+	"\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1܀\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f" +
+	"\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00" +
+	"\x00'\xfeр\x00\x00\x00\x00)\nc\xf0\x00\x00\x00\x00)\u07b3\x80\x00\x00\x00\x00*\xeaE\xf0\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3bp\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3D" +
+	"p\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x93&p\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00" +
+	"\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00;۬\xf0\x00\x00\x00\x00<\xaf\xfc" +
+	"\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00" +
+	"\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x04\x05\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xad\xd4\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x00\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x01\x14LMT\x00CDT\x00" +
+	"CST\x00EST\x00CWT\x00CPT\x00\nCST6CDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x111\x04q\xb3\x02" +
+	"\x00\x00\xb3\x02\x00\x00\x11\x00\x00\x00America/ChihuahuaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\x00\x00\x00\x05\x00\x00" +
+	"\x00\x14\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6fV`\xff\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff\xb8\f6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\x00\x00\x00\x001gv\x00\x00\x00" +
+	"\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7" +
+	"\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xf5\x12\x90\x00\x00\x00\x00;\xb6\xd1\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00" +
+	"\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00F\x0ft\x90\x00\x00\x00\x00G$" +
+	"A\x80\x00\x00\x00\x00G\xf8\x91\x10\x00\x00\x00\x00I\x04#\x80\x00\x00\x00\x00I\xd8s\x10\x00\x00\x00\x00J\xe4\x05\x80\x00\x00\x00\x00K\xb8U\x10\x00\x00\x00\x00L\xcd\"\x00\x00\x00\x00\x00M\x987\x10\x00\x00" +
+	"\x00\x00N\xad\x04\x00\x00\x00\x00\x00Ox\x19\x10\x00\x00\x00\x00P\x8c\xe6\x00\x00\x00\x00\x00Qa5\x90\x00\x00\x00\x00Rl\xc8\x00\x00\x00\x00\x00SA\x17\x90\x00\x00\x00\x00TL\xaa\x00\x00\x00\x00\x00U " +
+	"\xf9\x90\x00\x00\x00\x00V,\x8c\x00\x00\x00\x00\x00W\x00ې\x00\x00\x00\x00X\x15\xa8\x80\x00\x00\x00\x00Xཐ\x00\x00\x00\x00Y\xf5\x8a\x80\x00\x00\x00\x00Z\xc0\x9f\x90\x00\x00\x00\x00[\xd5l\x80\x00\x00" +
+	"\x00\x00\\\xa9\xbc\x10\x00\x00\x00\x00]\xb5N\x80\x00\x00\x00\x00^\x89\x9e\x10\x00\x00\x00\x00_\x950\x80\x00\x00\x00\x00`i\x80\x10\x00\x00\x00\x00a~M\x00\x00\x00\x00\x00bIb\x10\x00\x00\x00\x00c^" +
+	"/\x00\x01\x02\x01\x03\x01\x02\x04\x02\x04\x02\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01" +
+	"\x03\x02\xff\xff\x9c\x8c\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xb9\xb0\x01\x10LMT\x00MST\x00CST\x00MDT\x00CDT\x00\nCST6\nPK" +
+	"\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xad\xf2L\x06\xce\x02\x00\x00\xce\x02\x00\x00\x15\x00\x00\x00America/Ciudad_JuarezTZif2\x00\x00\x00\x00\x00\x00" +
 	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00\nCAT-2\n" +
-	"PK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\x0f\x00\x1c\x00Africa/DjiboutiUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux" +
-	"\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00" +
-	"\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff" +
-	"\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1\xed\xadX\xff\xff\xff\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\"\x84\x00\x00\x00\x00#(\x00\x04\x00\x00*0\x00\n\x00\x00&\xac\x00\x0eLMT" +
-	"\x00+0230\x00EAT\x00+0245\x00\nEAT-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0f\x00\x1c\x00Africa" +
-	"/FreetownUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbe" +
-	"T\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x1c\x00America/UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x03\x04\n\x00\x00" +
-	"\x00\x00\x00\x8fj\xbeTq\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x13\x00\x1c\x00America/Puerto_RicoUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01" +
-	"\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" +
-	"\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62" +
-	"\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT" +
-	"\x00\nAST4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xbf\x03u\xf3\xe4\x01\x00\x00\xe4\x01\x00\x00\x0e\x00\x1c\x00America/RecifeUT\t\x00\x03\xdd\xfc\x94b" +
-	"\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00" +
-	"\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaa" +
-	"g\xb8\xff\xff\xff\xff\xb8\x0fI\xe0\xff\xff\xff\xff\xb8\xfd@\xa0\xff\xff\xff\xff\xb9\xf140\xff\xff\xff\xff\xba\xdet \xff\xff\xff\xff\xda8\xae0\xff\xff\xff\xff\xda\xeb\xfa0\xff\xff\xff\xff\xdc\x19\xe1\xb0\xff\xff" +
-	"\xff\xffܹY \xff\xff\xff\xff\xdd\xfb\x150\xff\xff\xff\xffޛ\xde \xff\xff\xff\xff\xdfݚ0\xff\xff\xff\xff\xe0T3 \xff\xff\xff\xff\xf4\x97\xff\xb0\xff\xff\xff\xff\xf5\x05^ \xff\xff\xff\xff\xf6\xc0" +
-	"d0\xff\xff\xff\xff\xf7\x0e\x1e\xa0\xff\xff\xff\xff\xf8Q,0\xff\xff\xff\xff\xf8\xc7\xc5 \xff\xff\xff\xff\xfa\nҰ\xff\xff\xff\xff\xfa\xa8\xf8\xa0\xff\xff\xff\xff\xfb\xec\x060\xff\xff\xff\xff\xfc\x8b}\xa0\x00\x00" +
-	"\x00\x00\x1dɎ0\x00\x00\x00\x00\x1exנ\x00\x00\x00\x00\x1f\xa05\xb0\x00\x00\x00\x00 3Ϡ\x00\x00\x00\x00!\x81i0\x00\x00\x00\x00\"\vȠ\x00\x00\x00\x00#X\x10\xb0\x00\x00\x00\x00#\xe2" +
-	"p \x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xd4\xc7 \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xb8\x85 \x00\x00\x00\x009\xdf\xe30\x00\x00\x00\x009\xe9\x0f\xa0\x00\x00\x00\x00;\xc8\xff\xb0\x00\x00" +
-	"\x00\x00<o\x0e\xa0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xdfH\x00\x00\xff\xff\xe3\xe0\x01\x04\xff\xff\xd5" +
-	"\xd0\x00\bLMT\x00-02\x00-03\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xd6\xfe\xf3%\xb4\x02\x00\x00\xb4\x02\x00\x00\x10\x00\x1c\x00America" +
-	"/ResoluteUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00:\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xff\xd5\xfb\x81\x80\xff\xff\xff\xff\xf7/L`\xff\xff\xff\xff\xf8(w\xe0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00" +
-	"\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\"7p\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00" +
-	"\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1܀\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0" +
-	"\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)\nc\xf0\x00\x00\x00\x00)\u07b3\x80\x00\x00\x00\x00" +
-	"*\xeaE\xf0\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3bp\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3Dp\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x93&p\x00\x00\x00\x001gv\x00" +
-	"\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x00" +
-	"8\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00;۬\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0" +
-	"\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x03" +
-	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x03\x00\x00\x00\x00\x00\x00" +
-	"\xff\xff\xc7\xc0\x01\x04\xff\xff\xab\xa0\x00\t\xff\xff\xb9\xb0\x01\r\xff\xff\xb9\xb0\x00\x11-00\x00CDDT\x00CST\x00CDT\x00EST\x00\nCST6CDT,M3.2.0" +
-	",M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTa\xcb'\xe9\x9c\x01\x00\x00\x9c\x01\x00\x00\x0e\x00\x1c\x00America/ManausUT\t\x00\x03\xdd\xfc" +
-	"\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff" +
-	"\x96\xaa\x7fD\xff\xff\xff\xff\xb8\x0fW\xf0\xff\xff\xff\xff\xb8\xfdN\xb0\xff\xff\xff\xff\xb9\xf1B@\xff\xff\xff\xff\xbaނ0\xff\xff\xff\xff\xda8\xbc@\xff\xff\xff\xff\xda\xec\b@\xff\xff\xff\xff\xdc\x19\xef\xc0" +
-	"\xff\xff\xff\xffܹg0\xff\xff\xff\xff\xdd\xfb#@\xff\xff\xff\xffޛ\xec0\xff\xff\xff\xff\xdfݨ@\xff\xff\xff\xff\xe0TA0\xff\xff\xff\xff\xf4\x98\r\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff" +
-	"\xf6\xc0r@\xff\xff\xff\xff\xf7\x0e,\xb0\xff\xff\xff\xff\xf8Q:@\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xfa\n\xe0\xc0\xff\xff\xff\xff\xfa\xa9\x06\xb0\xff\xff\xff\xff\xfb\xec\x14@\xff\xff\xff\xff\xfc\x8b\x8b\xb0" +
-	"\x00\x00\x00\x00\x1dɜ@\x00\x00\x00\x00\x1ex\xe5\xb0\x00\x00\x00\x00\x1f\xa0C\xc0\x00\x00\x00\x00 3ݰ\x00\x00\x00\x00!\x81w@\x00\x00\x00\x00\"\vְ\x00\x00\x00\x00,\xc0\xc3@\x00\x00\x00\x00" +
-	"-f\xd20\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xffǼ\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\bLMT\x00-03" +
-	"\x00-04\x00\n<-04>4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT3\x9aG\xc8\xd0\x06\x00\x00\xd0\x06\x00\x00\x10\x00\x1c\x00America/New_YorkU" +
-	"T\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaf\x00\x00\x00\x05\x00\x00" +
-	"\x00\x14\xff\xff\xff\xff^\x03\xf0\x90\xff\xff\xff\xff\x9e\xa6\x1ep\xff\xff\xff\xff\x9f\xba\xeb`\xff\xff\xff\xff\xa0\x86\x00p\xff\xff\xff\xff\xa1\x9a\xcd`\xff\xff\xff\xff\xa2e\xe2p\xff\xff\xff\xff\xa3\x83\xe9\xe0\xff\xff" +
-	"\xff\xff\xa4j\xaep\xff\xff\xff\xff\xa55\xa7`\xff\xff\xff\xff\xa6S\xca\xf0\xff\xff\xff\xff\xa7\x15\x89`\xff\xff\xff\xff\xa83\xac\xf0\xff\xff\xff\xff\xa8\xfe\xa5\xe0\xff\xff\xff\xff\xaa\x13\x8e\xf0\xff\xff\xff\xff\xaa\xde" +
-	"\x87\xe0\xff\xff\xff\xff\xab\xf3p\xf0\xff\xff\xff\xff\xac\xbei\xe0\xff\xff\xff\xff\xad\xd3R\xf0\xff\xff\xff\xff\xae\x9eK\xe0\xff\xff\xff\xff\xaf\xb34\xf0\xff\xff\xff\xff\xb0~-\xe0\xff\xff\xff\xff\xb1\x9cQp\xff\xff" +
-	"\xff\xff\xb2gJ`\xff\xff\xff\xff\xb3|3p\xff\xff\xff\xff\xb4G,`\xff\xff\xff\xff\xb5\\\x15p\xff\xff\xff\xff\xb6'\x0e`\xff\xff\xff\xff\xb7;\xf7p\xff\xff\xff\xff\xb8\x06\xf0`\xff\xff\xff\xff\xb9\x1b" +
-	"\xd9p\xff\xff\xff\xff\xb9\xe6\xd2`\xff\xff\xff\xff\xbb\x04\xf5\xf0\xff\xff\xff\xff\xbbƴ`\xff\xff\xff\xff\xbc\xe4\xd7\xf0\xff\xff\xff\xff\xbd\xaf\xd0\xe0\xff\xff\xff\xff\xbeĹ\xf0\xff\xff\xff\xff\xbf\x8f\xb2\xe0\xff\xff" +
-	"\xff\xff\xc0\xa4\x9b\xf0\xff\xff\xff\xff\xc1o\x94\xe0\xff\xff\xff\xff\u0084}\xf0\xff\xff\xff\xff\xc3Ov\xe0\xff\xff\xff\xff\xc4d_\xf0\xff\xff\xff\xff\xc5/X\xe0\xff\xff\xff\xff\xc6M|p\xff\xff\xff\xff\xc7\x0f" +
-	":\xe0\xff\xff\xff\xff\xc8-^p\xff\xff\xff\xff\xc8\xf8W`\xff\xff\xff\xff\xca\r@p\xff\xff\xff\xff\xca\xd89`\xff\xff\xff\xffˈ\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\xff\xff" +
-	"\xff\xff\xd3u\xe4\xf0\xff\xff\xff\xff\xd4@\xdd\xe0\xff\xff\xff\xff\xd5U\xc6\xf0\xff\xff\xff\xff\xd6 \xbf\xe0\xff\xff\xff\xff\xd75\xa8\xf0\xff\xff\xff\xff\xd8\x00\xa1\xe0\xff\xff\xff\xff\xd9\x15\x8a\xf0\xff\xff\xff\xff\xd9\xe0" +
-	"\x83\xe0\xff\xff\xff\xff\xda\xfe\xa7p\xff\xff\xff\xff\xdb\xc0e\xe0\xff\xff\xff\xff\xdcމp\xff\xff\xff\xffݩ\x82`\xff\xff\xff\xff\u07bekp\xff\xff\xff\xff߉d`\xff\xff\xff\xff\xe0\x9eMp\xff\xff" +
-	"\xff\xff\xe1iF`\xff\xff\xff\xff\xe2~/p\xff\xff\xff\xff\xe3I(`\xff\xff\xff\xff\xe4^\x11p\xff\xff\xff\xff\xe5W.\xe0\xff\xff\xff\xff\xe6G-\xf0\xff\xff\xff\xff\xe77\x10\xe0\xff\xff\xff\xff\xe8'" +
-	"\x0f\xf0\xff\xff\xff\xff\xe9\x16\xf2\xe0\xff\xff\xff\xff\xea\x06\xf1\xf0\xff\xff\xff\xff\xea\xf6\xd4\xe0\xff\xff\xff\xff\xeb\xe6\xd3\xf0\xff\xff\xff\xff\xecֶ\xe0\xff\xff\xff\xff\xedƵ\xf0\xff\xff\xff\xff\xee\xbf\xd3`\xff\xff" +
-	"\xff\xff\xef\xaf\xd2p\xff\xff\xff\xff\xf0\x9f\xb5`\xff\xff\xff\xff\xf1\x8f\xb4p\xff\xff\xff\xff\xf2\x7f\x97`\xff\xff\xff\xff\xf3o\x96p\xff\xff\xff\xff\xf4_y`\xff\xff\xff\xff\xf5Oxp\xff\xff\xff\xff\xf6?" +
-	"[`\xff\xff\xff\xff\xf7/Zp\xff\xff\xff\xff\xf8(w\xe0\xff\xff\xff\xff\xf9\x0f<p\xff\xff\xff\xff\xfa\bY\xe0\xff\xff\xff\xff\xfa\xf8X\xf0\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff" +
-	"\xff\xff\xfd\xc8\x1d\xe0\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`" +
-	"\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\a0\xc2`\x00\x00\x00\x00\a\x8d\x19p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\t\xad\x94\xf0\x00\x00\x00\x00\n\xf0\x86`\x00\x00" +
-	"\x00\x00\v\xe0\x85p\x00\x00\x00\x00\f٢\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12y" +
-	"H\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00" +
-	"\x00\x00\x1a\x02\v`\x00\x00\x00\x00\x1a\xf2\np\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v" +
-	"\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\"U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00" +
-	"\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\nU\xe0\x00\x00\x00\x00)ޥp\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb3" +
-	"6`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00" +
-	"\x00\x0062\xbe`\x00\x00\x00\x007\a\r\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf" +
-	"\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00" +
-	"\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xba\x9e\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\f\xff\xff\xc7\xc0\x01\x10LMT\x00EDT\x00EST\x00E" +
-	"WT\x00EPT\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x1e+}\x15\xb4\x02\x00\x00\xb4\x02\x00\x00\x14\x00\x1c" +
-	"\x00America/Rankin_InletUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6fV`\xff\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff" +
+	"\xb8\f6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ" +
+	"\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xf5\x12\x90\x00\x00\x00\x00;\xb6\xd1\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00" +
+	"=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90" +
+	"\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00F\x0ft\x90\x00\x00\x00\x00G$A\x80\x00\x00\x00\x00G\xf8\x91\x10\x00\x00\x00\x00I\x04#\x80\x00\x00\x00\x00I\xd8s\x10\x00\x00\x00\x00J\xe4\x05\x80\x00\x00\x00\x00" +
+	"K\x9c\xa5\x90\x00\x00\x00\x00L\xd6\\\x80\x00\x00\x00\x00M|\x87\x90\x00\x00\x00\x00N\xb6>\x80\x00\x00\x00\x00O\\i\x90\x00\x00\x00\x00P\x96 \x80\x00\x00\x00\x00Q<K\x90\x00\x00\x00\x00Rv\x02\x80" +
+	"\x00\x00\x00\x00S\x1c-\x90\x00\x00\x00\x00TU\xe4\x80\x00\x00\x00\x00T\xfc\x0f\x90\x00\x00\x00\x00V5ƀ\x00\x00\x00\x00V\xe5,\x10\x00\x00\x00\x00X\x1e\xe3\x00\x00\x00\x00\x00X\xc5\x0e\x10\x00\x00\x00\x00" +
+	"Y\xfe\xc5\x00\x00\x00\x00\x00Z\xa4\xf0\x10\x00\x00\x00\x00[ާ\x00\x00\x00\x00\x00\\\x84\xd2\x10\x00\x00\x00\x00]\xbe\x89\x00\x00\x00\x00\x00^d\xb4\x10\x00\x00\x00\x00_\x9ek\x00\x00\x00\x00\x00`MА" +
+	"\x00\x00\x00\x00a\x87\x87\x80\x00\x00\x00\x00b-\xb2\x90\x00\x00\x00\x00c^/\x00\x00\x00\x00\x00c\x86\xf1`\x01\x02\x01\x03\x01\x02\x04\x02\x04\x02\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01" +
+	"\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x02\x01\xff\xff\x9c,\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xb9" +
+	"\xb0\x01\x10LMT\x00MST\x00CST\x00MDT\x00CDT\x00\nMST7MDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00Ծ\xe7#\x95\x00\x00\x00\x95\x00\x00\x00\x15\x00\x00\x00America/Coral_HarbourTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xffi\x87&\x10\xff\xff\xff\xff\x8b\xf4a\xe8\x01\x02\xff\xff\xb5p\x00\x00\xff\xff\xb5\x18\x00\x04\xff\xff\xb9\xb0\x00\bLMT\x00CMT\x00EST" +
+	"\x00\nEST5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xef\xf0R\x8a\xc4\x02\x00\x00\xc4\x02\x00\x00\x0f\x00\x00\x00America/CordobaTZif2\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xad\xb0\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff" +
+	"\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbe" +
+	"x\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff" +
+	"\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xff\xce" +
+	"\xb0\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff" +
+	"\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe" +
+	"\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00" +
+	"\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008" +
+	"\xbf*\xb0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x00\x00\x00\x00H\xfa\xa2\xb0\x00\x00\x00\x00I\xbca \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x04\x05\x04\x05\xff\xff\xc3\xd0\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f" +
+	"\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb1݂x\xe8\x00" +
+	"\x00\x00\xe8\x00\x00\x00\x12\x00\x00\x00America/Costa_RicaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x04\x00" +
+	"\x00\x00\x11\xff\xff\xff\xffi\x87*M\xff\xff\xff\xff\xa3\xe8\x16M\x00\x00\x00\x00\x116I`\x00\x00\x00\x00\x11\xb7nP\x00\x00\x00\x00\x13\x16+`\x00\x00\x00\x00\x13\x97PP\x00\x00\x00\x00'\x97\xe0`\x00" +
+	"\x00\x00\x00(n\xb6\xd0\x00\x00\x00\x00)w\xc2`\x00\x00\x00\x00)\xc2\xd9\xd0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\xb13\x00\x00\xff\xff\xb13\x00\x04\xff\xff\xb9\xb0\x01\t\xff\xff\xab\xa0\x00\rLMT" +
+	"\x00SJMT\x00CDT\x00CST\x00\nCST6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ø\xab\x9b\xf0\x00\x00\x00\xf0\x00\x00\x00\x0f\x00\x00\x00America/Cr" +
+	"estonTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif" +
+	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff^\x04\f\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff" +
+	"\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xcf\x17\xdf\x1c\xff\xff\xff\xffϏ\xe5\xac\xff\xff\xff\xffЁ\x1a\x1c\xff\xff\xff\xff\xfa\xf8u\x10" +
+	"\xff\xff\xff\xff\xfb\xe8X\x00\x02\x01\x02\x01\x02\x03\x02\x03\x02\x01\x02\xff\xff\x96\xee\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\fLMT\x00MDT\x00MST\x00MWT\x00\n" +
+	"MST7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f$*\xa0\xa6\x03\x00\x00\xa6\x03\x00\x00\x0e\x00\x00\x00America/CuiabaTZif2\x00\x00\x00\x00\x00\x00" +
 	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xff\xe7\x8cn\x00\xff\xff\xff\xff\xf7/L`\xff\xff\xff\xff\xf8(w\xe0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00" +
-	"\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\"7p\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80" +
-	"\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1܀\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00" +
-	"\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)\nc\xf0" +
-	"\x00\x00\x00\x00)\u07b3\x80\x00\x00\x00\x00*\xeaE\xf0\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3bp\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3Dp\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x00" +
-	"0\x93&p\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00" +
-	"\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00;۬\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00" +
-	">\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp" +
-	"\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x03\x02\x03\x02\x03\x02\x03" +
-	"\x02\x03\x02\x03\x02\x03\x00\x00\x00\x00\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xab\xa0\x00\t\xff\xff\xb9\xb0\x01\r\xff\xff\xb9\xb0\x00\x11-00\x00CDDT\x00CST\x00CDT\x00EST\x00\nCS" +
-	"T6CDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xfe7\xa1\x87\x1b\x01\x00\x00\x1b\x01\x00\x00\f\x00\x1c\x00America/L" +
-	"imaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00" +
-	"\x00\x04\x00\x00\x00\f\xff\xff\xff\xffi\x87#\xbc\xff\xff\xff\xff\x8ct@\xd4\xff\xff\xff\xff\xc3\xcfJP\xff\xff\xff\xff\xc4E\xe3@\xff\xff\xff\xff\xc5/J\xd0\xff\xff\xff\xff\xc6\x1f-\xc0\xff\xff\xff\xff\xc7\x0f" +
-	",\xd0\xff\xff\xff\xff\xc7\xff\x0f\xc0\x00\x00\x00\x00\x1e\x18\xc4P\x00\x00\x00\x00\x1e\x8f]@\x00\x00\x00\x00\x1f\xf9\xf7\xd0\x00\x00\x00\x00 p\x90\xc0\x00\x00\x00\x00%\x9e\xe3\xd0\x00\x00\x00\x00&\x15|\xc0\x00\x00" +
-	"\x00\x00-%\x03P\x00\x00\x00\x00-\x9b\x9c@\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\xb7\xc4\x00\x00\xff\xff\xb7\xac\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\bLMT\x00-0" +
-	"4\x00-05\x00\n<-05>5\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTq\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x15\x00\x1c\x00America/St_Barth" +
-	"elemyUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04" +
-	"\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0" +
-	"\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTP\x0f(\b=\x01\x00\x00=\x01\x00\x00\x15\x00\x1c\x00" +
-	"America/Santo_DomingoUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x06\x00\x00\x00\x1b\xff\xff\xff\xffi\x87\x1d\b\xff\xff\xff\xff\xba\xdfB`\xff\xff\xff\xff\xfa\bK\xd0\xff\xff\xff\xff\xfa\xa7\xc3@\xff\xff\xff\xff" +
-	"\xff\xa7\xf1\xd0\x00\x00\x00\x00\x00C{\xc8\x00\x00\x00\x00\x01\x87\xd3\xd0\x00\x00\x00\x00\x01\xfa\x7fH\x00\x00\x00\x00\x03p\xf0P\x00\x00\x00\x00\x03\xdd\x04H\x00\x00\x00\x00\x05P\xd2P\x00\x00\x00\x00\x05\xbf\x89H" +
-	"\x00\x00\x00\x00\a0\xb4P\x00\x00\x00\x00\a\xa0\xbc\xc8\x00\x00\x00\x00\t\x10\x96P\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:)\xe1`\x01\x03\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x05\x03\x05\xff\xff\xbe" +
-	"x\x00\x00\xff\xff\xbe`\x00\x04\xff\xff\xc7\xc0\x01\t\xff\xff\xb9\xb0\x00\r\xff\xff\xc0\xb8\x01\x11\xff\xff\xc7\xc0\x00\x17LMT\x00SDMT\x00EDT\x00EST\x00-0430\x00AST\x00" +
-	"\nAST4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT>\x14\xe7\x03\x83\x03\x00\x00\x83\x03\x00\x00\x0f\x00\x1c\x00America/DetroitUT\t\x00\x03\xdd\xfc\x94b" +
-	"\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaa{\x94\xff\xff\xff\xff\xb8\x0fW\xf0\xff\xff\xff\xff\xb8\xfdN\xb0\xff\xff\xff\xff\xb9\xf1B@\xff\xff\xff\xff" +
+	"\xbaނ0\xff\xff\xff\xff\xda8\xbc@\xff\xff\xff\xff\xda\xec\b@\xff\xff\xff\xff\xdc\x19\xef\xc0\xff\xff\xff\xffܹg0\xff\xff\xff\xff\xdd\xfb#@\xff\xff\xff\xffޛ\xec0\xff\xff\xff\xff\xdfݨ@" +
+	"\xff\xff\xff\xff\xe0TA0\xff\xff\xff\xff\xf4\x98\r\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf6\xc0r@\xff\xff\xff\xff\xf7\x0e,\xb0\xff\xff\xff\xff\xf8Q:@\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff" +
+	"\xfa\n\xe0\xc0\xff\xff\xff\xff\xfa\xa9\x06\xb0\xff\xff\xff\xff\xfb\xec\x14@\xff\xff\xff\xff\xfc\x8b\x8b\xb0\x00\x00\x00\x00\x1dɜ@\x00\x00\x00\x00\x1ex\xe5\xb0\x00\x00\x00\x00\x1f\xa0C\xc0\x00\x00\x00\x00 3ݰ" +
+	"\x00\x00\x00\x00!\x81w@\x00\x00\x00\x00\"\vְ\x00\x00\x00\x00#X\x1e\xc0\x00\x00\x00\x00#\xe2~0\x00\x00\x00\x00%8\x00\xc0\x00\x00\x00\x00%\xd4\xd50\x00\x00\x00\x00'!\x1d@\x00\x00\x00\x00" +
+	"'\xbd\xf1\xb0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\x94\x990\x00\x00\x00\x00*\xea\x1b\xc0\x00\x00\x00\x00+k@\xb0\x00\x00\x00\x00,\xc0\xc3@\x00\x00\x00\x00-f\xd20\x00\x00\x00\x00.\xa0\xa5@" +
+	"\x00\x00\x00\x00/F\xb40\x00\x00\x00\x000\x80\x87@\x00\x00\x00\x001\x1d[\xb0\x00\x00\x00\x002W.\xc0\x00\x00\x00\x003\x06x0\x00\x00\x00\x0048b@\x00\x00\x00\x004\xf8\xcf0\x00\x00\x00\x00" +
+	"6 -@\x00\x00\x00\x006\xcfv\xb0\x00\x00\x00\x007\xf6\xd4\xc0\x00\x00\x00\x008\xb8\x930\x00\x00\x00\x009\xdf\xf1@\x00\x00\x00\x00:\x8f:\xb0\x00\x00\x00\x00;\xc9\r\xc0\x00\x00\x00\x00<o\x1c\xb0" +
+	"\x00\x00\x00\x00=ğ@\x00\x00\x00\x00>N\xfe\xb0\x00\x00\x00\x00A\x87\x06@\x00\x00\x00\x00B\x17\xfd0\x00\x00\x00\x00CQ\xd0@\x00\x00\x00\x00C\xf7\xdf0\x00\x00\x00\x00EMa\xc0\x00\x00\x00\x00" +
+	"E\xe0\xfb\xb0\x00\x00\x00\x00G\x11\x94@\x00\x00\x00\x00G\xb7\xa30\x00\x00\x00\x00H\xfa\xb0\xc0\x00\x00\x00\x00I\x97\x850\x00\x00\x00\x00Jڒ\xc0\x00\x00\x00\x00K\x80\xa1\xb0\x00\x00\x00\x00L\xbat\xc0" +
+	"\x00\x00\x00\x00M`\x83\xb0\x00\x00\x00\x00N\x9aV\xc0\x00\x00\x00\x00OI\xa00\x00\x00\x00\x00P\x83s@\x00\x00\x00\x00Q G\xb0\x00\x00\x00\x00RcU@\x00\x00\x00\x00S\x00)\xb0\x00\x00\x00\x00" +
+	"TC7@\x00\x00\x00\x00T\xe9F0\x00\x00\x00\x00V#\x19@\x00\x00\x00\x00V\xc9(0\x00\x00\x00\x00X\x02\xfb@\x00\x00\x00\x00X\xa9\n0\x00\x00\x00\x00Y\xe2\xdd@\x00\x00\x00\x00Z\x88\xec0" +
+	"\x00\x00\x00\x00[\xden\xc0\x00\x00\x00\x00\\h\xce0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xcbl\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7" +
+	"\xc0\x00\bLMT\x00-03\x00-04\x00\n<-04>4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0f\x00\x00\x00America" +
+	"/CuracaoTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00T" +
+	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff" +
+	"\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\n" +
+	"AST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xc2\rx\xbf\x01\x00\x00\xbf\x01\x00\x00\x14\x00\x00\x00America/DanmarkshavnTZif2" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\"\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\x9b\x80I\x00\x00\x00\x00\x00\x13M|P\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#" +
+	"\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00" +
+	"\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<" +
+	"E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00" +
+	"\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x000\xe7" +
+	"N0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\xff\xff\xee\x80\x00\x00\xff\xff\xd5\xd0\x00\x04\xff\xff\xe3\xe0\x01\b\x00\x00\x00\x00\x00\f" +
+	"LMT\x00-03\x00-02\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe\xe6\xf5J\x05\x04\x00\x00\x05\x04\x00\x00\x0e\x00\x00\x00America/" +
+	"DawsonTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZi" +
+	"f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]\x00\x00\x00\t\x00\x00\x00%\xff\xff\xff\xff}\x86\x8e\xb4\xff\xff\xff\xff\x9e\xb8˰\xff\xff\xff" +
+	"\xff\x9f\xbb#\xa0\xff\xff\xff\xff\xa0\xd0\f\xb0\xff\xff\xff\xff\xa1\xa2Ҁ\xff\xff\xff\xffˉ(\xb0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a4 \xff\xff\xff\xff\xf7/v\x90\xff\xff\xff\xff\xf8(\xa2" +
+	"\x10\x00\x00\x00\x00\a0\xec\x90\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00" +
+	"\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1\xdb" +
+	"\x90\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\"V\r \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00" +
+	"\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\n\x80\x10\x00\x00\x00\x00)\xdeϠ\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93" +
+	"\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00" +
+	"\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\a8 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9" +
+	"\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00" +
+	"\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E\xf3\xd3 \x00\x00\x00\x00G-\x8a\x10\x00\x00\x00\x00Gӵ \x00\x00\x00\x00I\rl\x10\x00\x00\x00\x00I\xb3\x97" +
+	" \x00\x00\x00\x00J\xedN\x10\x00\x00\x00\x00K\x9c\xb3\xa0\x00\x00\x00\x00L\xd6j\x90\x00\x00\x00\x00M|\x95\xa0\x00\x00\x00\x00N\xb6L\x90\x00\x00\x00\x00O\\w\xa0\x00\x00\x00\x00P\x96.\x90\x00\x00\x00" +
+	"\x00Q<Y\xa0\x00\x00\x00\x00Rv\x10\x90\x00\x00\x00\x00S\x1c;\xa0\x00\x00\x00\x00TU\xf2\x90\x00\x00\x00\x00T\xfc\x1d\xa0\x00\x00\x00\x00V5Ԑ\x00\x00\x00\x00V\xe5: \x00\x00\x00\x00X\x1e\xf1" +
+	"\x10\x00\x00\x00\x00X\xc5\x1c \x00\x00\x00\x00Y\xfe\xd3\x10\x00\x00\x00\x00Z\xa4\xfe \x00\x00\x00\x00[\u07b5\x10\x00\x00\x00\x00\\\x84\xe0 \x00\x00\x00\x00]\xbe\x97\x10\x00\x00\x00\x00^d\xc2 \x00\x00\x00" +
+	"\x00_\x9e\\\xf0\x02\x01\x02\x01\x02\x03\x04\x02\x05\x02\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06" +
+	"\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\b\xff\xff}L\x00\x00\xff\xff\x8f\x80\x01\x04\xff\xff\x81p\x00\b\xff\xff\x8f\x80" +
+	"\x01\f\xff\xff\x8f\x80\x01\x10\xff\xff\x9d\x90\x01\x14\xff\xff\x8f\x80\x00\x19\xff\xff\x9d\x90\x01\x1d\xff\xff\x9d\x90\x00!LMT\x00YDT\x00YST\x00YWT\x00YPT\x00YDDT\x00PST" +
+	"\x00PDT\x00MST\x00\nMST7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00+\x10`ȫ\x02\x00\x00\xab\x02\x00\x00\x14\x00\x00\x00America/Dawson_" +
+	"CreekTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif" +
+	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff^=t8\xff\xff\xff\xff\x9e\xb8\xbd\xa0\xff\xff\xff\xff" +
+	"\x9f\xbb\x15\x90\xff\xff\xff\xffˉ\x1a\xa0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a&\x10\xff\xff\xff\xff\xd5U\xf1 \xff\xff\xff\xff\xd6 \xea\x10\xff\xff\xff\xff\xd75\xd3 \xff\xff\xff\xff\xd8\x00\xcc\x10" +
+	"\xff\xff\xff\xff\xd9\x15\xb5 \xff\xff\xff\xff\xd9\xe0\xae\x10\xff\xff\xff\xff\xda\xfeѠ\xff\xff\xff\xff\xdb\xc0\x90\x10\xff\xff\xff\xff\xdc\u07b3\xa0\xff\xff\xff\xffݩ\xac\x90\xff\xff\xff\xff\u07be\x95\xa0\xff\xff\xff\xff" +
+	"߉\x8e\x90\xff\xff\xff\xff\xe0\x9ew\xa0\xff\xff\xff\xff\xe1ip\x90\xff\xff\xff\xff\xe2~Y\xa0\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4^;\xa0\xff\xff\xff\xff\xe5)4\x90\xff\xff\xff\xff\xe6GX " +
+	"\xff\xff\xff\xff\xe7\x12Q\x10\xff\xff\xff\xff\xe8': \xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff\xff\xea\a\x1c \xff\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff\xff\xeb\xe6\xfe \xff\xff\xff\xff\xec\xb1\xf7\x10\xff\xff\xff\xff" +
+	"\xed\xc6\xe0 \xff\xff\xff\xff\xee\x91\xd9\x10\xff\xff\xff\xff\xef\xaf\xfc\xa0\xff\xff\xff\xff\xf0q\xbb\x10\xff\xff\xff\xff\xf1\x8fޠ\xff\xff\xff\xff\xf2\x7f\xc1\x90\xff\xff\xff\xff\xf3o\xc0\xa0\xff\xff\xff\xff\xf4_\xa3\x90" +
+	"\xff\xff\xff\xff\xf5O\xa2\xa0\xff\xff\xff\xff\xf6?\x85\x90\xff\xff\xff\xff\xf7/\x84\xa0\xff\xff\xff\xff\xf8(\xa2\x10\xff\xff\xff\xff\xf9\x0ff\xa0\xff\xff\xff\xff\xfa\b\x84\x10\xff\xff\xff\xff\xfa\xf8\x83 \xff\xff\xff\xff" +
+	"\xfb\xe8f\x10\xff\xff\xff\xff\xfc\xd8e \xff\xff\xff\xff\xfd\xc8H\x10\xff\xff\xff\xff\xfe\xb8G \xff\xff\xff\xff\xff\xa8*\x10\x00\x00\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88\f\x10\x00\x00\x00\x00\x02x\v " +
+	"\x00\x00\x00\x00\x03q(\x90\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05\x01\xf0\x90\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x05\xff\xff\x8fH\x00\x00\xff\xff\x9d\x90\x01\x04\xff\xff\x8f\x80\x00\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10\xff\xff\x9d\x90\x00\x14LM" +
+	"T\x00PDT\x00PST\x00PWT\x00PPT\x00MST\x00\nMST7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\x80\x94@\x12\x04\x00\x00\x12\x04\x00\x00\x0e\x00\x00\x00Am" +
+	"erica/DenverTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00" +
+	"\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff^\x04\f\xb0\xff\xff\xff\xff\x9e" +
+	"\xa6:\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff\xff\xff\xa2e\xfe\x90\xff\xff\xff\xff\xa3\x84\x06\x00\xff\xff\xff\xff\xa4E\xe0\x90\xff\xff\xff\xff\xa4\x8f\xa6\x80\xff" +
+	"\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xf7/v\x90\xff\xff\xff\xff\xf8(\x94\x00\xff\xff\xff\xff\xf9\x0fX\x90\xff\xff\xff\xff\xfa\bv\x00\xff\xff\xff\xff\xfa" +
+	"\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W\x10\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb89\x10\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x1b\x10\x00\x00\x00\x00\x01\x87\xfe\x00\x00" +
+	"\x00\x00\x00\x02w\xfd\x10\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\a\x8d5\x90\x00\x00\x00\x00\t" +
+	"\x10\xc0\x80\x00\x00\x00\x00\t\xad\xb1\x10\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\vࡐ\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00" +
+	"\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17" +
+	")(\x10\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00" +
+	"\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%" +
+	"J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeߐ\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00" +
+	"\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003" +
+	"Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00" +
+	"\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A" +
+	"\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\x9d\x94\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10LMT\x00MDT\x00MS" +
+	"T\x00MWT\x00MPT\x00\nMST7MDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x14\xe7\x03\x83\x03\x00\x00\x83\x03\x00\x00" +
+	"\x0f\x00\x00\x00America/DetroitTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00" +
 	"\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff\x85\xbd" +
 	"\"[\xff\xff\xff\xff\x99<\x94\x00\xff\xff\xff\xffˈ\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff\xd75\xa8\xf0\xff\xff\xff\xff\xd8\x00\xa1\xe0\xff\xff\xff\xff\xfb3\x90\x8c\xff\xff" +
 	"\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\a0\xc2`\x00\x00\x00\x00\a\x8d\x19p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\n\x00" +
@@ -452,1212 +910,411 @@
 	"\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x01\x02\x03\x04\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05" +
 	"\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\xff\xff\xb2%\x00\x00" +
 	"\xff\xff\xab\xa0\x00\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\f\xff\xff\xc7\xc0\x01\x10\xff\xff\xc7\xc0\x01\x14LMT\x00CST\x00EST\x00EWT\x00EPT\x00EDT\x00\nEST5E" +
-	"DT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xf1\xf9\x1dɻ\x00\x00\x00\xbb\x00\x00\x00\x12\x00\x1c\x00America/Para" +
-	"mariboUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x04\x00\x00\x00\x05\x00\x00\x00\x12\xff\xff\xff\xff\x91\x05\x8e\xb8\xff\xff\xff\xff\xbe*K\xc4\xff\xff\xff\xff\xd2b,\xb4\x00\x00\x00\x00\x1b\xbe1\xb8\x01\x02\x03\x04\xff\xff\xccH\x00\x00\xff\xff\xcc<\x00\x04\xff\xff\xcc" +
-	"L\x00\x04\xff\xff\xce\xc8\x00\b\xff\xff\xd5\xd0\x00\x0eLMT\x00PMT\x00-0330\x00-03\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT,\xdb~\xab\xb2" +
-	"\x03\x00\x00\xb2\x03\x00\x00\x0f\x00\x1c\x00America/YakutatUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S\x00\x00\x00\b\x00\x00\x00\x1e\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}\x877\xbf\xff\xff\xff\xffˉ(\xb0\xff\xff\xff\xff\xd2#\xf4" +
-	"p\xff\xff\xff\xff\xd2a4 \xff\xff\xff\xff\xfe\xb8U0\xff\xff\xff\xff\xff\xa88 \x00\x00\x00\x00\x00\x9870\x00\x00\x00\x00\x01\x88\x1a \x00\x00\x00\x00\x02x\x190\x00\x00\x00\x00\x03q6\xa0\x00\x00\x00" +
-	"\x00\x04a5\xb0\x00\x00\x00\x00\x05Q\x18\xa0\x00\x00\x00\x00\x06A\x17\xb0\x00\x00\x00\x00\a0\xfa\xa0\x00\x00\x00\x00\a\x8dQ\xb0\x00\x00\x00\x00\t\x10ܠ\x00\x00\x00\x00\t\xad\xcd0\x00\x00\x00\x00\n\xf0\xbe" +
-	"\xa0\x00\x00\x00\x00\v\u0f70\x00\x00\x00\x00\f\xd9\xdb \x00\x00\x00\x00\r\xc0\x9f\xb0\x00\x00\x00\x00\x0e\xb9\xbd \x00\x00\x00\x00\x0f\xa9\xbc0\x00\x00\x00\x00\x10\x99\x9f \x00\x00\x00\x00\x11\x89\x9e0\x00\x00\x00" +
-	"\x00\x12y\x81 \x00\x00\x00\x00\x13i\x800\x00\x00\x00\x00\x14Yc \x00\x00\x00\x00\x15Ib0\x00\x00\x00\x00\x169E \x00\x00\x00\x00\x17)D0\x00\x00\x00\x00\x18\"a\xa0\x00\x00\x00\x00\x19\t&" +
-	"0\x00\x00\x00\x00\x1a\x02C\xa0\x00\x00\x00\x00\x1a+\x14\x10\x00\x00\x00\x00\x1a\xf2B\xb0\x00\x00\x00\x00\x1b\xe2%\xa0\x00\x00\x00\x00\x1c\xd2$\xb0\x00\x00\x00\x00\x1d\xc2\a\xa0\x00\x00\x00\x00\x1e\xb2\x06\xb0\x00\x00\x00" +
-	"\x00\x1f\xa1\xe9\xa0\x00\x00\x00\x00 v90\x00\x00\x00\x00!\x81ˠ\x00\x00\x00\x00\"V\x1b0\x00\x00\x00\x00#j\xe8 \x00\x00\x00\x00$5\xfd0\x00\x00\x00\x00%J\xca \x00\x00\x00\x00&\x15\xdf" +
-	"0\x00\x00\x00\x00'*\xac \x00\x00\x00\x00'\xfe\xfb\xb0\x00\x00\x00\x00)\n\x8e \x00\x00\x00\x00)\xdeݰ\x00\x00\x00\x00*\xeap \x00\x00\x00\x00+\xbe\xbf\xb0\x00\x00\x00\x00,ӌ\xa0\x00\x00\x00" +
-	"\x00-\x9e\xa1\xb0\x00\x00\x00\x00.\xb3n\xa0\x00\x00\x00\x00/~\x83\xb0\x00\x00\x00\x000\x93P\xa0\x00\x00\x00\x001g\xa00\x00\x00\x00\x002s2\xa0\x00\x00\x00\x003G\x820\x00\x00\x00\x004S\x14" +
-	"\xa0\x00\x00\x00\x005'd0\x00\x00\x00\x0062\xf6\xa0\x00\x00\x00\x007\aF0\x00\x00\x00\x008\x1c\x13 \x00\x00\x00\x008\xe7(0\x00\x00\x00\x009\xfb\xf5 \x00\x00\x00\x00:\xc7\n0\x00\x00\x00" +
-	"\x00;\xdb\xd7 \x00\x00\x00\x00<\xb0&\xb0\x00\x00\x00\x00=\xbb\xb9 \x00\x00\x00\x00>\x90\b\xb0\x00\x00\x00\x00?\x9b\x9b \x00\x00\x00\x00@o\xea\xb0\x00\x00\x00\x00A\x84\xb7\xa0\x00\x00\x00\x00BO\xcc" +
-	"\xb0\x00\x00\x00\x00Cd\x99\xa0\x00\x00\x00\x00D/\xae\xb0\x00\x00\x00\x00ED{\xa0\x00\x00\x00\x00E\xf3\xe10\x01\x02\x03\x04\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02" +
-	"\x05\x02\x05\x02\x05\x02\x05\x02\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\x00\x00\u0381" +
-	"\x00\x00\xff\xff}\x01\x00\x00\xff\xff\x81p\x00\x04\xff\xff\x8f\x80\x01\b\xff\xff\x8f\x80\x01\f\xff\xff\x8f\x80\x01\x10\xff\xff\x8f\x80\x01\x14\xff\xff\x81p\x00\x19LMT\x00YST\x00YWT\x00YPT\x00" +
-	"YDT\x00AKDT\x00AKST\x00\nAKST9AKDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x04,2h\x99\x01" +
-	"\x00\x00\x99\x01\x00\x00\x10\x00\x1c\x00America/SantaremUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1e\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xff\x96\xaazH\xff\xff\xff\xff\xb8\x0fW\xf0\xff\xff\xff\xff\xb8\xfdN\xb0\xff\xff\xff\xff\xb9\xf1B" +
-	"@\xff\xff\xff\xff\xbaނ0\xff\xff\xff\xff\xda8\xbc@\xff\xff\xff\xff\xda\xec\b@\xff\xff\xff\xff\xdc\x19\xef\xc0\xff\xff\xff\xffܹg0\xff\xff\xff\xff\xdd\xfb#@\xff\xff\xff\xffޛ\xec0\xff\xff\xff" +
-	"\xff\xdfݨ@\xff\xff\xff\xff\xe0TA0\xff\xff\xff\xff\xf4\x98\r\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf6\xc0r@\xff\xff\xff\xff\xf7\x0e,\xb0\xff\xff\xff\xff\xf8Q:@\xff\xff\xff\xff\xf8\xc7\xd3" +
-	"0\xff\xff\xff\xff\xfa\n\xe0\xc0\xff\xff\xff\xff\xfa\xa9\x06\xb0\xff\xff\xff\xff\xfb\xec\x14@\xff\xff\xff\xff\xfc\x8b\x8b\xb0\x00\x00\x00\x00\x1dɜ@\x00\x00\x00\x00\x1ex\xe5\xb0\x00\x00\x00\x00\x1f\xa0C\xc0\x00\x00\x00" +
-	"\x00 3ݰ\x00\x00\x00\x00!\x81w@\x00\x00\x00\x00\"\vְ\x00\x00\x00\x00H`q@\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\xff" +
-	"\xff̸\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x00\x04LMT\x00-03\x00-04\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe5S\xea" +
-	"&\xb9\x04\x00\x00\xb9\x04\x00\x00\x14\x00\x1c\x00America/Punta_ArenasUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01" +
-	"\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\x00\x00\x00\a\x00\x00\x00\x14\xff\xff\xff\xffi\x87\x1d\xfc\xff\xff\xff\xff\x8f0GE\xff\xff\xff\xff\x9b\\\xe5P" +
-	"\xff\xff\xff\xff\x9f|\xe2\xc5\xff\xff\xff\xff\xa1\x00q\xc0\xff\xff\xff\xff\xb0^w\xc5\xff\xff\xff\xff\xb1w=@\xff\xff\xff\xff\xb2A\x00\xd0\xff\xff\xff\xff\xb3Xp\xc0\xff\xff\xff\xff\xb4\"4P\xff\xff\xff\xff" +
-	"\xb59\xa4@\xff\xff\xff\xff\xb6\x03g\xd0\xff\xff\xff\xff\xb7\x1a\xd7\xc0\xff\xff\xff\xff\xb7\xe4\x9bP\xff\xff\xff\xff\xb8\xfd\\\xc0\xff\xff\xff\xff\xb9\xc7 P\xff\xff\xff\xff\xcc\x1cn@\xff\xff\xff\xff\xccl\xe7\xd0" +
-	"\xff\xff\xff\xff\xd53U\xc0\xff\xff\xff\xff\xd5v\x92@\xff\xff\xff\xff\xfd\xd1<@\xff\xff\xff\xff\xfe\x92\xfa\xb0\xff\xff\xff\xff\xff\xcc\xcd\xc0\x00\x00\x00\x00\x00rܰ\x00\x00\x00\x00\x01uP\xc0\x00\x00\x00\x00" +
-	"\x02@I\xb0\x00\x00\x00\x00\x03U2\xc0\x00\x00\x00\x00\x04 +\xb0\x00\x00\x00\x00\x05>O@\x00\x00\x00\x00\x06\x00\r\xb0\x00\x00\x00\x00\a\v\xbc@\x00\x00\x00\x00\a\xdf\xef\xb0\x00\x00\x00\x00\b\xfe\x13@" +
-	"\x00\x00\x00\x00\t\xbfѰ\x00\x00\x00\x00\n\xdd\xf5@\x00\x00\x00\x00\v\xa8\xee0\x00\x00\x00\x00\f\xbd\xd7@\x00\x00\x00\x00\r\x88\xd00\x00\x00\x00\x00\x0e\x9d\xb9@\x00\x00\x00\x00\x0fh\xb20\x00\x00\x00\x00" +
-	"\x10\x86\xd5\xc0\x00\x00\x00\x00\x11H\x940\x00\x00\x00\x00\x12f\xb7\xc0\x00\x00\x00\x00\x13(v0\x00\x00\x00\x00\x14F\x99\xc0\x00\x00\x00\x00\x15\x11\x92\xb0\x00\x00\x00\x00\x16&{\xc0\x00\x00\x00\x00\x16\xf1t\xb0" +
-	"\x00\x00\x00\x00\x18\x06]\xc0\x00\x00\x00\x00\x18\xd1V\xb0\x00\x00\x00\x00\x19\xe6?\xc0\x00\x00\x00\x00\x1a\xb18\xb0\x00\x00\x00\x00\x1b\xcf\\@\x00\x00\x00\x00\x1c\x91\x1a\xb0\x00\x00\x00\x00\x1d\xaf>@\x00\x00\x00\x00" +
-	"\x1ep\xfc\xb0\x00\x00\x00\x00\x1f\x8f @\x00\x00\x00\x00 \x7f\x030\x00\x00\x00\x00!o\x02@\x00\x00\x00\x00\"9\xfb0\x00\x00\x00\x00#N\xe4@\x00\x00\x00\x00$\x19\xdd0\x00\x00\x00\x00%8\x00\xc0" +
-	"\x00\x00\x00\x00%\xf9\xbf0\x00\x00\x00\x00&\xf2\xf8\xc0\x00\x00\x00\x00'١0\x00\x00\x00\x00(\xf7\xc4\xc0\x00\x00\x00\x00)½\xb0\x00\x00\x00\x00*צ\xc0\x00\x00\x00\x00+\xa2\x9f\xb0\x00\x00\x00\x00" +
-	",\xb7\x88\xc0\x00\x00\x00\x00-\x82\x81\xb0\x00\x00\x00\x00.\x97j\xc0\x00\x00\x00\x00/bc\xb0\x00\x00\x00\x000\x80\x87@\x00\x00\x00\x001BE\xb0\x00\x00\x00\x002`i@\x00\x00\x00\x003=\xd70" +
-	"\x00\x00\x00\x004@K@\x00\x00\x00\x005\vD0\x00\x00\x00\x006\r\xb8@\x00\x00\x00\x007\x06հ\x00\x00\x00\x008\x00\x0f@\x00\x00\x00\x008\xcb\b0\x00\x00\x00\x009\xe9+\xc0\x00\x00\x00\x00" +
-	":\xaa\xea0\x00\x00\x00\x00;\xc9\r\xc0\x00\x00\x00\x00<\x8a\xcc0\x00\x00\x00\x00=\xa8\xef\xc0\x00\x00\x00\x00>j\xae0\x00\x00\x00\x00?\x88\xd1\xc0\x00\x00\x00\x00@Sʰ\x00\x00\x00\x00Ah\xb3\xc0" +
-	"\x00\x00\x00\x00B3\xac\xb0\x00\x00\x00\x00CH\x95\xc0\x00\x00\x00\x00D\x13\x8e\xb0\x00\x00\x00\x00E1\xb2@\x00\x00\x00\x00E\xf3p\xb0\x00\x00\x00\x00G\x11\x94@\x00\x00\x00\x00G\xef\x020\x00\x00\x00\x00" +
-	"H\xf1v@\x00\x00\x00\x00I\xbco0\x00\x00\x00\x00J\xd1X@\x00\x00\x00\x00K\xb8\x00\xb0\x00\x00\x00\x00L\xb1:@\x00\x00\x00\x00M\xc6\a0\x00\x00\x00\x00NP\x82\xc0\x00\x00\x00\x00O\x9c\xae\xb0" +
-	"\x00\x00\x00\x00PB\xd9\xc0\x00\x00\x00\x00Q|\x90\xb0\x00\x00\x00\x00R+\xf6@\x00\x00\x00\x00S\\r\xb0\x00\x00\x00\x00T\v\xd8@\x00\x00\x00\x00W7\xe60\x00\x00\x00\x00W\xaf\xec\xc0\x00\x00\x00\x00" +
-	"XC\x86\xb0\x01\x02\x01\x03\x01\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x03\x02\x03\x02\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03" +
-	"\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x06" +
-	"\xff\xff\xbd\x84\x00\x00\xff\xff\xbd\xbb\x00\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x00\f\xff\xff\xc7\xc0\x01\f\xff\xff\xd5\xd0\x01\x10\xff\xff\xd5\xd0\x00\x10LMT\x00SMT\x00-05\x00-04\x00-0" +
-	"3\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT:\x9a1T\xdf\x01\x00\x00\xdf\x01\x00\x00\x14\x00\x1c\x00America/Scoresbysund" +
-	"UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\"\x00\x00\x00\x05\x00" +
-	"\x00\x00\x10\xff\xff\xff\xff\x9b\x80L\x18\x00\x00\x00\x00\x13Mn@\x00\x00\x00\x00\x144$\xc0\x00\x00\x00\x00\x15#\xf9\xa0\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00" +
-	"\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f" +
-	"|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00" +
-	"\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-" +
-	"\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x01\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" +
-	"\x04\x03\x04\x03\x04\x03\x04\x03\x04\xff\xff\xebh\x00\x00\xff\xff\xe3\xe0\x00\x04\xff\xff\xf1\xf0\x01\b\xff\xff\xf1\xf0\x00\b\x00\x00\x00\x00\x01\fLMT\x00-02\x00-01\x00+00\x00\n<-01" +
-	">1<+00>,M3.5.0/0,M10.5.0/1\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTC\x1a\xec\xee\x02\x05\x00\x00\x02\x05\x00\x00\x10\x00\x1c\x00Ame" +
-	"rica/SantiagoUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00z\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffi\x87\x1d\xc5\xff\xff\xff\xff\x8f0GE\xff\xff\xff\xff\x9b\\\xe5P\xff\xff\xff\xff\x9f|\xe2\xc5\xff\xff\xff\xff\xa1\x00q\xc0\xff\xff\xff\xff" +
-	"\xb0^w\xc5\xff\xff\xff\xff\xb1w=@\xff\xff\xff\xff\xb2A\x00\xd0\xff\xff\xff\xff\xb3Xp\xc0\xff\xff\xff\xff\xb4\"4P\xff\xff\xff\xff\xb59\xa4@\xff\xff\xff\xff\xb6\x03g\xd0\xff\xff\xff\xff\xb7\x1a\xd7\xc0" +
-	"\xff\xff\xff\xff\xb7\xe4\x9bP\xff\xff\xff\xff\xb8\xfd\\\xc0\xff\xff\xff\xff\xb9\xc7 P\xff\xff\xff\xff\xcc\x1cn@\xff\xff\xff\xff\xccl\xe7\xd0\xff\xff\xff\xff\xd3\u070f\xc0\xff\xff\xff\xff\xd4\x1bɰ\xff\xff\xff\xff" +
-	"\xd53U\xc0\xff\xff\xff\xff\xd5v\x92@\xff\xff\xff\xff\xfd\xd1<@\xff\xff\xff\xff\xfe\x92\xfa\xb0\xff\xff\xff\xff\xff\xcc\xcd\xc0\x00\x00\x00\x00\x00rܰ\x00\x00\x00\x00\x01uP\xc0\x00\x00\x00\x00\x02@I\xb0" +
-	"\x00\x00\x00\x00\x03U2\xc0\x00\x00\x00\x00\x04 +\xb0\x00\x00\x00\x00\x05>O@\x00\x00\x00\x00\x06\x00\r\xb0\x00\x00\x00\x00\a\v\xbc@\x00\x00\x00\x00\a\xdf\xef\xb0\x00\x00\x00\x00\b\xfe\x13@\x00\x00\x00\x00" +
-	"\t\xbfѰ\x00\x00\x00\x00\n\xdd\xf5@\x00\x00\x00\x00\v\xa8\xee0\x00\x00\x00\x00\f\xbd\xd7@\x00\x00\x00\x00\r\x88\xd00\x00\x00\x00\x00\x0e\x9d\xb9@\x00\x00\x00\x00\x0fh\xb20\x00\x00\x00\x00\x10\x86\xd5\xc0" +
-	"\x00\x00\x00\x00\x11H\x940\x00\x00\x00\x00\x12f\xb7\xc0\x00\x00\x00\x00\x13(v0\x00\x00\x00\x00\x14F\x99\xc0\x00\x00\x00\x00\x15\x11\x92\xb0\x00\x00\x00\x00\x16&{\xc0\x00\x00\x00\x00\x16\xf1t\xb0\x00\x00\x00\x00" +
-	"\x18\x06]\xc0\x00\x00\x00\x00\x18\xd1V\xb0\x00\x00\x00\x00\x19\xe6?\xc0\x00\x00\x00\x00\x1a\xb18\xb0\x00\x00\x00\x00\x1b\xcf\\@\x00\x00\x00\x00\x1c\x91\x1a\xb0\x00\x00\x00\x00\x1d\xaf>@\x00\x00\x00\x00\x1ep\xfc\xb0" +
-	"\x00\x00\x00\x00\x1f\x8f @\x00\x00\x00\x00 \x7f\x030\x00\x00\x00\x00!o\x02@\x00\x00\x00\x00\"9\xfb0\x00\x00\x00\x00#N\xe4@\x00\x00\x00\x00$\x19\xdd0\x00\x00\x00\x00%8\x00\xc0\x00\x00\x00\x00" +
-	"%\xf9\xbf0\x00\x00\x00\x00&\xf2\xf8\xc0\x00\x00\x00\x00'١0\x00\x00\x00\x00(\xf7\xc4\xc0\x00\x00\x00\x00)½\xb0\x00\x00\x00\x00*צ\xc0\x00\x00\x00\x00+\xa2\x9f\xb0\x00\x00\x00\x00,\xb7\x88\xc0" +
-	"\x00\x00\x00\x00-\x82\x81\xb0\x00\x00\x00\x00.\x97j\xc0\x00\x00\x00\x00/bc\xb0\x00\x00\x00\x000\x80\x87@\x00\x00\x00\x001BE\xb0\x00\x00\x00\x002`i@\x00\x00\x00\x003=\xd70\x00\x00\x00\x00" +
-	"4@K@\x00\x00\x00\x005\vD0\x00\x00\x00\x006\r\xb8@\x00\x00\x00\x007\x06հ\x00\x00\x00\x008\x00\x0f@\x00\x00\x00\x008\xcb\b0\x00\x00\x00\x009\xe9+\xc0\x00\x00\x00\x00:\xaa\xea0" +
-	"\x00\x00\x00\x00;\xc9\r\xc0\x00\x00\x00\x00<\x8a\xcc0\x00\x00\x00\x00=\xa8\xef\xc0\x00\x00\x00\x00>j\xae0\x00\x00\x00\x00?\x88\xd1\xc0\x00\x00\x00\x00@Sʰ\x00\x00\x00\x00Ah\xb3\xc0\x00\x00\x00\x00" +
-	"B3\xac\xb0\x00\x00\x00\x00CH\x95\xc0\x00\x00\x00\x00D\x13\x8e\xb0\x00\x00\x00\x00E1\xb2@\x00\x00\x00\x00E\xf3p\xb0\x00\x00\x00\x00G\x11\x94@\x00\x00\x00\x00G\xef\x020\x00\x00\x00\x00H\xf1v@" +
-	"\x00\x00\x00\x00I\xbco0\x00\x00\x00\x00J\xd1X@\x00\x00\x00\x00K\xb8\x00\xb0\x00\x00\x00\x00L\xb1:@\x00\x00\x00\x00M\xc6\a0\x00\x00\x00\x00NP\x82\xc0\x00\x00\x00\x00O\x9c\xae\xb0\x00\x00\x00\x00" +
-	"PB\xd9\xc0\x00\x00\x00\x00Q|\x90\xb0\x00\x00\x00\x00R+\xf6@\x00\x00\x00\x00S\\r\xb0\x00\x00\x00\x00T\v\xd8@\x00\x00\x00\x00W7\xe60\x00\x00\x00\x00W\xaf\xec\xc0\x00\x00\x00\x00Y\x17\xc80" +
-	"\x00\x00\x00\x00Y\x8f\xce\xc0\x00\x00\x00\x00Z\xf7\xaa0\x00\x00\x00\x00[o\xb0\xc0\x00\x00\x00\x00\\\xa9g\xb0\x01\x02\x01\x03\x01\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x03\x02\x03\x05\x03\x02\x03\x05\x03\x05\x03\x05\x03" +
-	"\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03" +
-	"\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\xff\xff\xbd\xbb\x00\x00\xff\xff\xbd\xbb\x00\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x00\f\xff\xff" +
-	"\xc7\xc0\x01\f\xff\xff\xd5\xd0\x01\x10LMT\x00SMT\x00-05\x00-04\x00-03\x00\n<-04>4<-03>,M9.1.6/24,M4.1.6/" +
-	"24\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x01\x05\xf3\x89\xb5\x00\x00\x00\xb5\x00\x00\x00\x0e\x00\x1c\x00America/GuyanaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94b" +
-	"ux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00" +
-	"\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x92\x1d\x0f\x87\xff\xff" +
-	"\xff\xff\x98\xd9{@\x00\x00\x00\x00\n\x7f\x05\xbc\x00\x00\x00\x00)\xd5@\xc0\x01\x02\x03\x01\xff\xff\xc9y\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xcbD\x00\b\xff\xff\xd5\xd0\x00\x0eLMT\x00-04\x00-0" +
-	"345\x00-03\x00\n<-04>4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTԾ\xe7#\x95\x00\x00\x00\x95\x00\x00\x00\x15\x00\x1c\x00America/Coral_" +
-	"HarbourUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xffi\x87&\x10\xff\xff\xff\xff\x8b\xf4a\xe8\x01\x02\xff\xff\xb5p\x00\x00\xff\xff\xb5\x18\x00\x04\xff\xff\xb9\xb0\x00\bLMT\x00CMT\x00EST\x00\nE" +
-	"ST5\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTg\xf5K\x89\xa2\x01\x00\x00\xa2\x01\x00\x00\x12\x00\x1c\x00America/Rio_BrancoUT\t\x00\x03\xdd\xfc\x94" +
-	"b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" +
-	"\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xff\x96" +
-	"\xaa\x86\x90\xff\xff\xff\xff\xb8\x0ff\x00\xff\xff\xff\xff\xb8\xfd\\\xc0\xff\xff\xff\xff\xb9\xf1PP\xff\xff\xff\xff\xbaސ@\xff\xff\xff\xff\xda8\xcaP\xff\xff\xff\xff\xda\xec\x16P\xff\xff\xff\xff\xdc\x19\xfd\xd0\xff" +
-	"\xff\xff\xffܹu@\xff\xff\xff\xff\xdd\xfb1P\xff\xff\xff\xffޛ\xfa@\xff\xff\xff\xff\xdfݶP\xff\xff\xff\xff\xe0TO@\xff\xff\xff\xff\xf4\x98\x1b\xd0\xff\xff\xff\xff\xf5\x05z@\xff\xff\xff\xff\xf6" +
-	"\xc0\x80P\xff\xff\xff\xff\xf7\x0e:\xc0\xff\xff\xff\xff\xf8QHP\xff\xff\xff\xff\xf8\xc7\xe1@\xff\xff\xff\xff\xfa\n\xee\xd0\xff\xff\xff\xff\xfa\xa9\x14\xc0\xff\xff\xff\xff\xfb\xec\"P\xff\xff\xff\xff\xfc\x8b\x99\xc0\x00" +
-	"\x00\x00\x00\x1dɪP\x00\x00\x00\x00\x1ex\xf3\xc0\x00\x00\x00\x00\x1f\xa0Q\xd0\x00\x00\x00\x00 3\xeb\xc0\x00\x00\x00\x00!\x81\x85P\x00\x00\x00\x00\"\v\xe4\xc0\x00\x00\x00\x00H`\x7fP\x00\x00\x00\x00R" +
-	"\x7f\x04\xc0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\xff\xff\xc0p\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x00\x04LM" +
-	"T\x00-04\x00-05\x00\n<-05>5\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTg\xf5K\x89\xa2\x01\x00\x00\xa2\x01\x00\x00\x12\x00\x1c\x00America/Port" +
-	"o_AcreUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x1f\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xff\x96\xaa\x86\x90\xff\xff\xff\xff\xb8\x0ff\x00\xff\xff\xff\xff\xb8\xfd\\\xc0\xff\xff\xff\xff\xb9\xf1PP\xff\xff\xff\xff\xbaސ@\xff\xff\xff\xff\xda8\xcaP\xff\xff\xff" +
-	"\xff\xda\xec\x16P\xff\xff\xff\xff\xdc\x19\xfd\xd0\xff\xff\xff\xffܹu@\xff\xff\xff\xff\xdd\xfb1P\xff\xff\xff\xffޛ\xfa@\xff\xff\xff\xff\xdfݶP\xff\xff\xff\xff\xe0TO@\xff\xff\xff\xff\xf4\x98\x1b" +
-	"\xd0\xff\xff\xff\xff\xf5\x05z@\xff\xff\xff\xff\xf6\xc0\x80P\xff\xff\xff\xff\xf7\x0e:\xc0\xff\xff\xff\xff\xf8QHP\xff\xff\xff\xff\xf8\xc7\xe1@\xff\xff\xff\xff\xfa\n\xee\xd0\xff\xff\xff\xff\xfa\xa9\x14\xc0\xff\xff\xff" +
-	"\xff\xfb\xec\"P\xff\xff\xff\xff\xfc\x8b\x99\xc0\x00\x00\x00\x00\x1dɪP\x00\x00\x00\x00\x1ex\xf3\xc0\x00\x00\x00\x00\x1f\xa0Q\xd0\x00\x00\x00\x00 3\xeb\xc0\x00\x00\x00\x00!\x81\x85P\x00\x00\x00\x00\"\v\xe4" +
-	"\xc0\x00\x00\x00\x00H`\x7fP\x00\x00\x00\x00R\x7f\x04\xc0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\xff\xff\xc0p\x00\x00\xff\xff\xc7\xc0\x01\x04" +
-	"\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x00\x04LMT\x00-04\x00-05\x00\n<-05>5\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTp\x1b\xceRC\x03\x00\x00C\x03\x00\x00\x0f\x00" +
-	"\x1c\x00America/NipigonUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00J\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xffr\xee\x81@\xff\xff\xff\xff\x9e\xb8\x93p\xff\xff\xff\xff\x9f\xba\xeb`\xff\xff\xff\xff\xc8\xf8IP\xff\xff\xff\xffˈ\xf0p" +
-	"\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\x00\x00\x00\x00\b \xc1p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\n\x00\xa3p\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00" +
-	"\f٢\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0" +
-	"\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x00\x00\x00\x00" +
-	"\x1a\xf2\np\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`" +
-	"\x00\x00\x00\x00\"U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00" +
-	")\nU\xe0\x00\x00\x00\x00)ޥp\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp" +
-	"\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x00" +
-	"7\a\r\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0" +
-	"\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00" +
-	"EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xad@\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\f\xff\xff\xc7\xc0\x01\x10LMT\x00" +
-	"EDT\x00EST\x00EWT\x00EPT\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT{\a\a\xdc\xca\x03" +
-	"\x00\x00\xca\x03\x00\x00\x10\x00\x1c\x00America/EdmontonUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\x88\xde\xce\xe0\xff\xff\xff\xff\x9e\xb8\xaf\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x98\x91" +
-	"\x90\xff\xff\xff\xff\xa0҅\x80\xff\xff\xff\xff\xa2\x8a\xe8\x90\xff\xff\xff\xff\xa3\x84\x06\x00\xff\xff\xff\xff\xa4jʐ\xff\xff\xff\xff\xa55À\xff\xff\xff\xff\xa6S\xe7\x10\xff\xff\xff\xff\xa7\x15\xa5\x80\xff\xff\xff" +
-	"\xff\xa83\xc9\x10\xff\xff\xff\xff\xa8\xfe\xc2\x00\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xd5U\xe3\x10\xff\xff\xff\xff\xd6 \xdc\x00\x00\x00\x00\x00\x04a\x19" +
-	"\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\b ݐ\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\n\x00\xbf\x90\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00" +
-	"\x00\vࡐ\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye" +
-	"\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00" +
-	"\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x1d" +
-	"\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00" +
-	"\x00'\xfeߐ\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R" +
-	"\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00" +
-	"\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xb0\n" +
-	"\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00" +
-	"\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\x95\xa0\x00\x00\xff\xff\xab\xa0" +
-	"\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10LMT\x00MDT\x00MST\x00MWT\x00MPT\x00\nMST7MDT,M3.2.0,M11." +
-	"1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTq\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x15\x00\x1c\x00America/Port_of_SpainUT\t\x00\x03" +
-	"\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"DT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x00\x00America/Domi" +
+	"nicaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2" +
+	"#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4" +
+	"\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{\a\a\xdc\xca\x03\x00\x00\xca\x03\x00\x00\x10\x00\x00\x00America/EdmontonTZif2\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\x88\xde\xce\xe0\xff\xff\xff\xff\x9e\xb8\xaf\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x98\x91\x90\xff\xff\xff\xff\xa0\xd2" +
+	"\x85\x80\xff\xff\xff\xff\xa2\x8a\xe8\x90\xff\xff\xff\xff\xa3\x84\x06\x00\xff\xff\xff\xff\xa4jʐ\xff\xff\xff\xff\xa55À\xff\xff\xff\xff\xa6S\xe7\x10\xff\xff\xff\xff\xa7\x15\xa5\x80\xff\xff\xff\xff\xa83\xc9\x10\xff\xff" +
+	"\xff\xff\xa8\xfe\xc2\x00\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xd5U\xe3\x10\xff\xff\xff\xff\xd6 \xdc\x00\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P" +
+	"\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\b ݐ\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\n\x00\xbf\x90\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\vࡐ\x00\x00" +
+	"\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13i" +
+	"d\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00" +
+	"\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81" +
+	"\xaf\x80\x00\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeߐ\x00\x00" +
+	"\x00\x00)\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~" +
+	"g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00" +
+	"\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb" +
+	"\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00" +
+	"\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\x95\xa0\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00" +
+	"\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10LMT\x00MDT\x00MST\x00MWT\x00MPT\x00\nMST7MDT,M3.2.0,M11.1.0\nPK\x03" +
+	"\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00s\xb0\xeau\xb4\x01\x00\x00\xb4\x01\x00\x00\x10\x00\x00\x00America/EirunepeTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00!\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xff\x96\xaa\x88\x80\xff\xff\xff\xff\xb8\x0ff\x00\xff\xff\xff\xff\xb8\xfd\\\xc0\xff\xff\xff\xff\xb9\xf1PP\xff\xff\xff\xff\xbaސ@\xff\xff" +
+	"\xff\xff\xda8\xcaP\xff\xff\xff\xff\xda\xec\x16P\xff\xff\xff\xff\xdc\x19\xfd\xd0\xff\xff\xff\xffܹu@\xff\xff\xff\xff\xdd\xfb1P\xff\xff\xff\xffޛ\xfa@\xff\xff\xff\xff\xdfݶP\xff\xff\xff\xff\xe0T" +
+	"O@\xff\xff\xff\xff\xf4\x98\x1b\xd0\xff\xff\xff\xff\xf5\x05z@\xff\xff\xff\xff\xf6\xc0\x80P\xff\xff\xff\xff\xf7\x0e:\xc0\xff\xff\xff\xff\xf8QHP\xff\xff\xff\xff\xf8\xc7\xe1@\xff\xff\xff\xff\xfa\n\xee\xd0\xff\xff" +
+	"\xff\xff\xfa\xa9\x14\xc0\xff\xff\xff\xff\xfb\xec\"P\xff\xff\xff\xff\xfc\x8b\x99\xc0\x00\x00\x00\x00\x1dɪP\x00\x00\x00\x00\x1ex\xf3\xc0\x00\x00\x00\x00\x1f\xa0Q\xd0\x00\x00\x00\x00 3\xeb\xc0\x00\x00\x00\x00!\x81" +
+	"\x85P\x00\x00\x00\x00\"\v\xe4\xc0\x00\x00\x00\x00,\xc0\xd1P\x00\x00\x00\x00-f\xe0@\x00\x00\x00\x00H`\x7fP\x00\x00\x00\x00R\x7f\x04\xc0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\xff\xff\xbe\x80\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x00\x04LMT\x00-04\x00-05\x00\n<-05>5\nP" +
+	"K\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xea$\xc1\xbf\xb0\x00\x00\x00\xb0\x00\x00\x00\x13\x00\x00\x00America/El_SalvadorTZif2\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\xa3զ \x00\x00\x00\x00 \x9a\xdc\xe0\x00\x00\x00\x00!\\\x9bP\x00\x00\x00\x00\"z\xbe\xe0\x00\x00\x00\x00#" +
+	"<}P\x02\x01\x02\x01\x02\xff\xff\xac`\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\bLMT\x00CDT\x00CST\x00\nCST6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb9B" +
+	"$\x90\x01\x04\x00\x00\x01\x04\x00\x00\x10\x00\x00\x00America/EnsenadaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00^\x00\x00\x00" +
+	"\x06\x00\x00\x00\x18\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xa9yOp\xff\xff\xff\xff\xaf\xf2|\xf0\xff\xff\xff\xff\xb6fdp\xff\xff\xff\xff\xb7\x1b\x10\x00\xff\xff\xff\xff\xb8\n\xf2\xf0\xff\xff\xff\xff\xcb\xea\x8d" +
+	"\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xffҙ\xbap\xff\xff\xff\xff\xd7\x1bY\x00\xff\xff\xff\xffؑ\xb4\xf0\xff\xff\xff\xff\xe2~K\x90\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4^-\x90\xff\xff\xff" +
+	"\xff\xe5)4\x90\xff\xff\xff\xff\xe6GJ\x10\xff\xff\xff\xff\xe7\x12Q\x10\xff\xff\xff\xff\xe8',\x10\xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff\xff\xea\a\x0e\x10\xff\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff\xff\xeb\xe6\xf0" +
+	"\x10\xff\xff\xff\xff\xec\xb1\xf7\x10\xff\xff\xff\xff\xed\xc6\xd2\x10\xff\xff\xff\xff\xee\x91\xd9\x10\x00\x00\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00" +
+	"\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697" +
+	"\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00" +
+	"\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1ې\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\"V\r \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef" +
+	" \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\n\x80\x10\x00\x00\x00\x00)\xdeϠ\x00\x00\x00\x00*\xeab\x10\x00\x00\x00" +
+	"\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s$" +
+	"\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\a8 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00" +
+	"\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@o\xdc" +
+	"\xa0\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00F\x0f\x82\xa0\x00\x00\x00\x00G$O\x90\x00\x00\x00" +
+	"\x00G\xf8\x9f \x00\x00\x00\x00I\x041\x90\x00\x00\x00\x00I\u0601 \x00\x00\x00\x00J\xe4\x13\x90\x00\x00\x00\x00K\x9c\xb3\xa0\x01\x02\x01\x02\x03\x02\x04\x05\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\x92L\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\x8f\x80\x00\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10\xff\xff\x9d\x90\x01\x14LMT\x00MST\x00PST\x00P" +
+	"DT\x00PWT\x00PPT\x00\nPST8PDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6@\rm\xa8\x05\x00\x00\xa8\x05\x00" +
+	"\x00\x13\x00\x00\x00America/Fort_NelsonTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8f\x00\x00\x00\x06\x00\x00\x00\x18\xff" +
+	"\xff\xff\xff^=v\x87\xff\xff\xff\xff\x9e\xb8\xbd\xa0\xff\xff\xff\xff\x9f\xbb\x15\x90\xff\xff\xff\xffˉ\x1a\xa0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a&\x10\xff\xff\xff\xff\xd5U\xf1 \xff\xff\xff\xff\xd6" +
+	" \xea\x10\xff\xff\xff\xff\xd75\xd3 \xff\xff\xff\xff\xd8\x00\xcc\x10\xff\xff\xff\xff\xd9\x15\xb5 \xff\xff\xff\xff\xd9\xe0\xae\x10\xff\xff\xff\xff\xda\xfeѠ\xff\xff\xff\xff\xdb\xc0\x90\x10\xff\xff\xff\xff\xdc\u07b3\xa0\xff" +
+	"\xff\xff\xffݩ\xac\x90\xff\xff\xff\xff\u07be\x95\xa0\xff\xff\xff\xff߉\x8e\x90\xff\xff\xff\xff\xe0\x9ew\xa0\xff\xff\xff\xff\xe1ip\x90\xff\xff\xff\xff\xe2~Y\xa0\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4" +
+	"^;\xa0\xff\xff\xff\xff\xe5)4\x90\xff\xff\xff\xff\xe6GX \xff\xff\xff\xff\xe7\x12Q\x10\xff\xff\xff\xff\xe8': \xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff\xff\xea\a\x1c \xff\xff\xff\xff\xea\xd2\x15\x10\xff" +
+	"\xff\xff\xff\xeb\xe6\xfe \xff\xff\xff\xff\xec\xb1\xf7\x10\xff\xff\xff\xff\xed\xc6\xe0 \xff\xff\xff\xff\xee\x91\xd9\x10\xff\xff\xff\xff\xef\xaf\xfc\xa0\xff\xff\xff\xff\xf0q\xbb\x10\xff\xff\xff\xff\xf1\x8fޠ\xff\xff\xff\xff\xf2" +
+	"\x7f\xc1\x90\xff\xff\xff\xff\xf3o\xc0\xa0\xff\xff\xff\xff\xf4_\xa3\x90\xff\xff\xff\xff\xf5O\xa2\xa0\xff\xff\xff\xff\xf6?\x85\x90\xff\xff\xff\xff\xf7/\x84\xa0\xff\xff\xff\xff\xf8(\xa2\x10\xff\xff\xff\xff\xf9\x0ff\xa0\xff" +
+	"\xff\xff\xff\xfa\b\x84\x10\xff\xff\xff\xff\xfa\xf8\x83 \xff\xff\xff\xff\xfb\xe8f\x10\xff\xff\xff\xff\xfc\xd8e \xff\xff\xff\xff\xfd\xc8H\x10\xff\xff\xff\xff\xfe\xb8G \xff\xff\xff\xff\xff\xa8*\x10\x00\x00\x00\x00\x00" +
+	"\x98) \x00\x00\x00\x00\x01\x88\f\x10\x00\x00\x00\x00\x02x\v \x00\x00\x00\x00\x03q(\x90\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05Q\n\x90\x00\x00\x00\x00\x06A\t\xa0\x00\x00\x00\x00\a0\xec\x90\x00" +
+	"\x00\x00\x00\b \xeb\xa0\x00\x00\x00\x00\t\x10ΐ\x00\x00\x00\x00\n\x00͠\x00\x00\x00\x00\n\xf0\xb0\x90\x00\x00\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00\x00\x00\x0e" +
+	"\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00" +
+	"\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c" +
+	"\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1ې\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\"V\r \x00\x00\x00\x00#j\xda\x10\x00" +
+	"\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\n\x80\x10\x00\x00\x00\x00)\xdeϠ\x00\x00\x00\x00*" +
+	"\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00" +
+	"\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\a8 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008" +
+	"\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00" +
+	"\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E\xf3\xd3 \x00\x00\x00\x00G" +
+	"-\x8a\x10\x00\x00\x00\x00Gӵ \x00\x00\x00\x00I\rl\x10\x00\x00\x00\x00I\xb3\x97 \x00\x00\x00\x00J\xedN\x10\x00\x00\x00\x00K\x9c\xb3\xa0\x00\x00\x00\x00L\xd6j\x90\x00\x00\x00\x00M|\x95\xa0\x00" +
+	"\x00\x00\x00N\xb6L\x90\x00\x00\x00\x00O\\w\xa0\x00\x00\x00\x00P\x96.\x90\x00\x00\x00\x00Q<Y\xa0\x00\x00\x00\x00Rv\x10\x90\x00\x00\x00\x00S\x1c;\xa0\x00\x00\x00\x00TU\xf2\x90\x00\x00\x00\x00T" +
+	"\xfc\x1d\xa0\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\xff\xff\x8c\xf9\x00\x00\xff\xff\x9d\x90\x01\x04\xff\xff\x8f\x80\x00\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10\xff\xff\x9d\x90" +
+	"\x00\x14LMT\x00PDT\x00PST\x00PWT\x00PPT\x00MST\x00\nMST7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\xb6{\xc9\x13\x02\x00\x00\x13\x02\x00\x00\x12\x00" +
+	"\x00\x00America/Fort_WayneTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" +
+	"\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&\x00\x00\x00\a\x00\x00\x00\x1c\xff\xff\xff\xff^" +
+	"\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xcaW\"\x80\xff\xff\xff\xff\xca\xd8Gp\xff\xff\xff\xffˈ\xfe\x80\xff" +
+	"\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd3u\xf3\x00\xff\xff\xff\xff\xd4@\xeb\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8" +
+	"\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90p\xff\xff\xff\xff\u07bey\x80\xff" +
+	"\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea" +
+	"\a\x00\x00\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02" +
+	"\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x02\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xaf:\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01" +
+	"\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00EDT\x00\nEST5EDT,M3.2" +
+	".0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x11Z\xde\xe4\x01\x00\x00\xe4\x01\x00\x00\x11\x00\x00\x00America/FortalezaTZ" +
+	"if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaak\x18\xff\xff\xff\xff\xb8\x0fI\xe0\xff\xff\xff\xff\xb8\xfd@\xa0\xff\xff\xff" +
+	"\xff\xb9\xf140\xff\xff\xff\xff\xba\xdet \xff\xff\xff\xff\xda8\xae0\xff\xff\xff\xff\xda\xeb\xfa0\xff\xff\xff\xff\xdc\x19\xe1\xb0\xff\xff\xff\xffܹY \xff\xff\xff\xff\xdd\xfb\x150\xff\xff\xff\xffޛ\xde" +
+	" \xff\xff\xff\xff\xdfݚ0\xff\xff\xff\xff\xe0T3 \xff\xff\xff\xff\xf4\x97\xff\xb0\xff\xff\xff\xff\xf5\x05^ \xff\xff\xff\xff\xf6\xc0d0\xff\xff\xff\xff\xf7\x0e\x1e\xa0\xff\xff\xff\xff\xf8Q,0\xff\xff\xff" +
+	"\xff\xf8\xc7\xc5 \xff\xff\xff\xff\xfa\nҰ\xff\xff\xff\xff\xfa\xa8\xf8\xa0\xff\xff\xff\xff\xfb\xec\x060\xff\xff\xff\xff\xfc\x8b}\xa0\x00\x00\x00\x00\x1dɎ0\x00\x00\x00\x00\x1exנ\x00\x00\x00\x00\x1f\xa05" +
+	"\xb0\x00\x00\x00\x00 3Ϡ\x00\x00\x00\x00!\x81i0\x00\x00\x00\x00\"\vȠ\x00\x00\x00\x00#X\x10\xb0\x00\x00\x00\x00#\xe2p \x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xd4\xc7 \x00\x00\x00" +
+	"\x007\xf6ư\x00\x00\x00\x008\xb8\x85 \x00\x00\x00\x009\xdf\xe30\x00\x00\x00\x009\xf2J \x00\x00\x00\x00;\xc8\xff\xb0\x00\x00\x00\x00<o\x0e\xa0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xdb\xe8\x00\x00\xff\xff\xe3\xe0\x01\x04\xff\xff\xd5\xd0\x00\bLMT\x00-02\x00-03\x00\n<-03>" +
+	"3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00M\x94\xc7Kp\x03\x00\x00p\x03\x00\x00\x11\x00\x00\x00America/Glace_BayTZif2\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00O\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\x80\xf1\xa84\xff\xff\xff\xff\x9e\xb8\x85`\xff\xff\xff\xff\x9f\xba\xddP\xff\xff\xff\xffˈ\xe2`\xff\xff\xff\xff" +
+	"\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\xff\xff\xff\xff\xe0\x9e?`\xff\xff\xff\xff\xe1i8P\x00\x00\x00\x00\x04`\xef`\x00\x00\x00\x00\x05P\xd2P\x00\x00\x00\x00\x06@\xd1`\x00\x00\x00\x00\a0\xb4P" +
+	"\x00\x00\x00\x00\b \xb3`\x00\x00\x00\x00\t\x10\x96P\x00\x00\x00\x00\n\x00\x95`\x00\x00\x00\x00\n\xf0xP\x00\x00\x00\x00\v\xe0w`\x00\x00\x00\x00\fٔ\xd0\x00\x00\x00\x00\r\xc0Y`\x00\x00\x00\x00" +
+	"\x0e\xb9v\xd0\x00\x00\x00\x00\x0f\xa9u\xe0\x00\x00\x00\x00\x10\x99X\xd0\x00\x00\x00\x00\x11\x89W\xe0\x00\x00\x00\x00\x12y:\xd0\x00\x00\x00\x00\x13i9\xe0\x00\x00\x00\x00\x14Y\x1c\xd0\x00\x00\x00\x00\x15I\x1b\xe0" +
+	"\x00\x00\x00\x00\x168\xfe\xd0\x00\x00\x00\x00\x17(\xfd\xe0\x00\x00\x00\x00\x18\"\x1bP\x00\x00\x00\x00\x19\b\xdf\xe0\x00\x00\x00\x00\x1a\x01\xfdP\x00\x00\x00\x00\x1a\xf1\xfc`\x00\x00\x00\x00\x1b\xe1\xdfP\x00\x00\x00\x00" +
+	"\x1c\xd1\xde`\x00\x00\x00\x00\x1d\xc1\xc1P\x00\x00\x00\x00\x1e\xb1\xc0`\x00\x00\x00\x00\x1f\xa1\xa3P\x00\x00\x00\x00 u\xf2\xe0\x00\x00\x00\x00!\x81\x85P\x00\x00\x00\x00\"U\xd4\xe0\x00\x00\x00\x00#j\xa1\xd0" +
+	"\x00\x00\x00\x00$5\xb6\xe0\x00\x00\x00\x00%J\x83\xd0\x00\x00\x00\x00&\x15\x98\xe0\x00\x00\x00\x00'*e\xd0\x00\x00\x00\x00'\xfe\xb5`\x00\x00\x00\x00)\nG\xd0\x00\x00\x00\x00)ޗ`\x00\x00\x00\x00" +
+	"*\xea)\xd0\x00\x00\x00\x00+\xbey`\x00\x00\x00\x00,\xd3FP\x00\x00\x00\x00-\x9e[`\x00\x00\x00\x00.\xb3(P\x00\x00\x00\x00/~=`\x00\x00\x00\x000\x93\nP\x00\x00\x00\x001gY\xe0" +
+	"\x00\x00\x00\x002r\xecP\x00\x00\x00\x003G;\xe0\x00\x00\x00\x004R\xceP\x00\x00\x00\x005'\x1d\xe0\x00\x00\x00\x0062\xb0P\x00\x00\x00\x007\x06\xff\xe0\x00\x00\x00\x008\x1b\xcc\xd0\x00\x00\x00\x00" +
+	"8\xe6\xe1\xe0\x00\x00\x00\x009\xfb\xae\xd0\x00\x00\x00\x00:\xc6\xc3\xe0\x00\x00\x00\x00;ې\xd0\x00\x00\x00\x00<\xaf\xe0`\x00\x00\x00\x00=\xbbr\xd0\x00\x00\x00\x00>\x8f\xc2`\x00\x00\x00\x00?\x9bT\xd0" +
+	"\x00\x00\x00\x00@o\xa4`\x00\x00\x00\x00A\x84qP\x00\x00\x00\x00BO\x86`\x00\x00\x00\x00CdSP\x00\x00\x00\x00D/h`\x00\x00\x00\x00ED5P\x00\x00\x00\x00E\xf3\x9a\xe0\x02\x01\x02\x03" +
+	"\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xc7\xcc\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xd5\xd0\x01\x10LMT\x00ADT\x00AST\x00AWT" +
+	"\x00APT\x00\nAST4ADT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\xbc\xc9I\xa3\x03\x00\x00\xa3\x03\x00\x00\x0f\x00\x00\x00A" +
+	"merica/GodthabTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00" +
+	"\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xff\x9b\x80h\x00\x00\x00\x00" +
+	"\x00\x13M|P\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ" +
+	"\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00" +
+	"\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54" +
+	"\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00" +
+	"\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x00\x00\x00\x002r\xb4\x10\x00\x00\x00\x003=\xbb\x10\x00\x00\x00\x004R\x96\x10\x00\x00\x00\x005\x1d\x9d\x10\x00\x00\x00\x0062x" +
+	"\x10\x00\x00\x00\x006\xfd\x7f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x008\xdda\x10\x00\x00\x00\x009\xfbv\x90\x00\x00\x00\x00:\xbdC\x10\x00\x00\x00\x00;\xdbX\x90\x00\x00\x00\x00<\xa6_\x90\x00\x00\x00" +
+	"\x00=\xbb:\x90\x00\x00\x00\x00>\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7" +
+	"\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00" +
+	"\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle" +
+	"\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00" +
+	"\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\x7f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5" +
+	"\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x03\xff\xffπ\x00\x00\xff\xff\xd5\xd0\x00\x04\xff\xff\xe3\xe0\x01\b\xff\xff\xe3\xe0\x00\bLMT\x00-03\x00-02\x00\n<-02>2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d" +
+	"\xf7\a ,\x06\x00\x00,\x06\x00\x00\x11\x00\x00\x00America/Goose_BayTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x98\x00" +
+	"\x00\x00\n\x00\x00\x00!\xff\xff\xff\xff^=<$\xff\xff\xff\xff\x9e\xb8~\x8c\xff\xff\xff\xff\x9f\xba\xd6|\xff\xff\xff\xff\xbe\x9eMl\xff\xff\xff\xff\xc0\xb818\xff\xff\xff\xff\xc1y\xef\xa8\xff\xff\xff\xff\xc2" +
+	"\x98\x138\xff\xff\xff\xff\xc3YѨ\xff\xff\xff\xff\xc4w\xf58\xff\xff\xff\xff\xc59\xb3\xa8\xff\xff\xff\xff\xc6a\x11\xb8\xff\xff\xff\xff\xc7\x19\x95\xa8\xff\xff\xff\xff\xc8@\xf3\xb8\xff\xff\xff\xff\xc9\x02\xb2(\xff" +
+	"\xff\xff\xff\xca ո\xff\xff\xff\xff\xca\xe2\x94(\xff\xff\xff\xff\xcc\x00\xb7\xb8\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xe6\xc8\xff\xff\xff\xffӈD\xd8\xff\xff\xff\xff\xd4J\x03H\xff\xff\xff\xff\xd5" +
+	"h&\xd8\xff\xff\xff\xff\xd6)\xe5H\xff\xff\xff\xff\xd7H\b\xd8\xff\xff\xff\xff\xd8\t\xc7H\xff\xff\xff\xff\xd9'\xea\xd8\xff\xff\xff\xff\xd9\xe9\xa9H\xff\xff\xff\xff\xdb\x11\aX\xff\xff\xff\xff\xdb\xd2\xc5\xc8\xff" +
+	"\xff\xff\xff\xdc\xdetX\xff\xff\xff\xffݩmH\xff\xff\xff\xff\u07beVX\xff\xff\xff\xff߉OH\xff\xff\xff\xff\xe0\x9e8X\xff\xff\xff\xff\xe1i1H\xff\xff\xff\xff\xe2~\x1aX\xff\xff\xff\xff\xe3" +
+	"I\x13H\xff\xff\xff\xff\xe4]\xfcX\xff\xff\xff\xff\xe5(\xf5H\xff\xff\xff\xff\xe6G\x18\xd8\xff\xff\xff\xff\xe7\x12\x11\xc8\xff\xff\xff\xff\xe8&\xfa\xd8\xff\xff\xff\xff\xe8\xf1\xf3\xc8\xff\xff\xff\xff\xea\x06\xdc\xd8\xff" +
+	"\xff\xff\xff\xea\xd1\xd5\xc8\xff\xff\xff\xff\xeb\xe6\xbe\xd8\xff\xff\xff\xff챷\xc8\xff\xff\xff\xff\xedƠ\xd8\xff\xff\xff\xff\ueffeH\xff\xff\xff\xffﯽX\xff\xff\xff\xff\xf0\x9f\xa0H\xff\xff\xff\xff\xf1" +
+	"\x8f\x9fX\xff\xff\xff\xff\xf2\x7f\x82H\xff\xff\xff\xff\xf3o\x81X\xff\xff\xff\xff\xf4_dH\xff\xff\xff\xff\xf5OcX\xff\xff\xff\xff\xf6?FH\xff\xff\xff\xff\xf7/EX\xff\xff\xff\xff\xf8(b\xc8\xff" +
+	"\xff\xff\xff\xf8\xdakX\xff\xff\xff\xff\xf9\x0f.`\xff\xff\xff\xff\xfa\bK\xd0\xff\xff\xff\xff\xfa\xf8J\xe0\xff\xff\xff\xff\xfb\xe8-\xd0\xff\xff\xff\xff\xfc\xd8,\xe0\xff\xff\xff\xff\xfd\xc8\x0f\xd0\xff\xff\xff\xff\xfe" +
+	"\xb8\x0e\xe0\xff\xff\xff\xff\xff\xa7\xf1\xd0\x00\x00\x00\x00\x00\x97\xf0\xe0\x00\x00\x00\x00\x01\x87\xd3\xd0\x00\x00\x00\x00\x02w\xd2\xe0\x00\x00\x00\x00\x03p\xf0P\x00\x00\x00\x00\x04`\xef`\x00\x00\x00\x00\x05P\xd2P\x00" +
+	"\x00\x00\x00\x06@\xd1`\x00\x00\x00\x00\a0\xb4P\x00\x00\x00\x00\b \xb3`\x00\x00\x00\x00\t\x10\x96P\x00\x00\x00\x00\n\x00\x95`\x00\x00\x00\x00\n\xf0xP\x00\x00\x00\x00\v\xe0w`\x00\x00\x00\x00\f" +
+	"ٔ\xd0\x00\x00\x00\x00\r\xc0Y`\x00\x00\x00\x00\x0e\xb9v\xd0\x00\x00\x00\x00\x0f\xa9u\xe0\x00\x00\x00\x00\x10\x99X\xd0\x00\x00\x00\x00\x11\x89W\xe0\x00\x00\x00\x00\x12y:\xd0\x00\x00\x00\x00\x13i9\xe0\x00" +
+	"\x00\x00\x00\x14Y\x1c\xd0\x00\x00\x00\x00\x15I\x1b\xe0\x00\x00\x00\x00\x168\xfe\xd0\x00\x00\x00\x00\x17(\xfd\xe0\x00\x00\x00\x00\x18\"\x1bP\x00\x00\x00\x00\x19\b\xdf\xe0\x00\x00\x00\x00\x1a\x01\xfdP\x00\x00\x00\x00\x1a" +
+	"\xf1\xfc`\x00\x00\x00\x00\x1b\xe1\xdfP\x00\x00\x00\x00\x1c\xd1\xde`\x00\x00\x00\x00\x1d\xc1\xc1P\x00\x00\x00\x00\x1e\xb1\xc0`\x00\x00\x00\x00\x1f\xa1\xa3P\x00\x00\x00\x00 u\xd6\xfc\x00\x00\x00\x00!\x81il\x00" +
+	"\x00\x00\x00\"U\xb8\xfc\x00\x00\x00\x00#jw\xdc\x00\x00\x00\x00$5\x9a\xfc\x00\x00\x00\x00%Jg\xec\x00\x00\x00\x00&\x15|\xfc\x00\x00\x00\x00'*I\xec\x00\x00\x00\x00'\xfe\x99|\x00\x00\x00\x00)" +
+	"\n+\xec\x00\x00\x00\x00)\xde{|\x00\x00\x00\x00*\xea\r\xec\x00\x00\x00\x00+\xbe]|\x00\x00\x00\x00,\xd3*l\x00\x00\x00\x00-\x9e?|\x00\x00\x00\x00.\xb3\fl\x00\x00\x00\x00/~!|\x00" +
+	"\x00\x00\x000\x92\xeel\x00\x00\x00\x001g=\xfc\x00\x00\x00\x002r\xd0l\x00\x00\x00\x003G\x1f\xfc\x00\x00\x00\x004R\xb2l\x00\x00\x00\x005'\x01\xfc\x00\x00\x00\x0062\x94l\x00\x00\x00\x007" +
+	"\x06\xe3\xfc\x00\x00\x00\x008\x1b\xb0\xec\x00\x00\x00\x008\xe6\xc5\xfc\x00\x00\x00\x009\xfb\x92\xec\x00\x00\x00\x00:Ƨ\xfc\x00\x00\x00\x00;\xdbt\xec\x00\x00\x00\x00<\xaf\xc4|\x00\x00\x00\x00=\xbbV\xec\x00" +
+	"\x00\x00\x00>\x8f\xa6|\x00\x00\x00\x00?\x9b8\xec\x00\x00\x00\x00@o\x88|\x00\x00\x00\x00A\x84Ul\x00\x00\x00\x00BOj|\x00\x00\x00\x00Cd7l\x00\x00\x00\x00D/L|\x00\x00\x00\x00E" +
+	"D\x19l\x00\x00\x00\x00E\xf3~\xfc\x00\x00\x00\x00G-5\xec\x00\x00\x00\x00G\xd3`\xfc\x00\x00\x00\x00I\r\x17\xec\x00\x00\x00\x00I\xb3B\xfc\x00\x00\x00\x00J\xec\xf9\xec\x00\x00\x00\x00K\x9c_|\x00" +
+	"\x00\x00\x00L\xd6\x16l\x00\x00\x00\x00M|A|\x00\x00\x00\x00N\xb6\x14P\x01\x02\x01\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x06\x05\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" +
+	"\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a" +
+	"\b\a\b\a\b\a\b\t\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\xff\xff\xc7\\\x00" +
+	"\x00\xff\xffΔ\x00\x04\xff\xffܤ\x01\b\xff\xff\xce\xc8\x00\x04\xff\xff\xdc\xd8\x01\b\xff\xff\xdc\xd8\x01\f\xff\xff\xdc\xd8\x01\x10\xff\xff\xd5\xd0\x01\x14\xff\xff\xc7\xc0\x00\x18\xff\xff\xe3\xe0\x01\x1cLMT\x00N" +
+	"ST\x00NDT\x00NPT\x00NWT\x00ADT\x00AST\x00ADDT\x00\nAST4ADT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\xe3\xc9I\xd0U\x03\x00\x00U\x03\x00\x00\x12\x00\x00\x00America/Grand_TurkTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00L\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xffi\x87\x1e0\xff\xff\xff\xff\x93\x0f\xb4\xfe\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14" +
+	"Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x00\x00\x00\x00\x1a\xf2\np\x00" +
+	"\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\"" +
+	"U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\nU\xe0\x00" +
+	"\x00\x00\x00)ޥp\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000" +
+	"\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\a\r\xf0\x00" +
+	"\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>" +
+	"\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00" +
+	"\x00\x00\x00E\xf3\xa8\xf0\x00\x00\x00\x00G-_\xe0\x00\x00\x00\x00Gӊ\xf0\x00\x00\x00\x00I\rA\xe0\x00\x00\x00\x00I\xb3l\xf0\x00\x00\x00\x00J\xed#\xe0\x00\x00\x00\x00K\x9c\x89p\x00\x00\x00\x00L" +
+	"\xd6@`\x00\x00\x00\x00M|kp\x00\x00\x00\x00N\xb6\"`\x00\x00\x00\x00O\\Mp\x00\x00\x00\x00P\x96\x04`\x00\x00\x00\x00Q</p\x00\x00\x00\x00Ru\xe6`\x00\x00\x00\x00S\x1c\x11p\x00" +
+	"\x00\x00\x00TU\xc8`\x00\x00\x00\x00T\xfb\xf3p\x00\x00\x00\x00Z\xa4\xd3\xf0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x03\xff\xff\xbdP\x00\x00\xff\xff\xb8\x02\x00\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7" +
+	"\xc0\x01\f\xff\xff\xc7\xc0\x00\x10LMT\x00KMT\x00EST\x00EDT\x00AST\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0f\x00\x00\x00America/GrenadaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00" +
+	"\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00" +
+	"\x00\x12\x00\x00\x00America/GuadeloupeTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
 	"\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff" +
 	"\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLM" +
-	"T\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTq\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x15\x00\x1c\x00America/Lo" +
-	"wer_PrincesUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0" +
-	"\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTq\xc9*;\xb1\x00\x00\x00\xb1\x00" +
-	"\x00\x00\x11\x00\x1c\x00America/St_ThomasUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03" +
-	"\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj" +
-	"\xbeT\xac\x8a\x83S\xd4\x00\x00\x00\xd4\x00\x00\x00\x11\x00\x1c\x00America/GuatemalaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S" +
-	"_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x9f\x9d\xea\xdc\x00\x00\x00\x00\aU\xac`\x00\x00\x00\x00\a\xcd" +
-	"\x96\xd0\x00\x00\x00\x00\x19,x`\x00\x00\x00\x00\x19\xcf\xe4P\x00\x00\x00\x00'\xea\xee\xe0\x00\x00\x00\x00(\xc8\\\xd0\x00\x00\x00\x00DTR`\x00\x00\x00\x00E\x1fKP\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff" +
-	"\xff\xab$\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\bLMT\x00CDT\x00CST\x00\nCST6\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTR\xc8\xd9\xf6\xc4\x02\x00\x00\xc4\x02\x00" +
-	"\x00\x11\x00\x1c\x00America/CatamarcaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xaf,\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff" +
-	"\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n" +
-	"\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff" +
-	"\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed" +
-	"\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff" +
-	"\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c5" +
-	"0\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00" +
-	"\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*" +
-	"\xb0\x00\x00\x00\x00@\xbb\xf10\x00\x00\x00\x00@\xd5\v\xc0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
-	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\xff\xff\xc2T\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff" +
-	"\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTq\xc9*;\xb1\x00\x00\x00" +
-	"\xb1\x00\x00\x00\x0f\x00\x1c\x00America/AntiguaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03" +
-	"\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj" +
-	"\xbeT\x1b\x81-\xa9\x8a\x01\x00\x00\x8a\x01\x00\x00\x13\x00\x1c\x00America/Porto_VelhoUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00" +
-	"\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif" +
-	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaa\x82\xe8\xff\xff\xff\xff\xb8\x0fW\xf0\xff\xff\xff\xff" +
-	"\xb8\xfdN\xb0\xff\xff\xff\xff\xb9\xf1B@\xff\xff\xff\xff\xbaނ0\xff\xff\xff\xff\xda8\xbc@\xff\xff\xff\xff\xda\xec\b@\xff\xff\xff\xff\xdc\x19\xef\xc0\xff\xff\xff\xffܹg0\xff\xff\xff\xff\xdd\xfb#@" +
-	"\xff\xff\xff\xffޛ\xec0\xff\xff\xff\xff\xdfݨ@\xff\xff\xff\xff\xe0TA0\xff\xff\xff\xff\xf4\x98\r\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf6\xc0r@\xff\xff\xff\xff\xf7\x0e,\xb0\xff\xff\xff\xff" +
-	"\xf8Q:@\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xfa\n\xe0\xc0\xff\xff\xff\xff\xfa\xa9\x06\xb0\xff\xff\xff\xff\xfb\xec\x14@\xff\xff\xff\xff\xfc\x8b\x8b\xb0\x00\x00\x00\x00\x1dɜ@\x00\x00\x00\x00\x1ex\xe5\xb0" +
-	"\x00\x00\x00\x00\x1f\xa0C\xc0\x00\x00\x00\x00 3ݰ\x00\x00\x00\x00!\x81w@\x00\x00\x00\x00\"\vְ\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\xff\xff\xc4\x18\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\bLMT\x00-03\x00-04\x00\n<-04>4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xef\xf0R\x8a\xc4\x02\x00" +
-	"\x00\xc4\x02\x00\x00\x0f\x00\x1c\x00America/RosarioUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xad\xb0\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff" +
-	"\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbe" +
-	"x\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff" +
-	"\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xff\xce" +
-	"\xb0\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff" +
-	"\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe" +
-	"\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00" +
-	"\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008" +
-	"\xbf*\xb0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x00\x00\x00\x00H\xfa\xa2\xb0\x00\x00\x00\x00I\xbca \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
-	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x04\x05\x04\x05\xff\xff\xc3\xd0\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f" +
-	"\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9bܩ=\xda\x06" +
-	"\x00\x00\xda\x06\x00\x00\x0f\x00\x1c\x00America/ChicagoUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaf\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80" +
-	"\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xa2\xcbt\x00\xff\xff\xff\xff\xa3\x83\xf7\xf0\xff\xff\xff\xff\xa4EҀ\xff\xff\xff\xff\xa5c\xd9\xf0\xff\xff\xff\xff\xa6S\xd9\x00\xff\xff\xff\xff\xa7\x15\x97p\xff\xff\xff\xff" +
-	"\xa83\xbb\x00\xff\xff\xff\xff\xa8\xfe\xb3\xf0\xff\xff\xff\xff\xaa\x13\x9d\x00\xff\xff\xff\xff\xaaޕ\xf0\xff\xff\xff\xff\xab\xf3\x7f\x00\xff\xff\xff\xff\xac\xbew\xf0\xff\xff\xff\xff\xad\xd3a\x00\xff\xff\xff\xff\xae\x9eY\xf0" +
-	"\xff\xff\xff\xff\xaf\xb3C\x00\xff\xff\xff\xff\xb0~;\xf0\xff\xff\xff\xff\xb1\x9c_\x80\xff\xff\xff\xff\xb2gXp\xff\xff\xff\xff\xb3|A\x80\xff\xff\xff\xff\xb4G:p\xff\xff\xff\xff\xb5\\#\x80\xff\xff\xff\xff" +
-	"\xb6'\x1cp\xff\xff\xff\xff\xb7<\x05\x80\xff\xff\xff\xff\xb8\x06\xfep\xff\xff\xff\xff\xb9\x1b\xe7\x80\xff\xff\xff\xff\xb9\xe6\xe0p\xff\xff\xff\xff\xbb\x05\x04\x00\xff\xff\xff\xff\xbb\xc6\xc2p\xff\xff\xff\xff\xbc\xe4\xe6\x00" +
-	"\xff\xff\xff\xff\xbd\xaf\xde\xf0\xff\xff\xff\xff\xbe\xc4\xc8\x00\xff\xff\xff\xff\xbf\x8f\xc0\xf0\xff\xff\xff\xff\xc0Z\xd6\x00\xff\xff\xff\xff\xc1\xb0<p\xff\xff\xff\xff\u0084\x8c\x00\xff\xff\xff\xff\xc3O\x84\xf0\xff\xff\xff\xff" +
-	"\xc4dn\x00\xff\xff\xff\xff\xc5/f\xf0\xff\xff\xff\xff\xc6M\x8a\x80\xff\xff\xff\xff\xc7\x0fH\xf0\xff\xff\xff\xff\xc8-l\x80\xff\xff\xff\xff\xc8\xf8ep\xff\xff\xff\xff\xca\rN\x80\xff\xff\xff\xff\xca\xd8Gp" +
-	"\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd3u\xf3\x00\xff\xff\xff\xff\xd4@\xeb\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff" +
-	"\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90p" +
-	"\xff\xff\xff\xff\u07bey\x80\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff" +
-	"\xe5W<\xf0\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe77\x1e\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe9\x17\x00\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea\xf6\xe2\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00" +
-	"\xff\xff\xff\xff\xec\xd6\xc4\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\xee\xbf\xe1p\xff\xff\xff\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xf0\x9f\xc3p\xff\xff\xff\xff\xf1\x8f\u0080\xff\xff\xff\xff\xf2\x7f\xa5p\xff\xff\xff\xff" +
-	"\xf3o\xa4\x80\xff\xff\xff\xff\xf4_\x87p\xff\xff\xff\xff\xf5O\x86\x80\xff\xff\xff\xff\xf6?ip\xff\xff\xff\xff\xf7/h\x80\xff\xff\xff\xff\xf8(\x85\xf0\xff\xff\xff\xff\xf9\x0fJ\x80\xff\xff\xff\xff\xfa\bg\xf0" +
-	"\xff\xff\xff\xff\xfa\xf8g\x00\xff\xff\xff\xff\xfb\xe8I\xf0\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8+\xf0\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\r\xf0\x00\x00\x00\x00\x00\x98\r\x00\x00\x00\x00\x00" +
-	"\x01\x87\xef\xf0\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\fp\x00\x00\x00\x00\x04a\v\x80\x00\x00\x00\x00\x05P\xeep\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\a0\xd0p\x00\x00\x00\x00\a\x8d'\x80" +
-	"\x00\x00\x00\x00\t\x10\xb2p\x00\x00\x00\x00\t\xad\xa3\x00\x00\x00\x00\x00\n\xf0\x94p\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00\x00\x00\fٰ\xf0\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00" +
-	"\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99t\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0" +
-	"\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\"7p\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00" +
-	"\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1܀\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00" +
-	"\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)\nc\xf0\x00\x00\x00\x00)\u07b3\x80\x00\x00\x00\x00*\xeaE\xf0\x00\x00\x00\x00" +
-	"+\xbe\x95\x80\x00\x00\x00\x00,\xd3bp\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3Dp\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x93&p\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp" +
-	"\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x00" +
-	"9\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00;۬\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80" +
-	"\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x04\x05\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"T\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x8a\x83S\xd4\x00\x00\x00\xd4\x00\x00\x00\x11\x00\x00\x00America/Gu" +
+	"atemalaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZ" +
+	"if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x9f\x9d\xea\xdc\x00\x00\x00\x00\aU\xac`\x00\x00" +
+	"\x00\x00\a͖\xd0\x00\x00\x00\x00\x19,x`\x00\x00\x00\x00\x19\xcf\xe4P\x00\x00\x00\x00'\xea\xee\xe0\x00\x00\x00\x00(\xc8\\\xd0\x00\x00\x00\x00DTR`\x00\x00\x00\x00E\x1fKP\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\xff\xff\xab$\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\bLMT\x00CDT\x00CST\x00\nCST6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcd\xc3v\xe3\xb3\x00\x00" +
+	"\x00\xb3\x00\x00\x00\x11\x00\x00\x00America/GuayaquilTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00" +
+	"\x10\xff\xff\xff\xffi\x87&X\xff\xff\xff\xff\xb6\xa4B\x18\x00\x00\x00\x00+\x16\xfc\xd0\x00\x00\x00\x00+q\xe6@\x01\x03\x02\x03\xff\xff\xb5(\x00\x00\xff\xff\xb6h\x00\x04\xff\xff\xc7\xc0\x01\b\xff\xff\xb9\xb0\x00" +
+	"\fLMT\x00QMT\x00-04\x00-05\x00\n<-05>5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x05\xf3\x89\xb5\x00\x00\x00\xb5\x00\x00\x00\x0e\x00\x00\x00Ameri" +
+	"ca/GuyanaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" +
+	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x92\x1d\x0f\x87\xff\xff\xff\xff\x98\xd9{@" +
+	"\x00\x00\x00\x00\n\x7f\x05\xbc\x00\x00\x00\x00)\xd5@\xc0\x01\x02\x03\x01\xff\xff\xc9y\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xcbD\x00\b\xff\xff\xd5\xd0\x00\x0eLMT\x00-04\x00-0345\x00-0" +
+	"3\x00\n<-04>4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00):\x17-\x88\x06\x00\x00\x88\x06\x00\x00\x0f\x00\x00\x00America/HalifaxTZif2" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\x80\xf1\xab\xa0\xff\xff\xff\xff\x9a\xe4\xde\xc0\xff\xff\xff\xff\x9b\xd6\x130\xff\xff\xff\xff\x9e\xb8" +
+	"\x85`\xff\xff\xff\xff\x9f\xba\xddP\xff\xff\xff\xff\xa2\x9d\x17@\xff\xff\xff\xff\xa30\xb10\xff\xff\xff\xff\xa4zV@\xff\xff\xff\xff\xa5\x1b\x1f0\xff\xff\xff\xff\xa6S\xa0\xc0\xff\xff\xff\xff\xa6\xfcR\xb0\xff\xff" +
+	"\xff\xff\xa8<\xbd@\xff\xff\xff\xff\xa8\xdc4\xb0\xff\xff\xff\xff\xaa\x1c\x9f@\xff\xff\xff\xff\xaa\xcd:0\xff\xff\xff\xff\xab\xfc\x81@\xff\xff\xff\xff\xac\xbf\x910\xff\xff\xff\xff\xad\xee\xd8@\xff\xff\xff\xff\xae\x8c" +
+	"\xfe0\xff\xff\xff\xff\xaf\xbcE@\xff\xff\xff\xff\xb0\x7fU0\xff\xff\xff\xff\xb1\xae\x9c@\xff\xff\xff\xff\xb2Kp\xb0\xff\xff\xff\xff\xb3\x8e~@\xff\xff\xff\xff\xb4$\xbb0\xff\xff\xff\xff\xb5n`@\xff\xff" +
+	"\xff\xff\xb6\x15\xc0\xb0\xff\xff\xff\xff\xb7NB@\xff\xff\xff\xff\xb8\b\x17\xb0\xff\xff\xff\xff\xb9$\xe9\xc0\xff\xff\xff\xff\xb9\xe7\xf9\xb0\xff\xff\xff\xff\xbb\x04\xcb\xc0\xff\xff\xff\xff\xbb\xd1\x160\xff\xff\xff\xff\xbd\x00" +
+	"]@\xff\xff\xff\xff\xbd\x9d1\xb0\xff\xff\xff\xff\xbe\xf2\xb4@\xff\xff\xff\xff\xbf\x90\xda0\xff\xff\xff\xff\xc0\xd3\xe7\xc0\xff\xff\xff\xff\xc1^G0\xff\xff\xff\xff\u008d\x8e@\xff\xff\xff\xff\xc3P\x9e0\xff\xff" +
+	"\xff\xff\xc4mp@\xff\xff\xff\xff\xc50\x800\xff\xff\xff\xff\xc6r<@\xff\xff\xff\xff\xc7\x10b0\xff\xff\xff\xff\xc86n\xc0\xff\xff\xff\xff\xc8\xf9~\xb0\xff\xff\xff\xff\xca\x16P\xc0\xff\xff\xff\xff\xca\xd9" +
+	"`\xb0\xff\xff\xff\xffˈ\xe2`\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\xff\xff\xff\xff\xd3u\xd6\xe0\xff\xff\xff\xff\xd4@\xcf\xd0\xff\xff\xff\xff\xd5U\xb8\xe0\xff\xff\xff\xff\xd6 \xb1\xd0\xff\xff" +
+	"\xff\xff\xd75\x9a\xe0\xff\xff\xff\xff\xd8\x00\x93\xd0\xff\xff\xff\xff\xd9\x15|\xe0\xff\xff\xff\xff\xd9\xe0u\xd0\xff\xff\xff\xff\xdc\xde{`\xff\xff\xff\xffݩtP\xff\xff\xff\xff\u07be]`\xff\xff\xff\xff߉" +
+	"VP\xff\xff\xff\xff\xe0\x9e?`\xff\xff\xff\xff\xe1i8P\xff\xff\xff\xff\xe2~!`\xff\xff\xff\xff\xe3I\x1aP\xff\xff\xff\xff\xe6G\x1f\xe0\xff\xff\xff\xff\xe7\x12\x18\xd0\xff\xff\xff\xff\xe8'\x01\xe0\xff\xff" +
+	"\xff\xff\xe8\xf1\xfa\xd0\xff\xff\xff\xff\xea\x06\xe3\xe0\xff\xff\xff\xff\xea\xd1\xdc\xd0\xff\xff\xff\xff\xeb\xe6\xc5\xe0\xff\xff\xff\xff챾\xd0\xff\xff\xff\xff\xf1\x8f\xa6`\xff\xff\xff\xff\xf2\x7f\x89P\xff\xff\xff\xff\xf3o" +
+	"\x88`\xff\xff\xff\xff\xf4_kP\xff\xff\xff\xff\xf5Oj`\xff\xff\xff\xff\xf6?MP\xff\xff\xff\xff\xf7/L`\xff\xff\xff\xff\xf8(i\xd0\xff\xff\xff\xff\xf9\x0f.`\xff\xff\xff\xff\xfa\bK\xd0\xff\xff" +
+	"\xff\xff\xfa\xf8J\xe0\xff\xff\xff\xff\xfb\xe8-\xd0\xff\xff\xff\xff\xfc\xd8,\xe0\xff\xff\xff\xff\xfd\xc8\x0f\xd0\xff\xff\xff\xff\xfe\xb8\x0e\xe0\xff\xff\xff\xff\xff\xa7\xf1\xd0\x00\x00\x00\x00\x00\x97\xf0\xe0\x00\x00\x00\x00\x01\x87" +
+	"\xd3\xd0\x00\x00\x00\x00\x02w\xd2\xe0\x00\x00\x00\x00\x03p\xf0P\x00\x00\x00\x00\x04`\xef`\x00\x00\x00\x00\x05P\xd2P\x00\x00\x00\x00\x06@\xd1`\x00\x00\x00\x00\a0\xb4P\x00\x00\x00\x00\b \xb3`\x00\x00" +
+	"\x00\x00\t\x10\x96P\x00\x00\x00\x00\n\x00\x95`\x00\x00\x00\x00\n\xf0xP\x00\x00\x00\x00\v\xe0w`\x00\x00\x00\x00\fٔ\xd0\x00\x00\x00\x00\r\xc0Y`\x00\x00\x00\x00\x0e\xb9v\xd0\x00\x00\x00\x00\x0f\xa9" +
+	"u\xe0\x00\x00\x00\x00\x10\x99X\xd0\x00\x00\x00\x00\x11\x89W\xe0\x00\x00\x00\x00\x12y:\xd0\x00\x00\x00\x00\x13i9\xe0\x00\x00\x00\x00\x14Y\x1c\xd0\x00\x00\x00\x00\x15I\x1b\xe0\x00\x00\x00\x00\x168\xfe\xd0\x00\x00" +
+	"\x00\x00\x17(\xfd\xe0\x00\x00\x00\x00\x18\"\x1bP\x00\x00\x00\x00\x19\b\xdf\xe0\x00\x00\x00\x00\x1a\x01\xfdP\x00\x00\x00\x00\x1a\xf1\xfc`\x00\x00\x00\x00\x1b\xe1\xdfP\x00\x00\x00\x00\x1c\xd1\xde`\x00\x00\x00\x00\x1d\xc1" +
+	"\xc1P\x00\x00\x00\x00\x1e\xb1\xc0`\x00\x00\x00\x00\x1f\xa1\xa3P\x00\x00\x00\x00 u\xf2\xe0\x00\x00\x00\x00!\x81\x85P\x00\x00\x00\x00\"U\xd4\xe0\x00\x00\x00\x00#j\xa1\xd0\x00\x00\x00\x00$5\xb6\xe0\x00\x00" +
+	"\x00\x00%J\x83\xd0\x00\x00\x00\x00&\x15\x98\xe0\x00\x00\x00\x00'*e\xd0\x00\x00\x00\x00'\xfe\xb5`\x00\x00\x00\x00)\nG\xd0\x00\x00\x00\x00)ޗ`\x00\x00\x00\x00*\xea)\xd0\x00\x00\x00\x00+\xbe" +
+	"y`\x00\x00\x00\x00,\xd3FP\x00\x00\x00\x00-\x9e[`\x00\x00\x00\x00.\xb3(P\x00\x00\x00\x00/~=`\x00\x00\x00\x000\x93\nP\x00\x00\x00\x001gY\xe0\x00\x00\x00\x002r\xecP\x00\x00" +
+	"\x00\x003G;\xe0\x00\x00\x00\x004R\xceP\x00\x00\x00\x005'\x1d\xe0\x00\x00\x00\x0062\xb0P\x00\x00\x00\x007\x06\xff\xe0\x00\x00\x00\x008\x1b\xcc\xd0\x00\x00\x00\x008\xe6\xe1\xe0\x00\x00\x00\x009\xfb" +
+	"\xae\xd0\x00\x00\x00\x00:\xc6\xc3\xe0\x00\x00\x00\x00;ې\xd0\x00\x00\x00\x00<\xaf\xe0`\x00\x00\x00\x00=\xbbr\xd0\x00\x00\x00\x00>\x8f\xc2`\x00\x00\x00\x00?\x9bT\xd0\x00\x00\x00\x00@o\xa4`\x00\x00" +
+	"\x00\x00A\x84qP\x00\x00\x00\x00BO\x86`\x00\x00\x00\x00CdSP\x00\x00\x00\x00D/h`\x00\x00\x00\x00ED5P\x00\x00\x00\x00E\xf3\x9a\xe0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
 	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xad\xd4\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00" +
-	"\b\xff\xff\xb9\xb0\x00\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x01\x14LMT\x00CDT\x00CST\x00EST\x00CWT\x00CPT\x00\nCST6CDT,M3.2.0,M" +
-	"11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTø\xab\x9b\xf0\x00\x00\x00\xf0\x00\x00\x00\x0f\x00\x1c\x00America/CrestonUT\t\x00\x03\xdd\xfc\x94" +
-	"b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" +
-	"\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff^" +
-	"\x04\f\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xcf\x17\xdf\x1c\xff\xff\xff\xffϏ\xe5\xac\xff" +
-	"\xff\xff\xffЁ\x1a\x1c\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\x02\x01\x02\x01\x02\x03\x02\x03\x02\x01\x02\xff\xff\x96\xee\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\fLM" +
-	"T\x00MDT\x00MST\x00MWT\x00\nMST7\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe5s\xb3\\'\x01\x00\x00'\x01\x00\x00\x0f\x00\x1c\x00America/Ma" +
-	"naguaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10" +
-	"\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xffi\x87,d\xff\xff\xff\xff\xbd-H\xe8\x00\x00\x00\x00\x06Ct`\x00\x00\x00\x00\t\xa4>P\x00\x00\x00\x00\x11Q\xf8\xe0\x00\x00\x00\x00\x11\xd4oP\x00\x00\x00\x00" +
-	"\x131\xda\xe0\x00\x00\x00\x00\x13\xb4QP\x00\x00\x00\x00)a\x91 \x00\x00\x00\x00*\xc1KP\x00\x00\x00\x00+C\xdd\xe0\x00\x00\x00\x002\xc9\xefP\x00\x00\x00\x00BX\xc0\xe0\x00\x00\x00\x00C?iP" +
-	"\x00\x00\x00\x00DTn\x80\x00\x00\x00\x00E\x1fY`\x01\x02\x03\x02\x04\x02\x04\x02\x03\x02\x03\x02\x04\x02\x04\x02\xff\xff\xaf\x1c\x00\x00\xff\xff\xaf\x18\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x00\f\xff\xff\xb9\xb0" +
-	"\x01\x10LMT\x00MMT\x00CST\x00EST\x00CDT\x00\nCST6\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTӿ\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00\x0e\x00\x1c\x00Am" +
-	"erica/NassauUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xc4`\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xd5" +
+	"\xd0\x01\x10LMT\x00ADT\x00AST\x00AWT\x00APT\x00\nAST4ADT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\a\x1c\x9e\x9a]\x04\x00\x00]\x04\x00\x00\x0e\x00\x00\x00America/HavanaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00j\x00\x00" +
+	"\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffi\x87(\xb8\xff\xff\xff\xff\xacb\u0080\xff\xff\xff\xff\xb1ӔP\xff\xff\xff\xff\xb2t]@\xff\xff\xff\xff\xc8[f\xd0\xff\xff\xff\xff\xc8\xd3Q@\xff\xff\xff\xff\xca;" +
+	"H\xd0\xff\xff\xff\xffʼm\xc0\xff\xff\xff\xff\xcc$eP\xff\xff\xff\xff̜O\xc0\xff\xff\xff\xff\xd1\xc4\vP\xff\xff\xff\xff\xd2;\xf5\xc0\xff\xff\xff\xffӣ\xedP\xff\xff\xff\xff\xd4\x1b\xd7\xc0\xff\xff" +
+	"\xff\xff\xf7`\x05\xd0\xff\xff\xff\xff\xf7\xff}@\xff\xff\xff\xff\xf9=D\xd0\xff\xff\xff\xff\xf9\xe3S\xc0\xff\xff\xff\xff\xfa\xdb;\xd0\xff\xff\xff\xff\xfb\xa7\x86@\xff\xff\xff\xff\xfcũ\xd0\xff\xff\xff\xff\xfd\x87" +
+	"h@\xff\xff\xff\xff\xfe\xb8\x00\xd0\xff\xff\xff\xff\xff\xa7\xe3\xc0\x00\x00\x00\x00\x00\x97\xe2\xd0\x00\x00\x00\x00\x01\x87\xc5\xc0\x00\x00\x00\x00\x02w\xc4\xd0\x00\x00\x00\x00\x03p\xe2@\x00\x00\x00\x00\x04`\xe1P\x00\x00" +
+	"\x00\x00\x055\x14\xc0\x00\x00\x00\x00\x06@\xc3P\x00\x00\x00\x00\a\x16H@\x00\x00\x00\x00\b \xa5P\x00\x00\x00\x00\b\xf7{\xc0\x00\x00\x00\x00\n\x00\x87P\x00\x00\x00\x00\n\xf0j@\x00\x00\x00\x00\v\xe0" +
+	"iP\x00\x00\x00\x00\fن\xc0\x00\x00\x00\x00\r\xc0KP\x00\x00\x00\x00\x0e\xb9h\xc0\x00\x00\x00\x00\x0f\xb2\xa2P\x00\x00\x00\x00\x10}\x9b@\x00\x00\x00\x00\x11Q\xea\xd0\x00\x00\x00\x00\x12f\xb7\xc0\x00\x00" +
+	"\x00\x00\x131\xcc\xd0\x00\x00\x00\x00\x14F\x99\xc0\x00\x00\x00\x00\x15[\x82\xd0\x00\x00\x00\x00\x16&{\xc0\x00\x00\x00\x00\x17;d\xd0\x00\x00\x00\x00\x18\x06]\xc0\x00\x00\x00\x00\x19\x1bF\xd0\x00\x00\x00\x00\x19\xe6" +
+	"?\xc0\x00\x00\x00\x00\x1a\xfb(\xd0\x00\x00\x00\x00\x1b\xcf\\@\x00\x00\x00\x00\x1c\xdb\n\xd0\x00\x00\x00\x00\x1d\xaf>@\x00\x00\x00\x00\x1ezSP\x00\x00\x00\x00\x1f\x8f @\x00\x00\x00\x00 Z5P\x00\x00" +
+	"\x00\x00!o\x02@\x00\x00\x00\x00\"CQ\xd0\x00\x00\x00\x00#N\xe4@\x00\x00\x00\x00$#3\xd0\x00\x00\x00\x00%.\xc6@\x00\x00\x00\x00&\x15\x8a\xd0\x00\x00\x00\x00'\x17\xe2\xc0\x00\x00\x00\x00'\xfe" +
+	"\xa7P\x00\x00\x00\x00(\xf7\xd2\xd0\x00\x00\x00\x00)މP\x00\x00\x00\x00*״\xd0\x00\x00\x00\x00+\xbekP\x00\x00\x00\x00,\xb7\x96\xd0\x00\x00\x00\x00-\x9eMP\x00\x00\x00\x00.\x97x\xd0\x00\x00" +
+	"\x00\x00/~/P\x00\x00\x00\x000wZ\xd0\x00\x00\x00\x001gK\xd0\x00\x00\x00\x002W<\xd0\x00\x00\x00\x003G-\xd0\x00\x00\x00\x004@YP\x00\x00\x00\x005\x1d\xd5P\x00\x00\x00\x0062" +
+	"\xb0P\x00\x00\x00\x006\xfd\xb7P\x00\x00\x00\x008\x1b\xcc\xd0\x00\x00\x00\x008\xe6\xd3\xd0\x00\x00\x00\x009\xfb\xae\xd0\x00\x00\x00\x00:Ƶ\xd0\x00\x00\x00\x00;ې\xd0\x00\x00\x00\x00<\xaf\xd2P\x00\x00" +
+	"\x00\x00=\xbbr\xd0\x00\x00\x00\x00>\x8f\xb4P\x00\x00\x00\x00?\x9bT\xd0\x00\x00\x00\x00@f[\xd0\x00\x00\x00\x00ED5P\x00\x00\x00\x00E\xf3\x8c\xd0\x00\x00\x00\x00G$\x17P\x00\x00\x00\x00G\xdc" +
+	"\xa9P\x00\x00\x00\x00I\x03\xf9P\x00\x00\x00\x00I\xb3P\xd0\x00\x00\x00\x00J\xe3\xdbP\x00\x00\x00\x00K\x9cmP\x00\x00\x00\x00L\xcc\xf7\xd0\x00\x00\x00\x00M\x85\x89\xd0\x00\x00\x00\x00N\xbfN\xd0\x00\x00" +
+	"\x00\x00Ow\xe0\xd0\x00\x00\x00\x00P\x95\xf6P\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\xff\xff\xb2\xc8\x00\x00\xff\xff\xb2\xc0\x00\x04\xff\xff\xc7\xc0\x01\b\xff\xff\xb9\xb0\x00\fLMT\x00HMT\x00CDT\x00CST\x00\nCST5CDT,M3.2.0/0,M1" +
+	"1.1.0/1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe4MS\x99\x1e\x01\x00\x00\x1e\x01\x00\x00\x12\x00\x00\x00America/HermosilloTZif" +
+	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6fV`\xff\xff\xff\xff\xb7" +
+	"C\xd2`\xff\xff\xff\xff\xb8\f6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\xff\xff\xff\xff\xcb\xeaq`\xff\xff\xff\xffؑ\xb4\xf0\x00\x00\x00\x00\x00\x00p\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00" +
+	"\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x01\x02\x01\x03\x01\x02\x01\x04\x01\x03\x01\x03\x01\x03\x01\xff\xff\x97\xf8\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff" +
+	"\xab\xa0\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\x8f\x80\x00\x10LMT\x00MST\x00CST\x00MDT\x00PST\x00\nMST7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\xb6{\xc9" +
+	"\x13\x02\x00\x00\x13\x02\x00\x00\x1c\x00\x00\x00America/Indiana/IndianapolisTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
 	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\xac\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xffr\xeex\xec\xff\xff\xff\xff\x9e\xb8\x93p\xff\xff\xff\xff\x9f\xba\xeb`\xff\xff\xff\xff\xa0\x87.\xc8\xff\xff\xff\xff\xa1\x9a\xb1@\xff\xff\xff\xff\xa2" +
-	"\x94\x06\xf0\xff\xff\xff\xff\xa3U\xa9@\xff\xff\xff\xff\xa4\x86]\xf0\xff\xff\xff\xff\xa5(x`\xff\xff\xff\xff\xa6f?\xf0\xff\xff\xff\xff\xa7\fN\xe0\xff\xff\xff\xff\xa8F!\xf0\xff\xff\xff\xff\xa8\xec0\xe0\xff" +
-	"\xff\xff\xff\xaa\x1c\xc9p\xff\xff\xff\xff\xaa\xd5M`\xff\xff\xff\xff\xab\xfc\xabp\xff\xff\xff\xff\xac\xb5/`\xff\xff\xff\xff\xad܍p\xff\xff\xff\xff\xae\x95\x11`\xff\xff\xff\xff\xaf\xbcop\xff\xff\xff\xff\xb0" +
-	"~-\xe0\xff\xff\xff\xff\xb1\x9cQp\xff\xff\xff\xff\xb2gJ`\xff\xff\xff\xff\xb3|3p\xff\xff\xff\xff\xb4G,`\xff\xff\xff\xff\xb5\\\x15p\xff\xff\xff\xff\xb6'\x0e`\xff\xff\xff\xff\xb7;\xf7p\xff" +
-	"\xff\xff\xff\xb8\x06\xf0`\xff\xff\xff\xff\xb9%\x13\xf0\xff\xff\xff\xff\xb9\xe6\xd2`\xff\xff\xff\xff\xbb\x04\xf5\xf0\xff\xff\xff\xff\xbb\xcf\xee\xe0\xff\xff\xff\xff\xbc\xe4\xd7\xf0\xff\xff\xff\xff\xbd\xaf\xd0\xe0\xff\xff\xff\xff\xbe" +
-	"Ĺ\xf0\xff\xff\xff\xff\xbf\x8f\xb2\xe0\xff\xff\xff\xff\xc0\xa4\x9b\xf0\xff\xff\xff\xff\xc1o\x94\xe0\xff\xff\xff\xff\u0084}\xf0\xff\xff\xff\xff\xc3Ov\xe0\xff\xff\xff\xff\xc4d_\xf0\xff\xff\xff\xff\xc5/X\xe0\xff" +
-	"\xff\xff\xff\xc6M|p\xff\xff\xff\xff\xc7\x0f:\xe0\xff\xff\xff\xff\xc8-^p\xff\xff\xff\xffˈ\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff\xd3u\xe4\xf0\xff\xff\xff\xff\xd4" +
-	"@\xdd\xe0\xff\xff\xff\xff\xd5U\xaa\xd0\xff\xff\xff\xff\xd6 \xa3\xc0\xff\xff\xff\xff\xd75\x8c\xd0\xff\xff\xff\xff\xd8\x00\x85\xc0\xff\xff\xff\xff\xd9\x15n\xd0\xff\xff\xff\xff\xda3v@\xff\xff\xff\xff\xda\xfe\xa7p\xff" +
-	"\xff\xff\xff\xdc\x13t`\xff\xff\xff\xff\xdcމp\xff\xff\xff\xffݩ\x82`\xff\xff\xff\xff\u07bekp\xff\xff\xff\xff߉d`\xff\xff\xff\xff\xe0\x9eMp\xff\xff\xff\xff\xe1iF`\xff\xff\xff\xff\xe2" +
-	"~/p\xff\xff\xff\xff\xe3I(`\xff\xff\xff\xff\xe4^\x11p\xff\xff\xff\xff\xe5)\n`\xff\xff\xff\xff\xe6G-\xf0\xff\xff\xff\xff\xe7\x12&\xe0\xff\xff\xff\xff\xe8'\x0f\xf0\xff\xff\xff\xff\xe9\x16\xf2\xe0\xff" +
-	"\xff\xff\xff\xea\x06\xf1\xf0\xff\xff\xff\xff\xea\xf6\xd4\xe0\xff\xff\xff\xff\xeb\xe6\xd3\xf0\xff\xff\xff\xff\xecֶ\xe0\xff\xff\xff\xff\xedƵ\xf0\xff\xff\xff\xff\xee\xbf\xd3`\xff\xff\xff\xff\xef\xaf\xd2p\xff\xff\xff\xff\xf0" +
-	"\x9f\xb5`\xff\xff\xff\xff\xf1\x8f\xb4p\xff\xff\xff\xff\xf2\x7f\x97`\xff\xff\xff\xff\xf3o\x96p\xff\xff\xff\xff\xf4_y`\xff\xff\xff\xff\xf5Oxp\xff\xff\xff\xff\xf6?[`\xff\xff\xff\xff\xf7/Zp\xff" +
-	"\xff\xff\xff\xf8(w\xe0\xff\xff\xff\xff\xf9\x0f<p\xff\xff\xff\xff\xfa\bY\xe0\xff\xff\xff\xff\xfa\xf8X\xf0\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\xff\xff\xff\xff\xfe" +
-	"\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00" +
-	"\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\a0\xc2`\x00\x00\x00\x00\b \xc1p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\n\x00\xa3p\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00\f" +
-	"٢\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00" +
-	"\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x00\x00\x00\x00\x1a" +
-	"\xf2\np\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00" +
-	"\x00\x00\x00\"U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)" +
-	"\nU\xe0\x00\x00\x00\x00)ޥp\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00" +
-	"\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007" +
-	"\a\r\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00" +
-	"\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00E" +
-	"DC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x04\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\xff\xff\xb5\x94\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\f\xff\xff\xc7\xc0\x01\x10LMT\x00EDT\x00EST\x00EWT\x00EPT\x00\nEST5ED" +
-	"T,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTc)\xf6)\xb3\x00\x00\x00\xb3\x00\x00\x00\x0e\x00\x1c\x00America/Bogot" +
-	"aUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04" +
-	"\x00\x00\x00\x10\xff\xff\xff\xff^\x9c4\xf0\xff\xff\xff\xff\x98XUp\x00\x00\x00\x00*\x03sP\x00\x00\x00\x00+\xbe]@\x01\x03\x02\x03\xff\xff\xba\x90\x00\x00\xff\xff\xba\x90\x00\x04\xff\xff\xc7\xc0\x01\b\xff\xff" +
-	"\xb9\xb0\x00\fLMT\x00BMT\x00-04\x00-05\x00\n<-05>5\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xf2\x04\xde\xdd\x11\x02\x00\x00\x11\x02\x00\x00\x0e\x00\x1c\x00Am" +
-	"erica/CancunUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00*\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\xa5\xb6\xda`\x00\x00\x00\x00\x16\x86\xd5`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004" +
-	"R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x005\xc4\x00`\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00" +
-	"\x00\x00\x00:\xf5\x04\x80\x00\x00\x00\x00;\xb6\xc2\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A" +
-	"\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00F\x0ff\x80\x00\x00\x00\x00G$3p\x00\x00\x00\x00G\xf8\x83\x00\x00" +
-	"\x00\x00\x00I\x04\x15p\x00\x00\x00\x00I\xd8e\x00\x00\x00\x00\x00J\xe3\xf7p\x00\x00\x00\x00K\xb8G\x00\x00\x00\x00\x00L\xcd\x13\xf0\x00\x00\x00\x00M\x98)\x00\x00\x00\x00\x00N\xac\xf5\xf0\x00\x00\x00\x00O" +
-	"x\v\x00\x00\x00\x00\x00P\x8c\xd7\xf0\x00\x00\x00\x00Qa'\x80\x00\x00\x00\x00Rl\xb9\xf0\x00\x00\x00\x00SA\t\x80\x00\x00\x00\x00TL\x9b\xf0\x00\x00\x00\x00T\xcd\xdd\x00\x01\x03\x02\x03\x02\x03\x02\x04\x01" +
-	"\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x03\xff\xff\xae\xa8\x00\x00\xff\xff\xab\xa0\x00\x04\xff\xff\xc7\xc0\x01\b\xff\xff\xb9\xb0\x00\f\xff\xff\xb9" +
-	"\xb0\x01\x10LMT\x00CST\x00EDT\x00EST\x00CDT\x00\nEST5\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xb4\x82s\x1dT\x01\x00\x00T\x01\x00\x00\x11\x00\x1c\x00A" +
-	"merica/ChihuahuaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6fV`\xff\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff\xb8\f6`\xff" +
-	"\xff\xff\xff\xb8\xfd\x86\xf0\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007" +
-	"\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xf5\x12\x90\x00\x00\x00\x00;\xb6\xd1\x00\x00\x00\x00\x00<\xb0\n\x90\x01\x02\x01\x02\x01\x02\x03\x02\x03" +
-	"\x02\x04\x01\x04\x01\x04\x01\x04\x01\x04\xff\xff\x9c\x8c\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xab\xa0\x01\x10LMT\x00MST\x00CST\x00CDT\x00MDT\x00" +
-	"\nMST7MDT,M4.1.0,M10.5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x1e\xfbn۸\x03\x00\x00\xb8\x03\x00\x00\x14\x00\x1c\x00Americ" +
-	"a/Campo_GrandeUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00[\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaaz4\xff\xff\xff\xff\xb8\x0fW\xf0\xff\xff\xff\xff\xb8\xfdN\xb0\xff\xff\xff\xff\xb9\xf1B@\xff\xff\xff\xff\xbaނ0\xff\xff\xff" +
-	"\xff\xda8\xbc@\xff\xff\xff\xff\xda\xec\b@\xff\xff\xff\xff\xdc\x19\xef\xc0\xff\xff\xff\xffܹg0\xff\xff\xff\xff\xdd\xfb#@\xff\xff\xff\xffޛ\xec0\xff\xff\xff\xff\xdfݨ@\xff\xff\xff\xff\xe0TA" +
-	"0\xff\xff\xff\xff\xf4\x98\r\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf6\xc0r@\xff\xff\xff\xff\xf7\x0e,\xb0\xff\xff\xff\xff\xf8Q:@\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xfa\n\xe0\xc0\xff\xff\xff" +
-	"\xff\xfa\xa9\x06\xb0\xff\xff\xff\xff\xfb\xec\x14@\xff\xff\xff\xff\xfc\x8b\x8b\xb0\x00\x00\x00\x00\x1dɜ@\x00\x00\x00\x00\x1ex\xe5\xb0\x00\x00\x00\x00\x1f\xa0C\xc0\x00\x00\x00\x00 3ݰ\x00\x00\x00\x00!\x81w" +
-	"@\x00\x00\x00\x00\"\vְ\x00\x00\x00\x00#X\x1e\xc0\x00\x00\x00\x00#\xe2~0\x00\x00\x00\x00%8\x00\xc0\x00\x00\x00\x00%\xd4\xd50\x00\x00\x00\x00'!\x1d@\x00\x00\x00\x00'\xbd\xf1\xb0\x00\x00\x00" +
-	"\x00)\x00\xff@\x00\x00\x00\x00)\x94\x990\x00\x00\x00\x00*\xea\x1b\xc0\x00\x00\x00\x00+k@\xb0\x00\x00\x00\x00,\xc0\xc3@\x00\x00\x00\x00-f\xd20\x00\x00\x00\x00.\xa0\xa5@\x00\x00\x00\x00/F\xb4" +
-	"0\x00\x00\x00\x000\x80\x87@\x00\x00\x00\x001\x1d[\xb0\x00\x00\x00\x002W.\xc0\x00\x00\x00\x003\x06x0\x00\x00\x00\x0048b@\x00\x00\x00\x004\xf8\xcf0\x00\x00\x00\x006 -@\x00\x00\x00" +
-	"\x006\xcfv\xb0\x00\x00\x00\x007\xf6\xd4\xc0\x00\x00\x00\x008\xb8\x930\x00\x00\x00\x009\xdf\xf1@\x00\x00\x00\x00:\x8f:\xb0\x00\x00\x00\x00;\xc9\r\xc0\x00\x00\x00\x00<o\x1c\xb0\x00\x00\x00\x00=ğ" +
-	"@\x00\x00\x00\x00>N\xfe\xb0\x00\x00\x00\x00?\x92\f@\x00\x00\x00\x00@.\xe0\xb0\x00\x00\x00\x00A\x87\x06@\x00\x00\x00\x00B\x17\xfd0\x00\x00\x00\x00CQ\xd0@\x00\x00\x00\x00C\xf7\xdf0\x00\x00\x00" +
-	"\x00EMa\xc0\x00\x00\x00\x00E\xe0\xfb\xb0\x00\x00\x00\x00G\x11\x94@\x00\x00\x00\x00G\xb7\xa30\x00\x00\x00\x00H\xfa\xb0\xc0\x00\x00\x00\x00I\x97\x850\x00\x00\x00\x00Jڒ\xc0\x00\x00\x00\x00K\x80\xa1" +
-	"\xb0\x00\x00\x00\x00L\xbat\xc0\x00\x00\x00\x00M`\x83\xb0\x00\x00\x00\x00N\x9aV\xc0\x00\x00\x00\x00OI\xa00\x00\x00\x00\x00P\x83s@\x00\x00\x00\x00Q G\xb0\x00\x00\x00\x00RcU@\x00\x00\x00" +
-	"\x00S\x00)\xb0\x00\x00\x00\x00TC7@\x00\x00\x00\x00T\xe9F0\x00\x00\x00\x00V#\x19@\x00\x00\x00\x00V\xc9(0\x00\x00\x00\x00X\x02\xfb@\x00\x00\x00\x00X\xa9\n0\x00\x00\x00\x00Y\xe2\xdd" +
-	"@\x00\x00\x00\x00Z\x88\xec0\x00\x00\x00\x00[\xden\xc0\x00\x00\x00\x00\\h\xce0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xcc\xcc" +
-	"\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\bLMT\x00-03\x00-04\x00\n<-04>4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT):\x17-\x88\x06\x00\x00\x88\x06\x00\x00" +
-	"\x0f\x00\x1c\x00America/HalifaxUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\x80\xf1\xab\xa0\xff\xff\xff\xff\x9a\xe4\xde\xc0\xff\xff\xff\xff\x9b\xd6\x130\xff\xff\xff\xff\x9e\xb8\x85`\xff\xff\xff\xff\x9f\xba" +
-	"\xddP\xff\xff\xff\xff\xa2\x9d\x17@\xff\xff\xff\xff\xa30\xb10\xff\xff\xff\xff\xa4zV@\xff\xff\xff\xff\xa5\x1b\x1f0\xff\xff\xff\xff\xa6S\xa0\xc0\xff\xff\xff\xff\xa6\xfcR\xb0\xff\xff\xff\xff\xa8<\xbd@\xff\xff" +
-	"\xff\xff\xa8\xdc4\xb0\xff\xff\xff\xff\xaa\x1c\x9f@\xff\xff\xff\xff\xaa\xcd:0\xff\xff\xff\xff\xab\xfc\x81@\xff\xff\xff\xff\xac\xbf\x910\xff\xff\xff\xff\xad\xee\xd8@\xff\xff\xff\xff\xae\x8c\xfe0\xff\xff\xff\xff\xaf\xbc" +
-	"E@\xff\xff\xff\xff\xb0\x7fU0\xff\xff\xff\xff\xb1\xae\x9c@\xff\xff\xff\xff\xb2Kp\xb0\xff\xff\xff\xff\xb3\x8e~@\xff\xff\xff\xff\xb4$\xbb0\xff\xff\xff\xff\xb5n`@\xff\xff\xff\xff\xb6\x15\xc0\xb0\xff\xff" +
-	"\xff\xff\xb7NB@\xff\xff\xff\xff\xb8\b\x17\xb0\xff\xff\xff\xff\xb9$\xe9\xc0\xff\xff\xff\xff\xb9\xe7\xf9\xb0\xff\xff\xff\xff\xbb\x04\xcb\xc0\xff\xff\xff\xff\xbb\xd1\x160\xff\xff\xff\xff\xbd\x00]@\xff\xff\xff\xff\xbd\x9d" +
-	"1\xb0\xff\xff\xff\xff\xbe\xf2\xb4@\xff\xff\xff\xff\xbf\x90\xda0\xff\xff\xff\xff\xc0\xd3\xe7\xc0\xff\xff\xff\xff\xc1^G0\xff\xff\xff\xff\u008d\x8e@\xff\xff\xff\xff\xc3P\x9e0\xff\xff\xff\xff\xc4mp@\xff\xff" +
-	"\xff\xff\xc50\x800\xff\xff\xff\xff\xc6r<@\xff\xff\xff\xff\xc7\x10b0\xff\xff\xff\xff\xc86n\xc0\xff\xff\xff\xff\xc8\xf9~\xb0\xff\xff\xff\xff\xca\x16P\xc0\xff\xff\xff\xff\xca\xd9`\xb0\xff\xff\xff\xffˈ" +
-	"\xe2`\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\xff\xff\xff\xff\xd3u\xd6\xe0\xff\xff\xff\xff\xd4@\xcf\xd0\xff\xff\xff\xff\xd5U\xb8\xe0\xff\xff\xff\xff\xd6 \xb1\xd0\xff\xff\xff\xff\xd75\x9a\xe0\xff\xff" +
-	"\xff\xff\xd8\x00\x93\xd0\xff\xff\xff\xff\xd9\x15|\xe0\xff\xff\xff\xff\xd9\xe0u\xd0\xff\xff\xff\xff\xdc\xde{`\xff\xff\xff\xffݩtP\xff\xff\xff\xff\u07be]`\xff\xff\xff\xff߉VP\xff\xff\xff\xff\xe0\x9e" +
-	"?`\xff\xff\xff\xff\xe1i8P\xff\xff\xff\xff\xe2~!`\xff\xff\xff\xff\xe3I\x1aP\xff\xff\xff\xff\xe6G\x1f\xe0\xff\xff\xff\xff\xe7\x12\x18\xd0\xff\xff\xff\xff\xe8'\x01\xe0\xff\xff\xff\xff\xe8\xf1\xfa\xd0\xff\xff" +
-	"\xff\xff\xea\x06\xe3\xe0\xff\xff\xff\xff\xea\xd1\xdc\xd0\xff\xff\xff\xff\xeb\xe6\xc5\xe0\xff\xff\xff\xff챾\xd0\xff\xff\xff\xff\xf1\x8f\xa6`\xff\xff\xff\xff\xf2\x7f\x89P\xff\xff\xff\xff\xf3o\x88`\xff\xff\xff\xff\xf4_" +
-	"kP\xff\xff\xff\xff\xf5Oj`\xff\xff\xff\xff\xf6?MP\xff\xff\xff\xff\xf7/L`\xff\xff\xff\xff\xf8(i\xd0\xff\xff\xff\xff\xf9\x0f.`\xff\xff\xff\xff\xfa\bK\xd0\xff\xff\xff\xff\xfa\xf8J\xe0\xff\xff" +
-	"\xff\xff\xfb\xe8-\xd0\xff\xff\xff\xff\xfc\xd8,\xe0\xff\xff\xff\xff\xfd\xc8\x0f\xd0\xff\xff\xff\xff\xfe\xb8\x0e\xe0\xff\xff\xff\xff\xff\xa7\xf1\xd0\x00\x00\x00\x00\x00\x97\xf0\xe0\x00\x00\x00\x00\x01\x87\xd3\xd0\x00\x00\x00\x00\x02w" +
-	"\xd2\xe0\x00\x00\x00\x00\x03p\xf0P\x00\x00\x00\x00\x04`\xef`\x00\x00\x00\x00\x05P\xd2P\x00\x00\x00\x00\x06@\xd1`\x00\x00\x00\x00\a0\xb4P\x00\x00\x00\x00\b \xb3`\x00\x00\x00\x00\t\x10\x96P\x00\x00" +
-	"\x00\x00\n\x00\x95`\x00\x00\x00\x00\n\xf0xP\x00\x00\x00\x00\v\xe0w`\x00\x00\x00\x00\fٔ\xd0\x00\x00\x00\x00\r\xc0Y`\x00\x00\x00\x00\x0e\xb9v\xd0\x00\x00\x00\x00\x0f\xa9u\xe0\x00\x00\x00\x00\x10\x99" +
-	"X\xd0\x00\x00\x00\x00\x11\x89W\xe0\x00\x00\x00\x00\x12y:\xd0\x00\x00\x00\x00\x13i9\xe0\x00\x00\x00\x00\x14Y\x1c\xd0\x00\x00\x00\x00\x15I\x1b\xe0\x00\x00\x00\x00\x168\xfe\xd0\x00\x00\x00\x00\x17(\xfd\xe0\x00\x00" +
-	"\x00\x00\x18\"\x1bP\x00\x00\x00\x00\x19\b\xdf\xe0\x00\x00\x00\x00\x1a\x01\xfdP\x00\x00\x00\x00\x1a\xf1\xfc`\x00\x00\x00\x00\x1b\xe1\xdfP\x00\x00\x00\x00\x1c\xd1\xde`\x00\x00\x00\x00\x1d\xc1\xc1P\x00\x00\x00\x00\x1e\xb1" +
-	"\xc0`\x00\x00\x00\x00\x1f\xa1\xa3P\x00\x00\x00\x00 u\xf2\xe0\x00\x00\x00\x00!\x81\x85P\x00\x00\x00\x00\"U\xd4\xe0\x00\x00\x00\x00#j\xa1\xd0\x00\x00\x00\x00$5\xb6\xe0\x00\x00\x00\x00%J\x83\xd0\x00\x00" +
-	"\x00\x00&\x15\x98\xe0\x00\x00\x00\x00'*e\xd0\x00\x00\x00\x00'\xfe\xb5`\x00\x00\x00\x00)\nG\xd0\x00\x00\x00\x00)ޗ`\x00\x00\x00\x00*\xea)\xd0\x00\x00\x00\x00+\xbey`\x00\x00\x00\x00,\xd3" +
-	"FP\x00\x00\x00\x00-\x9e[`\x00\x00\x00\x00.\xb3(P\x00\x00\x00\x00/~=`\x00\x00\x00\x000\x93\nP\x00\x00\x00\x001gY\xe0\x00\x00\x00\x002r\xecP\x00\x00\x00\x003G;\xe0\x00\x00" +
-	"\x00\x004R\xceP\x00\x00\x00\x005'\x1d\xe0\x00\x00\x00\x0062\xb0P\x00\x00\x00\x007\x06\xff\xe0\x00\x00\x00\x008\x1b\xcc\xd0\x00\x00\x00\x008\xe6\xe1\xe0\x00\x00\x00\x009\xfb\xae\xd0\x00\x00\x00\x00:\xc6" +
-	"\xc3\xe0\x00\x00\x00\x00;ې\xd0\x00\x00\x00\x00<\xaf\xe0`\x00\x00\x00\x00=\xbbr\xd0\x00\x00\x00\x00>\x8f\xc2`\x00\x00\x00\x00?\x9bT\xd0\x00\x00\x00\x00@o\xa4`\x00\x00\x00\x00A\x84qP\x00\x00" +
-	"\x00\x00BO\x86`\x00\x00\x00\x00CdSP\x00\x00\x00\x00D/h`\x00\x00\x00\x00ED5P\x00\x00\x00\x00E\xf3\x9a\xe0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xc4`\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xd5\xd0\x01\x10LMT\x00A" +
-	"DT\x00AST\x00AWT\x00APT\x00\nAST4ADT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT.\xbe\x1a>\xe7\x03\x00" +
-	"\x00\xe7\x03\x00\x00\r\x00\x1c\x00America/BoiseUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Z\x00\x00\x00\a\x00\x00\x00\x1c\xff\xff\xff\xff^\x04\x1a\xc0\xff\xff\xff\xff\x9e\xa6H\xa0\xff\xff\xff\xff\x9f\xbb\x15\x90\xff\xff\xff\xff\xa0\x86*\xa0\xff\xff\xff" +
-	"\xff\xa1\x9a\xf7\x90\xff\xff\xff\xff\xa8FL \xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W" +
-	"\x10\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb89\x10\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x1b\x10\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xfd\x10\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00" +
-	"\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\a\xb2\x1f\x90\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\t\xad\xb1\x10\x00\x00\x00\x00\n\xf0\xa2" +
-	"\x80\x00\x00\x00\x00\vࡐ\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00" +
-	"\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n" +
-	"\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00" +
-	"\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90" +
-	"\x00\x00\x00\x00\x00'\xfeߐ\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00" +
-	"\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H" +
-	"\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;ۻ\x00\x00\x00\x00" +
-	"\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}" +
-	"\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x02\x01\x02\x01\x02\x05\x03\x04\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" +
-	"\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\x93\x0f\x00" +
-	"\x00\xff\xff\x9d\x90\x01\x04\xff\xff\x8f\x80\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10\xff\xff\x9d\x90\x00\x14\xff\xff\xab\xa0\x01\x18LMT\x00PDT\x00PST\x00MWT\x00MPT\x00MST" +
-	"\x00MDT\x00\nMST7MDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTӿ\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00\x10\x00\x1c\x00A" +
-	"merica/MontrealUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xffr\xeex\xec\xff\xff\xff\xff\x9e\xb8\x93p\xff\xff\xff\xff\x9f\xba\xeb`\xff\xff\xff\xff\xa0\x87.\xc8\xff\xff\xff\xff\xa1\x9a\xb1@\xff\xff" +
-	"\xff\xff\xa2\x94\x06\xf0\xff\xff\xff\xff\xa3U\xa9@\xff\xff\xff\xff\xa4\x86]\xf0\xff\xff\xff\xff\xa5(x`\xff\xff\xff\xff\xa6f?\xf0\xff\xff\xff\xff\xa7\fN\xe0\xff\xff\xff\xff\xa8F!\xf0\xff\xff\xff\xff\xa8\xec" +
-	"0\xe0\xff\xff\xff\xff\xaa\x1c\xc9p\xff\xff\xff\xff\xaa\xd5M`\xff\xff\xff\xff\xab\xfc\xabp\xff\xff\xff\xff\xac\xb5/`\xff\xff\xff\xff\xad܍p\xff\xff\xff\xff\xae\x95\x11`\xff\xff\xff\xff\xaf\xbcop\xff\xff" +
-	"\xff\xff\xb0~-\xe0\xff\xff\xff\xff\xb1\x9cQp\xff\xff\xff\xff\xb2gJ`\xff\xff\xff\xff\xb3|3p\xff\xff\xff\xff\xb4G,`\xff\xff\xff\xff\xb5\\\x15p\xff\xff\xff\xff\xb6'\x0e`\xff\xff\xff\xff\xb7;" +
-	"\xf7p\xff\xff\xff\xff\xb8\x06\xf0`\xff\xff\xff\xff\xb9%\x13\xf0\xff\xff\xff\xff\xb9\xe6\xd2`\xff\xff\xff\xff\xbb\x04\xf5\xf0\xff\xff\xff\xff\xbb\xcf\xee\xe0\xff\xff\xff\xff\xbc\xe4\xd7\xf0\xff\xff\xff\xff\xbd\xaf\xd0\xe0\xff\xff" +
-	"\xff\xff\xbeĹ\xf0\xff\xff\xff\xff\xbf\x8f\xb2\xe0\xff\xff\xff\xff\xc0\xa4\x9b\xf0\xff\xff\xff\xff\xc1o\x94\xe0\xff\xff\xff\xff\u0084}\xf0\xff\xff\xff\xff\xc3Ov\xe0\xff\xff\xff\xff\xc4d_\xf0\xff\xff\xff\xff\xc5/" +
-	"X\xe0\xff\xff\xff\xff\xc6M|p\xff\xff\xff\xff\xc7\x0f:\xe0\xff\xff\xff\xff\xc8-^p\xff\xff\xff\xffˈ\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff\xd3u\xe4\xf0\xff\xff" +
-	"\xff\xff\xd4@\xdd\xe0\xff\xff\xff\xff\xd5U\xaa\xd0\xff\xff\xff\xff\xd6 \xa3\xc0\xff\xff\xff\xff\xd75\x8c\xd0\xff\xff\xff\xff\xd8\x00\x85\xc0\xff\xff\xff\xff\xd9\x15n\xd0\xff\xff\xff\xff\xda3v@\xff\xff\xff\xff\xda\xfe" +
-	"\xa7p\xff\xff\xff\xff\xdc\x13t`\xff\xff\xff\xff\xdcމp\xff\xff\xff\xffݩ\x82`\xff\xff\xff\xff\u07bekp\xff\xff\xff\xff߉d`\xff\xff\xff\xff\xe0\x9eMp\xff\xff\xff\xff\xe1iF`\xff\xff" +
-	"\xff\xff\xe2~/p\xff\xff\xff\xff\xe3I(`\xff\xff\xff\xff\xe4^\x11p\xff\xff\xff\xff\xe5)\n`\xff\xff\xff\xff\xe6G-\xf0\xff\xff\xff\xff\xe7\x12&\xe0\xff\xff\xff\xff\xe8'\x0f\xf0\xff\xff\xff\xff\xe9\x16" +
-	"\xf2\xe0\xff\xff\xff\xff\xea\x06\xf1\xf0\xff\xff\xff\xff\xea\xf6\xd4\xe0\xff\xff\xff\xff\xeb\xe6\xd3\xf0\xff\xff\xff\xff\xecֶ\xe0\xff\xff\xff\xff\xedƵ\xf0\xff\xff\xff\xff\xee\xbf\xd3`\xff\xff\xff\xff\xef\xaf\xd2p\xff\xff" +
-	"\xff\xff\xf0\x9f\xb5`\xff\xff\xff\xff\xf1\x8f\xb4p\xff\xff\xff\xff\xf2\x7f\x97`\xff\xff\xff\xff\xf3o\x96p\xff\xff\xff\xff\xf4_y`\xff\xff\xff\xff\xf5Oxp\xff\xff\xff\xff\xf6?[`\xff\xff\xff\xff\xf7/" +
-	"Zp\xff\xff\xff\xff\xf8(w\xe0\xff\xff\xff\xff\xf9\x0f<p\xff\xff\xff\xff\xfa\bY\xe0\xff\xff\xff\xff\xfa\xf8X\xf0\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\xff\xff" +
-	"\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P" +
-	"\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\a0\xc2`\x00\x00\x00\x00\b \xc1p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\n\x00\xa3p\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00" +
-	"\x00\x00\f٢\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13i" +
-	"G\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x00\x00" +
-	"\x00\x00\x1a\xf2\np\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81" +
-	"\x93`\x00\x00\x00\x00\"U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00" +
-	"\x00\x00)\nU\xe0\x00\x00\x00\x00)ޥp\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~" +
-	"Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00" +
-	"\x00\x007\a\r\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb" +
-	"\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00" +
-	"\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\xff\xff\xb5\x94\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\f\xff\xff\xc7\xc0\x01\x10LMT\x00EDT\x00EST\x00EWT\x00EPT\x00\nEST" +
-	"5EDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x1d\xf7\a ,\x06\x00\x00,\x06\x00\x00\x11\x00\x1c\x00America/Go" +
-	"ose_BayUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x98\x00\x00\x00\n\x00\x00\x00!\xff\xff\xff\xff^=<$\xff\xff\xff\xff\x9e\xb8~\x8c\xff\xff\xff\xff\x9f\xba\xd6|\xff\xff\xff\xff\xbe\x9eMl\xff\xff\xff\xff\xc0\xb818\xff\xff\xff\xff\xc1y\xef\xa8\xff\xff" +
-	"\xff\xff\u0098\x138\xff\xff\xff\xff\xc3YѨ\xff\xff\xff\xff\xc4w\xf58\xff\xff\xff\xff\xc59\xb3\xa8\xff\xff\xff\xff\xc6a\x11\xb8\xff\xff\xff\xff\xc7\x19\x95\xa8\xff\xff\xff\xff\xc8@\xf3\xb8\xff\xff\xff\xff\xc9\x02" +
-	"\xb2(\xff\xff\xff\xff\xca ո\xff\xff\xff\xff\xca\xe2\x94(\xff\xff\xff\xff\xcc\x00\xb7\xb8\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xe6\xc8\xff\xff\xff\xffӈD\xd8\xff\xff\xff\xff\xd4J\x03H\xff\xff" +
-	"\xff\xff\xd5h&\xd8\xff\xff\xff\xff\xd6)\xe5H\xff\xff\xff\xff\xd7H\b\xd8\xff\xff\xff\xff\xd8\t\xc7H\xff\xff\xff\xff\xd9'\xea\xd8\xff\xff\xff\xff\xd9\xe9\xa9H\xff\xff\xff\xff\xdb\x11\aX\xff\xff\xff\xff\xdb\xd2" +
-	"\xc5\xc8\xff\xff\xff\xff\xdc\xdetX\xff\xff\xff\xffݩmH\xff\xff\xff\xff\u07beVX\xff\xff\xff\xff߉OH\xff\xff\xff\xff\xe0\x9e8X\xff\xff\xff\xff\xe1i1H\xff\xff\xff\xff\xe2~\x1aX\xff\xff" +
-	"\xff\xff\xe3I\x13H\xff\xff\xff\xff\xe4]\xfcX\xff\xff\xff\xff\xe5(\xf5H\xff\xff\xff\xff\xe6G\x18\xd8\xff\xff\xff\xff\xe7\x12\x11\xc8\xff\xff\xff\xff\xe8&\xfa\xd8\xff\xff\xff\xff\xe8\xf1\xf3\xc8\xff\xff\xff\xff\xea\x06" +
-	"\xdc\xd8\xff\xff\xff\xff\xea\xd1\xd5\xc8\xff\xff\xff\xff\xeb\xe6\xbe\xd8\xff\xff\xff\xff챷\xc8\xff\xff\xff\xff\xedƠ\xd8\xff\xff\xff\xff\ueffeH\xff\xff\xff\xffﯽX\xff\xff\xff\xff\xf0\x9f\xa0H\xff\xff" +
-	"\xff\xff\xf1\x8f\x9fX\xff\xff\xff\xff\xf2\x7f\x82H\xff\xff\xff\xff\xf3o\x81X\xff\xff\xff\xff\xf4_dH\xff\xff\xff\xff\xf5OcX\xff\xff\xff\xff\xf6?FH\xff\xff\xff\xff\xf7/EX\xff\xff\xff\xff\xf8(" +
-	"b\xc8\xff\xff\xff\xff\xf8\xdakX\xff\xff\xff\xff\xf9\x0f.`\xff\xff\xff\xff\xfa\bK\xd0\xff\xff\xff\xff\xfa\xf8J\xe0\xff\xff\xff\xff\xfb\xe8-\xd0\xff\xff\xff\xff\xfc\xd8,\xe0\xff\xff\xff\xff\xfd\xc8\x0f\xd0\xff\xff" +
-	"\xff\xff\xfe\xb8\x0e\xe0\xff\xff\xff\xff\xff\xa7\xf1\xd0\x00\x00\x00\x00\x00\x97\xf0\xe0\x00\x00\x00\x00\x01\x87\xd3\xd0\x00\x00\x00\x00\x02w\xd2\xe0\x00\x00\x00\x00\x03p\xf0P\x00\x00\x00\x00\x04`\xef`\x00\x00\x00\x00\x05P" +
-	"\xd2P\x00\x00\x00\x00\x06@\xd1`\x00\x00\x00\x00\a0\xb4P\x00\x00\x00\x00\b \xb3`\x00\x00\x00\x00\t\x10\x96P\x00\x00\x00\x00\n\x00\x95`\x00\x00\x00\x00\n\xf0xP\x00\x00\x00\x00\v\xe0w`\x00\x00" +
-	"\x00\x00\fٔ\xd0\x00\x00\x00\x00\r\xc0Y`\x00\x00\x00\x00\x0e\xb9v\xd0\x00\x00\x00\x00\x0f\xa9u\xe0\x00\x00\x00\x00\x10\x99X\xd0\x00\x00\x00\x00\x11\x89W\xe0\x00\x00\x00\x00\x12y:\xd0\x00\x00\x00\x00\x13i" +
-	"9\xe0\x00\x00\x00\x00\x14Y\x1c\xd0\x00\x00\x00\x00\x15I\x1b\xe0\x00\x00\x00\x00\x168\xfe\xd0\x00\x00\x00\x00\x17(\xfd\xe0\x00\x00\x00\x00\x18\"\x1bP\x00\x00\x00\x00\x19\b\xdf\xe0\x00\x00\x00\x00\x1a\x01\xfdP\x00\x00" +
-	"\x00\x00\x1a\xf1\xfc`\x00\x00\x00\x00\x1b\xe1\xdfP\x00\x00\x00\x00\x1c\xd1\xde`\x00\x00\x00\x00\x1d\xc1\xc1P\x00\x00\x00\x00\x1e\xb1\xc0`\x00\x00\x00\x00\x1f\xa1\xa3P\x00\x00\x00\x00 u\xd6\xfc\x00\x00\x00\x00!\x81" +
-	"il\x00\x00\x00\x00\"U\xb8\xfc\x00\x00\x00\x00#jw\xdc\x00\x00\x00\x00$5\x9a\xfc\x00\x00\x00\x00%Jg\xec\x00\x00\x00\x00&\x15|\xfc\x00\x00\x00\x00'*I\xec\x00\x00\x00\x00'\xfe\x99|\x00\x00" +
-	"\x00\x00)\n+\xec\x00\x00\x00\x00)\xde{|\x00\x00\x00\x00*\xea\r\xec\x00\x00\x00\x00+\xbe]|\x00\x00\x00\x00,\xd3*l\x00\x00\x00\x00-\x9e?|\x00\x00\x00\x00.\xb3\fl\x00\x00\x00\x00/~" +
-	"!|\x00\x00\x00\x000\x92\xeel\x00\x00\x00\x001g=\xfc\x00\x00\x00\x002r\xd0l\x00\x00\x00\x003G\x1f\xfc\x00\x00\x00\x004R\xb2l\x00\x00\x00\x005'\x01\xfc\x00\x00\x00\x0062\x94l\x00\x00" +
-	"\x00\x007\x06\xe3\xfc\x00\x00\x00\x008\x1b\xb0\xec\x00\x00\x00\x008\xe6\xc5\xfc\x00\x00\x00\x009\xfb\x92\xec\x00\x00\x00\x00:Ƨ\xfc\x00\x00\x00\x00;\xdbt\xec\x00\x00\x00\x00<\xaf\xc4|\x00\x00\x00\x00=\xbb" +
-	"V\xec\x00\x00\x00\x00>\x8f\xa6|\x00\x00\x00\x00?\x9b8\xec\x00\x00\x00\x00@o\x88|\x00\x00\x00\x00A\x84Ul\x00\x00\x00\x00BOj|\x00\x00\x00\x00Cd7l\x00\x00\x00\x00D/L|\x00\x00" +
-	"\x00\x00ED\x19l\x00\x00\x00\x00E\xf3~\xfc\x00\x00\x00\x00G-5\xec\x00\x00\x00\x00G\xd3`\xfc\x00\x00\x00\x00I\r\x17\xec\x00\x00\x00\x00I\xb3B\xfc\x00\x00\x00\x00J\xec\xf9\xec\x00\x00\x00\x00K\x9c" +
-	"_|\x00\x00\x00\x00L\xd6\x16l\x00\x00\x00\x00M|A|\x00\x00\x00\x00N\xb6\x14P\x01\x02\x01\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x06\x05\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" +
-	"\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b" +
-	"\a\b\a\b\a\b\a\b\a\b\t\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\xff\xff" +
-	"\xc7\\\x00\x00\xff\xffΔ\x00\x04\xff\xffܤ\x01\b\xff\xff\xce\xc8\x00\x04\xff\xff\xdc\xd8\x01\b\xff\xff\xdc\xd8\x01\f\xff\xff\xdc\xd8\x01\x10\xff\xff\xd5\xd0\x01\x14\xff\xff\xc7\xc0\x00\x18\xff\xff\xe3\xe0\x01\x1cLM" +
-	"T\x00NST\x00NDT\x00NPT\x00NWT\x00ADT\x00AST\x00ADDT\x00\nAST4ADT,M3.2.0,M11.1.0\nPK\x03\x04\n" +
-	"\x00\x00\x00\x00\x00\x8fj\xbeT\x9d?\xdfڸ\x03\x00\x00\xb8\x03\x00\x00\x11\x00\x1c\x00America/Sao_PauloUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01" +
-	"\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" +
-	"\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00[\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaar\xb4\xff\xff\xff\xff\xb8\x0fI" +
-	"\xe0\xff\xff\xff\xff\xb8\xfd@\xa0\xff\xff\xff\xff\xb9\xf140\xff\xff\xff\xff\xba\xdet \xff\xff\xff\xff\xda8\xae0\xff\xff\xff\xff\xda\xeb\xfa0\xff\xff\xff\xff\xdc\x19\xe1\xb0\xff\xff\xff\xffܹY \xff\xff\xff" +
-	"\xff\xdd\xfb\x150\xff\xff\xff\xffޛ\xde \xff\xff\xff\xff\xdfݚ0\xff\xff\xff\xff\xe0T3 \xff\xff\xff\xff\xf4Z\t0\xff\xff\xff\xff\xf5\x05^ \xff\xff\xff\xff\xf6\xc0d0\xff\xff\xff\xff\xf7\x0e\x1e" +
-	"\xa0\xff\xff\xff\xff\xf8Q,0\xff\xff\xff\xff\xf8\xc7\xc5 \xff\xff\xff\xff\xfa\nҰ\xff\xff\xff\xff\xfa\xa8\xf8\xa0\xff\xff\xff\xff\xfb\xec\x060\xff\xff\xff\xff\xfc\x8b}\xa0\x00\x00\x00\x00\x1dɎ0\x00\x00\x00" +
-	"\x00\x1exנ\x00\x00\x00\x00\x1f\xa05\xb0\x00\x00\x00\x00 3Ϡ\x00\x00\x00\x00!\x81i0\x00\x00\x00\x00\"\vȠ\x00\x00\x00\x00#X\x10\xb0\x00\x00\x00\x00#\xe2p \x00\x00\x00\x00%7\xf2" +
-	"\xb0\x00\x00\x00\x00%\xd4\xc7 \x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xbd\xe3\xa0\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\x94\x8b \x00\x00\x00\x00*\xea\r\xb0\x00\x00\x00\x00+k2\xa0\x00\x00\x00" +
-	"\x00,\xc0\xb50\x00\x00\x00\x00-f\xc4 \x00\x00\x00\x00.\xa0\x970\x00\x00\x00\x00/F\xa6 \x00\x00\x00\x000\x80y0\x00\x00\x00\x001\x1dM\xa0\x00\x00\x00\x002W \xb0\x00\x00\x00\x003\x06j" +
-	" \x00\x00\x00\x0048T0\x00\x00\x00\x004\xf8\xc1 \x00\x00\x00\x006 \x1f0\x00\x00\x00\x006\xcfh\xa0\x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xb8\x85 \x00\x00\x00\x009\xdf\xe30\x00\x00\x00" +
-	"\x00:\x8f,\xa0\x00\x00\x00\x00;\xc8\xff\xb0\x00\x00\x00\x00<o\x0e\xa0\x00\x00\x00\x00=đ0\x00\x00\x00\x00>N\xf0\xa0\x00\x00\x00\x00?\x91\xfe0\x00\x00\x00\x00@.Ҡ\x00\x00\x00\x00A\x86\xf8" +
-	"0\x00\x00\x00\x00B\x17\xef \x00\x00\x00\x00CQ\xc20\x00\x00\x00\x00C\xf7\xd1 \x00\x00\x00\x00EMS\xb0\x00\x00\x00\x00E\xe0\xed\xa0\x00\x00\x00\x00G\x11\x860\x00\x00\x00\x00G\xb7\x95 \x00\x00\x00" +
-	"\x00H\xfa\xa2\xb0\x00\x00\x00\x00I\x97w \x00\x00\x00\x00Jڄ\xb0\x00\x00\x00\x00K\x80\x93\xa0\x00\x00\x00\x00L\xbaf\xb0\x00\x00\x00\x00M`u\xa0\x00\x00\x00\x00N\x9aH\xb0\x00\x00\x00\x00OI\x92" +
-	" \x00\x00\x00\x00P\x83e0\x00\x00\x00\x00Q 9\xa0\x00\x00\x00\x00RcG0\x00\x00\x00\x00S\x00\x1b\xa0\x00\x00\x00\x00TC)0\x00\x00\x00\x00T\xe98 \x00\x00\x00\x00V#\v0\x00\x00\x00" +
-	"\x00V\xc9\x1a \x00\x00\x00\x00X\x02\xed0\x00\x00\x00\x00X\xa8\xfc \x00\x00\x00\x00Y\xe2\xcf0\x00\x00\x00\x00Z\x88\xde \x00\x00\x00\x00[\xde`\xb0\x00\x00\x00\x00\\h\xc0 \x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xd4L\x00\x00\xff\xff\xe3\xe0\x01\x04\xff\xff\xd5\xd0\x00\bLMT\x00-02\x00-03\x00\n<-03>" +
-	"3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTq\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x14\x00\x1c\x00America/Blanc-SablonUT\t\x00\x03\xdd\xfc\x94" +
-	"b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" +
-	"\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz" +
-	"敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00A" +
-	"ST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTø\xab\x9b\xf0\x00\x00\x00\xf0\x00\x00\x00\x0f\x00\x1c\x00America/Phoen" +
-	"ixUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00" +
-	"\x04\x00\x00\x00\x10\xff\xff\xff\xff^\x04\f\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xcf\x17\xdf" +
-	"\x1c\xff\xff\xff\xffϏ\xe5\xac\xff\xff\xff\xffЁ\x1a\x1c\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\x02\x01\x02\x01\x02\x03\x02\x03\x02\x01\x02\xff\xff\x96\xee\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90" +
-	"\x00\b\xff\xff\xab\xa0\x01\fLMT\x00MDT\x00MST\x00MWT\x00\nMST7\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTԾ\xe7#\x95\x00\x00\x00\x95\x00\x00\x00\x10\x00\x1c\x00" +
-	"America/AtikokanUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xffi\x87&\x10\xff\xff\xff\xff\x8b\xf4a\xe8\x01\x02\xff\xff\xb5p\x00\x00\xff\xff\xb5\x18\x00\x04\xff\xff\xb9\xb0\x00\bLMT\x00C" +
-	"MT\x00EST\x00\nEST5\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xa1'\a\xbd\x97\x00\x00\x00\x97\x00\x00\x00\x0f\x00\x1c\x00America/CayenneUT" +
-	"\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00" +
-	"\f\xff\xff\xff\xff\x91\xf4+\x90\xff\xff\xff\xff\xfb\xc35\xc0\x01\x02\xff\xff\xce\xf0\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x00\bLMT\x00-04\x00-03\x00\n<-03>3\nPK\x03" +
-	"\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe90T\x16\xd1\x01\x00\x00\xd1\x01\x00\x00\f\x00\x1c\x00America/NuukUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1" +
-	"\b\x00\x04S_\x01\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZ" +
-	"if3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\"\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x9b\x80h\x00\x00\x00\x00\x00\x13M|P\x00\x00" +
-	"\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1a\xc3" +
-	"\x91\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00" +
-	"\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5" +
-	"%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00" +
-	"\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xffπ\x00\x00\xff\xff\xd5\xd0\x00\x04" +
-	"\xff\xff\xe3\xe0\x01\bLMT\x00-03\x00-02\x00\n<-03>3<-02>,M3.5.0/-2,M10.5.0/-1\nPK\x03\x04\n\x00\x00\x00" +
-	"\x00\x00\x8fj\xbeT\xd0v\x01\x8a\x01\x04\x00\x00\x01\x04\x00\x00\x14\x00\x1c\x00America/Santa_IsabelUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01" +
-	"\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" +
-	"\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00^\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff\xa5\xb6\xf6\x80\xff\xff\xff\xff\xa9yO" +
-	"p\xff\xff\xff\xff\xaf\xf2|\xf0\xff\xff\xff\xff\xb6fdp\xff\xff\xff\xff\xb7\x1b\x10\x00\xff\xff\xff\xff\xb8\n\xf2\xf0\xff\xff\xff\xff\xcbꍀ\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xffҙ\xbap\xff\xff\xff" +
-	"\xff\xd7\x1bY\x00\xff\xff\xff\xffؑ\xb4\xf0\xff\xff\xff\xff\xe2~K\x90\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4^-\x90\xff\xff\xff\xff\xe5)4\x90\xff\xff\xff\xff\xe6GJ\x10\xff\xff\xff\xff\xe7\x12Q" +
-	"\x10\xff\xff\xff\xff\xe8',\x10\xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff\xff\xea\a\x0e\x10\xff\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff\xff\xeb\xe6\xf0\x10\xff\xff\xff\xff\xec\xb1\xf7\x10\xff\xff\xff\xff\xed\xc6\xd2\x10\xff\xff\xff" +
-	"\xff\xee\x91\xd9\x10\x00\x00\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90" +
-	" \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00" +
-	"\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1\xdb" +
-	"\x90\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\"V\r \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00" +
-	"\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\n\x80\x10\x00\x00\x00\x00)\xdeϠ\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93" +
-	"\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00" +
-	"\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\a8 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9" +
-	"\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00" +
-	"\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00F\x0f\x82\xa0\x00\x00\x00\x00G$O\x90\x00\x00\x00\x00G\xf8\x9f \x00\x00\x00\x00I\x041\x90\x00\x00\x00\x00I\u0601" +
-	" \x00\x00\x00\x00J\xe4\x13\x90\x00\x00\x00\x00K\x9c\xb3\xa0\x01\x02\x01\x02\x03\x02\x04\x05\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\x92L\x00\x00\xff\xff\x9d" +
-	"\x90\x00\x04\xff\xff\x8f\x80\x00\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10\xff\xff\x9d\x90\x01\x14LMT\x00MST\x00PST\x00PDT\x00PWT\x00PPT\x00\nPST8PDT," +
-	"M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xf8Dz\x97\xae\x01\x00\x00\xae\x01\x00\x00\x11\x00\x1c\x00America/Boa_Vis" +
-	"taUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00!\x00\x00\x00" +
-	"\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaa\x7f\xe0\xff\xff\xff\xff\xb8\x0fW\xf0\xff\xff\xff\xff\xb8\xfdN\xb0\xff\xff\xff\xff\xb9\xf1B@\xff\xff\xff\xff\xbaނ0\xff\xff\xff\xff\xda8\xbc@\xff\xff\xff\xff\xda\xec\b" +
-	"@\xff\xff\xff\xff\xdc\x19\xef\xc0\xff\xff\xff\xffܹg0\xff\xff\xff\xff\xdd\xfb#@\xff\xff\xff\xffޛ\xec0\xff\xff\xff\xff\xdfݨ@\xff\xff\xff\xff\xe0TA0\xff\xff\xff\xff\xf4\x98\r\xc0\xff\xff\xff" +
-	"\xff\xf5\x05l0\xff\xff\xff\xff\xf6\xc0r@\xff\xff\xff\xff\xf7\x0e,\xb0\xff\xff\xff\xff\xf8Q:@\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xfa\n\xe0\xc0\xff\xff\xff\xff\xfa\xa9\x06\xb0\xff\xff\xff\xff\xfb\xec\x14" +
-	"@\xff\xff\xff\xff\xfc\x8b\x8b\xb0\x00\x00\x00\x00\x1dɜ@\x00\x00\x00\x00\x1ex\xe5\xb0\x00\x00\x00\x00\x1f\xa0C\xc0\x00\x00\x00\x00 3ݰ\x00\x00\x00\x00!\x81w@\x00\x00\x00\x00\"\vְ\x00\x00\x00" +
-	"\x007\xf6\xd4\xc0\x00\x00\x00\x008\xb8\x930\x00\x00\x00\x009\xdf\xf1@\x00\x00\x00\x009\xe9\x1d\xb0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\xff\xff\xc7 \x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\bLMT\x00-03\x00-04\x00\n<-04>4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x8f\x19Ԇ\x12\x02" +
-	"\x00\x00\x12\x02\x00\x00\x16\x00\x1c\x00America/Bahia_BanderasUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00" +
-	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6fV`\xff" +
-	"\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff\xb8\f6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\xff\xff\xff\xff\xcb\xeaq`\xff\xff\xff\xffؑ\xb4\xf0\x00\x00\x00\x00\x00\x00p\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002" +
-	"s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00" +
-	"\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xf5\x12\x90\x00\x00\x00\x00;\xb6\xd1\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@" +
-	"oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00F\x0ft\x90\x00\x00\x00\x00G$A\x80\x00" +
-	"\x00\x00\x00G\xf8\x91\x10\x00\x00\x00\x00I\x04#\x80\x00\x00\x00\x00I\xd8s\x10\x00\x00\x00\x00J\xe4\x05\x80\x00\x00\x00\x00K\xb8U\x10\x00\x00\x00\x00L\xcd\x13\xf0\x01\x02\x01\x02\x01\x02\x01\x03\x01\x04\x01\x04\x01" +
-	"\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x05\x02\xff\xff\x9dT\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\x8f\x80\x00\f\xff\xff\xab\xa0\x01\x10\xff\xff\xb9\xb0" +
-	"\x01\x14LMT\x00MST\x00CST\x00PST\x00MDT\x00CDT\x00\nCST6CDT,M4.1.0,M10.5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00" +
-	"\x8fj\xbeT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x1c\x00America/Indiana/UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04" +
-	"S_\x01\x00PK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT \x17\x89}q\x01\x00\x00q\x01\x00\x00\x15\x00\x1c\x00America/Indiana/VevayUT\t\x00\x03" +
-	"\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\a\x00\x00\x00\x1c\xff\xff" +
-	"\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a" +
-	"\t\xf0\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00" +
-	"\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x03\x04\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff" +
-	"\xb0@\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18LMT\x00CDT\x00CST\x00CWT\x00CPT\x00" +
-	"EST\x00EDT\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTp\xb6{\xc9\x13\x02\x00\x00\x13\x02\x00\x00\x1c\x00" +
-	"\x1c\x00America/Indiana/IndianapolisUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZ" +
-	"if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&\x00\x00\x00\a\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff" +
-	"\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xcaW\"\x80\xff\xff\xff\xff\xca\xd8Gp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd3u\xf3" +
-	"\x00\xff\xff\xff\xff\xd4@\xeb\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff" +
-	"\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90p\xff\xff\xff\xff\u07bey\x80\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iT" +
-	"p\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00" +
-	"\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x05\x02\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xaf:\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18LMT" +
-	"\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00EDT\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8f" +
-	"j\xbeTK-E\xfad\x02\x00\x00d\x02\x00\x00\x17\x00\x1c\x00America/Indiana/WinamacUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01" +
-	"\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" +
-	"\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00/\x00\x00\x00\a\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6," +
-	"\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd3u\xf3\x00\xff\xff\xff" +
-	"\xff\xd4@\xeb\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xda\xfe\xb5" +
-	"\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90p\xff\xff\xff\xff\u07bey\x80\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff" +
-	"\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5W<\xf0\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe77\x1e\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16" +
-	"\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xb1\xda\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\ue47c\xf0\xff\xff\xff\xff\xef\xaf\xe0\x80\xff\xff\xff" +
-	"\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x00\x00\x00\x00G-_" +
-	"\xe0\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x06\x05\x06\x05\x01\x02\x06\x05\xff\xff\xae\xcf\x00\x00\xff\xff\xb9\xb0\x01\x04" +
-	"\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00EDT\x00\nE" +
-	"ST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTصK\xa6\n\x02\x00\x00\n\x02\x00\x00\x19\x00\x1c\x00America/" +
-	"Indiana/Tell_CityUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00%\x00\x00\x00\a\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp" +
-	"\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xe4g=\xe0\xff\xff\xff\xff\xe5)\x18p\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe7\x124\xf0\xff\xff\xff\xff" +
-	"\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xb1\xda\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\ue47c\xf0" +
-	"\xff\xff\xff\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xf0\x9f\xc3p\xff\xff\xff\xff\xf1\x8f\u0080\xff\xff\xff\xff\xf2\x7f\xa5p\xff\xff\xff\xff\xf3o\xa4\x80\xff\xff\xff\xff\xf4_\x87p\xff\xff\xff\xff\xf5O\x86\x80\xff\xff\xff\xff" +
-	"\xfb\xe8I\xf0\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8+\xf0\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00D/vp" +
-	"\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x02\x01\x02\x06\x05\x06\x05\x01\x02\x01\xff\xff\xae\xa9\x00\x00\xff" +
-	"\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00E" +
-	"DT\x00\nCST6CDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x01\xd8N\x8c\xab\x02\x00\x00\xab\x02\x00\x00\x1a\x00\x1c\x00Ame" +
-	"rica/Indiana/PetersburgUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00&\x00\x00\x00\a\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xca" +
+	"W\"\x80\xff\xff\xff\xff\xca\xd8Gp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd3u\xf3\x00\xff\xff\xff\xff\xd4@\xeb\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff" +
+	"\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdc" +
+	"ޗ\x80\xff\xff\xff\xffݩ\x90p\xff\xff\xff\xff\u07bey\x80\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff" +
+	"\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00D" +
+	"/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x02\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xaf" +
+	":\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18LMT\x00CDT\x00CST\x00CWT\x00CPT\x00E" +
+	"ST\x00EDT\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$ \x873\xf8\x03\x00\x00\xf8\x03\x00\x00\x14\x00\x00" +
+	"\x00America/Indiana/KnoxTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff" +
+	"^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0" +
+	"\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff" +
+	"\xdb\xc0s\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90p\xff\xff\xff\xff\u07bey\x80\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80" +
+	"\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5W<\xf0\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe77\x1e\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff" +
+	"\xea\a\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xd6\xc4\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\xee\xbf\xe1p\xff\xff\xff\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xf0\x9f\xc3p" +
+	"\xff\xff\xff\xff\xf1\x8f\u0080\xff\xff\xff\xff\xf4_\x87p\xff\xff\xff\xff\xfa\xf8g\x00\xff\xff\xff\xff\xfb\xe8I\xf0\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8+\xf0\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff" +
+	"\xff\xa8\r\xf0\x00\x00\x00\x00\x00\x98\r\x00\x00\x00\x00\x00\x01\x87\xef\xf0\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\fp\x00\x00\x00\x00\x04a\v\x80\x00\x00\x00\x00\x05P\xeep\x00\x00\x00\x00\x06@\xed\x80" +
+	"\x00\x00\x00\x00\a0\xd0p\x00\x00\x00\x00\a\x8d'\x80\x00\x00\x00\x00\t\x10\xb2p\x00\x00\x00\x00\t\xad\xa3\x00\x00\x00\x00\x00\n\xf0\x94p\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00\x00\x00\fٰ\xf0\x00\x00\x00\x00" +
+	"\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99t\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0" +
+	"\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\"7p\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00" +
+	"\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1܀\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\"U\xf1\x00" +
+	"\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)\nc\xf0\x00\x00\x00\x00" +
+	"D/vp\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x05\x01\x02\x01\xff\xff\xae\xca\x00\x00\xff" +
+	"\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00\nCST6CD" +
+	"T,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00M/U\x9f7\x02\x00\x007\x02\x00\x00\x17\x00\x00\x00America/India" +
+	"na/MarengoTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" +
+	"\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\x00\x00\x00\a\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6," +
+	"\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff" +
+	"\xffݩ\x90p\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5)\x18p\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe7\x124\xf0\xff\xff\xff\xff\xe8'\x1e" +
+	"\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xb1\xda\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\ue47c\xf0\xff\xff\xff" +
+	"\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfd" +
+	"p\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\a0\xc2`\x00\x00\x00\x00\a\x8d\x19p\x00\x00\x00\x00\t\x10\xb2p\x00\x00\x00\x00\t\xad\x94\xf0\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00" +
+	"\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x01\x05\x06\x05" +
+	"\x06\x05\x06\xff\xff\xaf\r\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18LMT\x00CDT\x00CST\x00CWT" +
+	"\x00CPT\x00EST\x00EDT\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xd8N\x8c\xab\x02\x00\x00\xab" +
+	"\x02\x00\x00\x1a\x00\x00\x00America/Indiana/PetersburgTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x008" +
+	"\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff" +
+	"\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xe4g=\xe0\xff\xff\xff\xff\xe5)\x18p\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe7\x124\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0" +
+	"\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xb1\xda\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\ue47c\xf0\xff\xff\xff\xff\xef\xaf\xe0\x80\xff\xff\xff\xff" +
+	"\xf0\x9f\xc3p\xff\xff\xff\xff\xf1\x8f\u0080\xff\xff\xff\xff\xf2\x7f\xa5p\xff\xff\xff\xff\xf3o\xa4\x80\xff\xff\xff\xff\xf4_\x87p\xff\xff\xff\xff\xf5O\x86\x80\xff\xff\xff\xff\xf6?ip\xff\xff\xff\xff\xf7/h\x80" +
+	"\xff\xff\xff\xff\xfa\bg\xf0\xff\xff\xff\xff\xfa\xf8g\x00\xff\xff\xff\xff\xfb\xe8I\xf0\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8+\xf0\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\r\xf0\x00\x00\x00\x00" +
+	"\x00\x98\r\x00\x00\x00\x00\x00\x01\x87\xef\xf0\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\fp\x00\x00\x00\x00\x04a\v\x80\x00\x00\x00\x00\x05P\xeep\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\a0\xd0p" +
+	"\x00\x00\x00\x00\a\x8d'\x80\x00\x00\x00\x00\t\x10\xb2p\x00\x00\x00\x00\t\xad\xa3\x00\x00\x00\x00\x00\n\xf0\x94p\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00\x00\x00\fٰ\xf0\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00" +
+	"\x0e\xb9\x92\xf0\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x00\x00\x00\x00G-m\xf0\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x05\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x05\x01\x02\x01\x05\xff\xff\xae-\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0" +
+	"\x01\x10\xff\xff\xb9\xb0\x00\x14LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03\x04" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00صK\xa6\n\x02\x00\x00\n\x02\x00\x00\x19\x00\x00\x00America/Indiana/Tell_CityTZif2\x00\x00\x00\x00" +
 	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x008\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00%\x00\x00\x00\a\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff" +
 	"\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xe4g=\xe0\xff\xff\xff\xff\xe5)\x18p\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe7\x12" +
 	"4\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xb1\xda\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff" +
 	"\xff\xff\ue47c\xf0\xff\xff\xff\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xf0\x9f\xc3p\xff\xff\xff\xff\xf1\x8f\u0080\xff\xff\xff\xff\xf2\x7f\xa5p\xff\xff\xff\xff\xf3o\xa4\x80\xff\xff\xff\xff\xf4_\x87p\xff\xff\xff\xff\xf5O" +
-	"\x86\x80\xff\xff\xff\xff\xf6?ip\xff\xff\xff\xff\xf7/h\x80\xff\xff\xff\xff\xfa\bg\xf0\xff\xff\xff\xff\xfa\xf8g\x00\xff\xff\xff\xff\xfb\xe8I\xf0\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8+\xf0\xff\xff" +
-	"\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\r\xf0\x00\x00\x00\x00\x00\x98\r\x00\x00\x00\x00\x00\x01\x87\xef\xf0\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\fp\x00\x00\x00\x00\x04a\v\x80\x00\x00\x00\x00\x05P" +
-	"\xeep\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\a0\xd0p\x00\x00\x00\x00\a\x8d'\x80\x00\x00\x00\x00\t\x10\xb2p\x00\x00\x00\x00\t\xad\xa3\x00\x00\x00\x00\x00\n\xf0\x94p\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00" +
-	"\x00\x00\fٰ\xf0\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x00\x00\x00\x00G-m\xf0\x02\x01\x02\x01\x02\x03" +
-	"\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x05\x01\x02\x01\x05\xff\xff\xae-\x00\x00\xff\xff\xb9\xb0" +
-	"\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00\nEST5EDT,M" +
-	"3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\r\xedsp.\x02\x00\x00.\x02\x00\x00\x19\x00\x1c\x00America/Indiana/" +
-	"VincennesUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00)\x00\x00\x00\a\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xffˈ\xfe\x80" +
-	"\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd3u\xf3\x00\xff\xff\xff\xff\xd4@\xeb\xf0\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff" +
-	"\xe3I6p\xff\xff\xff\xff\xe4g=\xe0\xff\xff\xff\xff\xe5)\x18p\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe7\x124\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00" +
-	"\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xb1\xda\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\xee\xbf\xe1p\xff\xff\xff\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xf0q\x9e\xf0\xff\xff\xff\xff" +
-	"\xf1\x8f\u0080\xff\xff\xff\xff\xf2\x7f\xa5p\xff\xff\xff\xff\xf3o\xa4\x80\xff\xff\xff\xff\xf4_\x87p\xff\xff\xff\xff\xf5O\x86\x80\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0" +
-	"\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x00\x00\x00\x00G-m\xf0\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x06\x05\x06\x05\x01\x02\x01\x05\xff\xff\xad\xf1\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7" +
-	"\xc0\x01\x18LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00EDT\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\n" +
-	"\x00\x00\x00\x00\x00\x8fj\xbeT$ \x873\xf8\x03\x00\x00\xf8\x03\x00\x00\x14\x00\x1c\x00America/Indiana/KnoxUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux" +
-	"\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00" +
-	"\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff" +
-	"\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd5U\xd5\x00" +
+	"\x86\x80\xff\xff\xff\xff\xfb\xe8I\xf0\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8+\xf0\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00" +
+	"\x00\x00D/vp\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x02\x01\x02\x06\x05\x06\x05\x01\x02\x01\xff" +
+	"\xff\xae\xa9\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18LMT\x00CDT\x00CST\x00CWT\x00CPT" +
+	"\x00EST\x00EDT\x00\nCST6CDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x17\x89}q\x01\x00\x00q\x01\x00\x00\x15" +
+	"\x00\x00\x00America/Indiana/VevayTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\a\x00\x00\x00\x1c\xff" +
+	"\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2" +
+	"a\t\xf0\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00" +
+	"\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x03\x04\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\xff" +
+	"\xff\xb0@\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18LMT\x00CDT\x00CST\x00CWT\x00CPT" +
+	"\x00EST\x00EDT\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r\xedsp.\x02\x00\x00.\x02\x00\x00\x19" +
+	"\x00\x00\x00America/Indiana/VincennesTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)\x00\x00\x00\a\x00" +
+	"\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff" +
+	"\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd3u\xf3\x00\xff\xff\xff\xff\xd4@\xeb\xf0\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4" +
+	"g=\xe0\xff\xff\xff\xff\xe5)\x18p\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe7\x124\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff" +
+	"\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xb1\xda\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\xee\xbf\xe1p\xff\xff\xff\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xf0q\x9e\xf0\xff\xff\xff\xff\xf1\x8f\u0080\xff\xff\xff\xff\xf2" +
+	"\x7f\xa5p\xff\xff\xff\xff\xf3o\xa4\x80\xff\xff\xff\xff\xf4_\x87p\xff\xff\xff\xff\xf5O\x86\x80\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00" +
+	"\x00\x00\x00D/vp\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x00\x00\x00\x00G-m\xf0\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x05\x06\x05\x06\x05\x01\x02\x01\x05\xff\xff\xad\xf1\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18LMT\x00CD" +
+	"T\x00CST\x00CWT\x00CPT\x00EST\x00EDT\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"K-E\xfad\x02\x00\x00d\x02\x00\x00\x17\x00\x00\x00America/Indiana/WinamacTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00/\x00\x00\x00\a\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xffˈ" +
+	"\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd3u\xf3\x00\xff\xff\xff\xff\xd4@\xeb\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff" +
+	"\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90p\xff\xff\xff\xff\u07be" +
+	"y\x80\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5W<\xf0\xff\xff" +
+	"\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe77\x1e\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xb1" +
+	"\xda\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\ue47c\xf0\xff\xff\xff\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00" +
+	"\x00\x00D/vp\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x00\x00\x00\x00G-_\xe0\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x05\x06\x05\x06\x05\x01\x02\x06\x05\xff\xff\xae\xcf\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18L" +
+	"MT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00EDT\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00p\xb6{\xc9\x13\x02\x00\x00\x13\x02\x00\x00\x14\x00\x00\x00America/IndianapolisTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00&\x00\x00\x00\a\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff" +
+	"\xcaW\"\x80\xff\xff\xff\xff\xca\xd8Gp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd3u\xf3\x00\xff\xff\xff\xff\xd4@\xeb\xf0\xff\xff\xff\xff\xd5U\xd5\x00" +
 	"\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff" +
 	"\xdcޗ\x80\xff\xff\xff\xffݩ\x90p\xff\xff\xff\xff\u07bey\x80\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p" +
-	"\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5W<\xf0\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe77\x1e\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff" +
-	"\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xd6\xc4\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\xee\xbf\xe1p\xff\xff\xff\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xf0\x9f\xc3p\xff\xff\xff\xff\xf1\x8f\u0080" +
-	"\xff\xff\xff\xff\xf4_\x87p\xff\xff\xff\xff\xfa\xf8g\x00\xff\xff\xff\xff\xfb\xe8I\xf0\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8+\xf0\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\r\xf0\x00\x00\x00\x00" +
-	"\x00\x98\r\x00\x00\x00\x00\x00\x01\x87\xef\xf0\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\fp\x00\x00\x00\x00\x04a\v\x80\x00\x00\x00\x00\x05P\xeep\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\a0\xd0p" +
-	"\x00\x00\x00\x00\a\x8d'\x80\x00\x00\x00\x00\t\x10\xb2p\x00\x00\x00\x00\t\xad\xa3\x00\x00\x00\x00\x00\n\xf0\x94p\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00\x00\x00\fٰ\xf0\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00" +
-	"\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99t\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00" +
-	"\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\"7p\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00" +
-	"\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1܀\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0" +
-	"\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)\nc\xf0\x00\x00\x00\x00D/vp\x00\x00\x00\x00" +
-	"EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x05\x01\x02\x01\xff\xff\xae\xca\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab" +
-	"\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00\nCST6CDT,M3.2.0" +
-	",M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTM/U\x9f7\x02\x00\x007\x02\x00\x00\x17\x00\x1c\x00America/Indiana/Maren" +
-	"goUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\x00\x00\x00" +
-	"\a\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4" +
-	"p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90p\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5)\x18p\xff\xff\xff" +
-	"\xff\xe6G<\x00\xff\xff\xff\xff\xe7\x124\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xb1\xda" +
-	"\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\ue47c\xf0\xff\xff\xff\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00" +
-	"\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\a0\xc2`\x00\x00\x00\x00\a\x8d\x19p\x00\x00\x00\x00\t\x10\xb2" +
-	"p\x00\x00\x00\x00\t\xad\x94\xf0\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x01\x05\x06\x05\x06\x05\x06\xff\xff\xaf\r\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff" +
-	"\xff\xc7\xc0\x01\x18LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00EDT\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03" +
-	"\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTp\xb6{\xc9\x13\x02\x00\x00\x13\x02\x00\x00\x14\x00\x1c\x00America/IndianapolisUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94b" +
-	"ux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00" +
-	"\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&\x00\x00\x00\a\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff" +
-	"\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xcaW\"\x80\xff\xff\xff\xff\xca\xd8Gp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#" +
-	"\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd3u\xf3\x00\xff\xff\xff\xff\xd4@\xeb\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff" +
-	"\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90p\xff\xff\xff\xff\u07bey\x80\xff\xff\xff\xff߉" +
-	"rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff" +
-	"\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x01" +
-	"\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x02\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xaf:\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0" +
-	"\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00EDT\x00\nEST5EDT,M3.2.0,M1" +
-	"1.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTq\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x1c\x00America/DominicaUT\t\x00\x03\xdd\xfc\x94" +
-	"b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" +
-	"\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz" +
-	"敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00A" +
-	"ST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12\x00\x1c\x00America/Argen" +
-	"tina/UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTt*\x9b!\xb2\x02\x00\x00\xb2\x02\x00\x00\x17" +
-	"\x00\x1c\x00America/Argentina/SaltaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00;\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xae\xd4\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1a\xc9" +
-	"\xb0\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff" +
-	"\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04" +
-	"@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff" +
-	"\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6\xe6\x9f" +
-	"\xb0\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff" +
-	"\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v" +
-	"\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00" +
-	"\x008\xbf*\xb0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
-	"\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x04\x05\xff\xff¬\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00" +
-	"CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x8b}\xb6\x1e\xc4\x02\x00\x00\xc4\x02\x00\x00\x19\x00\x1c\x00Americ" +
-	"a/Argentina/UshuaiaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xb1\x88\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e" +
-	"\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff" +
-	"\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe" +
-	"*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff" +
-	"\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13" +
-	"C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff" +
-	"\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!" +
-	"\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00" +
-	"\x00\x00@\xb9N0\x00\x00\x00\x00@\xd5\v\xc0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\xff\xff\xbf\xf8\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01" +
-	"\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTR\xc8\xd9\xf6\xc4\x02\x00\x00\xc4\x02\x00" +
-	"\x00\x1b\x00\x1c\x00America/Argentina/CatamarcaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00" +
-	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xaf,\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff" +
-	"\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd" +
-	"\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff" +
-	"\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xce" +
-	"M\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff" +
-	"\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd" +
-	"\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00" +
-	"\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007" +
-	"\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xbb\xf10\x00\x00\x00\x00@\xd5\v\xc0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
-	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\xff\xff\xc2T\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0" +
-	"\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj" +
-	"\xbeTR\xc8\xd9\xf6\xc4\x02\x00\x00\xc4\x02\x00\x00 \x00\x1c\x00America/Argentina/ComodRivadaviaUT\t\x00\x03\xdd\xfc\x94b\xdd" +
-	"\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00" +
-	"\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xaf" +
-	",\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff" +
-	"\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc3" +
-	"0\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff" +
-	"\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6" +
-	"\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff" +
-	"\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5" +
-	"\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00" +
-	"\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xbb\xf10\x00\x00\x00\x00@\xd5\v\xc0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f" +
-	" \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x02\x05" +
-	"\x04\x05\xff\xff\xc2T\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<" +
-	"-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xfcz=\xe1\xcd\x02\x00\x00\xcd\x02\x00\x00\x1a\x00\x1c\x00America/Argentina/San_Ju" +
-	"anUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x00\x00\x00" +
-	"\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xb1\xbc\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}" +
-	"\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff" +
-	"\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf" +
-	"0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff" +
-	"\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w" +
-	"@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00" +
-	"\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'͵\xa0\x00\x00\x00\x00(&&" +
-	"@\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xba\x9f\xb0\x00\x00\x00" +
-	"\x00A\x030@\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
-	"\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x05\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\xff\xff\xbf\xc4\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fL" +
-	"MT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x1c\x80\xb9\\\xcd\x02\x00\x00\xcd\x02\x00\x00\x1a\x00\x1c\x00Ame" +
-	"rica/Argentina/San_LuisUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xaf\xb4\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff" +
-	"\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex" +
-	"\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff" +
-	"\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ" +
-	"\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff" +
-	"\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c" +
-	"50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xfd\xa5\xa0\x00\x00" +
-	"\x00\x00'\x194@\x00\x00\x00\x00'\xcdð\x00\x00\x00\x00(G\x1b\xc0\x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xba\x9f\xb0\x00\x00\x00\x00A\x030@\x00\x00\x00\x00Gw" +
-	"\t\xb0\x00\x00\x00\x00G\x93\xfc\xa0\x00\x00\x00\x00G\xd3R\xb0\x00\x00\x00\x00H\xf1v@\x00\x00\x00\x00I\xb34\xb0\x00\x00\x00\x00J\xd1X@\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x02\x03\x02\x05\x03\x05\x02\x05\x04\x03\x02\x03\x02\x05\xff\xff\xc1\xcc\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0" +
-	"\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj" +
-	"\xbeT\x8ep\xb4c\xc4\x02\x00\x00\xc4\x02\x00\x00\x1e\x00\x1c\x00America/Argentina/Rio_GallegosUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94" +
-	"bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01" +
-	"\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xb2d\xff" +
-	"\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb" +
-	"\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff" +
-	"\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xca" +
-	"M\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff" +
-	"\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb" +
-	"\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00" +
-	"\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*" +
-	"\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xbb\xf10\x00\x00\x00\x00@\xd5\v\xc0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x01" +
-	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05" +
-	"\xff\xff\xbf\x1c\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-0" +
-	"3>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTutZ\x1a\xb2\x02\x00\x00\xb2\x02\x00\x00\x17\x00\x1c\x00America/Argentina/JujuyUT\t" +
-	"\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00;\x00\x00\x00\x06\x00\x00\x00\x14" +
-	"\xff\xff\xff\xffr\x9c\xae\xb8\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff" +
-	"\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@" +
-	"\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xff" +
-	"ȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0" +
-	"\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff" +
-	"\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0" +
-	"\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'*W\xc0\x00\x00\x00\x00'\xe2۰\x00\x00\x00\x00(\xee\x8a@\x00\x00\x00\x00" +
-	")\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x02\x03\x02\x04\x05\x04\x05\x03\x05\x04\x05\xff\xff\xc2\xc8\x00\x00\xff\xff\xc3" +
-	"\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\n" +
-	"\x00\x00\x00\x00\x00\x8fj\xbeTY\xd8֭\xd6\x02\x00\x00\xd6\x02\x00\x00\x19\x00\x1c\x00America/Argentina/TucumanUT\t\x00\x03\xdd\xfc\x94b\xdd" +
-	"\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00" +
-	"\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xae" +
-	"\xa4\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff" +
-	"\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc3" +
-	"0\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff" +
-	"\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6" +
-	"\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff" +
-	"\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5" +
-	"\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00" +
-	"\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xbb\xf10\x00\x00\x00\x00@\xcb\xd1@\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f" +
-	" \x00\x00\x00\x00H\xfa\xa2\xb0\x00\x00\x00\x00I\xbca \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05" +
-	"\x04\x05\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\x04\x05\xff\xff\xc2\xdc\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00" +
-	"CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe0\xbf\xf5\xe5\xc4\x02\x00\x00\xc4\x02\x00\x00\x1e\x00\x1c\x00Americ" +
-	"a/Argentina/Buenos_AiresUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xa8L\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff" +
-	"\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbe" +
-	"x\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff" +
-	"\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xff\xce" +
-	"\xb0\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff" +
-	"\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe" +
-	"\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00" +
-	"\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008" +
-	"\xbf*\xb0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x00\x00\x00\x00H\xfa\xa2\xb0\x00\x00\x00\x00I\xbca \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
-	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x03\x05\x04\x05\x04\x05\xff\xff\xc94\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f" +
-	"\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xef\xf0R\x8a\xc4\x02" +
-	"\x00\x00\xc4\x02\x00\x00\x19\x00\x1c\x00America/Argentina/CordobaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S" +
-	"_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xad\xb0\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{" +
-	"R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff" +
-	"\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c" +
-	"\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff" +
-	"\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62" +
-	"\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff" +
-	"\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7" +
-	"\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00" +
-	"\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x00\x00\x00\x00H\xfa\xa2\xb0\x00\x00\x00\x00I\xbca \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x04\x05\x04\x05\xff\xff\xc3\xd0\x00\x00\xff\xff\xc3\xd0\x00\x04\xff" +
-	"\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00" +
-	"\x00\x8fj\xbeTm\aD\x0e\xcd\x02\x00\x00\xcd\x02\x00\x00\x1a\x00\x1c\x00America/Argentina/La_RiojaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94b" +
-	"ux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00" +
-	"\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xb0,\xff\xff" +
-	"\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8" +
-	"\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff" +
-	"\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM" +
-	"\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff" +
-	"\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc3" +
-	"5\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00" +
-	"\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'͵\xa0\x00\x00\x00\x00(&&@\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\xb0" +
-	":\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xbb\xf10\x00\x00\x00\x00@\xd5\v\xc0\x00\x00\x00\x00Gw\t\xb0\x00\x00" +
-	"\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x05\x04\x05" +
-	"\x04\x05\x03\x05\x02\x05\x04\x05\xff\xff\xc1T\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00" +
-	"-02\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTŒZ\x8c\xc4\x02\x00\x00\xc4\x02\x00\x00\x19\x00\x1c\x00America/Argentina/" +
-	"MendozaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00=\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xb2\x04\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff" +
-	"\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z" +
-	"\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff" +
-	"\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4C" +
-	"d\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff" +
-	"\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3" +
-	"J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'\x194@\x00\x00\x00\x00'\xcdð\x00\x00" +
-	"\x00\x00(\xfag\xc0\x00\x00\x00\x00)\xb0H\xb0\x00\x00\x00\x00*\xe0\xe1@\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xb0\x13\xb0\x00\x00\x00\x00AV" +
-	">\xc0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x05\x04\x05\x04\x05\x04\x02\x03\x02\x03\x02\x04\x05\x03\x05\x02\x05\x04\x05\xff\xff\xbf|\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00C" +
-	"MT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xad`\x12\xe9\xaa\x00\x00\x00\xaa\x00\x00\x00\x0e\x00\x1c\x00America" +
-	"/La_PazUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x03\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffi\x87\x1bd\xff\xff\xff\xff\xb8\x1e\x96\xe4\xff\xff\xff\xff\xb8\xee\xd5\xd4\x01\x02\x03\xff\xff\xc0\x1c\x00\x00\xff\xff\xc0\x1c\x00\x04\xff\xff\xce,\x01\b\xff\xff\xc7\xc0\x00" +
-	"\fLMT\x00CMT\x00BST\x00-04\x00\n<-04>4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xfe\xe6\xf5J\x05\x04\x00\x00\x05\x04\x00\x00\x0e\x00\x1c\x00Ameri" +
-	"ca/DawsonUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00]\x00\x00\x00\t\x00\x00\x00%\xff\xff\xff\xff}\x86\x8e\xb4\xff\xff\xff\xff\x9e\xb8˰\xff\xff\xff\xff\x9f\xbb#\xa0\xff\xff\xff\xff\xa0\xd0\f\xb0\xff\xff\xff\xff\xa1\xa2Ҁ\xff\xff\xff\xffˉ(\xb0" +
-	"\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a4 \xff\xff\xff\xff\xf7/v\x90\xff\xff\xff\xff\xf8(\xa2\x10\x00\x00\x00\x00\a0\xec\x90\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00" +
-	"\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90" +
-	"\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1ې\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\"V\r \x00\x00\x00\x00" +
-	"#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\n\x80\x10\x00\x00\x00\x00)\xdeϠ" +
-	"\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x00" +
-	"1g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\a8 \x00\x00\x00\x008\x1c\x05\x10" +
-	"\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00" +
-	"?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E\xf3\xd3 " +
-	"\x00\x00\x00\x00G-\x8a\x10\x00\x00\x00\x00Gӵ \x00\x00\x00\x00I\rl\x10\x00\x00\x00\x00I\xb3\x97 \x00\x00\x00\x00J\xedN\x10\x00\x00\x00\x00K\x9c\xb3\xa0\x00\x00\x00\x00L\xd6j\x90\x00\x00\x00\x00" +
-	"M|\x95\xa0\x00\x00\x00\x00N\xb6L\x90\x00\x00\x00\x00O\\w\xa0\x00\x00\x00\x00P\x96.\x90\x00\x00\x00\x00Q<Y\xa0\x00\x00\x00\x00Rv\x10\x90\x00\x00\x00\x00S\x1c;\xa0\x00\x00\x00\x00TU\xf2\x90" +
-	"\x00\x00\x00\x00T\xfc\x1d\xa0\x00\x00\x00\x00V5Ԑ\x00\x00\x00\x00V\xe5: \x00\x00\x00\x00X\x1e\xf1\x10\x00\x00\x00\x00X\xc5\x1c \x00\x00\x00\x00Y\xfe\xd3\x10\x00\x00\x00\x00Z\xa4\xfe \x00\x00\x00\x00" +
-	"[\u07b5\x10\x00\x00\x00\x00\\\x84\xe0 \x00\x00\x00\x00]\xbe\x97\x10\x00\x00\x00\x00^d\xc2 \x00\x00\x00\x00_\x9e\\\xf0\x02\x01\x02\x01\x02\x03\x04\x02\x05\x02\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a" +
-	"\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a" +
-	"\x06\a\x06\a\x06\a\x06\a\b\xff\xff}L\x00\x00\xff\xff\x8f\x80\x01\x04\xff\xff\x81p\x00\b\xff\xff\x8f\x80\x01\f\xff\xff\x8f\x80\x01\x10\xff\xff\x9d\x90\x01\x14\xff\xff\x8f\x80\x00\x19\xff\xff\x9d\x90\x01\x1d\xff\xff\x9d" +
-	"\x90\x00!LMT\x00YDT\x00YST\x00YWT\x00YPT\x00YDDT\x00PST\x00PDT\x00MST\x00\nMST7\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT" +
-	".\xf9\xc0\x1e\xd5\x05\x00\x00\xd5\x05\x00\x00\x0f\x00\x1c\x00America/MonctonUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00T" +
-	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x92\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff^\x1e\xed\xbc\xff\xff\xff\xff\x80\xf1\xb6P\xff\xff\xff\xff\x9e\xb8\x85`\xff\xff" +
-	"\xff\xff\x9f\xba\xddP\xff\xff\xff\xff\xbb<8\xd0\xff\xff\xff\xff\xbb\xb4#@\xff\xff\xff\xff\xbd\x1c\x1a\xd0\xff\xff\xff\xff\xbd\x94\x05@\xff\xff\xff\xff\xbe\xfb\xfc\xd0\xff\xff\xff\xff\xbfs\xe7@\xff\xff\xff\xff\xc0\xdb" +
-	"\xde\xd0\xff\xff\xff\xff\xc1S\xc9@\xff\xff\xff\xff»\xc0\xd0\xff\xff\xff\xff\xc33\xab@\xff\xff\xff\xffě\xa2\xd0\xff\xff\xff\xff\xc5\x13\x8d@\xff\xff\xff\xff\xc6p\xf8\xd0\xff\xff\xff\xff\xc7\r\xcd@\xff\xff" +
-	"\xff\xff\xc8H\xf1\xd0\xff\xff\xff\xff\xc8\xed\xaf@\xff\xff\xff\xff\xca\x16^\xd0\xff\xff\xff\xff\xca\xd6\xcb\xc0\xff\xff\xff\xffˈ\xe2`\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\xff\xff\xff\xff\xd3u" +
-	"\xd6\xe0\xff\xff\xff\xff\xd4@\xcf\xd0\xff\xff\xff\xff\xd5U\xb8\xe0\xff\xff\xff\xff\xd6 \xb1\xd0\xff\xff\xff\xff\xd75\x9a\xe0\xff\xff\xff\xff\xd8\x00\x93\xd0\xff\xff\xff\xff\xd9\x15|\xe0\xff\xff\xff\xff\xd9\xe0u\xd0\xff\xff" +
-	"\xff\xff\xda\xfe\x99`\xff\xff\xff\xff\xdb\xc0W\xd0\xff\xff\xff\xff\xdc\xde{`\xff\xff\xff\xffݩtP\xff\xff\xff\xff\u07be]`\xff\xff\xff\xff߉VP\xff\xff\xff\xff\xe0\x9e?`\xff\xff\xff\xff\xe1i" +
-	"8P\xff\xff\xff\xff\xe2~!`\xff\xff\xff\xff\xe3I\x1aP\xff\xff\xff\xff\xe4^\x03`\xff\xff\xff\xff\xe5(\xfcP\xff\xff\xff\xff\xe6G\x1f\xe0\xff\xff\xff\xff\xe7\x12\x18\xd0\xff\xff\xff\xff\xe8'\x01\xe0\xff\xff" +
-	"\xff\xff\xe9\x16\xe4\xd0\xff\xff\xff\xff\xea\x06\xe3\xe0\xff\xff\xff\xff\xea\xf6\xc6\xd0\xff\xff\xff\xff\xeb\xe6\xc5\xe0\xff\xff\xff\xff\xec֨\xd0\xff\xff\xff\xff\xedƧ\xe0\xff\xff\xff\xff\xee\xbf\xc5P\xff\xff\xff\xff\xef\xaf" +
-	"\xc4`\xff\xff\xff\xff\xf0\x9f\xa7P\xff\xff\xff\xff\xf1\x8f\xa6`\xff\xff\xff\xff\xf2\x7f\x89P\xff\xff\xff\xff\xf3o\x88`\xff\xff\xff\xff\xf4_kP\xff\xff\xff\xff\xf5Oj`\xff\xff\xff\xff\xf6?MP\xff\xff" +
-	"\xff\xff\xf7/L`\xff\xff\xff\xff\xf8(i\xd0\xff\xff\xff\xff\xf9\x0f.`\xff\xff\xff\xff\xfa\bK\xd0\xff\xff\xff\xff\xfa\xf8J\xe0\xff\xff\xff\xff\xfb\xe8-\xd0\xff\xff\xff\xff\xfc\xd8,\xe0\xff\xff\xff\xff\xfd\xc8" +
-	"\x0f\xd0\xff\xff\xff\xff\xfe\xb8\x0e\xe0\xff\xff\xff\xff\xff\xa7\xf1\xd0\x00\x00\x00\x00\x00\x97\xf0\xe0\x00\x00\x00\x00\x01\x87\xd3\xd0\x00\x00\x00\x00\x02w\xd2\xe0\x00\x00\x00\x00\x03p\xf0P\x00\x00\x00\x00\x04`\xef`\x00\x00" +
-	"\x00\x00\x05P\xd2P\x00\x00\x00\x00\b \xb3`\x00\x00\x00\x00\t\x10\x96P\x00\x00\x00\x00\n\x00\x95`\x00\x00\x00\x00\n\xf0xP\x00\x00\x00\x00\v\xe0w`\x00\x00\x00\x00\fٔ\xd0\x00\x00\x00\x00\r\xc0" +
-	"Y`\x00\x00\x00\x00\x0e\xb9v\xd0\x00\x00\x00\x00\x0f\xa9u\xe0\x00\x00\x00\x00\x10\x99X\xd0\x00\x00\x00\x00\x11\x89W\xe0\x00\x00\x00\x00\x12y:\xd0\x00\x00\x00\x00\x13i9\xe0\x00\x00\x00\x00\x14Y\x1c\xd0\x00\x00" +
-	"\x00\x00\x15I\x1b\xe0\x00\x00\x00\x00\x168\xfe\xd0\x00\x00\x00\x00\x17(\xfd\xe0\x00\x00\x00\x00\x18\"\x1bP\x00\x00\x00\x00\x19\b\xdf\xe0\x00\x00\x00\x00\x1a\x01\xfdP\x00\x00\x00\x00\x1a\xf1\xfc`\x00\x00\x00\x00\x1b\xe1" +
-	"\xdfP\x00\x00\x00\x00\x1c\xd1\xde`\x00\x00\x00\x00\x1d\xc1\xc1P\x00\x00\x00\x00\x1e\xb1\xc0`\x00\x00\x00\x00\x1f\xa1\xa3P\x00\x00\x00\x00 u\xf2\xe0\x00\x00\x00\x00!\x81\x85P\x00\x00\x00\x00\"U\xd4\xe0\x00\x00" +
-	"\x00\x00#j\xa1\xd0\x00\x00\x00\x00$5\xb6\xe0\x00\x00\x00\x00%J\x83\xd0\x00\x00\x00\x00&\x15\x98\xe0\x00\x00\x00\x00'*e\xd0\x00\x00\x00\x00'\xfe\xb5`\x00\x00\x00\x00)\nG\xd0\x00\x00\x00\x00)\xde" +
-	"\x97`\x00\x00\x00\x00*\xea)\xd0\x00\x00\x00\x00+\xbe]|\x00\x00\x00\x00,\xd3*l\x00\x00\x00\x00-\x9e?|\x00\x00\x00\x00.\xb3\fl\x00\x00\x00\x00/~!|\x00\x00\x00\x000\x92\xeel\x00\x00" +
-	"\x00\x001g=\xfc\x00\x00\x00\x002r\xd0l\x00\x00\x00\x003G\x1f\xfc\x00\x00\x00\x004R\xb2l\x00\x00\x00\x005'\x01\xfc\x00\x00\x00\x0062\x94l\x00\x00\x00\x007\x06\xe3\xfc\x00\x00\x00\x008\x1b" +
-	"\xb0\xec\x00\x00\x00\x008\xe6\xc5\xfc\x00\x00\x00\x009\xfb\x92\xec\x00\x00\x00\x00:Ƨ\xfc\x00\x00\x00\x00;\xdbt\xec\x00\x00\x00\x00<\xaf\xc4|\x00\x00\x00\x00=\xbbV\xec\x00\x00\x00\x00>\x8f\xa6|\x00\x00" +
-	"\x00\x00?\x9b8\xec\x00\x00\x00\x00@o\x88|\x00\x00\x00\x00A\x84Ul\x00\x00\x00\x00BOj|\x00\x00\x00\x00Cd7l\x00\x00\x00\x00D/L|\x00\x00\x00\x00ED\x19l\x00\x00\x00\x00E\xf3" +
-	"\x9a\xe0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x05\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\xff\xff\xc3D\x00\x00\xff\xff\xb9\xb0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xc7\xc0\x00\f\xff\xff\xd5\xd0\x01\x10\xff\xff" +
-	"\xd5\xd0\x01\x14LMT\x00EST\x00ADT\x00AST\x00AWT\x00APT\x00\nAST4ADT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00" +
-	"\x00\x00\x8fj\xbeTU\xactA\xb5\x01\x00\x00\xb5\x01\x00\x00\x11\x00\x1c\x00America/MatamorosUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1" +
-	"\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZ" +
-	"if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\xa5\xb6\xda`\x00\x00\x00\x00\"U\xf1\x00\x00\x00" +
-	"\x00\x00#j\xbd\xf0\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a" +
-	"\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xf5\x04\x80\x00\x00\x00\x00;\xb6\xc2\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00" +
-	"\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00ED" +
-	"Qp\x00\x00\x00\x00F\x0ff\x80\x00\x00\x00\x00G$3p\x00\x00\x00\x00G\xf8\x83\x00\x00\x00\x00\x00I\x04\x15p\x00\x00\x00\x00I\xd8e\x00\x00\x00\x00\x00J\xe3\xf7p\x00\x00\x00\x00K\x9c\x97\x80\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xa2@\x00\x00\xff\xff\xab\xa0\x00\x04\xff\xff\xb9\xb0\x01\bLMT\x00CST\x00CDT\x00" +
-	"\nCST6CDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTq\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x12\x00\x1c\x00Americ" +
-	"a/St_VincentUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7" +
-	"\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\u0096dK~\x02\x00\x00~" +
-	"\x02\x00\x00\x0e\x00\x1c\x00America/ReginaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff\x86\xfd\x93\x1c\xff\xff\xff\xff\x9e\xb8\xaf\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xb5eO\xf0\xff\xff\xff\xff" +
-	"\xb60H\xe0\xff\xff\xff\xff\xb7E1\xf0\xff\xff\xff\xff\xb8\x10*\xe0\xff\xff\xff\xff\xb9%\x13\xf0\xff\xff\xff\xff\xb9\xf0\f\xe0\xff\xff\xff\xff\xbb\x0e0p\xff\xff\xff\xff\xbb\xcf\xee\xe0\xff\xff\xff\xff\xbc\xee\x12p" +
-	"\xff\xff\xff\xff\xbd\xb9\v`\xff\xff\xff\xff\xc2r\b\xf0\xff\xff\xff\xff\xc3a\xeb\xe0\xff\xff\xff\xff\xc4Q\xea\xf0\xff\xff\xff\xff\xc58\x93`\xff\xff\xff\xff\xc61\xcc\xf0\xff\xff\xff\xff\xc7!\xaf\xe0\xff\xff\xff\xff" +
-	"\xc8\x1a\xe9p\xff\xff\xff\xff\xc9\n\xcc`\xff\xff\xff\xff\xc9\xfa\xcbp\xff\xff\xff\xff\xca\xea\xae`\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xd3c\x8c\x10" +
-	"\xff\xff\xff\xff\xd4So\x00\xff\xff\xff\xff\xd5U\xe3\x10\xff\xff\xff\xff\xd6 \xdc\x00\xff\xff\xff\xff\xd75\xc5\x10\xff\xff\xff\xff\xd8\x00\xbe\x00\xff\xff\xff\xff\xd9\x15\xa7\x10\xff\xff\xff\xff\xd9\xe0\xa0\x00\xff\xff\xff\xff" +
-	"\xda\xfeÐ\xff\xff\xff\xff\xdb\xc0\x82\x00\xff\xff\xff\xff\xdcޥ\x90\xff\xff\xff\xffݩ\x9e\x80\xff\xff\xff\xff\u07be\x87\x90\xff\xff\xff\xff߉\x80\x80\xff\xff\xff\xff\xe0\x9ei\x90\xff\xff\xff\xff\xe1ib\x80" +
-	"\xff\xff\xff\xff\xe2~K\x90\xff\xff\xff\xff\xe3ID\x80\xff\xff\xff\xff\xe4^-\x90\xff\xff\xff\xff\xe5)&\x80\xff\xff\xff\xff\xe6GJ\x10\xff\xff\xff\xff\xe7\x12C\x00\xff\xff\xff\xff\xe8',\x10\xff\xff\xff\xff" +
-	"\xe8\xf2%\x00\xff\xff\xff\xff\xeb\xe6\xf0\x10\xff\xff\xff\xff\xec\xd6\xd3\x00\xff\xff\xff\xff\xed\xc6\xd2\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\xff\xff\x9d\xe4\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10\xff\xff\xab\xa0\x00\x14LMT" +
-	"\x00MDT\x00MST\x00MWT\x00MPT\x00CST\x00\nCST6\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTU!\x12f\xd9\x02\x00\x00\xd9\x02\x00\x00\x13\x00\x1c\x00Ame" +
-	"rica/YellowknifeUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x06\x00\x00\x00\x19\xff\xff\xff\xff\xbe*\x18\x00\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xf7/Zp\xff" +
-	"\xff\xff\xff\xf8(\x85\xf0\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19" +
+	"\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00" +
+	"D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x02\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff" +
+	"\xaf:\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18LMT\x00CDT\x00CST\x00CWT\x00CPT\x00" +
+	"EST\x00EDT\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ʼ\to1\x03\x00\x001\x03\x00\x00\x0e\x00" +
+	"\x00\x00America/InuvikTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01" +
+	"\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00H\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\xe0\x06N\x80\x00" +
+	"\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05Q\n\x90\x00\x00\x00\x00\x06A\t\xa0\x00\x00\x00\x00\a0\xec\x90\x00\x00\x00\x00\b \xeb\xa0\x00\x00\x00\x00\t\x10ΐ\x00\x00\x00\x00\n\x00͠\x00\x00\x00\x00\n" +
+	"\xf0\xb0\x90\x00\x00\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00" +
+	"\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19" +
 	"\t\n\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00" +
 	"\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'" +
 	"*\x90\x00\x00\x00\x00\x00'\xfeߐ\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00" +
 	"\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005" +
 	"'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;ۻ\x00\x00" +
 	"\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00C" +
-	"d}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x03\x01\x02\x03\x04\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05" +
-	"\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x00\x00\x00\x00\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\xab\xa0\x01\b\xff\xff\x9d\x90\x00\f\xff\xff\xb9\xb0\x01\x10\xff\xff" +
-	"\xab\xa0\x01\x15-00\x00MWT\x00MPT\x00MST\x00MDDT\x00MDT\x00\nMST7MDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00" +
-	"\x00\x00\x00\x8fj\xbeT\x1b\vKdC\x03\x00\x00C\x03\x00\x00\x13\x00\x1c\x00America/Rainy_RiverUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01" +
-	"\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" +
-	"\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00J\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xffr\xee\x87(\xff\xff\xff\xff\x9e\xb8\xa1" +
-	"\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xc8\xf8W`\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\x00\x00\x00\x00\b π\x00\x00\x00\x00\t\x10\xb2p\x00\x00\x00" +
-	"\x00\n\x00\xb1\x80\x00\x00\x00\x00\n\xf0\x94p\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00\x00\x00\fٰ\xf0\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99t" +
-	"\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00" +
-	"\x00\x18\"7p\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1\xdc" +
-	"\x80\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00" +
-	"\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)\nc\xf0\x00\x00\x00\x00)\u07b3\x80\x00\x00\x00\x00*\xeaE\xf0\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3b" +
-	"p\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3Dp\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x93&p\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00" +
-	"\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xe0" +
-	"\x00\x00\x00\x00\x00;۬\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00" +
-	"\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xa7X\x00\x00\xff\xff\xb9" +
-	"\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10LMT\x00CDT\x00CST\x00CWT\x00CPT\x00\nCST6CDT,M3.2.0,M11" +
-	".1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTq\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x12\x00\x1c\x00America/KralendijkUT\t\x00\x03\xdd\xfc" +
-	"\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff" +
-	"z敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00" +
-	"AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTMv\xa1\x0f%\x01\x00\x00%\x01\x00\x00\x11\x00\x1c\x00America/Mont" +
-	"erreyUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10" +
-	"\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\xa5\xb6\xda`\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x00" +
-	"4R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xf5\x04\x80" +
-	"\x00\x00\x00\x00;\xb6\xc2\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xa1\xf4\x00\x00\xff\xff\xab\xa0\x00\x04\xff\xff\xb9\xb0\x01\bLMT\x00CST\x00CD" +
-	"T\x00\nCST6CDT,M4.1.0,M10.5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT%J\xd5\xebS\x01\x00\x00S\x01\x00\x00\x0f\x00\x1c\x00Amer" +
-	"ica/JamaicaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x16\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffi\x87#~\xff\xff\xff\xff\x93\x0f\xb4\xfe\x00\x00\x00\x00\a\x8d\x19p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\t\xad\x94\xf0\x00\x00\x00\x00\n\xf0" +
-	"\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00\f٢\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00" +
-	"\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b" +
-	"\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\xff\xff\xb8\x02\x00\x00\xff\xff\xb8\x02\x00\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\fLMT\x00" +
-	"KMT\x00EST\x00EDT\x00\nEST5\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\a\x1c\x9e\x9a]\x04\x00\x00]\x04\x00\x00\x0e\x00\x1c\x00America/Hava" +
-	"naUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00j\x00\x00\x00" +
-	"\x04\x00\x00\x00\x10\xff\xff\xff\xffi\x87(\xb8\xff\xff\xff\xff\xacb\u0080\xff\xff\xff\xff\xb1ӔP\xff\xff\xff\xff\xb2t]@\xff\xff\xff\xff\xc8[f\xd0\xff\xff\xff\xff\xc8\xd3Q@\xff\xff\xff\xff\xca;H" +
-	"\xd0\xff\xff\xff\xffʼm\xc0\xff\xff\xff\xff\xcc$eP\xff\xff\xff\xff̜O\xc0\xff\xff\xff\xff\xd1\xc4\vP\xff\xff\xff\xff\xd2;\xf5\xc0\xff\xff\xff\xffӣ\xedP\xff\xff\xff\xff\xd4\x1b\xd7\xc0\xff\xff\xff" +
-	"\xff\xf7`\x05\xd0\xff\xff\xff\xff\xf7\xff}@\xff\xff\xff\xff\xf9=D\xd0\xff\xff\xff\xff\xf9\xe3S\xc0\xff\xff\xff\xff\xfa\xdb;\xd0\xff\xff\xff\xff\xfb\xa7\x86@\xff\xff\xff\xff\xfcũ\xd0\xff\xff\xff\xff\xfd\x87h" +
-	"@\xff\xff\xff\xff\xfe\xb8\x00\xd0\xff\xff\xff\xff\xff\xa7\xe3\xc0\x00\x00\x00\x00\x00\x97\xe2\xd0\x00\x00\x00\x00\x01\x87\xc5\xc0\x00\x00\x00\x00\x02w\xc4\xd0\x00\x00\x00\x00\x03p\xe2@\x00\x00\x00\x00\x04`\xe1P\x00\x00\x00" +
-	"\x00\x055\x14\xc0\x00\x00\x00\x00\x06@\xc3P\x00\x00\x00\x00\a\x16H@\x00\x00\x00\x00\b \xa5P\x00\x00\x00\x00\b\xf7{\xc0\x00\x00\x00\x00\n\x00\x87P\x00\x00\x00\x00\n\xf0j@\x00\x00\x00\x00\v\xe0i" +
-	"P\x00\x00\x00\x00\fن\xc0\x00\x00\x00\x00\r\xc0KP\x00\x00\x00\x00\x0e\xb9h\xc0\x00\x00\x00\x00\x0f\xb2\xa2P\x00\x00\x00\x00\x10}\x9b@\x00\x00\x00\x00\x11Q\xea\xd0\x00\x00\x00\x00\x12f\xb7\xc0\x00\x00\x00" +
-	"\x00\x131\xcc\xd0\x00\x00\x00\x00\x14F\x99\xc0\x00\x00\x00\x00\x15[\x82\xd0\x00\x00\x00\x00\x16&{\xc0\x00\x00\x00\x00\x17;d\xd0\x00\x00\x00\x00\x18\x06]\xc0\x00\x00\x00\x00\x19\x1bF\xd0\x00\x00\x00\x00\x19\xe6?" +
-	"\xc0\x00\x00\x00\x00\x1a\xfb(\xd0\x00\x00\x00\x00\x1b\xcf\\@\x00\x00\x00\x00\x1c\xdb\n\xd0\x00\x00\x00\x00\x1d\xaf>@\x00\x00\x00\x00\x1ezSP\x00\x00\x00\x00\x1f\x8f @\x00\x00\x00\x00 Z5P\x00\x00\x00" +
-	"\x00!o\x02@\x00\x00\x00\x00\"CQ\xd0\x00\x00\x00\x00#N\xe4@\x00\x00\x00\x00$#3\xd0\x00\x00\x00\x00%.\xc6@\x00\x00\x00\x00&\x15\x8a\xd0\x00\x00\x00\x00'\x17\xe2\xc0\x00\x00\x00\x00'\xfe\xa7" +
-	"P\x00\x00\x00\x00(\xf7\xd2\xd0\x00\x00\x00\x00)މP\x00\x00\x00\x00*״\xd0\x00\x00\x00\x00+\xbekP\x00\x00\x00\x00,\xb7\x96\xd0\x00\x00\x00\x00-\x9eMP\x00\x00\x00\x00.\x97x\xd0\x00\x00\x00" +
-	"\x00/~/P\x00\x00\x00\x000wZ\xd0\x00\x00\x00\x001gK\xd0\x00\x00\x00\x002W<\xd0\x00\x00\x00\x003G-\xd0\x00\x00\x00\x004@YP\x00\x00\x00\x005\x1d\xd5P\x00\x00\x00\x0062\xb0" +
-	"P\x00\x00\x00\x006\xfd\xb7P\x00\x00\x00\x008\x1b\xcc\xd0\x00\x00\x00\x008\xe6\xd3\xd0\x00\x00\x00\x009\xfb\xae\xd0\x00\x00\x00\x00:Ƶ\xd0\x00\x00\x00\x00;ې\xd0\x00\x00\x00\x00<\xaf\xd2P\x00\x00\x00" +
-	"\x00=\xbbr\xd0\x00\x00\x00\x00>\x8f\xb4P\x00\x00\x00\x00?\x9bT\xd0\x00\x00\x00\x00@f[\xd0\x00\x00\x00\x00ED5P\x00\x00\x00\x00E\xf3\x8c\xd0\x00\x00\x00\x00G$\x17P\x00\x00\x00\x00Gܩ" +
-	"P\x00\x00\x00\x00I\x03\xf9P\x00\x00\x00\x00I\xb3P\xd0\x00\x00\x00\x00J\xe3\xdbP\x00\x00\x00\x00K\x9cmP\x00\x00\x00\x00L\xcc\xf7\xd0\x00\x00\x00\x00M\x85\x89\xd0\x00\x00\x00\x00N\xbfN\xd0\x00\x00\x00" +
-	"\x00Ow\xe0\xd0\x00\x00\x00\x00P\x95\xf6P\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff" +
-	"\xff\xb2\xc8\x00\x00\xff\xff\xb2\xc0\x00\x04\xff\xff\xc7\xc0\x01\b\xff\xff\xb9\xb0\x00\fLMT\x00HMT\x00CDT\x00CST\x00\nCST5CDT,M3.2.0/0,M11" +
-	".1.0/1\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x82\x13z\xe2\xc2\x00\x00\x00\xc2\x00\x00\x00\x13\x00\x1c\x00America/TegucigalpaUT\t\x00" +
-	"\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x03\x00\x00\x00\f\xff" +
-	"\xff\xff\xff\xa4LKD\x00\x00\x00\x00 \x9a\xdc\xe0\x00\x00\x00\x00!\\\x9bP\x00\x00\x00\x00\"z\xbe\xe0\x00\x00\x00\x00#<}P\x00\x00\x00\x00D]\x8c\xe0\x00\x00\x00\x00D\xd6\xc8\xd0\x02\x01\x02\x01\x02" +
-	"\x01\x02\xff\xff\xae<\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\bLMT\x00CDT\x00CST\x00\nCST6\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xcd\xc3v\xe3\xb3\x00\x00\x00" +
-	"\xb3\x00\x00\x00\x11\x00\x1c\x00America/GuayaquilUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffi\x87&X\xff\xff\xff\xff\xb6\xa4B\x18\x00\x00\x00\x00+\x16\xfc\xd0\x00\x00\x00\x00+q\xe6@" +
-	"\x01\x03\x02\x03\xff\xff\xb5(\x00\x00\xff\xff\xb6h\x00\x04\xff\xff\xc7\xc0\x01\b\xff\xff\xb9\xb0\x00\fLMT\x00QMT\x00-04\x00-05\x00\n<-05>5\nPK\x03\x04\n\x00\x00\x00" +
-	"\x00\x00\x8fj\xbeT\xa2\x81\xbfyS\x02\x00\x00S\x02\x00\x00\x12\x00\x1c\x00America/MetlakatlaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91" +
-	"\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00T" +
-	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,\x00\x00\x00\b\x00\x00\x00\x1e\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}\x870\x1a\xff" +
-	"\xff\xff\xffˉ\x1a\xa0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a&\x10\xff\xff\xff\xff\xfe\xb8G \xff\xff\xff\xff\xff\xa8*\x10\x00\x00\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88\f\x10\x00\x00\x00\x00\x02" +
-	"x\v \x00\x00\x00\x00\x03q(\x90\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05Q\n\x90\x00\x00\x00\x00\x06A\t\xa0\x00\x00\x00\x00\a0\xec\x90\x00\x00\x00\x00\a\x8dC\xa0\x00\x00\x00\x00\t\x10ΐ\x00" +
-	"\x00\x00\x00\t\xad\xbf \x00\x00\x00\x00\n\xf0\xb0\x90\x00\x00\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10" +
-	"\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00" +
-	"\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00V5\xe2\xa0\x00\x00\x00\x00V\xe5H0\x00\x00\x00\x00X\x1e\xff \x00\x00\x00\x00X\xc5*0\x00\x00\x00\x00Y" +
-	"\xfe\xe1 \x00\x00\x00\x00Z\xa5\f0\x00\x00\x00\x00[\xde\xc3 \x00\x00\x00\x00\\DF\xa0\x00\x00\x00\x00\\\x84\xee0\x01\x02\x03\x04\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02" +
-	"\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x06\a\x06\a\x06\a\x02\x06\a\x00\x00\xd6&\x00\x00\xff\xff\x84\xa6\x00\x00\xff\xff\x8f\x80\x00\x04\xff\xff\x9d\x90\x01\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10\xff\xff\x81p\x00" +
-	"\x14\xff\xff\x8f\x80\x01\x19LMT\x00PST\x00PWT\x00PPT\x00PDT\x00AKST\x00AKDT\x00\nAKST9AKDT,M3.2.0,M11.1" +
-	".0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT8\xcdZ\x05o\x01\x00\x00o\x01\x00\x00\x10\x00\x1c\x00America/MazatlanUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc" +
-	"\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" +
-	"\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x16\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\xa5\xb6\xe8p" +
-	"\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6fV`\xff\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff\xb8\f6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\xff\xff\xff\xff\xcb\xeaq`\xff\xff\xff\xffؑ\xb4\xf0\x00\x00\x00\x00" +
-	"\x00\x00p\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10" +
-	"\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xf5\x12\x90\x00\x00\x00\x00;\xb6\xd1\x00\x00\x00\x00\x00<\xb0\n\x90\x01\x02\x01\x02\x01\x02\x01\x03\x01\x04\x01\x04" +
-	"\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\xff\xff\x9c<\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\x8f\x80\x00\f\xff\xff\xab\xa0\x01\x10LMT\x00MST\x00CST\x00PST\x00MDT\x00" +
-	"\nMST7MDT,M4.1.0,M10.5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x89غ\xee\x15\x04\x00\x00\x15\x04\x00\x00\x0e\x00\x1c\x00Americ" +
-	"a/BelizeUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00b\x00\x00\x00\x06\x00\x00\x00\x1a\xff\xff\xff\xff\x93^ٰ\xff\xff\xff\xff\x9f\x9f;\xe0\xff\xff\xff\xff\xa0EQ\xd8\xff\xff\xff\xff\xa1\x7f\x1d\xe0\xff\xff\xff\xff\xa2.nX\xff\xff\xff\xff\xa3^\xff\xe0\xff" +
-	"\xff\xff\xff\xa4\x0ePX\xff\xff\xff\xff\xa5>\xe1\xe0\xff\xff\xff\xff\xa5\xee2X\xff\xff\xff\xff\xa7'\xfe`\xff\xff\xff\xff\xa7\xce\x14X\xff\xff\xff\xff\xa9\a\xe0`\xff\xff\xff\xff\xa9\xad\xf6X\xff\xff\xff\xff\xaa" +
-	"\xe7\xc2`\xff\xff\xff\xff\xab\x97\x12\xd8\xff\xff\xff\xff\xacǤ`\xff\xff\xff\xff\xadv\xf4\xd8\xff\xff\xff\xff\xae\xa7\x86`\xff\xff\xff\xff\xafV\xd6\xd8\xff\xff\xff\xff\xb0\x87h`\xff\xff\xff\xff\xb16\xb8\xd8\xff" +
-	"\xff\xff\xff\xb2p\x84\xe0\xff\xff\xff\xff\xb3\x16\x9a\xd8\xff\xff\xff\xff\xb4Pf\xe0\xff\xff\xff\xff\xb4\xf6|\xd8\xff\xff\xff\xff\xb60H\xe0\xff\xff\xff\xff\xb6ߙX\xff\xff\xff\xff\xb8\x10*\xe0\xff\xff\xff\xff\xb8" +
-	"\xbf{X\xff\xff\xff\xff\xb9\xf0\f\xe0\xff\xff\xff\xff\xba\x9f]X\xff\xff\xff\xff\xbb\xd9)`\xff\xff\xff\xff\xbc\x7f?X\xff\xff\xff\xff\xbd\xb9\v`\xff\xff\xff\xff\xbe_!X\xff\xff\xff\xff\xbf\x98\xed`\xff" +
-	"\xff\xff\xff\xc0?\x03X\xff\xff\xff\xff\xc1x\xcf`\xff\xff\xff\xff\xc2(\x1f\xd8\xff\xff\xff\xff\xc3X\xb1`\xff\xff\xff\xff\xc4\b\x01\xd8\xff\xff\xff\xff\xc58\x93`\xff\xff\xff\xff\xc5\xe7\xe3\xd8\xff\xff\xff\xff\xc7" +
-	"!\xaf\xe0\xff\xff\xff\xff\xc7\xc7\xc5\xd8\xff\xff\xff\xff\xc9\x01\x91\xe0\xff\xff\xff\xffɧ\xa7\xd8\xff\xff\xff\xff\xca\xe1s\xe0\xff\xff\xff\xffː\xc4X\xff\xff\xff\xff\xcc@\"\xe0\xff\xff\xff\xff\xd2#\xf4p\xff" +
-	"\xff\xff\xff\xd2\xc6qP\xff\xff\xff\xff\xd6)\xfa`\xff\xff\xff\xff\xd6\xd9J\xd8\xff\xff\xff\xff\xd8\t\xdc`\xff\xff\xff\xffع,\xd8\xff\xff\xff\xff\xd9\xe9\xbe`\xff\xff\xff\xffڙ\x0e\xd8\xff\xff\xff\xff\xdb" +
-	"\xd2\xda\xe0\xff\xff\xff\xff\xdcx\xf0\xd8\xff\xff\xff\xffݲ\xbc\xe0\xff\xff\xff\xff\xdeX\xd2\xd8\xff\xff\xff\xffߒ\x9e\xe0\xff\xff\xff\xff\xe0A\xefX\xff\xff\xff\xff\xe1r\x80\xe0\xff\xff\xff\xff\xe2!\xd1X\xff" +
-	"\xff\xff\xff\xe3Rb\xe0\xff\xff\xff\xff\xe4\x01\xb3X\xff\xff\xff\xff\xe52D\xe0\xff\xff\xff\xff\xe5\xe1\x95X\xff\xff\xff\xff\xe7\x1ba`\xff\xff\xff\xff\xe7\xc1wX\xff\xff\xff\xff\xe8\xfbC`\xff\xff\xff\xff\xe9" +
-	"\xa1YX\xff\xff\xff\xff\xea\xdb%`\xff\xff\xff\xff\xeb\x8au\xd8\xff\xff\xff\xff\xec\xbb\a`\xff\xff\xff\xff\xedjW\xd8\xff\xff\xff\xff\xee\x9a\xe9`\xff\xff\xff\xff\xefJ9\xd8\xff\xff\xff\xff\xf0\x84\x05\xe0\xff" +
-	"\xff\xff\xff\xf1*\x1b\xd8\xff\xff\xff\xff\xf2c\xe7\xe0\xff\xff\xff\xff\xf3\t\xfd\xd8\xff\xff\xff\xff\xf4C\xc9\xe0\xff\xff\xff\xff\xf4\xe9\xdf\xd8\xff\xff\xff\xff\xf6#\xab\xe0\xff\xff\xff\xff\xf6\xd2\xfcX\xff\xff\xff\xff\xf8" +
-	"\x03\x8d\xe0\xff\xff\xff\xff\xf8\xb2\xdeX\xff\xff\xff\xff\xf9\xe3o\xe0\xff\xff\xff\xff\xfa\x92\xc0X\xff\xff\xff\xff\xfb̌`\xff\xff\xff\xff\xfcr\xa2X\x00\x00\x00\x00\ab\xdb`\x00\x00\x00\x00\a\xb9\xd0P\x00" +
-	"\x00\x00\x00\x18aq`\x00\x00\x00\x00\x18\xab7P\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x02\x05\x02\xff\xff\xadP\x00\x00\xff" +
-	"\xff\xb2\xa8\x01\x04\xff\xff\xab\xa0\x00\n\xff\xff\xb9\xb0\x01\x0e\xff\xff\xb9\xb0\x01\x12\xff\xff\xb9\xb0\x01\x16LMT\x00-0530\x00CST\x00CWT\x00CPT\x00CDT\x00\nCST6" +
-	"\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT$ \x873\xf8\x03\x00\x00\xf8\x03\x00\x00\x0f\x00\x1c\x00America/Knox_INUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bu" +
-	"x\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00" +
-	"\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff" +
-	"\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd5U\xd5" +
-	"\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff" +
-	"\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90p\xff\xff\xff\xff\u07bey\x80\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6" +
-	"p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5W<\xf0\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe77\x1e\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff" +
-	"\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xd6\xc4\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\xee\xbf\xe1p\xff\xff\xff\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xf0\x9f\xc3p\xff\xff\xff\xff\xf1\x8f\xc2" +
-	"\x80\xff\xff\xff\xff\xf4_\x87p\xff\xff\xff\xff\xfa\xf8g\x00\xff\xff\xff\xff\xfb\xe8I\xf0\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8+\xf0\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\r\xf0\x00\x00\x00" +
-	"\x00\x00\x98\r\x00\x00\x00\x00\x00\x01\x87\xef\xf0\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\fp\x00\x00\x00\x00\x04a\v\x80\x00\x00\x00\x00\x05P\xeep\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\a0\xd0" +
-	"p\x00\x00\x00\x00\a\x8d'\x80\x00\x00\x00\x00\t\x10\xb2p\x00\x00\x00\x00\t\xad\xa3\x00\x00\x00\x00\x00\n\xf0\x94p\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00\x00\x00\fٰ\xf0\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00" +
-	"\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99t\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8" +
-	"\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\"7p\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00" +
-	"\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1܀\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd" +
-	"\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)\nc\xf0\x00\x00\x00\x00D/vp\x00\x00\x00" +
-	"\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x05\x01\x02\x01\xff\xff\xae\xca\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff" +
-	"\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00\nCST6CDT,M3.2." +
-	"0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x7f$*\xa0\xa6\x03\x00\x00\xa6\x03\x00\x00\x0e\x00\x1c\x00America/CuiabaUT\t\x00\x03\xdd" +
-	"\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff" +
-	"\xff\x96\xaa{\x94\xff\xff\xff\xff\xb8\x0fW\xf0\xff\xff\xff\xff\xb8\xfdN\xb0\xff\xff\xff\xff\xb9\xf1B@\xff\xff\xff\xff\xbaނ0\xff\xff\xff\xff\xda8\xbc@\xff\xff\xff\xff\xda\xec\b@\xff\xff\xff\xff\xdc\x19\xef" +
-	"\xc0\xff\xff\xff\xffܹg0\xff\xff\xff\xff\xdd\xfb#@\xff\xff\xff\xffޛ\xec0\xff\xff\xff\xff\xdfݨ@\xff\xff\xff\xff\xe0TA0\xff\xff\xff\xff\xf4\x98\r\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff" +
-	"\xff\xf6\xc0r@\xff\xff\xff\xff\xf7\x0e,\xb0\xff\xff\xff\xff\xf8Q:@\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xfa\n\xe0\xc0\xff\xff\xff\xff\xfa\xa9\x06\xb0\xff\xff\xff\xff\xfb\xec\x14@\xff\xff\xff\xff\xfc\x8b\x8b" +
-	"\xb0\x00\x00\x00\x00\x1dɜ@\x00\x00\x00\x00\x1ex\xe5\xb0\x00\x00\x00\x00\x1f\xa0C\xc0\x00\x00\x00\x00 3ݰ\x00\x00\x00\x00!\x81w@\x00\x00\x00\x00\"\vְ\x00\x00\x00\x00#X\x1e\xc0\x00\x00\x00" +
-	"\x00#\xe2~0\x00\x00\x00\x00%8\x00\xc0\x00\x00\x00\x00%\xd4\xd50\x00\x00\x00\x00'!\x1d@\x00\x00\x00\x00'\xbd\xf1\xb0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\x94\x990\x00\x00\x00\x00*\xea\x1b" +
-	"\xc0\x00\x00\x00\x00+k@\xb0\x00\x00\x00\x00,\xc0\xc3@\x00\x00\x00\x00-f\xd20\x00\x00\x00\x00.\xa0\xa5@\x00\x00\x00\x00/F\xb40\x00\x00\x00\x000\x80\x87@\x00\x00\x00\x001\x1d[\xb0\x00\x00\x00" +
-	"\x002W.\xc0\x00\x00\x00\x003\x06x0\x00\x00\x00\x0048b@\x00\x00\x00\x004\xf8\xcf0\x00\x00\x00\x006 -@\x00\x00\x00\x006\xcfv\xb0\x00\x00\x00\x007\xf6\xd4\xc0\x00\x00\x00\x008\xb8\x93" +
-	"0\x00\x00\x00\x009\xdf\xf1@\x00\x00\x00\x00:\x8f:\xb0\x00\x00\x00\x00;\xc9\r\xc0\x00\x00\x00\x00<o\x1c\xb0\x00\x00\x00\x00=ğ@\x00\x00\x00\x00>N\xfe\xb0\x00\x00\x00\x00A\x87\x06@\x00\x00\x00" +
-	"\x00B\x17\xfd0\x00\x00\x00\x00CQ\xd0@\x00\x00\x00\x00C\xf7\xdf0\x00\x00\x00\x00EMa\xc0\x00\x00\x00\x00E\xe0\xfb\xb0\x00\x00\x00\x00G\x11\x94@\x00\x00\x00\x00G\xb7\xa30\x00\x00\x00\x00H\xfa\xb0" +
-	"\xc0\x00\x00\x00\x00I\x97\x850\x00\x00\x00\x00Jڒ\xc0\x00\x00\x00\x00K\x80\xa1\xb0\x00\x00\x00\x00L\xbat\xc0\x00\x00\x00\x00M`\x83\xb0\x00\x00\x00\x00N\x9aV\xc0\x00\x00\x00\x00OI\xa00\x00\x00\x00" +
-	"\x00P\x83s@\x00\x00\x00\x00Q G\xb0\x00\x00\x00\x00RcU@\x00\x00\x00\x00S\x00)\xb0\x00\x00\x00\x00TC7@\x00\x00\x00\x00T\xe9F0\x00\x00\x00\x00V#\x19@\x00\x00\x00\x00V\xc9(" +
-	"0\x00\x00\x00\x00X\x02\xfb@\x00\x00\x00\x00X\xa9\n0\x00\x00\x00\x00Y\xe2\xdd@\x00\x00\x00\x00Z\x88\xec0\x00\x00\x00\x00[\xden\xc0\x00\x00\x00\x00\\h\xce0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xcbl\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\bLMT\x00-03\x00-04\x00\n<-04>4\nPK\x03\x04" +
-	"\n\x00\x00\x00\x00\x00\x8fj\xbeTo_\x00v/\x01\x00\x00/\x01\x00\x00\x0e\x00\x1c\x00America/MeridaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91" +
-	"\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00T" +
-	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\xa5\xb6\xda`\x00\x00\x00\x00\x16\x86\xd5`\x00" +
-	"\x00\x00\x00\x18LKP\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007" +
-	"\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xf5\x04\x80\x00\x00\x00\x00;\xb6\xc2\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x01\x02\x01\x03\x01\x03\x01\x03\x01" +
-	"\x03\x01\x03\x01\x03\x01\x03\xff\xff\xab\xfc\x00\x00\xff\xff\xab\xa0\x00\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xb9\xb0\x01\fLMT\x00CST\x00EST\x00CDT\x00\nCST6CDT,M4.1" +
-	".0,M10.5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTutZ\x1a\xb2\x02\x00\x00\xb2\x02\x00\x00\r\x00\x1c\x00America/JujuyUT\t\x00\x03\xdd" +
-	"\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00;\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff" +
-	"\xffr\x9c\xae\xb8\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3" +
-	"\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff" +
-	"\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94" +
-	"@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff" +
-	"\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36" +
-	"\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00" +
-	"\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'*W\xc0\x00\x00\x00\x00'\xe2۰\x00\x00\x00\x00(\xee\x8a@\x00\x00\x00\x00)\xb0:" +
-	"\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
-	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x02\x03\x02\x04\x05\x04\x05\x03\x05\x04\x05\xff\xff\xc2\xc8\x00\x00\xff\xff\xc3\xd0\x00\x04" +
-	"\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00" +
-	"\x00\x00\x8fj\xbeTԾ\xe7#\x95\x00\x00\x00\x95\x00\x00\x00\x0e\x00\x1c\x00America/CaymanUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04" +
-	"S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xffi\x87&\x10\xff\xff\xff\xff\x8b\xf4a\xe8\x01\x02\xff\xff\xb5" +
-	"p\x00\x00\xff\xff\xb5\x18\x00\x04\xff\xff\xb9\xb0\x00\bLMT\x00CMT\x00EST\x00\nEST5\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x85-\xb9\xf8\x8a\x01\x00\x00\x8a\x01\x00\x00\r" +
-	"\x00\x1c\x00America/BelemUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaatt\xff\xff\xff\xff\xb8\x0fI\xe0\xff\xff\xff\xff\xb8\xfd@\xa0\xff\xff\xff\xff\xb9\xf140\xff\xff\xff\xff\xba\xdet \xff" +
-	"\xff\xff\xff\xda8\xae0\xff\xff\xff\xff\xda\xeb\xfa0\xff\xff\xff\xff\xdc\x19\xe1\xb0\xff\xff\xff\xffܹY \xff\xff\xff\xff\xdd\xfb\x150\xff\xff\xff\xffޛ\xde \xff\xff\xff\xff\xdfݚ0\xff\xff\xff\xff\xe0" +
-	"T3 \xff\xff\xff\xff\xf4\x97\xff\xb0\xff\xff\xff\xff\xf5\x05^ \xff\xff\xff\xff\xf6\xc0d0\xff\xff\xff\xff\xf7\x0e\x1e\xa0\xff\xff\xff\xff\xf8Q,0\xff\xff\xff\xff\xf8\xc7\xc5 \xff\xff\xff\xff\xfa\nҰ\xff" +
-	"\xff\xff\xff\xfa\xa8\xf8\xa0\xff\xff\xff\xff\xfb\xec\x060\xff\xff\xff\xff\xfc\x8b}\xa0\x00\x00\x00\x00\x1dɎ0\x00\x00\x00\x00\x1exנ\x00\x00\x00\x00\x1f\xa05\xb0\x00\x00\x00\x00 3Ϡ\x00\x00\x00\x00!" +
-	"\x81i0\x00\x00\x00\x00\"\vȠ\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xffҌ\x00\x00\xff\xff\xe3\xe0\x01\x04\xff\xff\xd5\xd0\x00\bLM" +
-	"T\x00-02\x00-03\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTs\xb0\xeau\xb4\x01\x00\x00\xb4\x01\x00\x00\x10\x00\x1c\x00America/Eiru" +
-	"nepeUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00!\x00" +
-	"\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xff\x96\xaa\x88\x80\xff\xff\xff\xff\xb8\x0ff\x00\xff\xff\xff\xff\xb8\xfd\\\xc0\xff\xff\xff\xff\xb9\xf1PP\xff\xff\xff\xff\xbaސ@\xff\xff\xff\xff\xda8\xcaP\xff\xff\xff\xff\xda" +
-	"\xec\x16P\xff\xff\xff\xff\xdc\x19\xfd\xd0\xff\xff\xff\xffܹu@\xff\xff\xff\xff\xdd\xfb1P\xff\xff\xff\xffޛ\xfa@\xff\xff\xff\xff\xdfݶP\xff\xff\xff\xff\xe0TO@\xff\xff\xff\xff\xf4\x98\x1b\xd0\xff" +
-	"\xff\xff\xff\xf5\x05z@\xff\xff\xff\xff\xf6\xc0\x80P\xff\xff\xff\xff\xf7\x0e:\xc0\xff\xff\xff\xff\xf8QHP\xff\xff\xff\xff\xf8\xc7\xe1@\xff\xff\xff\xff\xfa\n\xee\xd0\xff\xff\xff\xff\xfa\xa9\x14\xc0\xff\xff\xff\xff\xfb" +
-	"\xec\"P\xff\xff\xff\xff\xfc\x8b\x99\xc0\x00\x00\x00\x00\x1dɪP\x00\x00\x00\x00\x1ex\xf3\xc0\x00\x00\x00\x00\x1f\xa0Q\xd0\x00\x00\x00\x00 3\xeb\xc0\x00\x00\x00\x00!\x81\x85P\x00\x00\x00\x00\"\v\xe4\xc0\x00" +
-	"\x00\x00\x00,\xc0\xd1P\x00\x00\x00\x00-f\xe0@\x00\x00\x00\x00H`\x7fP\x00\x00\x00\x00R\x7f\x04\xc0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x03\x02\xff\xff\xbe\x80\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x00\x04LMT\x00-04\x00-05\x00\n<-05>5\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj" +
-	"\xbeTq\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x1c\x00America/St_LuciaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_" +
-	"\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4" +
-	"p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nP" +
-	"K\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTOKjǪ\x02\x00\x00\xaa\x02\x00\x00\r\x00\x1c\x00America/BahiaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01" +
-	"\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" +
-	"\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaak\x1c\xff\xff\xff\xff\xb8\x0fI" +
-	"\xe0\xff\xff\xff\xff\xb8\xfd@\xa0\xff\xff\xff\xff\xb9\xf140\xff\xff\xff\xff\xba\xdet \xff\xff\xff\xff\xda8\xae0\xff\xff\xff\xff\xda\xeb\xfa0\xff\xff\xff\xff\xdc\x19\xe1\xb0\xff\xff\xff\xffܹY \xff\xff\xff" +
-	"\xff\xdd\xfb\x150\xff\xff\xff\xffޛ\xde \xff\xff\xff\xff\xdfݚ0\xff\xff\xff\xff\xe0T3 \xff\xff\xff\xff\xf4\x97\xff\xb0\xff\xff\xff\xff\xf5\x05^ \xff\xff\xff\xff\xf6\xc0d0\xff\xff\xff\xff\xf7\x0e\x1e" +
-	"\xa0\xff\xff\xff\xff\xf8Q,0\xff\xff\xff\xff\xf8\xc7\xc5 \xff\xff\xff\xff\xfa\nҰ\xff\xff\xff\xff\xfa\xa8\xf8\xa0\xff\xff\xff\xff\xfb\xec\x060\xff\xff\xff\xff\xfc\x8b}\xa0\x00\x00\x00\x00\x1dɎ0\x00\x00\x00" +
-	"\x00\x1exנ\x00\x00\x00\x00\x1f\xa05\xb0\x00\x00\x00\x00 3Ϡ\x00\x00\x00\x00!\x81i0\x00\x00\x00\x00\"\vȠ\x00\x00\x00\x00#X\x10\xb0\x00\x00\x00\x00#\xe2p \x00\x00\x00\x00%7\xf2" +
-	"\xb0\x00\x00\x00\x00%\xd4\xc7 \x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xbd\xe3\xa0\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\x94\x8b \x00\x00\x00\x00*\xea\r\xb0\x00\x00\x00\x00+k2\xa0\x00\x00\x00" +
-	"\x00,\xc0\xb50\x00\x00\x00\x00-f\xc4 \x00\x00\x00\x00.\xa0\x970\x00\x00\x00\x00/F\xa6 \x00\x00\x00\x000\x80y0\x00\x00\x00\x001\x1dM\xa0\x00\x00\x00\x002W \xb0\x00\x00\x00\x003\x06j" +
-	" \x00\x00\x00\x0048T0\x00\x00\x00\x004\xf8\xc1 \x00\x00\x00\x006 \x1f0\x00\x00\x00\x006\xcfh\xa0\x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xb8\x85 \x00\x00\x00\x009\xdf\xe30\x00\x00\x00" +
-	"\x00:\x8f,\xa0\x00\x00\x00\x00;\xc8\xff\xb0\x00\x00\x00\x00<o\x0e\xa0\x00\x00\x00\x00=đ0\x00\x00\x00\x00>N\xf0\xa0\x00\x00\x00\x00N\x9aH\xb0\x00\x00\x00\x00OI\x92 \x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xdb\xe4\x00\x00" +
-	"\xff\xff\xe3\xe0\x01\x04\xff\xff\xd5\xd0\x00\bLMT\x00-02\x00-03\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xc1Ȇ\x90\x05\x04\x00\x00\x05\x04\x00\x00\x12\x00" +
-	"\x1c\x00America/WhitehorseUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]\x00\x00\x00\t\x00\x00\x00%\xff\xff\xff\xff}\x86\x8a\x9c\xff\xff\xff\xff\x9e\xb8˰\xff\xff\xff\xff\x9f\xbb#\xa0\xff\xff\xff\xff\xa0\xd0\f\xb0\xff\xff\xff\xff\xa1" +
-	"\xa2Ҁ\xff\xff\xff\xffˉ(\xb0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a4 \xff\xff\xff\xff\xf7/v\x90\xff\xff\xff\xff\xf8(\xa2\x10\xff\xff\xff\xff\xfb\x1d_\x10\x00\x00\x00\x00\x13ir \x00" +
-	"\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a" +
-	"\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1ې\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00" +
-	"\x00\x00\x00\"V\r \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)" +
-	"\n\x80\x10\x00\x00\x00\x00)\xdeϠ\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00" +
-	"\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007" +
-	"\a8 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00" +
-	"\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00E" +
-	"Dm\x90\x00\x00\x00\x00E\xf3\xd3 \x00\x00\x00\x00G-\x8a\x10\x00\x00\x00\x00Gӵ \x00\x00\x00\x00I\rl\x10\x00\x00\x00\x00I\xb3\x97 \x00\x00\x00\x00J\xedN\x10\x00\x00\x00\x00K\x9c\xb3\xa0\x00" +
-	"\x00\x00\x00L\xd6j\x90\x00\x00\x00\x00M|\x95\xa0\x00\x00\x00\x00N\xb6L\x90\x00\x00\x00\x00O\\w\xa0\x00\x00\x00\x00P\x96.\x90\x00\x00\x00\x00Q<Y\xa0\x00\x00\x00\x00Rv\x10\x90\x00\x00\x00\x00S" +
-	"\x1c;\xa0\x00\x00\x00\x00TU\xf2\x90\x00\x00\x00\x00T\xfc\x1d\xa0\x00\x00\x00\x00V5Ԑ\x00\x00\x00\x00V\xe5: \x00\x00\x00\x00X\x1e\xf1\x10\x00\x00\x00\x00X\xc5\x1c \x00\x00\x00\x00Y\xfe\xd3\x10\x00" +
-	"\x00\x00\x00Z\xa4\xfe \x00\x00\x00\x00[\u07b5\x10\x00\x00\x00\x00\\\x84\xe0 \x00\x00\x00\x00]\xbe\x97\x10\x00\x00\x00\x00^d\xc2 \x00\x00\x00\x00_\x9e\\\xf0\x02\x01\x02\x01\x02\x03\x04\x02\x05\x02\x06\a\x06" +
-	"\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06" +
-	"\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\b\xff\xff\x81d\x00\x00\xff\xff\x8f\x80\x01\x04\xff\xff\x81p\x00\b\xff\xff\x8f\x80\x01\f\xff\xff\x8f\x80\x01\x10\xff\xff\x9d\x90\x01\x14\xff\xff\x8f\x80" +
-	"\x00\x19\xff\xff\x9d\x90\x01\x1d\xff\xff\x9d\x90\x00!LMT\x00YDT\x00YST\x00YWT\x00YPT\x00YDDT\x00PST\x00PDT\x00MST\x00\nMST7\nPK\x03" +
-	"\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTq\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0f\x00\x1c\x00America/TortolaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01" +
-	"\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" +
-	"\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62" +
-	"\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT" +
-	"\x00\nAST4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTU9#\xbe2\x05\x00\x002\x05\x00\x00\x11\x00\x1c\x00America/VancouverUT\t\x00\x03\xdd" +
-	"\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff" +
-	"\xff^=v\xec\xff\xff\xff\xff\x9e\xb8\xbd\xa0\xff\xff\xff\xff\x9f\xbb\x15\x90\xff\xff\xff\xffˉ\x1a\xa0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a&\x10\xff\xff\xff\xff\xd3v\x0f \xff\xff\xff\xff\xd4A\b" +
-	"\x10\xff\xff\xff\xff\xd5U\xf1 \xff\xff\xff\xff\xd6 \xea\x10\xff\xff\xff\xff\xd75\xd3 \xff\xff\xff\xff\xd8\x00\xcc\x10\xff\xff\xff\xff\xd9\x15\xb5 \xff\xff\xff\xff\xd9\xe0\xae\x10\xff\xff\xff\xff\xda\xfeѠ\xff\xff\xff" +
-	"\xff\xdb\xc0\x90\x10\xff\xff\xff\xff\xdc\u07b3\xa0\xff\xff\xff\xffݩ\xac\x90\xff\xff\xff\xff\u07be\x95\xa0\xff\xff\xff\xff߉\x8e\x90\xff\xff\xff\xff\xe0\x9ew\xa0\xff\xff\xff\xff\xe1ip\x90\xff\xff\xff\xff\xe2~Y" +
-	"\xa0\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4^;\xa0\xff\xff\xff\xff\xe5)4\x90\xff\xff\xff\xff\xe6GX \xff\xff\xff\xff\xe7\x12Q\x10\xff\xff\xff\xff\xe8': \xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff" +
-	"\xff\xea\a\x1c \xff\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff\xff\xeb\xe6\xfe \xff\xff\xff\xff\xec\xb1\xf7\x10\xff\xff\xff\xff\xed\xc6\xe0 \xff\xff\xff\xff\xee\x91\xd9\x10\xff\xff\xff\xff\xef\xaf\xfc\xa0\xff\xff\xff\xff\xf0q\xbb" +
-	"\x10\xff\xff\xff\xff\xf1\x8fޠ\xff\xff\xff\xff\xf2\x7f\xc1\x90\xff\xff\xff\xff\xf3o\xc0\xa0\xff\xff\xff\xff\xf4_\xa3\x90\xff\xff\xff\xff\xf5O\xa2\xa0\xff\xff\xff\xff\xf6?\x85\x90\xff\xff\xff\xff\xf7/\x84\xa0\xff\xff\xff" +
-	"\xff\xf8(\xa2\x10\xff\xff\xff\xff\xf9\x0ff\xa0\xff\xff\xff\xff\xfa\b\x84\x10\xff\xff\xff\xff\xfa\xf8\x83 \xff\xff\xff\xff\xfb\xe8f\x10\xff\xff\xff\xff\xfc\xd8e \xff\xff\xff\xff\xfd\xc8H\x10\xff\xff\xff\xff\xfe\xb8G" +
-	" \xff\xff\xff\xff\xff\xa8*\x10\x00\x00\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88\f\x10\x00\x00\x00\x00\x02x\v \x00\x00\x00\x00\x03q(\x90\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05Q\n\x90\x00\x00\x00" +
-	"\x00\x06A\t\xa0\x00\x00\x00\x00\a0\xec\x90\x00\x00\x00\x00\b \xeb\xa0\x00\x00\x00\x00\t\x10ΐ\x00\x00\x00\x00\n\x00͠\x00\x00\x00\x00\n\xf0\xb0\x90\x00\x00\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd" +
-	"\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00" +
-	"\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24" +
-	"\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1ې\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00" +
-	"\x00\"V\r \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\n\x80" +
-	"\x10\x00\x00\x00\x00)\xdeϠ\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00" +
-	"\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\a8" +
-	" \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00" +
-	"\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm" +
-	"\x90\x00\x00\x00\x00E\xf3\xd3 \x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\x8c\x94\x00\x00\xff\xff\x9d\x90\x01\x04\xff\xff\x8f\x80\x00\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10LMT\x00PDT\x00PST\x00" +
-	"PWT\x00PPT\x00\nPST8PDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xf7\xe9 y\xbd\x02\x00\x00\xbd\x02\x00\x00\x0e\x00" +
-	"\x1c\x00America/InuvikUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00;\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xff\xe0\x06N\x80\xff\xff\xff\xff\xf7/h\x80\xff\xff\xff\xff\xf8(\x94\x00\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x13id\x10\x00" +
-	"\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a" +
-	"\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00" +
-	"\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeߐ\x00\x00\x00\x00)" +
-	"\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00" +
-	"\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007" +
-	"\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00" +
-	"\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00E" +
-	"D_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x02\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" +
-	"\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x00\x00\x00\x00\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x8f\x80\x00\t\xff\xff\x9d\x90\x00\r\xff\xff\xab\xa0\x01\x11-00\x00PDDT\x00PST\x00MST\x00MDT" +
-	"\x00\nMST7MDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xb4T\xbd\xeb5\x02\x00\x005\x02\x00\x00\x16\x00\x1c\x00Ameri" +
-	"ca/Port-au-PrinceUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xffi\x87\x1fP\xff\xff\xff\xff\x9cnq\xfc\x00\x00\x00\x00\x19\x1bF\xd0\x00\x00\x00\x00\x1a\x01\xef@\x00\x00\x00\x00\x1a\xf1\xeeP" +
-	"\x00\x00\x00\x00\x1b\xe1\xd1@\x00\x00\x00\x00\x1c\xd1\xd0P\x00\x00\x00\x00\x1d\xc1\xb3@\x00\x00\x00\x00\x1e\xb1\xb2P\x00\x00\x00\x00\x1f\xa1\x95@\x00\x00\x00\x00 \x91\x94P\x00\x00\x00\x00!\x81w@\x00\x00\x00\x00" +
-	"\"U\xd4\xe0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xb6\xe0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\x98\xe0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xb5`\x00\x00\x00\x00)\nU\xe0" +
-	"\x00\x00\x00\x00)ޗ`\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbey`\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9e[`\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~=`\x00\x00\x00\x00" +
-	"0\x93\x18`\x00\x00\x00\x001gY\xe0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003G;\xe0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x00BOxP\x00\x00\x00\x00CdE@\x00\x00\x00\x00D/ZP" +
-	"\x00\x00\x00\x00ED'@\x00\x00\x00\x00O\\Mp\x00\x00\x00\x00P\x96\x04`\x00\x00\x00\x00Q</p\x00\x00\x00\x00Ru\xe6`\x00\x00\x00\x00S\x1c\x11p\x00\x00\x00\x00TU\xc8`\x00\x00\x00\x00" +
-	"T\xfb\xf3p\x00\x00\x00\x00V5\xaa`\x00\x00\x00\x00X\xc4\xf1\xf0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
-	"\x02\x03\x02\x03\x02\xff\xff\xbc0\x00\x00\xff\xff\xbcD\x00\x04\xff\xff\xc7\xc0\x01\t\xff\xff\xb9\xb0\x00\rLMT\x00PPMT\x00EDT\x00EST\x00\nEST5EDT,M3.2." +
-	"0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xb4\x11Z\xde\xe4\x01\x00\x00\xe4\x01\x00\x00\x11\x00\x1c\x00America/FortalezaUT\t" +
-	"\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\x00\x00\x00\x03\x00\x00\x00\f" +
-	"\xff\xff\xff\xff\x96\xaak\x18\xff\xff\xff\xff\xb8\x0fI\xe0\xff\xff\xff\xff\xb8\xfd@\xa0\xff\xff\xff\xff\xb9\xf140\xff\xff\xff\xff\xba\xdet \xff\xff\xff\xff\xda8\xae0\xff\xff\xff\xff\xda\xeb\xfa0\xff\xff\xff\xff" +
-	"\xdc\x19\xe1\xb0\xff\xff\xff\xffܹY \xff\xff\xff\xff\xdd\xfb\x150\xff\xff\xff\xffޛ\xde \xff\xff\xff\xff\xdfݚ0\xff\xff\xff\xff\xe0T3 \xff\xff\xff\xff\xf4\x97\xff\xb0\xff\xff\xff\xff\xf5\x05^ " +
-	"\xff\xff\xff\xff\xf6\xc0d0\xff\xff\xff\xff\xf7\x0e\x1e\xa0\xff\xff\xff\xff\xf8Q,0\xff\xff\xff\xff\xf8\xc7\xc5 \xff\xff\xff\xff\xfa\nҰ\xff\xff\xff\xff\xfa\xa8\xf8\xa0\xff\xff\xff\xff\xfb\xec\x060\xff\xff\xff\xff" +
-	"\xfc\x8b}\xa0\x00\x00\x00\x00\x1dɎ0\x00\x00\x00\x00\x1exנ\x00\x00\x00\x00\x1f\xa05\xb0\x00\x00\x00\x00 3Ϡ\x00\x00\x00\x00!\x81i0\x00\x00\x00\x00\"\vȠ\x00\x00\x00\x00#X\x10\xb0" +
-	"\x00\x00\x00\x00#\xe2p \x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xd4\xc7 \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xb8\x85 \x00\x00\x00\x009\xdf\xe30\x00\x00\x00\x009\xf2J \x00\x00\x00\x00" +
-	";\xc8\xff\xb0\x00\x00\x00\x00<o\x0e\xa0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xdb\xe8\x00\x00\xff\xff\xe3" +
-	"\xe0\x01\x04\xff\xff\xd5\xd0\x00\bLMT\x00-02\x00-03\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xb7-2f\xe4\x01\x00\x00\xe4\x01\x00\x00\x0f\x00\x1c\x00A" +
-	"merica/NoronhaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00'\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaaed\xff\xff\xff\xff\xb8\x0f;\xd0\xff\xff\xff\xff\xb8\xfd2\x90\xff\xff\xff\xff\xb9\xf1& \xff\xff\xff\xff\xba\xdef\x10\xff\xff\xff" +
-	"\xff\xda8\xa0 \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdc\x19Ӡ\xff\xff\xff\xffܹK\x10\xff\xff\xff\xff\xdd\xfb\a \xff\xff\xff\xffޛ\xd0\x10\xff\xff\xff\xff\xdf\u074c \xff\xff\xff\xff\xe0T%" +
-	"\x10\xff\xff\xff\xff\xf4\x97\xf1\xa0\xff\xff\xff\xff\xf5\x05P\x10\xff\xff\xff\xff\xf6\xc0V \xff\xff\xff\xff\xf7\x0e\x10\x90\xff\xff\xff\xff\xf8Q\x1e \xff\xff\xff\xff\xf8Ƿ\x10\xff\xff\xff\xff\xfa\nĠ\xff\xff\xff" +
-	"\xff\xfa\xa8\xea\x90\xff\xff\xff\xff\xfb\xeb\xf8 \xff\xff\xff\xff\xfc\x8bo\x90\x00\x00\x00\x00\x1dɀ \x00\x00\x00\x00\x1exɐ\x00\x00\x00\x00\x1f\xa0'\xa0\x00\x00\x00\x00 3\xc1\x90\x00\x00\x00\x00!\x81[" +
-	" \x00\x00\x00\x00\"\v\xba\x90\x00\x00\x00\x00#X\x02\xa0\x00\x00\x00\x00#\xe2b\x10\x00\x00\x00\x00%7\xe4\xa0\x00\x00\x00\x00%Թ\x10\x00\x00\x00\x007\xf6\xb8\xa0\x00\x00\x00\x008\xb8w\x10\x00\x00\x00" +
-	"\x009\xdf\xd5 \x00\x00\x00\x009\xe9\x01\x90\x00\x00\x00\x00;\xc8\xf1\xa0\x00\x00\x00\x00<o\x00\x90\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xe1\x9c\x00\x00\xff\xff\xf1\xf0\x01\x04\xff\xff\xe3\xe0\x00\bLMT\x00-01\x00-02\x00\n<-02>2\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT" +
-	"\xe0\xbf\xf5\xe5\xc4\x02\x00\x00\xc4\x02\x00\x00\x14\x00\x1c\x00America/Buenos_AiresUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04" +
-	"S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xa8L\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6" +
-	"{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff" +
-	"\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4" +
-	"\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff" +
-	"\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf6" +
-	"2\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff" +
-	"\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%" +
-	"7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00" +
-	"\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x00\x00\x00\x00H\xfa\xa2\xb0\x00\x00\x00\x00I\xbca \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
-	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x03\x05\x04\x05\x04\x05\xff\xff\xc94\x00\x00\xff\xff\xc3\xd0\x00\x04" +
-	"\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00" +
-	"\x00\x00\x8fj\xbeT\xf6\"\x12\xfe\x0e\x05\x00\x00\x0e\x05\x00\x00\x13\x00\x1c\x00America/Los_AngelesUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04" +
-	"\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" +
-	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00}\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff^\x04\x1a\xc0\xff\xff\xff\xff\x9e\xa6H\xa0" +
-	"\xff\xff\xff\xff\x9f\xbb\x15\x90\xff\xff\xff\xff\xa0\x86*\xa0\xff\xff\xff\xff\xa1\x9a\xf7\x90\xff\xff\xff\xffˉ\x1a\xa0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a&\x10\xff\xff\xff\xff\xd6\xfet\\\xff\xff\xff\xff" +
-	"\u0600\xad\x90\xff\xff\xff\xff\xda\xfeÐ\xff\xff\xff\xff\xdb\xc0\x90\x10\xff\xff\xff\xff\xdcޥ\x90\xff\xff\xff\xffݩ\xac\x90\xff\xff\xff\xff\u07be\x87\x90\xff\xff\xff\xff߉\x8e\x90\xff\xff\xff\xff\xe0\x9ei\x90" +
-	"\xff\xff\xff\xff\xe1ip\x90\xff\xff\xff\xff\xe2~K\x90\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4^-\x90\xff\xff\xff\xff\xe5)4\x90\xff\xff\xff\xff\xe6GJ\x10\xff\xff\xff\xff\xe7\x12Q\x10\xff\xff\xff\xff" +
-	"\xe8',\x10\xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff\xff\xea\a\x0e\x10\xff\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff\xff\xeb\xe6\xf0\x10\xff\xff\xff\xff\xec\xb1\xf7\x10\xff\xff\xff\xff\xed\xc6\xd2\x10\xff\xff\xff\xff\xee\x91\xd9\x10" +
-	"\xff\xff\xff\xff\xef\xaf\xee\x90\xff\xff\xff\xff\xf0q\xbb\x10\xff\xff\xff\xff\xf1\x8fА\xff\xff\xff\xff\xf2\x7f\xc1\x90\xff\xff\xff\xff\xf3o\xb2\x90\xff\xff\xff\xff\xf4_\xa3\x90\xff\xff\xff\xff\xf5O\x94\x90\xff\xff\xff\xff" +
-	"\xf6?\x85\x90\xff\xff\xff\xff\xf7/v\x90\xff\xff\xff\xff\xf8(\xa2\x10\xff\xff\xff\xff\xf9\x0fX\x90\xff\xff\xff\xff\xfa\b\x84\x10\xff\xff\xff\xff\xfa\xf8\x83 \xff\xff\xff\xff\xfb\xe8f\x10\xff\xff\xff\xff\xfc\xd8e " +
-	"\xff\xff\xff\xff\xfd\xc8H\x10\xff\xff\xff\xff\xfe\xb8G \xff\xff\xff\xff\xff\xa8*\x10\x00\x00\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88\f\x10\x00\x00\x00\x00\x02x\v \x00\x00\x00\x00\x03q(\x90\x00\x00\x00\x00" +
-	"\x04a'\xa0\x00\x00\x00\x00\x05Q\n\x90\x00\x00\x00\x00\x06A\t\xa0\x00\x00\x00\x00\a0\xec\x90\x00\x00\x00\x00\a\x8dC\xa0\x00\x00\x00\x00\t\x10ΐ\x00\x00\x00\x00\t\xad\xbf \x00\x00\x00\x00\n\xf0\xb0\x90" +
-	"\x00\x00\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00" +
-	"\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 " +
-	"\x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1ې\x00\x00\x00\x00" +
-	" v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\"V\r \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10" +
-	"\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\n\x80\x10\x00\x00\x00\x00)\xdeϠ\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00" +
-	".\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V " +
-	"\x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\a8 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00" +
-	"<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90" +
-	"\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E\xf3\xd3 \x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\x91&\x00\x00\xff\xff\x9d\x90\x01\x04\xff\xff\x8f\x80\x00\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10L" +
-	"MT\x00PDT\x00PST\x00PWT\x00PPT\x00\nPST8PDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xea$\xc1" +
-	"\xbf\xb0\x00\x00\x00\xb0\x00\x00\x00\x13\x00\x1c\x00America/El_SalvadorUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00" +
+	"d}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" +
+	"\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x00\x00\x00\x00\x00\x00\xff\xff\x9d\x90\x01\x04\xff\xff\x8f\x80\x00\b\xff\xff\x9d" +
+	"\x90\x00\f\xff\xff\xab\xa0\x01\x10-00\x00PDT\x00PST\x00MST\x00MDT\x00\nMST7MDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00Š\xd6\x05W\x03\x00\x00W\x03\x00\x00\x0f\x00\x00\x00America/IqaluitTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00J\x00\x00\x00\a\x00\x00\x00\x1c\xff\xff\xff\xff\xccl\xa1\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdf" +
+	"p\x00\x00\x00\x00\a0\xc2`\x00\x00\x00\x00\b \xc1p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\n\x00\xa3p\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00\f٢\xe0\x00\x00\x00" +
+	"\x00\r\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*" +
+	"\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x00\x00\x00\x00\x1a\xf2\np\x00\x00\x00" +
+	"\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\"U\xe2" +
+	"\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\nU\xe0\x00\x00\x00" +
+	"\x00)ޥp\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18" +
+	"`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\a\r\xf0\x00\x00\x00" +
+	"\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0" +
+	"p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00" +
+	"\x00E\xf3\xa8\xf0\x04\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x05\x06\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00\x00\x00\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\f\xff\xff\xc7\xc0\x01\x10\xff\xff\xab\xa0\x00\x14\xff\xff\xb9\xb0\x01" +
+	"\x18-00\x00EPT\x00EST\x00EDT\x00EWT\x00CST\x00CDT\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00%J\xd5\xebS\x01\x00\x00S\x01\x00\x00\x0f\x00\x00\x00America/JamaicaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x16\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffi\x87#~\xff\xff\xff\xff\x93\x0f\xb4\xfe\x00\x00\x00\x00\a\x8d\x19p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\t\xad\x94\xf0\x00\x00\x00\x00\n\xf0\x86" +
+	"`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00\f٢\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00" +
+	"\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed" +
+	"\xf0\x00\x00\x00\x00\x1a\x02\v`\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\xff\xff\xb8\x02\x00\x00\xff\xff\xb8\x02\x00\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\fLMT\x00K" +
+	"MT\x00EST\x00EDT\x00\nEST5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00utZ\x1a\xb2\x02\x00\x00\xb2\x02\x00\x00\r\x00\x00\x00America/Jujuy" +
 	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\xa3զ \x00\x00\x00\x00 \x9a\xdc\xe0\x00\x00\x00\x00!\\\x9bP\x00" +
-	"\x00\x00\x00\"z\xbe\xe0\x00\x00\x00\x00#<}P\x02\x01\x02\x01\x02\xff\xff\xac`\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\bLMT\x00CDT\x00CST\x00\nCST6\nPK\x03\x04" +
-	"\n\x00\x00\x00\x00\x00\x8fj\xbeTV\x80\x94@\x12\x04\x00\x00\x12\x04\x00\x00\x0e\x00\x1c\x00America/DenverUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91" +
-	"\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00T" +
-	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff^\x04\f\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff" +
-	"\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff\xff\xff\xa2e\xfe\x90\xff\xff\xff\xff\xa3\x84\x06\x00\xff\xff\xff\xff\xa4E\xe0\x90\xff\xff\xff\xff\xa4\x8f\xa6\x80\xff\xff\xff\xff\xcb" +
-	"\x89\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xf7/v\x90\xff\xff\xff\xff\xf8(\x94\x00\xff\xff\xff\xff\xf9\x0fX\x90\xff\xff\xff\xff\xfa\bv\x00\xff\xff\xff\xff\xfa\xf8u\x10\xff" +
-	"\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W\x10\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb89\x10\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x1b\x10\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02" +
-	"w\xfd\x10\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\a\x8d5\x90\x00\x00\x00\x00\t\x10\xc0\x80\x00" +
-	"\x00\x00\x00\t\xad\xb1\x10\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\vࡐ\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10" +
-	"\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00" +
-	"\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e" +
-	"\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00" +
-	"\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeߐ\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00," +
-	"\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00" +
-	"\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:" +
-	"\xc6\xee\x10\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00" +
-	"\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\x9d\x94\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10LMT\x00MDT\x00MST\x00MW" +
-	"T\x00MPT\x00\nMST7MDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTp\xb6{\xc9\x13\x02\x00\x00\x13\x02\x00\x00\x12\x00\x1c\x00" +
-	"America/Fort_WayneUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&\x00\x00\x00\a\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdb" +
-	"p\xff\xff\xff\xff\xcaW\"\x80\xff\xff\xff\xff\xca\xd8Gp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd3u\xf3\x00\xff\xff\xff\xff\xd4@\xeb\xf0\xff\xff\xff" +
-	"\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s" +
-	"\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90p\xff\xff\xff\xff\u07bey\x80\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff" +
-	"\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1" +
-	"\xe0\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x02\x05\x06\x05\x06\x05" +
-	"\x06\x05\x06\xff\xff\xaf:\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18LMT\x00CDT\x00CST\x00CWT" +
-	"\x00CPT\x00EST\x00EDT\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x11\x00\x1c\x00America/Kentucky/UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x03\x04\n\x00\x00\x00" +
-	"\x00\x00\x8fj\xbeT\xdf\xe5\x8d\xc4\xda\x04\x00\x00\xda\x04\x00\x00\x1b\x00\x1c\x00America/Kentucky/LouisvilleUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc" +
-	"\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00;\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xae\xb8\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff" +
+	"\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd" +
+	"\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff" +
+	"\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xce" +
+	"M\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff" +
+	"\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd" +
+	"\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00" +
+	"\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'*W\xc0\x00\x00\x00\x00'\xe2۰\x00\x00\x00\x00(\xee\x8a@\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007" +
+	"\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x02\x03\x02\x04\x05\x04\x05\x03\x05\x04\x05\xff\xff\xc2\xc8\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0" +
+	"\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\xc9\x1c\xd4\xc6\x03\x00\x00\xc6\x03\x00\x00\x0e\x00\x00\x00" +
+	"America/JuneauTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00" +
+	"\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S\x00\x00\x00\n\x00\x00\x00&\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff" +
+	"\xff}\x872\xc5\xff\xff\xff\xffˉ\x1a\xa0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a&\x10\xff\xff\xff\xff\xfe\xb8G \xff\xff\xff\xff\xff\xa8*\x10\x00\x00\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88\f" +
+	"\x10\x00\x00\x00\x00\x02x\v \x00\x00\x00\x00\x03q(\x90\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05Q\n\x90\x00\x00\x00\x00\x06A\t\xa0\x00\x00\x00\x00\a0\xec\x90\x00\x00\x00\x00\a\x8dC\xa0\x00\x00\x00" +
+	"\x00\t\x10ΐ\x00\x00\x00\x00\t\xad\xbf \x00\x00\x00\x00\n\xf0\xb0\x90\x00\x00\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae" +
+	" \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14Yc \x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00" +
+	"\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a+\x14\x10\x00\x00\x00\x00\x1a\xf2B\xb0\x00\x00\x00\x00\x1b\xe2%\xa0\x00\x00\x00\x00\x1c\xd2$" +
+	"\xb0\x00\x00\x00\x00\x1d\xc2\a\xa0\x00\x00\x00\x00\x1e\xb2\x06\xb0\x00\x00\x00\x00\x1f\xa1\xe9\xa0\x00\x00\x00\x00 v90\x00\x00\x00\x00!\x81ˠ\x00\x00\x00\x00\"V\x1b0\x00\x00\x00\x00#j\xe8 \x00\x00\x00" +
+	"\x00$5\xfd0\x00\x00\x00\x00%J\xca \x00\x00\x00\x00&\x15\xdf0\x00\x00\x00\x00'*\xac \x00\x00\x00\x00'\xfe\xfb\xb0\x00\x00\x00\x00)\n\x8e \x00\x00\x00\x00)\xdeݰ\x00\x00\x00\x00*\xeap" +
+	" \x00\x00\x00\x00+\xbe\xbf\xb0\x00\x00\x00\x00,ӌ\xa0\x00\x00\x00\x00-\x9e\xa1\xb0\x00\x00\x00\x00.\xb3n\xa0\x00\x00\x00\x00/~\x83\xb0\x00\x00\x00\x000\x93P\xa0\x00\x00\x00\x001g\xa00\x00\x00\x00" +
+	"\x002s2\xa0\x00\x00\x00\x003G\x820\x00\x00\x00\x004S\x14\xa0\x00\x00\x00\x005'd0\x00\x00\x00\x0062\xf6\xa0\x00\x00\x00\x007\aF0\x00\x00\x00\x008\x1c\x13 \x00\x00\x00\x008\xe7(" +
+	"0\x00\x00\x00\x009\xfb\xf5 \x00\x00\x00\x00:\xc7\n0\x00\x00\x00\x00;\xdb\xd7 \x00\x00\x00\x00<\xb0&\xb0\x00\x00\x00\x00=\xbb\xb9 \x00\x00\x00\x00>\x90\b\xb0\x00\x00\x00\x00?\x9b\x9b \x00\x00\x00" +
+	"\x00@o\xea\xb0\x00\x00\x00\x00A\x84\xb7\xa0\x00\x00\x00\x00BO̰\x00\x00\x00\x00Cd\x99\xa0\x00\x00\x00\x00D/\xae\xb0\x00\x00\x00\x00ED{\xa0\x00\x00\x00\x00E\xf3\xe10\x01\x02\x03\x04\x02\x05\x02" +
+	"\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x06\x02\x05\x02\x05\x02\x05\a\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b" +
+	"\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\x00\x00\xd3{\x00\x00\xff\xff\x81\xfb\x00\x00\xff\xff\x8f\x80\x00\x04\xff\xff\x9d\x90\x01\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10\xff\xff\x8f\x80\x01\x14\xff\xff" +
+	"\x81p\x00\x18\xff\xff\x8f\x80\x01\x1c\xff\xff\x81p\x00!LMT\x00PST\x00PWT\x00PPT\x00PDT\x00YDT\x00YST\x00AKDT\x00AKST\x00\nAKST9" +
+	"AKDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdf\xe5\x8d\xc4\xda\x04\x00\x00\xda\x04\x00\x00\x1b\x00\x00\x00America/Ke" +
+	"ntucky/LouisvilleTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" +
 	"\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00u\x00\x00\x00\a\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0" +
 	"\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xa4s\xf7\x00\xff\xff\xff\xff\xa5\x16\x11p\xff\xff\xff\xff\xca\rN\x80\xff\xff\xff\xff" +
 	"\xca\xd8Gp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd3u\xd7\x1c\xff\xff\xff\xffӤ\tp\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0" +
@@ -1678,45 +1335,448 @@
 	"\x01\x02\x01\x02\x01\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x01\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" +
 	"\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xaf\x9a\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00" +
 	"\x14\xff\xff\xc7\xc0\x01\x18LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00EDT\x00\nEST5EDT,M3.2.0,M11.1.0\nP" +
-	"K\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x03\x1a|J\xcc\x03\x00\x00\xcc\x03\x00\x00\x1b\x00\x1c\x00America/Kentucky/MonticelloUT\t\x00" +
-	"\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00W\x00\x00\x00\a\x00\x00\x00\x1c\xff" +
-	"\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2" +
-	"a\t\xf0\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8+\xf0\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\r\xf0\x00\x00\x00\x00\x00\x98\r\x00\x00\x00\x00\x00\x01\x87\xef\xf0\x00\x00\x00\x00\x02w\xef\x00\x00" +
-	"\x00\x00\x00\x03q\fp\x00\x00\x00\x00\x04a\v\x80\x00\x00\x00\x00\x05P\xeep\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\a0\xd0p\x00\x00\x00\x00\a\x8d'\x80\x00\x00\x00\x00\t\x10\xb2p\x00\x00\x00\x00\t" +
-	"\xad\xa3\x00\x00\x00\x00\x00\n\xf0\x94p\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00\x00\x00\fٰ\xf0\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99t\xf0\x00" +
-	"\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18" +
-	"\"7p\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1܀\x00" +
-	"\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00&" +
-	"\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)\nc\xf0\x00\x00\x00\x00)\u07b3\x80\x00\x00\x00\x00*\xeaE\xf0\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3bp\x00" +
-	"\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3Dp\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x93&p\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004" +
-	"R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xd1\xf0\x00" +
-	"\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00B" +
-	"O\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" +
-	"\x06\x05\xff\xff\xb0t\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xc7\xc0\x01\x14\xff\xff\xb9\xb0\x00\x18LMT\x00CDT\x00CST\x00CWT\x00" +
-	"CPT\x00EDT\x00EST\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x15\x00\x1c\x00America/North_Dakota/UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x03\x04\n" +
-	"\x00\x00\x00\x00\x00\x8fj\xbeTR\x1b\x8b(\xde\x03\x00\x00\xde\x03\x00\x00\x1e\x00\x1c\x00America/North_Dakota/New_SalemUT\t\x00\x03" +
-	"\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y\x00\x00\x00\a\x00\x00\x00\x1c\xff\xff" +
-	"\xff\xff^\x04\f\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a" +
-	"\x18\x00\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W\x10\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb89\x10\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x1b\x10\x00\x00" +
-	"\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xfd\x10\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\a\x8d" +
-	"5\x90\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\t\xad\xb1\x10\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\vࡐ\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00" +
-	"\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169" +
-	")\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00" +
-	"\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5" +
-	"\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeߐ\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00" +
-	"\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s" +
-	"\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00" +
-	"\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@o" +
-	"\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02" +
+	"K\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x1a|J\xcc\x03\x00\x00\xcc\x03\x00\x00\x1b\x00\x00\x00America/Kentucky/MonticelloTZif" +
+	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00W\x00\x00\x00\a\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0" +
+	"\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8+\xf0\xff\xff\xff\xff\xfe\xb8+\x00\xff" +
+	"\xff\xff\xff\xff\xa8\r\xf0\x00\x00\x00\x00\x00\x98\r\x00\x00\x00\x00\x00\x01\x87\xef\xf0\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\fp\x00\x00\x00\x00\x04a\v\x80\x00\x00\x00\x00\x05P\xeep\x00\x00\x00\x00\x06" +
+	"@\xed\x80\x00\x00\x00\x00\a0\xd0p\x00\x00\x00\x00\a\x8d'\x80\x00\x00\x00\x00\t\x10\xb2p\x00\x00\x00\x00\t\xad\xa3\x00\x00\x00\x00\x00\n\xf0\x94p\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00\x00\x00\fٰ\xf0\x00" +
+	"\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99t\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14" +
+	"Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\"7p\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00" +
+	"\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1܀\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\"" +
+	"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)\nc\xf0\x00" +
+	"\x00\x00\x00)\u07b3\x80\x00\x00\x00\x00*\xeaE\xf0\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3bp\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3Dp\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000" +
+	"\x93&p\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00" +
+	"\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>" +
+	"\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00" +
+	"\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\xff\xff\xb0t\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff" +
+	"\xb9\xb0\x01\x10\xff\xff\xc7\xc0\x01\x14\xff\xff\xb9\xb0\x00\x18LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EDT\x00EST\x00\nEST5EDT,M3.2.0," +
+	"M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$ \x873\xf8\x03\x00\x00\xf8\x03\x00\x00\x0f\x00\x00\x00America/Knox_INTZif2\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80" +
+	"\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff" +
+	"\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90p\xff\xff\xff\xff\u07bey\x80" +
+	"\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5W<\xf0\xff\xff\xff\xff" +
+	"\xe6G<\x00\xff\xff\xff\xff\xe77\x1e\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xd6\xc4\xf0" +
+	"\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\xee\xbf\xe1p\xff\xff\xff\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xf0\x9f\xc3p\xff\xff\xff\xff\xf1\x8f\u0080\xff\xff\xff\xff\xf4_\x87p\xff\xff\xff\xff\xfa\xf8g\x00\xff\xff\xff\xff" +
+	"\xfb\xe8I\xf0\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8+\xf0\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\r\xf0\x00\x00\x00\x00\x00\x98\r\x00\x00\x00\x00\x00\x01\x87\xef\xf0\x00\x00\x00\x00\x02w\xef\x00" +
+	"\x00\x00\x00\x00\x03q\fp\x00\x00\x00\x00\x04a\v\x80\x00\x00\x00\x00\x05P\xeep\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\a0\xd0p\x00\x00\x00\x00\a\x8d'\x80\x00\x00\x00\x00\t\x10\xb2p\x00\x00\x00\x00" +
+	"\t\xad\xa3\x00\x00\x00\x00\x00\n\xf0\x94p\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00\x00\x00\fٰ\xf0\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99t\xf0" +
+	"\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00" +
+	"\x18\"7p\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1܀" +
+	"\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00" +
+	"&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)\nc\xf0\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\x03\x04\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x05\x01\x02\x01\xff\xff\xae\xca\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00" +
+	"\x14LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00\nCST6CDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x12\x00\x00\x00America/KralendijkTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04" +
+	"\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xad`\x12\xe9\xaa\x00\x00\x00\xaa\x00\x00\x00" +
+	"\x0e\x00\x00\x00America/La_PazTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00" +
+	"\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffi\x87\x1b" +
+	"d\xff\xff\xff\xff\xb8\x1e\x96\xe4\xff\xff\xff\xff\xb8\xee\xd5\xd4\x01\x02\x03\xff\xff\xc0\x1c\x00\x00\xff\xff\xc0\x1c\x00\x04\xff\xff\xce,\x01\b\xff\xff\xc7\xc0\x00\fLMT\x00CMT\x00BST\x00-04\x00" +
+	"\n<-04>4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe7\xa1\x87\x1b\x01\x00\x00\x1b\x01\x00\x00\f\x00\x00\x00America/LimaTZif2\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xffi\x87#\xbc\xff\xff\xff\xff\x8ct@\xd4\xff\xff\xff\xff\xc3\xcfJP\xff\xff\xff\xff\xc4E\xe3@\xff\xff\xff" +
+	"\xff\xc5/J\xd0\xff\xff\xff\xff\xc6\x1f-\xc0\xff\xff\xff\xff\xc7\x0f,\xd0\xff\xff\xff\xff\xc7\xff\x0f\xc0\x00\x00\x00\x00\x1e\x18\xc4P\x00\x00\x00\x00\x1e\x8f]@\x00\x00\x00\x00\x1f\xf9\xf7\xd0\x00\x00\x00\x00 p\x90" +
+	"\xc0\x00\x00\x00\x00%\x9e\xe3\xd0\x00\x00\x00\x00&\x15|\xc0\x00\x00\x00\x00-%\x03P\x00\x00\x00\x00-\x9b\x9c@\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\xb7\xc4\x00\x00\xff\xff\xb7\xac\x00" +
+	"\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\bLMT\x00-04\x00-05\x00\n<-05>5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\"\x12\xfe\x0e\x05\x00\x00\x0e\x05\x00\x00\x13" +
+	"\x00\x00\x00America/Los_AngelesTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00}\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff" +
+	"\xff^\x04\x1a\xc0\xff\xff\xff\xff\x9e\xa6H\xa0\xff\xff\xff\xff\x9f\xbb\x15\x90\xff\xff\xff\xff\xa0\x86*\xa0\xff\xff\xff\xff\xa1\x9a\xf7\x90\xff\xff\xff\xffˉ\x1a\xa0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a&" +
+	"\x10\xff\xff\xff\xff\xd6\xfet\\\xff\xff\xff\xff\u0600\xad\x90\xff\xff\xff\xff\xda\xfeÐ\xff\xff\xff\xff\xdb\xc0\x90\x10\xff\xff\xff\xff\xdcޥ\x90\xff\xff\xff\xffݩ\xac\x90\xff\xff\xff\xff\u07be\x87\x90\xff\xff\xff" +
+	"\xff߉\x8e\x90\xff\xff\xff\xff\xe0\x9ei\x90\xff\xff\xff\xff\xe1ip\x90\xff\xff\xff\xff\xe2~K\x90\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4^-\x90\xff\xff\xff\xff\xe5)4\x90\xff\xff\xff\xff\xe6GJ" +
+	"\x10\xff\xff\xff\xff\xe7\x12Q\x10\xff\xff\xff\xff\xe8',\x10\xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff\xff\xea\a\x0e\x10\xff\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff\xff\xeb\xe6\xf0\x10\xff\xff\xff\xff\xec\xb1\xf7\x10\xff\xff\xff" +
+	"\xff\xed\xc6\xd2\x10\xff\xff\xff\xff\xee\x91\xd9\x10\xff\xff\xff\xff\xef\xaf\xee\x90\xff\xff\xff\xff\xf0q\xbb\x10\xff\xff\xff\xff\xf1\x8fА\xff\xff\xff\xff\xf2\x7f\xc1\x90\xff\xff\xff\xff\xf3o\xb2\x90\xff\xff\xff\xff\xf4_\xa3" +
+	"\x90\xff\xff\xff\xff\xf5O\x94\x90\xff\xff\xff\xff\xf6?\x85\x90\xff\xff\xff\xff\xf7/v\x90\xff\xff\xff\xff\xf8(\xa2\x10\xff\xff\xff\xff\xf9\x0fX\x90\xff\xff\xff\xff\xfa\b\x84\x10\xff\xff\xff\xff\xfa\xf8\x83 \xff\xff\xff" +
+	"\xff\xfb\xe8f\x10\xff\xff\xff\xff\xfc\xd8e \xff\xff\xff\xff\xfd\xc8H\x10\xff\xff\xff\xff\xfe\xb8G \xff\xff\xff\xff\xff\xa8*\x10\x00\x00\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88\f\x10\x00\x00\x00\x00\x02x\v" +
+	" \x00\x00\x00\x00\x03q(\x90\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05Q\n\x90\x00\x00\x00\x00\x06A\t\xa0\x00\x00\x00\x00\a0\xec\x90\x00\x00\x00\x00\a\x8dC\xa0\x00\x00\x00\x00\t\x10ΐ\x00\x00\x00" +
+	"\x00\t\xad\xbf \x00\x00\x00\x00\n\xf0\xb0\x90\x00\x00\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91" +
+	"\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00" +
+	"\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8" +
+	"\xa0\x00\x00\x00\x00\x1f\xa1ې\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\"V\r \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00" +
+	"\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\n\x80\x10\x00\x00\x00\x00)\xdeϠ\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~" +
+	"\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00" +
+	"\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\a8 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc" +
+	" \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00" +
+	"\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E\xf3\xd3 \x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\x91&\x00\x00\xff\xff\x9d\x90\x01\x04\xff\xff\x8f\x80\x00\b" +
+	"\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10LMT\x00PDT\x00PST\x00PWT\x00PPT\x00\nPST8PDT,M3.2.0,M11.1.0\nPK\x03\x04" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdf\xe5\x8d\xc4\xda\x04\x00\x00\xda\x04\x00\x00\x12\x00\x00\x00America/LouisvilleTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00u\x00\x00\x00\a\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff" +
+	"\xff\xff\xff\xa4s\xf7\x00\xff\xff\xff\xff\xa5\x16\x11p\xff\xff\xff\xff\xca\rN\x80\xff\xff\xff\xff\xca\xd8Gp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd3" +
+	"u\xd7\x1c\xff\xff\xff\xffӤ\tp\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90p\xff\xff\xff\xff\u07bey\x80\xff\xff\xff\xff߉rp\xff" +
+	"\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5)\x18p\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe7" +
+	"7\x1e\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe9\x17\x00\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea\xf6\xe2\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xd6\xc4\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff" +
+	"\xff\xff\xff\xee\xbf\xe1p\xff\xff\xff\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xf0\x1e\x90p\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00" +
+	"\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\a0\xc2`\x00" +
+	"\x00\x00\x00\a\x8d\x19p\x00\x00\x00\x00\t\x10\xb2p\x00\x00\x00\x00\t\xad\x94\xf0\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00\f٢\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00\x00\x00\x0e" +
+	"\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00" +
+	"\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x00\x00\x00\x00\x1a\xf2\np\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c" +
+	"\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\"U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00" +
+	"\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\nU\xe0\x00\x00\x00\x00)ޥp\x00\x00\x00\x00*" +
+	"\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00" +
+	"\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\a\r\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008" +
+	"\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00" +
+	"\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x01\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" +
+	"\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xaf\x9a\x00\x00\xff\xff" +
+	"\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00ED" +
+	"T\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x15\x00\x00\x00Amer" +
+	"ica/Lower_PrincesTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" +
+	"\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹" +
+	"\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00" +
+	"APT\x00AWT\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00挋\x92\xf6\x01\x00\x00\xf6\x01\x00\x00\x0e\x00\x00\x00America/MaceioTZ" +
+	"if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaah|\xff\xff\xff\xff\xb8\x0fI\xe0\xff\xff\xff\xff\xb8\xfd@\xa0\xff\xff\xff" +
+	"\xff\xb9\xf140\xff\xff\xff\xff\xba\xdet \xff\xff\xff\xff\xda8\xae0\xff\xff\xff\xff\xda\xeb\xfa0\xff\xff\xff\xff\xdc\x19\xe1\xb0\xff\xff\xff\xffܹY \xff\xff\xff\xff\xdd\xfb\x150\xff\xff\xff\xffޛ\xde" +
+	" \xff\xff\xff\xff\xdfݚ0\xff\xff\xff\xff\xe0T3 \xff\xff\xff\xff\xf4\x97\xff\xb0\xff\xff\xff\xff\xf5\x05^ \xff\xff\xff\xff\xf6\xc0d0\xff\xff\xff\xff\xf7\x0e\x1e\xa0\xff\xff\xff\xff\xf8Q,0\xff\xff\xff" +
+	"\xff\xf8\xc7\xc5 \xff\xff\xff\xff\xfa\nҰ\xff\xff\xff\xff\xfa\xa8\xf8\xa0\xff\xff\xff\xff\xfb\xec\x060\xff\xff\xff\xff\xfc\x8b}\xa0\x00\x00\x00\x00\x1dɎ0\x00\x00\x00\x00\x1exנ\x00\x00\x00\x00\x1f\xa05" +
+	"\xb0\x00\x00\x00\x00 3Ϡ\x00\x00\x00\x00!\x81i0\x00\x00\x00\x00\"\vȠ\x00\x00\x00\x00#X\x10\xb0\x00\x00\x00\x00#\xe2p \x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xd4\xc7 \x00\x00\x00" +
+	"\x000\x80y0\x00\x00\x00\x001\x1dM\xa0\x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xb8\x85 \x00\x00\x00\x009\xdf\xe30\x00\x00\x00\x009\xf2J \x00\x00\x00\x00;\xc8\xff\xb0\x00\x00\x00\x00<o\x0e" +
+	"\xa0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xffބ\x00\x00\xff\xff\xe3\xe0\x01\x04\xff\xff\xd5\xd0\x00\b" +
+	"LMT\x00-02\x00-03\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5s\xb3\\'\x01\x00\x00'\x01\x00\x00\x0f\x00\x00\x00America/Ma" +
+	"naguaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif" +
+	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xffi\x87,d\xff\xff\xff\xff\xbd-H\xe8\x00\x00\x00\x00" +
+	"\x06Ct`\x00\x00\x00\x00\t\xa4>P\x00\x00\x00\x00\x11Q\xf8\xe0\x00\x00\x00\x00\x11\xd4oP\x00\x00\x00\x00\x131\xda\xe0\x00\x00\x00\x00\x13\xb4QP\x00\x00\x00\x00)a\x91 \x00\x00\x00\x00*\xc1KP" +
+	"\x00\x00\x00\x00+C\xdd\xe0\x00\x00\x00\x002\xc9\xefP\x00\x00\x00\x00BX\xc0\xe0\x00\x00\x00\x00C?iP\x00\x00\x00\x00DTn\x80\x00\x00\x00\x00E\x1fY`\x01\x02\x03\x02\x04\x02\x04\x02\x03\x02\x03\x02" +
+	"\x04\x02\x04\x02\xff\xff\xaf\x1c\x00\x00\xff\xff\xaf\x18\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x00\f\xff\xff\xb9\xb0\x01\x10LMT\x00MMT\x00CST\x00EST\x00CDT\x00\nCST6\n" +
+	"PK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a\xcb'\xe9\x9c\x01\x00\x00\x9c\x01\x00\x00\x0e\x00\x00\x00America/ManausTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaa\x7fD\xff\xff\xff\xff\xb8\x0fW\xf0\xff\xff\xff\xff\xb8\xfdN\xb0\xff\xff\xff\xff\xb9\xf1B@\xff\xff\xff\xff\xbaނ0\xff" +
+	"\xff\xff\xff\xda8\xbc@\xff\xff\xff\xff\xda\xec\b@\xff\xff\xff\xff\xdc\x19\xef\xc0\xff\xff\xff\xffܹg0\xff\xff\xff\xff\xdd\xfb#@\xff\xff\xff\xffޛ\xec0\xff\xff\xff\xff\xdfݨ@\xff\xff\xff\xff\xe0" +
+	"TA0\xff\xff\xff\xff\xf4\x98\r\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf6\xc0r@\xff\xff\xff\xff\xf7\x0e,\xb0\xff\xff\xff\xff\xf8Q:@\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xfa\n\xe0\xc0\xff" +
+	"\xff\xff\xff\xfa\xa9\x06\xb0\xff\xff\xff\xff\xfb\xec\x14@\xff\xff\xff\xff\xfc\x8b\x8b\xb0\x00\x00\x00\x00\x1dɜ@\x00\x00\x00\x00\x1ex\xe5\xb0\x00\x00\x00\x00\x1f\xa0C\xc0\x00\x00\x00\x00 3ݰ\x00\x00\x00\x00!" +
+	"\x81w@\x00\x00\x00\x00\"\vְ\x00\x00\x00\x00,\xc0\xc3@\x00\x00\x00\x00-f\xd20\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff" +
+	"Ǽ\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\bLMT\x00-03\x00-04\x00\n<-04>4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00" +
+	"\x00\x00\x0f\x00\x00\x00America/MarigotTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff" +
+	"z敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00" +
+	"AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x17jҲ\x00\x00\x00\xb2\x00\x00\x00\x12\x00\x00\x00America/Mart" +
+	"iniqueTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZi" +
+	"f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xffi\x87\x14\xc4\xff\xff\xff\xff\x91\xa3\xc8D\x00\x00\x00" +
+	"\x00\x13Mn@\x00\x00\x00\x00\x144\x16\xb0\x01\x02\x03\x02\xff\xffƼ\x00\x00\xff\xffƼ\x00\x04\xff\xff\xc7\xc0\x00\t\xff\xff\xd5\xd0\x01\rLMT\x00FFMT\x00AST\x00ADT\x00\nA" +
+	"ST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00((i\xe4\xb5\x01\x00\x00\xb5\x01\x00\x00\x11\x00\x00\x00America/MatamorosTZif2\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\xa5\xb6\xda`\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x001gv\x00\x00\x00" +
+	"\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6" +
+	"\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xf5\x04\x80\x00\x00\x00\x00;\xb6\xc2\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00\x00" +
+	"\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00F\x0ff\x80\x00\x00\x00\x00G$" +
+	"3p\x00\x00\x00\x00G\xf8\x83\x00\x00\x00\x00\x00I\x04\x15p\x00\x00\x00\x00I\xd8e\x00\x00\x00\x00\x00J\xe3\xf7p\x00\x00\x00\x00K\x9c\x97\x80\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xa4\x98\x00\x00\xff\xff\xab\xa0\x00\x04\xff\xff\xb9\xb0\x01\bLMT\x00CST\x00CDT\x00\nCST6CDT,M3.2.0," +
+	"M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\xad=\x98\xce\x02\x00\x00\xce\x02\x00\x00\x10\x00\x00\x00America/MazatlanTZif2\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6fV`\xff\xff\xff\xff\xb7C\xd2" +
+	"`\xff\xff\xff\xff\xb8\f6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\xff\xff\xff\xff\xcb\xeaq`\xff\xff\xff\xffؑ\xb4\xf0\x00\x00\x00\x00\x00\x00p\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00" +
+	"\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9" +
+	"\x00\x00\x00\x00\x00:\xf5\x12\x90\x00\x00\x00\x00;\xb6\xd1\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00" +
+	"\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00F\x0ft\x90\x00\x00\x00\x00G$A\x80\x00\x00\x00\x00G\xf8\x91" +
+	"\x10\x00\x00\x00\x00I\x04#\x80\x00\x00\x00\x00I\xd8s\x10\x00\x00\x00\x00J\xe4\x05\x80\x00\x00\x00\x00K\xb8U\x10\x00\x00\x00\x00L\xcd\"\x00\x00\x00\x00\x00M\x987\x10\x00\x00\x00\x00N\xad\x04\x00\x00\x00\x00" +
+	"\x00Ox\x19\x10\x00\x00\x00\x00P\x8c\xe6\x00\x00\x00\x00\x00Qa5\x90\x00\x00\x00\x00Rl\xc8\x00\x00\x00\x00\x00SA\x17\x90\x00\x00\x00\x00TL\xaa\x00\x00\x00\x00\x00U \xf9\x90\x00\x00\x00\x00V,\x8c" +
+	"\x00\x00\x00\x00\x00W\x00ې\x00\x00\x00\x00X\x15\xa8\x80\x00\x00\x00\x00Xཐ\x00\x00\x00\x00Y\xf5\x8a\x80\x00\x00\x00\x00Z\xc0\x9f\x90\x00\x00\x00\x00[\xd5l\x80\x00\x00\x00\x00\\\xa9\xbc\x10\x00\x00\x00" +
+	"\x00]\xb5N\x80\x00\x00\x00\x00^\x89\x9e\x10\x00\x00\x00\x00_\x950\x80\x00\x00\x00\x00`i\x80\x10\x00\x00\x00\x00a~M\x00\x00\x00\x00\x00bIb\x10\x00\x00\x00\x00c^/\x00\x01\x02\x01\x03\x01\x02\x01" +
+	"\x04\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\xff\xff\x9c<" +
+	"\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\x8f\x80\x00\x10LMT\x00MST\x00CST\x00MDT\x00PST\x00\nMST7\nPK\x03\x04\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00ŒZ\x8c\xc4\x02\x00\x00\xc4\x02\x00\x00\x0f\x00\x00\x00America/MendozaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00=\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xb2\x04\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0" +
+	"\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff" +
+	"\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0" +
+	"\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff" +
+	"\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30" +
+	"\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00" +
+	"\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'\x194@\x00\x00\x00\x00'\xcdð" +
+	"\x00\x00\x00\x00(\xfag\xc0\x00\x00\x00\x00)\xb0H\xb0\x00\x00\x00\x00*\xe0\xe1@\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xb0\x13\xb0\x00\x00\x00\x00" +
+	"AV>\xc0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x05\x04\x05\x04\x05\x04\x02\x03\x02\x03\x02\x04\x05\x03\x05\x02\x05\x04\x05\xff\xff\xbf|\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT" +
+	"\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x008O:\xbf\x95\x03\x00\x00\x95\x03\x00\x00\x11\x00\x00\x00Ameri" +
+	"ca/MenomineeTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00" +
+	"\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00R\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xffawIc\xff\xff\xff\xff\x9e" +
+	"\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd3u\xf3\x00\xff" +
+	"\xff\xff\xff\xd4@\xeb\xf0\xff\xff\xff\xff\xf9\x0fJ\x80\xff\xff\xff\xff\xfa\bg\xf0\xff\xff\xff\xff\xfe\xb8+\x00\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\a0\xd0p\x00\x00\x00\x00\a\x8d'\x80\x00\x00\x00\x00\t" +
+	"\x10\xb2p\x00\x00\x00\x00\t\xad\xa3\x00\x00\x00\x00\x00\n\xf0\x94p\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00\x00\x00\fٰ\xf0\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92\x00\x00" +
+	"\x00\x00\x00\x10\x99t\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17" +
+	")\x1a\x00\x00\x00\x00\x00\x18\"7p\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00" +
+	"\x00\x00\x00\x1e\xb1܀\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%" +
+	"J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)\nc\xf0\x00\x00\x00\x00)\u07b3\x80\x00\x00\x00\x00*\xeaE\xf0\x00\x00\x00\x00+\xbe\x95\x80\x00" +
+	"\x00\x00\x00,\xd3bp\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3Dp\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x93&p\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003" +
+	"GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00" +
+	"\x00\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00;۬\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A" +
+	"\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x05\x01\x02\x01\x02" +
 	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x06\x05\x06\x05\x06\x05\x06\x05\xff\xff\xa0\xed\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10\xff\xff\xb9\xb0\x01\x14\xff\xff\xab\xa0\x00" +
-	"\x18LMT\x00MDT\x00MST\x00MWT\x00MPT\x00CDT\x00CST\x00\nCST6CDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00" +
-	"\x00\x00\x00\x8fj\xbeTH\xeam\xef\xde\x03\x00\x00\xde\x03\x00\x00\x1b\x00\x1c\x00America/North_Dakota/CenterUT\t\x00\x03\xdd\xfc\x94b\xdd" +
-	"\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00" +
+	"\x01\x02\x01\x02\x01\xff\xff\xad\xdd\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14LMT\x00CDT\x00CST\x00CWT\x00CPT" +
+	"\x00EST\x00\nCST6CDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\xbd\x809\x8e\x02\x00\x00\x8e\x02\x00\x00\x0e\x00\x00\x00A" +
+	"merica/MeridaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00" +
+	"\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x009\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\xa5\xb6\xda`\x00\x00\x00\x00" +
+	"\x16\x86\xd5`\x00\x00\x00\x00\x18LKP\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp" +
+	"\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xf5\x04\x80\x00\x00\x00\x00;\xb6\xc2\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00" +
+	"=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80" +
+	"\x00\x00\x00\x00EDQp\x00\x00\x00\x00F\x0ff\x80\x00\x00\x00\x00G$3p\x00\x00\x00\x00G\xf8\x83\x00\x00\x00\x00\x00I\x04\x15p\x00\x00\x00\x00I\xd8e\x00\x00\x00\x00\x00J\xe3\xf7p\x00\x00\x00\x00" +
+	"K\xb8G\x00\x00\x00\x00\x00L\xcd\x13\xf0\x00\x00\x00\x00M\x98)\x00\x00\x00\x00\x00N\xac\xf5\xf0\x00\x00\x00\x00Ox\v\x00\x00\x00\x00\x00P\x8c\xd7\xf0\x00\x00\x00\x00Qa'\x80\x00\x00\x00\x00Rl\xb9\xf0" +
+	"\x00\x00\x00\x00SA\t\x80\x00\x00\x00\x00TL\x9b\xf0\x00\x00\x00\x00U \xeb\x80\x00\x00\x00\x00V,}\xf0\x00\x00\x00\x00W\x00̀\x00\x00\x00\x00X\x15\x9ap\x00\x00\x00\x00Xீ\x00\x00\x00\x00" +
+	"Y\xf5|p\x00\x00\x00\x00Z\xc0\x91\x80\x00\x00\x00\x00[\xd5^p\x00\x00\x00\x00\\\xa9\xae\x00\x00\x00\x00\x00]\xb5@p\x00\x00\x00\x00^\x89\x90\x00\x00\x00\x00\x00_\x95\"p\x00\x00\x00\x00`ir\x00" +
+	"\x00\x00\x00\x00a~>\xf0\x00\x00\x00\x00bIT\x00\x00\x00\x00\x00c^ \xf0\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03" +
+	"\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\xff\xff\xab\xfc\x00\x00\xff\xff\xab\xa0\x00\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xb9\xb0\x01\fLMT\x00CST\x00EST\x00CDT" +
+	"\x00\nCST6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa2\x81\xbfyS\x02\x00\x00S\x02\x00\x00\x12\x00\x00\x00America/MetlakatlaTZif2" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,\x00\x00\x00\b\x00\x00\x00\x1e\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}\x870\x1a\xff\xff\xff\xffˉ\x1a\xa0\xff\xff\xff\xff\xd2#" +
+	"\xf4p\xff\xff\xff\xff\xd2a&\x10\xff\xff\xff\xff\xfe\xb8G \xff\xff\xff\xff\xff\xa8*\x10\x00\x00\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88\f\x10\x00\x00\x00\x00\x02x\v \x00\x00\x00\x00\x03q(\x90\x00\x00" +
+	"\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05Q\n\x90\x00\x00\x00\x00\x06A\t\xa0\x00\x00\x00\x00\a0\xec\x90\x00\x00\x00\x00\a\x8dC\xa0\x00\x00\x00\x00\t\x10ΐ\x00\x00\x00\x00\t\xad\xbf \x00\x00\x00\x00\n\xf0" +
+	"\xb0\x90\x00\x00\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00" +
+	"\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t" +
+	"\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00V5\xe2\xa0\x00\x00\x00\x00V\xe5H0\x00\x00\x00\x00X\x1e\xff \x00\x00\x00\x00X\xc5*0\x00\x00\x00\x00Y\xfe\xe1 \x00\x00\x00\x00Z\xa5\f0\x00\x00" +
+	"\x00\x00[\xde\xc3 \x00\x00\x00\x00\\DF\xa0\x00\x00\x00\x00\\\x84\xee0\x01\x02\x03\x04\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x06\a\x06" +
+	"\a\x06\a\x02\x06\a\x00\x00\xd6&\x00\x00\xff\xff\x84\xa6\x00\x00\xff\xff\x8f\x80\x00\x04\xff\xff\x9d\x90\x01\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10\xff\xff\x81p\x00\x14\xff\xff\x8f\x80\x01\x19LMT\x00PS" +
+	"T\x00PWT\x00PPT\x00PDT\x00AKST\x00AKDT\x00\nAKST9AKDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\xd5\b\x89\x8c\x05\x03\x00\x00\x05\x03\x00\x00\x13\x00\x00\x00America/Mexico_CityTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00D\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6fV`\xff\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff\xb8\f6`\xff\xff\xff\xff\xb8\xfd" +
+	"\x86\xf0\xff\xff\xff\xff\xc5ް`\xff\xff\xff\xffƗ4P\xff\xff\xff\xff\xc9U\xf1\xe0\xff\xff\xff\xff\xc9\xea\xddP\xff\xff\xff\xff\xcf\x02\xc6\xe0\xff\xff\xff\xffϷVP\xff\xff\xff\xffڙ\x15\xe0\xff\xff" +
+	"\xff\xff\xdbv\x83\xd0\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a" +
+	"\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xf5\x04\x80\x00\x00\x00\x00;\xb6\xc2\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00" +
+	"\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00ED" +
+	"Qp\x00\x00\x00\x00F\x0ff\x80\x00\x00\x00\x00G$3p\x00\x00\x00\x00G\xf8\x83\x00\x00\x00\x00\x00I\x04\x15p\x00\x00\x00\x00I\xd8e\x00\x00\x00\x00\x00J\xe3\xf7p\x00\x00\x00\x00K\xb8G\x00\x00\x00" +
+	"\x00\x00L\xcd\x13\xf0\x00\x00\x00\x00M\x98)\x00\x00\x00\x00\x00N\xac\xf5\xf0\x00\x00\x00\x00Ox\v\x00\x00\x00\x00\x00P\x8c\xd7\xf0\x00\x00\x00\x00Qa'\x80\x00\x00\x00\x00Rl\xb9\xf0\x00\x00\x00\x00SA" +
+	"\t\x80\x00\x00\x00\x00TL\x9b\xf0\x00\x00\x00\x00U \xeb\x80\x00\x00\x00\x00V,}\xf0\x00\x00\x00\x00W\x00̀\x00\x00\x00\x00X\x15\x9ap\x00\x00\x00\x00Xீ\x00\x00\x00\x00Y\xf5|p\x00\x00" +
+	"\x00\x00Z\xc0\x91\x80\x00\x00\x00\x00[\xd5^p\x00\x00\x00\x00\\\xa9\xae\x00\x00\x00\x00\x00]\xb5@p\x00\x00\x00\x00^\x89\x90\x00\x00\x00\x00\x00_\x95\"p\x00\x00\x00\x00`ir\x00\x00\x00\x00\x00a~" +
+	">\xf0\x00\x00\x00\x00bIT\x00\x00\x00\x00\x00c^ \xf0\x01\x02\x01\x03\x01\x02\x04\x02\x04\x02\x05\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02" +
+	"\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\xff\xff\xa3\f\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0" +
+	"\x01\x14LMT\x00MST\x00CST\x00MDT\x00CDT\x00CWT\x00\nCST6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd7\b\\\xc6&\x02\x00\x00&\x02\x00\x00\x10\x00" +
+	"\x00\x00America/MiquelonTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00" +
+	"\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\x91\xb68" +
+	"\xa8\x00\x00\x00\x00\x13nc\xc0\x00\x00\x00\x00 u\xe4\xd0\x00\x00\x00\x00!\x81w@\x00\x00\x00\x00\"U\xc6\xd0\x00\x00\x00\x00#j\x93\xc0\x00\x00\x00\x00$5\xa8\xd0\x00\x00\x00\x00%Ju\xc0\x00\x00\x00" +
+	"\x00&\x15\x8a\xd0\x00\x00\x00\x00'*W\xc0\x00\x00\x00\x00'\xfe\xa7P\x00\x00\x00\x00)\n9\xc0\x00\x00\x00\x00)މP\x00\x00\x00\x00*\xea\x1b\xc0\x00\x00\x00\x00+\xbekP\x00\x00\x00\x00,\xd38" +
+	"@\x00\x00\x00\x00-\x9eMP\x00\x00\x00\x00.\xb3\x1a@\x00\x00\x00\x00/~/P\x00\x00\x00\x000\x92\xfc@\x00\x00\x00\x001gK\xd0\x00\x00\x00\x002r\xde@\x00\x00\x00\x003G-\xd0\x00\x00\x00" +
+	"\x004R\xc0@\x00\x00\x00\x005'\x0f\xd0\x00\x00\x00\x0062\xa2@\x00\x00\x00\x007\x06\xf1\xd0\x00\x00\x00\x008\x1b\xbe\xc0\x00\x00\x00\x008\xe6\xd3\xd0\x00\x00\x00\x009\xfb\xa0\xc0\x00\x00\x00\x00:Ƶ" +
+	"\xd0\x00\x00\x00\x00;ۂ\xc0\x00\x00\x00\x00<\xaf\xd2P\x00\x00\x00\x00=\xbbd\xc0\x00\x00\x00\x00>\x8f\xb4P\x00\x00\x00\x00?\x9bF\xc0\x00\x00\x00\x00@o\x96P\x00\x00\x00\x00A\x84c@\x00\x00\x00" +
+	"\x00BOxP\x00\x00\x00\x00CdE@\x00\x00\x00\x00D/ZP\x00\x00\x00\x00ED'@\x00\x00\x00\x00E\xf3\x8c\xd0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\xcbX\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x00\b\xff\xff\xe3\xe0\x01\fLMT\x00AST\x00-03\x00-02\x00" +
+	"\n<-03>3<-02>,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00.\xf9\xc0\x1e\xd5\x05\x00\x00\xd5\x05\x00\x00\x0f\x00\x00\x00Am" +
+	"erica/MonctonTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00" +
+	"\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x92\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff^\x1e\xed\xbc\xff\xff\xff\xff" +
+	"\x80\xf1\xb6P\xff\xff\xff\xff\x9e\xb8\x85`\xff\xff\xff\xff\x9f\xba\xddP\xff\xff\xff\xff\xbb<8\xd0\xff\xff\xff\xff\xbb\xb4#@\xff\xff\xff\xff\xbd\x1c\x1a\xd0\xff\xff\xff\xff\xbd\x94\x05@\xff\xff\xff\xff\xbe\xfb\xfc\xd0" +
+	"\xff\xff\xff\xff\xbfs\xe7@\xff\xff\xff\xff\xc0\xdb\xde\xd0\xff\xff\xff\xff\xc1S\xc9@\xff\xff\xff\xff»\xc0\xd0\xff\xff\xff\xff\xc33\xab@\xff\xff\xff\xffě\xa2\xd0\xff\xff\xff\xff\xc5\x13\x8d@\xff\xff\xff\xff" +
+	"\xc6p\xf8\xd0\xff\xff\xff\xff\xc7\r\xcd@\xff\xff\xff\xff\xc8H\xf1\xd0\xff\xff\xff\xff\xc8\xed\xaf@\xff\xff\xff\xff\xca\x16^\xd0\xff\xff\xff\xff\xca\xd6\xcb\xc0\xff\xff\xff\xffˈ\xe2`\xff\xff\xff\xff\xd2#\xf4p" +
+	"\xff\xff\xff\xff\xd2`\xed\xd0\xff\xff\xff\xff\xd3u\xd6\xe0\xff\xff\xff\xff\xd4@\xcf\xd0\xff\xff\xff\xff\xd5U\xb8\xe0\xff\xff\xff\xff\xd6 \xb1\xd0\xff\xff\xff\xff\xd75\x9a\xe0\xff\xff\xff\xff\xd8\x00\x93\xd0\xff\xff\xff\xff" +
+	"\xd9\x15|\xe0\xff\xff\xff\xff\xd9\xe0u\xd0\xff\xff\xff\xff\xda\xfe\x99`\xff\xff\xff\xff\xdb\xc0W\xd0\xff\xff\xff\xff\xdc\xde{`\xff\xff\xff\xffݩtP\xff\xff\xff\xff\u07be]`\xff\xff\xff\xff߉VP" +
+	"\xff\xff\xff\xff\xe0\x9e?`\xff\xff\xff\xff\xe1i8P\xff\xff\xff\xff\xe2~!`\xff\xff\xff\xff\xe3I\x1aP\xff\xff\xff\xff\xe4^\x03`\xff\xff\xff\xff\xe5(\xfcP\xff\xff\xff\xff\xe6G\x1f\xe0\xff\xff\xff\xff" +
+	"\xe7\x12\x18\xd0\xff\xff\xff\xff\xe8'\x01\xe0\xff\xff\xff\xff\xe9\x16\xe4\xd0\xff\xff\xff\xff\xea\x06\xe3\xe0\xff\xff\xff\xff\xea\xf6\xc6\xd0\xff\xff\xff\xff\xeb\xe6\xc5\xe0\xff\xff\xff\xff\xec֨\xd0\xff\xff\xff\xff\xedƧ\xe0" +
+	"\xff\xff\xff\xff\xee\xbf\xc5P\xff\xff\xff\xff\xef\xaf\xc4`\xff\xff\xff\xff\xf0\x9f\xa7P\xff\xff\xff\xff\xf1\x8f\xa6`\xff\xff\xff\xff\xf2\x7f\x89P\xff\xff\xff\xff\xf3o\x88`\xff\xff\xff\xff\xf4_kP\xff\xff\xff\xff" +
+	"\xf5Oj`\xff\xff\xff\xff\xf6?MP\xff\xff\xff\xff\xf7/L`\xff\xff\xff\xff\xf8(i\xd0\xff\xff\xff\xff\xf9\x0f.`\xff\xff\xff\xff\xfa\bK\xd0\xff\xff\xff\xff\xfa\xf8J\xe0\xff\xff\xff\xff\xfb\xe8-\xd0" +
+	"\xff\xff\xff\xff\xfc\xd8,\xe0\xff\xff\xff\xff\xfd\xc8\x0f\xd0\xff\xff\xff\xff\xfe\xb8\x0e\xe0\xff\xff\xff\xff\xff\xa7\xf1\xd0\x00\x00\x00\x00\x00\x97\xf0\xe0\x00\x00\x00\x00\x01\x87\xd3\xd0\x00\x00\x00\x00\x02w\xd2\xe0\x00\x00\x00\x00" +
+	"\x03p\xf0P\x00\x00\x00\x00\x04`\xef`\x00\x00\x00\x00\x05P\xd2P\x00\x00\x00\x00\b \xb3`\x00\x00\x00\x00\t\x10\x96P\x00\x00\x00\x00\n\x00\x95`\x00\x00\x00\x00\n\xf0xP\x00\x00\x00\x00\v\xe0w`" +
+	"\x00\x00\x00\x00\fٔ\xd0\x00\x00\x00\x00\r\xc0Y`\x00\x00\x00\x00\x0e\xb9v\xd0\x00\x00\x00\x00\x0f\xa9u\xe0\x00\x00\x00\x00\x10\x99X\xd0\x00\x00\x00\x00\x11\x89W\xe0\x00\x00\x00\x00\x12y:\xd0\x00\x00\x00\x00" +
+	"\x13i9\xe0\x00\x00\x00\x00\x14Y\x1c\xd0\x00\x00\x00\x00\x15I\x1b\xe0\x00\x00\x00\x00\x168\xfe\xd0\x00\x00\x00\x00\x17(\xfd\xe0\x00\x00\x00\x00\x18\"\x1bP\x00\x00\x00\x00\x19\b\xdf\xe0\x00\x00\x00\x00\x1a\x01\xfdP" +
+	"\x00\x00\x00\x00\x1a\xf1\xfc`\x00\x00\x00\x00\x1b\xe1\xdfP\x00\x00\x00\x00\x1c\xd1\xde`\x00\x00\x00\x00\x1d\xc1\xc1P\x00\x00\x00\x00\x1e\xb1\xc0`\x00\x00\x00\x00\x1f\xa1\xa3P\x00\x00\x00\x00 u\xf2\xe0\x00\x00\x00\x00" +
+	"!\x81\x85P\x00\x00\x00\x00\"U\xd4\xe0\x00\x00\x00\x00#j\xa1\xd0\x00\x00\x00\x00$5\xb6\xe0\x00\x00\x00\x00%J\x83\xd0\x00\x00\x00\x00&\x15\x98\xe0\x00\x00\x00\x00'*e\xd0\x00\x00\x00\x00'\xfe\xb5`" +
+	"\x00\x00\x00\x00)\nG\xd0\x00\x00\x00\x00)ޗ`\x00\x00\x00\x00*\xea)\xd0\x00\x00\x00\x00+\xbe]|\x00\x00\x00\x00,\xd3*l\x00\x00\x00\x00-\x9e?|\x00\x00\x00\x00.\xb3\fl\x00\x00\x00\x00" +
+	"/~!|\x00\x00\x00\x000\x92\xeel\x00\x00\x00\x001g=\xfc\x00\x00\x00\x002r\xd0l\x00\x00\x00\x003G\x1f\xfc\x00\x00\x00\x004R\xb2l\x00\x00\x00\x005'\x01\xfc\x00\x00\x00\x0062\x94l" +
+	"\x00\x00\x00\x007\x06\xe3\xfc\x00\x00\x00\x008\x1b\xb0\xec\x00\x00\x00\x008\xe6\xc5\xfc\x00\x00\x00\x009\xfb\x92\xec\x00\x00\x00\x00:Ƨ\xfc\x00\x00\x00\x00;\xdbt\xec\x00\x00\x00\x00<\xaf\xc4|\x00\x00\x00\x00" +
+	"=\xbbV\xec\x00\x00\x00\x00>\x8f\xa6|\x00\x00\x00\x00?\x9b8\xec\x00\x00\x00\x00@o\x88|\x00\x00\x00\x00A\x84Ul\x00\x00\x00\x00BOj|\x00\x00\x00\x00Cd7l\x00\x00\x00\x00D/L|" +
+	"\x00\x00\x00\x00ED\x19l\x00\x00\x00\x00E\xf3\x9a\xe0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x05\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\xff\xff\xc3D\x00\x00\xff\xff\xb9\xb0\x00\x04\xff\xff\xd5\xd0\x01\b" +
+	"\xff\xff\xc7\xc0\x00\f\xff\xff\xd5\xd0\x01\x10\xff\xff\xd5\xd0\x01\x14LMT\x00EST\x00ADT\x00AST\x00AWT\x00APT\x00\nAST4ADT,M3.2.0,M1" +
+	"1.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00L+\xe3u\x84\x02\x00\x00\x84\x02\x00\x00\x11\x00\x00\x00America/MonterreyTZif2\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x009\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\xa5\xb6\xda`\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x001gv\x00" +
+	"\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x00" +
+	"8\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xf5\x04\x80\x00\x00\x00\x00;\xb6\xc2\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0" +
+	"\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00F\x0ff\x80\x00\x00\x00\x00" +
+	"G$3p\x00\x00\x00\x00G\xf8\x83\x00\x00\x00\x00\x00I\x04\x15p\x00\x00\x00\x00I\xd8e\x00\x00\x00\x00\x00J\xe3\xf7p\x00\x00\x00\x00K\xb8G\x00\x00\x00\x00\x00L\xcd\x13\xf0\x00\x00\x00\x00M\x98)\x00" +
+	"\x00\x00\x00\x00N\xac\xf5\xf0\x00\x00\x00\x00Ox\v\x00\x00\x00\x00\x00P\x8c\xd7\xf0\x00\x00\x00\x00Qa'\x80\x00\x00\x00\x00Rl\xb9\xf0\x00\x00\x00\x00SA\t\x80\x00\x00\x00\x00TL\x9b\xf0\x00\x00\x00\x00" +
+	"U \xeb\x80\x00\x00\x00\x00V,}\xf0\x00\x00\x00\x00W\x00̀\x00\x00\x00\x00X\x15\x9ap\x00\x00\x00\x00Xீ\x00\x00\x00\x00Y\xf5|p\x00\x00\x00\x00Z\xc0\x91\x80\x00\x00\x00\x00[\xd5^p" +
+	"\x00\x00\x00\x00\\\xa9\xae\x00\x00\x00\x00\x00]\xb5@p\x00\x00\x00\x00^\x89\x90\x00\x00\x00\x00\x00_\x95\"p\x00\x00\x00\x00`ir\x00\x00\x00\x00\x00a~>\xf0\x00\x00\x00\x00bIT\x00\x00\x00\x00\x00" +
+	"c^ \xf0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\xff\xff\xa1\xf4\x00\x00\xff\xff\xab\xa0\x00\x04\xff\xff\xb9\xb0\x01\bLMT\x00CST\x00CDT\x00\nCST6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0\x98\x00\b\xc9\x03\x00\x00\xc9" +
+	"\x03\x00\x00\x12\x00\x00\x00America/MontevideoTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\x00\x00\x00\t\x00\x00\x00&" +
+	"\xff\xff\xff\xff\x8c4\xe53\xff\xff\xff\xff\xa2\x92\x87\xb3\xff\xff\xff\xff\xa8\xff\xdb@\xff\xff\xff\xff\xa9\xf1\x0f\xb0\xff\xff\xff\xff\xaa\xe2Y8\xff\xff\xff\xff\xab\xd2C0\xff\xff\xff\xff\xacÌ\xb8\xff\xff\xff\xff" +
+	"\xad\xb3v\xb0\xff\xff\xff\xff\xbb\xf4\xb5\xb8\xff\xff\xff\xff\xbc\xbf\xb5\xb0\xff\xff\xff\xff\xbdԗ\xb8\xff\xff\xff\xff\xbe\x9f\x97\xb0\xff\xff\xff\xff\xbf\xb4y\xb8\xff\xff\xff\xff\xc0\x7fy\xb0\xff\xff\xff\xff\xc1\x94[\xb8" +
+	"\xff\xff\xff\xff\xc2_[\xb0\xff\xff\xff\xff\xc3}x8\xff\xff\xff\xff\xc4?=\xb0\xff\xff\xff\xff\xc5]Z8\xff\xff\xff\xff\xc6\x1f\x1f\xb0\xff\xff\xff\xff\xc7\x18R8\xff\xff\xff\xff\xc8\b<0\xff\xff\xff\xff" +
+	"\xc9\x1d\x1e8\xff\xff\xff\xff\xc9\xe8\x1e0\xff\xff\xff\xffʋ\x9f8\xff\xff\xff\xff\xcd\x1e\xc60\xff\xff\xff\xff͕f(\xff\xff\xff\xff\xec\v\x85\xb0\xff\xff\xff\xff\xec\xf25(\xff\xff\xff\xff\xedEJ\xb0" +
+	"\xff\xff\xff\xff\xed\x85\xd6 \xff\xff\xff\xff\xf7\x13r\xb0\xff\xff\xff\xff\xf7\xfa\x1b \xff\xff\xff\xff\xfc\xfe>0\xff\xff\xff\xff\xfd\xf6\x11(\x00\x00\x00\x00\x00\x96u0\x00\x00\x00\x00\x00\xd8R \x00\x00\x00\x00" +
+	"\x04W\x8a\xb0\x00\x00\x00\x00\x04\xc6:\xa0\x00\x00\x00\x00\a\x96\x1b\xb0\x00\x00\x00\x00\a\xdfژ\x00\x00\x00\x00\bƟ(\x00\x00\x00\x00\tZN0\x00\x00\x00\x00\t\xdbs \x00\x00\x00\x00\r\x1a\x120" +
+	"\x00\x00\x00\x00\r\x7f\x87\xa0\x00\x00\x00\x00\x0e\xe7\x7f0\x00\x00\x00\x00\x0f_i\xa0\x00\x00\x00\x00\x10\xd9\xd60\x00\x00\x00\x00\x11?K\xa0\x00\x00\x00\x00\x11\x89-\xb0\x00\x00\x00\x00\x131\xa2\xa0\x00\x00\x00\x00" +
+	"!\xc3T0\x00\x00\x00\x00\"'x \x00\x00\x00\x00#\xa1\xe4\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%Jg\xb0\x00\x00\x00\x00%\xe7< \x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0" +
+	"\x00\x00\x00\x00)\n+\xb0\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x90\x1c\xa0\x00\x00\x00\x00AL\xf60\x00\x00\x00\x00BF/\xc0\x00\x00\x00\x00CH\xa3\xd0\x00\x00\x00\x00" +
+	"D\x13\x9c\xc0\x00\x00\x00\x00E\x1fKP\x00\x00\x00\x00E\xf3~\xc0\x00\x00\x00\x00G\bg\xd0\x00\x00\x00\x00G\xd3`\xc0\x00\x00\x00\x00H\xe8I\xd0\x00\x00\x00\x00I\xb3B\xc0\x00\x00\x00\x00J\xc8+\xd0" +
+	"\x00\x00\x00\x00K\x9c_@\x00\x00\x00\x00L\xa8\r\xd0\x00\x00\x00\x00M|A@\x00\x00\x00\x00N\x87\xef\xd0\x00\x00\x00\x00O\\#@\x00\x00\x00\x00Pq\fP\x00\x00\x00\x00Q<\x05@\x00\x00\x00\x00" +
+	"RP\xeeP\x00\x00\x00\x00S\x1b\xe7@\x00\x00\x00\x00T0\xd0P\x00\x00\x00\x00T\xfb\xc9@\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x06\x05\x06\x05\a\x05\a" +
+	"\x05\x06\x05\a\x05\a\x05\b\x06\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\xff\xff\xcbM\x00\x00" +
+	"\xff\xff\xcbM\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xce\xc8\x00\f\xff\xff\xd5\xd0\x01\x12\xff\xff\xd5\xd0\x00\x12\xff\xff\xdc\xd8\x01\x16\xff\xff\xe3\xe0\x01\x1c\xff\xff\xea\xe8\x01 LMT\x00MMT\x00-04\x00" +
+	"-0330\x00-03\x00-0230\x00-02\x00-0130\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ӿ\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00" +
+	"\x10\x00\x00\x00America/MontrealTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" +
+	"\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xffr" +
+	"\xeex\xec\xff\xff\xff\xff\x9e\xb8\x93p\xff\xff\xff\xff\x9f\xba\xeb`\xff\xff\xff\xff\xa0\x87.\xc8\xff\xff\xff\xff\xa1\x9a\xb1@\xff\xff\xff\xff\xa2\x94\x06\xf0\xff\xff\xff\xff\xa3U\xa9@\xff\xff\xff\xff\xa4\x86]\xf0\xff" +
+	"\xff\xff\xff\xa5(x`\xff\xff\xff\xff\xa6f?\xf0\xff\xff\xff\xff\xa7\fN\xe0\xff\xff\xff\xff\xa8F!\xf0\xff\xff\xff\xff\xa8\xec0\xe0\xff\xff\xff\xff\xaa\x1c\xc9p\xff\xff\xff\xff\xaa\xd5M`\xff\xff\xff\xff\xab" +
+	"\xfc\xabp\xff\xff\xff\xff\xac\xb5/`\xff\xff\xff\xff\xad܍p\xff\xff\xff\xff\xae\x95\x11`\xff\xff\xff\xff\xaf\xbcop\xff\xff\xff\xff\xb0~-\xe0\xff\xff\xff\xff\xb1\x9cQp\xff\xff\xff\xff\xb2gJ`\xff" +
+	"\xff\xff\xff\xb3|3p\xff\xff\xff\xff\xb4G,`\xff\xff\xff\xff\xb5\\\x15p\xff\xff\xff\xff\xb6'\x0e`\xff\xff\xff\xff\xb7;\xf7p\xff\xff\xff\xff\xb8\x06\xf0`\xff\xff\xff\xff\xb9%\x13\xf0\xff\xff\xff\xff\xb9" +
+	"\xe6\xd2`\xff\xff\xff\xff\xbb\x04\xf5\xf0\xff\xff\xff\xff\xbb\xcf\xee\xe0\xff\xff\xff\xff\xbc\xe4\xd7\xf0\xff\xff\xff\xff\xbd\xaf\xd0\xe0\xff\xff\xff\xff\xbeĹ\xf0\xff\xff\xff\xff\xbf\x8f\xb2\xe0\xff\xff\xff\xff\xc0\xa4\x9b\xf0\xff" +
+	"\xff\xff\xff\xc1o\x94\xe0\xff\xff\xff\xff\u0084}\xf0\xff\xff\xff\xff\xc3Ov\xe0\xff\xff\xff\xff\xc4d_\xf0\xff\xff\xff\xff\xc5/X\xe0\xff\xff\xff\xff\xc6M|p\xff\xff\xff\xff\xc7\x0f:\xe0\xff\xff\xff\xff\xc8" +
+	"-^p\xff\xff\xff\xffˈ\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff\xd3u\xe4\xf0\xff\xff\xff\xff\xd4@\xdd\xe0\xff\xff\xff\xff\xd5U\xaa\xd0\xff\xff\xff\xff\xd6 \xa3\xc0\xff" +
+	"\xff\xff\xff\xd75\x8c\xd0\xff\xff\xff\xff\xd8\x00\x85\xc0\xff\xff\xff\xff\xd9\x15n\xd0\xff\xff\xff\xff\xda3v@\xff\xff\xff\xff\xda\xfe\xa7p\xff\xff\xff\xff\xdc\x13t`\xff\xff\xff\xff\xdcމp\xff\xff\xff\xff\xdd" +
+	"\xa9\x82`\xff\xff\xff\xff\u07bekp\xff\xff\xff\xff߉d`\xff\xff\xff\xff\xe0\x9eMp\xff\xff\xff\xff\xe1iF`\xff\xff\xff\xff\xe2~/p\xff\xff\xff\xff\xe3I(`\xff\xff\xff\xff\xe4^\x11p\xff" +
+	"\xff\xff\xff\xe5)\n`\xff\xff\xff\xff\xe6G-\xf0\xff\xff\xff\xff\xe7\x12&\xe0\xff\xff\xff\xff\xe8'\x0f\xf0\xff\xff\xff\xff\xe9\x16\xf2\xe0\xff\xff\xff\xff\xea\x06\xf1\xf0\xff\xff\xff\xff\xea\xf6\xd4\xe0\xff\xff\xff\xff\xeb" +
+	"\xe6\xd3\xf0\xff\xff\xff\xff\xecֶ\xe0\xff\xff\xff\xff\xedƵ\xf0\xff\xff\xff\xff\xee\xbf\xd3`\xff\xff\xff\xff\xef\xaf\xd2p\xff\xff\xff\xff\xf0\x9f\xb5`\xff\xff\xff\xff\xf1\x8f\xb4p\xff\xff\xff\xff\xf2\x7f\x97`\xff" +
+	"\xff\xff\xff\xf3o\x96p\xff\xff\xff\xff\xf4_y`\xff\xff\xff\xff\xf5Oxp\xff\xff\xff\xff\xf6?[`\xff\xff\xff\xff\xf7/Zp\xff\xff\xff\xff\xf8(w\xe0\xff\xff\xff\xff\xf9\x0f<p\xff\xff\xff\xff\xfa" +
+	"\bY\xe0\xff\xff\xff\xff\xfa\xf8X\xf0\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00" +
+	"\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\a0\xc2`\x00\x00\x00\x00\b" +
+	" \xc1p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\n\x00\xa3p\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00\f٢\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00" +
+	"\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x16" +
+	"9\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x00\x00\x00\x00\x1a\xf2\np\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00" +
+	"\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\"U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$" +
+	"5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\nU\xe0\x00\x00\x00\x00)ޥp\x00\x00\x00\x00*\xea7\xe0\x00" +
+	"\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002" +
+	"r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\a\r\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00" +
+	"\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@" +
+	"o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xb5\x94\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00" +
+	"\b\xff\xff\xc7\xc0\x01\f\xff\xff\xc7\xc0\x01\x10LMT\x00EDT\x00EST\x00EWT\x00EPT\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03" +
+	"\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x12\x00\x00\x00America/MontserratTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a" +
+	"\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ӿ\x92\xbc" +
+	"\xb5\x06\x00\x00\xb5\x06\x00\x00\x0e\x00\x00\x00America/NassauTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x00\x00\x00\x05\x00\x00\x00" +
+	"\x14\xff\xff\xff\xffr\xeex\xec\xff\xff\xff\xff\x9e\xb8\x93p\xff\xff\xff\xff\x9f\xba\xeb`\xff\xff\xff\xff\xa0\x87.\xc8\xff\xff\xff\xff\xa1\x9a\xb1@\xff\xff\xff\xff\xa2\x94\x06\xf0\xff\xff\xff\xff\xa3U\xa9@\xff\xff\xff" +
+	"\xff\xa4\x86]\xf0\xff\xff\xff\xff\xa5(x`\xff\xff\xff\xff\xa6f?\xf0\xff\xff\xff\xff\xa7\fN\xe0\xff\xff\xff\xff\xa8F!\xf0\xff\xff\xff\xff\xa8\xec0\xe0\xff\xff\xff\xff\xaa\x1c\xc9p\xff\xff\xff\xff\xaa\xd5M" +
+	"`\xff\xff\xff\xff\xab\xfc\xabp\xff\xff\xff\xff\xac\xb5/`\xff\xff\xff\xff\xad܍p\xff\xff\xff\xff\xae\x95\x11`\xff\xff\xff\xff\xaf\xbcop\xff\xff\xff\xff\xb0~-\xe0\xff\xff\xff\xff\xb1\x9cQp\xff\xff\xff" +
+	"\xff\xb2gJ`\xff\xff\xff\xff\xb3|3p\xff\xff\xff\xff\xb4G,`\xff\xff\xff\xff\xb5\\\x15p\xff\xff\xff\xff\xb6'\x0e`\xff\xff\xff\xff\xb7;\xf7p\xff\xff\xff\xff\xb8\x06\xf0`\xff\xff\xff\xff\xb9%\x13" +
+	"\xf0\xff\xff\xff\xff\xb9\xe6\xd2`\xff\xff\xff\xff\xbb\x04\xf5\xf0\xff\xff\xff\xff\xbb\xcf\xee\xe0\xff\xff\xff\xff\xbc\xe4\xd7\xf0\xff\xff\xff\xff\xbd\xaf\xd0\xe0\xff\xff\xff\xff\xbeĹ\xf0\xff\xff\xff\xff\xbf\x8f\xb2\xe0\xff\xff\xff" +
+	"\xff\xc0\xa4\x9b\xf0\xff\xff\xff\xff\xc1o\x94\xe0\xff\xff\xff\xff\u0084}\xf0\xff\xff\xff\xff\xc3Ov\xe0\xff\xff\xff\xff\xc4d_\xf0\xff\xff\xff\xff\xc5/X\xe0\xff\xff\xff\xff\xc6M|p\xff\xff\xff\xff\xc7\x0f:" +
+	"\xe0\xff\xff\xff\xff\xc8-^p\xff\xff\xff\xffˈ\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff\xd3u\xe4\xf0\xff\xff\xff\xff\xd4@\xdd\xe0\xff\xff\xff\xff\xd5U\xaa\xd0\xff\xff\xff" +
+	"\xff\xd6 \xa3\xc0\xff\xff\xff\xff\xd75\x8c\xd0\xff\xff\xff\xff\xd8\x00\x85\xc0\xff\xff\xff\xff\xd9\x15n\xd0\xff\xff\xff\xff\xda3v@\xff\xff\xff\xff\xda\xfe\xa7p\xff\xff\xff\xff\xdc\x13t`\xff\xff\xff\xff\xdcމ" +
+	"p\xff\xff\xff\xffݩ\x82`\xff\xff\xff\xff\u07bekp\xff\xff\xff\xff߉d`\xff\xff\xff\xff\xe0\x9eMp\xff\xff\xff\xff\xe1iF`\xff\xff\xff\xff\xe2~/p\xff\xff\xff\xff\xe3I(`\xff\xff\xff" +
+	"\xff\xe4^\x11p\xff\xff\xff\xff\xe5)\n`\xff\xff\xff\xff\xe6G-\xf0\xff\xff\xff\xff\xe7\x12&\xe0\xff\xff\xff\xff\xe8'\x0f\xf0\xff\xff\xff\xff\xe9\x16\xf2\xe0\xff\xff\xff\xff\xea\x06\xf1\xf0\xff\xff\xff\xff\xea\xf6\xd4" +
+	"\xe0\xff\xff\xff\xff\xeb\xe6\xd3\xf0\xff\xff\xff\xff\xecֶ\xe0\xff\xff\xff\xff\xedƵ\xf0\xff\xff\xff\xff\xee\xbf\xd3`\xff\xff\xff\xff\xef\xaf\xd2p\xff\xff\xff\xff\xf0\x9f\xb5`\xff\xff\xff\xff\xf1\x8f\xb4p\xff\xff\xff" +
+	"\xff\xf2\x7f\x97`\xff\xff\xff\xff\xf3o\x96p\xff\xff\xff\xff\xf4_y`\xff\xff\xff\xff\xf5Oxp\xff\xff\xff\xff\xf6?[`\xff\xff\xff\xff\xf7/Zp\xff\xff\xff\xff\xf8(w\xe0\xff\xff\xff\xff\xf9\x0f<" +
+	"p\xff\xff\xff\xff\xfa\bY\xe0\xff\xff\xff\xff\xfa\xf8X\xf0\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00" +
+	"\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\a0\xc2" +
+	"`\x00\x00\x00\x00\b \xc1p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\n\x00\xa3p\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00\f٢\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00\x00" +
+	"\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)" +
+	"\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x00\x00\x00\x00\x1a\xf2\np\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00" +
+	"\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\"U\xe2\xf0\x00\x00\x00\x00#j\xaf" +
+	"\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\nU\xe0\x00\x00\x00\x00)ޥp\x00\x00\x00" +
+	"\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg" +
+	"\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\a\r\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00" +
+	"\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb" +
+	"\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xb5\x94\x00\x00\xff\xff\xc7\xc0\x01" +
+	"\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\f\xff\xff\xc7\xc0\x01\x10LMT\x00EDT\x00EST\x00EWT\x00EPT\x00\nEST5EDT,M3.2.0,M11.1" +
+	".0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\x9aG\xc8\xd0\x06\x00\x00\xd0\x06\x00\x00\x10\x00\x00\x00America/New_YorkTZif2\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaf\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff^\x03\xf0\x90\xff\xff\xff\xff\x9e\xa6\x1ep\xff\xff\xff\xff\x9f\xba\xeb`\xff\xff\xff\xff\xa0\x86\x00p\xff\xff\xff\xff" +
+	"\xa1\x9a\xcd`\xff\xff\xff\xff\xa2e\xe2p\xff\xff\xff\xff\xa3\x83\xe9\xe0\xff\xff\xff\xff\xa4j\xaep\xff\xff\xff\xff\xa55\xa7`\xff\xff\xff\xff\xa6S\xca\xf0\xff\xff\xff\xff\xa7\x15\x89`\xff\xff\xff\xff\xa83\xac\xf0" +
+	"\xff\xff\xff\xff\xa8\xfe\xa5\xe0\xff\xff\xff\xff\xaa\x13\x8e\xf0\xff\xff\xff\xff\xaaއ\xe0\xff\xff\xff\xff\xab\xf3p\xf0\xff\xff\xff\xff\xac\xbei\xe0\xff\xff\xff\xff\xad\xd3R\xf0\xff\xff\xff\xff\xae\x9eK\xe0\xff\xff\xff\xff" +
+	"\xaf\xb34\xf0\xff\xff\xff\xff\xb0~-\xe0\xff\xff\xff\xff\xb1\x9cQp\xff\xff\xff\xff\xb2gJ`\xff\xff\xff\xff\xb3|3p\xff\xff\xff\xff\xb4G,`\xff\xff\xff\xff\xb5\\\x15p\xff\xff\xff\xff\xb6'\x0e`" +
+	"\xff\xff\xff\xff\xb7;\xf7p\xff\xff\xff\xff\xb8\x06\xf0`\xff\xff\xff\xff\xb9\x1b\xd9p\xff\xff\xff\xff\xb9\xe6\xd2`\xff\xff\xff\xff\xbb\x04\xf5\xf0\xff\xff\xff\xff\xbbƴ`\xff\xff\xff\xff\xbc\xe4\xd7\xf0\xff\xff\xff\xff" +
+	"\xbd\xaf\xd0\xe0\xff\xff\xff\xff\xbeĹ\xf0\xff\xff\xff\xff\xbf\x8f\xb2\xe0\xff\xff\xff\xff\xc0\xa4\x9b\xf0\xff\xff\xff\xff\xc1o\x94\xe0\xff\xff\xff\xff\u0084}\xf0\xff\xff\xff\xff\xc3Ov\xe0\xff\xff\xff\xff\xc4d_\xf0" +
+	"\xff\xff\xff\xff\xc5/X\xe0\xff\xff\xff\xff\xc6M|p\xff\xff\xff\xff\xc7\x0f:\xe0\xff\xff\xff\xff\xc8-^p\xff\xff\xff\xff\xc8\xf8W`\xff\xff\xff\xff\xca\r@p\xff\xff\xff\xff\xca\xd89`\xff\xff\xff\xff" +
+	"ˈ\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff\xd3u\xe4\xf0\xff\xff\xff\xff\xd4@\xdd\xe0\xff\xff\xff\xff\xd5U\xc6\xf0\xff\xff\xff\xff\xd6 \xbf\xe0\xff\xff\xff\xff\xd75\xa8\xf0" +
+	"\xff\xff\xff\xff\xd8\x00\xa1\xe0\xff\xff\xff\xff\xd9\x15\x8a\xf0\xff\xff\xff\xff\xd9\xe0\x83\xe0\xff\xff\xff\xff\xda\xfe\xa7p\xff\xff\xff\xff\xdb\xc0e\xe0\xff\xff\xff\xff\xdcމp\xff\xff\xff\xffݩ\x82`\xff\xff\xff\xff" +
+	"\u07bekp\xff\xff\xff\xff߉d`\xff\xff\xff\xff\xe0\x9eMp\xff\xff\xff\xff\xe1iF`\xff\xff\xff\xff\xe2~/p\xff\xff\xff\xff\xe3I(`\xff\xff\xff\xff\xe4^\x11p\xff\xff\xff\xff\xe5W.\xe0" +
+	"\xff\xff\xff\xff\xe6G-\xf0\xff\xff\xff\xff\xe77\x10\xe0\xff\xff\xff\xff\xe8'\x0f\xf0\xff\xff\xff\xff\xe9\x16\xf2\xe0\xff\xff\xff\xff\xea\x06\xf1\xf0\xff\xff\xff\xff\xea\xf6\xd4\xe0\xff\xff\xff\xff\xeb\xe6\xd3\xf0\xff\xff\xff\xff" +
+	"\xecֶ\xe0\xff\xff\xff\xff\xedƵ\xf0\xff\xff\xff\xff\xee\xbf\xd3`\xff\xff\xff\xff\xef\xaf\xd2p\xff\xff\xff\xff\xf0\x9f\xb5`\xff\xff\xff\xff\xf1\x8f\xb4p\xff\xff\xff\xff\xf2\x7f\x97`\xff\xff\xff\xff\xf3o\x96p" +
+	"\xff\xff\xff\xff\xf4_y`\xff\xff\xff\xff\xf5Oxp\xff\xff\xff\xff\xf6?[`\xff\xff\xff\xff\xf7/Zp\xff\xff\xff\xff\xf8(w\xe0\xff\xff\xff\xff\xf9\x0f<p\xff\xff\xff\xff\xfa\bY\xe0\xff\xff\xff\xff" +
+	"\xfa\xf8X\xf0\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0" +
+	"\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\a0\xc2`\x00\x00\x00\x00\a\x8d\x19p\x00\x00\x00\x00" +
+	"\t\x10\xa4`\x00\x00\x00\x00\t\xad\x94\xf0\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00\f٢\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0" +
+	"\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00" +
+	"\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x00\x00\x00\x00\x1a\xf2\np\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`" +
+	"\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\"U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00" +
+	"%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\nU\xe0\x00\x00\x00\x00)ޥp\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p" +
+	"\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x00" +
+	"3GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\a\r\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0" +
+	"\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00" +
+	"A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xba\x9e\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7" +
+	"\xc0\x01\f\xff\xff\xc7\xc0\x01\x10LMT\x00EDT\x00EST\x00EWT\x00EPT\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00ӿ\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00\x0f\x00\x00\x00America/NipigonTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\xac\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xffr\xeex\xec\xff\xff\xff\xff\x9e\xb8\x93p\xff\xff\xff\xff\x9f\xba\xeb`\xff\xff\xff\xff\xa0\x87.\xc8\xff\xff\xff\xff\xa1\x9a\xb1@\xff\xff\xff\xff\xa2\x94\x06" +
+	"\xf0\xff\xff\xff\xff\xa3U\xa9@\xff\xff\xff\xff\xa4\x86]\xf0\xff\xff\xff\xff\xa5(x`\xff\xff\xff\xff\xa6f?\xf0\xff\xff\xff\xff\xa7\fN\xe0\xff\xff\xff\xff\xa8F!\xf0\xff\xff\xff\xff\xa8\xec0\xe0\xff\xff\xff" +
+	"\xff\xaa\x1c\xc9p\xff\xff\xff\xff\xaa\xd5M`\xff\xff\xff\xff\xab\xfc\xabp\xff\xff\xff\xff\xac\xb5/`\xff\xff\xff\xff\xad܍p\xff\xff\xff\xff\xae\x95\x11`\xff\xff\xff\xff\xaf\xbcop\xff\xff\xff\xff\xb0~-" +
+	"\xe0\xff\xff\xff\xff\xb1\x9cQp\xff\xff\xff\xff\xb2gJ`\xff\xff\xff\xff\xb3|3p\xff\xff\xff\xff\xb4G,`\xff\xff\xff\xff\xb5\\\x15p\xff\xff\xff\xff\xb6'\x0e`\xff\xff\xff\xff\xb7;\xf7p\xff\xff\xff" +
+	"\xff\xb8\x06\xf0`\xff\xff\xff\xff\xb9%\x13\xf0\xff\xff\xff\xff\xb9\xe6\xd2`\xff\xff\xff\xff\xbb\x04\xf5\xf0\xff\xff\xff\xff\xbb\xcf\xee\xe0\xff\xff\xff\xff\xbc\xe4\xd7\xf0\xff\xff\xff\xff\xbd\xaf\xd0\xe0\xff\xff\xff\xff\xbeĹ" +
+	"\xf0\xff\xff\xff\xff\xbf\x8f\xb2\xe0\xff\xff\xff\xff\xc0\xa4\x9b\xf0\xff\xff\xff\xff\xc1o\x94\xe0\xff\xff\xff\xff\u0084}\xf0\xff\xff\xff\xff\xc3Ov\xe0\xff\xff\xff\xff\xc4d_\xf0\xff\xff\xff\xff\xc5/X\xe0\xff\xff\xff" +
+	"\xff\xc6M|p\xff\xff\xff\xff\xc7\x0f:\xe0\xff\xff\xff\xff\xc8-^p\xff\xff\xff\xffˈ\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff\xd3u\xe4\xf0\xff\xff\xff\xff\xd4@\xdd" +
+	"\xe0\xff\xff\xff\xff\xd5U\xaa\xd0\xff\xff\xff\xff\xd6 \xa3\xc0\xff\xff\xff\xff\xd75\x8c\xd0\xff\xff\xff\xff\xd8\x00\x85\xc0\xff\xff\xff\xff\xd9\x15n\xd0\xff\xff\xff\xff\xda3v@\xff\xff\xff\xff\xda\xfe\xa7p\xff\xff\xff" +
+	"\xff\xdc\x13t`\xff\xff\xff\xff\xdcމp\xff\xff\xff\xffݩ\x82`\xff\xff\xff\xff\u07bekp\xff\xff\xff\xff߉d`\xff\xff\xff\xff\xe0\x9eMp\xff\xff\xff\xff\xe1iF`\xff\xff\xff\xff\xe2~/" +
+	"p\xff\xff\xff\xff\xe3I(`\xff\xff\xff\xff\xe4^\x11p\xff\xff\xff\xff\xe5)\n`\xff\xff\xff\xff\xe6G-\xf0\xff\xff\xff\xff\xe7\x12&\xe0\xff\xff\xff\xff\xe8'\x0f\xf0\xff\xff\xff\xff\xe9\x16\xf2\xe0\xff\xff\xff" +
+	"\xff\xea\x06\xf1\xf0\xff\xff\xff\xff\xea\xf6\xd4\xe0\xff\xff\xff\xff\xeb\xe6\xd3\xf0\xff\xff\xff\xff\xecֶ\xe0\xff\xff\xff\xff\xedƵ\xf0\xff\xff\xff\xff\xee\xbf\xd3`\xff\xff\xff\xff\xef\xaf\xd2p\xff\xff\xff\xff\xf0\x9f\xb5" +
+	"`\xff\xff\xff\xff\xf1\x8f\xb4p\xff\xff\xff\xff\xf2\x7f\x97`\xff\xff\xff\xff\xf3o\x96p\xff\xff\xff\xff\xf4_y`\xff\xff\xff\xff\xf5Oxp\xff\xff\xff\xff\xf6?[`\xff\xff\xff\xff\xf7/Zp\xff\xff\xff" +
+	"\xff\xf8(w\xe0\xff\xff\xff\xff\xf9\x0f<p\xff\xff\xff\xff\xfa\bY\xe0\xff\xff\xff\xff\xfa\xf8X\xf0\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\xff\xff\xff\xff\xfe\xb8\x1c" +
+	"\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00" +
+	"\x00\x06@\xdfp\x00\x00\x00\x00\a0\xc2`\x00\x00\x00\x00\b \xc1p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\n\x00\xa3p\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00\f٢" +
+	"\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00" +
+	"\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x00\x00\x00\x00\x1a\xf2\n" +
+	"p\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00" +
+	"\x00\"U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\nU" +
+	"\xe0\x00\x00\x00\x00)ޥp\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00" +
+	"\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\a\r" +
+	"\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00" +
+	"\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC" +
+	"`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x04\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\xff\xff\xb5\x94\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\f\xff\xff\xc7\xc0\x01\x10LMT\x00EDT\x00EST\x00EWT\x00EPT\x00\nEST5EDT," +
+	"M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\xab\xd5\xf9\xcf\x03\x00\x00\xcf\x03\x00\x00\f\x00\x00\x00America/NomeTZi" +
+	"f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00T\x00\x00\x00\n\x00\x00\x00&\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}\x87O\xd2\xff\xff\xff\xffˉD\xd0\xff\xff\xff\xff" +
+	"\xd2#\xf4p\xff\xff\xff\xff\xd2aP@\xff\xff\xff\xff\xfa\xd2U\xb0\xff\xff\xff\xff\xfe\xb8qP\xff\xff\xff\xff\xff\xa8T@\x00\x00\x00\x00\x00\x98SP\x00\x00\x00\x00\x01\x886@\x00\x00\x00\x00\x02x5P" +
+	"\x00\x00\x00\x00\x03qR\xc0\x00\x00\x00\x00\x04aQ\xd0\x00\x00\x00\x00\x05Q4\xc0\x00\x00\x00\x00\x06A3\xd0\x00\x00\x00\x00\a1\x16\xc0\x00\x00\x00\x00\a\x8dm\xd0\x00\x00\x00\x00\t\x10\xf8\xc0\x00\x00\x00\x00" +
+	"\t\xad\xe9P\x00\x00\x00\x00\n\xf0\xda\xc0\x00\x00\x00\x00\v\xe0\xd9\xd0\x00\x00\x00\x00\f\xd9\xf7@\x00\x00\x00\x00\r\xc0\xbb\xd0\x00\x00\x00\x00\x0e\xb9\xd9@\x00\x00\x00\x00\x0f\xa9\xd8P\x00\x00\x00\x00\x10\x99\xbb@" +
+	"\x00\x00\x00\x00\x11\x89\xbaP\x00\x00\x00\x00\x12y\x9d@\x00\x00\x00\x00\x13i\x9cP\x00\x00\x00\x00\x14Y\x7f@\x00\x00\x00\x00\x15I~P\x00\x00\x00\x00\x169a@\x00\x00\x00\x00\x17)`P\x00\x00\x00\x00" +
+	"\x18\"}\xc0\x00\x00\x00\x00\x19\tBP\x00\x00\x00\x00\x1a\x02_\xc0\x00\x00\x00\x00\x1a+\x14\x10\x00\x00\x00\x00\x1a\xf2B\xb0\x00\x00\x00\x00\x1b\xe2%\xa0\x00\x00\x00\x00\x1c\xd2$\xb0\x00\x00\x00\x00\x1d\xc2\a\xa0" +
+	"\x00\x00\x00\x00\x1e\xb2\x06\xb0\x00\x00\x00\x00\x1f\xa1\xe9\xa0\x00\x00\x00\x00 v90\x00\x00\x00\x00!\x81ˠ\x00\x00\x00\x00\"V\x1b0\x00\x00\x00\x00#j\xe8 \x00\x00\x00\x00$5\xfd0\x00\x00\x00\x00" +
+	"%J\xca \x00\x00\x00\x00&\x15\xdf0\x00\x00\x00\x00'*\xac \x00\x00\x00\x00'\xfe\xfb\xb0\x00\x00\x00\x00)\n\x8e \x00\x00\x00\x00)\xdeݰ\x00\x00\x00\x00*\xeap \x00\x00\x00\x00+\xbe\xbf\xb0" +
+	"\x00\x00\x00\x00,ӌ\xa0\x00\x00\x00\x00-\x9e\xa1\xb0\x00\x00\x00\x00.\xb3n\xa0\x00\x00\x00\x00/~\x83\xb0\x00\x00\x00\x000\x93P\xa0\x00\x00\x00\x001g\xa00\x00\x00\x00\x002s2\xa0\x00\x00\x00\x00" +
+	"3G\x820\x00\x00\x00\x004S\x14\xa0\x00\x00\x00\x005'd0\x00\x00\x00\x0062\xf6\xa0\x00\x00\x00\x007\aF0\x00\x00\x00\x008\x1c\x13 \x00\x00\x00\x008\xe7(0\x00\x00\x00\x009\xfb\xf5 " +
+	"\x00\x00\x00\x00:\xc7\n0\x00\x00\x00\x00;\xdb\xd7 \x00\x00\x00\x00<\xb0&\xb0\x00\x00\x00\x00=\xbb\xb9 \x00\x00\x00\x00>\x90\b\xb0\x00\x00\x00\x00?\x9b\x9b \x00\x00\x00\x00@o\xea\xb0\x00\x00\x00\x00" +
+	"A\x84\xb7\xa0\x00\x00\x00\x00BO̰\x00\x00\x00\x00Cd\x99\xa0\x00\x00\x00\x00D/\xae\xb0\x00\x00\x00\x00ED{\xa0\x00\x00\x00\x00E\xf3\xe10\x01\x02\x03\x04\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" +
+	"\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\a\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b" +
+	"\t\b\t\b\t\b\t\b\x00\x00\xb6n\x00\x00\xff\xffd\xee\x00\x00\xff\xffeP\x00\x04\xff\xffs`\x01\b\xff\xffs`\x01\f\xff\xffeP\x00\x10\xff\xffs`\x01\x14\xff\xff\x81p\x00\x18\xff\xff\x8f\x80" +
+	"\x01\x1c\xff\xff\x81p\x00!LMT\x00NST\x00NWT\x00NPT\x00BST\x00BDT\x00YST\x00AKDT\x00AKST\x00\nAKST9AKDT,M3." +
+	"2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7-2f\xe4\x01\x00\x00\xe4\x01\x00\x00\x0f\x00\x00\x00America/NoronhaTZi" +
+	"f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaaed\xff\xff\xff\xff\xb8\x0f;\xd0\xff\xff\xff\xff\xb8\xfd2\x90\xff\xff\xff\xff" +
+	"\xb9\xf1& \xff\xff\xff\xff\xba\xdef\x10\xff\xff\xff\xff\xda8\xa0 \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdc\x19Ӡ\xff\xff\xff\xffܹK\x10\xff\xff\xff\xff\xdd\xfb\a \xff\xff\xff\xffޛ\xd0\x10" +
+	"\xff\xff\xff\xff\xdf\u074c \xff\xff\xff\xff\xe0T%\x10\xff\xff\xff\xff\xf4\x97\xf1\xa0\xff\xff\xff\xff\xf5\x05P\x10\xff\xff\xff\xff\xf6\xc0V \xff\xff\xff\xff\xf7\x0e\x10\x90\xff\xff\xff\xff\xf8Q\x1e \xff\xff\xff\xff" +
+	"\xf8Ƿ\x10\xff\xff\xff\xff\xfa\nĠ\xff\xff\xff\xff\xfa\xa8\xea\x90\xff\xff\xff\xff\xfb\xeb\xf8 \xff\xff\xff\xff\xfc\x8bo\x90\x00\x00\x00\x00\x1dɀ \x00\x00\x00\x00\x1exɐ\x00\x00\x00\x00\x1f\xa0'\xa0" +
+	"\x00\x00\x00\x00 3\xc1\x90\x00\x00\x00\x00!\x81[ \x00\x00\x00\x00\"\v\xba\x90\x00\x00\x00\x00#X\x02\xa0\x00\x00\x00\x00#\xe2b\x10\x00\x00\x00\x00%7\xe4\xa0\x00\x00\x00\x00%Թ\x10\x00\x00\x00\x00" +
+	"7\xf6\xb8\xa0\x00\x00\x00\x008\xb8w\x10\x00\x00\x00\x009\xdf\xd5 \x00\x00\x00\x009\xe9\x01\x90\x00\x00\x00\x00;\xc8\xf1\xa0\x00\x00\x00\x00<o\x00\x90\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xe1\x9c\x00\x00\xff\xff\xf1\xf0\x01\x04\xff\xff\xe3\xe0\x00\bLMT\x00-01\x00-02\x00\n<-02>2" +
+	"\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7.\xb6*\x13\x04\x00\x00\x13\x04\x00\x00\x1b\x00\x00\x00America/North_Dakota/BeulahTZ" +
+	"if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff^\x04\f\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff" +
+	"\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W" +
+	"\x10\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb89\x10\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x1b\x10\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xfd\x10\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00" +
+	"\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\a\x8d5\x90\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\t\xad\xb1\x10\x00\x00\x00\x00\n\xf0\xa2" +
+	"\x80\x00\x00\x00\x00\vࡐ\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00" +
+	"\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n" +
+	"\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00" +
+	"\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90" +
+	"\x00\x00\x00\x00\x00'\xfeߐ\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00" +
+	"\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H" +
+	"\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;ۻ\x00\x00\x00\x00" +
+	"\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}" +
+	"\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x00\x00\x00\x00G-|\x00\x00\x00\x00\x00Gӧ\x10\x00\x00\x00\x00I\r^\x00\x00\x00\x00\x00I\xb3\x89\x10\x00\x00\x00" +
+	"\x00J\xed@\x00\x00\x00\x00\x00K\x9c\xa5\x90\x00\x00\x00\x00L\xd6\\\x80\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x05\xff\xff\xa0" +
+	"\x95\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10\xff\xff\xab\xa0\x00\x14LMT\x00MDT\x00MST\x00MWT\x00MPT\x00CST\x00\nCS" +
+	"T6CDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00H\xeam\xef\xde\x03\x00\x00\xde\x03\x00\x00\x1b\x00\x00\x00America/N" +
+	"orth_Dakota/CenterTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00" +
 	"\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y\x00\x00\x00\a\x00\x00\x00\x1c\xff\xff\xff\xff^\x04\f" +
 	"\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff" +
 	"\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W\x10\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb89\x10\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x1b\x10\x00\x00\x00\x00\x01\x87\xfe" +
@@ -1732,574 +1792,428 @@
 	"\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01" +
 	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" +
 	"\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\xff\xff\xa1\b\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10\xff\xff\xb9\xb0\x01\x14\xff\xff\xab\xa0\x00\x18LMT\x00" +
-	"MDT\x00MST\x00MWT\x00MPT\x00CDT\x00CST\x00\nCST6CDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj" +
-	"\xbeT\xb7.\xb6*\x13\x04\x00\x00\x13\x04\x00\x00\x1b\x00\x1c\x00America/North_Dakota/BeulahUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux" +
-	"\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00" +
-	"\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff^\x04\f\xb0\xff\xff\xff\xff" +
-	"\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xfa\xf8u\x10" +
-	"\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W\x10\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb89\x10\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x1b\x10\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00" +
-	"\x02w\xfd\x10\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\a\x8d5\x90\x00\x00\x00\x00\t\x10\xc0\x80" +
-	"\x00\x00\x00\x00\t\xad\xb1\x10\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\vࡐ\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00" +
-	"\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10" +
-	"\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00" +
-	"\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00" +
-	"\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeߐ\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00" +
-	",\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10" +
-	"\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00" +
-	":\xc6\xee\x10\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80" +
-	"\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x00\x00\x00\x00G-|\x00\x00\x00\x00\x00Gӧ\x10\x00\x00\x00\x00" +
-	"I\r^\x00\x00\x00\x00\x00I\xb3\x89\x10\x00\x00\x00\x00J\xed@\x00\x00\x00\x00\x00K\x9c\xa5\x90\x00\x00\x00\x00L\xd6\\\x80\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x05\xff\xff\xa0\x95\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10\xff\xff\xab\xa0\x00\x14LMT\x00MDT\x00MST\x00" +
-	"MWT\x00MPT\x00CST\x00\nCST6CDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTM\x94\xc7Kp\x03\x00\x00p\x03" +
-	"\x00\x00\x11\x00\x1c\x00America/Glace_BayUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00O\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\x80\xf1\xa84\xff\xff\xff\xff\x9e\xb8\x85`\xff\xff\xff\xff\x9f\xba\xddP\xff\xff\xff\xffˈ\xe2`\xff\xff" +
-	"\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\xff\xff\xff\xff\xe0\x9e?`\xff\xff\xff\xff\xe1i8P\x00\x00\x00\x00\x04`\xef`\x00\x00\x00\x00\x05P\xd2P\x00\x00\x00\x00\x06@\xd1`\x00\x00\x00\x00\a0" +
-	"\xb4P\x00\x00\x00\x00\b \xb3`\x00\x00\x00\x00\t\x10\x96P\x00\x00\x00\x00\n\x00\x95`\x00\x00\x00\x00\n\xf0xP\x00\x00\x00\x00\v\xe0w`\x00\x00\x00\x00\fٔ\xd0\x00\x00\x00\x00\r\xc0Y`\x00\x00" +
-	"\x00\x00\x0e\xb9v\xd0\x00\x00\x00\x00\x0f\xa9u\xe0\x00\x00\x00\x00\x10\x99X\xd0\x00\x00\x00\x00\x11\x89W\xe0\x00\x00\x00\x00\x12y:\xd0\x00\x00\x00\x00\x13i9\xe0\x00\x00\x00\x00\x14Y\x1c\xd0\x00\x00\x00\x00\x15I" +
-	"\x1b\xe0\x00\x00\x00\x00\x168\xfe\xd0\x00\x00\x00\x00\x17(\xfd\xe0\x00\x00\x00\x00\x18\"\x1bP\x00\x00\x00\x00\x19\b\xdf\xe0\x00\x00\x00\x00\x1a\x01\xfdP\x00\x00\x00\x00\x1a\xf1\xfc`\x00\x00\x00\x00\x1b\xe1\xdfP\x00\x00" +
-	"\x00\x00\x1c\xd1\xde`\x00\x00\x00\x00\x1d\xc1\xc1P\x00\x00\x00\x00\x1e\xb1\xc0`\x00\x00\x00\x00\x1f\xa1\xa3P\x00\x00\x00\x00 u\xf2\xe0\x00\x00\x00\x00!\x81\x85P\x00\x00\x00\x00\"U\xd4\xe0\x00\x00\x00\x00#j" +
-	"\xa1\xd0\x00\x00\x00\x00$5\xb6\xe0\x00\x00\x00\x00%J\x83\xd0\x00\x00\x00\x00&\x15\x98\xe0\x00\x00\x00\x00'*e\xd0\x00\x00\x00\x00'\xfe\xb5`\x00\x00\x00\x00)\nG\xd0\x00\x00\x00\x00)ޗ`\x00\x00" +
-	"\x00\x00*\xea)\xd0\x00\x00\x00\x00+\xbey`\x00\x00\x00\x00,\xd3FP\x00\x00\x00\x00-\x9e[`\x00\x00\x00\x00.\xb3(P\x00\x00\x00\x00/~=`\x00\x00\x00\x000\x93\nP\x00\x00\x00\x001g" +
-	"Y\xe0\x00\x00\x00\x002r\xecP\x00\x00\x00\x003G;\xe0\x00\x00\x00\x004R\xceP\x00\x00\x00\x005'\x1d\xe0\x00\x00\x00\x0062\xb0P\x00\x00\x00\x007\x06\xff\xe0\x00\x00\x00\x008\x1b\xcc\xd0\x00\x00" +
-	"\x00\x008\xe6\xe1\xe0\x00\x00\x00\x009\xfb\xae\xd0\x00\x00\x00\x00:\xc6\xc3\xe0\x00\x00\x00\x00;ې\xd0\x00\x00\x00\x00<\xaf\xe0`\x00\x00\x00\x00=\xbbr\xd0\x00\x00\x00\x00>\x8f\xc2`\x00\x00\x00\x00?\x9b" +
-	"T\xd0\x00\x00\x00\x00@o\xa4`\x00\x00\x00\x00A\x84qP\x00\x00\x00\x00BO\x86`\x00\x00\x00\x00CdSP\x00\x00\x00\x00D/h`\x00\x00\x00\x00ED5P\x00\x00\x00\x00E\xf3\x9a\xe0\x02\x01" +
-	"\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xc7\xcc\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xd5\xd0\x01\x10LMT\x00ADT\x00AST\x00A" +
-	"WT\x00APT\x00\nAST4ADT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTq\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x12\x00\x1c" +
-	"\x00America/MontserratUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff" +
-	"\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTӿ" +
-	"\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00\x0f\x00\x1c\x00America/TorontoUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZi" +
-	"f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xffr\xeex\xec\xff\xff\xff\xff\x9e\xb8\x93p\xff\xff\xff\xff\x9f\xba\xeb`\xff\xff\xff\xff" +
-	"\xa0\x87.\xc8\xff\xff\xff\xff\xa1\x9a\xb1@\xff\xff\xff\xff\xa2\x94\x06\xf0\xff\xff\xff\xff\xa3U\xa9@\xff\xff\xff\xff\xa4\x86]\xf0\xff\xff\xff\xff\xa5(x`\xff\xff\xff\xff\xa6f?\xf0\xff\xff\xff\xff\xa7\fN\xe0" +
-	"\xff\xff\xff\xff\xa8F!\xf0\xff\xff\xff\xff\xa8\xec0\xe0\xff\xff\xff\xff\xaa\x1c\xc9p\xff\xff\xff\xff\xaa\xd5M`\xff\xff\xff\xff\xab\xfc\xabp\xff\xff\xff\xff\xac\xb5/`\xff\xff\xff\xff\xad܍p\xff\xff\xff\xff" +
-	"\xae\x95\x11`\xff\xff\xff\xff\xaf\xbcop\xff\xff\xff\xff\xb0~-\xe0\xff\xff\xff\xff\xb1\x9cQp\xff\xff\xff\xff\xb2gJ`\xff\xff\xff\xff\xb3|3p\xff\xff\xff\xff\xb4G,`\xff\xff\xff\xff\xb5\\\x15p" +
-	"\xff\xff\xff\xff\xb6'\x0e`\xff\xff\xff\xff\xb7;\xf7p\xff\xff\xff\xff\xb8\x06\xf0`\xff\xff\xff\xff\xb9%\x13\xf0\xff\xff\xff\xff\xb9\xe6\xd2`\xff\xff\xff\xff\xbb\x04\xf5\xf0\xff\xff\xff\xff\xbb\xcf\xee\xe0\xff\xff\xff\xff" +
-	"\xbc\xe4\xd7\xf0\xff\xff\xff\xff\xbd\xaf\xd0\xe0\xff\xff\xff\xff\xbeĹ\xf0\xff\xff\xff\xff\xbf\x8f\xb2\xe0\xff\xff\xff\xff\xc0\xa4\x9b\xf0\xff\xff\xff\xff\xc1o\x94\xe0\xff\xff\xff\xff\u0084}\xf0\xff\xff\xff\xff\xc3Ov\xe0" +
-	"\xff\xff\xff\xff\xc4d_\xf0\xff\xff\xff\xff\xc5/X\xe0\xff\xff\xff\xff\xc6M|p\xff\xff\xff\xff\xc7\x0f:\xe0\xff\xff\xff\xff\xc8-^p\xff\xff\xff\xffˈ\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff" +
-	"\xd2`\xfb\xe0\xff\xff\xff\xff\xd3u\xe4\xf0\xff\xff\xff\xff\xd4@\xdd\xe0\xff\xff\xff\xff\xd5U\xaa\xd0\xff\xff\xff\xff\xd6 \xa3\xc0\xff\xff\xff\xff\xd75\x8c\xd0\xff\xff\xff\xff\xd8\x00\x85\xc0\xff\xff\xff\xff\xd9\x15n\xd0" +
-	"\xff\xff\xff\xff\xda3v@\xff\xff\xff\xff\xda\xfe\xa7p\xff\xff\xff\xff\xdc\x13t`\xff\xff\xff\xff\xdcމp\xff\xff\xff\xffݩ\x82`\xff\xff\xff\xff\u07bekp\xff\xff\xff\xff߉d`\xff\xff\xff\xff" +
-	"\xe0\x9eMp\xff\xff\xff\xff\xe1iF`\xff\xff\xff\xff\xe2~/p\xff\xff\xff\xff\xe3I(`\xff\xff\xff\xff\xe4^\x11p\xff\xff\xff\xff\xe5)\n`\xff\xff\xff\xff\xe6G-\xf0\xff\xff\xff\xff\xe7\x12&\xe0" +
-	"\xff\xff\xff\xff\xe8'\x0f\xf0\xff\xff\xff\xff\xe9\x16\xf2\xe0\xff\xff\xff\xff\xea\x06\xf1\xf0\xff\xff\xff\xff\xea\xf6\xd4\xe0\xff\xff\xff\xff\xeb\xe6\xd3\xf0\xff\xff\xff\xff\xecֶ\xe0\xff\xff\xff\xff\xedƵ\xf0\xff\xff\xff\xff" +
-	"\xee\xbf\xd3`\xff\xff\xff\xff\xef\xaf\xd2p\xff\xff\xff\xff\xf0\x9f\xb5`\xff\xff\xff\xff\xf1\x8f\xb4p\xff\xff\xff\xff\xf2\x7f\x97`\xff\xff\xff\xff\xf3o\x96p\xff\xff\xff\xff\xf4_y`\xff\xff\xff\xff\xf5Oxp" +
-	"\xff\xff\xff\xff\xf6?[`\xff\xff\xff\xff\xf7/Zp\xff\xff\xff\xff\xf8(w\xe0\xff\xff\xff\xff\xf9\x0f<p\xff\xff\xff\xff\xfa\bY\xe0\xff\xff\xff\xff\xfa\xf8X\xf0\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff" +
-	"\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`" +
-	"\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\a0\xc2`\x00\x00\x00\x00\b \xc1p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\n\x00\xa3p\x00\x00\x00\x00" +
-	"\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00\f٢\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0" +
-	"\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00" +
-	"\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x00\x00\x00\x00\x1a\xf2\np\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`" +
-	"\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\"U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00" +
-	"'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\nU\xe0\x00\x00\x00\x00)ޥp\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip" +
-	"\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x00" +
-	"5'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\a\r\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0" +
-	"\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00" +
-	"Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xb5\x94\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\f\xff\xff\xc7\xc0\x01\x10LMT\x00EDT\x00ES" +
-	"T\x00EWT\x00EPT\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTԾ\xe7#\x95\x00\x00\x00\x95\x00\x00\x00" +
-	"\x0e\x00\x1c\x00America/PanamaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xffi\x87&\x10\xff\xff\xff\xff\x8b\xf4a\xe8\x01\x02\xff\xff\xb5p\x00\x00\xff\xff\xb5\x18\x00\x04\xff\xff\xb9\xb0\x00\bLMT" +
-	"\x00CMT\x00EST\x00\nEST5\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xef\xf0R\x8a\xc4\x02\x00\x00\xc4\x02\x00\x00\x0f\x00\x1c\x00America/Cordoba" +
-	"UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x06\x00" +
-	"\x00\x00\x14\xff\xff\xff\xffr\x9c\xad\xb0\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff" +
-	"\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1" +
-	"\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff" +
-	"\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4" +
-	"=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff" +
-	"\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b" +
-	"$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xff@\x00" +
-	"\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x00\x00\x00\x00H" +
-	"\xfa\xa2\xb0\x00\x00\x00\x00I\xbca \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05" +
-	"\x04\x02\x04\x05\x04\x05\x03\x05\x04\x05\x04\x05\xff\xff\xc3\xd0\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00" +
-	"-03\x00-02\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xdf\xe5\x8d\xc4\xda\x04\x00\x00\xda\x04\x00\x00\x12\x00\x1c\x00America/Louisv" +
-	"illeUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00u\x00" +
-	"\x00\x00\a\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xa4s\xf7\x00\xff\xff\xff\xff\xa5" +
-	"\x16\x11p\xff\xff\xff\xff\xca\rN\x80\xff\xff\xff\xff\xca\xd8Gp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd3u\xd7\x1c\xff\xff\xff\xffӤ\tp\xff" +
-	"\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90p\xff\xff\xff\xff\u07bey\x80\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1" +
-	"iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5)\x18p\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe77\x1e\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff" +
-	"\xff\xff\xff\xe9\x17\x00\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea\xf6\xe2\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xd6\xc4\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\xee\xbf\xe1p\xff\xff\xff\xff\xef" +
-	"\xaf\xe0\x80\xff\xff\xff\xff\xf0\x1e\x90p\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00" +
-	"\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\a0\xc2`\x00\x00\x00\x00\a\x8d\x19p\x00\x00\x00\x00\t" +
-	"\x10\xb2p\x00\x00\x00\x00\t\xad\x94\xf0\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00\f٢\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00" +
-	"\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17" +
-	")\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x00\x00\x00\x00\x1a\xf2\np\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00" +
-	"\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\"U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%" +
-	"J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\nU\xe0\x00\x00\x00\x00)ޥp\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00" +
-	"\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003" +
-	"GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\a\r\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00" +
-	"\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A" +
-	"\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x01\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" +
-	"\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xaf\x9a\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff" +
-	"\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00EDT\x00\nEST5EDT,M" +
-	"3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xd0v\x01\x8a\x01\x04\x00\x00\x01\x04\x00\x00\x10\x00\x1c\x00America/Ensenada" +
-	"UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00^\x00\x00\x00\x06\x00" +
-	"\x00\x00\x18\xff\xff\xff\xff\xa5\xb6\xf6\x80\xff\xff\xff\xff\xa9yOp\xff\xff\xff\xff\xaf\xf2|\xf0\xff\xff\xff\xff\xb6fdp\xff\xff\xff\xff\xb7\x1b\x10\x00\xff\xff\xff\xff\xb8\n\xf2\xf0\xff\xff\xff\xff\xcbꍀ\xff" +
-	"\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xffҙ\xbap\xff\xff\xff\xff\xd7\x1bY\x00\xff\xff\xff\xffؑ\xb4\xf0\xff\xff\xff\xff\xe2~K\x90\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4^-\x90\xff\xff\xff\xff\xe5" +
-	")4\x90\xff\xff\xff\xff\xe6GJ\x10\xff\xff\xff\xff\xe7\x12Q\x10\xff\xff\xff\xff\xe8',\x10\xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff\xff\xea\a\x0e\x10\xff\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff\xff\xeb\xe6\xf0\x10\xff" +
-	"\xff\xff\xff\xec\xb1\xf7\x10\xff\xff\xff\xff\xed\xc6\xd2\x10\xff\xff\xff\xff\xee\x91\xd9\x10\x00\x00\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f" +
-	"\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00" +
-	"\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d" +
-	"\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1ې\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\"V\r \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00" +
-	"\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\n\x80\x10\x00\x00\x00\x00)\xdeϠ\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+" +
-	"\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00" +
-	"\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\a8 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009" +
-	"\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00" +
-	"\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00F\x0f\x82\xa0\x00\x00\x00\x00G$O\x90\x00\x00\x00\x00G" +
-	"\xf8\x9f \x00\x00\x00\x00I\x041\x90\x00\x00\x00\x00I\u0601 \x00\x00\x00\x00J\xe4\x13\x90\x00\x00\x00\x00K\x9c\xb3\xa0\x01\x02\x01\x02\x03\x02\x04\x05\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\x92L\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\x8f\x80\x00\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10\xff\xff\x9d\x90\x01\x14LMT\x00MST\x00PST\x00PDT" +
-	"\x00PWT\x00PPT\x00\nPST8PDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTV\x80\x94@\x12\x04\x00\x00\x12\x04\x00\x00\x10" +
-	"\x00\x1c\x00America/ShiprockUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff^\x04\f\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a" +
-	"\xe9\x80\xff\xff\xff\xff\xa2e\xfe\x90\xff\xff\xff\xff\xa3\x84\x06\x00\xff\xff\xff\xff\xa4E\xe0\x90\xff\xff\xff\xff\xa4\x8f\xa6\x80\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff" +
-	"\xff\xff\xf7/v\x90\xff\xff\xff\xff\xf8(\x94\x00\xff\xff\xff\xff\xf9\x0fX\x90\xff\xff\xff\xff\xfa\bv\x00\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W\x10\xff\xff\xff\xff\xfd\xc8" +
-	":\x00\xff\xff\xff\xff\xfe\xb89\x10\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x1b\x10\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xfd\x10\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\x19\x90\x00\x00" +
-	"\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\a\x8d5\x90\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\t\xad\xb1\x10\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\v\xe0" +
-	"\xa1\x90\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00" +
-	"\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00\x00\x1a\x02" +
-	"'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x1d\x10\x00\x00" +
-	"\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfe" +
-	"ߐ\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00" +
-	"\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062" +
-	"ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00" +
-	"\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/" +
-	"\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\x9d\x94\x00" +
-	"\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10LMT\x00MDT\x00MST\x00MWT\x00MPT\x00\nMST7MDT,M3.2.0" +
-	",M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT$\r\x89l\xe4\x01\x00\x00\xe4\x01\x00\x00\x0f\x00\x1c\x00America/OjinagaUT\t\x00\x03\xdd" +
-	"\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00#\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff" +
-	"\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6fV`\xff\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff\xb8\f6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\b" +
-	"p\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00" +
-	"\x009\xfb\xd9\x00\x00\x00\x00\x00:\xf5\x12\x90\x00\x00\x00\x00;\xb6\xd1\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@o\xce" +
-	"\x90\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00F\x0ft\x90\x00\x00\x00\x00G$A\x80\x00\x00\x00" +
-	"\x00G\xf8\x91\x10\x00\x00\x00\x00I\x04#\x80\x00\x00\x00\x00I\xd8s\x10\x00\x00\x00\x00J\xe4\x05\x80\x00\x00\x00\x00K\x9c\xa5\x90\x01\x02\x01\x02\x01\x02\x03\x02\x03\x02\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04" +
-	"\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\xff\xff\x9e\x1c\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xab\xa0\x01\x10LMT\x00MST\x00CST\x00CDT\x00MD" +
-	"T\x00\nMST7MDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTU\r\xf7\xd3\xc7\x01\x00\x00\xc7\x01\x00\x00\r\x00\x1c\x00Amer" +
-	"ica/ThuleUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\"\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x9b\x80w\xfc\x00\x00\x00\x00'\xf5z\xe0\x00\x00\x00\x00(\xe5]\xd0\x00\x00\x00\x00)\xd5\\\xe0\x00\x00\x00\x00*\xc5?\xd0\x00\x00\x00\x00+\xbey`" +
-	"\x00\x00\x00\x00,\xd3FP\x00\x00\x00\x00-\x9e[`\x00\x00\x00\x00.\xb3(P\x00\x00\x00\x00/~=`\x00\x00\x00\x000\x93\nP\x00\x00\x00\x001gY\xe0\x00\x00\x00\x002r\xecP\x00\x00\x00\x00" +
-	"3G;\xe0\x00\x00\x00\x004R\xceP\x00\x00\x00\x005'\x1d\xe0\x00\x00\x00\x0062\xb0P\x00\x00\x00\x007\x06\xff\xe0\x00\x00\x00\x008\x1b\xcc\xd0\x00\x00\x00\x008\xe6\xe1\xe0\x00\x00\x00\x009\xfb\xae\xd0" +
-	"\x00\x00\x00\x00:\xc6\xc3\xe0\x00\x00\x00\x00;ې\xd0\x00\x00\x00\x00<\xaf\xe0`\x00\x00\x00\x00=\xbbr\xd0\x00\x00\x00\x00>\x8f\xc2`\x00\x00\x00\x00?\x9bT\xd0\x00\x00\x00\x00@o\xa4`\x00\x00\x00\x00" +
-	"A\x84qP\x00\x00\x00\x00BO\x86`\x00\x00\x00\x00CdSP\x00\x00\x00\x00D/h`\x00\x00\x00\x00ED5P\x00\x00\x00\x00E\xf3\x9a\xe0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xbf\x84\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\bLMT\x00ADT\x00AST\x00\nAST4ADT,M3." +
-	"2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xac\x8e\xee\x13\xbe\x00\x00\x00\xbe\x00\x00\x00\x0f\x00\x1c\x00America/CaracasUT\t" +
-	"\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x00\x12" +
-	"\xff\xff\xff\xffi\x87\x1a@\xff\xff\xff\xff\x93\x1e,<\xff\xff\xff\xff\xf6\x98\xecH\x00\x00\x00\x00G[\x92p\x00\x00\x00\x00W%\xa9p\x01\x02\x03\x02\x03\xff\xff\xc1@\x00\x00\xff\xff\xc1D\x00\x04\xff\xff\xc0" +
-	"\xb8\x00\b\xff\xff\xc7\xc0\x00\x0eLMT\x00CMT\x00-0430\x00-04\x00\n<-04>4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT<\x01V\rP\x02\x00\x00P\x02\x00" +
-	"\x00\x11\x00\x1c\x00America/AraguainaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaat0\xff\xff\xff\xff\xb8\x0fI\xe0\xff\xff\xff\xff\xb8\xfd@\xa0\xff\xff\xff\xff\xb9\xf140\xff\xff\xff" +
-	"\xff\xba\xdet \xff\xff\xff\xff\xda8\xae0\xff\xff\xff\xff\xda\xeb\xfa0\xff\xff\xff\xff\xdc\x19\xe1\xb0\xff\xff\xff\xffܹY \xff\xff\xff\xff\xdd\xfb\x150\xff\xff\xff\xffޛ\xde \xff\xff\xff\xff\xdfݚ" +
-	"0\xff\xff\xff\xff\xe0T3 \xff\xff\xff\xff\xf4\x97\xff\xb0\xff\xff\xff\xff\xf5\x05^ \xff\xff\xff\xff\xf6\xc0d0\xff\xff\xff\xff\xf7\x0e\x1e\xa0\xff\xff\xff\xff\xf8Q,0\xff\xff\xff\xff\xf8\xc7\xc5 \xff\xff\xff" +
-	"\xff\xfa\nҰ\xff\xff\xff\xff\xfa\xa8\xf8\xa0\xff\xff\xff\xff\xfb\xec\x060\xff\xff\xff\xff\xfc\x8b}\xa0\x00\x00\x00\x00\x1dɎ0\x00\x00\x00\x00\x1exנ\x00\x00\x00\x00\x1f\xa05\xb0\x00\x00\x00\x00 3\xcf" +
-	"\xa0\x00\x00\x00\x00!\x81i0\x00\x00\x00\x00\"\vȠ\x00\x00\x00\x00#X\x10\xb0\x00\x00\x00\x00#\xe2p \x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xd4\xc7 \x00\x00\x00\x000\x80y0\x00\x00\x00" +
-	"\x001\x1dM\xa0\x00\x00\x00\x002W \xb0\x00\x00\x00\x003\x06j \x00\x00\x00\x0048T0\x00\x00\x00\x004\xf8\xc1 \x00\x00\x00\x006 \x1f0\x00\x00\x00\x006\xcfh\xa0\x00\x00\x00\x007\xf6\xc6" +
-	"\xb0\x00\x00\x00\x008\xb8\x85 \x00\x00\x00\x009\xdf\xe30\x00\x00\x00\x00:\x8f,\xa0\x00\x00\x00\x00;\xc8\xff\xb0\x00\x00\x00\x00<o\x0e\xa0\x00\x00\x00\x00=đ0\x00\x00\x00\x00>N\xf0\xa0\x00\x00\x00" +
-	"\x00P\x83e0\x00\x00\x00\x00Q 9\xa0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\xff\xff\xd2\xd0\x00\x00\xff\xff\xe3\xe0\x01\x04\xff\xff\xd5\xd0\x00\bLMT\x00-02\x00-03\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x1d`̟" +
-	"\x00\x03\x00\x00\x00\x03\x00\x00\x15\x00\x1c\x00America/Cambridge_BayUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01" +
-	"\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x00\x00\x00\t\x00\x00\x00%\xff\xff\xff\xff\xa1\xf2̀\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p" +
-	"\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xf7/Zp\xff\xff\xff\xff\xf8(\x85\xf0\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00" +
-	"\x17)(\x10\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80" +
-	"\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00" +
-	"%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeߐ\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90" +
-	"\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x00" +
-	"3Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0" +
-	"\x00\x00\x00\x00:\x04\xe9P\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00" +
-	"@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x03\x01\x02\x03\x04\x03\x05\x03" +
-	"\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\a\x06\b\a\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x00\x00\x00\x00\x00\x00" +
-	"\xff\xff\xab\xa0\x01\x04\xff\xff\xab\xa0\x01\b\xff\xff\x9d\x90\x00\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xab\xa0\x01\x15\xff\xff\xb9\xb0\x01\x19\xff\xff\xab\xa0\x00\x1d\xff\xff\xb9\xb0\x00!-00\x00MWT\x00MPT\x00" +
-	"MST\x00MDDT\x00MDT\x00CDT\x00CST\x00EST\x00\nMST7MDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8f" +
-	"j\xbeT?_p\x99\x0e\x05\x00\x00\x0e\x05\x00\x00\x10\x00\x1c\x00America/WinnipegUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S" +
-	"_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00}\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xffd䰔\xff\xff\xff\xff\x9b\x01\xfb\xe0\xff\xff\xff\xff\x9b\xc3" +
-	"\xbaP\xff\xff\xff\xff\x9e\xb8\xa1\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\u00a0;\x80\xff\xff\xff\xff\xc3O\x84\xf0\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff" +
-	"\xff\xffӈh\x00\xff\xff\xff\xff\xd4S`\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0" +
-	"\x91\xf0\xff\xff\xff\xff\xdb\x00\a\x00\xff\xff\xff\xff\xdb\xc8\\\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90p\xff\xff\xff\xff\u07bey\x80\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff" +
-	"\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5)\x18p\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe7\x124\xf0\xff\xff\xff\xff\xe8'" +
-	"\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xd6\xc4\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\ue47c\xf0\xff\xff" +
-	"\xff\xff\xf3o\xa4\x80\xff\xff\xff\xff\xf41b\xf0\xff\xff\xff\xff\xf9\x0fJ\x80\xff\xff\xff\xff\xfa\bv\x00\xff\xff\xff\xff\xfa\xf8g\x00\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8" +
-	":\x00\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\r\x00\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\v\x80\x00\x00" +
-	"\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\b π\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\n\x00\xb1\x80\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\v\xe0" +
-	"\x93\x80\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12ye\x00\x00\x00" +
-	"\x00\x00\x13iV\x00\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02" +
-	"'\x80\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1܀\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x0f\x00\x00\x00" +
-	"\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfe" +
-	"р\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\u07b3\x80\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3R\x80\x00\x00" +
-	"\x00\x00/~Y\x80\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005':\x00\x00\x00\x00\x0062" +
-	"ڀ\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00" +
-	"\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/" +
-	"\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xa4\xec\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10LMT\x00CDT" +
-	"\x00CST\x00CWT\x00CPT\x00\nCST6CDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe3\xc9I\xd0U\x03\x00\x00U" +
-	"\x03\x00\x00\x12\x00\x1c\x00America/Grand_TurkUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00L\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xffi\x87\x1e0\xff\xff\xff\xff\x93\x0f\xb4\xfe\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0" +
-	"\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00" +
-	"\x1a\x02\v`\x00\x00\x00\x00\x1a\xf2\np\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0" +
-	"\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\"U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00" +
-	"'\xfe\xc3p\x00\x00\x00\x00)\nU\xe0\x00\x00\x00\x00)ޥp\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`" +
-	"\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x00" +
-	"62\xbe`\x00\x00\x00\x007\a\r\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep" +
-	"\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00" +
-	"D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x00\x00\x00\x00G-_\xe0\x00\x00\x00\x00Gӊ\xf0\x00\x00\x00\x00I\rA\xe0\x00\x00\x00\x00I\xb3l\xf0\x00\x00\x00\x00J\xed#\xe0" +
-	"\x00\x00\x00\x00K\x9c\x89p\x00\x00\x00\x00L\xd6@`\x00\x00\x00\x00M|kp\x00\x00\x00\x00N\xb6\"`\x00\x00\x00\x00O\\Mp\x00\x00\x00\x00P\x96\x04`\x00\x00\x00\x00Q</p\x00\x00\x00\x00" +
-	"Ru\xe6`\x00\x00\x00\x00S\x1c\x11p\x00\x00\x00\x00TU\xc8`\x00\x00\x00\x00T\xfb\xf3p\x00\x00\x00\x00Z\xa4\xd3\xf0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x03\xff\xff\xbdP\x00\x00\xff\xff" +
-	"\xb8\x02\x00\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\f\xff\xff\xc7\xc0\x00\x10LMT\x00KMT\x00EST\x00EDT\x00AST\x00\nEST5EDT,M3.2.0,M1" +
-	"1.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTq\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0e\x00\x1c\x00America/VirginUT\t\x00\x03\xdd\xfc\x94b\xdd" +
-	"\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00" +
-	"\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz\xe6\x95" +
-	"\xb9\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST" +
-	"\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT5\x11Q\x06\xd1\x03\x00\x00\xd1\x03\x00\x00\x11\x00\x1c\x00America/Anchora" +
-	"geUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00T\x00\x00\x00" +
-	"\n\x00\x00\x00(\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}\x87AH\xff\xff\xff\xffˉ6\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2aB0\xff\xff\xff\xff\xfa\xd2G\xa0\xff\xff\xff\xff\xfe\xb8c" +
-	"@\xff\xff\xff\xff\xff\xa8F0\x00\x00\x00\x00\x00\x98E@\x00\x00\x00\x00\x01\x88(0\x00\x00\x00\x00\x02x'@\x00\x00\x00\x00\x03qD\xb0\x00\x00\x00\x00\x04aC\xc0\x00\x00\x00\x00\x05Q&\xb0\x00\x00\x00" +
-	"\x00\x06A%\xc0\x00\x00\x00\x00\a1\b\xb0\x00\x00\x00\x00\a\x8d_\xc0\x00\x00\x00\x00\t\x10\xea\xb0\x00\x00\x00\x00\t\xad\xdb@\x00\x00\x00\x00\n\xf0̰\x00\x00\x00\x00\v\xe0\xcb\xc0\x00\x00\x00\x00\f\xd9\xe9" +
-	"0\x00\x00\x00\x00\r\xc0\xad\xc0\x00\x00\x00\x00\x0e\xb9\xcb0\x00\x00\x00\x00\x0f\xa9\xca@\x00\x00\x00\x00\x10\x99\xad0\x00\x00\x00\x00\x11\x89\xac@\x00\x00\x00\x00\x12y\x8f0\x00\x00\x00\x00\x13i\x8e@\x00\x00\x00" +
-	"\x00\x14Yq0\x00\x00\x00\x00\x15Ip@\x00\x00\x00\x00\x169S0\x00\x00\x00\x00\x17)R@\x00\x00\x00\x00\x18\"o\xb0\x00\x00\x00\x00\x19\t4@\x00\x00\x00\x00\x1a\x02Q\xb0\x00\x00\x00\x00\x1a+\x14" +
-	"\x10\x00\x00\x00\x00\x1a\xf2B\xb0\x00\x00\x00\x00\x1b\xe2%\xa0\x00\x00\x00\x00\x1c\xd2$\xb0\x00\x00\x00\x00\x1d\xc2\a\xa0\x00\x00\x00\x00\x1e\xb2\x06\xb0\x00\x00\x00\x00\x1f\xa1\xe9\xa0\x00\x00\x00\x00 v90\x00\x00\x00" +
-	"\x00!\x81ˠ\x00\x00\x00\x00\"V\x1b0\x00\x00\x00\x00#j\xe8 \x00\x00\x00\x00$5\xfd0\x00\x00\x00\x00%J\xca \x00\x00\x00\x00&\x15\xdf0\x00\x00\x00\x00'*\xac \x00\x00\x00\x00'\xfe\xfb" +
-	"\xb0\x00\x00\x00\x00)\n\x8e \x00\x00\x00\x00)\xdeݰ\x00\x00\x00\x00*\xeap \x00\x00\x00\x00+\xbe\xbf\xb0\x00\x00\x00\x00,ӌ\xa0\x00\x00\x00\x00-\x9e\xa1\xb0\x00\x00\x00\x00.\xb3n\xa0\x00\x00\x00" +
-	"\x00/~\x83\xb0\x00\x00\x00\x000\x93P\xa0\x00\x00\x00\x001g\xa00\x00\x00\x00\x002s2\xa0\x00\x00\x00\x003G\x820\x00\x00\x00\x004S\x14\xa0\x00\x00\x00\x005'd0\x00\x00\x00\x0062\xf6" +
-	"\xa0\x00\x00\x00\x007\aF0\x00\x00\x00\x008\x1c\x13 \x00\x00\x00\x008\xe7(0\x00\x00\x00\x009\xfb\xf5 \x00\x00\x00\x00:\xc7\n0\x00\x00\x00\x00;\xdb\xd7 \x00\x00\x00\x00<\xb0&\xb0\x00\x00\x00" +
-	"\x00=\xbb\xb9 \x00\x00\x00\x00>\x90\b\xb0\x00\x00\x00\x00?\x9b\x9b \x00\x00\x00\x00@o\xea\xb0\x00\x00\x00\x00A\x84\xb7\xa0\x00\x00\x00\x00BO̰\x00\x00\x00\x00Cd\x99\xa0\x00\x00\x00\x00D/\xae" +
-	"\xb0\x00\x00\x00\x00ED{\xa0\x00\x00\x00\x00E\xf3\xe10\x01\x02\x03\x04\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\a\t\b\t\b\t\b\t" +
-	"\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\x00\x00\xc4\xf8\x00\x00\xff\xffsx\x00\x00\xff\xffs`\x00\x04\xff" +
-	"\xff\x81p\x01\b\xff\xff\x81p\x01\f\xff\xffs`\x00\x10\xff\xff\x81p\x01\x15\xff\xff\x81p\x00\x1a\xff\xff\x8f\x80\x01\x1e\xff\xff\x81p\x00#LMT\x00AST\x00AWT\x00APT\x00AHS" +
-	"T\x00AHDT\x00YST\x00AKDT\x00AKST\x00\nAKST9AKDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbe" +
-	"T\xb1݂x\xe8\x00\x00\x00\xe8\x00\x00\x00\x12\x00\x1c\x00America/Costa_RicaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S" +
-	"_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xffi\x87*M\xff\xff\xff\xff\xa3\xe8\x16M\x00\x00\x00\x00\x116" +
-	"I`\x00\x00\x00\x00\x11\xb7nP\x00\x00\x00\x00\x13\x16+`\x00\x00\x00\x00\x13\x97PP\x00\x00\x00\x00'\x97\xe0`\x00\x00\x00\x00(n\xb6\xd0\x00\x00\x00\x00)w\xc2`\x00\x00\x00\x00)\xc2\xd9\xd0\x01\x03" +
-	"\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\xb13\x00\x00\xff\xff\xb13\x00\x04\xff\xff\xb9\xb0\x01\t\xff\xff\xab\xa0\x00\rLMT\x00SJMT\x00CDT\x00CST\x00\nCST6\nPK\x03\x04\n" +
-	"\x00\x00\x00\x00\x00\x8fj\xbeTn\xab\xd5\xf9\xcf\x03\x00\x00\xcf\x03\x00\x00\f\x00\x1c\x00America/NomeUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00" +
-	"\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif" +
-	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00T\x00\x00\x00\n\x00\x00\x00&\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}\x87O\xd2\xff\xff\xff\xff" +
-	"ˉD\xd0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2aP@\xff\xff\xff\xff\xfa\xd2U\xb0\xff\xff\xff\xff\xfe\xb8qP\xff\xff\xff\xff\xff\xa8T@\x00\x00\x00\x00\x00\x98SP\x00\x00\x00\x00\x01\x886@" +
-	"\x00\x00\x00\x00\x02x5P\x00\x00\x00\x00\x03qR\xc0\x00\x00\x00\x00\x04aQ\xd0\x00\x00\x00\x00\x05Q4\xc0\x00\x00\x00\x00\x06A3\xd0\x00\x00\x00\x00\a1\x16\xc0\x00\x00\x00\x00\a\x8dm\xd0\x00\x00\x00\x00" +
-	"\t\x10\xf8\xc0\x00\x00\x00\x00\t\xad\xe9P\x00\x00\x00\x00\n\xf0\xda\xc0\x00\x00\x00\x00\v\xe0\xd9\xd0\x00\x00\x00\x00\f\xd9\xf7@\x00\x00\x00\x00\r\xc0\xbb\xd0\x00\x00\x00\x00\x0e\xb9\xd9@\x00\x00\x00\x00\x0f\xa9\xd8P" +
-	"\x00\x00\x00\x00\x10\x99\xbb@\x00\x00\x00\x00\x11\x89\xbaP\x00\x00\x00\x00\x12y\x9d@\x00\x00\x00\x00\x13i\x9cP\x00\x00\x00\x00\x14Y\x7f@\x00\x00\x00\x00\x15I~P\x00\x00\x00\x00\x169a@\x00\x00\x00\x00" +
-	"\x17)`P\x00\x00\x00\x00\x18\"}\xc0\x00\x00\x00\x00\x19\tBP\x00\x00\x00\x00\x1a\x02_\xc0\x00\x00\x00\x00\x1a+\x14\x10\x00\x00\x00\x00\x1a\xf2B\xb0\x00\x00\x00\x00\x1b\xe2%\xa0\x00\x00\x00\x00\x1c\xd2$\xb0" +
-	"\x00\x00\x00\x00\x1d\xc2\a\xa0\x00\x00\x00\x00\x1e\xb2\x06\xb0\x00\x00\x00\x00\x1f\xa1\xe9\xa0\x00\x00\x00\x00 v90\x00\x00\x00\x00!\x81ˠ\x00\x00\x00\x00\"V\x1b0\x00\x00\x00\x00#j\xe8 \x00\x00\x00\x00" +
-	"$5\xfd0\x00\x00\x00\x00%J\xca \x00\x00\x00\x00&\x15\xdf0\x00\x00\x00\x00'*\xac \x00\x00\x00\x00'\xfe\xfb\xb0\x00\x00\x00\x00)\n\x8e \x00\x00\x00\x00)\xdeݰ\x00\x00\x00\x00*\xeap " +
-	"\x00\x00\x00\x00+\xbe\xbf\xb0\x00\x00\x00\x00,ӌ\xa0\x00\x00\x00\x00-\x9e\xa1\xb0\x00\x00\x00\x00.\xb3n\xa0\x00\x00\x00\x00/~\x83\xb0\x00\x00\x00\x000\x93P\xa0\x00\x00\x00\x001g\xa00\x00\x00\x00\x00" +
-	"2s2\xa0\x00\x00\x00\x003G\x820\x00\x00\x00\x004S\x14\xa0\x00\x00\x00\x005'd0\x00\x00\x00\x0062\xf6\xa0\x00\x00\x00\x007\aF0\x00\x00\x00\x008\x1c\x13 \x00\x00\x00\x008\xe7(0" +
-	"\x00\x00\x00\x009\xfb\xf5 \x00\x00\x00\x00:\xc7\n0\x00\x00\x00\x00;\xdb\xd7 \x00\x00\x00\x00<\xb0&\xb0\x00\x00\x00\x00=\xbb\xb9 \x00\x00\x00\x00>\x90\b\xb0\x00\x00\x00\x00?\x9b\x9b \x00\x00\x00\x00" +
-	"@o\xea\xb0\x00\x00\x00\x00A\x84\xb7\xa0\x00\x00\x00\x00BO̰\x00\x00\x00\x00Cd\x99\xa0\x00\x00\x00\x00D/\xae\xb0\x00\x00\x00\x00ED{\xa0\x00\x00\x00\x00E\xf3\xe10\x01\x02\x03\x04\x02\x05\x06\x05" +
-	"\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\a\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b" +
-	"\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\x00\x00\xb6n\x00\x00\xff\xffd\xee\x00\x00\xff\xffeP\x00\x04\xff\xffs`\x01\b\xff\xffs`\x01\f\xff\xffeP\x00\x10\xff\xffs`\x01\x14\xff\xff" +
-	"\x81p\x00\x18\xff\xff\x8f\x80\x01\x1c\xff\xff\x81p\x00!LMT\x00NST\x00NWT\x00NPT\x00BST\x00BDT\x00YST\x00AKDT\x00AKST\x00\nAKST9" +
-	"AKDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTq\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0f\x00\x1c\x00America/Gr" +
-	"enadaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04" +
-	"\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0" +
-	"\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT~\xb2\x0e\x19V\a\x00\x00V\a\x00\x00\x10\x00\x1c\x00" +
-	"America/St_JohnsUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbb\x00\x00\x00\b\x00\x00\x00\x19\xff\xff\xff\xff^=4\xec\xff\xff\xff\xff\x9c\xcfb\f\xff\xff\xff\xff\x9d\xa4\xe6\xfc\xff\xff\xff\xff\x9e\xb8~\x8c\xff\xff\xff\xff\x9f\xba\xd6|\xff" +
-	"\xff\xff\xff\xa0\xb6\x88\xdc\xff\xff\xff\xff\xa18\xffL\xff\xff\xff\xff\xa2\x95\x19\\\xff\xff\xff\xff\xa3\x84\xfcL\xff\xff\xff\xff\xa4t\xfb\\\xff\xff\xff\xff\xa5d\xdeL\xff\xff\xff\xff\xa6^\x17\xdc\xff\xff\xff\xff\xa7" +
-	"D\xc0L\xff\xff\xff\xff\xa8=\xf9\xdc\xff\xff\xff\xff\xa9$\xa2L\xff\xff\xff\xff\xaa\x1d\xdb\xdc\xff\xff\xff\xff\xab\x04\x84L\xff\xff\xff\xff\xab\xfd\xbd\xdc\xff\xff\xff\xff\xac\xe4fL\xff\xff\xff\xff\xadݟ\xdc\xff" +
-	"\xff\xff\xff\xae͂\xcc\xff\xff\xff\xff\xaf\xbd\x81\xdc\xff\xff\xff\xff\xb0\xadd\xcc\xff\xff\xff\xff\xb1\xa6\x9e\\\xff\xff\xff\xff\xb2\x8dF\xcc\xff\xff\xff\xff\xb3\x86\x80\\\xff\xff\xff\xff\xb4m(\xcc\xff\xff\xff\xff\xb5" +
-	"fb\\\xff\xff\xff\xff\xb6M\n\xcc\xff\xff\xff\xff\xb7FD\\\xff\xff\xff\xff\xb8,\xec\xcc\xff\xff\xff\xff\xb9&&\\\xff\xff\xff\xff\xba\x16\tL\xff\xff\xff\xff\xbb\x0fB\xdc\xff\xff\xff\xff\xbb\xf5\xebL\xff" +
-	"\xff\xff\xff\xbc\xef$\xdc\xff\xff\xff\xff\xbd\xd5\xcdL\xff\xff\xff\xff\xbe\x9eMl\xff\xff\xff\xff\xbe\xcf\x06\xa8\xff\xff\xff\xff\xbf\xb5\xaf\x18\xff\xff\xff\xff\xc0\xb818\xff\xff\xff\xff\xc1y\xef\xa8\xff\xff\xff\xff\xc2" +
-	"\x98\x138\xff\xff\xff\xff\xc3YѨ\xff\xff\xff\xff\xc4w\xf58\xff\xff\xff\xff\xc59\xb3\xa8\xff\xff\xff\xff\xc6a\x11\xb8\xff\xff\xff\xff\xc7\x19\x95\xa8\xff\xff\xff\xff\xc8@\xf3\xb8\xff\xff\xff\xff\xc9\x02\xb2(\xff" +
-	"\xff\xff\xff\xca ո\xff\xff\xff\xff\xca\xe2\x94(\xff\xff\xff\xff\xcc\x00\xb7\xb8\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xe6\xc8\xff\xff\xff\xffӈD\xd8\xff\xff\xff\xff\xd4J\x03H\xff\xff\xff\xff\xd5" +
-	"h&\xd8\xff\xff\xff\xff\xd6)\xe5H\xff\xff\xff\xff\xd7H\b\xd8\xff\xff\xff\xff\xd8\t\xc7H\xff\xff\xff\xff\xd9'\xea\xd8\xff\xff\xff\xff\xd9\xe9\xa9H\xff\xff\xff\xff\xdb\x11\aX\xff\xff\xff\xff\xdb\xd2\xc5\xc8\xff" +
-	"\xff\xff\xff\xdc\xdetX\xff\xff\xff\xffݩmH\xff\xff\xff\xff\u07beVX\xff\xff\xff\xff߉OH\xff\xff\xff\xff\xe0\x9e8X\xff\xff\xff\xff\xe1i1H\xff\xff\xff\xff\xe2~\x1aX\xff\xff\xff\xff\xe3" +
-	"I\x13H\xff\xff\xff\xff\xe4]\xfcX\xff\xff\xff\xff\xe5(\xf5H\xff\xff\xff\xff\xe6G\x18\xd8\xff\xff\xff\xff\xe7\x12\x11\xc8\xff\xff\xff\xff\xe8&\xfa\xd8\xff\xff\xff\xff\xe8\xf1\xf3\xc8\xff\xff\xff\xff\xea\x06\xdc\xd8\xff" +
-	"\xff\xff\xff\xea\xd1\xd5\xc8\xff\xff\xff\xff\xeb\xe6\xbe\xd8\xff\xff\xff\xff챷\xc8\xff\xff\xff\xff\xedƠ\xd8\xff\xff\xff\xff\ueffeH\xff\xff\xff\xffﯽX\xff\xff\xff\xff\xf0\x9f\xa0H\xff\xff\xff\xff\xf1" +
-	"\x8f\x9fX\xff\xff\xff\xff\xf2\x7f\x82H\xff\xff\xff\xff\xf3o\x81X\xff\xff\xff\xff\xf4_dH\xff\xff\xff\xff\xf5OcX\xff\xff\xff\xff\xf6?FH\xff\xff\xff\xff\xf7/EX\xff\xff\xff\xff\xf8(b\xc8\xff" +
-	"\xff\xff\xff\xf9\x0f'X\xff\xff\xff\xff\xfa\bD\xc8\xff\xff\xff\xff\xfa\xf8C\xd8\xff\xff\xff\xff\xfb\xe8&\xc8\xff\xff\xff\xff\xfc\xd8%\xd8\xff\xff\xff\xff\xfd\xc8\b\xc8\xff\xff\xff\xff\xfe\xb8\a\xd8\xff\xff\xff\xff\xff" +
-	"\xa7\xea\xc8\x00\x00\x00\x00\x00\x97\xe9\xd8\x00\x00\x00\x00\x01\x87\xcc\xc8\x00\x00\x00\x00\x02w\xcb\xd8\x00\x00\x00\x00\x03p\xe9H\x00\x00\x00\x00\x04`\xe8X\x00\x00\x00\x00\x05P\xcbH\x00\x00\x00\x00\x06@\xcaX\x00" +
-	"\x00\x00\x00\a0\xadH\x00\x00\x00\x00\b \xacX\x00\x00\x00\x00\t\x10\x8fH\x00\x00\x00\x00\n\x00\x8eX\x00\x00\x00\x00\n\xf0qH\x00\x00\x00\x00\v\xe0pX\x00\x00\x00\x00\fٍ\xc8\x00\x00\x00\x00\r" +
-	"\xc0RX\x00\x00\x00\x00\x0e\xb9o\xc8\x00\x00\x00\x00\x0f\xa9n\xd8\x00\x00\x00\x00\x10\x99Q\xc8\x00\x00\x00\x00\x11\x89P\xd8\x00\x00\x00\x00\x12y3\xc8\x00\x00\x00\x00\x13i2\xd8\x00\x00\x00\x00\x14Y\x15\xc8\x00" +
-	"\x00\x00\x00\x15I\x14\xd8\x00\x00\x00\x00\x168\xf7\xc8\x00\x00\x00\x00\x17(\xf6\xd8\x00\x00\x00\x00\x18\"\x14H\x00\x00\x00\x00\x19\b\xd8\xd8\x00\x00\x00\x00\x1a\x01\xf6H\x00\x00\x00\x00\x1a\xf1\xf5X\x00\x00\x00\x00\x1b" +
-	"\xe1\xd8H\x00\x00\x00\x00\x1c\xd1\xd7X\x00\x00\x00\x00\x1d\xc1\xbaH\x00\x00\x00\x00\x1e\xb1\xb9X\x00\x00\x00\x00\x1f\xa1\x9cH\x00\x00\x00\x00 u\xcf\xf4\x00\x00\x00\x00!\x81bd\x00\x00\x00\x00\"U\xb1\xf4\x00" +
-	"\x00\x00\x00#jp\xd4\x00\x00\x00\x00$5\x93\xf4\x00\x00\x00\x00%J`\xe4\x00\x00\x00\x00&\x15u\xf4\x00\x00\x00\x00'*B\xe4\x00\x00\x00\x00'\xfe\x92t\x00\x00\x00\x00)\n$\xe4\x00\x00\x00\x00)" +
-	"\xdett\x00\x00\x00\x00*\xea\x06\xe4\x00\x00\x00\x00+\xbeVt\x00\x00\x00\x00,\xd3#d\x00\x00\x00\x00-\x9e8t\x00\x00\x00\x00.\xb3\x05d\x00\x00\x00\x00/~\x1at\x00\x00\x00\x000\x92\xe7d\x00" +
-	"\x00\x00\x001g6\xf4\x00\x00\x00\x002r\xc9d\x00\x00\x00\x003G\x18\xf4\x00\x00\x00\x004R\xabd\x00\x00\x00\x005&\xfa\xf4\x00\x00\x00\x0062\x8dd\x00\x00\x00\x007\x06\xdc\xf4\x00\x00\x00\x008" +
-	"\x1b\xa9\xe4\x00\x00\x00\x008\xe6\xbe\xf4\x00\x00\x00\x009\xfb\x8b\xe4\x00\x00\x00\x00:Ơ\xf4\x00\x00\x00\x00;\xdbm\xe4\x00\x00\x00\x00<\xaf\xbdt\x00\x00\x00\x00=\xbbO\xe4\x00\x00\x00\x00>\x8f\x9ft\x00" +
-	"\x00\x00\x00?\x9b1\xe4\x00\x00\x00\x00@o\x81t\x00\x00\x00\x00A\x84Nd\x00\x00\x00\x00BOct\x00\x00\x00\x00Cd0d\x00\x00\x00\x00D/Et\x00\x00\x00\x00ED\x12d\x00\x00\x00\x00E" +
-	"\xf3w\xf4\x00\x00\x00\x00G-.\xe4\x00\x00\x00\x00G\xd3Y\xf4\x00\x00\x00\x00I\r\x10\xe4\x00\x00\x00\x00I\xb3;\xf4\x00\x00\x00\x00J\xec\xf2\xe4\x00\x00\x00\x00K\x9cXt\x00\x00\x00\x00L\xd6\x0fd\x00" +
-	"\x00\x00\x00M|:t\x00\x00\x00\x00N\xb6\rH\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03" +
-	"\x04\x03\x04\x03\x04\x03\x04\x06\x05\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" +
-	"\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\a\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" +
-	"\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\xff\xffΔ\x00\x00\xff\xffܤ\x01\x04\xff\xffΔ\x00\b\xff\xff\xdc\xd8\x01\x04\xff\xff\xce\xc8\x00\b\xff\xff\xdc\xd8\x01\f\xff\xff" +
-	"\xdc\xd8\x01\x10\xff\xff\xea\xe8\x01\x14LMT\x00NDT\x00NST\x00NPT\x00NWT\x00NDDT\x00\nNST3:30NDT,M3.2.0,M11.1." +
-	"0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xae,\xa44\xc9\x03\x00\x00\xc9\x03\x00\x00\f\x00\x1c\x00America/AtkaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v" +
-	"\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00" +
-	"\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00T\x00\x00\x00\n\x00\x00\x00!\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}" +
-	"\x87Z^\xff\xff\xff\xffˉD\xd0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2aP@\xff\xff\xff\xff\xfa\xd2U\xb0\xff\xff\xff\xff\xfe\xb8qP\xff\xff\xff\xff\xff\xa8T@\x00\x00\x00\x00\x00\x98SP\x00" +
-	"\x00\x00\x00\x01\x886@\x00\x00\x00\x00\x02x5P\x00\x00\x00\x00\x03qR\xc0\x00\x00\x00\x00\x04aQ\xd0\x00\x00\x00\x00\x05Q4\xc0\x00\x00\x00\x00\x06A3\xd0\x00\x00\x00\x00\a1\x16\xc0\x00\x00\x00\x00\a" +
-	"\x8dm\xd0\x00\x00\x00\x00\t\x10\xf8\xc0\x00\x00\x00\x00\t\xad\xe9P\x00\x00\x00\x00\n\xf0\xda\xc0\x00\x00\x00\x00\v\xe0\xd9\xd0\x00\x00\x00\x00\f\xd9\xf7@\x00\x00\x00\x00\r\xc0\xbb\xd0\x00\x00\x00\x00\x0e\xb9\xd9@\x00" +
-	"\x00\x00\x00\x0f\xa9\xd8P\x00\x00\x00\x00\x10\x99\xbb@\x00\x00\x00\x00\x11\x89\xbaP\x00\x00\x00\x00\x12y\x9d@\x00\x00\x00\x00\x13i\x9cP\x00\x00\x00\x00\x14Y\x7f@\x00\x00\x00\x00\x15I~P\x00\x00\x00\x00\x16" +
-	"9a@\x00\x00\x00\x00\x17)`P\x00\x00\x00\x00\x18\"}\xc0\x00\x00\x00\x00\x19\tBP\x00\x00\x00\x00\x1a\x02_\xc0\x00\x00\x00\x00\x1a+\" \x00\x00\x00\x00\x1a\xf2P\xc0\x00\x00\x00\x00\x1b\xe23\xb0\x00" +
-	"\x00\x00\x00\x1c\xd22\xc0\x00\x00\x00\x00\x1d\xc2\x15\xb0\x00\x00\x00\x00\x1e\xb2\x14\xc0\x00\x00\x00\x00\x1f\xa1\xf7\xb0\x00\x00\x00\x00 vG@\x00\x00\x00\x00!\x81ٰ\x00\x00\x00\x00\"V)@\x00\x00\x00\x00#" +
-	"j\xf60\x00\x00\x00\x00$6\v@\x00\x00\x00\x00%J\xd80\x00\x00\x00\x00&\x15\xed@\x00\x00\x00\x00'*\xba0\x00\x00\x00\x00'\xff\t\xc0\x00\x00\x00\x00)\n\x9c0\x00\x00\x00\x00)\xde\xeb\xc0\x00" +
-	"\x00\x00\x00*\xea~0\x00\x00\x00\x00+\xbe\xcd\xc0\x00\x00\x00\x00,Ӛ\xb0\x00\x00\x00\x00-\x9e\xaf\xc0\x00\x00\x00\x00.\xb3|\xb0\x00\x00\x00\x00/~\x91\xc0\x00\x00\x00\x000\x93^\xb0\x00\x00\x00\x001" +
-	"g\xae@\x00\x00\x00\x002s@\xb0\x00\x00\x00\x003G\x90@\x00\x00\x00\x004S\"\xb0\x00\x00\x00\x005'r@\x00\x00\x00\x0063\x04\xb0\x00\x00\x00\x007\aT@\x00\x00\x00\x008\x1c!0\x00" +
-	"\x00\x00\x008\xe76@\x00\x00\x00\x009\xfc\x030\x00\x00\x00\x00:\xc7\x18@\x00\x00\x00\x00;\xdb\xe50\x00\x00\x00\x00<\xb04\xc0\x00\x00\x00\x00=\xbb\xc70\x00\x00\x00\x00>\x90\x16\xc0\x00\x00\x00\x00?" +
-	"\x9b\xa90\x00\x00\x00\x00@o\xf8\xc0\x00\x00\x00\x00A\x84Ű\x00\x00\x00\x00BO\xda\xc0\x00\x00\x00\x00Cd\xa7\xb0\x00\x00\x00\x00D/\xbc\xc0\x00\x00\x00\x00ED\x89\xb0\x00\x00\x00\x00E\xf3\xef@\x01" +
-	"\x02\x03\x04\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\a\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t" +
-	"\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\x00\x00\xab\xe2\x00\x00\xff\xffZb\x00\x00\xff\xffeP\x00\x04\xff\xffs`\x01\b\xff\xffs`\x01\f\xff\xffeP\x00\x10\xff" +
-	"\xffs`\x01\x14\xff\xffs`\x00\x18\xff\xff\x81p\x01\x1d\xff\xffs`\x00\x19LMT\x00NST\x00NWT\x00NPT\x00BST\x00BDT\x00AHST\x00HDT\x00\nHST" +
-	"10HDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTd\xa9y\x9at\x03\x00\x00t\x03\x00\x00\x10\x00\x1c\x00America/A" +
-	"suncionUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00O\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xffi\x87\x11\x90\xff\xff\xff\xff\xb8\x17\xf5\x90\x00\x00\x00\x00\x05+\xda@\x00\x00\x00\x00\a\xfc\xf0\xb0\x00\x00\x00\x00\n\xcft\xc0\x00\x00\x00\x00\v\x97ʰ\x00\x00" +
-	"\x00\x00\f\xb1\xf9\xc0\x00\x00\x00\x00\rx\xfe0\x00\x00\x00\x00\x0e\x93-@\x00\x00\x00\x00\x0fZ1\xb0\x00\x00\x00\x00\x10t`\xc0\x00\x00\x00\x00\x11dC\xb0\x00\x00\x00\x00\x12U\x94@\x00\x00\x00\x00\x13F" +
-	"Ȱ\x00\x00\x00\x00\x148\x19@\x00\x00\x00\x00\x15'\xfc0\x00\x00\x00\x00\x16\x19L\xc0\x00\x00\x00\x00\x17\t/\xb0\x00\x00\x00\x00\x17\xfa\x80@\x00\x00\x00\x00\x18\xeac0\x00\x00\x00\x00\x19۳\xc0\x00\x00" +
-	"\x00\x00\x1a\xcc\xe80\x00\x00\x00\x00\x1b\xbe8\xc0\x00\x00\x00\x00\x1c\xae\x1b\xb0\x00\x00\x00\x00\x1d\x9fl@\x00\x00\x00\x00\x1e\x8fO0\x00\x00\x00\x00\x1f\x80\x9f\xc0\x00\x00\x00\x00 p\x82\xb0\x00\x00\x00\x00!a" +
-	"\xd3@\x00\x00\x00\x00\"S\a\xb0\x00\x00\x00\x00#DX@\x00\x00\x00\x00$4;0\x00\x00\x00\x00%A;@\x00\x00\x00\x00&\x15n\xb0\x00\x00\x00\x00'\x06\xbf@\x00\x00\x00\x00'\xf6\xa20\x00\x00" +
-	"\x00\x00(\xee\x8a@\x00\x00\x00\x00)\xb0H\xb0\x00\x00\x00\x00*Ͻ\xc0\x00\x00\x00\x00+\xb9\t0\x00\x00\x00\x00,\xab\xab@\x00\x00\x00\x00-p\f\xb0\x00\x00\x00\x00.\x8c\xde\xc0\x00\x00\x00\x00/O" +
-	"\xee\xb0\x00\x00\x00\x000n\x12@\x00\x00\x00\x0016h0\x00\x00\x00\x002W.\xc0\x00\x00\x00\x003\x0f\xb2\xb0\x00\x00\x00\x0047\x10\xc0\x00\x00\x00\x004\xf8\xcf0\x00\x00\x00\x006\x16\xf2\xc0\x00\x00" +
-	"\x00\x006\xe1\xeb\xb0\x00\x00\x00\x007\xf6\xd4\xc0\x00\x00\x00\x008\xc1Ͱ\x00\x00\x00\x009ֶ\xc0\x00\x00\x00\x00:\xa1\xaf\xb0\x00\x00\x00\x00;\xbf\xd3@\x00\x00\x00\x00<\xaf\xb60\x00\x00\x00\x00=q" +
-	"\x90\xc0\x00\x00\x00\x00>\x8f\x980\x00\x00\x00\x00?Z\xad@\x00\x00\x00\x00@oz0\x00\x00\x00\x00Aq\xee@\x00\x00\x00\x00B3\xac\xb0\x00\x00\x00\x00CQ\xd0@\x00\x00\x00\x00D\x13\x8e\xb0\x00\x00" +
-	"\x00\x00E1\xb2@\x00\x00\x00\x00E\xf3p\xb0\x00\x00\x00\x00G\x1a\xce\xc0\x00\x00\x00\x00G\xd3R\xb0\x00\x00\x00\x00H\xfa\xb0\xc0\x00\x00\x00\x00I\xb34\xb0\x00\x00\x00\x00Jڒ\xc0\x00\x00\x00\x00K\xc1" +
-	";0\x00\x00\x00\x00L\xa7\xff\xc0\x00\x00\x00\x00M\xa1\x1d0\x00\x00\x00\x00N\x87\xe1\xc0\x00\x00\x00\x00O\x80\xff0\x00\x00\x00\x00Pp\xfe@\x01\x02\x03\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02" +
-	"\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02" +
-	"\x04\xff\xff\xc9\xf0\x00\x00\xff\xff\xc9\xf0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x00\f\xff\xff\xd5\xd0\x01\fLMT\x00AMT\x00-04\x00-03\x00\n<-04>4<-03>," +
-	"M10.1.0/0,M3.4.0/0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTB\xa0=:\x1e\x01\x00\x00\x1e\x01\x00\x00\x12\x00\x1c\x00America/Her" +
-	"mosilloUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x0f\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6fV`\xff\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff\xb8\f6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\xff\xff" +
-	"\xff\xff\xcb\xeaq`\xff\xff\xff\xffؑ\xb4\xf0\x00\x00\x00\x00\x00\x00p\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'" +
-	"H\x10\x00\x00\x00\x0062ڀ\x01\x02\x01\x02\x01\x02\x01\x03\x01\x04\x01\x04\x01\x04\x01\xff\xff\x97\xf8\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\x8f\x80\x00\f\xff\xff\xab\xa0\x01\x10LMT\x00M" +
-	"ST\x00CST\x00PST\x00MDT\x00\nMST7\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xd0v\x01\x8a\x01\x04\x00\x00\x01\x04\x00\x00\x0f\x00\x1c\x00America/T" +
-	"ijuanaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"^\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff\xa5\xb6\xf6\x80\xff\xff\xff\xff\xa9yOp\xff\xff\xff\xff\xaf\xf2|\xf0\xff\xff\xff\xff\xb6fdp\xff\xff\xff\xff\xb7\x1b\x10\x00\xff\xff\xff\xff\xb8\n\xf2\xf0\xff\xff\xff" +
-	"\xff\xcbꍀ\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xffҙ\xbap\xff\xff\xff\xff\xd7\x1bY\x00\xff\xff\xff\xffؑ\xb4\xf0\xff\xff\xff\xff\xe2~K\x90\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4^-" +
-	"\x90\xff\xff\xff\xff\xe5)4\x90\xff\xff\xff\xff\xe6GJ\x10\xff\xff\xff\xff\xe7\x12Q\x10\xff\xff\xff\xff\xe8',\x10\xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff\xff\xea\a\x0e\x10\xff\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff" +
-	"\xff\xeb\xe6\xf0\x10\xff\xff\xff\xff\xec\xb1\xf7\x10\xff\xff\xff\xff\xed\xc6\xd2\x10\xff\xff\xff\xff\xee\x91\xd9\x10\x00\x00\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf" +
-	"\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00" +
-	"\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16" +
-	"\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1ې\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\"V\r \x00\x00\x00\x00#j\xda\x10\x00\x00\x00" +
-	"\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\n\x80\x10\x00\x00\x00\x00)\xdeϠ\x00\x00\x00\x00*\xeab" +
-	"\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00" +
-	"\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\a8 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a" +
-	" \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00" +
-	"\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00F\x0f\x82\xa0\x00\x00\x00\x00G$O" +
-	"\x90\x00\x00\x00\x00G\xf8\x9f \x00\x00\x00\x00I\x041\x90\x00\x00\x00\x00I\u0601 \x00\x00\x00\x00J\xe4\x13\x90\x00\x00\x00\x00K\x9c\xb3\xa0\x01\x02\x01\x02\x03\x02\x04\x05\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\x92L\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\x8f\x80\x00\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10\xff\xff\x9d\x90\x01\x14LMT\x00MST\x00P" +
-	"ST\x00PDT\x00PWT\x00PPT\x00\nPST8PDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTq\xc9*;\xb1\x00\x00" +
-	"\x00\xb1\x00\x00\x00\x0f\x00\x1c\x00America/MarigotUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01" +
-	"\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8f" +
-	"j\xbeT?\xc9\x1c\xd4\xc6\x03\x00\x00\xc6\x03\x00\x00\x0e\x00\x1c\x00America/JuneauUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01" +
-	"\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S\x00\x00\x00\n\x00\x00\x00&\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}\x872\xc5\xff\xff\xff\xffˉ\x1a\xa0" +
-	"\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a&\x10\xff\xff\xff\xff\xfe\xb8G \xff\xff\xff\xff\xff\xa8*\x10\x00\x00\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88\f\x10\x00\x00\x00\x00\x02x\v \x00\x00\x00\x00" +
-	"\x03q(\x90\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05Q\n\x90\x00\x00\x00\x00\x06A\t\xa0\x00\x00\x00\x00\a0\xec\x90\x00\x00\x00\x00\a\x8dC\xa0\x00\x00\x00\x00\t\x10ΐ\x00\x00\x00\x00\t\xad\xbf " +
-	"\x00\x00\x00\x00\n\xf0\xb0\x90\x00\x00\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00" +
-	"\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14Yc \x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90" +
-	"\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a+\x14\x10\x00\x00\x00\x00\x1a\xf2B\xb0\x00\x00\x00\x00\x1b\xe2%\xa0\x00\x00\x00\x00\x1c\xd2$\xb0\x00\x00\x00\x00\x1d\xc2\a\xa0\x00\x00\x00\x00" +
-	"\x1e\xb2\x06\xb0\x00\x00\x00\x00\x1f\xa1\xe9\xa0\x00\x00\x00\x00 v90\x00\x00\x00\x00!\x81ˠ\x00\x00\x00\x00\"V\x1b0\x00\x00\x00\x00#j\xe8 \x00\x00\x00\x00$5\xfd0\x00\x00\x00\x00%J\xca " +
-	"\x00\x00\x00\x00&\x15\xdf0\x00\x00\x00\x00'*\xac \x00\x00\x00\x00'\xfe\xfb\xb0\x00\x00\x00\x00)\n\x8e \x00\x00\x00\x00)\xdeݰ\x00\x00\x00\x00*\xeap \x00\x00\x00\x00+\xbe\xbf\xb0\x00\x00\x00\x00" +
-	",ӌ\xa0\x00\x00\x00\x00-\x9e\xa1\xb0\x00\x00\x00\x00.\xb3n\xa0\x00\x00\x00\x00/~\x83\xb0\x00\x00\x00\x000\x93P\xa0\x00\x00\x00\x001g\xa00\x00\x00\x00\x002s2\xa0\x00\x00\x00\x003G\x820" +
-	"\x00\x00\x00\x004S\x14\xa0\x00\x00\x00\x005'd0\x00\x00\x00\x0062\xf6\xa0\x00\x00\x00\x007\aF0\x00\x00\x00\x008\x1c\x13 \x00\x00\x00\x008\xe7(0\x00\x00\x00\x009\xfb\xf5 \x00\x00\x00\x00" +
-	":\xc7\n0\x00\x00\x00\x00;\xdb\xd7 \x00\x00\x00\x00<\xb0&\xb0\x00\x00\x00\x00=\xbb\xb9 \x00\x00\x00\x00>\x90\b\xb0\x00\x00\x00\x00?\x9b\x9b \x00\x00\x00\x00@o\xea\xb0\x00\x00\x00\x00A\x84\xb7\xa0" +
-	"\x00\x00\x00\x00BO̰\x00\x00\x00\x00Cd\x99\xa0\x00\x00\x00\x00D/\xae\xb0\x00\x00\x00\x00ED{\xa0\x00\x00\x00\x00E\xf3\xe10\x01\x02\x03\x04\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05" +
-	"\x02\x05\x02\x05\x02\x05\x02\x06\x02\x05\x02\x05\x02\x05\a\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t" +
-	"\b\t\b\x00\x00\xd3{\x00\x00\xff\xff\x81\xfb\x00\x00\xff\xff\x8f\x80\x00\x04\xff\xff\x9d\x90\x01\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10\xff\xff\x8f\x80\x01\x14\xff\xff\x81p\x00\x18\xff\xff\x8f\x80\x01\x1c\xff\xff\x81" +
-	"p\x00!LMT\x00PST\x00PWT\x00PPT\x00PDT\x00YDT\x00YST\x00AKDT\x00AKST\x00\nAKST9AKDT,M3.2.0,M" +
-	"11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xc0\x98\x00\b\xc9\x03\x00\x00\xc9\x03\x00\x00\x12\x00\x1c\x00America/MontevideoUT\t\x00\x03" +
-	"\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\x00\x00\x00\t\x00\x00\x00&\xff\xff" +
-	"\xff\xff\x8c4\xe53\xff\xff\xff\xff\xa2\x92\x87\xb3\xff\xff\xff\xff\xa8\xff\xdb@\xff\xff\xff\xff\xa9\xf1\x0f\xb0\xff\xff\xff\xff\xaa\xe2Y8\xff\xff\xff\xff\xab\xd2C0\xff\xff\xff\xff\xacÌ\xb8\xff\xff\xff\xff\xad\xb3" +
-	"v\xb0\xff\xff\xff\xff\xbb\xf4\xb5\xb8\xff\xff\xff\xff\xbc\xbf\xb5\xb0\xff\xff\xff\xff\xbdԗ\xb8\xff\xff\xff\xff\xbe\x9f\x97\xb0\xff\xff\xff\xff\xbf\xb4y\xb8\xff\xff\xff\xff\xc0\x7fy\xb0\xff\xff\xff\xff\xc1\x94[\xb8\xff\xff" +
-	"\xff\xff\xc2_[\xb0\xff\xff\xff\xff\xc3}x8\xff\xff\xff\xff\xc4?=\xb0\xff\xff\xff\xff\xc5]Z8\xff\xff\xff\xff\xc6\x1f\x1f\xb0\xff\xff\xff\xff\xc7\x18R8\xff\xff\xff\xff\xc8\b<0\xff\xff\xff\xff\xc9\x1d" +
-	"\x1e8\xff\xff\xff\xff\xc9\xe8\x1e0\xff\xff\xff\xffʋ\x9f8\xff\xff\xff\xff\xcd\x1e\xc60\xff\xff\xff\xff͕f(\xff\xff\xff\xff\xec\v\x85\xb0\xff\xff\xff\xff\xec\xf25(\xff\xff\xff\xff\xedEJ\xb0\xff\xff" +
-	"\xff\xff\xed\x85\xd6 \xff\xff\xff\xff\xf7\x13r\xb0\xff\xff\xff\xff\xf7\xfa\x1b \xff\xff\xff\xff\xfc\xfe>0\xff\xff\xff\xff\xfd\xf6\x11(\x00\x00\x00\x00\x00\x96u0\x00\x00\x00\x00\x00\xd8R \x00\x00\x00\x00\x04W" +
-	"\x8a\xb0\x00\x00\x00\x00\x04\xc6:\xa0\x00\x00\x00\x00\a\x96\x1b\xb0\x00\x00\x00\x00\a\xdfژ\x00\x00\x00\x00\bƟ(\x00\x00\x00\x00\tZN0\x00\x00\x00\x00\t\xdbs \x00\x00\x00\x00\r\x1a\x120\x00\x00" +
-	"\x00\x00\r\x7f\x87\xa0\x00\x00\x00\x00\x0e\xe7\x7f0\x00\x00\x00\x00\x0f_i\xa0\x00\x00\x00\x00\x10\xd9\xd60\x00\x00\x00\x00\x11?K\xa0\x00\x00\x00\x00\x11\x89-\xb0\x00\x00\x00\x00\x131\xa2\xa0\x00\x00\x00\x00!\xc3" +
-	"T0\x00\x00\x00\x00\"'x \x00\x00\x00\x00#\xa1\xe4\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%Jg\xb0\x00\x00\x00\x00%\xe7< \x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00" +
-	"\x00\x00)\n+\xb0\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x90\x1c\xa0\x00\x00\x00\x00AL\xf60\x00\x00\x00\x00BF/\xc0\x00\x00\x00\x00CH\xa3\xd0\x00\x00\x00\x00D\x13" +
-	"\x9c\xc0\x00\x00\x00\x00E\x1fKP\x00\x00\x00\x00E\xf3~\xc0\x00\x00\x00\x00G\bg\xd0\x00\x00\x00\x00G\xd3`\xc0\x00\x00\x00\x00H\xe8I\xd0\x00\x00\x00\x00I\xb3B\xc0\x00\x00\x00\x00J\xc8+\xd0\x00\x00" +
-	"\x00\x00K\x9c_@\x00\x00\x00\x00L\xa8\r\xd0\x00\x00\x00\x00M|A@\x00\x00\x00\x00N\x87\xef\xd0\x00\x00\x00\x00O\\#@\x00\x00\x00\x00Pq\fP\x00\x00\x00\x00Q<\x05@\x00\x00\x00\x00RP" +
-	"\xeeP\x00\x00\x00\x00S\x1b\xe7@\x00\x00\x00\x00T0\xd0P\x00\x00\x00\x00T\xfb\xc9@\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x06\x05\x06\x05\a\x05\a\x05\x06" +
-	"\x05\a\x05\a\x05\b\x06\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\xff\xff\xcbM\x00\x00\xff\xff" +
-	"\xcbM\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xce\xc8\x00\f\xff\xff\xd5\xd0\x01\x12\xff\xff\xd5\xd0\x00\x12\xff\xff\xdc\xd8\x01\x16\xff\xff\xe3\xe0\x01\x1c\xff\xff\xea\xe8\x01 LMT\x00MMT\x00-04\x00-0" +
-	"330\x00-03\x00-0230\x00-02\x00-0130\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe90T\x16\xd1\x01\x00\x00\xd1\x01\x00\x00\x0f\x00" +
-	"\x1c\x00America/GodthabUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\"\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x9b\x80h\x00\x00\x00\x00\x00\x13M|P\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ" +
-	"\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00" +
-	"\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10" +
-	"\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00" +
-	"+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xffπ\x00\x00\xff\xff\xd5\xd0\x00\x04\xff\xff\xe3\xe0\x01\bLMT\x00-03\x00-02\x00\n<-0" +
-	"3>3<-02>,M3.5.0/-2,M10.5.0/-1\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTq\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x12\x00\x1c\x00" +
-	"America/GuadeloupeUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2" +
-	"\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT挋" +
-	"\x92\xf6\x01\x00\x00\xf6\x01\x00\x00\x0e\x00\x1c\x00America/MaceioUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaah|\xff\xff\xff\xff\xb8\x0fI\xe0\xff\xff\xff\xff\xb8\xfd@\xa0\xff\xff\xff\xff\xb9\xf1" +
-	"40\xff\xff\xff\xff\xba\xdet \xff\xff\xff\xff\xda8\xae0\xff\xff\xff\xff\xda\xeb\xfa0\xff\xff\xff\xff\xdc\x19\xe1\xb0\xff\xff\xff\xffܹY \xff\xff\xff\xff\xdd\xfb\x150\xff\xff\xff\xffޛ\xde \xff\xff" +
-	"\xff\xff\xdfݚ0\xff\xff\xff\xff\xe0T3 \xff\xff\xff\xff\xf4\x97\xff\xb0\xff\xff\xff\xff\xf5\x05^ \xff\xff\xff\xff\xf6\xc0d0\xff\xff\xff\xff\xf7\x0e\x1e\xa0\xff\xff\xff\xff\xf8Q,0\xff\xff\xff\xff\xf8\xc7" +
-	"\xc5 \xff\xff\xff\xff\xfa\nҰ\xff\xff\xff\xff\xfa\xa8\xf8\xa0\xff\xff\xff\xff\xfb\xec\x060\xff\xff\xff\xff\xfc\x8b}\xa0\x00\x00\x00\x00\x1dɎ0\x00\x00\x00\x00\x1exנ\x00\x00\x00\x00\x1f\xa05\xb0\x00\x00" +
-	"\x00\x00 3Ϡ\x00\x00\x00\x00!\x81i0\x00\x00\x00\x00\"\vȠ\x00\x00\x00\x00#X\x10\xb0\x00\x00\x00\x00#\xe2p \x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xd4\xc7 \x00\x00\x00\x000\x80" +
-	"y0\x00\x00\x00\x001\x1dM\xa0\x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xb8\x85 \x00\x00\x00\x009\xdf\xe30\x00\x00\x00\x009\xf2J \x00\x00\x00\x00;\xc8\xff\xb0\x00\x00\x00\x00<o\x0e\xa0\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xffބ\x00\x00\xff\xff\xe3\xe0\x01\x04\xff\xff\xd5\xd0\x00\bLMT" +
-	"\x00-02\x00-03\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTJtZ\x8c\x01\x03\x00\x00\x01\x03\x00\x00\x13\x00\x1c\x00America/Pangn" +
-	"irtungUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"=\x00\x00\x00\n\x00\x00\x00)\xff\xff\xff\xff\xa3\xd5R\x80\xff\xff\xff\xffˈ\xe2`\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\xff\xff\xff\xff\xf7/0@\xff\xff\xff\xff\xf8([\xc0\x00\x00\x00" +
-	"\x00\x13i9\xe0\x00\x00\x00\x00\x14Y\x1c\xd0\x00\x00\x00\x00\x15I\x1b\xe0\x00\x00\x00\x00\x168\xfe\xd0\x00\x00\x00\x00\x17(\xfd\xe0\x00\x00\x00\x00\x18\"\x1bP\x00\x00\x00\x00\x19\b\xdf\xe0\x00\x00\x00\x00\x1a\x01\xfd" +
-	"P\x00\x00\x00\x00\x1a\xf1\xfc`\x00\x00\x00\x00\x1b\xe1\xdfP\x00\x00\x00\x00\x1c\xd1\xde`\x00\x00\x00\x00\x1d\xc1\xc1P\x00\x00\x00\x00\x1e\xb1\xc0`\x00\x00\x00\x00\x1f\xa1\xa3P\x00\x00\x00\x00 u\xf2\xe0\x00\x00\x00" +
-	"\x00!\x81\x85P\x00\x00\x00\x00\"U\xd4\xe0\x00\x00\x00\x00#j\xa1\xd0\x00\x00\x00\x00$5\xb6\xe0\x00\x00\x00\x00%J\x83\xd0\x00\x00\x00\x00&\x15\x98\xe0\x00\x00\x00\x00'*e\xd0\x00\x00\x00\x00'\xfe\xb5" +
-	"`\x00\x00\x00\x00)\nG\xd0\x00\x00\x00\x00)ޗ`\x00\x00\x00\x00*\xea)\xd0\x00\x00\x00\x00+\xbey`\x00\x00\x00\x00,\xd3FP\x00\x00\x00\x00-\x9e[`\x00\x00\x00\x00.\xb3(P\x00\x00\x00" +
-	"\x00/~=`\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe" +
-	"`\x00\x00\x00\x007\a\r\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00" +
-	"\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/v" +
-	"p\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x03\x01\x02\x03\x04\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x06\a\x06\a\x06\a\x06" +
-	"\a\x06\b\t\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\x00\x00\x00\x00\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xc7\xc0\x00\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x01\x15\xff\xff\xc7\xc0\x01\x19" +
-	"\xff\xff\xb9\xb0\x00\x1d\xff\xff\xab\xa0\x00!\xff\xff\xb9\xb0\x01%-00\x00AWT\x00APT\x00AST\x00ADDT\x00ADT\x00EDT\x00EST\x00CST\x00CDT\x00\n" +
-	"EST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTq\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x1c\x00America" +
-	"/St_KittsUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04" +
-	"\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTl=\xad\xbe\x16\x01\x00\x00\x16\x01\x00\x00" +
-	"\x10\x00\x1c\x00America/BarbadosUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00" +
+	"MDT\x00MST\x00MWT\x00MPT\x00CDT\x00CST\x00\nCST6CDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00R\x1b\x8b(\xde\x03\x00\x00\xde\x03\x00\x00\x1e\x00\x00\x00America/North_Dakota/New_SalemTZif2\x00\x00\x00\x00\x00\x00\x00" +
 	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x92@\xa9e\xff\xff\xff\xff\xcb\xe3\xcb\xd0\xff\xff\xff\xff̔\x82\xe0\xff\xff\xff\xff\xcd\xd6\"\xd0\xff\xff\xff\xff\xce" +
-	"|M\xe0\xff\xff\xff\xffϛ\xa6\xd0\xff\xff\xff\xff\xd0ej`\x00\x00\x00\x00\x0e\x00\xf2\xe0\x00\x00\x00\x00\x0e\x94\x8c\xd0\x00\x00\x00\x00\x0f\x97\x00\xe0\x00\x00\x00\x00\x10tn\xd0\x00\x00\x00\x00\x11v\xe2\xe0\x00" +
-	"\x00\x00\x00\x12TP\xd0\x00\x00\x00\x00\x13_\xff`\x00\x00\x00\x00\x140>P\x02\x01\x02\x01\x02\x03\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xc8\x1b\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xce\xc8" +
-	"\x01\fLMT\x00ADT\x00AST\x00-0330\x00\nAST4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT<\xb9\x18\x87\xe4\x02\x00\x00\xe4\x02\x00\x00\x0f\x00\x1c\x00Amer" +
-	"ica/IqaluitUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00<\x00\x00\x00\b\x00\x00\x00!\xff\xff\xff\xff\xccl\xa1\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff\xf7/>P\xff\xff\xff\xff\xf8(i\xd0\x00\x00\x00\x00\x13i" +
-	"G\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x00\x00" +
-	"\x00\x00\x1a\xf2\np\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81" +
-	"\x93`\x00\x00\x00\x00\"U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00" +
-	"\x00\x00)\nU\xe0\x00\x00\x00\x00)ޥp\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~" +
-	"Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00" +
-	"\x00\x007\a\r\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb" +
-	"\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00" +
-	"\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x05\x01\x02\x03\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x06\a" +
-	"\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x00\x00\x00\x00\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xc7\xc0\x01\x11\xff\xff\xc7\xc0\x01\x15\xff\xff\xab\xa0\x00\x19\xff\xff\xb9\xb0" +
-	"\x01\x1d-00\x00EPT\x00EST\x00EDDT\x00EDT\x00EWT\x00CST\x00CDT\x00\nEST5EDT,M3.2.0,M11.1.0\nP" +
-	"K\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT8O:\xbf\x95\x03\x00\x00\x95\x03\x00\x00\x11\x00\x1c\x00America/MenomineeUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bu" +
-	"x\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00" +
-	"\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00R\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xffawIc\xff\xff\xff" +
-	"\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd3u\xf3" +
-	"\x00\xff\xff\xff\xff\xd4@\xeb\xf0\xff\xff\xff\xff\xf9\x0fJ\x80\xff\xff\xff\xff\xfa\bg\xf0\xff\xff\xff\xff\xfe\xb8+\x00\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\a0\xd0p\x00\x00\x00\x00\a\x8d'\x80\x00\x00\x00" +
-	"\x00\t\x10\xb2p\x00\x00\x00\x00\t\xad\xa3\x00\x00\x00\x00\x00\n\xf0\x94p\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00\x00\x00\fٰ\xf0\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92" +
-	"\x00\x00\x00\x00\x00\x10\x99t\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00" +
-	"\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\"7p\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xdd" +
-	"p\x00\x00\x00\x00\x1e\xb1܀\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00" +
-	"\x00%J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)\nc\xf0\x00\x00\x00\x00)\u07b3\x80\x00\x00\x00\x00*\xeaE\xf0\x00\x00\x00\x00+\xbe\x95" +
-	"\x80\x00\x00\x00\x00,\xd3bp\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3Dp\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x93&p\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00" +
-	"\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca" +
-	"\xf0\x00\x00\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00;۬\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00" +
-	"\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x05\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\xff\xff\xad\xdd\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14LMT\x00CDT\x00CST\x00CWT\x00C" +
-	"PT\x00EST\x00\nCST6CDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xa7\x17jҲ\x00\x00\x00\xb2\x00\x00\x00\x12\x00\x1c" +
-	"\x00America/MartiniqueUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xffi\x87\x14\xc4\xff\xff\xff\xff\x91\xa3\xc8D\x00\x00\x00\x00\x13Mn@\x00\x00\x00\x00\x144\x16\xb0\x01\x02\x03\x02\xff\xff" +
-	"Ƽ\x00\x00\xff\xffƼ\x00\x04\xff\xff\xc7\xc0\x00\t\xff\xff\xd5\xd0\x01\rLMT\x00FFMT\x00AST\x00ADT\x00\nAST4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xd6" +
-	"\xe1Հ\x9c\x01\x00\x00\x9c\x01\x00\x00\x13\x00\x1c\x00America/Mexico_CityUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_" +
-	"\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6fV" +
-	"`\xff\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff\xb8\f6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\xff\xff\xff\xff\xc5ް`\xff\xff\xff\xffƗ4P\xff\xff\xff\xff\xc9U\xf1\xe0\xff\xff\xff\xff\xc9\xea\xddP\xff\xff\xff" +
-	"\xff\xcf\x02\xc6\xe0\xff\xff\xff\xffϷVP\xff\xff\xff\xffڙ\x15\xe0\xff\xff\xff\xff\xdbv\x83\xd0\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xea" +
-	"p\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xf5\x04\x80\x00\x00\x00" +
-	"\x00;\xb6\xc2\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x01\x02\x01\x02\x01\x02\x03\x02\x03\x02\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\xa3\f\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff" +
-	"\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10LMT\x00MST\x00CST\x00CDT\x00CWT\x00\nCST6CDT,M4.1.0,M10.5.0\nPK\x03\x04\n\x00" +
-	"\x00\x00\x00\x00\x8fj\xbeT\x1c\xd8\x19\x9dp\x01\x00\x00p\x01\x00\x00\x15\x00\x1c\x00America/Swift_CurrentUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux" +
-	"\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00" +
-	"\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff\x86\xfd\x96\x18\xff\xff\xff\xff" +
-	"\x9e\xb8\xaf\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xd3v\x01\x10\xff\xff\xff\xff\xd4So\x00\xff\xff\xff\xff\xd5U\xe3\x10" +
-	"\xff\xff\xff\xff\xd6 \xdc\x00\xff\xff\xff\xff\xd75\xc5\x10\xff\xff\xff\xff\xd8\x00\xbe\x00\xff\xff\xff\xff\xd9\x15\xa7\x10\xff\xff\xff\xff\xd9\xe0\xa0\x00\xff\xff\xff\xff\xe8',\x10\xff\xff\xff\xff\xe9\x17\x0f\x00\xff\xff\xff\xff" +
-	"\xeb\xe6\xf0\x10\xff\xff\xff\xff\xec\xd6\xd3\x00\xff\xff\xff\xff\xed\xc6\xd2\x10\xff\xff\xff\xff\xee\x91\xcb\x00\xff\xff\xff\xff\xef\xaf\xee\x90\xff\xff\xff\xff\xf0q\xad\x00\x00\x00\x00\x00\x04a\x19\x90\x02\x01\x02\x03\x04\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\xff\xff\x9a\xe8\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10\xff\xff\xab\xa0\x00\x14LMT\x00MDT\x00M" +
-	"ST\x00MWT\x00MPT\x00CST\x00\nCST6\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xd7\b\\\xc6&\x02\x00\x00&\x02\x00\x00\x10\x00\x1c\x00America/M" +
-	"iquelonUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00+\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\x91\xb68\xa8\x00\x00\x00\x00\x13nc\xc0\x00\x00\x00\x00 u\xe4\xd0\x00\x00\x00\x00!\x81w@\x00\x00\x00\x00\"U\xc6\xd0\x00\x00\x00\x00#j\x93\xc0\x00\x00" +
-	"\x00\x00$5\xa8\xd0\x00\x00\x00\x00%Ju\xc0\x00\x00\x00\x00&\x15\x8a\xd0\x00\x00\x00\x00'*W\xc0\x00\x00\x00\x00'\xfe\xa7P\x00\x00\x00\x00)\n9\xc0\x00\x00\x00\x00)މP\x00\x00\x00\x00*\xea" +
-	"\x1b\xc0\x00\x00\x00\x00+\xbekP\x00\x00\x00\x00,\xd38@\x00\x00\x00\x00-\x9eMP\x00\x00\x00\x00.\xb3\x1a@\x00\x00\x00\x00/~/P\x00\x00\x00\x000\x92\xfc@\x00\x00\x00\x001gK\xd0\x00\x00" +
-	"\x00\x002r\xde@\x00\x00\x00\x003G-\xd0\x00\x00\x00\x004R\xc0@\x00\x00\x00\x005'\x0f\xd0\x00\x00\x00\x0062\xa2@\x00\x00\x00\x007\x06\xf1\xd0\x00\x00\x00\x008\x1b\xbe\xc0\x00\x00\x00\x008\xe6" +
-	"\xd3\xd0\x00\x00\x00\x009\xfb\xa0\xc0\x00\x00\x00\x00:Ƶ\xd0\x00\x00\x00\x00;ۂ\xc0\x00\x00\x00\x00<\xaf\xd2P\x00\x00\x00\x00=\xbbd\xc0\x00\x00\x00\x00>\x8f\xb4P\x00\x00\x00\x00?\x9bF\xc0\x00\x00" +
-	"\x00\x00@o\x96P\x00\x00\x00\x00A\x84c@\x00\x00\x00\x00BOxP\x00\x00\x00\x00CdE@\x00\x00\x00\x00D/ZP\x00\x00\x00\x00ED'@\x00\x00\x00\x00E\xf3\x8c\xd0\x01\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\xcbX\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x00\b\xff\xff\xe3\xe0\x01" +
-	"\fLMT\x00AST\x00-03\x00-02\x00\n<-03>3<-02>,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTq" +
-	"\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0f\x00\x1c\x00America/CuracaoUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZ" +
-	"if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff" +
-	"\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\n" +
-	"\x00\x00\x00\x00\x00\x8fj\xbeT+\x10`ȫ\x02\x00\x00\xab\x02\x00\x00\x14\x00\x1c\x00America/Dawson_CreekUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux" +
-	"\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00" +
-	"\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff^=t8\xff\xff\xff\xff" +
-	"\x9e\xb8\xbd\xa0\xff\xff\xff\xff\x9f\xbb\x15\x90\xff\xff\xff\xffˉ\x1a\xa0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a&\x10\xff\xff\xff\xff\xd5U\xf1 \xff\xff\xff\xff\xd6 \xea\x10\xff\xff\xff\xff\xd75\xd3 " +
-	"\xff\xff\xff\xff\xd8\x00\xcc\x10\xff\xff\xff\xff\xd9\x15\xb5 \xff\xff\xff\xff\xd9\xe0\xae\x10\xff\xff\xff\xff\xda\xfeѠ\xff\xff\xff\xff\xdb\xc0\x90\x10\xff\xff\xff\xff\xdc\u07b3\xa0\xff\xff\xff\xffݩ\xac\x90\xff\xff\xff\xff" +
-	"\u07be\x95\xa0\xff\xff\xff\xff߉\x8e\x90\xff\xff\xff\xff\xe0\x9ew\xa0\xff\xff\xff\xff\xe1ip\x90\xff\xff\xff\xff\xe2~Y\xa0\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4^;\xa0\xff\xff\xff\xff\xe5)4\x90" +
-	"\xff\xff\xff\xff\xe6GX \xff\xff\xff\xff\xe7\x12Q\x10\xff\xff\xff\xff\xe8': \xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff\xff\xea\a\x1c \xff\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff\xff\xeb\xe6\xfe \xff\xff\xff\xff" +
-	"\xec\xb1\xf7\x10\xff\xff\xff\xff\xed\xc6\xe0 \xff\xff\xff\xff\xee\x91\xd9\x10\xff\xff\xff\xff\xef\xaf\xfc\xa0\xff\xff\xff\xff\xf0q\xbb\x10\xff\xff\xff\xff\xf1\x8fޠ\xff\xff\xff\xff\xf2\x7f\xc1\x90\xff\xff\xff\xff\xf3o\xc0\xa0" +
-	"\xff\xff\xff\xff\xf4_\xa3\x90\xff\xff\xff\xff\xf5O\xa2\xa0\xff\xff\xff\xff\xf6?\x85\x90\xff\xff\xff\xff\xf7/\x84\xa0\xff\xff\xff\xff\xf8(\xa2\x10\xff\xff\xff\xff\xf9\x0ff\xa0\xff\xff\xff\xff\xfa\b\x84\x10\xff\xff\xff\xff" +
-	"\xfa\xf8\x83 \xff\xff\xff\xff\xfb\xe8f\x10\xff\xff\xff\xff\xfc\xd8e \xff\xff\xff\xff\xfd\xc8H\x10\xff\xff\xff\xff\xfe\xb8G \xff\xff\xff\xff\xff\xa8*\x10\x00\x00\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88\f\x10" +
-	"\x00\x00\x00\x00\x02x\v \x00\x00\x00\x00\x03q(\x90\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05\x01\xf0\x90\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x05\xff\xff\x8fH\x00\x00\xff\xff\x9d\x90\x01\x04\xff\xff\x8f\x80\x00\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10" +
-	"\xff\xff\x9d\x90\x00\x14LMT\x00PDT\x00PST\x00PWT\x00PPT\x00MST\x00\nMST7\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTŒZ\x8c\xc4\x02\x00\x00\xc4\x02" +
-	"\x00\x00\x0f\x00\x1c\x00America/MendozaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y\x00\x00\x00\a\x00\x00\x00\x1c\xff\xff\xff\xff^\x04\f\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1" +
+	"\x9a\xe9\x80\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W\x10\xff\xff\xff\xff\xfd\xc8:\x00\xff" +
+	"\xff\xff\xff\xfe\xb89\x10\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x1b\x10\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xfd\x10\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05" +
+	"P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\a\x8d5\x90\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\t\xad\xb1\x10\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\vࡐ\x00" +
+	"\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13" +
+	"id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00\x00\x1a\x02'\x80\x00" +
+	"\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!" +
+	"\x81\xaf\x80\x00\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeߐ\x00" +
+	"\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/" +
+	"~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00" +
+	"\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=" +
+	"\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00" +
+	"\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x06\x05\x06\x05\x06\x05\x06\x05\xff\xff\xa0\xed\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90" +
+	"\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10\xff\xff\xb9\xb0\x01\x14\xff\xff\xab\xa0\x00\x18LMT\x00MDT\x00MST\x00MWT\x00MPT\x00CDT\x00CST\x00\nCST6C" +
+	"DT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\xbc\xc9I\xa3\x03\x00\x00\xa3\x03\x00\x00\f\x00\x00\x00America/Nuuk" +
+	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xff\x9b\x80h\x00\x00\x00\x00\x00\x13M|P\x00\x00\x00\x00\x143\xfa\x90\x00" +
+	"\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b" +
+	"\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00" +
+	"\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)" +
+	"\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00" +
+	"\x00\x00\x001]\xd9\x10\x00\x00\x00\x002r\xb4\x10\x00\x00\x00\x003=\xbb\x10\x00\x00\x00\x004R\x96\x10\x00\x00\x00\x005\x1d\x9d\x10\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd\x7f\x10\x00\x00\x00\x008" +
+	"\x1b\x94\x90\x00\x00\x00\x008\xdda\x10\x00\x00\x00\x009\xfbv\x90\x00\x00\x00\x00:\xbdC\x10\x00\x00\x00\x00;\xdbX\x90\x00\x00\x00\x00<\xa6_\x90\x00\x00\x00\x00=\xbb:\x90\x00\x00\x00\x00>\x86A\x90\x00" +
+	"\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F" +
+	"\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00" +
+	"\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00T" +
+	"LG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00" +
+	"\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\x7f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b" +
+	"?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\xff\xffπ\x00\x00\xff\xff\xd5\xd0\x00\x04\xff" +
+	"\xff\xe3\xe0\x01\b\xff\xff\xe3\xe0\x00\bLMT\x00-03\x00-02\x00\n<-02>2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xe5\x9e<\xc5\x02\x00\x00\xc5\x02\x00\x00\x0f\x00\x00" +
+	"\x00America/OjinagaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01" +
+	"\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\xa5\xb6\xe8p\xff" +
+	"\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6fV`\xff\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff\xb8\f6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003" +
+	"GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00" +
+	"\x00\x00\x00:\xf5\x12\x90\x00\x00\x00\x00;\xb6\xd1\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A" +
+	"\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00F\x0ft\x90\x00\x00\x00\x00G$A\x80\x00\x00\x00\x00G\xf8\x91\x10\x00" +
+	"\x00\x00\x00I\x04#\x80\x00\x00\x00\x00I\xd8s\x10\x00\x00\x00\x00J\xe4\x05\x80\x00\x00\x00\x00K\x9c\xa5\x90\x00\x00\x00\x00L\xd6\\\x80\x00\x00\x00\x00M|\x87\x90\x00\x00\x00\x00N\xb6>\x80\x00\x00\x00\x00O" +
+	"\\i\x90\x00\x00\x00\x00P\x96 \x80\x00\x00\x00\x00Q<K\x90\x00\x00\x00\x00Rv\x02\x80\x00\x00\x00\x00S\x1c-\x90\x00\x00\x00\x00TU\xe4\x80\x00\x00\x00\x00T\xfc\x0f\x90\x00\x00\x00\x00V5ƀ\x00" +
+	"\x00\x00\x00V\xe5,\x10\x00\x00\x00\x00X\x1e\xe3\x00\x00\x00\x00\x00X\xc5\x0e\x10\x00\x00\x00\x00Y\xfe\xc5\x00\x00\x00\x00\x00Z\xa4\xf0\x10\x00\x00\x00\x00[ާ\x00\x00\x00\x00\x00\\\x84\xd2\x10\x00\x00\x00\x00]" +
+	"\xbe\x89\x00\x00\x00\x00\x00^d\xb4\x10\x00\x00\x00\x00_\x9ek\x00\x00\x00\x00\x00`MА\x00\x00\x00\x00a\x87\x87\x80\x00\x00\x00\x00b-\xb2\x90\x00\x00\x00\x00c^/\x00\x01\x02\x01\x03\x01\x02\x04\x02\x04" +
+	"\x02\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x02\xff\xff\x9e\x1c\x00\x00\xff\xff\x9d" +
+	"\x90\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xb9\xb0\x01\x10LMT\x00MST\x00CST\x00MDT\x00CDT\x00\nCST6CDT,M3.2.0,M11" +
+	".1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Ծ\xe7#\x95\x00\x00\x00\x95\x00\x00\x00\x0e\x00\x00\x00America/PanamaTZif2\x00\x00\x00\x00\x00\x00" +
 	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xb2\x04\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff" +
-	"\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0" +
-	"\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff" +
-	"\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0" +
-	"\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff" +
-	"\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50" +
-	"\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00" +
-	"'\x194@\x00\x00\x00\x00'\xcdð\x00\x00\x00\x00(\xfag\xc0\x00\x00\x00\x00)\xb0H\xb0\x00\x00\x00\x00*\xe0\xe1@\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0" +
-	"\x00\x00\x00\x00@\xb0\x13\xb0\x00\x00\x00\x00AV>\xc0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x02\x03\x02\x03\x02\x04\x05\x03\x05\x02\x05\x04\x05\xff\xff\xbf|\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3" +
-	"\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xae,\xa44\xc9\x03\x00\x00\xc9" +
-	"\x03\x00\x00\f\x00\x1c\x00America/AdakUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00T\x00\x00\x00\n\x00\x00\x00!\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}\x87Z^\xff\xff\xff\xffˉD\xd0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a" +
-	"P@\xff\xff\xff\xff\xfa\xd2U\xb0\xff\xff\xff\xff\xfe\xb8qP\xff\xff\xff\xff\xff\xa8T@\x00\x00\x00\x00\x00\x98SP\x00\x00\x00\x00\x01\x886@\x00\x00\x00\x00\x02x5P\x00\x00\x00\x00\x03qR\xc0\x00\x00" +
-	"\x00\x00\x04aQ\xd0\x00\x00\x00\x00\x05Q4\xc0\x00\x00\x00\x00\x06A3\xd0\x00\x00\x00\x00\a1\x16\xc0\x00\x00\x00\x00\a\x8dm\xd0\x00\x00\x00\x00\t\x10\xf8\xc0\x00\x00\x00\x00\t\xad\xe9P\x00\x00\x00\x00\n\xf0" +
-	"\xda\xc0\x00\x00\x00\x00\v\xe0\xd9\xd0\x00\x00\x00\x00\f\xd9\xf7@\x00\x00\x00\x00\r\xc0\xbb\xd0\x00\x00\x00\x00\x0e\xb9\xd9@\x00\x00\x00\x00\x0f\xa9\xd8P\x00\x00\x00\x00\x10\x99\xbb@\x00\x00\x00\x00\x11\x89\xbaP\x00\x00" +
-	"\x00\x00\x12y\x9d@\x00\x00\x00\x00\x13i\x9cP\x00\x00\x00\x00\x14Y\x7f@\x00\x00\x00\x00\x15I~P\x00\x00\x00\x00\x169a@\x00\x00\x00\x00\x17)`P\x00\x00\x00\x00\x18\"}\xc0\x00\x00\x00\x00\x19\t" +
-	"BP\x00\x00\x00\x00\x1a\x02_\xc0\x00\x00\x00\x00\x1a+\" \x00\x00\x00\x00\x1a\xf2P\xc0\x00\x00\x00\x00\x1b\xe23\xb0\x00\x00\x00\x00\x1c\xd22\xc0\x00\x00\x00\x00\x1d\xc2\x15\xb0\x00\x00\x00\x00\x1e\xb2\x14\xc0\x00\x00" +
-	"\x00\x00\x1f\xa1\xf7\xb0\x00\x00\x00\x00 vG@\x00\x00\x00\x00!\x81ٰ\x00\x00\x00\x00\"V)@\x00\x00\x00\x00#j\xf60\x00\x00\x00\x00$6\v@\x00\x00\x00\x00%J\xd80\x00\x00\x00\x00&\x15" +
-	"\xed@\x00\x00\x00\x00'*\xba0\x00\x00\x00\x00'\xff\t\xc0\x00\x00\x00\x00)\n\x9c0\x00\x00\x00\x00)\xde\xeb\xc0\x00\x00\x00\x00*\xea~0\x00\x00\x00\x00+\xbe\xcd\xc0\x00\x00\x00\x00,Ӛ\xb0\x00\x00" +
-	"\x00\x00-\x9e\xaf\xc0\x00\x00\x00\x00.\xb3|\xb0\x00\x00\x00\x00/~\x91\xc0\x00\x00\x00\x000\x93^\xb0\x00\x00\x00\x001g\xae@\x00\x00\x00\x002s@\xb0\x00\x00\x00\x003G\x90@\x00\x00\x00\x004S" +
-	"\"\xb0\x00\x00\x00\x005'r@\x00\x00\x00\x0063\x04\xb0\x00\x00\x00\x007\aT@\x00\x00\x00\x008\x1c!0\x00\x00\x00\x008\xe76@\x00\x00\x00\x009\xfc\x030\x00\x00\x00\x00:\xc7\x18@\x00\x00" +
-	"\x00\x00;\xdb\xe50\x00\x00\x00\x00<\xb04\xc0\x00\x00\x00\x00=\xbb\xc70\x00\x00\x00\x00>\x90\x16\xc0\x00\x00\x00\x00?\x9b\xa90\x00\x00\x00\x00@o\xf8\xc0\x00\x00\x00\x00A\x84Ű\x00\x00\x00\x00BO" +
-	"\xda\xc0\x00\x00\x00\x00Cd\xa7\xb0\x00\x00\x00\x00D/\xbc\xc0\x00\x00\x00\x00ED\x89\xb0\x00\x00\x00\x00E\xf3\xef@\x01\x02\x03\x04\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" +
-	"\x06\x05\x06\x05\x06\x05\x06\x05\x06\a\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\x00\x00" +
-	"\xab\xe2\x00\x00\xff\xffZb\x00\x00\xff\xffeP\x00\x04\xff\xffs`\x01\b\xff\xffs`\x01\f\xff\xffeP\x00\x10\xff\xffs`\x01\x14\xff\xffs`\x00\x18\xff\xff\x81p\x01\x1d\xff\xffs`\x00\x19LM" +
-	"T\x00NST\x00NWT\x00NPT\x00BST\x00BDT\x00AHST\x00HDT\x00\nHST10HDT,M3.2.0,M11.1.0\nPK\x03\x04" +
-	"\n\x00\x00\x00\x00\x00\x8fj\xbeT錴$q\x03\x00\x00q\x03\x00\x00\x13\x00\x1c\x00America/Thunder_BayUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux" +
-	"\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00" +
-	"\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00N\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xffr\xee\x82,\xff\xff\xff\xff" +
-	"\x8f${\xe0\xff\xff\xff\xffˈ\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`" +
-	"\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\b \xc1p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\n\x00\xa3p\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xffi\x87&\x10\xff\xff\xff\xff\x8b\xf4a\xe8\x01\x02\xff\xff\xb5p\x00\x00\xff\xff\xb5\x18\x00\x04\xff\xff\xb9\xb0\x00\b" +
+	"LMT\x00CMT\x00EST\x00\nEST5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Š\xd6\x05W\x03\x00\x00W\x03\x00\x00\x13\x00\x00\x00America/Pang" +
+	"nirtungTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZ" +
+	"if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00J\x00\x00\x00\a\x00\x00\x00\x1c\xff\xff\xff\xff\xccl\xa1\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff" +
+	"\xff\xff\xd2`\xfb\xe0\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\a0\xc2`\x00\x00\x00\x00\b \xc1p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\n\x00" +
+	"\xa3p\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00\f٢\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00" +
+	"\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\"" +
+	")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x00\x00\x00\x00\x1a\xf2\np\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00" +
+	"\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\"U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15" +
+	"\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\nU\xe0\x00\x00\x00\x00)ޥp\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00" +
+	"\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R" +
+	"\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\a\r\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00" +
+	"\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO" +
+	"\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x04\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x06\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00\x00\x00\x00\x00\xff\xff\xc7\xc0\x01\x04" +
+	"\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\f\xff\xff\xc7\xc0\x01\x10\xff\xff\xab\xa0\x00\x14\xff\xff\xb9\xb0\x01\x18-00\x00EPT\x00EST\x00EDT\x00EWT\x00CST\x00CDT\x00\nE" +
+	"ST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\xf9\x1dɻ\x00\x00\x00\xbb\x00\x00\x00\x12\x00\x00\x00America/" +
+	"ParamariboTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" +
+	"\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x12\xff\xff\xff\xff\x91\x05\x8e\xb8\xff\xff\xff\xff\xbe*K" +
+	"\xc4\xff\xff\xff\xff\xd2b,\xb4\x00\x00\x00\x00\x1b\xbe1\xb8\x01\x02\x03\x04\xff\xff\xccH\x00\x00\xff\xff\xcc<\x00\x04\xff\xff\xccL\x00\x04\xff\xff\xce\xc8\x00\b\xff\xff\xd5\xd0\x00\x0eLMT\x00PMT\x00-" +
+	"0330\x00-03\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ø\xab\x9b\xf0\x00\x00\x00\xf0\x00\x00\x00\x0f\x00\x00\x00America/Phoen" +
+	"ixTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff^\x04\f\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\a" +
+	"\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xcf\x17\xdf\x1c\xff\xff\xff\xffϏ\xe5\xac\xff\xff\xff\xffЁ\x1a\x1c\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff" +
+	"\xff\xfb\xe8X\x00\x02\x01\x02\x01\x02\x03\x02\x03\x02\x01\x02\xff\xff\x96\xee\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\fLMT\x00MDT\x00MST\x00MWT\x00\nMST" +
+	"7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4T\xbd\xeb5\x02\x00\x005\x02\x00\x00\x16\x00\x00\x00America/Port-au-PrinceTZif2\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xffi\x87\x1fP\xff\xff\xff\xff\x9cnq\xfc\x00\x00\x00\x00\x19\x1bF\xd0\x00\x00\x00\x00\x1a\x01\xef" +
+	"@\x00\x00\x00\x00\x1a\xf1\xeeP\x00\x00\x00\x00\x1b\xe1\xd1@\x00\x00\x00\x00\x1c\xd1\xd0P\x00\x00\x00\x00\x1d\xc1\xb3@\x00\x00\x00\x00\x1e\xb1\xb2P\x00\x00\x00\x00\x1f\xa1\x95@\x00\x00\x00\x00 \x91\x94P\x00\x00\x00" +
+	"\x00!\x81w@\x00\x00\x00\x00\"U\xd4\xe0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xb6\xe0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\x98\xe0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xb5" +
+	"`\x00\x00\x00\x00)\nU\xe0\x00\x00\x00\x00)ޗ`\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbey`\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9e[`\x00\x00\x00\x00.\xb36`\x00\x00\x00" +
+	"\x00/~=`\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gY\xe0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003G;\xe0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x00BOxP\x00\x00\x00\x00CdE" +
+	"@\x00\x00\x00\x00D/ZP\x00\x00\x00\x00ED'@\x00\x00\x00\x00O\\Mp\x00\x00\x00\x00P\x96\x04`\x00\x00\x00\x00Q</p\x00\x00\x00\x00Ru\xe6`\x00\x00\x00\x00S\x1c\x11p\x00\x00\x00" +
+	"\x00TU\xc8`\x00\x00\x00\x00T\xfb\xf3p\x00\x00\x00\x00V5\xaa`\x00\x00\x00\x00X\xc4\xf1\xf0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\xff\xff\xbc0\x00\x00\xff\xff\xbcD\x00\x04\xff\xff\xc7\xc0\x01\t\xff\xff\xb9\xb0\x00\rLMT\x00PPMT\x00EDT\x00EST\x00\nEST5" +
+	"EDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x15\x00\x00\x00America/Por" +
+	"t_of_SpainTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" +
+	"\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62" +
+	"\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT" +
+	"\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\xf5K\x89\xa2\x01\x00\x00\xa2\x01\x00\x00\x12\x00\x00\x00America/Porto_AcreTZif2" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xff\x96\xaa\x86\x90\xff\xff\xff\xff\xb8\x0ff\x00\xff\xff\xff\xff\xb8\xfd\\\xc0\xff\xff\xff\xff\xb9\xf1" +
+	"PP\xff\xff\xff\xff\xbaސ@\xff\xff\xff\xff\xda8\xcaP\xff\xff\xff\xff\xda\xec\x16P\xff\xff\xff\xff\xdc\x19\xfd\xd0\xff\xff\xff\xffܹu@\xff\xff\xff\xff\xdd\xfb1P\xff\xff\xff\xffޛ\xfa@\xff\xff" +
+	"\xff\xff\xdfݶP\xff\xff\xff\xff\xe0TO@\xff\xff\xff\xff\xf4\x98\x1b\xd0\xff\xff\xff\xff\xf5\x05z@\xff\xff\xff\xff\xf6\xc0\x80P\xff\xff\xff\xff\xf7\x0e:\xc0\xff\xff\xff\xff\xf8QHP\xff\xff\xff\xff\xf8\xc7" +
+	"\xe1@\xff\xff\xff\xff\xfa\n\xee\xd0\xff\xff\xff\xff\xfa\xa9\x14\xc0\xff\xff\xff\xff\xfb\xec\"P\xff\xff\xff\xff\xfc\x8b\x99\xc0\x00\x00\x00\x00\x1dɪP\x00\x00\x00\x00\x1ex\xf3\xc0\x00\x00\x00\x00\x1f\xa0Q\xd0\x00\x00" +
+	"\x00\x00 3\xeb\xc0\x00\x00\x00\x00!\x81\x85P\x00\x00\x00\x00\"\v\xe4\xc0\x00\x00\x00\x00H`\x7fP\x00\x00\x00\x00R\x7f\x04\xc0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x03\x02\xff\xff\xc0p\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x00\x04LMT\x00-04\x00-05\x00\n<-05>5\nPK\x03\x04\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x1b\x81-\xa9\x8a\x01\x00\x00\x8a\x01\x00\x00\x13\x00\x00\x00America/Porto_VelhoTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaa\x82\xe8\xff\xff\xff\xff\xb8\x0fW\xf0\xff\xff\xff\xff\xb8\xfdN\xb0\xff\xff\xff\xff\xb9\xf1B@\xff\xff\xff\xff\xbaނ0\xff\xff\xff" +
+	"\xff\xda8\xbc@\xff\xff\xff\xff\xda\xec\b@\xff\xff\xff\xff\xdc\x19\xef\xc0\xff\xff\xff\xffܹg0\xff\xff\xff\xff\xdd\xfb#@\xff\xff\xff\xffޛ\xec0\xff\xff\xff\xff\xdfݨ@\xff\xff\xff\xff\xe0TA" +
+	"0\xff\xff\xff\xff\xf4\x98\r\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf6\xc0r@\xff\xff\xff\xff\xf7\x0e,\xb0\xff\xff\xff\xff\xf8Q:@\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xfa\n\xe0\xc0\xff\xff\xff" +
+	"\xff\xfa\xa9\x06\xb0\xff\xff\xff\xff\xfb\xec\x14@\xff\xff\xff\xff\xfc\x8b\x8b\xb0\x00\x00\x00\x00\x1dɜ@\x00\x00\x00\x00\x1ex\xe5\xb0\x00\x00\x00\x00\x1f\xa0C\xc0\x00\x00\x00\x00 3ݰ\x00\x00\x00\x00!\x81w" +
+	"@\x00\x00\x00\x00\"\vְ\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xc4\x18\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\bLMT\x00" +
+	"-03\x00-04\x00\n<-04>4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x13\x00\x00\x00America/Puerto" +
+	"_RicoTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif" +
+	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff" +
+	"\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST" +
+	"4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x13\x9b\xb1\xc2\x04\x00\x00\xc2\x04\x00\x00\x14\x00\x00\x00America/Punta_ArenasTZif2\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00u\x00\x00\x00\a\x00\x00\x00\x14\xff\xff\xff\xffi\x87\x1d\xfc\xff\xff\xff\xff\x8f0GE\xff\xff\xff\xff\x9b\\\xe5P\xff\xff\xff\xff\x9f|\xe2\xc5\xff" +
+	"\xff\xff\xff\xa1\x00q\xc0\xff\xff\xff\xff\xb0^w\xc5\xff\xff\xff\xff\xb1w=@\xff\xff\xff\xff\xb2A\x00\xd0\xff\xff\xff\xff\xb3Xp\xc0\xff\xff\xff\xff\xb4\"4P\xff\xff\xff\xff\xb59\xa4@\xff\xff\xff\xff\xb6" +
+	"\x03g\xd0\xff\xff\xff\xff\xb7\x1a\xd7\xc0\xff\xff\xff\xff\xb7\xe4\x9bP\xff\xff\xff\xff\xb8\xfd\\\xc0\xff\xff\xff\xff\xb9\xc7 P\xff\xff\xff\xff\xcc\x1cn@\xff\xff\xff\xff\xccl\xe7\xd0\xff\xff\xff\xff\xd4\x17\xe3@\xff" +
+	"\xff\xff\xff\xd53U\xc0\xff\xff\xff\xff\xd5v\x92@\xff\xff\xff\xff\xfd\xd1<@\xff\xff\xff\xff\xfe\x92\xfa\xb0\xff\xff\xff\xff\xff\xcc\xcd\xc0\x00\x00\x00\x00\x00rܰ\x00\x00\x00\x00\x01uP\xc0\x00\x00\x00\x00\x02" +
+	"@I\xb0\x00\x00\x00\x00\x03U2\xc0\x00\x00\x00\x00\x04 +\xb0\x00\x00\x00\x00\x05>O@\x00\x00\x00\x00\x06\x00\r\xb0\x00\x00\x00\x00\a\v\xbc@\x00\x00\x00\x00\a\xdf\xef\xb0\x00\x00\x00\x00\b\xfe\x13@\x00" +
+	"\x00\x00\x00\t\xbfѰ\x00\x00\x00\x00\n\xdd\xf5@\x00\x00\x00\x00\v\xa8\xee0\x00\x00\x00\x00\f\xbd\xd7@\x00\x00\x00\x00\r\x88\xd00\x00\x00\x00\x00\x0e\x9d\xb9@\x00\x00\x00\x00\x0fh\xb20\x00\x00\x00\x00\x10" +
+	"\x86\xd5\xc0\x00\x00\x00\x00\x11H\x940\x00\x00\x00\x00\x12f\xb7\xc0\x00\x00\x00\x00\x13(v0\x00\x00\x00\x00\x14F\x99\xc0\x00\x00\x00\x00\x15\x11\x92\xb0\x00\x00\x00\x00\x16&{\xc0\x00\x00\x00\x00\x16\xf1t\xb0\x00" +
+	"\x00\x00\x00\x18\x06]\xc0\x00\x00\x00\x00\x18\xd1V\xb0\x00\x00\x00\x00\x19\xe6?\xc0\x00\x00\x00\x00\x1a\xb18\xb0\x00\x00\x00\x00\x1b\xcf\\@\x00\x00\x00\x00\x1c\x91\x1a\xb0\x00\x00\x00\x00\x1d\xaf>@\x00\x00\x00\x00\x1e" +
+	"p\xfc\xb0\x00\x00\x00\x00\x1f\x8f @\x00\x00\x00\x00 \x7f\x030\x00\x00\x00\x00!o\x02@\x00\x00\x00\x00\"9\xfb0\x00\x00\x00\x00#N\xe4@\x00\x00\x00\x00$\x19\xdd0\x00\x00\x00\x00%8\x00\xc0\x00" +
+	"\x00\x00\x00%\xf9\xbf0\x00\x00\x00\x00&\xf2\xf8\xc0\x00\x00\x00\x00'١0\x00\x00\x00\x00(\xf7\xc4\xc0\x00\x00\x00\x00)½\xb0\x00\x00\x00\x00*צ\xc0\x00\x00\x00\x00+\xa2\x9f\xb0\x00\x00\x00\x00," +
+	"\xb7\x88\xc0\x00\x00\x00\x00-\x82\x81\xb0\x00\x00\x00\x00.\x97j\xc0\x00\x00\x00\x00/bc\xb0\x00\x00\x00\x000\x80\x87@\x00\x00\x00\x001BE\xb0\x00\x00\x00\x002`i@\x00\x00\x00\x003=\xd70\x00" +
+	"\x00\x00\x004@K@\x00\x00\x00\x005\vD0\x00\x00\x00\x006\r\xb8@\x00\x00\x00\x007\x06հ\x00\x00\x00\x008\x00\x0f@\x00\x00\x00\x008\xcb\b0\x00\x00\x00\x009\xe9+\xc0\x00\x00\x00\x00:" +
+	"\xaa\xea0\x00\x00\x00\x00;\xc9\r\xc0\x00\x00\x00\x00<\x8a\xcc0\x00\x00\x00\x00=\xa8\xef\xc0\x00\x00\x00\x00>j\xae0\x00\x00\x00\x00?\x88\xd1\xc0\x00\x00\x00\x00@Sʰ\x00\x00\x00\x00Ah\xb3\xc0\x00" +
+	"\x00\x00\x00B3\xac\xb0\x00\x00\x00\x00CH\x95\xc0\x00\x00\x00\x00D\x13\x8e\xb0\x00\x00\x00\x00E1\xb2@\x00\x00\x00\x00E\xf3p\xb0\x00\x00\x00\x00G\x11\x94@\x00\x00\x00\x00G\xef\x020\x00\x00\x00\x00H" +
+	"\xf1v@\x00\x00\x00\x00I\xbco0\x00\x00\x00\x00J\xd1X@\x00\x00\x00\x00K\xb8\x00\xb0\x00\x00\x00\x00L\xb1:@\x00\x00\x00\x00M\xc6\a0\x00\x00\x00\x00NP\x82\xc0\x00\x00\x00\x00O\x9c\xae\xb0\x00" +
+	"\x00\x00\x00PB\xd9\xc0\x00\x00\x00\x00Q|\x90\xb0\x00\x00\x00\x00R+\xf6@\x00\x00\x00\x00S\\r\xb0\x00\x00\x00\x00T\v\xd8@\x00\x00\x00\x00W7\xe60\x00\x00\x00\x00W\xaf\xec\xc0\x00\x00\x00\x00X" +
+	"C\x86\xb0\x01\x02\x01\x03\x01\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x03\x02\x03\x04\x02\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03" +
+	"\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x06" +
+	"\xff\xff\xbd\x84\x00\x00\xff\xff\xbd\xbb\x00\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x00\f\xff\xff\xc7\xc0\x01\f\xff\xff\xd5\xd0\x01\x10\xff\xff\xd5\xd0\x00\x10LMT\x00SMT\x00-05\x00-04\x00-0" +
+	"3\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?_p\x99\x0e\x05\x00\x00\x0e\x05\x00\x00\x13\x00\x00\x00America/Rainy_RiverT" +
+	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00}\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xffd䰔\xff\xff\xff\xff\x9b\x01\xfb\xe0\xff\xff\xff\xff\x9búP\xff\xff" +
+	"\xff\xff\x9e\xb8\xa1\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\u00a0;\x80\xff\xff\xff\xff\xc3O\x84\xf0\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xffӈ" +
+	"h\x00\xff\xff\xff\xff\xd4S`\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff" +
+	"\xff\xff\xdb\x00\a\x00\xff\xff\xff\xff\xdb\xc8\\\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90p\xff\xff\xff\xff\u07bey\x80\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1i" +
+	"Tp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5)\x18p\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe7\x124\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff" +
+	"\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xd6\xc4\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\ue47c\xf0\xff\xff\xff\xff\xf3o" +
+	"\xa4\x80\xff\xff\xff\xff\xf41b\xf0\xff\xff\xff\xff\xf9\x0fJ\x80\xff\xff\xff\xff\xfa\bv\x00\xff\xff\xff\xff\xfa\xf8g\x00\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff" +
+	"\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\r\x00\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\v\x80\x00\x00\x00\x00\x05P" +
+	"\xfc\x80\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\b π\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\n\x00\xb1\x80\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00" +
+	"\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13i" +
+	"V\x00\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02'\x80\x00\x00" +
+	"\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1܀\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81" +
+	"\xaf\x80\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeр\x00\x00" +
+	"\x00\x00)\nr\x00\x00\x00\x00\x00)\u07b3\x80\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~" +
+	"Y\x80\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005':\x00\x00\x00\x00\x0062ڀ\x00\x00" +
+	"\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb" +
+	"\x9d\x00\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x84\x80\x00\x00" +
+	"\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xa4\xec\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10LMT\x00CDT\x00CST" +
+	"\x00CWT\x00CPT\x00\nCST6CDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xdfH\r'\x03\x00\x00'\x03\x00\x00\x14" +
+	"\x00\x00\x00America/Rankin_InletTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00H\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff" +
+	"\xff\xff\xe7\x8cn\x00\x00\x00\x00\x00\x04a\v\x80\x00\x00\x00\x00\x05P\xeep\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\a0\xd0p\x00\x00\x00\x00\b π\x00\x00\x00\x00\t\x10\xb2p\x00\x00\x00\x00\n\x00" +
+	"\xb1\x80\x00\x00\x00\x00\n\xf0\x94p\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00\x00\x00\fٰ\xf0\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99t\xf0\x00\x00" +
+	"\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\"" +
+	"7p\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1܀\x00\x00" +
+	"\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00&\x15" +
+	"\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)\nc\xf0\x00\x00\x00\x00)\u07b3\x80\x00\x00\x00\x00*\xeaE\xf0\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3bp\x00\x00" +
+	"\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3Dp\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x93&p\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R" +
+	"\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xe0\x00\x00\x00" +
+	"\x00\x00;۬\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO" +
+	"\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00\x00\x00\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff" +
+	"\xab\xa0\x00\b\xff\xff\xb9\xb0\x00\f-00\x00CDT\x00CST\x00EST\x00\nCST6CDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\xbf\x03u\xf3\xe4\x01\x00\x00\xe4\x01\x00\x00\x0e\x00\x00\x00America/RecifeTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"'\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaag\xb8\xff\xff\xff\xff\xb8\x0fI\xe0\xff\xff\xff\xff\xb8\xfd@\xa0\xff\xff\xff\xff\xb9\xf140\xff\xff\xff\xff\xba\xdet \xff\xff\xff\xff\xda8\xae0\xff\xff\xff" +
+	"\xff\xda\xeb\xfa0\xff\xff\xff\xff\xdc\x19\xe1\xb0\xff\xff\xff\xffܹY \xff\xff\xff\xff\xdd\xfb\x150\xff\xff\xff\xffޛ\xde \xff\xff\xff\xff\xdfݚ0\xff\xff\xff\xff\xe0T3 \xff\xff\xff\xff\xf4\x97\xff" +
+	"\xb0\xff\xff\xff\xff\xf5\x05^ \xff\xff\xff\xff\xf6\xc0d0\xff\xff\xff\xff\xf7\x0e\x1e\xa0\xff\xff\xff\xff\xf8Q,0\xff\xff\xff\xff\xf8\xc7\xc5 \xff\xff\xff\xff\xfa\nҰ\xff\xff\xff\xff\xfa\xa8\xf8\xa0\xff\xff\xff" +
+	"\xff\xfb\xec\x060\xff\xff\xff\xff\xfc\x8b}\xa0\x00\x00\x00\x00\x1dɎ0\x00\x00\x00\x00\x1exנ\x00\x00\x00\x00\x1f\xa05\xb0\x00\x00\x00\x00 3Ϡ\x00\x00\x00\x00!\x81i0\x00\x00\x00\x00\"\v\xc8" +
+	"\xa0\x00\x00\x00\x00#X\x10\xb0\x00\x00\x00\x00#\xe2p \x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xd4\xc7 \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xb8\x85 \x00\x00\x00\x009\xdf\xe30\x00\x00\x00" +
+	"\x009\xe9\x0f\xa0\x00\x00\x00\x00;\xc8\xff\xb0\x00\x00\x00\x00<o\x0e\xa0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\xff\xff\xdfH\x00\x00\xff\xff\xe3\xe0\x01\x04\xff\xff\xd5\xd0\x00\bLMT\x00-02\x00-03\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\u0096dK~\x02\x00\x00" +
+	"~\x02\x00\x00\x0e\x00\x00\x00America/ReginaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff" +
+	"\xff\x86\xfd\x93\x1c\xff\xff\xff\xff\x9e\xb8\xaf\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xb5eO\xf0\xff\xff\xff\xff\xb60H\xe0\xff\xff\xff\xff\xb7E1\xf0\xff\xff\xff\xff\xb8\x10*\xe0\xff\xff\xff\xff\xb9%\x13" +
+	"\xf0\xff\xff\xff\xff\xb9\xf0\f\xe0\xff\xff\xff\xff\xbb\x0e0p\xff\xff\xff\xff\xbb\xcf\xee\xe0\xff\xff\xff\xff\xbc\xee\x12p\xff\xff\xff\xff\xbd\xb9\v`\xff\xff\xff\xff\xc2r\b\xf0\xff\xff\xff\xff\xc3a\xeb\xe0\xff\xff\xff" +
+	"\xff\xc4Q\xea\xf0\xff\xff\xff\xff\xc58\x93`\xff\xff\xff\xff\xc61\xcc\xf0\xff\xff\xff\xff\xc7!\xaf\xe0\xff\xff\xff\xff\xc8\x1a\xe9p\xff\xff\xff\xff\xc9\n\xcc`\xff\xff\xff\xff\xc9\xfa\xcbp\xff\xff\xff\xff\xca\xea\xae" +
+	"`\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xd3c\x8c\x10\xff\xff\xff\xff\xd4So\x00\xff\xff\xff\xff\xd5U\xe3\x10\xff\xff\xff\xff\xd6 \xdc\x00\xff\xff\xff" +
+	"\xff\xd75\xc5\x10\xff\xff\xff\xff\xd8\x00\xbe\x00\xff\xff\xff\xff\xd9\x15\xa7\x10\xff\xff\xff\xff\xd9\xe0\xa0\x00\xff\xff\xff\xff\xda\xfeÐ\xff\xff\xff\xff\xdb\xc0\x82\x00\xff\xff\xff\xff\xdcޥ\x90\xff\xff\xff\xffݩ\x9e" +
+	"\x80\xff\xff\xff\xff\u07be\x87\x90\xff\xff\xff\xff߉\x80\x80\xff\xff\xff\xff\xe0\x9ei\x90\xff\xff\xff\xff\xe1ib\x80\xff\xff\xff\xff\xe2~K\x90\xff\xff\xff\xff\xe3ID\x80\xff\xff\xff\xff\xe4^-\x90\xff\xff\xff" +
+	"\xff\xe5)&\x80\xff\xff\xff\xff\xe6GJ\x10\xff\xff\xff\xff\xe7\x12C\x00\xff\xff\xff\xff\xe8',\x10\xff\xff\xff\xff\xe8\xf2%\x00\xff\xff\xff\xff\xeb\xe6\xf0\x10\xff\xff\xff\xff\xec\xd6\xd3\x00\xff\xff\xff\xff\xed\xc6\xd2" +
+	"\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\xff\xff\x9d\xe4\x00\x00" +
+	"\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10\xff\xff\xab\xa0\x00\x14LMT\x00MDT\x00MST\x00MWT\x00MPT\x00CST\x00\nCST6\n" +
+	"PK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0I~D'\x03\x00\x00'\x03\x00\x00\x10\x00\x00\x00America/ResoluteTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00H\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\xd5\xfb\x81\x80\x00\x00\x00\x00\x04a\v\x80\x00\x00\x00\x00\x05P\xeep\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\a0\xd0" +
+	"p\x00\x00\x00\x00\b π\x00\x00\x00\x00\t\x10\xb2p\x00\x00\x00\x00\n\x00\xb1\x80\x00\x00\x00\x00\n\xf0\x94p\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00\x00\x00\fٰ\xf0\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00" +
+	"\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99t\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8" +
+	"\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\"7p\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00" +
+	"\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1܀\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd" +
+	"\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)\nc\xf0\x00\x00\x00\x00)\u07b3\x80\x00\x00\x00" +
+	"\x00*\xeaE\xf0\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3bp\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3Dp\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x93&p\x00\x00\x00\x001gv" +
+	"\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00" +
+	"\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00;۬\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp" +
+	"\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x03\x01\x00\x00\x00\x00\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x00\f-00\x00CDT\x00CST\x00EST\x00\nCST6CDT,M3" +
+	".2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\xf5K\x89\xa2\x01\x00\x00\xa2\x01\x00\x00\x12\x00\x00\x00America/Rio_Branc" +
+	"oTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xff\x96\xaa\x86\x90\xff\xff\xff\xff\xb8\x0ff\x00\xff\xff\xff\xff\xb8\xfd\\\xc0" +
+	"\xff\xff\xff\xff\xb9\xf1PP\xff\xff\xff\xff\xbaސ@\xff\xff\xff\xff\xda8\xcaP\xff\xff\xff\xff\xda\xec\x16P\xff\xff\xff\xff\xdc\x19\xfd\xd0\xff\xff\xff\xffܹu@\xff\xff\xff\xff\xdd\xfb1P\xff\xff\xff\xff" +
+	"ޛ\xfa@\xff\xff\xff\xff\xdfݶP\xff\xff\xff\xff\xe0TO@\xff\xff\xff\xff\xf4\x98\x1b\xd0\xff\xff\xff\xff\xf5\x05z@\xff\xff\xff\xff\xf6\xc0\x80P\xff\xff\xff\xff\xf7\x0e:\xc0\xff\xff\xff\xff\xf8QHP" +
+	"\xff\xff\xff\xff\xf8\xc7\xe1@\xff\xff\xff\xff\xfa\n\xee\xd0\xff\xff\xff\xff\xfa\xa9\x14\xc0\xff\xff\xff\xff\xfb\xec\"P\xff\xff\xff\xff\xfc\x8b\x99\xc0\x00\x00\x00\x00\x1dɪP\x00\x00\x00\x00\x1ex\xf3\xc0\x00\x00\x00\x00" +
+	"\x1f\xa0Q\xd0\x00\x00\x00\x00 3\xeb\xc0\x00\x00\x00\x00!\x81\x85P\x00\x00\x00\x00\"\v\xe4\xc0\x00\x00\x00\x00H`\x7fP\x00\x00\x00\x00R\x7f\x04\xc0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\xff\xff\xc0p\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x00\x04LMT\x00-04\x00-05\x00\n<-05>5\nP" +
+	"K\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xef\xf0R\x8a\xc4\x02\x00\x00\xc4\x02\x00\x00\x0f\x00\x00\x00America/RosarioTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xad\xb0\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff" +
+	"\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf" +
+	"\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff" +
+	"\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3" +
+	")5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff" +
+	"\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff" +
+	"\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00" +
+	"\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00G" +
+	"w\t\xb0\x00\x00\x00\x00G\xdc\x7f \x00\x00\x00\x00H\xfa\xa2\xb0\x00\x00\x00\x00I\xbca \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x04\x05\x04\x05\xff\xff\xc3\xd0\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff" +
+	"\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb9B$\x90\x01\x04\x00\x00\x01\x04\x00\x00\x14\x00" +
+	"\x00\x00America/Santa_IsabelTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00^\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff" +
+	"\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xa9yOp\xff\xff\xff\xff\xaf\xf2|\xf0\xff\xff\xff\xff\xb6fdp\xff\xff\xff\xff\xb7\x1b\x10\x00\xff\xff\xff\xff\xb8\n\xf2\xf0\xff\xff\xff\xff\xcbꍀ\xff\xff\xff\xff\xd2#\xf4" +
+	"p\xff\xff\xff\xffҙ\xbap\xff\xff\xff\xff\xd7\x1bY\x00\xff\xff\xff\xffؑ\xb4\xf0\xff\xff\xff\xff\xe2~K\x90\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4^-\x90\xff\xff\xff\xff\xe5)4\x90\xff\xff\xff" +
+	"\xff\xe6GJ\x10\xff\xff\xff\xff\xe7\x12Q\x10\xff\xff\xff\xff\xe8',\x10\xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff\xff\xea\a\x0e\x10\xff\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff\xff\xeb\xe6\xf0\x10\xff\xff\xff\xff\xec\xb1\xf7" +
+	"\x10\xff\xff\xff\xff\xed\xc6\xd2\x10\xff\xff\xff\xff\xee\x91\xd9\x10\x00\x00\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00" +
+	"\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6" +
+	" \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00" +
+	"\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1ې\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\"V\r \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc" +
+	"\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\n\x80\x10\x00\x00\x00\x00)\xdeϠ\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00" +
+	"\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt" +
+	" \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\a8 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00" +
+	"\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9" +
+	"\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00F\x0f\x82\xa0\x00\x00\x00\x00G$O\x90\x00\x00\x00\x00G\xf8\x9f \x00\x00\x00" +
+	"\x00I\x041\x90\x00\x00\x00\x00I\u0601 \x00\x00\x00\x00J\xe4\x13\x90\x00\x00\x00\x00K\x9c\xb3\xa0\x01\x02\x01\x02\x03\x02\x04\x05\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\xff\xff\x92L\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\x8f\x80\x00\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10\xff\xff\x9d\x90\x01\x14LMT\x00MST\x00PST\x00PDT\x00PWT\x00P" +
+	"PT\x00\nPST8PDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04,2h\x99\x01\x00\x00\x99\x01\x00\x00\x10\x00\x00\x00Ame" +
+	"rica/SantaremTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00" +
+	"\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1e\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xff\x96\xaazH\xff\xff\xff\xff" +
+	"\xb8\x0fW\xf0\xff\xff\xff\xff\xb8\xfdN\xb0\xff\xff\xff\xff\xb9\xf1B@\xff\xff\xff\xff\xbaނ0\xff\xff\xff\xff\xda8\xbc@\xff\xff\xff\xff\xda\xec\b@\xff\xff\xff\xff\xdc\x19\xef\xc0\xff\xff\xff\xffܹg0" +
+	"\xff\xff\xff\xff\xdd\xfb#@\xff\xff\xff\xffޛ\xec0\xff\xff\xff\xff\xdfݨ@\xff\xff\xff\xff\xe0TA0\xff\xff\xff\xff\xf4\x98\r\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf6\xc0r@\xff\xff\xff\xff" +
+	"\xf7\x0e,\xb0\xff\xff\xff\xff\xf8Q:@\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xfa\n\xe0\xc0\xff\xff\xff\xff\xfa\xa9\x06\xb0\xff\xff\xff\xff\xfb\xec\x14@\xff\xff\xff\xff\xfc\x8b\x8b\xb0\x00\x00\x00\x00\x1dɜ@" +
+	"\x00\x00\x00\x00\x1ex\xe5\xb0\x00\x00\x00\x00\x1f\xa0C\xc0\x00\x00\x00\x00 3ݰ\x00\x00\x00\x00!\x81w@\x00\x00\x00\x00\"\vְ\x00\x00\x00\x00H`q@\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\xff\xff̸\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x00\x04LMT\x00-03\x00-04\x00\n<-03>" +
+	"3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]\"_WJ\x05\x00\x00J\x05\x00\x00\x10\x00\x00\x00America/SantiagoTZif3\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x82\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffi\x87\x1d\xc5\xff\xff\xff\xff\x8f0GE\xff\xff\xff\xff\x9b\\\xe5P\xff\xff\xff\xff\x9f|\xe2\xc5\xff\xff\xff\xff\xa1" +
+	"\x00q\xc0\xff\xff\xff\xff\xb0^w\xc5\xff\xff\xff\xff\xb1w=@\xff\xff\xff\xff\xb2A\x00\xd0\xff\xff\xff\xff\xb3Xp\xc0\xff\xff\xff\xff\xb4\"4P\xff\xff\xff\xff\xb59\xa4@\xff\xff\xff\xff\xb6\x03g\xd0\xff" +
+	"\xff\xff\xff\xb7\x1a\xd7\xc0\xff\xff\xff\xff\xb7\xe4\x9bP\xff\xff\xff\xff\xb8\xfd\\\xc0\xff\xff\xff\xff\xb9\xc7 P\xff\xff\xff\xff\xcc\x1cn@\xff\xff\xff\xff\xccl\xe7\xd0\xff\xff\xff\xff\xd3\u070f\xc0\xff\xff\xff\xff\xd4" +
+	"\x17\xd50\xff\xff\xff\xff\xd53U\xc0\xff\xff\xff\xff\xd5v\x92@\xff\xff\xff\xff\xfd\xd1<@\xff\xff\xff\xff\xfe\x92\xfa\xb0\xff\xff\xff\xff\xff\xcc\xcd\xc0\x00\x00\x00\x00\x00rܰ\x00\x00\x00\x00\x01uP\xc0\x00" +
+	"\x00\x00\x00\x02@I\xb0\x00\x00\x00\x00\x03U2\xc0\x00\x00\x00\x00\x04 +\xb0\x00\x00\x00\x00\x05>O@\x00\x00\x00\x00\x06\x00\r\xb0\x00\x00\x00\x00\a\v\xbc@\x00\x00\x00\x00\a\xdf\xef\xb0\x00\x00\x00\x00\b" +
+	"\xfe\x13@\x00\x00\x00\x00\t\xbfѰ\x00\x00\x00\x00\n\xdd\xf5@\x00\x00\x00\x00\v\xa8\xee0\x00\x00\x00\x00\f\xbd\xd7@\x00\x00\x00\x00\r\x88\xd00\x00\x00\x00\x00\x0e\x9d\xb9@\x00\x00\x00\x00\x0fh\xb20\x00" +
+	"\x00\x00\x00\x10\x86\xd5\xc0\x00\x00\x00\x00\x11H\x940\x00\x00\x00\x00\x12f\xb7\xc0\x00\x00\x00\x00\x13(v0\x00\x00\x00\x00\x14F\x99\xc0\x00\x00\x00\x00\x15\x11\x92\xb0\x00\x00\x00\x00\x16&{\xc0\x00\x00\x00\x00\x16" +
+	"\xf1t\xb0\x00\x00\x00\x00\x18\x06]\xc0\x00\x00\x00\x00\x18\xd1V\xb0\x00\x00\x00\x00\x19\xe6?\xc0\x00\x00\x00\x00\x1a\xb18\xb0\x00\x00\x00\x00\x1b\xcf\\@\x00\x00\x00\x00\x1c\x91\x1a\xb0\x00\x00\x00\x00\x1d\xaf>@\x00" +
+	"\x00\x00\x00\x1ep\xfc\xb0\x00\x00\x00\x00\x1f\x8f @\x00\x00\x00\x00 \x7f\x030\x00\x00\x00\x00!o\x02@\x00\x00\x00\x00\"9\xfb0\x00\x00\x00\x00#N\xe4@\x00\x00\x00\x00$\x19\xdd0\x00\x00\x00\x00%" +
+	"8\x00\xc0\x00\x00\x00\x00%\xf9\xbf0\x00\x00\x00\x00&\xf2\xf8\xc0\x00\x00\x00\x00'١0\x00\x00\x00\x00(\xf7\xc4\xc0\x00\x00\x00\x00)½\xb0\x00\x00\x00\x00*צ\xc0\x00\x00\x00\x00+\xa2\x9f\xb0\x00" +
+	"\x00\x00\x00,\xb7\x88\xc0\x00\x00\x00\x00-\x82\x81\xb0\x00\x00\x00\x00.\x97j\xc0\x00\x00\x00\x00/bc\xb0\x00\x00\x00\x000\x80\x87@\x00\x00\x00\x001BE\xb0\x00\x00\x00\x002`i@\x00\x00\x00\x003" +
+	"=\xd70\x00\x00\x00\x004@K@\x00\x00\x00\x005\vD0\x00\x00\x00\x006\r\xb8@\x00\x00\x00\x007\x06հ\x00\x00\x00\x008\x00\x0f@\x00\x00\x00\x008\xcb\b0\x00\x00\x00\x009\xe9+\xc0\x00" +
+	"\x00\x00\x00:\xaa\xea0\x00\x00\x00\x00;\xc9\r\xc0\x00\x00\x00\x00<\x8a\xcc0\x00\x00\x00\x00=\xa8\xef\xc0\x00\x00\x00\x00>j\xae0\x00\x00\x00\x00?\x88\xd1\xc0\x00\x00\x00\x00@Sʰ\x00\x00\x00\x00A" +
+	"h\xb3\xc0\x00\x00\x00\x00B3\xac\xb0\x00\x00\x00\x00CH\x95\xc0\x00\x00\x00\x00D\x13\x8e\xb0\x00\x00\x00\x00E1\xb2@\x00\x00\x00\x00E\xf3p\xb0\x00\x00\x00\x00G\x11\x94@\x00\x00\x00\x00G\xef\x020\x00" +
+	"\x00\x00\x00H\xf1v@\x00\x00\x00\x00I\xbco0\x00\x00\x00\x00J\xd1X@\x00\x00\x00\x00K\xb8\x00\xb0\x00\x00\x00\x00L\xb1:@\x00\x00\x00\x00M\xc6\a0\x00\x00\x00\x00NP\x82\xc0\x00\x00\x00\x00O" +
+	"\x9c\xae\xb0\x00\x00\x00\x00PB\xd9\xc0\x00\x00\x00\x00Q|\x90\xb0\x00\x00\x00\x00R+\xf6@\x00\x00\x00\x00S\\r\xb0\x00\x00\x00\x00T\v\xd8@\x00\x00\x00\x00W7\xe60\x00\x00\x00\x00W\xaf\xec\xc0\x00" +
+	"\x00\x00\x00Y\x17\xc80\x00\x00\x00\x00Y\x8f\xce\xc0\x00\x00\x00\x00Z\xf7\xaa0\x00\x00\x00\x00[o\xb0\xc0\x00\x00\x00\x00\\\xa9g\xb0\x00\x00\x00\x00]t|\xc0\x00\x00\x00\x00^\x89I\xb0\x00\x00\x00\x00_" +
+	"T^\xc0\x00\x00\x00\x00`i+\xb0\x00\x00\x00\x00a4@\xc0\x00\x00\x00\x00bI\r\xb0\x00\x00\x00\x00c\x1d]@\x00\x00\x00\x00d(\xef\xb0\x01\x02\x01\x03\x01\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x03\x02" +
+	"\x03\x05\x04\x02\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05" +
+	"\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\xff\xff\xbd\xbb\x00\x00\xff" +
+	"\xff\xbd\xbb\x00\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x00\f\xff\xff\xc7\xc0\x01\f\xff\xff\xd5\xd0\x01\x10LMT\x00SMT\x00-05\x00-04\x00-03\x00\n<-04>4<-03" +
+	">,M9.1.6/24,M4.1.6/24\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\x0f(\b=\x01\x00\x00=\x01\x00\x00\x15\x00\x00\x00America/" +
+	"Santo_DomingoTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00" +
+	"\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x06\x00\x00\x00\x1b\xff\xff\xff\xffi\x87\x1d\b\xff\xff\xff\xff" +
+	"\xba\xdfB`\xff\xff\xff\xff\xfa\bK\xd0\xff\xff\xff\xff\xfa\xa7\xc3@\xff\xff\xff\xff\xff\xa7\xf1\xd0\x00\x00\x00\x00\x00C{\xc8\x00\x00\x00\x00\x01\x87\xd3\xd0\x00\x00\x00\x00\x01\xfa\x7fH\x00\x00\x00\x00\x03p\xf0P" +
+	"\x00\x00\x00\x00\x03\xdd\x04H\x00\x00\x00\x00\x05P\xd2P\x00\x00\x00\x00\x05\xbf\x89H\x00\x00\x00\x00\a0\xb4P\x00\x00\x00\x00\a\xa0\xbc\xc8\x00\x00\x00\x00\t\x10\x96P\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00" +
+	":)\xe1`\x01\x03\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x05\x03\x05\xff\xff\xbex\x00\x00\xff\xff\xbe`\x00\x04\xff\xff\xc7\xc0\x01\t\xff\xff\xb9\xb0\x00\r\xff\xff\xc0\xb8\x01\x11\xff\xff\xc7\xc0\x00\x17LMT" +
+	"\x00SDMT\x00EDT\x00EST\x00-0430\x00AST\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9d?\xdfڸ\x03\x00\x00\xb8\x03\x00\x00\x11\x00\x00\x00" +
+	"America/Sao_PauloTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" +
+	"\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00[\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaar\xb4" +
+	"\xff\xff\xff\xff\xb8\x0fI\xe0\xff\xff\xff\xff\xb8\xfd@\xa0\xff\xff\xff\xff\xb9\xf140\xff\xff\xff\xff\xba\xdet \xff\xff\xff\xff\xda8\xae0\xff\xff\xff\xff\xda\xeb\xfa0\xff\xff\xff\xff\xdc\x19\xe1\xb0\xff\xff\xff\xff" +
+	"ܹY \xff\xff\xff\xff\xdd\xfb\x150\xff\xff\xff\xffޛ\xde \xff\xff\xff\xff\xdfݚ0\xff\xff\xff\xff\xe0T3 \xff\xff\xff\xff\xf4Z\t0\xff\xff\xff\xff\xf5\x05^ \xff\xff\xff\xff\xf6\xc0d0" +
+	"\xff\xff\xff\xff\xf7\x0e\x1e\xa0\xff\xff\xff\xff\xf8Q,0\xff\xff\xff\xff\xf8\xc7\xc5 \xff\xff\xff\xff\xfa\nҰ\xff\xff\xff\xff\xfa\xa8\xf8\xa0\xff\xff\xff\xff\xfb\xec\x060\xff\xff\xff\xff\xfc\x8b}\xa0\x00\x00\x00\x00" +
+	"\x1dɎ0\x00\x00\x00\x00\x1exנ\x00\x00\x00\x00\x1f\xa05\xb0\x00\x00\x00\x00 3Ϡ\x00\x00\x00\x00!\x81i0\x00\x00\x00\x00\"\vȠ\x00\x00\x00\x00#X\x10\xb0\x00\x00\x00\x00#\xe2p " +
+	"\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xd4\xc7 \x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xbd\xe3\xa0\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\x94\x8b \x00\x00\x00\x00*\xea\r\xb0\x00\x00\x00\x00" +
+	"+k2\xa0\x00\x00\x00\x00,\xc0\xb50\x00\x00\x00\x00-f\xc4 \x00\x00\x00\x00.\xa0\x970\x00\x00\x00\x00/F\xa6 \x00\x00\x00\x000\x80y0\x00\x00\x00\x001\x1dM\xa0\x00\x00\x00\x002W \xb0" +
+	"\x00\x00\x00\x003\x06j \x00\x00\x00\x0048T0\x00\x00\x00\x004\xf8\xc1 \x00\x00\x00\x006 \x1f0\x00\x00\x00\x006\xcfh\xa0\x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xb8\x85 \x00\x00\x00\x00" +
+	"9\xdf\xe30\x00\x00\x00\x00:\x8f,\xa0\x00\x00\x00\x00;\xc8\xff\xb0\x00\x00\x00\x00<o\x0e\xa0\x00\x00\x00\x00=đ0\x00\x00\x00\x00>N\xf0\xa0\x00\x00\x00\x00?\x91\xfe0\x00\x00\x00\x00@.Ҡ" +
+	"\x00\x00\x00\x00A\x86\xf80\x00\x00\x00\x00B\x17\xef \x00\x00\x00\x00CQ\xc20\x00\x00\x00\x00C\xf7\xd1 \x00\x00\x00\x00EMS\xb0\x00\x00\x00\x00E\xe0\xed\xa0\x00\x00\x00\x00G\x11\x860\x00\x00\x00\x00" +
+	"G\xb7\x95 \x00\x00\x00\x00H\xfa\xa2\xb0\x00\x00\x00\x00I\x97w \x00\x00\x00\x00Jڄ\xb0\x00\x00\x00\x00K\x80\x93\xa0\x00\x00\x00\x00L\xbaf\xb0\x00\x00\x00\x00M`u\xa0\x00\x00\x00\x00N\x9aH\xb0" +
+	"\x00\x00\x00\x00OI\x92 \x00\x00\x00\x00P\x83e0\x00\x00\x00\x00Q 9\xa0\x00\x00\x00\x00RcG0\x00\x00\x00\x00S\x00\x1b\xa0\x00\x00\x00\x00TC)0\x00\x00\x00\x00T\xe98 \x00\x00\x00\x00" +
+	"V#\v0\x00\x00\x00\x00V\xc9\x1a \x00\x00\x00\x00X\x02\xed0\x00\x00\x00\x00X\xa8\xfc \x00\x00\x00\x00Y\xe2\xcf0\x00\x00\x00\x00Z\x88\xde \x00\x00\x00\x00[\xde`\xb0\x00\x00\x00\x00\\h\xc0 " +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xd4L\x00\x00\xff\xff\xe3\xe0\x01\x04\xff\xff\xd5\xd0\x00\bLMT\x00-02\x00-03" +
+	"\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:\x9a1T\xdf\x01\x00\x00\xdf\x01\x00\x00\x14\x00\x00\x00America/ScoresbysundT" +
+	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\"\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\x9b\x80L\x18\x00\x00\x00\x00\x13Mn@\x00\x00\x00\x00\x144$\xc0\x00\x00" +
+	"\x00\x00\x15#\xf9\xa0\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc" +
+	"\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00" +
+	"\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5" +
+	"\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00" +
+	"\x00\x001]\xd9\x10\x01\x02\x01\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\xff\xff\xebh\x00\x00\xff\xff\xe3\xe0\x00\x04\xff\xff\xf1\xf0\x01\b\xff\xff" +
+	"\xf1\xf0\x00\b\x00\x00\x00\x00\x01\fLMT\x00-02\x00-01\x00+00\x00\n<-01>1<+00>,M3.5.0/0,M10.5.0/1\nPK" +
+	"\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\x80\x94@\x12\x04\x00\x00\x12\x04\x00\x00\x10\x00\x00\x00America/ShiprockTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff^\x04\f\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff" +
+	"\xff\xff\xff\xa2e\xfe\x90\xff\xff\xff\xff\xa3\x84\x06\x00\xff\xff\xff\xff\xa4E\xe0\x90\xff\xff\xff\xff\xa4\x8f\xa6\x80\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xf7" +
+	"/v\x90\xff\xff\xff\xff\xf8(\x94\x00\xff\xff\xff\xff\xf9\x0fX\x90\xff\xff\xff\xff\xfa\bv\x00\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W\x10\xff\xff\xff\xff\xfd\xc8:\x00\xff" +
+	"\xff\xff\xff\xfe\xb89\x10\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x1b\x10\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xfd\x10\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05" +
+	"P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\a\x8d5\x90\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\t\xad\xb1\x10\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\vࡐ\x00" +
+	"\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13" +
+	"id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00\x00\x1a\x02'\x80\x00" +
+	"\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!" +
+	"\x81\xaf\x80\x00\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeߐ\x00" +
+	"\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/" +
+	"~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00" +
+	"\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=" +
+	"\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00" +
+	"\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\x9d\x94\x00\x00\xff\xff" +
+	"\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10LMT\x00MDT\x00MST\x00MWT\x00MPT\x00\nMST7MDT,M3.2.0,M1" +
+	"1.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81{\xc1\x92\xbc\x03\x00\x00\xbc\x03\x00\x00\r\x00\x00\x00America/SitkaTZif2\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S\x00\x00\x00\t\x00\x00\x00\"\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}\x873\x99\xff\xff\xff\xffˉ\x1a\xa0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff" +
+	"\xd2a&\x10\xff\xff\xff\xff\xfe\xb8G \xff\xff\xff\xff\xff\xa8*\x10\x00\x00\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88\f\x10\x00\x00\x00\x00\x02x\v \x00\x00\x00\x00\x03q(\x90\x00\x00\x00\x00\x04a'\xa0" +
+	"\x00\x00\x00\x00\x05Q\n\x90\x00\x00\x00\x00\x06A\t\xa0\x00\x00\x00\x00\a0\xec\x90\x00\x00\x00\x00\a\x8dC\xa0\x00\x00\x00\x00\t\x10ΐ\x00\x00\x00\x00\t\xad\xbf \x00\x00\x00\x00\n\xf0\xb0\x90\x00\x00\x00\x00" +
+	"\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10" +
+	"\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00" +
+	"\x1a\x025\x90\x00\x00\x00\x00\x1a+\x14\x10\x00\x00\x00\x00\x1a\xf2B\xb0\x00\x00\x00\x00\x1b\xe2%\xa0\x00\x00\x00\x00\x1c\xd2$\xb0\x00\x00\x00\x00\x1d\xc2\a\xa0\x00\x00\x00\x00\x1e\xb2\x06\xb0\x00\x00\x00\x00\x1f\xa1\xe9\xa0" +
+	"\x00\x00\x00\x00 v90\x00\x00\x00\x00!\x81ˠ\x00\x00\x00\x00\"V\x1b0\x00\x00\x00\x00#j\xe8 \x00\x00\x00\x00$5\xfd0\x00\x00\x00\x00%J\xca \x00\x00\x00\x00&\x15\xdf0\x00\x00\x00\x00" +
+	"'*\xac \x00\x00\x00\x00'\xfe\xfb\xb0\x00\x00\x00\x00)\n\x8e \x00\x00\x00\x00)\xdeݰ\x00\x00\x00\x00*\xeap \x00\x00\x00\x00+\xbe\xbf\xb0\x00\x00\x00\x00,ӌ\xa0\x00\x00\x00\x00-\x9e\xa1\xb0" +
+	"\x00\x00\x00\x00.\xb3n\xa0\x00\x00\x00\x00/~\x83\xb0\x00\x00\x00\x000\x93P\xa0\x00\x00\x00\x001g\xa00\x00\x00\x00\x002s2\xa0\x00\x00\x00\x003G\x820\x00\x00\x00\x004S\x14\xa0\x00\x00\x00\x00" +
+	"5'd0\x00\x00\x00\x0062\xf6\xa0\x00\x00\x00\x007\aF0\x00\x00\x00\x008\x1c\x13 \x00\x00\x00\x008\xe7(0\x00\x00\x00\x009\xfb\xf5 \x00\x00\x00\x00:\xc7\n0\x00\x00\x00\x00;\xdb\xd7 " +
+	"\x00\x00\x00\x00<\xb0&\xb0\x00\x00\x00\x00=\xbb\xb9 \x00\x00\x00\x00>\x90\b\xb0\x00\x00\x00\x00?\x9b\x9b \x00\x00\x00\x00@o\xea\xb0\x00\x00\x00\x00A\x84\xb7\xa0\x00\x00\x00\x00BO̰\x00\x00\x00\x00" +
+	"Cd\x99\xa0\x00\x00\x00\x00D/\xae\xb0\x00\x00\x00\x00ED{\xa0\x00\x00\x00\x00E\xf3\xe10\x01\x02\x03\x04\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05" +
+	"\x02\x05\x06\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\x00\x00ҧ\x00\x00\xff\xff\x81" +
+	"'\x00\x00\xff\xff\x8f\x80\x00\x04\xff\xff\x9d\x90\x01\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10\xff\xff\x81p\x00\x14\xff\xff\x8f\x80\x01\x18\xff\xff\x81p\x00\x1dLMT\x00PST\x00PWT\x00PPT" +
+	"\x00PDT\x00YST\x00AKDT\x00AKST\x00\nAKST9AKDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q" +
+	"\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x15\x00\x00\x00America/St_BarthelemyTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff" +
+	"\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00~\xb2\x0e\x19V\a\x00\x00V\a\x00\x00\x10" +
+	"\x00\x00\x00America/St_JohnsTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00" +
+	"\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbb\x00\x00\x00\b\x00\x00\x00\x19\xff\xff\xff\xff^=" +
+	"4\xec\xff\xff\xff\xff\x9c\xcfb\f\xff\xff\xff\xff\x9d\xa4\xe6\xfc\xff\xff\xff\xff\x9e\xb8~\x8c\xff\xff\xff\xff\x9f\xba\xd6|\xff\xff\xff\xff\xa0\xb6\x88\xdc\xff\xff\xff\xff\xa18\xffL\xff\xff\xff\xff\xa2\x95\x19\\\xff\xff" +
+	"\xff\xff\xa3\x84\xfcL\xff\xff\xff\xff\xa4t\xfb\\\xff\xff\xff\xff\xa5d\xdeL\xff\xff\xff\xff\xa6^\x17\xdc\xff\xff\xff\xff\xa7D\xc0L\xff\xff\xff\xff\xa8=\xf9\xdc\xff\xff\xff\xff\xa9$\xa2L\xff\xff\xff\xff\xaa\x1d" +
+	"\xdb\xdc\xff\xff\xff\xff\xab\x04\x84L\xff\xff\xff\xff\xab\xfd\xbd\xdc\xff\xff\xff\xff\xac\xe4fL\xff\xff\xff\xff\xadݟ\xdc\xff\xff\xff\xff\xae͂\xcc\xff\xff\xff\xff\xaf\xbd\x81\xdc\xff\xff\xff\xff\xb0\xadd\xcc\xff\xff" +
+	"\xff\xff\xb1\xa6\x9e\\\xff\xff\xff\xff\xb2\x8dF\xcc\xff\xff\xff\xff\xb3\x86\x80\\\xff\xff\xff\xff\xb4m(\xcc\xff\xff\xff\xff\xb5fb\\\xff\xff\xff\xff\xb6M\n\xcc\xff\xff\xff\xff\xb7FD\\\xff\xff\xff\xff\xb8," +
+	"\xec\xcc\xff\xff\xff\xff\xb9&&\\\xff\xff\xff\xff\xba\x16\tL\xff\xff\xff\xff\xbb\x0fB\xdc\xff\xff\xff\xff\xbb\xf5\xebL\xff\xff\xff\xff\xbc\xef$\xdc\xff\xff\xff\xff\xbd\xd5\xcdL\xff\xff\xff\xff\xbe\x9eMl\xff\xff" +
+	"\xff\xff\xbe\xcf\x06\xa8\xff\xff\xff\xff\xbf\xb5\xaf\x18\xff\xff\xff\xff\xc0\xb818\xff\xff\xff\xff\xc1y\xef\xa8\xff\xff\xff\xff\u0098\x138\xff\xff\xff\xff\xc3YѨ\xff\xff\xff\xff\xc4w\xf58\xff\xff\xff\xff\xc59" +
+	"\xb3\xa8\xff\xff\xff\xff\xc6a\x11\xb8\xff\xff\xff\xff\xc7\x19\x95\xa8\xff\xff\xff\xff\xc8@\xf3\xb8\xff\xff\xff\xff\xc9\x02\xb2(\xff\xff\xff\xff\xca ո\xff\xff\xff\xff\xca\xe2\x94(\xff\xff\xff\xff\xcc\x00\xb7\xb8\xff\xff" +
+	"\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xe6\xc8\xff\xff\xff\xffӈD\xd8\xff\xff\xff\xff\xd4J\x03H\xff\xff\xff\xff\xd5h&\xd8\xff\xff\xff\xff\xd6)\xe5H\xff\xff\xff\xff\xd7H\b\xd8\xff\xff\xff\xff\xd8\t" +
+	"\xc7H\xff\xff\xff\xff\xd9'\xea\xd8\xff\xff\xff\xff\xd9\xe9\xa9H\xff\xff\xff\xff\xdb\x11\aX\xff\xff\xff\xff\xdb\xd2\xc5\xc8\xff\xff\xff\xff\xdc\xdetX\xff\xff\xff\xffݩmH\xff\xff\xff\xff\u07beVX\xff\xff" +
+	"\xff\xff߉OH\xff\xff\xff\xff\xe0\x9e8X\xff\xff\xff\xff\xe1i1H\xff\xff\xff\xff\xe2~\x1aX\xff\xff\xff\xff\xe3I\x13H\xff\xff\xff\xff\xe4]\xfcX\xff\xff\xff\xff\xe5(\xf5H\xff\xff\xff\xff\xe6G" +
+	"\x18\xd8\xff\xff\xff\xff\xe7\x12\x11\xc8\xff\xff\xff\xff\xe8&\xfa\xd8\xff\xff\xff\xff\xe8\xf1\xf3\xc8\xff\xff\xff\xff\xea\x06\xdc\xd8\xff\xff\xff\xff\xea\xd1\xd5\xc8\xff\xff\xff\xff\xeb\xe6\xbe\xd8\xff\xff\xff\xff챷\xc8\xff\xff" +
+	"\xff\xff\xedƠ\xd8\xff\xff\xff\xff\ueffeH\xff\xff\xff\xffﯽX\xff\xff\xff\xff\xf0\x9f\xa0H\xff\xff\xff\xff\xf1\x8f\x9fX\xff\xff\xff\xff\xf2\x7f\x82H\xff\xff\xff\xff\xf3o\x81X\xff\xff\xff\xff\xf4_" +
+	"dH\xff\xff\xff\xff\xf5OcX\xff\xff\xff\xff\xf6?FH\xff\xff\xff\xff\xf7/EX\xff\xff\xff\xff\xf8(b\xc8\xff\xff\xff\xff\xf9\x0f'X\xff\xff\xff\xff\xfa\bD\xc8\xff\xff\xff\xff\xfa\xf8C\xd8\xff\xff" +
+	"\xff\xff\xfb\xe8&\xc8\xff\xff\xff\xff\xfc\xd8%\xd8\xff\xff\xff\xff\xfd\xc8\b\xc8\xff\xff\xff\xff\xfe\xb8\a\xd8\xff\xff\xff\xff\xff\xa7\xea\xc8\x00\x00\x00\x00\x00\x97\xe9\xd8\x00\x00\x00\x00\x01\x87\xcc\xc8\x00\x00\x00\x00\x02w" +
+	"\xcb\xd8\x00\x00\x00\x00\x03p\xe9H\x00\x00\x00\x00\x04`\xe8X\x00\x00\x00\x00\x05P\xcbH\x00\x00\x00\x00\x06@\xcaX\x00\x00\x00\x00\a0\xadH\x00\x00\x00\x00\b \xacX\x00\x00\x00\x00\t\x10\x8fH\x00\x00" +
+	"\x00\x00\n\x00\x8eX\x00\x00\x00\x00\n\xf0qH\x00\x00\x00\x00\v\xe0pX\x00\x00\x00\x00\fٍ\xc8\x00\x00\x00\x00\r\xc0RX\x00\x00\x00\x00\x0e\xb9o\xc8\x00\x00\x00\x00\x0f\xa9n\xd8\x00\x00\x00\x00\x10\x99" +
+	"Q\xc8\x00\x00\x00\x00\x11\x89P\xd8\x00\x00\x00\x00\x12y3\xc8\x00\x00\x00\x00\x13i2\xd8\x00\x00\x00\x00\x14Y\x15\xc8\x00\x00\x00\x00\x15I\x14\xd8\x00\x00\x00\x00\x168\xf7\xc8\x00\x00\x00\x00\x17(\xf6\xd8\x00\x00" +
+	"\x00\x00\x18\"\x14H\x00\x00\x00\x00\x19\b\xd8\xd8\x00\x00\x00\x00\x1a\x01\xf6H\x00\x00\x00\x00\x1a\xf1\xf5X\x00\x00\x00\x00\x1b\xe1\xd8H\x00\x00\x00\x00\x1c\xd1\xd7X\x00\x00\x00\x00\x1d\xc1\xbaH\x00\x00\x00\x00\x1e\xb1" +
+	"\xb9X\x00\x00\x00\x00\x1f\xa1\x9cH\x00\x00\x00\x00 u\xcf\xf4\x00\x00\x00\x00!\x81bd\x00\x00\x00\x00\"U\xb1\xf4\x00\x00\x00\x00#jp\xd4\x00\x00\x00\x00$5\x93\xf4\x00\x00\x00\x00%J`\xe4\x00\x00" +
+	"\x00\x00&\x15u\xf4\x00\x00\x00\x00'*B\xe4\x00\x00\x00\x00'\xfe\x92t\x00\x00\x00\x00)\n$\xe4\x00\x00\x00\x00)\xdett\x00\x00\x00\x00*\xea\x06\xe4\x00\x00\x00\x00+\xbeVt\x00\x00\x00\x00,\xd3" +
+	"#d\x00\x00\x00\x00-\x9e8t\x00\x00\x00\x00.\xb3\x05d\x00\x00\x00\x00/~\x1at\x00\x00\x00\x000\x92\xe7d\x00\x00\x00\x001g6\xf4\x00\x00\x00\x002r\xc9d\x00\x00\x00\x003G\x18\xf4\x00\x00" +
+	"\x00\x004R\xabd\x00\x00\x00\x005&\xfa\xf4\x00\x00\x00\x0062\x8dd\x00\x00\x00\x007\x06\xdc\xf4\x00\x00\x00\x008\x1b\xa9\xe4\x00\x00\x00\x008\xe6\xbe\xf4\x00\x00\x00\x009\xfb\x8b\xe4\x00\x00\x00\x00:\xc6" +
+	"\xa0\xf4\x00\x00\x00\x00;\xdbm\xe4\x00\x00\x00\x00<\xaf\xbdt\x00\x00\x00\x00=\xbbO\xe4\x00\x00\x00\x00>\x8f\x9ft\x00\x00\x00\x00?\x9b1\xe4\x00\x00\x00\x00@o\x81t\x00\x00\x00\x00A\x84Nd\x00\x00" +
+	"\x00\x00BOct\x00\x00\x00\x00Cd0d\x00\x00\x00\x00D/Et\x00\x00\x00\x00ED\x12d\x00\x00\x00\x00E\xf3w\xf4\x00\x00\x00\x00G-.\xe4\x00\x00\x00\x00G\xd3Y\xf4\x00\x00\x00\x00I\r" +
+	"\x10\xe4\x00\x00\x00\x00I\xb3;\xf4\x00\x00\x00\x00J\xec\xf2\xe4\x00\x00\x00\x00K\x9cXt\x00\x00\x00\x00L\xd6\x0fd\x00\x00\x00\x00M|:t\x00\x00\x00\x00N\xb6\rH\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x06\x05\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" +
+	"\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" +
+	"\x04\x03\x04\x03\x04\x03\x04\x03\x04\a\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\xff\xff\xce" +
+	"\x94\x00\x00\xff\xffܤ\x01\x04\xff\xffΔ\x00\b\xff\xff\xdc\xd8\x01\x04\xff\xff\xce\xc8\x00\b\xff\xff\xdc\xd8\x01\f\xff\xff\xdc\xd8\x01\x10\xff\xff\xea\xe8\x01\x14LMT\x00NDT\x00NST\x00NPT" +
+	"\x00NWT\x00NDDT\x00\nNST3:30NDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1" +
+	"\x00\x00\x00\x10\x00\x00\x00America/St_KittsTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff" +
+	"\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLM" +
+	"T\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x00\x00America/St" +
+	"_LuciaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZi" +
+	"f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff" +
+	"\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAS" +
+	"T4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x11\x00\x00\x00America/St_ThomasTZif2\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02" +
+	"\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x12\x00\x00\x00America/St_VincentTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff" +
+	"\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\xd8\x19\x9dp\x01\x00\x00p\x01\x00\x00\x15\x00" +
+	"\x00\x00America/Swift_CurrentTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff" +
+	"\xff\xff\x86\xfd\x96\x18\xff\xff\xff\xff\x9e\xb8\xaf\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xd3v\x01\x10\xff\xff\xff\xff\xd4S" +
+	"o\x00\xff\xff\xff\xff\xd5U\xe3\x10\xff\xff\xff\xff\xd6 \xdc\x00\xff\xff\xff\xff\xd75\xc5\x10\xff\xff\xff\xff\xd8\x00\xbe\x00\xff\xff\xff\xff\xd9\x15\xa7\x10\xff\xff\xff\xff\xd9\xe0\xa0\x00\xff\xff\xff\xff\xe8',\x10\xff\xff" +
+	"\xff\xff\xe9\x17\x0f\x00\xff\xff\xff\xff\xeb\xe6\xf0\x10\xff\xff\xff\xff\xec\xd6\xd3\x00\xff\xff\xff\xff\xed\xc6\xd2\x10\xff\xff\xff\xff\xee\x91\xcb\x00\xff\xff\xff\xff\xef\xaf\xee\x90\xff\xff\xff\xff\xf0q\xad\x00\x00\x00\x00\x00\x04a" +
+	"\x19\x90\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\xff\xff\x9a\xe8\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10\xff\xff\xab\xa0\x00" +
+	"\x14LMT\x00MDT\x00MST\x00MWT\x00MPT\x00CST\x00\nCST6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x82\x13z\xe2\xc2\x00\x00\x00\xc2\x00\x00\x00\x13\x00\x00" +
+	"\x00America/TegucigalpaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" +
+	"\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\xa4" +
+	"LKD\x00\x00\x00\x00 \x9a\xdc\xe0\x00\x00\x00\x00!\\\x9bP\x00\x00\x00\x00\"z\xbe\xe0\x00\x00\x00\x00#<}P\x00\x00\x00\x00D]\x8c\xe0\x00\x00\x00\x00D\xd6\xc8\xd0\x02\x01\x02\x01\x02\x01\x02\xff\xff" +
+	"\xae<\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\bLMT\x00CDT\x00CST\x00\nCST6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00U\r\xf7\xd3\xc7\x01\x00\x00\xc7\x01\x00\x00" +
+	"\r\x00\x00\x00America/ThuleTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" +
+	"\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\"\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x9b\x80w\xfc" +
+	"\x00\x00\x00\x00'\xf5z\xe0\x00\x00\x00\x00(\xe5]\xd0\x00\x00\x00\x00)\xd5\\\xe0\x00\x00\x00\x00*\xc5?\xd0\x00\x00\x00\x00+\xbey`\x00\x00\x00\x00,\xd3FP\x00\x00\x00\x00-\x9e[`\x00\x00\x00\x00" +
+	".\xb3(P\x00\x00\x00\x00/~=`\x00\x00\x00\x000\x93\nP\x00\x00\x00\x001gY\xe0\x00\x00\x00\x002r\xecP\x00\x00\x00\x003G;\xe0\x00\x00\x00\x004R\xceP\x00\x00\x00\x005'\x1d\xe0" +
+	"\x00\x00\x00\x0062\xb0P\x00\x00\x00\x007\x06\xff\xe0\x00\x00\x00\x008\x1b\xcc\xd0\x00\x00\x00\x008\xe6\xe1\xe0\x00\x00\x00\x009\xfb\xae\xd0\x00\x00\x00\x00:\xc6\xc3\xe0\x00\x00\x00\x00;ې\xd0\x00\x00\x00\x00" +
+	"<\xaf\xe0`\x00\x00\x00\x00=\xbbr\xd0\x00\x00\x00\x00>\x8f\xc2`\x00\x00\x00\x00?\x9bT\xd0\x00\x00\x00\x00@o\xa4`\x00\x00\x00\x00A\x84qP\x00\x00\x00\x00BO\x86`\x00\x00\x00\x00CdSP" +
+	"\x00\x00\x00\x00D/h`\x00\x00\x00\x00ED5P\x00\x00\x00\x00E\xf3\x9a\xe0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff" +
+	"\xbf\x84\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\bLMT\x00ADT\x00AST\x00\nAST4ADT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00ӿ\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00\x13\x00\x00\x00America/Thunder_BayTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\xac\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xffr\xeex\xec\xff\xff\xff\xff\x9e\xb8\x93p\xff\xff\xff\xff\x9f\xba\xeb`\xff\xff\xff\xff\xa0\x87.\xc8\xff\xff\xff\xff\xa1\x9a\xb1@\xff\xff\xff\xff" +
+	"\xa2\x94\x06\xf0\xff\xff\xff\xff\xa3U\xa9@\xff\xff\xff\xff\xa4\x86]\xf0\xff\xff\xff\xff\xa5(x`\xff\xff\xff\xff\xa6f?\xf0\xff\xff\xff\xff\xa7\fN\xe0\xff\xff\xff\xff\xa8F!\xf0\xff\xff\xff\xff\xa8\xec0\xe0" +
+	"\xff\xff\xff\xff\xaa\x1c\xc9p\xff\xff\xff\xff\xaa\xd5M`\xff\xff\xff\xff\xab\xfc\xabp\xff\xff\xff\xff\xac\xb5/`\xff\xff\xff\xff\xad܍p\xff\xff\xff\xff\xae\x95\x11`\xff\xff\xff\xff\xaf\xbcop\xff\xff\xff\xff" +
+	"\xb0~-\xe0\xff\xff\xff\xff\xb1\x9cQp\xff\xff\xff\xff\xb2gJ`\xff\xff\xff\xff\xb3|3p\xff\xff\xff\xff\xb4G,`\xff\xff\xff\xff\xb5\\\x15p\xff\xff\xff\xff\xb6'\x0e`\xff\xff\xff\xff\xb7;\xf7p" +
+	"\xff\xff\xff\xff\xb8\x06\xf0`\xff\xff\xff\xff\xb9%\x13\xf0\xff\xff\xff\xff\xb9\xe6\xd2`\xff\xff\xff\xff\xbb\x04\xf5\xf0\xff\xff\xff\xff\xbb\xcf\xee\xe0\xff\xff\xff\xff\xbc\xe4\xd7\xf0\xff\xff\xff\xff\xbd\xaf\xd0\xe0\xff\xff\xff\xff" +
+	"\xbeĹ\xf0\xff\xff\xff\xff\xbf\x8f\xb2\xe0\xff\xff\xff\xff\xc0\xa4\x9b\xf0\xff\xff\xff\xff\xc1o\x94\xe0\xff\xff\xff\xff\u0084}\xf0\xff\xff\xff\xff\xc3Ov\xe0\xff\xff\xff\xff\xc4d_\xf0\xff\xff\xff\xff\xc5/X\xe0" +
+	"\xff\xff\xff\xff\xc6M|p\xff\xff\xff\xff\xc7\x0f:\xe0\xff\xff\xff\xff\xc8-^p\xff\xff\xff\xffˈ\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff\xd3u\xe4\xf0\xff\xff\xff\xff" +
+	"\xd4@\xdd\xe0\xff\xff\xff\xff\xd5U\xaa\xd0\xff\xff\xff\xff\xd6 \xa3\xc0\xff\xff\xff\xff\xd75\x8c\xd0\xff\xff\xff\xff\xd8\x00\x85\xc0\xff\xff\xff\xff\xd9\x15n\xd0\xff\xff\xff\xff\xda3v@\xff\xff\xff\xff\xda\xfe\xa7p" +
+	"\xff\xff\xff\xff\xdc\x13t`\xff\xff\xff\xff\xdcމp\xff\xff\xff\xffݩ\x82`\xff\xff\xff\xff\u07bekp\xff\xff\xff\xff߉d`\xff\xff\xff\xff\xe0\x9eMp\xff\xff\xff\xff\xe1iF`\xff\xff\xff\xff" +
+	"\xe2~/p\xff\xff\xff\xff\xe3I(`\xff\xff\xff\xff\xe4^\x11p\xff\xff\xff\xff\xe5)\n`\xff\xff\xff\xff\xe6G-\xf0\xff\xff\xff\xff\xe7\x12&\xe0\xff\xff\xff\xff\xe8'\x0f\xf0\xff\xff\xff\xff\xe9\x16\xf2\xe0" +
+	"\xff\xff\xff\xff\xea\x06\xf1\xf0\xff\xff\xff\xff\xea\xf6\xd4\xe0\xff\xff\xff\xff\xeb\xe6\xd3\xf0\xff\xff\xff\xff\xecֶ\xe0\xff\xff\xff\xff\xedƵ\xf0\xff\xff\xff\xff\xee\xbf\xd3`\xff\xff\xff\xff\xef\xaf\xd2p\xff\xff\xff\xff" +
+	"\xf0\x9f\xb5`\xff\xff\xff\xff\xf1\x8f\xb4p\xff\xff\xff\xff\xf2\x7f\x97`\xff\xff\xff\xff\xf3o\x96p\xff\xff\xff\xff\xf4_y`\xff\xff\xff\xff\xf5Oxp\xff\xff\xff\xff\xf6?[`\xff\xff\xff\xff\xf7/Zp" +
+	"\xff\xff\xff\xff\xf8(w\xe0\xff\xff\xff\xff\xf9\x0f<p\xff\xff\xff\xff\xfa\bY\xe0\xff\xff\xff\xff\xfa\xf8X\xf0\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\xff\xff\xff\xff" +
+	"\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`" +
+	"\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\a0\xc2`\x00\x00\x00\x00\b \xc1p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\n\x00\xa3p\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00" +
 	"\f٢\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0" +
 	"\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x00\x00\x00\x00" +
 	"\x1a\xf2\np\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`" +
@@ -2308,196 +2222,887 @@
 	"\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x00" +
 	"7\a\r\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0" +
 	"\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00" +
-	"EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x01\x02\x03\x04\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05" +
-	"\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\xff\xff\xacT\x00\x00\xff\xff\xab\xa0\x00\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\f\xff\xff\xc7\xc0\x01\x10" +
-	"\xff\xff\xc7\xc0\x01\x14LMT\x00CST\x00EST\x00EWT\x00EPT\x00EDT\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00" +
-	"\x00\x00\x00\x00\x8fj\xbeTq\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\r\x00\x1c\x00America/ArubaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00" +
-	"\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif" +
-	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff" +
-	"\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST" +
-	"4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xf6@\rm\xa8\x05\x00\x00\xa8\x05\x00\x00\x13\x00\x1c\x00America/Fort_NelsonUT\t\x00\x03\xdd\xfc\x94b" +
-	"\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00" +
-	"\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8f\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff^=" +
-	"v\x87\xff\xff\xff\xff\x9e\xb8\xbd\xa0\xff\xff\xff\xff\x9f\xbb\x15\x90\xff\xff\xff\xffˉ\x1a\xa0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a&\x10\xff\xff\xff\xff\xd5U\xf1 \xff\xff\xff\xff\xd6 \xea\x10\xff\xff" +
-	"\xff\xff\xd75\xd3 \xff\xff\xff\xff\xd8\x00\xcc\x10\xff\xff\xff\xff\xd9\x15\xb5 \xff\xff\xff\xff\xd9\xe0\xae\x10\xff\xff\xff\xff\xda\xfeѠ\xff\xff\xff\xff\xdb\xc0\x90\x10\xff\xff\xff\xff\xdc\u07b3\xa0\xff\xff\xff\xffݩ" +
-	"\xac\x90\xff\xff\xff\xff\u07be\x95\xa0\xff\xff\xff\xff߉\x8e\x90\xff\xff\xff\xff\xe0\x9ew\xa0\xff\xff\xff\xff\xe1ip\x90\xff\xff\xff\xff\xe2~Y\xa0\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4^;\xa0\xff\xff" +
-	"\xff\xff\xe5)4\x90\xff\xff\xff\xff\xe6GX \xff\xff\xff\xff\xe7\x12Q\x10\xff\xff\xff\xff\xe8': \xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff\xff\xea\a\x1c \xff\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff\xff\xeb\xe6" +
-	"\xfe \xff\xff\xff\xff\xec\xb1\xf7\x10\xff\xff\xff\xff\xed\xc6\xe0 \xff\xff\xff\xff\xee\x91\xd9\x10\xff\xff\xff\xff\xef\xaf\xfc\xa0\xff\xff\xff\xff\xf0q\xbb\x10\xff\xff\xff\xff\xf1\x8fޠ\xff\xff\xff\xff\xf2\x7f\xc1\x90\xff\xff" +
-	"\xff\xff\xf3o\xc0\xa0\xff\xff\xff\xff\xf4_\xa3\x90\xff\xff\xff\xff\xf5O\xa2\xa0\xff\xff\xff\xff\xf6?\x85\x90\xff\xff\xff\xff\xf7/\x84\xa0\xff\xff\xff\xff\xf8(\xa2\x10\xff\xff\xff\xff\xf9\x0ff\xa0\xff\xff\xff\xff\xfa\b" +
-	"\x84\x10\xff\xff\xff\xff\xfa\xf8\x83 \xff\xff\xff\xff\xfb\xe8f\x10\xff\xff\xff\xff\xfc\xd8e \xff\xff\xff\xff\xfd\xc8H\x10\xff\xff\xff\xff\xfe\xb8G \xff\xff\xff\xff\xff\xa8*\x10\x00\x00\x00\x00\x00\x98) \x00\x00" +
-	"\x00\x00\x01\x88\f\x10\x00\x00\x00\x00\x02x\v \x00\x00\x00\x00\x03q(\x90\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05Q\n\x90\x00\x00\x00\x00\x06A\t\xa0\x00\x00\x00\x00\a0\xec\x90\x00\x00\x00\x00\b " +
-	"\xeb\xa0\x00\x00\x00\x00\t\x10ΐ\x00\x00\x00\x00\n\x00͠\x00\x00\x00\x00\n\xf0\xb0\x90\x00\x00\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00" +
-	"\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x169" +
-	"7\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00" +
-	"\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1ې\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\"V\r \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5" +
-	"\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\n\x80\x10\x00\x00\x00\x00)\xdeϠ\x00\x00\x00\x00*\xeab\x10\x00\x00" +
-	"\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s" +
-	"$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\a8 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00" +
-	"\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@o" +
-	"ܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E\xf3\xd3 \x00\x00\x00\x00G-\x8a\x10\x00\x00" +
-	"\x00\x00Gӵ \x00\x00\x00\x00I\rl\x10\x00\x00\x00\x00I\xb3\x97 \x00\x00\x00\x00J\xedN\x10\x00\x00\x00\x00K\x9c\xb3\xa0\x00\x00\x00\x00L\xd6j\x90\x00\x00\x00\x00M|\x95\xa0\x00\x00\x00\x00N\xb6" +
-	"L\x90\x00\x00\x00\x00O\\w\xa0\x00\x00\x00\x00P\x96.\x90\x00\x00\x00\x00Q<Y\xa0\x00\x00\x00\x00Rv\x10\x90\x00\x00\x00\x00S\x1c;\xa0\x00\x00\x00\x00TU\xf2\x90\x00\x00\x00\x00T\xfc\x1d\xa0\x02\x01" +
-	"\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\xff\xff\x8c\xf9\x00\x00\xff\xff\x9d\x90\x01\x04\xff\xff\x8f\x80\x00\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10\xff\xff\x9d\x90\x00\x14LMT" +
-	"\x00PDT\x00PST\x00PWT\x00PPT\x00MST\x00\nMST7\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x81{\xc1\x92\xbc\x03\x00\x00\xbc\x03\x00\x00\r\x00\x1c\x00Ame" +
-	"rica/SitkaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00S\x00\x00\x00\t\x00\x00\x00\"\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}\x873\x99\xff\xff\xff\xffˉ\x1a\xa0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a&\x10\xff\xff\xff\xff\xfe\xb8G" +
-	" \xff\xff\xff\xff\xff\xa8*\x10\x00\x00\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88\f\x10\x00\x00\x00\x00\x02x\v \x00\x00\x00\x00\x03q(\x90\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05Q\n\x90\x00\x00\x00" +
-	"\x00\x06A\t\xa0\x00\x00\x00\x00\a0\xec\x90\x00\x00\x00\x00\a\x8dC\xa0\x00\x00\x00\x00\t\x10ΐ\x00\x00\x00\x00\t\xad\xbf \x00\x00\x00\x00\n\xf0\xb0\x90\x00\x00\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd" +
-	"\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00" +
-	"\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a+\x14" +
-	"\x10\x00\x00\x00\x00\x1a\xf2B\xb0\x00\x00\x00\x00\x1b\xe2%\xa0\x00\x00\x00\x00\x1c\xd2$\xb0\x00\x00\x00\x00\x1d\xc2\a\xa0\x00\x00\x00\x00\x1e\xb2\x06\xb0\x00\x00\x00\x00\x1f\xa1\xe9\xa0\x00\x00\x00\x00 v90\x00\x00\x00" +
-	"\x00!\x81ˠ\x00\x00\x00\x00\"V\x1b0\x00\x00\x00\x00#j\xe8 \x00\x00\x00\x00$5\xfd0\x00\x00\x00\x00%J\xca \x00\x00\x00\x00&\x15\xdf0\x00\x00\x00\x00'*\xac \x00\x00\x00\x00'\xfe\xfb" +
-	"\xb0\x00\x00\x00\x00)\n\x8e \x00\x00\x00\x00)\xdeݰ\x00\x00\x00\x00*\xeap \x00\x00\x00\x00+\xbe\xbf\xb0\x00\x00\x00\x00,ӌ\xa0\x00\x00\x00\x00-\x9e\xa1\xb0\x00\x00\x00\x00.\xb3n\xa0\x00\x00\x00" +
-	"\x00/~\x83\xb0\x00\x00\x00\x000\x93P\xa0\x00\x00\x00\x001g\xa00\x00\x00\x00\x002s2\xa0\x00\x00\x00\x003G\x820\x00\x00\x00\x004S\x14\xa0\x00\x00\x00\x005'd0\x00\x00\x00\x0062\xf6" +
-	"\xa0\x00\x00\x00\x007\aF0\x00\x00\x00\x008\x1c\x13 \x00\x00\x00\x008\xe7(0\x00\x00\x00\x009\xfb\xf5 \x00\x00\x00\x00:\xc7\n0\x00\x00\x00\x00;\xdb\xd7 \x00\x00\x00\x00<\xb0&\xb0\x00\x00\x00" +
-	"\x00=\xbb\xb9 \x00\x00\x00\x00>\x90\b\xb0\x00\x00\x00\x00?\x9b\x9b \x00\x00\x00\x00@o\xea\xb0\x00\x00\x00\x00A\x84\xb7\xa0\x00\x00\x00\x00BO̰\x00\x00\x00\x00Cd\x99\xa0\x00\x00\x00\x00D/\xae" +
-	"\xb0\x00\x00\x00\x00ED{\xa0\x00\x00\x00\x00E\xf3\xe10\x01\x02\x03\x04\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x06\b\a\b\a\b\a\b\a" +
-	"\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\x00\x00ҧ\x00\x00\xff\xff\x81'\x00\x00\xff\xff\x8f\x80\x00\x04\xff\xff" +
-	"\x9d\x90\x01\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10\xff\xff\x81p\x00\x14\xff\xff\x8f\x80\x01\x18\xff\xff\x81p\x00\x1dLMT\x00PST\x00PWT\x00PPT\x00PDT\x00YST\x00AK" +
-	"DT\x00AKST\x00\nAKST9AKDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTq\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00" +
-	"\x10\x00\x1c\x00America/AnguillaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff" +
-	"\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTk" +
-	"\xc2\rx\xbf\x01\x00\x00\xbf\x01\x00\x00\x14\x00\x1c\x00America/DanmarkshavnUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S" +
-	"_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\"\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\x9b\x80I\x00\x00\x00\x00\x00\x13M|P\x00\x00\x00\x00\x143" +
-	"\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00" +
-	"\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"L" +
-	"T\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00" +
-	"\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d" +
-	"\xad\x90\x00\x00\x00\x000\xe7N0\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\xff\xff\xee\x80\x00\x00\xff\xff\xd5\xd0\x00\x04\xff\xff\xe3\xe0" +
-	"\x01\b\x00\x00\x00\x00\x00\fLMT\x00-03\x00-02\x00GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x1c\x00" +
-	"Antarctica/UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x95{\xf3\xa9w\x03\x00" +
-	"\x00w\x03\x00\x00\x11\x00\x1c\x00Antarctica/PalmerUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00R\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xf6\x98\xad\x00\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd3" +
-	"0\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00" +
-	"\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00\x170\xbc\xb0\x00\x00\x00\x00\x18\x06]\xc0\x00\x00\x00\x00\x18\xd1V\xb0\x00\x00\x00\x00\x19\xe6?\xc0\x00\x00\x00\x00\x1a\xb18\xb0\x00\x00\x00\x00\x1b\xcf\\" +
-	"@\x00\x00\x00\x00\x1c\x91\x1a\xb0\x00\x00\x00\x00\x1d\xaf>@\x00\x00\x00\x00\x1ep\xfc\xb0\x00\x00\x00\x00\x1f\x8f @\x00\x00\x00\x00 \x7f\x030\x00\x00\x00\x00!o\x02@\x00\x00\x00\x00\"9\xfb0\x00\x00\x00" +
-	"\x00#N\xe4@\x00\x00\x00\x00$\x19\xdd0\x00\x00\x00\x00%8\x00\xc0\x00\x00\x00\x00%\xf9\xbf0\x00\x00\x00\x00&\xf2\xf8\xc0\x00\x00\x00\x00'١0\x00\x00\x00\x00(\xf7\xc4\xc0\x00\x00\x00\x00)½" +
-	"\xb0\x00\x00\x00\x00*צ\xc0\x00\x00\x00\x00+\xa2\x9f\xb0\x00\x00\x00\x00,\xb7\x88\xc0\x00\x00\x00\x00-\x82\x81\xb0\x00\x00\x00\x00.\x97j\xc0\x00\x00\x00\x00/bc\xb0\x00\x00\x00\x000\x80\x87@\x00\x00\x00" +
-	"\x001BE\xb0\x00\x00\x00\x002`i@\x00\x00\x00\x003=\xd70\x00\x00\x00\x004@K@\x00\x00\x00\x005\vD0\x00\x00\x00\x006\r\xb8@\x00\x00\x00\x007\x06հ\x00\x00\x00\x008\x00\x0f" +
-	"@\x00\x00\x00\x008\xcb\b0\x00\x00\x00\x009\xe9+\xc0\x00\x00\x00\x00:\xaa\xea0\x00\x00\x00\x00;\xc9\r\xc0\x00\x00\x00\x00<\x8a\xcc0\x00\x00\x00\x00=\xa8\xef\xc0\x00\x00\x00\x00>j\xae0\x00\x00\x00" +
-	"\x00?\x88\xd1\xc0\x00\x00\x00\x00@Sʰ\x00\x00\x00\x00Ah\xb3\xc0\x00\x00\x00\x00B3\xac\xb0\x00\x00\x00\x00CH\x95\xc0\x00\x00\x00\x00D\x13\x8e\xb0\x00\x00\x00\x00E1\xb2@\x00\x00\x00\x00E\xf3p" +
-	"\xb0\x00\x00\x00\x00G\x11\x94@\x00\x00\x00\x00G\xef\x020\x00\x00\x00\x00H\xf1v@\x00\x00\x00\x00I\xbco0\x00\x00\x00\x00J\xd1X@\x00\x00\x00\x00K\xb8\x00\xb0\x00\x00\x00\x00L\xb1:@\x00\x00\x00" +
-	"\x00M\xc6\a0\x00\x00\x00\x00NP\x82\xc0\x00\x00\x00\x00O\x9c\xae\xb0\x00\x00\x00\x00PB\xd9\xc0\x00\x00\x00\x00Q|\x90\xb0\x00\x00\x00\x00R+\xf6@\x00\x00\x00\x00S\\r\xb0\x00\x00\x00\x00T\v\xd8" +
-	"@\x00\x00\x00\x00W7\xe60\x00\x00\x00\x00W\xaf\xec\xc0\x00\x00\x00\x00XC\x86\xb0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x03\x04\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x04\x00\x00\x00\x00\x00\x00\xff\xff\xc7\xc0\x00\x04\xff" +
-	"\xff\xd5\xd0\x01\b\xff\xff\xe3\xe0\x01\f\xff\xff\xd5\xd0\x00\b-00\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\x95\xea\x06\xd3\xc5" +
-	"\x00\x00\x00\xc5\x00\x00\x00\x10\x00\x1c\x00Antarctica/DavisUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\xe7\x9c@\x00\xff\xff\xff\xff\xf6G\xdf\x10\xff\xff\xff\xff\xfeG\xab\x00\x00\x00\x00\x00J\xda" +
-	"\x140\x00\x00\x00\x00K\x97\xfa@\x00\x00\x00\x00N\xa9\xaa0\x00\x00\x00\x00OC\xf7\xc0\x01\x00\x01\x02\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00bp\x00\x04\x00\x00FP\x00\b-00\x00+07\x00+" +
-	"05\x00\n<+07>-7\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeTƉ\xf71\x84\x00\x00\x00\x84\x00\x00\x00\x12\x00\x1c\x00Antarctica/Rothera" +
-	"UT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00" +
-	"\x00\x00\b\x00\x00\x00\x00\r\x02-\x00\x01\x00\x00\x00\x00\x00\x00\xff\xff\xd5\xd0\x00\x04-00\x00-03\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\xc2\v\xae\b\x85\x00" +
-	"\x00\x00\x85\x00\x00\x00\x11\x00\x1c\x00Antarctica/VostokUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xe9X\x89\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00T`\x00\x04-00\x00+06\x00\n" +
-	"<+06>-6\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xcfׇ\xe1\x85\x00\x00\x00\x85\x00\x00\x00\x10\x00\x1c\x00Antarctica/SyowaUT\t\x00\x03\xdd" +
-	"\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff" +
-	"\xff\xd5\x1b6\xb4\x01\x00\x00+\xcc\x00\x00\x00\x00*0\x00\x04LMT\x00+03\x00\n<+03>-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTn\x04\x19y\x9a\x00\x00\x00\x9a\x00\x00" +
-	"\x00\x19\x00\x1c\x00Antarctica/DumontDUrvilleUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZ" +
-	"if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xffV\xb6Z\b\xff\xff\xff\xffr\xed\xa4\x90\x01\x02\x00\x00\x89\xf8\x00\x00\x00\x00\x89" +
-	"\xf0\x00\x04\x00\x00\x8c\xa0\x00\tLMT\x00PMMT\x00+10\x00\n<+10>-10\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTb\xb2\xaf\xf7\x13\x04\x00\x00\x13\x04\x00\x00\x12\x00" +
-	"\x1c\x00Antarctica/McMurdoUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`\x00\x00\x00\x06\x00\x00\x00\x13\xff\xff\xff\xffA\xb7L\xa8\xff\xff\xff\xff\xb0\xb4\xb2\xe8\xff\xff\xff\xff\xb1Q\x87X\xff\xff\xff\xff\xb2x\xe5h\xff\xff\xff\xff\xb3" +
-	"C\xe5`\xff\xff\xff\xff\xb4X\xc7h\xff\xff\xff\xff\xb5#\xc7`\xff\xff\xff\xff\xb68\xa9h\xff\xff\xff\xff\xb7\x03\xa9`\xff\xff\xff\xff\xb8\x18\x8bh\xff\xff\xff\xff\xb8\xec\xc5\xe0\xff\xff\xff\xff\xb9\xf8mh\xff" +
-	"\xff\xff\xff\xba̧\xe0\xff\xff\xff\xff\xbb\xd8Oh\xff\xff\xff\xff\xbc\xe3\xe8\xe0\xff\xff\xff\xff\xbd\xae\xf6\xe8\xff\xff\xff\xff\xbe\xc3\xca\xe0\xff\xff\xff\xff\xbf\x8e\xd8\xe8\xff\xff\xff\xff\xc0\xa3\xac\xe0\xff\xff\xff\xff\xc1" +
-	"n\xba\xe8\xff\xff\xff\xff\u0083\x8e\xe0\xff\xff\xff\xff\xc3N\x9c\xe8\xff\xff\xff\xff\xc4cp\xe0\xff\xff\xff\xff\xc5.~\xe8\xff\xff\xff\xff\xc6L\x8d`\xff\xff\xff\xff\xc7\x0e`\xe8\xff\xff\xff\xff\xc8,o`\xff" +
-	"\xff\xff\xff\xc8\xf7}h\xff\xff\xff\xff\xd2ښ@\x00\x00\x00\x00\t\x18\xfd\xe0\x00\x00\x00\x00\t\xac\xa5\xe0\x00\x00\x00\x00\n\xef\xa5`\x00\x00\x00\x00\v\x9e\xfc\xe0\x00\x00\x00\x00\f\xd8\xc1\xe0\x00\x00\x00\x00\r" +
-	"~\xde\xe0\x00\x00\x00\x00\x0e\xb8\xa3\xe0\x00\x00\x00\x00\x0f^\xc0\xe0\x00\x00\x00\x00\x10\x98\x85\xe0\x00\x00\x00\x00\x11>\xa2\xe0\x00\x00\x00\x00\x12xg\xe0\x00\x00\x00\x00\x13\x1e\x84\xe0\x00\x00\x00\x00\x14XI\xe0\x00" +
-	"\x00\x00\x00\x14\xfef\xe0\x00\x00\x00\x00\x168+\xe0\x00\x00\x00\x00\x16\xe7\x83`\x00\x00\x00\x00\x18!H`\x00\x00\x00\x00\x18\xc7e`\x00\x00\x00\x00\x1a\x01*`\x00\x00\x00\x00\x1a\xa7G`\x00\x00\x00\x00\x1b" +
-	"\xe1\f`\x00\x00\x00\x00\x1c\x87)`\x00\x00\x00\x00\x1d\xc0\xee`\x00\x00\x00\x00\x1eg\v`\x00\x00\x00\x00\x1f\xa0\xd0`\x00\x00\x00\x00 F\xed`\x00\x00\x00\x00!\x80\xb2`\x00\x00\x00\x00\"0\t\xe0\x00" +
-	"\x00\x00\x00#i\xce\xe0\x00\x00\x00\x00$\x0f\xeb\xe0\x00\x00\x00\x00%.\x01`\x00\x00\x00\x00&\x02B\xe0\x00\x00\x00\x00'\r\xe3`\x00\x00\x00\x00'\xe2$\xe0\x00\x00\x00\x00(\xed\xc5`\x00\x00\x00\x00)" +
-	"\xc2\x06\xe0\x00\x00\x00\x00*ͧ`\x00\x00\x00\x00+\xab#`\x00\x00\x00\x00,\xad\x89`\x00\x00\x00\x00-\x8b\x05`\x00\x00\x00\x00.\x8dk`\x00\x00\x00\x00/j\xe7`\x00\x00\x00\x000mM`\x00" +
-	"\x00\x00\x001J\xc9`\x00\x00\x00\x002Vi\xe0\x00\x00\x00\x003*\xab`\x00\x00\x00\x0046K\xe0\x00\x00\x00\x005\n\x8d`\x00\x00\x00\x006\x16-\xe0\x00\x00\x00\x006\xf3\xa9\xe0\x00\x00\x00\x007" +
-	"\xf6\x0f\xe0\x00\x00\x00\x008Ӌ\xe0\x00\x00\x00\x009\xd5\xf1\xe0\x00\x00\x00\x00:\xb3m\xe0\x00\x00\x00\x00;\xbf\x0e`\x00\x00\x00\x00<\x93O\xe0\x00\x00\x00\x00=\x9e\xf0`\x00\x00\x00\x00>s1\xe0\x00" +
-	"\x00\x00\x00?~\xd2`\x00\x00\x00\x00@\\N`\x00\x00\x00\x00A^\xb4`\x00\x00\x00\x00B<0`\x00\x00\x00\x00C>\x96`\x00\x00\x00\x00D\x1c\x12`\x00\x00\x00\x00E\x1ex`\x00\x00\x00\x00E" +
-	"\xfb\xf4`\x00\x00\x00\x00F\xfeZ`\x02\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" +
-	"\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x00\x00\xa3\xd8\x00\x00\x00\x00\xaf\xc8\x01\x04\x00" +
-	"\x00\xa1\xb8\x00\t\x00\x00\xa8\xc0\x01\x04\x00\x00\xb6\xd0\x01\x0e\x00\x00\xa8\xc0\x00\x04LMT\x00NZST\x00NZMT\x00NZDT\x00\nNZST-12NZDT,M9.5." +
-	"0,M4.1.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xb2\x84J]\xd0\x03\x00\x00\xd0\x03\x00\x00\x14\x00\x1c\x00Antarctica/Macquari" +
-	"eUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00[\x00\x00\x00\x03" +
-	"\x00\x00\x00\x0e\xff\xff\xff\xff|\x05\x16\x00\xff\xff\xff\xff\x9b\xd5x\x80\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\xa0\x87\xb4`\xff\xff\xff\xff\xd7\fh\x00\xff\xff\xff\xff\xfb\u008d\x00\xff\xff\xff\xff\xfc\xb2~\x00" +
-	"\xff\xff\xff\xff\xfd\xc7Y\x00\xff\xff\xff\xff\xfev\xb0\x80\xff\xff\xff\xff\xff\xa7;\x00\x00\x00\x00\x00\x00V\x92\x80\x00\x00\x00\x00\x01\x87\x1d\x00\x00\x00\x00\x00\x02?\xaf\x00\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00" +
-	"\x04\r\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00\a/\xfd\x80\x00\x00\x00\x00\a\xd6\x1a\x80\x00\x00\x00\x00\t\x0f߀\x00\x00\x00\x00\t\xb5\xfc\x80\x00\x00\x00\x00\n\xef\xc1\x80" +
-	"\x00\x00\x00\x00\v\x9f\x19\x00\x00\x00\x00\x00\f\xd8\xde\x00\x00\x00\x00\x00\r~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00" +
-	"\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x17\x03O\x00\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18\xe31\x00" +
-	"\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\n\x80\x00\x00\x00\x00\x1eg'\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00" +
-	" Y~\x80\x00\x00\x00\x00!\x80\u0380\x00\x00\x00\x00\"B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\"}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00&\x02_\x00\x00\x00\x00\x00')\xaf\x00" +
-	"\x00\x00\x00\x00'\xf4\xb6\x00\x00\x00\x00\x00(\xed\xe1\x80\x00\x00\x00\x00)Ԙ\x00\x00\x00\x00\x00*\xcdÀ\x00\x00\x00\x00+\xb4z\x00\x00\x00\x00\x00,\xad\xa5\x80\x00\x00\x00\x00-\x94\\\x00\x00\x00\x00\x00" +
-	".\x8d\x87\x80\x00\x00\x00\x00/t>\x00\x00\x00\x00\x000mi\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002V\x86\x00\x00\x00\x00\x003=<\x80\x00\x00\x00\x0046h\x00\x00\x00\x00\x005\x1d\x1e\x80" +
-	"\x00\x00\x00\x006\x16J\x00\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x007\xf6,\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbcĀ\x00\x00\x00\x00;\xbf*\x80\x00\x00\x00\x00" +
-	"<\xa5\xe1\x00\x00\x00\x00\x00=\x9f\f\x80\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?~\xee\x80\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A^Ѐ\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00C>\xb2\x80" +
-	"\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00E\x1e\x94\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G\a\xb1\x00\x00\x00\x00\x00G\xf7\xa2\x00\x00\x00\x00\x00H\xe7\x93\x00\x00\x00\x00\x00Iׄ\x00\x00\x00\x00\x00" +
-	"J\xc7u\x00\x00\x00\x00\x00M\x97H\x00\x01\x02\x01\x00\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00\x9a\xb0\x01" +
-	"\t-00\x00AEST\x00AEDT\x00\nAEST-10AEDT,M10.1.0,M4.1.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTb" +
-	"\xb2\xaf\xf7\x13\x04\x00\x00\x13\x04\x00\x00\x15\x00\x1c\x00Antarctica/South_PoleUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04" +
-	"S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`\x00\x00\x00\x06\x00\x00\x00\x13\xff\xff\xff\xffA\xb7L\xa8\xff\xff\xff\xff\xb0\xb4\xb2\xe8\xff\xff\xff\xff\xb1" +
-	"Q\x87X\xff\xff\xff\xff\xb2x\xe5h\xff\xff\xff\xff\xb3C\xe5`\xff\xff\xff\xff\xb4X\xc7h\xff\xff\xff\xff\xb5#\xc7`\xff\xff\xff\xff\xb68\xa9h\xff\xff\xff\xff\xb7\x03\xa9`\xff\xff\xff\xff\xb8\x18\x8bh\xff" +
-	"\xff\xff\xff\xb8\xec\xc5\xe0\xff\xff\xff\xff\xb9\xf8mh\xff\xff\xff\xff\xba̧\xe0\xff\xff\xff\xff\xbb\xd8Oh\xff\xff\xff\xff\xbc\xe3\xe8\xe0\xff\xff\xff\xff\xbd\xae\xf6\xe8\xff\xff\xff\xff\xbe\xc3\xca\xe0\xff\xff\xff\xff\xbf" +
-	"\x8e\xd8\xe8\xff\xff\xff\xff\xc0\xa3\xac\xe0\xff\xff\xff\xff\xc1n\xba\xe8\xff\xff\xff\xff\u0083\x8e\xe0\xff\xff\xff\xff\xc3N\x9c\xe8\xff\xff\xff\xff\xc4cp\xe0\xff\xff\xff\xff\xc5.~\xe8\xff\xff\xff\xff\xc6L\x8d`\xff" +
-	"\xff\xff\xff\xc7\x0e`\xe8\xff\xff\xff\xff\xc8,o`\xff\xff\xff\xff\xc8\xf7}h\xff\xff\xff\xff\xd2ښ@\x00\x00\x00\x00\t\x18\xfd\xe0\x00\x00\x00\x00\t\xac\xa5\xe0\x00\x00\x00\x00\n\xef\xa5`\x00\x00\x00\x00\v" +
-	"\x9e\xfc\xe0\x00\x00\x00\x00\f\xd8\xc1\xe0\x00\x00\x00\x00\r~\xde\xe0\x00\x00\x00\x00\x0e\xb8\xa3\xe0\x00\x00\x00\x00\x0f^\xc0\xe0\x00\x00\x00\x00\x10\x98\x85\xe0\x00\x00\x00\x00\x11>\xa2\xe0\x00\x00\x00\x00\x12xg\xe0\x00" +
-	"\x00\x00\x00\x13\x1e\x84\xe0\x00\x00\x00\x00\x14XI\xe0\x00\x00\x00\x00\x14\xfef\xe0\x00\x00\x00\x00\x168+\xe0\x00\x00\x00\x00\x16\xe7\x83`\x00\x00\x00\x00\x18!H`\x00\x00\x00\x00\x18\xc7e`\x00\x00\x00\x00\x1a" +
-	"\x01*`\x00\x00\x00\x00\x1a\xa7G`\x00\x00\x00\x00\x1b\xe1\f`\x00\x00\x00\x00\x1c\x87)`\x00\x00\x00\x00\x1d\xc0\xee`\x00\x00\x00\x00\x1eg\v`\x00\x00\x00\x00\x1f\xa0\xd0`\x00\x00\x00\x00 F\xed`\x00" +
-	"\x00\x00\x00!\x80\xb2`\x00\x00\x00\x00\"0\t\xe0\x00\x00\x00\x00#i\xce\xe0\x00\x00\x00\x00$\x0f\xeb\xe0\x00\x00\x00\x00%.\x01`\x00\x00\x00\x00&\x02B\xe0\x00\x00\x00\x00'\r\xe3`\x00\x00\x00\x00'" +
-	"\xe2$\xe0\x00\x00\x00\x00(\xed\xc5`\x00\x00\x00\x00)\xc2\x06\xe0\x00\x00\x00\x00*ͧ`\x00\x00\x00\x00+\xab#`\x00\x00\x00\x00,\xad\x89`\x00\x00\x00\x00-\x8b\x05`\x00\x00\x00\x00.\x8dk`\x00" +
-	"\x00\x00\x00/j\xe7`\x00\x00\x00\x000mM`\x00\x00\x00\x001J\xc9`\x00\x00\x00\x002Vi\xe0\x00\x00\x00\x003*\xab`\x00\x00\x00\x0046K\xe0\x00\x00\x00\x005\n\x8d`\x00\x00\x00\x006" +
-	"\x16-\xe0\x00\x00\x00\x006\xf3\xa9\xe0\x00\x00\x00\x007\xf6\x0f\xe0\x00\x00\x00\x008Ӌ\xe0\x00\x00\x00\x009\xd5\xf1\xe0\x00\x00\x00\x00:\xb3m\xe0\x00\x00\x00\x00;\xbf\x0e`\x00\x00\x00\x00<\x93O\xe0\x00" +
-	"\x00\x00\x00=\x9e\xf0`\x00\x00\x00\x00>s1\xe0\x00\x00\x00\x00?~\xd2`\x00\x00\x00\x00@\\N`\x00\x00\x00\x00A^\xb4`\x00\x00\x00\x00B<0`\x00\x00\x00\x00C>\x96`\x00\x00\x00\x00D" +
-	"\x1c\x12`\x00\x00\x00\x00E\x1ex`\x00\x00\x00\x00E\xfb\xf4`\x00\x00\x00\x00F\xfeZ`\x02\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x04\x05\x04\x05" +
-	"\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" +
-	"\x04\x05\x04\x00\x00\xa3\xd8\x00\x00\x00\x00\xaf\xc8\x01\x04\x00\x00\xa1\xb8\x00\t\x00\x00\xa8\xc0\x01\x04\x00\x00\xb6\xd0\x01\x0e\x00\x00\xa8\xc0\x00\x04LMT\x00NZST\x00NZMT\x00NZDT\x00\nN" +
-	"ZST-12NZDT,M9.5.0,M4.1.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT:\xc8P7\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x1c\x00Ant" +
-	"arctica/TrollUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\f\x00\x00\x00\x00B\rG\x00\x00\x00\x00\x00BF\x05\x90\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x00\x00\x00\b-00\x00+02\x00" +
-	"+00\x00\n<+00>0<+02>-2,M3.5.0/1,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\xd7N\xab\x8b\x98\x00\x00\x00" +
-	"\x98\x00\x00\x00\x11\x00\x1c\x00Antarctica/MawsonUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00" +
+	"EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x04" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\xff\xff\xb5\x94\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\f\xff\xff\xc7\xc0\x01\x10LMT\x00EDT\x00EST\x00EWT\x00EPT\x00\nEST5E" +
+	"DT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb9B$\x90\x01\x04\x00\x00\x01\x04\x00\x00\x0f\x00\x00\x00America/Tiju" +
+	"anaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00^\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xa9yOp\xff\xff\xff\xff\xaf\xf2" +
+	"|\xf0\xff\xff\xff\xff\xb6fdp\xff\xff\xff\xff\xb7\x1b\x10\x00\xff\xff\xff\xff\xb8\n\xf2\xf0\xff\xff\xff\xff\xcbꍀ\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xffҙ\xbap\xff\xff\xff\xff\xd7\x1bY\x00\xff\xff" +
+	"\xff\xffؑ\xb4\xf0\xff\xff\xff\xff\xe2~K\x90\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4^-\x90\xff\xff\xff\xff\xe5)4\x90\xff\xff\xff\xff\xe6GJ\x10\xff\xff\xff\xff\xe7\x12Q\x10\xff\xff\xff\xff\xe8'" +
+	",\x10\xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff\xff\xea\a\x0e\x10\xff\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff\xff\xeb\xe6\xf0\x10\xff\xff\xff\xff\xec\xb1\xf7\x10\xff\xff\xff\xff\xed\xc6\xd2\x10\xff\xff\xff\xff\xee\x91\xd9\x10\x00\x00" +
+	"\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12y" +
+	"s\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00" +
+	"\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1ې\x00\x00\x00\x00 v" +
+	"+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\"V\r \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00" +
+	"\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\n\x80\x10\x00\x00\x00\x00)\xdeϠ\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3" +
+	"`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00" +
+	"\x00\x0062\xe8\x90\x00\x00\x00\x007\a8 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0" +
+	"\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00" +
+	"\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00F\x0f\x82\xa0\x00\x00\x00\x00G$O\x90\x00\x00\x00\x00G\xf8\x9f \x00\x00\x00\x00I\x041\x90\x00\x00\x00\x00I\u0601 \x00\x00\x00\x00J\xe4" +
+	"\x13\x90\x00\x00\x00\x00K\x9c\xb3\xa0\x01\x02\x01\x02\x03\x02\x04\x05\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\x92L\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\x8f\x80" +
+	"\x00\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10\xff\xff\x9d\x90\x01\x14LMT\x00MST\x00PST\x00PDT\x00PWT\x00PPT\x00\nPST8PDT,M3.2.0," +
+	"M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ӿ\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00\x0f\x00\x00\x00America/TorontoTZif2\x00\x00" +
 	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\xe2 2\x80\x00\x00\x00\x00J\xda\"@\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00T`\x00\x04\x00\x00" +
-	"FP\x00\b-00\x00+06\x00+05\x00\n<+05>-5\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\xddzAh\xf3\x00\x00\x00\xf3\x00\x00\x00\x10\x00\x1c\x00Antar" +
-	"ctica/CaseyUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\f\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\xfe\x1è\x00\x00\x00\x00J\xda\x06 \x00\x00\x00\x00K\x8f\xca\xf0\x00\x00\x00\x00N\xa9\x9c \x00\x00\x00\x00OC͐\x00\x00\x00\x00X\n" +
-	";\x80\x00\x00\x00\x00Z\xa4\x0f\x10\x00\x00\x00\x00[\xb9\x14@\x00\x00\x00\x00\\\x8d\x1d\x80\x00\x00\x00\x00]\x96E0\x00\x00\x00\x00^c\xc5\x00\x00\x00\x00\x00_x\xa0<\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00p\x80\x00\x04\x00\x00\x9a\xb0\x00\b-00\x00+08\x00+11\x00\n<+11>-11\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x1c\x00Arctic/UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbe" +
-	"T\xa5\x97\aĤ\x02\x00\x00\xa4\x02\x00\x00\x13\x00\x1c\x00Arctic/LongyearbyenUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04" +
-	"S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xffr\xee$l\xff\xff\xff\xff\x9b'\xe3\x00\xff\xff\xff\xff\x9b" +
-	"\xd4{`\xff\xff\xff\xffȷM`\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff" +
-	"\xff\xff\xff\xd2b\a\x10\xff\xff\xff\xff\xeb\xaf \x90\xff\xff\xff\xff\xec\xa8L\x10\xff\xff\xff\xff\xed\x98=\x10\xff\xff\xff\xff\xee\x88.\x10\xff\xff\xff\xff\xefx\x1f\x10\xff\xff\xff\xff\xf0h\x10\x10\xff\xff\xff\xff\xf1" +
-	"X\x01\x10\xff\xff\xff\xff\xf2G\xf2\x10\xff\xff\xff\xff\xf37\xe3\x10\xff\xff\xff\xff\xf4'\xd4\x10\xff\xff\xff\xff\xf5\x17\xc5\x10\xff\xff\xff\xff\xf6\x10\xf0\x90\xff\xff\xff\xff\xf7/\x06\x10\xff\xff\xff\xff\xf7\xf0Ґ\x00" +
-	"\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19" +
-	"Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00" +
-	"\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'" +
-	"\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00" +
-	"\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00\n\x14\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\tLMT\x00CEST\x00CET\x00\nCET-1CE" +
-	"ST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x1c\x00Asia/UT\t\x00\x03" +
-	"\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT's\x96\x1en\x01\x00\x00n\x01\x00\x00\r\x00\x1c\x00Asia/Du" +
-	"shanbeUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xffr\xeex\xec\xff\xff\xff\xff\x9e\xb8\x93p\xff\xff\xff\xff\x9f\xba\xeb`\xff\xff\xff\xff\xa0\x87.\xc8" +
+	"\xff\xff\xff\xff\xa1\x9a\xb1@\xff\xff\xff\xff\xa2\x94\x06\xf0\xff\xff\xff\xff\xa3U\xa9@\xff\xff\xff\xff\xa4\x86]\xf0\xff\xff\xff\xff\xa5(x`\xff\xff\xff\xff\xa6f?\xf0\xff\xff\xff\xff\xa7\fN\xe0\xff\xff\xff\xff" +
+	"\xa8F!\xf0\xff\xff\xff\xff\xa8\xec0\xe0\xff\xff\xff\xff\xaa\x1c\xc9p\xff\xff\xff\xff\xaa\xd5M`\xff\xff\xff\xff\xab\xfc\xabp\xff\xff\xff\xff\xac\xb5/`\xff\xff\xff\xff\xad܍p\xff\xff\xff\xff\xae\x95\x11`" +
+	"\xff\xff\xff\xff\xaf\xbcop\xff\xff\xff\xff\xb0~-\xe0\xff\xff\xff\xff\xb1\x9cQp\xff\xff\xff\xff\xb2gJ`\xff\xff\xff\xff\xb3|3p\xff\xff\xff\xff\xb4G,`\xff\xff\xff\xff\xb5\\\x15p\xff\xff\xff\xff" +
+	"\xb6'\x0e`\xff\xff\xff\xff\xb7;\xf7p\xff\xff\xff\xff\xb8\x06\xf0`\xff\xff\xff\xff\xb9%\x13\xf0\xff\xff\xff\xff\xb9\xe6\xd2`\xff\xff\xff\xff\xbb\x04\xf5\xf0\xff\xff\xff\xff\xbb\xcf\xee\xe0\xff\xff\xff\xff\xbc\xe4\xd7\xf0" +
+	"\xff\xff\xff\xff\xbd\xaf\xd0\xe0\xff\xff\xff\xff\xbeĹ\xf0\xff\xff\xff\xff\xbf\x8f\xb2\xe0\xff\xff\xff\xff\xc0\xa4\x9b\xf0\xff\xff\xff\xff\xc1o\x94\xe0\xff\xff\xff\xff\u0084}\xf0\xff\xff\xff\xff\xc3Ov\xe0\xff\xff\xff\xff" +
+	"\xc4d_\xf0\xff\xff\xff\xff\xc5/X\xe0\xff\xff\xff\xff\xc6M|p\xff\xff\xff\xff\xc7\x0f:\xe0\xff\xff\xff\xff\xc8-^p\xff\xff\xff\xffˈ\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0" +
+	"\xff\xff\xff\xff\xd3u\xe4\xf0\xff\xff\xff\xff\xd4@\xdd\xe0\xff\xff\xff\xff\xd5U\xaa\xd0\xff\xff\xff\xff\xd6 \xa3\xc0\xff\xff\xff\xff\xd75\x8c\xd0\xff\xff\xff\xff\xd8\x00\x85\xc0\xff\xff\xff\xff\xd9\x15n\xd0\xff\xff\xff\xff" +
+	"\xda3v@\xff\xff\xff\xff\xda\xfe\xa7p\xff\xff\xff\xff\xdc\x13t`\xff\xff\xff\xff\xdcމp\xff\xff\xff\xffݩ\x82`\xff\xff\xff\xff\u07bekp\xff\xff\xff\xff߉d`\xff\xff\xff\xff\xe0\x9eMp" +
+	"\xff\xff\xff\xff\xe1iF`\xff\xff\xff\xff\xe2~/p\xff\xff\xff\xff\xe3I(`\xff\xff\xff\xff\xe4^\x11p\xff\xff\xff\xff\xe5)\n`\xff\xff\xff\xff\xe6G-\xf0\xff\xff\xff\xff\xe7\x12&\xe0\xff\xff\xff\xff" +
+	"\xe8'\x0f\xf0\xff\xff\xff\xff\xe9\x16\xf2\xe0\xff\xff\xff\xff\xea\x06\xf1\xf0\xff\xff\xff\xff\xea\xf6\xd4\xe0\xff\xff\xff\xff\xeb\xe6\xd3\xf0\xff\xff\xff\xff\xecֶ\xe0\xff\xff\xff\xff\xedƵ\xf0\xff\xff\xff\xff\xee\xbf\xd3`" +
+	"\xff\xff\xff\xff\xef\xaf\xd2p\xff\xff\xff\xff\xf0\x9f\xb5`\xff\xff\xff\xff\xf1\x8f\xb4p\xff\xff\xff\xff\xf2\x7f\x97`\xff\xff\xff\xff\xf3o\x96p\xff\xff\xff\xff\xf4_y`\xff\xff\xff\xff\xf5Oxp\xff\xff\xff\xff" +
+	"\xf6?[`\xff\xff\xff\xff\xf7/Zp\xff\xff\xff\xff\xf8(w\xe0\xff\xff\xff\xff\xf9\x0f<p\xff\xff\xff\xff\xfa\bY\xe0\xff\xff\xff\xff\xfa\xf8X\xf0\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0" +
+	"\xff\xff\xff\xff\xfd\xc8\x1d\xe0\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00" +
+	"\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\a0\xc2`\x00\x00\x00\x00\b \xc1p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\n\x00\xa3p\x00\x00\x00\x00\n\xf0\x86`" +
+	"\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00\f٢\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00" +
+	"\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0" +
+	"\x00\x00\x00\x00\x1a\x02\v`\x00\x00\x00\x00\x1a\xf2\np\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00" +
+	" v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\"U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0" +
+	"\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\nU\xe0\x00\x00\x00\x00)ޥp\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00" +
+	".\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0" +
+	"\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\a\r\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00" +
+	"<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`" +
+	"\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xb5\x94\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\f\xff\xff\xc7\xc0\x01\x10LMT\x00EDT\x00EST\x00EW" +
+	"T\x00EPT\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0f\x00\x00\x00" +
+	"America/TortolaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00" +
+	"\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff" +
+	"\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00AP" +
+	"T\x00AWT\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00U9#\xbe2\x05\x00\x002\x05\x00\x00\x11\x00\x00\x00America/VancouverT" +
+	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff^=v\xec\xff\xff\xff\xff\x9e\xb8\xbd\xa0\xff\xff\xff\xff\x9f\xbb\x15\x90\xff\xff" +
+	"\xff\xffˉ\x1a\xa0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a&\x10\xff\xff\xff\xff\xd3v\x0f \xff\xff\xff\xff\xd4A\b\x10\xff\xff\xff\xff\xd5U\xf1 \xff\xff\xff\xff\xd6 \xea\x10\xff\xff\xff\xff\xd75" +
+	"\xd3 \xff\xff\xff\xff\xd8\x00\xcc\x10\xff\xff\xff\xff\xd9\x15\xb5 \xff\xff\xff\xff\xd9\xe0\xae\x10\xff\xff\xff\xff\xda\xfeѠ\xff\xff\xff\xff\xdb\xc0\x90\x10\xff\xff\xff\xff\xdc\u07b3\xa0\xff\xff\xff\xffݩ\xac\x90\xff\xff" +
+	"\xff\xff\u07be\x95\xa0\xff\xff\xff\xff߉\x8e\x90\xff\xff\xff\xff\xe0\x9ew\xa0\xff\xff\xff\xff\xe1ip\x90\xff\xff\xff\xff\xe2~Y\xa0\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4^;\xa0\xff\xff\xff\xff\xe5)" +
+	"4\x90\xff\xff\xff\xff\xe6GX \xff\xff\xff\xff\xe7\x12Q\x10\xff\xff\xff\xff\xe8': \xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff\xff\xea\a\x1c \xff\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff\xff\xeb\xe6\xfe \xff\xff" +
+	"\xff\xff\xec\xb1\xf7\x10\xff\xff\xff\xff\xed\xc6\xe0 \xff\xff\xff\xff\xee\x91\xd9\x10\xff\xff\xff\xff\xef\xaf\xfc\xa0\xff\xff\xff\xff\xf0q\xbb\x10\xff\xff\xff\xff\xf1\x8fޠ\xff\xff\xff\xff\xf2\x7f\xc1\x90\xff\xff\xff\xff\xf3o" +
+	"\xc0\xa0\xff\xff\xff\xff\xf4_\xa3\x90\xff\xff\xff\xff\xf5O\xa2\xa0\xff\xff\xff\xff\xf6?\x85\x90\xff\xff\xff\xff\xf7/\x84\xa0\xff\xff\xff\xff\xf8(\xa2\x10\xff\xff\xff\xff\xf9\x0ff\xa0\xff\xff\xff\xff\xfa\b\x84\x10\xff\xff" +
+	"\xff\xff\xfa\xf8\x83 \xff\xff\xff\xff\xfb\xe8f\x10\xff\xff\xff\xff\xfc\xd8e \xff\xff\xff\xff\xfd\xc8H\x10\xff\xff\xff\xff\xfe\xb8G \xff\xff\xff\xff\xff\xa8*\x10\x00\x00\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88" +
+	"\f\x10\x00\x00\x00\x00\x02x\v \x00\x00\x00\x00\x03q(\x90\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05Q\n\x90\x00\x00\x00\x00\x06A\t\xa0\x00\x00\x00\x00\a0\xec\x90\x00\x00\x00\x00\b \xeb\xa0\x00\x00" +
+	"\x00\x00\t\x10ΐ\x00\x00\x00\x00\n\x00͠\x00\x00\x00\x00\n\xf0\xb0\x90\x00\x00\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9" +
+	"\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00" +
+	"\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1" +
+	"\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1ې\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\"V\r \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00" +
+	"\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\n\x80\x10\x00\x00\x00\x00)\xdeϠ\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe" +
+	"\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00" +
+	"\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\a8 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb" +
+	"\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00" +
+	"\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E\xf3\xd3 \x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\x8c\x94\x00" +
+	"\x00\xff\xff\x9d\x90\x01\x04\xff\xff\x8f\x80\x00\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10LMT\x00PDT\x00PST\x00PWT\x00PPT\x00\nPST8PDT,M3.2.0" +
+	",M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0e\x00\x00\x00America/VirginTZif2\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0" +
+	"\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\xbf\x1d\xee\x91\x05\x04\x00\x00\x05\x04\x00\x00\x12\x00\x00\x00America/WhitehorseTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00]\x00\x00\x00\t\x00\x00\x00%\xff\xff\xff\xff}\x86\x8a\x9c\xff\xff\xff\xff\x9e\xb8˰\xff\xff\xff\xff\x9f\xbb#\xa0\xff\xff\xff\xff\xa0\xd0\f\xb0\xff\xff\xff\xff\xa1\xa2Ҁ\xff\xff\xff\xffˉ(" +
+	"\xb0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a4 \xff\xff\xff\xff\xf7/v\x90\xff\xff\xff\xff\xf8(\xa2\x10\xff\xff\xff\xff\xf8ń\x90\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00" +
+	"\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17" +
+	"\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1ې\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\"V\r \x00\x00\x00" +
+	"\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\n\x80\x10\x00\x00\x00\x00)\xde\xcf" +
+	"\xa0\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00" +
+	"\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\a8 \x00\x00\x00\x008\x1c\x05" +
+	"\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00" +
+	"\x00?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E\xf3\xd3" +
+	" \x00\x00\x00\x00G-\x8a\x10\x00\x00\x00\x00Gӵ \x00\x00\x00\x00I\rl\x10\x00\x00\x00\x00I\xb3\x97 \x00\x00\x00\x00J\xedN\x10\x00\x00\x00\x00K\x9c\xb3\xa0\x00\x00\x00\x00L\xd6j\x90\x00\x00\x00" +
+	"\x00M|\x95\xa0\x00\x00\x00\x00N\xb6L\x90\x00\x00\x00\x00O\\w\xa0\x00\x00\x00\x00P\x96.\x90\x00\x00\x00\x00Q<Y\xa0\x00\x00\x00\x00Rv\x10\x90\x00\x00\x00\x00S\x1c;\xa0\x00\x00\x00\x00TU\xf2" +
+	"\x90\x00\x00\x00\x00T\xfc\x1d\xa0\x00\x00\x00\x00V5Ԑ\x00\x00\x00\x00V\xe5: \x00\x00\x00\x00X\x1e\xf1\x10\x00\x00\x00\x00X\xc5\x1c \x00\x00\x00\x00Y\xfe\xd3\x10\x00\x00\x00\x00Z\xa4\xfe \x00\x00\x00" +
+	"\x00[\u07b5\x10\x00\x00\x00\x00\\\x84\xe0 \x00\x00\x00\x00]\xbe\x97\x10\x00\x00\x00\x00^d\xc2 \x00\x00\x00\x00_\x9e\\\xf0\x02\x01\x02\x01\x02\x03\x04\x02\x05\x02\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06" +
+	"\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06" +
+	"\a\x06\a\x06\a\x06\a\x06\a\b\xff\xff\x81d\x00\x00\xff\xff\x8f\x80\x01\x04\xff\xff\x81p\x00\b\xff\xff\x8f\x80\x01\f\xff\xff\x8f\x80\x01\x10\xff\xff\x9d\x90\x01\x14\xff\xff\x8f\x80\x00\x19\xff\xff\x9d\x90\x01\x1d\xff\xff" +
+	"\x9d\x90\x00!LMT\x00YDT\x00YST\x00YWT\x00YPT\x00YDDT\x00PST\x00PDT\x00MST\x00\nMST7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00?_p\x99\x0e\x05\x00\x00\x0e\x05\x00\x00\x10\x00\x00\x00America/WinnipegTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00}" +
+	"\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xffd䰔\xff\xff\xff\xff\x9b\x01\xfb\xe0\xff\xff\xff\xff\x9búP\xff\xff\xff\xff\x9e\xb8\xa1\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\u00a0;\x80\xff\xff\xff\xff" +
+	"\xc3O\x84\xf0\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xffӈh\x00\xff\xff\xff\xff\xd4S`\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0" +
+	"\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xdb\x00\a\x00\xff\xff\xff\xff\xdb\xc8\\\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xff" +
+	"ݩ\x90p\xff\xff\xff\xff\u07bey\x80\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80" +
+	"\xff\xff\xff\xff\xe5)\x18p\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe7\x124\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff" +
+	"\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xd6\xc4\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\ue47c\xf0\xff\xff\xff\xff\xf3o\xa4\x80\xff\xff\xff\xff\xf41b\xf0\xff\xff\xff\xff\xf9\x0fJ\x80\xff\xff\xff\xff\xfa\bv\x00" +
+	"\xff\xff\xff\xff\xfa\xf8g\x00\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\r\x00\x00\x00\x00\x00" +
+	"\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\v\x80\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\b π" +
+	"\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\n\x00\xb1\x80\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00" +
+	"\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169)\x00" +
+	"\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00" +
+	"\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1܀\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xd3\x00" +
+	"\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\u07b3\x80\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00" +
+	"+\xbe\x95\x80\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\x16\x80" +
+	"\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005':\x00\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x00" +
+	"9\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@o\xc0\x80" +
+	"\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xa4\xec\x00\x00\xff" +
+	"\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10LMT\x00CDT\x00CST\x00CWT\x00CPT\x00\nCST6CDT,M3.2.0,M" +
+	"11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,\xdb~\xab\xb2\x03\x00\x00\xb2\x03\x00\x00\x0f\x00\x00\x00America/YakutatTZif2\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S\x00\x00\x00\b\x00\x00\x00\x1e\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}\x877\xbf\xff\xff\xff\xffˉ(\xb0\xff\xff\xff\xff\xd2#\xf4p\xff" +
+	"\xff\xff\xff\xd2a4 \xff\xff\xff\xff\xfe\xb8U0\xff\xff\xff\xff\xff\xa88 \x00\x00\x00\x00\x00\x9870\x00\x00\x00\x00\x01\x88\x1a \x00\x00\x00\x00\x02x\x190\x00\x00\x00\x00\x03q6\xa0\x00\x00\x00\x00\x04" +
+	"a5\xb0\x00\x00\x00\x00\x05Q\x18\xa0\x00\x00\x00\x00\x06A\x17\xb0\x00\x00\x00\x00\a0\xfa\xa0\x00\x00\x00\x00\a\x8dQ\xb0\x00\x00\x00\x00\t\x10ܠ\x00\x00\x00\x00\t\xad\xcd0\x00\x00\x00\x00\n\xf0\xbe\xa0\x00" +
+	"\x00\x00\x00\v\u0f70\x00\x00\x00\x00\f\xd9\xdb \x00\x00\x00\x00\r\xc0\x9f\xb0\x00\x00\x00\x00\x0e\xb9\xbd \x00\x00\x00\x00\x0f\xa9\xbc0\x00\x00\x00\x00\x10\x99\x9f \x00\x00\x00\x00\x11\x89\x9e0\x00\x00\x00\x00\x12" +
+	"y\x81 \x00\x00\x00\x00\x13i\x800\x00\x00\x00\x00\x14Yc \x00\x00\x00\x00\x15Ib0\x00\x00\x00\x00\x169E \x00\x00\x00\x00\x17)D0\x00\x00\x00\x00\x18\"a\xa0\x00\x00\x00\x00\x19\t&0\x00" +
+	"\x00\x00\x00\x1a\x02C\xa0\x00\x00\x00\x00\x1a+\x14\x10\x00\x00\x00\x00\x1a\xf2B\xb0\x00\x00\x00\x00\x1b\xe2%\xa0\x00\x00\x00\x00\x1c\xd2$\xb0\x00\x00\x00\x00\x1d\xc2\a\xa0\x00\x00\x00\x00\x1e\xb2\x06\xb0\x00\x00\x00\x00\x1f" +
+	"\xa1\xe9\xa0\x00\x00\x00\x00 v90\x00\x00\x00\x00!\x81ˠ\x00\x00\x00\x00\"V\x1b0\x00\x00\x00\x00#j\xe8 \x00\x00\x00\x00$5\xfd0\x00\x00\x00\x00%J\xca \x00\x00\x00\x00&\x15\xdf0\x00" +
+	"\x00\x00\x00'*\xac \x00\x00\x00\x00'\xfe\xfb\xb0\x00\x00\x00\x00)\n\x8e \x00\x00\x00\x00)\xdeݰ\x00\x00\x00\x00*\xeap \x00\x00\x00\x00+\xbe\xbf\xb0\x00\x00\x00\x00,ӌ\xa0\x00\x00\x00\x00-" +
+	"\x9e\xa1\xb0\x00\x00\x00\x00.\xb3n\xa0\x00\x00\x00\x00/~\x83\xb0\x00\x00\x00\x000\x93P\xa0\x00\x00\x00\x001g\xa00\x00\x00\x00\x002s2\xa0\x00\x00\x00\x003G\x820\x00\x00\x00\x004S\x14\xa0\x00" +
+	"\x00\x00\x005'd0\x00\x00\x00\x0062\xf6\xa0\x00\x00\x00\x007\aF0\x00\x00\x00\x008\x1c\x13 \x00\x00\x00\x008\xe7(0\x00\x00\x00\x009\xfb\xf5 \x00\x00\x00\x00:\xc7\n0\x00\x00\x00\x00;" +
+	"\xdb\xd7 \x00\x00\x00\x00<\xb0&\xb0\x00\x00\x00\x00=\xbb\xb9 \x00\x00\x00\x00>\x90\b\xb0\x00\x00\x00\x00?\x9b\x9b \x00\x00\x00\x00@o\xea\xb0\x00\x00\x00\x00A\x84\xb7\xa0\x00\x00\x00\x00BO̰\x00" +
+	"\x00\x00\x00Cd\x99\xa0\x00\x00\x00\x00D/\xae\xb0\x00\x00\x00\x00ED{\xa0\x00\x00\x00\x00E\xf3\xe10\x01\x02\x03\x04\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02" +
+	"\x05\x02\x05\x02\x05\x02\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\x00\x00\u0381\x00\x00" +
+	"\xff\xff}\x01\x00\x00\xff\xff\x81p\x00\x04\xff\xff\x8f\x80\x01\b\xff\xff\x8f\x80\x01\f\xff\xff\x8f\x80\x01\x10\xff\xff\x8f\x80\x01\x14\xff\xff\x81p\x00\x19LMT\x00YST\x00YWT\x00YPT\x00YD" +
+	"T\x00AKDT\x00AKST\x00\nAKST9AKDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00/5\xe20L\x03\x00\x00" +
+	"L\x03\x00\x00\x13\x00\x00\x00America/YellowknifeTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00K\x00\x00\x00\x05\x00\x00" +
+	"\x00\x14\xff\xff\xff\xff\xbe*\x18\x00\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00" +
+	"\x00\x00\a0ހ\x00\x00\x00\x00\b ݐ\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\n\x00\xbf\x90\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\vࡐ\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0" +
+	"\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00" +
+	"\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2" +
+	"\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xff\x10\x00\x00" +
+	"\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeߐ\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\xde" +
+	"\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00" +
+	"\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b" +
+	"\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00" +
+	"\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3" +
+	"\xc5\x10\x03\x01\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" +
+	"\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x00\x00\x00\x00\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\xab\xa0\x01\b\xff\xff\x9d\x90\x00\f\xff\xff\xab\xa0\x01\x10-00\x00MWT\x00MPT\x00M" +
+	"ST\x00MDT\x00\nMST7MDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xddzAh\xf3\x00\x00\x00\xf3\x00\x00\x00\x10\x00\x00" +
+	"\x00Antarctica/CaseyTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" +
+	"\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\f\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\xfe\x1è" +
+	"\x00\x00\x00\x00J\xda\x06 \x00\x00\x00\x00K\x8f\xca\xf0\x00\x00\x00\x00N\xa9\x9c \x00\x00\x00\x00OC͐\x00\x00\x00\x00X\n;\x80\x00\x00\x00\x00Z\xa4\x0f\x10\x00\x00\x00\x00[\xb9\x14@\x00\x00\x00\x00" +
+	"\\\x8d\x1d\x80\x00\x00\x00\x00]\x96E0\x00\x00\x00\x00^c\xc5\x00\x00\x00\x00\x00_x\xa0<\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00p\x80\x00\x04\x00\x00\x9a\xb0\x00\b-0" +
+	"0\x00+08\x00+11\x00\n<+11>-11\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\xea\x06\xd3\xc5\x00\x00\x00\xc5\x00\x00\x00\x10\x00\x00\x00Antarctica" +
+	"/DavisTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZi" +
+	"f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\xe7\x9c@\x00\xff\xff\xff\xff\xf6G\xdf\x10\xff\xff\xff" +
+	"\xff\xfeG\xab\x00\x00\x00\x00\x00J\xda\x140\x00\x00\x00\x00K\x97\xfa@\x00\x00\x00\x00N\xa9\xaa0\x00\x00\x00\x00OC\xf7\xc0\x01\x00\x01\x02\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00bp\x00\x04\x00\x00FP" +
+	"\x00\b-00\x00+07\x00+05\x00\n<+07>-7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\x04\x19y\x9a\x00\x00\x00\x9a\x00\x00\x00\x19\x00\x00\x00Antarct" +
+	"ica/DumontDUrvilleTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00" +
+	"\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xffV\xb6Z" +
+	"\b\xff\xff\xff\xffr\xed\xa4\x90\x01\x02\x00\x00\x89\xf8\x00\x00\x00\x00\x89\xf0\x00\x04\x00\x00\x8c\xa0\x00\tLMT\x00PMMT\x00+10\x00\n<+10>-10\nPK\x03\x04\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\xb2\x84J]\xd0\x03\x00\x00\xd0\x03\x00\x00\x14\x00\x00\x00Antarctica/MacquarieTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00[\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xff|\x05\x16\x00\xff\xff\xff\xff\x9b\xd5x\x80\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\xa0\x87\xb4`\xff\xff\xff\xff\xd7\fh\x00\xff\xff\xff" +
+	"\xff\xfb\u008d\x00\xff\xff\xff\xff\xfc\xb2~\x00\xff\xff\xff\xff\xfd\xc7Y\x00\xff\xff\xff\xff\xfev\xb0\x80\xff\xff\xff\xff\xff\xa7;\x00\x00\x00\x00\x00\x00V\x92\x80\x00\x00\x00\x00\x01\x87\x1d\x00\x00\x00\x00\x00\x02?\xaf" +
+	"\x00\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00\a/\xfd\x80\x00\x00\x00\x00\a\xd6\x1a\x80\x00\x00\x00\x00\t\x0f߀\x00\x00\x00" +
+	"\x00\t\xb5\xfc\x80\x00\x00\x00\x00\n\xef\xc1\x80\x00\x00\x00\x00\v\x9f\x19\x00\x00\x00\x00\x00\f\xd8\xde\x00\x00\x00\x00\x00\r~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2" +
+	"\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x17\x03O\x00\x00\x00\x00" +
+	"\x00\x18!d\x80\x00\x00\x00\x00\x18\xe31\x00\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\n\x80\x00\x00\x00\x00\x1eg'" +
+	"\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!\x80\u0380\x00\x00\x00\x00\"B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\"}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00" +
+	"\x00&\x02_\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xf4\xb6\x00\x00\x00\x00\x00(\xed\xe1\x80\x00\x00\x00\x00)Ԙ\x00\x00\x00\x00\x00*\xcdÀ\x00\x00\x00\x00+\xb4z\x00\x00\x00\x00\x00,\xad\xa5" +
+	"\x80\x00\x00\x00\x00-\x94\\\x00\x00\x00\x00\x00.\x8d\x87\x80\x00\x00\x00\x00/t>\x00\x00\x00\x00\x000mi\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002V\x86\x00\x00\x00\x00\x003=<\x80\x00\x00\x00" +
+	"\x0046h\x00\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x006\x16J\x00\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x007\xf6,\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbc\xc4" +
+	"\x80\x00\x00\x00\x00;\xbf*\x80\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\x9f\f\x80\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?~\xee\x80\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A^Ѐ\x00\x00\x00" +
+	"\x00BE\x87\x00\x00\x00\x00\x00C>\xb2\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00E\x1e\x94\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G\a\xb1\x00\x00\x00\x00\x00G\xf7\xa2\x00\x00\x00\x00\x00H\xe7\x93" +
+	"\x00\x00\x00\x00\x00Iׄ\x00\x00\x00\x00\x00J\xc7u\x00\x00\x00\x00\x00M\x97H\x00\x01\x02\x01\x00\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00\x9a\xb0\x01\t-00\x00AEST\x00AEDT\x00\nAEST-10AEDT,M10.1.0,M4.1.0/3\nPK" +
+	"\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd7N\xab\x8b\x98\x00\x00\x00\x98\x00\x00\x00\x11\x00\x00\x00Antarctica/MawsonTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\xe2 2\x80\x00\x00\x00\x00J\xda\"@\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00T`\x00\x04\x00\x00FP\x00\b-00\x00" +
+	"+06\x00+05\x00\n<+05>-5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b\xb2\xaf\xf7\x13\x04\x00\x00\x13\x04\x00\x00\x12\x00\x00\x00Antarctica/Mc" +
+	"MurdoTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif" +
+	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`\x00\x00\x00\x06\x00\x00\x00\x13\xff\xff\xff\xffA\xb7L\xa8\xff\xff\xff\xff\xb0\xb4\xb2\xe8\xff\xff\xff\xff" +
+	"\xb1Q\x87X\xff\xff\xff\xff\xb2x\xe5h\xff\xff\xff\xff\xb3C\xe5`\xff\xff\xff\xff\xb4X\xc7h\xff\xff\xff\xff\xb5#\xc7`\xff\xff\xff\xff\xb68\xa9h\xff\xff\xff\xff\xb7\x03\xa9`\xff\xff\xff\xff\xb8\x18\x8bh" +
+	"\xff\xff\xff\xff\xb8\xec\xc5\xe0\xff\xff\xff\xff\xb9\xf8mh\xff\xff\xff\xff\xba̧\xe0\xff\xff\xff\xff\xbb\xd8Oh\xff\xff\xff\xff\xbc\xe3\xe8\xe0\xff\xff\xff\xff\xbd\xae\xf6\xe8\xff\xff\xff\xff\xbe\xc3\xca\xe0\xff\xff\xff\xff" +
+	"\xbf\x8e\xd8\xe8\xff\xff\xff\xff\xc0\xa3\xac\xe0\xff\xff\xff\xff\xc1n\xba\xe8\xff\xff\xff\xff\u0083\x8e\xe0\xff\xff\xff\xff\xc3N\x9c\xe8\xff\xff\xff\xff\xc4cp\xe0\xff\xff\xff\xff\xc5.~\xe8\xff\xff\xff\xff\xc6L\x8d`" +
+	"\xff\xff\xff\xff\xc7\x0e`\xe8\xff\xff\xff\xff\xc8,o`\xff\xff\xff\xff\xc8\xf7}h\xff\xff\xff\xff\xd2ښ@\x00\x00\x00\x00\t\x18\xfd\xe0\x00\x00\x00\x00\t\xac\xa5\xe0\x00\x00\x00\x00\n\xef\xa5`\x00\x00\x00\x00" +
+	"\v\x9e\xfc\xe0\x00\x00\x00\x00\f\xd8\xc1\xe0\x00\x00\x00\x00\r~\xde\xe0\x00\x00\x00\x00\x0e\xb8\xa3\xe0\x00\x00\x00\x00\x0f^\xc0\xe0\x00\x00\x00\x00\x10\x98\x85\xe0\x00\x00\x00\x00\x11>\xa2\xe0\x00\x00\x00\x00\x12xg\xe0" +
+	"\x00\x00\x00\x00\x13\x1e\x84\xe0\x00\x00\x00\x00\x14XI\xe0\x00\x00\x00\x00\x14\xfef\xe0\x00\x00\x00\x00\x168+\xe0\x00\x00\x00\x00\x16\xe7\x83`\x00\x00\x00\x00\x18!H`\x00\x00\x00\x00\x18\xc7e`\x00\x00\x00\x00" +
+	"\x1a\x01*`\x00\x00\x00\x00\x1a\xa7G`\x00\x00\x00\x00\x1b\xe1\f`\x00\x00\x00\x00\x1c\x87)`\x00\x00\x00\x00\x1d\xc0\xee`\x00\x00\x00\x00\x1eg\v`\x00\x00\x00\x00\x1f\xa0\xd0`\x00\x00\x00\x00 F\xed`" +
+	"\x00\x00\x00\x00!\x80\xb2`\x00\x00\x00\x00\"0\t\xe0\x00\x00\x00\x00#i\xce\xe0\x00\x00\x00\x00$\x0f\xeb\xe0\x00\x00\x00\x00%.\x01`\x00\x00\x00\x00&\x02B\xe0\x00\x00\x00\x00'\r\xe3`\x00\x00\x00\x00" +
+	"'\xe2$\xe0\x00\x00\x00\x00(\xed\xc5`\x00\x00\x00\x00)\xc2\x06\xe0\x00\x00\x00\x00*ͧ`\x00\x00\x00\x00+\xab#`\x00\x00\x00\x00,\xad\x89`\x00\x00\x00\x00-\x8b\x05`\x00\x00\x00\x00.\x8dk`" +
+	"\x00\x00\x00\x00/j\xe7`\x00\x00\x00\x000mM`\x00\x00\x00\x001J\xc9`\x00\x00\x00\x002Vi\xe0\x00\x00\x00\x003*\xab`\x00\x00\x00\x0046K\xe0\x00\x00\x00\x005\n\x8d`\x00\x00\x00\x00" +
+	"6\x16-\xe0\x00\x00\x00\x006\xf3\xa9\xe0\x00\x00\x00\x007\xf6\x0f\xe0\x00\x00\x00\x008Ӌ\xe0\x00\x00\x00\x009\xd5\xf1\xe0\x00\x00\x00\x00:\xb3m\xe0\x00\x00\x00\x00;\xbf\x0e`\x00\x00\x00\x00<\x93O\xe0" +
+	"\x00\x00\x00\x00=\x9e\xf0`\x00\x00\x00\x00>s1\xe0\x00\x00\x00\x00?~\xd2`\x00\x00\x00\x00@\\N`\x00\x00\x00\x00A^\xb4`\x00\x00\x00\x00B<0`\x00\x00\x00\x00C>\x96`\x00\x00\x00\x00" +
+	"D\x1c\x12`\x00\x00\x00\x00E\x1ex`\x00\x00\x00\x00E\xfb\xf4`\x00\x00\x00\x00F\xfeZ`\x02\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x04\x05\x04" +
+	"\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" +
+	"\x05\x04\x05\x04\x00\x00\xa3\xd8\x00\x00\x00\x00\xaf\xc8\x01\x04\x00\x00\xa1\xb8\x00\t\x00\x00\xa8\xc0\x01\x04\x00\x00\xb6\xd0\x01\x0e\x00\x00\xa8\xc0\x00\x04LMT\x00NZST\x00NZMT\x00NZDT\x00\n" +
+	"NZST-12NZDT,M9.5.0,M4.1.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95{\xf3\xa9w\x03\x00\x00w\x03\x00\x00\x11\x00\x00\x00An" +
+	"tarctica/PalmerTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00" +
+	"\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00R\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xf6\x98\xad\x00\xff\xff" +
+	"\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xac" +
+	"R@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00\x170\xbc\xb0\x00\x00\x00\x00\x18\x06]\xc0\x00\x00\x00\x00\x18\xd1V\xb0\x00\x00" +
+	"\x00\x00\x19\xe6?\xc0\x00\x00\x00\x00\x1a\xb18\xb0\x00\x00\x00\x00\x1b\xcf\\@\x00\x00\x00\x00\x1c\x91\x1a\xb0\x00\x00\x00\x00\x1d\xaf>@\x00\x00\x00\x00\x1ep\xfc\xb0\x00\x00\x00\x00\x1f\x8f @\x00\x00\x00\x00 \x7f" +
+	"\x030\x00\x00\x00\x00!o\x02@\x00\x00\x00\x00\"9\xfb0\x00\x00\x00\x00#N\xe4@\x00\x00\x00\x00$\x19\xdd0\x00\x00\x00\x00%8\x00\xc0\x00\x00\x00\x00%\xf9\xbf0\x00\x00\x00\x00&\xf2\xf8\xc0\x00\x00" +
+	"\x00\x00'١0\x00\x00\x00\x00(\xf7\xc4\xc0\x00\x00\x00\x00)½\xb0\x00\x00\x00\x00*צ\xc0\x00\x00\x00\x00+\xa2\x9f\xb0\x00\x00\x00\x00,\xb7\x88\xc0\x00\x00\x00\x00-\x82\x81\xb0\x00\x00\x00\x00.\x97" +
+	"j\xc0\x00\x00\x00\x00/bc\xb0\x00\x00\x00\x000\x80\x87@\x00\x00\x00\x001BE\xb0\x00\x00\x00\x002`i@\x00\x00\x00\x003=\xd70\x00\x00\x00\x004@K@\x00\x00\x00\x005\vD0\x00\x00" +
+	"\x00\x006\r\xb8@\x00\x00\x00\x007\x06հ\x00\x00\x00\x008\x00\x0f@\x00\x00\x00\x008\xcb\b0\x00\x00\x00\x009\xe9+\xc0\x00\x00\x00\x00:\xaa\xea0\x00\x00\x00\x00;\xc9\r\xc0\x00\x00\x00\x00<\x8a" +
+	"\xcc0\x00\x00\x00\x00=\xa8\xef\xc0\x00\x00\x00\x00>j\xae0\x00\x00\x00\x00?\x88\xd1\xc0\x00\x00\x00\x00@Sʰ\x00\x00\x00\x00Ah\xb3\xc0\x00\x00\x00\x00B3\xac\xb0\x00\x00\x00\x00CH\x95\xc0\x00\x00" +
+	"\x00\x00D\x13\x8e\xb0\x00\x00\x00\x00E1\xb2@\x00\x00\x00\x00E\xf3p\xb0\x00\x00\x00\x00G\x11\x94@\x00\x00\x00\x00G\xef\x020\x00\x00\x00\x00H\xf1v@\x00\x00\x00\x00I\xbco0\x00\x00\x00\x00J\xd1" +
+	"X@\x00\x00\x00\x00K\xb8\x00\xb0\x00\x00\x00\x00L\xb1:@\x00\x00\x00\x00M\xc6\a0\x00\x00\x00\x00NP\x82\xc0\x00\x00\x00\x00O\x9c\xae\xb0\x00\x00\x00\x00PB\xd9\xc0\x00\x00\x00\x00Q|\x90\xb0\x00\x00" +
+	"\x00\x00R+\xf6@\x00\x00\x00\x00S\\r\xb0\x00\x00\x00\x00T\v\xd8@\x00\x00\x00\x00W7\xe60\x00\x00\x00\x00W\xaf\xec\xc0\x00\x00\x00\x00XC\x86\xb0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x03\x04\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x04\x00\x00\x00\x00\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xe3\xe0\x01\f\xff\xff\xd5\xd0\x00\b-00\x00-04\x00-03\x00-02\x00\n<-03>" +
+	"3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Ɖ\xf71\x84\x00\x00\x00\x84\x00\x00\x00\x12\x00\x00\x00Antarctica/RotheraTZif2\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\x00\x00\x00\x00\r\x02-\x00\x01\x00\x00\x00\x00\x00\x00\xff\xff\xd5\xd0\x00\x04-00\x00-03\x00\n<-03>" +
+	"3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b\xb2\xaf\xf7\x13\x04\x00\x00\x13\x04\x00\x00\x15\x00\x00\x00Antarctica/South_PoleTZif2\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`\x00\x00\x00\x06\x00\x00\x00\x13\xff\xff\xff\xffA\xb7L\xa8\xff\xff\xff\xff\xb0\xb4\xb2\xe8\xff\xff\xff\xff\xb1Q\x87X\xff\xff\xff\xff\xb2x\xe5h" +
+	"\xff\xff\xff\xff\xb3C\xe5`\xff\xff\xff\xff\xb4X\xc7h\xff\xff\xff\xff\xb5#\xc7`\xff\xff\xff\xff\xb68\xa9h\xff\xff\xff\xff\xb7\x03\xa9`\xff\xff\xff\xff\xb8\x18\x8bh\xff\xff\xff\xff\xb8\xec\xc5\xe0\xff\xff\xff\xff" +
+	"\xb9\xf8mh\xff\xff\xff\xff\xba̧\xe0\xff\xff\xff\xff\xbb\xd8Oh\xff\xff\xff\xff\xbc\xe3\xe8\xe0\xff\xff\xff\xff\xbd\xae\xf6\xe8\xff\xff\xff\xff\xbe\xc3\xca\xe0\xff\xff\xff\xff\xbf\x8e\xd8\xe8\xff\xff\xff\xff\xc0\xa3\xac\xe0" +
+	"\xff\xff\xff\xff\xc1n\xba\xe8\xff\xff\xff\xff\u0083\x8e\xe0\xff\xff\xff\xff\xc3N\x9c\xe8\xff\xff\xff\xff\xc4cp\xe0\xff\xff\xff\xff\xc5.~\xe8\xff\xff\xff\xff\xc6L\x8d`\xff\xff\xff\xff\xc7\x0e`\xe8\xff\xff\xff\xff" +
+	"\xc8,o`\xff\xff\xff\xff\xc8\xf7}h\xff\xff\xff\xff\xd2ښ@\x00\x00\x00\x00\t\x18\xfd\xe0\x00\x00\x00\x00\t\xac\xa5\xe0\x00\x00\x00\x00\n\xef\xa5`\x00\x00\x00\x00\v\x9e\xfc\xe0\x00\x00\x00\x00\f\xd8\xc1\xe0" +
+	"\x00\x00\x00\x00\r~\xde\xe0\x00\x00\x00\x00\x0e\xb8\xa3\xe0\x00\x00\x00\x00\x0f^\xc0\xe0\x00\x00\x00\x00\x10\x98\x85\xe0\x00\x00\x00\x00\x11>\xa2\xe0\x00\x00\x00\x00\x12xg\xe0\x00\x00\x00\x00\x13\x1e\x84\xe0\x00\x00\x00\x00" +
+	"\x14XI\xe0\x00\x00\x00\x00\x14\xfef\xe0\x00\x00\x00\x00\x168+\xe0\x00\x00\x00\x00\x16\xe7\x83`\x00\x00\x00\x00\x18!H`\x00\x00\x00\x00\x18\xc7e`\x00\x00\x00\x00\x1a\x01*`\x00\x00\x00\x00\x1a\xa7G`" +
+	"\x00\x00\x00\x00\x1b\xe1\f`\x00\x00\x00\x00\x1c\x87)`\x00\x00\x00\x00\x1d\xc0\xee`\x00\x00\x00\x00\x1eg\v`\x00\x00\x00\x00\x1f\xa0\xd0`\x00\x00\x00\x00 F\xed`\x00\x00\x00\x00!\x80\xb2`\x00\x00\x00\x00" +
+	"\"0\t\xe0\x00\x00\x00\x00#i\xce\xe0\x00\x00\x00\x00$\x0f\xeb\xe0\x00\x00\x00\x00%.\x01`\x00\x00\x00\x00&\x02B\xe0\x00\x00\x00\x00'\r\xe3`\x00\x00\x00\x00'\xe2$\xe0\x00\x00\x00\x00(\xed\xc5`" +
+	"\x00\x00\x00\x00)\xc2\x06\xe0\x00\x00\x00\x00*ͧ`\x00\x00\x00\x00+\xab#`\x00\x00\x00\x00,\xad\x89`\x00\x00\x00\x00-\x8b\x05`\x00\x00\x00\x00.\x8dk`\x00\x00\x00\x00/j\xe7`\x00\x00\x00\x00" +
+	"0mM`\x00\x00\x00\x001J\xc9`\x00\x00\x00\x002Vi\xe0\x00\x00\x00\x003*\xab`\x00\x00\x00\x0046K\xe0\x00\x00\x00\x005\n\x8d`\x00\x00\x00\x006\x16-\xe0\x00\x00\x00\x006\xf3\xa9\xe0" +
+	"\x00\x00\x00\x007\xf6\x0f\xe0\x00\x00\x00\x008Ӌ\xe0\x00\x00\x00\x009\xd5\xf1\xe0\x00\x00\x00\x00:\xb3m\xe0\x00\x00\x00\x00;\xbf\x0e`\x00\x00\x00\x00<\x93O\xe0\x00\x00\x00\x00=\x9e\xf0`\x00\x00\x00\x00" +
+	">s1\xe0\x00\x00\x00\x00?~\xd2`\x00\x00\x00\x00@\\N`\x00\x00\x00\x00A^\xb4`\x00\x00\x00\x00B<0`\x00\x00\x00\x00C>\x96`\x00\x00\x00\x00D\x1c\x12`\x00\x00\x00\x00E\x1ex`" +
+	"\x00\x00\x00\x00E\xfb\xf4`\x00\x00\x00\x00F\xfeZ`\x02\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" +
+	"\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x00\x00\xa3\xd8\x00\x00\x00\x00" +
+	"\xaf\xc8\x01\x04\x00\x00\xa1\xb8\x00\t\x00\x00\xa8\xc0\x01\x04\x00\x00\xb6\xd0\x01\x0e\x00\x00\xa8\xc0\x00\x04LMT\x00NZST\x00NZMT\x00NZDT\x00\nNZST-12NZDT," +
+	"M9.5.0,M4.1.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcfׇ\xe1\x85\x00\x00\x00\x85\x00\x00\x00\x10\x00\x00\x00Antarctica/Syo" +
+	"waTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xd5\x1b6\xb4\x01\x00\x00+\xcc\x00\x00\x00\x00*0\x00\x04LM" +
+	"T\x00+03\x00\n<+03>-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:\xc8P7\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x00\x00Antarctica/Trol" +
+	"lTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\f\x00\x00\x00\x00B\rG\x00\x00\x00\x00\x00BF\x05\x90\x02\x01\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x1c \x01\x04\x00\x00\x00\x00\x00\b-00\x00+02\x00+00\x00\n<+00>0<+02>-2,M3.5.0/1,M10.5.0/3\nPK" +
+	"\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x1d\xc6\x1b\x85\x00\x00\x00\x85\x00\x00\x00\x11\x00\x00\x00Antarctica/VostokTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xb0\xfe\xbad\x01\x00\x00R\x1c\x00\x00\x00\x00T`\x00\x04LMT\x00+06\x00\n<+06>-6\nPK" +
+	"\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17S\x91\xb3\xc1\x02\x00\x00\xc1\x02\x00\x00\x13\x00\x00\x00Arctic/LongyearbyenTZif2\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xffo\xa2a\xf8\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4" +
+	"\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xc8\tq\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff" +
+	"\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xffѶ\x96\x00\xff\xff\xff\xff\xd2X\xbe\x80\xff\xff\xff\xffҡO\x10\xff\xff\xff\xff\xd3c\x1b\x90\xff\xff\xff\xff\xd4K#\x90\xff\xff\xff\xff\xd59" +
+	"\xd1 \xff\xff\xff\xff\xd5g\xe7\x90\xff\xff\xff\xffըs\x00\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xd9\x02\xc1\x90\xff\xff\xff\xff\xd9\xe9x\x10\x00\x00" +
+	"\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19\xd3" +
+	"\xa0\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00" +
+	"\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf5" +
+	"4\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00" +
+	"\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00\f\x88\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00*0\x01\rLMT\x00CEST\x00CET\x00C" +
+	"EMT\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcfׇ\xe1\x85\x00\x00\x00\x85\x00\x00\x00\t\x00" +
+	"\x00\x00Asia/AdenTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00" +
+	"\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xd5\x1b6\xb4\x01\x00\x00+\xcc\x00" +
+	"\x00\x00\x00*0\x00\x04LMT\x00+03\x00\n<+03>-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S\xdd\\2a\x02\x00\x00a\x02\x00\x00\v\x00\x00\x00Asia/A" +
+	"lmatyTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif" +
+	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19{\xdc\xff\xff\xff\xff\xb5\xa3\xef0\x00\x00\x00\x00" +
+	"\x15'}\xa0\x00\x00\x00\x00\x16\x18\xb2\x10\x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xe5\x90\x00\x00\x00\x00\x18\xe9\xe4\xa0\x00\x00\x00\x00\x19\xdb\x19\x10\x00\x00\x00\x00\x1a\xcci\xa0\x00\x00\x00\x00\x1b\xbcv\xc0" +
+	"\x00\x00\x00\x00\x1c\xacg\xc0\x00\x00\x00\x00\x1d\x9cX\xc0\x00\x00\x00\x00\x1e\x8cI\xc0\x00\x00\x00\x00\x1f|:\xc0\x00\x00\x00\x00 l+\xc0\x00\x00\x00\x00!\\\x1c\xc0\x00\x00\x00\x00\"L\r\xc0\x00\x00\x00\x00" +
+	"#;\xfe\xc0\x00\x00\x00\x00$+\xef\xc0\x00\x00\x00\x00%\x1b\xe0\xc0\x00\x00\x00\x00&\v\xd1\xc0\x00\x00\x00\x00'\x04\xfd@\x00\x00\x00\x00'\xf4\xee@\x00\x00\x00\x00(\xe4\xedP\x00\x00\x00\x00)x\x95P" +
+	"\x00\x00\x00\x00)\xd4\xd0@\x00\x00\x00\x00*\xc4\xc1@\x00\x00\x00\x00+\xb4\xb2@\x00\x00\x00\x00,\xa4\xa3@\x00\x00\x00\x00-\x94\x94@\x00\x00\x00\x00.\x84\x85@\x00\x00\x00\x00/tv@\x00\x00\x00\x00" +
+	"0dg@\x00\x00\x00\x001]\x92\xc0\x00\x00\x00\x002rm\xc0\x00\x00\x00\x003=t\xc0\x00\x00\x00\x004RO\xc0\x00\x00\x00\x005\x1dV\xc0\x00\x00\x00\x00621\xc0\x00\x00\x00\x006\xfd8\xc0" +
+	"\x00\x00\x00\x008\x1bN@\x00\x00\x00\x008\xdd\x1a\xc0\x00\x00\x00\x009\xfb0@\x00\x00\x00\x00:\xbc\xfc\xc0\x00\x00\x00\x00;\xdb\x12@\x00\x00\x00\x00<\xa6\x19@\x00\x00\x00\x00=\xba\xf4@\x00\x00\x00\x00" +
+	">\x85\xfb@\x00\x00\x00\x00?\x9a\xd6@\x00\x00\x00\x00@e\xdd@\x00\x00\x00\x00A\x83\xf2\xc0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00H$\x00\x00\x00\x00FP\x00\x04\x00\x00bp\x01\b\x00\x00T`\x00\f\x00\x00T`\x01\fLMT\x00+05\x00+07" +
+	"\x00+06\x00\n<+06>-6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaf\rs\xad\xa0\x03\x00\x00\xa0\x03\x00\x00\n\x00\x00\x00Asia/AmmanTZif2\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00W\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff\xb6\xa3\xd6\xd0\x00\x00\x00\x00\x06ry\xe0\x00\x00\x00\x00\a\f\xabP\x00\x00\x00\x00\b$7" +
+	"`\x00\x00\x00\x00\b\xed\xde\xd0\x00\x00\x00\x00\n\x05j\xe0\x00\x00\x00\x00\n\xcf\x12P\x00\x00\x00\x00\v\xe7\xef\xe0\x00\x00\x00\x00\f\xdau\xd0\x00\x00\x00\x00\r\xc9#`\x00\x00\x00\x00\x0e\x92\xca\xd0\x00\x00\x00" +
+	"\x00\x0f\xa9\x05`\x00\x00\x00\x00\x10r\xac\xd0\x00\x00\x00\x00\x1c\xad\xd5`\x00\x00\x00\x00\x1d\x9f\t\xd0\x00\x00\x00\x00\x1e\x92\xfd`\x00\x00\x00\x00\x1f\x82\xe0P\x00\x00\x00\x00 r\xdf`\x00\x00\x00\x00!b\xc2" +
+	"P\x00\x00\x00\x00\"R\xc1`\x00\x00\x00\x00#K\xde\xd0\x00\x00\x00\x00$d\xbc`\x00\x00\x00\x00%+\xc0\xd0\x00\x00\x00\x00&7o`\x00\x00\x00\x00'\v\xa2\xd0\x00\x00\x00\x00(\vs\xe0\x00\x00\x00" +
+	"\x00(\xe2JP\x00\x00\x00\x00)\xe4\xbe`\x00\x00\x00\x00*\xcbf\xd0\x00\x00\x00\x00+\xbbe\xe0\x00\x00\x00\x00,\xabH\xd0\x00\x00\x00\x00-\x9bG\xe0\x00\x00\x00\x00.x\xb5\xd0\x00\x00\x00\x00/\x84d" +
+	"`\x00\x00\x00\x000X\xa5\xe0\x00\x00\x00\x001dF`\x00\x00\x00\x002A\xc2`\x00\x00\x00\x003D(`\x00\x00\x00\x004!\xa4`\x00\x00\x00\x005$\n`\x00\x00\x00\x006\x01\x86`\x00\x00\x00" +
+	"\x007z\x93`\x00\x00\x00\x007\xea\xa2\xe0\x00\x00\x00\x008\xe2|\xe0\x00\x00\x00\x009ӿ`\x00\x00\x00\x00:\xc2^\xe0\x00\x00\x00\x00;\xb3\xa1`\x00\x00\x00\x00<\xa3\x92`\x00\x00\x00\x00=\x93\x83" +
+	"`\x00\x00\x00\x00>\x83t`\x00\x00\x00\x00?\x98O`\x00\x00\x00\x00@cV`\x00\x00\x00\x00An\xf6\xe0\x00\x00\x00\x00BLr\xe0\x00\x00\x00\x00C<c\xe0\x00\x00\x00\x00D,T\xe0\x00\x00\x00" +
+	"\x00EA/\xe0\x00\x00\x00\x00F\f6\xe0\x00\x00\x00\x00G!\x11\xe0\x00\x00\x00\x00G\xec\x18\xe0\x00\x00\x00\x00I\n.`\x00\x00\x00\x00I\xcb\xfa\xe0\x00\x00\x00\x00J\xea\x10`\x00\x00\x00\x00K\xab\xdc" +
+	"\xe0\x00\x00\x00\x00L\xc9\xf2`\x00\x00\x00\x00M\x94\xf9`\x00\x00\x00\x00N\xa9\xd4`\x00\x00\x00\x00Ot\xdb`\x00\x00\x00\x00R\xb3^P\x00\x00\x00\x00S4\x9f`\x00\x00\x00\x00TR\xb4\xe0\x00\x00\x00" +
+	"\x00U\x14\x81`\x00\x00\x00\x00V2\x96\xe0\x00\x00\x00\x00V\xfd\x9d\xe0\x00\x00\x00\x00X\x12x\xe0\x00\x00\x00\x00X\xdd\x7f\xe0\x00\x00\x00\x00Y\xf2Z\xe0\x00\x00\x00\x00Z\xbda\xe0\x00\x00\x00\x00[\xd2<" +
+	"\xe0\x00\x00\x00\x00\\\x9dC\xe0\x00\x00\x00\x00]\xb2\x1e\xe0\x00\x00\x00\x00^}%\xe0\x00\x00\x00\x00_\x9b;`\x00\x00\x00\x00`]\a\xe0\x00\x00\x00\x00a{\x1d`\x00\x00\x00\x00b\x17\xff\xe0\x00\x00\x00" +
+	"\x00cZ\xff`\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x00\x00!\xb0\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\t\x00\x00*0\x00\rLMT\x00" +
+	"EEST\x00EET\x00+03\x00\n<+03>-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\xe0\xe7!\xe7\x02\x00\x00\xe7\x02\x00\x00\v\x00\x00\x00Asia/Ana" +
+	"dyrTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\a\x00\x00\x00\x14\xff\xff\xff\xff\xaa\x19\x1d\x9c\xff\xff\xff\xff\xb5\xa3\x8c\xc0\x00\x00\x00\x00\x15'" +
+	"\x1b0\x00\x00\x00\x00\x16\x18O\xa0\x00\x00\x00\x00\x17\bN\xb0\x00\x00\x00\x00\x17\xf9\x910\x00\x00\x00\x00\x18\xe9\x90@\x00\x00\x00\x00\x19\xdaİ\x00\x00\x00\x00\x1a\xcc\x15@\x00\x00\x00\x00\x1b\xbc\"`\x00\x00" +
+	"\x00\x00\x1c\xac\x13`\x00\x00\x00\x00\x1d\x9c\x04`\x00\x00\x00\x00\x1e\x8b\xf5`\x00\x00\x00\x00\x1f{\xe6`\x00\x00\x00\x00 k\xd7`\x00\x00\x00\x00![\xc8`\x00\x00\x00\x00\"K\xb9`\x00\x00\x00\x00#;" +
+	"\xaa`\x00\x00\x00\x00$+\x9b`\x00\x00\x00\x00%\x1b\x8c`\x00\x00\x00\x00&\v}`\x00\x00\x00\x00'\x04\xa8\xe0\x00\x00\x00\x00'\xf4\x99\xe0\x00\x00\x00\x00(\xe4\x98\xf0\x00\x00\x00\x00)x@\xf0\x00\x00" +
+	"\x00\x00)\xd4{\xe0\x00\x00\x00\x00*\xc4l\xe0\x00\x00\x00\x00+\xb4]\xe0\x00\x00\x00\x00,\xa4N\xe0\x00\x00\x00\x00-\x94?\xe0\x00\x00\x00\x00.\x840\xe0\x00\x00\x00\x00/t!\xe0\x00\x00\x00\x000d" +
+	"\x12\xe0\x00\x00\x00\x001]>`\x00\x00\x00\x002r\x19`\x00\x00\x00\x003= `\x00\x00\x00\x004Q\xfb`\x00\x00\x00\x005\x1d\x02`\x00\x00\x00\x0061\xdd`\x00\x00\x00\x006\xfc\xe4`\x00\x00" +
+	"\x00\x008\x1a\xf9\xe0\x00\x00\x00\x008\xdc\xc6`\x00\x00\x00\x009\xfa\xdb\xe0\x00\x00\x00\x00:\xbc\xa8`\x00\x00\x00\x00;ڽ\xe0\x00\x00\x00\x00<\xa5\xc4\xe0\x00\x00\x00\x00=\xba\x9f\xe0\x00\x00\x00\x00>\x85" +
+	"\xa6\xe0\x00\x00\x00\x00?\x9a\x81\xe0\x00\x00\x00\x00@e\x88\xe0\x00\x00\x00\x00A\x83\x9e`\x00\x00\x00\x00BEj\xe0\x00\x00\x00\x00Cc\x80`\x00\x00\x00\x00D%L\xe0\x00\x00\x00\x00ECb`\x00\x00" +
+	"\x00\x00F\x05.\xe0\x00\x00\x00\x00G#D`\x00\x00\x00\x00G\xeeK`\x00\x00\x00\x00I\x03&`\x00\x00\x00\x00I\xce-`\x00\x00\x00\x00J\xe3\b`\x00\x00\x00\x00K\xae\x0f`\x00\x00\x00\x00L\xcc" +
+	"2\xf0\x00\x00\x00\x00M\x8d\xffp\x01\x03\x02\x03\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x05\x06\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04" +
+	"\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x05\x06\x01\x00\x00\xa6d\x00\x00\x00\x00\xa8\xc0\x00\x04\x00\x00\xc4\xe0\x01\b\x00\x00\xb6\xd0\x00\f\x00\x00\xb6\xd0\x01\f\x00\x00\xa8\xc0\x01\x04\x00\x00\x9a\xb0\x00\x10LMT\x00" +
+	"+12\x00+14\x00+13\x00+11\x00\n<+12>-12\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00T\x81\x18G^\x02\x00\x00^\x02\x00\x00\n\x00\x00\x00Asia" +
+	"/AqtauTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZi" +
+	"f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x002\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x94\xe0\xff\xff\xff\xff\xb5\xa3\xfd@\x00\x00\x00" +
+	"\x00\x16\x18\xce0\x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu" +
+	"\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L\x1b\xd0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00" +
+	"\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\v\xdf\xd0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\xa3`\x00\x00\x00\x00)\xd4\xde" +
+	"P\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xc0P\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xa2P\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000d\x83`\x00\x00\x00" +
+	"\x001]\xae\xe0\x00\x00\x00\x002r\x89\xe0\x00\x00\x00\x003=\x90\xe0\x00\x00\x00\x004Rk\xe0\x00\x00\x00\x005\x1dr\xe0\x00\x00\x00\x0062M\xe0\x00\x00\x00\x006\xfdT\xe0\x00\x00\x00\x008\x1bj" +
+	"`\x00\x00\x00\x008\xdd6\xe0\x00\x00\x00\x009\xfbL`\x00\x00\x00\x00:\xbd\x18\xe0\x00\x00\x00\x00;\xdb.`\x00\x00\x00\x00<\xa65`\x00\x00\x00\x00=\xbb\x10`\x00\x00\x00\x00>\x86\x17`\x00\x00\x00" +
+	"\x00?\x9a\xf2`\x00\x00\x00\x00@e\xf9`\x00\x00\x00\x00A\x84\x0e\xe0\x01\x02\x03\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x05\x01\x02\x04\x02\x04\x02\x04\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05" +
+	"\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x02\x00\x00/ \x00\x00\x00\x008@\x00\x04\x00\x00FP\x00\b\x00\x00T`\x00\f\x00\x00T`\x01\f\x00\x00FP\x01\bLMT\x00+04\x00+05\x00+" +
+	"06\x00\n<+05>-5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdb\xfa\xb5\xbeg\x02\x00\x00g\x02\x00\x00\v\x00\x00\x00Asia/AqtobeTZif2\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x8eh\xff\xff\xff\xff\xb5\xa3\xfd@\x00\x00\x00\x00\x15'\x8b\xb0\x00\x00\x00\x00\x16\x18\xc0 " +
+	"\x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00" +
+	"\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L\x1b\xd0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$+\xfd\xd0" +
+	"\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\v\xdf\xd0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\xa3`\x00\x00\x00\x00)\xd4\xdeP\x00\x00\x00\x00" +
+	"*\xc4\xcfP\x00\x00\x00\x00+\xb4\xc0P\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xa2P\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x84P\x00\x00\x00\x000duP\x00\x00\x00\x001]\xa0\xd0" +
+	"\x00\x00\x00\x002r{\xd0\x00\x00\x00\x003=\x82\xd0\x00\x00\x00\x004R]\xd0\x00\x00\x00\x005\x1dd\xd0\x00\x00\x00\x0062?\xd0\x00\x00\x00\x006\xfdF\xd0\x00\x00\x00\x008\x1b\\P\x00\x00\x00\x00" +
+	"8\xdd(\xd0\x00\x00\x00\x009\xfb>P\x00\x00\x00\x00:\xbd\n\xd0\x00\x00\x00\x00;\xdb P\x00\x00\x00\x00<\xa6'P\x00\x00\x00\x00=\xbb\x02P\x00\x00\x00\x00>\x86\tP\x00\x00\x00\x00?\x9a\xe4P" +
+	"\x00\x00\x00\x00@e\xebP\x00\x00\x00\x00A\x84\x00\xd0\x01\x02\x03\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x00\x005\x98\x00\x00\x00\x008@\x00\x04\x00\x00FP\x00\b\x00\x00T`\x01\f\x00\x00T`\x00\f\x00\x00FP\x01\bLMT\x00+04\x00+05\x00+06\x00\n" +
+	"<+05>-5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00e\x1bb2w\x01\x00\x00w\x01\x00\x00\r\x00\x00\x00Asia/AshgabatTZif2\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x19\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x8dD\xff\xff\xff\xff\xb5\xa3\xfd@\x00\x00\x00\x00\x15'\x8b\xb0\x00\x00\x00\x00\x16\x18\xc0 \x00\x00" +
+	"\x00\x00\x17\b\xbf0\x00\x00\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9c" +
+	"f\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L\x1b\xd0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00" +
+	"\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\v\xdf\xd0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\xa3`\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x00\x006\xbc\x00\x00\x00\x008@\x00\x04\x00\x00T`\x01\b\x00\x00FP\x00\f\x00\x00FP\x01\fLMT\x00+04\x00+06\x00+05\x00\n<+" +
+	"05>-5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00e\x1bb2w\x01\x00\x00w\x01\x00\x00\x0e\x00\x00\x00Asia/AshkhabadTZif2\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x19\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x8dD\xff\xff\xff\xff\xb5\xa3\xfd@\x00\x00\x00\x00\x15'\x8b\xb0\x00\x00\x00\x00\x16\x18\xc0 \x00\x00\x00" +
+	"\x00\x17\b\xbf0\x00\x00\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf" +
+	"\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L\x1b\xd0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00" +
+	"\x00%\x1b\xee\xd0\x00\x00\x00\x00&\v\xdf\xd0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\xa3`\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x00\x006\xbc\x00\x00\x00\x008@\x00\x04\x00\x00T`\x01\b\x00\x00FP\x00\f\x00\x00FP\x01\fLMT\x00+04\x00+06\x00+05\x00\n<+0" +
+	"5>-5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\xa7^\xfah\x02\x00\x00h\x02\x00\x00\v\x00\x00\x00Asia/AtyrauTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x002\x00\x00\x00\a\x00\x00\x00\x14\xff\xff\xff\xff\xaa\x19\x93P\xff\xff\xff\xff\xb5\xa4\vP\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xf3" +
+	"\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00" +
+	"\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L\x1b\xd0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\v\xdf" +
+	"\xd0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\xa3`\x00\x00\x00\x00)\xd4\xdeP\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xc0P\x00\x00\x00" +
+	"\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xa2P\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x84P\x00\x00\x00\x000duP\x00\x00\x00\x001]\xa0\xd0\x00\x00\x00\x002r{\xd0\x00\x00\x00\x003=\x82" +
+	"\xd0\x00\x00\x00\x004R]\xd0\x00\x00\x00\x005\x1dd\xd0\x00\x00\x00\x0062?\xd0\x00\x00\x00\x006\xfdF\xd0\x00\x00\x00\x008\x1bj`\x00\x00\x00\x008\xdd6\xe0\x00\x00\x00\x009\xfbL`\x00\x00\x00" +
+	"\x00:\xbd\x18\xe0\x00\x00\x00\x00;\xdb.`\x00\x00\x00\x00<\xa65`\x00\x00\x00\x00=\xbb\x10`\x00\x00\x00\x00>\x86\x17`\x00\x00\x00\x00?\x9a\xf2`\x00\x00\x00\x00@e\xf9`\x00\x00\x00\x00A\x84\x0e" +
+	"\xe0\x01\x02\x03\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x05\x06\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x02\x00\x000\xb0\x00\x00\x00\x00*" +
+	"0\x00\x04\x00\x00FP\x00\b\x00\x00T`\x00\f\x00\x00T`\x01\f\x00\x00FP\x01\b\x00\x008@\x00\x10LMT\x00+03\x00+05\x00+06\x00+04\x00\n<+05>-" +
+	"5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd7e&uv\x02\x00\x00v\x02\x00\x00\f\x00\x00\x00Asia/BaghdadTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x006\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffi\x86\xb1\xdc\xff\xff\xff\xff\x9e0<\xe0\x00\x00\x00\x00\x170hP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xe8\xbdP\x00" +
+	"\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbd\xc8@\x00\x00\x00\x00\x1c\xad\xc7P\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 " +
+	"lG\xe0\x00\x00\x00\x00!\\8\xe0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<\x1a\xe0\x00\x00\x00\x00$,\v\xe0\x00\x00\x00\x00%\x1b\xfc\xe0\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00'\x05\x19`\x00" +
+	"\x00\x00\x00'\xf6x\x00\x00\x00\x00\x00(纀\x00\x00\x00\x00)\xd8\xfd\x00\x00\x00\x00\x00*\xca?\x80\x00\x00\x00\x00+\xba0\x80\x00\x00\x00\x00,\xabs\x00\x00\x00\x00\x00-\x9bd\x00\x00\x00\x00\x00." +
+	"\x8c\xa6\x80\x00\x00\x00\x00/|\x97\x80\x00\x00\x00\x000m\xda\x00\x00\x00\x00\x001_\x1c\x80\x00\x00\x00\x002P_\x00\x00\x00\x00\x003@P\x00\x00\x00\x00\x0041\x92\x80\x00\x00\x00\x005!\x83\x80\x00" +
+	"\x00\x00\x006\x12\xc6\x00\x00\x00\x00\x007\x02\xb7\x00\x00\x00\x00\x007\xf3\xf9\x80\x00\x00\x00\x008\xe5<\x00\x00\x00\x00\x009\xd6~\x80\x00\x00\x00\x00:\xc6o\x80\x00\x00\x00\x00;\xb7\xb2\x00\x00\x00\x00\x00<" +
+	"\xa7\xa3\x00\x00\x00\x00\x00=\x98\xe5\x80\x00\x00\x00\x00>\x88ր\x00\x00\x00\x00?z\x19\x00\x00\x00\x00\x00@k[\x80\x00\x00\x00\x00A\\\x9e\x00\x00\x00\x00\x00BL\x8f\x00\x00\x00\x00\x00C=р\x00" +
+	"\x00\x00\x00D-\u0080\x00\x00\x00\x00E\x1f\x05\x00\x00\x00\x00\x00F\x0e\xf6\x00\x00\x00\x00\x00G\x008\x80\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00)\xa4\x00\x00\x00\x00)\xa0\x00\x04\x00\x00*0\x00\b\x00\x008@\x01\fLMT\x00BMT\x00+03" +
+	"\x00+04\x00\n<+03>-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdav\x19z\x98\x00\x00\x00\x98\x00\x00\x00\f\x00\x00\x00Asia/BahrainTZif" +
+	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\xa1\xf2\x9d0\x00\x00\x00\x00\x04\x8a\x92\xc0\x01\x02\x00\x000P\x00\x00\x00\x008@\x00" +
+	"\x04\x00\x00*0\x00\bLMT\x00+04\x00+03\x00\n<+03>-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x87\xb3<\xe8\x02\x00\x00\xe8\x02\x00\x00\t\x00\x00\x00As" +
+	"ia/BakuTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZ" +
+	"if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x95D\xff\xff\xff\xff\xe7\xda\fP\x00\x00" +
+	"\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\b\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a̅\xc0\x00\x00\x00\x00\x1b\xbc" +
+	"\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\8\xe0\x00\x00\x00\x00\"L)\xe0\x00\x00" +
+	"\x00\x00#<\x1a\xe0\x00\x00\x00\x00$,\v\xe0\x00\x00\x00\x00%\x1b\xfc\xe0\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00'\x05\x19`\x00\x00\x00\x00'\xf5\n`\x00\x00\x00\x00(\xe5\tp\x00\x00\x00\x00)\xd4" +
+	"\xfap\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x001]\xd9\x10\x00\x00\x00\x002r\xb4\x10\x00\x00\x00\x003=\xad\x00\x00\x00\x00\x004R\x88\x00\x00\x00\x00\x005\x1d\x8f\x00\x00\x00\x00\x0062j\x00\x00\x00" +
+	"\x00\x006\xfdq\x00\x00\x00\x00\x008\x1b\x86\x80\x00\x00\x00\x008\xddS\x00\x00\x00\x00\x009\xfbh\x80\x00\x00\x00\x00:\xbd5\x00\x00\x00\x00\x00;\xdbJ\x80\x00\x00\x00\x00<\xa6Q\x80\x00\x00\x00\x00=\xbb" +
+	",\x80\x00\x00\x00\x00>\x863\x80\x00\x00\x00\x00?\x9b\x0e\x80\x00\x00\x00\x00@f\x15\x80\x00\x00\x00\x00A\x84+\x00\x00\x00\x00\x00BE\xf7\x80\x00\x00\x00\x00Cd\r\x00\x00\x00\x00\x00D%ـ\x00\x00" +
+	"\x00\x00EC\xef\x00\x00\x00\x00\x00F\x05\xbb\x80\x00\x00\x00\x00G#\xd1\x00\x00\x00\x00\x00G\xee\xd8\x00\x00\x00\x00\x00I\x03\xb3\x00\x00\x00\x00\x00Iκ\x00\x00\x00\x00\x00J\xe3\x95\x00\x00\x00\x00\x00K\xae" +
+	"\x9c\x00\x00\x00\x00\x00Ḻ\x80\x00\x00\x00\x00M\x8e~\x00\x00\x00\x00\x00N\xac\x93\x80\x00\x00\x00\x00On`\x00\x00\x00\x00\x00P\x8cu\x80\x00\x00\x00\x00QW|\x80\x00\x00\x00\x00RlW\x80\x00\x00" +
+	"\x00\x00S7^\x80\x00\x00\x00\x00TL9\x80\x00\x00\x00\x00U\x17@\x80\x00\x00\x00\x00V,\x1b\x80\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x04\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00.\xbc\x00\x00\x00\x00*0\x00\x04\x00\x00FP\x01\b\x00\x008@\x00\f" +
+	"\x00\x008@\x01\fLMT\x00+03\x00+05\x00+04\x00\n<+04>-4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x88\xf6C\x84\x98\x00\x00\x00\x98\x00\x00\x00\f\x00\x00" +
+	"\x00Asia/BangkokTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00" +
+	"\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xffV\xb6\x85\xc4\xff\xff\xff\xff" +
+	"\xa2jg\xc4\x01\x02\x00\x00^<\x00\x00\x00\x00^<\x00\x04\x00\x00bp\x00\bLMT\x00BMT\x00+07\x00\n<+07>-7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x87" +
+	"\xbd\xedL\xf1\x02\x00\x00\xf1\x02\x00\x00\f\x00\x00\x00Asia/BarnaulTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00C\x00\x00\x00\x05\x00\x00" +
+	"\x00\x10\xff\xff\xff\xff\xa1\xd5}\xfc\xff\xff\xff\xff\xb5\xa3\xe1 \x00\x00\x00\x00\x15'o\x90\x00\x00\x00\x00\x16\x18\xa4\x00\x00\x00\x00\x00\x17\b\xa3\x10\x00\x00\x00\x00\x17\xf9׀\x00\x00\x00\x00\x18\xe9\u0590\x00\x00" +
+	"\x00\x00\x19\xdb\v\x00\x00\x00\x00\x00\x1a\xcc[\x90\x00\x00\x00\x00\x1b\xbch\xb0\x00\x00\x00\x00\x1c\xacY\xb0\x00\x00\x00\x00\x1d\x9cJ\xb0\x00\x00\x00\x00\x1e\x8c;\xb0\x00\x00\x00\x00\x1f|,\xb0\x00\x00\x00\x00 l" +
+	"\x1d\xb0\x00\x00\x00\x00!\\\x0e\xb0\x00\x00\x00\x00\"K\xff\xb0\x00\x00\x00\x00#;\xf0\xb0\x00\x00\x00\x00$+\xe1\xb0\x00\x00\x00\x00%\x1bҰ\x00\x00\x00\x00&\vð\x00\x00\x00\x00'\x04\xef0\x00\x00" +
+	"\x00\x00'\xf4\xe00\x00\x00\x00\x00(\xe4\xdf@\x00\x00\x00\x00)x\x87@\x00\x00\x00\x00)\xd4\xc20\x00\x00\x00\x00*ij0\x00\x00\x00\x00+\xb4\xa40\x00\x00\x00\x00,\xa4\x950\x00\x00\x00\x00-\x94" +
+	"\x860\x00\x00\x00\x00.\x84w0\x00\x00\x00\x00/th0\x00\x00\x00\x00/\xc7L\x80\x00\x00\x00\x000dg@\x00\x00\x00\x001]\x92\xc0\x00\x00\x00\x002rm\xc0\x00\x00\x00\x003=t\xc0\x00\x00" +
+	"\x00\x004RO\xc0\x00\x00\x00\x005\x1dV\xc0\x00\x00\x00\x00621\xc0\x00\x00\x00\x006\xfd8\xc0\x00\x00\x00\x008\x1bN@\x00\x00\x00\x008\xdd\x1a\xc0\x00\x00\x00\x009\xfb0@\x00\x00\x00\x00:\xbc" +
+	"\xfc\xc0\x00\x00\x00\x00;\xdb\x12@\x00\x00\x00\x00<\xa6\x19@\x00\x00\x00\x00=\xba\xf4@\x00\x00\x00\x00>\x85\xfb@\x00\x00\x00\x00?\x9a\xd6@\x00\x00\x00\x00@e\xdd@\x00\x00\x00\x00A\x83\xf2\xc0\x00\x00" +
+	"\x00\x00BE\xbf@\x00\x00\x00\x00Cc\xd4\xc0\x00\x00\x00\x00D%\xa1@\x00\x00\x00\x00EC\xb6\xc0\x00\x00\x00\x00F\x05\x83@\x00\x00\x00\x00G#\x98\xc0\x00\x00\x00\x00G\xee\x9f\xc0\x00\x00\x00\x00I\x03" +
+	"z\xc0\x00\x00\x00\x00I\u0381\xc0\x00\x00\x00\x00J\xe3\\\xc0\x00\x00\x00\x00K\xaec\xc0\x00\x00\x00\x00L\xccy@\x00\x00\x00\x00M\x8eE\xc0\x00\x00\x00\x00TK\xf30\x00\x00\x00\x00V\xf6\xea@\x01\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01" +
+	"\x04\x01\x03\x01\x03\x00\x00N\x84\x00\x00\x00\x00T`\x00\x04\x00\x00p\x80\x01\b\x00\x00bp\x00\f\x00\x00bp\x01\fLMT\x00+06\x00+08\x00+07\x00\n<+07>-7\n" +
+	"PK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7\x11\xe1[\xdc\x02\x00\x00\xdc\x02\x00\x00\v\x00\x00\x00Asia/BeirutTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xffV\xb6¸\xff\xff\xff\xff\xa2ec\xe0\xff\xff\xff\xff\xa3{\x82P\xff\xff\xff\xff\xa4N\x80`\xff\xff\xff\xff\xa5?\xb4\xd0\xff\xff\xff\xff" +
+	"\xa6%'\xe0\xff\xff\xff\xff\xa7'\x7f\xd0\xff\xff\xff\xff\xa8)\xf3\xe0\xff\xff\xff\xff\xa8\xeb\xb2P\xff\xff\xff\xff\xe8*\x85\xe0\xff\xff\xff\xff\xe8\xf4-P\xff\xff\xff\xff\xea\v\xb9`\xff\xff\xff\xff\xea\xd5`\xd0" +
+	"\xff\xff\xff\xff\xeb\xec\xec\xe0\xff\xff\xff\xff추P\xff\xff\xff\xff\xed\xcfq\xe0\xff\xff\xff\xff\xee\x99\x19P\xff\xff\xff\xffﰥ`\xff\xff\xff\xff\xf0zL\xd0\x00\x00\x00\x00\x04\xa6^`\x00\x00\x00\x00" +
+	"\x05+w\xd0\x00\x00\x00\x00\x06C\x03\xe0\x00\x00\x00\x00\a\f\xabP\x00\x00\x00\x00\b$7`\x00\x00\x00\x00\b\xed\xde\xd0\x00\x00\x00\x00\n\x05j\xe0\x00\x00\x00\x00\n\xcf\x12P\x00\x00\x00\x00\v\xe7\xef\xe0" +
+	"\x00\x00\x00\x00\f\xb1\x97P\x00\x00\x00\x00\r\xc9#`\x00\x00\x00\x00\x0e\x92\xca\xd0\x00\x00\x00\x00\x0f\xa9\x05`\x00\x00\x00\x00\x10r\xac\xd0\x00\x00\x00\x00\x1a\xf4.\xe0\x00\x00\x00\x00\x1bќ\xd0\x00\x00\x00\x00" +
+	"\x1c\xd5b`\x00\x00\x00\x00\x1d\xb2\xd0P\x00\x00\x00\x00\x1e\xb6\x95\xe0\x00\x00\x00\x00\x1f\x94\x03\xd0\x00\x00\x00\x00 \x97\xc9`\x00\x00\x00\x00!u7P\x00\x00\x00\x00\"\xa3,\xe0\x00\x00\x00\x00#W\xbcP" +
+	"\x00\x00\x00\x00$g_`\x00\x00\x00\x00%8\xef\xd0\x00\x00\x00\x00&<\xb5`\x00\x00\x00\x00'\x1a#P\x00\x00\x00\x00(\x1d\xe8\xe0\x00\x00\x00\x00(\xfbV\xd0\x00\x00\x00\x00*\x00m\xe0\x00\x00\x00\x00" +
+	"*\xce\t\xd0\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000duP\x00\x00\x00\x001]\xae\xe0" +
+	"\x00\x00\x00\x002M\x91\xd0\x00\x00\x00\x003=\x90\xe0\x00\x00\x00\x004-s\xd0\x00\x00\x00\x005\x1dr\xe0\x00\x00\x00\x006\rU\xd0\x00\x00\x00\x006\xfdT\xe0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00!H\x00\x00\x00\x00" +
+	"*0\x01\x04\x00\x00\x1c \x00\tLMT\x00EEST\x00EET\x00\nEET-2EEST,M3.5.0/0,M10.5.0/0\nPK\x03\x04\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x000]*\x1bj\x02\x00\x00j\x02\x00\x00\f\x00\x00\x00Asia/BishkekTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x004\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19~\x10\xff\xff\xff\xff\xb5\xa3\xef0\x00\x00\x00\x00\x15'}\xa0\x00\x00\x00\x00\x16\x18\xb2\x10\x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xe5\x90\x00\x00" +
+	"\x00\x00\x18\xe9\xe4\xa0\x00\x00\x00\x00\x19\xdb\x19\x10\x00\x00\x00\x00\x1a\xcci\xa0\x00\x00\x00\x00\x1b\xbcv\xc0\x00\x00\x00\x00\x1c\xacg\xc0\x00\x00\x00\x00\x1d\x9cX\xc0\x00\x00\x00\x00\x1e\x8cI\xc0\x00\x00\x00\x00\x1f|" +
+	":\xc0\x00\x00\x00\x00 l+\xc0\x00\x00\x00\x00!\\\x1c\xc0\x00\x00\x00\x00\"L\r\xc0\x00\x00\x00\x00#;\xfe\xc0\x00\x00\x00\x00$+\xef\xc0\x00\x00\x00\x00%\x1b\xe0\xc0\x00\x00\x00\x00&\v\xd1\xc0\x00\x00" +
+	"\x00\x00'\x04\xfd@\x00\x00\x00\x00'\xf4\xee@\x00\x00\x00\x00(\xbe\xa3\xc0\x00\x00\x00\x00)\xe770\x00\x00\x00\x00*ĥ \x00\x00\x00\x00+\xc7\x190\x00\x00\x00\x00,\xa4\x87 \x00\x00\x00\x00-\xa6" +
+	"\xfb0\x00\x00\x00\x00.\x84i \x00\x00\x00\x00/\x86\xdd0\x00\x00\x00\x000dK \x00\x00\x00\x001f\xbf0\x00\x00\x00\x002Mg\xa0\x00\x00\x00\x003=\x89\xd8\x00\x00\x00\x004RV\xc8\x00\x00" +
+	"\x00\x005\x1dk\xd8\x00\x00\x00\x00628\xc8\x00\x00\x00\x006\xfdM\xd8\x00\x00\x00\x008\x1bUH\x00\x00\x00\x008\xdd/\xd8\x00\x00\x00\x009\xfb7H\x00\x00\x00\x00:\xbd\x11\xd8\x00\x00\x00\x00;\xdb" +
+	"\x19H\x00\x00\x00\x00<\xa6.X\x00\x00\x00\x00=\xba\xfbH\x00\x00\x00\x00>\x86\x10X\x00\x00\x00\x00?\x9a\xddH\x00\x00\x00\x00@e\xf2X\x00\x00\x00\x00A\x83\xf9\xc8\x00\x00\x00\x00BE\xd4X\x00\x00" +
+	"\x00\x00B\xfb\x92 \x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x03\x00\x00" +
+	"E\xf0\x00\x00\x00\x00FP\x00\x04\x00\x00bp\x01\b\x00\x00T`\x00\f\x00\x00T`\x01\fLMT\x00+05\x00+07\x00+06\x00\n<+06>-6\nPK\x03\x04\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\xa7f^]@\x01\x00\x00@\x01\x00\x00\v\x00\x00\x00Asia/BruneiTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
 	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x18\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x83\x80\xff\xff\xff\xff\xb5\xa3\xef0\x00\x00\x00\x00\x15'}\xa0\x00\x00\x00\x00\x16\x18\xb2\x10\x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xe5\x90\x00\x00\x00" +
-	"\x00\x18\xe9\xe4\xa0\x00\x00\x00\x00\x19\xdb\x19\x10\x00\x00\x00\x00\x1a\xcci\xa0\x00\x00\x00\x00\x1b\xbcv\xc0\x00\x00\x00\x00\x1c\xacg\xc0\x00\x00\x00\x00\x1d\x9cX\xc0\x00\x00\x00\x00\x1e\x8cI\xc0\x00\x00\x00\x00\x1f|:" +
-	"\xc0\x00\x00\x00\x00 l+\xc0\x00\x00\x00\x00!\\\x1c\xc0\x00\x00\x00\x00\"L\r\xc0\x00\x00\x00\x00#;\xfe\xc0\x00\x00\x00\x00$+\xef\xc0\x00\x00\x00\x00%\x1b\xe0\xc0\x00\x00\x00\x00&\v\xd1\xc0\x00\x00\x00" +
-	"\x00'\x04\xfd@\x00\x00\x00\x00'\xf4\xee@\x00\x00\x00\x00(ʏP\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x00\x00@\x80\x00\x00\x00\x00FP\x00\x04\x00\x00b" +
-	"p\x01\b\x00\x00T`\x00\f\x00\x00T`\x01\fLMT\x00+05\x00+07\x00+06\x00\n<+05>-5\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xa1\xfax\x98g\x02" +
-	"\x00\x00g\x02\x00\x00\r\x00\x1c\x00Asia/QostanayUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00" +
+	"\x12\x00\x00\x00\x05\x00\x00\x00\x18\xff\xff\xff\xff\xad\x8a\x06\x90\xff\xff\xff\xff\xbagG\x88\xff\xff\xff\xff\xbf{'\x80\xff\xff\xff\xff\xbf\xf3\x1bP\xff\xff\xff\xff\xc1]\xac\x80\xff\xff\xff\xff\xc1ՠP\xff\xff\xff" +
+	"\xff\xc3>\xe0\x00\xff\xff\xff\xffö\xd3\xd0\xff\xff\xff\xff\xc5 \x13\x80\xff\xff\xff\xffŘ\aP\xff\xff\xff\xff\xc7\x01G\x00\xff\xff\xff\xff\xc7y:\xd0\xff\xff\xff\xff\xc8\xe3\xcc\x00\xff\xff\xff\xff\xc9[\xbf" +
+	"\xd0\xff\xff\xff\xff\xca\xc4\xff\x80\xff\xff\xff\xff\xcb<\xf3P\xff\xff\xff\xffˑX\x00\xff\xff\xff\xff\xd2Hm\xf0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x03\x00\x00gp\x00\x00\x00\x00i" +
+	"x\x00\x04\x00\x00u0\x01\n\x00\x00p\x80\x00\x10\x00\x00~\x90\x00\x14LMT\x00+0730\x00+0820\x00+08\x00+09\x00\n<+08>-8\nPK\x03\x04\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x9a\x1a\xdc\xca\xdc\x00\x00\x00\xdc\x00\x00\x00\r\x00\x00\x00Asia/CalcuttaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\a\x00\x00\x00\x05\x00\x00\x00\x16\xff\xff\xff\xff&\xba\x18(\xff\xff\xff\xffC\xe7\xeb0\xff\xff\xff\xff\x87\x9d\xbc\xba\xff\xff\xff\xff\xcaی(\xff\xff\xff\xff\xcc\x05q\x18\xff\xff\xff\xff̕2\xa8" +
+	"\xff\xff\xff\xff\xd2t\x12\x98\x01\x02\x03\x04\x03\x04\x03\x00\x00R\xd8\x00\x00\x00\x00R\xd0\x00\x04\x00\x00KF\x00\b\x00\x00MX\x00\f\x00\x00[h\x01\x10LMT\x00HMT\x00MMT\x00IST" +
+	"\x00+0630\x00\nIST-5:30\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\xcd\xdf\x05\xee\x02\x00\x00\xee\x02\x00\x00\n\x00\x00\x00Asia/ChitaTZi" +
+	"f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xdb\xf9\xa0\xff\xff\xff\xff\xb5\xa3\xc5\x00\x00\x00\x00\x00\x15'Sp\x00\x00\x00\x00" +
+	"\x16\x18\x87\xe0\x00\x00\x00\x00\x17\b\x86\xf0\x00\x00\x00\x00\x17\xf9\xbb`\x00\x00\x00\x00\x18\xe9\xbap\x00\x00\x00\x00\x19\xda\xee\xe0\x00\x00\x00\x00\x1a\xcc?p\x00\x00\x00\x00\x1b\xbcL\x90\x00\x00\x00\x00\x1c\xac=\x90" +
+	"\x00\x00\x00\x00\x1d\x9c.\x90\x00\x00\x00\x00\x1e\x8c\x1f\x90\x00\x00\x00\x00\x1f|\x10\x90\x00\x00\x00\x00 l\x01\x90\x00\x00\x00\x00![\xf2\x90\x00\x00\x00\x00\"K\xe3\x90\x00\x00\x00\x00#;Ԑ\x00\x00\x00\x00" +
+	"$+Ő\x00\x00\x00\x00%\x1b\xb6\x90\x00\x00\x00\x00&\v\xa7\x90\x00\x00\x00\x00'\x04\xd3\x10\x00\x00\x00\x00'\xf4\xc4\x10\x00\x00\x00\x00(\xe4\xc3 \x00\x00\x00\x00)xk \x00\x00\x00\x00)Ԧ\x10" +
+	"\x00\x00\x00\x00*ė\x10\x00\x00\x00\x00+\xb4\x88\x10\x00\x00\x00\x00,\xa4y\x10\x00\x00\x00\x00-\x94j\x10\x00\x00\x00\x00.\x84[\x10\x00\x00\x00\x00/tL\x10\x00\x00\x00\x000d=\x10\x00\x00\x00\x00" +
+	"1]h\x90\x00\x00\x00\x002rC\x90\x00\x00\x00\x003=J\x90\x00\x00\x00\x004R%\x90\x00\x00\x00\x005\x1d,\x90\x00\x00\x00\x0062\a\x90\x00\x00\x00\x006\xfd\x0e\x90\x00\x00\x00\x008\x1b$\x10" +
+	"\x00\x00\x00\x008\xdc\xf0\x90\x00\x00\x00\x009\xfb\x06\x10\x00\x00\x00\x00:\xbcҐ\x00\x00\x00\x00;\xda\xe8\x10\x00\x00\x00\x00<\xa5\xef\x10\x00\x00\x00\x00=\xba\xca\x10\x00\x00\x00\x00>\x85\xd1\x10\x00\x00\x00\x00" +
+	"?\x9a\xac\x10\x00\x00\x00\x00@e\xb3\x10\x00\x00\x00\x00A\x83Ȑ\x00\x00\x00\x00BE\x95\x10\x00\x00\x00\x00Cc\xaa\x90\x00\x00\x00\x00D%w\x10\x00\x00\x00\x00EC\x8c\x90\x00\x00\x00\x00F\x05Y\x10" +
+	"\x00\x00\x00\x00G#n\x90\x00\x00\x00\x00G\xeeu\x90\x00\x00\x00\x00I\x03P\x90\x00\x00\x00\x00I\xceW\x90\x00\x00\x00\x00J\xe32\x90\x00\x00\x00\x00K\xae9\x90\x00\x00\x00\x00L\xccO\x10\x00\x00\x00\x00" +
+	"M\x8e\x1b\x90\x00\x00\x00\x00TK\xc9\x00\x00\x00\x00\x00V\xf6\xce \x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x01\x03\x00\x00j`\x00\x00\x00\x00p\x80\x00\x04\x00\x00\x8c\xa0\x01\b\x00\x00~\x90\x00\f\x00\x00~\x90\x01\f\x00\x00\x8c\xa0" +
+	"\x00\bLMT\x00+08\x00+10\x00+09\x00\n<+09>-9\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81z&\x80k\x02\x00\x00k\x02\x00\x00\x0f\x00\x00\x00Asi" +
+	"a/ChoibalsanTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00" +
+	"\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xff\x86\xd3\xe7(\x00\x00\x00\x00\x0f" +
+	"\vܐ\x00\x00\x00\x00\x18\xe9Ȁ\x00\x00\x00\x00\x19\xda\xee\xe0\x00\x00\x00\x00\x1a\xcc?p\x00\x00\x00\x00\x1b\xbc\"`\x00\x00\x00\x00\x1c\xac!p\x00\x00\x00\x00\x1d\x9c\x04`\x00\x00\x00\x00\x1e\x8c\x03p\x00" +
+	"\x00\x00\x00\x1f{\xe6`\x00\x00\x00\x00 k\xe5p\x00\x00\x00\x00![\xc8`\x00\x00\x00\x00\"K\xc7p\x00\x00\x00\x00#;\xaa`\x00\x00\x00\x00$+\xa9p\x00\x00\x00\x00%\x1b\x8c`\x00\x00\x00\x00&" +
+	"\v\x8bp\x00\x00\x00\x00'\x04\xa8\xe0\x00\x00\x00\x00'\xf4\xa7\xf0\x00\x00\x00\x00(\xe4\x8a\xe0\x00\x00\x00\x00)ԉ\xf0\x00\x00\x00\x00*\xc4l\xe0\x00\x00\x00\x00+\xb4k\xf0\x00\x00\x00\x00,\xa4N\xe0\x00" +
+	"\x00\x00\x00-\x94M\xf0\x00\x00\x00\x00.\x840\xe0\x00\x00\x00\x00/t/\xf0\x00\x00\x00\x000d\x12\xe0\x00\x00\x00\x001]Lp\x00\x00\x00\x002M/`\x00\x00\x00\x003=.p\x00\x00\x00\x004" +
+	"-\x11`\x00\x00\x00\x005\x1d\x10p\x00\x00\x00\x006\f\xf3`\x00\x00\x00\x00:饐\x00\x00\x00\x00;\xb4\x9e\x80\x00\x00\x00\x00<\xa4\x9d\x90\x00\x00\x00\x00=\x94\x80\x80\x00\x00\x00\x00>\x84\x7f\x90\x00" +
+	"\x00\x00\x00?tb\x80\x00\x00\x00\x00@da\x90\x00\x00\x00\x00ATD\x80\x00\x00\x00\x00BDC\x90\x00\x00\x00\x00C4&\x80\x00\x00\x00\x00D$%\x90\x00\x00\x00\x00E\x1dC\x00\x00\x00\x00\x00G" +
+	"\xef\xaa\xf0\x00\x00\x00\x00U\x15\x9a\xa0\x00\x00\x00\x00V\x05ap\x00\x00\x00\x00V\xf5|\xa0\x00\x00\x00\x00W\xe5Cp\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" +
+	"\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x02\x05\x02\x05\x02\x00\x00kX\x00\x00\x00\x00bp\x00\x04\x00\x00p\x80\x00\b\x00\x00~\x90\x00\f\x00\x00\x8c\xa0\x01\x10\x00\x00~\x90" +
+	"\x01\fLMT\x00+07\x00+08\x00+09\x00+10\x00\n<+08>-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00\x00\x0e\x00\x00" +
+	"\x00Asia/ChongqingTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00" +
+	"\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff~6C)\xff\xff" +
+	"\xff\xff\xa0\x97\xa2\x80\xff\xff\xff\xff\xa1y\x04\xf0\xff\xff\xff\xff\xc8Y^\x80\xff\xff\xff\xff\xc9\t\xf9p\xff\xff\xff\xff\xc9ӽ\x00\xff\xff\xff\xff\xcb\x05\x8a\xf0\xff\xff\xff\xff\xcb|@\x00\xff\xff\xff\xff\xd2;" +
+	">\xf0\xff\xff\xff\xffӋ{\x80\xff\xff\xff\xff\xd4B\xad\xf0\xff\xff\xff\xff\xd5E\"\x00\xff\xff\xff\xff\xd6L\xbf\xf0\xff\xff\xff\xff\xd7<\xbf\x00\xff\xff\xff\xff\xd8\x06fp\xff\xff\xff\xff\xd9\x1d\xf2\x80\xff\xff" +
+	"\xff\xff\xd9A|\xf0\x00\x00\x00\x00\x1e\xbaR \x00\x00\x00\x00\x1fi\x9b\x90\x00\x00\x00\x00 ~\x84\xa0\x00\x00\x00\x00!I}\x90\x00\x00\x00\x00\"g\xa1 \x00\x00\x00\x00#)_\x90\x00\x00\x00\x00$G" +
+	"\x83 \x00\x00\x00\x00%\x12|\x10\x00\x00\x00\x00&'e \x00\x00\x00\x00&\xf2^\x10\x00\x00\x00\x00(\aG \x00\x00\x00\x00(\xd2@\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00q\xd7\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\bLMT\x00CDT\x00CST\x00\nCST-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00\x00\x0e\x00\x00\x00Asia/ChungkingTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00" +
+	"\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff~6C)\xff\xff\xff\xff\xa0\x97\xa2\x80\xff\xff\xff\xff\xa1y\x04\xf0\xff\xff\xff\xff\xc8Y^\x80\xff\xff\xff\xff\xc9\t\xf9p\xff\xff\xff\xff\xc9ӽ\x00\xff\xff\xff\xff\xcb" +
+	"\x05\x8a\xf0\xff\xff\xff\xff\xcb|@\x00\xff\xff\xff\xff\xd2;>\xf0\xff\xff\xff\xffӋ{\x80\xff\xff\xff\xff\xd4B\xad\xf0\xff\xff\xff\xff\xd5E\"\x00\xff\xff\xff\xff\xd6L\xbf\xf0\xff\xff\xff\xff\xd7<\xbf\x00\xff" +
+	"\xff\xff\xff\xd8\x06fp\xff\xff\xff\xff\xd9\x1d\xf2\x80\xff\xff\xff\xff\xd9A|\xf0\x00\x00\x00\x00\x1e\xbaR \x00\x00\x00\x00\x1fi\x9b\x90\x00\x00\x00\x00 ~\x84\xa0\x00\x00\x00\x00!I}\x90\x00\x00\x00\x00\"" +
+	"g\xa1 \x00\x00\x00\x00#)_\x90\x00\x00\x00\x00$G\x83 \x00\x00\x00\x00%\x12|\x10\x00\x00\x00\x00&'e \x00\x00\x00\x00&\xf2^\x10\x00\x00\x00\x00(\aG \x00\x00\x00\x00(\xd2@\x10\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00q\xd7\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\bLMT\x00CDT\x00CST\x00\nC" +
+	"ST-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\\\x91\x87\xbb\xf7\x00\x00\x00\xf7\x00\x00\x00\f\x00\x00\x00Asia/ColomboTZif2\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\a\x00\x00\x00\x18\xff\xff\xff\xffV\xb6\x99$\xff\xff\xff\xff\x87\x9d\xbd\x1c\xff\xff\xff\xff\xcbZ\x1c(\xff\xff\xff\xff̕+\xa0\xff\xff\xff\xff\xd2u" +
+	"\x808\x00\x00\x00\x001\xa6\x00(\x00\x00\x00\x002q\x00 \x00\x00\x00\x00D?\xea(\x01\x02\x03\x04\x02\x05\x06\x02\x00\x00J\xdc\x00\x00\x00\x00J\xe4\x00\x04\x00\x00MX\x00\b\x00\x00T`\x01\x0e\x00\x00" +
+	"[h\x01\x12\x00\x00[h\x00\x12\x00\x00T`\x00\x0eLMT\x00MMT\x00+0530\x00+06\x00+0630\x00\n<+0530>-5:30\nPK\x03\x04\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00?Y\xaf\x19\xe7\x00\x00\x00\xe7\x00\x00\x00\n\x00\x00\x00Asia/DaccaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\a\x00\x00\x00\x06\x00\x00\x00\x1c\xff\xff\xff\xffi\x86\x86\xbc\xff\xff\xff\xff\xcaۆ\xb0\xff\xff\xff\xff\xcc\x05q\x18\xff\xff\xff\xff̕2\xa8\xff\xff\xff\xffݨҘ\x00\x00\x00\x00J;\xc4\x10\x00\x00\x00" +
+	"\x00K<ؐ\x01\x02\x03\x02\x04\x05\x04\x00\x00T\xc4\x00\x00\x00\x00R\xd0\x00\x04\x00\x00[h\x00\b\x00\x00MX\x00\x0e\x00\x00T`\x00\x14\x00\x00bp\x01\x18LMT\x00HMT\x00+063" +
+	"0\x00+0530\x00+06\x00+07\x00\n<+06>-6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x87\a\xeci\xd2\x04\x00\x00\xd2\x04\x00\x00\r\x00\x00\x00Asia/" +
+	"DamascusTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00T" +
+	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00y\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff\xa1\xf2\xabx\xff\xff\xff\xff\xa2\x81/\x80\xff" +
+	"\xff\xff\xff\xa3^\x9dp\xff\xff\xff\xff\xa4a\x11\x80\xff\xff\xff\xff\xa5>\x7fp\xff\xff\xff\xff\xa6@\xf3\x80\xff\xff\xff\xff\xa7\x1eap\xff\xff\xff\xff\xa8 Հ\xff\xff\xff\xff\xa9\a}\xf0\xff\xff\xff\xff\xf1" +
+	"\x8fR\x00\xff\xff\xff\xff\xf2[\x9cp\xff\xff\xff\xff\xf3s(\x80\xff\xff\xff\xff\xf4;~p\xff\xff\xff\xff\xf5U\xad\x80\xff\xff\xff\xff\xf6\x1fT\xf0\xff\xff\xff\xff\xf76\xe1\x00\xff\xff\xff\xff\xf7\xff6\xf0\xff" +
+	"\xff\xff\xff\xf9\x0e\xda\x00\xff\xff\xff\xff\xf9\xe1\xbb\xf0\xff\xff\xff\xff\xfa\xf9H\x00\xff\xff\xff\xff\xfb\xc2\xefp\xff\xff\xff\xff\xfc\xdb\xcd\x00\xff\xff\xff\xff\xfd\xa5tp\xff\xff\xff\xff\xfe\xbd\x00\x80\xff\xff\xff\xff\xff" +
+	"\x86\xa7\xf0\x00\x00\x00\x00\x00\x9e4\x00\x00\x00\x00\x00\x01g\xdbp\x00\x00\x00\x00\x02\x7fg\x80\x00\x00\x00\x00\x03I\x0e\xf0\x00\x00\x00\x00\x04a\xec\x80\x00\x00\x00\x00\x05+\x93\xf0\x00\x00\x00\x00\x06C \x00\x00" +
+	"\x00\x00\x00\a\f\xc7p\x00\x00\x00\x00\b$S\x80\x00\x00\x00\x00\b\xed\xfa\xf0\x00\x00\x00\x00\n\x05\x87\x00\x00\x00\x00\x00\n\xcf.p\x00\x00\x00\x00\v\xe8\f\x00\x00\x00\x00\x00\f\xb1\xb3p\x00\x00\x00\x00\r" +
+	"\xc9?\x80\x00\x00\x00\x00\x0ekY\xf0\x00\x00\x00\x00\x0f\xaas\x00\x00\x00\x00\x00\x10L\x8dp\x00\x00\x00\x00\x18\xf4\xc5\x00\x00\x00\x00\x00\x19\xdbmp\x00\x00\x00\x00\x1a\xd7J\x00\x00\x00\x00\x00\x1b\xbd\xf2p\x00" +
+	"\x00\x00\x00\x1eU#\x00\x00\x00\x00\x00\x1f\x8a\xe5p\x00\x00\x00\x00 Gz\x00\x00\x00\x00\x00!\x89\x19\xf0\x00\x00\x00\x00\"<t\x00\x00\x00\x00\x00#k\x9e\xf0\x00\x00\x00\x00$2\xbf\x80\x00\x00\x00\x00%" +
+	"%Ep\x00\x00\x00\x00&\x15D\x80\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf6[\xe0\x00\x00\x00\x00(\xe7\x90P\x00\x00\x00\x00)\xe2\x1b`\x00\x00\x00\x00*\xca\x15P\x00\x00\x00\x00+\xb2+`\x00" +
+	"\x00\x00\x00,\xa3_\xd0\x00\x00\x00\x00-\x9bG\xe0\x00\x00\x00\x00.\x8c|P\x00\x00\x00\x00/|{`\x00\x00\x00\x000m\xaf\xd0\x00\x00\x00\x001_\x00`\x00\x00\x00\x002P4\xd0\x00\x00\x00\x003" +
+	">\xe2`\x00\x00\x00\x0041hP\x00\x00\x00\x005\x1e\xc4`\x00\x00\x00\x006\x12\x9b\xd0\x00\x00\x00\x007\x02\x9a\xe0\x00\x00\x00\x007\xf3\xcfP\x00\x00\x00\x008\xe5\x1f\xe0\x00\x00\x00\x009\xd6TP\x00" +
+	"\x00\x00\x00:\xc6S`\x00\x00\x00\x00;\xb7\x87\xd0\x00\x00\x00\x00<\xa7\x86\xe0\x00\x00\x00\x00=\x98\xbbP\x00\x00\x00\x00>\x88\xba`\x00\x00\x00\x00?y\xee\xd0\x00\x00\x00\x00@k?`\x00\x00\x00\x00A" +
+	"\\s\xd0\x00\x00\x00\x00BLr\xe0\x00\x00\x00\x00C=\xa7P\x00\x00\x00\x00D-\xa6`\x00\x00\x00\x00E\x12\xfdP\x00\x00\x00\x00F\f6\xe0\x00\x00\x00\x00G*>P\x00\x00\x00\x00G\xf5S`\x00" +
+	"\x00\x00\x00I\vq\xd0\x00\x00\x00\x00I\xcb\xfa\xe0\x00\x00\x00\x00J\xea\x02P\x00\x00\x00\x00K\xb5\x17`\x00\x00\x00\x00L\xc9\xe4P\x00\x00\x00\x00M\x94\xf9`\x00\x00\x00\x00N\xa9\xc6P\x00\x00\x00\x00O" +
+	"t\xdb`\x00\x00\x00\x00P\x89\xa8P\x00\x00\x00\x00QT\xbd`\x00\x00\x00\x00Ri\x8aP\x00\x00\x00\x00S4\x9f`\x00\x00\x00\x00TR\xa6\xd0\x00\x00\x00\x00U\x14\x81`\x00\x00\x00\x00V2\x88\xd0\x00" +
+	"\x00\x00\x00V\xf4c`\x00\x00\x00\x00X\x12j\xd0\x00\x00\x00\x00X\xdd\x7f\xe0\x00\x00\x00\x00Y\xf2L\xd0\x00\x00\x00\x00Z\xbda\xe0\x00\x00\x00\x00[\xd2.\xd0\x00\x00\x00\x00\\\x9dC\xe0\x00\x00\x00\x00]" +
+	"\xb2\x10\xd0\x00\x00\x00\x00^}%\xe0\x00\x00\x00\x00_\x9b-P\x00\x00\x00\x00`]\a\xe0\x00\x00\x00\x00a{\x0fP\x00\x00\x00\x00b<\xe9\xe0\x00\x00\x00\x00cZ\xf1P\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x00\x00\"\b\x00\x00\x00\x00" +
+	"*0\x01\x04\x00\x00\x1c \x00\t\x00\x00*0\x00\rLMT\x00EEST\x00EET\x00+03\x00\n<+03>-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?Y\xaf\x19" +
+	"\xe7\x00\x00\x00\xe7\x00\x00\x00\n\x00\x00\x00Asia/DhakaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x06\x00\x00\x00\x1c\xff\xff\xff" +
+	"\xffi\x86\x86\xbc\xff\xff\xff\xff\xcaۆ\xb0\xff\xff\xff\xff\xcc\x05q\x18\xff\xff\xff\xff̕2\xa8\xff\xff\xff\xffݨҘ\x00\x00\x00\x00J;\xc4\x10\x00\x00\x00\x00K<ؐ\x01\x02\x03\x02\x04\x05\x04" +
+	"\x00\x00T\xc4\x00\x00\x00\x00R\xd0\x00\x04\x00\x00[h\x00\b\x00\x00MX\x00\x0e\x00\x00T`\x00\x14\x00\x00bp\x01\x18LMT\x00HMT\x00+0630\x00+0530\x00+06\x00" +
+	"+07\x00\n<+06>-6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Β\x1a\x8c\xaa\x00\x00\x00\xaa\x00\x00\x00\t\x00\x00\x00Asia/DiliTZif2\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x92\xe6\x18\xc4\xff\xff\xff\xff˙2\xf0\x00\x00\x00\x00\v\xea0p\x00\x00\x00\x009Ù\x00\x01" +
+	"\x02\x01\x02\x00\x00u\xbc\x00\x00\x00\x00p\x80\x00\x04\x00\x00~\x90\x00\bLMT\x00+08\x00+09\x00\n<+09>-9\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xed\x8c\xf1\x91" +
+	"\x85\x00\x00\x00\x85\x00\x00\x00\n\x00\x00\x00Asia/DubaiTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff" +
+	"\xff\xa1\xf2\x99\xa8\x01\x00\x003\xd8\x00\x00\x00\x008@\x00\x04LMT\x00+04\x00\n<+04>-4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00's\x96\x1en\x01\x00\x00n\x01\x00" +
+	"\x00\r\x00\x00\x00Asia/DushanbeTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00" +
+	"\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x83" +
+	"\x80\xff\xff\xff\xff\xb5\xa3\xef0\x00\x00\x00\x00\x15'}\xa0\x00\x00\x00\x00\x16\x18\xb2\x10\x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xe5\x90\x00\x00\x00\x00\x18\xe9\xe4\xa0\x00\x00\x00\x00\x19\xdb\x19\x10\x00\x00\x00" +
+	"\x00\x1a\xcci\xa0\x00\x00\x00\x00\x1b\xbcv\xc0\x00\x00\x00\x00\x1c\xacg\xc0\x00\x00\x00\x00\x1d\x9cX\xc0\x00\x00\x00\x00\x1e\x8cI\xc0\x00\x00\x00\x00\x1f|:\xc0\x00\x00\x00\x00 l+\xc0\x00\x00\x00\x00!\\\x1c" +
+	"\xc0\x00\x00\x00\x00\"L\r\xc0\x00\x00\x00\x00#;\xfe\xc0\x00\x00\x00\x00$+\xef\xc0\x00\x00\x00\x00%\x1b\xe0\xc0\x00\x00\x00\x00&\v\xd1\xc0\x00\x00\x00\x00'\x04\xfd@\x00\x00\x00\x00'\xf4\xee@\x00\x00\x00" +
+	"\x00(ʏP\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x00\x00@\x80\x00\x00\x00\x00FP\x00\x04\x00\x00bp\x01\b\x00\x00T`\x00\f\x00\x00T`\x01\fL" +
+	"MT\x00+05\x00+07\x00+06\x00\n<+05>-5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]S\xbb\x12\xac\x03\x00\x00\xac\x03\x00\x00\x0e\x00\x00\x00Asia/F" +
+	"amagustaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00T" +
+	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff\xa5w\x1e,\x00\x00\x00\x00\t\xed\xaf\xe0\x00" +
+	"\x00\x00\x00\nݒ\xd0\x00\x00\x00\x00\v\xfad\xe0\x00\x00\x00\x00\f\xbe\xc6P\x00\x00\x00\x00\r\xa49`\x00\x00\x00\x00\x0e\x8a\xe1\xd0\x00\x00\x00\x00\x0f\x84\x1b`\x00\x00\x00\x00\x10uO\xd0\x00\x00\x00\x00\x11" +
+	"c\xfd`\x00\x00\x00\x00\x12S\xe0P\x00\x00\x00\x00\x13M\x19\xe0\x00\x00\x00\x00\x143\xc2P\x00\x00\x00\x00\x15#\xc1`\x00\x00\x00\x00\x16\x13\xa4P\x00\x00\x00\x00\x17\x03\xa3`\x00\x00\x00\x00\x17\xf3\x86P\x00" +
+	"\x00\x00\x00\x18\xe3\x85`\x00\x00\x00\x00\x19\xd3hP\x00\x00\x00\x00\x1a\xc3g`\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f" +
+	"|H\xd0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$,\v\xe0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\v\xed\xe0\x00" +
+	"\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf5\n`\x00\x00\x00\x00(\xe4\xedP\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-" +
+	"\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000duP\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002M\x91\xd0\x00\x00\x00\x003=\x90\xe0\x00\x00\x00\x004-s\xd0\x00" +
+	"\x00\x00\x005\x1dr\xe0\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd\x7f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x008\xdda\x10\x00\x00\x00\x009\xfbv\x90\x00\x00\x00\x00:\xbdC\x10\x00\x00\x00\x00;" +
+	"\xdbX\x90\x00\x00\x00\x00<\xa6_\x90\x00\x00\x00\x00=\xbb:\x90\x00\x00\x00\x00>\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00" +
+	"\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I" +
+	"\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00" +
+	"\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00W" +
+	"\xd0\x7f\xd0\x00\x00\x00\x00Y\xf5(\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x02\x00\x00\x1f\xd4\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\t\x00\x00*0\x00" +
+	"\rLMT\x00EEST\x00EET\x00+03\x00\nEET-2EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00= \x17x\xea\x04\x00\x00\xea\x04\x00\x00\t\x00\x00\x00Asia/GazaTZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00x\x00\x00\x00\x05\x00\x00" +
+	"\x00\x15\xff\xff\xff\xff}\xbdJ\xb0\xff\xff\xff\xff\xc8Y\xcf\x00\xff\xff\xff\xff\xc8\xfa\xa6\x00\xff\xff\xff\xff\xc98\x9c\x80\xff\xff\xff\xff\xcc\xe5\xeb\x80\xff\xff\xff\xffͬ\xfe\x00\xff\xff\xff\xff\xce\xc7\x1f\x00\xff\xff" +
+	"\xff\xffϏ\x83\x00\xff\xff\xff\xffЩ\xa4\x00\xff\xff\xff\xffф}\x00\xff\xff\xff\xffҊ׀\xff\xff\xff\xff\xd3e\xb0\x80\xff\xff\xff\xff\xd4l\v\x00\xff\xff\xff\xff\xe86c`\xff\xff\xff\xff\xe8\xf4" +
+	"-P\xff\xff\xff\xff\xea\v\xb9`\xff\xff\xff\xff\xea\xd5`\xd0\xff\xff\xff\xff\xeb\xec\xfa\xf0\xff\xff\xff\xff\xec\xb5m\x00\xff\xff\xff\xff\xed\xcf\x7f\xf0\xff\xff\xff\xff\xee\x97\xf2\x00\xff\xff\xff\xffﰳp\xff\xff" +
+	"\xff\xff\xf0y%\x80\xff\xff\xff\xff\xf1\x91\xe6\xf0\xff\xff\xff\xff\xf2ZY\x00\xff\xff\xff\xff\xf3s\x1ap\xff\xff\xff\xff\xf4;\x8c\x80\xff\xff\xff\xff\xf5U\x9fp\xff\xff\xff\xff\xf6\x1e\x11\x80\xff\xff\xff\xff\xf76" +
+	"\xd2\xf0\xff\xff\xff\xff\xf7\xffE\x00\xff\xff\xff\xff\xf9\x18\x06p\xff\xff\xff\xff\xf9\xe1\xca\x00\xff\xff\xff\xff\xfa\xf99\xf0\xff\xff\xff\xff\xfb'BP\x00\x00\x00\x00\b|\x8b\xe0\x00\x00\x00\x00\b\xfd\xb0\xd0\x00\x00" +
+	"\x00\x00\t\xf6\xea`\x00\x00\x00\x00\n\xa63\xd0\x00\x00\x00\x00\x13\xe9\xfc`\x00\x00\x00\x00\x14![`\x00\x00\x00\x00\x1a\xfa\xc6`\x00\x00\x00\x00\x1b\x8en`\x00\x00\x00\x00\x1c\xbe\xf8\xe0\x00\x00\x00\x00\x1dw" +
+	"|\xd0\x00\x00\x00\x00\x1e\xcc\xff`\x00\x00\x00\x00\x1f`\x99P\x00\x00\x00\x00 \x82\xb1`\x00\x00\x00\x00!I\xb5\xd0\x00\x00\x00\x00\"^\x9e\xe0\x00\x00\x00\x00# ]P\x00\x00\x00\x00$Z0`\x00\x00" +
+	"\x00\x00%\x00?P\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00&\xd6\xe6\xd0\x00\x00\x00\x00'\xeb\xcf\xe0\x00\x00\x00\x00(\xc0\x03P\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xa9\x1f\xd0\x00\x00\x00\x00+\xbb" +
+	"e\xe0\x00\x00\x00\x00,\x89\x01\xd0\x00\x00\x00\x00-\x9bG\xe0\x00\x00\x00\x00._\xa9P\x00\x00\x00\x00/{)\xe0\x00\x00\x00\x000H\xc5\xd0\x00\x00\x00\x000\xe7\a\xe0\x00\x00\x00\x001dF`\x00\x00" +
+	"\x00\x002A\xc2`\x00\x00\x00\x003D(`\x00\x00\x00\x004!\xa4`\x00\x00\x00\x005$\n`\x00\x00\x00\x006\x01\x86`\x00\x00\x00\x007\x16a`\x00\x00\x00\x008\x06DP\x00\x00\x00\x008\xff" +
+	"}\xe0\x00\x00\x00\x009\xef`\xd0\x00\x00\x00\x00:\xdf_\xe0\x00\x00\x00\x00;\xcfB\xd0\x00\x00\x00\x00<\xbfA\xe0\x00\x00\x00\x00=\xaf$\xd0\x00\x00\x00\x00>\x9f#\xe0\x00\x00\x00\x00?\x8f\x06\xd0\x00\x00" +
+	"\x00\x00@\x7f\x05\xe0\x00\x00\x00\x00A\\\x81\xe0\x00\x00\x00\x00B^\xe7\xe0\x00\x00\x00\x00CA\xb7\xf0\x00\x00\x00\x00D-\xa6`\x00\x00\x00\x00E\x12\xfdP\x00\x00\x00\x00F\x0e\xd9\xe0\x00\x00\x00\x00F\xe8" +
+	"op\x00\x00\x00\x00G\xec\x18\xe0\x00\x00\x00\x00H\xb7\x11\xd0\x00\x00\x00\x00I\xcb\xfa\xe0\x00\x00\x00\x00J\xa0<`\x00\x00\x00\x00K\xad.\x9c\x00\x00\x00\x00La\xbd\xd0\x00\x00\x00\x00M\x94\xf9\x9c\x00\x00" +
+	"\x00\x00N5\xc2P\x00\x00\x00\x00Ot\xdb`\x00\x00\x00\x00P[\x91\xe0\x00\x00\x00\x00QT\xbd`\x00\x00\x00\x00RD\xa0P\x00\x00\x00\x00S4\x9f`\x00\x00\x00\x00TIlP\x00\x00\x00\x00U\x15" +
+	"\xd2\xe0\x00\x00\x00\x00V)\\`\x00\x00\x00\x00V\xf5\xc2\xf0\x00\x00\x00\x00X\x13\xca`\x00\x00\x00\x00Xդ\xf0\x00\x00\x00\x00Y\xf3\xac`\x00\x00\x00\x00Z\xb5\x86\xf0\x00\x00\x00\x00[ӎ`\x00\x00" +
+	"\x00\x00\\\x9dC\xe0\x00\x00\x00\x00]\xb3bP\x00\x00\x00\x00^~w`\x00\x00\x00\x00_\x93R`\x00\x00\x00\x00`^Y`\x00\x00\x00\x00a{\x1d`\x00\x00\x00\x00b?\x8c\xe0\x00\x00\x00\x00c\\" +
+	"^\xf0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" +
+	"\x04\x03\x04\x03\x04\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x00\x00 P\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\t\x00\x00*0\x01\r\x00\x00\x1c \x00\x11LMT\x00EEST\x00EET\x00IDT\x00IST\x00\nEET-2E" +
+	"EST,M3.4.4/50,M10.4.4/50\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00\x00\v\x00\x00\x00Asia/" +
+	"HarbinTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZi" +
+	"f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff~6C)\xff\xff\xff\xff\xa0\x97\xa2\x80\xff\xff\xff" +
+	"\xff\xa1y\x04\xf0\xff\xff\xff\xff\xc8Y^\x80\xff\xff\xff\xff\xc9\t\xf9p\xff\xff\xff\xff\xc9ӽ\x00\xff\xff\xff\xff\xcb\x05\x8a\xf0\xff\xff\xff\xff\xcb|@\x00\xff\xff\xff\xff\xd2;>\xf0\xff\xff\xff\xffӋ{" +
+	"\x80\xff\xff\xff\xff\xd4B\xad\xf0\xff\xff\xff\xff\xd5E\"\x00\xff\xff\xff\xff\xd6L\xbf\xf0\xff\xff\xff\xff\xd7<\xbf\x00\xff\xff\xff\xff\xd8\x06fp\xff\xff\xff\xff\xd9\x1d\xf2\x80\xff\xff\xff\xff\xd9A|\xf0\x00\x00\x00" +
+	"\x00\x1e\xbaR \x00\x00\x00\x00\x1fi\x9b\x90\x00\x00\x00\x00 ~\x84\xa0\x00\x00\x00\x00!I}\x90\x00\x00\x00\x00\"g\xa1 \x00\x00\x00\x00#)_\x90\x00\x00\x00\x00$G\x83 \x00\x00\x00\x00%\x12|" +
+	"\x10\x00\x00\x00\x00&'e \x00\x00\x00\x00&\xf2^\x10\x00\x00\x00\x00(\aG \x00\x00\x00\x00(\xd2@\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x00\x00q\xd7\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\bLMT\x00CDT\x00CST\x00\nCST-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00C\xbe\x86\xb6\xfc\x04\x00" +
+	"\x00\xfc\x04\x00\x00\v\x00\x00\x00Asia/HebronTZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" +
+	"\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00z\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xff}" +
+	"\xbdJ\x19\xff\xff\xff\xff\xc8Y\xcf\x00\xff\xff\xff\xff\xc8\xfa\xa6\x00\xff\xff\xff\xff\xc98\x9c\x80\xff\xff\xff\xff\xcc\xe5\xeb\x80\xff\xff\xff\xffͬ\xfe\x00\xff\xff\xff\xff\xce\xc7\x1f\x00\xff\xff\xff\xffϏ\x83\x00\xff" +
+	"\xff\xff\xffЩ\xa4\x00\xff\xff\xff\xffф}\x00\xff\xff\xff\xffҊ׀\xff\xff\xff\xff\xd3e\xb0\x80\xff\xff\xff\xff\xd4l\v\x00\xff\xff\xff\xff\xe86c`\xff\xff\xff\xff\xe8\xf4-P\xff\xff\xff\xff\xea" +
+	"\v\xb9`\xff\xff\xff\xff\xea\xd5`\xd0\xff\xff\xff\xff\xeb\xec\xfa\xf0\xff\xff\xff\xff\xec\xb5m\x00\xff\xff\xff\xff\xed\xcf\x7f\xf0\xff\xff\xff\xff\xee\x97\xf2\x00\xff\xff\xff\xffﰳp\xff\xff\xff\xff\xf0y%\x80\xff" +
+	"\xff\xff\xff\xf1\x91\xe6\xf0\xff\xff\xff\xff\xf2ZY\x00\xff\xff\xff\xff\xf3s\x1ap\xff\xff\xff\xff\xf4;\x8c\x80\xff\xff\xff\xff\xf5U\x9fp\xff\xff\xff\xff\xf6\x1e\x11\x80\xff\xff\xff\xff\xf76\xd2\xf0\xff\xff\xff\xff\xf7" +
+	"\xffE\x00\xff\xff\xff\xff\xf9\x18\x06p\xff\xff\xff\xff\xf9\xe1\xca\x00\xff\xff\xff\xff\xfa\xf99\xf0\xff\xff\xff\xff\xfb'BP\x00\x00\x00\x00\b|\x8b\xe0\x00\x00\x00\x00\b\xfd\xb0\xd0\x00\x00\x00\x00\t\xf6\xea`\x00" +
+	"\x00\x00\x00\n\xa63\xd0\x00\x00\x00\x00\x13\xe9\xfc`\x00\x00\x00\x00\x14![`\x00\x00\x00\x00\x1a\xfa\xc6`\x00\x00\x00\x00\x1b\x8en`\x00\x00\x00\x00\x1c\xbe\xf8\xe0\x00\x00\x00\x00\x1dw|\xd0\x00\x00\x00\x00\x1e" +
+	"\xcc\xff`\x00\x00\x00\x00\x1f`\x99P\x00\x00\x00\x00 \x82\xb1`\x00\x00\x00\x00!I\xb5\xd0\x00\x00\x00\x00\"^\x9e\xe0\x00\x00\x00\x00# ]P\x00\x00\x00\x00$Z0`\x00\x00\x00\x00%\x00?P\x00" +
+	"\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00&\xd6\xe6\xd0\x00\x00\x00\x00'\xeb\xcf\xe0\x00\x00\x00\x00(\xc0\x03P\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xa9\x1f\xd0\x00\x00\x00\x00+\xbbe\xe0\x00\x00\x00\x00," +
+	"\x89\x01\xd0\x00\x00\x00\x00-\x9bG\xe0\x00\x00\x00\x00._\xa9P\x00\x00\x00\x00/{)\xe0\x00\x00\x00\x000H\xc5\xd0\x00\x00\x00\x000\xe7\a\xe0\x00\x00\x00\x001dF`\x00\x00\x00\x002A\xc2`\x00" +
+	"\x00\x00\x003D(`\x00\x00\x00\x004!\xa4`\x00\x00\x00\x005$\n`\x00\x00\x00\x006\x01\x86`\x00\x00\x00\x007\x16a`\x00\x00\x00\x008\x06DP\x00\x00\x00\x008\xff}\xe0\x00\x00\x00\x009" +
+	"\xef`\xd0\x00\x00\x00\x00:\xdf_\xe0\x00\x00\x00\x00;\xcfB\xd0\x00\x00\x00\x00<\xbfA\xe0\x00\x00\x00\x00=\xaf$\xd0\x00\x00\x00\x00>\x9f#\xe0\x00\x00\x00\x00?\x8f\x06\xd0\x00\x00\x00\x00@\x7f\x05\xe0\x00" +
+	"\x00\x00\x00A\\\x81\xe0\x00\x00\x00\x00B^\xe7\xe0\x00\x00\x00\x00CA\xb7\xf0\x00\x00\x00\x00D-\xa6`\x00\x00\x00\x00E\x12\xfdP\x00\x00\x00\x00F\x0e\xd9\xe0\x00\x00\x00\x00F\xe8op\x00\x00\x00\x00G" +
+	"\xec\x18\xe0\x00\x00\x00\x00H\xbb\x06P\x00\x00\x00\x00I\xcb\xfa\xe0\x00\x00\x00\x00J\xa0<`\x00\x00\x00\x00K\xab\xdc\xe0\x00\x00\x00\x00La\xbd\xd0\x00\x00\x00\x00M\x94\xf9\x9c\x00\x00\x00\x00N5\xc2P\x00" +
+	"\x00\x00\x00N\\\v\xe0\x00\x00\x00\x00N\x84\xdcP\x00\x00\x00\x00Ot\xdb`\x00\x00\x00\x00P[\x91\xe0\x00\x00\x00\x00QT\xbd`\x00\x00\x00\x00RD\xa0P\x00\x00\x00\x00S4\x9f`\x00\x00\x00\x00T" +
+	"IlP\x00\x00\x00\x00U\x15\xd2\xe0\x00\x00\x00\x00V)\\`\x00\x00\x00\x00V\xf5\xc2\xf0\x00\x00\x00\x00X\x13\xca`\x00\x00\x00\x00Xդ\xf0\x00\x00\x00\x00Y\xf3\xac`\x00\x00\x00\x00Z\xb5\x86\xf0\x00" +
+	"\x00\x00\x00[ӎ`\x00\x00\x00\x00\\\x9dC\xe0\x00\x00\x00\x00]\xb3bP\x00\x00\x00\x00^~w`\x00\x00\x00\x00_\x93R`\x00\x00\x00\x00`^Y`\x00\x00\x00\x00a{\x1d`\x00\x00\x00\x00b" +
+	"?\x8c\xe0\x00\x00\x00\x00c\\^\xf0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" +
+	"\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00 \xe7\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\t\x00\x00*0\x01\r\x00\x00\x1c \x00\x11LMT\x00EEST\x00EET\x00IDT\x00" +
+	"IST\x00\nEET-2EEST,M3.4.4/50,M10.4.4/50\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000I\xc7\xde\xec\x00\x00\x00\xec\x00" +
+	"\x00\x00\x10\x00\x00\x00Asia/Ho_Chi_MinhTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff" +
+	"\xff\x88\x8cC\x8a\xff\xff\xff\xff\x91\xa3+\n\xff\xff\xff\xff\xcd5\xe6\x80\xff\xff\xff\xff\xd1Y\xcep\xff\xff\xff\xff\xd2;>\xf0\xff\xff\xff\xff\xd52\xbb\x10\xff\xff\xff\xff\xe4\xb6\xe4\x80\xff\xff\xff\xff\xed/\x98" +
+	"\x00\x00\x00\x00\x00\n=\xc7\x00\x01\x02\x03\x04\x02\x03\x02\x03\x02\x00\x00c\xf6\x00\x00\x00\x00c\xf6\x00\x04\x00\x00bp\x00\t\x00\x00p\x80\x00\r\x00\x00~\x90\x00\x11LMT\x00PLMT\x00+07" +
+	"\x00+08\x00+09\x00\n<+07>-7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\t\xfa-\a\x03\x00\x00\a\x03\x00\x00\x0e\x00\x00\x00Asia/Hong_Ko" +
+	"ngTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\x00\x00\x00\x05\x00\x00\x00\x16\xff\xff\xff\xff\x85ic\x90\xff\xff\xff\xff\xcaM10\xff\xff\xff\xff\xcaۓ" +
+	"0\xff\xff\xff\xff\xcbKqx\xff\xff\xff\xffҠސ\xff\xff\xff\xff\xd3k׀\xff\xff\xff\xffԓX\xb8\xff\xff\xff\xff\xd5B\xb08\xff\xff\xff\xff\xd6s:\xb8\xff\xff\xff\xff\xd7>A\xb8\xff\xff\xff" +
+	"\xff\xd8.2\xb8\xff\xff\xff\xff\xd8\xf99\xb8\xff\xff\xff\xff\xda\x0e\x14\xb8\xff\xff\xff\xff\xda\xd9\x1b\xb8\xff\xff\xff\xff\xdb\xed\xf6\xb8\xff\xff\xff\xffܸ\xfd\xb8\xff\xff\xff\xff\xdd\xcdظ\xff\xff\xff\xffޢ\x1a" +
+	"8\xff\xff\xff\xff߶\xf58\xff\xff\xff\xff\xe0\x81\xfc8\xff\xff\xff\xff\xe1\x96\xc9(\xff\xff\xff\xff\xe2Oi8\xff\xff\xff\xff\xe3v\xab(\xff\xff\xff\xff\xe4/K8\xff\xff\xff\xff\xe5_Ǩ\xff\xff\xff" +
+	"\xff\xe6\x0f-8\xff\xff\xff\xff\xe7?\xa9\xa8\xff\xff\xff\xff\xe7\xf8I\xb8\xff\xff\xff\xff\xe9\x1f\x8b\xa8\xff\xff\xff\xff\xe9\xd8+\xb8\xff\xff\xff\xff\xea\xffm\xa8\xff\xff\xff\xff\xeb\xb8\r\xb8\xff\xff\xff\xff\xec\xdfO" +
+	"\xa8\xff\xff\xff\xff\xed\x97\xef\xb8\xff\xff\xff\xff\xee\xc8l(\xff\xff\xff\xff\xefwѸ\xff\xff\xff\xff\xf0\xa8N(\xff\xff\xff\xff\xf1W\xb3\xb8\xff\xff\xff\xff\xf2\x880(\xff\xff\xff\xff\xf3@\xd08\xff\xff\xff" +
+	"\xff\xf4h\x12(\xff\xff\xff\xff\xf5 \xb28\xff\xff\xff\xff\xf6G\xf4(\xff\xff\xff\xff\xf7%~8\xff\xff\xff\xff\xf8\x15a(\xff\xff\xff\xff\xf9\x05`8\xff\xff\xff\xff\xf9\xf5C(\xff\xff\xff\xff\xfa\xe5B" +
+	"8\xff\xff\xff\xff\xfb\xde_\xa8\xff\xff\xff\xff\xfc\xce^\xb8\xff\xff\xff\xff\xfd\xbeA\xa8\xff\xff\xff\xff\xfe\xae@\xb8\xff\xff\xff\xff\xff\x9e#\xa8\x00\x00\x00\x00\x00\x8e\"\xb8\x00\x00\x00\x00\x01~\x05\xa8\x00\x00\x00" +
+	"\x00\x02n\x04\xb8\x00\x00\x00\x00\x03]\xe7\xa8\x00\x00\x00\x00\x04M\xe6\xb8\x00\x00\x00\x00\x05G\x04(\x00\x00\x00\x00\x067\x038\x00\x00\x00\x00\a&\xe6(\x00\x00\x00\x00\a\x83=8\x00\x00\x00\x00\t\x06\xc8" +
+	"(\x00\x00\x00\x00\t\xf6\xc78\x00\x00\x00\x00\n\xe6\xaa(\x00\x00\x00\x00\v֩8\x00\x00\x00\x00\fƌ(\x00\x00\x00\x00\x11\x9b98\x00\x00\x00\x00\x12ol\xa8\x01\x02\x03\x04\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00" +
+	"k\n\x00\x00\x00\x00p\x80\x00\x04\x00\x00~\x90\x01\b\x00\x00w\x88\x01\r\x00\x00~\x90\x00\x12LMT\x00HKT\x00HKST\x00HKWT\x00JST\x00\nHKT-8\nPK\x03" +
+	"\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xba\xa3b\xc1R\x02\x00\x00R\x02\x00\x00\t\x00\x00\x00Asia/HovdTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x002\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\x86\xd3\xfc\x94\x00\x00\x00\x00\x0f\v\xea\xa0\x00\x00\x00\x00\x18\xe9\u0590\x00\x00\x00\x00\x19\xdb\v\x00\x00\x00\x00\x00\x1a\xcc[\x90\x00\x00\x00\x00\x1b\xbc>\x80\x00" +
+	"\x00\x00\x00\x1c\xac=\x90\x00\x00\x00\x00\x1d\x9c \x80\x00\x00\x00\x00\x1e\x8c\x1f\x90\x00\x00\x00\x00\x1f|\x02\x80\x00\x00\x00\x00 l\x01\x90\x00\x00\x00\x00![\xe4\x80\x00\x00\x00\x00\"K\xe3\x90\x00\x00\x00\x00#" +
+	";ƀ\x00\x00\x00\x00$+Ő\x00\x00\x00\x00%\x1b\xa8\x80\x00\x00\x00\x00&\v\xa7\x90\x00\x00\x00\x00'\x04\xc5\x00\x00\x00\x00\x00'\xf4\xc4\x10\x00\x00\x00\x00(\xe4\xa7\x00\x00\x00\x00\x00)Ԧ\x10\x00" +
+	"\x00\x00\x00*ĉ\x00\x00\x00\x00\x00+\xb4\x88\x10\x00\x00\x00\x00,\xa4k\x00\x00\x00\x00\x00-\x94j\x10\x00\x00\x00\x00.\x84M\x00\x00\x00\x00\x00/tL\x10\x00\x00\x00\x000d/\x00\x00\x00\x00\x001" +
+	"]h\x90\x00\x00\x00\x002MK\x80\x00\x00\x00\x003=J\x90\x00\x00\x00\x004--\x80\x00\x00\x00\x005\x1d,\x90\x00\x00\x00\x006\r\x0f\x80\x00\x00\x00\x00:\xe9\xc1\xb0\x00\x00\x00\x00;\xb4\xba\xa0\x00" +
+	"\x00\x00\x00<\xa4\xb9\xb0\x00\x00\x00\x00=\x94\x9c\xa0\x00\x00\x00\x00>\x84\x9b\xb0\x00\x00\x00\x00?t~\xa0\x00\x00\x00\x00@d}\xb0\x00\x00\x00\x00AT`\xa0\x00\x00\x00\x00BD_\xb0\x00\x00\x00\x00C" +
+	"4B\xa0\x00\x00\x00\x00D$A\xb0\x00\x00\x00\x00E\x1d_ \x00\x00\x00\x00U\x15\xa8\xb0\x00\x00\x00\x00V\x05o\x80\x00\x00\x00\x00V\xf5\x8a\xb0\x00\x00\x00\x00W\xe5Q\x80\x01\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00U\xec\x00\x00\x00\x00T`\x00\x04\x00\x00p\x80\x01\b\x00" +
+	"\x00bp\x00\fLMT\x00+06\x00+08\x00+07\x00\n<+07>-7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf9l\x03\x12\xf8\x02\x00\x00\xf8\x02\x00\x00\f\x00\x00\x00" +
+	"Asia/IrkutskTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00" +
+	"\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x00\x00\x00\a\x00\x00\x00\x14\xff\xff\xff\xffV\xb6\x82?\xff\xff\xff\xff\xa2" +
+	"\x12\x0f\xbf\xff\xff\xff\xff\xb5\xa3\xd3\x10\x00\x00\x00\x00\x15'a\x80\x00\x00\x00\x00\x16\x18\x95\xf0\x00\x00\x00\x00\x17\b\x95\x00\x00\x00\x00\x00\x17\xf9\xc9p\x00\x00\x00\x00\x18\xe9Ȁ\x00\x00\x00\x00\x19\xda\xfc\xf0\x00" +
+	"\x00\x00\x00\x1a\xccM\x80\x00\x00\x00\x00\x1b\xbcZ\xa0\x00\x00\x00\x00\x1c\xacK\xa0\x00\x00\x00\x00\x1d\x9c<\xa0\x00\x00\x00\x00\x1e\x8c-\xa0\x00\x00\x00\x00\x1f|\x1e\xa0\x00\x00\x00\x00 l\x0f\xa0\x00\x00\x00\x00!" +
+	"\\\x00\xa0\x00\x00\x00\x00\"K\xf1\xa0\x00\x00\x00\x00#;\xe2\xa0\x00\x00\x00\x00$+Ӡ\x00\x00\x00\x00%\x1bĠ\x00\x00\x00\x00&\v\xb5\xa0\x00\x00\x00\x00'\x04\xe1 \x00\x00\x00\x00'\xf4\xd2 \x00" +
+	"\x00\x00\x00(\xe4\xd10\x00\x00\x00\x00)xy0\x00\x00\x00\x00)Դ \x00\x00\x00\x00*ĥ \x00\x00\x00\x00+\xb4\x96 \x00\x00\x00\x00,\xa4\x87 \x00\x00\x00\x00-\x94x \x00\x00\x00\x00." +
+	"\x84i \x00\x00\x00\x00/tZ \x00\x00\x00\x000dK \x00\x00\x00\x001]v\xa0\x00\x00\x00\x002rQ\xa0\x00\x00\x00\x003=X\xa0\x00\x00\x00\x004R3\xa0\x00\x00\x00\x005\x1d:\xa0\x00" +
+	"\x00\x00\x0062\x15\xa0\x00\x00\x00\x006\xfd\x1c\xa0\x00\x00\x00\x008\x1b2 \x00\x00\x00\x008\xdc\xfe\xa0\x00\x00\x00\x009\xfb\x14 \x00\x00\x00\x00:\xbc\xe0\xa0\x00\x00\x00\x00;\xda\xf6 \x00\x00\x00\x00<" +
+	"\xa5\xfd \x00\x00\x00\x00=\xba\xd8 \x00\x00\x00\x00>\x85\xdf \x00\x00\x00\x00?\x9a\xba \x00\x00\x00\x00@e\xc1 \x00\x00\x00\x00A\x83֠\x00\x00\x00\x00BE\xa3 \x00\x00\x00\x00Cc\xb8\xa0\x00" +
+	"\x00\x00\x00D%\x85 \x00\x00\x00\x00EC\x9a\xa0\x00\x00\x00\x00F\x05g \x00\x00\x00\x00G#|\xa0\x00\x00\x00\x00G\ue0e0\x00\x00\x00\x00I\x03^\xa0\x00\x00\x00\x00I\xcee\xa0\x00\x00\x00\x00J" +
+	"\xe3@\xa0\x00\x00\x00\x00K\xaeG\xa0\x00\x00\x00\x00L\xcc] \x00\x00\x00\x00M\x8e)\xa0\x00\x00\x00\x00TK\xd7\x10\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x05\x02" +
+	"\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x06\x04\x00\x00a\xc1\x00\x00\x00\x00a\xc1\x00\x04\x00\x00bp\x00\b\x00" +
+	"\x00~\x90\x01\f\x00\x00p\x80\x00\x10\x00\x00p\x80\x01\x10\x00\x00~\x90\x00\fLMT\x00IMT\x00+07\x00+09\x00+08\x00\n<+08>-8\nPK\x03\x04\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\aW\x10Ѱ\x04\x00\x00\xb0\x04\x00\x00\r\x00\x00\x00Asia/IstanbulTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00s\x00\x00\x00\x06\x00\x00\x00\x19\xff\xff\xff\xffV\xb6\xc8\xd8\xff\xff\xff\xff\x90\x8b\xf5\x98\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9bվ\xd0\xff\xff\xff\xff\xa2ec\xe0\xff\xff\xff\xff\xa3{\x82P\xff\xff" +
+	"\xff\xff\xa4N\x80`\xff\xff\xff\xff\xa5?\xb4\xd0\xff\xff\xff\xff\xa6%'\xe0\xff\xff\xff\xff\xa7'\x7f\xd0\xff\xff\xff\xff\xaa((`\xff\xff\xff\xff\xaa\xe1\xfd\xd0\xff\xff\xff\xff\xab\xf9\x89\xe0\xff\xff\xff\xff\xac\xc3" +
+	"1P\xff\xff\xff\xffȁ?\xe0\xff\xff\xff\xff\xc9\x01\x13P\xff\xff\xff\xff\xc9J\xf5`\xff\xff\xff\xff\xca\u0380P\xff\xff\xff\xff\xcbˮ`\xff\xff\xff\xff\xd2k\tP\xff\xff\xff\xffӢ9`\xff\xff" +
+	"\xff\xff\xd4C\x02P\xff\xff\xff\xff\xd5L\r\xe0\xff\xff\xff\xff\xd6){\xd0\xff\xff\xff\xff\xd7+\xef\xe0\xff\xff\xff\xff\xd8\t]\xd0\xff\xff\xff\xff\xd9\x02\x97`\xff\xff\xff\xff\xd9\xe9?\xd0\xff\xff\xff\xff\xda\xeb" +
+	"\xb3\xe0\xff\xff\xff\xff\xdb\xd2\\P\xff\xff\xff\xff\xdc\xd4\xd0`\xff\xff\xff\xffݲ>P\xff\xff\xff\xff\xf1\xf4\xb9`\xff\xff\xff\xff\xf4b\xefP\xff\xff\xff\xff\xf5h\x06`\xff\xff\xff\xff\xf6\x1f8\xd0\x00\x00" +
+	"\x00\x00\x06n\x93p\x00\x00\x00\x00\a9\x9ap\x00\x00\x00\x00\a\xfbu\x00\x00\x00\x00\x00\t\x19|p\x00\x00\x00\x00\t\xd0\xcb\x00\x00\x00\x00\x00\n\xf9^p\x00\x00\x00\x00\v\xb1\xfe\x80\x00\x00\x00\x00\f\xd9" +
+	"@p\x00\x00\x00\x00\r\xa4U\x80\x00\x00\x00\x00\x0e\xa6\xadp\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00\x0f\xf8\x11P\x00\x00\x00\x00\x19\x89\xb0p\x00\x00\x00\x00\x19ܰ\xe0\x00\x00\x00\x00\x1b\xe6\xd0\xf0\x00\x00" +
+	"\x00\x00\x1c\xc6\xef\xf0\x00\x00\x00\x00\x1d\x9b1p\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<" +
+	"(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00(\xe5\tp\x00\x00\x00\x00)\xd4\xfap\x00\x00" +
+	"\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x8b\x83\xf0\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]" +
+	"\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00" +
+	"\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb<p\x00\x00\x00\x00<\xa6Cp\x00\x00\x00\x00=\xbb\x1ep\x00\x00\x00\x00>\x86%p\x00\x00\x00\x00?\x9b" +
+	"\x00p\x00\x00\x00\x00@f\ap\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05ɐ\x00\x00" +
+	"\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8f" +
+	"ݐ\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S8\xbe\x10\x00\x00\x00\x00TLG\x90\x00\x00" +
+	"\x00\x00U\x17N\x90\x00\x00\x00\x00V>\x9e\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00W\xcf.P\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x00\x00\x1b(\x00\x00\x00\x00\x1bh\x00\x04\x00\x00*0\x01\b\x00\x00\x1c \x00\r\x00\x00*0\x00\x11\x00\x008@\x01" +
+	"\x15LMT\x00IMT\x00EEST\x00EET\x00+03\x00+04\x00\n<+03>-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b\xadű\xf8\x00\x00\x00\xf8\x00\x00" +
+	"\x00\f\x00\x00\x00Asia/JakartaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" +
+	"\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\a\x00\x00\x00 \xff\xff\xff\xff?fI`" +
+	"\xff\xff\xff\xff\xa9x\x85\xe0\xff\xff\xff\xff\xba\x16\xde`\xff\xff\xff\xff˿\x83\x88\xff\xff\xff\xff\xd2V\xeep\xff\xff\xff\xff\xd7<\xc6\b\xff\xff\xff\xff\xda\xff&\x00\xff\xff\xff\xff\xf4\xb5\xbe\x88\x01\x02\x03\x04" +
+	"\x03\x05\x03\x06\x00\x00d \x00\x00\x00\x00d \x00\x04\x00\x00g \x00\b\x00\x00ix\x00\x0e\x00\x00~\x90\x00\x14\x00\x00p\x80\x00\x18\x00\x00bp\x00\x1cLMT\x00BMT\x00+0720\x00" +
+	"+0730\x00+09\x00+08\x00WIB\x00\nWIB-7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00.>[K\xab\x00\x00\x00\xab\x00\x00\x00\r\x00\x00\x00Asia/" +
+	"JayapuraTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00T" +
+	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\xba\x16\xc1\x98\xff\xff\xff\xff\xd0X\xb9\xf0\xff" +
+	"\xff\xff\xff\xf4\xb5\xa2h\x01\x02\x03\x00\x00\x83\xe8\x00\x00\x00\x00~\x90\x00\x04\x00\x00\x85\x98\x00\b\x00\x00~\x90\x00\x0eLMT\x00+09\x00+0930\x00WIT\x00\nWIT-9\nP" +
+	"K\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17✳2\x04\x00\x002\x04\x00\x00\x0e\x00\x00\x00Asia/JerusalemTZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xffV\xb6\xc2\xfa\xff\xff\xff\xff\x9e0E\x88\xff\xff\xff\xff\xc8Y\xcf\x00\xff\xff\xff\xff\xc8\xfa\xa6\x00\xff\xff\xff\xff\xc98\x9c\x80\xff\xff" +
+	"\xff\xff\xcc\xe5\xeb\x80\xff\xff\xff\xffͬ\xfe\x00\xff\xff\xff\xff\xce\xc7\x1f\x00\xff\xff\xff\xffϏ\x83\x00\xff\xff\xff\xffЩ\xa4\x00\xff\xff\xff\xffф}\x00\xff\xff\xff\xffҊ׀\xff\xff\xff\xff\xd3e" +
+	"\xb0\x80\xff\xff\xff\xff\xd4l\v\x00\xff\xff\xff\xff\xd7Z0\x80\xff\xff\xff\xff\xd7\xdfX\x00\xff\xff\xff\xff\xd8/À\xff\xff\xff\xff\xd9\x1ec\x00\xff\xff\xff\xff\xda\x10\xf7\x00\xff\xff\xff\xff\xda\xeb\xd0\x00\xff\xff" +
+	"\xff\xff۴4\x00\xff\xff\xff\xffܹ=\x00\xff\xff\xff\xff\xdd\xe0\x8d\x00\xff\xff\xff\xff\u07b4\u0380\xff\xff\xff\xffߤ\xbf\x80\xff\xff\xff\xff\xe0\x8bv\x00\xff\xff\xff\xff\xe1V}\x00\xff\xff\xff\xff\xe2\xbe" +
+	"f\x80\xff\xff\xff\xff\xe36_\x00\xff\xff\xff\xff\xe4\x9eH\x80\xff\xff\xff\xff\xe5\x16A\x00\xff\xff\xff\xff\xe6t\xf0\x00\xff\xff\xff\xff\xe7\x11Ҁ\xff\xff\xff\xff\xe8&\xad\x80\xff\xff\xff\xff\xe8\xe8z\x00\x00\x00" +
+	"\x00\x00\b|\x8b\xe0\x00\x00\x00\x00\b\xfd\xb0\xd0\x00\x00\x00\x00\t\xf6\xea`\x00\x00\x00\x00\n\xa63\xd0\x00\x00\x00\x00\x13\xe9\xfc`\x00\x00\x00\x00\x14![`\x00\x00\x00\x00\x1a\xfa\xc6`\x00\x00\x00\x00\x1b\x8e" +
+	"n`\x00\x00\x00\x00\x1c\xbe\xf8\xe0\x00\x00\x00\x00\x1dw|\xd0\x00\x00\x00\x00\x1e\xcc\xff`\x00\x00\x00\x00\x1f`\x99P\x00\x00\x00\x00 \x82\xb1`\x00\x00\x00\x00!I\xb5\xd0\x00\x00\x00\x00\"^\x9e\xe0\x00\x00" +
+	"\x00\x00# ]P\x00\x00\x00\x00$Z0`\x00\x00\x00\x00%\x00?P\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00&\xd6\xe6\xd0\x00\x00\x00\x00'\xeb\xcf\xe0\x00\x00\x00\x00(\xc0\x03P\x00\x00\x00\x00)\xd4" +
+	"\xec`\x00\x00\x00\x00*\xa9\x1f\xd0\x00\x00\x00\x00+\xbbe\xe0\x00\x00\x00\x00,\x89\x01\xd0\x00\x00\x00\x00-\x9bG\xe0\x00\x00\x00\x00._\xa9P\x00\x00\x00\x00/{)\xe0\x00\x00\x00\x000H\xc5\xd0\x00\x00" +
+	"\x00\x001H\x96\xe0\x00\x00\x00\x002<nP\x00\x00\x00\x0031\xb3`\x00\x00\x00\x004\x1a\xfe\xd0\x00\x00\x00\x005\x11\x95`\x00\x00\x00\x005\xf1\xa6P\x00\x00\x00\x007\x04\b\x80\x00\x00\x00\x007\xcf" +
+	"\x01p\x00\x00\x00\x008\xf6_\x80\x00\x00\x00\x009\xdc\xf9\xe0\x00\x00\x00\x00:\xd0\xedp\x00\x00\x00\x00;\xae[`\x00\x00\x00\x00<\xa3\xa0p\x00\x00\x00\x00=\xa0\xb2`\x00\x00\x00\x00>\x83\x82p\x00\x00" +
+	"\x00\x00?|\x9f\xe0\x00\x00\x00\x00@s6p\x00\x00\x00\x00AP\xa4`\x00\x00\x00\x00BL\x8f\x00\x00\x00\x00\x00CHOp\x00\x00\x00\x00D,q\x00\x00\x00\x00\x00E\x1e\xf6\xf0\x00\x00\x00\x00F\f" +
+	"S\x00\x00\x00\x00\x00F\xecc\xf0\x00\x00\x00\x00G\xec5\x00\x00\x00\x00\x00H\xe7\xf5p\x00\x00\x00\x00I\xcc\x17\x00\x00\x00\x00\x00J\xbe\x9c\xf0\x00\x00\x00\x00K\xab\xf9\x00\x00\x00\x00\x00L\x8c\t\xf0\x00\x00" +
+	"\x00\x00M\x95\x15\x80\x00\x00\x00\x00N\x87\x9bp\x00\x00\x00\x00Ot\xf7\x80\x00\x00\x00\x00P^B\xf0\x00\x00\x00\x00QTـ\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00!\x06\x00\x00\x00\x00 \xf8\x00\x04\x00\x00*0\x01\b\x00\x00\x1c \x00\f\x00\x008@\x01\x10LMT\x00JMT\x00IDT\x00" +
+	"IST\x00IDDT\x00\nIST-2IDT,M3.4.4/26,M10.5.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\xe2\\\xff\x9f\x00\x00\x00\x9f" +
+	"\x00\x00\x00\n\x00\x00\x00Asia/KabulTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" +
+	"\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffi\x86\x9a\xa0" +
+	"\xff\xff\xff\xff\xd0\xf9\xd7@\x01\x02\x00\x00@\xe0\x00\x00\x00\x008@\x00\x04\x00\x00?H\x00\bLMT\x00+04\x00+0430\x00\n<+0430>-4:30\nPK\x03\x04" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\x9cf>\xd7\x02\x00\x00\xd7\x02\x00\x00\x0e\x00\x00\x00Asia/KamchatkaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xa7R\x96\xc4\xff\xff\xff\xff\xb5\xa3\x9a\xd0\x00\x00\x00\x00\x15')@\x00\x00\x00\x00\x16\x18]\xb0\x00\x00\x00\x00\x17\b\\\xc0\x00\x00\x00\x00\x17" +
+	"\xf9\x910\x00\x00\x00\x00\x18\xe9\x90@\x00\x00\x00\x00\x19\xdaİ\x00\x00\x00\x00\x1a\xcc\x15@\x00\x00\x00\x00\x1b\xbc\"`\x00\x00\x00\x00\x1c\xac\x13`\x00\x00\x00\x00\x1d\x9c\x04`\x00\x00\x00\x00\x1e\x8b\xf5`\x00" +
+	"\x00\x00\x00\x1f{\xe6`\x00\x00\x00\x00 k\xd7`\x00\x00\x00\x00![\xc8`\x00\x00\x00\x00\"K\xb9`\x00\x00\x00\x00#;\xaa`\x00\x00\x00\x00$+\x9b`\x00\x00\x00\x00%\x1b\x8c`\x00\x00\x00\x00&" +
+	"\v}`\x00\x00\x00\x00'\x04\xa8\xe0\x00\x00\x00\x00'\xf4\x99\xe0\x00\x00\x00\x00(\xe4\x98\xf0\x00\x00\x00\x00)x@\xf0\x00\x00\x00\x00)\xd4{\xe0\x00\x00\x00\x00*\xc4l\xe0\x00\x00\x00\x00+\xb4]\xe0\x00" +
+	"\x00\x00\x00,\xa4N\xe0\x00\x00\x00\x00-\x94?\xe0\x00\x00\x00\x00.\x840\xe0\x00\x00\x00\x00/t!\xe0\x00\x00\x00\x000d\x12\xe0\x00\x00\x00\x001]>`\x00\x00\x00\x002r\x19`\x00\x00\x00\x003" +
+	"= `\x00\x00\x00\x004Q\xfb`\x00\x00\x00\x005\x1d\x02`\x00\x00\x00\x0061\xdd`\x00\x00\x00\x006\xfc\xe4`\x00\x00\x00\x008\x1a\xf9\xe0\x00\x00\x00\x008\xdc\xc6`\x00\x00\x00\x009\xfa\xdb\xe0\x00" +
+	"\x00\x00\x00:\xbc\xa8`\x00\x00\x00\x00;ڽ\xe0\x00\x00\x00\x00<\xa5\xc4\xe0\x00\x00\x00\x00=\xba\x9f\xe0\x00\x00\x00\x00>\x85\xa6\xe0\x00\x00\x00\x00?\x9a\x81\xe0\x00\x00\x00\x00@e\x88\xe0\x00\x00\x00\x00A" +
+	"\x83\x9e`\x00\x00\x00\x00BEj\xe0\x00\x00\x00\x00Cc\x80`\x00\x00\x00\x00D%L\xe0\x00\x00\x00\x00ECb`\x00\x00\x00\x00F\x05.\xe0\x00\x00\x00\x00G#D`\x00\x00\x00\x00G\xeeK`\x00" +
+	"\x00\x00\x00I\x03&`\x00\x00\x00\x00I\xce-`\x00\x00\x00\x00J\xe3\b`\x00\x00\x00\x00K\xae\x0f`\x00\x00\x00\x00L\xcc2\xf0\x00\x00\x00\x00M\x8d\xffp\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x00\x00\x94\xbc\x00\x00\x00\x00\x9a" +
+	"\xb0\x00\x04\x00\x00\xb6\xd0\x01\b\x00\x00\xa8\xc0\x00\f\x00\x00\xa8\xc0\x01\fLMT\x00+11\x00+13\x00+12\x00\n<+12>-12\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x009Y\xb7\xf1\n\x01\x00\x00\n\x01\x00\x00\f\x00\x00\x00Asia/KarachiTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x06" +
+	"\x00\x00\x00\x1d\xff\xff\xff\xff\x89~\xfc\xa4\xff\xff\xff\xff̕2\xa8\xff\xff\xff\xff\xd2t\x12\x98\xff\xff\xff\xffݨ\xe0\xa8\x00\x00\x00\x00\x02O\xab0\x00\x00\x00\x00<\xafE\xb0\x00\x00\x00\x00=\x9f(\xa0" +
+	"\x00\x00\x00\x00HA\xa00\x00\x00\x00\x00I\vG\xa0\x00\x00\x00\x00I\xe4\xdd0\x00\x00\x00\x00J\xec{ \x01\x02\x01\x03\x05\x04\x05\x04\x05\x04\x05\x00\x00>\xdc\x00\x00\x00\x00MX\x00\x04\x00\x00[h\x01" +
+	"\n\x00\x00FP\x00\x10\x00\x00T`\x01\x14\x00\x00FP\x00\x19LMT\x00+0530\x00+0630\x00+05\x00PKST\x00PKT\x00\nPKT-5\nPK\x03\x04\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x1d\xc6\x1b\x85\x00\x00\x00\x85\x00\x00\x00\f\x00\x00\x00Asia/KashgarTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xb0\xfe\xbad\x01\x00\x00R\x1c\x00\x00\x00\x00T`\x00\x04LMT\x00+06\x00\n<+06>-6\nPK\x03\x04\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x8bSnT\xa1\x00\x00\x00\xa1\x00\x00\x00\x0e\x00\x00\x00Asia/KathmanduTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x02\x00\x00\x00\x03\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xf2}\x84\x00\x00\x00\x00\x1e\x180\xa8\x01\x02\x00\x00O\xfc\x00\x00\x00\x00MX\x00\x04\x00\x00P\xdc\x00\nLMT\x00+0530\x00+0545" +
+	"\x00\n<+0545>-5:45\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8bSnT\xa1\x00\x00\x00\xa1\x00\x00\x00\r\x00\x00\x00Asia/KatmanduTZ" +
+	"if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xf2}\x84\x00\x00\x00\x00\x1e\x180\xa8\x01\x02\x00\x00O\xfc\x00\x00\x00\x00M" +
+	"X\x00\x04\x00\x00P\xdc\x00\nLMT\x00+0530\x00+0545\x00\n<+0545>-5:45\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x83g\x95M\a\x03\x00" +
+	"\x00\a\x03\x00\x00\r\x00\x00\x00Asia/KhandygaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00C\x00\x00\x00\b\x00\x00\x00\x14\xff\xff\xff" +
+	"\xff\xa1\xdb\xe4\xeb\xff\xff\xff\xff\xb5\xa3\xc5\x00\x00\x00\x00\x00\x15'Sp\x00\x00\x00\x00\x16\x18\x87\xe0\x00\x00\x00\x00\x17\b\x86\xf0\x00\x00\x00\x00\x17\xf9\xbb`\x00\x00\x00\x00\x18\xe9\xbap\x00\x00\x00\x00\x19\xda\xee" +
+	"\xe0\x00\x00\x00\x00\x1a\xcc?p\x00\x00\x00\x00\x1b\xbcL\x90\x00\x00\x00\x00\x1c\xac=\x90\x00\x00\x00\x00\x1d\x9c.\x90\x00\x00\x00\x00\x1e\x8c\x1f\x90\x00\x00\x00\x00\x1f|\x10\x90\x00\x00\x00\x00 l\x01\x90\x00\x00\x00" +
+	"\x00![\xf2\x90\x00\x00\x00\x00\"K\xe3\x90\x00\x00\x00\x00#;Ԑ\x00\x00\x00\x00$+Ő\x00\x00\x00\x00%\x1b\xb6\x90\x00\x00\x00\x00&\v\xa7\x90\x00\x00\x00\x00'\x04\xd3\x10\x00\x00\x00\x00'\xf4\xc4" +
+	"\x10\x00\x00\x00\x00(\xe4\xc3 \x00\x00\x00\x00)xk \x00\x00\x00\x00)Ԧ\x10\x00\x00\x00\x00*ė\x10\x00\x00\x00\x00+\xb4\x88\x10\x00\x00\x00\x00,\xa4y\x10\x00\x00\x00\x00-\x94j\x10\x00\x00\x00" +
+	"\x00.\x84[\x10\x00\x00\x00\x00/tL\x10\x00\x00\x00\x000d=\x10\x00\x00\x00\x001]h\x90\x00\x00\x00\x002rC\x90\x00\x00\x00\x003=J\x90\x00\x00\x00\x004R%\x90\x00\x00\x00\x005\x1d," +
+	"\x90\x00\x00\x00\x0062\a\x90\x00\x00\x00\x006\xfd\x0e\x90\x00\x00\x00\x008\x1b$\x10\x00\x00\x00\x008\xdc\xf0\x90\x00\x00\x00\x009\xfb\x06\x10\x00\x00\x00\x00:\xbcҐ\x00\x00\x00\x00;\xda\xe8\x10\x00\x00\x00" +
+	"\x00<\xa5\xef\x10\x00\x00\x00\x00=\xba\xca\x10\x00\x00\x00\x00>\x85\xd1\x10\x00\x00\x00\x00?\x9a\xac\x10\x00\x00\x00\x00?\xf2\xe4p\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87" +
+	"\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D%i\x00\x00\x00\x00\x00EC~\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xeeg\x80\x00\x00\x00\x00I\x03B\x80\x00\x00\x00" +
+	"\x00I\xceI\x80\x00\x00\x00\x00J\xe3$\x80\x00\x00\x00\x00K\xae+\x80\x00\x00\x00\x00L\xccA\x00\x00\x00\x00\x00M\x8e\r\x80\x00\x00\x00\x00Nn\x02P\x00\x00\x00\x00TK\xc9\x00\x01\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\a\x06\x03" +
+	"\x00\x00\x7f\x15\x00\x00\x00\x00p\x80\x00\x04\x00\x00\x8c\xa0\x01\b\x00\x00~\x90\x00\f\x00\x00~\x90\x01\f\x00\x00\x9a\xb0\x01\x10\x00\x00\x8c\xa0\x00\b\x00\x00\x9a\xb0\x00\x10LMT\x00+08\x00+10\x00" +
+	"+09\x00+11\x00\n<+09>-9\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9a\x1a\xdc\xca\xdc\x00\x00\x00\xdc\x00\x00\x00\f\x00\x00\x00Asia/KolkataT" +
+	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x05\x00\x00\x00\x16\xff\xff\xff\xff&\xba\x18(\xff\xff\xff\xffC\xe7\xeb0\xff\xff\xff\xff\x87\x9d\xbc\xba\xff\xff" +
+	"\xff\xff\xcaی(\xff\xff\xff\xff\xcc\x05q\x18\xff\xff\xff\xff̕2\xa8\xff\xff\xff\xff\xd2t\x12\x98\x01\x02\x03\x04\x03\x04\x03\x00\x00R\xd8\x00\x00\x00\x00R\xd0\x00\x04\x00\x00KF\x00\b\x00\x00MX\x00" +
+	"\f\x00\x00[h\x01\x10LMT\x00HMT\x00MMT\x00IST\x00+0630\x00\nIST-5:30\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00L\xe0\x91y\xe5\x02\x00" +
+	"\x00\xe5\x02\x00\x00\x10\x00\x00\x00Asia/KrasnoyarskTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00A\x00\x00\x00\x06\x00\x00\x00\x10" +
+	"\xff\xff\xff\xff\xa1\xf9\r\xf2\xff\xff\xff\xff\xb5\xa3\xe1 \x00\x00\x00\x00\x15'o\x90\x00\x00\x00\x00\x16\x18\xa4\x00\x00\x00\x00\x00\x17\b\xa3\x10\x00\x00\x00\x00\x17\xf9׀\x00\x00\x00\x00\x18\xe9\u0590\x00\x00\x00\x00" +
+	"\x19\xdb\v\x00\x00\x00\x00\x00\x1a\xcc[\x90\x00\x00\x00\x00\x1b\xbch\xb0\x00\x00\x00\x00\x1c\xacY\xb0\x00\x00\x00\x00\x1d\x9cJ\xb0\x00\x00\x00\x00\x1e\x8c;\xb0\x00\x00\x00\x00\x1f|,\xb0\x00\x00\x00\x00 l\x1d\xb0" +
+	"\x00\x00\x00\x00!\\\x0e\xb0\x00\x00\x00\x00\"K\xff\xb0\x00\x00\x00\x00#;\xf0\xb0\x00\x00\x00\x00$+\xe1\xb0\x00\x00\x00\x00%\x1bҰ\x00\x00\x00\x00&\vð\x00\x00\x00\x00'\x04\xef0\x00\x00\x00\x00" +
+	"'\xf4\xe00\x00\x00\x00\x00(\xe4\xdf@\x00\x00\x00\x00)x\x87@\x00\x00\x00\x00)\xd4\xc20\x00\x00\x00\x00*ij0\x00\x00\x00\x00+\xb4\xa40\x00\x00\x00\x00,\xa4\x950\x00\x00\x00\x00-\x94\x860" +
+	"\x00\x00\x00\x00.\x84w0\x00\x00\x00\x00/th0\x00\x00\x00\x000dY0\x00\x00\x00\x001]\x84\xb0\x00\x00\x00\x002r_\xb0\x00\x00\x00\x003=f\xb0\x00\x00\x00\x004RA\xb0\x00\x00\x00\x00" +
+	"5\x1dH\xb0\x00\x00\x00\x0062#\xb0\x00\x00\x00\x006\xfd*\xb0\x00\x00\x00\x008\x1b@0\x00\x00\x00\x008\xdd\f\xb0\x00\x00\x00\x009\xfb\"0\x00\x00\x00\x00:\xbc\xee\xb0\x00\x00\x00\x00;\xdb\x040" +
+	"\x00\x00\x00\x00<\xa6\v0\x00\x00\x00\x00=\xba\xe60\x00\x00\x00\x00>\x85\xed0\x00\x00\x00\x00?\x9a\xc80\x00\x00\x00\x00@e\xcf0\x00\x00\x00\x00A\x83\xe4\xb0\x00\x00\x00\x00BE\xb10\x00\x00\x00\x00" +
+	"Ccư\x00\x00\x00\x00D%\x930\x00\x00\x00\x00EC\xa8\xb0\x00\x00\x00\x00F\x05u0\x00\x00\x00\x00G#\x8a\xb0\x00\x00\x00\x00G\ue470\x00\x00\x00\x00I\x03l\xb0\x00\x00\x00\x00I\xces\xb0" +
+	"\x00\x00\x00\x00J\xe3N\xb0\x00\x00\x00\x00K\xaeU\xb0\x00\x00\x00\x00L\xcck0\x00\x00\x00\x00M\x8e7\xb0\x00\x00\x00\x00TK\xe5 \x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x03\x00\x00W\x0e\x00\x00\x00\x00T`\x00\x04\x00\x00p" +
+	"\x80\x01\b\x00\x00bp\x00\f\x00\x00bp\x01\f\x00\x00p\x80\x00\bLMT\x00+06\x00+08\x00+07\x00\n<+07>-7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"F7k\x1c\x00\x01\x00\x00\x00\x01\x00\x00\x11\x00\x00\x00Asia/Kuala_LumpurTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b" +
+	"\x00\x00\x00\b\x00\x00\x00 \xff\xff\xff\xff~6S\xa3\xff\xff\xff\xff\x86\x83\x85\xa3\xff\xff\xff\xff\xbagN\x90\xff\xff\xff\xff\xc0\n\xe4`\xff\xff\xff\xffʳ\xe5`\xff\xff\xff\xffˑ_\b\xff\xff\xff\xff" +
+	"\xd2Hm\xf0\x00\x00\x00\x00\x16\x91\xee\x00\x01\x02\x03\x04\x05\x06\x05\a\x00\x00a]\x00\x00\x00\x00a]\x00\x04\x00\x00bp\x00\b\x00\x00g \x01\f\x00\x00g \x00\f\x00\x00ix\x00\x12\x00\x00~\x90" +
+	"\x00\x18\x00\x00p\x80\x00\x1cLMT\x00SMT\x00+07\x00+0720\x00+0730\x00+09\x00+08\x00\n<+08>-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\xa7f^]@\x01\x00\x00@\x01\x00\x00\f\x00\x00\x00Asia/KuchingTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12\x00\x00" +
+	"\x00\x05\x00\x00\x00\x18\xff\xff\xff\xff\xad\x8a\x06\x90\xff\xff\xff\xff\xbagG\x88\xff\xff\xff\xff\xbf{'\x80\xff\xff\xff\xff\xbf\xf3\x1bP\xff\xff\xff\xff\xc1]\xac\x80\xff\xff\xff\xff\xc1ՠP\xff\xff\xff\xff\xc3>" +
+	"\xe0\x00\xff\xff\xff\xffö\xd3\xd0\xff\xff\xff\xff\xc5 \x13\x80\xff\xff\xff\xffŘ\aP\xff\xff\xff\xff\xc7\x01G\x00\xff\xff\xff\xff\xc7y:\xd0\xff\xff\xff\xff\xc8\xe3\xcc\x00\xff\xff\xff\xff\xc9[\xbf\xd0\xff\xff" +
+	"\xff\xff\xca\xc4\xff\x80\xff\xff\xff\xff\xcb<\xf3P\xff\xff\xff\xffˑX\x00\xff\xff\xff\xff\xd2Hm\xf0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x03\x00\x00gp\x00\x00\x00\x00ix\x00\x04" +
+	"\x00\x00u0\x01\n\x00\x00p\x80\x00\x10\x00\x00~\x90\x00\x14LMT\x00+0730\x00+0820\x00+08\x00+09\x00\n<+08>-8\nPK\x03\x04\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\xcfׇ\xe1\x85\x00\x00\x00\x85\x00\x00\x00\v\x00\x00\x00Asia/KuwaitTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00" +
+	"\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xd5\x1b6\xb4\x01\x00\x00+\xcc\x00\x00\x00\x00*0\x00\x04LMT\x00+03\x00\n<+03>-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d" +
+	"?v\f\x17\x03\x00\x00\x17\x03\x00\x00\n\x00\x00\x00Asia/MacaoTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x05\x00\x00\x00\x14" +
+	"\xff\xff\xff\xff\x85i[\x8e\xff\xff\xff\xff\xcbGu\xf0\xff\xff\xff\xff\xcb\xf2\xca\xe0\xff\xff\xff\xff\xcc\xfb\xbaP\xff\xff\xff\xff\xcd\xd3\xfe`\xff\xff\xff\xffΝ\xa5\xd0\xff\xff\xff\xff\xd2azp\xff\xff\xff\xff" +
+	"\xd3x\xf8p\xff\xff\xff\xff\xd4B\xad\xf0\xff\xff\xff\xff\xd5K\xabp\xff\xff\xff\xff\xd6tL\xf0\xff\xff\xff\xff\xd7?S\xf0\xff\xff\xff\xff\xd8/D\xf0\xff\xff\xff\xff\xd8\xf8\xfap\xff\xff\xff\xff\xda\r\xd5p" +
+	"\xff\xff\xff\xff\xda\xd8\xdcp\xff\xff\xff\xff\xdb\xed\xb7p\xff\xff\xff\xffܸ\xbep\xff\xff\xff\xff\xdd\xce\xea\xf0\xff\xff\xff\xffޡ\xda\xf0\xff\xff\xff\xff߶\xb5\xf0\xff\xff\xff\xff\xe0\x81\xbc\xf0\xff\xff\xff\xff" +
+	"ᖗ\xf0\xff\xff\xff\xff\xe2O)\xf0\xff\xff\xff\xff\xe3vy\xf0\xff\xff\xff\xff\xe4/\v\xf0\xff\xff\xff\xff\xe5_\x96p\xff\xff\xff\xff\xe6\x0e\xed\xf0\xff\xff\xff\xff\xe7?\xa9\xa8\xff\xff\xff\xff\xe7\xf8I\xb8" +
+	"\xff\xff\xff\xff\xe9\x1f\x8b\xa8\xff\xff\xff\xff\xe9\xd8+\xb8\xff\xff\xff\xff\xea\xffm\xa8\xff\xff\xff\xff\xeb\xb8\r\xb8\xff\xff\xff\xff\xec\xdfO\xa8\xff\xff\xff\xff\xed\x97\xef\xb8\xff\xff\xff\xff\xee\xc8l(\xff\xff\xff\xff" +
+	"\xefwѸ\xff\xff\xff\xff\xf0\xa8N(\xff\xff\xff\xff\xf1W\xb3\xb8\xff\xff\xff\xff\xf2\x880(\xff\xff\xff\xff\xf3@\xd08\xff\xff\xff\xff\xf4h\x12(\xff\xff\xff\xff\xf5 \xb28\xff\xff\xff\xff\xf6G\xf4(" +
+	"\xff\xff\xff\xff\xf7%~8\xff\xff\xff\xff\xf8\x15S\x18\xff\xff\xff\xff\xf9\x05`8\xff\xff\xff\xff\xf9\xf55\x18\xff\xff\xff\xff\xfa\xe5B8\xff\xff\xff\xff\xfb\xde_\xa8\xff\xff\xff\xff\xfc\xce^\xb8\xff\xff\xff\xff" +
+	"\xfd\xbeA\xa8\xff\xff\xff\xff\xfe\xae@\xb8\xff\xff\xff\xff\xff\x9e#\xa8\x00\x00\x00\x00\x00\x8e\"\xb8\x00\x00\x00\x00\x01~\x05\xa8\x00\x00\x00\x00\x02n\x04\xb8\x00\x00\x00\x00\x03]\xe7\xa8\x00\x00\x00\x00\x04M\xe6\xb8" +
+	"\x00\x00\x00\x00\x05G\x04(\x00\x00\x00\x00\x067\x038\x00\x00\x00\x00\a&\xe6(\x00\x00\x00\x00\a\x83=8\x00\x00\x00\x00\t\x06\xc8(\x00\x00\x00\x00\t\xf6\xc78\x00\x00\x00\x00\n\xe6\xaa(\x00\x00\x00\x00" +
+	"\v֩8\x00\x00\x00\x00\fƌ(\x00\x00\x00\x00\x11\x9b98\x00\x00\x00\x00\x12ol\xa8\x01\x03\x02\x03\x02\x03\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04" +
+	"\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x00\x00jr\x00\x00\x00\x00p\x80\x00\x04\x00\x00\x8c\xa0\x01\b\x00\x00~" +
+	"\x90\x00\f\x00\x00~\x90\x01\x10LMT\x00CST\x00+10\x00+09\x00CDT\x00\nCST-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d?v\f\x17\x03\x00\x00\x17\x03" +
+	"\x00\x00\n\x00\x00\x00Asia/MacauTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01" +
+	"\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\x85i[\x8e\xff" +
+	"\xff\xff\xff\xcbGu\xf0\xff\xff\xff\xff\xcb\xf2\xca\xe0\xff\xff\xff\xff\xcc\xfb\xbaP\xff\xff\xff\xff\xcd\xd3\xfe`\xff\xff\xff\xffΝ\xa5\xd0\xff\xff\xff\xff\xd2azp\xff\xff\xff\xff\xd3x\xf8p\xff\xff\xff\xff\xd4" +
+	"B\xad\xf0\xff\xff\xff\xff\xd5K\xabp\xff\xff\xff\xff\xd6tL\xf0\xff\xff\xff\xff\xd7?S\xf0\xff\xff\xff\xff\xd8/D\xf0\xff\xff\xff\xff\xd8\xf8\xfap\xff\xff\xff\xff\xda\r\xd5p\xff\xff\xff\xff\xda\xd8\xdcp\xff" +
+	"\xff\xff\xff\xdb\xed\xb7p\xff\xff\xff\xffܸ\xbep\xff\xff\xff\xff\xdd\xce\xea\xf0\xff\xff\xff\xffޡ\xda\xf0\xff\xff\xff\xff߶\xb5\xf0\xff\xff\xff\xff\xe0\x81\xbc\xf0\xff\xff\xff\xffᖗ\xf0\xff\xff\xff\xff\xe2" +
+	"O)\xf0\xff\xff\xff\xff\xe3vy\xf0\xff\xff\xff\xff\xe4/\v\xf0\xff\xff\xff\xff\xe5_\x96p\xff\xff\xff\xff\xe6\x0e\xed\xf0\xff\xff\xff\xff\xe7?\xa9\xa8\xff\xff\xff\xff\xe7\xf8I\xb8\xff\xff\xff\xff\xe9\x1f\x8b\xa8\xff" +
+	"\xff\xff\xff\xe9\xd8+\xb8\xff\xff\xff\xff\xea\xffm\xa8\xff\xff\xff\xff\xeb\xb8\r\xb8\xff\xff\xff\xff\xec\xdfO\xa8\xff\xff\xff\xff\xed\x97\xef\xb8\xff\xff\xff\xff\xee\xc8l(\xff\xff\xff\xff\xefwѸ\xff\xff\xff\xff\xf0" +
+	"\xa8N(\xff\xff\xff\xff\xf1W\xb3\xb8\xff\xff\xff\xff\xf2\x880(\xff\xff\xff\xff\xf3@\xd08\xff\xff\xff\xff\xf4h\x12(\xff\xff\xff\xff\xf5 \xb28\xff\xff\xff\xff\xf6G\xf4(\xff\xff\xff\xff\xf7%~8\xff" +
+	"\xff\xff\xff\xf8\x15S\x18\xff\xff\xff\xff\xf9\x05`8\xff\xff\xff\xff\xf9\xf55\x18\xff\xff\xff\xff\xfa\xe5B8\xff\xff\xff\xff\xfb\xde_\xa8\xff\xff\xff\xff\xfc\xce^\xb8\xff\xff\xff\xff\xfd\xbeA\xa8\xff\xff\xff\xff\xfe" +
+	"\xae@\xb8\xff\xff\xff\xff\xff\x9e#\xa8\x00\x00\x00\x00\x00\x8e\"\xb8\x00\x00\x00\x00\x01~\x05\xa8\x00\x00\x00\x00\x02n\x04\xb8\x00\x00\x00\x00\x03]\xe7\xa8\x00\x00\x00\x00\x04M\xe6\xb8\x00\x00\x00\x00\x05G\x04(\x00" +
+	"\x00\x00\x00\x067\x038\x00\x00\x00\x00\a&\xe6(\x00\x00\x00\x00\a\x83=8\x00\x00\x00\x00\t\x06\xc8(\x00\x00\x00\x00\t\xf6\xc78\x00\x00\x00\x00\n\xe6\xaa(\x00\x00\x00\x00\v֩8\x00\x00\x00\x00\f" +
+	"ƌ(\x00\x00\x00\x00\x11\x9b98\x00\x00\x00\x00\x12ol\xa8\x01\x03\x02\x03\x02\x03\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01" +
+	"\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x00\x00jr\x00\x00\x00\x00p\x80\x00\x04\x00\x00\x8c\xa0\x01\b\x00\x00~\x90\x00\f\x00\x00~\x90\x01\x10" +
+	"LMT\x00CST\x00+10\x00+09\x00CDT\x00\nCST-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe4_P\x18\xef\x02\x00\x00\xef\x02\x00\x00\f\x00\x00\x00Asi" +
+	"a/MagadanTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" +
+	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x196\xa0\xff\xff\xff\xff\xb5\xa3\xa8\xe0" +
+	"\x00\x00\x00\x00\x15'7P\x00\x00\x00\x00\x16\x18k\xc0\x00\x00\x00\x00\x17\bj\xd0\x00\x00\x00\x00\x17\xf9\x9f@\x00\x00\x00\x00\x18\xe9\x9eP\x00\x00\x00\x00\x19\xda\xd2\xc0\x00\x00\x00\x00\x1a\xcc#P\x00\x00\x00\x00" +
+	"\x1b\xbc0p\x00\x00\x00\x00\x1c\xac!p\x00\x00\x00\x00\x1d\x9c\x12p\x00\x00\x00\x00\x1e\x8c\x03p\x00\x00\x00\x00\x1f{\xf4p\x00\x00\x00\x00 k\xe5p\x00\x00\x00\x00![\xd6p\x00\x00\x00\x00\"K\xc7p" +
+	"\x00\x00\x00\x00#;\xb8p\x00\x00\x00\x00$+\xa9p\x00\x00\x00\x00%\x1b\x9ap\x00\x00\x00\x00&\v\x8bp\x00\x00\x00\x00'\x04\xb6\xf0\x00\x00\x00\x00'\xf4\xa7\xf0\x00\x00\x00\x00(\xe4\xa7\x00\x00\x00\x00\x00" +
+	")xO\x00\x00\x00\x00\x00)ԉ\xf0\x00\x00\x00\x00*\xc4z\xf0\x00\x00\x00\x00+\xb4k\xf0\x00\x00\x00\x00,\xa4\\\xf0\x00\x00\x00\x00-\x94M\xf0\x00\x00\x00\x00.\x84>\xf0\x00\x00\x00\x00/t/\xf0" +
+	"\x00\x00\x00\x000d \xf0\x00\x00\x00\x001]Lp\x00\x00\x00\x002r'p\x00\x00\x00\x003=.p\x00\x00\x00\x004R\tp\x00\x00\x00\x005\x1d\x10p\x00\x00\x00\x0061\xebp\x00\x00\x00\x00" +
+	"6\xfc\xf2p\x00\x00\x00\x008\x1b\a\xf0\x00\x00\x00\x008\xdc\xd4p\x00\x00\x00\x009\xfa\xe9\xf0\x00\x00\x00\x00:\xbc\xb6p\x00\x00\x00\x00;\xda\xcb\xf0\x00\x00\x00\x00<\xa5\xd2\xf0\x00\x00\x00\x00=\xba\xad\xf0" +
+	"\x00\x00\x00\x00>\x85\xb4\xf0\x00\x00\x00\x00?\x9a\x8f\xf0\x00\x00\x00\x00@e\x96\xf0\x00\x00\x00\x00A\x83\xacp\x00\x00\x00\x00BEx\xf0\x00\x00\x00\x00Cc\x8ep\x00\x00\x00\x00D%Z\xf0\x00\x00\x00\x00" +
+	"ECpp\x00\x00\x00\x00F\x05<\xf0\x00\x00\x00\x00G#Rp\x00\x00\x00\x00G\xeeYp\x00\x00\x00\x00I\x034p\x00\x00\x00\x00I\xce;p\x00\x00\x00\x00J\xe3\x16p\x00\x00\x00\x00K\xae\x1dp" +
+	"\x00\x00\x00\x00L\xcc2\xf0\x00\x00\x00\x00M\x8d\xffp\x00\x00\x00\x00TK\xac\xe0\x00\x00\x00\x00W\x1b\x9c\x00\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x01\x03\x00\x00\x8d`\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00\xa8\xc0\x01\b\x00\x00\x9a\xb0" +
+	"\x00\f\x00\x00\x9a\xb0\x01\f\x00\x00\xa8\xc0\x00\bLMT\x00+10\x00+12\x00+11\x00\n<+11>-11\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`\xc9\xd4\\\xbe\x00" +
+	"\x00\x00\xbe\x00\x00\x00\r\x00\x00\x00Asia/MakassarTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff" +
+	"\xff\xff\xa1\xf2]\x90\xff\xff\xff\xff\xba\x16Ր\xff\xff\xff\xffˈ\x1d\x80\xff\xff\xff\xff\xd2V\xeep\x01\x02\x03\x04\x00\x00o\xf0\x00\x00\x00\x00o\xf0\x00\x04\x00\x00p\x80\x00\b\x00\x00~\x90\x00\f\x00\x00" +
+	"p\x80\x00\x10LMT\x00MMT\x00+08\x00+09\x00WITA\x00\nWITA-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ǯ\xdf\x1c\xee\x00\x00\x00\xee\x00\x00\x00\v" +
+	"\x00\x00\x00Asia/ManilaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00" +
+	"\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\x14\xe1\xdc\x10\xff\xff\xff" +
+	"\xff{\x1f?\x90\xff\xff\xff\xff\xc1\x9c\xf4\x80\xff\xff\xff\xff\xc2\x160p\xff\xff\xff\xff\xcb\xf2\xe7\x00\xff\xff\xff\xffЩ%p\xff\xff\xff\xff\xe2l9\x00\xff\xff\xff\xff\xe2բ\xf0\x00\x00\x00\x00\x0fuF" +
+	"\x80\x00\x00\x00\x00\x10fz\xf0\x01\x03\x02\x03\x04\x03\x02\x03\x02\x03\xff\xff\x1f\xf0\x00\x00\x00\x00qp\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\b\x00\x00~\x90\x00\fLMT\x00PDT\x00PST" +
+	"\x00JST\x00\nPST-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xed\x8c\xf1\x91\x85\x00\x00\x00\x85\x00\x00\x00\v\x00\x00\x00Asia/MuscatTZif2\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xa1\xf2\x99\xa8\x01\x00\x003\xd8\x00\x00\x00\x008@\x00\x04LMT\x00+04\x00\n<+" +
+	"04>-4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03R\xda\xedU\x02\x00\x00U\x02\x00\x00\f\x00\x00\x00Asia/NicosiaTZif2\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x001\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xff\xa5w\x1e\xb8\x00\x00\x00\x00\t\xed\xaf\xe0\x00\x00\x00\x00\nݒ\xd0\x00\x00\x00\x00\v\xfad\xe0\x00\x00\x00\x00\f" +
+	"\xbe\xc6P\x00\x00\x00\x00\r\xa49`\x00\x00\x00\x00\x0e\x8a\xe1\xd0\x00\x00\x00\x00\x0f\x84\x1b`\x00\x00\x00\x00\x10uO\xd0\x00\x00\x00\x00\x11c\xfd`\x00\x00\x00\x00\x12S\xe0P\x00\x00\x00\x00\x13M\x19\xe0\x00" +
+	"\x00\x00\x00\x143\xc2P\x00\x00\x00\x00\x15#\xc1`\x00\x00\x00\x00\x16\x13\xa4P\x00\x00\x00\x00\x17\x03\xa3`\x00\x00\x00\x00\x17\xf3\x86P\x00\x00\x00\x00\x18\xe3\x85`\x00\x00\x00\x00\x19\xd3hP\x00\x00\x00\x00\x1a" +
+	"\xc3g`\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\*\xd0\x00" +
+	"\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$,\v\xe0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf5\n`\x00\x00\x00\x00(" +
+	"\xe4\xedP\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x92`\x00" +
+	"\x00\x00\x000duP\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002M\x91\xd0\x00\x00\x00\x003=\x90\xe0\x00\x00\x00\x004-s\xd0\x00\x00\x00\x005\x1dr\xe0\x00\x00\x00\x0062x\x10\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x1fH\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c " +
+	"\x00\tLMT\x00EEST\x00EET\x00\nEET-2EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8a" +
+	"\x9a\x90\xf7\xd6\x02\x00\x00\xd6\x02\x00\x00\x11\x00\x00\x00Asia/NovokuznetskTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00" +
+	"\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x18 \xc0\xff\xff\xff\xff\xb5\xa3\xe1 \x00\x00\x00\x00\x15'o\x90\x00\x00\x00\x00\x16\x18\xa4\x00\x00\x00\x00\x00\x17\b\xa3\x10\x00\x00\x00\x00\x17\xf9׀\x00\x00\x00\x00\x18" +
+	"\xe9\u0590\x00\x00\x00\x00\x19\xdb\v\x00\x00\x00\x00\x00\x1a\xcc[\x90\x00\x00\x00\x00\x1b\xbch\xb0\x00\x00\x00\x00\x1c\xacY\xb0\x00\x00\x00\x00\x1d\x9cJ\xb0\x00\x00\x00\x00\x1e\x8c;\xb0\x00\x00\x00\x00\x1f|,\xb0\x00" +
+	"\x00\x00\x00 l\x1d\xb0\x00\x00\x00\x00!\\\x0e\xb0\x00\x00\x00\x00\"K\xff\xb0\x00\x00\x00\x00#;\xf0\xb0\x00\x00\x00\x00$+\xe1\xb0\x00\x00\x00\x00%\x1bҰ\x00\x00\x00\x00&\vð\x00\x00\x00\x00'" +
+	"\x04\xef0\x00\x00\x00\x00'\xf4\xe00\x00\x00\x00\x00(\xe4\xdf@\x00\x00\x00\x00)x\x87@\x00\x00\x00\x00)\xd4\xc20\x00\x00\x00\x00*ij0\x00\x00\x00\x00+\xb4\xa40\x00\x00\x00\x00,\xa4\x950\x00" +
+	"\x00\x00\x00-\x94\x860\x00\x00\x00\x00.\x84w0\x00\x00\x00\x00/th0\x00\x00\x00\x000dY0\x00\x00\x00\x001]\x84\xb0\x00\x00\x00\x002r_\xb0\x00\x00\x00\x003=f\xb0\x00\x00\x00\x004" +
+	"RA\xb0\x00\x00\x00\x005\x1dH\xb0\x00\x00\x00\x0062#\xb0\x00\x00\x00\x006\xfd*\xb0\x00\x00\x00\x008\x1b@0\x00\x00\x00\x008\xdd\f\xb0\x00\x00\x00\x009\xfb\"0\x00\x00\x00\x00:\xbc\xee\xb0\x00" +
+	"\x00\x00\x00;\xdb\x040\x00\x00\x00\x00<\xa6\v0\x00\x00\x00\x00=\xba\xe60\x00\x00\x00\x00>\x85\xed0\x00\x00\x00\x00?\x9a\xc80\x00\x00\x00\x00@e\xcf0\x00\x00\x00\x00A\x83\xe4\xb0\x00\x00\x00\x00B" +
+	"E\xb10\x00\x00\x00\x00Ccư\x00\x00\x00\x00D%\x930\x00\x00\x00\x00EC\xa8\xb0\x00\x00\x00\x00F\x05u0\x00\x00\x00\x00G#\x8a\xb0\x00\x00\x00\x00G\ue470\x00\x00\x00\x00I\x03l\xb0\x00" +
+	"\x00\x00\x00I\xces\xb0\x00\x00\x00\x00J\xe3N\xb0\x00\x00\x00\x00K\xaeU\xb0\x00\x00\x00\x00L\xccy@\x00\x00\x00\x00M\x8eE\xc0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x00\x00Q\xc0\x00\x00\x00\x00T`\x00\x04\x00\x00p\x80\x01" +
+	"\b\x00\x00bp\x00\f\x00\x00bp\x01\fLMT\x00+06\x00+08\x00+07\x00\n<+07>-7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)p\x1cX\xf1\x02\x00\x00" +
+	"\xf1\x02\x00\x00\x10\x00\x00\x00Asia/NovosibirskTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00C\x00\x00\x00\x05\x00\x00\x00\x10\xff" +
+	"\xff\xff\xff\xa1\xdb\x19$\xff\xff\xff\xff\xb5\xa3\xe1 \x00\x00\x00\x00\x15'o\x90\x00\x00\x00\x00\x16\x18\xa4\x00\x00\x00\x00\x00\x17\b\xa3\x10\x00\x00\x00\x00\x17\xf9׀\x00\x00\x00\x00\x18\xe9\u0590\x00\x00\x00\x00\x19" +
+	"\xdb\v\x00\x00\x00\x00\x00\x1a\xcc[\x90\x00\x00\x00\x00\x1b\xbch\xb0\x00\x00\x00\x00\x1c\xacY\xb0\x00\x00\x00\x00\x1d\x9cJ\xb0\x00\x00\x00\x00\x1e\x8c;\xb0\x00\x00\x00\x00\x1f|,\xb0\x00\x00\x00\x00 l\x1d\xb0\x00" +
+	"\x00\x00\x00!\\\x0e\xb0\x00\x00\x00\x00\"K\xff\xb0\x00\x00\x00\x00#;\xf0\xb0\x00\x00\x00\x00$+\xe1\xb0\x00\x00\x00\x00%\x1bҰ\x00\x00\x00\x00&\vð\x00\x00\x00\x00'\x04\xef0\x00\x00\x00\x00'" +
+	"\xf4\xe00\x00\x00\x00\x00(\xe4\xdf@\x00\x00\x00\x00)x\x87@\x00\x00\x00\x00)\xd4\xc20\x00\x00\x00\x00*ij0\x00\x00\x00\x00+\xb4\xa40\x00\x00\x00\x00+\xfeN\x00\x00\x00\x00\x00,\xa4\xa3@\x00" +
+	"\x00\x00\x00-\x94\x94@\x00\x00\x00\x00.\x84\x85@\x00\x00\x00\x00/tv@\x00\x00\x00\x000dg@\x00\x00\x00\x001]\x92\xc0\x00\x00\x00\x002rm\xc0\x00\x00\x00\x003=t\xc0\x00\x00\x00\x004" +
+	"RO\xc0\x00\x00\x00\x005\x1dV\xc0\x00\x00\x00\x00621\xc0\x00\x00\x00\x006\xfd8\xc0\x00\x00\x00\x008\x1bN@\x00\x00\x00\x008\xdd\x1a\xc0\x00\x00\x00\x009\xfb0@\x00\x00\x00\x00:\xbc\xfc\xc0\x00" +
+	"\x00\x00\x00;\xdb\x12@\x00\x00\x00\x00<\xa6\x19@\x00\x00\x00\x00=\xba\xf4@\x00\x00\x00\x00>\x85\xfb@\x00\x00\x00\x00?\x9a\xd6@\x00\x00\x00\x00@e\xdd@\x00\x00\x00\x00A\x83\xf2\xc0\x00\x00\x00\x00B" +
+	"E\xbf@\x00\x00\x00\x00Cc\xd4\xc0\x00\x00\x00\x00D%\xa1@\x00\x00\x00\x00EC\xb6\xc0\x00\x00\x00\x00F\x05\x83@\x00\x00\x00\x00G#\x98\xc0\x00\x00\x00\x00G\xee\x9f\xc0\x00\x00\x00\x00I\x03z\xc0\x00" +
+	"\x00\x00\x00I\u0381\xc0\x00\x00\x00\x00J\xe3\\\xc0\x00\x00\x00\x00K\xaec\xc0\x00\x00\x00\x00L\xccy@\x00\x00\x00\x00M\x8eE\xc0\x00\x00\x00\x00TK\xf30\x00\x00\x00\x00W\x93\xcc\xc0\x01\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x03" +
+	"\x01\x03\x00\x00M\xbc\x00\x00\x00\x00T`\x00\x04\x00\x00p\x80\x01\b\x00\x00bp\x00\f\x00\x00bp\x01\fLMT\x00+06\x00+08\x00+07\x00\n<+07>-7\nPK\x03" +
+	"\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:\x11\xea\xa2\xe5\x02\x00\x00\xe5\x02\x00\x00\t\x00\x00\x00Asia/OmskTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00A\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xb3@\xb6\xff\xff\xff\xff\xb5\xa3\xef0\x00\x00\x00\x00\x15'}\xa0\x00\x00\x00\x00\x16\x18\xb2\x10\x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xe5\x90\x00" +
+	"\x00\x00\x00\x18\xe9\xe4\xa0\x00\x00\x00\x00\x19\xdb\x19\x10\x00\x00\x00\x00\x1a\xcci\xa0\x00\x00\x00\x00\x1b\xbcv\xc0\x00\x00\x00\x00\x1c\xacg\xc0\x00\x00\x00\x00\x1d\x9cX\xc0\x00\x00\x00\x00\x1e\x8cI\xc0\x00\x00\x00\x00\x1f" +
+	"|:\xc0\x00\x00\x00\x00 l+\xc0\x00\x00\x00\x00!\\\x1c\xc0\x00\x00\x00\x00\"L\r\xc0\x00\x00\x00\x00#;\xfe\xc0\x00\x00\x00\x00$+\xef\xc0\x00\x00\x00\x00%\x1b\xe0\xc0\x00\x00\x00\x00&\v\xd1\xc0\x00" +
+	"\x00\x00\x00'\x04\xfd@\x00\x00\x00\x00'\xf4\xee@\x00\x00\x00\x00(\xe4\xedP\x00\x00\x00\x00)x\x95P\x00\x00\x00\x00)\xd4\xd0@\x00\x00\x00\x00*\xc4\xc1@\x00\x00\x00\x00+\xb4\xb2@\x00\x00\x00\x00," +
+	"\xa4\xa3@\x00\x00\x00\x00-\x94\x94@\x00\x00\x00\x00.\x84\x85@\x00\x00\x00\x00/tv@\x00\x00\x00\x000dg@\x00\x00\x00\x001]\x92\xc0\x00\x00\x00\x002rm\xc0\x00\x00\x00\x003=t\xc0\x00" +
+	"\x00\x00\x004RO\xc0\x00\x00\x00\x005\x1dV\xc0\x00\x00\x00\x00621\xc0\x00\x00\x00\x006\xfd8\xc0\x00\x00\x00\x008\x1bN@\x00\x00\x00\x008\xdd\x1a\xc0\x00\x00\x00\x009\xfb0@\x00\x00\x00\x00:" +
+	"\xbc\xfc\xc0\x00\x00\x00\x00;\xdb\x12@\x00\x00\x00\x00<\xa6\x19@\x00\x00\x00\x00=\xba\xf4@\x00\x00\x00\x00>\x85\xfb@\x00\x00\x00\x00?\x9a\xd6@\x00\x00\x00\x00@e\xdd@\x00\x00\x00\x00A\x83\xf2\xc0\x00" +
+	"\x00\x00\x00BE\xbf@\x00\x00\x00\x00Cc\xd4\xc0\x00\x00\x00\x00D%\xa1@\x00\x00\x00\x00EC\xb6\xc0\x00\x00\x00\x00F\x05\x83@\x00\x00\x00\x00G#\x98\xc0\x00\x00\x00\x00G\xee\x9f\xc0\x00\x00\x00\x00I" +
+	"\x03z\xc0\x00\x00\x00\x00I\u0381\xc0\x00\x00\x00\x00J\xe3\\\xc0\x00\x00\x00\x00K\xaec\xc0\x00\x00\x00\x00L\xccy@\x00\x00\x00\x00M\x8eE\xc0\x00\x00\x00\x00TK\xf30\x01\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x03\x00\x00D\xca" +
+	"\x00\x00\x00\x00FP\x00\x04\x00\x00bp\x01\b\x00\x00T`\x00\f\x00\x00T`\x01\f\x00\x00bp\x00\bLMT\x00+05\x00+07\x00+06\x00\n<+06>-6\nPK\x03" +
+	"\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&\xe9\xd1\xd8q\x02\x00\x00q\x02\x00\x00\t\x00\x00\x00Asia/OralTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x003\x00\x00\x00\a\x00\x00\x00\x14\xff\xff\xff\xff\xaa\x19\x93\xdc\xff\xff\xff\xff\xb5\xa4\vP\x00\x00\x00\x00\x15'\x8b\xb0\x00\x00\x00\x00\x16\x18\xc0 \x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xf3\xa0\x00" +
+	"\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00\x1f" +
+	"|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L\x1b\xd0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xfc\xe0\x00\x00\x00\x00&\v\xed\xe0\x00" +
+	"\x00\x00\x00'\x05\x19`\x00\x00\x00\x00'\xf5\n`\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\xa3`\x00\x00\x00\x00)\xd4\xdeP\x00\x00\x00\x00*\xc4\xdd`\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00," +
+	"\xa4\xbf`\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\xa1`\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000d\x83`\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002r\x89\xe0\x00\x00\x00\x003=\x90\xe0\x00" +
+	"\x00\x00\x004Rk\xe0\x00\x00\x00\x005\x1dr\xe0\x00\x00\x00\x0062M\xe0\x00\x00\x00\x006\xfdT\xe0\x00\x00\x00\x008\x1bj`\x00\x00\x00\x008\xdd6\xe0\x00\x00\x00\x009\xfbL`\x00\x00\x00\x00:" +
+	"\xbd\x18\xe0\x00\x00\x00\x00;\xdb.`\x00\x00\x00\x00<\xa65`\x00\x00\x00\x00=\xbb\x10`\x00\x00\x00\x00>\x86\x17`\x00\x00\x00\x00?\x9a\xf2`\x00\x00\x00\x00@e\xf9`\x00\x00\x00\x00A\x84\x0e\xe0\x01" +
+	"\x02\x03\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x06\x05\x06\x05\x06\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x02\x00\x000$\x00\x00\x00\x00*0" +
+	"\x00\x04\x00\x00FP\x00\b\x00\x00T`\x01\f\x00\x00T`\x00\f\x00\x00FP\x01\b\x00\x008@\x00\x10LMT\x00+03\x00+05\x00+06\x00+04\x00\n<+05>-5" +
+	"\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x88\xf6C\x84\x98\x00\x00\x00\x98\x00\x00\x00\x0f\x00\x00\x00Asia/Phnom_PenhTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xffV\xb6\x85\xc4\xff\xff\xff\xff\xa2jg\xc4\x01\x02\x00\x00^<\x00\x00\x00\x00^<\x00\x04\x00\x00bp\x00\bLMT" +
+	"\x00BMT\x00+07\x00\n<+07>-7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S\xa5\x81e\xf7\x00\x00\x00\xf7\x00\x00\x00\x0e\x00\x00\x00Asia/Pontian" +
+	"akTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\a\x00\x00\x00\x1f\xff\xff\xff\xff\x8b\xff\x8e\x00\xff\xff\xff\xff\xba\x16\xdf\x00\xff\xff\xff\xff\xcby\xa4" +
+	"\b\xff\xff\xff\xff\xd2V\xeep\xff\xff\xff\xff\xd7<\xc6\b\xff\xff\xff\xff\xda\xff&\x00\xff\xff\xff\xff\xf4\xb5\xbe\x88\x00\x00\x00\x00!\xdat\x80\x01\x02\x03\x02\x04\x02\x05\x06\x00\x00f\x80\x00\x00\x00\x00f\x80\x00" +
+	"\x04\x00\x00ix\x00\b\x00\x00~\x90\x00\x0e\x00\x00p\x80\x00\x12\x00\x00p\x80\x00\x16\x00\x00bp\x00\x1bLMT\x00PMT\x00+0730\x00+09\x00+08\x00WITA\x00WI" +
+	"B\x00\nWIB-7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8a\xc1\x1eB\xb7\x00\x00\x00\xb7\x00\x00\x00\x0e\x00\x00\x00Asia/PyongyangTZif2\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xff\x8b\xd7\xf1\x9c\xff\xff\xff\xff\x92\xe6\x16\xf8\xff\xff\xff\xff\xd2/ap\x00\x00\x00\x00U\xce\x02p" +
+	"\x00\x00\x00\x00Z\xecup\x01\x02\x03\x01\x03\x00\x00u\xe4\x00\x00\x00\x00w\x88\x00\x04\x00\x00~\x90\x00\b\x00\x00~\x90\x00\x04LMT\x00KST\x00JST\x00\nKST-9\nPK\x03\x04" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdav\x19z\x98\x00\x00\x00\x98\x00\x00\x00\n\x00\x00\x00Asia/QatarTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\xa1\xf2\x9d0\x00\x00\x00\x00\x04\x8a\x92\xc0\x01\x02\x00\x000P\x00\x00\x00\x008@\x00\x04\x00\x00*0\x00\bLMT\x00+04\x00+03\x00\n" +
+	"<+03>-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1\xfax\x98g\x02\x00\x00g\x02\x00\x00\r\x00\x00\x00Asia/QostanayTZif2\x00\x00\x00\x00" +
 	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
 	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x88\\\xff\xff\xff\xff\xb5\xa3\xfd@\x00\x00\x00\x00\x15'\x8b\xb0\x00\x00\x00\x00\x16\x18\xc0 \x00\x00" +
 	"\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9c" +
@@ -2508,1143 +3113,437 @@
 	"(\xd0\x00\x00\x00\x009\xfb>P\x00\x00\x00\x00:\xbd\n\xd0\x00\x00\x00\x00;\xdb P\x00\x00\x00\x00<\xa6'P\x00\x00\x00\x00=\xbb\x02P\x00\x00\x00\x00>\x86\tP\x00\x00\x00\x00?\x9a\xe4P\x00\x00" +
 	"\x00\x00@e\xebP\x00\x00\x00\x00A\x84\x00\xd0\x01\x02\x03\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
 	"\x02\x03\x02\x03\x04\x00\x00;\xa4\x00\x00\x00\x008@\x00\x04\x00\x00FP\x00\b\x00\x00T`\x01\f\x00\x00T`\x00\f\x00\x00FP\x01\bLMT\x00+04\x00+05\x00+06\x00\n<+" +
-	"06>-6\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9a\x1a\xdc\xca\xdc\x00\x00\x00\xdc\x00\x00\x00\r\x00\x1c\x00Asia/CalcuttaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc" +
-	"\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" +
-	"\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x05\x00\x00\x00\x16\xff\xff\xff\xff&\xba\x18(" +
-	"\xff\xff\xff\xffC\xe7\xeb0\xff\xff\xff\xff\x87\x9d\xbc\xba\xff\xff\xff\xff\xcaی(\xff\xff\xff\xff\xcc\x05q\x18\xff\xff\xff\xff̕2\xa8\xff\xff\xff\xff\xd2t\x12\x98\x01\x02\x03\x04\x03\x04\x03\x00\x00R\xd8\x00" +
-	"\x00\x00\x00R\xd0\x00\x04\x00\x00KF\x00\b\x00\x00MX\x00\f\x00\x00[h\x01\x10LMT\x00HMT\x00MMT\x00IST\x00+0630\x00\nIST-5:30\nPK\x03" +
-	"\x04\n\x00\x00\x00\x00\x00\x8ej\xbeTB\x1d\xc6\x1b\x85\x00\x00\x00\x85\x00\x00\x00\v\x00\x1c\x00Asia/UrumqiUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b" +
-	"\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZi" +
-	"f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xb0\xfe\xbad\x01\x00\x00R\x1c\x00\x00\x00\x00T`" +
-	"\x00\x04LMT\x00+06\x00\n<+06>-6\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT9Y\xb7\xf1\n\x01\x00\x00\n\x01\x00\x00\f\x00\x1c\x00Asia/Karach" +
-	"iUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x06" +
-	"\x00\x00\x00\x1d\xff\xff\xff\xff\x89~\xfc\xa4\xff\xff\xff\xff̕2\xa8\xff\xff\xff\xff\xd2t\x12\x98\xff\xff\xff\xffݨ\xe0\xa8\x00\x00\x00\x00\x02O\xab0\x00\x00\x00\x00<\xafE\xb0\x00\x00\x00\x00=\x9f(\xa0" +
-	"\x00\x00\x00\x00HA\xa00\x00\x00\x00\x00I\vG\xa0\x00\x00\x00\x00I\xe4\xdd0\x00\x00\x00\x00J\xec{ \x01\x02\x01\x03\x05\x04\x05\x04\x05\x04\x05\x00\x00>\xdc\x00\x00\x00\x00MX\x00\x04\x00\x00[h\x01" +
-	"\n\x00\x00FP\x00\x10\x00\x00T`\x01\x14\x00\x00FP\x00\x19LMT\x00+0530\x00+0630\x00+05\x00PKST\x00PKT\x00\nPKT-5\nPK\x03\x04\n" +
-	"\x00\x00\x00\x00\x00\x8fj\xbeT\x83g\x95M\a\x03\x00\x00\a\x03\x00\x00\r\x00\x1c\x00Asia/KhandygaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b" +
-	"\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZi" +
-	"f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00C\x00\x00\x00\b\x00\x00\x00\x14\xff\xff\xff\xff\xa1\xdb\xe4\xeb\xff\xff\xff\xff\xb5\xa3\xc5\x00\x00\x00\x00" +
-	"\x00\x15'Sp\x00\x00\x00\x00\x16\x18\x87\xe0\x00\x00\x00\x00\x17\b\x86\xf0\x00\x00\x00\x00\x17\xf9\xbb`\x00\x00\x00\x00\x18\xe9\xbap\x00\x00\x00\x00\x19\xda\xee\xe0\x00\x00\x00\x00\x1a\xcc?p\x00\x00\x00\x00\x1b\xbcL" +
-	"\x90\x00\x00\x00\x00\x1c\xac=\x90\x00\x00\x00\x00\x1d\x9c.\x90\x00\x00\x00\x00\x1e\x8c\x1f\x90\x00\x00\x00\x00\x1f|\x10\x90\x00\x00\x00\x00 l\x01\x90\x00\x00\x00\x00![\xf2\x90\x00\x00\x00\x00\"K\xe3\x90\x00\x00\x00" +
-	"\x00#;Ԑ\x00\x00\x00\x00$+Ő\x00\x00\x00\x00%\x1b\xb6\x90\x00\x00\x00\x00&\v\xa7\x90\x00\x00\x00\x00'\x04\xd3\x10\x00\x00\x00\x00'\xf4\xc4\x10\x00\x00\x00\x00(\xe4\xc3 \x00\x00\x00\x00)xk" +
-	" \x00\x00\x00\x00)Ԧ\x10\x00\x00\x00\x00*ė\x10\x00\x00\x00\x00+\xb4\x88\x10\x00\x00\x00\x00,\xa4y\x10\x00\x00\x00\x00-\x94j\x10\x00\x00\x00\x00.\x84[\x10\x00\x00\x00\x00/tL\x10\x00\x00\x00" +
-	"\x000d=\x10\x00\x00\x00\x001]h\x90\x00\x00\x00\x002rC\x90\x00\x00\x00\x003=J\x90\x00\x00\x00\x004R%\x90\x00\x00\x00\x005\x1d,\x90\x00\x00\x00\x0062\a\x90\x00\x00\x00\x006\xfd\x0e" +
-	"\x90\x00\x00\x00\x008\x1b$\x10\x00\x00\x00\x008\xdc\xf0\x90\x00\x00\x00\x009\xfb\x06\x10\x00\x00\x00\x00:\xbcҐ\x00\x00\x00\x00;\xda\xe8\x10\x00\x00\x00\x00<\xa5\xef\x10\x00\x00\x00\x00=\xba\xca\x10\x00\x00\x00" +
-	"\x00>\x85\xd1\x10\x00\x00\x00\x00?\x9a\xac\x10\x00\x00\x00\x00?\xf2\xe4p\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D%i" +
-	"\x00\x00\x00\x00\x00EC~\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xeeg\x80\x00\x00\x00\x00I\x03B\x80\x00\x00\x00\x00I\xceI\x80\x00\x00\x00\x00J\xe3$\x80\x00\x00\x00" +
-	"\x00K\xae+\x80\x00\x00\x00\x00L\xccA\x00\x00\x00\x00\x00M\x8e\r\x80\x00\x00\x00\x00Nn\x02P\x00\x00\x00\x00TK\xc9\x00\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04" +
-	"\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\a\x06\x03\x00\x00\x7f\x15\x00\x00\x00\x00p\x80\x00\x04\x00\x00\x8c\xa0" +
-	"\x01\b\x00\x00~\x90\x00\f\x00\x00~\x90\x01\f\x00\x00\x9a\xb0\x01\x10\x00\x00\x8c\xa0\x00\b\x00\x00\x9a\xb0\x00\x10LMT\x00+08\x00+10\x00+09\x00+11\x00\n<+09>-9" +
-	"\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeTj$\xcd\xf4\x9a\x00\x00\x00\x9a\x00\x00\x00\v\x00\x1c\x00Asia/ThimbuUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01" +
-	"\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" +
-	"\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xff\xd5\xe6\x15t\x00\x00\x00\x00!aM" +
-	"\xa8\x01\x02\x00\x00T\f\x00\x00\x00\x00MX\x00\x04\x00\x00T`\x00\nLMT\x00+0530\x00+06\x00\n<+06>-6\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeTj$" +
-	"\xcd\xf4\x9a\x00\x00\x00\x9a\x00\x00\x00\f\x00\x1c\x00Asia/ThimphuUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xff\xd5\xe6\x15t\x00\x00\x00\x00!aM\xa8\x01\x02\x00\x00T\f\x00\x00\x00\x00MX\x00\x04\x00" +
-	"\x00T`\x00\nLMT\x00+0530\x00+06\x00\n<+06>-6\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTd%\x05\xd8\xe6\x02\x00\x00\xe6\x02\x00\x00\x10\x00\x1c\x00As" +
-	"ia/VladivostokUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00A\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xa7YG]\xff\xff\xff\xff\xb5\xa3\xb6\xf0\x00\x00\x00\x00\x15'E`\x00\x00\x00\x00\x16\x18y\xd0\x00\x00\x00\x00\x17\bx\xe0\x00\x00\x00" +
-	"\x00\x17\xf9\xadP\x00\x00\x00\x00\x18\xe9\xac`\x00\x00\x00\x00\x19\xda\xe0\xd0\x00\x00\x00\x00\x1a\xcc1`\x00\x00\x00\x00\x1b\xbc>\x80\x00\x00\x00\x00\x1c\xac/\x80\x00\x00\x00\x00\x1d\x9c \x80\x00\x00\x00\x00\x1e\x8c\x11" +
-	"\x80\x00\x00\x00\x00\x1f|\x02\x80\x00\x00\x00\x00 k\xf3\x80\x00\x00\x00\x00![\xe4\x80\x00\x00\x00\x00\"KՀ\x00\x00\x00\x00#;ƀ\x00\x00\x00\x00$+\xb7\x80\x00\x00\x00\x00%\x1b\xa8\x80\x00\x00\x00" +
-	"\x00&\v\x99\x80\x00\x00\x00\x00'\x04\xc5\x00\x00\x00\x00\x00'\xf4\xb6\x00\x00\x00\x00\x00(\xe4\xb5\x10\x00\x00\x00\x00)x]\x10\x00\x00\x00\x00)Ԙ\x00\x00\x00\x00\x00*ĉ\x00\x00\x00\x00\x00+\xb4z" +
-	"\x00\x00\x00\x00\x00,\xa4k\x00\x00\x00\x00\x00-\x94\\\x00\x00\x00\x00\x00.\x84M\x00\x00\x00\x00\x00/t>\x00\x00\x00\x00\x000d/\x00\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002r5\x80\x00\x00\x00" +
-	"\x003=<\x80\x00\x00\x00\x004R\x17\x80\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x0061\xf9\x80\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x008\x1b\x16\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xfa\xf8" +
-	"\x00\x00\x00\x00\x00:\xbcĀ\x00\x00\x00\x00;\xda\xda\x00\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\xba\xbc\x00\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?\x9a\x9e\x00\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00" +
-	"\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D%i\x00\x00\x00\x00\x00EC~\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xeeg" +
-	"\x80\x00\x00\x00\x00I\x03B\x80\x00\x00\x00\x00I\xceI\x80\x00\x00\x00\x00J\xe3$\x80\x00\x00\x00\x00K\xae+\x80\x00\x00\x00\x00L\xccA\x00\x00\x00\x00\x00M\x8e\r\x80\x00\x00\x00\x00TK\xba\xf0\x01\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
-	"\x05\x03\x00\x00{\xa3\x00\x00\x00\x00~\x90\x00\x04\x00\x00\x9a\xb0\x01\b\x00\x00\x8c\xa0\x00\f\x00\x00\x8c\xa0\x01\f\x00\x00\x9a\xb0\x00\bLMT\x00+09\x00+11\x00+10\x00\n<+10>" +
-	"-10\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x88\xf6C\x84\x98\x00\x00\x00\x98\x00\x00\x00\x0e\x00\x1c\x00Asia/VientianeUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94" +
-	"bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01" +
-	"\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xffV\xb6\x85\xc4\xff" +
-	"\xff\xff\xff\xa2jg\xc4\x01\x02\x00\x00^<\x00\x00\x00\x00^<\x00\x04\x00\x00bp\x00\bLMT\x00BMT\x00+07\x00\n<+07>-7\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej" +
-	"\xbeT*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00\x00\r\x00\x1c\x00Asia/ShanghaiUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00T" +
-	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff~6C)\xff\xff\xff\xff\xa0\x97\xa2\x80\xff\xff\xff\xff\xa1y\x04\xf0\xff\xff" +
-	"\xff\xff\xc8Y^\x80\xff\xff\xff\xff\xc9\t\xf9p\xff\xff\xff\xff\xc9ӽ\x00\xff\xff\xff\xff\xcb\x05\x8a\xf0\xff\xff\xff\xff\xcb|@\x00\xff\xff\xff\xff\xd2;>\xf0\xff\xff\xff\xffӋ{\x80\xff\xff\xff\xff\xd4B" +
-	"\xad\xf0\xff\xff\xff\xff\xd5E\"\x00\xff\xff\xff\xff\xd6L\xbf\xf0\xff\xff\xff\xff\xd7<\xbf\x00\xff\xff\xff\xff\xd8\x06fp\xff\xff\xff\xff\xd9\x1d\xf2\x80\xff\xff\xff\xff\xd9A|\xf0\x00\x00\x00\x00\x1e\xbaR \x00\x00" +
-	"\x00\x00\x1fi\x9b\x90\x00\x00\x00\x00 ~\x84\xa0\x00\x00\x00\x00!I}\x90\x00\x00\x00\x00\"g\xa1 \x00\x00\x00\x00#)_\x90\x00\x00\x00\x00$G\x83 \x00\x00\x00\x00%\x12|\x10\x00\x00\x00\x00&'" +
-	"e \x00\x00\x00\x00&\xf2^\x10\x00\x00\x00\x00(\aG \x00\x00\x00\x00(\xd2@\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00q\xd7\x00" +
-	"\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\bLMT\x00CDT\x00CST\x00\nCST-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xb2\xb9\xf4\xb6R\x02\x00\x00R\x02\x00\x00\x0f\x00" +
-	"\x1c\x00Asia/Ulan_BatorUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x002\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\x86\xd3\xeeL\x00\x00\x00\x00\x0f\vܐ\x00\x00\x00\x00\x18\xe9Ȁ\x00\x00\x00\x00\x19\xda\xfc\xf0\x00\x00\x00\x00\x1a\xccM\x80" +
-	"\x00\x00\x00\x00\x1b\xbc0p\x00\x00\x00\x00\x1c\xac/\x80\x00\x00\x00\x00\x1d\x9c\x12p\x00\x00\x00\x00\x1e\x8c\x11\x80\x00\x00\x00\x00\x1f{\xf4p\x00\x00\x00\x00 k\xf3\x80\x00\x00\x00\x00![\xd6p\x00\x00\x00\x00" +
-	"\"KՀ\x00\x00\x00\x00#;\xb8p\x00\x00\x00\x00$+\xb7\x80\x00\x00\x00\x00%\x1b\x9ap\x00\x00\x00\x00&\v\x99\x80\x00\x00\x00\x00'\x04\xb6\xf0\x00\x00\x00\x00'\xf4\xb6\x00\x00\x00\x00\x00(\xe4\x98\xf0" +
-	"\x00\x00\x00\x00)Ԙ\x00\x00\x00\x00\x00*\xc4z\xf0\x00\x00\x00\x00+\xb4z\x00\x00\x00\x00\x00,\xa4\\\xf0\x00\x00\x00\x00-\x94\\\x00\x00\x00\x00\x00.\x84>\xf0\x00\x00\x00\x00/t>\x00\x00\x00\x00\x00" +
-	"0d \xf0\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002M=p\x00\x00\x00\x003=<\x80\x00\x00\x00\x004-\x1fp\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x006\r\x01p\x00\x00\x00\x00:鳠" +
-	"\x00\x00\x00\x00;\xb4\xac\x90\x00\x00\x00\x00<\xa4\xab\xa0\x00\x00\x00\x00=\x94\x8e\x90\x00\x00\x00\x00>\x84\x8d\xa0\x00\x00\x00\x00?tp\x90\x00\x00\x00\x00@do\xa0\x00\x00\x00\x00ATR\x90\x00\x00\x00\x00" +
-	"BDQ\xa0\x00\x00\x00\x00C44\x90\x00\x00\x00\x00D$3\xa0\x00\x00\x00\x00E\x1dQ\x10\x00\x00\x00\x00U\x15\x9a\xa0\x00\x00\x00\x00V\x05ap\x00\x00\x00\x00V\xf5|\xa0\x00\x00\x00\x00W\xe5Cp" +
-	"\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00d4\x00\x00\x00\x00bp" +
-	"\x00\x04\x00\x00~\x90\x01\b\x00\x00p\x80\x00\fLMT\x00+07\x00+09\x00+08\x00\n<+08>-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xcfׇ\xe1\x85\x00\x00" +
-	"\x00\x85\x00\x00\x00\t\x00\x1c\x00Asia/AdenUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xd5\x1b6\xb4\x01\x00\x00+\xcc\x00\x00\x00\x00*0\x00\x04LMT\x00+03\x00\n<+03>-3\nP" +
-	"K\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xed\x8c\xf1\x91\x85\x00\x00\x00\x85\x00\x00\x00\v\x00\x1c\x00Asia/MuscatUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91" +
-	"\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00T" +
-	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xa1\xf2\x99\xa8\x01\x00\x003\xd8\x00\x00\x00\x00" +
-	"8@\x00\x04LMT\x00+04\x00\n<+04>-4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xef\\\xf4q\x17\x04\x00\x00\x17\x04\x00\x00\r\x00\x1c\x00Asia/Dama" +
-	"scusUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00c\x00" +
-	"\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xff\xa1\xf2\xabx\xff\xff\xff\xff\xa2\x81/\x80\xff\xff\xff\xff\xa3^\x9dp\xff\xff\xff\xff\xa4a\x11\x80\xff\xff\xff\xff\xa5>\x7fp\xff\xff\xff\xff\xa6@\xf3\x80\xff\xff\xff\xff\xa7" +
-	"\x1eap\xff\xff\xff\xff\xa8 Հ\xff\xff\xff\xff\xa9\a}\xf0\xff\xff\xff\xff\xf1\x8fR\x00\xff\xff\xff\xff\xf2[\x9cp\xff\xff\xff\xff\xf3s(\x80\xff\xff\xff\xff\xf4;~p\xff\xff\xff\xff\xf5U\xad\x80\xff" +
-	"\xff\xff\xff\xf6\x1fT\xf0\xff\xff\xff\xff\xf76\xe1\x00\xff\xff\xff\xff\xf7\xff6\xf0\xff\xff\xff\xff\xf9\x0e\xda\x00\xff\xff\xff\xff\xf9\xe1\xbb\xf0\xff\xff\xff\xff\xfa\xf9H\x00\xff\xff\xff\xff\xfb\xc2\xefp\xff\xff\xff\xff\xfc" +
-	"\xdb\xcd\x00\xff\xff\xff\xff\xfd\xa5tp\xff\xff\xff\xff\xfe\xbd\x00\x80\xff\xff\xff\xff\xff\x86\xa7\xf0\x00\x00\x00\x00\x00\x9e4\x00\x00\x00\x00\x00\x01g\xdbp\x00\x00\x00\x00\x02\x7fg\x80\x00\x00\x00\x00\x03I\x0e\xf0\x00" +
-	"\x00\x00\x00\x04a\xec\x80\x00\x00\x00\x00\x05+\x93\xf0\x00\x00\x00\x00\x06C \x00\x00\x00\x00\x00\a\f\xc7p\x00\x00\x00\x00\b$S\x80\x00\x00\x00\x00\b\xed\xfa\xf0\x00\x00\x00\x00\n\x05\x87\x00\x00\x00\x00\x00\n" +
-	"\xcf.p\x00\x00\x00\x00\v\xe8\f\x00\x00\x00\x00\x00\f\xb1\xb3p\x00\x00\x00\x00\r\xc9?\x80\x00\x00\x00\x00\x0ekY\xf0\x00\x00\x00\x00\x0f\xaas\x00\x00\x00\x00\x00\x10L\x8dp\x00\x00\x00\x00\x18\xf4\xc5\x00\x00" +
-	"\x00\x00\x00\x19\xdbmp\x00\x00\x00\x00\x1a\xd7J\x00\x00\x00\x00\x00\x1b\xbd\xf2p\x00\x00\x00\x00\x1eU#\x00\x00\x00\x00\x00\x1f\x8a\xe5p\x00\x00\x00\x00 Gz\x00\x00\x00\x00\x00!\x89\x19\xf0\x00\x00\x00\x00\"" +
-	"<t\x00\x00\x00\x00\x00#k\x9e\xf0\x00\x00\x00\x00$2\xbf\x80\x00\x00\x00\x00%%Ep\x00\x00\x00\x00&\x15D\x80\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf6[\xe0\x00\x00\x00\x00(\xe7\x90P\x00" +
-	"\x00\x00\x00)\xe2\x1b`\x00\x00\x00\x00*\xca\x15P\x00\x00\x00\x00+\xb2+`\x00\x00\x00\x00,\xa3_\xd0\x00\x00\x00\x00-\x9bG\xe0\x00\x00\x00\x00.\x8c|P\x00\x00\x00\x00/|{`\x00\x00\x00\x000" +
-	"m\xaf\xd0\x00\x00\x00\x001_\x00`\x00\x00\x00\x002P4\xd0\x00\x00\x00\x003>\xe2`\x00\x00\x00\x0041hP\x00\x00\x00\x005\x1e\xc4`\x00\x00\x00\x006\x12\x9b\xd0\x00\x00\x00\x007\x02\x9a\xe0\x00" +
-	"\x00\x00\x007\xf3\xcfP\x00\x00\x00\x008\xe5\x1f\xe0\x00\x00\x00\x009\xd6TP\x00\x00\x00\x00:\xc6S`\x00\x00\x00\x00;\xb7\x87\xd0\x00\x00\x00\x00<\xa7\x86\xe0\x00\x00\x00\x00=\x98\xbbP\x00\x00\x00\x00>" +
-	"\x88\xba`\x00\x00\x00\x00?y\xee\xd0\x00\x00\x00\x00@k?`\x00\x00\x00\x00A\\s\xd0\x00\x00\x00\x00BLr\xe0\x00\x00\x00\x00C=\xa7P\x00\x00\x00\x00D-\xa6`\x00\x00\x00\x00E\x12\xfdP\x00" +
-	"\x00\x00\x00F\f6\xe0\x00\x00\x00\x00G*>P\x00\x00\x00\x00G\xf5S`\x00\x00\x00\x00I\vq\xd0\x00\x00\x00\x00I\xcb\xfa\xe0\x00\x00\x00\x00J\xea\x02P\x00\x00\x00\x00K\xb5\x17`\x00\x00\x00\x00L" +
-	"\xc9\xe4P\x00\x00\x00\x00M\x94\xf9`\x00\x00\x00\x00N\xa9\xc6P\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00" +
-	"\"\b\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\tLMT\x00EEST\x00EET\x00\nEET-2EEST,M3.5.5/0,M10.5.5/0\nP" +
-	"K\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x17✳2\x04\x00\x002\x04\x00\x00\x0e\x00\x1c\x00Asia/JerusalemUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00" +
-	"\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00" +
-	"\x00\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xffV\xb6\xc2\xfa\xff\xff\xff\xff\x9e0" +
-	"E\x88\xff\xff\xff\xff\xc8Y\xcf\x00\xff\xff\xff\xff\xc8\xfa\xa6\x00\xff\xff\xff\xff\xc98\x9c\x80\xff\xff\xff\xff\xcc\xe5\xeb\x80\xff\xff\xff\xffͬ\xfe\x00\xff\xff\xff\xff\xce\xc7\x1f\x00\xff\xff\xff\xffϏ\x83\x00\xff\xff" +
-	"\xff\xffЩ\xa4\x00\xff\xff\xff\xffф}\x00\xff\xff\xff\xffҊ׀\xff\xff\xff\xff\xd3e\xb0\x80\xff\xff\xff\xff\xd4l\v\x00\xff\xff\xff\xff\xd7Z0\x80\xff\xff\xff\xff\xd7\xdfX\x00\xff\xff\xff\xff\xd8/" +
-	"À\xff\xff\xff\xff\xd9\x1ec\x00\xff\xff\xff\xff\xda\x10\xf7\x00\xff\xff\xff\xff\xda\xeb\xd0\x00\xff\xff\xff\xff۴4\x00\xff\xff\xff\xffܹ=\x00\xff\xff\xff\xff\xdd\xe0\x8d\x00\xff\xff\xff\xff\u07b4\u0380\xff\xff" +
-	"\xff\xffߤ\xbf\x80\xff\xff\xff\xff\xe0\x8bv\x00\xff\xff\xff\xff\xe1V}\x00\xff\xff\xff\xff\xe2\xbef\x80\xff\xff\xff\xff\xe36_\x00\xff\xff\xff\xff\xe4\x9eH\x80\xff\xff\xff\xff\xe5\x16A\x00\xff\xff\xff\xff\xe6t" +
-	"\xf0\x00\xff\xff\xff\xff\xe7\x11Ҁ\xff\xff\xff\xff\xe8&\xad\x80\xff\xff\xff\xff\xe8\xe8z\x00\x00\x00\x00\x00\b|\x8b\xe0\x00\x00\x00\x00\b\xfd\xb0\xd0\x00\x00\x00\x00\t\xf6\xea`\x00\x00\x00\x00\n\xa63\xd0\x00\x00" +
-	"\x00\x00\x13\xe9\xfc`\x00\x00\x00\x00\x14![`\x00\x00\x00\x00\x1a\xfa\xc6`\x00\x00\x00\x00\x1b\x8en`\x00\x00\x00\x00\x1c\xbe\xf8\xe0\x00\x00\x00\x00\x1dw|\xd0\x00\x00\x00\x00\x1e\xcc\xff`\x00\x00\x00\x00\x1f`" +
-	"\x99P\x00\x00\x00\x00 \x82\xb1`\x00\x00\x00\x00!I\xb5\xd0\x00\x00\x00\x00\"^\x9e\xe0\x00\x00\x00\x00# ]P\x00\x00\x00\x00$Z0`\x00\x00\x00\x00%\x00?P\x00\x00\x00\x00&\v\xed\xe0\x00\x00" +
-	"\x00\x00&\xd6\xe6\xd0\x00\x00\x00\x00'\xeb\xcf\xe0\x00\x00\x00\x00(\xc0\x03P\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xa9\x1f\xd0\x00\x00\x00\x00+\xbbe\xe0\x00\x00\x00\x00,\x89\x01\xd0\x00\x00\x00\x00-\x9b" +
-	"G\xe0\x00\x00\x00\x00._\xa9P\x00\x00\x00\x00/{)\xe0\x00\x00\x00\x000H\xc5\xd0\x00\x00\x00\x001H\x96\xe0\x00\x00\x00\x002<nP\x00\x00\x00\x0031\xb3`\x00\x00\x00\x004\x1a\xfe\xd0\x00\x00" +
-	"\x00\x005\x11\x95`\x00\x00\x00\x005\xf1\xa6P\x00\x00\x00\x007\x04\b\x80\x00\x00\x00\x007\xcf\x01p\x00\x00\x00\x008\xf6_\x80\x00\x00\x00\x009\xdc\xf9\xe0\x00\x00\x00\x00:\xd0\xedp\x00\x00\x00\x00;\xae" +
-	"[`\x00\x00\x00\x00<\xa3\xa0p\x00\x00\x00\x00=\xa0\xb2`\x00\x00\x00\x00>\x83\x82p\x00\x00\x00\x00?|\x9f\xe0\x00\x00\x00\x00@s6p\x00\x00\x00\x00AP\xa4`\x00\x00\x00\x00BL\x8f\x00\x00\x00" +
-	"\x00\x00CHOp\x00\x00\x00\x00D,q\x00\x00\x00\x00\x00E\x1e\xf6\xf0\x00\x00\x00\x00F\fS\x00\x00\x00\x00\x00F\xecc\xf0\x00\x00\x00\x00G\xec5\x00\x00\x00\x00\x00H\xe7\xf5p\x00\x00\x00\x00I\xcc" +
-	"\x17\x00\x00\x00\x00\x00J\xbe\x9c\xf0\x00\x00\x00\x00K\xab\xf9\x00\x00\x00\x00\x00L\x8c\t\xf0\x00\x00\x00\x00M\x95\x15\x80\x00\x00\x00\x00N\x87\x9bp\x00\x00\x00\x00Ot\xf7\x80\x00\x00\x00\x00P^B\xf0\x00\x00" +
-	"\x00\x00QTـ\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00!\x06\x00\x00\x00\x00 \xf8\x00\x04\x00\x00" +
-	"*0\x01\b\x00\x00\x1c \x00\f\x00\x008@\x01\x10LMT\x00JMT\x00IDT\x00IST\x00IDDT\x00\nIST-2IDT,M3.4.4/26,M10" +
-	".5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeTy\x19\xe0N\x9a\x00\x00\x00\x9a\x00\x00\x00\v\x00\x1c\x00Asia/BruneiUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bu" +
-	"x\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00" +
-	"\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xff\xad\x8a\x02D\xff\xff\xff" +
-	"\xff\xbagG\x88\x01\x02\x00\x00k\xbc\x00\x00\x00\x00ix\x00\x04\x00\x00p\x80\x00\nLMT\x00+0730\x00+08\x00\n<+08>-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj" +
-	"\xbeT\xb2\xb9\xf4\xb6R\x02\x00\x00R\x02\x00\x00\x10\x00\x1c\x00Asia/UlaanbaatarUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_" +
-	"\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x002\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\x86\xd3\xeeL\x00\x00\x00\x00\x0f\vܐ\x00\x00\x00\x00\x18\xe9\xc8" +
-	"\x80\x00\x00\x00\x00\x19\xda\xfc\xf0\x00\x00\x00\x00\x1a\xccM\x80\x00\x00\x00\x00\x1b\xbc0p\x00\x00\x00\x00\x1c\xac/\x80\x00\x00\x00\x00\x1d\x9c\x12p\x00\x00\x00\x00\x1e\x8c\x11\x80\x00\x00\x00\x00\x1f{\xf4p\x00\x00\x00" +
-	"\x00 k\xf3\x80\x00\x00\x00\x00![\xd6p\x00\x00\x00\x00\"KՀ\x00\x00\x00\x00#;\xb8p\x00\x00\x00\x00$+\xb7\x80\x00\x00\x00\x00%\x1b\x9ap\x00\x00\x00\x00&\v\x99\x80\x00\x00\x00\x00'\x04\xb6" +
-	"\xf0\x00\x00\x00\x00'\xf4\xb6\x00\x00\x00\x00\x00(\xe4\x98\xf0\x00\x00\x00\x00)Ԙ\x00\x00\x00\x00\x00*\xc4z\xf0\x00\x00\x00\x00+\xb4z\x00\x00\x00\x00\x00,\xa4\\\xf0\x00\x00\x00\x00-\x94\\\x00\x00\x00\x00" +
-	"\x00.\x84>\xf0\x00\x00\x00\x00/t>\x00\x00\x00\x00\x000d \xf0\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002M=p\x00\x00\x00\x003=<\x80\x00\x00\x00\x004-\x1fp\x00\x00\x00\x005\x1d\x1e" +
-	"\x80\x00\x00\x00\x006\r\x01p\x00\x00\x00\x00:鳠\x00\x00\x00\x00;\xb4\xac\x90\x00\x00\x00\x00<\xa4\xab\xa0\x00\x00\x00\x00=\x94\x8e\x90\x00\x00\x00\x00>\x84\x8d\xa0\x00\x00\x00\x00?tp\x90\x00\x00\x00" +
-	"\x00@do\xa0\x00\x00\x00\x00ATR\x90\x00\x00\x00\x00BDQ\xa0\x00\x00\x00\x00C44\x90\x00\x00\x00\x00D$3\xa0\x00\x00\x00\x00E\x1dQ\x10\x00\x00\x00\x00U\x15\x9a\xa0\x00\x00\x00\x00V\x05a" +
-	"p\x00\x00\x00\x00V\xf5|\xa0\x00\x00\x00\x00W\xe5Cp\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x00\x00d4\x00\x00\x00\x00bp\x00\x04\x00\x00~\x90\x01\b\x00\x00p\x80\x00\fLMT\x00+07\x00+09\x00+08\x00\n<+08>-8\nPK\x03\x04" +
-	"\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9e\x88|`\x9a\x03\x00\x00\x9a\x03\x00\x00\n\x00\x1c\x00Asia/AmmanUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04" +
-	"S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00U\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xff\xb6\xa3\xd6\xd0\x00\x00\x00\x00\x06ry\xe0\x00\x00\x00\x00\a" +
-	"\f\xabP\x00\x00\x00\x00\b$7`\x00\x00\x00\x00\b\xed\xde\xd0\x00\x00\x00\x00\n\x05j\xe0\x00\x00\x00\x00\n\xcf\x12P\x00\x00\x00\x00\v\xe7\xef\xe0\x00\x00\x00\x00\f\xdau\xd0\x00\x00\x00\x00\r\xc9#`\x00" +
-	"\x00\x00\x00\x0e\x92\xca\xd0\x00\x00\x00\x00\x0f\xa9\x05`\x00\x00\x00\x00\x10r\xac\xd0\x00\x00\x00\x00\x1c\xad\xd5`\x00\x00\x00\x00\x1d\x9f\t\xd0\x00\x00\x00\x00\x1e\x92\xfd`\x00\x00\x00\x00\x1f\x82\xe0P\x00\x00\x00\x00 " +
-	"r\xdf`\x00\x00\x00\x00!b\xc2P\x00\x00\x00\x00\"R\xc1`\x00\x00\x00\x00#K\xde\xd0\x00\x00\x00\x00$d\xbc`\x00\x00\x00\x00%+\xc0\xd0\x00\x00\x00\x00&7o`\x00\x00\x00\x00'\v\xa2\xd0\x00" +
-	"\x00\x00\x00(\vs\xe0\x00\x00\x00\x00(\xe2JP\x00\x00\x00\x00)\xe4\xbe`\x00\x00\x00\x00*\xcbf\xd0\x00\x00\x00\x00+\xbbe\xe0\x00\x00\x00\x00,\xabH\xd0\x00\x00\x00\x00-\x9bG\xe0\x00\x00\x00\x00." +
-	"x\xb5\xd0\x00\x00\x00\x00/\x84d`\x00\x00\x00\x000X\xa5\xe0\x00\x00\x00\x001dF`\x00\x00\x00\x002A\xc2`\x00\x00\x00\x003D(`\x00\x00\x00\x004!\xa4`\x00\x00\x00\x005$\n`\x00" +
-	"\x00\x00\x006\x01\x86`\x00\x00\x00\x007z\x93`\x00\x00\x00\x007\xea\xa2\xe0\x00\x00\x00\x008\xe2|\xe0\x00\x00\x00\x009ӿ`\x00\x00\x00\x00:\xc2^\xe0\x00\x00\x00\x00;\xb3\xa1`\x00\x00\x00\x00<" +
-	"\xa3\x92`\x00\x00\x00\x00=\x93\x83`\x00\x00\x00\x00>\x83t`\x00\x00\x00\x00?\x98O`\x00\x00\x00\x00@cV`\x00\x00\x00\x00An\xf6\xe0\x00\x00\x00\x00BLr\xe0\x00\x00\x00\x00C<c\xe0\x00" +
-	"\x00\x00\x00D,T\xe0\x00\x00\x00\x00EA/\xe0\x00\x00\x00\x00F\f6\xe0\x00\x00\x00\x00G!\x11\xe0\x00\x00\x00\x00G\xec\x18\xe0\x00\x00\x00\x00I\n.`\x00\x00\x00\x00I\xcb\xfa\xe0\x00\x00\x00\x00J" +
-	"\xea\x10`\x00\x00\x00\x00K\xab\xdc\xe0\x00\x00\x00\x00L\xc9\xf2`\x00\x00\x00\x00M\x94\xf9`\x00\x00\x00\x00N\xa9\xd4`\x00\x00\x00\x00Ot\xdb`\x00\x00\x00\x00R\xb3^P\x00\x00\x00\x00S4\x9f`\x00" +
-	"\x00\x00\x00TR\xb4\xe0\x00\x00\x00\x00U\x14\x81`\x00\x00\x00\x00V2\x96\xe0\x00\x00\x00\x00V\xfd\x9d\xe0\x00\x00\x00\x00X\x12x\xe0\x00\x00\x00\x00X\xdd\x7f\xe0\x00\x00\x00\x00Y\xf2Z\xe0\x00\x00\x00\x00Z" +
-	"\xbda\xe0\x00\x00\x00\x00[\xd2<\xe0\x00\x00\x00\x00\\\x9dC\xe0\x00\x00\x00\x00]\xb2\x1e\xe0\x00\x00\x00\x00^}%\xe0\x00\x00\x00\x00_\x9b;`\x00\x00\x00\x00`]\a\xe0\x00\x00\x00\x00a{\x1d`\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00!\xb0\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\tLMT\x00EEST\x00EET\x00\nEET-" +
-	"2EEST,M2.5.4/24,M10.5.5/1\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xa7f^]@\x01\x00\x00@\x01\x00\x00\f\x00\x1c\x00Asia" +
-	"/KuchingUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x12\x00\x00\x00\x05\x00\x00\x00\x18\xff\xff\xff\xff\xad\x8a\x06\x90\xff\xff\xff\xff\xbagG\x88\xff\xff\xff\xff\xbf{'\x80\xff\xff\xff\xff\xbf\xf3\x1bP\xff\xff\xff\xff\xc1]\xac\x80\xff\xff\xff\xff\xc1ՠP\xff" +
-	"\xff\xff\xff\xc3>\xe0\x00\xff\xff\xff\xffö\xd3\xd0\xff\xff\xff\xff\xc5 \x13\x80\xff\xff\xff\xffŘ\aP\xff\xff\xff\xff\xc7\x01G\x00\xff\xff\xff\xff\xc7y:\xd0\xff\xff\xff\xff\xc8\xe3\xcc\x00\xff\xff\xff\xff\xc9" +
-	"[\xbf\xd0\xff\xff\xff\xff\xca\xc4\xff\x80\xff\xff\xff\xff\xcb<\xf3P\xff\xff\xff\xffˑX\x00\xff\xff\xff\xff\xd2Hm\xf0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x03\x00\x00gp\x00\x00\x00" +
-	"\x00ix\x00\x04\x00\x00u0\x01\n\x00\x00p\x80\x00\x10\x00\x00~\x90\x00\x14LMT\x00+0730\x00+0820\x00+08\x00+09\x00\n<+08>-8\nPK\x03\x04" +
-	"\n\x00\x00\x00\x00\x00\x8fj\xbeT\x17✳2\x04\x00\x002\x04\x00\x00\r\x00\x1c\x00Asia/Tel_AvivUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1" +
-	"\b\x00\x04S_\x01\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZ" +
-	"if3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xffV\xb6\xc2\xfa\xff\xff\xff\xff\x9e0E\x88\xff\xff" +
-	"\xff\xff\xc8Y\xcf\x00\xff\xff\xff\xff\xc8\xfa\xa6\x00\xff\xff\xff\xff\xc98\x9c\x80\xff\xff\xff\xff\xcc\xe5\xeb\x80\xff\xff\xff\xffͬ\xfe\x00\xff\xff\xff\xff\xce\xc7\x1f\x00\xff\xff\xff\xffϏ\x83\x00\xff\xff\xff\xffЩ" +
-	"\xa4\x00\xff\xff\xff\xffф}\x00\xff\xff\xff\xffҊ׀\xff\xff\xff\xff\xd3e\xb0\x80\xff\xff\xff\xff\xd4l\v\x00\xff\xff\xff\xff\xd7Z0\x80\xff\xff\xff\xff\xd7\xdfX\x00\xff\xff\xff\xff\xd8/À\xff\xff" +
-	"\xff\xff\xd9\x1ec\x00\xff\xff\xff\xff\xda\x10\xf7\x00\xff\xff\xff\xff\xda\xeb\xd0\x00\xff\xff\xff\xff۴4\x00\xff\xff\xff\xffܹ=\x00\xff\xff\xff\xff\xdd\xe0\x8d\x00\xff\xff\xff\xff\u07b4\u0380\xff\xff\xff\xffߤ" +
-	"\xbf\x80\xff\xff\xff\xff\xe0\x8bv\x00\xff\xff\xff\xff\xe1V}\x00\xff\xff\xff\xff\xe2\xbef\x80\xff\xff\xff\xff\xe36_\x00\xff\xff\xff\xff\xe4\x9eH\x80\xff\xff\xff\xff\xe5\x16A\x00\xff\xff\xff\xff\xe6t\xf0\x00\xff\xff" +
-	"\xff\xff\xe7\x11Ҁ\xff\xff\xff\xff\xe8&\xad\x80\xff\xff\xff\xff\xe8\xe8z\x00\x00\x00\x00\x00\b|\x8b\xe0\x00\x00\x00\x00\b\xfd\xb0\xd0\x00\x00\x00\x00\t\xf6\xea`\x00\x00\x00\x00\n\xa63\xd0\x00\x00\x00\x00\x13\xe9" +
-	"\xfc`\x00\x00\x00\x00\x14![`\x00\x00\x00\x00\x1a\xfa\xc6`\x00\x00\x00\x00\x1b\x8en`\x00\x00\x00\x00\x1c\xbe\xf8\xe0\x00\x00\x00\x00\x1dw|\xd0\x00\x00\x00\x00\x1e\xcc\xff`\x00\x00\x00\x00\x1f`\x99P\x00\x00" +
-	"\x00\x00 \x82\xb1`\x00\x00\x00\x00!I\xb5\xd0\x00\x00\x00\x00\"^\x9e\xe0\x00\x00\x00\x00# ]P\x00\x00\x00\x00$Z0`\x00\x00\x00\x00%\x00?P\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00&\xd6" +
-	"\xe6\xd0\x00\x00\x00\x00'\xeb\xcf\xe0\x00\x00\x00\x00(\xc0\x03P\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xa9\x1f\xd0\x00\x00\x00\x00+\xbbe\xe0\x00\x00\x00\x00,\x89\x01\xd0\x00\x00\x00\x00-\x9bG\xe0\x00\x00" +
-	"\x00\x00._\xa9P\x00\x00\x00\x00/{)\xe0\x00\x00\x00\x000H\xc5\xd0\x00\x00\x00\x001H\x96\xe0\x00\x00\x00\x002<nP\x00\x00\x00\x0031\xb3`\x00\x00\x00\x004\x1a\xfe\xd0\x00\x00\x00\x005\x11" +
-	"\x95`\x00\x00\x00\x005\xf1\xa6P\x00\x00\x00\x007\x04\b\x80\x00\x00\x00\x007\xcf\x01p\x00\x00\x00\x008\xf6_\x80\x00\x00\x00\x009\xdc\xf9\xe0\x00\x00\x00\x00:\xd0\xedp\x00\x00\x00\x00;\xae[`\x00\x00" +
-	"\x00\x00<\xa3\xa0p\x00\x00\x00\x00=\xa0\xb2`\x00\x00\x00\x00>\x83\x82p\x00\x00\x00\x00?|\x9f\xe0\x00\x00\x00\x00@s6p\x00\x00\x00\x00AP\xa4`\x00\x00\x00\x00BL\x8f\x00\x00\x00\x00\x00CH" +
-	"Op\x00\x00\x00\x00D,q\x00\x00\x00\x00\x00E\x1e\xf6\xf0\x00\x00\x00\x00F\fS\x00\x00\x00\x00\x00F\xecc\xf0\x00\x00\x00\x00G\xec5\x00\x00\x00\x00\x00H\xe7\xf5p\x00\x00\x00\x00I\xcc\x17\x00\x00\x00" +
-	"\x00\x00J\xbe\x9c\xf0\x00\x00\x00\x00K\xab\xf9\x00\x00\x00\x00\x00L\x8c\t\xf0\x00\x00\x00\x00M\x95\x15\x80\x00\x00\x00\x00N\x87\x9bp\x00\x00\x00\x00Ot\xf7\x80\x00\x00\x00\x00P^B\xf0\x00\x00\x00\x00QT" +
-	"ـ\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00!\x06\x00\x00\x00\x00 \xf8\x00\x04\x00\x00*0\x01\b" +
-	"\x00\x00\x1c \x00\f\x00\x008@\x01\x10LMT\x00JMT\x00IDT\x00IST\x00IDDT\x00\nIST-2IDT,M3.4.4/26,M10.5.0" +
-	"\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xc7X,Y\x9f\x01\x00\x00\x9f\x01\x00\x00\n\x00\x1c\x00Asia/SeoulUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04" +
-	"\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" +
-	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\x8b\xd7\xf0x\xff\xff\xff\xff\x92\xe6\x16\xf8" +
-	"\xff\xff\xff\xff\xd2C'\xf0\xff\xff\xff\xff\xd7e\x8fp\xff\xff\xff\xff\xd7\xee\x9d`\xff\xff\xff\xff\xd8\xf8\xfap\xff\xff\xff\xff\xd9\xcd-\xe0\xff\xff\xff\xff\xda\u05ca\xf0\xff\xff\xff\xffۭ\x0f\xe0\xff\xff\xff\xff" +
-	"\xdc\xe6\xe2\xf0\xff\xff\xff\xff\u074c\xf1\xe0\xff\xff\xff\xff\xe2O)\xf0\xff\xff\xff\xff\xe4k\xb7\xf8\xff\xff\xff\xff\xe5\x13\x18h\xff\xff\xff\xff\xe6b\x03x\xff\xff\xff\xff\xe7\x11L\xe8\xff\xff\xff\xff\xe8/px" +
-	"\xff\xff\xff\xff\xe8\xe7\xf4h\xff\xff\xff\xff\xea\x0fRx\xff\xff\xff\xff\xea\xc7\xd6h\xff\xff\xff\xff\xeb\xef4x\xff\xff\xff\xff째h\xff\xff\xff\xff\xed\xcf\x16x\xff\xff\xff\xff\ue1dah\xff\xff\xff\xff" +
-	"\xf05qx\x00\x00\x00\x00 \xa3`\x90\x00\x00\x00\x00!ng\x90\x00\x00\x00\x00\"\x83B\x90\x00\x00\x00\x00#NI\x90\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01" +
-	"\x04\x03\x04\x03\x04\x00\x00w\b\x00\x00\x00\x00w\x88\x00\x04\x00\x00~\x90\x00\b\x00\x00\x8c\xa0\x01\f\x00\x00~\x90\x00\x04\x00\x00\x85\x98\x01\fLMT\x00KST\x00JST\x00KDT\x00\nKS" +
-	"T-9\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT?\xa7^\xfah\x02\x00\x00h\x02\x00\x00\v\x00\x1c\x00Asia/AtyrauUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux" +
-	"\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00" +
-	"\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x002\x00\x00\x00\a\x00\x00\x00\x14\xff\xff\xff\xff\xaa\x19\x93P\xff\xff\xff\xff" +
-	"\xb5\xa4\vP\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0" +
-	"\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L\x1b\xd0\x00\x00\x00\x00" +
-	"#<\f\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\v\xdf\xd0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\xa3`" +
-	"\x00\x00\x00\x00)\xd4\xdeP\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xc0P\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xa2P\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x84P\x00\x00\x00\x00" +
-	"0duP\x00\x00\x00\x001]\xa0\xd0\x00\x00\x00\x002r{\xd0\x00\x00\x00\x003=\x82\xd0\x00\x00\x00\x004R]\xd0\x00\x00\x00\x005\x1dd\xd0\x00\x00\x00\x0062?\xd0\x00\x00\x00\x006\xfdF\xd0" +
-	"\x00\x00\x00\x008\x1bj`\x00\x00\x00\x008\xdd6\xe0\x00\x00\x00\x009\xfbL`\x00\x00\x00\x00:\xbd\x18\xe0\x00\x00\x00\x00;\xdb.`\x00\x00\x00\x00<\xa65`\x00\x00\x00\x00=\xbb\x10`\x00\x00\x00\x00" +
-	">\x86\x17`\x00\x00\x00\x00?\x9a\xf2`\x00\x00\x00\x00@e\xf9`\x00\x00\x00\x00A\x84\x0e\xe0\x01\x02\x03\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x05\x06\x02\x04\x02\x04\x02\x04\x02\x04\x02" +
-	"\x04\x02\x04\x02\x04\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x02\x00\x000\xb0\x00\x00\x00\x00*0\x00\x04\x00\x00FP\x00\b\x00\x00T`\x00\f\x00\x00T`\x01\f\x00\x00FP\x01\b\x00\x008@\x00\x10" +
-	"LMT\x00+03\x00+05\x00+06\x00+04\x00\n<+05>-5\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x8a\xc1\x1eB\xb7\x00\x00\x00\xb7\x00\x00\x00\x0e\x00\x1c\x00A" +
-	"sia/PyongyangUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xff\x8b\xd7\xf1\x9c\xff\xff\xff\xff\x92\xe6\x16\xf8\xff\xff\xff\xff\xd2/ap\x00\x00\x00\x00U\xce\x02p\x00\x00\x00\x00Z\xecup\x01\x02\x03\x01" +
-	"\x03\x00\x00u\xe4\x00\x00\x00\x00w\x88\x00\x04\x00\x00~\x90\x00\b\x00\x00~\x90\x00\x04LMT\x00KST\x00JST\x00\nKST-9\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xba\xa3" +
-	"b\xc1R\x02\x00\x00R\x02\x00\x00\t\x00\x1c\x00Asia/HovdUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x002\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\x86\xd3\xfc\x94\x00\x00\x00\x00\x0f\v\xea\xa0\x00\x00\x00\x00\x18\xe9\u0590\x00\x00\x00\x00\x19\xdb\v\x00\x00\x00" +
-	"\x00\x00\x1a\xcc[\x90\x00\x00\x00\x00\x1b\xbc>\x80\x00\x00\x00\x00\x1c\xac=\x90\x00\x00\x00\x00\x1d\x9c \x80\x00\x00\x00\x00\x1e\x8c\x1f\x90\x00\x00\x00\x00\x1f|\x02\x80\x00\x00\x00\x00 l\x01\x90\x00\x00\x00\x00![" +
-	"\xe4\x80\x00\x00\x00\x00\"K\xe3\x90\x00\x00\x00\x00#;ƀ\x00\x00\x00\x00$+Ő\x00\x00\x00\x00%\x1b\xa8\x80\x00\x00\x00\x00&\v\xa7\x90\x00\x00\x00\x00'\x04\xc5\x00\x00\x00\x00\x00'\xf4\xc4\x10\x00\x00" +
-	"\x00\x00(\xe4\xa7\x00\x00\x00\x00\x00)Ԧ\x10\x00\x00\x00\x00*ĉ\x00\x00\x00\x00\x00+\xb4\x88\x10\x00\x00\x00\x00,\xa4k\x00\x00\x00\x00\x00-\x94j\x10\x00\x00\x00\x00.\x84M\x00\x00\x00\x00\x00/t" +
-	"L\x10\x00\x00\x00\x000d/\x00\x00\x00\x00\x001]h\x90\x00\x00\x00\x002MK\x80\x00\x00\x00\x003=J\x90\x00\x00\x00\x004--\x80\x00\x00\x00\x005\x1d,\x90\x00\x00\x00\x006\r\x0f\x80\x00\x00" +
-	"\x00\x00:\xe9\xc1\xb0\x00\x00\x00\x00;\xb4\xba\xa0\x00\x00\x00\x00<\xa4\xb9\xb0\x00\x00\x00\x00=\x94\x9c\xa0\x00\x00\x00\x00>\x84\x9b\xb0\x00\x00\x00\x00?t~\xa0\x00\x00\x00\x00@d}\xb0\x00\x00\x00\x00AT" +
-	"`\xa0\x00\x00\x00\x00BD_\xb0\x00\x00\x00\x00C4B\xa0\x00\x00\x00\x00D$A\xb0\x00\x00\x00\x00E\x1d_ \x00\x00\x00\x00U\x15\xa8\xb0\x00\x00\x00\x00V\x05o\x80\x00\x00\x00\x00V\xf5\x8a\xb0\x00\x00" +
-	"\x00\x00W\xe5Q\x80\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00U\xec" +
-	"\x00\x00\x00\x00T`\x00\x04\x00\x00p\x80\x01\b\x00\x00bp\x00\fLMT\x00+06\x00+08\x00+07\x00\n<+07>-7\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x1e" +
-	"\x1f\x96\xde\xea\x04\x00\x00\xea\x04\x00\x00\v\x00\x1c\x00Asia/HebronUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif3\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00x\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xff}\xbdJ\x19\xff\xff\xff\xff\xc8Y\xcf\x00\xff\xff\xff\xff\xc8\xfa\xa6\x00\xff\xff\xff\xff\xc98\x9c" +
-	"\x80\xff\xff\xff\xff\xcc\xe5\xeb\x80\xff\xff\xff\xffͬ\xfe\x00\xff\xff\xff\xff\xce\xc7\x1f\x00\xff\xff\xff\xffϏ\x83\x00\xff\xff\xff\xffЩ\xa4\x00\xff\xff\xff\xffф}\x00\xff\xff\xff\xffҊ׀\xff\xff\xff" +
-	"\xff\xd3e\xb0\x80\xff\xff\xff\xff\xd4l\v\x00\xff\xff\xff\xff\xe86c`\xff\xff\xff\xff\xe8\xf4-P\xff\xff\xff\xff\xea\v\xb9`\xff\xff\xff\xff\xea\xd5`\xd0\xff\xff\xff\xff\xeb\xec\xfa\xf0\xff\xff\xff\xff\xec\xb5m" +
-	"\x00\xff\xff\xff\xff\xed\xcf\x7f\xf0\xff\xff\xff\xff\xee\x97\xf2\x00\xff\xff\xff\xffﰳp\xff\xff\xff\xff\xf0y%\x80\xff\xff\xff\xff\xf1\x91\xe6\xf0\xff\xff\xff\xff\xf2ZY\x00\xff\xff\xff\xff\xf3s\x1ap\xff\xff\xff" +
-	"\xff\xf4;\x8c\x80\xff\xff\xff\xff\xf5U\x9fp\xff\xff\xff\xff\xf6\x1e\x11\x80\xff\xff\xff\xff\xf76\xd2\xf0\xff\xff\xff\xff\xf7\xffE\x00\xff\xff\xff\xff\xf9\x18\x06p\xff\xff\xff\xff\xf9\xe1\xca\x00\xff\xff\xff\xff\xfa\xf99" +
-	"\xf0\xff\xff\xff\xff\xfb'BP\x00\x00\x00\x00\b|\x8b\xe0\x00\x00\x00\x00\b\xfd\xb0\xd0\x00\x00\x00\x00\t\xf6\xea`\x00\x00\x00\x00\n\xa63\xd0\x00\x00\x00\x00\x13\xe9\xfc`\x00\x00\x00\x00\x14![`\x00\x00\x00" +
-	"\x00\x1a\xfa\xc6`\x00\x00\x00\x00\x1b\x8en`\x00\x00\x00\x00\x1c\xbe\xf8\xe0\x00\x00\x00\x00\x1dw|\xd0\x00\x00\x00\x00\x1e\xcc\xff`\x00\x00\x00\x00\x1f`\x99P\x00\x00\x00\x00 \x82\xb1`\x00\x00\x00\x00!I\xb5" +
-	"\xd0\x00\x00\x00\x00\"^\x9e\xe0\x00\x00\x00\x00# ]P\x00\x00\x00\x00$Z0`\x00\x00\x00\x00%\x00?P\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00&\xd6\xe6\xd0\x00\x00\x00\x00'\xeb\xcf\xe0\x00\x00\x00" +
-	"\x00(\xc0\x03P\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xa9\x1f\xd0\x00\x00\x00\x00+\xbbe\xe0\x00\x00\x00\x00,\x89\x01\xd0\x00\x00\x00\x00-\x9bG\xe0\x00\x00\x00\x00._\xa9P\x00\x00\x00\x00/{)" +
-	"\xe0\x00\x00\x00\x000H\xc5\xd0\x00\x00\x00\x000\xe7\a\xe0\x00\x00\x00\x001dF`\x00\x00\x00\x002A\xc2`\x00\x00\x00\x003D(`\x00\x00\x00\x004!\xa4`\x00\x00\x00\x005$\n`\x00\x00\x00" +
-	"\x006\x01\x86`\x00\x00\x00\x007\x16a`\x00\x00\x00\x008\x06DP\x00\x00\x00\x008\xff}\xe0\x00\x00\x00\x009\xef`\xd0\x00\x00\x00\x00:\xdf_\xe0\x00\x00\x00\x00;\xcfB\xd0\x00\x00\x00\x00<\xbfA" +
-	"\xe0\x00\x00\x00\x00=\xaf$\xd0\x00\x00\x00\x00>\x9f#\xe0\x00\x00\x00\x00?\x8f\x06\xd0\x00\x00\x00\x00@\x7f\x05\xe0\x00\x00\x00\x00A\\\x81\xe0\x00\x00\x00\x00B^\xe7\xe0\x00\x00\x00\x00CA\xb7\xf0\x00\x00\x00" +
-	"\x00D-\xa6`\x00\x00\x00\x00E\x12\xfdP\x00\x00\x00\x00F\x0e\xd9\xe0\x00\x00\x00\x00F\xe8op\x00\x00\x00\x00G\xec\x18\xe0\x00\x00\x00\x00H\xbb\x06P\x00\x00\x00\x00I\xcb\xfa\xe0\x00\x00\x00\x00J\xa0<" +
-	"`\x00\x00\x00\x00K\xab\xdc\xe0\x00\x00\x00\x00La\xbd\xd0\x00\x00\x00\x00M\x94\xf9\x9c\x00\x00\x00\x00N5\xc2P\x00\x00\x00\x00N\\\v\xe0\x00\x00\x00\x00N\x84\xdcP\x00\x00\x00\x00Ot\xdb`\x00\x00\x00" +
-	"\x00P[\x91\xe0\x00\x00\x00\x00QT\xbd`\x00\x00\x00\x00RD\xa0P\x00\x00\x00\x00S4\x9f`\x00\x00\x00\x00TIlP\x00\x00\x00\x00U\x15\xd2\xe0\x00\x00\x00\x00V)\\`\x00\x00\x00\x00V\xf5\xc2" +
-	"\xf0\x00\x00\x00\x00X\x13\xca`\x00\x00\x00\x00Xդ\xf0\x00\x00\x00\x00Y\xf3\xac`\x00\x00\x00\x00Z\xb5\x86\xf0\x00\x00\x00\x00[ӎ`\x00\x00\x00\x00\\\x9dC\xe0\x00\x00\x00\x00]\xb3bP\x00\x00\x00" +
-	"\x00^~w`\x00\x00\x00\x00_\x93R`\x00\x00\x00\x00`^Y`\x00\x00\x00\x00a{\x1d`\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00 \xe7\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\t\x00\x00*0\x01\r\x00\x00\x1c \x00\x11L" +
-	"MT\x00EEST\x00EET\x00IDT\x00IST\x00\nEET-2EEST,M3.4.4/72,M10.4.4/25\nPK\x03\x04\n\x00\x00\x00" +
-	"\x00\x00\x8fj\xbeT\xcfׇ\xe1\x85\x00\x00\x00\x85\x00\x00\x00\v\x00\x1c\x00Asia/KuwaitUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01" +
-	"\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xd5\x1b6\xb4\x01\x00\x00+\xcc\x00\x00\x00\x00*0\x00\x04LMT" +
-	"\x00+03\x00\n<+03>-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT[u\x99q\xf1\x02\x00\x00\xf1\x02\x00\x00\n\x00\x1c\x00Asia/TomskUT\t\x00\x03\xdd" +
-	"\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00C\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff" +
-	"\xff\xa1\xe5N\xd9\xff\xff\xff\xff\xb5\xa3\xe1 \x00\x00\x00\x00\x15'o\x90\x00\x00\x00\x00\x16\x18\xa4\x00\x00\x00\x00\x00\x17\b\xa3\x10\x00\x00\x00\x00\x17\xf9׀\x00\x00\x00\x00\x18\xe9\u0590\x00\x00\x00\x00\x19\xdb\v" +
-	"\x00\x00\x00\x00\x00\x1a\xcc[\x90\x00\x00\x00\x00\x1b\xbch\xb0\x00\x00\x00\x00\x1c\xacY\xb0\x00\x00\x00\x00\x1d\x9cJ\xb0\x00\x00\x00\x00\x1e\x8c;\xb0\x00\x00\x00\x00\x1f|,\xb0\x00\x00\x00\x00 l\x1d\xb0\x00\x00\x00" +
-	"\x00!\\\x0e\xb0\x00\x00\x00\x00\"K\xff\xb0\x00\x00\x00\x00#;\xf0\xb0\x00\x00\x00\x00$+\xe1\xb0\x00\x00\x00\x00%\x1bҰ\x00\x00\x00\x00&\vð\x00\x00\x00\x00'\x04\xef0\x00\x00\x00\x00'\xf4\xe0" +
-	"0\x00\x00\x00\x00(\xe4\xdf@\x00\x00\x00\x00)x\x87@\x00\x00\x00\x00)\xd4\xc20\x00\x00\x00\x00*ij0\x00\x00\x00\x00+\xb4\xa40\x00\x00\x00\x00,\xa4\x950\x00\x00\x00\x00-\x94\x860\x00\x00\x00" +
-	"\x00.\x84w0\x00\x00\x00\x00/th0\x00\x00\x00\x000dY0\x00\x00\x00\x001]\x84\xb0\x00\x00\x00\x002r_\xb0\x00\x00\x00\x003=f\xb0\x00\x00\x00\x004RA\xb0\x00\x00\x00\x005\x1dH" +
-	"\xb0\x00\x00\x00\x0062#\xb0\x00\x00\x00\x006\xfd*\xb0\x00\x00\x00\x008\x1b@0\x00\x00\x00\x008\xdd\f\xb0\x00\x00\x00\x009\xfb\"0\x00\x00\x00\x00:\xbc\xee\xb0\x00\x00\x00\x00;\xdb\x040\x00\x00\x00" +
-	"\x00<\xa6\v0\x00\x00\x00\x00<\xce\xe9\xb0\x00\x00\x00\x00=\xba\xf4@\x00\x00\x00\x00>\x85\xfb@\x00\x00\x00\x00?\x9a\xd6@\x00\x00\x00\x00@e\xdd@\x00\x00\x00\x00A\x83\xf2\xc0\x00\x00\x00\x00BE\xbf" +
-	"@\x00\x00\x00\x00Cc\xd4\xc0\x00\x00\x00\x00D%\xa1@\x00\x00\x00\x00EC\xb6\xc0\x00\x00\x00\x00F\x05\x83@\x00\x00\x00\x00G#\x98\xc0\x00\x00\x00\x00G\xee\x9f\xc0\x00\x00\x00\x00I\x03z\xc0\x00\x00\x00" +
-	"\x00I\u0381\xc0\x00\x00\x00\x00J\xe3\\\xc0\x00\x00\x00\x00K\xaec\xc0\x00\x00\x00\x00L\xccy@\x00\x00\x00\x00M\x8eE\xc0\x00\x00\x00\x00TK\xf30\x00\x00\x00\x00WI\xf8\xc0\x01\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x03\x01\x03" +
-	"\x00\x00O\xa7\x00\x00\x00\x00T`\x00\x04\x00\x00p\x80\x01\b\x00\x00bp\x00\f\x00\x00bp\x01\fLMT\x00+06\x00+08\x00+07\x00\n<+07>-7\nPK\x03\x04\n" +
-	"\x00\x00\x00\x00\x00\x8fj\xbeTǯ\xdf\x1c\xee\x00\x00\x00\xee\x00\x00\x00\v\x00\x1c\x00Asia/ManilaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04" +
-	"S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\x14\xe1\xdc\x10\xff\xff\xff\xff{\x1f?\x90\xff\xff\xff\xff\xc1" +
-	"\x9c\xf4\x80\xff\xff\xff\xff\xc2\x160p\xff\xff\xff\xff\xcb\xf2\xe7\x00\xff\xff\xff\xffЩ%p\xff\xff\xff\xff\xe2l9\x00\xff\xff\xff\xff\xe2բ\xf0\x00\x00\x00\x00\x0fuF\x80\x00\x00\x00\x00\x10fz\xf0\x01" +
-	"\x03\x02\x03\x04\x03\x02\x03\x02\x03\xff\xff\x1f\xf0\x00\x00\x00\x00qp\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\b\x00\x00~\x90\x00\fLMT\x00PDT\x00PST\x00JST\x00\nPST-" +
-	"8\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xab\xcd\xdf\x05\xee\x02\x00\x00\xee\x02\x00\x00\n\x00\x1c\x00Asia/ChitaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01" +
-	"\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" +
-	"\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xdb\xf9\xa0\xff\xff\xff\xff\xb5\xa3\xc5" +
-	"\x00\x00\x00\x00\x00\x15'Sp\x00\x00\x00\x00\x16\x18\x87\xe0\x00\x00\x00\x00\x17\b\x86\xf0\x00\x00\x00\x00\x17\xf9\xbb`\x00\x00\x00\x00\x18\xe9\xbap\x00\x00\x00\x00\x19\xda\xee\xe0\x00\x00\x00\x00\x1a\xcc?p\x00\x00\x00" +
-	"\x00\x1b\xbcL\x90\x00\x00\x00\x00\x1c\xac=\x90\x00\x00\x00\x00\x1d\x9c.\x90\x00\x00\x00\x00\x1e\x8c\x1f\x90\x00\x00\x00\x00\x1f|\x10\x90\x00\x00\x00\x00 l\x01\x90\x00\x00\x00\x00![\xf2\x90\x00\x00\x00\x00\"K\xe3" +
-	"\x90\x00\x00\x00\x00#;Ԑ\x00\x00\x00\x00$+Ő\x00\x00\x00\x00%\x1b\xb6\x90\x00\x00\x00\x00&\v\xa7\x90\x00\x00\x00\x00'\x04\xd3\x10\x00\x00\x00\x00'\xf4\xc4\x10\x00\x00\x00\x00(\xe4\xc3 \x00\x00\x00" +
-	"\x00)xk \x00\x00\x00\x00)Ԧ\x10\x00\x00\x00\x00*ė\x10\x00\x00\x00\x00+\xb4\x88\x10\x00\x00\x00\x00,\xa4y\x10\x00\x00\x00\x00-\x94j\x10\x00\x00\x00\x00.\x84[\x10\x00\x00\x00\x00/tL" +
-	"\x10\x00\x00\x00\x000d=\x10\x00\x00\x00\x001]h\x90\x00\x00\x00\x002rC\x90\x00\x00\x00\x003=J\x90\x00\x00\x00\x004R%\x90\x00\x00\x00\x005\x1d,\x90\x00\x00\x00\x0062\a\x90\x00\x00\x00" +
-	"\x006\xfd\x0e\x90\x00\x00\x00\x008\x1b$\x10\x00\x00\x00\x008\xdc\xf0\x90\x00\x00\x00\x009\xfb\x06\x10\x00\x00\x00\x00:\xbcҐ\x00\x00\x00\x00;\xda\xe8\x10\x00\x00\x00\x00<\xa5\xef\x10\x00\x00\x00\x00=\xba\xca" +
-	"\x10\x00\x00\x00\x00>\x85\xd1\x10\x00\x00\x00\x00?\x9a\xac\x10\x00\x00\x00\x00@e\xb3\x10\x00\x00\x00\x00A\x83Ȑ\x00\x00\x00\x00BE\x95\x10\x00\x00\x00\x00Cc\xaa\x90\x00\x00\x00\x00D%w\x10\x00\x00\x00" +
-	"\x00EC\x8c\x90\x00\x00\x00\x00F\x05Y\x10\x00\x00\x00\x00G#n\x90\x00\x00\x00\x00G\xeeu\x90\x00\x00\x00\x00I\x03P\x90\x00\x00\x00\x00I\xceW\x90\x00\x00\x00\x00J\xe32\x90\x00\x00\x00\x00K\xae9" +
-	"\x90\x00\x00\x00\x00L\xccO\x10\x00\x00\x00\x00M\x8e\x1b\x90\x00\x00\x00\x00TK\xc9\x00\x00\x00\x00\x00V\xf6\xce \x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03" +
-	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x01\x03\x00\x00j`\x00\x00\x00\x00p\x80\x00\x04\x00\x00\x8c\xa0\x01\b\x00\x00~" +
-	"\x90\x00\f\x00\x00~\x90\x01\f\x00\x00\x8c\xa0\x00\bLMT\x00+08\x00+10\x00+09\x00\n<+09>-9\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x8bSnT\xa1\x00" +
-	"\x00\x00\xa1\x00\x00\x00\r\x00\x1c\x00Asia/KatmanduUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xf2}\x84\x00\x00\x00\x00\x1e\x180\xa8\x01\x02\x00\x00O\xfc\x00\x00\x00\x00MX\x00\x04\x00\x00P\xdc" +
-	"\x00\nLMT\x00+0530\x00+0545\x00\n<+0545>-5:45\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9e\xa1=H\xd8\x04\x00\x00\xd8\x04\x00\x00\t\x00" +
-	"\x1c\x00Asia/GazaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00v\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xff}\xbdJ\xb0\xff\xff\xff\xff\xc8Y\xcf\x00\xff\xff\xff\xff\xc8\xfa\xa6\x00\xff\xff\xff\xff\xc98\x9c\x80\xff\xff\xff\xff\xcc\xe5\xeb\x80\xff\xff\xff\xffͬ" +
-	"\xfe\x00\xff\xff\xff\xff\xce\xc7\x1f\x00\xff\xff\xff\xffϏ\x83\x00\xff\xff\xff\xffЩ\xa4\x00\xff\xff\xff\xffф}\x00\xff\xff\xff\xffҊ׀\xff\xff\xff\xff\xd3e\xb0\x80\xff\xff\xff\xff\xd4l\v\x00\xff\xff" +
-	"\xff\xff\xe86c`\xff\xff\xff\xff\xe8\xf4-P\xff\xff\xff\xff\xea\v\xb9`\xff\xff\xff\xff\xea\xd5`\xd0\xff\xff\xff\xff\xeb\xec\xfa\xf0\xff\xff\xff\xff\xec\xb5m\x00\xff\xff\xff\xff\xed\xcf\x7f\xf0\xff\xff\xff\xff\xee\x97" +
-	"\xf2\x00\xff\xff\xff\xffﰳp\xff\xff\xff\xff\xf0y%\x80\xff\xff\xff\xff\xf1\x91\xe6\xf0\xff\xff\xff\xff\xf2ZY\x00\xff\xff\xff\xff\xf3s\x1ap\xff\xff\xff\xff\xf4;\x8c\x80\xff\xff\xff\xff\xf5U\x9fp\xff\xff" +
-	"\xff\xff\xf6\x1e\x11\x80\xff\xff\xff\xff\xf76\xd2\xf0\xff\xff\xff\xff\xf7\xffE\x00\xff\xff\xff\xff\xf9\x18\x06p\xff\xff\xff\xff\xf9\xe1\xca\x00\xff\xff\xff\xff\xfa\xf99\xf0\xff\xff\xff\xff\xfb'BP\x00\x00\x00\x00\b|" +
-	"\x8b\xe0\x00\x00\x00\x00\b\xfd\xb0\xd0\x00\x00\x00\x00\t\xf6\xea`\x00\x00\x00\x00\n\xa63\xd0\x00\x00\x00\x00\x13\xe9\xfc`\x00\x00\x00\x00\x14![`\x00\x00\x00\x00\x1a\xfa\xc6`\x00\x00\x00\x00\x1b\x8en`\x00\x00" +
-	"\x00\x00\x1c\xbe\xf8\xe0\x00\x00\x00\x00\x1dw|\xd0\x00\x00\x00\x00\x1e\xcc\xff`\x00\x00\x00\x00\x1f`\x99P\x00\x00\x00\x00 \x82\xb1`\x00\x00\x00\x00!I\xb5\xd0\x00\x00\x00\x00\"^\x9e\xe0\x00\x00\x00\x00# " +
-	"]P\x00\x00\x00\x00$Z0`\x00\x00\x00\x00%\x00?P\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00&\xd6\xe6\xd0\x00\x00\x00\x00'\xeb\xcf\xe0\x00\x00\x00\x00(\xc0\x03P\x00\x00\x00\x00)\xd4\xec`\x00\x00" +
-	"\x00\x00*\xa9\x1f\xd0\x00\x00\x00\x00+\xbbe\xe0\x00\x00\x00\x00,\x89\x01\xd0\x00\x00\x00\x00-\x9bG\xe0\x00\x00\x00\x00._\xa9P\x00\x00\x00\x00/{)\xe0\x00\x00\x00\x000H\xc5\xd0\x00\x00\x00\x000\xe7" +
-	"\a\xe0\x00\x00\x00\x001dF`\x00\x00\x00\x002A\xc2`\x00\x00\x00\x003D(`\x00\x00\x00\x004!\xa4`\x00\x00\x00\x005$\n`\x00\x00\x00\x006\x01\x86`\x00\x00\x00\x007\x16a`\x00\x00" +
-	"\x00\x008\x06DP\x00\x00\x00\x008\xff}\xe0\x00\x00\x00\x009\xef`\xd0\x00\x00\x00\x00:\xdf_\xe0\x00\x00\x00\x00;\xcfB\xd0\x00\x00\x00\x00<\xbfA\xe0\x00\x00\x00\x00=\xaf$\xd0\x00\x00\x00\x00>\x9f" +
-	"#\xe0\x00\x00\x00\x00?\x8f\x06\xd0\x00\x00\x00\x00@\x7f\x05\xe0\x00\x00\x00\x00A\\\x81\xe0\x00\x00\x00\x00B^\xe7\xe0\x00\x00\x00\x00CA\xb7\xf0\x00\x00\x00\x00D-\xa6`\x00\x00\x00\x00E\x12\xfdP\x00\x00" +
-	"\x00\x00F\x0e\xd9\xe0\x00\x00\x00\x00F\xe8op\x00\x00\x00\x00G\xec\x18\xe0\x00\x00\x00\x00H\xb7\x11\xd0\x00\x00\x00\x00I\xcb\xfa\xe0\x00\x00\x00\x00J\xa0<`\x00\x00\x00\x00K\xad.\x9c\x00\x00\x00\x00La" +
-	"\xbd\xd0\x00\x00\x00\x00M\x94\xf9\x9c\x00\x00\x00\x00N5\xc2P\x00\x00\x00\x00Ot\xdb`\x00\x00\x00\x00P[\x91\xe0\x00\x00\x00\x00QT\xbd`\x00\x00\x00\x00RD\xa0P\x00\x00\x00\x00S4\x9f`\x00\x00" +
-	"\x00\x00TIlP\x00\x00\x00\x00U\x15\xd2\xe0\x00\x00\x00\x00V)\\`\x00\x00\x00\x00V\xf5\xc2\xf0\x00\x00\x00\x00X\x13\xca`\x00\x00\x00\x00Xդ\xf0\x00\x00\x00\x00Y\xf3\xac`\x00\x00\x00\x00Z\xb5" +
-	"\x86\xf0\x00\x00\x00\x00[ӎ`\x00\x00\x00\x00\\\x9dC\xe0\x00\x00\x00\x00]\xb3bP\x00\x00\x00\x00^~w`\x00\x00\x00\x00_\x93R`\x00\x00\x00\x00`^Y`\x00\x00\x00\x00a{\x1d`\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" +
-	"\x04\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00 P" +
-	"\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\t\x00\x00*0\x01\r\x00\x00\x1c \x00\x11LMT\x00EEST\x00EET\x00IDT\x00IST\x00\nEET-2EEST,M3" +
-	".4.4/72,M10.4.4/25\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTw\rD\an\x01\x00\x00n\x01\x00\x00\x0e\x00\x1c\x00Asia/Samark" +
-	"andUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x00" +
-	"\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x857\xff\xff\xff\xff\xb5\xa3\xfd@\x00\x00\x00\x00\x15'\x8b\xb0\x00\x00\x00\x00\x16\x18\xc0 \x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9" +
-	"\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00\x1f|H\xd0\x00\x00" +
-	"\x00\x00 l9\xd0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L\x1b\xd0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\v\xdf\xd0\x00\x00\x00\x00'\x05" +
-	"\vP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xedP\x01\x02\x03\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00>\xc9\x00\x00\x00\x008@\x00\x04\x00\x00FP\x00\b" +
-	"\x00\x00T`\x01\f\x00\x00T`\x00\fLMT\x00+04\x00+05\x00+06\x00\n<+05>-5\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\xee\xf0BB\xff\x01\x00\x00\xff" +
-	"\x01\x00\x00\v\x00\x1c\x00Asia/TaipeiUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xfft\xce\xf0\x18\xff\xff\xff\xff\xc3UI\x80\xff\xff\xff\xff\xd2TY\x80\xff\xff\xff\xffӋ{\x80\xff\xff\xff\xff\xd4B\xad" +
-	"\xf0\xff\xff\xff\xff\xd5E\"\x00\xff\xff\xff\xff\xd6L\xbf\xf0\xff\xff\xff\xff\xd7<\xbf\x00\xff\xff\xff\xff\xd8\x06fp\xff\xff\xff\xff\xd9\x1d\xf2\x80\xff\xff\xff\xff\xd9\xe7\x99\xf0\xff\xff\xff\xff\xda\xff&\x00\xff\xff\xff" +
-	"\xff\xdb\xc8\xcdp\xff\xff\xff\xff\xdc\xe0Y\x80\xff\xff\xff\xffݪ\x00\xf0\xff\xff\xff\xff\xders\x00\xff\xff\xff\xffߵdp\xff\xff\xff\xff\xe0|\x85\x00\xff\xff\xff\xffᖗ\xf0\xff\xff\xff\xff\xe2]\xb8" +
-	"\x80\xff\xff\xff\xff\xe3w\xcbp\xff\xff\xff\xff\xe4>\xec\x00\xff\xff\xff\xff\xe50 p\xff\xff\xff\xff\xe6!q\x00\xff\xff\xff\xff\xe7\x12\xa5p\xff\xff\xff\xff\xe8\x02\xa4\x80\xff\xff\xff\xff\xe8\xf3\xd8\xf0\xff\xff\xff" +
-	"\xff\xe9\xe3\xd8\x00\xff\xff\xff\xff\xea\xd5\fp\xff\xff\xff\xff\xeb\xc5\v\x80\xff\xff\xff\xff\xec\xb6?\xf0\xff\xff\xff\xff\xed\xf7\xfc\x00\xff\xff\xff\xff\xee\x98\xc4\xf0\xff\xff\xff\xff\xef\xd9/\x80\xff\xff\xff\xff\xf0y\xf8" +
-	"p\x00\x00\x00\x00\a\xfcV\x00\x00\x00\x00\x00\b\xed\x8ap\x00\x00\x00\x00\t݉\x80\x00\x00\x00\x00\nν\xf0\x00\x00\x00\x00\x11ۡ\x80\x00\x00\x00\x00\x12T\xddp\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01" +
-	"\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x00\x00q\xe8\x00\x00\x00\x00p\x80\x00\x04\x00\x00~\x90\x00\b\x00\x00~\x90\x01\fLMT\x00CS" +
-	"T\x00JST\x00CDT\x00\nCST-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xb2\xe27Yn\x01\x00\x00n\x01\x00\x00\r\x00\x1c\x00Asia/Tashkent" +
-	"UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x00\x00\x00\x05\x00" +
-	"\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x83\t\xff\xff\xff\xff\xb5\xa3\xef0\x00\x00\x00\x00\x15'}\xa0\x00\x00\x00\x00\x16\x18\xb2\x10\x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xe5\x90\x00\x00\x00\x00\x18\xe9\xe4\xa0\x00" +
-	"\x00\x00\x00\x19\xdb\x19\x10\x00\x00\x00\x00\x1a\xcci\xa0\x00\x00\x00\x00\x1b\xbcv\xc0\x00\x00\x00\x00\x1c\xacg\xc0\x00\x00\x00\x00\x1d\x9cX\xc0\x00\x00\x00\x00\x1e\x8cI\xc0\x00\x00\x00\x00\x1f|:\xc0\x00\x00\x00\x00 " +
-	"l+\xc0\x00\x00\x00\x00!\\\x1c\xc0\x00\x00\x00\x00\"L\r\xc0\x00\x00\x00\x00#;\xfe\xc0\x00\x00\x00\x00$+\xef\xc0\x00\x00\x00\x00%\x1b\xe0\xc0\x00\x00\x00\x00&\v\xd1\xc0\x00\x00\x00\x00'\x04\xfd@\x00" +
-	"\x00\x00\x00'\xf4\xee@\x00\x00\x00\x00(\xe4\xedP\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x00\x00@\xf7\x00\x00\x00\x00FP\x00\x04\x00\x00bp\x01\b\x00\x00T" +
-	"`\x00\f\x00\x00T`\x01\fLMT\x00+05\x00+07\x00+06\x00\n<+05>-5\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9a\xea\x18\xd4\xf8\x02\x00\x00\xf8\x02\x00\x00" +
-	"\x12\x00\x1c\x00Asia/YekaterinburgUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00" +
+	"06>-6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd5ΜGp\x02\x00\x00p\x02\x00\x00\x0e\x00\x00\x00Asia/QyzylordaTZif2\x00\x00\x00\x00\x00" +
 	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x00\x00\x00\a\x00\x00\x00\x14\xff\xff\xff\xff\x9b_\t'\xff\xff\xff\xff\xa1\x12\xb1\xff\xff\xff\xff\xff\xb5\xa3\xfd@\x00\x00\x00\x00\x15'\x8b\xb0\x00\x00\x00" +
-	"\x00\x16\x18\xc0 \x00\x00\x00\x00\x17\b\xbf0\x00\x00\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu" +
-	"\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L\x1b\xd0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00" +
-	"\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\v\xdf\xd0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\xa3`\x00\x00\x00\x00)\xd4\xde" +
-	"P\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xc0P\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xa2P\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x84P\x00\x00\x00\x000duP\x00\x00\x00" +
-	"\x001]\xa0\xd0\x00\x00\x00\x002r{\xd0\x00\x00\x00\x003=\x82\xd0\x00\x00\x00\x004R]\xd0\x00\x00\x00\x005\x1dd\xd0\x00\x00\x00\x0062?\xd0\x00\x00\x00\x006\xfdF\xd0\x00\x00\x00\x008\x1b\\" +
-	"P\x00\x00\x00\x008\xdd(\xd0\x00\x00\x00\x009\xfb>P\x00\x00\x00\x00:\xbd\n\xd0\x00\x00\x00\x00;\xdb P\x00\x00\x00\x00<\xa6'P\x00\x00\x00\x00=\xbb\x02P\x00\x00\x00\x00>\x86\tP\x00\x00\x00" +
-	"\x00?\x9a\xe4P\x00\x00\x00\x00@e\xebP\x00\x00\x00\x00A\x84\x00\xd0\x00\x00\x00\x00BE\xcdP\x00\x00\x00\x00Cc\xe2\xd0\x00\x00\x00\x00D%\xafP\x00\x00\x00\x00EC\xc4\xd0\x00\x00\x00\x00F\x05\x91" +
-	"P\x00\x00\x00\x00G#\xa6\xd0\x00\x00\x00\x00G\xee\xad\xd0\x00\x00\x00\x00I\x03\x88\xd0\x00\x00\x00\x00IΏ\xd0\x00\x00\x00\x00J\xe3j\xd0\x00\x00\x00\x00K\xaeq\xd0\x00\x00\x00\x00L̇P\x00\x00\x00" +
-	"\x00M\x8eS\xd0\x00\x00\x00\x00TL\x01@\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x05\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" +
-	"\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x06\x04\x00\x008\xd9\x00\x00\x00\x004\xc1\x00\x04\x00\x008@\x00\b\x00\x00T`\x01\f\x00\x00FP\x00\x10\x00\x00FP\x01\x10\x00\x00T`\x00" +
-	"\fLMT\x00PMT\x00+04\x00+06\x00+05\x00\n<+05>-5\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\x1d?v\f\x17\x03\x00\x00\x17\x03\x00\x00\n\x00\x1c\x00" +
-	"Asia/MacauUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x004\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x86\xa0\xff\xff\xff\xff\xb5\xa3\xfd@\x00\x00\x00\x00\x15'\x8b\xb0\x00\x00\x00\x00\x16\x18\xc0 \x00\x00\x00" +
+	"\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf" +
+	"\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L\x1b\xd0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00" +
+	"\x00%\x1b\xee\xd0\x00\x00\x00\x00&\v\xdf\xd0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\x95P\x00\x00\x00\x00)\xd4\xd0@\x00\x00\x00\x00*\xc4\xcf" +
+	"P\x00\x00\x00\x00+\xb4\xc0P\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xa2P\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x84P\x00\x00\x00\x000duP\x00\x00\x00\x001]\xa0\xd0\x00\x00\x00" +
+	"\x002r{\xd0\x00\x00\x00\x003=\x82\xd0\x00\x00\x00\x004R]\xd0\x00\x00\x00\x005\x1dd\xd0\x00\x00\x00\x0062?\xd0\x00\x00\x00\x006\xfdF\xd0\x00\x00\x00\x008\x1b\\P\x00\x00\x00\x008\xdd(" +
+	"\xd0\x00\x00\x00\x009\xfb>P\x00\x00\x00\x00:\xbd\n\xd0\x00\x00\x00\x00;\xdb P\x00\x00\x00\x00<\xa6'P\x00\x00\x00\x00=\xbb\x02P\x00\x00\x00\x00>\x86\tP\x00\x00\x00\x00?\x9a\xe4P\x00\x00\x00" +
+	"\x00@e\xebP\x00\x00\x00\x00A\x84\x00\xd0\x00\x00\x00\x00\\\x1bؠ\x01\x02\x03\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x02\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x02\x00\x00=`\x00\x00\x00\x008@\x00\x04\x00\x00FP\x00\b\x00\x00T`\x01\f\x00\x00T`\x00\f\x00\x00FP\x01\bLMT\x00+04\x00+05" +
+	"\x00+06\x00\n<+05>-5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ʇ{_\xbb\x00\x00\x00\xbb\x00\x00\x00\f\x00\x00\x00Asia/RangoonTZif" +
+	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xffV\xb6\x89\xd1\xff\xff\xff\xff\xa1\xf2sQ\xff\xff\xff\xff\xcb\xf2\xfc\x18\xff\xff\xff\xff\xd1" +
+	"\x9ag\xf0\x01\x02\x03\x02\x00\x00Z/\x00\x00\x00\x00Z/\x00\x04\x00\x00[h\x00\b\x00\x00~\x90\x00\x0eLMT\x00RMT\x00+0630\x00+09\x00\n<+0630>-6:" +
+	"30\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcfׇ\xe1\x85\x00\x00\x00\x85\x00\x00\x00\v\x00\x00\x00Asia/RiyadhTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xd5\x1b6\xb4\x01\x00\x00+\xcc\x00\x00\x00\x00*0\x00\x04LMT\x00+03\x00\n<+03>-3\nPK\x03" +
+	"\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000I\xc7\xde\xec\x00\x00\x00\xec\x00\x00\x00\v\x00\x00\x00Asia/SaigonTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
 	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00G\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\x85i[\x8e\xff\xff\xff\xff\xcbGu\xf0\xff\xff\xff\xff\xcb\xf2\xca\xe0\xff\xff\xff\xff\xcc\xfb\xbaP\xff\xff\xff\xff\xcd\xd3\xfe`\xff\xff\xff\xffΝ\xa5" +
-	"\xd0\xff\xff\xff\xff\xd2azp\xff\xff\xff\xff\xd3x\xf8p\xff\xff\xff\xff\xd4B\xad\xf0\xff\xff\xff\xff\xd5K\xabp\xff\xff\xff\xff\xd6tL\xf0\xff\xff\xff\xff\xd7?S\xf0\xff\xff\xff\xff\xd8/D\xf0\xff\xff\xff" +
-	"\xff\xd8\xf8\xfap\xff\xff\xff\xff\xda\r\xd5p\xff\xff\xff\xff\xda\xd8\xdcp\xff\xff\xff\xff\xdb\xed\xb7p\xff\xff\xff\xffܸ\xbep\xff\xff\xff\xff\xdd\xce\xea\xf0\xff\xff\xff\xffޡ\xda\xf0\xff\xff\xff\xff߶\xb5" +
-	"\xf0\xff\xff\xff\xff\xe0\x81\xbc\xf0\xff\xff\xff\xffᖗ\xf0\xff\xff\xff\xff\xe2O)\xf0\xff\xff\xff\xff\xe3vy\xf0\xff\xff\xff\xff\xe4/\v\xf0\xff\xff\xff\xff\xe5_\x96p\xff\xff\xff\xff\xe6\x0e\xed\xf0\xff\xff\xff" +
-	"\xff\xe7?\xa9\xa8\xff\xff\xff\xff\xe7\xf8I\xb8\xff\xff\xff\xff\xe9\x1f\x8b\xa8\xff\xff\xff\xff\xe9\xd8+\xb8\xff\xff\xff\xff\xea\xffm\xa8\xff\xff\xff\xff\xeb\xb8\r\xb8\xff\xff\xff\xff\xec\xdfO\xa8\xff\xff\xff\xff\xed\x97\xef" +
-	"\xb8\xff\xff\xff\xff\xee\xc8l(\xff\xff\xff\xff\xefwѸ\xff\xff\xff\xff\xf0\xa8N(\xff\xff\xff\xff\xf1W\xb3\xb8\xff\xff\xff\xff\xf2\x880(\xff\xff\xff\xff\xf3@\xd08\xff\xff\xff\xff\xf4h\x12(\xff\xff\xff" +
-	"\xff\xf5 \xb28\xff\xff\xff\xff\xf6G\xf4(\xff\xff\xff\xff\xf7%~8\xff\xff\xff\xff\xf8\x15S\x18\xff\xff\xff\xff\xf9\x05`8\xff\xff\xff\xff\xf9\xf55\x18\xff\xff\xff\xff\xfa\xe5B8\xff\xff\xff\xff\xfb\xde_" +
-	"\xa8\xff\xff\xff\xff\xfc\xce^\xb8\xff\xff\xff\xff\xfd\xbeA\xa8\xff\xff\xff\xff\xfe\xae@\xb8\xff\xff\xff\xff\xff\x9e#\xa8\x00\x00\x00\x00\x00\x8e\"\xb8\x00\x00\x00\x00\x01~\x05\xa8\x00\x00\x00\x00\x02n\x04\xb8\x00\x00\x00" +
-	"\x00\x03]\xe7\xa8\x00\x00\x00\x00\x04M\xe6\xb8\x00\x00\x00\x00\x05G\x04(\x00\x00\x00\x00\x067\x038\x00\x00\x00\x00\a&\xe6(\x00\x00\x00\x00\a\x83=8\x00\x00\x00\x00\t\x06\xc8(\x00\x00\x00\x00\t\xf6\xc7" +
-	"8\x00\x00\x00\x00\n\xe6\xaa(\x00\x00\x00\x00\v֩8\x00\x00\x00\x00\fƌ(\x00\x00\x00\x00\x11\x9b98\x00\x00\x00\x00\x12ol\xa8\x01\x03\x02\x03\x02\x03\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01" +
-	"\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x00\x00jr\x00\x00\x00\x00" +
-	"p\x80\x00\x04\x00\x00\x8c\xa0\x01\b\x00\x00~\x90\x00\f\x00\x00~\x90\x01\x10LMT\x00CST\x00+10\x00+09\x00CDT\x00\nCST-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8f" +
-	"j\xbeT\xd5ΜGp\x02\x00\x00p\x02\x00\x00\x0e\x00\x1c\x00Asia/QyzylordaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01" +
-	"\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x004\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x86\xa0\xff\xff\xff\xff\xb5\xa3\xfd@\x00\x00\x00\x00\x15'\x8b\xb0" +
-	"\x00\x00\x00\x00\x16\x18\xc0 \x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00" +
-	"\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L\x1b\xd0\x00\x00\x00\x00#<\f\xd0" +
-	"\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\v\xdf\xd0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\x95P\x00\x00\x00\x00" +
-	")\xd4\xd0@\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xc0P\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xa2P\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x84P\x00\x00\x00\x000duP" +
-	"\x00\x00\x00\x001]\xa0\xd0\x00\x00\x00\x002r{\xd0\x00\x00\x00\x003=\x82\xd0\x00\x00\x00\x004R]\xd0\x00\x00\x00\x005\x1dd\xd0\x00\x00\x00\x0062?\xd0\x00\x00\x00\x006\xfdF\xd0\x00\x00\x00\x00" +
-	"8\x1b\\P\x00\x00\x00\x008\xdd(\xd0\x00\x00\x00\x009\xfb>P\x00\x00\x00\x00:\xbd\n\xd0\x00\x00\x00\x00;\xdb P\x00\x00\x00\x00<\xa6'P\x00\x00\x00\x00=\xbb\x02P\x00\x00\x00\x00>\x86\tP" +
-	"\x00\x00\x00\x00?\x9a\xe4P\x00\x00\x00\x00@e\xebP\x00\x00\x00\x00A\x84\x00\xd0\x00\x00\x00\x00\\\x1bؠ\x01\x02\x03\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x02\x04\x03\x02\x03" +
-	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x02\x00\x00=`\x00\x00\x00\x008@\x00\x04\x00\x00FP\x00\b\x00\x00T`\x01\f\x00\x00T`\x00\f\x00\x00FP\x01\b" +
-	"LMT\x00+04\x00+05\x00+06\x00\n<+05>-5\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\x1d?v\f\x17\x03\x00\x00\x17\x03\x00\x00\n\x00\x1c\x00Asia/" +
-	"MacaoUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00G" +
-	"\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\x85i[\x8e\xff\xff\xff\xff\xcbGu\xf0\xff\xff\xff\xff\xcb\xf2\xca\xe0\xff\xff\xff\xff\xcc\xfb\xbaP\xff\xff\xff\xff\xcd\xd3\xfe`\xff\xff\xff\xffΝ\xa5\xd0\xff\xff\xff\xff" +
-	"\xd2azp\xff\xff\xff\xff\xd3x\xf8p\xff\xff\xff\xff\xd4B\xad\xf0\xff\xff\xff\xff\xd5K\xabp\xff\xff\xff\xff\xd6tL\xf0\xff\xff\xff\xff\xd7?S\xf0\xff\xff\xff\xff\xd8/D\xf0\xff\xff\xff\xff\xd8\xf8\xfap" +
-	"\xff\xff\xff\xff\xda\r\xd5p\xff\xff\xff\xff\xda\xd8\xdcp\xff\xff\xff\xff\xdb\xed\xb7p\xff\xff\xff\xffܸ\xbep\xff\xff\xff\xff\xdd\xce\xea\xf0\xff\xff\xff\xffޡ\xda\xf0\xff\xff\xff\xff߶\xb5\xf0\xff\xff\xff\xff" +
-	"\xe0\x81\xbc\xf0\xff\xff\xff\xffᖗ\xf0\xff\xff\xff\xff\xe2O)\xf0\xff\xff\xff\xff\xe3vy\xf0\xff\xff\xff\xff\xe4/\v\xf0\xff\xff\xff\xff\xe5_\x96p\xff\xff\xff\xff\xe6\x0e\xed\xf0\xff\xff\xff\xff\xe7?\xa9\xa8" +
-	"\xff\xff\xff\xff\xe7\xf8I\xb8\xff\xff\xff\xff\xe9\x1f\x8b\xa8\xff\xff\xff\xff\xe9\xd8+\xb8\xff\xff\xff\xff\xea\xffm\xa8\xff\xff\xff\xff\xeb\xb8\r\xb8\xff\xff\xff\xff\xec\xdfO\xa8\xff\xff\xff\xff\xed\x97\xef\xb8\xff\xff\xff\xff" +
-	"\xee\xc8l(\xff\xff\xff\xff\xefwѸ\xff\xff\xff\xff\xf0\xa8N(\xff\xff\xff\xff\xf1W\xb3\xb8\xff\xff\xff\xff\xf2\x880(\xff\xff\xff\xff\xf3@\xd08\xff\xff\xff\xff\xf4h\x12(\xff\xff\xff\xff\xf5 \xb28" +
-	"\xff\xff\xff\xff\xf6G\xf4(\xff\xff\xff\xff\xf7%~8\xff\xff\xff\xff\xf8\x15S\x18\xff\xff\xff\xff\xf9\x05`8\xff\xff\xff\xff\xf9\xf55\x18\xff\xff\xff\xff\xfa\xe5B8\xff\xff\xff\xff\xfb\xde_\xa8\xff\xff\xff\xff" +
-	"\xfc\xce^\xb8\xff\xff\xff\xff\xfd\xbeA\xa8\xff\xff\xff\xff\xfe\xae@\xb8\xff\xff\xff\xff\xff\x9e#\xa8\x00\x00\x00\x00\x00\x8e\"\xb8\x00\x00\x00\x00\x01~\x05\xa8\x00\x00\x00\x00\x02n\x04\xb8\x00\x00\x00\x00\x03]\xe7\xa8" +
-	"\x00\x00\x00\x00\x04M\xe6\xb8\x00\x00\x00\x00\x05G\x04(\x00\x00\x00\x00\x067\x038\x00\x00\x00\x00\a&\xe6(\x00\x00\x00\x00\a\x83=8\x00\x00\x00\x00\t\x06\xc8(\x00\x00\x00\x00\t\xf6\xc78\x00\x00\x00\x00" +
-	"\n\xe6\xaa(\x00\x00\x00\x00\v֩8\x00\x00\x00\x00\fƌ(\x00\x00\x00\x00\x11\x9b98\x00\x00\x00\x00\x12ol\xa8\x01\x03\x02\x03\x02\x03\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04" +
-	"\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x00\x00jr\x00\x00\x00\x00p\x80\x00\x04\x00" +
-	"\x00\x8c\xa0\x01\b\x00\x00~\x90\x00\f\x00\x00~\x90\x01\x10LMT\x00CST\x00+10\x00+09\x00CDT\x00\nCST-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x02\xf4" +
-	"\xaeg\xd5\x00\x00\x00\xd5\x00\x00\x00\n\x00\x1c\x00Asia/TokyoUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xffe¤p\xff\xff\xff\xff\xd7>\x02p\xff\xff\xff\xff\xd7\xedY\xf0\xff\xff\xff\xff\xd8\xf8\xfap\xff" +
-	"\xff\xff\xff\xd9\xcd;\xf0\xff\xff\xff\xff\xdb\a\x00\xf0\xff\xff\xff\xffۭ\x1d\xf0\xff\xff\xff\xff\xdc\xe6\xe2\xf0\xff\xff\xff\xff\u074c\xff\xf0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x83\x03\x00\x00\x00\x00\x8c\xa0\x01\x04" +
-	"\x00\x00~\x90\x00\bLMT\x00JDT\x00JST\x00\nJST-9\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\x03\x87\xb3<\xe8\x02\x00\x00\xe8\x02\x00\x00\t\x00\x1c\x00Asia/" +
-	"BakuUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x00" +
-	"\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x95D\xff\xff\xff\xff\xe7\xda\fP\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\b\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18" +
-	"\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a̅\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00" +
-	"\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\8\xe0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<\x1a\xe0\x00\x00\x00\x00$,\v\xe0\x00\x00\x00\x00%\x1b\xfc\xe0\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00'" +
-	"\x05\x19`\x00\x00\x00\x00'\xf5\n`\x00\x00\x00\x00(\xe5\tp\x00\x00\x00\x00)\xd4\xfap\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x001]\xd9\x10\x00\x00\x00\x002r\xb4\x10\x00\x00\x00\x003=\xad\x00\x00" +
-	"\x00\x00\x004R\x88\x00\x00\x00\x00\x005\x1d\x8f\x00\x00\x00\x00\x0062j\x00\x00\x00\x00\x006\xfdq\x00\x00\x00\x00\x008\x1b\x86\x80\x00\x00\x00\x008\xddS\x00\x00\x00\x00\x009\xfbh\x80\x00\x00\x00\x00:" +
-	"\xbd5\x00\x00\x00\x00\x00;\xdbJ\x80\x00\x00\x00\x00<\xa6Q\x80\x00\x00\x00\x00=\xbb,\x80\x00\x00\x00\x00>\x863\x80\x00\x00\x00\x00?\x9b\x0e\x80\x00\x00\x00\x00@f\x15\x80\x00\x00\x00\x00A\x84+\x00\x00" +
-	"\x00\x00\x00BE\xf7\x80\x00\x00\x00\x00Cd\r\x00\x00\x00\x00\x00D%ـ\x00\x00\x00\x00EC\xef\x00\x00\x00\x00\x00F\x05\xbb\x80\x00\x00\x00\x00G#\xd1\x00\x00\x00\x00\x00G\xee\xd8\x00\x00\x00\x00\x00I" +
-	"\x03\xb3\x00\x00\x00\x00\x00Iκ\x00\x00\x00\x00\x00J\xe3\x95\x00\x00\x00\x00\x00K\xae\x9c\x00\x00\x00\x00\x00Ḻ\x80\x00\x00\x00\x00M\x8e~\x00\x00\x00\x00\x00N\xac\x93\x80\x00\x00\x00\x00On`\x00\x00" +
-	"\x00\x00\x00P\x8cu\x80\x00\x00\x00\x00QW|\x80\x00\x00\x00\x00RlW\x80\x00\x00\x00\x00S7^\x80\x00\x00\x00\x00TL9\x80\x00\x00\x00\x00U\x17@\x80\x00\x00\x00\x00V,\x1b\x80\x01\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x00\x00.\xbc\x00\x00\x00\x00*0\x00\x04\x00\x00FP\x01\b\x00\x008@\x00\f\x00\x008@\x01\fLMT\x00+03\x00+05\x00+04\x00\n<+04>-4\nPK\x03\x04" +
-	"\n\x00\x00\x00\x00\x00\x8fj\xbeT\x87\xbd\xedL\xf1\x02\x00\x00\xf1\x02\x00\x00\f\x00\x1c\x00Asia/BarnaulUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b" +
-	"\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZi" +
-	"f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00C\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xd5}\xfc\xff\xff\xff\xff\xb5\xa3\xe1 \x00\x00\x00" +
-	"\x00\x15'o\x90\x00\x00\x00\x00\x16\x18\xa4\x00\x00\x00\x00\x00\x17\b\xa3\x10\x00\x00\x00\x00\x17\xf9׀\x00\x00\x00\x00\x18\xe9\u0590\x00\x00\x00\x00\x19\xdb\v\x00\x00\x00\x00\x00\x1a\xcc[\x90\x00\x00\x00\x00\x1b\xbch" +
-	"\xb0\x00\x00\x00\x00\x1c\xacY\xb0\x00\x00\x00\x00\x1d\x9cJ\xb0\x00\x00\x00\x00\x1e\x8c;\xb0\x00\x00\x00\x00\x1f|,\xb0\x00\x00\x00\x00 l\x1d\xb0\x00\x00\x00\x00!\\\x0e\xb0\x00\x00\x00\x00\"K\xff\xb0\x00\x00\x00" +
-	"\x00#;\xf0\xb0\x00\x00\x00\x00$+\xe1\xb0\x00\x00\x00\x00%\x1bҰ\x00\x00\x00\x00&\vð\x00\x00\x00\x00'\x04\xef0\x00\x00\x00\x00'\xf4\xe00\x00\x00\x00\x00(\xe4\xdf@\x00\x00\x00\x00)x\x87" +
-	"@\x00\x00\x00\x00)\xd4\xc20\x00\x00\x00\x00*ij0\x00\x00\x00\x00+\xb4\xa40\x00\x00\x00\x00,\xa4\x950\x00\x00\x00\x00-\x94\x860\x00\x00\x00\x00.\x84w0\x00\x00\x00\x00/th0\x00\x00\x00" +
-	"\x00/\xc7L\x80\x00\x00\x00\x000dg@\x00\x00\x00\x001]\x92\xc0\x00\x00\x00\x002rm\xc0\x00\x00\x00\x003=t\xc0\x00\x00\x00\x004RO\xc0\x00\x00\x00\x005\x1dV\xc0\x00\x00\x00\x00621" +
-	"\xc0\x00\x00\x00\x006\xfd8\xc0\x00\x00\x00\x008\x1bN@\x00\x00\x00\x008\xdd\x1a\xc0\x00\x00\x00\x009\xfb0@\x00\x00\x00\x00:\xbc\xfc\xc0\x00\x00\x00\x00;\xdb\x12@\x00\x00\x00\x00<\xa6\x19@\x00\x00\x00" +
-	"\x00=\xba\xf4@\x00\x00\x00\x00>\x85\xfb@\x00\x00\x00\x00?\x9a\xd6@\x00\x00\x00\x00@e\xdd@\x00\x00\x00\x00A\x83\xf2\xc0\x00\x00\x00\x00BE\xbf@\x00\x00\x00\x00Cc\xd4\xc0\x00\x00\x00\x00D%\xa1" +
-	"@\x00\x00\x00\x00EC\xb6\xc0\x00\x00\x00\x00F\x05\x83@\x00\x00\x00\x00G#\x98\xc0\x00\x00\x00\x00G\xee\x9f\xc0\x00\x00\x00\x00I\x03z\xc0\x00\x00\x00\x00I\u0381\xc0\x00\x00\x00\x00J\xe3\\\xc0\x00\x00\x00" +
-	"\x00K\xaec\xc0\x00\x00\x00\x00L\xccy@\x00\x00\x00\x00M\x8eE\xc0\x00\x00\x00\x00TK\xf30\x00\x00\x00\x00V\xf6\xea@\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04" +
-	"\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x03\x01\x03\x00\x00N\x84\x00\x00\x00\x00T`\x00\x04\x00\x00p\x80" +
-	"\x01\b\x00\x00bp\x00\f\x00\x00bp\x01\fLMT\x00+06\x00+08\x00+07\x00\n<+07>-7\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\aW\x10Ѱ\x04\x00" +
-	"\x00\xb0\x04\x00\x00\r\x00\x1c\x00Asia/IstanbulUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00s\x00\x00\x00\x06\x00\x00\x00\x19\xff\xff\xff\xffV\xb6\xc8\xd8\xff\xff\xff\xff\x90\x8b\xf5\x98\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9bվ\xd0\xff\xff\xff" +
-	"\xff\xa2ec\xe0\xff\xff\xff\xff\xa3{\x82P\xff\xff\xff\xff\xa4N\x80`\xff\xff\xff\xff\xa5?\xb4\xd0\xff\xff\xff\xff\xa6%'\xe0\xff\xff\xff\xff\xa7'\x7f\xd0\xff\xff\xff\xff\xaa((`\xff\xff\xff\xff\xaa\xe1\xfd" +
-	"\xd0\xff\xff\xff\xff\xab\xf9\x89\xe0\xff\xff\xff\xff\xac\xc31P\xff\xff\xff\xffȁ?\xe0\xff\xff\xff\xff\xc9\x01\x13P\xff\xff\xff\xff\xc9J\xf5`\xff\xff\xff\xff\xca\u0380P\xff\xff\xff\xff\xcbˮ`\xff\xff\xff" +
-	"\xff\xd2k\tP\xff\xff\xff\xffӢ9`\xff\xff\xff\xff\xd4C\x02P\xff\xff\xff\xff\xd5L\r\xe0\xff\xff\xff\xff\xd6){\xd0\xff\xff\xff\xff\xd7+\xef\xe0\xff\xff\xff\xff\xd8\t]\xd0\xff\xff\xff\xff\xd9\x02\x97" +
-	"`\xff\xff\xff\xff\xd9\xe9?\xd0\xff\xff\xff\xff\xda\xeb\xb3\xe0\xff\xff\xff\xff\xdb\xd2\\P\xff\xff\xff\xff\xdc\xd4\xd0`\xff\xff\xff\xffݲ>P\xff\xff\xff\xff\xf1\xf4\xb9`\xff\xff\xff\xff\xf4b\xefP\xff\xff\xff" +
-	"\xff\xf5h\x06`\xff\xff\xff\xff\xf6\x1f8\xd0\x00\x00\x00\x00\x06n\x93p\x00\x00\x00\x00\a9\x9ap\x00\x00\x00\x00\a\xfbu\x00\x00\x00\x00\x00\t\x19|p\x00\x00\x00\x00\t\xd0\xcb\x00\x00\x00\x00\x00\n\xf9^" +
-	"p\x00\x00\x00\x00\v\xb1\xfe\x80\x00\x00\x00\x00\f\xd9@p\x00\x00\x00\x00\r\xa4U\x80\x00\x00\x00\x00\x0e\xa6\xadp\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00\x0f\xf8\x11P\x00\x00\x00\x00\x19\x89\xb0p\x00\x00\x00" +
-	"\x00\x19ܰ\xe0\x00\x00\x00\x00\x1b\xe6\xd0\xf0\x00\x00\x00\x00\x1c\xc6\xef\xf0\x00\x00\x00\x00\x1d\x9b1p\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F" +
-	"\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00" +
-	"\x00(\xe5\tp\x00\x00\x00\x00)\xd4\xfap\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x8b\x83\xf0\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0" +
-	"p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00" +
-	"\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb<p\x00\x00\x00\x00<\xa6Cp\x00\x00\x00\x00=\xbb\x1e" +
-	"p\x00\x00\x00\x00>\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f\ap\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00" +
-	"\x00EC\xe0\xf0\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa" +
-	"\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8fݐ\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00" +
-	"\x00S8\xbe\x10\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V>\x9e\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00W\xcf.P\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
-	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x00\x00\x1b(\x00\x00\x00\x00\x1bh\x00\x04\x00\x00*0\x01\b\x00\x00" +
-	"\x1c \x00\r\x00\x00*0\x00\x11\x00\x008@\x01\x15LMT\x00IMT\x00EEST\x00EET\x00+03\x00+04\x00\n<+03>-3\nPK\x03\x04\n\x00\x00\x00\x00\x00" +
-	"\x8fj\xbeT\xf9l\x03\x12\xf8\x02\x00\x00\xf8\x02\x00\x00\f\x00\x1c\x00Asia/IrkutskUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00" +
-	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x00\x00\x00\a\x00\x00\x00\x14\xff\xff\xff\xffV\xb6\x82?\xff\xff\xff\xff\xa2\x12\x0f\xbf\xff\xff\xff\xff\xb5\xa3\xd3\x10\x00" +
-	"\x00\x00\x00\x15'a\x80\x00\x00\x00\x00\x16\x18\x95\xf0\x00\x00\x00\x00\x17\b\x95\x00\x00\x00\x00\x00\x17\xf9\xc9p\x00\x00\x00\x00\x18\xe9Ȁ\x00\x00\x00\x00\x19\xda\xfc\xf0\x00\x00\x00\x00\x1a\xccM\x80\x00\x00\x00\x00\x1b" +
-	"\xbcZ\xa0\x00\x00\x00\x00\x1c\xacK\xa0\x00\x00\x00\x00\x1d\x9c<\xa0\x00\x00\x00\x00\x1e\x8c-\xa0\x00\x00\x00\x00\x1f|\x1e\xa0\x00\x00\x00\x00 l\x0f\xa0\x00\x00\x00\x00!\\\x00\xa0\x00\x00\x00\x00\"K\xf1\xa0\x00" +
-	"\x00\x00\x00#;\xe2\xa0\x00\x00\x00\x00$+Ӡ\x00\x00\x00\x00%\x1bĠ\x00\x00\x00\x00&\v\xb5\xa0\x00\x00\x00\x00'\x04\xe1 \x00\x00\x00\x00'\xf4\xd2 \x00\x00\x00\x00(\xe4\xd10\x00\x00\x00\x00)" +
-	"xy0\x00\x00\x00\x00)Դ \x00\x00\x00\x00*ĥ \x00\x00\x00\x00+\xb4\x96 \x00\x00\x00\x00,\xa4\x87 \x00\x00\x00\x00-\x94x \x00\x00\x00\x00.\x84i \x00\x00\x00\x00/tZ \x00" +
-	"\x00\x00\x000dK \x00\x00\x00\x001]v\xa0\x00\x00\x00\x002rQ\xa0\x00\x00\x00\x003=X\xa0\x00\x00\x00\x004R3\xa0\x00\x00\x00\x005\x1d:\xa0\x00\x00\x00\x0062\x15\xa0\x00\x00\x00\x006" +
-	"\xfd\x1c\xa0\x00\x00\x00\x008\x1b2 \x00\x00\x00\x008\xdc\xfe\xa0\x00\x00\x00\x009\xfb\x14 \x00\x00\x00\x00:\xbc\xe0\xa0\x00\x00\x00\x00;\xda\xf6 \x00\x00\x00\x00<\xa5\xfd \x00\x00\x00\x00=\xba\xd8 \x00" +
-	"\x00\x00\x00>\x85\xdf \x00\x00\x00\x00?\x9a\xba \x00\x00\x00\x00@e\xc1 \x00\x00\x00\x00A\x83֠\x00\x00\x00\x00BE\xa3 \x00\x00\x00\x00Cc\xb8\xa0\x00\x00\x00\x00D%\x85 \x00\x00\x00\x00E" +
-	"C\x9a\xa0\x00\x00\x00\x00F\x05g \x00\x00\x00\x00G#|\xa0\x00\x00\x00\x00G\ue0e0\x00\x00\x00\x00I\x03^\xa0\x00\x00\x00\x00I\xcee\xa0\x00\x00\x00\x00J\xe3@\xa0\x00\x00\x00\x00K\xaeG\xa0\x00" +
-	"\x00\x00\x00L\xcc] \x00\x00\x00\x00M\x8e)\xa0\x00\x00\x00\x00TK\xd7\x10\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x05\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" +
-	"\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x06\x04\x00\x00a\xc1\x00\x00\x00\x00a\xc1\x00\x04\x00\x00bp\x00\b\x00\x00~\x90\x01\f\x00\x00p\x80\x00\x10\x00" +
-	"\x00p\x80\x01\x10\x00\x00~\x90\x00\fLMT\x00IMT\x00+07\x00+09\x00+08\x00\n<+08>-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xdav\x19z\x98\x00" +
-	"\x00\x00\x98\x00\x00\x00\n\x00\x1c\x00Asia/QatarUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\xa1\xf2\x9d0\x00\x00\x00\x00\x04\x8a\x92\xc0\x01\x02\x00\x000P\x00\x00\x00\x008@\x00\x04\x00\x00*0\x00\bL" +
-	"MT\x00+04\x00+03\x00\n<+03>-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xdav\x19z\x98\x00\x00\x00\x98\x00\x00\x00\f\x00\x1c\x00Asia/Bahra" +
-	"inUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00" +
-	"\x03\x00\x00\x00\f\xff\xff\xff\xff\xa1\xf2\x9d0\x00\x00\x00\x00\x04\x8a\x92\xc0\x01\x02\x00\x000P\x00\x00\x00\x008@\x00\x04\x00\x00*0\x00\bLMT\x00+04\x00+03\x00\n<+03>-" +
-	"3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeTʇ{_\xbb\x00\x00\x00\xbb\x00\x00\x00\v\x00\x1c\x00Asia/YangonUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00" +
-	"\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00" +
-	"\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xffV\xb6\x89\xd1\xff\xff\xff\xff\xa1\xf2" +
-	"sQ\xff\xff\xff\xff\xcb\xf2\xfc\x18\xff\xff\xff\xffњg\xf0\x01\x02\x03\x02\x00\x00Z/\x00\x00\x00\x00Z/\x00\x04\x00\x00[h\x00\b\x00\x00~\x90\x00\x0eLMT\x00RMT\x00+0630\x00" +
-	"+09\x00\n<+0630>-6:30\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\x02\x95-\xad\xc4\x02\x00\x00\xc4\x02\x00\x00\f\x00\x1c\x00Asia/Yerevan" +
-	"UT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x00\x00\x00\x05\x00" +
-	"\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x9aH\xff\xff\xff\xff\xe7\xda\fP\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\b\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00" +
-	"\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a̅\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 " +
-	"lG\xe0\x00\x00\x00\x00!\\8\xe0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<\x1a\xe0\x00\x00\x00\x00$,\v\xe0\x00\x00\x00\x00%\x1b\xfc\xe0\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00'\x05\x19`\x00" +
-	"\x00\x00\x00'\xf5\n`\x00\x00\x00\x00(\xe5\tp\x00\x00\x00\x00)\xd4\xfap\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x94\xbep\x00\x00\x00\x00." +
-	"\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x003=\x90\xe0\x00\x00\x00\x004Rk\xe0\x00\x00\x00\x005\x1dr\xe0\x00\x00\x00\x0062M\xe0\x00\x00\x00\x006\xfdT\xe0\x00" +
-	"\x00\x00\x008\x1bj`\x00\x00\x00\x008\xdd6\xe0\x00\x00\x00\x009\xfbL`\x00\x00\x00\x00:\xbd\x18\xe0\x00\x00\x00\x00;\xdb.`\x00\x00\x00\x00<\xa65`\x00\x00\x00\x00=\xbb\x10`\x00\x00\x00\x00>" +
-	"\x86\x17`\x00\x00\x00\x00?\x9a\xf2`\x00\x00\x00\x00@e\xf9`\x00\x00\x00\x00A\x84\x0e\xe0\x00\x00\x00\x00BE\xdb`\x00\x00\x00\x00Cc\xf0\xe0\x00\x00\x00\x00D%\xbd`\x00\x00\x00\x00EC\xd2\xe0\x00" +
-	"\x00\x00\x00F\x05\x9f`\x00\x00\x00\x00G#\xb4\xe0\x00\x00\x00\x00G\xee\xbb\xe0\x00\x00\x00\x00I\x03\x96\xe0\x00\x00\x00\x00IΝ\xe0\x00\x00\x00\x00J\xe3x\xe0\x00\x00\x00\x00K\xae\x7f\xe0\x00\x00\x00\x00L" +
-	"̕`\x00\x00\x00\x00M\x8ea\xe0\x00\x00\x00\x00N\xacw`\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x04\x01\x04\x01\x04\x01\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00)\xb8\x00\x00\x00\x00*0\x00\x04\x00\x00FP\x01\b\x00\x008@\x00\f\x00\x008@\x01\fLMT\x00+03\x00+" +
-	"05\x00+04\x00\n<+04>-4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTS\xdd\\2a\x02\x00\x00a\x02\x00\x00\v\x00\x1c\x00Asia/AlmatyUT\t" +
-	"\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\x00\x00\x00\x05\x00\x00\x00\x10" +
-	"\xff\xff\xff\xff\xaa\x19{\xdc\xff\xff\xff\xff\xb5\xa3\xef0\x00\x00\x00\x00\x15'}\xa0\x00\x00\x00\x00\x16\x18\xb2\x10\x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xe5\x90\x00\x00\x00\x00\x18\xe9\xe4\xa0\x00\x00\x00\x00" +
-	"\x19\xdb\x19\x10\x00\x00\x00\x00\x1a\xcci\xa0\x00\x00\x00\x00\x1b\xbcv\xc0\x00\x00\x00\x00\x1c\xacg\xc0\x00\x00\x00\x00\x1d\x9cX\xc0\x00\x00\x00\x00\x1e\x8cI\xc0\x00\x00\x00\x00\x1f|:\xc0\x00\x00\x00\x00 l+\xc0" +
-	"\x00\x00\x00\x00!\\\x1c\xc0\x00\x00\x00\x00\"L\r\xc0\x00\x00\x00\x00#;\xfe\xc0\x00\x00\x00\x00$+\xef\xc0\x00\x00\x00\x00%\x1b\xe0\xc0\x00\x00\x00\x00&\v\xd1\xc0\x00\x00\x00\x00'\x04\xfd@\x00\x00\x00\x00" +
-	"'\xf4\xee@\x00\x00\x00\x00(\xe4\xedP\x00\x00\x00\x00)x\x95P\x00\x00\x00\x00)\xd4\xd0@\x00\x00\x00\x00*\xc4\xc1@\x00\x00\x00\x00+\xb4\xb2@\x00\x00\x00\x00,\xa4\xa3@\x00\x00\x00\x00-\x94\x94@" +
-	"\x00\x00\x00\x00.\x84\x85@\x00\x00\x00\x00/tv@\x00\x00\x00\x000dg@\x00\x00\x00\x001]\x92\xc0\x00\x00\x00\x002rm\xc0\x00\x00\x00\x003=t\xc0\x00\x00\x00\x004RO\xc0\x00\x00\x00\x00" +
-	"5\x1dV\xc0\x00\x00\x00\x00621\xc0\x00\x00\x00\x006\xfd8\xc0\x00\x00\x00\x008\x1bN@\x00\x00\x00\x008\xdd\x1a\xc0\x00\x00\x00\x009\xfb0@\x00\x00\x00\x00:\xbc\xfc\xc0\x00\x00\x00\x00;\xdb\x12@" +
-	"\x00\x00\x00\x00<\xa6\x19@\x00\x00\x00\x00=\xba\xf4@\x00\x00\x00\x00>\x85\xfb@\x00\x00\x00\x00?\x9a\xd6@\x00\x00\x00\x00@e\xdd@\x00\x00\x00\x00A\x83\xf2\xc0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
-	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00H$\x00\x00\x00\x00FP\x00\x04\x00\x00bp\x01\b\x00\x00T" +
-	"`\x00\f\x00\x00T`\x01\fLMT\x00+05\x00+07\x00+06\x00\n<+06>-6\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTΒ\x1a\x8c\xaa\x00\x00\x00\xaa\x00\x00\x00" +
-	"\t\x00\x1c\x00Asia/DiliUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x92\xe6\x18\xc4\xff\xff\xff\xff˙2\xf0\x00\x00\x00\x00\v\xea0p\x00\x00\x00\x009Ù\x00\x01\x02\x01\x02\x00\x00u\xbc\x00\x00\x00\x00" +
-	"p\x80\x00\x04\x00\x00~\x90\x00\bLMT\x00+08\x00+09\x00\n<+09>-9\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT?Y\xaf\x19\xe7\x00\x00\x00\xe7\x00\x00\x00\n\x00\x1c" +
-	"\x00Asia/DaccaUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\a\x00\x00\x00\x06\x00\x00\x00\x1c\xff\xff\xff\xffi\x86\x86\xbc\xff\xff\xff\xff\xcaۆ\xb0\xff\xff\xff\xff\xcc\x05q\x18\xff\xff\xff\xff̕2\xa8\xff\xff\xff\xffݨҘ\x00\x00\x00\x00J;" +
-	"\xc4\x10\x00\x00\x00\x00K<ؐ\x01\x02\x03\x02\x04\x05\x04\x00\x00T\xc4\x00\x00\x00\x00R\xd0\x00\x04\x00\x00[h\x00\b\x00\x00MX\x00\x0e\x00\x00T`\x00\x14\x00\x00bp\x01\x18LMT\x00HMT" +
-	"\x00+0630\x00+0530\x00+06\x00+07\x00\n<+06>-6\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00\x00\x0e\x00\x1c\x00" +
-	"Asia/ChongqingUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff~6C)\xff\xff\xff\xff\xa0\x97\xa2\x80\xff\xff\xff\xff\xa1y\x04\xf0\xff\xff\xff\xff\xc8Y^\x80\xff\xff\xff\xff\xc9\t\xf9p\xff\xff\xff" +
-	"\xff\xc9ӽ\x00\xff\xff\xff\xff\xcb\x05\x8a\xf0\xff\xff\xff\xff\xcb|@\x00\xff\xff\xff\xff\xd2;>\xf0\xff\xff\xff\xffӋ{\x80\xff\xff\xff\xff\xd4B\xad\xf0\xff\xff\xff\xff\xd5E\"\x00\xff\xff\xff\xff\xd6L\xbf" +
-	"\xf0\xff\xff\xff\xff\xd7<\xbf\x00\xff\xff\xff\xff\xd8\x06fp\xff\xff\xff\xff\xd9\x1d\xf2\x80\xff\xff\xff\xff\xd9A|\xf0\x00\x00\x00\x00\x1e\xbaR \x00\x00\x00\x00\x1fi\x9b\x90\x00\x00\x00\x00 ~\x84\xa0\x00\x00\x00" +
-	"\x00!I}\x90\x00\x00\x00\x00\"g\xa1 \x00\x00\x00\x00#)_\x90\x00\x00\x00\x00$G\x83 \x00\x00\x00\x00%\x12|\x10\x00\x00\x00\x00&'e \x00\x00\x00\x00&\xf2^\x10\x00\x00\x00\x00(\aG" +
-	" \x00\x00\x00\x00(\xd2@\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00q\xd7\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\bLMT\x00" +
-	"CDT\x00CST\x00\nCST-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTw\x86\x8d^\x03\x03\x00\x00\x03\x03\x00\x00\r\x00\x1c\x00Asia/Ust-NeraUT" +
-	"\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x00\x00\x00\b\x00\x00\x00" +
-	"\x18\xff\xff\xff\xff\xa1\xdbݺ\xff\xff\xff\xff\xb5\xa3\xc5\x00\x00\x00\x00\x00\x15'Sp\x00\x00\x00\x00\x16\x18k\xc0\x00\x00\x00\x00\x17\bj\xd0\x00\x00\x00\x00\x17\xf9\x9f@\x00\x00\x00\x00\x18\xe9\x9eP\x00\x00\x00" +
-	"\x00\x19\xda\xd2\xc0\x00\x00\x00\x00\x1a\xcc#P\x00\x00\x00\x00\x1b\xbc0p\x00\x00\x00\x00\x1c\xac!p\x00\x00\x00\x00\x1d\x9c\x12p\x00\x00\x00\x00\x1e\x8c\x03p\x00\x00\x00\x00\x1f{\xf4p\x00\x00\x00\x00 k\xe5" +
-	"p\x00\x00\x00\x00![\xd6p\x00\x00\x00\x00\"K\xc7p\x00\x00\x00\x00#;\xb8p\x00\x00\x00\x00$+\xa9p\x00\x00\x00\x00%\x1b\x9ap\x00\x00\x00\x00&\v\x8bp\x00\x00\x00\x00'\x04\xb6\xf0\x00\x00\x00" +
-	"\x00'\xf4\xa7\xf0\x00\x00\x00\x00(\xe4\xa7\x00\x00\x00\x00\x00)xO\x00\x00\x00\x00\x00)ԉ\xf0\x00\x00\x00\x00*\xc4z\xf0\x00\x00\x00\x00+\xb4k\xf0\x00\x00\x00\x00,\xa4\\\xf0\x00\x00\x00\x00-\x94M" +
-	"\xf0\x00\x00\x00\x00.\x84>\xf0\x00\x00\x00\x00/t/\xf0\x00\x00\x00\x000d \xf0\x00\x00\x00\x001]Lp\x00\x00\x00\x002r'p\x00\x00\x00\x003=.p\x00\x00\x00\x004R\tp\x00\x00\x00" +
-	"\x005\x1d\x10p\x00\x00\x00\x0061\xebp\x00\x00\x00\x006\xfc\xf2p\x00\x00\x00\x008\x1b\a\xf0\x00\x00\x00\x008\xdc\xd4p\x00\x00\x00\x009\xfa\xe9\xf0\x00\x00\x00\x00:\xbc\xb6p\x00\x00\x00\x00;\xda\xcb" +
-	"\xf0\x00\x00\x00\x00<\xa5\xd2\xf0\x00\x00\x00\x00=\xba\xad\xf0\x00\x00\x00\x00>\x85\xb4\xf0\x00\x00\x00\x00?\x9a\x8f\xf0\x00\x00\x00\x00@e\x96\xf0\x00\x00\x00\x00A\x83\xacp\x00\x00\x00\x00BEx\xf0\x00\x00\x00" +
-	"\x00Cc\x8ep\x00\x00\x00\x00D%Z\xf0\x00\x00\x00\x00ECpp\x00\x00\x00\x00F\x05<\xf0\x00\x00\x00\x00G#Rp\x00\x00\x00\x00G\xeeYp\x00\x00\x00\x00I\x034p\x00\x00\x00\x00I\xce;" +
-	"p\x00\x00\x00\x00J\xe3\x16p\x00\x00\x00\x00K\xae\x1dp\x00\x00\x00\x00L\xcc2\xf0\x00\x00\x00\x00M\x8d\xffp\x00\x00\x00\x00Nm\xf4@\x00\x00\x00\x00TK\xba\xf0\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04" +
-	"\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x05\x06\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\a\x03\x06\x00\x00\x86F\x00" +
-	"\x00\x00\x00p\x80\x00\x04\x00\x00~\x90\x00\b\x00\x00\x9a\xb0\x00\f\x00\x00\xa8\xc0\x01\x10\x00\x00\x9a\xb0\x01\f\x00\x00\x8c\xa0\x00\x14\x00\x00\xa8\xc0\x00\x10LMT\x00+08\x00+09\x00+11\x00+" +
-	"12\x00+10\x00\n<+10>-10\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe4_P\x18\xef\x02\x00\x00\xef\x02\x00\x00\f\x00\x1c\x00Asia/MagadanU" +
-	"T\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x00\x00\x00\x06\x00\x00" +
-	"\x00\x10\xff\xff\xff\xff\xaa\x196\xa0\xff\xff\xff\xff\xb5\xa3\xa8\xe0\x00\x00\x00\x00\x15'7P\x00\x00\x00\x00\x16\x18k\xc0\x00\x00\x00\x00\x17\bj\xd0\x00\x00\x00\x00\x17\xf9\x9f@\x00\x00\x00\x00\x18\xe9\x9eP\x00\x00" +
-	"\x00\x00\x19\xda\xd2\xc0\x00\x00\x00\x00\x1a\xcc#P\x00\x00\x00\x00\x1b\xbc0p\x00\x00\x00\x00\x1c\xac!p\x00\x00\x00\x00\x1d\x9c\x12p\x00\x00\x00\x00\x1e\x8c\x03p\x00\x00\x00\x00\x1f{\xf4p\x00\x00\x00\x00 k" +
-	"\xe5p\x00\x00\x00\x00![\xd6p\x00\x00\x00\x00\"K\xc7p\x00\x00\x00\x00#;\xb8p\x00\x00\x00\x00$+\xa9p\x00\x00\x00\x00%\x1b\x9ap\x00\x00\x00\x00&\v\x8bp\x00\x00\x00\x00'\x04\xb6\xf0\x00\x00" +
-	"\x00\x00'\xf4\xa7\xf0\x00\x00\x00\x00(\xe4\xa7\x00\x00\x00\x00\x00)xO\x00\x00\x00\x00\x00)ԉ\xf0\x00\x00\x00\x00*\xc4z\xf0\x00\x00\x00\x00+\xb4k\xf0\x00\x00\x00\x00,\xa4\\\xf0\x00\x00\x00\x00-\x94" +
-	"M\xf0\x00\x00\x00\x00.\x84>\xf0\x00\x00\x00\x00/t/\xf0\x00\x00\x00\x000d \xf0\x00\x00\x00\x001]Lp\x00\x00\x00\x002r'p\x00\x00\x00\x003=.p\x00\x00\x00\x004R\tp\x00\x00" +
-	"\x00\x005\x1d\x10p\x00\x00\x00\x0061\xebp\x00\x00\x00\x006\xfc\xf2p\x00\x00\x00\x008\x1b\a\xf0\x00\x00\x00\x008\xdc\xd4p\x00\x00\x00\x009\xfa\xe9\xf0\x00\x00\x00\x00:\xbc\xb6p\x00\x00\x00\x00;\xda" +
-	"\xcb\xf0\x00\x00\x00\x00<\xa5\xd2\xf0\x00\x00\x00\x00=\xba\xad\xf0\x00\x00\x00\x00>\x85\xb4\xf0\x00\x00\x00\x00?\x9a\x8f\xf0\x00\x00\x00\x00@e\x96\xf0\x00\x00\x00\x00A\x83\xacp\x00\x00\x00\x00BEx\xf0\x00\x00" +
-	"\x00\x00Cc\x8ep\x00\x00\x00\x00D%Z\xf0\x00\x00\x00\x00ECpp\x00\x00\x00\x00F\x05<\xf0\x00\x00\x00\x00G#Rp\x00\x00\x00\x00G\xeeYp\x00\x00\x00\x00I\x034p\x00\x00\x00\x00I\xce" +
-	";p\x00\x00\x00\x00J\xe3\x16p\x00\x00\x00\x00K\xae\x1dp\x00\x00\x00\x00L\xcc2\xf0\x00\x00\x00\x00M\x8d\xffp\x00\x00\x00\x00TK\xac\xe0\x00\x00\x00\x00W\x1b\x9c\x00\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
-	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x01\x03\x00\x00\x8d`" +
-	"\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00\xa8\xc0\x01\b\x00\x00\x9a\xb0\x00\f\x00\x00\x9a\xb0\x01\f\x00\x00\xa8\xc0\x00\bLMT\x00+10\x00+12\x00+11\x00\n<+11>-11\nPK" +
-	"\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\\\x91\x87\xbb\xf7\x00\x00\x00\xf7\x00\x00\x00\f\x00\x1c\x00Asia/ColomboUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91" +
-	"\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00T" +
-	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\a\x00\x00\x00\x18\xff\xff\xff\xffV\xb6\x99$\xff\xff\xff\xff\x87\x9d\xbd\x1c\xff" +
-	"\xff\xff\xff\xcbZ\x1c(\xff\xff\xff\xff̕+\xa0\xff\xff\xff\xff\xd2u\x808\x00\x00\x00\x001\xa6\x00(\x00\x00\x00\x002q\x00 \x00\x00\x00\x00D?\xea(\x01\x02\x03\x04\x02\x05\x06\x02\x00\x00J\xdc\x00" +
-	"\x00\x00\x00J\xe4\x00\x04\x00\x00MX\x00\b\x00\x00T`\x01\x0e\x00\x00[h\x01\x12\x00\x00[h\x00\x12\x00\x00T`\x00\x0eLMT\x00MMT\x00+0530\x00+06\x00+0630" +
-	"\x00\n<+0530>-5:30\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTL\xe0\x91y\xe5\x02\x00\x00\xe5\x02\x00\x00\x10\x00\x1c\x00Asia/Krasnoyars" +
-	"kUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00A\x00\x00\x00\x06" +
-	"\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xf9\r\xf2\xff\xff\xff\xff\xb5\xa3\xe1 \x00\x00\x00\x00\x15'o\x90\x00\x00\x00\x00\x16\x18\xa4\x00\x00\x00\x00\x00\x17\b\xa3\x10\x00\x00\x00\x00\x17\xf9׀\x00\x00\x00\x00\x18\xe9\u0590" +
-	"\x00\x00\x00\x00\x19\xdb\v\x00\x00\x00\x00\x00\x1a\xcc[\x90\x00\x00\x00\x00\x1b\xbch\xb0\x00\x00\x00\x00\x1c\xacY\xb0\x00\x00\x00\x00\x1d\x9cJ\xb0\x00\x00\x00\x00\x1e\x8c;\xb0\x00\x00\x00\x00\x1f|,\xb0\x00\x00\x00\x00" +
-	" l\x1d\xb0\x00\x00\x00\x00!\\\x0e\xb0\x00\x00\x00\x00\"K\xff\xb0\x00\x00\x00\x00#;\xf0\xb0\x00\x00\x00\x00$+\xe1\xb0\x00\x00\x00\x00%\x1bҰ\x00\x00\x00\x00&\vð\x00\x00\x00\x00'\x04\xef0" +
-	"\x00\x00\x00\x00'\xf4\xe00\x00\x00\x00\x00(\xe4\xdf@\x00\x00\x00\x00)x\x87@\x00\x00\x00\x00)\xd4\xc20\x00\x00\x00\x00*ij0\x00\x00\x00\x00+\xb4\xa40\x00\x00\x00\x00,\xa4\x950\x00\x00\x00\x00" +
-	"-\x94\x860\x00\x00\x00\x00.\x84w0\x00\x00\x00\x00/th0\x00\x00\x00\x000dY0\x00\x00\x00\x001]\x84\xb0\x00\x00\x00\x002r_\xb0\x00\x00\x00\x003=f\xb0\x00\x00\x00\x004RA\xb0" +
-	"\x00\x00\x00\x005\x1dH\xb0\x00\x00\x00\x0062#\xb0\x00\x00\x00\x006\xfd*\xb0\x00\x00\x00\x008\x1b@0\x00\x00\x00\x008\xdd\f\xb0\x00\x00\x00\x009\xfb\"0\x00\x00\x00\x00:\xbc\xee\xb0\x00\x00\x00\x00" +
-	";\xdb\x040\x00\x00\x00\x00<\xa6\v0\x00\x00\x00\x00=\xba\xe60\x00\x00\x00\x00>\x85\xed0\x00\x00\x00\x00?\x9a\xc80\x00\x00\x00\x00@e\xcf0\x00\x00\x00\x00A\x83\xe4\xb0\x00\x00\x00\x00BE\xb10" +
-	"\x00\x00\x00\x00Ccư\x00\x00\x00\x00D%\x930\x00\x00\x00\x00EC\xa8\xb0\x00\x00\x00\x00F\x05u0\x00\x00\x00\x00G#\x8a\xb0\x00\x00\x00\x00G\ue470\x00\x00\x00\x00I\x03l\xb0\x00\x00\x00\x00" +
-	"I\xces\xb0\x00\x00\x00\x00J\xe3N\xb0\x00\x00\x00\x00K\xaeU\xb0\x00\x00\x00\x00L\xcck0\x00\x00\x00\x00M\x8e7\xb0\x00\x00\x00\x00TK\xe5 \x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
-	"\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x03\x00\x00W\x0e\x00\x00\x00\x00T`\x00" +
-	"\x04\x00\x00p\x80\x01\b\x00\x00bp\x00\f\x00\x00bp\x01\f\x00\x00p\x80\x00\bLMT\x00+06\x00+08\x00+07\x00\n<+07>-7\nPK\x03\x04\n\x00\x00\x00\x00\x00" +
-	"\x8fj\xbeT\xf0\x9cf>\xd7\x02\x00\x00\xd7\x02\x00\x00\x0e\x00\x1c\x00Asia/KamchatkaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_" +
-	"\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xa7R\x96\xc4\xff\xff\xff\xff\xb5\xa3\x9a\xd0\x00\x00\x00\x00\x15')" +
-	"@\x00\x00\x00\x00\x16\x18]\xb0\x00\x00\x00\x00\x17\b\\\xc0\x00\x00\x00\x00\x17\xf9\x910\x00\x00\x00\x00\x18\xe9\x90@\x00\x00\x00\x00\x19\xdaİ\x00\x00\x00\x00\x1a\xcc\x15@\x00\x00\x00\x00\x1b\xbc\"`\x00\x00\x00" +
-	"\x00\x1c\xac\x13`\x00\x00\x00\x00\x1d\x9c\x04`\x00\x00\x00\x00\x1e\x8b\xf5`\x00\x00\x00\x00\x1f{\xe6`\x00\x00\x00\x00 k\xd7`\x00\x00\x00\x00![\xc8`\x00\x00\x00\x00\"K\xb9`\x00\x00\x00\x00#;\xaa" +
-	"`\x00\x00\x00\x00$+\x9b`\x00\x00\x00\x00%\x1b\x8c`\x00\x00\x00\x00&\v}`\x00\x00\x00\x00'\x04\xa8\xe0\x00\x00\x00\x00'\xf4\x99\xe0\x00\x00\x00\x00(\xe4\x98\xf0\x00\x00\x00\x00)x@\xf0\x00\x00\x00" +
-	"\x00)\xd4{\xe0\x00\x00\x00\x00*\xc4l\xe0\x00\x00\x00\x00+\xb4]\xe0\x00\x00\x00\x00,\xa4N\xe0\x00\x00\x00\x00-\x94?\xe0\x00\x00\x00\x00.\x840\xe0\x00\x00\x00\x00/t!\xe0\x00\x00\x00\x000d\x12" +
-	"\xe0\x00\x00\x00\x001]>`\x00\x00\x00\x002r\x19`\x00\x00\x00\x003= `\x00\x00\x00\x004Q\xfb`\x00\x00\x00\x005\x1d\x02`\x00\x00\x00\x0061\xdd`\x00\x00\x00\x006\xfc\xe4`\x00\x00\x00" +
-	"\x008\x1a\xf9\xe0\x00\x00\x00\x008\xdc\xc6`\x00\x00\x00\x009\xfa\xdb\xe0\x00\x00\x00\x00:\xbc\xa8`\x00\x00\x00\x00;ڽ\xe0\x00\x00\x00\x00<\xa5\xc4\xe0\x00\x00\x00\x00=\xba\x9f\xe0\x00\x00\x00\x00>\x85\xa6" +
-	"\xe0\x00\x00\x00\x00?\x9a\x81\xe0\x00\x00\x00\x00@e\x88\xe0\x00\x00\x00\x00A\x83\x9e`\x00\x00\x00\x00BEj\xe0\x00\x00\x00\x00Cc\x80`\x00\x00\x00\x00D%L\xe0\x00\x00\x00\x00ECb`\x00\x00\x00" +
-	"\x00F\x05.\xe0\x00\x00\x00\x00G#D`\x00\x00\x00\x00G\xeeK`\x00\x00\x00\x00I\x03&`\x00\x00\x00\x00I\xce-`\x00\x00\x00\x00J\xe3\b`\x00\x00\x00\x00K\xae\x0f`\x00\x00\x00\x00L\xcc2" +
-	"\xf0\x00\x00\x00\x00M\x8d\xffp\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
-	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x00\x00\x94\xbc\x00\x00\x00\x00\x9a\xb0\x00\x04\x00\x00\xb6\xd0\x01\b\x00\x00\xa8\xc0\x00\f\x00\x00\xa8\xc0\x01\fLMT\x00+11\x00+13\x00+12\x00\n" +
-	"<+12>-12\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT`\xc9\xd4\\\xbe\x00\x00\x00\xbe\x00\x00\x00\x12\x00\x1c\x00Asia/Ujung_PandangUT\t" +
-	"\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x15" +
-	"\xff\xff\xff\xff\xa1\xf2]\x90\xff\xff\xff\xff\xba\x16Ր\xff\xff\xff\xffˈ\x1d\x80\xff\xff\xff\xff\xd2V\xeep\x01\x02\x03\x04\x00\x00o\xf0\x00\x00\x00\x00o\xf0\x00\x04\x00\x00p\x80\x00\b\x00\x00~\x90\x00\f" +
-	"\x00\x00p\x80\x00\x10LMT\x00MMT\x00+08\x00+09\x00WITA\x00\nWITA-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTb\xadű\xf8\x00\x00\x00\xf8\x00\x00" +
-	"\x00\f\x00\x1c\x00Asia/JakartaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\a\x00\x00\x00 \xff\xff\xff\xff?fI`\xff\xff\xff\xff\xa9x\x85\xe0\xff\xff\xff\xff\xba\x16\xde`\xff\xff\xff\xff˿\x83\x88\xff\xff\xff\xff\xd2V\xeep" +
-	"\xff\xff\xff\xff\xd7<\xc6\b\xff\xff\xff\xff\xda\xff&\x00\xff\xff\xff\xff\xf4\xb5\xbe\x88\x01\x02\x03\x04\x03\x05\x03\x06\x00\x00d \x00\x00\x00\x00d \x00\x04\x00\x00g \x00\b\x00\x00ix\x00\x0e\x00\x00~\x90" +
-	"\x00\x14\x00\x00p\x80\x00\x18\x00\x00bp\x00\x1cLMT\x00BMT\x00+0720\x00+0730\x00+09\x00+08\x00WIB\x00\nWIB-7\nPK\x03\x04\n\x00\x00" +
-	"\x00\x00\x00\x8fj\xbeT\x9a\x1a\xdc\xca\xdc\x00\x00\x00\xdc\x00\x00\x00\f\x00\x1c\x00Asia/KolkataUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S" +
-	"_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x05\x00\x00\x00\x16\xff\xff\xff\xff&\xba\x18(\xff\xff\xff\xffC\xe7\xeb0\xff\xff\xff\xff\x87\x9d" +
-	"\xbc\xba\xff\xff\xff\xff\xcaی(\xff\xff\xff\xff\xcc\x05q\x18\xff\xff\xff\xff̕2\xa8\xff\xff\xff\xff\xd2t\x12\x98\x01\x02\x03\x04\x03\x04\x03\x00\x00R\xd8\x00\x00\x00\x00R\xd0\x00\x04\x00\x00KF\x00\b\x00" +
-	"\x00MX\x00\f\x00\x00[h\x01\x10LMT\x00HMT\x00MMT\x00IST\x00+0630\x00\nIST-5:30\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT'\xe2\\" +
-	"\xff\x9f\x00\x00\x00\x9f\x00\x00\x00\n\x00\x1c\x00Asia/KabulUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffi\x86\x9a\xa0\xff\xff\xff\xff\xd0\xf9\xd7@\x01\x02\x00\x00@\xe0\x00\x00\x00\x008@\x00\x04\x00\x00?H" +
-	"\x00\bLMT\x00+04\x00+0430\x00\n<+0430>-4:30\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT&\xe9\xd1\xd8q\x02\x00\x00q\x02\x00\x00\t\x00\x1c\x00" +
-	"Asia/OralUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x003\x00\x00\x00\a\x00\x00\x00\x14\xff\xff\xff\xff\xaa\x19\x93\xdc\xff\xff\xff\xff\xb5\xa4\vP\x00\x00\x00\x00\x15'\x8b\xb0\x00\x00\x00\x00\x16\x18\xc0 \x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xf3\xa0" +
-	"\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00" +
-	"\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L\x1b\xd0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xfc\xe0\x00\x00\x00\x00&\v\xed\xe0" +
-	"\x00\x00\x00\x00'\x05\x19`\x00\x00\x00\x00'\xf5\n`\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\xa3`\x00\x00\x00\x00)\xd4\xdeP\x00\x00\x00\x00*\xc4\xdd`\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00" +
-	",\xa4\xbf`\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\xa1`\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000d\x83`\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002r\x89\xe0\x00\x00\x00\x003=\x90\xe0" +
-	"\x00\x00\x00\x004Rk\xe0\x00\x00\x00\x005\x1dr\xe0\x00\x00\x00\x0062M\xe0\x00\x00\x00\x006\xfdT\xe0\x00\x00\x00\x008\x1bj`\x00\x00\x00\x008\xdd6\xe0\x00\x00\x00\x009\xfbL`\x00\x00\x00\x00" +
-	":\xbd\x18\xe0\x00\x00\x00\x00;\xdb.`\x00\x00\x00\x00<\xa65`\x00\x00\x00\x00=\xbb\x10`\x00\x00\x00\x00>\x86\x17`\x00\x00\x00\x00?\x9a\xf2`\x00\x00\x00\x00@e\xf9`\x00\x00\x00\x00A\x84\x0e\xe0" +
-	"\x01\x02\x03\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x06\x05\x06\x05\x06\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x02\x00\x000$\x00\x00\x00\x00*" +
-	"0\x00\x04\x00\x00FP\x00\b\x00\x00T`\x01\f\x00\x00T`\x00\f\x00\x00FP\x01\b\x00\x008@\x00\x10LMT\x00+03\x00+05\x00+06\x00+04\x00\n<+05>-" +
-	"5\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT.>[K\xab\x00\x00\x00\xab\x00\x00\x00\r\x00\x1c\x00Asia/JayapuraUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux" +
-	"\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00" +
-	"\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\xba\x16\xc1\x98\xff\xff\xff\xff" +
-	"\xd0X\xb9\xf0\xff\xff\xff\xff\xf4\xb5\xa2h\x01\x02\x03\x00\x00\x83\xe8\x00\x00\x00\x00~\x90\x00\x04\x00\x00\x85\x98\x00\b\x00\x00~\x90\x00\x0eLMT\x00+09\x00+0930\x00WIT\x00\nWI" +
-	"T-9\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTS\xa5\x81e\xf7\x00\x00\x00\xf7\x00\x00\x00\x0e\x00\x1c\x00Asia/PontianakUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94" +
-	"bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01" +
-	"\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\a\x00\x00\x00\x1f\xff\xff\xff\xff\x8b\xff\x8e\x00\xff" +
-	"\xff\xff\xff\xba\x16\xdf\x00\xff\xff\xff\xff\xcby\xa4\b\xff\xff\xff\xff\xd2V\xeep\xff\xff\xff\xff\xd7<\xc6\b\xff\xff\xff\xff\xda\xff&\x00\xff\xff\xff\xff\xf4\xb5\xbe\x88\x00\x00\x00\x00!\xdat\x80\x01\x02\x03\x02\x04" +
-	"\x02\x05\x06\x00\x00f\x80\x00\x00\x00\x00f\x80\x00\x04\x00\x00ix\x00\b\x00\x00~\x90\x00\x0e\x00\x00p\x80\x00\x12\x00\x00p\x80\x00\x16\x00\x00bp\x00\x1bLMT\x00PMT\x00+0730\x00+" +
-	"09\x00+08\x00WITA\x00WIB\x00\nWIB-7\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT`\xc9\xd4\\\xbe\x00\x00\x00\xbe\x00\x00\x00\r\x00\x1c\x00Asia/Ma" +
-	"kassarUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x04\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xff\xa1\xf2]\x90\xff\xff\xff\xff\xba\x16Ր\xff\xff\xff\xffˈ\x1d\x80\xff\xff\xff\xff\xd2V\xeep\x01\x02\x03\x04\x00\x00o\xf0\x00\x00\x00\x00o\xf0\x00\x04\x00\x00p" +
-	"\x80\x00\b\x00\x00~\x90\x00\f\x00\x00p\x80\x00\x10LMT\x00MMT\x00+08\x00+09\x00WITA\x00\nWITA-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeTѾ" +
-	"\xa8\xc7u\x02\x00\x00u\x02\x00\x00\f\x00\x1c\x00Asia/TbilisiUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x004\x00\x00\x00\x06\x00\x00\x00\x15\xff\xff\xff\xffV\xb6\xba\x01\xff\xff\xff\xff\xaa\x19\x9a\x01\xff\xff\xff\xff\xe7\xda\fP\x00\x00\x00\x00\x15'\x99" +
-	"\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\b\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a̅\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00" +
-	"\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\8\xe0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<\x1a" +
-	"\xe0\x00\x00\x00\x00$,\v\xe0\x00\x00\x00\x00%\x1b\xfc\xe0\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00'\x05\x19`\x00\x00\x00\x00'\xf5\n`\x00\x00\x00\x00(\xe5\tp\x00\x00\x00\x00)\xd4\xdeP\x00\x00\x00" +
-	"\x00*\xc4\xc1@\x00\x00\x00\x00+\xb4\xc0P\x00\x00\x00\x00,\xa4\xa3@\x00\x00\x00\x00-\x94\xa2P\x00\x00\x00\x00.\x84\x85@\x00\x00\x00\x00/tv@\x00\x00\x00\x000dY0\x00\x00\x00\x001]\x92" +
-	"\xc0\x00\x00\x00\x003=f\xb0\x00\x00\x00\x004RA\xb0\x00\x00\x00\x005\x1dV\xc0\x00\x00\x00\x0062#\xb0\x00\x00\x00\x006\xfd8\xc0\x00\x00\x00\x008\x1b@0\x00\x00\x00\x008\xdd\x1a\xc0\x00\x00\x00" +
-	"\x009\xfb\"0\x00\x00\x00\x00:\xbc\xfc\xc0\x00\x00\x00\x00;\xdb\x040\x00\x00\x00\x00<\xa6\x19@\x00\x00\x00\x00=\xba\xe60\x00\x00\x00\x00>\x85\xfb@\x00\x00\x00\x00?\x9a\xc80\x00\x00\x00\x00@e\xdd" +
-	"@\x00\x00\x00\x00@\xddǰ\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x05\x02\x05\x02\x05\x02\x05\x04\x03\x04\x03\x03" +
-	"\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x05\x02\x04\x00\x00)\xff\x00\x00\x00\x00)\xff\x00\x04\x00\x00*0\x00\t\x00\x00FP\x01\r\x00\x008@\x00\x11\x00\x008@\x01\x11LMT\x00TBM" +
-	"T\x00+03\x00+05\x00+04\x00\n<+04>-4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x06\xaa>\xa8\x00\x01\x00\x00\x00\x01\x00\x00\x0e\x00\x1c\x00Asia/Si" +
-	"ngaporeUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\b\x00\x00\x00\b\x00\x00\x00 \xff\xff\xff\xff~6S\xa3\xff\xff\xff\xff\x86\x83\x85\xa3\xff\xff\xff\xff\xbagN\x90\xff\xff\xff\xff\xc0\n\xe4`\xff\xff\xff\xffʳ\xe5`\xff\xff\xff\xffˑ_\b\xff\xff" +
-	"\xff\xff\xd2Hm\xf0\x00\x00\x00\x00\x16\x91\xf5\b\x01\x02\x03\x04\x05\x06\x05\a\x00\x00a]\x00\x00\x00\x00a]\x00\x04\x00\x00bp\x00\b\x00\x00g \x01\f\x00\x00g \x00\f\x00\x00ix\x00\x12\x00\x00" +
-	"~\x90\x00\x18\x00\x00p\x80\x00\x1cLMT\x00SMT\x00+07\x00+0720\x00+0730\x00+09\x00+08\x00\n<+08>-8\nPK\x03\x04\n\x00\x00\x00\x00" +
-	"\x00\x8ej\xbeT*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00\x00\v\x00\x1c\x00Asia/HarbinUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00" +
+	"\x00\x00\x00\x00\t\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xff\x88\x8cC\x8a\xff\xff\xff\xff\x91\xa3+\n\xff\xff\xff\xff\xcd5\xe6\x80\xff\xff\xff\xff\xd1Y\xcep\xff\xff\xff\xff\xd2;>\xf0\xff\xff\xff\xff\xd52\xbb" +
+	"\x10\xff\xff\xff\xff\xe4\xb6\xe4\x80\xff\xff\xff\xff\xed/\x98\x00\x00\x00\x00\x00\n=\xc7\x00\x01\x02\x03\x04\x02\x03\x02\x03\x02\x00\x00c\xf6\x00\x00\x00\x00c\xf6\x00\x04\x00\x00bp\x00\t\x00\x00p\x80\x00\r\x00\x00" +
+	"~\x90\x00\x11LMT\x00PLMT\x00+07\x00+08\x00+09\x00\n<+07>-7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)\x15II\xf3\x02\x00\x00\xf3\x02\x00\x00" +
+	"\r\x00\x00\x00Asia/SakhalinTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" +
+	"\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xff\x86\xf0\u0378" +
+	"\xff\xff\xff\xff\xd20\xb2\xf0\x00\x00\x00\x00\x15'7P\x00\x00\x00\x00\x16\x18k\xc0\x00\x00\x00\x00\x17\bj\xd0\x00\x00\x00\x00\x17\xf9\x9f@\x00\x00\x00\x00\x18\xe9\x9eP\x00\x00\x00\x00\x19\xda\xd2\xc0\x00\x00\x00\x00" +
+	"\x1a\xcc#P\x00\x00\x00\x00\x1b\xbc0p\x00\x00\x00\x00\x1c\xac!p\x00\x00\x00\x00\x1d\x9c\x12p\x00\x00\x00\x00\x1e\x8c\x03p\x00\x00\x00\x00\x1f{\xf4p\x00\x00\x00\x00 k\xe5p\x00\x00\x00\x00![\xd6p" +
+	"\x00\x00\x00\x00\"K\xc7p\x00\x00\x00\x00#;\xb8p\x00\x00\x00\x00$+\xa9p\x00\x00\x00\x00%\x1b\x9ap\x00\x00\x00\x00&\v\x8bp\x00\x00\x00\x00'\x04\xb6\xf0\x00\x00\x00\x00'\xf4\xa7\xf0\x00\x00\x00\x00" +
+	"(\xe4\xa7\x00\x00\x00\x00\x00)xO\x00\x00\x00\x00\x00)ԉ\xf0\x00\x00\x00\x00*\xc4z\xf0\x00\x00\x00\x00+\xb4k\xf0\x00\x00\x00\x00,\xa4\\\xf0\x00\x00\x00\x00-\x94M\xf0\x00\x00\x00\x00.\x84>\xf0" +
+	"\x00\x00\x00\x00/t/\xf0\x00\x00\x00\x000d \xf0\x00\x00\x00\x001]Lp\x00\x00\x00\x002r'p\x00\x00\x00\x003=.p\x00\x00\x00\x004R\x17\x80\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x00" +
+	"61\xf9\x80\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x008\x1b\x16\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xfa\xf8\x00\x00\x00\x00\x00:\xbcĀ\x00\x00\x00\x00;\xda\xda\x00\x00\x00\x00\x00<\xa5\xe1\x00" +
+	"\x00\x00\x00\x00=\xba\xbc\x00\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?\x9a\x9e\x00\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00" +
+	"D%i\x00\x00\x00\x00\x00EC~\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xeeg\x80\x00\x00\x00\x00I\x03B\x80\x00\x00\x00\x00I\xceI\x80\x00\x00\x00\x00J\xe3$\x80" +
+	"\x00\x00\x00\x00K\xae+\x80\x00\x00\x00\x00L\xccA\x00\x00\x00\x00\x00M\x8e\r\x80\x00\x00\x00\x00TK\xba\xf0\x00\x00\x00\x00V\xf6\xb2\x00\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x04\x05\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x03\x05\x03\x00\x00\x85\xc8\x00\x00\x00\x00~\x90\x00\x04\x00\x00" +
+	"\xa8\xc0\x01\b\x00\x00\x9a\xb0\x00\f\x00\x00\x9a\xb0\x01\f\x00\x00\x8c\xa0\x00\x10LMT\x00+09\x00+12\x00+11\x00+10\x00\n<+11>-11\nPK\x03\x04\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00w\rD\an\x01\x00\x00n\x01\x00\x00\x0e\x00\x00\x00Asia/SamarkandTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x18\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x857\xff\xff\xff\xff\xb5\xa3\xfd@\x00\x00\x00\x00\x15'\x8b\xb0\x00\x00\x00\x00\x16\x18\xc0 \x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xf3\xa0\x00" +
+	"\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00\x1f" +
+	"|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L\x1b\xd0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\v\xdf\xd0\x00" +
+	"\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xedP\x01\x02\x03\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00>\xc9\x00\x00\x00\x008@\x00\x04\x00" +
+	"\x00FP\x00\b\x00\x00T`\x01\f\x00\x00T`\x00\fLMT\x00+04\x00+05\x00+06\x00\n<+05>-5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7X,Y" +
+	"\x9f\x01\x00\x00\x9f\x01\x00\x00\n\x00\x00\x00Asia/SeoulTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff" +
+	"\xff\x8b\xd7\xf0x\xff\xff\xff\xff\x92\xe6\x16\xf8\xff\xff\xff\xff\xd2C'\xf0\xff\xff\xff\xff\xd7e\x8fp\xff\xff\xff\xff\xd7\xee\x9d`\xff\xff\xff\xff\xd8\xf8\xfap\xff\xff\xff\xff\xd9\xcd-\xe0\xff\xff\xff\xff\xda\u05ca" +
+	"\xf0\xff\xff\xff\xffۭ\x0f\xe0\xff\xff\xff\xff\xdc\xe6\xe2\xf0\xff\xff\xff\xff\u074c\xf1\xe0\xff\xff\xff\xff\xe2O)\xf0\xff\xff\xff\xff\xe4k\xb7\xf8\xff\xff\xff\xff\xe5\x13\x18h\xff\xff\xff\xff\xe6b\x03x\xff\xff\xff" +
+	"\xff\xe7\x11L\xe8\xff\xff\xff\xff\xe8/px\xff\xff\xff\xff\xe8\xe7\xf4h\xff\xff\xff\xff\xea\x0fRx\xff\xff\xff\xff\xea\xc7\xd6h\xff\xff\xff\xff\xeb\xef4x\xff\xff\xff\xff째h\xff\xff\xff\xff\xed\xcf\x16" +
+	"x\xff\xff\xff\xff\ue1dah\xff\xff\xff\xff\xf05qx\x00\x00\x00\x00 \xa3`\x90\x00\x00\x00\x00!ng\x90\x00\x00\x00\x00\"\x83B\x90\x00\x00\x00\x00#NI\x90\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04" +
+	"\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01\x04\x03\x04\x03\x04\x00\x00w\b\x00\x00\x00\x00w\x88\x00\x04\x00\x00~\x90\x00\b\x00\x00\x8c\xa0\x01\f\x00\x00~\x90\x00\x04\x00\x00\x85\x98\x01\fLMT\x00KS" +
+	"T\x00JST\x00KDT\x00\nKST-9\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00\x00\r\x00\x00\x00Asia/Shanghai" +
 	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00" +
 	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff~6C)\xff\xff\xff\xff\xa0\x97\xa2\x80\xff\xff\xff\xff\xa1y\x04\xf0\xff" +
 	"\xff\xff\xff\xc8Y^\x80\xff\xff\xff\xff\xc9\t\xf9p\xff\xff\xff\xff\xc9ӽ\x00\xff\xff\xff\xff\xcb\x05\x8a\xf0\xff\xff\xff\xff\xcb|@\x00\xff\xff\xff\xff\xd2;>\xf0\xff\xff\xff\xffӋ{\x80\xff\xff\xff\xff\xd4" +
 	"B\xad\xf0\xff\xff\xff\xff\xd5E\"\x00\xff\xff\xff\xff\xd6L\xbf\xf0\xff\xff\xff\xff\xd7<\xbf\x00\xff\xff\xff\xff\xd8\x06fp\xff\xff\xff\xff\xd9\x1d\xf2\x80\xff\xff\xff\xff\xd9A|\xf0\x00\x00\x00\x00\x1e\xbaR \x00" +
 	"\x00\x00\x00\x1fi\x9b\x90\x00\x00\x00\x00 ~\x84\xa0\x00\x00\x00\x00!I}\x90\x00\x00\x00\x00\"g\xa1 \x00\x00\x00\x00#)_\x90\x00\x00\x00\x00$G\x83 \x00\x00\x00\x00%\x12|\x10\x00\x00\x00\x00&" +
 	"'e \x00\x00\x00\x00&\xf2^\x10\x00\x00\x00\x00(\aG \x00\x00\x00\x00(\xd2@\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00q\xd7" +
-	"\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\bLMT\x00CDT\x00CST\x00\nCST-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeTB\x1d\xc6\x1b\x85\x00\x00\x00\x85\x00\x00\x00\f" +
-	"\x00\x1c\x00Asia/KashgarUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xb0\xfe\xbad\x01\x00\x00R\x1c\x00\x00\x00\x00T`\x00\x04LMT\x00+06\x00\n<+06>-6\nPK\x03\x04" +
-	"\n\x00\x00\x00\x00\x00\x8ej\xbeT?Y\xaf\x19\xe7\x00\x00\x00\xe7\x00\x00\x00\n\x00\x1c\x00Asia/DhakaUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04" +
-	"S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x06\x00\x00\x00\x1c\xff\xff\xff\xffi\x86\x86\xbc\xff\xff\xff\xff\xcaۆ\xb0\xff\xff\xff\xff\xcc" +
-	"\x05q\x18\xff\xff\xff\xff̕2\xa8\xff\xff\xff\xffݨҘ\x00\x00\x00\x00J;\xc4\x10\x00\x00\x00\x00K<ؐ\x01\x02\x03\x02\x04\x05\x04\x00\x00T\xc4\x00\x00\x00\x00R\xd0\x00\x04\x00\x00[h\x00\b" +
-	"\x00\x00MX\x00\x0e\x00\x00T`\x00\x14\x00\x00bp\x01\x18LMT\x00HMT\x00+0630\x00+0530\x00+06\x00+07\x00\n<+06>-6\nPK\x03\x04\n" +
-	"\x00\x00\x00\x00\x00\x8fj\xbeTO\xb0\x03\xe9\xe5\x02\x00\x00\xe5\x02\x00\x00\f\x00\x1c\x00Asia/YakutskUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00" +
-	"\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif" +
-	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00A\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xdb\xea^\xff\xff\xff\xff\xb5\xa3\xc5\x00\x00\x00\x00\x00" +
-	"\x15'Sp\x00\x00\x00\x00\x16\x18\x87\xe0\x00\x00\x00\x00\x17\b\x86\xf0\x00\x00\x00\x00\x17\xf9\xbb`\x00\x00\x00\x00\x18\xe9\xbap\x00\x00\x00\x00\x19\xda\xee\xe0\x00\x00\x00\x00\x1a\xcc?p\x00\x00\x00\x00\x1b\xbcL\x90" +
-	"\x00\x00\x00\x00\x1c\xac=\x90\x00\x00\x00\x00\x1d\x9c.\x90\x00\x00\x00\x00\x1e\x8c\x1f\x90\x00\x00\x00\x00\x1f|\x10\x90\x00\x00\x00\x00 l\x01\x90\x00\x00\x00\x00![\xf2\x90\x00\x00\x00\x00\"K\xe3\x90\x00\x00\x00\x00" +
-	"#;Ԑ\x00\x00\x00\x00$+Ő\x00\x00\x00\x00%\x1b\xb6\x90\x00\x00\x00\x00&\v\xa7\x90\x00\x00\x00\x00'\x04\xd3\x10\x00\x00\x00\x00'\xf4\xc4\x10\x00\x00\x00\x00(\xe4\xc3 \x00\x00\x00\x00)xk " +
-	"\x00\x00\x00\x00)Ԧ\x10\x00\x00\x00\x00*ė\x10\x00\x00\x00\x00+\xb4\x88\x10\x00\x00\x00\x00,\xa4y\x10\x00\x00\x00\x00-\x94j\x10\x00\x00\x00\x00.\x84[\x10\x00\x00\x00\x00/tL\x10\x00\x00\x00\x00" +
-	"0d=\x10\x00\x00\x00\x001]h\x90\x00\x00\x00\x002rC\x90\x00\x00\x00\x003=J\x90\x00\x00\x00\x004R%\x90\x00\x00\x00\x005\x1d,\x90\x00\x00\x00\x0062\a\x90\x00\x00\x00\x006\xfd\x0e\x90" +
-	"\x00\x00\x00\x008\x1b$\x10\x00\x00\x00\x008\xdc\xf0\x90\x00\x00\x00\x009\xfb\x06\x10\x00\x00\x00\x00:\xbcҐ\x00\x00\x00\x00;\xda\xe8\x10\x00\x00\x00\x00<\xa5\xef\x10\x00\x00\x00\x00=\xba\xca\x10\x00\x00\x00\x00" +
-	">\x85\xd1\x10\x00\x00\x00\x00?\x9a\xac\x10\x00\x00\x00\x00@e\xb3\x10\x00\x00\x00\x00A\x83Ȑ\x00\x00\x00\x00BE\x95\x10\x00\x00\x00\x00Cc\xaa\x90\x00\x00\x00\x00D%w\x10\x00\x00\x00\x00EC\x8c\x90" +
-	"\x00\x00\x00\x00F\x05Y\x10\x00\x00\x00\x00G#n\x90\x00\x00\x00\x00G\xeeu\x90\x00\x00\x00\x00I\x03P\x90\x00\x00\x00\x00I\xceW\x90\x00\x00\x00\x00J\xe32\x90\x00\x00\x00\x00K\xae9\x90\x00\x00\x00\x00" +
-	"L\xccO\x10\x00\x00\x00\x00M\x8e\x1b\x90\x00\x00\x00\x00TK\xc9\x00\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x03\x00\x00y\xa2\x00\x00\x00\x00p\x80\x00\x04\x00\x00\x8c\xa0\x01\b\x00\x00~\x90\x00\f\x00\x00~\x90\x01\f\x00\x00\x8c\xa0\x00" +
-	"\bLMT\x00+08\x00+10\x00+09\x00\n<+09>-9\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT恸\x1e\x00\x01\x00\x00\x00\x01\x00\x00\x11\x00\x1c\x00Asia" +
-	"/Kuala_LumpurUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\b\x00\x00\x00 \xff\xff\xff\xff~6U\xaa\xff\xff\xff\xff\x86\x83\x85\xa3\xff\xff\xff\xff\xbagN\x90\xff\xff\xff\xff\xc0\n\xe4`\xff\xff\xff\xffʳ\xe5`\xff\xff\xff\xff" +
-	"ˑ_\b\xff\xff\xff\xff\xd2Hm\xf0\x00\x00\x00\x00\x16\x91\xf5\b\x01\x02\x03\x04\x05\x06\x05\a\x00\x00_V\x00\x00\x00\x00a]\x00\x04\x00\x00bp\x00\b\x00\x00g \x01\f\x00\x00g \x00\f\x00\x00" +
-	"ix\x00\x12\x00\x00~\x90\x00\x18\x00\x00p\x80\x00\x1cLMT\x00SMT\x00+07\x00+0720\x00+0730\x00+09\x00+08\x00\n<+08>-8\nPK\x03" +
-	"\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT;\x7fP\x8d\xd4\a\x00\x00\xd4\a\x00\x00\v\x00\x1c\x00Asia/TehranUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b" +
-	"\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZi" +
-	"f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc9\x00\x00\x00\x06\x00\x00\x00\x1c\xff\xff\xff\xff\x9al}\xc8\xff\xff\xff\xff\xd2\xdb\x12\xc8\x00\x00\x00" +
-	"\x00\x0e\xbb\xa2H\x00\x00\x00\x00\x0ft-@\x00\x00\x00\x00\x10\x8e@0\x00\x00\x00\x00\x10\xed:@\x00\x00\x00\x00\x11Ug\xc8\x00\x00\x00\x00\x12EJ\xb8\x00\x00\x00\x00\x137\xec\xc8\x00\x00\x00\x00\x14-\x15" +
-	"\xb8\x00\x00\x00\x00( v\xc8\x00\x00\x00\x00(\u06dd\xb8\x00\x00\x00\x00)˜\xc8\x00\x00\x00\x00*\xbe\"\xb8\x00\x00\x00\x00+\xac\xd0H\x00\x00\x00\x00,\x9fV8\x00\x00\x00\x00-\x8e\x03\xc8\x00\x00\x00" +
-	"\x00.\x80\x89\xb8\x00\x00\x00\x00/o7H\x00\x00\x00\x000a\xbd8\x00\x00\x00\x001Pj\xc8\x00\x00\x00\x002B\xf0\xb8\x00\x00\x00\x0032\xef\xc8\x00\x00\x00\x004%u\xb8\x00\x00\x00\x005\x14#" +
-	"H\x00\x00\x00\x006\x06\xa98\x00\x00\x00\x006\xf5V\xc8\x00\x00\x00\x007\xe7ܸ\x00\x00\x00\x008֊H\x00\x00\x00\x009\xc9\x108\x00\x00\x00\x00:\xb9\x0fH\x00\x00\x00\x00;\xab\x958\x00\x00\x00" +
-	"\x00<\x9aB\xc8\x00\x00\x00\x00=\x8cȸ\x00\x00\x00\x00>{vH\x00\x00\x00\x00?m\xfc8\x00\x00\x00\x00@\\\xa9\xc8\x00\x00\x00\x00AO/\xb8\x00\x00\x00\x00B?.\xc8\x00\x00\x00\x00C1\xb4" +
-	"\xb8\x00\x00\x00\x00G\xe2\xc9H\x00\x00\x00\x00H\xd5O8\x00\x00\x00\x00I\xc5NH\x00\x00\x00\x00J\xb7\xd48\x00\x00\x00\x00K\xa6\x81\xc8\x00\x00\x00\x00L\x99\a\xb8\x00\x00\x00\x00M\x87\xb5H\x00\x00\x00" +
-	"\x00Nz;8\x00\x00\x00\x00Oh\xe8\xc8\x00\x00\x00\x00P[n\xb8\x00\x00\x00\x00QKm\xc8\x00\x00\x00\x00R=\xf3\xb8\x00\x00\x00\x00S,\xa1H\x00\x00\x00\x00T\x1f'8\x00\x00\x00\x00U\r\xd4" +
-	"\xc8\x00\x00\x00\x00V\x00Z\xb8\x00\x00\x00\x00V\xef\bH\x00\x00\x00\x00W\xe1\x8e8\x00\x00\x00\x00XэH\x00\x00\x00\x00Y\xc4\x138\x00\x00\x00\x00Z\xb2\xc0\xc8\x00\x00\x00\x00[\xa5F\xb8\x00\x00\x00" +
-	"\x00\\\x93\xf4H\x00\x00\x00\x00]\x86z8\x00\x00\x00\x00^u'\xc8\x00\x00\x00\x00_g\xad\xb8\x00\x00\x00\x00`W\xac\xc8\x00\x00\x00\x00aJ2\xb8\x00\x00\x00\x00b8\xe0H\x00\x00\x00\x00c+f" +
-	"8\x00\x00\x00\x00d\x1a\x13\xc8\x00\x00\x00\x00e\f\x99\xb8\x00\x00\x00\x00e\xfbGH\x00\x00\x00\x00f\xed\xcd8\x00\x00\x00\x00g\xdd\xccH\x00\x00\x00\x00h\xd0R8\x00\x00\x00\x00i\xbe\xff\xc8\x00\x00\x00" +
-	"\x00j\xb1\x85\xb8\x00\x00\x00\x00k\xa03H\x00\x00\x00\x00l\x92\xb98\x00\x00\x00\x00m\x81f\xc8\x00\x00\x00\x00ns\xec\xb8\x00\x00\x00\x00ob\x9aH\x00\x00\x00\x00pU 8\x00\x00\x00\x00qE\x1f" +
-	"H\x00\x00\x00\x00r7\xa58\x00\x00\x00\x00s&R\xc8\x00\x00\x00\x00t\x18ظ\x00\x00\x00\x00u\a\x86H\x00\x00\x00\x00u\xfa\f8\x00\x00\x00\x00v\xe8\xb9\xc8\x00\x00\x00\x00w\xdb?\xb8\x00\x00\x00" +
-	"\x00x\xcb>\xc8\x00\x00\x00\x00y\xbdĸ\x00\x00\x00\x00z\xacrH\x00\x00\x00\x00{\x9e\xf88\x00\x00\x00\x00|\x8d\xa5\xc8\x00\x00\x00\x00}\x80+\xb8\x00\x00\x00\x00~n\xd9H\x00\x00\x00\x00\x7fa_" +
-	"8\x00\x00\x00\x00\x80Q^H\x00\x00\x00\x00\x81C\xe48\x00\x00\x00\x00\x822\x91\xc8\x00\x00\x00\x00\x83%\x17\xb8\x00\x00\x00\x00\x84\x13\xc5H\x00\x00\x00\x00\x85\x06K8\x00\x00\x00\x00\x85\xf4\xf8\xc8\x00\x00\x00" +
-	"\x00\x86\xe7~\xb8\x00\x00\x00\x00\x87\xd7}\xc8\x00\x00\x00\x00\x88\xca\x03\xb8\x00\x00\x00\x00\x89\xb8\xb1H\x00\x00\x00\x00\x8a\xab78\x00\x00\x00\x00\x8b\x99\xe4\xc8\x00\x00\x00\x00\x8c\x8cj\xb8\x00\x00\x00\x00\x8d{\x18" +
-	"H\x00\x00\x00\x00\x8em\x9e8\x00\x00\x00\x00\x8f]\x9dH\x00\x00\x00\x00\x90P#8\x00\x00\x00\x00\x91>\xd0\xc8\x00\x00\x00\x00\x921V\xb8\x00\x00\x00\x00\x93 \x04H\x00\x00\x00\x00\x94\x12\x8a8\x00\x00\x00" +
-	"\x00\x95\x017\xc8\x00\x00\x00\x00\x95\xf3\xbd\xb8\x00\x00\x00\x00\x96\xe3\xbc\xc8\x00\x00\x00\x00\x97\xd6B\xb8\x00\x00\x00\x00\x98\xc4\xf0H\x00\x00\x00\x00\x99\xb7v8\x00\x00\x00\x00\x9a\xa6#\xc8\x00\x00\x00\x00\x9b\x98\xa9" +
-	"\xb8\x00\x00\x00\x00\x9c\x87WH\x00\x00\x00\x00\x9dy\xdd8\x00\x00\x00\x00\x9ei\xdcH\x00\x00\x00\x00\x9f\\b8\x00\x00\x00\x00\xa0K\x0f\xc8\x00\x00\x00\x00\xa1=\x95\xb8\x00\x00\x00\x00\xa2,CH\x00\x00\x00" +
-	"\x00\xa3\x1e\xc98\x00\x00\x00\x00\xa4\rv\xc8\x00\x00\x00\x00\xa4\xff\xfc\xb8\x00\x00\x00\x00\xa5\xef\xfb\xc8\x00\x00\x00\x00\xa6⁸\x00\x00\x00\x00\xa7\xd1/H\x00\x00\x00\x00\xa8õ8\x00\x00\x00\x00\xa9\xb2b" +
-	"\xc8\x00\x00\x00\x00\xaa\xa4\xe8\xb8\x00\x00\x00\x00\xab\x93\x96H\x00\x00\x00\x00\xac\x86\x1c8\x00\x00\x00\x00\xadt\xc9\xc8\x00\x00\x00\x00\xaegO\xb8\x00\x00\x00\x00\xafWN\xc8\x00\x00\x00\x00\xb0IԸ\x00\x00\x00" +
-	"\x00\xb18\x82H\x00\x00\x00\x00\xb2+\b8\x00\x00\x00\x00\xb3\x19\xb5\xc8\x00\x00\x00\x00\xb4\f;\xb8\x00\x00\x00\x00\xb4\xfa\xe9H\x00\x00\x00\x00\xb5\xedo8\x00\x00\x00\x00\xb6\xddnH\x00\x00\x00\x00\xb7\xcf\xf4" +
-	"8\x00\x00\x00\x00\xb8\xbe\xa1\xc8\x00\x00\x00\x00\xb9\xb1'\xb8\x00\x00\x00\x00\xba\x9f\xd5H\x00\x00\x00\x00\xbb\x92[8\x00\x00\x00\x00\xbc\x81\b\xc8\x00\x00\x00\x00\xbds\x8e\xb8\x00\x00\x00\x00\xbec\x8d\xc8\x00\x00\x00" +
-	"\x00\xbfV\x13\xb8\x00\x00\x00\x00\xc0D\xc1H\x00\x00\x00\x00\xc17G8\x00\x00\x00\x00\xc2%\xf4\xc8\x00\x00\x00\x00\xc3\x18z\xb8\x00\x00\x00\x00\xc4\a(H\x00\x00\x00\x00\xc4\xf9\xae8\x00\x00\x00\x00\xc5\xe9\xad" +
-	"H\x00\x00\x00\x00\xc6\xdc38\x00\x00\x00\x00\xc7\xca\xe0\xc8\x00\x00\x00\x00Ƚf\xb8\x00\x00\x00\x00ɬ\x14H\x00\x00\x00\x00ʞ\x9a8\x00\x00\x00\x00ˍG\xc8\x00\x00\x00\x00\xcc\x7f\u0378\x00\x00\x00" +
-	"\x00\xcdo\xcc\xc8\x00\x00\x00\x00\xcebR\xb8\x00\x00\x00\x00\xcfQ\x00H\x00\x00\x00\x00\xd0C\x868\x00\x00\x00\x00\xd123\xc8\x00\x00\x00\x00\xd2$\xb9\xb8\x00\x00\x00\x00\xd3\x13gH\x00\x00\x00\x00\xd4\x05\xed" +
-	"8\x00\x00\x00\x00\xd4\xf5\xecH\x00\x00\x00\x00\xd5\xe8r8\x00\x00\x00\x00\xd6\xd7\x1f\xc8\x00\x00\x00\x00\xd7ɥ\xb8\x00\x00\x00\x00ظSH\x00\x00\x00\x00٪\xd98\x00\x00\x00\x00ڙ\x86\xc8\x00\x00\x00" +
-	"\x00ی\f\xb8\x00\x00\x00\x00\xdc|\v\xc8\x00\x00\x00\x00\xddn\x91\xb8\x00\x00\x00\x00\xde]?H\x01\x02\x04\x03\x04\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05" +
-	"\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05" +
-	"\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05" +
-	"\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x00\x0008\x00\x00\x00\x0008" +
-	"\x00\x04\x00\x0018\x00\b\x00\x00FP\x01\x0e\x00\x008@\x00\x12\x00\x00?H\x01\x16LMT\x00TMT\x00+0330\x00+05\x00+04\x00+0430\x00\n<+033" +
-	"0>-3:30<+0430>,J79/24,J263/24\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xc7\x11\xe1[\xdc\x02\x00\x00\xdc\x02\x00\x00\v\x00\x1c\x00" +
-	"Asia/BeirutUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00@\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xffV\xb6¸\xff\xff\xff\xff\xa2ec\xe0\xff\xff\xff\xff\xa3{\x82P\xff\xff\xff\xff\xa4N\x80`\xff\xff\xff\xff\xa5?\xb4\xd0\xff\xff\xff\xff\xa6%" +
-	"'\xe0\xff\xff\xff\xff\xa7'\x7f\xd0\xff\xff\xff\xff\xa8)\xf3\xe0\xff\xff\xff\xff\xa8\xeb\xb2P\xff\xff\xff\xff\xe8*\x85\xe0\xff\xff\xff\xff\xe8\xf4-P\xff\xff\xff\xff\xea\v\xb9`\xff\xff\xff\xff\xea\xd5`\xd0\xff\xff" +
-	"\xff\xff\xeb\xec\xec\xe0\xff\xff\xff\xff추P\xff\xff\xff\xff\xed\xcfq\xe0\xff\xff\xff\xff\xee\x99\x19P\xff\xff\xff\xffﰥ`\xff\xff\xff\xff\xf0zL\xd0\x00\x00\x00\x00\x04\xa6^`\x00\x00\x00\x00\x05+" +
-	"w\xd0\x00\x00\x00\x00\x06C\x03\xe0\x00\x00\x00\x00\a\f\xabP\x00\x00\x00\x00\b$7`\x00\x00\x00\x00\b\xed\xde\xd0\x00\x00\x00\x00\n\x05j\xe0\x00\x00\x00\x00\n\xcf\x12P\x00\x00\x00\x00\v\xe7\xef\xe0\x00\x00" +
-	"\x00\x00\f\xb1\x97P\x00\x00\x00\x00\r\xc9#`\x00\x00\x00\x00\x0e\x92\xca\xd0\x00\x00\x00\x00\x0f\xa9\x05`\x00\x00\x00\x00\x10r\xac\xd0\x00\x00\x00\x00\x1a\xf4.\xe0\x00\x00\x00\x00\x1bќ\xd0\x00\x00\x00\x00\x1c\xd5" +
-	"b`\x00\x00\x00\x00\x1d\xb2\xd0P\x00\x00\x00\x00\x1e\xb6\x95\xe0\x00\x00\x00\x00\x1f\x94\x03\xd0\x00\x00\x00\x00 \x97\xc9`\x00\x00\x00\x00!u7P\x00\x00\x00\x00\"\xa3,\xe0\x00\x00\x00\x00#W\xbcP\x00\x00" +
-	"\x00\x00$g_`\x00\x00\x00\x00%8\xef\xd0\x00\x00\x00\x00&<\xb5`\x00\x00\x00\x00'\x1a#P\x00\x00\x00\x00(\x1d\xe8\xe0\x00\x00\x00\x00(\xfbV\xd0\x00\x00\x00\x00*\x00m\xe0\x00\x00\x00\x00*\xce" +
-	"\t\xd0\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000duP\x00\x00\x00\x001]\xae\xe0\x00\x00" +
-	"\x00\x002M\x91\xd0\x00\x00\x00\x003=\x90\xe0\x00\x00\x00\x004-s\xd0\x00\x00\x00\x005\x1dr\xe0\x00\x00\x00\x006\rU\xd0\x00\x00\x00\x006\xfdT\xe0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00!H\x00\x00\x00\x00*0" +
-	"\x01\x04\x00\x00\x1c \x00\tLMT\x00EEST\x00EET\x00\nEET-2EEST,M3.5.0/0,M10.5.0/0\nPK\x03\x04\n\x00\x00\x00\x00" +
-	"\x00\x8fj\xbeT\xdb\xfa\xb5\xbeg\x02\x00\x00g\x02\x00\x00\v\x00\x1c\x00Asia/AqtobeUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00" +
-	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x8eh\xff\xff\xff\xff\xb5\xa3\xfd@\x00\x00\x00\x00\x15'\x8b\xb0\x00" +
-	"\x00\x00\x00\x16\x18\xc0 \x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c" +
-	"\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L\x1b\xd0\x00\x00\x00\x00#<\f\xd0\x00" +
-	"\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\v\xdf\xd0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\xa3`\x00\x00\x00\x00)" +
-	"\xd4\xdeP\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xc0P\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xa2P\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x84P\x00\x00\x00\x000duP\x00" +
-	"\x00\x00\x001]\xa0\xd0\x00\x00\x00\x002r{\xd0\x00\x00\x00\x003=\x82\xd0\x00\x00\x00\x004R]\xd0\x00\x00\x00\x005\x1dd\xd0\x00\x00\x00\x0062?\xd0\x00\x00\x00\x006\xfdF\xd0\x00\x00\x00\x008" +
-	"\x1b\\P\x00\x00\x00\x008\xdd(\xd0\x00\x00\x00\x009\xfb>P\x00\x00\x00\x00:\xbd\n\xd0\x00\x00\x00\x00;\xdb P\x00\x00\x00\x00<\xa6'P\x00\x00\x00\x00=\xbb\x02P\x00\x00\x00\x00>\x86\tP\x00" +
-	"\x00\x00\x00?\x9a\xe4P\x00\x00\x00\x00@e\xebP\x00\x00\x00\x00A\x84\x00\xd0\x01\x02\x03\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x005\x98\x00\x00\x00\x008@\x00\x04\x00\x00FP\x00\b\x00\x00T`\x01\f\x00\x00T`\x00\f\x00\x00FP\x01\bLMT\x00+04\x00+0" +
-	"5\x00+06\x00\n<+05>-5\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTV\xe0\xe7!\xe7\x02\x00\x00\xe7\x02\x00\x00\v\x00\x1c\x00Asia/AnadyrUT\t\x00" +
-	"\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\a\x00\x00\x00\x14\xff" +
-	"\xff\xff\xff\xaa\x19\x1d\x9c\xff\xff\xff\xff\xb5\xa3\x8c\xc0\x00\x00\x00\x00\x15'\x1b0\x00\x00\x00\x00\x16\x18O\xa0\x00\x00\x00\x00\x17\bN\xb0\x00\x00\x00\x00\x17\xf9\x910\x00\x00\x00\x00\x18\xe9\x90@\x00\x00\x00\x00\x19" +
-	"\xdaİ\x00\x00\x00\x00\x1a\xcc\x15@\x00\x00\x00\x00\x1b\xbc\"`\x00\x00\x00\x00\x1c\xac\x13`\x00\x00\x00\x00\x1d\x9c\x04`\x00\x00\x00\x00\x1e\x8b\xf5`\x00\x00\x00\x00\x1f{\xe6`\x00\x00\x00\x00 k\xd7`\x00" +
-	"\x00\x00\x00![\xc8`\x00\x00\x00\x00\"K\xb9`\x00\x00\x00\x00#;\xaa`\x00\x00\x00\x00$+\x9b`\x00\x00\x00\x00%\x1b\x8c`\x00\x00\x00\x00&\v}`\x00\x00\x00\x00'\x04\xa8\xe0\x00\x00\x00\x00'" +
-	"\xf4\x99\xe0\x00\x00\x00\x00(\xe4\x98\xf0\x00\x00\x00\x00)x@\xf0\x00\x00\x00\x00)\xd4{\xe0\x00\x00\x00\x00*\xc4l\xe0\x00\x00\x00\x00+\xb4]\xe0\x00\x00\x00\x00,\xa4N\xe0\x00\x00\x00\x00-\x94?\xe0\x00" +
-	"\x00\x00\x00.\x840\xe0\x00\x00\x00\x00/t!\xe0\x00\x00\x00\x000d\x12\xe0\x00\x00\x00\x001]>`\x00\x00\x00\x002r\x19`\x00\x00\x00\x003= `\x00\x00\x00\x004Q\xfb`\x00\x00\x00\x005" +
-	"\x1d\x02`\x00\x00\x00\x0061\xdd`\x00\x00\x00\x006\xfc\xe4`\x00\x00\x00\x008\x1a\xf9\xe0\x00\x00\x00\x008\xdc\xc6`\x00\x00\x00\x009\xfa\xdb\xe0\x00\x00\x00\x00:\xbc\xa8`\x00\x00\x00\x00;ڽ\xe0\x00" +
-	"\x00\x00\x00<\xa5\xc4\xe0\x00\x00\x00\x00=\xba\x9f\xe0\x00\x00\x00\x00>\x85\xa6\xe0\x00\x00\x00\x00?\x9a\x81\xe0\x00\x00\x00\x00@e\x88\xe0\x00\x00\x00\x00A\x83\x9e`\x00\x00\x00\x00BEj\xe0\x00\x00\x00\x00C" +
-	"c\x80`\x00\x00\x00\x00D%L\xe0\x00\x00\x00\x00ECb`\x00\x00\x00\x00F\x05.\xe0\x00\x00\x00\x00G#D`\x00\x00\x00\x00G\xeeK`\x00\x00\x00\x00I\x03&`\x00\x00\x00\x00I\xce-`\x00" +
-	"\x00\x00\x00J\xe3\b`\x00\x00\x00\x00K\xae\x0f`\x00\x00\x00\x00L\xcc2\xf0\x00\x00\x00\x00M\x8d\xffp\x01\x03\x02\x03\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x05\x06\x01\x04\x01\x04\x01" +
-	"\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x05\x06\x01\x00\x00\xa6d\x00\x00\x00\x00\xa8\xc0\x00\x04\x00\x00\xc4\xe0\x01\b\x00\x00\xb6\xd0\x00\f\x00" +
-	"\x00\xb6\xd0\x01\f\x00\x00\xa8\xc0\x01\x04\x00\x00\x9a\xb0\x00\x10LMT\x00+12\x00+14\x00+13\x00+11\x00\n<+12>-12\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbe" +
-	"T0]*\x1bj\x02\x00\x00j\x02\x00\x00\f\x00\x1c\x00Asia/BishkekUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZi" +
-	"f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x004\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19~\x10\xff\xff\xff\xff\xb5\xa3\xef0\x00\x00\x00\x00\x15'}\xa0\x00\x00\x00\x00" +
-	"\x16\x18\xb2\x10\x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xe5\x90\x00\x00\x00\x00\x18\xe9\xe4\xa0\x00\x00\x00\x00\x19\xdb\x19\x10\x00\x00\x00\x00\x1a\xcci\xa0\x00\x00\x00\x00\x1b\xbcv\xc0\x00\x00\x00\x00\x1c\xacg\xc0" +
-	"\x00\x00\x00\x00\x1d\x9cX\xc0\x00\x00\x00\x00\x1e\x8cI\xc0\x00\x00\x00\x00\x1f|:\xc0\x00\x00\x00\x00 l+\xc0\x00\x00\x00\x00!\\\x1c\xc0\x00\x00\x00\x00\"L\r\xc0\x00\x00\x00\x00#;\xfe\xc0\x00\x00\x00\x00" +
-	"$+\xef\xc0\x00\x00\x00\x00%\x1b\xe0\xc0\x00\x00\x00\x00&\v\xd1\xc0\x00\x00\x00\x00'\x04\xfd@\x00\x00\x00\x00'\xf4\xee@\x00\x00\x00\x00(\xbe\xa3\xc0\x00\x00\x00\x00)\xe770\x00\x00\x00\x00*ĥ " +
-	"\x00\x00\x00\x00+\xc7\x190\x00\x00\x00\x00,\xa4\x87 \x00\x00\x00\x00-\xa6\xfb0\x00\x00\x00\x00.\x84i \x00\x00\x00\x00/\x86\xdd0\x00\x00\x00\x000dK \x00\x00\x00\x001f\xbf0\x00\x00\x00\x00" +
-	"2Mg\xa0\x00\x00\x00\x003=\x89\xd8\x00\x00\x00\x004RV\xc8\x00\x00\x00\x005\x1dk\xd8\x00\x00\x00\x00628\xc8\x00\x00\x00\x006\xfdM\xd8\x00\x00\x00\x008\x1bUH\x00\x00\x00\x008\xdd/\xd8" +
-	"\x00\x00\x00\x009\xfb7H\x00\x00\x00\x00:\xbd\x11\xd8\x00\x00\x00\x00;\xdb\x19H\x00\x00\x00\x00<\xa6.X\x00\x00\x00\x00=\xba\xfbH\x00\x00\x00\x00>\x86\x10X\x00\x00\x00\x00?\x9a\xddH\x00\x00\x00\x00" +
-	"@e\xf2X\x00\x00\x00\x00A\x83\xf9\xc8\x00\x00\x00\x00BE\xd4X\x00\x00\x00\x00B\xfb\x92 \x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01" +
-	"\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x03\x00\x00E\xf0\x00\x00\x00\x00FP\x00\x04\x00\x00bp\x01\b\x00\x00T`\x00\f\x00\x00T`\x01\fLMT\x00+05\x00+0" +
-	"7\x00+06\x00\n<+06>-6\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xed\x8c\xf1\x91\x85\x00\x00\x00\x85\x00\x00\x00\n\x00\x1c\x00Asia/DubaiUT\t\x00\x03" +
-	"\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff" +
-	"\xff\xff\xa1\xf2\x99\xa8\x01\x00\x003\xd8\x00\x00\x00\x008@\x00\x04LMT\x00+04\x00\n<+04>-4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xcfׇ\xe1\x85\x00\x00\x00\x85\x00" +
-	"\x00\x00\v\x00\x1c\x00Asia/RiyadhUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xd5\x1b6\xb4\x01\x00\x00+\xcc\x00\x00\x00\x00*0\x00\x04LMT\x00+03\x00\n<+03>-3\nPK" +
-	"\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x8a\x9a\x90\xf7\xd6\x02\x00\x00\xd6\x02\x00\x00\x11\x00\x1c\x00Asia/NovokuznetskUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux" +
-	"\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00" +
-	"\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x18 \xc0\xff\xff\xff\xff" +
-	"\xb5\xa3\xe1 \x00\x00\x00\x00\x15'o\x90\x00\x00\x00\x00\x16\x18\xa4\x00\x00\x00\x00\x00\x17\b\xa3\x10\x00\x00\x00\x00\x17\xf9׀\x00\x00\x00\x00\x18\xe9\u0590\x00\x00\x00\x00\x19\xdb\v\x00\x00\x00\x00\x00\x1a\xcc[\x90" +
-	"\x00\x00\x00\x00\x1b\xbch\xb0\x00\x00\x00\x00\x1c\xacY\xb0\x00\x00\x00\x00\x1d\x9cJ\xb0\x00\x00\x00\x00\x1e\x8c;\xb0\x00\x00\x00\x00\x1f|,\xb0\x00\x00\x00\x00 l\x1d\xb0\x00\x00\x00\x00!\\\x0e\xb0\x00\x00\x00\x00" +
-	"\"K\xff\xb0\x00\x00\x00\x00#;\xf0\xb0\x00\x00\x00\x00$+\xe1\xb0\x00\x00\x00\x00%\x1bҰ\x00\x00\x00\x00&\vð\x00\x00\x00\x00'\x04\xef0\x00\x00\x00\x00'\xf4\xe00\x00\x00\x00\x00(\xe4\xdf@" +
-	"\x00\x00\x00\x00)x\x87@\x00\x00\x00\x00)\xd4\xc20\x00\x00\x00\x00*ij0\x00\x00\x00\x00+\xb4\xa40\x00\x00\x00\x00,\xa4\x950\x00\x00\x00\x00-\x94\x860\x00\x00\x00\x00.\x84w0\x00\x00\x00\x00" +
-	"/th0\x00\x00\x00\x000dY0\x00\x00\x00\x001]\x84\xb0\x00\x00\x00\x002r_\xb0\x00\x00\x00\x003=f\xb0\x00\x00\x00\x004RA\xb0\x00\x00\x00\x005\x1dH\xb0\x00\x00\x00\x0062#\xb0" +
-	"\x00\x00\x00\x006\xfd*\xb0\x00\x00\x00\x008\x1b@0\x00\x00\x00\x008\xdd\f\xb0\x00\x00\x00\x009\xfb\"0\x00\x00\x00\x00:\xbc\xee\xb0\x00\x00\x00\x00;\xdb\x040\x00\x00\x00\x00<\xa6\v0\x00\x00\x00\x00" +
-	"=\xba\xe60\x00\x00\x00\x00>\x85\xed0\x00\x00\x00\x00?\x9a\xc80\x00\x00\x00\x00@e\xcf0\x00\x00\x00\x00A\x83\xe4\xb0\x00\x00\x00\x00BE\xb10\x00\x00\x00\x00Ccư\x00\x00\x00\x00D%\x930" +
-	"\x00\x00\x00\x00EC\xa8\xb0\x00\x00\x00\x00F\x05u0\x00\x00\x00\x00G#\x8a\xb0\x00\x00\x00\x00G\ue470\x00\x00\x00\x00I\x03l\xb0\x00\x00\x00\x00I\xces\xb0\x00\x00\x00\x00J\xe3N\xb0\x00\x00\x00\x00" +
-	"K\xaeU\xb0\x00\x00\x00\x00L\xccy@\x00\x00\x00\x00M\x8eE\xc0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x00\x00Q\xc0\x00\x00\x00\x00T`\x00\x04\x00\x00p\x80\x01\b\x00\x00bp\x00\f\x00\x00bp\x01\fLMT\x00+0" +
-	"6\x00+08\x00+07\x00\n<+07>-7\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTT\x81\x18G^\x02\x00\x00^\x02\x00\x00\n\x00\x1c\x00Asia/AqtauU" +
-	"T\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x002\x00\x00\x00\x06\x00\x00" +
-	"\x00\x10\xff\xff\xff\xff\xaa\x19\x94\xe0\xff\xff\xff\xff\xb5\xa3\xfd@\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00" +
-	"\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\\" +
-	"*\xd0\x00\x00\x00\x00\"L\x1b\xd0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\v\xdf\xd0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf4\xfcP\x00\x00" +
-	"\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\xa3`\x00\x00\x00\x00)\xd4\xdeP\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xc0P\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xa2P\x00\x00\x00\x00.\x84" +
-	"\x93P\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000d\x83`\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002r\x89\xe0\x00\x00\x00\x003=\x90\xe0\x00\x00\x00\x004Rk\xe0\x00\x00\x00\x005\x1dr\xe0\x00\x00" +
-	"\x00\x0062M\xe0\x00\x00\x00\x006\xfdT\xe0\x00\x00\x00\x008\x1bj`\x00\x00\x00\x008\xdd6\xe0\x00\x00\x00\x009\xfbL`\x00\x00\x00\x00:\xbd\x18\xe0\x00\x00\x00\x00;\xdb.`\x00\x00\x00\x00<\xa6" +
-	"5`\x00\x00\x00\x00=\xbb\x10`\x00\x00\x00\x00>\x86\x17`\x00\x00\x00\x00?\x9a\xf2`\x00\x00\x00\x00@e\xf9`\x00\x00\x00\x00A\x84\x0e\xe0\x01\x02\x03\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04" +
-	"\x02\x04\x02\x05\x01\x02\x04\x02\x04\x02\x04\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x02\x00\x00/ \x00\x00\x00\x008@\x00\x04\x00\x00FP\x00\b\x00\x00T`\x00\f\x00\x00T`" +
-	"\x01\f\x00\x00FP\x01\bLMT\x00+04\x00+05\x00+06\x00\n<+05>-5\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT:\x11\xea\xa2\xe5\x02\x00\x00\xe5\x02\x00\x00\t" +
-	"\x00\x1c\x00Asia/OmskUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00A\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xb3@\xb6\xff\xff\xff\xff\xb5\xa3\xef0\x00\x00\x00\x00\x15'}\xa0\x00\x00\x00\x00\x16\x18\xb2\x10\x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17" +
-	"\xf9\xe5\x90\x00\x00\x00\x00\x18\xe9\xe4\xa0\x00\x00\x00\x00\x19\xdb\x19\x10\x00\x00\x00\x00\x1a\xcci\xa0\x00\x00\x00\x00\x1b\xbcv\xc0\x00\x00\x00\x00\x1c\xacg\xc0\x00\x00\x00\x00\x1d\x9cX\xc0\x00\x00\x00\x00\x1e\x8cI\xc0\x00" +
-	"\x00\x00\x00\x1f|:\xc0\x00\x00\x00\x00 l+\xc0\x00\x00\x00\x00!\\\x1c\xc0\x00\x00\x00\x00\"L\r\xc0\x00\x00\x00\x00#;\xfe\xc0\x00\x00\x00\x00$+\xef\xc0\x00\x00\x00\x00%\x1b\xe0\xc0\x00\x00\x00\x00&" +
-	"\v\xd1\xc0\x00\x00\x00\x00'\x04\xfd@\x00\x00\x00\x00'\xf4\xee@\x00\x00\x00\x00(\xe4\xedP\x00\x00\x00\x00)x\x95P\x00\x00\x00\x00)\xd4\xd0@\x00\x00\x00\x00*\xc4\xc1@\x00\x00\x00\x00+\xb4\xb2@\x00" +
-	"\x00\x00\x00,\xa4\xa3@\x00\x00\x00\x00-\x94\x94@\x00\x00\x00\x00.\x84\x85@\x00\x00\x00\x00/tv@\x00\x00\x00\x000dg@\x00\x00\x00\x001]\x92\xc0\x00\x00\x00\x002rm\xc0\x00\x00\x00\x003" +
-	"=t\xc0\x00\x00\x00\x004RO\xc0\x00\x00\x00\x005\x1dV\xc0\x00\x00\x00\x00621\xc0\x00\x00\x00\x006\xfd8\xc0\x00\x00\x00\x008\x1bN@\x00\x00\x00\x008\xdd\x1a\xc0\x00\x00\x00\x009\xfb0@\x00" +
-	"\x00\x00\x00:\xbc\xfc\xc0\x00\x00\x00\x00;\xdb\x12@\x00\x00\x00\x00<\xa6\x19@\x00\x00\x00\x00=\xba\xf4@\x00\x00\x00\x00>\x85\xfb@\x00\x00\x00\x00?\x9a\xd6@\x00\x00\x00\x00@e\xdd@\x00\x00\x00\x00A" +
-	"\x83\xf2\xc0\x00\x00\x00\x00BE\xbf@\x00\x00\x00\x00Cc\xd4\xc0\x00\x00\x00\x00D%\xa1@\x00\x00\x00\x00EC\xb6\xc0\x00\x00\x00\x00F\x05\x83@\x00\x00\x00\x00G#\x98\xc0\x00\x00\x00\x00G\xee\x9f\xc0\x00" +
-	"\x00\x00\x00I\x03z\xc0\x00\x00\x00\x00I\u0381\xc0\x00\x00\x00\x00J\xe3\\\xc0\x00\x00\x00\x00K\xaec\xc0\x00\x00\x00\x00L\xccy@\x00\x00\x00\x00M\x8eE\xc0\x00\x00\x00\x00TK\xf30\x01\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x03" +
-	"\x00\x00D\xca\x00\x00\x00\x00FP\x00\x04\x00\x00bp\x01\b\x00\x00T`\x00\f\x00\x00T`\x01\f\x00\x00bp\x00\bLMT\x00+05\x00+07\x00+06\x00\n<+06>-6" +
-	"\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTe\x1bb2w\x01\x00\x00w\x01\x00\x00\x0e\x00\x1c\x00Asia/AshkhabadUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux" +
-	"\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00" +
-	"\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x19\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x8dD\xff\xff\xff\xff" +
-	"\xb5\xa3\xfd@\x00\x00\x00\x00\x15'\x8b\xb0\x00\x00\x00\x00\x16\x18\xc0 \x00\x00\x00\x00\x17\b\xbf0\x00\x00\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0" +
-	"\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00" +
-	"\"L\x1b\xd0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\v\xdf\xd0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xfb`" +
-	"\x00\x00\x00\x00)x\xa3`\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x00\x006\xbc\x00\x00\x00\x008@\x00\x04\x00\x00T`\x01\b\x00\x00FP\x00\f\x00\x00F" +
-	"P\x01\fLMT\x00+04\x00+06\x00+05\x00\n<+05>-5\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x84)\r\xbd\xec\x00\x00\x00\xec\x00\x00\x00\v\x00\x1c\x00As" +
-	"ia/SaigonUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\t\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xff\x88\x8cC\x80\xff\xff\xff\xff\x91\xa3+\n\xff\xff\xff\xff\xcd5\xe6\x80\xff\xff\xff\xff\xd1Y\xcep\xff\xff\xff\xff\xd2;>\xf0\xff\xff\xff\xff\xd52\xbb\x10" +
-	"\xff\xff\xff\xff\xe4\xb6\xe4\x80\xff\xff\xff\xff\xed/\x98\x00\x00\x00\x00\x00\n=\xc7\x00\x01\x02\x03\x04\x02\x03\x02\x03\x02\x00\x00d\x00\x00\x00\x00\x00c\xf6\x00\x04\x00\x00bp\x00\t\x00\x00p\x80\x00\r\x00\x00~" +
-	"\x90\x00\x11LMT\x00PLMT\x00+07\x00+08\x00+09\x00\n<+07>-7\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT)\x15II\xf3\x02\x00\x00\xf3\x02\x00\x00\r" +
-	"\x00\x1c\x00Asia/SakhalinUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xff\x86\xf0\u0378\xff\xff\xff\xff\xd20\xb2\xf0\x00\x00\x00\x00\x15'7P\x00\x00\x00\x00\x16\x18k\xc0\x00\x00\x00\x00\x17\bj\xd0\x00" +
-	"\x00\x00\x00\x17\xf9\x9f@\x00\x00\x00\x00\x18\xe9\x9eP\x00\x00\x00\x00\x19\xda\xd2\xc0\x00\x00\x00\x00\x1a\xcc#P\x00\x00\x00\x00\x1b\xbc0p\x00\x00\x00\x00\x1c\xac!p\x00\x00\x00\x00\x1d\x9c\x12p\x00\x00\x00\x00\x1e" +
-	"\x8c\x03p\x00\x00\x00\x00\x1f{\xf4p\x00\x00\x00\x00 k\xe5p\x00\x00\x00\x00![\xd6p\x00\x00\x00\x00\"K\xc7p\x00\x00\x00\x00#;\xb8p\x00\x00\x00\x00$+\xa9p\x00\x00\x00\x00%\x1b\x9ap\x00" +
-	"\x00\x00\x00&\v\x8bp\x00\x00\x00\x00'\x04\xb6\xf0\x00\x00\x00\x00'\xf4\xa7\xf0\x00\x00\x00\x00(\xe4\xa7\x00\x00\x00\x00\x00)xO\x00\x00\x00\x00\x00)ԉ\xf0\x00\x00\x00\x00*\xc4z\xf0\x00\x00\x00\x00+" +
-	"\xb4k\xf0\x00\x00\x00\x00,\xa4\\\xf0\x00\x00\x00\x00-\x94M\xf0\x00\x00\x00\x00.\x84>\xf0\x00\x00\x00\x00/t/\xf0\x00\x00\x00\x000d \xf0\x00\x00\x00\x001]Lp\x00\x00\x00\x002r'p\x00" +
-	"\x00\x00\x003=.p\x00\x00\x00\x004R\x17\x80\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x0061\xf9\x80\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x008\x1b\x16\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009" +
-	"\xfa\xf8\x00\x00\x00\x00\x00:\xbcĀ\x00\x00\x00\x00;\xda\xda\x00\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\xba\xbc\x00\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?\x9a\x9e\x00\x00\x00\x00\x00@e\xa5\x00\x00" +
-	"\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D%i\x00\x00\x00\x00\x00EC~\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G" +
-	"\xeeg\x80\x00\x00\x00\x00I\x03B\x80\x00\x00\x00\x00I\xceI\x80\x00\x00\x00\x00J\xe3$\x80\x00\x00\x00\x00K\xae+\x80\x00\x00\x00\x00L\xccA\x00\x00\x00\x00\x00M\x8e\r\x80\x00\x00\x00\x00TK\xba\xf0\x00" +
-	"\x00\x00\x00V\xf6\xb2\x00\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x05\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" +
-	"\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x03\x05\x03\x00\x00\x85\xc8\x00\x00\x00\x00~\x90\x00\x04\x00\x00\xa8\xc0\x01\b\x00\x00\x9a\xb0\x00\f\x00\x00\x9a\xb0\x01\f\x00\x00\x8c\xa0\x00\x10LMT\x00+09\x00+12" +
-	"\x00+11\x00+10\x00\n<+11>-11\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeTE\t\xfa-\a\x03\x00\x00\a\x03\x00\x00\x0e\x00\x1c\x00Asia/Hong_K" +
-	"ongUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\x00\x00" +
-	"\x00\x05\x00\x00\x00\x16\xff\xff\xff\xff\x85ic\x90\xff\xff\xff\xff\xcaM10\xff\xff\xff\xff\xcaۓ0\xff\xff\xff\xff\xcbKqx\xff\xff\xff\xffҠސ\xff\xff\xff\xff\xd3k׀\xff\xff\xff\xffԓ" +
-	"X\xb8\xff\xff\xff\xff\xd5B\xb08\xff\xff\xff\xff\xd6s:\xb8\xff\xff\xff\xff\xd7>A\xb8\xff\xff\xff\xff\xd8.2\xb8\xff\xff\xff\xff\xd8\xf99\xb8\xff\xff\xff\xff\xda\x0e\x14\xb8\xff\xff\xff\xff\xda\xd9\x1b\xb8\xff\xff" +
-	"\xff\xff\xdb\xed\xf6\xb8\xff\xff\xff\xffܸ\xfd\xb8\xff\xff\xff\xff\xdd\xcdظ\xff\xff\xff\xffޢ\x1a8\xff\xff\xff\xff߶\xf58\xff\xff\xff\xff\xe0\x81\xfc8\xff\xff\xff\xff\xe1\x96\xc9(\xff\xff\xff\xff\xe2O" +
-	"i8\xff\xff\xff\xff\xe3v\xab(\xff\xff\xff\xff\xe4/K8\xff\xff\xff\xff\xe5_Ǩ\xff\xff\xff\xff\xe6\x0f-8\xff\xff\xff\xff\xe7?\xa9\xa8\xff\xff\xff\xff\xe7\xf8I\xb8\xff\xff\xff\xff\xe9\x1f\x8b\xa8\xff\xff" +
-	"\xff\xff\xe9\xd8+\xb8\xff\xff\xff\xff\xea\xffm\xa8\xff\xff\xff\xff\xeb\xb8\r\xb8\xff\xff\xff\xff\xec\xdfO\xa8\xff\xff\xff\xff\xed\x97\xef\xb8\xff\xff\xff\xff\xee\xc8l(\xff\xff\xff\xff\xefwѸ\xff\xff\xff\xff\xf0\xa8" +
-	"N(\xff\xff\xff\xff\xf1W\xb3\xb8\xff\xff\xff\xff\xf2\x880(\xff\xff\xff\xff\xf3@\xd08\xff\xff\xff\xff\xf4h\x12(\xff\xff\xff\xff\xf5 \xb28\xff\xff\xff\xff\xf6G\xf4(\xff\xff\xff\xff\xf7%~8\xff\xff" +
-	"\xff\xff\xf8\x15a(\xff\xff\xff\xff\xf9\x05`8\xff\xff\xff\xff\xf9\xf5C(\xff\xff\xff\xff\xfa\xe5B8\xff\xff\xff\xff\xfb\xde_\xa8\xff\xff\xff\xff\xfc\xce^\xb8\xff\xff\xff\xff\xfd\xbeA\xa8\xff\xff\xff\xff\xfe\xae" +
-	"@\xb8\xff\xff\xff\xff\xff\x9e#\xa8\x00\x00\x00\x00\x00\x8e\"\xb8\x00\x00\x00\x00\x01~\x05\xa8\x00\x00\x00\x00\x02n\x04\xb8\x00\x00\x00\x00\x03]\xe7\xa8\x00\x00\x00\x00\x04M\xe6\xb8\x00\x00\x00\x00\x05G\x04(\x00\x00" +
-	"\x00\x00\x067\x038\x00\x00\x00\x00\a&\xe6(\x00\x00\x00\x00\a\x83=8\x00\x00\x00\x00\t\x06\xc8(\x00\x00\x00\x00\t\xf6\xc78\x00\x00\x00\x00\n\xe6\xaa(\x00\x00\x00\x00\v֩8\x00\x00\x00\x00\f\xc6" +
-	"\x8c(\x00\x00\x00\x00\x11\x9b98\x00\x00\x00\x00\x12ol\xa8\x01\x02\x03\x04\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00k\n\x00\x00\x00\x00p\x80\x00\x04\x00\x00~\x90\x01\b\x00\x00w\x88\x01\r\x00\x00~\x90\x00\x12LMT" +
-	"\x00HKT\x00HKST\x00HKWT\x00JST\x00\nHKT-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x88\xf6C\x84\x98\x00\x00\x00\x98\x00\x00\x00\x0f\x00\x1c\x00Asia" +
-	"/Phnom_PenhUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xffV\xb6\x85\xc4\xff\xff\xff\xff\xa2jg\xc4\x01\x02\x00\x00^<\x00\x00\x00\x00^<\x00\x04\x00\x00bp\x00\bLMT\x00BMT\x00+0" +
-	"7\x00\n<+07>-7\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\x03R\xda\xedU\x02\x00\x00U\x02\x00\x00\f\x00\x1c\x00Asia/NicosiaUT\t\x00\x03\xdc\xfc" +
-	"\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x001\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xff" +
-	"\xa5w\x1e\xb8\x00\x00\x00\x00\t\xed\xaf\xe0\x00\x00\x00\x00\nݒ\xd0\x00\x00\x00\x00\v\xfad\xe0\x00\x00\x00\x00\f\xbe\xc6P\x00\x00\x00\x00\r\xa49`\x00\x00\x00\x00\x0e\x8a\xe1\xd0\x00\x00\x00\x00\x0f\x84\x1b`" +
-	"\x00\x00\x00\x00\x10uO\xd0\x00\x00\x00\x00\x11c\xfd`\x00\x00\x00\x00\x12S\xe0P\x00\x00\x00\x00\x13M\x19\xe0\x00\x00\x00\x00\x143\xc2P\x00\x00\x00\x00\x15#\xc1`\x00\x00\x00\x00\x16\x13\xa4P\x00\x00\x00\x00" +
-	"\x17\x03\xa3`\x00\x00\x00\x00\x17\xf3\x86P\x00\x00\x00\x00\x18\xe3\x85`\x00\x00\x00\x00\x19\xd3hP\x00\x00\x00\x00\x1a\xc3g`\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9cf\xd0" +
-	"\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$,\v\xe0\x00\x00\x00\x00" +
-	"%\x1b\xee\xd0\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf5\n`\x00\x00\x00\x00(\xe4\xedP\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xce`" +
-	"\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000duP\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002M\x91\xd0\x00\x00\x00\x00" +
-	"3=\x90\xe0\x00\x00\x00\x004-s\xd0\x00\x00\x00\x005\x1dr\xe0\x00\x00\x00\x0062x\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x1fH\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\tLMT\x00EEST\x00EET\x00\nEET-2EEST,M" +
-	"3.5.0/3,M10.5.0/4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xd7e&uv\x02\x00\x00v\x02\x00\x00\f\x00\x1c\x00Asia/Baghdad" +
-	"UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x006\x00\x00\x00\x04\x00" +
-	"\x00\x00\x10\xff\xff\xff\xffi\x86\xb1\xdc\xff\xff\xff\xff\x9e0<\xe0\x00\x00\x00\x00\x170hP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xe8\xbdP\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00" +
-	"\x00\x00\x00\x1b\xbd\xc8@\x00\x00\x00\x00\x1c\xad\xc7P\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\8\xe0\x00\x00\x00\x00\"" +
-	"L)\xe0\x00\x00\x00\x00#<\x1a\xe0\x00\x00\x00\x00$,\v\xe0\x00\x00\x00\x00%\x1b\xfc\xe0\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00'\x05\x19`\x00\x00\x00\x00'\xf6x\x00\x00\x00\x00\x00(纀\x00" +
-	"\x00\x00\x00)\xd8\xfd\x00\x00\x00\x00\x00*\xca?\x80\x00\x00\x00\x00+\xba0\x80\x00\x00\x00\x00,\xabs\x00\x00\x00\x00\x00-\x9bd\x00\x00\x00\x00\x00.\x8c\xa6\x80\x00\x00\x00\x00/|\x97\x80\x00\x00\x00\x000" +
-	"m\xda\x00\x00\x00\x00\x001_\x1c\x80\x00\x00\x00\x002P_\x00\x00\x00\x00\x003@P\x00\x00\x00\x00\x0041\x92\x80\x00\x00\x00\x005!\x83\x80\x00\x00\x00\x006\x12\xc6\x00\x00\x00\x00\x007\x02\xb7\x00\x00" +
-	"\x00\x00\x007\xf3\xf9\x80\x00\x00\x00\x008\xe5<\x00\x00\x00\x00\x009\xd6~\x80\x00\x00\x00\x00:\xc6o\x80\x00\x00\x00\x00;\xb7\xb2\x00\x00\x00\x00\x00<\xa7\xa3\x00\x00\x00\x00\x00=\x98\xe5\x80\x00\x00\x00\x00>" +
-	"\x88ր\x00\x00\x00\x00?z\x19\x00\x00\x00\x00\x00@k[\x80\x00\x00\x00\x00A\\\x9e\x00\x00\x00\x00\x00BL\x8f\x00\x00\x00\x00\x00C=р\x00\x00\x00\x00D-\u0080\x00\x00\x00\x00E\x1f\x05\x00\x00" +
-	"\x00\x00\x00F\x0e\xf6\x00\x00\x00\x00\x00G\x008\x80\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
-	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00)\xa4\x00\x00\x00\x00)\xa0\x00\x04\x00\x00*0\x00\b\x00\x008@\x01\fLMT\x00BMT\x00+03\x00+04\x00\n<+03>-3\nPK" +
-	"\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xa4Zߐ\xe6\x02\x00\x00\xe6\x02\x00\x00\x12\x00\x1c\x00Asia/SrednekolymskUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bu" +
-	"x\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00" +
-	"\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00A\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x193\xe4\xff\xff\xff" +
-	"\xff\xb5\xa3\xa8\xe0\x00\x00\x00\x00\x15'7P\x00\x00\x00\x00\x16\x18k\xc0\x00\x00\x00\x00\x17\bj\xd0\x00\x00\x00\x00\x17\xf9\x9f@\x00\x00\x00\x00\x18\xe9\x9eP\x00\x00\x00\x00\x19\xda\xd2\xc0\x00\x00\x00\x00\x1a\xcc#" +
-	"P\x00\x00\x00\x00\x1b\xbc0p\x00\x00\x00\x00\x1c\xac!p\x00\x00\x00\x00\x1d\x9c\x12p\x00\x00\x00\x00\x1e\x8c\x03p\x00\x00\x00\x00\x1f{\xf4p\x00\x00\x00\x00 k\xe5p\x00\x00\x00\x00![\xd6p\x00\x00\x00" +
-	"\x00\"K\xc7p\x00\x00\x00\x00#;\xb8p\x00\x00\x00\x00$+\xa9p\x00\x00\x00\x00%\x1b\x9ap\x00\x00\x00\x00&\v\x8bp\x00\x00\x00\x00'\x04\xb6\xf0\x00\x00\x00\x00'\xf4\xa7\xf0\x00\x00\x00\x00(\xe4\xa7" +
-	"\x00\x00\x00\x00\x00)xO\x00\x00\x00\x00\x00)ԉ\xf0\x00\x00\x00\x00*\xc4z\xf0\x00\x00\x00\x00+\xb4k\xf0\x00\x00\x00\x00,\xa4\\\xf0\x00\x00\x00\x00-\x94M\xf0\x00\x00\x00\x00.\x84>\xf0\x00\x00\x00" +
-	"\x00/t/\xf0\x00\x00\x00\x000d \xf0\x00\x00\x00\x001]Lp\x00\x00\x00\x002r'p\x00\x00\x00\x003=.p\x00\x00\x00\x004R\tp\x00\x00\x00\x005\x1d\x10p\x00\x00\x00\x0061\xeb" +
-	"p\x00\x00\x00\x006\xfc\xf2p\x00\x00\x00\x008\x1b\a\xf0\x00\x00\x00\x008\xdc\xd4p\x00\x00\x00\x009\xfa\xe9\xf0\x00\x00\x00\x00:\xbc\xb6p\x00\x00\x00\x00;\xda\xcb\xf0\x00\x00\x00\x00<\xa5\xd2\xf0\x00\x00\x00" +
-	"\x00=\xba\xad\xf0\x00\x00\x00\x00>\x85\xb4\xf0\x00\x00\x00\x00?\x9a\x8f\xf0\x00\x00\x00\x00@e\x96\xf0\x00\x00\x00\x00A\x83\xacp\x00\x00\x00\x00BEx\xf0\x00\x00\x00\x00Cc\x8ep\x00\x00\x00\x00D%Z" +
-	"\xf0\x00\x00\x00\x00ECpp\x00\x00\x00\x00F\x05<\xf0\x00\x00\x00\x00G#Rp\x00\x00\x00\x00G\xeeYp\x00\x00\x00\x00I\x034p\x00\x00\x00\x00I\xce;p\x00\x00\x00\x00J\xe3\x16p\x00\x00\x00" +
-	"\x00K\xae\x1dp\x00\x00\x00\x00L\xcc2\xf0\x00\x00\x00\x00M\x8d\xffp\x00\x00\x00\x00TK\xac\xe0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03" +
-	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x03\x00\x00\x90\x1c\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00\xa8\xc0\x01\b\x00\x00\x9a\xb0\x00\f\x00\x00" +
-	"\x9a\xb0\x01\f\x00\x00\xa8\xc0\x00\bLMT\x00+10\x00+12\x00+11\x00\n<+11>-11\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTe\x1bb2w\x01\x00\x00w\x01" +
-	"\x00\x00\r\x00\x1c\x00Asia/AshgabatUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x19\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x8dD\xff\xff\xff\xff\xb5\xa3\xfd@\x00\x00\x00\x00\x15'\x8b\xb0\x00\x00\x00\x00\x16\x18\xc0 \x00\x00\x00\x00\x17\b" +
-	"\xbf0\x00\x00\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00" +
-	"\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L\x1b\xd0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b" +
-	"\xee\xd0\x00\x00\x00\x00&\v\xdf\xd0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\xa3`\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
-	"\x02\x03\x02\x03\x04\x01\x03\x00\x006\xbc\x00\x00\x00\x008@\x00\x04\x00\x00T`\x01\b\x00\x00FP\x00\f\x00\x00FP\x01\fLMT\x00+04\x00+06\x00+05\x00\n<+05>-" +
-	"5\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x8bSnT\xa1\x00\x00\x00\xa1\x00\x00\x00\x0e\x00\x1c\x00Asia/KathmanduUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bu" +
-	"x\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00" +
-	"\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xf2}\x84\x00\x00\x00" +
-	"\x00\x1e\x180\xa8\x01\x02\x00\x00O\xfc\x00\x00\x00\x00MX\x00\x04\x00\x00P\xdc\x00\nLMT\x00+0530\x00+0545\x00\n<+0545>-5:45\nPK\x03\x04\n" +
-	"\x00\x00\x00\x00\x00\x8fj\xbeT\x81z&\x80k\x02\x00\x00k\x02\x00\x00\x0f\x00\x1c\x00Asia/ChoibalsanUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91" +
-	"\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00T" +
-	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xff\x86\xd3\xe7(\x00\x00\x00\x00\x0f\vܐ\x00" +
-	"\x00\x00\x00\x18\xe9Ȁ\x00\x00\x00\x00\x19\xda\xee\xe0\x00\x00\x00\x00\x1a\xcc?p\x00\x00\x00\x00\x1b\xbc\"`\x00\x00\x00\x00\x1c\xac!p\x00\x00\x00\x00\x1d\x9c\x04`\x00\x00\x00\x00\x1e\x8c\x03p\x00\x00\x00\x00\x1f" +
-	"{\xe6`\x00\x00\x00\x00 k\xe5p\x00\x00\x00\x00![\xc8`\x00\x00\x00\x00\"K\xc7p\x00\x00\x00\x00#;\xaa`\x00\x00\x00\x00$+\xa9p\x00\x00\x00\x00%\x1b\x8c`\x00\x00\x00\x00&\v\x8bp\x00" +
-	"\x00\x00\x00'\x04\xa8\xe0\x00\x00\x00\x00'\xf4\xa7\xf0\x00\x00\x00\x00(\xe4\x8a\xe0\x00\x00\x00\x00)ԉ\xf0\x00\x00\x00\x00*\xc4l\xe0\x00\x00\x00\x00+\xb4k\xf0\x00\x00\x00\x00,\xa4N\xe0\x00\x00\x00\x00-" +
-	"\x94M\xf0\x00\x00\x00\x00.\x840\xe0\x00\x00\x00\x00/t/\xf0\x00\x00\x00\x000d\x12\xe0\x00\x00\x00\x001]Lp\x00\x00\x00\x002M/`\x00\x00\x00\x003=.p\x00\x00\x00\x004-\x11`\x00" +
-	"\x00\x00\x005\x1d\x10p\x00\x00\x00\x006\f\xf3`\x00\x00\x00\x00:饐\x00\x00\x00\x00;\xb4\x9e\x80\x00\x00\x00\x00<\xa4\x9d\x90\x00\x00\x00\x00=\x94\x80\x80\x00\x00\x00\x00>\x84\x7f\x90\x00\x00\x00\x00?" +
-	"tb\x80\x00\x00\x00\x00@da\x90\x00\x00\x00\x00ATD\x80\x00\x00\x00\x00BDC\x90\x00\x00\x00\x00C4&\x80\x00\x00\x00\x00D$%\x90\x00\x00\x00\x00E\x1dC\x00\x00\x00\x00\x00G\xef\xaa\xf0\x00" +
-	"\x00\x00\x00U\x15\x9a\xa0\x00\x00\x00\x00V\x05ap\x00\x00\x00\x00V\xf5|\xa0\x00\x00\x00\x00W\xe5Cp\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" +
-	"\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x02\x05\x02\x05\x02\x00\x00kX\x00\x00\x00\x00bp\x00\x04\x00\x00p\x80\x00\b\x00\x00~\x90\x00\f\x00\x00\x8c\xa0\x01\x10\x00\x00~\x90\x01\fLM" +
-	"T\x00+07\x00+08\x00+09\x00+10\x00\n<+08>-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x88\xf6C\x84\x98\x00\x00\x00\x98\x00\x00\x00\f\x00\x1c\x00Asi" +
-	"a/BangkokUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xffV\xb6\x85\xc4\xff\xff\xff\xff\xa2jg\xc4\x01\x02\x00\x00^<\x00\x00\x00\x00^<\x00\x04\x00\x00bp\x00\bLMT\x00BMT\x00+07\x00" +
-	"\n<+07>-7\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00\x00\x0e\x00\x1c\x00Asia/ChungkingUT\t\x00\x03\xdc\xfc" +
-	"\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff" +
-	"~6C)\xff\xff\xff\xff\xa0\x97\xa2\x80\xff\xff\xff\xff\xa1y\x04\xf0\xff\xff\xff\xff\xc8Y^\x80\xff\xff\xff\xff\xc9\t\xf9p\xff\xff\xff\xff\xc9ӽ\x00\xff\xff\xff\xff\xcb\x05\x8a\xf0\xff\xff\xff\xff\xcb|@\x00" +
-	"\xff\xff\xff\xff\xd2;>\xf0\xff\xff\xff\xffӋ{\x80\xff\xff\xff\xff\xd4B\xad\xf0\xff\xff\xff\xff\xd5E\"\x00\xff\xff\xff\xff\xd6L\xbf\xf0\xff\xff\xff\xff\xd7<\xbf\x00\xff\xff\xff\xff\xd8\x06fp\xff\xff\xff\xff" +
-	"\xd9\x1d\xf2\x80\xff\xff\xff\xff\xd9A|\xf0\x00\x00\x00\x00\x1e\xbaR \x00\x00\x00\x00\x1fi\x9b\x90\x00\x00\x00\x00 ~\x84\xa0\x00\x00\x00\x00!I}\x90\x00\x00\x00\x00\"g\xa1 \x00\x00\x00\x00#)_\x90" +
-	"\x00\x00\x00\x00$G\x83 \x00\x00\x00\x00%\x12|\x10\x00\x00\x00\x00&'e \x00\x00\x00\x00&\xf2^\x10\x00\x00\x00\x00(\aG \x00\x00\x00\x00(\xd2@\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00q\xd7\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\bLMT\x00CDT\x00CST\x00\nCST-8\nPK\x03\x04\n\x00" +
-	"\x00\x00\x00\x00\x8fj\xbeT)p\x1cX\xf1\x02\x00\x00\xf1\x02\x00\x00\x10\x00\x1c\x00Asia/NovosibirskUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91" +
-	"\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00T" +
-	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00C\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xdb\x19$\xff\xff\xff\xff\xb5\xa3\xe1 \x00" +
-	"\x00\x00\x00\x15'o\x90\x00\x00\x00\x00\x16\x18\xa4\x00\x00\x00\x00\x00\x17\b\xa3\x10\x00\x00\x00\x00\x17\xf9׀\x00\x00\x00\x00\x18\xe9\u0590\x00\x00\x00\x00\x19\xdb\v\x00\x00\x00\x00\x00\x1a\xcc[\x90\x00\x00\x00\x00\x1b" +
-	"\xbch\xb0\x00\x00\x00\x00\x1c\xacY\xb0\x00\x00\x00\x00\x1d\x9cJ\xb0\x00\x00\x00\x00\x1e\x8c;\xb0\x00\x00\x00\x00\x1f|,\xb0\x00\x00\x00\x00 l\x1d\xb0\x00\x00\x00\x00!\\\x0e\xb0\x00\x00\x00\x00\"K\xff\xb0\x00" +
-	"\x00\x00\x00#;\xf0\xb0\x00\x00\x00\x00$+\xe1\xb0\x00\x00\x00\x00%\x1bҰ\x00\x00\x00\x00&\vð\x00\x00\x00\x00'\x04\xef0\x00\x00\x00\x00'\xf4\xe00\x00\x00\x00\x00(\xe4\xdf@\x00\x00\x00\x00)" +
-	"x\x87@\x00\x00\x00\x00)\xd4\xc20\x00\x00\x00\x00*ij0\x00\x00\x00\x00+\xb4\xa40\x00\x00\x00\x00+\xfeN\x00\x00\x00\x00\x00,\xa4\xa3@\x00\x00\x00\x00-\x94\x94@\x00\x00\x00\x00.\x84\x85@\x00" +
-	"\x00\x00\x00/tv@\x00\x00\x00\x000dg@\x00\x00\x00\x001]\x92\xc0\x00\x00\x00\x002rm\xc0\x00\x00\x00\x003=t\xc0\x00\x00\x00\x004RO\xc0\x00\x00\x00\x005\x1dV\xc0\x00\x00\x00\x006" +
-	"21\xc0\x00\x00\x00\x006\xfd8\xc0\x00\x00\x00\x008\x1bN@\x00\x00\x00\x008\xdd\x1a\xc0\x00\x00\x00\x009\xfb0@\x00\x00\x00\x00:\xbc\xfc\xc0\x00\x00\x00\x00;\xdb\x12@\x00\x00\x00\x00<\xa6\x19@\x00" +
-	"\x00\x00\x00=\xba\xf4@\x00\x00\x00\x00>\x85\xfb@\x00\x00\x00\x00?\x9a\xd6@\x00\x00\x00\x00@e\xdd@\x00\x00\x00\x00A\x83\xf2\xc0\x00\x00\x00\x00BE\xbf@\x00\x00\x00\x00Cc\xd4\xc0\x00\x00\x00\x00D" +
-	"%\xa1@\x00\x00\x00\x00EC\xb6\xc0\x00\x00\x00\x00F\x05\x83@\x00\x00\x00\x00G#\x98\xc0\x00\x00\x00\x00G\xee\x9f\xc0\x00\x00\x00\x00I\x03z\xc0\x00\x00\x00\x00I\u0381\xc0\x00\x00\x00\x00J\xe3\\\xc0\x00" +
-	"\x00\x00\x00K\xaec\xc0\x00\x00\x00\x00L\xccy@\x00\x00\x00\x00M\x8eE\xc0\x00\x00\x00\x00TK\xf30\x00\x00\x00\x00W\x93\xcc\xc0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x04\x01\x03\x02\x03\x02\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x03\x01\x03\x00\x00M\xbc\x00\x00\x00\x00T`\x00\x04\x00\x00" +
-	"p\x80\x01\b\x00\x00bp\x00\f\x00\x00bp\x01\fLMT\x00+06\x00+08\x00+07\x00\n<+07>-7\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT]S\xbb\x12\xac" +
-	"\x03\x00\x00\xac\x03\x00\x00\x0e\x00\x1c\x00Asia/FamagustaUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff\xa5w\x1e,\x00\x00\x00\x00\t\xed\xaf\xe0\x00\x00\x00\x00\nݒ\xd0\x00\x00\x00\x00\v\xfad\xe0" +
-	"\x00\x00\x00\x00\f\xbe\xc6P\x00\x00\x00\x00\r\xa49`\x00\x00\x00\x00\x0e\x8a\xe1\xd0\x00\x00\x00\x00\x0f\x84\x1b`\x00\x00\x00\x00\x10uO\xd0\x00\x00\x00\x00\x11c\xfd`\x00\x00\x00\x00\x12S\xe0P\x00\x00\x00\x00" +
-	"\x13M\x19\xe0\x00\x00\x00\x00\x143\xc2P\x00\x00\x00\x00\x15#\xc1`\x00\x00\x00\x00\x16\x13\xa4P\x00\x00\x00\x00\x17\x03\xa3`\x00\x00\x00\x00\x17\xf3\x86P\x00\x00\x00\x00\x18\xe3\x85`\x00\x00\x00\x00\x19\xd3hP" +
-	"\x00\x00\x00\x00\x1a\xc3g`\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00" +
-	"!\\*\xd0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$,\v\xe0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf5\n`" +
-	"\x00\x00\x00\x00(\xe4\xedP\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00" +
-	"/t\x92`\x00\x00\x00\x000duP\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002M\x91\xd0\x00\x00\x00\x003=\x90\xe0\x00\x00\x00\x004-s\xd0\x00\x00\x00\x005\x1dr\xe0\x00\x00\x00\x0062x\x10" +
-	"\x00\x00\x00\x006\xfd\x7f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x008\xdda\x10\x00\x00\x00\x009\xfbv\x90\x00\x00\x00\x00:\xbdC\x10\x00\x00\x00\x00;\xdbX\x90\x00\x00\x00\x00<\xa6_\x90\x00\x00\x00\x00" +
-	"=\xbb:\x90\x00\x00\x00\x00>\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90" +
-	"\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00" +
-	"K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90" +
-	"\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00W\xd0\x7f\xd0\x00\x00\x00\x00Y\xf5(\x10\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x02\x00\x00\x1f\xd4\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\t\x00\x00*0\x00\rLMT\x00EEST\x00EET\x00+" +
-	"03\x00\nEET-2EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeTʇ{_\xbb\x00\x00\x00\xbb\x00\x00\x00\f" +
-	"\x00\x1c\x00Asia/RangoonUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xffV\xb6\x89\xd1\xff\xff\xff\xff\xa1\xf2sQ\xff\xff\xff\xff\xcb\xf2\xfc\x18\xff\xff\xff\xffњg\xf0\x01\x02\x03\x02\x00\x00Z/\x00\x00" +
-	"\x00\x00Z/\x00\x04\x00\x00[h\x00\b\x00\x00~\x90\x00\x0eLMT\x00RMT\x00+0630\x00+09\x00\n<+0630>-6:30\nPK\x03\x04\n\x00\x00\x00\x00\x00" +
-	"\x8fj\xbeT\x84)\r\xbd\xec\x00\x00\x00\xec\x00\x00\x00\x10\x00\x1c\x00Asia/Ho_Chi_MinhUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04" +
-	"S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xff\x88\x8cC\x80\xff\xff\xff\xff\x91\xa3+\n\xff\xff\xff\xff\xcd" +
-	"5\xe6\x80\xff\xff\xff\xff\xd1Y\xcep\xff\xff\xff\xff\xd2;>\xf0\xff\xff\xff\xff\xd52\xbb\x10\xff\xff\xff\xff\xe4\xb6\xe4\x80\xff\xff\xff\xff\xed/\x98\x00\x00\x00\x00\x00\n=\xc7\x00\x01\x02\x03\x04\x02\x03\x02\x03\x02" +
-	"\x00\x00d\x00\x00\x00\x00\x00c\xf6\x00\x04\x00\x00bp\x00\t\x00\x00p\x80\x00\r\x00\x00~\x90\x00\x11LMT\x00PLMT\x00+07\x00+08\x00+09\x00\n<+07>-7\n" +
-	"PK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x1c\x00Atlantic/UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1" +
-	"\b\x00\x04S_\x01\x00PK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xb7\x0e\xbdm\xb9\x01\x00\x00\xb9\x01\x00\x00\x0e\x00\x1c\x00Atlantic/FaroeUT\t\x00\x03\xdd\xfc\x94b" +
-	"\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00" +
-	"\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xff\x8bm" +
-	"\xa4X\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00" +
-	"\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"L" +
-	"T\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00" +
-	"\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d" +
-	"\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xf9\xa8\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x0e\x10\x01\b" +
-	"LMT\x00WET\x00WEST\x00\nWET0WEST,M3.5.0/1,M10.5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xaf|7\xb3\xde\x01" +
-	"\x00\x00\xde\x01\x00\x00\x0f\x00\x1c\x00Atlantic/CanaryUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00#\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff\xa6\x04\\\xf0\xff\xff\xff\xff\xd4A\xf7 \x00\x00\x00\x00\x13M6\x00\x00\x00\x00\x00\x143\xfa\x90" +
-	"\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00" +
-	"\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10" +
-	"\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00" +
-	")\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90" +
-	"\x00\x00\x00\x001]\xd9\x10\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\xf1\x90\x00\x00\xff\xff\xf1\xf0\x00\x04\x00\x00\x00\x00\x00" +
-	"\b\x00\x00\x0e\x10\x01\fLMT\x00-01\x00WET\x00WEST\x00\nWET0WEST,M3.5.0/1,M10.5.0\nPK\x03\x04\n\x00\x00\x00\x00" +
-	"\x00\x8fj\xbeT\xe7\xcf^\xb0\x15\x03\x00\x00\x15\x03\x00\x00\x10\x00\x1c\x00Atlantic/StanleyUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00" +
-	"\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif" +
-	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00F\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffi\x87\x11\xbc\xff\xff\xff\xff\x93D_<\xff\xff\xff\xff" +
-	"\xc3OZ\xc0\xff\xff\xff\xff\xc46\x030\xff\xff\xff\xff\xc5/<\xc0\xff\xff\xff\xff\xc6\x15\xe50\xff\xff\xff\xff\xc7\x18Y@\xff\xff\xff\xff\xc7\xff\x01\xb0\xff\xff\xff\xff\xc8\xf8;@\xff\xff\xff\xff\xc9\xde\xe3\xb0" +
-	"\xff\xff\xff\xff\xca\xd8\x1d@\xff\xff\xff\xff˾Ű\xff\xff\xff\xff̷\xff@\xff\xff\xff\xff\xcd6\x810\x00\x00\x00\x00\x19\x11\xfe@\x00\x00\x00\x00\x19Ӽ\xb0\x00\x00\x00\x00\x1a\xf1\xc4 \x00\x00\x00\x00" +
-	"\x1b\xaad0\x00\x00\x00\x00\x1cѦ \x00\x00\x00\x00\x1d\x8aF0\x00\x00\x00\x00\x1e\xa8[\xb0\x00\x00\x00\x00\x1fj6@\x00\x00\x00\x00 \x88=\xb0\x00\x00\x00\x00!J\x18@\x00\x00\x00\x00\"h\x1f\xb0" +
-	"\x00\x00\x00\x00#)\xfa@\x00\x00\x00\x00$H\x01\xb0\x00\x00\x00\x00%\t\xdc@\x00\x00\x00\x00&1\x1e0\x00\x00\x00\x00&\xe9\xbe@\x00\x00\x00\x00(\x11\x000\x00\x00\x00\x00(\xd2\xda\xc0\x00\x00\x00\x00" +
-	")\xf0\xe20\x00\x00\x00\x00*\xb2\xbc\xc0\x00\x00\x00\x00+\xd0\xc40\x00\x00\x00\x00,\x92\x9e\xc0\x00\x00\x00\x00-\xb0\xa60\x00\x00\x00\x00.r\x80\xc0\x00\x00\x00\x00/\x90\x880\x00\x00\x00\x000Rb\xc0" +
-	"\x00\x00\x00\x001y\xa4\xb0\x00\x00\x00\x002;\x7f@\x00\x00\x00\x003Y\x86\xb0\x00\x00\x00\x004\x1ba@\x00\x00\x00\x0059h\xb0\x00\x00\x00\x005\xfbC@\x00\x00\x00\x007\x19J\xb0\x00\x00\x00\x00" +
-	"7\xdb%@\x00\x00\x00\x008\xf9,\xb0\x00\x00\x00\x009\xbb\a@\x00\x00\x00\x00:\xd9*\xd0\x00\x00\x00\x00;\x91\xca\xe0\x00\x00\x00\x00<\xc2GP\x00\x00\x00\x00=q\xac\xe0\x00\x00\x00\x00>\xa2)P" +
-	"\x00\x00\x00\x00?Z\xc9`\x00\x00\x00\x00@\x82\vP\x00\x00\x00\x00A:\xab`\x00\x00\x00\x00Ba\xedP\x00\x00\x00\x00C\x1a\x8d`\x00\x00\x00\x00DA\xcfP\x00\x00\x00\x00D\xfao`\x00\x00\x00\x00" +
-	"F!\xb1P\x00\x00\x00\x00F\xdaQ`\x00\x00\x00\x00H\n\xcd\xd0\x00\x00\x00\x00H\xc3m\xe0\x00\x00\x00\x00I\xea\xaf\xd0\x00\x00\x00\x00J\xa3O\xe0\x00\x00\x00\x00Kʑ\xd0\x00\x00\x00\x00L\x831\xe0" +
-	"\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x04\x05\x04\x05\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\xff\xff\xc9\xc4\x00\x00\xff\xff\xc9\xc4\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xc7\xc0\x00\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\bLMT\x00SMT\x00-03\x00-0" +
-	"4\x00-02\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTl&\x04\x99\x00\x04\x00\x00\x00\x04\x00\x00\x10\x00\x1c\x00Atlantic/Bermuda" +
-	"UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00_\x00\x00\x00\x05\x00" +
-	"\x00\x00\x14\xff\xff\xff\xffi\x87\x18F\xff\xff\xff\xff\x9c̮F\xff\xff\xff\xff\x9d\xb7K6\xff\xff\xff\xff\x9e\xb8m\xc6\xff\xff\xff\xff\x9f\x84\xb86\xff\xff\xff\xff\xb4\xc3\x1d\xe6\xff\xff\xff\xff\xcbb\xa6\xe0\xff" +
-	"\xff\xff\xff\xccӼ\xd0\xff\xff\xff\xff͞\xd1\xe0\xff\xff\xff\xff\xce\xc6\x13\xd0\xff\xff\xff\xff\xcfuy`\xff\xff\xff\xffЯ0P\xff\xff\xff\xff\xd1U[`\xff\xff\xff\xffҏ\x12P\xff\xff\xff\xff\xd5" +
-	"qh`\xff\xff\xff\xff\xd6\x0e<\xd0\xff\xff\xff\xff\xd7Z\x84\xe0\xff\xff\xff\xff\xd7\xe4\xe4P\xff\xff\xff\xff\xd9:f\xe0\xff\xff\xff\xff\xd9\xc4\xc6P\xff\xff\xff\xff\xdb#\x83`\xff\xff\xff\xffۤ\xa8P\xff" +
-	"\xff\xff\xff\xdd\x03e`\xff\xff\xff\xff݄\x8aP\xff\xff\xff\xff\xde\xe3G`\xff\xff\xff\xff\xdfm\xa6\xd0\xff\xff\xff\xff\xe6l\t\xe0\xff\xff\xff\xff\xe77\x02\xd0\x00\x00\x00\x00\b \xb3`\x00\x00\x00\x00\t" +
-	"\x10\x96P\x00\x00\x00\x00\n\x00\x95`\x00\x00\x00\x00\n\xf0xP\x00\x00\x00\x00\v\xe0w`\x00\x00\x00\x00\fٔ\xd0\x00\x00\x00\x00\r\xc0Y`\x00\x00\x00\x00\x0e\xb9v\xd0\x00\x00\x00\x00\x0f\xa9u\xe0\x00" +
-	"\x00\x00\x00\x10\x99X\xd0\x00\x00\x00\x00\x11\x89W\xe0\x00\x00\x00\x00\x12y:\xd0\x00\x00\x00\x00\x13i9\xe0\x00\x00\x00\x00\x14Y\x1c\xd0\x00\x00\x00\x00\x15I\x1b\xe0\x00\x00\x00\x00\x168\xfe\xd0\x00\x00\x00\x00\x17" +
-	"(\xfd\xe0\x00\x00\x00\x00\x18\"\x1bP\x00\x00\x00\x00\x19\b\xdf\xe0\x00\x00\x00\x00\x1a\x01\xfdP\x00\x00\x00\x00\x1a\xf1\xfc`\x00\x00\x00\x00\x1b\xe1\xdfP\x00\x00\x00\x00\x1c\xd1\xde`\x00\x00\x00\x00\x1d\xc1\xc1P\x00" +
-	"\x00\x00\x00\x1e\xb1\xc0`\x00\x00\x00\x00\x1f\xa1\xa3P\x00\x00\x00\x00 u\xf2\xe0\x00\x00\x00\x00!\x81\x85P\x00\x00\x00\x00\"U\xd4\xe0\x00\x00\x00\x00#j\xa1\xd0\x00\x00\x00\x00$5\xb6\xe0\x00\x00\x00\x00%" +
-	"J\x83\xd0\x00\x00\x00\x00&\x15\x98\xe0\x00\x00\x00\x00'*e\xd0\x00\x00\x00\x00'\xfe\xb5`\x00\x00\x00\x00)\nG\xd0\x00\x00\x00\x00)ޗ`\x00\x00\x00\x00*\xea)\xd0\x00\x00\x00\x00+\xbey`\x00" +
-	"\x00\x00\x00,\xd3FP\x00\x00\x00\x00-\x9e[`\x00\x00\x00\x00.\xb3(P\x00\x00\x00\x00/~=`\x00\x00\x00\x000\x93\nP\x00\x00\x00\x001gY\xe0\x00\x00\x00\x002r\xecP\x00\x00\x00\x003" +
-	"G;\xe0\x00\x00\x00\x004R\xceP\x00\x00\x00\x005'\x1d\xe0\x00\x00\x00\x0062\xb0P\x00\x00\x00\x007\x06\xff\xe0\x00\x00\x00\x008\x1b\xcc\xd0\x00\x00\x00\x008\xe6\xe1\xe0\x00\x00\x00\x009\xfb\xae\xd0\x00" +
-	"\x00\x00\x00:\xc6\xc3\xe0\x00\x00\x00\x00;ې\xd0\x00\x00\x00\x00<\xaf\xe0`\x00\x00\x00\x00=\xbbr\xd0\x00\x00\x00\x00>\x8f\xc2`\x00\x00\x00\x00?\x9bT\xd0\x00\x00\x00\x00@o\xa4`\x00\x00\x00\x00A" +
-	"\x84qP\x00\x00\x00\x00BO\x86`\x00\x00\x00\x00CdSP\x00\x00\x00\x00D/h`\x00\x00\x00\x00ED5P\x00\x00\x00\x00E\xf3\x9a\xe0\x02\x01\x02\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" +
-	"\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" +
-	"\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\xff\xff\xc3:\x00\x00\xff\xff\xd1J\x01\x04\xff\xff\xc3:\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xc7\xc0\x00\x10LMT\x00BST\x00BMT\x00" +
-	"ADT\x00AST\x00\nAST4ADT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x0f-\xadׄ\x00\x00\x00\x84\x00\x00\x00\x16\x00" +
-	"\x1c\x00Atlantic/South_GeorgiaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xffi\x86\xfd\xc0\x01\xff\xff\xdd\xc0\x00\x00\xff\xff\xe3\xe0\x00\x04LMT\x00-02\x00\n<-0" +
-	"2>2\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x12\x00\x1c\x00Atlantic/St_HelenaUT\t\x00\x03\xdc\xfc\x94" +
-	"b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" +
-	"\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x92" +
-	"\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xa5\x97\aĤ\x02\x00\x00\xa4\x02\x00\x00\x12\x00\x1c\x00" +
-	"Atlantic/Jan_MayenUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xffr\xee$l\xff\xff\xff\xff\x9b'\xe3\x00\xff\xff\xff\xff\x9b\xd4{`\xff\xff\xff\xffȷM`\xff\xff\xff\xff\xcc\xe7K" +
-	"\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2b\a\x10\xff\xff\xff\xff\xeb\xaf \x90\xff\xff\xff" +
-	"\xff\xec\xa8L\x10\xff\xff\xff\xff\xed\x98=\x10\xff\xff\xff\xff\xee\x88.\x10\xff\xff\xff\xff\xefx\x1f\x10\xff\xff\xff\xff\xf0h\x10\x10\xff\xff\xff\xff\xf1X\x01\x10\xff\xff\xff\xff\xf2G\xf2\x10\xff\xff\xff\xff\xf37\xe3" +
-	"\x10\xff\xff\xff\xff\xf4'\xd4\x10\xff\xff\xff\xff\xf5\x17\xc5\x10\xff\xff\xff\xff\xf6\x10\xf0\x90\xff\xff\xff\xff\xf7/\x06\x10\xff\xff\xff\xff\xf7\xf0Ґ\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00" +
-	"\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd" +
-	"\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00" +
-	"\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16" +
-	"\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00" +
-	"\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x00\x00\n\x14\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\tLMT\x00CEST\x00CET\x00\nCET-1CEST,M3.5.0,M10.5.0/" +
-	"3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xb7\x0e\xbdm\xb9\x01\x00\x00\xb9\x01\x00\x00\x0f\x00\x1c\x00Atlantic/FaeroeUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94b" +
-	"ux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00" +
-	"\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xff\x8bm\xa4X\x00\x00" +
-	"\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc" +
-	"\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00" +
-	"\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5" +
-	"\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00" +
-	"\x00\x001]\xd9\x10\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xf9\xa8\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x0e\x10\x01\bLMT\x00" +
-	"WET\x00WEST\x00\nWET0WEST,M3.5.0/1,M10.5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTm\xbd\x10k\xf1\x02\x00\x00\xf1\x02" +
-	"\x00\x00\x12\x00\x1c\x00Atlantic/ReykjavikUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00D\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\x8b`\x83\xa0\xff\xff\xff\xff\x9c\x91\x1e\x00\xff\xff\xff\xff\x9dш\x90\xff\xff\xff\xff\x9erQ\x80\xff" +
-	"\xff\xff\xff\x9f\xd5\x03\x10\xff\xff\xff\xff\xa0S\x85\x00\xff\xff\xff\xff\xa1\xb66\x90\xff\xff\xff\xff\xa4<'\x80\xff\xff\xff\xff\xa4\xb9t\x10\xff\xff\xff\xff\xc6M\x1a\x00\xff\xff\xff\xff\xc7=' \xff\xff\xff\xff\xc7" +
-	"\xda\x17\xb0\xff\xff\xff\xff\xc9&C\xa0\xff\xff\xff\xff\xc9\xc3& \xff\xff\xff\xff\xcb\x06%\xa0\xff\xff\xff\xffˬB\xa0\xff\xff\xff\xff\xcc\xdc\xcd \xff\xff\xff\xff͌$\xa0\xff\xff\xff\xffμ\xaf \xff" +
-	"\xff\xff\xff\xcfl\x06\xa0\xff\xff\xff\xffМ\x91 \xff\xff\xff\xff\xd1K\xe8\xa0\xff\xff\xff\xff҅\xad\xa0\xff\xff\xff\xff\xd3+ʠ\xff\xff\xff\xff\xd4e\x8f\xa0\xff\xff\xff\xff\xd59\xd1 \xff\xff\xff\xff\xd6" +
-	"Eq\xa0\xff\xff\xff\xff\xd7\x19\xb3 \xff\xff\xff\xff\xd8%S\xa0\xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xd9w \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xffܹY \xff" +
-	"\xff\xff\xff\xdd\xce4 \xff\xff\xff\xffޢu\xa0\xff\xff\xff\xff߮\x16 \xff\xff\xff\xff\xe0\x82W\xa0\xff\xff\xff\xff\xe1\x8d\xf8 \xff\xff\xff\xff\xe2b9\xa0\xff\xff\xff\xff\xe3m\xda \xff\xff\xff\xff\xe4" +
-	"B\x1b\xa0\xff\xff\xff\xff\xe5M\xbc \xff\xff\xff\xff\xe6!\xfd\xa0\xff\xff\xff\xff\xe76ؠ\xff\xff\xff\xff\xe8\v\x1a \xff\xff\xff\xff\xe9\x16\xba\xa0\xff\xff\xff\xff\xe9\xea\xfc \xff\xff\xff\xff\xea\xf6\x9c\xa0\xff" +
-	"\xff\xff\xff\xeb\xca\xde \xff\xff\xff\xff\xec\xd6~\xa0\xff\xff\xff\xff\xed\xaa\xc0 \xff\xff\xff\xff\xee\xb6`\xa0\xff\xff\xff\xff\uf2a2 \xff\xff\xff\xff\xf0\x96B\xa0\xff\xff\xff\xff\xf1j\x84 \xff\xff\xff\xff\xf2" +
-	"\x7f_ \xff\xff\xff\xff\xf3S\xa0\xa0\xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf53\x82\xa0\xff\xff\xff\xff\xf6?# \xff\xff\xff\xff\xf7\x13d\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xf3F\xa0\xff" +
-	"\xff\xff\xff\xf9\xfe\xe7 \xff\xff\xff\xff\xfa\xd3(\xa0\xff\xff\xff\xff\xfb\xe8\x03\xa0\xff\xff\xff\xff\xfc\xbcE \x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\xff\xff\xeb`\x00\x00\x00\x00\x00\x00\x01\x04\xff\xff\xf1\xf0\x00\b\x00\x00\x00" +
-	"\x00\x00\fLMT\x00+00\x00-01\x00GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\u0097N\xad\xaf\x00\x00\x00\xaf\x00\x00\x00\x13\x00\x1c\x00Atlan" +
-	"tic/Cape_VerdeUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\bLMT\x00CDT\x00CST\x00\nCST-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00F7k\x1c\x00\x01\x00\x00\x00\x01\x00\x00\x0e" +
+	"\x00\x00\x00Asia/SingaporeTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" +
+	"\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\b\x00\x00\x00 \xff\xff\xff\xff~6S\xa3" +
+	"\xff\xff\xff\xff\x86\x83\x85\xa3\xff\xff\xff\xff\xbagN\x90\xff\xff\xff\xff\xc0\n\xe4`\xff\xff\xff\xffʳ\xe5`\xff\xff\xff\xffˑ_\b\xff\xff\xff\xff\xd2Hm\xf0\x00\x00\x00\x00\x16\x91\xee\x00\x01\x02\x03\x04" +
+	"\x05\x06\x05\a\x00\x00a]\x00\x00\x00\x00a]\x00\x04\x00\x00bp\x00\b\x00\x00g \x01\f\x00\x00g \x00\f\x00\x00ix\x00\x12\x00\x00~\x90\x00\x18\x00\x00p\x80\x00\x1cLMT\x00SMT\x00" +
+	"+07\x00+0720\x00+0730\x00+09\x00+08\x00\n<+08>-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4Zߐ\xe6\x02\x00\x00\xe6\x02\x00\x00\x12" +
+	"\x00\x00\x00Asia/SrednekolymskTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00A\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff" +
+	"\xaa\x193\xe4\xff\xff\xff\xff\xb5\xa3\xa8\xe0\x00\x00\x00\x00\x15'7P\x00\x00\x00\x00\x16\x18k\xc0\x00\x00\x00\x00\x17\bj\xd0\x00\x00\x00\x00\x17\xf9\x9f@\x00\x00\x00\x00\x18\xe9\x9eP\x00\x00\x00\x00\x19\xda\xd2\xc0" +
+	"\x00\x00\x00\x00\x1a\xcc#P\x00\x00\x00\x00\x1b\xbc0p\x00\x00\x00\x00\x1c\xac!p\x00\x00\x00\x00\x1d\x9c\x12p\x00\x00\x00\x00\x1e\x8c\x03p\x00\x00\x00\x00\x1f{\xf4p\x00\x00\x00\x00 k\xe5p\x00\x00\x00\x00" +
+	"![\xd6p\x00\x00\x00\x00\"K\xc7p\x00\x00\x00\x00#;\xb8p\x00\x00\x00\x00$+\xa9p\x00\x00\x00\x00%\x1b\x9ap\x00\x00\x00\x00&\v\x8bp\x00\x00\x00\x00'\x04\xb6\xf0\x00\x00\x00\x00'\xf4\xa7\xf0" +
+	"\x00\x00\x00\x00(\xe4\xa7\x00\x00\x00\x00\x00)xO\x00\x00\x00\x00\x00)ԉ\xf0\x00\x00\x00\x00*\xc4z\xf0\x00\x00\x00\x00+\xb4k\xf0\x00\x00\x00\x00,\xa4\\\xf0\x00\x00\x00\x00-\x94M\xf0\x00\x00\x00\x00" +
+	".\x84>\xf0\x00\x00\x00\x00/t/\xf0\x00\x00\x00\x000d \xf0\x00\x00\x00\x001]Lp\x00\x00\x00\x002r'p\x00\x00\x00\x003=.p\x00\x00\x00\x004R\tp\x00\x00\x00\x005\x1d\x10p" +
+	"\x00\x00\x00\x0061\xebp\x00\x00\x00\x006\xfc\xf2p\x00\x00\x00\x008\x1b\a\xf0\x00\x00\x00\x008\xdc\xd4p\x00\x00\x00\x009\xfa\xe9\xf0\x00\x00\x00\x00:\xbc\xb6p\x00\x00\x00\x00;\xda\xcb\xf0\x00\x00\x00\x00" +
+	"<\xa5\xd2\xf0\x00\x00\x00\x00=\xba\xad\xf0\x00\x00\x00\x00>\x85\xb4\xf0\x00\x00\x00\x00?\x9a\x8f\xf0\x00\x00\x00\x00@e\x96\xf0\x00\x00\x00\x00A\x83\xacp\x00\x00\x00\x00BEx\xf0\x00\x00\x00\x00Cc\x8ep" +
+	"\x00\x00\x00\x00D%Z\xf0\x00\x00\x00\x00ECpp\x00\x00\x00\x00F\x05<\xf0\x00\x00\x00\x00G#Rp\x00\x00\x00\x00G\xeeYp\x00\x00\x00\x00I\x034p\x00\x00\x00\x00I\xce;p\x00\x00\x00\x00" +
+	"J\xe3\x16p\x00\x00\x00\x00K\xae\x1dp\x00\x00\x00\x00L\xcc2\xf0\x00\x00\x00\x00M\x8d\xffp\x00\x00\x00\x00TK\xac\xe0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x03\x00\x00\x90\x1c\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00\xa8\xc0\x01\b\x00" +
+	"\x00\x9a\xb0\x00\f\x00\x00\x9a\xb0\x01\f\x00\x00\xa8\xc0\x00\bLMT\x00+10\x00+12\x00+11\x00\n<+11>-11\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xee\xf0B" +
+	"B\xff\x01\x00\x00\xff\x01\x00\x00\v\x00\x00\x00Asia/TaipeiTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)\x00\x00\x00\x04\x00\x00\x00\x10\xff" +
+	"\xff\xff\xfft\xce\xf0\x18\xff\xff\xff\xff\xc3UI\x80\xff\xff\xff\xff\xd2TY\x80\xff\xff\xff\xffӋ{\x80\xff\xff\xff\xff\xd4B\xad\xf0\xff\xff\xff\xff\xd5E\"\x00\xff\xff\xff\xff\xd6L\xbf\xf0\xff\xff\xff\xff\xd7" +
+	"<\xbf\x00\xff\xff\xff\xff\xd8\x06fp\xff\xff\xff\xff\xd9\x1d\xf2\x80\xff\xff\xff\xff\xd9\xe7\x99\xf0\xff\xff\xff\xff\xda\xff&\x00\xff\xff\xff\xff\xdb\xc8\xcdp\xff\xff\xff\xff\xdc\xe0Y\x80\xff\xff\xff\xffݪ\x00\xf0\xff" +
+	"\xff\xff\xff\xders\x00\xff\xff\xff\xffߵdp\xff\xff\xff\xff\xe0|\x85\x00\xff\xff\xff\xffᖗ\xf0\xff\xff\xff\xff\xe2]\xb8\x80\xff\xff\xff\xff\xe3w\xcbp\xff\xff\xff\xff\xe4>\xec\x00\xff\xff\xff\xff\xe5" +
+	"0 p\xff\xff\xff\xff\xe6!q\x00\xff\xff\xff\xff\xe7\x12\xa5p\xff\xff\xff\xff\xe8\x02\xa4\x80\xff\xff\xff\xff\xe8\xf3\xd8\xf0\xff\xff\xff\xff\xe9\xe3\xd8\x00\xff\xff\xff\xff\xea\xd5\fp\xff\xff\xff\xff\xeb\xc5\v\x80\xff" +
+	"\xff\xff\xff\xec\xb6?\xf0\xff\xff\xff\xff\xed\xf7\xfc\x00\xff\xff\xff\xff\xee\x98\xc4\xf0\xff\xff\xff\xff\xef\xd9/\x80\xff\xff\xff\xff\xf0y\xf8p\x00\x00\x00\x00\a\xfcV\x00\x00\x00\x00\x00\b\xed\x8ap\x00\x00\x00\x00\t" +
+	"݉\x80\x00\x00\x00\x00\nν\xf0\x00\x00\x00\x00\x11ۡ\x80\x00\x00\x00\x00\x12T\xddp\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01" +
+	"\x03\x01\x03\x01\x03\x01\x03\x01\x00\x00q\xe8\x00\x00\x00\x00p\x80\x00\x04\x00\x00~\x90\x00\b\x00\x00~\x90\x01\fLMT\x00CST\x00JST\x00CDT\x00\nCST-8\nPK\x03\x04\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\xe27Yn\x01\x00\x00n\x01\x00\x00\r\x00\x00\x00Asia/TashkentTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x18\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x83\t\xff\xff\xff\xff\xb5\xa3\xef0\x00\x00\x00\x00\x15'}\xa0\x00\x00\x00\x00\x16\x18\xb2\x10\x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xe5" +
+	"\x90\x00\x00\x00\x00\x18\xe9\xe4\xa0\x00\x00\x00\x00\x19\xdb\x19\x10\x00\x00\x00\x00\x1a\xcci\xa0\x00\x00\x00\x00\x1b\xbcv\xc0\x00\x00\x00\x00\x1c\xacg\xc0\x00\x00\x00\x00\x1d\x9cX\xc0\x00\x00\x00\x00\x1e\x8cI\xc0\x00\x00\x00" +
+	"\x00\x1f|:\xc0\x00\x00\x00\x00 l+\xc0\x00\x00\x00\x00!\\\x1c\xc0\x00\x00\x00\x00\"L\r\xc0\x00\x00\x00\x00#;\xfe\xc0\x00\x00\x00\x00$+\xef\xc0\x00\x00\x00\x00%\x1b\xe0\xc0\x00\x00\x00\x00&\v\xd1" +
+	"\xc0\x00\x00\x00\x00'\x04\xfd@\x00\x00\x00\x00'\xf4\xee@\x00\x00\x00\x00(\xe4\xedP\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x00\x00@\xf7\x00\x00\x00\x00FP\x00" +
+	"\x04\x00\x00bp\x01\b\x00\x00T`\x00\f\x00\x00T`\x01\fLMT\x00+05\x00+07\x00+06\x00\n<+05>-5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Ѿ" +
+	"\xa8\xc7u\x02\x00\x00u\x02\x00\x00\f\x00\x00\x00Asia/TbilisiTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x004\x00\x00\x00\x06\x00\x00\x00" +
+	"\x15\xff\xff\xff\xffV\xb6\xba\x01\xff\xff\xff\xff\xaa\x19\x9a\x01\xff\xff\xff\xff\xe7\xda\fP\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\b\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00" +
+	"\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a̅\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V" +
+	"\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\8\xe0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<\x1a\xe0\x00\x00\x00\x00$,\v\xe0\x00\x00\x00\x00%\x1b\xfc\xe0\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00" +
+	"\x00'\x05\x19`\x00\x00\x00\x00'\xf5\n`\x00\x00\x00\x00(\xe5\tp\x00\x00\x00\x00)\xd4\xdeP\x00\x00\x00\x00*\xc4\xc1@\x00\x00\x00\x00+\xb4\xc0P\x00\x00\x00\x00,\xa4\xa3@\x00\x00\x00\x00-\x94\xa2" +
+	"P\x00\x00\x00\x00.\x84\x85@\x00\x00\x00\x00/tv@\x00\x00\x00\x000dY0\x00\x00\x00\x001]\x92\xc0\x00\x00\x00\x003=f\xb0\x00\x00\x00\x004RA\xb0\x00\x00\x00\x005\x1dV\xc0\x00\x00\x00" +
+	"\x0062#\xb0\x00\x00\x00\x006\xfd8\xc0\x00\x00\x00\x008\x1b@0\x00\x00\x00\x008\xdd\x1a\xc0\x00\x00\x00\x009\xfb\"0\x00\x00\x00\x00:\xbc\xfc\xc0\x00\x00\x00\x00;\xdb\x040\x00\x00\x00\x00<\xa6\x19" +
+	"@\x00\x00\x00\x00=\xba\xe60\x00\x00\x00\x00>\x85\xfb@\x00\x00\x00\x00?\x9a\xc80\x00\x00\x00\x00@e\xdd@\x00\x00\x00\x00@\xddǰ\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x01\x02\x04" +
+	"\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x05\x02\x05\x02\x05\x02\x05\x04\x03\x04\x03\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x05\x02\x04\x00\x00)\xff\x00\x00\x00\x00)\xff\x00" +
+	"\x04\x00\x00*0\x00\t\x00\x00FP\x01\r\x00\x008@\x00\x11\x00\x008@\x01\x11LMT\x00TBMT\x00+03\x00+05\x00+04\x00\n<+04>-4\nPK\x03\x04\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c\xdb?\xec,\x03\x00\x00,\x03\x00\x00\v\x00\x00\x00Asia/TehranTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00G\x00\x00\x00\x06\x00\x00\x00\x1c\xff\xff\xff\xff\x9al}\xc8\xff\xff\xff\xff\xbf\x00\xccH\x00\x00\x00\x00\r\x94D8\x00\x00\x00\x00\x0e\xad\x13\xb8\x00\x00\x00\x00\x0fys@\x00\x00\x00\x00\x10(\xca\xc0\x00" +
+	"\x00\x00\x00\x10\xed:@\x00\x00\x00\x00\x11\xad\xbcH\x00\x00\x00\x00\x12EJ\xb8\x00\x00\x00\x00\x137\xec\xc8\x00\x00\x00\x00\x14-\x15\xb8\x00\x00\x00\x00( v\xc8\x00\x00\x00\x00(\u06dd\xb8\x00\x00\x00\x00)" +
+	"˜\xc8\x00\x00\x00\x00*\xbe\"\xb8\x00\x00\x00\x00+\xac\xd0H\x00\x00\x00\x00,\x9fV8\x00\x00\x00\x00-\x8e\x03\xc8\x00\x00\x00\x00.\x80\x89\xb8\x00\x00\x00\x00/o7H\x00\x00\x00\x000a\xbd8\x00" +
+	"\x00\x00\x001Pj\xc8\x00\x00\x00\x002B\xf0\xb8\x00\x00\x00\x0032\xef\xc8\x00\x00\x00\x004%u\xb8\x00\x00\x00\x005\x14#H\x00\x00\x00\x006\x06\xa98\x00\x00\x00\x006\xf5V\xc8\x00\x00\x00\x007" +
+	"\xe7ܸ\x00\x00\x00\x008֊H\x00\x00\x00\x009\xc9\x108\x00\x00\x00\x00:\xb9\x0fH\x00\x00\x00\x00;\xab\x958\x00\x00\x00\x00<\x9aB\xc8\x00\x00\x00\x00=\x8cȸ\x00\x00\x00\x00>{vH\x00" +
+	"\x00\x00\x00?m\xfc8\x00\x00\x00\x00@\\\xa9\xc8\x00\x00\x00\x00AO/\xb8\x00\x00\x00\x00B?.\xc8\x00\x00\x00\x00C1\xb4\xb8\x00\x00\x00\x00G\xe2\xc9H\x00\x00\x00\x00H\xd5O8\x00\x00\x00\x00I" +
+	"\xc5NH\x00\x00\x00\x00J\xb7\xd48\x00\x00\x00\x00K\xa6\x81\xc8\x00\x00\x00\x00L\x99\a\xb8\x00\x00\x00\x00M\x87\xb5H\x00\x00\x00\x00Nz;8\x00\x00\x00\x00Oh\xe8\xc8\x00\x00\x00\x00P[n\xb8\x00" +
+	"\x00\x00\x00QKm\xc8\x00\x00\x00\x00R=\xf3\xb8\x00\x00\x00\x00S,\xa1H\x00\x00\x00\x00T\x1f'8\x00\x00\x00\x00U\r\xd4\xc8\x00\x00\x00\x00V\x00Z\xb8\x00\x00\x00\x00V\xef\bH\x00\x00\x00\x00W" +
+	"\xe1\x8e8\x00\x00\x00\x00XэH\x00\x00\x00\x00Y\xc4\x138\x00\x00\x00\x00Z\xb2\xc0\xc8\x00\x00\x00\x00[\xa5F\xb8\x00\x00\x00\x00\\\x93\xf4H\x00\x00\x00\x00]\x86z8\x00\x00\x00\x00^u'\xc8\x00" +
+	"\x00\x00\x00_g\xad\xb8\x00\x00\x00\x00`W\xac\xc8\x00\x00\x00\x00aJ2\xb8\x00\x00\x00\x00b8\xe0H\x00\x00\x00\x00c+f8\x01\x03\x02\x05\x04\x05\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x0008\x00\x00\x00\x0008" +
+	"\x00\x04\x00\x00?H\x01\b\x00\x0018\x00\x0e\x00\x00FP\x01\x14\x00\x008@\x00\x18LMT\x00TMT\x00+0430\x00+0330\x00+05\x00+04\x00\n<+033" +
+	"0>-3:30\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17✳2\x04\x00\x002\x04\x00\x00\r\x00\x00\x00Asia/Tel_AvivTZif3\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xffV\xb6\xc2\xfa\xff\xff\xff\xff\x9e0E\x88\xff\xff\xff\xff\xc8Y\xcf\x00\xff\xff\xff\xff\xc8\xfa\xa6\x00\xff\xff" +
+	"\xff\xff\xc98\x9c\x80\xff\xff\xff\xff\xcc\xe5\xeb\x80\xff\xff\xff\xffͬ\xfe\x00\xff\xff\xff\xff\xce\xc7\x1f\x00\xff\xff\xff\xffϏ\x83\x00\xff\xff\xff\xffЩ\xa4\x00\xff\xff\xff\xffф}\x00\xff\xff\xff\xffҊ" +
+	"׀\xff\xff\xff\xff\xd3e\xb0\x80\xff\xff\xff\xff\xd4l\v\x00\xff\xff\xff\xff\xd7Z0\x80\xff\xff\xff\xff\xd7\xdfX\x00\xff\xff\xff\xff\xd8/À\xff\xff\xff\xff\xd9\x1ec\x00\xff\xff\xff\xff\xda\x10\xf7\x00\xff\xff" +
+	"\xff\xff\xda\xeb\xd0\x00\xff\xff\xff\xff۴4\x00\xff\xff\xff\xffܹ=\x00\xff\xff\xff\xff\xdd\xe0\x8d\x00\xff\xff\xff\xff\u07b4\u0380\xff\xff\xff\xffߤ\xbf\x80\xff\xff\xff\xff\xe0\x8bv\x00\xff\xff\xff\xff\xe1V" +
+	"}\x00\xff\xff\xff\xff\xe2\xbef\x80\xff\xff\xff\xff\xe36_\x00\xff\xff\xff\xff\xe4\x9eH\x80\xff\xff\xff\xff\xe5\x16A\x00\xff\xff\xff\xff\xe6t\xf0\x00\xff\xff\xff\xff\xe7\x11Ҁ\xff\xff\xff\xff\xe8&\xad\x80\xff\xff" +
+	"\xff\xff\xe8\xe8z\x00\x00\x00\x00\x00\b|\x8b\xe0\x00\x00\x00\x00\b\xfd\xb0\xd0\x00\x00\x00\x00\t\xf6\xea`\x00\x00\x00\x00\n\xa63\xd0\x00\x00\x00\x00\x13\xe9\xfc`\x00\x00\x00\x00\x14![`\x00\x00\x00\x00\x1a\xfa" +
+	"\xc6`\x00\x00\x00\x00\x1b\x8en`\x00\x00\x00\x00\x1c\xbe\xf8\xe0\x00\x00\x00\x00\x1dw|\xd0\x00\x00\x00\x00\x1e\xcc\xff`\x00\x00\x00\x00\x1f`\x99P\x00\x00\x00\x00 \x82\xb1`\x00\x00\x00\x00!I\xb5\xd0\x00\x00" +
+	"\x00\x00\"^\x9e\xe0\x00\x00\x00\x00# ]P\x00\x00\x00\x00$Z0`\x00\x00\x00\x00%\x00?P\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00&\xd6\xe6\xd0\x00\x00\x00\x00'\xeb\xcf\xe0\x00\x00\x00\x00(\xc0" +
+	"\x03P\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xa9\x1f\xd0\x00\x00\x00\x00+\xbbe\xe0\x00\x00\x00\x00,\x89\x01\xd0\x00\x00\x00\x00-\x9bG\xe0\x00\x00\x00\x00._\xa9P\x00\x00\x00\x00/{)\xe0\x00\x00" +
+	"\x00\x000H\xc5\xd0\x00\x00\x00\x001H\x96\xe0\x00\x00\x00\x002<nP\x00\x00\x00\x0031\xb3`\x00\x00\x00\x004\x1a\xfe\xd0\x00\x00\x00\x005\x11\x95`\x00\x00\x00\x005\xf1\xa6P\x00\x00\x00\x007\x04" +
+	"\b\x80\x00\x00\x00\x007\xcf\x01p\x00\x00\x00\x008\xf6_\x80\x00\x00\x00\x009\xdc\xf9\xe0\x00\x00\x00\x00:\xd0\xedp\x00\x00\x00\x00;\xae[`\x00\x00\x00\x00<\xa3\xa0p\x00\x00\x00\x00=\xa0\xb2`\x00\x00" +
+	"\x00\x00>\x83\x82p\x00\x00\x00\x00?|\x9f\xe0\x00\x00\x00\x00@s6p\x00\x00\x00\x00AP\xa4`\x00\x00\x00\x00BL\x8f\x00\x00\x00\x00\x00CHOp\x00\x00\x00\x00D,q\x00\x00\x00\x00\x00E\x1e" +
+	"\xf6\xf0\x00\x00\x00\x00F\fS\x00\x00\x00\x00\x00F\xecc\xf0\x00\x00\x00\x00G\xec5\x00\x00\x00\x00\x00H\xe7\xf5p\x00\x00\x00\x00I\xcc\x17\x00\x00\x00\x00\x00J\xbe\x9c\xf0\x00\x00\x00\x00K\xab\xf9\x00\x00\x00" +
+	"\x00\x00L\x8c\t\xf0\x00\x00\x00\x00M\x95\x15\x80\x00\x00\x00\x00N\x87\x9bp\x00\x00\x00\x00Ot\xf7\x80\x00\x00\x00\x00P^B\xf0\x00\x00\x00\x00QTـ\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00!\x06\x00\x00\x00\x00 \xf8\x00\x04\x00\x00*0\x01\b\x00\x00\x1c \x00\f\x00\x008@\x01\x10LMT\x00" +
+	"JMT\x00IDT\x00IST\x00IDDT\x00\nIST-2IDT,M3.4.4/26,M10.5.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00j" +
+	"$\xcd\xf4\x9a\x00\x00\x00\x9a\x00\x00\x00\v\x00\x00\x00Asia/ThimbuTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00" +
+	"\x0e\xff\xff\xff\xff\xd5\xe6\x15t\x00\x00\x00\x00!aM\xa8\x01\x02\x00\x00T\f\x00\x00\x00\x00MX\x00\x04\x00\x00T`\x00\nLMT\x00+0530\x00+06\x00\n<+06>-6\n" +
+	"PK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00j$\xcd\xf4\x9a\x00\x00\x00\x9a\x00\x00\x00\f\x00\x00\x00Asia/ThimphuTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
 	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xff\x92檠\xff\xff\xff\xff̕\x9c \xff\xff\xff\xff\xd2t|\x10\x00\x00\x00\x00\v\x17\xf7@\x01\x02\x01\x03\xff\xff\xe9\xf4\x00\x00\xff" +
-	"\xff\xe3\xe0\x00\x04\xff\xff\xf1\xf0\x01\b\xff\xff\xf1\xf0\x00\bLMT\x00-02\x00-01\x00\n<-01>1\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe8\x8dY\x80\xad\x05\x00\x00\xad" +
-	"\x05\x00\x00\x0f\x00\x1c\x00Atlantic/AzoresUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c\x00\x00\x00\a\x00\x00\x00\x18\xff\xff\xff\xff^=\x1b\x90\xff\xff\xff\xff\x92檠\xff\xff\xff\xff\x9bK\x89\x90\xff\xff\xff\xff\x9b\xfe\xe3\xa0\xff\xff\xff" +
-	"\xff\x9c\x9d\t\x90\xff\xff\xff\xff\x9dɟ\x90\xff\xff\xff\xff\x9e\x7f\x8e\x90\xff\xff\xff\xff\x9f\xaa\xd3\x10\xff\xff\xff\xff\xa0_p\x90\xff\xff\xff\xff\xa1\x8c\x06\x90\xff\xff\xff\xff\xa2A\xf5\x90\xff\xff\xff\xff\xa3n\x8b" +
-	"\x90\xff\xff\xff\xff\xa4#)\x10\xff\xff\xff\xff\xa5O\xbf\x10\xff\xff\xff\xff\xaa\x06\v\x90\xff\xff\xff\xff\xaa\xf4\xab\x10\xff\xff\xff\xff\xad\xc9\xc4\x10\xff\xff\xff\xff\xae\xa7@\x10\xff\xff\xff\xff\xaf\xa0k\x90\xff\xff\xff" +
-	"\xff\xb0\x87\"\x10\xff\xff\xff\xff\xb1\x89\x88\x10\xff\xff\xff\xff\xb2p>\x90\xff\xff\xff\xff\xb3r\xa4\x90\xff\xff\xff\xff\xb4P \x90\xff\xff\xff\xff\xb72h\x90\xff\xff\xff\xff\xb8\x0f\xe4\x90\xff\xff\xff\xff\xb8\xff\xd5" +
-	"\x90\xff\xff\xff\xff\xb9\xefƐ\xff\xff\xff\xff\xbc\xc8\xd4\x10\xff\xff\xff\xff\xbd\xb8\xc5\x10\xff\xff\xff\xff\xbe\x9f{\x90\xff\xff\xff\xff\xbf\x98\xa7\x10\xff\xff\xff\xff\xc0\x9b\r\x10\xff\xff\xff\xff\xc1x\x89\x10\xff\xff\xff" +
-	"\xff\xc2hz\x10\xff\xff\xff\xff\xc3Xk\x10\xff\xff\xff\xff\xc4?!\x90\xff\xff\xff\xff\xc58M\x10\xff\xff\xff\xff\xc6:\xb3\x10\xff\xff\xff\xff\xc7XȐ\xff\xff\xff\xff\xc7\xd9\xfb\x90\xff\xff\xff\xff\xc9\x01K" +
-	"\x90\xff\xff\xff\xff\xc9\xf1<\x90\xff\xff\xff\xff\xca\xe2\x7f\x10\xff\xff\xff\xff˵o\x10\xff\xff\xff\xff\xcb\xec\xc0\x00\xff\xff\xff\xff̀h\x00\xff\xff\xff\xff\xccܿ\x10\xff\xff\xff\xff͕Q\x10\xff\xff\xff" +
-	"\xff\xcd\xc3g\x80\xff\xff\xff\xff\xcer\xbf\x00\xff\xff\xff\xff\xce\xc5ې\xff\xff\xff\xff\xcfu3\x10\xff\xff\xff\xffϬ\x84\x00\xff\xff\xff\xff\xd0R\xa1\x00\xff\xff\xff\xffХ\xbd\x90\xff\xff\xff\xff\xd1U\x15" +
-	"\x10\xff\xff\xff\xffьf\x00\xff\xff\xff\xff\xd22\x83\x00\xff\xff\xff\xff҅\x9f\x90\xff\xff\xff\xff\xd3Y\xe1\x10\xff\xff\xff\xff\xd4I\xd2\x10\xff\xff\xff\xff\xd59\xed@\xff\xff\xff\xff\xd6)\xde@\xff\xff\xff" +
-	"\xff\xd7\x19\xcf@\xff\xff\xff\xff\xd8\t\xc0@\xff\xff\xff\xff\xd8\xf9\xb1@\xff\xff\xff\xff\xd9\xe9\xa2@\xff\xff\xff\xff\xdaٓ@\xff\xff\xff\xff\xdbɄ@\xff\xff\xff\xffܹu@\xff\xff\xff\xffݲ\xa0" +
-	"\xc0\xff\xff\xff\xffޢ\x91\xc0\xff\xff\xff\xffߒ\x82\xc0\xff\xff\xff\xff\xe0\x82s\xc0\xff\xff\xff\xff\xe1rd\xc0\xff\xff\xff\xff\xe2bU\xc0\xff\xff\xff\xff\xe3RF\xc0\xff\xff\xff\xff\xe4B7\xc0\xff\xff\xff" +
-	"\xff\xe52(\xc0\xff\xff\xff\xff\xe6\"\x19\xc0\xff\xff\xff\xff\xe7\x1bE@\xff\xff\xff\xff\xe8\v6@\xff\xff\xff\xff\xe8\xfb'@\xff\xff\xff\xff\xe9\xeb\x18@\xff\xff\xff\xff\xea\xdb\t@\xff\xff\xff\xff\xeb\xca\xfa" +
-	"@\xff\xff\xff\xff\xec\xba\xeb@\xff\xff\xff\xff\xed\xaa\xdc@\xff\xff\xff\xff\xee\x9a\xcd@\xff\xff\xff\xff\uf2be@\xff\xff\xff\xff\xf0z\xaf@\xff\xff\xff\xff\xf1j\xa0@\xff\xff\xff\xff\xf2c\xcb\xc0\xff\xff\xff" +
-	"\xff\xf3S\xbc\xc0\xff\xff\xff\xff\xf4C\xad\xc0\xff\xff\xff\xff\xf53\x9e\xc0\xff\xff\xff\xff\xf6#\x8f\xc0\xff\xff\xff\xff\xf7\x13\x80\xc0\xff\xff\xff\xff\xf8\x03q\xc0\xff\xff\xff\xff\xf8\xf3b\xc0\x00\x00\x00\x00\r\x9b)" +
-	"\x10\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T&\xa0\x00\x00\x00\x00\x13D\t\x90\x00\x00\x00\x00\x144\b\xa0\x00\x00\x00" +
-	"\x00\x15#\xf9\xa0\x00\x00\x00\x00\x16\x13\xea\xa0\x00\x00\x00\x00\x17\x03۠\x00\x00\x00\x00\x17\xf3̠\x00\x00\x00\x00\x18\xe3˰\x00\x00\x00\x00\x19Ӯ\xa0\x00\x00\x00\x00\x1aß\xa0\x00\x00\x00\x00\x1b\xbc\xcb" +
-	" \x00\x00\x00\x00\x1c\xac\xbc \x00\x00\x00\x00\x1d\x9c\xad \x00\x00\x00\x00\x1e\x8c\x9e \x00\x00\x00\x00\x1f|\x8f \x00\x00\x00\x00 l\x80 \x00\x00\x00\x00!\\q \x00\x00\x00\x00\"Lb \x00\x00\x00" +
-	"\x00#<S \x00\x00\x00\x00$,D \x00\x00\x00\x00%\x1c5 \x00\x00\x00\x00&\f& \x00\x00\x00\x00'\x05Q\xa0\x00\x00\x00\x00'\xf5B\xa0\x00\x00\x00\x00(\xe53\xa0\x00\x00\x00\x00)\xd5$" +
-	"\xa0\x00\x00\x00\x00*\xc5\x15\xa0\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00" +
-	"\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x02\x03\x02\x04\x02\x03\x02\x04\x02" +
-	"\x03\x02\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" +
-	"\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\x04\x05\x04\x05\x04\x05\x04\xff\xff\xe7\xf0\x00\x00\xff\xff\xe5(\x00\x04\xff\xff\xf1\xf0\x01\b\xff\xff\xe3\xe0\x00\f\x00\x00\x00\x00\x01\x10\xff\xff\xf1\xf0\x00" +
-	"\b\x00\x00\x00\x00\x00\x14LMT\x00HMT\x00-01\x00-02\x00+00\x00WET\x00\n<-01>1<+00>,M3.5.0/0,M10.5.0" +
-	"/1\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT1)7\xad\xad\x05\x00\x00\xad\x05\x00\x00\x10\x00\x1c\x00Atlantic/MadeiraUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc" +
-	"\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" +
-	"\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c\x00\x00\x00\a\x00\x00\x00\x1d\xff\xff\xff\xff^=\x13X" +
-	"\xff\xff\xff\xff\x92朐\xff\xff\xff\xff\x9bK{\x80\xff\xff\xff\xff\x9b\xfeՐ\xff\xff\xff\xff\x9c\x9c\xfb\x80\xff\xff\xff\xff\x9dɑ\x80\xff\xff\xff\xff\x9e\x7f\x80\x80\xff\xff\xff\xff\x9f\xaa\xc5\x00\xff\xff\xff\xff" +
-	"\xa0_b\x80\xff\xff\xff\xff\xa1\x8b\xf8\x80\xff\xff\xff\xff\xa2A\xe7\x80\xff\xff\xff\xff\xa3n}\x80\xff\xff\xff\xff\xa4#\x1b\x00\xff\xff\xff\xff\xa5O\xb1\x00\xff\xff\xff\xff\xaa\x05\xfd\x80\xff\xff\xff\xff\xaa\xf4\x9d\x00" +
-	"\xff\xff\xff\xff\xadɶ\x00\xff\xff\xff\xff\xae\xa72\x00\xff\xff\xff\xff\xaf\xa0]\x80\xff\xff\xff\xff\xb0\x87\x14\x00\xff\xff\xff\xff\xb1\x89z\x00\xff\xff\xff\xff\xb2p0\x80\xff\xff\xff\xff\xb3r\x96\x80\xff\xff\xff\xff" +
-	"\xb4P\x12\x80\xff\xff\xff\xff\xb72Z\x80\xff\xff\xff\xff\xb8\x0fր\xff\xff\xff\xff\xb8\xffǀ\xff\xff\xff\xff\xb9︀\xff\xff\xff\xff\xbc\xc8\xc6\x00\xff\xff\xff\xff\xbd\xb8\xb7\x00\xff\xff\xff\xff\xbe\x9fm\x80" +
-	"\xff\xff\xff\xff\xbf\x98\x99\x00\xff\xff\xff\xff\xc0\x9a\xff\x00\xff\xff\xff\xff\xc1x{\x00\xff\xff\xff\xff\xc2hl\x00\xff\xff\xff\xff\xc3X]\x00\xff\xff\xff\xff\xc4?\x13\x80\xff\xff\xff\xff\xc58?\x00\xff\xff\xff\xff" +
-	"\xc6:\xa5\x00\xff\xff\xff\xff\xc7X\xba\x80\xff\xff\xff\xff\xc7\xd9\xed\x80\xff\xff\xff\xff\xc9\x01=\x80\xff\xff\xff\xff\xc9\xf1.\x80\xff\xff\xff\xff\xca\xe2q\x00\xff\xff\xff\xff˵a\x00\xff\xff\xff\xff\xcb\xec\xb1\xf0" +
-	"\xff\xff\xff\xff̀Y\xf0\xff\xff\xff\xff\xccܱ\x00\xff\xff\xff\xff͕C\x00\xff\xff\xff\xff\xcd\xc3Yp\xff\xff\xff\xff\xcer\xb0\xf0\xff\xff\xff\xff\xce\xc5̀\xff\xff\xff\xff\xcfu%\x00\xff\xff\xff\xff" +
-	"Ϭu\xf0\xff\xff\xff\xff\xd0R\x92\xf0\xff\xff\xff\xffХ\xaf\x80\xff\xff\xff\xff\xd1U\a\x00\xff\xff\xff\xffьW\xf0\xff\xff\xff\xff\xd22t\xf0\xff\xff\xff\xff҅\x91\x80\xff\xff\xff\xff\xd3Y\xd3\x00" +
-	"\xff\xff\xff\xff\xd4I\xc4\x00\xff\xff\xff\xff\xd59\xdf0\xff\xff\xff\xff\xd6)\xd00\xff\xff\xff\xff\xd7\x19\xc10\xff\xff\xff\xff\xd8\t\xb20\xff\xff\xff\xff\xd8\xf9\xa30\xff\xff\xff\xff\xd9\xe9\x940\xff\xff\xff\xff" +
-	"\xdaم0\xff\xff\xff\xff\xdb\xc9v0\xff\xff\xff\xffܹg0\xff\xff\xff\xffݲ\x92\xb0\xff\xff\xff\xffޢ\x83\xb0\xff\xff\xff\xffߒt\xb0\xff\xff\xff\xff\xe0\x82e\xb0\xff\xff\xff\xff\xe1rV\xb0" +
-	"\xff\xff\xff\xff\xe2bG\xb0\xff\xff\xff\xff\xe3R8\xb0\xff\xff\xff\xff\xe4B)\xb0\xff\xff\xff\xff\xe52\x1a\xb0\xff\xff\xff\xff\xe6\"\v\xb0\xff\xff\xff\xff\xe7\x1b70\xff\xff\xff\xff\xe8\v(0\xff\xff\xff\xff" +
-	"\xe8\xfb\x190\xff\xff\xff\xff\xe9\xeb\n0\xff\xff\xff\xff\xea\xda\xfb0\xff\xff\xff\xff\xeb\xca\xec0\xff\xff\xff\xff\xec\xba\xdd0\xff\xff\xff\xff\xed\xaa\xce0\xff\xff\xff\xff\ue6bf0\xff\xff\xff\xff\uf2b00" +
-	"\xff\xff\xff\xff\xf0z\xa10\xff\xff\xff\xff\xf1j\x920\xff\xff\xff\xff\xf2c\xbd\xb0\xff\xff\xff\xff\xf3S\xae\xb0\xff\xff\xff\xff\xf4C\x9f\xb0\xff\xff\xff\xff\xf53\x90\xb0\xff\xff\xff\xff\xf6#\x81\xb0\xff\xff\xff\xff" +
-	"\xf7\x13r\xb0\xff\xff\xff\xff\xf8\x03c\xb0\xff\xff\xff\xff\xf8\xf3T\xb0\x00\x00\x00\x00\r\x9b\x1b\x00\x00\x00\x00\x00\x0e\x8b\f\x00\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00\x10t(\x80\x00\x00\x00\x00\x11d\x19\x80" +
-	"\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13C\xfb\x80\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00" +
-	"\x18㽠\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10" +
-	"\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00" +
-	"'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ" +
-	"\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
-	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x02\x03\x02\x04\x02\x03\x02\x04\x02\x03\x02\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
-	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\xff\xff\xf0(\x00\x00\xff\xff" +
-	"\xf0(\x00\x04\x00\x00\x00\x00\x01\b\xff\xff\xf1\xf0\x00\f\x00\x00\x0e\x10\x01\x10\x00\x00\x0e\x10\x01\x14\x00\x00\x00\x00\x00\x19LMT\x00FMT\x00+00\x00-01\x00+01\x00WEST\x00W" +
-	"ET\x00\nWET0WEST,M3.5.0/1,M10.5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x1c\x00" +
-	"Australia/UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9b\xe1\xc1\xa9\x88\x03\x00\x00" +
-	"\x88\x03\x00\x00\x13\x00\x1c\x00Australia/MelbourneUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x85\x18\xff\xff\xff\xff\x9cN\u0080\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\xcbT" +
-	"\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff̷V\x80\xff\xff\xff\xffͧG\x80\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ)\x80\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00" +
-	"\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00\a/\xfd\x80\x00\x00\x00\x00\a\xd6\x1a\x80\x00\x00\x00\x00\t\x0f߀\x00\x00\x00\x00\t\xb5\xfc\x80\x00\x00\x00\x00\n\xef\xc1\x80\x00\x00\x00\x00\v\x9f" +
-	"\x19\x00\x00\x00\x00\x00\f\xd8\xde\x00\x00\x00\x00\x00\r~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00" +
-	"\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x16矀\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18ǁ\x80\x00\x00\x00\x00\x1a\x01" +
-	"F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\n\x80\x00\x00\x00\x00\x1ey\x9c\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00" +
-	"\x00\x00!w\x94\x00\x00\x00\x00\x00\"B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\"}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00&\x02_\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xcf" +
-	"\xcc\x00\x00\x00\x00\x00)\t\x91\x00\x00\x00\x00\x00)\xaf\xae\x00\x00\x00\x00\x00*\xe9s\x00\x00\x00\x00\x00+\x98ʀ\x00\x00\x00\x00,ҏ\x80\x00\x00\x00\x00-x\xac\x80\x00\x00\x00\x00.\xb2q\x80\x00\x00" +
-	"\x00\x00/t>\x00\x00\x00\x00\x000\x92S\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002r5\x80\x00\x00\x00\x003=<\x80\x00\x00\x00\x004R\x17\x80\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x0061" +
-	"\xf9\x80\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x008\x1b\x16\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbcĀ\x00\x00\x00\x00;\xda\xda\x00\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00" +
-	"\x00\x00=\xba\xbc\x00\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?\x9a\x9e\x00\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D." +
-	"\xa3\x80\x00\x00\x00\x00EC~\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xf7\xa2\x00\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x87" +
-	"\xe8\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\nAEST-10AEDT,M10.1.0,M4.1.0/3\nP" +
-	"K\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT3\xba\xde\xd3!\x01\x00\x00!\x01\x00\x00\x14\x00\x1c\x00Australia/QueenslandUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc" +
-	"\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xff\xd5\xe6\x15t\x00\x00\x00\x00!aM\xa8\x01\x02\x00\x00T\f\x00\x00\x00\x00MX\x00\x04\x00\x00T`\x00\nLMT\x00+05" +
+	"30\x00+06\x00\n<+06>-6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xf4\xaeg\xd5\x00\x00\x00\xd5\x00\x00\x00\n\x00\x00\x00Asia/TokyoTZif" +
+	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xffe¤p\xff\xff\xff\xff\xd7>\x02p\xff\xff\xff\xff\xd7\xedY\xf0\xff\xff\xff\xff\xd8" +
+	"\xf8\xfap\xff\xff\xff\xff\xd9\xcd;\xf0\xff\xff\xff\xff\xdb\a\x00\xf0\xff\xff\xff\xffۭ\x1d\xf0\xff\xff\xff\xff\xdc\xe6\xe2\xf0\xff\xff\xff\xff\u074c\xff\xf0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x83\x03\x00\x00\x00\x00" +
+	"\x8c\xa0\x01\x04\x00\x00~\x90\x00\bLMT\x00JDT\x00JST\x00\nJST-9\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00[u\x99q\xf1\x02\x00\x00\xf1\x02\x00\x00\n\x00\x00\x00A" +
+	"sia/TomskTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" +
+	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00C\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xe5N\xd9\xff\xff\xff\xff\xb5\xa3\xe1 " +
+	"\x00\x00\x00\x00\x15'o\x90\x00\x00\x00\x00\x16\x18\xa4\x00\x00\x00\x00\x00\x17\b\xa3\x10\x00\x00\x00\x00\x17\xf9׀\x00\x00\x00\x00\x18\xe9\u0590\x00\x00\x00\x00\x19\xdb\v\x00\x00\x00\x00\x00\x1a\xcc[\x90\x00\x00\x00\x00" +
+	"\x1b\xbch\xb0\x00\x00\x00\x00\x1c\xacY\xb0\x00\x00\x00\x00\x1d\x9cJ\xb0\x00\x00\x00\x00\x1e\x8c;\xb0\x00\x00\x00\x00\x1f|,\xb0\x00\x00\x00\x00 l\x1d\xb0\x00\x00\x00\x00!\\\x0e\xb0\x00\x00\x00\x00\"K\xff\xb0" +
+	"\x00\x00\x00\x00#;\xf0\xb0\x00\x00\x00\x00$+\xe1\xb0\x00\x00\x00\x00%\x1bҰ\x00\x00\x00\x00&\vð\x00\x00\x00\x00'\x04\xef0\x00\x00\x00\x00'\xf4\xe00\x00\x00\x00\x00(\xe4\xdf@\x00\x00\x00\x00" +
+	")x\x87@\x00\x00\x00\x00)\xd4\xc20\x00\x00\x00\x00*ij0\x00\x00\x00\x00+\xb4\xa40\x00\x00\x00\x00,\xa4\x950\x00\x00\x00\x00-\x94\x860\x00\x00\x00\x00.\x84w0\x00\x00\x00\x00/th0" +
+	"\x00\x00\x00\x000dY0\x00\x00\x00\x001]\x84\xb0\x00\x00\x00\x002r_\xb0\x00\x00\x00\x003=f\xb0\x00\x00\x00\x004RA\xb0\x00\x00\x00\x005\x1dH\xb0\x00\x00\x00\x0062#\xb0\x00\x00\x00\x00" +
+	"6\xfd*\xb0\x00\x00\x00\x008\x1b@0\x00\x00\x00\x008\xdd\f\xb0\x00\x00\x00\x009\xfb\"0\x00\x00\x00\x00:\xbc\xee\xb0\x00\x00\x00\x00;\xdb\x040\x00\x00\x00\x00<\xa6\v0\x00\x00\x00\x00<\xce\xe9\xb0" +
+	"\x00\x00\x00\x00=\xba\xf4@\x00\x00\x00\x00>\x85\xfb@\x00\x00\x00\x00?\x9a\xd6@\x00\x00\x00\x00@e\xdd@\x00\x00\x00\x00A\x83\xf2\xc0\x00\x00\x00\x00BE\xbf@\x00\x00\x00\x00Cc\xd4\xc0\x00\x00\x00\x00" +
+	"D%\xa1@\x00\x00\x00\x00EC\xb6\xc0\x00\x00\x00\x00F\x05\x83@\x00\x00\x00\x00G#\x98\xc0\x00\x00\x00\x00G\xee\x9f\xc0\x00\x00\x00\x00I\x03z\xc0\x00\x00\x00\x00I\u0381\xc0\x00\x00\x00\x00J\xe3\\\xc0" +
+	"\x00\x00\x00\x00K\xaec\xc0\x00\x00\x00\x00L\xccy@\x00\x00\x00\x00M\x8eE\xc0\x00\x00\x00\x00TK\xf30\x00\x00\x00\x00WI\xf8\xc0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x03\x01\x03\x00\x00O\xa7\x00\x00\x00\x00T`\x00\x04\x00" +
+	"\x00p\x80\x01\b\x00\x00bp\x00\f\x00\x00bp\x01\fLMT\x00+06\x00+08\x00+07\x00\n<+07>-7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`\xc9\xd4\\" +
+	"\xbe\x00\x00\x00\xbe\x00\x00\x00\x12\x00\x00\x00Asia/Ujung_PandangTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00" +
+	"\x05\x00\x00\x00\x15\xff\xff\xff\xff\xa1\xf2]\x90\xff\xff\xff\xff\xba\x16Ր\xff\xff\xff\xffˈ\x1d\x80\xff\xff\xff\xff\xd2V\xeep\x01\x02\x03\x04\x00\x00o\xf0\x00\x00\x00\x00o\xf0\x00\x04\x00\x00p\x80\x00\b\x00" +
+	"\x00~\x90\x00\f\x00\x00p\x80\x00\x10LMT\x00MMT\x00+08\x00+09\x00WITA\x00\nWITA-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\xb9\xf4\xb6R\x02" +
+	"\x00\x00R\x02\x00\x00\x10\x00\x00\x00Asia/UlaanbaatarTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x002\x00\x00\x00\x04\x00\x00\x00" +
+	"\x10\xff\xff\xff\xff\x86\xd3\xeeL\x00\x00\x00\x00\x0f\vܐ\x00\x00\x00\x00\x18\xe9Ȁ\x00\x00\x00\x00\x19\xda\xfc\xf0\x00\x00\x00\x00\x1a\xccM\x80\x00\x00\x00\x00\x1b\xbc0p\x00\x00\x00\x00\x1c\xac/\x80\x00\x00\x00" +
+	"\x00\x1d\x9c\x12p\x00\x00\x00\x00\x1e\x8c\x11\x80\x00\x00\x00\x00\x1f{\xf4p\x00\x00\x00\x00 k\xf3\x80\x00\x00\x00\x00![\xd6p\x00\x00\x00\x00\"KՀ\x00\x00\x00\x00#;\xb8p\x00\x00\x00\x00$+\xb7" +
+	"\x80\x00\x00\x00\x00%\x1b\x9ap\x00\x00\x00\x00&\v\x99\x80\x00\x00\x00\x00'\x04\xb6\xf0\x00\x00\x00\x00'\xf4\xb6\x00\x00\x00\x00\x00(\xe4\x98\xf0\x00\x00\x00\x00)Ԙ\x00\x00\x00\x00\x00*\xc4z\xf0\x00\x00\x00" +
+	"\x00+\xb4z\x00\x00\x00\x00\x00,\xa4\\\xf0\x00\x00\x00\x00-\x94\\\x00\x00\x00\x00\x00.\x84>\xf0\x00\x00\x00\x00/t>\x00\x00\x00\x00\x000d \xf0\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002M=" +
+	"p\x00\x00\x00\x003=<\x80\x00\x00\x00\x004-\x1fp\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x006\r\x01p\x00\x00\x00\x00:鳠\x00\x00\x00\x00;\xb4\xac\x90\x00\x00\x00\x00<\xa4\xab\xa0\x00\x00\x00" +
+	"\x00=\x94\x8e\x90\x00\x00\x00\x00>\x84\x8d\xa0\x00\x00\x00\x00?tp\x90\x00\x00\x00\x00@do\xa0\x00\x00\x00\x00ATR\x90\x00\x00\x00\x00BDQ\xa0\x00\x00\x00\x00C44\x90\x00\x00\x00\x00D$3" +
+	"\xa0\x00\x00\x00\x00E\x1dQ\x10\x00\x00\x00\x00U\x15\x9a\xa0\x00\x00\x00\x00V\x05ap\x00\x00\x00\x00V\xf5|\xa0\x00\x00\x00\x00W\xe5Cp\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00d4\x00\x00\x00\x00bp\x00\x04\x00\x00~\x90\x01\b\x00\x00p\x80\x00\fLMT\x00+" +
+	"07\x00+09\x00+08\x00\n<+08>-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\xb9\xf4\xb6R\x02\x00\x00R\x02\x00\x00\x0f\x00\x00\x00Asia/Ulan_" +
+	"BatorTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif" +
+	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x002\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\x86\xd3\xeeL\x00\x00\x00\x00\x0f\vܐ\x00\x00\x00\x00" +
+	"\x18\xe9Ȁ\x00\x00\x00\x00\x19\xda\xfc\xf0\x00\x00\x00\x00\x1a\xccM\x80\x00\x00\x00\x00\x1b\xbc0p\x00\x00\x00\x00\x1c\xac/\x80\x00\x00\x00\x00\x1d\x9c\x12p\x00\x00\x00\x00\x1e\x8c\x11\x80\x00\x00\x00\x00\x1f{\xf4p" +
+	"\x00\x00\x00\x00 k\xf3\x80\x00\x00\x00\x00![\xd6p\x00\x00\x00\x00\"KՀ\x00\x00\x00\x00#;\xb8p\x00\x00\x00\x00$+\xb7\x80\x00\x00\x00\x00%\x1b\x9ap\x00\x00\x00\x00&\v\x99\x80\x00\x00\x00\x00" +
+	"'\x04\xb6\xf0\x00\x00\x00\x00'\xf4\xb6\x00\x00\x00\x00\x00(\xe4\x98\xf0\x00\x00\x00\x00)Ԙ\x00\x00\x00\x00\x00*\xc4z\xf0\x00\x00\x00\x00+\xb4z\x00\x00\x00\x00\x00,\xa4\\\xf0\x00\x00\x00\x00-\x94\\\x00" +
+	"\x00\x00\x00\x00.\x84>\xf0\x00\x00\x00\x00/t>\x00\x00\x00\x00\x000d \xf0\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002M=p\x00\x00\x00\x003=<\x80\x00\x00\x00\x004-\x1fp\x00\x00\x00\x00" +
+	"5\x1d\x1e\x80\x00\x00\x00\x006\r\x01p\x00\x00\x00\x00:鳠\x00\x00\x00\x00;\xb4\xac\x90\x00\x00\x00\x00<\xa4\xab\xa0\x00\x00\x00\x00=\x94\x8e\x90\x00\x00\x00\x00>\x84\x8d\xa0\x00\x00\x00\x00?tp\x90" +
+	"\x00\x00\x00\x00@do\xa0\x00\x00\x00\x00ATR\x90\x00\x00\x00\x00BDQ\xa0\x00\x00\x00\x00C44\x90\x00\x00\x00\x00D$3\xa0\x00\x00\x00\x00E\x1dQ\x10\x00\x00\x00\x00U\x15\x9a\xa0\x00\x00\x00\x00" +
+	"V\x05ap\x00\x00\x00\x00V\xf5|\xa0\x00\x00\x00\x00W\xe5Cp\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00d4\x00\x00\x00\x00bp\x00\x04\x00\x00~\x90\x01\b\x00\x00p\x80\x00\fLMT\x00+07\x00+09\x00+08\x00\n<+08>-8\nP" +
+	"K\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x1d\xc6\x1b\x85\x00\x00\x00\x85\x00\x00\x00\v\x00\x00\x00Asia/UrumqiTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xb0\xfe\xbad\x01\x00\x00R\x1c\x00\x00\x00\x00T`\x00\x04LMT\x00+06\x00\n<+06>-6\nPK\x03\x04\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00w\x86\x8d^\x03\x03\x00\x00\x03\x03\x00\x00\r\x00\x00\x00Asia/Ust-NeraTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00B\x00\x00\x00\b\x00\x00\x00\x18\xff\xff\xff\xff\xa1\xdbݺ\xff\xff\xff\xff\xb5\xa3\xc5\x00\x00\x00\x00\x00\x15'Sp\x00\x00\x00\x00\x16\x18k\xc0\x00\x00\x00\x00\x17\bj\xd0\x00\x00\x00\x00\x17\xf9\x9f@\x00" +
+	"\x00\x00\x00\x18\xe9\x9eP\x00\x00\x00\x00\x19\xda\xd2\xc0\x00\x00\x00\x00\x1a\xcc#P\x00\x00\x00\x00\x1b\xbc0p\x00\x00\x00\x00\x1c\xac!p\x00\x00\x00\x00\x1d\x9c\x12p\x00\x00\x00\x00\x1e\x8c\x03p\x00\x00\x00\x00\x1f" +
+	"{\xf4p\x00\x00\x00\x00 k\xe5p\x00\x00\x00\x00![\xd6p\x00\x00\x00\x00\"K\xc7p\x00\x00\x00\x00#;\xb8p\x00\x00\x00\x00$+\xa9p\x00\x00\x00\x00%\x1b\x9ap\x00\x00\x00\x00&\v\x8bp\x00" +
+	"\x00\x00\x00'\x04\xb6\xf0\x00\x00\x00\x00'\xf4\xa7\xf0\x00\x00\x00\x00(\xe4\xa7\x00\x00\x00\x00\x00)xO\x00\x00\x00\x00\x00)ԉ\xf0\x00\x00\x00\x00*\xc4z\xf0\x00\x00\x00\x00+\xb4k\xf0\x00\x00\x00\x00," +
+	"\xa4\\\xf0\x00\x00\x00\x00-\x94M\xf0\x00\x00\x00\x00.\x84>\xf0\x00\x00\x00\x00/t/\xf0\x00\x00\x00\x000d \xf0\x00\x00\x00\x001]Lp\x00\x00\x00\x002r'p\x00\x00\x00\x003=.p\x00" +
+	"\x00\x00\x004R\tp\x00\x00\x00\x005\x1d\x10p\x00\x00\x00\x0061\xebp\x00\x00\x00\x006\xfc\xf2p\x00\x00\x00\x008\x1b\a\xf0\x00\x00\x00\x008\xdc\xd4p\x00\x00\x00\x009\xfa\xe9\xf0\x00\x00\x00\x00:" +
+	"\xbc\xb6p\x00\x00\x00\x00;\xda\xcb\xf0\x00\x00\x00\x00<\xa5\xd2\xf0\x00\x00\x00\x00=\xba\xad\xf0\x00\x00\x00\x00>\x85\xb4\xf0\x00\x00\x00\x00?\x9a\x8f\xf0\x00\x00\x00\x00@e\x96\xf0\x00\x00\x00\x00A\x83\xacp\x00" +
+	"\x00\x00\x00BEx\xf0\x00\x00\x00\x00Cc\x8ep\x00\x00\x00\x00D%Z\xf0\x00\x00\x00\x00ECpp\x00\x00\x00\x00F\x05<\xf0\x00\x00\x00\x00G#Rp\x00\x00\x00\x00G\xeeYp\x00\x00\x00\x00I" +
+	"\x034p\x00\x00\x00\x00I\xce;p\x00\x00\x00\x00J\xe3\x16p\x00\x00\x00\x00K\xae\x1dp\x00\x00\x00\x00L\xcc2\xf0\x00\x00\x00\x00M\x8d\xffp\x00\x00\x00\x00Nm\xf4@\x00\x00\x00\x00TK\xba\xf0\x01" +
+	"\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x05\x06\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" +
+	"\x04\x03\a\x03\x06\x00\x00\x86F\x00\x00\x00\x00p\x80\x00\x04\x00\x00~\x90\x00\b\x00\x00\x9a\xb0\x00\f\x00\x00\xa8\xc0\x01\x10\x00\x00\x9a\xb0\x01\f\x00\x00\x8c\xa0\x00\x14\x00\x00\xa8\xc0\x00\x10LMT\x00+08" +
+	"\x00+09\x00+11\x00+12\x00+10\x00\n<+10>-10\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x88\xf6C\x84\x98\x00\x00\x00\x98\x00\x00\x00\x0e\x00\x00\x00Asi" +
+	"a/VientianeTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00" +
+	"\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xffV\xb6\x85\xc4\xff\xff\xff\xff\xa2j" +
+	"g\xc4\x01\x02\x00\x00^<\x00\x00\x00\x00^<\x00\x04\x00\x00bp\x00\bLMT\x00BMT\x00+07\x00\n<+07>-7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d%\x05" +
+	"\xd8\xe6\x02\x00\x00\xe6\x02\x00\x00\x10\x00\x00\x00Asia/VladivostokTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00A\x00\x00\x00\x06" +
+	"\x00\x00\x00\x10\xff\xff\xff\xff\xa7YG]\xff\xff\xff\xff\xb5\xa3\xb6\xf0\x00\x00\x00\x00\x15'E`\x00\x00\x00\x00\x16\x18y\xd0\x00\x00\x00\x00\x17\bx\xe0\x00\x00\x00\x00\x17\xf9\xadP\x00\x00\x00\x00\x18\xe9\xac`" +
+	"\x00\x00\x00\x00\x19\xda\xe0\xd0\x00\x00\x00\x00\x1a\xcc1`\x00\x00\x00\x00\x1b\xbc>\x80\x00\x00\x00\x00\x1c\xac/\x80\x00\x00\x00\x00\x1d\x9c \x80\x00\x00\x00\x00\x1e\x8c\x11\x80\x00\x00\x00\x00\x1f|\x02\x80\x00\x00\x00\x00" +
+	" k\xf3\x80\x00\x00\x00\x00![\xe4\x80\x00\x00\x00\x00\"KՀ\x00\x00\x00\x00#;ƀ\x00\x00\x00\x00$+\xb7\x80\x00\x00\x00\x00%\x1b\xa8\x80\x00\x00\x00\x00&\v\x99\x80\x00\x00\x00\x00'\x04\xc5\x00" +
+	"\x00\x00\x00\x00'\xf4\xb6\x00\x00\x00\x00\x00(\xe4\xb5\x10\x00\x00\x00\x00)x]\x10\x00\x00\x00\x00)Ԙ\x00\x00\x00\x00\x00*ĉ\x00\x00\x00\x00\x00+\xb4z\x00\x00\x00\x00\x00,\xa4k\x00\x00\x00\x00\x00" +
+	"-\x94\\\x00\x00\x00\x00\x00.\x84M\x00\x00\x00\x00\x00/t>\x00\x00\x00\x00\x000d/\x00\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002r5\x80\x00\x00\x00\x003=<\x80\x00\x00\x00\x004R\x17\x80" +
+	"\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x0061\xf9\x80\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x008\x1b\x16\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xfa\xf8\x00\x00\x00\x00\x00:\xbcĀ\x00\x00\x00\x00" +
+	";\xda\xda\x00\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\xba\xbc\x00\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?\x9a\x9e\x00\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00" +
+	"\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D%i\x00\x00\x00\x00\x00EC~\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xeeg\x80\x00\x00\x00\x00I\x03B\x80\x00\x00\x00\x00" +
+	"I\xceI\x80\x00\x00\x00\x00J\xe3$\x80\x00\x00\x00\x00K\xae+\x80\x00\x00\x00\x00L\xccA\x00\x00\x00\x00\x00M\x8e\r\x80\x00\x00\x00\x00TK\xba\xf0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x03\x00\x00{\xa3\x00\x00\x00\x00~\x90\x00" +
+	"\x04\x00\x00\x9a\xb0\x01\b\x00\x00\x8c\xa0\x00\f\x00\x00\x8c\xa0\x01\f\x00\x00\x9a\xb0\x00\bLMT\x00+09\x00+11\x00+10\x00\n<+10>-10\nPK\x03\x04\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00O\xb0\x03\xe9\xe5\x02\x00\x00\xe5\x02\x00\x00\f\x00\x00\x00Asia/YakutskTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00A" +
+	"\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xdb\xea^\xff\xff\xff\xff\xb5\xa3\xc5\x00\x00\x00\x00\x00\x15'Sp\x00\x00\x00\x00\x16\x18\x87\xe0\x00\x00\x00\x00\x17\b\x86\xf0\x00\x00\x00\x00\x17\xf9\xbb`\x00\x00\x00\x00" +
+	"\x18\xe9\xbap\x00\x00\x00\x00\x19\xda\xee\xe0\x00\x00\x00\x00\x1a\xcc?p\x00\x00\x00\x00\x1b\xbcL\x90\x00\x00\x00\x00\x1c\xac=\x90\x00\x00\x00\x00\x1d\x9c.\x90\x00\x00\x00\x00\x1e\x8c\x1f\x90\x00\x00\x00\x00\x1f|\x10\x90" +
+	"\x00\x00\x00\x00 l\x01\x90\x00\x00\x00\x00![\xf2\x90\x00\x00\x00\x00\"K\xe3\x90\x00\x00\x00\x00#;Ԑ\x00\x00\x00\x00$+Ő\x00\x00\x00\x00%\x1b\xb6\x90\x00\x00\x00\x00&\v\xa7\x90\x00\x00\x00\x00" +
+	"'\x04\xd3\x10\x00\x00\x00\x00'\xf4\xc4\x10\x00\x00\x00\x00(\xe4\xc3 \x00\x00\x00\x00)xk \x00\x00\x00\x00)Ԧ\x10\x00\x00\x00\x00*ė\x10\x00\x00\x00\x00+\xb4\x88\x10\x00\x00\x00\x00,\xa4y\x10" +
+	"\x00\x00\x00\x00-\x94j\x10\x00\x00\x00\x00.\x84[\x10\x00\x00\x00\x00/tL\x10\x00\x00\x00\x000d=\x10\x00\x00\x00\x001]h\x90\x00\x00\x00\x002rC\x90\x00\x00\x00\x003=J\x90\x00\x00\x00\x00" +
+	"4R%\x90\x00\x00\x00\x005\x1d,\x90\x00\x00\x00\x0062\a\x90\x00\x00\x00\x006\xfd\x0e\x90\x00\x00\x00\x008\x1b$\x10\x00\x00\x00\x008\xdc\xf0\x90\x00\x00\x00\x009\xfb\x06\x10\x00\x00\x00\x00:\xbcҐ" +
+	"\x00\x00\x00\x00;\xda\xe8\x10\x00\x00\x00\x00<\xa5\xef\x10\x00\x00\x00\x00=\xba\xca\x10\x00\x00\x00\x00>\x85\xd1\x10\x00\x00\x00\x00?\x9a\xac\x10\x00\x00\x00\x00@e\xb3\x10\x00\x00\x00\x00A\x83Ȑ\x00\x00\x00\x00" +
+	"BE\x95\x10\x00\x00\x00\x00Cc\xaa\x90\x00\x00\x00\x00D%w\x10\x00\x00\x00\x00EC\x8c\x90\x00\x00\x00\x00F\x05Y\x10\x00\x00\x00\x00G#n\x90\x00\x00\x00\x00G\xeeu\x90\x00\x00\x00\x00I\x03P\x90" +
+	"\x00\x00\x00\x00I\xceW\x90\x00\x00\x00\x00J\xe32\x90\x00\x00\x00\x00K\xae9\x90\x00\x00\x00\x00L\xccO\x10\x00\x00\x00\x00M\x8e\x1b\x90\x00\x00\x00\x00TK\xc9\x00\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x03\x00\x00y\xa2\x00\x00\x00" +
+	"\x00p\x80\x00\x04\x00\x00\x8c\xa0\x01\b\x00\x00~\x90\x00\f\x00\x00~\x90\x01\f\x00\x00\x8c\xa0\x00\bLMT\x00+08\x00+10\x00+09\x00\n<+09>-9\nPK\x03\x04\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00ʇ{_\xbb\x00\x00\x00\xbb\x00\x00\x00\v\x00\x00\x00Asia/YangonTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xffV\xb6\x89\xd1\xff\xff\xff\xff\xa1\xf2sQ\xff\xff\xff\xff\xcb\xf2\xfc\x18\xff\xff\xff\xffњg\xf0\x01\x02\x03\x02\x00\x00Z/\x00\x00\x00\x00Z/\x00\x04\x00\x00" +
+	"[h\x00\b\x00\x00~\x90\x00\x0eLMT\x00RMT\x00+0630\x00+09\x00\n<+0630>-6:30\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9a\xea\x18\xd4" +
+	"\xf8\x02\x00\x00\xf8\x02\x00\x00\x12\x00\x00\x00Asia/YekaterinburgTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x00\x00\x00" +
+	"\a\x00\x00\x00\x14\xff\xff\xff\xff\x9b_\t'\xff\xff\xff\xff\xa1\x12\xb1\xff\xff\xff\xff\xff\xb5\xa3\xfd@\x00\x00\x00\x00\x15'\x8b\xb0\x00\x00\x00\x00\x16\x18\xc0 \x00\x00\x00\x00\x17\b\xbf0\x00\x00\x00\x00\x17\xf9\xf3" +
+	"\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00" +
+	"\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L\x1b\xd0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\v\xdf" +
+	"\xd0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\xa3`\x00\x00\x00\x00)\xd4\xdeP\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xc0P\x00\x00\x00" +
+	"\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xa2P\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x84P\x00\x00\x00\x000duP\x00\x00\x00\x001]\xa0\xd0\x00\x00\x00\x002r{\xd0\x00\x00\x00\x003=\x82" +
+	"\xd0\x00\x00\x00\x004R]\xd0\x00\x00\x00\x005\x1dd\xd0\x00\x00\x00\x0062?\xd0\x00\x00\x00\x006\xfdF\xd0\x00\x00\x00\x008\x1b\\P\x00\x00\x00\x008\xdd(\xd0\x00\x00\x00\x009\xfb>P\x00\x00\x00" +
+	"\x00:\xbd\n\xd0\x00\x00\x00\x00;\xdb P\x00\x00\x00\x00<\xa6'P\x00\x00\x00\x00=\xbb\x02P\x00\x00\x00\x00>\x86\tP\x00\x00\x00\x00?\x9a\xe4P\x00\x00\x00\x00@e\xebP\x00\x00\x00\x00A\x84\x00" +
+	"\xd0\x00\x00\x00\x00BE\xcdP\x00\x00\x00\x00Cc\xe2\xd0\x00\x00\x00\x00D%\xafP\x00\x00\x00\x00EC\xc4\xd0\x00\x00\x00\x00F\x05\x91P\x00\x00\x00\x00G#\xa6\xd0\x00\x00\x00\x00G\xee\xad\xd0\x00\x00\x00" +
+	"\x00I\x03\x88\xd0\x00\x00\x00\x00IΏ\xd0\x00\x00\x00\x00J\xe3j\xd0\x00\x00\x00\x00K\xaeq\xd0\x00\x00\x00\x00L̇P\x00\x00\x00\x00M\x8eS\xd0\x00\x00\x00\x00TL\x01@\x01\x02\x04\x03\x04\x03\x04" +
+	"\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x05\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x06\x04\x00" +
+	"\x008\xd9\x00\x00\x00\x004\xc1\x00\x04\x00\x008@\x00\b\x00\x00T`\x01\f\x00\x00FP\x00\x10\x00\x00FP\x01\x10\x00\x00T`\x00\fLMT\x00PMT\x00+04\x00+06\x00+05" +
+	"\x00\n<+05>-5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x95-\xad\xc4\x02\x00\x00\xc4\x02\x00\x00\f\x00\x00\x00Asia/YerevanTZif2\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x9aH\xff\xff\xff\xff\xe7\xda\fP\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00" +
+	"\x00\x00\x00\x17\b\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a̅\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d" +
+	"\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\8\xe0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<\x1a\xe0\x00\x00\x00\x00$,\v\xe0\x00" +
+	"\x00\x00\x00%\x1b\xfc\xe0\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00'\x05\x19`\x00\x00\x00\x00'\xf5\n`\x00\x00\x00\x00(\xe5\tp\x00\x00\x00\x00)\xd4\xfap\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+" +
+	"\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x94\xbep\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x003=\x90\xe0\x00\x00\x00\x004Rk\xe0\x00" +
+	"\x00\x00\x005\x1dr\xe0\x00\x00\x00\x0062M\xe0\x00\x00\x00\x006\xfdT\xe0\x00\x00\x00\x008\x1bj`\x00\x00\x00\x008\xdd6\xe0\x00\x00\x00\x009\xfbL`\x00\x00\x00\x00:\xbd\x18\xe0\x00\x00\x00\x00;" +
+	"\xdb.`\x00\x00\x00\x00<\xa65`\x00\x00\x00\x00=\xbb\x10`\x00\x00\x00\x00>\x86\x17`\x00\x00\x00\x00?\x9a\xf2`\x00\x00\x00\x00@e\xf9`\x00\x00\x00\x00A\x84\x0e\xe0\x00\x00\x00\x00BE\xdb`\x00" +
+	"\x00\x00\x00Cc\xf0\xe0\x00\x00\x00\x00D%\xbd`\x00\x00\x00\x00EC\xd2\xe0\x00\x00\x00\x00F\x05\x9f`\x00\x00\x00\x00G#\xb4\xe0\x00\x00\x00\x00G\xee\xbb\xe0\x00\x00\x00\x00I\x03\x96\xe0\x00\x00\x00\x00I" +
+	"Ν\xe0\x00\x00\x00\x00J\xe3x\xe0\x00\x00\x00\x00K\xae\x7f\xe0\x00\x00\x00\x00L̕`\x00\x00\x00\x00M\x8ea\xe0\x00\x00\x00\x00N\xacw`\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x04\x01\x04\x01\x04\x01\x04\x01\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00)\xb8\x00\x00\x00\x00*0\x00\x04\x00\x00F" +
+	"P\x01\b\x00\x008@\x00\f\x00\x008@\x01\fLMT\x00+03\x00+05\x00+04\x00\n<+04>-4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe8\x8dY\x80\xad\x05" +
+	"\x00\x00\xad\x05\x00\x00\x0f\x00\x00\x00Atlantic/AzoresTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c\x00\x00\x00\a\x00\x00\x00\x18" +
+	"\xff\xff\xff\xff^=\x1b\x90\xff\xff\xff\xff\x92檠\xff\xff\xff\xff\x9bK\x89\x90\xff\xff\xff\xff\x9b\xfe\xe3\xa0\xff\xff\xff\xff\x9c\x9d\t\x90\xff\xff\xff\xff\x9dɟ\x90\xff\xff\xff\xff\x9e\x7f\x8e\x90\xff\xff\xff\xff" +
+	"\x9f\xaa\xd3\x10\xff\xff\xff\xff\xa0_p\x90\xff\xff\xff\xff\xa1\x8c\x06\x90\xff\xff\xff\xff\xa2A\xf5\x90\xff\xff\xff\xff\xa3n\x8b\x90\xff\xff\xff\xff\xa4#)\x10\xff\xff\xff\xff\xa5O\xbf\x10\xff\xff\xff\xff\xaa\x06\v\x90" +
+	"\xff\xff\xff\xff\xaa\xf4\xab\x10\xff\xff\xff\xff\xad\xc9\xc4\x10\xff\xff\xff\xff\xae\xa7@\x10\xff\xff\xff\xff\xaf\xa0k\x90\xff\xff\xff\xff\xb0\x87\"\x10\xff\xff\xff\xff\xb1\x89\x88\x10\xff\xff\xff\xff\xb2p>\x90\xff\xff\xff\xff" +
+	"\xb3r\xa4\x90\xff\xff\xff\xff\xb4P \x90\xff\xff\xff\xff\xb72h\x90\xff\xff\xff\xff\xb8\x0f\xe4\x90\xff\xff\xff\xff\xb8\xffՐ\xff\xff\xff\xff\xb9\xefƐ\xff\xff\xff\xff\xbc\xc8\xd4\x10\xff\xff\xff\xff\xbd\xb8\xc5\x10" +
+	"\xff\xff\xff\xff\xbe\x9f{\x90\xff\xff\xff\xff\xbf\x98\xa7\x10\xff\xff\xff\xff\xc0\x9b\r\x10\xff\xff\xff\xff\xc1x\x89\x10\xff\xff\xff\xff\xc2hz\x10\xff\xff\xff\xff\xc3Xk\x10\xff\xff\xff\xff\xc4?!\x90\xff\xff\xff\xff" +
+	"\xc58M\x10\xff\xff\xff\xff\xc6:\xb3\x10\xff\xff\xff\xff\xc7XȐ\xff\xff\xff\xff\xc7\xd9\xfb\x90\xff\xff\xff\xff\xc9\x01K\x90\xff\xff\xff\xff\xc9\xf1<\x90\xff\xff\xff\xff\xca\xe2\x7f\x10\xff\xff\xff\xff˵o\x10" +
+	"\xff\xff\xff\xff\xcb\xec\xc0\x00\xff\xff\xff\xff̀h\x00\xff\xff\xff\xff\xccܿ\x10\xff\xff\xff\xff͕Q\x10\xff\xff\xff\xff\xcd\xc3g\x80\xff\xff\xff\xff\xcer\xbf\x00\xff\xff\xff\xff\xce\xc5ې\xff\xff\xff\xff" +
+	"\xcfu3\x10\xff\xff\xff\xffϬ\x84\x00\xff\xff\xff\xff\xd0R\xa1\x00\xff\xff\xff\xffХ\xbd\x90\xff\xff\xff\xff\xd1U\x15\x10\xff\xff\xff\xffьf\x00\xff\xff\xff\xff\xd22\x83\x00\xff\xff\xff\xff҅\x9f\x90" +
+	"\xff\xff\xff\xff\xd3Y\xe1\x10\xff\xff\xff\xff\xd4I\xd2\x10\xff\xff\xff\xff\xd59\xed@\xff\xff\xff\xff\xd6)\xde@\xff\xff\xff\xff\xd7\x19\xcf@\xff\xff\xff\xff\xd8\t\xc0@\xff\xff\xff\xff\xd8\xf9\xb1@\xff\xff\xff\xff" +
+	"\xd9\xe9\xa2@\xff\xff\xff\xff\xdaٓ@\xff\xff\xff\xff\xdbɄ@\xff\xff\xff\xffܹu@\xff\xff\xff\xffݲ\xa0\xc0\xff\xff\xff\xffޢ\x91\xc0\xff\xff\xff\xffߒ\x82\xc0\xff\xff\xff\xff\xe0\x82s\xc0" +
+	"\xff\xff\xff\xff\xe1rd\xc0\xff\xff\xff\xff\xe2bU\xc0\xff\xff\xff\xff\xe3RF\xc0\xff\xff\xff\xff\xe4B7\xc0\xff\xff\xff\xff\xe52(\xc0\xff\xff\xff\xff\xe6\"\x19\xc0\xff\xff\xff\xff\xe7\x1bE@\xff\xff\xff\xff" +
+	"\xe8\v6@\xff\xff\xff\xff\xe8\xfb'@\xff\xff\xff\xff\xe9\xeb\x18@\xff\xff\xff\xff\xea\xdb\t@\xff\xff\xff\xff\xeb\xca\xfa@\xff\xff\xff\xff\xec\xba\xeb@\xff\xff\xff\xff\xed\xaa\xdc@\xff\xff\xff\xff\xee\x9a\xcd@" +
+	"\xff\xff\xff\xff\uf2be@\xff\xff\xff\xff\xf0z\xaf@\xff\xff\xff\xff\xf1j\xa0@\xff\xff\xff\xff\xf2c\xcb\xc0\xff\xff\xff\xff\xf3S\xbc\xc0\xff\xff\xff\xff\xf4C\xad\xc0\xff\xff\xff\xff\xf53\x9e\xc0\xff\xff\xff\xff" +
+	"\xf6#\x8f\xc0\xff\xff\xff\xff\xf7\x13\x80\xc0\xff\xff\xff\xff\xf8\x03q\xc0\xff\xff\xff\xff\xf8\xf3b\xc0\x00\x00\x00\x00\r\x9b)\x10\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90" +
+	"\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T&\xa0\x00\x00\x00\x00\x13D\t\x90\x00\x00\x00\x00\x144\b\xa0\x00\x00\x00\x00\x15#\xf9\xa0\x00\x00\x00\x00\x16\x13\xea\xa0\x00\x00\x00\x00\x17\x03۠\x00\x00\x00\x00" +
+	"\x17\xf3̠\x00\x00\x00\x00\x18\xe3˰\x00\x00\x00\x00\x19Ӯ\xa0\x00\x00\x00\x00\x1aß\xa0\x00\x00\x00\x00\x1b\xbc\xcb \x00\x00\x00\x00\x1c\xac\xbc \x00\x00\x00\x00\x1d\x9c\xad \x00\x00\x00\x00\x1e\x8c\x9e " +
+	"\x00\x00\x00\x00\x1f|\x8f \x00\x00\x00\x00 l\x80 \x00\x00\x00\x00!\\q \x00\x00\x00\x00\"Lb \x00\x00\x00\x00#<S \x00\x00\x00\x00$,D \x00\x00\x00\x00%\x1c5 \x00\x00\x00\x00" +
+	"&\f& \x00\x00\x00\x00'\x05Q\xa0\x00\x00\x00\x00'\xf5B\xa0\x00\x00\x00\x00(\xe53\xa0\x00\x00\x00\x00)\xd5$\xa0\x00\x00\x00\x00*\xc5\x15\xa0\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90" +
+	"\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x02\x03\x02\x04\x02\x03\x02\x04\x02\x03\x02\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x06\x04\x05\x04\x05\x04\x05\x04" +
+	"\xff\xff\xe7\xf0\x00\x00\xff\xff\xe5(\x00\x04\xff\xff\xf1\xf0\x01\b\xff\xff\xe3\xe0\x00\f\x00\x00\x00\x00\x01\x10\xff\xff\xf1\xf0\x00\b\x00\x00\x00\x00\x00\x14LMT\x00HMT\x00-01\x00-02\x00+0" +
+	"0\x00WET\x00\n<-01>1<+00>,M3.5.0/0,M10.5.0/1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00l&\x04\x99\x00\x04\x00\x00" +
+	"\x00\x04\x00\x00\x10\x00\x00\x00Atlantic/BermudaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00_\x00\x00\x00\x05\x00\x00\x00\x14\xff" +
+	"\xff\xff\xffi\x87\x18F\xff\xff\xff\xff\x9c̮F\xff\xff\xff\xff\x9d\xb7K6\xff\xff\xff\xff\x9e\xb8m\xc6\xff\xff\xff\xff\x9f\x84\xb86\xff\xff\xff\xff\xb4\xc3\x1d\xe6\xff\xff\xff\xff\xcbb\xa6\xe0\xff\xff\xff\xff\xcc" +
+	"Ӽ\xd0\xff\xff\xff\xff͞\xd1\xe0\xff\xff\xff\xff\xce\xc6\x13\xd0\xff\xff\xff\xff\xcfuy`\xff\xff\xff\xffЯ0P\xff\xff\xff\xff\xd1U[`\xff\xff\xff\xffҏ\x12P\xff\xff\xff\xff\xd5qh`\xff" +
+	"\xff\xff\xff\xd6\x0e<\xd0\xff\xff\xff\xff\xd7Z\x84\xe0\xff\xff\xff\xff\xd7\xe4\xe4P\xff\xff\xff\xff\xd9:f\xe0\xff\xff\xff\xff\xd9\xc4\xc6P\xff\xff\xff\xff\xdb#\x83`\xff\xff\xff\xffۤ\xa8P\xff\xff\xff\xff\xdd" +
+	"\x03e`\xff\xff\xff\xff݄\x8aP\xff\xff\xff\xff\xde\xe3G`\xff\xff\xff\xff\xdfm\xa6\xd0\xff\xff\xff\xff\xe6l\t\xe0\xff\xff\xff\xff\xe77\x02\xd0\x00\x00\x00\x00\b \xb3`\x00\x00\x00\x00\t\x10\x96P\x00" +
+	"\x00\x00\x00\n\x00\x95`\x00\x00\x00\x00\n\xf0xP\x00\x00\x00\x00\v\xe0w`\x00\x00\x00\x00\fٔ\xd0\x00\x00\x00\x00\r\xc0Y`\x00\x00\x00\x00\x0e\xb9v\xd0\x00\x00\x00\x00\x0f\xa9u\xe0\x00\x00\x00\x00\x10" +
+	"\x99X\xd0\x00\x00\x00\x00\x11\x89W\xe0\x00\x00\x00\x00\x12y:\xd0\x00\x00\x00\x00\x13i9\xe0\x00\x00\x00\x00\x14Y\x1c\xd0\x00\x00\x00\x00\x15I\x1b\xe0\x00\x00\x00\x00\x168\xfe\xd0\x00\x00\x00\x00\x17(\xfd\xe0\x00" +
+	"\x00\x00\x00\x18\"\x1bP\x00\x00\x00\x00\x19\b\xdf\xe0\x00\x00\x00\x00\x1a\x01\xfdP\x00\x00\x00\x00\x1a\xf1\xfc`\x00\x00\x00\x00\x1b\xe1\xdfP\x00\x00\x00\x00\x1c\xd1\xde`\x00\x00\x00\x00\x1d\xc1\xc1P\x00\x00\x00\x00\x1e" +
+	"\xb1\xc0`\x00\x00\x00\x00\x1f\xa1\xa3P\x00\x00\x00\x00 u\xf2\xe0\x00\x00\x00\x00!\x81\x85P\x00\x00\x00\x00\"U\xd4\xe0\x00\x00\x00\x00#j\xa1\xd0\x00\x00\x00\x00$5\xb6\xe0\x00\x00\x00\x00%J\x83\xd0\x00" +
+	"\x00\x00\x00&\x15\x98\xe0\x00\x00\x00\x00'*e\xd0\x00\x00\x00\x00'\xfe\xb5`\x00\x00\x00\x00)\nG\xd0\x00\x00\x00\x00)ޗ`\x00\x00\x00\x00*\xea)\xd0\x00\x00\x00\x00+\xbey`\x00\x00\x00\x00," +
+	"\xd3FP\x00\x00\x00\x00-\x9e[`\x00\x00\x00\x00.\xb3(P\x00\x00\x00\x00/~=`\x00\x00\x00\x000\x93\nP\x00\x00\x00\x001gY\xe0\x00\x00\x00\x002r\xecP\x00\x00\x00\x003G;\xe0\x00" +
+	"\x00\x00\x004R\xceP\x00\x00\x00\x005'\x1d\xe0\x00\x00\x00\x0062\xb0P\x00\x00\x00\x007\x06\xff\xe0\x00\x00\x00\x008\x1b\xcc\xd0\x00\x00\x00\x008\xe6\xe1\xe0\x00\x00\x00\x009\xfb\xae\xd0\x00\x00\x00\x00:" +
+	"\xc6\xc3\xe0\x00\x00\x00\x00;ې\xd0\x00\x00\x00\x00<\xaf\xe0`\x00\x00\x00\x00=\xbbr\xd0\x00\x00\x00\x00>\x8f\xc2`\x00\x00\x00\x00?\x9bT\xd0\x00\x00\x00\x00@o\xa4`\x00\x00\x00\x00A\x84qP\x00" +
+	"\x00\x00\x00BO\x86`\x00\x00\x00\x00CdSP\x00\x00\x00\x00D/h`\x00\x00\x00\x00ED5P\x00\x00\x00\x00E\xf3\x9a\xe0\x02\x01\x02\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" +
+	"\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" +
+	"\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\xff\xff\xc3:\x00\x00\xff\xff\xd1J\x01\x04\xff\xff\xc3:\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xc7\xc0\x00\x10LMT\x00BST\x00BMT\x00ADT\x00" +
+	"AST\x00\nAST4ADT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaf|7\xb3\xde\x01\x00\x00\xde\x01\x00\x00\x0f\x00\x00\x00At" +
+	"lantic/CanaryTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00" +
+	"\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00#\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff\xa6\x04\\\xf0\xff\xff\xff\xff" +
+	"\xd4A\xf7 \x00\x00\x00\x00\x13M6\x00\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐" +
+	"\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00" +
+	" lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90" +
+	"\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00" +
+	".\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\xff\xff\xf1\x90\x00\x00\xff\xff\xf1\xf0\x00\x04\x00\x00\x00\x00\x00\b\x00\x00\x0e\x10\x01\fLMT\x00-01\x00WET\x00WEST\x00\nWET0WEST,M3.5.0" +
+	"/1,M10.5.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\u0097N\xad\xaf\x00\x00\x00\xaf\x00\x00\x00\x13\x00\x00\x00Atlantic/Cape_Verde" +
+	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xff\x92檠\xff\xff\xff\xff̕\x9c \xff\xff\xff\xff\xd2t|\x10\x00" +
+	"\x00\x00\x00\v\x17\xf7@\x01\x02\x01\x03\xff\xff\xe9\xf4\x00\x00\xff\xff\xe3\xe0\x00\x04\xff\xff\xf1\xf0\x01\b\xff\xff\xf1\xf0\x00\bLMT\x00-02\x00-01\x00\n<-01>1\nPK\x03\x04\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7\x0e\xbdm\xb9\x01\x00\x00\xb9\x01\x00\x00\x0f\x00\x00\x00Atlantic/FaeroeTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xff\x8bm\xa4X\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18" +
+	"㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00" +
+	"\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'" +
+	"\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00" +
+	"\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\xff\xff\xf9\xa8\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x0e\x10\x01\bLMT\x00WET\x00WEST\x00\nWET0WEST,M3.5.0/1,M10.5.0" +
+	"\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7\x0e\xbdm\xb9\x01\x00\x00\xb9\x01\x00\x00\x0e\x00\x00\x00Atlantic/FaroeTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xff\x8bm\xa4X\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90" +
+	"\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00" +
+	"\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10" +
+	"\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00" +
+	"-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xf9\xa8\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x0e\x10\x01\bLMT\x00WET\x00WEST\x00\nWET0WEST,M3.5.0/1,M1" +
+	"0.5.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17S\x91\xb3\xc1\x02\x00\x00\xc1\x02\x00\x00\x12\x00\x00\x00Atlantic/Jan_MayenTZif2\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xffo\xa2a\xf8\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ" +
+	"\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xc8\tq\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff" +
+	"\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xffѶ\x96\x00\xff\xff\xff\xff\xd2X\xbe\x80\xff\xff\xff\xffҡO\x10\xff\xff\xff\xff\xd3c\x1b\x90\xff\xff\xff\xff\xd4K#" +
+	"\x90\xff\xff\xff\xff\xd59\xd1 \xff\xff\xff\xff\xd5g\xe7\x90\xff\xff\xff\xffըs\x00\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xd9\x02\xc1\x90\xff\xff\xff" +
+	"\xff\xd9\xe9x\x10\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf" +
+	"\x90\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00" +
+	"\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C" +
+	"\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00" +
+	"\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00\f\x88\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00*0\x01\rLMT\x00CES" +
+	"T\x00CET\x00CEMT\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x001)7\xad\xad\x05\x00" +
+	"\x00\xad\x05\x00\x00\x10\x00\x00\x00Atlantic/MadeiraTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c\x00\x00\x00\a\x00\x00\x00\x1d" +
+	"\xff\xff\xff\xff^=\x13X\xff\xff\xff\xff\x92朐\xff\xff\xff\xff\x9bK{\x80\xff\xff\xff\xff\x9b\xfeՐ\xff\xff\xff\xff\x9c\x9c\xfb\x80\xff\xff\xff\xff\x9dɑ\x80\xff\xff\xff\xff\x9e\x7f\x80\x80\xff\xff\xff\xff" +
+	"\x9f\xaa\xc5\x00\xff\xff\xff\xff\xa0_b\x80\xff\xff\xff\xff\xa1\x8b\xf8\x80\xff\xff\xff\xff\xa2A\xe7\x80\xff\xff\xff\xff\xa3n}\x80\xff\xff\xff\xff\xa4#\x1b\x00\xff\xff\xff\xff\xa5O\xb1\x00\xff\xff\xff\xff\xaa\x05\xfd\x80" +
+	"\xff\xff\xff\xff\xaa\xf4\x9d\x00\xff\xff\xff\xff\xadɶ\x00\xff\xff\xff\xff\xae\xa72\x00\xff\xff\xff\xff\xaf\xa0]\x80\xff\xff\xff\xff\xb0\x87\x14\x00\xff\xff\xff\xff\xb1\x89z\x00\xff\xff\xff\xff\xb2p0\x80\xff\xff\xff\xff" +
+	"\xb3r\x96\x80\xff\xff\xff\xff\xb4P\x12\x80\xff\xff\xff\xff\xb72Z\x80\xff\xff\xff\xff\xb8\x0fր\xff\xff\xff\xff\xb8\xffǀ\xff\xff\xff\xff\xb9︀\xff\xff\xff\xff\xbc\xc8\xc6\x00\xff\xff\xff\xff\xbd\xb8\xb7\x00" +
+	"\xff\xff\xff\xff\xbe\x9fm\x80\xff\xff\xff\xff\xbf\x98\x99\x00\xff\xff\xff\xff\xc0\x9a\xff\x00\xff\xff\xff\xff\xc1x{\x00\xff\xff\xff\xff\xc2hl\x00\xff\xff\xff\xff\xc3X]\x00\xff\xff\xff\xff\xc4?\x13\x80\xff\xff\xff\xff" +
+	"\xc58?\x00\xff\xff\xff\xff\xc6:\xa5\x00\xff\xff\xff\xff\xc7X\xba\x80\xff\xff\xff\xff\xc7\xd9\xed\x80\xff\xff\xff\xff\xc9\x01=\x80\xff\xff\xff\xff\xc9\xf1.\x80\xff\xff\xff\xff\xca\xe2q\x00\xff\xff\xff\xff˵a\x00" +
+	"\xff\xff\xff\xff\xcb\xec\xb1\xf0\xff\xff\xff\xff̀Y\xf0\xff\xff\xff\xff\xccܱ\x00\xff\xff\xff\xff͕C\x00\xff\xff\xff\xff\xcd\xc3Yp\xff\xff\xff\xff\xcer\xb0\xf0\xff\xff\xff\xff\xce\xc5̀\xff\xff\xff\xff" +
+	"\xcfu%\x00\xff\xff\xff\xffϬu\xf0\xff\xff\xff\xff\xd0R\x92\xf0\xff\xff\xff\xffХ\xaf\x80\xff\xff\xff\xff\xd1U\a\x00\xff\xff\xff\xffьW\xf0\xff\xff\xff\xff\xd22t\xf0\xff\xff\xff\xff҅\x91\x80" +
+	"\xff\xff\xff\xff\xd3Y\xd3\x00\xff\xff\xff\xff\xd4I\xc4\x00\xff\xff\xff\xff\xd59\xdf0\xff\xff\xff\xff\xd6)\xd00\xff\xff\xff\xff\xd7\x19\xc10\xff\xff\xff\xff\xd8\t\xb20\xff\xff\xff\xff\xd8\xf9\xa30\xff\xff\xff\xff" +
+	"\xd9\xe9\x940\xff\xff\xff\xff\xdaم0\xff\xff\xff\xff\xdb\xc9v0\xff\xff\xff\xffܹg0\xff\xff\xff\xffݲ\x92\xb0\xff\xff\xff\xffޢ\x83\xb0\xff\xff\xff\xffߒt\xb0\xff\xff\xff\xff\xe0\x82e\xb0" +
+	"\xff\xff\xff\xff\xe1rV\xb0\xff\xff\xff\xff\xe2bG\xb0\xff\xff\xff\xff\xe3R8\xb0\xff\xff\xff\xff\xe4B)\xb0\xff\xff\xff\xff\xe52\x1a\xb0\xff\xff\xff\xff\xe6\"\v\xb0\xff\xff\xff\xff\xe7\x1b70\xff\xff\xff\xff" +
+	"\xe8\v(0\xff\xff\xff\xff\xe8\xfb\x190\xff\xff\xff\xff\xe9\xeb\n0\xff\xff\xff\xff\xea\xda\xfb0\xff\xff\xff\xff\xeb\xca\xec0\xff\xff\xff\xff\xec\xba\xdd0\xff\xff\xff\xff\xed\xaa\xce0\xff\xff\xff\xff\ue6bf0" +
+	"\xff\xff\xff\xff\uf2b00\xff\xff\xff\xff\xf0z\xa10\xff\xff\xff\xff\xf1j\x920\xff\xff\xff\xff\xf2c\xbd\xb0\xff\xff\xff\xff\xf3S\xae\xb0\xff\xff\xff\xff\xf4C\x9f\xb0\xff\xff\xff\xff\xf53\x90\xb0\xff\xff\xff\xff" +
+	"\xf6#\x81\xb0\xff\xff\xff\xff\xf7\x13r\xb0\xff\xff\xff\xff\xf8\x03c\xb0\xff\xff\xff\xff\xf8\xf3T\xb0\x00\x00\x00\x00\r\x9b\x1b\x00\x00\x00\x00\x00\x0e\x8b\f\x00\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00\x10t(\x80" +
+	"\x00\x00\x00\x00\x11d\x19\x80\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13C\xfb\x80\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00" +
+	"\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㽠\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10" +
+	"\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00" +
+	"&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90" +
+	"\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x02\x03\x02\x04\x02\x03\x02\x04\x02\x03\x02\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" +
+	"\xff\xff\xf0(\x00\x00\xff\xff\xf0(\x00\x04\x00\x00\x00\x00\x01\b\xff\xff\xf1\xf0\x00\f\x00\x00\x0e\x10\x01\x10\x00\x00\x0e\x10\x01\x14\x00\x00\x00\x00\x00\x19LMT\x00FMT\x00+00\x00-01\x00+0" +
+	"1\x00WEST\x00WET\x00\nWET0WEST,M3.5.0/1,M10.5.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00" +
+	"\x82\x00\x00\x00\x12\x00\x00\x00Atlantic/ReykjavikTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00" +
+	"\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f-\xadׄ\x00\x00\x00\x84\x00" +
+	"\x00\x00\x16\x00\x00\x00Atlantic/South_GeorgiaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00" +
+	"\x00\x00\b\xff\xff\xff\xffi\x86\xfd\xc0\x01\xff\xff\xdd\xc0\x00\x00\xff\xff\xe3\xe0\x00\x04LMT\x00-02\x00\n<-02>2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00" +
+	"\x00\x00\x82\x00\x00\x00\x12\x00\x00\x00Atlantic/St_HelenaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00" +
+	"\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe7\xcf^\xb0\x15\x03\x00\x00" +
+	"\x15\x03\x00\x00\x10\x00\x00\x00Atlantic/StanleyTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00F\x00\x00\x00\x06\x00\x00\x00\x14\xff" +
+	"\xff\xff\xffi\x87\x11\xbc\xff\xff\xff\xff\x93D_<\xff\xff\xff\xff\xc3OZ\xc0\xff\xff\xff\xff\xc46\x030\xff\xff\xff\xff\xc5/<\xc0\xff\xff\xff\xff\xc6\x15\xe50\xff\xff\xff\xff\xc7\x18Y@\xff\xff\xff\xff\xc7" +
+	"\xff\x01\xb0\xff\xff\xff\xff\xc8\xf8;@\xff\xff\xff\xff\xc9\xde\xe3\xb0\xff\xff\xff\xff\xca\xd8\x1d@\xff\xff\xff\xff˾Ű\xff\xff\xff\xff̷\xff@\xff\xff\xff\xff\xcd6\x810\x00\x00\x00\x00\x19\x11\xfe@\x00" +
+	"\x00\x00\x00\x19Ӽ\xb0\x00\x00\x00\x00\x1a\xf1\xc4 \x00\x00\x00\x00\x1b\xaad0\x00\x00\x00\x00\x1cѦ \x00\x00\x00\x00\x1d\x8aF0\x00\x00\x00\x00\x1e\xa8[\xb0\x00\x00\x00\x00\x1fj6@\x00\x00\x00\x00 " +
+	"\x88=\xb0\x00\x00\x00\x00!J\x18@\x00\x00\x00\x00\"h\x1f\xb0\x00\x00\x00\x00#)\xfa@\x00\x00\x00\x00$H\x01\xb0\x00\x00\x00\x00%\t\xdc@\x00\x00\x00\x00&1\x1e0\x00\x00\x00\x00&\xe9\xbe@\x00" +
+	"\x00\x00\x00(\x11\x000\x00\x00\x00\x00(\xd2\xda\xc0\x00\x00\x00\x00)\xf0\xe20\x00\x00\x00\x00*\xb2\xbc\xc0\x00\x00\x00\x00+\xd0\xc40\x00\x00\x00\x00,\x92\x9e\xc0\x00\x00\x00\x00-\xb0\xa60\x00\x00\x00\x00." +
+	"r\x80\xc0\x00\x00\x00\x00/\x90\x880\x00\x00\x00\x000Rb\xc0\x00\x00\x00\x001y\xa4\xb0\x00\x00\x00\x002;\x7f@\x00\x00\x00\x003Y\x86\xb0\x00\x00\x00\x004\x1ba@\x00\x00\x00\x0059h\xb0\x00" +
+	"\x00\x00\x005\xfbC@\x00\x00\x00\x007\x19J\xb0\x00\x00\x00\x007\xdb%@\x00\x00\x00\x008\xf9,\xb0\x00\x00\x00\x009\xbb\a@\x00\x00\x00\x00:\xd9*\xd0\x00\x00\x00\x00;\x91\xca\xe0\x00\x00\x00\x00<" +
+	"\xc2GP\x00\x00\x00\x00=q\xac\xe0\x00\x00\x00\x00>\xa2)P\x00\x00\x00\x00?Z\xc9`\x00\x00\x00\x00@\x82\vP\x00\x00\x00\x00A:\xab`\x00\x00\x00\x00Ba\xedP\x00\x00\x00\x00C\x1a\x8d`\x00" +
+	"\x00\x00\x00DA\xcfP\x00\x00\x00\x00D\xfao`\x00\x00\x00\x00F!\xb1P\x00\x00\x00\x00F\xdaQ`\x00\x00\x00\x00H\n\xcd\xd0\x00\x00\x00\x00H\xc3m\xe0\x00\x00\x00\x00I\xea\xaf\xd0\x00\x00\x00\x00J" +
+	"\xa3O\xe0\x00\x00\x00\x00Kʑ\xd0\x00\x00\x00\x00L\x831\xe0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x04\x05\x04\x05\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\xff\xff\xc9\xc4\x00\x00\xff\xff\xc9\xc4\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xc7\xc0\x00\f\xff\xff\xe3\xe0\x01\x10\xff" +
+	"\xff\xd5\xd0\x00\bLMT\x00SMT\x00-03\x00-04\x00-02\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X\xb9\x9ap\x88\x03\x00\x00\x88\x03\x00\x00\r" +
+	"\x00\x00\x00Australia/ACTTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01" +
+	"\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x7f<\xff" +
+	"\xff\xff\xff\x9cN\u0080\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff̷V\x80\xff\xff\xff\xffͧG\x80\xff\xff\xff\xffΠs\x00\xff\xff\xff\xff\xcf" +
+	"\x87)\x80\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00\a/\xfd\x80\x00\x00\x00\x00\a\xd6\x1a\x80\x00\x00\x00\x00\t\x0f߀\x00" +
+	"\x00\x00\x00\t\xb5\xfc\x80\x00\x00\x00\x00\n\xef\xc1\x80\x00\x00\x00\x00\v\x9f\x19\x00\x00\x00\x00\x00\f\xd8\xde\x00\x00\x00\x00\x00\r~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10" +
+	"\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x17\f\x89\x80\x00" +
+	"\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18ǁ\x80\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\n\x80\x00\x00\x00\x00\x1e" +
+	"y\x9c\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!\x80\u0380\x00\x00\x00\x00\"B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\"}\x00\x00\x00\x00\x00%I\xcd\x00\x00" +
+	"\x00\x00\x00%\xef\xea\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)\t\x91\x00\x00\x00\x00\x00)\xaf\xae\x00\x00\x00\x00\x00*\xe9s\x00\x00\x00\x00\x00+\x98ʀ\x00\x00\x00\x00," +
+	"ҏ\x80\x00\x00\x00\x00-x\xac\x80\x00\x00\x00\x00.\xb2q\x80\x00\x00\x00\x00/X\x8e\x80\x00\x00\x00\x000\x92S\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002r5\x80\x00\x00\x00\x003=<\x80\x00" +
+	"\x00\x00\x004R\x17\x80\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x0061\xf9\x80\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x008\x1b\x16\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:" +
+	"\xbcĀ\x00\x00\x00\x00;\xda\xda\x00\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\xba\xbc\x00\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?\x9a\x9e\x00\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00" +
+	"\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00EC~\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xf7\xa2\x00\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x8d\xc4\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\nAEST-10AE" +
+	"DT,M10.1.0,M4.1.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8ff~ՙ\x03\x00\x00\x99\x03\x00\x00\x12\x00\x00\x00Australia/" +
+	"AdelaideTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00T" +
+	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00T\x00\x00\x00\x04\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x8b\x14\xff\xff\xff\xff{\x12\x03p\xff" +
+	"\xff\xff\xff\x9cNɈ\xff\xff\xff\xff\x9c\xbc6\b\xff\xff\xff\xff\xcbT\xba\b\xff\xff\xff\xff\xcb\xc7l\x88\xff\xff\xff\xff̷]\x88\xff\xff\xff\xffͧN\x88\xff\xff\xff\xffΠz\b\xff\xff\xff\xff\xcf" +
+	"\x870\x88\x00\x00\x00\x00\x03p@\x88\x00\x00\x00\x00\x04\r#\b\x00\x00\x00\x00\x05P\"\x88\x00\x00\x00\x00\x05\xf6?\x88\x00\x00\x00\x00\a0\x04\x88\x00\x00\x00\x00\a\xd6!\x88\x00\x00\x00\x00\t\x0f\xe6\x88\x00" +
+	"\x00\x00\x00\t\xb6\x03\x88\x00\x00\x00\x00\n\xefȈ\x00\x00\x00\x00\v\x9f \b\x00\x00\x00\x00\f\xd8\xe5\b\x00\x00\x00\x00\r\x7f\x02\b\x00\x00\x00\x00\x0e\xb8\xc7\b\x00\x00\x00\x00\x0f^\xe4\b\x00\x00\x00\x00\x10" +
+	"\x98\xa9\b\x00\x00\x00\x00\x11>\xc6\b\x00\x00\x00\x00\x12x\x8b\b\x00\x00\x00\x00\x13\x1e\xa8\b\x00\x00\x00\x00\x14Xm\b\x00\x00\x00\x00\x14\xfe\x8a\b\x00\x00\x00\x00\x168O\b\x00\x00\x00\x00\x16禈\x00" +
+	"\x00\x00\x00\x18!k\x88\x00\x00\x00\x00\x18Lj\x88\x00\x00\x00\x00\x1a\x01M\x88\x00\x00\x00\x00\x1a\xa7j\x88\x00\x00\x00\x00\x1b\xe1/\x88\x00\x00\x00\x00\x1c\x87L\x88\x00\x00\x00\x00\x1d\xc1\x11\x88\x00\x00\x00\x00\x1e" +
+	"y\xa3\x88\x00\x00\x00\x00\x1f\x97\xb9\b\x00\x00\x00\x00 Y\x85\x88\x00\x00\x00\x00!\x80Ո\x00\x00\x00\x00\"B\xa2\b\x00\x00\x00\x00#i\xf2\b\x00\x00\x00\x00$\"\x84\b\x00\x00\x00\x00%I\xd4\b\x00" +
+	"\x00\x00\x00&\x02f\b\x00\x00\x00\x00')\xb6\b\x00\x00\x00\x00'\xcf\xd3\b\x00\x00\x00\x00)\t\x98\b\x00\x00\x00\x00)\xcbd\x88\x00\x00\x00\x00*\xe9z\b\x00\x00\x00\x00+\x98ш\x00\x00\x00\x00," +
+	"Җ\x88\x00\x00\x00\x00-\x8b(\x88\x00\x00\x00\x00.\xb2x\x88\x00\x00\x00\x00/tE\b\x00\x00\x00\x000\x92Z\x88\x00\x00\x00\x001]a\x88\x00\x00\x00\x002r<\x88\x00\x00\x00\x003=C\x88\x00" +
+	"\x00\x00\x004R\x1e\x88\x00\x00\x00\x005\x1d%\x88\x00\x00\x00\x0062\x00\x88\x00\x00\x00\x006\xfd\a\x88\x00\x00\x00\x008\x1b\x1d\b\x00\x00\x00\x008\xdc\xe9\x88\x00\x00\x00\x009\xfa\xff\b\x00\x00\x00\x00:" +
+	"\xbcˈ\x00\x00\x00\x00;\xda\xe1\b\x00\x00\x00\x00<\xa5\xe8\b\x00\x00\x00\x00=\xba\xc3\b\x00\x00\x00\x00>\x85\xca\b\x00\x00\x00\x00?\x9a\xa5\b\x00\x00\x00\x00@e\xac\b\x00\x00\x00\x00A\x83\xc1\x88\x00" +
+	"\x00\x00\x00BE\x8e\b\x00\x00\x00\x00Cc\xa3\x88\x00\x00\x00\x00D.\xaa\x88\x00\x00\x00\x00EC\x85\x88\x00\x00\x00\x00F\x05R\b\x00\x00\x00\x00G#g\x88\x00\x00\x00\x00G\xf7\xa9\b\x01\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00\x81\xec\x00\x00\x00\x00~\x90\x00\x04\x00\x00\x93\xa8\x01\t\x00\x00\x85\x98\x00\x04LMT\x00ACST\x00ACDT\x00\nAC" +
+	"ST-9:30ACDT,M10.1.0,M4.1.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\xba\xde\xd3!\x01\x00\x00!\x01\x00\x00\x12\x00\x00\x00A" +
+	"ustralia/BrisbaneTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" +
 	"\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffr\xed\x9f\b" +
 	"\xff\xff\xff\xff\x9cN\u0080\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff̷V\x80\xff\xff\xff\xffͧG\x80\xff\xff\xff\xffΠs\x00\xff\xff\xff\xff" +
 	"χ)\x80\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00%\xef\xea\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)\t\x91\x00" +
 	"\x00\x00\x00\x00)\xaf\xae\x00\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x8fx\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\nAE" +
-	"ST-10\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xc8R\x1a\x1b\xea\x00\x00\x00\xea\x00\x00\x00\x0f\x00\x1c\x00Australia/NorthUT\t\x00\x03\xdd\xfc\x94b" +
-	"\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00" +
-	"\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x04\x00\x00\x00\x0e\xff\xff\xff\xffs\x16" +
-	"\x92X\xff\xff\xff\xff{\x12\x03p\xff\xff\xff\xff\x9cNɈ\xff\xff\xff\xff\x9c\xbc6\b\xff\xff\xff\xff\xcbT\xba\b\xff\xff\xff\xff\xcb\xc7l\x88\xff\xff\xff\xff̷]\x88\xff\xff\xff\xffͧN\x88\xff\xff" +
-	"\xff\xffΠz\b\xff\xff\xff\xffχ0\x88\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00z\xa8\x00\x00\x00\x00~\x90\x00\x04\x00\x00\x93\xa8\x01\t\x00\x00\x85\x98\x00\x04LMT\x00ACST\x00ACD" +
-	"T\x00\nACST-9:30\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTo3\xdaR\xb4\x02\x00\x00\xb4\x02\x00\x00\x13\x00\x1c\x00Australia/Lord_Ho" +
-	"weUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x008\x00\x00\x00" +
-	"\x05\x00\x00\x00\x19\xff\xff\xff\xffs\x16w\xdc\x00\x00\x00\x00\x14\xfef\xe0\x00\x00\x00\x00\x168@\xf8\x00\x00\x00\x00\x16\xe7\x8ah\x00\x00\x00\x00\x18!]x\x00\x00\x00\x00\x18\xc7lh\x00\x00\x00\x00\x1a\x01?" +
-	"x\x00\x00\x00\x00\x1a\xa7Nh\x00\x00\x00\x00\x1b\xe1!x\x00\x00\x00\x00\x1c\x870h\x00\x00\x00\x00\x1d\xc1\x03x\x00\x00\x00\x00\x1ey\x8ep\x00\x00\x00\x00\x1f\x97\xaa\xf8\x00\x00\x00\x00 Ypp\x00\x00\x00" +
-	"\x00!\x80\xc7x\x00\x00\x00\x00\"B\x8c\xf0\x00\x00\x00\x00#i\xe3\xf8\x00\x00\x00\x00$\"n\xf0\x00\x00\x00\x00%I\xc5\xf8\x00\x00\x00\x00%\xef\xdb\xf0\x00\x00\x00\x00')\xa7\xf8\x00\x00\x00\x00'Ͻ" +
-	"\xf0\x00\x00\x00\x00)\t\x89\xf8\x00\x00\x00\x00)\xaf\x9f\xf0\x00\x00\x00\x00*\xe9k\xf8\x00\x00\x00\x00+\x98\xbcp\x00\x00\x00\x00,҈x\x00\x00\x00\x00-x\x9ep\x00\x00\x00\x00.\xb2jx\x00\x00\x00" +
-	"\x00/X\x80p\x00\x00\x00\x000\x92Lx\x00\x00\x00\x001]Lp\x00\x00\x00\x002r.x\x00\x00\x00\x003=.p\x00\x00\x00\x004R\x10x\x00\x00\x00\x005\x1d\x10p\x00\x00\x00\x0061\xf2" +
-	"x\x00\x00\x00\x006\xfc\xf2p\x00\x00\x00\x008\x1b\x0e\xf8\x00\x00\x00\x008\xdc\xd4p\x00\x00\x00\x009\xa7\xe2x\x00\x00\x00\x00:\xbc\xb6p\x00\x00\x00\x00;\xda\xd2\xf8\x00\x00\x00\x00<\xa5\xd2\xf0\x00\x00\x00" +
-	"\x00=\xba\xb4\xf8\x00\x00\x00\x00>\x85\xb4\xf0\x00\x00\x00\x00?\x9a\x96\xf8\x00\x00\x00\x00@e\x96\xf0\x00\x00\x00\x00A\x83\xb3x\x00\x00\x00\x00BEx\xf0\x00\x00\x00\x00Cc\x95x\x00\x00\x00\x00D.\x95" +
-	"p\x00\x00\x00\x00ECwx\x00\x00\x00\x00F\x05<\xf0\x00\x00\x00\x00G#Yx\x00\x00\x00\x00G\xf7\x93\xf0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" +
-	"\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x95$\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00\xa1\xb8\x01\t\x00\x00\x93\xa8\x00\x0f\x00\x00\x9a\xb0\x01\x15L" +
-	"MT\x00AEST\x00+1130\x00+1030\x00+11\x00\n<+1030>-10:30<+11>-11,M10.1.0,M4.1." +
-	"0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x8ff~ՙ\x03\x00\x00\x99\x03\x00\x00\x12\x00\x1c\x00Australia/AdelaideUT\t\x00\x03\xdd\xfc\x94b\xdd" +
-	"\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00" +
-	"\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00T\x00\x00\x00\x04\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x8b" +
-	"\x14\xff\xff\xff\xff{\x12\x03p\xff\xff\xff\xff\x9cNɈ\xff\xff\xff\xff\x9c\xbc6\b\xff\xff\xff\xff\xcbT\xba\b\xff\xff\xff\xff\xcb\xc7l\x88\xff\xff\xff\xff̷]\x88\xff\xff\xff\xffͧN\x88\xff\xff\xff" +
-	"\xffΠz\b\xff\xff\xff\xffχ0\x88\x00\x00\x00\x00\x03p@\x88\x00\x00\x00\x00\x04\r#\b\x00\x00\x00\x00\x05P\"\x88\x00\x00\x00\x00\x05\xf6?\x88\x00\x00\x00\x00\a0\x04\x88\x00\x00\x00\x00\a\xd6!" +
-	"\x88\x00\x00\x00\x00\t\x0f\xe6\x88\x00\x00\x00\x00\t\xb6\x03\x88\x00\x00\x00\x00\n\xefȈ\x00\x00\x00\x00\v\x9f \b\x00\x00\x00\x00\f\xd8\xe5\b\x00\x00\x00\x00\r\x7f\x02\b\x00\x00\x00\x00\x0e\xb8\xc7\b\x00\x00\x00" +
-	"\x00\x0f^\xe4\b\x00\x00\x00\x00\x10\x98\xa9\b\x00\x00\x00\x00\x11>\xc6\b\x00\x00\x00\x00\x12x\x8b\b\x00\x00\x00\x00\x13\x1e\xa8\b\x00\x00\x00\x00\x14Xm\b\x00\x00\x00\x00\x14\xfe\x8a\b\x00\x00\x00\x00\x168O" +
-	"\b\x00\x00\x00\x00\x16禈\x00\x00\x00\x00\x18!k\x88\x00\x00\x00\x00\x18Lj\x88\x00\x00\x00\x00\x1a\x01M\x88\x00\x00\x00\x00\x1a\xa7j\x88\x00\x00\x00\x00\x1b\xe1/\x88\x00\x00\x00\x00\x1c\x87L\x88\x00\x00\x00" +
-	"\x00\x1d\xc1\x11\x88\x00\x00\x00\x00\x1ey\xa3\x88\x00\x00\x00\x00\x1f\x97\xb9\b\x00\x00\x00\x00 Y\x85\x88\x00\x00\x00\x00!\x80Ո\x00\x00\x00\x00\"B\xa2\b\x00\x00\x00\x00#i\xf2\b\x00\x00\x00\x00$\"\x84" +
-	"\b\x00\x00\x00\x00%I\xd4\b\x00\x00\x00\x00&\x02f\b\x00\x00\x00\x00')\xb6\b\x00\x00\x00\x00'\xcf\xd3\b\x00\x00\x00\x00)\t\x98\b\x00\x00\x00\x00)\xcbd\x88\x00\x00\x00\x00*\xe9z\b\x00\x00\x00" +
-	"\x00+\x98ш\x00\x00\x00\x00,Җ\x88\x00\x00\x00\x00-\x8b(\x88\x00\x00\x00\x00.\xb2x\x88\x00\x00\x00\x00/tE\b\x00\x00\x00\x000\x92Z\x88\x00\x00\x00\x001]a\x88\x00\x00\x00\x002r<" +
-	"\x88\x00\x00\x00\x003=C\x88\x00\x00\x00\x004R\x1e\x88\x00\x00\x00\x005\x1d%\x88\x00\x00\x00\x0062\x00\x88\x00\x00\x00\x006\xfd\a\x88\x00\x00\x00\x008\x1b\x1d\b\x00\x00\x00\x008\xdc\xe9\x88\x00\x00\x00" +
-	"\x009\xfa\xff\b\x00\x00\x00\x00:\xbcˈ\x00\x00\x00\x00;\xda\xe1\b\x00\x00\x00\x00<\xa5\xe8\b\x00\x00\x00\x00=\xba\xc3\b\x00\x00\x00\x00>\x85\xca\b\x00\x00\x00\x00?\x9a\xa5\b\x00\x00\x00\x00@e\xac" +
-	"\b\x00\x00\x00\x00A\x83\xc1\x88\x00\x00\x00\x00BE\x8e\b\x00\x00\x00\x00Cc\xa3\x88\x00\x00\x00\x00D.\xaa\x88\x00\x00\x00\x00EC\x85\x88\x00\x00\x00\x00F\x05R\b\x00\x00\x00\x00G#g\x88\x00\x00\x00" +
-	"\x00G\xf7\xa9\b\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00\x81\xec\x00\x00\x00\x00~\x90\x00\x04\x00\x00\x93\xa8\x01\t\x00\x00\x85\x98\x00\x04LMT\x00ACS" +
-	"T\x00ACDT\x00\nACST-9:30ACDT,M10.1.0,M4.1.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xbd\xca#\x7f\xad\x03\x00" +
-	"\x00\xad\x03\x00\x00\x14\x00\x1c\x00Australia/YancowinnaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZi" +
+	"ST-10\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbd\xca#\x7f\xad\x03\x00\x00\xad\x03\x00\x00\x15\x00\x00\x00Australia/Broken_HillTZi" +
 	"f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00" +
 	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00U\x00\x00\x00\x05\x00\x00\x00\x13\xff\xff\xff\xffs\x16\x88d\xff\xff\xff\xffv\x04\xa5\xe0\xff\xff\xff\xff{\x12\x03p\xff\xff\xff\xff" +
 	"\x9cNɈ\xff\xff\xff\xff\x9c\xbc6\b\xff\xff\xff\xff\xcbT\xba\b\xff\xff\xff\xff\xcb\xc7l\x88\xff\xff\xff\xff̷]\x88\xff\xff\xff\xffͧN\x88\xff\xff\xff\xffΠz\b\xff\xff\xff\xffχ0\x88" +
@@ -3660,41 +3559,116 @@
 	"BE\x8e\b\x00\x00\x00\x00Cc\xa3\x88\x00\x00\x00\x00D.\xaa\x88\x00\x00\x00\x00EC\x85\x88\x00\x00\x00\x00F\x05R\b\x00\x00\x00\x00G#g\x88\x00\x00\x00\x00G\xf7\xa9\b\x01\x02\x04\x03\x04\x03\x04\x03" +
 	"\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" +
 	"\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x00\x00\x84\x9c\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00~\x90\x00\t\x00\x00\x93\xa8\x01\x0e\x00\x00\x85\x98\x00\tLMT\x00AEST\x00ACST" +
-	"\x00ACDT\x00\nACST-9:30ACDT,M10.1.0,M4.1.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9b\xe1\xc1\xa9\x88\x03\x00\x00" +
-	"\x88\x03\x00\x00\x12\x00\x1c\x00Australia/VictoriaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x85\x18\xff\xff\xff\xff\x9cN\u0080\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\xcbT\xb3" +
-	"\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff̷V\x80\xff\xff\xff\xffͧG\x80\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ)\x80\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00" +
-	"\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00\a/\xfd\x80\x00\x00\x00\x00\a\xd6\x1a\x80\x00\x00\x00\x00\t\x0f߀\x00\x00\x00\x00\t\xb5\xfc\x80\x00\x00\x00\x00\n\xef\xc1\x80\x00\x00\x00\x00\v\x9f\x19" +
-	"\x00\x00\x00\x00\x00\f\xd8\xde\x00\x00\x00\x00\x00\r~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00" +
-	"\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x16矀\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18ǁ\x80\x00\x00\x00\x00\x1a\x01F" +
-	"\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\n\x80\x00\x00\x00\x00\x1ey\x9c\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00" +
-	"\x00!w\x94\x00\x00\x00\x00\x00\"B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\"}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00&\x02_\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xcf\xcc" +
-	"\x00\x00\x00\x00\x00)\t\x91\x00\x00\x00\x00\x00)\xaf\xae\x00\x00\x00\x00\x00*\xe9s\x00\x00\x00\x00\x00+\x98ʀ\x00\x00\x00\x00,ҏ\x80\x00\x00\x00\x00-x\xac\x80\x00\x00\x00\x00.\xb2q\x80\x00\x00\x00" +
-	"\x00/t>\x00\x00\x00\x00\x000\x92S\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002r5\x80\x00\x00\x00\x003=<\x80\x00\x00\x00\x004R\x17\x80\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x0061\xf9" +
-	"\x80\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x008\x1b\x16\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbcĀ\x00\x00\x00\x00;\xda\xda\x00\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00" +
-	"\x00=\xba\xbc\x00\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?\x9a\x9e\x00\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D.\xa3" +
-	"\x80\x00\x00\x00\x00EC~\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xf7\xa2\x00\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x87\xe8" +
-	"\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\nAEST-10AEDT,M10.1.0,M4.1.0/3\nPK" +
-	"\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTX\xb9\x9ap\x88\x03\x00\x00\x88\x03\x00\x00\x12\x00\x1c\x00Australia/CanberraUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bu" +
-	"x\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00" +
-	"\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x7f<\xff\xff\xff" +
-	"\xff\x9cN\u0080\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff̷V\x80\xff\xff\xff\xffͧG\x80\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ)" +
-	"\x80\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00\a/\xfd\x80\x00\x00\x00\x00\a\xd6\x1a\x80\x00\x00\x00\x00\t\x0f߀\x00\x00\x00" +
-	"\x00\t\xb5\xfc\x80\x00\x00\x00\x00\n\xef\xc1\x80\x00\x00\x00\x00\v\x9f\x19\x00\x00\x00\x00\x00\f\xd8\xde\x00\x00\x00\x00\x00\r~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2" +
-	"\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x17\f\x89\x80\x00\x00\x00" +
-	"\x00\x18!d\x80\x00\x00\x00\x00\x18ǁ\x80\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\n\x80\x00\x00\x00\x00\x1ey\x9c" +
-	"\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!\x80\u0380\x00\x00\x00\x00\"B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\"}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00" +
-	"\x00%\xef\xea\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)\t\x91\x00\x00\x00\x00\x00)\xaf\xae\x00\x00\x00\x00\x00*\xe9s\x00\x00\x00\x00\x00+\x98ʀ\x00\x00\x00\x00,ҏ" +
-	"\x80\x00\x00\x00\x00-x\xac\x80\x00\x00\x00\x00.\xb2q\x80\x00\x00\x00\x00/X\x8e\x80\x00\x00\x00\x000\x92S\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002r5\x80\x00\x00\x00\x003=<\x80\x00\x00\x00" +
-	"\x004R\x17\x80\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x0061\xf9\x80\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x008\x1b\x16\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbc\xc4" +
-	"\x80\x00\x00\x00\x00;\xda\xda\x00\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\xba\xbc\x00\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?\x9a\x9e\x00\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00" +
-	"\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00EC~\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xf7\xa2\x00\x02\x01\x02\x01\x02\x01\x02" +
+	"\x00ACDT\x00\nACST-9:30ACDT,M10.1.0,M4.1.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X\xb9\x9ap\x88\x03\x00\x00" +
+	"\x88\x03\x00\x00\x12\x00\x00\x00Australia/CanberraTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S\x00\x00\x00\x03\x00\x00\x00" +
+	"\x0e\xff\xff\xff\xffs\x16\x7f<\xff\xff\xff\xff\x9cN\u0080\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff̷V\x80\xff\xff\xff\xffͧG\x80\xff\xff\xff" +
+	"\xffΠs\x00\xff\xff\xff\xffχ)\x80\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00\a/\xfd\x80\x00\x00\x00\x00\a\xd6\x1a" +
+	"\x80\x00\x00\x00\x00\t\x0f߀\x00\x00\x00\x00\t\xb5\xfc\x80\x00\x00\x00\x00\n\xef\xc1\x80\x00\x00\x00\x00\v\x9f\x19\x00\x00\x00\x00\x00\f\xd8\xde\x00\x00\x00\x00\x00\r~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00" +
+	"\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H" +
+	"\x00\x00\x00\x00\x00\x17\f\x89\x80\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18ǁ\x80\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00" +
+	"\x00\x1d\xc1\n\x80\x00\x00\x00\x00\x1ey\x9c\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!\x80\u0380\x00\x00\x00\x00\"B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\"}" +
+	"\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00%\xef\xea\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)\t\x91\x00\x00\x00\x00\x00)\xaf\xae\x00\x00\x00\x00\x00*\xe9s\x00\x00\x00\x00" +
+	"\x00+\x98ʀ\x00\x00\x00\x00,ҏ\x80\x00\x00\x00\x00-x\xac\x80\x00\x00\x00\x00.\xb2q\x80\x00\x00\x00\x00/X\x8e\x80\x00\x00\x00\x000\x92S\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002r5" +
+	"\x80\x00\x00\x00\x003=<\x80\x00\x00\x00\x004R\x17\x80\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x0061\xf9\x80\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x008\x1b\x16\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00" +
+	"\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbcĀ\x00\x00\x00\x00;\xda\xda\x00\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\xba\xbc\x00\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?\x9a\x9e\x00\x00\x00\x00\x00@e\xa5" +
+	"\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00EC~\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00" +
+	"\x00G\xf7\xa2\x00\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x8d\xc4\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00" +
+	"\nAEST-10AEDT,M10.1.0,M4.1.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\xf2\xe6Z\xeb\x03\x00\x00\xeb\x03\x00\x00\x10\x00\x00\x00" +
+	"Australia/CurrieTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01" +
+	"\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00^\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xfft.\x00\xe4\xff" +
+	"\xff\xff\xff\x9b\xd5x\x80\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\x9d\xdaD\x80\xff\xff\xff\xff\x9e\x80a\x80\xff\xff\xff\xff\x9f\xba&\x80\xff\xff\xff\xff\xa0`C\x80\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb" +
+	"\xc7e\x80\xff\xff\xff\xff̷V\x80\xff\xff\xff\xffͧG\x80\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ)\x80\xff\xff\xff\xff\xfb\u008d\x00\xff\xff\xff\xff\xfc\xb2~\x00\xff\xff\xff\xff\xfd\xc7Y\x00\xff" +
+	"\xff\xff\xff\xfev\xb0\x80\xff\xff\xff\xff\xff\xa7;\x00\x00\x00\x00\x00\x00V\x92\x80\x00\x00\x00\x00\x01\x87\x1d\x00\x00\x00\x00\x00\x02?\xaf\x00\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00\x05" +
+	"P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00\a/\xfd\x80\x00\x00\x00\x00\a\xd6\x1a\x80\x00\x00\x00\x00\t\x0f߀\x00\x00\x00\x00\t\xb5\xfc\x80\x00\x00\x00\x00\n\xef\xc1\x80\x00\x00\x00\x00\v\x9f\x19\x00\x00" +
+	"\x00\x00\x00\f\xd8\xde\x00\x00\x00\x00\x00\r~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13" +
+	"\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x17\x03O\x00\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18\xe31\x00\x00\x00\x00\x00\x1a\x01F\x80\x00" +
+	"\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\n\x80\x00\x00\x00\x00\x1eg'\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!" +
+	"\x80\u0380\x00\x00\x00\x00\"B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\"}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00&\x02_\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xf4\xb6\x00\x00" +
+	"\x00\x00\x00(\xed\xe1\x80\x00\x00\x00\x00)Ԙ\x00\x00\x00\x00\x00*\xcdÀ\x00\x00\x00\x00+\xb4z\x00\x00\x00\x00\x00,\xad\xa5\x80\x00\x00\x00\x00-\x94\\\x00\x00\x00\x00\x00.\x8d\x87\x80\x00\x00\x00\x00/" +
+	"t>\x00\x00\x00\x00\x000mi\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002V\x86\x00\x00\x00\x00\x003=<\x80\x00\x00\x00\x0046h\x00\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x006\x16J\x00\x00" +
+	"\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x007\xf6,\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbcĀ\x00\x00\x00\x00;\xbf*\x80\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=" +
+	"\x9f\f\x80\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?~\xee\x80\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A^Ѐ\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00C>\xb2\x80\x00\x00\x00\x00D.\xa3\x80\x00" +
+	"\x00\x00\x00E\x1e\x94\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G\a\xb1\x00\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00\x8a" +
+	"\x1c\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\nAEST-10AEDT,M10.1.0,M4.1.0/3\nP" +
+	"K\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8R\x1a\x1b\xea\x00\x00\x00\xea\x00\x00\x00\x10\x00\x00\x00Australia/DarwinTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x04\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x92X\xff\xff\xff\xff{\x12\x03p\xff\xff\xff\xff\x9cNɈ\xff\xff\xff\xff\x9c\xbc6\b\xff\xff\xff\xff\xcbT\xba\b" +
+	"\xff\xff\xff\xff\xcb\xc7l\x88\xff\xff\xff\xff̷]\x88\xff\xff\xff\xffͧN\x88\xff\xff\xff\xffΠz\b\xff\xff\xff\xffχ0\x88\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00z\xa8\x00\x00\x00\x00~\x90" +
+	"\x00\x04\x00\x00\x93\xa8\x01\t\x00\x00\x85\x98\x00\x04LMT\x00ACST\x00ACDT\x00\nACST-9:30\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa2ܺ\xca:\x01\x00" +
+	"\x00:\x01\x00\x00\x0f\x00\x00\x00Australia/EuclaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x03\x00\x00\x00\x10\xff" +
+	"\xff\xff\xfft\xa6\n\xb0\xff\xff\xff\xff\x9cN\xd4\x14\xff\xff\xff\xff\x9c\xbc@\x94\xff\xff\xff\xff\xcbTĔ\xff\xff\xff\xff\xcb\xc7w\x14\xff\xff\xff\xff̷h\x14\xff\xff\xff\xffͧY\x14\x00\x00\x00\x00\t" +
+	"\x0f\xf1\x14\x00\x00\x00\x00\t\xb6\x0e\x14\x00\x00\x00\x00\x1a\x01X\x14\x00\x00\x00\x00\x1a\xa7u\x14\x00\x00\x00\x00)%R\x14\x00\x00\x00\x00)\xaf\xbf\x94\x00\x00\x00\x00Eq\xb4\x94\x00\x00\x00\x00F\x05\\\x94\x00" +
+	"\x00\x00\x00G#r\x14\x00\x00\x00\x00G\xeey\x14\x00\x00\x00\x00I\x03T\x14\x00\x00\x00\x00I\xce[\x14\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00x\xd0\x00\x00\x00\x00\x89\x1c" +
+	"\x01\x04\x00\x00{\f\x00\nLMT\x00+0945\x00+0845\x00\n<+0845>-8:45\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\xf2\xe6Z\xeb\x03\x00\x00" +
+	"\xeb\x03\x00\x00\x10\x00\x00\x00Australia/HobartTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00^\x00\x00\x00\x03\x00\x00\x00\x0e\xff" +
+	"\xff\xff\xfft.\x00\xe4\xff\xff\xff\xff\x9b\xd5x\x80\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\x9d\xdaD\x80\xff\xff\xff\xff\x9e\x80a\x80\xff\xff\xff\xff\x9f\xba&\x80\xff\xff\xff\xff\xa0`C\x80\xff\xff\xff\xff\xcb" +
+	"T\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff̷V\x80\xff\xff\xff\xffͧG\x80\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ)\x80\xff\xff\xff\xff\xfb\u008d\x00\xff\xff\xff\xff\xfc\xb2~\x00\xff" +
+	"\xff\xff\xff\xfd\xc7Y\x00\xff\xff\xff\xff\xfev\xb0\x80\xff\xff\xff\xff\xff\xa7;\x00\x00\x00\x00\x00\x00V\x92\x80\x00\x00\x00\x00\x01\x87\x1d\x00\x00\x00\x00\x00\x02?\xaf\x00\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04" +
+	"\r\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00\a/\xfd\x80\x00\x00\x00\x00\a\xd6\x1a\x80\x00\x00\x00\x00\t\x0f߀\x00\x00\x00\x00\t\xb5\xfc\x80\x00\x00\x00\x00\n\xef\xc1\x80\x00" +
+	"\x00\x00\x00\v\x9f\x19\x00\x00\x00\x00\x00\f\xd8\xde\x00\x00\x00\x00\x00\r~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12" +
+	"x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x17\x03O\x00\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18\xe31\x00\x00" +
+	"\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\n\x80\x00\x00\x00\x00\x1eg'\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 " +
+	"Y~\x80\x00\x00\x00\x00!\x80\u0380\x00\x00\x00\x00\"B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\"}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00&\x02_\x00\x00\x00\x00\x00')\xaf\x00\x00" +
+	"\x00\x00\x00'\xf4\xb6\x00\x00\x00\x00\x00(\xed\xe1\x80\x00\x00\x00\x00)Ԙ\x00\x00\x00\x00\x00*\xcdÀ\x00\x00\x00\x00+\xb4z\x00\x00\x00\x00\x00,\xad\xa5\x80\x00\x00\x00\x00-\x94\\\x00\x00\x00\x00\x00." +
+	"\x8d\x87\x80\x00\x00\x00\x00/t>\x00\x00\x00\x00\x000mi\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002V\x86\x00\x00\x00\x00\x003=<\x80\x00\x00\x00\x0046h\x00\x00\x00\x00\x005\x1d\x1e\x80\x00" +
+	"\x00\x00\x006\x16J\x00\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x007\xf6,\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbcĀ\x00\x00\x00\x00;\xbf*\x80\x00\x00\x00\x00<" +
+	"\xa5\xe1\x00\x00\x00\x00\x00=\x9f\f\x80\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?~\xee\x80\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A^Ѐ\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00C>\xb2\x80\x00" +
+	"\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00E\x1e\x94\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G\a\xb1\x00\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
 	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x8d\xc4\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\nAEST-10AEDT" +
-	",M10.1.0,M4.1.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTX\xb9\x9ap\x88\x03\x00\x00\x88\x03\x00\x00\x10\x00\x1c\x00Australia/Sy" +
-	"dneyUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x01\x02\x01\x02\x01\x00\x00\x8a\x1c\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\nAEST-10AEDT,M10.1.0,M4" +
+	".1.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o3\xdaR\xb4\x02\x00\x00\xb4\x02\x00\x00\r\x00\x00\x00Australia/LHITZif2\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x008\x00\x00\x00\x05\x00\x00\x00\x19\xff\xff\xff\xffs\x16w\xdc\x00\x00\x00\x00\x14\xfef\xe0\x00\x00\x00\x00\x168@\xf8\x00\x00\x00\x00\x16\xe7\x8ah\x00\x00\x00" +
+	"\x00\x18!]x\x00\x00\x00\x00\x18\xc7lh\x00\x00\x00\x00\x1a\x01?x\x00\x00\x00\x00\x1a\xa7Nh\x00\x00\x00\x00\x1b\xe1!x\x00\x00\x00\x00\x1c\x870h\x00\x00\x00\x00\x1d\xc1\x03x\x00\x00\x00\x00\x1ey\x8e" +
+	"p\x00\x00\x00\x00\x1f\x97\xaa\xf8\x00\x00\x00\x00 Ypp\x00\x00\x00\x00!\x80\xc7x\x00\x00\x00\x00\"B\x8c\xf0\x00\x00\x00\x00#i\xe3\xf8\x00\x00\x00\x00$\"n\xf0\x00\x00\x00\x00%I\xc5\xf8\x00\x00\x00" +
+	"\x00%\xef\xdb\xf0\x00\x00\x00\x00')\xa7\xf8\x00\x00\x00\x00'Ͻ\xf0\x00\x00\x00\x00)\t\x89\xf8\x00\x00\x00\x00)\xaf\x9f\xf0\x00\x00\x00\x00*\xe9k\xf8\x00\x00\x00\x00+\x98\xbcp\x00\x00\x00\x00,҈" +
+	"x\x00\x00\x00\x00-x\x9ep\x00\x00\x00\x00.\xb2jx\x00\x00\x00\x00/X\x80p\x00\x00\x00\x000\x92Lx\x00\x00\x00\x001]Lp\x00\x00\x00\x002r.x\x00\x00\x00\x003=.p\x00\x00\x00" +
+	"\x004R\x10x\x00\x00\x00\x005\x1d\x10p\x00\x00\x00\x0061\xf2x\x00\x00\x00\x006\xfc\xf2p\x00\x00\x00\x008\x1b\x0e\xf8\x00\x00\x00\x008\xdc\xd4p\x00\x00\x00\x009\xa7\xe2x\x00\x00\x00\x00:\xbc\xb6" +
+	"p\x00\x00\x00\x00;\xda\xd2\xf8\x00\x00\x00\x00<\xa5\xd2\xf0\x00\x00\x00\x00=\xba\xb4\xf8\x00\x00\x00\x00>\x85\xb4\xf0\x00\x00\x00\x00?\x9a\x96\xf8\x00\x00\x00\x00@e\x96\xf0\x00\x00\x00\x00A\x83\xb3x\x00\x00\x00" +
+	"\x00BEx\xf0\x00\x00\x00\x00Cc\x95x\x00\x00\x00\x00D.\x95p\x00\x00\x00\x00ECwx\x00\x00\x00\x00F\x05<\xf0\x00\x00\x00\x00G#Yx\x00\x00\x00\x00G\xf7\x93\xf0\x01\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x95$\x00\x00\x00\x00\x8c\xa0\x00" +
+	"\x04\x00\x00\xa1\xb8\x01\t\x00\x00\x93\xa8\x00\x0f\x00\x00\x9a\xb0\x01\x15LMT\x00AEST\x00+1130\x00+1030\x00+11\x00\n<+1030>-10:30<+" +
+	"11>-11,M10.1.0,M4.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\x95\xbd\x12E\x01\x00\x00E\x01\x00\x00\x12\x00\x00\x00Australi" +
+	"a/LindemanTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" +
+	"\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffr\xed\xa2\xd4\xff\xff\xff\xff\x9cN\xc2" +
+	"\x80\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff̷V\x80\xff\xff\xff\xffͧG\x80\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ)\x80\x00\x00\x00" +
+	"\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00%\xef\xea\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)\t\x91\x00\x00\x00\x00\x00)\xaf\xae" +
+	"\x00\x00\x00\x00\x00*\xe9s\x00\x00\x00\x00\x00+\x98ʀ\x00\x00\x00\x00,ҏ\x80\x00\x00\x00\x00-x\xac\x80\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x8b\xac\x00\x00" +
+	"\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\nAEST-10\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o3\xdaR\xb4\x02\x00\x00\xb4\x02\x00" +
+	"\x00\x13\x00\x00\x00Australia/Lord_HoweTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x008\x00\x00\x00\x05\x00\x00\x00\x19\xff" +
+	"\xff\xff\xffs\x16w\xdc\x00\x00\x00\x00\x14\xfef\xe0\x00\x00\x00\x00\x168@\xf8\x00\x00\x00\x00\x16\xe7\x8ah\x00\x00\x00\x00\x18!]x\x00\x00\x00\x00\x18\xc7lh\x00\x00\x00\x00\x1a\x01?x\x00\x00\x00\x00\x1a" +
+	"\xa7Nh\x00\x00\x00\x00\x1b\xe1!x\x00\x00\x00\x00\x1c\x870h\x00\x00\x00\x00\x1d\xc1\x03x\x00\x00\x00\x00\x1ey\x8ep\x00\x00\x00\x00\x1f\x97\xaa\xf8\x00\x00\x00\x00 Ypp\x00\x00\x00\x00!\x80\xc7x\x00" +
+	"\x00\x00\x00\"B\x8c\xf0\x00\x00\x00\x00#i\xe3\xf8\x00\x00\x00\x00$\"n\xf0\x00\x00\x00\x00%I\xc5\xf8\x00\x00\x00\x00%\xef\xdb\xf0\x00\x00\x00\x00')\xa7\xf8\x00\x00\x00\x00'Ͻ\xf0\x00\x00\x00\x00)" +
+	"\t\x89\xf8\x00\x00\x00\x00)\xaf\x9f\xf0\x00\x00\x00\x00*\xe9k\xf8\x00\x00\x00\x00+\x98\xbcp\x00\x00\x00\x00,҈x\x00\x00\x00\x00-x\x9ep\x00\x00\x00\x00.\xb2jx\x00\x00\x00\x00/X\x80p\x00" +
+	"\x00\x00\x000\x92Lx\x00\x00\x00\x001]Lp\x00\x00\x00\x002r.x\x00\x00\x00\x003=.p\x00\x00\x00\x004R\x10x\x00\x00\x00\x005\x1d\x10p\x00\x00\x00\x0061\xf2x\x00\x00\x00\x006" +
+	"\xfc\xf2p\x00\x00\x00\x008\x1b\x0e\xf8\x00\x00\x00\x008\xdc\xd4p\x00\x00\x00\x009\xa7\xe2x\x00\x00\x00\x00:\xbc\xb6p\x00\x00\x00\x00;\xda\xd2\xf8\x00\x00\x00\x00<\xa5\xd2\xf0\x00\x00\x00\x00=\xba\xb4\xf8\x00" +
+	"\x00\x00\x00>\x85\xb4\xf0\x00\x00\x00\x00?\x9a\x96\xf8\x00\x00\x00\x00@e\x96\xf0\x00\x00\x00\x00A\x83\xb3x\x00\x00\x00\x00BEx\xf0\x00\x00\x00\x00Cc\x95x\x00\x00\x00\x00D.\x95p\x00\x00\x00\x00E" +
+	"Cwx\x00\x00\x00\x00F\x05<\xf0\x00\x00\x00\x00G#Yx\x00\x00\x00\x00G\xf7\x93\xf0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" +
+	"\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x95$\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00\xa1\xb8\x01\t\x00\x00\x93\xa8\x00\x0f\x00\x00\x9a\xb0\x01\x15LMT\x00AES" +
+	"T\x00+1130\x00+1030\x00+11\x00\n<+1030>-10:30<+11>-11,M10.1.0,M4.1.0\nPK\x03\x04" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\xe1\xc1\xa9\x88\x03\x00\x00\x88\x03\x00\x00\x13\x00\x00\x00Australia/MelbourneTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x85\x18\xff\xff\xff\xff\x9cN\u0080\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80" +
+	"\xff\xff\xff\xff̷V\x80\xff\xff\xff\xffͧG\x80\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ)\x80\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00" +
+	"\x05\xf68\x80\x00\x00\x00\x00\a/\xfd\x80\x00\x00\x00\x00\a\xd6\x1a\x80\x00\x00\x00\x00\t\x0f߀\x00\x00\x00\x00\t\xb5\xfc\x80\x00\x00\x00\x00\n\xef\xc1\x80\x00\x00\x00\x00\v\x9f\x19\x00\x00\x00\x00\x00\f\xd8\xde\x00" +
+	"\x00\x00\x00\x00\r~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00" +
+	"\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x16矀\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18ǁ\x80\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80" +
+	"\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\n\x80\x00\x00\x00\x00\x1ey\x9c\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!w\x94\x00\x00\x00\x00\x00" +
+	"\"B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\"}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00&\x02_\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)\t\x91\x00" +
+	"\x00\x00\x00\x00)\xaf\xae\x00\x00\x00\x00\x00*\xe9s\x00\x00\x00\x00\x00+\x98ʀ\x00\x00\x00\x00,ҏ\x80\x00\x00\x00\x00-x\xac\x80\x00\x00\x00\x00.\xb2q\x80\x00\x00\x00\x00/t>\x00\x00\x00\x00\x00" +
+	"0\x92S\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002r5\x80\x00\x00\x00\x003=<\x80\x00\x00\x00\x004R\x17\x80\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x0061\xf9\x80\x00\x00\x00\x006\xfd\x00\x80" +
+	"\x00\x00\x00\x008\x1b\x16\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbcĀ\x00\x00\x00\x00;\xda\xda\x00\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\xba\xbc\x00\x00\x00\x00\x00" +
+	">\x85\xc3\x00\x00\x00\x00\x00?\x9a\x9e\x00\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00EC~\x80" +
+	"\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xf7\xa2\x00\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x87\xe8\x00\x00\x00\x00\x9a\xb0\x01\x04\x00" +
+	"\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\nAEST-10AEDT,M10.1.0,M4.1.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00X\xb9\x9ap\x88\x03\x00\x00\x88\x03\x00\x00\r\x00\x00\x00Australia/NSWTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
 	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S\x00" +
 	"\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x7f<\xff\xff\xff\xff\x9cN\u0080\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff̷V\x80\xff\xff\xff\xff\xcd" +
 	"\xa7G\x80\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ)\x80\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00\a/\xfd\x80\x00" +
@@ -3709,1113 +3683,863 @@
 	"\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00EC~\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G" +
 	"#`\x80\x00\x00\x00\x00G\xf7\xa2\x00\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
 	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x8d\xc4\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT" +
-	"\x00AEST\x00\nAEST-10AEDT,M10.1.0,M4.1.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTX\xb9\x9ap\x88\x03\x00\x00\x88\x03" +
-	"\x00\x00\r\x00\x1c\x00Australia/ACTUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x7f<\xff\xff\xff\xff\x9cN\u0080\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7" +
-	"e\x80\xff\xff\xff\xff̷V\x80\xff\xff\xff\xffͧG\x80\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ)\x80\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00" +
-	"\x00\x00\x05\xf68\x80\x00\x00\x00\x00\a/\xfd\x80\x00\x00\x00\x00\a\xd6\x1a\x80\x00\x00\x00\x00\t\x0f߀\x00\x00\x00\x00\t\xb5\xfc\x80\x00\x00\x00\x00\n\xef\xc1\x80\x00\x00\x00\x00\v\x9f\x19\x00\x00\x00\x00\x00\f\xd8" +
-	"\xde\x00\x00\x00\x00\x00\r~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00" +
-	"\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x17\f\x89\x80\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18ǁ\x80\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7" +
-	"c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\n\x80\x00\x00\x00\x00\x1ey\x9c\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!\x80\u0380\x00\x00" +
-	"\x00\x00\"B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\"}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00%\xef\xea\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)\t" +
-	"\x91\x00\x00\x00\x00\x00)\xaf\xae\x00\x00\x00\x00\x00*\xe9s\x00\x00\x00\x00\x00+\x98ʀ\x00\x00\x00\x00,ҏ\x80\x00\x00\x00\x00-x\xac\x80\x00\x00\x00\x00.\xb2q\x80\x00\x00\x00\x00/X\x8e\x80\x00\x00" +
-	"\x00\x000\x92S\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002r5\x80\x00\x00\x00\x003=<\x80\x00\x00\x00\x004R\x17\x80\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x0061\xf9\x80\x00\x00\x00\x006\xfd" +
-	"\x00\x80\x00\x00\x00\x008\x1b\x16\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbcĀ\x00\x00\x00\x00;\xda\xda\x00\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\xba\xbc\x00\x00\x00" +
-	"\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?\x9a\x9e\x00\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00EC" +
-	"~\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xf7\xa2\x00\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x8d\xc4\x00\x00\x00\x00\x9a\xb0\x01" +
-	"\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\nAEST-10AEDT,M10.1.0,M4.1.0/3\nPK\x03\x04\n\x00\x00\x00\x00" +
-	"\x00\x8fj\xbeT\xa2ܺ\xca:\x01\x00\x00:\x01\x00\x00\x0f\x00\x1c\x00Australia/EuclaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04" +
-	"S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x03\x00\x00\x00\x10\xff\xff\xff\xfft\xa6\n\xb0\xff\xff\xff\xff\x9cN\xd4\x14\xff\xff\xff\xff\x9c" +
-	"\xbc@\x94\xff\xff\xff\xff\xcbTĔ\xff\xff\xff\xff\xcb\xc7w\x14\xff\xff\xff\xff̷h\x14\xff\xff\xff\xffͧY\x14\x00\x00\x00\x00\t\x0f\xf1\x14\x00\x00\x00\x00\t\xb6\x0e\x14\x00\x00\x00\x00\x1a\x01X\x14\x00" +
-	"\x00\x00\x00\x1a\xa7u\x14\x00\x00\x00\x00)%R\x14\x00\x00\x00\x00)\xaf\xbf\x94\x00\x00\x00\x00Eq\xb4\x94\x00\x00\x00\x00F\x05\\\x94\x00\x00\x00\x00G#r\x14\x00\x00\x00\x00G\xeey\x14\x00\x00\x00\x00I" +
-	"\x03T\x14\x00\x00\x00\x00I\xce[\x14\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00x\xd0\x00\x00\x00\x00\x89\x1c\x01\x04\x00\x00{\f\x00\nLMT\x00+0945\x00+0" +
-	"845\x00\n<+0845>-8:45\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT3\xba\xde\xd3!\x01\x00\x00!\x01\x00\x00\x12\x00\x1c\x00Australia/Br" +
-	"isbaneUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x11\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffr\xed\x9f\b\xff\xff\xff\xff\x9cN\u0080\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff̷V\x80\xff\xff\xff" +
-	"\xffͧG\x80\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ)\x80\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00%\xef\xea\x00\x00\x00\x00\x00')\xaf" +
-	"\x00\x00\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)\t\x91\x00\x00\x00\x00\x00)\xaf\xae\x00\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x8fx\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\t" +
-	"LMT\x00AEDT\x00AEST\x00\nAEST-10\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTE\xf2\xe6Z\xeb\x03\x00\x00\xeb\x03\x00\x00\x12\x00\x1c\x00Austral" +
-	"ia/TasmaniaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00^\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xfft.\x00\xe4\xff\xff\xff\xff\x9b\xd5x\x80\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\x9d\xdaD\x80\xff\xff\xff\xff\x9e\x80a\x80\xff\xff\xff\xff\x9f\xba" +
-	"&\x80\xff\xff\xff\xff\xa0`C\x80\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff̷V\x80\xff\xff\xff\xffͧG\x80\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ)\x80\xff\xff" +
-	"\xff\xff\xfb\u008d\x00\xff\xff\xff\xff\xfc\xb2~\x00\xff\xff\xff\xff\xfd\xc7Y\x00\xff\xff\xff\xff\xfev\xb0\x80\xff\xff\xff\xff\xff\xa7;\x00\x00\x00\x00\x00\x00V\x92\x80\x00\x00\x00\x00\x01\x87\x1d\x00\x00\x00\x00\x00\x02?" +
-	"\xaf\x00\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00\a/\xfd\x80\x00\x00\x00\x00\a\xd6\x1a\x80\x00\x00\x00\x00\t\x0f߀\x00\x00" +
-	"\x00\x00\t\xb5\xfc\x80\x00\x00\x00\x00\n\xef\xc1\x80\x00\x00\x00\x00\v\x9f\x19\x00\x00\x00\x00\x00\f\xd8\xde\x00\x00\x00\x00\x00\r~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98" +
-	"\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x17\x03O\x00\x00\x00" +
-	"\x00\x00\x18!d\x80\x00\x00\x00\x00\x18\xe31\x00\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\n\x80\x00\x00\x00\x00\x1eg" +
-	"'\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!\x80\u0380\x00\x00\x00\x00\"B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\"}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00" +
-	"\x00\x00&\x02_\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xf4\xb6\x00\x00\x00\x00\x00(\xed\xe1\x80\x00\x00\x00\x00)Ԙ\x00\x00\x00\x00\x00*\xcdÀ\x00\x00\x00\x00+\xb4z\x00\x00\x00\x00\x00,\xad" +
-	"\xa5\x80\x00\x00\x00\x00-\x94\\\x00\x00\x00\x00\x00.\x8d\x87\x80\x00\x00\x00\x00/t>\x00\x00\x00\x00\x000mi\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002V\x86\x00\x00\x00\x00\x003=<\x80\x00\x00" +
-	"\x00\x0046h\x00\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x006\x16J\x00\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x007\xf6,\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbc" +
-	"Ā\x00\x00\x00\x00;\xbf*\x80\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\x9f\f\x80\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?~\xee\x80\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A^Ѐ\x00\x00" +
-	"\x00\x00BE\x87\x00\x00\x00\x00\x00C>\xb2\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00E\x1e\x94\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G\a\xb1\x00\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00\x8a\x1c\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\nAEST-10" +
-	"AEDT,M10.1.0,M4.1.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTE\xf2\xe6Z\xeb\x03\x00\x00\xeb\x03\x00\x00\x10\x00\x1c\x00Australi" +
-	"a/HobartUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00^\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xfft.\x00\xe4\xff\xff\xff\xff\x9b\xd5x\x80\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\x9d\xdaD\x80\xff\xff\xff\xff\x9e\x80a\x80\xff\xff\xff\xff\x9f\xba&\x80\xff" +
-	"\xff\xff\xff\xa0`C\x80\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff̷V\x80\xff\xff\xff\xffͧG\x80\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ)\x80\xff\xff\xff\xff\xfb" +
-	"\u008d\x00\xff\xff\xff\xff\xfc\xb2~\x00\xff\xff\xff\xff\xfd\xc7Y\x00\xff\xff\xff\xff\xfev\xb0\x80\xff\xff\xff\xff\xff\xa7;\x00\x00\x00\x00\x00\x00V\x92\x80\x00\x00\x00\x00\x01\x87\x1d\x00\x00\x00\x00\x00\x02?\xaf\x00\x00" +
-	"\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00\a/\xfd\x80\x00\x00\x00\x00\a\xd6\x1a\x80\x00\x00\x00\x00\t\x0f߀\x00\x00\x00\x00\t" +
-	"\xb5\xfc\x80\x00\x00\x00\x00\n\xef\xc1\x80\x00\x00\x00\x00\v\x9f\x19\x00\x00\x00\x00\x00\f\xd8\xde\x00\x00\x00\x00\x00\r~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00" +
-	"\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x17\x03O\x00\x00\x00\x00\x00\x18" +
-	"!d\x80\x00\x00\x00\x00\x18\xe31\x00\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\n\x80\x00\x00\x00\x00\x1eg'\x80\x00" +
-	"\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!\x80\u0380\x00\x00\x00\x00\"B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\"}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00&" +
-	"\x02_\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xf4\xb6\x00\x00\x00\x00\x00(\xed\xe1\x80\x00\x00\x00\x00)Ԙ\x00\x00\x00\x00\x00*\xcdÀ\x00\x00\x00\x00+\xb4z\x00\x00\x00\x00\x00,\xad\xa5\x80\x00" +
-	"\x00\x00\x00-\x94\\\x00\x00\x00\x00\x00.\x8d\x87\x80\x00\x00\x00\x00/t>\x00\x00\x00\x00\x000mi\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002V\x86\x00\x00\x00\x00\x003=<\x80\x00\x00\x00\x004" +
-	"6h\x00\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x006\x16J\x00\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x007\xf6,\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbcĀ\x00" +
-	"\x00\x00\x00;\xbf*\x80\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\x9f\f\x80\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?~\xee\x80\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A^Ѐ\x00\x00\x00\x00B" +
-	"E\x87\x00\x00\x00\x00\x00C>\xb2\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00E\x1e\x94\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G\a\xb1\x00\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00\x8a\x1c\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\nAEST-10AED" +
-	"T,M10.1.0,M4.1.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTϻ\xca\x1a2\x01\x00\x002\x01\x00\x00\x0f\x00\x1c\x00Australia/P" +
-	"erthUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13\x00" +
-	"\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xfft\xa6\x16\xe4\xff\xff\xff\xff\x9cNޠ\xff\xff\xff\xff\x9c\xbcK \xff\xff\xff\xff\xcbT\xcf \xff\xff\xff\xff\xcbǁ\xa0\xff\xff\xff\xff̷r\xa0\xff\xff\xff\xff\xcd" +
-	"\xa7c\xa0\x00\x00\x00\x00\t\x0f\xfb\xa0\x00\x00\x00\x00\t\xb6\x18\xa0\x00\x00\x00\x00\x1a\x01b\xa0\x00\x00\x00\x00\x1a\xa7\x7f\xa0\x00\x00\x00\x00)%\\\xa0\x00\x00\x00\x00)\xaf\xca \x00\x00\x00\x00Eq\xbf \x00" +
-	"\x00\x00\x00F\x05g \x00\x00\x00\x00G#|\xa0\x00\x00\x00\x00G\ue0e0\x00\x00\x00\x00I\x03^\xa0\x00\x00\x00\x00I\xcee\xa0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00" +
-	"l\x9c\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\tLMT\x00AWDT\x00AWST\x00\nAWST-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x8ff~ՙ\x03\x00\x00" +
-	"\x99\x03\x00\x00\x0f\x00\x1c\x00Australia/SouthUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00T\x00\x00\x00\x04\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x8b\x14\xff\xff\xff\xff{\x12\x03p\xff\xff\xff\xff\x9cNɈ\xff\xff\xff\xff\x9c\xbc6\b\xff\xff" +
-	"\xff\xff\xcbT\xba\b\xff\xff\xff\xff\xcb\xc7l\x88\xff\xff\xff\xff̷]\x88\xff\xff\xff\xffͧN\x88\xff\xff\xff\xffΠz\b\xff\xff\xff\xffχ0\x88\x00\x00\x00\x00\x03p@\x88\x00\x00\x00\x00\x04\r" +
-	"#\b\x00\x00\x00\x00\x05P\"\x88\x00\x00\x00\x00\x05\xf6?\x88\x00\x00\x00\x00\a0\x04\x88\x00\x00\x00\x00\a\xd6!\x88\x00\x00\x00\x00\t\x0f\xe6\x88\x00\x00\x00\x00\t\xb6\x03\x88\x00\x00\x00\x00\n\xefȈ\x00\x00" +
-	"\x00\x00\v\x9f \b\x00\x00\x00\x00\f\xd8\xe5\b\x00\x00\x00\x00\r\x7f\x02\b\x00\x00\x00\x00\x0e\xb8\xc7\b\x00\x00\x00\x00\x0f^\xe4\b\x00\x00\x00\x00\x10\x98\xa9\b\x00\x00\x00\x00\x11>\xc6\b\x00\x00\x00\x00\x12x" +
-	"\x8b\b\x00\x00\x00\x00\x13\x1e\xa8\b\x00\x00\x00\x00\x14Xm\b\x00\x00\x00\x00\x14\xfe\x8a\b\x00\x00\x00\x00\x168O\b\x00\x00\x00\x00\x16禈\x00\x00\x00\x00\x18!k\x88\x00\x00\x00\x00\x18Lj\x88\x00\x00" +
-	"\x00\x00\x1a\x01M\x88\x00\x00\x00\x00\x1a\xa7j\x88\x00\x00\x00\x00\x1b\xe1/\x88\x00\x00\x00\x00\x1c\x87L\x88\x00\x00\x00\x00\x1d\xc1\x11\x88\x00\x00\x00\x00\x1ey\xa3\x88\x00\x00\x00\x00\x1f\x97\xb9\b\x00\x00\x00\x00 Y" +
-	"\x85\x88\x00\x00\x00\x00!\x80Ո\x00\x00\x00\x00\"B\xa2\b\x00\x00\x00\x00#i\xf2\b\x00\x00\x00\x00$\"\x84\b\x00\x00\x00\x00%I\xd4\b\x00\x00\x00\x00&\x02f\b\x00\x00\x00\x00')\xb6\b\x00\x00" +
-	"\x00\x00'\xcf\xd3\b\x00\x00\x00\x00)\t\x98\b\x00\x00\x00\x00)\xcbd\x88\x00\x00\x00\x00*\xe9z\b\x00\x00\x00\x00+\x98ш\x00\x00\x00\x00,Җ\x88\x00\x00\x00\x00-\x8b(\x88\x00\x00\x00\x00.\xb2" +
-	"x\x88\x00\x00\x00\x00/tE\b\x00\x00\x00\x000\x92Z\x88\x00\x00\x00\x001]a\x88\x00\x00\x00\x002r<\x88\x00\x00\x00\x003=C\x88\x00\x00\x00\x004R\x1e\x88\x00\x00\x00\x005\x1d%\x88\x00\x00" +
-	"\x00\x0062\x00\x88\x00\x00\x00\x006\xfd\a\x88\x00\x00\x00\x008\x1b\x1d\b\x00\x00\x00\x008\xdc\xe9\x88\x00\x00\x00\x009\xfa\xff\b\x00\x00\x00\x00:\xbcˈ\x00\x00\x00\x00;\xda\xe1\b\x00\x00\x00\x00<\xa5" +
-	"\xe8\b\x00\x00\x00\x00=\xba\xc3\b\x00\x00\x00\x00>\x85\xca\b\x00\x00\x00\x00?\x9a\xa5\b\x00\x00\x00\x00@e\xac\b\x00\x00\x00\x00A\x83\xc1\x88\x00\x00\x00\x00BE\x8e\b\x00\x00\x00\x00Cc\xa3\x88\x00\x00" +
-	"\x00\x00D.\xaa\x88\x00\x00\x00\x00EC\x85\x88\x00\x00\x00\x00F\x05R\b\x00\x00\x00\x00G#g\x88\x00\x00\x00\x00G\xf7\xa9\b\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
-	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
-	"\x02\x03\x00\x00\x81\xec\x00\x00\x00\x00~\x90\x00\x04\x00\x00\x93\xa8\x01\t\x00\x00\x85\x98\x00\x04LMT\x00ACST\x00ACDT\x00\nACST-9:30ACDT,M10.1" +
-	".0,M4.1.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT?\x95\xbd\x12E\x01\x00\x00E\x01\x00\x00\x12\x00\x1c\x00Australia/Lindeman" +
-	"UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x00\x03\x00" +
-	"\x00\x00\x0e\xff\xff\xff\xffr\xed\xa2\xd4\xff\xff\xff\xff\x9cN\u0080\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff̷V\x80\xff\xff\xff\xffͧG\x80\xff" +
-	"\xff\xff\xffΠs\x00\xff\xff\xff\xffχ)\x80\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00%\xef\xea\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'" +
-	"\xcf\xcc\x00\x00\x00\x00\x00)\t\x91\x00\x00\x00\x00\x00)\xaf\xae\x00\x00\x00\x00\x00*\xe9s\x00\x00\x00\x00\x00+\x98ʀ\x00\x00\x00\x00,ҏ\x80\x00\x00\x00\x00-x\xac\x80\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x8b\xac\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\nAEST-10\nPK\x03\x04\n\x00\x00" +
-	"\x00\x00\x00\x8fj\xbeT\xc8R\x1a\x1b\xea\x00\x00\x00\xea\x00\x00\x00\x10\x00\x1c\x00Australia/DarwinUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1" +
-	"\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZ" +
-	"if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x04\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x92X\xff\xff\xff\xff{\x12\x03p\xff\xff" +
-	"\xff\xff\x9cNɈ\xff\xff\xff\xff\x9c\xbc6\b\xff\xff\xff\xff\xcbT\xba\b\xff\xff\xff\xff\xcb\xc7l\x88\xff\xff\xff\xff̷]\x88\xff\xff\xff\xffͧN\x88\xff\xff\xff\xffΠz\b\xff\xff\xff\xffχ" +
-	"0\x88\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00z\xa8\x00\x00\x00\x00~\x90\x00\x04\x00\x00\x93\xa8\x01\t\x00\x00\x85\x98\x00\x04LMT\x00ACST\x00ACDT\x00\nACST-9:30" +
-	"\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTϻ\xca\x1a2\x01\x00\x002\x01\x00\x00\x0e\x00\x1c\x00Australia/WestUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux" +
-	"\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00" +
-	"\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xfft\xa6\x16\xe4\xff\xff\xff\xff" +
-	"\x9cNޠ\xff\xff\xff\xff\x9c\xbcK \xff\xff\xff\xff\xcbT\xcf \xff\xff\xff\xff\xcbǁ\xa0\xff\xff\xff\xff̷r\xa0\xff\xff\xff\xffͧc\xa0\x00\x00\x00\x00\t\x0f\xfb\xa0\x00\x00\x00\x00\t\xb6\x18\xa0" +
-	"\x00\x00\x00\x00\x1a\x01b\xa0\x00\x00\x00\x00\x1a\xa7\x7f\xa0\x00\x00\x00\x00)%\\\xa0\x00\x00\x00\x00)\xaf\xca \x00\x00\x00\x00Eq\xbf \x00\x00\x00\x00F\x05g \x00\x00\x00\x00G#|\xa0\x00\x00\x00\x00" +
-	"G\ue0e0\x00\x00\x00\x00I\x03^\xa0\x00\x00\x00\x00I\xcee\xa0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00l\x9c\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\tLMT" +
-	"\x00AWDT\x00AWST\x00\nAWST-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTo3\xdaR\xb4\x02\x00\x00\xb4\x02\x00\x00\r\x00\x1c\x00Australia/L" +
-	"HIUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x008\x00\x00\x00" +
-	"\x05\x00\x00\x00\x19\xff\xff\xff\xffs\x16w\xdc\x00\x00\x00\x00\x14\xfef\xe0\x00\x00\x00\x00\x168@\xf8\x00\x00\x00\x00\x16\xe7\x8ah\x00\x00\x00\x00\x18!]x\x00\x00\x00\x00\x18\xc7lh\x00\x00\x00\x00\x1a\x01?" +
-	"x\x00\x00\x00\x00\x1a\xa7Nh\x00\x00\x00\x00\x1b\xe1!x\x00\x00\x00\x00\x1c\x870h\x00\x00\x00\x00\x1d\xc1\x03x\x00\x00\x00\x00\x1ey\x8ep\x00\x00\x00\x00\x1f\x97\xaa\xf8\x00\x00\x00\x00 Ypp\x00\x00\x00" +
-	"\x00!\x80\xc7x\x00\x00\x00\x00\"B\x8c\xf0\x00\x00\x00\x00#i\xe3\xf8\x00\x00\x00\x00$\"n\xf0\x00\x00\x00\x00%I\xc5\xf8\x00\x00\x00\x00%\xef\xdb\xf0\x00\x00\x00\x00')\xa7\xf8\x00\x00\x00\x00'Ͻ" +
-	"\xf0\x00\x00\x00\x00)\t\x89\xf8\x00\x00\x00\x00)\xaf\x9f\xf0\x00\x00\x00\x00*\xe9k\xf8\x00\x00\x00\x00+\x98\xbcp\x00\x00\x00\x00,҈x\x00\x00\x00\x00-x\x9ep\x00\x00\x00\x00.\xb2jx\x00\x00\x00" +
-	"\x00/X\x80p\x00\x00\x00\x000\x92Lx\x00\x00\x00\x001]Lp\x00\x00\x00\x002r.x\x00\x00\x00\x003=.p\x00\x00\x00\x004R\x10x\x00\x00\x00\x005\x1d\x10p\x00\x00\x00\x0061\xf2" +
-	"x\x00\x00\x00\x006\xfc\xf2p\x00\x00\x00\x008\x1b\x0e\xf8\x00\x00\x00\x008\xdc\xd4p\x00\x00\x00\x009\xa7\xe2x\x00\x00\x00\x00:\xbc\xb6p\x00\x00\x00\x00;\xda\xd2\xf8\x00\x00\x00\x00<\xa5\xd2\xf0\x00\x00\x00" +
-	"\x00=\xba\xb4\xf8\x00\x00\x00\x00>\x85\xb4\xf0\x00\x00\x00\x00?\x9a\x96\xf8\x00\x00\x00\x00@e\x96\xf0\x00\x00\x00\x00A\x83\xb3x\x00\x00\x00\x00BEx\xf0\x00\x00\x00\x00Cc\x95x\x00\x00\x00\x00D.\x95" +
-	"p\x00\x00\x00\x00ECwx\x00\x00\x00\x00F\x05<\xf0\x00\x00\x00\x00G#Yx\x00\x00\x00\x00G\xf7\x93\xf0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" +
-	"\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x95$\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00\xa1\xb8\x01\t\x00\x00\x93\xa8\x00\x0f\x00\x00\x9a\xb0\x01\x15L" +
-	"MT\x00AEST\x00+1130\x00+1030\x00+11\x00\n<+1030>-10:30<+11>-11,M10.1.0,M4.1." +
-	"0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTX\xb9\x9ap\x88\x03\x00\x00\x88\x03\x00\x00\r\x00\x1c\x00Australia/NSWUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux" +
-	"\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00" +
-	"\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x7f<\xff\xff\xff\xff" +
-	"\x9cN\u0080\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff̷V\x80\xff\xff\xff\xffͧG\x80\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ)\x80" +
-	"\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00\a/\xfd\x80\x00\x00\x00\x00\a\xd6\x1a\x80\x00\x00\x00\x00\t\x0f߀\x00\x00\x00\x00" +
-	"\t\xb5\xfc\x80\x00\x00\x00\x00\n\xef\xc1\x80\x00\x00\x00\x00\v\x9f\x19\x00\x00\x00\x00\x00\f\xd8\xde\x00\x00\x00\x00\x00\r~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00" +
-	"\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x17\f\x89\x80\x00\x00\x00\x00" +
-	"\x18!d\x80\x00\x00\x00\x00\x18ǁ\x80\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\n\x80\x00\x00\x00\x00\x1ey\x9c\x80" +
-	"\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!\x80\u0380\x00\x00\x00\x00\"B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\"}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00" +
-	"%\xef\xea\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)\t\x91\x00\x00\x00\x00\x00)\xaf\xae\x00\x00\x00\x00\x00*\xe9s\x00\x00\x00\x00\x00+\x98ʀ\x00\x00\x00\x00,ҏ\x80" +
-	"\x00\x00\x00\x00-x\xac\x80\x00\x00\x00\x00.\xb2q\x80\x00\x00\x00\x00/X\x8e\x80\x00\x00\x00\x000\x92S\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002r5\x80\x00\x00\x00\x003=<\x80\x00\x00\x00\x00" +
-	"4R\x17\x80\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x0061\xf9\x80\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x008\x1b\x16\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbcĀ" +
-	"\x00\x00\x00\x00;\xda\xda\x00\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\xba\xbc\x00\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?\x9a\x9e\x00\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00" +
-	"BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00EC~\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xf7\xa2\x00\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x8d\xc4\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\nAEST-10AEDT," +
-	"M10.1.0,M4.1.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xbd\xca#\x7f\xad\x03\x00\x00\xad\x03\x00\x00\x15\x00\x1c\x00Australia/Bro" +
-	"ken_HillUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00U\x00\x00\x00\x05\x00\x00\x00\x13\xff\xff\xff\xffs\x16\x88d\xff\xff\xff\xffv\x04\xa5\xe0\xff\xff\xff\xff{\x12\x03p\xff\xff\xff\xff\x9cNɈ\xff\xff\xff\xff\x9c\xbc6\b\xff\xff\xff\xff\xcbT\xba\b\xff" +
-	"\xff\xff\xff\xcb\xc7l\x88\xff\xff\xff\xff̷]\x88\xff\xff\xff\xffͧN\x88\xff\xff\xff\xffΠz\b\xff\xff\xff\xffχ0\x88\x00\x00\x00\x00\x03p@\x88\x00\x00\x00\x00\x04\r#\b\x00\x00\x00\x00\x05" +
-	"P\"\x88\x00\x00\x00\x00\x05\xf6?\x88\x00\x00\x00\x00\a0\x04\x88\x00\x00\x00\x00\a\xd6!\x88\x00\x00\x00\x00\t\x0f\xe6\x88\x00\x00\x00\x00\t\xb6\x03\x88\x00\x00\x00\x00\n\xefȈ\x00\x00\x00\x00\v\x9f \b\x00" +
-	"\x00\x00\x00\f\xd8\xe5\b\x00\x00\x00\x00\r\x7f\x02\b\x00\x00\x00\x00\x0e\xb8\xc7\b\x00\x00\x00\x00\x0f^\xe4\b\x00\x00\x00\x00\x10\x98\xa9\b\x00\x00\x00\x00\x11>\xc6\b\x00\x00\x00\x00\x12x\x8b\b\x00\x00\x00\x00\x13" +
-	"\x1e\xa8\b\x00\x00\x00\x00\x14Xm\b\x00\x00\x00\x00\x14\xfe\x8a\b\x00\x00\x00\x00\x168O\b\x00\x00\x00\x00\x17\f\x90\x88\x00\x00\x00\x00\x18!k\x88\x00\x00\x00\x00\x18Lj\x88\x00\x00\x00\x00\x1a\x01M\x88\x00" +
-	"\x00\x00\x00\x1a\xa7j\x88\x00\x00\x00\x00\x1b\xe1/\x88\x00\x00\x00\x00\x1c\x87L\x88\x00\x00\x00\x00\x1d\xc1\x11\x88\x00\x00\x00\x00\x1ey\xa3\x88\x00\x00\x00\x00\x1f\x97\xb9\b\x00\x00\x00\x00 Y\x85\x88\x00\x00\x00\x00!" +
-	"\x80Ո\x00\x00\x00\x00\"B\xa2\b\x00\x00\x00\x00#i\xf2\b\x00\x00\x00\x00$\"\x84\b\x00\x00\x00\x00%I\xd4\b\x00\x00\x00\x00%\xef\xf1\b\x00\x00\x00\x00')\xb6\b\x00\x00\x00\x00'\xcf\xd3\b\x00" +
-	"\x00\x00\x00)\t\x98\b\x00\x00\x00\x00)\xaf\xb5\b\x00\x00\x00\x00*\xe9z\b\x00\x00\x00\x00+\x98ш\x00\x00\x00\x00,Җ\x88\x00\x00\x00\x00-x\xb3\x88\x00\x00\x00\x00.\xb2x\x88\x00\x00\x00\x00/" +
-	"X\x95\x88\x00\x00\x00\x000\x92Z\x88\x00\x00\x00\x001]a\x88\x00\x00\x00\x002r<\x88\x00\x00\x00\x003=C\x88\x00\x00\x00\x004R\x1e\x88\x00\x00\x00\x005\x1d%\x88\x00\x00\x00\x0062\x00\x88\x00" +
-	"\x00\x00\x006\xfd\a\x88\x00\x00\x00\x008\x1b\x1d\b\x00\x00\x00\x008\xdc\xe9\x88\x00\x00\x00\x009\xfa\xff\b\x00\x00\x00\x00:\xbcˈ\x00\x00\x00\x00;\xda\xe1\b\x00\x00\x00\x00<\xa5\xe8\b\x00\x00\x00\x00=" +
-	"\xba\xc3\b\x00\x00\x00\x00>\x85\xca\b\x00\x00\x00\x00?\x9a\xa5\b\x00\x00\x00\x00@e\xac\b\x00\x00\x00\x00A\x83\xc1\x88\x00\x00\x00\x00BE\x8e\b\x00\x00\x00\x00Cc\xa3\x88\x00\x00\x00\x00D.\xaa\x88\x00" +
-	"\x00\x00\x00EC\x85\x88\x00\x00\x00\x00F\x05R\b\x00\x00\x00\x00G#g\x88\x00\x00\x00\x00G\xf7\xa9\b\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" +
-	"\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x00\x00\x84\x9c" +
-	"\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00~\x90\x00\t\x00\x00\x93\xa8\x01\x0e\x00\x00\x85\x98\x00\tLMT\x00AEST\x00ACST\x00ACDT\x00\nACST-9:30ACDT," +
-	"M10.1.0,M4.1.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTE\xf2\xe6Z\xeb\x03\x00\x00\xeb\x03\x00\x00\x10\x00\x1c\x00Australia/Cur" +
-	"rieUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00^\x00\x00" +
-	"\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xfft.\x00\xe4\xff\xff\xff\xff\x9b\xd5x\x80\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\x9d\xdaD\x80\xff\xff\xff\xff\x9e\x80a\x80\xff\xff\xff\xff\x9f\xba&\x80\xff\xff\xff\xff\xa0`" +
-	"C\x80\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff̷V\x80\xff\xff\xff\xffͧG\x80\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ)\x80\xff\xff\xff\xff\xfb\u008d\x00\xff\xff" +
-	"\xff\xff\xfc\xb2~\x00\xff\xff\xff\xff\xfd\xc7Y\x00\xff\xff\xff\xff\xfev\xb0\x80\xff\xff\xff\xff\xff\xa7;\x00\x00\x00\x00\x00\x00V\x92\x80\x00\x00\x00\x00\x01\x87\x1d\x00\x00\x00\x00\x00\x02?\xaf\x00\x00\x00\x00\x00\x03p" +
-	"9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00\a/\xfd\x80\x00\x00\x00\x00\a\xd6\x1a\x80\x00\x00\x00\x00\t\x0f߀\x00\x00\x00\x00\t\xb5\xfc\x80\x00\x00" +
-	"\x00\x00\n\xef\xc1\x80\x00\x00\x00\x00\v\x9f\x19\x00\x00\x00\x00\x00\f\xd8\xde\x00\x00\x00\x00\x00\r~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>" +
-	"\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x17\x03O\x00\x00\x00\x00\x00\x18!d\x80\x00\x00" +
-	"\x00\x00\x18\xe31\x00\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\n\x80\x00\x00\x00\x00\x1eg'\x80\x00\x00\x00\x00\x1f\x97" +
-	"\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!\x80\u0380\x00\x00\x00\x00\"B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\"}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00&\x02_\x00\x00\x00" +
-	"\x00\x00')\xaf\x00\x00\x00\x00\x00'\xf4\xb6\x00\x00\x00\x00\x00(\xed\xe1\x80\x00\x00\x00\x00)Ԙ\x00\x00\x00\x00\x00*\xcdÀ\x00\x00\x00\x00+\xb4z\x00\x00\x00\x00\x00,\xad\xa5\x80\x00\x00\x00\x00-\x94" +
-	"\\\x00\x00\x00\x00\x00.\x8d\x87\x80\x00\x00\x00\x00/t>\x00\x00\x00\x00\x000mi\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002V\x86\x00\x00\x00\x00\x003=<\x80\x00\x00\x00\x0046h\x00\x00\x00" +
-	"\x00\x005\x1d\x1e\x80\x00\x00\x00\x006\x16J\x00\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x007\xf6,\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbcĀ\x00\x00\x00\x00;\xbf" +
-	"*\x80\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\x9f\f\x80\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?~\xee\x80\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A^Ѐ\x00\x00\x00\x00BE\x87\x00\x00\x00" +
-	"\x00\x00C>\xb2\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00E\x1e\x94\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G\a\xb1\x00\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00\x8a\x1c\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\nAEST-10AEDT,M10" +
-	".1.0,M4.1.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x1c\x00Brazil/UT\t\x00\x03\xdd\xfc\x94b" +
-	"\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xb7-2f\xe4\x01\x00\x00\xe4\x01\x00\x00\x10\x00\x1c\x00Brazil/DeNo" +
-	"ronhaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'" +
-	"\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaaed\xff\xff\xff\xff\xb8\x0f;\xd0\xff\xff\xff\xff\xb8\xfd2\x90\xff\xff\xff\xff\xb9\xf1& \xff\xff\xff\xff\xba\xdef\x10\xff\xff\xff\xff\xda8\xa0 \xff\xff\xff\xff" +
-	"\xda\xeb\xec \xff\xff\xff\xff\xdc\x19Ӡ\xff\xff\xff\xffܹK\x10\xff\xff\xff\xff\xdd\xfb\a \xff\xff\xff\xffޛ\xd0\x10\xff\xff\xff\xff\xdf\u074c \xff\xff\xff\xff\xe0T%\x10\xff\xff\xff\xff\xf4\x97\xf1\xa0" +
-	"\xff\xff\xff\xff\xf5\x05P\x10\xff\xff\xff\xff\xf6\xc0V \xff\xff\xff\xff\xf7\x0e\x10\x90\xff\xff\xff\xff\xf8Q\x1e \xff\xff\xff\xff\xf8Ƿ\x10\xff\xff\xff\xff\xfa\nĠ\xff\xff\xff\xff\xfa\xa8\xea\x90\xff\xff\xff\xff" +
-	"\xfb\xeb\xf8 \xff\xff\xff\xff\xfc\x8bo\x90\x00\x00\x00\x00\x1dɀ \x00\x00\x00\x00\x1exɐ\x00\x00\x00\x00\x1f\xa0'\xa0\x00\x00\x00\x00 3\xc1\x90\x00\x00\x00\x00!\x81[ \x00\x00\x00\x00\"\v\xba\x90" +
-	"\x00\x00\x00\x00#X\x02\xa0\x00\x00\x00\x00#\xe2b\x10\x00\x00\x00\x00%7\xe4\xa0\x00\x00\x00\x00%Թ\x10\x00\x00\x00\x007\xf6\xb8\xa0\x00\x00\x00\x008\xb8w\x10\x00\x00\x00\x009\xdf\xd5 \x00\x00\x00\x00" +
-	"9\xe9\x01\x90\x00\x00\x00\x00;\xc8\xf1\xa0\x00\x00\x00\x00<o\x00\x90\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff" +
-	"\xff\xe1\x9c\x00\x00\xff\xff\xf1\xf0\x01\x04\xff\xff\xe3\xe0\x00\bLMT\x00-01\x00-02\x00\n<-02>2\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTg\xf5K\x89\xa2\x01\x00\x00\xa2" +
-	"\x01\x00\x00\v\x00\x1c\x00Brazil/AcreUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xff\x96\xaa\x86\x90\xff\xff\xff\xff\xb8\x0ff\x00\xff\xff\xff\xff\xb8\xfd\\\xc0\xff\xff\xff\xff\xb9\xf1PP\xff\xff\xff\xff\xbaސ" +
-	"@\xff\xff\xff\xff\xda8\xcaP\xff\xff\xff\xff\xda\xec\x16P\xff\xff\xff\xff\xdc\x19\xfd\xd0\xff\xff\xff\xffܹu@\xff\xff\xff\xff\xdd\xfb1P\xff\xff\xff\xffޛ\xfa@\xff\xff\xff\xff\xdfݶP\xff\xff\xff" +
-	"\xff\xe0TO@\xff\xff\xff\xff\xf4\x98\x1b\xd0\xff\xff\xff\xff\xf5\x05z@\xff\xff\xff\xff\xf6\xc0\x80P\xff\xff\xff\xff\xf7\x0e:\xc0\xff\xff\xff\xff\xf8QHP\xff\xff\xff\xff\xf8\xc7\xe1@\xff\xff\xff\xff\xfa\n\xee" +
-	"\xd0\xff\xff\xff\xff\xfa\xa9\x14\xc0\xff\xff\xff\xff\xfb\xec\"P\xff\xff\xff\xff\xfc\x8b\x99\xc0\x00\x00\x00\x00\x1dɪP\x00\x00\x00\x00\x1ex\xf3\xc0\x00\x00\x00\x00\x1f\xa0Q\xd0\x00\x00\x00\x00 3\xeb\xc0\x00\x00\x00" +
-	"\x00!\x81\x85P\x00\x00\x00\x00\"\v\xe4\xc0\x00\x00\x00\x00H`\x7fP\x00\x00\x00\x00R\x7f\x04\xc0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02" +
-	"\xff\xff\xc0p\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x00\x04LMT\x00-04\x00-05\x00\n<-05>5\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9d?" +
-	"\xdfڸ\x03\x00\x00\xb8\x03\x00\x00\v\x00\x1c\x00Brazil/EastUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00[\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaar\xb4\xff\xff\xff\xff\xb8\x0fI\xe0\xff\xff\xff\xff\xb8\xfd@\xa0\xff\xff\xff\xff\xb9\xf140" +
-	"\xff\xff\xff\xff\xba\xdet \xff\xff\xff\xff\xda8\xae0\xff\xff\xff\xff\xda\xeb\xfa0\xff\xff\xff\xff\xdc\x19\xe1\xb0\xff\xff\xff\xffܹY \xff\xff\xff\xff\xdd\xfb\x150\xff\xff\xff\xffޛ\xde \xff\xff\xff\xff" +
-	"\xdfݚ0\xff\xff\xff\xff\xe0T3 \xff\xff\xff\xff\xf4Z\t0\xff\xff\xff\xff\xf5\x05^ \xff\xff\xff\xff\xf6\xc0d0\xff\xff\xff\xff\xf7\x0e\x1e\xa0\xff\xff\xff\xff\xf8Q,0\xff\xff\xff\xff\xf8\xc7\xc5 " +
-	"\xff\xff\xff\xff\xfa\nҰ\xff\xff\xff\xff\xfa\xa8\xf8\xa0\xff\xff\xff\xff\xfb\xec\x060\xff\xff\xff\xff\xfc\x8b}\xa0\x00\x00\x00\x00\x1dɎ0\x00\x00\x00\x00\x1exנ\x00\x00\x00\x00\x1f\xa05\xb0\x00\x00\x00\x00" +
-	" 3Ϡ\x00\x00\x00\x00!\x81i0\x00\x00\x00\x00\"\vȠ\x00\x00\x00\x00#X\x10\xb0\x00\x00\x00\x00#\xe2p \x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xd4\xc7 \x00\x00\x00\x00'!\x0f0" +
-	"\x00\x00\x00\x00'\xbd\xe3\xa0\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\x94\x8b \x00\x00\x00\x00*\xea\r\xb0\x00\x00\x00\x00+k2\xa0\x00\x00\x00\x00,\xc0\xb50\x00\x00\x00\x00-f\xc4 \x00\x00\x00\x00" +
-	".\xa0\x970\x00\x00\x00\x00/F\xa6 \x00\x00\x00\x000\x80y0\x00\x00\x00\x001\x1dM\xa0\x00\x00\x00\x002W \xb0\x00\x00\x00\x003\x06j \x00\x00\x00\x0048T0\x00\x00\x00\x004\xf8\xc1 " +
-	"\x00\x00\x00\x006 \x1f0\x00\x00\x00\x006\xcfh\xa0\x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xb8\x85 \x00\x00\x00\x009\xdf\xe30\x00\x00\x00\x00:\x8f,\xa0\x00\x00\x00\x00;\xc8\xff\xb0\x00\x00\x00\x00" +
-	"<o\x0e\xa0\x00\x00\x00\x00=đ0\x00\x00\x00\x00>N\xf0\xa0\x00\x00\x00\x00?\x91\xfe0\x00\x00\x00\x00@.Ҡ\x00\x00\x00\x00A\x86\xf80\x00\x00\x00\x00B\x17\xef \x00\x00\x00\x00CQ\xc20" +
-	"\x00\x00\x00\x00C\xf7\xd1 \x00\x00\x00\x00EMS\xb0\x00\x00\x00\x00E\xe0\xed\xa0\x00\x00\x00\x00G\x11\x860\x00\x00\x00\x00G\xb7\x95 \x00\x00\x00\x00H\xfa\xa2\xb0\x00\x00\x00\x00I\x97w \x00\x00\x00\x00" +
-	"Jڄ\xb0\x00\x00\x00\x00K\x80\x93\xa0\x00\x00\x00\x00L\xbaf\xb0\x00\x00\x00\x00M`u\xa0\x00\x00\x00\x00N\x9aH\xb0\x00\x00\x00\x00OI\x92 \x00\x00\x00\x00P\x83e0\x00\x00\x00\x00Q 9\xa0" +
-	"\x00\x00\x00\x00RcG0\x00\x00\x00\x00S\x00\x1b\xa0\x00\x00\x00\x00TC)0\x00\x00\x00\x00T\xe98 \x00\x00\x00\x00V#\v0\x00\x00\x00\x00V\xc9\x1a \x00\x00\x00\x00X\x02\xed0\x00\x00\x00\x00" +
-	"X\xa8\xfc \x00\x00\x00\x00Y\xe2\xcf0\x00\x00\x00\x00Z\x88\xde \x00\x00\x00\x00[\xde`\xb0\x00\x00\x00\x00\\h\xc0 \x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\xff\xff\xd4L\x00\x00\xff\xff\xe3\xe0\x01\x04\xff\xff\xd5\xd0\x00\bLMT\x00-02\x00-03\x00\n<-03>3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTa" +
-	"\xcb'\xe9\x9c\x01\x00\x00\x9c\x01\x00\x00\v\x00\x1c\x00Brazil/WestUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaa\x7fD\xff\xff\xff\xff\xb8\x0fW\xf0\xff\xff\xff\xff\xb8\xfdN\xb0\xff\xff\xff\xff\xb9\xf1B" +
-	"@\xff\xff\xff\xff\xbaނ0\xff\xff\xff\xff\xda8\xbc@\xff\xff\xff\xff\xda\xec\b@\xff\xff\xff\xff\xdc\x19\xef\xc0\xff\xff\xff\xffܹg0\xff\xff\xff\xff\xdd\xfb#@\xff\xff\xff\xffޛ\xec0\xff\xff\xff" +
-	"\xff\xdfݨ@\xff\xff\xff\xff\xe0TA0\xff\xff\xff\xff\xf4\x98\r\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf6\xc0r@\xff\xff\xff\xff\xf7\x0e,\xb0\xff\xff\xff\xff\xf8Q:@\xff\xff\xff\xff\xf8\xc7\xd3" +
-	"0\xff\xff\xff\xff\xfa\n\xe0\xc0\xff\xff\xff\xff\xfa\xa9\x06\xb0\xff\xff\xff\xff\xfb\xec\x14@\xff\xff\xff\xff\xfc\x8b\x8b\xb0\x00\x00\x00\x00\x1dɜ@\x00\x00\x00\x00\x1ex\xe5\xb0\x00\x00\x00\x00\x1f\xa0C\xc0\x00\x00\x00" +
-	"\x00 3ݰ\x00\x00\x00\x00!\x81w@\x00\x00\x00\x00\"\vְ\x00\x00\x00\x00,\xc0\xc3@\x00\x00\x00\x00-f\xd20\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\xff\xffǼ\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\bLMT\x00-03\x00-04\x00\n<-04>4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT" +
-	"\xe6\x9aM\xbem\x02\x00\x00m\x02\x00\x00\x03\x00\x1c\x00CETUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005\x00\x00\x00\x02\x00\x00\x00\t\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9" +
-	"\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xc8\tq\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff" +
-	"\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\r\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T" +
-	"\x18\x90\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00" +
-	"\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 l" +
-	"r\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00" +
-	"\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84" +
-	"ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00" +
-	"\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x00\x0e\x10\x00\x05\x00\x00\x1c \x01\x00CEST\x00CET\x00\nCET-1CEST,M3.5.0,M1" +
-	"0.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT<\x8b\x99\x1e\xb7\x03\x00\x00\xb7\x03\x00\x00\a\x00\x1c\x00CST6CDTUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux" +
-	"\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00" +
-	"\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff" +
-	"\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xfa\xf8g\x00\xff\xff\xff\xff\xfb\xe8I\xf0" +
-	"\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8+\xf0\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\r\xf0\x00\x00\x00\x00\x00\x98\r\x00\x00\x00\x00\x00\x01\x87\xef\xf0\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00" +
-	"\x03q\fp\x00\x00\x00\x00\x04a\v\x80\x00\x00\x00\x00\x05P\xeep\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\a0\xd0p\x00\x00\x00\x00\a\x8d'\x80\x00\x00\x00\x00\t\x10\xb2p\x00\x00\x00\x00\t\xad\xa3\x00" +
-	"\x00\x00\x00\x00\n\xf0\x94p\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00\x00\x00\fٰ\xf0\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99t\xf0\x00\x00\x00\x00" +
-	"\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\"7p" +
-	"\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1܀\x00\x00\x00\x00" +
-	"\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00" +
-	"\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)\nc\xf0\x00\x00\x00\x00)\u07b3\x80\x00\x00\x00\x00*\xeaE\xf0\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3bp\x00\x00\x00\x00" +
-	"-\x9ew\x80\x00\x00\x00\x00.\xb3Dp\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x93&p\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap" +
-	"\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00" +
-	";۬\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80" +
-	"\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x01\x00\x01\x00\x02\x03\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01" +
-	"\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01" +
-	"\xff\xff\xab\xa0\x00\x04\xff\xff\xb9\xb0\x01\x00\xff\xff\xb9\xb0\x01\b\xff\xff\xb9\xb0\x01\fCDT\x00CST\x00CWT\x00CPT\x00\nCST6CDT,M3.2.0,M11." +
-	"1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x1c\x00Canada/UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04" +
-	"\x91\xf1\b\x00\x04S_\x01\x00PK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT):\x17-\x88\x06\x00\x00\x88\x06\x00\x00\x0f\x00\x1c\x00Canada/AtlanticUT\t\x00\x03\xdd" +
-	"\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff" +
-	"\xff\x80\xf1\xab\xa0\xff\xff\xff\xff\x9a\xe4\xde\xc0\xff\xff\xff\xff\x9b\xd6\x130\xff\xff\xff\xff\x9e\xb8\x85`\xff\xff\xff\xff\x9f\xba\xddP\xff\xff\xff\xff\xa2\x9d\x17@\xff\xff\xff\xff\xa30\xb10\xff\xff\xff\xff\xa4zV" +
-	"@\xff\xff\xff\xff\xa5\x1b\x1f0\xff\xff\xff\xff\xa6S\xa0\xc0\xff\xff\xff\xff\xa6\xfcR\xb0\xff\xff\xff\xff\xa8<\xbd@\xff\xff\xff\xff\xa8\xdc4\xb0\xff\xff\xff\xff\xaa\x1c\x9f@\xff\xff\xff\xff\xaa\xcd:0\xff\xff\xff" +
-	"\xff\xab\xfc\x81@\xff\xff\xff\xff\xac\xbf\x910\xff\xff\xff\xff\xad\xee\xd8@\xff\xff\xff\xff\xae\x8c\xfe0\xff\xff\xff\xff\xaf\xbcE@\xff\xff\xff\xff\xb0\x7fU0\xff\xff\xff\xff\xb1\xae\x9c@\xff\xff\xff\xff\xb2Kp" +
-	"\xb0\xff\xff\xff\xff\xb3\x8e~@\xff\xff\xff\xff\xb4$\xbb0\xff\xff\xff\xff\xb5n`@\xff\xff\xff\xff\xb6\x15\xc0\xb0\xff\xff\xff\xff\xb7NB@\xff\xff\xff\xff\xb8\b\x17\xb0\xff\xff\xff\xff\xb9$\xe9\xc0\xff\xff\xff" +
-	"\xff\xb9\xe7\xf9\xb0\xff\xff\xff\xff\xbb\x04\xcb\xc0\xff\xff\xff\xff\xbb\xd1\x160\xff\xff\xff\xff\xbd\x00]@\xff\xff\xff\xff\xbd\x9d1\xb0\xff\xff\xff\xff\xbe\xf2\xb4@\xff\xff\xff\xff\xbf\x90\xda0\xff\xff\xff\xff\xc0\xd3\xe7" +
-	"\xc0\xff\xff\xff\xff\xc1^G0\xff\xff\xff\xff\u008d\x8e@\xff\xff\xff\xff\xc3P\x9e0\xff\xff\xff\xff\xc4mp@\xff\xff\xff\xff\xc50\x800\xff\xff\xff\xff\xc6r<@\xff\xff\xff\xff\xc7\x10b0\xff\xff\xff" +
-	"\xff\xc86n\xc0\xff\xff\xff\xff\xc8\xf9~\xb0\xff\xff\xff\xff\xca\x16P\xc0\xff\xff\xff\xff\xca\xd9`\xb0\xff\xff\xff\xffˈ\xe2`\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\xff\xff\xff\xff\xd3u\xd6" +
-	"\xe0\xff\xff\xff\xff\xd4@\xcf\xd0\xff\xff\xff\xff\xd5U\xb8\xe0\xff\xff\xff\xff\xd6 \xb1\xd0\xff\xff\xff\xff\xd75\x9a\xe0\xff\xff\xff\xff\xd8\x00\x93\xd0\xff\xff\xff\xff\xd9\x15|\xe0\xff\xff\xff\xff\xd9\xe0u\xd0\xff\xff\xff" +
-	"\xff\xdc\xde{`\xff\xff\xff\xffݩtP\xff\xff\xff\xff\u07be]`\xff\xff\xff\xff߉VP\xff\xff\xff\xff\xe0\x9e?`\xff\xff\xff\xff\xe1i8P\xff\xff\xff\xff\xe2~!`\xff\xff\xff\xff\xe3I\x1a" +
-	"P\xff\xff\xff\xff\xe6G\x1f\xe0\xff\xff\xff\xff\xe7\x12\x18\xd0\xff\xff\xff\xff\xe8'\x01\xe0\xff\xff\xff\xff\xe8\xf1\xfa\xd0\xff\xff\xff\xff\xea\x06\xe3\xe0\xff\xff\xff\xff\xea\xd1\xdc\xd0\xff\xff\xff\xff\xeb\xe6\xc5\xe0\xff\xff\xff" +
-	"\xff챾\xd0\xff\xff\xff\xff\xf1\x8f\xa6`\xff\xff\xff\xff\xf2\x7f\x89P\xff\xff\xff\xff\xf3o\x88`\xff\xff\xff\xff\xf4_kP\xff\xff\xff\xff\xf5Oj`\xff\xff\xff\xff\xf6?MP\xff\xff\xff\xff\xf7/L" +
-	"`\xff\xff\xff\xff\xf8(i\xd0\xff\xff\xff\xff\xf9\x0f.`\xff\xff\xff\xff\xfa\bK\xd0\xff\xff\xff\xff\xfa\xf8J\xe0\xff\xff\xff\xff\xfb\xe8-\xd0\xff\xff\xff\xff\xfc\xd8,\xe0\xff\xff\xff\xff\xfd\xc8\x0f\xd0\xff\xff\xff" +
-	"\xff\xfe\xb8\x0e\xe0\xff\xff\xff\xff\xff\xa7\xf1\xd0\x00\x00\x00\x00\x00\x97\xf0\xe0\x00\x00\x00\x00\x01\x87\xd3\xd0\x00\x00\x00\x00\x02w\xd2\xe0\x00\x00\x00\x00\x03p\xf0P\x00\x00\x00\x00\x04`\xef`\x00\x00\x00\x00\x05P\xd2" +
-	"P\x00\x00\x00\x00\x06@\xd1`\x00\x00\x00\x00\a0\xb4P\x00\x00\x00\x00\b \xb3`\x00\x00\x00\x00\t\x10\x96P\x00\x00\x00\x00\n\x00\x95`\x00\x00\x00\x00\n\xf0xP\x00\x00\x00\x00\v\xe0w`\x00\x00\x00" +
-	"\x00\fٔ\xd0\x00\x00\x00\x00\r\xc0Y`\x00\x00\x00\x00\x0e\xb9v\xd0\x00\x00\x00\x00\x0f\xa9u\xe0\x00\x00\x00\x00\x10\x99X\xd0\x00\x00\x00\x00\x11\x89W\xe0\x00\x00\x00\x00\x12y:\xd0\x00\x00\x00\x00\x13i9" +
-	"\xe0\x00\x00\x00\x00\x14Y\x1c\xd0\x00\x00\x00\x00\x15I\x1b\xe0\x00\x00\x00\x00\x168\xfe\xd0\x00\x00\x00\x00\x17(\xfd\xe0\x00\x00\x00\x00\x18\"\x1bP\x00\x00\x00\x00\x19\b\xdf\xe0\x00\x00\x00\x00\x1a\x01\xfdP\x00\x00\x00" +
-	"\x00\x1a\xf1\xfc`\x00\x00\x00\x00\x1b\xe1\xdfP\x00\x00\x00\x00\x1c\xd1\xde`\x00\x00\x00\x00\x1d\xc1\xc1P\x00\x00\x00\x00\x1e\xb1\xc0`\x00\x00\x00\x00\x1f\xa1\xa3P\x00\x00\x00\x00 u\xf2\xe0\x00\x00\x00\x00!\x81\x85" +
-	"P\x00\x00\x00\x00\"U\xd4\xe0\x00\x00\x00\x00#j\xa1\xd0\x00\x00\x00\x00$5\xb6\xe0\x00\x00\x00\x00%J\x83\xd0\x00\x00\x00\x00&\x15\x98\xe0\x00\x00\x00\x00'*e\xd0\x00\x00\x00\x00'\xfe\xb5`\x00\x00\x00" +
-	"\x00)\nG\xd0\x00\x00\x00\x00)ޗ`\x00\x00\x00\x00*\xea)\xd0\x00\x00\x00\x00+\xbey`\x00\x00\x00\x00,\xd3FP\x00\x00\x00\x00-\x9e[`\x00\x00\x00\x00.\xb3(P\x00\x00\x00\x00/~=" +
-	"`\x00\x00\x00\x000\x93\nP\x00\x00\x00\x001gY\xe0\x00\x00\x00\x002r\xecP\x00\x00\x00\x003G;\xe0\x00\x00\x00\x004R\xceP\x00\x00\x00\x005'\x1d\xe0\x00\x00\x00\x0062\xb0P\x00\x00\x00" +
-	"\x007\x06\xff\xe0\x00\x00\x00\x008\x1b\xcc\xd0\x00\x00\x00\x008\xe6\xe1\xe0\x00\x00\x00\x009\xfb\xae\xd0\x00\x00\x00\x00:\xc6\xc3\xe0\x00\x00\x00\x00;ې\xd0\x00\x00\x00\x00<\xaf\xe0`\x00\x00\x00\x00=\xbbr" +
-	"\xd0\x00\x00\x00\x00>\x8f\xc2`\x00\x00\x00\x00?\x9bT\xd0\x00\x00\x00\x00@o\xa4`\x00\x00\x00\x00A\x84qP\x00\x00\x00\x00BO\x86`\x00\x00\x00\x00CdSP\x00\x00\x00\x00D/h`\x00\x00\x00" +
-	"\x00ED5P\x00\x00\x00\x00E\xf3\x9a\xe0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\xff\xff\xc4`\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xd5\xd0\x01\x10LMT\x00ADT\x00AST\x00AWT\x00APT\x00\nAST4ADT,M" +
-	"3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTU9#\xbe2\x05\x00\x002\x05\x00\x00\x0e\x00\x1c\x00Canada/PacificUT" +
-	"\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x00\x00\x00\x05\x00\x00\x00" +
-	"\x14\xff\xff\xff\xff^=v\xec\xff\xff\xff\xff\x9e\xb8\xbd\xa0\xff\xff\xff\xff\x9f\xbb\x15\x90\xff\xff\xff\xffˉ\x1a\xa0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a&\x10\xff\xff\xff\xff\xd3v\x0f \xff\xff\xff" +
-	"\xff\xd4A\b\x10\xff\xff\xff\xff\xd5U\xf1 \xff\xff\xff\xff\xd6 \xea\x10\xff\xff\xff\xff\xd75\xd3 \xff\xff\xff\xff\xd8\x00\xcc\x10\xff\xff\xff\xff\xd9\x15\xb5 \xff\xff\xff\xff\xd9\xe0\xae\x10\xff\xff\xff\xff\xda\xfe\xd1" +
-	"\xa0\xff\xff\xff\xff\xdb\xc0\x90\x10\xff\xff\xff\xff\xdc\u07b3\xa0\xff\xff\xff\xffݩ\xac\x90\xff\xff\xff\xff\u07be\x95\xa0\xff\xff\xff\xff߉\x8e\x90\xff\xff\xff\xff\xe0\x9ew\xa0\xff\xff\xff\xff\xe1ip\x90\xff\xff\xff" +
-	"\xff\xe2~Y\xa0\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4^;\xa0\xff\xff\xff\xff\xe5)4\x90\xff\xff\xff\xff\xe6GX \xff\xff\xff\xff\xe7\x12Q\x10\xff\xff\xff\xff\xe8': \xff\xff\xff\xff\xe8\xf23" +
-	"\x10\xff\xff\xff\xff\xea\a\x1c \xff\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff\xff\xeb\xe6\xfe \xff\xff\xff\xff\xec\xb1\xf7\x10\xff\xff\xff\xff\xed\xc6\xe0 \xff\xff\xff\xff\xee\x91\xd9\x10\xff\xff\xff\xff\xef\xaf\xfc\xa0\xff\xff\xff" +
-	"\xff\xf0q\xbb\x10\xff\xff\xff\xff\xf1\x8fޠ\xff\xff\xff\xff\xf2\x7f\xc1\x90\xff\xff\xff\xff\xf3o\xc0\xa0\xff\xff\xff\xff\xf4_\xa3\x90\xff\xff\xff\xff\xf5O\xa2\xa0\xff\xff\xff\xff\xf6?\x85\x90\xff\xff\xff\xff\xf7/\x84" +
-	"\xa0\xff\xff\xff\xff\xf8(\xa2\x10\xff\xff\xff\xff\xf9\x0ff\xa0\xff\xff\xff\xff\xfa\b\x84\x10\xff\xff\xff\xff\xfa\xf8\x83 \xff\xff\xff\xff\xfb\xe8f\x10\xff\xff\xff\xff\xfc\xd8e \xff\xff\xff\xff\xfd\xc8H\x10\xff\xff\xff" +
-	"\xff\xfe\xb8G \xff\xff\xff\xff\xff\xa8*\x10\x00\x00\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88\f\x10\x00\x00\x00\x00\x02x\v \x00\x00\x00\x00\x03q(\x90\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05Q\n" +
-	"\x90\x00\x00\x00\x00\x06A\t\xa0\x00\x00\x00\x00\a0\xec\x90\x00\x00\x00\x00\b \xeb\xa0\x00\x00\x00\x00\t\x10ΐ\x00\x00\x00\x00\n\x00͠\x00\x00\x00\x00\n\xf0\xb0\x90\x00\x00\x00\x00\v\u0be0\x00\x00\x00" +
-	"\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir" +
-	" \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00" +
-	"\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1ې\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd" +
-	"\x90\x00\x00\x00\x00\"V\r \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00" +
-	"\x00)\n\x80\x10\x00\x00\x00\x00)\xdeϠ\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u" +
-	"\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00" +
-	"\x007\a8 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab" +
-	"\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00" +
-	"\x00EDm\x90\x00\x00\x00\x00E\xf3\xd3 \x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\x8c\x94\x00\x00\xff\xff\x9d\x90\x01\x04\xff\xff\x8f\x80\x00\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10LMT\x00PDT\x00" +
-	"PST\x00PWT\x00PPT\x00\nPST8PDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTӿ\x92\xbc\xb5\x06\x00\x00\xb5\x06" +
-	"\x00\x00\x0e\x00\x1c\x00Canada/EasternUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xffr\xeex\xec\xff\xff\xff\xff\x9e\xb8\x93p\xff\xff\xff\xff\x9f\xba\xeb`\xff\xff\xff\xff\xa0\x87.\xc8\xff\xff\xff\xff\xa1" +
-	"\x9a\xb1@\xff\xff\xff\xff\xa2\x94\x06\xf0\xff\xff\xff\xff\xa3U\xa9@\xff\xff\xff\xff\xa4\x86]\xf0\xff\xff\xff\xff\xa5(x`\xff\xff\xff\xff\xa6f?\xf0\xff\xff\xff\xff\xa7\fN\xe0\xff\xff\xff\xff\xa8F!\xf0\xff" +
-	"\xff\xff\xff\xa8\xec0\xe0\xff\xff\xff\xff\xaa\x1c\xc9p\xff\xff\xff\xff\xaa\xd5M`\xff\xff\xff\xff\xab\xfc\xabp\xff\xff\xff\xff\xac\xb5/`\xff\xff\xff\xff\xad܍p\xff\xff\xff\xff\xae\x95\x11`\xff\xff\xff\xff\xaf" +
-	"\xbcop\xff\xff\xff\xff\xb0~-\xe0\xff\xff\xff\xff\xb1\x9cQp\xff\xff\xff\xff\xb2gJ`\xff\xff\xff\xff\xb3|3p\xff\xff\xff\xff\xb4G,`\xff\xff\xff\xff\xb5\\\x15p\xff\xff\xff\xff\xb6'\x0e`\xff" +
-	"\xff\xff\xff\xb7;\xf7p\xff\xff\xff\xff\xb8\x06\xf0`\xff\xff\xff\xff\xb9%\x13\xf0\xff\xff\xff\xff\xb9\xe6\xd2`\xff\xff\xff\xff\xbb\x04\xf5\xf0\xff\xff\xff\xff\xbb\xcf\xee\xe0\xff\xff\xff\xff\xbc\xe4\xd7\xf0\xff\xff\xff\xff\xbd" +
-	"\xaf\xd0\xe0\xff\xff\xff\xff\xbeĹ\xf0\xff\xff\xff\xff\xbf\x8f\xb2\xe0\xff\xff\xff\xff\xc0\xa4\x9b\xf0\xff\xff\xff\xff\xc1o\x94\xe0\xff\xff\xff\xff\u0084}\xf0\xff\xff\xff\xff\xc3Ov\xe0\xff\xff\xff\xff\xc4d_\xf0\xff" +
-	"\xff\xff\xff\xc5/X\xe0\xff\xff\xff\xff\xc6M|p\xff\xff\xff\xff\xc7\x0f:\xe0\xff\xff\xff\xff\xc8-^p\xff\xff\xff\xffˈ\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff\xd3" +
-	"u\xe4\xf0\xff\xff\xff\xff\xd4@\xdd\xe0\xff\xff\xff\xff\xd5U\xaa\xd0\xff\xff\xff\xff\xd6 \xa3\xc0\xff\xff\xff\xff\xd75\x8c\xd0\xff\xff\xff\xff\xd8\x00\x85\xc0\xff\xff\xff\xff\xd9\x15n\xd0\xff\xff\xff\xff\xda3v@\xff" +
-	"\xff\xff\xff\xda\xfe\xa7p\xff\xff\xff\xff\xdc\x13t`\xff\xff\xff\xff\xdcމp\xff\xff\xff\xffݩ\x82`\xff\xff\xff\xff\u07bekp\xff\xff\xff\xff߉d`\xff\xff\xff\xff\xe0\x9eMp\xff\xff\xff\xff\xe1" +
-	"iF`\xff\xff\xff\xff\xe2~/p\xff\xff\xff\xff\xe3I(`\xff\xff\xff\xff\xe4^\x11p\xff\xff\xff\xff\xe5)\n`\xff\xff\xff\xff\xe6G-\xf0\xff\xff\xff\xff\xe7\x12&\xe0\xff\xff\xff\xff\xe8'\x0f\xf0\xff" +
-	"\xff\xff\xff\xe9\x16\xf2\xe0\xff\xff\xff\xff\xea\x06\xf1\xf0\xff\xff\xff\xff\xea\xf6\xd4\xe0\xff\xff\xff\xff\xeb\xe6\xd3\xf0\xff\xff\xff\xff\xecֶ\xe0\xff\xff\xff\xff\xedƵ\xf0\xff\xff\xff\xff\xee\xbf\xd3`\xff\xff\xff\xff\xef" +
-	"\xaf\xd2p\xff\xff\xff\xff\xf0\x9f\xb5`\xff\xff\xff\xff\xf1\x8f\xb4p\xff\xff\xff\xff\xf2\x7f\x97`\xff\xff\xff\xff\xf3o\x96p\xff\xff\xff\xff\xf4_y`\xff\xff\xff\xff\xf5Oxp\xff\xff\xff\xff\xf6?[`\xff" +
-	"\xff\xff\xff\xf7/Zp\xff\xff\xff\xff\xf8(w\xe0\xff\xff\xff\xff\xf9\x0f<p\xff\xff\xff\xff\xfa\bY\xe0\xff\xff\xff\xff\xfa\xf8X\xf0\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd" +
-	"\xc8\x1d\xe0\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00" +
-	"\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\a0\xc2`\x00\x00\x00\x00\b \xc1p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\n\x00\xa3p\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v" +
-	"\xe0\x85p\x00\x00\x00\x00\f٢\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00" +
-	"\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a" +
-	"\x02\v`\x00\x00\x00\x00\x1a\xf2\np\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00" +
-	"\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\"U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'" +
-	"\xfe\xc3p\x00\x00\x00\x00)\nU\xe0\x00\x00\x00\x00)ޥp\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00" +
-	"\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x006" +
-	"2\xbe`\x00\x00\x00\x007\a\r\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00" +
-	"\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D" +
-	"/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xb5\x94\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\f\xff\xff\xc7\xc0\x01\x10LMT\x00EDT\x00EST\x00EWT\x00EPT" +
-	"\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xc1Ȇ\x90\x05\x04\x00\x00\x05\x04\x00\x00\f\x00\x1c\x00Canad" +
-	"a/YukonUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00]\x00\x00\x00\t\x00\x00\x00%\xff\xff\xff\xff}\x86\x8a\x9c\xff\xff\xff\xff\x9e\xb8˰\xff\xff\xff\xff\x9f\xbb#\xa0\xff\xff\xff\xff\xa0\xd0\f\xb0\xff\xff\xff\xff\xa1\xa2Ҁ\xff\xff\xff\xffˉ(\xb0\xff\xff" +
-	"\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a4 \xff\xff\xff\xff\xf7/v\x90\xff\xff\xff\xff\xf8(\xa2\x10\xff\xff\xff\xff\xfb\x1d_\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15I" +
-	"T \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00" +
-	"\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1ې\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\"V\r \x00\x00\x00\x00#j" +
-	"\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\n\x80\x10\x00\x00\x00\x00)\xdeϠ\x00\x00" +
-	"\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g" +
-	"\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\a8 \x00\x00\x00\x008\x1c\x05\x10\x00\x00" +
-	"\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b" +
-	"\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E\xf3\xd3 \x00\x00" +
-	"\x00\x00G-\x8a\x10\x00\x00\x00\x00Gӵ \x00\x00\x00\x00I\rl\x10\x00\x00\x00\x00I\xb3\x97 \x00\x00\x00\x00J\xedN\x10\x00\x00\x00\x00K\x9c\xb3\xa0\x00\x00\x00\x00L\xd6j\x90\x00\x00\x00\x00M|" +
-	"\x95\xa0\x00\x00\x00\x00N\xb6L\x90\x00\x00\x00\x00O\\w\xa0\x00\x00\x00\x00P\x96.\x90\x00\x00\x00\x00Q<Y\xa0\x00\x00\x00\x00Rv\x10\x90\x00\x00\x00\x00S\x1c;\xa0\x00\x00\x00\x00TU\xf2\x90\x00\x00" +
-	"\x00\x00T\xfc\x1d\xa0\x00\x00\x00\x00V5Ԑ\x00\x00\x00\x00V\xe5: \x00\x00\x00\x00X\x1e\xf1\x10\x00\x00\x00\x00X\xc5\x1c \x00\x00\x00\x00Y\xfe\xd3\x10\x00\x00\x00\x00Z\xa4\xfe \x00\x00\x00\x00[\xde" +
-	"\xb5\x10\x00\x00\x00\x00\\\x84\xe0 \x00\x00\x00\x00]\xbe\x97\x10\x00\x00\x00\x00^d\xc2 \x00\x00\x00\x00_\x9e\\\xf0\x02\x01\x02\x01\x02\x03\x04\x02\x05\x02\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a" +
-	"\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a" +
-	"\x06\a\x06\a\x06\a\b\xff\xff\x81d\x00\x00\xff\xff\x8f\x80\x01\x04\xff\xff\x81p\x00\b\xff\xff\x8f\x80\x01\f\xff\xff\x8f\x80\x01\x10\xff\xff\x9d\x90\x01\x14\xff\xff\x8f\x80\x00\x19\xff\xff\x9d\x90\x01\x1d\xff\xff\x9d\x90\x00" +
-	"!LMT\x00YDT\x00YST\x00YWT\x00YPT\x00YDDT\x00PST\x00PDT\x00MST\x00\nMST7\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\u0096" +
-	"dK~\x02\x00\x00~\x02\x00\x00\x13\x00\x1c\x00Canada/SaskatchewanUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01" +
-	"\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff\x86\xfd\x93\x1c\xff\xff\xff\xff\x9e\xb8\xaf\x90\xff\xff\xff\xff\x9f\xbb\a\x80" +
-	"\xff\xff\xff\xff\xb5eO\xf0\xff\xff\xff\xff\xb60H\xe0\xff\xff\xff\xff\xb7E1\xf0\xff\xff\xff\xff\xb8\x10*\xe0\xff\xff\xff\xff\xb9%\x13\xf0\xff\xff\xff\xff\xb9\xf0\f\xe0\xff\xff\xff\xff\xbb\x0e0p\xff\xff\xff\xff" +
-	"\xbb\xcf\xee\xe0\xff\xff\xff\xff\xbc\xee\x12p\xff\xff\xff\xff\xbd\xb9\v`\xff\xff\xff\xff\xc2r\b\xf0\xff\xff\xff\xff\xc3a\xeb\xe0\xff\xff\xff\xff\xc4Q\xea\xf0\xff\xff\xff\xff\xc58\x93`\xff\xff\xff\xff\xc61\xcc\xf0" +
-	"\xff\xff\xff\xff\xc7!\xaf\xe0\xff\xff\xff\xff\xc8\x1a\xe9p\xff\xff\xff\xff\xc9\n\xcc`\xff\xff\xff\xff\xc9\xfa\xcbp\xff\xff\xff\xff\xca\xea\xae`\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff" +
-	"\xd2a\x18\x00\xff\xff\xff\xff\xd3c\x8c\x10\xff\xff\xff\xff\xd4So\x00\xff\xff\xff\xff\xd5U\xe3\x10\xff\xff\xff\xff\xd6 \xdc\x00\xff\xff\xff\xff\xd75\xc5\x10\xff\xff\xff\xff\xd8\x00\xbe\x00\xff\xff\xff\xff\xd9\x15\xa7\x10" +
-	"\xff\xff\xff\xff\xd9\xe0\xa0\x00\xff\xff\xff\xff\xda\xfeÐ\xff\xff\xff\xff\xdb\xc0\x82\x00\xff\xff\xff\xff\xdcޥ\x90\xff\xff\xff\xffݩ\x9e\x80\xff\xff\xff\xff\u07be\x87\x90\xff\xff\xff\xff߉\x80\x80\xff\xff\xff\xff" +
-	"\xe0\x9ei\x90\xff\xff\xff\xff\xe1ib\x80\xff\xff\xff\xff\xe2~K\x90\xff\xff\xff\xff\xe3ID\x80\xff\xff\xff\xff\xe4^-\x90\xff\xff\xff\xff\xe5)&\x80\xff\xff\xff\xff\xe6GJ\x10\xff\xff\xff\xff\xe7\x12C\x00" +
-	"\xff\xff\xff\xff\xe8',\x10\xff\xff\xff\xff\xe8\xf2%\x00\xff\xff\xff\xff\xeb\xe6\xf0\x10\xff\xff\xff\xff\xec\xd6\xd3\x00\xff\xff\xff\xff\xed\xc6\xd2\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\xff\xff\x9d\xe4\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab" +
-	"\xa0\x01\x10\xff\xff\xab\xa0\x00\x14LMT\x00MDT\x00MST\x00MWT\x00MPT\x00CST\x00\nCST6\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT~\xb2\x0e\x19V\a\x00" +
-	"\x00V\a\x00\x00\x13\x00\x1c\x00Canada/NewfoundlandUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif" +
+	"\x00AEST\x00\nAEST-10AEDT,M10.1.0,M4.1.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8R\x1a\x1b\xea\x00\x00\x00\xea\x00" +
+	"\x00\x00\x0f\x00\x00\x00Australia/NorthTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x04\x00\x00\x00\x0e\xff\xff\xff\xff" +
+	"s\x16\x92X\xff\xff\xff\xff{\x12\x03p\xff\xff\xff\xff\x9cNɈ\xff\xff\xff\xff\x9c\xbc6\b\xff\xff\xff\xff\xcbT\xba\b\xff\xff\xff\xff\xcb\xc7l\x88\xff\xff\xff\xff̷]\x88\xff\xff\xff\xffͧN\x88" +
+	"\xff\xff\xff\xffΠz\b\xff\xff\xff\xffχ0\x88\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00z\xa8\x00\x00\x00\x00~\x90\x00\x04\x00\x00\x93\xa8\x01\t\x00\x00\x85\x98\x00\x04LMT\x00ACST\x00A" +
+	"CDT\x00\nACST-9:30\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ϻ\xca\x1a2\x01\x00\x002\x01\x00\x00\x0f\x00\x00\x00Australia/Perth" +
+	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xfft\xa6\x16\xe4\xff\xff\xff\xff\x9cNޠ\xff\xff\xff\xff\x9c\xbcK \xff" +
+	"\xff\xff\xff\xcbT\xcf \xff\xff\xff\xff\xcbǁ\xa0\xff\xff\xff\xff̷r\xa0\xff\xff\xff\xffͧc\xa0\x00\x00\x00\x00\t\x0f\xfb\xa0\x00\x00\x00\x00\t\xb6\x18\xa0\x00\x00\x00\x00\x1a\x01b\xa0\x00\x00\x00\x00\x1a" +
+	"\xa7\x7f\xa0\x00\x00\x00\x00)%\\\xa0\x00\x00\x00\x00)\xaf\xca \x00\x00\x00\x00Eq\xbf \x00\x00\x00\x00F\x05g \x00\x00\x00\x00G#|\xa0\x00\x00\x00\x00G\ue0e0\x00\x00\x00\x00I\x03^\xa0\x00" +
+	"\x00\x00\x00I\xcee\xa0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00l\x9c\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\tLMT\x00AWDT\x00AWST\x00\nA" +
+	"WST-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\xba\xde\xd3!\x01\x00\x00!\x01\x00\x00\x14\x00\x00\x00Australia/QueenslandTZif" +
 	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbb\x00\x00\x00\b\x00\x00\x00\x19\xff\xff\xff\xff^=4\xec\xff\xff\xff\xff\x9c\xcfb\f\xff\xff\xff\xff\x9d\xa4\xe6\xfc\xff\xff\xff\xff\x9e" +
-	"\xb8~\x8c\xff\xff\xff\xff\x9f\xba\xd6|\xff\xff\xff\xff\xa0\xb6\x88\xdc\xff\xff\xff\xff\xa18\xffL\xff\xff\xff\xff\xa2\x95\x19\\\xff\xff\xff\xff\xa3\x84\xfcL\xff\xff\xff\xff\xa4t\xfb\\\xff\xff\xff\xff\xa5d\xdeL\xff" +
-	"\xff\xff\xff\xa6^\x17\xdc\xff\xff\xff\xff\xa7D\xc0L\xff\xff\xff\xff\xa8=\xf9\xdc\xff\xff\xff\xff\xa9$\xa2L\xff\xff\xff\xff\xaa\x1d\xdb\xdc\xff\xff\xff\xff\xab\x04\x84L\xff\xff\xff\xff\xab\xfd\xbd\xdc\xff\xff\xff\xff\xac" +
-	"\xe4fL\xff\xff\xff\xff\xadݟ\xdc\xff\xff\xff\xff\xae͂\xcc\xff\xff\xff\xff\xaf\xbd\x81\xdc\xff\xff\xff\xff\xb0\xadd\xcc\xff\xff\xff\xff\xb1\xa6\x9e\\\xff\xff\xff\xff\xb2\x8dF\xcc\xff\xff\xff\xff\xb3\x86\x80\\\xff" +
-	"\xff\xff\xff\xb4m(\xcc\xff\xff\xff\xff\xb5fb\\\xff\xff\xff\xff\xb6M\n\xcc\xff\xff\xff\xff\xb7FD\\\xff\xff\xff\xff\xb8,\xec\xcc\xff\xff\xff\xff\xb9&&\\\xff\xff\xff\xff\xba\x16\tL\xff\xff\xff\xff\xbb" +
-	"\x0fB\xdc\xff\xff\xff\xff\xbb\xf5\xebL\xff\xff\xff\xff\xbc\xef$\xdc\xff\xff\xff\xff\xbd\xd5\xcdL\xff\xff\xff\xff\xbe\x9eMl\xff\xff\xff\xff\xbe\xcf\x06\xa8\xff\xff\xff\xff\xbf\xb5\xaf\x18\xff\xff\xff\xff\xc0\xb818\xff" +
-	"\xff\xff\xff\xc1y\xef\xa8\xff\xff\xff\xff\u0098\x138\xff\xff\xff\xff\xc3YѨ\xff\xff\xff\xff\xc4w\xf58\xff\xff\xff\xff\xc59\xb3\xa8\xff\xff\xff\xff\xc6a\x11\xb8\xff\xff\xff\xff\xc7\x19\x95\xa8\xff\xff\xff\xff\xc8" +
-	"@\xf3\xb8\xff\xff\xff\xff\xc9\x02\xb2(\xff\xff\xff\xff\xca ո\xff\xff\xff\xff\xca\xe2\x94(\xff\xff\xff\xff\xcc\x00\xb7\xb8\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xe6\xc8\xff\xff\xff\xffӈD\xd8\xff" +
-	"\xff\xff\xff\xd4J\x03H\xff\xff\xff\xff\xd5h&\xd8\xff\xff\xff\xff\xd6)\xe5H\xff\xff\xff\xff\xd7H\b\xd8\xff\xff\xff\xff\xd8\t\xc7H\xff\xff\xff\xff\xd9'\xea\xd8\xff\xff\xff\xff\xd9\xe9\xa9H\xff\xff\xff\xff\xdb" +
-	"\x11\aX\xff\xff\xff\xff\xdb\xd2\xc5\xc8\xff\xff\xff\xff\xdc\xdetX\xff\xff\xff\xffݩmH\xff\xff\xff\xff\u07beVX\xff\xff\xff\xff߉OH\xff\xff\xff\xff\xe0\x9e8X\xff\xff\xff\xff\xe1i1H\xff" +
-	"\xff\xff\xff\xe2~\x1aX\xff\xff\xff\xff\xe3I\x13H\xff\xff\xff\xff\xe4]\xfcX\xff\xff\xff\xff\xe5(\xf5H\xff\xff\xff\xff\xe6G\x18\xd8\xff\xff\xff\xff\xe7\x12\x11\xc8\xff\xff\xff\xff\xe8&\xfa\xd8\xff\xff\xff\xff\xe8" +
-	"\xf1\xf3\xc8\xff\xff\xff\xff\xea\x06\xdc\xd8\xff\xff\xff\xff\xea\xd1\xd5\xc8\xff\xff\xff\xff\xeb\xe6\xbe\xd8\xff\xff\xff\xff챷\xc8\xff\xff\xff\xff\xedƠ\xd8\xff\xff\xff\xff\ueffeH\xff\xff\xff\xffﯽX\xff" +
-	"\xff\xff\xff\xf0\x9f\xa0H\xff\xff\xff\xff\xf1\x8f\x9fX\xff\xff\xff\xff\xf2\x7f\x82H\xff\xff\xff\xff\xf3o\x81X\xff\xff\xff\xff\xf4_dH\xff\xff\xff\xff\xf5OcX\xff\xff\xff\xff\xf6?FH\xff\xff\xff\xff\xf7" +
-	"/EX\xff\xff\xff\xff\xf8(b\xc8\xff\xff\xff\xff\xf9\x0f'X\xff\xff\xff\xff\xfa\bD\xc8\xff\xff\xff\xff\xfa\xf8C\xd8\xff\xff\xff\xff\xfb\xe8&\xc8\xff\xff\xff\xff\xfc\xd8%\xd8\xff\xff\xff\xff\xfd\xc8\b\xc8\xff" +
-	"\xff\xff\xff\xfe\xb8\a\xd8\xff\xff\xff\xff\xff\xa7\xea\xc8\x00\x00\x00\x00\x00\x97\xe9\xd8\x00\x00\x00\x00\x01\x87\xcc\xc8\x00\x00\x00\x00\x02w\xcb\xd8\x00\x00\x00\x00\x03p\xe9H\x00\x00\x00\x00\x04`\xe8X\x00\x00\x00\x00\x05" +
-	"P\xcbH\x00\x00\x00\x00\x06@\xcaX\x00\x00\x00\x00\a0\xadH\x00\x00\x00\x00\b \xacX\x00\x00\x00\x00\t\x10\x8fH\x00\x00\x00\x00\n\x00\x8eX\x00\x00\x00\x00\n\xf0qH\x00\x00\x00\x00\v\xe0pX\x00" +
-	"\x00\x00\x00\fٍ\xc8\x00\x00\x00\x00\r\xc0RX\x00\x00\x00\x00\x0e\xb9o\xc8\x00\x00\x00\x00\x0f\xa9n\xd8\x00\x00\x00\x00\x10\x99Q\xc8\x00\x00\x00\x00\x11\x89P\xd8\x00\x00\x00\x00\x12y3\xc8\x00\x00\x00\x00\x13" +
-	"i2\xd8\x00\x00\x00\x00\x14Y\x15\xc8\x00\x00\x00\x00\x15I\x14\xd8\x00\x00\x00\x00\x168\xf7\xc8\x00\x00\x00\x00\x17(\xf6\xd8\x00\x00\x00\x00\x18\"\x14H\x00\x00\x00\x00\x19\b\xd8\xd8\x00\x00\x00\x00\x1a\x01\xf6H\x00" +
-	"\x00\x00\x00\x1a\xf1\xf5X\x00\x00\x00\x00\x1b\xe1\xd8H\x00\x00\x00\x00\x1c\xd1\xd7X\x00\x00\x00\x00\x1d\xc1\xbaH\x00\x00\x00\x00\x1e\xb1\xb9X\x00\x00\x00\x00\x1f\xa1\x9cH\x00\x00\x00\x00 u\xcf\xf4\x00\x00\x00\x00!" +
-	"\x81bd\x00\x00\x00\x00\"U\xb1\xf4\x00\x00\x00\x00#jp\xd4\x00\x00\x00\x00$5\x93\xf4\x00\x00\x00\x00%J`\xe4\x00\x00\x00\x00&\x15u\xf4\x00\x00\x00\x00'*B\xe4\x00\x00\x00\x00'\xfe\x92t\x00" +
-	"\x00\x00\x00)\n$\xe4\x00\x00\x00\x00)\xdett\x00\x00\x00\x00*\xea\x06\xe4\x00\x00\x00\x00+\xbeVt\x00\x00\x00\x00,\xd3#d\x00\x00\x00\x00-\x9e8t\x00\x00\x00\x00.\xb3\x05d\x00\x00\x00\x00/" +
-	"~\x1at\x00\x00\x00\x000\x92\xe7d\x00\x00\x00\x001g6\xf4\x00\x00\x00\x002r\xc9d\x00\x00\x00\x003G\x18\xf4\x00\x00\x00\x004R\xabd\x00\x00\x00\x005&\xfa\xf4\x00\x00\x00\x0062\x8dd\x00" +
-	"\x00\x00\x007\x06\xdc\xf4\x00\x00\x00\x008\x1b\xa9\xe4\x00\x00\x00\x008\xe6\xbe\xf4\x00\x00\x00\x009\xfb\x8b\xe4\x00\x00\x00\x00:Ơ\xf4\x00\x00\x00\x00;\xdbm\xe4\x00\x00\x00\x00<\xaf\xbdt\x00\x00\x00\x00=" +
-	"\xbbO\xe4\x00\x00\x00\x00>\x8f\x9ft\x00\x00\x00\x00?\x9b1\xe4\x00\x00\x00\x00@o\x81t\x00\x00\x00\x00A\x84Nd\x00\x00\x00\x00BOct\x00\x00\x00\x00Cd0d\x00\x00\x00\x00D/Et\x00" +
-	"\x00\x00\x00ED\x12d\x00\x00\x00\x00E\xf3w\xf4\x00\x00\x00\x00G-.\xe4\x00\x00\x00\x00G\xd3Y\xf4\x00\x00\x00\x00I\r\x10\xe4\x00\x00\x00\x00I\xb3;\xf4\x00\x00\x00\x00J\xec\xf2\xe4\x00\x00\x00\x00K" +
-	"\x9cXt\x00\x00\x00\x00L\xd6\x0fd\x00\x00\x00\x00M|:t\x00\x00\x00\x00N\xb6\rH\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x06\x05\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" +
-	"\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\a\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" +
-	"\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\xff\xffΔ\x00\x00\xff\xffܤ\x01\x04\xff\xffΔ\x00\b\xff\xff\xdc\xd8\x01\x04\xff\xff" +
-	"\xce\xc8\x00\b\xff\xff\xdc\xd8\x01\f\xff\xff\xdc\xd8\x01\x10\xff\xff\xea\xe8\x01\x14LMT\x00NDT\x00NST\x00NPT\x00NWT\x00NDDT\x00\nNST3:30NDT,M" +
-	"3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT?_p\x99\x0e\x05\x00\x00\x0e\x05\x00\x00\x0e\x00\x1c\x00Canada/CentralUT" +
-	"\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00}\x00\x00\x00\x05\x00\x00\x00" +
-	"\x14\xff\xff\xff\xffd䰔\xff\xff\xff\xff\x9b\x01\xfb\xe0\xff\xff\xff\xff\x9búP\xff\xff\xff\xff\x9e\xb8\xa1\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\u00a0;\x80\xff\xff\xff\xff\xc3O\x84\xf0\xff\xff\xff" +
-	"\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xffӈh\x00\xff\xff\xff\xff\xd4S`\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7" +
-	"\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xdb\x00\a\x00\xff\xff\xff\xff\xdb\xc8\\\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90p\xff\xff\xff" +
-	"\xff\u07bey\x80\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5)\x18" +
-	"p\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe7\x124\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff" +
-	"\xff\xec\xd6\xc4\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\ue47c\xf0\xff\xff\xff\xff\xf3o\xa4\x80\xff\xff\xff\xff\xf41b\xf0\xff\xff\xff\xff\xf9\x0fJ\x80\xff\xff\xff\xff\xfa\bv\x00\xff\xff\xff\xff\xfa\xf8g" +
-	"\x00\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\r\x00\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00" +
-	"\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\v\x80\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\b π\x00\x00\x00\x00\t\x10\xc0" +
-	"\x80\x00\x00\x00\x00\n\x00\xb1\x80\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00" +
-	"\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)\x1a" +
-	"\x00\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00" +
-	"\x00\x1e\xb1܀\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\xae" +
-	"\x00\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\u07b3\x80\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00" +
-	"\x00,\xd3p\x80\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003GX" +
-	"\x00\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005':\x00\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00" +
-	"\x00:\xc6\xe0\x00\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x9b" +
-	"\x80\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffr\xed\x9f\b\xff\xff\xff\xff\x9cN\u0080\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\xcb" +
+	"T\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff̷V\x80\xff\xff\xff\xffͧG\x80\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ)\x80\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00" +
+	"\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00%\xef\xea\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)\t\x91\x00\x00\x00\x00\x00)\xaf\xae\x00\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x00\x00\x8fx\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\nAEST-10\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8f" +
+	"f~ՙ\x03\x00\x00\x99\x03\x00\x00\x0f\x00\x00\x00Australia/SouthTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00T\x00\x00\x00" +
+	"\x04\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x8b\x14\xff\xff\xff\xff{\x12\x03p\xff\xff\xff\xff\x9cNɈ\xff\xff\xff\xff\x9c\xbc6\b\xff\xff\xff\xff\xcbT\xba\b\xff\xff\xff\xff\xcb\xc7l\x88\xff\xff\xff\xff̷]" +
+	"\x88\xff\xff\xff\xffͧN\x88\xff\xff\xff\xffΠz\b\xff\xff\xff\xffχ0\x88\x00\x00\x00\x00\x03p@\x88\x00\x00\x00\x00\x04\r#\b\x00\x00\x00\x00\x05P\"\x88\x00\x00\x00\x00\x05\xf6?\x88\x00\x00\x00" +
+	"\x00\a0\x04\x88\x00\x00\x00\x00\a\xd6!\x88\x00\x00\x00\x00\t\x0f\xe6\x88\x00\x00\x00\x00\t\xb6\x03\x88\x00\x00\x00\x00\n\xefȈ\x00\x00\x00\x00\v\x9f \b\x00\x00\x00\x00\f\xd8\xe5\b\x00\x00\x00\x00\r\x7f\x02" +
+	"\b\x00\x00\x00\x00\x0e\xb8\xc7\b\x00\x00\x00\x00\x0f^\xe4\b\x00\x00\x00\x00\x10\x98\xa9\b\x00\x00\x00\x00\x11>\xc6\b\x00\x00\x00\x00\x12x\x8b\b\x00\x00\x00\x00\x13\x1e\xa8\b\x00\x00\x00\x00\x14Xm\b\x00\x00\x00" +
+	"\x00\x14\xfe\x8a\b\x00\x00\x00\x00\x168O\b\x00\x00\x00\x00\x16禈\x00\x00\x00\x00\x18!k\x88\x00\x00\x00\x00\x18Lj\x88\x00\x00\x00\x00\x1a\x01M\x88\x00\x00\x00\x00\x1a\xa7j\x88\x00\x00\x00\x00\x1b\xe1/" +
+	"\x88\x00\x00\x00\x00\x1c\x87L\x88\x00\x00\x00\x00\x1d\xc1\x11\x88\x00\x00\x00\x00\x1ey\xa3\x88\x00\x00\x00\x00\x1f\x97\xb9\b\x00\x00\x00\x00 Y\x85\x88\x00\x00\x00\x00!\x80Ո\x00\x00\x00\x00\"B\xa2\b\x00\x00\x00" +
+	"\x00#i\xf2\b\x00\x00\x00\x00$\"\x84\b\x00\x00\x00\x00%I\xd4\b\x00\x00\x00\x00&\x02f\b\x00\x00\x00\x00')\xb6\b\x00\x00\x00\x00'\xcf\xd3\b\x00\x00\x00\x00)\t\x98\b\x00\x00\x00\x00)\xcbd" +
+	"\x88\x00\x00\x00\x00*\xe9z\b\x00\x00\x00\x00+\x98ш\x00\x00\x00\x00,Җ\x88\x00\x00\x00\x00-\x8b(\x88\x00\x00\x00\x00.\xb2x\x88\x00\x00\x00\x00/tE\b\x00\x00\x00\x000\x92Z\x88\x00\x00\x00" +
+	"\x001]a\x88\x00\x00\x00\x002r<\x88\x00\x00\x00\x003=C\x88\x00\x00\x00\x004R\x1e\x88\x00\x00\x00\x005\x1d%\x88\x00\x00\x00\x0062\x00\x88\x00\x00\x00\x006\xfd\a\x88\x00\x00\x00\x008\x1b\x1d" +
+	"\b\x00\x00\x00\x008\xdc\xe9\x88\x00\x00\x00\x009\xfa\xff\b\x00\x00\x00\x00:\xbcˈ\x00\x00\x00\x00;\xda\xe1\b\x00\x00\x00\x00<\xa5\xe8\b\x00\x00\x00\x00=\xba\xc3\b\x00\x00\x00\x00>\x85\xca\b\x00\x00\x00" +
+	"\x00?\x9a\xa5\b\x00\x00\x00\x00@e\xac\b\x00\x00\x00\x00A\x83\xc1\x88\x00\x00\x00\x00BE\x8e\b\x00\x00\x00\x00Cc\xa3\x88\x00\x00\x00\x00D.\xaa\x88\x00\x00\x00\x00EC\x85\x88\x00\x00\x00\x00F\x05R" +
+	"\b\x00\x00\x00\x00G#g\x88\x00\x00\x00\x00G\xf7\xa9\b\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00\x81\xec\x00\x00\x00\x00~\x90\x00\x04\x00\x00\x93\xa8\x01\t\x00" +
+	"\x00\x85\x98\x00\x04LMT\x00ACST\x00ACDT\x00\nACST-9:30ACDT,M10.1.0,M4.1.0/3\nPK\x03\x04\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00X\xb9\x9ap\x88\x03\x00\x00\x88\x03\x00\x00\x10\x00\x00\x00Australia/SydneyTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00S\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x7f<\xff\xff\xff\xff\x9cN\u0080\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff̷V\x80" +
+	"\xff\xff\xff\xffͧG\x80\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ)\x80\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00" +
+	"\a/\xfd\x80\x00\x00\x00\x00\a\xd6\x1a\x80\x00\x00\x00\x00\t\x0f߀\x00\x00\x00\x00\t\xb5\xfc\x80\x00\x00\x00\x00\n\xef\xc1\x80\x00\x00\x00\x00\v\x9f\x19\x00\x00\x00\x00\x00\f\xd8\xde\x00\x00\x00\x00\x00\r~\xfb\x00" +
+	"\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00" +
+	"\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x17\f\x89\x80\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18ǁ\x80\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80" +
+	"\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\n\x80\x00\x00\x00\x00\x1ey\x9c\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!\x80\u0380\x00\x00\x00\x00\"B\x9b\x00\x00\x00\x00\x00" +
+	"#i\xeb\x00\x00\x00\x00\x00$\"}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00%\xef\xea\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)\t\x91\x00\x00\x00\x00\x00)\xaf\xae\x00" +
+	"\x00\x00\x00\x00*\xe9s\x00\x00\x00\x00\x00+\x98ʀ\x00\x00\x00\x00,ҏ\x80\x00\x00\x00\x00-x\xac\x80\x00\x00\x00\x00.\xb2q\x80\x00\x00\x00\x00/X\x8e\x80\x00\x00\x00\x000\x92S\x80\x00\x00\x00\x00" +
+	"1]Z\x80\x00\x00\x00\x002r5\x80\x00\x00\x00\x003=<\x80\x00\x00\x00\x004R\x17\x80\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x0061\xf9\x80\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x008\x1b\x16\x00" +
+	"\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbcĀ\x00\x00\x00\x00;\xda\xda\x00\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\xba\xbc\x00\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00" +
+	"?\x9a\x9e\x00\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00EC~\x80\x00\x00\x00\x00F\x05K\x00" +
+	"\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xf7\xa2\x00\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x8d\xc4\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT" +
+	"\x00AEDT\x00AEST\x00\nAEST-10AEDT,M10.1.0,M4.1.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\xf2\xe6Z\xeb" +
+	"\x03\x00\x00\xeb\x03\x00\x00\x12\x00\x00\x00Australia/TasmaniaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00^\x00\x00\x00\x03" +
+	"\x00\x00\x00\x0e\xff\xff\xff\xfft.\x00\xe4\xff\xff\xff\xff\x9b\xd5x\x80\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\x9d\xdaD\x80\xff\xff\xff\xff\x9e\x80a\x80\xff\xff\xff\xff\x9f\xba&\x80\xff\xff\xff\xff\xa0`C\x80" +
+	"\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff̷V\x80\xff\xff\xff\xffͧG\x80\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ)\x80\xff\xff\xff\xff\xfb\u008d\x00\xff\xff\xff\xff" +
+	"\xfc\xb2~\x00\xff\xff\xff\xff\xfd\xc7Y\x00\xff\xff\xff\xff\xfev\xb0\x80\xff\xff\xff\xff\xff\xa7;\x00\x00\x00\x00\x00\x00V\x92\x80\x00\x00\x00\x00\x01\x87\x1d\x00\x00\x00\x00\x00\x02?\xaf\x00\x00\x00\x00\x00\x03p9\x80" +
+	"\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00\a/\xfd\x80\x00\x00\x00\x00\a\xd6\x1a\x80\x00\x00\x00\x00\t\x0f߀\x00\x00\x00\x00\t\xb5\xfc\x80\x00\x00\x00\x00" +
+	"\n\xef\xc1\x80\x00\x00\x00\x00\v\x9f\x19\x00\x00\x00\x00\x00\f\xd8\xde\x00\x00\x00\x00\x00\r~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00" +
+	"\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x17\x03O\x00\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00" +
+	"\x18\xe31\x00\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\n\x80\x00\x00\x00\x00\x1eg'\x80\x00\x00\x00\x00\x1f\x97\xb2\x00" +
+	"\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!\x80\u0380\x00\x00\x00\x00\"B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\"}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00&\x02_\x00\x00\x00\x00\x00" +
+	"')\xaf\x00\x00\x00\x00\x00'\xf4\xb6\x00\x00\x00\x00\x00(\xed\xe1\x80\x00\x00\x00\x00)Ԙ\x00\x00\x00\x00\x00*\xcdÀ\x00\x00\x00\x00+\xb4z\x00\x00\x00\x00\x00,\xad\xa5\x80\x00\x00\x00\x00-\x94\\\x00" +
+	"\x00\x00\x00\x00.\x8d\x87\x80\x00\x00\x00\x00/t>\x00\x00\x00\x00\x000mi\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002V\x86\x00\x00\x00\x00\x003=<\x80\x00\x00\x00\x0046h\x00\x00\x00\x00\x00" +
+	"5\x1d\x1e\x80\x00\x00\x00\x006\x16J\x00\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x007\xf6,\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbcĀ\x00\x00\x00\x00;\xbf*\x80" +
+	"\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\x9f\f\x80\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?~\xee\x80\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A^Ѐ\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00" +
+	"C>\xb2\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00E\x1e\x94\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G\a\xb1\x00\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
 	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xa4\xec\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff" +
-	"\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10LMT\x00CDT\x00CST\x00CWT\x00CPT\x00\nCST6CDT,M3.2.0,M11.1.0\n" +
-	"PK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT{\a\a\xdc\xca\x03\x00\x00\xca\x03\x00\x00\x0f\x00\x1c\x00Canada/MountainUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux" +
-	"\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00" +
-	"\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\x88\xde\xce\xe0\xff\xff\xff\xff" +
-	"\x9e\xb8\xaf\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x98\x91\x90\xff\xff\xff\xff\xa0҅\x80\xff\xff\xff\xff\xa2\x8a\xe8\x90\xff\xff\xff\xff\xa3\x84\x06\x00\xff\xff\xff\xff\xa4jʐ\xff\xff\xff\xff\xa55À" +
-	"\xff\xff\xff\xff\xa6S\xe7\x10\xff\xff\xff\xff\xa7\x15\xa5\x80\xff\xff\xff\xff\xa83\xc9\x10\xff\xff\xff\xff\xa8\xfe\xc2\x00\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff" +
-	"\xd5U\xe3\x10\xff\xff\xff\xff\xd6 \xdc\x00\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\b ݐ\x00\x00\x00\x00\t\x10\xc0\x80" +
-	"\x00\x00\x00\x00\n\x00\xbf\x90\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\vࡐ\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00" +
-	"\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10" +
-	"\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00" +
-	"\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00" +
-	"\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeߐ\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00" +
-	",\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10" +
-	"\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00" +
-	":\xc6\xee\x10\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80" +
-	"\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00\x8a\x1c\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\nAEST-10AEDT,M10.1" +
+	".0,M4.1.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\xe1\xc1\xa9\x88\x03\x00\x00\x88\x03\x00\x00\x12\x00\x00\x00Australia/Victoria" +
+	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x85\x18\xff\xff\xff\xff\x9cN\u0080\xff\xff\xff\xff\x9c\xbc/\x00\xff" +
+	"\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff̷V\x80\xff\xff\xff\xffͧG\x80\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ)\x80\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04" +
+	"\r\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00\a/\xfd\x80\x00\x00\x00\x00\a\xd6\x1a\x80\x00\x00\x00\x00\t\x0f߀\x00\x00\x00\x00\t\xb5\xfc\x80\x00\x00\x00\x00\n\xef\xc1\x80\x00" +
+	"\x00\x00\x00\v\x9f\x19\x00\x00\x00\x00\x00\f\xd8\xde\x00\x00\x00\x00\x00\r~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12" +
+	"x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x16矀\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18ǁ\x80\x00" +
+	"\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\n\x80\x00\x00\x00\x00\x1ey\x9c\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 " +
+	"Y~\x80\x00\x00\x00\x00!w\x94\x00\x00\x00\x00\x00\"B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\"}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00&\x02_\x00\x00\x00\x00\x00')\xaf\x00\x00" +
+	"\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)\t\x91\x00\x00\x00\x00\x00)\xaf\xae\x00\x00\x00\x00\x00*\xe9s\x00\x00\x00\x00\x00+\x98ʀ\x00\x00\x00\x00,ҏ\x80\x00\x00\x00\x00-x\xac\x80\x00\x00\x00\x00." +
+	"\xb2q\x80\x00\x00\x00\x00/t>\x00\x00\x00\x00\x000\x92S\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002r5\x80\x00\x00\x00\x003=<\x80\x00\x00\x00\x004R\x17\x80\x00\x00\x00\x005\x1d\x1e\x80\x00" +
+	"\x00\x00\x0061\xf9\x80\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x008\x1b\x16\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbcĀ\x00\x00\x00\x00;\xda\xda\x00\x00\x00\x00\x00<" +
+	"\xa5\xe1\x00\x00\x00\x00\x00=\xba\xbc\x00\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?\x9a\x9e\x00\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00" +
+	"\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00EC~\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xf7\xa2\x00\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
 	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\x95\xa0\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10LMT\x00MDT\x00MST\x00MWT\x00MPT\x00\n" +
-	"MST7MDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x1c\x00Chile/U" +
-	"T\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xee\xd0\x1cYN\x04\x00\x00N\x04\x00\x00\x12\x00\x1c\x00Chi" +
-	"le/EasterIslandUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00f\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffi\x87B\b\xff\xff\xff\xff\xb9\xc7@\x88\xff\xff\xff\xff\xfd\xd1<@\xff\xff\xff\xff\xfe\x92\xfa\xb0\xff\xff\xff\xff\xff\xcc\xcd\xc0\x00\x00" +
-	"\x00\x00\x00rܰ\x00\x00\x00\x00\x01uP\xc0\x00\x00\x00\x00\x02@I\xb0\x00\x00\x00\x00\x03U2\xc0\x00\x00\x00\x00\x04 +\xb0\x00\x00\x00\x00\x05>O@\x00\x00\x00\x00\x06\x00\r\xb0\x00\x00\x00\x00\a\v" +
-	"\xbc@\x00\x00\x00\x00\a\xdf\xef\xb0\x00\x00\x00\x00\b\xfe\x13@\x00\x00\x00\x00\t\xbfѰ\x00\x00\x00\x00\n\xdd\xf5@\x00\x00\x00\x00\v\xa8\xee0\x00\x00\x00\x00\f\xbd\xd7@\x00\x00\x00\x00\r\x88\xd00\x00\x00" +
-	"\x00\x00\x0e\x9d\xb9@\x00\x00\x00\x00\x0fh\xb20\x00\x00\x00\x00\x10\x86\xd5\xc0\x00\x00\x00\x00\x11H\x940\x00\x00\x00\x00\x12f\xb7\xc0\x00\x00\x00\x00\x13(v0\x00\x00\x00\x00\x14F\x99\xc0\x00\x00\x00\x00\x15\x11" +
-	"\x92\xb0\x00\x00\x00\x00\x16&{\xc0\x00\x00\x00\x00\x16\xf1t\xb0\x00\x00\x00\x00\x18\x06]\xc0\x00\x00\x00\x00\x18\xd1V\xb0\x00\x00\x00\x00\x19\xe6?\xc0\x00\x00\x00\x00\x1a\xb18\xb0\x00\x00\x00\x00\x1b\xcf\\@\x00\x00" +
-	"\x00\x00\x1c\x91\x1a\xb0\x00\x00\x00\x00\x1d\xaf>@\x00\x00\x00\x00\x1ep\xfc\xb0\x00\x00\x00\x00\x1f\x8f @\x00\x00\x00\x00 \x7f\x030\x00\x00\x00\x00!o\x02@\x00\x00\x00\x00\"9\xfb0\x00\x00\x00\x00#N" +
-	"\xe4@\x00\x00\x00\x00$\x19\xdd0\x00\x00\x00\x00%8\x00\xc0\x00\x00\x00\x00%\xf9\xbf0\x00\x00\x00\x00&\xf2\xf8\xc0\x00\x00\x00\x00'١0\x00\x00\x00\x00(\xf7\xc4\xc0\x00\x00\x00\x00)½\xb0\x00\x00" +
-	"\x00\x00*צ\xc0\x00\x00\x00\x00+\xa2\x9f\xb0\x00\x00\x00\x00,\xb7\x88\xc0\x00\x00\x00\x00-\x82\x81\xb0\x00\x00\x00\x00.\x97j\xc0\x00\x00\x00\x00/bc\xb0\x00\x00\x00\x000\x80\x87@\x00\x00\x00\x001B" +
-	"E\xb0\x00\x00\x00\x002`i@\x00\x00\x00\x003=\xd70\x00\x00\x00\x004@K@\x00\x00\x00\x005\vD0\x00\x00\x00\x006\r\xb8@\x00\x00\x00\x007\x06հ\x00\x00\x00\x008\x00\x0f@\x00\x00" +
-	"\x00\x008\xcb\b0\x00\x00\x00\x009\xe9+\xc0\x00\x00\x00\x00:\xaa\xea0\x00\x00\x00\x00;\xc9\r\xc0\x00\x00\x00\x00<\x8a\xcc0\x00\x00\x00\x00=\xa8\xef\xc0\x00\x00\x00\x00>j\xae0\x00\x00\x00\x00?\x88" +
-	"\xd1\xc0\x00\x00\x00\x00@Sʰ\x00\x00\x00\x00Ah\xb3\xc0\x00\x00\x00\x00B3\xac\xb0\x00\x00\x00\x00CH\x95\xc0\x00\x00\x00\x00D\x13\x8e\xb0\x00\x00\x00\x00E1\xb2@\x00\x00\x00\x00E\xf3p\xb0\x00\x00" +
-	"\x00\x00G\x11\x94@\x00\x00\x00\x00G\xef\x020\x00\x00\x00\x00H\xf1v@\x00\x00\x00\x00I\xbco0\x00\x00\x00\x00J\xd1X@\x00\x00\x00\x00K\xb8\x00\xb0\x00\x00\x00\x00L\xb1:@\x00\x00\x00\x00M\xc6" +
-	"\a0\x00\x00\x00\x00NP\x82\xc0\x00\x00\x00\x00O\x9c\xae\xb0\x00\x00\x00\x00PB\xd9\xc0\x00\x00\x00\x00Q|\x90\xb0\x00\x00\x00\x00R+\xf6@\x00\x00\x00\x00S\\r\xb0\x00\x00\x00\x00T\v\xd8@\x00\x00" +
-	"\x00\x00W7\xe60\x00\x00\x00\x00W\xaf\xec\xc0\x00\x00\x00\x00Y\x17\xc80\x00\x00\x00\x00Y\x8f\xce\xc0\x00\x00\x00\x00Z\xf7\xaa0\x00\x00\x00\x00[o\xb0\xc0\x00\x00\x00\x00\\\xa9g\xb0\x01\x03\x02\x03\x02\x03" +
-	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" +
-	"\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\xff\xff\x99x\x00\x00\xff\xff\x99x\x00\x04\xff\xff\xab\xa0\x01\b\xff\xff\x9d\x90\x00\f" +
-	"\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\x10LMT\x00EMT\x00-06\x00-07\x00-05\x00\n<-06>6<-05>,M9.1.6/22,M4.1." +
-	"6/22\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTC\x1a\xec\xee\x02\x05\x00\x00\x02\x05\x00\x00\x11\x00\x1c\x00Chile/ContinentalUT\t\x00\x03\xdd\xfc\x94" +
-	"b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" +
-	"\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00z\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffi" +
-	"\x87\x1d\xc5\xff\xff\xff\xff\x8f0GE\xff\xff\xff\xff\x9b\\\xe5P\xff\xff\xff\xff\x9f|\xe2\xc5\xff\xff\xff\xff\xa1\x00q\xc0\xff\xff\xff\xff\xb0^w\xc5\xff\xff\xff\xff\xb1w=@\xff\xff\xff\xff\xb2A\x00\xd0\xff" +
-	"\xff\xff\xff\xb3Xp\xc0\xff\xff\xff\xff\xb4\"4P\xff\xff\xff\xff\xb59\xa4@\xff\xff\xff\xff\xb6\x03g\xd0\xff\xff\xff\xff\xb7\x1a\xd7\xc0\xff\xff\xff\xff\xb7\xe4\x9bP\xff\xff\xff\xff\xb8\xfd\\\xc0\xff\xff\xff\xff\xb9" +
-	"\xc7 P\xff\xff\xff\xff\xcc\x1cn@\xff\xff\xff\xff\xccl\xe7\xd0\xff\xff\xff\xff\xd3\u070f\xc0\xff\xff\xff\xff\xd4\x1bɰ\xff\xff\xff\xff\xd53U\xc0\xff\xff\xff\xff\xd5v\x92@\xff\xff\xff\xff\xfd\xd1<@\xff" +
-	"\xff\xff\xff\xfe\x92\xfa\xb0\xff\xff\xff\xff\xff\xcc\xcd\xc0\x00\x00\x00\x00\x00rܰ\x00\x00\x00\x00\x01uP\xc0\x00\x00\x00\x00\x02@I\xb0\x00\x00\x00\x00\x03U2\xc0\x00\x00\x00\x00\x04 +\xb0\x00\x00\x00\x00\x05" +
-	">O@\x00\x00\x00\x00\x06\x00\r\xb0\x00\x00\x00\x00\a\v\xbc@\x00\x00\x00\x00\a\xdf\xef\xb0\x00\x00\x00\x00\b\xfe\x13@\x00\x00\x00\x00\t\xbfѰ\x00\x00\x00\x00\n\xdd\xf5@\x00\x00\x00\x00\v\xa8\xee0\x00" +
-	"\x00\x00\x00\f\xbd\xd7@\x00\x00\x00\x00\r\x88\xd00\x00\x00\x00\x00\x0e\x9d\xb9@\x00\x00\x00\x00\x0fh\xb20\x00\x00\x00\x00\x10\x86\xd5\xc0\x00\x00\x00\x00\x11H\x940\x00\x00\x00\x00\x12f\xb7\xc0\x00\x00\x00\x00\x13" +
-	"(v0\x00\x00\x00\x00\x14F\x99\xc0\x00\x00\x00\x00\x15\x11\x92\xb0\x00\x00\x00\x00\x16&{\xc0\x00\x00\x00\x00\x16\xf1t\xb0\x00\x00\x00\x00\x18\x06]\xc0\x00\x00\x00\x00\x18\xd1V\xb0\x00\x00\x00\x00\x19\xe6?\xc0\x00" +
-	"\x00\x00\x00\x1a\xb18\xb0\x00\x00\x00\x00\x1b\xcf\\@\x00\x00\x00\x00\x1c\x91\x1a\xb0\x00\x00\x00\x00\x1d\xaf>@\x00\x00\x00\x00\x1ep\xfc\xb0\x00\x00\x00\x00\x1f\x8f @\x00\x00\x00\x00 \x7f\x030\x00\x00\x00\x00!" +
-	"o\x02@\x00\x00\x00\x00\"9\xfb0\x00\x00\x00\x00#N\xe4@\x00\x00\x00\x00$\x19\xdd0\x00\x00\x00\x00%8\x00\xc0\x00\x00\x00\x00%\xf9\xbf0\x00\x00\x00\x00&\xf2\xf8\xc0\x00\x00\x00\x00'١0\x00" +
-	"\x00\x00\x00(\xf7\xc4\xc0\x00\x00\x00\x00)½\xb0\x00\x00\x00\x00*צ\xc0\x00\x00\x00\x00+\xa2\x9f\xb0\x00\x00\x00\x00,\xb7\x88\xc0\x00\x00\x00\x00-\x82\x81\xb0\x00\x00\x00\x00.\x97j\xc0\x00\x00\x00\x00/" +
-	"bc\xb0\x00\x00\x00\x000\x80\x87@\x00\x00\x00\x001BE\xb0\x00\x00\x00\x002`i@\x00\x00\x00\x003=\xd70\x00\x00\x00\x004@K@\x00\x00\x00\x005\vD0\x00\x00\x00\x006\r\xb8@\x00" +
-	"\x00\x00\x007\x06հ\x00\x00\x00\x008\x00\x0f@\x00\x00\x00\x008\xcb\b0\x00\x00\x00\x009\xe9+\xc0\x00\x00\x00\x00:\xaa\xea0\x00\x00\x00\x00;\xc9\r\xc0\x00\x00\x00\x00<\x8a\xcc0\x00\x00\x00\x00=" +
-	"\xa8\xef\xc0\x00\x00\x00\x00>j\xae0\x00\x00\x00\x00?\x88\xd1\xc0\x00\x00\x00\x00@Sʰ\x00\x00\x00\x00Ah\xb3\xc0\x00\x00\x00\x00B3\xac\xb0\x00\x00\x00\x00CH\x95\xc0\x00\x00\x00\x00D\x13\x8e\xb0\x00" +
-	"\x00\x00\x00E1\xb2@\x00\x00\x00\x00E\xf3p\xb0\x00\x00\x00\x00G\x11\x94@\x00\x00\x00\x00G\xef\x020\x00\x00\x00\x00H\xf1v@\x00\x00\x00\x00I\xbco0\x00\x00\x00\x00J\xd1X@\x00\x00\x00\x00K" +
-	"\xb8\x00\xb0\x00\x00\x00\x00L\xb1:@\x00\x00\x00\x00M\xc6\a0\x00\x00\x00\x00NP\x82\xc0\x00\x00\x00\x00O\x9c\xae\xb0\x00\x00\x00\x00PB\xd9\xc0\x00\x00\x00\x00Q|\x90\xb0\x00\x00\x00\x00R+\xf6@\x00" +
-	"\x00\x00\x00S\\r\xb0\x00\x00\x00\x00T\v\xd8@\x00\x00\x00\x00W7\xe60\x00\x00\x00\x00W\xaf\xec\xc0\x00\x00\x00\x00Y\x17\xc80\x00\x00\x00\x00Y\x8f\xce\xc0\x00\x00\x00\x00Z\xf7\xaa0\x00\x00\x00\x00[" +
-	"o\xb0\xc0\x00\x00\x00\x00\\\xa9g\xb0\x01\x02\x01\x03\x01\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x03\x02\x03\x05\x03\x02\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05" +
-	"\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05" +
-	"\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\xff\xff\xbd\xbb\x00\x00\xff\xff\xbd\xbb\x00\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x00\f\xff\xff\xc7\xc0\x01\f\xff\xff\xd5\xd0\x01\x10LMT\x00SMT\x00-05" +
-	"\x00-04\x00-03\x00\n<-04>4<-03>,M9.1.6/24,M4.1.6/24\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\a\x1c\x9e\x9a" +
-	"]\x04\x00\x00]\x04\x00\x00\x04\x00\x1c\x00CubaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00j\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffi\x87(\xb8\xff\xff\xff\xff\xacb\u0080\xff\xff\xff\xff\xb1ӔP\xff\xff\xff\xff\xb2t]@\xff\xff\xff\xff\xc8[f\xd0\xff" +
-	"\xff\xff\xff\xc8\xd3Q@\xff\xff\xff\xff\xca;H\xd0\xff\xff\xff\xffʼm\xc0\xff\xff\xff\xff\xcc$eP\xff\xff\xff\xff̜O\xc0\xff\xff\xff\xff\xd1\xc4\vP\xff\xff\xff\xff\xd2;\xf5\xc0\xff\xff\xff\xff\xd3" +
-	"\xa3\xedP\xff\xff\xff\xff\xd4\x1b\xd7\xc0\xff\xff\xff\xff\xf7`\x05\xd0\xff\xff\xff\xff\xf7\xff}@\xff\xff\xff\xff\xf9=D\xd0\xff\xff\xff\xff\xf9\xe3S\xc0\xff\xff\xff\xff\xfa\xdb;\xd0\xff\xff\xff\xff\xfb\xa7\x86@\xff" +
-	"\xff\xff\xff\xfcũ\xd0\xff\xff\xff\xff\xfd\x87h@\xff\xff\xff\xff\xfe\xb8\x00\xd0\xff\xff\xff\xff\xff\xa7\xe3\xc0\x00\x00\x00\x00\x00\x97\xe2\xd0\x00\x00\x00\x00\x01\x87\xc5\xc0\x00\x00\x00\x00\x02w\xc4\xd0\x00\x00\x00\x00\x03" +
-	"p\xe2@\x00\x00\x00\x00\x04`\xe1P\x00\x00\x00\x00\x055\x14\xc0\x00\x00\x00\x00\x06@\xc3P\x00\x00\x00\x00\a\x16H@\x00\x00\x00\x00\b \xa5P\x00\x00\x00\x00\b\xf7{\xc0\x00\x00\x00\x00\n\x00\x87P\x00" +
-	"\x00\x00\x00\n\xf0j@\x00\x00\x00\x00\v\xe0iP\x00\x00\x00\x00\fن\xc0\x00\x00\x00\x00\r\xc0KP\x00\x00\x00\x00\x0e\xb9h\xc0\x00\x00\x00\x00\x0f\xb2\xa2P\x00\x00\x00\x00\x10}\x9b@\x00\x00\x00\x00\x11" +
-	"Q\xea\xd0\x00\x00\x00\x00\x12f\xb7\xc0\x00\x00\x00\x00\x131\xcc\xd0\x00\x00\x00\x00\x14F\x99\xc0\x00\x00\x00\x00\x15[\x82\xd0\x00\x00\x00\x00\x16&{\xc0\x00\x00\x00\x00\x17;d\xd0\x00\x00\x00\x00\x18\x06]\xc0\x00" +
-	"\x00\x00\x00\x19\x1bF\xd0\x00\x00\x00\x00\x19\xe6?\xc0\x00\x00\x00\x00\x1a\xfb(\xd0\x00\x00\x00\x00\x1b\xcf\\@\x00\x00\x00\x00\x1c\xdb\n\xd0\x00\x00\x00\x00\x1d\xaf>@\x00\x00\x00\x00\x1ezSP\x00\x00\x00\x00\x1f" +
-	"\x8f @\x00\x00\x00\x00 Z5P\x00\x00\x00\x00!o\x02@\x00\x00\x00\x00\"CQ\xd0\x00\x00\x00\x00#N\xe4@\x00\x00\x00\x00$#3\xd0\x00\x00\x00\x00%.\xc6@\x00\x00\x00\x00&\x15\x8a\xd0\x00" +
-	"\x00\x00\x00'\x17\xe2\xc0\x00\x00\x00\x00'\xfe\xa7P\x00\x00\x00\x00(\xf7\xd2\xd0\x00\x00\x00\x00)މP\x00\x00\x00\x00*״\xd0\x00\x00\x00\x00+\xbekP\x00\x00\x00\x00,\xb7\x96\xd0\x00\x00\x00\x00-" +
-	"\x9eMP\x00\x00\x00\x00.\x97x\xd0\x00\x00\x00\x00/~/P\x00\x00\x00\x000wZ\xd0\x00\x00\x00\x001gK\xd0\x00\x00\x00\x002W<\xd0\x00\x00\x00\x003G-\xd0\x00\x00\x00\x004@YP\x00" +
-	"\x00\x00\x005\x1d\xd5P\x00\x00\x00\x0062\xb0P\x00\x00\x00\x006\xfd\xb7P\x00\x00\x00\x008\x1b\xcc\xd0\x00\x00\x00\x008\xe6\xd3\xd0\x00\x00\x00\x009\xfb\xae\xd0\x00\x00\x00\x00:Ƶ\xd0\x00\x00\x00\x00;" +
-	"ې\xd0\x00\x00\x00\x00<\xaf\xd2P\x00\x00\x00\x00=\xbbr\xd0\x00\x00\x00\x00>\x8f\xb4P\x00\x00\x00\x00?\x9bT\xd0\x00\x00\x00\x00@f[\xd0\x00\x00\x00\x00ED5P\x00\x00\x00\x00E\xf3\x8c\xd0\x00" +
-	"\x00\x00\x00G$\x17P\x00\x00\x00\x00GܩP\x00\x00\x00\x00I\x03\xf9P\x00\x00\x00\x00I\xb3P\xd0\x00\x00\x00\x00J\xe3\xdbP\x00\x00\x00\x00K\x9cmP\x00\x00\x00\x00L\xcc\xf7\xd0\x00\x00\x00\x00M" +
-	"\x85\x89\xd0\x00\x00\x00\x00N\xbfN\xd0\x00\x00\x00\x00Ow\xe0\xd0\x00\x00\x00\x00P\x95\xf6P\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\xb2\xc8\x00\x00\xff\xff\xb2\xc0\x00\x04\xff\xff\xc7\xc0\x01\b\xff\xff\xb9\xb0\x00\fLMT\x00HMT\x00CDT\x00CST\x00\nCST5CD" +
-	"T,M3.2.0/0,M11.1.0/1\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT`l\x8d~\xf1\x01\x00\x00\xf1\x01\x00\x00\x03\x00\x1c\x00EETUT\t\x00\x03\xdd" +
-	"\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\x00\x00\x00\x02\x00\x00\x00\t\x00\x00\x00" +
-	"\x00\r\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa" +
-	"\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00" +
-	"\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT" +
-	"\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00" +
-	"\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad" +
-	"\x90\x00\x00\x00\x001]\xd9\x10\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x00\x1c \x00\x05\x00\x00*0\x01\x00" +
-	"EEST\x00EET\x00\nEET-2EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTtX\xbe\xe4o\x00\x00" +
-	"\x00o\x00\x00\x00\x03\x00\x1c\x00ESTUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\xb9\xb0\x00\x00EST\x00\nEST5\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe7/\xebT\xb7\x03\x00\x00\xb7\x03\x00\x00\a\x00\x1c" +
-	"\x00EST5EDTUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00X\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\x9e\xa6\x1ep\xff\xff\xff\xff\x9f\xba\xeb`\xff\xff\xff\xff\xa0\x86\x00p\xff\xff\xff\xff\xa1\x9a\xcd`\xff\xff\xff\xffˈ\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff" +
-	"\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff\xfa\xf8X\xf0\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00" +
-	"\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\a0\xc2`\x00" +
-	"\x00\x00\x00\a\x8d\x19p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\t\xad\x94\xf0\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00\f٢\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00\x00\x00\x0e" +
-	"\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00" +
-	"\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x00\x00\x00\x00\x1a\xf2\np\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c" +
-	"\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\"U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00" +
-	"\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\nU\xe0\x00\x00\x00\x00)ޥp\x00\x00\x00\x00*" +
-	"\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00" +
-	"\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\a\r\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008" +
-	"\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00" +
-	"\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x01\x00\x01\x00\x02" +
-	"\x03\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00" +
-	"\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\xff\xff\xb9\xb0\x00\x04\xff\xff\xc7\xc0\x01\x00\xff\xff\xc7\xc0\x01\b\xff\xff\xc7\xc0\x01\fEDT\x00EST\x00EWT\x00E" +
-	"PT\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\x12tnj\xfc\x04\x00\x00\xfc\x04\x00\x00\x05\x00\x1c\x00Egy" +
-	"ptUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00" +
-	"\x03\x00\x00\x00\r\xff\xff\xff\xff}\xbdM\xab\xff\xff\xff\xffȓ\xb4\xe0\xff\xff\xff\xff\xc8\xfa{\xd0\xff\xff\xff\xff\xc9\xfc\xef\xe0\xff\xff\xff\xff\xca\xc7\xe8\xd0\xff\xff\xff\xff\xcbˮ`\xff\xff\xff\xff\xcc\xdf)" +
-	"\xd0\xff\xff\xff\xffͬ\xe1\xe0\xff\xff\xff\xff\xce\xc6\xf4\xd0\xff\xff\xff\xffϏf\xe0\xff\xff\xff\xffЩy\xd0\xff\xff\xff\xffф`\xe0\xff\xff\xff\xffҊ\xadP\xff\xff\xff\xff\xe86c`\xff\xff\xff" +
-	"\xff\xe8\xf4-P\xff\xff\xff\xff\xea\v\xb9`\xff\xff\xff\xff\xea\xd5`\xd0\xff\xff\xff\xff\xeb\xec\xfa\xf0\xff\xff\xff\xff\xec\xb5m\x00\xff\xff\xff\xff\xed\xcf\x7f\xf0\xff\xff\xff\xff\xee\x97\xf2\x00\xff\xff\xff\xffﰳ" +
-	"p\xff\xff\xff\xff\xf0y%\x80\xff\xff\xff\xff\xf1\x91\xe6\xf0\xff\xff\xff\xff\xf2ZY\x00\xff\xff\xff\xff\xf3s\x1ap\xff\xff\xff\xff\xf4;\x8c\x80\xff\xff\xff\xff\xf5U\x9fp\xff\xff\xff\xff\xf6\x1e\x11\x80\xff\xff\xff" +
-	"\xff\xf76\xd2\xf0\xff\xff\xff\xff\xf7\xffE\x00\xff\xff\xff\xff\xf9\x18\x06p\xff\xff\xff\xff\xf9\xe1\xca\x00\xff\xff\xff\xff\xfa\xf99\xf0\xff\xff\xff\xff\xfb\xc2\xfd\x80\xff\xff\xff\xff\xfc۾\xf0\xff\xff\xff\xff\xfd\xa5\x82" +
-	"\x80\xff\xff\xff\xff\xfe\xbc\xf2p\xff\xff\xff\xff\xff\x86\xb6\x00\x00\x00\x00\x00\x00\x9e%\xf0\x00\x00\x00\x00\x01g\xe9\x80\x00\x00\x00\x00\x02\x7fYp\x00\x00\x00\x00\x03I\x1d\x00\x00\x00\x00\x00\x04a\xdep\x00\x00\x00" +
-	"\x00\x05+\xa2\x00\x00\x00\x00\x00\x06C\x11\xf0\x00\x00\x00\x00\a\fՀ\x00\x00\x00\x00\b$Ep\x00\x00\x00\x00\b\xee\t\x00\x00\x00\x00\x00\n\x05x\xf0\x00\x00\x00\x00\n\xcf<\x80\x00\x00\x00\x00\v\xe7\xfd" +
-	"\xf0\x00\x00\x00\x00\f\xb1\xc1\x80\x00\x00\x00\x00\r\xc91p\x00\x00\x00\x00\x0e\x92\xf5\x00\x00\x00\x00\x00\x0f\xaad\xf0\x00\x00\x00\x00\x10t(\x80\x00\x00\x00\x00\x11\x8b\x98p\x00\x00\x00\x00\x12U\\\x00\x00\x00\x00" +
-	"\x00\x13n\x1dp\x00\x00\x00\x00\x147\xe1\x00\x00\x00\x00\x00\x15OP\xf0\x00\x00\x00\x00\x16\x19\x14\x80\x00\x00\x00\x00\x17\xa0\x93\xf0\x00\x00\x00\x00\x17\xfaH\x00\x00\x00\x00\x00\x19p\xa3\xf0\x00\x00\x00\x00\x19\xdb{" +
-	"\x80\x00\x00\x00\x00\x1a\xf4<\xf0\x00\x00\x00\x00\x1b\xbe\x00\x80\x00\x00\x00\x00\x1c\xd5pp\x00\x00\x00\x00\x1d\x9f4\x00\x00\x00\x00\x00\x1e\xb6\xa3\xf0\x00\x00\x00\x00\x1f\x80g\x80\x00\x00\x00\x00 \x97\xd7p\x00\x00\x00" +
-	"\x00!a\x9b\x00\x00\x00\x00\x00\"z\\p\x00\x00\x00\x00#D \x00\x00\x00\x00\x00$b'p\x00\x00\x00\x00%%S\x80\x00\x00\x00\x00&<\xc3p\x00\x00\x00\x00'\x06\x87\x00\x00\x00\x00\x00(\x1d\xf6" +
-	"\xf0\x00\x00\x00\x00(纀\x00\x00\x00\x00*\x00{\xf0\x00\x00\x00\x00*\xca?\x80\x00\x00\x00\x00+\xe1\xafp\x00\x00\x00\x00,\xabs\x00\x00\x00\x00\x00-\xc2\xe2\xf0\x00\x00\x00\x00.\x8c\xa6\x80\x00\x00\x00" +
-	"\x00/\xa0\x13\xe0\x00\x00\x00\x000k\f\xd0\x00\x00\x00\x001\x7f\xf5\xe0\x00\x00\x00\x002J\xee\xd0\x00\x00\x00\x003_\xd7\xe0\x00\x00\x00\x004*\xd0\xd0\x00\x00\x00\x005?\xb9\xe0\x00\x00\x00\x006\n\xb2" +
-	"\xd0\x00\x00\x00\x007(\xd6`\x00\x00\x00\x007\xf3\xcfP\x00\x00\x00\x009\b\xb8`\x00\x00\x00\x009ӱP\x00\x00\x00\x00:\xe8\x9a`\x00\x00\x00\x00;\xb3\x93P\x00\x00\x00\x00<\xc8|`\x00\x00\x00" +
-	"\x00=\x93uP\x00\x00\x00\x00>\xa8^`\x00\x00\x00\x00?sWP\x00\x00\x00\x00@\x91z\xe0\x00\x00\x00\x00A\\s\xd0\x00\x00\x00\x00Bq\\\xe0\x00\x00\x00\x00C<U\xd0\x00\x00\x00\x00DQ>" +
-	"\xe0\x00\x00\x00\x00E\x12\xfdP\x00\x00\x00\x00F1 \xe0\x00\x00\x00\x00F\xe0jP\x00\x00\x00\x00H\x11\x02\xe0\x00\x00\x00\x00H\xb7\x11\xd0\x00\x00\x00\x00I\xf0\xe4\xe0\x00\x00\x00\x00J\x8d\xb9P\x00\x00\x00" +
-	"\x00K\xda\x01`\x00\x00\x00\x00La\xbd\xd0\x00\x00\x00\x00L\x89X\xe0\x00\x00\x00\x00L\xa4\xfaP\x00\x00\x00\x00Su8\xe0\x00\x00\x00\x00S\xac\x89\xd0\x00\x00\x00\x00Sڼ`\x00\x00\x00\x00T$\x82" +
-	"P\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x1dU\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\tLMT\x00EEST\x00EET\x00\nEET-2\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT" +
-	"\x9a\v\xf9/\xd8\x05\x00\x00\xd8\x05\x00\x00\x04\x00\x1c\x00EireUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00" +
+	"\x01\x02\x00\x00\x87\xe8\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\nAEST-10AEDT,M10.1.0,M4.1." +
+	"0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ϻ\xca\x1a2\x01\x00\x002\x01\x00\x00\x0e\x00\x00\x00Australia/WestTZif2\x00\x00\x00\x00\x00\x00\x00" +
 	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x91\x00\x00\x00\b\x00\x00\x00\x14\xff\xff\xff\xffW\xd1\n\xdc\xff\xff\xff\xff\x9b&\xb3\x91\xff\xff\xff\xff\x9b\xd6\v\x11\xff\xff\xff\xff\x9c\xcf0\xa0\xff\xff\xff\xff\x9d" +
-	"\xa4à\xff\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff\xff\xff\xa0\x85\xba \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{Ƞ\xff\xff\xff\xff\xa4N\xb8\xa0\xff" +
-	"\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00Ӡ\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab" +
-	"\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \xff\xff\xff\xff\xb1\x92Р\xff\xff\xff\xff\xb2pL\xa0\xff" +
-	"\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \xff\xff\xff\xff\xb60\x10\xa0\xff\xff\xff\xff\xb72v\xa0\xff\xff\xff\xff\xb8\x0f\xf2\xa0\xff\xff\xff\xff\xb9\x12X\xa0\xff\xff\xff\xff\xb9" +
-	"\xefԠ\xff\xff\xff\xff\xba\xe9\x00 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff" +
-	"\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7" +
-	"\xda\t\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd7,( \xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff" +
-	"\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\u07b4\xea\xa0\xff\xff\xff\xff߮\x16 \xff\xff\xff\xff\xe0\x94̠\xff\xff\xff\xff\xe1" +
-	"rH\xa0\xff\xff\xff\xff\xe2kt \xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4T\x90\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6=\xad \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\xff" +
-	"\xff\xff\xff\xe8\xfb\v \xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\ue6b1 \xff\xff\xff\xff\xef" +
-	"\x81g\xa0\xff\xff\xff\xff\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\x7f_ \xff\xff\xff\xff\xf3Jf \xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\r\xa0\xff\xff\xff\xff\xf6?# \xff" +
-	"\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0Ѡ\xff\xff\xff\xff\xf9\xfe\xe7 \xff\xff\xff\xff\xfa\xc0\xb3\xa0\xff\xff\xff\xff\xfb\xe8\x03\xa0\xff\xff\xff\xff\xfc{\xab\xa0\xff\xff\xff\xff\xfd" +
-	"ǻp\x00\x00\x00\x00\x03p\xc6 \x00\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\t: \x00\x00\x00\x00\a0\x8a \x00\x00\x00\x00\a\xe9\x1c \x00\x00\x00\x00\t\x10l \x00" +
-	"\x00\x00\x00\t\xc8\xfe \x00\x00\x00\x00\n\xf0N \x00\x00\x00\x00\v\xb2\x1a\xa0\x00\x00\x00\x00\f\xd00 \x00\x00\x00\x00\r\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \x00\x00\x00\x00\x0fqޠ\x00\x00\x00\x00\x10" +
-	"\x99.\xa0\x00\x00\x00\x00\x11Q\xc0\xa0\x00\x00\x00\x00\x12y\x10\xa0\x00\x00\x00\x00\x131\xa2\xa0\x00\x00\x00\x00\x14X\xf2\xa0\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x168Ɛ\x00\x00\x00\x00\x17\x03͐\x00" +
-	"\x00\x00\x00\x18\x18\xa8\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19\xf8\x8a\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xe1\xa7\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\xc1\x89\x10\x00\x00\x00\x00\x1e" +
-	"\x8c\x90\x10\x00\x00\x00\x00\x1f\xa1k\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\x81M\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#a/\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%JK\x90\x00" +
-	"\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'*-\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00)\n\x0f\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xe9\xf1\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00," +
-	"\xc9Ӑ\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\xa9\xb5\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000\x89\x97\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x05\x04\x05\x04" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xfft\xa6\x16\xe4\xff\xff\xff\xff\x9cNޠ\xff\xff\xff\xff\x9c\xbcK \xff\xff\xff\xff\xcbT\xcf \xff\xff\xff\xff\xcb" +
+	"ǁ\xa0\xff\xff\xff\xff̷r\xa0\xff\xff\xff\xffͧc\xa0\x00\x00\x00\x00\t\x0f\xfb\xa0\x00\x00\x00\x00\t\xb6\x18\xa0\x00\x00\x00\x00\x1a\x01b\xa0\x00\x00\x00\x00\x1a\xa7\x7f\xa0\x00\x00\x00\x00)%\\\xa0\x00" +
+	"\x00\x00\x00)\xaf\xca \x00\x00\x00\x00Eq\xbf \x00\x00\x00\x00F\x05g \x00\x00\x00\x00G#|\xa0\x00\x00\x00\x00G\ue0e0\x00\x00\x00\x00I\x03^\xa0\x00\x00\x00\x00I\xcee\xa0\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00l\x9c\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\tLMT\x00AWDT\x00AWST\x00\nAWST-8\nPK\x03\x04\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\xbd\xca#\x7f\xad\x03\x00\x00\xad\x03\x00\x00\x14\x00\x00\x00Australia/YancowinnaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00U\x00\x00\x00\x05\x00\x00\x00\x13\xff\xff\xff\xffs\x16\x88d\xff\xff\xff\xffv\x04\xa5\xe0\xff\xff\xff\xff{\x12\x03p\xff\xff\xff\xff\x9cNɈ\xff\xff\xff\xff\x9c\xbc6\b\xff" +
+	"\xff\xff\xff\xcbT\xba\b\xff\xff\xff\xff\xcb\xc7l\x88\xff\xff\xff\xff̷]\x88\xff\xff\xff\xffͧN\x88\xff\xff\xff\xffΠz\b\xff\xff\xff\xffχ0\x88\x00\x00\x00\x00\x03p@\x88\x00\x00\x00\x00\x04" +
+	"\r#\b\x00\x00\x00\x00\x05P\"\x88\x00\x00\x00\x00\x05\xf6?\x88\x00\x00\x00\x00\a0\x04\x88\x00\x00\x00\x00\a\xd6!\x88\x00\x00\x00\x00\t\x0f\xe6\x88\x00\x00\x00\x00\t\xb6\x03\x88\x00\x00\x00\x00\n\xefȈ\x00" +
+	"\x00\x00\x00\v\x9f \b\x00\x00\x00\x00\f\xd8\xe5\b\x00\x00\x00\x00\r\x7f\x02\b\x00\x00\x00\x00\x0e\xb8\xc7\b\x00\x00\x00\x00\x0f^\xe4\b\x00\x00\x00\x00\x10\x98\xa9\b\x00\x00\x00\x00\x11>\xc6\b\x00\x00\x00\x00\x12" +
+	"x\x8b\b\x00\x00\x00\x00\x13\x1e\xa8\b\x00\x00\x00\x00\x14Xm\b\x00\x00\x00\x00\x14\xfe\x8a\b\x00\x00\x00\x00\x168O\b\x00\x00\x00\x00\x17\f\x90\x88\x00\x00\x00\x00\x18!k\x88\x00\x00\x00\x00\x18Lj\x88\x00" +
+	"\x00\x00\x00\x1a\x01M\x88\x00\x00\x00\x00\x1a\xa7j\x88\x00\x00\x00\x00\x1b\xe1/\x88\x00\x00\x00\x00\x1c\x87L\x88\x00\x00\x00\x00\x1d\xc1\x11\x88\x00\x00\x00\x00\x1ey\xa3\x88\x00\x00\x00\x00\x1f\x97\xb9\b\x00\x00\x00\x00 " +
+	"Y\x85\x88\x00\x00\x00\x00!\x80Ո\x00\x00\x00\x00\"B\xa2\b\x00\x00\x00\x00#i\xf2\b\x00\x00\x00\x00$\"\x84\b\x00\x00\x00\x00%I\xd4\b\x00\x00\x00\x00%\xef\xf1\b\x00\x00\x00\x00')\xb6\b\x00" +
+	"\x00\x00\x00'\xcf\xd3\b\x00\x00\x00\x00)\t\x98\b\x00\x00\x00\x00)\xaf\xb5\b\x00\x00\x00\x00*\xe9z\b\x00\x00\x00\x00+\x98ш\x00\x00\x00\x00,Җ\x88\x00\x00\x00\x00-x\xb3\x88\x00\x00\x00\x00." +
+	"\xb2x\x88\x00\x00\x00\x00/X\x95\x88\x00\x00\x00\x000\x92Z\x88\x00\x00\x00\x001]a\x88\x00\x00\x00\x002r<\x88\x00\x00\x00\x003=C\x88\x00\x00\x00\x004R\x1e\x88\x00\x00\x00\x005\x1d%\x88\x00" +
+	"\x00\x00\x0062\x00\x88\x00\x00\x00\x006\xfd\a\x88\x00\x00\x00\x008\x1b\x1d\b\x00\x00\x00\x008\xdc\xe9\x88\x00\x00\x00\x009\xfa\xff\b\x00\x00\x00\x00:\xbcˈ\x00\x00\x00\x00;\xda\xe1\b\x00\x00\x00\x00<" +
+	"\xa5\xe8\b\x00\x00\x00\x00=\xba\xc3\b\x00\x00\x00\x00>\x85\xca\b\x00\x00\x00\x00?\x9a\xa5\b\x00\x00\x00\x00@e\xac\b\x00\x00\x00\x00A\x83\xc1\x88\x00\x00\x00\x00BE\x8e\b\x00\x00\x00\x00Cc\xa3\x88\x00" +
+	"\x00\x00\x00D.\xaa\x88\x00\x00\x00\x00EC\x85\x88\x00\x00\x00\x00F\x05R\b\x00\x00\x00\x00G#g\x88\x00\x00\x00\x00G\xf7\xa9\b\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" +
+	"\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" +
+	"\x03\x04\x03\x04\x00\x00\x84\x9c\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00~\x90\x00\t\x00\x00\x93\xa8\x01\x0e\x00\x00\x85\x98\x00\tLMT\x00AEST\x00ACST\x00ACDT\x00\nACST-9" +
+	":30ACDT,M10.1.0,M4.1.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\xf5K\x89\xa2\x01\x00\x00\xa2\x01\x00\x00\v\x00\x00\x00Brazi" +
+	"l/AcreTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZi" +
+	"f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xff\x96\xaa\x86\x90\xff\xff\xff\xff\xb8\x0ff\x00\xff\xff\xff" +
+	"\xff\xb8\xfd\\\xc0\xff\xff\xff\xff\xb9\xf1PP\xff\xff\xff\xff\xbaސ@\xff\xff\xff\xff\xda8\xcaP\xff\xff\xff\xff\xda\xec\x16P\xff\xff\xff\xff\xdc\x19\xfd\xd0\xff\xff\xff\xffܹu@\xff\xff\xff\xff\xdd\xfb1" +
+	"P\xff\xff\xff\xffޛ\xfa@\xff\xff\xff\xff\xdfݶP\xff\xff\xff\xff\xe0TO@\xff\xff\xff\xff\xf4\x98\x1b\xd0\xff\xff\xff\xff\xf5\x05z@\xff\xff\xff\xff\xf6\xc0\x80P\xff\xff\xff\xff\xf7\x0e:\xc0\xff\xff\xff" +
+	"\xff\xf8QHP\xff\xff\xff\xff\xf8\xc7\xe1@\xff\xff\xff\xff\xfa\n\xee\xd0\xff\xff\xff\xff\xfa\xa9\x14\xc0\xff\xff\xff\xff\xfb\xec\"P\xff\xff\xff\xff\xfc\x8b\x99\xc0\x00\x00\x00\x00\x1dɪP\x00\x00\x00\x00\x1ex\xf3" +
+	"\xc0\x00\x00\x00\x00\x1f\xa0Q\xd0\x00\x00\x00\x00 3\xeb\xc0\x00\x00\x00\x00!\x81\x85P\x00\x00\x00\x00\"\v\xe4\xc0\x00\x00\x00\x00H`\x7fP\x00\x00\x00\x00R\x7f\x04\xc0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\xff\xff\xc0p\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x00\x04LMT\x00-04\x00-05\x00\n<-0" +
+	"5>5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7-2f\xe4\x01\x00\x00\xe4\x01\x00\x00\x10\x00\x00\x00Brazil/DeNoronhaTZif2\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaaed\xff\xff\xff\xff\xb8\x0f;\xd0\xff\xff\xff\xff\xb8\xfd2\x90\xff\xff\xff\xff\xb9\xf1& \xff\xff\xff" +
+	"\xff\xba\xdef\x10\xff\xff\xff\xff\xda8\xa0 \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdc\x19Ӡ\xff\xff\xff\xffܹK\x10\xff\xff\xff\xff\xdd\xfb\a \xff\xff\xff\xffޛ\xd0\x10\xff\xff\xff\xff\xdf\u074c" +
+	" \xff\xff\xff\xff\xe0T%\x10\xff\xff\xff\xff\xf4\x97\xf1\xa0\xff\xff\xff\xff\xf5\x05P\x10\xff\xff\xff\xff\xf6\xc0V \xff\xff\xff\xff\xf7\x0e\x10\x90\xff\xff\xff\xff\xf8Q\x1e \xff\xff\xff\xff\xf8Ƿ\x10\xff\xff\xff" +
+	"\xff\xfa\nĠ\xff\xff\xff\xff\xfa\xa8\xea\x90\xff\xff\xff\xff\xfb\xeb\xf8 \xff\xff\xff\xff\xfc\x8bo\x90\x00\x00\x00\x00\x1dɀ \x00\x00\x00\x00\x1exɐ\x00\x00\x00\x00\x1f\xa0'\xa0\x00\x00\x00\x00 3\xc1" +
+	"\x90\x00\x00\x00\x00!\x81[ \x00\x00\x00\x00\"\v\xba\x90\x00\x00\x00\x00#X\x02\xa0\x00\x00\x00\x00#\xe2b\x10\x00\x00\x00\x00%7\xe4\xa0\x00\x00\x00\x00%Թ\x10\x00\x00\x00\x007\xf6\xb8\xa0\x00\x00\x00" +
+	"\x008\xb8w\x10\x00\x00\x00\x009\xdf\xd5 \x00\x00\x00\x009\xe9\x01\x90\x00\x00\x00\x00;\xc8\xf1\xa0\x00\x00\x00\x00<o\x00\x90\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xe1\x9c\x00\x00\xff\xff\xf1\xf0\x01\x04\xff\xff\xe3\xe0\x00\bLMT\x00-01\x00-02\x00\n<-02>2\nPK\x03\x04\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x9d?\xdfڸ\x03\x00\x00\xb8\x03\x00\x00\v\x00\x00\x00Brazil/EastTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00[\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaar\xb4\xff\xff\xff\xff\xb8\x0fI\xe0\xff\xff\xff\xff\xb8\xfd@\xa0\xff\xff\xff\xff\xb9\xf140\xff\xff\xff\xff\xba\xdet \xff\xff\xff\xff\xda8\xae0\xff\xff" +
+	"\xff\xff\xda\xeb\xfa0\xff\xff\xff\xff\xdc\x19\xe1\xb0\xff\xff\xff\xffܹY \xff\xff\xff\xff\xdd\xfb\x150\xff\xff\xff\xffޛ\xde \xff\xff\xff\xff\xdfݚ0\xff\xff\xff\xff\xe0T3 \xff\xff\xff\xff\xf4Z" +
+	"\t0\xff\xff\xff\xff\xf5\x05^ \xff\xff\xff\xff\xf6\xc0d0\xff\xff\xff\xff\xf7\x0e\x1e\xa0\xff\xff\xff\xff\xf8Q,0\xff\xff\xff\xff\xf8\xc7\xc5 \xff\xff\xff\xff\xfa\nҰ\xff\xff\xff\xff\xfa\xa8\xf8\xa0\xff\xff" +
+	"\xff\xff\xfb\xec\x060\xff\xff\xff\xff\xfc\x8b}\xa0\x00\x00\x00\x00\x1dɎ0\x00\x00\x00\x00\x1exנ\x00\x00\x00\x00\x1f\xa05\xb0\x00\x00\x00\x00 3Ϡ\x00\x00\x00\x00!\x81i0\x00\x00\x00\x00\"\v" +
+	"Ƞ\x00\x00\x00\x00#X\x10\xb0\x00\x00\x00\x00#\xe2p \x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xd4\xc7 \x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xbd\xe3\xa0\x00\x00\x00\x00)\x00\xf10\x00\x00" +
+	"\x00\x00)\x94\x8b \x00\x00\x00\x00*\xea\r\xb0\x00\x00\x00\x00+k2\xa0\x00\x00\x00\x00,\xc0\xb50\x00\x00\x00\x00-f\xc4 \x00\x00\x00\x00.\xa0\x970\x00\x00\x00\x00/F\xa6 \x00\x00\x00\x000\x80" +
+	"y0\x00\x00\x00\x001\x1dM\xa0\x00\x00\x00\x002W \xb0\x00\x00\x00\x003\x06j \x00\x00\x00\x0048T0\x00\x00\x00\x004\xf8\xc1 \x00\x00\x00\x006 \x1f0\x00\x00\x00\x006\xcfh\xa0\x00\x00" +
+	"\x00\x007\xf6ư\x00\x00\x00\x008\xb8\x85 \x00\x00\x00\x009\xdf\xe30\x00\x00\x00\x00:\x8f,\xa0\x00\x00\x00\x00;\xc8\xff\xb0\x00\x00\x00\x00<o\x0e\xa0\x00\x00\x00\x00=đ0\x00\x00\x00\x00>N" +
+	"\xf0\xa0\x00\x00\x00\x00?\x91\xfe0\x00\x00\x00\x00@.Ҡ\x00\x00\x00\x00A\x86\xf80\x00\x00\x00\x00B\x17\xef \x00\x00\x00\x00CQ\xc20\x00\x00\x00\x00C\xf7\xd1 \x00\x00\x00\x00EMS\xb0\x00\x00" +
+	"\x00\x00E\xe0\xed\xa0\x00\x00\x00\x00G\x11\x860\x00\x00\x00\x00G\xb7\x95 \x00\x00\x00\x00H\xfa\xa2\xb0\x00\x00\x00\x00I\x97w \x00\x00\x00\x00Jڄ\xb0\x00\x00\x00\x00K\x80\x93\xa0\x00\x00\x00\x00L\xba" +
+	"f\xb0\x00\x00\x00\x00M`u\xa0\x00\x00\x00\x00N\x9aH\xb0\x00\x00\x00\x00OI\x92 \x00\x00\x00\x00P\x83e0\x00\x00\x00\x00Q 9\xa0\x00\x00\x00\x00RcG0\x00\x00\x00\x00S\x00\x1b\xa0\x00\x00" +
+	"\x00\x00TC)0\x00\x00\x00\x00T\xe98 \x00\x00\x00\x00V#\v0\x00\x00\x00\x00V\xc9\x1a \x00\x00\x00\x00X\x02\xed0\x00\x00\x00\x00X\xa8\xfc \x00\x00\x00\x00Y\xe2\xcf0\x00\x00\x00\x00Z\x88" +
+	"\xde \x00\x00\x00\x00[\xde`\xb0\x00\x00\x00\x00\\h\xc0 \x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xd4L\x00\x00\xff\xff\xe3\xe0\x01" +
+	"\x04\xff\xff\xd5\xd0\x00\bLMT\x00-02\x00-03\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a\xcb'\xe9\x9c\x01\x00\x00\x9c\x01\x00\x00\v\x00\x00\x00Bra" +
+	"zil/WestTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00T" +
+	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaa\x7fD\xff\xff\xff\xff\xb8\x0fW\xf0\xff" +
+	"\xff\xff\xff\xb8\xfdN\xb0\xff\xff\xff\xff\xb9\xf1B@\xff\xff\xff\xff\xbaނ0\xff\xff\xff\xff\xda8\xbc@\xff\xff\xff\xff\xda\xec\b@\xff\xff\xff\xff\xdc\x19\xef\xc0\xff\xff\xff\xffܹg0\xff\xff\xff\xff\xdd" +
+	"\xfb#@\xff\xff\xff\xffޛ\xec0\xff\xff\xff\xff\xdfݨ@\xff\xff\xff\xff\xe0TA0\xff\xff\xff\xff\xf4\x98\r\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf6\xc0r@\xff\xff\xff\xff\xf7\x0e,\xb0\xff" +
+	"\xff\xff\xff\xf8Q:@\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xfa\n\xe0\xc0\xff\xff\xff\xff\xfa\xa9\x06\xb0\xff\xff\xff\xff\xfb\xec\x14@\xff\xff\xff\xff\xfc\x8b\x8b\xb0\x00\x00\x00\x00\x1dɜ@\x00\x00\x00\x00\x1e" +
+	"x\xe5\xb0\x00\x00\x00\x00\x1f\xa0C\xc0\x00\x00\x00\x00 3ݰ\x00\x00\x00\x00!\x81w@\x00\x00\x00\x00\"\vְ\x00\x00\x00\x00,\xc0\xc3@\x00\x00\x00\x00-f\xd20\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xffǼ\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\bLMT\x00-03\x00-04\x00\n<-04>4\n" +
+	"PK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe6\x9aM\xbem\x02\x00\x00m\x02\x00\x00\x03\x00\x00\x00CETTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005" +
+	"\x00\x00\x00\x02\x00\x00\x00\t\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff" +
+	"\xc8\tq\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2N@\x90" +
+	"\x00\x00\x00\x00\r\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00" +
+	"\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90" +
+	"\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00" +
+	"\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90" +
+	"\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x00" +
+	"0d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00" +
+	"\x01\x00\x01\x00\x01\x00\x00\x0e\x10\x00\x05\x00\x00\x1c \x01\x00CEST\x00CET\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00<\x8b\x99\x1e\xb7\x03\x00\x00\xb7\x03\x00\x00\a\x00\x00\x00CST6CDTTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X\x00\x00" +
+	"\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a" +
+	"\t\xf0\xff\xff\xff\xff\xfa\xf8g\x00\xff\xff\xff\xff\xfb\xe8I\xf0\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8+\xf0\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\r\xf0\x00\x00\x00\x00\x00\x98\r\x00\x00\x00" +
+	"\x00\x00\x01\x87\xef\xf0\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\fp\x00\x00\x00\x00\x04a\v\x80\x00\x00\x00\x00\x05P\xeep\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\a0\xd0p\x00\x00\x00\x00\a\x8d" +
+	"'\x80\x00\x00\x00\x00\t\x10\xb2p\x00\x00\x00\x00\t\xad\xa3\x00\x00\x00\x00\x00\n\xf0\x94p\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00\x00\x00\fٰ\xf0\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00" +
+	"\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99t\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169" +
+	"\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\"7p\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00" +
+	"\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1܀\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5" +
+	"\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)\nc\xf0\x00\x00\x00\x00)\u07b3\x80\x00\x00\x00\x00*\xeaE\xf0\x00\x00" +
+	"\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3bp\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3Dp\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x93&p\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s" +
+	"\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00" +
+	"\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00;۬\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o" +
+	"\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x01\x00\x01\x00\x02\x03\x00\x01\x00\x01" +
+	"\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01" +
+	"\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\xff\xff\xab\xa0\x00\x04\xff\xff\xb9\xb0\x01\x00\xff\xff\xb9\xb0\x01\b\xff\xff\xb9\xb0\x01\fCDT\x00CST\x00CWT\x00CPT\x00\nC" +
+	"ST6CDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00):\x17-\x88\x06\x00\x00\x88\x06\x00\x00\x0f\x00\x00\x00Canada/A" +
+	"tlanticTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZ" +
+	"if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\x80\xf1\xab\xa0\xff\xff\xff\xff\x9a\xe4\xde\xc0\xff\xff" +
+	"\xff\xff\x9b\xd6\x130\xff\xff\xff\xff\x9e\xb8\x85`\xff\xff\xff\xff\x9f\xba\xddP\xff\xff\xff\xff\xa2\x9d\x17@\xff\xff\xff\xff\xa30\xb10\xff\xff\xff\xff\xa4zV@\xff\xff\xff\xff\xa5\x1b\x1f0\xff\xff\xff\xff\xa6S" +
+	"\xa0\xc0\xff\xff\xff\xff\xa6\xfcR\xb0\xff\xff\xff\xff\xa8<\xbd@\xff\xff\xff\xff\xa8\xdc4\xb0\xff\xff\xff\xff\xaa\x1c\x9f@\xff\xff\xff\xff\xaa\xcd:0\xff\xff\xff\xff\xab\xfc\x81@\xff\xff\xff\xff\xac\xbf\x910\xff\xff" +
+	"\xff\xff\xad\xee\xd8@\xff\xff\xff\xff\xae\x8c\xfe0\xff\xff\xff\xff\xaf\xbcE@\xff\xff\xff\xff\xb0\x7fU0\xff\xff\xff\xff\xb1\xae\x9c@\xff\xff\xff\xff\xb2Kp\xb0\xff\xff\xff\xff\xb3\x8e~@\xff\xff\xff\xff\xb4$" +
+	"\xbb0\xff\xff\xff\xff\xb5n`@\xff\xff\xff\xff\xb6\x15\xc0\xb0\xff\xff\xff\xff\xb7NB@\xff\xff\xff\xff\xb8\b\x17\xb0\xff\xff\xff\xff\xb9$\xe9\xc0\xff\xff\xff\xff\xb9\xe7\xf9\xb0\xff\xff\xff\xff\xbb\x04\xcb\xc0\xff\xff" +
+	"\xff\xff\xbb\xd1\x160\xff\xff\xff\xff\xbd\x00]@\xff\xff\xff\xff\xbd\x9d1\xb0\xff\xff\xff\xff\xbe\xf2\xb4@\xff\xff\xff\xff\xbf\x90\xda0\xff\xff\xff\xff\xc0\xd3\xe7\xc0\xff\xff\xff\xff\xc1^G0\xff\xff\xff\xff\u008d" +
+	"\x8e@\xff\xff\xff\xff\xc3P\x9e0\xff\xff\xff\xff\xc4mp@\xff\xff\xff\xff\xc50\x800\xff\xff\xff\xff\xc6r<@\xff\xff\xff\xff\xc7\x10b0\xff\xff\xff\xff\xc86n\xc0\xff\xff\xff\xff\xc8\xf9~\xb0\xff\xff" +
+	"\xff\xff\xca\x16P\xc0\xff\xff\xff\xff\xca\xd9`\xb0\xff\xff\xff\xffˈ\xe2`\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\xff\xff\xff\xff\xd3u\xd6\xe0\xff\xff\xff\xff\xd4@\xcf\xd0\xff\xff\xff\xff\xd5U" +
+	"\xb8\xe0\xff\xff\xff\xff\xd6 \xb1\xd0\xff\xff\xff\xff\xd75\x9a\xe0\xff\xff\xff\xff\xd8\x00\x93\xd0\xff\xff\xff\xff\xd9\x15|\xe0\xff\xff\xff\xff\xd9\xe0u\xd0\xff\xff\xff\xff\xdc\xde{`\xff\xff\xff\xffݩtP\xff\xff" +
+	"\xff\xff\u07be]`\xff\xff\xff\xff߉VP\xff\xff\xff\xff\xe0\x9e?`\xff\xff\xff\xff\xe1i8P\xff\xff\xff\xff\xe2~!`\xff\xff\xff\xff\xe3I\x1aP\xff\xff\xff\xff\xe6G\x1f\xe0\xff\xff\xff\xff\xe7\x12" +
+	"\x18\xd0\xff\xff\xff\xff\xe8'\x01\xe0\xff\xff\xff\xff\xe8\xf1\xfa\xd0\xff\xff\xff\xff\xea\x06\xe3\xe0\xff\xff\xff\xff\xea\xd1\xdc\xd0\xff\xff\xff\xff\xeb\xe6\xc5\xe0\xff\xff\xff\xff챾\xd0\xff\xff\xff\xff\xf1\x8f\xa6`\xff\xff" +
+	"\xff\xff\xf2\x7f\x89P\xff\xff\xff\xff\xf3o\x88`\xff\xff\xff\xff\xf4_kP\xff\xff\xff\xff\xf5Oj`\xff\xff\xff\xff\xf6?MP\xff\xff\xff\xff\xf7/L`\xff\xff\xff\xff\xf8(i\xd0\xff\xff\xff\xff\xf9\x0f" +
+	".`\xff\xff\xff\xff\xfa\bK\xd0\xff\xff\xff\xff\xfa\xf8J\xe0\xff\xff\xff\xff\xfb\xe8-\xd0\xff\xff\xff\xff\xfc\xd8,\xe0\xff\xff\xff\xff\xfd\xc8\x0f\xd0\xff\xff\xff\xff\xfe\xb8\x0e\xe0\xff\xff\xff\xff\xff\xa7\xf1\xd0\x00\x00" +
+	"\x00\x00\x00\x97\xf0\xe0\x00\x00\x00\x00\x01\x87\xd3\xd0\x00\x00\x00\x00\x02w\xd2\xe0\x00\x00\x00\x00\x03p\xf0P\x00\x00\x00\x00\x04`\xef`\x00\x00\x00\x00\x05P\xd2P\x00\x00\x00\x00\x06@\xd1`\x00\x00\x00\x00\a0" +
+	"\xb4P\x00\x00\x00\x00\b \xb3`\x00\x00\x00\x00\t\x10\x96P\x00\x00\x00\x00\n\x00\x95`\x00\x00\x00\x00\n\xf0xP\x00\x00\x00\x00\v\xe0w`\x00\x00\x00\x00\fٔ\xd0\x00\x00\x00\x00\r\xc0Y`\x00\x00" +
+	"\x00\x00\x0e\xb9v\xd0\x00\x00\x00\x00\x0f\xa9u\xe0\x00\x00\x00\x00\x10\x99X\xd0\x00\x00\x00\x00\x11\x89W\xe0\x00\x00\x00\x00\x12y:\xd0\x00\x00\x00\x00\x13i9\xe0\x00\x00\x00\x00\x14Y\x1c\xd0\x00\x00\x00\x00\x15I" +
+	"\x1b\xe0\x00\x00\x00\x00\x168\xfe\xd0\x00\x00\x00\x00\x17(\xfd\xe0\x00\x00\x00\x00\x18\"\x1bP\x00\x00\x00\x00\x19\b\xdf\xe0\x00\x00\x00\x00\x1a\x01\xfdP\x00\x00\x00\x00\x1a\xf1\xfc`\x00\x00\x00\x00\x1b\xe1\xdfP\x00\x00" +
+	"\x00\x00\x1c\xd1\xde`\x00\x00\x00\x00\x1d\xc1\xc1P\x00\x00\x00\x00\x1e\xb1\xc0`\x00\x00\x00\x00\x1f\xa1\xa3P\x00\x00\x00\x00 u\xf2\xe0\x00\x00\x00\x00!\x81\x85P\x00\x00\x00\x00\"U\xd4\xe0\x00\x00\x00\x00#j" +
+	"\xa1\xd0\x00\x00\x00\x00$5\xb6\xe0\x00\x00\x00\x00%J\x83\xd0\x00\x00\x00\x00&\x15\x98\xe0\x00\x00\x00\x00'*e\xd0\x00\x00\x00\x00'\xfe\xb5`\x00\x00\x00\x00)\nG\xd0\x00\x00\x00\x00)ޗ`\x00\x00" +
+	"\x00\x00*\xea)\xd0\x00\x00\x00\x00+\xbey`\x00\x00\x00\x00,\xd3FP\x00\x00\x00\x00-\x9e[`\x00\x00\x00\x00.\xb3(P\x00\x00\x00\x00/~=`\x00\x00\x00\x000\x93\nP\x00\x00\x00\x001g" +
+	"Y\xe0\x00\x00\x00\x002r\xecP\x00\x00\x00\x003G;\xe0\x00\x00\x00\x004R\xceP\x00\x00\x00\x005'\x1d\xe0\x00\x00\x00\x0062\xb0P\x00\x00\x00\x007\x06\xff\xe0\x00\x00\x00\x008\x1b\xcc\xd0\x00\x00" +
+	"\x00\x008\xe6\xe1\xe0\x00\x00\x00\x009\xfb\xae\xd0\x00\x00\x00\x00:\xc6\xc3\xe0\x00\x00\x00\x00;ې\xd0\x00\x00\x00\x00<\xaf\xe0`\x00\x00\x00\x00=\xbbr\xd0\x00\x00\x00\x00>\x8f\xc2`\x00\x00\x00\x00?\x9b" +
+	"T\xd0\x00\x00\x00\x00@o\xa4`\x00\x00\x00\x00A\x84qP\x00\x00\x00\x00BO\x86`\x00\x00\x00\x00CdSP\x00\x00\x00\x00D/h`\x00\x00\x00\x00ED5P\x00\x00\x00\x00E\xf3\x9a\xe0\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xc4`\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7" +
+	"\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xd5\xd0\x01\x10LMT\x00ADT\x00AST\x00AWT\x00APT\x00\nAST4ADT,M3.2.0,M11.1.0\nP" +
+	"K\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?_p\x99\x0e\x05\x00\x00\x0e\x05\x00\x00\x0e\x00\x00\x00Canada/CentralTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00}\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xffd䰔\xff\xff\xff\xff\x9b\x01\xfb\xe0\xff\xff\xff\xff\x9búP\xff\xff\xff\xff\x9e\xb8\xa1\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff" +
+	"\xff\xff\u00a0;\x80\xff\xff\xff\xff\xc3O\x84\xf0\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xffӈh\x00\xff\xff\xff\xff\xd4S`\xf0\xff\xff\xff\xff\xd5U" +
+	"\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xdb\x00\a\x00\xff\xff\xff\xff\xdb\xc8\\\xf0\xff\xff" +
+	"\xff\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90p\xff\xff\xff\xff\u07bey\x80\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I" +
+	"6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5)\x18p\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe7\x124\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff" +
+	"\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xd6\xc4\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\ue47c\xf0\xff\xff\xff\xff\xf3o\xa4\x80\xff\xff\xff\xff\xf41b\xf0\xff\xff\xff\xff\xf9\x0f" +
+	"J\x80\xff\xff\xff\xff\xfa\bv\x00\xff\xff\xff\xff\xfa\xf8g\x00\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00" +
+	"\x00\x00\x00\x98\r\x00\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\v\x80\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\a0" +
+	"ހ\x00\x00\x00\x00\b π\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\n\x00\xb1\x80\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0u\x80\x00\x00" +
+	"\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15I" +
+	"8\x00\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00" +
+	"\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1܀\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j" +
+	"\xcc\x00\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\u07b3\x80\x00\x00" +
+	"\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g" +
+	"v\x00\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005':\x00\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xf7\x00\x00\x00" +
+	"\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9b" +
+	"\x7f\x00\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01" +
+	"\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\xff\xff\xa4\xec\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10LMT\x00CDT\x00CST\x00CWT\x00CPT\x00\nCST6CD" +
+	"T,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ӿ\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00\x0e\x00\x00\x00Canada/Easter" +
+	"nTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xffr\xeex\xec\xff\xff\xff\xff\x9e\xb8\x93p\xff\xff\xff\xff\x9f\xba\xeb`" +
+	"\xff\xff\xff\xff\xa0\x87.\xc8\xff\xff\xff\xff\xa1\x9a\xb1@\xff\xff\xff\xff\xa2\x94\x06\xf0\xff\xff\xff\xff\xa3U\xa9@\xff\xff\xff\xff\xa4\x86]\xf0\xff\xff\xff\xff\xa5(x`\xff\xff\xff\xff\xa6f?\xf0\xff\xff\xff\xff" +
+	"\xa7\fN\xe0\xff\xff\xff\xff\xa8F!\xf0\xff\xff\xff\xff\xa8\xec0\xe0\xff\xff\xff\xff\xaa\x1c\xc9p\xff\xff\xff\xff\xaa\xd5M`\xff\xff\xff\xff\xab\xfc\xabp\xff\xff\xff\xff\xac\xb5/`\xff\xff\xff\xff\xad܍p" +
+	"\xff\xff\xff\xff\xae\x95\x11`\xff\xff\xff\xff\xaf\xbcop\xff\xff\xff\xff\xb0~-\xe0\xff\xff\xff\xff\xb1\x9cQp\xff\xff\xff\xff\xb2gJ`\xff\xff\xff\xff\xb3|3p\xff\xff\xff\xff\xb4G,`\xff\xff\xff\xff" +
+	"\xb5\\\x15p\xff\xff\xff\xff\xb6'\x0e`\xff\xff\xff\xff\xb7;\xf7p\xff\xff\xff\xff\xb8\x06\xf0`\xff\xff\xff\xff\xb9%\x13\xf0\xff\xff\xff\xff\xb9\xe6\xd2`\xff\xff\xff\xff\xbb\x04\xf5\xf0\xff\xff\xff\xff\xbb\xcf\xee\xe0" +
+	"\xff\xff\xff\xff\xbc\xe4\xd7\xf0\xff\xff\xff\xff\xbd\xaf\xd0\xe0\xff\xff\xff\xff\xbeĹ\xf0\xff\xff\xff\xff\xbf\x8f\xb2\xe0\xff\xff\xff\xff\xc0\xa4\x9b\xf0\xff\xff\xff\xff\xc1o\x94\xe0\xff\xff\xff\xff\u0084}\xf0\xff\xff\xff\xff" +
+	"\xc3Ov\xe0\xff\xff\xff\xff\xc4d_\xf0\xff\xff\xff\xff\xc5/X\xe0\xff\xff\xff\xff\xc6M|p\xff\xff\xff\xff\xc7\x0f:\xe0\xff\xff\xff\xff\xc8-^p\xff\xff\xff\xffˈ\xf0p\xff\xff\xff\xff\xd2#\xf4p" +
+	"\xff\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff\xd3u\xe4\xf0\xff\xff\xff\xff\xd4@\xdd\xe0\xff\xff\xff\xff\xd5U\xaa\xd0\xff\xff\xff\xff\xd6 \xa3\xc0\xff\xff\xff\xff\xd75\x8c\xd0\xff\xff\xff\xff\xd8\x00\x85\xc0\xff\xff\xff\xff" +
+	"\xd9\x15n\xd0\xff\xff\xff\xff\xda3v@\xff\xff\xff\xff\xda\xfe\xa7p\xff\xff\xff\xff\xdc\x13t`\xff\xff\xff\xff\xdcމp\xff\xff\xff\xffݩ\x82`\xff\xff\xff\xff\u07bekp\xff\xff\xff\xff߉d`" +
+	"\xff\xff\xff\xff\xe0\x9eMp\xff\xff\xff\xff\xe1iF`\xff\xff\xff\xff\xe2~/p\xff\xff\xff\xff\xe3I(`\xff\xff\xff\xff\xe4^\x11p\xff\xff\xff\xff\xe5)\n`\xff\xff\xff\xff\xe6G-\xf0\xff\xff\xff\xff" +
+	"\xe7\x12&\xe0\xff\xff\xff\xff\xe8'\x0f\xf0\xff\xff\xff\xff\xe9\x16\xf2\xe0\xff\xff\xff\xff\xea\x06\xf1\xf0\xff\xff\xff\xff\xea\xf6\xd4\xe0\xff\xff\xff\xff\xeb\xe6\xd3\xf0\xff\xff\xff\xff\xecֶ\xe0\xff\xff\xff\xff\xedƵ\xf0" +
+	"\xff\xff\xff\xff\xee\xbf\xd3`\xff\xff\xff\xff\xef\xaf\xd2p\xff\xff\xff\xff\xf0\x9f\xb5`\xff\xff\xff\xff\xf1\x8f\xb4p\xff\xff\xff\xff\xf2\x7f\x97`\xff\xff\xff\xff\xf3o\x96p\xff\xff\xff\xff\xf4_y`\xff\xff\xff\xff" +
+	"\xf5Oxp\xff\xff\xff\xff\xf6?[`\xff\xff\xff\xff\xf7/Zp\xff\xff\xff\xff\xf8(w\xe0\xff\xff\xff\xff\xf9\x0f<p\xff\xff\xff\xff\xfa\bY\xe0\xff\xff\xff\xff\xfa\xf8X\xf0\xff\xff\xff\xff\xfb\xe8;\xe0" +
+	"\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00" +
+	"\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\a0\xc2`\x00\x00\x00\x00\b \xc1p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\n\x00\xa3p" +
+	"\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00\f٢\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00" +
+	"\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`" +
+	"\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x00\x00\x00\x00\x1a\xf2\np\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00" +
+	"\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\"U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0" +
+	"\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\nU\xe0\x00\x00\x00\x00)ޥp\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00" +
+	"-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`" +
+	"\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\a\r\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00" +
+	";۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p" +
+	"\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xb5\x94\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\f\xff\xff\xc7\xc0\x01\x10LMT\x00ED" +
+	"T\x00EST\x00EWT\x00EPT\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{\a\a\xdc\xca\x03\x00\x00" +
+	"\xca\x03\x00\x00\x0f\x00\x00\x00Canada/MountainTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff" +
+	"\xff\xff\x88\xde\xce\xe0\xff\xff\xff\xff\x9e\xb8\xaf\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x98\x91\x90\xff\xff\xff\xff\xa0҅\x80\xff\xff\xff\xff\xa2\x8a\xe8\x90\xff\xff\xff\xff\xa3\x84\x06\x00\xff\xff\xff\xff\xa4j" +
+	"ʐ\xff\xff\xff\xff\xa55À\xff\xff\xff\xff\xa6S\xe7\x10\xff\xff\xff\xff\xa7\x15\xa5\x80\xff\xff\xff\xff\xa83\xc9\x10\xff\xff\xff\xff\xa8\xfe\xc2\x00\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff" +
+	"\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xd5U\xe3\x10\xff\xff\xff\xff\xd6 \xdc\x00\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\b " +
+	"ݐ\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\n\x00\xbf\x90\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\vࡐ\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00" +
+	"\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169" +
+	")\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00" +
+	"\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5" +
+	"\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeߐ\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00" +
+	"\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s" +
+	"\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00" +
+	"\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@o" +
+	"ΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\x95\xa0\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10LMT\x00MDT\x00MST" +
+	"\x00MWT\x00MPT\x00\nMST7MDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00~\xb2\x0e\x19V\a\x00\x00V\a\x00\x00\x13" +
+	"\x00\x00\x00Canada/NewfoundlandTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbb\x00\x00\x00\b\x00\x00\x00\x19\xff\xff\xff" +
+	"\xff^=4\xec\xff\xff\xff\xff\x9c\xcfb\f\xff\xff\xff\xff\x9d\xa4\xe6\xfc\xff\xff\xff\xff\x9e\xb8~\x8c\xff\xff\xff\xff\x9f\xba\xd6|\xff\xff\xff\xff\xa0\xb6\x88\xdc\xff\xff\xff\xff\xa18\xffL\xff\xff\xff\xff\xa2\x95\x19" +
+	"\\\xff\xff\xff\xff\xa3\x84\xfcL\xff\xff\xff\xff\xa4t\xfb\\\xff\xff\xff\xff\xa5d\xdeL\xff\xff\xff\xff\xa6^\x17\xdc\xff\xff\xff\xff\xa7D\xc0L\xff\xff\xff\xff\xa8=\xf9\xdc\xff\xff\xff\xff\xa9$\xa2L\xff\xff\xff" +
+	"\xff\xaa\x1d\xdb\xdc\xff\xff\xff\xff\xab\x04\x84L\xff\xff\xff\xff\xab\xfd\xbd\xdc\xff\xff\xff\xff\xac\xe4fL\xff\xff\xff\xff\xadݟ\xdc\xff\xff\xff\xff\xae͂\xcc\xff\xff\xff\xff\xaf\xbd\x81\xdc\xff\xff\xff\xff\xb0\xadd" +
+	"\xcc\xff\xff\xff\xff\xb1\xa6\x9e\\\xff\xff\xff\xff\xb2\x8dF\xcc\xff\xff\xff\xff\xb3\x86\x80\\\xff\xff\xff\xff\xb4m(\xcc\xff\xff\xff\xff\xb5fb\\\xff\xff\xff\xff\xb6M\n\xcc\xff\xff\xff\xff\xb7FD\\\xff\xff\xff" +
+	"\xff\xb8,\xec\xcc\xff\xff\xff\xff\xb9&&\\\xff\xff\xff\xff\xba\x16\tL\xff\xff\xff\xff\xbb\x0fB\xdc\xff\xff\xff\xff\xbb\xf5\xebL\xff\xff\xff\xff\xbc\xef$\xdc\xff\xff\xff\xff\xbd\xd5\xcdL\xff\xff\xff\xff\xbe\x9eM" +
+	"l\xff\xff\xff\xff\xbe\xcf\x06\xa8\xff\xff\xff\xff\xbf\xb5\xaf\x18\xff\xff\xff\xff\xc0\xb818\xff\xff\xff\xff\xc1y\xef\xa8\xff\xff\xff\xff\u0098\x138\xff\xff\xff\xff\xc3YѨ\xff\xff\xff\xff\xc4w\xf58\xff\xff\xff" +
+	"\xff\xc59\xb3\xa8\xff\xff\xff\xff\xc6a\x11\xb8\xff\xff\xff\xff\xc7\x19\x95\xa8\xff\xff\xff\xff\xc8@\xf3\xb8\xff\xff\xff\xff\xc9\x02\xb2(\xff\xff\xff\xff\xca ո\xff\xff\xff\xff\xca\xe2\x94(\xff\xff\xff\xff\xcc\x00\xb7" +
+	"\xb8\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xe6\xc8\xff\xff\xff\xffӈD\xd8\xff\xff\xff\xff\xd4J\x03H\xff\xff\xff\xff\xd5h&\xd8\xff\xff\xff\xff\xd6)\xe5H\xff\xff\xff\xff\xd7H\b\xd8\xff\xff\xff" +
+	"\xff\xd8\t\xc7H\xff\xff\xff\xff\xd9'\xea\xd8\xff\xff\xff\xff\xd9\xe9\xa9H\xff\xff\xff\xff\xdb\x11\aX\xff\xff\xff\xff\xdb\xd2\xc5\xc8\xff\xff\xff\xff\xdc\xdetX\xff\xff\xff\xffݩmH\xff\xff\xff\xff\u07beV" +
+	"X\xff\xff\xff\xff߉OH\xff\xff\xff\xff\xe0\x9e8X\xff\xff\xff\xff\xe1i1H\xff\xff\xff\xff\xe2~\x1aX\xff\xff\xff\xff\xe3I\x13H\xff\xff\xff\xff\xe4]\xfcX\xff\xff\xff\xff\xe5(\xf5H\xff\xff\xff" +
+	"\xff\xe6G\x18\xd8\xff\xff\xff\xff\xe7\x12\x11\xc8\xff\xff\xff\xff\xe8&\xfa\xd8\xff\xff\xff\xff\xe8\xf1\xf3\xc8\xff\xff\xff\xff\xea\x06\xdc\xd8\xff\xff\xff\xff\xea\xd1\xd5\xc8\xff\xff\xff\xff\xeb\xe6\xbe\xd8\xff\xff\xff\xff챷" +
+	"\xc8\xff\xff\xff\xff\xedƠ\xd8\xff\xff\xff\xff\ueffeH\xff\xff\xff\xffﯽX\xff\xff\xff\xff\xf0\x9f\xa0H\xff\xff\xff\xff\xf1\x8f\x9fX\xff\xff\xff\xff\xf2\x7f\x82H\xff\xff\xff\xff\xf3o\x81X\xff\xff\xff" +
+	"\xff\xf4_dH\xff\xff\xff\xff\xf5OcX\xff\xff\xff\xff\xf6?FH\xff\xff\xff\xff\xf7/EX\xff\xff\xff\xff\xf8(b\xc8\xff\xff\xff\xff\xf9\x0f'X\xff\xff\xff\xff\xfa\bD\xc8\xff\xff\xff\xff\xfa\xf8C" +
+	"\xd8\xff\xff\xff\xff\xfb\xe8&\xc8\xff\xff\xff\xff\xfc\xd8%\xd8\xff\xff\xff\xff\xfd\xc8\b\xc8\xff\xff\xff\xff\xfe\xb8\a\xd8\xff\xff\xff\xff\xff\xa7\xea\xc8\x00\x00\x00\x00\x00\x97\xe9\xd8\x00\x00\x00\x00\x01\x87\xcc\xc8\x00\x00\x00" +
+	"\x00\x02w\xcb\xd8\x00\x00\x00\x00\x03p\xe9H\x00\x00\x00\x00\x04`\xe8X\x00\x00\x00\x00\x05P\xcbH\x00\x00\x00\x00\x06@\xcaX\x00\x00\x00\x00\a0\xadH\x00\x00\x00\x00\b \xacX\x00\x00\x00\x00\t\x10\x8f" +
+	"H\x00\x00\x00\x00\n\x00\x8eX\x00\x00\x00\x00\n\xf0qH\x00\x00\x00\x00\v\xe0pX\x00\x00\x00\x00\fٍ\xc8\x00\x00\x00\x00\r\xc0RX\x00\x00\x00\x00\x0e\xb9o\xc8\x00\x00\x00\x00\x0f\xa9n\xd8\x00\x00\x00" +
+	"\x00\x10\x99Q\xc8\x00\x00\x00\x00\x11\x89P\xd8\x00\x00\x00\x00\x12y3\xc8\x00\x00\x00\x00\x13i2\xd8\x00\x00\x00\x00\x14Y\x15\xc8\x00\x00\x00\x00\x15I\x14\xd8\x00\x00\x00\x00\x168\xf7\xc8\x00\x00\x00\x00\x17(\xf6" +
+	"\xd8\x00\x00\x00\x00\x18\"\x14H\x00\x00\x00\x00\x19\b\xd8\xd8\x00\x00\x00\x00\x1a\x01\xf6H\x00\x00\x00\x00\x1a\xf1\xf5X\x00\x00\x00\x00\x1b\xe1\xd8H\x00\x00\x00\x00\x1c\xd1\xd7X\x00\x00\x00\x00\x1d\xc1\xbaH\x00\x00\x00" +
+	"\x00\x1e\xb1\xb9X\x00\x00\x00\x00\x1f\xa1\x9cH\x00\x00\x00\x00 u\xcf\xf4\x00\x00\x00\x00!\x81bd\x00\x00\x00\x00\"U\xb1\xf4\x00\x00\x00\x00#jp\xd4\x00\x00\x00\x00$5\x93\xf4\x00\x00\x00\x00%J`" +
+	"\xe4\x00\x00\x00\x00&\x15u\xf4\x00\x00\x00\x00'*B\xe4\x00\x00\x00\x00'\xfe\x92t\x00\x00\x00\x00)\n$\xe4\x00\x00\x00\x00)\xdett\x00\x00\x00\x00*\xea\x06\xe4\x00\x00\x00\x00+\xbeVt\x00\x00\x00" +
+	"\x00,\xd3#d\x00\x00\x00\x00-\x9e8t\x00\x00\x00\x00.\xb3\x05d\x00\x00\x00\x00/~\x1at\x00\x00\x00\x000\x92\xe7d\x00\x00\x00\x001g6\xf4\x00\x00\x00\x002r\xc9d\x00\x00\x00\x003G\x18" +
+	"\xf4\x00\x00\x00\x004R\xabd\x00\x00\x00\x005&\xfa\xf4\x00\x00\x00\x0062\x8dd\x00\x00\x00\x007\x06\xdc\xf4\x00\x00\x00\x008\x1b\xa9\xe4\x00\x00\x00\x008\xe6\xbe\xf4\x00\x00\x00\x009\xfb\x8b\xe4\x00\x00\x00" +
+	"\x00:Ơ\xf4\x00\x00\x00\x00;\xdbm\xe4\x00\x00\x00\x00<\xaf\xbdt\x00\x00\x00\x00=\xbbO\xe4\x00\x00\x00\x00>\x8f\x9ft\x00\x00\x00\x00?\x9b1\xe4\x00\x00\x00\x00@o\x81t\x00\x00\x00\x00A\x84N" +
+	"d\x00\x00\x00\x00BOct\x00\x00\x00\x00Cd0d\x00\x00\x00\x00D/Et\x00\x00\x00\x00ED\x12d\x00\x00\x00\x00E\xf3w\xf4\x00\x00\x00\x00G-.\xe4\x00\x00\x00\x00G\xd3Y\xf4\x00\x00\x00" +
+	"\x00I\r\x10\xe4\x00\x00\x00\x00I\xb3;\xf4\x00\x00\x00\x00J\xec\xf2\xe4\x00\x00\x00\x00K\x9cXt\x00\x00\x00\x00L\xd6\x0fd\x00\x00\x00\x00M|:t\x00\x00\x00\x00N\xb6\rH\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x06\x05\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" +
+	"\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" +
+	"\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\a\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" +
+	"\xff\xffΔ\x00\x00\xff\xffܤ\x01\x04\xff\xffΔ\x00\b\xff\xff\xdc\xd8\x01\x04\xff\xff\xce\xc8\x00\b\xff\xff\xdc\xd8\x01\f\xff\xff\xdc\xd8\x01\x10\xff\xff\xea\xe8\x01\x14LMT\x00NDT\x00NST\x00" +
+	"NPT\x00NWT\x00NDDT\x00\nNST3:30NDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00U9#\xbe2\x05" +
+	"\x00\x002\x05\x00\x00\x0e\x00\x00\x00Canada/PacificTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x00\x00\x00\x05\x00\x00\x00\x14\xff" +
+	"\xff\xff\xff^=v\xec\xff\xff\xff\xff\x9e\xb8\xbd\xa0\xff\xff\xff\xff\x9f\xbb\x15\x90\xff\xff\xff\xffˉ\x1a\xa0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a&\x10\xff\xff\xff\xff\xd3v\x0f \xff\xff\xff\xff\xd4" +
+	"A\b\x10\xff\xff\xff\xff\xd5U\xf1 \xff\xff\xff\xff\xd6 \xea\x10\xff\xff\xff\xff\xd75\xd3 \xff\xff\xff\xff\xd8\x00\xcc\x10\xff\xff\xff\xff\xd9\x15\xb5 \xff\xff\xff\xff\xd9\xe0\xae\x10\xff\xff\xff\xff\xda\xfeѠ\xff" +
+	"\xff\xff\xff\xdb\xc0\x90\x10\xff\xff\xff\xff\xdc\u07b3\xa0\xff\xff\xff\xffݩ\xac\x90\xff\xff\xff\xff\u07be\x95\xa0\xff\xff\xff\xff߉\x8e\x90\xff\xff\xff\xff\xe0\x9ew\xa0\xff\xff\xff\xff\xe1ip\x90\xff\xff\xff\xff\xe2" +
+	"~Y\xa0\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4^;\xa0\xff\xff\xff\xff\xe5)4\x90\xff\xff\xff\xff\xe6GX \xff\xff\xff\xff\xe7\x12Q\x10\xff\xff\xff\xff\xe8': \xff\xff\xff\xff\xe8\xf23\x10\xff" +
+	"\xff\xff\xff\xea\a\x1c \xff\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff\xff\xeb\xe6\xfe \xff\xff\xff\xff\xec\xb1\xf7\x10\xff\xff\xff\xff\xed\xc6\xe0 \xff\xff\xff\xff\xee\x91\xd9\x10\xff\xff\xff\xff\xef\xaf\xfc\xa0\xff\xff\xff\xff\xf0" +
+	"q\xbb\x10\xff\xff\xff\xff\xf1\x8fޠ\xff\xff\xff\xff\xf2\x7f\xc1\x90\xff\xff\xff\xff\xf3o\xc0\xa0\xff\xff\xff\xff\xf4_\xa3\x90\xff\xff\xff\xff\xf5O\xa2\xa0\xff\xff\xff\xff\xf6?\x85\x90\xff\xff\xff\xff\xf7/\x84\xa0\xff" +
+	"\xff\xff\xff\xf8(\xa2\x10\xff\xff\xff\xff\xf9\x0ff\xa0\xff\xff\xff\xff\xfa\b\x84\x10\xff\xff\xff\xff\xfa\xf8\x83 \xff\xff\xff\xff\xfb\xe8f\x10\xff\xff\xff\xff\xfc\xd8e \xff\xff\xff\xff\xfd\xc8H\x10\xff\xff\xff\xff\xfe" +
+	"\xb8G \xff\xff\xff\xff\xff\xa8*\x10\x00\x00\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88\f\x10\x00\x00\x00\x00\x02x\v \x00\x00\x00\x00\x03q(\x90\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05Q\n\x90\x00" +
+	"\x00\x00\x00\x06A\t\xa0\x00\x00\x00\x00\a0\xec\x90\x00\x00\x00\x00\b \xeb\xa0\x00\x00\x00\x00\t\x10ΐ\x00\x00\x00\x00\n\x00͠\x00\x00\x00\x00\n\xf0\xb0\x90\x00\x00\x00\x00\v\u0be0\x00\x00\x00\x00\f" +
+	"\xd9\xcd\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00" +
+	"\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a" +
+	"\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1ې\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00" +
+	"\x00\x00\x00\"V\r \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)" +
+	"\n\x80\x10\x00\x00\x00\x00)\xdeϠ\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00" +
+	"\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007" +
+	"\a8 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00" +
+	"\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00E" +
+	"Dm\x90\x00\x00\x00\x00E\xf3\xd3 \x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\x8c\x94\x00\x00\xff\xff\x9d\x90\x01\x04\xff\xff\x8f\x80\x00\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10LMT\x00PDT\x00PS" +
+	"T\x00PWT\x00PPT\x00\nPST8PDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\u0096dK~\x02\x00\x00~\x02\x00\x00" +
+	"\x13\x00\x00\x00Canada/SaskatchewanTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff" +
+	"\xff\xff\x86\xfd\x93\x1c\xff\xff\xff\xff\x9e\xb8\xaf\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xb5eO\xf0\xff\xff\xff\xff\xb60H\xe0\xff\xff\xff\xff\xb7E1\xf0\xff\xff\xff\xff\xb8\x10*\xe0\xff\xff\xff\xff\xb9%" +
+	"\x13\xf0\xff\xff\xff\xff\xb9\xf0\f\xe0\xff\xff\xff\xff\xbb\x0e0p\xff\xff\xff\xff\xbb\xcf\xee\xe0\xff\xff\xff\xff\xbc\xee\x12p\xff\xff\xff\xff\xbd\xb9\v`\xff\xff\xff\xff\xc2r\b\xf0\xff\xff\xff\xff\xc3a\xeb\xe0\xff\xff" +
+	"\xff\xff\xc4Q\xea\xf0\xff\xff\xff\xff\xc58\x93`\xff\xff\xff\xff\xc61\xcc\xf0\xff\xff\xff\xff\xc7!\xaf\xe0\xff\xff\xff\xff\xc8\x1a\xe9p\xff\xff\xff\xff\xc9\n\xcc`\xff\xff\xff\xff\xc9\xfa\xcbp\xff\xff\xff\xff\xca\xea" +
+	"\xae`\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xd3c\x8c\x10\xff\xff\xff\xff\xd4So\x00\xff\xff\xff\xff\xd5U\xe3\x10\xff\xff\xff\xff\xd6 \xdc\x00\xff\xff" +
+	"\xff\xff\xd75\xc5\x10\xff\xff\xff\xff\xd8\x00\xbe\x00\xff\xff\xff\xff\xd9\x15\xa7\x10\xff\xff\xff\xff\xd9\xe0\xa0\x00\xff\xff\xff\xff\xda\xfeÐ\xff\xff\xff\xff\xdb\xc0\x82\x00\xff\xff\xff\xff\xdcޥ\x90\xff\xff\xff\xffݩ" +
+	"\x9e\x80\xff\xff\xff\xff\u07be\x87\x90\xff\xff\xff\xff߉\x80\x80\xff\xff\xff\xff\xe0\x9ei\x90\xff\xff\xff\xff\xe1ib\x80\xff\xff\xff\xff\xe2~K\x90\xff\xff\xff\xff\xe3ID\x80\xff\xff\xff\xff\xe4^-\x90\xff\xff" +
+	"\xff\xff\xe5)&\x80\xff\xff\xff\xff\xe6GJ\x10\xff\xff\xff\xff\xe7\x12C\x00\xff\xff\xff\xff\xe8',\x10\xff\xff\xff\xff\xe8\xf2%\x00\xff\xff\xff\xff\xeb\xe6\xf0\x10\xff\xff\xff\xff\xec\xd6\xd3\x00\xff\xff\xff\xff\xed\xc6" +
+	"\xd2\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\xff\xff\x9d\xe4\x00" +
+	"\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10\xff\xff\xab\xa0\x00\x14LMT\x00MDT\x00MST\x00MWT\x00MPT\x00CST\x00\nCST6" +
+	"\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbf\x1d\xee\x91\x05\x04\x00\x00\x05\x04\x00\x00\f\x00\x00\x00Canada/YukonTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00]\x00\x00\x00\t\x00\x00\x00%\xff\xff\xff\xff}\x86\x8a\x9c\xff\xff\xff\xff\x9e\xb8˰\xff\xff\xff\xff\x9f\xbb#\xa0\xff\xff\xff\xff\xa0\xd0\f\xb0\xff\xff\xff\xff\xa1\xa2Ҁ\xff\xff" +
+	"\xff\xffˉ(\xb0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a4 \xff\xff\xff\xff\xf7/v\x90\xff\xff\xff\xff\xf8(\xa2\x10\xff\xff\xff\xff\xf8ń\x90\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14Y" +
+	"U\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00" +
+	"\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1ې\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\"V" +
+	"\r \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\n\x80\x10\x00\x00" +
+	"\x00\x00)\xdeϠ\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93" +
+	"B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\a8 \x00\x00" +
+	"\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f" +
+	"\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00" +
+	"\x00\x00E\xf3\xd3 \x00\x00\x00\x00G-\x8a\x10\x00\x00\x00\x00Gӵ \x00\x00\x00\x00I\rl\x10\x00\x00\x00\x00I\xb3\x97 \x00\x00\x00\x00J\xedN\x10\x00\x00\x00\x00K\x9c\xb3\xa0\x00\x00\x00\x00L\xd6" +
+	"j\x90\x00\x00\x00\x00M|\x95\xa0\x00\x00\x00\x00N\xb6L\x90\x00\x00\x00\x00O\\w\xa0\x00\x00\x00\x00P\x96.\x90\x00\x00\x00\x00Q<Y\xa0\x00\x00\x00\x00Rv\x10\x90\x00\x00\x00\x00S\x1c;\xa0\x00\x00" +
+	"\x00\x00TU\xf2\x90\x00\x00\x00\x00T\xfc\x1d\xa0\x00\x00\x00\x00V5Ԑ\x00\x00\x00\x00V\xe5: \x00\x00\x00\x00X\x1e\xf1\x10\x00\x00\x00\x00X\xc5\x1c \x00\x00\x00\x00Y\xfe\xd3\x10\x00\x00\x00\x00Z\xa4" +
+	"\xfe \x00\x00\x00\x00[\u07b5\x10\x00\x00\x00\x00\\\x84\xe0 \x00\x00\x00\x00]\xbe\x97\x10\x00\x00\x00\x00^d\xc2 \x00\x00\x00\x00_\x9e\\\xf0\x02\x01\x02\x01\x02\x03\x04\x02\x05\x02\x06\a\x06\a\x06\a\x06\a" +
+	"\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a" +
+	"\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\b\xff\xff\x81d\x00\x00\xff\xff\x8f\x80\x01\x04\xff\xff\x81p\x00\b\xff\xff\x8f\x80\x01\f\xff\xff\x8f\x80\x01\x10\xff\xff\x9d\x90\x01\x14\xff\xff\x8f\x80\x00\x19\xff\xff\x9d" +
+	"\x90\x01\x1d\xff\xff\x9d\x90\x00!LMT\x00YDT\x00YST\x00YWT\x00YPT\x00YDDT\x00PST\x00PDT\x00MST\x00\nMST7\nPK\x03\x04\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00]\"_WJ\x05\x00\x00J\x05\x00\x00\x11\x00\x00\x00Chile/ContinentalTZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x82\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffi\x87\x1d\xc5\xff\xff\xff\xff\x8f0GE\xff\xff\xff\xff\x9b\\\xe5P\xff\xff\xff\xff\x9f|\xe2\xc5\xff\xff\xff\xff\xa1\x00q\xc0\xff\xff\xff\xff\xb0^" +
+	"w\xc5\xff\xff\xff\xff\xb1w=@\xff\xff\xff\xff\xb2A\x00\xd0\xff\xff\xff\xff\xb3Xp\xc0\xff\xff\xff\xff\xb4\"4P\xff\xff\xff\xff\xb59\xa4@\xff\xff\xff\xff\xb6\x03g\xd0\xff\xff\xff\xff\xb7\x1a\xd7\xc0\xff\xff" +
+	"\xff\xff\xb7\xe4\x9bP\xff\xff\xff\xff\xb8\xfd\\\xc0\xff\xff\xff\xff\xb9\xc7 P\xff\xff\xff\xff\xcc\x1cn@\xff\xff\xff\xff\xccl\xe7\xd0\xff\xff\xff\xff\xd3\u070f\xc0\xff\xff\xff\xff\xd4\x17\xd50\xff\xff\xff\xff\xd53" +
+	"U\xc0\xff\xff\xff\xff\xd5v\x92@\xff\xff\xff\xff\xfd\xd1<@\xff\xff\xff\xff\xfe\x92\xfa\xb0\xff\xff\xff\xff\xff\xcc\xcd\xc0\x00\x00\x00\x00\x00rܰ\x00\x00\x00\x00\x01uP\xc0\x00\x00\x00\x00\x02@I\xb0\x00\x00" +
+	"\x00\x00\x03U2\xc0\x00\x00\x00\x00\x04 +\xb0\x00\x00\x00\x00\x05>O@\x00\x00\x00\x00\x06\x00\r\xb0\x00\x00\x00\x00\a\v\xbc@\x00\x00\x00\x00\a\xdf\xef\xb0\x00\x00\x00\x00\b\xfe\x13@\x00\x00\x00\x00\t\xbf" +
+	"Ѱ\x00\x00\x00\x00\n\xdd\xf5@\x00\x00\x00\x00\v\xa8\xee0\x00\x00\x00\x00\f\xbd\xd7@\x00\x00\x00\x00\r\x88\xd00\x00\x00\x00\x00\x0e\x9d\xb9@\x00\x00\x00\x00\x0fh\xb20\x00\x00\x00\x00\x10\x86\xd5\xc0\x00\x00" +
+	"\x00\x00\x11H\x940\x00\x00\x00\x00\x12f\xb7\xc0\x00\x00\x00\x00\x13(v0\x00\x00\x00\x00\x14F\x99\xc0\x00\x00\x00\x00\x15\x11\x92\xb0\x00\x00\x00\x00\x16&{\xc0\x00\x00\x00\x00\x16\xf1t\xb0\x00\x00\x00\x00\x18\x06" +
+	"]\xc0\x00\x00\x00\x00\x18\xd1V\xb0\x00\x00\x00\x00\x19\xe6?\xc0\x00\x00\x00\x00\x1a\xb18\xb0\x00\x00\x00\x00\x1b\xcf\\@\x00\x00\x00\x00\x1c\x91\x1a\xb0\x00\x00\x00\x00\x1d\xaf>@\x00\x00\x00\x00\x1ep\xfc\xb0\x00\x00" +
+	"\x00\x00\x1f\x8f @\x00\x00\x00\x00 \x7f\x030\x00\x00\x00\x00!o\x02@\x00\x00\x00\x00\"9\xfb0\x00\x00\x00\x00#N\xe4@\x00\x00\x00\x00$\x19\xdd0\x00\x00\x00\x00%8\x00\xc0\x00\x00\x00\x00%\xf9" +
+	"\xbf0\x00\x00\x00\x00&\xf2\xf8\xc0\x00\x00\x00\x00'١0\x00\x00\x00\x00(\xf7\xc4\xc0\x00\x00\x00\x00)½\xb0\x00\x00\x00\x00*צ\xc0\x00\x00\x00\x00+\xa2\x9f\xb0\x00\x00\x00\x00,\xb7\x88\xc0\x00\x00" +
+	"\x00\x00-\x82\x81\xb0\x00\x00\x00\x00.\x97j\xc0\x00\x00\x00\x00/bc\xb0\x00\x00\x00\x000\x80\x87@\x00\x00\x00\x001BE\xb0\x00\x00\x00\x002`i@\x00\x00\x00\x003=\xd70\x00\x00\x00\x004@" +
+	"K@\x00\x00\x00\x005\vD0\x00\x00\x00\x006\r\xb8@\x00\x00\x00\x007\x06հ\x00\x00\x00\x008\x00\x0f@\x00\x00\x00\x008\xcb\b0\x00\x00\x00\x009\xe9+\xc0\x00\x00\x00\x00:\xaa\xea0\x00\x00" +
+	"\x00\x00;\xc9\r\xc0\x00\x00\x00\x00<\x8a\xcc0\x00\x00\x00\x00=\xa8\xef\xc0\x00\x00\x00\x00>j\xae0\x00\x00\x00\x00?\x88\xd1\xc0\x00\x00\x00\x00@Sʰ\x00\x00\x00\x00Ah\xb3\xc0\x00\x00\x00\x00B3" +
+	"\xac\xb0\x00\x00\x00\x00CH\x95\xc0\x00\x00\x00\x00D\x13\x8e\xb0\x00\x00\x00\x00E1\xb2@\x00\x00\x00\x00E\xf3p\xb0\x00\x00\x00\x00G\x11\x94@\x00\x00\x00\x00G\xef\x020\x00\x00\x00\x00H\xf1v@\x00\x00" +
+	"\x00\x00I\xbco0\x00\x00\x00\x00J\xd1X@\x00\x00\x00\x00K\xb8\x00\xb0\x00\x00\x00\x00L\xb1:@\x00\x00\x00\x00M\xc6\a0\x00\x00\x00\x00NP\x82\xc0\x00\x00\x00\x00O\x9c\xae\xb0\x00\x00\x00\x00PB" +
+	"\xd9\xc0\x00\x00\x00\x00Q|\x90\xb0\x00\x00\x00\x00R+\xf6@\x00\x00\x00\x00S\\r\xb0\x00\x00\x00\x00T\v\xd8@\x00\x00\x00\x00W7\xe60\x00\x00\x00\x00W\xaf\xec\xc0\x00\x00\x00\x00Y\x17\xc80\x00\x00" +
+	"\x00\x00Y\x8f\xce\xc0\x00\x00\x00\x00Z\xf7\xaa0\x00\x00\x00\x00[o\xb0\xc0\x00\x00\x00\x00\\\xa9g\xb0\x00\x00\x00\x00]t|\xc0\x00\x00\x00\x00^\x89I\xb0\x00\x00\x00\x00_T^\xc0\x00\x00\x00\x00`i" +
+	"+\xb0\x00\x00\x00\x00a4@\xc0\x00\x00\x00\x00bI\r\xb0\x00\x00\x00\x00c\x1d]@\x00\x00\x00\x00d(\xef\xb0\x01\x02\x01\x03\x01\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x03\x02\x03\x05\x04\x02\x03\x05\x03\x05\x03" +
+	"\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03" +
+	"\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\xff\xff\xbd\xbb\x00\x00\xff\xff\xbd\xbb\x00\x04\xff\xff\xb9\xb0" +
+	"\x00\b\xff\xff\xc7\xc0\x00\f\xff\xff\xc7\xc0\x01\f\xff\xff\xd5\xd0\x01\x10LMT\x00SMT\x00-05\x00-04\x00-03\x00\n<-04>4<-03>,M9.1.6/" +
+	"24,M4.1.6/24\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?X'\x8e\x96\x04\x00\x00\x96\x04\x00\x00\x12\x00\x00\x00Chile/EasterIslan" +
+	"dTZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif3\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffi\x87B\b\xff\xff\xff\xff\xb9\xc7@\x88\xff\xff\xff\xff\xfd\xd1<@" +
+	"\xff\xff\xff\xff\xfe\x92\xfa\xb0\xff\xff\xff\xff\xff\xcc\xcd\xc0\x00\x00\x00\x00\x00rܰ\x00\x00\x00\x00\x01uP\xc0\x00\x00\x00\x00\x02@I\xb0\x00\x00\x00\x00\x03U2\xc0\x00\x00\x00\x00\x04 +\xb0\x00\x00\x00\x00" +
+	"\x05>O@\x00\x00\x00\x00\x06\x00\r\xb0\x00\x00\x00\x00\a\v\xbc@\x00\x00\x00\x00\a\xdf\xef\xb0\x00\x00\x00\x00\b\xfe\x13@\x00\x00\x00\x00\t\xbfѰ\x00\x00\x00\x00\n\xdd\xf5@\x00\x00\x00\x00\v\xa8\xee0" +
+	"\x00\x00\x00\x00\f\xbd\xd7@\x00\x00\x00\x00\r\x88\xd00\x00\x00\x00\x00\x0e\x9d\xb9@\x00\x00\x00\x00\x0fh\xb20\x00\x00\x00\x00\x10\x86\xd5\xc0\x00\x00\x00\x00\x11H\x940\x00\x00\x00\x00\x12f\xb7\xc0\x00\x00\x00\x00" +
+	"\x13(v0\x00\x00\x00\x00\x14F\x99\xc0\x00\x00\x00\x00\x15\x11\x92\xb0\x00\x00\x00\x00\x16&{\xc0\x00\x00\x00\x00\x16\xf1t\xb0\x00\x00\x00\x00\x18\x06]\xc0\x00\x00\x00\x00\x18\xd1V\xb0\x00\x00\x00\x00\x19\xe6?\xc0" +
+	"\x00\x00\x00\x00\x1a\xb18\xb0\x00\x00\x00\x00\x1b\xcf\\@\x00\x00\x00\x00\x1c\x91\x1a\xb0\x00\x00\x00\x00\x1d\xaf>@\x00\x00\x00\x00\x1ep\xfc\xb0\x00\x00\x00\x00\x1f\x8f @\x00\x00\x00\x00 \x7f\x030\x00\x00\x00\x00" +
+	"!o\x02@\x00\x00\x00\x00\"9\xfb0\x00\x00\x00\x00#N\xe4@\x00\x00\x00\x00$\x19\xdd0\x00\x00\x00\x00%8\x00\xc0\x00\x00\x00\x00%\xf9\xbf0\x00\x00\x00\x00&\xf2\xf8\xc0\x00\x00\x00\x00'١0" +
+	"\x00\x00\x00\x00(\xf7\xc4\xc0\x00\x00\x00\x00)½\xb0\x00\x00\x00\x00*צ\xc0\x00\x00\x00\x00+\xa2\x9f\xb0\x00\x00\x00\x00,\xb7\x88\xc0\x00\x00\x00\x00-\x82\x81\xb0\x00\x00\x00\x00.\x97j\xc0\x00\x00\x00\x00" +
+	"/bc\xb0\x00\x00\x00\x000\x80\x87@\x00\x00\x00\x001BE\xb0\x00\x00\x00\x002`i@\x00\x00\x00\x003=\xd70\x00\x00\x00\x004@K@\x00\x00\x00\x005\vD0\x00\x00\x00\x006\r\xb8@" +
+	"\x00\x00\x00\x007\x06հ\x00\x00\x00\x008\x00\x0f@\x00\x00\x00\x008\xcb\b0\x00\x00\x00\x009\xe9+\xc0\x00\x00\x00\x00:\xaa\xea0\x00\x00\x00\x00;\xc9\r\xc0\x00\x00\x00\x00<\x8a\xcc0\x00\x00\x00\x00" +
+	"=\xa8\xef\xc0\x00\x00\x00\x00>j\xae0\x00\x00\x00\x00?\x88\xd1\xc0\x00\x00\x00\x00@Sʰ\x00\x00\x00\x00Ah\xb3\xc0\x00\x00\x00\x00B3\xac\xb0\x00\x00\x00\x00CH\x95\xc0\x00\x00\x00\x00D\x13\x8e\xb0" +
+	"\x00\x00\x00\x00E1\xb2@\x00\x00\x00\x00E\xf3p\xb0\x00\x00\x00\x00G\x11\x94@\x00\x00\x00\x00G\xef\x020\x00\x00\x00\x00H\xf1v@\x00\x00\x00\x00I\xbco0\x00\x00\x00\x00J\xd1X@\x00\x00\x00\x00" +
+	"K\xb8\x00\xb0\x00\x00\x00\x00L\xb1:@\x00\x00\x00\x00M\xc6\a0\x00\x00\x00\x00NP\x82\xc0\x00\x00\x00\x00O\x9c\xae\xb0\x00\x00\x00\x00PB\xd9\xc0\x00\x00\x00\x00Q|\x90\xb0\x00\x00\x00\x00R+\xf6@" +
+	"\x00\x00\x00\x00S\\r\xb0\x00\x00\x00\x00T\v\xd8@\x00\x00\x00\x00W7\xe60\x00\x00\x00\x00W\xaf\xec\xc0\x00\x00\x00\x00Y\x17\xc80\x00\x00\x00\x00Y\x8f\xce\xc0\x00\x00\x00\x00Z\xf7\xaa0\x00\x00\x00\x00" +
+	"[o\xb0\xc0\x00\x00\x00\x00\\\xa9g\xb0\x00\x00\x00\x00]t|\xc0\x00\x00\x00\x00^\x89I\xb0\x00\x00\x00\x00_T^\xc0\x00\x00\x00\x00`i+\xb0\x00\x00\x00\x00a4@\xc0\x00\x00\x00\x00bI\r\xb0" +
+	"\x00\x00\x00\x00c\x1d]@\x00\x00\x00\x00d(\xef\xb0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" +
 	"\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" +
-	"\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a" +
-	"\x06\a\x06\a\x06\a\x06\a\xff\xff\xfa$\x00\x00\xff\xff\xfa\x0f\x00\x04\x00\x00\b\x1f\x01\b\x00\x00\x0e\x10\x01\f\x00\x00\x00\x00\x00\x10\x00\x00\x0e\x10\x01\b\x00\x00\x00\x00\x01\x10\x00\x00\x0e\x10\x00\bLMT\x00" +
-	"DMT\x00IST\x00BST\x00GMT\x00\nIST-1GMT0,M10.5.0,M3.5.0/1\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x1c\x00Etc/UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT" +
-	"\xd9|\xbd7s\x00\x00\x00s\x00\x00\x00\n\x00\x1c\x00Etc/GMT-10UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x8c\xa0\x00\x00+10\x00\n<+10>-10\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8f" +
-	"j\xbeT\xe5\xf38cr\x00\x00\x00r\x00\x00\x00\n\x00\x1c\x00Etc/GMT+12UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZi" +
-	"f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xffW@\x00\x00-12\x00\n<-12>12\nPK\x03\x04\n\x00\x00\x00\x00" +
-	"\x00\x8fj\xbeT\xb2\xab\xd1Is\x00\x00\x00s\x00\x00\x00\n\x00\x1c\x00Etc/GMT-11UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00T" +
+	"\x05\x04\x05\x04\x05\x04\xff\xff\x99x\x00\x00\xff\xff\x99x\x00\x04\xff\xff\xab\xa0\x01\b\xff\xff\x9d\x90\x00\f\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\x10LMT\x00EMT\x00-06\x00-07\x00-0" +
+	"5\x00\n<-06>6<-05>,M9.1.6/22,M4.1.6/22\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x1c\x9e\x9a]\x04\x00\x00]\x04\x00" +
+	"\x00\x04\x00\x00\x00CubaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" +
+	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00j\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffi\x87(\xb8\xff\xff\xff\xff\xacb\u0080" +
+	"\xff\xff\xff\xff\xb1ӔP\xff\xff\xff\xff\xb2t]@\xff\xff\xff\xff\xc8[f\xd0\xff\xff\xff\xff\xc8\xd3Q@\xff\xff\xff\xff\xca;H\xd0\xff\xff\xff\xffʼm\xc0\xff\xff\xff\xff\xcc$eP\xff\xff\xff\xff" +
+	"̜O\xc0\xff\xff\xff\xff\xd1\xc4\vP\xff\xff\xff\xff\xd2;\xf5\xc0\xff\xff\xff\xffӣ\xedP\xff\xff\xff\xff\xd4\x1b\xd7\xc0\xff\xff\xff\xff\xf7`\x05\xd0\xff\xff\xff\xff\xf7\xff}@\xff\xff\xff\xff\xf9=D\xd0" +
+	"\xff\xff\xff\xff\xf9\xe3S\xc0\xff\xff\xff\xff\xfa\xdb;\xd0\xff\xff\xff\xff\xfb\xa7\x86@\xff\xff\xff\xff\xfcũ\xd0\xff\xff\xff\xff\xfd\x87h@\xff\xff\xff\xff\xfe\xb8\x00\xd0\xff\xff\xff\xff\xff\xa7\xe3\xc0\x00\x00\x00\x00" +
+	"\x00\x97\xe2\xd0\x00\x00\x00\x00\x01\x87\xc5\xc0\x00\x00\x00\x00\x02w\xc4\xd0\x00\x00\x00\x00\x03p\xe2@\x00\x00\x00\x00\x04`\xe1P\x00\x00\x00\x00\x055\x14\xc0\x00\x00\x00\x00\x06@\xc3P\x00\x00\x00\x00\a\x16H@" +
+	"\x00\x00\x00\x00\b \xa5P\x00\x00\x00\x00\b\xf7{\xc0\x00\x00\x00\x00\n\x00\x87P\x00\x00\x00\x00\n\xf0j@\x00\x00\x00\x00\v\xe0iP\x00\x00\x00\x00\fن\xc0\x00\x00\x00\x00\r\xc0KP\x00\x00\x00\x00" +
+	"\x0e\xb9h\xc0\x00\x00\x00\x00\x0f\xb2\xa2P\x00\x00\x00\x00\x10}\x9b@\x00\x00\x00\x00\x11Q\xea\xd0\x00\x00\x00\x00\x12f\xb7\xc0\x00\x00\x00\x00\x131\xcc\xd0\x00\x00\x00\x00\x14F\x99\xc0\x00\x00\x00\x00\x15[\x82\xd0" +
+	"\x00\x00\x00\x00\x16&{\xc0\x00\x00\x00\x00\x17;d\xd0\x00\x00\x00\x00\x18\x06]\xc0\x00\x00\x00\x00\x19\x1bF\xd0\x00\x00\x00\x00\x19\xe6?\xc0\x00\x00\x00\x00\x1a\xfb(\xd0\x00\x00\x00\x00\x1b\xcf\\@\x00\x00\x00\x00" +
+	"\x1c\xdb\n\xd0\x00\x00\x00\x00\x1d\xaf>@\x00\x00\x00\x00\x1ezSP\x00\x00\x00\x00\x1f\x8f @\x00\x00\x00\x00 Z5P\x00\x00\x00\x00!o\x02@\x00\x00\x00\x00\"CQ\xd0\x00\x00\x00\x00#N\xe4@" +
+	"\x00\x00\x00\x00$#3\xd0\x00\x00\x00\x00%.\xc6@\x00\x00\x00\x00&\x15\x8a\xd0\x00\x00\x00\x00'\x17\xe2\xc0\x00\x00\x00\x00'\xfe\xa7P\x00\x00\x00\x00(\xf7\xd2\xd0\x00\x00\x00\x00)މP\x00\x00\x00\x00" +
+	"*״\xd0\x00\x00\x00\x00+\xbekP\x00\x00\x00\x00,\xb7\x96\xd0\x00\x00\x00\x00-\x9eMP\x00\x00\x00\x00.\x97x\xd0\x00\x00\x00\x00/~/P\x00\x00\x00\x000wZ\xd0\x00\x00\x00\x001gK\xd0" +
+	"\x00\x00\x00\x002W<\xd0\x00\x00\x00\x003G-\xd0\x00\x00\x00\x004@YP\x00\x00\x00\x005\x1d\xd5P\x00\x00\x00\x0062\xb0P\x00\x00\x00\x006\xfd\xb7P\x00\x00\x00\x008\x1b\xcc\xd0\x00\x00\x00\x00" +
+	"8\xe6\xd3\xd0\x00\x00\x00\x009\xfb\xae\xd0\x00\x00\x00\x00:Ƶ\xd0\x00\x00\x00\x00;ې\xd0\x00\x00\x00\x00<\xaf\xd2P\x00\x00\x00\x00=\xbbr\xd0\x00\x00\x00\x00>\x8f\xb4P\x00\x00\x00\x00?\x9bT\xd0" +
+	"\x00\x00\x00\x00@f[\xd0\x00\x00\x00\x00ED5P\x00\x00\x00\x00E\xf3\x8c\xd0\x00\x00\x00\x00G$\x17P\x00\x00\x00\x00GܩP\x00\x00\x00\x00I\x03\xf9P\x00\x00\x00\x00I\xb3P\xd0\x00\x00\x00\x00" +
+	"J\xe3\xdbP\x00\x00\x00\x00K\x9cmP\x00\x00\x00\x00L\xcc\xf7\xd0\x00\x00\x00\x00M\x85\x89\xd0\x00\x00\x00\x00N\xbfN\xd0\x00\x00\x00\x00Ow\xe0\xd0\x00\x00\x00\x00P\x95\xf6P\x01\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\xb2\xc8\x00\x00\xff\xff\xb2\xc0\x00\x04\xff\xff\xc7\xc0\x01\b\xff\xff\xb9\xb0" +
+	"\x00\fLMT\x00HMT\x00CDT\x00CST\x00\nCST5CDT,M3.2.0/0,M11.1.0/1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"`l\x8d~\xf1\x01\x00\x00\xf1\x01\x00\x00\x03\x00\x00\x00EETTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00" +
+	"\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\x00\x00\x00\x02\x00\x00\x00\t\x00\x00\x00\x00\r\xa4" +
+	"c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00" +
+	"\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc" +
+	"\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00" +
+	"\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5" +
+	"\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00" +
+	"\x00\x001]\xd9\x10\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x00\x1c \x00\x05\x00\x00*0\x01\x00EES" +
+	"T\x00EET\x00\nEET-2EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00tX\xbe\xe4o\x00\x00\x00o\x00" +
+	"\x00\x00\x03\x00\x00\x00ESTTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" +
+	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\xb9\xb0\x00\x00EST\x00\nEST5\n" +
+	"PK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe7/\xebT\xb7\x03\x00\x00\xb7\x03\x00\x00\a\x00\x00\x00EST5EDTTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00X\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\x9e\xa6\x1ep\xff\xff\xff\xff\x9f\xba\xeb`\xff\xff\xff\xff\xa0\x86\x00p\xff\xff\xff\xff\xa1\x9a\xcd`\xff\xff\xff\xffˈ\xf0p\xff\xff\xff\xff\xd2#\xf4p" +
+	"\xff\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff\xfa\xf8X\xf0\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00" +
+	"\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\a0\xc2`" +
+	"\x00\x00\x00\x00\a\x8d\x19p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\t\xad\x94\xf0\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00\f٢\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00\x00\x00" +
+	"\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0" +
+	"\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x00\x00\x00\x00\x1a\xf2\np\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00" +
+	"\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\"U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0" +
+	"\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\nU\xe0\x00\x00\x00\x00)ޥp\x00\x00\x00\x00" +
+	"*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0" +
+	"\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\a\r\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x00" +
+	"8\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0" +
+	"\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x01\x00\x01\x00" +
+	"\x02\x03\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01" +
+	"\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\xff\xff\xb9\xb0\x00\x04\xff\xff\xc7\xc0\x01\x00\xff\xff\xc7\xc0\x01\b\xff\xff\xc7\xc0\x01\fEDT\x00EST\x00EWT\x00" +
+	"EPT\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12tnj\xfc\x04\x00\x00\xfc\x04\x00\x00\x05\x00\x00\x00Eg" +
+	"yptTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xff}\xbdM\xab\xff\xff\xff\xffȓ\xb4\xe0\xff\xff\xff\xff\xc8\xfa" +
+	"{\xd0\xff\xff\xff\xff\xc9\xfc\xef\xe0\xff\xff\xff\xff\xca\xc7\xe8\xd0\xff\xff\xff\xff\xcbˮ`\xff\xff\xff\xff\xcc\xdf)\xd0\xff\xff\xff\xffͬ\xe1\xe0\xff\xff\xff\xff\xce\xc6\xf4\xd0\xff\xff\xff\xffϏf\xe0\xff\xff" +
+	"\xff\xffЩy\xd0\xff\xff\xff\xffф`\xe0\xff\xff\xff\xffҊ\xadP\xff\xff\xff\xff\xe86c`\xff\xff\xff\xff\xe8\xf4-P\xff\xff\xff\xff\xea\v\xb9`\xff\xff\xff\xff\xea\xd5`\xd0\xff\xff\xff\xff\xeb\xec" +
+	"\xfa\xf0\xff\xff\xff\xff\xec\xb5m\x00\xff\xff\xff\xff\xed\xcf\x7f\xf0\xff\xff\xff\xff\xee\x97\xf2\x00\xff\xff\xff\xffﰳp\xff\xff\xff\xff\xf0y%\x80\xff\xff\xff\xff\xf1\x91\xe6\xf0\xff\xff\xff\xff\xf2ZY\x00\xff\xff" +
+	"\xff\xff\xf3s\x1ap\xff\xff\xff\xff\xf4;\x8c\x80\xff\xff\xff\xff\xf5U\x9fp\xff\xff\xff\xff\xf6\x1e\x11\x80\xff\xff\xff\xff\xf76\xd2\xf0\xff\xff\xff\xff\xf7\xffE\x00\xff\xff\xff\xff\xf9\x18\x06p\xff\xff\xff\xff\xf9\xe1" +
+	"\xca\x00\xff\xff\xff\xff\xfa\xf99\xf0\xff\xff\xff\xff\xfb\xc2\xfd\x80\xff\xff\xff\xff\xfc۾\xf0\xff\xff\xff\xff\xfd\xa5\x82\x80\xff\xff\xff\xff\xfe\xbc\xf2p\xff\xff\xff\xff\xff\x86\xb6\x00\x00\x00\x00\x00\x00\x9e%\xf0\x00\x00" +
+	"\x00\x00\x01g\xe9\x80\x00\x00\x00\x00\x02\x7fYp\x00\x00\x00\x00\x03I\x1d\x00\x00\x00\x00\x00\x04a\xdep\x00\x00\x00\x00\x05+\xa2\x00\x00\x00\x00\x00\x06C\x11\xf0\x00\x00\x00\x00\a\fՀ\x00\x00\x00\x00\b$" +
+	"Ep\x00\x00\x00\x00\b\xee\t\x00\x00\x00\x00\x00\n\x05x\xf0\x00\x00\x00\x00\n\xcf<\x80\x00\x00\x00\x00\v\xe7\xfd\xf0\x00\x00\x00\x00\f\xb1\xc1\x80\x00\x00\x00\x00\r\xc91p\x00\x00\x00\x00\x0e\x92\xf5\x00\x00\x00" +
+	"\x00\x00\x0f\xaad\xf0\x00\x00\x00\x00\x10t(\x80\x00\x00\x00\x00\x11\x8b\x98p\x00\x00\x00\x00\x12U\\\x00\x00\x00\x00\x00\x13n\x1dp\x00\x00\x00\x00\x147\xe1\x00\x00\x00\x00\x00\x15OP\xf0\x00\x00\x00\x00\x16\x19" +
+	"\x14\x80\x00\x00\x00\x00\x17\xa0\x93\xf0\x00\x00\x00\x00\x17\xfaH\x00\x00\x00\x00\x00\x19p\xa3\xf0\x00\x00\x00\x00\x19\xdb{\x80\x00\x00\x00\x00\x1a\xf4<\xf0\x00\x00\x00\x00\x1b\xbe\x00\x80\x00\x00\x00\x00\x1c\xd5pp\x00\x00" +
+	"\x00\x00\x1d\x9f4\x00\x00\x00\x00\x00\x1e\xb6\xa3\xf0\x00\x00\x00\x00\x1f\x80g\x80\x00\x00\x00\x00 \x97\xd7p\x00\x00\x00\x00!a\x9b\x00\x00\x00\x00\x00\"z\\p\x00\x00\x00\x00#D \x00\x00\x00\x00\x00$b" +
+	"'p\x00\x00\x00\x00%%S\x80\x00\x00\x00\x00&<\xc3p\x00\x00\x00\x00'\x06\x87\x00\x00\x00\x00\x00(\x1d\xf6\xf0\x00\x00\x00\x00(纀\x00\x00\x00\x00*\x00{\xf0\x00\x00\x00\x00*\xca?\x80\x00\x00" +
+	"\x00\x00+\xe1\xafp\x00\x00\x00\x00,\xabs\x00\x00\x00\x00\x00-\xc2\xe2\xf0\x00\x00\x00\x00.\x8c\xa6\x80\x00\x00\x00\x00/\xa0\x13\xe0\x00\x00\x00\x000k\f\xd0\x00\x00\x00\x001\x7f\xf5\xe0\x00\x00\x00\x002J" +
+	"\xee\xd0\x00\x00\x00\x003_\xd7\xe0\x00\x00\x00\x004*\xd0\xd0\x00\x00\x00\x005?\xb9\xe0\x00\x00\x00\x006\n\xb2\xd0\x00\x00\x00\x007(\xd6`\x00\x00\x00\x007\xf3\xcfP\x00\x00\x00\x009\b\xb8`\x00\x00" +
+	"\x00\x009ӱP\x00\x00\x00\x00:\xe8\x9a`\x00\x00\x00\x00;\xb3\x93P\x00\x00\x00\x00<\xc8|`\x00\x00\x00\x00=\x93uP\x00\x00\x00\x00>\xa8^`\x00\x00\x00\x00?sWP\x00\x00\x00\x00@\x91" +
+	"z\xe0\x00\x00\x00\x00A\\s\xd0\x00\x00\x00\x00Bq\\\xe0\x00\x00\x00\x00C<U\xd0\x00\x00\x00\x00DQ>\xe0\x00\x00\x00\x00E\x12\xfdP\x00\x00\x00\x00F1 \xe0\x00\x00\x00\x00F\xe0jP\x00\x00" +
+	"\x00\x00H\x11\x02\xe0\x00\x00\x00\x00H\xb7\x11\xd0\x00\x00\x00\x00I\xf0\xe4\xe0\x00\x00\x00\x00J\x8d\xb9P\x00\x00\x00\x00K\xda\x01`\x00\x00\x00\x00La\xbd\xd0\x00\x00\x00\x00L\x89X\xe0\x00\x00\x00\x00L\xa4" +
+	"\xfaP\x00\x00\x00\x00Su8\xe0\x00\x00\x00\x00S\xac\x89\xd0\x00\x00\x00\x00Sڼ`\x00\x00\x00\x00T$\x82P\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x1dU\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\tL" +
+	"MT\x00EEST\x00EET\x00\nEET-2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1\xd6jL\xd8\x05\x00\x00\xd8\x05\x00\x00\x04\x00\x00\x00EireTZif2\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x91\x00\x00\x00\b\x00\x00\x00\x14\xff\xff\xff\xffW\xd1\n\xf1\xff\xff\xff\xff\x9b&\xb3\x91\xff\xff\xff\xff\x9b\xd6\v\x11\xff\xff\xff\xff\x9c\xcf0\xa0" +
+	"\xff\xff\xff\xff\x9d\xa4à\xff\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff\xff\xff\xa0\x85\xba \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{Ƞ\xff\xff\xff\xff" +
+	"\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00Ӡ\xff\xff\xff\xff\xaa\xd5\x15 " +
+	"\xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \xff\xff\xff\xff\xb1\x92Р\xff\xff\xff\xff" +
+	"\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \xff\xff\xff\xff\xb60\x10\xa0\xff\xff\xff\xff\xb72v\xa0\xff\xff\xff\xff\xb8\x0f\xf2\xa0\xff\xff\xff\xff\xb9\x12X\xa0" +
+	"\xff\xff\xff\xff\xb9\xefԠ\xff\xff\xff\xff\xba\xe9\x00 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff" +
+	"\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠" +
+	"\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd7,( \xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff" +
+	"\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\u07b4\xea\xa0\xff\xff\xff\xff߮\x16 \xff\xff\xff\xff\xe0\x94̠" +
+	"\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt \xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4T\x90\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6=\xad \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff" +
+	"\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\v \xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\ue6b1 " +
+	"\xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\x7f_ \xff\xff\xff\xff\xf3Jf \xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\r\xa0\xff\xff\xff\xff" +
+	"\xf6?# \xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0Ѡ\xff\xff\xff\xff\xf9\xfe\xe7 \xff\xff\xff\xff\xfa\xc0\xb3\xa0\xff\xff\xff\xff\xfb\xe8\x03\xa0\xff\xff\xff\xff\xfc{\xab\xa0" +
+	"\xff\xff\xff\xff\xfdǻp\x00\x00\x00\x00\x03p\xc6 \x00\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\t: \x00\x00\x00\x00\a0\x8a \x00\x00\x00\x00\a\xe9\x1c \x00\x00\x00\x00" +
+	"\t\x10l \x00\x00\x00\x00\t\xc8\xfe \x00\x00\x00\x00\n\xf0N \x00\x00\x00\x00\v\xb2\x1a\xa0\x00\x00\x00\x00\f\xd00 \x00\x00\x00\x00\r\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \x00\x00\x00\x00\x0fqޠ" +
+	"\x00\x00\x00\x00\x10\x99.\xa0\x00\x00\x00\x00\x11Q\xc0\xa0\x00\x00\x00\x00\x12y\x10\xa0\x00\x00\x00\x00\x131\xa2\xa0\x00\x00\x00\x00\x14X\xf2\xa0\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x168Ɛ\x00\x00\x00\x00" +
+	"\x17\x03͐\x00\x00\x00\x00\x18\x18\xa8\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19\xf8\x8a\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xe1\xa7\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\xc1\x89\x10" +
+	"\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f\xa1k\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\x81M\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#a/\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00" +
+	"%JK\x90\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'*-\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00)\n\x0f\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xe9\xf1\x90\x00\x00\x00\x00+\xb4\xf8\x90" +
+	"\x00\x00\x00\x00,\xc9Ӑ\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\xa9\xb5\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000\x89\x97\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" +
+	"\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" +
+	"\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06" +
+	"\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\xff\xff\xfa\x0f\x00\x00\xff\xff\xfa\x0f\x00\x04\x00\x00\b\x1f\x01\b\x00\x00\x0e\x10\x01\f\x00\x00\x00\x00\x00\x10\x00\x00\x0e\x10\x01\b\x00\x00\x00\x00\x01\x10\x00\x00\x0e\x10\x00" +
+	"\bLMT\x00DMT\x00IST\x00BST\x00GMT\x00\nIST-1GMT0,M10.5.0,M3.5.0/1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\a\x00\x00\x00Etc/GMTTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" +
+	"\x04\x00\x00\x00\x00\x00\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\t\x00\x00\x00Etc/GMT+0TZif" +
+	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x005\xb8\xe8\x86q\x00\x00\x00q\x00\x00\x00\t\x00\x00\x00Etc/GMT+1TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" +
+	"\x04\xff\xff\xf1\xf0\x00\x00-01\x00\n<-01>1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8e\x1569r\x00\x00\x00r\x00\x00\x00\n\x00\x00\x00Etc/GMT+10T" +
 	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x9a\xb0\x00\x00+11\x00\n<+11>-11\nPK\x03\x04\n\x00" +
-	"\x00\x00\x00\x00\x8fj\xbeT\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\r\x00\x1c\x00Etc/UniversalUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00" +
-	"\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif" +
-	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00\nUTC0\nPK\x03\x04" +
-	"\n\x00\x00\x00\x00\x00\x8fj\xbeTP\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\r\x00\x1c\x00Etc/GreenwichUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1" +
-	"\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZ" +
-	"if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\nGMT0\nPK" +
-	"\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTj\xd5d\xb0r\x00\x00\x00r\x00\x00\x00\t\x00\x1c\x00Etc/GMT-6UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00" +
-	"\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif" +
-	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00T`\x00\x00+06\x00\n<+06>-6\nP" +
-	"K\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xf7\x1ac\xc3r\x00\x00\x00r\x00\x00\x00\t\x00\x1c\x00Etc/GMT-1UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b" +
-	"\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZi" +
-	"f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x0e\x10\x00\x00+01\x00\n<+01>-1\n" +
-	"PK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xc5\x18\xb6\xfbr\x00\x00\x00r\x00\x00\x00\t\x00\x1c\x00Etc/GMT-8UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1" +
-	"\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZ" +
-	"if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00p\x80\x00\x00+08\x00\n<+08>-8" +
-	"\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xd0\xfaFDq\x00\x00\x00q\x00\x00\x00\t\x00\x1c\x00Etc/GMT+4UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91" +
-	"\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00T" +
-	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\xc7\xc0\x00\x00-04\x00\n<-04>4" +
-	"\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTe\xcb\xe9Qq\x00\x00\x00q\x00\x00\x00\t\x00\x1c\x00Etc/GMT+3UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91" +
-	"\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00T" +
-	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\xd5\xd0\x00\x00-03\x00\n<-03>3" +
-	"\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xfc\x19@\xb9r\x00\x00\x00r\x00\x00\x00\t\x00\x1c\x00Etc/GMT-9UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91" +
-	"\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00T" +
-	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00~\x90\x00\x00+09\x00\n<+09>-" +
-	"9\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTP\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\t\x00\x1c\x00Etc/GMT-0UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04" +
-	"\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" +
-	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\nGMT0\n" +
-	"PK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTJ0p-r\x00\x00\x00r\x00\x00\x00\t\x00\x1c\x00Etc/GMT-7UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1" +
-	"\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZ" +
-	"if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00bp\x00\x00+07\x00\n<+07>-7" +
-	"\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xa9{\xa2qq\x00\x00\x00q\x00\x00\x00\t\x00\x1c\x00Etc/GMT+2UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91" +
-	"\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00T" +
-	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\xe3\xe0\x00\x00-02\x00\n<-02>2" +
-	"\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xd4X\x9b\xf3q\x00\x00\x00q\x00\x00\x00\t\x00\x1c\x00Etc/GMT+5UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91" +
-	"\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00T" +
-	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\xb9\xb0\x00\x00-05\x00\n<-05>5" +
-	"\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTP\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\a\x00\x1c\x00Etc/GMTUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b" +
-	"\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZi" +
-	"f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\nGMT0\nPK\x03" +
-	"\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\b\x00\x1c\x00Etc/ZuluUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S" +
-	"_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00\nUTC0\nPK\x03\x04\n\x00" +
-	"\x00\x00\x00\x00\x8fj\xbeT)\xb9\xbe\x9dr\x00\x00\x00r\x00\x00\x00\n\x00\x1c\x00Etc/GMT+11UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_" +
-	"\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xffeP\x00\x00-11\x00\n<-11>11\nPK\x03\x04" +
-	"\n\x00\x00\x00\x00\x00\x8fj\xbeT\x90`N\xe8s\x00\x00\x00s\x00\x00\x00\n\x00\x1c\x00Etc/GMT-13UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04" +
-	"S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\xb6\xd0\x00\x00+13\x00\n<+13>-13\nP" +
-	"K\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT,{\xdc;s\x00\x00\x00s\x00\x00\x00\n\x00\x1c\x00Etc/GMT-14UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1" +
-	"\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZ" +
-	"if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\xc4\xe0\x00\x00+14\x00\n<+14>-1" +
-	"4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x8e\x1569r\x00\x00\x00r\x00\x00\x00\n\x00\x1c\x00Etc/GMT+10UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01" +
-	"\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" +
-	"\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xffs`\x00\x00-10\x00\n<-10" +
-	">10\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xf7\x19s\x81s\x00\x00\x00s\x00\x00\x00\n\x00\x1c\x00Etc/GMT-12UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v" +
-	"\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00" +
-	"\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\xa8\xc0\x00\x00+12\x00\n<+" +
-	"12>-12\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTP\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\b\x00\x1c\x00Etc/GMT0UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux" +
-	"\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00" +
-	"\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\nG" +
-	"MT0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\a\x00\x1c\x00Etc/UCTUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04" +
-	"\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" +
-	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00\nUTC0\n" +
-	"PK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTP\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\t\x00\x1c\x00Etc/GMT+0UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1" +
-	"\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZ" +
-	"if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\nGMT0\nPK" +
-	"\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x84+\x9a$q\x00\x00\x00q\x00\x00\x00\t\x00\x1c\x00Etc/GMT+7UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00" +
-	"\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif" +
-	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\x9d\x90\x00\x00-07\x00\n<-07>7\nPK" +
-	"\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x84\x19\xb3\tq\x00\x00\x00q\x00\x00\x00\t\x00\x1c\x00Etc/GMT+9UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00" +
-	"\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif" +
-	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\x81p\x00\x00-09\x00\n<-09>9\nPK" +
-	"\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xbc\x19y\x04r\x00\x00\x00r\x00\x00\x00\t\x00\x1c\x00Etc/GMT-2UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00" +
-	"\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif" +
-	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x1c \x00\x00+02\x00\n<+02>-2\nP" +
-	"K\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT!\xd6~wr\x00\x00\x00r\x00\x00\x00\t\x00\x1c\x00Etc/GMT-5UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b" +
-	"\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZi" +
-	"f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00FP\x00\x00+05\x00\n<+05>-5\n" +
-	"PK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\"\xf8\x8f/q\x00\x00\x00q\x00\x00\x00\t\x00\x1c\x00Etc/GMT+8UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1" +
-	"\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZ" +
-	"if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\x8f\x80\x00\x00-08\x00\n<-08>8\n" +
-	"PK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTH\x9b\xd1\x04q\x00\x00\x00q\x00\x00\x00\t\x00\x1c\x00Etc/GMT+6UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1" +
-	"\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZ" +
-	"if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\xab\xa0\x00\x00-06\x00\n<-06>6\n" +
-	"PK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT5\xb8\xe8\x86q\x00\x00\x00q\x00\x00\x00\t\x00\x1c\x00Etc/GMT+1UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1" +
-	"\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZ" +
-	"if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\xf1\xf0\x00\x00-01\x00\n<-01>1\n" +
-	"PK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\a\x00\x1c\x00Etc/UTCUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00" +
-	"\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif" +
-	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00\nUTC0\nPK\x03\x04" +
-	"\n\x00\x00\x00\x00\x00\x8fj\xbeTk\x19<Qr\x00\x00\x00r\x00\x00\x00\t\x00\x1c\x00Etc/GMT-4UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S" +
-	"_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x008@\x00\x00+04\x00\n<+04>-4\nPK\x03" +
-	"\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9c\xfcm\x99r\x00\x00\x00r\x00\x00\x00\t\x00\x1c\x00Etc/GMT-3UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04" +
-	"S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00*0\x00\x00+03\x00\n<+03>-3\nPK" +
-	"\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x1c\x00Europe/UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S" +
-	"_\x01\x00PK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTDd#\xc4\xf1\x01\x00\x00\xf1\x01\x00\x00\r\x00\x1c\x00Europe/ZurichUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bu" +
-	"x\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00" +
-	"\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00%\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff$\xf0\xea\x80\xff\xff\xff" +
-	"\xffq\xd4\x06\x86\xff\xff\xff\xff\xca\x17j\x00\xff\xff\xff\xff\xca\xe2q\x00\xff\xff\xff\xff\xcb\xf7L\x00\xff\xff\xff\xff\xcc\xc2S\x00\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03\xcd" +
-	"\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00" +
-	"\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'" +
-	"\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00" +
-	"\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\b\x00\x00\x00\x00\x00\x06\xfa\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\rLMT\x00BMT\x00CEST\x00C" +
-	"ET\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xc7\xf5\x94\xdaQ\x04\x00\x00Q\x04\x00\x00\f\x00\x1c" +
-	"\x00Europe/ParisUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00e\x00\x00\x00\a\x00\x00\x00\x1f\xff\xff\xff\xffkɛ\xcf\xff\xff\xff\xff\x91`PO\xff\xff\xff\xff\x9bGx\xf0\xff\xff\xff\xff\x9b\xd7,p\xff\xff\xff\xff\x9c\xbc\x91p\xff\xff\xff\xff" +
-	"\x9d\xc0H\xf0\xff\xff\xff\xff\x9e\x89\xfep\xff\xff\xff\xff\x9f\xa0*\xf0\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1\x80\f\xf0\xff\xff\xff\xff\xa2.\x12\xf0\xff\xff\xff\xff\xa3zL\xf0\xff\xff\xff\xff\xa45\x81\xf0" +
-	"\xff\xff\xff\xff\xa5^#p\xff\xff\xff\xff\xa6%5\xf0\xff\xff\xff\xff\xa7'\x9b\xf0\xff\xff\xff\xff\xa8X&p\xff\xff\xff\xff\xa9\a}\xf0\xff\xff\xff\xff\xa9\xee4p\xff\xff\xff\xff\xaa\xe7_\xf0\xff\xff\xff\xff" +
-	"\xab\xd7P\xf0\xff\xff\xff\xff\xac\xc7A\xf0\xff\xff\xff\xff\xadɧ\xf0\xff\xff\xff\xff\xae\xa7#\xf0\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x05\xf0\xff\xff\xff\xff\xb1\x89k\xf0\xff\xff\xff\xff\xb2p\"p" +
-	"\xff\xff\xff\xff\xb3r\x88p\xff\xff\xff\xff\xb4P\x04p\xff\xff\xff\xff\xb5I/\xf0\xff\xff\xff\xff\xb6/\xe6p\xff\xff\xff\xff\xb72Lp\xff\xff\xff\xff\xb8\x0f\xc8p\xff\xff\xff\xff\xb8\xff\xb9p\xff\xff\xff\xff" +
-	"\xb9\xef\xaap\xff\xff\xff\xff\xba\xd6`\xf0\xff\xff\xff\xff\xbb\xd8\xc6\xf0\xff\xff\xff\xff\xbcȷ\xf0\xff\xff\xff\xff\xbd\xb8\xa8\xf0\xff\xff\xff\xff\xbe\x9f_p\xff\xff\xff\xff\xbf\x98\x8a\xf0\xff\xff\xff\xff\xc0\x9a\xf0\xf0" +
-	"\xff\xff\xff\xff\xc1xl\xf0\xff\xff\xff\xff\xc2h]\xf0\xff\xff\xff\xff\xc3XN\xf0\xff\xff\xff\xff\xc4?\x05p\xff\xff\xff\xff\xc580\xf0\xff\xff\xff\xff\xc6:\x96\xf0\xff\xff\xff\xff\xc7X\xacp\xff\xff\xff\xff" +
-	"\xc7\xda\t\xa0\xff\xff\xff\xff\xc8l'\xe0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xff\xd0O\xe1\xe0\xff\xff\xff\xffЉ\xf1\xf0" +
-	"\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\v\xbb9\x00\x00\x00\x00\x00\f\xab\x1b\xf0\x00\x00\x00\x00\r\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00" +
-	"\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐" +
-	"\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00" +
-	"\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10" +
-	"\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00" +
-	",\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
-	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x06\x02\x06\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" +
-	"\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x00\x00\x021\x00\x00\x00\x00\x021\x00\x04\x00\x00\x0e\x10\x01\b\x00\x00\x00\x00\x00\r\x00\x00\x0e\x10\x00\x11\x00\x00\x1c \x01" +
-	"\x15\x00\x00\x1c \x01\x1aLMT\x00PMT\x00WEST\x00WET\x00CET\x00CEST\x00WEMT\x00\nCET-1CEST,M3.5.0,M10." +
-	"5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe1\xc1\xeb\x05\x8c\x03\x00\x00\x8c\x03\x00\x00\r\x00\x1c\x00Europe/MoscowUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc" +
-	"\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" +
-	"\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00N\x00\x00\x00\v\x00\x00\x00&\xff\xff\xff\xffV\xb6\xc0\xc7" +
-	"\xff\xff\xff\xff\x9b_\x1e\xc7\xff\xff\xff\xff\x9d>\xf2y\xff\xff\xff\xff\x9e*\xee\xf9\xff\xff\xff\xff\x9e\xf79i\xff\xff\xff\xff\x9f\x84W\xf9\xff\xff\xff\xff\xa0\xd8l\xe9\xff\xff\xff\xff\xa1\x009\x80\xff\xff\xff\xff" +
-	"\xa1<\xa6@\xff\xff\xff\xff\xa4\x10m\xc0\xff\xff\xff\xff\xa4=2\xb0\xff\xff\xff\xff\xa5\x15h\xb0\xff\xff\xff\xff\xa5=\x03\xc0\xff\xff\xff\xff\xa7\x1eEP\xff\xff\xff\xff\xb5\xa4\x19`\x00\x00\x00\x00\x15'\xa7\xd0" +
-	"\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00" +
-	"\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0" +
-	"\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)x\xbf\x80\x00\x00\x00\x00" +
-	")\xd4\xfap\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x94\xbep\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p" +
-	"\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x00" +
-	"8\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb<p\x00\x00\x00\x00<\xa6Cp\x00\x00\x00\x00=\xbb\x1ep\x00\x00\x00\x00>\x86%p" +
-	"\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f\ap\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00" +
-	"F\x05\xadp\x00\x00\x00\x00G#\xc2\xf0\x00\x00\x00\x00G\xee\xc9\xf0\x00\x00\x00\x00I\x03\xa4\xf0\x00\x00\x00\x00IΫ\xf0\x00\x00\x00\x00J\xe3\x86\xf0\x00\x00\x00\x00K\xae\x8d\xf0\x00\x00\x00\x00Ḷp" +
-	"\x00\x00\x00\x00M\x8eo\xf0\x00\x00\x00\x00TL\x1d`\x01\x03\x02\x03\x04\x02\x04\x05\x06\x05\a\x05\x06\b\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\t\b\x06\x05\x06\x05\x06\x05\x06" +
-	"\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\n\x06\x00\x00#9\x00\x00\x00\x00#9\x00\x04\x00\x001\x87\x01\b\x00\x00#w\x00\x04\x00\x00" +
-	"?\x97\x01\f\x00\x008@\x01\x11\x00\x00*0\x00\x15\x00\x00FP\x01\x19\x00\x00\x1c \x00\x1d\x00\x00*0\x01!\x00\x008@\x00\x15LMT\x00MMT\x00MST\x00MDST\x00MSD" +
-	"\x00MSK\x00+05\x00EET\x00EEST\x00\nMSK-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTM\xe5\xa9 ?\x04\x00\x00?\x04\x00\x00\x11\x00\x1c\x00Europ" +
-	"e/LuxembourgUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xffs`\x00\x00-10\x00\n<-10>10\nPK\x03\x04\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00)\xb9\xbe\x9dr\x00\x00\x00r\x00\x00\x00\n\x00\x00\x00Etc/GMT+11TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x01\x00\x00\x00\x04\xff\xffeP\x00\x00-11\x00\n<-11>11\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5\xf38cr\x00\x00\x00r\x00\x00\x00\n\x00\x00\x00Etc" +
+	"/GMT+12TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZ" +
+	"if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xffW@\x00\x00-12\x00\n<-12>12" +
+	"\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa9{\xa2qq\x00\x00\x00q\x00\x00\x00\t\x00\x00\x00Etc/GMT+2TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
 	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00d\x00\x00\x00\a\x00\x00\x00\x16\xff\xff\xff\xff\x84\xa2\xad\xbc\xff\xff\xff\xff\x9b\x1e\x8c`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9c\xea\xa7\xe0\xff\xff\xff\xff\x9d\xa4\x99p\xff\xff\xff\xff\x9e" +
-	"\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\x9f\xe0\xc4p\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1~\xe5\xa0\xff\xff\xff\xff\xa2.\x12\xf0\xff\xff\xff\xff\xa3zi\x10\xff\xff\xff\xff\xa45\x81\xf0\xff" +
-	"\xff\xff\xff\xa5^?\x90\xff\xff\xff\xff\xa6%5\xf0\xff\xff\xff\xff\xa7'\xaa\x00\xff\xff\xff\xff\xa8*\x01\xf0\xff\xff\xff\xff\xa9\a\x9a\x10\xff\xff\xff\xff\xa9\xee4p\xff\xff\xff\xff\xaa\xe7n\x00\xff\xff\xff\xff\xab" +
-	"آp\xff\xff\xff\xff\xac\xc7P\x00\xff\xff\xff\xff\xadɧ\xf0\xff\xff\xff\xff\xae\xa72\x00\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x14\x00\xff\xff\xff\xff\xb1\x89k\xf0\xff\xff\xff\xff\xb2p0\x80\xff" +
-	"\xff\xff\xff\xb3r\x88p\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \xff\xff\xff\xff\xb60\x10\xa0\xff\xff\xff\xff\xb72v\xa0\xff\xff\xff\xff\xb8\x0f\xf2\xa0\xff\xff\xff\xff\xb8\xff\xe3\xa0\xff\xff\xff\xff\xb9" +
-	"\xefԠ\xff\xff\xff\xff\xba\u058b \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xc8\xe2 \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\x9f\x89\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff" +
-	"\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2h\x88 \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4?/\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7" +
-	"\xda\t\xa0\xff\xff\xff\xff\xc8B0 \xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xff\xd0o\xb0\x10\xff\xff\xff\xff\xd1r\x16\x10\xff" +
-	"\xff\xff\xff\xd2N@\x90\xff\xff\xff\xffӑ@\x10\xff\xff\xff\xff\xd4K#\x90\x00\x00\x00\x00\r\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11" +
-	"d'\x90\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00" +
-	"\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f" +
-	"|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00" +
-	"\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-" +
-	"\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" +
-	"\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x06\x05\x06\x05\x06\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00\x05\xc4\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x0e\x10\x01\r\x00\x00\x00\x00\x00\x12\x00\x00\x0e\x10\x00\x12\x00\x00\x1c \x01\rLMT" +
-	"\x00CEST\x00CET\x00WEST\x00WET\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbe" +
-	"T\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\x10\x00\x1c\x00Europe/LjubljanaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01" +
-	"\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xff^<\xf0H\xff\xff\xff\xff\xca\x025\xe0\xff\xff\xff\xff\xcc\xe7K\x10" +
-	"\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xffѡ\x8c\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\xe3\xe0\x00\x00-02\x00\n<-02>2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00e\xcb\xe9Qq\x00\x00\x00q\x00\x00\x00\t" +
+	"\x00\x00\x00Etc/GMT+3TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00" +
+	"\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\xd5\xd0\x00\x00-03\x00\n<-" +
+	"03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd0\xfaFDq\x00\x00\x00q\x00\x00\x00\t\x00\x00\x00Etc/GMT+4TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\xc7\xc0\x00\x00-04\x00\n<-04>4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd4X\x9b\xf3q\x00\x00\x00q" +
+	"\x00\x00\x00\t\x00\x00\x00Etc/GMT+5TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01" +
+	"\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\xb9\xb0\x00\x00-05" +
+	"\x00\n<-05>5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00H\x9b\xd1\x04q\x00\x00\x00q\x00\x00\x00\t\x00\x00\x00Etc/GMT+6TZif2\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\xab\xa0\x00\x00-06\x00\n<-06>6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84+\x9a$q" +
+	"\x00\x00\x00q\x00\x00\x00\t\x00\x00\x00Etc/GMT+7TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" +
+	"\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\x9d\x90\x00" +
+	"\x00-07\x00\n<-07>7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\"\xf8\x8f/q\x00\x00\x00q\x00\x00\x00\t\x00\x00\x00Etc/GMT+8TZif2\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\x8f\x80\x00\x00-08\x00\n<-08>8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84" +
+	"\x19\xb3\tq\x00\x00\x00q\x00\x00\x00\t\x00\x00\x00Etc/GMT+9TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff" +
+	"\xff\x81p\x00\x00-09\x00\n<-09>9\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\t\x00\x00\x00Etc/GMT-0TZif" +
+	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\xf7\x1ac\xc3r\x00\x00\x00r\x00\x00\x00\t\x00\x00\x00Etc/GMT-1TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" +
+	"\x04\x00\x00\x0e\x10\x00\x00+01\x00\n<+01>-1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd9|\xbd7s\x00\x00\x00s\x00\x00\x00\n\x00\x00\x00Etc/GMT-10" +
+	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x8c\xa0\x00\x00+10\x00\n<+10>-10\nPK\x03\x04\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\xab\xd1Is\x00\x00\x00s\x00\x00\x00\n\x00\x00\x00Etc/GMT-11TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x9a\xb0\x00\x00+11\x00\n<+11>-11\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf7\x19s\x81s\x00\x00\x00s\x00\x00\x00\n\x00\x00\x00" +
+	"Etc/GMT-12TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" +
+	"\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\xa8\xc0\x00\x00+12\x00\n<+12" +
+	">-12\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90`N\xe8s\x00\x00\x00s\x00\x00\x00\n\x00\x00\x00Etc/GMT-13TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\xb6\xd0\x00\x00+13\x00\n<+13>-13\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,{\xdc;s\x00" +
+	"\x00\x00s\x00\x00\x00\n\x00\x00\x00Etc/GMT-14TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" +
+	"\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\xc4\xe0\x00" +
+	"\x00+14\x00\n<+14>-14\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\x19y\x04r\x00\x00\x00r\x00\x00\x00\t\x00\x00\x00Etc/GMT-2TZif2\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x1c \x00\x00+02\x00\n<+02>-2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x9c\xfcm\x99r\x00\x00\x00r\x00\x00\x00\t\x00\x00\x00Etc/GMT-3TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00" +
+	"\x00\x04\x00\x00*0\x00\x00+03\x00\n<+03>-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\x19<Qr\x00\x00\x00r\x00\x00\x00\t\x00\x00\x00Etc/GMT-4" +
+	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x008@\x00\x00+04\x00\n<+04>-4\nPK\x03\x04\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00!\xd6~wr\x00\x00\x00r\x00\x00\x00\t\x00\x00\x00Etc/GMT-5TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00FP\x00\x00+05\x00\n<+05>-5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00j\xd5d\xb0r\x00\x00\x00r\x00\x00\x00\t\x00\x00\x00Etc" +
+	"/GMT-6TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZi" +
+	"f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00T`\x00\x00+06\x00\n<+06>-6\n" +
+	"PK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00J0p-r\x00\x00\x00r\x00\x00\x00\t\x00\x00\x00Etc/GMT-7TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00bp\x00\x00+07\x00\n<+07>-7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc5\x18\xb6\xfbr\x00\x00\x00r\x00\x00\x00\t" +
+	"\x00\x00\x00Etc/GMT-8TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00" +
+	"\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00p\x80\x00\x00+08\x00\n<+" +
+	"08>-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfc\x19@\xb9r\x00\x00\x00r\x00\x00\x00\t\x00\x00\x00Etc/GMT-9TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00~\x90\x00\x00+09\x00\n<+09>-9\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00" +
+	"\x00o\x00\x00\x00\b\x00\x00\x00Etc/GMT0TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" +
+	"\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GM" +
+	"T\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\r\x00\x00\x00Etc/GreenwichTZif2\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4x" +
+	"o\x00\x00\x00o\x00\x00\x00\a\x00\x00\x00Etc/UCTTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00" +
+	"\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00" +
+	"UTC\x00\nUTC0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\a\x00\x00\x00Etc/UTCTZif2\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00\nUTC0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00" +
+	"o\x00\x00\x00\r\x00\x00\x00Etc/UniversalTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00" +
+	"\x00\x00UTC\x00\nUTC0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\b\x00\x00\x00Etc/ZuluTZif2\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00\nUTC0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o\xbc\x831O" +
+	"\x04\x00\x00O\x04\x00\x00\x10\x00\x00\x00Europe/AmsterdamTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00f\x00\x00\x00\x06\x00\x00" +
+	"\x00\x1a\xff\xff\xff\xffV\xb6\xdf\xe6\xff\xff\xff\xffm\xe8\xc8\x00\xff\xff\xff\xff\x98DI\x80\xff\xff\xff\xff\x9b\f%p\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff" +
+	"\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\x9f\xce\xf80\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1~\xbbp\xff\xff\xff\xff\xa2.\x12\xf0\xff\xff\xff\xff\xa3zL\xf0\xff\xff\xff\xff\xa45" +
+	"\x81\xf0\xff\xff\xff\xff\xa5^#p\xff\xff\xff\xff\xa6%5\xf0\xff\xff\xff\xff\xa7'\x9b\xf0\xff\xff\xff\xff\xa8*\x01\xf0\xff\xff\xff\xff\xa9\a}\xf0\xff\xff\xff\xff\xa9\xee4p\xff\xff\xff\xff\xaa\xe7_\xf0\xff\xff" +
+	"\xff\xff\xab\xd7P\xf0\xff\xff\xff\xff\xac\xc7A\xf0\xff\xff\xff\xff\xadɧ\xf0\xff\xff\xff\xff\xae\xa7#\xf0\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x05\xf0\xff\xff\xff\xff\xb1\x89k\xf0\xff\xff\xff\xff\xb2p" +
+	"L\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \xff\xff\xff\xff\xb60\x10\xa0\xff\xff\xff\xff\xb72v\xa0\xff\xff\xff\xff\xb8\x0f\xf2\xa0\xff\xff\xff\xff\xb8\xff\xe3\xa0\xff\xff" +
+	"\xff\xff\xb9\xefԠ\xff\xff\xff\xff\xba\u058b \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xc8\xe2 \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\x9f\x89\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b" +
+	"\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2h\x88 \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4?/\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff" +
+	"\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xc8J\x19 \xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r" +
+	"\x16\x10\xff\xff\xff\xff\xd2N@\x90\xff\xff\xff\xffӑ@\x10\xff\xff\xff\xff\xd4K#\x90\x00\x00\x00\x00\r\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00" +
+	"\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3" +
+	"\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00" +
+	"\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f" +
+	"\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00" +
+	"\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x03\x04\x03\x04\x03\x04\x03\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02" +
+	"\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" +
+	"\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x00\x00\x04\x1a\x00\x00\x00\x00\x04\x1a\x00\x04\x00\x00\x00\x00\x00\b\x00\x00\x0e\x10\x00\f\x00\x00\x1c \x01\x10\x00\x00\x0e\x10\x01\x15LMT\x00" +
+	"BMT\x00WET\x00CET\x00CEST\x00WEST\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00ߜvυ\x01\x00\x00\x85\x01\x00\x00\x0e\x00\x00\x00Europe/AndorraTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x19\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff~6\xb3\x94\xff\xff\xff\xff\xd4A\xdb\x00\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00" +
+	"\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C" +
+	"\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00" +
+	"\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00\x01l\x00\x00" +
+	"\x00\x00\x00\x00\x00\x04\x00\x00\x0e\x10\x00\b\x00\x00\x1c \x01\fLMT\x00WET\x00CET\x00CEST\x00\nCET-1CEST,M3.5.0,M10.5.0" +
+	"/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]i\x11u\xd6\x02\x00\x00\xd6\x02\x00\x00\x10\x00\x00\x00Europe/AstrakhanTZif2\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x18Et\xff\xff\xff\xff\xb5\xa4\vP\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00" +
+	"\x17\b\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a̅\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0" +
+	"\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\8\xe0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<\x1a\xe0\x00\x00\x00\x00$,\v\xe0\x00\x00\x00\x00" +
+	"%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp" +
+	"\x00\x00\x00\x00-\x94\xbep\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x00" +
+	"4Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0" +
+	"\x00\x00\x00\x00;\xdb<p\x00\x00\x00\x00<\xa6Cp\x00\x00\x00\x00=\xbb\x1ep\x00\x00\x00\x00>\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f\ap\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00" +
+	"BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05\xadp\x00\x00\x00\x00G#\xc2\xf0\x00\x00\x00\x00G\xee\xc9\xf0\x00\x00\x00\x00I\x03\xa4\xf0" +
+	"\x00\x00\x00\x00IΫ\xf0\x00\x00\x00\x00J\xe3\x86\xf0\x00\x00\x00\x00K\xae\x8d\xf0\x00\x00\x00\x00Ḷp\x00\x00\x00\x00M\x8eo\xf0\x00\x00\x00\x00TL\x1d`\x00\x00\x00\x00V\xf7\x14p\x01\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x04\x01\x03\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x03\x01\x03" +
+	"\x00\x00-\f\x00\x00\x00\x00*0\x00\x04\x00\x00FP\x01\b\x00\x008@\x00\f\x00\x008@\x01\fLMT\x00+03\x00+05\x00+04\x00\n<+04>-4\nPK\x03\x04\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcb*j\x8f\xaa\x02\x00\x00\xaa\x02\x00\x00\r\x00\x00\x00Europe/AthensTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x007\x00\x00\x00\x06\x00\x00\x00\x1a\xff\xff\xff\xfft?\x98D\xff\xff\xff\xff\x9b\x80!\x80\xff\xff\xff\xff\xb9|\xe9\xe0\xff\xff\xff\xff\xb9Ư\xd0\xff\xff\xff\xff\xc9\xf2c\xe0\xff\xff\xff\xff\xca\x10\xa8" +
+	"P\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͪL\xf0\xff\xff\xff\xff\u03a2\x18\xe0\xff\xff\xff\xffϓip\xff\xff\xff\xff\xdf\x13\x9e`\xff\xff\xff\xff߷\nP\x00\x00\x00\x00\t\xec^`\x00\x00\x00" +
+	"\x00\v\x18\xf4`\x00\x00\x00\x00\vͮ\x00\x00\x00\x00\x00\f\xbd\x9f\x00\x00\x00\x00\x00\r\xa4U\x80\x00\x00\x00\x00\x0e\x8c]\x80\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00\x10j\xfc\x10\x00\x00\x00\x00\x11d{" +
+	"\xf0\x00\x00\x00\x00\x12R\xaa\xf0\x00\x00\x00\x00\x13F\x82`\x00\x00\x00\x00\x143\xc2P\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00" +
+	"\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81" +
+	"\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00" +
+	"\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda" +
+	"\x90\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x05\x04\x05\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\x16<\x00\x00\x00\x00\x16<\x00\x04\x00\x00*0\x01\b\x00\x00\x1c \x00\r\x00\x00\x0e\x10\x00\x11\x00\x00" +
+	"\x1c \x01\x15LMT\x00AMT\x00EEST\x00EET\x00CET\x00CEST\x00\nEET-2EEST,M3.5.0/3,M10.5.0/4\n" +
+	"PK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\x0e\x00\x00\x00Europe/BelfastTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f\x00\x00\x00\x05\x00\x00\x00\x11\xff\xff\xff\xff\x1a]\t\xcb\xff\xff\xff\xff\x9b&\xad\xa0\xff\xff\xff\xff\x9b\xd6\x05 \xff\xff\xff\xff\x9c\xcf0\xa0\xff\xff\xff\xff\x9d\xa4à\xff" +
+	"\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff\xff\xff\xa0\x85\xba \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{Ƞ\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5" +
+	"?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00Ӡ\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 \xff" +
+	"\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \xff\xff\xff\xff\xb1\x92Р\xff\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3" +
+	"r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \xff\xff\xff\xff\xb60\x10\xa0\xff\xff\xff\xff\xb72v\xa0\xff\xff\xff\xff\xb8\x0f\xf2\xa0\xff\xff\xff\xff\xb9\x12X\xa0\xff\xff\xff\xff\xb9\xefԠ\xff" +
+	"\xff\xff\xff\xba\xe9\x00 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1" +
+	"x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7\xda\t\xa0\xff" +
+	"\xff\xff\xff\xca\x16&\x90\xff\xff\xff\xffʗY\x90\xff\xff\xff\xff\xcb\xd1\x1e\x90\xff\xff\xff\xff\xccw;\x90\xff\xff\xff\xffͱ\x00\x90\xff\xff\xff\xff\xce`X\x10\xff\xff\xff\xffϐ\xe2\x90\xff\xff\xff\xff\xd0" +
+	"n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xfb2\x10\xff\xff\xff\xff\xd2i\xfe \xff\xff\xff\xff\xd3c)\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd5B\xfd\x90\xff" +
+	"\xff\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd6\xfe\x03\xa0\xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb" +
+	"\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\u07b4\xea\xa0\xff\xff\xff\xff߮\x16 \xff\xff\xff\xff\xe0\x94̠\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt \xff" +
+	"\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4T\x90\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6=\xad \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\v \xff\xff\xff\xff\xe9" +
+	"\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\ue6b1 \xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f} \xff" +
+	"\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\x7f_ \xff\xff\xff\xff\xf3Jf \xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\r\xa0\xff\xff\xff\xff\xf6?# \xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8" +
+	"\x1f\x05 \xff\xff\xff\xff\xf8\xe0Ѡ\xff\xff\xff\xff\xf9\xfe\xe7 \xff\xff\xff\xff\xfa\xc0\xb3\xa0\xff\xff\xff\xff\xfb\xe8\x03\xa0\xff\xff\xff\xff\xfc{\xab\xa0\xff\xff\xff\xff\xfdǻp\x00\x00\x00\x00\x03p\xc6 \x00" +
+	"\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\t: \x00\x00\x00\x00\a0\x8a \x00\x00\x00\x00\a\xe9\x1c \x00\x00\x00\x00\t\x10l \x00\x00\x00\x00\t\xc8\xfe \x00\x00\x00\x00\n" +
+	"\xf0N \x00\x00\x00\x00\v\xb2\x1a\xa0\x00\x00\x00\x00\f\xd00 \x00\x00\x00\x00\r\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \x00\x00\x00\x00\x0fqޠ\x00\x00\x00\x00\x10\x99.\xa0\x00\x00\x00\x00\x11Q\xc0\xa0\x00" +
+	"\x00\x00\x00\x12y\x10\xa0\x00\x00\x00\x00\x131\xa2\xa0\x00\x00\x00\x00\x14X\xf2\xa0\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x168Ɛ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x18\x18\xa8\x90\x00\x00\x00\x00\x18" +
+	"㯐\x00\x00\x00\x00\x19\xf8\x8a\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xe1\xa7\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\xc1\x89\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f\xa1k\x10\x00" +
+	"\x00\x00\x00 lr\x10\x00\x00\x00\x00!\x81M\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#a/\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%JK\x90\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'" +
+	"*-\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00)\n\x0f\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xe9\xf1\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xc9Ӑ\x00\x00\x00\x00-\x94ڐ\x00" +
+	"\x00\x00\x00.\xa9\xb5\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000\x89\x97\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xff\xb5\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x00\x04LMT\x00BST\x00GMT\x00BDST\x00\nGM" +
+	"T0BST,M3.5.0/1,M10.5.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\x0f\x00\x00\x00Europe/" +
+	"BelgradeTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00T" +
+	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xff^<\xf0H\xff\xff\xff\xff\xca\x025\xe0\xff" +
+	"\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xffѡ\x8c\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\x18" +
+	"㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00" +
+	"\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'" +
+	"\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00" +
+	"\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x00\x00\x138\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\bLMT\x00CET\x00CEST\x00\nCET-1CEST,M3.5.0,M10." +
+	"5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17S\x91\xb3\xc1\x02\x00\x00\xc1\x02\x00\x00\r\x00\x00\x00Europe/BerlinTZif2\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xffo\xa2a\xf8\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff" +
+	"\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xc8\tq\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10" +
+	"\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xffѶ\x96\x00\xff\xff\xff\xff\xd2X\xbe\x80\xff\xff\xff\xffҡO\x10\xff\xff\xff\xff\xd3c\x1b\x90\xff\xff\xff\xff\xd4K#\x90\xff\xff\xff\xff" +
+	"\xd59\xd1 \xff\xff\xff\xff\xd5g\xe7\x90\xff\xff\xff\xffըs\x00\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xd9\x02\xc1\x90\xff\xff\xff\xff\xd9\xe9x\x10" +
+	"\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00" +
 	"\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10" +
 	"\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00" +
 	"'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː" +
-	"\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x00\x00\x138\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\bLMT\x00CET\x00CEST\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nP" +
-	"K\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe5\xc8X\xa7\xe1\x01\x00\x00\xe1\x01\x00\x00\x0f\x00\x1c\x00Europe/HelsinkiUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v" +
-	"\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00" +
-	"\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00#\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xffS\xba&\x9b\xff\xff\xff\xff\xa4" +
-	"so\x1b\xff\xff\xff\xff\xcb\xceQ`\xff\xff\xff\xff\xcc\xc0\xe5`\x00\x00\x00\x00\x15#݀\x00\x00\x00\x00\x16\x13\u0380\x00\x00\x00\x00\x17\x03\xbf\x80\x00\x00\x00\x00\x17\xf3\xb0\x80\x00\x00\x00\x00\x18㯐\x00" +
-	"\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 " +
-	"lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00" +
-	"\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00." +
-	"\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x00\x00\x17e\x00\x00\x00\x00\x17e\x00\x04\x00\x00*0\x01\b\x00\x00\x1c \x00\rLMT\x00HMT\x00EEST\x00EET\x00\nEET-2EEST,M3.5.0" +
-	"/3,M10.5.0/4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTWI\xc3\x7f(\x03\x00\x00(\x03\x00\x00\f\x00\x1c\x00Europe/MinskUT\t\x00\x03" +
-	"\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00D\x00\x00\x00\t\x00\x00\x00&\xff\xff" +
-	"\xff\xffV\xb6\xca(\xff\xff\xff\xff\xaa\x19\xaa8\xff\xff\xff\xff\xb5\xa4\x19`\xff\xff\xff\xff\xca^p\xd0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ" +
-	"4\x10\xff\xff\xff\xff\xd0\n\x02`\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00" +
-	"\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\" +
-	"F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd5\b\x80\x00\x00" +
-	"\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4ۀ\x00\x00\x00\x00-\x94̀\x00\x00\x00\x00.\x84\xbd\x80\x00\x00\x00\x00/t\xae\x80\x00\x00\x00\x000d\x9f\x80\x00\x00\x00\x001]" +
-	"\xcb\x00\x00\x00\x00\x002r\xa6\x00\x00\x00\x00\x003=\xad\x00\x00\x00\x00\x004R\x88\x00\x00\x00\x00\x005\x1d\x8f\x00\x00\x00\x00\x0062j\x00\x00\x00\x00\x006\xfdq\x00\x00\x00\x00\x008\x1b\x86\x80\x00\x00" +
-	"\x00\x008\xddS\x00\x00\x00\x00\x009\xfbh\x80\x00\x00\x00\x00:\xbd5\x00\x00\x00\x00\x00;\xdbJ\x80\x00\x00\x00\x00<\xa6Q\x80\x00\x00\x00\x00=\xbb,\x80\x00\x00\x00\x00>\x863\x80\x00\x00\x00\x00?\x9b" +
-	"\x0e\x80\x00\x00\x00\x00@f\x15\x80\x00\x00\x00\x00A\x84+\x00\x00\x00\x00\x00BE\xf7\x80\x00\x00\x00\x00Cd\r\x00\x00\x00\x00\x00D%ـ\x00\x00\x00\x00EC\xef\x00\x00\x00\x00\x00F\x05\xbb\x80\x00\x00" +
-	"\x00\x00G#\xd1\x00\x00\x00\x00\x00G\xee\xd8\x00\x00\x00\x00\x00I\x03\xb3\x00\x00\x00\x00\x00Iκ\x00\x00\x00\x00\x00J\xe3\x95\x00\x00\x00\x00\x00K\xae\x9c\x00\x00\x00\x00\x00Ḻ\x80\x00\x00\x00\x00M\x8e" +
-	"~\x00\x01\x02\x03\x05\x04\x05\x04\x05\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a" +
-	"\x02\a\x02\a\x02\a\x02\a\x02\b\x00\x00\x19\xd8\x00\x00\x00\x00\x19\xc8\x00\x04\x00\x00\x1c \x00\b\x00\x00*0\x00\f\x00\x00\x0e\x10\x00\x10\x00\x00\x1c \x01\x14\x00\x008@\x01\x19\x00\x00*0\x01\x1d\x00\x00" +
-	"*0\x00\"LMT\x00MMT\x00EET\x00MSK\x00CET\x00CEST\x00MSD\x00EEST\x00+03\x00\n<+03>-3\nPK\x03\x04\n\x00\x00\x00\x00" +
-	"\x00\x8fj\xbeT\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\r\x00\x1c\x00Europe/SkopjeUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_" +
-	"\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xff^<\xf0H\xff\xff\xff\xff\xca\x025\xe0\xff\xff\xff\xff\xcc\xe7K" +
-	"\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xffѡ\x8c\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00" +
-	"\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr" +
-	"\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00" +
-	"\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84\xcb" +
-	"\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x00\x00\x138\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\bLMT\x00CET\x00CEST\x00\nCET-1CEST,M3.5.0,M10.5.0/3\n" +
-	"PK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9a\v\xf9/\xd8\x05\x00\x00\xd8\x05\x00\x00\r\x00\x1c\x00Europe/DublinUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00" +
-	"\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00" +
-	"\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x91\x00\x00\x00\b\x00\x00\x00\x14\xff\xff\xff\xffW\xd1\n\xdc\xff\xff\xff\xff\x9b&" +
-	"\xb3\x91\xff\xff\xff\xff\x9b\xd6\v\x11\xff\xff\xff\xff\x9c\xcf0\xa0\xff\xff\xff\xff\x9d\xa4à\xff\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff\xff\xff\xa0\x85\xba \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff" +
-	"\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{Ƞ\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb" +
-	"\xf8\xa0\xff\xff\xff\xff\xaa\x00Ӡ\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff" +
-	"\xff\xff\xb0\x870 \xff\xff\xff\xff\xb1\x92Р\xff\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \xff\xff\xff\xff\xb60\x10\xa0\xff\xff\xff\xff\xb72" +
-	"v\xa0\xff\xff\xff\xff\xb8\x0f\xf2\xa0\xff\xff\xff\xff\xb9\x12X\xa0\xff\xff\xff\xff\xb9\xefԠ\xff\xff\xff\xff\xba\xe9\x00 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff" +
-	"\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58" +
-	"[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd7,( \xff\xff" +
-	"\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\u07b4" +
-	"\xea\xa0\xff\xff\xff\xff߮\x16 \xff\xff\xff\xff\xe0\x94̠\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt \xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4T\x90\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff" +
-	"\xff\xff\xe6=\xad \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\v \xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba" +
-	"\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\ue6b1 \xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\x7f_ \xff\xff\xff\xff\xf3Jf \xff\xff" +
-	"\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\r\xa0\xff\xff\xff\xff\xf6?# \xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0Ѡ\xff\xff\xff\xff\xf9\xfe\xe7 \xff\xff\xff\xff\xfa\xc0" +
-	"\xb3\xa0\xff\xff\xff\xff\xfb\xe8\x03\xa0\xff\xff\xff\xff\xfc{\xab\xa0\xff\xff\xff\xff\xfdǻp\x00\x00\x00\x00\x03p\xc6 \x00\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\t: \x00\x00" +
-	"\x00\x00\a0\x8a \x00\x00\x00\x00\a\xe9\x1c \x00\x00\x00\x00\t\x10l \x00\x00\x00\x00\t\xc8\xfe \x00\x00\x00\x00\n\xf0N \x00\x00\x00\x00\v\xb2\x1a\xa0\x00\x00\x00\x00\f\xd00 \x00\x00\x00\x00\r\x91" +
-	"\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \x00\x00\x00\x00\x0fqޠ\x00\x00\x00\x00\x10\x99.\xa0\x00\x00\x00\x00\x11Q\xc0\xa0\x00\x00\x00\x00\x12y\x10\xa0\x00\x00\x00\x00\x131\xa2\xa0\x00\x00\x00\x00\x14X\xf2\xa0\x00\x00" +
-	"\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x168Ɛ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x18\x18\xa8\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19\xf8\x8a\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xe1" +
-	"\xa7\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\xc1\x89\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f\xa1k\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\x81M\x10\x00\x00\x00\x00\"LT\x10\x00\x00" +
-	"\x00\x00#a/\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%JK\x90\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'*-\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00)\n\x0f\x90\x00\x00\x00\x00)\xd5" +
-	"\x16\x90\x00\x00\x00\x00*\xe9\xf1\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xc9Ӑ\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\xa9\xb5\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000\x89\x97\x90\x00\x00" +
-	"\x00\x001]\xd9\x10\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" +
-	"\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06" +
-	"\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\xff\xff\xfa$\x00\x00\xff\xff\xfa\x0f\x00\x04\x00\x00\b\x1f\x01\b\x00\x00\x0e\x10\x01\f\x00\x00\x00\x00\x00" +
-	"\x10\x00\x00\x0e\x10\x01\b\x00\x00\x00\x00\x01\x10\x00\x00\x0e\x10\x00\bLMT\x00DMT\x00IST\x00BST\x00GMT\x00\nIST-1GMT0,M10.5.0,M3" +
-	".5.0/1\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTk\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\r\x00\x1c\x00Europe/JerseyUT\t\x00\x03\xdd\xfc\x94b\xdd" +
-	"\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00" +
-	"\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f\x00\x00\x00\x05\x00\x00\x00\x11\xff\xff\xff\xff\x1a]\t" +
-	"\xcb\xff\xff\xff\xff\x9b&\xad\xa0\xff\xff\xff\xff\x9b\xd6\x05 \xff\xff\xff\xff\x9c\xcf0\xa0\xff\xff\xff\xff\x9d\xa4à\xff\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff\xff\xff\xa0\x85\xba \xff\xff\xff" +
-	"\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{Ƞ\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*," +
-	" \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00Ӡ\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff" +
-	"\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \xff\xff\xff\xff\xb1\x92Р\xff\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \xff\xff\xff\xff\xb60\x10" +
-	"\xa0\xff\xff\xff\xff\xb72v\xa0\xff\xff\xff\xff\xb8\x0f\xf2\xa0\xff\xff\xff\xff\xb9\x12X\xa0\xff\xff\xff\xff\xb9\xefԠ\xff\xff\xff\xff\xba\xe9\x00 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff" +
-	"\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4" +
-	"\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xca\x16&\x90\xff\xff\xff\xffʗY\x90\xff\xff\xff\xff\xcb\xd1\x1e\x90\xff\xff\xff" +
-	"\xff\xccw;\x90\xff\xff\xff\xffͱ\x00\x90\xff\xff\xff\xff\xce`X\x10\xff\xff\xff\xffϐ\xe2\x90\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xfb2\x10\xff\xff\xff\xff\xd2i\xfe" +
-	" \xff\xff\xff\xff\xd3c)\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd5B\xfd\x90\xff\xff\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd6\xfe\x03\xa0\xff\xff\xff" +
-	"\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\u07b4\xea" +
-	"\xa0\xff\xff\xff\xff߮\x16 \xff\xff\xff\xff\xe0\x94̠\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt \xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4T\x90\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff" +
-	"\xff\xe6=\xad \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\v \xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba\xcf" +
-	" \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\ue6b1 \xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\x7f_ \xff\xff\xff\xff\xf3Jf \xff\xff\xff" +
-	"\xff\xf4_A \xff\xff\xff\xff\xf5!\r\xa0\xff\xff\xff\xff\xf6?# \xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0Ѡ\xff\xff\xff\xff\xf9\xfe\xe7 \xff\xff\xff\xff\xfa\xc0\xb3" +
-	"\xa0\xff\xff\xff\xff\xfb\xe8\x03\xa0\xff\xff\xff\xff\xfc{\xab\xa0\xff\xff\xff\xff\xfdǻp\x00\x00\x00\x00\x03p\xc6 \x00\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\t: \x00\x00\x00" +
-	"\x00\a0\x8a \x00\x00\x00\x00\a\xe9\x1c \x00\x00\x00\x00\t\x10l \x00\x00\x00\x00\t\xc8\xfe \x00\x00\x00\x00\n\xf0N \x00\x00\x00\x00\v\xb2\x1a\xa0\x00\x00\x00\x00\f\xd00 \x00\x00\x00\x00\r\x91\xfc" +
-	"\xa0\x00\x00\x00\x00\x0e\xb0\x12 \x00\x00\x00\x00\x0fqޠ\x00\x00\x00\x00\x10\x99.\xa0\x00\x00\x00\x00\x11Q\xc0\xa0\x00\x00\x00\x00\x12y\x10\xa0\x00\x00\x00\x00\x131\xa2\xa0\x00\x00\x00\x00\x14X\xf2\xa0\x00\x00\x00" +
-	"\x00\x15#\xeb\x90\x00\x00\x00\x00\x168Ɛ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x18\x18\xa8\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19\xf8\x8a\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xe1\xa7" +
-	"\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\xc1\x89\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f\xa1k\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\x81M\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00" +
-	"\x00#a/\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%JK\x90\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'*-\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00)\n\x0f\x90\x00\x00\x00\x00)\xd5\x16" +
-	"\x90\x00\x00\x00\x00*\xe9\xf1\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xc9Ӑ\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\xa9\xb5\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000\x89\x97\x90\x00\x00\x00" +
-	"\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x03\x01\x03" +
-	"\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xff\xb5\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00" +
-	"\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x00\x04LMT\x00BST\x00GMT\x00BDST\x00\nGMT0BST,M3.5.0/1,M10.5.0\nPK\x03" +
-	"\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x95\xb4\x9e\xe7\xb3\x03\x00\x00\xb3\x03\x00\x00\x11\x00\x1c\x00Europe/San_MarinoUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v" +
-	"\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00" +
-	"\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00W\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff>(\xe8L\xff\xff\xff\xffp" +
-	"\xbc\x81p\xff\xff\xff\xff\x9b8\xf8p\xff\xff\xff\xff\x9b\xd5\xcc\xe0\xff\xff\xff\xff\x9c\xc5\xcb\xf0\xff\xff\xff\xff\x9d\xb7\x00`\xff\xff\xff\xff\x9e\x89\xfep\xff\xff\xff\xff\x9f\xa0\x1c\xe0\xff\xff\xff\xff\xa0`\xa5\xf0\xff" +
-	"\xff\xff\xff\xa1~\xad`\xff\xff\xff\xff\xa2\\7p\xff\xff\xff\xff\xa3L\x1a`\xff\xff\xff\xff\xc8l5\xf0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xff\xcf" +
-	"\x924\x10\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2L\xd2\xf0\xff\xff\xff\xff\xd3>1\x90\xff\xff\xff\xff\xd4I\xd2\x10\xff\xff\xff\xff\xd5\x1d\xf7p\xff\xff\xff\xff\xd6)\x97\xf0\xff" +
-	"\xff\xff\xff\xd6뀐\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xf93\xb5\xf0\xff\xff\xff\xff\xf9\xd9\xc4\xe0\xff\xff\xff\xff\xfb\x1c\xd2p\xff\xff\xff\xff\xfb\xb9\xb4\xf0\xff\xff\xff\xff\xfc\xfc\xb4p\xff\xff\xff\xff\xfd" +
-	"\x99\x96\xf0\xff\xff\xff\xff\xfe\xe5\xd0\xf0\xff\xff\xff\xff\xff\x82\xb3p\x00\x00\x00\x00\x00Ų\xf0\x00\x00\x00\x00\x01b\x95p\x00\x00\x00\x00\x02\x9cZp\x00\x00\x00\x00\x03Bwp\x00\x00\x00\x00\x04\x85v\xf0\x00" +
-	"\x00\x00\x00\x05+\x93\xf0\x00\x00\x00\x00\x06n\x93p\x00\x00\x00\x00\a\vu\xf0\x00\x00\x00\x00\bE:\xf0\x00\x00\x00\x00\b\xebW\xf0\x00\x00\x00\x00\n.Wp\x00\x00\x00\x00\n\xcb9\xf0\x00\x00\x00\x00\f" +
-	"\x0e9p\x00\x00\x00\x00\f\xab\x1b\xf0\x00\x00\x00\x00\r\xe4\xe0\xf0\x00\x00\x00\x00\x0e\x8a\xfd\xf0\x00\x00\x00\x00\x0f\xcd\xfdp\x00\x00\x00\x00\x10t\x1ap\x00\x00\x00\x00\x11\xad\xdfp\x00\x00\x00\x00\x12S\xfcp\x00" +
-	"\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19" +
-	"Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00" +
-	"\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'" +
-	"\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00" +
-	"\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\v\xb4\x00\x00\x00\x00\v\xb4" +
-	"\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\rLMT\x00RMT\x00CEST\x00CET\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nP" +
-	"K\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT==\xa4\x16\xc4\x04\x00\x00\xc4\x04\x00\x00\x10\x00\x1c\x00Europe/GibraltarUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux" +
-	"\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00" +
-	"\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00s\x00\x00\x00\x06\x00\x00\x00\x1a\xff\xff\xff\xffW\xd1\n\x04\xff\xff\xff\xff" +
-	"\x9b&\xad\xa0\xff\xff\xff\xff\x9b\xd6\x05 \xff\xff\xff\xff\x9c\xcf0\xa0\xff\xff\xff\xff\x9d\xa4à\xff\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff\xff\xff\xa0\x85\xba \xff\xff\xff\xff\xa1v\xfc\xa0" +
-	"\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{Ƞ\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff" +
-	"\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00Ӡ\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0" +
-	"\xff\xff\xff\xff\xb0\x870 \xff\xff\xff\xff\xb1\x92Р\xff\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \xff\xff\xff\xff\xb60\x10\xa0\xff\xff\xff\xff" +
-	"\xb72v\xa0\xff\xff\xff\xff\xb8\x0f\xf2\xa0\xff\xff\xff\xff\xb9\x12X\xa0\xff\xff\xff\xff\xb9\xefԠ\xff\xff\xff\xff\xba\xe9\x00 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 " +
-	"\xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff" +
-	"\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xca\x16&\x90\xff\xff\xff\xffʗY\x90\xff\xff\xff\xff\xcb\xd1\x1e\x90\xff\xff\xff\xff\xccw;\x90" +
-	"\xff\xff\xff\xffͱ\x00\x90\xff\xff\xff\xff\xce`X\x10\xff\xff\xff\xffϐ\xe2\x90\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xfb2\x10\xff\xff\xff\xff\xd2i\xfe \xff\xff\xff\xff" +
-	"\xd3c)\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd5B\xfd\x90\xff\xff\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd6\xfe\x03\xa0\xff\xff\xff\xff\xd8.\x8e " +
-	"\xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\u07b4\xea\xa0\xff\xff\xff\xff" +
-	"߮\x16 \xff\xff\xff\xff\xe0\x94̠\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt \xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4T\x90\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6=\xad " +
-	"\xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00" +
-	"\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10" +
-	"\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00" +
-	")\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90" +
-	"\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01" +
-	"\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" +
-	"\x05\x04\x05\xff\xff\xfa\xfc\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x00\x11\x00\x00\x1c \x01\x15LMT\x00BST\x00GMT\x00BDST\x00CET\x00" +
-	"CEST\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\x0f" +
-	"\x00\x1c\x00Europe/BelgradeUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xff^<\xf0H\xff\xff\xff\xff\xca\x025\xe0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C" +
-	"\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xffѡ\x8c\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00" +
-	"\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT" +
-	"\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00" +
-	"\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad" +
-	"\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x138\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x1c" +
-	" \x01\bLMT\x00CET\x00CEST\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTk\xa4" +
-	",\xb6?\x06\x00\x00?\x06\x00\x00\x0f\x00\x1c\x00Europe/GuernseyUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZi" +
-	"f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f\x00\x00\x00\x05\x00\x00\x00\x11\xff\xff\xff\xff\x1a]\t\xcb\xff\xff\xff\xff\x9b&\xad\xa0\xff\xff\xff\xff\x9b\xd6\x05 \xff\xff\xff\xff" +
-	"\x9c\xcf0\xa0\xff\xff\xff\xff\x9d\xa4à\xff\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff\xff\xff\xa0\x85\xba \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{Ƞ" +
-	"\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00Ӡ\xff\xff\xff\xff" +
-	"\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \xff\xff\xff\xff\xb1\x92Р" +
-	"\xff\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \xff\xff\xff\xff\xb60\x10\xa0\xff\xff\xff\xff\xb72v\xa0\xff\xff\xff\xff\xb8\x0f\xf2\xa0\xff\xff\xff\xff" +
-	"\xb9\x12X\xa0\xff\xff\xff\xff\xb9\xefԠ\xff\xff\xff\xff\xba\xe9\x00 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 " +
-	"\xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff" +
-	"\xc7X֠\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xca\x16&\x90\xff\xff\xff\xffʗY\x90\xff\xff\xff\xff\xcb\xd1\x1e\x90\xff\xff\xff\xff\xccw;\x90\xff\xff\xff\xffͱ\x00\x90\xff\xff\xff\xff\xce`X\x10" +
-	"\xff\xff\xff\xffϐ\xe2\x90\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xfb2\x10\xff\xff\xff\xff\xd2i\xfe \xff\xff\xff\xff\xd3c)\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff" +
-	"\xd5\x1e!\xa0\xff\xff\xff\xff\xd5B\xfd\x90\xff\xff\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd6\xfe\x03\xa0\xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep " +
-	"\xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\u07b4\xea\xa0\xff\xff\xff\xff߮\x16 \xff\xff\xff\xff\xe0\x94̠\xff\xff\xff\xff" +
-	"\xe1rH\xa0\xff\xff\xff\xff\xe2kt \xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4T\x90\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6=\xad \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0" +
-	"\xff\xff\xff\xff\xe8\xfb\v \xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\ue6b1 \xff\xff\xff\xff" +
-	"\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\x7f_ \xff\xff\xff\xff\xf3Jf \xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\r\xa0\xff\xff\xff\xff\xf6?# " +
-	"\xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0Ѡ\xff\xff\xff\xff\xf9\xfe\xe7 \xff\xff\xff\xff\xfa\xc0\xb3\xa0\xff\xff\xff\xff\xfb\xe8\x03\xa0\xff\xff\xff\xff\xfc{\xab\xa0\xff\xff\xff\xff" +
-	"\xfdǻp\x00\x00\x00\x00\x03p\xc6 \x00\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\t: \x00\x00\x00\x00\a0\x8a \x00\x00\x00\x00\a\xe9\x1c \x00\x00\x00\x00\t\x10l " +
-	"\x00\x00\x00\x00\t\xc8\xfe \x00\x00\x00\x00\n\xf0N \x00\x00\x00\x00\v\xb2\x1a\xa0\x00\x00\x00\x00\f\xd00 \x00\x00\x00\x00\r\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \x00\x00\x00\x00\x0fqޠ\x00\x00\x00\x00" +
-	"\x10\x99.\xa0\x00\x00\x00\x00\x11Q\xc0\xa0\x00\x00\x00\x00\x12y\x10\xa0\x00\x00\x00\x00\x131\xa2\xa0\x00\x00\x00\x00\x14X\xf2\xa0\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x168Ɛ\x00\x00\x00\x00\x17\x03͐" +
-	"\x00\x00\x00\x00\x18\x18\xa8\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19\xf8\x8a\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xe1\xa7\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\xc1\x89\x10\x00\x00\x00\x00" +
-	"\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f\xa1k\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\x81M\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#a/\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%JK\x90" +
-	"\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'*-\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00)\n\x0f\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xe9\xf1\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00" +
-	",\xc9Ӑ\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\xa9\xb5\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000\x89\x97\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xff\xb5\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x00\x04LMT\x00BST" +
-	"\x00GMT\x00BDST\x00\nGMT0BST,M3.5.0/1,M10.5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTu\xb0\xcd\xfc\xf8\x02\x00\x00\xf8\x02" +
-	"\x00\x00\x10\x00\x1c\x00Europe/UlyanovskUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x00\x00\x00\a\x00\x00\x00\x14\xff\xff\xff\xff\xa1\x009\x80\xff\xff\xff\xff\xb5\xa4\vP\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00" +
-	"\x00\x17\b\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a̅\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct" +
-	"\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\8\xe0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<\x1a\xe0\x00\x00\x00\x00$,\v\xe0\x00\x00\x00" +
-	"\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)x\xbf\x80\x00\x00\x00\x00)\xd4\xfap\x00\x00\x00\x00*\xc4\xeb" +
-	"p\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x94\xbep\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00" +
-	"\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD" +
-	"\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb<p\x00\x00\x00\x00<\xa6Cp\x00\x00\x00\x00=\xbb\x1ep\x00\x00\x00\x00>\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00" +
-	"\x00@f\ap\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05\xadp\x00\x00\x00\x00G#\xc2" +
-	"\xf0\x00\x00\x00\x00G\xee\xc9\xf0\x00\x00\x00\x00I\x03\xa4\xf0\x00\x00\x00\x00IΫ\xf0\x00\x00\x00\x00J\xe3\x86\xf0\x00\x00\x00\x00K\xae\x8d\xf0\x00\x00\x00\x00Ḷp\x00\x00\x00\x00M\x8eo\xf0\x00\x00\x00" +
-	"\x00TL\x1d`\x00\x00\x00\x00V\xf7\x14p\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x04\x01\x05\x06\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01" +
-	"\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x03\x01\x03\x00\x00-`\x00\x00\x00\x00*0\x00\x04\x00\x00FP\x01\b\x00\x008@\x00\f\x00\x008@\x01\f\x00\x00*0\x01\x04\x00\x00\x1c \x00" +
-	"\x10LMT\x00+03\x00+05\x00+04\x00+02\x00\n<+04>-4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x1b8\xfel\xd6\x02\x00\x00\xd6\x02\x00\x00\x0e\x00\x1c\x00" +
-	"Europe/SaratovUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xa1\x009\x80\xff\xff\xff\xff\xb5\xa4\vP\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\b\xcd@\x00\x00\x00" +
-	"\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a̅\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce" +
-	"\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\8\xe0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00" +
-	"\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x94\xbe" +
-	"p\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00" +
-	"\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb<" +
-	"p\x00\x00\x00\x00<\xa6Cp\x00\x00\x00\x00=\xbb\x1ep\x00\x00\x00\x00>\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f\ap\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00" +
-	"\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05\xadp\x00\x00\x00\x00G#\xc2\xf0\x00\x00\x00\x00G\xee\xc9\xf0\x00\x00\x00\x00I\x03\xa4\xf0\x00\x00\x00\x00IΫ" +
-	"\xf0\x00\x00\x00\x00J\xe3\x86\xf0\x00\x00\x00\x00K\xae\x8d\xf0\x00\x00\x00\x00Ḷp\x00\x00\x00\x00M\x8eo\xf0\x00\x00\x00\x00TL\x1d`\x00\x00\x00\x00XCNp\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x04\x01\x04\x01\x04\x01\x03\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x03\x01\x03\x00\x00+2\x00\x00\x00" +
-	"\x00*0\x00\x04\x00\x00FP\x01\b\x00\x008@\x00\f\x00\x008@\x01\fLMT\x00+03\x00+05\x00+04\x00\n<+04>-4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj" +
-	"\xbeTDd#\xc4\xf1\x01\x00\x00\xf1\x01\x00\x00\f\x00\x1c\x00Europe/VaduzUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZ" +
-	"if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00%\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff$\xf0\xea\x80\xff\xff\xff\xffq\xd4\x06\x86\xff\xff\xff\xff\xca\x17j\x00\xff\xff\xff" +
-	"\xff\xca\xe2q\x00\xff\xff\xff\xff\xcb\xf7L\x00\xff\xff\xff\xff\xcc\xc2S\x00\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf" +
-	"\x90\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00" +
-	"\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C" +
-	"\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00" +
-	"\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x00\x00\b\x00\x00\x00\x00\x00\x06\xfa\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\rLMT\x00BMT\x00CEST\x00CET\x00\nCET-1CEST,M3" +
-	".5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\aW\x10Ѱ\x04\x00\x00\xb0\x04\x00\x00\x0f\x00\x1c\x00Europe/Istanbul" +
-	"UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00s\x00\x00\x00\x06\x00" +
-	"\x00\x00\x19\xff\xff\xff\xffV\xb6\xc8\xd8\xff\xff\xff\xff\x90\x8b\xf5\x98\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9bվ\xd0\xff\xff\xff\xff\xa2ec\xe0\xff\xff\xff\xff\xa3{\x82P\xff\xff\xff\xff\xa4N\x80`\xff" +
-	"\xff\xff\xff\xa5?\xb4\xd0\xff\xff\xff\xff\xa6%'\xe0\xff\xff\xff\xff\xa7'\x7f\xd0\xff\xff\xff\xff\xaa((`\xff\xff\xff\xff\xaa\xe1\xfd\xd0\xff\xff\xff\xff\xab\xf9\x89\xe0\xff\xff\xff\xff\xac\xc31P\xff\xff\xff\xff\xc8" +
-	"\x81?\xe0\xff\xff\xff\xff\xc9\x01\x13P\xff\xff\xff\xff\xc9J\xf5`\xff\xff\xff\xff\xca\u0380P\xff\xff\xff\xff\xcbˮ`\xff\xff\xff\xff\xd2k\tP\xff\xff\xff\xffӢ9`\xff\xff\xff\xff\xd4C\x02P\xff" +
-	"\xff\xff\xff\xd5L\r\xe0\xff\xff\xff\xff\xd6){\xd0\xff\xff\xff\xff\xd7+\xef\xe0\xff\xff\xff\xff\xd8\t]\xd0\xff\xff\xff\xff\xd9\x02\x97`\xff\xff\xff\xff\xd9\xe9?\xd0\xff\xff\xff\xff\xda\xeb\xb3\xe0\xff\xff\xff\xff\xdb" +
-	"\xd2\\P\xff\xff\xff\xff\xdc\xd4\xd0`\xff\xff\xff\xffݲ>P\xff\xff\xff\xff\xf1\xf4\xb9`\xff\xff\xff\xff\xf4b\xefP\xff\xff\xff\xff\xf5h\x06`\xff\xff\xff\xff\xf6\x1f8\xd0\x00\x00\x00\x00\x06n\x93p\x00" +
-	"\x00\x00\x00\a9\x9ap\x00\x00\x00\x00\a\xfbu\x00\x00\x00\x00\x00\t\x19|p\x00\x00\x00\x00\t\xd0\xcb\x00\x00\x00\x00\x00\n\xf9^p\x00\x00\x00\x00\v\xb1\xfe\x80\x00\x00\x00\x00\f\xd9@p\x00\x00\x00\x00\r" +
-	"\xa4U\x80\x00\x00\x00\x00\x0e\xa6\xadp\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00\x0f\xf8\x11P\x00\x00\x00\x00\x19\x89\xb0p\x00\x00\x00\x00\x19ܰ\xe0\x00\x00\x00\x00\x1b\xe6\xd0\xf0\x00\x00\x00\x00\x1c\xc6\xef\xf0\x00" +
-	"\x00\x00\x00\x1d\x9b1p\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$" +
-	",\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00(\xe5\tp\x00\x00\x00\x00)\xd4\xfap\x00\x00\x00\x00*\xc4\xebp\x00" +
-	"\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x8b\x83\xf0\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002" +
-	"r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00" +
-	"\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb<p\x00\x00\x00\x00<\xa6Cp\x00\x00\x00\x00=\xbb\x1ep\x00\x00\x00\x00>\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@" +
-	"f\ap\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00" +
-	"\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8fݐ\x00\x00\x00\x00N" +
-	"\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S8\xbe\x10\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00" +
-	"\x00\x00\x00V>\x9e\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00W\xcf.P\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
-	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x00\x00\x1b(\x00\x00\x00\x00\x1bh\x00\x04\x00\x00*0\x01\b\x00\x00\x1c \x00\r\x00\x00*0\x00\x11\x00\x008@\x01\x15LMT\x00IM" +
-	"T\x00EEST\x00EET\x00+03\x00+04\x00\n<+03>-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT&S\x03\t\xae\x05\x00\x00\xae\x05\x00\x00\r\x00\x1c\x00Eu" +
-	"rope/LisbonUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x8d\x00\x00\x00\x06\x00\x00\x00\x1b\xff\xff\xff\xff^=\f\x1d\xff\xff\xff\xff\x92掀\xff\xff\xff\xff\x9bKmp\xff\xff\xff\xff\x9b\xfeǀ\xff\xff\xff\xff\x9c\x9c\xedp\xff\xff\xff\xff\x9d\xc9" +
-	"\x83p\xff\xff\xff\xff\x9e\x7frp\xff\xff\xff\xff\x9f\xaa\xb6\xf0\xff\xff\xff\xff\xa0_Tp\xff\xff\xff\xff\xa1\x8b\xeap\xff\xff\xff\xff\xa2A\xd9p\xff\xff\xff\xff\xa3nop\xff\xff\xff\xff\xa4#\f\xf0\xff\xff" +
-	"\xff\xff\xa5O\xa2\xf0\xff\xff\xff\xff\xaa\x05\xefp\xff\xff\xff\xff\xaa\xf4\x8e\xf0\xff\xff\xff\xff\xadɧ\xf0\xff\xff\xff\xff\xae\xa7#\xf0\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x05\xf0\xff\xff\xff\xff\xb1\x89" +
-	"k\xf0\xff\xff\xff\xff\xb2p\"p\xff\xff\xff\xff\xb3r\x88p\xff\xff\xff\xff\xb4P\x04p\xff\xff\xff\xff\xb72Lp\xff\xff\xff\xff\xb8\x0f\xc8p\xff\xff\xff\xff\xb8\xff\xb9p\xff\xff\xff\xff\xb9\xef\xaap\xff\xff" +
-	"\xff\xff\xbcȷ\xf0\xff\xff\xff\xff\xbd\xb8\xa8\xf0\xff\xff\xff\xff\xbe\x9f_p\xff\xff\xff\xff\xbf\x98\x8a\xf0\xff\xff\xff\xff\xc0\x9a\xf0\xf0\xff\xff\xff\xff\xc1xl\xf0\xff\xff\xff\xff\xc2h]\xf0\xff\xff\xff\xff\xc3X" +
-	"N\xf0\xff\xff\xff\xff\xc4?\x05p\xff\xff\xff\xff\xc580\xf0\xff\xff\xff\xff\xc6:\x96\xf0\xff\xff\xff\xff\xc7X\xacp\xff\xff\xff\xff\xc7\xd9\xdfp\xff\xff\xff\xff\xc9\x01/p\xff\xff\xff\xff\xc9\xf1 p\xff\xff" +
-	"\xff\xff\xca\xe2b\xf0\xff\xff\xff\xff˵R\xf0\xff\xff\xff\xff\xcb\xec\xa3\xe0\xff\xff\xff\xff̀K\xe0\xff\xff\xff\xff\xccܢ\xf0\xff\xff\xff\xff͕4\xf0\xff\xff\xff\xff\xcd\xc3K`\xff\xff\xff\xff\xcer" +
-	"\xa2\xe0\xff\xff\xff\xff\xceſp\xff\xff\xff\xff\xcfu\x16\xf0\xff\xff\xff\xffϬg\xe0\xff\xff\xff\xff\xd0R\x84\xe0\xff\xff\xff\xffХ\xa1p\xff\xff\xff\xff\xd1T\xf8\xf0\xff\xff\xff\xffьI\xe0\xff\xff" +
-	"\xff\xff\xd22f\xe0\xff\xff\xff\xff҅\x83p\xff\xff\xff\xff\xd3Y\xc4\xf0\xff\xff\xff\xff\xd4I\xb5\xf0\xff\xff\xff\xff\xd59\xd1 \xff\xff\xff\xff\xd6)\xc2 \xff\xff\xff\xff\xd7\x19\xb3 \xff\xff\xff\xff\xd8\t" +
-	"\xa4 \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xd9\xe9\x86 \xff\xff\xff\xff\xda\xd9w \xff\xff\xff\xff\xdb\xc9h \xff\xff\xff\xffܹY \xff\xff\xff\xffݲ\x84\xa0\xff\xff\xff\xffޢu\xa0\xff\xff" +
-	"\xff\xffߒf\xa0\xff\xff\xff\xff\xe0\x82W\xa0\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2b9\xa0\xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4B\x1b\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6!" +
-	"\xfd\xa0\xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\v\x1a \xff\xff\xff\xff\xe8\xfb\v \xff\xff\xff\xff\xe9\xea\xfc \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xca\xde \xff\xff\xff\xff\xec\xba\xcf \xff\xff" +
-	"\xff\xff\xed\xaa\xc0 \xff\xff\xff\xff\ue6b1 \xff\xff\xff\xff\uf2a2 \xff\xff\xff\xff\xf0z\x93 \xff\xff\xff\xff\xf1j\x84 \xff\xff\xff\xff\xf2c\xaf\xa0\xff\xff\xff\xff\xf3S\xa0\xa0\xff\xff\xff\xff\xf4C" +
-	"\x91\xa0\xff\xff\xff\xff\xf53\x82\xa0\xff\xff\xff\xff\xf6#s\xa0\xff\xff\xff\xff\xf7\x13d\xa0\xff\xff\xff\xff\xf8\x03U\xa0\xff\xff\xff\xff\xf8\xf3F\xa0\x00\x00\x00\x00\f\xab*\x00\x00\x00\x00\x00\r\x9b\x1b\x00\x00\x00" +
-	"\x00\x00\x0e\x8b\f\x00\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00\x10t(\x80\x00\x00\x00\x00\x11d\x19\x80\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13C\xfb\x80\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#" +
-	"\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㽠\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00" +
-	"\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<" +
-	"E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00" +
-	"\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]" +
-	"\xd9\x10\x00\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x02\x01\x03\x01\x02\x01\x03\x01\x02\x01\x03" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x05\x04\x05\x04\x05\x04\x01\xff\xff\xf7c\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\t\x00\x00\x1c \x01\r\x00\x00\x0e\x10\x00\x12\x00\x00\x1c \x01\x16L" +
-	"MT\x00WEST\x00WET\x00WEMT\x00CET\x00CEST\x00\nWET0WEST,M3.5.0/1,M10.5.0\nPK\x03\x04\n\x00\x00" +
-	"\x00\x00\x00\x8fj\xbeT\xda\xc0\x86\xd2\x1b\x02\x00\x00\x1b\x02\x00\x00\x0f\x00\x1c\x00Europe/UzhgorodUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b" +
-	"\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZi" +
-	"f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&\x00\x00\x00\a\x00\x00\x00\x1e\xff\xff\xff\xffj\xee\xb0\x18\xff\xff\xff\xff\xc8\tq\x90\xff\xff\xff" +
-	"\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffС\x9e\xe0\xff\xff\xff\xff\xd1\xe5\xfd\xf0\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc" +
-	"@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00" +
-	"\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19" +
-	"\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\x8d.\xf0\x00\x00\x00\x00'\xf5B\xa0\x00\x00\x00\x00)\xd5\b\x80\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4ۀ\x00\x00\x00" +
-	"\x00-\x94̀\x00\x00\x00\x00.\x84\xbd\x80\x00\x00\x00\x00/t\xae\x80\x00\x00\x00\x000d\x9f\x80\x00\x00\x00\x001]\xcb\x00\x00\x00\x00\x002r\xb4\x10\x01\x02\x01\x02\x01\x02\x01\x04\x03\x04\x03\x04\x03\x04\x03" +
-	"\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x01\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x00\x00\x14\xe8\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\b\x00\x008@\x01\r\x00\x00*0\x00\x11\x00\x00\x1c \x00\x15\x00" +
-	"\x00*0\x01\x19LMT\x00CET\x00CEST\x00MSD\x00MSK\x00EET\x00EEST\x00\nEET-2EEST,M3.5.0/3,M10.5" +
-	".0/4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe0\xfe\x83\xe5\xcd\x02\x00\x00\xcd\x02\x00\x00\f\x00\x1c\x00Europe/KirovUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94b" +
-	"ux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00" +
-	"\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xa1\x009\x80\xff\xff" +
-	"\xff\xff\xb5\xa4\vP\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\b\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a\xcc" +
-	"\x85\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\8\xe0\x00\x00" +
-	"\x00\x00\"L)\xe0\x00\x00\x00\x00#<\x1a\xe0\x00\x00\x00\x00$,\v\xe0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00)\xd4" +
-	"\xec`\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x94\xbep\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00" +
-	"\x00\x001]\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1b" +
-	"xp\x00\x00\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb<p\x00\x00\x00\x00<\xa6Cp\x00\x00\x00\x00=\xbb\x1ep\x00\x00\x00\x00>\x86%p\x00\x00" +
-	"\x00\x00?\x9b\x00p\x00\x00\x00\x00@f\ap\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05" +
-	"\xadp\x00\x00\x00\x00G#\xc2\xf0\x00\x00\x00\x00G\xee\xc9\xf0\x00\x00\x00\x00I\x03\xa4\xf0\x00\x00\x00\x00IΫ\xf0\x00\x00\x00\x00J\xe3\x86\xf0\x00\x00\x00\x00K\xae\x8d\xf0\x00\x00\x00\x00Ḷp\x00\x00" +
-	"\x00\x00M\x8eo\xf0\x00\x00\x00\x00TL\x1d`\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x04\x01\x03\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04" +
-	"\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x03\x01\x00\x00.\x98\x00\x00\x00\x00*0\x00\x04\x00\x00FP\x01\b\x00\x008@\x00\f\x00\x008@\x01\fLMT\x00+03\x00+05\x00+" +
-	"04\x00\n<+03>-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xea\xc48\xde\\\x02\x00\x00\\\x02\x00\x00\r\x00\x1c\x00Europe/TiraneUT\t\x00\x03" +
-	"\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x002\x00\x00\x00\x03\x00\x00\x00\r\xff\xff" +
-	"\xff\xff\x96\xaa4h\xff\xff\xff\xff\xc8m\x87p\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u0378\xe9\x90\x00\x00\x00\x00\b(9\xf0\x00\x00\x00\x00\b\xef>`\x00\x00\x00\x00\n\x05" +
-	"x\xf0\x00\x00\x00\x00\n\xd0q\xe0\x00\x00\x00\x00\v\xe9Op\x00\x00\x00\x00\f\xb4H`\x00\x00\x00\x00\r\xd2k\xf0\x00\x00\x00\x00\x0e\x94*`\x00\x00\x00\x00\x0f\xb0\xfcp\x00\x00\x00\x00\x10t\f`\x00\x00" +
-	"\x00\x00\x11\x90\xdep\x00\x00\x00\x00\x12S\xee`\x00\x00\x00\x00\x13p\xc0p\x00\x00\x00\x00\x14;\xb9`\x00\x00\x00\x00\x15H\xb9p\x00\x00\x00\x00\x16\x13\xb2`\x00\x00\x00\x00\x171\xd5\xf0\x00\x00\x00\x00\x17\xfc" +
-	"\xce\xe0\x00\x00\x00\x00\x19\x00\x94p\x00\x00\x00\x00\x19\xdb_`\x00\x00\x00\x00\x1a̯\xf0\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00" +
-	"\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f" +
-	"\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00" +
-	"\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x12\x98\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\bLMT\x00CET\x00CEST\x00\n" +
-	"CET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTI\xb8\xbc\xd3\xf3\x02\x00\x00\xf3\x02\x00\x00\x0f\x00\x1c\x00Eur" +
-	"ope/TiraspolUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00<\x00\x00\x00\t\x00\x00\x00&\xff\xff\xff\xffV\xb6\xc8\xf8\xff\xff\xff\xff\x9ek\x9f\f\xff\xff\xff\xff\xb7\xb0\xd2\b\xff\xff\xff\xff\xb9>\xf3`\xff\xff\xff\xff\xb9\xef\x9c`\xff\xff\xff\xff\xba" +
-	"ߍ`\xff\xff\xff\xff\xbb\xcf~`\xff\xff\xff\xff\xbcȩ\xe0\xff\xff\xff\xff\xbd\xb8\x9a\xe0\xff\xff\xff\xff\xbe\xa8\x8b\xe0\xff\xff\xff\xff\xbf\x98|\xe0\xff\xff\xff\xff\xc0\x88m\xe0\xff\xff\xff\xff\xc1x^\xe0\xff" +
-	"\xff\xff\xff\xc2hO\xe0\xff\xff\xff\xff\xc3X@\xe0\xff\xff\xff\xff\xc4H1\xe0\xff\xff\xff\xff\xc58\"\xe0\xff\xff\xff\xff\xc6(\x13\xe0\xff\xff\xff\xff\xc7\x18\x04\xe0\xff\xff\xff\xffȼ\x93`\xff\xff\xff\xff\xca" +
-	"w}P\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xff\xd0N\x90`\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00" +
-	"\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d" +
-	"\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00" +
-	"\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00&CL\xe0\x00\x00\x00\x00'\x055\x80\x00\x00\x00\x00'\xf5&\x80\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*" +
-	"\xc4\xcfP\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000duP\x00\x00\x00\x001]\xae\xe0\x00" +
-	"\x00\x00\x002r{\xd0\x00\x00\x00\x003=\xad\x00\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x06\x05\x06\x05\x06\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a" +
-	"\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x1b\b\x00\x00\x00\x00\x1a\xf4\x00\x04\x00\x00\x18x\x00\b\x00\x00*0\x01\f\x00\x00\x1c \x00\x11\x00\x00\x0e\x10\x00\x15\x00\x00\x1c \x01\x19\x00\x008" +
-	"@\x01\x1e\x00\x00*0\x00\"LMT\x00CMT\x00BMT\x00EEST\x00EET\x00CET\x00CEST\x00MSD\x00MSK\x00\nEET-2EEST,M3" +
-	".5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\x0f\x00\x1c\x00Europe/Sarajevo" +
-	"UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$\x00\x00\x00\x03\x00" +
-	"\x00\x00\r\xff\xff\xff\xff^<\xf0H\xff\xff\xff\xff\xca\x025\xe0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff" +
-	"\xff\xff\xffѡ\x8c\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d" +
-	"\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00" +
-	"\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+" +
-	"\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x138\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\bLMT\x00CET\x00CEST\x00\nC" +
-	"ET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTZk#V\x81\x03\x00\x00\x81\x03\x00\x00\r\x00\x1c\x00Euro" +
-	"pe/MadridUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00\f\x88\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00*0\x01\rLMT\x00CEST\x00CET" +
+	"\x00CEMT\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Io\x11{\xd3\x02\x00\x00\xd3\x02\x00\x00" +
+	"\x11\x00\x00\x00Europe/BratislavaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xff" +
+	"\x1eI\x92\xf8\xff\xff\xff\xffl\xcf\xea\xf8\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90" +
+	"\xff\xff\xff\xff\xc8\tq\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff" +
+	"\xd2b\a\x10\xff\xff\xff\xffӀ\x1c\x90\xff\xff\xff\xff\xd4I\xd2\x10\xff\xff\xff\xffԓ\xb4 \xff\xff\xff\xff\xd5\x02r \xff\xff\xff\xff\xd5L8\x10\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10" +
+	"\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xd9\x01p\x10\xff\xff\xff\xff\xd9\xe9x\x10\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00" +
+	"\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10" +
+	"\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00" +
+	"#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90" +
+	"\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x00" +
+	"1]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x00\x00\r\x88\x00\x00\x00\x00\r\x88\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\r\x00\x00\x00\x00\x01\x11LMT\x00PMT\x00CEST\x00CET\x00GMT\x00\nCET" +
+	"-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o\xbc\x831O\x04\x00\x00O\x04\x00\x00\x0f\x00\x00\x00Europe" +
+	"/BrusselsTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" +
+	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00f\x00\x00\x00\x06\x00\x00\x00\x1a\xff\xff\xff\xffV\xb6\xdf\xe6\xff\xff\xff\xffm\xe8\xc8\x00" +
+	"\xff\xff\xff\xff\x98DI\x80\xff\xff\xff\xff\x9b\f%p\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff" +
+	"\x9f\xce\xf80\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1~\xbbp\xff\xff\xff\xff\xa2.\x12\xf0\xff\xff\xff\xff\xa3zL\xf0\xff\xff\xff\xff\xa45\x81\xf0\xff\xff\xff\xff\xa5^#p\xff\xff\xff\xff\xa6%5\xf0" +
+	"\xff\xff\xff\xff\xa7'\x9b\xf0\xff\xff\xff\xff\xa8*\x01\xf0\xff\xff\xff\xff\xa9\a}\xf0\xff\xff\xff\xff\xa9\xee4p\xff\xff\xff\xff\xaa\xe7_\xf0\xff\xff\xff\xff\xab\xd7P\xf0\xff\xff\xff\xff\xac\xc7A\xf0\xff\xff\xff\xff" +
+	"\xadɧ\xf0\xff\xff\xff\xff\xae\xa7#\xf0\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x05\xf0\xff\xff\xff\xff\xb1\x89k\xf0\xff\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0" +
+	"\xff\xff\xff\xff\xb5IZ \xff\xff\xff\xff\xb60\x10\xa0\xff\xff\xff\xff\xb72v\xa0\xff\xff\xff\xff\xb8\x0f\xf2\xa0\xff\xff\xff\xff\xb8\xff\xe3\xa0\xff\xff\xff\xff\xb9\xefԠ\xff\xff\xff\xff\xba\u058b \xff\xff\xff\xff" +
+	"\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xc8\xe2 \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\x9f\x89\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2h\x88 " +
+	"\xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4?/\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xc8J\x19 \xff\xff\xff\xff" +
+	"\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2N@\x90\xff\xff\xff\xffӑ@\x10" +
+	"\xff\xff\xff\xff\xd4K#\x90\x00\x00\x00\x00\r\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00" +
+	"\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90" +
+	"\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00" +
+	"!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90" +
+	"\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00" +
+	"/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x03\x04\x03\x04\x03\x04\x03\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02" +
+	"\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" +
+	"\x03\x04\x00\x00\x04\x1a\x00\x00\x00\x00\x04\x1a\x00\x04\x00\x00\x00\x00\x00\b\x00\x00\x0e\x10\x00\f\x00\x00\x1c \x01\x10\x00\x00\x0e\x10\x01\x15LMT\x00BMT\x00WET\x00CET\x00CEST\x00W" +
+	"EST\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90\xa9\xf5ϕ\x02\x00\x00\x95\x02\x00\x00\x10\x00" +
+	"\x00\x00Europe/BucharestTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00" +
+	"\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x007\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xffl\xcf\xe0" +
+	"\b\xff\xff\xff\xff\xb7\xb0\xd2\b\xff\xff\xff\xff\xb9>\xf3`\xff\xff\xff\xff\xb9\xef\x9c`\xff\xff\xff\xff\xbaߍ`\xff\xff\xff\xff\xbb\xcf~`\xff\xff\xff\xff\xbcȩ\xe0\xff\xff\xff\xff\xbd\xb8\x9a\xe0\xff\xff\xff" +
+	"\xff\xbe\xa8\x8b\xe0\xff\xff\xff\xff\xbf\x98|\xe0\xff\xff\xff\xff\xc0\x88m\xe0\xff\xff\xff\xff\xc1x^\xe0\xff\xff\xff\xff\xc2hO\xe0\xff\xff\xff\xff\xc3X@\xe0\xff\xff\xff\xff\xc4H1\xe0\xff\xff\xff\xff\xc58\"" +
+	"\xe0\xff\xff\xff\xff\xc6(\x13\xe0\xff\xff\xff\xff\xc7\x18\x04\xe0\x00\x00\x00\x00\x11\xad\xd1`\x00\x00\x00\x00\x12S\xe0P\x00\x00\x00\x00\x13M\v\xd0\x00\x00\x00\x00\x143\xd0`\x00\x00\x00\x00\x15#݀\x00\x00\x00" +
+	"\x00\x16\x13\u0380\x00\x00\x00\x00\x17\x03\xbf\x80\x00\x00\x00\x00\x17\xf3\xb0\x80\x00\x00\x00\x00\x18㡀\x00\x00\x00\x00\x19Ӓ\x80\x00\x00\x00\x00\x1aÃ\x80\x00\x00\x00\x00\x1b\xbc\xaf\x00\x00\x00\x00\x00\x1c\xac\xa0" +
+	"\x00\x00\x00\x00\x00\x1d\x9c\x91\x00\x00\x00\x00\x00\x1e\x8c\x82\x00\x00\x00\x00\x00\x1f|s\x00\x00\x00\x00\x00 ld\x00\x00\x00\x00\x00!\\U\x00\x00\x00\x00\x00\"LF\x00\x00\x00\x00\x00#<7\x00\x00\x00\x00" +
+	"\x00$,(\x00\x00\x00\x00\x00%\x1c\x19\x00\x00\x00\x00\x00&\f\n\x00\x00\x00\x00\x00'\x055\x80\x00\x00\x00\x00'\xf5\n`\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xdd" +
+	"`\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xbf`\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000duP\x00\x00\x00\x001]\xae\xe0\x00\x00\x00" +
+	"\x002r{\xd0\x00\x00\x00\x003=\xbb\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\x18x\x00\x00\x00\x00\x18x\x00\x04\x00\x00*0\x01\b\x00\x00\x1c \x00\rLMT\x00BMT\x00EEST\x00EET\x00\nEET-2EEST," +
+	"M3.5.0/3,M10.5.0/4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe6Kf\xab\xfe\x02\x00\x00\xfe\x02\x00\x00\x0f\x00\x00\x00Europe/Buda" +
+	"pestTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00D\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xffk\x17\x91\x9c\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b" +
+	"\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xa0\x9a\xc4\x10\xff\xff\xff\xff\xa1dy\x90\xff\xff\xff\xff\xa2p\x1a\x10\xff" +
+	"\xff\xff\xff\xa3M\x96\x10\xff\xff\xff\xff\xc9\xf3\xb5`\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1" +
+	"\x99x\xe0\xff\xff\xff\xffҊ\xc9p\xff\xff\xff\xff\xd3P\xa6\x90\xff\xff\xff\xff\xd4K\x15\x80\xff\xff\xff\xff\xd59\xc3\x10\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7\x19\xa5\x10\xff\xff\xff\xff\xd8\t\x96\x10\xff" +
+	"\xff\xff\xff\xd9\x02\xc1\x90\xff\xff\xff\xff\xd9\xe9x\x10\xff\xff\xff\xff⢨\xf0\xff\xff\xff\xff\xe3Q\xf2`\xff\xff\xff\xff䂧\x10\xff\xff\xff\xff\xe51\xfe\x90\xff\xff\xff\xff\xe6t\xfe\x10\xff\xff\xff\xff\xe7" +
+	"\x11\xe0\x90\xff\xff\xff\xff\xe8T\xe0\x10\xff\xff\xff\xff\xe8\xf1\u0090\x00\x00\x00\x00\x13M'\xf0\x00\x00\x00\x00\x143\xdep\x00\x00\x00\x00\x15#\xcfp\x00\x00\x00\x00\x16\x13\xc0p\x00\x00\x00\x00\x17\x03\xb1p\x00" +
+	"\x00\x00\x00\x17\xf3\xa2p\x00\x00\x00\x00\x18\xe3\x93p\x00\x00\x00\x00\x19ӄp\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e" +
+	"\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00" +
+	"\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00," +
+	"\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00\x11\xe4\x00\x00\x00\x00\x1c" +
+	" \x01\x04\x00\x00\x0e\x10\x00\tLMT\x00CEST\x00CET\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00Dd#\xc4\xf1\x01\x00\x00\xf1\x01\x00\x00\x0f\x00\x00\x00Europe/BusingenTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00%\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff$\xf0\xea\x80\xff\xff\xff\xffq\xd4\x06\x86\xff\xff\xff\xff\xca\x17j\x00\xff\xff\xff\xff\xca\xe2q\x00\xff\xff\xff\xff\xcb\xf7L\x00\xff\xff\xff\xff\xcc\xc2S\x00\x00\x00" +
+	"\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc" +
+	"\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00" +
+	"\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5" +
+	"\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00" +
+	"\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\b\x00\x00\x00\x00\x00\x06\xfa\x00\x04\x00\x00\x1c \x01" +
+	"\b\x00\x00\x0e\x10\x00\rLMT\x00BMT\x00CEST\x00CET\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00I\xb8\xbc\xd3\xf3\x02\x00\x00\xf3\x02\x00\x00\x0f\x00\x00\x00Europe/ChisinauTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
 	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00O\x00\x00\x00\x06\x00\x00\x00\x1b\xff\xff\xff\xff~6\xb5\x00\xff\xff\xff\xff\x9e\xba\xc5\xf0\xff\xff\xff\xff\x9f\xa09\x00\xff\xff\xff\xff\xa0\x90\x1b\xf0\xff\xff\xff\xff\xa1\x81l\x80\xff\xff\xff\xff\xaa\x05\xefp" +
-	"\xff\xff\xff\xff\xaa\xe7n\x00\xff\xff\xff\xff\xadɧ\xf0\xff\xff\xff\xff\xae\xa72\x00\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x14\x00\xff\xff\xff\xff\xb1\x89z\x00\xff\xff\xff\xff\xb2p0\x80\xff\xff\xff\xff" +
-	"\xb3r\x88p\xff\xff\xff\xff\xb4P\x12\x80\xff\xff\xff\xff\xc2\xc9\xec\xf0\xff\xff\xff\xff\xc3X]\x00\xff\xff\xff\xff\xc4H?\xf0\xff\xff\xff\xff\xc4m\x1b\xe0\xff\xff\xff\xff\xc59t`\xff\xff\xff\xff\xc7![\x80" +
-	"\xff\xff\xff\xff\xc7\xf5\x8e\xf0\xff\xff\xff\xff\xcb\xf5\xde`\xff\xff\xff\xff̕q\xf0\xff\xff\xff\xff\xcd\xc3K`\xff\xff\xff\xffΠ\xd5p\xff\xff\xff\xffϣ-`\xff\xff\xff\xffЀ\xb7p\xff\xff\xff\xff" +
-	"у\x0f`\xff\xff\xff\xff\xd2`\x99p\xff\xff\xff\xff\xd3b\xf1`\xff\xff\xff\xff\xd4@{p\xff\xff\xff\xff\xd9\x1eF\xe0\xff\xff\xff\xff\xd9\xe9[\xf0\x00\x00\x00\x00\b\r\xcd\xe0\x00\x00\x00\x00\b\xf4\x92p" +
-	"\x00\x00\x00\x00\t\xed\xaf\xe0\x00\x00\x00\x00\n\xd4tp\x00\x00\x00\x00\v\xbb\x1c\xe0\x00\x00\x00\x00\f\xab\x1b\xf0\x00\x00\x00\x00\r\xa49`\x00\x00\x00\x00\x0e\x8a\xfd\xf0\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00" +
-	"\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐" +
-	"\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00" +
-	"\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10" +
-	"\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00" +
-	",\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x03\x01\x02\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" +
-	"\x04\x05\x04\xff\xff\xfc\x8c\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\t\x00\x00\x1c \x01\r\x00\x00\x1c \x01\x12\x00\x00\x0e\x10\x00\x17LMT\x00WEST\x00WET\x00WEMT\x00CES" +
-	"T\x00CET\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00" +
-	"\x10\x00\x1c\x00Europe/PodgoricaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xff^<\xf0H\xff\xff\xff\xff\xca\x025\xe0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\xce" +
-	"\xa2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xffѡ\x8c\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00" +
-	"\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"" +
-	"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00" +
-	"\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000" +
-	"d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x138\x00\x00\x00\x00\x0e\x10\x00\x04\x00" +
-	"\x00\x1c \x01\bLMT\x00CET\x00CEST\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT" +
-	"Dd#\xc4\xf1\x01\x00\x00\xf1\x01\x00\x00\x0f\x00\x1c\x00Europe/BusingenUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00T" +
+	"\x00\x00\x00<\x00\x00\x00\t\x00\x00\x00&\xff\xff\xff\xffV\xb6\xc8\xf8\xff\xff\xff\xff\x9ek\x9f\f\xff\xff\xff\xff\xb7\xb0\xd2\b\xff\xff\xff\xff\xb9>\xf3`\xff\xff\xff\xff\xb9\xef\x9c`\xff\xff\xff\xff\xbaߍ`" +
+	"\xff\xff\xff\xff\xbb\xcf~`\xff\xff\xff\xff\xbcȩ\xe0\xff\xff\xff\xff\xbd\xb8\x9a\xe0\xff\xff\xff\xff\xbe\xa8\x8b\xe0\xff\xff\xff\xff\xbf\x98|\xe0\xff\xff\xff\xff\xc0\x88m\xe0\xff\xff\xff\xff\xc1x^\xe0\xff\xff\xff\xff" +
+	"\xc2hO\xe0\xff\xff\xff\xff\xc3X@\xe0\xff\xff\xff\xff\xc4H1\xe0\xff\xff\xff\xff\xc58\"\xe0\xff\xff\xff\xff\xc6(\x13\xe0\xff\xff\xff\xff\xc7\x18\x04\xe0\xff\xff\xff\xffȼ\x93`\xff\xff\xff\xff\xcaw}P" +
+	"\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xff\xd0N\x90`\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00" +
+	"\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0" +
+	"\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00" +
+	"%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00&CL\xe0\x00\x00\x00\x00'\x055\x80\x00\x00\x00\x00'\xf5&\x80\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xcfP" +
+	"\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000duP\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x00" +
+	"2r{\xd0\x00\x00\x00\x003=\xad\x00\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x06\x05\x06\x05\x06\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\x03\x04\x03" +
+	"\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x1b\b\x00\x00\x00\x00\x1a\xf4\x00\x04\x00\x00\x18x\x00\b\x00\x00*0\x01\f\x00\x00\x1c \x00\x11\x00\x00\x0e\x10\x00\x15\x00\x00\x1c \x01\x19\x00\x008@\x01\x1e" +
+	"\x00\x00*0\x00\"LMT\x00CMT\x00BMT\x00EEST\x00EET\x00CET\x00CEST\x00MSD\x00MSK\x00\nEET-2EEST,M3.5." +
+	"0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17S\x91\xb3\xc1\x02\x00\x00\xc1\x02\x00\x00\x11\x00\x00\x00Europe/CopenhagenT" +
 	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00%\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff$\xf0\xea\x80\xff\xff\xff\xffq\xd4\x06\x86\xff\xff\xff\xff\xca\x17j\x00\xff\xff" +
-	"\xff\xff\xca\xe2q\x00\xff\xff\xff\xff\xcb\xf7L\x00\xff\xff\xff\xff\xcc\xc2S\x00\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3" +
-	"\xaf\x90\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00" +
-	"\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05" +
-	"C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00" +
-	"\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
-	"\x02\x03\x02\x03\x02\x03\x02\x00\x00\b\x00\x00\x00\x00\x00\x06\xfa\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\rLMT\x00BMT\x00CEST\x00CET\x00\nCET-1CEST,M" +
-	"3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x95\xb4\x9e\xe7\xb3\x03\x00\x00\xb3\x03\x00\x00\x0e\x00\x1c\x00Europe/Vatican" +
-	"UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00W\x00\x00\x00\x04\x00" +
-	"\x00\x00\x11\xff\xff\xff\xff>(\xe8L\xff\xff\xff\xffp\xbc\x81p\xff\xff\xff\xff\x9b8\xf8p\xff\xff\xff\xff\x9b\xd5\xcc\xe0\xff\xff\xff\xff\x9c\xc5\xcb\xf0\xff\xff\xff\xff\x9d\xb7\x00`\xff\xff\xff\xff\x9e\x89\xfep\xff" +
-	"\xff\xff\xff\x9f\xa0\x1c\xe0\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1~\xad`\xff\xff\xff\xff\xa2\\7p\xff\xff\xff\xff\xa3L\x1a`\xff\xff\xff\xff\xc8l5\xf0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd" +
-	"\xa9\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2L\xd2\xf0\xff\xff\xff\xff\xd3>1\x90\xff\xff\xff\xff\xd4I\xd2\x10\xff" +
-	"\xff\xff\xff\xd5\x1d\xf7p\xff\xff\xff\xff\xd6)\x97\xf0\xff\xff\xff\xff\xd6뀐\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xf93\xb5\xf0\xff\xff\xff\xff\xf9\xd9\xc4\xe0\xff\xff\xff\xff\xfb\x1c\xd2p\xff\xff\xff\xff\xfb" +
-	"\xb9\xb4\xf0\xff\xff\xff\xff\xfc\xfc\xb4p\xff\xff\xff\xff\xfd\x99\x96\xf0\xff\xff\xff\xff\xfe\xe5\xd0\xf0\xff\xff\xff\xff\xff\x82\xb3p\x00\x00\x00\x00\x00Ų\xf0\x00\x00\x00\x00\x01b\x95p\x00\x00\x00\x00\x02\x9cZp\x00" +
-	"\x00\x00\x00\x03Bwp\x00\x00\x00\x00\x04\x85v\xf0\x00\x00\x00\x00\x05+\x93\xf0\x00\x00\x00\x00\x06n\x93p\x00\x00\x00\x00\a\vu\xf0\x00\x00\x00\x00\bE:\xf0\x00\x00\x00\x00\b\xebW\xf0\x00\x00\x00\x00\n" +
-	".Wp\x00\x00\x00\x00\n\xcb9\xf0\x00\x00\x00\x00\f\x0e9p\x00\x00\x00\x00\f\xab\x1b\xf0\x00\x00\x00\x00\r\xe4\xe0\xf0\x00\x00\x00\x00\x0e\x8a\xfd\xf0\x00\x00\x00\x00\x0f\xcd\xfdp\x00\x00\x00\x00\x10t\x1ap\x00" +
-	"\x00\x00\x00\x11\xad\xdfp\x00\x00\x00\x00\x12S\xfcp\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17" +
-	"\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00" +
-	"\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&" +
-	"\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00" +
-	"\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x00\x00\v\xb4\x00\x00\x00\x00\v\xb4\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\rLMT\x00RMT\x00CEST\x00CET\x00\nCET-1CEST,M3" +
-	".5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTk\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\x0e\x00\x1c\x00Europe/BelfastU" +
-	"T\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xffo\xa2a\xf8\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff" +
+	"\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xc8\tq\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2" +
+	"C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xffѶ\x96\x00\xff\xff\xff\xff\xd2X\xbe\x80\xff\xff\xff\xffҡO\x10\xff\xff\xff\xff\xd3c\x1b\x90\xff\xff" +
+	"\xff\xff\xd4K#\x90\xff\xff\xff\xff\xd59\xd1 \xff\xff\xff\xff\xd5g\xe7\x90\xff\xff\xff\xffըs\x00\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xd9\x02" +
+	"\xc1\x90\xff\xff\xff\xff\xd9\xe9x\x10\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00" +
+	"\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|" +
+	"\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00" +
+	"\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94" +
+	"ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00\f\x88\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00*0\x01\rLM" +
+	"T\x00CEST\x00CET\x00CEMT\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1\xd6" +
+	"jL\xd8\x05\x00\x00\xd8\x05\x00\x00\r\x00\x00\x00Europe/DublinTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x91\x00\x00\x00\b\x00\x00" +
+	"\x00\x14\xff\xff\xff\xffW\xd1\n\xf1\xff\xff\xff\xff\x9b&\xb3\x91\xff\xff\xff\xff\x9b\xd6\v\x11\xff\xff\xff\xff\x9c\xcf0\xa0\xff\xff\xff\xff\x9d\xa4à\xff\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff" +
+	"\xff\xff\xa0\x85\xba \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{Ƞ\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'" +
+	"\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00Ӡ\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff" +
+	"\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \xff\xff\xff\xff\xb1\x92Р\xff\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5I" +
+	"Z \xff\xff\xff\xff\xb60\x10\xa0\xff\xff\xff\xff\xb72v\xa0\xff\xff\xff\xff\xb8\x0f\xf2\xa0\xff\xff\xff\xff\xb9\x12X\xa0\xff\xff\xff\xff\xb9\xefԠ\xff\xff\xff\xff\xba\xe9\x00 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff" +
+	"\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3X" +
+	"y \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff" +
+	"\xff\xff\xd6N\xac \xff\xff\xff\xff\xd7,( \xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb" +
+	"\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\u07b4\xea\xa0\xff\xff\xff\xff߮\x16 \xff\xff\xff\xff\xe0\x94̠\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt \xff\xff\xff\xff\xe3R*\xa0\xff\xff" +
+	"\xff\xff\xe4T\x90\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6=\xad \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\v \xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda" +
+	"\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\ue6b1 \xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0\xff\xff" +
+	"\xff\xff\xf2\x7f_ \xff\xff\xff\xff\xf3Jf \xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\r\xa0\xff\xff\xff\xff\xf6?# \xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0" +
+	"Ѡ\xff\xff\xff\xff\xf9\xfe\xe7 \xff\xff\xff\xff\xfa\xc0\xb3\xa0\xff\xff\xff\xff\xfb\xe8\x03\xa0\xff\xff\xff\xff\xfc{\xab\xa0\xff\xff\xff\xff\xfdǻp\x00\x00\x00\x00\x03p\xc6 \x00\x00\x00\x00\x04)X \x00\x00" +
+	"\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\t: \x00\x00\x00\x00\a0\x8a \x00\x00\x00\x00\a\xe9\x1c \x00\x00\x00\x00\t\x10l \x00\x00\x00\x00\t\xc8\xfe \x00\x00\x00\x00\n\xf0N \x00\x00\x00\x00\v\xb2" +
+	"\x1a\xa0\x00\x00\x00\x00\f\xd00 \x00\x00\x00\x00\r\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \x00\x00\x00\x00\x0fqޠ\x00\x00\x00\x00\x10\x99.\xa0\x00\x00\x00\x00\x11Q\xc0\xa0\x00\x00\x00\x00\x12y\x10\xa0\x00\x00" +
+	"\x00\x00\x131\xa2\xa0\x00\x00\x00\x00\x14X\xf2\xa0\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x168Ɛ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x18\x18\xa8\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19\xf8" +
+	"\x8a\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xe1\xa7\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\xc1\x89\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f\xa1k\x10\x00\x00\x00\x00 lr\x10\x00\x00" +
+	"\x00\x00!\x81M\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#a/\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%JK\x90\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'*-\x90\x00\x00\x00\x00'\xf5" +
+	"4\x90\x00\x00\x00\x00)\n\x0f\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xe9\xf1\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xc9Ӑ\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\xa9\xb5\x90\x00\x00" +
+	"\x00\x00/t\xbc\x90\x00\x00\x00\x000\x89\x97\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" +
+	"\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\a\x06\a\x06" +
+	"\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\xff\xff\xfa\x0f\x00\x00\xff\xff\xfa\x0f\x00\x04\x00" +
+	"\x00\b\x1f\x01\b\x00\x00\x0e\x10\x01\f\x00\x00\x00\x00\x00\x10\x00\x00\x0e\x10\x01\b\x00\x00\x00\x00\x01\x10\x00\x00\x0e\x10\x00\bLMT\x00DMT\x00IST\x00BST\x00GMT\x00\nIST-" +
+	"1GMT0,M10.5.0,M3.5.0/1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00==\xa4\x16\xc4\x04\x00\x00\xc4\x04\x00\x00\x10\x00\x00\x00Europe/" +
+	"GibraltarTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" +
+	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00s\x00\x00\x00\x06\x00\x00\x00\x1a\xff\xff\xff\xffW\xd1\n\x04\xff\xff\xff\xff\x9b&\xad\xa0" +
+	"\xff\xff\xff\xff\x9b\xd6\x05 \xff\xff\xff\xff\x9c\xcf0\xa0\xff\xff\xff\xff\x9d\xa4à\xff\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff\xff\xff\xa0\x85\xba \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff" +
+	"\xa2e\x9c \xff\xff\xff\xff\xa3{Ƞ\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0" +
+	"\xff\xff\xff\xff\xaa\x00Ӡ\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff" +
+	"\xb0\x870 \xff\xff\xff\xff\xb1\x92Р\xff\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \xff\xff\xff\xff\xb60\x10\xa0\xff\xff\xff\xff\xb72v\xa0" +
+	"\xff\xff\xff\xff\xb8\x0f\xf2\xa0\xff\xff\xff\xff\xb9\x12X\xa0\xff\xff\xff\xff\xb9\xefԠ\xff\xff\xff\xff\xba\xe9\x00 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff" +
+	"\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ " +
+	"\xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xca\x16&\x90\xff\xff\xff\xffʗY\x90\xff\xff\xff\xff\xcb\xd1\x1e\x90\xff\xff\xff\xff\xccw;\x90\xff\xff\xff\xff" +
+	"ͱ\x00\x90\xff\xff\xff\xff\xce`X\x10\xff\xff\xff\xffϐ\xe2\x90\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xfb2\x10\xff\xff\xff\xff\xd2i\xfe \xff\xff\xff\xff\xd3c)\xa0" +
+	"\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd5B\xfd\x90\xff\xff\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd6\xfe\x03\xa0\xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff" +
+	"\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\u07b4\xea\xa0\xff\xff\xff\xff߮\x16 " +
+	"\xff\xff\xff\xff\xe0\x94̠\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt \xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4T\x90\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6=\xad \xff\xff\xff\xff" +
+	"\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10" +
+	"\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00" +
+	"#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90" +
+	"\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x00" +
+	"1]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x03\x01\x03\x01" +
+	"\x03\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\xff" +
+	"\xff\xfa\xfc\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x00\x11\x00\x00\x1c \x01\x15LMT\x00BST\x00GMT\x00BDST\x00CET\x00CEST" +
+	"\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\x0f\x00\x00\x00E" +
+	"urope/GuernseyTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00" +
+	"\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f\x00\x00\x00\x05\x00\x00\x00\x11\xff\xff\xff\xff\x1a]\t\xcb\xff\xff\xff" +
+	"\xff\x9b&\xad\xa0\xff\xff\xff\xff\x9b\xd6\x05 \xff\xff\xff\xff\x9c\xcf0\xa0\xff\xff\xff\xff\x9d\xa4à\xff\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff\xff\xff\xa0\x85\xba \xff\xff\xff\xff\xa1v\xfc" +
+	"\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{Ƞ\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff" +
+	"\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00Ӡ\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y" +
+	"\xa0\xff\xff\xff\xff\xb0\x870 \xff\xff\xff\xff\xb1\x92Р\xff\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \xff\xff\xff\xff\xb60\x10\xa0\xff\xff\xff" +
+	"\xff\xb72v\xa0\xff\xff\xff\xff\xb8\x0f\xf2\xa0\xff\xff\xff\xff\xb9\x12X\xa0\xff\xff\xff\xff\xb9\xefԠ\xff\xff\xff\xff\xba\xe9\x00 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3" +
+	" \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff" +
+	"\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xca\x16&\x90\xff\xff\xff\xffʗY\x90\xff\xff\xff\xff\xcb\xd1\x1e\x90\xff\xff\xff\xff\xccw;" +
+	"\x90\xff\xff\xff\xffͱ\x00\x90\xff\xff\xff\xff\xce`X\x10\xff\xff\xff\xffϐ\xe2\x90\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xfb2\x10\xff\xff\xff\xff\xd2i\xfe \xff\xff\xff" +
+	"\xff\xd3c)\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd5B\xfd\x90\xff\xff\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd6\xfe\x03\xa0\xff\xff\xff\xff\xd8.\x8e" +
+	" \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\u07b4\xea\xa0\xff\xff\xff" +
+	"\xff߮\x16 \xff\xff\xff\xff\xe0\x94̠\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt \xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4T\x90\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6=\xad" +
+	" \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\v \xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff" +
+	"\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\ue6b1 \xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\x7f_ \xff\xff\xff\xff\xf3Jf \xff\xff\xff\xff\xf4_A" +
+	" \xff\xff\xff\xff\xf5!\r\xa0\xff\xff\xff\xff\xf6?# \xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0Ѡ\xff\xff\xff\xff\xf9\xfe\xe7 \xff\xff\xff\xff\xfa\xc0\xb3\xa0\xff\xff\xff" +
+	"\xff\xfb\xe8\x03\xa0\xff\xff\xff\xff\xfc{\xab\xa0\xff\xff\xff\xff\xfdǻp\x00\x00\x00\x00\x03p\xc6 \x00\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\t: \x00\x00\x00\x00\a0\x8a" +
+	" \x00\x00\x00\x00\a\xe9\x1c \x00\x00\x00\x00\t\x10l \x00\x00\x00\x00\t\xc8\xfe \x00\x00\x00\x00\n\xf0N \x00\x00\x00\x00\v\xb2\x1a\xa0\x00\x00\x00\x00\f\xd00 \x00\x00\x00\x00\r\x91\xfc\xa0\x00\x00\x00" +
+	"\x00\x0e\xb0\x12 \x00\x00\x00\x00\x0fqޠ\x00\x00\x00\x00\x10\x99.\xa0\x00\x00\x00\x00\x11Q\xc0\xa0\x00\x00\x00\x00\x12y\x10\xa0\x00\x00\x00\x00\x131\xa2\xa0\x00\x00\x00\x00\x14X\xf2\xa0\x00\x00\x00\x00\x15#\xeb" +
+	"\x90\x00\x00\x00\x00\x168Ɛ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x18\x18\xa8\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19\xf8\x8a\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xe1\xa7\x10\x00\x00\x00" +
+	"\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\xc1\x89\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f\xa1k\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\x81M\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#a/" +
+	"\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%JK\x90\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'*-\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00)\n\x0f\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00" +
+	"\x00*\xe9\xf1\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xc9Ӑ\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\xa9\xb5\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000\x89\x97\x90\x00\x00\x00\x001]\xd9" +
+	"\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03" +
+	"\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xff\xb5\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00" +
+	"\x1c \x01\f\x00\x00\x0e\x10\x00\x04LMT\x00BST\x00GMT\x00BDST\x00\nGMT0BST,M3.5.0/1,M10.5.0\nPK\x03\x04\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\xe5\xc8X\xa7\xe1\x01\x00\x00\xe1\x01\x00\x00\x0f\x00\x00\x00Europe/HelsinkiTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00#\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xffS\xba&\x9b\xff\xff\xff\xff\xa4so\x1b\xff\xff\xff\xff\xcb\xceQ`\xff\xff\xff\xff\xcc\xc0\xe5`\x00\x00\x00\x00\x15#݀\x00\x00\x00\x00\x16\x13\xce" +
+	"\x80\x00\x00\x00\x00\x17\x03\xbf\x80\x00\x00\x00\x00\x17\xf3\xb0\x80\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00" +
+	"\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6" +
+	"\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00" +
+	"\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\x17e\x00\x00\x00\x00\x17e\x00\x04\x00\x00*0\x01\b\x00\x00\x1c \x00\rLMT\x00HMT\x00" +
+	"EEST\x00EET\x00\nEET-2EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00" +
+	"\x00?\x06\x00\x00\x12\x00\x00\x00Europe/Isle_of_ManTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
 	"\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f\x00\x00\x00\x05\x00\x00" +
 	"\x00\x11\xff\xff\xff\xff\x1a]\t\xcb\xff\xff\xff\xff\x9b&\xad\xa0\xff\xff\xff\xff\x9b\xd6\x05 \xff\xff\xff\xff\x9c\xcf0\xa0\xff\xff\xff\xff\x9d\xa4à\xff\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff" +
 	"\xff\xff\xa0\x85\xba \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{Ƞ\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'" +
@@ -4842,1164 +4566,7 @@
 	"\x02\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
 	"\x02\x01\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xff\xb5\x00\x00\x00" +
 	"\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x00\x04LMT\x00BST\x00GMT\x00BDST\x00\nGMT0BST,M3.5.0/1,M1" +
-	"0.5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTIo\x11{\xd3\x02\x00\x00\xd3\x02\x00\x00\x11\x00\x1c\x00Europe/BratislavaUT\t\x00\x03\xdd\xfc" +
-	"\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xff" +
-	"\x1eI\x92\xf8\xff\xff\xff\xffl\xcf\xea\xf8\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90" +
-	"\xff\xff\xff\xff\xc8\tq\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff" +
-	"\xd2b\a\x10\xff\xff\xff\xffӀ\x1c\x90\xff\xff\xff\xff\xd4I\xd2\x10\xff\xff\xff\xffԓ\xb4 \xff\xff\xff\xff\xd5\x02r \xff\xff\xff\xff\xd5L8\x10\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10" +
-	"\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xd9\x01p\x10\xff\xff\xff\xff\xd9\xe9x\x10\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00" +
-	"\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10" +
-	"\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00" +
-	"#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90" +
-	"\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x00" +
-	"1]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
-	"\x02\x03\x02\x03\x02\x00\x00\r\x88\x00\x00\x00\x00\r\x88\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\r\x00\x00\x00\x00\x01\x11LMT\x00PMT\x00CEST\x00CET\x00GMT\x00\nCET" +
-	"-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTiS\x18D.\x02\x00\x00.\x02\x00\x00\v\x00\x1c\x00Europe" +
-	"/KievUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'" +
-	"\x00\x00\x00\b\x00\x00\x00\"\xff\xff\xff\xffV\xb6\xc7d\xff\xff\xff\xff\xaa\x19\xa7d\xff\xff\xff\xff\xb5\xa4\x19`\xff\xff\xff\xff\xca\xcd.\xd0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff" +
-	"\u03a2C\x10\xff\xff\xff\xff\xceͨp\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@" +
-	"\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00" +
-	"!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00&\x8d \xe0\x00\x00\x00\x00(\xe5\x17\x80" +
-	"\x00\x00\x00\x00)\xd5\b\x80\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4ۀ\x00\x00\x00\x00-\x94̀\x00\x00\x00\x00.\x84\xbd\x80\x00\x00\x00\x00/t\xae\x80\x00\x00\x00\x00" +
-	"0d\x9f\x80\x00\x00\x00\x001]\xcb\x00\x00\x00\x00\x002r\xb4\x10\x01\x02\x03\x05\x04\x05\x04\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\x00" +
-	"\x00\x1c\x9c\x00\x00\x00\x00\x1c\x9c\x00\x04\x00\x00\x1c \x00\b\x00\x00*0\x00\f\x00\x00\x0e\x10\x00\x10\x00\x00\x1c \x01\x14\x00\x008@\x01\x19\x00\x00*0\x01\x1dLMT\x00KMT\x00EET\x00M" +
-	"SK\x00CET\x00CEST\x00MSD\x00EEST\x00\nEET-2EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\n\x00\x00\x00\x00" +
-	"\x00\x8fj\xbeTO+j\x94\x88\x03\x00\x00\x88\x03\x00\x00\x12\x00\x1c\x00Europe/KaliningradUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1" +
-	"\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZ" +
-	"if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\x00\x00\x00\b\x00\x00\x00\"\xff\xff\xff\xffo\xa2[H\xff\xff\xff\xff\x9b\f\x17`\xff\xff" +
-	"\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xc8\tq\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ" +
-	"\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1|w\xe0\xff\xff\xff\xffѕ\x84`\xff\xff\xff\xffҊ\xadP\xff\xff" +
-	"\xff\xff\xd3Y\xb6\xe0\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a\xcc" +
-	"\x93\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00" +
-	"\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\x19\x00\x00\x00\x00\x00&\f\n\x00\x00\x00\x00\x00'\x055\x80\x00\x00\x00\x00'\xf5&\x80\x00\x00\x00\x00(\xe5" +
-	"\x17\x80\x00\x00\x00\x00)\xd5\b\x80\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4ۀ\x00\x00\x00\x00-\x94̀\x00\x00\x00\x00.\x84\xbd\x80\x00\x00\x00\x00/t\xae\x80\x00\x00" +
-	"\x00\x000d\x9f\x80\x00\x00\x00\x001]\xcb\x00\x00\x00\x00\x002r\xa6\x00\x00\x00\x00\x003=\xad\x00\x00\x00\x00\x004R\x88\x00\x00\x00\x00\x005\x1d\x8f\x00\x00\x00\x00\x0062j\x00\x00\x00\x00\x006\xfd" +
-	"q\x00\x00\x00\x00\x008\x1b\x86\x80\x00\x00\x00\x008\xddS\x00\x00\x00\x00\x009\xfbh\x80\x00\x00\x00\x00:\xbd5\x00\x00\x00\x00\x00;\xdbJ\x80\x00\x00\x00\x00<\xa6Q\x80\x00\x00\x00\x00=\xbb,\x80\x00\x00" +
-	"\x00\x00>\x863\x80\x00\x00\x00\x00?\x9b\x0e\x80\x00\x00\x00\x00@f\x15\x80\x00\x00\x00\x00A\x84+\x00\x00\x00\x00\x00BE\xf7\x80\x00\x00\x00\x00Cd\r\x00\x00\x00\x00\x00D%ـ\x00\x00\x00\x00EC" +
-	"\xef\x00\x00\x00\x00\x00F\x05\xbb\x80\x00\x00\x00\x00G#\xd1\x00\x00\x00\x00\x00G\xee\xd8\x00\x00\x00\x00\x00I\x03\xb3\x00\x00\x00\x00\x00Iκ\x00\x00\x00\x00\x00J\xe3\x95\x00\x00\x00\x00\x00K\xae\x9c\x00\x00\x00" +
-	"\x00\x00Ḻ\x80\x00\x00\x00\x00M\x8e~\x00\x00\x00\x00\x00TL+p\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x03\x04\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x03\x04\x03\x04" +
-	"\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\a\x04\x00\x00\x138\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t" +
-	"\x00\x00*0\x01\r\x00\x00\x1c \x00\x12\x00\x008@\x01\x16\x00\x00*0\x00\x1a\x00\x00*0\x00\x1eLMT\x00CEST\x00CET\x00EEST\x00EET\x00MSD\x00MSK\x00" +
-	"+03\x00\nEET-2\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xfc\xbe\xb5\xac9\x02\x00\x009\x02\x00\x00\x11\x00\x1c\x00Europe/ZaporozhyeUT" +
-	"\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00(\x00\x00\x00\b\x00\x00\x00" +
-	"$\xff\xff\xff\xffV\xb6\xc3\b\xff\xff\xff\xff\xaa\x19\xa30\xff\xff\xff\xff\xb5\xa4\x19`\xff\xff\xff\xffʪ\xe7\xd0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff" +
-	"\xffν\xd6p\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓" +
-	"\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00" +
-	"\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00(\xe4\xed" +
-	"P\x00\x00\x00\x00)\xd5\b\x80\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4ۀ\x00\x00\x00\x00-\x94̀\x00\x00\x00\x00.\x84\xbd\x80\x00\x00\x00\x00/t\xae\x80\x00\x00\x00" +
-	"\x000d\x9f\x80\x00\x00\x00\x001]\xcb\x00\x00\x00\x00\x002r\xb4\x10\x01\x02\x03\x05\x04\x05\x04\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\a\x02\a\x02\a\x02\a\x02\a\x02\a" +
-	"\x02\x00\x00 \xf8\x00\x00\x00\x00 \xd0\x00\x04\x00\x00\x1c \x00\n\x00\x00*0\x00\x0e\x00\x00\x0e\x10\x00\x12\x00\x00\x1c \x01\x16\x00\x008@\x01\x1b\x00\x00*0\x01\x1fLMT\x00+0220\x00E" +
-	"ET\x00MSK\x00CET\x00CEST\x00MSD\x00EEST\x00\nEET-2EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\n" +
-	"\x00\x00\x00\x00\x00\x8fj\xbeTZ\x05wג\x02\x00\x00\x92\x02\x00\x00\r\x00\x1c\x00Europe/ViennaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b" +
-	"\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZi" +
-	"f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x008\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xffo\xa2_/\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff" +
-	"\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xa2p\x1a\x10\xff\xff\xff\xff\xa3D[\x90\xff\xff\xff\xff\xc8\tq" +
-	"\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\x7fE\x10\xff\xff\xff" +
-	"\xff\xd3c\x1b\x90\xff\xff\xff\xff\xd4K#\x90\xff\xff\xff\xff\xd59\xc3\x10\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\t\x96\x10\x00\x00\x00\x00\x13M'\xf0\x00\x00\x00\x00\x143\xd0" +
-	"`\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00" +
-	"\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT" +
-	"\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00" +
-	"\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad" +
-	"\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x00\x00\x0fQ\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\tLMT\x00CEST\x00CET\x00\nCET-1CEST,M3.5.0,M10.5." +
-	"0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe6Kf\xab\xfe\x02\x00\x00\xfe\x02\x00\x00\x0f\x00\x1c\x00Europe/BudapestUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc" +
-	"\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" +
-	"\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00D\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xffk\x17\x91\x9c" +
-	"\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xa0\x9a\xc4\x10\xff\xff\xff\xff" +
-	"\xa1dy\x90\xff\xff\xff\xff\xa2p\x1a\x10\xff\xff\xff\xff\xa3M\x96\x10\xff\xff\xff\xff\xc9\xf3\xb5`\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10" +
-	"\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xffљx\xe0\xff\xff\xff\xffҊ\xc9p\xff\xff\xff\xff\xd3P\xa6\x90\xff\xff\xff\xff\xd4K\x15\x80\xff\xff\xff\xff\xd59\xc3\x10\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff" +
-	"\xd7\x19\xa5\x10\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xd9\x02\xc1\x90\xff\xff\xff\xff\xd9\xe9x\x10\xff\xff\xff\xff⢨\xf0\xff\xff\xff\xff\xe3Q\xf2`\xff\xff\xff\xff䂧\x10\xff\xff\xff\xff\xe51\xfe\x90" +
-	"\xff\xff\xff\xff\xe6t\xfe\x10\xff\xff\xff\xff\xe7\x11\xe0\x90\xff\xff\xff\xff\xe8T\xe0\x10\xff\xff\xff\xff\xe8\xf1\u0090\x00\x00\x00\x00\x13M'\xf0\x00\x00\x00\x00\x143\xdep\x00\x00\x00\x00\x15#\xcfp\x00\x00\x00\x00" +
-	"\x16\x13\xc0p\x00\x00\x00\x00\x17\x03\xb1p\x00\x00\x00\x00\x17\xf3\xa2p\x00\x00\x00\x00\x18\xe3\x93p\x00\x00\x00\x00\x19ӄp\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10" +
-	"\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00" +
-	"$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90" +
-	"\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x00\x00\x11\xe4\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\tLMT\x00CEST\x00CET\x00\nCET-1CEST,M3.5.0,M10.5.0" +
-	"/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xccb\xf72\xa4\x02\x00\x00\xa4\x02\x00\x00\x0e\x00\x1c\x00Europe/VilniusUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94b" +
-	"ux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00" +
-	"\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\x00\x00\x00\t\x00\x00\x00&\xff\xff\xff\xffV\xb6\xccD\xff\xff" +
-	"\xff\xff\x9cO\x1fP\xff\xff\xff\xff\xa1\x85J\x98\xff\xff\xff\xff\xa2\xf10\xf0\xff\xff\xff\xff\xa3fx`\xff\xff\xff\xffȬ\xcfp\xff\xff\xff\xff\xcaY*\xd0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ" +
-	"\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xff\xd00=\xe0\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00" +
-	"\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|" +
-	"d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\x19\x00\x00\x00\x00\x00&\f\n\x00\x00\x00" +
-	"\x00\x00'\x055\x80\x00\x00\x00\x00'\xf5&\x80\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd5\b\x80\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4ۀ\x00\x00\x00\x00-\x94" +
-	"̀\x00\x00\x00\x00.\x84\xbd\x80\x00\x00\x00\x00/t\xae\x80\x00\x00\x00\x000d\x9f\x80\x00\x00\x00\x001]\xcb\x00\x00\x00\x00\x002r\xa6\x00\x00\x00\x00\x003=\xad\x00\x00\x00\x00\x004R\x88\x00\x00\x00" +
-	"\x00\x005\x1d\x9d\x10\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd\x7f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x00>\x86A\x90\x01\x02\x03\x04\x03\x05\x06\x03\x06\x03\x06\x05\a\x05\a\x05\a\x05\a\x05\a\x05" +
-	"\a\x05\a\x05\a\x05\b\x04\b\x04\b\x04\b\x04\b\x04\b\x04\b\x04\b\x04\b\x04\x06\x03\x06\x04\b\x00\x00\x17\xbc\x00\x00\x00\x00\x13\xb0\x00\x04\x00\x00\x16h\x00\b\x00\x00\x0e\x10\x00\f\x00\x00\x1c \x00\x10\x00" +
-	"\x00*0\x00\x14\x00\x00\x1c \x01\x18\x00\x008@\x01\x1d\x00\x00*0\x01!LMT\x00WMT\x00KMT\x00CET\x00EET\x00MSK\x00CEST\x00MSD\x00EEST" +
-	"\x00\nEET-2EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTn\x81\xf4\xd7Z\x04\x00\x00Z\x04\x00\x00\r\x00\x1c" +
-	"\x00Europe/MonacoUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00f\x00\x00\x00\a\x00\x00\x00\x1f\xff\xff\xff\xffn\x11\x9f\x94\xff\xff\xff\xff\x91x\vO\xff\xff\xff\xff\x9bGx\xf0\xff\xff\xff\xff\x9b\xd7,p\xff\xff\xff\xff\x9c\xbc\x91p\xff\xff\xff" +
-	"\xff\x9d\xc0H\xf0\xff\xff\xff\xff\x9e\x89\xfep\xff\xff\xff\xff\x9f\xa0*\xf0\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1\x80\f\xf0\xff\xff\xff\xff\xa2.\x12\xf0\xff\xff\xff\xff\xa3zL\xf0\xff\xff\xff\xff\xa45\x81" +
-	"\xf0\xff\xff\xff\xff\xa5^#p\xff\xff\xff\xff\xa6%5\xf0\xff\xff\xff\xff\xa7'\x9b\xf0\xff\xff\xff\xff\xa8X&p\xff\xff\xff\xff\xa9\a}\xf0\xff\xff\xff\xff\xa9\xee4p\xff\xff\xff\xff\xaa\xe7_\xf0\xff\xff\xff" +
-	"\xff\xab\xd7P\xf0\xff\xff\xff\xff\xac\xc7A\xf0\xff\xff\xff\xff\xadɧ\xf0\xff\xff\xff\xff\xae\xa7#\xf0\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x05\xf0\xff\xff\xff\xff\xb1\x89k\xf0\xff\xff\xff\xff\xb2p\"" +
-	"p\xff\xff\xff\xff\xb3r\x88p\xff\xff\xff\xff\xb4P\x04p\xff\xff\xff\xff\xb5I/\xf0\xff\xff\xff\xff\xb6/\xe6p\xff\xff\xff\xff\xb72Lp\xff\xff\xff\xff\xb8\x0f\xc8p\xff\xff\xff\xff\xb8\xff\xb9p\xff\xff\xff" +
-	"\xff\xb9\xef\xaap\xff\xff\xff\xff\xba\xd6`\xf0\xff\xff\xff\xff\xbb\xd8\xc6\xf0\xff\xff\xff\xff\xbcȷ\xf0\xff\xff\xff\xff\xbd\xb8\xa8\xf0\xff\xff\xff\xff\xbe\x9f_p\xff\xff\xff\xff\xbf\x98\x8a\xf0\xff\xff\xff\xff\xc0\x9a\xf0" +
-	"\xf0\xff\xff\xff\xff\xc1xl\xf0\xff\xff\xff\xff\xc2h]\xf0\xff\xff\xff\xff\xc3XN\xf0\xff\xff\xff\xff\xc4?\x05p\xff\xff\xff\xff\xc580\xf0\xff\xff\xff\xff\xc6:\x96\xf0\xff\xff\xff\xff\xc7X\xacp\xff\xff\xff" +
-	"\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xca\x17[\xf0\xff\xff\xff\xff\xca\xe2T\xe0\xff\xff\xff\xff˭i\xf0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4" +
-	"\x10\xff\xff\xff\xffЉ\xf1\xf0\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\v\xbb9\x00\x00\x00\x00\x00\f\xab\x1b\xf0\x00\x00\x00\x00\r\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00" +
-	"\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13\xdc" +
-	"\x90\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00" +
-	"\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6" +
-	"\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00" +
-	"\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x06\x05\x06\x05\x06\x05\x06" +
-	"\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x00\x00\x06\xec\x00\x00\x00\x00\x021\x00\x04\x00\x00\x0e\x10\x01\b\x00\x00\x00\x00\x00\r\x00" +
-	"\x00\x1c \x01\x11\x00\x00\x1c \x01\x16\x00\x00\x0e\x10\x00\x1bLMT\x00PMT\x00WEST\x00WET\x00WEMT\x00CEST\x00CET\x00\nCET-1CEST,M" +
-	"3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xa5\x97\aĤ\x02\x00\x00\xa4\x02\x00\x00\v\x00\x1c\x00Europe/OsloUT\t" +
-	"\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:\x00\x00\x00\x03\x00\x00\x00\r" +
-	"\xff\xff\xff\xffr\xee$l\xff\xff\xff\xff\x9b'\xe3\x00\xff\xff\xff\xff\x9b\xd4{`\xff\xff\xff\xffȷM`\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xff" +
-	"ϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2b\a\x10\xff\xff\xff\xff\xeb\xaf \x90\xff\xff\xff\xff\xec\xa8L\x10\xff\xff\xff\xff\xed\x98=\x10\xff\xff\xff\xff\xee\x88.\x10" +
-	"\xff\xff\xff\xff\xefx\x1f\x10\xff\xff\xff\xff\xf0h\x10\x10\xff\xff\xff\xff\xf1X\x01\x10\xff\xff\xff\xff\xf2G\xf2\x10\xff\xff\xff\xff\xf37\xe3\x10\xff\xff\xff\xff\xf4'\xd4\x10\xff\xff\xff\xff\xf5\x17\xc5\x10\xff\xff\xff\xff" +
-	"\xf6\x10\xf0\x90\xff\xff\xff\xff\xf7/\x06\x10\xff\xff\xff\xff\xf7\xf0Ґ\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐" +
-	"\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00" +
-	"\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10" +
-	"\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00" +
-	",\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00\n\x14\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t" +
-	"LMT\x00CEST\x00CET\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT]i\x11u\xd6" +
-	"\x02\x00\x00\xd6\x02\x00\x00\x10\x00\x1c\x00Europe/AstrakhanUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x18Et\xff\xff\xff\xff\xb5\xa4\vP\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18" +
-	"\xce0\x00\x00\x00\x00\x17\b\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a̅\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00" +
-	"\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\8\xe0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<\x1a\xe0\x00\x00\x00\x00$," +
-	"\v\xe0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00" +
-	"\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x94\xbep\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=" +
-	"\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00" +
-	"\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb<p\x00\x00\x00\x00<\xa6Cp\x00\x00\x00\x00=\xbb\x1ep\x00\x00\x00\x00>\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f\ap\x00\x00\x00\x00A\x84" +
-	"\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05\xadp\x00\x00\x00\x00G#\xc2\xf0\x00\x00\x00\x00G\xee\xc9\xf0\x00\x00" +
-	"\x00\x00I\x03\xa4\xf0\x00\x00\x00\x00IΫ\xf0\x00\x00\x00\x00J\xe3\x86\xf0\x00\x00\x00\x00K\xae\x8d\xf0\x00\x00\x00\x00Ḷp\x00\x00\x00\x00M\x8eo\xf0\x00\x00\x00\x00TL\x1d`\x00\x00\x00\x00V\xf7" +
-	"\x14p\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x04\x01\x03\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04" +
-	"\x01\x04\x01\x03\x01\x03\x00\x00-\f\x00\x00\x00\x00*0\x00\x04\x00\x00FP\x01\b\x00\x008@\x00\f\x00\x008@\x01\fLMT\x00+03\x00+05\x00+04\x00\n<+04>-4" +
-	"\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x11\xda\x1d\xd5a\x03\x00\x00a\x03\x00\x00\x11\x00\x1c\x00Europe/SimferopolUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94" +
-	"bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01" +
-	"\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00K\x00\x00\x00\t\x00\x00\x00\"\xff\xff\xff\xffV\xb6\xc4\b\xff" +
-	"\xff\xff\xff\xaa\x19\xa4 \xff\xff\xff\xff\xb5\xa4\x19`\xff\xff\xff\xff\xcb\x04\x8d\xd0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xff\xcf" +
-	"\x9f8\xe0\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00" +
-	"\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"" +
-	"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\x8d.\xf0\x00\x00\x00\x00)\xd5\b\x80\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00" +
-	"\x00\x00\x00,\xa4ۀ\x00\x00\x00\x00-\x94̀\x00\x00\x00\x00-\xc2\xc6\xd0\x00\x00\x00\x00.\x84\x85@\x00\x00\x00\x00/t\x84P\x00\x00\x00\x000dg@\x00\x00\x00\x001]\xa0\xd0\x00\x00\x00\x002" +
-	"r\xa6\x00\x00\x00\x00\x003=\xbb\x10\x00\x00\x00\x004R\x96\x10\x00\x00\x00\x005\x1d\x9d\x10\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd\x7f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x008\xdda\x10\x00" +
-	"\x00\x00\x009\xfbv\x90\x00\x00\x00\x00:\xbdC\x10\x00\x00\x00\x00;\xdbX\x90\x00\x00\x00\x00<\xa6_\x90\x00\x00\x00\x00=\xbb:\x90\x00\x00\x00\x00>\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@" +
-	"f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00" +
-	"\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N" +
-	"\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7^\x80\x00\x00\x00\x00TL\x1d`\x01\x02\x03\x05\x04\x05\x04\x05\x03" +
-	"\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x02\a\x02\a\x02\a\x06\x03\x06\x03\x06\x03\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02" +
-	"\a\x02\a\x02\b\x03\x00\x00\x1f\xf8\x00\x00\x00\x00\x1f\xe0\x00\x04\x00\x00\x1c \x00\b\x00\x00*0\x00\f\x00\x00\x0e\x10\x00\x10\x00\x00\x1c \x01\x14\x00\x008@\x01\x19\x00\x00*0\x01\x1d\x00\x008@\x00\f" +
-	"LMT\x00SMT\x00EET\x00MSK\x00CET\x00CEST\x00MSD\x00EEST\x00\nMSK-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTVa\x92\xd3\xdf" +
-	"\x02\x00\x00\xdf\x02\x00\x00\x10\x00\x1c\x00Europe/VolgogradUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00A\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xf5F\xdc\xff\xff\xff\xff\xb5\xa4\vP\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18" +
-	"\xce0\x00\x00\x00\x00\x17\b\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a̅\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00" +
-	"\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\8\xe0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$," +
-	"\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00" +
-	"\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x94\xbep\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=" +
-	"\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00" +
-	"\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb<p\x00\x00\x00\x00<\xa6Cp\x00\x00\x00\x00=\xbb\x1ep\x00\x00\x00\x00>\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f\ap\x00\x00\x00\x00A\x84" +
-	"\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05\xadp\x00\x00\x00\x00G#\xc2\xf0\x00\x00\x00\x00G\xee\xc9\xf0\x00\x00" +
-	"\x00\x00I\x03\xa4\xf0\x00\x00\x00\x00IΫ\xf0\x00\x00\x00\x00J\xe3\x86\xf0\x00\x00\x00\x00K\xae\x8d\xf0\x00\x00\x00\x00Ḷp\x00\x00\x00\x00M\x8eo\xf0\x00\x00\x00\x00TL\x1d`\x00\x00\x00\x00[\xd4" +
-	"\xed\xf0\x00\x00\x00\x00_\xe7\xb2`\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x01\x04\x01\x04\x01\x02\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04" +
-	"\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x02\x01\x02\x01\x00\x00)\xa4\x00\x00\x00\x00*0\x00\x04\x00\x008@\x00\b\x00\x00FP\x01\f\x00\x008@\x01\bLMT\x00+03\x00+04\x00+05" +
-	"\x00\n<+03>-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTk\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\x12\x00\x1c\x00Europe/Isle_of_ManUT" +
-	"\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f\x00\x00\x00\x05\x00\x00\x00" +
-	"\x11\xff\xff\xff\xff\x1a]\t\xcb\xff\xff\xff\xff\x9b&\xad\xa0\xff\xff\xff\xff\x9b\xd6\x05 \xff\xff\xff\xff\x9c\xcf0\xa0\xff\xff\xff\xff\x9d\xa4à\xff\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff\xff" +
-	"\xff\xa0\x85\xba \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{Ƞ\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6" +
-	" \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00Ӡ\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff" +
-	"\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \xff\xff\xff\xff\xb1\x92Р\xff\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ" +
-	" \xff\xff\xff\xff\xb60\x10\xa0\xff\xff\xff\xff\xb72v\xa0\xff\xff\xff\xff\xb8\x0f\xf2\xa0\xff\xff\xff\xff\xb9\x12X\xa0\xff\xff\xff\xff\xb9\xefԠ\xff\xff\xff\xff\xba\xe9\x00 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff" +
-	"\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy" +
-	" \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xca\x16&\x90\xff\xff\xff\xffʗY\x90\xff\xff\xff" +
-	"\xff\xcb\xd1\x1e\x90\xff\xff\xff\xff\xccw;\x90\xff\xff\xff\xffͱ\x00\x90\xff\xff\xff\xff\xce`X\x10\xff\xff\xff\xffϐ\xe2\x90\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xfb2" +
-	"\x10\xff\xff\xff\xff\xd2i\xfe \xff\xff\xff\xff\xd3c)\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd5B\xfd\x90\xff\xff\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff\xff\xd6N\xac \xff\xff\xff" +
-	"\xff\xd6\xfe\x03\xa0\xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9" +
-	"\xa0\xff\xff\xff\xff\u07b4\xea\xa0\xff\xff\xff\xff߮\x16 \xff\xff\xff\xff\xe0\x94̠\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt \xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4T\x90\xa0\xff\xff\xff" +
-	"\xff\xe52\f\xa0\xff\xff\xff\xff\xe6=\xad \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\v \xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS" +
-	" \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\ue6b1 \xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\x7f_ \xff\xff\xff" +
-	"\xff\xf3Jf \xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\r\xa0\xff\xff\xff\xff\xf6?# \xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0Ѡ\xff\xff\xff\xff\xf9\xfe\xe7" +
-	" \xff\xff\xff\xff\xfa\xc0\xb3\xa0\xff\xff\xff\xff\xfb\xe8\x03\xa0\xff\xff\xff\xff\xfc{\xab\xa0\xff\xff\xff\xff\xfdǻp\x00\x00\x00\x00\x03p\xc6 \x00\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00" +
-	"\x00\x06\t: \x00\x00\x00\x00\a0\x8a \x00\x00\x00\x00\a\xe9\x1c \x00\x00\x00\x00\t\x10l \x00\x00\x00\x00\t\xc8\xfe \x00\x00\x00\x00\n\xf0N \x00\x00\x00\x00\v\xb2\x1a\xa0\x00\x00\x00\x00\f\xd00" +
-	" \x00\x00\x00\x00\r\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \x00\x00\x00\x00\x0fqޠ\x00\x00\x00\x00\x10\x99.\xa0\x00\x00\x00\x00\x11Q\xc0\xa0\x00\x00\x00\x00\x12y\x10\xa0\x00\x00\x00\x00\x131\xa2\xa0\x00\x00\x00" +
-	"\x00\x14X\xf2\xa0\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x168Ɛ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x18\x18\xa8\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19\xf8\x8a\x90\x00\x00\x00\x00\x1aÑ" +
-	"\x90\x00\x00\x00\x00\x1b\xe1\xa7\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\xc1\x89\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f\xa1k\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\x81M\x10\x00\x00\x00" +
-	"\x00\"LT\x10\x00\x00\x00\x00#a/\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%JK\x90\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'*-\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00)\n\x0f" +
-	"\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xe9\xf1\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xc9Ӑ\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\xa9\xb5\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00" +
-	"\x000\x89\x97\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xff\xb5\x00\x00\x00\x00" +
-	"\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x00\x04LMT\x00BST\x00GMT\x00BDST\x00\nGMT0BST,M3.5.0/1,M10" +
-	".5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTk\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\r\x00\x1c\x00Europe/LondonUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94" +
-	"bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01" +
-	"\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f\x00\x00\x00\x05\x00\x00\x00\x11\xff\xff\xff\xff\x1a]\t\xcb\xff" +
-	"\xff\xff\xff\x9b&\xad\xa0\xff\xff\xff\xff\x9b\xd6\x05 \xff\xff\xff\xff\x9c\xcf0\xa0\xff\xff\xff\xff\x9d\xa4à\xff\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff\xff\xff\xa0\x85\xba \xff\xff\xff\xff\xa1" +
-	"v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{Ƞ\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff" +
-	"\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00Ӡ\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf" +
-	"\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \xff\xff\xff\xff\xb1\x92Р\xff\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \xff\xff\xff\xff\xb60\x10\xa0\xff" +
-	"\xff\xff\xff\xb72v\xa0\xff\xff\xff\xff\xb8\x0f\xf2\xa0\xff\xff\xff\xff\xb9\x12X\xa0\xff\xff\xff\xff\xb9\xefԠ\xff\xff\xff\xff\xba\xe9\x00 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd" +
-	"\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff" +
-	"\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xca\x16&\x90\xff\xff\xff\xffʗY\x90\xff\xff\xff\xff\xcb\xd1\x1e\x90\xff\xff\xff\xff\xcc" +
-	"w;\x90\xff\xff\xff\xffͱ\x00\x90\xff\xff\xff\xff\xce`X\x10\xff\xff\xff\xffϐ\xe2\x90\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xfb2\x10\xff\xff\xff\xff\xd2i\xfe \xff" +
-	"\xff\xff\xff\xd3c)\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd5B\xfd\x90\xff\xff\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd6\xfe\x03\xa0\xff\xff\xff\xff\xd8" +
-	".\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\u07b4\xea\xa0\xff" +
-	"\xff\xff\xff߮\x16 \xff\xff\xff\xff\xe0\x94̠\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt \xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4T\x90\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6" +
-	"=\xad \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\v \xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba\xcf \xff" +
-	"\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\ue6b1 \xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\x7f_ \xff\xff\xff\xff\xf3Jf \xff\xff\xff\xff\xf4" +
-	"_A \xff\xff\xff\xff\xf5!\r\xa0\xff\xff\xff\xff\xf6?# \xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0Ѡ\xff\xff\xff\xff\xf9\xfe\xe7 \xff\xff\xff\xff\xfa\xc0\xb3\xa0\xff" +
-	"\xff\xff\xff\xfb\xe8\x03\xa0\xff\xff\xff\xff\xfc{\xab\xa0\xff\xff\xff\xff\xfdǻp\x00\x00\x00\x00\x03p\xc6 \x00\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\t: \x00\x00\x00\x00\a" +
-	"0\x8a \x00\x00\x00\x00\a\xe9\x1c \x00\x00\x00\x00\t\x10l \x00\x00\x00\x00\t\xc8\xfe \x00\x00\x00\x00\n\xf0N \x00\x00\x00\x00\v\xb2\x1a\xa0\x00\x00\x00\x00\f\xd00 \x00\x00\x00\x00\r\x91\xfc\xa0\x00" +
-	"\x00\x00\x00\x0e\xb0\x12 \x00\x00\x00\x00\x0fqޠ\x00\x00\x00\x00\x10\x99.\xa0\x00\x00\x00\x00\x11Q\xc0\xa0\x00\x00\x00\x00\x12y\x10\xa0\x00\x00\x00\x00\x131\xa2\xa0\x00\x00\x00\x00\x14X\xf2\xa0\x00\x00\x00\x00\x15" +
-	"#\xeb\x90\x00\x00\x00\x00\x168Ɛ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x18\x18\xa8\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19\xf8\x8a\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xe1\xa7\x10\x00" +
-	"\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\xc1\x89\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f\xa1k\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\x81M\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#" +
-	"a/\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%JK\x90\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'*-\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00)\n\x0f\x90\x00\x00\x00\x00)\xd5\x16\x90\x00" +
-	"\x00\x00\x00*\xe9\xf1\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xc9Ӑ\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\xa9\xb5\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000\x89\x97\x90\x00\x00\x00\x001" +
-	"]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03" +
-	"\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xff\xb5\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b" +
-	"\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x00\x04LMT\x00BST\x00GMT\x00BDST\x00\nGMT0BST,M3.5.0/1,M10.5.0\nPK\x03\x04\n" +
-	"\x00\x00\x00\x00\x00\x8fj\xbeTgp\xc0\xa7\xb6\x02\x00\x00\xb6\x02\x00\x00\v\x00\x1c\x00Europe/RigaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04" +
-	"S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005\x00\x00\x00\t\x00\x00\x00&\xff\xff\xff\xffV\xb6\xcd^\xff\xff\xff\xff\x9e\xb9\x87\xfe\xff\xff\xff\xff\x9f" +
-	"\x84\x8e\xfe\xff\xff\xff\xff\xa0\x88F~\xff\xff\xff\xff\xa0˂\xfe\xff\xff\xff\xff\xad\xe7\xf1\xde\xff\xff\xff\xffȯd`\xff\xff\xff\xff\xcabeP\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff" +
-	"\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xffА\x89p\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17" +
-	"\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00" +
-	"\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\x19\x00\x00\x00\x00\x00&" +
-	"\f\n\x00\x00\x00\x00\x00'\x055\x80\x00\x00\x00\x00'\xf5&\x80\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd5\b\x80\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4ۀ\x00" +
-	"\x00\x00\x00-\x94̀\x00\x00\x00\x00.\x84\xbd\x80\x00\x00\x00\x00/t\xae\x80\x00\x00\x00\x000d\x9f\x80\x00\x00\x00\x001]\xcb\x00\x00\x00\x00\x002M\xbc\x00\x00\x00\x00\x003=\xbb\x10\x00\x00\x00\x004" +
-	"R\x96\x10\x00\x00\x00\x005\x1d\x9d\x10\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd\x7f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x00:\xbdC\x10\x01\x02\x01\x02\x01\x03\x04\x06\x05\x06\x05\x06\x05\x04\a\x04\a" +
-	"\x04\a\x04\a\x04\a\x04\a\x04\a\x04\a\x04\b\x03\b\x03\b\x03\b\x03\b\x03\b\x03\b\x03\b\x03\b\x03\b\x03\b\x03\b\x00\x00\x16\xa2\x00\x00\x00\x00\x16\xa2\x00\x04\x00\x00$\xb2\x01\b\x00\x00\x1c \x00\f" +
-	"\x00\x00*0\x00\x10\x00\x00\x0e\x10\x00\x14\x00\x00\x1c \x01\x18\x00\x008@\x01\x1d\x00\x00*0\x01!LMT\x00RMT\x00LST\x00EET\x00MSK\x00CET\x00CEST\x00M" +
-	"SD\x00EEST\x00\nEET-2EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTߜvυ\x01\x00\x00" +
-	"\x85\x01\x00\x00\x0e\x00\x1c\x00Europe/AndorraUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x19\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff~6\xb3\x94\xff\xff\xff\xff\xd4A\xdb\x00\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00" +
-	"\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'" +
-	"\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00" +
-	"\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
-	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00\x01l\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x0e\x10\x00\b\x00\x00\x1c \x01\fLMT\x00WET\x00CET\x00CEST\x00\nCET-1CES" +
-	"T,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTIo\x11{\xd3\x02\x00\x00\xd3\x02\x00\x00\r\x00\x1c\x00Europe/Prag" +
-	"ueUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00" +
-	"\x05\x00\x00\x00\x15\xff\xff\xff\xff\x1eI\x92\xf8\xff\xff\xff\xffl\xcf\xea\xf8\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90" +
-	"\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xc8\tq\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff" +
-	"\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2b\a\x10\xff\xff\xff\xffӀ\x1c\x90\xff\xff\xff\xff\xd4I\xd2\x10\xff\xff\xff\xffԓ\xb4 \xff\xff\xff\xff\xd5\x02r \xff\xff\xff\xff\xd5L8\x10\xff\xff\xff\xff\xd6)\xb4" +
-	"\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xd9\x01p\x10\xff\xff\xff\xff\xd9\xe9x\x10\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13MD\x10\x00\x00\x00" +
-	"\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ" +
-	"\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00" +
-	"\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%" +
-	"\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00" +
-	"\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\r\x88\x00\x00\x00\x00\r\x88\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\r\x00\x00\x00\x00\x01\x11LMT\x00PMT\x00CEST\x00CET" +
-	"\x00GMT\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x17S\x91\xb3\xc1\x02\x00\x00\xc1\x02\x00\x00\r" +
-	"\x00\x1c\x00Europe/BerlinUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xffo\xa2a\xf8\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff" +
-	"\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xc8\tq\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xff\xd0" +
-	"\x82%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xffѶ\x96\x00\xff\xff\xff\xff\xd2X\xbe\x80\xff\xff\xff\xffҡO\x10\xff\xff\xff\xff\xd3c\x1b\x90\xff\xff\xff\xff\xd4K#\x90\xff\xff\xff\xff\xd59\xd1 \xff" +
-	"\xff\xff\xff\xd5g\xe7\x90\xff\xff\xff\xffըs\x00\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xd9\x02\xc1\x90\xff\xff\xff\xff\xd9\xe9x\x10\x00\x00\x00\x00\x13" +
-	"MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00" +
-	"\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!" +
-	"\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00" +
-	"\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/" +
-	"t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00\f\x88\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00*0\x01\rLMT\x00CEST\x00CET\x00CEMT" +
-	"\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTq\x16\x9b?\xa3\x02\x00\x00\xa3\x02\x00\x00\x0e\x00\x1c\x00E" +
-	"urope/TallinnUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x004\x00\x00\x00\b\x00\x00\x00\"\xff\xff\xff\xffV\xb6\xcc\xcc\xff\xff\xff\xff\x9eY-\xcc\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xa1\x00+p\xff\xff\xff\xff" +
-	"\xa4soL\xff\xff\xff\xffȰ\xb5\xe0\xff\xff\xff\xff\xcaƗP\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xff\xd0t\xcb\xe0" +
-	"\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00" +
-	"\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0" +
-	"\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\x19\x00\x00\x00\x00\x00&\f\n\x00\x00\x00\x00\x00'\x055\x80\x00\x00\x00\x00'\xf5&\x80\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00" +
-	")\xd5\b\x80\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4ۀ\x00\x00\x00\x00-\x94̀\x00\x00\x00\x00.\x84\xbd\x80\x00\x00\x00\x00/t\xae\x80\x00\x00\x00\x000d\x9f\x80" +
-	"\x00\x00\x00\x001]\xcb\x00\x00\x00\x00\x002r\xa6\x00\x00\x00\x00\x003=\xad\x00\x00\x00\x00\x004R\x88\x00\x00\x00\x00\x005\x1d\x8f\x00\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd\x7f\x10\x00\x00\x00\x00" +
-	"8\x1b\x94\x90\x00\x00\x00\x00<\xa6_\x90\x01\x03\x02\x03\x01\x04\x05\x02\x03\x02\x03\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\a\x04\a\x04\a\x04\a\x04\a\x04\a\x04\a\x04\a\x04\a\x04\a" +
-	"\x04\a\x04\a\x00\x00\x174\x00\x00\x00\x00\x174\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\r\x00\x00\x1c \x00\x11\x00\x00*0\x00\x15\x00\x008@\x01\x19\x00\x00*0\x01\x1dLMT\x00TMT\x00" +
-	"CEST\x00CET\x00EET\x00MSK\x00MSD\x00EEST\x00\nEET-2EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04" +
-	"\n\x00\x00\x00\x00\x00\x8fj\xbeT\x95\xb4\x9e\xe7\xb3\x03\x00\x00\xb3\x03\x00\x00\v\x00\x1c\x00Europe/RomeUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00" +
-	"\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif" +
-	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00W\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff>(\xe8L\xff\xff\xff\xffp\xbc\x81p\xff\xff\xff\xff" +
-	"\x9b8\xf8p\xff\xff\xff\xff\x9b\xd5\xcc\xe0\xff\xff\xff\xff\x9c\xc5\xcb\xf0\xff\xff\xff\xff\x9d\xb7\x00`\xff\xff\xff\xff\x9e\x89\xfep\xff\xff\xff\xff\x9f\xa0\x1c\xe0\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1~\xad`" +
-	"\xff\xff\xff\xff\xa2\\7p\xff\xff\xff\xff\xa3L\x1a`\xff\xff\xff\xff\xc8l5\xf0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xff" +
-	"\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2L\xd2\xf0\xff\xff\xff\xff\xd3>1\x90\xff\xff\xff\xff\xd4I\xd2\x10\xff\xff\xff\xff\xd5\x1d\xf7p\xff\xff\xff\xff\xd6)\x97\xf0\xff\xff\xff\xff\xd6뀐" +
-	"\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xf93\xb5\xf0\xff\xff\xff\xff\xf9\xd9\xc4\xe0\xff\xff\xff\xff\xfb\x1c\xd2p\xff\xff\xff\xff\xfb\xb9\xb4\xf0\xff\xff\xff\xff\xfc\xfc\xb4p\xff\xff\xff\xff\xfd\x99\x96\xf0\xff\xff\xff\xff" +
-	"\xfe\xe5\xd0\xf0\xff\xff\xff\xff\xff\x82\xb3p\x00\x00\x00\x00\x00Ų\xf0\x00\x00\x00\x00\x01b\x95p\x00\x00\x00\x00\x02\x9cZp\x00\x00\x00\x00\x03Bwp\x00\x00\x00\x00\x04\x85v\xf0\x00\x00\x00\x00\x05+\x93\xf0" +
-	"\x00\x00\x00\x00\x06n\x93p\x00\x00\x00\x00\a\vu\xf0\x00\x00\x00\x00\bE:\xf0\x00\x00\x00\x00\b\xebW\xf0\x00\x00\x00\x00\n.Wp\x00\x00\x00\x00\n\xcb9\xf0\x00\x00\x00\x00\f\x0e9p\x00\x00\x00\x00" +
-	"\f\xab\x1b\xf0\x00\x00\x00\x00\r\xe4\xe0\xf0\x00\x00\x00\x00\x0e\x8a\xfd\xf0\x00\x00\x00\x00\x0f\xcd\xfdp\x00\x00\x00\x00\x10t\x1ap\x00\x00\x00\x00\x11\xad\xdfp\x00\x00\x00\x00\x12S\xfcp\x00\x00\x00\x00\x13MD\x10" +
-	"\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00" +
-	"\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10" +
-	"\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00" +
-	"(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90" +
-	"\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
-	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\v\xb4\x00\x00\x00\x00\v\xb4\x00\x04\x00\x00\x1c \x01" +
-	"\b\x00\x00\x0e\x10\x00\rLMT\x00RMT\x00CEST\x00CET\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00" +
-	"\x00\x00\x8fj\xbeTh\xa5J[\xa0\x03\x00\x00\xa0\x03\x00\x00\f\x00\x1c\x00Europe/MaltaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_" +
-	"\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xffp\xbd\xd3d\xff\xff\xff\xff\x9b8\xf8p\xff\xff\xff\xff\x9b\xd5\xcc" +
-	"\xe0\xff\xff\xff\xff\x9c\xc5\xcb\xf0\xff\xff\xff\xff\x9d\xb7\x00`\xff\xff\xff\xff\x9e\x89\xfep\xff\xff\xff\xff\x9f\xa0\x1c\xe0\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1~\xad`\xff\xff\xff\xff\xa2\\7p\xff\xff\xff" +
-	"\xff\xa3L\x1a`\xff\xff\xff\xff\xc8l5\xf0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϐ\xe2\x90\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16" +
-	"\x10\xff\xff\xff\xff\xd2L\xd2\xf0\xff\xff\xff\xff\xd3>1\x90\xff\xff\xff\xff\xd4I\xd2\x10\xff\xff\xff\xff\xd5\x1d\xf7p\xff\xff\xff\xff\xd6)\x97\xf0\xff\xff\xff\xff\xd6뀐\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff" +
-	"\xff\xf93\xb5\xf0\xff\xff\xff\xff\xf9\xd9\xc4\xe0\xff\xff\xff\xff\xfb\x1c\xd2p\xff\xff\xff\xff\xfb\xb9\xb4\xf0\xff\xff\xff\xff\xfc\xfc\xb4p\xff\xff\xff\xff\xfd\x99\x96\xf0\xff\xff\xff\xff\xfe\xe5\xd0\xf0\xff\xff\xff\xff\xff\x82\xb3" +
-	"p\x00\x00\x00\x00\x00Ų\xf0\x00\x00\x00\x00\x01b\x95p\x00\x00\x00\x00\x02\x9cZp\x00\x00\x00\x00\x03Bwp\x00\x00\x00\x00\x04\x85v\xf0\x00\x00\x00\x00\x05+\x93\xf0\x00\x00\x00\x00\x06\x1a3p\x00\x00\x00" +
-	"\x00\a\n$p\x00\x00\x00\x00\b\x17\x16p\x00\x00\x00\x00\b\xda4p\x00\x00\x00\x00\t\xf7\x14\x90\x00\x00\x00\x00\n\xc2\r\x80\x00\x00\x00\x00\v\xd6\xf6\x90\x00\x00\x00\x00\f\xa1\xef\x80\x00\x00\x00\x00\r\xb6\xd8" +
-	"\x90\x00\x00\x00\x00\x0e\x81р\x00\x00\x00\x00\x0f\x96\xba\x90\x00\x00\x00\x00\x10a\xb3\x80\x00\x00\x00\x00\x11v\x9c\x90\x00\x00\x00\x00\x12A\x95\x80\x00\x00\x00\x00\x13E[\x10\x00\x00\x00\x00\x14*\xb2\x00\x00\x00\x00" +
-	"\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd" +
-	"\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00" +
-	"\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16" +
-	"\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00" +
-	"\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00\r\x9c\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\tLMT\x00CEST\x00CE" +
-	"T\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\r\x00\x1c\x00" +
-	"Europe/ZagrebUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00$\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xff^<\xf0H\xff\xff\xff\xff\xca\x025\xe0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xff" +
-	"ϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xffѡ\x8c\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10" +
-	"\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00" +
-	"#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90" +
-	"\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x00" +
-	"1]\xd9\x10\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x138\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\bLM" +
-	"T\x00CET\x00CEST\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xc9\a\xa0\xe1/\x04\x00" +
-	"\x00/\x04\x00\x00\x10\x00\x1c\x00Europe/AmsterdamUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a\x00\x00\x00\a\x00\x00\x00!\xff\xff\xff\xff\x02\x12Ql\xff\xff\xff\xff\x9b\f.\xec\xff\xff\xff\xff\x9b\xd5\xd6\\\xff\xff\xff\xff\x9cٸ\f" +
-	"\xff\xff\xff\xff\x9d\xa4\xbf\f\xff\xff\xff\xff\x9e\xa7%\f\xff\xff\xff\xff\x9f\x97\x16\f\xff\xff\xff\xff\xa0\x90A\x8c\xff\xff\xff\xff\xa1v\xf8\f\xff\xff\xff\xff\xa2p#\x8c\xff\xff\xff\xff\xa3V\xda\f\xff\xff\xff\xff" +
-	"\xa4P\x05\x8c\xff\xff\xff\xff\xa56\xbc\f\xff\xff\xff\xff\xa6%[\x8c\xff\xff\xff\xff\xa7'\xc1\x8c\xff\xff\xff\xff\xa8^\xe3\x8c\xff\xff\xff\xff\xa9\a\xa3\x8c\xff\xff\xff\xff\xa9\xeeZ\f\xff\xff\xff\xff\xaa煌" +
-	"\xff\xff\xff\xff\xac'\xe2\f\xff\xff\xff\xff\xac\xc7g\x8c\xff\xff\xff\xff\xad\xedf\f\xff\xff\xff\xff\xae\xa7I\x8c\xff\xff\xff\xff\xafΙ\x8c\xff\xff\xff\xff\xb0\x87+\x8c\xff\xff\xff\xff\xb1\xb1\x1e\x8c\xff\xff\xff\xff" +
-	"\xb2pH\f\xff\xff\xff\xff\xb3\x92R\f\xff\xff\xff\xff\xb4P*\f\xff\xff\xff\xff\xb5s\x85\x8c\xff\xff\xff\xff\xb60\f\f\xff\xff\xff\xff\xb7T\xb9\f\xff\xff\xff\xff\xb8\x0f\xee\f\xff\xff\xff\xff\xb9@x\x8c" +
-	"\xff\xff\xff\xff\xb9\xef\xd0\f\xff\xff\xff\xff\xbb\x18q\x8c\xff\xff\xff\xff\xbb\xd8\xec\x8c\xff\xff\xff\xff\xbc\xf9\xa5\f\xff\xff\xff\xff\xbd\xb8Ό\xff\xff\xff\xff\xbe\xda،\xff\xff\xff\xff\xbf\x98\xb0\x8c\xff\xff\xff\xff" +
-	"\xc0\xbd]\x8c\xff\xff\xff\xff\xc1x\x92\x8c\xff\xff\xff\xff§ˌ\xff\xff\xff\xff\xc2\xdc]\\\xff\xff\xff\xff\xc3Xtp\xff\xff\xff\xff\xc4\x7f\xc4p\xff\xff\xff\xff\xc58Vp\xff\xff\xff\xff\xc6`\xf7\xf0" +
-	"\xff\xff\xff\xff\xc7!r\xf0\xff\xff\xff\xff\xc8D\xb2P\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff" +
-	"\xd1r\x16\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\r\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90" +
-	"\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00" +
-	"\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10" +
-	"\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00" +
-	"'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː" +
-	"\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x04\x03\x04\x03\x04\x03\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" +
-	"\x06\x00\x00\x04\x94\x00\x00\x00\x00\x12\xa4\x01\x04\x00\x00\x04\x94\x00\b\x00\x00\x04\xb0\x00\f\x00\x00\x12\xc0\x01\x12\x00\x00\x0e\x10\x00\x18\x00\x00\x1c \x01\x1cLMT\x00NST\x00AMT\x00+0020" +
-	"\x00+0120\x00CET\x00CEST\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\x03R" +
-	"\xda\xedU\x02\x00\x00U\x02\x00\x00\x0e\x00\x1c\x00Europe/NicosiaUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif" +
-	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x001\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xff\xa5w\x1e\xb8\x00\x00\x00\x00\t\xed\xaf\xe0\x00\x00\x00\x00\nݒ\xd0\x00\x00\x00\x00\v" +
-	"\xfad\xe0\x00\x00\x00\x00\f\xbe\xc6P\x00\x00\x00\x00\r\xa49`\x00\x00\x00\x00\x0e\x8a\xe1\xd0\x00\x00\x00\x00\x0f\x84\x1b`\x00\x00\x00\x00\x10uO\xd0\x00\x00\x00\x00\x11c\xfd`\x00\x00\x00\x00\x12S\xe0P\x00" +
-	"\x00\x00\x00\x13M\x19\xe0\x00\x00\x00\x00\x143\xc2P\x00\x00\x00\x00\x15#\xc1`\x00\x00\x00\x00\x16\x13\xa4P\x00\x00\x00\x00\x17\x03\xa3`\x00\x00\x00\x00\x17\xf3\x86P\x00\x00\x00\x00\x18\xe3\x85`\x00\x00\x00\x00\x19" +
-	"\xd3hP\x00\x00\x00\x00\x1a\xc3g`\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 lG\xe0\x00" +
-	"\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$,\v\xe0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'" +
-	"\xf5\n`\x00\x00\x00\x00(\xe4\xedP\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00" +
-	"\x00\x00\x00/t\x92`\x00\x00\x00\x000duP\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002M\x91\xd0\x00\x00\x00\x003=\x90\xe0\x00\x00\x00\x004-s\xd0\x00\x00\x00\x005\x1dr\xe0\x00\x00\x00\x006" +
-	"2x\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x1fH\x00\x00\x00\x00" +
-	"*0\x01\x04\x00\x00\x1c \x00\tLMT\x00EEST\x00EET\x00\nEET-2EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\n\x00\x00" +
-	"\x00\x00\x00\x8fj\xbeT\x90\xa9\xf5ϕ\x02\x00\x00\x95\x02\x00\x00\x10\x00\x1c\x00Europe/BucharestUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1" +
-	"\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZ" +
-	"if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x007\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xffl\xcf\xe0\b\xff\xff\xff\xff\xb7\xb0\xd2\b\xff\xff" +
-	"\xff\xff\xb9>\xf3`\xff\xff\xff\xff\xb9\xef\x9c`\xff\xff\xff\xff\xbaߍ`\xff\xff\xff\xff\xbb\xcf~`\xff\xff\xff\xff\xbcȩ\xe0\xff\xff\xff\xff\xbd\xb8\x9a\xe0\xff\xff\xff\xff\xbe\xa8\x8b\xe0\xff\xff\xff\xff\xbf\x98" +
-	"|\xe0\xff\xff\xff\xff\xc0\x88m\xe0\xff\xff\xff\xff\xc1x^\xe0\xff\xff\xff\xff\xc2hO\xe0\xff\xff\xff\xff\xc3X@\xe0\xff\xff\xff\xff\xc4H1\xe0\xff\xff\xff\xff\xc58\"\xe0\xff\xff\xff\xff\xc6(\x13\xe0\xff\xff" +
-	"\xff\xff\xc7\x18\x04\xe0\x00\x00\x00\x00\x11\xad\xd1`\x00\x00\x00\x00\x12S\xe0P\x00\x00\x00\x00\x13M\v\xd0\x00\x00\x00\x00\x143\xd0`\x00\x00\x00\x00\x15#݀\x00\x00\x00\x00\x16\x13\u0380\x00\x00\x00\x00\x17\x03" +
-	"\xbf\x80\x00\x00\x00\x00\x17\xf3\xb0\x80\x00\x00\x00\x00\x18㡀\x00\x00\x00\x00\x19Ӓ\x80\x00\x00\x00\x00\x1aÃ\x80\x00\x00\x00\x00\x1b\xbc\xaf\x00\x00\x00\x00\x00\x1c\xac\xa0\x00\x00\x00\x00\x00\x1d\x9c\x91\x00\x00\x00" +
-	"\x00\x00\x1e\x8c\x82\x00\x00\x00\x00\x00\x1f|s\x00\x00\x00\x00\x00 ld\x00\x00\x00\x00\x00!\\U\x00\x00\x00\x00\x00\"LF\x00\x00\x00\x00\x00#<7\x00\x00\x00\x00\x00$,(\x00\x00\x00\x00\x00%\x1c" +
-	"\x19\x00\x00\x00\x00\x00&\f\n\x00\x00\x00\x00\x00'\x055\x80\x00\x00\x00\x00'\xf5\n`\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xdd`\x00\x00\x00\x00+\xb4\xce`\x00\x00" +
-	"\x00\x00,\xa4\xbf`\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000duP\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002r{\xd0\x00\x00\x00\x003=" +
-	"\xbb\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\x18" +
-	"x\x00\x00\x00\x00\x18x\x00\x04\x00\x00*0\x01\b\x00\x00\x1c \x00\rLMT\x00BMT\x00EEST\x00EET\x00\nEET-2EEST,M3.5.0/3,M1" +
-	"0.5.0/4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x92\xfc\f+o\x02\x00\x00o\x02\x00\x00\x11\x00\x1c\x00Europe/CopenhagenUT\t\x00\x03" +
-	"\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff" +
-	"\xff\xffi\x86ϴ\xff\xff\xff\xffq\f\xef4\xff\xff\xff\xff\x9b\x1e\x8c`\xff\xff\xff\xff\x9bվ\xd0\xff\xff\xff\xff\xc8CWp\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2" +
-	"C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2$\x10\x90\xff\xff\xff\xff\xd3y\x85\x10\xff\xff\xff\xff\xd4\x1b\xad\x90\xff\xff\xff\xff\xd5^\xad\x10\xff\xff" +
-	"\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff\xff\xd7Gɐ\xff\xff\xff\xff\u05ff\xc2\x10\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03" +
-	"͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00" +
-	"\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c" +
-	"'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00" +
-	"\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
-	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\v\xcc\x00\x00\x00\x00\v\xcc\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00" +
-	"\rLMT\x00CMT\x00CEST\x00CET\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT" +
-	"I\xb8\xbc\xd3\xf3\x02\x00\x00\xf3\x02\x00\x00\x0f\x00\x1c\x00Europe/ChisinauUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00T" +
-	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\x00\x00\x00\t\x00\x00\x00&\xff\xff\xff\xffV\xb6\xc8\xf8\xff\xff\xff\xff\x9ek\x9f\f\xff\xff\xff\xff\xb7\xb0\xd2\b\xff\xff" +
-	"\xff\xff\xb9>\xf3`\xff\xff\xff\xff\xb9\xef\x9c`\xff\xff\xff\xff\xbaߍ`\xff\xff\xff\xff\xbb\xcf~`\xff\xff\xff\xff\xbcȩ\xe0\xff\xff\xff\xff\xbd\xb8\x9a\xe0\xff\xff\xff\xff\xbe\xa8\x8b\xe0\xff\xff\xff\xff\xbf\x98" +
-	"|\xe0\xff\xff\xff\xff\xc0\x88m\xe0\xff\xff\xff\xff\xc1x^\xe0\xff\xff\xff\xff\xc2hO\xe0\xff\xff\xff\xff\xc3X@\xe0\xff\xff\xff\xff\xc4H1\xe0\xff\xff\xff\xff\xc58\"\xe0\xff\xff\xff\xff\xc6(\x13\xe0\xff\xff" +
-	"\xff\xff\xc7\x18\x04\xe0\xff\xff\xff\xffȼ\x93`\xff\xff\xff\xff\xcaw}P\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xff\xd0N" +
-	"\x90`\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00" +
-	"\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L" +
-	"7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00&CL\xe0\x00\x00\x00\x00'\x055\x80\x00\x00\x00\x00'\xf5&\x80\x00\x00" +
-	"\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t" +
-	"\x92`\x00\x00\x00\x000duP\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002r{\xd0\x00\x00\x00\x003=\xad\x00\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x06\x05\x06\x05\x06\b" +
-	"\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x1b\b\x00\x00\x00\x00\x1a\xf4\x00\x04\x00\x00\x18x\x00\b\x00\x00*0\x01\f\x00\x00" +
-	"\x1c \x00\x11\x00\x00\x0e\x10\x00\x15\x00\x00\x1c \x01\x19\x00\x008@\x01\x1e\x00\x00*0\x00\"LMT\x00CMT\x00BMT\x00EEST\x00EET\x00CET\x00CEST\x00MS" +
-	"D\x00MSK\x00\nEET-2EEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe5\xc8X\xa7\xe1\x01\x00\x00\xe1\x01\x00\x00" +
-	"\x10\x00\x1c\x00Europe/MariehamnUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00#\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xffS\xba&\x9b\xff\xff\xff\xff\xa4so\x1b\xff\xff\xff\xff\xcb\xceQ`\xff\xff\xff\xff\xcc\xc0\xe5`\x00\x00\x00\x00\x15" +
-	"#݀\x00\x00\x00\x00\x16\x13\u0380\x00\x00\x00\x00\x17\x03\xbf\x80\x00\x00\x00\x00\x17\xf3\xb0\x80\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00" +
-	"\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#" +
-	"<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00" +
-	"\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001" +
-	"]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\x17e\x00\x00\x00\x00\x17e\x00\x04\x00\x00*0\x01\b\x00\x00\x1c " +
-	"\x00\rLMT\x00HMT\x00EEST\x00EET\x00\nEET-2EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8f" +
-	"j\xbeT\x8c\xc8\x15\xd0P\x02\x00\x00P\x02\x00\x00\f\x00\x1c\x00Europe/SofiaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00T" +
-	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-\x00\x00\x00\x06\x00\x00\x00\x1a\xff\xff\xff\xffV\xb6\xce$\xff\xff\xff\xffr\xc3\xe3\x18\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff" +
-	"\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r$ \x00\x00\x00\x00\x11c\xefP\x00\x00\x00\x00\x12U?\xe0\x00\x00\x00\x00\x13M" +
-	"\v\xd0\x00\x00\x00\x00\x145!\xe0\x00\x00\x00\x00\x15,\xed\xd0\x00\x00\x00\x00\x16\x13\xc0p\x00\x00\x00\x00\x17\f\xcf\xd0\x00\x00\x00\x00\x17\xf3\xb0\x80\x00\x00\x00\x00\x18㡀\x00\x00\x00\x00\x19Ӓ\x80\x00\x00" +
-	"\x00\x00\x1aÃ\x80\x00\x00\x00\x00\x1b\xbc\xaf\x00\x00\x00\x00\x00\x1c\xac\xa0\x00\x00\x00\x00\x00\x1d\x9c\x91\x00\x00\x00\x00\x00\x1e\x8c\x82\x00\x00\x00\x00\x00\x1f|s\x00\x00\x00\x00\x00 ld\x00\x00\x00\x00\x00!\\" +
-	"U\x00\x00\x00\x00\x00\"LF\x00\x00\x00\x00\x00#<7\x00\x00\x00\x00\x00$,(\x00\x00\x00\x00\x00%\x1c\x19\x00\x00\x00\x00\x00&\f\n\x00\x00\x00\x00\x00'\x055\x80\x00\x00\x00\x00'\xf5\n`\x00\x00" +
-	"\x00\x00(\xe4\xedP\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t" +
-	"\x92`\x00\x00\x00\x000duP\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002r{\xd0\x00\x00\x00\x003=\xbb\x10\x01\x02\x03\x04\x03\x04\x03\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02" +
-	"\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x00\x00\x15\xdc\x00\x00\x00\x00\x1bh\x00\x04\x00\x00\x1c \x00\b\x00\x00\x0e\x10\x00\f\x00\x00\x1c \x01\x10\x00\x00*0\x01\x15LMT\x00I" +
-	"MT\x00EET\x00CET\x00CEST\x00EEST\x00\nEET-2EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\n\x00\x00\x00\x00" +
-	"\x00\x8fj\xbeT\xcb*j\x8f\xaa\x02\x00\x00\xaa\x02\x00\x00\r\x00\x1c\x00Europe/AthensUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_" +
-	"\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x007\x00\x00\x00\x06\x00\x00\x00\x1a\xff\xff\xff\xfft?\x98D\xff\xff\xff\xff\x9b\x80!\x80\xff\xff\xff\xff\xb9|\xe9" +
-	"\xe0\xff\xff\xff\xff\xb9Ư\xd0\xff\xff\xff\xff\xc9\xf2c\xe0\xff\xff\xff\xff\xca\x10\xa8P\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͪL\xf0\xff\xff\xff\xff\u03a2\x18\xe0\xff\xff\xff\xffϓip\xff\xff\xff" +
-	"\xff\xdf\x13\x9e`\xff\xff\xff\xff߷\nP\x00\x00\x00\x00\t\xec^`\x00\x00\x00\x00\v\x18\xf4`\x00\x00\x00\x00\vͮ\x00\x00\x00\x00\x00\f\xbd\x9f\x00\x00\x00\x00\x00\r\xa4U\x80\x00\x00\x00\x00\x0e\x8c]" +
-	"\x80\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00\x10j\xfc\x10\x00\x00\x00\x00\x11d{\xf0\x00\x00\x00\x00\x12R\xaa\xf0\x00\x00\x00\x00\x13F\x82`\x00\x00\x00\x00\x143\xc2P\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00" +
-	"\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae" +
-	"\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00" +
-	"\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a" +
-	"\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02" +
-	"\x03\x02\x05\x04\x05\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\x16<\x00\x00\x00\x00" +
-	"\x16<\x00\x04\x00\x00*0\x01\b\x00\x00\x1c \x00\r\x00\x00\x0e\x10\x00\x11\x00\x00\x1c \x01\x15LMT\x00AMT\x00EEST\x00EET\x00CET\x00CEST\x00\nEET-2" +
-	"EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xd9L\xf6\xf7\xf1\x01\x00\x00\xf1\x01\x00\x00\x10\x00\x1c\x00Europe" +
-	"/StockholmUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00%\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xffT՟\x94\xff\xff\xff\xff|Usb\xff\xff\xff\xff\x9b\x1e\x8c`\xff\xff\xff\xff\x9b\xd5\xda\xf0\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa" +
-	"\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00" +
-	"\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT" +
-	"\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00" +
-	"\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad" +
-	"\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00\x10\xec\x00\x00\x00\x00\x0e\x1e\x00\x04\x00\x00" +
-	"\x0e\x10\x00\b\x00\x00\x1c \x01\fLMT\x00SET\x00CET\x00CEST\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n" +
-	"\x00\x00\x00\x00\x00\x8fj\xbeT\x95\x7fpp\xdc\x02\x00\x00\xdc\x02\x00\x00\r\x00\x1c\x00Europe/SamaraUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b" +
-	"\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZi" +
-	"f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xa1\x009\x80\xff\xff\xff\xff\xb5\xa4\vP\x00\x00\x00" +
-	"\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\b\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a̅\xc0\x00\x00\x00\x00\x1b\xbc\x92" +
-	"\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\8\xe0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00" +
-	"\x00#<\x1a\xe0\x00\x00\x00\x00$,\v\xe0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\x00\xc7" +
-	"\x00\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xdd`\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xbf`\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\xa1`\x00\x00\x00\x00/t\x92`\x00\x00\x00" +
-	"\x000d\x83`\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002r\x89\xe0\x00\x00\x00\x003=\x90\xe0\x00\x00\x00\x004Rk\xe0\x00\x00\x00\x005\x1dr\xe0\x00\x00\x00\x0062M\xe0\x00\x00\x00\x006\xfdT" +
-	"\xe0\x00\x00\x00\x008\x1bj`\x00\x00\x00\x008\xdd6\xe0\x00\x00\x00\x009\xfbL`\x00\x00\x00\x00:\xbd\x18\xe0\x00\x00\x00\x00;\xdb.`\x00\x00\x00\x00<\xa65`\x00\x00\x00\x00=\xbb\x10`\x00\x00\x00" +
-	"\x00>\x86\x17`\x00\x00\x00\x00?\x9a\xf2`\x00\x00\x00\x00@e\xf9`\x00\x00\x00\x00A\x84\x0e\xe0\x00\x00\x00\x00BE\xdb`\x00\x00\x00\x00Cc\xf0\xe0\x00\x00\x00\x00D%\xbd`\x00\x00\x00\x00EC\xd2" +
-	"\xe0\x00\x00\x00\x00F\x05\x9f`\x00\x00\x00\x00G#\xb4\xe0\x00\x00\x00\x00G\xee\xbb\xe0\x00\x00\x00\x00I\x03\x96\xe0\x00\x00\x00\x00IΝ\xe0\x00\x00\x00\x00J\xe3x\xe0\x00\x00\x00\x00K\xae\x7f\xe0\x00\x00\x00" +
-	"\x00Ḷp\x00\x00\x00\x00M\x8eo\xf0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x01\x04\x01\x05\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x01\x02\x00\x00.\xf4\x00\x00\x00\x00*0\x00\x04\x00\x008@\x00\b\x00\x00FP\x01\f\x00\x008@\x01\b\x00\x00*0\x01\x04LMT\x00+03" +
-	"\x00+04\x00+05\x00\n<+04>-4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTo\xbc\x831O\x04\x00\x00O\x04\x00\x00\x0f\x00\x1c\x00Europe/Bruss" +
-	"elsUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00f\x00\x00" +
-	"\x00\x06\x00\x00\x00\x1a\xff\xff\xff\xffV\xb6\xdf\xe6\xff\xff\xff\xffm\xe8\xc8\x00\xff\xff\xff\xff\x98DI\x80\xff\xff\xff\xff\x9b\f%p\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4" +
-	"\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\x9f\xce\xf80\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1~\xbbp\xff\xff\xff\xff\xa2.\x12\xf0\xff\xff\xff\xff\xa3zL\xf0\xff\xff" +
-	"\xff\xff\xa45\x81\xf0\xff\xff\xff\xff\xa5^#p\xff\xff\xff\xff\xa6%5\xf0\xff\xff\xff\xff\xa7'\x9b\xf0\xff\xff\xff\xff\xa8*\x01\xf0\xff\xff\xff\xff\xa9\a}\xf0\xff\xff\xff\xff\xa9\xee4p\xff\xff\xff\xff\xaa\xe7" +
-	"_\xf0\xff\xff\xff\xff\xab\xd7P\xf0\xff\xff\xff\xff\xac\xc7A\xf0\xff\xff\xff\xff\xadɧ\xf0\xff\xff\xff\xff\xae\xa7#\xf0\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x05\xf0\xff\xff\xff\xff\xb1\x89k\xf0\xff\xff" +
-	"\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \xff\xff\xff\xff\xb60\x10\xa0\xff\xff\xff\xff\xb72v\xa0\xff\xff\xff\xff\xb8\x0f\xf2\xa0\xff\xff\xff\xff\xb8\xff" +
-	"\xe3\xa0\xff\xff\xff\xff\xb9\xefԠ\xff\xff\xff\xff\xba\u058b \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xc8\xe2 \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\x9f\x89\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff" +
-	"\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2h\x88 \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4?/\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X" +
-	"֠\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xc8J\x19 \xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xff\xd0n^\x90\xff\xff" +
-	"\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2N@\x90\xff\xff\xff\xffӑ@\x10\xff\xff\xff\xff\xd4K#\x90\x00\x00\x00\x00\r\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t" +
-	"6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00" +
-	"\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c" +
-	"\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00" +
-	"\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4" +
-	"\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x03\x04\x03\x04\x03\x04\x03\x02\x05\x02\x05\x02\x05\x02\x05\x02" +
-	"\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" +
-	"\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x00\x00\x04\x1a\x00\x00\x00\x00\x04\x1a\x00\x04\x00\x00\x00\x00\x00\b\x00\x00\x0e\x10\x00\f\x00\x00\x1c \x01\x10\x00\x00\x0e\x10\x01\x15" +
-	"LMT\x00BMT\x00WET\x00CET\x00CEST\x00WEST\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00" +
-	"\x00\x00\x00\x00\x8fj\xbeT>\xfe垛\x03\x00\x00\x9b\x03\x00\x00\r\x00\x1c\x00Europe/WarsawUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00" +
-	"\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif" +
-	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00R\x00\x00\x00\x06\x00\x00\x00\x1a\xff\xff\xff\xffV\xb6\xd0P\xff\xff\xff\xff\x99\xa8*\xd0\xff\xff\xff\xff" +
-	"\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xa0\x9a\xb6\x00\xff\xff\xff\xff\xa1e\xbd\x00" +
-	"\xff\xff\xff\xff\xa6}|`\xff\xff\xff\xff\xc8v\xde\x10\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЄ\xba\x00\xff\xff\xff\xff" +
-	"ѕ\x92p\xff\xff\xff\xffҊ\xbb`\xff\xff\xff\xff\xd3b\xffp\xff\xff\xff\xff\xd4K#\x90\xff\xff\xff\xff\xd5^\xad\x10\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\t\x96\x10" +
-	"\xff\xff\xff\xff\xd9\x02\xc1\x90\xff\xff\xff\xff\xd9\xe9x\x10\xff\xff\xff\xff\xe8T\xd2\x00\xff\xff\xff\xff\xe8\xf1\xb4\x80\xff\xff\xff\xff\xe9᥀\xff\xff\xff\xff\xeaі\x80\xff\xff\xff\xff\xec\x14\x96\x00\xff\xff\xff\xff" +
-	"캳\x00\xff\xff\xff\xff\xed\xaa\xa4\x00\xff\xff\xff\xff\ue695\x00\xff\xff\xff\xff\xef\xd4Z\x00\xff\xff\xff\xff\xf0zw\x00\xff\xff\xff\xff\xf1\xb4<\x00\xff\xff\xff\xff\xf2ZY\x00\xff\xff\xff\xff\xf3\x94\x1e\x00" +
-	"\xff\xff\xff\xff\xf4:;\x00\xff\xff\xff\xff\xf5}:\x80\xff\xff\xff\xff\xf6\x1a\x1d\x00\x00\x00\x00\x00\r\xa4U\x80\x00\x00\x00\x00\x0e\x8b\f\x00\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00\x10t(\x80\x00\x00\x00\x00" +
-	"\x11d\x19\x80\x00\x00\x00\x00\x12T\n\x80\x00\x00\x00\x00\x13M6\x00\x00\x00\x00\x00\x143\xec\x80\x00\x00\x00\x00\x15#݀\x00\x00\x00\x00\x16\x13\u0380\x00\x00\x00\x00\x17\x03\xbf\x80\x00\x00\x00\x00\x17\xf3\xb0\x80" +
-	"\x00\x00\x00\x00\x18㡀\x00\x00\x00\x00\x19Ӓ\x80\x00\x00\x00\x00\x1aÃ\x80\x00\x00\x00\x00\x1b\xbc\xaf\x00\x00\x00\x00\x00\x1c\xac\xa0\x00\x00\x00\x00\x00\x1d\x9c\x91\x00\x00\x00\x00\x00\x1e\x8c\x82\x00\x00\x00\x00\x00" +
-	"\x1f|s\x00\x00\x00\x00\x00 ld\x00\x00\x00\x00\x00!\\U\x00\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10" +
-	"\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00" +
-	"-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x05\x04\x05\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00" +
-	"\x13\xb0\x00\x00\x00\x00\x13\xb0\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\r\x00\x00*0\x01\x11\x00\x00\x1c \x00\x16LMT\x00WMT\x00CEST\x00CET\x00EEST\x00EET\x00" +
-	"\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xab\x80c$q\x00\x00\x00q\x00\x00\x00\a\x00\x1c\x00Fa" +
-	"ctoryUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00-00\x00\n<-00>0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTk\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\x02\x00\x1c\x00GBUT" +
-	"\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f\x00\x00\x00\x05\x00\x00\x00" +
-	"\x11\xff\xff\xff\xff\x1a]\t\xcb\xff\xff\xff\xff\x9b&\xad\xa0\xff\xff\xff\xff\x9b\xd6\x05 \xff\xff\xff\xff\x9c\xcf0\xa0\xff\xff\xff\xff\x9d\xa4à\xff\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff\xff" +
-	"\xff\xa0\x85\xba \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{Ƞ\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6" +
-	" \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00Ӡ\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff" +
-	"\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \xff\xff\xff\xff\xb1\x92Р\xff\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ" +
-	" \xff\xff\xff\xff\xb60\x10\xa0\xff\xff\xff\xff\xb72v\xa0\xff\xff\xff\xff\xb8\x0f\xf2\xa0\xff\xff\xff\xff\xb9\x12X\xa0\xff\xff\xff\xff\xb9\xefԠ\xff\xff\xff\xff\xba\xe9\x00 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff" +
-	"\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy" +
-	" \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xca\x16&\x90\xff\xff\xff\xffʗY\x90\xff\xff\xff" +
-	"\xff\xcb\xd1\x1e\x90\xff\xff\xff\xff\xccw;\x90\xff\xff\xff\xffͱ\x00\x90\xff\xff\xff\xff\xce`X\x10\xff\xff\xff\xffϐ\xe2\x90\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xfb2" +
-	"\x10\xff\xff\xff\xff\xd2i\xfe \xff\xff\xff\xff\xd3c)\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd5B\xfd\x90\xff\xff\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff\xff\xd6N\xac \xff\xff\xff" +
-	"\xff\xd6\xfe\x03\xa0\xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9" +
-	"\xa0\xff\xff\xff\xff\u07b4\xea\xa0\xff\xff\xff\xff߮\x16 \xff\xff\xff\xff\xe0\x94̠\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt \xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4T\x90\xa0\xff\xff\xff" +
-	"\xff\xe52\f\xa0\xff\xff\xff\xff\xe6=\xad \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\v \xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS" +
-	" \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\ue6b1 \xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\x7f_ \xff\xff\xff" +
-	"\xff\xf3Jf \xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\r\xa0\xff\xff\xff\xff\xf6?# \xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0Ѡ\xff\xff\xff\xff\xf9\xfe\xe7" +
-	" \xff\xff\xff\xff\xfa\xc0\xb3\xa0\xff\xff\xff\xff\xfb\xe8\x03\xa0\xff\xff\xff\xff\xfc{\xab\xa0\xff\xff\xff\xff\xfdǻp\x00\x00\x00\x00\x03p\xc6 \x00\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00" +
-	"\x00\x06\t: \x00\x00\x00\x00\a0\x8a \x00\x00\x00\x00\a\xe9\x1c \x00\x00\x00\x00\t\x10l \x00\x00\x00\x00\t\xc8\xfe \x00\x00\x00\x00\n\xf0N \x00\x00\x00\x00\v\xb2\x1a\xa0\x00\x00\x00\x00\f\xd00" +
-	" \x00\x00\x00\x00\r\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \x00\x00\x00\x00\x0fqޠ\x00\x00\x00\x00\x10\x99.\xa0\x00\x00\x00\x00\x11Q\xc0\xa0\x00\x00\x00\x00\x12y\x10\xa0\x00\x00\x00\x00\x131\xa2\xa0\x00\x00\x00" +
-	"\x00\x14X\xf2\xa0\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x168Ɛ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x18\x18\xa8\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19\xf8\x8a\x90\x00\x00\x00\x00\x1aÑ" +
-	"\x90\x00\x00\x00\x00\x1b\xe1\xa7\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\xc1\x89\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f\xa1k\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\x81M\x10\x00\x00\x00" +
-	"\x00\"LT\x10\x00\x00\x00\x00#a/\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%JK\x90\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'*-\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00)\n\x0f" +
-	"\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xe9\xf1\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xc9Ӑ\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\xa9\xb5\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00" +
-	"\x000\x89\x97\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xff\xb5\x00\x00\x00\x00" +
-	"\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x00\x04LMT\x00BST\x00GMT\x00BDST\x00\nGMT0BST,M3.5.0/1,M10" +
-	".5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTk\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\a\x00\x1c\x00GB-EireUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01" +
-	"\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" +
-	"\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f\x00\x00\x00\x05\x00\x00\x00\x11\xff\xff\xff\xff\x1a]\t\xcb\xff\xff\xff\xff\x9b&\xad" +
-	"\xa0\xff\xff\xff\xff\x9b\xd6\x05 \xff\xff\xff\xff\x9c\xcf0\xa0\xff\xff\xff\xff\x9d\xa4à\xff\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff\xff\xff\xa0\x85\xba \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff" +
-	"\xff\xa2e\x9c \xff\xff\xff\xff\xa3{Ƞ\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8" +
-	"\xa0\xff\xff\xff\xff\xaa\x00Ӡ\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff" +
-	"\xff\xb0\x870 \xff\xff\xff\xff\xb1\x92Р\xff\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \xff\xff\xff\xff\xb60\x10\xa0\xff\xff\xff\xff\xb72v" +
-	"\xa0\xff\xff\xff\xff\xb8\x0f\xf2\xa0\xff\xff\xff\xff\xb9\x12X\xa0\xff\xff\xff\xff\xb9\xefԠ\xff\xff\xff\xff\xba\xe9\x00 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff" +
-	"\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[" +
-	" \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xca\x16&\x90\xff\xff\xff\xffʗY\x90\xff\xff\xff\xff\xcb\xd1\x1e\x90\xff\xff\xff\xff\xccw;\x90\xff\xff\xff" +
-	"\xffͱ\x00\x90\xff\xff\xff\xff\xce`X\x10\xff\xff\xff\xffϐ\xe2\x90\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xfb2\x10\xff\xff\xff\xff\xd2i\xfe \xff\xff\xff\xff\xd3c)" +
-	"\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd5B\xfd\x90\xff\xff\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd6\xfe\x03\xa0\xff\xff\xff\xff\xd8.\x8e \xff\xff\xff" +
-	"\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\u07b4\xea\xa0\xff\xff\xff\xff߮\x16" +
-	" \xff\xff\xff\xff\xe0\x94̠\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt \xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4T\x90\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6=\xad \xff\xff\xff" +
-	"\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\v \xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa" +
-	"\xa0\xff\xff\xff\xff\ue6b1 \xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\x7f_ \xff\xff\xff\xff\xf3Jf \xff\xff\xff\xff\xf4_A \xff\xff\xff" +
-	"\xff\xf5!\r\xa0\xff\xff\xff\xff\xf6?# \xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0Ѡ\xff\xff\xff\xff\xf9\xfe\xe7 \xff\xff\xff\xff\xfa\xc0\xb3\xa0\xff\xff\xff\xff\xfb\xe8\x03" +
-	"\xa0\xff\xff\xff\xff\xfc{\xab\xa0\xff\xff\xff\xff\xfdǻp\x00\x00\x00\x00\x03p\xc6 \x00\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\t: \x00\x00\x00\x00\a0\x8a \x00\x00\x00" +
-	"\x00\a\xe9\x1c \x00\x00\x00\x00\t\x10l \x00\x00\x00\x00\t\xc8\xfe \x00\x00\x00\x00\n\xf0N \x00\x00\x00\x00\v\xb2\x1a\xa0\x00\x00\x00\x00\f\xd00 \x00\x00\x00\x00\r\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12" +
-	" \x00\x00\x00\x00\x0fqޠ\x00\x00\x00\x00\x10\x99.\xa0\x00\x00\x00\x00\x11Q\xc0\xa0\x00\x00\x00\x00\x12y\x10\xa0\x00\x00\x00\x00\x131\xa2\xa0\x00\x00\x00\x00\x14X\xf2\xa0\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00" +
-	"\x00\x168Ɛ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x18\x18\xa8\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19\xf8\x8a\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xe1\xa7\x10\x00\x00\x00\x00\x1c\xac\xae" +
-	"\x10\x00\x00\x00\x00\x1d\xc1\x89\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f\xa1k\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\x81M\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#a/\x10\x00\x00\x00" +
-	"\x00$,6\x10\x00\x00\x00\x00%JK\x90\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'*-\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00)\n\x0f\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xe9\xf1" +
-	"\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xc9Ӑ\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\xa9\xb5\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000\x89\x97\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02" +
-	"\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xff\xb5\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x1c \x01\f" +
-	"\x00\x00\x0e\x10\x00\x04LMT\x00BST\x00GMT\x00BDST\x00\nGMT0BST,M3.5.0/1,M10.5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8f" +
-	"j\xbeTP\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\x03\x00\x1c\x00GMTUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTP\xda\xfa\x03o" +
-	"\x00\x00\x00o\x00\x00\x00\x05\x00\x1c\x00GMT+0UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTP\xda\xfa\x03o\x00\x00\x00o\x00\x00" +
-	"\x00\x05\x00\x1c\x00GMT-0UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTP\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\x04\x00\x1c\x00G" +
-	"MT0UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTP\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\t\x00\x1c\x00Greenwic" +
-	"hUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" +
-	"\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT=\xf7\xfawp\x00\x00\x00p\x00\x00\x00\x03\x00\x1c\x00HSTUT\t\x00\x03\xdd\xfc" +
-	"\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xffs`" +
-	"\x00\x00HST\x00\nHST10\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeTE\t\xfa-\a\x03\x00\x00\a\x03\x00\x00\b\x00\x1c\x00HongkongUT\t\x00\x03\xdc\xfc\x94b" +
-	"\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00" +
-	"\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\x00\x00\x00\x05\x00\x00\x00\x16\xff\xff\xff\xff\x85i" +
-	"c\x90\xff\xff\xff\xff\xcaM10\xff\xff\xff\xff\xcaۓ0\xff\xff\xff\xff\xcbKqx\xff\xff\xff\xffҠސ\xff\xff\xff\xff\xd3k׀\xff\xff\xff\xffԓX\xb8\xff\xff\xff\xff\xd5B\xb08\xff\xff" +
-	"\xff\xff\xd6s:\xb8\xff\xff\xff\xff\xd7>A\xb8\xff\xff\xff\xff\xd8.2\xb8\xff\xff\xff\xff\xd8\xf99\xb8\xff\xff\xff\xff\xda\x0e\x14\xb8\xff\xff\xff\xff\xda\xd9\x1b\xb8\xff\xff\xff\xff\xdb\xed\xf6\xb8\xff\xff\xff\xffܸ" +
-	"\xfd\xb8\xff\xff\xff\xff\xdd\xcdظ\xff\xff\xff\xffޢ\x1a8\xff\xff\xff\xff߶\xf58\xff\xff\xff\xff\xe0\x81\xfc8\xff\xff\xff\xff\xe1\x96\xc9(\xff\xff\xff\xff\xe2Oi8\xff\xff\xff\xff\xe3v\xab(\xff\xff" +
-	"\xff\xff\xe4/K8\xff\xff\xff\xff\xe5_Ǩ\xff\xff\xff\xff\xe6\x0f-8\xff\xff\xff\xff\xe7?\xa9\xa8\xff\xff\xff\xff\xe7\xf8I\xb8\xff\xff\xff\xff\xe9\x1f\x8b\xa8\xff\xff\xff\xff\xe9\xd8+\xb8\xff\xff\xff\xff\xea\xff" +
-	"m\xa8\xff\xff\xff\xff\xeb\xb8\r\xb8\xff\xff\xff\xff\xec\xdfO\xa8\xff\xff\xff\xff\xed\x97\xef\xb8\xff\xff\xff\xff\xee\xc8l(\xff\xff\xff\xff\xefwѸ\xff\xff\xff\xff\xf0\xa8N(\xff\xff\xff\xff\xf1W\xb3\xb8\xff\xff" +
-	"\xff\xff\xf2\x880(\xff\xff\xff\xff\xf3@\xd08\xff\xff\xff\xff\xf4h\x12(\xff\xff\xff\xff\xf5 \xb28\xff\xff\xff\xff\xf6G\xf4(\xff\xff\xff\xff\xf7%~8\xff\xff\xff\xff\xf8\x15a(\xff\xff\xff\xff\xf9\x05" +
-	"`8\xff\xff\xff\xff\xf9\xf5C(\xff\xff\xff\xff\xfa\xe5B8\xff\xff\xff\xff\xfb\xde_\xa8\xff\xff\xff\xff\xfc\xce^\xb8\xff\xff\xff\xff\xfd\xbeA\xa8\xff\xff\xff\xff\xfe\xae@\xb8\xff\xff\xff\xff\xff\x9e#\xa8\x00\x00" +
-	"\x00\x00\x00\x8e\"\xb8\x00\x00\x00\x00\x01~\x05\xa8\x00\x00\x00\x00\x02n\x04\xb8\x00\x00\x00\x00\x03]\xe7\xa8\x00\x00\x00\x00\x04M\xe6\xb8\x00\x00\x00\x00\x05G\x04(\x00\x00\x00\x00\x067\x038\x00\x00\x00\x00\a&" +
-	"\xe6(\x00\x00\x00\x00\a\x83=8\x00\x00\x00\x00\t\x06\xc8(\x00\x00\x00\x00\t\xf6\xc78\x00\x00\x00\x00\n\xe6\xaa(\x00\x00\x00\x00\v֩8\x00\x00\x00\x00\fƌ(\x00\x00\x00\x00\x11\x9b98\x00\x00" +
-	"\x00\x00\x12ol\xa8\x01\x02\x03\x04\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00k\n\x00\x00\x00\x00p\x80\x00\x04\x00\x00~\x90\x01\b\x00\x00w\x88\x01\r\x00\x00~\x90\x00\x12LMT\x00HKT\x00HKST\x00HK" +
-	"WT\x00JST\x00\nHKT-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTm\xbd\x10k\xf1\x02\x00\x00\xf1\x02\x00\x00\a\x00\x1c\x00IcelandUT\t\x00\x03\xdd\xfc\x94b" +
-	"\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00" +
-	"\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00D\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\x8b`" +
-	"\x83\xa0\xff\xff\xff\xff\x9c\x91\x1e\x00\xff\xff\xff\xff\x9dш\x90\xff\xff\xff\xff\x9erQ\x80\xff\xff\xff\xff\x9f\xd5\x03\x10\xff\xff\xff\xff\xa0S\x85\x00\xff\xff\xff\xff\xa1\xb66\x90\xff\xff\xff\xff\xa4<'\x80\xff\xff" +
-	"\xff\xff\xa4\xb9t\x10\xff\xff\xff\xff\xc6M\x1a\x00\xff\xff\xff\xff\xc7=' \xff\xff\xff\xff\xc7\xda\x17\xb0\xff\xff\xff\xff\xc9&C\xa0\xff\xff\xff\xff\xc9\xc3& \xff\xff\xff\xff\xcb\x06%\xa0\xff\xff\xff\xffˬ" +
-	"B\xa0\xff\xff\xff\xff\xcc\xdc\xcd \xff\xff\xff\xff͌$\xa0\xff\xff\xff\xffμ\xaf \xff\xff\xff\xff\xcfl\x06\xa0\xff\xff\xff\xffМ\x91 \xff\xff\xff\xff\xd1K\xe8\xa0\xff\xff\xff\xff҅\xad\xa0\xff\xff" +
-	"\xff\xff\xd3+ʠ\xff\xff\xff\xff\xd4e\x8f\xa0\xff\xff\xff\xff\xd59\xd1 \xff\xff\xff\xff\xd6Eq\xa0\xff\xff\xff\xff\xd7\x19\xb3 \xff\xff\xff\xff\xd8%S\xa0\xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0e" +
-	"p \xff\xff\xff\xff\xda\xd9w \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xffܹY \xff\xff\xff\xff\xdd\xce4 \xff\xff\xff\xffޢu\xa0\xff\xff\xff\xff߮\x16 \xff\xff\xff\xff\xe0\x82W\xa0\xff\xff" +
-	"\xff\xff\xe1\x8d\xf8 \xff\xff\xff\xff\xe2b9\xa0\xff\xff\xff\xff\xe3m\xda \xff\xff\xff\xff\xe4B\x1b\xa0\xff\xff\xff\xff\xe5M\xbc \xff\xff\xff\xff\xe6!\xfd\xa0\xff\xff\xff\xff\xe76ؠ\xff\xff\xff\xff\xe8\v" +
-	"\x1a \xff\xff\xff\xff\xe9\x16\xba\xa0\xff\xff\xff\xff\xe9\xea\xfc \xff\xff\xff\xff\xea\xf6\x9c\xa0\xff\xff\xff\xff\xeb\xca\xde \xff\xff\xff\xff\xec\xd6~\xa0\xff\xff\xff\xff\xed\xaa\xc0 \xff\xff\xff\xff\xee\xb6`\xa0\xff\xff" +
-	"\xff\xff\uf2a2 \xff\xff\xff\xff\xf0\x96B\xa0\xff\xff\xff\xff\xf1j\x84 \xff\xff\xff\xff\xf2\x7f_ \xff\xff\xff\xff\xf3S\xa0\xa0\xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf53\x82\xa0\xff\xff\xff\xff\xf6?" +
-	"# \xff\xff\xff\xff\xf7\x13d\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xf3F\xa0\xff\xff\xff\xff\xf9\xfe\xe7 \xff\xff\xff\xff\xfa\xd3(\xa0\xff\xff\xff\xff\xfb\xe8\x03\xa0\xff\xff\xff\xff\xfc\xbcE \x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x03\xff\xff\xeb`\x00\x00\x00\x00\x00\x00\x01\x04\xff\xff\xf1\xf0\x00\b\x00\x00\x00\x00\x00\fLMT\x00+00\x00-01\x00GMT\x00\nGMT0\nPK\x03\x04\n\x00\x00\x00" +
-	"\x00\x00\x8fj\xbeT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x1c\x00Indian/UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x03" +
-	"\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\x96\xed=\x98\xb3\x00\x00\x00\xb3\x00\x00\x00\x10\x00\x1c\x00Indian/MauritiusUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00" +
-	"\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00" +
-	"\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x89\x7f\x05\x98\x00\x00\x00\x00\x18\x05" +
-	"\xed@\x00\x00\x00\x00\x18\xdbr0\x00\x00\x00\x00I\x03\x96\xe0\x00\x00\x00\x00IΏ\xd0\x02\x01\x02\x01\x02\x00\x005\xe8\x00\x00\x00\x00FP\x01\x04\x00\x008@\x00\bLMT\x00+05\x00+04" +
-	"\x00\n<+04>-4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeTx\xb0W\x14\x98\x00\x00\x00\x98\x00\x00\x00\r\x00\x1c\x00Indian/ChagosUT\t\x00\x03\xdc\xfc" +
-	"\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff" +
-	"\x89~\xf7\x9c\x00\x00\x00\x000\xe6ݰ\x01\x02\x00\x00C\xe4\x00\x00\x00\x00FP\x00\x04\x00\x00T`\x00\bLMT\x00+05\x00+06\x00\n<+06>-6\nPK\x03\x04\n\x00\x00" +
-	"\x00\x00\x00\x8ej\xbeT\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\x0e\x00\x1c\x00Indian/MayotteUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00" +
-	"\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif" +
-	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff" +
-	"\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1\xed\xadX\xff\xff\xff\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\"\x84\x00\x00\x00\x00#(\x00\x04\x00\x00*0\x00\n\x00\x00&\xac\x00\x0eLMT\x00+0230\x00E" +
-	"AT\x00+0245\x00\nEAT-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT$l=҅\x00\x00\x00\x85\x00\x00\x00\x10\x00\x1c\x00Indian/Christm" +
-	"asUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" +
-	"\x02\x00\x00\x00\b\xff\xff\xff\xffs\x16\xa9\xe4\x01\x00\x00c\x1c\x00\x00\x00\x00bp\x00\x04LMT\x00+07\x00\n<+07>-7\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTͲ\xfb" +
-	"\xf6\x8c\x00\x00\x00\x8c\x00\x00\x00\f\x00\x1c\x00Indian/CocosUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\n\xff\xff\xff\xff|U&\xa4\x01\x00\x00Z\xdc\x00\x00\x00\x00[h\x00\x04LMT\x00+0630\x00\n" +
-	"<+0630>-6:30\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xb9\xb2Z\xac\x98\x00\x00\x00\x98\x00\x00\x00\x0f\x00\x1c\x00Indian/MaldivesUT" +
-	"\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00" +
-	"\f\xff\xff\xff\xffV\xb6\x9f\x18\xff\xff\xff\xff\xed/Ø\x01\x02\x00\x00D\xe8\x00\x00\x00\x00D\xe8\x00\x04\x00\x00FP\x00\bLMT\x00MMT\x00+05\x00\n<+05>-5\nPK" +
-	"\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\r\x00\x1c\x00Indian/ComoroUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04" +
-	"\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" +
-	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX" +
-	"\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1\xed\xadX\xff\xff\xff\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\"\x84\x00\x00\x00\x00#(\x00\x04\x00\x00*0\x00\n\x00\x00&\xac\x00\x0eLMT\x00+02" +
-	"30\x00EAT\x00+0245\x00\nEAT-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeTy(\xb6\x8f\x85\x00\x00\x00\x85\x00\x00\x00\x0e\x00\x1c\x00Indian/Reu" +
-	"nionUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00" +
-	"\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x91\xcc9\x80\x01\x00\x004\x00\x00\x00\x00\x008@\x00\x04LMT\x00+04\x00\n<+04>-4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeTa" +
-	"\x85jo\x85\x00\x00\x00\x85\x00\x00\x00\v\x00\x1c\x00Indian/MaheUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x89\x7f\a\x84\x01\x00\x003\xfc\x00\x00\x00\x008@\x00\x04LMT\x00+04\x00\n<" +
-	"+04>-4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\xb8K\xabυ\x00\x00\x00\x85\x00\x00\x00\x10\x00\x1c\x00Indian/KerguelenUT\t\x00\x03\xdc\xfc" +
-	"\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff" +
-	"\xdaab\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00FP\x00\x04-00\x00+05\x00\n<+05>-5\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00" +
-	"\x13\x00\x1c\x00Indian/AntananarivoUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1\xed\xadX\xff\xff" +
-	"\xff\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\"\x84\x00\x00\x00\x00#(\x00\x04\x00\x00*0\x00\n\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00+0245\x00\nEAT-" +
-	"3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT;\x7fP\x8d\xd4\a\x00\x00\xd4\a\x00\x00\x04\x00\x1c\x00IranUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04" +
-	"S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc9\x00\x00\x00\x06\x00\x00\x00\x1c\xff\xff\xff\xff\x9al}\xc8\xff\xff\xff\xff\xd2\xdb\x12\xc8\x00\x00\x00\x00\x0e" +
-	"\xbb\xa2H\x00\x00\x00\x00\x0ft-@\x00\x00\x00\x00\x10\x8e@0\x00\x00\x00\x00\x10\xed:@\x00\x00\x00\x00\x11Ug\xc8\x00\x00\x00\x00\x12EJ\xb8\x00\x00\x00\x00\x137\xec\xc8\x00\x00\x00\x00\x14-\x15\xb8\x00" +
-	"\x00\x00\x00( v\xc8\x00\x00\x00\x00(\u06dd\xb8\x00\x00\x00\x00)˜\xc8\x00\x00\x00\x00*\xbe\"\xb8\x00\x00\x00\x00+\xac\xd0H\x00\x00\x00\x00,\x9fV8\x00\x00\x00\x00-\x8e\x03\xc8\x00\x00\x00\x00." +
-	"\x80\x89\xb8\x00\x00\x00\x00/o7H\x00\x00\x00\x000a\xbd8\x00\x00\x00\x001Pj\xc8\x00\x00\x00\x002B\xf0\xb8\x00\x00\x00\x0032\xef\xc8\x00\x00\x00\x004%u\xb8\x00\x00\x00\x005\x14#H\x00" +
-	"\x00\x00\x006\x06\xa98\x00\x00\x00\x006\xf5V\xc8\x00\x00\x00\x007\xe7ܸ\x00\x00\x00\x008֊H\x00\x00\x00\x009\xc9\x108\x00\x00\x00\x00:\xb9\x0fH\x00\x00\x00\x00;\xab\x958\x00\x00\x00\x00<" +
-	"\x9aB\xc8\x00\x00\x00\x00=\x8cȸ\x00\x00\x00\x00>{vH\x00\x00\x00\x00?m\xfc8\x00\x00\x00\x00@\\\xa9\xc8\x00\x00\x00\x00AO/\xb8\x00\x00\x00\x00B?.\xc8\x00\x00\x00\x00C1\xb4\xb8\x00" +
-	"\x00\x00\x00G\xe2\xc9H\x00\x00\x00\x00H\xd5O8\x00\x00\x00\x00I\xc5NH\x00\x00\x00\x00J\xb7\xd48\x00\x00\x00\x00K\xa6\x81\xc8\x00\x00\x00\x00L\x99\a\xb8\x00\x00\x00\x00M\x87\xb5H\x00\x00\x00\x00N" +
-	"z;8\x00\x00\x00\x00Oh\xe8\xc8\x00\x00\x00\x00P[n\xb8\x00\x00\x00\x00QKm\xc8\x00\x00\x00\x00R=\xf3\xb8\x00\x00\x00\x00S,\xa1H\x00\x00\x00\x00T\x1f'8\x00\x00\x00\x00U\r\xd4\xc8\x00" +
-	"\x00\x00\x00V\x00Z\xb8\x00\x00\x00\x00V\xef\bH\x00\x00\x00\x00W\xe1\x8e8\x00\x00\x00\x00XэH\x00\x00\x00\x00Y\xc4\x138\x00\x00\x00\x00Z\xb2\xc0\xc8\x00\x00\x00\x00[\xa5F\xb8\x00\x00\x00\x00\\" +
-	"\x93\xf4H\x00\x00\x00\x00]\x86z8\x00\x00\x00\x00^u'\xc8\x00\x00\x00\x00_g\xad\xb8\x00\x00\x00\x00`W\xac\xc8\x00\x00\x00\x00aJ2\xb8\x00\x00\x00\x00b8\xe0H\x00\x00\x00\x00c+f8\x00" +
-	"\x00\x00\x00d\x1a\x13\xc8\x00\x00\x00\x00e\f\x99\xb8\x00\x00\x00\x00e\xfbGH\x00\x00\x00\x00f\xed\xcd8\x00\x00\x00\x00g\xdd\xccH\x00\x00\x00\x00h\xd0R8\x00\x00\x00\x00i\xbe\xff\xc8\x00\x00\x00\x00j" +
-	"\xb1\x85\xb8\x00\x00\x00\x00k\xa03H\x00\x00\x00\x00l\x92\xb98\x00\x00\x00\x00m\x81f\xc8\x00\x00\x00\x00ns\xec\xb8\x00\x00\x00\x00ob\x9aH\x00\x00\x00\x00pU 8\x00\x00\x00\x00qE\x1fH\x00" +
-	"\x00\x00\x00r7\xa58\x00\x00\x00\x00s&R\xc8\x00\x00\x00\x00t\x18ظ\x00\x00\x00\x00u\a\x86H\x00\x00\x00\x00u\xfa\f8\x00\x00\x00\x00v\xe8\xb9\xc8\x00\x00\x00\x00w\xdb?\xb8\x00\x00\x00\x00x" +
-	"\xcb>\xc8\x00\x00\x00\x00y\xbdĸ\x00\x00\x00\x00z\xacrH\x00\x00\x00\x00{\x9e\xf88\x00\x00\x00\x00|\x8d\xa5\xc8\x00\x00\x00\x00}\x80+\xb8\x00\x00\x00\x00~n\xd9H\x00\x00\x00\x00\x7fa_8\x00" +
-	"\x00\x00\x00\x80Q^H\x00\x00\x00\x00\x81C\xe48\x00\x00\x00\x00\x822\x91\xc8\x00\x00\x00\x00\x83%\x17\xb8\x00\x00\x00\x00\x84\x13\xc5H\x00\x00\x00\x00\x85\x06K8\x00\x00\x00\x00\x85\xf4\xf8\xc8\x00\x00\x00\x00\x86" +
-	"\xe7~\xb8\x00\x00\x00\x00\x87\xd7}\xc8\x00\x00\x00\x00\x88\xca\x03\xb8\x00\x00\x00\x00\x89\xb8\xb1H\x00\x00\x00\x00\x8a\xab78\x00\x00\x00\x00\x8b\x99\xe4\xc8\x00\x00\x00\x00\x8c\x8cj\xb8\x00\x00\x00\x00\x8d{\x18H\x00" +
-	"\x00\x00\x00\x8em\x9e8\x00\x00\x00\x00\x8f]\x9dH\x00\x00\x00\x00\x90P#8\x00\x00\x00\x00\x91>\xd0\xc8\x00\x00\x00\x00\x921V\xb8\x00\x00\x00\x00\x93 \x04H\x00\x00\x00\x00\x94\x12\x8a8\x00\x00\x00\x00\x95" +
-	"\x017\xc8\x00\x00\x00\x00\x95\xf3\xbd\xb8\x00\x00\x00\x00\x96\xe3\xbc\xc8\x00\x00\x00\x00\x97\xd6B\xb8\x00\x00\x00\x00\x98\xc4\xf0H\x00\x00\x00\x00\x99\xb7v8\x00\x00\x00\x00\x9a\xa6#\xc8\x00\x00\x00\x00\x9b\x98\xa9\xb8\x00" +
-	"\x00\x00\x00\x9c\x87WH\x00\x00\x00\x00\x9dy\xdd8\x00\x00\x00\x00\x9ei\xdcH\x00\x00\x00\x00\x9f\\b8\x00\x00\x00\x00\xa0K\x0f\xc8\x00\x00\x00\x00\xa1=\x95\xb8\x00\x00\x00\x00\xa2,CH\x00\x00\x00\x00\xa3" +
-	"\x1e\xc98\x00\x00\x00\x00\xa4\rv\xc8\x00\x00\x00\x00\xa4\xff\xfc\xb8\x00\x00\x00\x00\xa5\xef\xfb\xc8\x00\x00\x00\x00\xa6⁸\x00\x00\x00\x00\xa7\xd1/H\x00\x00\x00\x00\xa8õ8\x00\x00\x00\x00\xa9\xb2b\xc8\x00" +
-	"\x00\x00\x00\xaa\xa4\xe8\xb8\x00\x00\x00\x00\xab\x93\x96H\x00\x00\x00\x00\xac\x86\x1c8\x00\x00\x00\x00\xadt\xc9\xc8\x00\x00\x00\x00\xaegO\xb8\x00\x00\x00\x00\xafWN\xc8\x00\x00\x00\x00\xb0IԸ\x00\x00\x00\x00\xb1" +
-	"8\x82H\x00\x00\x00\x00\xb2+\b8\x00\x00\x00\x00\xb3\x19\xb5\xc8\x00\x00\x00\x00\xb4\f;\xb8\x00\x00\x00\x00\xb4\xfa\xe9H\x00\x00\x00\x00\xb5\xedo8\x00\x00\x00\x00\xb6\xddnH\x00\x00\x00\x00\xb7\xcf\xf48\x00" +
-	"\x00\x00\x00\xb8\xbe\xa1\xc8\x00\x00\x00\x00\xb9\xb1'\xb8\x00\x00\x00\x00\xba\x9f\xd5H\x00\x00\x00\x00\xbb\x92[8\x00\x00\x00\x00\xbc\x81\b\xc8\x00\x00\x00\x00\xbds\x8e\xb8\x00\x00\x00\x00\xbec\x8d\xc8\x00\x00\x00\x00\xbf" +
-	"V\x13\xb8\x00\x00\x00\x00\xc0D\xc1H\x00\x00\x00\x00\xc17G8\x00\x00\x00\x00\xc2%\xf4\xc8\x00\x00\x00\x00\xc3\x18z\xb8\x00\x00\x00\x00\xc4\a(H\x00\x00\x00\x00\xc4\xf9\xae8\x00\x00\x00\x00\xc5\xe9\xadH\x00" +
-	"\x00\x00\x00\xc6\xdc38\x00\x00\x00\x00\xc7\xca\xe0\xc8\x00\x00\x00\x00Ƚf\xb8\x00\x00\x00\x00ɬ\x14H\x00\x00\x00\x00ʞ\x9a8\x00\x00\x00\x00ˍG\xc8\x00\x00\x00\x00\xcc\x7f\u0378\x00\x00\x00\x00\xcd" +
-	"o\xcc\xc8\x00\x00\x00\x00\xcebR\xb8\x00\x00\x00\x00\xcfQ\x00H\x00\x00\x00\x00\xd0C\x868\x00\x00\x00\x00\xd123\xc8\x00\x00\x00\x00\xd2$\xb9\xb8\x00\x00\x00\x00\xd3\x13gH\x00\x00\x00\x00\xd4\x05\xed8\x00" +
-	"\x00\x00\x00\xd4\xf5\xecH\x00\x00\x00\x00\xd5\xe8r8\x00\x00\x00\x00\xd6\xd7\x1f\xc8\x00\x00\x00\x00\xd7ɥ\xb8\x00\x00\x00\x00ظSH\x00\x00\x00\x00٪\xd98\x00\x00\x00\x00ڙ\x86\xc8\x00\x00\x00\x00\xdb" +
-	"\x8c\f\xb8\x00\x00\x00\x00\xdc|\v\xc8\x00\x00\x00\x00\xddn\x91\xb8\x00\x00\x00\x00\xde]?H\x01\x02\x04\x03\x04\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05" +
-	"\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05" +
-	"\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05" +
-	"\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x00\x0008\x00\x00\x00\x0008\x00\x04" +
-	"\x00\x0018\x00\b\x00\x00FP\x01\x0e\x00\x008@\x00\x12\x00\x00?H\x01\x16LMT\x00TMT\x00+0330\x00+05\x00+04\x00+0430\x00\n<+0330>" +
-	"-3:30<+0430>,J79/24,J263/24\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x17✳2\x04\x00\x002\x04\x00\x00\x06\x00\x1c\x00Is" +
-	"raelUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x00" +
-	"\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xffV\xb6\xc2\xfa\xff\xff\xff\xff\x9e0E\x88\xff\xff\xff\xff\xc8Y\xcf\x00\xff\xff\xff\xff\xc8\xfa\xa6\x00\xff\xff\xff\xff\xc98\x9c\x80\xff\xff\xff\xff\xcc\xe5\xeb\x80\xff\xff\xff\xff\xcd" +
-	"\xac\xfe\x00\xff\xff\xff\xff\xce\xc7\x1f\x00\xff\xff\xff\xffϏ\x83\x00\xff\xff\xff\xffЩ\xa4\x00\xff\xff\xff\xffф}\x00\xff\xff\xff\xffҊ׀\xff\xff\xff\xff\xd3e\xb0\x80\xff\xff\xff\xff\xd4l\v\x00\xff" +
-	"\xff\xff\xff\xd7Z0\x80\xff\xff\xff\xff\xd7\xdfX\x00\xff\xff\xff\xff\xd8/À\xff\xff\xff\xff\xd9\x1ec\x00\xff\xff\xff\xff\xda\x10\xf7\x00\xff\xff\xff\xff\xda\xeb\xd0\x00\xff\xff\xff\xff۴4\x00\xff\xff\xff\xff\xdc" +
-	"\xb9=\x00\xff\xff\xff\xff\xdd\xe0\x8d\x00\xff\xff\xff\xff\u07b4\u0380\xff\xff\xff\xffߤ\xbf\x80\xff\xff\xff\xff\xe0\x8bv\x00\xff\xff\xff\xff\xe1V}\x00\xff\xff\xff\xff\xe2\xbef\x80\xff\xff\xff\xff\xe36_\x00\xff" +
-	"\xff\xff\xff\xe4\x9eH\x80\xff\xff\xff\xff\xe5\x16A\x00\xff\xff\xff\xff\xe6t\xf0\x00\xff\xff\xff\xff\xe7\x11Ҁ\xff\xff\xff\xff\xe8&\xad\x80\xff\xff\xff\xff\xe8\xe8z\x00\x00\x00\x00\x00\b|\x8b\xe0\x00\x00\x00\x00\b" +
-	"\xfd\xb0\xd0\x00\x00\x00\x00\t\xf6\xea`\x00\x00\x00\x00\n\xa63\xd0\x00\x00\x00\x00\x13\xe9\xfc`\x00\x00\x00\x00\x14![`\x00\x00\x00\x00\x1a\xfa\xc6`\x00\x00\x00\x00\x1b\x8en`\x00\x00\x00\x00\x1c\xbe\xf8\xe0\x00" +
-	"\x00\x00\x00\x1dw|\xd0\x00\x00\x00\x00\x1e\xcc\xff`\x00\x00\x00\x00\x1f`\x99P\x00\x00\x00\x00 \x82\xb1`\x00\x00\x00\x00!I\xb5\xd0\x00\x00\x00\x00\"^\x9e\xe0\x00\x00\x00\x00# ]P\x00\x00\x00\x00$" +
-	"Z0`\x00\x00\x00\x00%\x00?P\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00&\xd6\xe6\xd0\x00\x00\x00\x00'\xeb\xcf\xe0\x00\x00\x00\x00(\xc0\x03P\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xa9\x1f\xd0\x00" +
-	"\x00\x00\x00+\xbbe\xe0\x00\x00\x00\x00,\x89\x01\xd0\x00\x00\x00\x00-\x9bG\xe0\x00\x00\x00\x00._\xa9P\x00\x00\x00\x00/{)\xe0\x00\x00\x00\x000H\xc5\xd0\x00\x00\x00\x001H\x96\xe0\x00\x00\x00\x002" +
-	"<nP\x00\x00\x00\x0031\xb3`\x00\x00\x00\x004\x1a\xfe\xd0\x00\x00\x00\x005\x11\x95`\x00\x00\x00\x005\xf1\xa6P\x00\x00\x00\x007\x04\b\x80\x00\x00\x00\x007\xcf\x01p\x00\x00\x00\x008\xf6_\x80\x00" +
-	"\x00\x00\x009\xdc\xf9\xe0\x00\x00\x00\x00:\xd0\xedp\x00\x00\x00\x00;\xae[`\x00\x00\x00\x00<\xa3\xa0p\x00\x00\x00\x00=\xa0\xb2`\x00\x00\x00\x00>\x83\x82p\x00\x00\x00\x00?|\x9f\xe0\x00\x00\x00\x00@" +
-	"s6p\x00\x00\x00\x00AP\xa4`\x00\x00\x00\x00BL\x8f\x00\x00\x00\x00\x00CHOp\x00\x00\x00\x00D,q\x00\x00\x00\x00\x00E\x1e\xf6\xf0\x00\x00\x00\x00F\fS\x00\x00\x00\x00\x00F\xecc\xf0\x00" +
-	"\x00\x00\x00G\xec5\x00\x00\x00\x00\x00H\xe7\xf5p\x00\x00\x00\x00I\xcc\x17\x00\x00\x00\x00\x00J\xbe\x9c\xf0\x00\x00\x00\x00K\xab\xf9\x00\x00\x00\x00\x00L\x8c\t\xf0\x00\x00\x00\x00M\x95\x15\x80\x00\x00\x00\x00N" +
-	"\x87\x9bp\x00\x00\x00\x00Ot\xf7\x80\x00\x00\x00\x00P^B\xf0\x00\x00\x00\x00QTـ\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
-	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
-	"\x02\x03\x02\x03\x02\x03\x02\x00\x00!\x06\x00\x00\x00\x00 \xf8\x00\x04\x00\x00*0\x01\b\x00\x00\x1c \x00\f\x00\x008@\x01\x10LMT\x00JMT\x00IDT\x00IST\x00IDDT\x00\nI" +
-	"ST-2IDT,M3.4.4/26,M10.5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT%J\xd5\xebS\x01\x00\x00S\x01\x00\x00\a\x00\x1c\x00Jama" +
-	"icaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x16\x00\x00" +
-	"\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffi\x87#~\xff\xff\xff\xff\x93\x0f\xb4\xfe\x00\x00\x00\x00\a\x8d\x19p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\t\xad\x94\xf0\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0" +
-	"\x85p\x00\x00\x00\x00\f٢\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00" +
-	"\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02" +
-	"\v`\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\xff\xff\xb8\x02\x00\x00\xff\xff\xb8\x02\x00\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\fLMT\x00KMT\x00EST\x00" +
-	"EDT\x00\nEST5\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x02\xf4\xaeg\xd5\x00\x00\x00\xd5\x00\x00\x00\x05\x00\x1c\x00JapanUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux" +
-	"\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00" +
-	"\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xffe¤p\xff\xff\xff\xff" +
-	"\xd7>\x02p\xff\xff\xff\xff\xd7\xedY\xf0\xff\xff\xff\xff\xd8\xf8\xfap\xff\xff\xff\xff\xd9\xcd;\xf0\xff\xff\xff\xff\xdb\a\x00\xf0\xff\xff\xff\xffۭ\x1d\xf0\xff\xff\xff\xff\xdc\xe6\xe2\xf0\xff\xff\xff\xff\u074c\xff\xf0" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x83\x03\x00\x00\x00\x00\x8c\xa0\x01\x04\x00\x00~\x90\x00\bLMT\x00JDT\x00JST\x00\nJST-9\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT" +
-	"\xf6\xe8]*\xdb\x00\x00\x00\xdb\x00\x00\x00\t\x00\x1c\x00KwajaleinUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff~6\x18 \xff\xff\xff\xff\xc1\xed5\xd0\xff\xff\xff\xff\xc9\xea\n`\xff\xff\xff\xff\xcfF\x81\xf0" +
-	"\xff\xff\xff\xff\xff\x86\x1bP\x00\x00\x00\x00,v\x0e@\x01\x02\x03\x01\x04\x05\x00\x00\x9c\xe0\x00\x00\x00\x00\x9a\xb0\x00\x04\x00\x00\x8c\xa0\x00\b\x00\x00~\x90\x00\f\xff\xffW@\x00\x10\x00\x00\xa8\xc0\x00\x14LM" +
-	"T\x00+11\x00+10\x00+09\x00-12\x00+12\x00\n<+12>-12\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT_\x7f2[\xaf\x01\x00\x00\xaf\x01\x00\x00\x05\x00" +
-	"\x1c\x00LibyaUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00 \x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff\xa1\xf2\xc1$\xff\xff\xff\xffݻ\xb1\x10\xff\xff\xff\xff\xde#\xad`\xff\xff\xff\xff\xe1x\xd2\x10\xff\xff\xff\xff\xe1\xe7e\xe0\xff\xff\xff\xff\xe5/?p\xff\xff" +
-	"\xff\xff\xe5\xa9\xcc\xe0\xff\xff\xff\xff\xebN\xc6\xf0\x00\x00\x00\x00\x16\x92B`\x00\x00\x00\x00\x17\b\xf7p\x00\x00\x00\x00\x17\xfa+\xe0\x00\x00\x00\x00\x18\xea*\xf0\x00\x00\x00\x00\x19\xdb_`\x00\x00\x00\x00\x1a\xcc" +
-	"\xaf\xf0\x00\x00\x00\x00\x1b\xbd\xe4`\x00\x00\x00\x00\x1c\xb4z\xf0\x00\x00\x00\x00\x1d\x9f\x17\xe0\x00\x00\x00\x00\x1e\x93\vp\x00\x00\x00\x00\x1f\x82\xee`\x00\x00\x00\x00 pJp\x00\x00\x00\x00!a~\xe0\x00\x00" +
-	"\x00\x00\"R\xcfp\x00\x00\x00\x00#D\x03\xe0\x00\x00\x00\x00$4\x02\xf0\x00\x00\x00\x00%%7`\x00\x00\x00\x00&@\xb7\xf0\x00\x00\x00\x002N\xf1`\x00\x00\x00\x003D6p\x00\x00\x00\x0045" +
-	"j\xe0\x00\x00\x00\x00P\x9d\x99\x00\x00\x00\x00\x00QTـ\x00\x00\x00\x00Ri\xb4\x80\x02\x01\x02\x01\x02\x01\x02\x03\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x01\x03\x02\x01\x03\x00\x00" +
-	"\f\\\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x1c \x00\rLMT\x00CEST\x00CET\x00EET\x00\nEET-2\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT" +
-	"\xfe\x9d\x1b\xc9m\x02\x00\x00m\x02\x00\x00\x03\x00\x1c\x00METUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005\x00\x00\x00\x02\x00\x00\x00\t\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9" +
-	"\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xc8\tq\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff" +
-	"\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\r\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T" +
-	"\x18\x90\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00" +
-	"\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 l" +
-	"r\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00" +
-	"\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84" +
-	"ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00" +
-	"\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x00\x0e\x10\x00\x05\x00\x00\x1c \x01\x00MEST\x00MET\x00\nMET-1MEST,M3.5.0,M1" +
-	"0.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xf5\x8d\x99\x92o\x00\x00\x00o\x00\x00\x00\x03\x00\x1c\x00MSTUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04" +
-	"\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" +
-	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\x9d\x90\x00\x00MST\x00\nMST7\n" +
-	"PK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe6h\xcac\xb7\x03\x00\x00\xb7\x03\x00\x00\a\x00\x1c\x00MST7MDTUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00" +
-	"\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif" +
-	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff" +
-	"\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W\x10" +
-	"\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb89\x10\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x1b\x10\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xfd\x10\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00" +
-	"\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\a\x8d5\x90\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\t\xad\xb1\x10\x00\x00\x00\x00\n\xf0\xa2\x80" +
-	"\x00\x00\x00\x00\vࡐ\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00" +
-	"\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n\x10" +
-	"\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00" +
-	" v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00" +
-	"\x00\x00\x00\x00'\xfeߐ\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00" +
-	".\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10" +
-	"\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00" +
-	"<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80" +
-	"\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x01\x00\x01\x00\x02\x03\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01" +
-	"\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\xff\xff\x9d\x90\x00\x04\xff\xff" +
-	"\xab\xa0\x01\x00\xff\xff\xab\xa0\x01\b\xff\xff\xab\xa0\x01\fMDT\x00MST\x00MWT\x00MPT\x00\nMST7MDT,M3.2.0,M11.1.0\nPK\x03\x04" +
-	"\n\x00\x00\x00\x00\x00\x8fj\xbeT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x1c\x00Mexico/UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01" +
-	"\x00PK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xd0v\x01\x8a\x01\x04\x00\x00\x01\x04\x00\x00\x10\x00\x1c\x00Mexico/BajaNorteUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94b" +
-	"ux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00" +
-	"\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00^\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff\xa5\xb6\xf6\x80\xff\xff" +
-	"\xff\xff\xa9yOp\xff\xff\xff\xff\xaf\xf2|\xf0\xff\xff\xff\xff\xb6fdp\xff\xff\xff\xff\xb7\x1b\x10\x00\xff\xff\xff\xff\xb8\n\xf2\xf0\xff\xff\xff\xff\xcbꍀ\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xffҙ" +
-	"\xbap\xff\xff\xff\xff\xd7\x1bY\x00\xff\xff\xff\xffؑ\xb4\xf0\xff\xff\xff\xff\xe2~K\x90\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4^-\x90\xff\xff\xff\xff\xe5)4\x90\xff\xff\xff\xff\xe6GJ\x10\xff\xff" +
-	"\xff\xff\xe7\x12Q\x10\xff\xff\xff\xff\xe8',\x10\xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff\xff\xea\a\x0e\x10\xff\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff\xff\xeb\xe6\xf0\x10\xff\xff\xff\xff\xec\xb1\xf7\x10\xff\xff\xff\xff\xed\xc6" +
-	"\xd2\x10\xff\xff\xff\xff\xee\x91\xd9\x10\x00\x00\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00" +
-	"\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"" +
-	"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00" +
-	"\x00\x00\x1f\xa1ې\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\"V\r \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15" +
-	"\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\n\x80\x10\x00\x00\x00\x00)\xdeϠ\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00" +
-	"\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S" +
-	"\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\a8 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00" +
-	"\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO" +
-	"\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00F\x0f\x82\xa0\x00\x00\x00\x00G$O\x90\x00\x00\x00\x00G\xf8\x9f \x00\x00\x00\x00I\x041\x90\x00\x00" +
-	"\x00\x00I\u0601 \x00\x00\x00\x00J\xe4\x13\x90\x00\x00\x00\x00K\x9c\xb3\xa0\x01\x02\x01\x02\x03\x02\x04\x05\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
-	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\x92L" +
-	"\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\x8f\x80\x00\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10\xff\xff\x9d\x90\x01\x14LMT\x00MST\x00PST\x00PDT\x00PWT\x00PPT\x00\nPST" +
-	"8PDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xd6\xe1Հ\x9c\x01\x00\x00\x9c\x01\x00\x00\x0e\x00\x1c\x00Mexico/Gen" +
-	"eralUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\x00" +
-	"\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6fV`\xff\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff\xb8\f6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\xff\xff\xff\xff\xc5" +
-	"ް`\xff\xff\xff\xffƗ4P\xff\xff\xff\xff\xc9U\xf1\xe0\xff\xff\xff\xff\xc9\xea\xddP\xff\xff\xff\xff\xcf\x02\xc6\xe0\xff\xff\xff\xffϷVP\xff\xff\xff\xffڙ\x15\xe0\xff\xff\xff\xff\xdbv\x83\xd0\x00" +
-	"\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008" +
-	"\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xf5\x04\x80\x00\x00\x00\x00;\xb6\xc2\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x01\x02\x01\x02\x01\x02\x03\x02\x03\x02\x04\x02\x03\x02\x03\x02\x03" +
-	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\xa3\f\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10LMT\x00MST\x00CST\x00CDT\x00CWT\x00" +
-	"\nCST6CDT,M4.1.0,M10.5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT8\xcdZ\x05o\x01\x00\x00o\x01\x00\x00\x0e\x00\x1c\x00Mexico" +
-	"/BajaSurUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x16\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6fV`\xff\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff\xb8\f6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\xff" +
-	"\xff\xff\xff\xcb\xeaq`\xff\xff\xff\xffؑ\xb4\xf0\x00\x00\x00\x00\x00\x00p\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005" +
-	"'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xf5\x12\x90\x00\x00\x00\x00;\xb6\xd1\x00\x00" +
-	"\x00\x00\x00<\xb0\n\x90\x01\x02\x01\x02\x01\x02\x01\x03\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\xff\xff\x9c<\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\x8f\x80\x00\f\xff\xff\xab\xa0\x01\x10L" +
-	"MT\x00MST\x00CST\x00PST\x00MDT\x00\nMST7MDT,M4.1.0,M10.5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTb\xb2\xaf" +
-	"\xf7\x13\x04\x00\x00\x13\x04\x00\x00\x02\x00\x1c\x00NZUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00`\x00\x00\x00\x06\x00\x00\x00\x13\xff\xff\xff\xffA\xb7L\xa8\xff\xff\xff\xff\xb0\xb4\xb2\xe8\xff\xff\xff\xff\xb1Q\x87X\xff\xff\xff\xff\xb2x\xe5h\xff\xff\xff\xff\xb3C\xe5`\xff\xff" +
-	"\xff\xff\xb4X\xc7h\xff\xff\xff\xff\xb5#\xc7`\xff\xff\xff\xff\xb68\xa9h\xff\xff\xff\xff\xb7\x03\xa9`\xff\xff\xff\xff\xb8\x18\x8bh\xff\xff\xff\xff\xb8\xec\xc5\xe0\xff\xff\xff\xff\xb9\xf8mh\xff\xff\xff\xff\xba\xcc" +
-	"\xa7\xe0\xff\xff\xff\xff\xbb\xd8Oh\xff\xff\xff\xff\xbc\xe3\xe8\xe0\xff\xff\xff\xff\xbd\xae\xf6\xe8\xff\xff\xff\xff\xbe\xc3\xca\xe0\xff\xff\xff\xff\xbf\x8e\xd8\xe8\xff\xff\xff\xff\xc0\xa3\xac\xe0\xff\xff\xff\xff\xc1n\xba\xe8\xff\xff" +
-	"\xff\xff\u0083\x8e\xe0\xff\xff\xff\xff\xc3N\x9c\xe8\xff\xff\xff\xff\xc4cp\xe0\xff\xff\xff\xff\xc5.~\xe8\xff\xff\xff\xff\xc6L\x8d`\xff\xff\xff\xff\xc7\x0e`\xe8\xff\xff\xff\xff\xc8,o`\xff\xff\xff\xff\xc8\xf7" +
-	"}h\xff\xff\xff\xff\xd2ښ@\x00\x00\x00\x00\t\x18\xfd\xe0\x00\x00\x00\x00\t\xac\xa5\xe0\x00\x00\x00\x00\n\xef\xa5`\x00\x00\x00\x00\v\x9e\xfc\xe0\x00\x00\x00\x00\f\xd8\xc1\xe0\x00\x00\x00\x00\r~\xde\xe0\x00\x00" +
-	"\x00\x00\x0e\xb8\xa3\xe0\x00\x00\x00\x00\x0f^\xc0\xe0\x00\x00\x00\x00\x10\x98\x85\xe0\x00\x00\x00\x00\x11>\xa2\xe0\x00\x00\x00\x00\x12xg\xe0\x00\x00\x00\x00\x13\x1e\x84\xe0\x00\x00\x00\x00\x14XI\xe0\x00\x00\x00\x00\x14\xfe" +
-	"f\xe0\x00\x00\x00\x00\x168+\xe0\x00\x00\x00\x00\x16\xe7\x83`\x00\x00\x00\x00\x18!H`\x00\x00\x00\x00\x18\xc7e`\x00\x00\x00\x00\x1a\x01*`\x00\x00\x00\x00\x1a\xa7G`\x00\x00\x00\x00\x1b\xe1\f`\x00\x00" +
-	"\x00\x00\x1c\x87)`\x00\x00\x00\x00\x1d\xc0\xee`\x00\x00\x00\x00\x1eg\v`\x00\x00\x00\x00\x1f\xa0\xd0`\x00\x00\x00\x00 F\xed`\x00\x00\x00\x00!\x80\xb2`\x00\x00\x00\x00\"0\t\xe0\x00\x00\x00\x00#i" +
-	"\xce\xe0\x00\x00\x00\x00$\x0f\xeb\xe0\x00\x00\x00\x00%.\x01`\x00\x00\x00\x00&\x02B\xe0\x00\x00\x00\x00'\r\xe3`\x00\x00\x00\x00'\xe2$\xe0\x00\x00\x00\x00(\xed\xc5`\x00\x00\x00\x00)\xc2\x06\xe0\x00\x00" +
-	"\x00\x00*ͧ`\x00\x00\x00\x00+\xab#`\x00\x00\x00\x00,\xad\x89`\x00\x00\x00\x00-\x8b\x05`\x00\x00\x00\x00.\x8dk`\x00\x00\x00\x00/j\xe7`\x00\x00\x00\x000mM`\x00\x00\x00\x001J" +
-	"\xc9`\x00\x00\x00\x002Vi\xe0\x00\x00\x00\x003*\xab`\x00\x00\x00\x0046K\xe0\x00\x00\x00\x005\n\x8d`\x00\x00\x00\x006\x16-\xe0\x00\x00\x00\x006\xf3\xa9\xe0\x00\x00\x00\x007\xf6\x0f\xe0\x00\x00" +
-	"\x00\x008Ӌ\xe0\x00\x00\x00\x009\xd5\xf1\xe0\x00\x00\x00\x00:\xb3m\xe0\x00\x00\x00\x00;\xbf\x0e`\x00\x00\x00\x00<\x93O\xe0\x00\x00\x00\x00=\x9e\xf0`\x00\x00\x00\x00>s1\xe0\x00\x00\x00\x00?~" +
-	"\xd2`\x00\x00\x00\x00@\\N`\x00\x00\x00\x00A^\xb4`\x00\x00\x00\x00B<0`\x00\x00\x00\x00C>\x96`\x00\x00\x00\x00D\x1c\x12`\x00\x00\x00\x00E\x1ex`\x00\x00\x00\x00E\xfb\xf4`\x00\x00" +
-	"\x00\x00F\xfeZ`\x02\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" +
-	"\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x00\x00\xa3\xd8\x00\x00\x00\x00\xaf\xc8\x01\x04\x00\x00\xa1\xb8\x00\t" +
-	"\x00\x00\xa8\xc0\x01\x04\x00\x00\xb6\xd0\x01\x0e\x00\x00\xa8\xc0\x00\x04LMT\x00NZST\x00NZMT\x00NZDT\x00\nNZST-12NZDT,M9.5.0,M4." +
-	"1.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x96\xc5FF(\x03\x00\x00(\x03\x00\x00\a\x00\x1c\x00NZ-CHATUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00" +
-	"\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00" +
-	"\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\x00\x00\x00\x04\x00\x00\x00\x16\xff\xff\xff\xffA\xb7D\x84\xff\xff\xff\xff\xd2\xda" +
-	"\x96\xbc\x00\x00\x00\x00\t\x18\xfd\xe0\x00\x00\x00\x00\t\xac\xa5\xe0\x00\x00\x00\x00\n\xef\xa5`\x00\x00\x00\x00\v\x9e\xfc\xe0\x00\x00\x00\x00\f\xd8\xc1\xe0\x00\x00\x00\x00\r~\xde\xe0\x00\x00\x00\x00\x0e\xb8\xa3\xe0\x00\x00" +
-	"\x00\x00\x0f^\xc0\xe0\x00\x00\x00\x00\x10\x98\x85\xe0\x00\x00\x00\x00\x11>\xa2\xe0\x00\x00\x00\x00\x12xg\xe0\x00\x00\x00\x00\x13\x1e\x84\xe0\x00\x00\x00\x00\x14XI\xe0\x00\x00\x00\x00\x14\xfef\xe0\x00\x00\x00\x00\x168" +
-	"+\xe0\x00\x00\x00\x00\x16\xe7\x83`\x00\x00\x00\x00\x18!H`\x00\x00\x00\x00\x18\xc7e`\x00\x00\x00\x00\x1a\x01*`\x00\x00\x00\x00\x1a\xa7G`\x00\x00\x00\x00\x1b\xe1\f`\x00\x00\x00\x00\x1c\x87)`\x00\x00" +
-	"\x00\x00\x1d\xc0\xee`\x00\x00\x00\x00\x1eg\v`\x00\x00\x00\x00\x1f\xa0\xd0`\x00\x00\x00\x00 F\xed`\x00\x00\x00\x00!\x80\xb2`\x00\x00\x00\x00\"0\t\xe0\x00\x00\x00\x00#i\xce\xe0\x00\x00\x00\x00$\x0f" +
-	"\xeb\xe0\x00\x00\x00\x00%.\x01`\x00\x00\x00\x00&\x02B\xe0\x00\x00\x00\x00'\r\xe3`\x00\x00\x00\x00'\xe2$\xe0\x00\x00\x00\x00(\xed\xc5`\x00\x00\x00\x00)\xc2\x06\xe0\x00\x00\x00\x00*ͧ`\x00\x00" +
-	"\x00\x00+\xab#`\x00\x00\x00\x00,\xad\x89`\x00\x00\x00\x00-\x8b\x05`\x00\x00\x00\x00.\x8dk`\x00\x00\x00\x00/j\xe7`\x00\x00\x00\x000mM`\x00\x00\x00\x001J\xc9`\x00\x00\x00\x002V" +
-	"i\xe0\x00\x00\x00\x003*\xab`\x00\x00\x00\x0046K\xe0\x00\x00\x00\x005\n\x8d`\x00\x00\x00\x006\x16-\xe0\x00\x00\x00\x006\xf3\xa9\xe0\x00\x00\x00\x007\xf6\x0f\xe0\x00\x00\x00\x008Ӌ\xe0\x00\x00" +
-	"\x00\x009\xd5\xf1\xe0\x00\x00\x00\x00:\xb3m\xe0\x00\x00\x00\x00;\xbf\x0e`\x00\x00\x00\x00<\x93O\xe0\x00\x00\x00\x00=\x9e\xf0`\x00\x00\x00\x00>s1\xe0\x00\x00\x00\x00?~\xd2`\x00\x00\x00\x00@\\" +
-	"N`\x00\x00\x00\x00A^\xb4`\x00\x00\x00\x00B<0`\x00\x00\x00\x00C>\x96`\x00\x00\x00\x00D\x1c\x12`\x00\x00\x00\x00E\x1ex`\x00\x00\x00\x00E\xfb\xf4`\x00\x00\x00\x00F\xfeZ`\x01\x03" +
-	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
-	"\x02\x03\x02\x03\x02\x03\x02\x00\x00\xab\xfc\x00\x00\x00\x00\xacD\x00\x04\x00\x00\xc1\\\x01\n\x00\x00\xb3L\x00\x10LMT\x00+1215\x00+1345\x00+1245\x00\n<+1245" +
-	">-12:45<+1345>,M9.5.0/2:45,M4.1.0/3:45\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTV\x80\x94@\x12\x04\x00" +
-	"\x00\x12\x04\x00\x00\x06\x00\x1c\x00NavajoUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00a\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff^\x04\f\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff" +
-	"\xff\xff\xa2e\xfe\x90\xff\xff\xff\xff\xa3\x84\x06\x00\xff\xff\xff\xff\xa4E\xe0\x90\xff\xff\xff\xff\xa4\x8f\xa6\x80\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xf7/" +
-	"v\x90\xff\xff\xff\xff\xf8(\x94\x00\xff\xff\xff\xff\xf9\x0fX\x90\xff\xff\xff\xff\xfa\bv\x00\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W\x10\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff" +
-	"\xff\xff\xfe\xb89\x10\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x1b\x10\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xfd\x10\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P" +
-	"\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\a\x8d5\x90\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\t\xad\xb1\x10\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\vࡐ\x00\x00" +
-	"\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13i" +
-	"d\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00" +
-	"\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81" +
-	"\xaf\x80\x00\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeߐ\x00\x00" +
-	"\x00\x00)\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~" +
-	"g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00" +
-	"\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb" +
-	"\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00" +
-	"\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\x9d\x94\x00\x00\xff\xff\xab" +
-	"\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10LMT\x00MDT\x00MST\x00MWT\x00MPT\x00\nMST7MDT,M3.2.0,M11" +
-	".1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8ej\xbeT*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00\x00\x03\x00\x1c\x00PRCUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b" +
-	"\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZi" +
-	"f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff~6C)\xff\xff\xff\xff\xa0\x97\xa2\x80\xff\xff\xff" +
-	"\xff\xa1y\x04\xf0\xff\xff\xff\xff\xc8Y^\x80\xff\xff\xff\xff\xc9\t\xf9p\xff\xff\xff\xff\xc9ӽ\x00\xff\xff\xff\xff\xcb\x05\x8a\xf0\xff\xff\xff\xff\xcb|@\x00\xff\xff\xff\xff\xd2;>\xf0\xff\xff\xff\xffӋ{" +
-	"\x80\xff\xff\xff\xff\xd4B\xad\xf0\xff\xff\xff\xff\xd5E\"\x00\xff\xff\xff\xff\xd6L\xbf\xf0\xff\xff\xff\xff\xd7<\xbf\x00\xff\xff\xff\xff\xd8\x06fp\xff\xff\xff\xff\xd9\x1d\xf2\x80\xff\xff\xff\xff\xd9A|\xf0\x00\x00\x00" +
-	"\x00\x1e\xbaR \x00\x00\x00\x00\x1fi\x9b\x90\x00\x00\x00\x00 ~\x84\xa0\x00\x00\x00\x00!I}\x90\x00\x00\x00\x00\"g\xa1 \x00\x00\x00\x00#)_\x90\x00\x00\x00\x00$G\x83 \x00\x00\x00\x00%\x12|" +
-	"\x10\x00\x00\x00\x00&'e \x00\x00\x00\x00&\xf2^\x10\x00\x00\x00\x00(\aG \x00\x00\x00\x00(\xd2@\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x00\x00q\xd7\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\bLMT\x00CDT\x00CST\x00\nCST-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTŭV\xad\xb7\x03\x00" +
-	"\x00\xb7\x03\x00\x00\a\x00\x1c\x00PST8PDTUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\x9e\xa6H\xa0\xff\xff\xff\xff\x9f\xbb\x15\x90\xff\xff\xff\xff\xa0\x86*\xa0\xff\xff\xff\xff\xa1\x9a\xf7\x90\xff\xff\xff\xffˉ\x1a\xa0\xff" +
-	"\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a&\x10\xff\xff\xff\xff\xfa\xf8\x83 \xff\xff\xff\xff\xfb\xe8f\x10\xff\xff\xff\xff\xfc\xd8e \xff\xff\xff\xff\xfd\xc8H\x10\xff\xff\xff\xff\xfe\xb8G \xff\xff\xff\xff\xff" +
-	"\xa8*\x10\x00\x00\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88\f\x10\x00\x00\x00\x00\x02x\v \x00\x00\x00\x00\x03q(\x90\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05Q\n\x90\x00\x00\x00\x00\x06A\t\xa0\x00" +
-	"\x00\x00\x00\a0\xec\x90\x00\x00\x00\x00\a\x8dC\xa0\x00\x00\x00\x00\t\x10ΐ\x00\x00\x00\x00\t\xad\xbf \x00\x00\x00\x00\n\xf0\xb0\x90\x00\x00\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r" +
-	"\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00" +
-	"\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b" +
-	"\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1ې\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\"V\r \x00" +
-	"\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\n\x80\x10\x00\x00\x00\x00)" +
-	"\xdeϠ\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00" +
-	"\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\a8 \x00\x00\x00\x008" +
-	"\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00" +
-	"\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E" +
-	"\xf3\xd3 \x01\x00\x01\x00\x02\x03\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00" +
-	"\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\xff\xff\x8f\x80\x00\x04\xff\xff\x9d\x90\x01\x00\xff\xff\x9d\x90\x01\b\xff\xff\x9d\x90\x01\fPDT\x00P" +
-	"ST\x00PWT\x00PPT\x00\nPST8PDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\b\x00\x1c\x00Pacific/UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTn\x04\x19y\x9a" +
-	"\x00\x00\x00\x9a\x00\x00\x00\x14\x00\x1c\x00Pacific/Port_MoresbyUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00T" +
-	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xffV\xb6Z\b\xff\xff\xff\xffr\xed\xa4\x90\x01\x02\x00\x00\x89\xf8\x00\x00\x00\x00" +
-	"\x89\xf0\x00\x04\x00\x00\x8c\xa0\x00\tLMT\x00PMMT\x00+10\x00\n<+10>-10\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xcc\xf39a\xc3\x00\x00\x00\xc3\x00\x00\x00\r" +
-	"\x00\x1c\x00Pacific/ChuukUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xff\x14\xe1\xbf4\xff\xff\xff\xff~6&\xb4\xff\xff\xff\xff\x98\x11\xa3\xe0\xff\xff\xff\xff\xa09\xf9\xf0\xff\xff\xff\xff\xc9\xea\n`\xff" +
-	"\xff\xff\xff\xd2\x11\x0e\xf0\x01\x02\x03\x02\x03\x02\xff\xff<\xcc\x00\x00\x00\x00\x8eL\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00~\x90\x00\bLMT\x00+10\x00+09\x00\n<+10>-10\nP" +
-	"K\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xee\xd0\x1cYN\x04\x00\x00N\x04\x00\x00\x0e\x00\x1c\x00Pacific/EasterUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00" +
-	"\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00" +
-	"\x00\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00f\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffi\x87B\b\xff\xff\xff\xff\xb9\xc7" +
-	"@\x88\xff\xff\xff\xff\xfd\xd1<@\xff\xff\xff\xff\xfe\x92\xfa\xb0\xff\xff\xff\xff\xff\xcc\xcd\xc0\x00\x00\x00\x00\x00rܰ\x00\x00\x00\x00\x01uP\xc0\x00\x00\x00\x00\x02@I\xb0\x00\x00\x00\x00\x03U2\xc0\x00\x00" +
-	"\x00\x00\x04 +\xb0\x00\x00\x00\x00\x05>O@\x00\x00\x00\x00\x06\x00\r\xb0\x00\x00\x00\x00\a\v\xbc@\x00\x00\x00\x00\a\xdf\xef\xb0\x00\x00\x00\x00\b\xfe\x13@\x00\x00\x00\x00\t\xbfѰ\x00\x00\x00\x00\n\xdd" +
-	"\xf5@\x00\x00\x00\x00\v\xa8\xee0\x00\x00\x00\x00\f\xbd\xd7@\x00\x00\x00\x00\r\x88\xd00\x00\x00\x00\x00\x0e\x9d\xb9@\x00\x00\x00\x00\x0fh\xb20\x00\x00\x00\x00\x10\x86\xd5\xc0\x00\x00\x00\x00\x11H\x940\x00\x00" +
-	"\x00\x00\x12f\xb7\xc0\x00\x00\x00\x00\x13(v0\x00\x00\x00\x00\x14F\x99\xc0\x00\x00\x00\x00\x15\x11\x92\xb0\x00\x00\x00\x00\x16&{\xc0\x00\x00\x00\x00\x16\xf1t\xb0\x00\x00\x00\x00\x18\x06]\xc0\x00\x00\x00\x00\x18\xd1" +
-	"V\xb0\x00\x00\x00\x00\x19\xe6?\xc0\x00\x00\x00\x00\x1a\xb18\xb0\x00\x00\x00\x00\x1b\xcf\\@\x00\x00\x00\x00\x1c\x91\x1a\xb0\x00\x00\x00\x00\x1d\xaf>@\x00\x00\x00\x00\x1ep\xfc\xb0\x00\x00\x00\x00\x1f\x8f @\x00\x00" +
-	"\x00\x00 \x7f\x030\x00\x00\x00\x00!o\x02@\x00\x00\x00\x00\"9\xfb0\x00\x00\x00\x00#N\xe4@\x00\x00\x00\x00$\x19\xdd0\x00\x00\x00\x00%8\x00\xc0\x00\x00\x00\x00%\xf9\xbf0\x00\x00\x00\x00&\xf2" +
-	"\xf8\xc0\x00\x00\x00\x00'١0\x00\x00\x00\x00(\xf7\xc4\xc0\x00\x00\x00\x00)½\xb0\x00\x00\x00\x00*צ\xc0\x00\x00\x00\x00+\xa2\x9f\xb0\x00\x00\x00\x00,\xb7\x88\xc0\x00\x00\x00\x00-\x82\x81\xb0\x00\x00" +
-	"\x00\x00.\x97j\xc0\x00\x00\x00\x00/bc\xb0\x00\x00\x00\x000\x80\x87@\x00\x00\x00\x001BE\xb0\x00\x00\x00\x002`i@\x00\x00\x00\x003=\xd70\x00\x00\x00\x004@K@\x00\x00\x00\x005\v" +
-	"D0\x00\x00\x00\x006\r\xb8@\x00\x00\x00\x007\x06հ\x00\x00\x00\x008\x00\x0f@\x00\x00\x00\x008\xcb\b0\x00\x00\x00\x009\xe9+\xc0\x00\x00\x00\x00:\xaa\xea0\x00\x00\x00\x00;\xc9\r\xc0\x00\x00" +
-	"\x00\x00<\x8a\xcc0\x00\x00\x00\x00=\xa8\xef\xc0\x00\x00\x00\x00>j\xae0\x00\x00\x00\x00?\x88\xd1\xc0\x00\x00\x00\x00@Sʰ\x00\x00\x00\x00Ah\xb3\xc0\x00\x00\x00\x00B3\xac\xb0\x00\x00\x00\x00CH" +
-	"\x95\xc0\x00\x00\x00\x00D\x13\x8e\xb0\x00\x00\x00\x00E1\xb2@\x00\x00\x00\x00E\xf3p\xb0\x00\x00\x00\x00G\x11\x94@\x00\x00\x00\x00G\xef\x020\x00\x00\x00\x00H\xf1v@\x00\x00\x00\x00I\xbco0\x00\x00" +
-	"\x00\x00J\xd1X@\x00\x00\x00\x00K\xb8\x00\xb0\x00\x00\x00\x00L\xb1:@\x00\x00\x00\x00M\xc6\a0\x00\x00\x00\x00NP\x82\xc0\x00\x00\x00\x00O\x9c\xae\xb0\x00\x00\x00\x00PB\xd9\xc0\x00\x00\x00\x00Q|" +
-	"\x90\xb0\x00\x00\x00\x00R+\xf6@\x00\x00\x00\x00S\\r\xb0\x00\x00\x00\x00T\v\xd8@\x00\x00\x00\x00W7\xe60\x00\x00\x00\x00W\xaf\xec\xc0\x00\x00\x00\x00Y\x17\xc80\x00\x00\x00\x00Y\x8f\xce\xc0\x00\x00" +
-	"\x00\x00Z\xf7\xaa0\x00\x00\x00\x00[o\xb0\xc0\x00\x00\x00\x00\\\xa9g\xb0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04" +
-	"\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" +
-	"\x05\x04\x05\x04\xff\xff\x99x\x00\x00\xff\xff\x99x\x00\x04\xff\xff\xab\xa0\x01\b\xff\xff\x9d\x90\x00\f\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\x10LMT\x00EMT\x00-06\x00-07\x00-05\x00" +
-	"\n<-06>6<-05>,M9.1.6/22,M4.1.6/22\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xf6\xe8]*\xdb\x00\x00\x00\xdb\x00\x00\x00\x11" +
-	"\x00\x1c\x00Pacific/KwajaleinUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff~6\x18 \xff\xff\xff\xff\xc1\xed5\xd0\xff\xff\xff\xff\xc9\xea\n`\xff\xff\xff\xff\xcfF\x81\xf0\xff\xff\xff\xff\xff" +
-	"\x86\x1bP\x00\x00\x00\x00,v\x0e@\x01\x02\x03\x01\x04\x05\x00\x00\x9c\xe0\x00\x00\x00\x00\x9a\xb0\x00\x04\x00\x00\x8c\xa0\x00\b\x00\x00~\x90\x00\f\xff\xffW@\x00\x10\x00\x00\xa8\xc0\x00\x14LMT\x00+11" +
-	"\x00+10\x00+09\x00-12\x00+12\x00\n<+12>-12\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x97F\x91\xb3\xed\x00\x00\x00\xed\x00\x00\x00\x11\x00\x1c\x00Pac" +
-	"ific/TongatapuUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\xd2E\x9c@\xff\xff\xff\xff\xef\x11\xe0\x10\x00\x00\x00\x007\xfbG\xd0\x00\x00\x00\x008\xd3}\xd0\x00\x00\x00\x00:\x04\bP\x00\x00\x00" +
-	"\x00:r\xb8@\x00\x00\x00\x00;\xe3\xeaP\x00\x00\x00\x00<R\x9a@\x00\x00\x00\x00X\x1d\xd7\xd0\x00\x00\x00\x00Xz \xd0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\xad@\x00\x00\x00\x00\xadp\x00\x04\x00" +
-	"\x00\xb6\xd0\x00\n\x00\x00\xc4\xe0\x01\x0eLMT\x00+1220\x00+13\x00+14\x00\n<+13>-13\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xcc\xf39a\xc3\x00\x00" +
-	"\x00\xc3\x00\x00\x00\v\x00\x1c\x00Pacific/YapUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xff\x14\xe1\xbf4\xff\xff\xff\xff~6&\xb4\xff\xff\xff\xff\x98\x11\xa3\xe0\xff\xff\xff\xff\xa09\xf9\xf0\xff\xff\xff\xff\xc9" +
-	"\xea\n`\xff\xff\xff\xff\xd2\x11\x0e\xf0\x01\x02\x03\x02\x03\x02\xff\xff<\xcc\x00\x00\x00\x00\x8eL\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00~\x90\x00\bLMT\x00+10\x00+09\x00\n<+10>-" +
-	"10\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT1\xce_(\x86\x00\x00\x00\x86\x00\x00\x00\x0e\x00\x1c\x00Pacific/WallisUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94b" +
-	"ux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00" +
-	"\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff~6\b\xa8\x01\x00" +
-	"\x00\xacX\x00\x00\x00\x00\xa8\xc0\x00\x04LMT\x00+12\x00\n<+12>-12\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xa8A\x15\xfe\x97\x01\x00\x00\x97\x01\x00\x00\f\x00\x1c\x00P" +
-	"acific/ApiaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x1a\x00\x00\x00\a\x00\x00\x00\x1a\xff\xff\xff\xffn=\xc9\x00\xff\xff\xff\xff\x91\x05\xfc\x00\xff\xff\xff\xff\xdab\x048\x00\x00\x00\x00L\x9f'\xb0\x00\x00\x00\x00M\x97+\xe0\x00\x00\x00\x00N}" +
-	"\xe2`\x00\x00\x00\x00N\xfd\x8b\xa0\x00\x00\x00\x00Ow\r\xe0\x00\x00\x00\x00Pf\xfe\xe0\x00\x00\x00\x00Q`*`\x00\x00\x00\x00RF\xe0\xe0\x00\x00\x00\x00S@\f`\x00\x00\x00\x00T&\xc2\xe0\x00\x00" +
-	"\x00\x00U\x1f\xee`\x00\x00\x00\x00V\x06\xa4\xe0\x00\x00\x00\x00V\xff\xd0`\x00\x00\x00\x00W\xe6\x86\xe0\x00\x00\x00\x00X߲`\x00\x00\x00\x00Y\xc6h\xe0\x00\x00\x00\x00Z\xbf\x94`\x00\x00\x00\x00[\xaf" +
-	"\x85`\x00\x00\x00\x00\\\xa8\xb0\xe0\x00\x00\x00\x00]\x8fg`\x00\x00\x00\x00^\x88\x92\xe0\x00\x00\x00\x00_oI`\x00\x00\x00\x00`ht\xe0\x01\x02\x04\x03\x04\x03\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" +
-	"\x06\x05\x06\x05\x06\x05\x06\x05\x00\x00\xb0\x80\x00\x00\xff\xff_\x00\x00\x00\xff\xff^H\x00\x04\xff\xffs`\x01\n\xff\xffeP\x00\x0e\x00\x00\xb6\xd0\x00\x12\x00\x00\xc4\xe0\x01\x16LMT\x00-1130\x00" +
-	"-10\x00-11\x00+13\x00+14\x00\n<+13>-13\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTY5\x1a6\xf7\x00\x00\x00\xf7\x00\x00\x00\x0f\x00\x1c\x00Paci" +
-	"fic/NorfolkUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x1e\xff\xff\xff\xff~6\x17\x88\xff\xff\xff\xff\xdcA\xf8\x80\x00\x00\x00\x00\t\x0f\xcah\x00\x00\x00\x00\t\xb5\xe7h\x00\x00\x00\x00V\x0f\xe6h\x00\x00\x00\x00]\x98" +
-	"\xaf\xf0\x01\x02\x03\x02\x04\x05\x00\x00\x9dx\x00\x00\x00\x00\x9d\x80\x00\x04\x00\x00\xa1\xb8\x00\n\x00\x00\xaf\xc8\x01\x10\x00\x00\x9a\xb0\x00\x16\x00\x00\xa8\xc0\x01\x1aLMT\x00+1112\x00+1130\x00" +
-	"+1230\x00+11\x00+12\x00\n<+11>-11<+12>,M10.1.0,M4.1.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT" +
-	"\x9e\x7f\xab\x95V\x01\x00\x00V\x01\x00\x00\r\x00\x1c\x00Pacific/EfateUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZi" +
-	"f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x92\xf5´\x00\x00\x00\x00\ay\x99@\x00\x00\x00\x00\a\xfa\xcc@\x00\x00\x00\x00" +
-	"\x19\xd2\xf7\xd0\x00\x00\x00\x00\x1a\xc2\xda\xc0\x00\x00\x00\x00\x1b\xb2\xd9\xd0\x00\x00\x00\x00\x1c\xa2\xbc\xc0\x00\x00\x00\x00\x1d\x9b\xf6P\x00\x00\x00\x00\x1e\x82\x9e\xc0\x00\x00\x00\x00\x1f{\xd8P\x00\x00\x00\x00 k\xbb@" +
-	"\x00\x00\x00\x00![\xbaP\x00\x00\x00\x00\"K\x9d@\x00\x00\x00\x00#;\x9cP\x00\x00\x00\x00$+\x7f@\x00\x00\x00\x00%\x1b~P\x00\x00\x00\x00&\va@\x00\x00\x00\x00&\xfb`P\x00\x00\x00\x00" +
-	"'\xebC@\x00\x00\x00\x00(\xe4|\xd0\x00\x00\x00\x00)\x81Q@\x00\x00\x00\x00*\xe9H\xd0\x00\x00\x00\x00+a3@\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00" +
-	"\x00\x9d\xcc\x00\x00\x00\x00\xa8\xc0\x01\x04\x00\x00\x9a\xb0\x00\bLMT\x00+12\x00+11\x00\n<+11>-11\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTcF/.\xac\x01\x00" +
-	"\x00\xac\x01\x00\x00\f\x00\x1c\x00Pacific/FijiUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif3\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1e\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x9a\x13\xb1\xc0\x00\x00\x00\x006;\x17\xe0\x00\x00\x00\x006\xd7\xfa`\x00\x00\x00\x008$4`\x00\x00\x00\x00" +
-	"8\xb7\xdc`\x00\x00\x00\x00K\x11,\xe0\x00\x00\x00\x00K\xae\x0f`\x00\x00\x00\x00L\xc2\xea`\x00\x00\x00\x00MrA\xe0\x00\x00\x00\x00N\xa2\xcc`\x00\x00\x00\x00O\x1a\xc4\xe0\x00\x00\x00\x00P\x82\xae`" +
-	"\x00\x00\x00\x00P\xfa\xa6\xe0\x00\x00\x00\x00Rk\xca\xe0\x00\x00\x00\x00R\xdaz\xd0\x00\x00\x00\x00TT\xe7`\x00\x00\x00\x00T\xbaj\xe0\x00\x00\x00\x00V4\xc9`\x00\x00\x00\x00V\x9aL\xe0\x00\x00\x00\x00" +
-	"X\x1d\xe5\xe0\x00\x00\x00\x00Xz.\xe0\x00\x00\x00\x00Y\xfd\xc7\xe0\x00\x00\x00\x00ZZ\x10\xe0\x00\x00\x00\x00[ݩ\xe0\x00\x00\x00\x00\\9\xf2\xe0\x00\x00\x00\x00]\xc6\xc6`\x00\x00\x00\x00^\x19\xd4\xe0" +
-	"\x00\x00\x00\x00_\xde\a`\x00\x00\x00\x00`\x02\xf1`\x00\x00\x00\x00co\xa6\xe0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00\xa7\xc0\x00\x00" +
-	"\x00\x00\xb6\xd0\x01\x04\x00\x00\xa8\xc0\x00\bLMT\x00+13\x00+12\x00\n<+12>-12<+13>,M11.2.0,M1.2.3/99\nPK\x03" +
-	"\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTa\vೆ\x00\x00\x00\x86\x00\x00\x00\x10\x00\x1c\x00Pacific/FunafutiUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00" +
-	"\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00" +
-	"\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff~6\f\xfc\x01\x00\x00\xa8\x04\x00" +
-	"\x00\x00\x00\xa8\xc0\x00\x04LMT\x00+12\x00\n<+12>-12\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x80\xf8vܔ\x00\x00\x00\x94\x00\x00\x00\r\x00\x1c\x00Pacif" +
-	"ic/PalauUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\b\xff\xff\xff\xff\x14\xe1\xcfl\xff\xff\xff\xff~66\xec\x01\x02\xff\xff,\x94\x00\x00\x00\x00~\x14\x00\x00\x00\x00~\x90\x00\x04LMT\x00+09\x00\n<+09" +
-	">-9\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTFI\xfe\x14^\x01\x00\x00^\x01\x00\x00\f\x00\x1c\x00Pacific/GuamUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bu" +
-	"x\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00" +
-	"\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x00\x06\x00\x00\x00\x15\xff\xff\xff\xff\x14\xe1\xc5\xcc\xff\xff\xff" +
-	"\xff~6-L\xff\xff\xff\xff\xcb7\x95\xe0\xff\xff\xff\xff\xd0.\x89\xf0\xff\xff\xff\xff\xec7\xbe\x00\xff\xff\xff\xff\xef6\xf8\xf0\xff\xff\xff\xff\xfb\x9b\x00\x00\xff\xff\xff\xff\xfe?'\x8c\xff\xff\xff\xff\xff\x01\x1e" +
-	"\x00\xff\xff\xff\xff\xff]X\xf0\x00\x00\x00\x00\x00\x97,\x00\x00\x00\x00\x00\x01Fup\x00\x00\x00\x00\x02w\x0e\x00\x00\x00\x00\x00\x03&Wp\x00\x00\x00\x00\ap\x97\x00\x00\x00\x00\x00\a\xcc\xd1\xf0\x00\x00\x00" +
-	"\x00\f\b\x91\x00\x00\x00\x00\x00\f|\x87,\x00\x00\x00\x00\r\xbf\x94\x80\x00\x00\x00\x00\x0ee\xa3p\x00\x00\x00\x00:C^`\x01\x02\x03\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x05\xff\xff" +
-	"64\x00\x00\x00\x00\x87\xb4\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00~\x90\x00\b\x00\x00\x9a\xb0\x01\f\x00\x00\x8c\xa0\x00\x10LMT\x00GST\x00+09\x00GDT\x00ChST\x00\nChST" +
-	"-10\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTFI\xfe\x14^\x01\x00\x00^\x01\x00\x00\x0e\x00\x1c\x00Pacific/SaipanUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94" +
-	"bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01" +
-	"\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x00\x06\x00\x00\x00\x15\xff\xff\xff\xff\x14\xe1\xc5\xcc\xff" +
-	"\xff\xff\xff~6-L\xff\xff\xff\xff\xcb7\x95\xe0\xff\xff\xff\xff\xd0.\x89\xf0\xff\xff\xff\xff\xec7\xbe\x00\xff\xff\xff\xff\xef6\xf8\xf0\xff\xff\xff\xff\xfb\x9b\x00\x00\xff\xff\xff\xff\xfe?'\x8c\xff\xff\xff\xff\xff" +
-	"\x01\x1e\x00\xff\xff\xff\xff\xff]X\xf0\x00\x00\x00\x00\x00\x97,\x00\x00\x00\x00\x00\x01Fup\x00\x00\x00\x00\x02w\x0e\x00\x00\x00\x00\x00\x03&Wp\x00\x00\x00\x00\ap\x97\x00\x00\x00\x00\x00\a\xcc\xd1\xf0\x00" +
-	"\x00\x00\x00\f\b\x91\x00\x00\x00\x00\x00\f|\x87,\x00\x00\x00\x00\r\xbf\x94\x80\x00\x00\x00\x00\x0ee\xa3p\x00\x00\x00\x00:C^`\x01\x02\x03\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x05" +
-	"\xff\xff64\x00\x00\x00\x00\x87\xb4\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00~\x90\x00\b\x00\x00\x9a\xb0\x01\f\x00\x00\x8c\xa0\x00\x10LMT\x00GST\x00+09\x00GDT\x00ChST\x00\nCh" +
-	"ST-10\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x97n7\x1a\xf2\x00\x00\x00\xf2\x00\x00\x00\x0e\x00\x1c\x00Pacific/KosraeUT\t\x00\x03\xdd\xfc\x94b\xdd" +
-	"\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00" +
-	"\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xff\x14\xe1\xb4" +
-	"\xb4\xff\xff\xff\xff~6\x1c4\xff\xff\xff\xff\x98\x11\x95\xd0\xff\xff\xff\xff\xa09\xf9\xf0\xff\xff\xff\xff\xc1\xed5\xd0\xff\xff\xff\xff\xc9\xea\n`\xff\xff\xff\xff\xd2\x11\x0e\xf0\xff\xff\xff\xff\xff\x86\x1bP\x00\x00\x00" +
-	"\x006\x8bg@\x01\x02\x03\x02\x04\x03\x02\x05\x02\xff\xffGL\x00\x00\x00\x00\x98\xcc\x00\x00\x00\x00\x9a\xb0\x00\x04\x00\x00~\x90\x00\b\x00\x00\x8c\xa0\x00\f\x00\x00\xa8\xc0\x00\x10LMT\x00+11\x00+0" +
-	"9\x00+10\x00+12\x00\n<+11>-11\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x91\xd60\f\x9a\x00\x00\x00\x9a\x00\x00\x00\f\x00\x1c\x00Pacific/Ni" +
-	"ueUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00" +
-	"\x03\x00\x00\x00\x0e\xff\xff\xff\xffߡjL\xff\xff\xff\xff\xf5\xa6\xb8`\x01\x02\xff\xff`\xb4\x00\x00\xff\xff`\xa0\x00\x04\xff\xffeP\x00\nLMT\x00-1120\x00-11\x00\n<-11" +
-	">11\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\u07b54-\xd6\x00\x00\x00\xd6\x00\x00\x00\x0e\x00\x1c\x00Pacific/PonapeUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94" +
-	"bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01" +
-	"\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\x14\xe1\xb9,\xff" +
-	"\xff\xff\xff~6 \xac\xff\xff\xff\xff\x98\x11\x95\xd0\xff\xff\xff\xff\xa09\xf9\xf0\xff\xff\xff\xff\xc1\xed5\xd0\xff\xff\xff\xff\xc9\xea\n`\xff\xff\xff\xff\xd2\x11\x0e\xf0\x01\x02\x03\x02\x04\x03\x02\xff\xffB\xd4\x00\x00" +
-	"\x00\x00\x94T\x00\x00\x00\x00\x9a\xb0\x00\x04\x00\x00~\x90\x00\b\x00\x00\x8c\xa0\x00\fLMT\x00+11\x00+09\x00+10\x00\n<+11>-11\nPK\x03\x04\n\x00\x00\x00\x00\x00" +
-	"\x8fj\xbeT߃\xa0_\x86\x00\x00\x00\x86\x00\x00\x00\f\x00\x1c\x00Pacific/WakeUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00" +
-	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff~6\x18\xcc\x01\x00\x00\x9c4\x00\x00\x00\x00\xa8\xc0\x00\x04LMT\x00" +
-	"+12\x00\n<+12>-12\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x81\xe3w\n\xaf\x00\x00\x00\xaf\x00\x00\x00\x11\x00\x1c\x00Pacific/Galapago" +
-	"sUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04" +
-	"\x00\x00\x00\f\xff\xff\xff\xff\xb6\xa4L\x80\x00\x00\x00\x00\x1e\x18\xc4P\x00\x00\x00\x00+\x17\n\xe0\x00\x00\x00\x00+q\xf4P\x01\x03\x02\x03\xff\xff\xac\x00\x00\x00\xff\xff\xb9\xb0\x00\x04\xff\xff\xb9\xb0\x01\x04\xff\xff" +
-	"\xab\xa0\x00\bLMT\x00-05\x00-06\x00\n<-06>6\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xeaK\x85v\xdd\x00\x00\x00\xdd\x00\x00\x00\x10\x00\x1c\x00Pacifi" +
-	"c/JohnstonUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\a\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xfft\xe0p\xbe\xff\xff\xff\xff\xbb\x05CH\xff\xff\xff\xff\xbb!qX\xff\xff\xff\xffˉ=\xc8\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2aI" +
-	"8\xff\xff\xff\xffՍsH\x01\x02\x01\x03\x04\x01\x05\xff\xffl\x02\x00\x00\xff\xfflX\x00\x04\xff\xffzh\x01\b\xff\xffzh\x01\f\xff\xffzh\x01\x10\xff\xffs`\x00\x04LMT\x00HST\x00" +
-	"HDT\x00HWT\x00HPT\x00\nHST10\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTt\xca{e\x92\x00\x00\x00\x92\x00\x00\x00\x0e\x00\x1c\x00Pacific/Mid" +
-	"wayUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00" +
-	"\x00\x03\x00\x00\x00\b\xff\xff\xff\xffn=\xc8\b\xff\xff\xff\xff\x91\x05\xfb\b\x01\x02\x00\x00\xb1x\x00\x00\xff\xff_\xf8\x00\x00\xff\xffeP\x00\x04LMT\x00SST\x00\nSST11\nPK\x03" +
-	"\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe2;Z\xf7\xb7\x00\x00\x00\xb7\x00\x00\x00\r\x00\x1c\x00Pacific/NauruUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91" +
-	"\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00T" +
-	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\xa3\xe7+\x04\xff\xff\xff\xff̐\xe9\xc8\xff" +
-	"\xff\xff\xff\xd2C'\xf0\x00\x00\x00\x00\x11!\xa8\xe8\x01\x02\x01\x03\x00\x00\x9c|\x00\x00\x00\x00\xa1\xb8\x00\x04\x00\x00~\x90\x00\n\x00\x00\xa8\xc0\x00\x0eLMT\x00+1130\x00+09\x00+12" +
-	"\x00\n<+12>-12\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTY\xd2K|\x86\x00\x00\x00\x86\x00\x00\x00\x13\x00\x1c\x00Pacific/Guadalcanal" +
-	"UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00" +
-	"\x00\x00\b\xff\xff\xff\xff\x94O3\x8c\x01\x00\x00\x95\xf4\x00\x00\x00\x00\x9a\xb0\x00\x04LMT\x00+11\x00\n<+11>-11\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x96\xc5FF" +
-	"(\x03\x00\x00(\x03\x00\x00\x0f\x00\x1c\x00Pacific/ChathamUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\x00\x00\x00\x04\x00\x00\x00\x16\xff\xff\xff\xffA\xb7D\x84\xff\xff\xff\xff\xd2ږ\xbc\x00\x00\x00\x00\t\x18\xfd\xe0\x00\x00\x00\x00\t\xac" +
-	"\xa5\xe0\x00\x00\x00\x00\n\xef\xa5`\x00\x00\x00\x00\v\x9e\xfc\xe0\x00\x00\x00\x00\f\xd8\xc1\xe0\x00\x00\x00\x00\r~\xde\xe0\x00\x00\x00\x00\x0e\xb8\xa3\xe0\x00\x00\x00\x00\x0f^\xc0\xe0\x00\x00\x00\x00\x10\x98\x85\xe0\x00\x00" +
-	"\x00\x00\x11>\xa2\xe0\x00\x00\x00\x00\x12xg\xe0\x00\x00\x00\x00\x13\x1e\x84\xe0\x00\x00\x00\x00\x14XI\xe0\x00\x00\x00\x00\x14\xfef\xe0\x00\x00\x00\x00\x168+\xe0\x00\x00\x00\x00\x16\xe7\x83`\x00\x00\x00\x00\x18!" +
-	"H`\x00\x00\x00\x00\x18\xc7e`\x00\x00\x00\x00\x1a\x01*`\x00\x00\x00\x00\x1a\xa7G`\x00\x00\x00\x00\x1b\xe1\f`\x00\x00\x00\x00\x1c\x87)`\x00\x00\x00\x00\x1d\xc0\xee`\x00\x00\x00\x00\x1eg\v`\x00\x00" +
-	"\x00\x00\x1f\xa0\xd0`\x00\x00\x00\x00 F\xed`\x00\x00\x00\x00!\x80\xb2`\x00\x00\x00\x00\"0\t\xe0\x00\x00\x00\x00#i\xce\xe0\x00\x00\x00\x00$\x0f\xeb\xe0\x00\x00\x00\x00%.\x01`\x00\x00\x00\x00&\x02" +
-	"B\xe0\x00\x00\x00\x00'\r\xe3`\x00\x00\x00\x00'\xe2$\xe0\x00\x00\x00\x00(\xed\xc5`\x00\x00\x00\x00)\xc2\x06\xe0\x00\x00\x00\x00*ͧ`\x00\x00\x00\x00+\xab#`\x00\x00\x00\x00,\xad\x89`\x00\x00" +
-	"\x00\x00-\x8b\x05`\x00\x00\x00\x00.\x8dk`\x00\x00\x00\x00/j\xe7`\x00\x00\x00\x000mM`\x00\x00\x00\x001J\xc9`\x00\x00\x00\x002Vi\xe0\x00\x00\x00\x003*\xab`\x00\x00\x00\x0046" +
-	"K\xe0\x00\x00\x00\x005\n\x8d`\x00\x00\x00\x006\x16-\xe0\x00\x00\x00\x006\xf3\xa9\xe0\x00\x00\x00\x007\xf6\x0f\xe0\x00\x00\x00\x008Ӌ\xe0\x00\x00\x00\x009\xd5\xf1\xe0\x00\x00\x00\x00:\xb3m\xe0\x00\x00" +
-	"\x00\x00;\xbf\x0e`\x00\x00\x00\x00<\x93O\xe0\x00\x00\x00\x00=\x9e\xf0`\x00\x00\x00\x00>s1\xe0\x00\x00\x00\x00?~\xd2`\x00\x00\x00\x00@\\N`\x00\x00\x00\x00A^\xb4`\x00\x00\x00\x00B<" +
-	"0`\x00\x00\x00\x00C>\x96`\x00\x00\x00\x00D\x1c\x12`\x00\x00\x00\x00E\x1ex`\x00\x00\x00\x00E\xfb\xf4`\x00\x00\x00\x00F\xfeZ`\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
-	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\xab\xfc\x00\x00\x00\x00\xac" +
-	"D\x00\x04\x00\x00\xc1\\\x01\n\x00\x00\xb3L\x00\x10LMT\x00+1215\x00+1345\x00+1245\x00\n<+1245>-12:45<+1345>,M" +
-	"9.5.0/2:45,M4.1.0/3:45\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTb\xb2\xaf\xf7\x13\x04\x00\x00\x13\x04\x00\x00\x10\x00\x1c\x00Pacific" +
-	"/AucklandUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00`\x00\x00\x00\x06\x00\x00\x00\x13\xff\xff\xff\xffA\xb7L\xa8\xff\xff\xff\xff\xb0\xb4\xb2\xe8\xff\xff\xff\xff\xb1Q\x87X\xff\xff\xff\xff\xb2x\xe5h\xff\xff\xff\xff\xb3C\xe5`\xff\xff\xff\xff\xb4X\xc7h" +
-	"\xff\xff\xff\xff\xb5#\xc7`\xff\xff\xff\xff\xb68\xa9h\xff\xff\xff\xff\xb7\x03\xa9`\xff\xff\xff\xff\xb8\x18\x8bh\xff\xff\xff\xff\xb8\xec\xc5\xe0\xff\xff\xff\xff\xb9\xf8mh\xff\xff\xff\xff\xba̧\xe0\xff\xff\xff\xff" +
-	"\xbb\xd8Oh\xff\xff\xff\xff\xbc\xe3\xe8\xe0\xff\xff\xff\xff\xbd\xae\xf6\xe8\xff\xff\xff\xff\xbe\xc3\xca\xe0\xff\xff\xff\xff\xbf\x8e\xd8\xe8\xff\xff\xff\xff\xc0\xa3\xac\xe0\xff\xff\xff\xff\xc1n\xba\xe8\xff\xff\xff\xff\u0083\x8e\xe0" +
-	"\xff\xff\xff\xff\xc3N\x9c\xe8\xff\xff\xff\xff\xc4cp\xe0\xff\xff\xff\xff\xc5.~\xe8\xff\xff\xff\xff\xc6L\x8d`\xff\xff\xff\xff\xc7\x0e`\xe8\xff\xff\xff\xff\xc8,o`\xff\xff\xff\xff\xc8\xf7}h\xff\xff\xff\xff" +
-	"\xd2ښ@\x00\x00\x00\x00\t\x18\xfd\xe0\x00\x00\x00\x00\t\xac\xa5\xe0\x00\x00\x00\x00\n\xef\xa5`\x00\x00\x00\x00\v\x9e\xfc\xe0\x00\x00\x00\x00\f\xd8\xc1\xe0\x00\x00\x00\x00\r~\xde\xe0\x00\x00\x00\x00\x0e\xb8\xa3\xe0" +
-	"\x00\x00\x00\x00\x0f^\xc0\xe0\x00\x00\x00\x00\x10\x98\x85\xe0\x00\x00\x00\x00\x11>\xa2\xe0\x00\x00\x00\x00\x12xg\xe0\x00\x00\x00\x00\x13\x1e\x84\xe0\x00\x00\x00\x00\x14XI\xe0\x00\x00\x00\x00\x14\xfef\xe0\x00\x00\x00\x00" +
-	"\x168+\xe0\x00\x00\x00\x00\x16\xe7\x83`\x00\x00\x00\x00\x18!H`\x00\x00\x00\x00\x18\xc7e`\x00\x00\x00\x00\x1a\x01*`\x00\x00\x00\x00\x1a\xa7G`\x00\x00\x00\x00\x1b\xe1\f`\x00\x00\x00\x00\x1c\x87)`" +
-	"\x00\x00\x00\x00\x1d\xc0\xee`\x00\x00\x00\x00\x1eg\v`\x00\x00\x00\x00\x1f\xa0\xd0`\x00\x00\x00\x00 F\xed`\x00\x00\x00\x00!\x80\xb2`\x00\x00\x00\x00\"0\t\xe0\x00\x00\x00\x00#i\xce\xe0\x00\x00\x00\x00" +
-	"$\x0f\xeb\xe0\x00\x00\x00\x00%.\x01`\x00\x00\x00\x00&\x02B\xe0\x00\x00\x00\x00'\r\xe3`\x00\x00\x00\x00'\xe2$\xe0\x00\x00\x00\x00(\xed\xc5`\x00\x00\x00\x00)\xc2\x06\xe0\x00\x00\x00\x00*ͧ`" +
-	"\x00\x00\x00\x00+\xab#`\x00\x00\x00\x00,\xad\x89`\x00\x00\x00\x00-\x8b\x05`\x00\x00\x00\x00.\x8dk`\x00\x00\x00\x00/j\xe7`\x00\x00\x00\x000mM`\x00\x00\x00\x001J\xc9`\x00\x00\x00\x00" +
-	"2Vi\xe0\x00\x00\x00\x003*\xab`\x00\x00\x00\x0046K\xe0\x00\x00\x00\x005\n\x8d`\x00\x00\x00\x006\x16-\xe0\x00\x00\x00\x006\xf3\xa9\xe0\x00\x00\x00\x007\xf6\x0f\xe0\x00\x00\x00\x008Ӌ\xe0" +
-	"\x00\x00\x00\x009\xd5\xf1\xe0\x00\x00\x00\x00:\xb3m\xe0\x00\x00\x00\x00;\xbf\x0e`\x00\x00\x00\x00<\x93O\xe0\x00\x00\x00\x00=\x9e\xf0`\x00\x00\x00\x00>s1\xe0\x00\x00\x00\x00?~\xd2`\x00\x00\x00\x00" +
-	"@\\N`\x00\x00\x00\x00A^\xb4`\x00\x00\x00\x00B<0`\x00\x00\x00\x00C>\x96`\x00\x00\x00\x00D\x1c\x12`\x00\x00\x00\x00E\x1ex`\x00\x00\x00\x00E\xfb\xf4`\x00\x00\x00\x00F\xfeZ`" +
-	"\x02\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" +
-	"\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x00\x00\xa3\xd8\x00\x00\x00\x00\xaf\xc8\x01\x04\x00\x00\xa1\xb8\x00\t\x00\x00\xa8\xc0\x01\x04" +
-	"\x00\x00\xb6\xd0\x01\x0e\x00\x00\xa8\xc0\x00\x04LMT\x00NZST\x00NZMT\x00NZDT\x00\nNZST-12NZDT,M9.5.0,M4.1.0/3\n" +
-	"PK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xb7\xef\x97\xc6\xc6\x00\x00\x00\xc6\x00\x00\x00\x0e\x00\x1c\x00Pacific/NoumeaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v" +
-	"\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00" +
-	"\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x92\xf5\xc4t\x00\x00\x00\x00\x0e" +
-	"\xe6\xbaP\x00\x00\x00\x00\x0fV\xbb\xc0\x00\x00\x00\x00\x10ƜP\x00\x00\x00\x00\x117\xef@\x00\x00\x00\x002\xa0K\xf0\x00\x00\x00\x003\x18Dp\x02\x01\x02\x01\x02\x01\x02\x00\x00\x9c\f\x00\x00\x00\x00\xa8\xc0" +
-	"\x01\x04\x00\x00\x9a\xb0\x00\bLMT\x00+12\x00+11\x00\n<+11>-11\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x8a|\xdcU\x99\x00\x00\x00\x99\x00\x00\x00\x0f\x00\x1c\x00" +
-	"Pacific/FakaofoUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff~7U\x88\x00\x00\x00\x00N\xfd\x99\xb0\x01\x02\xff\xff_x\x00\x00\xff\xffeP\x00\x04\x00\x00\xb6\xd0\x00\bLMT\x00-1" +
-	"1\x00+13\x00\n<+13>-13\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xea\xc1\xdaυ\x00\x00\x00\x85\x00\x00\x00\x0e\x00\x1c\x00Pacific/Tahiti" +
-	"UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00" +
-	"\x00\x00\b\xff\xff\xff\xff\x94PU\xb8\x01\xff\xffs\xc8\x00\x00\xff\xffs`\x00\x04LMT\x00-10\x00\n<-10>10\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xc23\xa0\xbc\x84" +
-	"\x00\x00\x00\x84\x00\x00\x00\x0f\x00\x1c\x00Pacific/GambierUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x94PH\x04\x01\xff\xff\x81|\x00\x00\xff\xff\x81p\x00\x04LMT\x00-09\x00\n<" +
-	"-09>9\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xca\"\xb8i\xda\x00\x00\x00\xda\x00\x00\x00\x0e\x00\x1c\x00Pacific/MajuroUT\t\x00\x03\xdd\xfc\x94b\xdd" +
-	"\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00" +
-	"\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff~6\x14" +
-	"\x80\xff\xff\xff\xff\x98\x11\x95\xd0\xff\xff\xff\xff\xa09\xf9\xf0\xff\xff\xff\xff\xc1\xed5\xd0\xff\xff\xff\xff\xc9\xea\n`\xff\xff\xff\xff\xcf=Gp\xff\xff\xff\xff\xff\x86\x1bP\x01\x02\x01\x03\x02\x01\x04\x00\x00\xa0\x80" +
-	"\x00\x00\x00\x00\x9a\xb0\x00\x04\x00\x00~\x90\x00\b\x00\x00\x8c\xa0\x00\f\x00\x00\xa8\xc0\x00\x10LMT\x00+11\x00+09\x00+10\x00+12\x00\n<+12>-12\nPK\x03\x04" +
-	"\n\x00\x00\x00\x00\x00\x8fj\xbeT\xeaK\x85v\xdd\x00\x00\x00\xdd\x00\x00\x00\x10\x00\x1c\x00Pacific/HonoluluUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01" +
-	"\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" +
-	"\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xfft\xe0p\xbe\xff\xff\xff\xff\xbb\x05C" +
-	"H\xff\xff\xff\xff\xbb!qX\xff\xff\xff\xffˉ=\xc8\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2aI8\xff\xff\xff\xffՍsH\x01\x02\x01\x03\x04\x01\x05\xff\xffl\x02\x00\x00\xff\xfflX\x00\x04" +
-	"\xff\xffzh\x01\b\xff\xffzh\x01\f\xff\xffzh\x01\x10\xff\xffs`\x00\x04LMT\x00HST\x00HDT\x00HWT\x00HPT\x00\nHST10\nPK\x03\x04\n\x00\x00\x00\x00" +
-	"\x00\x8fj\xbeT\u07b54-\xd6\x00\x00\x00\xd6\x00\x00\x00\x0f\x00\x1c\x00Pacific/PohnpeiUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04" +
-	"S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\x14\xe1\xb9,\xff\xff\xff\xff~6 \xac\xff\xff\xff\xff\x98" +
-	"\x11\x95\xd0\xff\xff\xff\xff\xa09\xf9\xf0\xff\xff\xff\xff\xc1\xed5\xd0\xff\xff\xff\xff\xc9\xea\n`\xff\xff\xff\xff\xd2\x11\x0e\xf0\x01\x02\x03\x02\x04\x03\x02\xff\xffB\xd4\x00\x00\x00\x00\x94T\x00\x00\x00\x00\x9a\xb0\x00\x04" +
-	"\x00\x00~\x90\x00\b\x00\x00\x8c\xa0\x00\fLMT\x00+11\x00+09\x00+10\x00\n<+11>-11\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTt\xca{e\x92\x00\x00\x00" +
-	"\x92\x00\x00\x00\x11\x00\x1c\x00Pacific/Pago_PagoUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\b\xff\xff\xff\xffn=\xc8\b\xff\xff\xff\xff\x91\x05\xfb\b\x01\x02\x00\x00\xb1x\x00\x00\xff\xff_\xf8\x00\x00\xff\xff" +
-	"eP\x00\x04LMT\x00SST\x00\nSST11\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xcc\xf39a\xc3\x00\x00\x00\xc3\x00\x00\x00\f\x00\x1c\x00Pacific/Tru" +
-	"kUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x04" +
-	"\x00\x00\x00\f\xff\xff\xff\xff\x14\xe1\xbf4\xff\xff\xff\xff~6&\xb4\xff\xff\xff\xff\x98\x11\xa3\xe0\xff\xff\xff\xff\xa09\xf9\xf0\xff\xff\xff\xff\xc9\xea\n`\xff\xff\xff\xff\xd2\x11\x0e\xf0\x01\x02\x03\x02\x03\x02\xff\xff" +
-	"<\xcc\x00\x00\x00\x00\x8eL\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00~\x90\x00\bLMT\x00+10\x00+09\x00\n<+10>-10\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xfa\x0f" +
-	"A\x05\x99\x00\x00\x00\x99\x00\x00\x00\x10\x00\x1c\x00Pacific/PitcairnUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZ" +
-	"if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xff~7.\xf4\x00\x00\x00\x005DB\b\x01\x02\xff\xff\x86\f\x00\x00\xff\xff\x88" +
-	"x\x00\x04\xff\xff\x8f\x80\x00\nLMT\x00-0830\x00-08\x00\n<-08>8\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTD6\x83\xa1\x8b\x00\x00\x00\x8b\x00\x00\x00\x11\x00\x1c" +
-	"\x00Pacific/MarquesasUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\n\xff\xff\xff\xff\x94PLH\x01\xff\xff}8\x00\x00\xff\xffzh\x00\x04LMT\x00-0930\x00\n<-0930>" +
-	"9:30\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xec =\x89\xac\x00\x00\x00\xac\x00\x00\x00\x0e\x00\x1c\x00Pacific/KantonUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc" +
-	"\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" +
-	"\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\xc3,ۀ" +
-	"\x00\x00\x00\x00\x12V\x04\xc0\x00\x00\x00\x00/\x059\xb0\x01\x02\x03\x00\x00\x00\x00\x00\x00\xff\xffW@\x00\x04\xff\xffeP\x00\b\x00\x00\xb6\xd0\x00\f-00\x00-12\x00-11\x00+13\x00\n" +
-	"<+13>-13\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9a\xf2:F\xc9\x00\x00\x00\xc9\x00\x00\x00\x14\x00\x1c\x00Pacific/BougainvilleU" +
-	"T\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00" +
-	"\x00\x15\xff\xff\xff\xffV\xb6R(\xff\xff\xff\xffr\xed\xa4\x90\xff\xff\xff\xff\xccC6`\xff\xff\xff\xff\xd2+l\xf0\x00\x00\x00\x00T\x9e׀\x01\x02\x03\x02\x04\x00\x00\x91\xd8\x00\x00\x00\x00\x89\xf0\x00\x04\x00" +
-	"\x00\x8c\xa0\x00\t\x00\x00~\x90\x00\r\x00\x00\x9a\xb0\x00\x11LMT\x00PMMT\x00+10\x00+09\x00+11\x00\n<+11>-11\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj" +
-	"\xbeT6\xb7S{\x86\x00\x00\x00\x86\x00\x00\x00\x0e\x00\x1c\x00Pacific/TarawaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00" +
-	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff~6\x12\xcc\x01\x00\x00\xa24\x00\x00\x00\x00\xa8\xc0\x00\x04LMT\x00" +
-	"+12\x00\n<+12>-12\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x1c\xe3\xa3S\x96\x01\x00\x00\x96\x01\x00\x00\x11\x00\x1c\x00Pacific/Rarotong" +
-	"aUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\x00\x00\x00\x05" +
-	"\x00\x00\x00\x14\xff\xff\xff\xff|L\xdc\xc8\xff\xff\xff\xffߡ`\xc8\x00\x00\x00\x00\x10\xac\x1b(\x00\x00\x00\x00\x11?\xb5\x18\x00\x00\x00\x00\x12y\x81 \x00\x00\x00\x00\x13\x1f\x97\x18\x00\x00\x00\x00\x14Yc " +
-	"\x00\x00\x00\x00\x14\xffy\x18\x00\x00\x00\x00\x169E \x00\x00\x00\x00\x16蕘\x00\x00\x00\x00\x18\"a\xa0\x00\x00\x00\x00\x18\xc8w\x98\x00\x00\x00\x00\x1a\x02C\xa0\x00\x00\x00\x00\x1a\xa8Y\x98\x00\x00\x00\x00" +
-	"\x1b\xe2%\xa0\x00\x00\x00\x00\x1c\x88;\x98\x00\x00\x00\x00\x1d\xc2\a\xa0\x00\x00\x00\x00\x1eh\x1d\x98\x00\x00\x00\x00\x1f\xa1\xe9\xa0\x00\x00\x00\x00 G\xff\x98\x00\x00\x00\x00!\x81ˠ\x00\x00\x00\x00\"1\x1c\x18" +
-	"\x00\x00\x00\x00#j\xe8 \x00\x00\x00\x00$\x10\xfe\x18\x00\x00\x00\x00%J\xca \x00\x00\x00\x00%\xf0\xe0\x18\x00\x00\x00\x00'*\xac \x00\x00\x00\x00'\xd0\xc2\x18\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" +
-	"\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\xbb\xb8\x00\x00\xff\xffj8\x00\x00\xff\xfflX\x00\x04\xff\xffs`\x00\n\xff\xffzh\x01\x0eLMT\x00-1030\x00-10\x00" +
-	"-0930\x00\n<-10>10\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTt\xca{e\x92\x00\x00\x00\x92\x00\x00\x00\r\x00\x1c\x00Pacific/SamoaUT" +
-	"\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00" +
-	"\b\xff\xff\xff\xffn=\xc8\b\xff\xff\xff\xff\x91\x05\xfb\b\x01\x02\x00\x00\xb1x\x00\x00\xff\xff_\xf8\x00\x00\xff\xffeP\x00\x04LMT\x00SST\x00\nSST11\nPK\x03\x04\n\x00\x00\x00" +
-	"\x00\x00\x8fj\xbeT\xc8=ku\xae\x00\x00\x00\xae\x00\x00\x00\x12\x00\x1c\x00Pacific/KiritimatiUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91" +
-	"\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00T" +
-	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff~7H\x80\x00\x00\x00\x00\x12U\xf2\x00\x00" +
-	"\x00\x00\x00/\x05+\xa0\x01\x02\x03\xff\xffl\x80\x00\x00\xff\xffj\x00\x00\x04\xff\xffs`\x00\n\x00\x00\xc4\xe0\x00\x0eLMT\x00-1040\x00-10\x00+14\x00\n<+14>-1" +
-	"4\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xec =\x89\xac\x00\x00\x00\xac\x00\x00\x00\x11\x00\x1c\x00Pacific/EnderburyUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc" +
-	"\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" +
-	"\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\xc3,ۀ" +
-	"\x00\x00\x00\x00\x12V\x04\xc0\x00\x00\x00\x00/\x059\xb0\x01\x02\x03\x00\x00\x00\x00\x00\x00\xff\xffW@\x00\x04\xff\xffeP\x00\b\x00\x00\xb6\xd0\x00\f-00\x00-12\x00-11\x00+13\x00\n" +
-	"<+13>-13\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT>\xfe垛\x03\x00\x00\x9b\x03\x00\x00\x06\x00\x1c\x00PolandUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux" +
-	"\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00" +
-	"\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00R\x00\x00\x00\x06\x00\x00\x00\x1a\xff\xff\xff\xffV\xb6\xd0P\xff\xff\xff\xff" +
-	"\x99\xa8*\xd0\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xa0\x9a\xb6\x00" +
-	"\xff\xff\xff\xff\xa1e\xbd\x00\xff\xff\xff\xff\xa6}|`\xff\xff\xff\xff\xc8v\xde\x10\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xff" +
-	"Є\xba\x00\xff\xff\xff\xffѕ\x92p\xff\xff\xff\xffҊ\xbb`\xff\xff\xff\xff\xd3b\xffp\xff\xff\xff\xff\xd4K#\x90\xff\xff\xff\xff\xd5^\xad\x10\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10" +
-	"\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xd9\x02\xc1\x90\xff\xff\xff\xff\xd9\xe9x\x10\xff\xff\xff\xff\xe8T\xd2\x00\xff\xff\xff\xff\xe8\xf1\xb4\x80\xff\xff\xff\xff\xe9᥀\xff\xff\xff\xff\xeaі\x80\xff\xff\xff\xff" +
-	"\xec\x14\x96\x00\xff\xff\xff\xff캳\x00\xff\xff\xff\xff\xed\xaa\xa4\x00\xff\xff\xff\xff\ue695\x00\xff\xff\xff\xff\xef\xd4Z\x00\xff\xff\xff\xff\xf0zw\x00\xff\xff\xff\xff\xf1\xb4<\x00\xff\xff\xff\xff\xf2ZY\x00" +
-	"\xff\xff\xff\xff\xf3\x94\x1e\x00\xff\xff\xff\xff\xf4:;\x00\xff\xff\xff\xff\xf5}:\x80\xff\xff\xff\xff\xf6\x1a\x1d\x00\x00\x00\x00\x00\r\xa4U\x80\x00\x00\x00\x00\x0e\x8b\f\x00\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00" +
-	"\x10t(\x80\x00\x00\x00\x00\x11d\x19\x80\x00\x00\x00\x00\x12T\n\x80\x00\x00\x00\x00\x13M6\x00\x00\x00\x00\x00\x143\xec\x80\x00\x00\x00\x00\x15#݀\x00\x00\x00\x00\x16\x13\u0380\x00\x00\x00\x00\x17\x03\xbf\x80" +
-	"\x00\x00\x00\x00\x17\xf3\xb0\x80\x00\x00\x00\x00\x18㡀\x00\x00\x00\x00\x19Ӓ\x80\x00\x00\x00\x00\x1aÃ\x80\x00\x00\x00\x00\x1b\xbc\xaf\x00\x00\x00\x00\x00\x1c\xac\xa0\x00\x00\x00\x00\x00\x1d\x9c\x91\x00\x00\x00\x00\x00" +
-	"\x1e\x8c\x82\x00\x00\x00\x00\x00\x1f|s\x00\x00\x00\x00\x00 ld\x00\x00\x00\x00\x00!\\U\x00\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10" +
-	"\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00" +
-	",\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x05\x04\x05\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
-	"\x03\x02\x03\x02\x03\x02\x00\x00\x13\xb0\x00\x00\x00\x00\x13\xb0\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\r\x00\x00*0\x01\x11\x00\x00\x1c \x00\x16LMT\x00WMT\x00CEST\x00CET\x00E" +
-	"EST\x00EET\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT&S\x03\t\xae\x05\x00\x00\xae\x05" +
-	"\x00\x00\b\x00\x1c\x00PortugalUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x8d\x00\x00\x00\x06\x00\x00\x00\x1b\xff\xff\xff\xff^=\f\x1d\xff\xff\xff\xff\x92掀\xff\xff\xff\xff\x9bKmp\xff\xff\xff\xff\x9b\xfeǀ\xff\xff\xff\xff\x9c\x9c\xedp\xff\xff\xff" +
-	"\xff\x9dɃp\xff\xff\xff\xff\x9e\x7frp\xff\xff\xff\xff\x9f\xaa\xb6\xf0\xff\xff\xff\xff\xa0_Tp\xff\xff\xff\xff\xa1\x8b\xeap\xff\xff\xff\xff\xa2A\xd9p\xff\xff\xff\xff\xa3nop\xff\xff\xff\xff\xa4#\f" +
-	"\xf0\xff\xff\xff\xff\xa5O\xa2\xf0\xff\xff\xff\xff\xaa\x05\xefp\xff\xff\xff\xff\xaa\xf4\x8e\xf0\xff\xff\xff\xff\xadɧ\xf0\xff\xff\xff\xff\xae\xa7#\xf0\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x05\xf0\xff\xff\xff" +
-	"\xff\xb1\x89k\xf0\xff\xff\xff\xff\xb2p\"p\xff\xff\xff\xff\xb3r\x88p\xff\xff\xff\xff\xb4P\x04p\xff\xff\xff\xff\xb72Lp\xff\xff\xff\xff\xb8\x0f\xc8p\xff\xff\xff\xff\xb8\xff\xb9p\xff\xff\xff\xff\xb9\xef\xaa" +
-	"p\xff\xff\xff\xff\xbcȷ\xf0\xff\xff\xff\xff\xbd\xb8\xa8\xf0\xff\xff\xff\xff\xbe\x9f_p\xff\xff\xff\xff\xbf\x98\x8a\xf0\xff\xff\xff\xff\xc0\x9a\xf0\xf0\xff\xff\xff\xff\xc1xl\xf0\xff\xff\xff\xff\xc2h]\xf0\xff\xff\xff" +
-	"\xff\xc3XN\xf0\xff\xff\xff\xff\xc4?\x05p\xff\xff\xff\xff\xc580\xf0\xff\xff\xff\xff\xc6:\x96\xf0\xff\xff\xff\xff\xc7X\xacp\xff\xff\xff\xff\xc7\xd9\xdfp\xff\xff\xff\xff\xc9\x01/p\xff\xff\xff\xff\xc9\xf1 " +
-	"p\xff\xff\xff\xff\xca\xe2b\xf0\xff\xff\xff\xff˵R\xf0\xff\xff\xff\xff\xcb\xec\xa3\xe0\xff\xff\xff\xff̀K\xe0\xff\xff\xff\xff\xccܢ\xf0\xff\xff\xff\xff͕4\xf0\xff\xff\xff\xff\xcd\xc3K`\xff\xff\xff" +
-	"\xff\xcer\xa2\xe0\xff\xff\xff\xff\xceſp\xff\xff\xff\xff\xcfu\x16\xf0\xff\xff\xff\xffϬg\xe0\xff\xff\xff\xff\xd0R\x84\xe0\xff\xff\xff\xffХ\xa1p\xff\xff\xff\xff\xd1T\xf8\xf0\xff\xff\xff\xffьI" +
-	"\xe0\xff\xff\xff\xff\xd22f\xe0\xff\xff\xff\xff҅\x83p\xff\xff\xff\xff\xd3Y\xc4\xf0\xff\xff\xff\xff\xd4I\xb5\xf0\xff\xff\xff\xff\xd59\xd1 \xff\xff\xff\xff\xd6)\xc2 \xff\xff\xff\xff\xd7\x19\xb3 \xff\xff\xff" +
-	"\xff\xd8\t\xa4 \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xd9\xe9\x86 \xff\xff\xff\xff\xda\xd9w \xff\xff\xff\xff\xdb\xc9h \xff\xff\xff\xffܹY \xff\xff\xff\xffݲ\x84\xa0\xff\xff\xff\xffޢu" +
-	"\xa0\xff\xff\xff\xffߒf\xa0\xff\xff\xff\xff\xe0\x82W\xa0\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2b9\xa0\xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4B\x1b\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff" +
-	"\xff\xe6!\xfd\xa0\xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\v\x1a \xff\xff\xff\xff\xe8\xfb\v \xff\xff\xff\xff\xe9\xea\xfc \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xca\xde \xff\xff\xff\xff\xec\xba\xcf" +
-	" \xff\xff\xff\xff\xed\xaa\xc0 \xff\xff\xff\xff\ue6b1 \xff\xff\xff\xff\uf2a2 \xff\xff\xff\xff\xf0z\x93 \xff\xff\xff\xff\xf1j\x84 \xff\xff\xff\xff\xf2c\xaf\xa0\xff\xff\xff\xff\xf3S\xa0\xa0\xff\xff\xff" +
-	"\xff\xf4C\x91\xa0\xff\xff\xff\xff\xf53\x82\xa0\xff\xff\xff\xff\xf6#s\xa0\xff\xff\xff\xff\xf7\x13d\xa0\xff\xff\xff\xff\xf8\x03U\xa0\xff\xff\xff\xff\xf8\xf3F\xa0\x00\x00\x00\x00\f\xab*\x00\x00\x00\x00\x00\r\x9b\x1b" +
-	"\x00\x00\x00\x00\x00\x0e\x8b\f\x00\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00\x10t(\x80\x00\x00\x00\x00\x11d\x19\x80\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13C\xfb\x80\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00" +
-	"\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㽠\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd" +
-	"\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00" +
-	"\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16" +
-	"\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00" +
-	"\x001]\xd9\x10\x00\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x02\x01\x03\x01\x02\x01\x03\x01" +
-	"\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x05\x04\x05\x04\x05\x04\x01\xff\xff\xf7c\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\t\x00\x00\x1c \x01\r\x00\x00\x0e\x10\x00\x12\x00\x00\x1c " +
-	"\x01\x16LMT\x00WEST\x00WET\x00WEMT\x00CET\x00CEST\x00\nWET0WEST,M3.5.0/1,M10.5.0\nPK\x03\x04" +
-	"\n\x00\x00\x00\x00\x00\x8ej\xbeT\xee\xf0BB\xff\x01\x00\x00\xff\x01\x00\x00\x03\x00\x1c\x00ROCUT\t\x00\x03\xdc\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZi" +
-	"f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xfft\xce\xf0\x18\xff\xff\xff\xff\xc3UI\x80\xff\xff\xff\xff\xd2TY\x80\xff\xff\xff\xff" +
-	"Ӌ{\x80\xff\xff\xff\xff\xd4B\xad\xf0\xff\xff\xff\xff\xd5E\"\x00\xff\xff\xff\xff\xd6L\xbf\xf0\xff\xff\xff\xff\xd7<\xbf\x00\xff\xff\xff\xff\xd8\x06fp\xff\xff\xff\xff\xd9\x1d\xf2\x80\xff\xff\xff\xff\xd9\xe7\x99\xf0" +
-	"\xff\xff\xff\xff\xda\xff&\x00\xff\xff\xff\xff\xdb\xc8\xcdp\xff\xff\xff\xff\xdc\xe0Y\x80\xff\xff\xff\xffݪ\x00\xf0\xff\xff\xff\xff\xders\x00\xff\xff\xff\xffߵdp\xff\xff\xff\xff\xe0|\x85\x00\xff\xff\xff\xff" +
-	"ᖗ\xf0\xff\xff\xff\xff\xe2]\xb8\x80\xff\xff\xff\xff\xe3w\xcbp\xff\xff\xff\xff\xe4>\xec\x00\xff\xff\xff\xff\xe50 p\xff\xff\xff\xff\xe6!q\x00\xff\xff\xff\xff\xe7\x12\xa5p\xff\xff\xff\xff\xe8\x02\xa4\x80" +
-	"\xff\xff\xff\xff\xe8\xf3\xd8\xf0\xff\xff\xff\xff\xe9\xe3\xd8\x00\xff\xff\xff\xff\xea\xd5\fp\xff\xff\xff\xff\xeb\xc5\v\x80\xff\xff\xff\xff\xec\xb6?\xf0\xff\xff\xff\xff\xed\xf7\xfc\x00\xff\xff\xff\xff\xee\x98\xc4\xf0\xff\xff\xff\xff" +
-	"\xef\xd9/\x80\xff\xff\xff\xff\xf0y\xf8p\x00\x00\x00\x00\a\xfcV\x00\x00\x00\x00\x00\b\xed\x8ap\x00\x00\x00\x00\t݉\x80\x00\x00\x00\x00\nν\xf0\x00\x00\x00\x00\x11ۡ\x80\x00\x00\x00\x00\x12T\xddp" +
-	"\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x00\x00q\xe8\x00\x00\x00\x00p\x80\x00\x04\x00\x00~\x90\x00\b\x00" +
-	"\x00~\x90\x01\fLMT\x00CST\x00JST\x00CDT\x00\nCST-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xc7X,Y\x9f\x01\x00\x00\x9f\x01\x00\x00\x03\x00\x1c\x00RO" +
-	"KUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x06" +
-	"\x00\x00\x00\x10\xff\xff\xff\xff\x8b\xd7\xf0x\xff\xff\xff\xff\x92\xe6\x16\xf8\xff\xff\xff\xff\xd2C'\xf0\xff\xff\xff\xff\xd7e\x8fp\xff\xff\xff\xff\xd7\xee\x9d`\xff\xff\xff\xff\xd8\xf8\xfap\xff\xff\xff\xff\xd9\xcd-\xe0" +
-	"\xff\xff\xff\xff\xda\u05ca\xf0\xff\xff\xff\xffۭ\x0f\xe0\xff\xff\xff\xff\xdc\xe6\xe2\xf0\xff\xff\xff\xff\u074c\xf1\xe0\xff\xff\xff\xff\xe2O)\xf0\xff\xff\xff\xff\xe4k\xb7\xf8\xff\xff\xff\xff\xe5\x13\x18h\xff\xff\xff\xff" +
-	"\xe6b\x03x\xff\xff\xff\xff\xe7\x11L\xe8\xff\xff\xff\xff\xe8/px\xff\xff\xff\xff\xe8\xe7\xf4h\xff\xff\xff\xff\xea\x0fRx\xff\xff\xff\xff\xea\xc7\xd6h\xff\xff\xff\xff\xeb\xef4x\xff\xff\xff\xff째h" +
-	"\xff\xff\xff\xff\xed\xcf\x16x\xff\xff\xff\xff\ue1dah\xff\xff\xff\xff\xf05qx\x00\x00\x00\x00 \xa3`\x90\x00\x00\x00\x00!ng\x90\x00\x00\x00\x00\"\x83B\x90\x00\x00\x00\x00#NI\x90\x01\x02\x04\x03" +
-	"\x04\x03\x04\x03\x04\x03\x04\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01\x04\x03\x04\x03\x04\x00\x00w\b\x00\x00\x00\x00w\x88\x00\x04\x00\x00~\x90\x00\b\x00\x00\x8c\xa0\x01\f\x00\x00~\x90\x00\x04\x00\x00\x85\x98\x01" +
-	"\fLMT\x00KST\x00JST\x00KDT\x00\nKST-9\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x06\xaa>\xa8\x00\x01\x00\x00\x00\x01\x00\x00\t\x00\x1c\x00Singap" +
-	"oreUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00" +
-	"\x00\b\x00\x00\x00 \xff\xff\xff\xff~6S\xa3\xff\xff\xff\xff\x86\x83\x85\xa3\xff\xff\xff\xff\xbagN\x90\xff\xff\xff\xff\xc0\n\xe4`\xff\xff\xff\xffʳ\xe5`\xff\xff\xff\xffˑ_\b\xff\xff\xff\xff\xd2H" +
-	"m\xf0\x00\x00\x00\x00\x16\x91\xf5\b\x01\x02\x03\x04\x05\x06\x05\a\x00\x00a]\x00\x00\x00\x00a]\x00\x04\x00\x00bp\x00\b\x00\x00g \x01\f\x00\x00g \x00\f\x00\x00ix\x00\x12\x00\x00~\x90\x00\x18" +
-	"\x00\x00p\x80\x00\x1cLMT\x00SMT\x00+07\x00+0720\x00+0730\x00+09\x00+08\x00\n<+08>-8\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbe" +
-	"T\aW\x10Ѱ\x04\x00\x00\xb0\x04\x00\x00\x06\x00\x1c\x00TurkeyUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00" +
+	"0.5.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\aW\x10Ѱ\x04\x00\x00\xb0\x04\x00\x00\x0f\x00\x00\x00Europe/IstanbulTZif2\x00\x00\x00\x00" +
 	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
 	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00s\x00\x00\x00\x06\x00\x00\x00\x19\xff\xff\xff\xffV\xb6\xc8\xd8\xff\xff\xff\xff\x90\x8b\xf5\x98\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9bվ\xd0\xff\xff" +
 	"\xff\xff\xa2ec\xe0\xff\xff\xff\xff\xa3{\x82P\xff\xff\xff\xff\xa4N\x80`\xff\xff\xff\xff\xa5?\xb4\xd0\xff\xff\xff\xff\xa6%'\xe0\xff\xff\xff\xff\xa7'\x7f\xd0\xff\xff\xff\xff\xaa((`\xff\xff\xff\xff\xaa\xe1" +
@@ -6019,1099 +4586,2058 @@
 	"\x00\x00S8\xbe\x10\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V>\x9e\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00W\xcf.P\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
 	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
 	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x00\x00\x1b(\x00\x00\x00\x00\x1bh\x00\x04\x00\x00*0\x01\b\x00" +
-	"\x00\x1c \x00\r\x00\x00*0\x00\x11\x00\x008@\x01\x15LMT\x00IMT\x00EEST\x00EET\x00+03\x00+04\x00\n<+03>-3\nPK\x03\x04\n\x00\x00\x00\x00" +
-	"\x00\x8fj\xbeT\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\x03\x00\x1c\x00UCTUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00\nUTC0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x1c\x00US/UT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT5\x11" +
-	"Q\x06\xd1\x03\x00\x00\xd1\x03\x00\x00\t\x00\x1c\x00US/AlaskaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00" +
+	"\x00\x1c \x00\r\x00\x00*0\x00\x11\x00\x008@\x01\x15LMT\x00IMT\x00EEST\x00EET\x00+03\x00+04\x00\n<+03>-3\nPK\x03\x04\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\r\x00\x00\x00Europe/JerseyTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x9f\x00\x00\x00\x05\x00\x00\x00\x11\xff\xff\xff\xff\x1a]\t\xcb\xff\xff\xff\xff\x9b&\xad\xa0\xff\xff\xff\xff\x9b\xd6\x05 \xff\xff\xff\xff\x9c\xcf0\xa0\xff\xff\xff\xff\x9d\xa4à\xff\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff" +
+	"\xff\x9f\x97\x1a\xa0\xff\xff\xff\xff\xa0\x85\xba \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{Ƞ\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%`" +
+	" \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00Ӡ\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff" +
+	"\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \xff\xff\xff\xff\xb1\x92Р\xff\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P." +
+	"\xa0\xff\xff\xff\xff\xb5IZ \xff\xff\xff\xff\xb60\x10\xa0\xff\xff\xff\xff\xb72v\xa0\xff\xff\xff\xff\xb8\x0f\xf2\xa0\xff\xff\xff\xff\xb9\x12X\xa0\xff\xff\xff\xff\xb9\xefԠ\xff\xff\xff\xff\xba\xe9\x00 \xff\xff\xff" +
+	"\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd" +
+	" \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xca\x16&\x90\xff\xff\xff" +
+	"\xffʗY\x90\xff\xff\xff\xff\xcb\xd1\x1e\x90\xff\xff\xff\xff\xccw;\x90\xff\xff\xff\xffͱ\x00\x90\xff\xff\xff\xff\xce`X\x10\xff\xff\xff\xffϐ\xe2\x90\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16" +
+	"\x10\xff\xff\xff\xff\xd1\xfb2\x10\xff\xff\xff\xff\xd2i\xfe \xff\xff\xff\xff\xd3c)\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd5B\xfd\x90\xff\xff\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff" +
+	"\xff\xd6N\xac \xff\xff\xff\xff\xd6\xfe\x03\xa0\xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce" +
+	" \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\u07b4\xea\xa0\xff\xff\xff\xff߮\x16 \xff\xff\xff\xff\xe0\x94̠\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt \xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff" +
+	"\xff\xe4T\x90\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6=\xad \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\v \xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed" +
+	" \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\ue6b1 \xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff" +
+	"\xff\xf2\x7f_ \xff\xff\xff\xff\xf3Jf \xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\r\xa0\xff\xff\xff\xff\xf6?# \xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0\xd1" +
+	"\xa0\xff\xff\xff\xff\xf9\xfe\xe7 \xff\xff\xff\xff\xfa\xc0\xb3\xa0\xff\xff\xff\xff\xfb\xe8\x03\xa0\xff\xff\xff\xff\xfc{\xab\xa0\xff\xff\xff\xff\xfdǻp\x00\x00\x00\x00\x03p\xc6 \x00\x00\x00\x00\x04)X \x00\x00\x00" +
+	"\x00\x05P\xa8 \x00\x00\x00\x00\x06\t: \x00\x00\x00\x00\a0\x8a \x00\x00\x00\x00\a\xe9\x1c \x00\x00\x00\x00\t\x10l \x00\x00\x00\x00\t\xc8\xfe \x00\x00\x00\x00\n\xf0N \x00\x00\x00\x00\v\xb2\x1a" +
+	"\xa0\x00\x00\x00\x00\f\xd00 \x00\x00\x00\x00\r\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \x00\x00\x00\x00\x0fqޠ\x00\x00\x00\x00\x10\x99.\xa0\x00\x00\x00\x00\x11Q\xc0\xa0\x00\x00\x00\x00\x12y\x10\xa0\x00\x00\x00" +
+	"\x00\x131\xa2\xa0\x00\x00\x00\x00\x14X\xf2\xa0\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x168Ɛ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x18\x18\xa8\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19\xf8\x8a" +
+	"\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xe1\xa7\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\xc1\x89\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f\xa1k\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00" +
+	"\x00!\x81M\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#a/\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%JK\x90\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'*-\x90\x00\x00\x00\x00'\xf54" +
+	"\x90\x00\x00\x00\x00)\n\x0f\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xe9\xf1\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xc9Ӑ\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\xa9\xb5\x90\x00\x00\x00" +
+	"\x00/t\xbc\x90\x00\x00\x00\x000\x89\x97\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\xff\xff\xff\xb5\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x00\x04LMT\x00BST\x00GMT\x00BDST\x00\nGMT0BST,M3.5" +
+	".0/1,M10.5.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00O+j\x94\x88\x03\x00\x00\x88\x03\x00\x00\x12\x00\x00\x00Europe/Kaliningra" +
+	"dTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\x00\x00\x00\b\x00\x00\x00\"\xff\xff\xff\xffo\xa2[H\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0" +
+	"\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xc8\tq\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff" +
+	"\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1|w\xe0\xff\xff\xff\xffѕ\x84`\xff\xff\xff\xffҊ\xadP\xff\xff\xff\xff\xd3Y\xb6\xe0" +
+	"\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00" +
+	"\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0" +
+	"\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\x19\x00\x00\x00\x00\x00&\f\n\x00\x00\x00\x00\x00'\x055\x80\x00\x00\x00\x00'\xf5&\x80\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00" +
+	")\xd5\b\x80\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4ۀ\x00\x00\x00\x00-\x94̀\x00\x00\x00\x00.\x84\xbd\x80\x00\x00\x00\x00/t\xae\x80\x00\x00\x00\x000d\x9f\x80" +
+	"\x00\x00\x00\x001]\xcb\x00\x00\x00\x00\x002r\xa6\x00\x00\x00\x00\x003=\xad\x00\x00\x00\x00\x004R\x88\x00\x00\x00\x00\x005\x1d\x8f\x00\x00\x00\x00\x0062j\x00\x00\x00\x00\x006\xfdq\x00\x00\x00\x00\x00" +
+	"8\x1b\x86\x80\x00\x00\x00\x008\xddS\x00\x00\x00\x00\x009\xfbh\x80\x00\x00\x00\x00:\xbd5\x00\x00\x00\x00\x00;\xdbJ\x80\x00\x00\x00\x00<\xa6Q\x80\x00\x00\x00\x00=\xbb,\x80\x00\x00\x00\x00>\x863\x80" +
+	"\x00\x00\x00\x00?\x9b\x0e\x80\x00\x00\x00\x00@f\x15\x80\x00\x00\x00\x00A\x84+\x00\x00\x00\x00\x00BE\xf7\x80\x00\x00\x00\x00Cd\r\x00\x00\x00\x00\x00D%ـ\x00\x00\x00\x00EC\xef\x00\x00\x00\x00\x00" +
+	"F\x05\xbb\x80\x00\x00\x00\x00G#\xd1\x00\x00\x00\x00\x00G\xee\xd8\x00\x00\x00\x00\x00I\x03\xb3\x00\x00\x00\x00\x00Iκ\x00\x00\x00\x00\x00J\xe3\x95\x00\x00\x00\x00\x00K\xae\x9c\x00\x00\x00\x00\x00Ḻ\x80" +
+	"\x00\x00\x00\x00M\x8e~\x00\x00\x00\x00\x00TL+p\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x03\x04\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" +
+	"\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\a\x04\x00\x00\x138\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00*0\x01\r" +
+	"\x00\x00\x1c \x00\x12\x00\x008@\x01\x16\x00\x00*0\x00\x1a\x00\x00*0\x00\x1eLMT\x00CEST\x00CET\x00EEST\x00EET\x00MSD\x00MSK\x00+03\x00\nE" +
+	"ET-2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00iS\x18D.\x02\x00\x00.\x02\x00\x00\v\x00\x00\x00Europe/KievTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\x00\x00\x00\b\x00\x00\x00\"\xff\xff\xff\xffV\xb6\xc7d\xff\xff\xff\xff\xaa\x19\xa7d\xff\xff\xff\xff\xb5\xa4\x19`\xff\xff\xff\xff\xca\xcd.\xd0\xff\xff\xff\xff\xcc\xe7K" +
+	"\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xff\xceͨp\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00" +
+	"\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d" +
+	"\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00" +
+	"\x00&\x8d \xe0\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd5\b\x80\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4ۀ\x00\x00\x00\x00-\x94̀\x00\x00\x00\x00.\x84\xbd" +
+	"\x80\x00\x00\x00\x00/t\xae\x80\x00\x00\x00\x000d\x9f\x80\x00\x00\x00\x001]\xcb\x00\x00\x00\x00\x002r\xb4\x10\x01\x02\x03\x05\x04\x05\x04\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06" +
+	"\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\x00\x00\x1c\x9c\x00\x00\x00\x00\x1c\x9c\x00\x04\x00\x00\x1c \x00\b\x00\x00*0\x00\f\x00\x00\x0e\x10\x00\x10\x00\x00\x1c \x01\x14\x00\x008@\x01\x19\x00\x00*0\x01\x1d" +
+	"LMT\x00KMT\x00EET\x00MSK\x00CET\x00CEST\x00MSD\x00EEST\x00\nEET-2EEST,M3.5.0/3,M10.5." +
+	"0/4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\xfe\x83\xe5\xcd\x02\x00\x00\xcd\x02\x00\x00\f\x00\x00\x00Europe/KirovTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xa1\x009\x80\xff\xff\xff\xff\xb5\xa4\vP\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\b\xcd" +
+	"@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a̅\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00" +
+	"\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\8\xe0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<\x1a\xe0\x00\x00\x00\x00$,\v\xe0\x00\x00\x00\x00%\x1c\n" +
+	"\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00" +
+	"\x00-\x94\xbep\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry" +
+	"\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00" +
+	"\x00;\xdb<p\x00\x00\x00\x00<\xa6Cp\x00\x00\x00\x00=\xbb\x1ep\x00\x00\x00\x00>\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f\ap\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9" +
+	"p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05\xadp\x00\x00\x00\x00G#\xc2\xf0\x00\x00\x00\x00G\xee\xc9\xf0\x00\x00\x00\x00I\x03\xa4\xf0\x00\x00\x00" +
+	"\x00IΫ\xf0\x00\x00\x00\x00J\xe3\x86\xf0\x00\x00\x00\x00K\xae\x8d\xf0\x00\x00\x00\x00Ḷp\x00\x00\x00\x00M\x8eo\xf0\x00\x00\x00\x00TL\x1d`\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x04\x01\x04\x01\x03\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x03\x01\x00\x00.\x98\x00\x00\x00\x00*0\x00\x04" +
+	"\x00\x00FP\x01\b\x00\x008@\x00\f\x00\x008@\x01\fLMT\x00+03\x00+05\x00+04\x00\n<+03>-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00iS\x18" +
+	"D.\x02\x00\x00.\x02\x00\x00\v\x00\x00\x00Europe/KyivTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\x00\x00\x00\b\x00\x00\x00\"\xff" +
+	"\xff\xff\xffV\xb6\xc7d\xff\xff\xff\xff\xaa\x19\xa7d\xff\xff\xff\xff\xb5\xa4\x19`\xff\xff\xff\xff\xca\xcd.\xd0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xff\xce" +
+	"ͨp\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00" +
+	"\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"" +
+	"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00&\x8d \xe0\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd5\b\x80\x00" +
+	"\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4ۀ\x00\x00\x00\x00-\x94̀\x00\x00\x00\x00.\x84\xbd\x80\x00\x00\x00\x00/t\xae\x80\x00\x00\x00\x000d\x9f\x80\x00\x00\x00\x001" +
+	"]\xcb\x00\x00\x00\x00\x002r\xb4\x10\x01\x02\x03\x05\x04\x05\x04\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\x00\x00\x1c\x9c\x00\x00\x00\x00\x1c\x9c" +
+	"\x00\x04\x00\x00\x1c \x00\b\x00\x00*0\x00\f\x00\x00\x0e\x10\x00\x10\x00\x00\x1c \x01\x14\x00\x008@\x01\x19\x00\x00*0\x01\x1dLMT\x00KMT\x00EET\x00MSK\x00CET\x00CE" +
+	"ST\x00MSD\x00EEST\x00\nEET-2EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&S\x03\t" +
+	"\xae\x05\x00\x00\xae\x05\x00\x00\r\x00\x00\x00Europe/LisbonTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8d\x00\x00\x00\x06\x00\x00\x00\x1b" +
+	"\xff\xff\xff\xff^=\f\x1d\xff\xff\xff\xff\x92掀\xff\xff\xff\xff\x9bKmp\xff\xff\xff\xff\x9b\xfeǀ\xff\xff\xff\xff\x9c\x9c\xedp\xff\xff\xff\xff\x9dɃp\xff\xff\xff\xff\x9e\x7frp\xff\xff\xff\xff" +
+	"\x9f\xaa\xb6\xf0\xff\xff\xff\xff\xa0_Tp\xff\xff\xff\xff\xa1\x8b\xeap\xff\xff\xff\xff\xa2A\xd9p\xff\xff\xff\xff\xa3nop\xff\xff\xff\xff\xa4#\f\xf0\xff\xff\xff\xff\xa5O\xa2\xf0\xff\xff\xff\xff\xaa\x05\xefp" +
+	"\xff\xff\xff\xff\xaa\xf4\x8e\xf0\xff\xff\xff\xff\xadɧ\xf0\xff\xff\xff\xff\xae\xa7#\xf0\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x05\xf0\xff\xff\xff\xff\xb1\x89k\xf0\xff\xff\xff\xff\xb2p\"p\xff\xff\xff\xff" +
+	"\xb3r\x88p\xff\xff\xff\xff\xb4P\x04p\xff\xff\xff\xff\xb72Lp\xff\xff\xff\xff\xb8\x0f\xc8p\xff\xff\xff\xff\xb8\xff\xb9p\xff\xff\xff\xff\xb9\xef\xaap\xff\xff\xff\xff\xbcȷ\xf0\xff\xff\xff\xff\xbd\xb8\xa8\xf0" +
+	"\xff\xff\xff\xff\xbe\x9f_p\xff\xff\xff\xff\xbf\x98\x8a\xf0\xff\xff\xff\xff\xc0\x9a\xf0\xf0\xff\xff\xff\xff\xc1xl\xf0\xff\xff\xff\xff\xc2h]\xf0\xff\xff\xff\xff\xc3XN\xf0\xff\xff\xff\xff\xc4?\x05p\xff\xff\xff\xff" +
+	"\xc580\xf0\xff\xff\xff\xff\xc6:\x96\xf0\xff\xff\xff\xff\xc7X\xacp\xff\xff\xff\xff\xc7\xd9\xdfp\xff\xff\xff\xff\xc9\x01/p\xff\xff\xff\xff\xc9\xf1 p\xff\xff\xff\xff\xca\xe2b\xf0\xff\xff\xff\xff˵R\xf0" +
+	"\xff\xff\xff\xff\xcb\xec\xa3\xe0\xff\xff\xff\xff̀K\xe0\xff\xff\xff\xff\xccܢ\xf0\xff\xff\xff\xff͕4\xf0\xff\xff\xff\xff\xcd\xc3K`\xff\xff\xff\xff\xcer\xa2\xe0\xff\xff\xff\xff\xceſp\xff\xff\xff\xff" +
+	"\xcfu\x16\xf0\xff\xff\xff\xffϬg\xe0\xff\xff\xff\xff\xd0R\x84\xe0\xff\xff\xff\xffХ\xa1p\xff\xff\xff\xff\xd1T\xf8\xf0\xff\xff\xff\xffьI\xe0\xff\xff\xff\xff\xd22f\xe0\xff\xff\xff\xff҅\x83p" +
+	"\xff\xff\xff\xff\xd3Y\xc4\xf0\xff\xff\xff\xff\xd4I\xb5\xf0\xff\xff\xff\xff\xd59\xd1 \xff\xff\xff\xff\xd6)\xc2 \xff\xff\xff\xff\xd7\x19\xb3 \xff\xff\xff\xff\xd8\t\xa4 \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff" +
+	"\xd9\xe9\x86 \xff\xff\xff\xff\xda\xd9w \xff\xff\xff\xff\xdb\xc9h \xff\xff\xff\xffܹY \xff\xff\xff\xffݲ\x84\xa0\xff\xff\xff\xffޢu\xa0\xff\xff\xff\xffߒf\xa0\xff\xff\xff\xff\xe0\x82W\xa0" +
+	"\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2b9\xa0\xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4B\x1b\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6!\xfd\xa0\xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff" +
+	"\xe8\v\x1a \xff\xff\xff\xff\xe8\xfb\v \xff\xff\xff\xff\xe9\xea\xfc \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xca\xde \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xaa\xc0 \xff\xff\xff\xff\ue6b1 " +
+	"\xff\xff\xff\xff\uf2a2 \xff\xff\xff\xff\xf0z\x93 \xff\xff\xff\xff\xf1j\x84 \xff\xff\xff\xff\xf2c\xaf\xa0\xff\xff\xff\xff\xf3S\xa0\xa0\xff\xff\xff\xff\xf4C\x91\xa0\xff\xff\xff\xff\xf53\x82\xa0\xff\xff\xff\xff" +
+	"\xf6#s\xa0\xff\xff\xff\xff\xf7\x13d\xa0\xff\xff\xff\xff\xf8\x03U\xa0\xff\xff\xff\xff\xf8\xf3F\xa0\x00\x00\x00\x00\f\xab*\x00\x00\x00\x00\x00\r\x9b\x1b\x00\x00\x00\x00\x00\x0e\x8b\f\x00\x00\x00\x00\x00\x0f\x847\x80" +
+	"\x00\x00\x00\x00\x10t(\x80\x00\x00\x00\x00\x11d\x19\x80\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13C\xfb\x80\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00" +
+	"\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㽠\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10" +
+	"\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00" +
+	"%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90" +
+	"\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x00\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x02\x01\x03\x01\x02\x01\x03\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x04\x05\x04\x05\x04\x05\x04\x01\xff\xff\xf7c\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\t\x00\x00\x1c \x01\r\x00\x00\x0e\x10\x00\x12\x00\x00\x1c \x01\x16LMT\x00WEST\x00WET\x00WE" +
+	"MT\x00CET\x00CEST\x00\nWET0WEST,M3.5.0/1,M10.5.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1C\xf9\xa1\xde\x01\x00" +
+	"\x00\xde\x01\x00\x00\x10\x00\x00\x00Europe/LjubljanaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$\x00\x00\x00\x03\x00\x00\x00\r" +
+	"\xff\xff\xff\xff^<\xf0H\xff\xff\xff\xff\xca\x025\xe0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff" +
+	"ѡ\x8c\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10" +
+	"\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00" +
+	"%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90" +
+	"\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x138\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\bLMT\x00CET\x00CEST\x00\nCET-" +
+	"1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\r\x00\x00\x00Europe/" +
+	"LondonTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZi" +
+	"f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f\x00\x00\x00\x05\x00\x00\x00\x11\xff\xff\xff\xff\x1a]\t\xcb\xff\xff\xff\xff\x9b&\xad\xa0\xff\xff\xff" +
+	"\xff\x9b\xd6\x05 \xff\xff\xff\xff\x9c\xcf0\xa0\xff\xff\xff\xff\x9d\xa4à\xff\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff\xff\xff\xa0\x85\xba \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c" +
+	" \xff\xff\xff\xff\xa3{Ƞ\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff" +
+	"\xff\xaa\x00Ӡ\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870" +
+	" \xff\xff\xff\xff\xb1\x92Р\xff\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \xff\xff\xff\xff\xb60\x10\xa0\xff\xff\xff\xff\xb72v\xa0\xff\xff\xff" +
+	"\xff\xb8\x0f\xf2\xa0\xff\xff\xff\xff\xb9\x12X\xa0\xff\xff\xff\xff\xb9\xefԠ\xff\xff\xff\xff\xba\xe9\x00 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe" +
+	"\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff" +
+	"\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xca\x16&\x90\xff\xff\xff\xffʗY\x90\xff\xff\xff\xff\xcb\xd1\x1e\x90\xff\xff\xff\xff\xccw;\x90\xff\xff\xff\xffͱ\x00" +
+	"\x90\xff\xff\xff\xff\xce`X\x10\xff\xff\xff\xffϐ\xe2\x90\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xfb2\x10\xff\xff\xff\xff\xd2i\xfe \xff\xff\xff\xff\xd3c)\xa0\xff\xff\xff" +
+	"\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd5B\xfd\x90\xff\xff\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd6\xfe\x03\xa0\xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95" +
+	" \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\u07b4\xea\xa0\xff\xff\xff\xff߮\x16 \xff\xff\xff" +
+	"\xff\xe0\x94̠\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt \xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4T\x90\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6=\xad \xff\xff\xff\xff\xe7\x1b)" +
+	" \xff\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\v \xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff" +
+	"\xff\ue6b1 \xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\x7f_ \xff\xff\xff\xff\xf3Jf \xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\r" +
+	"\xa0\xff\xff\xff\xff\xf6?# \xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0Ѡ\xff\xff\xff\xff\xf9\xfe\xe7 \xff\xff\xff\xff\xfa\xc0\xb3\xa0\xff\xff\xff\xff\xfb\xe8\x03\xa0\xff\xff\xff" +
+	"\xff\xfc{\xab\xa0\xff\xff\xff\xff\xfdǻp\x00\x00\x00\x00\x03p\xc6 \x00\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\t: \x00\x00\x00\x00\a0\x8a \x00\x00\x00\x00\a\xe9\x1c" +
+	" \x00\x00\x00\x00\t\x10l \x00\x00\x00\x00\t\xc8\xfe \x00\x00\x00\x00\n\xf0N \x00\x00\x00\x00\v\xb2\x1a\xa0\x00\x00\x00\x00\f\xd00 \x00\x00\x00\x00\r\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \x00\x00\x00" +
+	"\x00\x0fqޠ\x00\x00\x00\x00\x10\x99.\xa0\x00\x00\x00\x00\x11Q\xc0\xa0\x00\x00\x00\x00\x12y\x10\xa0\x00\x00\x00\x00\x131\xa2\xa0\x00\x00\x00\x00\x14X\xf2\xa0\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x168\xc6" +
+	"\x90\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x18\x18\xa8\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19\xf8\x8a\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xe1\xa7\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00" +
+	"\x00\x1d\xc1\x89\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f\xa1k\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\x81M\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#a/\x10\x00\x00\x00\x00$,6" +
+	"\x10\x00\x00\x00\x00%JK\x90\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'*-\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00)\n\x0f\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xe9\xf1\x90\x00\x00\x00" +
+	"\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xc9Ӑ\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\xa9\xb5\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000\x89\x97\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xff\xb5\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10" +
+	"\x00\x04LMT\x00BST\x00GMT\x00BDST\x00\nGMT0BST,M3.5.0/1,M10.5.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o" +
+	"\xbc\x831O\x04\x00\x00O\x04\x00\x00\x11\x00\x00\x00Europe/LuxembourgTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00f\x00" +
+	"\x00\x00\x06\x00\x00\x00\x1a\xff\xff\xff\xffV\xb6\xdf\xe6\xff\xff\xff\xffm\xe8\xc8\x00\xff\xff\xff\xff\x98DI\x80\xff\xff\xff\xff\x9b\f%p\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d" +
+	"\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\x9f\xce\xf80\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1~\xbbp\xff\xff\xff\xff\xa2.\x12\xf0\xff\xff\xff\xff\xa3zL\xf0\xff" +
+	"\xff\xff\xff\xa45\x81\xf0\xff\xff\xff\xff\xa5^#p\xff\xff\xff\xff\xa6%5\xf0\xff\xff\xff\xff\xa7'\x9b\xf0\xff\xff\xff\xff\xa8*\x01\xf0\xff\xff\xff\xff\xa9\a}\xf0\xff\xff\xff\xff\xa9\xee4p\xff\xff\xff\xff\xaa" +
+	"\xe7_\xf0\xff\xff\xff\xff\xab\xd7P\xf0\xff\xff\xff\xff\xac\xc7A\xf0\xff\xff\xff\xff\xadɧ\xf0\xff\xff\xff\xff\xae\xa7#\xf0\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x05\xf0\xff\xff\xff\xff\xb1\x89k\xf0\xff" +
+	"\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \xff\xff\xff\xff\xb60\x10\xa0\xff\xff\xff\xff\xb72v\xa0\xff\xff\xff\xff\xb8\x0f\xf2\xa0\xff\xff\xff\xff\xb8" +
+	"\xff\xe3\xa0\xff\xff\xff\xff\xb9\xefԠ\xff\xff\xff\xff\xba\u058b \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xc8\xe2 \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\x9f\x89\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff" +
+	"\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2h\x88 \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4?/\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7" +
+	"X֠\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xc8J\x19 \xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xff\xd0n^\x90\xff" +
+	"\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2N@\x90\xff\xff\xff\xffӑ@\x10\xff\xff\xff\xff\xd4K#\x90\x00\x00\x00\x00\r\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10" +
+	"t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00" +
+	"\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e" +
+	"\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00" +
+	"\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00," +
+	"\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x03\x04\x03\x04\x03\x04\x03\x02\x05\x02\x05\x02\x05\x02\x05" +
+	"\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" +
+	"\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x00\x00\x04\x1a\x00\x00\x00\x00\x04\x1a\x00\x04\x00\x00\x00\x00\x00\b\x00\x00\x0e\x10\x00\f\x00\x00\x1c \x01\x10\x00\x00\x0e\x10\x01" +
+	"\x15LMT\x00BMT\x00WET\x00CET\x00CEST\x00WEST\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00Zk#V\x81\x03\x00\x00\x81\x03\x00\x00\r\x00\x00\x00Europe/MadridTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00O\x00\x00\x00\x06\x00\x00\x00\x1b\xff\xff\xff\xff~6\xb5\x00\xff\xff\xff\xff\x9e\xba\xc5\xf0\xff\xff\xff\xff\x9f\xa09\x00\xff\xff\xff\xff\xa0\x90\x1b\xf0\xff\xff\xff\xff\xa1\x81l\x80\xff\xff\xff\xff\xaa\x05\xef" +
+	"p\xff\xff\xff\xff\xaa\xe7n\x00\xff\xff\xff\xff\xadɧ\xf0\xff\xff\xff\xff\xae\xa72\x00\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x14\x00\xff\xff\xff\xff\xb1\x89z\x00\xff\xff\xff\xff\xb2p0\x80\xff\xff\xff" +
+	"\xff\xb3r\x88p\xff\xff\xff\xff\xb4P\x12\x80\xff\xff\xff\xff\xc2\xc9\xec\xf0\xff\xff\xff\xff\xc3X]\x00\xff\xff\xff\xff\xc4H?\xf0\xff\xff\xff\xff\xc4m\x1b\xe0\xff\xff\xff\xff\xc59t`\xff\xff\xff\xff\xc7![" +
+	"\x80\xff\xff\xff\xff\xc7\xf5\x8e\xf0\xff\xff\xff\xff\xcb\xf5\xde`\xff\xff\xff\xff̕q\xf0\xff\xff\xff\xff\xcd\xc3K`\xff\xff\xff\xffΠ\xd5p\xff\xff\xff\xffϣ-`\xff\xff\xff\xffЀ\xb7p\xff\xff\xff" +
+	"\xffу\x0f`\xff\xff\xff\xff\xd2`\x99p\xff\xff\xff\xff\xd3b\xf1`\xff\xff\xff\xff\xd4@{p\xff\xff\xff\xff\xd9\x1eF\xe0\xff\xff\xff\xff\xd9\xe9[\xf0\x00\x00\x00\x00\b\r\xcd\xe0\x00\x00\x00\x00\b\xf4\x92" +
+	"p\x00\x00\x00\x00\t\xed\xaf\xe0\x00\x00\x00\x00\n\xd4tp\x00\x00\x00\x00\v\xbb\x1c\xe0\x00\x00\x00\x00\f\xab\x1b\xf0\x00\x00\x00\x00\r\xa49`\x00\x00\x00\x00\x0e\x8a\xfd\xf0\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00" +
+	"\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03\xcd" +
+	"\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00" +
+	"\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'" +
+	"\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00" +
+	"\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x03\x01\x02\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" +
+	"\x05\x04\x05\x04\xff\xff\xfc\x8c\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\t\x00\x00\x1c \x01\r\x00\x00\x1c \x01\x12\x00\x00\x0e\x10\x00\x17LMT\x00WEST\x00WET\x00WEMT\x00CE" +
+	"ST\x00CET\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\xa5J[\xa0\x03\x00\x00\xa0\x03\x00" +
+	"\x00\f\x00\x00\x00Europe/MaltaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" +
+	"\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xffp\xbd\xd3d" +
+	"\xff\xff\xff\xff\x9b8\xf8p\xff\xff\xff\xff\x9b\xd5\xcc\xe0\xff\xff\xff\xff\x9c\xc5\xcb\xf0\xff\xff\xff\xff\x9d\xb7\x00`\xff\xff\xff\xff\x9e\x89\xfep\xff\xff\xff\xff\x9f\xa0\x1c\xe0\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff" +
+	"\xa1~\xad`\xff\xff\xff\xff\xa2\\7p\xff\xff\xff\xff\xa3L\x1a`\xff\xff\xff\xff\xc8l5\xf0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϐ\xe2\x90" +
+	"\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2L\xd2\xf0\xff\xff\xff\xff\xd3>1\x90\xff\xff\xff\xff\xd4I\xd2\x10\xff\xff\xff\xff\xd5\x1d\xf7p\xff\xff\xff\xff\xd6)\x97\xf0\xff\xff\xff\xff" +
+	"\xd6뀐\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xf93\xb5\xf0\xff\xff\xff\xff\xf9\xd9\xc4\xe0\xff\xff\xff\xff\xfb\x1c\xd2p\xff\xff\xff\xff\xfb\xb9\xb4\xf0\xff\xff\xff\xff\xfc\xfc\xb4p\xff\xff\xff\xff\xfd\x99\x96\xf0" +
+	"\xff\xff\xff\xff\xfe\xe5\xd0\xf0\xff\xff\xff\xff\xff\x82\xb3p\x00\x00\x00\x00\x00Ų\xf0\x00\x00\x00\x00\x01b\x95p\x00\x00\x00\x00\x02\x9cZp\x00\x00\x00\x00\x03Bwp\x00\x00\x00\x00\x04\x85v\xf0\x00\x00\x00\x00" +
+	"\x05+\x93\xf0\x00\x00\x00\x00\x06\x1a3p\x00\x00\x00\x00\a\n$p\x00\x00\x00\x00\b\x17\x16p\x00\x00\x00\x00\b\xda4p\x00\x00\x00\x00\t\xf7\x14\x90\x00\x00\x00\x00\n\xc2\r\x80\x00\x00\x00\x00\v\xd6\xf6\x90" +
+	"\x00\x00\x00\x00\f\xa1\xef\x80\x00\x00\x00\x00\r\xb6ؐ\x00\x00\x00\x00\x0e\x81р\x00\x00\x00\x00\x0f\x96\xba\x90\x00\x00\x00\x00\x10a\xb3\x80\x00\x00\x00\x00\x11v\x9c\x90\x00\x00\x00\x00\x12A\x95\x80\x00\x00\x00\x00" +
+	"\x13E[\x10\x00\x00\x00\x00\x14*\xb2\x00\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90" +
+	"\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00" +
+	"!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90" +
+	"\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00" +
+	"/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00\r\x9c\x00\x00\x00\x00\x1c \x01\x04\x00\x00" +
+	"\x0e\x10\x00\tLMT\x00CEST\x00CET\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5" +
+	"\xc8X\xa7\xe1\x01\x00\x00\xe1\x01\x00\x00\x10\x00\x00\x00Europe/MariehamnTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00#\x00\x00" +
+	"\x00\x04\x00\x00\x00\x11\xff\xff\xff\xffS\xba&\x9b\xff\xff\xff\xff\xa4so\x1b\xff\xff\xff\xff\xcb\xceQ`\xff\xff\xff\xff\xcc\xc0\xe5`\x00\x00\x00\x00\x15#݀\x00\x00\x00\x00\x16\x13\u0380\x00\x00\x00\x00\x17\x03" +
+	"\xbf\x80\x00\x00\x00\x00\x17\xf3\xb0\x80\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00" +
+	"\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c" +
+	"'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00" +
+	"\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\x17e\x00\x00\x00\x00\x17e\x00\x04\x00\x00*0\x01\b\x00\x00\x1c \x00\rLMT\x00HMT\x00EEST\x00EE" +
+	"T\x00\nEET-2EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00WI\xc3\x7f(\x03\x00\x00(\x03\x00\x00\f\x00" +
+	"\x00\x00Europe/MinskTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00" +
+	"\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00D\x00\x00\x00\t\x00\x00\x00&\xff\xff\xff\xffV\xb6\xca(\xff\xff\xff" +
+	"\xff\xaa\x19\xaa8\xff\xff\xff\xff\xb5\xa4\x19`\xff\xff\xff\xff\xca^p\xd0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xff\xd0\n\x02" +
+	"`\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00" +
+	"\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7" +
+	"\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd5\b\x80\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00" +
+	"\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4ۀ\x00\x00\x00\x00-\x94̀\x00\x00\x00\x00.\x84\xbd\x80\x00\x00\x00\x00/t\xae\x80\x00\x00\x00\x000d\x9f\x80\x00\x00\x00\x001]\xcb\x00\x00\x00\x00\x002r\xa6" +
+	"\x00\x00\x00\x00\x003=\xad\x00\x00\x00\x00\x004R\x88\x00\x00\x00\x00\x005\x1d\x8f\x00\x00\x00\x00\x0062j\x00\x00\x00\x00\x006\xfdq\x00\x00\x00\x00\x008\x1b\x86\x80\x00\x00\x00\x008\xddS\x00\x00\x00\x00" +
+	"\x009\xfbh\x80\x00\x00\x00\x00:\xbd5\x00\x00\x00\x00\x00;\xdbJ\x80\x00\x00\x00\x00<\xa6Q\x80\x00\x00\x00\x00=\xbb,\x80\x00\x00\x00\x00>\x863\x80\x00\x00\x00\x00?\x9b\x0e\x80\x00\x00\x00\x00@f\x15" +
+	"\x80\x00\x00\x00\x00A\x84+\x00\x00\x00\x00\x00BE\xf7\x80\x00\x00\x00\x00Cd\r\x00\x00\x00\x00\x00D%ـ\x00\x00\x00\x00EC\xef\x00\x00\x00\x00\x00F\x05\xbb\x80\x00\x00\x00\x00G#\xd1\x00\x00\x00\x00" +
+	"\x00G\xee\xd8\x00\x00\x00\x00\x00I\x03\xb3\x00\x00\x00\x00\x00Iκ\x00\x00\x00\x00\x00J\xe3\x95\x00\x00\x00\x00\x00K\xae\x9c\x00\x00\x00\x00\x00Ḻ\x80\x00\x00\x00\x00M\x8e~\x00\x01\x02\x03\x05\x04\x05\x04" +
+	"\x05\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02" +
+	"\b\x00\x00\x19\xd8\x00\x00\x00\x00\x19\xc8\x00\x04\x00\x00\x1c \x00\b\x00\x00*0\x00\f\x00\x00\x0e\x10\x00\x10\x00\x00\x1c \x01\x14\x00\x008@\x01\x19\x00\x00*0\x01\x1d\x00\x00*0\x00\"LMT\x00M" +
+	"MT\x00EET\x00MSK\x00CET\x00CEST\x00MSD\x00EEST\x00+03\x00\n<+03>-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7\xf5\x94\xda" +
+	"Q\x04\x00\x00Q\x04\x00\x00\r\x00\x00\x00Europe/MonacoTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00e\x00\x00\x00\a\x00\x00\x00\x1f" +
+	"\xff\xff\xff\xffkɛ\xcf\xff\xff\xff\xff\x91`PO\xff\xff\xff\xff\x9bGx\xf0\xff\xff\xff\xff\x9b\xd7,p\xff\xff\xff\xff\x9c\xbc\x91p\xff\xff\xff\xff\x9d\xc0H\xf0\xff\xff\xff\xff\x9e\x89\xfep\xff\xff\xff\xff" +
+	"\x9f\xa0*\xf0\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1\x80\f\xf0\xff\xff\xff\xff\xa2.\x12\xf0\xff\xff\xff\xff\xa3zL\xf0\xff\xff\xff\xff\xa45\x81\xf0\xff\xff\xff\xff\xa5^#p\xff\xff\xff\xff\xa6%5\xf0" +
+	"\xff\xff\xff\xff\xa7'\x9b\xf0\xff\xff\xff\xff\xa8X&p\xff\xff\xff\xff\xa9\a}\xf0\xff\xff\xff\xff\xa9\xee4p\xff\xff\xff\xff\xaa\xe7_\xf0\xff\xff\xff\xff\xab\xd7P\xf0\xff\xff\xff\xff\xac\xc7A\xf0\xff\xff\xff\xff" +
+	"\xadɧ\xf0\xff\xff\xff\xff\xae\xa7#\xf0\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x05\xf0\xff\xff\xff\xff\xb1\x89k\xf0\xff\xff\xff\xff\xb2p\"p\xff\xff\xff\xff\xb3r\x88p\xff\xff\xff\xff\xb4P\x04p" +
+	"\xff\xff\xff\xff\xb5I/\xf0\xff\xff\xff\xff\xb6/\xe6p\xff\xff\xff\xff\xb72Lp\xff\xff\xff\xff\xb8\x0f\xc8p\xff\xff\xff\xff\xb8\xff\xb9p\xff\xff\xff\xff\xb9\xef\xaap\xff\xff\xff\xff\xba\xd6`\xf0\xff\xff\xff\xff" +
+	"\xbb\xd8\xc6\xf0\xff\xff\xff\xff\xbcȷ\xf0\xff\xff\xff\xff\xbd\xb8\xa8\xf0\xff\xff\xff\xff\xbe\x9f_p\xff\xff\xff\xff\xbf\x98\x8a\xf0\xff\xff\xff\xff\xc0\x9a\xf0\xf0\xff\xff\xff\xff\xc1xl\xf0\xff\xff\xff\xff\xc2h]\xf0" +
+	"\xff\xff\xff\xff\xc3XN\xf0\xff\xff\xff\xff\xc4?\x05p\xff\xff\xff\xff\xc580\xf0\xff\xff\xff\xff\xc6:\x96\xf0\xff\xff\xff\xff\xc7X\xacp\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xc8l'\xe0\xff\xff\xff\xff" +
+	"\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xff\xd0O\xe1\xe0\xff\xff\xff\xffЉ\xf1\xf0\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2N@\x90" +
+	"\x00\x00\x00\x00\v\xbb9\x00\x00\x00\x00\x00\f\xab\x1b\xf0\x00\x00\x00\x00\r\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00" +
+	"\x12T\x18\x90\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐" +
+	"\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00" +
+	" lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90" +
+	"\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00" +
+	".\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x06\x02\x06\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" +
+	"\x05\x04\x05\x04\x05\x04\x05\x04\x05\x00\x00\x021\x00\x00\x00\x00\x021\x00\x04\x00\x00\x0e\x10\x01\b\x00\x00\x00\x00\x00\r\x00\x00\x0e\x10\x00\x11\x00\x00\x1c \x01\x15\x00\x00\x1c \x01\x1aLMT\x00PMT\x00W" +
+	"EST\x00WET\x00CET\x00CEST\x00WEMT\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\xe1\xc1\xeb\x05\x8c\x03\x00\x00\x8c\x03\x00\x00\r\x00\x00\x00Europe/MoscowTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00N" +
+	"\x00\x00\x00\v\x00\x00\x00&\xff\xff\xff\xffV\xb6\xc0\xc7\xff\xff\xff\xff\x9b_\x1e\xc7\xff\xff\xff\xff\x9d>\xf2y\xff\xff\xff\xff\x9e*\xee\xf9\xff\xff\xff\xff\x9e\xf79i\xff\xff\xff\xff\x9f\x84W\xf9\xff\xff\xff\xff" +
+	"\xa0\xd8l\xe9\xff\xff\xff\xff\xa1\x009\x80\xff\xff\xff\xff\xa1<\xa6@\xff\xff\xff\xff\xa4\x10m\xc0\xff\xff\xff\xff\xa4=2\xb0\xff\xff\xff\xff\xa5\x15h\xb0\xff\xff\xff\xff\xa5=\x03\xc0\xff\xff\xff\xff\xa7\x1eEP" +
+	"\xff\xff\xff\xff\xb5\xa4\x19`\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00" +
+	"\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0" +
+	"\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00" +
+	"(\xe5\x17\x80\x00\x00\x00\x00)x\xbf\x80\x00\x00\x00\x00)\xd4\xfap\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x94\xbep\x00\x00\x00\x00.\x84\xafp" +
+	"\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x00" +
+	"62[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb<p\x00\x00\x00\x00<\xa6Cp" +
+	"\x00\x00\x00\x00=\xbb\x1ep\x00\x00\x00\x00>\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f\ap\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00" +
+	"D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05\xadp\x00\x00\x00\x00G#\xc2\xf0\x00\x00\x00\x00G\xee\xc9\xf0\x00\x00\x00\x00I\x03\xa4\xf0\x00\x00\x00\x00IΫ\xf0\x00\x00\x00\x00J\xe3\x86\xf0" +
+	"\x00\x00\x00\x00K\xae\x8d\xf0\x00\x00\x00\x00Ḷp\x00\x00\x00\x00M\x8eo\xf0\x00\x00\x00\x00TL\x1d`\x01\x03\x02\x03\x04\x02\x04\x05\x06\x05\a\x05\x06\b\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" +
+	"\x06\x05\x06\x05\x06\x05\x06\t\b\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\n\x06\x00\x00#9\x00\x00\x00\x00#9" +
+	"\x00\x04\x00\x001\x87\x01\b\x00\x00#w\x00\x04\x00\x00?\x97\x01\f\x00\x008@\x01\x11\x00\x00*0\x00\x15\x00\x00FP\x01\x19\x00\x00\x1c \x00\x1d\x00\x00*0\x01!\x00\x008@\x00\x15LMT\x00" +
+	"MMT\x00MST\x00MDST\x00MSD\x00MSK\x00+05\x00EET\x00EEST\x00\nMSK-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03R\xda\xedU" +
+	"\x02\x00\x00U\x02\x00\x00\x0e\x00\x00\x00Europe/NicosiaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x001\x00\x00\x00\x03\x00\x00\x00\r" +
+	"\xff\xff\xff\xff\xa5w\x1e\xb8\x00\x00\x00\x00\t\xed\xaf\xe0\x00\x00\x00\x00\nݒ\xd0\x00\x00\x00\x00\v\xfad\xe0\x00\x00\x00\x00\f\xbe\xc6P\x00\x00\x00\x00\r\xa49`\x00\x00\x00\x00\x0e\x8a\xe1\xd0\x00\x00\x00\x00" +
+	"\x0f\x84\x1b`\x00\x00\x00\x00\x10uO\xd0\x00\x00\x00\x00\x11c\xfd`\x00\x00\x00\x00\x12S\xe0P\x00\x00\x00\x00\x13M\x19\xe0\x00\x00\x00\x00\x143\xc2P\x00\x00\x00\x00\x15#\xc1`\x00\x00\x00\x00\x16\x13\xa4P" +
+	"\x00\x00\x00\x00\x17\x03\xa3`\x00\x00\x00\x00\x17\xf3\x86P\x00\x00\x00\x00\x18\xe3\x85`\x00\x00\x00\x00\x19\xd3hP\x00\x00\x00\x00\x1a\xc3g`\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00" +
+	"\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$,\v\xe0" +
+	"\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf5\n`\x00\x00\x00\x00(\xe4\xedP\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00" +
+	"+\xb4\xce`\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000duP\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002M\x91\xd0" +
+	"\x00\x00\x00\x003=\x90\xe0\x00\x00\x00\x004-s\xd0\x00\x00\x00\x005\x1dr\xe0\x00\x00\x00\x0062x\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x1fH\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\tLMT\x00EEST\x00EET\x00\nEET-2EE" +
+	"ST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17S\x91\xb3\xc1\x02\x00\x00\xc1\x02\x00\x00\v\x00\x00\x00Europe/O" +
+	"sloTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xffo\xa2a\xf8\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5" +
+	"\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xc8\tq\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff" +
+	"\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xffѶ\x96\x00\xff\xff\xff\xff\xd2X\xbe\x80\xff\xff\xff\xffҡO\x10\xff\xff\xff\xff\xd3c" +
+	"\x1b\x90\xff\xff\xff\xff\xd4K#\x90\xff\xff\xff\xff\xd59\xd1 \xff\xff\xff\xff\xd5g\xe7\x90\xff\xff\xff\xffըs\x00\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff" +
+	"\xff\xff\xd9\x02\xc1\x90\xff\xff\xff\xff\xd9\xe9x\x10\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3" +
+	"\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00" +
+	"\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f" +
+	"\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00" +
+	"\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x03\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00\f\x88\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00*0" +
+	"\x01\rLMT\x00CEST\x00CET\x00CEMT\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\xc7\xf5\x94\xdaQ\x04\x00\x00Q\x04\x00\x00\f\x00\x00\x00Europe/ParisTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00e\x00\x00\x00" +
+	"\a\x00\x00\x00\x1f\xff\xff\xff\xffkɛ\xcf\xff\xff\xff\xff\x91`PO\xff\xff\xff\xff\x9bGx\xf0\xff\xff\xff\xff\x9b\xd7,p\xff\xff\xff\xff\x9c\xbc\x91p\xff\xff\xff\xff\x9d\xc0H\xf0\xff\xff\xff\xff\x9e\x89\xfe" +
+	"p\xff\xff\xff\xff\x9f\xa0*\xf0\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1\x80\f\xf0\xff\xff\xff\xff\xa2.\x12\xf0\xff\xff\xff\xff\xa3zL\xf0\xff\xff\xff\xff\xa45\x81\xf0\xff\xff\xff\xff\xa5^#p\xff\xff\xff" +
+	"\xff\xa6%5\xf0\xff\xff\xff\xff\xa7'\x9b\xf0\xff\xff\xff\xff\xa8X&p\xff\xff\xff\xff\xa9\a}\xf0\xff\xff\xff\xff\xa9\xee4p\xff\xff\xff\xff\xaa\xe7_\xf0\xff\xff\xff\xff\xab\xd7P\xf0\xff\xff\xff\xff\xac\xc7A" +
+	"\xf0\xff\xff\xff\xff\xadɧ\xf0\xff\xff\xff\xff\xae\xa7#\xf0\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x05\xf0\xff\xff\xff\xff\xb1\x89k\xf0\xff\xff\xff\xff\xb2p\"p\xff\xff\xff\xff\xb3r\x88p\xff\xff\xff" +
+	"\xff\xb4P\x04p\xff\xff\xff\xff\xb5I/\xf0\xff\xff\xff\xff\xb6/\xe6p\xff\xff\xff\xff\xb72Lp\xff\xff\xff\xff\xb8\x0f\xc8p\xff\xff\xff\xff\xb8\xff\xb9p\xff\xff\xff\xff\xb9\xef\xaap\xff\xff\xff\xff\xba\xd6`" +
+	"\xf0\xff\xff\xff\xff\xbb\xd8\xc6\xf0\xff\xff\xff\xff\xbcȷ\xf0\xff\xff\xff\xff\xbd\xb8\xa8\xf0\xff\xff\xff\xff\xbe\x9f_p\xff\xff\xff\xff\xbf\x98\x8a\xf0\xff\xff\xff\xff\xc0\x9a\xf0\xf0\xff\xff\xff\xff\xc1xl\xf0\xff\xff\xff" +
+	"\xff\xc2h]\xf0\xff\xff\xff\xff\xc3XN\xf0\xff\xff\xff\xff\xc4?\x05p\xff\xff\xff\xff\xc580\xf0\xff\xff\xff\xff\xc6:\x96\xf0\xff\xff\xff\xff\xc7X\xacp\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xc8l'" +
+	"\xe0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xff\xd0O\xe1\xe0\xff\xff\xff\xffЉ\xf1\xf0\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff" +
+	"\xff\xd2N@\x90\x00\x00\x00\x00\v\xbb9\x00\x00\x00\x00\x00\f\xab\x1b\xf0\x00\x00\x00\x00\r\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'" +
+	"\x90\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00" +
+	"\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81" +
+	"\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00" +
+	"\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda" +
+	"\x90\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x06\x02\x06\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" +
+	"\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x00\x00\x021\x00\x00\x00\x00\x021\x00\x04\x00\x00\x0e\x10\x01\b\x00\x00\x00\x00\x00\r\x00\x00\x0e\x10\x00\x11\x00\x00\x1c \x01\x15\x00\x00\x1c \x01\x1aLMT\x00" +
+	"PMT\x00WEST\x00WET\x00CET\x00CEST\x00WEMT\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\x10\x00\x00\x00Europe/PodgoricaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00$\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xff^<\xf0H\xff\xff\xff\xff\xca\x025\xe0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xff" +
+	"ϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xffѡ\x8c\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10" +
+	"\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00" +
+	"#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90" +
+	"\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x00" +
+	"1]\xd9\x10\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x138\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\bLM" +
+	"T\x00CET\x00CEST\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Io\x11{\xd3\x02\x00" +
+	"\x00\xd3\x02\x00\x00\r\x00\x00\x00Europe/PragueTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff" +
+	"\xff\x1eI\x92\xf8\xff\xff\xff\xffl\xcf\xea\xf8\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97" +
+	"\x90\xff\xff\xff\xff\xc8\tq\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff" +
+	"\xff\xd2b\a\x10\xff\xff\xff\xffӀ\x1c\x90\xff\xff\xff\xff\xd4I\xd2\x10\xff\xff\xff\xffԓ\xb4 \xff\xff\xff\xff\xd5\x02r \xff\xff\xff\xff\xd5L8\x10\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a" +
+	"\x10\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xd9\x01p\x10\xff\xff\xff\xff\xd9\xe9x\x10\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00" +
+	"\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd" +
+	"\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00" +
+	"\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16" +
+	"\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00" +
+	"\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x00\x00\r\x88\x00\x00\x00\x00\r\x88\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\r\x00\x00\x00\x00\x01\x11LMT\x00PMT\x00CEST\x00CET\x00GMT\x00\nCE" +
+	"T-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00gp\xc0\xa7\xb6\x02\x00\x00\xb6\x02\x00\x00\v\x00\x00\x00Europ" +
+	"e/RigaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZi" +
+	"f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005\x00\x00\x00\t\x00\x00\x00&\xff\xff\xff\xffV\xb6\xcd^\xff\xff\xff\xff\x9e\xb9\x87\xfe\xff\xff\xff" +
+	"\xff\x9f\x84\x8e\xfe\xff\xff\xff\xff\xa0\x88F~\xff\xff\xff\xff\xa0˂\xfe\xff\xff\xff\xff\xad\xe7\xf1\xde\xff\xff\xff\xffȯd`\xff\xff\xff\xff\xcabeP\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17" +
+	"\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xffА\x89p\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00" +
+	"\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs" +
+	"\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\x19\x00\x00\x00\x00" +
+	"\x00&\f\n\x00\x00\x00\x00\x00'\x055\x80\x00\x00\x00\x00'\xf5&\x80\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd5\b\x80\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4\xdb" +
+	"\x80\x00\x00\x00\x00-\x94̀\x00\x00\x00\x00.\x84\xbd\x80\x00\x00\x00\x00/t\xae\x80\x00\x00\x00\x000d\x9f\x80\x00\x00\x00\x001]\xcb\x00\x00\x00\x00\x002M\xbc\x00\x00\x00\x00\x003=\xbb\x10\x00\x00\x00" +
+	"\x004R\x96\x10\x00\x00\x00\x005\x1d\x9d\x10\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd\x7f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x00:\xbdC\x10\x01\x02\x01\x02\x01\x03\x04\x06\x05\x06\x05\x06\x05\x04\a" +
+	"\x04\a\x04\a\x04\a\x04\a\x04\a\x04\a\x04\a\x04\b\x03\b\x03\b\x03\b\x03\b\x03\b\x03\b\x03\b\x03\b\x03\b\x03\b\x03\b\x00\x00\x16\xa2\x00\x00\x00\x00\x16\xa2\x00\x04\x00\x00$\xb2\x01\b\x00\x00\x1c " +
+	"\x00\f\x00\x00*0\x00\x10\x00\x00\x0e\x10\x00\x14\x00\x00\x1c \x01\x18\x00\x008@\x01\x1d\x00\x00*0\x01!LMT\x00RMT\x00LST\x00EET\x00MSK\x00CET\x00CEST" +
+	"\x00MSD\x00EEST\x00\nEET-2EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\xb4\x9e\xe7\xb3\x03" +
+	"\x00\x00\xb3\x03\x00\x00\v\x00\x00\x00Europe/RomeTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00W\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff" +
+	">(\xe8L\xff\xff\xff\xffp\xbc\x81p\xff\xff\xff\xff\x9b8\xf8p\xff\xff\xff\xff\x9b\xd5\xcc\xe0\xff\xff\xff\xff\x9c\xc5\xcb\xf0\xff\xff\xff\xff\x9d\xb7\x00`\xff\xff\xff\xff\x9e\x89\xfep\xff\xff\xff\xff\x9f\xa0\x1c\xe0" +
+	"\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1~\xad`\xff\xff\xff\xff\xa2\\7p\xff\xff\xff\xff\xa3L\x1a`\xff\xff\xff\xff\xc8l5\xf0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff" +
+	"\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2L\xd2\xf0\xff\xff\xff\xff\xd3>1\x90\xff\xff\xff\xff\xd4I\xd2\x10\xff\xff\xff\xff\xd5\x1d\xf7p" +
+	"\xff\xff\xff\xff\xd6)\x97\xf0\xff\xff\xff\xff\xd6뀐\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xf93\xb5\xf0\xff\xff\xff\xff\xf9\xd9\xc4\xe0\xff\xff\xff\xff\xfb\x1c\xd2p\xff\xff\xff\xff\xfb\xb9\xb4\xf0\xff\xff\xff\xff" +
+	"\xfc\xfc\xb4p\xff\xff\xff\xff\xfd\x99\x96\xf0\xff\xff\xff\xff\xfe\xe5\xd0\xf0\xff\xff\xff\xff\xff\x82\xb3p\x00\x00\x00\x00\x00Ų\xf0\x00\x00\x00\x00\x01b\x95p\x00\x00\x00\x00\x02\x9cZp\x00\x00\x00\x00\x03Bwp" +
+	"\x00\x00\x00\x00\x04\x85v\xf0\x00\x00\x00\x00\x05+\x93\xf0\x00\x00\x00\x00\x06n\x93p\x00\x00\x00\x00\a\vu\xf0\x00\x00\x00\x00\bE:\xf0\x00\x00\x00\x00\b\xebW\xf0\x00\x00\x00\x00\n.Wp\x00\x00\x00\x00" +
+	"\n\xcb9\xf0\x00\x00\x00\x00\f\x0e9p\x00\x00\x00\x00\f\xab\x1b\xf0\x00\x00\x00\x00\r\xe4\xe0\xf0\x00\x00\x00\x00\x0e\x8a\xfd\xf0\x00\x00\x00\x00\x0f\xcd\xfdp\x00\x00\x00\x00\x10t\x1ap\x00\x00\x00\x00\x11\xad\xdfp" +
+	"\x00\x00\x00\x00\x12S\xfcp\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00" +
+	"\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10" +
+	"\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00" +
+	"'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ" +
+	"\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00" +
+	"\x00\v\xb4\x00\x00\x00\x00\v\xb4\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\rLMT\x00RMT\x00CEST\x00CET\x00\nCET-1CEST,M3.5.0,M1" +
+	"0.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\x7fpp\xdc\x02\x00\x00\xdc\x02\x00\x00\r\x00\x00\x00Europe/SamaraTZif2\x00\x00\x00\x00" +
 	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00T\x00\x00\x00\n\x00\x00\x00(\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}\x87AH\xff\xff\xff\xffˉ6\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff" +
-	"\xff\xff\xd2aB0\xff\xff\xff\xff\xfa\xd2G\xa0\xff\xff\xff\xff\xfe\xb8c@\xff\xff\xff\xff\xff\xa8F0\x00\x00\x00\x00\x00\x98E@\x00\x00\x00\x00\x01\x88(0\x00\x00\x00\x00\x02x'@\x00\x00\x00\x00\x03q" +
-	"D\xb0\x00\x00\x00\x00\x04aC\xc0\x00\x00\x00\x00\x05Q&\xb0\x00\x00\x00\x00\x06A%\xc0\x00\x00\x00\x00\a1\b\xb0\x00\x00\x00\x00\a\x8d_\xc0\x00\x00\x00\x00\t\x10\xea\xb0\x00\x00\x00\x00\t\xad\xdb@\x00\x00" +
-	"\x00\x00\n\xf0̰\x00\x00\x00\x00\v\xe0\xcb\xc0\x00\x00\x00\x00\f\xd9\xe90\x00\x00\x00\x00\r\xc0\xad\xc0\x00\x00\x00\x00\x0e\xb9\xcb0\x00\x00\x00\x00\x0f\xa9\xca@\x00\x00\x00\x00\x10\x99\xad0\x00\x00\x00\x00\x11\x89" +
-	"\xac@\x00\x00\x00\x00\x12y\x8f0\x00\x00\x00\x00\x13i\x8e@\x00\x00\x00\x00\x14Yq0\x00\x00\x00\x00\x15Ip@\x00\x00\x00\x00\x169S0\x00\x00\x00\x00\x17)R@\x00\x00\x00\x00\x18\"o\xb0\x00\x00" +
-	"\x00\x00\x19\t4@\x00\x00\x00\x00\x1a\x02Q\xb0\x00\x00\x00\x00\x1a+\x14\x10\x00\x00\x00\x00\x1a\xf2B\xb0\x00\x00\x00\x00\x1b\xe2%\xa0\x00\x00\x00\x00\x1c\xd2$\xb0\x00\x00\x00\x00\x1d\xc2\a\xa0\x00\x00\x00\x00\x1e\xb2" +
-	"\x06\xb0\x00\x00\x00\x00\x1f\xa1\xe9\xa0\x00\x00\x00\x00 v90\x00\x00\x00\x00!\x81ˠ\x00\x00\x00\x00\"V\x1b0\x00\x00\x00\x00#j\xe8 \x00\x00\x00\x00$5\xfd0\x00\x00\x00\x00%J\xca \x00\x00" +
-	"\x00\x00&\x15\xdf0\x00\x00\x00\x00'*\xac \x00\x00\x00\x00'\xfe\xfb\xb0\x00\x00\x00\x00)\n\x8e \x00\x00\x00\x00)\xdeݰ\x00\x00\x00\x00*\xeap \x00\x00\x00\x00+\xbe\xbf\xb0\x00\x00\x00\x00,\xd3" +
-	"\x8c\xa0\x00\x00\x00\x00-\x9e\xa1\xb0\x00\x00\x00\x00.\xb3n\xa0\x00\x00\x00\x00/~\x83\xb0\x00\x00\x00\x000\x93P\xa0\x00\x00\x00\x001g\xa00\x00\x00\x00\x002s2\xa0\x00\x00\x00\x003G\x820\x00\x00" +
-	"\x00\x004S\x14\xa0\x00\x00\x00\x005'd0\x00\x00\x00\x0062\xf6\xa0\x00\x00\x00\x007\aF0\x00\x00\x00\x008\x1c\x13 \x00\x00\x00\x008\xe7(0\x00\x00\x00\x009\xfb\xf5 \x00\x00\x00\x00:\xc7" +
-	"\n0\x00\x00\x00\x00;\xdb\xd7 \x00\x00\x00\x00<\xb0&\xb0\x00\x00\x00\x00=\xbb\xb9 \x00\x00\x00\x00>\x90\b\xb0\x00\x00\x00\x00?\x9b\x9b \x00\x00\x00\x00@o\xea\xb0\x00\x00\x00\x00A\x84\xb7\xa0\x00\x00" +
-	"\x00\x00BO̰\x00\x00\x00\x00Cd\x99\xa0\x00\x00\x00\x00D/\xae\xb0\x00\x00\x00\x00ED{\xa0\x00\x00\x00\x00E\xf3\xe10\x01\x02\x03\x04\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" +
-	"\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\a\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b" +
-	"\t\b\x00\x00\xc4\xf8\x00\x00\xff\xffsx\x00\x00\xff\xffs`\x00\x04\xff\xff\x81p\x01\b\xff\xff\x81p\x01\f\xff\xffs`\x00\x10\xff\xff\x81p\x01\x15\xff\xff\x81p\x00\x1a\xff\xff\x8f\x80\x01\x1e\xff\xff\x81p" +
-	"\x00#LMT\x00AST\x00AWT\x00APT\x00AHST\x00AHDT\x00YST\x00AKDT\x00AKST\x00\nAKST9AKDT,M3.2.0," +
-	"M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xf6\"\x12\xfe\x0e\x05\x00\x00\x0e\x05\x00\x00\n\x00\x1c\x00US/PacificUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94" +
-	"bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01" +
-	"\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00}\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff^\x04\x1a\xc0\xff" +
-	"\xff\xff\xff\x9e\xa6H\xa0\xff\xff\xff\xff\x9f\xbb\x15\x90\xff\xff\xff\xff\xa0\x86*\xa0\xff\xff\xff\xff\xa1\x9a\xf7\x90\xff\xff\xff\xffˉ\x1a\xa0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a&\x10\xff\xff\xff\xff\xd6" +
-	"\xfet\\\xff\xff\xff\xff\u0600\xad\x90\xff\xff\xff\xff\xda\xfeÐ\xff\xff\xff\xff\xdb\xc0\x90\x10\xff\xff\xff\xff\xdcޥ\x90\xff\xff\xff\xffݩ\xac\x90\xff\xff\xff\xff\u07be\x87\x90\xff\xff\xff\xff߉\x8e\x90\xff" +
-	"\xff\xff\xff\xe0\x9ei\x90\xff\xff\xff\xff\xe1ip\x90\xff\xff\xff\xff\xe2~K\x90\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4^-\x90\xff\xff\xff\xff\xe5)4\x90\xff\xff\xff\xff\xe6GJ\x10\xff\xff\xff\xff\xe7" +
-	"\x12Q\x10\xff\xff\xff\xff\xe8',\x10\xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff\xff\xea\a\x0e\x10\xff\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff\xff\xeb\xe6\xf0\x10\xff\xff\xff\xff\xec\xb1\xf7\x10\xff\xff\xff\xff\xed\xc6\xd2\x10\xff" +
-	"\xff\xff\xff\xee\x91\xd9\x10\xff\xff\xff\xff\xef\xaf\xee\x90\xff\xff\xff\xff\xf0q\xbb\x10\xff\xff\xff\xff\xf1\x8fА\xff\xff\xff\xff\xf2\x7f\xc1\x90\xff\xff\xff\xff\xf3o\xb2\x90\xff\xff\xff\xff\xf4_\xa3\x90\xff\xff\xff\xff\xf5" +
-	"O\x94\x90\xff\xff\xff\xff\xf6?\x85\x90\xff\xff\xff\xff\xf7/v\x90\xff\xff\xff\xff\xf8(\xa2\x10\xff\xff\xff\xff\xf9\x0fX\x90\xff\xff\xff\xff\xfa\b\x84\x10\xff\xff\xff\xff\xfa\xf8\x83 \xff\xff\xff\xff\xfb\xe8f\x10\xff" +
-	"\xff\xff\xff\xfc\xd8e \xff\xff\xff\xff\xfd\xc8H\x10\xff\xff\xff\xff\xfe\xb8G \xff\xff\xff\xff\xff\xa8*\x10\x00\x00\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88\f\x10\x00\x00\x00\x00\x02x\v \x00\x00\x00\x00\x03" +
-	"q(\x90\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05Q\n\x90\x00\x00\x00\x00\x06A\t\xa0\x00\x00\x00\x00\a0\xec\x90\x00\x00\x00\x00\a\x8dC\xa0\x00\x00\x00\x00\t\x10ΐ\x00\x00\x00\x00\t\xad\xbf \x00" +
-	"\x00\x00\x00\n\xf0\xb0\x90\x00\x00\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11" +
-	"\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00" +
-	"\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f" +
-	"\xa1ې\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\"V\r \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00" +
-	"\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\n\x80\x10\x00\x00\x00\x00)\xdeϠ\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-" +
-	"\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00" +
-	"\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\a8 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;" +
-	"\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00" +
-	"\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E\xf3\xd3 \x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\x91&\x00\x00\xff\xff\x9d\x90\x01\x04\xff\xff\x8f\x80\x00\b\xff\xff\x9d\x90\x01\f" +
-	"\xff\xff\x9d\x90\x01\x10LMT\x00PDT\x00PST\x00PWT\x00PPT\x00\nPST8PDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00" +
-	"\x8fj\xbeT3\x9aG\xc8\xd0\x06\x00\x00\xd0\x06\x00\x00\n\x00\x1c\x00US/EasternUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZ" +
-	"if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaf\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff^\x03\xf0\x90\xff\xff\xff\xff\x9e\xa6\x1ep\xff\xff\xff\xff\x9f\xba\xeb`\xff\xff\xff" +
-	"\xff\xa0\x86\x00p\xff\xff\xff\xff\xa1\x9a\xcd`\xff\xff\xff\xff\xa2e\xe2p\xff\xff\xff\xff\xa3\x83\xe9\xe0\xff\xff\xff\xff\xa4j\xaep\xff\xff\xff\xff\xa55\xa7`\xff\xff\xff\xff\xa6S\xca\xf0\xff\xff\xff\xff\xa7\x15\x89" +
-	"`\xff\xff\xff\xff\xa83\xac\xf0\xff\xff\xff\xff\xa8\xfe\xa5\xe0\xff\xff\xff\xff\xaa\x13\x8e\xf0\xff\xff\xff\xff\xaaއ\xe0\xff\xff\xff\xff\xab\xf3p\xf0\xff\xff\xff\xff\xac\xbei\xe0\xff\xff\xff\xff\xad\xd3R\xf0\xff\xff\xff" +
-	"\xff\xae\x9eK\xe0\xff\xff\xff\xff\xaf\xb34\xf0\xff\xff\xff\xff\xb0~-\xe0\xff\xff\xff\xff\xb1\x9cQp\xff\xff\xff\xff\xb2gJ`\xff\xff\xff\xff\xb3|3p\xff\xff\xff\xff\xb4G,`\xff\xff\xff\xff\xb5\\\x15" +
-	"p\xff\xff\xff\xff\xb6'\x0e`\xff\xff\xff\xff\xb7;\xf7p\xff\xff\xff\xff\xb8\x06\xf0`\xff\xff\xff\xff\xb9\x1b\xd9p\xff\xff\xff\xff\xb9\xe6\xd2`\xff\xff\xff\xff\xbb\x04\xf5\xf0\xff\xff\xff\xff\xbbƴ`\xff\xff\xff" +
-	"\xff\xbc\xe4\xd7\xf0\xff\xff\xff\xff\xbd\xaf\xd0\xe0\xff\xff\xff\xff\xbeĹ\xf0\xff\xff\xff\xff\xbf\x8f\xb2\xe0\xff\xff\xff\xff\xc0\xa4\x9b\xf0\xff\xff\xff\xff\xc1o\x94\xe0\xff\xff\xff\xff\u0084}\xf0\xff\xff\xff\xff\xc3Ov" +
-	"\xe0\xff\xff\xff\xff\xc4d_\xf0\xff\xff\xff\xff\xc5/X\xe0\xff\xff\xff\xff\xc6M|p\xff\xff\xff\xff\xc7\x0f:\xe0\xff\xff\xff\xff\xc8-^p\xff\xff\xff\xff\xc8\xf8W`\xff\xff\xff\xff\xca\r@p\xff\xff\xff" +
-	"\xff\xca\xd89`\xff\xff\xff\xffˈ\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff\xd3u\xe4\xf0\xff\xff\xff\xff\xd4@\xdd\xe0\xff\xff\xff\xff\xd5U\xc6\xf0\xff\xff\xff\xff\xd6 \xbf" +
-	"\xe0\xff\xff\xff\xff\xd75\xa8\xf0\xff\xff\xff\xff\xd8\x00\xa1\xe0\xff\xff\xff\xff\xd9\x15\x8a\xf0\xff\xff\xff\xff\xd9\xe0\x83\xe0\xff\xff\xff\xff\xda\xfe\xa7p\xff\xff\xff\xff\xdb\xc0e\xe0\xff\xff\xff\xff\xdcމp\xff\xff\xff" +
-	"\xffݩ\x82`\xff\xff\xff\xff\u07bekp\xff\xff\xff\xff߉d`\xff\xff\xff\xff\xe0\x9eMp\xff\xff\xff\xff\xe1iF`\xff\xff\xff\xff\xe2~/p\xff\xff\xff\xff\xe3I(`\xff\xff\xff\xff\xe4^\x11" +
-	"p\xff\xff\xff\xff\xe5W.\xe0\xff\xff\xff\xff\xe6G-\xf0\xff\xff\xff\xff\xe77\x10\xe0\xff\xff\xff\xff\xe8'\x0f\xf0\xff\xff\xff\xff\xe9\x16\xf2\xe0\xff\xff\xff\xff\xea\x06\xf1\xf0\xff\xff\xff\xff\xea\xf6\xd4\xe0\xff\xff\xff" +
-	"\xff\xeb\xe6\xd3\xf0\xff\xff\xff\xff\xecֶ\xe0\xff\xff\xff\xff\xedƵ\xf0\xff\xff\xff\xff\xee\xbf\xd3`\xff\xff\xff\xff\xef\xaf\xd2p\xff\xff\xff\xff\xf0\x9f\xb5`\xff\xff\xff\xff\xf1\x8f\xb4p\xff\xff\xff\xff\xf2\x7f\x97" +
-	"`\xff\xff\xff\xff\xf3o\x96p\xff\xff\xff\xff\xf4_y`\xff\xff\xff\xff\xf5Oxp\xff\xff\xff\xff\xf6?[`\xff\xff\xff\xff\xf7/Zp\xff\xff\xff\xff\xf8(w\xe0\xff\xff\xff\xff\xf9\x0f<p\xff\xff\xff" +
-	"\xff\xfa\bY\xe0\xff\xff\xff\xff\xfa\xf8X\xf0\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe" +
-	"\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\a0\xc2`\x00\x00\x00" +
-	"\x00\a\x8d\x19p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\t\xad\x94\xf0\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00\f٢\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00\x00\x00\x0e\xb9\x84" +
-	"\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00" +
-	"\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x00\x00\x00\x00\x1a\xf2\np\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xec" +
-	"p\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\"U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00" +
-	"\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\nU\xe0\x00\x00\x00\x00)ޥp\x00\x00\x00\x00*\xea7" +
-	"\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00" +
-	"\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\a\r\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef" +
-	"\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00" +
-	"\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xba\x9e\x00\x00\xff\xff\xc7\xc0\x01\x04" +
-	"\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\f\xff\xff\xc7\xc0\x01\x10LMT\x00EDT\x00EST\x00EWT\x00EPT\x00\nEST5EDT,M3.2.0,M11.1." +
-	"0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT>\x14\xe7\x03\x83\x03\x00\x00\x83\x03\x00\x00\v\x00\x1c\x00US/MichiganUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00" +
-	"\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00" +
-	"\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff\x85\xbd\"[\xff\xff\xff\xff\x99<" +
-	"\x94\x00\xff\xff\xff\xffˈ\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff\xd75\xa8\xf0\xff\xff\xff\xff\xd8\x00\xa1\xe0\xff\xff\xff\xff\xfb3\x90\x8c\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff" +
-	"\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\a0\xc2`\x00\x00\x00\x00\a\x8d\x19p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\n\x00\xa3p\x00\x00\x00\x00\n\xf0" +
-	"\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00\f٢\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00" +
-	"\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b" +
-	"\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x00\x00\x00\x00\x1a\xf2\np\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00" +
-	"\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\"U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*" +
-	"s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\nU\xe0\x00\x00\x00\x00)ޥp\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00" +
-	"\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'" +
-	"+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\a\r\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00" +
-	"\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cd" +
-	"a`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x01\x02\x03\x04\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05" +
-	"\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\xff\xff\xb2%\x00\x00\xff\xff\xab\xa0\x00\x04\xff\xff" +
-	"\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\f\xff\xff\xc7\xc0\x01\x10\xff\xff\xc7\xc0\x01\x14LMT\x00CST\x00EST\x00EWT\x00EPT\x00EDT\x00\nEST5EDT,M3.2." +
-	"0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTø\xab\x9b\xf0\x00\x00\x00\xf0\x00\x00\x00\n\x00\x1c\x00US/ArizonaUT\t\x00\x03\xdd\xfc\x94b\xdd" +
-	"\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00" +
-	"\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff^\x04\f" +
-	"\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xcf\x17\xdf\x1c\xff\xff\xff\xffϏ\xe5\xac\xff\xff\xff" +
-	"\xffЁ\x1a\x1c\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\x02\x01\x02\x01\x02\x03\x02\x03\x02\x01\x02\xff\xff\x96\xee\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\fLMT\x00" +
-	"MDT\x00MST\x00MWT\x00\nMST7\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT$ \x873\xf8\x03\x00\x00\xf8\x03\x00\x00\x11\x00\x1c\x00US/Indiana-S" +
-	"tarkeUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]" +
-	"\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff" +
-	"\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0" +
-	"\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90p\xff\xff\xff\xff\u07bey\x80\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff" +
-	"\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5W<\xf0\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe77\x1e\xf0\xff\xff\xff\xff\xe8'\x1e\x00" +
-	"\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xd6\xc4\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\xee\xbf\xe1p\xff\xff\xff\xff" +
-	"\xef\xaf\xe0\x80\xff\xff\xff\xff\xf0\x9f\xc3p\xff\xff\xff\xff\xf1\x8f\u0080\xff\xff\xff\xff\xf4_\x87p\xff\xff\xff\xff\xfa\xf8g\x00\xff\xff\xff\xff\xfb\xe8I\xf0\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8+\xf0" +
-	"\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\r\xf0\x00\x00\x00\x00\x00\x98\r\x00\x00\x00\x00\x00\x01\x87\xef\xf0\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\fp\x00\x00\x00\x00\x04a\v\x80\x00\x00\x00\x00" +
-	"\x05P\xeep\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\a0\xd0p\x00\x00\x00\x00\a\x8d'\x80\x00\x00\x00\x00\t\x10\xb2p\x00\x00\x00\x00\t\xad\xa3\x00\x00\x00\x00\x00\n\xf0\x94p\x00\x00\x00\x00\v\xe0\x93\x80" +
-	"\x00\x00\x00\x00\fٰ\xf0\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99t\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00" +
-	"\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\"7p\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p" +
-	"\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1܀\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00" +
-	"!\x81\xa1p\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfeр" +
-	"\x00\x00\x00\x00)\nc\xf0\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x05\x01\x02\x01\xff\xff\xae\xca\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14LMT\x00CDT\x00CST\x00CWT\x00CPT" +
-	"\x00EST\x00\nCST6CDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\xae,\xa44\xc9\x03\x00\x00\xc9\x03\x00\x00\v\x00\x1c\x00U" +
-	"S/AleutianUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00T\x00\x00\x00\n\x00\x00\x00!\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}\x87Z^\xff\xff\xff\xffˉD\xd0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2aP@\xff\xff\xff\xff\xfa\xd2U" +
-	"\xb0\xff\xff\xff\xff\xfe\xb8qP\xff\xff\xff\xff\xff\xa8T@\x00\x00\x00\x00\x00\x98SP\x00\x00\x00\x00\x01\x886@\x00\x00\x00\x00\x02x5P\x00\x00\x00\x00\x03qR\xc0\x00\x00\x00\x00\x04aQ\xd0\x00\x00\x00" +
-	"\x00\x05Q4\xc0\x00\x00\x00\x00\x06A3\xd0\x00\x00\x00\x00\a1\x16\xc0\x00\x00\x00\x00\a\x8dm\xd0\x00\x00\x00\x00\t\x10\xf8\xc0\x00\x00\x00\x00\t\xad\xe9P\x00\x00\x00\x00\n\xf0\xda\xc0\x00\x00\x00\x00\v\xe0\xd9" +
-	"\xd0\x00\x00\x00\x00\f\xd9\xf7@\x00\x00\x00\x00\r\xc0\xbb\xd0\x00\x00\x00\x00\x0e\xb9\xd9@\x00\x00\x00\x00\x0f\xa9\xd8P\x00\x00\x00\x00\x10\x99\xbb@\x00\x00\x00\x00\x11\x89\xbaP\x00\x00\x00\x00\x12y\x9d@\x00\x00\x00" +
-	"\x00\x13i\x9cP\x00\x00\x00\x00\x14Y\x7f@\x00\x00\x00\x00\x15I~P\x00\x00\x00\x00\x169a@\x00\x00\x00\x00\x17)`P\x00\x00\x00\x00\x18\"}\xc0\x00\x00\x00\x00\x19\tBP\x00\x00\x00\x00\x1a\x02_" +
-	"\xc0\x00\x00\x00\x00\x1a+\" \x00\x00\x00\x00\x1a\xf2P\xc0\x00\x00\x00\x00\x1b\xe23\xb0\x00\x00\x00\x00\x1c\xd22\xc0\x00\x00\x00\x00\x1d\xc2\x15\xb0\x00\x00\x00\x00\x1e\xb2\x14\xc0\x00\x00\x00\x00\x1f\xa1\xf7\xb0\x00\x00\x00" +
-	"\x00 vG@\x00\x00\x00\x00!\x81ٰ\x00\x00\x00\x00\"V)@\x00\x00\x00\x00#j\xf60\x00\x00\x00\x00$6\v@\x00\x00\x00\x00%J\xd80\x00\x00\x00\x00&\x15\xed@\x00\x00\x00\x00'*\xba" +
-	"0\x00\x00\x00\x00'\xff\t\xc0\x00\x00\x00\x00)\n\x9c0\x00\x00\x00\x00)\xde\xeb\xc0\x00\x00\x00\x00*\xea~0\x00\x00\x00\x00+\xbe\xcd\xc0\x00\x00\x00\x00,Ӛ\xb0\x00\x00\x00\x00-\x9e\xaf\xc0\x00\x00\x00" +
-	"\x00.\xb3|\xb0\x00\x00\x00\x00/~\x91\xc0\x00\x00\x00\x000\x93^\xb0\x00\x00\x00\x001g\xae@\x00\x00\x00\x002s@\xb0\x00\x00\x00\x003G\x90@\x00\x00\x00\x004S\"\xb0\x00\x00\x00\x005'r" +
-	"@\x00\x00\x00\x0063\x04\xb0\x00\x00\x00\x007\aT@\x00\x00\x00\x008\x1c!0\x00\x00\x00\x008\xe76@\x00\x00\x00\x009\xfc\x030\x00\x00\x00\x00:\xc7\x18@\x00\x00\x00\x00;\xdb\xe50\x00\x00\x00" +
-	"\x00<\xb04\xc0\x00\x00\x00\x00=\xbb\xc70\x00\x00\x00\x00>\x90\x16\xc0\x00\x00\x00\x00?\x9b\xa90\x00\x00\x00\x00@o\xf8\xc0\x00\x00\x00\x00A\x84Ű\x00\x00\x00\x00BO\xda\xc0\x00\x00\x00\x00Cd\xa7" +
-	"\xb0\x00\x00\x00\x00D/\xbc\xc0\x00\x00\x00\x00ED\x89\xb0\x00\x00\x00\x00E\xf3\xef@\x01\x02\x03\x04\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" +
-	"\a\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\x00\x00\xab\xe2\x00\x00\xff\xffZb\x00" +
-	"\x00\xff\xffeP\x00\x04\xff\xffs`\x01\b\xff\xffs`\x01\f\xff\xffeP\x00\x10\xff\xffs`\x01\x14\xff\xffs`\x00\x18\xff\xff\x81p\x01\x1d\xff\xffs`\x00\x19LMT\x00NST\x00NWT" +
-	"\x00NPT\x00BST\x00BDT\x00AHST\x00HDT\x00\nHST10HDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbe" +
-	"T\xeaK\x85v\xdd\x00\x00\x00\xdd\x00\x00\x00\t\x00\x1c\x00US/HawaiiUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xfft\xe0p\xbe\xff\xff\xff\xff\xbb\x05CH\xff\xff\xff\xff\xbb!qX\xff\xff\xff\xffˉ=" +
-	"\xc8\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2aI8\xff\xff\xff\xffՍsH\x01\x02\x01\x03\x04\x01\x05\xff\xffl\x02\x00\x00\xff\xfflX\x00\x04\xff\xffzh\x01\b\xff\xffzh\x01\f\xff\xffzh" +
-	"\x01\x10\xff\xffs`\x00\x04LMT\x00HST\x00HDT\x00HWT\x00HPT\x00\nHST10\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTp\xb6{\xc9\x13\x02\x00\x00\x13\x02\x00" +
-	"\x00\x0f\x00\x1c\x00US/East-IndianaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&\x00\x00\x00\a\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1" +
-	"\x9a\xdbp\xff\xff\xff\xff\xcaW\"\x80\xff\xff\xff\xff\xca\xd8Gp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd3u\xf3\x00\xff\xff\xff\xff\xd4@\xeb\xf0\xff" +
-	"\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb" +
-	"\xc0s\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90p\xff\xff\xff\xff\u07bey\x80\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff" +
-	"\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01" +
-	"\x87\xe1\xe0\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x02\x05\x06\x05" +
-	"\x06\x05\x06\x05\x06\xff\xff\xaf:\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18LMT\x00CDT\x00CST\x00C" +
-	"WT\x00CPT\x00EST\x00EDT\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9bܩ=\xda\x06\x00" +
-	"\x00\xda\x06\x00\x00\n\x00\x1c\x00US/CentralUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaf\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a" +
-	"\xdbp\xff\xff\xff\xff\xa2\xcbt\x00\xff\xff\xff\xff\xa3\x83\xf7\xf0\xff\xff\xff\xff\xa4EҀ\xff\xff\xff\xff\xa5c\xd9\xf0\xff\xff\xff\xff\xa6S\xd9\x00\xff\xff\xff\xff\xa7\x15\x97p\xff\xff\xff\xff\xa83\xbb\x00\xff\xff" +
-	"\xff\xff\xa8\xfe\xb3\xf0\xff\xff\xff\xff\xaa\x13\x9d\x00\xff\xff\xff\xff\xaaޕ\xf0\xff\xff\xff\xff\xab\xf3\x7f\x00\xff\xff\xff\xff\xac\xbew\xf0\xff\xff\xff\xff\xad\xd3a\x00\xff\xff\xff\xff\xae\x9eY\xf0\xff\xff\xff\xff\xaf\xb3" +
-	"C\x00\xff\xff\xff\xff\xb0~;\xf0\xff\xff\xff\xff\xb1\x9c_\x80\xff\xff\xff\xff\xb2gXp\xff\xff\xff\xff\xb3|A\x80\xff\xff\xff\xff\xb4G:p\xff\xff\xff\xff\xb5\\#\x80\xff\xff\xff\xff\xb6'\x1cp\xff\xff" +
-	"\xff\xff\xb7<\x05\x80\xff\xff\xff\xff\xb8\x06\xfep\xff\xff\xff\xff\xb9\x1b\xe7\x80\xff\xff\xff\xff\xb9\xe6\xe0p\xff\xff\xff\xff\xbb\x05\x04\x00\xff\xff\xff\xff\xbb\xc6\xc2p\xff\xff\xff\xff\xbc\xe4\xe6\x00\xff\xff\xff\xff\xbd\xaf" +
-	"\xde\xf0\xff\xff\xff\xff\xbe\xc4\xc8\x00\xff\xff\xff\xff\xbf\x8f\xc0\xf0\xff\xff\xff\xff\xc0Z\xd6\x00\xff\xff\xff\xff\xc1\xb0<p\xff\xff\xff\xff\u0084\x8c\x00\xff\xff\xff\xff\xc3O\x84\xf0\xff\xff\xff\xff\xc4dn\x00\xff\xff" +
-	"\xff\xff\xc5/f\xf0\xff\xff\xff\xff\xc6M\x8a\x80\xff\xff\xff\xff\xc7\x0fH\xf0\xff\xff\xff\xff\xc8-l\x80\xff\xff\xff\xff\xc8\xf8ep\xff\xff\xff\xff\xca\rN\x80\xff\xff\xff\xff\xca\xd8Gp\xff\xff\xff\xffˈ" +
-	"\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd3u\xf3\x00\xff\xff\xff\xff\xd4@\xeb\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff" +
-	"\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90p\xff\xff\xff\xff\u07be" +
-	"y\x80\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5W<\xf0\xff\xff" +
-	"\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe77\x1e\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe9\x17\x00\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea\xf6\xe2\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xd6" +
-	"\xc4\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\xee\xbf\xe1p\xff\xff\xff\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xf0\x9f\xc3p\xff\xff\xff\xff\xf1\x8f\u0080\xff\xff\xff\xff\xf2\x7f\xa5p\xff\xff\xff\xff\xf3o\xa4\x80\xff\xff" +
-	"\xff\xff\xf4_\x87p\xff\xff\xff\xff\xf5O\x86\x80\xff\xff\xff\xff\xf6?ip\xff\xff\xff\xff\xf7/h\x80\xff\xff\xff\xff\xf8(\x85\xf0\xff\xff\xff\xff\xf9\x0fJ\x80\xff\xff\xff\xff\xfa\bg\xf0\xff\xff\xff\xff\xfa\xf8" +
-	"g\x00\xff\xff\xff\xff\xfb\xe8I\xf0\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8+\xf0\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\r\xf0\x00\x00\x00\x00\x00\x98\r\x00\x00\x00\x00\x00\x01\x87\xef\xf0\x00\x00" +
-	"\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\fp\x00\x00\x00\x00\x04a\v\x80\x00\x00\x00\x00\x05P\xeep\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\a0\xd0p\x00\x00\x00\x00\a\x8d'\x80\x00\x00\x00\x00\t\x10" +
-	"\xb2p\x00\x00\x00\x00\t\xad\xa3\x00\x00\x00\x00\x00\n\xf0\x94p\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00\x00\x00\fٰ\xf0\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00" +
-	"\x00\x00\x10\x99t\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)" +
-	"\x1a\x00\x00\x00\x00\x00\x18\"7p\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00" +
-	"\x00\x00\x1e\xb1܀\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J" +
-	"\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)\nc\xf0\x00\x00\x00\x00)\u07b3\x80\x00\x00\x00\x00*\xeaE\xf0\x00\x00\x00\x00+\xbe\x95\x80\x00\x00" +
-	"\x00\x00,\xd3bp\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3Dp\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x93&p\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003G" +
-	"X\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00" +
-	"\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00;۬\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84" +
-	"\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x04\x05\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
-	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xad\xd4\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x00" +
-	"\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x01\x14LMT\x00CDT\x00CST\x00EST\x00CWT\x00CPT\x00\nCST6CDT,M3.2.0,M11.1.0" +
-	"\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTV\x80\x94@\x12\x04\x00\x00\x12\x04\x00\x00\v\x00\x1c\x00US/MountainUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01" +
-	"\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00" +
-	"\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff^\x04\f\xb0\xff\xff\xff\xff\x9e\xa6:" +
-	"\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff\xff\xff\xa2e\xfe\x90\xff\xff\xff\xff\xa3\x84\x06\x00\xff\xff\xff\xff\xa4E\xe0\x90\xff\xff\xff\xff\xa4\x8f\xa6\x80\xff\xff\xff" +
-	"\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xf7/v\x90\xff\xff\xff\xff\xf8(\x94\x00\xff\xff\xff\xff\xf9\x0fX\x90\xff\xff\xff\xff\xfa\bv\x00\xff\xff\xff\xff\xfa\xf8u" +
-	"\x10\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W\x10\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb89\x10\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x1b\x10\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00" +
-	"\x00\x02w\xfd\x10\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\a\x8d5\x90\x00\x00\x00\x00\t\x10\xc0" +
-	"\x80\x00\x00\x00\x00\t\xad\xb1\x10\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\vࡐ\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00" +
-	"\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(" +
-	"\x10\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00" +
-	"\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae" +
-	"\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeߐ\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00" +
-	"\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf" +
-	"\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00" +
-	"\x00:\xc6\xee\x10\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b" +
-	"\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
-	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\x9d\x94\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10LMT\x00MDT\x00MST\x00" +
-	"MWT\x00MPT\x00\nMST7MDT,M3.2.0,M11.1.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeTt\xca{e\x92\x00\x00\x00\x92\x00\x00\x00\b\x00" +
-	"\x1c\x00US/SamoaUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\b\xff\xff\xff\xffn=\xc8\b\xff\xff\xff\xff\x91\x05\xfb\b\x01\x02\x00\x00\xb1x\x00\x00\xff\xff_\xf8\x00\x00\xff\xffeP\x00\x04LMT\x00SST\x00\nSS" +
-	"T11\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\x03\x00\x1c\x00UTCUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00" +
-	"\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif" +
-	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00\nUTC0\nPK\x03\x04" +
-	"\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\t\x00\x1c\x00UniversalUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S" +
-	"_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00\nUTC0\nPK\x03\x04\n\x00" +
-	"\x00\x00\x00\x00\x8fj\xbeT\xe1\xc1\xeb\x05\x8c\x03\x00\x00\x8c\x03\x00\x00\x04\x00\x1c\x00W-SUUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xa1\x009\x80\xff\xff\xff\xff\xb5\xa4\vP\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00" +
+	"\x00\x00\x17\b\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a̅\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9c" +
+	"t\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\8\xe0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<\x1a\xe0\x00\x00\x00\x00$,\v\xe0\x00\x00" +
+	"\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\x00\xc7\x00\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4" +
+	"\xdd`\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xbf`\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\xa1`\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000d\x83`\x00\x00\x00\x001]\xae\xe0\x00\x00" +
+	"\x00\x002r\x89\xe0\x00\x00\x00\x003=\x90\xe0\x00\x00\x00\x004Rk\xe0\x00\x00\x00\x005\x1dr\xe0\x00\x00\x00\x0062M\xe0\x00\x00\x00\x006\xfdT\xe0\x00\x00\x00\x008\x1bj`\x00\x00\x00\x008\xdd" +
+	"6\xe0\x00\x00\x00\x009\xfbL`\x00\x00\x00\x00:\xbd\x18\xe0\x00\x00\x00\x00;\xdb.`\x00\x00\x00\x00<\xa65`\x00\x00\x00\x00=\xbb\x10`\x00\x00\x00\x00>\x86\x17`\x00\x00\x00\x00?\x9a\xf2`\x00\x00" +
+	"\x00\x00@e\xf9`\x00\x00\x00\x00A\x84\x0e\xe0\x00\x00\x00\x00BE\xdb`\x00\x00\x00\x00Cc\xf0\xe0\x00\x00\x00\x00D%\xbd`\x00\x00\x00\x00EC\xd2\xe0\x00\x00\x00\x00F\x05\x9f`\x00\x00\x00\x00G#" +
+	"\xb4\xe0\x00\x00\x00\x00G\xee\xbb\xe0\x00\x00\x00\x00I\x03\x96\xe0\x00\x00\x00\x00IΝ\xe0\x00\x00\x00\x00J\xe3x\xe0\x00\x00\x00\x00K\xae\x7f\xe0\x00\x00\x00\x00Ḷp\x00\x00\x00\x00M\x8eo\xf0\x01\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x01\x04\x01\x05\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04" +
+	"\x01\x02\x00\x00.\xf4\x00\x00\x00\x00*0\x00\x04\x00\x008@\x00\b\x00\x00FP\x01\f\x00\x008@\x01\b\x00\x00*0\x01\x04LMT\x00+03\x00+04\x00+05\x00\n<+04>" +
+	"-4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\xb4\x9e\xe7\xb3\x03\x00\x00\xb3\x03\x00\x00\x11\x00\x00\x00Europe/San_MarinoTZif2\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00W\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff>(\xe8L\xff\xff\xff\xffp\xbc\x81p\xff\xff\xff\xff\x9b8\xf8p\xff\xff\xff\xff\x9b\xd5\xcc\xe0\xff\xff\xff" +
+	"\xff\x9c\xc5\xcb\xf0\xff\xff\xff\xff\x9d\xb7\x00`\xff\xff\xff\xff\x9e\x89\xfep\xff\xff\xff\xff\x9f\xa0\x1c\xe0\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1~\xad`\xff\xff\xff\xff\xa2\\7p\xff\xff\xff\xff\xa3L\x1a" +
+	"`\xff\xff\xff\xff\xc8l5\xf0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff" +
+	"\xff\xd2L\xd2\xf0\xff\xff\xff\xff\xd3>1\x90\xff\xff\xff\xff\xd4I\xd2\x10\xff\xff\xff\xff\xd5\x1d\xf7p\xff\xff\xff\xff\xd6)\x97\xf0\xff\xff\xff\xff\xd6뀐\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xf93\xb5" +
+	"\xf0\xff\xff\xff\xff\xf9\xd9\xc4\xe0\xff\xff\xff\xff\xfb\x1c\xd2p\xff\xff\xff\xff\xfb\xb9\xb4\xf0\xff\xff\xff\xff\xfc\xfc\xb4p\xff\xff\xff\xff\xfd\x99\x96\xf0\xff\xff\xff\xff\xfe\xe5\xd0\xf0\xff\xff\xff\xff\xff\x82\xb3p\x00\x00\x00" +
+	"\x00\x00Ų\xf0\x00\x00\x00\x00\x01b\x95p\x00\x00\x00\x00\x02\x9cZp\x00\x00\x00\x00\x03Bwp\x00\x00\x00\x00\x04\x85v\xf0\x00\x00\x00\x00\x05+\x93\xf0\x00\x00\x00\x00\x06n\x93p\x00\x00\x00\x00\a\vu" +
+	"\xf0\x00\x00\x00\x00\bE:\xf0\x00\x00\x00\x00\b\xebW\xf0\x00\x00\x00\x00\n.Wp\x00\x00\x00\x00\n\xcb9\xf0\x00\x00\x00\x00\f\x0e9p\x00\x00\x00\x00\f\xab\x1b\xf0\x00\x00\x00\x00\r\xe4\xe0\xf0\x00\x00\x00" +
+	"\x00\x0e\x8a\xfd\xf0\x00\x00\x00\x00\x0f\xcd\xfdp\x00\x00\x00\x00\x10t\x1ap\x00\x00\x00\x00\x11\xad\xdfp\x00\x00\x00\x00\x12S\xfcp\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb" +
+	"\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00" +
+	"\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E" +
+	"\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00" +
+	"\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9" +
+	"\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\v\xb4\x00\x00\x00\x00\v\xb4\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\rLMT\x00RMT\x00" +
+	"CEST\x00CET\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1C\xf9\xa1\xde\x01\x00\x00\xde" +
+	"\x01\x00\x00\x0f\x00\x00\x00Europe/SarajevoTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff" +
+	"\xff^<\xf0H\xff\xff\xff\xff\xca\x025\xe0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xffѡ\x8c" +
+	"\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00" +
+	"\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'" +
+	"\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00" +
+	"\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x138\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\bLMT\x00CET\x00CEST\x00\nCET-1CE" +
+	"ST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b8\xfel\xd6\x02\x00\x00\xd6\x02\x00\x00\x0e\x00\x00\x00Europe/Sar" +
+	"atovTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xa1\x009\x80\xff\xff\xff\xff\xb5\xa4\vP\x00\x00\x00\x00\x15" +
+	"'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\b\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a̅\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00" +
+	"\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\8\xe0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#" +
+	"<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xebp\x00" +
+	"\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x94\xbep\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002" +
+	"r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00" +
+	"\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb<p\x00\x00\x00\x00<\xa6Cp\x00\x00\x00\x00=\xbb\x1ep\x00\x00\x00\x00>\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@" +
+	"f\ap\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05\xadp\x00\x00\x00\x00G#\xc2\xf0\x00" +
+	"\x00\x00\x00G\xee\xc9\xf0\x00\x00\x00\x00I\x03\xa4\xf0\x00\x00\x00\x00IΫ\xf0\x00\x00\x00\x00J\xe3\x86\xf0\x00\x00\x00\x00K\xae\x8d\xf0\x00\x00\x00\x00Ḷp\x00\x00\x00\x00M\x8eo\xf0\x00\x00\x00\x00T" +
+	"L\x1d`\x00\x00\x00\x00XCNp\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x04\x01\x04\x01\x03\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01" +
+	"\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x03\x01\x03\x00\x00+2\x00\x00\x00\x00*0\x00\x04\x00\x00FP\x01\b\x00\x008@\x00\f\x00\x008@\x01\fLMT\x00+03\x00+05\x00+04" +
+	"\x00\n<+04>-4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00}\xb4N\xb8a\x03\x00\x00a\x03\x00\x00\x11\x00\x00\x00Europe/SimferopolTZi" +
+	"f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00K\x00\x00\x00\t\x00\x00\x00\"\xff\xff\xff\xffV\xb6\xc4\b\xff\xff\xff\xff\xaa\x19\xa4 \xff\xff\xff\xff\xb5\xa4\x19`\xff\xff\xff\xff" +
+	"\xcb\x04\x8d\xd0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffϟ8\xe0\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@" +
+	"\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00" +
+	"\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0" +
+	"\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\x8d.\xf0\x00\x00\x00\x00)\xd5\b\x80\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4ۀ\x00\x00\x00\x00-\x94̀\x00\x00\x00\x00" +
+	"-\xc2\xc6\xd0\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xa0\xd0\x00\x00\x00\x002r\xa6\x00\x00\x00\x00\x003=\xbb\x10\x00\x00\x00\x004R\x96\x10" +
+	"\x00\x00\x00\x005\x1d\x9d\x10\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd\x7f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x008\xdda\x10\x00\x00\x00\x009\xfbv\x90\x00\x00\x00\x00:\xbdC\x10\x00\x00\x00\x00" +
+	";\xdbX\x90\x00\x00\x00\x00<\xa6_\x90\x00\x00\x00\x00=\xbb:\x90\x00\x00\x00\x00>\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90" +
+	"\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00" +
+	"I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90" +
+	"\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7^\x80\x00\x00\x00\x00TL\x1d`\x01\x02\x03\x05\x04\x05\x04\x05\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x02" +
+	"\a\x02\a\x02\a\x06\x03\x06\x03\x06\x03\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\b\x03\x00\x00\x1f\xf8\x00\x00\x00\x00\x1f\xe0\x00\x04\x00" +
+	"\x00\x1c \x00\b\x00\x00*0\x00\f\x00\x00\x0e\x10\x00\x10\x00\x00\x1c \x01\x14\x00\x008@\x01\x19\x00\x00*0\x01\x1d\x00\x008@\x00\fLMT\x00SMT\x00EET\x00MSK\x00CET" +
+	"\x00CEST\x00MSD\x00EEST\x00\nMSK-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\r\x00\x00\x00Europe/S" +
+	"kopjeTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif" +
+	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xff^<\xf0H\xff\xff\xff\xff\xca\x025\xe0\xff\xff\xff\xff" +
+	"\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xffѡ\x8c\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\x18㯐" +
+	"\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00" +
+	" lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90" +
+	"\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00" +
+	".\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x00\x00\x138\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\bLMT\x00CET\x00CEST\x00\nCET-1CEST,M3.5.0,M10.5.0" +
+	"/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c\xc8\x15\xd0P\x02\x00\x00P\x02\x00\x00\f\x00\x00\x00Europe/SofiaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-\x00\x00\x00\x06\x00\x00\x00\x1a\xff\xff\xff\xffV\xb6\xce$\xff\xff\xff\xffr\xc3\xe3\x18\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10" +
+	"\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r$ \x00\x00\x00\x00\x11c\xefP\x00\x00\x00\x00\x12U?\xe0\x00\x00\x00\x00\x13M\v\xd0\x00\x00\x00\x00\x145!\xe0\x00\x00\x00\x00" +
+	"\x15,\xed\xd0\x00\x00\x00\x00\x16\x13\xc0p\x00\x00\x00\x00\x17\f\xcf\xd0\x00\x00\x00\x00\x17\xf3\xb0\x80\x00\x00\x00\x00\x18㡀\x00\x00\x00\x00\x19Ӓ\x80\x00\x00\x00\x00\x1aÃ\x80\x00\x00\x00\x00\x1b\xbc\xaf\x00" +
+	"\x00\x00\x00\x00\x1c\xac\xa0\x00\x00\x00\x00\x00\x1d\x9c\x91\x00\x00\x00\x00\x00\x1e\x8c\x82\x00\x00\x00\x00\x00\x1f|s\x00\x00\x00\x00\x00 ld\x00\x00\x00\x00\x00!\\U\x00\x00\x00\x00\x00\"LF\x00\x00\x00\x00\x00" +
+	"#<7\x00\x00\x00\x00\x00$,(\x00\x00\x00\x00\x00%\x1c\x19\x00\x00\x00\x00\x00&\f\n\x00\x00\x00\x00\x00'\x055\x80\x00\x00\x00\x00'\xf5\n`\x00\x00\x00\x00(\xe4\xedP\x00\x00\x00\x00)\xd4\xec`" +
+	"\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000duP\x00\x00\x00\x00" +
+	"1]\xae\xe0\x00\x00\x00\x002r{\xd0\x00\x00\x00\x003=\xbb\x10\x01\x02\x03\x04\x03\x04\x03\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02" +
+	"\x05\x02\x05\x02\x05\x00\x00\x15\xdc\x00\x00\x00\x00\x1bh\x00\x04\x00\x00\x1c \x00\b\x00\x00\x0e\x10\x00\f\x00\x00\x1c \x01\x10\x00\x00*0\x01\x15LMT\x00IMT\x00EET\x00CET\x00CES" +
+	"T\x00EEST\x00\nEET-2EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17S\x91\xb3\xc1\x02\x00\x00\xc1" +
+	"\x02\x00\x00\x10\x00\x00\x00Europe/StockholmTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff" +
+	"\xff\xffo\xa2a\xf8\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xc8\t" +
+	"q\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xffѶ\x96\x00\xff\xff" +
+	"\xff\xff\xd2X\xbe\x80\xff\xff\xff\xffҡO\x10\xff\xff\xff\xff\xd3c\x1b\x90\xff\xff\xff\xff\xd4K#\x90\xff\xff\xff\xff\xd59\xd1 \xff\xff\xff\xff\xd5g\xe7\x90\xff\xff\xff\xffըs\x00\xff\xff\xff\xff\xd6)" +
+	"\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xd9\x02\xc1\x90\xff\xff\xff\xff\xd9\xe9x\x10\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00" +
+	"\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac" +
+	"\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00" +
+	"\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5" +
+	"\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00" +
+	"\f\x88\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00*0\x01\rLMT\x00CEST\x00CET\x00CEMT\x00\nCET-1CEST,M3.5.0,M1" +
+	"0.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\x16\x9b?\xa3\x02\x00\x00\xa3\x02\x00\x00\x0e\x00\x00\x00Europe/TallinnTZif2\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x004\x00\x00\x00\b\x00\x00\x00\"\xff\xff\xff\xffV\xb6\xcc\xcc\xff\xff\xff\xff\x9eY-\xcc\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff" +
+	"\xff\xff\xff\xa1\x00+p\xff\xff\xff\xff\xa4soL\xff\xff\xff\xffȰ\xb5\xe0\xff\xff\xff\xff\xcaƗP\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xff\xcf" +
+	"\x924\x10\xff\xff\xff\xff\xd0t\xcb\xe0\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00" +
+	"\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!" +
+	"\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\x19\x00\x00\x00\x00\x00&\f\n\x00\x00\x00\x00\x00'\x055\x80\x00\x00\x00\x00'\xf5&\x80\x00" +
+	"\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd5\b\x80\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4ۀ\x00\x00\x00\x00-\x94̀\x00\x00\x00\x00.\x84\xbd\x80\x00\x00\x00\x00/" +
+	"t\xae\x80\x00\x00\x00\x000d\x9f\x80\x00\x00\x00\x001]\xcb\x00\x00\x00\x00\x002r\xa6\x00\x00\x00\x00\x003=\xad\x00\x00\x00\x00\x004R\x88\x00\x00\x00\x00\x005\x1d\x8f\x00\x00\x00\x00\x0062x\x10\x00" +
+	"\x00\x00\x006\xfd\x7f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x00<\xa6_\x90\x01\x03\x02\x03\x01\x04\x05\x02\x03\x02\x03\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\a\x04\a\x04\a\x04\a\x04" +
+	"\a\x04\a\x04\a\x04\a\x04\a\x04\a\x04\a\x04\a\x00\x00\x174\x00\x00\x00\x00\x174\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\r\x00\x00\x1c \x00\x11\x00\x00*0\x00\x15\x00\x008@\x01\x19\x00\x00*" +
+	"0\x01\x1dLMT\x00TMT\x00CEST\x00CET\x00EET\x00MSK\x00MSD\x00EEST\x00\nEET-2EEST,M3.5.0/3,M10" +
+	".5.0/4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xea\xc48\xde\\\x02\x00\x00\\\x02\x00\x00\r\x00\x00\x00Europe/TiraneTZif2\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x002\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xff\x96\xaa4h\xff\xff\xff\xff\xc8m\x87p\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff" +
+	"\xff\u0378\xe9\x90\x00\x00\x00\x00\b(9\xf0\x00\x00\x00\x00\b\xef>`\x00\x00\x00\x00\n\x05x\xf0\x00\x00\x00\x00\n\xd0q\xe0\x00\x00\x00\x00\v\xe9Op\x00\x00\x00\x00\f\xb4H`\x00\x00\x00\x00\r\xd2k" +
+	"\xf0\x00\x00\x00\x00\x0e\x94*`\x00\x00\x00\x00\x0f\xb0\xfcp\x00\x00\x00\x00\x10t\f`\x00\x00\x00\x00\x11\x90\xdep\x00\x00\x00\x00\x12S\xee`\x00\x00\x00\x00\x13p\xc0p\x00\x00\x00\x00\x14;\xb9`\x00\x00\x00" +
+	"\x00\x15H\xb9p\x00\x00\x00\x00\x16\x13\xb2`\x00\x00\x00\x00\x171\xd5\xf0\x00\x00\x00\x00\x17\xfc\xce\xe0\x00\x00\x00\x00\x19\x00\x94p\x00\x00\x00\x00\x19\xdb_`\x00\x00\x00\x00\x1a̯\xf0\x00\x00\x00\x00\x1b\xbc\xbd" +
+	"\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00" +
+	"\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16" +
+	"\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00" +
+	"\x001]\xd9\x10\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x12\x98\x00" +
+	"\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\bLMT\x00CET\x00CEST\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00I\xb8\xbc\xd3\xf3\x02\x00\x00\xf3\x02\x00\x00\x0f\x00\x00\x00Europe/TiraspolTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00<\x00\x00\x00\t\x00\x00\x00&\xff\xff\xff\xffV\xb6\xc8\xf8\xff\xff\xff\xff\x9ek\x9f\f\xff\xff\xff\xff\xb7\xb0\xd2\b\xff\xff\xff\xff\xb9>\xf3`\xff\xff\xff\xff\xb9\xef\x9c`\xff\xff\xff\xff\xba\xdf" +
+	"\x8d`\xff\xff\xff\xff\xbb\xcf~`\xff\xff\xff\xff\xbcȩ\xe0\xff\xff\xff\xff\xbd\xb8\x9a\xe0\xff\xff\xff\xff\xbe\xa8\x8b\xe0\xff\xff\xff\xff\xbf\x98|\xe0\xff\xff\xff\xff\xc0\x88m\xe0\xff\xff\xff\xff\xc1x^\xe0\xff\xff" +
+	"\xff\xff\xc2hO\xe0\xff\xff\xff\xff\xc3X@\xe0\xff\xff\xff\xff\xc4H1\xe0\xff\xff\xff\xff\xc58\"\xe0\xff\xff\xff\xff\xc6(\x13\xe0\xff\xff\xff\xff\xc7\x18\x04\xe0\xff\xff\xff\xffȼ\x93`\xff\xff\xff\xff\xcaw" +
+	"}P\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xff\xd0N\x90`\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00" +
+	"\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c" +
+	"\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00" +
+	"\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00&CL\xe0\x00\x00\x00\x00'\x055\x80\x00\x00\x00\x00'\xf5&\x80\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4" +
+	"\xcfP\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000duP\x00\x00\x00\x001]\xae\xe0\x00\x00" +
+	"\x00\x002r{\xd0\x00\x00\x00\x003=\xad\x00\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x06\x05\x06\x05\x06\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\x03" +
+	"\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x1b\b\x00\x00\x00\x00\x1a\xf4\x00\x04\x00\x00\x18x\x00\b\x00\x00*0\x01\f\x00\x00\x1c \x00\x11\x00\x00\x0e\x10\x00\x15\x00\x00\x1c \x01\x19\x00\x008@" +
+	"\x01\x1e\x00\x00*0\x00\"LMT\x00CMT\x00BMT\x00EEST\x00EET\x00CET\x00CEST\x00MSD\x00MSK\x00\nEET-2EEST,M3." +
+	"5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00u\xb0\xcd\xfc\xf8\x02\x00\x00\xf8\x02\x00\x00\x10\x00\x00\x00Europe/Ulyanovsk" +
+	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x00\x00\x00\a\x00\x00\x00\x14\xff\xff\xff\xff\xa1\x009\x80\xff\xff\xff\xff\xb5\xa4\vP\x00\x00\x00\x00\x15'\x99\xc0\x00" +
+	"\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\b\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a̅\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c" +
+	"\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\8\xe0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<\x1a\xe0\x00" +
+	"\x00\x00\x00$,\v\xe0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)x\xbf\x80\x00\x00\x00\x00)" +
+	"\xd4\xfap\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x94\xbep\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00" +
+	"\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008" +
+	"\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb<p\x00\x00\x00\x00<\xa6Cp\x00\x00\x00\x00=\xbb\x1ep\x00\x00\x00\x00>\x86%p\x00" +
+	"\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f\ap\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F" +
+	"\x05\xadp\x00\x00\x00\x00G#\xc2\xf0\x00\x00\x00\x00G\xee\xc9\xf0\x00\x00\x00\x00I\x03\xa4\xf0\x00\x00\x00\x00IΫ\xf0\x00\x00\x00\x00J\xe3\x86\xf0\x00\x00\x00\x00K\xae\x8d\xf0\x00\x00\x00\x00Ḷp\x00" +
+	"\x00\x00\x00M\x8eo\xf0\x00\x00\x00\x00TL\x1d`\x00\x00\x00\x00V\xf7\x14p\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x04\x01\x05\x06\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01" +
+	"\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x03\x01\x03\x00\x00-`\x00\x00\x00\x00*0\x00\x04\x00\x00FP\x01\b\x00\x008@\x00\f\x00\x008@\x01\f\x00" +
+	"\x00*0\x01\x04\x00\x00\x1c \x00\x10LMT\x00+03\x00+05\x00+04\x00+02\x00\n<+04>-4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00iS\x18D.\x02" +
+	"\x00\x00.\x02\x00\x00\x0f\x00\x00\x00Europe/UzhgorodTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\x00\x00\x00\b\x00\x00\x00\"" +
+	"\xff\xff\xff\xffV\xb6\xc7d\xff\xff\xff\xff\xaa\x19\xa7d\xff\xff\xff\xff\xb5\xa4\x19`\xff\xff\xff\xff\xca\xcd.\xd0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xff" +
+	"\xceͨp\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0" +
+	"\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00" +
+	"\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00&\x8d \xe0\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd5\b\x80" +
+	"\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4ۀ\x00\x00\x00\x00-\x94̀\x00\x00\x00\x00.\x84\xbd\x80\x00\x00\x00\x00/t\xae\x80\x00\x00\x00\x000d\x9f\x80\x00\x00\x00\x00" +
+	"1]\xcb\x00\x00\x00\x00\x002r\xb4\x10\x01\x02\x03\x05\x04\x05\x04\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\x00\x00\x1c\x9c\x00\x00\x00\x00\x1c" +
+	"\x9c\x00\x04\x00\x00\x1c \x00\b\x00\x00*0\x00\f\x00\x00\x0e\x10\x00\x10\x00\x00\x1c \x01\x14\x00\x008@\x01\x19\x00\x00*0\x01\x1dLMT\x00KMT\x00EET\x00MSK\x00CET\x00C" +
+	"EST\x00MSD\x00EEST\x00\nEET-2EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Dd#" +
+	"\xc4\xf1\x01\x00\x00\xf1\x01\x00\x00\f\x00\x00\x00Europe/VaduzTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00%\x00\x00\x00\x04\x00\x00\x00\x11" +
+	"\xff\xff\xff\xff$\xf0\xea\x80\xff\xff\xff\xffq\xd4\x06\x86\xff\xff\xff\xff\xca\x17j\x00\xff\xff\xff\xff\xca\xe2q\x00\xff\xff\xff\xff\xcb\xf7L\x00\xff\xff\xff\xff\xcc\xc2S\x00\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00" +
+	"\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10" +
+	"\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00" +
+	"$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90" +
+	"\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\b\x00\x00\x00\x00\x00\x06\xfa\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\rLMT" +
+	"\x00BMT\x00CEST\x00CET\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\xb4\x9e\xe7" +
+	"\xb3\x03\x00\x00\xb3\x03\x00\x00\x0e\x00\x00\x00Europe/VaticanTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00W\x00\x00\x00\x04\x00\x00\x00" +
+	"\x11\xff\xff\xff\xff>(\xe8L\xff\xff\xff\xffp\xbc\x81p\xff\xff\xff\xff\x9b8\xf8p\xff\xff\xff\xff\x9b\xd5\xcc\xe0\xff\xff\xff\xff\x9c\xc5\xcb\xf0\xff\xff\xff\xff\x9d\xb7\x00`\xff\xff\xff\xff\x9e\x89\xfep\xff\xff\xff" +
+	"\xff\x9f\xa0\x1c\xe0\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1~\xad`\xff\xff\xff\xff\xa2\\7p\xff\xff\xff\xff\xa3L\x1a`\xff\xff\xff\xff\xc8l5\xf0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17" +
+	"\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2L\xd2\xf0\xff\xff\xff\xff\xd3>1\x90\xff\xff\xff\xff\xd4I\xd2\x10\xff\xff\xff" +
+	"\xff\xd5\x1d\xf7p\xff\xff\xff\xff\xd6)\x97\xf0\xff\xff\xff\xff\xd6뀐\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xf93\xb5\xf0\xff\xff\xff\xff\xf9\xd9\xc4\xe0\xff\xff\xff\xff\xfb\x1c\xd2p\xff\xff\xff\xff\xfb\xb9\xb4" +
+	"\xf0\xff\xff\xff\xff\xfc\xfc\xb4p\xff\xff\xff\xff\xfd\x99\x96\xf0\xff\xff\xff\xff\xfe\xe5\xd0\xf0\xff\xff\xff\xff\xff\x82\xb3p\x00\x00\x00\x00\x00Ų\xf0\x00\x00\x00\x00\x01b\x95p\x00\x00\x00\x00\x02\x9cZp\x00\x00\x00" +
+	"\x00\x03Bwp\x00\x00\x00\x00\x04\x85v\xf0\x00\x00\x00\x00\x05+\x93\xf0\x00\x00\x00\x00\x06n\x93p\x00\x00\x00\x00\a\vu\xf0\x00\x00\x00\x00\bE:\xf0\x00\x00\x00\x00\b\xebW\xf0\x00\x00\x00\x00\n.W" +
+	"p\x00\x00\x00\x00\n\xcb9\xf0\x00\x00\x00\x00\f\x0e9p\x00\x00\x00\x00\f\xab\x1b\xf0\x00\x00\x00\x00\r\xe4\xe0\xf0\x00\x00\x00\x00\x0e\x8a\xfd\xf0\x00\x00\x00\x00\x0f\xcd\xfdp\x00\x00\x00\x00\x10t\x1ap\x00\x00\x00" +
+	"\x00\x11\xad\xdfp\x00\x00\x00\x00\x12S\xfcp\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe" +
+	"\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00" +
+	"\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18" +
+	"\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00" +
+	"\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x00\x00\v\xb4\x00\x00\x00\x00\v\xb4\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\rLMT\x00RMT\x00CEST\x00CET\x00\nCET-1CEST,M3.5" +
+	".0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Z\x05wג\x02\x00\x00\x92\x02\x00\x00\r\x00\x00\x00Europe/ViennaTZif" +
 	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00N\x00\x00\x00\v\x00\x00\x00&\xff\xff\xff\xffV\xb6\xc0\xc7\xff\xff\xff\xff\x9b_\x1e\xc7\xff\xff\xff\xff\x9d>\xf2y\xff\xff\xff\xff\x9e" +
-	"*\xee\xf9\xff\xff\xff\xff\x9e\xf79i\xff\xff\xff\xff\x9f\x84W\xf9\xff\xff\xff\xff\xa0\xd8l\xe9\xff\xff\xff\xff\xa1\x009\x80\xff\xff\xff\xff\xa1<\xa6@\xff\xff\xff\xff\xa4\x10m\xc0\xff\xff\xff\xff\xa4=2\xb0\xff" +
-	"\xff\xff\xff\xa5\x15h\xb0\xff\xff\xff\xff\xa5=\x03\xc0\xff\xff\xff\xff\xa7\x1eEP\xff\xff\xff\xff\xb5\xa4\x19`\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17" +
-	"\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00" +
-	"\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&" +
-	"\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)x\xbf\x80\x00\x00\x00\x00)\xd4\xfap\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00" +
-	"\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x94\xbep\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003" +
-	"=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00" +
-	"\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb<p\x00\x00\x00\x00<\xa6Cp\x00\x00\x00\x00=\xbb\x1ep\x00\x00\x00\x00>\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f\ap\x00\x00\x00\x00A" +
-	"\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05\xadp\x00\x00\x00\x00G#\xc2\xf0\x00\x00\x00\x00G\xee\xc9\xf0\x00" +
-	"\x00\x00\x00I\x03\xa4\xf0\x00\x00\x00\x00IΫ\xf0\x00\x00\x00\x00J\xe3\x86\xf0\x00\x00\x00\x00K\xae\x8d\xf0\x00\x00\x00\x00Ḷp\x00\x00\x00\x00M\x8eo\xf0\x00\x00\x00\x00TL\x1d`\x01\x03\x02\x03\x04" +
-	"\x02\x04\x05\x06\x05\a\x05\x06\b\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\t\b\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" +
-	"\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\n\x06\x00\x00#9\x00\x00\x00\x00#9\x00\x04\x00\x001\x87\x01\b\x00\x00#w\x00\x04\x00\x00?\x97\x01\f\x00\x008@\x01\x11\x00\x00*0\x00\x15\x00\x00FP\x01" +
-	"\x19\x00\x00\x1c \x00\x1d\x00\x00*0\x01!\x00\x008@\x00\x15LMT\x00MMT\x00MST\x00MDST\x00MSD\x00MSK\x00+05\x00EET\x00EEST\x00\nMS" +
-	"K-3\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT2\x91B\xc0\xee\x01\x00\x00\xee\x01\x00\x00\x03\x00\x1c\x00WETUT\t\x00\x03\xdd\xfc\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00" +
-	"\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif" +
-	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\x00\x00\x00\x02\x00\x00\x00\t\x00\x00\x00\x00\r\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00" +
-	"\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ" +
-	"\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00" +
-	"\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10" +
-	"\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00" +
-	"+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x00\x01\x00\x01\x00\x01\x00" +
-	"\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x00\x00\x00\x00\x05\x00\x00\x0e\x10\x01\x00WEST\x00WET\x00\nWET0WES" +
-	"T,M3.5.0/1,M10.5.0\nPK\x03\x04\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\x04\x00\x1c\x00ZuluUT\t\x00\x03\xdd\xfc" +
-	"\x94b\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00" +
-	"\x00\x00UTC\x00\nUTC0\nPK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x18\x00\x00\x00\x00\x00\x00\x00\x10\x00\xedA\x00\x00\x00\x00Af" +
-	"rica/UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\xc1\n\x8a\x84\xad\x00\x00\x00\xad\x00\x00\x00\x0f\x00\x18" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81A\x00\x00\x00Africa/Sao_TomeUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03" +
-	"\n\x00\x00\x00\x00\x00\x8ej\xbeT\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x817\x01\x00\x00Africa/ConakryUT\x05\x00\x03\xdc" +
-	"\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81" +
-	"\x01\x02\x00\x00Africa/DakarUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\xaa\x81\t\x03" +
-	"\xa0\x00\x00\x00\xa0\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xc9\x02\x00\x00Africa/NdjamenaUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00" +
-	"\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeTd\x01\x05\x89\x7f\a\x00\x00\x7f\a\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xb2\x03\x00\x00Africa/Ca" +
-	"sablancaUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00" +
-	"\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81|\v\x00\x00Africa/LomeUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n" +
-	"\x00\x00\x00\x00\x00\x8ej\xbeTÊ\x0e\xc0\xd6\x01\x00\x00\xd6\x01\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81C\f\x00\x00Africa/AlgiersUT\x05\x00\x03\xdc\xfc" +
-	"\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81a" +
-	"\x0e\x00\x00Africa/MogadishuUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\xa7" +
-	"\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81j\x0f\x00\x00Africa/LagosUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00" +
-	"\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81d\x10\x00\x00Africa/Br" +
-	"azzavilleUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00" +
-	"\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81d\x11\x00\x00Africa/TimbuktuUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK" +
-	"\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81/\x12\x00\x00Africa/Nouakchot" +
-	"tUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\xcc\fTξ\x00\x00\x00\xbe\x00\x00\x00\r\x00\x18\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\xa4\x81\xfc\x12\x00\x00Africa/MaseruUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00" +
-	"\x8ej\xbeT\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x01\x14\x00\x00Africa/LibrevilleUT\x05\x00\x03\xdc\xfc\x94b" +
-	"ux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x00\x15\x00" +
-	"\x00Africa/HarareUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\xa7\x1d\xb3c\xb4\x00" +
-	"\x00\x00\xb4\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xca\x15\x00\x00Africa/MalaboUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01" +
-	"\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xc5\x16\x00\x00Africa/Bangui" +
-	"UT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\xa4\x81\xc0\x17\x00\x00Africa/NairobiUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00" +
-	"\x8ej\xbeT\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xc7\x18\x00\x00Africa/KinshasaUT\x05\x00\x03\xdc\xfc\x94bux" +
-	"\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xc4\x19\x00\x00A" +
-	"frica/Porto-NovoUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\x12tnj" +
-	"\xfc\x04\x00\x00\xfc\x04\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xc3\x1a\x00\x00Africa/CairoUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_" +
-	"\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x05 \x00\x00Africa/Doual" +
-	"aUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\x14\xcf\x10n\xca\x01\x00\x00\xca\x01\x00\x00\v\x00\x18\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\xa4\x81\x00!\x00\x00Africa/JubaUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej" +
-	"\xbeT \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x0f#\x00\x00Africa/GaboroneUT\x05\x00\x03\xdc\xfc\x94bux\v\x00" +
-	"\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\x93\xf4\x94\v\xc1\x01\x00\x00\xc1\x01\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xdb#\x00\x00Afr" +
-	"ica/TunisUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00" +
-	"\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xe2%\x00\x00Africa/KampalaUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01" +
-	"\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\xcc\fTξ\x00\x00\x00\xbe\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xe9&\x00\x00Africa/MbabaneUT\x05" +
-	"\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\xa4\x81\xef'\x00\x00Africa/Addis_AbabaUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00" +
-	"\x00\x8ej\xbeT \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xfa(\x00\x00Africa/MaputoUT\x05\x00\x03\xdc\xfc\x94bux\v" +
-	"\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\xca>\xd5\xe0\x95\x00\x00\x00\x95\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xc4)\x00\x00Af" +
-	"rica/BissauUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT \x1b\xb0_\x83\x00\x00\x00\x83" +
-	"\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xa0*\x00\x00Africa/BlantyreUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00" +
-	"PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81l+\x00\x00Africa/NiameyU" +
-	"T\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\xa4\x81g,\x00\x00Africa/BanjulUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej" +
-	"\xbeT\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x810-\x00\x00Africa/AbidjanUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01" +
-	"\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xfa-\x00\x00Afri" +
-	"ca/AsmaraUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00" +
-	"\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x00/\x00\x00Africa/BamakoUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02" +
-	"\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xc9/\x00\x00Africa/Ouagadougou" +
-	"UT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\xa4\x81\x970\x00\x00Africa/LusakaUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8e" +
-	"j\xbeT\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81a1\x00\x00Africa/LuandaUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01" +
-	"\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\\2\x00\x00Afri" +
-	"ca/AsmeraUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00" +
-	"\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81b3\x00\x00Africa/LubumbashiUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00" +
-	"PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x8104\x00\x00Africa/AccraUT" +
-	"\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeTV\xadD\xef\xca\x01\x00\x00\xca\x01\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\xa4\x81\xf84\x00\x00Africa/KhartoumUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8f" +
-	"j\xbeT\x9f\x1b\xeb\xdd2\x02\x00\x002\x02\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\v7\x00\x00Africa/CeutaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04" +
-	"\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x839\x00\x00Afric" +
-	"a/BujumburaUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeTm)\xb8P~\x02\x00\x00~" +
-	"\x02\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81P:\x00\x00Africa/WindhoekUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00" +
-	"PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT)\xae\x8eo&\a\x00\x00&\a\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x17=\x00\x00Africa/El_Aaiu" +
-	"nUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT_\x7f2[\xaf\x01\x00\x00\xaf\x01\x00\x00\x0e\x00\x18\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\xa4\x81\x86D\x00\x00Africa/TripoliUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00" +
-	"\x00\x8ej\xbeT6\x99rU\xa4\x00\x00\x00\xa4\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81}F\x00\x00Africa/MonroviaUT\x05\x00\x03\xdc\xfc\x94bu" +
-	"x\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\x14\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81jG\x00\x00" +
-	"Africa/Dar_es_SalaamUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT" +
-	"\xcc\fTξ\x00\x00\x00\xbe\x00\x00\x00\x13\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81wH\x00\x00Africa/JohannesburgUT\x05\x00\x03\xdc\xfc\x94bux" +
-	"\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x82I\x00\x00A" +
-	"frica/KigaliUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\xb4\x8d\x98ƿ\x00\x00\x00" +
-	"\xbf\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81LJ\x00\x00Africa/DjiboutiUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01" +
-	"\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81TK\x00\x00Africa/Freeto" +
-	"wnUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x18\x00\x00\x00" +
-	"\x00\x00\x00\x00\x10\x00\xedA\x1fL\x00\x00America/UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT" +
-	"q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x13\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81aL\x00\x00America/Puerto_RicoUT\x05\x00\x03\xdd\xfc\x94bux" +
-	"\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xbf\x03u\xf3\xe4\x01\x00\x00\xe4\x01\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81_M\x00\x00A" +
-	"merica/RecifeUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xd6\xfe\xf3%\xb4\x02\x00" +
-	"\x00\xb4\x02\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x8bO\x00\x00America/ResoluteUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S" +
-	"_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTa\xcb'\xe9\x9c\x01\x00\x00\x9c\x01\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x89R\x00\x00America/Man" +
-	"ausUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT3\x9aG\xc8\xd0\x06\x00\x00\xd0\x06\x00\x00\x10\x00\x18\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\xa4\x81mT\x00\x00America/New_YorkUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n" +
-	"\x00\x00\x00\x00\x00\x8fj\xbeT\x1e+}\x15\xb4\x02\x00\x00\xb4\x02\x00\x00\x14\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x87[\x00\x00America/Rankin_InletU" +
-	"T\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xfe7\xa1\x87\x1b\x01\x00\x00\x1b\x01\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\xa4\x81\x89^\x00\x00America/LimaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbe" +
-	"Tq\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x15\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xea_\x00\x00America/St_BarthelemyUT\x05\x00\x03\xdd\xfc\x94" +
-	"bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTP\x0f(\b=\x01\x00\x00=\x01\x00\x00\x15\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xea`" +
-	"\x00\x00America/Santo_DomingoUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8f" +
-	"j\xbeT>\x14\xe7\x03\x83\x03\x00\x00\x83\x03\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81vb\x00\x00America/DetroitUT\x05\x00\x03\xdd\xfc\x94bux\v" +
-	"\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xf1\xf9\x1dɻ\x00\x00\x00\xbb\x00\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81Bf\x00\x00Am" +
-	"erica/ParamariboUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT,\xdb~\xab" +
-	"\xb2\x03\x00\x00\xb2\x03\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81Ig\x00\x00America/YakutatUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00" +
-	"\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x04,2h\x99\x01\x00\x00\x99\x01\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81Dk\x00\x00America/S" +
-	"antaremUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe5S\xea&\xb9\x04\x00\x00\xb9\x04\x00\x00\x14" +
-	"\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81'm\x00\x00America/Punta_ArenasUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01" +
-	"\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT:\x9a1T\xdf\x01\x00\x00\xdf\x01\x00\x00\x14\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81.r\x00\x00America/Score" +
-	"sbysundUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTC\x1a\xec\xee\x02\x05\x00\x00\x02\x05\x00\x00\x10" +
-	"\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81[t\x00\x00America/SantiagoUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01" +
-	"\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x01\x05\xf3\x89\xb5\x00\x00\x00\xb5\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xa7y\x00\x00America/GuyanaUT\x05" +
-	"\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTԾ\xe7#\x95\x00\x00\x00\x95\x00\x00\x00\x15\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\xa4\x81\xa4z\x00\x00America/Coral_HarbourUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00" +
-	"\x00\x00\x00\x00\x8fj\xbeTg\xf5K\x89\xa2\x01\x00\x00\xa2\x01\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x88{\x00\x00America/Rio_BrancoUT\x05\x00" +
-	"\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTg\xf5K\x89\xa2\x01\x00\x00\xa2\x01\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\xa4\x81v}\x00\x00America/Porto_AcreUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00" +
-	"\x8fj\xbeTp\x1b\xceRC\x03\x00\x00C\x03\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81d\x7f\x00\x00America/NipigonUT\x05\x00\x03\xdd\xfc\x94bux" +
-	"\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT{\a\a\xdc\xca\x03\x00\x00\xca\x03\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xf0\x82\x00\x00A" +
-	"merica/EdmontonUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTq\xc9*;\xb1" +
-	"\x00\x00\x00\xb1\x00\x00\x00\x15\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x04\x87\x00\x00America/Port_of_SpainUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01" +
-	"\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTq\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x15\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x04\x88\x00\x00Amer" +
-	"ica/Lower_PrincesUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTq\xc9*" +
-	";\xb1\x00\x00\x00\xb1\x00\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x04\x89\x00\x00America/St_ThomasUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91" +
-	"\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xac\x8a\x83S\xd4\x00\x00\x00\xd4\x00\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x00\x8a\x00\x00Americ" +
-	"a/GuatemalaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTR\xc8\xd9\xf6\xc4\x02\x00\x00\xc4" +
-	"\x02\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x1f\x8b\x00\x00America/CatamarcaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_" +
-	"\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTq\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81.\x8e\x00\x00America/Anti" +
-	"guaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x1b\x81-\xa9\x8a\x01\x00\x00\x8a\x01\x00\x00\x13\x00\x18\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\xa4\x81(\x8f\x00\x00America/Porto_VelhoUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02" +
-	"\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xef\xf0R\x8a\xc4\x02\x00\x00\xc4\x02\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xff\x90\x00\x00America/RosarioUT\x05" +
-	"\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9bܩ=\xda\x06\x00\x00\xda\x06\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\xa4\x81\f\x94\x00\x00America/ChicagoUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj" +
-	"\xbeTø\xab\x9b\xf0\x00\x00\x00\xf0\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81/\x9b\x00\x00America/CrestonUT\x05\x00\x03\xdd\xfc\x94bux\v\x00" +
-	"\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe5s\xb3\\'\x01\x00\x00'\x01\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81h\x9c\x00\x00Ame" +
-	"rica/ManaguaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTӿ\x92\xbc\xb5\x06\x00\x00" +
-	"\xb5\x06\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\u061d\x00\x00America/NassauUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00" +
-	"PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTc)\xf6)\xb3\x00\x00\x00\xb3\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81դ\x00\x00America/Bogota" +
-	"UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xf2\x04\xde\xdd\x11\x02\x00\x00\x11\x02\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\xa4\x81Х\x00\x00America/CancunUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00" +
-	"\x8fj\xbeT\xb4\x82s\x1dT\x01\x00\x00T\x01\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81)\xa8\x00\x00America/ChihuahuaUT\x05\x00\x03\xdd\xfc\x94b" +
-	"ux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x1e\xfbn۸\x03\x00\x00\xb8\x03\x00\x00\x14\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81ȩ\x00" +
-	"\x00America/Campo_GrandeUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbe" +
-	"T):\x17-\x88\x06\x00\x00\x88\x06\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81έ\x00\x00America/HalifaxUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01" +
-	"\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT.\xbe\x1a>\xe7\x03\x00\x00\xe7\x03\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x9f\xb4\x00\x00Amer" +
-	"ica/BoiseUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTӿ\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00" +
-	"\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\u0378\x00\x00America/MontrealUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00P" +
-	"K\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x1d\xf7\a ,\x06\x00\x00,\x06\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81̿\x00\x00America/Goose_B" +
-	"ayUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9d?\xdfڸ\x03\x00\x00\xb8\x03\x00\x00\x11\x00\x18\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\xa4\x81C\xc6\x00\x00America/Sao_PauloUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n" +
-	"\x00\x00\x00\x00\x00\x8fj\xbeTq\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x14\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81F\xca\x00\x00America/Blanc-SablonU" +
-	"T\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTø\xab\x9b\xf0\x00\x00\x00\xf0\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\xa4\x81E\xcb\x00\x00America/PhoenixUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00" +
-	"\x8fj\xbeTԾ\xe7#\x95\x00\x00\x00\x95\x00\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81~\xcc\x00\x00America/AtikokanUT\x05\x00\x03\xdd\xfc\x94bu" +
-	"x\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xa1'\a\xbd\x97\x00\x00\x00\x97\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81]\xcd\x00\x00" +
-	"America/CayenneUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe90T\x16\xd1" +
-	"\x01\x00\x00\xd1\x01\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81=\xce\x00\x00America/NuukUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01" +
-	"\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xd0v\x01\x8a\x01\x04\x00\x00\x01\x04\x00\x00\x14\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81T\xd0\x00\x00America/Santa" +
-	"_IsabelUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xf8Dz\x97\xae\x01\x00\x00\xae\x01\x00\x00\x11" +
-	"\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xa3\xd4\x00\x00America/Boa_VistaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK" +
-	"\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x8f\x19Ԇ\x12\x02\x00\x00\x12\x02\x00\x00\x16\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x9c\xd6\x00\x00America/Bahia_Ba" +
-	"nderasUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00" +
-	"\x18\x00\x00\x00\x00\x00\x00\x00\x10\x00\xedA\xfe\xd8\x00\x00America/Indiana/UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02" +
-	"\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT \x17\x89}q\x01\x00\x00q\x01\x00\x00\x15\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81H\xd9\x00\x00America/Indiana/Ve" +
-	"vayUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTp\xb6{\xc9\x13\x02\x00\x00\x13\x02\x00\x00\x1c\x00\x18\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\xa4\x81\b\xdb\x00\x00America/Indiana/IndianapolisUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00" +
-	"\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTK-E\xfad\x02\x00\x00d\x02\x00\x00\x17\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81q\xdd\x00\x00America/I" +
-	"ndiana/WinamacUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTصK\xa6\n\x02" +
-	"\x00\x00\n\x02\x00\x00\x19\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81&\xe0\x00\x00America/Indiana/Tell_CityUT\x05\x00\x03\xdd\xfc\x94bux" +
-	"\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x01\xd8N\x8c\xab\x02\x00\x00\xab\x02\x00\x00\x1a\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x83\xe2\x00\x00A" +
-	"merica/Indiana/PetersburgUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00" +
-	"\x00\x8fj\xbeT\r\xedsp.\x02\x00\x00.\x02\x00\x00\x19\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x82\xe5\x00\x00America/Indiana/Vincennes" +
-	"UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT$ \x873\xf8\x03\x00\x00\xf8\x03\x00\x00\x14\x00\x18\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\xa4\x81\x03\xe8\x00\x00America/Indiana/KnoxUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03" +
-	"\n\x00\x00\x00\x00\x00\x8fj\xbeTM/U\x9f7\x02\x00\x007\x02\x00\x00\x17\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81I\xec\x00\x00America/Indiana/Mare" +
-	"ngoUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTp\xb6{\xc9\x13\x02\x00\x00\x13\x02\x00\x00\x14\x00\x18\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xd1\xee\x00\x00America/IndianapolisUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01" +
-	"\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTq\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x812\xf1\x00\x00America/DominicaU" +
-	"T\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00" +
-	"\x00\x10\x00\xedA-\xf2\x00\x00America/Argentina/UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00" +
-	"\x00\x00\x00\x8fj\xbeTt*\x9b!\xb2\x02\x00\x00\xb2\x02\x00\x00\x17\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81y\xf2\x00\x00America/Argentina/Salta" +
-	"UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x8b}\xb6\x1e\xc4\x02\x00\x00\xc4\x02\x00\x00\x19\x00\x18\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\xa4\x81|\xf5\x00\x00America/Argentina/UshuaiaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00P" +
-	"K\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTR\xc8\xd9\xf6\xc4\x02\x00\x00\xc4\x02\x00\x00\x1b\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x93\xf8\x00\x00America/Argenti" +
-	"na/CatamarcaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTR\xc8\xd9\xf6\xc4\x02\x00\x00" +
-	"\xc4\x02\x00\x00 \x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xac\xfb\x00\x00America/Argentina/ComodRivadaviaUT\x05\x00\x03\xdd" +
-	"\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xfcz=\xe1\xcd\x02\x00\x00\xcd\x02\x00\x00\x1a\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81" +
-	"\xca\xfe\x00\x00America/Argentina/San_JuanUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03" +
-	"\n\x00\x00\x00\x00\x00\x8fj\xbeT\x1c\x80\xb9\\\xcd\x02\x00\x00\xcd\x02\x00\x00\x1a\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xeb\x01\x01\x00America/Argentina/Sa" +
-	"n_LuisUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x8ep\xb4c\xc4\x02\x00\x00\xc4\x02\x00\x00\x1e\x00" +
-	"\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\f\x05\x01\x00America/Argentina/Rio_GallegosUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01" +
-	"\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTutZ\x1a\xb2\x02\x00\x00\xb2\x02\x00\x00\x17\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81(\b\x01\x00Amer" +
-	"ica/Argentina/JujuyUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTY" +
-	"\xd8֭\xd6\x02\x00\x00\xd6\x02\x00\x00\x19\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81+\v\x01\x00America/Argentina/TucumanUT\x05\x00\x03\xdd" +
-	"\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe0\xbf\xf5\xe5\xc4\x02\x00\x00\xc4\x02\x00\x00\x1e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81" +
-	"T\x0e\x01\x00America/Argentina/Buenos_AiresUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK" +
-	"\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xef\xf0R\x8a\xc4\x02\x00\x00\xc4\x02\x00\x00\x19\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81p\x11\x01\x00America/Argentin" +
-	"a/CordobaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTm\aD\x0e\xcd\x02\x00\x00\xcd\x02\x00" +
-	"\x00\x1a\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x87\x14\x01\x00America/Argentina/La_RiojaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04" +
-	"\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTŒZ\x8c\xc4\x02\x00\x00\xc4\x02\x00\x00\x19\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xa8\x17\x01\x00Ameri" +
-	"ca/Argentina/MendozaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT" +
-	"\xad`\x12\xe9\xaa\x00\x00\x00\xaa\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xbf\x1a\x01\x00America/La_PazUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91" +
-	"\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xfe\xe6\xf5J\x05\x04\x00\x00\x05\x04\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xb1\x1b\x01\x00Americ" +
-	"a/DawsonUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT.\xf9\xc0\x1e\xd5\x05\x00\x00\xd5\x05\x00\x00" +
-	"\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xfe\x1f\x01\x00America/MonctonUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01" +
-	"\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTU\xactA\xb5\x01\x00\x00\xb5\x01\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x1c&\x01\x00America/Matamoros" +
-	"UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTq\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\xa4\x81\x1c(\x01\x00America/St_VincentUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00" +
-	"\x00\x00\x00\x00\x8fj\xbeT\u0096dK~\x02\x00\x00~\x02\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x19)\x01\x00America/ReginaUT\x05\x00\x03\xdd\xfc\x94" +
-	"bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTU!\x12f\xd9\x02\x00\x00\xd9\x02\x00\x00\x13\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xdf+" +
-	"\x01\x00America/YellowknifeUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbe" +
-	"T\x1b\vKdC\x03\x00\x00C\x03\x00\x00\x13\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x05/\x01\x00America/Rainy_RiverUT\x05\x00\x03\xdd\xfc\x94bu" +
-	"x\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTq\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x952\x01\x00" +
-	"America/KralendijkUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTMv" +
-	"\xa1\x0f%\x01\x00\x00%\x01\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x923\x01\x00America/MonterreyUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04" +
-	"\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT%J\xd5\xebS\x01\x00\x00S\x01\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x025\x01\x00Ameri" +
-	"ca/JamaicaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\a\x1c\x9e\x9a]\x04\x00\x00]\x04" +
-	"\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x9e6\x01\x00America/HavanaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK" +
-	"\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x82\x13z\xe2\xc2\x00\x00\x00\xc2\x00\x00\x00\x13\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81C;\x01\x00America/Teguciga" +
-	"lpaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xcd\xc3v\xe3\xb3\x00\x00\x00\xb3\x00\x00\x00\x11\x00\x18\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\xa4\x81R<\x01\x00America/GuayaquilUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03" +
-	"\n\x00\x00\x00\x00\x00\x8fj\xbeT\xa2\x81\xbfyS\x02\x00\x00S\x02\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81P=\x01\x00America/MetlakatlaUT" +
-	"\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT8\xcdZ\x05o\x01\x00\x00o\x01\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\xa4\x81\xef?\x01\x00America/MazatlanUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00" +
-	"\x8fj\xbeT\x89غ\xee\x15\x04\x00\x00\x15\x04\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xa8A\x01\x00America/BelizeUT\x05\x00\x03\xdd\xfc\x94bux\v" +
-	"\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT$ \x873\xf8\x03\x00\x00\xf8\x03\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x05F\x01\x00Am" +
-	"erica/Knox_INUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x7f$*\xa0\xa6\x03\x00" +
-	"\x00\xa6\x03\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81FJ\x01\x00America/CuiabaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01" +
-	"\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTo_\x00v/\x01\x00\x00/\x01\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x814N\x01\x00America/Merid" +
-	"aUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTutZ\x1a\xb2\x02\x00\x00\xb2\x02\x00\x00\r\x00\x18\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\xa4\x81\xabO\x01\x00America/JujuyUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00" +
-	"\x8fj\xbeTԾ\xe7#\x95\x00\x00\x00\x95\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xa4R\x01\x00America/CaymanUT\x05\x00\x03\xdd\xfc\x94bux\v" +
-	"\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x85-\xb9\xf8\x8a\x01\x00\x00\x8a\x01\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x81S\x01\x00Am" +
-	"erica/BelemUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTs\xb0\xeau\xb4\x01\x00\x00\xb4" +
-	"\x01\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81RU\x01\x00America/EirunepeUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01" +
-	"\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTq\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81PW\x01\x00America/St_Lu" +
-	"ciaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTOKjǪ\x02\x00\x00\xaa\x02\x00\x00\r\x00\x18\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\xa4\x81KX\x01\x00America/BahiaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00" +
-	"\x00\x00\x8fj\xbeT\xc1Ȇ\x90\x05\x04\x00\x00\x05\x04\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81<[\x01\x00America/WhitehorseUT\x05\x00\x03\xdd" +
-	"\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTq\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81" +
-	"\x8d_\x01\x00America/TortolaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTU" +
-	"9#\xbe2\x05\x00\x002\x05\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x87`\x01\x00America/VancouverUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01" +
-	"\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xf7\xe9 y\xbd\x02\x00\x00\xbd\x02\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x04f\x01\x00Amer" +
-	"ica/InuvikUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xb4T\xbd\xeb5\x02\x00\x005\x02" +
-	"\x00\x00\x16\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\ti\x01\x00America/Port-au-PrinceUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b" +
-	"\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xb4\x11Z\xde\xe4\x01\x00\x00\xe4\x01\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x8ek\x01\x00America/" +
-	"FortalezaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xb7-2f\xe4\x01\x00\x00\xe4\x01\x00" +
-	"\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xbdm\x01\x00America/NoronhaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK" +
-	"\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe0\xbf\xf5\xe5\xc4\x02\x00\x00\xc4\x02\x00\x00\x14\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xeao\x01\x00America/Buenos_A" +
-	"iresUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xf6\"\x12\xfe\x0e\x05\x00\x00\x0e\x05\x00\x00\x13\x00\x18\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xfcr\x01\x00America/Los_AngelesUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01" +
-	"\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xea$\xc1\xbf\xb0\x00\x00\x00\xb0\x00\x00\x00\x13\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81Wx\x01\x00America/El_Salvad" +
-	"orUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTV\x80\x94@\x12\x04\x00\x00\x12\x04\x00\x00\x0e\x00\x18\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\xa4\x81Ty\x01\x00America/DenverUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00" +
-	"\x00\x00\x8fj\xbeTp\xb6{\xc9\x13\x02\x00\x00\x13\x02\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xae}\x01\x00America/Fort_WayneUT\x05\x00\x03\xdd" +
-	"\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x10\x00\xedA" +
-	"\r\x80\x01\x00America/Kentucky/UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbe" +
-	"T\xdf\xe5\x8d\xc4\xda\x04\x00\x00\xda\x04\x00\x00\x1b\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81X\x80\x01\x00America/Kentucky/LouisvilleUT" +
-	"\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x03\x1a|J\xcc\x03\x00\x00\xcc\x03\x00\x00\x1b\x00\x18\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\xa4\x81\x87\x85\x01\x00America/Kentucky/MonticelloUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00P" +
-	"K\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15\x00\x18\x00\x00\x00\x00\x00\x00\x00\x10\x00\xedA\xa8\x89\x01\x00America/North_D" +
-	"akota/UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTR\x1b\x8b(\xde\x03\x00\x00\xde\x03\x00\x00\x1e\x00" +
-	"\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xf7\x89\x01\x00America/North_Dakota/New_SalemUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01" +
-	"\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTH\xeam\xef\xde\x03\x00\x00\xde\x03\x00\x00\x1b\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81-\x8e\x01\x00Amer" +
-	"ica/North_Dakota/CenterUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8f" +
-	"j\xbeT\xb7.\xb6*\x13\x04\x00\x00\x13\x04\x00\x00\x1b\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81`\x92\x01\x00America/North_Dakota/Beulah" +
-	"UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTM\x94\xc7Kp\x03\x00\x00p\x03\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\xa4\x81Ȗ\x01\x00America/Glace_BayUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00" +
-	"\x00\x00\x00\x8fj\xbeTq\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x83\x9a\x01\x00America/MontserratUT\x05\x00\x03" +
-	"\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTӿ\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4" +
-	"\x81\x80\x9b\x01\x00America/TorontoUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT" +
-	"Ծ\xe7#\x95\x00\x00\x00\x95\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81~\xa2\x01\x00America/PanamaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91" +
-	"\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xef\xf0R\x8a\xc4\x02\x00\x00\xc4\x02\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81[\xa3\x01\x00Americ" +
-	"a/CordobaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xdf\xe5\x8d\xc4\xda\x04\x00\x00\xda\x04\x00" +
-	"\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81h\xa6\x01\x00America/LouisvilleUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01" +
-	"\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xd0v\x01\x8a\x01\x04\x00\x00\x01\x04\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x8e\xab\x01\x00America/Ensen" +
-	"adaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTV\x80\x94@\x12\x04\x00\x00\x12\x04\x00\x00\x10\x00\x18\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\xa4\x81ٯ\x01\x00America/ShiprockUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n" +
-	"\x00\x00\x00\x00\x00\x8fj\xbeT$\r\x89l\xe4\x01\x00\x00\xe4\x01\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x815\xb4\x01\x00America/OjinagaUT\x05\x00\x03\xdd" +
-	"\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTU\r\xf7\xd3\xc7\x01\x00\x00\xc7\x01\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81" +
-	"b\xb6\x01\x00America/ThuleUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xac\x8e\xee" +
-	"\x13\xbe\x00\x00\x00\xbe\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81p\xb8\x01\x00America/CaracasUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b" +
-	"\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT<\x01V\rP\x02\x00\x00P\x02\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81w\xb9\x01\x00America/" +
-	"AraguainaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x1d`̟\x00\x03\x00\x00\x00\x03\x00" +
-	"\x00\x15\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x12\xbc\x01\x00America/Cambridge_BayUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04" +
-	"S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT?_p\x99\x0e\x05\x00\x00\x0e\x05\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81a\xbf\x01\x00America/Wi" +
-	"nnipegUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe3\xc9I\xd0U\x03\x00\x00U\x03\x00\x00\x12\x00" +
-	"\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xb9\xc4\x01\x00America/Grand_TurkUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK" +
-	"\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTq\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81Z\xc8\x01\x00America/VirginUT" +
-	"\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT5\x11Q\x06\xd1\x03\x00\x00\xd1\x03\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\xa4\x81S\xc9\x01\x00America/AnchorageUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00" +
-	"\x00\x8fj\xbeT\xb1݂x\xe8\x00\x00\x00\xe8\x00\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81o\xcd\x01\x00America/Costa_RicaUT\x05\x00\x03\xdd\xfc" +
-	"\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTn\xab\xd5\xf9\xcf\x03\x00\x00\xcf\x03\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xa3" +
-	"\xce\x01\x00America/NomeUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTq\xc9*;\xb1" +
-	"\x00\x00\x00\xb1\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xb8\xd2\x01\x00America/GrenadaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04" +
-	"S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT~\xb2\x0e\x19V\a\x00\x00V\a\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xb2\xd3\x01\x00America/St" +
-	"_JohnsUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xae,\xa44\xc9\x03\x00\x00\xc9\x03\x00\x00\f\x00" +
-	"\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81R\xdb\x01\x00America/AtkaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00" +
-	"\x00\x00\x00\x00\x8fj\xbeTd\xa9y\x9at\x03\x00\x00t\x03\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81a\xdf\x01\x00America/AsuncionUT\x05\x00\x03\xdd" +
-	"\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTB\xa0=:\x1e\x01\x00\x00\x1e\x01\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81" +
-	"\x1f\xe3\x01\x00America/HermosilloUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj" +
-	"\xbeT\xd0v\x01\x8a\x01\x04\x00\x00\x01\x04\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x89\xe4\x01\x00America/TijuanaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00" +
-	"\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTq\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xd3\xe8\x01\x00Ame" +
-	"rica/MarigotUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT?\xc9\x1c\xd4\xc6\x03\x00\x00" +
-	"\xc6\x03\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xcd\xe9\x01\x00America/JuneauUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00" +
-	"PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xc0\x98\x00\b\xc9\x03\x00\x00\xc9\x03\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xdb\xed\x01\x00America/Montev" +
-	"ideoUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe90T\x16\xd1\x01\x00\x00\xd1\x01\x00\x00\x0f\x00\x18\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xf0\xf1\x01\x00America/GodthabUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n" +
-	"\x00\x00\x00\x00\x00\x8fj\xbeTq\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\n\xf4\x01\x00America/GuadeloupeUT\x05" +
-	"\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT挋\x92\xf6\x01\x00\x00\xf6\x01\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\xa4\x81\a\xf5\x01\x00America/MaceioUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbe" +
-	"TJtZ\x8c\x01\x03\x00\x00\x01\x03\x00\x00\x13\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81E\xf7\x01\x00America/PangnirtungUT\x05\x00\x03\xdd\xfc\x94bu" +
-	"x\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTq\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x93\xfa\x01\x00" +
-	"America/St_KittsUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTl=\xad\xbe" +
-	"\x16\x01\x00\x00\x16\x01\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x8e\xfb\x01\x00America/BarbadosUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b" +
-	"\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT<\xb9\x18\x87\xe4\x02\x00\x00\xe4\x02\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xee\xfc\x01\x00America/" +
-	"IqaluitUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT8O:\xbf\x95\x03\x00\x00\x95\x03\x00\x00\x11" +
-	"\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x1b\x00\x02\x00America/MenomineeUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK" +
-	"\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xa7\x17jҲ\x00\x00\x00\xb2\x00\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xfb\x03\x02\x00America/Martiniq" +
-	"ueUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xd6\xe1Հ\x9c\x01\x00\x00\x9c\x01\x00\x00\x13\x00\x18\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\xa4\x81\xf9\x04\x02\x00America/Mexico_CityUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e" +
-	"\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x1c\xd8\x19\x9dp\x01\x00\x00p\x01\x00\x00\x15\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xe2\x06\x02\x00America/Swift_Curre" +
-	"ntUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xd7\b\\\xc6&\x02\x00\x00&\x02\x00\x00\x10\x00\x18\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\xa4\x81\xa1\b\x02\x00America/MiquelonUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00" +
-	"\x00\x00\x00\x00\x8fj\xbeTq\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x11\v\x02\x00America/CuracaoUT\x05\x00\x03\xdd\xfc" +
-	"\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT+\x10`ȫ\x02\x00\x00\xab\x02\x00\x00\x14\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\v" +
-	"\f\x02\x00America/Dawson_CreekUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8f" +
-	"j\xbeTŒZ\x8c\xc4\x02\x00\x00\xc4\x02\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x04\x0f\x02\x00America/MendozaUT\x05\x00\x03\xdd\xfc\x94bux\v" +
-	"\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xae,\xa44\xc9\x03\x00\x00\xc9\x03\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x11\x12\x02\x00Am" +
-	"erica/AdakUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT錴$q\x03\x00\x00q\x03" +
-	"\x00\x00\x13\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81 \x16\x02\x00America/Thunder_BayUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S" +
-	"_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTq\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xde\x19\x02\x00America/Aru" +
-	"baUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xf6@\rm\xa8\x05\x00\x00\xa8\x05\x00\x00\x13\x00\x18\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\xa4\x81\xd6\x1a\x02\x00America/Fort_NelsonUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e" +
-	"\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x81{\xc1\x92\xbc\x03\x00\x00\xbc\x03\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xcb \x02\x00America/SitkaUT\x05\x00\x03\xdd" +
-	"\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTq\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81" +
-	"\xce$\x02\x00America/AnguillaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT" +
-	"k\xc2\rx\xbf\x01\x00\x00\xbf\x01\x00\x00\x14\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xc9%\x02\x00America/DanmarkshavnUT\x05\x00\x03\xdd\xfc\x94bu" +
-	"x\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x10\x00\xedA\xd6'\x02\x00" +
-	"Antarctica/UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x95{\xf3\xa9w\x03\x00\x00w" +
-	"\x03\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x1b(\x02\x00Antarctica/PalmerUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_" +
-	"\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\x95\xea\x06\xd3\xc5\x00\x00\x00\xc5\x00\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xdd+\x02\x00Antarctica/D" +
-	"avisUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeTƉ\xf71\x84\x00\x00\x00\x84\x00\x00\x00\x12\x00\x18\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xec,\x02\x00Antarctica/RotheraUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02" +
-	"\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\xc2\v\xae\b\x85\x00\x00\x00\x85\x00\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xbc-\x02\x00Antarctica/VostokU" +
-	"T\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xcfׇ\xe1\x85\x00\x00\x00\x85\x00\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\xa4\x81\x8c.\x02\x00Antarctica/SyowaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00" +
-	"\x00\x8fj\xbeTn\x04\x19y\x9a\x00\x00\x00\x9a\x00\x00\x00\x19\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81[/\x02\x00Antarctica/DumontDUrville" +
-	"UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTb\xb2\xaf\xf7\x13\x04\x00\x00\x13\x04\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\xa4\x81H0\x02\x00Antarctica/McMurdoUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00" +
-	"\x00\x00\x00\x00\x8fj\xbeT\xb2\x84J]\xd0\x03\x00\x00\xd0\x03\x00\x00\x14\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xa74\x02\x00Antarctica/MacquarieUT" +
-	"\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTb\xb2\xaf\xf7\x13\x04\x00\x00\x13\x04\x00\x00\x15\x00\x18\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\xa4\x81\xc58\x02\x00Antarctica/South_PoleUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n" +
-	"\x00\x00\x00\x00\x00\x8ej\xbeT:\xc8P7\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81'=\x02\x00Antarctica/TrollUT\x05\x00\x03" +
-	"\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\xd7N\xab\x8b\x98\x00\x00\x00\x98\x00\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4" +
-	"\x81\">\x02\x00Antarctica/MawsonUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej" +
-	"\xbeT\xddzAh\xf3\x00\x00\x00\xf3\x00\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x05?\x02\x00Antarctica/CaseyUT\x05\x00\x03\xdc\xfc\x94bux\v" +
-	"\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x18\x00\x00\x00\x00\x00\x00\x00\x10\x00\xedAB@\x02\x00Ar" +
-	"ctic/UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xa5\x97\aĤ\x02\x00\x00\xa4\x02\x00\x00\x13\x00\x18" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x83@\x02\x00Arctic/LongyearbyenUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK" +
-	"\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x18\x00\x00\x00\x00\x00\x00\x00\x10\x00\xedAtC\x02\x00Asia/UT\x05\x00\x03\xdd\xfc\x94bux" +
-	"\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT's\x96\x1en\x01\x00\x00n\x01\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xb3C\x02\x00A" +
-	"sia/DushanbeUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xa1\xfax\x98g\x02\x00\x00" +
-	"g\x02\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81hE\x02\x00Asia/QostanayUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00P" +
-	"K\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9a\x1a\xdc\xca\xdc\x00\x00\x00\xdc\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x16H\x02\x00Asia/CalcuttaUT" +
-	"\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeTB\x1d\xc6\x1b\x85\x00\x00\x00\x85\x00\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\xa4\x819I\x02\x00Asia/UrumqiUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT9" +
-	"Y\xb7\xf1\n\x01\x00\x00\n\x01\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x03J\x02\x00Asia/KarachiUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00" +
-	"\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x83g\x95M\a\x03\x00\x00\a\x03\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81SK\x02\x00Asia/Khan" +
-	"dygaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeTj$\xcd\xf4\x9a\x00\x00\x00\x9a\x00\x00\x00\v\x00\x18\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xa1N\x02\x00Asia/ThimbuUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00" +
-	"\x00\x8ej\xbeTj$\xcd\xf4\x9a\x00\x00\x00\x9a\x00\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x80O\x02\x00Asia/ThimphuUT\x05\x00\x03\xdc\xfc\x94bux\v\x00" +
-	"\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTd%\x05\xd8\xe6\x02\x00\x00\xe6\x02\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81`P\x02\x00Asi" +
-	"a/VladivostokUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x88\xf6C\x84\x98\x00\x00" +
-	"\x00\x98\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x90S\x02\x00Asia/VientianeUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01" +
-	"\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81pT\x02\x00Asia/Shanghai" +
-	"UT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xb2\xb9\xf4\xb6R\x02\x00\x00R\x02\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\xa4\x81@V\x02\x00Asia/Ulan_BatorUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00" +
-	"\x00\x8fj\xbeT\xcfׇ\xe1\x85\x00\x00\x00\x85\x00\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xdbX\x02\x00Asia/AdenUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91" +
-	"\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xed\x8c\xf1\x91\x85\x00\x00\x00\x85\x00\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xa3Y\x02\x00Asia/M" +
-	"uscatUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xef\\\xf4q\x17\x04\x00\x00\x17\x04\x00\x00\r\x00\x18" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81mZ\x02\x00Asia/DamascusUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00" +
-	"\x00\x00\x00\x00\x8fj\xbeT\x17✳2\x04\x00\x002\x04\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xcb^\x02\x00Asia/JerusalemUT\x05\x00\x03\xdd\xfc\x94" +
-	"bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeTy\x19\xe0N\x9a\x00\x00\x00\x9a\x00\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81Ec" +
-	"\x02\x00Asia/BruneiUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xb2\xb9\xf4\xb6R\x02\x00" +
-	"\x00R\x02\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81$d\x02\x00Asia/UlaanbaatarUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S" +
-	"_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9e\x88|`\x9a\x03\x00\x00\x9a\x03\x00\x00\n\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xc0f\x02\x00Asia/AmmanU" +
-	"T\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xa7f^]@\x01\x00\x00@\x01\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\xa4\x81\x9ej\x02\x00Asia/KuchingUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbe" +
-	"T\x17✳2\x04\x00\x002\x04\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81$l\x02\x00Asia/Tel_AvivUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91" +
-	"\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xc7X,Y\x9f\x01\x00\x00\x9f\x01\x00\x00\n\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x9dp\x02\x00Asia/S" +
-	"eoulUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT?\xa7^\xfah\x02\x00\x00h\x02\x00\x00\v\x00\x18\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x80r\x02\x00Asia/AtyrauUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00" +
-	"\x00\x8fj\xbeT\x8a\xc1\x1eB\xb7\x00\x00\x00\xb7\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81-u\x02\x00Asia/PyongyangUT\x05\x00\x03\xdd\xfc\x94bux" +
-	"\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xba\xa3b\xc1R\x02\x00\x00R\x02\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81,v\x02\x00A" +
-	"sia/HovdUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x1e\x1f\x96\xde\xea\x04\x00\x00\xea\x04\x00\x00" +
-	"\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xc1x\x02\x00Asia/HebronUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n" +
-	"\x00\x00\x00\x00\x00\x8fj\xbeT\xcfׇ\xe1\x85\x00\x00\x00\x85\x00\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xf0}\x02\x00Asia/KuwaitUT\x05\x00\x03\xdd\xfc\x94bu" +
-	"x\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT[u\x99q\xf1\x02\x00\x00\xf1\x02\x00\x00\n\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xba~\x02\x00" +
-	"Asia/TomskUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTǯ\xdf\x1c\xee\x00\x00\x00\xee\x00" +
-	"\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xef\x81\x02\x00Asia/ManilaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e" +
-	"\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xab\xcd\xdf\x05\xee\x02\x00\x00\xee\x02\x00\x00\n\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\"\x83\x02\x00Asia/ChitaUT\x05\x00\x03\xdd\xfc\x94b" +
-	"ux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x8bSnT\xa1\x00\x00\x00\xa1\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81T\x86\x02" +
-	"\x00Asia/KatmanduUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9e\xa1=H\xd8\x04" +
-	"\x00\x00\xd8\x04\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81<\x87\x02\x00Asia/GazaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01" +
-	"\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTw\rD\an\x01\x00\x00n\x01\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81W\x8c\x02\x00Asia/SamarkandUT\x05" +
-	"\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\xee\xf0BB\xff\x01\x00\x00\xff\x01\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\xa4\x81\r\x8e\x02\x00Asia/TaipeiUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xb2\xe2" +
-	"7Yn\x01\x00\x00n\x01\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81Q\x90\x02\x00Asia/TashkentUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00" +
-	"\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9a\xea\x18\xd4\xf8\x02\x00\x00\xf8\x02\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x06\x92\x02\x00Asia/Yeka" +
-	"terinburgUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\x1d?v\f\x17\x03\x00\x00\x17\x03\x00" +
-	"\x00\n\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81J\x95\x02\x00Asia/MacauUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n" +
-	"\x00\x00\x00\x00\x00\x8fj\xbeT\xd5ΜGp\x02\x00\x00p\x02\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xa5\x98\x02\x00Asia/QyzylordaUT\x05\x00\x03\xdd\xfc" +
-	"\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\x1d?v\f\x17\x03\x00\x00\x17\x03\x00\x00\n\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81]" +
-	"\x9b\x02\x00Asia/MacaoUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x02\xf4\xaeg\xd5\x00\x00" +
-	"\x00\xd5\x00\x00\x00\n\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xb8\x9e\x02\x00Asia/TokyoUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01" +
-	"\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\x03\x87\xb3<\xe8\x02\x00\x00\xe8\x02\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81џ\x02\x00Asia/BakuUT\x05\x00\x03\xdc\xfc\x94" +
-	"bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x87\xbd\xedL\xf1\x02\x00\x00\xf1\x02\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xfc\xa2" +
-	"\x02\x00Asia/BarnaulUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\aW\x10Ѱ\x04" +
-	"\x00\x00\xb0\x04\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x813\xa6\x02\x00Asia/IstanbulUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01" +
-	"\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xf9l\x03\x12\xf8\x02\x00\x00\xf8\x02\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81*\xab\x02\x00Asia/IrkutskU" +
-	"T\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xdav\x19z\x98\x00\x00\x00\x98\x00\x00\x00\n\x00\x18\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\xa4\x81h\xae\x02\x00Asia/QatarUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xda" +
-	"v\x19z\x98\x00\x00\x00\x98\x00\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81D\xaf\x02\x00Asia/BahrainUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00" +
-	"\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeTʇ{_\xbb\x00\x00\x00\xbb\x00\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\"\xb0\x02\x00Asia/Yang" +
-	"onUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\x02\x95-\xad\xc4\x02\x00\x00\xc4\x02\x00\x00\f\x00\x18\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\xa4\x81\"\xb1\x02\x00Asia/YerevanUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00" +
-	"\x8fj\xbeTS\xdd\\2a\x02\x00\x00a\x02\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81,\xb4\x02\x00Asia/AlmatyUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04" +
-	"\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTΒ\x1a\x8c\xaa\x00\x00\x00\xaa\x00\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81Ҷ\x02\x00Asia/" +
-	"DiliUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT?Y\xaf\x19\xe7\x00\x00\x00\xe7\x00\x00\x00\n\x00\x18\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xbf\xb7\x02\x00Asia/DaccaUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00" +
-	"\x8ej\xbeT*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xea\xb8\x02\x00Asia/ChongqingUT\x05\x00\x03\xdc\xfc\x94bux\v" +
-	"\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTw\x86\x8d^\x03\x03\x00\x00\x03\x03\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xbb\xba\x02\x00As" +
-	"ia/Ust-NeraUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe4_P\x18\xef\x02\x00\x00\xef" +
-	"\x02\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x05\xbe\x02\x00Asia/MagadanUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01" +
-	"\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\\\x91\x87\xbb\xf7\x00\x00\x00\xf7\x00\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81:\xc1\x02\x00Asia/ColomboUT\x05\x00\x03" +
-	"\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTL\xe0\x91y\xe5\x02\x00\x00\xe5\x02\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4" +
-	"\x81w\xc2\x02\x00Asia/KrasnoyarskUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbe" +
-	"T\xf0\x9cf>\xd7\x02\x00\x00\xd7\x02\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xa6\xc5\x02\x00Asia/KamchatkaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04" +
-	"\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT`\xc9\xd4\\\xbe\x00\x00\x00\xbe\x00\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xc5\xc8\x02\x00Asia/" +
-	"Ujung_PandangUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTb\xadű\xf8\x00\x00" +
-	"\x00\xf8\x00\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xcf\xc9\x02\x00Asia/JakartaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00P" +
-	"K\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9a\x1a\xdc\xca\xdc\x00\x00\x00\xdc\x00\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\r\xcb\x02\x00Asia/KolkataUT\x05" +
-	"\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT'\xe2\\\xff\x9f\x00\x00\x00\x9f\x00\x00\x00\n\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\xa4\x81/\xcc\x02\x00Asia/KabulUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT&\xe9\xd1" +
-	"\xd8q\x02\x00\x00q\x02\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x12\xcd\x02\x00Asia/OralUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00" +
-	"PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT.>[K\xab\x00\x00\x00\xab\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xc6\xcf\x02\x00Asia/JayapuraU" +
-	"T\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTS\xa5\x81e\xf7\x00\x00\x00\xf7\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\xa4\x81\xb8\xd0\x02\x00Asia/PontianakUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8f" +
-	"j\xbeT`\xc9\xd4\\\xbe\x00\x00\x00\xbe\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xf7\xd1\x02\x00Asia/MakassarUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01" +
-	"\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeTѾ\xa8\xc7u\x02\x00\x00u\x02\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xfc\xd2\x02\x00Asia" +
-	"/TbilisiUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x06\xaa>\xa8\x00\x01\x00\x00\x00\x01\x00\x00" +
-	"\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xb7\xd5\x02\x00Asia/SingaporeUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02" +
-	"\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xff\xd6\x02\x00Asia/HarbinUT\x05\x00\x03\xdc\xfc" +
-	"\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeTB\x1d\xc6\x1b\x85\x00\x00\x00\x85\x00\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xcd" +
-	"\xd8\x02\x00Asia/KashgarUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT?Y\xaf\x19\xe7" +
-	"\x00\x00\x00\xe7\x00\x00\x00\n\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x98\xd9\x02\x00Asia/DhakaUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00P" +
-	"K\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTO\xb0\x03\xe9\xe5\x02\x00\x00\xe5\x02\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xc3\xda\x02\x00Asia/YakutskUT\x05" +
-	"\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT恸\x1e\x00\x01\x00\x00\x00\x01\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\xa4\x81\xee\xdd\x02\x00Asia/Kuala_LumpurUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00" +
-	"\x8fj\xbeT;\x7fP\x8d\xd4\a\x00\x00\xd4\a\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x819\xdf\x02\x00Asia/TehranUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04" +
-	"\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xc7\x11\xe1[\xdc\x02\x00\x00\xdc\x02\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81R\xe7\x02\x00Asia/" +
-	"BeirutUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xdb\xfa\xb5\xbeg\x02\x00\x00g\x02\x00\x00\v\x00" +
-	"\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81s\xea\x02\x00Asia/AqtobeUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00" +
-	"\x00\x00\x00\x8fj\xbeTV\xe0\xe7!\xe7\x02\x00\x00\xe7\x02\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x1f\xed\x02\x00Asia/AnadyrUT\x05\x00\x03\xdd\xfc\x94bux\v" +
-	"\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT0]*\x1bj\x02\x00\x00j\x02\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81K\xf0\x02\x00As" +
-	"ia/BishkekUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xed\x8c\xf1\x91\x85\x00\x00\x00\x85\x00" +
-	"\x00\x00\n\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xfb\xf2\x02\x00Asia/DubaiUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03" +
-	"\n\x00\x00\x00\x00\x00\x8fj\xbeT\xcfׇ\xe1\x85\x00\x00\x00\x85\x00\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xc4\xf3\x02\x00Asia/RiyadhUT\x05\x00\x03\xdd\xfc\x94b" +
-	"ux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x8a\x9a\x90\xf7\xd6\x02\x00\x00\xd6\x02\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x8e\xf4\x02" +
-	"\x00Asia/NovokuznetskUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTT\x81" +
-	"\x18G^\x02\x00\x00^\x02\x00\x00\n\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xaf\xf7\x02\x00Asia/AqtauUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_" +
-	"\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT:\x11\xea\xa2\xe5\x02\x00\x00\xe5\x02\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81Q\xfa\x02\x00Asia/OmskUT\x05" +
-	"\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTe\x1bb2w\x01\x00\x00w\x01\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\xa4\x81y\xfd\x02\x00Asia/AshkhabadUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbe" +
-	"T\x84)\r\xbd\xec\x00\x00\x00\xec\x00\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x818\xff\x02\x00Asia/SaigonUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b" +
-	"\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT)\x15II\xf3\x02\x00\x00\xf3\x02\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81i\x00\x03\x00Asia/Sak" +
-	"halinUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeTE\t\xfa-\a\x03\x00\x00\a\x03\x00\x00\x0e\x00\x18" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xa3\x03\x03\x00Asia/Hong_KongUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n" +
-	"\x00\x00\x00\x00\x00\x8fj\xbeT\x88\xf6C\x84\x98\x00\x00\x00\x98\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xf2\x06\x03\x00Asia/Phnom_PenhUT\x05\x00\x03\xdd" +
-	"\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\x03R\xda\xedU\x02\x00\x00U\x02\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81" +
-	"\xd3\a\x03\x00Asia/NicosiaUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xd7e&u" +
-	"v\x02\x00\x00v\x02\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81n\n\x03\x00Asia/BaghdadUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_" +
-	"\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xa4Zߐ\xe6\x02\x00\x00\xe6\x02\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81*\r\x03\x00Asia/Srednek" +
-	"olymskUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTe\x1bb2w\x01\x00\x00w\x01\x00\x00\r\x00" +
-	"\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\\\x10\x03\x00Asia/AshgabatUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n" +
-	"\x00\x00\x00\x00\x00\x8fj\xbeT\x8bSnT\xa1\x00\x00\x00\xa1\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x1a\x12\x03\x00Asia/KathmanduUT\x05\x00\x03\xdd\xfc" +
-	"\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x81z&\x80k\x02\x00\x00k\x02\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x03" +
-	"\x13\x03\x00Asia/ChoibalsanUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x88\xf6" +
-	"C\x84\x98\x00\x00\x00\x98\x00\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xb7\x15\x03\x00Asia/BangkokUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04" +
-	"S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x95\x16\x03\x00Asia/Chung" +
-	"kingUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT)p\x1cX\xf1\x02\x00\x00\xf1\x02\x00\x00\x10\x00\x18\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81f\x18\x03\x00Asia/NovosibirskUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03" +
-	"\n\x00\x00\x00\x00\x00\x8ej\xbeT]S\xbb\x12\xac\x03\x00\x00\xac\x03\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xa1\x1b\x03\x00Asia/FamagustaUT\x05\x00\x03\xdc" +
-	"\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeTʇ{_\xbb\x00\x00\x00\xbb\x00\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81" +
-	"\x95\x1f\x03\x00Asia/RangoonUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x84)\r\xbd" +
-	"\xec\x00\x00\x00\xec\x00\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x96 \x03\x00Asia/Ho_Chi_MinhUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b" +
-	"\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x10\x00\xedA\xcc!\x03\x00Atlantic" +
-	"/UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xb7\x0e\xbdm\xb9\x01\x00\x00\xb9\x01\x00\x00\x0e\x00\x18\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\xa4\x81\x0f\"\x03\x00Atlantic/FaroeUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00" +
-	"\x00\x8fj\xbeT\xaf|7\xb3\xde\x01\x00\x00\xde\x01\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x10$\x03\x00Atlantic/CanaryUT\x05\x00\x03\xdd\xfc\x94bu" +
-	"x\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe7\xcf^\xb0\x15\x03\x00\x00\x15\x03\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x817&\x03\x00" +
-	"Atlantic/StanleyUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTl&\x04\x99" +
-	"\x00\x04\x00\x00\x00\x04\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x96)\x03\x00Atlantic/BermudaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b" +
-	"\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x0f-\xadׄ\x00\x00\x00\x84\x00\x00\x00\x16\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xe0-\x03\x00Atlantic" +
-	"/South_GeorgiaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\xf1\b{\x87\x82\x00" +
-	"\x00\x00\x82\x00\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xb4.\x03\x00Atlantic/St_HelenaUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b" +
-	"\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xa5\x97\aĤ\x02\x00\x00\xa4\x02\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x82/\x03\x00Atlantic" +
-	"/Jan_MayenUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xb7\x0e\xbdm\xb9\x01\x00\x00\xb9\x01" +
-	"\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81r2\x03\x00Atlantic/FaeroeUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00P" +
-	"K\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTm\xbd\x10k\xf1\x02\x00\x00\xf1\x02\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81t4\x03\x00Atlantic/Reykja" +
-	"vikUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\u0097N\xad\xaf\x00\x00\x00\xaf\x00\x00\x00\x13\x00\x18\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xb17\x03\x00Atlantic/Cape_VerdeUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02" +
-	"\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe8\x8dY\x80\xad\x05\x00\x00\xad\x05\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xad8\x03\x00Atlantic/AzoresUT\x05" +
-	"\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT1)7\xad\xad\x05\x00\x00\xad\x05\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\xa4\x81\xa3>\x03\x00Atlantic/MadeiraUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8f" +
-	"j\xbeT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x18\x00\x00\x00\x00\x00\x00\x00\x10\x00\xedA\x9aD\x03\x00Australia/UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1" +
-	"\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9b\xe1\xc1\xa9\x88\x03\x00\x00\x88\x03\x00\x00\x13\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xdeD\x03\x00Austral" +
-	"ia/MelbourneUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT3\xba\xde\xd3!\x01\x00\x00" +
-	"!\x01\x00\x00\x14\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xb3H\x03\x00Australia/QueenslandUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b" +
-	"\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xc8R\x1a\x1b\xea\x00\x00\x00\xea\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\"J\x03\x00Australi" +
-	"a/NorthUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTo3\xdaR\xb4\x02\x00\x00\xb4\x02\x00\x00\x13" +
-	"\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81UK\x03\x00Australia/Lord_HoweUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00" +
-	"PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x8ff~ՙ\x03\x00\x00\x99\x03\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81VN\x03\x00Australia/Adel" +
-	"aideUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xbd\xca#\x7f\xad\x03\x00\x00\xad\x03\x00\x00\x14\x00\x18\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81;R\x03\x00Australia/YancowinnaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK" +
-	"\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9b\xe1\xc1\xa9\x88\x03\x00\x00\x88\x03\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x816V\x03\x00Australia/Victor" +
-	"iaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTX\xb9\x9ap\x88\x03\x00\x00\x88\x03\x00\x00\x12\x00\x18\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\xa4\x81\nZ\x03\x00Australia/CanberraUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03" +
-	"\n\x00\x00\x00\x00\x00\x8fj\xbeTX\xb9\x9ap\x88\x03\x00\x00\x88\x03\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xde]\x03\x00Australia/SydneyUT\x05\x00" +
-	"\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTX\xb9\x9ap\x88\x03\x00\x00\x88\x03\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\xa4\x81\xb0a\x03\x00Australia/ACTUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xa2" +
-	"ܺ\xca:\x01\x00\x00:\x01\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x7fe\x03\x00Australia/EuclaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91" +
-	"\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT3\xba\xde\xd3!\x01\x00\x00!\x01\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x02g\x03\x00Austra" +
-	"lia/BrisbaneUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTE\xf2\xe6Z\xeb\x03\x00\x00" +
-	"\xeb\x03\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81oh\x03\x00Australia/TasmaniaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04" +
-	"S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTE\xf2\xe6Z\xeb\x03\x00\x00\xeb\x03\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xa6l\x03\x00Australia/" +
-	"HobartUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTϻ\xca\x1a2\x01\x00\x002\x01\x00\x00\x0f\x00" +
-	"\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xdbp\x03\x00Australia/PerthUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e" +
-	"\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x8ff~ՙ\x03\x00\x00\x99\x03\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81Vr\x03\x00Australia/SouthUT\x05\x00" +
-	"\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT?\x95\xbd\x12E\x01\x00\x00E\x01\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\xa4\x818v\x03\x00Australia/LindemanUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00" +
-	"\x8fj\xbeT\xc8R\x1a\x1b\xea\x00\x00\x00\xea\x00\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xc9w\x03\x00Australia/DarwinUT\x05\x00\x03\xdd\xfc\x94bu" +
-	"x\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTϻ\xca\x1a2\x01\x00\x002\x01\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xfdx\x03\x00" +
-	"Australia/WestUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTo3\xdaR\xb4\x02" +
-	"\x00\x00\xb4\x02\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81wz\x03\x00Australia/LHIUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01" +
-	"\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTX\xb9\x9ap\x88\x03\x00\x00\x88\x03\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81r}\x03\x00Australia/NSW" +
-	"UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xbd\xca#\x7f\xad\x03\x00\x00\xad\x03\x00\x00\x15\x00\x18\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\xa4\x81A\x81\x03\x00Australia/Broken_HillUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e" +
-	"\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTE\xf2\xe6Z\xeb\x03\x00\x00\xeb\x03\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81=\x85\x03\x00Australia/CurrieUT\x05" +
-	"\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x18\x00\x00\x00\x00\x00\x00\x00\x10" +
-	"\x00\xedAr\x89\x03\x00Brazil/UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xb7-2f\xe4\x01" +
-	"\x00\x00\xe4\x01\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xb3\x89\x03\x00Brazil/DeNoronhaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04" +
-	"S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTg\xf5K\x89\xa2\x01\x00\x00\xa2\x01\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xe1\x8b\x03\x00Brazil/Acr" +
-	"eUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9d?\xdfڸ\x03\x00\x00\xb8\x03\x00\x00\v\x00\x18\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\xa4\x81ȍ\x03\x00Brazil/EastUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj" +
-	"\xbeTa\xcb'\xe9\x9c\x01\x00\x00\x9c\x01\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81ő\x03\x00Brazil/WestUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1" +
-	"\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe6\x9aM\xbem\x02\x00\x00m\x02\x00\x00\x03\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xa6\x93\x03\x00CETUT\x05\x00" +
-	"\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT<\x8b\x99\x1e\xb7\x03\x00\x00\xb7\x03\x00\x00\a\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\xa4\x81P\x96\x03\x00CST6CDTUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\a\x00\x18\x00\x00\x00\x00\x00\x00\x00\x10\x00\xedAH\x9a\x03\x00Canada/UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03" +
-	"\n\x00\x00\x00\x00\x00\x8fj\xbeT):\x17-\x88\x06\x00\x00\x88\x06\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x89\x9a\x03\x00Canada/AtlanticUT\x05\x00\x03" +
-	"\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTU9#\xbe2\x05\x00\x002\x05\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4" +
-	"\x81Z\xa1\x03\x00Canada/PacificUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xd3" +
-	"\xbf\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81Ԧ\x03\x00Canada/EasternUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1" +
-	"\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xc1Ȇ\x90\x05\x04\x00\x00\x05\x04\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81ѭ\x03\x00Canada/" +
-	"YukonUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\u0096dK~\x02\x00\x00~\x02\x00\x00\x13\x00\x18" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x1c\xb2\x03\x00Canada/SaskatchewanUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK" +
-	"\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT~\xb2\x0e\x19V\a\x00\x00V\a\x00\x00\x13\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xe7\xb4\x03\x00Canada/Newfoundl" +
-	"andUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT?_p\x99\x0e\x05\x00\x00\x0e\x05\x00\x00\x0e\x00\x18\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x8a\xbc\x03\x00Canada/CentralUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00" +
-	"\x00\x00\x00\x8fj\xbeT{\a\a\xdc\xca\x03\x00\x00\xca\x03\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xe0\xc1\x03\x00Canada/MountainUT\x05\x00\x03\xdd\xfc\x94" +
-	"bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x18\x00\x00\x00\x00\x00\x00\x00\x10\x00\xedA\xf3\xc5" +
-	"\x03\x00Chile/UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xee\xd0\x1cYN\x04\x00\x00N\x04\x00\x00" +
-	"\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x813\xc6\x03\x00Chile/EasterIslandUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00" +
-	"PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTC\x1a\xec\xee\x02\x05\x00\x00\x02\x05\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xcd\xca\x03\x00Chile/Continen" +
-	"talUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\a\x1c\x9e\x9a]\x04\x00\x00]\x04\x00\x00\x04\x00\x18\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x1a\xd0\x03\x00CubaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT`l\x8d" +
-	"~\xf1\x01\x00\x00\xf1\x01\x00\x00\x03\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xb5\xd4\x03\x00EETUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03" +
-	"\n\x00\x00\x00\x00\x00\x8fj\xbeTtX\xbe\xe4o\x00\x00\x00o\x00\x00\x00\x03\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xe3\xd6\x03\x00ESTUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1" +
-	"\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe7/\xebT\xb7\x03\x00\x00\xb7\x03\x00\x00\a\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x8f\xd7\x03\x00EST5EDT" +
-	"UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\x12tnj\xfc\x04\x00\x00\xfc\x04\x00\x00\x05\x00\x18\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\xa4\x81\x87\xdb\x03\x00EgyptUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9a\v\xf9/\xd8" +
-	"\x05\x00\x00\xd8\x05\x00\x00\x04\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xc2\xe0\x03\x00EireUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n" +
-	"\x00\x00\x00\x00\x00\x8fj\xbeT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x18\x00\x00\x00\x00\x00\x00\x00\x10\x00\xedA\xd8\xe6\x03\x00Etc/UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1" +
-	"\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xd9|\xbd7s\x00\x00\x00s\x00\x00\x00\n\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x16\xe7\x03\x00Etc/GMT" +
-	"-10UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe5\xf38cr\x00\x00\x00r\x00\x00\x00\n\x00\x18\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xcd\xe7\x03\x00Etc/GMT+12UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8f" +
-	"j\xbeT\xb2\xab\xd1Is\x00\x00\x00s\x00\x00\x00\n\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x83\xe8\x03\x00Etc/GMT-11UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1" +
-	"\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81:\xe9\x03\x00Etc/Uni" +
-	"versalUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTP\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\r\x00" +
-	"\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xf0\xe9\x03\x00Etc/GreenwichUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n" +
-	"\x00\x00\x00\x00\x00\x8fj\xbeTj\xd5d\xb0r\x00\x00\x00r\x00\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xa6\xea\x03\x00Etc/GMT-6UT\x05\x00\x03\xdd\xfc\x94bux\v" +
-	"\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xf7\x1ac\xc3r\x00\x00\x00r\x00\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81[\xeb\x03\x00Et" +
-	"c/GMT-1UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xc5\x18\xb6\xfbr\x00\x00\x00r\x00\x00\x00\t" +
-	"\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x10\xec\x03\x00Etc/GMT-8UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00" +
-	"\x00\x00\x8fj\xbeT\xd0\xfaFDq\x00\x00\x00q\x00\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xc5\xec\x03\x00Etc/GMT+4UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04" +
-	"\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTe\xcb\xe9Qq\x00\x00\x00q\x00\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81y\xed\x03\x00Etc/G" +
-	"MT+3UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xfc\x19@\xb9r\x00\x00\x00r\x00\x00\x00\t\x00\x18\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81-\xee\x03\x00Etc/GMT-9UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8f" +
-	"j\xbeTP\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xe2\xee\x03\x00Etc/GMT-0UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b" +
-	"\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTJ0p-r\x00\x00\x00r\x00\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x94\xef\x03\x00Etc/GMT-" +
-	"7UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xa9{\xa2qq\x00\x00\x00q\x00\x00\x00\t\x00\x18\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\xa4\x81I\xf0\x03\x00Etc/GMT+2UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT" +
-	"\xd4X\x9b\xf3q\x00\x00\x00q\x00\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xfd\xf0\x03\x00Etc/GMT+5UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S" +
-	"_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTP\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\a\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xb1\xf1\x03\x00Etc/GMTUT\x05\x00" +
-	"\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\b\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\xa4\x81a\xf2\x03\x00Etc/ZuluUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT)\xb9\xbe\x9dr\x00" +
-	"\x00\x00r\x00\x00\x00\n\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x12\xf3\x03\x00Etc/GMT+11UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK" +
-	"\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x90`N\xe8s\x00\x00\x00s\x00\x00\x00\n\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xc8\xf3\x03\x00Etc/GMT-13UT\x05\x00\x03\xdd" +
-	"\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT,{\xdc;s\x00\x00\x00s\x00\x00\x00\n\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81" +
-	"\x7f\xf4\x03\x00Etc/GMT-14UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x8e\x1569r\x00" +
-	"\x00\x00r\x00\x00\x00\n\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x816\xf5\x03\x00Etc/GMT+10UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK" +
-	"\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xf7\x19s\x81s\x00\x00\x00s\x00\x00\x00\n\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xec\xf5\x03\x00Etc/GMT-12UT\x05\x00\x03\xdd" +
-	"\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTP\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\b\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81" +
-	"\xa3\xf6\x03\x00Etc/GMT0UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9f.\xe4xo\x00\x00\x00" +
-	"o\x00\x00\x00\a\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81T\xf7\x03\x00Etc/UCTUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n" +
-	"\x00\x00\x00\x00\x00\x8fj\xbeTP\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x04\xf8\x03\x00Etc/GMT+0UT\x05\x00\x03\xdd\xfc\x94bux\v" +
-	"\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x84+\x9a$q\x00\x00\x00q\x00\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xb6\xf8\x03\x00Et" +
-	"c/GMT+7UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x84\x19\xb3\tq\x00\x00\x00q\x00\x00\x00\t" +
-	"\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81j\xf9\x03\x00Etc/GMT+9UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00" +
-	"\x00\x00\x8fj\xbeT\xbc\x19y\x04r\x00\x00\x00r\x00\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x1e\xfa\x03\x00Etc/GMT-2UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04" +
-	"\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT!\xd6~wr\x00\x00\x00r\x00\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xd3\xfa\x03\x00Etc/G" +
-	"MT-5UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\"\xf8\x8f/q\x00\x00\x00q\x00\x00\x00\t\x00\x18\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x88\xfb\x03\x00Etc/GMT+8UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8f" +
-	"j\xbeTH\x9b\xd1\x04q\x00\x00\x00q\x00\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81<\xfc\x03\x00Etc/GMT+6UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b" +
-	"\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT5\xb8\xe8\x86q\x00\x00\x00q\x00\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xf0\xfc\x03\x00Etc/GMT+" +
-	"1UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\a\x00\x18\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\xa4\x81\xa4\xfd\x03\x00Etc/UTCUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTk\x19" +
-	"<Qr\x00\x00\x00r\x00\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81T\xfe\x03\x00Etc/GMT-4UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01" +
-	"\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9c\xfcm\x99r\x00\x00\x00r\x00\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\t\xff\x03\x00Etc/GMT-3UT\x05\x00" +
-	"\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x18\x00\x00\x00\x00\x00\x00\x00\x10\x00" +
-	"\xedA\xbe\xff\x03\x00Europe/UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTDd#\xc4\xf1\x01\x00" +
-	"\x00\xf1\x01\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xff\xff\x03\x00Europe/ZurichUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00" +
-	"PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xc7\xf5\x94\xdaQ\x04\x00\x00Q\x04\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x817\x02\x04\x00Europe/ParisUT" +
-	"\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe1\xc1\xeb\x05\x8c\x03\x00\x00\x8c\x03\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\xa4\x81\xce\x06\x04\x00Europe/MoscowUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbe" +
-	"TM\xe5\xa9 ?\x04\x00\x00?\x04\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xa1\n\x04\x00Europe/LuxembourgUT\x05\x00\x03\xdd\xfc\x94bux\v" +
-	"\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81+\x0f\x04\x00Eu" +
-	"rope/LjubljanaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe5\xc8X\xa7\xe1\x01" +
-	"\x00\x00\xe1\x01\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81S\x11\x04\x00Europe/HelsinkiUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S" +
-	"_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTWI\xc3\x7f(\x03\x00\x00(\x03\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81}\x13\x04\x00Europe/Mins" +
-	"kUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\r\x00\x18\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\xa4\x81\xeb\x16\x04\x00Europe/SkopjeUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00" +
-	"\x8fj\xbeT\x9a\v\xf9/\xd8\x05\x00\x00\xd8\x05\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x10\x19\x04\x00Europe/DublinUT\x05\x00\x03\xdd\xfc\x94bux\v\x00" +
-	"\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTk\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81/\x1f\x04\x00Eur" +
-	"ope/JerseyUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x95\xb4\x9e\xe7\xb3\x03\x00\x00\xb3\x03" +
-	"\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xb5%\x04\x00Europe/San_MarinoUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01" +
-	"\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT==\xa4\x16\xc4\x04\x00\x00\xc4\x04\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xb3)\x04\x00Europe/Gibral" +
-	"tarUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\x0f\x00\x18\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xc1.\x04\x00Europe/BelgradeUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00" +
-	"\x00\x00\x00\x00\x8fj\xbeTk\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xe80\x04\x00Europe/GuernseyUT\x05\x00\x03\xdd\xfc" +
-	"\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTu\xb0\xcd\xfc\xf8\x02\x00\x00\xf8\x02\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81p" +
-	"7\x04\x00Europe/UlyanovskUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x1b" +
-	"8\xfel\xd6\x02\x00\x00\xd6\x02\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xb2:\x04\x00Europe/SaratovUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1" +
-	"\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTDd#\xc4\xf1\x01\x00\x00\xf1\x01\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xd0=\x04\x00Europe/" +
-	"VaduzUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\aW\x10Ѱ\x04\x00\x00\xb0\x04\x00\x00\x0f\x00\x18" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\a@\x04\x00Europe/IstanbulUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03" +
-	"\n\x00\x00\x00\x00\x00\x8fj\xbeT&S\x03\t\xae\x05\x00\x00\xae\x05\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x00E\x04\x00Europe/LisbonUT\x05\x00\x03\xdd\xfc" +
-	"\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xda\xc0\x86\xd2\x1b\x02\x00\x00\x1b\x02\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xf5" +
-	"J\x04\x00Europe/UzhgorodUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe0\xfe" +
-	"\x83\xe5\xcd\x02\x00\x00\xcd\x02\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81YM\x04\x00Europe/KirovUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04" +
-	"S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xea\xc48\xde\\\x02\x00\x00\\\x02\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81lP\x04\x00Europe/Tir" +
-	"aneUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTI\xb8\xbc\xd3\xf3\x02\x00\x00\xf3\x02\x00\x00\x0f\x00\x18\x00\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x0fS\x04\x00Europe/TiraspolUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00" +
-	"\x00\x00\x00\x00\x8fj\xbeT\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81KV\x04\x00Europe/SarajevoUT\x05\x00\x03\xdd\xfc" +
-	"\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTZk#V\x81\x03\x00\x00\x81\x03\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81r" +
-	"X\x04\x00Europe/MadridUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe1C\xf9\xa1" +
-	"\xde\x01\x00\x00\xde\x01\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81:\\\x04\x00Europe/PodgoricaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b" +
-	"\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTDd#\xc4\xf1\x01\x00\x00\xf1\x01\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81b^\x04\x00Europe/B" +
-	"usingenUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x95\xb4\x9e\xe7\xb3\x03\x00\x00\xb3\x03\x00\x00\x0e" +
-	"\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x9c`\x04\x00Europe/VaticanUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e" +
-	"\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTk\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x97d\x04\x00Europe/BelfastUT\x05\x00\x03" +
-	"\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTIo\x11{\xd3\x02\x00\x00\xd3\x02\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4" +
-	"\x81\x1ek\x04\x00Europe/BratislavaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj" +
-	"\xbeTiS\x18D.\x02\x00\x00.\x02\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81<n\x04\x00Europe/KievUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1" +
-	"\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTO+j\x94\x88\x03\x00\x00\x88\x03\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xafp\x04\x00Europe/" +
-	"KaliningradUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xfc\xbe\xb5\xac9\x02\x00\x009" +
-	"\x02\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x83t\x04\x00Europe/ZaporozhyeUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_" +
-	"\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTZ\x05wג\x02\x00\x00\x92\x02\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\aw\x04\x00Europe/Vienn" +
-	"aUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe6Kf\xab\xfe\x02\x00\x00\xfe\x02\x00\x00\x0f\x00\x18\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\xa4\x81\xe0y\x04\x00Europe/BudapestUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00" +
-	"\x00\x00\x8fj\xbeT\xccb\xf72\xa4\x02\x00\x00\xa4\x02\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81'}\x04\x00Europe/VilniusUT\x05\x00\x03\xdd\xfc\x94bu" +
-	"x\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTn\x81\xf4\xd7Z\x04\x00\x00Z\x04\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x13\x80\x04\x00" +
-	"Europe/MonacoUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xa5\x97\aĤ\x02\x00" +
-	"\x00\xa4\x02\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xb4\x84\x04\x00Europe/OsloUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK" +
-	"\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT]i\x11u\xd6\x02\x00\x00\xd6\x02\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x9d\x87\x04\x00Europe/Astrakhan" +
-	"UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x11\xda\x1d\xd5a\x03\x00\x00a\x03\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\xa4\x81\xbd\x8a\x04\x00Europe/SimferopolUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00" +
-	"\x00\x00\x00\x8fj\xbeTVa\x92\xd3\xdf\x02\x00\x00\xdf\x02\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81i\x8e\x04\x00Europe/VolgogradUT\x05\x00\x03\xdd\xfc" +
-	"\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTk\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x92" +
-	"\x91\x04\x00Europe/Isle_of_ManUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbe" +
-	"Tk\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x1d\x98\x04\x00Europe/LondonUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91" +
-	"\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTgp\xc0\xa7\xb6\x02\x00\x00\xb6\x02\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xa3\x9e\x04\x00Europe" +
-	"/RigaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTߜvυ\x01\x00\x00\x85\x01\x00\x00\x0e\x00\x18" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x9e\xa1\x04\x00Europe/AndorraUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n" +
-	"\x00\x00\x00\x00\x00\x8fj\xbeTIo\x11{\xd3\x02\x00\x00\xd3\x02\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81k\xa3\x04\x00Europe/PragueUT\x05\x00\x03\xdd\xfc\x94" +
-	"bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x17S\x91\xb3\xc1\x02\x00\x00\xc1\x02\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x85\xa6" +
-	"\x04\x00Europe/BerlinUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTq\x16\x9b?\xa3" +
-	"\x02\x00\x00\xa3\x02\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x8d\xa9\x04\x00Europe/TallinnUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S" +
-	"_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x95\xb4\x9e\xe7\xb3\x03\x00\x00\xb3\x03\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81x\xac\x04\x00Europe/Rome" +
-	"UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTh\xa5J[\xa0\x03\x00\x00\xa0\x03\x00\x00\f\x00\x18\x00\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\xa4\x81p\xb0\x04\x00Europe/MaltaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj" +
-	"\xbeT\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81V\xb4\x04\x00Europe/ZagrebUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04" +
-	"\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xc9\a\xa0\xe1/\x04\x00\x00/\x04\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81{\xb6\x04\x00Europ" +
-	"e/AmsterdamUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\x03R\xda\xedU\x02\x00\x00U" +
-	"\x02\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xf4\xba\x04\x00Europe/NicosiaUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00P" +
-	"K\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x90\xa9\xf5ϕ\x02\x00\x00\x95\x02\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x91\xbd\x04\x00Europe/Buchares" +
-	"tUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x92\xfc\f+o\x02\x00\x00o\x02\x00\x00\x11\x00\x18\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\xa4\x81p\xc0\x04\x00Europe/CopenhagenUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00" +
-	"\x00\x00\x00\x00\x8fj\xbeTI\xb8\xbc\xd3\xf3\x02\x00\x00\xf3\x02\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81*\xc3\x04\x00Europe/ChisinauUT\x05\x00\x03\xdd\xfc" +
-	"\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe5\xc8X\xa7\xe1\x01\x00\x00\xe1\x01\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81f" +
-	"\xc6\x04\x00Europe/MariehamnUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x8c" +
-	"\xc8\x15\xd0P\x02\x00\x00P\x02\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x91\xc8\x04\x00Europe/SofiaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00" +
-	"\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xcb*j\x8f\xaa\x02\x00\x00\xaa\x02\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81'\xcb\x04\x00Europe/At" +
-	"hensUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xd9L\xf6\xf7\xf1\x01\x00\x00\xf1\x01\x00\x00\x10\x00\x18\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x18\xce\x04\x00Europe/StockholmUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03" +
-	"\n\x00\x00\x00\x00\x00\x8fj\xbeT\x95\x7fpp\xdc\x02\x00\x00\xdc\x02\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81S\xd0\x04\x00Europe/SamaraUT\x05\x00\x03\xdd\xfc" +
-	"\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTo\xbc\x831O\x04\x00\x00O\x04\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81v" +
-	"\xd3\x04\x00Europe/BrusselsUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT>\xfe" +
-	"垛\x03\x00\x00\x9b\x03\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x0e\xd8\x04\x00Europe/WarsawUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00" +
-	"\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xab\x80c$q\x00\x00\x00q\x00\x00\x00\a\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xf0\xdb\x04\x00FactoryUT" +
-	"\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTk\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\x02\x00\x18\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\xa4\x81\xa2\xdc\x04\x00GBUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTk\xa4,\xb6?\x06\x00\x00?\x06" +
-	"\x00\x00\a\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x1d\xe3\x04\x00GB-EireUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00" +
-	"\x00\x00\x00\x8fj\xbeTP\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\x03\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x9d\xe9\x04\x00GMTUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04" +
-	"S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTP\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\x05\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81I\xea\x04\x00GMT+0UT\x05\x00\x03" +
-	"\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTP\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\x05\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4" +
-	"\x81\xf7\xea\x04\x00GMT-0UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTP\xda\xfa\x03o\x00\x00\x00o\x00" +
-	"\x00\x00\x04\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xa5\xeb\x04\x00GMT0UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00" +
-	"\x8fj\xbeTP\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81R\xec\x04\x00GreenwichUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1" +
-	"\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT=\xf7\xfawp\x00\x00\x00p\x00\x00\x00\x03\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x04\xed\x04\x00HSTUT\x05\x00" +
-	"\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeTE\t\xfa-\a\x03\x00\x00\a\x03\x00\x00\b\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\xa4\x81\xb1\xed\x04\x00HongkongUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTm\xbd\x10k\xf1\x02" +
-	"\x00\x00\xf1\x02\x00\x00\a\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xfa\xf0\x04\x00IcelandUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e" +
-	"\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x18\x00\x00\x00\x00\x00\x00\x00\x10\x00\xedA,\xf4\x04\x00Indian/UT\x05\x00\x03\xdd\xfc\x94bux\v" +
-	"\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\x96\xed=\x98\xb3\x00\x00\x00\xb3\x00\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81m\xf4\x04\x00In" +
-	"dian/MauritiusUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeTx\xb0W\x14\x98\x00" +
-	"\x00\x00\x98\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81j\xf5\x04\x00Indian/ChagosUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01" +
-	"\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81I\xf6\x04\x00Indian/Mayott" +
-	"eUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT$l=҅\x00\x00\x00\x85\x00\x00\x00\x10\x00\x18\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\xa4\x81P\xf7\x04\x00Indian/ChristmasUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00" +
-	"\x00\x00\x00\x8fj\xbeTͲ\xfb\xf6\x8c\x00\x00\x00\x8c\x00\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x1f\xf8\x04\x00Indian/CocosUT\x05\x00\x03\xdd\xfc\x94bux" +
-	"\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xb9\xb2Z\xac\x98\x00\x00\x00\x98\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xf1\xf8\x04\x00I" +
-	"ndian/MaldivesUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\xb4\x8d\x98ƿ\x00" +
-	"\x00\x00\xbf\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xd2\xf9\x04\x00Indian/ComoroUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01" +
-	"\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeTy(\xb6\x8f\x85\x00\x00\x00\x85\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xd8\xfa\x04\x00Indian/Reunio" +
-	"nUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeTa\x85jo\x85\x00\x00\x00\x85\x00\x00\x00\v\x00\x18\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\xa4\x81\xa5\xfb\x04\x00Indian/MaheUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej" +
-	"\xbeT\xb8K\xabυ\x00\x00\x00\x85\x00\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81o\xfc\x04\x00Indian/KerguelenUT\x05\x00\x03\xdc\xfc\x94bux\v" +
-	"\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\x13\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81>\xfd\x04\x00In" +
-	"dian/AntananarivoUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT;\x7fP" +
-	"\x8d\xd4\a\x00\x00\xd4\a\x00\x00\x04\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81J\xfe\x04\x00IranUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e" +
-	"\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x17✳2\x04\x00\x002\x04\x00\x00\x06\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\\\x06\x05\x00IsraelUT\x05\x00\x03\xdd\xfc\x94bux\v\x00" +
-	"\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT%J\xd5\xebS\x01\x00\x00S\x01\x00\x00\a\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xce\n\x05\x00Jam" +
-	"aicaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x02\xf4\xaeg\xd5\x00\x00\x00\xd5\x00\x00\x00\x05\x00\x18\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81b\f\x05\x00JapanUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xf6" +
-	"\xe8]*\xdb\x00\x00\x00\xdb\x00\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81v\r\x05\x00KwajaleinUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_" +
-	"\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT_\x7f2[\xaf\x01\x00\x00\xaf\x01\x00\x00\x05\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x94\x0e\x05\x00LibyaUT\x05\x00\x03\xdc\xfc" +
-	"\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xfe\x9d\x1b\xc9m\x02\x00\x00m\x02\x00\x00\x03\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x82" +
-	"\x10\x05\x00METUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xf5\x8d\x99\x92o\x00\x00\x00o\x00\x00\x00\x03\x00" +
-	"\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81,\x13\x05\x00MSTUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe6" +
-	"h\xcac\xb7\x03\x00\x00\xb7\x03\x00\x00\a\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xd8\x13\x05\x00MST7MDTUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00" +
-	"PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x18\x00\x00\x00\x00\x00\x00\x00\x10\x00\xedA\xd0\x17\x05\x00Mexico/UT\x05\x00\x03\xdd\xfc" +
-	"\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xd0v\x01\x8a\x01\x04\x00\x00\x01\x04\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x11" +
-	"\x18\x05\x00Mexico/BajaNorteUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xd6" +
-	"\xe1Հ\x9c\x01\x00\x00\x9c\x01\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\\\x1c\x05\x00Mexico/GeneralUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1" +
-	"\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT8\xcdZ\x05o\x01\x00\x00o\x01\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81@\x1e\x05\x00Mexico/" +
-	"BajaSurUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTb\xb2\xaf\xf7\x13\x04\x00\x00\x13\x04\x00\x00\x02" +
-	"\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xf7\x1f\x05\x00NZUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x96" +
-	"\xc5FF(\x03\x00\x00(\x03\x00\x00\a\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81F$\x05\x00NZ-CHATUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00" +
-	"PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTV\x80\x94@\x12\x04\x00\x00\x12\x04\x00\x00\x06\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xaf'\x05\x00NavajoUT\x05\x00\x03\xdd\xfc\x94" +
-	"bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8ej\xbeT*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00\x00\x03\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x01," +
-	"\x05\x00PRCUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTŭV\xad\xb7\x03\x00\x00\xb7\x03\x00\x00\a\x00\x18" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xc7-\x05\x00PST8PDTUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj" +
-	"\xbeT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x18\x00\x00\x00\x00\x00\x00\x00\x10\x00\xedA\xbf1\x05\x00Pacific/UT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04" +
-	"S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTn\x04\x19y\x9a\x00\x00\x00\x9a\x00\x00\x00\x14\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x012\x05\x00Pacific/Po" +
-	"rt_MoresbyUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xcc\xf39a\xc3\x00\x00\x00\xc3\x00" +
-	"\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xe92\x05\x00Pacific/ChuukUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01" +
-	"\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xee\xd0\x1cYN\x04\x00\x00N\x04\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xf33\x05\x00Pacific/EasterUT\x05" +
-	"\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xf6\xe8]*\xdb\x00\x00\x00\xdb\x00\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\xa4\x81\x898\x05\x00Pacific/KwajaleinUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00" +
-	"\x8fj\xbeT\x97F\x91\xb3\xed\x00\x00\x00\xed\x00\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xaf9\x05\x00Pacific/TongatapuUT\x05\x00\x03\xdd\xfc\x94b" +
-	"ux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xcc\xf39a\xc3\x00\x00\x00\xc3\x00\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xe7:\x05" +
-	"\x00Pacific/YapUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT1\xce_(\x86\x00\x00\x00" +
-	"\x86\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xef;\x05\x00Pacific/WallisUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00" +
-	"PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xa8A\x15\xfe\x97\x01\x00\x00\x97\x01\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xbd<\x05\x00Pacific/ApiaUT" +
-	"\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTY5\x1a6\xf7\x00\x00\x00\xf7\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\xa4\x81\x9a>\x05\x00Pacific/NorfolkUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8f" +
-	"j\xbeT\x9e\x7f\xab\x95V\x01\x00\x00V\x01\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xda?\x05\x00Pacific/EfateUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01" +
-	"\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTcF/.\xac\x01\x00\x00\xac\x01\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81wA\x05\x00Paci" +
-	"fic/FijiUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTa\vೆ\x00\x00\x00\x86\x00\x00\x00" +
-	"\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81iC\x05\x00Pacific/FunafutiUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK" +
-	"\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x80\xf8vܔ\x00\x00\x00\x94\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x819D\x05\x00Pacific/PalauUT\x05" +
-	"\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTFI\xfe\x14^\x01\x00\x00^\x01\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\xa4\x81\x14E\x05\x00Pacific/GuamUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTF" +
-	"I\xfe\x14^\x01\x00\x00^\x01\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xb8F\x05\x00Pacific/SaipanUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1" +
-	"\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x97n7\x1a\xf2\x00\x00\x00\xf2\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81^H\x05\x00Pacific" +
-	"/KosraeUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x91\xd60\f\x9a\x00\x00\x00\x9a\x00\x00\x00\f" +
-	"\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x98I\x05\x00Pacific/NiueUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n" +
-	"\x00\x00\x00\x00\x00\x8fj\xbeT\u07b54-\xd6\x00\x00\x00\xd6\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81xJ\x05\x00Pacific/PonapeUT\x05\x00\x03\xdd\xfc" +
-	"\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT߃\xa0_\x86\x00\x00\x00\x86\x00\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x96" +
-	"K\x05\x00Pacific/WakeUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x81\xe3w\n\xaf" +
-	"\x00\x00\x00\xaf\x00\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81bL\x05\x00Pacific/GalapagosUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b" +
-	"\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xeaK\x85v\xdd\x00\x00\x00\xdd\x00\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\\M\x05\x00Pacific/" +
-	"JohnstonUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTt\xca{e\x92\x00\x00\x00\x92\x00\x00\x00" +
-	"\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x83N\x05\x00Pacific/MidwayUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02" +
-	"\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe2;Z\xf7\xb7\x00\x00\x00\xb7\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81]O\x05\x00Pacific/NauruUT\x05\x00\x03" +
-	"\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTY\xd2K|\x86\x00\x00\x00\x86\x00\x00\x00\x13\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4" +
-	"\x81[P\x05\x00Pacific/GuadalcanalUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00" +
-	"\x8fj\xbeT\x96\xc5FF(\x03\x00\x00(\x03\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81.Q\x05\x00Pacific/ChathamUT\x05\x00\x03\xdd\xfc\x94bux" +
-	"\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTb\xb2\xaf\xf7\x13\x04\x00\x00\x13\x04\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x9fT\x05\x00P" +
-	"acific/AucklandUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xb7\xef\x97\xc6\xc6" +
-	"\x00\x00\x00\xc6\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xfcX\x05\x00Pacific/NoumeaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S" +
-	"_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x8a|\xdcU\x99\x00\x00\x00\x99\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\nZ\x05\x00Pacific/Fak" +
-	"aofoUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xea\xc1\xdaυ\x00\x00\x00\x85\x00\x00\x00\x0e\x00\x18\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xecZ\x05\x00Pacific/TahitiUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00" +
-	"\x00\x00\x00\x00\x8fj\xbeT\xc23\xa0\xbc\x84\x00\x00\x00\x84\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xb9[\x05\x00Pacific/GambierUT\x05\x00\x03\xdd\xfc" +
-	"\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xca\"\xb8i\xda\x00\x00\x00\xda\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x86" +
-	"\\\x05\x00Pacific/MajuroUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xeaK\x85" +
-	"v\xdd\x00\x00\x00\xdd\x00\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xa8]\x05\x00Pacific/HonoluluUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1" +
-	"\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\u07b54-\xd6\x00\x00\x00\xd6\x00\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xcf^\x05\x00Pacific" +
-	"/PohnpeiUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTt\xca{e\x92\x00\x00\x00\x92\x00\x00\x00" +
-	"\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xee_\x05\x00Pacific/Pago_PagoUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00P" +
-	"K\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xcc\xf39a\xc3\x00\x00\x00\xc3\x00\x00\x00\f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xcb`\x05\x00Pacific/TrukUT\x05" +
-	"\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xfa\x0fA\x05\x99\x00\x00\x00\x99\x00\x00\x00\x10\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\xa4\x81\xd4a\x05\x00Pacific/PitcairnUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8f" +
-	"j\xbeTD6\x83\xa1\x8b\x00\x00\x00\x8b\x00\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xb7b\x05\x00Pacific/MarquesasUT\x05\x00\x03\xdd\xfc\x94bu" +
-	"x\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xec =\x89\xac\x00\x00\x00\xac\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x8dc\x05\x00" +
-	"Pacific/KantonUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9a\xf2:F\xc9\x00" +
-	"\x00\x00\xc9\x00\x00\x00\x14\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x81d\x05\x00Pacific/BougainvilleUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91" +
-	"\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT6\xb7S{\x86\x00\x00\x00\x86\x00\x00\x00\x0e\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x98e\x05\x00Pacifi" +
-	"c/TarawaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x1c\xe3\xa3S\x96\x01\x00\x00\x96\x01\x00\x00" +
-	"\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81ff\x05\x00Pacific/RarotongaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00P" +
-	"K\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTt\xca{e\x92\x00\x00\x00\x92\x00\x00\x00\r\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81Gh\x05\x00Pacific/SamoaUT" +
-	"\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xc8=ku\xae\x00\x00\x00\xae\x00\x00\x00\x12\x00\x18\x00\x00\x00\x00\x00\x00\x00" +
-	"\x00\x00\xa4\x81 i\x05\x00Pacific/KiritimatiUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00" +
-	"\x00\x00\x8fj\xbeT\xec =\x89\xac\x00\x00\x00\xac\x00\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x1aj\x05\x00Pacific/EnderburyUT\x05\x00\x03\xdd\xfc" +
-	"\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT>\xfe垛\x03\x00\x00\x9b\x03\x00\x00\x06\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x11" +
-	"k\x05\x00PolandUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT&S\x03\t\xae\x05\x00\x00\xae\x05\x00" +
-	"\x00\b\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xecn\x05\x00PortugalUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00" +
-	"\x00\x00\x00\x8ej\xbeT\xee\xf0BB\xff\x01\x00\x00\xff\x01\x00\x00\x03\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xdct\x05\x00ROCUT\x05\x00\x03\xdc\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04" +
-	"S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xc7X,Y\x9f\x01\x00\x00\x9f\x01\x00\x00\x03\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x18w\x05\x00ROKUT\x05\x00\x03\xdd\xfc" +
-	"\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x06\xaa>\xa8\x00\x01\x00\x00\x00\x01\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xf4" +
-	"x\x05\x00SingaporeUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\aW\x10Ѱ\x04\x00\x00" +
-	"\xb0\x04\x00\x00\x06\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x817z\x05\x00TurkeyUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00" +
-	"\x00\x00\x00\x00\x8fj\xbeT\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\x03\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81'\x7f\x05\x00UCTUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00" +
-	"\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x18\x00\x00\x00\x00\x00\x00\x00\x10\x00\xedA\xd3\x7f\x05\x00US/UT\x05\x00\x03\xdd" +
-	"\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT5\x11Q\x06\xd1\x03\x00\x00\xd1\x03\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81" +
-	"\x10\x80\x05\x00US/AlaskaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xf6\"\x12\xfe\x0e\x05\x00" +
-	"\x00\x0e\x05\x00\x00\n\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81$\x84\x05\x00US/PacificUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01" +
-	"\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT3\x9aG\xc8\xd0\x06\x00\x00\xd0\x06\x00\x00\n\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81v\x89\x05\x00US/EasternUT\x05\x00\x03\xdd\xfc" +
-	"\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT>\x14\xe7\x03\x83\x03\x00\x00\x83\x03\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x8a" +
-	"\x90\x05\x00US/MichiganUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTø\xab\x9b\xf0\x00" +
-	"\x00\x00\xf0\x00\x00\x00\n\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81R\x94\x05\x00US/ArizonaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK" +
-	"\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT$ \x873\xf8\x03\x00\x00\xf8\x03\x00\x00\x11\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x86\x95\x05\x00US/Indiana-Stark" +
-	"eUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xae,\xa44\xc9\x03\x00\x00\xc9\x03\x00\x00\v\x00\x18\x00\x00\x00\x00" +
-	"\x00\x00\x00\x00\x00\xa4\x81ə\x05\x00US/AleutianUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj" +
-	"\xbeT\xeaK\x85v\xdd\x00\x00\x00\xdd\x00\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81ם\x05\x00US/HawaiiUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00" +
-	"\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTp\xb6{\xc9\x13\x02\x00\x00\x13\x02\x00\x00\x0f\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xf7\x9e\x05\x00US/East-I" +
-	"ndianaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9bܩ=\xda\x06\x00\x00\xda\x06\x00\x00\n\x00" +
-	"\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81S\xa1\x05\x00US/CentralUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00" +
-	"\x00\x00\x8fj\xbeTV\x80\x94@\x12\x04\x00\x00\x12\x04\x00\x00\v\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81q\xa8\x05\x00US/MountainUT\x05\x00\x03\xdd\xfc\x94bux\v\x00" +
-	"\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeTt\xca{e\x92\x00\x00\x00\x92\x00\x00\x00\b\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81Ȭ\x05\x00US/" +
-	"SamoaUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\x03\x00\x18" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x9c\xad\x05\x00UTCUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9f." +
-	"\xe4xo\x00\x00\x00o\x00\x00\x00\t\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81H\xae\x05\x00UniversalUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01" +
-	"\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\xe1\xc1\xeb\x05\x8c\x03\x00\x00\x8c\x03\x00\x00\x04\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xfa\xae\x05\x00W-SUUT\x05\x00\x03\xdd\xfc\x94b" +
-	"ux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT2\x91B\xc0\xee\x01\x00\x00\xee\x01\x00\x00\x03\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81IJ\x05" +
-	"\x00WETUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x01\x02\x1e\x03\n\x00\x00\x00\x00\x00\x8fj\xbeT\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\x04\x00\x18\x00" +
-	"\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xef\xb4\x05\x00ZuluUT\x05\x00\x03\xdd\xfc\x94bux\v\x00\x01\x04\x91\xf1\b\x00\x04S_\x01\x00PK\x05\x06\x00\x00\x00\x00g\x02g\x02\xea\xc9\x00\x00\x9c\xb5" +
-	"\x05\x00\x00\x00"
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x008\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xffo\xa2_/\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9c" +
+	"ٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xa2p\x1a\x10\xff\xff\xff\xff\xa3D[\x90\xff\xff\xff\xff\xc8\tq\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff" +
+	"\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\x7fE\x10\xff\xff\xff\xff\xd3c\x1b\x90\xff\xff\xff\xff\xd4" +
+	"K#\x90\xff\xff\xff\xff\xd59\xc3\x10\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\t\x96\x10\x00\x00\x00\x00\x13M'\xf0\x00\x00\x00\x00\x143\xd0`\x00\x00\x00\x00\x15#\xeb\x90\x00" +
+	"\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c" +
+	"\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00" +
+	"\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*" +
+	"\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00\x0fQ\x00" +
+	"\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\tLMT\x00CEST\x00CET\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\xccb\xf72\xa4\x02\x00\x00\xa4\x02\x00\x00\x0e\x00\x00\x00Europe/VilniusTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x003\x00\x00\x00\t\x00\x00\x00&\xff\xff\xff\xffV\xb6\xccD\xff\xff\xff\xff\x9cO\x1fP\xff\xff\xff\xff\xa1\x85J\x98\xff\xff\xff\xff\xa2\xf10\xf0\xff\xff\xff\xff\xa3fx`\xff\xff\xff\xffȬ\xcf" +
+	"p\xff\xff\xff\xff\xcaY*\xd0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xff\xd00=\xe0\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00" +
+	"\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91" +
+	"\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00" +
+	"\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\x19\x00\x00\x00\x00\x00&\f\n\x00\x00\x00\x00\x00'\x055\x80\x00\x00\x00\x00'\xf5&\x80\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd5\b\x80\x00\x00\x00\x00*\xc4\xf9" +
+	"\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4ۀ\x00\x00\x00\x00-\x94̀\x00\x00\x00\x00.\x84\xbd\x80\x00\x00\x00\x00/t\xae\x80\x00\x00\x00\x000d\x9f\x80\x00\x00\x00\x001]\xcb\x00\x00\x00\x00" +
+	"\x002r\xa6\x00\x00\x00\x00\x003=\xad\x00\x00\x00\x00\x004R\x88\x00\x00\x00\x00\x005\x1d\x9d\x10\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd\x7f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x00>\x86A" +
+	"\x90\x01\x02\x03\x04\x03\x05\x06\x03\x06\x03\x06\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\b\x04\b\x04\b\x04\b\x04\b\x04\b\x04\b\x04\b\x04\b\x04\x06\x03\x06\x04\b\x00\x00\x17\xbc\x00\x00\x00\x00" +
+	"\x13\xb0\x00\x04\x00\x00\x16h\x00\b\x00\x00\x0e\x10\x00\f\x00\x00\x1c \x00\x10\x00\x00*0\x00\x14\x00\x00\x1c \x01\x18\x00\x008@\x01\x1d\x00\x00*0\x01!LMT\x00WMT\x00KMT\x00CE" +
+	"T\x00EET\x00MSK\x00CEST\x00MSD\x00EEST\x00\nEET-2EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00Va\x92\xd3\xdf\x02\x00\x00\xdf\x02\x00\x00\x10\x00\x00\x00Europe/VolgogradTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00A\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xf5F\xdc\xff\xff\xff\xff\xb5\xa4\vP\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\b\xcd@\x00\x00\x00\x00\x17" +
+	"\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a̅\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00" +
+	"\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\8\xe0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&" +
+	"\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x94\xbep\x00" +
+	"\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005" +
+	"\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb<p\x00" +
+	"\x00\x00\x00<\xa6Cp\x00\x00\x00\x00=\xbb\x1ep\x00\x00\x00\x00>\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f\ap\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00C" +
+	"c\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05\xadp\x00\x00\x00\x00G#\xc2\xf0\x00\x00\x00\x00G\xee\xc9\xf0\x00\x00\x00\x00I\x03\xa4\xf0\x00\x00\x00\x00IΫ\xf0\x00" +
+	"\x00\x00\x00J\xe3\x86\xf0\x00\x00\x00\x00K\xae\x8d\xf0\x00\x00\x00\x00Ḷp\x00\x00\x00\x00M\x8eo\xf0\x00\x00\x00\x00TL\x1d`\x00\x00\x00\x00[\xd4\xed\xf0\x00\x00\x00\x00_\xe7\xb2`\x01\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x01\x04\x01\x04\x01\x02\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x02\x01\x02\x01" +
+	"\x00\x00)\xa4\x00\x00\x00\x00*0\x00\x04\x00\x008@\x00\b\x00\x00FP\x01\f\x00\x008@\x01\bLMT\x00+03\x00+04\x00+05\x00\n<+03>-3\nPK\x03\x04\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00>\xfe垛\x03\x00\x00\x9b\x03\x00\x00\r\x00\x00\x00Europe/WarsawTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00R\x00\x00\x00\x06\x00\x00\x00\x1a\xff\xff\xff\xffV\xb6\xd0P\xff\xff\xff\xff\x99\xa8*\xd0\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5" +
+	"\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xa0\x9a\xb6\x00\xff\xff\xff\xff\xa1e\xbd\x00\xff\xff\xff\xff\xa6}|`\xff\xff\xff\xff\xc8v\xde\x10\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff" +
+	"\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЄ\xba\x00\xff\xff\xff\xffѕ\x92p\xff\xff\xff\xffҊ\xbb`\xff\xff\xff\xff\xd3b\xffp\xff\xff\xff\xff\xd4K#" +
+	"\x90\xff\xff\xff\xff\xd5^\xad\x10\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xd9\x02\xc1\x90\xff\xff\xff\xff\xd9\xe9x\x10\xff\xff\xff\xff\xe8T\xd2\x00\xff\xff\xff" +
+	"\xff\xe8\xf1\xb4\x80\xff\xff\xff\xff\xe9᥀\xff\xff\xff\xff\xeaі\x80\xff\xff\xff\xff\xec\x14\x96\x00\xff\xff\xff\xff캳\x00\xff\xff\xff\xff\xed\xaa\xa4\x00\xff\xff\xff\xff\ue695\x00\xff\xff\xff\xff\xef\xd4Z" +
+	"\x00\xff\xff\xff\xff\xf0zw\x00\xff\xff\xff\xff\xf1\xb4<\x00\xff\xff\xff\xff\xf2ZY\x00\xff\xff\xff\xff\xf3\x94\x1e\x00\xff\xff\xff\xff\xf4:;\x00\xff\xff\xff\xff\xf5}:\x80\xff\xff\xff\xff\xf6\x1a\x1d\x00\x00\x00\x00" +
+	"\x00\r\xa4U\x80\x00\x00\x00\x00\x0e\x8b\f\x00\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00\x10t(\x80\x00\x00\x00\x00\x11d\x19\x80\x00\x00\x00\x00\x12T\n\x80\x00\x00\x00\x00\x13M6\x00\x00\x00\x00\x00\x143\xec" +
+	"\x80\x00\x00\x00\x00\x15#݀\x00\x00\x00\x00\x16\x13\u0380\x00\x00\x00\x00\x17\x03\xbf\x80\x00\x00\x00\x00\x17\xf3\xb0\x80\x00\x00\x00\x00\x18㡀\x00\x00\x00\x00\x19Ӓ\x80\x00\x00\x00\x00\x1aÃ\x80\x00\x00\x00" +
+	"\x00\x1b\xbc\xaf\x00\x00\x00\x00\x00\x1c\xac\xa0\x00\x00\x00\x00\x00\x1d\x9c\x91\x00\x00\x00\x00\x00\x1e\x8c\x82\x00\x00\x00\x00\x00\x1f|s\x00\x00\x00\x00\x00 ld\x00\x00\x00\x00\x00!\\U\x00\x00\x00\x00\x00\"LT" +
+	"\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00" +
+	"\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad" +
+	"\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x05\x04\x05\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\x13\xb0\x00\x00\x00\x00\x13\xb0\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\r\x00\x00*0\x01" +
+	"\x11\x00\x00\x1c \x00\x16LMT\x00WMT\x00CEST\x00CET\x00EEST\x00EET\x00\nCET-1CEST,M3.5.0,M10.5.0/3" +
+	"\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\r\x00\x00\x00Europe/ZagrebTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xff^<\xf0H\xff\xff\xff\xff\xca\x025\xe0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff" +
+	"\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xffѡ\x8c\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b" +
+	"\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00" +
+	"\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)" +
+	"\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00" +
+	"\x00\x00\x001]\xd9\x10\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x138\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01" +
+	"\bLMT\x00CET\x00CEST\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00iS\x18D" +
+	".\x02\x00\x00.\x02\x00\x00\x11\x00\x00\x00Europe/ZaporozhyeTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\x00\x00\x00\b" +
+	"\x00\x00\x00\"\xff\xff\xff\xffV\xb6\xc7d\xff\xff\xff\xff\xaa\x19\xa7d\xff\xff\xff\xff\xb5\xa4\x19`\xff\xff\xff\xff\xca\xcd.\xd0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10" +
+	"\xff\xff\xff\xff\xceͨp\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00" +
+	"\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0" +
+	"\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00&\x8d \xe0\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00" +
+	")\xd5\b\x80\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4ۀ\x00\x00\x00\x00-\x94̀\x00\x00\x00\x00.\x84\xbd\x80\x00\x00\x00\x00/t\xae\x80\x00\x00\x00\x000d\x9f\x80" +
+	"\x00\x00\x00\x001]\xcb\x00\x00\x00\x00\x002r\xb4\x10\x01\x02\x03\x05\x04\x05\x04\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\x00\x00\x1c\x9c\x00" +
+	"\x00\x00\x00\x1c\x9c\x00\x04\x00\x00\x1c \x00\b\x00\x00*0\x00\f\x00\x00\x0e\x10\x00\x10\x00\x00\x1c \x01\x14\x00\x008@\x01\x19\x00\x00*0\x01\x1dLMT\x00KMT\x00EET\x00MSK\x00C" +
+	"ET\x00CEST\x00MSD\x00EEST\x00\nEET-2EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00Dd#\xc4\xf1\x01\x00\x00\xf1\x01\x00\x00\r\x00\x00\x00Europe/ZurichTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00%\x00\x00\x00" +
+	"\x04\x00\x00\x00\x11\xff\xff\xff\xff$\xf0\xea\x80\xff\xff\xff\xffq\xd4\x06\x86\xff\xff\xff\xff\xca\x17j\x00\xff\xff\xff\xff\xca\xe2q\x00\xff\xff\xff\xff\xcb\xf7L\x00\xff\xff\xff\xff\xcc\xc2S\x00\x00\x00\x00\x00\x15#\xeb" +
+	"\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00" +
+	"\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E" +
+	"\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00" +
+	"\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9" +
+	"\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\b\x00\x00\x00\x00\x00\x06\xfa\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10" +
+	"\x00\rLMT\x00BMT\x00CEST\x00CET\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\xab\x80c$q\x00\x00\x00q\x00\x00\x00\a\x00\x00\x00FactoryTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00" +
+	"\x00\x00\x00\x00\x00-00\x00\n<-00>0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\x02\x00\x00\x00GBTZif2\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f\x00\x00\x00\x05\x00\x00\x00\x11\xff\xff\xff\xff\x1a]\t\xcb\xff\xff\xff\xff\x9b&\xad\xa0\xff\xff\xff\xff\x9b\xd6\x05 \xff\xff\xff\xff\x9c\xcf0\xa0\xff\xff\xff\xff" +
+	"\x9d\xa4à\xff\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff\xff\xff\xa0\x85\xba \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{Ƞ\xff\xff\xff\xff\xa4N\xb8\xa0" +
+	"\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00Ӡ\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff" +
+	"\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \xff\xff\xff\xff\xb1\x92Р\xff\xff\xff\xff\xb2pL\xa0" +
+	"\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \xff\xff\xff\xff\xb60\x10\xa0\xff\xff\xff\xff\xb72v\xa0\xff\xff\xff\xff\xb8\x0f\xf2\xa0\xff\xff\xff\xff\xb9\x12X\xa0\xff\xff\xff\xff" +
+	"\xb9\xefԠ\xff\xff\xff\xff\xba\xe9\x00 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b " +
+	"\xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff" +
+	"\xc7\xda\t\xa0\xff\xff\xff\xff\xca\x16&\x90\xff\xff\xff\xffʗY\x90\xff\xff\xff\xff\xcb\xd1\x1e\x90\xff\xff\xff\xff\xccw;\x90\xff\xff\xff\xffͱ\x00\x90\xff\xff\xff\xff\xce`X\x10\xff\xff\xff\xffϐ\xe2\x90" +
+	"\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xfb2\x10\xff\xff\xff\xff\xd2i\xfe \xff\xff\xff\xff\xd3c)\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff" +
+	"\xd5B\xfd\x90\xff\xff\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd6\xfe\x03\xa0\xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec " +
+	"\xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\u07b4\xea\xa0\xff\xff\xff\xff߮\x16 \xff\xff\xff\xff\xe0\x94̠\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff" +
+	"\xe2kt \xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4T\x90\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6=\xad \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\v " +
+	"\xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\ue6b1 \xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff" +
+	"\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\x7f_ \xff\xff\xff\xff\xf3Jf \xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\r\xa0\xff\xff\xff\xff\xf6?# \xff\xff\xff\xff\xf7\x00\xef\xa0" +
+	"\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0Ѡ\xff\xff\xff\xff\xf9\xfe\xe7 \xff\xff\xff\xff\xfa\xc0\xb3\xa0\xff\xff\xff\xff\xfb\xe8\x03\xa0\xff\xff\xff\xff\xfc{\xab\xa0\xff\xff\xff\xff\xfdǻp\x00\x00\x00\x00" +
+	"\x03p\xc6 \x00\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\t: \x00\x00\x00\x00\a0\x8a \x00\x00\x00\x00\a\xe9\x1c \x00\x00\x00\x00\t\x10l \x00\x00\x00\x00\t\xc8\xfe " +
+	"\x00\x00\x00\x00\n\xf0N \x00\x00\x00\x00\v\xb2\x1a\xa0\x00\x00\x00\x00\f\xd00 \x00\x00\x00\x00\r\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \x00\x00\x00\x00\x0fqޠ\x00\x00\x00\x00\x10\x99.\xa0\x00\x00\x00\x00" +
+	"\x11Q\xc0\xa0\x00\x00\x00\x00\x12y\x10\xa0\x00\x00\x00\x00\x131\xa2\xa0\x00\x00\x00\x00\x14X\xf2\xa0\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x168Ɛ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x18\x18\xa8\x90" +
+	"\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19\xf8\x8a\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xe1\xa7\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\xc1\x89\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00" +
+	"\x1f\xa1k\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\x81M\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#a/\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%JK\x90\x00\x00\x00\x00&\f\x18\x10" +
+	"\x00\x00\x00\x00'*-\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00)\n\x0f\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xe9\xf1\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xc9Ӑ\x00\x00\x00\x00" +
+	"-\x94ڐ\x00\x00\x00\x00.\xa9\xb5\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000\x89\x97\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xff\xb5\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x00\x04LMT\x00BST\x00GMT\x00BDS" +
+	"T\x00\nGMT0BST,M3.5.0/1,M10.5.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\a\x00\x00\x00GB" +
+	"-EireTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif" +
+	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f\x00\x00\x00\x05\x00\x00\x00\x11\xff\xff\xff\xff\x1a]\t\xcb\xff\xff\xff\xff\x9b&\xad\xa0\xff\xff\xff\xff" +
+	"\x9b\xd6\x05 \xff\xff\xff\xff\x9c\xcf0\xa0\xff\xff\xff\xff\x9d\xa4à\xff\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff\xff\xff\xa0\x85\xba \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c " +
+	"\xff\xff\xff\xff\xa3{Ƞ\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff" +
+	"\xaa\x00Ӡ\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 " +
+	"\xff\xff\xff\xff\xb1\x92Р\xff\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \xff\xff\xff\xff\xb60\x10\xa0\xff\xff\xff\xff\xb72v\xa0\xff\xff\xff\xff" +
+	"\xb8\x0f\xf2\xa0\xff\xff\xff\xff\xb9\x12X\xa0\xff\xff\xff\xff\xb9\xefԠ\xff\xff\xff\xff\xba\xe9\x00 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0" +
+	"\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff" +
+	"\xc6:\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xca\x16&\x90\xff\xff\xff\xffʗY\x90\xff\xff\xff\xff\xcb\xd1\x1e\x90\xff\xff\xff\xff\xccw;\x90\xff\xff\xff\xffͱ\x00\x90" +
+	"\xff\xff\xff\xff\xce`X\x10\xff\xff\xff\xffϐ\xe2\x90\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xfb2\x10\xff\xff\xff\xff\xd2i\xfe \xff\xff\xff\xff\xd3c)\xa0\xff\xff\xff\xff" +
+	"\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd5B\xfd\x90\xff\xff\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd6\xfe\x03\xa0\xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 " +
+	"\xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\u07b4\xea\xa0\xff\xff\xff\xff߮\x16 \xff\xff\xff\xff" +
+	"\xe0\x94̠\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt \xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4T\x90\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6=\xad \xff\xff\xff\xff\xe7\x1b) " +
+	"\xff\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\v \xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff" +
+	"\ue6b1 \xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\x7f_ \xff\xff\xff\xff\xf3Jf \xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\r\xa0" +
+	"\xff\xff\xff\xff\xf6?# \xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0Ѡ\xff\xff\xff\xff\xf9\xfe\xe7 \xff\xff\xff\xff\xfa\xc0\xb3\xa0\xff\xff\xff\xff\xfb\xe8\x03\xa0\xff\xff\xff\xff" +
+	"\xfc{\xab\xa0\xff\xff\xff\xff\xfdǻp\x00\x00\x00\x00\x03p\xc6 \x00\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\t: \x00\x00\x00\x00\a0\x8a \x00\x00\x00\x00\a\xe9\x1c " +
+	"\x00\x00\x00\x00\t\x10l \x00\x00\x00\x00\t\xc8\xfe \x00\x00\x00\x00\n\xf0N \x00\x00\x00\x00\v\xb2\x1a\xa0\x00\x00\x00\x00\f\xd00 \x00\x00\x00\x00\r\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \x00\x00\x00\x00" +
+	"\x0fqޠ\x00\x00\x00\x00\x10\x99.\xa0\x00\x00\x00\x00\x11Q\xc0\xa0\x00\x00\x00\x00\x12y\x10\xa0\x00\x00\x00\x00\x131\xa2\xa0\x00\x00\x00\x00\x14X\xf2\xa0\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x168Ɛ" +
+	"\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x18\x18\xa8\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19\xf8\x8a\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xe1\xa7\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00" +
+	"\x1d\xc1\x89\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f\xa1k\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\x81M\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#a/\x10\x00\x00\x00\x00$,6\x10" +
+	"\x00\x00\x00\x00%JK\x90\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'*-\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00)\n\x0f\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xe9\xf1\x90\x00\x00\x00\x00" +
+	"+\xb4\xf8\x90\x00\x00\x00\x00,\xc9Ӑ\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\xa9\xb5\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000\x89\x97\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xff\xb5\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x00" +
+	"\x04LMT\x00BST\x00GMT\x00BDST\x00\nGMT0BST,M3.5.0/1,M10.5.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda" +
+	"\xfa\x03o\x00\x00\x00o\x00\x00\x00\x03\x00\x00\x00GMTTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" +
+	"\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GM" +
+	"T\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\x05\x00\x00\x00GMT+0TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00" +
+	"\x05\x00\x00\x00GMT-0TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" +
+	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\nGMT0\n" +
+	"PK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\x04\x00\x00\x00GMT0TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\t\x00\x00\x00Green" +
+	"wichTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\nGMT0\nPK\x03\x04\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00=\xf7\xfawp\x00\x00\x00p\x00\x00\x00\x03\x00\x00\x00HSTTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00" +
+	"\x00\x00\x04\xff\xffs`\x00\x00HST\x00\nHST10\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\t\xfa-\a\x03\x00\x00\a\x03\x00\x00\b\x00\x00\x00HongkongTZ" +
+	"if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\x00\x00\x00\x05\x00\x00\x00\x16\xff\xff\xff\xff\x85ic\x90\xff\xff\xff\xff\xcaM10\xff\xff\xff\xff\xcaۓ0\xff\xff\xff" +
+	"\xff\xcbKqx\xff\xff\xff\xffҠސ\xff\xff\xff\xff\xd3k׀\xff\xff\xff\xffԓX\xb8\xff\xff\xff\xff\xd5B\xb08\xff\xff\xff\xff\xd6s:\xb8\xff\xff\xff\xff\xd7>A\xb8\xff\xff\xff\xff\xd8.2" +
+	"\xb8\xff\xff\xff\xff\xd8\xf99\xb8\xff\xff\xff\xff\xda\x0e\x14\xb8\xff\xff\xff\xff\xda\xd9\x1b\xb8\xff\xff\xff\xff\xdb\xed\xf6\xb8\xff\xff\xff\xffܸ\xfd\xb8\xff\xff\xff\xff\xdd\xcdظ\xff\xff\xff\xffޢ\x1a8\xff\xff\xff" +
+	"\xff߶\xf58\xff\xff\xff\xff\xe0\x81\xfc8\xff\xff\xff\xff\xe1\x96\xc9(\xff\xff\xff\xff\xe2Oi8\xff\xff\xff\xff\xe3v\xab(\xff\xff\xff\xff\xe4/K8\xff\xff\xff\xff\xe5_Ǩ\xff\xff\xff\xff\xe6\x0f-" +
+	"8\xff\xff\xff\xff\xe7?\xa9\xa8\xff\xff\xff\xff\xe7\xf8I\xb8\xff\xff\xff\xff\xe9\x1f\x8b\xa8\xff\xff\xff\xff\xe9\xd8+\xb8\xff\xff\xff\xff\xea\xffm\xa8\xff\xff\xff\xff\xeb\xb8\r\xb8\xff\xff\xff\xff\xec\xdfO\xa8\xff\xff\xff" +
+	"\xff\xed\x97\xef\xb8\xff\xff\xff\xff\xee\xc8l(\xff\xff\xff\xff\xefwѸ\xff\xff\xff\xff\xf0\xa8N(\xff\xff\xff\xff\xf1W\xb3\xb8\xff\xff\xff\xff\xf2\x880(\xff\xff\xff\xff\xf3@\xd08\xff\xff\xff\xff\xf4h\x12" +
+	"(\xff\xff\xff\xff\xf5 \xb28\xff\xff\xff\xff\xf6G\xf4(\xff\xff\xff\xff\xf7%~8\xff\xff\xff\xff\xf8\x15a(\xff\xff\xff\xff\xf9\x05`8\xff\xff\xff\xff\xf9\xf5C(\xff\xff\xff\xff\xfa\xe5B8\xff\xff\xff" +
+	"\xff\xfb\xde_\xa8\xff\xff\xff\xff\xfc\xce^\xb8\xff\xff\xff\xff\xfd\xbeA\xa8\xff\xff\xff\xff\xfe\xae@\xb8\xff\xff\xff\xff\xff\x9e#\xa8\x00\x00\x00\x00\x00\x8e\"\xb8\x00\x00\x00\x00\x01~\x05\xa8\x00\x00\x00\x00\x02n\x04" +
+	"\xb8\x00\x00\x00\x00\x03]\xe7\xa8\x00\x00\x00\x00\x04M\xe6\xb8\x00\x00\x00\x00\x05G\x04(\x00\x00\x00\x00\x067\x038\x00\x00\x00\x00\a&\xe6(\x00\x00\x00\x00\a\x83=8\x00\x00\x00\x00\t\x06\xc8(\x00\x00\x00" +
+	"\x00\t\xf6\xc78\x00\x00\x00\x00\n\xe6\xaa(\x00\x00\x00\x00\v֩8\x00\x00\x00\x00\fƌ(\x00\x00\x00\x00\x11\x9b98\x00\x00\x00\x00\x12ol\xa8\x01\x02\x03\x04\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00k\n\x00\x00" +
+	"\x00\x00p\x80\x00\x04\x00\x00~\x90\x01\b\x00\x00w\x88\x01\r\x00\x00~\x90\x00\x12LMT\x00HKT\x00HKST\x00HKWT\x00JST\x00\nHKT-8\nPK\x03\x04\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\a\x00\x00\x00IcelandTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" +
+	"\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98ƿ\x00" +
+	"\x00\x00\xbf\x00\x00\x00\x13\x00\x00\x00Indian/AntananarivoTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x04" +
+	"\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1\xed\xadX\xff\xff\xff\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\"\x84\x00\x00\x00\x00#(\x00" +
+	"\x04\x00\x00*0\x00\n\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00+0245\x00\nEAT-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00x\xb0W\x14\x98\x00" +
+	"\x00\x00\x98\x00\x00\x00\r\x00\x00\x00Indian/ChagosTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff" +
+	"\xff\xff\x89~\xf7\x9c\x00\x00\x00\x000\xe6ݰ\x01\x02\x00\x00C\xe4\x00\x00\x00\x00FP\x00\x04\x00\x00T`\x00\bLMT\x00+05\x00+06\x00\n<+06>-6\nPK\x03\x04\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x88\xf6C\x84\x98\x00\x00\x00\x98\x00\x00\x00\x10\x00\x00\x00Indian/ChristmasTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xffV\xb6\x85\xc4\xff\xff\xff\xff\xa2jg\xc4\x01\x02\x00\x00^<\x00\x00\x00\x00^<\x00\x04\x00\x00bp\x00\bLMT\x00BMT\x00" +
+	"+07\x00\n<+07>-7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ʇ{_\xbb\x00\x00\x00\xbb\x00\x00\x00\f\x00\x00\x00Indian/CocosTZif2" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xffV\xb6\x89\xd1\xff\xff\xff\xff\xa1\xf2sQ\xff\xff\xff\xff\xcb\xf2\xfc\x18\xff\xff\xff\xffњ" +
+	"g\xf0\x01\x02\x03\x02\x00\x00Z/\x00\x00\x00\x00Z/\x00\x04\x00\x00[h\x00\b\x00\x00~\x90\x00\x0eLMT\x00RMT\x00+0630\x00+09\x00\n<+0630>-6:3" +
+	"0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\r\x00\x00\x00Indian/ComoroTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1\xed\xadX\xff\xff\xff\xff\xcclz\xd4" +
+	"\x01\x02\x01\x03\x02\x00\x00\"\x84\x00\x00\x00\x00#(\x00\x04\x00\x00*0\x00\n\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00+0245\x00\nEAT-3\nPK\x03\x04" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb9\xb2Z\xac\x98\x00\x00\x00\x98\x00\x00\x00\x10\x00\x00\x00Indian/KerguelenTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xffV\xb6\x9f\x18\xff\xff\xff\xff\xed/Ø\x01\x02\x00\x00D\xe8\x00\x00\x00\x00D\xe8\x00\x04\x00\x00FP\x00\bLMT\x00MMT" +
+	"\x00+05\x00\n<+05>-5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xed\x8c\xf1\x91\x85\x00\x00\x00\x85\x00\x00\x00\v\x00\x00\x00Indian/MaheTZif2" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xa1\xf2\x99\xa8\x01\x00\x003\xd8\x00\x00\x00\x008@\x00\x04LMT\x00+04\x00\n" +
+	"<+04>-4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb9\xb2Z\xac\x98\x00\x00\x00\x98\x00\x00\x00\x0f\x00\x00\x00Indian/MaldivesTZif2\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xffV\xb6\x9f\x18\xff\xff\xff\xff\xed/Ø\x01\x02\x00\x00D\xe8\x00\x00\x00\x00D\xe8\x00\x04\x00\x00" +
+	"FP\x00\bLMT\x00MMT\x00+05\x00\n<+05>-5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xed=\x98\xb3\x00\x00\x00\xb3\x00\x00\x00\x10\x00\x00\x00India" +
+	"n/MauritiusTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00" +
+	"\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x89\x7f\x05\x98\x00\x00\x00\x00\x18\x05" +
+	"\xed@\x00\x00\x00\x00\x18\xdbr0\x00\x00\x00\x00I\x03\x96\xe0\x00\x00\x00\x00IΏ\xd0\x02\x01\x02\x01\x02\x00\x005\xe8\x00\x00\x00\x00FP\x01\x04\x00\x008@\x00\bLMT\x00+05\x00+04" +
+	"\x00\n<+04>-4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\x0e\x00\x00\x00Indian/MayotteTZif2\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1\xed\xad" +
+	"X\xff\xff\xff\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\"\x84\x00\x00\x00\x00#(\x00\x04\x00\x00*0\x00\n\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00+0245\x00\nE" +
+	"AT-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xed\x8c\xf1\x91\x85\x00\x00\x00\x85\x00\x00\x00\x0e\x00\x00\x00Indian/ReunionTZif2\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xa1\xf2\x99\xa8\x01\x00\x003\xd8\x00\x00\x00\x008@\x00\x04LMT\x00+04\x00\n<+04>-" +
+	"4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c\xdb?\xec,\x03\x00\x00,\x03\x00\x00\x04\x00\x00\x00IranTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00G\x00\x00\x00\x06\x00\x00\x00\x1c\xff\xff\xff\xff\x9al}\xc8\xff\xff\xff\xff\xbf\x00\xccH\x00\x00\x00\x00\r\x94D8\x00\x00\x00\x00\x0e\xad\x13\xb8\x00\x00\x00\x00\x0fys@\x00\x00\x00\x00\x10(\xca\xc0\x00" +
+	"\x00\x00\x00\x10\xed:@\x00\x00\x00\x00\x11\xad\xbcH\x00\x00\x00\x00\x12EJ\xb8\x00\x00\x00\x00\x137\xec\xc8\x00\x00\x00\x00\x14-\x15\xb8\x00\x00\x00\x00( v\xc8\x00\x00\x00\x00(\u06dd\xb8\x00\x00\x00\x00)" +
+	"˜\xc8\x00\x00\x00\x00*\xbe\"\xb8\x00\x00\x00\x00+\xac\xd0H\x00\x00\x00\x00,\x9fV8\x00\x00\x00\x00-\x8e\x03\xc8\x00\x00\x00\x00.\x80\x89\xb8\x00\x00\x00\x00/o7H\x00\x00\x00\x000a\xbd8\x00" +
+	"\x00\x00\x001Pj\xc8\x00\x00\x00\x002B\xf0\xb8\x00\x00\x00\x0032\xef\xc8\x00\x00\x00\x004%u\xb8\x00\x00\x00\x005\x14#H\x00\x00\x00\x006\x06\xa98\x00\x00\x00\x006\xf5V\xc8\x00\x00\x00\x007" +
+	"\xe7ܸ\x00\x00\x00\x008֊H\x00\x00\x00\x009\xc9\x108\x00\x00\x00\x00:\xb9\x0fH\x00\x00\x00\x00;\xab\x958\x00\x00\x00\x00<\x9aB\xc8\x00\x00\x00\x00=\x8cȸ\x00\x00\x00\x00>{vH\x00" +
+	"\x00\x00\x00?m\xfc8\x00\x00\x00\x00@\\\xa9\xc8\x00\x00\x00\x00AO/\xb8\x00\x00\x00\x00B?.\xc8\x00\x00\x00\x00C1\xb4\xb8\x00\x00\x00\x00G\xe2\xc9H\x00\x00\x00\x00H\xd5O8\x00\x00\x00\x00I" +
+	"\xc5NH\x00\x00\x00\x00J\xb7\xd48\x00\x00\x00\x00K\xa6\x81\xc8\x00\x00\x00\x00L\x99\a\xb8\x00\x00\x00\x00M\x87\xb5H\x00\x00\x00\x00Nz;8\x00\x00\x00\x00Oh\xe8\xc8\x00\x00\x00\x00P[n\xb8\x00" +
+	"\x00\x00\x00QKm\xc8\x00\x00\x00\x00R=\xf3\xb8\x00\x00\x00\x00S,\xa1H\x00\x00\x00\x00T\x1f'8\x00\x00\x00\x00U\r\xd4\xc8\x00\x00\x00\x00V\x00Z\xb8\x00\x00\x00\x00V\xef\bH\x00\x00\x00\x00W" +
+	"\xe1\x8e8\x00\x00\x00\x00XэH\x00\x00\x00\x00Y\xc4\x138\x00\x00\x00\x00Z\xb2\xc0\xc8\x00\x00\x00\x00[\xa5F\xb8\x00\x00\x00\x00\\\x93\xf4H\x00\x00\x00\x00]\x86z8\x00\x00\x00\x00^u'\xc8\x00" +
+	"\x00\x00\x00_g\xad\xb8\x00\x00\x00\x00`W\xac\xc8\x00\x00\x00\x00aJ2\xb8\x00\x00\x00\x00b8\xe0H\x00\x00\x00\x00c+f8\x01\x03\x02\x05\x04\x05\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x0008\x00\x00\x00\x0008" +
+	"\x00\x04\x00\x00?H\x01\b\x00\x0018\x00\x0e\x00\x00FP\x01\x14\x00\x008@\x00\x18LMT\x00TMT\x00+0430\x00+0330\x00+05\x00+04\x00\n<+033" +
+	"0>-3:30\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17✳2\x04\x00\x002\x04\x00\x00\x06\x00\x00\x00IsraelTZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xffV\xb6\xc2\xfa\xff\xff\xff\xff\x9e0E\x88\xff\xff\xff\xff\xc8Y\xcf\x00\xff\xff\xff\xff\xc8\xfa\xa6\x00\xff\xff\xff\xff\xc98\x9c\x80\xff" +
+	"\xff\xff\xff\xcc\xe5\xeb\x80\xff\xff\xff\xffͬ\xfe\x00\xff\xff\xff\xff\xce\xc7\x1f\x00\xff\xff\xff\xffϏ\x83\x00\xff\xff\xff\xffЩ\xa4\x00\xff\xff\xff\xffф}\x00\xff\xff\xff\xffҊ׀\xff\xff\xff\xff\xd3" +
+	"e\xb0\x80\xff\xff\xff\xff\xd4l\v\x00\xff\xff\xff\xff\xd7Z0\x80\xff\xff\xff\xff\xd7\xdfX\x00\xff\xff\xff\xff\xd8/À\xff\xff\xff\xff\xd9\x1ec\x00\xff\xff\xff\xff\xda\x10\xf7\x00\xff\xff\xff\xff\xda\xeb\xd0\x00\xff" +
+	"\xff\xff\xff۴4\x00\xff\xff\xff\xffܹ=\x00\xff\xff\xff\xff\xdd\xe0\x8d\x00\xff\xff\xff\xff\u07b4\u0380\xff\xff\xff\xffߤ\xbf\x80\xff\xff\xff\xff\xe0\x8bv\x00\xff\xff\xff\xff\xe1V}\x00\xff\xff\xff\xff\xe2" +
+	"\xbef\x80\xff\xff\xff\xff\xe36_\x00\xff\xff\xff\xff\xe4\x9eH\x80\xff\xff\xff\xff\xe5\x16A\x00\xff\xff\xff\xff\xe6t\xf0\x00\xff\xff\xff\xff\xe7\x11Ҁ\xff\xff\xff\xff\xe8&\xad\x80\xff\xff\xff\xff\xe8\xe8z\x00\x00" +
+	"\x00\x00\x00\b|\x8b\xe0\x00\x00\x00\x00\b\xfd\xb0\xd0\x00\x00\x00\x00\t\xf6\xea`\x00\x00\x00\x00\n\xa63\xd0\x00\x00\x00\x00\x13\xe9\xfc`\x00\x00\x00\x00\x14![`\x00\x00\x00\x00\x1a\xfa\xc6`\x00\x00\x00\x00\x1b" +
+	"\x8en`\x00\x00\x00\x00\x1c\xbe\xf8\xe0\x00\x00\x00\x00\x1dw|\xd0\x00\x00\x00\x00\x1e\xcc\xff`\x00\x00\x00\x00\x1f`\x99P\x00\x00\x00\x00 \x82\xb1`\x00\x00\x00\x00!I\xb5\xd0\x00\x00\x00\x00\"^\x9e\xe0\x00" +
+	"\x00\x00\x00# ]P\x00\x00\x00\x00$Z0`\x00\x00\x00\x00%\x00?P\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00&\xd6\xe6\xd0\x00\x00\x00\x00'\xeb\xcf\xe0\x00\x00\x00\x00(\xc0\x03P\x00\x00\x00\x00)" +
+	"\xd4\xec`\x00\x00\x00\x00*\xa9\x1f\xd0\x00\x00\x00\x00+\xbbe\xe0\x00\x00\x00\x00,\x89\x01\xd0\x00\x00\x00\x00-\x9bG\xe0\x00\x00\x00\x00._\xa9P\x00\x00\x00\x00/{)\xe0\x00\x00\x00\x000H\xc5\xd0\x00" +
+	"\x00\x00\x001H\x96\xe0\x00\x00\x00\x002<nP\x00\x00\x00\x0031\xb3`\x00\x00\x00\x004\x1a\xfe\xd0\x00\x00\x00\x005\x11\x95`\x00\x00\x00\x005\xf1\xa6P\x00\x00\x00\x007\x04\b\x80\x00\x00\x00\x007" +
+	"\xcf\x01p\x00\x00\x00\x008\xf6_\x80\x00\x00\x00\x009\xdc\xf9\xe0\x00\x00\x00\x00:\xd0\xedp\x00\x00\x00\x00;\xae[`\x00\x00\x00\x00<\xa3\xa0p\x00\x00\x00\x00=\xa0\xb2`\x00\x00\x00\x00>\x83\x82p\x00" +
+	"\x00\x00\x00?|\x9f\xe0\x00\x00\x00\x00@s6p\x00\x00\x00\x00AP\xa4`\x00\x00\x00\x00BL\x8f\x00\x00\x00\x00\x00CHOp\x00\x00\x00\x00D,q\x00\x00\x00\x00\x00E\x1e\xf6\xf0\x00\x00\x00\x00F" +
+	"\fS\x00\x00\x00\x00\x00F\xecc\xf0\x00\x00\x00\x00G\xec5\x00\x00\x00\x00\x00H\xe7\xf5p\x00\x00\x00\x00I\xcc\x17\x00\x00\x00\x00\x00J\xbe\x9c\xf0\x00\x00\x00\x00K\xab\xf9\x00\x00\x00\x00\x00L\x8c\t\xf0\x00" +
+	"\x00\x00\x00M\x95\x15\x80\x00\x00\x00\x00N\x87\x9bp\x00\x00\x00\x00Ot\xf7\x80\x00\x00\x00\x00P^B\xf0\x00\x00\x00\x00QTـ\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00!\x06\x00\x00\x00\x00 \xf8\x00\x04\x00\x00*0\x01\b\x00\x00\x1c \x00\f\x00\x008@\x01\x10LMT\x00JMT\x00IDT" +
+	"\x00IST\x00IDDT\x00\nIST-2IDT,M3.4.4/26,M10.5.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00%J\xd5\xebS\x01\x00\x00" +
+	"S\x01\x00\x00\a\x00\x00\x00JamaicaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00" +
+	"\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x16\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffi\x87#~\xff\xff" +
+	"\xff\xff\x93\x0f\xb4\xfe\x00\x00\x00\x00\a\x8d\x19p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\t\xad\x94\xf0\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00\f٢\xe0\x00\x00\x00\x00\r\xc0" +
+	"gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00" +
+	"\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\xff\xff\xb8\x02\x00\x00\xff\xff\xb8\x02\x00\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\fLMT\x00KMT\x00EST\x00EDT\x00\nEST5\nPK\x03\x04\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x02\xf4\xaeg\xd5\x00\x00\x00\xd5\x00\x00\x00\x05\x00\x00\x00JapanTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x03" +
+	"\x00\x00\x00\f\xff\xff\xff\xffe¤p\xff\xff\xff\xff\xd7>\x02p\xff\xff\xff\xff\xd7\xedY\xf0\xff\xff\xff\xff\xd8\xf8\xfap\xff\xff\xff\xff\xd9\xcd;\xf0\xff\xff\xff\xff\xdb\a\x00\xf0\xff\xff\xff\xffۭ\x1d\xf0" +
+	"\xff\xff\xff\xff\xdc\xe6\xe2\xf0\xff\xff\xff\xff\u074c\xff\xf0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x83\x03\x00\x00\x00\x00\x8c\xa0\x01\x04\x00\x00~\x90\x00\bLMT\x00JDT\x00JST\x00\nJST-" +
+	"9\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\xe8]*\xdb\x00\x00\x00\xdb\x00\x00\x00\t\x00\x00\x00KwajaleinTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff~6\x18 \xff\xff\xff\xff\xc1\xed5\xd0\xff\xff\xff\xff\xc9\xea\n`\xff\xff\xff\xff\xcfF\x81\xf0\xff\xff\xff\xff\xff\x86\x1bP\x00\x00\x00\x00" +
+	",v\x0e@\x01\x02\x03\x01\x04\x05\x00\x00\x9c\xe0\x00\x00\x00\x00\x9a\xb0\x00\x04\x00\x00\x8c\xa0\x00\b\x00\x00~\x90\x00\f\xff\xffW@\x00\x10\x00\x00\xa8\xc0\x00\x14LMT\x00+11\x00+10\x00+0" +
+	"9\x00-12\x00+12\x00\n<+12>-12\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00_\x7f2[\xaf\x01\x00\x00\xaf\x01\x00\x00\x05\x00\x00\x00LibyaTZif2" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff\xa1\xf2\xc1$\xff\xff\xff\xffݻ\xb1\x10\xff\xff\xff\xff\xde#\xad`\xff\xff\xff\xff\xe1x" +
+	"\xd2\x10\xff\xff\xff\xff\xe1\xe7e\xe0\xff\xff\xff\xff\xe5/?p\xff\xff\xff\xff\xe5\xa9\xcc\xe0\xff\xff\xff\xff\xebN\xc6\xf0\x00\x00\x00\x00\x16\x92B`\x00\x00\x00\x00\x17\b\xf7p\x00\x00\x00\x00\x17\xfa+\xe0\x00\x00" +
+	"\x00\x00\x18\xea*\xf0\x00\x00\x00\x00\x19\xdb_`\x00\x00\x00\x00\x1a̯\xf0\x00\x00\x00\x00\x1b\xbd\xe4`\x00\x00\x00\x00\x1c\xb4z\xf0\x00\x00\x00\x00\x1d\x9f\x17\xe0\x00\x00\x00\x00\x1e\x93\vp\x00\x00\x00\x00\x1f\x82" +
+	"\xee`\x00\x00\x00\x00 pJp\x00\x00\x00\x00!a~\xe0\x00\x00\x00\x00\"R\xcfp\x00\x00\x00\x00#D\x03\xe0\x00\x00\x00\x00$4\x02\xf0\x00\x00\x00\x00%%7`\x00\x00\x00\x00&@\xb7\xf0\x00\x00" +
+	"\x00\x002N\xf1`\x00\x00\x00\x003D6p\x00\x00\x00\x0045j\xe0\x00\x00\x00\x00P\x9d\x99\x00\x00\x00\x00\x00QTـ\x00\x00\x00\x00Ri\xb4\x80\x02\x01\x02\x01\x02\x01\x02\x03\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x01\x03\x02\x01\x03\x00\x00\f\\\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x1c \x00\rLMT\x00CEST\x00CET\x00EET\x00\n" +
+	"EET-2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe\x9d\x1b\xc9m\x02\x00\x00m\x02\x00\x00\x03\x00\x00\x00METTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x005\x00\x00\x00\x02\x00\x00\x00\t\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84" +
+	"\x97\x90\xff\xff\xff\xff\xc8\tq\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff" +
+	"\xff\xff\xd2N@\x90\x00\x00\x00\x00\r\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13M" +
+	"D\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00" +
+	"\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\" +
+	"c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00" +
+	"\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t" +
+	"\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00" +
+	"\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x00\x0e\x10\x00\x05\x00\x00\x1c \x01\x00MEST\x00MET\x00\nMET-1MEST,M3.5.0,M10.5.0/3\n" +
+	"PK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf5\x8d\x99\x92o\x00\x00\x00o\x00\x00\x00\x03\x00\x00\x00MSTTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x01\x00\x00\x00\x04\xff\xff\x9d\x90\x00\x00MST\x00\nMST7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe6h\xcac\xb7\x03\x00\x00\xb7\x03\x00\x00\a\x00\x00\x00MST7MD" +
+	"TTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x86\x1c\x90" +
+	"\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W\x10\xff\xff\xff\xff" +
+	"\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb89\x10\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x1b\x10\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xfd\x10\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\x19\x90" +
+	"\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\a\x8d5\x90\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\t\xad\xb1\x10\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00" +
+	"\vࡐ\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00" +
+	"\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00\x00" +
+	"\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x1d\x10" +
+	"\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00" +
+	"'\xfeߐ\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80" +
+	"\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x00" +
+	"62ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xb0\n\x90" +
+	"\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00" +
+	"D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x01\x00\x01\x00\x02\x03\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01" +
+	"\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x01\x00" +
+	"\xff\xff\xab\xa0\x01\b\xff\xff\xab\xa0\x01\fMDT\x00MST\x00MWT\x00MPT\x00\nMST7MDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\xb9B$\x90\x01\x04\x00\x00\x01\x04\x00\x00\x10\x00\x00\x00Mexico/BajaNorteTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00^\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xa9yOp\xff\xff\xff\xff\xaf\xf2|\xf0\xff\xff\xff\xff\xb6fdp\xff\xff\xff\xff\xb7\x1b\x10\x00\xff\xff\xff\xff\xb8\n\xf2" +
+	"\xf0\xff\xff\xff\xff\xcbꍀ\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xffҙ\xbap\xff\xff\xff\xff\xd7\x1bY\x00\xff\xff\xff\xffؑ\xb4\xf0\xff\xff\xff\xff\xe2~K\x90\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff" +
+	"\xff\xe4^-\x90\xff\xff\xff\xff\xe5)4\x90\xff\xff\xff\xff\xe6GJ\x10\xff\xff\xff\xff\xe7\x12Q\x10\xff\xff\xff\xff\xe8',\x10\xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff\xff\xea\a\x0e\x10\xff\xff\xff\xff\xea\xd2\x15" +
+	"\x10\xff\xff\xff\xff\xeb\xe6\xf0\x10\xff\xff\xff\xff\xec\xb1\xf7\x10\xff\xff\xff\xff\xed\xc6\xd2\x10\xff\xff\xff\xff\xee\x91\xd9\x10\x00\x00\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00\x00" +
+	"\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT" +
+	" \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00" +
+	"\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1ې\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\"V\r \x00\x00\x00\x00#j\xda" +
+	"\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\n\x80\x10\x00\x00\x00\x00)\xdeϠ\x00\x00\x00" +
+	"\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92" +
+	" \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\a8 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00" +
+	"\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d" +
+	"\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00F\x0f\x82\xa0\x00\x00\x00" +
+	"\x00G$O\x90\x00\x00\x00\x00G\xf8\x9f \x00\x00\x00\x00I\x041\x90\x00\x00\x00\x00I\u0601 \x00\x00\x00\x00J\xe4\x13\x90\x00\x00\x00\x00K\x9c\xb3\xa0\x01\x02\x01\x02\x03\x02\x04\x05\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\x92L\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\x8f\x80\x00\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10\xff\xff\x9d\x90\x01\x14LMT\x00M" +
+	"ST\x00PST\x00PDT\x00PWT\x00PPT\x00\nPST8PDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\xad=" +
+	"\x98\xce\x02\x00\x00\xce\x02\x00\x00\x0e\x00\x00\x00Mexico/BajaSurTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\x00\x00\x00\x05\x00\x00" +
+	"\x00\x14\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6fV`\xff\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff\xb8\f6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\xff\xff\xff\xff\xcb\xeaq`\xff\xff" +
+	"\xff\xffؑ\xb4\xf0\x00\x00\x00\x00\x00\x00p\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062" +
+	"ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xf5\x12\x90\x00\x00\x00\x00;\xb6\xd1\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00" +
+	"\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/" +
+	"\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00F\x0ft\x90\x00\x00\x00\x00G$A\x80\x00\x00\x00\x00G\xf8\x91\x10\x00\x00\x00\x00I\x04#\x80\x00\x00\x00\x00I\xd8s\x10\x00\x00\x00\x00J\xe4\x05\x80\x00\x00" +
+	"\x00\x00K\xb8U\x10\x00\x00\x00\x00L\xcd\"\x00\x00\x00\x00\x00M\x987\x10\x00\x00\x00\x00N\xad\x04\x00\x00\x00\x00\x00Ox\x19\x10\x00\x00\x00\x00P\x8c\xe6\x00\x00\x00\x00\x00Qa5\x90\x00\x00\x00\x00Rl" +
+	"\xc8\x00\x00\x00\x00\x00SA\x17\x90\x00\x00\x00\x00TL\xaa\x00\x00\x00\x00\x00U \xf9\x90\x00\x00\x00\x00V,\x8c\x00\x00\x00\x00\x00W\x00ې\x00\x00\x00\x00X\x15\xa8\x80\x00\x00\x00\x00Xཐ\x00\x00" +
+	"\x00\x00Y\xf5\x8a\x80\x00\x00\x00\x00Z\xc0\x9f\x90\x00\x00\x00\x00[\xd5l\x80\x00\x00\x00\x00\\\xa9\xbc\x10\x00\x00\x00\x00]\xb5N\x80\x00\x00\x00\x00^\x89\x9e\x10\x00\x00\x00\x00_\x950\x80\x00\x00\x00\x00`i" +
+	"\x80\x10\x00\x00\x00\x00a~M\x00\x00\x00\x00\x00bIb\x10\x00\x00\x00\x00c^/\x00\x01\x02\x01\x03\x01\x02\x01\x04\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03" +
+	"\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\xff\xff\x9c<\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\x8f\x80\x00\x10L" +
+	"MT\x00MST\x00CST\x00MDT\x00PST\x00\nMST7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd5\b\x89\x8c\x05\x03\x00\x00\x05\x03\x00\x00\x0e\x00\x00\x00Mexic" +
+	"o/GeneralTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" +
+	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00D\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0" +
+	"\xff\xff\xff\xff\xb6fV`\xff\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff\xb8\f6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\xff\xff\xff\xff\xc5ް`\xff\xff\xff\xffƗ4P\xff\xff\xff\xff\xc9U\xf1\xe0\xff\xff\xff\xff" +
+	"\xc9\xea\xddP\xff\xff\xff\xff\xcf\x02\xc6\xe0\xff\xff\xff\xffϷVP\xff\xff\xff\xffڙ\x15\xe0\xff\xff\xff\xff\xdbv\x83\xd0\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00" +
+	"\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00" +
+	":\xf5\x04\x80\x00\x00\x00\x00;\xb6\xc2\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp" +
+	"\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00F\x0ff\x80\x00\x00\x00\x00G$3p\x00\x00\x00\x00G\xf8\x83\x00\x00\x00\x00\x00" +
+	"I\x04\x15p\x00\x00\x00\x00I\xd8e\x00\x00\x00\x00\x00J\xe3\xf7p\x00\x00\x00\x00K\xb8G\x00\x00\x00\x00\x00L\xcd\x13\xf0\x00\x00\x00\x00M\x98)\x00\x00\x00\x00\x00N\xac\xf5\xf0\x00\x00\x00\x00Ox\v\x00" +
+	"\x00\x00\x00\x00P\x8c\xd7\xf0\x00\x00\x00\x00Qa'\x80\x00\x00\x00\x00Rl\xb9\xf0\x00\x00\x00\x00SA\t\x80\x00\x00\x00\x00TL\x9b\xf0\x00\x00\x00\x00U \xeb\x80\x00\x00\x00\x00V,}\xf0\x00\x00\x00\x00" +
+	"W\x00̀\x00\x00\x00\x00X\x15\x9ap\x00\x00\x00\x00Xீ\x00\x00\x00\x00Y\xf5|p\x00\x00\x00\x00Z\xc0\x91\x80\x00\x00\x00\x00[\xd5^p\x00\x00\x00\x00\\\xa9\xae\x00\x00\x00\x00\x00]\xb5@p" +
+	"\x00\x00\x00\x00^\x89\x90\x00\x00\x00\x00\x00_\x95\"p\x00\x00\x00\x00`ir\x00\x00\x00\x00\x00a~>\xf0\x00\x00\x00\x00bIT\x00\x00\x00\x00\x00c^ \xf0\x01\x02\x01\x03\x01\x02\x04\x02\x04\x02\x05\x02" +
+	"\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\xff\xff\xa3\f" +
+	"\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x01\x14LMT\x00MST\x00CST\x00MDT\x00CDT\x00CWT\x00\nCST" +
+	"6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b\xb2\xaf\xf7\x13\x04\x00\x00\x13\x04\x00\x00\x02\x00\x00\x00NZTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"`\x00\x00\x00\x06\x00\x00\x00\x13\xff\xff\xff\xffA\xb7L\xa8\xff\xff\xff\xff\xb0\xb4\xb2\xe8\xff\xff\xff\xff\xb1Q\x87X\xff\xff\xff\xff\xb2x\xe5h\xff\xff\xff\xff\xb3C\xe5`\xff\xff\xff\xff\xb4X\xc7h\xff\xff\xff" +
+	"\xff\xb5#\xc7`\xff\xff\xff\xff\xb68\xa9h\xff\xff\xff\xff\xb7\x03\xa9`\xff\xff\xff\xff\xb8\x18\x8bh\xff\xff\xff\xff\xb8\xec\xc5\xe0\xff\xff\xff\xff\xb9\xf8mh\xff\xff\xff\xff\xba̧\xe0\xff\xff\xff\xff\xbb\xd8O" +
+	"h\xff\xff\xff\xff\xbc\xe3\xe8\xe0\xff\xff\xff\xff\xbd\xae\xf6\xe8\xff\xff\xff\xff\xbe\xc3\xca\xe0\xff\xff\xff\xff\xbf\x8e\xd8\xe8\xff\xff\xff\xff\xc0\xa3\xac\xe0\xff\xff\xff\xff\xc1n\xba\xe8\xff\xff\xff\xff\u0083\x8e\xe0\xff\xff\xff" +
+	"\xff\xc3N\x9c\xe8\xff\xff\xff\xff\xc4cp\xe0\xff\xff\xff\xff\xc5.~\xe8\xff\xff\xff\xff\xc6L\x8d`\xff\xff\xff\xff\xc7\x0e`\xe8\xff\xff\xff\xff\xc8,o`\xff\xff\xff\xff\xc8\xf7}h\xff\xff\xff\xff\xd2ښ" +
+	"@\x00\x00\x00\x00\t\x18\xfd\xe0\x00\x00\x00\x00\t\xac\xa5\xe0\x00\x00\x00\x00\n\xef\xa5`\x00\x00\x00\x00\v\x9e\xfc\xe0\x00\x00\x00\x00\f\xd8\xc1\xe0\x00\x00\x00\x00\r~\xde\xe0\x00\x00\x00\x00\x0e\xb8\xa3\xe0\x00\x00\x00" +
+	"\x00\x0f^\xc0\xe0\x00\x00\x00\x00\x10\x98\x85\xe0\x00\x00\x00\x00\x11>\xa2\xe0\x00\x00\x00\x00\x12xg\xe0\x00\x00\x00\x00\x13\x1e\x84\xe0\x00\x00\x00\x00\x14XI\xe0\x00\x00\x00\x00\x14\xfef\xe0\x00\x00\x00\x00\x168+" +
+	"\xe0\x00\x00\x00\x00\x16\xe7\x83`\x00\x00\x00\x00\x18!H`\x00\x00\x00\x00\x18\xc7e`\x00\x00\x00\x00\x1a\x01*`\x00\x00\x00\x00\x1a\xa7G`\x00\x00\x00\x00\x1b\xe1\f`\x00\x00\x00\x00\x1c\x87)`\x00\x00\x00" +
+	"\x00\x1d\xc0\xee`\x00\x00\x00\x00\x1eg\v`\x00\x00\x00\x00\x1f\xa0\xd0`\x00\x00\x00\x00 F\xed`\x00\x00\x00\x00!\x80\xb2`\x00\x00\x00\x00\"0\t\xe0\x00\x00\x00\x00#i\xce\xe0\x00\x00\x00\x00$\x0f\xeb" +
+	"\xe0\x00\x00\x00\x00%.\x01`\x00\x00\x00\x00&\x02B\xe0\x00\x00\x00\x00'\r\xe3`\x00\x00\x00\x00'\xe2$\xe0\x00\x00\x00\x00(\xed\xc5`\x00\x00\x00\x00)\xc2\x06\xe0\x00\x00\x00\x00*ͧ`\x00\x00\x00" +
+	"\x00+\xab#`\x00\x00\x00\x00,\xad\x89`\x00\x00\x00\x00-\x8b\x05`\x00\x00\x00\x00.\x8dk`\x00\x00\x00\x00/j\xe7`\x00\x00\x00\x000mM`\x00\x00\x00\x001J\xc9`\x00\x00\x00\x002Vi" +
+	"\xe0\x00\x00\x00\x003*\xab`\x00\x00\x00\x0046K\xe0\x00\x00\x00\x005\n\x8d`\x00\x00\x00\x006\x16-\xe0\x00\x00\x00\x006\xf3\xa9\xe0\x00\x00\x00\x007\xf6\x0f\xe0\x00\x00\x00\x008Ӌ\xe0\x00\x00\x00" +
+	"\x009\xd5\xf1\xe0\x00\x00\x00\x00:\xb3m\xe0\x00\x00\x00\x00;\xbf\x0e`\x00\x00\x00\x00<\x93O\xe0\x00\x00\x00\x00=\x9e\xf0`\x00\x00\x00\x00>s1\xe0\x00\x00\x00\x00?~\xd2`\x00\x00\x00\x00@\\N" +
+	"`\x00\x00\x00\x00A^\xb4`\x00\x00\x00\x00B<0`\x00\x00\x00\x00C>\x96`\x00\x00\x00\x00D\x1c\x12`\x00\x00\x00\x00E\x1ex`\x00\x00\x00\x00E\xfb\xf4`\x00\x00\x00\x00F\xfeZ`\x02\x01\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05" +
+	"\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x00\x00\xa3\xd8\x00\x00\x00\x00\xaf\xc8\x01\x04\x00\x00\xa1\xb8\x00\t\x00\x00\xa8\xc0\x01\x04\x00\x00\xb6" +
+	"\xd0\x01\x0e\x00\x00\xa8\xc0\x00\x04LMT\x00NZST\x00NZMT\x00NZDT\x00\nNZST-12NZDT,M9.5.0,M4.1.0/3\nPK\x03" +
+	"\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xc5FF(\x03\x00\x00(\x03\x00\x00\a\x00\x00\x00NZ-CHATTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"E\x00\x00\x00\x04\x00\x00\x00\x16\xff\xff\xff\xffA\xb7D\x84\xff\xff\xff\xff\xd2ږ\xbc\x00\x00\x00\x00\t\x18\xfd\xe0\x00\x00\x00\x00\t\xac\xa5\xe0\x00\x00\x00\x00\n\xef\xa5`\x00\x00\x00\x00\v\x9e\xfc\xe0\x00\x00\x00" +
+	"\x00\f\xd8\xc1\xe0\x00\x00\x00\x00\r~\xde\xe0\x00\x00\x00\x00\x0e\xb8\xa3\xe0\x00\x00\x00\x00\x0f^\xc0\xe0\x00\x00\x00\x00\x10\x98\x85\xe0\x00\x00\x00\x00\x11>\xa2\xe0\x00\x00\x00\x00\x12xg\xe0\x00\x00\x00\x00\x13\x1e\x84" +
+	"\xe0\x00\x00\x00\x00\x14XI\xe0\x00\x00\x00\x00\x14\xfef\xe0\x00\x00\x00\x00\x168+\xe0\x00\x00\x00\x00\x16\xe7\x83`\x00\x00\x00\x00\x18!H`\x00\x00\x00\x00\x18\xc7e`\x00\x00\x00\x00\x1a\x01*`\x00\x00\x00" +
+	"\x00\x1a\xa7G`\x00\x00\x00\x00\x1b\xe1\f`\x00\x00\x00\x00\x1c\x87)`\x00\x00\x00\x00\x1d\xc0\xee`\x00\x00\x00\x00\x1eg\v`\x00\x00\x00\x00\x1f\xa0\xd0`\x00\x00\x00\x00 F\xed`\x00\x00\x00\x00!\x80\xb2" +
+	"`\x00\x00\x00\x00\"0\t\xe0\x00\x00\x00\x00#i\xce\xe0\x00\x00\x00\x00$\x0f\xeb\xe0\x00\x00\x00\x00%.\x01`\x00\x00\x00\x00&\x02B\xe0\x00\x00\x00\x00'\r\xe3`\x00\x00\x00\x00'\xe2$\xe0\x00\x00\x00" +
+	"\x00(\xed\xc5`\x00\x00\x00\x00)\xc2\x06\xe0\x00\x00\x00\x00*ͧ`\x00\x00\x00\x00+\xab#`\x00\x00\x00\x00,\xad\x89`\x00\x00\x00\x00-\x8b\x05`\x00\x00\x00\x00.\x8dk`\x00\x00\x00\x00/j\xe7" +
+	"`\x00\x00\x00\x000mM`\x00\x00\x00\x001J\xc9`\x00\x00\x00\x002Vi\xe0\x00\x00\x00\x003*\xab`\x00\x00\x00\x0046K\xe0\x00\x00\x00\x005\n\x8d`\x00\x00\x00\x006\x16-\xe0\x00\x00\x00" +
+	"\x006\xf3\xa9\xe0\x00\x00\x00\x007\xf6\x0f\xe0\x00\x00\x00\x008Ӌ\xe0\x00\x00\x00\x009\xd5\xf1\xe0\x00\x00\x00\x00:\xb3m\xe0\x00\x00\x00\x00;\xbf\x0e`\x00\x00\x00\x00<\x93O\xe0\x00\x00\x00\x00=\x9e\xf0" +
+	"`\x00\x00\x00\x00>s1\xe0\x00\x00\x00\x00?~\xd2`\x00\x00\x00\x00@\\N`\x00\x00\x00\x00A^\xb4`\x00\x00\x00\x00B<0`\x00\x00\x00\x00C>\x96`\x00\x00\x00\x00D\x1c\x12`\x00\x00\x00" +
+	"\x00E\x1ex`\x00\x00\x00\x00E\xfb\xf4`\x00\x00\x00\x00F\xfeZ`\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\xab\xfc\x00\x00\x00\x00\xacD\x00\x04\x00\x00\xc1\\\x01\n\x00\x00\xb3L\x00\x10LMT\x00+1" +
+	"215\x00+1345\x00+1245\x00\n<+1245>-12:45<+1345>,M9.5.0/2:45,M4.1.0/3:4" +
+	"5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\x80\x94@\x12\x04\x00\x00\x12\x04\x00\x00\x06\x00\x00\x00NavajoTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00a\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff^\x04\f\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff\xff\xff\xa2e\xfe" +
+	"\x90\xff\xff\xff\xff\xa3\x84\x06\x00\xff\xff\xff\xff\xa4E\xe0\x90\xff\xff\xff\xff\xa4\x8f\xa6\x80\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xf7/v\x90\xff\xff\xff" +
+	"\xff\xf8(\x94\x00\xff\xff\xff\xff\xf9\x0fX\x90\xff\xff\xff\xff\xfa\bv\x00\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W\x10\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb89" +
+	"\x10\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x1b\x10\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xfd\x10\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00" +
+	"\x00\x06@\xfb\x90\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\a\x8d5\x90\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\t\xad\xb1\x10\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\vࡐ\x00\x00\x00\x00\fٿ" +
+	"\x00\x00\x00\x00\x00\r\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00" +
+	"\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&" +
+	"\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00" +
+	"\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeߐ\x00\x00\x00\x00)\nr" +
+	"\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00" +
+	"\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*" +
+	"\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00" +
+	"\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_" +
+	"\x80\x00\x00\x00\x00E\xf3\xc5\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\x9d\x94\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff" +
+	"\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10LMT\x00MDT\x00MST\x00MWT\x00MPT\x00\nMST7MDT,M3.2.0,M11.1.0\n" +
+	"PK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00\x00\x03\x00\x00\x00PRCTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d" +
+	"\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff~6C)\xff\xff\xff\xff\xa0\x97\xa2\x80\xff\xff\xff\xff\xa1y\x04\xf0\xff\xff\xff\xff\xc8Y^\x80\xff\xff\xff\xff\xc9\t\xf9p\xff\xff\xff\xff\xc9ӽ\x00\xff\xff\xff\xff" +
+	"\xcb\x05\x8a\xf0\xff\xff\xff\xff\xcb|@\x00\xff\xff\xff\xff\xd2;>\xf0\xff\xff\xff\xffӋ{\x80\xff\xff\xff\xff\xd4B\xad\xf0\xff\xff\xff\xff\xd5E\"\x00\xff\xff\xff\xff\xd6L\xbf\xf0\xff\xff\xff\xff\xd7<\xbf\x00" +
+	"\xff\xff\xff\xff\xd8\x06fp\xff\xff\xff\xff\xd9\x1d\xf2\x80\xff\xff\xff\xff\xd9A|\xf0\x00\x00\x00\x00\x1e\xbaR \x00\x00\x00\x00\x1fi\x9b\x90\x00\x00\x00\x00 ~\x84\xa0\x00\x00\x00\x00!I}\x90\x00\x00\x00\x00" +
+	"\"g\xa1 \x00\x00\x00\x00#)_\x90\x00\x00\x00\x00$G\x83 \x00\x00\x00\x00%\x12|\x10\x00\x00\x00\x00&'e \x00\x00\x00\x00&\xf2^\x10\x00\x00\x00\x00(\aG \x00\x00\x00\x00(\xd2@\x10" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00q\xd7\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\bLMT\x00CDT\x00CST\x00\n" +
+	"CST-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ŭV\xad\xb7\x03\x00\x00\xb7\x03\x00\x00\a\x00\x00\x00PST8PDTTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00X\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\x9e\xa6H\xa0\xff\xff\xff\xff\x9f\xbb\x15\x90\xff\xff\xff\xff\xa0\x86*\xa0\xff\xff\xff\xff\xa1\x9a\xf7\x90\xff\xff\xff\xffˉ\x1a\xa0\xff\xff" +
+	"\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a&\x10\xff\xff\xff\xff\xfa\xf8\x83 \xff\xff\xff\xff\xfb\xe8f\x10\xff\xff\xff\xff\xfc\xd8e \xff\xff\xff\xff\xfd\xc8H\x10\xff\xff\xff\xff\xfe\xb8G \xff\xff\xff\xff\xff\xa8" +
+	"*\x10\x00\x00\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88\f\x10\x00\x00\x00\x00\x02x\v \x00\x00\x00\x00\x03q(\x90\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05Q\n\x90\x00\x00\x00\x00\x06A\t\xa0\x00\x00" +
+	"\x00\x00\a0\xec\x90\x00\x00\x00\x00\a\x8dC\xa0\x00\x00\x00\x00\t\x10ΐ\x00\x00\x00\x00\t\xad\xbf \x00\x00\x00\x00\n\xf0\xb0\x90\x00\x00\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r\xc0" +
+	"\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00" +
+	"\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2" +
+	"\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1ې\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\"V\r \x00\x00" +
+	"\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\n\x80\x10\x00\x00\x00\x00)\xde" +
+	"Ϡ\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00" +
+	"\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\a8 \x00\x00\x00\x008\x1c" +
+	"\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00" +
+	"\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E\xf3" +
+	"\xd3 \x01\x00\x01\x00\x02\x03\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01" +
+	"\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\xff\xff\x8f\x80\x00\x04\xff\xff\x9d\x90\x01\x00\xff\xff\x9d\x90\x01\b\xff\xff\x9d\x90\x01\fPDT\x00PS" +
+	"T\x00PWT\x00PPT\x00\nPST8PDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa8A\x15\xfe\x97\x01\x00\x00\x97\x01\x00\x00" +
+	"\f\x00\x00\x00Pacific/ApiaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01" +
+	"\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1a\x00\x00\x00\a\x00\x00\x00\x1a\xff\xff\xff\xffn=\xc9\x00\xff" +
+	"\xff\xff\xff\x91\x05\xfc\x00\xff\xff\xff\xff\xdab\x048\x00\x00\x00\x00L\x9f'\xb0\x00\x00\x00\x00M\x97+\xe0\x00\x00\x00\x00N}\xe2`\x00\x00\x00\x00N\xfd\x8b\xa0\x00\x00\x00\x00Ow\r\xe0\x00\x00\x00\x00P" +
+	"f\xfe\xe0\x00\x00\x00\x00Q`*`\x00\x00\x00\x00RF\xe0\xe0\x00\x00\x00\x00S@\f`\x00\x00\x00\x00T&\xc2\xe0\x00\x00\x00\x00U\x1f\xee`\x00\x00\x00\x00V\x06\xa4\xe0\x00\x00\x00\x00V\xff\xd0`\x00" +
+	"\x00\x00\x00W\xe6\x86\xe0\x00\x00\x00\x00X߲`\x00\x00\x00\x00Y\xc6h\xe0\x00\x00\x00\x00Z\xbf\x94`\x00\x00\x00\x00[\xaf\x85`\x00\x00\x00\x00\\\xa8\xb0\xe0\x00\x00\x00\x00]\x8fg`\x00\x00\x00\x00^" +
+	"\x88\x92\xe0\x00\x00\x00\x00_oI`\x00\x00\x00\x00`ht\xe0\x01\x02\x04\x03\x04\x03\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x00\x00\xb0\x80\x00\x00\xff\xff_\x00\x00\x00\xff\xff^" +
+	"H\x00\x04\xff\xffs`\x01\n\xff\xffeP\x00\x0e\x00\x00\xb6\xd0\x00\x12\x00\x00\xc4\xe0\x01\x16LMT\x00-1130\x00-10\x00-11\x00+13\x00+14\x00\n<+13>-" +
+	"13\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b\xb2\xaf\xf7\x13\x04\x00\x00\x13\x04\x00\x00\x10\x00\x00\x00Pacific/AucklandTZif2\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`\x00\x00\x00\x06\x00\x00\x00\x13\xff\xff\xff\xffA\xb7L\xa8\xff\xff\xff\xff\xb0\xb4\xb2\xe8\xff\xff\xff\xff\xb1Q\x87X\xff\xff\xff\xff\xb2x\xe5h\xff\xff\xff\xff" +
+	"\xb3C\xe5`\xff\xff\xff\xff\xb4X\xc7h\xff\xff\xff\xff\xb5#\xc7`\xff\xff\xff\xff\xb68\xa9h\xff\xff\xff\xff\xb7\x03\xa9`\xff\xff\xff\xff\xb8\x18\x8bh\xff\xff\xff\xff\xb8\xec\xc5\xe0\xff\xff\xff\xff\xb9\xf8mh" +
+	"\xff\xff\xff\xff\xba̧\xe0\xff\xff\xff\xff\xbb\xd8Oh\xff\xff\xff\xff\xbc\xe3\xe8\xe0\xff\xff\xff\xff\xbd\xae\xf6\xe8\xff\xff\xff\xff\xbe\xc3\xca\xe0\xff\xff\xff\xff\xbf\x8e\xd8\xe8\xff\xff\xff\xff\xc0\xa3\xac\xe0\xff\xff\xff\xff" +
+	"\xc1n\xba\xe8\xff\xff\xff\xff\u0083\x8e\xe0\xff\xff\xff\xff\xc3N\x9c\xe8\xff\xff\xff\xff\xc4cp\xe0\xff\xff\xff\xff\xc5.~\xe8\xff\xff\xff\xff\xc6L\x8d`\xff\xff\xff\xff\xc7\x0e`\xe8\xff\xff\xff\xff\xc8,o`" +
+	"\xff\xff\xff\xff\xc8\xf7}h\xff\xff\xff\xff\xd2ښ@\x00\x00\x00\x00\t\x18\xfd\xe0\x00\x00\x00\x00\t\xac\xa5\xe0\x00\x00\x00\x00\n\xef\xa5`\x00\x00\x00\x00\v\x9e\xfc\xe0\x00\x00\x00\x00\f\xd8\xc1\xe0\x00\x00\x00\x00" +
+	"\r~\xde\xe0\x00\x00\x00\x00\x0e\xb8\xa3\xe0\x00\x00\x00\x00\x0f^\xc0\xe0\x00\x00\x00\x00\x10\x98\x85\xe0\x00\x00\x00\x00\x11>\xa2\xe0\x00\x00\x00\x00\x12xg\xe0\x00\x00\x00\x00\x13\x1e\x84\xe0\x00\x00\x00\x00\x14XI\xe0" +
+	"\x00\x00\x00\x00\x14\xfef\xe0\x00\x00\x00\x00\x168+\xe0\x00\x00\x00\x00\x16\xe7\x83`\x00\x00\x00\x00\x18!H`\x00\x00\x00\x00\x18\xc7e`\x00\x00\x00\x00\x1a\x01*`\x00\x00\x00\x00\x1a\xa7G`\x00\x00\x00\x00" +
+	"\x1b\xe1\f`\x00\x00\x00\x00\x1c\x87)`\x00\x00\x00\x00\x1d\xc0\xee`\x00\x00\x00\x00\x1eg\v`\x00\x00\x00\x00\x1f\xa0\xd0`\x00\x00\x00\x00 F\xed`\x00\x00\x00\x00!\x80\xb2`\x00\x00\x00\x00\"0\t\xe0" +
+	"\x00\x00\x00\x00#i\xce\xe0\x00\x00\x00\x00$\x0f\xeb\xe0\x00\x00\x00\x00%.\x01`\x00\x00\x00\x00&\x02B\xe0\x00\x00\x00\x00'\r\xe3`\x00\x00\x00\x00'\xe2$\xe0\x00\x00\x00\x00(\xed\xc5`\x00\x00\x00\x00" +
+	")\xc2\x06\xe0\x00\x00\x00\x00*ͧ`\x00\x00\x00\x00+\xab#`\x00\x00\x00\x00,\xad\x89`\x00\x00\x00\x00-\x8b\x05`\x00\x00\x00\x00.\x8dk`\x00\x00\x00\x00/j\xe7`\x00\x00\x00\x000mM`" +
+	"\x00\x00\x00\x001J\xc9`\x00\x00\x00\x002Vi\xe0\x00\x00\x00\x003*\xab`\x00\x00\x00\x0046K\xe0\x00\x00\x00\x005\n\x8d`\x00\x00\x00\x006\x16-\xe0\x00\x00\x00\x006\xf3\xa9\xe0\x00\x00\x00\x00" +
+	"7\xf6\x0f\xe0\x00\x00\x00\x008Ӌ\xe0\x00\x00\x00\x009\xd5\xf1\xe0\x00\x00\x00\x00:\xb3m\xe0\x00\x00\x00\x00;\xbf\x0e`\x00\x00\x00\x00<\x93O\xe0\x00\x00\x00\x00=\x9e\xf0`\x00\x00\x00\x00>s1\xe0" +
+	"\x00\x00\x00\x00?~\xd2`\x00\x00\x00\x00@\\N`\x00\x00\x00\x00A^\xb4`\x00\x00\x00\x00B<0`\x00\x00\x00\x00C>\x96`\x00\x00\x00\x00D\x1c\x12`\x00\x00\x00\x00E\x1ex`\x00\x00\x00\x00" +
+	"E\xfb\xf4`\x00\x00\x00\x00F\xfeZ`\x02\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" +
+	"\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x00\x00\xa3\xd8\x00\x00\x00\x00\xaf\xc8\x01\x04" +
+	"\x00\x00\xa1\xb8\x00\t\x00\x00\xa8\xc0\x01\x04\x00\x00\xb6\xd0\x01\x0e\x00\x00\xa8\xc0\x00\x04LMT\x00NZST\x00NZMT\x00NZDT\x00\nNZST-12NZDT,M9.5" +
+	".0,M4.1.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9a\xf2:F\xc9\x00\x00\x00\xc9\x00\x00\x00\x14\x00\x00\x00Pacific/Bougainvil" +
+	"leTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xffV\xb6R(\xff\xff\xff\xffr\xed\xa4\x90\xff\xff\xff\xff\xccC6" +
+	"`\xff\xff\xff\xff\xd2+l\xf0\x00\x00\x00\x00T\x9e׀\x01\x02\x03\x02\x04\x00\x00\x91\xd8\x00\x00\x00\x00\x89\xf0\x00\x04\x00\x00\x8c\xa0\x00\t\x00\x00~\x90\x00\r\x00\x00\x9a\xb0\x00\x11LMT\x00PMMT" +
+	"\x00+10\x00+09\x00+11\x00\n<+11>-11\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xc5FF(\x03\x00\x00(\x03\x00\x00\x0f\x00\x00\x00Pacific" +
+	"/ChathamTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00T" +
+	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\x00\x00\x00\x04\x00\x00\x00\x16\xff\xff\xff\xffA\xb7D\x84\xff\xff\xff\xff\xd2ږ\xbc\x00" +
+	"\x00\x00\x00\t\x18\xfd\xe0\x00\x00\x00\x00\t\xac\xa5\xe0\x00\x00\x00\x00\n\xef\xa5`\x00\x00\x00\x00\v\x9e\xfc\xe0\x00\x00\x00\x00\f\xd8\xc1\xe0\x00\x00\x00\x00\r~\xde\xe0\x00\x00\x00\x00\x0e\xb8\xa3\xe0\x00\x00\x00\x00\x0f" +
+	"^\xc0\xe0\x00\x00\x00\x00\x10\x98\x85\xe0\x00\x00\x00\x00\x11>\xa2\xe0\x00\x00\x00\x00\x12xg\xe0\x00\x00\x00\x00\x13\x1e\x84\xe0\x00\x00\x00\x00\x14XI\xe0\x00\x00\x00\x00\x14\xfef\xe0\x00\x00\x00\x00\x168+\xe0\x00" +
+	"\x00\x00\x00\x16\xe7\x83`\x00\x00\x00\x00\x18!H`\x00\x00\x00\x00\x18\xc7e`\x00\x00\x00\x00\x1a\x01*`\x00\x00\x00\x00\x1a\xa7G`\x00\x00\x00\x00\x1b\xe1\f`\x00\x00\x00\x00\x1c\x87)`\x00\x00\x00\x00\x1d" +
+	"\xc0\xee`\x00\x00\x00\x00\x1eg\v`\x00\x00\x00\x00\x1f\xa0\xd0`\x00\x00\x00\x00 F\xed`\x00\x00\x00\x00!\x80\xb2`\x00\x00\x00\x00\"0\t\xe0\x00\x00\x00\x00#i\xce\xe0\x00\x00\x00\x00$\x0f\xeb\xe0\x00" +
+	"\x00\x00\x00%.\x01`\x00\x00\x00\x00&\x02B\xe0\x00\x00\x00\x00'\r\xe3`\x00\x00\x00\x00'\xe2$\xe0\x00\x00\x00\x00(\xed\xc5`\x00\x00\x00\x00)\xc2\x06\xe0\x00\x00\x00\x00*ͧ`\x00\x00\x00\x00+" +
+	"\xab#`\x00\x00\x00\x00,\xad\x89`\x00\x00\x00\x00-\x8b\x05`\x00\x00\x00\x00.\x8dk`\x00\x00\x00\x00/j\xe7`\x00\x00\x00\x000mM`\x00\x00\x00\x001J\xc9`\x00\x00\x00\x002Vi\xe0\x00" +
+	"\x00\x00\x003*\xab`\x00\x00\x00\x0046K\xe0\x00\x00\x00\x005\n\x8d`\x00\x00\x00\x006\x16-\xe0\x00\x00\x00\x006\xf3\xa9\xe0\x00\x00\x00\x007\xf6\x0f\xe0\x00\x00\x00\x008Ӌ\xe0\x00\x00\x00\x009" +
+	"\xd5\xf1\xe0\x00\x00\x00\x00:\xb3m\xe0\x00\x00\x00\x00;\xbf\x0e`\x00\x00\x00\x00<\x93O\xe0\x00\x00\x00\x00=\x9e\xf0`\x00\x00\x00\x00>s1\xe0\x00\x00\x00\x00?~\xd2`\x00\x00\x00\x00@\\N`\x00" +
+	"\x00\x00\x00A^\xb4`\x00\x00\x00\x00B<0`\x00\x00\x00\x00C>\x96`\x00\x00\x00\x00D\x1c\x12`\x00\x00\x00\x00E\x1ex`\x00\x00\x00\x00E\xfb\xf4`\x00\x00\x00\x00F\xfeZ`\x01\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x00\x00\xab\xfc\x00\x00\x00\x00\xacD\x00\x04\x00\x00\xc1\\\x01\n\x00\x00\xb3L\x00\x10LMT\x00+1215\x00+1345\x00+1245\x00\n<+1245>-1" +
+	"2:45<+1345>,M9.5.0/2:45,M4.1.0/3:45\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\x04\x19y\x9a\x00\x00\x00\x9a\x00" +
+	"\x00\x00\r\x00\x00\x00Pacific/ChuukTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00" +
+	"\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xffV\xb6" +
+	"Z\b\xff\xff\xff\xffr\xed\xa4\x90\x01\x02\x00\x00\x89\xf8\x00\x00\x00\x00\x89\xf0\x00\x04\x00\x00\x8c\xa0\x00\tLMT\x00PMMT\x00+10\x00\n<+10>-10\nPK\x03\x04\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00?X'\x8e\x96\x04\x00\x00\x96\x04\x00\x00\x0e\x00\x00\x00Pacific/EasterTZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00n\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffi\x87B\b\xff\xff\xff\xff\xb9\xc7@\x88\xff\xff\xff\xff\xfd\xd1<@\xff\xff\xff\xff\xfe\x92\xfa\xb0\xff\xff\xff\xff\xff\xcc\xcd\xc0\x00\x00\x00\x00\x00rܰ" +
+	"\x00\x00\x00\x00\x01uP\xc0\x00\x00\x00\x00\x02@I\xb0\x00\x00\x00\x00\x03U2\xc0\x00\x00\x00\x00\x04 +\xb0\x00\x00\x00\x00\x05>O@\x00\x00\x00\x00\x06\x00\r\xb0\x00\x00\x00\x00\a\v\xbc@\x00\x00\x00\x00" +
+	"\a\xdf\xef\xb0\x00\x00\x00\x00\b\xfe\x13@\x00\x00\x00\x00\t\xbfѰ\x00\x00\x00\x00\n\xdd\xf5@\x00\x00\x00\x00\v\xa8\xee0\x00\x00\x00\x00\f\xbd\xd7@\x00\x00\x00\x00\r\x88\xd00\x00\x00\x00\x00\x0e\x9d\xb9@" +
+	"\x00\x00\x00\x00\x0fh\xb20\x00\x00\x00\x00\x10\x86\xd5\xc0\x00\x00\x00\x00\x11H\x940\x00\x00\x00\x00\x12f\xb7\xc0\x00\x00\x00\x00\x13(v0\x00\x00\x00\x00\x14F\x99\xc0\x00\x00\x00\x00\x15\x11\x92\xb0\x00\x00\x00\x00" +
+	"\x16&{\xc0\x00\x00\x00\x00\x16\xf1t\xb0\x00\x00\x00\x00\x18\x06]\xc0\x00\x00\x00\x00\x18\xd1V\xb0\x00\x00\x00\x00\x19\xe6?\xc0\x00\x00\x00\x00\x1a\xb18\xb0\x00\x00\x00\x00\x1b\xcf\\@\x00\x00\x00\x00\x1c\x91\x1a\xb0" +
+	"\x00\x00\x00\x00\x1d\xaf>@\x00\x00\x00\x00\x1ep\xfc\xb0\x00\x00\x00\x00\x1f\x8f @\x00\x00\x00\x00 \x7f\x030\x00\x00\x00\x00!o\x02@\x00\x00\x00\x00\"9\xfb0\x00\x00\x00\x00#N\xe4@\x00\x00\x00\x00" +
+	"$\x19\xdd0\x00\x00\x00\x00%8\x00\xc0\x00\x00\x00\x00%\xf9\xbf0\x00\x00\x00\x00&\xf2\xf8\xc0\x00\x00\x00\x00'١0\x00\x00\x00\x00(\xf7\xc4\xc0\x00\x00\x00\x00)½\xb0\x00\x00\x00\x00*צ\xc0" +
+	"\x00\x00\x00\x00+\xa2\x9f\xb0\x00\x00\x00\x00,\xb7\x88\xc0\x00\x00\x00\x00-\x82\x81\xb0\x00\x00\x00\x00.\x97j\xc0\x00\x00\x00\x00/bc\xb0\x00\x00\x00\x000\x80\x87@\x00\x00\x00\x001BE\xb0\x00\x00\x00\x00" +
+	"2`i@\x00\x00\x00\x003=\xd70\x00\x00\x00\x004@K@\x00\x00\x00\x005\vD0\x00\x00\x00\x006\r\xb8@\x00\x00\x00\x007\x06հ\x00\x00\x00\x008\x00\x0f@\x00\x00\x00\x008\xcb\b0" +
+	"\x00\x00\x00\x009\xe9+\xc0\x00\x00\x00\x00:\xaa\xea0\x00\x00\x00\x00;\xc9\r\xc0\x00\x00\x00\x00<\x8a\xcc0\x00\x00\x00\x00=\xa8\xef\xc0\x00\x00\x00\x00>j\xae0\x00\x00\x00\x00?\x88\xd1\xc0\x00\x00\x00\x00" +
+	"@Sʰ\x00\x00\x00\x00Ah\xb3\xc0\x00\x00\x00\x00B3\xac\xb0\x00\x00\x00\x00CH\x95\xc0\x00\x00\x00\x00D\x13\x8e\xb0\x00\x00\x00\x00E1\xb2@\x00\x00\x00\x00E\xf3p\xb0\x00\x00\x00\x00G\x11\x94@" +
+	"\x00\x00\x00\x00G\xef\x020\x00\x00\x00\x00H\xf1v@\x00\x00\x00\x00I\xbco0\x00\x00\x00\x00J\xd1X@\x00\x00\x00\x00K\xb8\x00\xb0\x00\x00\x00\x00L\xb1:@\x00\x00\x00\x00M\xc6\a0\x00\x00\x00\x00" +
+	"NP\x82\xc0\x00\x00\x00\x00O\x9c\xae\xb0\x00\x00\x00\x00PB\xd9\xc0\x00\x00\x00\x00Q|\x90\xb0\x00\x00\x00\x00R+\xf6@\x00\x00\x00\x00S\\r\xb0\x00\x00\x00\x00T\v\xd8@\x00\x00\x00\x00W7\xe60" +
+	"\x00\x00\x00\x00W\xaf\xec\xc0\x00\x00\x00\x00Y\x17\xc80\x00\x00\x00\x00Y\x8f\xce\xc0\x00\x00\x00\x00Z\xf7\xaa0\x00\x00\x00\x00[o\xb0\xc0\x00\x00\x00\x00\\\xa9g\xb0\x00\x00\x00\x00]t|\xc0\x00\x00\x00\x00" +
+	"^\x89I\xb0\x00\x00\x00\x00_T^\xc0\x00\x00\x00\x00`i+\xb0\x00\x00\x00\x00a4@\xc0\x00\x00\x00\x00bI\r\xb0\x00\x00\x00\x00c\x1d]@\x00\x00\x00\x00d(\xef\xb0\x01\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04" +
+	"\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\xff\xff\x99x\x00\x00\xff\xff\x99x\x00\x04\xff\xff\xab\xa0\x01\b" +
+	"\xff\xff\x9d\x90\x00\f\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\x10LMT\x00EMT\x00-06\x00-07\x00-05\x00\n<-06>6<-05>,M9.1.6/22" +
+	",M4.1.6/22\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9e\x7f\xab\x95V\x01\x00\x00V\x01\x00\x00\r\x00\x00\x00Pacific/EfateTZif2\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x92\xf5´\x00\x00\x00\x00\ay\x99@\x00\x00\x00\x00\a\xfa\xcc@\x00\x00\x00\x00\x19\xd2\xf7" +
+	"\xd0\x00\x00\x00\x00\x1a\xc2\xda\xc0\x00\x00\x00\x00\x1b\xb2\xd9\xd0\x00\x00\x00\x00\x1c\xa2\xbc\xc0\x00\x00\x00\x00\x1d\x9b\xf6P\x00\x00\x00\x00\x1e\x82\x9e\xc0\x00\x00\x00\x00\x1f{\xd8P\x00\x00\x00\x00 k\xbb@\x00\x00\x00" +
+	"\x00![\xbaP\x00\x00\x00\x00\"K\x9d@\x00\x00\x00\x00#;\x9cP\x00\x00\x00\x00$+\x7f@\x00\x00\x00\x00%\x1b~P\x00\x00\x00\x00&\va@\x00\x00\x00\x00&\xfb`P\x00\x00\x00\x00'\xebC" +
+	"@\x00\x00\x00\x00(\xe4|\xd0\x00\x00\x00\x00)\x81Q@\x00\x00\x00\x00*\xe9H\xd0\x00\x00\x00\x00+a3@\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x9d\xcc" +
+	"\x00\x00\x00\x00\xa8\xc0\x01\x04\x00\x00\x9a\xb0\x00\bLMT\x00+12\x00+11\x00\n<+11>-11\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xec =\x89\xac\x00\x00\x00\xac\x00" +
+	"\x00\x00\x11\x00\x00\x00Pacific/EnderburyTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff" +
+	"\xff\xff\xc3,ۀ\x00\x00\x00\x00\x12V\x04\xc0\x00\x00\x00\x00/\x059\xb0\x01\x02\x03\x00\x00\x00\x00\x00\x00\xff\xffW@\x00\x04\xff\xffeP\x00\b\x00\x00\xb6\xd0\x00\f-00\x00-12\x00-11" +
+	"\x00+13\x00\n<+13>-13\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8a|\xdcU\x99\x00\x00\x00\x99\x00\x00\x00\x0f\x00\x00\x00Pacific/Fakaofo" +
+	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff~7U\x88\x00\x00\x00\x00N\xfd\x99\xb0\x01\x02\xff\xff_x\x00\x00\xff" +
+	"\xffeP\x00\x04\x00\x00\xb6\xd0\x00\bLMT\x00-11\x00+13\x00\n<+13>-13\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfd_yl\x8c\x01\x00\x00\x8c\x01\x00\x00\f" +
+	"\x00\x00\x00Pacific/FijiTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00" +
+	"\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x9a\x13\xb1\xc0\x00\x00" +
+	"\x00\x006;\x17\xe0\x00\x00\x00\x006\xd7\xfa`\x00\x00\x00\x008$4`\x00\x00\x00\x008\xb7\xdc`\x00\x00\x00\x00K\x11,\xe0\x00\x00\x00\x00K\xae\x0f`\x00\x00\x00\x00L\xc2\xea`\x00\x00\x00\x00Mr" +
+	"A\xe0\x00\x00\x00\x00N\xa2\xcc`\x00\x00\x00\x00O\x1a\xc4\xe0\x00\x00\x00\x00P\x82\xae`\x00\x00\x00\x00P\xfa\xa6\xe0\x00\x00\x00\x00Rk\xca\xe0\x00\x00\x00\x00R\xdaz\xd0\x00\x00\x00\x00TT\xe7`\x00\x00" +
+	"\x00\x00T\xbaj\xe0\x00\x00\x00\x00V4\xc9`\x00\x00\x00\x00V\x9aL\xe0\x00\x00\x00\x00X\x1d\xe5\xe0\x00\x00\x00\x00Xz.\xe0\x00\x00\x00\x00Y\xfd\xc7\xe0\x00\x00\x00\x00ZZ\x10\xe0\x00\x00\x00\x00[\xdd" +
+	"\xa9\xe0\x00\x00\x00\x00\\9\xf2\xe0\x00\x00\x00\x00]\xc6\xc6`\x00\x00\x00\x00^\x19\xd4\xe0\x00\x00\x00\x00_\xde\a`\x00\x00\x00\x00`\x02\xf1`\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\xa7\xc0\x00\x00\x00\x00\xb6\xd0\x01\x04\x00\x00\xa8\xc0\x00\bLMT\x00+13\x00+12\x00\n<+12>-12\nPK\x03\x04\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x006\xb7S{\x86\x00\x00\x00\x86\x00\x00\x00\x10\x00\x00\x00Pacific/FunafutiTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff~6\x12\xcc\x01\x00\x00\xa24\x00\x00\x00\x00\xa8\xc0\x00\x04LMT\x00+12\x00\n<+12>-12\nPK\x03\x04\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x81\xe3w\n\xaf\x00\x00\x00\xaf\x00\x00\x00\x11\x00\x00\x00Pacific/GalapagosTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xff\xb6\xa4L\x80\x00\x00\x00\x00\x1e\x18\xc4P\x00\x00\x00\x00+\x17\n\xe0\x00\x00\x00\x00+q\xf4P\x01\x03\x02\x03\xff\xff\xac\x00\x00\x00\xff\xff\xb9\xb0\x00" +
+	"\x04\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\bLMT\x00-05\x00-06\x00\n<-06>6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc23\xa0\xbc\x84\x00\x00\x00\x84\x00\x00\x00\x0f" +
+	"\x00\x00\x00Pacific/GambierTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00" +
+	"\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x94PH" +
+	"\x04\x01\xff\xff\x81|\x00\x00\xff\xff\x81p\x00\x04LMT\x00-09\x00\n<-09>9\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y\xd2K|\x86\x00\x00\x00\x86\x00\x00\x00\x13\x00\x00\x00" +
+	"Pacific/GuadalcanalTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00" +
+	"\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x94O" +
+	"3\x8c\x01\x00\x00\x95\xf4\x00\x00\x00\x00\x9a\xb0\x00\x04LMT\x00+11\x00\n<+11>-11\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00FI\xfe\x14^\x01\x00\x00^\x01\x00\x00\f" +
+	"\x00\x00\x00Pacific/GuamTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00" +
+	"\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x00\x06\x00\x00\x00\x15\xff\xff\xff\xff\x14\xe1\xc5\xcc\xff\xff" +
+	"\xff\xff~6-L\xff\xff\xff\xff\xcb7\x95\xe0\xff\xff\xff\xff\xd0.\x89\xf0\xff\xff\xff\xff\xec7\xbe\x00\xff\xff\xff\xff\xef6\xf8\xf0\xff\xff\xff\xff\xfb\x9b\x00\x00\xff\xff\xff\xff\xfe?'\x8c\xff\xff\xff\xff\xff\x01" +
+	"\x1e\x00\xff\xff\xff\xff\xff]X\xf0\x00\x00\x00\x00\x00\x97,\x00\x00\x00\x00\x00\x01Fup\x00\x00\x00\x00\x02w\x0e\x00\x00\x00\x00\x00\x03&Wp\x00\x00\x00\x00\ap\x97\x00\x00\x00\x00\x00\a\xcc\xd1\xf0\x00\x00" +
+	"\x00\x00\f\b\x91\x00\x00\x00\x00\x00\f|\x87,\x00\x00\x00\x00\r\xbf\x94\x80\x00\x00\x00\x00\x0ee\xa3p\x00\x00\x00\x00:C^`\x01\x02\x03\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x05\xff" +
+	"\xff64\x00\x00\x00\x00\x87\xb4\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00~\x90\x00\b\x00\x00\x9a\xb0\x01\f\x00\x00\x8c\xa0\x00\x10LMT\x00GST\x00+09\x00GDT\x00ChST\x00\nChS" +
+	"T-10\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xeaK\x85v\xdd\x00\x00\x00\xdd\x00\x00\x00\x10\x00\x00\x00Pacific/HonoluluTZif2\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xfft\xe0p\xbe\xff\xff\xff\xff\xbb\x05CH\xff\xff\xff\xff\xbb!qX\xff\xff\xff\xffˉ=\xc8\xff\xff" +
+	"\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2aI8\xff\xff\xff\xffՍsH\x01\x02\x01\x03\x04\x01\x05\xff\xffl\x02\x00\x00\xff\xfflX\x00\x04\xff\xffzh\x01\b\xff\xffzh\x01\f\xff\xffzh\x01\x10\xff" +
+	"\xffs`\x00\x04LMT\x00HST\x00HDT\x00HWT\x00HPT\x00\nHST10\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xeaK\x85v\xdd\x00\x00\x00\xdd\x00\x00\x00\x10\x00" +
+	"\x00\x00Pacific/JohnstonTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00" +
+	"\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xfft\xe0p" +
+	"\xbe\xff\xff\xff\xff\xbb\x05CH\xff\xff\xff\xff\xbb!qX\xff\xff\xff\xffˉ=\xc8\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2aI8\xff\xff\xff\xffՍsH\x01\x02\x01\x03\x04\x01\x05\xff\xffl\x02" +
+	"\x00\x00\xff\xfflX\x00\x04\xff\xffzh\x01\b\xff\xffzh\x01\f\xff\xffzh\x01\x10\xff\xffs`\x00\x04LMT\x00HST\x00HDT\x00HWT\x00HPT\x00\nHST10\nP" +
+	"K\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xec =\x89\xac\x00\x00\x00\xac\x00\x00\x00\x0e\x00\x00\x00Pacific/KantonTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\xc3,ۀ\x00\x00\x00\x00\x12V\x04\xc0\x00\x00\x00\x00/\x059\xb0\x01\x02\x03\x00\x00\x00\x00\x00\x00\xff\xffW@\x00\x04\xff\xffe" +
+	"P\x00\b\x00\x00\xb6\xd0\x00\f-00\x00-12\x00-11\x00+13\x00\n<+13>-13\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8=ku\xae\x00\x00\x00\xae\x00\x00" +
+	"\x00\x12\x00\x00\x00Pacific/KiritimatiTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff" +
+	"\xff\xff~7H\x80\x00\x00\x00\x00\x12U\xf2\x00\x00\x00\x00\x00/\x05+\xa0\x01\x02\x03\xff\xffl\x80\x00\x00\xff\xffj\x00\x00\x04\xff\xffs`\x00\n\x00\x00\xc4\xe0\x00\x0eLMT\x00-1040\x00-" +
+	"10\x00+14\x00\n<+14>-14\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x97n7\x1a\xf2\x00\x00\x00\xf2\x00\x00\x00\x0e\x00\x00\x00Pacific/Kosra" +
+	"eTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xff\x14ᴴ\xff\xff\xff\xff~6\x1c4\xff\xff\xff\xff\x98\x11\x95\xd0" +
+	"\xff\xff\xff\xff\xa09\xf9\xf0\xff\xff\xff\xff\xc1\xed5\xd0\xff\xff\xff\xff\xc9\xea\n`\xff\xff\xff\xff\xd2\x11\x0e\xf0\xff\xff\xff\xff\xff\x86\x1bP\x00\x00\x00\x006\x8bg@\x01\x02\x03\x02\x04\x03\x02\x05\x02\xff\xffG" +
+	"L\x00\x00\x00\x00\x98\xcc\x00\x00\x00\x00\x9a\xb0\x00\x04\x00\x00~\x90\x00\b\x00\x00\x8c\xa0\x00\f\x00\x00\xa8\xc0\x00\x10LMT\x00+11\x00+09\x00+10\x00+12\x00\n<+11>-" +
+	"11\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\xe8]*\xdb\x00\x00\x00\xdb\x00\x00\x00\x11\x00\x00\x00Pacific/KwajaleinTZif2\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff~6\x18 \xff\xff\xff\xff\xc1\xed5\xd0\xff\xff\xff\xff\xc9\xea\n`\xff\xff\xff\xff\xcfF\x81\xf0\xff\xff\xff" +
+	"\xff\xff\x86\x1bP\x00\x00\x00\x00,v\x0e@\x01\x02\x03\x01\x04\x05\x00\x00\x9c\xe0\x00\x00\x00\x00\x9a\xb0\x00\x04\x00\x00\x8c\xa0\x00\b\x00\x00~\x90\x00\f\xff\xffW@\x00\x10\x00\x00\xa8\xc0\x00\x14LMT\x00+" +
+	"11\x00+10\x00+09\x00-12\x00+12\x00\n<+12>-12\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x006\xb7S{\x86\x00\x00\x00\x86\x00\x00\x00\x0e\x00\x00\x00P" +
+	"acific/MajuroTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00" +
+	"\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff~6\x12\xcc\x01\x00\x00\xa2" +
+	"4\x00\x00\x00\x00\xa8\xc0\x00\x04LMT\x00+12\x00\n<+12>-12\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00D6\x83\xa1\x8b\x00\x00\x00\x8b\x00\x00\x00\x11\x00\x00\x00Pac" +
+	"ific/MarquesasTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00" +
+	"\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\n\xff\xff\xff\xff\x94PLH\x01\xff\xff" +
+	"}8\x00\x00\xff\xffzh\x00\x04LMT\x00-0930\x00\n<-0930>9:30\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\xca{e\x92\x00\x00\x00\x92\x00\x00\x00\x0e" +
+	"\x00\x00\x00Pacific/MidwayTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00" +
+	"\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\b\xff\xff\xff\xffn=\xc8\b" +
+	"\xff\xff\xff\xff\x91\x05\xfb\b\x01\x02\x00\x00\xb1x\x00\x00\xff\xff_\xf8\x00\x00\xff\xffeP\x00\x04LMT\x00SST\x00\nSST11\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe2;Z" +
+	"\xf7\xb7\x00\x00\x00\xb7\x00\x00\x00\r\x00\x00\x00Pacific/NauruTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00" +
+	"\x12\xff\xff\xff\xff\xa3\xe7+\x04\xff\xff\xff\xff̐\xe9\xc8\xff\xff\xff\xff\xd2C'\xf0\x00\x00\x00\x00\x11!\xa8\xe8\x01\x02\x01\x03\x00\x00\x9c|\x00\x00\x00\x00\xa1\xb8\x00\x04\x00\x00~\x90\x00\n\x00\x00\xa8\xc0\x00" +
+	"\x0eLMT\x00+1130\x00+09\x00+12\x00\n<+12>-12\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x91\xd60\f\x9a\x00\x00\x00\x9a\x00\x00\x00\f\x00\x00\x00P" +
+	"acific/NiueTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00" +
+	"\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffߡjL\xff\xff\xff\xff\xf5\xa6" +
+	"\xb8`\x01\x02\xff\xff`\xb4\x00\x00\xff\xff`\xa0\x00\x04\xff\xffeP\x00\nLMT\x00-1120\x00-11\x00\n<-11>11\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y" +
+	"5\x1a6\xf7\x00\x00\x00\xf7\x00\x00\x00\x0f\x00\x00\x00Pacific/NorfolkTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00" +
+	"\x06\x00\x00\x00\x1e\xff\xff\xff\xff~6\x17\x88\xff\xff\xff\xff\xdcA\xf8\x80\x00\x00\x00\x00\t\x0f\xcah\x00\x00\x00\x00\t\xb5\xe7h\x00\x00\x00\x00V\x0f\xe6h\x00\x00\x00\x00]\x98\xaf\xf0\x01\x02\x03\x02\x04\x05\x00" +
+	"\x00\x9dx\x00\x00\x00\x00\x9d\x80\x00\x04\x00\x00\xa1\xb8\x00\n\x00\x00\xaf\xc8\x01\x10\x00\x00\x9a\xb0\x00\x16\x00\x00\xa8\xc0\x01\x1aLMT\x00+1112\x00+1130\x00+1230\x00+11" +
+	"\x00+12\x00\n<+11>-11<+12>,M10.1.0,M4.1.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7\xef\x97\xc6\xc6\x00\x00\x00\xc6" +
+	"\x00\x00\x00\x0e\x00\x00\x00Pacific/NoumeaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff" +
+	"\x92\xf5\xc4t\x00\x00\x00\x00\x0e\xe6\xbaP\x00\x00\x00\x00\x0fV\xbb\xc0\x00\x00\x00\x00\x10ƜP\x00\x00\x00\x00\x117\xef@\x00\x00\x00\x002\xa0K\xf0\x00\x00\x00\x003\x18Dp\x02\x01\x02\x01\x02\x01\x02\x00" +
+	"\x00\x9c\f\x00\x00\x00\x00\xa8\xc0\x01\x04\x00\x00\x9a\xb0\x00\bLMT\x00+12\x00+11\x00\n<+11>-11\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\xca{e\x92\x00\x00" +
+	"\x00\x92\x00\x00\x00\x11\x00\x00\x00Pacific/Pago_PagoTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00" +
+	"\b\xff\xff\xff\xffn=\xc8\b\xff\xff\xff\xff\x91\x05\xfb\b\x01\x02\x00\x00\xb1x\x00\x00\xff\xff_\xf8\x00\x00\xff\xffeP\x00\x04LMT\x00SST\x00\nSST11\nPK\x03\x04\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x80\xf8vܔ\x00\x00\x00\x94\x00\x00\x00\r\x00\x00\x00Pacific/PalauTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x02\x00\x00\x00\x03\x00\x00\x00\b\xff\xff\xff\xff\x14\xe1\xcfl\xff\xff\xff\xff~66\xec\x01\x02\xff\xff,\x94\x00\x00\x00\x00~\x14\x00\x00\x00\x00~\x90\x00\x04LMT\x00+09\x00\n<+09>" +
+	"-9\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfa\x0fA\x05\x99\x00\x00\x00\x99\x00\x00\x00\x10\x00\x00\x00Pacific/PitcairnTZif2\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xff~7.\xf4\x00\x00\x00\x005DB\b\x01\x02\xff\xff\x86\f\x00\x00\xff\xff\x88x\x00\x04\xff\xff\x8f\x80\x00\n" +
+	"LMT\x00-0830\x00-08\x00\n<-08>8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y\xd2K|\x86\x00\x00\x00\x86\x00\x00\x00\x0f\x00\x00\x00Pacific/" +
+	"PohnpeiTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZ" +
+	"if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x94O3\x8c\x01\x00\x00\x95\xf4\x00\x00\x00\x00\x9a" +
+	"\xb0\x00\x04LMT\x00+11\x00\n<+11>-11\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y\xd2K|\x86\x00\x00\x00\x86\x00\x00\x00\x0e\x00\x00\x00Pacific/P" +
+	"onapeTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif" +
+	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x94O3\x8c\x01\x00\x00\x95\xf4\x00\x00\x00\x00\x9a\xb0\x00" +
+	"\x04LMT\x00+11\x00\n<+11>-11\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\x04\x19y\x9a\x00\x00\x00\x9a\x00\x00\x00\x14\x00\x00\x00Pacific/Por" +
+	"t_MoresbyTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" +
+	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xffV\xb6Z\b\xff\xff\xff\xffr\xed\xa4\x90" +
+	"\x01\x02\x00\x00\x89\xf8\x00\x00\x00\x00\x89\xf0\x00\x04\x00\x00\x8c\xa0\x00\tLMT\x00PMMT\x00+10\x00\n<+10>-10\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\xe3\xa3" +
+	"S\x96\x01\x00\x00\x96\x01\x00\x00\x11\x00\x00\x00Pacific/RarotongaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\x00\x00\x00" +
+	"\x05\x00\x00\x00\x14\xff\xff\xff\xff|L\xdc\xc8\xff\xff\xff\xffߡ`\xc8\x00\x00\x00\x00\x10\xac\x1b(\x00\x00\x00\x00\x11?\xb5\x18\x00\x00\x00\x00\x12y\x81 \x00\x00\x00\x00\x13\x1f\x97\x18\x00\x00\x00\x00\x14Yc" +
+	" \x00\x00\x00\x00\x14\xffy\x18\x00\x00\x00\x00\x169E \x00\x00\x00\x00\x16蕘\x00\x00\x00\x00\x18\"a\xa0\x00\x00\x00\x00\x18\xc8w\x98\x00\x00\x00\x00\x1a\x02C\xa0\x00\x00\x00\x00\x1a\xa8Y\x98\x00\x00\x00" +
+	"\x00\x1b\xe2%\xa0\x00\x00\x00\x00\x1c\x88;\x98\x00\x00\x00\x00\x1d\xc2\a\xa0\x00\x00\x00\x00\x1eh\x1d\x98\x00\x00\x00\x00\x1f\xa1\xe9\xa0\x00\x00\x00\x00 G\xff\x98\x00\x00\x00\x00!\x81ˠ\x00\x00\x00\x00\"1\x1c" +
+	"\x18\x00\x00\x00\x00#j\xe8 \x00\x00\x00\x00$\x10\xfe\x18\x00\x00\x00\x00%J\xca \x00\x00\x00\x00%\xf0\xe0\x18\x00\x00\x00\x00'*\xac \x00\x00\x00\x00'\xd0\xc2\x18\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04" +
+	"\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\xbb\xb8\x00\x00\xff\xffj8\x00\x00\xff\xfflX\x00\x04\xff\xffs`\x00\n\xff\xffzh\x01\x0eLMT\x00-1030\x00-10" +
+	"\x00-0930\x00\n<-10>10\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00FI\xfe\x14^\x01\x00\x00^\x01\x00\x00\x0e\x00\x00\x00Pacific/Saipan" +
+	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x00\x06\x00\x00\x00\x15\xff\xff\xff\xff\x14\xe1\xc5\xcc\xff\xff\xff\xff~6-L\xff\xff\xff\xff\xcb7\x95\xe0\xff" +
+	"\xff\xff\xff\xd0.\x89\xf0\xff\xff\xff\xff\xec7\xbe\x00\xff\xff\xff\xff\xef6\xf8\xf0\xff\xff\xff\xff\xfb\x9b\x00\x00\xff\xff\xff\xff\xfe?'\x8c\xff\xff\xff\xff\xff\x01\x1e\x00\xff\xff\xff\xff\xff]X\xf0\x00\x00\x00\x00\x00" +
+	"\x97,\x00\x00\x00\x00\x00\x01Fup\x00\x00\x00\x00\x02w\x0e\x00\x00\x00\x00\x00\x03&Wp\x00\x00\x00\x00\ap\x97\x00\x00\x00\x00\x00\a\xcc\xd1\xf0\x00\x00\x00\x00\f\b\x91\x00\x00\x00\x00\x00\f|\x87,\x00" +
+	"\x00\x00\x00\r\xbf\x94\x80\x00\x00\x00\x00\x0ee\xa3p\x00\x00\x00\x00:C^`\x01\x02\x03\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x05\xff\xff64\x00\x00\x00\x00\x87\xb4\x00\x00\x00\x00\x8c\xa0" +
+	"\x00\x04\x00\x00~\x90\x00\b\x00\x00\x9a\xb0\x01\f\x00\x00\x8c\xa0\x00\x10LMT\x00GST\x00+09\x00GDT\x00ChST\x00\nChST-10\nPK\x03\x04\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00t\xca{e\x92\x00\x00\x00\x92\x00\x00\x00\r\x00\x00\x00Pacific/SamoaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02" +
+	"\x00\x00\x00\x03\x00\x00\x00\b\xff\xff\xff\xffn=\xc8\b\xff\xff\xff\xff\x91\x05\xfb\b\x01\x02\x00\x00\xb1x\x00\x00\xff\xff_\xf8\x00\x00\xff\xffeP\x00\x04LMT\x00SST\x00\nSST11\nP" +
+	"K\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xea\xc1\xdaυ\x00\x00\x00\x85\x00\x00\x00\x0e\x00\x00\x00Pacific/TahitiTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x94PU\xb8\x01\xff\xffs\xc8\x00\x00\xff\xffs`\x00\x04LMT\x00-10\x00\n<-10>10\nPK\x03\x04" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x006\xb7S{\x86\x00\x00\x00\x86\x00\x00\x00\x0e\x00\x00\x00Pacific/TarawaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff~6\x12\xcc\x01\x00\x00\xa24\x00\x00\x00\x00\xa8\xc0\x00\x04LMT\x00+12\x00\n<+12>-12\nPK\x03\x04\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x97F\x91\xb3\xed\x00\x00\x00\xed\x00\x00\x00\x11\x00\x00\x00Pacific/TongatapuTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\xd2E\x9c@\xff\xff\xff\xff\xef\x11\xe0\x10\x00\x00\x00\x007\xfbG\xd0\x00\x00\x00\x008\xd3}\xd0\x00\x00\x00\x00:\x04\bP\x00\x00\x00\x00" +
+	":r\xb8@\x00\x00\x00\x00;\xe3\xeaP\x00\x00\x00\x00<R\x9a@\x00\x00\x00\x00X\x1d\xd7\xd0\x00\x00\x00\x00Xz \xd0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\xad@\x00\x00\x00\x00\xadp\x00\x04\x00\x00" +
+	"\xb6\xd0\x00\n\x00\x00\xc4\xe0\x01\x0eLMT\x00+1220\x00+13\x00+14\x00\n<+13>-13\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\x04\x19y\x9a\x00\x00\x00" +
+	"\x9a\x00\x00\x00\f\x00\x00\x00Pacific/TrukTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" +
+	"\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xffV" +
+	"\xb6Z\b\xff\xff\xff\xffr\xed\xa4\x90\x01\x02\x00\x00\x89\xf8\x00\x00\x00\x00\x89\xf0\x00\x04\x00\x00\x8c\xa0\x00\tLMT\x00PMMT\x00+10\x00\n<+10>-10\nPK\x03\x04\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x006\xb7S{\x86\x00\x00\x00\x86\x00\x00\x00\f\x00\x00\x00Pacific/WakeTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff~6\x12\xcc\x01\x00\x00\xa24\x00\x00\x00\x00\xa8\xc0\x00\x04LMT\x00+12\x00\n<+12>-12\nPK\x03\x04\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x006\xb7S{\x86\x00\x00\x00\x86\x00\x00\x00\x0e\x00\x00\x00Pacific/WallisTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff~6\x12\xcc\x01\x00\x00\xa24\x00\x00\x00\x00\xa8\xc0\x00\x04LMT\x00+12\x00\n<+12>-12\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00n\x04\x19y\x9a\x00\x00\x00\x9a\x00\x00\x00\v\x00\x00\x00Pacific/YapTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03" +
+	"\x00\x00\x00\r\xff\xff\xff\xffV\xb6Z\b\xff\xff\xff\xffr\xed\xa4\x90\x01\x02\x00\x00\x89\xf8\x00\x00\x00\x00\x89\xf0\x00\x04\x00\x00\x8c\xa0\x00\tLMT\x00PMMT\x00+10\x00\n<+10>-" +
+	"10\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\xfe垛\x03\x00\x00\x9b\x03\x00\x00\x06\x00\x00\x00PolandTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00R\x00\x00\x00\x06\x00\x00\x00\x1a\xff\xff\xff\xffV\xb6\xd0P\xff\xff\xff\xff\x99\xa8*\xd0\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9cٮ\x90\xff\xff\xff\xff\x9d\xa4" +
+	"\xb5\x90\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xa0\x9a\xb6\x00\xff\xff\xff\xff\xa1e\xbd\x00\xff\xff\xff\xff\xa6}|`\xff\xff\xff\xff\xc8v\xde\x10\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff" +
+	"\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЄ\xba\x00\xff\xff\xff\xffѕ\x92p\xff\xff\xff\xffҊ\xbb`\xff\xff\xff\xff\xd3b\xffp\xff\xff\xff\xff\xd4K" +
+	"#\x90\xff\xff\xff\xff\xd5^\xad\x10\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xd9\x02\xc1\x90\xff\xff\xff\xff\xd9\xe9x\x10\xff\xff\xff\xff\xe8T\xd2\x00\xff\xff" +
+	"\xff\xff\xe8\xf1\xb4\x80\xff\xff\xff\xff\xe9᥀\xff\xff\xff\xff\xeaі\x80\xff\xff\xff\xff\xec\x14\x96\x00\xff\xff\xff\xff캳\x00\xff\xff\xff\xff\xed\xaa\xa4\x00\xff\xff\xff\xff\ue695\x00\xff\xff\xff\xff\xef\xd4" +
+	"Z\x00\xff\xff\xff\xff\xf0zw\x00\xff\xff\xff\xff\xf1\xb4<\x00\xff\xff\xff\xff\xf2ZY\x00\xff\xff\xff\xff\xf3\x94\x1e\x00\xff\xff\xff\xff\xf4:;\x00\xff\xff\xff\xff\xf5}:\x80\xff\xff\xff\xff\xf6\x1a\x1d\x00\x00\x00" +
+	"\x00\x00\r\xa4U\x80\x00\x00\x00\x00\x0e\x8b\f\x00\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00\x10t(\x80\x00\x00\x00\x00\x11d\x19\x80\x00\x00\x00\x00\x12T\n\x80\x00\x00\x00\x00\x13M6\x00\x00\x00\x00\x00\x143" +
+	"\xec\x80\x00\x00\x00\x00\x15#݀\x00\x00\x00\x00\x16\x13\u0380\x00\x00\x00\x00\x17\x03\xbf\x80\x00\x00\x00\x00\x17\xf3\xb0\x80\x00\x00\x00\x00\x18㡀\x00\x00\x00\x00\x19Ӓ\x80\x00\x00\x00\x00\x1aÃ\x80\x00\x00" +
+	"\x00\x00\x1b\xbc\xaf\x00\x00\x00\x00\x00\x1c\xac\xa0\x00\x00\x00\x00\x00\x1d\x9c\x91\x00\x00\x00\x00\x00\x1e\x8c\x82\x00\x00\x00\x00\x00\x1f|s\x00\x00\x00\x00\x00 ld\x00\x00\x00\x00\x00!\\U\x00\x00\x00\x00\x00\"L" +
+	"T\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00" +
+	"\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d" +
+	"\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x05\x04\x05\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\x13\xb0\x00\x00\x00\x00\x13\xb0\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\r\x00\x00*0" +
+	"\x01\x11\x00\x00\x1c \x00\x16LMT\x00WMT\x00CEST\x00CET\x00EEST\x00EET\x00\nCET-1CEST,M3.5.0,M10.5.0/" +
+	"3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&S\x03\t\xae\x05\x00\x00\xae\x05\x00\x00\b\x00\x00\x00PortugalTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x8d\x00\x00\x00\x06\x00\x00\x00\x1b\xff\xff\xff\xff^=\f\x1d\xff\xff\xff\xff\x92掀\xff\xff\xff\xff\x9bKmp\xff\xff\xff\xff\x9b\xfeǀ\xff\xff\xff\xff\x9c\x9c\xedp\xff\xff\xff\xff\x9d" +
+	"Ƀp\xff\xff\xff\xff\x9e\x7frp\xff\xff\xff\xff\x9f\xaa\xb6\xf0\xff\xff\xff\xff\xa0_Tp\xff\xff\xff\xff\xa1\x8b\xeap\xff\xff\xff\xff\xa2A\xd9p\xff\xff\xff\xff\xa3nop\xff\xff\xff\xff\xa4#\f\xf0\xff" +
+	"\xff\xff\xff\xa5O\xa2\xf0\xff\xff\xff\xff\xaa\x05\xefp\xff\xff\xff\xff\xaa\xf4\x8e\xf0\xff\xff\xff\xff\xadɧ\xf0\xff\xff\xff\xff\xae\xa7#\xf0\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x05\xf0\xff\xff\xff\xff\xb1" +
+	"\x89k\xf0\xff\xff\xff\xff\xb2p\"p\xff\xff\xff\xff\xb3r\x88p\xff\xff\xff\xff\xb4P\x04p\xff\xff\xff\xff\xb72Lp\xff\xff\xff\xff\xb8\x0f\xc8p\xff\xff\xff\xff\xb8\xff\xb9p\xff\xff\xff\xff\xb9\xef\xaap\xff" +
+	"\xff\xff\xff\xbcȷ\xf0\xff\xff\xff\xff\xbd\xb8\xa8\xf0\xff\xff\xff\xff\xbe\x9f_p\xff\xff\xff\xff\xbf\x98\x8a\xf0\xff\xff\xff\xff\xc0\x9a\xf0\xf0\xff\xff\xff\xff\xc1xl\xf0\xff\xff\xff\xff\xc2h]\xf0\xff\xff\xff\xff\xc3" +
+	"XN\xf0\xff\xff\xff\xff\xc4?\x05p\xff\xff\xff\xff\xc580\xf0\xff\xff\xff\xff\xc6:\x96\xf0\xff\xff\xff\xff\xc7X\xacp\xff\xff\xff\xff\xc7\xd9\xdfp\xff\xff\xff\xff\xc9\x01/p\xff\xff\xff\xff\xc9\xf1 p\xff" +
+	"\xff\xff\xff\xca\xe2b\xf0\xff\xff\xff\xff˵R\xf0\xff\xff\xff\xff\xcb\xec\xa3\xe0\xff\xff\xff\xff̀K\xe0\xff\xff\xff\xff\xccܢ\xf0\xff\xff\xff\xff͕4\xf0\xff\xff\xff\xff\xcd\xc3K`\xff\xff\xff\xff\xce" +
+	"r\xa2\xe0\xff\xff\xff\xff\xceſp\xff\xff\xff\xff\xcfu\x16\xf0\xff\xff\xff\xffϬg\xe0\xff\xff\xff\xff\xd0R\x84\xe0\xff\xff\xff\xffХ\xa1p\xff\xff\xff\xff\xd1T\xf8\xf0\xff\xff\xff\xffьI\xe0\xff" +
+	"\xff\xff\xff\xd22f\xe0\xff\xff\xff\xff҅\x83p\xff\xff\xff\xff\xd3Y\xc4\xf0\xff\xff\xff\xff\xd4I\xb5\xf0\xff\xff\xff\xff\xd59\xd1 \xff\xff\xff\xff\xd6)\xc2 \xff\xff\xff\xff\xd7\x19\xb3 \xff\xff\xff\xff\xd8" +
+	"\t\xa4 \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xd9\xe9\x86 \xff\xff\xff\xff\xda\xd9w \xff\xff\xff\xff\xdb\xc9h \xff\xff\xff\xffܹY \xff\xff\xff\xffݲ\x84\xa0\xff\xff\xff\xffޢu\xa0\xff" +
+	"\xff\xff\xffߒf\xa0\xff\xff\xff\xff\xe0\x82W\xa0\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2b9\xa0\xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4B\x1b\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6" +
+	"!\xfd\xa0\xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\v\x1a \xff\xff\xff\xff\xe8\xfb\v \xff\xff\xff\xff\xe9\xea\xfc \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xca\xde \xff\xff\xff\xff\xec\xba\xcf \xff" +
+	"\xff\xff\xff\xed\xaa\xc0 \xff\xff\xff\xff\ue6b1 \xff\xff\xff\xff\uf2a2 \xff\xff\xff\xff\xf0z\x93 \xff\xff\xff\xff\xf1j\x84 \xff\xff\xff\xff\xf2c\xaf\xa0\xff\xff\xff\xff\xf3S\xa0\xa0\xff\xff\xff\xff\xf4" +
+	"C\x91\xa0\xff\xff\xff\xff\xf53\x82\xa0\xff\xff\xff\xff\xf6#s\xa0\xff\xff\xff\xff\xf7\x13d\xa0\xff\xff\xff\xff\xf8\x03U\xa0\xff\xff\xff\xff\xf8\xf3F\xa0\x00\x00\x00\x00\f\xab*\x00\x00\x00\x00\x00\r\x9b\x1b\x00\x00" +
+	"\x00\x00\x00\x0e\x8b\f\x00\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00\x10t(\x80\x00\x00\x00\x00\x11d\x19\x80\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13C\xfb\x80\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15" +
+	"#\xeb\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㽠\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00" +
+	"\x00\x00\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#" +
+	"<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00" +
+	"\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001" +
+	"]\xd9\x10\x00\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x02\x01\x03\x01\x02\x01\x03\x01\x02\x01" +
+	"\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x05\x04\x05\x04\x05\x04\x01\xff\xff\xf7c\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\t\x00\x00\x1c \x01\r\x00\x00\x0e\x10\x00\x12\x00\x00\x1c \x01\x16" +
+	"LMT\x00WEST\x00WET\x00WEMT\x00CET\x00CEST\x00\nWET0WEST,M3.5.0/1,M10.5.0\nPK\x03\x04\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\xee\xf0BB\xff\x01\x00\x00\xff\x01\x00\x00\x03\x00\x00\x00ROCTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)\x00\x00\x00\x04\x00\x00" +
+	"\x00\x10\xff\xff\xff\xfft\xce\xf0\x18\xff\xff\xff\xff\xc3UI\x80\xff\xff\xff\xff\xd2TY\x80\xff\xff\xff\xffӋ{\x80\xff\xff\xff\xff\xd4B\xad\xf0\xff\xff\xff\xff\xd5E\"\x00\xff\xff\xff\xff\xd6L\xbf\xf0\xff\xff" +
+	"\xff\xff\xd7<\xbf\x00\xff\xff\xff\xff\xd8\x06fp\xff\xff\xff\xff\xd9\x1d\xf2\x80\xff\xff\xff\xff\xd9\xe7\x99\xf0\xff\xff\xff\xff\xda\xff&\x00\xff\xff\xff\xff\xdb\xc8\xcdp\xff\xff\xff\xff\xdc\xe0Y\x80\xff\xff\xff\xffݪ" +
+	"\x00\xf0\xff\xff\xff\xff\xders\x00\xff\xff\xff\xffߵdp\xff\xff\xff\xff\xe0|\x85\x00\xff\xff\xff\xffᖗ\xf0\xff\xff\xff\xff\xe2]\xb8\x80\xff\xff\xff\xff\xe3w\xcbp\xff\xff\xff\xff\xe4>\xec\x00\xff\xff" +
+	"\xff\xff\xe50 p\xff\xff\xff\xff\xe6!q\x00\xff\xff\xff\xff\xe7\x12\xa5p\xff\xff\xff\xff\xe8\x02\xa4\x80\xff\xff\xff\xff\xe8\xf3\xd8\xf0\xff\xff\xff\xff\xe9\xe3\xd8\x00\xff\xff\xff\xff\xea\xd5\fp\xff\xff\xff\xff\xeb\xc5" +
+	"\v\x80\xff\xff\xff\xff\xec\xb6?\xf0\xff\xff\xff\xff\xed\xf7\xfc\x00\xff\xff\xff\xff\xee\x98\xc4\xf0\xff\xff\xff\xff\xef\xd9/\x80\xff\xff\xff\xff\xf0y\xf8p\x00\x00\x00\x00\a\xfcV\x00\x00\x00\x00\x00\b\xed\x8ap\x00\x00" +
+	"\x00\x00\t݉\x80\x00\x00\x00\x00\nν\xf0\x00\x00\x00\x00\x11ۡ\x80\x00\x00\x00\x00\x12T\xddp\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03" +
+	"\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x00\x00q\xe8\x00\x00\x00\x00p\x80\x00\x04\x00\x00~\x90\x00\b\x00\x00~\x90\x01\fLMT\x00CST\x00JST\x00CDT\x00\nCST-8\nPK" +
+	"\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7X,Y\x9f\x01\x00\x00\x9f\x01\x00\x00\x03\x00\x00\x00ROKTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00" +
+	"\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\x8b\xd7\xf0x\xff\xff\xff\xff\x92\xe6\x16\xf8\xff\xff\xff\xff\xd2C'\xf0\xff\xff\xff\xff\xd7e\x8fp\xff\xff\xff\xff\xd7\xee\x9d`\xff\xff\xff\xff\xd8\xf8\xfap\xff\xff\xff\xff\xd9\xcd" +
+	"-\xe0\xff\xff\xff\xff\xda\u05ca\xf0\xff\xff\xff\xffۭ\x0f\xe0\xff\xff\xff\xff\xdc\xe6\xe2\xf0\xff\xff\xff\xff\u074c\xf1\xe0\xff\xff\xff\xff\xe2O)\xf0\xff\xff\xff\xff\xe4k\xb7\xf8\xff\xff\xff\xff\xe5\x13\x18h\xff\xff" +
+	"\xff\xff\xe6b\x03x\xff\xff\xff\xff\xe7\x11L\xe8\xff\xff\xff\xff\xe8/px\xff\xff\xff\xff\xe8\xe7\xf4h\xff\xff\xff\xff\xea\x0fRx\xff\xff\xff\xff\xea\xc7\xd6h\xff\xff\xff\xff\xeb\xef4x\xff\xff\xff\xff\xec\xa7" +
+	"\xb8h\xff\xff\xff\xff\xed\xcf\x16x\xff\xff\xff\xff\ue1dah\xff\xff\xff\xff\xf05qx\x00\x00\x00\x00 \xa3`\x90\x00\x00\x00\x00!ng\x90\x00\x00\x00\x00\"\x83B\x90\x00\x00\x00\x00#NI\x90\x01\x02" +
+	"\x04\x03\x04\x03\x04\x03\x04\x03\x04\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01\x04\x03\x04\x03\x04\x00\x00w\b\x00\x00\x00\x00w\x88\x00\x04\x00\x00~\x90\x00\b\x00\x00\x8c\xa0\x01\f\x00\x00~\x90\x00\x04\x00\x00\x85" +
+	"\x98\x01\fLMT\x00KST\x00JST\x00KDT\x00\nKST-9\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00F7k\x1c\x00\x01\x00\x00\x00\x01\x00\x00\t\x00\x00\x00Sing" +
+	"aporeTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif" +
+	"2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x00\x00\x00\b\x00\x00\x00 \xff\xff\xff\xff~6S\xa3\xff\xff\xff\xff\x86\x83\x85\xa3\xff\xff\xff\xff" +
+	"\xbagN\x90\xff\xff\xff\xff\xc0\n\xe4`\xff\xff\xff\xffʳ\xe5`\xff\xff\xff\xffˑ_\b\xff\xff\xff\xff\xd2Hm\xf0\x00\x00\x00\x00\x16\x91\xee\x00\x01\x02\x03\x04\x05\x06\x05\a\x00\x00a]\x00\x00\x00\x00" +
+	"a]\x00\x04\x00\x00bp\x00\b\x00\x00g \x01\f\x00\x00g \x00\f\x00\x00ix\x00\x12\x00\x00~\x90\x00\x18\x00\x00p\x80\x00\x1cLMT\x00SMT\x00+07\x00+0720\x00+0" +
+	"730\x00+09\x00+08\x00\n<+08>-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\aW\x10Ѱ\x04\x00\x00\xb0\x04\x00\x00\x06\x00\x00\x00TurkeyTZi" +
+	"f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00s\x00\x00\x00\x06\x00\x00\x00\x19\xff\xff\xff\xffV\xb6\xc8\xd8\xff\xff\xff\xff\x90\x8b\xf5\x98\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff" +
+	"\x9bվ\xd0\xff\xff\xff\xff\xa2ec\xe0\xff\xff\xff\xff\xa3{\x82P\xff\xff\xff\xff\xa4N\x80`\xff\xff\xff\xff\xa5?\xb4\xd0\xff\xff\xff\xff\xa6%'\xe0\xff\xff\xff\xff\xa7'\x7f\xd0\xff\xff\xff\xff\xaa((`" +
+	"\xff\xff\xff\xff\xaa\xe1\xfd\xd0\xff\xff\xff\xff\xab\xf9\x89\xe0\xff\xff\xff\xff\xac\xc31P\xff\xff\xff\xffȁ?\xe0\xff\xff\xff\xff\xc9\x01\x13P\xff\xff\xff\xff\xc9J\xf5`\xff\xff\xff\xff\xca\u0380P\xff\xff\xff\xff" +
+	"\xcbˮ`\xff\xff\xff\xff\xd2k\tP\xff\xff\xff\xffӢ9`\xff\xff\xff\xff\xd4C\x02P\xff\xff\xff\xff\xd5L\r\xe0\xff\xff\xff\xff\xd6){\xd0\xff\xff\xff\xff\xd7+\xef\xe0\xff\xff\xff\xff\xd8\t]\xd0" +
+	"\xff\xff\xff\xff\xd9\x02\x97`\xff\xff\xff\xff\xd9\xe9?\xd0\xff\xff\xff\xff\xda\xeb\xb3\xe0\xff\xff\xff\xff\xdb\xd2\\P\xff\xff\xff\xff\xdc\xd4\xd0`\xff\xff\xff\xffݲ>P\xff\xff\xff\xff\xf1\xf4\xb9`\xff\xff\xff\xff" +
+	"\xf4b\xefP\xff\xff\xff\xff\xf5h\x06`\xff\xff\xff\xff\xf6\x1f8\xd0\x00\x00\x00\x00\x06n\x93p\x00\x00\x00\x00\a9\x9ap\x00\x00\x00\x00\a\xfbu\x00\x00\x00\x00\x00\t\x19|p\x00\x00\x00\x00\t\xd0\xcb\x00" +
+	"\x00\x00\x00\x00\n\xf9^p\x00\x00\x00\x00\v\xb1\xfe\x80\x00\x00\x00\x00\f\xd9@p\x00\x00\x00\x00\r\xa4U\x80\x00\x00\x00\x00\x0e\xa6\xadp\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00\x0f\xf8\x11P\x00\x00\x00\x00" +
+	"\x19\x89\xb0p\x00\x00\x00\x00\x19ܰ\xe0\x00\x00\x00\x00\x1b\xe6\xd0\xf0\x00\x00\x00\x00\x1c\xc6\xef\xf0\x00\x00\x00\x00\x1d\x9b1p\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0" +
+	"\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00" +
+	"'\xf5\x18p\x00\x00\x00\x00(\xe5\tp\x00\x00\x00\x00)\xd4\xfap\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x8b\x83\xf0\x00\x00\x00\x00.\x84\xafp" +
+	"\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x00" +
+	"62[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb<p\x00\x00\x00\x00<\xa6Cp" +
+	"\x00\x00\x00\x00=\xbb\x1ep\x00\x00\x00\x00>\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f\ap\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00" +
+	"D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10" +
+	"\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8fݐ\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00" +
+	"Rle\x90\x00\x00\x00\x00S8\xbe\x10\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V>\x9e\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00W\xcf.P\x01\x03\x02\x03\x02\x03\x02\x03" +
+	"\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
+	"\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x00\x00\x1b(\x00\x00\x00\x00\x1bh\x00\x04\x00" +
+	"\x00*0\x01\b\x00\x00\x1c \x00\r\x00\x00*0\x00\x11\x00\x008@\x01\x15LMT\x00IMT\x00EEST\x00EET\x00+03\x00+04\x00\n<+03>-3\nPK\x03" +
+	"\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\x03\x00\x00\x00UCTTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00\nUTC0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005\x11Q\x06\xd1\x03\x00\x00\xd1\x03\x00\x00\t\x00\x00\x00US/Alaska" +
+	"TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00T\x00\x00\x00\n\x00\x00\x00(\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}\x87AH\xff\xff\xff\xffˉ6\xc0\xff" +
+	"\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2aB0\xff\xff\xff\xff\xfa\xd2G\xa0\xff\xff\xff\xff\xfe\xb8c@\xff\xff\xff\xff\xff\xa8F0\x00\x00\x00\x00\x00\x98E@\x00\x00\x00\x00\x01\x88(0\x00\x00\x00\x00\x02" +
+	"x'@\x00\x00\x00\x00\x03qD\xb0\x00\x00\x00\x00\x04aC\xc0\x00\x00\x00\x00\x05Q&\xb0\x00\x00\x00\x00\x06A%\xc0\x00\x00\x00\x00\a1\b\xb0\x00\x00\x00\x00\a\x8d_\xc0\x00\x00\x00\x00\t\x10\xea\xb0\x00" +
+	"\x00\x00\x00\t\xad\xdb@\x00\x00\x00\x00\n\xf0̰\x00\x00\x00\x00\v\xe0\xcb\xc0\x00\x00\x00\x00\f\xd9\xe90\x00\x00\x00\x00\r\xc0\xad\xc0\x00\x00\x00\x00\x0e\xb9\xcb0\x00\x00\x00\x00\x0f\xa9\xca@\x00\x00\x00\x00\x10" +
+	"\x99\xad0\x00\x00\x00\x00\x11\x89\xac@\x00\x00\x00\x00\x12y\x8f0\x00\x00\x00\x00\x13i\x8e@\x00\x00\x00\x00\x14Yq0\x00\x00\x00\x00\x15Ip@\x00\x00\x00\x00\x169S0\x00\x00\x00\x00\x17)R@\x00" +
+	"\x00\x00\x00\x18\"o\xb0\x00\x00\x00\x00\x19\t4@\x00\x00\x00\x00\x1a\x02Q\xb0\x00\x00\x00\x00\x1a+\x14\x10\x00\x00\x00\x00\x1a\xf2B\xb0\x00\x00\x00\x00\x1b\xe2%\xa0\x00\x00\x00\x00\x1c\xd2$\xb0\x00\x00\x00\x00\x1d" +
+	"\xc2\a\xa0\x00\x00\x00\x00\x1e\xb2\x06\xb0\x00\x00\x00\x00\x1f\xa1\xe9\xa0\x00\x00\x00\x00 v90\x00\x00\x00\x00!\x81ˠ\x00\x00\x00\x00\"V\x1b0\x00\x00\x00\x00#j\xe8 \x00\x00\x00\x00$5\xfd0\x00" +
+	"\x00\x00\x00%J\xca \x00\x00\x00\x00&\x15\xdf0\x00\x00\x00\x00'*\xac \x00\x00\x00\x00'\xfe\xfb\xb0\x00\x00\x00\x00)\n\x8e \x00\x00\x00\x00)\xdeݰ\x00\x00\x00\x00*\xeap \x00\x00\x00\x00+" +
+	"\xbe\xbf\xb0\x00\x00\x00\x00,ӌ\xa0\x00\x00\x00\x00-\x9e\xa1\xb0\x00\x00\x00\x00.\xb3n\xa0\x00\x00\x00\x00/~\x83\xb0\x00\x00\x00\x000\x93P\xa0\x00\x00\x00\x001g\xa00\x00\x00\x00\x002s2\xa0\x00" +
+	"\x00\x00\x003G\x820\x00\x00\x00\x004S\x14\xa0\x00\x00\x00\x005'd0\x00\x00\x00\x0062\xf6\xa0\x00\x00\x00\x007\aF0\x00\x00\x00\x008\x1c\x13 \x00\x00\x00\x008\xe7(0\x00\x00\x00\x009" +
+	"\xfb\xf5 \x00\x00\x00\x00:\xc7\n0\x00\x00\x00\x00;\xdb\xd7 \x00\x00\x00\x00<\xb0&\xb0\x00\x00\x00\x00=\xbb\xb9 \x00\x00\x00\x00>\x90\b\xb0\x00\x00\x00\x00?\x9b\x9b \x00\x00\x00\x00@o\xea\xb0\x00" +
+	"\x00\x00\x00A\x84\xb7\xa0\x00\x00\x00\x00BO̰\x00\x00\x00\x00Cd\x99\xa0\x00\x00\x00\x00D/\xae\xb0\x00\x00\x00\x00ED{\xa0\x00\x00\x00\x00E\xf3\xe10\x01\x02\x03\x04\x02\x05\x06\x05\x06\x05\x06\x05\x06" +
+	"\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\a\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t" +
+	"\b\t\b\t\b\t\b\t\b\t\b\x00\x00\xc4\xf8\x00\x00\xff\xffsx\x00\x00\xff\xffs`\x00\x04\xff\xff\x81p\x01\b\xff\xff\x81p\x01\f\xff\xffs`\x00\x10\xff\xff\x81p\x01\x15\xff\xff\x81p\x00\x1a\xff" +
+	"\xff\x8f\x80\x01\x1e\xff\xff\x81p\x00#LMT\x00AST\x00AWT\x00APT\x00AHST\x00AHDT\x00YST\x00AKDT\x00AKST\x00\nAKST9AKD" +
+	"T,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xae,\xa44\xc9\x03\x00\x00\xc9\x03\x00\x00\v\x00\x00\x00US/AleutianTZ" +
+	"if2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00T\x00\x00\x00\n\x00\x00\x00!\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}\x87Z^\xff\xff\xff\xffˉD\xd0\xff\xff\xff" +
+	"\xff\xd2#\xf4p\xff\xff\xff\xff\xd2aP@\xff\xff\xff\xff\xfa\xd2U\xb0\xff\xff\xff\xff\xfe\xb8qP\xff\xff\xff\xff\xff\xa8T@\x00\x00\x00\x00\x00\x98SP\x00\x00\x00\x00\x01\x886@\x00\x00\x00\x00\x02x5" +
+	"P\x00\x00\x00\x00\x03qR\xc0\x00\x00\x00\x00\x04aQ\xd0\x00\x00\x00\x00\x05Q4\xc0\x00\x00\x00\x00\x06A3\xd0\x00\x00\x00\x00\a1\x16\xc0\x00\x00\x00\x00\a\x8dm\xd0\x00\x00\x00\x00\t\x10\xf8\xc0\x00\x00\x00" +
+	"\x00\t\xad\xe9P\x00\x00\x00\x00\n\xf0\xda\xc0\x00\x00\x00\x00\v\xe0\xd9\xd0\x00\x00\x00\x00\f\xd9\xf7@\x00\x00\x00\x00\r\xc0\xbb\xd0\x00\x00\x00\x00\x0e\xb9\xd9@\x00\x00\x00\x00\x0f\xa9\xd8P\x00\x00\x00\x00\x10\x99\xbb" +
+	"@\x00\x00\x00\x00\x11\x89\xbaP\x00\x00\x00\x00\x12y\x9d@\x00\x00\x00\x00\x13i\x9cP\x00\x00\x00\x00\x14Y\x7f@\x00\x00\x00\x00\x15I~P\x00\x00\x00\x00\x169a@\x00\x00\x00\x00\x17)`P\x00\x00\x00" +
+	"\x00\x18\"}\xc0\x00\x00\x00\x00\x19\tBP\x00\x00\x00\x00\x1a\x02_\xc0\x00\x00\x00\x00\x1a+\" \x00\x00\x00\x00\x1a\xf2P\xc0\x00\x00\x00\x00\x1b\xe23\xb0\x00\x00\x00\x00\x1c\xd22\xc0\x00\x00\x00\x00\x1d\xc2\x15" +
+	"\xb0\x00\x00\x00\x00\x1e\xb2\x14\xc0\x00\x00\x00\x00\x1f\xa1\xf7\xb0\x00\x00\x00\x00 vG@\x00\x00\x00\x00!\x81ٰ\x00\x00\x00\x00\"V)@\x00\x00\x00\x00#j\xf60\x00\x00\x00\x00$6\v@\x00\x00\x00" +
+	"\x00%J\xd80\x00\x00\x00\x00&\x15\xed@\x00\x00\x00\x00'*\xba0\x00\x00\x00\x00'\xff\t\xc0\x00\x00\x00\x00)\n\x9c0\x00\x00\x00\x00)\xde\xeb\xc0\x00\x00\x00\x00*\xea~0\x00\x00\x00\x00+\xbe\xcd" +
+	"\xc0\x00\x00\x00\x00,Ӛ\xb0\x00\x00\x00\x00-\x9e\xaf\xc0\x00\x00\x00\x00.\xb3|\xb0\x00\x00\x00\x00/~\x91\xc0\x00\x00\x00\x000\x93^\xb0\x00\x00\x00\x001g\xae@\x00\x00\x00\x002s@\xb0\x00\x00\x00" +
+	"\x003G\x90@\x00\x00\x00\x004S\"\xb0\x00\x00\x00\x005'r@\x00\x00\x00\x0063\x04\xb0\x00\x00\x00\x007\aT@\x00\x00\x00\x008\x1c!0\x00\x00\x00\x008\xe76@\x00\x00\x00\x009\xfc\x03" +
+	"0\x00\x00\x00\x00:\xc7\x18@\x00\x00\x00\x00;\xdb\xe50\x00\x00\x00\x00<\xb04\xc0\x00\x00\x00\x00=\xbb\xc70\x00\x00\x00\x00>\x90\x16\xc0\x00\x00\x00\x00?\x9b\xa90\x00\x00\x00\x00@o\xf8\xc0\x00\x00\x00" +
+	"\x00A\x84Ű\x00\x00\x00\x00BO\xda\xc0\x00\x00\x00\x00Cd\xa7\xb0\x00\x00\x00\x00D/\xbc\xc0\x00\x00\x00\x00ED\x89\xb0\x00\x00\x00\x00E\xf3\xef@\x01\x02\x03\x04\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" +
+	"\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\a\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t" +
+	"\b\t\b\t\b\t\b\t\b\x00\x00\xab\xe2\x00\x00\xff\xffZb\x00\x00\xff\xffeP\x00\x04\xff\xffs`\x01\b\xff\xffs`\x01\f\xff\xffeP\x00\x10\xff\xffs`\x01\x14\xff\xffs`\x00\x18\xff\xff\x81" +
+	"p\x01\x1d\xff\xffs`\x00\x19LMT\x00NST\x00NWT\x00NPT\x00BST\x00BDT\x00AHST\x00HDT\x00\nHST10HDT,M3.2.0,M" +
+	"11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ø\xab\x9b\xf0\x00\x00\x00\xf0\x00\x00\x00\n\x00\x00\x00US/ArizonaTZif2\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff^\x04\f\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a" +
+	"\xe9\x80\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xcf\x17\xdf\x1c\xff\xff\xff\xffϏ\xe5\xac\xff\xff\xff\xffЁ\x1a\x1c\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\x02\x01\x02\x01\x02\x03\x02\x03\x02\x01" +
+	"\x02\xff\xff\x96\xee\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\fLMT\x00MDT\x00MST\x00MWT\x00\nMST7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x9bܩ=\xda\x06\x00\x00\xda\x06\x00\x00\n\x00\x00\x00US/CentralTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaf\x00\x00\x00\x06\x00\x00" +
+	"\x00\x18\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xa2\xcbt\x00\xff\xff\xff\xff\xa3\x83\xf7\xf0\xff\xff" +
+	"\xff\xff\xa4EҀ\xff\xff\xff\xff\xa5c\xd9\xf0\xff\xff\xff\xff\xa6S\xd9\x00\xff\xff\xff\xff\xa7\x15\x97p\xff\xff\xff\xff\xa83\xbb\x00\xff\xff\xff\xff\xa8\xfe\xb3\xf0\xff\xff\xff\xff\xaa\x13\x9d\x00\xff\xff\xff\xff\xaa\xde" +
+	"\x95\xf0\xff\xff\xff\xff\xab\xf3\x7f\x00\xff\xff\xff\xff\xac\xbew\xf0\xff\xff\xff\xff\xad\xd3a\x00\xff\xff\xff\xff\xae\x9eY\xf0\xff\xff\xff\xff\xaf\xb3C\x00\xff\xff\xff\xff\xb0~;\xf0\xff\xff\xff\xff\xb1\x9c_\x80\xff\xff" +
+	"\xff\xff\xb2gXp\xff\xff\xff\xff\xb3|A\x80\xff\xff\xff\xff\xb4G:p\xff\xff\xff\xff\xb5\\#\x80\xff\xff\xff\xff\xb6'\x1cp\xff\xff\xff\xff\xb7<\x05\x80\xff\xff\xff\xff\xb8\x06\xfep\xff\xff\xff\xff\xb9\x1b" +
+	"\xe7\x80\xff\xff\xff\xff\xb9\xe6\xe0p\xff\xff\xff\xff\xbb\x05\x04\x00\xff\xff\xff\xff\xbb\xc6\xc2p\xff\xff\xff\xff\xbc\xe4\xe6\x00\xff\xff\xff\xff\xbd\xaf\xde\xf0\xff\xff\xff\xff\xbe\xc4\xc8\x00\xff\xff\xff\xff\xbf\x8f\xc0\xf0\xff\xff" +
+	"\xff\xff\xc0Z\xd6\x00\xff\xff\xff\xff\xc1\xb0<p\xff\xff\xff\xff\u0084\x8c\x00\xff\xff\xff\xff\xc3O\x84\xf0\xff\xff\xff\xff\xc4dn\x00\xff\xff\xff\xff\xc5/f\xf0\xff\xff\xff\xff\xc6M\x8a\x80\xff\xff\xff\xff\xc7\x0f" +
+	"H\xf0\xff\xff\xff\xff\xc8-l\x80\xff\xff\xff\xff\xc8\xf8ep\xff\xff\xff\xff\xca\rN\x80\xff\xff\xff\xff\xca\xd8Gp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff" +
+	"\xff\xff\xd3u\xf3\x00\xff\xff\xff\xff\xd4@\xeb\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0" +
+	"\x91\xf0\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90p\xff\xff\xff\xff\u07bey\x80\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff" +
+	"\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5W<\xf0\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe77\x1e\xf0\xff\xff\xff\xff\xe8'" +
+	"\x1e\x00\xff\xff\xff\xff\xe9\x17\x00\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea\xf6\xe2\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xd6\xc4\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\xee\xbf\xe1p\xff\xff" +
+	"\xff\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xf0\x9f\xc3p\xff\xff\xff\xff\xf1\x8f\u0080\xff\xff\xff\xff\xf2\x7f\xa5p\xff\xff\xff\xff\xf3o\xa4\x80\xff\xff\xff\xff\xf4_\x87p\xff\xff\xff\xff\xf5O\x86\x80\xff\xff\xff\xff\xf6?" +
+	"ip\xff\xff\xff\xff\xf7/h\x80\xff\xff\xff\xff\xf8(\x85\xf0\xff\xff\xff\xff\xf9\x0fJ\x80\xff\xff\xff\xff\xfa\bg\xf0\xff\xff\xff\xff\xfa\xf8g\x00\xff\xff\xff\xff\xfb\xe8I\xf0\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff" +
+	"\xff\xff\xfd\xc8+\xf0\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\r\xf0\x00\x00\x00\x00\x00\x98\r\x00\x00\x00\x00\x00\x01\x87\xef\xf0\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\fp\x00\x00\x00\x00\x04a" +
+	"\v\x80\x00\x00\x00\x00\x05P\xeep\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\a0\xd0p\x00\x00\x00\x00\a\x8d'\x80\x00\x00\x00\x00\t\x10\xb2p\x00\x00\x00\x00\t\xad\xa3\x00\x00\x00\x00\x00\n\xf0\x94p\x00\x00" +
+	"\x00\x00\v\xe0\x93\x80\x00\x00\x00\x00\fٰ\xf0\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99t\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12y" +
+	"V\xf0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\"7p\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00" +
+	"\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1܀\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v" +
+	"\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00" +
+	"\x00\x00'\xfeр\x00\x00\x00\x00)\nc\xf0\x00\x00\x00\x00)\u07b3\x80\x00\x00\x00\x00*\xeaE\xf0\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3bp\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3" +
+	"Dp\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x93&p\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00" +
+	"\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00;۬\xf0\x00\x00\x00\x00<\xaf" +
+	"\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00" +
+	"\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x04\x05\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xad\xd4\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x00\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x01\x14LMT\x00CDT" +
+	"\x00CST\x00EST\x00CWT\x00CPT\x00\nCST6CDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\xb6{\xc9\x13" +
+	"\x02\x00\x00\x13\x02\x00\x00\x0f\x00\x00\x00US/East-IndianaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&\x00\x00\x00\a\x00\x00\x00" +
+	"\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xcaW\"\x80\xff\xff\xff\xff\xca\xd8Gp\xff\xff\xff" +
+	"\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd3u\xf3\x00\xff\xff\xff\xff\xd4@\xeb\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7" +
+	"\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90p\xff\xff\xff" +
+	"\xff\u07bey\x80\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe8\xf2\x16" +
+	"\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00" +
+	"\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x02\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xaf:\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00" +
+	"\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00EDT\x00\nEST5ED" +
+	"T,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\x9aG\xc8\xd0\x06\x00\x00\xd0\x06\x00\x00\n\x00\x00\x00US/EasternTZi" +
+	"f2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaf\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff^\x03\xf0\x90\xff\xff\xff\xff\x9e\xa6\x1ep\xff\xff\xff\xff\x9f\xba\xeb`\xff\xff\xff\xff" +
+	"\xa0\x86\x00p\xff\xff\xff\xff\xa1\x9a\xcd`\xff\xff\xff\xff\xa2e\xe2p\xff\xff\xff\xff\xa3\x83\xe9\xe0\xff\xff\xff\xff\xa4j\xaep\xff\xff\xff\xff\xa55\xa7`\xff\xff\xff\xff\xa6S\xca\xf0\xff\xff\xff\xff\xa7\x15\x89`" +
+	"\xff\xff\xff\xff\xa83\xac\xf0\xff\xff\xff\xff\xa8\xfe\xa5\xe0\xff\xff\xff\xff\xaa\x13\x8e\xf0\xff\xff\xff\xff\xaaއ\xe0\xff\xff\xff\xff\xab\xf3p\xf0\xff\xff\xff\xff\xac\xbei\xe0\xff\xff\xff\xff\xad\xd3R\xf0\xff\xff\xff\xff" +
+	"\xae\x9eK\xe0\xff\xff\xff\xff\xaf\xb34\xf0\xff\xff\xff\xff\xb0~-\xe0\xff\xff\xff\xff\xb1\x9cQp\xff\xff\xff\xff\xb2gJ`\xff\xff\xff\xff\xb3|3p\xff\xff\xff\xff\xb4G,`\xff\xff\xff\xff\xb5\\\x15p" +
+	"\xff\xff\xff\xff\xb6'\x0e`\xff\xff\xff\xff\xb7;\xf7p\xff\xff\xff\xff\xb8\x06\xf0`\xff\xff\xff\xff\xb9\x1b\xd9p\xff\xff\xff\xff\xb9\xe6\xd2`\xff\xff\xff\xff\xbb\x04\xf5\xf0\xff\xff\xff\xff\xbbƴ`\xff\xff\xff\xff" +
+	"\xbc\xe4\xd7\xf0\xff\xff\xff\xff\xbd\xaf\xd0\xe0\xff\xff\xff\xff\xbeĹ\xf0\xff\xff\xff\xff\xbf\x8f\xb2\xe0\xff\xff\xff\xff\xc0\xa4\x9b\xf0\xff\xff\xff\xff\xc1o\x94\xe0\xff\xff\xff\xff\u0084}\xf0\xff\xff\xff\xff\xc3Ov\xe0" +
+	"\xff\xff\xff\xff\xc4d_\xf0\xff\xff\xff\xff\xc5/X\xe0\xff\xff\xff\xff\xc6M|p\xff\xff\xff\xff\xc7\x0f:\xe0\xff\xff\xff\xff\xc8-^p\xff\xff\xff\xff\xc8\xf8W`\xff\xff\xff\xff\xca\r@p\xff\xff\xff\xff" +
+	"\xca\xd89`\xff\xff\xff\xffˈ\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff\xd3u\xe4\xf0\xff\xff\xff\xff\xd4@\xdd\xe0\xff\xff\xff\xff\xd5U\xc6\xf0\xff\xff\xff\xff\xd6 \xbf\xe0" +
+	"\xff\xff\xff\xff\xd75\xa8\xf0\xff\xff\xff\xff\xd8\x00\xa1\xe0\xff\xff\xff\xff\xd9\x15\x8a\xf0\xff\xff\xff\xff\xd9\xe0\x83\xe0\xff\xff\xff\xff\xda\xfe\xa7p\xff\xff\xff\xff\xdb\xc0e\xe0\xff\xff\xff\xff\xdcމp\xff\xff\xff\xff" +
+	"ݩ\x82`\xff\xff\xff\xff\u07bekp\xff\xff\xff\xff߉d`\xff\xff\xff\xff\xe0\x9eMp\xff\xff\xff\xff\xe1iF`\xff\xff\xff\xff\xe2~/p\xff\xff\xff\xff\xe3I(`\xff\xff\xff\xff\xe4^\x11p" +
+	"\xff\xff\xff\xff\xe5W.\xe0\xff\xff\xff\xff\xe6G-\xf0\xff\xff\xff\xff\xe77\x10\xe0\xff\xff\xff\xff\xe8'\x0f\xf0\xff\xff\xff\xff\xe9\x16\xf2\xe0\xff\xff\xff\xff\xea\x06\xf1\xf0\xff\xff\xff\xff\xea\xf6\xd4\xe0\xff\xff\xff\xff" +
+	"\xeb\xe6\xd3\xf0\xff\xff\xff\xff\xecֶ\xe0\xff\xff\xff\xff\xedƵ\xf0\xff\xff\xff\xff\xee\xbf\xd3`\xff\xff\xff\xff\xef\xaf\xd2p\xff\xff\xff\xff\xf0\x9f\xb5`\xff\xff\xff\xff\xf1\x8f\xb4p\xff\xff\xff\xff\xf2\x7f\x97`" +
+	"\xff\xff\xff\xff\xf3o\x96p\xff\xff\xff\xff\xf4_y`\xff\xff\xff\xff\xf5Oxp\xff\xff\xff\xff\xf6?[`\xff\xff\xff\xff\xf7/Zp\xff\xff\xff\xff\xf8(w\xe0\xff\xff\xff\xff\xf9\x0f<p\xff\xff\xff\xff" +
+	"\xfa\bY\xe0\xff\xff\xff\xff\xfa\xf8X\xf0\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0" +
+	"\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\a0\xc2`\x00\x00\x00\x00" +
+	"\a\x8d\x19p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\t\xad\x94\xf0\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00\f٢\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0" +
+	"\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00" +
+	"\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x00\x00\x00\x00\x1a\xf2\np\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp" +
+	"\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\"U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00" +
+	"$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\nU\xe0\x00\x00\x00\x00)ޥp\x00\x00\x00\x00*\xea7\xe0" +
+	"\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x00" +
+	"2r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\a\r\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0" +
+	"\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00" +
+	"@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xba\x9e\x00\x00\xff\xff\xc7\xc0\x01\x04\xff" +
+	"\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\f\xff\xff\xc7\xc0\x01\x10LMT\x00EDT\x00EST\x00EWT\x00EPT\x00\nEST5EDT,M3.2.0,M11.1.0" +
+	"\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xeaK\x85v\xdd\x00\x00\x00\xdd\x00\x00\x00\t\x00\x00\x00US/HawaiiTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\a\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xfft\xe0p\xbe\xff\xff\xff\xff\xbb\x05CH\xff\xff\xff\xff\xbb!qX\xff\xff\xff\xffˉ=\xc8\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2" +
+	"aI8\xff\xff\xff\xffՍsH\x01\x02\x01\x03\x04\x01\x05\xff\xffl\x02\x00\x00\xff\xfflX\x00\x04\xff\xffzh\x01\b\xff\xffzh\x01\f\xff\xffzh\x01\x10\xff\xffs`\x00\x04LMT\x00HS" +
+	"T\x00HDT\x00HWT\x00HPT\x00\nHST10\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$ \x873\xf8\x03\x00\x00\xf8\x03\x00\x00\x11\x00\x00\x00US/Indian" +
+	"a-StarkeTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00T" +
+	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff" +
+	"\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6" +
+	" \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdcޗ\x80\xff" +
+	"\xff\xff\xffݩ\x90p\xff\xff\xff\xff\u07bey\x80\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4" +
+	"^\x1f\x80\xff\xff\xff\xff\xe5W<\xf0\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe77\x1e\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff" +
+	"\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xd6\xc4\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\xee\xbf\xe1p\xff\xff\xff\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xf0\x9f\xc3p\xff\xff\xff\xff\xf1\x8f\u0080\xff\xff\xff\xff\xf4" +
+	"_\x87p\xff\xff\xff\xff\xfa\xf8g\x00\xff\xff\xff\xff\xfb\xe8I\xf0\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8+\xf0\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\r\xf0\x00\x00\x00\x00\x00\x98\r\x00\x00" +
+	"\x00\x00\x00\x01\x87\xef\xf0\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\fp\x00\x00\x00\x00\x04a\v\x80\x00\x00\x00\x00\x05P\xeep\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\a0\xd0p\x00\x00\x00\x00\a" +
+	"\x8d'\x80\x00\x00\x00\x00\t\x10\xb2p\x00\x00\x00\x00\t\xad\xa3\x00\x00\x00\x00\x00\n\xf0\x94p\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00\x00\x00\fٰ\xf0\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00" +
+	"\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99t\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x16" +
+	"9\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\"7p\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00" +
+	"\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1܀\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$" +
+	"5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)\nc\xf0\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDQp\x00" +
+	"\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x05\x01\x02\x01\xff\xff\xae\xca\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff" +
+	"\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00\nCST6CDT,M3.2.0,M11." +
+	"1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x14\xe7\x03\x83\x03\x00\x00\x83\x03\x00\x00\v\x00\x00\x00US/MichiganTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff\x85\xbd\"[\xff\xff\xff\xff\x99<\x94\x00\xff\xff\xff\xffˈ\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0" +
+	"\xff\xff\xff\xff\xd75\xa8\xf0\xff\xff\xff\xff\xd8\x00\xa1\xe0\xff\xff\xff\xff\xfb3\x90\x8c\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00" +
+	"\a0\xc2`\x00\x00\x00\x00\a\x8d\x19p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\n\x00\xa3p\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00\f٢\xe0\x00\x00\x00\x00\r\xc0gp" +
+	"\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00" +
+	"\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x00\x00\x00\x00\x1a\xf2\np\x00\x00\x00\x00\x1b\xe1\xed`" +
+	"\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\"U\xe2\xf0\x00\x00\x00\x00" +
+	"#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\nU\xe0\x00\x00\x00\x00)ޥp" +
+	"\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x00" +
+	"1gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\a\r\xf0\x00\x00\x00\x008\x1b\xda\xe0" +
+	"\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00" +
+	"?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0" +
+	"\x01\x02\x03\x04\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05" +
+	"\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\xff\xff\xb2%\x00\x00\xff\xff\xab\xa0\x00\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\f\xff\xff\xc7\xc0\x01\x10\xff\xff\xc7\xc0\x01\x14LMT\x00" +
+	"CST\x00EST\x00EWT\x00EPT\x00EDT\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\x80" +
+	"\x94@\x12\x04\x00\x00\x12\x04\x00\x00\v\x00\x00\x00US/MountainTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a\x00\x00\x00\x05\x00\x00\x00\x14" +
+	"\xff\xff\xff\xff^\x04\f\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff\xff\xff\xa2e\xfe\x90\xff\xff\xff\xff\xa3\x84\x06\x00\xff\xff\xff\xff" +
+	"\xa4E\xe0\x90\xff\xff\xff\xff\xa4\x8f\xa6\x80\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xf7/v\x90\xff\xff\xff\xff\xf8(\x94\x00\xff\xff\xff\xff\xf9\x0fX\x90" +
+	"\xff\xff\xff\xff\xfa\bv\x00\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W\x10\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb89\x10\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00" +
+	"\x00\x98\x1b\x10\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xfd\x10\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\a0ހ" +
+	"\x00\x00\x00\x00\a\x8d5\x90\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\t\xad\xb1\x10\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\vࡐ\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0\x83\x90\x00\x00\x00\x00" +
+	"\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10" +
+	"\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00" +
+	"\x1c\xd2\b\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00" +
+	"\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeߐ\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00" +
+	"*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10" +
+	"\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x00" +
+	"8\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00" +
+	"\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x02\x01\x02\x01" +
+	"\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\x9d\x94\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab" +
+	"\xa0\x01\x10LMT\x00MDT\x00MST\x00MWT\x00MPT\x00\nMST7MDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\xf6\"\x12\xfe\x0e\x05\x00\x00\x0e\x05\x00\x00\n\x00\x00\x00US/PacificTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00}\x00\x00\x00\x05\x00\x00" +
+	"\x00\x14\xff\xff\xff\xff^\x04\x1a\xc0\xff\xff\xff\xff\x9e\xa6H\xa0\xff\xff\xff\xff\x9f\xbb\x15\x90\xff\xff\xff\xff\xa0\x86*\xa0\xff\xff\xff\xff\xa1\x9a\xf7\x90\xff\xff\xff\xffˉ\x1a\xa0\xff\xff\xff\xff\xd2#\xf4p\xff\xff" +
+	"\xff\xff\xd2a&\x10\xff\xff\xff\xff\xd6\xfet\\\xff\xff\xff\xff\u0600\xad\x90\xff\xff\xff\xff\xda\xfeÐ\xff\xff\xff\xff\xdb\xc0\x90\x10\xff\xff\xff\xff\xdcޥ\x90\xff\xff\xff\xffݩ\xac\x90\xff\xff\xff\xff\u07be" +
+	"\x87\x90\xff\xff\xff\xff߉\x8e\x90\xff\xff\xff\xff\xe0\x9ei\x90\xff\xff\xff\xff\xe1ip\x90\xff\xff\xff\xff\xe2~K\x90\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4^-\x90\xff\xff\xff\xff\xe5)4\x90\xff\xff" +
+	"\xff\xff\xe6GJ\x10\xff\xff\xff\xff\xe7\x12Q\x10\xff\xff\xff\xff\xe8',\x10\xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff\xff\xea\a\x0e\x10\xff\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff\xff\xeb\xe6\xf0\x10\xff\xff\xff\xff\xec\xb1" +
+	"\xf7\x10\xff\xff\xff\xff\xed\xc6\xd2\x10\xff\xff\xff\xff\xee\x91\xd9\x10\xff\xff\xff\xff\xef\xaf\xee\x90\xff\xff\xff\xff\xf0q\xbb\x10\xff\xff\xff\xff\xf1\x8fА\xff\xff\xff\xff\xf2\x7f\xc1\x90\xff\xff\xff\xff\xf3o\xb2\x90\xff\xff" +
+	"\xff\xff\xf4_\xa3\x90\xff\xff\xff\xff\xf5O\x94\x90\xff\xff\xff\xff\xf6?\x85\x90\xff\xff\xff\xff\xf7/v\x90\xff\xff\xff\xff\xf8(\xa2\x10\xff\xff\xff\xff\xf9\x0fX\x90\xff\xff\xff\xff\xfa\b\x84\x10\xff\xff\xff\xff\xfa\xf8" +
+	"\x83 \xff\xff\xff\xff\xfb\xe8f\x10\xff\xff\xff\xff\xfc\xd8e \xff\xff\xff\xff\xfd\xc8H\x10\xff\xff\xff\xff\xfe\xb8G \xff\xff\xff\xff\xff\xa8*\x10\x00\x00\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88\f\x10\x00\x00" +
+	"\x00\x00\x02x\v \x00\x00\x00\x00\x03q(\x90\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05Q\n\x90\x00\x00\x00\x00\x06A\t\xa0\x00\x00\x00\x00\a0\xec\x90\x00\x00\x00\x00\a\x8dC\xa0\x00\x00\x00\x00\t\x10" +
+	"ΐ\x00\x00\x00\x00\t\xad\xbf \x00\x00\x00\x00\n\xf0\xb0\x90\x00\x00\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00" +
+	"\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)" +
+	"6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00" +
+	"\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1ې\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\"V\r \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J" +
+	"\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\n\x80\x10\x00\x00\x00\x00)\xdeϠ\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00" +
+	"\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003G" +
+	"t \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\a8 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00" +
+	"\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84" +
+	"\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E\xf3\xd3 \x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
+	"\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\x91&\x00\x00\xff\xff\x9d\x90\x01\x04\xff" +
+	"\xff\x8f\x80\x00\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10LMT\x00PDT\x00PST\x00PWT\x00PPT\x00\nPST8PDT,M3.2.0,M11.1.0" +
+	"\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\xca{e\x92\x00\x00\x00\x92\x00\x00\x00\b\x00\x00\x00US/SamoaTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\b\xff\xff\xff\xffn=\xc8\b\xff\xff\xff\xff\x91\x05\xfb\b\x01\x02\x00\x00\xb1x\x00\x00\xff\xff_\xf8\x00\x00\xff\xffeP\x00\x04LMT\x00SST\x00\nS" +
+	"ST11\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\x03\x00\x00\x00UTCTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00\nUTC0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\t\x00\x00\x00U" +
+	"niversalTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00T" +
+	"Zif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00\nUTC0\nP" +
+	"K\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1\xc1\xeb\x05\x8c\x03\x00\x00\x8c\x03\x00\x00\x04\x00\x00\x00W-SUTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00N" +
+	"\x00\x00\x00\v\x00\x00\x00&\xff\xff\xff\xffV\xb6\xc0\xc7\xff\xff\xff\xff\x9b_\x1e\xc7\xff\xff\xff\xff\x9d>\xf2y\xff\xff\xff\xff\x9e*\xee\xf9\xff\xff\xff\xff\x9e\xf79i\xff\xff\xff\xff\x9f\x84W\xf9\xff\xff\xff\xff" +
+	"\xa0\xd8l\xe9\xff\xff\xff\xff\xa1\x009\x80\xff\xff\xff\xff\xa1<\xa6@\xff\xff\xff\xff\xa4\x10m\xc0\xff\xff\xff\xff\xa4=2\xb0\xff\xff\xff\xff\xa5\x15h\xb0\xff\xff\xff\xff\xa5=\x03\xc0\xff\xff\xff\xff\xa7\x1eEP" +
+	"\xff\xff\xff\xff\xb5\xa4\x19`\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00" +
+	"\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0" +
+	"\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00" +
+	"(\xe5\x17\x80\x00\x00\x00\x00)x\xbf\x80\x00\x00\x00\x00)\xd4\xfap\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x94\xbep\x00\x00\x00\x00.\x84\xafp" +
+	"\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x00" +
+	"62[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb<p\x00\x00\x00\x00<\xa6Cp" +
+	"\x00\x00\x00\x00=\xbb\x1ep\x00\x00\x00\x00>\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f\ap\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00" +
+	"D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05\xadp\x00\x00\x00\x00G#\xc2\xf0\x00\x00\x00\x00G\xee\xc9\xf0\x00\x00\x00\x00I\x03\xa4\xf0\x00\x00\x00\x00IΫ\xf0\x00\x00\x00\x00J\xe3\x86\xf0" +
+	"\x00\x00\x00\x00K\xae\x8d\xf0\x00\x00\x00\x00Ḷp\x00\x00\x00\x00M\x8eo\xf0\x00\x00\x00\x00TL\x1d`\x01\x03\x02\x03\x04\x02\x04\x05\x06\x05\a\x05\x06\b\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" +
+	"\x06\x05\x06\x05\x06\x05\x06\t\b\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\n\x06\x00\x00#9\x00\x00\x00\x00#9" +
+	"\x00\x04\x00\x001\x87\x01\b\x00\x00#w\x00\x04\x00\x00?\x97\x01\f\x00\x008@\x01\x11\x00\x00*0\x00\x15\x00\x00FP\x01\x19\x00\x00\x1c \x00\x1d\x00\x00*0\x01!\x00\x008@\x00\x15LMT\x00" +
+	"MMT\x00MST\x00MDST\x00MSD\x00MSK\x00+05\x00EET\x00EEST\x00\nMSK-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x002\x91B\xc0\xee" +
+	"\x01\x00\x00\xee\x01\x00\x00\x03\x00\x00\x00WETTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00" +
+	"\x00\x00\x00\x00\x00TZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\x00\x00\x00\x02\x00\x00\x00\t\x00\x00\x00\x00\r\xa4c\x90\x00\x00\x00" +
+	"\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb" +
+	"\x90\x00\x00\x00\x00\x16\x13ܐ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19Ӡ\x90\x00\x00\x00\x00\x1aÑ\x90\x00\x00\x00\x00\x1b\xbc\xbd\x10\x00\x00\x00" +
+	"\x00\x1c\xac\xae\x10\x00\x00\x00\x00\x1d\x9c\x9f\x10\x00\x00\x00\x00\x1e\x8c\x90\x10\x00\x00\x00\x00\x1f|\x81\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E" +
+	"\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00" +
+	"\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9" +
+	"\x10\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x00\x00\x00\x00\x05\x00\x00\x0e\x10\x01\x00WEST\x00WET" +
+	"\x00\nWET0WEST,M3.5.0/1,M10.5.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\x04\x00\x00\x00Zu" +
+	"luTZif2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00TZif2\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00\nUTC0\nPK\x01\x02\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Africa/AbidjanPK\x01\x02\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xae\x00\x00\x00Africa/AccraPK\x01\x02\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Z\x01\x00\x00Africa/Addis_AbabaPK\x01\x02\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Ê\x0e\xc0\xd6\x01\x00\x00\xd6\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00I\x02\x00\x00Africa/AlgiersPK\x01\x02\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00K\x04\x00\x00Africa/AsmaraPK\x01\x02\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005\x05\x00\x00Africa/AsmeraPK\x01\x02\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x06\x00\x00Africa/BamakoPK\x01\x02\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcc\x06\x00\x00Africa/BanguiPK\x01\x02\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\a\x00\x00Africa/BanjulPK\x01\x02\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\xca>\xd5\xe0\x95\x00\x00\x00\x95\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X\b\x00\x00Africa/BissauPK\x01\x02\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\t\x00\x00Africa/BlantyrePK\x01\x02\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8\t\x00\x00Africa/BrazzavillePK\x01\x02\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\n\x00\x00Africa/BujumburaPK\x01\x02" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12tnj\xfc\x04\x00\x00\xfc\x04\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]\v\x00\x00Africa/CairoPK\x01\x02\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x01\x05\x89\x7f\a\x00\x00\x7f\a\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x83\x10\x00\x00Africa/CasablancaPK\x01" +
+	"\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f\x1b\xeb\xdd2\x02\x00\x002\x02\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x001\x18\x00\x00Africa/CeutaPK\x01\x02\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8d\x1a\x00\x00Africa/ConakryPK\x01\x02\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00;\x1b\x00\x00Africa/DakarPK\x01\x02\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe7\x1b\x00\x00Africa/Dar_es_SalaamP" +
+	"K\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd8\x1c\x00\x00Africa/Djibouti" +
+	"PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc4\x1d\x00\x00Africa/DoualaP" +
+	"K\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)\xae\x8eo&\a\x00\x00&\a\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa3\x1e\x00\x00Africa/El_Aaiun" +
+	"PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6%\x00\x00Africa/Freetow" +
+	"nPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa5&\x00\x00Africa/Gaboro" +
+	"nePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00U'\x00\x00Africa/Harar" +
+	"ePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcc\fTξ\x00\x00\x00\xbe\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03(\x00\x00Africa/Johann" +
+	"esburgPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\xcf\x10n\xca\x01\x00\x00\xca\x01\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf2(\x00\x00Africa/J" +
+	"ubaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5*\x00\x00Africa/Kamp" +
+	"alaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\xadD\xef\xca\x01\x00\x00\xca\x01\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd0+\x00\x00Africa/Khar" +
+	"toumPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7-\x00\x00Africa/Kig" +
+	"aliPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00u.\x00\x00Africa/Kins" +
+	"hasaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V/\x00\x00Africa/Lag" +
+	"osPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0040\x00\x00Africa/Libre" +
+	"villePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x171\x00\x00Africa/Lo" +
+	"mePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc21\x00\x00Africa/Luand" +
+	"aPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa12\x00\x00Africa/Lubumb" +
+	"ashiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S3\x00\x00Africa/Lus" +
+	"akaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x014\x00\x00Africa/Mala" +
+	"boPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe04\x00\x00Africa/Maput" +
+	"oPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcc\fTξ\x00\x00\x00\xbe\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8e5\x00\x00Africa/Maseru" +
+	"PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcc\fTξ\x00\x00\x00\xbe\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00w6\x00\x00Africa/Mbabane" +
+	"PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a7\x00\x00Africa/Mogadis" +
+	"huPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x006\x99rU\xa4\x00\x00\x00\xa4\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00N8\x00\x00Africa/Monro" +
+	"viaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f9\x00\x00Africa/Nair" +
+	"obiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa\x81\t\x03\xa0\x00\x00\x00\xa0\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n:\x00\x00Africa/Ndja" +
+	"menaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd7:\x00\x00Africa/Nia" +
+	"meyPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb6;\x00\x00Africa/Noua" +
+	"kchottPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g<\x00\x00Africa/O" +
+	"uagadougouPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x19=\x00\x00Afri" +
+	"ca/Porto-NovoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc1\n\x8a\x84\xad\x00\x00\x00\xad\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfc=\x00\x00A" +
+	"frica/Sao_TomePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd6>\x00\x00" +
+	"Africa/TimbuktuPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00_\x7f2[\xaf\x01\x00\x00\xaf\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85?\x00" +
+	"\x00Africa/TripoliPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x93\xf4\x94\v\xc1\x01\x00\x00\xc1\x01\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`A\x00" +
+	"\x00Africa/TunisPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00m)\xb8P~\x02\x00\x00~\x02\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00KC\x00\x00A" +
+	"frica/WindhoekPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xae,\xa44\xc9\x03\x00\x00\xc9\x03\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6E\x00\x00" +
+	"America/AdakPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005\x11Q\x06\xd1\x03\x00\x00\xd1\x03\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe9I\x00\x00Am" +
+	"erica/AnchoragePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe9M\x00" +
+	"\x00America/AnguillaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8" +
+	"N\x00\x00America/AntiguaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\x01V\rP\x02\x00\x00P\x02\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\xa6O\x00\x00America/AraguainaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\xbf\xf5\xe5\xc4\x02\x00\x00\xc4\x02\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00%R\x00\x00America/Argentina/Buenos_AiresPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00R\xc8\xd9\xf6\xc4\x02\x00" +
+	"\x00\xc4\x02\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00%U\x00\x00America/Argentina/CatamarcaPK\x01\x02\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00R\xc8\xd9\xf6\xc4\x02\x00\x00\xc4\x02\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\"X\x00\x00America/Argentina/ComodR" +
+	"ivadaviaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xef\xf0R\x8a\xc4\x02\x00\x00\xc4\x02\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$[\x00\x00Americ" +
+	"a/Argentina/CordobaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00utZ\x1a\xb2\x02\x00\x00\xb2\x02\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x1f^\x00\x00America/Argentina/JujuyPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00m\aD\x0e\xcd\x02\x00\x00\xcd\x02\x00\x00\x1a\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06a\x00\x00America/Argentina/La_RiojaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ŒZ\x8c" +
+	"\xc4\x02\x00\x00\xc4\x02\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\vd\x00\x00America/Argentina/MendozaPK\x01\x02\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x8ep\xb4c\xc4\x02\x00\x00\xc4\x02\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06g\x00\x00America/Argentina/Rio_G" +
+	"allegosPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t*\x9b!\xb2\x02\x00\x00\xb2\x02\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06j\x00\x00America" +
+	"/Argentina/SaltaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfcz=\xe1\xcd\x02\x00\x00\xcd\x02\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xedl" +
+	"\x00\x00America/Argentina/San_JuanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\x80\xb9\\\xcd\x02\x00\x00\xcd\x02\x00\x00\x1a\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf2o\x00\x00America/Argentina/San_LuisPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y\xd8֭" +
+	"\xd6\x02\x00\x00\xd6\x02\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf7r\x00\x00America/Argentina/TucumanPK\x01\x02\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x8b}\xb6\x1e\xc4\x02\x00\x00\xc4\x02\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04v\x00\x00America/Argentina/Ushua" +
+	"iaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xffx\x00\x00America/Arub" +
+	"aPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\xa9y\x9at\x03\x00\x00t\x03\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdby\x00\x00America/Asunc" +
+	"ionPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Ծ\xe7#\x95\x00\x00\x00\x95\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00}}\x00\x00America/Ati" +
+	"kokanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xae,\xa44\xc9\x03\x00\x00\xc9\x03\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@~\x00\x00America/A" +
+	"tkaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00OKjǪ\x02\x00\x00\xaa\x02\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\x82\x00\x00America/Bah" +
+	"iaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00U\x0e\x01n\xd8\x02\x00\x00\xd8\x02\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x85\x00\x00America/Bahi" +
+	"a_BanderasPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00l=\xad\xbe\x16\x01\x00\x00\x16\x01\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\x88\x00\x00Amer" +
+	"ica/BarbadosPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85-\xb9\xf8\x8a\x01\x00\x00\x8a\x01\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X\x89\x00\x00Am" +
+	"erica/BelemPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x89غ\xee\x15\x04\x00\x00\x15\x04\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r\x8b\x00\x00Ame" +
+	"rica/BelizePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00N\x8f\x00\x00Ame" +
+	"rica/Blanc-SablonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8Dz\x97\xae\x01\x00\x00\xae\x01\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x001" +
+	"\x90\x00\x00America/Boa_VistaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,g\xec\xec\xb3\x00\x00\x00\xb3\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x0e\x92\x00\x00America/BogotaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00.\xbe\x1a>\xe7\x03\x00\x00\xe7\x03\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\xed\x92\x00\x00America/BoisePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\xbf\xf5\xe5\xc4\x02\x00\x00\xc4\x02\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\xff\x96\x00\x00America/Buenos_AiresPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\xba\xb2\x94s\x03\x00\x00s\x03\x00\x00\x15\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\xf5\x99\x00\x00America/Cambridge_BayPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1e\xfbn۸\x03\x00\x00\xb8\x03\x00\x00" +
+	"\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\x9d\x00\x00America/Campo_GrandePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf2\x04\xde\xdd\x11\x02" +
+	"\x00\x00\x11\x02\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85\xa1\x00\x00America/CancunPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x8e\xee\x13\xbe\x00" +
+	"\x00\x00\xbe\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00£\x00\x00America/CaracasPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00R\xc8\xd9\xf6\xc4" +
+	"\x02\x00\x00\xc4\x02\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xad\xa4\x00\x00America/CatamarcaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1'" +
+	"\a\xbd\x97\x00\x00\x00\x97\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa0\xa7\x00\x00America/CayennePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd4" +
+	"\xbe\xe7#\x95\x00\x00\x00\x95\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\xa8\x00\x00America/CaymanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b" +
+	"ܩ=\xda\x06\x00\x00\xda\x06\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00%\xa9\x00\x00America/ChicagoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x111\x04q\xb3\x02\x00\x00\xb3\x02\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,\xb0\x00\x00America/ChihuahuaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\xad\xf2L\x06\xce\x02\x00\x00\xce\x02\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\xb3\x00\x00America/Ciudad_JuarezPK\x01\x02\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Ծ\xe7#\x95\x00\x00\x00\x95\x00\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\xb6\x00\x00America/Coral_Harbou" +
+	"rPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xef\xf0R\x8a\xc4\x02\x00\x00\xc4\x02\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\u05f6\x00\x00America/Cordo" +
+	"baPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb1݂x\xe8\x00\x00\x00\xe8\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ȹ\x00\x00America/Cost" +
+	"a_RicaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ø\xab\x9b\xf0\x00\x00\x00\xf0\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\xba\x00\x00America/" +
+	"CrestonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f$*\xa0\xa6\x03\x00\x00\xa6\x03\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xbb\x00\x00America" +
+	"/CuiabaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Ͽ\x00\x00America" +
+	"/CuracaoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xc2\rx\xbf\x01\x00\x00\xbf\x01\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xad\xc0\x00\x00Americ" +
+	"a/DanmarkshavnPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe\xe6\xf5J\x05\x04\x00\x00\x05\x04\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9e\xc2\x00\x00" +
+	"America/DawsonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00+\x10`ȫ\x02\x00\x00\xab\x02\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcf\xc6\x00\x00" +
+	"America/Dawson_CreekPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\x80\x94@\x12\x04\x00\x00\x12\x04\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\xac\xc9\x00\x00America/DenverPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x14\xe7\x03\x83\x03\x00\x00\x83\x03\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\xea\xcd\x00\x00America/DetroitPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x9a\xd1\x00\x00America/DominicaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{\a\a\xdc\xca\x03\x00\x00\xca\x03\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00y\xd2\x00\x00America/EdmontonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00s\xb0\xeau\xb4\x01\x00\x00\xb4\x01\x00\x00\x10\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00q\xd6\x00\x00America/EirunepePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xea$\xc1\xbf\xb0\x00\x00\x00\xb0\x00\x00\x00\x13\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00S\xd8\x00\x00America/El_SalvadorPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb9B$\x90\x01\x04\x00\x00\x01\x04\x00\x00" +
+	"\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x004\xd9\x00\x00America/EnsenadaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6@\rm\xa8\x05\x00\x00\xa8\x05" +
+	"\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00c\xdd\x00\x00America/Fort_NelsonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\xb6{\xc9\x13" +
+	"\x02\x00\x00\x13\x02\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\xe3\x00\x00America/Fort_WaynePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4" +
+	"\x11Z\xde\xe4\x01\x00\x00\xe4\x01\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\xe5\x00\x00America/FortalezaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00M\x94\xc7Kp\x03\x00\x00p\x03\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x92\xe7\x00\x00America/Glace_BayPK\x01\x02\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x80\xbc\xc9I\xa3\x03\x00\x00\xa3\x03\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x001\xeb\x00\x00America/GodthabPK\x01\x02\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x1d\xf7\a ,\x06\x00\x00,\x06\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xef\x00\x00America/Goose_BayPK\x01\x02\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe3\xc9I\xd0U\x03\x00\x00U\x03\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\\\xf5\x00\x00America/Grand_TurkPK\x01" +
+	"\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1\xf8\x00\x00America/GrenadaPK" +
+	"\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbf\xf9\x00\x00America/Guadelou" +
+	"pePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x8a\x83S\xd4\x00\x00\x00\xd4\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa0\xfa\x00\x00America/Guat" +
+	"emalaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcd\xc3v\xe3\xb3\x00\x00\x00\xb3\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa3\xfb\x00\x00America/G" +
+	"uayaquilPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x05\xf3\x89\xb5\x00\x00\x00\xb5\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85\xfc\x00\x00Americ" +
+	"a/GuyanaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00):\x17-\x88\x06\x00\x00\x88\x06\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00f\xfd\x00\x00Americ" +
+	"a/HalifaxPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x1c\x9e\x9a]\x04\x00\x00]\x04\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\x04\x01\x00Ameri" +
+	"ca/HavanaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe4MS\x99\x1e\x01\x00\x00\x1e\x01\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\b\x01\x00Ameri" +
+	"ca/HermosilloPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\xb6{\xc9\x13\x02\x00\x00\x13\x02\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf2\t\x01\x00A" +
+	"merica/Indiana/IndianapolisPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$ \x873\xf8\x03\x00\x00\xf8\x03\x00\x00\x14\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00?\f\x01\x00America/Indiana/KnoxPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00M/U\x9f7\x02\x00\x007\x02\x00" +
+	"\x00\x17\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00i\x10\x01\x00America/Indiana/MarengoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xd8" +
+	"N\x8c\xab\x02\x00\x00\xab\x02\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd5\x12\x01\x00America/Indiana/PetersburgPK\x01\x02\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00صK\xa6\n\x02\x00\x00\n\x02\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb8\x15\x01\x00America/Indiana/Tell" +
+	"_CityPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x17\x89}q\x01\x00\x00q\x01\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf9\x17\x01\x00America/I" +
+	"ndiana/VevayPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r\xedsp.\x02\x00\x00.\x02\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9d\x19\x01\x00Am" +
+	"erica/Indiana/VincennesPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00K-E\xfad\x02\x00\x00d\x02\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x02\x1c\x01\x00America/Indiana/WinamacPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\xb6{\xc9\x13\x02\x00\x00\x13\x02\x00\x00" +
+	"\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\x1e\x01\x00America/IndianapolisPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ʼ\to1\x03" +
+	"\x00\x001\x03\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0 \x01\x00America/InuvikPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Š\xd6\x05W\x03" +
+	"\x00\x00W\x03\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=$\x01\x00America/IqaluitPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00%J\xd5\xebS" +
+	"\x01\x00\x00S\x01\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc1'\x01\x00America/JamaicaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00utZ\x1a" +
+	"\xb2\x02\x00\x00\xb2\x02\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00A)\x01\x00America/JujuyPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\xc9\x1c\xd4\xc6" +
+	"\x03\x00\x00\xc6\x03\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1e,\x01\x00America/JuneauPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdf\xe5\x8d\xc4\xda" +
+	"\x04\x00\x00\xda\x04\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x100\x01\x00America/Kentucky/LouisvillePK\x01\x02\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x03\x1a|J\xcc\x03\x00\x00\xcc\x03\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00#5\x01\x00America/Kentucky/Monti" +
+	"celloPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$ \x873\xf8\x03\x00\x00\xf8\x03\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00(9\x01\x00America/K" +
+	"nox_INPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00M=\x01\x00America/" +
+	"KralendijkPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xad`\x12\xe9\xaa\x00\x00\x00\xaa\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00.>\x01\x00Amer" +
+	"ica/La_PazPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe7\xa1\x87\x1b\x01\x00\x00\x1b\x01\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04?\x01\x00Amer" +
+	"ica/LimaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\"\x12\xfe\x0e\x05\x00\x00\x0e\x05\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00I@\x01\x00Americ" +
+	"a/Los_AngelesPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdf\xe5\x8d\xc4\xda\x04\x00\x00\xda\x04\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x88E\x01\x00A" +
+	"merica/LouisvillePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x92" +
+	"J\x01\x00America/Lower_PrincesPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00挋\x92\xf6\x01\x00\x00\xf6\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00vK\x01\x00America/MaceioPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5s\xb3\\'\x01\x00\x00'\x01\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x98M\x01\x00America/ManaguaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a\xcb'\xe9\x9c\x01\x00\x00\x9c\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\xecN\x01\x00America/ManausPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\xb4P\x01\x00America/MarigotPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x17jҲ\x00\x00\x00\xb2\x00\x00\x00\x12\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x92Q\x01\x00America/MartiniquePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00((i\xe4\xb5\x01\x00\x00\xb5\x01\x00\x00\x11\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00tR\x01\x00America/MatamorosPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\xad=\x98\xce\x02\x00\x00\xce\x02\x00" +
+	"\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00XT\x01\x00America/MazatlanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ŒZ\x8c\xc4\x02\x00\x00\xc4" +
+	"\x02\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00TW\x01\x00America/MendozaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x008O:\xbf\x95\x03\x00\x00" +
+	"\x95\x03\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00EZ\x01\x00America/MenomineePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\xbd\x809\x8e" +
+	"\x02\x00\x00\x8e\x02\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t^\x01\x00America/MeridaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa2\x81\xbfyS" +
+	"\x02\x00\x00S\x02\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc3`\x01\x00America/MetlakatlaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd5" +
+	"\b\x89\x8c\x05\x03\x00\x00\x05\x03\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Fc\x01\x00America/Mexico_CityPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\xd7\b\\\xc6&\x02\x00\x00&\x02\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|f\x01\x00America/MiquelonPK\x01\x02\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00.\xf9\xc0\x1e\xd5\x05\x00\x00\xd5\x05\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd0h\x01\x00America/MonctonPK\x01\x02\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00L+\xe3u\x84\x02\x00\x00\x84\x02\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd2n\x01\x00America/MonterreyPK\x01\x02\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0\x98\x00\b\xc9\x03\x00\x00\xc9\x03\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85q\x01\x00America/MontevideoPK" +
+	"\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ӿ\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00~u\x01\x00America/Montreal" +
+	"PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a|\x01\x00America/Montse" +
+	"rratPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ӿ\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B}\x01\x00America/Na" +
+	"ssauPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\x9aG\xc8\xd0\x06\x00\x00\xd0\x06\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00#\x84\x01\x00America/Ne" +
+	"w_YorkPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ӿ\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00!\x8b\x01\x00America/" +
+	"NipigonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\xab\xd5\xf9\xcf\x03\x00\x00\xcf\x03\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x92\x01\x00America" +
+	"/NomePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7-2f\xe4\x01\x00\x00\xe4\x01\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfc\x95\x01\x00America/N" +
+	"oronhaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7.\xb6*\x13\x04\x00\x00\x13\x04\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r\x98\x01\x00America/" +
+	"North_Dakota/BeulahPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00H\xeam\xef\xde\x03\x00\x00\xde\x03\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00Y\x9c\x01\x00America/North_Dakota/CenterPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00R\x1b\x8b(\xde\x03\x00\x00\xde\x03\x00\x00" +
+	"\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\xa0\x01\x00America/North_Dakota/New_SalemPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x80\xbc\xc9I\xa3\x03\x00\x00\xa3\x03\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8a\xa4\x01\x00America/NuukPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x01\xe5\x9e<\xc5\x02\x00\x00\xc5\x02\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00W\xa8\x01\x00America/OjinagaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00Ծ\xe7#\x95\x00\x00\x00\x95\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00I\xab\x01\x00America/PanamaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00Š\xd6\x05W\x03\x00\x00W\x03\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\xac\x01\x00America/PangnirtungPK\x01\x02\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\xf1\xf9\x1dɻ\x00\x00\x00\xbb\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x92\xaf\x01\x00America/ParamariboPK\x01\x02" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ø\xab\x9b\xf0\x00\x00\x00\xf0\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00}\xb0\x01\x00America/PhoenixPK\x01" +
+	"\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4T\xbd\xeb5\x02\x00\x005\x02\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9a\xb1\x01\x00America/Port-au-P" +
+	"rincePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xb4\x01\x00America/P" +
+	"ort_of_SpainPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\xf5K\x89\xa2\x01\x00\x00\xa2\x01\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe7\xb4\x01\x00Am" +
+	"erica/Porto_AcrePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\x81-\xa9\x8a\x01\x00\x00\x8a\x01\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb9\xb6" +
+	"\x01\x00America/Porto_VelhoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00t\xb8\x01\x00America/Puerto_RicoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x13\x9b\xb1\xc2\x04\x00\x00\xc2\x04\x00\x00\x14\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00V\xb9\x01\x00America/Punta_ArenasPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?_p\x99\x0e\x05\x00\x00\x0e\x05\x00\x00" +
+	"\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00J\xbe\x01\x00America/Rainy_RiverPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xdfH\r'\x03\x00" +
+	"\x00'\x03\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x89\xc3\x01\x00America/Rankin_InletPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbf" +
+	"\x03u\xf3\xe4\x01\x00\x00\xe4\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe2\xc6\x01\x00America/RecifePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc2" +
+	"\x96dK~\x02\x00\x00~\x02\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf2\xc8\x01\x00America/ReginaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0" +
+	"I~D'\x03\x00\x00'\x03\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9c\xcb\x01\x00America/ResolutePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00g\xf5K\x89\xa2\x01\x00\x00\xa2\x01\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\xce\x01\x00America/Rio_BrancoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\xef\xf0R\x8a\xc4\x02\x00\x00\xc4\x02\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc3\xd0\x01\x00America/RosarioPK\x01\x02\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\xb9B$\x90\x01\x04\x00\x00\x01\x04\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\xd3\x01\x00America/Santa_IsabelPK\x01\x02" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04,2h\x99\x01\x00\x00\x99\x01\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe7\xd7\x01\x00America/SantaremPK" +
+	"\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]\"_WJ\x05\x00\x00J\x05\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xae\xd9\x01\x00America/Santiago" +
+	"PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\x0f(\b=\x01\x00\x00=\x01\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&\xdf\x01\x00America/Santo_" +
+	"DomingoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9d?\xdfڸ\x03\x00\x00\xb8\x03\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xe0\x01\x00America" +
+	"/Sao_PauloPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:\x9a1T\xdf\x01\x00\x00\xdf\x01\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00}\xe4\x01\x00Amer" +
+	"ica/ScoresbysundPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\x80\x94@\x12\x04\x00\x00\x12\x04\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8e\xe6" +
+	"\x01\x00America/ShiprockPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81{\xc1\x92\xbc\x03\x00\x00\xbc\x03\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\xce\xea\x01\x00America/SitkaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb5" +
+	"\xee\x01\x00America/St_BarthelemyPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00~\xb2\x0e\x19V\a\x00\x00V\a\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x99\xef\x01\x00America/St_JohnsPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x1d\xf7\x01\x00America/St_KittsPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfc\xf7\x01\x00America/St_LuciaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x11\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdb\xf8\x01\x00America/St_ThomasPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00" +
+	"\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbb\xf9\x01\x00America/St_VincentPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\xd8\x19\x9dp\x01\x00" +
+	"\x00p\x01\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9c\xfa\x01\x00America/Swift_CurrentPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x82\x13z\xe2\xc2\x00\x00\x00\xc2\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\xfc\x01\x00America/TegucigalpaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00U\r\xf7\xd3\xc7\x01\x00\x00\xc7\x01\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x002\xfd\x01\x00America/ThulePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00ӿ\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$\xff\x01\x00America/Thunder_BayPK\x01\x02\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb9B$\x90\x01\x04\x00\x00\x01\x04\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x06\x02\x00America/TijuanaPK\x01\x02\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ӿ\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x008\n\x02\x00America/TorontoPK\x01\x02\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1a\x11\x02\x00America/TortolaPK\x01\x02" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00U9#\xbe2\x05\x00\x002\x05\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8\x11\x02\x00America/VancouverP" +
+	"K\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y\x17\x02\x00America/VirginP" +
+	"K\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbf\x1d\xee\x91\x05\x04\x00\x00\x05\x04\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x006\x18\x02\x00America/Whiteho" +
+	"rsePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?_p\x99\x0e\x05\x00\x00\x0e\x05\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\x1c\x02\x00America/Win" +
+	"nipegPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,\xdb~\xab\xb2\x03\x00\x00\xb2\x03\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7!\x02\x00America/Y" +
+	"akutatPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00/5\xe20L\x03\x00\x00L\x03\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x86%\x02\x00America/" +
+	"YellowknifePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xddzAh\xf3\x00\x00\x00\xf3\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03)\x02\x00Ant" +
+	"arctica/CaseyPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\xea\x06\xd3\xc5\x00\x00\x00\xc5\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$*\x02\x00A" +
+	"ntarctica/DavisPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\x04\x19y\x9a\x00\x00\x00\x9a\x00\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17+\x02" +
+	"\x00Antarctica/DumontDUrvillePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\x84J]\xd0\x03\x00\x00\xd0\x03\x00\x00\x14\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\xe8+\x02\x00Antarctica/MacquariePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd7N\xab\x8b\x98\x00\x00\x00\x98\x00\x00\x00" +
+	"\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xea/\x02\x00Antarctica/MawsonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b\xb2\xaf\xf7\x13\x04\x00\x00\x13" +
+	"\x04\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb10\x02\x00Antarctica/McMurdoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95{\xf3\xa9w" +
+	"\x03\x00\x00w\x03\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf44\x02\x00Antarctica/PalmerPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Ɖ" +
+	"\xf71\x84\x00\x00\x00\x84\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9a8\x02\x00Antarctica/RotheraPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00b\xb2\xaf\xf7\x13\x04\x00\x00\x13\x04\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00N9\x02\x00Antarctica/South_PolePK\x01\x02\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcfׇ\xe1\x85\x00\x00\x00\x85\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x94=\x02\x00Antarctica/SyowaPK\x01\x02\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:\xc8P7\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00G>\x02\x00Antarctica/TrollPK\x01" +
+	"\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x1d\xc6\x1b\x85\x00\x00\x00\x85\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&?\x02\x00Antarctica/Vostok" +
+	"PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17S\x91\xb3\xc1\x02\x00\x00\xc1\x02\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xda?\x02\x00Arctic/Longyea" +
+	"rbyenPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcfׇ\xe1\x85\x00\x00\x00\x85\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xccB\x02\x00Asia/Aden" +
+	"PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S\xdd\\2a\x02\x00\x00a\x02\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00xC\x02\x00Asia/AlmatyPK\x01" +
+	"\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaf\rs\xad\xa0\x03\x00\x00\xa0\x03\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02F\x02\x00Asia/AmmanPK\x01\x02\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00V\xe0\xe7!\xe7\x02\x00\x00\xe7\x02\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcaI\x02\x00Asia/AnadyrPK\x01\x02\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00T\x81\x18G^\x02\x00\x00^\x02\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdaL\x02\x00Asia/AqtauPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\xdb\xfa\xb5\xbeg\x02\x00\x00g\x02\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`O\x02\x00Asia/AqtobePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00e" +
+	"\x1bb2w\x01\x00\x00w\x01\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0Q\x02\x00Asia/AshgabatPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00e\x1b" +
+	"b2w\x01\x00\x00w\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x92S\x02\x00Asia/AshkhabadPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\xa7" +
+	"^\xfah\x02\x00\x00h\x02\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005U\x02\x00Asia/AtyrauPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd7e&uv" +
+	"\x02\x00\x00v\x02\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc6W\x02\x00Asia/BaghdadPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdav\x19z\x98\x00\x00" +
+	"\x00\x98\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00fZ\x02\x00Asia/BahrainPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x87\xb3<\xe8\x02\x00\x00\xe8" +
+	"\x02\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00([\x02\x00Asia/BakuPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x88\xf6C\x84\x98\x00\x00\x00\x98\x00\x00\x00\f\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x007^\x02\x00Asia/BangkokPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x87\xbd\xedL\xf1\x02\x00\x00\xf1\x02\x00\x00\f\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf9^\x02\x00Asia/BarnaulPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7\x11\xe1[\xdc\x02\x00\x00\xdc\x02\x00\x00\v\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x14b\x02\x00Asia/BeirutPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000]*\x1bj\x02\x00\x00j\x02\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x19e\x02\x00Asia/BishkekPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7f^]@\x01\x00\x00@\x01\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\xadg\x02\x00Asia/BruneiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9a\x1a\xdc\xca\xdc\x00\x00\x00\xdc\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x16i\x02\x00Asia/CalcuttaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\xcd\xdf\x05\xee\x02\x00\x00\xee\x02\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d" +
+	"j\x02\x00Asia/ChitaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81z&\x80k\x02\x00\x00k\x02\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003m\x02\x00A" +
+	"sia/ChoibalsanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcbo\x02\x00" +
+	"Asia/ChongqingPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80q\x02\x00" +
+	"Asia/ChungkingPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\\\x91\x87\xbb\xf7\x00\x00\x00\xf7\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005s\x02\x00" +
+	"Asia/ColomboPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?Y\xaf\x19\xe7\x00\x00\x00\xe7\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Vt\x02\x00As" +
+	"ia/DaccaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x87\a\xeci\xd2\x04\x00\x00\xd2\x04\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00eu\x02\x00Asia/D" +
+	"amascusPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?Y\xaf\x19\xe7\x00\x00\x00\xe7\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00bz\x02\x00Asia/Dh" +
+	"akaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Β\x1a\x8c\xaa\x00\x00\x00\xaa\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q{\x02\x00Asia/DiliPK" +
+	"\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xed\x8c\xf1\x91\x85\x00\x00\x00\x85\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B|\x02\x00Asia/DubaiPK\x01\x02\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00's\x96\x1en\x01\x00\x00n\x01\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xef|\x02\x00Asia/DushanbePK\x01\x02\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00]S\xbb\x12\xac\x03\x00\x00\xac\x03\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x88~\x02\x00Asia/FamagustaPK\x01\x02\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00= \x17x\xea\x04\x00\x00\xea\x04\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`\x82\x02\x00Asia/GazaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\x87\x02\x00Asia/HarbinPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00C\xbe\x86\xb6\xfc\x04\x00\x00\xfc\x04\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00#\x89\x02\x00Asia/HebronPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000I" +
+	"\xc7\xde\xec\x00\x00\x00\xec\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00H\x8e\x02\x00Asia/Ho_Chi_MinhPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"E\t\xfa-\a\x03\x00\x00\a\x03\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b\x8f\x02\x00Asia/Hong_KongPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\xba\xa3b\xc1R\x02\x00\x00R\x02\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\x92\x02\x00Asia/HovdPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf9l\x03\x12\xf8" +
+	"\x02\x00\x00\xf8\x02\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x95\x02\x00Asia/IrkutskPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\aW\x10Ѱ\x04\x00" +
+	"\x00\xb0\x04\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000\x98\x02\x00Asia/IstanbulPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b\xadű\xf8\x00\x00\x00" +
+	"\xf8\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\x9d\x02\x00Asia/JakartaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00.>[K\xab\x00\x00\x00\xab\x00" +
+	"\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-\x9e\x02\x00Asia/JayapuraPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17✳2\x04\x00\x002\x04\x00" +
+	"\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x9f\x02\x00Asia/JerusalemPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\xe2\\\xff\x9f\x00\x00\x00\x9f\x00\x00" +
+	"\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a\xa3\x02\x00Asia/KabulPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\x9cf>\xd7\x02\x00\x00\xd7\x02\x00\x00\x0e\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00(\xa4\x02\x00Asia/KamchatkaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x009Y\xb7\xf1\n\x01\x00\x00\n\x01\x00\x00\f\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00+\xa7\x02\x00Asia/KarachiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x1d\xc6\x1b\x85\x00\x00\x00\x85\x00\x00\x00\f\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00_\xa8\x02\x00Asia/KashgarPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8bSnT\xa1\x00\x00\x00\xa1\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x0e\xa9\x02\x00Asia/KathmanduPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8bSnT\xa1\x00\x00\x00\xa1\x00\x00\x00\r\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00۩\x02\x00Asia/KatmanduPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x83g\x95M\a\x03\x00\x00\a\x03\x00\x00\r\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\xa7\xaa\x02\x00Asia/KhandygaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9a\x1a\xdc\xca\xdc\x00\x00\x00\xdc\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00٭\x02\x00Asia/KolkataPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00L\xe0\x91y\xe5\x02\x00\x00\xe5\x02\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00߮\x02\x00Asia/KrasnoyarskPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00F7k\x1c\x00\x01\x00\x00\x00\x01\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\xf2\xb1\x02\x00Asia/Kuala_LumpurPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7f^]@\x01\x00\x00@\x01\x00\x00\f\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00!\xb3\x02\x00Asia/KuchingPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcfׇ\xe1\x85\x00\x00\x00\x85\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x8b\xb4\x02\x00Asia/KuwaitPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d?v\f\x17\x03\x00\x00\x17\x03\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x009\xb5\x02\x00Asia/MacaoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d?v\f\x17\x03\x00\x00\x17\x03\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00x" +
+	"\xb8\x02\x00Asia/MacauPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe4_P\x18\xef\x02\x00\x00\xef\x02\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7\xbb\x02\x00A" +
+	"sia/MagadanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`\xc9\xd4\\\xbe\x00\x00\x00\xbe\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00о\x02\x00Asi" +
+	"a/MakassarPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ǯ\xdf\x1c\xee\x00\x00\x00\xee\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb9\xbf\x02\x00Asia" +
+	"/ManilaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xed\x8c\xf1\x91\x85\x00\x00\x00\x85\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd0\xc0\x02\x00Asia/Mu" +
+	"scatPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03R\xda\xedU\x02\x00\x00U\x02\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00~\xc1\x02\x00Asia/Nicos" +
+	"iaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8a\x9a\x90\xf7\xd6\x02\x00\x00\xd6\x02\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xc3\x02\x00Asia/Novokuz" +
+	"netskPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)p\x1cX\xf1\x02\x00\x00\xf1\x02\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xc7\x02\x00Asia/Novo" +
+	"sibirskPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:\x11\xea\xa2\xe5\x02\x00\x00\xe5\x02\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00!\xca\x02\x00Asia/Om" +
+	"skPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&\xe9\xd1\xd8q\x02\x00\x00q\x02\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-\xcd\x02\x00Asia/OralPK\x01" +
+	"\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x88\xf6C\x84\x98\x00\x00\x00\x98\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc5\xcf\x02\x00Asia/Phnom_PenhPK" +
+	"\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S\xa5\x81e\xf7\x00\x00\x00\xf7\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8a\xd0\x02\x00Asia/PontianakPK" +
+	"\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8a\xc1\x1eB\xb7\x00\x00\x00\xb7\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xad\xd1\x02\x00Asia/PyongyangPK" +
+	"\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdav\x19z\x98\x00\x00\x00\x98\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90\xd2\x02\x00Asia/QatarPK\x01\x02\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1\xfax\x98g\x02\x00\x00g\x02\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xd3\x02\x00Asia/QostanayPK\x01\x02\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd5ΜGp\x02\x00\x00p\x02\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe2\xd5\x02\x00Asia/QyzylordaPK\x01\x02\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00ʇ{_\xbb\x00\x00\x00\xbb\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00~\xd8\x02\x00Asia/RangoonPK\x01\x02\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\xcfׇ\xe1\x85\x00\x00\x00\x85\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00c\xd9\x02\x00Asia/RiyadhPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x000I\xc7\xde\xec\x00\x00\x00\xec\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\xda\x02\x00Asia/SaigonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00)\x15II\xf3\x02\x00\x00\xf3\x02\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&\xdb\x02\x00Asia/SakhalinPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"w\rD\an\x01\x00\x00n\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00D\xde\x02\x00Asia/SamarkandPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\xc7X,Y\x9f\x01\x00\x00\x9f\x01\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xdf\x02\x00Asia/SeoulPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\xe4@\xa9" +
+	"\x89\x01\x00\x00\x89\x01\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa5\xe1\x02\x00Asia/ShanghaiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00F7k\x1c\x00" +
+	"\x01\x00\x00\x00\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y\xe3\x02\x00Asia/SingaporePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4Zߐ\xe6" +
+	"\x02\x00\x00\xe6\x02\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85\xe4\x02\x00Asia/SrednekolymskPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xee" +
+	"\xf0BB\xff\x01\x00\x00\xff\x01\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\xe7\x02\x00Asia/TaipeiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\xe27Y" +
+	"n\x01\x00\x00n\x01\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc3\xe9\x02\x00Asia/TashkentPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Ѿ\xa8\xc7u" +
+	"\x02\x00\x00u\x02\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\\\xeb\x02\x00Asia/TbilisiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c\xdb?\xec,\x03\x00" +
+	"\x00,\x03\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfb\xed\x02\x00Asia/TehranPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17✳2\x04\x00\x002\x04" +
+	"\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xf1\x02\x00Asia/Tel_AvivPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00j$\xcd\xf4\x9a\x00\x00\x00\x9a\x00\x00" +
+	"\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xad\xf5\x02\x00Asia/ThimbuPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00j$\xcd\xf4\x9a\x00\x00\x00\x9a\x00\x00\x00\f\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\xf6\x02\x00Asia/ThimphuPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xf4\xaeg\xd5\x00\x00\x00\xd5\x00\x00\x00\n\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x004\xf7\x02\x00Asia/TokyoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00[u\x99q\xf1\x02\x00\x00\xf1\x02\x00\x00\n\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x001\xf8\x02\x00Asia/TomskPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`\xc9\xd4\\\xbe\x00\x00\x00\xbe\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00J\xfb\x02\x00Asia/Ujung_PandangPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\xb9\xf4\xb6R\x02\x00\x00R\x02\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x008\xfc\x02\x00Asia/UlaanbaatarPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\xb9\xf4\xb6R\x02\x00\x00R\x02\x00\x00\x0f\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\xb8\xfe\x02\x00Asia/Ulan_BatorPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x1d\xc6\x1b\x85\x00\x00\x00\x85\x00\x00\x00\v\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x007\x01\x03\x00Asia/UrumqiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00w\x86\x8d^\x03\x03\x00\x00\x03\x03\x00\x00\r\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\xe5\x01\x03\x00Asia/Ust-NeraPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x88\xf6C\x84\x98\x00\x00\x00\x98\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x13\x05\x03\x00Asia/VientianePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d%\x05\xd8\xe6\x02\x00\x00\xe6\x02\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\xd7\x05\x03\x00Asia/VladivostokPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00O\xb0\x03\xe9\xe5\x02\x00\x00\xe5\x02\x00\x00\f\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\xeb\b\x03\x00Asia/YakutskPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ʇ{_\xbb\x00\x00\x00\xbb\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\xfa\v\x03\x00Asia/YangonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9a\xea\x18\xd4\xf8\x02\x00\x00\xf8\x02\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\xde\f\x03\x00Asia/YekaterinburgPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x95-\xad\xc4\x02\x00\x00\xc4\x02\x00\x00\f\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x06\x10\x03\x00Asia/YerevanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe8\x8dY\x80\xad\x05\x00\x00\xad\x05\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\xf4\x12\x03\x00Atlantic/AzoresPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00l&\x04\x99\x00\x04\x00\x00\x00\x04\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\xce\x18\x03\x00Atlantic/BermudaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaf|7\xb3\xde\x01\x00\x00\xde\x01\x00\x00\x0f\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\xfc\x1c\x03\x00Atlantic/CanaryPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\u0097N\xad\xaf\x00\x00\x00\xaf\x00\x00\x00\x13\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\a\x1f\x03\x00Atlantic/Cape_VerdePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7\x0e\xbdm\xb9\x01\x00\x00\xb9\x01\x00\x00\x0f" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe7\x1f\x03\x00Atlantic/FaeroePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7\x0e\xbdm\xb9\x01\x00\x00\xb9\x01\x00\x00" +
+	"\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcd!\x03\x00Atlantic/FaroePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17S\x91\xb3\xc1\x02\x00\x00\xc1\x02\x00\x00" +
+	"\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2#\x03\x00Atlantic/Jan_MayenPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x001)7\xad\xad\x05\x00\x00" +
+	"\xad\x05\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa3&\x03\x00Atlantic/MadeiraPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00" +
+	"\x00\x00\x82\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00~,\x03\x00Atlantic/ReykjavikPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f-" +
+	"\xadׄ\x00\x00\x00\x84\x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000-\x03\x00Atlantic/South_GeorgiaPK\x01\x02\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe8-\x03\x00Atlantic/St_HelenaPK\x01\x02\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe7\xcf^\xb0\x15\x03\x00\x00\x15\x03\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9a.\x03\x00Atlantic/StanleyPK\x01\x02" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X\xb9\x9ap\x88\x03\x00\x00\x88\x03\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdd1\x03\x00Australia/ACTPK\x01\x02\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8ff~ՙ\x03\x00\x00\x99\x03\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x905\x03\x00Australia/AdelaideP" +
+	"K\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\xba\xde\xd3!\x01\x00\x00!\x01\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y9\x03\x00Australia/Brisb" +
+	"anePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbd\xca#\x7f\xad\x03\x00\x00\xad\x03\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa:\x03\x00Australia/B" +
+	"roken_HillPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X\xb9\x9ap\x88\x03\x00\x00\x88\x03\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8a>\x03\x00Aust" +
+	"ralia/CanberraPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\xf2\xe6Z\xeb\x03\x00\x00\xeb\x03\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00BB\x03\x00" +
+	"Australia/CurriePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8R\x1a\x1b\xea\x00\x00\x00\xea\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00[F" +
+	"\x03\x00Australia/DarwinPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa2ܺ\xca:\x01\x00\x00:\x01\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"sG\x03\x00Australia/EuclaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\xf2\xe6Z\xeb\x03\x00\x00\xeb\x03\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\xdaH\x03\x00Australia/HobartPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o3\xdaR\xb4\x02\x00\x00\xb4\x02\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\xf3L\x03\x00Australia/LHIPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\x95\xbd\x12E\x01\x00\x00E\x01\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\xd2O\x03\x00Australia/LindemanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o3\xdaR\xb4\x02\x00\x00\xb4\x02\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00GQ\x03\x00Australia/Lord_HowePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\xe1\xc1\xa9\x88\x03\x00\x00\x88\x03\x00\x00\x13\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,T\x03\x00Australia/MelbournePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X\xb9\x9ap\x88\x03\x00\x00\x88\x03" +
+	"\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5W\x03\x00Australia/NSWPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8R\x1a\x1b\xea\x00\x00\x00\xea\x00\x00" +
+	"\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x98[\x03\x00Australia/NorthPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ϻ\xca\x1a2\x01\x00\x002\x01" +
+	"\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaf\\\x03\x00Australia/PerthPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\xba\xde\xd3!\x01\x00\x00!" +
+	"\x01\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e^\x03\x00Australia/QueenslandPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8ff~" +
+	"ՙ\x03\x00\x00\x99\x03\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a_\x03\x00Australia/SouthPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X\xb9" +
+	"\x9ap\x88\x03\x00\x00\x88\x03\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'c\x03\x00Australia/SydneyPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"E\xf2\xe6Z\xeb\x03\x00\x00\xeb\x03\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xddf\x03\x00Australia/TasmaniaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x9b\xe1\xc1\xa9\x88\x03\x00\x00\x88\x03\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8j\x03\x00Australia/VictoriaPK\x01\x02\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00ϻ\xca\x1a2\x01\x00\x002\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0n\x03\x00Australia/WestPK\x01\x02\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\xbd\xca#\x7f\xad\x03\x00\x00\xad\x03\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0ep\x03\x00Australia/YancowinnaPK" +
+	"\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\xf5K\x89\xa2\x01\x00\x00\xa2\x01\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xeds\x03\x00Brazil/AcrePK\x01\x02\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7-2f\xe4\x01\x00\x00\xe4\x01\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb8u\x03\x00Brazil/DeNoronhaPK\x01" +
+	"\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9d?\xdfڸ\x03\x00\x00\xb8\x03\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcaw\x03\x00Brazil/EastPK\x01\x02\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a\xcb'\xe9\x9c\x01\x00\x00\x9c\x01\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab{\x03\x00Brazil/WestPK\x01\x02\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\xe6\x9aM\xbem\x02\x00\x00m\x02\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p}\x03\x00CETPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\x8b\x99\x1e" +
+	"\xb7\x03\x00\x00\xb7\x03\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe\x7f\x03\x00CST6CDTPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00):\x17-\x88\x06\x00\x00\x88\x06\x00" +
+	"\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ڃ\x03\x00Canada/AtlanticPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?_p\x99\x0e\x05\x00\x00\x0e\x05" +
+	"\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8f\x8a\x03\x00Canada/CentralPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ӿ\x92\xbc\xb5\x06\x00\x00\xb5\x06" +
+	"\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ɏ\x03\x00Canada/EasternPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{\a\a\xdc\xca\x03\x00\x00\xca\x03" +
+	"\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa\x96\x03\x00Canada/MountainPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00~\xb2\x0e\x19V\a\x00\x00V" +
+	"\a\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1\x9a\x03\x00Canada/NewfoundlandPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00U9#\xbe" +
+	"2\x05\x00\x002\x05\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00(\xa2\x03\x00Canada/PacificPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\u0096dK" +
+	"~\x02\x00\x00~\x02\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x86\xa7\x03\x00Canada/SaskatchewanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\xbf\x1d\xee\x91\x05\x04\x00\x00\x05\x04\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005\xaa\x03\x00Canada/YukonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]" +
+	"\"_WJ\x05\x00\x00J\x05\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\xae\x03\x00Chile/ContinentalPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00?X'\x8e\x96\x04\x00\x00\x96\x04\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ݳ\x03\x00Chile/EasterIslandPK\x01\x02\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\a\x1c\x9e\x9a]\x04\x00\x00]\x04\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa3\xb8\x03\x00CubaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`l\x8d~" +
+	"\xf1\x01\x00\x00\xf1\x01\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\"\xbd\x03\x00EETPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00tX\xbe\xe4o\x00\x00\x00o\x00\x00\x00\x03\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x004\xbf\x03\x00ESTPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe7/\xebT\xb7\x03\x00\x00\xb7\x03\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"Ŀ\x03\x00EST5EDTPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12tnj\xfc\x04\x00\x00\xfc\x04\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa0\xc3\x03\x00Egy" +
+	"ptPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1\xd6jL\xd8\x05\x00\x00\xd8\x05\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbf\xc8\x03\x00EirePK\x01\x02\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb9\xce\x03\x00Etc/GMTPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00M\xcf\x03\x00Etc/GMT+0PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005\xb8\xe8\x86" +
+	"q\x00\x00\x00q\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe3\xcf\x03\x00Etc/GMT+1PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8e\x1569r\x00\x00\x00r" +
+	"\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{\xd0\x03\x00Etc/GMT+10PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)\xb9\xbe\x9dr\x00\x00\x00r\x00\x00\x00\n" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15\xd1\x03\x00Etc/GMT+11PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5\xf38cr\x00\x00\x00r\x00\x00\x00\n\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaf\xd1\x03\x00Etc/GMT+12PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa9{\xa2qq\x00\x00\x00q\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00I\xd2\x03\x00Etc/GMT+2PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00e\xcb\xe9Qq\x00\x00\x00q\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\xe1\xd2\x03\x00Etc/GMT+3PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd0\xfaFDq\x00\x00\x00q\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00y\xd3\x03\x00E" +
+	"tc/GMT+4PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd4X\x9b\xf3q\x00\x00\x00q\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\xd4\x03\x00Etc/GM" +
+	"T+5PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00H\x9b\xd1\x04q\x00\x00\x00q\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa9\xd4\x03\x00Etc/GMT+6PK" +
+	"\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84+\x9a$q\x00\x00\x00q\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00A\xd5\x03\x00Etc/GMT+7PK\x01\x02\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\"\xf8\x8f/q\x00\x00\x00q\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd9\xd5\x03\x00Etc/GMT+8PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x84\x19\xb3\tq\x00\x00\x00q\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xd6\x03\x00Etc/GMT+9PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P" +
+	"\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\xd7\x03\x00Etc/GMT-0PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf7\x1ac\xc3r\x00" +
+	"\x00\x00r\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f\xd7\x03\x00Etc/GMT-1PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd9|\xbd7s\x00\x00\x00s\x00\x00" +
+	"\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x008\xd8\x03\x00Etc/GMT-10PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\xab\xd1Is\x00\x00\x00s\x00\x00\x00\n\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd3\xd8\x03\x00Etc/GMT-11PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf7\x19s\x81s\x00\x00\x00s\x00\x00\x00\n\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00n\xd9\x03\x00Etc/GMT-12PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90`N\xe8s\x00\x00\x00s\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\t\xda\x03\x00Etc/GMT-13PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,{\xdc;s\x00\x00\x00s\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4" +
+	"\xda\x03\x00Etc/GMT-14PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\x19y\x04r\x00\x00\x00r\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\xdb\x03\x00E" +
+	"tc/GMT-2PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9c\xfcm\x99r\x00\x00\x00r\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd8\xdb\x03\x00Etc/GM" +
+	"T-3PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\x19<Qr\x00\x00\x00r\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xdc\x03\x00Etc/GMT-4PK" +
+	"\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00!\xd6~wr\x00\x00\x00r\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\xdd\x03\x00Etc/GMT-5PK\x01\x02\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00j\xd5d\xb0r\x00\x00\x00r\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa3\xdd\x03\x00Etc/GMT-6PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00J0p-r\x00\x00\x00r\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\xde\x03\x00Etc/GMT-7PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc5" +
+	"\x18\xb6\xfbr\x00\x00\x00r\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd5\xde\x03\x00Etc/GMT-8PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfc\x19@\xb9r\x00" +
+	"\x00\x00r\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\xdf\x03\x00Etc/GMT-9PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00" +
+	"\x00\b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\xe0\x03\x00Etc/GMT0PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\r\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9c\xe0\x03\x00Etc/GreenwichPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\a\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x006\xe1\x03\x00Etc/UCTPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\xca\xe1\x03\x00Etc/UTCPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00^\xe2\x03\x00Et" +
+	"c/UniversalPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8\xe2\x03\x00Etc" +
+	"/ZuluPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o\xbc\x831O\x04\x00\x00O\x04\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8d\xe3\x03\x00Europe/Am" +
+	"sterdamPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ߜvυ\x01\x00\x00\x85\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\xe8\x03\x00Europe/" +
+	"AndorraPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]i\x11u\xd6\x02\x00\x00\xd6\x02\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbb\xe9\x03\x00Europe/" +
+	"AstrakhanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcb*j\x8f\xaa\x02\x00\x00\xaa\x02\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbf\xec\x03\x00Europ" +
+	"e/AthensPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x94\xef\x03\x00Europe" +
+	"/BelfastPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xf5\x03\x00Europe" +
+	"/BelgradePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17S\x91\xb3\xc1\x02\x00\x00\xc1\x02\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\xf8\x03\x00Europ" +
+	"e/BerlinPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Io\x11{\xd3\x02\x00\x00\xd3\x02\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\xfa\x03\x00Europe" +
+	"/BratislavaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o\xbc\x831O\x04\x00\x00O\x04\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8\xfd\x03\x00Eur" +
+	"ope/BrusselsPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90\xa9\xf5ϕ\x02\x00\x00\x95\x02\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\x02\x04\x00Eu" +
+	"rope/BucharestPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe6Kf\xab\xfe\x02\x00\x00\xfe\x02\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x007\x05\x04\x00" +
+	"Europe/BudapestPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Dd#\xc4\xf1\x01\x00\x00\xf1\x01\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b\b\x04" +
+	"\x00Europe/BusingenPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00I\xb8\xbc\xd3\xf3\x02\x00\x00\xf3\x02\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\n" +
+	"\x04\x00Europe/ChisinauPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17S\x91\xb3\xc1\x02\x00\x00\xc1\x02\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa0" +
+	"\r\x04\x00Europe/CopenhagenPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1\xd6jL\xd8\x05\x00\x00\xd8\x05\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x90\x10\x04\x00Europe/DublinPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00==\xa4\x16\xc4\x04\x00\x00\xc4\x04\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x93\x16\x04\x00Europe/GibraltarPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x85\x1b\x04\x00Europe/GuernseyPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5\xc8X\xa7\xe1\x01\x00\x00\xe1\x01\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\xf1!\x04\x00Europe/HelsinkiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\xff#\x04\x00Europe/Isle_of_ManPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\aW\x10Ѱ\x04\x00\x00\xb0\x04\x00\x00\x0f\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00n*\x04\x00Europe/IstanbulPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\r\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00K/\x04\x00Europe/JerseyPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00O+j\x94\x88\x03\x00\x00\x88\x03\x00\x00\x12\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb55\x04\x00Europe/KaliningradPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00iS\x18D.\x02\x00\x00.\x02\x00\x00\v" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00m9\x04\x00Europe/KievPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\xfe\x83\xe5\xcd\x02\x00\x00\xcd\x02\x00\x00\f\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc4;\x04\x00Europe/KirovPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00iS\x18D.\x02\x00\x00.\x02\x00\x00\v\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\xbb>\x04\x00Europe/KyivPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&S\x03\t\xae\x05\x00\x00\xae\x05\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x12A\x04\x00Europe/LisbonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\xebF\x04\x00Europe/LjubljanaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\r\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\xf7H\x04\x00Europe/LondonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o\xbc\x831O\x04\x00\x00O\x04\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00aO\x04\x00Europe/LuxembourgPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Zk#V\x81\x03\x00\x00\x81\x03\x00\x00\r\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\xdfS\x04\x00Europe/MadridPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\xa5J[\xa0\x03\x00\x00\xa0\x03\x00\x00\f\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x8bW\x04\x00Europe/MaltaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5\xc8X\xa7\xe1\x01\x00\x00\xe1\x01\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00U[\x04\x00Europe/MariehamnPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00WI\xc3\x7f(\x03\x00\x00(\x03\x00\x00\f\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00d]\x04\x00Europe/MinskPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7\xf5\x94\xdaQ\x04\x00\x00Q\x04\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\xb6`\x04\x00Europe/MonacoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1\xc1\xeb\x05\x8c\x03\x00\x00\x8c\x03\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x002e\x04\x00Europe/MoscowPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03R\xda\xedU\x02\x00\x00U\x02\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\xe9h\x04\x00Europe/NicosiaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17S\x91\xb3\xc1\x02\x00\x00\xc1\x02\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00jk\x04\x00Europe/OsloPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7\xf5\x94\xdaQ\x04\x00\x00Q\x04\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"Tn\x04\x00Europe/ParisPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcfr" +
+	"\x04\x00Europe/PodgoricaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Io\x11{\xd3\x02\x00\x00\xd3\x02\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\xdbt\x04\x00Europe/PraguePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00gp\xc0\xa7\xb6\x02\x00\x00\xb6\x02\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd9" +
+	"w\x04\x00Europe/RigaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\xb4\x9e\xe7\xb3\x03\x00\x00\xb3\x03\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb8z\x04\x00" +
+	"Europe/RomePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\x7fpp\xdc\x02\x00\x00\xdc\x02\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x94~\x04\x00Eur" +
+	"ope/SamaraPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\xb4\x9e\xe7\xb3\x03\x00\x00\xb3\x03\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\x81\x04\x00Euro" +
+	"pe/San_MarinoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00}\x85\x04\x00E" +
+	"urope/SarajevoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b8\xfel\xd6\x02\x00\x00\xd6\x02\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x88\x87\x04\x00" +
+	"Europe/SaratovPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00}\xb4N\xb8a\x03\x00\x00a\x03\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8a\x8a\x04\x00" +
+	"Europe/SimferopolPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1a" +
+	"\x8e\x04\x00Europe/SkopjePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c\xc8\x15\xd0P\x02\x00\x00P\x02\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00#\x90" +
+	"\x04\x00Europe/SofiaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17S\x91\xb3\xc1\x02\x00\x00\xc1\x02\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9d\x92\x04\x00" +
+	"Europe/StockholmPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\x16\x9b?\xa3\x02\x00\x00\xa3\x02\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c\x95" +
+	"\x04\x00Europe/TallinnPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xea\xc48\xde\\\x02\x00\x00\\\x02\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00[\x98" +
+	"\x04\x00Europe/TiranePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00I\xb8\xbc\xd3\xf3\x02\x00\x00\xf3\x02\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe2\x9a\x04" +
+	"\x00Europe/TiraspolPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00u\xb0\xcd\xfc\xf8\x02\x00\x00\xf8\x02\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x9e" +
+	"\x04\x00Europe/UlyanovskPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00iS\x18D.\x02\x00\x00.\x02\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"(\xa1\x04\x00Europe/UzhgorodPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Dd#\xc4\xf1\x01\x00\x00\xf1\x01\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x83\xa3\x04\x00Europe/VaduzPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\xb4\x9e\xe7\xb3\x03\x00\x00\xb3\x03\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9e" +
+	"\xa5\x04\x00Europe/VaticanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Z\x05wג\x02\x00\x00\x92\x02\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00}" +
+	"\xa9\x04\x00Europe/ViennaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xccb\xf72\xa4\x02\x00\x00\xa4\x02\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:\xac" +
+	"\x04\x00Europe/VilniusPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Va\x92\xd3\xdf\x02\x00\x00\xdf\x02\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\xaf" +
+	"\x04\x00Europe/VolgogradPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\xfe垛\x03\x00\x00\x9b\x03\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x17\xb2\x04\x00Europe/WarsawPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdd" +
+	"\xb5\x04\x00Europe/ZagrebPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00iS\x18D.\x02\x00\x00.\x02\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe6\xb7" +
+	"\x04\x00Europe/ZaporozhyePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Dd#\xc4\xf1\x01\x00\x00\xf1\x01\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00C\xba\x04\x00Europe/ZurichPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x80c$q\x00\x00\x00q\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"_\xbc\x04\x00FactoryPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf5\xbc\x04\x00GBP" +
+	"K\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00T\xc3\x04\x00GB-EirePK\x01\x02\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb8\xc9\x04\x00GMTPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa" +
+	"\x03o\x00\x00\x00o\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00H\xca\x04\x00GMT+0PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00" +
+	"\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xda\xca\x04\x00GMT-0PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00l\xcb\x04\x00GMT0PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xcb\x04\x00G" +
+	"reenwichPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\xf7\xfawp\x00\x00\x00p\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x93\xcc\x04\x00HSTPK\x01" +
+	"\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\t\xfa-\a\x03\x00\x00\a\x03\x00\x00\b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$\xcd\x04\x00HongkongPK\x01\x02\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Q\xd0\x04\x00IcelandPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8\xd0\x04\x00Indian/AntananarivoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00x\xb0W\x14\x98\x00\x00\x00\x98\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe8\xd1\x04\x00Indian/ChagosPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x88\xf6C\x84\x98\x00\x00\x00\x98\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\xd2\x04\x00Indian/ChristmasPK\x01\x02\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00ʇ{_\xbb\x00\x00\x00\xbb\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xd3\x04\x00Indian/CocosPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\xd4\x04\x00Indian/ComoroPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\xb9\xb2Z\xac\x98\x00\x00\x00\x98\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\xd5\x04\x00Indian/KerguelenPK\x01\x02\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\xed\x8c\xf1\x91\x85\x00\x00\x00\x85\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\xd6\x04\x00Indian/MahePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\xb9\xb2Z\xac\x98\x00\x00\x00\x98\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\xd6\x04\x00Indian/MaldivesPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x96\xed=\x98\xb3\x00\x00\x00\xb3\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00y\xd7\x04\x00Indian/MauritiusPK\x01\x02\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Z\xd8\x04\x00Indian/MayottePK\x01\x02\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\xed\x8c\xf1\x91\x85\x00\x00\x00\x85\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\xd9\x04\x00Indian/ReunionPK\x01\x02\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x8c\xdb?\xec,\x03\x00\x00,\x03\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\xd9\x04\x00IranPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17✳2" +
+	"\x04\x00\x002\x04\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00D\xdd\x04\x00IsraelPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00%J\xd5\xebS\x01\x00\x00S\x01\x00\x00\a" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9a\xe1\x04\x00JamaicaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xf4\xaeg\xd5\x00\x00\x00\xd5\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x12\xe3\x04\x00JapanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\xe8]*\xdb\x00\x00\x00\xdb\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\xe4\x04" +
+	"\x00KwajaleinPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00_\x7f2[\xaf\x01\x00\x00\xaf\x01\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\f\xe5\x04\x00Liby" +
+	"aPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe\x9d\x1b\xc9m\x02\x00\x00m\x02\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xe6\x04\x00METPK\x01\x02\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\xf5\x8d\x99\x92o\x00\x00\x00o\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00l\xe9\x04\x00MSTPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe6h\xcac\xb7" +
+	"\x03\x00\x00\xb7\x03\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfc\xe9\x04\x00MST7MDTPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb9B$\x90\x01\x04\x00\x00\x01\x04\x00\x00" +
+	"\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd8\xed\x04\x00Mexico/BajaNortePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\xad=\x98\xce\x02\x00\x00\xce\x02" +
+	"\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\xf2\x04\x00Mexico/BajaSurPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd5\b\x89\x8c\x05\x03\x00\x00\x05\x03" +
+	"\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xf5\x04\x00Mexico/GeneralPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b\xb2\xaf\xf7\x13\x04\x00\x00\x13\x04" +
+	"\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x002\xf8\x04\x00NZPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xc5FF(\x03\x00\x00(\x03\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00e\xfc\x04\x00NZ-CHATPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\x80\x94@\x12\x04\x00\x00\x12\x04\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\xff\x04" +
+	"\x00NavajoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe8\x03\x05\x00PRCPK\x01\x02" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ŭV\xad\xb7\x03\x00\x00\xb7\x03\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x92\x05\x05\x00PST8PDTPK\x01\x02\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\xa8A\x15\xfe\x97\x01\x00\x00\x97\x01\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\t\x05\x00Pacific/ApiaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00b\xb2\xaf\xf7\x13\x04\x00\x00\x13\x04\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00/\v\x05\x00Pacific/AucklandPK\x01\x02\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x9a\xf2:F\xc9\x00\x00\x00\xc9\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\x0f\x05\x00Pacific/BougainvillePK\x01\x02\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xc5FF(\x03\x00\x00(\x03\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\x10\x05\x00Pacific/ChathamPK\x01\x02" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\x04\x19y\x9a\x00\x00\x00\x9a\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0\x13\x05\x00Pacific/ChuukPK\x01\x02\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?X'\x8e\x96\x04\x00\x00\x96\x04\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85\x14\x05\x00Pacific/EasterPK\x01\x02\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9e\x7f\xab\x95V\x01\x00\x00V\x01\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00G\x19\x05\x00Pacific/EfatePK\x01\x02\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xec =\x89\xac\x00\x00\x00\xac\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8\x1a\x05\x00Pacific/EnderburyPK\x01" +
+	"\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8a|\xdcU\x99\x00\x00\x00\x99\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa3\x1b\x05\x00Pacific/FakaofoPK" +
+	"\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfd_yl\x8c\x01\x00\x00\x8c\x01\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00i\x1c\x05\x00Pacific/FijiPK\x01\x02" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x006\xb7S{\x86\x00\x00\x00\x86\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x1e\x05\x00Pacific/FunafutiPK" +
+	"\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\xe3w\n\xaf\x00\x00\x00\xaf\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd3\x1e\x05\x00Pacific/Galapago" +
+	"sPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc23\xa0\xbc\x84\x00\x00\x00\x84\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb1\x1f\x05\x00Pacific/Gambi" +
+	"erPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y\xd2K|\x86\x00\x00\x00\x86\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b \x05\x00Pacific/Guad" +
+	"alcanalPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00FI\xfe\x14^\x01\x00\x00^\x01\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x19!\x05\x00Pacific" +
+	"/GuamPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xeaK\x85v\xdd\x00\x00\x00\xdd\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1\"\x05\x00Pacific/H" +
+	"onoluluPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xeaK\x85v\xdd\x00\x00\x00\xdd\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac#\x05\x00Pacific" +
+	"/JohnstonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xec =\x89\xac\x00\x00\x00\xac\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7$\x05\x00Pacif" +
+	"ic/KantonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8=ku\xae\x00\x00\x00\xae\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8f%\x05\x00Pacif" +
+	"ic/KiritimatiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x97n7\x1a\xf2\x00\x00\x00\xf2\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00m&\x05\x00P" +
+	"acific/KosraePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\xe8]*\xdb\x00\x00\x00\xdb\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8b'\x05\x00P" +
+	"acific/KwajaleinPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x006\xb7S{\x86\x00\x00\x00\x86\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95(" +
+	"\x05\x00Pacific/MajuroPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00D6\x83\xa1\x8b\x00\x00\x00\x8b\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00G)" +
+	"\x05\x00Pacific/MarquesasPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\xca{e\x92\x00\x00\x00\x92\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x01*\x05\x00Pacific/MidwayPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe2;Z\xf7\xb7\x00\x00\x00\xb7\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\xbf*\x05\x00Pacific/NauruPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x91\xd60\f\x9a\x00\x00\x00\x9a\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\xa1+\x05\x00Pacific/NiuePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y5\x1a6\xf7\x00\x00\x00\xf7\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00e," +
+	"\x05\x00Pacific/NorfolkPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7\xef\x97\xc6\xc6\x00\x00\x00\xc6\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x89" +
+	"-\x05\x00Pacific/NoumeaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\xca{e\x92\x00\x00\x00\x92\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{" +
+	".\x05\x00Pacific/Pago_PagoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\xf8vܔ\x00\x00\x00\x94\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00</\x05\x00Pacific/PalauPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfa\x0fA\x05\x99\x00\x00\x00\x99\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\xfb/\x05\x00Pacific/PitcairnPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y\xd2K|\x86\x00\x00\x00\x86\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\xc20\x05\x00Pacific/PohnpeiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y\xd2K|\x86\x00\x00\x00\x86\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00u1\x05\x00Pacific/PonapePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\x04\x19y\x9a\x00\x00\x00\x9a\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00'2\x05\x00Pacific/Port_MoresbyPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\xe3\xa3S\x96\x01\x00\x00\x96\x01\x00\x00\x11\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf32\x05\x00Pacific/RarotongaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00FI\xfe\x14^\x01\x00\x00^\x01\x00\x00\x0e" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb84\x05\x00Pacific/SaipanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\xca{e\x92\x00\x00\x00\x92\x00\x00\x00\r" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B6\x05\x00Pacific/SamoaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xea\xc1\xdaυ\x00\x00\x00\x85\x00\x00\x00\x0e\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff6\x05\x00Pacific/TahitiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x006\xb7S{\x86\x00\x00\x00\x86\x00\x00\x00\x0e\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb07\x05\x00Pacific/TarawaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x97F\x91\xb3\xed\x00\x00\x00\xed\x00\x00\x00\x11\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b8\x05\x00Pacific/TongatapuPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\x04\x19y\x9a\x00\x00\x00\x9a\x00\x00" +
+	"\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00~9\x05\x00Pacific/TrukPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x006\xb7S{\x86\x00\x00\x00\x86\x00\x00\x00\f" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B:\x05\x00Pacific/WakePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x006\xb7S{\x86\x00\x00\x00\x86\x00\x00\x00\x0e\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf2:\x05\x00Pacific/WallisPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\x04\x19y\x9a\x00\x00\x00\x9a\x00\x00\x00\v\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4;\x05\x00Pacific/YapPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\xfe垛\x03\x00\x00\x9b\x03\x00\x00\x06\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00g<\x05\x00PolandPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&S\x03\t\xae\x05\x00\x00\xae\x05\x00\x00\b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"&@\x05\x00PortugalPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xee\xf0BB\xff\x01\x00\x00\xff\x01\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfaE\x05\x00RO" +
+	"CPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7X,Y\x9f\x01\x00\x00\x9f\x01\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1aH\x05\x00ROKPK\x01\x02\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00F7k\x1c\x00\x01\x00\x00\x00\x01\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdaI\x05\x00SingaporePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\aW\x10Ѱ\x04\x00\x00\xb0\x04\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01K\x05\x00TurkeyPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00" +
+	"\x00o\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd5O\x05\x00UCTPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005\x11Q\x06\xd1\x03\x00\x00\xd1\x03\x00\x00\t\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00eP\x05\x00US/AlaskaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xae,\xa44\xc9\x03\x00\x00\xc9\x03\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00]T\x05\x00US/AleutianPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ø\xab\x9b\xf0\x00\x00\x00\xf0\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"OX\x05\x00US/ArizonaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9bܩ=\xda\x06\x00\x00\xda\x06\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00gY\x05\x00" +
+	"US/CentralPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\xb6{\xc9\x13\x02\x00\x00\x13\x02\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00i`\x05\x00US/E" +
+	"ast-IndianaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\x9aG\xc8\xd0\x06\x00\x00\xd0\x06\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa9b\x05\x00US/" +
+	"EasternPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xeaK\x85v\xdd\x00\x00\x00\xdd\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1i\x05\x00US/Hawa" +
+	"iiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$ \x873\xf8\x03\x00\x00\xf8\x03\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa5j\x05\x00US/Indiana-S" +
+	"tarkePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x14\xe7\x03\x83\x03\x00\x00\x83\x03\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xccn\x05\x00US/Michig" +
+	"anPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\x80\x94@\x12\x04\x00\x00\x12\x04\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00xr\x05\x00US/MountainP" +
+	"K\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\"\x12\xfe\x0e\x05\x00\x00\x0e\x05\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb3v\x05\x00US/PacificPK\x01\x02\x00" +
+	"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\xca{e\x92\x00\x00\x00\x92\x00\x00\x00\b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe9{\x05\x00US/SamoaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1|\x05\x00UTCPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00" +
+	"\x00\x00o\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x001}\x05\x00UniversalPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1\xc1\xeb\x05\x8c\x03\x00\x00\x8c\x03\x00" +
+	"\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7}\x05\x00W-SUPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x002\x91B\xc0\xee\x01\x00\x00\xee\x01\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00" +
+	"\x00\x00\x00\x00\x00u\x81\x05\x00WETPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84\x83\x05\x00Zu" +
+	"luPK\x05\x06\x00\x00\x00\x00U\x02U\x02m\x8c\x00\x00\x15\x84\x05\x00\x00\x00"
diff --git a/src/time/zoneinfo.go b/src/time/zoneinfo.go
index b331358..dd3b4ed 100644
--- a/src/time/zoneinfo.go
+++ b/src/time/zoneinfo.go
@@ -100,9 +100,30 @@
 	return l.get().name
 }
 
+var unnamedFixedZones []*Location
+var unnamedFixedZonesOnce sync.Once
+
 // FixedZone returns a Location that always uses
 // the given zone name and offset (seconds east of UTC).
 func FixedZone(name string, offset int) *Location {
+	// Most calls to FixedZone have an unnamed zone with an offset by the hour.
+	// Optimize for that case by returning the same *Location for a given hour.
+	const hoursBeforeUTC = 12
+	const hoursAfterUTC = 14
+	hour := offset / 60 / 60
+	if name == "" && -hoursBeforeUTC <= hour && hour <= +hoursAfterUTC && hour*60*60 == offset {
+		unnamedFixedZonesOnce.Do(func() {
+			unnamedFixedZones = make([]*Location, hoursBeforeUTC+1+hoursAfterUTC)
+			for hr := -hoursBeforeUTC; hr <= +hoursAfterUTC; hr++ {
+				unnamedFixedZones[hr+hoursBeforeUTC] = fixedZone("", hr*60*60)
+			}
+		})
+		return unnamedFixedZones[hour+hoursBeforeUTC]
+	}
+	return fixedZone(name, offset)
+}
+
+func fixedZone(name string, offset int) *Location {
 	l := &Location{
 		name:       name,
 		zone:       []zone{{name, offset, false}},
@@ -634,10 +655,10 @@
 // LoadLocation looks for the IANA Time Zone database in the following
 // locations in order:
 //
-// - the directory or uncompressed zip file named by the ZONEINFO environment variable
-// - on a Unix system, the system standard installation location
-// - $GOROOT/lib/time/zoneinfo.zip
-// - the time/tzdata package, if it was imported
+//   - the directory or uncompressed zip file named by the ZONEINFO environment variable
+//   - on a Unix system, the system standard installation location
+//   - $GOROOT/lib/time/zoneinfo.zip
+//   - the time/tzdata package, if it was imported
 func LoadLocation(name string) (*Location, error) {
 	if name == "" || name == "UTC" {
 		return UTC, nil
diff --git a/src/time/zoneinfo_abbrs_windows.go b/src/time/zoneinfo_abbrs_windows.go
index 3294d0d..139bda1 100644
--- a/src/time/zoneinfo_abbrs_windows.go
+++ b/src/time/zoneinfo_abbrs_windows.go
@@ -16,10 +16,11 @@
 	"Egypt Standard Time":             {"EET", "EET"},     // Africa/Cairo
 	"Morocco Standard Time":           {"+00", "+01"},     // Africa/Casablanca
 	"South Africa Standard Time":      {"SAST", "SAST"},   // Africa/Johannesburg
+	"South Sudan Standard Time":       {"CAT", "CAT"},     // Africa/Juba
 	"Sudan Standard Time":             {"CAT", "CAT"},     // Africa/Khartoum
 	"W. Central Africa Standard Time": {"WAT", "WAT"},     // Africa/Lagos
 	"E. Africa Standard Time":         {"EAT", "EAT"},     // Africa/Nairobi
-	"Sao Tome Standard Time":          {"GMT", "WAT"},     // Africa/Sao_Tome
+	"Sao Tome Standard Time":          {"GMT", "GMT"},     // Africa/Sao_Tome
 	"Libya Standard Time":             {"EET", "EET"},     // Africa/Tripoli
 	"Namibia Standard Time":           {"CAT", "CAT"},     // Africa/Windhoek
 	"Aleutian Standard Time":          {"HST", "HDT"},     // America/Adak
@@ -33,8 +34,8 @@
 	"Venezuela Standard Time":         {"-04", "-04"},     // America/Caracas
 	"SA Eastern Standard Time":        {"-03", "-03"},     // America/Cayenne
 	"Central Standard Time":           {"CST", "CDT"},     // America/Chicago
-	"Mountain Standard Time (Mexico)": {"MST", "MDT"},     // America/Chihuahua
-	"Central Brazilian Standard Time": {"-04", "-03"},     // America/Cuiaba
+	"Mountain Standard Time (Mexico)": {"CST", "CST"},     // America/Chihuahua
+	"Central Brazilian Standard Time": {"-04", "-04"},     // America/Cuiaba
 	"Mountain Standard Time":          {"MST", "MDT"},     // America/Denver
 	"Greenland Standard Time":         {"-03", "-02"},     // America/Godthab
 	"Turks And Caicos Standard Time":  {"EST", "EDT"},     // America/Grand_Turk
@@ -44,7 +45,7 @@
 	"US Eastern Standard Time":        {"EST", "EDT"},     // America/Indianapolis
 	"SA Western Standard Time":        {"-04", "-04"},     // America/La_Paz
 	"Pacific Standard Time":           {"PST", "PDT"},     // America/Los_Angeles
-	"Central Standard Time (Mexico)":  {"CST", "CDT"},     // America/Mexico_City
+	"Central Standard Time (Mexico)":  {"CST", "CST"},     // America/Mexico_City
 	"Saint Pierre Standard Time":      {"-03", "-02"},     // America/Miquelon
 	"Montevideo Standard Time":        {"-03", "-03"},     // America/Montevideo
 	"Eastern Standard Time":           {"EST", "EDT"},     // America/New_York
@@ -53,11 +54,12 @@
 	"Magallanes Standard Time":        {"-03", "-03"},     // America/Punta_Arenas
 	"Canada Central Standard Time":    {"CST", "CST"},     // America/Regina
 	"Pacific SA Standard Time":        {"-04", "-03"},     // America/Santiago
-	"E. South America Standard Time":  {"-03", "-02"},     // America/Sao_Paulo
+	"E. South America Standard Time":  {"-03", "-03"},     // America/Sao_Paulo
 	"Newfoundland Standard Time":      {"NST", "NDT"},     // America/St_Johns
 	"Pacific Standard Time (Mexico)":  {"PST", "PDT"},     // America/Tijuana
+	"Yukon Standard Time":             {"MST", "MST"},     // America/Whitehorse
 	"Central Asia Standard Time":      {"+06", "+06"},     // Asia/Almaty
-	"Jordan Standard Time":            {"EET", "EEST"},    // Asia/Amman
+	"Jordan Standard Time":            {"+03", "+03"},     // Asia/Amman
 	"Arabic Standard Time":            {"+03", "+03"},     // Asia/Baghdad
 	"Azerbaijan Standard Time":        {"+04", "+04"},     // Asia/Baku
 	"SE Asia Standard Time":           {"+07", "+07"},     // Asia/Bangkok
@@ -66,7 +68,7 @@
 	"India Standard Time":             {"IST", "IST"},     // Asia/Calcutta
 	"Transbaikal Standard Time":       {"+09", "+09"},     // Asia/Chita
 	"Sri Lanka Standard Time":         {"+0530", "+0530"}, // Asia/Colombo
-	"Syria Standard Time":             {"EET", "EEST"},    // Asia/Damascus
+	"Syria Standard Time":             {"+03", "+03"},     // Asia/Damascus
 	"Bangladesh Standard Time":        {"+06", "+06"},     // Asia/Dhaka
 	"Arabian Standard Time":           {"+04", "+04"},     // Asia/Dubai
 	"West Bank Standard Time":         {"EET", "EEST"},    // Asia/Hebron
@@ -82,7 +84,7 @@
 	"N. Central Asia Standard Time":   {"+07", "+07"},     // Asia/Novosibirsk
 	"Omsk Standard Time":              {"+06", "+06"},     // Asia/Omsk
 	"North Korea Standard Time":       {"KST", "KST"},     // Asia/Pyongyang
-	"Qyzylorda Standard Time":         {"+05", "+06"},     // Asia/Qyzylorda
+	"Qyzylorda Standard Time":         {"+05", "+05"},     // Asia/Qyzylorda
 	"Myanmar Standard Time":           {"+0630", "+0630"}, // Asia/Rangoon
 	"Arab Standard Time":              {"+03", "+03"},     // Asia/Riyadh
 	"Sakhalin Standard Time":          {"+11", "+11"},     // Asia/Sakhalin
@@ -93,7 +95,7 @@
 	"Taipei Standard Time":            {"CST", "CST"},     // Asia/Taipei
 	"West Asia Standard Time":         {"+05", "+05"},     // Asia/Tashkent
 	"Georgian Standard Time":          {"+04", "+04"},     // Asia/Tbilisi
-	"Iran Standard Time":              {"+0330", "+0430"}, // Asia/Tehran
+	"Iran Standard Time":              {"+0330", "+0330"}, // Asia/Tehran
 	"Tokyo Standard Time":             {"JST", "JST"},     // Asia/Tokyo
 	"Tomsk Standard Time":             {"+07", "+07"},     // Asia/Tomsk
 	"Ulaanbaatar Standard Time":       {"+08", "+08"},     // Asia/Ulaanbaatar
@@ -112,7 +114,6 @@
 	"Lord Howe Standard Time":         {"+1030", "+11"},   // Australia/Lord_Howe
 	"W. Australia Standard Time":      {"AWST", "AWST"},   // Australia/Perth
 	"AUS Eastern Standard Time":       {"AEST", "AEDT"},   // Australia/Sydney
-	"UTC":                             {"GMT", "GMT"},     // Etc/GMT
 	"UTC-11":                          {"-11", "-11"},     // Etc/GMT+11
 	"Dateline Standard Time":          {"-12", "-12"},     // Etc/GMT+12
 	"UTC-02":                          {"-02", "-02"},     // Etc/GMT+2
@@ -120,6 +121,7 @@
 	"UTC-09":                          {"-09", "-09"},     // Etc/GMT+9
 	"UTC+12":                          {"+12", "+12"},     // Etc/GMT-12
 	"UTC+13":                          {"+13", "+13"},     // Etc/GMT-13
+	"UTC":                             {"UTC", "UTC"},     // Etc/UTC
 	"Astrakhan Standard Time":         {"+04", "+04"},     // Europe/Astrakhan
 	"W. Europe Standard Time":         {"CET", "CEST"},    // Europe/Berlin
 	"GTB Standard Time":               {"EET", "EEST"},    // Europe/Bucharest
@@ -134,20 +136,20 @@
 	"Romance Standard Time":           {"CET", "CEST"},    // Europe/Paris
 	"Russia Time Zone 3":              {"+04", "+04"},     // Europe/Samara
 	"Saratov Standard Time":           {"+04", "+04"},     // Europe/Saratov
-	"Volgograd Standard Time":         {"+04", "+04"},     // Europe/Volgograd
+	"Volgograd Standard Time":         {"+03", "+03"},     // Europe/Volgograd
 	"Central European Standard Time":  {"CET", "CEST"},    // Europe/Warsaw
 	"Mauritius Standard Time":         {"+04", "+04"},     // Indian/Mauritius
-	"Samoa Standard Time":             {"+13", "+14"},     // Pacific/Apia
+	"Samoa Standard Time":             {"+13", "+13"},     // Pacific/Apia
 	"New Zealand Standard Time":       {"NZST", "NZDT"},   // Pacific/Auckland
 	"Bougainville Standard Time":      {"+11", "+11"},     // Pacific/Bougainville
 	"Chatham Islands Standard Time":   {"+1245", "+1345"}, // Pacific/Chatham
 	"Easter Island Standard Time":     {"-06", "-05"},     // Pacific/Easter
-	"Fiji Standard Time":              {"+12", "+13"},     // Pacific/Fiji
+	"Fiji Standard Time":              {"+12", "+12"},     // Pacific/Fiji
 	"Central Pacific Standard Time":   {"+11", "+11"},     // Pacific/Guadalcanal
 	"Hawaiian Standard Time":          {"HST", "HST"},     // Pacific/Honolulu
 	"Line Islands Standard Time":      {"+14", "+14"},     // Pacific/Kiritimati
 	"Marquesas Standard Time":         {"-0930", "-0930"}, // Pacific/Marquesas
-	"Norfolk Standard Time":           {"+11", "+11"},     // Pacific/Norfolk
+	"Norfolk Standard Time":           {"+11", "+12"},     // Pacific/Norfolk
 	"West Pacific Standard Time":      {"+10", "+10"},     // Pacific/Port_Moresby
 	"Tonga Standard Time":             {"+13", "+13"},     // Pacific/Tongatapu
 }
diff --git a/src/time/zoneinfo_js.go b/src/time/zoneinfo_js.go
index 06306cf..8da34a2 100644
--- a/src/time/zoneinfo_js.go
+++ b/src/time/zoneinfo_js.go
@@ -7,6 +7,7 @@
 package time
 
 import (
+	"internal/itoa"
 	"syscall/js"
 )
 
@@ -35,31 +36,10 @@
 	} else {
 		z.name += "+"
 	}
-	z.name += itoa(offset / 60)
+	z.name += itoa.Itoa(offset / 60)
 	min := offset % 60
 	if min != 0 {
-		z.name += ":" + itoa(min)
+		z.name += ":" + itoa.Itoa(min)
 	}
 	localLoc.zone = []zone{z}
 }
-
-// itoa is like strconv.Itoa but only works for values of i in range [0,99].
-// It panics if i is out of range.
-func itoa(i int) string {
-	if i < 10 {
-		return digits[i : i+1]
-	}
-	return smallsString[i*2 : i*2+2]
-}
-
-const smallsString = "00010203040506070809" +
-	"10111213141516171819" +
-	"20212223242526272829" +
-	"30313233343536373839" +
-	"40414243444546474849" +
-	"50515253545556575859" +
-	"60616263646566676869" +
-	"70717273747576777879" +
-	"80818283848586878889" +
-	"90919293949596979899"
-const digits = "0123456789"
diff --git a/src/unicode/utf16/utf16.go b/src/unicode/utf16/utf16.go
index 1a881aa..38d8be6 100644
--- a/src/unicode/utf16/utf16.go
+++ b/src/unicode/utf16/utf16.go
@@ -83,6 +83,23 @@
 	return a[:n]
 }
 
+// AppendRune appends the UTF-16 encoding of the Unicode code point r
+// to the end of p and returns the extended buffer. If the rune is not
+// a valid Unicode code point, it appends the encoding of U+FFFD.
+func AppendRune(a []uint16, r rune) []uint16 {
+	// This function is inlineable for fast handling of ASCII.
+	switch {
+	case 0 <= r && r < surr1, surr3 <= r && r < surrSelf:
+		// normal rune
+		return append(a, uint16(r))
+	case surrSelf <= r && r <= maxRune:
+		// needs surrogate sequence
+		r1, r2 := EncodeRune(r)
+		return append(a, uint16(r1), uint16(r2))
+	}
+	return append(a, replacementChar)
+}
+
 // Decode returns the Unicode code point sequence represented
 // by the UTF-16 encoding s.
 func Decode(s []uint16) []rune {
diff --git a/src/unicode/utf16/utf16_test.go b/src/unicode/utf16/utf16_test.go
index 4ecaabe..be339b1 100644
--- a/src/unicode/utf16/utf16_test.go
+++ b/src/unicode/utf16/utf16_test.go
@@ -43,6 +43,18 @@
 	}
 }
 
+func TestAppendRune(t *testing.T) {
+	for _, tt := range encodeTests {
+		var out []uint16
+		for _, u := range tt.in {
+			out = AppendRune(out, u)
+		}
+		if !reflect.DeepEqual(out, tt.out) {
+			t.Errorf("AppendRune(%x) = %x; want %x", tt.in, out, tt.out)
+		}
+	}
+}
+
 func TestEncodeRune(t *testing.T) {
 	for i, tt := range encodeTests {
 		j := 0
@@ -193,6 +205,28 @@
 	}
 }
 
+func BenchmarkAppendRuneValidASCII(b *testing.B) {
+	data := []rune{'h', 'e', 'l', 'l', 'o'}
+	a := make([]uint16, 0, len(data)*2)
+	for i := 0; i < b.N; i++ {
+		for _, u := range data {
+			a = AppendRune(a, u)
+		}
+		a = a[:0]
+	}
+}
+
+func BenchmarkAppendRuneValidJapaneseChars(b *testing.B) {
+	data := []rune{'日', '本', '語'}
+	a := make([]uint16, 0, len(data)*2)
+	for i := 0; i < b.N; i++ {
+		for _, u := range data {
+			a = AppendRune(a, u)
+		}
+		a = a[:0]
+	}
+}
+
 func BenchmarkEncodeRune(b *testing.B) {
 	for i := 0; i < b.N; i++ {
 		for _, u := range []rune{'𝓐', '𝓑', '𝓒', '𝓓', '𝓔'} {
diff --git a/src/unicode/utf8/utf8_test.go b/src/unicode/utf8/utf8_test.go
index e7c3122..19a04dc 100644
--- a/src/unicode/utf8/utf8_test.go
+++ b/src/unicode/utf8/utf8_test.go
@@ -626,7 +626,7 @@
 
 func init() {
 	const japanese = "日本語日本語日本語日"
-	var b bytes.Buffer
+	var b strings.Builder
 	for i := 0; b.Len() < 100_000; i++ {
 		if i%100 == 0 {
 			b.WriteString(japanese)
diff --git a/src/unsafe/unsafe.go b/src/unsafe/unsafe.go
index 5051b3e..2f4212a 100644
--- a/src/unsafe/unsafe.go
+++ b/src/unsafe/unsafe.go
@@ -239,3 +239,31 @@
 // At run time, if len is negative, or if ptr is nil and len is not zero,
 // a run-time panic occurs.
 func Slice(ptr *ArbitraryType, len IntegerType) []ArbitraryType
+
+// SliceData returns a pointer to the underlying array of the argument
+// slice.
+//   - If cap(slice) > 0, SliceData returns &slice[:1][0].
+//   - If slice == nil, SliceData returns nil.
+//   - Otherwise, SliceData returns a non-nil pointer to an
+//     unspecified memory address.
+func SliceData(slice []ArbitraryType) *ArbitraryType
+
+// String returns a string value whose underlying bytes
+// start at ptr and whose length is len.
+//
+// The len argument must be of integer type or an untyped constant.
+// A constant len argument must be non-negative and representable by a value of type int;
+// if it is an untyped constant it is given type int.
+// At run time, if len is negative, or if ptr is nil and len is not zero,
+// a run-time panic occurs.
+//
+// Since Go strings are immutable, the bytes passed to String
+// must not be modified afterwards.
+func String(ptr *byte, len IntegerType) string
+
+// StringData returns a pointer to the underlying bytes of str.
+// For an empty string the return value is unspecified, and may be nil.
+//
+// Since Go strings are immutable, the bytes returned by StringData
+// must not be modified.
+func StringData(str string) *byte
diff --git a/src/vendor/golang.org/x/crypto/AUTHORS b/src/vendor/golang.org/x/crypto/AUTHORS
deleted file mode 100644
index 2b00ddb..0000000
--- a/src/vendor/golang.org/x/crypto/AUTHORS
+++ /dev/null
@@ -1,3 +0,0 @@
-# This source code refers to The Go Authors for copyright purposes.
-# The master list of authors is in the main Go distribution,
-# visible at https://tip.golang.org/AUTHORS.
diff --git a/src/vendor/golang.org/x/crypto/CONTRIBUTORS b/src/vendor/golang.org/x/crypto/CONTRIBUTORS
deleted file mode 100644
index 1fbd3e9..0000000
--- a/src/vendor/golang.org/x/crypto/CONTRIBUTORS
+++ /dev/null
@@ -1,3 +0,0 @@
-# This source code was written by the Go contributors.
-# The master list of contributors is in the main Go distribution,
-# visible at https://tip.golang.org/CONTRIBUTORS.
diff --git a/src/vendor/golang.org/x/crypto/chacha20/chacha_generic.go b/src/vendor/golang.org/x/crypto/chacha20/chacha_generic.go
index a2ecf5c..93eb5ae 100644
--- a/src/vendor/golang.org/x/crypto/chacha20/chacha_generic.go
+++ b/src/vendor/golang.org/x/crypto/chacha20/chacha_generic.go
@@ -12,7 +12,7 @@
 	"errors"
 	"math/bits"
 
-	"golang.org/x/crypto/internal/subtle"
+	"golang.org/x/crypto/internal/alias"
 )
 
 const (
@@ -189,7 +189,7 @@
 		panic("chacha20: output smaller than input")
 	}
 	dst = dst[:len(src)]
-	if subtle.InexactOverlap(dst, src) {
+	if alias.InexactOverlap(dst, src) {
 		panic("chacha20: invalid buffer overlap")
 	}
 
diff --git a/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go b/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go
index 25959b9..0c408c5 100644
--- a/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go
+++ b/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go
@@ -10,7 +10,7 @@
 import (
 	"encoding/binary"
 
-	"golang.org/x/crypto/internal/subtle"
+	"golang.org/x/crypto/internal/alias"
 	"golang.org/x/sys/cpu"
 )
 
@@ -56,7 +56,7 @@
 	setupState(&state, &c.key, nonce)
 
 	ret, out := sliceForAppend(dst, len(plaintext)+16)
-	if subtle.InexactOverlap(out, plaintext) {
+	if alias.InexactOverlap(out, plaintext) {
 		panic("chacha20poly1305: invalid buffer overlap")
 	}
 	chacha20Poly1305Seal(out[:], state[:], plaintext, additionalData)
@@ -73,7 +73,7 @@
 
 	ciphertext = ciphertext[:len(ciphertext)-16]
 	ret, out := sliceForAppend(dst, len(ciphertext))
-	if subtle.InexactOverlap(out, ciphertext) {
+	if alias.InexactOverlap(out, ciphertext) {
 		panic("chacha20poly1305: invalid buffer overlap")
 	}
 	if !chacha20Poly1305Open(out, state[:], ciphertext, additionalData) {
diff --git a/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go b/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go
index 96b2fd8..6313898 100644
--- a/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go
+++ b/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go
@@ -8,8 +8,8 @@
 	"encoding/binary"
 
 	"golang.org/x/crypto/chacha20"
+	"golang.org/x/crypto/internal/alias"
 	"golang.org/x/crypto/internal/poly1305"
-	"golang.org/x/crypto/internal/subtle"
 )
 
 func writeWithPadding(p *poly1305.MAC, b []byte) {
@@ -30,7 +30,7 @@
 func (c *chacha20poly1305) sealGeneric(dst, nonce, plaintext, additionalData []byte) []byte {
 	ret, out := sliceForAppend(dst, len(plaintext)+poly1305.TagSize)
 	ciphertext, tag := out[:len(plaintext)], out[len(plaintext):]
-	if subtle.InexactOverlap(out, plaintext) {
+	if alias.InexactOverlap(out, plaintext) {
 		panic("chacha20poly1305: invalid buffer overlap")
 	}
 
@@ -66,7 +66,7 @@
 	writeUint64(p, len(ciphertext))
 
 	ret, out := sliceForAppend(dst, len(ciphertext))
-	if subtle.InexactOverlap(out, ciphertext) {
+	if alias.InexactOverlap(out, ciphertext) {
 		panic("chacha20poly1305: invalid buffer overlap")
 	}
 	if !p.Verify(tag) {
diff --git a/src/vendor/golang.org/x/crypto/cryptobyte/asn1.go b/src/vendor/golang.org/x/crypto/cryptobyte/asn1.go
index 3a1674a..401414d 100644
--- a/src/vendor/golang.org/x/crypto/cryptobyte/asn1.go
+++ b/src/vendor/golang.org/x/crypto/cryptobyte/asn1.go
@@ -264,36 +264,35 @@
 	return true
 }
 
-var bigIntType = reflect.TypeOf((*big.Int)(nil)).Elem()
-
 // ReadASN1Integer decodes an ASN.1 INTEGER into out and advances. If out does
-// not point to an integer or to a big.Int, it panics. It reports whether the
-// read was successful.
+// not point to an integer, to a big.Int, or to a []byte it panics. Only
+// positive and zero values can be decoded into []byte, and they are returned as
+// big-endian binary values that share memory with s. Positive values will have
+// no leading zeroes, and zero will be returned as a single zero byte.
+// ReadASN1Integer reports whether the read was successful.
 func (s *String) ReadASN1Integer(out interface{}) bool {
-	if reflect.TypeOf(out).Kind() != reflect.Ptr {
-		panic("out is not a pointer")
-	}
-	switch reflect.ValueOf(out).Elem().Kind() {
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+	switch out := out.(type) {
+	case *int, *int8, *int16, *int32, *int64:
 		var i int64
 		if !s.readASN1Int64(&i) || reflect.ValueOf(out).Elem().OverflowInt(i) {
 			return false
 		}
 		reflect.ValueOf(out).Elem().SetInt(i)
 		return true
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+	case *uint, *uint8, *uint16, *uint32, *uint64:
 		var u uint64
 		if !s.readASN1Uint64(&u) || reflect.ValueOf(out).Elem().OverflowUint(u) {
 			return false
 		}
 		reflect.ValueOf(out).Elem().SetUint(u)
 		return true
-	case reflect.Struct:
-		if reflect.TypeOf(out).Elem() == bigIntType {
-			return s.readASN1BigInt(out.(*big.Int))
-		}
+	case *big.Int:
+		return s.readASN1BigInt(out)
+	case *[]byte:
+		return s.readASN1Bytes(out)
+	default:
+		panic("out does not point to an integer type")
 	}
-	panic("out does not point to an integer type")
 }
 
 func checkASN1Integer(bytes []byte) bool {
@@ -333,6 +332,21 @@
 	return true
 }
 
+func (s *String) readASN1Bytes(out *[]byte) bool {
+	var bytes String
+	if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) {
+		return false
+	}
+	if bytes[0]&0x80 == 0x80 {
+		return false
+	}
+	for len(bytes) > 1 && bytes[0] == 0 {
+		bytes = bytes[1:]
+	}
+	*out = bytes
+	return true
+}
+
 func (s *String) readASN1Int64(out *int64) bool {
 	var bytes String
 	if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) || !asn1Signed(out, bytes) {
@@ -532,7 +546,7 @@
 		return false
 	}
 
-	paddingBits := uint8(bytes[0])
+	paddingBits := bytes[0]
 	bytes = bytes[1:]
 	if paddingBits > 7 ||
 		len(bytes) == 0 && paddingBits != 0 ||
@@ -554,7 +568,7 @@
 		return false
 	}
 
-	paddingBits := uint8(bytes[0])
+	paddingBits := bytes[0]
 	if paddingBits != 0 {
 		return false
 	}
@@ -654,34 +668,27 @@
 	return s.ReadASN1(&unused, tag)
 }
 
-// ReadOptionalASN1Integer attempts to read an optional ASN.1 INTEGER
-// explicitly tagged with tag into out and advances. If no element with a
-// matching tag is present, it writes defaultValue into out instead. If out
-// does not point to an integer or to a big.Int, it panics. It reports
-// whether the read was successful.
+// ReadOptionalASN1Integer attempts to read an optional ASN.1 INTEGER explicitly
+// tagged with tag into out and advances. If no element with a matching tag is
+// present, it writes defaultValue into out instead. Otherwise, it behaves like
+// ReadASN1Integer.
 func (s *String) ReadOptionalASN1Integer(out interface{}, tag asn1.Tag, defaultValue interface{}) bool {
-	if reflect.TypeOf(out).Kind() != reflect.Ptr {
-		panic("out is not a pointer")
-	}
 	var present bool
 	var i String
 	if !s.ReadOptionalASN1(&i, &present, tag) {
 		return false
 	}
 	if !present {
-		switch reflect.ValueOf(out).Elem().Kind() {
-		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
-			reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+		switch out.(type) {
+		case *int, *int8, *int16, *int32, *int64,
+			*uint, *uint8, *uint16, *uint32, *uint64, *[]byte:
 			reflect.ValueOf(out).Elem().Set(reflect.ValueOf(defaultValue))
-		case reflect.Struct:
-			if reflect.TypeOf(out).Elem() != bigIntType {
-				panic("invalid integer type")
-			}
-			if reflect.TypeOf(defaultValue).Kind() != reflect.Ptr ||
-				reflect.TypeOf(defaultValue).Elem() != bigIntType {
+		case *big.Int:
+			if defaultValue, ok := defaultValue.(*big.Int); ok {
+				out.(*big.Int).Set(defaultValue)
+			} else {
 				panic("out points to big.Int, but defaultValue does not")
 			}
-			out.(*big.Int).Set(defaultValue.(*big.Int))
 		default:
 			panic("invalid integer type")
 		}
diff --git a/src/vendor/golang.org/x/crypto/cryptobyte/builder.go b/src/vendor/golang.org/x/crypto/cryptobyte/builder.go
index c7ded75..2a90c59 100644
--- a/src/vendor/golang.org/x/crypto/cryptobyte/builder.go
+++ b/src/vendor/golang.org/x/crypto/cryptobyte/builder.go
@@ -95,6 +95,11 @@
 	b.add(byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
 }
 
+// AddUint64 appends a big-endian, 64-bit value to the byte string.
+func (b *Builder) AddUint64(v uint64) {
+	b.add(byte(v>>56), byte(v>>48), byte(v>>40), byte(v>>32), byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
+}
+
 // AddBytes appends a sequence of bytes to the byte string.
 func (b *Builder) AddBytes(v []byte) {
 	b.add(v...)
diff --git a/src/vendor/golang.org/x/crypto/cryptobyte/string.go b/src/vendor/golang.org/x/crypto/cryptobyte/string.go
index 589d297..0531a3d 100644
--- a/src/vendor/golang.org/x/crypto/cryptobyte/string.go
+++ b/src/vendor/golang.org/x/crypto/cryptobyte/string.go
@@ -81,6 +81,17 @@
 	return true
 }
 
+// ReadUint64 decodes a big-endian, 64-bit value into out and advances over it.
+// It reports whether the read was successful.
+func (s *String) ReadUint64(out *uint64) bool {
+	v := s.read(8)
+	if v == nil {
+		return false
+	}
+	*out = uint64(v[0])<<56 | uint64(v[1])<<48 | uint64(v[2])<<40 | uint64(v[3])<<32 | uint64(v[4])<<24 | uint64(v[5])<<16 | uint64(v[6])<<8 | uint64(v[7])
+	return true
+}
+
 func (s *String) readUnsigned(out *uint32, length int) bool {
 	v := s.read(length)
 	if v == nil {
diff --git a/src/vendor/golang.org/x/crypto/curve25519/curve25519.go b/src/vendor/golang.org/x/crypto/curve25519/curve25519.go
deleted file mode 100644
index cda3fdd..0000000
--- a/src/vendor/golang.org/x/crypto/curve25519/curve25519.go
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package curve25519 provides an implementation of the X25519 function, which
-// performs scalar multiplication on the elliptic curve known as Curve25519.
-// See RFC 7748.
-package curve25519 // import "golang.org/x/crypto/curve25519"
-
-import (
-	"crypto/subtle"
-	"fmt"
-
-	"golang.org/x/crypto/curve25519/internal/field"
-)
-
-// ScalarMult sets dst to the product scalar * point.
-//
-// Deprecated: when provided a low-order point, ScalarMult will set dst to all
-// zeroes, irrespective of the scalar. Instead, use the X25519 function, which
-// will return an error.
-func ScalarMult(dst, scalar, point *[32]byte) {
-	var e [32]byte
-
-	copy(e[:], scalar[:])
-	e[0] &= 248
-	e[31] &= 127
-	e[31] |= 64
-
-	var x1, x2, z2, x3, z3, tmp0, tmp1 field.Element
-	x1.SetBytes(point[:])
-	x2.One()
-	x3.Set(&x1)
-	z3.One()
-
-	swap := 0
-	for pos := 254; pos >= 0; pos-- {
-		b := e[pos/8] >> uint(pos&7)
-		b &= 1
-		swap ^= int(b)
-		x2.Swap(&x3, swap)
-		z2.Swap(&z3, swap)
-		swap = int(b)
-
-		tmp0.Subtract(&x3, &z3)
-		tmp1.Subtract(&x2, &z2)
-		x2.Add(&x2, &z2)
-		z2.Add(&x3, &z3)
-		z3.Multiply(&tmp0, &x2)
-		z2.Multiply(&z2, &tmp1)
-		tmp0.Square(&tmp1)
-		tmp1.Square(&x2)
-		x3.Add(&z3, &z2)
-		z2.Subtract(&z3, &z2)
-		x2.Multiply(&tmp1, &tmp0)
-		tmp1.Subtract(&tmp1, &tmp0)
-		z2.Square(&z2)
-
-		z3.Mult32(&tmp1, 121666)
-		x3.Square(&x3)
-		tmp0.Add(&tmp0, &z3)
-		z3.Multiply(&x1, &z2)
-		z2.Multiply(&tmp1, &tmp0)
-	}
-
-	x2.Swap(&x3, swap)
-	z2.Swap(&z3, swap)
-
-	z2.Invert(&z2)
-	x2.Multiply(&x2, &z2)
-	copy(dst[:], x2.Bytes())
-}
-
-// ScalarBaseMult sets dst to the product scalar * base where base is the
-// standard generator.
-//
-// It is recommended to use the X25519 function with Basepoint instead, as
-// copying into fixed size arrays can lead to unexpected bugs.
-func ScalarBaseMult(dst, scalar *[32]byte) {
-	ScalarMult(dst, scalar, &basePoint)
-}
-
-const (
-	// ScalarSize is the size of the scalar input to X25519.
-	ScalarSize = 32
-	// PointSize is the size of the point input to X25519.
-	PointSize = 32
-)
-
-// Basepoint is the canonical Curve25519 generator.
-var Basepoint []byte
-
-var basePoint = [32]byte{9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
-
-func init() { Basepoint = basePoint[:] }
-
-func checkBasepoint() {
-	if subtle.ConstantTimeCompare(Basepoint, []byte{
-		0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	}) != 1 {
-		panic("curve25519: global Basepoint value was modified")
-	}
-}
-
-// X25519 returns the result of the scalar multiplication (scalar * point),
-// according to RFC 7748, Section 5. scalar, point and the return value are
-// slices of 32 bytes.
-//
-// scalar can be generated at random, for example with crypto/rand. point should
-// be either Basepoint or the output of another X25519 call.
-//
-// If point is Basepoint (but not if it's a different slice with the same
-// contents) a precomputed implementation might be used for performance.
-func X25519(scalar, point []byte) ([]byte, error) {
-	// Outline the body of function, to let the allocation be inlined in the
-	// caller, and possibly avoid escaping to the heap.
-	var dst [32]byte
-	return x25519(&dst, scalar, point)
-}
-
-func x25519(dst *[32]byte, scalar, point []byte) ([]byte, error) {
-	var in [32]byte
-	if l := len(scalar); l != 32 {
-		return nil, fmt.Errorf("bad scalar length: %d, expected %d", l, 32)
-	}
-	if l := len(point); l != 32 {
-		return nil, fmt.Errorf("bad point length: %d, expected %d", l, 32)
-	}
-	copy(in[:], scalar)
-	if &point[0] == &Basepoint[0] {
-		checkBasepoint()
-		ScalarBaseMult(dst, &in)
-	} else {
-		var base, zero [32]byte
-		copy(base[:], point)
-		ScalarMult(dst, &in, &base)
-		if subtle.ConstantTimeCompare(dst[:], zero[:]) == 1 {
-			return nil, fmt.Errorf("bad input point: low order point")
-		}
-	}
-	return dst[:], nil
-}
diff --git a/src/vendor/golang.org/x/crypto/curve25519/internal/field/README b/src/vendor/golang.org/x/crypto/curve25519/internal/field/README
deleted file mode 100644
index e25bca7..0000000
--- a/src/vendor/golang.org/x/crypto/curve25519/internal/field/README
+++ /dev/null
@@ -1,7 +0,0 @@
-This package is kept in sync with crypto/ed25519/internal/edwards25519/field in
-the standard library.
-
-If there are any changes in the standard library that need to be synced to this
-package, run sync.sh. It will not overwrite any local changes made since the
-previous sync, so it's ok to land changes in this package first, and then sync
-to the standard library later.
diff --git a/src/vendor/golang.org/x/crypto/curve25519/internal/field/fe.go b/src/vendor/golang.org/x/crypto/curve25519/internal/field/fe.go
deleted file mode 100644
index ca841ad..0000000
--- a/src/vendor/golang.org/x/crypto/curve25519/internal/field/fe.go
+++ /dev/null
@@ -1,416 +0,0 @@
-// Copyright (c) 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package field implements fast arithmetic modulo 2^255-19.
-package field
-
-import (
-	"crypto/subtle"
-	"encoding/binary"
-	"math/bits"
-)
-
-// Element represents an element of the field GF(2^255-19). Note that this
-// is not a cryptographically secure group, and should only be used to interact
-// with edwards25519.Point coordinates.
-//
-// This type works similarly to math/big.Int, and all arguments and receivers
-// are allowed to alias.
-//
-// The zero value is a valid zero element.
-type Element struct {
-	// An element t represents the integer
-	//     t.l0 + t.l1*2^51 + t.l2*2^102 + t.l3*2^153 + t.l4*2^204
-	//
-	// Between operations, all limbs are expected to be lower than 2^52.
-	l0 uint64
-	l1 uint64
-	l2 uint64
-	l3 uint64
-	l4 uint64
-}
-
-const maskLow51Bits uint64 = (1 << 51) - 1
-
-var feZero = &Element{0, 0, 0, 0, 0}
-
-// Zero sets v = 0, and returns v.
-func (v *Element) Zero() *Element {
-	*v = *feZero
-	return v
-}
-
-var feOne = &Element{1, 0, 0, 0, 0}
-
-// One sets v = 1, and returns v.
-func (v *Element) One() *Element {
-	*v = *feOne
-	return v
-}
-
-// reduce reduces v modulo 2^255 - 19 and returns it.
-func (v *Element) reduce() *Element {
-	v.carryPropagate()
-
-	// After the light reduction we now have a field element representation
-	// v < 2^255 + 2^13 * 19, but need v < 2^255 - 19.
-
-	// If v >= 2^255 - 19, then v + 19 >= 2^255, which would overflow 2^255 - 1,
-	// generating a carry. That is, c will be 0 if v < 2^255 - 19, and 1 otherwise.
-	c := (v.l0 + 19) >> 51
-	c = (v.l1 + c) >> 51
-	c = (v.l2 + c) >> 51
-	c = (v.l3 + c) >> 51
-	c = (v.l4 + c) >> 51
-
-	// If v < 2^255 - 19 and c = 0, this will be a no-op. Otherwise, it's
-	// effectively applying the reduction identity to the carry.
-	v.l0 += 19 * c
-
-	v.l1 += v.l0 >> 51
-	v.l0 = v.l0 & maskLow51Bits
-	v.l2 += v.l1 >> 51
-	v.l1 = v.l1 & maskLow51Bits
-	v.l3 += v.l2 >> 51
-	v.l2 = v.l2 & maskLow51Bits
-	v.l4 += v.l3 >> 51
-	v.l3 = v.l3 & maskLow51Bits
-	// no additional carry
-	v.l4 = v.l4 & maskLow51Bits
-
-	return v
-}
-
-// Add sets v = a + b, and returns v.
-func (v *Element) Add(a, b *Element) *Element {
-	v.l0 = a.l0 + b.l0
-	v.l1 = a.l1 + b.l1
-	v.l2 = a.l2 + b.l2
-	v.l3 = a.l3 + b.l3
-	v.l4 = a.l4 + b.l4
-	// Using the generic implementation here is actually faster than the
-	// assembly. Probably because the body of this function is so simple that
-	// the compiler can figure out better optimizations by inlining the carry
-	// propagation. TODO
-	return v.carryPropagateGeneric()
-}
-
-// Subtract sets v = a - b, and returns v.
-func (v *Element) Subtract(a, b *Element) *Element {
-	// We first add 2 * p, to guarantee the subtraction won't underflow, and
-	// then subtract b (which can be up to 2^255 + 2^13 * 19).
-	v.l0 = (a.l0 + 0xFFFFFFFFFFFDA) - b.l0
-	v.l1 = (a.l1 + 0xFFFFFFFFFFFFE) - b.l1
-	v.l2 = (a.l2 + 0xFFFFFFFFFFFFE) - b.l2
-	v.l3 = (a.l3 + 0xFFFFFFFFFFFFE) - b.l3
-	v.l4 = (a.l4 + 0xFFFFFFFFFFFFE) - b.l4
-	return v.carryPropagate()
-}
-
-// Negate sets v = -a, and returns v.
-func (v *Element) Negate(a *Element) *Element {
-	return v.Subtract(feZero, a)
-}
-
-// Invert sets v = 1/z mod p, and returns v.
-//
-// If z == 0, Invert returns v = 0.
-func (v *Element) Invert(z *Element) *Element {
-	// Inversion is implemented as exponentiation with exponent p − 2. It uses the
-	// same sequence of 255 squarings and 11 multiplications as [Curve25519].
-	var z2, z9, z11, z2_5_0, z2_10_0, z2_20_0, z2_50_0, z2_100_0, t Element
-
-	z2.Square(z)             // 2
-	t.Square(&z2)            // 4
-	t.Square(&t)             // 8
-	z9.Multiply(&t, z)       // 9
-	z11.Multiply(&z9, &z2)   // 11
-	t.Square(&z11)           // 22
-	z2_5_0.Multiply(&t, &z9) // 31 = 2^5 - 2^0
-
-	t.Square(&z2_5_0) // 2^6 - 2^1
-	for i := 0; i < 4; i++ {
-		t.Square(&t) // 2^10 - 2^5
-	}
-	z2_10_0.Multiply(&t, &z2_5_0) // 2^10 - 2^0
-
-	t.Square(&z2_10_0) // 2^11 - 2^1
-	for i := 0; i < 9; i++ {
-		t.Square(&t) // 2^20 - 2^10
-	}
-	z2_20_0.Multiply(&t, &z2_10_0) // 2^20 - 2^0
-
-	t.Square(&z2_20_0) // 2^21 - 2^1
-	for i := 0; i < 19; i++ {
-		t.Square(&t) // 2^40 - 2^20
-	}
-	t.Multiply(&t, &z2_20_0) // 2^40 - 2^0
-
-	t.Square(&t) // 2^41 - 2^1
-	for i := 0; i < 9; i++ {
-		t.Square(&t) // 2^50 - 2^10
-	}
-	z2_50_0.Multiply(&t, &z2_10_0) // 2^50 - 2^0
-
-	t.Square(&z2_50_0) // 2^51 - 2^1
-	for i := 0; i < 49; i++ {
-		t.Square(&t) // 2^100 - 2^50
-	}
-	z2_100_0.Multiply(&t, &z2_50_0) // 2^100 - 2^0
-
-	t.Square(&z2_100_0) // 2^101 - 2^1
-	for i := 0; i < 99; i++ {
-		t.Square(&t) // 2^200 - 2^100
-	}
-	t.Multiply(&t, &z2_100_0) // 2^200 - 2^0
-
-	t.Square(&t) // 2^201 - 2^1
-	for i := 0; i < 49; i++ {
-		t.Square(&t) // 2^250 - 2^50
-	}
-	t.Multiply(&t, &z2_50_0) // 2^250 - 2^0
-
-	t.Square(&t) // 2^251 - 2^1
-	t.Square(&t) // 2^252 - 2^2
-	t.Square(&t) // 2^253 - 2^3
-	t.Square(&t) // 2^254 - 2^4
-	t.Square(&t) // 2^255 - 2^5
-
-	return v.Multiply(&t, &z11) // 2^255 - 21
-}
-
-// Set sets v = a, and returns v.
-func (v *Element) Set(a *Element) *Element {
-	*v = *a
-	return v
-}
-
-// SetBytes sets v to x, which must be a 32-byte little-endian encoding.
-//
-// Consistent with RFC 7748, the most significant bit (the high bit of the
-// last byte) is ignored, and non-canonical values (2^255-19 through 2^255-1)
-// are accepted. Note that this is laxer than specified by RFC 8032.
-func (v *Element) SetBytes(x []byte) *Element {
-	if len(x) != 32 {
-		panic("edwards25519: invalid field element input size")
-	}
-
-	// Bits 0:51 (bytes 0:8, bits 0:64, shift 0, mask 51).
-	v.l0 = binary.LittleEndian.Uint64(x[0:8])
-	v.l0 &= maskLow51Bits
-	// Bits 51:102 (bytes 6:14, bits 48:112, shift 3, mask 51).
-	v.l1 = binary.LittleEndian.Uint64(x[6:14]) >> 3
-	v.l1 &= maskLow51Bits
-	// Bits 102:153 (bytes 12:20, bits 96:160, shift 6, mask 51).
-	v.l2 = binary.LittleEndian.Uint64(x[12:20]) >> 6
-	v.l2 &= maskLow51Bits
-	// Bits 153:204 (bytes 19:27, bits 152:216, shift 1, mask 51).
-	v.l3 = binary.LittleEndian.Uint64(x[19:27]) >> 1
-	v.l3 &= maskLow51Bits
-	// Bits 204:251 (bytes 24:32, bits 192:256, shift 12, mask 51).
-	// Note: not bytes 25:33, shift 4, to avoid overread.
-	v.l4 = binary.LittleEndian.Uint64(x[24:32]) >> 12
-	v.l4 &= maskLow51Bits
-
-	return v
-}
-
-// Bytes returns the canonical 32-byte little-endian encoding of v.
-func (v *Element) Bytes() []byte {
-	// This function is outlined to make the allocations inline in the caller
-	// rather than happen on the heap.
-	var out [32]byte
-	return v.bytes(&out)
-}
-
-func (v *Element) bytes(out *[32]byte) []byte {
-	t := *v
-	t.reduce()
-
-	var buf [8]byte
-	for i, l := range [5]uint64{t.l0, t.l1, t.l2, t.l3, t.l4} {
-		bitsOffset := i * 51
-		binary.LittleEndian.PutUint64(buf[:], l<<uint(bitsOffset%8))
-		for i, bb := range buf {
-			off := bitsOffset/8 + i
-			if off >= len(out) {
-				break
-			}
-			out[off] |= bb
-		}
-	}
-
-	return out[:]
-}
-
-// Equal returns 1 if v and u are equal, and 0 otherwise.
-func (v *Element) Equal(u *Element) int {
-	sa, sv := u.Bytes(), v.Bytes()
-	return subtle.ConstantTimeCompare(sa, sv)
-}
-
-// mask64Bits returns 0xffffffff if cond is 1, and 0 otherwise.
-func mask64Bits(cond int) uint64 { return ^(uint64(cond) - 1) }
-
-// Select sets v to a if cond == 1, and to b if cond == 0.
-func (v *Element) Select(a, b *Element, cond int) *Element {
-	m := mask64Bits(cond)
-	v.l0 = (m & a.l0) | (^m & b.l0)
-	v.l1 = (m & a.l1) | (^m & b.l1)
-	v.l2 = (m & a.l2) | (^m & b.l2)
-	v.l3 = (m & a.l3) | (^m & b.l3)
-	v.l4 = (m & a.l4) | (^m & b.l4)
-	return v
-}
-
-// Swap swaps v and u if cond == 1 or leaves them unchanged if cond == 0, and returns v.
-func (v *Element) Swap(u *Element, cond int) {
-	m := mask64Bits(cond)
-	t := m & (v.l0 ^ u.l0)
-	v.l0 ^= t
-	u.l0 ^= t
-	t = m & (v.l1 ^ u.l1)
-	v.l1 ^= t
-	u.l1 ^= t
-	t = m & (v.l2 ^ u.l2)
-	v.l2 ^= t
-	u.l2 ^= t
-	t = m & (v.l3 ^ u.l3)
-	v.l3 ^= t
-	u.l3 ^= t
-	t = m & (v.l4 ^ u.l4)
-	v.l4 ^= t
-	u.l4 ^= t
-}
-
-// IsNegative returns 1 if v is negative, and 0 otherwise.
-func (v *Element) IsNegative() int {
-	return int(v.Bytes()[0] & 1)
-}
-
-// Absolute sets v to |u|, and returns v.
-func (v *Element) Absolute(u *Element) *Element {
-	return v.Select(new(Element).Negate(u), u, u.IsNegative())
-}
-
-// Multiply sets v = x * y, and returns v.
-func (v *Element) Multiply(x, y *Element) *Element {
-	feMul(v, x, y)
-	return v
-}
-
-// Square sets v = x * x, and returns v.
-func (v *Element) Square(x *Element) *Element {
-	feSquare(v, x)
-	return v
-}
-
-// Mult32 sets v = x * y, and returns v.
-func (v *Element) Mult32(x *Element, y uint32) *Element {
-	x0lo, x0hi := mul51(x.l0, y)
-	x1lo, x1hi := mul51(x.l1, y)
-	x2lo, x2hi := mul51(x.l2, y)
-	x3lo, x3hi := mul51(x.l3, y)
-	x4lo, x4hi := mul51(x.l4, y)
-	v.l0 = x0lo + 19*x4hi // carried over per the reduction identity
-	v.l1 = x1lo + x0hi
-	v.l2 = x2lo + x1hi
-	v.l3 = x3lo + x2hi
-	v.l4 = x4lo + x3hi
-	// The hi portions are going to be only 32 bits, plus any previous excess,
-	// so we can skip the carry propagation.
-	return v
-}
-
-// mul51 returns lo + hi * 2⁵¹ = a * b.
-func mul51(a uint64, b uint32) (lo uint64, hi uint64) {
-	mh, ml := bits.Mul64(a, uint64(b))
-	lo = ml & maskLow51Bits
-	hi = (mh << 13) | (ml >> 51)
-	return
-}
-
-// Pow22523 set v = x^((p-5)/8), and returns v. (p-5)/8 is 2^252-3.
-func (v *Element) Pow22523(x *Element) *Element {
-	var t0, t1, t2 Element
-
-	t0.Square(x)             // x^2
-	t1.Square(&t0)           // x^4
-	t1.Square(&t1)           // x^8
-	t1.Multiply(x, &t1)      // x^9
-	t0.Multiply(&t0, &t1)    // x^11
-	t0.Square(&t0)           // x^22
-	t0.Multiply(&t1, &t0)    // x^31
-	t1.Square(&t0)           // x^62
-	for i := 1; i < 5; i++ { // x^992
-		t1.Square(&t1)
-	}
-	t0.Multiply(&t1, &t0)     // x^1023 -> 1023 = 2^10 - 1
-	t1.Square(&t0)            // 2^11 - 2
-	for i := 1; i < 10; i++ { // 2^20 - 2^10
-		t1.Square(&t1)
-	}
-	t1.Multiply(&t1, &t0)     // 2^20 - 1
-	t2.Square(&t1)            // 2^21 - 2
-	for i := 1; i < 20; i++ { // 2^40 - 2^20
-		t2.Square(&t2)
-	}
-	t1.Multiply(&t2, &t1)     // 2^40 - 1
-	t1.Square(&t1)            // 2^41 - 2
-	for i := 1; i < 10; i++ { // 2^50 - 2^10
-		t1.Square(&t1)
-	}
-	t0.Multiply(&t1, &t0)     // 2^50 - 1
-	t1.Square(&t0)            // 2^51 - 2
-	for i := 1; i < 50; i++ { // 2^100 - 2^50
-		t1.Square(&t1)
-	}
-	t1.Multiply(&t1, &t0)      // 2^100 - 1
-	t2.Square(&t1)             // 2^101 - 2
-	for i := 1; i < 100; i++ { // 2^200 - 2^100
-		t2.Square(&t2)
-	}
-	t1.Multiply(&t2, &t1)     // 2^200 - 1
-	t1.Square(&t1)            // 2^201 - 2
-	for i := 1; i < 50; i++ { // 2^250 - 2^50
-		t1.Square(&t1)
-	}
-	t0.Multiply(&t1, &t0)     // 2^250 - 1
-	t0.Square(&t0)            // 2^251 - 2
-	t0.Square(&t0)            // 2^252 - 4
-	return v.Multiply(&t0, x) // 2^252 - 3 -> x^(2^252-3)
-}
-
-// sqrtM1 is 2^((p-1)/4), which squared is equal to -1 by Euler's Criterion.
-var sqrtM1 = &Element{1718705420411056, 234908883556509,
-	2233514472574048, 2117202627021982, 765476049583133}
-
-// SqrtRatio sets r to the non-negative square root of the ratio of u and v.
-//
-// If u/v is square, SqrtRatio returns r and 1. If u/v is not square, SqrtRatio
-// sets r according to Section 4.3 of draft-irtf-cfrg-ristretto255-decaf448-00,
-// and returns r and 0.
-func (r *Element) SqrtRatio(u, v *Element) (rr *Element, wasSquare int) {
-	var a, b Element
-
-	// r = (u * v3) * (u * v7)^((p-5)/8)
-	v2 := a.Square(v)
-	uv3 := b.Multiply(u, b.Multiply(v2, v))
-	uv7 := a.Multiply(uv3, a.Square(v2))
-	r.Multiply(uv3, r.Pow22523(uv7))
-
-	check := a.Multiply(v, a.Square(r)) // check = v * r^2
-
-	uNeg := b.Negate(u)
-	correctSignSqrt := check.Equal(u)
-	flippedSignSqrt := check.Equal(uNeg)
-	flippedSignSqrtI := check.Equal(uNeg.Multiply(uNeg, sqrtM1))
-
-	rPrime := b.Multiply(r, sqrtM1) // r_prime = SQRT_M1 * r
-	// r = CT_SELECT(r_prime IF flipped_sign_sqrt | flipped_sign_sqrt_i ELSE r)
-	r.Select(rPrime, r, flippedSignSqrt|flippedSignSqrtI)
-
-	r.Absolute(r) // Choose the nonnegative square root.
-	return r, correctSignSqrt | flippedSignSqrt
-}
diff --git a/src/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.go b/src/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.go
deleted file mode 100644
index edcf163..0000000
--- a/src/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT.
-
-//go:build amd64 && gc && !purego
-// +build amd64,gc,!purego
-
-package field
-
-// feMul sets out = a * b. It works like feMulGeneric.
-//
-//go:noescape
-func feMul(out *Element, a *Element, b *Element)
-
-// feSquare sets out = a * a. It works like feSquareGeneric.
-//
-//go:noescape
-func feSquare(out *Element, a *Element)
diff --git a/src/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.s b/src/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.s
deleted file mode 100644
index 293f013..0000000
--- a/src/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.s
+++ /dev/null
@@ -1,379 +0,0 @@
-// Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT.
-
-//go:build amd64 && gc && !purego
-// +build amd64,gc,!purego
-
-#include "textflag.h"
-
-// func feMul(out *Element, a *Element, b *Element)
-TEXT ·feMul(SB), NOSPLIT, $0-24
-	MOVQ a+8(FP), CX
-	MOVQ b+16(FP), BX
-
-	// r0 = a0×b0
-	MOVQ (CX), AX
-	MULQ (BX)
-	MOVQ AX, DI
-	MOVQ DX, SI
-
-	// r0 += 19×a1×b4
-	MOVQ   8(CX), AX
-	IMUL3Q $0x13, AX, AX
-	MULQ   32(BX)
-	ADDQ   AX, DI
-	ADCQ   DX, SI
-
-	// r0 += 19×a2×b3
-	MOVQ   16(CX), AX
-	IMUL3Q $0x13, AX, AX
-	MULQ   24(BX)
-	ADDQ   AX, DI
-	ADCQ   DX, SI
-
-	// r0 += 19×a3×b2
-	MOVQ   24(CX), AX
-	IMUL3Q $0x13, AX, AX
-	MULQ   16(BX)
-	ADDQ   AX, DI
-	ADCQ   DX, SI
-
-	// r0 += 19×a4×b1
-	MOVQ   32(CX), AX
-	IMUL3Q $0x13, AX, AX
-	MULQ   8(BX)
-	ADDQ   AX, DI
-	ADCQ   DX, SI
-
-	// r1 = a0×b1
-	MOVQ (CX), AX
-	MULQ 8(BX)
-	MOVQ AX, R9
-	MOVQ DX, R8
-
-	// r1 += a1×b0
-	MOVQ 8(CX), AX
-	MULQ (BX)
-	ADDQ AX, R9
-	ADCQ DX, R8
-
-	// r1 += 19×a2×b4
-	MOVQ   16(CX), AX
-	IMUL3Q $0x13, AX, AX
-	MULQ   32(BX)
-	ADDQ   AX, R9
-	ADCQ   DX, R8
-
-	// r1 += 19×a3×b3
-	MOVQ   24(CX), AX
-	IMUL3Q $0x13, AX, AX
-	MULQ   24(BX)
-	ADDQ   AX, R9
-	ADCQ   DX, R8
-
-	// r1 += 19×a4×b2
-	MOVQ   32(CX), AX
-	IMUL3Q $0x13, AX, AX
-	MULQ   16(BX)
-	ADDQ   AX, R9
-	ADCQ   DX, R8
-
-	// r2 = a0×b2
-	MOVQ (CX), AX
-	MULQ 16(BX)
-	MOVQ AX, R11
-	MOVQ DX, R10
-
-	// r2 += a1×b1
-	MOVQ 8(CX), AX
-	MULQ 8(BX)
-	ADDQ AX, R11
-	ADCQ DX, R10
-
-	// r2 += a2×b0
-	MOVQ 16(CX), AX
-	MULQ (BX)
-	ADDQ AX, R11
-	ADCQ DX, R10
-
-	// r2 += 19×a3×b4
-	MOVQ   24(CX), AX
-	IMUL3Q $0x13, AX, AX
-	MULQ   32(BX)
-	ADDQ   AX, R11
-	ADCQ   DX, R10
-
-	// r2 += 19×a4×b3
-	MOVQ   32(CX), AX
-	IMUL3Q $0x13, AX, AX
-	MULQ   24(BX)
-	ADDQ   AX, R11
-	ADCQ   DX, R10
-
-	// r3 = a0×b3
-	MOVQ (CX), AX
-	MULQ 24(BX)
-	MOVQ AX, R13
-	MOVQ DX, R12
-
-	// r3 += a1×b2
-	MOVQ 8(CX), AX
-	MULQ 16(BX)
-	ADDQ AX, R13
-	ADCQ DX, R12
-
-	// r3 += a2×b1
-	MOVQ 16(CX), AX
-	MULQ 8(BX)
-	ADDQ AX, R13
-	ADCQ DX, R12
-
-	// r3 += a3×b0
-	MOVQ 24(CX), AX
-	MULQ (BX)
-	ADDQ AX, R13
-	ADCQ DX, R12
-
-	// r3 += 19×a4×b4
-	MOVQ   32(CX), AX
-	IMUL3Q $0x13, AX, AX
-	MULQ   32(BX)
-	ADDQ   AX, R13
-	ADCQ   DX, R12
-
-	// r4 = a0×b4
-	MOVQ (CX), AX
-	MULQ 32(BX)
-	MOVQ AX, R15
-	MOVQ DX, R14
-
-	// r4 += a1×b3
-	MOVQ 8(CX), AX
-	MULQ 24(BX)
-	ADDQ AX, R15
-	ADCQ DX, R14
-
-	// r4 += a2×b2
-	MOVQ 16(CX), AX
-	MULQ 16(BX)
-	ADDQ AX, R15
-	ADCQ DX, R14
-
-	// r4 += a3×b1
-	MOVQ 24(CX), AX
-	MULQ 8(BX)
-	ADDQ AX, R15
-	ADCQ DX, R14
-
-	// r4 += a4×b0
-	MOVQ 32(CX), AX
-	MULQ (BX)
-	ADDQ AX, R15
-	ADCQ DX, R14
-
-	// First reduction chain
-	MOVQ   $0x0007ffffffffffff, AX
-	SHLQ   $0x0d, DI, SI
-	SHLQ   $0x0d, R9, R8
-	SHLQ   $0x0d, R11, R10
-	SHLQ   $0x0d, R13, R12
-	SHLQ   $0x0d, R15, R14
-	ANDQ   AX, DI
-	IMUL3Q $0x13, R14, R14
-	ADDQ   R14, DI
-	ANDQ   AX, R9
-	ADDQ   SI, R9
-	ANDQ   AX, R11
-	ADDQ   R8, R11
-	ANDQ   AX, R13
-	ADDQ   R10, R13
-	ANDQ   AX, R15
-	ADDQ   R12, R15
-
-	// Second reduction chain (carryPropagate)
-	MOVQ   DI, SI
-	SHRQ   $0x33, SI
-	MOVQ   R9, R8
-	SHRQ   $0x33, R8
-	MOVQ   R11, R10
-	SHRQ   $0x33, R10
-	MOVQ   R13, R12
-	SHRQ   $0x33, R12
-	MOVQ   R15, R14
-	SHRQ   $0x33, R14
-	ANDQ   AX, DI
-	IMUL3Q $0x13, R14, R14
-	ADDQ   R14, DI
-	ANDQ   AX, R9
-	ADDQ   SI, R9
-	ANDQ   AX, R11
-	ADDQ   R8, R11
-	ANDQ   AX, R13
-	ADDQ   R10, R13
-	ANDQ   AX, R15
-	ADDQ   R12, R15
-
-	// Store output
-	MOVQ out+0(FP), AX
-	MOVQ DI, (AX)
-	MOVQ R9, 8(AX)
-	MOVQ R11, 16(AX)
-	MOVQ R13, 24(AX)
-	MOVQ R15, 32(AX)
-	RET
-
-// func feSquare(out *Element, a *Element)
-TEXT ·feSquare(SB), NOSPLIT, $0-16
-	MOVQ a+8(FP), CX
-
-	// r0 = l0×l0
-	MOVQ (CX), AX
-	MULQ (CX)
-	MOVQ AX, SI
-	MOVQ DX, BX
-
-	// r0 += 38×l1×l4
-	MOVQ   8(CX), AX
-	IMUL3Q $0x26, AX, AX
-	MULQ   32(CX)
-	ADDQ   AX, SI
-	ADCQ   DX, BX
-
-	// r0 += 38×l2×l3
-	MOVQ   16(CX), AX
-	IMUL3Q $0x26, AX, AX
-	MULQ   24(CX)
-	ADDQ   AX, SI
-	ADCQ   DX, BX
-
-	// r1 = 2×l0×l1
-	MOVQ (CX), AX
-	SHLQ $0x01, AX
-	MULQ 8(CX)
-	MOVQ AX, R8
-	MOVQ DX, DI
-
-	// r1 += 38×l2×l4
-	MOVQ   16(CX), AX
-	IMUL3Q $0x26, AX, AX
-	MULQ   32(CX)
-	ADDQ   AX, R8
-	ADCQ   DX, DI
-
-	// r1 += 19×l3×l3
-	MOVQ   24(CX), AX
-	IMUL3Q $0x13, AX, AX
-	MULQ   24(CX)
-	ADDQ   AX, R8
-	ADCQ   DX, DI
-
-	// r2 = 2×l0×l2
-	MOVQ (CX), AX
-	SHLQ $0x01, AX
-	MULQ 16(CX)
-	MOVQ AX, R10
-	MOVQ DX, R9
-
-	// r2 += l1×l1
-	MOVQ 8(CX), AX
-	MULQ 8(CX)
-	ADDQ AX, R10
-	ADCQ DX, R9
-
-	// r2 += 38×l3×l4
-	MOVQ   24(CX), AX
-	IMUL3Q $0x26, AX, AX
-	MULQ   32(CX)
-	ADDQ   AX, R10
-	ADCQ   DX, R9
-
-	// r3 = 2×l0×l3
-	MOVQ (CX), AX
-	SHLQ $0x01, AX
-	MULQ 24(CX)
-	MOVQ AX, R12
-	MOVQ DX, R11
-
-	// r3 += 2×l1×l2
-	MOVQ   8(CX), AX
-	IMUL3Q $0x02, AX, AX
-	MULQ   16(CX)
-	ADDQ   AX, R12
-	ADCQ   DX, R11
-
-	// r3 += 19×l4×l4
-	MOVQ   32(CX), AX
-	IMUL3Q $0x13, AX, AX
-	MULQ   32(CX)
-	ADDQ   AX, R12
-	ADCQ   DX, R11
-
-	// r4 = 2×l0×l4
-	MOVQ (CX), AX
-	SHLQ $0x01, AX
-	MULQ 32(CX)
-	MOVQ AX, R14
-	MOVQ DX, R13
-
-	// r4 += 2×l1×l3
-	MOVQ   8(CX), AX
-	IMUL3Q $0x02, AX, AX
-	MULQ   24(CX)
-	ADDQ   AX, R14
-	ADCQ   DX, R13
-
-	// r4 += l2×l2
-	MOVQ 16(CX), AX
-	MULQ 16(CX)
-	ADDQ AX, R14
-	ADCQ DX, R13
-
-	// First reduction chain
-	MOVQ   $0x0007ffffffffffff, AX
-	SHLQ   $0x0d, SI, BX
-	SHLQ   $0x0d, R8, DI
-	SHLQ   $0x0d, R10, R9
-	SHLQ   $0x0d, R12, R11
-	SHLQ   $0x0d, R14, R13
-	ANDQ   AX, SI
-	IMUL3Q $0x13, R13, R13
-	ADDQ   R13, SI
-	ANDQ   AX, R8
-	ADDQ   BX, R8
-	ANDQ   AX, R10
-	ADDQ   DI, R10
-	ANDQ   AX, R12
-	ADDQ   R9, R12
-	ANDQ   AX, R14
-	ADDQ   R11, R14
-
-	// Second reduction chain (carryPropagate)
-	MOVQ   SI, BX
-	SHRQ   $0x33, BX
-	MOVQ   R8, DI
-	SHRQ   $0x33, DI
-	MOVQ   R10, R9
-	SHRQ   $0x33, R9
-	MOVQ   R12, R11
-	SHRQ   $0x33, R11
-	MOVQ   R14, R13
-	SHRQ   $0x33, R13
-	ANDQ   AX, SI
-	IMUL3Q $0x13, R13, R13
-	ADDQ   R13, SI
-	ANDQ   AX, R8
-	ADDQ   BX, R8
-	ANDQ   AX, R10
-	ADDQ   DI, R10
-	ANDQ   AX, R12
-	ADDQ   R9, R12
-	ANDQ   AX, R14
-	ADDQ   R11, R14
-
-	// Store output
-	MOVQ out+0(FP), AX
-	MOVQ SI, (AX)
-	MOVQ R8, 8(AX)
-	MOVQ R10, 16(AX)
-	MOVQ R12, 24(AX)
-	MOVQ R14, 32(AX)
-	RET
diff --git a/src/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64_noasm.go b/src/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64_noasm.go
deleted file mode 100644
index ddb6c9b..0000000
--- a/src/vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64_noasm.go
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build !amd64 || !gc || purego
-// +build !amd64 !gc purego
-
-package field
-
-func feMul(v, x, y *Element) { feMulGeneric(v, x, y) }
-
-func feSquare(v, x *Element) { feSquareGeneric(v, x) }
diff --git a/src/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.go b/src/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.go
deleted file mode 100644
index af459ef..0000000
--- a/src/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build arm64 && gc && !purego
-// +build arm64,gc,!purego
-
-package field
-
-//go:noescape
-func carryPropagate(v *Element)
-
-func (v *Element) carryPropagate() *Element {
-	carryPropagate(v)
-	return v
-}
diff --git a/src/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.s b/src/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.s
deleted file mode 100644
index 5c91e45..0000000
--- a/src/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64.s
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (c) 2020 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build arm64 && gc && !purego
-// +build arm64,gc,!purego
-
-#include "textflag.h"
-
-// carryPropagate works exactly like carryPropagateGeneric and uses the
-// same AND, ADD, and LSR+MADD instructions emitted by the compiler, but
-// avoids loading R0-R4 twice and uses LDP and STP.
-//
-// See https://golang.org/issues/43145 for the main compiler issue.
-//
-// func carryPropagate(v *Element)
-TEXT ·carryPropagate(SB),NOFRAME|NOSPLIT,$0-8
-	MOVD v+0(FP), R20
-
-	LDP 0(R20), (R0, R1)
-	LDP 16(R20), (R2, R3)
-	MOVD 32(R20), R4
-
-	AND $0x7ffffffffffff, R0, R10
-	AND $0x7ffffffffffff, R1, R11
-	AND $0x7ffffffffffff, R2, R12
-	AND $0x7ffffffffffff, R3, R13
-	AND $0x7ffffffffffff, R4, R14
-
-	ADD R0>>51, R11, R11
-	ADD R1>>51, R12, R12
-	ADD R2>>51, R13, R13
-	ADD R3>>51, R14, R14
-	// R4>>51 * 19 + R10 -> R10
-	LSR $51, R4, R21
-	MOVD $19, R22
-	MADD R22, R10, R21, R10
-
-	STP (R10, R11), 0(R20)
-	STP (R12, R13), 16(R20)
-	MOVD R14, 32(R20)
-
-	RET
diff --git a/src/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64_noasm.go b/src/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64_noasm.go
deleted file mode 100644
index 234a5b2..0000000
--- a/src/vendor/golang.org/x/crypto/curve25519/internal/field/fe_arm64_noasm.go
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build !arm64 || !gc || purego
-// +build !arm64 !gc purego
-
-package field
-
-func (v *Element) carryPropagate() *Element {
-	return v.carryPropagateGeneric()
-}
diff --git a/src/vendor/golang.org/x/crypto/curve25519/internal/field/fe_generic.go b/src/vendor/golang.org/x/crypto/curve25519/internal/field/fe_generic.go
deleted file mode 100644
index 7b5b78c..0000000
--- a/src/vendor/golang.org/x/crypto/curve25519/internal/field/fe_generic.go
+++ /dev/null
@@ -1,264 +0,0 @@
-// Copyright (c) 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package field
-
-import "math/bits"
-
-// uint128 holds a 128-bit number as two 64-bit limbs, for use with the
-// bits.Mul64 and bits.Add64 intrinsics.
-type uint128 struct {
-	lo, hi uint64
-}
-
-// mul64 returns a * b.
-func mul64(a, b uint64) uint128 {
-	hi, lo := bits.Mul64(a, b)
-	return uint128{lo, hi}
-}
-
-// addMul64 returns v + a * b.
-func addMul64(v uint128, a, b uint64) uint128 {
-	hi, lo := bits.Mul64(a, b)
-	lo, c := bits.Add64(lo, v.lo, 0)
-	hi, _ = bits.Add64(hi, v.hi, c)
-	return uint128{lo, hi}
-}
-
-// shiftRightBy51 returns a >> 51. a is assumed to be at most 115 bits.
-func shiftRightBy51(a uint128) uint64 {
-	return (a.hi << (64 - 51)) | (a.lo >> 51)
-}
-
-func feMulGeneric(v, a, b *Element) {
-	a0 := a.l0
-	a1 := a.l1
-	a2 := a.l2
-	a3 := a.l3
-	a4 := a.l4
-
-	b0 := b.l0
-	b1 := b.l1
-	b2 := b.l2
-	b3 := b.l3
-	b4 := b.l4
-
-	// Limb multiplication works like pen-and-paper columnar multiplication, but
-	// with 51-bit limbs instead of digits.
-	//
-	//                          a4   a3   a2   a1   a0  x
-	//                          b4   b3   b2   b1   b0  =
-	//                         ------------------------
-	//                        a4b0 a3b0 a2b0 a1b0 a0b0  +
-	//                   a4b1 a3b1 a2b1 a1b1 a0b1       +
-	//              a4b2 a3b2 a2b2 a1b2 a0b2            +
-	//         a4b3 a3b3 a2b3 a1b3 a0b3                 +
-	//    a4b4 a3b4 a2b4 a1b4 a0b4                      =
-	//   ----------------------------------------------
-	//      r8   r7   r6   r5   r4   r3   r2   r1   r0
-	//
-	// We can then use the reduction identity (a * 2²⁵⁵ + b = a * 19 + b) to
-	// reduce the limbs that would overflow 255 bits. r5 * 2²⁵⁵ becomes 19 * r5,
-	// r6 * 2³⁰⁶ becomes 19 * r6 * 2⁵¹, etc.
-	//
-	// Reduction can be carried out simultaneously to multiplication. For
-	// example, we do not compute r5: whenever the result of a multiplication
-	// belongs to r5, like a1b4, we multiply it by 19 and add the result to r0.
-	//
-	//            a4b0    a3b0    a2b0    a1b0    a0b0  +
-	//            a3b1    a2b1    a1b1    a0b1 19×a4b1  +
-	//            a2b2    a1b2    a0b2 19×a4b2 19×a3b2  +
-	//            a1b3    a0b3 19×a4b3 19×a3b3 19×a2b3  +
-	//            a0b4 19×a4b4 19×a3b4 19×a2b4 19×a1b4  =
-	//           --------------------------------------
-	//              r4      r3      r2      r1      r0
-	//
-	// Finally we add up the columns into wide, overlapping limbs.
-
-	a1_19 := a1 * 19
-	a2_19 := a2 * 19
-	a3_19 := a3 * 19
-	a4_19 := a4 * 19
-
-	// r0 = a0×b0 + 19×(a1×b4 + a2×b3 + a3×b2 + a4×b1)
-	r0 := mul64(a0, b0)
-	r0 = addMul64(r0, a1_19, b4)
-	r0 = addMul64(r0, a2_19, b3)
-	r0 = addMul64(r0, a3_19, b2)
-	r0 = addMul64(r0, a4_19, b1)
-
-	// r1 = a0×b1 + a1×b0 + 19×(a2×b4 + a3×b3 + a4×b2)
-	r1 := mul64(a0, b1)
-	r1 = addMul64(r1, a1, b0)
-	r1 = addMul64(r1, a2_19, b4)
-	r1 = addMul64(r1, a3_19, b3)
-	r1 = addMul64(r1, a4_19, b2)
-
-	// r2 = a0×b2 + a1×b1 + a2×b0 + 19×(a3×b4 + a4×b3)
-	r2 := mul64(a0, b2)
-	r2 = addMul64(r2, a1, b1)
-	r2 = addMul64(r2, a2, b0)
-	r2 = addMul64(r2, a3_19, b4)
-	r2 = addMul64(r2, a4_19, b3)
-
-	// r3 = a0×b3 + a1×b2 + a2×b1 + a3×b0 + 19×a4×b4
-	r3 := mul64(a0, b3)
-	r3 = addMul64(r3, a1, b2)
-	r3 = addMul64(r3, a2, b1)
-	r3 = addMul64(r3, a3, b0)
-	r3 = addMul64(r3, a4_19, b4)
-
-	// r4 = a0×b4 + a1×b3 + a2×b2 + a3×b1 + a4×b0
-	r4 := mul64(a0, b4)
-	r4 = addMul64(r4, a1, b3)
-	r4 = addMul64(r4, a2, b2)
-	r4 = addMul64(r4, a3, b1)
-	r4 = addMul64(r4, a4, b0)
-
-	// After the multiplication, we need to reduce (carry) the five coefficients
-	// to obtain a result with limbs that are at most slightly larger than 2⁵¹,
-	// to respect the Element invariant.
-	//
-	// Overall, the reduction works the same as carryPropagate, except with
-	// wider inputs: we take the carry for each coefficient by shifting it right
-	// by 51, and add it to the limb above it. The top carry is multiplied by 19
-	// according to the reduction identity and added to the lowest limb.
-	//
-	// The largest coefficient (r0) will be at most 111 bits, which guarantees
-	// that all carries are at most 111 - 51 = 60 bits, which fits in a uint64.
-	//
-	//     r0 = a0×b0 + 19×(a1×b4 + a2×b3 + a3×b2 + a4×b1)
-	//     r0 < 2⁵²×2⁵² + 19×(2⁵²×2⁵² + 2⁵²×2⁵² + 2⁵²×2⁵² + 2⁵²×2⁵²)
-	//     r0 < (1 + 19 × 4) × 2⁵² × 2⁵²
-	//     r0 < 2⁷ × 2⁵² × 2⁵²
-	//     r0 < 2¹¹¹
-	//
-	// Moreover, the top coefficient (r4) is at most 107 bits, so c4 is at most
-	// 56 bits, and c4 * 19 is at most 61 bits, which again fits in a uint64 and
-	// allows us to easily apply the reduction identity.
-	//
-	//     r4 = a0×b4 + a1×b3 + a2×b2 + a3×b1 + a4×b0
-	//     r4 < 5 × 2⁵² × 2⁵²
-	//     r4 < 2¹⁰⁷
-	//
-
-	c0 := shiftRightBy51(r0)
-	c1 := shiftRightBy51(r1)
-	c2 := shiftRightBy51(r2)
-	c3 := shiftRightBy51(r3)
-	c4 := shiftRightBy51(r4)
-
-	rr0 := r0.lo&maskLow51Bits + c4*19
-	rr1 := r1.lo&maskLow51Bits + c0
-	rr2 := r2.lo&maskLow51Bits + c1
-	rr3 := r3.lo&maskLow51Bits + c2
-	rr4 := r4.lo&maskLow51Bits + c3
-
-	// Now all coefficients fit into 64-bit registers but are still too large to
-	// be passed around as a Element. We therefore do one last carry chain,
-	// where the carries will be small enough to fit in the wiggle room above 2⁵¹.
-	*v = Element{rr0, rr1, rr2, rr3, rr4}
-	v.carryPropagate()
-}
-
-func feSquareGeneric(v, a *Element) {
-	l0 := a.l0
-	l1 := a.l1
-	l2 := a.l2
-	l3 := a.l3
-	l4 := a.l4
-
-	// Squaring works precisely like multiplication above, but thanks to its
-	// symmetry we get to group a few terms together.
-	//
-	//                          l4   l3   l2   l1   l0  x
-	//                          l4   l3   l2   l1   l0  =
-	//                         ------------------------
-	//                        l4l0 l3l0 l2l0 l1l0 l0l0  +
-	//                   l4l1 l3l1 l2l1 l1l1 l0l1       +
-	//              l4l2 l3l2 l2l2 l1l2 l0l2            +
-	//         l4l3 l3l3 l2l3 l1l3 l0l3                 +
-	//    l4l4 l3l4 l2l4 l1l4 l0l4                      =
-	//   ----------------------------------------------
-	//      r8   r7   r6   r5   r4   r3   r2   r1   r0
-	//
-	//            l4l0    l3l0    l2l0    l1l0    l0l0  +
-	//            l3l1    l2l1    l1l1    l0l1 19×l4l1  +
-	//            l2l2    l1l2    l0l2 19×l4l2 19×l3l2  +
-	//            l1l3    l0l3 19×l4l3 19×l3l3 19×l2l3  +
-	//            l0l4 19×l4l4 19×l3l4 19×l2l4 19×l1l4  =
-	//           --------------------------------------
-	//              r4      r3      r2      r1      r0
-	//
-	// With precomputed 2×, 19×, and 2×19× terms, we can compute each limb with
-	// only three Mul64 and four Add64, instead of five and eight.
-
-	l0_2 := l0 * 2
-	l1_2 := l1 * 2
-
-	l1_38 := l1 * 38
-	l2_38 := l2 * 38
-	l3_38 := l3 * 38
-
-	l3_19 := l3 * 19
-	l4_19 := l4 * 19
-
-	// r0 = l0×l0 + 19×(l1×l4 + l2×l3 + l3×l2 + l4×l1) = l0×l0 + 19×2×(l1×l4 + l2×l3)
-	r0 := mul64(l0, l0)
-	r0 = addMul64(r0, l1_38, l4)
-	r0 = addMul64(r0, l2_38, l3)
-
-	// r1 = l0×l1 + l1×l0 + 19×(l2×l4 + l3×l3 + l4×l2) = 2×l0×l1 + 19×2×l2×l4 + 19×l3×l3
-	r1 := mul64(l0_2, l1)
-	r1 = addMul64(r1, l2_38, l4)
-	r1 = addMul64(r1, l3_19, l3)
-
-	// r2 = l0×l2 + l1×l1 + l2×l0 + 19×(l3×l4 + l4×l3) = 2×l0×l2 + l1×l1 + 19×2×l3×l4
-	r2 := mul64(l0_2, l2)
-	r2 = addMul64(r2, l1, l1)
-	r2 = addMul64(r2, l3_38, l4)
-
-	// r3 = l0×l3 + l1×l2 + l2×l1 + l3×l0 + 19×l4×l4 = 2×l0×l3 + 2×l1×l2 + 19×l4×l4
-	r3 := mul64(l0_2, l3)
-	r3 = addMul64(r3, l1_2, l2)
-	r3 = addMul64(r3, l4_19, l4)
-
-	// r4 = l0×l4 + l1×l3 + l2×l2 + l3×l1 + l4×l0 = 2×l0×l4 + 2×l1×l3 + l2×l2
-	r4 := mul64(l0_2, l4)
-	r4 = addMul64(r4, l1_2, l3)
-	r4 = addMul64(r4, l2, l2)
-
-	c0 := shiftRightBy51(r0)
-	c1 := shiftRightBy51(r1)
-	c2 := shiftRightBy51(r2)
-	c3 := shiftRightBy51(r3)
-	c4 := shiftRightBy51(r4)
-
-	rr0 := r0.lo&maskLow51Bits + c4*19
-	rr1 := r1.lo&maskLow51Bits + c0
-	rr2 := r2.lo&maskLow51Bits + c1
-	rr3 := r3.lo&maskLow51Bits + c2
-	rr4 := r4.lo&maskLow51Bits + c3
-
-	*v = Element{rr0, rr1, rr2, rr3, rr4}
-	v.carryPropagate()
-}
-
-// carryPropagate brings the limbs below 52 bits by applying the reduction
-// identity (a * 2²⁵⁵ + b = a * 19 + b) to the l4 carry. TODO inline
-func (v *Element) carryPropagateGeneric() *Element {
-	c0 := v.l0 >> 51
-	c1 := v.l1 >> 51
-	c2 := v.l2 >> 51
-	c3 := v.l3 >> 51
-	c4 := v.l4 >> 51
-
-	v.l0 = v.l0&maskLow51Bits + c4*19
-	v.l1 = v.l1&maskLow51Bits + c0
-	v.l2 = v.l2&maskLow51Bits + c1
-	v.l3 = v.l3&maskLow51Bits + c2
-	v.l4 = v.l4&maskLow51Bits + c3
-
-	return v
-}
diff --git a/src/vendor/golang.org/x/crypto/curve25519/internal/field/sync.checkpoint b/src/vendor/golang.org/x/crypto/curve25519/internal/field/sync.checkpoint
deleted file mode 100644
index e3685f9..0000000
--- a/src/vendor/golang.org/x/crypto/curve25519/internal/field/sync.checkpoint
+++ /dev/null
@@ -1 +0,0 @@
-b0c49ae9f59d233526f8934262c5bbbe14d4358d
diff --git a/src/vendor/golang.org/x/crypto/curve25519/internal/field/sync.sh b/src/vendor/golang.org/x/crypto/curve25519/internal/field/sync.sh
deleted file mode 100644
index 1ba22a8..0000000
--- a/src/vendor/golang.org/x/crypto/curve25519/internal/field/sync.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#! /bin/bash
-set -euo pipefail
-
-cd "$(git rev-parse --show-toplevel)"
-
-STD_PATH=src/crypto/ed25519/internal/edwards25519/field
-LOCAL_PATH=curve25519/internal/field
-LAST_SYNC_REF=$(cat $LOCAL_PATH/sync.checkpoint)
-
-git fetch https://go.googlesource.com/go master
-
-if git diff --quiet $LAST_SYNC_REF:$STD_PATH FETCH_HEAD:$STD_PATH; then
-    echo "No changes."
-else
-    NEW_REF=$(git rev-parse FETCH_HEAD | tee $LOCAL_PATH/sync.checkpoint)
-    echo "Applying changes from $LAST_SYNC_REF to $NEW_REF..."
-    git diff $LAST_SYNC_REF:$STD_PATH FETCH_HEAD:$STD_PATH | \
-        git apply -3 --directory=$LOCAL_PATH
-fi
diff --git a/src/vendor/golang.org/x/crypto/internal/alias/alias.go b/src/vendor/golang.org/x/crypto/internal/alias/alias.go
new file mode 100644
index 0000000..69c17f8
--- /dev/null
+++ b/src/vendor/golang.org/x/crypto/internal/alias/alias.go
@@ -0,0 +1,32 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !purego
+// +build !purego
+
+// Package alias implements memory aliasing tests.
+package alias
+
+import "unsafe"
+
+// AnyOverlap reports whether x and y share memory at any (not necessarily
+// corresponding) index. The memory beyond the slice length is ignored.
+func AnyOverlap(x, y []byte) bool {
+	return len(x) > 0 && len(y) > 0 &&
+		uintptr(unsafe.Pointer(&x[0])) <= uintptr(unsafe.Pointer(&y[len(y)-1])) &&
+		uintptr(unsafe.Pointer(&y[0])) <= uintptr(unsafe.Pointer(&x[len(x)-1]))
+}
+
+// InexactOverlap reports whether x and y share memory at any non-corresponding
+// index. The memory beyond the slice length is ignored. Note that x and y can
+// have different lengths and still not have any inexact overlap.
+//
+// InexactOverlap can be used to implement the requirements of the crypto/cipher
+// AEAD, Block, BlockMode and Stream interfaces.
+func InexactOverlap(x, y []byte) bool {
+	if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] {
+		return false
+	}
+	return AnyOverlap(x, y)
+}
diff --git a/src/vendor/golang.org/x/crypto/internal/alias/alias_purego.go b/src/vendor/golang.org/x/crypto/internal/alias/alias_purego.go
new file mode 100644
index 0000000..4775b0a
--- /dev/null
+++ b/src/vendor/golang.org/x/crypto/internal/alias/alias_purego.go
@@ -0,0 +1,35 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build purego
+// +build purego
+
+// Package alias implements memory aliasing tests.
+package alias
+
+// This is the Google App Engine standard variant based on reflect
+// because the unsafe package and cgo are disallowed.
+
+import "reflect"
+
+// AnyOverlap reports whether x and y share memory at any (not necessarily
+// corresponding) index. The memory beyond the slice length is ignored.
+func AnyOverlap(x, y []byte) bool {
+	return len(x) > 0 && len(y) > 0 &&
+		reflect.ValueOf(&x[0]).Pointer() <= reflect.ValueOf(&y[len(y)-1]).Pointer() &&
+		reflect.ValueOf(&y[0]).Pointer() <= reflect.ValueOf(&x[len(x)-1]).Pointer()
+}
+
+// InexactOverlap reports whether x and y share memory at any non-corresponding
+// index. The memory beyond the slice length is ignored. Note that x and y can
+// have different lengths and still not have any inexact overlap.
+//
+// InexactOverlap can be used to implement the requirements of the crypto/cipher
+// AEAD, Block, BlockMode and Stream interfaces.
+func InexactOverlap(x, y []byte) bool {
+	if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] {
+		return false
+	}
+	return AnyOverlap(x, y)
+}
diff --git a/src/vendor/golang.org/x/crypto/internal/subtle/aliasing.go b/src/vendor/golang.org/x/crypto/internal/subtle/aliasing.go
deleted file mode 100644
index 4fad24f..0000000
--- a/src/vendor/golang.org/x/crypto/internal/subtle/aliasing.go
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build !purego
-// +build !purego
-
-// Package subtle implements functions that are often useful in cryptographic
-// code but require careful thought to use correctly.
-package subtle // import "golang.org/x/crypto/internal/subtle"
-
-import "unsafe"
-
-// AnyOverlap reports whether x and y share memory at any (not necessarily
-// corresponding) index. The memory beyond the slice length is ignored.
-func AnyOverlap(x, y []byte) bool {
-	return len(x) > 0 && len(y) > 0 &&
-		uintptr(unsafe.Pointer(&x[0])) <= uintptr(unsafe.Pointer(&y[len(y)-1])) &&
-		uintptr(unsafe.Pointer(&y[0])) <= uintptr(unsafe.Pointer(&x[len(x)-1]))
-}
-
-// InexactOverlap reports whether x and y share memory at any non-corresponding
-// index. The memory beyond the slice length is ignored. Note that x and y can
-// have different lengths and still not have any inexact overlap.
-//
-// InexactOverlap can be used to implement the requirements of the crypto/cipher
-// AEAD, Block, BlockMode and Stream interfaces.
-func InexactOverlap(x, y []byte) bool {
-	if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] {
-		return false
-	}
-	return AnyOverlap(x, y)
-}
diff --git a/src/vendor/golang.org/x/crypto/internal/subtle/aliasing_purego.go b/src/vendor/golang.org/x/crypto/internal/subtle/aliasing_purego.go
deleted file mode 100644
index 80ccbed..0000000
--- a/src/vendor/golang.org/x/crypto/internal/subtle/aliasing_purego.go
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build purego
-// +build purego
-
-// Package subtle implements functions that are often useful in cryptographic
-// code but require careful thought to use correctly.
-package subtle // import "golang.org/x/crypto/internal/subtle"
-
-// This is the Google App Engine standard variant based on reflect
-// because the unsafe package and cgo are disallowed.
-
-import "reflect"
-
-// AnyOverlap reports whether x and y share memory at any (not necessarily
-// corresponding) index. The memory beyond the slice length is ignored.
-func AnyOverlap(x, y []byte) bool {
-	return len(x) > 0 && len(y) > 0 &&
-		reflect.ValueOf(&x[0]).Pointer() <= reflect.ValueOf(&y[len(y)-1]).Pointer() &&
-		reflect.ValueOf(&y[0]).Pointer() <= reflect.ValueOf(&x[len(x)-1]).Pointer()
-}
-
-// InexactOverlap reports whether x and y share memory at any non-corresponding
-// index. The memory beyond the slice length is ignored. Note that x and y can
-// have different lengths and still not have any inexact overlap.
-//
-// InexactOverlap can be used to implement the requirements of the crypto/cipher
-// AEAD, Block, BlockMode and Stream interfaces.
-func InexactOverlap(x, y []byte) bool {
-	if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] {
-		return false
-	}
-	return AnyOverlap(x, y)
-}
diff --git a/src/vendor/golang.org/x/net/AUTHORS b/src/vendor/golang.org/x/net/AUTHORS
deleted file mode 100644
index 15167cd..0000000
--- a/src/vendor/golang.org/x/net/AUTHORS
+++ /dev/null
@@ -1,3 +0,0 @@
-# This source code refers to The Go Authors for copyright purposes.
-# The master list of authors is in the main Go distribution,
-# visible at http://tip.golang.org/AUTHORS.
diff --git a/src/vendor/golang.org/x/net/CONTRIBUTORS b/src/vendor/golang.org/x/net/CONTRIBUTORS
deleted file mode 100644
index 1c4577e..0000000
--- a/src/vendor/golang.org/x/net/CONTRIBUTORS
+++ /dev/null
@@ -1,3 +0,0 @@
-# This source code was written by the Go contributors.
-# The master list of contributors is in the main Go distribution,
-# visible at http://tip.golang.org/CONTRIBUTORS.
diff --git a/src/vendor/golang.org/x/net/dns/dnsmessage/message.go b/src/vendor/golang.org/x/net/dns/dnsmessage/message.go
index 0cdf89f..ffdf19d 100644
--- a/src/vendor/golang.org/x/net/dns/dnsmessage/message.go
+++ b/src/vendor/golang.org/x/net/dns/dnsmessage/message.go
@@ -317,6 +317,8 @@
 	Truncated          bool
 	RecursionDesired   bool
 	RecursionAvailable bool
+	AuthenticData      bool
+	CheckingDisabled   bool
 	RCode              RCode
 }
 
@@ -338,6 +340,12 @@
 	if m.Response {
 		bits |= headerBitQR
 	}
+	if m.AuthenticData {
+		bits |= headerBitAD
+	}
+	if m.CheckingDisabled {
+		bits |= headerBitCD
+	}
 	return
 }
 
@@ -379,6 +387,8 @@
 	headerBitTC = 1 << 9  // truncated
 	headerBitRD = 1 << 8  // recursion desired
 	headerBitRA = 1 << 7  // recursion available
+	headerBitAD = 1 << 5  // authentic data
+	headerBitCD = 1 << 4  // checking disabled
 )
 
 var sectionNames = map[section]string{
@@ -456,6 +466,8 @@
 		Truncated:          (h.bits & headerBitTC) != 0,
 		RecursionDesired:   (h.bits & headerBitRD) != 0,
 		RecursionAvailable: (h.bits & headerBitRA) != 0,
+		AuthenticData:      (h.bits & headerBitAD) != 0,
+		CheckingDisabled:   (h.bits & headerBitCD) != 0,
 		RCode:              RCode(h.bits & 0xF),
 	}
 }
@@ -1887,11 +1899,11 @@
 
 // NewName creates a new Name from a string.
 func NewName(name string) (Name, error) {
-	if len([]byte(name)) > nameLen {
+	if len(name) > nameLen {
 		return Name{}, errCalcLen
 	}
 	n := Name{Length: uint8(len(name))}
-	copy(n.Data[:], []byte(name))
+	copy(n.Data[:], name)
 	return n, nil
 }
 
diff --git a/src/vendor/golang.org/x/net/http/httpproxy/proxy.go b/src/vendor/golang.org/x/net/http/httpproxy/proxy.go
index 16994ac..c3bd9a1 100644
--- a/src/vendor/golang.org/x/net/http/httpproxy/proxy.go
+++ b/src/vendor/golang.org/x/net/http/httpproxy/proxy.go
@@ -81,8 +81,7 @@
 
 // FromEnvironment returns a Config instance populated from the
 // environment variables HTTP_PROXY, HTTPS_PROXY and NO_PROXY (or the
-// lowercase versions thereof). HTTPS_PROXY takes precedence over
-// HTTP_PROXY for https requests.
+// lowercase versions thereof).
 //
 // The environment values may be either a complete URL or a
 // "host[:port]", in which case the "http" scheme is assumed. An error
diff --git a/src/vendor/golang.org/x/net/http2/hpack/encode.go b/src/vendor/golang.org/x/net/http2/hpack/encode.go
index 97f1783..46219da 100644
--- a/src/vendor/golang.org/x/net/http2/hpack/encode.go
+++ b/src/vendor/golang.org/x/net/http2/hpack/encode.go
@@ -116,6 +116,11 @@
 	e.dynTab.setMaxSize(v)
 }
 
+// MaxDynamicTableSize returns the current dynamic header table size.
+func (e *Encoder) MaxDynamicTableSize() (v uint32) {
+	return e.dynTab.maxSize
+}
+
 // SetMaxDynamicTableSizeLimit changes the maximum value that can be
 // specified in SetMaxDynamicTableSize to v. By default, it is set to
 // 4096, which is the same size of the default dynamic header table
@@ -191,7 +196,7 @@
 // bit prefix, to dst and returns the extended buffer.
 //
 // See
-// http://http2.github.io/http2-spec/compression.html#integer.representation
+// https://httpwg.org/specs/rfc7541.html#integer.representation
 func appendVarInt(dst []byte, n byte, i uint64) []byte {
 	k := uint64((1 << n) - 1)
 	if i < k {
diff --git a/src/vendor/golang.org/x/net/http2/hpack/hpack.go b/src/vendor/golang.org/x/net/http2/hpack/hpack.go
index 85f18a2..fe52df9 100644
--- a/src/vendor/golang.org/x/net/http2/hpack/hpack.go
+++ b/src/vendor/golang.org/x/net/http2/hpack/hpack.go
@@ -59,7 +59,7 @@
 
 // Size returns the size of an entry per RFC 7541 section 4.1.
 func (hf HeaderField) Size() uint32 {
-	// http://http2.github.io/http2-spec/compression.html#rfc.section.4.1
+	// https://httpwg.org/specs/rfc7541.html#rfc.section.4.1
 	// "The size of the dynamic table is the sum of the size of
 	// its entries. The size of an entry is the sum of its name's
 	// length in octets (as defined in Section 5.2), its value's
@@ -158,7 +158,7 @@
 }
 
 type dynamicTable struct {
-	// http://http2.github.io/http2-spec/compression.html#rfc.section.2.3.2
+	// https://httpwg.org/specs/rfc7541.html#rfc.section.2.3.2
 	table          headerFieldTable
 	size           uint32 // in bytes
 	maxSize        uint32 // current maxSize
@@ -307,27 +307,27 @@
 	case b&128 != 0:
 		// Indexed representation.
 		// High bit set?
-		// http://http2.github.io/http2-spec/compression.html#rfc.section.6.1
+		// https://httpwg.org/specs/rfc7541.html#rfc.section.6.1
 		return d.parseFieldIndexed()
 	case b&192 == 64:
 		// 6.2.1 Literal Header Field with Incremental Indexing
 		// 0b10xxxxxx: top two bits are 10
-		// http://http2.github.io/http2-spec/compression.html#rfc.section.6.2.1
+		// https://httpwg.org/specs/rfc7541.html#rfc.section.6.2.1
 		return d.parseFieldLiteral(6, indexedTrue)
 	case b&240 == 0:
 		// 6.2.2 Literal Header Field without Indexing
 		// 0b0000xxxx: top four bits are 0000
-		// http://http2.github.io/http2-spec/compression.html#rfc.section.6.2.2
+		// https://httpwg.org/specs/rfc7541.html#rfc.section.6.2.2
 		return d.parseFieldLiteral(4, indexedFalse)
 	case b&240 == 16:
 		// 6.2.3 Literal Header Field never Indexed
 		// 0b0001xxxx: top four bits are 0001
-		// http://http2.github.io/http2-spec/compression.html#rfc.section.6.2.3
+		// https://httpwg.org/specs/rfc7541.html#rfc.section.6.2.3
 		return d.parseFieldLiteral(4, indexedNever)
 	case b&224 == 32:
 		// 6.3 Dynamic Table Size Update
 		// Top three bits are '001'.
-		// http://http2.github.io/http2-spec/compression.html#rfc.section.6.3
+		// https://httpwg.org/specs/rfc7541.html#rfc.section.6.3
 		return d.parseDynamicTableSizeUpdate()
 	}
 
@@ -359,6 +359,7 @@
 
 	var hf HeaderField
 	wantStr := d.emitEnabled || it.indexed()
+	var undecodedName undecodedString
 	if nameIdx > 0 {
 		ihf, ok := d.at(nameIdx)
 		if !ok {
@@ -366,15 +367,27 @@
 		}
 		hf.Name = ihf.Name
 	} else {
-		hf.Name, buf, err = d.readString(buf, wantStr)
+		undecodedName, buf, err = d.readString(buf)
 		if err != nil {
 			return err
 		}
 	}
-	hf.Value, buf, err = d.readString(buf, wantStr)
+	undecodedValue, buf, err := d.readString(buf)
 	if err != nil {
 		return err
 	}
+	if wantStr {
+		if nameIdx <= 0 {
+			hf.Name, err = d.decodeString(undecodedName)
+			if err != nil {
+				return err
+			}
+		}
+		hf.Value, err = d.decodeString(undecodedValue)
+		if err != nil {
+			return err
+		}
+	}
 	d.buf = buf
 	if it.indexed() {
 		d.dynTab.add(hf)
@@ -420,7 +433,7 @@
 
 // readVarInt reads an unsigned variable length integer off the
 // beginning of p. n is the parameter as described in
-// http://http2.github.io/http2-spec/compression.html#rfc.section.5.1.
+// https://httpwg.org/specs/rfc7541.html#rfc.section.5.1.
 //
 // n must always be between 1 and 8.
 //
@@ -459,46 +472,52 @@
 	return 0, origP, errNeedMore
 }
 
-// readString decodes an hpack string from p.
+// readString reads an hpack string from p.
 //
-// wantStr is whether s will be used. If false, decompression and
-// []byte->string garbage are skipped if s will be ignored
-// anyway. This does mean that huffman decoding errors for non-indexed
-// strings past the MAX_HEADER_LIST_SIZE are ignored, but the server
-// is returning an error anyway, and because they're not indexed, the error
-// won't affect the decoding state.
-func (d *Decoder) readString(p []byte, wantStr bool) (s string, remain []byte, err error) {
+// It returns a reference to the encoded string data to permit deferring decode costs
+// until after the caller verifies all data is present.
+func (d *Decoder) readString(p []byte) (u undecodedString, remain []byte, err error) {
 	if len(p) == 0 {
-		return "", p, errNeedMore
+		return u, p, errNeedMore
 	}
 	isHuff := p[0]&128 != 0
 	strLen, p, err := readVarInt(7, p)
 	if err != nil {
-		return "", p, err
+		return u, p, err
 	}
 	if d.maxStrLen != 0 && strLen > uint64(d.maxStrLen) {
-		return "", nil, ErrStringLength
+		// Returning an error here means Huffman decoding errors
+		// for non-indexed strings past the maximum string length
+		// are ignored, but the server is returning an error anyway
+		// and because the string is not indexed the error will not
+		// affect the decoding state.
+		return u, nil, ErrStringLength
 	}
 	if uint64(len(p)) < strLen {
-		return "", p, errNeedMore
+		return u, p, errNeedMore
 	}
-	if !isHuff {
-		if wantStr {
-			s = string(p[:strLen])
-		}
-		return s, p[strLen:], nil
-	}
+	u.isHuff = isHuff
+	u.b = p[:strLen]
+	return u, p[strLen:], nil
+}
 
-	if wantStr {
-		buf := bufPool.Get().(*bytes.Buffer)
-		buf.Reset() // don't trust others
-		defer bufPool.Put(buf)
-		if err := huffmanDecode(buf, d.maxStrLen, p[:strLen]); err != nil {
-			buf.Reset()
-			return "", nil, err
-		}
-		s = buf.String()
-		buf.Reset() // be nice to GC
+type undecodedString struct {
+	isHuff bool
+	b      []byte
+}
+
+func (d *Decoder) decodeString(u undecodedString) (string, error) {
+	if !u.isHuff {
+		return string(u.b), nil
 	}
-	return s, p[strLen:], nil
+	buf := bufPool.Get().(*bytes.Buffer)
+	buf.Reset() // don't trust others
+	var s string
+	err := huffmanDecode(buf, d.maxStrLen, u.b)
+	if err == nil {
+		s = buf.String()
+	}
+	buf.Reset() // be nice to GC
+	bufPool.Put(buf)
+	return s, err
 }
diff --git a/src/vendor/golang.org/x/net/http2/hpack/huffman.go b/src/vendor/golang.org/x/net/http2/hpack/huffman.go
index fe0b84c..20d083a 100644
--- a/src/vendor/golang.org/x/net/http2/hpack/huffman.go
+++ b/src/vendor/golang.org/x/net/http2/hpack/huffman.go
@@ -169,25 +169,50 @@
 // AppendHuffmanString appends s, as encoded in Huffman codes, to dst
 // and returns the extended buffer.
 func AppendHuffmanString(dst []byte, s string) []byte {
-	rembits := uint8(8)
-
+	// This relies on the maximum huffman code length being 30 (See tables.go huffmanCodeLen array)
+	// So if a uint64 buffer has less than 32 valid bits can always accommodate another huffmanCode.
+	var (
+		x uint64 // buffer
+		n uint   // number valid of bits present in x
+	)
 	for i := 0; i < len(s); i++ {
-		if rembits == 8 {
-			dst = append(dst, 0)
+		c := s[i]
+		n += uint(huffmanCodeLen[c])
+		x <<= huffmanCodeLen[c] % 64
+		x |= uint64(huffmanCodes[c])
+		if n >= 32 {
+			n %= 32             // Normally would be -= 32 but %= 32 informs compiler 0 <= n <= 31 for upcoming shift
+			y := uint32(x >> n) // Compiler doesn't combine memory writes if y isn't uint32
+			dst = append(dst, byte(y>>24), byte(y>>16), byte(y>>8), byte(y))
 		}
-		dst, rembits = appendByteToHuffmanCode(dst, rembits, s[i])
 	}
-
-	if rembits < 8 {
-		// special EOS symbol
-		code := uint32(0x3fffffff)
-		nbits := uint8(30)
-
-		t := uint8(code >> (nbits - rembits))
-		dst[len(dst)-1] |= t
+	// Add padding bits if necessary
+	if over := n % 8; over > 0 {
+		const (
+			eosCode    = 0x3fffffff
+			eosNBits   = 30
+			eosPadByte = eosCode >> (eosNBits - 8)
+		)
+		pad := 8 - over
+		x = (x << pad) | (eosPadByte >> over)
+		n += pad // 8 now divides into n exactly
 	}
-
-	return dst
+	// n in (0, 8, 16, 24, 32)
+	switch n / 8 {
+	case 0:
+		return dst
+	case 1:
+		return append(dst, byte(x))
+	case 2:
+		y := uint16(x)
+		return append(dst, byte(y>>8), byte(y))
+	case 3:
+		y := uint16(x >> 8)
+		return append(dst, byte(y>>8), byte(y), byte(x))
+	}
+	//	case 4:
+	y := uint32(x)
+	return append(dst, byte(y>>24), byte(y>>16), byte(y>>8), byte(y))
 }
 
 // HuffmanEncodeLength returns the number of bytes required to encode
@@ -199,35 +224,3 @@
 	}
 	return (n + 7) / 8
 }
-
-// appendByteToHuffmanCode appends Huffman code for c to dst and
-// returns the extended buffer and the remaining bits in the last
-// element. The appending is not byte aligned and the remaining bits
-// in the last element of dst is given in rembits.
-func appendByteToHuffmanCode(dst []byte, rembits uint8, c byte) ([]byte, uint8) {
-	code := huffmanCodes[c]
-	nbits := huffmanCodeLen[c]
-
-	for {
-		if rembits > nbits {
-			t := uint8(code << (rembits - nbits))
-			dst[len(dst)-1] |= t
-			rembits -= nbits
-			break
-		}
-
-		t := uint8(code >> (nbits - rembits))
-		dst[len(dst)-1] |= t
-
-		nbits -= rembits
-		rembits = 8
-
-		if nbits == 0 {
-			break
-		}
-
-		dst = append(dst, 0)
-	}
-
-	return dst, rembits
-}
diff --git a/src/vendor/golang.org/x/net/http2/hpack/static_table.go b/src/vendor/golang.org/x/net/http2/hpack/static_table.go
new file mode 100644
index 0000000..754a1eb
--- /dev/null
+++ b/src/vendor/golang.org/x/net/http2/hpack/static_table.go
@@ -0,0 +1,188 @@
+// go generate gen.go
+// Code generated by the command above; DO NOT EDIT.
+
+package hpack
+
+var staticTable = &headerFieldTable{
+	evictCount: 0,
+	byName: map[string]uint64{
+		":authority":                  1,
+		":method":                     3,
+		":path":                       5,
+		":scheme":                     7,
+		":status":                     14,
+		"accept-charset":              15,
+		"accept-encoding":             16,
+		"accept-language":             17,
+		"accept-ranges":               18,
+		"accept":                      19,
+		"access-control-allow-origin": 20,
+		"age":                         21,
+		"allow":                       22,
+		"authorization":               23,
+		"cache-control":               24,
+		"content-disposition":         25,
+		"content-encoding":            26,
+		"content-language":            27,
+		"content-length":              28,
+		"content-location":            29,
+		"content-range":               30,
+		"content-type":                31,
+		"cookie":                      32,
+		"date":                        33,
+		"etag":                        34,
+		"expect":                      35,
+		"expires":                     36,
+		"from":                        37,
+		"host":                        38,
+		"if-match":                    39,
+		"if-modified-since":           40,
+		"if-none-match":               41,
+		"if-range":                    42,
+		"if-unmodified-since":         43,
+		"last-modified":               44,
+		"link":                        45,
+		"location":                    46,
+		"max-forwards":                47,
+		"proxy-authenticate":          48,
+		"proxy-authorization":         49,
+		"range":                       50,
+		"referer":                     51,
+		"refresh":                     52,
+		"retry-after":                 53,
+		"server":                      54,
+		"set-cookie":                  55,
+		"strict-transport-security":   56,
+		"transfer-encoding":           57,
+		"user-agent":                  58,
+		"vary":                        59,
+		"via":                         60,
+		"www-authenticate":            61,
+	},
+	byNameValue: map[pairNameValue]uint64{
+		{name: ":authority", value: ""}:                   1,
+		{name: ":method", value: "GET"}:                   2,
+		{name: ":method", value: "POST"}:                  3,
+		{name: ":path", value: "/"}:                       4,
+		{name: ":path", value: "/index.html"}:             5,
+		{name: ":scheme", value: "http"}:                  6,
+		{name: ":scheme", value: "https"}:                 7,
+		{name: ":status", value: "200"}:                   8,
+		{name: ":status", value: "204"}:                   9,
+		{name: ":status", value: "206"}:                   10,
+		{name: ":status", value: "304"}:                   11,
+		{name: ":status", value: "400"}:                   12,
+		{name: ":status", value: "404"}:                   13,
+		{name: ":status", value: "500"}:                   14,
+		{name: "accept-charset", value: ""}:               15,
+		{name: "accept-encoding", value: "gzip, deflate"}: 16,
+		{name: "accept-language", value: ""}:              17,
+		{name: "accept-ranges", value: ""}:                18,
+		{name: "accept", value: ""}:                       19,
+		{name: "access-control-allow-origin", value: ""}:  20,
+		{name: "age", value: ""}:                          21,
+		{name: "allow", value: ""}:                        22,
+		{name: "authorization", value: ""}:                23,
+		{name: "cache-control", value: ""}:                24,
+		{name: "content-disposition", value: ""}:          25,
+		{name: "content-encoding", value: ""}:             26,
+		{name: "content-language", value: ""}:             27,
+		{name: "content-length", value: ""}:               28,
+		{name: "content-location", value: ""}:             29,
+		{name: "content-range", value: ""}:                30,
+		{name: "content-type", value: ""}:                 31,
+		{name: "cookie", value: ""}:                       32,
+		{name: "date", value: ""}:                         33,
+		{name: "etag", value: ""}:                         34,
+		{name: "expect", value: ""}:                       35,
+		{name: "expires", value: ""}:                      36,
+		{name: "from", value: ""}:                         37,
+		{name: "host", value: ""}:                         38,
+		{name: "if-match", value: ""}:                     39,
+		{name: "if-modified-since", value: ""}:            40,
+		{name: "if-none-match", value: ""}:                41,
+		{name: "if-range", value: ""}:                     42,
+		{name: "if-unmodified-since", value: ""}:          43,
+		{name: "last-modified", value: ""}:                44,
+		{name: "link", value: ""}:                         45,
+		{name: "location", value: ""}:                     46,
+		{name: "max-forwards", value: ""}:                 47,
+		{name: "proxy-authenticate", value: ""}:           48,
+		{name: "proxy-authorization", value: ""}:          49,
+		{name: "range", value: ""}:                        50,
+		{name: "referer", value: ""}:                      51,
+		{name: "refresh", value: ""}:                      52,
+		{name: "retry-after", value: ""}:                  53,
+		{name: "server", value: ""}:                       54,
+		{name: "set-cookie", value: ""}:                   55,
+		{name: "strict-transport-security", value: ""}:    56,
+		{name: "transfer-encoding", value: ""}:            57,
+		{name: "user-agent", value: ""}:                   58,
+		{name: "vary", value: ""}:                         59,
+		{name: "via", value: ""}:                          60,
+		{name: "www-authenticate", value: ""}:             61,
+	},
+	ents: []HeaderField{
+		{Name: ":authority", Value: "", Sensitive: false},
+		{Name: ":method", Value: "GET", Sensitive: false},
+		{Name: ":method", Value: "POST", Sensitive: false},
+		{Name: ":path", Value: "/", Sensitive: false},
+		{Name: ":path", Value: "/index.html", Sensitive: false},
+		{Name: ":scheme", Value: "http", Sensitive: false},
+		{Name: ":scheme", Value: "https", Sensitive: false},
+		{Name: ":status", Value: "200", Sensitive: false},
+		{Name: ":status", Value: "204", Sensitive: false},
+		{Name: ":status", Value: "206", Sensitive: false},
+		{Name: ":status", Value: "304", Sensitive: false},
+		{Name: ":status", Value: "400", Sensitive: false},
+		{Name: ":status", Value: "404", Sensitive: false},
+		{Name: ":status", Value: "500", Sensitive: false},
+		{Name: "accept-charset", Value: "", Sensitive: false},
+		{Name: "accept-encoding", Value: "gzip, deflate", Sensitive: false},
+		{Name: "accept-language", Value: "", Sensitive: false},
+		{Name: "accept-ranges", Value: "", Sensitive: false},
+		{Name: "accept", Value: "", Sensitive: false},
+		{Name: "access-control-allow-origin", Value: "", Sensitive: false},
+		{Name: "age", Value: "", Sensitive: false},
+		{Name: "allow", Value: "", Sensitive: false},
+		{Name: "authorization", Value: "", Sensitive: false},
+		{Name: "cache-control", Value: "", Sensitive: false},
+		{Name: "content-disposition", Value: "", Sensitive: false},
+		{Name: "content-encoding", Value: "", Sensitive: false},
+		{Name: "content-language", Value: "", Sensitive: false},
+		{Name: "content-length", Value: "", Sensitive: false},
+		{Name: "content-location", Value: "", Sensitive: false},
+		{Name: "content-range", Value: "", Sensitive: false},
+		{Name: "content-type", Value: "", Sensitive: false},
+		{Name: "cookie", Value: "", Sensitive: false},
+		{Name: "date", Value: "", Sensitive: false},
+		{Name: "etag", Value: "", Sensitive: false},
+		{Name: "expect", Value: "", Sensitive: false},
+		{Name: "expires", Value: "", Sensitive: false},
+		{Name: "from", Value: "", Sensitive: false},
+		{Name: "host", Value: "", Sensitive: false},
+		{Name: "if-match", Value: "", Sensitive: false},
+		{Name: "if-modified-since", Value: "", Sensitive: false},
+		{Name: "if-none-match", Value: "", Sensitive: false},
+		{Name: "if-range", Value: "", Sensitive: false},
+		{Name: "if-unmodified-since", Value: "", Sensitive: false},
+		{Name: "last-modified", Value: "", Sensitive: false},
+		{Name: "link", Value: "", Sensitive: false},
+		{Name: "location", Value: "", Sensitive: false},
+		{Name: "max-forwards", Value: "", Sensitive: false},
+		{Name: "proxy-authenticate", Value: "", Sensitive: false},
+		{Name: "proxy-authorization", Value: "", Sensitive: false},
+		{Name: "range", Value: "", Sensitive: false},
+		{Name: "referer", Value: "", Sensitive: false},
+		{Name: "refresh", Value: "", Sensitive: false},
+		{Name: "retry-after", Value: "", Sensitive: false},
+		{Name: "server", Value: "", Sensitive: false},
+		{Name: "set-cookie", Value: "", Sensitive: false},
+		{Name: "strict-transport-security", Value: "", Sensitive: false},
+		{Name: "transfer-encoding", Value: "", Sensitive: false},
+		{Name: "user-agent", Value: "", Sensitive: false},
+		{Name: "vary", Value: "", Sensitive: false},
+		{Name: "via", Value: "", Sensitive: false},
+		{Name: "www-authenticate", Value: "", Sensitive: false},
+	},
+}
diff --git a/src/vendor/golang.org/x/net/http2/hpack/tables.go b/src/vendor/golang.org/x/net/http2/hpack/tables.go
index a66cfbe..8cbdf3f 100644
--- a/src/vendor/golang.org/x/net/http2/hpack/tables.go
+++ b/src/vendor/golang.org/x/net/http2/hpack/tables.go
@@ -96,8 +96,7 @@
 // meaning t.ents is reversed for dynamic tables. Hence, when t is a dynamic
 // table, the return value i actually refers to the entry t.ents[t.len()-i].
 //
-// All tables are assumed to be a dynamic tables except for the global
-// staticTable pointer.
+// All tables are assumed to be a dynamic tables except for the global staticTable.
 //
 // See Section 2.3.3.
 func (t *headerFieldTable) search(f HeaderField) (i uint64, nameValueMatch bool) {
@@ -125,81 +124,6 @@
 	return k + 1
 }
 
-// http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-07#appendix-B
-var staticTable = newStaticTable()
-var staticTableEntries = [...]HeaderField{
-	{Name: ":authority"},
-	{Name: ":method", Value: "GET"},
-	{Name: ":method", Value: "POST"},
-	{Name: ":path", Value: "/"},
-	{Name: ":path", Value: "/index.html"},
-	{Name: ":scheme", Value: "http"},
-	{Name: ":scheme", Value: "https"},
-	{Name: ":status", Value: "200"},
-	{Name: ":status", Value: "204"},
-	{Name: ":status", Value: "206"},
-	{Name: ":status", Value: "304"},
-	{Name: ":status", Value: "400"},
-	{Name: ":status", Value: "404"},
-	{Name: ":status", Value: "500"},
-	{Name: "accept-charset"},
-	{Name: "accept-encoding", Value: "gzip, deflate"},
-	{Name: "accept-language"},
-	{Name: "accept-ranges"},
-	{Name: "accept"},
-	{Name: "access-control-allow-origin"},
-	{Name: "age"},
-	{Name: "allow"},
-	{Name: "authorization"},
-	{Name: "cache-control"},
-	{Name: "content-disposition"},
-	{Name: "content-encoding"},
-	{Name: "content-language"},
-	{Name: "content-length"},
-	{Name: "content-location"},
-	{Name: "content-range"},
-	{Name: "content-type"},
-	{Name: "cookie"},
-	{Name: "date"},
-	{Name: "etag"},
-	{Name: "expect"},
-	{Name: "expires"},
-	{Name: "from"},
-	{Name: "host"},
-	{Name: "if-match"},
-	{Name: "if-modified-since"},
-	{Name: "if-none-match"},
-	{Name: "if-range"},
-	{Name: "if-unmodified-since"},
-	{Name: "last-modified"},
-	{Name: "link"},
-	{Name: "location"},
-	{Name: "max-forwards"},
-	{Name: "proxy-authenticate"},
-	{Name: "proxy-authorization"},
-	{Name: "range"},
-	{Name: "referer"},
-	{Name: "refresh"},
-	{Name: "retry-after"},
-	{Name: "server"},
-	{Name: "set-cookie"},
-	{Name: "strict-transport-security"},
-	{Name: "transfer-encoding"},
-	{Name: "user-agent"},
-	{Name: "vary"},
-	{Name: "via"},
-	{Name: "www-authenticate"},
-}
-
-func newStaticTable() *headerFieldTable {
-	t := &headerFieldTable{}
-	t.init()
-	for _, e := range staticTableEntries[:] {
-		t.addEntry(e)
-	}
-	return t
-}
-
 var huffmanCodes = [256]uint32{
 	0x1ff8,
 	0x7fffd8,
diff --git a/src/vendor/golang.org/x/net/lif/address.go b/src/vendor/golang.org/x/net/lif/address.go
index 34b6432..8eaddb5 100644
--- a/src/vendor/golang.org/x/net/lif/address.go
+++ b/src/vendor/golang.org/x/net/lif/address.go
@@ -9,6 +9,7 @@
 
 import (
 	"errors"
+	"syscall"
 	"unsafe"
 )
 
@@ -25,7 +26,7 @@
 }
 
 // Family implements the Family method of Addr interface.
-func (a *Inet4Addr) Family() int { return sysAF_INET }
+func (a *Inet4Addr) Family() int { return syscall.AF_INET }
 
 // An Inet6Addr represents an internet address for IPv6.
 type Inet6Addr struct {
@@ -35,7 +36,7 @@
 }
 
 // Family implements the Family method of Addr interface.
-func (a *Inet6Addr) Family() int { return sysAF_INET6 }
+func (a *Inet6Addr) Family() int { return syscall.AF_INET6 }
 
 // Addrs returns a list of interface addresses.
 //
@@ -62,7 +63,7 @@
 			lifr.Name[i] = int8(ll.Name[i])
 		}
 		for _, ep := range eps {
-			ioc := int64(sysSIOCGLIFADDR)
+			ioc := int64(syscall.SIOCGLIFADDR)
 			err := ioctl(ep.s, uintptr(ioc), unsafe.Pointer(&lifr))
 			if err != nil {
 				continue
@@ -73,11 +74,11 @@
 				continue
 			}
 			switch sa.Family {
-			case sysAF_INET:
+			case syscall.AF_INET:
 				a := &Inet4Addr{PrefixLen: l}
 				copy(a.IP[:], lifr.Lifru[4:8])
 				as = append(as, a)
-			case sysAF_INET6:
+			case syscall.AF_INET6:
 				a := &Inet6Addr{PrefixLen: l, ZoneID: int(nativeEndian.Uint32(lifr.Lifru[24:28]))}
 				copy(a.IP[:], lifr.Lifru[8:24])
 				as = append(as, a)
diff --git a/src/vendor/golang.org/x/net/lif/lif.go b/src/vendor/golang.org/x/net/lif/lif.go
index 95c7d25..f1fce48 100644
--- a/src/vendor/golang.org/x/net/lif/lif.go
+++ b/src/vendor/golang.org/x/net/lif/lif.go
@@ -11,7 +11,9 @@
 // The package supports Solaris 11 or above.
 package lif
 
-import "syscall"
+import (
+	"syscall"
+)
 
 type endpoint struct {
 	af int
@@ -25,12 +27,12 @@
 func newEndpoints(af int) ([]endpoint, error) {
 	var lastErr error
 	var eps []endpoint
-	afs := []int{sysAF_INET, sysAF_INET6}
-	if af != sysAF_UNSPEC {
+	afs := []int{syscall.AF_INET, syscall.AF_INET6}
+	if af != syscall.AF_UNSPEC {
 		afs = []int{af}
 	}
 	for _, af := range afs {
-		s, err := syscall.Socket(af, sysSOCK_DGRAM, 0)
+		s, err := syscall.Socket(af, syscall.SOCK_DGRAM, 0)
 		if err != nil {
 			lastErr = err
 			continue
diff --git a/src/vendor/golang.org/x/net/lif/link.go b/src/vendor/golang.org/x/net/lif/link.go
index f1af130..00b7854 100644
--- a/src/vendor/golang.org/x/net/lif/link.go
+++ b/src/vendor/golang.org/x/net/lif/link.go
@@ -7,7 +7,10 @@
 
 package lif
 
-import "unsafe"
+import (
+	"syscall"
+	"unsafe"
+)
 
 // A Link represents logical data link information.
 //
@@ -30,22 +33,22 @@
 	for i := 0; i < len(ll.Name); i++ {
 		lifr.Name[i] = int8(ll.Name[i])
 	}
-	ioc := int64(sysSIOCGLIFINDEX)
+	ioc := int64(syscall.SIOCGLIFINDEX)
 	if err := ioctl(s, uintptr(ioc), unsafe.Pointer(&lifr)); err == nil {
 		ll.Index = int(nativeEndian.Uint32(lifr.Lifru[:4]))
 	}
-	ioc = int64(sysSIOCGLIFFLAGS)
+	ioc = int64(syscall.SIOCGLIFFLAGS)
 	if err := ioctl(s, uintptr(ioc), unsafe.Pointer(&lifr)); err == nil {
 		ll.Flags = int(nativeEndian.Uint64(lifr.Lifru[:8]))
 	}
-	ioc = int64(sysSIOCGLIFMTU)
+	ioc = int64(syscall.SIOCGLIFMTU)
 	if err := ioctl(s, uintptr(ioc), unsafe.Pointer(&lifr)); err == nil {
 		ll.MTU = int(nativeEndian.Uint32(lifr.Lifru[:4]))
 	}
 	switch ll.Type {
-	case sysIFT_IPV4, sysIFT_IPV6, sysIFT_6TO4:
+	case syscall.IFT_IPV4, syscall.IFT_IPV6, syscall.IFT_6TO4:
 	default:
-		ioc = int64(sysSIOCGLIFHWADDR)
+		ioc = int64(syscall.SIOCGLIFHWADDR)
 		if err := ioctl(s, uintptr(ioc), unsafe.Pointer(&lifr)); err == nil {
 			ll.Addr, _ = parseLinkAddr(lifr.Lifru[4:])
 		}
@@ -75,7 +78,7 @@
 	lifc := lifconf{Flags: sysLIFC_NOXMIT | sysLIFC_TEMPORARY | sysLIFC_ALLZONES | sysLIFC_UNDER_IPMP}
 	for _, ep := range eps {
 		lifn.Family = uint16(ep.af)
-		ioc := int64(sysSIOCGLIFNUM)
+		ioc := int64(syscall.SIOCGLIFNUM)
 		if err := ioctl(ep.s, uintptr(ioc), unsafe.Pointer(&lifn)); err != nil {
 			continue
 		}
@@ -90,7 +93,7 @@
 		} else {
 			nativeEndian.PutUint32(lifc.Lifcu[:], uint32(uintptr(unsafe.Pointer(&b[0]))))
 		}
-		ioc = int64(sysSIOCGLIFCONF)
+		ioc = int64(syscall.SIOCGLIFCONF)
 		if err := ioctl(ep.s, uintptr(ioc), unsafe.Pointer(&lifc)); err != nil {
 			continue
 		}
diff --git a/src/vendor/golang.org/x/net/lif/zsys_solaris_amd64.go b/src/vendor/golang.org/x/net/lif/zsys_solaris_amd64.go
index d7a70d4..30651c7 100644
--- a/src/vendor/golang.org/x/net/lif/zsys_solaris_amd64.go
+++ b/src/vendor/golang.org/x/net/lif/zsys_solaris_amd64.go
@@ -3,14 +3,6 @@
 
 package lif
 
-const (
-	sysAF_UNSPEC = 0x0
-	sysAF_INET   = 0x2
-	sysAF_INET6  = 0x1a
-
-	sysSOCK_DGRAM = 0x1
-)
-
 type sockaddrStorage struct {
 	Family     uint16
 	X_ss_pad1  [6]int8
@@ -25,37 +17,6 @@
 	sysLIFC_ALLZONES        = 0x8
 	sysLIFC_UNDER_IPMP      = 0x10
 	sysLIFC_ENABLED         = 0x20
-
-	sysSIOCGLIFADDR    = -0x3f87968f
-	sysSIOCGLIFDSTADDR = -0x3f87968d
-	sysSIOCGLIFFLAGS   = -0x3f87968b
-	sysSIOCGLIFMTU     = -0x3f879686
-	sysSIOCGLIFNETMASK = -0x3f879683
-	sysSIOCGLIFMETRIC  = -0x3f879681
-	sysSIOCGLIFNUM     = -0x3ff3967e
-	sysSIOCGLIFINDEX   = -0x3f87967b
-	sysSIOCGLIFSUBNET  = -0x3f879676
-	sysSIOCGLIFLNKINFO = -0x3f879674
-	sysSIOCGLIFCONF    = -0x3fef965b
-	sysSIOCGLIFHWADDR  = -0x3f879640
-)
-
-const (
-	sysIFF_UP          = 0x1
-	sysIFF_BROADCAST   = 0x2
-	sysIFF_DEBUG       = 0x4
-	sysIFF_LOOPBACK    = 0x8
-	sysIFF_POINTOPOINT = 0x10
-	sysIFF_NOTRAILERS  = 0x20
-	sysIFF_RUNNING     = 0x40
-	sysIFF_NOARP       = 0x80
-	sysIFF_PROMISC     = 0x100
-	sysIFF_ALLMULTI    = 0x200
-	sysIFF_INTELLIGENT = 0x400
-	sysIFF_MULTICAST   = 0x800
-	sysIFF_MULTI_BCAST = 0x1000
-	sysIFF_UNNUMBERED  = 0x2000
-	sysIFF_PRIVATE     = 0x8000
 )
 
 const (
@@ -95,9 +56,3 @@
 	Reachretrans uint32
 	Maxmtu       uint32
 }
-
-const (
-	sysIFT_IPV4 = 0xc8
-	sysIFT_IPV6 = 0xc9
-	sysIFT_6TO4 = 0xca
-)
diff --git a/src/vendor/golang.org/x/net/nettest/conntest.go b/src/vendor/golang.org/x/net/nettest/conntest.go
index 55ad42a..615f498 100644
--- a/src/vendor/golang.org/x/net/nettest/conntest.go
+++ b/src/vendor/golang.org/x/net/nettest/conntest.go
@@ -398,7 +398,11 @@
 	t.Helper()
 	if nerr, ok := err.(net.Error); ok {
 		if !nerr.Timeout() {
-			t.Errorf("got error: %v, want err.Timeout() = true", nerr)
+			if runtime.GOOS == "windows" && runtime.GOARCH == "arm64" && t.Name() == "TestTestConn/TCP/RacyRead" {
+				t.Logf("ignoring known failure mode on windows/arm64; see https://go.dev/issue/52893")
+			} else {
+				t.Errorf("got error: %v, want err.Timeout() = true", nerr)
+			}
 		}
 	} else {
 		t.Errorf("got %T: %v, want net.Error", err, err)
diff --git a/src/vendor/golang.org/x/net/nettest/nettest.go b/src/vendor/golang.org/x/net/nettest/nettest.go
index ae5413b..6918f2c 100644
--- a/src/vendor/golang.org/x/net/nettest/nettest.go
+++ b/src/vendor/golang.org/x/net/nettest/nettest.go
@@ -218,7 +218,11 @@
 // LocalPath returns a local path that can be used for Unix-domain
 // protocol testing.
 func LocalPath() (string, error) {
-	f, err := ioutil.TempFile("", "go-nettest")
+	dir := ""
+	if runtime.GOOS == "darwin" {
+		dir = "/tmp"
+	}
+	f, err := ioutil.TempFile(dir, "go-nettest")
 	if err != nil {
 		return "", err
 	}
diff --git a/src/vendor/golang.org/x/net/route/address.go b/src/vendor/golang.org/x/net/route/address.go
index 1898ed0..5a3cc06 100644
--- a/src/vendor/golang.org/x/net/route/address.go
+++ b/src/vendor/golang.org/x/net/route/address.go
@@ -7,7 +7,10 @@
 
 package route
 
-import "runtime"
+import (
+	"runtime"
+	"syscall"
+)
 
 // An Addr represents an address associated with packet routing.
 type Addr interface {
@@ -23,7 +26,7 @@
 }
 
 // Family implements the Family method of Addr interface.
-func (a *LinkAddr) Family() int { return sysAF_LINK }
+func (a *LinkAddr) Family() int { return syscall.AF_LINK }
 
 func (a *LinkAddr) lenAndSpace() (int, int) {
 	l := 8 + len(a.Name) + len(a.Addr)
@@ -40,7 +43,7 @@
 		return 0, errInvalidAddr
 	}
 	b[0] = byte(l)
-	b[1] = sysAF_LINK
+	b[1] = syscall.AF_LINK
 	if a.Index > 0 {
 		nativeEndian.PutUint16(b[2:4], uint16(a.Index))
 	}
@@ -62,7 +65,7 @@
 	if len(b) < 8 {
 		return nil, errInvalidAddr
 	}
-	_, a, err := parseKernelLinkAddr(sysAF_LINK, b[4:])
+	_, a, err := parseKernelLinkAddr(syscall.AF_LINK, b[4:])
 	if err != nil {
 		return nil, err
 	}
@@ -122,7 +125,7 @@
 }
 
 // Family implements the Family method of Addr interface.
-func (a *Inet4Addr) Family() int { return sysAF_INET }
+func (a *Inet4Addr) Family() int { return syscall.AF_INET }
 
 func (a *Inet4Addr) lenAndSpace() (int, int) {
 	return sizeofSockaddrInet, roundup(sizeofSockaddrInet)
@@ -134,7 +137,7 @@
 		return 0, errShortBuffer
 	}
 	b[0] = byte(l)
-	b[1] = sysAF_INET
+	b[1] = syscall.AF_INET
 	copy(b[4:8], a.IP[:])
 	return ll, nil
 }
@@ -146,7 +149,7 @@
 }
 
 // Family implements the Family method of Addr interface.
-func (a *Inet6Addr) Family() int { return sysAF_INET6 }
+func (a *Inet6Addr) Family() int { return syscall.AF_INET6 }
 
 func (a *Inet6Addr) lenAndSpace() (int, int) {
 	return sizeofSockaddrInet6, roundup(sizeofSockaddrInet6)
@@ -158,7 +161,7 @@
 		return 0, errShortBuffer
 	}
 	b[0] = byte(l)
-	b[1] = sysAF_INET6
+	b[1] = syscall.AF_INET6
 	copy(b[8:24], a.IP[:])
 	if a.ZoneID > 0 {
 		nativeEndian.PutUint32(b[24:28], uint32(a.ZoneID))
@@ -169,14 +172,14 @@
 // parseInetAddr parses b as an internet address for IPv4 or IPv6.
 func parseInetAddr(af int, b []byte) (Addr, error) {
 	switch af {
-	case sysAF_INET:
+	case syscall.AF_INET:
 		if len(b) < sizeofSockaddrInet {
 			return nil, errInvalidAddr
 		}
 		a := &Inet4Addr{}
 		copy(a.IP[:], b[4:8])
 		return a, nil
-	case sysAF_INET6:
+	case syscall.AF_INET6:
 		if len(b) < sizeofSockaddrInet6 {
 			return nil, errInvalidAddr
 		}
@@ -245,7 +248,7 @@
 		a := &Inet6Addr{}
 		copy(a.IP[:], b[off6:off6+16])
 		return int(b[0]), a, nil
-	case af == sysAF_INET6:
+	case af == syscall.AF_INET6:
 		a := &Inet6Addr{}
 		if l-1 < off6 {
 			copy(a.IP[:], b[1:l])
@@ -365,15 +368,15 @@
 }
 
 func parseAddrs(attrs uint, fn func(int, []byte) (int, Addr, error), b []byte) ([]Addr, error) {
-	var as [sysRTAX_MAX]Addr
-	af := int(sysAF_UNSPEC)
-	for i := uint(0); i < sysRTAX_MAX && len(b) >= roundup(0); i++ {
+	var as [syscall.RTAX_MAX]Addr
+	af := int(syscall.AF_UNSPEC)
+	for i := uint(0); i < syscall.RTAX_MAX && len(b) >= roundup(0); i++ {
 		if attrs&(1<<i) == 0 {
 			continue
 		}
-		if i <= sysRTAX_BRD {
+		if i <= syscall.RTAX_BRD {
 			switch b[1] {
-			case sysAF_LINK:
+			case syscall.AF_LINK:
 				a, err := parseLinkAddr(b)
 				if err != nil {
 					return nil, err
@@ -384,7 +387,7 @@
 					return nil, errMessageTooShort
 				}
 				b = b[l:]
-			case sysAF_INET, sysAF_INET6:
+			case syscall.AF_INET, syscall.AF_INET6:
 				af = int(b[1])
 				a, err := parseInetAddr(af, b)
 				if err != nil {
diff --git a/src/vendor/golang.org/x/net/route/interface_classic.go b/src/vendor/golang.org/x/net/route/interface_classic.go
index 85b7e99..903a196 100644
--- a/src/vendor/golang.org/x/net/route/interface_classic.go
+++ b/src/vendor/golang.org/x/net/route/interface_classic.go
@@ -7,7 +7,10 @@
 
 package route
 
-import "runtime"
+import (
+	"runtime"
+	"syscall"
+)
 
 func (w *wireFormat) parseInterfaceMessage(_ RIBType, b []byte) (Message, error) {
 	if len(b) < w.bodyOff {
@@ -18,13 +21,13 @@
 		return nil, errInvalidMessage
 	}
 	attrs := uint(nativeEndian.Uint32(b[4:8]))
-	if attrs&sysRTA_IFP == 0 {
+	if attrs&syscall.RTA_IFP == 0 {
 		return nil, nil
 	}
 	m := &InterfaceMessage{
 		Version: int(b[2]),
 		Type:    int(b[3]),
-		Addrs:   make([]Addr, sysRTAX_MAX),
+		Addrs:   make([]Addr, syscall.RTAX_MAX),
 		Flags:   int(nativeEndian.Uint32(b[8:12])),
 		Index:   int(nativeEndian.Uint16(b[12:14])),
 		extOff:  w.extOff,
@@ -34,7 +37,7 @@
 	if err != nil {
 		return nil, err
 	}
-	m.Addrs[sysRTAX_IFP] = a
+	m.Addrs[syscall.RTAX_IFP] = a
 	m.Name = a.(*LinkAddr).Name
 	return m, nil
 }
diff --git a/src/vendor/golang.org/x/net/route/interface_freebsd.go b/src/vendor/golang.org/x/net/route/interface_freebsd.go
index 9f6f50c..14d251c 100644
--- a/src/vendor/golang.org/x/net/route/interface_freebsd.go
+++ b/src/vendor/golang.org/x/net/route/interface_freebsd.go
@@ -4,9 +4,11 @@
 
 package route
 
+import "syscall"
+
 func (w *wireFormat) parseInterfaceMessage(typ RIBType, b []byte) (Message, error) {
 	var extOff, bodyOff int
-	if typ == sysNET_RT_IFLISTL {
+	if typ == syscall.NET_RT_IFLISTL {
 		if len(b) < 20 {
 			return nil, errMessageTooShort
 		}
@@ -24,7 +26,7 @@
 		return nil, errInvalidMessage
 	}
 	attrs := uint(nativeEndian.Uint32(b[4:8]))
-	if attrs&sysRTA_IFP == 0 {
+	if attrs&syscall.RTA_IFP == 0 {
 		return nil, nil
 	}
 	m := &InterfaceMessage{
@@ -32,7 +34,7 @@
 		Type:    int(b[3]),
 		Flags:   int(nativeEndian.Uint32(b[8:12])),
 		Index:   int(nativeEndian.Uint16(b[12:14])),
-		Addrs:   make([]Addr, sysRTAX_MAX),
+		Addrs:   make([]Addr, syscall.RTAX_MAX),
 		extOff:  extOff,
 		raw:     b[:l],
 	}
@@ -40,14 +42,14 @@
 	if err != nil {
 		return nil, err
 	}
-	m.Addrs[sysRTAX_IFP] = a
+	m.Addrs[syscall.RTAX_IFP] = a
 	m.Name = a.(*LinkAddr).Name
 	return m, nil
 }
 
 func (w *wireFormat) parseInterfaceAddrMessage(typ RIBType, b []byte) (Message, error) {
 	var bodyOff int
-	if typ == sysNET_RT_IFLISTL {
+	if typ == syscall.NET_RT_IFLISTL {
 		if len(b) < 24 {
 			return nil, errMessageTooShort
 		}
diff --git a/src/vendor/golang.org/x/net/route/interface_openbsd.go b/src/vendor/golang.org/x/net/route/interface_openbsd.go
index e4a143c..d369409 100644
--- a/src/vendor/golang.org/x/net/route/interface_openbsd.go
+++ b/src/vendor/golang.org/x/net/route/interface_openbsd.go
@@ -4,6 +4,8 @@
 
 package route
 
+import "syscall"
+
 func (*wireFormat) parseInterfaceMessage(_ RIBType, b []byte) (Message, error) {
 	if len(b) < 32 {
 		return nil, errMessageTooShort
@@ -13,7 +15,7 @@
 		return nil, errInvalidMessage
 	}
 	attrs := uint(nativeEndian.Uint32(b[12:16]))
-	if attrs&sysRTA_IFP == 0 {
+	if attrs&syscall.RTA_IFP == 0 {
 		return nil, nil
 	}
 	m := &InterfaceMessage{
@@ -21,7 +23,7 @@
 		Type:    int(b[3]),
 		Flags:   int(nativeEndian.Uint32(b[16:20])),
 		Index:   int(nativeEndian.Uint16(b[6:8])),
-		Addrs:   make([]Addr, sysRTAX_MAX),
+		Addrs:   make([]Addr, syscall.RTAX_MAX),
 		raw:     b[:l],
 	}
 	ll := int(nativeEndian.Uint16(b[4:6]))
@@ -32,7 +34,7 @@
 	if err != nil {
 		return nil, err
 	}
-	m.Addrs[sysRTAX_IFP] = a
+	m.Addrs[syscall.RTAX_IFP] = a
 	m.Name = a.(*LinkAddr).Name
 	return m, nil
 }
diff --git a/src/vendor/golang.org/x/net/route/route.go b/src/vendor/golang.org/x/net/route/route.go
index fd0019e..3ab5bcd 100644
--- a/src/vendor/golang.org/x/net/route/route.go
+++ b/src/vendor/golang.org/x/net/route/route.go
@@ -111,7 +111,7 @@
 	try := 0
 	for {
 		try++
-		mib := [6]int32{sysCTL_NET, sysAF_ROUTE, 0, int32(af), int32(typ), int32(arg)}
+		mib := [6]int32{syscall.CTL_NET, syscall.AF_ROUTE, 0, int32(af), int32(typ), int32(arg)}
 		n := uintptr(0)
 		if err := sysctl(mib[:], nil, &n, nil, 0); err != nil {
 			return nil, os.NewSyscallError("sysctl", err)
diff --git a/src/vendor/golang.org/x/net/route/route_openbsd.go b/src/vendor/golang.org/x/net/route/route_openbsd.go
index daf2e90..f848fb1 100644
--- a/src/vendor/golang.org/x/net/route/route_openbsd.go
+++ b/src/vendor/golang.org/x/net/route/route_openbsd.go
@@ -4,14 +4,16 @@
 
 package route
 
-import "syscall"
+import (
+	"syscall"
+)
 
 func (m *RouteMessage) marshal() ([]byte, error) {
 	l := sizeofRtMsghdr + addrsSpace(m.Addrs)
 	b := make([]byte, l)
 	nativeEndian.PutUint16(b[:2], uint16(l))
 	if m.Version == 0 {
-		b[2] = sysRTM_VERSION
+		b[2] = syscall.RTM_VERSION
 	} else {
 		b[2] = byte(m.Version)
 	}
diff --git a/src/vendor/golang.org/x/net/route/sys.go b/src/vendor/golang.org/x/net/route/sys.go
index 537484a..7c75574 100644
--- a/src/vendor/golang.org/x/net/route/sys.go
+++ b/src/vendor/golang.org/x/net/route/sys.go
@@ -7,7 +7,10 @@
 
 package route
 
-import "unsafe"
+import (
+	"syscall"
+	"unsafe"
+)
 
 var (
 	nativeEndian binaryByteOrder
@@ -25,7 +28,7 @@
 		nativeEndian = bigEndian
 	}
 	// might get overridden in probeRoutingStack
-	rtmVersion = sysRTM_VERSION
+	rtmVersion = syscall.RTM_VERSION
 	kernelAlign, wireFormats = probeRoutingStack()
 }
 
diff --git a/src/vendor/golang.org/x/net/route/sys_darwin.go b/src/vendor/golang.org/x/net/route/sys_darwin.go
index d2daf5c..c8c4eec 100644
--- a/src/vendor/golang.org/x/net/route/sys_darwin.go
+++ b/src/vendor/golang.org/x/net/route/sys_darwin.go
@@ -4,9 +4,11 @@
 
 package route
 
+import "syscall"
+
 func (typ RIBType) parseable() bool {
 	switch typ {
-	case sysNET_RT_STAT, sysNET_RT_TRASH:
+	case syscall.NET_RT_STAT, syscall.NET_RT_TRASH:
 		return false
 	default:
 		return true
@@ -66,22 +68,22 @@
 	ifmam2.parse = ifmam2.parseInterfaceMulticastAddrMessage
 	// Darwin kernels require 32-bit aligned access to routing facilities.
 	return 4, map[int]*wireFormat{
-		sysRTM_ADD:       rtm,
-		sysRTM_DELETE:    rtm,
-		sysRTM_CHANGE:    rtm,
-		sysRTM_GET:       rtm,
-		sysRTM_LOSING:    rtm,
-		sysRTM_REDIRECT:  rtm,
-		sysRTM_MISS:      rtm,
-		sysRTM_LOCK:      rtm,
-		sysRTM_RESOLVE:   rtm,
-		sysRTM_NEWADDR:   ifam,
-		sysRTM_DELADDR:   ifam,
-		sysRTM_IFINFO:    ifm,
-		sysRTM_NEWMADDR:  ifmam,
-		sysRTM_DELMADDR:  ifmam,
-		sysRTM_IFINFO2:   ifm2,
-		sysRTM_NEWMADDR2: ifmam2,
-		sysRTM_GET2:      rtm2,
+		syscall.RTM_ADD:       rtm,
+		syscall.RTM_DELETE:    rtm,
+		syscall.RTM_CHANGE:    rtm,
+		syscall.RTM_GET:       rtm,
+		syscall.RTM_LOSING:    rtm,
+		syscall.RTM_REDIRECT:  rtm,
+		syscall.RTM_MISS:      rtm,
+		syscall.RTM_LOCK:      rtm,
+		syscall.RTM_RESOLVE:   rtm,
+		syscall.RTM_NEWADDR:   ifam,
+		syscall.RTM_DELADDR:   ifam,
+		syscall.RTM_IFINFO:    ifm,
+		syscall.RTM_NEWMADDR:  ifmam,
+		syscall.RTM_DELMADDR:  ifmam,
+		syscall.RTM_IFINFO2:   ifm2,
+		syscall.RTM_NEWMADDR2: ifmam2,
+		syscall.RTM_GET2:      rtm2,
 	}
 }
diff --git a/src/vendor/golang.org/x/net/route/sys_dragonfly.go b/src/vendor/golang.org/x/net/route/sys_dragonfly.go
index a138951..577fb16 100644
--- a/src/vendor/golang.org/x/net/route/sys_dragonfly.go
+++ b/src/vendor/golang.org/x/net/route/sys_dragonfly.go
@@ -69,20 +69,20 @@
 	}
 
 	return int(unsafe.Sizeof(p)), map[int]*wireFormat{
-		sysRTM_ADD:        rtm,
-		sysRTM_DELETE:     rtm,
-		sysRTM_CHANGE:     rtm,
-		sysRTM_GET:        rtm,
-		sysRTM_LOSING:     rtm,
-		sysRTM_REDIRECT:   rtm,
-		sysRTM_MISS:       rtm,
-		sysRTM_LOCK:       rtm,
-		sysRTM_RESOLVE:    rtm,
-		sysRTM_NEWADDR:    ifam,
-		sysRTM_DELADDR:    ifam,
-		sysRTM_IFINFO:     ifm,
-		sysRTM_NEWMADDR:   ifmam,
-		sysRTM_DELMADDR:   ifmam,
-		sysRTM_IFANNOUNCE: ifanm,
+		syscall.RTM_ADD:        rtm,
+		syscall.RTM_DELETE:     rtm,
+		syscall.RTM_CHANGE:     rtm,
+		syscall.RTM_GET:        rtm,
+		syscall.RTM_LOSING:     rtm,
+		syscall.RTM_REDIRECT:   rtm,
+		syscall.RTM_MISS:       rtm,
+		syscall.RTM_LOCK:       rtm,
+		syscall.RTM_RESOLVE:    rtm,
+		syscall.RTM_NEWADDR:    ifam,
+		syscall.RTM_DELADDR:    ifam,
+		syscall.RTM_IFINFO:     ifm,
+		syscall.RTM_NEWMADDR:   ifmam,
+		syscall.RTM_DELMADDR:   ifmam,
+		syscall.RTM_IFANNOUNCE: ifanm,
 	}
 }
diff --git a/src/vendor/golang.org/x/net/route/sys_freebsd.go b/src/vendor/golang.org/x/net/route/sys_freebsd.go
index 3599601..0a66dce 100644
--- a/src/vendor/golang.org/x/net/route/sys_freebsd.go
+++ b/src/vendor/golang.org/x/net/route/sys_freebsd.go
@@ -141,20 +141,20 @@
 	ifmam.parse = ifmam.parseInterfaceMulticastAddrMessage
 	ifanm.parse = ifanm.parseInterfaceAnnounceMessage
 	return align, map[int]*wireFormat{
-		sysRTM_ADD:        rtm,
-		sysRTM_DELETE:     rtm,
-		sysRTM_CHANGE:     rtm,
-		sysRTM_GET:        rtm,
-		sysRTM_LOSING:     rtm,
-		sysRTM_REDIRECT:   rtm,
-		sysRTM_MISS:       rtm,
-		sysRTM_LOCK:       rtm,
-		sysRTM_RESOLVE:    rtm,
-		sysRTM_NEWADDR:    ifam,
-		sysRTM_DELADDR:    ifam,
-		sysRTM_IFINFO:     ifm,
-		sysRTM_NEWMADDR:   ifmam,
-		sysRTM_DELMADDR:   ifmam,
-		sysRTM_IFANNOUNCE: ifanm,
+		syscall.RTM_ADD:        rtm,
+		syscall.RTM_DELETE:     rtm,
+		syscall.RTM_CHANGE:     rtm,
+		syscall.RTM_GET:        rtm,
+		syscall.RTM_LOSING:     rtm,
+		syscall.RTM_REDIRECT:   rtm,
+		syscall.RTM_MISS:       rtm,
+		syscall.RTM_LOCK:       rtm,
+		syscall.RTM_RESOLVE:    rtm,
+		syscall.RTM_NEWADDR:    ifam,
+		syscall.RTM_DELADDR:    ifam,
+		syscall.RTM_IFINFO:     ifm,
+		syscall.RTM_NEWMADDR:   ifmam,
+		syscall.RTM_DELMADDR:   ifmam,
+		syscall.RTM_IFANNOUNCE: ifanm,
 	}
 }
diff --git a/src/vendor/golang.org/x/net/route/sys_netbsd.go b/src/vendor/golang.org/x/net/route/sys_netbsd.go
index 02f71d5..be4460e 100644
--- a/src/vendor/golang.org/x/net/route/sys_netbsd.go
+++ b/src/vendor/golang.org/x/net/route/sys_netbsd.go
@@ -4,6 +4,8 @@
 
 package route
 
+import "syscall"
+
 func (typ RIBType) parseable() bool { return true }
 
 // RouteMetrics represents route metrics.
@@ -54,18 +56,18 @@
 	// NetBSD 6 and above kernels require 64-bit aligned access to
 	// routing facilities.
 	return 8, map[int]*wireFormat{
-		sysRTM_ADD:        rtm,
-		sysRTM_DELETE:     rtm,
-		sysRTM_CHANGE:     rtm,
-		sysRTM_GET:        rtm,
-		sysRTM_LOSING:     rtm,
-		sysRTM_REDIRECT:   rtm,
-		sysRTM_MISS:       rtm,
-		sysRTM_LOCK:       rtm,
-		sysRTM_RESOLVE:    rtm,
-		sysRTM_NEWADDR:    ifam,
-		sysRTM_DELADDR:    ifam,
-		sysRTM_IFANNOUNCE: ifanm,
-		sysRTM_IFINFO:     ifm,
+		syscall.RTM_ADD:        rtm,
+		syscall.RTM_DELETE:     rtm,
+		syscall.RTM_CHANGE:     rtm,
+		syscall.RTM_GET:        rtm,
+		syscall.RTM_LOSING:     rtm,
+		syscall.RTM_REDIRECT:   rtm,
+		syscall.RTM_MISS:       rtm,
+		syscall.RTM_LOCK:       rtm,
+		syscall.RTM_RESOLVE:    rtm,
+		syscall.RTM_NEWADDR:    ifam,
+		syscall.RTM_DELADDR:    ifam,
+		syscall.RTM_IFANNOUNCE: ifanm,
+		syscall.RTM_IFINFO:     ifm,
 	}
 }
diff --git a/src/vendor/golang.org/x/net/route/sys_openbsd.go b/src/vendor/golang.org/x/net/route/sys_openbsd.go
index c5674e8..7f4f93c 100644
--- a/src/vendor/golang.org/x/net/route/sys_openbsd.go
+++ b/src/vendor/golang.org/x/net/route/sys_openbsd.go
@@ -4,11 +4,14 @@
 
 package route
 
-import "unsafe"
+import (
+	"syscall"
+	"unsafe"
+)
 
 func (typ RIBType) parseable() bool {
 	switch typ {
-	case sysNET_RT_STATS, sysNET_RT_TABLE:
+	case syscall.NET_RT_STATS, syscall.NET_RT_TABLE:
 		return false
 	default:
 		return true
@@ -62,19 +65,18 @@
 	ifanm := &wireFormat{extOff: -1, bodyOff: -1}
 	ifanm.parse = ifanm.parseInterfaceAnnounceMessage
 	return int(unsafe.Sizeof(p)), map[int]*wireFormat{
-		sysRTM_ADD:        rtm,
-		sysRTM_DELETE:     rtm,
-		sysRTM_CHANGE:     rtm,
-		sysRTM_GET:        rtm,
-		sysRTM_LOSING:     rtm,
-		sysRTM_REDIRECT:   rtm,
-		sysRTM_MISS:       rtm,
-		sysRTM_LOCK:       rtm,
-		sysRTM_RESOLVE:    rtm,
-		sysRTM_NEWADDR:    ifam,
-		sysRTM_DELADDR:    ifam,
-		sysRTM_IFINFO:     ifm,
-		sysRTM_IFANNOUNCE: ifanm,
-		sysRTM_DESYNC:     rtm,
+		syscall.RTM_ADD:        rtm,
+		syscall.RTM_DELETE:     rtm,
+		syscall.RTM_CHANGE:     rtm,
+		syscall.RTM_GET:        rtm,
+		syscall.RTM_LOSING:     rtm,
+		syscall.RTM_REDIRECT:   rtm,
+		syscall.RTM_MISS:       rtm,
+		syscall.RTM_RESOLVE:    rtm,
+		syscall.RTM_NEWADDR:    ifam,
+		syscall.RTM_DELADDR:    ifam,
+		syscall.RTM_IFINFO:     ifm,
+		syscall.RTM_IFANNOUNCE: ifanm,
+		syscall.RTM_DESYNC:     rtm,
 	}
 }
diff --git a/src/vendor/golang.org/x/net/route/zsys_darwin.go b/src/vendor/golang.org/x/net/route/zsys_darwin.go
index 19e4133..56a0c66 100644
--- a/src/vendor/golang.org/x/net/route/zsys_darwin.go
+++ b/src/vendor/golang.org/x/net/route/zsys_darwin.go
@@ -4,83 +4,6 @@
 package route
 
 const (
-	sysAF_UNSPEC = 0x0
-	sysAF_INET   = 0x2
-	sysAF_ROUTE  = 0x11
-	sysAF_LINK   = 0x12
-	sysAF_INET6  = 0x1e
-
-	sysSOCK_RAW = 0x3
-
-	sysNET_RT_DUMP    = 0x1
-	sysNET_RT_FLAGS   = 0x2
-	sysNET_RT_IFLIST  = 0x3
-	sysNET_RT_STAT    = 0x4
-	sysNET_RT_TRASH   = 0x5
-	sysNET_RT_IFLIST2 = 0x6
-	sysNET_RT_DUMP2   = 0x7
-	sysNET_RT_MAXID   = 0xa
-)
-
-const (
-	sysCTL_MAXNAME = 0xc
-
-	sysCTL_UNSPEC  = 0x0
-	sysCTL_KERN    = 0x1
-	sysCTL_VM      = 0x2
-	sysCTL_VFS     = 0x3
-	sysCTL_NET     = 0x4
-	sysCTL_DEBUG   = 0x5
-	sysCTL_HW      = 0x6
-	sysCTL_MACHDEP = 0x7
-	sysCTL_USER    = 0x8
-	sysCTL_MAXID   = 0x9
-)
-
-const (
-	sysRTM_VERSION = 0x5
-
-	sysRTM_ADD       = 0x1
-	sysRTM_DELETE    = 0x2
-	sysRTM_CHANGE    = 0x3
-	sysRTM_GET       = 0x4
-	sysRTM_LOSING    = 0x5
-	sysRTM_REDIRECT  = 0x6
-	sysRTM_MISS      = 0x7
-	sysRTM_LOCK      = 0x8
-	sysRTM_OLDADD    = 0x9
-	sysRTM_OLDDEL    = 0xa
-	sysRTM_RESOLVE   = 0xb
-	sysRTM_NEWADDR   = 0xc
-	sysRTM_DELADDR   = 0xd
-	sysRTM_IFINFO    = 0xe
-	sysRTM_NEWMADDR  = 0xf
-	sysRTM_DELMADDR  = 0x10
-	sysRTM_IFINFO2   = 0x12
-	sysRTM_NEWMADDR2 = 0x13
-	sysRTM_GET2      = 0x14
-
-	sysRTA_DST     = 0x1
-	sysRTA_GATEWAY = 0x2
-	sysRTA_NETMASK = 0x4
-	sysRTA_GENMASK = 0x8
-	sysRTA_IFP     = 0x10
-	sysRTA_IFA     = 0x20
-	sysRTA_AUTHOR  = 0x40
-	sysRTA_BRD     = 0x80
-
-	sysRTAX_DST     = 0x0
-	sysRTAX_GATEWAY = 0x1
-	sysRTAX_NETMASK = 0x2
-	sysRTAX_GENMASK = 0x3
-	sysRTAX_IFP     = 0x4
-	sysRTAX_IFA     = 0x5
-	sysRTAX_AUTHOR  = 0x6
-	sysRTAX_BRD     = 0x7
-	sysRTAX_MAX     = 0x8
-)
-
-const (
 	sizeofIfMsghdrDarwin15    = 0x70
 	sizeofIfaMsghdrDarwin15   = 0x14
 	sizeofIfmaMsghdrDarwin15  = 0x10
diff --git a/src/vendor/golang.org/x/net/route/zsys_dragonfly.go b/src/vendor/golang.org/x/net/route/zsys_dragonfly.go
index 34f0eaa..f7c7a60 100644
--- a/src/vendor/golang.org/x/net/route/zsys_dragonfly.go
+++ b/src/vendor/golang.org/x/net/route/zsys_dragonfly.go
@@ -4,84 +4,6 @@
 package route
 
 const (
-	sysAF_UNSPEC = 0x0
-	sysAF_INET   = 0x2
-	sysAF_ROUTE  = 0x11
-	sysAF_LINK   = 0x12
-	sysAF_INET6  = 0x1c
-
-	sysSOCK_RAW = 0x3
-
-	sysNET_RT_DUMP   = 0x1
-	sysNET_RT_FLAGS  = 0x2
-	sysNET_RT_IFLIST = 0x3
-	sysNET_RT_MAXID  = 0x4
-)
-
-const (
-	sysCTL_MAXNAME = 0xc
-
-	sysCTL_UNSPEC   = 0x0
-	sysCTL_KERN     = 0x1
-	sysCTL_VM       = 0x2
-	sysCTL_VFS      = 0x3
-	sysCTL_NET      = 0x4
-	sysCTL_DEBUG    = 0x5
-	sysCTL_HW       = 0x6
-	sysCTL_MACHDEP  = 0x7
-	sysCTL_USER     = 0x8
-	sysCTL_P1003_1B = 0x9
-	sysCTL_LWKT     = 0xa
-	sysCTL_MAXID    = 0xb
-)
-
-const (
-	sysRTM_VERSION = 0x6
-
-	sysRTM_ADD        = 0x1
-	sysRTM_DELETE     = 0x2
-	sysRTM_CHANGE     = 0x3
-	sysRTM_GET        = 0x4
-	sysRTM_LOSING     = 0x5
-	sysRTM_REDIRECT   = 0x6
-	sysRTM_MISS       = 0x7
-	sysRTM_LOCK       = 0x8
-	sysRTM_RESOLVE    = 0xb
-	sysRTM_NEWADDR    = 0xc
-	sysRTM_DELADDR    = 0xd
-	sysRTM_IFINFO     = 0xe
-	sysRTM_NEWMADDR   = 0xf
-	sysRTM_DELMADDR   = 0x10
-	sysRTM_IFANNOUNCE = 0x11
-	sysRTM_IEEE80211  = 0x12
-
-	sysRTA_DST     = 0x1
-	sysRTA_GATEWAY = 0x2
-	sysRTA_NETMASK = 0x4
-	sysRTA_GENMASK = 0x8
-	sysRTA_IFP     = 0x10
-	sysRTA_IFA     = 0x20
-	sysRTA_AUTHOR  = 0x40
-	sysRTA_BRD     = 0x80
-	sysRTA_MPLS1   = 0x100
-	sysRTA_MPLS2   = 0x200
-	sysRTA_MPLS3   = 0x400
-
-	sysRTAX_DST     = 0x0
-	sysRTAX_GATEWAY = 0x1
-	sysRTAX_NETMASK = 0x2
-	sysRTAX_GENMASK = 0x3
-	sysRTAX_IFP     = 0x4
-	sysRTAX_IFA     = 0x5
-	sysRTAX_AUTHOR  = 0x6
-	sysRTAX_BRD     = 0x7
-	sysRTAX_MPLS1   = 0x8
-	sysRTAX_MPLS2   = 0x9
-	sysRTAX_MPLS3   = 0xa
-	sysRTAX_MAX     = 0xb
-)
-
-const (
 	sizeofIfMsghdrDragonFlyBSD4         = 0xb0
 	sizeofIfaMsghdrDragonFlyBSD4        = 0x14
 	sizeofIfmaMsghdrDragonFlyBSD4       = 0x10
diff --git a/src/vendor/golang.org/x/net/route/zsys_freebsd_386.go b/src/vendor/golang.org/x/net/route/zsys_freebsd_386.go
index f36aaad..3f985c7 100644
--- a/src/vendor/golang.org/x/net/route/zsys_freebsd_386.go
+++ b/src/vendor/golang.org/x/net/route/zsys_freebsd_386.go
@@ -4,77 +4,6 @@
 package route
 
 const (
-	sysAF_UNSPEC = 0x0
-	sysAF_INET   = 0x2
-	sysAF_ROUTE  = 0x11
-	sysAF_LINK   = 0x12
-	sysAF_INET6  = 0x1c
-
-	sysSOCK_RAW = 0x3
-
-	sysNET_RT_DUMP     = 0x1
-	sysNET_RT_FLAGS    = 0x2
-	sysNET_RT_IFLIST   = 0x3
-	sysNET_RT_IFMALIST = 0x4
-	sysNET_RT_IFLISTL  = 0x5
-)
-
-const (
-	sysCTL_MAXNAME = 0x18
-
-	sysCTL_UNSPEC   = 0x0
-	sysCTL_KERN     = 0x1
-	sysCTL_VM       = 0x2
-	sysCTL_VFS      = 0x3
-	sysCTL_NET      = 0x4
-	sysCTL_DEBUG    = 0x5
-	sysCTL_HW       = 0x6
-	sysCTL_MACHDEP  = 0x7
-	sysCTL_USER     = 0x8
-	sysCTL_P1003_1B = 0x9
-)
-
-const (
-	sysRTM_VERSION = 0x5
-
-	sysRTM_ADD        = 0x1
-	sysRTM_DELETE     = 0x2
-	sysRTM_CHANGE     = 0x3
-	sysRTM_GET        = 0x4
-	sysRTM_LOSING     = 0x5
-	sysRTM_REDIRECT   = 0x6
-	sysRTM_MISS       = 0x7
-	sysRTM_LOCK       = 0x8
-	sysRTM_RESOLVE    = 0xb
-	sysRTM_NEWADDR    = 0xc
-	sysRTM_DELADDR    = 0xd
-	sysRTM_IFINFO     = 0xe
-	sysRTM_NEWMADDR   = 0xf
-	sysRTM_DELMADDR   = 0x10
-	sysRTM_IFANNOUNCE = 0x11
-	sysRTM_IEEE80211  = 0x12
-
-	sysRTA_DST     = 0x1
-	sysRTA_GATEWAY = 0x2
-	sysRTA_NETMASK = 0x4
-	sysRTA_GENMASK = 0x8
-	sysRTA_IFP     = 0x10
-	sysRTA_IFA     = 0x20
-	sysRTA_AUTHOR  = 0x40
-	sysRTA_BRD     = 0x80
-
-	sysRTAX_DST     = 0x0
-	sysRTAX_GATEWAY = 0x1
-	sysRTAX_NETMASK = 0x2
-	sysRTAX_GENMASK = 0x3
-	sysRTAX_IFP     = 0x4
-	sysRTAX_IFA     = 0x5
-	sysRTAX_AUTHOR  = 0x6
-	sysRTAX_BRD     = 0x7
-	sysRTAX_MAX     = 0x8
-)
-
-const (
 	sizeofIfMsghdrlFreeBSD10        = 0x68
 	sizeofIfaMsghdrFreeBSD10        = 0x14
 	sizeofIfaMsghdrlFreeBSD10       = 0x6c
diff --git a/src/vendor/golang.org/x/net/route/zsys_freebsd_amd64.go b/src/vendor/golang.org/x/net/route/zsys_freebsd_amd64.go
index 4c639b8..9293393 100644
--- a/src/vendor/golang.org/x/net/route/zsys_freebsd_amd64.go
+++ b/src/vendor/golang.org/x/net/route/zsys_freebsd_amd64.go
@@ -4,77 +4,6 @@
 package route
 
 const (
-	sysAF_UNSPEC = 0x0
-	sysAF_INET   = 0x2
-	sysAF_ROUTE  = 0x11
-	sysAF_LINK   = 0x12
-	sysAF_INET6  = 0x1c
-
-	sysSOCK_RAW = 0x3
-
-	sysNET_RT_DUMP     = 0x1
-	sysNET_RT_FLAGS    = 0x2
-	sysNET_RT_IFLIST   = 0x3
-	sysNET_RT_IFMALIST = 0x4
-	sysNET_RT_IFLISTL  = 0x5
-)
-
-const (
-	sysCTL_MAXNAME = 0x18
-
-	sysCTL_UNSPEC   = 0x0
-	sysCTL_KERN     = 0x1
-	sysCTL_VM       = 0x2
-	sysCTL_VFS      = 0x3
-	sysCTL_NET      = 0x4
-	sysCTL_DEBUG    = 0x5
-	sysCTL_HW       = 0x6
-	sysCTL_MACHDEP  = 0x7
-	sysCTL_USER     = 0x8
-	sysCTL_P1003_1B = 0x9
-)
-
-const (
-	sysRTM_VERSION = 0x5
-
-	sysRTM_ADD        = 0x1
-	sysRTM_DELETE     = 0x2
-	sysRTM_CHANGE     = 0x3
-	sysRTM_GET        = 0x4
-	sysRTM_LOSING     = 0x5
-	sysRTM_REDIRECT   = 0x6
-	sysRTM_MISS       = 0x7
-	sysRTM_LOCK       = 0x8
-	sysRTM_RESOLVE    = 0xb
-	sysRTM_NEWADDR    = 0xc
-	sysRTM_DELADDR    = 0xd
-	sysRTM_IFINFO     = 0xe
-	sysRTM_NEWMADDR   = 0xf
-	sysRTM_DELMADDR   = 0x10
-	sysRTM_IFANNOUNCE = 0x11
-	sysRTM_IEEE80211  = 0x12
-
-	sysRTA_DST     = 0x1
-	sysRTA_GATEWAY = 0x2
-	sysRTA_NETMASK = 0x4
-	sysRTA_GENMASK = 0x8
-	sysRTA_IFP     = 0x10
-	sysRTA_IFA     = 0x20
-	sysRTA_AUTHOR  = 0x40
-	sysRTA_BRD     = 0x80
-
-	sysRTAX_DST     = 0x0
-	sysRTAX_GATEWAY = 0x1
-	sysRTAX_NETMASK = 0x2
-	sysRTAX_GENMASK = 0x3
-	sysRTAX_IFP     = 0x4
-	sysRTAX_IFA     = 0x5
-	sysRTAX_AUTHOR  = 0x6
-	sysRTAX_BRD     = 0x7
-	sysRTAX_MAX     = 0x8
-)
-
-const (
 	sizeofIfMsghdrlFreeBSD10        = 0xb0
 	sizeofIfaMsghdrFreeBSD10        = 0x14
 	sizeofIfaMsghdrlFreeBSD10       = 0xb0
diff --git a/src/vendor/golang.org/x/net/route/zsys_freebsd_arm.go b/src/vendor/golang.org/x/net/route/zsys_freebsd_arm.go
index 710c147..a2bdb4a 100644
--- a/src/vendor/golang.org/x/net/route/zsys_freebsd_arm.go
+++ b/src/vendor/golang.org/x/net/route/zsys_freebsd_arm.go
@@ -4,77 +4,6 @@
 package route
 
 const (
-	sysAF_UNSPEC = 0x0
-	sysAF_INET   = 0x2
-	sysAF_ROUTE  = 0x11
-	sysAF_LINK   = 0x12
-	sysAF_INET6  = 0x1c
-
-	sysSOCK_RAW = 0x3
-
-	sysNET_RT_DUMP     = 0x1
-	sysNET_RT_FLAGS    = 0x2
-	sysNET_RT_IFLIST   = 0x3
-	sysNET_RT_IFMALIST = 0x4
-	sysNET_RT_IFLISTL  = 0x5
-)
-
-const (
-	sysCTL_MAXNAME = 0x18
-
-	sysCTL_UNSPEC   = 0x0
-	sysCTL_KERN     = 0x1
-	sysCTL_VM       = 0x2
-	sysCTL_VFS      = 0x3
-	sysCTL_NET      = 0x4
-	sysCTL_DEBUG    = 0x5
-	sysCTL_HW       = 0x6
-	sysCTL_MACHDEP  = 0x7
-	sysCTL_USER     = 0x8
-	sysCTL_P1003_1B = 0x9
-)
-
-const (
-	sysRTM_VERSION = 0x5
-
-	sysRTM_ADD        = 0x1
-	sysRTM_DELETE     = 0x2
-	sysRTM_CHANGE     = 0x3
-	sysRTM_GET        = 0x4
-	sysRTM_LOSING     = 0x5
-	sysRTM_REDIRECT   = 0x6
-	sysRTM_MISS       = 0x7
-	sysRTM_LOCK       = 0x8
-	sysRTM_RESOLVE    = 0xb
-	sysRTM_NEWADDR    = 0xc
-	sysRTM_DELADDR    = 0xd
-	sysRTM_IFINFO     = 0xe
-	sysRTM_NEWMADDR   = 0xf
-	sysRTM_DELMADDR   = 0x10
-	sysRTM_IFANNOUNCE = 0x11
-	sysRTM_IEEE80211  = 0x12
-
-	sysRTA_DST     = 0x1
-	sysRTA_GATEWAY = 0x2
-	sysRTA_NETMASK = 0x4
-	sysRTA_GENMASK = 0x8
-	sysRTA_IFP     = 0x10
-	sysRTA_IFA     = 0x20
-	sysRTA_AUTHOR  = 0x40
-	sysRTA_BRD     = 0x80
-
-	sysRTAX_DST     = 0x0
-	sysRTAX_GATEWAY = 0x1
-	sysRTAX_NETMASK = 0x2
-	sysRTAX_GENMASK = 0x3
-	sysRTAX_IFP     = 0x4
-	sysRTAX_IFA     = 0x5
-	sysRTAX_AUTHOR  = 0x6
-	sysRTAX_BRD     = 0x7
-	sysRTAX_MAX     = 0x8
-)
-
-const (
 	sizeofIfMsghdrlFreeBSD10        = 0x68
 	sizeofIfaMsghdrFreeBSD10        = 0x14
 	sizeofIfaMsghdrlFreeBSD10       = 0x6c
diff --git a/src/vendor/golang.org/x/net/route/zsys_freebsd_arm64.go b/src/vendor/golang.org/x/net/route/zsys_freebsd_arm64.go
index 4c639b8..9293393 100644
--- a/src/vendor/golang.org/x/net/route/zsys_freebsd_arm64.go
+++ b/src/vendor/golang.org/x/net/route/zsys_freebsd_arm64.go
@@ -4,77 +4,6 @@
 package route
 
 const (
-	sysAF_UNSPEC = 0x0
-	sysAF_INET   = 0x2
-	sysAF_ROUTE  = 0x11
-	sysAF_LINK   = 0x12
-	sysAF_INET6  = 0x1c
-
-	sysSOCK_RAW = 0x3
-
-	sysNET_RT_DUMP     = 0x1
-	sysNET_RT_FLAGS    = 0x2
-	sysNET_RT_IFLIST   = 0x3
-	sysNET_RT_IFMALIST = 0x4
-	sysNET_RT_IFLISTL  = 0x5
-)
-
-const (
-	sysCTL_MAXNAME = 0x18
-
-	sysCTL_UNSPEC   = 0x0
-	sysCTL_KERN     = 0x1
-	sysCTL_VM       = 0x2
-	sysCTL_VFS      = 0x3
-	sysCTL_NET      = 0x4
-	sysCTL_DEBUG    = 0x5
-	sysCTL_HW       = 0x6
-	sysCTL_MACHDEP  = 0x7
-	sysCTL_USER     = 0x8
-	sysCTL_P1003_1B = 0x9
-)
-
-const (
-	sysRTM_VERSION = 0x5
-
-	sysRTM_ADD        = 0x1
-	sysRTM_DELETE     = 0x2
-	sysRTM_CHANGE     = 0x3
-	sysRTM_GET        = 0x4
-	sysRTM_LOSING     = 0x5
-	sysRTM_REDIRECT   = 0x6
-	sysRTM_MISS       = 0x7
-	sysRTM_LOCK       = 0x8
-	sysRTM_RESOLVE    = 0xb
-	sysRTM_NEWADDR    = 0xc
-	sysRTM_DELADDR    = 0xd
-	sysRTM_IFINFO     = 0xe
-	sysRTM_NEWMADDR   = 0xf
-	sysRTM_DELMADDR   = 0x10
-	sysRTM_IFANNOUNCE = 0x11
-	sysRTM_IEEE80211  = 0x12
-
-	sysRTA_DST     = 0x1
-	sysRTA_GATEWAY = 0x2
-	sysRTA_NETMASK = 0x4
-	sysRTA_GENMASK = 0x8
-	sysRTA_IFP     = 0x10
-	sysRTA_IFA     = 0x20
-	sysRTA_AUTHOR  = 0x40
-	sysRTA_BRD     = 0x80
-
-	sysRTAX_DST     = 0x0
-	sysRTAX_GATEWAY = 0x1
-	sysRTAX_NETMASK = 0x2
-	sysRTAX_GENMASK = 0x3
-	sysRTAX_IFP     = 0x4
-	sysRTAX_IFA     = 0x5
-	sysRTAX_AUTHOR  = 0x6
-	sysRTAX_BRD     = 0x7
-	sysRTAX_MAX     = 0x8
-)
-
-const (
 	sizeofIfMsghdrlFreeBSD10        = 0xb0
 	sizeofIfaMsghdrFreeBSD10        = 0x14
 	sizeofIfaMsghdrlFreeBSD10       = 0xb0
diff --git a/src/vendor/golang.org/x/net/route/zsys_freebsd_riscv64.go b/src/vendor/golang.org/x/net/route/zsys_freebsd_riscv64.go
new file mode 100644
index 0000000..9293393
--- /dev/null
+++ b/src/vendor/golang.org/x/net/route/zsys_freebsd_riscv64.go
@@ -0,0 +1,52 @@
+// Code generated by cmd/cgo -godefs; DO NOT EDIT.
+// cgo -godefs defs_freebsd.go
+
+package route
+
+const (
+	sizeofIfMsghdrlFreeBSD10        = 0xb0
+	sizeofIfaMsghdrFreeBSD10        = 0x14
+	sizeofIfaMsghdrlFreeBSD10       = 0xb0
+	sizeofIfmaMsghdrFreeBSD10       = 0x10
+	sizeofIfAnnouncemsghdrFreeBSD10 = 0x18
+
+	sizeofRtMsghdrFreeBSD10  = 0x98
+	sizeofRtMetricsFreeBSD10 = 0x70
+
+	sizeofIfMsghdrFreeBSD7  = 0xa8
+	sizeofIfMsghdrFreeBSD8  = 0xa8
+	sizeofIfMsghdrFreeBSD9  = 0xa8
+	sizeofIfMsghdrFreeBSD10 = 0xa8
+	sizeofIfMsghdrFreeBSD11 = 0xa8
+
+	sizeofIfDataFreeBSD7  = 0x98
+	sizeofIfDataFreeBSD8  = 0x98
+	sizeofIfDataFreeBSD9  = 0x98
+	sizeofIfDataFreeBSD10 = 0x98
+	sizeofIfDataFreeBSD11 = 0x98
+
+	sizeofIfMsghdrlFreeBSD10Emu        = 0xb0
+	sizeofIfaMsghdrFreeBSD10Emu        = 0x14
+	sizeofIfaMsghdrlFreeBSD10Emu       = 0xb0
+	sizeofIfmaMsghdrFreeBSD10Emu       = 0x10
+	sizeofIfAnnouncemsghdrFreeBSD10Emu = 0x18
+
+	sizeofRtMsghdrFreeBSD10Emu  = 0x98
+	sizeofRtMetricsFreeBSD10Emu = 0x70
+
+	sizeofIfMsghdrFreeBSD7Emu  = 0xa8
+	sizeofIfMsghdrFreeBSD8Emu  = 0xa8
+	sizeofIfMsghdrFreeBSD9Emu  = 0xa8
+	sizeofIfMsghdrFreeBSD10Emu = 0xa8
+	sizeofIfMsghdrFreeBSD11Emu = 0xa8
+
+	sizeofIfDataFreeBSD7Emu  = 0x98
+	sizeofIfDataFreeBSD8Emu  = 0x98
+	sizeofIfDataFreeBSD9Emu  = 0x98
+	sizeofIfDataFreeBSD10Emu = 0x98
+	sizeofIfDataFreeBSD11Emu = 0x98
+
+	sizeofSockaddrStorage = 0x80
+	sizeofSockaddrInet    = 0x10
+	sizeofSockaddrInet6   = 0x1c
+)
diff --git a/src/vendor/golang.org/x/net/route/zsys_netbsd.go b/src/vendor/golang.org/x/net/route/zsys_netbsd.go
index b4f66ca..eaffe8c 100644
--- a/src/vendor/golang.org/x/net/route/zsys_netbsd.go
+++ b/src/vendor/golang.org/x/net/route/zsys_netbsd.go
@@ -4,86 +4,6 @@
 package route
 
 const (
-	sysAF_UNSPEC = 0x0
-	sysAF_INET   = 0x2
-	sysAF_ROUTE  = 0x22
-	sysAF_LINK   = 0x12
-	sysAF_INET6  = 0x18
-
-	sysSOCK_RAW = 0x3
-
-	sysNET_RT_DUMP   = 0x1
-	sysNET_RT_FLAGS  = 0x2
-	sysNET_RT_IFLIST = 0x5
-	sysNET_RT_MAXID  = 0x6
-)
-
-const (
-	sysCTL_MAXNAME = 0xc
-
-	sysCTL_UNSPEC   = 0x0
-	sysCTL_KERN     = 0x1
-	sysCTL_VM       = 0x2
-	sysCTL_VFS      = 0x3
-	sysCTL_NET      = 0x4
-	sysCTL_DEBUG    = 0x5
-	sysCTL_HW       = 0x6
-	sysCTL_MACHDEP  = 0x7
-	sysCTL_USER     = 0x8
-	sysCTL_DDB      = 0x9
-	sysCTL_PROC     = 0xa
-	sysCTL_VENDOR   = 0xb
-	sysCTL_EMUL     = 0xc
-	sysCTL_SECURITY = 0xd
-	sysCTL_MAXID    = 0xe
-)
-
-const (
-	sysRTM_VERSION = 0x4
-
-	sysRTM_ADD        = 0x1
-	sysRTM_DELETE     = 0x2
-	sysRTM_CHANGE     = 0x3
-	sysRTM_GET        = 0x4
-	sysRTM_LOSING     = 0x5
-	sysRTM_REDIRECT   = 0x6
-	sysRTM_MISS       = 0x7
-	sysRTM_LOCK       = 0x8
-	sysRTM_OLDADD     = 0x9
-	sysRTM_OLDDEL     = 0xa
-	sysRTM_RESOLVE    = 0xb
-	sysRTM_NEWADDR    = 0xc
-	sysRTM_DELADDR    = 0xd
-	sysRTM_IFANNOUNCE = 0x10
-	sysRTM_IEEE80211  = 0x11
-	sysRTM_SETGATE    = 0x12
-	sysRTM_LLINFO_UPD = 0x13
-	sysRTM_IFINFO     = 0x14
-	sysRTM_CHGADDR    = 0x15
-
-	sysRTA_DST     = 0x1
-	sysRTA_GATEWAY = 0x2
-	sysRTA_NETMASK = 0x4
-	sysRTA_GENMASK = 0x8
-	sysRTA_IFP     = 0x10
-	sysRTA_IFA     = 0x20
-	sysRTA_AUTHOR  = 0x40
-	sysRTA_BRD     = 0x80
-	sysRTA_TAG     = 0x100
-
-	sysRTAX_DST     = 0x0
-	sysRTAX_GATEWAY = 0x1
-	sysRTAX_NETMASK = 0x2
-	sysRTAX_GENMASK = 0x3
-	sysRTAX_IFP     = 0x4
-	sysRTAX_IFA     = 0x5
-	sysRTAX_AUTHOR  = 0x6
-	sysRTAX_BRD     = 0x7
-	sysRTAX_TAG     = 0x8
-	sysRTAX_MAX     = 0x9
-)
-
-const (
 	sizeofIfMsghdrNetBSD7         = 0x98
 	sizeofIfaMsghdrNetBSD7        = 0x18
 	sizeofIfAnnouncemsghdrNetBSD7 = 0x18
diff --git a/src/vendor/golang.org/x/net/route/zsys_openbsd.go b/src/vendor/golang.org/x/net/route/zsys_openbsd.go
index 1021b4c..b11b812 100644
--- a/src/vendor/golang.org/x/net/route/zsys_openbsd.go
+++ b/src/vendor/golang.org/x/net/route/zsys_openbsd.go
@@ -4,95 +4,6 @@
 package route
 
 const (
-	sysAF_UNSPEC = 0x0
-	sysAF_INET   = 0x2
-	sysAF_ROUTE  = 0x11
-	sysAF_LINK   = 0x12
-	sysAF_INET6  = 0x18
-
-	sysSOCK_RAW = 0x3
-
-	sysNET_RT_DUMP    = 0x1
-	sysNET_RT_FLAGS   = 0x2
-	sysNET_RT_IFLIST  = 0x3
-	sysNET_RT_STATS   = 0x4
-	sysNET_RT_TABLE   = 0x5
-	sysNET_RT_IFNAMES = 0x6
-	sysNET_RT_MAXID   = 0x7
-)
-
-const (
-	sysCTL_MAXNAME = 0xc
-
-	sysCTL_UNSPEC  = 0x0
-	sysCTL_KERN    = 0x1
-	sysCTL_VM      = 0x2
-	sysCTL_FS      = 0x3
-	sysCTL_NET     = 0x4
-	sysCTL_DEBUG   = 0x5
-	sysCTL_HW      = 0x6
-	sysCTL_MACHDEP = 0x7
-	sysCTL_DDB     = 0x9
-	sysCTL_VFS     = 0xa
-	sysCTL_MAXID   = 0xb
-)
-
-const (
-	sysRTM_VERSION = 0x5
-
-	sysRTM_ADD        = 0x1
-	sysRTM_DELETE     = 0x2
-	sysRTM_CHANGE     = 0x3
-	sysRTM_GET        = 0x4
-	sysRTM_LOSING     = 0x5
-	sysRTM_REDIRECT   = 0x6
-	sysRTM_MISS       = 0x7
-	sysRTM_LOCK       = 0x8
-	sysRTM_RESOLVE    = 0xb
-	sysRTM_NEWADDR    = 0xc
-	sysRTM_DELADDR    = 0xd
-	sysRTM_IFINFO     = 0xe
-	sysRTM_IFANNOUNCE = 0xf
-	sysRTM_DESYNC     = 0x10
-	sysRTM_INVALIDATE = 0x11
-	sysRTM_BFD        = 0x12
-	sysRTM_PROPOSAL   = 0x13
-
-	sysRTA_DST     = 0x1
-	sysRTA_GATEWAY = 0x2
-	sysRTA_NETMASK = 0x4
-	sysRTA_GENMASK = 0x8
-	sysRTA_IFP     = 0x10
-	sysRTA_IFA     = 0x20
-	sysRTA_AUTHOR  = 0x40
-	sysRTA_BRD     = 0x80
-	sysRTA_SRC     = 0x100
-	sysRTA_SRCMASK = 0x200
-	sysRTA_LABEL   = 0x400
-	sysRTA_BFD     = 0x800
-	sysRTA_DNS     = 0x1000
-	sysRTA_STATIC  = 0x2000
-	sysRTA_SEARCH  = 0x4000
-
-	sysRTAX_DST     = 0x0
-	sysRTAX_GATEWAY = 0x1
-	sysRTAX_NETMASK = 0x2
-	sysRTAX_GENMASK = 0x3
-	sysRTAX_IFP     = 0x4
-	sysRTAX_IFA     = 0x5
-	sysRTAX_AUTHOR  = 0x6
-	sysRTAX_BRD     = 0x7
-	sysRTAX_SRC     = 0x8
-	sysRTAX_SRCMASK = 0x9
-	sysRTAX_LABEL   = 0xa
-	sysRTAX_BFD     = 0xb
-	sysRTAX_DNS     = 0xc
-	sysRTAX_STATIC  = 0xd
-	sysRTAX_SEARCH  = 0xe
-	sysRTAX_MAX     = 0xf
-)
-
-const (
 	sizeofRtMsghdr = 0x60
 
 	sizeofSockaddrStorage = 0x100
diff --git a/src/vendor/golang.org/x/sys/AUTHORS b/src/vendor/golang.org/x/sys/AUTHORS
deleted file mode 100644
index 15167cd..0000000
--- a/src/vendor/golang.org/x/sys/AUTHORS
+++ /dev/null
@@ -1,3 +0,0 @@
-# This source code refers to The Go Authors for copyright purposes.
-# The master list of authors is in the main Go distribution,
-# visible at http://tip.golang.org/AUTHORS.
diff --git a/src/vendor/golang.org/x/sys/CONTRIBUTORS b/src/vendor/golang.org/x/sys/CONTRIBUTORS
deleted file mode 100644
index 1c4577e..0000000
--- a/src/vendor/golang.org/x/sys/CONTRIBUTORS
+++ /dev/null
@@ -1,3 +0,0 @@
-# This source code was written by the Go contributors.
-# The master list of contributors is in the main Go distribution,
-# visible at http://tip.golang.org/CONTRIBUTORS.
diff --git a/src/vendor/golang.org/x/sys/cpu/cpu_arm64.go b/src/vendor/golang.org/x/sys/cpu/cpu_arm64.go
index 87dd5e3..f3eb993 100644
--- a/src/vendor/golang.org/x/sys/cpu/cpu_arm64.go
+++ b/src/vendor/golang.org/x/sys/cpu/cpu_arm64.go
@@ -6,7 +6,10 @@
 
 import "runtime"
 
-const cacheLineSize = 64
+// cacheLineSize is used to prevent false sharing of cache lines.
+// We choose 128 because Apple Silicon, a.k.a. M1, has 128-byte cache line size.
+// It doesn't cost much and is much more future-proof.
+const cacheLineSize = 128
 
 func initOptions() {
 	options = []option{
@@ -41,13 +44,10 @@
 	switch runtime.GOOS {
 	case "freebsd":
 		readARM64Registers()
-	case "linux", "netbsd":
+	case "linux", "netbsd", "openbsd":
 		doinit()
 	default:
-		// Most platforms don't seem to allow reading these registers.
-		//
-		// OpenBSD:
-		// See https://golang.org/issue/31746
+		// Many platforms don't seem to allow reading these registers.
 		setMinimalFeatures()
 	}
 }
diff --git a/src/vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.go b/src/vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.go
new file mode 100644
index 0000000..85b64d5
--- /dev/null
+++ b/src/vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.go
@@ -0,0 +1,65 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cpu
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+// Minimal copy of functionality from x/sys/unix so the cpu package can call
+// sysctl without depending on x/sys/unix.
+
+const (
+	// From OpenBSD's sys/sysctl.h.
+	_CTL_MACHDEP = 7
+
+	// From OpenBSD's machine/cpu.h.
+	_CPU_ID_AA64ISAR0 = 2
+	_CPU_ID_AA64ISAR1 = 3
+)
+
+// Implemented in the runtime package (runtime/sys_openbsd3.go)
+func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
+
+//go:linkname syscall_syscall6 syscall.syscall6
+
+func sysctl(mib []uint32, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
+	_, _, errno := syscall_syscall6(libc_sysctl_trampoline_addr, uintptr(unsafe.Pointer(&mib[0])), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
+	if errno != 0 {
+		return errno
+	}
+	return nil
+}
+
+var libc_sysctl_trampoline_addr uintptr
+
+//go:cgo_import_dynamic libc_sysctl sysctl "libc.so"
+
+func sysctlUint64(mib []uint32) (uint64, bool) {
+	var out uint64
+	nout := unsafe.Sizeof(out)
+	if err := sysctl(mib, (*byte)(unsafe.Pointer(&out)), &nout, nil, 0); err != nil {
+		return 0, false
+	}
+	return out, true
+}
+
+func doinit() {
+	setMinimalFeatures()
+
+	// Get ID_AA64ISAR0 and ID_AA64ISAR1 from sysctl.
+	isar0, ok := sysctlUint64([]uint32{_CTL_MACHDEP, _CPU_ID_AA64ISAR0})
+	if !ok {
+		return
+	}
+	isar1, ok := sysctlUint64([]uint32{_CTL_MACHDEP, _CPU_ID_AA64ISAR1})
+	if !ok {
+		return
+	}
+	parseARM64SystemRegisters(isar0, isar1, 0)
+
+	Initialized = true
+}
diff --git a/src/vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.s b/src/vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.s
new file mode 100644
index 0000000..054ba05
--- /dev/null
+++ b/src/vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.s
@@ -0,0 +1,11 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
+	JMP	libc_sysctl(SB)
+
+GLOBL	·libc_sysctl_trampoline_addr(SB), RODATA, $8
+DATA	·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB)
diff --git a/src/vendor/golang.org/x/sys/cpu/cpu_other_arm64.go b/src/vendor/golang.org/x/sys/cpu/cpu_other_arm64.go
index f8c484f..f3cde12 100644
--- a/src/vendor/golang.org/x/sys/cpu/cpu_other_arm64.go
+++ b/src/vendor/golang.org/x/sys/cpu/cpu_other_arm64.go
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build !linux && !netbsd && arm64
-// +build !linux,!netbsd,arm64
+//go:build !linux && !netbsd && !openbsd && arm64
+// +build !linux,!netbsd,!openbsd,arm64
 
 package cpu
 
diff --git a/src/vendor/golang.org/x/sys/cpu/cpu_other_ppc64x.go b/src/vendor/golang.org/x/sys/cpu/cpu_other_ppc64x.go
new file mode 100644
index 0000000..060d46b
--- /dev/null
+++ b/src/vendor/golang.org/x/sys/cpu/cpu_other_ppc64x.go
@@ -0,0 +1,15 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !aix && !linux && (ppc64 || ppc64le)
+// +build !aix
+// +build !linux
+// +build ppc64 ppc64le
+
+package cpu
+
+func archInit() {
+	PPC64.IsPOWER8 = true
+	Initialized = true
+}
diff --git a/src/vendor/golang.org/x/sys/cpu/cpu_other_riscv64.go b/src/vendor/golang.org/x/sys/cpu/cpu_other_riscv64.go
new file mode 100644
index 0000000..dd10eb7
--- /dev/null
+++ b/src/vendor/golang.org/x/sys/cpu/cpu_other_riscv64.go
@@ -0,0 +1,12 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !linux && riscv64
+// +build !linux,riscv64
+
+package cpu
+
+func archInit() {
+	Initialized = true
+}
diff --git a/src/vendor/golang.org/x/text/AUTHORS b/src/vendor/golang.org/x/text/AUTHORS
deleted file mode 100644
index 15167cd..0000000
--- a/src/vendor/golang.org/x/text/AUTHORS
+++ /dev/null
@@ -1,3 +0,0 @@
-# This source code refers to The Go Authors for copyright purposes.
-# The master list of authors is in the main Go distribution,
-# visible at http://tip.golang.org/AUTHORS.
diff --git a/src/vendor/golang.org/x/text/CONTRIBUTORS b/src/vendor/golang.org/x/text/CONTRIBUTORS
deleted file mode 100644
index 1c4577e..0000000
--- a/src/vendor/golang.org/x/text/CONTRIBUTORS
+++ /dev/null
@@ -1,3 +0,0 @@
-# This source code was written by the Go contributors.
-# The master list of contributors is in the main Go distribution,
-# visible at http://tip.golang.org/CONTRIBUTORS.
diff --git a/src/vendor/golang.org/x/text/unicode/bidi/trieval.go b/src/vendor/golang.org/x/text/unicode/bidi/trieval.go
index 4c459c4..6a796e2 100644
--- a/src/vendor/golang.org/x/text/unicode/bidi/trieval.go
+++ b/src/vendor/golang.org/x/text/unicode/bidi/trieval.go
@@ -37,18 +37,6 @@
 	unknownClass = ^Class(0)
 )
 
-var controlToClass = map[rune]Class{
-	0x202D: LRO, // LeftToRightOverride,
-	0x202E: RLO, // RightToLeftOverride,
-	0x202A: LRE, // LeftToRightEmbedding,
-	0x202B: RLE, // RightToLeftEmbedding,
-	0x202C: PDF, // PopDirectionalFormat,
-	0x2066: LRI, // LeftToRightIsolate,
-	0x2067: RLI, // RightToLeftIsolate,
-	0x2068: FSI, // FirstStrongIsolate,
-	0x2069: PDI, // PopDirectionalIsolate,
-}
-
 // A trie entry has the following bits:
 // 7..5  XOR mask for brackets
 // 4     1: Bracket open, 0: Bracket close
diff --git a/src/vendor/golang.org/x/text/unicode/norm/tables13.0.0.go b/src/vendor/golang.org/x/text/unicode/norm/tables13.0.0.go
index 96a130d..9115ef2 100644
--- a/src/vendor/golang.org/x/text/unicode/norm/tables13.0.0.go
+++ b/src/vendor/golang.org/x/text/unicode/norm/tables13.0.0.go
@@ -7315,7 +7315,7 @@
 	"\x00V\x03\x03\x00\x00\x1e|" + // 0x00560303: 0x00001E7C
 	"\x00v\x03\x03\x00\x00\x1e}" + // 0x00760303: 0x00001E7D
 	"\x00V\x03#\x00\x00\x1e~" + // 0x00560323: 0x00001E7E
-	"\x00v\x03#\x00\x00\x1e\u007f" + // 0x00760323: 0x00001E7F
+	"\x00v\x03#\x00\x00\x1e\x7f" + // 0x00760323: 0x00001E7F
 	"\x00W\x03\x00\x00\x00\x1e\x80" + // 0x00570300: 0x00001E80
 	"\x00w\x03\x00\x00\x00\x1e\x81" + // 0x00770300: 0x00001E81
 	"\x00W\x03\x01\x00\x00\x1e\x82" + // 0x00570301: 0x00001E82
@@ -7342,7 +7342,7 @@
 	"\x00t\x03\b\x00\x00\x1e\x97" + // 0x00740308: 0x00001E97
 	"\x00w\x03\n\x00\x00\x1e\x98" + // 0x0077030A: 0x00001E98
 	"\x00y\x03\n\x00\x00\x1e\x99" + // 0x0079030A: 0x00001E99
-	"\x01\u007f\x03\a\x00\x00\x1e\x9b" + // 0x017F0307: 0x00001E9B
+	"\x01\x7f\x03\a\x00\x00\x1e\x9b" + // 0x017F0307: 0x00001E9B
 	"\x00A\x03#\x00\x00\x1e\xa0" + // 0x00410323: 0x00001EA0
 	"\x00a\x03#\x00\x00\x1e\xa1" + // 0x00610323: 0x00001EA1
 	"\x00A\x03\t\x00\x00\x1e\xa2" + // 0x00410309: 0x00001EA2
diff --git a/src/vendor/modules.txt b/src/vendor/modules.txt
index dfb87ab..89a7c86 100644
--- a/src/vendor/modules.txt
+++ b/src/vendor/modules.txt
@@ -1,15 +1,13 @@
-# golang.org/x/crypto v0.0.0-20220516162934-403b01795ae8
+# golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a
 ## explicit; go 1.17
 golang.org/x/crypto/chacha20
 golang.org/x/crypto/chacha20poly1305
 golang.org/x/crypto/cryptobyte
 golang.org/x/crypto/cryptobyte/asn1
-golang.org/x/crypto/curve25519
-golang.org/x/crypto/curve25519/internal/field
 golang.org/x/crypto/hkdf
+golang.org/x/crypto/internal/alias
 golang.org/x/crypto/internal/poly1305
-golang.org/x/crypto/internal/subtle
-# golang.org/x/net v0.0.0-20220517181318-183a9ca12b87
+# golang.org/x/net v0.4.1-0.20230214201333-88ed8ca3307d
 ## explicit; go 1.17
 golang.org/x/net/dns/dnsmessage
 golang.org/x/net/http/httpguts
@@ -19,10 +17,10 @@
 golang.org/x/net/lif
 golang.org/x/net/nettest
 golang.org/x/net/route
-# golang.org/x/sys v0.0.0-20220614162138-6c1b26c55098
+# golang.org/x/sys v0.3.0
 ## explicit; go 1.17
 golang.org/x/sys/cpu
-# golang.org/x/text v0.3.8-0.20220509174342-b4bca84b0361
+# golang.org/x/text v0.5.0
 ## explicit; go 1.17
 golang.org/x/text/secure/bidirule
 golang.org/x/text/transform